@teispace/next-maker 1.20.1 → 2.0.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 +24 -0
- package/README.md +9 -6
- package/dist/index.js +92 -92
- package/dist/index.js.map +3 -3
- package/dist/src/config/paths.d.ts +2 -0
- package/dist/src/config/paths.d.ts.map +1 -1
- package/dist/src/generators/templates/crud-service.template.d.ts.map +1 -1
- package/dist/src/manifests/http-client.manifest.d.ts.map +1 -1
- package/dist/src/modifiers/api-registration.modifier.d.ts.map +1 -1
- package/dist/src/services/setup/http-client/assets.d.ts.map +1 -1
- package/dist/src/services/setup/http-client/index.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/detection/existence.checker.ts", "../src/detection/project.detector.ts", "../src/detection/index.ts", "../src/index.ts", "../src/commands/app.ts", "../src/config/errorHandlers.ts", "../src/config/output.ts", "../src/config/spinner.ts", "../src/config/utils.ts", "../src/config/index.ts", "../src/core/git.ts", "../src/core/package-manager.ts", "../src/prompts/create-app.prompt.ts", "../src/services/common/test-utils.ts", "../src/services/init/cleanup/bundle-analyzer.cleanup.ts", "../src/config/packages.ts", "../src/services/init/cleanup/dark-mode.cleanup.ts", "../src/services/init/cleanup/http.cleanup.ts", "../src/services/init/cleanup/i18n.cleanup.ts", "../src/services/init/cleanup/misc.cleanup.ts", "../src/services/init/cleanup/react-compiler.cleanup.ts", "../src/services/init/cleanup/redux.cleanup.ts", "../src/services/init/cleanup/tests.cleanup.ts", "../src/services/init/cleanup/index.ts", "../src/services/init/config.service.ts", "../src/services/init/devtools.service.ts", "../src/services/init/providers.service.ts", "../src/services/init/template.service.ts", "../src/commands/component.ts", "../src/generators/component.generator.ts", "../src/generators/templates/shared-component.template.ts", "../src/generators/crud-service.generator.ts", "../src/generators/templates/crud-service.template.ts", "../src/generators/feature.generator.ts", "../src/generators/service.generator.ts", "../src/generators/templates/service.template.ts", "../src/generators/slice.generator.ts", "../src/generators/templates/barrel.template.ts", "../src/generators/templates/persist.template.ts", "../src/generators/templates/selectors.template.ts", "../src/generators/templates/slice.template.ts", "../src/generators/templates/types.template.ts", "../src/generators/templates/component.template.ts", "../src/generators/templates/hook.template.ts", "../src/generators/hook.generator.ts", "../src/generators/templates/custom-hook.template.ts", "../src/generators/layout.generator.ts", "../src/generators/templates/layout.template.ts", "../src/generators/locale.generator.ts", "../src/generators/page.generator.ts", "../src/generators/templates/page.template.ts", "../src/generators/provider.generator.ts", "../src/generators/templates/provider.template.ts", "../src/generators/test.generator.ts", "../src/generators/templates/test.template.ts", "../src/prompts/component.prompt.ts", "../src/commands/doctor.ts", "../src/manifests/bundle-analyzer.manifest.ts", "../src/services/setup/bundle-analyzer/index.ts", "../src/manifests/transforms/unwrap-jsx.ts", "../src/manifests/transforms/next-config.ts", "../src/manifests/commitizen.manifest.ts", "../src/services/setup/commitizen/index.ts", "../src/services/setup/commitizen/package-modifier.ts", "../src/manifests/dark-theme.manifest.ts", "../src/services/setup/dark-theme/index.ts", "../src/services/setup/dark-theme/assets.ts", "../src/services/setup/dark-theme/checks.ts", "../src/services/setup/dark-theme/utils.ts", "../src/services/setup/dark-theme/injectors.ts", "../src/services/setup/http-client/index.ts", "../src/services/setup/http-client/assets.ts", "../src/services/setup/http-client/checks.ts", "../src/manifests/http-client.manifest.ts", "../src/services/setup/i18n/index.ts", "../src/services/setup/i18n/assets.ts", "../src/services/setup/i18n/checks.ts", "../src/services/setup/i18n/injectors.ts", "../src/manifests/i18n.manifest.ts", "../src/manifests/react-compiler.manifest.ts", "../src/services/setup/react-compiler/index.ts", "../src/services/setup/redux/index.ts", "../src/services/setup/redux/assets.ts", "../src/services/setup/redux/checks.ts", "../src/services/setup/redux/injectors.ts", "../src/manifests/redux.manifest.ts", "../src/manifests/security-headers.manifest.ts", "../src/services/setup/security-headers/index.ts", "../src/services/setup/security-headers/headers.ts", "../src/manifests/tests.manifest.ts", "../src/services/setup/tests/index.ts", "../src/manifests/validate-scripts.manifest.ts", "../src/services/setup/validate-scripts/index.ts", "../src/services/setup/validate-scripts/package-modifier.ts", "../src/services/setup/validate-scripts/scripts.ts", "../src/manifests/runner.ts", "../src/manifests/index.ts", "../src/commands/env.ts", "../src/modifiers/env-var.modifier.ts", "../src/commands/favicon.ts", "../src/prompts/favicon.prompt.ts", "../src/services/favicon/detect.ts", "../src/services/favicon/pipeline.ts", "../src/services/favicon/encoders.ts", "../src/services/favicon/shapes.ts", "../src/services/favicon/manifest.ts", "../src/services/favicon/validate.ts", "../src/services/favicon/css-colors.ts", "../src/commands/feature.ts", "../src/pipelines/feature.pipeline.ts", "../src/modifiers/api-registration.modifier.ts", "../src/modifiers/helpers.ts", "../src/modifiers/app-paths.modifier.ts", "../src/modifiers/root-provider.modifier.ts", "../src/modifiers/root-reducer.modifier.ts", "../src/modifiers/translation.modifier.ts", "../src/pipelines/runner.ts", "../src/pipelines/service.pipeline.ts", "../src/pipelines/slice.pipeline.ts", "../src/prompts/feature.prompt.ts", "../src/commands/hook.ts", "../src/prompts/hook.prompt.ts", "../src/commands/layout.ts", "../src/commands/locale.ts", "../src/prompts/locale.prompt.ts", "../src/commands/page.ts", "../src/prompts/page.prompt.ts", "../src/commands/provider.ts", "../src/commands/remove.ts", "../src/commands/service.ts", "../src/modifiers/crud-api-registration.modifier.ts", "../src/prompts/service.prompt.ts", "../src/commands/setup.ts", "../src/commands/slice.ts", "../src/prompts/slice.prompt.ts", "../src/commands/test.ts", "../src/commands/index.ts"],
|
|
4
|
-
"sourcesContent": ["import { existsSync } from 'node:fs';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\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 POSTCSS_CONFIG: 'postcss.config.mjs',\n BIOME_CONFIG: 'biome.json',\n VITEST_CONFIG: 'vitest.config.ts',\n TEST_DIR: 'test',\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 AGENTS_MD: 'AGENTS.md',\n CLAUDE_MD: 'CLAUDE.md',\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\n // Template-specific (should be cleaned on init)\n SCRIPTS_DIR: 'scripts',\n DOCS_DIR: 'docs',\n CLAUDE_DIR: '.claude',\n VSCODE_DIR: '.vscode',\n} as const;\n", "import { exec } from 'node:child_process';\nimport path from 'node:path';\nimport { promisify } from 'node:util';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { fileExists, readFile, writeFile } from '../../../core/files';\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 { existsSync } from 'node:fs';\nimport { access } from 'node:fs/promises';\nimport path from 'node:path';\n\n/**\n * Check if a directory exists at projectPath/basePath/name.\n */\nexport const directoryExists = async (\n projectPath: string,\n name: string,\n basePath: string,\n): Promise<boolean> => {\n try {\n await access(path.join(projectPath, basePath, name));\n return true;\n } catch {\n return false;\n }\n};\n\n/**\n * Check if a specific file exists at projectPath/basePath/fileName.\n */\nexport const fileExistsAt = (projectPath: string, basePath: string, fileName: string): boolean => {\n return existsSync(path.join(projectPath, basePath, fileName));\n};\n", "import { access, readFile } 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 hasTests: boolean;\n}\n\nexport const detectProjectSetup = async (projectPath: string): Promise<ProjectDetection> => {\n try {\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 const hasRedux = !!(dependencies['@reduxjs/toolkit'] && dependencies['react-redux']);\n const hasI18n = !!dependencies['next-intl'];\n\n // Check for HTTP clients: must be both in dependencies AND have client directory\n let hasAxios = !!dependencies.axios;\n let hasFetch = false;\n\n const axiosClientPath = path.join(projectPath, 'src', 'lib', 'utils', 'http', 'axios-client');\n try {\n await access(axiosClientPath);\n } catch {\n hasAxios = false;\n }\n\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;\n }\n\n let httpClient: ProjectDetection['httpClient'];\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 let hasTests = !!dependencies.vitest;\n if (!hasTests) {\n try {\n await access(path.join(projectPath, 'vitest.config.ts'));\n hasTests = true;\n } catch {\n /* no vitest config */\n }\n }\n\n return { hasRedux, httpClient, hasI18n, hasTests };\n } catch (error) {\n throw new Error(`Failed to detect project setup: ${error}`, { cause: error });\n }\n};\n", "export { directoryExists, fileExistsAt } from './existence.checker';\nexport type { ProjectDetection } from './project.detector';\nexport { detectProjectSetup } from './project.detector';\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 path from 'node:path';\nimport type { Command } from 'commander';\nimport type { Ora } from 'ora';\nimport pc from 'picocolors';\nimport { log, logError, printBanner } from '../config';\nimport { startSpinner } from '../config/spinner';\nimport { deleteDirectory, fileExists } from '../core/files';\nimport { initializeGit } from '../core/git';\nimport { installDependencies, type PackageManager, runScript } from '../core/package-manager';\nimport {\n defaultProjectAnswers,\n type ProjectPrompts,\n promptForProjectDetails,\n} from '../prompts/create-app.prompt';\nimport { cleanupFeatures } from '../services/init/cleanup';\nimport { configurePackageJson } from '../services/init/config.service';\nimport { setupDevTools } from '../services/init/devtools.service';\nimport { generateLayout, generateRootProvider } from '../services/init/providers.service';\nimport { cloneTemplate } from '../services/init/template.service';\n\ninterface InitCommandOptions {\n yes?: boolean;\n packageManager?: string;\n}\n\nconst VALID_PACKAGE_MANAGERS: ReadonlyArray<PackageManager> = ['npm', 'yarn', 'pnpm', 'bun'];\n\nconst validatePackageManagerOverride = (raw: string | undefined): PackageManager | undefined => {\n if (raw === undefined) return undefined;\n if (!VALID_PACKAGE_MANAGERS.includes(raw as PackageManager)) {\n throw new Error(\n `Invalid --package-manager \"${raw}\". Valid: ${VALID_PACKAGE_MANAGERS.join(', ')}.`,\n );\n }\n return raw as PackageManager;\n};\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 .option('-y, --yes', 'Skip all prompts and use the recommended production defaults')\n .option(\n '--package-manager <pm>',\n `Override the package manager (one of: ${VALID_PACKAGE_MANAGERS.join(', ')})`,\n )\n .action(async (name: string | undefined, options: InitCommandOptions) => {\n try {\n const packageManager = validatePackageManagerOverride(options.packageManager);\n await createApp(name, { yes: options.yes ?? false, packageManager });\n } catch (err) {\n logError(`${err instanceof Error ? err.message : err}`);\n process.exit(1);\n }\n });\n};\n\n/**\n * Run a step with a dedicated spinner, ensuring at most one is active at a\n * time. Sub-services that manage their own spinners must be called\n * *outside* this helper \u2014 wrapping them would create concurrent spinners\n * (ora 9.4+ surfaces this as a runtime warning).\n */\nconst withStepSpinner = async <T>(\n text: string,\n successText: string,\n fn: () => Promise<T>,\n ref: { current: Ora | null },\n): Promise<T> => {\n const spinner = startSpinner(text);\n ref.current = spinner;\n try {\n const result = await fn();\n spinner.succeed(successText);\n return result;\n } finally {\n if (ref.current === spinner) ref.current = null;\n }\n};\n\ninterface CreateAppFlags {\n yes: boolean;\n packageManager?: PackageManager;\n}\n\nconst summariseDefaults = (answers: ProjectPrompts): void => {\n const features: string[] = [];\n if (answers.darkMode) features.push('dark mode');\n if (answers.redux) features.push('redux');\n if (answers.i18n) features.push('i18n');\n if (answers.tests) features.push('tests');\n if (answers.reactCompiler) features.push('react-compiler');\n if (answers.preCommitHooks) features.push('pre-commit hooks');\n if (answers.commitizen) features.push('commitizen');\n if (answers.httpClient !== 'none') features.push(`http (${answers.httpClient})`);\n\n log(pc.dim('Defaults applied (run `next-maker remove <feature>` to undo any of them):'));\n log(pc.dim(` package manager : ${answers.packageManager}`));\n log(pc.dim(` features : ${features.join(', ')}`));\n log('');\n};\n\nconst createApp = async (initialName: string | undefined, flags: CreateAppFlags): Promise<void> => {\n printBanner();\n\n let answers: ProjectPrompts;\n if (flags.yes) {\n answers = defaultProjectAnswers(initialName, {\n packageManager: flags.packageManager,\n });\n log(pc.cyan(`\u2728 Bootstrapping ${answers.projectName} with the recommended defaults`));\n log('');\n summariseDefaults(answers);\n } else {\n log('Welcome to the Teispace Next.js App Creator!');\n log('');\n answers = await promptForProjectDetails(initialName);\n if (flags.packageManager) {\n answers = { ...answers, packageManager: flags.packageManager };\n }\n }\n\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 // Tracks the *currently* active spinner (if any) so signal/cleanup can\n // halt it cleanly. Only one of our spinners is alive at a time.\n const active: { current: Ora | null } = { current: null };\n\n const performCleanup = async () => {\n if (fileExists(projectPath)) {\n active.current?.stop();\n active.current = null;\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 const handleSignal = async () => {\n console.log(pc.red('\\nProcess interrupted. Cleaning up...'));\n await performCleanup();\n process.exit(1);\n };\n\n process.on('SIGINT', handleSignal);\n process.on('SIGTERM', handleSignal);\n\n try {\n // 1\u20133. Each of these owns its own spinner; do not wrap them.\n await cloneTemplate(projectPath);\n await configurePackageJson(projectPath, answers);\n await cleanupFeatures(projectPath, answers);\n\n // 4. Providers + layout \u2014 silent under one outer spinner.\n await withStepSpinner(\n 'Generating providers and layout...',\n 'Providers and layout generated.',\n async () => {\n await generateRootProvider(projectPath, answers);\n await generateLayout(projectPath, answers);\n },\n active,\n );\n\n // 5. DevTools (community files, Docker, hooks, etc.) \u2014 no inner spinners.\n await withStepSpinner(\n 'Setting up developer tools...',\n 'Developer tools configured.',\n () => setupDevTools(projectPath, answers),\n active,\n );\n\n // 6. Git\n await withStepSpinner(\n 'Initializing Git...',\n 'Git initialized.',\n () => initializeGit(projectPath, answers.gitRemote, answers.pushToRemote),\n active,\n );\n\n // 7. Install\n await withStepSpinner(\n 'Installing dependencies...',\n 'Dependencies installed.',\n () => installDependencies(projectPath, answers.packageManager),\n active,\n );\n\n // 8. Format + Lint (biome check --write does both)\n await withStepSpinner(\n 'Formatting and linting...',\n 'Formatted.',\n () => runScript(projectPath, answers.packageManager, 'lint:fix'),\n active,\n );\n\n // 9. Copy .env.example \u2192 .env (cheap, no spinner needed)\n if (answers.copyEnv) {\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 process.off('SIGINT', handleSignal);\n process.off('SIGTERM', handleSignal);\n\n log('');\n log(pc.green(`\u2728 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 active.current?.fail('Failed to create project.');\n active.current = null;\n console.error(err);\n await performCleanup();\n process.exit(1);\n }\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", "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", "import ora, { type Options, type Ora } 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", "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 './errorHandlers';\nexport * from './output';\nexport * from './spinner';\nexport * from './utils';\n\n// Re-export spinner instance\nimport ora from 'ora';\nexport const spinner = ora();\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}`, { cause: 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}`, { cause: 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\nconst getDevFlag = (manager: PackageManager): string => {\n switch (manager) {\n case 'npm':\n return '--save-dev';\n case 'yarn':\n case 'pnpm':\n case 'bun':\n return '-D';\n default:\n return '--save-dev';\n }\n};\n\nexport const installDevPackages = async (\n cwd: string,\n manager: PackageManager,\n packages: string[],\n): Promise<void> => {\n if (packages.length === 0) return;\n const installCommand = getInstallCommand(manager);\n const flag = getDevFlag(manager);\n const command = `${installCommand} ${flag} ${packages.join(' ')}`;\n try {\n await execAsync(command, { cwd });\n } catch (error) {\n throw new Error(`Failed to install dev packages with ${manager}: ${error}`, { cause: error });\n }\n};\n\nexport const installDevPackage = async (cwd: string, packageName: string): Promise<void> => {\n const manager = await detectPackageManager(cwd);\n await installDevPackages(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}`, { cause: 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 Enquirer from 'enquirer';\nimport type { PackageManager } from '../core/package-manager';\n\nconst PROJECT_NAME_RE = /^[a-z0-9-_]+$/;\nconst SEMVER_RE = /^\\d+\\.\\d+\\.\\d+$/;\n\nconst isValidProjectName = (value: string): boolean => PROJECT_NAME_RE.test(value);\nconst isValidSemver = (value: string): boolean => SEMVER_RE.test(value);\n\n/**\n * The opinionated production defaults `init --yes` ships. Mirrors the\n * \"should I include X?\" answer the prompt walkthrough would suggest as\n * `initial`/`default` for each question \u2014 every architecture feature ON,\n * the heavyweight integrations (Docker, GitHub Actions, bundle analyzer)\n * OFF. Users who want a leaner install run `next-maker remove <feature>`\n * after init.\n */\nexport const defaultProjectAnswers = (\n initialName: string | undefined,\n overrides: Partial<ProjectPrompts> = {},\n): ProjectPrompts => {\n const projectName = overrides.projectName ?? initialName ?? 'my-app';\n if (!isValidProjectName(projectName)) {\n throw new Error(\n `Invalid project name \"${projectName}\". Use lowercase letters, digits, hyphens, and underscores only.`,\n );\n }\n const version = overrides.version ?? '0.1.0';\n if (!isValidSemver(version)) {\n throw new Error(`Invalid version \"${version}\". Expected semver (e.g. 0.1.0).`);\n }\n\n const author = overrides.author ?? 'Teispace';\n const company = overrides.company ?? author;\n\n return {\n projectName,\n description: overrides.description ?? 'A Next.js application',\n author,\n version,\n packageManager: overrides.packageManager ?? 'yarn',\n gitRemote: overrides.gitRemote ?? '',\n pushToRemote: overrides.pushToRemote ?? false,\n gitIssues: overrides.gitIssues ?? '',\n gitHomepage: overrides.gitHomepage ?? '',\n httpClient: overrides.httpClient ?? 'fetch',\n reactSecureStorage: overrides.reactSecureStorage ?? true,\n email: overrides.email ?? 'support@example.com',\n company,\n keepTemplates: overrides.keepTemplates ?? false,\n darkMode: overrides.darkMode ?? true,\n redux: overrides.redux ?? true,\n i18n: overrides.i18n ?? true,\n communityFiles: overrides.communityFiles ?? [],\n readme: overrides.readme ?? true,\n docker: overrides.docker ?? false,\n containerName: overrides.containerName,\n imageName: overrides.imageName,\n imageTag: overrides.imageTag,\n ci: overrides.ci ?? false,\n preCommitHooks: overrides.preCommitHooks ?? true,\n commitizen: overrides.commitizen ?? true,\n copyEnv: overrides.copyEnv ?? true,\n tests: overrides.tests ?? true,\n reactCompiler: overrides.reactCompiler ?? true,\n bundleAnalyzer: overrides.bundleAnalyzer ?? false,\n };\n};\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 tests: boolean;\n reactCompiler: boolean;\n bundleAnalyzer: 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 + @teispace/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: 'confirm',\n name: 'tests',\n message: 'Do you want to include testing setup (Vitest + React Testing Library)?',\n initial: true,\n },\n {\n type: 'confirm',\n name: 'reactCompiler',\n message: 'Do you want to enable the React Compiler?',\n initial: true,\n },\n {\n type: 'confirm',\n name: 'bundleAnalyzer',\n message: 'Do you want to include @next/bundle-analyzer?',\n initial: false,\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 path from 'node:path';\nimport { writeFile } from '../../core/files';\n\nexport type TestUtilsFeatures = {\n redux: boolean;\n i18n: boolean;\n};\n\n/**\n * Emit `test/test-utils.tsx` tailored to the currently-enabled features.\n * Selected between four pre-baked variants so the output stays readable and\n * the cross-feature edge cases (redux-only / i18n-only / neither) produce\n * a file that actually type-checks.\n */\nexport const writeTestUtils = async (\n projectPath: string,\n features: TestUtilsFeatures,\n): Promise<void> => {\n const content = pickTemplate(features);\n await writeFile(path.join(projectPath, 'test/test-utils.tsx'), content);\n};\n\nconst pickTemplate = ({ redux, i18n }: TestUtilsFeatures): string => {\n if (redux && i18n) return BOTH;\n if (redux) return REDUX_ONLY;\n if (i18n) return I18N_ONLY;\n return MINIMAL;\n};\n\nconst BOTH = `import { type RenderOptions, render } from '@testing-library/react';\nimport { NextIntlClientProvider } from 'next-intl';\nimport type { ReactElement, ReactNode } from 'react';\nimport { Provider } from 'react-redux';\nimport { type AppState, type AppStore, makeStore } from '@/store';\nimport type { SupportedLocale } from '@/types/i18n';\n\ntype TestProvidersProps = {\n children: ReactNode;\n store?: AppStore;\n preloadedState?: Partial<AppState>;\n messages?: Record<string, unknown>;\n locale?: SupportedLocale;\n};\n\nexport function TestProviders({\n children,\n store,\n preloadedState,\n messages = {},\n locale = 'en',\n}: TestProvidersProps) {\n const testStore = store ?? makeStore(preloadedState);\n\n return (\n <Provider store={testStore}>\n <NextIntlClientProvider locale={locale} messages={messages} timeZone=\"UTC\">\n {children}\n </NextIntlClientProvider>\n </Provider>\n );\n}\n\ntype ExtendedRenderOptions = Omit<RenderOptions, 'wrapper'> & {\n store?: AppStore;\n preloadedState?: Partial<AppState>;\n messages?: Record<string, unknown>;\n locale?: SupportedLocale;\n};\n\nexport function renderWithProviders(\n ui: ReactElement,\n { store, preloadedState, messages, locale, ...renderOptions }: ExtendedRenderOptions = {},\n) {\n const testStore = store ?? makeStore(preloadedState);\n\n return {\n store: testStore,\n ...render(ui, {\n wrapper: ({ children }) => (\n <TestProviders store={testStore} messages={messages} locale={locale}>\n {children}\n </TestProviders>\n ),\n ...renderOptions,\n }),\n };\n}\n\nexport * from '@testing-library/react';\nexport { default as userEvent } from '@testing-library/user-event';\n`;\n\nconst REDUX_ONLY = `import { type RenderOptions, render } from '@testing-library/react';\nimport type { ReactElement, ReactNode } from 'react';\nimport { Provider } from 'react-redux';\nimport { type AppState, type AppStore, makeStore } from '@/store';\n\ntype TestProvidersProps = {\n children: ReactNode;\n store?: AppStore;\n preloadedState?: Partial<AppState>;\n};\n\nexport function TestProviders({ children, store, preloadedState }: TestProvidersProps) {\n const testStore = store ?? makeStore(preloadedState);\n\n return <Provider store={testStore}>{children}</Provider>;\n}\n\ntype ExtendedRenderOptions = Omit<RenderOptions, 'wrapper'> & {\n store?: AppStore;\n preloadedState?: Partial<AppState>;\n};\n\nexport function renderWithProviders(\n ui: ReactElement,\n { store, preloadedState, ...renderOptions }: ExtendedRenderOptions = {},\n) {\n const testStore = store ?? makeStore(preloadedState);\n\n return {\n store: testStore,\n ...render(ui, {\n wrapper: ({ children }) => <TestProviders store={testStore}>{children}</TestProviders>,\n ...renderOptions,\n }),\n };\n}\n\nexport * from '@testing-library/react';\nexport { default as userEvent } from '@testing-library/user-event';\n`;\n\nconst I18N_ONLY = `import { type RenderOptions, render } from '@testing-library/react';\nimport { NextIntlClientProvider } from 'next-intl';\nimport type { ReactElement, ReactNode } from 'react';\nimport type { SupportedLocale } from '@/types/i18n';\n\ntype TestProvidersProps = {\n children: ReactNode;\n messages?: Record<string, unknown>;\n locale?: SupportedLocale;\n};\n\nexport function TestProviders({ children, messages = {}, locale = 'en' }: TestProvidersProps) {\n return (\n <NextIntlClientProvider locale={locale} messages={messages} timeZone=\"UTC\">\n {children}\n </NextIntlClientProvider>\n );\n}\n\ntype ExtendedRenderOptions = Omit<RenderOptions, 'wrapper'> & {\n messages?: Record<string, unknown>;\n locale?: SupportedLocale;\n};\n\nexport function renderWithProviders(\n ui: ReactElement,\n { messages, locale, ...renderOptions }: ExtendedRenderOptions = {},\n) {\n return render(ui, {\n wrapper: ({ children }) => (\n <TestProviders messages={messages} locale={locale}>\n {children}\n </TestProviders>\n ),\n ...renderOptions,\n });\n}\n\nexport * from '@testing-library/react';\nexport { default as userEvent } from '@testing-library/user-event';\n`;\n\nconst MINIMAL = `import { type RenderOptions, render } from '@testing-library/react';\nimport type { ReactElement, ReactNode } from 'react';\n\ntype TestProvidersProps = {\n children: ReactNode;\n};\n\nexport function TestProviders({ children }: TestProvidersProps) {\n return <>{children}</>;\n}\n\ntype ExtendedRenderOptions = Omit<RenderOptions, 'wrapper'>;\n\nexport function renderWithProviders(ui: ReactElement, options: ExtendedRenderOptions = {}) {\n return render(ui, {\n wrapper: ({ children }) => <TestProviders>{children}</TestProviders>,\n ...options,\n });\n}\n\nexport * from '@testing-library/react';\nexport { default as userEvent } from '@testing-library/user-event';\n`;\n", "import path from 'node:path';\nimport { PACKAGES } from '../../../config/packages';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { fileExists, readFile, updateJson, writeFile } from '../../../core/files';\nimport type { ProjectPrompts } from '../../../prompts/create-app.prompt';\n\nexport const cleanupBundleAnalyzer = async (\n projectPath: string,\n answers: ProjectPrompts,\n): Promise<void> => {\n if (answers.bundleAnalyzer) return;\n\n const nextConfigPath = path.join(projectPath, PROJECT_PATHS.NEXT_CONFIG);\n if (fileExists(nextConfigPath)) {\n let content = await readFile(nextConfigPath);\n content = content.replace(\n /import\\s+withBundleAnalyzer\\s+from\\s+'@next\\/bundle-analyzer';\\n/,\n '',\n );\n content = content.replace(\n /const\\s+bundleAnalyzer\\s*=\\s*withBundleAnalyzer\\(\\{[\\s\\S]*?\\}\\);\\n+/,\n '',\n );\n // Unwrap any `bundleAnalyzer(...)` call inside `export default`.\n content = content.replace(/bundleAnalyzer\\(([^)]*)\\)/, '$1');\n await writeFile(nextConfigPath, content);\n }\n\n await updateJson(path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON), (pkg) => {\n if (pkg.devDependencies) {\n delete pkg.devDependencies[PACKAGES.NEXT_BUNDLE_ANALYZER];\n }\n if (pkg.scripts) {\n delete pkg.scripts.analyze;\n }\n return pkg;\n });\n};\n", "export const PACKAGES = {\n // Dependencies\n REDUX_TOOLKIT: '@reduxjs/toolkit',\n REACT_REDUX: 'react-redux',\n REDUX: 'redux',\n REDUX_PERSIST: 'redux-persist',\n REACT_SECURE_STORAGE: 'react-secure-storage',\n NEXT_INTL: 'next-intl',\n NEXT_THEMES: '@teispace/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\n // Testing\n VITEST: 'vitest',\n JSDOM: 'jsdom',\n VITE_PLUGIN_REACT: '@vitejs/plugin-react',\n TESTING_LIBRARY_DOM: '@testing-library/dom',\n TESTING_LIBRARY_JEST_DOM: '@testing-library/jest-dom',\n TESTING_LIBRARY_REACT: '@testing-library/react',\n TESTING_LIBRARY_USER_EVENT: '@testing-library/user-event',\n\n // Optional tooling\n REACT_COMPILER_BABEL: 'babel-plugin-react-compiler',\n NEXT_BUNDLE_ANALYZER: '@next/bundle-analyzer',\n} as const;\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { deleteFile, fileExists, readFile, writeFile } from '../../../core/files';\nimport type { ProjectPrompts } from '../../../prompts/create-app.prompt';\n\nexport const cleanupDarkMode = async (\n projectPath: string,\n answers: ProjectPrompts,\n): Promise<void> => {\n if (answers.darkMode) return;\n\n await deleteFile(path.join(projectPath, PROJECT_PATHS.THEME_PROVIDER));\n await removeThemeProviderExport(projectPath);\n await removeDarkModeCSS(projectPath);\n // Strip dark-mode classes from whichever layout is present. generateLayout\n // overwrites src/app/layout.tsx when i18n is off, so we focus on [locale]/layout.tsx\n // but handle both for robustness.\n await removeDarkModeFromLayout(projectPath);\n};\n\nconst removeThemeProviderExport = async (projectPath: string): Promise<void> => {\n const providersIndexPath = path.join(projectPath, PROJECT_PATHS.PROVIDERS_INDEX);\n let content = await readFile(providersIndexPath);\n content = content.replace(/export \\* from '\\.\\/CustomThemeProvider';\\n/, '');\n await writeFile(providersIndexPath, content);\n};\n\nconst removeDarkModeCSS = async (projectPath: string): Promise<void> => {\n const globalsCssPath = path.join(projectPath, PROJECT_PATHS.GLOBALS_CSS);\n if (fileExists(globalsCssPath)) {\n let content = await readFile(globalsCssPath);\n content = content.replace(/@custom-variant dark \\(.*?\\);\\n\\n/, '');\n content = content.replace(/@theme \\{[\\s\\S]*?\\}\\n/, '');\n await writeFile(globalsCssPath, content);\n }\n};\n\nconst stripDarkModeClasses = (content: string): string => {\n // Template layouts use \"bg-light antialiased dark:bg-dark\" in various orderings.\n // Drop the bg-light and dark:bg-dark tokens and collapse stray whitespace.\n return content\n .replace(/\\bbg-light\\b\\s?/g, '')\n .replace(/\\bdark:bg-dark\\b\\s?/g, '')\n .replace(/\\s{2,}/g, ' ')\n .replace(/suppressHydrationWarning=\\{true\\}/g, '');\n};\n\nconst removeDarkModeFromLayout = async (projectPath: string): Promise<void> => {\n const layoutPaths = [\n path.join(projectPath, PROJECT_PATHS.ROOT_LAYOUT),\n path.join(projectPath, 'src/app/[locale]/layout.tsx'),\n ];\n\n for (const layoutPath of layoutPaths) {\n if (fileExists(layoutPath)) {\n const original = await readFile(layoutPath);\n const updated = stripDarkModeClasses(original);\n if (updated !== original) {\n await writeFile(layoutPath, updated);\n }\n }\n }\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { deleteDirectory, deleteFile, fileExists, readFile, writeFile } from '../../../core/files';\nimport type { ProjectPrompts } from '../../../prompts/create-app.prompt';\nimport { cleanupHttpTypes } from '../../setup/http-client/injectors';\n\nexport const cleanupHttpClient = async (\n projectPath: string,\n answers: ProjectPrompts,\n): 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 cleanupNoHttpClient(projectPath, httpUtilsPath, keepSecureStorage);\n } else if (answers.httpClient === 'axios') {\n await cleanupFetchClient(projectPath, httpUtilsPath);\n } else if (answers.httpClient === 'fetch') {\n await cleanupAxiosClient(projectPath, httpUtilsPath);\n }\n};\n\nconst cleanupNoHttpClient = async (\n projectPath: string,\n httpUtilsPath: string,\n keepSecureStorage: boolean,\n): Promise<void> => {\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 await deleteFile(path.join(projectPath, PROJECT_PATHS.CLIENT_UTILS));\n await cleanupHttpTypes(projectPath, []);\n } else {\n await deleteDirectory(httpUtilsPath);\n await removeHttpExports(projectPath);\n await deleteFile(path.join(projectPath, PROJECT_PATHS.APP_APIS));\n await removeAppApisExport(projectPath);\n }\n\n await removeApiConstants(projectPath);\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.ERRORS_DIR));\n\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 await removeTypesExports(projectPath);\n }\n};\n\nconst cleanupFetchClient = async (projectPath: string, httpUtilsPath: string): Promise<void> => {\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 const httpTypesPath = path.join(projectPath, PROJECT_PATHS.HTTP_TYPES);\n if (fileExists(httpTypesPath)) {\n let typesContent = await readFile(httpTypesPath);\n typesContent = typesContent.replace(/export interface FetchClientOptions \\{[\\s\\S]*?\\}\\n\\n/, '');\n typesContent = typesContent.replace(\n /export interface ExtendedRequestInit extends RequestInit \\{[\\s\\S]*?\\}\\n\\n/,\n '',\n );\n await writeFile(httpTypesPath, typesContent);\n }\n};\n\nconst cleanupAxiosClient = async (projectPath: string, httpUtilsPath: string): Promise<void> => {\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 await cleanupHttpTypes(projectPath, ['fetch']);\n\n const httpTypesPath = path.join(projectPath, PROJECT_PATHS.HTTP_TYPES);\n if (fileExists(httpTypesPath)) {\n let typesContent = await readFile(httpTypesPath);\n typesContent = typesContent.replace(/export interface AxiosClientOptions \\{[\\s\\S]*?\\}\\n\\n/, '');\n await writeFile(httpTypesPath, typesContent);\n }\n};\n\nconst removeHttpExports = 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 content = content.replace(/export \\* from '\\.\\/http';\\n/, '');\n await writeFile(utilsIndexPath, content);\n }\n};\n\nconst removeAppApisExport = 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 content = content.replace(/export \\* from '\\.\\/app-apis';\\n/, '');\n await writeFile(configIndexPath, content);\n }\n};\n\nconst removeApiConstants = async (projectPath: string): Promise<void> => {\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\nconst removeTypesExports = 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 content = content.replace(/export \\* from '\\.\\/utility';\\n/, '');\n content = content.replace(/export \\* from '\\.\\/common';\\n/, '');\n await writeFile(typesIndexPath, content);\n }\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { deleteDirectory, deleteFile, fileExists, readFile, writeFile } from '../../../core/files';\nimport type { ProjectPrompts } from '../../../prompts/create-app.prompt';\n\nexport const cleanupI18n = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n if (answers.i18n) return;\n\n await deleteI18nFiles(projectPath);\n await removeI18nExports(projectPath);\n await removeI18nFromNextConfig(projectPath);\n await removeI18nFromCounter(projectPath);\n await removeI18nFromEnv(projectPath);\n};\n\nconst removeI18nFromEnv = async (projectPath: string): Promise<void> => {\n const envPath = path.join(projectPath, PROJECT_PATHS.ENV_EXAMPLE);\n if (!fileExists(envPath)) return;\n let content = await readFile(envPath);\n // Strip the DEFAULT_TIMEZONE/DEFAULT_LOCALE blocks (incl. their comment headers).\n content = content.replace(/#[^\\n]*IANA time zone[\\s\\S]*?DEFAULT_TIMEZONE=[^\\n]*\\n?/, '');\n content = content.replace(/#[^\\n]*Fallback locale[\\s\\S]*?DEFAULT_LOCALE=[^\\n]*\\n?/, '');\n // Fallback cleanup if the comments changed/were removed.\n content = content.replace(/^DEFAULT_TIMEZONE=.*\\n?/m, '');\n content = content.replace(/^DEFAULT_LOCALE=.*\\n?/m, '');\n await writeFile(envPath, content);\n};\n\nconst deleteI18nFiles = async (projectPath: string): Promise<void> => {\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\nconst removeI18nExports = 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 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\nconst removeI18nFromNextConfig = 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 content = content.replace(/import createNextIntlPlugin from 'next-intl\\/plugin';\\n/, '');\n content = content.replace(/const withNextIntl = createNextIntlPlugin\\(\\);\\n+/, '');\n // Unwrap withNextIntl(...) wherever it appears \u2014 the arg may itself be\n // a call like bundleAnalyzer(...) depending on enabled features.\n content = content.replace(/withNextIntl\\(([^)]+)\\)/, '$1');\n await writeFile(nextConfigPath, content);\n }\n};\n\nconst removeI18nFromCounter = async (projectPath: string): Promise<void> => {\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(\n /\\{t\\('currentCount',\\s*\\{\\s*count:\\s*value\\s*\\}\\)\\}/g,\n 'Current Count: {value}',\n );\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 // Counter.test.tsx and test-utils.tsx both depend on i18n \u2014 delete them\n // to avoid dangling references. Users can re-introduce tests later.\n const counterTestPath = path.join(\n projectPath,\n 'src/features/counter/components/Counter.test.tsx',\n );\n const testUtilsPath = path.join(projectPath, 'test/test-utils.tsx');\n await deleteFile(counterTestPath);\n await deleteFile(testUtilsPath);\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { deleteDirectory, deleteFile } from '../../../core/files';\nimport type { ProjectPrompts } from '../../../prompts/create-app.prompt';\n\nexport const 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\nexport const cleanupLicense = async (projectPath: string): Promise<void> => {\n await deleteFile(path.join(projectPath, PROJECT_PATHS.LICENSE));\n};\n\nexport const cleanupChangelog = async (projectPath: string): Promise<void> => {\n await deleteFile(path.join(projectPath, PROJECT_PATHS.CHANGELOG));\n};\n\nexport const 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\n/**\n * Remove template-specific directories that should not ship in generated projects.\n * - .claude/ \u2014 Claude Code workspace config from the starter template\n * - docs/ \u2014 Starter template documentation (structure.md etc.)\n * - .vscode/ \u2014 IDE-specific settings from the starter\n */\nexport const cleanupTemplateArtifacts = async (projectPath: string): Promise<void> => {\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.CLAUDE_DIR));\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.DOCS_DIR));\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.VSCODE_DIR));\n};\n", "import path from 'node:path';\nimport { PACKAGES } from '../../../config/packages';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { fileExists, readFile, updateJson, writeFile } from '../../../core/files';\nimport type { ProjectPrompts } from '../../../prompts/create-app.prompt';\n\nexport const cleanupReactCompiler = async (\n projectPath: string,\n answers: ProjectPrompts,\n): Promise<void> => {\n if (answers.reactCompiler) return;\n\n const nextConfigPath = path.join(projectPath, PROJECT_PATHS.NEXT_CONFIG);\n if (fileExists(nextConfigPath)) {\n let content = await readFile(nextConfigPath);\n content = content.replace(/^\\s*reactCompiler:\\s*true,?\\n/m, '');\n await writeFile(nextConfigPath, content);\n }\n\n await updateJson(path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON), (pkg) => {\n if (pkg.devDependencies) {\n delete pkg.devDependencies[PACKAGES.REACT_COMPILER_BABEL];\n }\n return pkg;\n });\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { deleteDirectory, deleteFile, fileExists, readFile, writeFile } from '../../../core/files';\nimport type { ProjectPrompts } from '../../../prompts/create-app.prompt';\n\nexport const cleanupRedux = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n if (answers.redux) return;\n\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 // test-utils.tsx imports @/store \u2014 drop it so the template still builds.\n await deleteFile(path.join(projectPath, 'test/test-utils.tsx'));\n\n await removeStoreProviderExport(projectPath);\n await removeCounterFromPages(projectPath);\n};\n\nconst removeStoreProviderExport = async (projectPath: string): Promise<void> => {\n const providersIndexPath = path.join(projectPath, PROJECT_PATHS.PROVIDERS_INDEX);\n let content = await readFile(providersIndexPath);\n content = content.replace(/export \\* from '\\.\\/StoreProvider';\\n/, '');\n await writeFile(providersIndexPath, content);\n};\n\nconst removeCounterFromPages = async (projectPath: string): Promise<void> => {\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", "import path from 'node:path';\nimport { PACKAGES } from '../../../config/packages';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { deleteDirectory, deleteFile, updateJson } from '../../../core/files';\nimport type { ProjectPrompts } from '../../../prompts/create-app.prompt';\n\nconst TEST_DEVDEPS = [\n PACKAGES.VITEST,\n PACKAGES.JSDOM,\n PACKAGES.VITE_PLUGIN_REACT,\n PACKAGES.TESTING_LIBRARY_DOM,\n PACKAGES.TESTING_LIBRARY_JEST_DOM,\n PACKAGES.TESTING_LIBRARY_REACT,\n PACKAGES.TESTING_LIBRARY_USER_EVENT,\n];\n\nexport const cleanupTests = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n if (answers.tests) return;\n\n await deleteFile(path.join(projectPath, PROJECT_PATHS.VITEST_CONFIG));\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.TEST_DIR));\n // Counter.test.tsx may still exist when i18n is enabled but tests are off.\n await deleteFile(path.join(projectPath, 'src/features/counter/components/Counter.test.tsx'));\n\n await updateJson(path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON), (pkg) => {\n if (pkg.devDependencies) {\n for (const dep of TEST_DEVDEPS) delete pkg.devDependencies[dep];\n }\n if (pkg.scripts) {\n delete pkg.scripts.test;\n delete pkg.scripts['test:watch'];\n delete pkg.scripts['test:coverage'];\n // Drop the `test` step from the validate chain.\n // Negative lookahead guards against matching `test:watch` / `test:coverage`.\n if (typeof pkg.scripts.validate === 'string') {\n pkg.scripts.validate = pkg.scripts.validate\n .replace(/\\s*&&\\s*yarn\\s+test(?![:\\w])/, '')\n .replace(/\\byarn\\s+test(?![:\\w])\\s*&&\\s*/, '');\n }\n }\n return pkg;\n });\n};\n", "import { startSpinner } from '../../../config/spinner';\nimport type { ProjectPrompts } from '../../../prompts/create-app.prompt';\nimport { writeTestUtils } from '../../common/test-utils';\nimport { cleanupBundleAnalyzer } from './bundle-analyzer.cleanup';\nimport { cleanupDarkMode } from './dark-mode.cleanup';\nimport { cleanupHttpClient } from './http.cleanup';\nimport { cleanupI18n } from './i18n.cleanup';\nimport {\n cleanupChangelog,\n cleanupConfig,\n cleanupLicense,\n cleanupSecureStorage,\n cleanupTemplateArtifacts,\n} from './misc.cleanup';\nimport { cleanupReactCompiler } from './react-compiler.cleanup';\nimport { cleanupRedux } from './redux.cleanup';\nimport { cleanupTests } from './tests.cleanup';\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 // next.config.ts modifiers: run bundle-analyzer first (unwraps the outer\n // call), then i18n (unwraps withNextIntl), then react-compiler.\n await cleanupBundleAnalyzer(projectPath, answers);\n await cleanupI18n(projectPath, answers);\n await cleanupReactCompiler(projectPath, answers);\n await cleanupTests(projectPath, answers);\n await cleanupLicense(projectPath);\n await cleanupChangelog(projectPath);\n await cleanupConfig(projectPath);\n await cleanupTemplateArtifacts(projectPath);\n // Rebuild test-utils only if tests are kept. redux/i18n cleanups delete\n // the template version whenever their feature is dropped, so the file\n // shape may not match the final feature set \u2014 regenerate from scratch.\n if (answers.tests) {\n await writeTestUtils(projectPath, { redux: answers.redux, i18n: answers.i18n });\n }\n spinner.succeed('Features customized.');\n } catch (error) {\n spinner.fail('Failed to customize features.');\n throw error;\n }\n};\n", "import path from 'node:path';\nimport { PACKAGES } from '../../config/packages';\nimport { PROJECT_PATHS } from '../../config/paths';\nimport { startSpinner } from '../../config/spinner';\nimport { updateJson } from '../../core/files';\nimport type { ProjectPrompts } from '../../prompts/create-app.prompt';\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];\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", "import { readdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport { PACKAGES } from '../../config/packages';\nimport { PROJECT_PATHS } from '../../config/paths';\nimport {\n deleteDirectory,\n deleteFile,\n fileExists,\n readFile,\n updateJson,\n writeFile,\n} from '../../core/files';\nimport type { ProjectPrompts } from '../../prompts/create-app.prompt';\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 path from 'node:path';\nimport { PROJECT_PATHS } from '../../config/paths';\nimport { writeFile } from '../../core/files';\nimport type { ProjectPrompts } from '../../prompts/create-app.prompt';\n\nexport const generateRootProvider = async (\n projectPath: string,\n answers: ProjectPrompts,\n): Promise<void> => {\n const imports: string[] = [];\n\n if (answers.i18n) {\n imports.push(\"import { type AbstractIntlMessages, NextIntlClientProvider } from 'next-intl';\");\n }\n\n if (answers.darkMode) {\n imports.push(\"import { CustomThemeProvider } from '@/providers';\");\n }\n\n if (answers.redux) {\n imports.push(\"import type { AppState } from '@/store';\");\n }\n\n if (answers.i18n) {\n imports.push(\"import type { SupportedLocale } from '@/types/i18n';\");\n }\n\n if (answers.redux) {\n imports.push(\"import { StoreProvider } from './StoreProvider';\");\n }\n\n const propsFields: string[] = ['children: React.ReactNode;'];\n const destructureFields: string[] = ['children'];\n\n if (answers.i18n) {\n propsFields.push('locale: SupportedLocale;');\n propsFields.push('messages: AbstractIntlMessages;');\n propsFields.push('timeZone: string;');\n destructureFields.push('locale', 'messages', 'timeZone');\n }\n\n if (answers.redux) {\n propsFields.push('preloadedState?: Partial<AppState>;');\n destructureFields.push('preloadedState');\n }\n\n // Build the nested JSX from innermost to outermost\n let jsx = '{children}';\n\n if (answers.i18n) {\n jsx = `<NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>\n ${jsx}\n </NextIntlClientProvider>`;\n }\n\n if (answers.darkMode) {\n jsx = `<CustomThemeProvider>\n ${jsx}\n </CustomThemeProvider>`;\n }\n\n if (answers.redux) {\n jsx = `<StoreProvider preloadedState={preloadedState}>\n ${jsx}\n </StoreProvider>`;\n }\n\n // Ensure a valid JSX expression even with no wrappers\n if (jsx === '{children}') {\n jsx = '<>{children}</>';\n }\n\n const propsType = `type RootProviderProps = {\n ${propsFields.join('\\n ')}\n};`;\n\n const rootProviderContent = `'use client';\n${imports.join('\\n')}\n\n${propsType}\n\nexport const RootProvider = ({ ${destructureFields.join(', ')} }: RootProviderProps) => {\n return (\n ${jsx}\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) return;\n\n const htmlClasses = `\\`\\${livvic.variable} ${answers.darkMode ? 'bg-light antialiased dark:bg-dark' : 'antialiased'}\\``;\n const providerPropsLine = answers.redux ? '' : '';\n\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\"${answers.darkMode ? ' suppressHydrationWarning={true}' : ''}>\n <body className={${htmlClasses}}>\n <RootProvider${providerPropsLine}>\n {children}\n </RootProvider>\n </body>\n </html>\n );\n}\n`;\n await writeFile(path.join(projectPath, PROJECT_PATHS.ROOT_LAYOUT), basicLayout);\n\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", "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 type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { kebabToPascal } from '../config/utils';\nimport { detectProjectSetup } from '../detection';\nimport { generateComponent, generateTest } from '../generators';\nimport { promptForComponentDetails } from '../prompts/component.prompt';\n\ninterface ComponentCommandOptions {\n client?: boolean;\n i18n?: boolean;\n feature?: string;\n test?: boolean;\n noTest?: boolean;\n}\n\nexport const registerComponentCommand = (program: Command) => {\n program\n .command('component [name]')\n .description('Generate a shared component')\n .option('--client', \"Add 'use client' directive\")\n .option('--i18n', 'Add useTranslations hook')\n .option('--feature <path>', 'Generate in feature directory (e.g., src/features/auth)')\n .option('--test', 'Also generate a sibling test file')\n .option('--no-test', 'Skip test file generation')\n .action(async (name: string | undefined, options: ComponentCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\n log(pc.cyan('\\n\uD83E\uDDE9 Component Generator\\n'));\n\n // Detect i18n for auto-adding useTranslations\n spinner.start('Detecting project setup...');\n const detection = await detectProjectSetup(projectPath);\n spinner.succeed('Project setup detected');\n\n // Prompt \u2014 skip questions whose answers were already given via flags.\n const componentOptions = await promptForComponentDetails(name, {\n client: options.client,\n });\n const componentName = kebabToPascal(componentOptions.componentName);\n const isClient = componentOptions.isClient;\n const hasI18n = options.i18n ?? false;\n const shouldTest = resolveShouldTest(options, detection.hasTests);\n\n // Generate\n spinner.start('Generating component...');\n await generateComponent({\n name: componentOptions.componentName,\n projectPath,\n isClient: isClient || hasI18n,\n hasI18n,\n featurePath: options.feature,\n });\n spinner.succeed('Component generated');\n\n let testFile: string | null = null;\n if (shouldTest) {\n const componentFile = options.feature\n ? path.join(projectPath, options.feature, 'components', `${componentName}.tsx`)\n : path.join(\n projectPath,\n 'src/components/common',\n componentName,\n `${componentName}.tsx`,\n );\n spinner.start('Generating test...');\n testFile = await generateTest({\n projectPath,\n sourceFile: componentFile,\n kind: 'component',\n symbolName: componentName,\n hasRedux: detection.hasRedux,\n hasI18n: detection.hasI18n,\n });\n spinner.succeed('Test generated');\n }\n\n // Success\n const location = options.feature\n ? `${options.feature}/components/${componentName}.tsx`\n : `src/components/common/${componentName}/${componentName}.tsx`;\n\n log(pc.green(`\\n\u2728 Component '${componentName}' created successfully!\\n`));\n log(pc.dim(` \uD83D\uDCC4 ${location}`));\n\n if (!options.feature) {\n log(pc.dim(` \uD83D\uDCC4 src/components/common/${componentName}/index.ts`));\n log(pc.dim(` \uD83D\uDCDD Updated src/components/common/index.ts`));\n log(pc.dim(` \uD83D\uDCDD Updated src/components/index.ts`));\n }\n if (testFile) {\n log(pc.dim(` \uD83E\uDDEA ${path.relative(projectPath, testFile)}`));\n }\n\n log('');\n log(pc.cyan('Usage:'));\n if (options.feature) {\n log(\n pc.dim(\n ` import { ${componentName} } from '${options.feature.replace(/^src\\//, '@/')}/components/${componentName}';`,\n ),\n );\n } else {\n log(pc.dim(` import { ${componentName} } from '@/components';`));\n }\n log('');\n } catch (error) {\n spinner.fail('Component generation failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n\nconst resolveShouldTest = (\n options: { test?: boolean; noTest?: boolean },\n hasTests: boolean,\n): boolean => {\n if (options.noTest) return false;\n if (options.test) return true;\n // Default: co-generate when tests are already installed.\n return hasTests;\n};\n", "import { mkdir, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToPascal } from '../config/utils';\nimport { fileExists, readFile, writeFile as writeFileCore } from '../core/files';\nimport {\n componentBarrelTemplate,\n sharedComponentTemplate,\n} from './templates/shared-component.template';\n\nexport interface ComponentGeneratorOptions {\n name: string;\n projectPath: string;\n isClient: boolean;\n hasI18n: boolean;\n featurePath?: string;\n}\n\nexport const generateComponent = async (options: ComponentGeneratorOptions): Promise<void> => {\n const { name, projectPath, isClient, hasI18n, featurePath } = options;\n const componentName = kebabToPascal(name);\n\n if (featurePath) {\n await generateFeatureComponent(componentName, projectPath, featurePath, isClient, hasI18n);\n } else {\n await generateSharedComponent(componentName, name, projectPath, isClient, hasI18n);\n }\n};\n\nconst generateFeatureComponent = async (\n componentName: string,\n projectPath: string,\n featurePath: string,\n isClient: boolean,\n hasI18n: boolean,\n): Promise<void> => {\n const componentsDir = path.join(projectPath, featurePath, 'components');\n await mkdir(componentsDir, { recursive: true });\n\n await writeFile(\n path.join(componentsDir, `${componentName}.tsx`),\n sharedComponentTemplate({ componentName, isClient, hasI18n }),\n );\n};\n\nconst generateSharedComponent = async (\n componentName: string,\n _kebabName: string,\n projectPath: string,\n isClient: boolean,\n hasI18n: boolean,\n): Promise<void> => {\n const componentDir = path.join(projectPath, 'src', 'components', 'common', componentName);\n await mkdir(componentDir, { recursive: true });\n\n // Generate component file\n await writeFile(\n path.join(componentDir, `${componentName}.tsx`),\n sharedComponentTemplate({ componentName, isClient, hasI18n }),\n );\n\n // Generate folder barrel (ComponentName/index.ts)\n await writeFile(path.join(componentDir, 'index.ts'), componentBarrelTemplate({ componentName }));\n\n // Append to common/index.ts\n const commonIndexPath = path.join(projectPath, 'src', 'components', 'common', 'index.ts');\n await appendExport(commonIndexPath, `export { ${componentName} } from './${componentName}';\\n`);\n\n // Append to components/index.ts\n const rootIndexPath = path.join(projectPath, 'src', 'components', 'index.ts');\n await ensureCommonReExport(rootIndexPath);\n};\n\nconst appendExport = async (filePath: string, exportLine: string): Promise<void> => {\n let content = '';\n if (fileExists(filePath)) {\n content = await readFile(filePath);\n }\n if (!content.includes(exportLine.trim())) {\n content += exportLine;\n await writeFileCore(filePath, content);\n }\n};\n\nconst ensureCommonReExport = async (filePath: string): Promise<void> => {\n let content = '';\n if (fileExists(filePath)) {\n content = await readFile(filePath);\n }\n const commonExport = \"export * from './common';\\n\";\n if (!content.includes(commonExport.trim())) {\n content += commonExport;\n await writeFileCore(filePath, content);\n }\n};\n", "export const sharedComponentTemplate = (params: {\n componentName: string;\n isClient: boolean;\n hasI18n: boolean;\n translationNamespace?: string;\n}): string => {\n const { componentName, isClient, hasI18n } = params;\n const ns = params.translationNamespace || componentName;\n const lines: string[] = [];\n\n if (isClient || hasI18n) {\n lines.push(\"'use client';\");\n }\n\n if (hasI18n) {\n lines.push(\"import { useTranslations } from 'next-intl';\");\n }\n\n lines.push('');\n lines.push(`export function ${componentName}() {`);\n\n if (hasI18n) {\n lines.push(` const t = useTranslations('${ns}');`);\n lines.push('');\n lines.push(' return (');\n lines.push(' <div>');\n lines.push(` <h2>{t('title')}</h2>`);\n lines.push(' </div>');\n lines.push(' );');\n } else {\n lines.push(' return (');\n lines.push(' <div>');\n lines.push(` <h2>${componentName}</h2>`);\n lines.push(' </div>');\n lines.push(' );');\n }\n\n lines.push('}');\n lines.push('');\n\n return lines.join('\\n');\n};\n\nexport const componentBarrelTemplate = (params: { componentName: string }): string => {\n return `export { ${params.componentName} } from './${params.componentName}';\\n`;\n};\n", "import { writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel, kebabToPascal } from '../config/utils';\nimport { crudServiceTemplate } from './templates/crud-service.template';\nimport type { ServiceGeneratorOptions } from './types';\n\n/**\n * Generate a CRUD API service file with getAll, getById, create, update, delete methods + DTO types.\n */\nexport const generateCrudService = async (options: ServiceGeneratorOptions): Promise<void> => {\n const { name, outputPath, httpClient } = options;\n const camelName = kebabToCamel(name);\n const pascalName = kebabToPascal(name);\n\n await writeFile(\n path.join(outputPath, `${name}.service.ts`),\n crudServiceTemplate({ camelName, pascalName, httpClient }),\n );\n};\n", "export const crudServiceTemplate = (params: {\n camelName: string;\n pascalName: string;\n httpClient: 'axios' | 'fetch';\n}): string => {\n const { camelName, pascalName, httpClient } = params;\n const clientImport =\n httpClient === 'axios'\n ? `import { axiosClient } from '@/lib/utils/http';`\n : `import { fetchClient } from '@/lib/utils/http';`;\n const clientName = httpClient === 'axios' ? 'axiosClient' : 'fetchClient';\n\n return `import { AppApis } from '@/lib/config';\n${clientImport}\nimport type { ResultAsync } from '@/types';\n\n/**\n * Summary type used in list responses (e.g., cards, tables).\n */\nexport interface ${pascalName}Summary {\n id: string;\n // Add list/card fields here (title, thumbnail, status, etc.)\n}\n\n/**\n * Detail type used in single-item responses (e.g., detail page).\n */\nexport interface ${pascalName}Detail extends ${pascalName}Summary {\n // Add detailed fields here (content, metadata, relations, etc.)\n}\n\nexport interface Create${pascalName}Dto {\n // Add create fields here\n}\n\nexport interface Update${pascalName}Dto {\n // Add update fields here\n}\n\nexport const ${camelName}Service = {\n getAll: (): ResultAsync<${pascalName}Summary[]> => {\n return ${clientName}.get<${pascalName}Summary[]>(AppApis.${camelName}.getAll);\n },\n\n getById: (id: string): ResultAsync<${pascalName}Detail> => {\n return ${clientName}.get<${pascalName}Detail>(AppApis.${camelName}.getById(id));\n },\n\n create: (data: Create${pascalName}Dto): ResultAsync<${pascalName}Detail> => {\n return ${clientName}.post<${pascalName}Detail>(AppApis.${camelName}.create, data);\n },\n\n update: (id: string, data: Update${pascalName}Dto): ResultAsync<${pascalName}Detail> => {\n return ${clientName}.patch<${pascalName}Detail>(AppApis.${camelName}.update(id), data);\n },\n\n delete: (id: string): ResultAsync<void> => {\n return ${clientName}.delete<void>(AppApis.${camelName}.delete(id));\n },\n};\n`;\n};\n\nexport const crudApiConfigTemplate = (params: { camelName: string; kebabName: string }): string => {\n const { camelName, kebabName } = params;\n return ` ${camelName}: {\n base: \\`\\${API_PREFIX}/${kebabName}\\`,\n getAll: \\`\\${API_PREFIX}/${kebabName}\\`,\n getById: (id: string) => \\`\\${API_PREFIX}/${kebabName}/\\${id}\\`,\n create: \\`\\${API_PREFIX}/${kebabName}\\`,\n update: (id: string) => \\`\\${API_PREFIX}/${kebabName}/\\${id}\\`,\n delete: (id: string) => \\`\\${API_PREFIX}/${kebabName}/\\${id}\\`,\n },`;\n};\n", "import { mkdir, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToPascal } from '../config/utils';\nimport { generateService } from './service.generator';\nimport { generateSlice } from './slice.generator';\nimport { featureBarrelTemplate } from './templates/barrel.template';\nimport { componentTemplate } from './templates/component.template';\nimport { hookWithoutStoreTemplate, hookWithStoreTemplate } from './templates/hook.template';\nimport { stateTypesTemplate } from './templates/types.template';\nimport type { FeatureGeneratorOptions } from './types';\n\n/**\n * Generate a complete feature module with component, hook, types,\n * and optionally store (slice) and service sub-modules.\n */\nexport const generateFeature = async (options: FeatureGeneratorOptions): Promise<void> => {\n const { name, outputPath, createStore, persistStore, createService, httpClient } = options;\n\n const componentName = kebabToPascal(name);\n const hookName = `use${componentName}`;\n\n // Create directories\n const dirs = [\n path.join(outputPath, 'components'),\n path.join(outputPath, 'hooks'),\n path.join(outputPath, 'types'),\n ...(createStore ? [path.join(outputPath, 'store')] : []),\n ...(createService ? [path.join(outputPath, 'services')] : []),\n ];\n await Promise.all(dirs.map((dir) => mkdir(dir, { recursive: true })));\n\n // Generate base files\n await Promise.all([\n writeFile(\n path.join(outputPath, 'components', `${componentName}.tsx`),\n componentTemplate({ componentName, hookName }),\n ),\n writeFile(\n path.join(outputPath, 'hooks', `${hookName}.ts`),\n createStore\n ? hookWithStoreTemplate({ hookName, componentName, featureName: name })\n : hookWithoutStoreTemplate({ hookName }),\n ),\n writeFile(\n path.join(outputPath, 'types', `${name}.types.ts`),\n stateTypesTemplate({ componentName, withStore: createStore }),\n ),\n writeFile(\n path.join(outputPath, 'index.ts'),\n featureBarrelTemplate({\n featureName: name,\n componentName,\n hookName,\n withStore: createStore,\n withService: createService,\n }),\n ),\n ]);\n\n // Generate store (slice) if requested \u2014 types import from ../types/\n if (createStore) {\n await generateSlice({\n name,\n outputPath: path.join(outputPath, 'store'),\n persist: persistStore,\n typesImportPath: `../types/${name}.types`,\n });\n }\n\n // Generate service if requested\n if (createService && httpClient) {\n await generateService({\n name,\n outputPath: path.join(outputPath, 'services'),\n httpClient,\n });\n }\n};\n", "import { writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel } from '../config/utils';\nimport { serviceTemplate } from './templates/service.template';\nimport type { ServiceGeneratorOptions } from './types';\n\n/**\n * Generate an API service file for the given HTTP client.\n */\nexport const generateService = async (options: ServiceGeneratorOptions): Promise<void> => {\n const { name, outputPath, httpClient } = options;\n const camelName = kebabToCamel(name);\n\n await writeFile(\n path.join(outputPath, `${name}.service.ts`),\n serviceTemplate({ camelName, httpClient }),\n );\n};\n", "export const serviceTemplate = (params: {\n camelName: string;\n httpClient: 'axios' | 'fetch';\n}): string => {\n const { camelName, httpClient } = params;\n const clientImport =\n httpClient === 'axios'\n ? `import { axiosClient } from '@/lib/utils/http';`\n : `import { fetchClient } from '@/lib/utils/http';`;\n const clientName = httpClient === 'axios' ? 'axiosClient' : 'fetchClient';\n\n return `import { AppApis } from '@/lib/config';\n${clientImport}\nimport type { ResultAsync } from '@/types';\n\nexport const ${camelName}Service = {\n getAll: (): ResultAsync<string> => {\n return ${clientName}.get<string>(AppApis.${camelName}.getAll);\n },\n};\n`;\n};\n", "import { mkdir, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel, kebabToPascal } from '../config/utils';\nimport { sliceBarrelTemplate } from './templates/barrel.template';\nimport { persistTemplate } from './templates/persist.template';\nimport { selectorsTemplate } from './templates/selectors.template';\nimport { sliceTemplate } from './templates/slice.template';\nimport { stateTypesTemplate } from './templates/types.template';\nimport type { SliceGeneratorOptions } from './types';\n\n/**\n * Generate a complete Redux slice with types, selectors, optional persist, and barrel export.\n *\n * Used by both the `slice` command (standalone) and the `feature` command (embedded in feature/store/).\n * The `typesImportPath` controls whether types are imported from `../types/` (feature) or `./` (standalone).\n */\nexport const generateSlice = async (\n options: SliceGeneratorOptions & { typesImportPath?: string },\n): Promise<void> => {\n const { name, outputPath, persist, typesImportPath = `./${name}.types` } = options;\n\n await mkdir(outputPath, { recursive: true });\n\n const componentName = kebabToPascal(name);\n const camelName = kebabToCamel(name);\n\n await Promise.all([\n writeFile(\n path.join(outputPath, `${name}.types.ts`),\n stateTypesTemplate({ componentName, withStore: true }),\n ),\n writeFile(\n path.join(outputPath, `${name}.slice.ts`),\n sliceTemplate({ componentName, camelName, typesImportPath }),\n ),\n writeFile(\n path.join(outputPath, `${name}.selectors.ts`),\n selectorsTemplate({ componentName, camelName, sliceName: name }),\n ),\n ...(persist\n ? [\n writeFile(\n path.join(outputPath, 'persist.ts'),\n persistTemplate({ componentName, camelName, typesImportPath }),\n ),\n ]\n : []),\n writeFile(\n path.join(outputPath, 'index.ts'),\n sliceBarrelTemplate({ sliceName: name, withPersist: persist }),\n ),\n ]);\n};\n", "export const sliceBarrelTemplate = (params: {\n sliceName: string;\n withPersist: boolean;\n}): string => {\n const { sliceName, withPersist } = params;\n return `export * from './${sliceName}.slice';\nexport * from './${sliceName}.selectors';\nexport * from './${sliceName}.types';${withPersist ? \"\\nexport * from './persist';\" : ''}\n`;\n};\n\nexport const featureBarrelTemplate = (params: {\n featureName: string;\n componentName: string;\n hookName: string;\n withStore: boolean;\n withService: boolean;\n}): string => {\n const { featureName, componentName, hookName, withStore, withService } = params;\n return `export { default as ${componentName} } from './components/${componentName}';\nexport { ${hookName} } from './hooks/${hookName}';\nexport * from './types/${featureName}.types';${withStore ? `\\nexport * from './store';` : ''}${withService ? `\\nexport * from './services/${featureName}.service';` : ''}\n`;\n};\n", "export const persistTemplate = (params: {\n componentName: string;\n camelName: string;\n typesImportPath: string;\n}): string => {\n const { componentName, camelName, typesImportPath } = params;\n const versionConst = `${camelName.toUpperCase()}_PERSIST_VERSION`;\n return `import { createMigrate, type PersistConfig, type PersistedState } from 'redux-persist';\nimport storage from '@/store/storage';\nimport type { ${componentName}State } from '${typesImportPath}';\n\nconst ${versionConst} = 1;\n\nconst migrations = {\n // Bump ${versionConst} and add a migration here when ${componentName}State's\n // shape changes. Receives the previously-persisted state, returns the new\n // shape. Returning \\`undefined\\` discards stale state.\n // 2: (state) => ({ ...state, newField: defaultValue }),\n} satisfies Record<number, (state: PersistedState) => PersistedState>;\n\nexport const ${camelName}PersistConfig: PersistConfig<${componentName}State> = {\n key: '${camelName}',\n storage,\n version: ${versionConst},\n // whitelist: ['someField'], // Specify which fields to persist\n migrate: createMigrate(migrations, { debug: false }),\n};\n`;\n};\n", "export const selectorsTemplate = (params: {\n componentName: string;\n camelName: string;\n sliceName: string;\n}): string => {\n const { componentName, camelName, sliceName } = params;\n return `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", "export const sliceTemplate = (params: {\n componentName: string;\n camelName: string;\n typesImportPath: string;\n}): string => {\n const { componentName, camelName, typesImportPath } = params;\n return `import { createSlice, type PayloadAction } from '@reduxjs/toolkit';\nimport type { ${componentName}State } from '${typesImportPath}';\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", "export const stateTypesTemplate = (params: {\n componentName: string;\n withStore: boolean;\n}): string => {\n const { componentName, withStore } = params;\n return `export interface ${componentName}State {\n ${withStore ? 'loading: boolean;\\n error: string | null;\\n // Add your state properties here' : '// Add your state properties here\\n // example: value: string;'}\n}\n`;\n};\n", "export const componentTemplate = (params: { componentName: string; hookName: string }): string => {\n const { componentName, hookName } = params;\n return `'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", "export const hookWithStoreTemplate = (params: {\n hookName: string;\n componentName: string;\n featureName: string;\n}): string => {\n const { hookName, componentName, featureName } = params;\n return `'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 };\n\n const handleSetError = (error: string | null) => {\n dispatch(setError(error));\n };\n\n return {\n state,\n setLoading: handleSetLoading,\n setError: handleSetError,\n } as const;\n};\n`;\n};\n\nexport const hookWithoutStoreTemplate = (params: { hookName: string }): string => {\n const { hookName } = params;\n return `'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", "import { mkdir, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToPascal } from '../config/utils';\nimport { customHookTemplate } from './templates/custom-hook.template';\n\nexport interface HookGeneratorOptions {\n name: string;\n projectPath: string;\n isClient: boolean;\n featurePath?: string;\n}\n\nexport const generateHook = async (options: HookGeneratorOptions): Promise<void> => {\n const { name, projectPath, isClient, featurePath } = options;\n const pascalName = kebabToPascal(name);\n const hookName = `use${pascalName}`;\n\n let hooksDir: string;\n if (featurePath) {\n hooksDir = path.join(projectPath, featurePath, 'hooks');\n } else {\n hooksDir = path.join(projectPath, 'src', 'hooks');\n }\n\n await mkdir(hooksDir, { recursive: true });\n\n await writeFile(\n path.join(hooksDir, `${hookName}.ts`),\n customHookTemplate({ hookName, isClient }),\n );\n};\n", "export const customHookTemplate = (params: { hookName: string; isClient: boolean }): string => {\n const { hookName, isClient } = params;\n const lines: string[] = [];\n\n if (isClient) {\n lines.push(\"'use client';\");\n }\n\n lines.push(\"import { useState, useCallback } from 'react';\");\n lines.push('');\n lines.push(`export const ${hookName} = () => {`);\n lines.push(' const [loading, setLoading] = useState(false);');\n lines.push(' const [error, setError] = useState<string | null>(null);');\n lines.push('');\n lines.push(' const execute = useCallback(async () => {');\n lines.push(' setLoading(true);');\n lines.push(' setError(null);');\n lines.push(' try {');\n lines.push(' // Add your logic here');\n lines.push(' } catch (err) {');\n lines.push(\" setError(err instanceof Error ? err.message : 'An error occurred');\");\n lines.push(' } finally {');\n lines.push(' setLoading(false);');\n lines.push(' }');\n lines.push(' }, []);');\n lines.push('');\n lines.push(' return {');\n lines.push(' loading,');\n lines.push(' error,');\n lines.push(' execute,');\n lines.push(' } as const;');\n lines.push('};');\n lines.push('');\n\n return lines.join('\\n');\n};\n", "import { mkdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToPascal } from '../config/utils';\nimport { fileExists, writeFile } from '../core/files';\nimport { layoutTemplate } from './templates/layout.template';\n\nexport interface LayoutGeneratorOptions {\n /**\n * The leaf segment for the layout, e.g. `dashboard` or `marketing`. Route\n * groups are expressed via `withGroup: true` rather than encoding parens\n * into the segment string \u2014 keeps validation simple.\n */\n segment: string;\n /** Optional path under the locale root, e.g. `dashboard/settings`. The leaf becomes the layout. */\n at?: string;\n projectPath: string;\n hasI18n: boolean;\n /** Wraps the leaf segment in parens to form a route group `(marketing)`. */\n withGroup: boolean;\n}\n\nexport interface LayoutGeneratorResult {\n layoutFile: string;\n /** Display path for logging, e.g. `src/app/[locale]/(marketing)/layout.tsx`. */\n displayPath: string;\n componentName: string;\n}\n\nconst SEGMENT_RE = /^[a-z][a-z0-9-]*$/;\nconst SEGMENT_LIST_RE = /^[a-z][a-z0-9-]*(\\/[a-z][a-z0-9-]*)*$/;\n\nconst validateSegment = (segment: string): void => {\n if (!SEGMENT_RE.test(segment)) {\n throw new Error(\n `Invalid layout segment \"${segment}\". Use kebab-case letters, digits, and hyphens. ` +\n 'For route groups pass --group instead of wrapping in parens.',\n );\n }\n};\n\nconst validateAt = (at: string): void => {\n if (!SEGMENT_LIST_RE.test(at)) {\n throw new Error(\n `Invalid --at path \"${at}\". Use kebab-case segments separated by \"/\", e.g. \"dashboard/settings\".`,\n );\n }\n};\n\nexport const generateLayout = async (\n options: LayoutGeneratorOptions,\n): Promise<LayoutGeneratorResult> => {\n const { segment, at, projectPath, hasI18n, withGroup } = options;\n\n validateSegment(segment);\n if (at) validateAt(at);\n\n const componentName = `${kebabToPascal(segment)}Layout`;\n const leaf = withGroup ? `(${segment})` : segment;\n\n const baseSegments = ['src', 'app'];\n if (hasI18n) baseSegments.push('[locale]');\n if (at) baseSegments.push(...at.split('/'));\n baseSegments.push(leaf);\n\n const targetDir = path.join(projectPath, ...baseSegments);\n const layoutFile = path.join(targetDir, 'layout.tsx');\n\n if (fileExists(layoutFile)) {\n throw new Error(`Layout already exists at ${path.relative(projectPath, layoutFile)}.`);\n }\n\n await mkdir(targetDir, { recursive: true });\n await writeFile(layoutFile, layoutTemplate({ componentName, hasI18n }));\n\n return {\n layoutFile,\n displayPath: path.relative(projectPath, layoutFile),\n componentName,\n };\n};\n", "/**\n * Templates for the `layout` generator (B2). Nested layouts only \u2014 the root\n * layout is owned by the starter and is too heavy (fonts, providers, html/body)\n * to scaffold from a CLI.\n */\n\nexport interface LayoutTemplateParams {\n /** PascalCase component name (e.g. `DashboardLayout`). */\n componentName: string;\n /** True when the layout sits under `src/app/[locale]/...` and should consume the locale param. */\n hasI18n: boolean;\n}\n\nconst i18nTemplate = (componentName: string): string =>\n `import { setRequestLocale } from 'next-intl/server';\nimport type { SupportedLocale } from '@/types/i18n';\n\ntype Props = {\n children: React.ReactNode;\n params: Promise<{ locale: string }>;\n};\n\nexport default async function ${componentName}({ children, params }: Props) {\n const { locale } = await params;\n setRequestLocale(locale as SupportedLocale);\n\n return <>{children}</>;\n}\n`;\n\nconst plainTemplate = (componentName: string): string =>\n `type Props = {\n children: React.ReactNode;\n};\n\nexport default function ${componentName}({ children }: Props) {\n return <>{children}</>;\n}\n`;\n\nexport const layoutTemplate = ({ componentName, hasI18n }: LayoutTemplateParams): string =>\n hasI18n ? i18nTemplate(componentName) : plainTemplate(componentName);\n", "import { copyFile, readFile as readFileFs, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { fileExists, readFile, writeFile as writeFileCore } from '../core/files';\n\nexport interface LocaleGeneratorOptions {\n code: string;\n name: string;\n country: string;\n flag: string;\n projectPath: string;\n copyTranslations: boolean;\n}\n\nexport const generateLocale = async (options: LocaleGeneratorOptions): Promise<void> => {\n const { code, name, country, flag, projectPath, copyTranslations } = options;\n\n await createTranslationFile(projectPath, code, copyTranslations);\n await updateSupportedLocaleType(projectPath, code);\n await updateAppLocalesConfig(projectPath, code, name, country, flag);\n};\n\nconst createTranslationFile = async (\n projectPath: string,\n code: string,\n copyTranslations: boolean,\n): Promise<void> => {\n const translationsDir = path.join(projectPath, 'src', 'i18n', 'translations');\n const sourcePath = path.join(translationsDir, 'en.json');\n const destPath = path.join(translationsDir, `${code}.json`);\n\n if (copyTranslations) {\n await copyFile(sourcePath, destPath);\n } else {\n // Copy structure but empty all string values\n const sourceContent = await readFileFs(sourcePath, 'utf-8');\n const sourceJson = JSON.parse(sourceContent);\n const emptyJson = emptyValues(sourceJson);\n await writeFile(destPath, `${JSON.stringify(emptyJson, null, 2)}\\n`);\n }\n};\n\nconst emptyValues = (obj: Record<string, unknown>): Record<string, unknown> => {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (typeof value === 'object' && value !== null) {\n result[key] = emptyValues(value as Record<string, unknown>);\n } else {\n result[key] = '';\n }\n }\n return result;\n};\n\nconst updateSupportedLocaleType = async (projectPath: string, code: string): Promise<void> => {\n const typesPath = path.join(projectPath, 'src', 'types', 'i18n.ts');\n if (!fileExists(typesPath)) return;\n\n let content = await readFile(typesPath);\n\n // Add to SupportedLocale union: 'en' | 'es' \u2192 'en' | 'es' | 'fr'\n const localeTypeRegex = /export type SupportedLocale = (.*);/;\n const match = content.match(localeTypeRegex);\n\n if (match && !match[1].includes(`'${code}'`)) {\n const newType = `${match[1]} | '${code}'`;\n content = content.replace(localeTypeRegex, `export type SupportedLocale = ${newType};`);\n await writeFileCore(typesPath, content);\n }\n};\n\nconst updateAppLocalesConfig = async (\n projectPath: string,\n code: string,\n localeName: string,\n country: string,\n flag: string,\n): Promise<void> => {\n const configPath = path.join(projectPath, 'src', 'lib', 'config', 'app-locales.ts');\n if (!fileExists(configPath)) return;\n\n let content = await readFile(configPath);\n\n if (content.includes(`locale: '${code}'`)) return;\n\n // Insert new locale before the closing bracket\n const closingBracket = content.lastIndexOf('];');\n if (closingBracket === -1) return;\n\n const newLocale = ` {\n name: '${localeName}',\n locale: '${code}',\n flag: '${flag}',\n country: '${country}',\n },\\n`;\n\n content = content.slice(0, closingBracket) + newLocale + content.slice(closingBracket);\n await writeFileCore(configPath, content);\n};\n", "import { mkdir, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToPascal } from '../config/utils';\nimport {\n dynamicPageTemplate,\n errorTemplate,\n loadingTemplate,\n pageTemplate,\n} from './templates/page.template';\n\nexport interface PageGeneratorOptions {\n name: string;\n projectPath: string;\n hasI18n: boolean;\n dynamic?: string;\n withLoading?: boolean;\n withError?: boolean;\n}\n\nexport const generatePage = async (options: PageGeneratorOptions): Promise<void> => {\n const { name, projectPath, hasI18n, dynamic, withLoading = false, withError = false } = options;\n\n const componentName = kebabToPascal(name);\n const routePath = `/${name}`;\n\n // Determine page directory\n const baseDir = hasI18n ? 'src/app/[locale]' : 'src/app';\n let pageDir: string;\n\n if (dynamic) {\n pageDir = path.join(projectPath, baseDir, name, `[${dynamic}]`);\n } else {\n pageDir = path.join(projectPath, baseDir, name);\n }\n\n await mkdir(pageDir, { recursive: true });\n\n // Generate page file\n const pageContent = dynamic\n ? dynamicPageTemplate({\n componentName,\n routePath: dynamic ? `${routePath}/[${dynamic}]` : routePath,\n paramName: dynamic,\n hasI18n,\n })\n : pageTemplate({ componentName, routePath, hasI18n });\n\n await writeFile(path.join(pageDir, 'page.tsx'), pageContent);\n\n if (withLoading) {\n await writeFile(path.join(pageDir, 'loading.tsx'), loadingTemplate({ componentName }));\n }\n\n if (withError) {\n await writeFile(path.join(pageDir, 'error.tsx'), errorTemplate({ componentName }));\n }\n};\n", "export const pageTemplate = (params: {\n componentName: string;\n routePath: string;\n hasI18n: boolean;\n}): string => {\n const { componentName, routePath, hasI18n } = params;\n\n if (hasI18n) {\n return `import { generateSEOMetadata } from '@/lib/config/seo';\nimport type { Metadata } from 'next';\nimport { getTranslations, setRequestLocale } from 'next-intl/server';\nimport type { SupportedLocale } from '@/types/i18n';\n\ntype Props = {\n params: Promise<{ locale: string }>;\n};\n\nexport async function generateMetadata(props: Props): Promise<Metadata> {\n const locale = (await props.params).locale as SupportedLocale;\n const t = await getTranslations({ locale, namespace: '${componentName}' });\n\n return generateSEOMetadata({\n title: t('title'),\n description: t('description'),\n path: '${routePath}',\n });\n}\n\nexport default async function ${componentName}Page(props: Props) {\n const locale = (await props.params).locale as SupportedLocale;\n setRequestLocale(locale);\n\n const t = await getTranslations('${componentName}');\n\n return (\n <div>\n <h1>{t('title')}</h1>\n </div>\n );\n}\n`;\n }\n\n return `import type { Metadata } from 'next';\n\nexport const metadata: Metadata = {\n title: '${componentName}',\n description: '${componentName} page',\n};\n\nexport default function ${componentName}Page() {\n return (\n <div>\n <h1>${componentName}</h1>\n </div>\n );\n}\n`;\n};\n\nexport const dynamicPageTemplate = (params: {\n componentName: string;\n routePath: string;\n paramName: string;\n hasI18n: boolean;\n}): string => {\n const { componentName, paramName, routePath, hasI18n } = params;\n\n if (hasI18n) {\n return `import { generateSEOMetadata } from '@/lib/config/seo';\nimport type { Metadata } from 'next';\nimport { getTranslations, setRequestLocale } from 'next-intl/server';\nimport type { SupportedLocale } from '@/types/i18n';\n\ntype Props = {\n params: Promise<{ locale: string; ${paramName}: string }>;\n};\n\nexport async function generateMetadata(props: Props): Promise<Metadata> {\n const { locale, ${paramName} } = await props.params;\n const t = await getTranslations({ locale: locale as SupportedLocale, namespace: '${componentName}' });\n\n return generateSEOMetadata({\n title: t('title'),\n description: t('description'),\n path: '${routePath}',\n });\n}\n\nexport default async function ${componentName}Page(props: Props) {\n const { locale, ${paramName} } = await props.params;\n setRequestLocale(locale);\n\n const t = await getTranslations('${componentName}');\n\n return (\n <div>\n <h1>{t('title')}</h1>\n <p>${componentName}: {${paramName}}</p>\n </div>\n );\n}\n`;\n }\n\n return `import type { Metadata } from 'next';\n\nexport const metadata: Metadata = {\n title: '${componentName}',\n description: '${componentName} page',\n};\n\ntype Props = {\n params: Promise<{ ${paramName}: string }>;\n};\n\nexport default async function ${componentName}Page(props: Props) {\n const { ${paramName} } = await props.params;\n\n return (\n <div>\n <h1>${componentName}</h1>\n <p>${componentName}: {${paramName}}</p>\n </div>\n );\n}\n`;\n};\n\nexport const loadingTemplate = (params: { componentName: string }): string => {\n return `export default function ${params.componentName}Loading() {\n return (\n <div className=\"flex h-full items-center justify-center\">\n <p>Loading...</p>\n </div>\n );\n}\n`;\n};\n\nexport const errorTemplate = (params: { componentName: string }): string => {\n return `'use client';\n\nexport default function ${params.componentName}Error({\n error,\n reset,\n}: {\n error: Error & { digest?: string };\n reset: () => void;\n}) {\n return (\n <div className=\"flex h-full flex-col items-center justify-center gap-4\">\n <h2>Something went wrong!</h2>\n <p>{error.message}</p>\n <button type=\"button\" onClick={() => reset()}>Try again</button>\n </div>\n );\n}\n`;\n};\n", "import { mkdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport { PROJECT_PATHS } from '../config/paths';\nimport { kebabToPascal } from '../config/utils';\nimport { fileExists, writeFile } from '../core/files';\nimport { providerComponentName, providerTemplate } from './templates/provider.template';\n\nexport interface ProviderGeneratorOptions {\n /** Kebab-case or PascalCase base name (e.g. `auth` or `Auth`). */\n name: string;\n projectPath: string;\n}\n\nexport interface ProviderGeneratorResult {\n componentName: string;\n /** Filename without extension, e.g. `AuthProvider`. */\n fileBaseName: string;\n /** Absolute path to the generated provider file. */\n providerFile: string;\n}\n\nconst NAME_RE = /^[A-Za-z][A-Za-z0-9-]*$/;\n\nconst toPascal = (name: string): string =>\n name.includes('-') ? kebabToPascal(name) : name.charAt(0).toUpperCase() + name.slice(1);\n\nexport const generateProvider = async (\n options: ProviderGeneratorOptions,\n): Promise<ProviderGeneratorResult> => {\n const { name, projectPath } = options;\n\n if (!NAME_RE.test(name)) {\n throw new Error(\n `Invalid provider name \"${name}\". Use kebab-case or PascalCase letters and digits only.`,\n );\n }\n\n const baseName = toPascal(name).replace(/Provider$/, '');\n const componentName = providerComponentName(baseName);\n const fileBaseName = componentName;\n\n const providerDir = path.join(projectPath, PROJECT_PATHS.PROVIDERS);\n const providerFile = path.join(providerDir, `${fileBaseName}.tsx`);\n\n if (fileExists(providerFile)) {\n throw new Error(`Provider already exists at ${path.relative(projectPath, providerFile)}.`);\n }\n\n await mkdir(providerDir, { recursive: true });\n await writeFile(providerFile, providerTemplate({ baseName }));\n\n return { componentName, fileBaseName, providerFile };\n};\n", "/**\n * Templates for the `provider` generator (B3). Generates a context-based\n * provider \u2014 the most common use case. Users who only need a thin wrapper\n * around an external `<XxxProvider>` can delete the context boilerplate.\n */\n\nexport interface ProviderTemplateParams {\n /** PascalCase base name (e.g. `Auth`). The template appends `Provider` for the component and `useX` for the hook. */\n baseName: string;\n}\n\nconst ensureSuffix = (name: string, suffix: string): string =>\n name.endsWith(suffix) ? name : `${name}${suffix}`;\n\nexport const providerTemplate = ({ baseName }: ProviderTemplateParams): string => {\n const componentName = ensureSuffix(baseName, 'Provider');\n // Strip the Provider suffix for the value/context name (e.g. AuthProvider -> Auth).\n const root = componentName.replace(/Provider$/, '');\n const valueType = `${root}ContextValue`;\n const contextName = `${root}Context`;\n const hookName = `use${root}`;\n\n return `'use client';\nimport { createContext, useContext, useMemo } from 'react';\n\ntype ${valueType} = {\n // TODO: declare context value fields\n};\n\nconst ${contextName} = createContext<${valueType} | null>(null);\n\nexport const ${hookName} = (): ${valueType} => {\n const ctx = useContext(${contextName});\n if (!ctx) {\n throw new Error('${hookName} must be used within ${componentName}');\n }\n return ctx;\n};\n\nexport const ${componentName} = ({ children }: { children: React.ReactNode }) => {\n const value = useMemo<${valueType}>(() => ({}), []);\n return <${contextName}.Provider value={value}>{children}</${contextName}.Provider>;\n};\n`;\n};\n\nexport const providerComponentName = (baseName: string): string =>\n ensureSuffix(baseName, 'Provider');\n", "import path from 'node:path';\nimport { writeFile } from '../core/files';\nimport {\n componentTestTemplate,\n hookTestTemplate,\n sliceTestTemplate,\n} from './templates/test.template';\n\nexport type TestKind = 'component' | 'hook' | 'slice';\n\nexport type GenerateTestOptions = {\n projectPath: string;\n /** Absolute path to the source file being tested. */\n sourceFile: string;\n kind: TestKind;\n /** Component/hook/slice identifier (e.g. \"Counter\", \"useCounter\", \"counter\"). */\n symbolName: string;\n hasRedux?: boolean;\n hasI18n?: boolean;\n /** Whether the hook uses the Redux store (only relevant for `kind === 'hook'`). */\n hookUsesStore?: boolean;\n};\n\n/**\n * Emit a sibling *.test.{ts,tsx} next to the source file. Returns the path\n * that was written.\n */\nexport const generateTest = async (options: GenerateTestOptions): Promise<string> => {\n const { projectPath, sourceFile, kind, symbolName } = options;\n const testDir = path.dirname(sourceFile);\n const sourceBaseName = path.basename(sourceFile).replace(/\\.(tsx?|jsx?)$/i, '');\n const extension = kind === 'component' ? '.tsx' : '.ts';\n const testFile = path.join(testDir, `${sourceBaseName}.test${extension}`);\n\n const sourceImportPath = `./${sourceBaseName}`;\n const testUtilsImportPath = relativeImport(testDir, path.join(projectPath, 'test', 'test-utils'));\n\n let content: string;\n if (kind === 'component') {\n content = componentTestTemplate({\n componentName: symbolName,\n sourceImportPath,\n testUtilsImportPath,\n hasRedux: !!options.hasRedux,\n hasI18n: !!options.hasI18n,\n });\n } else if (kind === 'hook') {\n content = hookTestTemplate({\n hookName: symbolName,\n sourceImportPath,\n withStore: !!options.hookUsesStore,\n testUtilsImportPath: options.hookUsesStore ? testUtilsImportPath : undefined,\n });\n } else {\n content = sliceTestTemplate({\n camelName: symbolName,\n sourceImportPath,\n });\n }\n\n await writeFile(testFile, content);\n return testFile;\n};\n\nconst relativeImport = (from: string, to: string): string => {\n const rel = path.relative(from, to).replace(/\\\\/g, '/');\n return rel.startsWith('.') ? rel : `./${rel}`;\n};\n", "export type ComponentTestParams = {\n componentName: string;\n /** Import path from the test file to the component, without extension. */\n sourceImportPath: string;\n /** Import path from the test file to `test/test-utils`, without extension. */\n testUtilsImportPath: string;\n hasRedux: boolean;\n hasI18n: boolean;\n};\n\nexport const componentTestTemplate = (params: ComponentTestParams): string => {\n const { componentName, sourceImportPath, testUtilsImportPath, hasRedux, hasI18n } = params;\n\n const extraOptions: string[] = [];\n if (hasI18n) extraOptions.push('messages: {}');\n if (hasRedux) extraOptions.push('preloadedState: {}');\n const optionsBlock = extraOptions.length\n ? `, {\\n ${extraOptions.join(',\\n ')},\\n }`\n : '';\n\n return `import { describe, expect, it } from 'vitest';\nimport { renderWithProviders, screen } from '${testUtilsImportPath}';\nimport { ${componentName} } from '${sourceImportPath}';\n\ndescribe('${componentName}', () => {\n it('renders without crashing', () => {\n renderWithProviders(<${componentName} />${optionsBlock});\n // TODO: assert something meaningful about the rendered output.\n expect(screen).toBeDefined();\n });\n});\n`;\n};\n\nexport type HookTestParams = {\n hookName: string;\n sourceImportPath: string;\n /** When the hook reads from the Redux store, wrap `renderHook` in TestProviders. */\n withStore: boolean;\n /** Only used when withStore is true. */\n testUtilsImportPath?: string;\n};\n\nexport const hookTestTemplate = (params: HookTestParams): string => {\n const { hookName, sourceImportPath, withStore, testUtilsImportPath } = params;\n\n if (withStore) {\n return `import { renderHook } from '@testing-library/react';\nimport { describe, expect, it } from 'vitest';\nimport { TestProviders } from '${testUtilsImportPath}';\nimport { ${hookName} } from '${sourceImportPath}';\n\ndescribe('${hookName}', () => {\n it('returns a defined value', () => {\n const { result } = renderHook(() => ${hookName}(), { wrapper: TestProviders });\n expect(result.current).toBeDefined();\n });\n});\n`;\n }\n\n return `import { renderHook } from '@testing-library/react';\nimport { describe, expect, it } from 'vitest';\nimport { ${hookName} } from '${sourceImportPath}';\n\ndescribe('${hookName}', () => {\n it('returns a defined value', () => {\n const { result } = renderHook(() => ${hookName}());\n expect(result.current).toBeDefined();\n });\n});\n`;\n};\n\nexport type SliceTestParams = {\n /** e.g. `counter` */\n camelName: string;\n /** Import path from the test file to the `.slice` file, without extension. */\n sourceImportPath: string;\n};\n\nexport const sliceTestTemplate = (params: SliceTestParams): string => {\n const { camelName, sourceImportPath } = params;\n const sliceRef = `${camelName}Slice`;\n\n return `import { describe, expect, it } from 'vitest';\nimport { ${sliceRef}, resetState, setError, setLoading } from '${sourceImportPath}';\n\ndescribe('${sliceRef}', () => {\n const initialState = { loading: false, error: null } as const;\n\n it('returns the initial state', () => {\n expect(${sliceRef}.reducer(undefined, { type: '@@INIT' })).toEqual(initialState);\n });\n\n it('handles setLoading', () => {\n const next = ${sliceRef}.reducer(initialState, setLoading(true));\n expect(next.loading).toBe(true);\n });\n\n it('handles setError', () => {\n const next = ${sliceRef}.reducer(initialState, setError('boom'));\n expect(next.error).toBe('boom');\n });\n\n it('handles resetState', () => {\n const next = ${sliceRef}.reducer({ loading: true, error: 'boom' }, resetState());\n expect(next).toEqual(initialState);\n });\n});\n`;\n};\n", "import Enquirer from 'enquirer';\n\nconst { prompt } = Enquirer;\n\nexport interface ComponentPromptResult {\n componentName: string;\n isClient: boolean;\n}\n\nexport interface ComponentPromptPresets {\n /** When set, the `'use client'` prompt is skipped and this value is used. */\n client?: boolean;\n}\n\nexport const promptForComponentDetails = async (\n name?: string,\n presets: ComponentPromptPresets = {},\n): Promise<ComponentPromptResult> => {\n const questions: any[] = [];\n\n if (!name) {\n questions.push({\n type: 'input',\n name: 'componentName',\n message: 'Component name (kebab-case):',\n validate: (value: string) => {\n if (!value) return 'Component name is required';\n if (!/^[a-z][a-z0-9-]*$/.test(value)) {\n return 'Use lowercase letters, numbers, and hyphens only';\n }\n return true;\n },\n });\n }\n\n if (presets.client === undefined) {\n questions.push({\n type: 'confirm',\n name: 'isClient',\n message: \"Add 'use client' directive?\",\n initial: false,\n });\n }\n\n const answers =\n questions.length > 0\n ? ((await prompt(questions)) as unknown as Partial<ComponentPromptResult>)\n : {};\n\n return {\n componentName: name ?? (answers.componentName as string),\n isClient: presets.client ?? answers.isClient ?? false,\n };\n};\n", "import type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError } from '../config';\nimport { checkManifest, MANIFESTS } from '../manifests';\nimport type { FeatureCheckResult, FeatureFinding } from '../manifests/types';\n\ninterface DoctorCommandOptions {\n fix?: boolean;\n feature?: string;\n json?: boolean;\n}\n\nconst formatFinding = (f: FeatureFinding): string => {\n switch (f.kind) {\n case 'missingFile':\n return `missing file: ${f.file}`;\n case 'missingPackage':\n return `missing ${f.depKind === 'dependency' ? 'dep' : 'devDep'}: ${f.name}`;\n case 'missingScript':\n return `missing script: ${f.name}`;\n case 'mismatchedScript':\n return `script \"${f.name}\" expected ${pc.dim(f.expected)} but got ${pc.dim(f.actual)}`;\n case 'missingInjection':\n return `missing block in ${f.file}: ${f.description}`;\n }\n};\n\nconst summary = (\n results: FeatureCheckResult[],\n): {\n installedCount: number;\n driftedCount: number;\n cleanCount: number;\n driftedResults: FeatureCheckResult[];\n} => {\n const installed = results.filter((r) => r.installed);\n const drifted = installed.filter((r) => r.drift.length > 0);\n return {\n installedCount: installed.length,\n driftedCount: drifted.length,\n cleanCount: installed.length - drifted.length,\n driftedResults: drifted,\n };\n};\n\nexport const registerDoctorCommand = (program: Command) => {\n program\n .command('doctor')\n .description('Diagnose drift between the project and known feature manifests')\n .option('--fix', 'Re-apply manifests that report drift (idempotent)')\n .option('--feature <id>', 'Only check this manifest id (e.g. redux, security-headers)')\n .option('--json', 'Print machine-readable JSON instead of the human report')\n .action(async (options: DoctorCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\n const targets = options.feature\n ? MANIFESTS.filter((m) => m.id === options.feature)\n : MANIFESTS;\n\n if (options.feature && targets.length === 0) {\n throw new Error(\n `Unknown feature \"${options.feature}\". Valid: ${MANIFESTS.map((m) => m.id).join(', ')}.`,\n );\n }\n\n const results: FeatureCheckResult[] = [];\n for (const manifest of targets) {\n results.push(await checkManifest(manifest, projectPath));\n }\n\n if (options.json) {\n log(\n JSON.stringify(\n results.map((r) => ({\n id: r.manifest.id,\n name: r.manifest.name,\n installed: r.installed,\n drift: r.drift,\n })),\n null,\n 2,\n ),\n );\n process.exit(results.some((r) => r.drift.length > 0) ? 1 : 0);\n }\n\n log(pc.cyan('\\n\uD83E\uDE7A Project Doctor\\n'));\n\n for (const result of results) {\n const { manifest, installed, drift } = result;\n if (!installed) {\n log(` ${pc.dim('\u2014')} ${pc.dim(manifest.name)} ${pc.dim('(not installed)')}`);\n continue;\n }\n if (drift.length === 0) {\n log(` ${pc.green('\u2713')} ${manifest.name}`);\n continue;\n }\n log(\n ` ${pc.yellow('!')} ${pc.bold(manifest.name)} ${pc.dim(`(${drift.length} issue${drift.length === 1 ? '' : 's'})`)}`,\n );\n for (const f of drift) {\n log(` ${pc.yellow('\u2022')} ${formatFinding(f)}`);\n }\n }\n\n const stats = summary(results);\n log('');\n log(\n pc.dim(\n `${stats.cleanCount} clean, ${stats.driftedCount} drifted, ${results.length - stats.installedCount} not installed`,\n ),\n );\n\n if (stats.driftedCount === 0) {\n log(pc.green('\\n\u2713 No drift detected.\\n'));\n process.exit(0);\n }\n\n if (!options.fix) {\n log(pc.dim('\\nRun with --fix to re-apply drifted features.\\n'));\n process.exit(1);\n }\n\n log(pc.cyan('\\n\uD83D\uDD27 Applying fixes...\\n'));\n for (const result of stats.driftedResults) {\n if (!result.manifest.apply) {\n log(pc.yellow(` \u26A0\uFE0F ${result.manifest.name} has no apply() \u2014 skipping.`));\n continue;\n }\n try {\n await result.manifest.apply(projectPath);\n } catch (error) {\n logError(`Failed to fix ${result.manifest.name}: ${error}`);\n }\n }\n\n log(pc.green('\\n\u2713 Doctor finished.\\n'));\n } catch (error) {\n logError(`${error instanceof Error ? error.message : error}`);\n process.exit(1);\n }\n });\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../config/paths';\nimport { fileExists, readFile } from '../core/files';\nimport { setupBundleAnalyzer } from '../services/setup/bundle-analyzer';\nimport { unwrapBundleAnalyzer } from './transforms/next-config';\nimport type { FeatureManifest } from './types';\n\nexport const bundleAnalyzerManifest: FeatureManifest = {\n id: 'bundle-analyzer',\n name: 'Bundle Analyzer',\n description: '@next/bundle-analyzer wrapped around the default export',\n detect: async (projectPath) => {\n const target = path.join(projectPath, PROJECT_PATHS.NEXT_CONFIG);\n if (!fileExists(target)) return false;\n return /@next\\/bundle-analyzer/.test(await readFile(target));\n },\n files: [],\n packages: [{ name: '@next/bundle-analyzer', kind: 'devDependency' }],\n scripts: [{ name: 'analyze', expectedValue: 'ANALYZE=true next build' }],\n injections: [\n {\n file: PROJECT_PATHS.NEXT_CONFIG,\n description: 'withBundleAnalyzer import + wrapping',\n presence: /@next\\/bundle-analyzer/,\n removePattern: unwrapBundleAnalyzer,\n },\n ],\n apply: setupBundleAnalyzer,\n};\n", "import path from 'node:path';\nimport pc from 'picocolors';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { startSpinner } from '../../../config/spinner';\nimport { fileExists, readFile, updateJson, writeFile } from '../../../core/files';\nimport { installDevPackage } from '../../../core/package-manager';\n\nexport const setupBundleAnalyzer = async (projectPath: string): Promise<void> => {\n const spinner = startSpinner('Adding @next/bundle-analyzer...');\n try {\n const nextConfigPath = path.join(projectPath, PROJECT_PATHS.NEXT_CONFIG);\n if (!fileExists(nextConfigPath)) {\n throw new Error(`${PROJECT_PATHS.NEXT_CONFIG} not found.`);\n }\n\n let content = await readFile(nextConfigPath);\n if (content.includes('@next/bundle-analyzer')) {\n spinner.fail('@next/bundle-analyzer is already configured.');\n return;\n }\n\n // 1. Add import at the top.\n content = `import withBundleAnalyzer from '@next/bundle-analyzer';\\n${content}`;\n\n // 2. Insert the `const bundleAnalyzer = withBundleAnalyzer(...)` declaration\n // just before `export default ...`.\n const exportDefaultRe = /export default (.*?);/;\n const match = content.match(exportDefaultRe);\n if (!match) {\n throw new Error('Could not locate `export default` in next.config.ts.');\n }\n const existingExport = match[1];\n const replacement = `const bundleAnalyzer = withBundleAnalyzer({\\n enabled: process.env.ANALYZE === 'true',\\n});\\n\\nexport default bundleAnalyzer(${existingExport});`;\n content = content.replace(exportDefaultRe, replacement);\n await writeFile(nextConfigPath, content);\n\n // 3. Add the `analyze` script to package.json.\n await updateJson(path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON), (pkg) => {\n pkg.scripts = pkg.scripts ?? {};\n if (!pkg.scripts.analyze) {\n pkg.scripts.analyze = 'ANALYZE=true next build';\n }\n return pkg;\n });\n\n spinner.text = 'Installing @next/bundle-analyzer...';\n await installDevPackage(projectPath, '@next/bundle-analyzer');\n\n spinner.succeed(pc.green('@next/bundle-analyzer configured.'));\n } catch (error) {\n spinner.fail('Failed to add @next/bundle-analyzer.');\n throw error;\n }\n};\n", "/**\n * JSX unwrap helpers used by manifests' `removePattern` to undo a provider\n * chain wrap (e.g. unwrap `<NextIntlClientProvider>{children}</NextIntlClientProvider>`\n * back to `{children}`) and clean up the now-orphan import statement.\n *\n * String-only transforms \u2014 no AST. Conservative: bail out (return `null`) when\n * the file shape has drifted from the canonical pattern instead of guessing.\n */\n\nimport type { RemoveTransform } from '../types';\n\n/**\n * Drop a named or default import for `symbol`. If the import was the only\n * symbol in a named-import block, the whole line is removed; otherwise the\n * symbol is excised from the brace list.\n */\nexport const removeNamedImport = (content: string, symbol: string): string => {\n const lines = content.split('\\n');\n const out: string[] = [];\n const defaultRe = new RegExp(`^import\\\\s+${symbol}\\\\s+from\\\\s+['\"][^'\"]+['\"];?\\\\s*$`);\n const namedRe = /^(import\\s+)\\{([^}]+)\\}(\\s+from\\s+['\"][^'\"]+['\"];?\\s*)$/;\n\n for (const line of lines) {\n if (defaultRe.test(line)) continue; // drop default import line entirely\n\n const m = line.match(namedRe);\n if (m) {\n const symbols = m[2]\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n const filtered = symbols.filter((s) => {\n const name = s\n .replace(/^type\\s+/, '')\n .split(/\\s+as\\s+/)[0]\n .trim();\n return name !== symbol;\n });\n if (filtered.length === 0) continue; // every symbol was the target \u2014 drop line\n if (filtered.length < symbols.length) {\n out.push(`${m[1]}{ ${filtered.join(', ')} }${m[3]}`);\n continue;\n }\n }\n out.push(line);\n }\n\n return out.join('\\n');\n};\n\n/**\n * Build a `RemoveTransform` that:\n * 1. Locates `<ComponentName ...>` ... `</ComponentName>` in the file.\n * 2. Replaces the wrap with its body, outdented by one level (2 spaces).\n * 3. Drops the orphan import for `ComponentName`.\n *\n * Returns `null` (\u2192 manual cleanup) when:\n * - The opening tag isn't found.\n * - The opening tag spans multiple lines (attributes broken across lines).\n * - No matching closing tag at the same indent is found.\n *\n * The conservative bail-outs keep auto-removal trustworthy: if the user has\n * customised the file beyond the canonical shape, we surface a manual hint\n * rather than corrupt their JSX.\n */\nexport const unwrapJsxChain =\n (componentName: string): RemoveTransform =>\n (content) => {\n const lines = content.split('\\n');\n\n const openRe = new RegExp(`^([ \\\\t]*)<${componentName}\\\\b`);\n let openIdx = -1;\n let openIndent = '';\n for (let i = 0; i < lines.length; i++) {\n const m = lines[i].match(openRe);\n if (m) {\n openIdx = i;\n openIndent = m[1];\n break;\n }\n }\n if (openIdx === -1) return null;\n\n // Opening tag must close on the same line \u2014 multi-line opening tags\n // would require attribute-aware parsing which we deliberately skip.\n if (!/>\\s*$/.test(lines[openIdx])) return null;\n\n const escapedIndent = openIndent.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const closeRe = new RegExp(`^${escapedIndent}<\\\\/${componentName}>\\\\s*$`);\n let closeIdx = -1;\n for (let i = openIdx + 1; i < lines.length; i++) {\n if (closeRe.test(lines[i])) {\n closeIdx = i;\n break;\n }\n }\n if (closeIdx === -1) return null;\n\n // Outdent the body by 2 spaces (one indent level).\n const inner = lines\n .slice(openIdx + 1, closeIdx)\n .map((line) => (line.startsWith(' ') ? line.slice(2) : line));\n\n const merged = [...lines.slice(0, openIdx), ...inner, ...lines.slice(closeIdx + 1)].join('\\n');\n\n return removeNamedImport(merged, componentName);\n };\n", "/**\n * Transforms for `next.config.ts` \u2014 undo the wraps that `setupI18n` and\n * `setupBundleAnalyzer` apply.\n *\n * Conservative: each helper bails out (returns `null`) if the file's shape\n * has drifted away from the canonical pattern. Better to ask the user to\n * resolve it than to corrupt their config.\n */\n\nimport type { RemoveTransform } from '../types';\nimport { removeNamedImport } from './unwrap-jsx';\n\n/**\n * Undo `setupI18n`'s wrap: removes\n * - `import createNextIntlPlugin from 'next-intl/plugin';`\n * - `const withNextIntl = createNextIntlPlugin(...);`\n * - the `withNextIntl(...)` call inside the default export, replacing it\n * with the inner argument.\n */\nexport const unwrapNextIntlPlugin: RemoveTransform = (content) => {\n let result = content\n .split('\\n')\n .filter(\n (line) =>\n !/^import\\s+createNextIntlPlugin\\s+from\\s+['\"]next-intl\\/plugin['\"];?\\s*$/.test(line),\n )\n .join('\\n');\n\n // Drop the `const withNextIntl = createNextIntlPlugin(...)` line(s). The\n // call may take args, so allow multi-line content between the outer parens.\n result = result.replace(/^const\\s+withNextIntl\\s*=\\s*createNextIntlPlugin\\([^)]*\\);\\s*\\n?/m, '');\n\n // Unwrap `withNextIntl(<arg>)` in the default export. The inner arg is\n // typically a bare identifier (`nextConfig`) or a sibling wrap call\n // (`bundleAnalyzer(nextConfig)`). We tolerate the second case by allowing\n // one level of nested parens.\n const callRe = /withNextIntl\\(\\s*((?:[^()]|\\([^()]*\\))+?)\\s*\\)/;\n if (!callRe.test(result)) return null;\n result = result.replace(callRe, '$1');\n\n return result;\n};\n\n/**\n * Undo `setupBundleAnalyzer`'s wrap: removes\n * - `import withBundleAnalyzer from '@next/bundle-analyzer';`\n * - the `const bundleAnalyzer = withBundleAnalyzer({ ... });` block.\n * - the `bundleAnalyzer(...)` call inside the default export.\n */\nexport const unwrapBundleAnalyzer: RemoveTransform = (content) => {\n let result = removeNamedImport(content, 'withBundleAnalyzer');\n\n // The `const bundleAnalyzer = withBundleAnalyzer({...});` block is\n // generated as a multi-line statement. We match conservatively: a `const`\n // declaration whose call body never closes its top-level `}` until we\n // see `);`. Bail out if it isn't there.\n const blockRe = /^const\\s+bundleAnalyzer\\s*=\\s*withBundleAnalyzer\\(\\{[\\s\\S]*?\\}\\);\\s*\\n?/m;\n if (!blockRe.test(result)) {\n return null;\n }\n result = result.replace(blockRe, '');\n\n // Unwrap `bundleAnalyzer(<arg>)` in the default export.\n const callRe = /bundleAnalyzer\\(\\s*((?:[^()]|\\([^()]*\\))+?)\\s*\\)/;\n if (!callRe.test(result)) return null;\n result = result.replace(callRe, '$1');\n\n return result;\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../config/paths';\nimport { fileExists } from '../core/files';\nimport { setupCommitizen } from '../services/setup/commitizen';\nimport type { FeatureManifest } from './types';\n\nexport const commitizenManifest: FeatureManifest = {\n id: 'commitizen',\n name: 'Commitizen',\n description: 'Guided conventional-commit prompt via `commit` script',\n detect: async (projectPath) => fileExists(path.join(projectPath, PROJECT_PATHS.CZRC)),\n files: [{ path: PROJECT_PATHS.CZRC, generated: true }],\n packages: [\n { name: 'commitizen', kind: 'devDependency' },\n { name: 'cz-conventional-changelog', kind: 'devDependency' },\n ],\n scripts: [{ name: 'commit', expectedValue: 'cz' }],\n injections: [],\n apply: setupCommitizen,\n};\n", "import path from 'node:path';\nimport pc from 'picocolors';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { startSpinner } from '../../../config/spinner';\nimport { fileExists, readFile, updateJson, writeFile } from '../../../core/files';\nimport { detectPackageManager, installDevPackages } from '../../../core/package-manager';\nimport { addCommitizen, missingCommitizenDeps, type PackageJsonShape } from './package-modifier';\n\nexport {\n addCommitizen,\n missingCommitizenDeps,\n type PackageJsonShape,\n} from './package-modifier';\n\nconst CZRC_CONTENT = `${JSON.stringify({ path: 'cz-conventional-changelog' }, null, 2)}\\n`;\n\nexport const setupCommitizen = async (projectPath: string): Promise<void> => {\n const spinner = startSpinner('Setting up Commitizen...');\n try {\n const czrcPath = path.join(projectPath, PROJECT_PATHS.CZRC);\n if (!fileExists(czrcPath)) {\n await writeFile(czrcPath, CZRC_CONTENT);\n }\n\n const pkgPath = path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON);\n const beforePkg = JSON.parse(await readFile(pkgPath)) as PackageJsonShape;\n const missing = missingCommitizenDeps(beforePkg);\n\n await updateJson<PackageJsonShape>(pkgPath, (pkg) => addCommitizen(pkg));\n\n if (missing.length > 0) {\n spinner.text = `Installing ${missing.join(', ')}...`;\n const manager = await detectPackageManager(projectPath);\n await installDevPackages(projectPath, manager, missing);\n }\n\n spinner.succeed(pc.green('Commitizen configured. Use `commit` to start a guided commit.'));\n } catch (error) {\n spinner.fail('Failed to set up Commitizen.');\n throw error;\n }\n};\n", "import { PACKAGES } from '../../../config/packages';\n\n/**\n * Pure JSON modifier for Commitizen retrofit. Kept separate from the service\n * so it can be unit-tested with no filesystem.\n */\n\nexport interface PackageJsonShape {\n scripts?: Record<string, string>;\n devDependencies?: Record<string, string>;\n config?: Record<string, unknown> & {\n commitizen?: { path: string };\n };\n [key: string]: unknown;\n}\n\nexport const addCommitizen = (pkg: PackageJsonShape): PackageJsonShape => {\n const scripts = { ...(pkg.scripts ?? {}) };\n const devDeps = { ...(pkg.devDependencies ?? {}) };\n\n if (!scripts.commit) {\n scripts.commit = 'cz';\n }\n if (!devDeps[PACKAGES.COMMITIZEN]) {\n devDeps[PACKAGES.COMMITIZEN] = '*';\n }\n if (!devDeps[PACKAGES.CZ_CONVENTIONAL_CHANGELOG]) {\n devDeps[PACKAGES.CZ_CONVENTIONAL_CHANGELOG] = '*';\n }\n\n return { ...pkg, scripts, devDependencies: devDeps };\n};\n\nexport const missingCommitizenDeps = (pkg: PackageJsonShape): string[] => {\n const devDeps = pkg.devDependencies ?? {};\n const missing: string[] = [];\n if (!devDeps[PACKAGES.COMMITIZEN]) missing.push(PACKAGES.COMMITIZEN);\n if (!devDeps[PACKAGES.CZ_CONVENTIONAL_CHANGELOG])\n missing.push(PACKAGES.CZ_CONVENTIONAL_CHANGELOG);\n return missing;\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../config/paths';\nimport { fileExists } from '../core/files';\nimport { setupDarkTheme } from '../services/setup/dark-theme';\nimport { unwrapJsxChain } from './transforms/unwrap-jsx';\nimport type { FeatureManifest } from './types';\n\nexport const darkThemeManifest: FeatureManifest = {\n id: 'dark-theme',\n name: 'Dark Theme',\n description: '@teispace/next-themes + CustomThemeProvider',\n detect: async (projectPath) => fileExists(path.join(projectPath, PROJECT_PATHS.THEME_PROVIDER)),\n files: [{ path: PROJECT_PATHS.THEME_PROVIDER, generated: true }],\n packages: [{ name: '@teispace/next-themes', kind: 'dependency' }],\n scripts: [],\n injections: [\n {\n file: 'src/providers/RootProvider.tsx',\n description: '<CustomThemeProvider> wrap',\n presence: /CustomThemeProvider/,\n removePattern: unwrapJsxChain('CustomThemeProvider'),\n },\n ],\n apply: setupDarkTheme,\n};\n", "import path from 'node:path';\nimport pc from 'picocolors';\nimport { startSpinner } from '../../../config/spinner';\nimport { deleteDirectory } from '../../../core/files';\nimport { detectPackageManager, installPackage, runScript } from '../../../core/package-manager';\nimport { copyThemeProvider, fetchAssets } from './assets';\nimport { checkIsAlreadySetup, validateProjectStructure } from './checks';\nimport {\n updateGlobalsCss,\n updateLayout,\n updateProvidersIndex,\n updateRootProvider,\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 @teispace/next-themes...';\n await installPackage(projectPath, '@teispace/next-themes');\n\n // 7. Format Code\n spinner.text = 'Formatting code...';\n const packageManager = await detectPackageManager(projectPath);\n await runScript(projectPath, packageManager, 'lint:fix');\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 degit from 'degit';\nimport type { Ora } from 'ora';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { copyFile } from '../../../core/files';\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 { PROJECT_PATHS } from '../../../config/paths';\nimport { fileExists, readFile } from '../../../core/files';\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 const themesPkg = '@teispace/next-themes';\n if (packageJson.dependencies?.[themesPkg] || packageJson.devDependencies?.[themesPkg]) {\n return { isSetup: true, reason: `${themesPkg} 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 { PROJECT_PATHS } from '../../../config/paths';\nimport { fileExists, readFile } from '../../../core/files';\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 { PROJECT_PATHS } from '../../../config/paths';\nimport { fileExists, readFile, writeFile } from '../../../core/files';\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)) return;\n\n let content = await readFile(rootProviderPath);\n\n const useClientDirective = \"'use client';\";\n const hasUseClient = content.includes(useClientDirective);\n if (hasUseClient) {\n content = content.replace(useClientDirective, '').trim();\n }\n\n // Add CustomThemeProvider import if missing\n if (!content.includes('CustomThemeProvider')) {\n if (/import\\s*\\{[^}]*\\}\\s*from\\s*'@\\/providers'/.test(content)) {\n content = content.replace(\n /(import\\s*\\{)([^}]*)(\\}\\s*from\\s*'@\\/providers')/,\n (_m, open, names, close) =>\n `${open}${names.trim() ? `${names.trim()}, CustomThemeProvider ` : ' CustomThemeProvider '}${close}`,\n );\n } else {\n content = `import { CustomThemeProvider } from '@/providers';\\n${content}`;\n }\n }\n\n if (hasUseClient) {\n content = `${useClientDirective}\\n${content}`;\n }\n\n // Wrap {children} with CustomThemeProvider (innermost to preserve any outer providers)\n if (!content.includes('<CustomThemeProvider')) {\n if (content.includes('{children}')) {\n content = content.replace(\n /\\{children\\}/,\n '<CustomThemeProvider>{children}</CustomThemeProvider>',\n );\n } else {\n // Fallback: wrap entire return JSX\n const returnMatch = content.match(/return\\s*\\(\\s*([\\s\\S]*?)\\s*\\);/);\n if (returnMatch) {\n content = content.replace(\n returnMatch[0],\n `return (\\n <CustomThemeProvider>\\n ${returnMatch[1]}\\n </CustomThemeProvider>\\n );`,\n );\n }\n }\n }\n\n await writeFile(rootProviderPath, content);\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 fs from 'node:fs/promises';\nimport path from 'node:path';\nimport Enquirer from 'enquirer';\nimport pc from 'picocolors';\nimport { startSpinner } from '../../../config/spinner';\nimport { deleteDirectory, fileExists } from '../../../core/files';\nimport {\n detectPackageManager,\n installPackage,\n runScript,\n uninstallPackage,\n} from '../../../core/package-manager';\nimport { copyHttpClientFiles, fetchAssets, performFullCleanup } from './assets';\nimport { checkIsAlreadySetup, type HttpClientType, validateProjectStructure } from './checks';\nimport {\n cleanupHttpTypes,\n migrateClientUsages,\n removeHttpExports,\n updateConfigIndex,\n updateHttpIndex,\n updateTypesIndex,\n updateUtilsIndex,\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, 'lint:fix');\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 fs from 'node:fs/promises';\nimport path from 'node:path';\nimport degit from 'degit';\nimport type { Ora } from 'ora';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { copyFile, deleteDirectory, fileExists, readFile, writeFile } from '../../../core/files';\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 path from 'node:path';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { fileExists } from '../../../core/files';\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 { setupHttpClient } from '../services/setup/http-client';\nimport type { FeatureManifest } from './types';\n\nexport const httpClientManifest: FeatureManifest = {\n id: 'http-client',\n name: 'HTTP Client',\n description: 'Axios and/or Fetch client utilities',\n detect: async (projectPath) => {\n const { detectProjectSetup } = await import('../detection');\n return (await detectProjectSetup(projectPath)).httpClient !== 'none';\n },\n files: [\n {\n path: 'src/lib/utils/http',\n generated: true,\n isDir: true,\n containsUserContent: true,\n removeHint:\n 'holds the http client + any service modules you wired through it \u2014 review before deleting',\n },\n ],\n // No deps listed: axios is conditionally installed; the manifest can't\n // know which client variant is active without re-running detection.\n packages: [],\n scripts: [],\n injections: [],\n apply: setupHttpClient,\n};\n", "import path from 'node:path';\nimport pc from 'picocolors';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { startSpinner } from '../../../config/spinner';\nimport { deleteDirectory, fileExists, readFile } from '../../../core/files';\nimport { detectPackageManager, installPackage, runScript } from '../../../core/package-manager';\nimport { writeTestUtils } from '../../common/test-utils';\nimport { copyI18nFiles, fetchAssets } from './assets';\nimport { checkIsAlreadySetup, validateProjectStructure } from './checks';\nimport {\n migrateToLocaleStructure,\n updateConfigIndex,\n updateNextConfig,\n updateRootProvider,\n updateTypesIndex,\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. If tests are present, regenerate test-utils so it wraps in i18n.\n const vitestConfigPath = path.join(projectPath, PROJECT_PATHS.VITEST_CONFIG);\n if (fileExists(vitestConfigPath)) {\n const pkg = JSON.parse(await readFile(path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON)));\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n const hasRedux = !!(deps['@reduxjs/toolkit'] && deps['react-redux']);\n await writeTestUtils(projectPath, { redux: hasRedux, i18n: true });\n }\n\n // 8. Format Code\n spinner.text = 'Formatting code...';\n const packageManager = await detectPackageManager(projectPath);\n await runScript(projectPath, packageManager, 'lint:fix');\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 fs from 'node:fs/promises';\nimport path from 'node:path';\nimport degit from 'degit';\nimport type { Ora } from 'ora';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { copyFile } from '../../../core/files';\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 { PROJECT_PATHS } from '../../../config/paths';\nimport { fileExists, readFile } from '../../../core/files';\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 (packageJson.dependencies?.['next-intl'] || packageJson.devDependencies?.['next-intl']) {\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 fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { deleteFile, fileExists, readFile, writeFile } from '../../../core/files';\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 { type AbstractIntlMessages, NextIntlClientProvider } from 'next-intl';\nimport type { SupportedLocale } from '@/types/i18n';\n`;\n content = imports + content;\n }\n\n if (hasUseClient) {\n content = `${useClientDirective}\\n${content}`;\n }\n\n // Extend props with locale/messages/timeZone. Handle two shapes:\n // 1) inline \u2014 `({ children }: { children: ReactNode })`\n // 2) aliased \u2014 `type RootProviderProps = { ... }` + `({ children }: RootProviderProps)`\n if (!content.includes('locale: SupportedLocale')) {\n const i18nFields = ` locale: SupportedLocale;\\n messages: AbstractIntlMessages;\\n timeZone: string;`;\n const aliasRe = /(type\\s+RootProviderProps\\s*=\\s*\\{)([\\s\\S]*?)(\\};?)/;\n const inlineRe = /export const RootProvider = \\(\\{([\\s\\S]*?)\\}: \\{([\\s\\S]*?)\\}\\) => \\{/;\n\n if (aliasRe.test(content)) {\n content = content.replace(aliasRe, (_m, open, body, close) => {\n const trimmed = body.replace(/\\s+$/, '');\n return `${open}${trimmed}\\n${i18nFields}\\n${close}`;\n });\n // Add locale/messages/timeZone to destructured args too.\n content = content.replace(\n /export const RootProvider = \\(\\{([\\s\\S]*?)\\}:\\s*RootProviderProps\\)/,\n (_m, inner) => {\n const existing = inner.trim().replace(/,$/, '');\n return `export const RootProvider = ({ ${existing ? `${existing}, ` : ''}locale, messages, timeZone }: RootProviderProps)`;\n },\n );\n } else {\n const match = content.match(inlineRe);\n if (match) {\n const existingParams = match[1].trim().replace(/,$/, '');\n const existingTypes = match[2].trim().replace(/;$/, '');\n const newParams = `\\n ${existingParams ? `${existingParams},\\n ` : ''}locale,\\n messages,\\n timeZone,`;\n const newTypes = `\\n ${existingTypes ? `${existingTypes};\\n ` : ''}locale: SupportedLocale;\\n messages: AbstractIntlMessages;\\n timeZone: string;`;\n content = content.replace(\n match[0],\n `export const RootProvider = ({${newParams}\\n}: {${newTypes}\\n}) => {`,\n );\n }\n }\n }\n\n // Wrap {children} with NextIntlClientProvider\n if (!content.includes('<NextIntlClientProvider')) {\n const returnMatch = content.match(/return\\s*(?:\\(\\s*)?([\\s\\S]*?)(?:\\s*\\))?;/);\n if (returnMatch) {\n const existingJsx = returnMatch[1];\n const wrapped = `<NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>\\n {children}\\n </NextIntlClientProvider>`;\n if (existingJsx.includes('{children}')) {\n const newJsx = existingJsx.replace('{children}', wrapped);\n content = content.replace(returnMatch[0], `return (\\n ${newJsx}\\n );`);\n } else {\n content = content.replace(\n returnMatch[0],\n `return (\\n <NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>\\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 = `import { routing } from '@/i18n/routing';\nimport { hasLocale } from 'next-intl';\nimport { notFound } from 'next/navigation';\nimport { getMessages, getTimeZone, setRequestLocale } from 'next-intl/server';\nimport { getLocaleDirection } from '@/lib/config/app-locales';\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, timeZone] = await Promise.all([getMessages(), getTimeZone()]);\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} timeZone={timeZone}>',\n );\n\n // 4. Update html lang and direction\n content = content.replace(\n /<html lang=\"en\"/,\n '<html lang={locale} dir={getLocaleDirection(locale)}',\n );\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 = `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 { setupI18n } from '../services/setup/i18n';\nimport { unwrapNextIntlPlugin } from './transforms/next-config';\nimport { unwrapJsxChain } from './transforms/unwrap-jsx';\nimport type { FeatureManifest } from './types';\n\nexport const i18nManifest: FeatureManifest = {\n id: 'i18n',\n name: 'Internationalization',\n description: 'next-intl with [locale] routing, RootProvider, and proxy.ts',\n detect: async (projectPath) => {\n const { detectProjectSetup } = await import('../detection');\n return (await detectProjectSetup(projectPath)).hasI18n;\n },\n files: [\n {\n path: 'src/i18n',\n generated: true,\n isDir: true,\n containsUserContent: true,\n removeHint:\n 'holds your translation JSON files \u2014 copy any you want to keep, then delete by hand',\n },\n { path: 'src/proxy.ts', generated: true },\n {\n path: 'src/app/[locale]',\n generated: true,\n isDir: true,\n containsUserContent: true,\n removeHint:\n 'holds every page you generated under the locale segment \u2014 move them to src/app/ before deleting',\n },\n ],\n packages: [{ name: 'next-intl', kind: 'dependency' }],\n scripts: [],\n injections: [\n {\n file: 'next.config.ts',\n description: 'createNextIntlPlugin wrap in next.config.ts',\n presence: /next-intl\\/plugin/,\n removePattern: unwrapNextIntlPlugin,\n },\n {\n file: 'src/providers/RootProvider.tsx',\n description: '<NextIntlClientProvider> wrap',\n presence: /NextIntlClientProvider/,\n removePattern: unwrapJsxChain('NextIntlClientProvider'),\n },\n ],\n apply: setupI18n,\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../config/paths';\nimport { fileExists, readFile } from '../core/files';\nimport { setupReactCompiler } from '../services/setup/react-compiler';\nimport type { FeatureManifest } from './types';\n\nexport const reactCompilerManifest: FeatureManifest = {\n id: 'react-compiler',\n name: 'React Compiler',\n description: 'reactCompiler: true in next.config.ts + babel-plugin-react-compiler',\n detect: async (projectPath) => {\n const target = path.join(projectPath, PROJECT_PATHS.NEXT_CONFIG);\n if (!fileExists(target)) return false;\n return /reactCompiler\\s*:\\s*true/.test(await readFile(target));\n },\n files: [],\n packages: [{ name: 'babel-plugin-react-compiler', kind: 'devDependency' }],\n scripts: [],\n injections: [\n {\n file: PROJECT_PATHS.NEXT_CONFIG,\n description: '`reactCompiler: true` flag',\n presence: /reactCompiler\\s*:\\s*true/,\n removePattern: /\\n\\s*reactCompiler:\\s*true,?/,\n },\n ],\n apply: setupReactCompiler,\n};\n", "import path from 'node:path';\nimport pc from 'picocolors';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { startSpinner } from '../../../config/spinner';\nimport { fileExists, readFile, writeFile } from '../../../core/files';\nimport { installDevPackage } from '../../../core/package-manager';\n\nexport const setupReactCompiler = async (projectPath: string): Promise<void> => {\n const spinner = startSpinner('Enabling React Compiler...');\n try {\n const nextConfigPath = path.join(projectPath, PROJECT_PATHS.NEXT_CONFIG);\n if (!fileExists(nextConfigPath)) {\n throw new Error(`${PROJECT_PATHS.NEXT_CONFIG} not found.`);\n }\n\n let content = await readFile(nextConfigPath);\n if (content.includes('reactCompiler:')) {\n spinner.fail('React Compiler is already configured in next.config.ts.');\n return;\n }\n\n // Inject `reactCompiler: true` inside `const nextConfig: NextConfig = { ... };`\n const configBlock = /(const\\s+nextConfig\\s*:\\s*NextConfig\\s*=\\s*\\{)/;\n if (!configBlock.test(content)) {\n throw new Error('Could not locate `const nextConfig: NextConfig = {` in next.config.ts.');\n }\n content = content.replace(configBlock, '$1\\n reactCompiler: true,');\n await writeFile(nextConfigPath, content);\n\n spinner.text = 'Installing babel-plugin-react-compiler...';\n await installDevPackage(projectPath, 'babel-plugin-react-compiler');\n\n spinner.succeed(pc.green('React Compiler enabled.'));\n } catch (error) {\n spinner.fail('Failed to enable React Compiler.');\n throw error;\n }\n};\n", "import path from 'node:path';\nimport pc from 'picocolors';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { startSpinner } from '../../../config/spinner';\nimport { deleteDirectory, fileExists, readFile } from '../../../core/files';\nimport { detectPackageManager, installPackage, runScript } from '../../../core/package-manager';\nimport { writeTestUtils } from '../../common/test-utils';\nimport { copyReduxFiles, createCounterFeature, fetchAssets } from './assets';\nimport { checkIsAlreadySetup, validateProjectStructure } from './checks';\nimport { updatePage, updateProvidersIndex, updateRootProvider } 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. If tests are present, regenerate test-utils so it wraps in Redux.\n const vitestConfigPath = path.join(projectPath, PROJECT_PATHS.VITEST_CONFIG);\n if (fileExists(vitestConfigPath)) {\n const pkg = JSON.parse(await readFile(path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON)));\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n await writeTestUtils(projectPath, { redux: true, i18n: !!deps['next-intl'] });\n }\n\n // 8. Format Code\n spinner.text = 'Formatting code...';\n const packageManager = await detectPackageManager(projectPath);\n await runScript(projectPath, packageManager, 'lint:fix');\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 fs from 'node:fs/promises';\nimport path from 'node:path';\nimport degit from 'degit';\nimport type { Ora } from 'ora';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { copyFile, fileExists, readFile, writeFile } from '../../../core/files';\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 { PROJECT_PATHS } from '../../../config/paths';\nimport { fileExists, readFile } from '../../../core/files';\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?.['@reduxjs/toolkit'] ||\n 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 { PROJECT_PATHS } from '../../../config/paths';\nimport { fileExists, readFile, writeFile } from '../../../core/files';\n\nexport const updateProvidersIndex = async (_projectPath: string): Promise<void> => {\n // StoreProvider is intentionally NOT exported from `@/providers` in the current\n // template \u2014 RootProvider imports it via a relative path. Nothing to do here.\n return;\n};\n\nexport const updateRootProvider = async (projectPath: string): Promise<void> => {\n const rootProviderPath = path.join(projectPath, 'src/providers/RootProvider.tsx');\n if (!fileExists(rootProviderPath)) return;\n\n let content = await readFile(rootProviderPath);\n\n const useClientDirective = \"'use client';\";\n const hasUseClient = content.includes(useClientDirective);\n if (hasUseClient) {\n content = content.replace(useClientDirective, '').trim();\n }\n\n // Ensure AppState + StoreProvider imports exist\n if (!content.includes(\"from '@/store'\")) {\n content = `import type { AppState } from '@/store';\\n${content}`;\n }\n if (!content.includes(\"from './StoreProvider'\")) {\n content = `${content.includes(\"from '@/store'\") ? '' : ''}import { StoreProvider } from './StoreProvider';\\n${content}`;\n }\n\n if (hasUseClient) {\n content = `${useClientDirective}\\n${content}`;\n }\n\n // Add preloadedState to props (both the type and the destructured args)\n if (!content.includes('preloadedState')) {\n content = content.replace(\n /children:\\s*React\\.ReactNode;/,\n 'children: React.ReactNode;\\n preloadedState?: Partial<AppState>;',\n );\n // Add to destructuring\n content = content.replace(\n /export const RootProvider = \\(\\{([\\s\\S]*?)\\}:/,\n (_m, inner) => `export const RootProvider = ({${inner}, preloadedState }:`,\n );\n // Clean up duplicate commas that may arise\n content = content\n .replace(/,\\s*,/g, ',')\n .replace(/\\{\\s*,/g, '{ ')\n .replace(/,\\s*\\}/g, ' }');\n }\n\n // Wrap the existing return JSX with StoreProvider\n if (!content.includes('<StoreProvider')) {\n const returnMatch = content.match(/return\\s*\\(\\s*([\\s\\S]*?)\\s*\\);/);\n if (returnMatch) {\n const existingJsx = returnMatch[1];\n content = content.replace(\n returnMatch[0],\n `return (\\n <StoreProvider preloadedState={preloadedState}>\\n ${existingJsx}\\n </StoreProvider>\\n );`,\n );\n }\n }\n\n await writeFile(rootProviderPath, content);\n};\n\nexport const updatePage = async (projectPath: string): Promise<void> => {\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 if (!pagePath) return;\n\n let pageContent = await readFile(pagePath);\n\n if (!pageContent.includes('Counter')) {\n pageContent = `import { Counter } from '@/features/counter';\\n${pageContent}`;\n }\n\n if (!pageContent.includes('<Counter />')) {\n const lastDivIndex = pageContent.lastIndexOf('</div>');\n const lastMainIndex = pageContent.lastIndexOf('</main>');\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=\"mb-4 text-2xl font-bold\">Redux Counter</h2>\\n <Counter />\\n </div>\\n' +\n pageContent.slice(insertIndex);\n await writeFile(pagePath, pageContent);\n }\n }\n};\n", "import { setupRedux } from '../services/setup/redux';\nimport { unwrapJsxChain } from './transforms/unwrap-jsx';\nimport type { FeatureManifest } from './types';\n\n/**\n * Slim manifest for Redux. Detection covers the typical footprint, but the\n * code injections (root reducer, providers chain, page wiring) aren't\n * encoded as `removePattern`s \u2014 `remove` reports them as manual cleanup so\n * the user can confirm before stripping.\n */\nexport const reduxManifest: FeatureManifest = {\n id: 'redux',\n name: 'Redux Toolkit',\n description: 'Redux Toolkit + react-redux + redux-persist + StoreProvider',\n detect: async (projectPath) => {\n const { detectProjectSetup } = await import('../detection');\n return (await detectProjectSetup(projectPath)).hasRedux;\n },\n files: [\n {\n path: 'src/store',\n generated: true,\n isDir: true,\n containsUserContent: true,\n removeHint: 'holds the rootReducer and any slices you registered \u2014 review before deleting',\n },\n { path: 'src/providers/StoreProvider.tsx', generated: true },\n ],\n packages: [\n { name: '@reduxjs/toolkit', kind: 'dependency' },\n { name: 'react-redux', kind: 'dependency' },\n { name: 'redux-persist', kind: 'dependency' },\n ],\n scripts: [],\n injections: [\n {\n file: 'src/providers/RootProvider.tsx',\n description: '<StoreProvider> wrap in RootProvider',\n presence: /<StoreProvider/,\n removePattern: unwrapJsxChain('StoreProvider'),\n },\n ],\n apply: setupRedux,\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../config/paths';\nimport { fileExists, readFile } from '../core/files';\nimport { hasSecurityHeaders, setupSecurityHeaders } from '../services/setup/security-headers';\nimport type { FeatureManifest } from './types';\n\nexport const securityHeadersManifest: FeatureManifest = {\n id: 'security-headers',\n name: 'Security Headers',\n description: 'Hardened HTTP headers in next.config.ts',\n detect: async (projectPath) => {\n const target = path.join(projectPath, PROJECT_PATHS.NEXT_CONFIG);\n if (!fileExists(target)) return false;\n return hasSecurityHeaders(await readFile(target));\n },\n files: [],\n packages: [],\n scripts: [],\n injections: [\n {\n file: PROJECT_PATHS.NEXT_CONFIG,\n description: 'headers() function in next.config.ts',\n presence: /^\\s+headers\\s*:/m,\n removePattern: /\\s+headers:\\s*async\\s*\\(\\)\\s*=>\\s*\\{[\\s\\S]*?\\n\\s{0,2}\\},/m,\n },\n ],\n apply: setupSecurityHeaders,\n};\n", "import path from 'node:path';\nimport pc from 'picocolors';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { startSpinner } from '../../../config/spinner';\nimport { fileExists, readFile, writeFile } from '../../../core/files';\nimport { hasSecurityHeaders, injectSecurityHeaders } from './headers';\n\nexport { hasSecurityHeaders, injectSecurityHeaders, SECURITY_HEADERS } from './headers';\n\nexport const setupSecurityHeaders = async (projectPath: string): Promise<void> => {\n const spinner = startSpinner('Adding security headers to next.config.ts...');\n try {\n const nextConfigPath = path.join(projectPath, PROJECT_PATHS.NEXT_CONFIG);\n if (!fileExists(nextConfigPath)) {\n throw new Error(`${PROJECT_PATHS.NEXT_CONFIG} not found.`);\n }\n\n const content = await readFile(nextConfigPath);\n if (hasSecurityHeaders(content)) {\n spinner.succeed('Security headers already configured.');\n return;\n }\n\n const updated = injectSecurityHeaders(content);\n await writeFile(nextConfigPath, updated);\n\n spinner.succeed(pc.green('Security headers added.'));\n } catch (error) {\n spinner.fail('Failed to add security headers.');\n throw error;\n }\n};\n", "/**\n * Pure transformation logic for the `setupSecurityHeaders` retrofit.\n *\n * Kept separate from `index.ts` so it can be unit-tested with string inputs\n * without touching the filesystem.\n */\n\n/**\n * The header set the starter ships in `next.config.ts`. Single source of truth\n * \u2014 `setupSecurityHeaders` and the manifest (D1) both consume this list.\n */\nexport const SECURITY_HEADERS: ReadonlyArray<{ key: string; value: string }> = [\n { key: 'X-DNS-Prefetch-Control', value: 'on' },\n {\n key: 'Strict-Transport-Security',\n value: 'max-age=63072000; includeSubDomains; preload',\n },\n { key: 'X-XSS-Protection', value: '1; mode=block' },\n { key: 'X-Frame-Options', value: 'SAMEORIGIN' },\n { key: 'X-Content-Type-Options', value: 'nosniff' },\n { key: 'Referrer-Policy', value: 'origin-when-cross-origin' },\n];\n\nconst NEXT_CONFIG_BLOCK_RE = /(const\\s+nextConfig\\s*:\\s*NextConfig\\s*=\\s*\\{)/;\n\n// Matches ` headers:` at the start of an indented line \u2014 the config-key\n// shape, not the `key: 'Permissions-Policy'` string-value shape.\nconst HEADERS_KEY_RE = /^\\s+headers\\s*:/m;\n\nconst buildHeadersBlock = (headers: ReadonlyArray<{ key: string; value: string }>): string => {\n const lines = headers\n .map(({ key, value }) => ` { key: '${key}', value: '${value}' },`)\n .join('\\n');\n\n return `\\n headers: async () => {\n return [\n {\n source: '/:path*',\n headers: [\n${lines}\n ],\n },\n ];\n },`;\n};\n\nexport const hasSecurityHeaders = (content: string): boolean => HEADERS_KEY_RE.test(content);\n\n/**\n * Inject the standard security-headers block into a `next.config.ts` source.\n *\n * - Idempotent: returns the input unchanged if a `headers:` key already exists\n * anywhere in the file (we never overwrite a user-defined header set).\n * - Throws if the canonical `const nextConfig: NextConfig = {` shape is missing\n * \u2014 same contract as the React-Compiler retrofit, so behaviour stays\n * predictable across `setup` services.\n */\nexport const injectSecurityHeaders = (\n content: string,\n headers: ReadonlyArray<{ key: string; value: string }> = SECURITY_HEADERS,\n): string => {\n if (hasSecurityHeaders(content)) {\n return content;\n }\n if (!NEXT_CONFIG_BLOCK_RE.test(content)) {\n throw new Error('Could not locate `const nextConfig: NextConfig = {` in next.config.ts.');\n }\n return content.replace(NEXT_CONFIG_BLOCK_RE, `$1${buildHeadersBlock(headers)}`);\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../config/paths';\nimport { fileExists } from '../core/files';\nimport { setupTests } from '../services/setup/tests';\nimport type { FeatureManifest } from './types';\n\nexport const testsManifest: FeatureManifest = {\n id: 'tests',\n name: 'Tests',\n description: 'Vitest + React Testing Library + jsdom',\n detect: async (projectPath) => fileExists(path.join(projectPath, PROJECT_PATHS.VITEST_CONFIG)),\n files: [\n { path: PROJECT_PATHS.VITEST_CONFIG, generated: true },\n {\n path: 'test',\n generated: true,\n isDir: true,\n containsUserContent: true,\n removeHint:\n 'holds setup.ts / test-utils.tsx and any helpers you added \u2014 review before deleting',\n },\n ],\n packages: [\n { name: 'vitest', kind: 'devDependency' },\n { name: 'jsdom', kind: 'devDependency' },\n { name: '@vitejs/plugin-react', kind: 'devDependency' },\n { name: '@testing-library/dom', kind: 'devDependency' },\n { name: '@testing-library/jest-dom', kind: 'devDependency' },\n { name: '@testing-library/react', kind: 'devDependency' },\n { name: '@testing-library/user-event', kind: 'devDependency' },\n ],\n scripts: [\n { name: 'test', expectedValue: 'vitest run' },\n { name: 'test:watch', expectedValue: 'vitest' },\n ],\n injections: [],\n apply: setupTests,\n};\n", "import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport degit from 'degit';\nimport pc from 'picocolors';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { startSpinner } from '../../../config/spinner';\nimport { copyFile, deleteDirectory, fileExists, readFile, updateJson } from '../../../core/files';\nimport { detectPackageManager, installDevPackages, runScript } from '../../../core/package-manager';\nimport { writeTestUtils } from '../../common/test-utils';\n\nconst TEST_DEVDEPS = [\n 'vitest',\n 'jsdom',\n '@vitejs/plugin-react',\n '@testing-library/dom',\n '@testing-library/jest-dom',\n '@testing-library/react',\n '@testing-library/user-event',\n];\n\nexport const setupTests = async (projectPath: string): Promise<void> => {\n const spinner = startSpinner('Setting up testing (Vitest + RTL)...');\n const tempDir = path.join(projectPath, '.next-maker-temp-tests');\n\n try {\n const vitestConfigPath = path.join(projectPath, PROJECT_PATHS.VITEST_CONFIG);\n if (fileExists(vitestConfigPath)) {\n spinner.fail('Testing is already set up (vitest.config.ts exists).');\n return;\n }\n\n // 1. Fetch the starter to copy vitest.config.ts + test/setup.ts.\n spinner.text = 'Fetching assets from starter repo...';\n const emitter = degit('teispace/nextjs-starter', { cache: false, force: true, verbose: false });\n await emitter.clone(tempDir);\n\n await copyFile(\n path.join(tempDir, PROJECT_PATHS.VITEST_CONFIG),\n path.join(projectPath, PROJECT_PATHS.VITEST_CONFIG),\n );\n\n const testDir = path.join(projectPath, PROJECT_PATHS.TEST_DIR);\n await fs.mkdir(testDir, { recursive: true });\n await copyFile(\n path.join(tempDir, PROJECT_PATHS.TEST_DIR, 'setup.ts'),\n path.join(testDir, 'setup.ts'),\n );\n\n // 2. Generate test-utils matching existing features.\n const packageJsonPath = path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON);\n const pkg = JSON.parse(await readFile(packageJsonPath));\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n const hasRedux = !!(deps['@reduxjs/toolkit'] && deps['react-redux']);\n const hasI18n = !!deps['next-intl'];\n await writeTestUtils(projectPath, { redux: hasRedux, i18n: hasI18n });\n\n // 3. Update package.json: scripts + reinstate `yarn test` in validate.\n await updateJson(packageJsonPath, (p) => {\n p.scripts = p.scripts ?? {};\n p.scripts.test = p.scripts.test ?? 'vitest run';\n p.scripts['test:watch'] = p.scripts['test:watch'] ?? 'vitest';\n p.scripts['test:coverage'] = p.scripts['test:coverage'] ?? 'vitest run --coverage';\n if (\n typeof p.scripts.validate === 'string' &&\n !/\\byarn\\s+test(?![:\\w])/.test(p.scripts.validate)\n ) {\n p.scripts.validate = p.scripts.validate.replace(\n /(\\byarn\\s+check:deprecated\\s*)(&&)/,\n '$1&& yarn test $2',\n );\n }\n return p;\n });\n\n // 4. Install dev deps.\n spinner.text = 'Installing testing devDependencies...';\n const manager = await detectPackageManager(projectPath);\n await installDevPackages(projectPath, manager, TEST_DEVDEPS);\n\n // 5. Format.\n spinner.text = 'Formatting code...';\n await runScript(projectPath, manager, 'lint:fix');\n\n spinner.succeed(pc.green('Testing setup complete.'));\n } catch (error) {\n spinner.fail('Failed to set up testing.');\n throw error;\n } finally {\n await deleteDirectory(tempDir);\n }\n};\n", "import path from 'node:path';\nimport { fileExists } from '../core/files';\nimport { setupValidationScripts } from '../services/setup/validate-scripts';\nimport type { FeatureManifest } from './types';\n\nconst SCRIPT_FILES = ['scripts/sync-env.ts', 'scripts/check-deprecated.ts'] as const;\n\nexport const validateScriptsManifest: FeatureManifest = {\n id: 'validate-scripts',\n name: 'Validation Scripts',\n description: 'sync-env, check-deprecated, and the validate chain',\n detect: async (projectPath) =>\n SCRIPT_FILES.every((rel) => fileExists(path.join(projectPath, rel))),\n files: SCRIPT_FILES.map((p) => ({ path: p, generated: true })),\n packages: [{ name: 'tsx', kind: 'devDependency' }],\n scripts: [\n { name: 'env:sync', expectedValue: 'tsx scripts/sync-env.ts' },\n { name: 'check:deprecated', expectedValue: 'tsx scripts/check-deprecated.ts' },\n { name: 'type-check', expectedValue: 'tsc --noEmit' },\n { name: 'validate' },\n ],\n injections: [],\n apply: setupValidationScripts,\n};\n", "import path from 'node:path';\nimport pc from 'picocolors';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { startSpinner } from '../../../config/spinner';\nimport { fileExists, updateJson, writeFile } from '../../../core/files';\nimport { detectPackageManager, installDevPackages } from '../../../core/package-manager';\nimport { addValidationScripts, type PackageJsonShape } from './package-modifier';\nimport { CHECK_DEPRECATED_SCRIPT, SYNC_ENV_SCRIPT } from './scripts';\n\nexport {\n addValidationScripts,\n type PackageJsonShape,\n} from './package-modifier';\nexport { CHECK_DEPRECATED_SCRIPT, SYNC_ENV_SCRIPT } from './scripts';\n\nconst SCRIPT_TARGETS = [\n { relative: 'scripts/sync-env.ts', content: SYNC_ENV_SCRIPT },\n { relative: 'scripts/check-deprecated.ts', content: CHECK_DEPRECATED_SCRIPT },\n] as const;\n\nexport const setupValidationScripts = async (projectPath: string): Promise<void> => {\n const spinner = startSpinner('Adding validation scripts...');\n try {\n // 1. Write script files (skip when present \u2014 never overwrite user edits)\n let wroteAny = false;\n for (const { relative, content } of SCRIPT_TARGETS) {\n const target = path.join(projectPath, relative);\n if (fileExists(target)) continue;\n await writeFile(target, content);\n wroteAny = true;\n }\n\n // 2. Patch package.json\n const manager = await detectPackageManager(projectPath);\n let needsTsx = false;\n await updateJson<PackageJsonShape>(\n path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON),\n (pkg) => {\n const before = pkg.devDependencies?.tsx;\n const next = addValidationScripts(pkg, manager);\n needsTsx = !before && !!next.devDependencies?.tsx;\n return next;\n },\n );\n\n // 3. Install tsx (only if it was newly added)\n if (needsTsx) {\n spinner.text = 'Installing tsx...';\n await installDevPackages(projectPath, manager, ['tsx']);\n }\n\n spinner.succeed(\n pc.green(\n wroteAny\n ? 'Validation scripts added (env:sync, check:deprecated, validate).'\n : 'Validation scripts already present \u2014 refreshed package.json.',\n ),\n );\n } catch (error) {\n spinner.fail('Failed to add validation scripts.');\n throw error;\n }\n};\n", "import type { PackageManager } from '../../../core/package-manager';\n\n/**\n * Pure modifiers for the package.json `scripts` block \u2014 separated from the\n * service so they can be unit-tested without touching the filesystem.\n */\n\nexport interface PackageJsonShape {\n scripts?: Record<string, string>;\n devDependencies?: Record<string, string>;\n [key: string]: unknown;\n}\n\nconst SCRIPT_RUNNER_PREFIX: Record<PackageManager, string> = {\n npm: 'npm run',\n yarn: 'yarn',\n pnpm: 'pnpm',\n bun: 'bun run',\n};\n\nconst buildValidateChain = (manager: PackageManager): string => {\n const prefix = SCRIPT_RUNNER_PREFIX[manager];\n return ['ci:check', 'type-check', 'check:deprecated', 'test', 'build']\n .map((name) => `${prefix} ${name}`)\n .join(' && ');\n};\n\n/**\n * Add the validation scripts (env:sync, check:deprecated, validate) and the\n * matching tsx/typescript dev-deps, never overwriting a user-defined entry.\n *\n * Returns a *new* package.json object \u2014 callers pass it through `updateJson`\n * which already understands \"function returns the new value\".\n */\nexport const addValidationScripts = (\n pkg: PackageJsonShape,\n manager: PackageManager,\n): PackageJsonShape => {\n const scripts = { ...(pkg.scripts ?? {}) };\n const devDeps = { ...(pkg.devDependencies ?? {}) };\n\n if (!scripts['env:sync']) {\n scripts['env:sync'] = 'tsx scripts/sync-env.ts';\n }\n if (!scripts['check:deprecated']) {\n scripts['check:deprecated'] = 'tsx scripts/check-deprecated.ts';\n }\n if (!scripts['type-check']) {\n scripts['type-check'] = 'tsc --noEmit';\n }\n if (!scripts.validate) {\n scripts.validate = buildValidateChain(manager);\n }\n\n if (!devDeps.tsx && !pkg.dependencies?.hasOwnProperty('tsx')) {\n devDeps.tsx = '*';\n }\n\n return { ...pkg, scripts, devDependencies: devDeps };\n};\n", "/**\n * Source for the two validation scripts the starter ships under `scripts/`.\n *\n * Inlined here (not fetched from the starter via degit) because (a) these\n * scripts are stable and don't drift, (b) we get instant offline retrofits,\n * and (c) the diff between starter and next-maker is small enough to spot\n * during release reviews. If they ever start to differ, switch this module\n * to a degit fetch \u2014 the rest of the service won't need to change.\n */\n\nexport const SYNC_ENV_SCRIPT = `import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nconst checkOnly = process.argv.includes('--check');\n\nconst envPath = path.join(process.cwd(), '.env');\nconst examplePath = path.join(process.cwd(), '.env.example');\n\nif (!fs.existsSync(envPath)) {\n console.log('\u26A0\uFE0F No .env file found. Skipping sync.');\n process.exit(0);\n}\n\nconst envContent = fs.readFileSync(envPath, 'utf-8');\nconst lines = envContent.split('\\\\n');\n\nlet isPublicBlock = false;\n\nconst exampleLines = lines.map((line) => {\n const trimmed = line.trim();\n\n // Preserve empty lines and reset public block state\n if (!trimmed) {\n isPublicBlock = false;\n return line;\n }\n\n // Preserve comments\n if (trimmed.startsWith('#')) {\n if (line.toLowerCase().includes('-public')) {\n isPublicBlock = true;\n }\n return line;\n }\n\n // Parse KEY=VALUE\n const match = line.match(/^([^=]+)=(.*)$/);\n\n if (match) {\n const key = match[1];\n\n // Public marker: explicit \"# -public\" comment, or \"KEY=VAL # -public\"\n if (isPublicBlock || line.toLowerCase().includes('-public')) {\n isPublicBlock = false;\n return line;\n }\n\n isPublicBlock = false;\n return \\`\\${key}=\\`;\n }\n\n isPublicBlock = false;\n return line;\n});\n\nconst newExampleContent = exampleLines.join('\\\\n');\n\nlet currentExampleContent = '';\nif (fs.existsSync(examplePath)) {\n currentExampleContent = fs.readFileSync(examplePath, 'utf-8');\n}\n\nif (currentExampleContent === newExampleContent) {\n console.log('\u2728 .env.example is already up to date');\n process.exit(0);\n}\n\nif (checkOnly) {\n console.error('\u274C .env.example is out of sync with .env. Run \"yarn env:sync\" to update.');\n process.exit(1);\n}\n\nfs.writeFileSync(examplePath, newExampleContent);\nconsole.log('\u2705 Synchronized .env.example with .env');\n`;\n\nexport const CHECK_DEPRECATED_SCRIPT = `/**\n * Walks every identifier in the project and flags any whose resolved TypeScript\n * symbol carries a \\`@deprecated\\` JSDoc tag. Catches deprecated API usage that\n * \\`tsc --noEmit\\` does not surface (deprecations are \"suggestion\"-level, not\n * errors) and that Biome does not yet detect.\n *\n * Exits 1 if any deprecated usage is found (so it can gate CI).\n */\nimport path from 'node:path';\nimport ts from 'typescript';\n\nconst cwd = process.cwd();\nconst configPath = ts.findConfigFile(cwd, ts.sys.fileExists, 'tsconfig.json');\n\nif (!configPath) {\n console.error('tsconfig.json not found');\n process.exit(1);\n}\n\nconst raw = ts.readConfigFile(configPath, ts.sys.readFile).config;\nconst parsed = ts.parseJsonConfigFileContent(raw, ts.sys, path.dirname(configPath));\n\nconst program = ts.createProgram({\n rootNames: parsed.fileNames,\n options: parsed.options,\n});\n\nconst checker = program.getTypeChecker();\n\nfunction isDeprecated(sym: ts.Symbol | undefined): boolean {\n if (!sym) return false;\n return sym.getJsDocTags(checker).some((tag) => tag.name === 'deprecated');\n}\n\nlet hits = 0;\n\nfor (const sourceFile of program.getSourceFiles()) {\n if (sourceFile.fileName.includes('node_modules')) continue;\n if (!sourceFile.fileName.startsWith(cwd)) continue;\n\n const visit = (node: ts.Node): void => {\n if (ts.isIdentifier(node)) {\n const sym = checker.getSymbolAtLocation(node);\n if (isDeprecated(sym)) {\n const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n console.log(\n \\`\\${path.relative(cwd, sourceFile.fileName)}:\\${line + 1}:\\${character + 1} \\${node.text} (@deprecated)\\`,\n );\n hits++;\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n}\n\nif (hits === 0) {\n console.log('\u2713 No deprecated API usage found.');\n process.exit(0);\n}\n\nconsole.log(\\`\\\\n\\${hits} deprecated symbol use(s) found.\\`);\nprocess.exit(1);\n`;\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../config/paths';\nimport { fileExists, readFile, writeFile } from '../core/files';\nimport { detectPackageManager, uninstallPackages } from '../core/package-manager';\nimport type {\n FeatureCheckResult,\n FeatureFinding,\n FeatureManifest,\n PackageRequirement,\n} from './types';\n\ninterface PackageJsonShape {\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n [key: string]: unknown;\n}\n\nconst readPackageJson = async (projectPath: string): Promise<PackageJsonShape | null> => {\n const pkgPath = path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON);\n if (!fileExists(pkgPath)) return null;\n return JSON.parse(await readFile(pkgPath));\n};\n\nconst writePackageJson = async (projectPath: string, pkg: PackageJsonShape): Promise<void> => {\n const pkgPath = path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON);\n await writeFile(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n};\n\nconst depsFor = (pkg: PackageJsonShape, kind: PackageRequirement['kind']): Record<string, string> =>\n (kind === 'dependency' ? pkg.dependencies : pkg.devDependencies) ?? {};\n\n/**\n * Compute drift: walk every piece of the manifest's footprint and report\n * what's missing or mismatched. Returns an empty array when the feature is\n * present and complete.\n */\nexport const checkManifest = async (\n manifest: FeatureManifest,\n projectPath: string,\n): Promise<FeatureCheckResult> => {\n const installed = await manifest.detect(projectPath);\n const drift: FeatureFinding[] = [];\n\n if (!installed) {\n return { manifest, installed: false, drift: [] };\n }\n\n for (const file of manifest.files) {\n const required = file.required !== false;\n if (!required) continue;\n if (!fileExists(path.join(projectPath, file.path))) {\n drift.push({ kind: 'missingFile', file: file.path });\n }\n }\n\n const pkg = await readPackageJson(projectPath);\n if (pkg) {\n for (const dep of manifest.packages) {\n const map = depsFor(pkg, dep.kind);\n if (!map[dep.name]) {\n drift.push({ kind: 'missingPackage', name: dep.name, depKind: dep.kind });\n }\n }\n\n const scripts = pkg.scripts ?? {};\n for (const script of manifest.scripts) {\n const actual = scripts[script.name];\n if (!actual) {\n drift.push({ kind: 'missingScript', name: script.name });\n } else if (script.expectedValue && actual !== script.expectedValue) {\n drift.push({\n kind: 'mismatchedScript',\n name: script.name,\n expected: script.expectedValue,\n actual,\n });\n }\n }\n }\n\n for (const injection of manifest.injections) {\n const filePath = path.join(projectPath, injection.file);\n if (!fileExists(filePath)) {\n drift.push({\n kind: 'missingInjection',\n file: injection.file,\n description: injection.description,\n });\n continue;\n }\n const content = await readFile(filePath);\n if (!injection.presence.test(content)) {\n drift.push({\n kind: 'missingInjection',\n file: injection.file,\n description: injection.description,\n });\n }\n }\n\n return { manifest, installed, drift };\n};\n\nexport interface RemoveSummary {\n filesRemoved: string[];\n packagesUninstalled: string[];\n scriptsRemoved: string[];\n blocksStripped: Array<{ file: string; description: string }>;\n /** Manual-cleanup items the runner couldn't safely remove. */\n manualCleanup: Array<{ file: string; description: string }>;\n}\n\n/**\n * Generic reverse: walk the footprint and undo what we can confidently undo.\n *\n * - Files marked `generated: true` are deleted.\n * - Files marked `generated: false` are left alone (user-owned).\n * - Packages are uninstalled.\n * - Scripts are removed from package.json.\n * - Code blocks with a `removePattern` are stripped; without one, they end\n * up in `manualCleanup` so the caller can prompt the user.\n *\n * The `dryRun` flag computes the summary without touching anything.\n */\nexport const reverseManifest = async (\n manifest: FeatureManifest,\n projectPath: string,\n options: { dryRun?: boolean } = {},\n): Promise<RemoveSummary> => {\n const dryRun = options.dryRun ?? false;\n const summary: RemoveSummary = {\n filesRemoved: [],\n packagesUninstalled: [],\n scriptsRemoved: [],\n blocksStripped: [],\n manualCleanup: [],\n };\n\n // 1. Strip code blocks first \u2014 they reference files/packages we may delete next.\n for (const injection of manifest.injections) {\n const filePath = path.join(projectPath, injection.file);\n if (!fileExists(filePath)) continue;\n if (!injection.removePattern) {\n summary.manualCleanup.push({ file: injection.file, description: injection.description });\n continue;\n }\n const content = await readFile(filePath);\n if (!injection.presence.test(content)) continue;\n\n // RemoveTransform supports two shapes \u2014 RegExp for simple replace, or a\n // function that returns the transformed content (or null to bail out to\n // manual cleanup when the file shape has drifted from expectations).\n let stripped: string;\n if (typeof injection.removePattern === 'function') {\n const out = injection.removePattern(content);\n if (out === null) {\n summary.manualCleanup.push({ file: injection.file, description: injection.description });\n continue;\n }\n stripped = out;\n } else {\n stripped = content.replace(injection.removePattern, '');\n }\n\n if (stripped !== content) {\n if (!dryRun) await writeFile(filePath, stripped);\n summary.blocksStripped.push({ file: injection.file, description: injection.description });\n } else {\n summary.manualCleanup.push({ file: injection.file, description: injection.description });\n }\n }\n\n // 2. Remove files we generated. Directories flagged as\n // `containsUserContent` are NEVER deleted \u2014 they're listed as manual\n // cleanup so the user can migrate their content first. This guards\n // against e.g. `remove i18n` wiping every page under src/app/[locale]/.\n const { rm } = await import('node:fs/promises');\n for (const file of manifest.files) {\n if (!file.generated) continue;\n const target = path.join(projectPath, file.path);\n if (!fileExists(target)) continue;\n if (file.containsUserContent) {\n const description = file.removeHint\n ? `${file.path} \u2014 ${file.removeHint}`\n : `${file.path} (may contain user-authored files; review before deleting)`;\n summary.manualCleanup.push({ file: file.path, description });\n continue;\n }\n if (!dryRun) {\n await rm(target, { recursive: true, force: true });\n }\n summary.filesRemoved.push(file.path);\n }\n\n // 3. Update package.json: scripts + deps.\n const pkg = await readPackageJson(projectPath);\n if (pkg) {\n let touched = false;\n if (pkg.scripts) {\n for (const script of manifest.scripts) {\n if (pkg.scripts[script.name]) {\n if (!dryRun) delete pkg.scripts[script.name];\n summary.scriptsRemoved.push(script.name);\n touched = true;\n }\n }\n }\n\n for (const dep of manifest.packages) {\n const map = depsFor(pkg, dep.kind);\n if (map[dep.name]) {\n summary.packagesUninstalled.push(dep.name);\n }\n }\n\n if (touched && !dryRun) {\n await writePackageJson(projectPath, pkg);\n }\n }\n\n // 4. Run the package manager uninstall (skipped on dry-run).\n if (!dryRun && summary.packagesUninstalled.length > 0) {\n const manager = await detectPackageManager(projectPath);\n await uninstallPackages(projectPath, manager, summary.packagesUninstalled);\n }\n\n return summary;\n};\n", "/**\n * Central registry of feature manifests. `doctor` and `remove` walk this\n * registry; `setup` imports individual manifests when it needs `apply`.\n */\n\nimport { bundleAnalyzerManifest } from './bundle-analyzer.manifest';\nimport { commitizenManifest } from './commitizen.manifest';\nimport { darkThemeManifest } from './dark-theme.manifest';\nimport { httpClientManifest } from './http-client.manifest';\nimport { i18nManifest } from './i18n.manifest';\nimport { reactCompilerManifest } from './react-compiler.manifest';\nimport { reduxManifest } from './redux.manifest';\nimport { securityHeadersManifest } from './security-headers.manifest';\nimport { testsManifest } from './tests.manifest';\nimport type { FeatureManifest } from './types';\nimport { validateScriptsManifest } from './validate-scripts.manifest';\n\nexport type { RemoveSummary } from './runner';\nexport { checkManifest, reverseManifest } from './runner';\nexport type {\n CodeBlockRequirement,\n DepKind,\n FeatureCheckResult,\n FeatureFinding,\n FeatureManifest,\n FileRequirement,\n PackageRequirement,\n ScriptRequirement,\n} from './types';\n\n/** Ordered for sensible doctor output: simple/visible features first. */\nexport const MANIFESTS: ReadonlyArray<FeatureManifest> = [\n securityHeadersManifest,\n validateScriptsManifest,\n commitizenManifest,\n reactCompilerManifest,\n bundleAnalyzerManifest,\n testsManifest,\n darkThemeManifest,\n httpClientManifest,\n reduxManifest,\n i18nManifest,\n];\n\nexport const getManifest = (id: string): FeatureManifest | undefined =>\n MANIFESTS.find((m) => m.id === id);\n\nexport {\n bundleAnalyzerManifest,\n commitizenManifest,\n darkThemeManifest,\n httpClientManifest,\n i18nManifest,\n reactCompilerManifest,\n reduxManifest,\n securityHeadersManifest,\n testsManifest,\n validateScriptsManifest,\n};\n", "import type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport {\n addEnvVar,\n type EnvVarSpec,\n type EnvVarType,\n ensurePublicPrefix,\n} from '../modifiers/env-var.modifier';\n\ninterface EnvCommandOptions {\n type?: string;\n required?: boolean;\n default?: string;\n public?: boolean;\n describe?: string;\n enum?: string;\n}\n\nconst VALID_TYPES: ReadonlySet<EnvVarType> = new Set([\n 'string',\n 'url',\n 'number',\n 'boolean',\n 'enum',\n]);\n\nconst parseType = (raw: string | undefined): EnvVarType => {\n const value = (raw ?? 'string').toLowerCase() as EnvVarType;\n if (!VALID_TYPES.has(value)) {\n throw new Error(`Invalid --type \"${raw}\". Valid: ${Array.from(VALID_TYPES).join(', ')}.`);\n }\n return value;\n};\n\nconst parseEnum = (raw: string | undefined): string[] | undefined => {\n if (!raw) return undefined;\n const values = raw\n .split(',')\n .map((v) => v.trim())\n .filter(Boolean);\n return values.length === 0 ? undefined : values;\n};\n\nexport const registerEnvCommand = (program: Command) => {\n program\n .command('env <NAME>')\n .description('Declare a new environment variable across schema, .env.example, and .env')\n .option('--type <type>', 'Zod type (string|url|number|boolean|enum)', 'string')\n .option('--required', 'Make the variable required (no .optional() / .default())')\n .option('--default <value>', 'Set a default value (mutually exclusive with --required)')\n .option('--public', 'Mark as public (auto-prefix NEXT_PUBLIC_ and tag .env.example)')\n .option('--describe <text>', 'Description (rendered as .describe() and .env.example comment)')\n .option('--enum <list>', 'Comma-separated values when --type=enum (e.g. \"dev,prod\")')\n .action(async (name: string, options: EnvCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\n log(pc.cyan('\\n\uD83D\uDD10 Env Var Generator\\n'));\n\n if (options.required && options.default !== undefined) {\n throw new Error('--required and --default are mutually exclusive.');\n }\n\n const type = parseType(options.type);\n const enumValues = parseEnum(options.enum);\n if (type === 'enum' && (!enumValues || enumValues.length === 0)) {\n throw new Error('--type=enum requires at least one value via --enum a,b,c.');\n }\n\n const spec: EnvVarSpec = {\n name,\n type,\n required: !!options.required,\n default: options.default,\n description: options.describe,\n enumValues,\n public: !!options.public,\n };\n\n spinner.start('Updating schema, .env.example, and .env...');\n const result = await addEnvVar(projectPath, spec);\n spinner.succeed('Env var written');\n\n const fullName = ensurePublicPrefix(spec.name, spec.public);\n log(pc.green(`\\n\u2728 ${fullName} declared.\\n`));\n log(pc.dim('Touched:'));\n log(pc.dim(` ${result.schemaUpdated ? '\u270F\uFE0F ' : '\u23ED '} src/lib/env/schema.ts`));\n log(pc.dim(` ${result.envExampleUpdated ? '\u270F\uFE0F ' : '\u23ED '} .env.example`));\n log(pc.dim(` ${result.envUpdated ? '\u270F\uFE0F ' : '\u23ED '} .env`));\n log('');\n } catch (error) {\n spinner.fail('Env var declaration failed');\n logError(`${error instanceof Error ? error.message : error}`);\n process.exit(1);\n }\n });\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../config/paths';\nimport { fileExists, readFile, writeFile } from '../core/files';\n\n/**\n * Adds a new environment variable across the four files that the starter\n * keeps in sync: `.env.example`, `.env` (when present), the Zod\n * `envSchema`, and the typed config. Each transformation is pure and\n * idempotent so the orchestrator can call them in any order without\n * worrying about duplicate writes.\n */\n\nexport type EnvVarType = 'string' | 'url' | 'number' | 'boolean' | 'enum';\n\nexport interface EnvVarSpec {\n /** UPPER_SNAKE_CASE identifier as it will appear in the schema and `.env`. */\n name: string;\n type: EnvVarType;\n required: boolean;\n /** When set, the schema gets `.default(...)` and `.env`/`.env.example` get this initial value. */\n default?: string;\n description?: string;\n /** Allowed values when `type === 'enum'`. */\n enumValues?: string[];\n /** When true, mark the value as public (visible to the browser via `# -public` and the NEXT_PUBLIC_ prefix). */\n public: boolean;\n}\n\nconst NAME_RE = /^[A-Z][A-Z0-9_]*$/;\n\nexport const validateName = (name: string): void => {\n if (!NAME_RE.test(name)) {\n throw new Error(\n `Invalid env var name \"${name}\". Use UPPER_SNAKE_CASE (e.g. SENTRY_DSN, NEXT_PUBLIC_API_URL).`,\n );\n }\n};\n\nexport const ensurePublicPrefix = (name: string, isPublic: boolean): string => {\n if (!isPublic) return name;\n return name.startsWith('NEXT_PUBLIC_') ? name : `NEXT_PUBLIC_${name}`;\n};\n\nconst formatDefault = (spec: EnvVarSpec): string => {\n if (spec.default === undefined) return '';\n switch (spec.type) {\n case 'number':\n return `.default(${Number(spec.default)})`;\n case 'boolean':\n return `.default(${spec.default === 'true'})`;\n default:\n return `.default('${spec.default.replace(/'/g, \"\\\\'\")}')`;\n }\n};\n\nconst baseSchemaTypeFor = (spec: EnvVarSpec): string => {\n switch (spec.type) {\n case 'url':\n return 'z.url()';\n case 'number':\n return 'z.coerce.number()';\n case 'boolean':\n return 'z.coerce.boolean()';\n case 'enum': {\n const values = spec.enumValues ?? [];\n if (values.length === 0) {\n throw new Error(`Enum env var \"${spec.name}\" requires --enum values.`);\n }\n const formatted = values.map((v) => `'${v.replace(/'/g, \"\\\\'\")}'`).join(', ');\n return `z.enum([${formatted}])`;\n }\n case 'string':\n default:\n return 'z.string()';\n }\n};\n\n/**\n * Build the line that goes inside `envSchema = z.object({ ... })`.\n *\n * Mirrors the starter's house style: numeric/string types get the\n * `preprocess(emptyStringToUndefined, \u2026)` wrapper so empty values in `.env`\n * don't pre-empt zod defaults; enums skip it because they reject empty\n * strings outright anyway.\n */\nexport const buildSchemaEntry = (spec: EnvVarSpec): string => {\n const fullName = ensurePublicPrefix(spec.name, spec.public);\n const base = baseSchemaTypeFor(spec);\n\n let inner = base;\n const hasDefault = spec.default !== undefined;\n const optional = !spec.required && !hasDefault;\n if (hasDefault) inner += formatDefault(spec);\n if (optional && spec.type !== 'enum') inner += '.optional()';\n\n let expression: string;\n if (spec.type === 'enum') {\n expression = inner;\n } else {\n expression = `z.preprocess(emptyStringToUndefined, ${inner})`;\n }\n\n if (spec.description) {\n const escaped = spec.description.replace(/'/g, \"\\\\'\");\n expression += `\\n .describe('${escaped}')`;\n }\n\n return ` ${fullName}: ${expression},`;\n};\n\nconst ENV_SCHEMA_RE = /(export const envSchema\\s*=\\s*z\\.object\\(\\{)([\\s\\S]*?)(\\}\\);?)/;\n\n/**\n * Insert a new entry into `envSchema = z.object({ ... })`. Preserves the\n * existing trailing newline shape and is idempotent.\n */\nexport const injectSchemaEntry = (content: string, spec: EnvVarSpec): string => {\n const fullName = ensurePublicPrefix(spec.name, spec.public);\n const presentRe = new RegExp(`\\\\b${fullName}\\\\s*:`);\n if (presentRe.test(content)) return content;\n\n const match = content.match(ENV_SCHEMA_RE);\n if (!match) {\n throw new Error('Could not locate `export const envSchema = z.object({ \u2026 })` in schema.ts.');\n }\n\n const [, head, body, tail] = match;\n const trimmedBody = body.replace(/\\s+$/, '');\n // Ensure prior entry ends with a comma so we don't end up with `foo: zX\\n NEW`\n const normalisedBody =\n trimmedBody.length === 0 || /,\\s*$/.test(trimmedBody) ? trimmedBody : `${trimmedBody},`;\n const entry = buildSchemaEntry(spec);\n const newBody = `${normalisedBody}\\n${entry}\\n`;\n return content.replace(ENV_SCHEMA_RE, `${head}${newBody}${tail}`);\n};\n\nconst PUBLIC_MARKER_SUFFIX = '# -public';\n\nconst exampleLineFor = (spec: EnvVarSpec): string => {\n const fullName = ensurePublicPrefix(spec.name, spec.public);\n const value = spec.default ?? '';\n const trailing = spec.public ? ` ${PUBLIC_MARKER_SUFFIX}` : '';\n return `${fullName}=${value}${trailing}`;\n};\n\n/**\n * Append a `KEY=` (or `KEY=defaultValue`) line to the .env.example contents.\n * Adds an optional comment line for the description. Idempotent.\n */\nexport const appendEnvExampleEntry = (content: string, spec: EnvVarSpec): string => {\n const fullName = ensurePublicPrefix(spec.name, spec.public);\n const lineRe = new RegExp(`^${fullName}=`, 'm');\n if (lineRe.test(content)) return content;\n\n const trailingNewline = content === '' || content.endsWith('\\n') ? '' : '\\n';\n const blank = content === '' ? '' : '\\n';\n const description = spec.description ? `# ${spec.description}\\n` : '';\n return `${content}${trailingNewline}${blank}${description}${exampleLineFor(spec)}\\n`;\n};\n\n/**\n * Mirror of `appendEnvExampleEntry` for `.env`. Always uses the spec default\n * (or empty) so secrets aren't leaked into the example file by mistake.\n * Idempotent.\n */\nexport const appendEnvEntry = (content: string, spec: EnvVarSpec): string => {\n const fullName = ensurePublicPrefix(spec.name, spec.public);\n const lineRe = new RegExp(`^${fullName}=`, 'm');\n if (lineRe.test(content)) return content;\n\n const trailingNewline = content === '' || content.endsWith('\\n') ? '' : '\\n';\n const value = spec.default ?? '';\n return `${content}${trailingNewline}${fullName}=${value}\\n`;\n};\n\nexport interface AddEnvVarResult {\n schemaUpdated: boolean;\n envExampleUpdated: boolean;\n envUpdated: boolean;\n}\n\n/**\n * Orchestrates the four-file update. Each step is independently idempotent\n * so partial failures are easy to recover from \u2014 re-running picks up where\n * the previous run left off.\n */\nexport const addEnvVar = async (\n projectPath: string,\n spec: EnvVarSpec,\n): Promise<AddEnvVarResult> => {\n validateName(spec.name);\n\n const schemaPath = path.join(projectPath, 'src/lib/env/schema.ts');\n if (!fileExists(schemaPath)) {\n throw new Error(`src/lib/env/schema.ts not found \u2014 run \\`next-maker init\\` first.`);\n }\n\n const schemaBefore = await readFile(schemaPath);\n const schemaAfter = injectSchemaEntry(schemaBefore, spec);\n const schemaUpdated = schemaAfter !== schemaBefore;\n if (schemaUpdated) await writeFile(schemaPath, schemaAfter);\n\n const envExamplePath = path.join(projectPath, PROJECT_PATHS.ENV_EXAMPLE);\n let envExampleUpdated = false;\n if (fileExists(envExamplePath)) {\n const before = await readFile(envExamplePath);\n const after = appendEnvExampleEntry(before, spec);\n envExampleUpdated = after !== before;\n if (envExampleUpdated) await writeFile(envExamplePath, after);\n }\n\n const envPath = path.join(projectPath, '.env');\n let envUpdated = false;\n if (fileExists(envPath)) {\n const before = await readFile(envPath);\n const after = appendEnvEntry(before, spec);\n envUpdated = after !== before;\n if (envUpdated) await writeFile(envPath, after);\n }\n\n return { schemaUpdated, envExampleUpdated, envUpdated };\n};\n", "import path from 'node:path';\nimport type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner, warning } from '../config';\nimport { promptForFaviconSource } from '../prompts/favicon.prompt';\nimport { detectAppDir, runFavicon } from '../services/favicon';\nimport { CSS_NAMED_COLORS } from '../services/favicon/css-colors';\nimport type { FaviconFit, FaviconOptions, FaviconShape } from '../services/favicon/types';\nimport { parseSizes } from '../services/favicon/validate';\n\ninterface RawFaviconCliOptions {\n path?: string;\n out?: string;\n force?: boolean;\n dryRun?: boolean;\n\n icon?: boolean;\n apple?: boolean;\n og?: boolean;\n ogSource?: string;\n twitter?: boolean;\n all?: boolean;\n\n pwa?: boolean;\n pwaInit?: boolean;\n\n shape?: string;\n radius?: string;\n bg?: string;\n padding?: string;\n fit?: string;\n sizes?: string;\n quality?: string;\n}\n\nconst SHAPES: FaviconShape[] = ['square', 'rounded', 'circle', 'squircle'];\nconst FITS: FaviconFit[] = ['contain', 'cover', 'clip'];\n\nconst parseEnumOption = <T extends string>(\n raw: string | undefined,\n allowed: T[],\n fallback: T,\n flag: string,\n): T => {\n if (!raw) return fallback;\n if (!allowed.includes(raw as T)) {\n throw new Error(`Invalid value for --${flag}: '${raw}'. Allowed: ${allowed.join(', ')}`);\n }\n return raw as T;\n};\n\nconst parseNumberOption = (\n raw: string | undefined,\n fallback: number,\n flag: string,\n min: number,\n max: number,\n): number => {\n if (raw === undefined) return fallback;\n const n = Number(raw);\n if (!Number.isFinite(n) || n < min || n > max) {\n throw new Error(\n `Invalid value for --${flag}: '${raw}'. Must be a number between ${min}\u2013${max}.`,\n );\n }\n return n;\n};\n\nexport const registerFaviconCommand = (program: Command) => {\n program\n .command('favicon')\n .description('Generate favicon.ico (and optionally icons, OG image, PWA manifest icons)')\n .option('--path <file>', 'Path to source image (PNG, JPG, JPEG, WebP, SVG, AVIF)')\n .option('--out <dir>', 'Output dir (default: src/app or app)')\n .option('--force', 'Overwrite existing files without prompt', false)\n .option('--dry-run', 'Show what would be written without writing', false)\n .option('--icon', 'Also emit icon.png (512\u00D7512)', false)\n .option('--apple', 'Also emit apple-icon.png (180\u00D7180)', false)\n .option('--og', 'Also emit opengraph-image.png (1200\u00D7630)', false)\n .option('--og-source <file>', 'Use a separate image for the OG/Twitter card')\n .option('--twitter', 'Also emit twitter-image.png (1200\u00D7600)', false)\n .option('--all', 'Shorthand for --icon --apple --og', false)\n .option(\n '--pwa',\n 'Detect PWA setup and emit manifest icons (192/512); errors if not detected',\n false,\n )\n .option('--pwa-init', 'Bootstrap public/manifest.webmanifest with icons', false)\n .option('--shape <shape>', 'square | rounded | circle | squircle', 'square')\n .option('--radius <percent>', 'Corner radius % when shape=rounded (0-50)', '20')\n .option('--bg <color>', 'Background color (hex, css name, or \"transparent\")', 'transparent')\n .option('--padding <percent>', 'Padding around source content (0-30)', '0')\n .option('--fit <fit>', 'How source fits target: contain | cover | clip', 'contain')\n .option('--sizes <list>', 'Comma-separated ICO sizes (default: 16,32,48)')\n .option(\n '--quality <n>',\n 'PNG compression 1-100 (higher = smaller file; PNG is lossless, default: 90)',\n '90',\n )\n .action(async (raw: RawFaviconCliOptions) => {\n try {\n const projectPath = process.cwd();\n\n log(pc.cyan('\\n\uD83C\uDFA8 Favicon Generator\\n'));\n\n const promptResult = await promptForFaviconSource({ source: raw.path });\n\n const outDir = await resolveOutDir(projectPath, raw.out);\n const shape = parseEnumOption(raw.shape, SHAPES, 'square', 'shape');\n const fit = parseEnumOption(raw.fit, FITS, 'contain', 'fit');\n const radius = parseNumberOption(raw.radius, 20, 'radius', 0, 50);\n const padding = parseNumberOption(raw.padding, 0, 'padding', 0, 30);\n const quality = parseNumberOption(raw.quality, 90, 'quality', 1, 100);\n const icoSizes = parseSizes(raw.sizes, [16, 32, 48]);\n const bg = raw.bg ?? 'transparent';\n validateBg(bg);\n\n const all = raw.all === true;\n const options: FaviconOptions = {\n source: promptResult.source,\n outDir,\n force: !!raw.force,\n dryRun: !!raw.dryRun,\n emitIcon: !!raw.icon || all,\n emitApple: !!raw.apple || all,\n emitOg: !!raw.og || all,\n emitTwitter: !!raw.twitter,\n ogSource: raw.ogSource,\n pwa: !!raw.pwa,\n pwaInit: !!raw.pwaInit,\n shape,\n radius,\n bg,\n padding,\n fit,\n icoSizes,\n quality,\n };\n\n spinner.start('Generating favicon assets...');\n const result = await runFavicon(projectPath, options);\n spinner.succeed(options.dryRun ? 'Favicon plan ready' : 'Favicon assets generated');\n\n log('');\n for (const out of result.outputs) {\n const rel = path.relative(projectPath, out.path);\n if (out.skipped) {\n log(pc.yellow(` \u21B7 skipped ${rel} (exists; use --force to overwrite)`));\n } else if (options.dryRun) {\n log(pc.dim(` \uD83D\uDCC4 would write ${rel} (${formatBytes(out.bytes)})`));\n } else {\n log(pc.green(` \u2713 ${rel} `) + pc.dim(`(${formatBytes(out.bytes)})`));\n }\n }\n\n if (result.pwaSnippet) {\n log('');\n log(pc.cyan('Add this to your typed manifest (src/app/manifest.ts):'));\n log(pc.dim(result.pwaSnippet));\n }\n\n log('');\n } catch (err) {\n spinner.fail('Favicon generation failed');\n const message = err instanceof Error ? err.message : String(err);\n logError(message);\n process.exit(1);\n }\n });\n};\n\nconst resolveOutDir = async (projectPath: string, override?: string): Promise<string> => {\n if (override) return path.isAbsolute(override) ? override : path.resolve(projectPath, override);\n const detected = await detectAppDir(projectPath);\n if (detected) return detected;\n warning('Could not detect app/ or src/app/ \u2014 falling back to src/app');\n return path.join(projectPath, 'src', 'app');\n};\n\nconst HEX_RE = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;\nconst FUNCTIONAL_RE = /^(?:rgb|rgba|hsl|hsla)\\(\\s*[\\d.,%\\s/]+\\)$/i;\n\nconst validateBg = (bg: string): void => {\n if (bg === 'transparent') return;\n if (HEX_RE.test(bg)) return;\n if (FUNCTIONAL_RE.test(bg)) return;\n if (CSS_NAMED_COLORS.has(bg.toLowerCase())) return;\n throw new Error(\n `Invalid value for --bg: '${bg}'. Use 'transparent', a hex code (e.g. #0f172a), a CSS color name, or rgb()/rgba()/hsl()/hsla().`,\n );\n};\n\nconst formatBytes = (n: number): string => {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n return `${(n / 1024 / 1024).toFixed(2)} MB`;\n};\n", "import Enquirer from 'enquirer';\n\nconst { prompt } = Enquirer;\n\nexport interface FaviconPromptResult {\n source: string;\n}\n\nexport const promptForFaviconSource = async (\n presets: { source?: string } = {},\n): Promise<FaviconPromptResult> => {\n if (presets.source) return { source: presets.source };\n\n const answer = (await prompt({\n type: 'input',\n name: 'source',\n message: 'Path to source image (PNG/JPG/JPEG/SVG/WebP/AVIF):',\n validate: (value: string) => {\n if (!value) return 'Source path is required';\n return true;\n },\n })) as { source: string };\n\n return { source: answer.source };\n};\n", "import { access, readFile, stat } from 'node:fs/promises';\nimport path from 'node:path';\n\nconst exists = async (p: string): Promise<boolean> => {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n};\n\nconst isDirectory = async (p: string): Promise<boolean> => {\n try {\n return (await stat(p)).isDirectory();\n } catch {\n return false;\n }\n};\n\n/**\n * Resolve the App Router directory for metadata files.\n * Prefers `src/app`, falls back to `app`. Returns absolute path.\n */\nexport const detectAppDir = async (projectPath: string): Promise<string | null> => {\n const candidates = [path.join(projectPath, 'src', 'app'), path.join(projectPath, 'app')];\n for (const candidate of candidates) {\n if (await isDirectory(candidate)) return candidate;\n }\n return null;\n};\n\nexport interface PwaDetection {\n isPwa: boolean;\n /** Path to a static manifest file (json/webmanifest) if present in /public. */\n publicManifestPath?: string;\n /** Path to a typed `manifest.ts`/`manifest.tsx` in app dir if present. */\n appManifestPath?: string;\n /** Detected PWA framework, if any. */\n framework?: 'next-pwa' | '@ducanh2912/next-pwa' | '@serwist/next' | 'serwist';\n}\n\nconst PWA_PACKAGES = ['next-pwa', '@ducanh2912/next-pwa', '@serwist/next', 'serwist'] as const;\n\nexport const detectPwa = async (projectPath: string): Promise<PwaDetection> => {\n const result: PwaDetection = { isPwa: false };\n\n // Static manifest in /public\n const publicCandidates = [\n path.join(projectPath, 'public', 'manifest.json'),\n path.join(projectPath, 'public', 'manifest.webmanifest'),\n path.join(projectPath, 'public', 'site.webmanifest'),\n ];\n for (const p of publicCandidates) {\n if (await exists(p)) {\n result.publicManifestPath = p;\n result.isPwa = true;\n break;\n }\n }\n\n // Typed manifest in app dir\n const appDir = await detectAppDir(projectPath);\n if (appDir) {\n for (const ext of ['ts', 'tsx', 'js']) {\n const candidate = path.join(appDir, `manifest.${ext}`);\n if (await exists(candidate)) {\n result.appManifestPath = candidate;\n result.isPwa = true;\n break;\n }\n }\n }\n\n // Package-based detection\n try {\n const pkg = JSON.parse(await readFile(path.join(projectPath, 'package.json'), 'utf-8'));\n const deps = { ...pkg.dependencies, ...pkg.devDependencies } as Record<string, string>;\n for (const name of PWA_PACKAGES) {\n if (deps[name]) {\n result.framework = name;\n result.isPwa = true;\n break;\n }\n }\n } catch {\n /* no package.json \u2014 skip */\n }\n\n return result;\n};\n", "import { mkdir, readFile, stat, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport sharp from 'sharp';\nimport { detectPwa } from './detect';\nimport { encodeIco, flatColor, renderPng } from './encoders';\nimport {\n buildBootstrapManifest,\n buildIconEntries,\n patchJsonManifest,\n renderManifestSnippet,\n} from './manifest';\nimport type { FaviconOptions, FaviconRunResult, FaviconWriteResult } from './types';\nimport { validateSource } from './validate';\n\nconst fileExists = async (p: string): Promise<boolean> => {\n try {\n await stat(p);\n return true;\n } catch {\n return false;\n }\n};\n\ninterface WriteJob {\n outPath: string;\n bytes: Buffer;\n /** When true, overwrite even if the target exists and --force is not set. */\n alwaysWrite?: boolean;\n}\n\nconst writeAll = async (\n jobs: WriteJob[],\n force: boolean,\n dryRun: boolean,\n): Promise<FaviconWriteResult[]> => {\n const results: FaviconWriteResult[] = [];\n for (const job of jobs) {\n const exists = await fileExists(job.outPath);\n if (exists && !force && !job.alwaysWrite) {\n results.push({ path: job.outPath, bytes: job.bytes.length, skipped: true });\n continue;\n }\n if (!dryRun) {\n await mkdir(path.dirname(job.outPath), { recursive: true });\n await writeFile(job.outPath, job.bytes);\n }\n results.push({ path: job.outPath, bytes: job.bytes.length });\n }\n return results;\n};\n\nexport const runFavicon = async (\n projectPath: string,\n options: FaviconOptions,\n): Promise<FaviconRunResult> => {\n const source = await validateSource(options.source);\n const sourceBuffer = await readFile(source.absolutePath);\n const ogSourceBuffer = options.ogSource\n ? await readFile((await validateSource(options.ogSource)).absolutePath)\n : sourceBuffer;\n\n const jobs: WriteJob[] = [];\n\n // 1. favicon.ico \u2014 always, multi-size, square\n const icoFrames: Buffer[] = [];\n for (const size of options.icoSizes) {\n icoFrames.push(\n await renderPng({\n sourceBuffer,\n size,\n shape: 'square',\n radiusPercent: options.radius,\n bg: options.bg,\n paddingPercent: options.padding,\n fit: options.fit,\n quality: options.quality,\n forceSquare: true,\n }),\n );\n }\n const icoBuffer = await encodeIco(icoFrames);\n jobs.push({ outPath: path.join(options.outDir, 'favicon.ico'), bytes: icoBuffer });\n\n // 2. icon.png (512\u00D7512)\n if (options.emitIcon) {\n const buf = await renderPng({\n sourceBuffer,\n size: 512,\n shape: options.shape,\n radiusPercent: options.radius,\n bg: options.bg,\n paddingPercent: options.padding,\n fit: options.fit,\n quality: options.quality,\n });\n jobs.push({ outPath: path.join(options.outDir, 'icon.png'), bytes: buf });\n }\n\n // 3. apple-icon.png (180\u00D7180, opaque bg per Apple guidelines)\n if (options.emitApple) {\n const appleBg = options.bg === 'transparent' ? '#ffffff' : options.bg;\n const buf = await renderPng({\n sourceBuffer,\n size: 180,\n shape: options.shape,\n radiusPercent: options.radius,\n bg: appleBg,\n paddingPercent: options.padding,\n fit: options.fit,\n quality: options.quality,\n });\n jobs.push({ outPath: path.join(options.outDir, 'apple-icon.png'), bytes: buf });\n }\n\n // 4. opengraph-image.png (1200\u00D7630, contained on bg)\n if (options.emitOg) {\n const buf = await renderOgImage(ogSourceBuffer, options, false);\n jobs.push({ outPath: path.join(options.outDir, 'opengraph-image.png'), bytes: buf });\n }\n\n // 5. twitter-image.png (1200\u00D7600)\n if (options.emitTwitter) {\n const buf = await renderOgImage(ogSourceBuffer, options, true);\n jobs.push({ outPath: path.join(options.outDir, 'twitter-image.png'), bytes: buf });\n }\n\n // 6. PWA icons + manifest\n let pwaSnippet: string | undefined;\n if (options.pwa || options.pwaInit) {\n const pwa = await detectPwa(projectPath);\n if (options.pwa && !pwa.isPwa) {\n throw new Error(\n 'No PWA setup detected. Use --pwa-init to bootstrap a manifest, or set up next-pwa/serwist first.',\n );\n }\n\n const publicDir = path.join(projectPath, 'public');\n const sizes = [192, 512];\n const iconJobs: { src: string; size: number }[] = [];\n for (const size of sizes) {\n const buf = await renderPng({\n sourceBuffer,\n size,\n shape: options.shape,\n radiusPercent: options.radius,\n bg: options.bg,\n paddingPercent: options.padding,\n fit: options.fit,\n quality: options.quality,\n });\n const fileName = `icon-${size}.png`;\n jobs.push({ outPath: path.join(publicDir, fileName), bytes: buf });\n iconJobs.push({ src: `/${fileName}`, size });\n }\n\n const icons = buildIconEntries(iconJobs);\n if (pwa.publicManifestPath) {\n // Patched manifest merges with existing content, so always write it back.\n const next = await patchJsonManifest(pwa.publicManifestPath, icons);\n jobs.push({\n outPath: pwa.publicManifestPath,\n bytes: Buffer.from(next, 'utf-8'),\n alwaysWrite: true,\n });\n } else if (pwa.appManifestPath) {\n pwaSnippet = renderManifestSnippet(icons);\n } else if (options.pwaInit) {\n const bootstrapPath = path.join(publicDir, 'manifest.webmanifest');\n const content = buildBootstrapManifest(path.basename(projectPath) || 'App', '#000000', icons);\n jobs.push({ outPath: bootstrapPath, bytes: Buffer.from(content, 'utf-8') });\n }\n }\n\n const outputs = await writeAll(jobs, options.force, options.dryRun);\n return { outputs, pwaSnippet };\n};\n\nconst renderOgImage = async (\n sourceBuffer: Buffer,\n options: FaviconOptions,\n isTwitter: boolean,\n): Promise<Buffer> => {\n const targetWidth = 1200;\n const targetHeight = isTwitter ? 600 : 630;\n const innerSize = Math.round(\n Math.min(targetWidth, targetHeight) * (1 - (options.padding * 2) / 100),\n );\n\n const inner = await renderPng({\n sourceBuffer,\n size: innerSize,\n shape: options.shape,\n radiusPercent: options.radius,\n bg: 'transparent',\n paddingPercent: 0,\n fit: options.fit,\n quality: options.quality,\n });\n\n const bgColor = options.bg === 'transparent' ? '#ffffff' : options.bg;\n const background = await flatColor(bgColor);\n const offsetLeft = Math.round((targetWidth - innerSize) / 2);\n const offsetTop = Math.round((targetHeight - innerSize) / 2);\n\n return sharp({\n create: {\n width: targetWidth,\n height: targetHeight,\n channels: 4,\n background,\n },\n })\n .composite([{ input: inner, left: offsetLeft, top: offsetTop }])\n .png()\n .toBuffer();\n};\n", "import pngToIco from 'png-to-ico';\nimport sharp from 'sharp';\nimport { buildBackground, buildShapeMask } from './shapes';\nimport type { FaviconFit, FaviconShape } from './types';\n\nexport interface RenderOptions {\n /** Pre-loaded source bytes \u2014 read once by the pipeline and reused per size. */\n sourceBuffer: Buffer;\n size: number;\n shape: FaviconShape;\n radiusPercent: number;\n bg: string;\n paddingPercent: number;\n fit: FaviconFit;\n /** PNG compression level mapped 1..100 \u2192 9..0; lossless, affects file size only. */\n quality: number;\n /** When true, never apply shape clipping (used for ICO frames). */\n forceSquare?: boolean;\n}\n\nexport const renderPng = async (opts: RenderOptions): Promise<Buffer> => {\n const {\n size,\n paddingPercent,\n bg,\n fit,\n shape,\n radiusPercent,\n quality,\n forceSquare,\n sourceBuffer,\n } = opts;\n\n const innerSize = Math.max(1, Math.round(size * (1 - (paddingPercent * 2) / 100)));\n\n const sharpFit = fit === 'cover' ? 'cover' : 'contain';\n const resized = await sharp(sourceBuffer, { density: 384 })\n .resize(innerSize, innerSize, {\n fit: sharpFit,\n background: { r: 0, g: 0, b: 0, alpha: 0 },\n })\n .png()\n .toBuffer();\n\n const offset = Math.round((size - innerSize) / 2);\n const canvasBg = bg === 'transparent' ? { r: 0, g: 0, b: 0, alpha: 0 } : await flatColor(bg);\n\n let composed = await sharp({\n create: {\n width: size,\n height: size,\n channels: 4,\n background: canvasBg,\n },\n })\n .composite([{ input: resized, left: offset, top: offset }])\n .png()\n .toBuffer();\n\n // forceSquare wins absolutely \u2014 ICO frames must stay rectangular regardless of --fit.\n const shouldClip = !forceSquare && (shape !== 'square' || fit === 'clip');\n if (shouldClip) {\n const clipShape: FaviconShape = shape === 'square' ? 'rounded' : shape;\n const mask = Buffer.from(buildShapeMask(clipShape, size, radiusPercent));\n composed = await sharp(composed)\n .composite([{ input: mask, blend: 'dest-in' }])\n .png({ compressionLevel: clampCompression(quality) })\n .toBuffer();\n } else {\n composed = await sharp(composed)\n .png({ compressionLevel: clampCompression(quality) })\n .toBuffer();\n }\n\n return composed;\n};\n\nexport const flatColor = async (color: string): Promise<sharp.Color> => {\n // Use sharp to parse arbitrary CSS color via a tiny SVG \u2192 first pixel.\n const probe = await sharp(Buffer.from(buildBackground(1, color)))\n .raw()\n .toBuffer({ resolveWithObject: true });\n const [r, g, b, a = 255] = probe.data;\n return { r, g, b, alpha: a / 255 };\n};\n\nconst clampCompression = (quality: number): number => {\n // sharp PNG compressionLevel: 0 (fastest, biggest) \u2013 9 (slowest, smallest).\n // Map quality 1..100 inversely: high quality \u2192 high compression for small files.\n const n = Math.round(((100 - quality) / 100) * 9);\n return Math.max(0, Math.min(9, n));\n};\n\n/**\n * Build a multi-size ICO from a set of source PNG buffers.\n */\nexport const encodeIco = async (frames: Buffer[]): Promise<Buffer> => {\n if (frames.length === 0) throw new Error('No frames provided to encodeIco');\n return pngToIco(frames);\n};\n", "import type { FaviconShape } from './types';\n\nconst escapeForXml = (value: string): string =>\n value.replace(/&/g, '&').replace(/\"/g, '"').replace(/</g, '<');\n\n/**\n * Build an SVG mask (white shape on transparent) sized to `size` \u00D7 `size`.\n * Used as a destIn composite over the resized source to clip it to the shape.\n */\nexport const buildShapeMask = (\n shape: FaviconShape,\n size: number,\n radiusPercent: number,\n): string => {\n switch (shape) {\n case 'square':\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${size}\" height=\"${size}\"><rect width=\"${size}\" height=\"${size}\" fill=\"white\"/></svg>`;\n case 'circle': {\n const r = size / 2;\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${size}\" height=\"${size}\"><circle cx=\"${r}\" cy=\"${r}\" r=\"${r}\" fill=\"white\"/></svg>`;\n }\n case 'rounded': {\n const r = Math.round((size * radiusPercent) / 100);\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${size}\" height=\"${size}\"><rect width=\"${size}\" height=\"${size}\" rx=\"${r}\" ry=\"${r}\" fill=\"white\"/></svg>`;\n }\n case 'squircle':\n return buildSquircle(size);\n }\n};\n\n/**\n * iOS-style squircle (superellipse, n\u22484). Approximated with a cubic-bezier path.\n */\nconst buildSquircle = (size: number): string => {\n const s = size;\n const c = s * 0.225; // bezier control offset for a smooth ~iOS squircle\n const path = [\n `M 0 ${c}`,\n `C 0 0 0 0 ${c} 0`,\n `L ${s - c} 0`,\n `C ${s} 0 ${s} 0 ${s} ${c}`,\n `L ${s} ${s - c}`,\n `C ${s} ${s} ${s} ${s} ${s - c} ${s}`,\n `L ${c} ${s}`,\n `C 0 ${s} 0 ${s} 0 ${s - c}`,\n 'Z',\n ].join(' ');\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${s}\" height=\"${s}\"><path d=\"${escapeForXml(path)}\" fill=\"white\"/></svg>`;\n};\n\n/**\n * Build a flat-color background SVG of the given size.\n */\nexport const buildBackground = (size: number, color: string): string =>\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${size}\" height=\"${size}\"><rect width=\"${size}\" height=\"${size}\" fill=\"${escapeForXml(color)}\"/></svg>`;\n", "import { readFile, writeFile } from 'node:fs/promises';\n\nexport interface ManifestIcon {\n src: string;\n sizes: string;\n type: string;\n purpose?: string;\n}\n\nexport const buildIconEntries = (publicPaths: { src: string; size: number }[]): ManifestIcon[] =>\n publicPaths.map(({ src, size }) => ({\n src,\n sizes: `${size}x${size}`,\n type: 'image/png',\n purpose: 'any maskable',\n }));\n\n/**\n * Merge new icons into a JSON manifest, deduping by `src`. Returns the\n * formatted JSON string ready to write back.\n */\nexport const patchJsonManifest = async (\n manifestPath: string,\n icons: ManifestIcon[],\n): Promise<string> => {\n const raw = await readFile(manifestPath, 'utf-8');\n const parsed = JSON.parse(raw) as { icons?: ManifestIcon[]; [key: string]: unknown };\n const existing = Array.isArray(parsed.icons) ? parsed.icons : [];\n const bySrc = new Map<string, ManifestIcon>();\n for (const icon of [...existing, ...icons]) {\n if (icon && typeof icon.src === 'string') bySrc.set(icon.src, icon);\n }\n parsed.icons = [...bySrc.values()];\n return `${JSON.stringify(parsed, null, 2)}\\n`;\n};\n\nexport const writeJsonManifest = async (\n manifestPath: string,\n icons: ManifestIcon[],\n): Promise<void> => {\n const next = await patchJsonManifest(manifestPath, icons);\n await writeFile(manifestPath, next, 'utf-8');\n};\n\n/**\n * Render a snippet the user can paste into a typed `manifest.ts`.\n */\nexport const renderManifestSnippet = (icons: ManifestIcon[]): string => {\n const body = icons\n .map(\n (icon) =>\n ` { src: '${icon.src}', sizes: '${icon.sizes}', type: '${icon.type}'${\n icon.purpose ? `, purpose: '${icon.purpose}'` : ''\n } }`,\n )\n .join(',\\n');\n return `icons: [\\n${body},\\n ],`;\n};\n\n/**\n * Bootstrap a fresh `manifest.webmanifest` for projects without one.\n */\nexport const buildBootstrapManifest = (\n appName: string,\n themeColor: string,\n icons: ManifestIcon[],\n): string => {\n const manifest = {\n name: appName,\n short_name: appName,\n start_url: '/',\n display: 'standalone',\n background_color: '#ffffff',\n theme_color: themeColor,\n icons,\n };\n return `${JSON.stringify(manifest, null, 2)}\\n`;\n};\n", "import { stat } from 'node:fs/promises';\nimport path from 'node:path';\n\nconst SUPPORTED_EXTS = ['.png', '.jpg', '.jpeg', '.webp', '.svg', '.avif'];\n\nexport interface SourceInfo {\n absolutePath: string;\n ext: string;\n bytes: number;\n isVector: boolean;\n}\n\nexport const validateSource = async (source: string): Promise<SourceInfo> => {\n if (!source) throw new Error('Source image path is required (use --path).');\n\n const absolutePath = path.isAbsolute(source) ? source : path.resolve(process.cwd(), source);\n let info: Awaited<ReturnType<typeof stat>>;\n try {\n info = await stat(absolutePath);\n } catch {\n throw new Error(`Source image not found: ${absolutePath}`);\n }\n if (!info.isFile()) throw new Error(`Source is not a file: ${absolutePath}`);\n\n const ext = path.extname(absolutePath).toLowerCase();\n if (!SUPPORTED_EXTS.includes(ext)) {\n throw new Error(`Unsupported source format '${ext}'. Use one of: ${SUPPORTED_EXTS.join(', ')}`);\n }\n\n return { absolutePath, ext, bytes: info.size, isVector: ext === '.svg' };\n};\n\nexport const isHexColor = (value: string): boolean =>\n /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(value);\n\nexport const normalizeBg = (value: string): string => {\n if (value === 'transparent') return value;\n if (isHexColor(value)) return value;\n // Allow CSS named colors as-is \u2014 sharp accepts them via composite over a flat layer.\n return value;\n};\n\nexport const parseSizes = (raw: string | undefined, fallback: number[]): number[] => {\n if (!raw) return fallback;\n const sizes = raw\n .split(',')\n .map((s) => Number.parseInt(s.trim(), 10))\n .filter((n) => Number.isFinite(n) && n > 0 && n <= 1024);\n if (sizes.length === 0) {\n throw new Error(`Invalid --sizes value: '${raw}'. Provide comma-separated positive integers.`);\n }\n return sizes;\n};\n", "/**\n * Standard CSS named colors. Used to validate --bg before passing it to sharp,\n * which silently accepts unknown strings.\n *\n * Source: https://developer.mozilla.org/en-US/docs/Web/CSS/named-color\n */\nexport const CSS_NAMED_COLORS = new Set([\n 'aliceblue',\n 'antiquewhite',\n 'aqua',\n 'aquamarine',\n 'azure',\n 'beige',\n 'bisque',\n 'black',\n 'blanchedalmond',\n 'blue',\n 'blueviolet',\n 'brown',\n 'burlywood',\n 'cadetblue',\n 'chartreuse',\n 'chocolate',\n 'coral',\n 'cornflowerblue',\n 'cornsilk',\n 'crimson',\n 'cyan',\n 'darkblue',\n 'darkcyan',\n 'darkgoldenrod',\n 'darkgray',\n 'darkgreen',\n 'darkgrey',\n 'darkkhaki',\n 'darkmagenta',\n 'darkolivegreen',\n 'darkorange',\n 'darkorchid',\n 'darkred',\n 'darksalmon',\n 'darkseagreen',\n 'darkslateblue',\n 'darkslategray',\n 'darkslategrey',\n 'darkturquoise',\n 'darkviolet',\n 'deeppink',\n 'deepskyblue',\n 'dimgray',\n 'dimgrey',\n 'dodgerblue',\n 'firebrick',\n 'floralwhite',\n 'forestgreen',\n 'fuchsia',\n 'gainsboro',\n 'ghostwhite',\n 'gold',\n 'goldenrod',\n 'gray',\n 'green',\n 'greenyellow',\n 'grey',\n 'honeydew',\n 'hotpink',\n 'indianred',\n 'indigo',\n 'ivory',\n 'khaki',\n 'lavender',\n 'lavenderblush',\n 'lawngreen',\n 'lemonchiffon',\n 'lightblue',\n 'lightcoral',\n 'lightcyan',\n 'lightgoldenrodyellow',\n 'lightgray',\n 'lightgreen',\n 'lightgrey',\n 'lightpink',\n 'lightsalmon',\n 'lightseagreen',\n 'lightskyblue',\n 'lightslategray',\n 'lightslategrey',\n 'lightsteelblue',\n 'lightyellow',\n 'lime',\n 'limegreen',\n 'linen',\n 'magenta',\n 'maroon',\n 'mediumaquamarine',\n 'mediumblue',\n 'mediumorchid',\n 'mediumpurple',\n 'mediumseagreen',\n 'mediumslateblue',\n 'mediumspringgreen',\n 'mediumturquoise',\n 'mediumvioletred',\n 'midnightblue',\n 'mintcream',\n 'mistyrose',\n 'moccasin',\n 'navajowhite',\n 'navy',\n 'oldlace',\n 'olive',\n 'olivedrab',\n 'orange',\n 'orangered',\n 'orchid',\n 'palegoldenrod',\n 'palegreen',\n 'paleturquoise',\n 'palevioletred',\n 'papayawhip',\n 'peachpuff',\n 'peru',\n 'pink',\n 'plum',\n 'powderblue',\n 'purple',\n 'rebeccapurple',\n 'red',\n 'rosybrown',\n 'royalblue',\n 'saddlebrown',\n 'salmon',\n 'sandybrown',\n 'seagreen',\n 'seashell',\n 'sienna',\n 'silver',\n 'skyblue',\n 'slateblue',\n 'slategray',\n 'slategrey',\n 'snow',\n 'springgreen',\n 'steelblue',\n 'tan',\n 'teal',\n 'thistle',\n 'tomato',\n 'turquoise',\n 'violet',\n 'wheat',\n 'white',\n 'whitesmoke',\n 'yellow',\n 'yellowgreen',\n]);\n", "import path from 'node:path';\nimport type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { directoryExists } from '../detection';\nimport { createFeaturePipelineSteps, executePipeline } from '../pipelines';\nimport { promptForFeatureDetails } from '../prompts/feature.prompt';\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 validateFeatureOptions(options);\n\n log(pc.cyan('\\n\uD83C\uDFAF Feature Generator\\n'));\n\n // Detect & prompt\n const steps = createFeaturePipelineSteps();\n spinner.start('Detecting project setup...');\n const { detectProjectSetup } = await import('../detection');\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 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 const basePath = options.path || path.join('src', 'features');\n const featurePath = path.join(projectPath, basePath, featureOptions.featureName);\n\n const exists = await directoryExists(projectPath, featureOptions.featureName, basePath);\n if (exists) {\n logError(`Feature '${featureOptions.featureName}' already exists at ${basePath}!`);\n process.exit(1);\n }\n\n // Execute generation pipeline (generate \u2192 register API \u2192 register reducer)\n await executePipeline(steps.slice(1), {\n projectPath,\n spinner,\n featureName: featureOptions.featureName,\n basePath,\n featurePath,\n createStore: featureOptions.createStore,\n persistStore: featureOptions.persistStore,\n createService: featureOptions.createService,\n httpClient: featureOptions.selectedHttpClient,\n detection,\n });\n\n printFeatureSuccess(featureOptions, basePath);\n } catch (error) {\n spinner.fail('Feature generation failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n\nconst validateFeatureOptions = (options: FeatureCommandOptions) => {\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 if (options.service && !['axios', 'fetch'].includes(options.service)) {\n logError('Invalid --service option. Use: axios or fetch');\n process.exit(1);\n }\n if (options.skipStore && options.store) {\n logError('Cannot use --skip-store and --store together');\n process.exit(1);\n }\n if (options.skipService && options.service) {\n logError('Cannot use --skip-service and --service together');\n process.exit(1);\n }\n};\n\nconst printFeatureSuccess = (\n featureOptions: { featureName: string; createStore: boolean; createService: boolean },\n basePath: string,\n) => {\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};\n", "import path from 'node:path';\nimport type { ProjectDetection } from '../detection';\nimport { detectProjectSetup } from '../detection';\nimport { generateFeature } from '../generators';\nimport { registerApiEndpoints, registerInRootReducer } from '../modifiers';\nimport type { PipelineContext, PipelineStep } from './types';\n\nexport interface FeaturePipelineContext extends PipelineContext {\n featureName: string;\n basePath: string;\n featurePath: string;\n createStore: boolean;\n persistStore: boolean;\n createService: boolean;\n httpClient?: 'axios' | 'fetch';\n detection: ProjectDetection;\n}\n\nexport const createFeaturePipelineSteps = (): PipelineStep<FeaturePipelineContext>[] => [\n {\n name: 'Project setup detected',\n spinnerText: 'Detecting project setup...',\n execute: async (ctx) => {\n ctx.detection = await detectProjectSetup(ctx.projectPath);\n },\n },\n {\n name: 'Feature files generated',\n spinnerText: 'Generating feature files...',\n execute: async (ctx) => {\n await generateFeature({\n name: ctx.featureName,\n outputPath: ctx.featurePath,\n createStore: ctx.createStore,\n persistStore: ctx.persistStore,\n createService: ctx.createService,\n httpClient: ctx.httpClient,\n });\n },\n },\n {\n name: 'API endpoints registered',\n spinnerText: 'Registering API endpoints...',\n shouldSkip: (ctx) => !ctx.createService,\n execute: async (ctx) => {\n await registerApiEndpoints({\n serviceName: ctx.featureName,\n projectPath: ctx.projectPath,\n });\n },\n },\n {\n name: 'Feature registered in rootReducer',\n spinnerText: 'Registering feature in rootReducer...',\n shouldSkip: (ctx) => !ctx.createStore || !ctx.detection.hasRedux,\n execute: async (ctx) => {\n await registerInRootReducer({\n projectPath: ctx.projectPath,\n name: ctx.featureName,\n persist: ctx.persistStore,\n importPath: path.join(ctx.basePath, ctx.featureName, 'store'),\n });\n },\n },\n];\n", "import { readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel } from '../config/utils';\nimport { addToAppApis } from './helpers';\nimport type { RegisterApiOptions } from './types';\n\n/**\n * Register API endpoints for a service in app-apis.ts.\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 let content = await readFile(apiConfigPath, 'utf-8');\n\n // Skip if already registered\n if (content.includes(`${camelName}:`)) {\n return;\n }\n\n // Validate AppApis object exists\n if (!content.match(/export const AppApis = \\{[\\s\\S]*?\\} as const;/)) {\n throw new Error('Could not find AppApis object in app-apis.ts');\n }\n\n const newEndpoint = ` ${camelName}: {\n base: \\`\\${API_PREFIX}/${serviceName}\\`,\n getAll: \\`\\${API_PREFIX}/${serviceName}\\`,\n },`;\n\n content = addToAppApis(content, newEndpoint);\n await writeFile(apiConfigPath, content);\n } catch (error) {\n throw new Error(`Failed to register API endpoints: ${error}`, { cause: error });\n }\n};\n", "/**\n * Add an import statement after the last existing import in a file.\n * If no imports exist, prepends to the file.\n */\nexport const addImportStatement = (fileContent: string, importStatement: string): string => {\n const importRegex = /import\\s+.*\\s+from\\s+['\"].*['\"];?\\n/g;\n const imports = fileContent.match(importRegex);\n\n if (imports && imports.length > 0) {\n const lastImport = imports[imports.length - 1];\n const lastImportIndex = fileContent.lastIndexOf(lastImport);\n return (\n fileContent.slice(0, lastImportIndex + lastImport.length) +\n importStatement +\n '\\n' +\n fileContent.slice(lastImportIndex + lastImport.length)\n );\n }\n\n return `${importStatement}\\n${fileContent}`;\n};\n\n/**\n * Add a reducer entry to a combineReducers({...}) call.\n */\nexport const addToCombineReducers = (\n fileContent: string,\n reducerKey: string,\n reducerEntry: string,\n): string => {\n const combineReducersRegex = /combineReducers\\(\\{([^}]*)\\}\\)/s;\n const match = fileContent.match(combineReducersRegex);\n\n if (!match) {\n throw new Error('Could not find combineReducers in rootReducer.ts');\n }\n\n const reducersContent = match[1];\n const newEntry = `\\n ${reducerKey}: ${reducerEntry},`;\n const updatedReducersContent = reducersContent.trimEnd() + newEntry;\n\n return fileContent.replace(\n combineReducersRegex,\n `combineReducers({${updatedReducersContent}\\n})`,\n );\n};\n\n/**\n * Insert a new endpoint object before the closing `} as const;` of AppApis.\n */\nexport const addToAppApis = (fileContent: string, endpointBlock: string): string => {\n const insertPosition = fileContent.lastIndexOf('} as const;');\n if (insertPosition === -1) {\n throw new Error('Could not find closing brace of AppApis object');\n }\n\n const beforeClosing = fileContent.substring(0, insertPosition);\n const afterClosing = fileContent.substring(insertPosition);\n\n return `${beforeClosing.trimEnd()}\\n${endpointBlock}\\n${afterClosing}`;\n};\n", "import { readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel } from '../config/utils';\nimport { fileExists } from '../core/files';\n\n/**\n * Add a route to AppPaths in app-paths.ts.\n */\nexport const registerAppPath = async (\n projectPath: string,\n routeName: string,\n routePath: string,\n): Promise<void> => {\n const appPathsFile = path.join(projectPath, 'src', 'lib', 'config', 'app-paths.ts');\n if (!fileExists(appPathsFile)) return;\n\n let content = await readFile(appPathsFile, 'utf-8');\n const camelName = kebabToCamel(routeName);\n\n if (content.includes(`${camelName}:`)) return;\n\n const closingBrace = content.lastIndexOf('} as const;');\n if (closingBrace === -1) return;\n\n const newEntry = ` ${camelName}: '${routePath}',\\n`;\n content = content.slice(0, closingBrace) + newEntry + content.slice(closingBrace);\n\n await writeFile(appPathsFile, content);\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../config/paths';\nimport { fileExists, readFile, writeFile } from '../core/files';\nimport { addImportStatement } from './helpers';\n\n/**\n * Modifies the project's `RootProvider.tsx` to wrap `{children}` in a newly\n * generated provider. Two-tier detection:\n * 1. Canonical path: `src/providers/RootProvider.tsx`\n * 2. Heuristic scan of `src/providers/*.tsx` for the file whose JSX\n * contains `{children}` (most projects only have one).\n *\n * Pure transformation logic lives in this module too (`injectProviderIntoChain`,\n * `addProviderToBarrel`) so it can be unit-tested without filesystem.\n */\n\nconst COMPONENT_TAG_RE = (componentName: string): RegExp => new RegExp(`<\\\\s*${componentName}\\\\b`);\n\n/**\n * Insert `<ComponentName>{children}</ComponentName>` as the innermost wrap\n * around `{children}`. Idempotent: returns the input unchanged if the tag\n * is already present.\n */\nexport const injectProviderIntoChain = (content: string, componentName: string): string => {\n if (COMPONENT_TAG_RE(componentName).test(content)) {\n return content;\n }\n\n // Capture the indentation of the `{children}` line so we preserve formatting.\n const childrenLineRe = /^(?<indent>[ \\t]*)\\{children\\}\\s*$/m;\n const match = content.match(childrenLineRe);\n if (!match || match.index === undefined) {\n throw new Error(\n 'Could not locate `{children}` line in RootProvider \u2014 expected a line containing only `{children}`.',\n );\n }\n\n const indent = match.groups?.indent ?? '';\n const innerIndent = `${indent} `;\n const replacement = `${indent}<${componentName}>\\n${innerIndent}{children}\\n${indent}</${componentName}>`;\n\n return content.replace(childrenLineRe, replacement);\n};\n\n/**\n * Append a `export * from './<basename>';` line to the providers barrel,\n * keeping it sorted alphabetically among the other exports. Idempotent.\n */\nexport const addProviderToBarrel = (content: string, fileBaseName: string): string => {\n const exportLine = `export * from './${fileBaseName}';`;\n if (content.includes(exportLine)) return content;\n\n const lines = content.split('\\n');\n const exportLines: string[] = [];\n const others: string[] = [];\n\n for (const line of lines) {\n if (/^export \\* from '\\.\\/.*';\\s*$/.test(line)) {\n exportLines.push(line);\n } else {\n others.push(line);\n }\n }\n\n const merged = [...exportLines, exportLine].sort();\n // Reconstitute: keep non-export lines (likely empty trailing/leading) where\n // they were, but place the sorted export block where the first export was.\n const firstExportIdx = lines.findIndex((l) => /^export \\* from '\\.\\//.test(l));\n if (firstExportIdx === -1) {\n return `${exportLine}\\n${content.replace(/^\\n+/, '')}`;\n }\n\n const before = lines.slice(0, firstExportIdx);\n const afterStart = lines.findIndex(\n (l, idx) => idx > firstExportIdx && !/^export \\* from '\\.\\//.test(l),\n );\n const after = afterStart === -1 ? [] : lines.slice(afterStart);\n\n return [...before, ...merged, ...after].join('\\n');\n};\n\nconst PROVIDER_DIR_REL = PROJECT_PATHS.PROVIDERS;\nconst ROOT_PROVIDER_REL = PROJECT_PATHS.ROOT_PROVIDER;\nconst PROVIDERS_INDEX_REL = PROJECT_PATHS.PROVIDERS_INDEX;\n\n/** Locates the RootProvider file or returns null when none can be confidently identified. */\nexport const findRootProviderFile = async (\n projectPath: string,\n fs: { fileExists: (p: string) => boolean; readFile: (p: string) => Promise<string> } = {\n fileExists,\n readFile,\n },\n): Promise<string | null> => {\n const canonical = path.join(projectPath, ROOT_PROVIDER_REL);\n if (fs.fileExists(canonical)) return canonical;\n\n const dir = path.join(projectPath, PROVIDER_DIR_REL);\n if (!fs.fileExists(dir)) return null;\n\n const { readdir } = await import('node:fs/promises');\n const entries = await readdir(dir).catch(() => [] as string[]);\n const candidates = entries.filter((name) => name.endsWith('.tsx'));\n\n let best: { file: string; depth: number } | null = null;\n for (const entry of candidates) {\n const filePath = path.join(dir, entry);\n const contents = await fs.readFile(filePath);\n if (!/\\{children\\}/.test(contents)) continue;\n // Depth heuristic: number of opening JSX tags before `{children}`.\n const beforeChildren = contents.split('{children}')[0] ?? '';\n const depth = (beforeChildren.match(/<[A-Z][A-Za-z0-9_]*\\b/g) ?? []).length;\n if (!best || depth > best.depth) {\n best = { file: filePath, depth };\n }\n }\n\n return best?.file ?? null;\n};\n\nexport interface RegisterProviderOptions {\n projectPath: string;\n componentName: string;\n fileBaseName: string;\n}\n\nexport const registerProvider = async (\n options: RegisterProviderOptions,\n): Promise<{ rootProviderFile: string | null; barrelFile: string | null }> => {\n const { projectPath, componentName, fileBaseName } = options;\n\n const rootProviderFile = await findRootProviderFile(projectPath);\n if (rootProviderFile) {\n const before = await readFile(rootProviderFile);\n let after = before;\n if (!/from '\\.\\//.test(before) || !before.includes(`{ ${componentName} }`)) {\n after = addImportStatement(after, `import { ${componentName} } from './${fileBaseName}';`);\n }\n after = injectProviderIntoChain(after, componentName);\n if (after !== before) {\n await writeFile(rootProviderFile, after);\n }\n }\n\n const barrelPath = path.join(projectPath, PROVIDERS_INDEX_REL);\n let barrelFile: string | null = null;\n if (fileExists(barrelPath)) {\n const before = await readFile(barrelPath);\n const after = addProviderToBarrel(before, fileBaseName);\n if (after !== before) {\n await writeFile(barrelPath, after);\n }\n barrelFile = barrelPath;\n }\n\n return { rootProviderFile, barrelFile };\n};\n", "import { readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel } from '../config/utils';\nimport { addImportStatement, addToCombineReducers } from './helpers';\nimport type { RegisterReducerOptions } from './types';\n\n/**\n * Register a reducer in rootReducer.ts \u2014 unified handler for both\n * feature-embedded slices (import from /store) and standalone slices.\n */\nexport const registerInRootReducer = async (options: RegisterReducerOptions): Promise<void> => {\n const { projectPath, name, persist, importPath } = options;\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(name);\n const reducerName = `${camelName}Reducer`;\n const persistConfigName = `${camelName}PersistConfig`;\n\n // Convert path to import alias format (src/... -> @/...)\n const aliasPath = importPath.replace(/^src\\//, '@/');\n\n // Build import statement\n const importStatement = persist\n ? `import { ${reducerName}, ${persistConfigName} } from '${aliasPath}';`\n : `import { ${reducerName} } from '${aliasPath}';`;\n\n content = addImportStatement(content, importStatement);\n\n // Build reducer entry\n const reducerEntry = persist\n ? `persistReducer(${persistConfigName}, ${reducerName})`\n : reducerName;\n\n content = addToCombineReducers(content, camelName, reducerEntry);\n\n await writeFile(rootReducerPath, content);\n } catch (error) {\n throw new Error(`Failed to register reducer '${name}' in rootReducer: ${error}`, {\n cause: error,\n });\n }\n};\n", "import { readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { fileExists } from '../core/files';\n\n/**\n * Add a translation namespace to the default (en) translation file.\n */\nexport const addTranslationNamespace = async (\n projectPath: string,\n namespace: string,\n): Promise<void> => {\n const translationFile = path.join(projectPath, 'src', 'i18n', 'translations', 'en.json');\n if (!fileExists(translationFile)) return;\n\n const content = await readFile(translationFile, 'utf-8');\n const json = JSON.parse(content);\n\n if (json[namespace]) return;\n\n json[namespace] = {\n title: namespace,\n description: `${namespace} page description`,\n };\n\n await writeFile(translationFile, `${JSON.stringify(json, null, 2)}\\n`);\n};\n", "import type { PipelineContext, PipelineStep } from './types';\n\n/**\n * Execute a sequence of pipeline steps with spinner feedback.\n * Each step gets the shared context and reports progress via the spinner.\n */\nexport const executePipeline = async <T extends PipelineContext>(\n steps: PipelineStep<T>[],\n context: T,\n): Promise<void> => {\n for (const step of steps) {\n if (step.shouldSkip?.(context)) continue;\n\n context.spinner.start(step.spinnerText);\n\n try {\n await step.execute(context);\n context.spinner.succeed(step.name);\n } catch (error) {\n context.spinner.fail(step.name);\n throw error;\n }\n }\n};\n", "import { generateService } from '../generators';\nimport { registerApiEndpoints } from '../modifiers';\nimport type { PipelineContext, PipelineStep } from './types';\n\nexport interface ServicePipelineContext extends PipelineContext {\n serviceName: string;\n servicePath: string;\n httpClient: 'axios' | 'fetch';\n}\n\nexport const createServicePipelineSteps = (): PipelineStep<ServicePipelineContext>[] => [\n {\n name: 'Service files generated',\n spinnerText: 'Generating service files...',\n execute: async (ctx) => {\n await generateService({\n name: ctx.serviceName,\n outputPath: ctx.servicePath,\n httpClient: ctx.httpClient,\n });\n },\n },\n {\n name: 'API endpoints registered',\n spinnerText: 'Registering API endpoints...',\n execute: async (ctx) => {\n await registerApiEndpoints({\n serviceName: ctx.serviceName,\n projectPath: ctx.projectPath,\n });\n },\n },\n];\n", "import path from 'node:path';\nimport { generateSlice } from '../generators';\nimport { registerInRootReducer } from '../modifiers';\nimport type { PipelineContext, PipelineStep } from './types';\n\nexport interface SlicePipelineContext extends PipelineContext {\n sliceName: string;\n basePath: string;\n slicePath: string;\n persistSlice: boolean;\n}\n\nexport const createSlicePipelineSteps = (): PipelineStep<SlicePipelineContext>[] => [\n {\n name: 'Slice files generated',\n spinnerText: 'Generating slice files...',\n execute: async (ctx) => {\n await generateSlice({\n name: ctx.sliceName,\n outputPath: ctx.slicePath,\n persist: ctx.persistSlice,\n });\n },\n },\n {\n name: 'Slice registered in rootReducer',\n spinnerText: 'Registering slice in rootReducer...',\n execute: async (ctx) => {\n await registerInRootReducer({\n projectPath: ctx.projectPath,\n name: ctx.sliceName,\n persist: ctx.persistSlice,\n importPath: path.join(ctx.basePath, ctx.sliceName),\n });\n },\n },\n];\n", "import Enquirer from 'enquirer';\n\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 path from 'node:path';\nimport type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { kebabToPascal } from '../config/utils';\nimport { detectProjectSetup } from '../detection';\nimport { generateHook, generateTest } from '../generators';\nimport { promptForHookDetails } from '../prompts/hook.prompt';\n\ninterface HookCommandOptions {\n client?: boolean;\n feature?: string;\n test?: boolean;\n noTest?: boolean;\n}\n\nexport const registerHookCommand = (program: Command) => {\n program\n .command('hook [name]')\n .description('Generate a custom React hook')\n .option('--client', \"Add 'use client' directive (default: true)\", true)\n .option('--feature <path>', 'Generate in feature directory (e.g., src/features/auth)')\n .option('--test', 'Also generate a sibling test file')\n .option('--no-test', 'Skip test file generation')\n .action(async (name: string | undefined, options: HookCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\n log(pc.cyan('\\n\uD83E\uDE9D Hook Generator\\n'));\n\n const detection = await detectProjectSetup(projectPath);\n\n const hookOptions = await promptForHookDetails(name);\n const pascalName = kebabToPascal(hookOptions.hookName);\n const hookName = `use${pascalName}`;\n const shouldTest = resolveShouldTest(options, detection.hasTests);\n\n spinner.start('Generating hook...');\n await generateHook({\n name: hookOptions.hookName,\n projectPath,\n isClient: options.client ?? true,\n featurePath: options.feature,\n });\n spinner.succeed('Hook generated');\n\n const hookFile = options.feature\n ? path.join(projectPath, options.feature, 'hooks', `${hookName}.ts`)\n : path.join(projectPath, 'src/hooks', `${hookName}.ts`);\n\n let testFile: string | null = null;\n if (shouldTest) {\n spinner.start('Generating test...');\n testFile = await generateTest({\n projectPath,\n sourceFile: hookFile,\n kind: 'hook',\n symbolName: hookName,\n hookUsesStore: detection.hasRedux && !!options.feature,\n });\n spinner.succeed('Test generated');\n }\n\n const location = options.feature\n ? `${options.feature}/hooks/${hookName}.ts`\n : `src/hooks/${hookName}.ts`;\n\n log(pc.green(`\\n\u2728 Hook '${hookName}' created successfully!\\n`));\n log(pc.dim(` \uD83D\uDCC4 ${location}`));\n if (testFile) log(pc.dim(` \uD83E\uDDEA ${path.relative(projectPath, testFile)}`));\n log('');\n log(pc.cyan('Usage:'));\n const importPath = options.feature\n ? `${options.feature.replace(/^src\\//, '@/')}/hooks/${hookName}`\n : `@/hooks/${hookName}`;\n log(pc.dim(` import { ${hookName} } from '${importPath}';`));\n log('');\n } catch (error) {\n spinner.fail('Hook generation failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n\nconst resolveShouldTest = (\n options: { test?: boolean; noTest?: boolean },\n hasTests: boolean,\n): boolean => {\n if (options.noTest) return false;\n if (options.test) return true;\n return hasTests;\n};\n", "import Enquirer from 'enquirer';\n\nconst { prompt } = Enquirer;\n\nexport interface HookPromptResult {\n hookName: string;\n}\n\nexport const promptForHookDetails = async (name?: string): Promise<HookPromptResult> => {\n if (name) return { hookName: name };\n\n const answers = (await prompt({\n type: 'input',\n name: 'hookName',\n message: 'Hook name (kebab-case, without \"use\" prefix):',\n validate: (value: string) => {\n if (!value) return 'Hook name is required';\n if (!/^[a-z][a-z0-9-]*$/.test(value)) {\n return 'Use lowercase letters, numbers, and hyphens only';\n }\n return true;\n },\n })) as unknown as HookPromptResult;\n\n return answers;\n};\n", "import type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { detectProjectSetup } from '../detection';\nimport { generateLayout } from '../generators/layout.generator';\n\ninterface LayoutCommandOptions {\n group?: boolean;\n at?: string;\n locale?: boolean;\n}\n\nexport const registerLayoutCommand = (program: Command) => {\n program\n .command('layout <segment>')\n .description('Generate a nested layout.tsx (locale-aware when i18n is detected)')\n .option('--group', 'Treat the segment as a route group (wraps it in parens)')\n .option('--at <path>', 'Place the layout under this nested path (kebab-case, slash-separated)')\n .option('--no-locale', 'Skip the locale wrapper even if i18n is detected')\n .action(async (segment: string, options: LayoutCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\n log(pc.cyan('\\n\uD83D\uDCD0 Layout Generator\\n'));\n\n spinner.start('Detecting project setup...');\n const detection = await detectProjectSetup(projectPath);\n spinner.succeed('Project setup detected');\n\n const hasI18n = detection.hasI18n && options.locale !== false;\n log(pc.dim(` i18n: ${hasI18n ? '\u2713' : '\u2717'}\\n`));\n\n spinner.start('Generating layout...');\n const result = await generateLayout({\n segment,\n at: options.at,\n projectPath,\n hasI18n,\n withGroup: !!options.group,\n });\n spinner.succeed('Layout generated');\n\n log(pc.green(`\\n\u2728 ${result.componentName} created!\\n`));\n log(pc.dim(` \uD83D\uDCC4 ${result.displayPath}`));\n log('');\n } catch (error) {\n spinner.fail('Layout generation failed');\n logError(`${error instanceof Error ? error.message : error}`);\n process.exit(1);\n }\n });\n};\n", "import path from 'node:path';\nimport type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { fileExists } from '../core/files';\nimport { detectProjectSetup } from '../detection';\nimport { generateLocale } from '../generators';\nimport { promptForLocaleDetails } from '../prompts/locale.prompt';\n\ninterface LocaleCommandOptions {\n copyTranslations?: boolean;\n}\n\nexport const registerLocaleCommand = (program: Command) => {\n program\n .command('locale [code]')\n .description('Add a new locale/language')\n .option('--copy-translations', 'Copy translations from English instead of empty values')\n .action(async (code: string | undefined, options: LocaleCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\n log(pc.cyan('\\n\uD83C\uDF0D Locale Generator\\n'));\n\n // Check i18n is set up\n spinner.start('Detecting project setup...');\n const detection = await detectProjectSetup(projectPath);\n spinner.succeed('Project setup detected');\n\n if (!detection.hasI18n) {\n spinner.fail('i18n is not set up in this project');\n logError('Please set up internationalization first');\n log(pc.dim('\\nRun: npx @teispace/next-maker setup --i18n\\n'));\n process.exit(1);\n }\n\n // Prompt \u2014 skip questions whose answers were already given via flags.\n const localeOptions = await promptForLocaleDetails(code, {\n copyTranslations: options.copyTranslations,\n });\n\n // Check if locale already exists\n const translationFile = path.join(\n projectPath,\n 'src',\n 'i18n',\n 'translations',\n `${localeOptions.code}.json`,\n );\n if (fileExists(translationFile)) {\n logError(`Locale '${localeOptions.code}' already exists!`);\n process.exit(1);\n }\n\n // Generate\n spinner.start('Adding locale...');\n await generateLocale({\n ...localeOptions,\n projectPath,\n });\n spinner.succeed('Locale added');\n\n // Success\n log(\n pc.green(\n `\\n\u2728 Locale '${localeOptions.code}' (${localeOptions.name}) added successfully!\\n`,\n ),\n );\n log(pc.dim('Updated files:'));\n log(pc.dim(` \uD83D\uDCC4 src/i18n/translations/${localeOptions.code}.json`));\n log(pc.dim(` \uD83D\uDCDD src/types/i18n.ts (SupportedLocale type)`));\n log(pc.dim(` \uD83D\uDCDD src/lib/config/app-locales.ts`));\n log('');\n\n log(pc.cyan('Next steps:'));\n log(pc.dim(` 1. Translate: src/i18n/translations/${localeOptions.code}.json`));\n log(pc.dim(` 2. Visit: http://localhost:3000/${localeOptions.code}`));\n log('');\n } catch (error) {\n spinner.fail('Locale generation failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n", "import Enquirer from 'enquirer';\n\nconst { prompt } = Enquirer;\n\nexport interface LocalePromptResult {\n code: string;\n name: string;\n country: string;\n flag: string;\n copyTranslations: boolean;\n}\n\nexport interface LocalePromptPresets {\n /** When set, the copy-translations prompt is skipped and this value is used. */\n copyTranslations?: boolean;\n}\n\nexport const promptForLocaleDetails = async (\n code?: string,\n presets: LocalePromptPresets = {},\n): Promise<LocalePromptResult> => {\n const questions: any[] = [];\n\n if (!code) {\n questions.push({\n type: 'input',\n name: 'code',\n message: 'Locale code (e.g., es, fr, de):',\n validate: (value: string) => {\n if (!value) return 'Locale code is required';\n if (!/^[a-z]{2}(-[A-Z]{2})?$/.test(value)) {\n return 'Use format: xx or xx-XX (e.g., es, pt-BR)';\n }\n return true;\n },\n });\n }\n\n questions.push(\n {\n type: 'input',\n name: 'name',\n message: 'Language name (e.g., Spanish, French):',\n validate: (value: string) => (value ? true : 'Language name is required'),\n },\n {\n type: 'input',\n name: 'country',\n message: 'Country (e.g., Spain, France):',\n validate: (value: string) => (value ? true : 'Country is required'),\n },\n {\n type: 'input',\n name: 'flag',\n message: 'Flag emoji (e.g., \uD83C\uDDEA\uD83C\uDDF8, \uD83C\uDDEB\uD83C\uDDF7):',\n validate: (value: string) => (value ? true : 'Flag emoji is required'),\n },\n );\n\n if (presets.copyTranslations === undefined) {\n questions.push({\n type: 'confirm',\n name: 'copyTranslations',\n message: 'Copy translations from English? (No = empty values)',\n initial: false,\n });\n }\n\n const answers = (await prompt(questions)) as unknown as Partial<LocalePromptResult>;\n\n return {\n code: code ?? (answers.code as string),\n name: answers.name as string,\n country: answers.country as string,\n flag: answers.flag as string,\n copyTranslations: presets.copyTranslations ?? answers.copyTranslations ?? false,\n };\n};\n", "import path from 'node:path';\nimport type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { kebabToPascal } from '../config/utils';\nimport { detectProjectSetup, directoryExists } from '../detection';\nimport { generatePage } from '../generators';\nimport { addTranslationNamespace, registerAppPath } from '../modifiers';\nimport { promptForPageDetails } from '../prompts/page.prompt';\n\ninterface PageCommandOptions {\n dynamic?: string;\n loading?: boolean;\n error?: boolean;\n}\n\nexport const registerPageCommand = (program: Command) => {\n program\n .command('page [name]')\n .description('Generate a new page/route')\n .option('--dynamic <param>', 'Create dynamic route with parameter (e.g., id)')\n .option('--loading', 'Generate loading.tsx')\n .option('--error', 'Generate error.tsx')\n .action(async (name: string | undefined, options: PageCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\n log(pc.cyan('\\n\uD83D\uDCC4 Page Generator\\n'));\n\n // Detect i18n\n spinner.start('Detecting project setup...');\n const detection = await detectProjectSetup(projectPath);\n spinner.succeed('Project setup detected');\n\n log(pc.dim(` i18n: ${detection.hasI18n ? '\u2713' : '\u2717'}\\n`));\n\n // Prompt \u2014 skip questions whose answers were already given via flags.\n const pageOptions = await promptForPageDetails(name, {\n loading: options.loading,\n error: options.error,\n });\n const pageName = pageOptions.pageName;\n const componentName = kebabToPascal(pageName);\n\n // Check existence\n const baseDir = detection.hasI18n ? 'src/app/[locale]' : 'src/app';\n const exists = await directoryExists(projectPath, pageName, baseDir);\n if (exists) {\n logError(`Page '${pageName}' already exists at ${baseDir}/${pageName}!`);\n process.exit(1);\n }\n\n // Generate\n spinner.start('Generating page files...');\n await generatePage({\n name: pageName,\n projectPath,\n hasI18n: detection.hasI18n,\n dynamic: options.dynamic,\n withLoading: options.loading ?? pageOptions.withLoading,\n withError: options.error ?? pageOptions.withError,\n });\n spinner.succeed('Page files generated');\n\n // Register route in app-paths\n spinner.start('Registering route...');\n const routePath = options.dynamic ? `/${pageName}/[${options.dynamic}]` : `/${pageName}`;\n await registerAppPath(projectPath, pageName, routePath);\n spinner.succeed('Route registered');\n\n // Add translation namespace if i18n\n if (detection.hasI18n) {\n spinner.start('Adding translation namespace...');\n await addTranslationNamespace(projectPath, componentName);\n spinner.succeed('Translation namespace added');\n }\n\n // Success\n const displayPath = options.dynamic\n ? path.join(baseDir, pageName, `[${options.dynamic}]`)\n : path.join(baseDir, pageName);\n\n log(pc.green(`\\n\u2728 Page '${pageName}' created successfully!\\n`));\n log(pc.dim('Generated files:'));\n log(pc.dim(` \uD83D\uDCC2 ${displayPath}/`));\n log(pc.dim(` \u251C\u2500\u2500 page.tsx`));\n if (options.loading ?? pageOptions.withLoading) log(pc.dim(` \u251C\u2500\u2500 loading.tsx`));\n if (options.error ?? pageOptions.withError) log(pc.dim(` \u2514\u2500\u2500 error.tsx`));\n log('');\n\n if (detection.hasI18n) {\n log(pc.cyan('Next steps:'));\n log(\n pc.dim(` 1. Add translations in: src/i18n/translations/en.json \u2192 \"${componentName}\"`),\n );\n log(pc.dim(` 2. Visit: http://localhost:3000/${pageName}`));\n log('');\n }\n } catch (error) {\n spinner.fail('Page generation failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n", "import Enquirer from 'enquirer';\n\nconst { prompt } = Enquirer;\n\nexport interface PagePromptResult {\n pageName: string;\n withLoading: boolean;\n withError: boolean;\n}\n\nexport interface PagePromptPresets {\n /** When set, the loading prompt is skipped and this value is used. */\n loading?: boolean;\n /** When set, the error prompt is skipped and this value is used. */\n error?: boolean;\n}\n\nexport const promptForPageDetails = async (\n name?: string,\n presets: PagePromptPresets = {},\n): Promise<PagePromptResult> => {\n const questions: any[] = [];\n\n if (!name) {\n questions.push({\n type: 'input',\n name: 'pageName',\n message: 'Page name (kebab-case):',\n validate: (value: string) => {\n if (!value) return 'Page name is required';\n if (!/^[a-z][a-z0-9-]*$/.test(value)) {\n return 'Use lowercase letters, numbers, and hyphens only';\n }\n return true;\n },\n });\n }\n\n if (presets.loading === undefined) {\n questions.push({\n type: 'confirm',\n name: 'withLoading',\n message: 'Generate loading.tsx?',\n initial: true,\n });\n }\n\n if (presets.error === undefined) {\n questions.push({\n type: 'confirm',\n name: 'withError',\n message: 'Generate error.tsx?',\n initial: true,\n });\n }\n\n const answers =\n questions.length > 0 ? ((await prompt(questions)) as unknown as Partial<PagePromptResult>) : {};\n\n return {\n pageName: name ?? (answers.pageName as string),\n withLoading: presets.loading ?? answers.withLoading ?? true,\n withError: presets.error ?? answers.withError ?? true,\n };\n};\n", "import path from 'node:path';\nimport type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { generateProvider } from '../generators/provider.generator';\nimport { registerProvider } from '../modifiers/root-provider.modifier';\n\nexport const registerProviderCommand = (program: Command) => {\n program\n .command('provider <name>')\n .description('Generate a context provider in src/providers/ and wire it into RootProvider')\n .action(async (name: string) => {\n try {\n const projectPath = process.cwd();\n\n log(pc.cyan('\\n\uD83D\uDD0C Provider Generator\\n'));\n\n spinner.start('Generating provider...');\n const { componentName, fileBaseName, providerFile } = await generateProvider({\n name,\n projectPath,\n });\n spinner.succeed('Provider generated');\n\n spinner.start('Registering provider in RootProvider and barrel...');\n const { rootProviderFile, barrelFile } = await registerProvider({\n projectPath,\n componentName,\n fileBaseName,\n });\n spinner.succeed('Provider registered');\n\n log(pc.green(`\\n\u2728 ${componentName} created!\\n`));\n log(pc.dim('Generated files:'));\n log(pc.dim(` \uD83D\uDCC4 ${path.relative(projectPath, providerFile)}`));\n if (rootProviderFile) {\n log(pc.dim(` \u270F\uFE0F ${path.relative(projectPath, rootProviderFile)} \u2014 wrapped {children}`));\n } else {\n log(\n pc.yellow('\\n\u26A0\uFE0F Could not locate a RootProvider file. Wire the new provider manually:'),\n );\n log(pc.dim(` <${componentName}>{children}</${componentName}>`));\n }\n if (barrelFile) {\n log(pc.dim(` \u270F\uFE0F ${path.relative(projectPath, barrelFile)} \u2014 added re-export`));\n }\n log('');\n } catch (error) {\n spinner.fail('Provider generation failed');\n logError(`${error instanceof Error ? error.message : error}`);\n process.exit(1);\n }\n });\n};\n", "import type { Command } from 'commander';\nimport Enquirer from 'enquirer';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { checkManifest, getManifest, MANIFESTS, reverseManifest } from '../manifests';\nimport type { RemoveSummary } from '../manifests/runner';\n\nconst { prompt } = Enquirer;\n\ninterface RemoveCommandOptions {\n yes?: boolean;\n dryRun?: boolean;\n}\n\nconst formatSummary = (summary: RemoveSummary): string[] => {\n const lines: string[] = [];\n for (const file of summary.filesRemoved) {\n lines.push(` ${pc.red('-')} delete: ${file}`);\n }\n for (const block of summary.blocksStripped) {\n lines.push(` ${pc.red('-')} strip block: ${block.description} ${pc.dim(`(${block.file})`)}`);\n }\n for (const script of summary.scriptsRemoved) {\n lines.push(` ${pc.red('-')} remove script: ${script}`);\n }\n for (const dep of summary.packagesUninstalled) {\n lines.push(` ${pc.red('-')} uninstall: ${dep}`);\n }\n for (const item of summary.manualCleanup) {\n lines.push(\n ` ${pc.yellow('?')} manual cleanup: ${item.description} ${pc.dim(`(${item.file})`)}`,\n );\n }\n return lines;\n};\n\nconst isEmpty = (s: RemoveSummary): boolean =>\n s.filesRemoved.length === 0 &&\n s.blocksStripped.length === 0 &&\n s.scriptsRemoved.length === 0 &&\n s.packagesUninstalled.length === 0 &&\n s.manualCleanup.length === 0;\n\nexport const registerRemoveCommand = (program: Command) => {\n program\n .command('remove <feature>')\n .alias('uninstall')\n .description('Reverse a feature install (uses the feature manifest)')\n .option('-y, --yes', 'Skip confirmation prompt')\n .option('--dry-run', 'Show what would change without writing')\n .action(async (feature: string, options: RemoveCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\n const manifest = getManifest(feature);\n if (!manifest) {\n throw new Error(\n `Unknown feature \"${feature}\". Valid: ${MANIFESTS.map((m) => m.id).join(', ')}.`,\n );\n }\n\n log(pc.cyan(`\\n\uD83D\uDDD1 Remove ${manifest.name}\\n`));\n\n const detection = await checkManifest(manifest, projectPath);\n if (!detection.installed) {\n log(pc.dim(`${manifest.name} is not installed \u2014 nothing to remove.`));\n return;\n }\n\n spinner.start('Computing changes...');\n const planned = await reverseManifest(manifest, projectPath, { dryRun: true });\n spinner.succeed('Computed plan');\n\n if (isEmpty(planned)) {\n log(pc.yellow('\\n\u26A0\uFE0F Manifest had no removable artifacts. Nothing to do.\\n'));\n return;\n }\n\n log(pc.bold('\\nPlanned changes:\\n'));\n for (const line of formatSummary(planned)) log(line);\n log('');\n\n if (options.dryRun) {\n log(pc.dim('--dry-run set \u2014 exiting without writing.\\n'));\n return;\n }\n\n if (!options.yes) {\n const { confirm } = await prompt<{ confirm: boolean }>({\n type: 'confirm',\n name: 'confirm',\n message: `Apply the changes above to remove ${manifest.name}?`,\n initial: false,\n });\n if (!confirm) {\n log(pc.yellow('\\nAborted.\\n'));\n return;\n }\n }\n\n spinner.start(`Removing ${manifest.name}...`);\n const applied = manifest.remove\n ? (await manifest.remove(projectPath), planned)\n : await reverseManifest(manifest, projectPath);\n spinner.succeed(`${manifest.name} removed`);\n\n log(pc.green(`\\n\u2713 ${manifest.name} removed.`));\n if (applied.manualCleanup.length > 0) {\n log(pc.yellow('\\n\u26A0\uFE0F Manual cleanup still required:'));\n for (const item of applied.manualCleanup) {\n log(` - ${item.description} (${item.file})`);\n }\n }\n log('');\n } catch (error) {\n spinner.fail('Remove failed');\n logError(`${error instanceof Error ? error.message : error}`);\n process.exit(1);\n }\n });\n};\n", "import { existsSync } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { detectProjectSetup, fileExistsAt } from '../detection';\nimport { generateCrudService } from '../generators';\nimport { registerCrudApiEndpoints } from '../modifiers/crud-api-registration.modifier';\nimport { createServicePipelineSteps, executePipeline } from '../pipelines';\nimport { promptForServiceDetails } from '../prompts/service.prompt';\n\ninterface ServiceCommandOptions {\n path?: string;\n axios?: boolean;\n fetch?: boolean;\n crud?: 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 .option('--crud', 'Generate full CRUD service (getAll, getById, create, update, delete)')\n .action(async (name: string | undefined, options: ServiceCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\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 // Detect and validate HTTP clients\n spinner.start('Detecting project setup...');\n const detection = await detectProjectSetup(projectPath);\n spinner.succeed('Project setup detected');\n\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 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 // Prompt and resolve paths\n const serviceOptions = await promptForServiceDetails(\n name,\n options.axios,\n options.fetch,\n detection.httpClient,\n );\n\n const { basePath, servicePath } = resolveServicePaths(\n projectPath,\n serviceOptions.serviceName,\n options.path,\n );\n\n if (!existsSync(servicePath)) {\n await mkdir(servicePath, { recursive: true });\n }\n\n const exists = fileExistsAt(\n projectPath,\n basePath,\n `${serviceOptions.serviceName}.service.ts`,\n );\n if (exists) {\n logError(`Service '${serviceOptions.serviceName}' already exists at ${basePath}!`);\n process.exit(1);\n }\n\n // Execute generation\n if (options.crud) {\n spinner.start('Generating CRUD service files...');\n await generateCrudService({\n name: serviceOptions.serviceName,\n outputPath: servicePath,\n httpClient: serviceOptions.httpClient,\n });\n spinner.succeed('CRUD service files generated');\n\n spinner.start('Registering CRUD API endpoints...');\n await registerCrudApiEndpoints(projectPath, serviceOptions.serviceName);\n spinner.succeed('CRUD API endpoints registered');\n } else {\n await executePipeline(createServicePipelineSteps(), {\n projectPath,\n spinner,\n serviceName: serviceOptions.serviceName,\n servicePath,\n httpClient: serviceOptions.httpClient,\n });\n }\n\n printServiceSuccess(serviceOptions, basePath, !!options.crud);\n } catch (error) {\n spinner.fail('Service generation failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n\nconst resolveServicePaths = (\n projectPath: string,\n serviceName: string,\n customPath?: string,\n): { basePath: string; servicePath: string } => {\n let basePath: string;\n\n if (customPath) {\n const cleanPath = customPath.replace(/^src\\//, '');\n if (cleanPath.startsWith('features/')) {\n const featureName = cleanPath.split('/')[1];\n basePath = path.join('src', 'features', featureName, 'services');\n } else {\n basePath = path.join('src', cleanPath);\n }\n } else {\n basePath = path.join('src', 'features', serviceName, 'services');\n }\n\n return {\n basePath,\n servicePath: path.join(projectPath, basePath),\n };\n};\n\nconst printServiceSuccess = (\n serviceOptions: { serviceName: string; httpClient: string },\n basePath: string,\n isCrud: boolean = false,\n) => {\n const displayPath = path.join(basePath, `${serviceOptions.serviceName}.service.ts`);\n log(\n pc.green(\n `\\n\u2728 ${isCrud ? 'CRUD ' : ''}Service '${serviceOptions.serviceName}' created successfully!\\n`,\n ),\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 if (isCrud) {\n log(pc.dim(` 2. Available methods: getAll, getById, create, update, delete`));\n log(pc.dim(` 3. Update DTO types in the service file`));\n } else {\n log(\n pc.dim(\n ` 2. Use in component: const data = await ${serviceOptions.serviceName}Service.getAll()`,\n ),\n );\n }\n log('');\n};\n", "import { readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel } from '../config/utils';\nimport { crudApiConfigTemplate } from '../generators/templates/crud-service.template';\nimport { addToAppApis } from './helpers';\n\n/**\n * Register CRUD API endpoints for a service in app-apis.ts.\n */\nexport const registerCrudApiEndpoints = async (\n projectPath: string,\n serviceName: string,\n): Promise<void> => {\n const camelName = kebabToCamel(serviceName);\n const apiConfigPath = path.join(projectPath, 'src', 'lib', 'config', 'app-apis.ts');\n\n try {\n let content = await readFile(apiConfigPath, 'utf-8');\n\n if (content.includes(`${camelName}:`)) return;\n\n if (!content.match(/export const AppApis = \\{[\\s\\S]*?\\} as const;/)) {\n throw new Error('Could not find AppApis object in app-apis.ts');\n }\n\n const newEndpoint = crudApiConfigTemplate({ camelName, kebabName: serviceName });\n content = addToAppApis(content, newEndpoint);\n await writeFile(apiConfigPath, content);\n } catch (error) {\n throw new Error(`Failed to register CRUD API endpoints: ${error}`, { cause: error });\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 type { Command } from 'commander';\nimport Enquirer from 'enquirer';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { setupBundleAnalyzer } from '../services/setup/bundle-analyzer';\nimport { setupCommitizen } from '../services/setup/commitizen';\nimport { setupDarkTheme } from '../services/setup/dark-theme';\nimport { setupHttpClient } from '../services/setup/http-client';\nimport { setupI18n } from '../services/setup/i18n';\nimport { setupReactCompiler } from '../services/setup/react-compiler';\nimport { setupRedux } from '../services/setup/redux';\nimport { setupSecurityHeaders } from '../services/setup/security-headers';\nimport { setupTests } from '../services/setup/tests';\nimport { setupValidationScripts } from '../services/setup/validate-scripts';\n\nconst { prompt } = Enquirer;\n\ninterface SetupOptions {\n httpClient?: string;\n darkTheme?: boolean;\n redux?: boolean;\n i18n?: boolean;\n tests?: boolean;\n reactCompiler?: boolean;\n bundleAnalyzer?: boolean;\n securityHeaders?: boolean;\n validateScripts?: boolean;\n commitizen?: 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 + @teispace/next-themes)')\n .option('--redux', 'Setup Redux Toolkit')\n .option('--i18n', 'Setup next-intl for internationalization')\n .option('--tests', 'Setup testing (Vitest + React Testing Library)')\n .option('--react-compiler', 'Enable the React Compiler')\n .option('--bundle-analyzer', 'Add @next/bundle-analyzer')\n .option('--security-headers', 'Add hardened HTTP headers to next.config.ts')\n .option(\n '--validate-scripts',\n 'Add scripts/sync-env.ts, scripts/check-deprecated.ts, and the validate chain',\n )\n .option('--commitizen', 'Add Commitizen with the conventional-changelog adapter')\n .action(async (options: SetupOptions) => {\n try {\n log(pc.cyan('\\n\uD83D\uDD27 Setup Wizard\\n'));\n\n const anyFlag =\n options.httpClient ||\n options.darkTheme ||\n options.redux ||\n options.i18n ||\n options.tests ||\n options.reactCompiler ||\n options.bundleAnalyzer ||\n options.securityHeaders ||\n options.validateScripts ||\n options.commitizen;\n\n if (anyFlag) {\n if (options.httpClient) await setupHttpClient(process.cwd());\n if (options.darkTheme) await setupDarkTheme(process.cwd());\n if (options.redux) await setupRedux(process.cwd());\n if (options.i18n) await setupI18n(process.cwd());\n if (options.tests) await setupTests(process.cwd());\n if (options.reactCompiler) await setupReactCompiler(process.cwd());\n if (options.bundleAnalyzer) await setupBundleAnalyzer(process.cwd());\n if (options.securityHeaders) await setupSecurityHeaders(process.cwd());\n if (options.validateScripts) await setupValidationScripts(process.cwd());\n if (options.commitizen) await setupCommitizen(process.cwd());\n return;\n }\n\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 { name: 'Testing (Vitest + RTL)', value: 'tests' },\n { name: 'React Compiler', value: 'react-compiler' },\n { name: 'Bundle Analyzer', value: 'bundle-analyzer' },\n { name: 'Security Headers', value: 'security-headers' },\n { name: 'Validation Scripts', value: 'validate-scripts' },\n { name: 'Commitizen', value: 'commitizen' },\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 const handlers: Record<string, (cwd: string) => Promise<void>> = {\n 'dark-theme': setupDarkTheme,\n redux: setupRedux,\n 'http-client': setupHttpClient,\n i18n: setupI18n,\n tests: setupTests,\n 'react-compiler': setupReactCompiler,\n 'bundle-analyzer': setupBundleAnalyzer,\n 'security-headers': setupSecurityHeaders,\n 'validate-scripts': setupValidationScripts,\n commitizen: setupCommitizen,\n };\n\n const handler = handlers[feature];\n if (handler) {\n await handler(process.cwd());\n } else {\n log(pc.yellow(`\\n\u26A0\uFE0F ${feature} setup is not implemented yet.`));\n }\n } catch (error) {\n spinner.fail('Setup failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n", "import { existsSync } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { kebabToCamel } from '../config/utils';\nimport { detectProjectSetup, directoryExists } from '../detection';\nimport { generateTest } from '../generators';\nimport { createSlicePipelineSteps, executePipeline } from '../pipelines';\nimport { promptForSliceDetails } from '../prompts/slice.prompt';\n\ninterface SliceCommandOptions {\n path?: string;\n persist?: boolean;\n noPersist?: boolean;\n test?: boolean;\n noTest?: 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 .option('--test', 'Also generate a sibling test file')\n .option('--no-test', 'Skip test file generation')\n .action(async (name: string | undefined, options: SliceCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\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 // Detect and validate Redux\n spinner.start('Detecting project setup...');\n const detection = await detectProjectSetup(projectPath);\n spinner.succeed('Project setup detected');\n\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 // Prompt and resolve paths\n const sliceOptions = await promptForSliceDetails(\n name,\n options.persist,\n options.noPersist === true ? false : undefined,\n );\n\n const { basePath, slicePath } = resolveSlicePaths(\n projectPath,\n sliceOptions.sliceName,\n options.path,\n );\n\n const featureStorePath = path.join(projectPath, basePath);\n if (!existsSync(featureStorePath)) {\n await mkdir(featureStorePath, { recursive: true });\n }\n\n const exists = await directoryExists(projectPath, sliceOptions.sliceName, basePath);\n if (exists) {\n logError(`Slice '${sliceOptions.sliceName}' already exists at ${basePath}!`);\n process.exit(1);\n }\n\n // Execute generation pipeline\n await executePipeline(createSlicePipelineSteps(), {\n projectPath,\n spinner,\n sliceName: sliceOptions.sliceName,\n basePath,\n slicePath,\n persistSlice: sliceOptions.persistSlice,\n });\n\n // Optional sibling test.\n let testFile: string | null = null;\n const shouldTest = resolveShouldTest(options, detection.hasTests);\n if (shouldTest) {\n const sliceFile = path.join(slicePath, `${sliceOptions.sliceName}.slice.ts`);\n spinner.start('Generating test...');\n testFile = await generateTest({\n projectPath,\n sourceFile: sliceFile,\n kind: 'slice',\n symbolName: kebabToCamel(sliceOptions.sliceName),\n });\n spinner.succeed('Test generated');\n }\n\n printSliceSuccess(sliceOptions, basePath, testFile, projectPath);\n } catch (error) {\n spinner.fail('Slice generation failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n\nconst resolveSlicePaths = (\n projectPath: string,\n sliceName: string,\n customPath?: string,\n): { basePath: string; slicePath: string } => {\n let basePath: string;\n\n if (customPath) {\n const cleanPath = customPath.replace(/^src\\//, '');\n if (cleanPath.startsWith('features/')) {\n const featureName = cleanPath.split('/')[1];\n basePath = path.join('src', 'features', featureName, 'store');\n } else {\n basePath = path.join('src', cleanPath);\n }\n } else {\n basePath = path.join('src', 'features', sliceName, 'store');\n }\n\n return {\n basePath,\n slicePath: path.join(projectPath, basePath, sliceName),\n };\n};\n\nconst resolveShouldTest = (\n options: { test?: boolean; noTest?: boolean },\n hasTests: boolean,\n): boolean => {\n if (options.noTest) return false;\n if (options.test) return true;\n return hasTests;\n};\n\nconst printSliceSuccess = (\n sliceOptions: { sliceName: string; persistSlice: boolean },\n basePath: string,\n testFile: string | null,\n projectPath: string,\n) => {\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 if (testFile) log(pc.dim(` \uD83E\uDDEA ${path.relative(projectPath, testFile)}\\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};\n", "import Enquirer from 'enquirer';\n\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 path from 'node:path';\nimport type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { kebabToCamel, kebabToPascal } from '../config/utils';\nimport { fileExists, readFile } from '../core/files';\nimport { detectProjectSetup } from '../detection';\nimport { generateTest, type TestKind } from '../generators';\n\ninterface TestCommandOptions {\n kind?: string;\n force?: boolean;\n}\n\nexport const registerTestCommand = (program: Command) => {\n program\n .command('test <file>')\n .description(\n 'Generate a sibling test file for an existing component, hook, or slice.\\n' +\n 'Infers the kind from filename/content; pass --kind to override.',\n )\n .option('--kind <kind>', 'Override inferred kind: component | hook | slice')\n .option('--force', 'Overwrite an existing test file')\n .action(async (file: string, options: TestCommandOptions) => {\n try {\n const projectPath = process.cwd();\n const sourceFile = path.isAbsolute(file) ? file : path.join(projectPath, file);\n\n log(pc.cyan('\\n\uD83E\uDDEA Test Generator\\n'));\n\n if (!fileExists(sourceFile)) {\n logError(`Source file not found: ${file}`);\n process.exit(1);\n }\n\n const detection = await detectProjectSetup(projectPath);\n if (!detection.hasTests) {\n logError(\n 'Testing is not installed in this project. Run `next-maker setup --tests` first.',\n );\n process.exit(1);\n }\n\n const content = await readFile(sourceFile);\n const kind = validateKind(options.kind) ?? inferKind(sourceFile, content);\n if (!kind) {\n logError(\n `Could not infer test kind for ${path.basename(sourceFile)}. Pass --kind component|hook|slice.`,\n );\n process.exit(1);\n }\n\n const symbolName = inferSymbolName(sourceFile, kind);\n\n const testPath = getTestPath(sourceFile, kind);\n if (fileExists(testPath) && !options.force) {\n logError(\n `Test file already exists: ${path.relative(projectPath, testPath)}. Use --force to overwrite.`,\n );\n process.exit(1);\n }\n\n spinner.start(`Generating ${kind} test...`);\n const written = await generateTest({\n projectPath,\n sourceFile,\n kind,\n symbolName,\n hasRedux: detection.hasRedux,\n hasI18n: detection.hasI18n,\n hookUsesStore:\n kind === 'hook' && detection.hasRedux && content.includes('useAppSelector'),\n });\n spinner.succeed('Test generated');\n\n log(pc.green(`\\n\u2728 Test '${path.basename(written)}' created.\\n`));\n log(pc.dim(` \uD83E\uDDEA ${path.relative(projectPath, written)}`));\n log('');\n } catch (error) {\n spinner.fail('Test generation failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n\nconst validateKind = (input: string | undefined): TestKind | null => {\n if (!input) return null;\n if (input === 'component' || input === 'hook' || input === 'slice') return input;\n throw new Error(`Invalid --kind: ${input}. Use component | hook | slice.`);\n};\n\nconst inferKind = (sourceFile: string, content: string): TestKind | null => {\n const base = path.basename(sourceFile);\n if (/\\.slice\\.ts$/.test(base)) return 'slice';\n if (/^use[A-Z]/.test(base.replace(/\\.tsx?$/, ''))) return 'hook';\n if (base.endsWith('.tsx')) return 'component';\n // .ts file that's not a slice and not a hook \u2014 check content for signals.\n if (/createSlice\\s*\\(/.test(content)) return 'slice';\n if (/^export\\s+(const|function)\\s+use[A-Z]/m.test(content)) return 'hook';\n return null;\n};\n\nconst inferSymbolName = (sourceFile: string, kind: TestKind): string => {\n const base = path.basename(sourceFile).replace(/\\.(tsx?|jsx?)$/i, '');\n if (kind === 'slice') {\n // counter.slice \u2192 counter\n return kebabToCamel(base.replace(/\\.slice$/, ''));\n }\n if (kind === 'hook') {\n // useCounter.ts \u2192 useCounter; use-counter.ts \u2192 useCounter\n if (/^use[A-Z]/.test(base)) return base;\n return `use${kebabToPascal(base.replace(/^use-?/, ''))}`;\n }\n return kebabToPascal(base);\n};\n\nconst getTestPath = (sourceFile: string, kind: TestKind): string => {\n const dir = path.dirname(sourceFile);\n const base = path.basename(sourceFile).replace(/\\.(tsx?|jsx?)$/i, '');\n const ext = kind === 'component' ? '.tsx' : '.ts';\n return path.join(dir, `${base}.test${ext}`);\n};\n", "import type { Command } from 'commander';\nimport { registerAppCommand } from './app';\nimport { registerComponentCommand } from './component';\nimport { registerDoctorCommand } from './doctor';\nimport { registerEnvCommand } from './env';\nimport { registerFaviconCommand } from './favicon';\nimport { registerFeatureCommand } from './feature';\nimport { registerHookCommand } from './hook';\nimport { registerLayoutCommand } from './layout';\nimport { registerLocaleCommand } from './locale';\nimport { registerPageCommand } from './page';\nimport { registerProviderCommand } from './provider';\nimport { registerRemoveCommand } from './remove';\nimport { registerServiceCommand } from './service';\nimport { registerSetupCommand } from './setup';\nimport { registerSliceCommand } from './slice';\nimport { registerTestCommand } from './test';\n\nexport const registerCommands = (program: Command) => {\n registerAppCommand(program);\n registerSetupCommand(program);\n registerFeatureCommand(program);\n registerSliceCommand(program);\n registerServiceCommand(program);\n registerPageCommand(program);\n registerLayoutCommand(program);\n registerComponentCommand(program);\n registerLocaleCommand(program);\n registerHookCommand(program);\n registerProviderCommand(program);\n registerEnvCommand(program);\n registerFaviconCommand(program);\n registerDoctorCommand(program);\n registerRemoveCommand(program);\n registerTestCommand(program);\n};\n"],
|
|
5
|
-
"mappings": "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EKjNO,IAAME,GAAmB,IAAI,IAAI,CACtC,YACA,eACA,OACA,aACA,QACA,QACA,SACA,QACA,iBACA,OACA,aACA,QACA,YACA,YACA,aACA,YACA,QACA,iBACA,WACA,UACA,OACA,WACA,WACA,gBACA,WACA,YACA,WACA,YACA,cACA,iBACA,aACA,aACA,UACA,aACA,eACA,gBACA,gBACA,gBACA,gBACA,aACA,WACA,cACA,UACA,UACA,aACA,YACA,cACA,cACA,UACA,YACA,aACA,OACA,YACA,OACA,QACA,cACA,OACA,WACA,UACA,YACA,SACA,QACA,QACA,WACA,gBACA,YACA,eACA,YACA,aACA,YACA,uBACA,YACA,aACA,YACA,YACA,cACA,gBACA,eACA,iBACA,iBACA,iBACA,cACA,OACA,YACA,QACA,UACA,SACA,mBACA,aACA,eACA,eACA,iBACA,kBACA,oBACA,kBACA,kBACA,eACA,YACA,YACA,WACA,cACA,OACA,UACA,QACA,YACA,SACA,YACA,SACA,gBACA,YACA,gBACA,gBACA,aACA,YACA,OACA,OACA,OACA,aACA,SACA,gBACA,MACA,YACA,YACA,cACA,SACA,aACA,WACA,WACA,SACA,SACA,UACA,YACA,YACA,YACA,OACA,cACA,YACA,MACA,OACA,UACA,SACA,YACA,SACA,QACA,QACA,aACA,SACA,aACF,CAAC,ERxHD,IAAMC,GAAyB,CAAC,SAAU,UAAW,SAAU,UAAU,EACnEC,GAAqB,CAAC,UAAW,QAAS,MAAM,EAEhDC,GAAkB,CACtBC,EACAC,EACAC,EACAC,IACM,CACN,GAAI,CAACH,EAAK,OAAOE,EACjB,GAAI,CAACD,EAAQ,SAASD,CAAQ,EAC5B,MAAM,IAAI,MAAM,uBAAuBG,CAAI,MAAMH,CAAG,eAAeC,EAAQ,KAAK,IAAI,CAAC,EAAE,EAEzF,OAAOD,CACT,EAEMI,GAAoB,CACxBJ,EACAE,EACAC,EACAE,EACAC,IACW,CACX,GAAIN,IAAQ,OAAW,OAAOE,EAC9B,IAAMK,EAAI,OAAOP,CAAG,EACpB,GAAI,CAAC,OAAO,S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",
|
|
6
|
-
"names": ["existsSync", "fs", "path", "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", "exec", "path", "promisify", "execAsync", "init_injectors", "__esmMin", "init_paths", "init_files", "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", "existsSync", "access", "path", "directoryExists", "fileExistsAt", "init_existence_checker", "__esmMin", "projectPath", "name", "basePath", "fileName", "access", "readFile", "path", "detectProjectSetup", "init_project_detector", "__esmMin", "projectPath", "packageJsonPath", "packageJsonContent", "packageJson", "dependencies", "hasRedux", "hasI18n", "hasAxios", "hasFetch", "axiosClientPath", "fetchClientPath", "httpClient", "hasTests", "error", "detection_exports", "__export", "detectProjectSetup", "directoryExists", "fileExistsAt", "init_detection", "__esmMin", "init_existence_checker", "init_project_detector", "Command", "path", "pc", "setupCancellationHandlers", "options", "logger", "m", "exitOnCancel", "onCancel", "onUncaught", "err", "onRejection", "reason", "pc", "colorMap", "s", "print", "message", "color", "colorFn", "text", "error", "message", "print", "logError", "warning", "log", "message", "print", "printBanner", "ora", "startSpinner", "text", "options", "spinner", "capitalize", "str", "kebabToCamel", "_", "letter", "kebabToPascal", "ora", "spinner", "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", "getDevFlag", "installDevPackages", "installCommand", "flag", "installDevPackage", "uninstallPackages", "getUninstallCommand", "uninstallPackage", "Enquirer", "PROJECT_NAME_RE", "SEMVER_RE", "isValidProjectName", "value", "isValidSemver", "defaultProjectAnswers", "initialName", "overrides", "projectName", "version", "author", "company", "prompt", "promptForProjectDetails", "response", "answers", "baseUrl", "init_files", "path", "writeTestUtils", "projectPath", "features", "content", "pickTemplate", "writeFile", "redux", "i18n", "BOTH", "REDUX_ONLY", "I18N_ONLY", "MINIMAL", "path", "PACKAGES", "init_paths", "init_files", "cleanupBundleAnalyzer", "projectPath", "answers", "nextConfigPath", "path", "PROJECT_PATHS", "fileExists", "content", "readFile", "writeFile", "updateJson", "pkg", "PACKAGES", "init_paths", "init_files", "path", "cleanupDarkMode", "projectPath", "answers", "deleteFile", "PROJECT_PATHS", "removeThemeProviderExport", "removeDarkModeCSS", "removeDarkModeFromLayout", "providersIndexPath", "content", "readFile", "writeFile", "globalsCssPath", "fileExists", "stripDarkModeClasses", "layoutPaths", "layoutPath", "original", "updated", "init_paths", "init_files", "init_injectors", "path", "cleanupHttpClient", "projectPath", "answers", "httpUtilsPath", "PROJECT_PATHS", "keepSecureStorage", "cleanupNoHttpClient", "cleanupFetchClient", "cleanupAxiosClient", "deleteDirectory", "writeFile", "deleteFile", "cleanupHttpTypes", "removeHttpExports", "removeAppApisExport", "removeApiConstants", "removeTypesExports", "content", "readFile", "httpTypesPath", "fileExists", "typesContent", "utilsIndexPath", "configIndexPath", "constantsPath", "typesIndexPath", "init_paths", "init_files", "path", "cleanupI18n", "projectPath", "answers", "deleteI18nFiles", "removeI18nExports", "removeI18nFromNextConfig", "removeI18nFromCounter", "removeI18nFromEnv", "envPath", "PROJECT_PATHS", "fileExists", "content", "readFile", "writeFile", "deleteDirectory", "deleteFile", "typesIndexPath", "configIndexPath", "nextConfigPath", "counterComponentPath", "counterTestPath", "testUtilsPath", "init_paths", "init_files", "path", "cleanupSecureStorage", "projectPath", "answers", "deleteDirectory", "PROJECT_PATHS", "cleanupLicense", "deleteFile", "cleanupChangelog", "cleanupConfig", "cleanupTemplateArtifacts", "path", "init_paths", "init_files", "cleanupReactCompiler", "projectPath", "answers", "nextConfigPath", "path", "PROJECT_PATHS", "fileExists", "content", "readFile", "writeFile", "updateJson", "pkg", "PACKAGES", "init_paths", "init_files", "path", "cleanupRedux", "projectPath", "answers", "deleteDirectory", "PROJECT_PATHS", "deleteFile", "removeStoreProviderExport", "removeCounterFromPages", "providersIndexPath", "content", "readFile", "writeFile", "pagesToClean", "pagePath", "fileExists", "path", "init_paths", "init_files", "TEST_DEVDEPS", "PACKAGES", "cleanupTests", "projectPath", "answers", "deleteFile", "path", "PROJECT_PATHS", "deleteDirectory", "updateJson", "pkg", "dep", "cleanupFeatures", "projectPath", "answers", "spinner", "startSpinner", "cleanupHttpClient", "cleanupSecureStorage", "cleanupRedux", "cleanupDarkMode", "cleanupBundleAnalyzer", "cleanupI18n", "cleanupReactCompiler", "cleanupTests", "cleanupLicense", "cleanupChangelog", "cleanupConfig", "cleanupTemplateArtifacts", "writeTestUtils", "error", "path", "init_paths", "init_files", "configurePackageJson", "projectPath", "answers", "spinner", "startSpinner", "gitRemote", "gitHomepage", "gitIssues", "updateJson", "path", "PROJECT_PATHS", "pkg", "PACKAGES", "error", "readdir", "path", "init_paths", "init_files", "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", "init_paths", "init_files", "path", "generateRootProvider", "projectPath", "answers", "imports", "propsFields", "destructureFields", "jsx", "propsType", "rootProviderContent", "writeFile", "PROJECT_PATHS", "generateLayout", "htmlClasses", "providerPropsLine", "basicLayout", "counterImport", "counterComponent", "basicPage", "degit", "cloneTemplate", "projectPath", "spinner", "startSpinner", "degit", "error", "VALID_PACKAGE_MANAGERS", "validatePackageManagerOverride", "raw", "registerAppCommand", "program", "name", "options", "packageManager", "createApp", "err", "logError", "withStepSpinner", "text", "successText", "fn", "ref", "spinner", "startSpinner", "result", "summariseDefaults", "answers", "features", "log", "pc", "initialName", "flags", "printBanner", "defaultProjectAnswers", "promptForProjectDetails", "projectPath", "path", "fileExists", "active", "performCleanup", "deleteDirectory", "cleanupErr", "handleSignal", "cloneTemplate", "configurePackageJson", "cleanupFeatures", "generateRootProvider", "generateLayout", "setupDevTools", "initializeGit", "installDependencies", "runScript", "envExamplePath", "envPath", "path", "pc", "init_detection", "mkdir", "writeFile", "path", "init_files", "sharedComponentTemplate", "params", "componentName", "isClient", "hasI18n", "ns", "lines", "componentBarrelTemplate", "generateComponent", "options", "name", "projectPath", "isClient", "hasI18n", "featurePath", "componentName", "kebabToPascal", "generateFeatureComponent", "generateSharedComponent", "componentsDir", "path", "mkdir", "writeFile", "sharedComponentTemplate", "_kebabName", "componentDir", "componentBarrelTemplate", "commonIndexPath", "appendExport", "rootIndexPath", "ensureCommonReExport", "filePath", "exportLine", "content", "fileExists", "readFile", "commonExport", "writeFile", "path", "crudServiceTemplate", "params", "camelName", "pascalName", "httpClient", "clientImport", "clientName", "crudApiConfigTemplate", "kebabName", "generateCrudService", "options", "name", "outputPath", "httpClient", "camelName", "kebabToCamel", "pascalName", "kebabToPascal", "writeFile", "path", "crudServiceTemplate", "mkdir", "writeFile", "path", "writeFile", "path", "serviceTemplate", "params", "camelName", "httpClient", "generateService", "options", "name", "outputPath", "httpClient", "camelName", "kebabToCamel", "writeFile", "path", "serviceTemplate", "mkdir", "writeFile", "path", "sliceBarrelTemplate", "params", "sliceName", "withPersist", "featureBarrelTemplate", "featureName", "componentName", "hookName", "withStore", "withService", "persistTemplate", "params", "componentName", "camelName", "typesImportPath", "versionConst", "selectorsTemplate", "params", "componentName", "camelName", "sliceName", "sliceTemplate", "params", "componentName", "camelName", "typesImportPath", "stateTypesTemplate", "params", "componentName", "withStore", "generateSlice", "options", "name", "outputPath", "persist", "typesImportPath", "mkdir", "componentName", "kebabToPascal", "camelName", "kebabToCamel", "writeFile", "path", "stateTypesTemplate", "sliceTemplate", "selectorsTemplate", "persistTemplate", "sliceBarrelTemplate", "componentTemplate", "params", "componentName", "hookName", "hookWithStoreTemplate", "params", "hookName", "componentName", "featureName", "hookWithoutStoreTemplate", "generateFeature", "options", "name", "outputPath", "createStore", "persistStore", "createService", "httpClient", "componentName", "kebabToPascal", "hookName", "dirs", "path", "dir", "mkdir", "writeFile", "componentTemplate", "hookWithStoreTemplate", "hookWithoutStoreTemplate", "stateTypesTemplate", "featureBarrelTemplate", "generateSlice", "generateService", "mkdir", "writeFile", "path", "customHookTemplate", "params", "hookName", "isClient", "lines", "generateHook", "options", "name", "projectPath", "isClient", "featurePath", "hookName", "kebabToPascal", "hooksDir", "path", "mkdir", "writeFile", "customHookTemplate", "mkdir", "path", "init_files", "i18nTemplate", "componentName", "plainTemplate", "layoutTemplate", "hasI18n", "SEGMENT_RE", "SEGMENT_LIST_RE", "validateSegment", "segment", "validateAt", "at", "generateLayout", "options", "projectPath", "hasI18n", "withGroup", "componentName", "kebabToPascal", "leaf", "baseSegments", "targetDir", "path", "layoutFile", "fileExists", "mkdir", "writeFile", "layoutTemplate", "init_files", "copyFile", "readFileFs", "writeFile", "path", "generateLocale", "options", "code", "name", "country", "flag", "projectPath", "copyTranslations", "createTranslationFile", "updateSupportedLocaleType", "updateAppLocalesConfig", "translationsDir", "sourcePath", "destPath", "sourceContent", "sourceJson", "emptyJson", "emptyValues", "obj", "result", "key", "value", "typesPath", "fileExists", "content", "readFile", "localeTypeRegex", "match", "newType", "localeName", "configPath", "closingBracket", "newLocale", "mkdir", "writeFile", "path", "pageTemplate", "params", "componentName", "routePath", "hasI18n", "dynamicPageTemplate", "paramName", "loadingTemplate", "errorTemplate", "generatePage", "options", "name", "projectPath", "hasI18n", "dynamic", "withLoading", "withError", "componentName", "kebabToPascal", "routePath", "baseDir", "pageDir", "path", "mkdir", "pageContent", "dynamicPageTemplate", "pageTemplate", "writeFile", "loadingTemplate", "errorTemplate", "init_paths", "mkdir", "path", "init_files", "ensureSuffix", "name", "suffix", "providerTemplate", "baseName", "componentName", "root", "valueType", "contextName", "hookName", "providerComponentName", "NAME_RE", "toPascal", "name", "kebabToPascal", "generateProvider", "options", "projectPath", "baseName", "componentName", "providerComponentName", "fileBaseName", "providerDir", "path", "PROJECT_PATHS", "providerFile", "fileExists", "mkdir", "writeFile", "providerTemplate", "init_files", "path", "componentTestTemplate", "params", "componentName", "sourceImportPath", "testUtilsImportPath", "hasRedux", "hasI18n", "extraOptions", "optionsBlock", "hookTestTemplate", "hookName", "withStore", "sliceTestTemplate", "camelName", "sliceRef", "generateTest", "options", "projectPath", "sourceFile", "kind", "symbolName", "testDir", "path", "sourceBaseName", "extension", "testFile", "sourceImportPath", "testUtilsImportPath", "relativeImport", "content", "componentTestTemplate", "hookTestTemplate", "sliceTestTemplate", "writeFile", "from", "to", "rel", "Enquirer", "prompt", "promptForComponentDetails", "name", "presets", "questions", "value", "answers", "registerComponentCommand", "program", "name", "options", "projectPath", "log", "pc", "spinner", "detection", "detectProjectSetup", "componentOptions", "promptForComponentDetails", "componentName", "kebabToPascal", "isClient", "hasI18n", "shouldTest", "resolveShouldTest", "generateComponent", "testFile", "componentFile", "path", "generateTest", "location", "error", "logError", "hasTests", "pc", "init_paths", "init_files", "path", "init_paths", "path", "pc", "init_files", "setupBundleAnalyzer", "projectPath", "spinner", "startSpinner", "nextConfigPath", "path", "PROJECT_PATHS", "fileExists", "content", "readFile", "exportDefaultRe", "match", "replacement", "writeFile", "updateJson", "pkg", "installDevPackage", "pc", "error", "removeNamedImport", "content", "symbol", "lines", "out", "defaultRe", "namedRe", "line", "m", "symbols", "s", "filtered", "unwrapJsxChain", "componentName", "openRe", "openIdx", "openIndent", "i", "escapedIndent", "closeRe", "closeIdx", "inner", "merged", "unwrapNextIntlPlugin", "content", "result", "line", "callRe", "unwrapBundleAnalyzer", "removeNamedImport", "blockRe", "bundleAnalyzerManifest", "projectPath", "target", "path", "PROJECT_PATHS", "fileExists", "readFile", "unwrapBundleAnalyzer", "setupBundleAnalyzer", "init_paths", "init_files", "path", "init_paths", "path", "pc", "init_files", "addCommitizen", "pkg", "scripts", "devDeps", "PACKAGES", "missingCommitizenDeps", "missing", "CZRC_CONTENT", "setupCommitizen", "projectPath", "spinner", "startSpinner", "czrcPath", "path", "PROJECT_PATHS", "fileExists", "writeFile", "pkgPath", "beforePkg", "readFile", "missing", "missingCommitizenDeps", "updateJson", "pkg", "addCommitizen", "manager", "detectPackageManager", "installDevPackages", "pc", "error", "commitizenManifest", "projectPath", "fileExists", "path", "PROJECT_PATHS", "setupCommitizen", "init_paths", "init_files", "path", "path", "pc", "init_files", "init_paths", "init_files", "path", "degit", "fetchAssets", "tempDir", "spinner", "copyThemeProvider", "projectPath", "themeProviderPath", "PROJECT_PATHS", "sourceProviderPath", "copyFile", "init_paths", "init_files", "path", "init_paths", "init_files", "path", "findLayoutPath", "projectPath", "possibleLayoutPaths", "PROJECT_PATHS", "p", "fileExists", "readFile", "checkIsAlreadySetup", "projectPath", "themeProviderPath", "path", "PROJECT_PATHS", "globalsCssPath", "packageJsonPath", "fileExists", "packageJson", "readFile", "themesPkg", "validateProjectStructure", "providersIndexPath", "layoutPath", "findLayoutPath", "init_paths", "init_files", "path", "updateProvidersIndex", "projectPath", "providersIndexPath", "PROJECT_PATHS", "providersContent", "readFile", "writeFile", "updateRootProvider", "rootProviderPath", "fileExists", "content", "useClientDirective", "hasUseClient", "_m", "open", "names", "close", "returnMatch", "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", "darkThemeManifest", "projectPath", "fileExists", "path", "PROJECT_PATHS", "unwrapJsxChain", "setupDarkTheme", "fs", "path", "Enquirer", "pc", "init_files", "init_paths", "init_files", "fs", "path", "degit", "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_paths", "init_files", "path", "checkIsAlreadySetup", "projectPath", "fetchClientPath", "PROJECT_PATHS", "axiosClientPath", "hasFetch", "fileExists", "hasAxios", "validateProjectStructure", "missingPaths", "p", "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", "httpClientManifest", "projectPath", "detectProjectSetup", "setupHttpClient", "init_paths", "path", "pc", "init_files", "init_paths", "init_files", "fs", "path", "degit", "fetchAssets", "tempDir", "spinner", "copyI18nFiles", "projectPath", "sourceI18nDir", "destI18nDir", "PROJECT_PATHS", "sourceProxyPath", "destProxyPath", "copyFile", "sourceTypesPath", "destTypesPath", "sourceLocalesPath", "destLocalesPath", "init_paths", "init_files", "path", "checkIsAlreadySetup", "projectPath", "i18nDir", "PROJECT_PATHS", "packageJsonPath", "fileExists", "packageJson", "readFile", "validateProjectStructure", "rootLayoutPath", "localeLayoutPath", "init_paths", "init_files", "fs", "path", "updateNextConfig", "projectPath", "nextConfigPath", "PROJECT_PATHS", "fileExists", "content", "readFile", "exportDefaultRegex", "writeFile", "updateTypesIndex", "typesIndexPath", "updateConfigIndex", "configIndexPath", "updateRootProvider", "rootProviderPath", "useClientDirective", "hasUseClient", "i18nFields", "aliasRe", "inlineRe", "_m", "open", "body", "close", "trimmed", "inner", "existing", "match", "existingParams", "existingTypes", "newParams", "newTypes", "returnMatch", "existingJsx", "wrapped", "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", "vitestConfigPath", "PROJECT_PATHS", "fileExists", "pkg", "readFile", "deps", "hasRedux", "writeTestUtils", "packageManager", "detectPackageManager", "runScript", "pc", "error", "deleteDirectory", "i18nManifest", "projectPath", "detectProjectSetup", "unwrapNextIntlPlugin", "unwrapJsxChain", "setupI18n", "init_paths", "init_files", "path", "init_paths", "path", "pc", "init_files", "setupReactCompiler", "projectPath", "spinner", "startSpinner", "nextConfigPath", "path", "PROJECT_PATHS", "fileExists", "content", "readFile", "configBlock", "writeFile", "installDevPackage", "pc", "error", "reactCompilerManifest", "projectPath", "target", "path", "PROJECT_PATHS", "fileExists", "readFile", "setupReactCompiler", "init_paths", "path", "pc", "init_files", "init_paths", "init_files", "fs", "path", "degit", "fetchAssets", "tempDir", "spinner", "copyReduxFiles", "projectPath", "sourceProviderPath", "destProviderPath", "PROJECT_PATHS", "copyFile", "sourceStoreDir", "destStoreDir", "createCounterFeature", "sourceFeatureDir", "destFeatureDir", "counterComponentPath", "fileExists", "content", "readFile", "writeFile", "init_paths", "init_files", "path", "checkIsAlreadySetup", "projectPath", "storePath", "path", "PROJECT_PATHS", "packageJsonPath", "fileExists", "packageJson", "readFile", "validateProjectStructure", "providersIndexPath", "findLayoutPath", "init_paths", "init_files", "path", "updateProvidersIndex", "_projectPath", "updateRootProvider", "projectPath", "rootProviderPath", "fileExists", "content", "readFile", "useClientDirective", "hasUseClient", "_m", "inner", "returnMatch", "existingJsx", "writeFile", "updatePage", "possiblePagePaths", "PROJECT_PATHS", "pagePath", "p", "pageContent", "lastDivIndex", "lastMainIndex", "insertIndex", "setupRedux", "projectPath", "spinner", "startSpinner", "tempDir", "path", "isSetup", "reason", "checkIsAlreadySetup", "validateProjectStructure", "fetchAssets", "copyReduxFiles", "createCounterFeature", "updateProvidersIndex", "updateRootProvider", "updatePage", "installPackage", "vitestConfigPath", "PROJECT_PATHS", "fileExists", "pkg", "readFile", "deps", "writeTestUtils", "packageManager", "detectPackageManager", "runScript", "pc", "error", "deleteDirectory", "reduxManifest", "projectPath", "detectProjectSetup", "unwrapJsxChain", "setupRedux", "init_paths", "init_files", "path", "init_paths", "path", "pc", "init_files", "SECURITY_HEADERS", "NEXT_CONFIG_BLOCK_RE", "HEADERS_KEY_RE", "buildHeadersBlock", "headers", "key", "value", "hasSecurityHeaders", "content", "injectSecurityHeaders", "setupSecurityHeaders", "projectPath", "spinner", "startSpinner", "nextConfigPath", "path", "PROJECT_PATHS", "fileExists", "content", "readFile", "hasSecurityHeaders", "updated", "injectSecurityHeaders", "writeFile", "pc", "error", "securityHeadersManifest", "projectPath", "target", "path", "PROJECT_PATHS", "fileExists", "hasSecurityHeaders", "readFile", "setupSecurityHeaders", "init_paths", "init_files", "path", "init_paths", "fs", "path", "degit", "pc", "init_files", "TEST_DEVDEPS", "setupTests", "projectPath", "spinner", "startSpinner", "tempDir", "path", "vitestConfigPath", "PROJECT_PATHS", "fileExists", "degit", "copyFile", "testDir", "fs", "packageJsonPath", "pkg", "readFile", "deps", "hasRedux", "hasI18n", "writeTestUtils", "updateJson", "p", "manager", "detectPackageManager", "installDevPackages", "runScript", "pc", "error", "deleteDirectory", "testsManifest", "projectPath", "fileExists", "path", "PROJECT_PATHS", "setupTests", "init_files", "path", "init_paths", "path", "pc", "init_files", "SCRIPT_RUNNER_PREFIX", "buildValidateChain", "manager", "prefix", "name", "addValidationScripts", "pkg", "scripts", "devDeps", "SYNC_ENV_SCRIPT", "CHECK_DEPRECATED_SCRIPT", "SCRIPT_TARGETS", "SYNC_ENV_SCRIPT", "CHECK_DEPRECATED_SCRIPT", "setupValidationScripts", "projectPath", "spinner", "startSpinner", "wroteAny", "relative", "content", "target", "path", "fileExists", "writeFile", "manager", "detectPackageManager", "needsTsx", "updateJson", "PROJECT_PATHS", "pkg", "before", "next", "addValidationScripts", "installDevPackages", "pc", "error", "SCRIPT_FILES", "validateScriptsManifest", "projectPath", "rel", "fileExists", "path", "p", "setupValidationScripts", "init_paths", "init_files", "path", "readPackageJson", "projectPath", "pkgPath", "path", "PROJECT_PATHS", "fileExists", "readFile", "writePackageJson", "pkg", "writeFile", "depsFor", "kind", "checkManifest", "manifest", "installed", "drift", "file", "dep", "scripts", "script", "actual", "injection", "filePath", "content", "reverseManifest", "options", "dryRun", "summary", "stripped", "out", "rm", "target", "description", "touched", "manager", "detectPackageManager", "uninstallPackages", "MANIFESTS", "securityHeadersManifest", "validateScriptsManifest", "commitizenManifest", "reactCompilerManifest", "bundleAnalyzerManifest", "testsManifest", "darkThemeManifest", "httpClientManifest", "reduxManifest", "i18nManifest", "getManifest", "id", "m", "formatFinding", "f", "pc", "summary", "results", "installed", "r", "drifted", "registerDoctorCommand", "program", "options", "projectPath", "targets", "MANIFESTS", "m", "manifest", "checkManifest", "log", "result", "drift", "stats", "error", "logError", "pc", "init_paths", "init_files", "path", "NAME_RE", "validateName", "name", "ensurePublicPrefix", "isPublic", "formatDefault", "spec", "baseSchemaTypeFor", "values", "v", "buildSchemaEntry", "fullName", "inner", "hasDefault", "optional", "expression", "escaped", "ENV_SCHEMA_RE", "injectSchemaEntry", "content", "match", "head", "body", "tail", "trimmedBody", "normalisedBody", "entry", "newBody", "PUBLIC_MARKER_SUFFIX", "exampleLineFor", "value", "trailing", "appendEnvExampleEntry", "trailingNewline", "blank", "description", "appendEnvEntry", "addEnvVar", "projectPath", "schemaPath", "fileExists", "schemaBefore", "readFile", "schemaAfter", "schemaUpdated", "writeFile", "envExamplePath", "PROJECT_PATHS", "envExampleUpdated", "before", "after", "envPath", "envUpdated", "VALID_TYPES", "parseType", "raw", "value", "parseEnum", "values", "v", "registerEnvCommand", "program", "name", "options", "projectPath", "log", "pc", "type", "enumValues", "spec", "spinner", "result", "addEnvVar", "fullName", "ensurePublicPrefix", "error", "logError", "path", "pc", "Enquirer", "prompt", "promptForFaviconSource", "presets", "value", "access", "readFile", "stat", "path", "exists", "p", "isDirectory", "detectAppDir", "projectPath", "candidates", "candidate", "PWA_PACKAGES", "detectPwa", "result", "publicCandidates", "appDir", "ext", "pkg", "deps", "name", "mkdir", "readFile", "stat", "writeFile", "path", "sharp", "pngToIco", "sharp", "escapeForXml", "value", "buildShapeMask", "shape", "size", "radiusPercent", "r", "buildSquircle", "s", "c", "path", "buildBackground", "color", "renderPng", "opts", "size", "paddingPercent", "bg", "fit", "shape", "radiusPercent", "quality", "forceSquare", "sourceBuffer", "innerSize", "sharpFit", "resized", "sharp", "offset", "canvasBg", "flatColor", "composed", "clipShape", "mask", "buildShapeMask", "clampCompression", "color", "probe", "buildBackground", "g", "b", "a", "n", "encodeIco", "frames", "pngToIco", "readFile", "writeFile", "buildIconEntries", "publicPaths", "src", "size", "patchJsonManifest", "manifestPath", "icons", "raw", "parsed", "existing", "bySrc", "icon", "renderManifestSnippet", "icons", "icon", "buildBootstrapManifest", "appName", "themeColor", "stat", "path", "SUPPORTED_EXTS", "validateSource", "source", "absolutePath", "info", "ext", "parseSizes", "raw", "fallback", "sizes", "s", "fileExists", "p", "stat", "writeAll", "jobs", "force", "dryRun", "results", "job", "mkdir", "path", "writeFile", "runFavicon", "projectPath", "options", "source", "validateSource", "sourceBuffer", "readFile", "ogSourceBuffer", "icoFrames", "size", "renderPng", "icoBuffer", "encodeIco", "buf", "appleBg", "renderOgImage", "pwaSnippet", "pwa", "detectPwa", "publicDir", "sizes", "iconJobs", "fileName", "icons", "buildIconEntries", "next", "patchJsonManifest", "renderManifestSnippet", "bootstrapPath", "content", "buildBootstrapManifest", "isTwitter", "targetHeight", "innerSize", "inner", "bgColor", "background", "flatColor", "offsetLeft", "offsetTop", "sharp", "CSS_NAMED_COLORS", "SHAPES", "FITS", "parseEnumOption", "raw", "allowed", "fallback", "flag", "parseNumberOption", "min", "max", "n", "registerFaviconCommand", "program", "projectPath", "log", "pc", "promptResult", "promptForFaviconSource", "outDir", "resolveOutDir", "shape", "fit", "radius", "padding", "quality", "icoSizes", "parseSizes", "bg", "validateBg", "all", "options", "spinner", "result", "runFavicon", "out", "rel", "path", "formatBytes", "err", "message", "logError", "override", "detected", "detectAppDir", "warning", "HEX_RE", "FUNCTIONAL_RE", "CSS_NAMED_COLORS", "path", "pc", "init_detection", "init_detection", "path", "readFile", "writeFile", "path", "addImportStatement", "fileContent", "importStatement", "importRegex", "imports", "lastImport", "lastImportIndex", "addToCombineReducers", "reducerKey", "reducerEntry", "combineReducersRegex", "match", "reducersContent", "newEntry", "updatedReducersContent", "addToAppApis", "endpointBlock", "insertPosition", "beforeClosing", "afterClosing", "registerApiEndpoints", "options", "serviceName", "projectPath", "camelName", "kebabToCamel", "apiConfigPath", "path", "content", "readFile", "newEndpoint", "addToAppApis", "writeFile", "error", "readFile", "writeFile", "path", "init_files", "registerAppPath", "projectPath", "routeName", "routePath", "appPathsFile", "path", "fileExists", "content", "readFile", "camelName", "kebabToCamel", "closingBrace", "newEntry", "writeFile", "init_paths", "init_files", "path", "COMPONENT_TAG_RE", "componentName", "injectProviderIntoChain", "content", "childrenLineRe", "match", "indent", "innerIndent", "replacement", "addProviderToBarrel", "fileBaseName", "exportLine", "lines", "exportLines", "others", "line", "merged", "firstExportIdx", "l", "before", "afterStart", "idx", "after", "PROVIDER_DIR_REL", "PROJECT_PATHS", "ROOT_PROVIDER_REL", "PROVIDERS_INDEX_REL", "findRootProviderFile", "projectPath", "fs", "fileExists", "readFile", "canonical", "path", "dir", "readdir", "candidates", "name", "best", "entry", "filePath", "contents", "depth", "registerProvider", "options", "rootProviderFile", "addImportStatement", "writeFile", "barrelPath", "barrelFile", "readFile", "writeFile", "path", "registerInRootReducer", "options", "projectPath", "name", "persist", "importPath", "rootReducerPath", "path", "content", "readFile", "camelName", "kebabToCamel", "reducerName", "persistConfigName", "aliasPath", "importStatement", "addImportStatement", "reducerEntry", "addToCombineReducers", "writeFile", "error", "init_files", "readFile", "writeFile", "path", "addTranslationNamespace", "projectPath", "namespace", "translationFile", "fileExists", "content", "json", "createFeaturePipelineSteps", "ctx", "detectProjectSetup", "generateFeature", "registerApiEndpoints", "registerInRootReducer", "path", "executePipeline", "steps", "context", "step", "error", "createServicePipelineSteps", "ctx", "generateService", "registerApiEndpoints", "path", "createSlicePipelineSteps", "ctx", "generateSlice", "registerInRootReducer", "path", "Enquirer", "prompt", "promptForFeatureDetails", "featureName", "hasRedux", "httpClient", "skipStore", "storeOption", "skipService", "serviceClient", "questions", "value", "answers", "registerFeatureCommand", "program", "name", "options", "projectPath", "validateFeatureOptions", "log", "pc", "steps", "createFeaturePipelineSteps", "spinner", "detectProjectSetup", "detection", "featureOptions", "promptForFeatureDetails", "basePath", "path", "featurePath", "directoryExists", "logError", "executePipeline", "printFeatureSuccess", "error", "displayPath", "importPath", "path", "pc", "init_detection", "Enquirer", "prompt", "promptForHookDetails", "name", "value", "registerHookCommand", "program", "name", "options", "projectPath", "log", "pc", "detection", "detectProjectSetup", "hookOptions", "promptForHookDetails", "hookName", "kebabToPascal", "shouldTest", "resolveShouldTest", "spinner", "generateHook", "hookFile", "path", "testFile", "generateTest", "location", "importPath", "error", "logError", "hasTests", "pc", "init_detection", "registerLayoutCommand", "program", "segment", "options", "projectPath", "log", "pc", "spinner", "detection", "detectProjectSetup", "hasI18n", "result", "generateLayout", "error", "logError", "path", "pc", "init_files", "init_detection", "Enquirer", "prompt", "promptForLocaleDetails", "code", "presets", "questions", "value", "answers", "registerLocaleCommand", "program", "code", "options", "projectPath", "log", "pc", "spinner", "detection", "detectProjectSetup", "logError", "localeOptions", "promptForLocaleDetails", "translationFile", "path", "fileExists", "generateLocale", "error", "path", "pc", "init_detection", "Enquirer", "prompt", "promptForPageDetails", "name", "presets", "questions", "value", "answers", "registerPageCommand", "program", "name", "options", "projectPath", "log", "pc", "spinner", "detection", "detectProjectSetup", "pageOptions", "promptForPageDetails", "pageName", "componentName", "kebabToPascal", "baseDir", "directoryExists", "logError", "generatePage", "routePath", "registerAppPath", "addTranslationNamespace", "displayPath", "path", "error", "path", "pc", "registerProviderCommand", "program", "name", "projectPath", "log", "pc", "spinner", "componentName", "fileBaseName", "providerFile", "generateProvider", "rootProviderFile", "barrelFile", "registerProvider", "path", "error", "logError", "Enquirer", "pc", "prompt", "Enquirer", "formatSummary", "summary", "lines", "file", "pc", "block", "script", "dep", "item", "isEmpty", "s", "registerRemoveCommand", "program", "feature", "options", "projectPath", "manifest", "getManifest", "MANIFESTS", "m", "log", "checkManifest", "spinner", "planned", "reverseManifest", "line", "confirm", "applied", "error", "logError", "existsSync", "mkdir", "path", "pc", "init_detection", "readFile", "writeFile", "path", "registerCrudApiEndpoints", "projectPath", "serviceName", "camelName", "kebabToCamel", "apiConfigPath", "path", "content", "readFile", "newEndpoint", "crudApiConfigTemplate", "addToAppApis", "writeFile", "error", "enquirer", "promptForServiceDetails", "name", "axiosFlag", "fetchFlag", "availableClients", "serviceName", "input", "httpClient", "registerServiceCommand", "program", "name", "options", "projectPath", "logError", "log", "pc", "spinner", "detection", "detectProjectSetup", "availableClients", "serviceOptions", "promptForServiceDetails", "basePath", "servicePath", "resolveServicePaths", "existsSync", "mkdir", "fileExistsAt", "generateCrudService", "registerCrudApiEndpoints", "executePipeline", "createServicePipelineSteps", "printServiceSuccess", "error", "serviceName", "customPath", "cleanPath", "featureName", "path", "isCrud", "displayPath", "importPath", "Enquirer", "pc", "prompt", "Enquirer", "registerSetupCommand", "program", "options", "log", "pc", "setupHttpClient", "setupDarkTheme", "setupRedux", "setupI18n", "setupTests", "setupReactCompiler", "setupBundleAnalyzer", "setupSecurityHeaders", "setupValidationScripts", "setupCommitizen", "feature", "handler", "error", "spinner", "logError", "existsSync", "mkdir", "path", "pc", "init_detection", "Enquirer", "prompt", "promptForSliceDetails", "sliceName", "persist", "noPersist", "questions", "value", "answers", "registerSliceCommand", "program", "name", "options", "projectPath", "logError", "log", "pc", "spinner", "detection", "detectProjectSetup", "sliceOptions", "promptForSliceDetails", "basePath", "slicePath", "resolveSlicePaths", "featureStorePath", "path", "existsSync", "mkdir", "directoryExists", "executePipeline", "createSlicePipelineSteps", "testFile", "resolveShouldTest", "sliceFile", "generateTest", "kebabToCamel", "printSliceSuccess", "error", "sliceName", "customPath", "cleanPath", "featureName", "hasTests", "displayPath", "importPath", "path", "pc", "init_files", "init_detection", "registerTestCommand", "program", "file", "options", "projectPath", "sourceFile", "path", "log", "pc", "fileExists", "logError", "detection", "detectProjectSetup", "content", "readFile", "kind", "validateKind", "inferKind", "symbolName", "inferSymbolName", "testPath", "getTestPath", "spinner", "written", "generateTest", "error", "input", "base", "kebabToCamel", "kebabToPascal", "dir", "ext", "registerCommands", "program", "registerAppCommand", "registerSetupCommand", "registerFeatureCommand", "registerSliceCommand", "registerServiceCommand", "registerPageCommand", "registerLayoutCommand", "registerComponentCommand", "registerLocaleCommand", "registerHookCommand", "registerProviderCommand", "registerEnvCommand", "registerFaviconCommand", "registerDoctorCommand", "registerRemoveCommand", "registerTestCommand", "originalEmitWarning", "warning", "_type", "_code", "_ctor", "main", "setupCancellationHandlers", "m", "error", "program", "Command", "registerCommands", "err", "message"]
|
|
4
|
+
"sourcesContent": ["import { existsSync } from 'node:fs';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\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 POSTCSS_CONFIG: 'postcss.config.mjs',\n BIOME_CONFIG: 'biome.json',\n VITEST_CONFIG: 'vitest.config.ts',\n TEST_DIR: 'test',\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 AGENTS_MD: 'AGENTS.md',\n CLAUDE_MD: 'CLAUDE.md',\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 HTTP_SHARED: 'src/lib/utils/http/shared',\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 API_URL_FILE: 'src/lib/config/api-url.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\n // Template-specific (should be cleaned on init)\n SCRIPTS_DIR: 'scripts',\n DOCS_DIR: 'docs',\n CLAUDE_DIR: '.claude',\n VSCODE_DIR: '.vscode',\n} as const;\n", "import { exec } from 'node:child_process';\nimport path from 'node:path';\nimport { promisify } from 'node:util';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { fileExists, readFile, writeFile } from '../../../core/files';\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 { existsSync } from 'node:fs';\nimport { access } from 'node:fs/promises';\nimport path from 'node:path';\n\n/**\n * Check if a directory exists at projectPath/basePath/name.\n */\nexport const directoryExists = async (\n projectPath: string,\n name: string,\n basePath: string,\n): Promise<boolean> => {\n try {\n await access(path.join(projectPath, basePath, name));\n return true;\n } catch {\n return false;\n }\n};\n\n/**\n * Check if a specific file exists at projectPath/basePath/fileName.\n */\nexport const fileExistsAt = (projectPath: string, basePath: string, fileName: string): boolean => {\n return existsSync(path.join(projectPath, basePath, fileName));\n};\n", "import { access, readFile } 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 hasTests: boolean;\n}\n\nexport const detectProjectSetup = async (projectPath: string): Promise<ProjectDetection> => {\n try {\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 const hasRedux = !!(dependencies['@reduxjs/toolkit'] && dependencies['react-redux']);\n const hasI18n = !!dependencies['next-intl'];\n\n // Check for HTTP clients: must be both in dependencies AND have client directory\n let hasAxios = !!dependencies.axios;\n let hasFetch = false;\n\n const axiosClientPath = path.join(projectPath, 'src', 'lib', 'utils', 'http', 'axios-client');\n try {\n await access(axiosClientPath);\n } catch {\n hasAxios = false;\n }\n\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;\n }\n\n let httpClient: ProjectDetection['httpClient'];\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 let hasTests = !!dependencies.vitest;\n if (!hasTests) {\n try {\n await access(path.join(projectPath, 'vitest.config.ts'));\n hasTests = true;\n } catch {\n /* no vitest config */\n }\n }\n\n return { hasRedux, httpClient, hasI18n, hasTests };\n } catch (error) {\n throw new Error(`Failed to detect project setup: ${error}`, { cause: error });\n }\n};\n", "export { directoryExists, fileExistsAt } from './existence.checker';\nexport type { ProjectDetection } from './project.detector';\nexport { detectProjectSetup } from './project.detector';\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 path from 'node:path';\nimport type { Command } from 'commander';\nimport type { Ora } from 'ora';\nimport pc from 'picocolors';\nimport { log, logError, printBanner } from '../config';\nimport { startSpinner } from '../config/spinner';\nimport { deleteDirectory, fileExists } from '../core/files';\nimport { initializeGit } from '../core/git';\nimport { installDependencies, type PackageManager, runScript } from '../core/package-manager';\nimport {\n defaultProjectAnswers,\n type ProjectPrompts,\n promptForProjectDetails,\n} from '../prompts/create-app.prompt';\nimport { cleanupFeatures } from '../services/init/cleanup';\nimport { configurePackageJson } from '../services/init/config.service';\nimport { setupDevTools } from '../services/init/devtools.service';\nimport { generateLayout, generateRootProvider } from '../services/init/providers.service';\nimport { cloneTemplate } from '../services/init/template.service';\n\ninterface InitCommandOptions {\n yes?: boolean;\n packageManager?: string;\n}\n\nconst VALID_PACKAGE_MANAGERS: ReadonlyArray<PackageManager> = ['npm', 'yarn', 'pnpm', 'bun'];\n\nconst validatePackageManagerOverride = (raw: string | undefined): PackageManager | undefined => {\n if (raw === undefined) return undefined;\n if (!VALID_PACKAGE_MANAGERS.includes(raw as PackageManager)) {\n throw new Error(\n `Invalid --package-manager \"${raw}\". Valid: ${VALID_PACKAGE_MANAGERS.join(', ')}.`,\n );\n }\n return raw as PackageManager;\n};\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 .option('-y, --yes', 'Skip all prompts and use the recommended production defaults')\n .option(\n '--package-manager <pm>',\n `Override the package manager (one of: ${VALID_PACKAGE_MANAGERS.join(', ')})`,\n )\n .action(async (name: string | undefined, options: InitCommandOptions) => {\n try {\n const packageManager = validatePackageManagerOverride(options.packageManager);\n await createApp(name, { yes: options.yes ?? false, packageManager });\n } catch (err) {\n logError(`${err instanceof Error ? err.message : err}`);\n process.exit(1);\n }\n });\n};\n\n/**\n * Run a step with a dedicated spinner, ensuring at most one is active at a\n * time. Sub-services that manage their own spinners must be called\n * *outside* this helper \u2014 wrapping them would create concurrent spinners\n * (ora 9.4+ surfaces this as a runtime warning).\n */\nconst withStepSpinner = async <T>(\n text: string,\n successText: string,\n fn: () => Promise<T>,\n ref: { current: Ora | null },\n): Promise<T> => {\n const spinner = startSpinner(text);\n ref.current = spinner;\n try {\n const result = await fn();\n spinner.succeed(successText);\n return result;\n } finally {\n if (ref.current === spinner) ref.current = null;\n }\n};\n\ninterface CreateAppFlags {\n yes: boolean;\n packageManager?: PackageManager;\n}\n\nconst summariseDefaults = (answers: ProjectPrompts): void => {\n const features: string[] = [];\n if (answers.darkMode) features.push('dark mode');\n if (answers.redux) features.push('redux');\n if (answers.i18n) features.push('i18n');\n if (answers.tests) features.push('tests');\n if (answers.reactCompiler) features.push('react-compiler');\n if (answers.preCommitHooks) features.push('pre-commit hooks');\n if (answers.commitizen) features.push('commitizen');\n if (answers.httpClient !== 'none') features.push(`http (${answers.httpClient})`);\n\n log(pc.dim('Defaults applied (run `next-maker remove <feature>` to undo any of them):'));\n log(pc.dim(` package manager : ${answers.packageManager}`));\n log(pc.dim(` features : ${features.join(', ')}`));\n log('');\n};\n\nconst createApp = async (initialName: string | undefined, flags: CreateAppFlags): Promise<void> => {\n printBanner();\n\n let answers: ProjectPrompts;\n if (flags.yes) {\n answers = defaultProjectAnswers(initialName, {\n packageManager: flags.packageManager,\n });\n log(pc.cyan(`\u2728 Bootstrapping ${answers.projectName} with the recommended defaults`));\n log('');\n summariseDefaults(answers);\n } else {\n log('Welcome to the Teispace Next.js App Creator!');\n log('');\n answers = await promptForProjectDetails(initialName);\n if (flags.packageManager) {\n answers = { ...answers, packageManager: flags.packageManager };\n }\n }\n\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 // Tracks the *currently* active spinner (if any) so signal/cleanup can\n // halt it cleanly. Only one of our spinners is alive at a time.\n const active: { current: Ora | null } = { current: null };\n\n const performCleanup = async () => {\n if (fileExists(projectPath)) {\n active.current?.stop();\n active.current = null;\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 const handleSignal = async () => {\n console.log(pc.red('\\nProcess interrupted. Cleaning up...'));\n await performCleanup();\n process.exit(1);\n };\n\n process.on('SIGINT', handleSignal);\n process.on('SIGTERM', handleSignal);\n\n try {\n // 1\u20133. Each of these owns its own spinner; do not wrap them.\n await cloneTemplate(projectPath);\n await configurePackageJson(projectPath, answers);\n await cleanupFeatures(projectPath, answers);\n\n // 4. Providers + layout \u2014 silent under one outer spinner.\n await withStepSpinner(\n 'Generating providers and layout...',\n 'Providers and layout generated.',\n async () => {\n await generateRootProvider(projectPath, answers);\n await generateLayout(projectPath, answers);\n },\n active,\n );\n\n // 5. DevTools (community files, Docker, hooks, etc.) \u2014 no inner spinners.\n await withStepSpinner(\n 'Setting up developer tools...',\n 'Developer tools configured.',\n () => setupDevTools(projectPath, answers),\n active,\n );\n\n // 6. Git\n await withStepSpinner(\n 'Initializing Git...',\n 'Git initialized.',\n () => initializeGit(projectPath, answers.gitRemote, answers.pushToRemote),\n active,\n );\n\n // 7. Install\n await withStepSpinner(\n 'Installing dependencies...',\n 'Dependencies installed.',\n () => installDependencies(projectPath, answers.packageManager),\n active,\n );\n\n // 8. Format + Lint (biome check --write does both)\n await withStepSpinner(\n 'Formatting and linting...',\n 'Formatted.',\n () => runScript(projectPath, answers.packageManager, 'lint:fix'),\n active,\n );\n\n // 9. Copy .env.example \u2192 .env (cheap, no spinner needed)\n if (answers.copyEnv) {\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 process.off('SIGINT', handleSignal);\n process.off('SIGTERM', handleSignal);\n\n log('');\n log(pc.green(`\u2728 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 active.current?.fail('Failed to create project.');\n active.current = null;\n console.error(err);\n await performCleanup();\n process.exit(1);\n }\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", "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", "import ora, { type Options, type Ora } 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", "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 './errorHandlers';\nexport * from './output';\nexport * from './spinner';\nexport * from './utils';\n\n// Re-export spinner instance\nimport ora from 'ora';\nexport const spinner = ora();\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}`, { cause: 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}`, { cause: 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\nconst getDevFlag = (manager: PackageManager): string => {\n switch (manager) {\n case 'npm':\n return '--save-dev';\n case 'yarn':\n case 'pnpm':\n case 'bun':\n return '-D';\n default:\n return '--save-dev';\n }\n};\n\nexport const installDevPackages = async (\n cwd: string,\n manager: PackageManager,\n packages: string[],\n): Promise<void> => {\n if (packages.length === 0) return;\n const installCommand = getInstallCommand(manager);\n const flag = getDevFlag(manager);\n const command = `${installCommand} ${flag} ${packages.join(' ')}`;\n try {\n await execAsync(command, { cwd });\n } catch (error) {\n throw new Error(`Failed to install dev packages with ${manager}: ${error}`, { cause: error });\n }\n};\n\nexport const installDevPackage = async (cwd: string, packageName: string): Promise<void> => {\n const manager = await detectPackageManager(cwd);\n await installDevPackages(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}`, { cause: 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 Enquirer from 'enquirer';\nimport type { PackageManager } from '../core/package-manager';\n\nconst PROJECT_NAME_RE = /^[a-z0-9-_]+$/;\nconst SEMVER_RE = /^\\d+\\.\\d+\\.\\d+$/;\n\nconst isValidProjectName = (value: string): boolean => PROJECT_NAME_RE.test(value);\nconst isValidSemver = (value: string): boolean => SEMVER_RE.test(value);\n\n/**\n * The opinionated production defaults `init --yes` ships. Mirrors the\n * \"should I include X?\" answer the prompt walkthrough would suggest as\n * `initial`/`default` for each question \u2014 every architecture feature ON,\n * the heavyweight integrations (Docker, GitHub Actions, bundle analyzer)\n * OFF. Users who want a leaner install run `next-maker remove <feature>`\n * after init.\n */\nexport const defaultProjectAnswers = (\n initialName: string | undefined,\n overrides: Partial<ProjectPrompts> = {},\n): ProjectPrompts => {\n const projectName = overrides.projectName ?? initialName ?? 'my-app';\n if (!isValidProjectName(projectName)) {\n throw new Error(\n `Invalid project name \"${projectName}\". Use lowercase letters, digits, hyphens, and underscores only.`,\n );\n }\n const version = overrides.version ?? '0.1.0';\n if (!isValidSemver(version)) {\n throw new Error(`Invalid version \"${version}\". Expected semver (e.g. 0.1.0).`);\n }\n\n const author = overrides.author ?? 'Teispace';\n const company = overrides.company ?? author;\n\n return {\n projectName,\n description: overrides.description ?? 'A Next.js application',\n author,\n version,\n packageManager: overrides.packageManager ?? 'yarn',\n gitRemote: overrides.gitRemote ?? '',\n pushToRemote: overrides.pushToRemote ?? false,\n gitIssues: overrides.gitIssues ?? '',\n gitHomepage: overrides.gitHomepage ?? '',\n httpClient: overrides.httpClient ?? 'fetch',\n reactSecureStorage: overrides.reactSecureStorage ?? true,\n email: overrides.email ?? 'support@example.com',\n company,\n keepTemplates: overrides.keepTemplates ?? false,\n darkMode: overrides.darkMode ?? true,\n redux: overrides.redux ?? true,\n i18n: overrides.i18n ?? true,\n communityFiles: overrides.communityFiles ?? [],\n readme: overrides.readme ?? true,\n docker: overrides.docker ?? false,\n containerName: overrides.containerName,\n imageName: overrides.imageName,\n imageTag: overrides.imageTag,\n ci: overrides.ci ?? false,\n preCommitHooks: overrides.preCommitHooks ?? true,\n commitizen: overrides.commitizen ?? true,\n copyEnv: overrides.copyEnv ?? true,\n tests: overrides.tests ?? true,\n reactCompiler: overrides.reactCompiler ?? true,\n bundleAnalyzer: overrides.bundleAnalyzer ?? false,\n };\n};\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 tests: boolean;\n reactCompiler: boolean;\n bundleAnalyzer: 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 + @teispace/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: 'confirm',\n name: 'tests',\n message: 'Do you want to include testing setup (Vitest + React Testing Library)?',\n initial: true,\n },\n {\n type: 'confirm',\n name: 'reactCompiler',\n message: 'Do you want to enable the React Compiler?',\n initial: true,\n },\n {\n type: 'confirm',\n name: 'bundleAnalyzer',\n message: 'Do you want to include @next/bundle-analyzer?',\n initial: false,\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 path from 'node:path';\nimport { writeFile } from '../../core/files';\n\nexport type TestUtilsFeatures = {\n redux: boolean;\n i18n: boolean;\n};\n\n/**\n * Emit `test/test-utils.tsx` tailored to the currently-enabled features.\n * Selected between four pre-baked variants so the output stays readable and\n * the cross-feature edge cases (redux-only / i18n-only / neither) produce\n * a file that actually type-checks.\n */\nexport const writeTestUtils = async (\n projectPath: string,\n features: TestUtilsFeatures,\n): Promise<void> => {\n const content = pickTemplate(features);\n await writeFile(path.join(projectPath, 'test/test-utils.tsx'), content);\n};\n\nconst pickTemplate = ({ redux, i18n }: TestUtilsFeatures): string => {\n if (redux && i18n) return BOTH;\n if (redux) return REDUX_ONLY;\n if (i18n) return I18N_ONLY;\n return MINIMAL;\n};\n\nconst BOTH = `import { type RenderOptions, render } from '@testing-library/react';\nimport { NextIntlClientProvider } from 'next-intl';\nimport type { ReactElement, ReactNode } from 'react';\nimport { Provider } from 'react-redux';\nimport { type AppState, type AppStore, makeStore } from '@/store';\nimport type { SupportedLocale } from '@/types/i18n';\n\ntype TestProvidersProps = {\n children: ReactNode;\n store?: AppStore;\n preloadedState?: Partial<AppState>;\n messages?: Record<string, unknown>;\n locale?: SupportedLocale;\n};\n\nexport function TestProviders({\n children,\n store,\n preloadedState,\n messages = {},\n locale = 'en',\n}: TestProvidersProps) {\n const testStore = store ?? makeStore(preloadedState);\n\n return (\n <Provider store={testStore}>\n <NextIntlClientProvider locale={locale} messages={messages} timeZone=\"UTC\">\n {children}\n </NextIntlClientProvider>\n </Provider>\n );\n}\n\ntype ExtendedRenderOptions = Omit<RenderOptions, 'wrapper'> & {\n store?: AppStore;\n preloadedState?: Partial<AppState>;\n messages?: Record<string, unknown>;\n locale?: SupportedLocale;\n};\n\nexport function renderWithProviders(\n ui: ReactElement,\n { store, preloadedState, messages, locale, ...renderOptions }: ExtendedRenderOptions = {},\n) {\n const testStore = store ?? makeStore(preloadedState);\n\n return {\n store: testStore,\n ...render(ui, {\n wrapper: ({ children }) => (\n <TestProviders store={testStore} messages={messages} locale={locale}>\n {children}\n </TestProviders>\n ),\n ...renderOptions,\n }),\n };\n}\n\nexport * from '@testing-library/react';\nexport { default as userEvent } from '@testing-library/user-event';\n`;\n\nconst REDUX_ONLY = `import { type RenderOptions, render } from '@testing-library/react';\nimport type { ReactElement, ReactNode } from 'react';\nimport { Provider } from 'react-redux';\nimport { type AppState, type AppStore, makeStore } from '@/store';\n\ntype TestProvidersProps = {\n children: ReactNode;\n store?: AppStore;\n preloadedState?: Partial<AppState>;\n};\n\nexport function TestProviders({ children, store, preloadedState }: TestProvidersProps) {\n const testStore = store ?? makeStore(preloadedState);\n\n return <Provider store={testStore}>{children}</Provider>;\n}\n\ntype ExtendedRenderOptions = Omit<RenderOptions, 'wrapper'> & {\n store?: AppStore;\n preloadedState?: Partial<AppState>;\n};\n\nexport function renderWithProviders(\n ui: ReactElement,\n { store, preloadedState, ...renderOptions }: ExtendedRenderOptions = {},\n) {\n const testStore = store ?? makeStore(preloadedState);\n\n return {\n store: testStore,\n ...render(ui, {\n wrapper: ({ children }) => <TestProviders store={testStore}>{children}</TestProviders>,\n ...renderOptions,\n }),\n };\n}\n\nexport * from '@testing-library/react';\nexport { default as userEvent } from '@testing-library/user-event';\n`;\n\nconst I18N_ONLY = `import { type RenderOptions, render } from '@testing-library/react';\nimport { NextIntlClientProvider } from 'next-intl';\nimport type { ReactElement, ReactNode } from 'react';\nimport type { SupportedLocale } from '@/types/i18n';\n\ntype TestProvidersProps = {\n children: ReactNode;\n messages?: Record<string, unknown>;\n locale?: SupportedLocale;\n};\n\nexport function TestProviders({ children, messages = {}, locale = 'en' }: TestProvidersProps) {\n return (\n <NextIntlClientProvider locale={locale} messages={messages} timeZone=\"UTC\">\n {children}\n </NextIntlClientProvider>\n );\n}\n\ntype ExtendedRenderOptions = Omit<RenderOptions, 'wrapper'> & {\n messages?: Record<string, unknown>;\n locale?: SupportedLocale;\n};\n\nexport function renderWithProviders(\n ui: ReactElement,\n { messages, locale, ...renderOptions }: ExtendedRenderOptions = {},\n) {\n return render(ui, {\n wrapper: ({ children }) => (\n <TestProviders messages={messages} locale={locale}>\n {children}\n </TestProviders>\n ),\n ...renderOptions,\n });\n}\n\nexport * from '@testing-library/react';\nexport { default as userEvent } from '@testing-library/user-event';\n`;\n\nconst MINIMAL = `import { type RenderOptions, render } from '@testing-library/react';\nimport type { ReactElement, ReactNode } from 'react';\n\ntype TestProvidersProps = {\n children: ReactNode;\n};\n\nexport function TestProviders({ children }: TestProvidersProps) {\n return <>{children}</>;\n}\n\ntype ExtendedRenderOptions = Omit<RenderOptions, 'wrapper'>;\n\nexport function renderWithProviders(ui: ReactElement, options: ExtendedRenderOptions = {}) {\n return render(ui, {\n wrapper: ({ children }) => <TestProviders>{children}</TestProviders>,\n ...options,\n });\n}\n\nexport * from '@testing-library/react';\nexport { default as userEvent } from '@testing-library/user-event';\n`;\n", "import path from 'node:path';\nimport { PACKAGES } from '../../../config/packages';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { fileExists, readFile, updateJson, writeFile } from '../../../core/files';\nimport type { ProjectPrompts } from '../../../prompts/create-app.prompt';\n\nexport const cleanupBundleAnalyzer = async (\n projectPath: string,\n answers: ProjectPrompts,\n): Promise<void> => {\n if (answers.bundleAnalyzer) return;\n\n const nextConfigPath = path.join(projectPath, PROJECT_PATHS.NEXT_CONFIG);\n if (fileExists(nextConfigPath)) {\n let content = await readFile(nextConfigPath);\n content = content.replace(\n /import\\s+withBundleAnalyzer\\s+from\\s+'@next\\/bundle-analyzer';\\n/,\n '',\n );\n content = content.replace(\n /const\\s+bundleAnalyzer\\s*=\\s*withBundleAnalyzer\\(\\{[\\s\\S]*?\\}\\);\\n+/,\n '',\n );\n // Unwrap any `bundleAnalyzer(...)` call inside `export default`.\n content = content.replace(/bundleAnalyzer\\(([^)]*)\\)/, '$1');\n await writeFile(nextConfigPath, content);\n }\n\n await updateJson(path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON), (pkg) => {\n if (pkg.devDependencies) {\n delete pkg.devDependencies[PACKAGES.NEXT_BUNDLE_ANALYZER];\n }\n if (pkg.scripts) {\n delete pkg.scripts.analyze;\n }\n return pkg;\n });\n};\n", "export const PACKAGES = {\n // Dependencies\n REDUX_TOOLKIT: '@reduxjs/toolkit',\n REACT_REDUX: 'react-redux',\n REDUX: 'redux',\n REDUX_PERSIST: 'redux-persist',\n REACT_SECURE_STORAGE: 'react-secure-storage',\n NEXT_INTL: 'next-intl',\n NEXT_THEMES: '@teispace/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\n // Testing\n VITEST: 'vitest',\n JSDOM: 'jsdom',\n VITE_PLUGIN_REACT: '@vitejs/plugin-react',\n TESTING_LIBRARY_DOM: '@testing-library/dom',\n TESTING_LIBRARY_JEST_DOM: '@testing-library/jest-dom',\n TESTING_LIBRARY_REACT: '@testing-library/react',\n TESTING_LIBRARY_USER_EVENT: '@testing-library/user-event',\n\n // Optional tooling\n REACT_COMPILER_BABEL: 'babel-plugin-react-compiler',\n NEXT_BUNDLE_ANALYZER: '@next/bundle-analyzer',\n} as const;\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { deleteFile, fileExists, readFile, writeFile } from '../../../core/files';\nimport type { ProjectPrompts } from '../../../prompts/create-app.prompt';\n\nexport const cleanupDarkMode = async (\n projectPath: string,\n answers: ProjectPrompts,\n): Promise<void> => {\n if (answers.darkMode) return;\n\n await deleteFile(path.join(projectPath, PROJECT_PATHS.THEME_PROVIDER));\n await removeThemeProviderExport(projectPath);\n await removeDarkModeCSS(projectPath);\n // Strip dark-mode classes from whichever layout is present. generateLayout\n // overwrites src/app/layout.tsx when i18n is off, so we focus on [locale]/layout.tsx\n // but handle both for robustness.\n await removeDarkModeFromLayout(projectPath);\n};\n\nconst removeThemeProviderExport = async (projectPath: string): Promise<void> => {\n const providersIndexPath = path.join(projectPath, PROJECT_PATHS.PROVIDERS_INDEX);\n let content = await readFile(providersIndexPath);\n content = content.replace(/export \\* from '\\.\\/CustomThemeProvider';\\n/, '');\n await writeFile(providersIndexPath, content);\n};\n\nconst removeDarkModeCSS = async (projectPath: string): Promise<void> => {\n const globalsCssPath = path.join(projectPath, PROJECT_PATHS.GLOBALS_CSS);\n if (fileExists(globalsCssPath)) {\n let content = await readFile(globalsCssPath);\n content = content.replace(/@custom-variant dark \\(.*?\\);\\n\\n/, '');\n content = content.replace(/@theme \\{[\\s\\S]*?\\}\\n/, '');\n await writeFile(globalsCssPath, content);\n }\n};\n\nconst stripDarkModeClasses = (content: string): string => {\n // Template layouts use \"bg-light antialiased dark:bg-dark\" in various orderings.\n // Drop the bg-light and dark:bg-dark tokens and collapse stray whitespace.\n return content\n .replace(/\\bbg-light\\b\\s?/g, '')\n .replace(/\\bdark:bg-dark\\b\\s?/g, '')\n .replace(/\\s{2,}/g, ' ')\n .replace(/suppressHydrationWarning=\\{true\\}/g, '');\n};\n\nconst removeDarkModeFromLayout = async (projectPath: string): Promise<void> => {\n const layoutPaths = [\n path.join(projectPath, PROJECT_PATHS.ROOT_LAYOUT),\n path.join(projectPath, 'src/app/[locale]/layout.tsx'),\n ];\n\n for (const layoutPath of layoutPaths) {\n if (fileExists(layoutPath)) {\n const original = await readFile(layoutPath);\n const updated = stripDarkModeClasses(original);\n if (updated !== original) {\n await writeFile(layoutPath, updated);\n }\n }\n }\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { deleteDirectory, deleteFile, fileExists, readFile, writeFile } from '../../../core/files';\nimport type { ProjectPrompts } from '../../../prompts/create-app.prompt';\nimport { cleanupHttpTypes } from '../../setup/http-client/injectors';\n\nexport const cleanupHttpClient = async (\n projectPath: string,\n answers: ProjectPrompts,\n): 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 cleanupNoHttpClient(projectPath, httpUtilsPath, keepSecureStorage);\n } else if (answers.httpClient === 'axios') {\n await cleanupFetchClient(projectPath, httpUtilsPath);\n } else if (answers.httpClient === 'fetch') {\n await cleanupAxiosClient(projectPath, httpUtilsPath);\n }\n};\n\nconst cleanupNoHttpClient = async (\n projectPath: string,\n httpUtilsPath: string,\n keepSecureStorage: boolean,\n): Promise<void> => {\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 await deleteFile(path.join(projectPath, PROJECT_PATHS.CLIENT_UTILS));\n await cleanupHttpTypes(projectPath, []);\n } else {\n await deleteDirectory(httpUtilsPath);\n await removeHttpExports(projectPath);\n await deleteFile(path.join(projectPath, PROJECT_PATHS.APP_APIS));\n await removeAppApisExport(projectPath);\n }\n\n await removeApiConstants(projectPath);\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.ERRORS_DIR));\n\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 await removeTypesExports(projectPath);\n }\n};\n\nconst cleanupFetchClient = async (projectPath: string, httpUtilsPath: string): Promise<void> => {\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 const httpTypesPath = path.join(projectPath, PROJECT_PATHS.HTTP_TYPES);\n if (fileExists(httpTypesPath)) {\n let typesContent = await readFile(httpTypesPath);\n typesContent = typesContent.replace(/export interface FetchClientOptions \\{[\\s\\S]*?\\}\\n\\n/, '');\n typesContent = typesContent.replace(\n /export interface ExtendedRequestInit extends RequestInit \\{[\\s\\S]*?\\}\\n\\n/,\n '',\n );\n await writeFile(httpTypesPath, typesContent);\n }\n};\n\nconst cleanupAxiosClient = async (projectPath: string, httpUtilsPath: string): Promise<void> => {\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 await cleanupHttpTypes(projectPath, ['fetch']);\n\n const httpTypesPath = path.join(projectPath, PROJECT_PATHS.HTTP_TYPES);\n if (fileExists(httpTypesPath)) {\n let typesContent = await readFile(httpTypesPath);\n typesContent = typesContent.replace(/export interface AxiosClientOptions \\{[\\s\\S]*?\\}\\n\\n/, '');\n await writeFile(httpTypesPath, typesContent);\n }\n};\n\nconst removeHttpExports = 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 content = content.replace(/export \\* from '\\.\\/http';\\n/, '');\n await writeFile(utilsIndexPath, content);\n }\n};\n\nconst removeAppApisExport = 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 content = content.replace(/export \\* from '\\.\\/app-apis';\\n/, '');\n await writeFile(configIndexPath, content);\n }\n};\n\nconst removeApiConstants = async (projectPath: string): Promise<void> => {\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\nconst removeTypesExports = 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 content = content.replace(/export \\* from '\\.\\/utility';\\n/, '');\n content = content.replace(/export \\* from '\\.\\/common';\\n/, '');\n await writeFile(typesIndexPath, content);\n }\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { deleteDirectory, deleteFile, fileExists, readFile, writeFile } from '../../../core/files';\nimport type { ProjectPrompts } from '../../../prompts/create-app.prompt';\n\nexport const cleanupI18n = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n if (answers.i18n) return;\n\n await deleteI18nFiles(projectPath);\n await removeI18nExports(projectPath);\n await removeI18nFromNextConfig(projectPath);\n await removeI18nFromCounter(projectPath);\n await removeI18nFromEnv(projectPath);\n};\n\nconst removeI18nFromEnv = async (projectPath: string): Promise<void> => {\n const envPath = path.join(projectPath, PROJECT_PATHS.ENV_EXAMPLE);\n if (!fileExists(envPath)) return;\n let content = await readFile(envPath);\n // Strip the DEFAULT_TIMEZONE/DEFAULT_LOCALE blocks (incl. their comment headers).\n content = content.replace(/#[^\\n]*IANA time zone[\\s\\S]*?DEFAULT_TIMEZONE=[^\\n]*\\n?/, '');\n content = content.replace(/#[^\\n]*Fallback locale[\\s\\S]*?DEFAULT_LOCALE=[^\\n]*\\n?/, '');\n // Fallback cleanup if the comments changed/were removed.\n content = content.replace(/^DEFAULT_TIMEZONE=.*\\n?/m, '');\n content = content.replace(/^DEFAULT_LOCALE=.*\\n?/m, '');\n await writeFile(envPath, content);\n};\n\nconst deleteI18nFiles = async (projectPath: string): Promise<void> => {\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\nconst removeI18nExports = 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 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\nconst removeI18nFromNextConfig = 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 content = content.replace(/import createNextIntlPlugin from 'next-intl\\/plugin';\\n/, '');\n content = content.replace(/const withNextIntl = createNextIntlPlugin\\(\\);\\n+/, '');\n // Unwrap withNextIntl(...) wherever it appears \u2014 the arg may itself be\n // a call like bundleAnalyzer(...) depending on enabled features.\n content = content.replace(/withNextIntl\\(([^)]+)\\)/, '$1');\n await writeFile(nextConfigPath, content);\n }\n};\n\nconst removeI18nFromCounter = async (projectPath: string): Promise<void> => {\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(\n /\\{t\\('currentCount',\\s*\\{\\s*count:\\s*value\\s*\\}\\)\\}/g,\n 'Current Count: {value}',\n );\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 // Counter.test.tsx and test-utils.tsx both depend on i18n \u2014 delete them\n // to avoid dangling references. Users can re-introduce tests later.\n const counterTestPath = path.join(\n projectPath,\n 'src/features/counter/components/Counter.test.tsx',\n );\n const testUtilsPath = path.join(projectPath, 'test/test-utils.tsx');\n await deleteFile(counterTestPath);\n await deleteFile(testUtilsPath);\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { deleteDirectory, deleteFile } from '../../../core/files';\nimport type { ProjectPrompts } from '../../../prompts/create-app.prompt';\n\nexport const 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\nexport const cleanupLicense = async (projectPath: string): Promise<void> => {\n await deleteFile(path.join(projectPath, PROJECT_PATHS.LICENSE));\n};\n\nexport const cleanupChangelog = async (projectPath: string): Promise<void> => {\n await deleteFile(path.join(projectPath, PROJECT_PATHS.CHANGELOG));\n};\n\nexport const 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\n/**\n * Remove template-specific directories that should not ship in generated projects.\n * - .claude/ \u2014 Claude Code workspace config from the starter template\n * - docs/ \u2014 Starter template documentation (structure.md etc.)\n * - .vscode/ \u2014 IDE-specific settings from the starter\n */\nexport const cleanupTemplateArtifacts = async (projectPath: string): Promise<void> => {\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.CLAUDE_DIR));\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.DOCS_DIR));\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.VSCODE_DIR));\n};\n", "import path from 'node:path';\nimport { PACKAGES } from '../../../config/packages';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { fileExists, readFile, updateJson, writeFile } from '../../../core/files';\nimport type { ProjectPrompts } from '../../../prompts/create-app.prompt';\n\nexport const cleanupReactCompiler = async (\n projectPath: string,\n answers: ProjectPrompts,\n): Promise<void> => {\n if (answers.reactCompiler) return;\n\n const nextConfigPath = path.join(projectPath, PROJECT_PATHS.NEXT_CONFIG);\n if (fileExists(nextConfigPath)) {\n let content = await readFile(nextConfigPath);\n content = content.replace(/^\\s*reactCompiler:\\s*true,?\\n/m, '');\n await writeFile(nextConfigPath, content);\n }\n\n await updateJson(path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON), (pkg) => {\n if (pkg.devDependencies) {\n delete pkg.devDependencies[PACKAGES.REACT_COMPILER_BABEL];\n }\n return pkg;\n });\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { deleteDirectory, deleteFile, fileExists, readFile, writeFile } from '../../../core/files';\nimport type { ProjectPrompts } from '../../../prompts/create-app.prompt';\n\nexport const cleanupRedux = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n if (answers.redux) return;\n\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 // test-utils.tsx imports @/store \u2014 drop it so the template still builds.\n await deleteFile(path.join(projectPath, 'test/test-utils.tsx'));\n\n await removeStoreProviderExport(projectPath);\n await removeCounterFromPages(projectPath);\n};\n\nconst removeStoreProviderExport = async (projectPath: string): Promise<void> => {\n const providersIndexPath = path.join(projectPath, PROJECT_PATHS.PROVIDERS_INDEX);\n let content = await readFile(providersIndexPath);\n content = content.replace(/export \\* from '\\.\\/StoreProvider';\\n/, '');\n await writeFile(providersIndexPath, content);\n};\n\nconst removeCounterFromPages = async (projectPath: string): Promise<void> => {\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", "import path from 'node:path';\nimport { PACKAGES } from '../../../config/packages';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { deleteDirectory, deleteFile, updateJson } from '../../../core/files';\nimport type { ProjectPrompts } from '../../../prompts/create-app.prompt';\n\nconst TEST_DEVDEPS = [\n PACKAGES.VITEST,\n PACKAGES.JSDOM,\n PACKAGES.VITE_PLUGIN_REACT,\n PACKAGES.TESTING_LIBRARY_DOM,\n PACKAGES.TESTING_LIBRARY_JEST_DOM,\n PACKAGES.TESTING_LIBRARY_REACT,\n PACKAGES.TESTING_LIBRARY_USER_EVENT,\n];\n\nexport const cleanupTests = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n if (answers.tests) return;\n\n await deleteFile(path.join(projectPath, PROJECT_PATHS.VITEST_CONFIG));\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.TEST_DIR));\n // Counter.test.tsx may still exist when i18n is enabled but tests are off.\n await deleteFile(path.join(projectPath, 'src/features/counter/components/Counter.test.tsx'));\n\n await updateJson(path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON), (pkg) => {\n if (pkg.devDependencies) {\n for (const dep of TEST_DEVDEPS) delete pkg.devDependencies[dep];\n }\n if (pkg.scripts) {\n delete pkg.scripts.test;\n delete pkg.scripts['test:watch'];\n delete pkg.scripts['test:coverage'];\n // Drop the `test` step from the validate chain.\n // Negative lookahead guards against matching `test:watch` / `test:coverage`.\n if (typeof pkg.scripts.validate === 'string') {\n pkg.scripts.validate = pkg.scripts.validate\n .replace(/\\s*&&\\s*yarn\\s+test(?![:\\w])/, '')\n .replace(/\\byarn\\s+test(?![:\\w])\\s*&&\\s*/, '');\n }\n }\n return pkg;\n });\n};\n", "import { startSpinner } from '../../../config/spinner';\nimport type { ProjectPrompts } from '../../../prompts/create-app.prompt';\nimport { writeTestUtils } from '../../common/test-utils';\nimport { cleanupBundleAnalyzer } from './bundle-analyzer.cleanup';\nimport { cleanupDarkMode } from './dark-mode.cleanup';\nimport { cleanupHttpClient } from './http.cleanup';\nimport { cleanupI18n } from './i18n.cleanup';\nimport {\n cleanupChangelog,\n cleanupConfig,\n cleanupLicense,\n cleanupSecureStorage,\n cleanupTemplateArtifacts,\n} from './misc.cleanup';\nimport { cleanupReactCompiler } from './react-compiler.cleanup';\nimport { cleanupRedux } from './redux.cleanup';\nimport { cleanupTests } from './tests.cleanup';\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 // next.config.ts modifiers: run bundle-analyzer first (unwraps the outer\n // call), then i18n (unwraps withNextIntl), then react-compiler.\n await cleanupBundleAnalyzer(projectPath, answers);\n await cleanupI18n(projectPath, answers);\n await cleanupReactCompiler(projectPath, answers);\n await cleanupTests(projectPath, answers);\n await cleanupLicense(projectPath);\n await cleanupChangelog(projectPath);\n await cleanupConfig(projectPath);\n await cleanupTemplateArtifacts(projectPath);\n // Rebuild test-utils only if tests are kept. redux/i18n cleanups delete\n // the template version whenever their feature is dropped, so the file\n // shape may not match the final feature set \u2014 regenerate from scratch.\n if (answers.tests) {\n await writeTestUtils(projectPath, { redux: answers.redux, i18n: answers.i18n });\n }\n spinner.succeed('Features customized.');\n } catch (error) {\n spinner.fail('Failed to customize features.');\n throw error;\n }\n};\n", "import path from 'node:path';\nimport { PACKAGES } from '../../config/packages';\nimport { PROJECT_PATHS } from '../../config/paths';\nimport { startSpinner } from '../../config/spinner';\nimport { updateJson } from '../../core/files';\nimport type { ProjectPrompts } from '../../prompts/create-app.prompt';\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];\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", "import { readdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport { PACKAGES } from '../../config/packages';\nimport { PROJECT_PATHS } from '../../config/paths';\nimport {\n deleteDirectory,\n deleteFile,\n fileExists,\n readFile,\n updateJson,\n writeFile,\n} from '../../core/files';\nimport type { ProjectPrompts } from '../../prompts/create-app.prompt';\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 path from 'node:path';\nimport { PROJECT_PATHS } from '../../config/paths';\nimport { writeFile } from '../../core/files';\nimport type { ProjectPrompts } from '../../prompts/create-app.prompt';\n\nexport const generateRootProvider = async (\n projectPath: string,\n answers: ProjectPrompts,\n): Promise<void> => {\n const imports: string[] = [];\n\n if (answers.i18n) {\n imports.push(\"import { type AbstractIntlMessages, NextIntlClientProvider } from 'next-intl';\");\n }\n\n if (answers.darkMode) {\n imports.push(\"import { CustomThemeProvider } from '@/providers';\");\n }\n\n if (answers.redux) {\n imports.push(\"import type { AppState } from '@/store';\");\n }\n\n if (answers.i18n) {\n imports.push(\"import type { SupportedLocale } from '@/types/i18n';\");\n }\n\n if (answers.redux) {\n imports.push(\"import { StoreProvider } from './StoreProvider';\");\n }\n\n const propsFields: string[] = ['children: React.ReactNode;'];\n const destructureFields: string[] = ['children'];\n\n if (answers.i18n) {\n propsFields.push('locale: SupportedLocale;');\n propsFields.push('messages: AbstractIntlMessages;');\n propsFields.push('timeZone: string;');\n destructureFields.push('locale', 'messages', 'timeZone');\n }\n\n if (answers.redux) {\n propsFields.push('preloadedState?: Partial<AppState>;');\n destructureFields.push('preloadedState');\n }\n\n // Build the nested JSX from innermost to outermost\n let jsx = '{children}';\n\n if (answers.i18n) {\n jsx = `<NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>\n ${jsx}\n </NextIntlClientProvider>`;\n }\n\n if (answers.darkMode) {\n jsx = `<CustomThemeProvider>\n ${jsx}\n </CustomThemeProvider>`;\n }\n\n if (answers.redux) {\n jsx = `<StoreProvider preloadedState={preloadedState}>\n ${jsx}\n </StoreProvider>`;\n }\n\n // Ensure a valid JSX expression even with no wrappers\n if (jsx === '{children}') {\n jsx = '<>{children}</>';\n }\n\n const propsType = `type RootProviderProps = {\n ${propsFields.join('\\n ')}\n};`;\n\n const rootProviderContent = `'use client';\n${imports.join('\\n')}\n\n${propsType}\n\nexport const RootProvider = ({ ${destructureFields.join(', ')} }: RootProviderProps) => {\n return (\n ${jsx}\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) return;\n\n const htmlClasses = `\\`\\${livvic.variable} ${answers.darkMode ? 'bg-light antialiased dark:bg-dark' : 'antialiased'}\\``;\n const providerPropsLine = answers.redux ? '' : '';\n\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\"${answers.darkMode ? ' suppressHydrationWarning={true}' : ''}>\n <body className={${htmlClasses}}>\n <RootProvider${providerPropsLine}>\n {children}\n </RootProvider>\n </body>\n </html>\n );\n}\n`;\n await writeFile(path.join(projectPath, PROJECT_PATHS.ROOT_LAYOUT), basicLayout);\n\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", "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 type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { kebabToPascal } from '../config/utils';\nimport { detectProjectSetup } from '../detection';\nimport { generateComponent, generateTest } from '../generators';\nimport { promptForComponentDetails } from '../prompts/component.prompt';\n\ninterface ComponentCommandOptions {\n client?: boolean;\n i18n?: boolean;\n feature?: string;\n test?: boolean;\n noTest?: boolean;\n}\n\nexport const registerComponentCommand = (program: Command) => {\n program\n .command('component [name]')\n .description('Generate a shared component')\n .option('--client', \"Add 'use client' directive\")\n .option('--i18n', 'Add useTranslations hook')\n .option('--feature <path>', 'Generate in feature directory (e.g., src/features/auth)')\n .option('--test', 'Also generate a sibling test file')\n .option('--no-test', 'Skip test file generation')\n .action(async (name: string | undefined, options: ComponentCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\n log(pc.cyan('\\n\uD83E\uDDE9 Component Generator\\n'));\n\n // Detect i18n for auto-adding useTranslations\n spinner.start('Detecting project setup...');\n const detection = await detectProjectSetup(projectPath);\n spinner.succeed('Project setup detected');\n\n // Prompt \u2014 skip questions whose answers were already given via flags.\n const componentOptions = await promptForComponentDetails(name, {\n client: options.client,\n });\n const componentName = kebabToPascal(componentOptions.componentName);\n const isClient = componentOptions.isClient;\n const hasI18n = options.i18n ?? false;\n const shouldTest = resolveShouldTest(options, detection.hasTests);\n\n // Generate\n spinner.start('Generating component...');\n await generateComponent({\n name: componentOptions.componentName,\n projectPath,\n isClient: isClient || hasI18n,\n hasI18n,\n featurePath: options.feature,\n });\n spinner.succeed('Component generated');\n\n let testFile: string | null = null;\n if (shouldTest) {\n const componentFile = options.feature\n ? path.join(projectPath, options.feature, 'components', `${componentName}.tsx`)\n : path.join(\n projectPath,\n 'src/components/common',\n componentName,\n `${componentName}.tsx`,\n );\n spinner.start('Generating test...');\n testFile = await generateTest({\n projectPath,\n sourceFile: componentFile,\n kind: 'component',\n symbolName: componentName,\n hasRedux: detection.hasRedux,\n hasI18n: detection.hasI18n,\n });\n spinner.succeed('Test generated');\n }\n\n // Success\n const location = options.feature\n ? `${options.feature}/components/${componentName}.tsx`\n : `src/components/common/${componentName}/${componentName}.tsx`;\n\n log(pc.green(`\\n\u2728 Component '${componentName}' created successfully!\\n`));\n log(pc.dim(` \uD83D\uDCC4 ${location}`));\n\n if (!options.feature) {\n log(pc.dim(` \uD83D\uDCC4 src/components/common/${componentName}/index.ts`));\n log(pc.dim(` \uD83D\uDCDD Updated src/components/common/index.ts`));\n log(pc.dim(` \uD83D\uDCDD Updated src/components/index.ts`));\n }\n if (testFile) {\n log(pc.dim(` \uD83E\uDDEA ${path.relative(projectPath, testFile)}`));\n }\n\n log('');\n log(pc.cyan('Usage:'));\n if (options.feature) {\n log(\n pc.dim(\n ` import { ${componentName} } from '${options.feature.replace(/^src\\//, '@/')}/components/${componentName}';`,\n ),\n );\n } else {\n log(pc.dim(` import { ${componentName} } from '@/components';`));\n }\n log('');\n } catch (error) {\n spinner.fail('Component generation failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n\nconst resolveShouldTest = (\n options: { test?: boolean; noTest?: boolean },\n hasTests: boolean,\n): boolean => {\n if (options.noTest) return false;\n if (options.test) return true;\n // Default: co-generate when tests are already installed.\n return hasTests;\n};\n", "import { mkdir, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToPascal } from '../config/utils';\nimport { fileExists, readFile, writeFile as writeFileCore } from '../core/files';\nimport {\n componentBarrelTemplate,\n sharedComponentTemplate,\n} from './templates/shared-component.template';\n\nexport interface ComponentGeneratorOptions {\n name: string;\n projectPath: string;\n isClient: boolean;\n hasI18n: boolean;\n featurePath?: string;\n}\n\nexport const generateComponent = async (options: ComponentGeneratorOptions): Promise<void> => {\n const { name, projectPath, isClient, hasI18n, featurePath } = options;\n const componentName = kebabToPascal(name);\n\n if (featurePath) {\n await generateFeatureComponent(componentName, projectPath, featurePath, isClient, hasI18n);\n } else {\n await generateSharedComponent(componentName, name, projectPath, isClient, hasI18n);\n }\n};\n\nconst generateFeatureComponent = async (\n componentName: string,\n projectPath: string,\n featurePath: string,\n isClient: boolean,\n hasI18n: boolean,\n): Promise<void> => {\n const componentsDir = path.join(projectPath, featurePath, 'components');\n await mkdir(componentsDir, { recursive: true });\n\n await writeFile(\n path.join(componentsDir, `${componentName}.tsx`),\n sharedComponentTemplate({ componentName, isClient, hasI18n }),\n );\n};\n\nconst generateSharedComponent = async (\n componentName: string,\n _kebabName: string,\n projectPath: string,\n isClient: boolean,\n hasI18n: boolean,\n): Promise<void> => {\n const componentDir = path.join(projectPath, 'src', 'components', 'common', componentName);\n await mkdir(componentDir, { recursive: true });\n\n // Generate component file\n await writeFile(\n path.join(componentDir, `${componentName}.tsx`),\n sharedComponentTemplate({ componentName, isClient, hasI18n }),\n );\n\n // Generate folder barrel (ComponentName/index.ts)\n await writeFile(path.join(componentDir, 'index.ts'), componentBarrelTemplate({ componentName }));\n\n // Append to common/index.ts\n const commonIndexPath = path.join(projectPath, 'src', 'components', 'common', 'index.ts');\n await appendExport(commonIndexPath, `export { ${componentName} } from './${componentName}';\\n`);\n\n // Append to components/index.ts\n const rootIndexPath = path.join(projectPath, 'src', 'components', 'index.ts');\n await ensureCommonReExport(rootIndexPath);\n};\n\nconst appendExport = async (filePath: string, exportLine: string): Promise<void> => {\n let content = '';\n if (fileExists(filePath)) {\n content = await readFile(filePath);\n }\n if (!content.includes(exportLine.trim())) {\n content += exportLine;\n await writeFileCore(filePath, content);\n }\n};\n\nconst ensureCommonReExport = async (filePath: string): Promise<void> => {\n let content = '';\n if (fileExists(filePath)) {\n content = await readFile(filePath);\n }\n const commonExport = \"export * from './common';\\n\";\n if (!content.includes(commonExport.trim())) {\n content += commonExport;\n await writeFileCore(filePath, content);\n }\n};\n", "export const sharedComponentTemplate = (params: {\n componentName: string;\n isClient: boolean;\n hasI18n: boolean;\n translationNamespace?: string;\n}): string => {\n const { componentName, isClient, hasI18n } = params;\n const ns = params.translationNamespace || componentName;\n const lines: string[] = [];\n\n if (isClient || hasI18n) {\n lines.push(\"'use client';\");\n }\n\n if (hasI18n) {\n lines.push(\"import { useTranslations } from 'next-intl';\");\n }\n\n lines.push('');\n lines.push(`export function ${componentName}() {`);\n\n if (hasI18n) {\n lines.push(` const t = useTranslations('${ns}');`);\n lines.push('');\n lines.push(' return (');\n lines.push(' <div>');\n lines.push(` <h2>{t('title')}</h2>`);\n lines.push(' </div>');\n lines.push(' );');\n } else {\n lines.push(' return (');\n lines.push(' <div>');\n lines.push(` <h2>${componentName}</h2>`);\n lines.push(' </div>');\n lines.push(' );');\n }\n\n lines.push('}');\n lines.push('');\n\n return lines.join('\\n');\n};\n\nexport const componentBarrelTemplate = (params: { componentName: string }): string => {\n return `export { ${params.componentName} } from './${params.componentName}';\\n`;\n};\n", "import { writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel, kebabToPascal } from '../config/utils';\nimport { crudServiceTemplate } from './templates/crud-service.template';\nimport type { ServiceGeneratorOptions } from './types';\n\n/**\n * Generate a CRUD API service file with getAll, getById, create, update, delete methods + DTO types.\n */\nexport const generateCrudService = async (options: ServiceGeneratorOptions): Promise<void> => {\n const { name, outputPath, httpClient } = options;\n const camelName = kebabToCamel(name);\n const pascalName = kebabToPascal(name);\n\n await writeFile(\n path.join(outputPath, `${name}.service.ts`),\n crudServiceTemplate({ camelName, pascalName, httpClient }),\n );\n};\n", "export const crudServiceTemplate = (params: {\n camelName: string;\n pascalName: string;\n httpClient: 'axios' | 'fetch';\n}): string => {\n const { camelName, pascalName, httpClient } = params;\n const clientImport =\n httpClient === 'axios'\n ? `import { axiosClient } from '@/lib/utils/http';`\n : `import { fetchClient } from '@/lib/utils/http';`;\n const clientName = httpClient === 'axios' ? 'axiosClient' : 'fetchClient';\n\n return `import { AppApis } from '@/lib/config';\n${clientImport}\nimport type { ResultAsync } from '@/types';\n\n/**\n * Summary type used in list responses (e.g., cards, tables).\n */\nexport interface ${pascalName}Summary {\n id: string;\n // Add list/card fields here (title, thumbnail, status, etc.)\n}\n\n/**\n * Detail type used in single-item responses (e.g., detail page).\n */\nexport interface ${pascalName}Detail extends ${pascalName}Summary {\n // Add detailed fields here (content, metadata, relations, etc.)\n}\n\nexport interface Create${pascalName}Dto {\n // Add create fields here\n}\n\nexport interface Update${pascalName}Dto {\n // Add update fields here\n}\n\nexport const ${camelName}Service = {\n getAll: (): ResultAsync<${pascalName}Summary[]> => {\n return ${clientName}.get<${pascalName}Summary[]>(AppApis.${camelName}.getAll);\n },\n\n getById: (id: string): ResultAsync<${pascalName}Detail> => {\n return ${clientName}.get<${pascalName}Detail>(AppApis.${camelName}.getById(id));\n },\n\n create: (data: Create${pascalName}Dto): ResultAsync<${pascalName}Detail> => {\n return ${clientName}.post<${pascalName}Detail>(AppApis.${camelName}.create, data);\n },\n\n update: (id: string, data: Update${pascalName}Dto): ResultAsync<${pascalName}Detail> => {\n return ${clientName}.patch<${pascalName}Detail>(AppApis.${camelName}.update(id), data);\n },\n\n delete: (id: string): ResultAsync<void> => {\n return ${clientName}.delete<void>(AppApis.${camelName}.delete(id));\n },\n};\n`;\n};\n\nexport const crudApiConfigTemplate = (params: { camelName: string; kebabName: string }): string => {\n const { camelName, kebabName } = params;\n // Bare paths \u2014 `getApiBaseUrl()` already prepends `/api/v{n}`, so the\n // endpoints here are relative to the API base. Mirrors `AppApis.auth` in\n // the starter template.\n return ` ${camelName}: {\n base: '/${kebabName}',\n getAll: '/${kebabName}',\n getById: (id: string) => \\`/${kebabName}/\\${id}\\`,\n create: '/${kebabName}',\n update: (id: string) => \\`/${kebabName}/\\${id}\\`,\n delete: (id: string) => \\`/${kebabName}/\\${id}\\`,\n },`;\n};\n", "import { mkdir, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToPascal } from '../config/utils';\nimport { generateService } from './service.generator';\nimport { generateSlice } from './slice.generator';\nimport { featureBarrelTemplate } from './templates/barrel.template';\nimport { componentTemplate } from './templates/component.template';\nimport { hookWithoutStoreTemplate, hookWithStoreTemplate } from './templates/hook.template';\nimport { stateTypesTemplate } from './templates/types.template';\nimport type { FeatureGeneratorOptions } from './types';\n\n/**\n * Generate a complete feature module with component, hook, types,\n * and optionally store (slice) and service sub-modules.\n */\nexport const generateFeature = async (options: FeatureGeneratorOptions): Promise<void> => {\n const { name, outputPath, createStore, persistStore, createService, httpClient } = options;\n\n const componentName = kebabToPascal(name);\n const hookName = `use${componentName}`;\n\n // Create directories\n const dirs = [\n path.join(outputPath, 'components'),\n path.join(outputPath, 'hooks'),\n path.join(outputPath, 'types'),\n ...(createStore ? [path.join(outputPath, 'store')] : []),\n ...(createService ? [path.join(outputPath, 'services')] : []),\n ];\n await Promise.all(dirs.map((dir) => mkdir(dir, { recursive: true })));\n\n // Generate base files\n await Promise.all([\n writeFile(\n path.join(outputPath, 'components', `${componentName}.tsx`),\n componentTemplate({ componentName, hookName }),\n ),\n writeFile(\n path.join(outputPath, 'hooks', `${hookName}.ts`),\n createStore\n ? hookWithStoreTemplate({ hookName, componentName, featureName: name })\n : hookWithoutStoreTemplate({ hookName }),\n ),\n writeFile(\n path.join(outputPath, 'types', `${name}.types.ts`),\n stateTypesTemplate({ componentName, withStore: createStore }),\n ),\n writeFile(\n path.join(outputPath, 'index.ts'),\n featureBarrelTemplate({\n featureName: name,\n componentName,\n hookName,\n withStore: createStore,\n withService: createService,\n }),\n ),\n ]);\n\n // Generate store (slice) if requested \u2014 types import from ../types/\n if (createStore) {\n await generateSlice({\n name,\n outputPath: path.join(outputPath, 'store'),\n persist: persistStore,\n typesImportPath: `../types/${name}.types`,\n });\n }\n\n // Generate service if requested\n if (createService && httpClient) {\n await generateService({\n name,\n outputPath: path.join(outputPath, 'services'),\n httpClient,\n });\n }\n};\n", "import { writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel } from '../config/utils';\nimport { serviceTemplate } from './templates/service.template';\nimport type { ServiceGeneratorOptions } from './types';\n\n/**\n * Generate an API service file for the given HTTP client.\n */\nexport const generateService = async (options: ServiceGeneratorOptions): Promise<void> => {\n const { name, outputPath, httpClient } = options;\n const camelName = kebabToCamel(name);\n\n await writeFile(\n path.join(outputPath, `${name}.service.ts`),\n serviceTemplate({ camelName, httpClient }),\n );\n};\n", "export const serviceTemplate = (params: {\n camelName: string;\n httpClient: 'axios' | 'fetch';\n}): string => {\n const { camelName, httpClient } = params;\n const clientImport =\n httpClient === 'axios'\n ? `import { axiosClient } from '@/lib/utils/http';`\n : `import { fetchClient } from '@/lib/utils/http';`;\n const clientName = httpClient === 'axios' ? 'axiosClient' : 'fetchClient';\n\n return `import { AppApis } from '@/lib/config';\n${clientImport}\nimport type { ResultAsync } from '@/types';\n\nexport const ${camelName}Service = {\n getAll: (): ResultAsync<string> => {\n return ${clientName}.get<string>(AppApis.${camelName}.getAll);\n },\n};\n`;\n};\n", "import { mkdir, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel, kebabToPascal } from '../config/utils';\nimport { sliceBarrelTemplate } from './templates/barrel.template';\nimport { persistTemplate } from './templates/persist.template';\nimport { selectorsTemplate } from './templates/selectors.template';\nimport { sliceTemplate } from './templates/slice.template';\nimport { stateTypesTemplate } from './templates/types.template';\nimport type { SliceGeneratorOptions } from './types';\n\n/**\n * Generate a complete Redux slice with types, selectors, optional persist, and barrel export.\n *\n * Used by both the `slice` command (standalone) and the `feature` command (embedded in feature/store/).\n * The `typesImportPath` controls whether types are imported from `../types/` (feature) or `./` (standalone).\n */\nexport const generateSlice = async (\n options: SliceGeneratorOptions & { typesImportPath?: string },\n): Promise<void> => {\n const { name, outputPath, persist, typesImportPath = `./${name}.types` } = options;\n\n await mkdir(outputPath, { recursive: true });\n\n const componentName = kebabToPascal(name);\n const camelName = kebabToCamel(name);\n\n await Promise.all([\n writeFile(\n path.join(outputPath, `${name}.types.ts`),\n stateTypesTemplate({ componentName, withStore: true }),\n ),\n writeFile(\n path.join(outputPath, `${name}.slice.ts`),\n sliceTemplate({ componentName, camelName, typesImportPath }),\n ),\n writeFile(\n path.join(outputPath, `${name}.selectors.ts`),\n selectorsTemplate({ componentName, camelName, sliceName: name }),\n ),\n ...(persist\n ? [\n writeFile(\n path.join(outputPath, 'persist.ts'),\n persistTemplate({ componentName, camelName, typesImportPath }),\n ),\n ]\n : []),\n writeFile(\n path.join(outputPath, 'index.ts'),\n sliceBarrelTemplate({ sliceName: name, withPersist: persist }),\n ),\n ]);\n};\n", "export const sliceBarrelTemplate = (params: {\n sliceName: string;\n withPersist: boolean;\n}): string => {\n const { sliceName, withPersist } = params;\n return `export * from './${sliceName}.slice';\nexport * from './${sliceName}.selectors';\nexport * from './${sliceName}.types';${withPersist ? \"\\nexport * from './persist';\" : ''}\n`;\n};\n\nexport const featureBarrelTemplate = (params: {\n featureName: string;\n componentName: string;\n hookName: string;\n withStore: boolean;\n withService: boolean;\n}): string => {\n const { featureName, componentName, hookName, withStore, withService } = params;\n return `export { default as ${componentName} } from './components/${componentName}';\nexport { ${hookName} } from './hooks/${hookName}';\nexport * from './types/${featureName}.types';${withStore ? `\\nexport * from './store';` : ''}${withService ? `\\nexport * from './services/${featureName}.service';` : ''}\n`;\n};\n", "export const persistTemplate = (params: {\n componentName: string;\n camelName: string;\n typesImportPath: string;\n}): string => {\n const { componentName, camelName, typesImportPath } = params;\n const versionConst = `${camelName.toUpperCase()}_PERSIST_VERSION`;\n return `import { createMigrate, type PersistConfig, type PersistedState } from 'redux-persist';\nimport storage from '@/store/storage';\nimport type { ${componentName}State } from '${typesImportPath}';\n\nconst ${versionConst} = 1;\n\nconst migrations = {\n // Bump ${versionConst} and add a migration here when ${componentName}State's\n // shape changes. Receives the previously-persisted state, returns the new\n // shape. Returning \\`undefined\\` discards stale state.\n // 2: (state) => ({ ...state, newField: defaultValue }),\n} satisfies Record<number, (state: PersistedState) => PersistedState>;\n\nexport const ${camelName}PersistConfig: PersistConfig<${componentName}State> = {\n key: '${camelName}',\n storage,\n version: ${versionConst},\n // whitelist: ['someField'], // Specify which fields to persist\n migrate: createMigrate(migrations, { debug: false }),\n};\n`;\n};\n", "export const selectorsTemplate = (params: {\n componentName: string;\n camelName: string;\n sliceName: string;\n}): string => {\n const { componentName, camelName, sliceName } = params;\n return `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", "export const sliceTemplate = (params: {\n componentName: string;\n camelName: string;\n typesImportPath: string;\n}): string => {\n const { componentName, camelName, typesImportPath } = params;\n return `import { createSlice, type PayloadAction } from '@reduxjs/toolkit';\nimport type { ${componentName}State } from '${typesImportPath}';\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", "export const stateTypesTemplate = (params: {\n componentName: string;\n withStore: boolean;\n}): string => {\n const { componentName, withStore } = params;\n return `export interface ${componentName}State {\n ${withStore ? 'loading: boolean;\\n error: string | null;\\n // Add your state properties here' : '// Add your state properties here\\n // example: value: string;'}\n}\n`;\n};\n", "export const componentTemplate = (params: { componentName: string; hookName: string }): string => {\n const { componentName, hookName } = params;\n return `'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", "export const hookWithStoreTemplate = (params: {\n hookName: string;\n componentName: string;\n featureName: string;\n}): string => {\n const { hookName, componentName, featureName } = params;\n return `'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 };\n\n const handleSetError = (error: string | null) => {\n dispatch(setError(error));\n };\n\n return {\n state,\n setLoading: handleSetLoading,\n setError: handleSetError,\n } as const;\n};\n`;\n};\n\nexport const hookWithoutStoreTemplate = (params: { hookName: string }): string => {\n const { hookName } = params;\n return `'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", "import { mkdir, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToPascal } from '../config/utils';\nimport { customHookTemplate } from './templates/custom-hook.template';\n\nexport interface HookGeneratorOptions {\n name: string;\n projectPath: string;\n isClient: boolean;\n featurePath?: string;\n}\n\nexport const generateHook = async (options: HookGeneratorOptions): Promise<void> => {\n const { name, projectPath, isClient, featurePath } = options;\n const pascalName = kebabToPascal(name);\n const hookName = `use${pascalName}`;\n\n let hooksDir: string;\n if (featurePath) {\n hooksDir = path.join(projectPath, featurePath, 'hooks');\n } else {\n hooksDir = path.join(projectPath, 'src', 'hooks');\n }\n\n await mkdir(hooksDir, { recursive: true });\n\n await writeFile(\n path.join(hooksDir, `${hookName}.ts`),\n customHookTemplate({ hookName, isClient }),\n );\n};\n", "export const customHookTemplate = (params: { hookName: string; isClient: boolean }): string => {\n const { hookName, isClient } = params;\n const lines: string[] = [];\n\n if (isClient) {\n lines.push(\"'use client';\");\n }\n\n lines.push(\"import { useState, useCallback } from 'react';\");\n lines.push('');\n lines.push(`export const ${hookName} = () => {`);\n lines.push(' const [loading, setLoading] = useState(false);');\n lines.push(' const [error, setError] = useState<string | null>(null);');\n lines.push('');\n lines.push(' const execute = useCallback(async () => {');\n lines.push(' setLoading(true);');\n lines.push(' setError(null);');\n lines.push(' try {');\n lines.push(' // Add your logic here');\n lines.push(' } catch (err) {');\n lines.push(\" setError(err instanceof Error ? err.message : 'An error occurred');\");\n lines.push(' } finally {');\n lines.push(' setLoading(false);');\n lines.push(' }');\n lines.push(' }, []);');\n lines.push('');\n lines.push(' return {');\n lines.push(' loading,');\n lines.push(' error,');\n lines.push(' execute,');\n lines.push(' } as const;');\n lines.push('};');\n lines.push('');\n\n return lines.join('\\n');\n};\n", "import { mkdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToPascal } from '../config/utils';\nimport { fileExists, writeFile } from '../core/files';\nimport { layoutTemplate } from './templates/layout.template';\n\nexport interface LayoutGeneratorOptions {\n /**\n * The leaf segment for the layout, e.g. `dashboard` or `marketing`. Route\n * groups are expressed via `withGroup: true` rather than encoding parens\n * into the segment string \u2014 keeps validation simple.\n */\n segment: string;\n /** Optional path under the locale root, e.g. `dashboard/settings`. The leaf becomes the layout. */\n at?: string;\n projectPath: string;\n hasI18n: boolean;\n /** Wraps the leaf segment in parens to form a route group `(marketing)`. */\n withGroup: boolean;\n}\n\nexport interface LayoutGeneratorResult {\n layoutFile: string;\n /** Display path for logging, e.g. `src/app/[locale]/(marketing)/layout.tsx`. */\n displayPath: string;\n componentName: string;\n}\n\nconst SEGMENT_RE = /^[a-z][a-z0-9-]*$/;\nconst SEGMENT_LIST_RE = /^[a-z][a-z0-9-]*(\\/[a-z][a-z0-9-]*)*$/;\n\nconst validateSegment = (segment: string): void => {\n if (!SEGMENT_RE.test(segment)) {\n throw new Error(\n `Invalid layout segment \"${segment}\". Use kebab-case letters, digits, and hyphens. ` +\n 'For route groups pass --group instead of wrapping in parens.',\n );\n }\n};\n\nconst validateAt = (at: string): void => {\n if (!SEGMENT_LIST_RE.test(at)) {\n throw new Error(\n `Invalid --at path \"${at}\". Use kebab-case segments separated by \"/\", e.g. \"dashboard/settings\".`,\n );\n }\n};\n\nexport const generateLayout = async (\n options: LayoutGeneratorOptions,\n): Promise<LayoutGeneratorResult> => {\n const { segment, at, projectPath, hasI18n, withGroup } = options;\n\n validateSegment(segment);\n if (at) validateAt(at);\n\n const componentName = `${kebabToPascal(segment)}Layout`;\n const leaf = withGroup ? `(${segment})` : segment;\n\n const baseSegments = ['src', 'app'];\n if (hasI18n) baseSegments.push('[locale]');\n if (at) baseSegments.push(...at.split('/'));\n baseSegments.push(leaf);\n\n const targetDir = path.join(projectPath, ...baseSegments);\n const layoutFile = path.join(targetDir, 'layout.tsx');\n\n if (fileExists(layoutFile)) {\n throw new Error(`Layout already exists at ${path.relative(projectPath, layoutFile)}.`);\n }\n\n await mkdir(targetDir, { recursive: true });\n await writeFile(layoutFile, layoutTemplate({ componentName, hasI18n }));\n\n return {\n layoutFile,\n displayPath: path.relative(projectPath, layoutFile),\n componentName,\n };\n};\n", "/**\n * Templates for the `layout` generator (B2). Nested layouts only \u2014 the root\n * layout is owned by the starter and is too heavy (fonts, providers, html/body)\n * to scaffold from a CLI.\n */\n\nexport interface LayoutTemplateParams {\n /** PascalCase component name (e.g. `DashboardLayout`). */\n componentName: string;\n /** True when the layout sits under `src/app/[locale]/...` and should consume the locale param. */\n hasI18n: boolean;\n}\n\nconst i18nTemplate = (componentName: string): string =>\n `import { setRequestLocale } from 'next-intl/server';\nimport type { SupportedLocale } from '@/types/i18n';\n\ntype Props = {\n children: React.ReactNode;\n params: Promise<{ locale: string }>;\n};\n\nexport default async function ${componentName}({ children, params }: Props) {\n const { locale } = await params;\n setRequestLocale(locale as SupportedLocale);\n\n return <>{children}</>;\n}\n`;\n\nconst plainTemplate = (componentName: string): string =>\n `type Props = {\n children: React.ReactNode;\n};\n\nexport default function ${componentName}({ children }: Props) {\n return <>{children}</>;\n}\n`;\n\nexport const layoutTemplate = ({ componentName, hasI18n }: LayoutTemplateParams): string =>\n hasI18n ? i18nTemplate(componentName) : plainTemplate(componentName);\n", "import { copyFile, readFile as readFileFs, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { fileExists, readFile, writeFile as writeFileCore } from '../core/files';\n\nexport interface LocaleGeneratorOptions {\n code: string;\n name: string;\n country: string;\n flag: string;\n projectPath: string;\n copyTranslations: boolean;\n}\n\nexport const generateLocale = async (options: LocaleGeneratorOptions): Promise<void> => {\n const { code, name, country, flag, projectPath, copyTranslations } = options;\n\n await createTranslationFile(projectPath, code, copyTranslations);\n await updateSupportedLocaleType(projectPath, code);\n await updateAppLocalesConfig(projectPath, code, name, country, flag);\n};\n\nconst createTranslationFile = async (\n projectPath: string,\n code: string,\n copyTranslations: boolean,\n): Promise<void> => {\n const translationsDir = path.join(projectPath, 'src', 'i18n', 'translations');\n const sourcePath = path.join(translationsDir, 'en.json');\n const destPath = path.join(translationsDir, `${code}.json`);\n\n if (copyTranslations) {\n await copyFile(sourcePath, destPath);\n } else {\n // Copy structure but empty all string values\n const sourceContent = await readFileFs(sourcePath, 'utf-8');\n const sourceJson = JSON.parse(sourceContent);\n const emptyJson = emptyValues(sourceJson);\n await writeFile(destPath, `${JSON.stringify(emptyJson, null, 2)}\\n`);\n }\n};\n\nconst emptyValues = (obj: Record<string, unknown>): Record<string, unknown> => {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (typeof value === 'object' && value !== null) {\n result[key] = emptyValues(value as Record<string, unknown>);\n } else {\n result[key] = '';\n }\n }\n return result;\n};\n\nconst updateSupportedLocaleType = async (projectPath: string, code: string): Promise<void> => {\n const typesPath = path.join(projectPath, 'src', 'types', 'i18n.ts');\n if (!fileExists(typesPath)) return;\n\n let content = await readFile(typesPath);\n\n // Add to SupportedLocale union: 'en' | 'es' \u2192 'en' | 'es' | 'fr'\n const localeTypeRegex = /export type SupportedLocale = (.*);/;\n const match = content.match(localeTypeRegex);\n\n if (match && !match[1].includes(`'${code}'`)) {\n const newType = `${match[1]} | '${code}'`;\n content = content.replace(localeTypeRegex, `export type SupportedLocale = ${newType};`);\n await writeFileCore(typesPath, content);\n }\n};\n\nconst updateAppLocalesConfig = async (\n projectPath: string,\n code: string,\n localeName: string,\n country: string,\n flag: string,\n): Promise<void> => {\n const configPath = path.join(projectPath, 'src', 'lib', 'config', 'app-locales.ts');\n if (!fileExists(configPath)) return;\n\n let content = await readFile(configPath);\n\n if (content.includes(`locale: '${code}'`)) return;\n\n // Insert new locale before the closing bracket\n const closingBracket = content.lastIndexOf('];');\n if (closingBracket === -1) return;\n\n const newLocale = ` {\n name: '${localeName}',\n locale: '${code}',\n flag: '${flag}',\n country: '${country}',\n },\\n`;\n\n content = content.slice(0, closingBracket) + newLocale + content.slice(closingBracket);\n await writeFileCore(configPath, content);\n};\n", "import { mkdir, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToPascal } from '../config/utils';\nimport {\n dynamicPageTemplate,\n errorTemplate,\n loadingTemplate,\n pageTemplate,\n} from './templates/page.template';\n\nexport interface PageGeneratorOptions {\n name: string;\n projectPath: string;\n hasI18n: boolean;\n dynamic?: string;\n withLoading?: boolean;\n withError?: boolean;\n}\n\nexport const generatePage = async (options: PageGeneratorOptions): Promise<void> => {\n const { name, projectPath, hasI18n, dynamic, withLoading = false, withError = false } = options;\n\n const componentName = kebabToPascal(name);\n const routePath = `/${name}`;\n\n // Determine page directory\n const baseDir = hasI18n ? 'src/app/[locale]' : 'src/app';\n let pageDir: string;\n\n if (dynamic) {\n pageDir = path.join(projectPath, baseDir, name, `[${dynamic}]`);\n } else {\n pageDir = path.join(projectPath, baseDir, name);\n }\n\n await mkdir(pageDir, { recursive: true });\n\n // Generate page file\n const pageContent = dynamic\n ? dynamicPageTemplate({\n componentName,\n routePath: dynamic ? `${routePath}/[${dynamic}]` : routePath,\n paramName: dynamic,\n hasI18n,\n })\n : pageTemplate({ componentName, routePath, hasI18n });\n\n await writeFile(path.join(pageDir, 'page.tsx'), pageContent);\n\n if (withLoading) {\n await writeFile(path.join(pageDir, 'loading.tsx'), loadingTemplate({ componentName }));\n }\n\n if (withError) {\n await writeFile(path.join(pageDir, 'error.tsx'), errorTemplate({ componentName }));\n }\n};\n", "export const pageTemplate = (params: {\n componentName: string;\n routePath: string;\n hasI18n: boolean;\n}): string => {\n const { componentName, routePath, hasI18n } = params;\n\n if (hasI18n) {\n return `import { generateSEOMetadata } from '@/lib/config/seo';\nimport type { Metadata } from 'next';\nimport { getTranslations, setRequestLocale } from 'next-intl/server';\nimport type { SupportedLocale } from '@/types/i18n';\n\ntype Props = {\n params: Promise<{ locale: string }>;\n};\n\nexport async function generateMetadata(props: Props): Promise<Metadata> {\n const locale = (await props.params).locale as SupportedLocale;\n const t = await getTranslations({ locale, namespace: '${componentName}' });\n\n return generateSEOMetadata({\n title: t('title'),\n description: t('description'),\n path: '${routePath}',\n });\n}\n\nexport default async function ${componentName}Page(props: Props) {\n const locale = (await props.params).locale as SupportedLocale;\n setRequestLocale(locale);\n\n const t = await getTranslations('${componentName}');\n\n return (\n <div>\n <h1>{t('title')}</h1>\n </div>\n );\n}\n`;\n }\n\n return `import type { Metadata } from 'next';\n\nexport const metadata: Metadata = {\n title: '${componentName}',\n description: '${componentName} page',\n};\n\nexport default function ${componentName}Page() {\n return (\n <div>\n <h1>${componentName}</h1>\n </div>\n );\n}\n`;\n};\n\nexport const dynamicPageTemplate = (params: {\n componentName: string;\n routePath: string;\n paramName: string;\n hasI18n: boolean;\n}): string => {\n const { componentName, paramName, routePath, hasI18n } = params;\n\n if (hasI18n) {\n return `import { generateSEOMetadata } from '@/lib/config/seo';\nimport type { Metadata } from 'next';\nimport { getTranslations, setRequestLocale } from 'next-intl/server';\nimport type { SupportedLocale } from '@/types/i18n';\n\ntype Props = {\n params: Promise<{ locale: string; ${paramName}: string }>;\n};\n\nexport async function generateMetadata(props: Props): Promise<Metadata> {\n const { locale, ${paramName} } = await props.params;\n const t = await getTranslations({ locale: locale as SupportedLocale, namespace: '${componentName}' });\n\n return generateSEOMetadata({\n title: t('title'),\n description: t('description'),\n path: '${routePath}',\n });\n}\n\nexport default async function ${componentName}Page(props: Props) {\n const { locale, ${paramName} } = await props.params;\n setRequestLocale(locale);\n\n const t = await getTranslations('${componentName}');\n\n return (\n <div>\n <h1>{t('title')}</h1>\n <p>${componentName}: {${paramName}}</p>\n </div>\n );\n}\n`;\n }\n\n return `import type { Metadata } from 'next';\n\nexport const metadata: Metadata = {\n title: '${componentName}',\n description: '${componentName} page',\n};\n\ntype Props = {\n params: Promise<{ ${paramName}: string }>;\n};\n\nexport default async function ${componentName}Page(props: Props) {\n const { ${paramName} } = await props.params;\n\n return (\n <div>\n <h1>${componentName}</h1>\n <p>${componentName}: {${paramName}}</p>\n </div>\n );\n}\n`;\n};\n\nexport const loadingTemplate = (params: { componentName: string }): string => {\n return `export default function ${params.componentName}Loading() {\n return (\n <div className=\"flex h-full items-center justify-center\">\n <p>Loading...</p>\n </div>\n );\n}\n`;\n};\n\nexport const errorTemplate = (params: { componentName: string }): string => {\n return `'use client';\n\nexport default function ${params.componentName}Error({\n error,\n reset,\n}: {\n error: Error & { digest?: string };\n reset: () => void;\n}) {\n return (\n <div className=\"flex h-full flex-col items-center justify-center gap-4\">\n <h2>Something went wrong!</h2>\n <p>{error.message}</p>\n <button type=\"button\" onClick={() => reset()}>Try again</button>\n </div>\n );\n}\n`;\n};\n", "import { mkdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport { PROJECT_PATHS } from '../config/paths';\nimport { kebabToPascal } from '../config/utils';\nimport { fileExists, writeFile } from '../core/files';\nimport { providerComponentName, providerTemplate } from './templates/provider.template';\n\nexport interface ProviderGeneratorOptions {\n /** Kebab-case or PascalCase base name (e.g. `auth` or `Auth`). */\n name: string;\n projectPath: string;\n}\n\nexport interface ProviderGeneratorResult {\n componentName: string;\n /** Filename without extension, e.g. `AuthProvider`. */\n fileBaseName: string;\n /** Absolute path to the generated provider file. */\n providerFile: string;\n}\n\nconst NAME_RE = /^[A-Za-z][A-Za-z0-9-]*$/;\n\nconst toPascal = (name: string): string =>\n name.includes('-') ? kebabToPascal(name) : name.charAt(0).toUpperCase() + name.slice(1);\n\nexport const generateProvider = async (\n options: ProviderGeneratorOptions,\n): Promise<ProviderGeneratorResult> => {\n const { name, projectPath } = options;\n\n if (!NAME_RE.test(name)) {\n throw new Error(\n `Invalid provider name \"${name}\". Use kebab-case or PascalCase letters and digits only.`,\n );\n }\n\n const baseName = toPascal(name).replace(/Provider$/, '');\n const componentName = providerComponentName(baseName);\n const fileBaseName = componentName;\n\n const providerDir = path.join(projectPath, PROJECT_PATHS.PROVIDERS);\n const providerFile = path.join(providerDir, `${fileBaseName}.tsx`);\n\n if (fileExists(providerFile)) {\n throw new Error(`Provider already exists at ${path.relative(projectPath, providerFile)}.`);\n }\n\n await mkdir(providerDir, { recursive: true });\n await writeFile(providerFile, providerTemplate({ baseName }));\n\n return { componentName, fileBaseName, providerFile };\n};\n", "/**\n * Templates for the `provider` generator (B3). Generates a context-based\n * provider \u2014 the most common use case. Users who only need a thin wrapper\n * around an external `<XxxProvider>` can delete the context boilerplate.\n */\n\nexport interface ProviderTemplateParams {\n /** PascalCase base name (e.g. `Auth`). The template appends `Provider` for the component and `useX` for the hook. */\n baseName: string;\n}\n\nconst ensureSuffix = (name: string, suffix: string): string =>\n name.endsWith(suffix) ? name : `${name}${suffix}`;\n\nexport const providerTemplate = ({ baseName }: ProviderTemplateParams): string => {\n const componentName = ensureSuffix(baseName, 'Provider');\n // Strip the Provider suffix for the value/context name (e.g. AuthProvider -> Auth).\n const root = componentName.replace(/Provider$/, '');\n const valueType = `${root}ContextValue`;\n const contextName = `${root}Context`;\n const hookName = `use${root}`;\n\n return `'use client';\nimport { createContext, useContext, useMemo } from 'react';\n\ntype ${valueType} = {\n // TODO: declare context value fields\n};\n\nconst ${contextName} = createContext<${valueType} | null>(null);\n\nexport const ${hookName} = (): ${valueType} => {\n const ctx = useContext(${contextName});\n if (!ctx) {\n throw new Error('${hookName} must be used within ${componentName}');\n }\n return ctx;\n};\n\nexport const ${componentName} = ({ children }: { children: React.ReactNode }) => {\n const value = useMemo<${valueType}>(() => ({}), []);\n return <${contextName}.Provider value={value}>{children}</${contextName}.Provider>;\n};\n`;\n};\n\nexport const providerComponentName = (baseName: string): string =>\n ensureSuffix(baseName, 'Provider');\n", "import path from 'node:path';\nimport { writeFile } from '../core/files';\nimport {\n componentTestTemplate,\n hookTestTemplate,\n sliceTestTemplate,\n} from './templates/test.template';\n\nexport type TestKind = 'component' | 'hook' | 'slice';\n\nexport type GenerateTestOptions = {\n projectPath: string;\n /** Absolute path to the source file being tested. */\n sourceFile: string;\n kind: TestKind;\n /** Component/hook/slice identifier (e.g. \"Counter\", \"useCounter\", \"counter\"). */\n symbolName: string;\n hasRedux?: boolean;\n hasI18n?: boolean;\n /** Whether the hook uses the Redux store (only relevant for `kind === 'hook'`). */\n hookUsesStore?: boolean;\n};\n\n/**\n * Emit a sibling *.test.{ts,tsx} next to the source file. Returns the path\n * that was written.\n */\nexport const generateTest = async (options: GenerateTestOptions): Promise<string> => {\n const { projectPath, sourceFile, kind, symbolName } = options;\n const testDir = path.dirname(sourceFile);\n const sourceBaseName = path.basename(sourceFile).replace(/\\.(tsx?|jsx?)$/i, '');\n const extension = kind === 'component' ? '.tsx' : '.ts';\n const testFile = path.join(testDir, `${sourceBaseName}.test${extension}`);\n\n const sourceImportPath = `./${sourceBaseName}`;\n const testUtilsImportPath = relativeImport(testDir, path.join(projectPath, 'test', 'test-utils'));\n\n let content: string;\n if (kind === 'component') {\n content = componentTestTemplate({\n componentName: symbolName,\n sourceImportPath,\n testUtilsImportPath,\n hasRedux: !!options.hasRedux,\n hasI18n: !!options.hasI18n,\n });\n } else if (kind === 'hook') {\n content = hookTestTemplate({\n hookName: symbolName,\n sourceImportPath,\n withStore: !!options.hookUsesStore,\n testUtilsImportPath: options.hookUsesStore ? testUtilsImportPath : undefined,\n });\n } else {\n content = sliceTestTemplate({\n camelName: symbolName,\n sourceImportPath,\n });\n }\n\n await writeFile(testFile, content);\n return testFile;\n};\n\nconst relativeImport = (from: string, to: string): string => {\n const rel = path.relative(from, to).replace(/\\\\/g, '/');\n return rel.startsWith('.') ? rel : `./${rel}`;\n};\n", "export type ComponentTestParams = {\n componentName: string;\n /** Import path from the test file to the component, without extension. */\n sourceImportPath: string;\n /** Import path from the test file to `test/test-utils`, without extension. */\n testUtilsImportPath: string;\n hasRedux: boolean;\n hasI18n: boolean;\n};\n\nexport const componentTestTemplate = (params: ComponentTestParams): string => {\n const { componentName, sourceImportPath, testUtilsImportPath, hasRedux, hasI18n } = params;\n\n const extraOptions: string[] = [];\n if (hasI18n) extraOptions.push('messages: {}');\n if (hasRedux) extraOptions.push('preloadedState: {}');\n const optionsBlock = extraOptions.length\n ? `, {\\n ${extraOptions.join(',\\n ')},\\n }`\n : '';\n\n return `import { describe, expect, it } from 'vitest';\nimport { renderWithProviders, screen } from '${testUtilsImportPath}';\nimport { ${componentName} } from '${sourceImportPath}';\n\ndescribe('${componentName}', () => {\n it('renders without crashing', () => {\n renderWithProviders(<${componentName} />${optionsBlock});\n // TODO: assert something meaningful about the rendered output.\n expect(screen).toBeDefined();\n });\n});\n`;\n};\n\nexport type HookTestParams = {\n hookName: string;\n sourceImportPath: string;\n /** When the hook reads from the Redux store, wrap `renderHook` in TestProviders. */\n withStore: boolean;\n /** Only used when withStore is true. */\n testUtilsImportPath?: string;\n};\n\nexport const hookTestTemplate = (params: HookTestParams): string => {\n const { hookName, sourceImportPath, withStore, testUtilsImportPath } = params;\n\n if (withStore) {\n return `import { renderHook } from '@testing-library/react';\nimport { describe, expect, it } from 'vitest';\nimport { TestProviders } from '${testUtilsImportPath}';\nimport { ${hookName} } from '${sourceImportPath}';\n\ndescribe('${hookName}', () => {\n it('returns a defined value', () => {\n const { result } = renderHook(() => ${hookName}(), { wrapper: TestProviders });\n expect(result.current).toBeDefined();\n });\n});\n`;\n }\n\n return `import { renderHook } from '@testing-library/react';\nimport { describe, expect, it } from 'vitest';\nimport { ${hookName} } from '${sourceImportPath}';\n\ndescribe('${hookName}', () => {\n it('returns a defined value', () => {\n const { result } = renderHook(() => ${hookName}());\n expect(result.current).toBeDefined();\n });\n});\n`;\n};\n\nexport type SliceTestParams = {\n /** e.g. `counter` */\n camelName: string;\n /** Import path from the test file to the `.slice` file, without extension. */\n sourceImportPath: string;\n};\n\nexport const sliceTestTemplate = (params: SliceTestParams): string => {\n const { camelName, sourceImportPath } = params;\n const sliceRef = `${camelName}Slice`;\n\n return `import { describe, expect, it } from 'vitest';\nimport { ${sliceRef}, resetState, setError, setLoading } from '${sourceImportPath}';\n\ndescribe('${sliceRef}', () => {\n const initialState = { loading: false, error: null } as const;\n\n it('returns the initial state', () => {\n expect(${sliceRef}.reducer(undefined, { type: '@@INIT' })).toEqual(initialState);\n });\n\n it('handles setLoading', () => {\n const next = ${sliceRef}.reducer(initialState, setLoading(true));\n expect(next.loading).toBe(true);\n });\n\n it('handles setError', () => {\n const next = ${sliceRef}.reducer(initialState, setError('boom'));\n expect(next.error).toBe('boom');\n });\n\n it('handles resetState', () => {\n const next = ${sliceRef}.reducer({ loading: true, error: 'boom' }, resetState());\n expect(next).toEqual(initialState);\n });\n});\n`;\n};\n", "import Enquirer from 'enquirer';\n\nconst { prompt } = Enquirer;\n\nexport interface ComponentPromptResult {\n componentName: string;\n isClient: boolean;\n}\n\nexport interface ComponentPromptPresets {\n /** When set, the `'use client'` prompt is skipped and this value is used. */\n client?: boolean;\n}\n\nexport const promptForComponentDetails = async (\n name?: string,\n presets: ComponentPromptPresets = {},\n): Promise<ComponentPromptResult> => {\n const questions: any[] = [];\n\n if (!name) {\n questions.push({\n type: 'input',\n name: 'componentName',\n message: 'Component name (kebab-case):',\n validate: (value: string) => {\n if (!value) return 'Component name is required';\n if (!/^[a-z][a-z0-9-]*$/.test(value)) {\n return 'Use lowercase letters, numbers, and hyphens only';\n }\n return true;\n },\n });\n }\n\n if (presets.client === undefined) {\n questions.push({\n type: 'confirm',\n name: 'isClient',\n message: \"Add 'use client' directive?\",\n initial: false,\n });\n }\n\n const answers =\n questions.length > 0\n ? ((await prompt(questions)) as unknown as Partial<ComponentPromptResult>)\n : {};\n\n return {\n componentName: name ?? (answers.componentName as string),\n isClient: presets.client ?? answers.isClient ?? false,\n };\n};\n", "import type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError } from '../config';\nimport { checkManifest, MANIFESTS } from '../manifests';\nimport type { FeatureCheckResult, FeatureFinding } from '../manifests/types';\n\ninterface DoctorCommandOptions {\n fix?: boolean;\n feature?: string;\n json?: boolean;\n}\n\nconst formatFinding = (f: FeatureFinding): string => {\n switch (f.kind) {\n case 'missingFile':\n return `missing file: ${f.file}`;\n case 'missingPackage':\n return `missing ${f.depKind === 'dependency' ? 'dep' : 'devDep'}: ${f.name}`;\n case 'missingScript':\n return `missing script: ${f.name}`;\n case 'mismatchedScript':\n return `script \"${f.name}\" expected ${pc.dim(f.expected)} but got ${pc.dim(f.actual)}`;\n case 'missingInjection':\n return `missing block in ${f.file}: ${f.description}`;\n }\n};\n\nconst summary = (\n results: FeatureCheckResult[],\n): {\n installedCount: number;\n driftedCount: number;\n cleanCount: number;\n driftedResults: FeatureCheckResult[];\n} => {\n const installed = results.filter((r) => r.installed);\n const drifted = installed.filter((r) => r.drift.length > 0);\n return {\n installedCount: installed.length,\n driftedCount: drifted.length,\n cleanCount: installed.length - drifted.length,\n driftedResults: drifted,\n };\n};\n\nexport const registerDoctorCommand = (program: Command) => {\n program\n .command('doctor')\n .description('Diagnose drift between the project and known feature manifests')\n .option('--fix', 'Re-apply manifests that report drift (idempotent)')\n .option('--feature <id>', 'Only check this manifest id (e.g. redux, security-headers)')\n .option('--json', 'Print machine-readable JSON instead of the human report')\n .action(async (options: DoctorCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\n const targets = options.feature\n ? MANIFESTS.filter((m) => m.id === options.feature)\n : MANIFESTS;\n\n if (options.feature && targets.length === 0) {\n throw new Error(\n `Unknown feature \"${options.feature}\". Valid: ${MANIFESTS.map((m) => m.id).join(', ')}.`,\n );\n }\n\n const results: FeatureCheckResult[] = [];\n for (const manifest of targets) {\n results.push(await checkManifest(manifest, projectPath));\n }\n\n if (options.json) {\n log(\n JSON.stringify(\n results.map((r) => ({\n id: r.manifest.id,\n name: r.manifest.name,\n installed: r.installed,\n drift: r.drift,\n })),\n null,\n 2,\n ),\n );\n process.exit(results.some((r) => r.drift.length > 0) ? 1 : 0);\n }\n\n log(pc.cyan('\\n\uD83E\uDE7A Project Doctor\\n'));\n\n for (const result of results) {\n const { manifest, installed, drift } = result;\n if (!installed) {\n log(` ${pc.dim('\u2014')} ${pc.dim(manifest.name)} ${pc.dim('(not installed)')}`);\n continue;\n }\n if (drift.length === 0) {\n log(` ${pc.green('\u2713')} ${manifest.name}`);\n continue;\n }\n log(\n ` ${pc.yellow('!')} ${pc.bold(manifest.name)} ${pc.dim(`(${drift.length} issue${drift.length === 1 ? '' : 's'})`)}`,\n );\n for (const f of drift) {\n log(` ${pc.yellow('\u2022')} ${formatFinding(f)}`);\n }\n }\n\n const stats = summary(results);\n log('');\n log(\n pc.dim(\n `${stats.cleanCount} clean, ${stats.driftedCount} drifted, ${results.length - stats.installedCount} not installed`,\n ),\n );\n\n if (stats.driftedCount === 0) {\n log(pc.green('\\n\u2713 No drift detected.\\n'));\n process.exit(0);\n }\n\n if (!options.fix) {\n log(pc.dim('\\nRun with --fix to re-apply drifted features.\\n'));\n process.exit(1);\n }\n\n log(pc.cyan('\\n\uD83D\uDD27 Applying fixes...\\n'));\n for (const result of stats.driftedResults) {\n if (!result.manifest.apply) {\n log(pc.yellow(` \u26A0\uFE0F ${result.manifest.name} has no apply() \u2014 skipping.`));\n continue;\n }\n try {\n await result.manifest.apply(projectPath);\n } catch (error) {\n logError(`Failed to fix ${result.manifest.name}: ${error}`);\n }\n }\n\n log(pc.green('\\n\u2713 Doctor finished.\\n'));\n } catch (error) {\n logError(`${error instanceof Error ? error.message : error}`);\n process.exit(1);\n }\n });\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../config/paths';\nimport { fileExists, readFile } from '../core/files';\nimport { setupBundleAnalyzer } from '../services/setup/bundle-analyzer';\nimport { unwrapBundleAnalyzer } from './transforms/next-config';\nimport type { FeatureManifest } from './types';\n\nexport const bundleAnalyzerManifest: FeatureManifest = {\n id: 'bundle-analyzer',\n name: 'Bundle Analyzer',\n description: '@next/bundle-analyzer wrapped around the default export',\n detect: async (projectPath) => {\n const target = path.join(projectPath, PROJECT_PATHS.NEXT_CONFIG);\n if (!fileExists(target)) return false;\n return /@next\\/bundle-analyzer/.test(await readFile(target));\n },\n files: [],\n packages: [{ name: '@next/bundle-analyzer', kind: 'devDependency' }],\n scripts: [{ name: 'analyze', expectedValue: 'ANALYZE=true next build' }],\n injections: [\n {\n file: PROJECT_PATHS.NEXT_CONFIG,\n description: 'withBundleAnalyzer import + wrapping',\n presence: /@next\\/bundle-analyzer/,\n removePattern: unwrapBundleAnalyzer,\n },\n ],\n apply: setupBundleAnalyzer,\n};\n", "import path from 'node:path';\nimport pc from 'picocolors';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { startSpinner } from '../../../config/spinner';\nimport { fileExists, readFile, updateJson, writeFile } from '../../../core/files';\nimport { installDevPackage } from '../../../core/package-manager';\n\nexport const setupBundleAnalyzer = async (projectPath: string): Promise<void> => {\n const spinner = startSpinner('Adding @next/bundle-analyzer...');\n try {\n const nextConfigPath = path.join(projectPath, PROJECT_PATHS.NEXT_CONFIG);\n if (!fileExists(nextConfigPath)) {\n throw new Error(`${PROJECT_PATHS.NEXT_CONFIG} not found.`);\n }\n\n let content = await readFile(nextConfigPath);\n if (content.includes('@next/bundle-analyzer')) {\n spinner.fail('@next/bundle-analyzer is already configured.');\n return;\n }\n\n // 1. Add import at the top.\n content = `import withBundleAnalyzer from '@next/bundle-analyzer';\\n${content}`;\n\n // 2. Insert the `const bundleAnalyzer = withBundleAnalyzer(...)` declaration\n // just before `export default ...`.\n const exportDefaultRe = /export default (.*?);/;\n const match = content.match(exportDefaultRe);\n if (!match) {\n throw new Error('Could not locate `export default` in next.config.ts.');\n }\n const existingExport = match[1];\n const replacement = `const bundleAnalyzer = withBundleAnalyzer({\\n enabled: process.env.ANALYZE === 'true',\\n});\\n\\nexport default bundleAnalyzer(${existingExport});`;\n content = content.replace(exportDefaultRe, replacement);\n await writeFile(nextConfigPath, content);\n\n // 3. Add the `analyze` script to package.json.\n await updateJson(path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON), (pkg) => {\n pkg.scripts = pkg.scripts ?? {};\n if (!pkg.scripts.analyze) {\n pkg.scripts.analyze = 'ANALYZE=true next build';\n }\n return pkg;\n });\n\n spinner.text = 'Installing @next/bundle-analyzer...';\n await installDevPackage(projectPath, '@next/bundle-analyzer');\n\n spinner.succeed(pc.green('@next/bundle-analyzer configured.'));\n } catch (error) {\n spinner.fail('Failed to add @next/bundle-analyzer.');\n throw error;\n }\n};\n", "/**\n * JSX unwrap helpers used by manifests' `removePattern` to undo a provider\n * chain wrap (e.g. unwrap `<NextIntlClientProvider>{children}</NextIntlClientProvider>`\n * back to `{children}`) and clean up the now-orphan import statement.\n *\n * String-only transforms \u2014 no AST. Conservative: bail out (return `null`) when\n * the file shape has drifted from the canonical pattern instead of guessing.\n */\n\nimport type { RemoveTransform } from '../types';\n\n/**\n * Drop a named or default import for `symbol`. If the import was the only\n * symbol in a named-import block, the whole line is removed; otherwise the\n * symbol is excised from the brace list.\n */\nexport const removeNamedImport = (content: string, symbol: string): string => {\n const lines = content.split('\\n');\n const out: string[] = [];\n const defaultRe = new RegExp(`^import\\\\s+${symbol}\\\\s+from\\\\s+['\"][^'\"]+['\"];?\\\\s*$`);\n const namedRe = /^(import\\s+)\\{([^}]+)\\}(\\s+from\\s+['\"][^'\"]+['\"];?\\s*)$/;\n\n for (const line of lines) {\n if (defaultRe.test(line)) continue; // drop default import line entirely\n\n const m = line.match(namedRe);\n if (m) {\n const symbols = m[2]\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n const filtered = symbols.filter((s) => {\n const name = s\n .replace(/^type\\s+/, '')\n .split(/\\s+as\\s+/)[0]\n .trim();\n return name !== symbol;\n });\n if (filtered.length === 0) continue; // every symbol was the target \u2014 drop line\n if (filtered.length < symbols.length) {\n out.push(`${m[1]}{ ${filtered.join(', ')} }${m[3]}`);\n continue;\n }\n }\n out.push(line);\n }\n\n return out.join('\\n');\n};\n\n/**\n * Build a `RemoveTransform` that:\n * 1. Locates `<ComponentName ...>` ... `</ComponentName>` in the file.\n * 2. Replaces the wrap with its body, outdented by one level (2 spaces).\n * 3. Drops the orphan import for `ComponentName`.\n *\n * Returns `null` (\u2192 manual cleanup) when:\n * - The opening tag isn't found.\n * - The opening tag spans multiple lines (attributes broken across lines).\n * - No matching closing tag at the same indent is found.\n *\n * The conservative bail-outs keep auto-removal trustworthy: if the user has\n * customised the file beyond the canonical shape, we surface a manual hint\n * rather than corrupt their JSX.\n */\nexport const unwrapJsxChain =\n (componentName: string): RemoveTransform =>\n (content) => {\n const lines = content.split('\\n');\n\n const openRe = new RegExp(`^([ \\\\t]*)<${componentName}\\\\b`);\n let openIdx = -1;\n let openIndent = '';\n for (let i = 0; i < lines.length; i++) {\n const m = lines[i].match(openRe);\n if (m) {\n openIdx = i;\n openIndent = m[1];\n break;\n }\n }\n if (openIdx === -1) return null;\n\n // Opening tag must close on the same line \u2014 multi-line opening tags\n // would require attribute-aware parsing which we deliberately skip.\n if (!/>\\s*$/.test(lines[openIdx])) return null;\n\n const escapedIndent = openIndent.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const closeRe = new RegExp(`^${escapedIndent}<\\\\/${componentName}>\\\\s*$`);\n let closeIdx = -1;\n for (let i = openIdx + 1; i < lines.length; i++) {\n if (closeRe.test(lines[i])) {\n closeIdx = i;\n break;\n }\n }\n if (closeIdx === -1) return null;\n\n // Outdent the body by 2 spaces (one indent level).\n const inner = lines\n .slice(openIdx + 1, closeIdx)\n .map((line) => (line.startsWith(' ') ? line.slice(2) : line));\n\n const merged = [...lines.slice(0, openIdx), ...inner, ...lines.slice(closeIdx + 1)].join('\\n');\n\n return removeNamedImport(merged, componentName);\n };\n", "/**\n * Transforms for `next.config.ts` \u2014 undo the wraps that `setupI18n` and\n * `setupBundleAnalyzer` apply.\n *\n * Conservative: each helper bails out (returns `null`) if the file's shape\n * has drifted away from the canonical pattern. Better to ask the user to\n * resolve it than to corrupt their config.\n */\n\nimport type { RemoveTransform } from '../types';\nimport { removeNamedImport } from './unwrap-jsx';\n\n/**\n * Undo `setupI18n`'s wrap: removes\n * - `import createNextIntlPlugin from 'next-intl/plugin';`\n * - `const withNextIntl = createNextIntlPlugin(...);`\n * - the `withNextIntl(...)` call inside the default export, replacing it\n * with the inner argument.\n */\nexport const unwrapNextIntlPlugin: RemoveTransform = (content) => {\n let result = content\n .split('\\n')\n .filter(\n (line) =>\n !/^import\\s+createNextIntlPlugin\\s+from\\s+['\"]next-intl\\/plugin['\"];?\\s*$/.test(line),\n )\n .join('\\n');\n\n // Drop the `const withNextIntl = createNextIntlPlugin(...)` line(s). The\n // call may take args, so allow multi-line content between the outer parens.\n result = result.replace(/^const\\s+withNextIntl\\s*=\\s*createNextIntlPlugin\\([^)]*\\);\\s*\\n?/m, '');\n\n // Unwrap `withNextIntl(<arg>)` in the default export. The inner arg is\n // typically a bare identifier (`nextConfig`) or a sibling wrap call\n // (`bundleAnalyzer(nextConfig)`). We tolerate the second case by allowing\n // one level of nested parens.\n const callRe = /withNextIntl\\(\\s*((?:[^()]|\\([^()]*\\))+?)\\s*\\)/;\n if (!callRe.test(result)) return null;\n result = result.replace(callRe, '$1');\n\n return result;\n};\n\n/**\n * Undo `setupBundleAnalyzer`'s wrap: removes\n * - `import withBundleAnalyzer from '@next/bundle-analyzer';`\n * - the `const bundleAnalyzer = withBundleAnalyzer({ ... });` block.\n * - the `bundleAnalyzer(...)` call inside the default export.\n */\nexport const unwrapBundleAnalyzer: RemoveTransform = (content) => {\n let result = removeNamedImport(content, 'withBundleAnalyzer');\n\n // The `const bundleAnalyzer = withBundleAnalyzer({...});` block is\n // generated as a multi-line statement. We match conservatively: a `const`\n // declaration whose call body never closes its top-level `}` until we\n // see `);`. Bail out if it isn't there.\n const blockRe = /^const\\s+bundleAnalyzer\\s*=\\s*withBundleAnalyzer\\(\\{[\\s\\S]*?\\}\\);\\s*\\n?/m;\n if (!blockRe.test(result)) {\n return null;\n }\n result = result.replace(blockRe, '');\n\n // Unwrap `bundleAnalyzer(<arg>)` in the default export.\n const callRe = /bundleAnalyzer\\(\\s*((?:[^()]|\\([^()]*\\))+?)\\s*\\)/;\n if (!callRe.test(result)) return null;\n result = result.replace(callRe, '$1');\n\n return result;\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../config/paths';\nimport { fileExists } from '../core/files';\nimport { setupCommitizen } from '../services/setup/commitizen';\nimport type { FeatureManifest } from './types';\n\nexport const commitizenManifest: FeatureManifest = {\n id: 'commitizen',\n name: 'Commitizen',\n description: 'Guided conventional-commit prompt via `commit` script',\n detect: async (projectPath) => fileExists(path.join(projectPath, PROJECT_PATHS.CZRC)),\n files: [{ path: PROJECT_PATHS.CZRC, generated: true }],\n packages: [\n { name: 'commitizen', kind: 'devDependency' },\n { name: 'cz-conventional-changelog', kind: 'devDependency' },\n ],\n scripts: [{ name: 'commit', expectedValue: 'cz' }],\n injections: [],\n apply: setupCommitizen,\n};\n", "import path from 'node:path';\nimport pc from 'picocolors';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { startSpinner } from '../../../config/spinner';\nimport { fileExists, readFile, updateJson, writeFile } from '../../../core/files';\nimport { detectPackageManager, installDevPackages } from '../../../core/package-manager';\nimport { addCommitizen, missingCommitizenDeps, type PackageJsonShape } from './package-modifier';\n\nexport {\n addCommitizen,\n missingCommitizenDeps,\n type PackageJsonShape,\n} from './package-modifier';\n\nconst CZRC_CONTENT = `${JSON.stringify({ path: 'cz-conventional-changelog' }, null, 2)}\\n`;\n\nexport const setupCommitizen = async (projectPath: string): Promise<void> => {\n const spinner = startSpinner('Setting up Commitizen...');\n try {\n const czrcPath = path.join(projectPath, PROJECT_PATHS.CZRC);\n if (!fileExists(czrcPath)) {\n await writeFile(czrcPath, CZRC_CONTENT);\n }\n\n const pkgPath = path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON);\n const beforePkg = JSON.parse(await readFile(pkgPath)) as PackageJsonShape;\n const missing = missingCommitizenDeps(beforePkg);\n\n await updateJson<PackageJsonShape>(pkgPath, (pkg) => addCommitizen(pkg));\n\n if (missing.length > 0) {\n spinner.text = `Installing ${missing.join(', ')}...`;\n const manager = await detectPackageManager(projectPath);\n await installDevPackages(projectPath, manager, missing);\n }\n\n spinner.succeed(pc.green('Commitizen configured. Use `commit` to start a guided commit.'));\n } catch (error) {\n spinner.fail('Failed to set up Commitizen.');\n throw error;\n }\n};\n", "import { PACKAGES } from '../../../config/packages';\n\n/**\n * Pure JSON modifier for Commitizen retrofit. Kept separate from the service\n * so it can be unit-tested with no filesystem.\n */\n\nexport interface PackageJsonShape {\n scripts?: Record<string, string>;\n devDependencies?: Record<string, string>;\n config?: Record<string, unknown> & {\n commitizen?: { path: string };\n };\n [key: string]: unknown;\n}\n\nexport const addCommitizen = (pkg: PackageJsonShape): PackageJsonShape => {\n const scripts = { ...(pkg.scripts ?? {}) };\n const devDeps = { ...(pkg.devDependencies ?? {}) };\n\n if (!scripts.commit) {\n scripts.commit = 'cz';\n }\n if (!devDeps[PACKAGES.COMMITIZEN]) {\n devDeps[PACKAGES.COMMITIZEN] = '*';\n }\n if (!devDeps[PACKAGES.CZ_CONVENTIONAL_CHANGELOG]) {\n devDeps[PACKAGES.CZ_CONVENTIONAL_CHANGELOG] = '*';\n }\n\n return { ...pkg, scripts, devDependencies: devDeps };\n};\n\nexport const missingCommitizenDeps = (pkg: PackageJsonShape): string[] => {\n const devDeps = pkg.devDependencies ?? {};\n const missing: string[] = [];\n if (!devDeps[PACKAGES.COMMITIZEN]) missing.push(PACKAGES.COMMITIZEN);\n if (!devDeps[PACKAGES.CZ_CONVENTIONAL_CHANGELOG])\n missing.push(PACKAGES.CZ_CONVENTIONAL_CHANGELOG);\n return missing;\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../config/paths';\nimport { fileExists } from '../core/files';\nimport { setupDarkTheme } from '../services/setup/dark-theme';\nimport { unwrapJsxChain } from './transforms/unwrap-jsx';\nimport type { FeatureManifest } from './types';\n\nexport const darkThemeManifest: FeatureManifest = {\n id: 'dark-theme',\n name: 'Dark Theme',\n description: '@teispace/next-themes + CustomThemeProvider',\n detect: async (projectPath) => fileExists(path.join(projectPath, PROJECT_PATHS.THEME_PROVIDER)),\n files: [{ path: PROJECT_PATHS.THEME_PROVIDER, generated: true }],\n packages: [{ name: '@teispace/next-themes', kind: 'dependency' }],\n scripts: [],\n injections: [\n {\n file: 'src/providers/RootProvider.tsx',\n description: '<CustomThemeProvider> wrap',\n presence: /CustomThemeProvider/,\n removePattern: unwrapJsxChain('CustomThemeProvider'),\n },\n ],\n apply: setupDarkTheme,\n};\n", "import path from 'node:path';\nimport pc from 'picocolors';\nimport { startSpinner } from '../../../config/spinner';\nimport { deleteDirectory } from '../../../core/files';\nimport { detectPackageManager, installPackage, runScript } from '../../../core/package-manager';\nimport { copyThemeProvider, fetchAssets } from './assets';\nimport { checkIsAlreadySetup, validateProjectStructure } from './checks';\nimport {\n updateGlobalsCss,\n updateLayout,\n updateProvidersIndex,\n updateRootProvider,\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 @teispace/next-themes...';\n await installPackage(projectPath, '@teispace/next-themes');\n\n // 7. Format Code\n spinner.text = 'Formatting code...';\n const packageManager = await detectPackageManager(projectPath);\n await runScript(projectPath, packageManager, 'lint:fix');\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 degit from 'degit';\nimport type { Ora } from 'ora';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { copyFile } from '../../../core/files';\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 { PROJECT_PATHS } from '../../../config/paths';\nimport { fileExists, readFile } from '../../../core/files';\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 const themesPkg = '@teispace/next-themes';\n if (packageJson.dependencies?.[themesPkg] || packageJson.devDependencies?.[themesPkg]) {\n return { isSetup: true, reason: `${themesPkg} 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 { PROJECT_PATHS } from '../../../config/paths';\nimport { fileExists, readFile } from '../../../core/files';\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 { PROJECT_PATHS } from '../../../config/paths';\nimport { fileExists, readFile, writeFile } from '../../../core/files';\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)) return;\n\n let content = await readFile(rootProviderPath);\n\n const useClientDirective = \"'use client';\";\n const hasUseClient = content.includes(useClientDirective);\n if (hasUseClient) {\n content = content.replace(useClientDirective, '').trim();\n }\n\n // Add CustomThemeProvider import if missing\n if (!content.includes('CustomThemeProvider')) {\n if (/import\\s*\\{[^}]*\\}\\s*from\\s*'@\\/providers'/.test(content)) {\n content = content.replace(\n /(import\\s*\\{)([^}]*)(\\}\\s*from\\s*'@\\/providers')/,\n (_m, open, names, close) =>\n `${open}${names.trim() ? `${names.trim()}, CustomThemeProvider ` : ' CustomThemeProvider '}${close}`,\n );\n } else {\n content = `import { CustomThemeProvider } from '@/providers';\\n${content}`;\n }\n }\n\n if (hasUseClient) {\n content = `${useClientDirective}\\n${content}`;\n }\n\n // Wrap {children} with CustomThemeProvider (innermost to preserve any outer providers)\n if (!content.includes('<CustomThemeProvider')) {\n if (content.includes('{children}')) {\n content = content.replace(\n /\\{children\\}/,\n '<CustomThemeProvider>{children}</CustomThemeProvider>',\n );\n } else {\n // Fallback: wrap entire return JSX\n const returnMatch = content.match(/return\\s*\\(\\s*([\\s\\S]*?)\\s*\\);/);\n if (returnMatch) {\n content = content.replace(\n returnMatch[0],\n `return (\\n <CustomThemeProvider>\\n ${returnMatch[1]}\\n </CustomThemeProvider>\\n );`,\n );\n }\n }\n }\n\n await writeFile(rootProviderPath, content);\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 fs from 'node:fs/promises';\nimport path from 'node:path';\nimport Enquirer from 'enquirer';\nimport pc from 'picocolors';\nimport { startSpinner } from '../../../config/spinner';\nimport { deleteDirectory, fileExists } from '../../../core/files';\nimport {\n detectPackageManager,\n installPackage,\n runScript,\n uninstallPackage,\n} from '../../../core/package-manager';\nimport { copyHttpClientFiles, fetchAssets, performFullCleanup } from './assets';\nimport { checkIsAlreadySetup, type HttpClientType, validateProjectStructure } from './checks';\nimport {\n cleanupHttpTypes,\n migrateClientUsages,\n removeHttpExports,\n updateConfigIndex,\n updateHttpIndex,\n updateTypesIndex,\n updateUtilsIndex,\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 // server-only \u2014 guards the next/headers reader in shared/server-cookies.ts.\n // Required by both clients (via shared/cookie-injection's dynamic import),\n // so it tracks \"any client active\" rather than a specific variant.\n if (activeClients.length > 0) {\n if (!dependencies['server-only']) {\n spinner.text = 'Installing server-only...';\n await installPackage(projectPath, 'server-only');\n }\n } else {\n if (dependencies['server-only']) {\n spinner.text = 'Uninstalling server-only...';\n await uninstallPackage(projectPath, 'server-only');\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, 'lint:fix');\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 fs from 'node:fs/promises';\nimport path from 'node:path';\nimport degit from 'degit';\nimport type { Ora } from 'ora';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { copyFile, deleteDirectory, fileExists, readFile, writeFile } from '../../../core/files';\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/api-url.ts (getApiBaseUrl \u2014 composes bare origin + /api/v{n})\n // Skip-if-exists: never overwrite user edits. The file is small and\n // self-contained, so a stale copy from a pre-shared-layout install is\n // tolerable; users can regenerate by deleting it before re-running setup.\n const apiUrlPath = path.join(projectPath, PROJECT_PATHS.API_URL_FILE);\n if (!fileExists(apiUrlPath)) {\n await copyFile(path.join(tempDir, PROJECT_PATHS.API_URL_FILE), apiUrlPath);\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 // shared/ \u2014 runtime detection, cookie injection, request-id, error parsing,\n // params serialiser. Required by BOTH clients, so it's copied unconditionally\n // regardless of which client(s) the user selected. Always overwritten \u2014\n // package-managed code, not a user-edit surface.\n await fs.cp(\n path.join(tempDir, PROJECT_PATHS.HTTP_SHARED),\n path.join(projectPath, PROJECT_PATHS.HTTP_SHARED),\n { recursive: true, force: true },\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 // api-url.ts is owned by the http stack. Drop it only if nothing references\n // `getApiBaseUrl` outside the file itself \u2014 protects users who exported the\n // helper to compose other URLs.\n const apiUrlPath = path.join(projectPath, PROJECT_PATHS.API_URL_FILE);\n if (fileExists(apiUrlPath)) {\n const isUsed = await isStringUsed(projectPath, 'getApiBaseUrl', [apiUrlPath]);\n if (!isUsed) {\n await fs.unlink(apiUrlPath);\n }\n }\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 path from 'node:path';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { fileExists } from '../../../core/files';\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 { setupHttpClient } from '../services/setup/http-client';\nimport type { FeatureManifest } from './types';\n\nexport const httpClientManifest: FeatureManifest = {\n id: 'http-client',\n name: 'HTTP Client',\n description: 'Axios and/or Fetch client utilities',\n detect: async (projectPath) => {\n const { detectProjectSetup } = await import('../detection');\n return (await detectProjectSetup(projectPath)).httpClient !== 'none';\n },\n files: [\n {\n path: 'src/lib/utils/http',\n generated: true,\n isDir: true,\n containsUserContent: true,\n removeHint:\n 'holds the http client + any service modules you wired through it \u2014 review before deleting',\n },\n {\n // Tracked separately so `doctor` reports it by name when missing \u2014\n // shared/ is the foundation both clients import from, and silent\n // drift here breaks every request. Re-running setup restores it.\n path: 'src/lib/utils/http/shared',\n generated: true,\n isDir: true,\n },\n {\n path: 'src/lib/config/api-url.ts',\n generated: true,\n },\n ],\n // No deps listed: axios is conditionally installed; the manifest can't\n // know which client variant is active without re-running detection.\n packages: [],\n scripts: [],\n injections: [],\n apply: setupHttpClient,\n};\n", "import path from 'node:path';\nimport pc from 'picocolors';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { startSpinner } from '../../../config/spinner';\nimport { deleteDirectory, fileExists, readFile } from '../../../core/files';\nimport { detectPackageManager, installPackage, runScript } from '../../../core/package-manager';\nimport { writeTestUtils } from '../../common/test-utils';\nimport { copyI18nFiles, fetchAssets } from './assets';\nimport { checkIsAlreadySetup, validateProjectStructure } from './checks';\nimport {\n migrateToLocaleStructure,\n updateConfigIndex,\n updateNextConfig,\n updateRootProvider,\n updateTypesIndex,\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. If tests are present, regenerate test-utils so it wraps in i18n.\n const vitestConfigPath = path.join(projectPath, PROJECT_PATHS.VITEST_CONFIG);\n if (fileExists(vitestConfigPath)) {\n const pkg = JSON.parse(await readFile(path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON)));\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n const hasRedux = !!(deps['@reduxjs/toolkit'] && deps['react-redux']);\n await writeTestUtils(projectPath, { redux: hasRedux, i18n: true });\n }\n\n // 8. Format Code\n spinner.text = 'Formatting code...';\n const packageManager = await detectPackageManager(projectPath);\n await runScript(projectPath, packageManager, 'lint:fix');\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 fs from 'node:fs/promises';\nimport path from 'node:path';\nimport degit from 'degit';\nimport type { Ora } from 'ora';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { copyFile } from '../../../core/files';\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 { PROJECT_PATHS } from '../../../config/paths';\nimport { fileExists, readFile } from '../../../core/files';\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 (packageJson.dependencies?.['next-intl'] || packageJson.devDependencies?.['next-intl']) {\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 fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { deleteFile, fileExists, readFile, writeFile } from '../../../core/files';\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 { type AbstractIntlMessages, NextIntlClientProvider } from 'next-intl';\nimport type { SupportedLocale } from '@/types/i18n';\n`;\n content = imports + content;\n }\n\n if (hasUseClient) {\n content = `${useClientDirective}\\n${content}`;\n }\n\n // Extend props with locale/messages/timeZone. Handle two shapes:\n // 1) inline \u2014 `({ children }: { children: ReactNode })`\n // 2) aliased \u2014 `type RootProviderProps = { ... }` + `({ children }: RootProviderProps)`\n if (!content.includes('locale: SupportedLocale')) {\n const i18nFields = ` locale: SupportedLocale;\\n messages: AbstractIntlMessages;\\n timeZone: string;`;\n const aliasRe = /(type\\s+RootProviderProps\\s*=\\s*\\{)([\\s\\S]*?)(\\};?)/;\n const inlineRe = /export const RootProvider = \\(\\{([\\s\\S]*?)\\}: \\{([\\s\\S]*?)\\}\\) => \\{/;\n\n if (aliasRe.test(content)) {\n content = content.replace(aliasRe, (_m, open, body, close) => {\n const trimmed = body.replace(/\\s+$/, '');\n return `${open}${trimmed}\\n${i18nFields}\\n${close}`;\n });\n // Add locale/messages/timeZone to destructured args too.\n content = content.replace(\n /export const RootProvider = \\(\\{([\\s\\S]*?)\\}:\\s*RootProviderProps\\)/,\n (_m, inner) => {\n const existing = inner.trim().replace(/,$/, '');\n return `export const RootProvider = ({ ${existing ? `${existing}, ` : ''}locale, messages, timeZone }: RootProviderProps)`;\n },\n );\n } else {\n const match = content.match(inlineRe);\n if (match) {\n const existingParams = match[1].trim().replace(/,$/, '');\n const existingTypes = match[2].trim().replace(/;$/, '');\n const newParams = `\\n ${existingParams ? `${existingParams},\\n ` : ''}locale,\\n messages,\\n timeZone,`;\n const newTypes = `\\n ${existingTypes ? `${existingTypes};\\n ` : ''}locale: SupportedLocale;\\n messages: AbstractIntlMessages;\\n timeZone: string;`;\n content = content.replace(\n match[0],\n `export const RootProvider = ({${newParams}\\n}: {${newTypes}\\n}) => {`,\n );\n }\n }\n }\n\n // Wrap {children} with NextIntlClientProvider\n if (!content.includes('<NextIntlClientProvider')) {\n const returnMatch = content.match(/return\\s*(?:\\(\\s*)?([\\s\\S]*?)(?:\\s*\\))?;/);\n if (returnMatch) {\n const existingJsx = returnMatch[1];\n const wrapped = `<NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>\\n {children}\\n </NextIntlClientProvider>`;\n if (existingJsx.includes('{children}')) {\n const newJsx = existingJsx.replace('{children}', wrapped);\n content = content.replace(returnMatch[0], `return (\\n ${newJsx}\\n );`);\n } else {\n content = content.replace(\n returnMatch[0],\n `return (\\n <NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>\\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 = `import { routing } from '@/i18n/routing';\nimport { hasLocale } from 'next-intl';\nimport { notFound } from 'next/navigation';\nimport { getMessages, getTimeZone, setRequestLocale } from 'next-intl/server';\nimport { getLocaleDirection } from '@/lib/config/app-locales';\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, timeZone] = await Promise.all([getMessages(), getTimeZone()]);\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} timeZone={timeZone}>',\n );\n\n // 4. Update html lang and direction\n content = content.replace(\n /<html lang=\"en\"/,\n '<html lang={locale} dir={getLocaleDirection(locale)}',\n );\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 = `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 { setupI18n } from '../services/setup/i18n';\nimport { unwrapNextIntlPlugin } from './transforms/next-config';\nimport { unwrapJsxChain } from './transforms/unwrap-jsx';\nimport type { FeatureManifest } from './types';\n\nexport const i18nManifest: FeatureManifest = {\n id: 'i18n',\n name: 'Internationalization',\n description: 'next-intl with [locale] routing, RootProvider, and proxy.ts',\n detect: async (projectPath) => {\n const { detectProjectSetup } = await import('../detection');\n return (await detectProjectSetup(projectPath)).hasI18n;\n },\n files: [\n {\n path: 'src/i18n',\n generated: true,\n isDir: true,\n containsUserContent: true,\n removeHint:\n 'holds your translation JSON files \u2014 copy any you want to keep, then delete by hand',\n },\n { path: 'src/proxy.ts', generated: true },\n {\n path: 'src/app/[locale]',\n generated: true,\n isDir: true,\n containsUserContent: true,\n removeHint:\n 'holds every page you generated under the locale segment \u2014 move them to src/app/ before deleting',\n },\n ],\n packages: [{ name: 'next-intl', kind: 'dependency' }],\n scripts: [],\n injections: [\n {\n file: 'next.config.ts',\n description: 'createNextIntlPlugin wrap in next.config.ts',\n presence: /next-intl\\/plugin/,\n removePattern: unwrapNextIntlPlugin,\n },\n {\n file: 'src/providers/RootProvider.tsx',\n description: '<NextIntlClientProvider> wrap',\n presence: /NextIntlClientProvider/,\n removePattern: unwrapJsxChain('NextIntlClientProvider'),\n },\n ],\n apply: setupI18n,\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../config/paths';\nimport { fileExists, readFile } from '../core/files';\nimport { setupReactCompiler } from '../services/setup/react-compiler';\nimport type { FeatureManifest } from './types';\n\nexport const reactCompilerManifest: FeatureManifest = {\n id: 'react-compiler',\n name: 'React Compiler',\n description: 'reactCompiler: true in next.config.ts + babel-plugin-react-compiler',\n detect: async (projectPath) => {\n const target = path.join(projectPath, PROJECT_PATHS.NEXT_CONFIG);\n if (!fileExists(target)) return false;\n return /reactCompiler\\s*:\\s*true/.test(await readFile(target));\n },\n files: [],\n packages: [{ name: 'babel-plugin-react-compiler', kind: 'devDependency' }],\n scripts: [],\n injections: [\n {\n file: PROJECT_PATHS.NEXT_CONFIG,\n description: '`reactCompiler: true` flag',\n presence: /reactCompiler\\s*:\\s*true/,\n removePattern: /\\n\\s*reactCompiler:\\s*true,?/,\n },\n ],\n apply: setupReactCompiler,\n};\n", "import path from 'node:path';\nimport pc from 'picocolors';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { startSpinner } from '../../../config/spinner';\nimport { fileExists, readFile, writeFile } from '../../../core/files';\nimport { installDevPackage } from '../../../core/package-manager';\n\nexport const setupReactCompiler = async (projectPath: string): Promise<void> => {\n const spinner = startSpinner('Enabling React Compiler...');\n try {\n const nextConfigPath = path.join(projectPath, PROJECT_PATHS.NEXT_CONFIG);\n if (!fileExists(nextConfigPath)) {\n throw new Error(`${PROJECT_PATHS.NEXT_CONFIG} not found.`);\n }\n\n let content = await readFile(nextConfigPath);\n if (content.includes('reactCompiler:')) {\n spinner.fail('React Compiler is already configured in next.config.ts.');\n return;\n }\n\n // Inject `reactCompiler: true` inside `const nextConfig: NextConfig = { ... };`\n const configBlock = /(const\\s+nextConfig\\s*:\\s*NextConfig\\s*=\\s*\\{)/;\n if (!configBlock.test(content)) {\n throw new Error('Could not locate `const nextConfig: NextConfig = {` in next.config.ts.');\n }\n content = content.replace(configBlock, '$1\\n reactCompiler: true,');\n await writeFile(nextConfigPath, content);\n\n spinner.text = 'Installing babel-plugin-react-compiler...';\n await installDevPackage(projectPath, 'babel-plugin-react-compiler');\n\n spinner.succeed(pc.green('React Compiler enabled.'));\n } catch (error) {\n spinner.fail('Failed to enable React Compiler.');\n throw error;\n }\n};\n", "import path from 'node:path';\nimport pc from 'picocolors';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { startSpinner } from '../../../config/spinner';\nimport { deleteDirectory, fileExists, readFile } from '../../../core/files';\nimport { detectPackageManager, installPackage, runScript } from '../../../core/package-manager';\nimport { writeTestUtils } from '../../common/test-utils';\nimport { copyReduxFiles, createCounterFeature, fetchAssets } from './assets';\nimport { checkIsAlreadySetup, validateProjectStructure } from './checks';\nimport { updatePage, updateProvidersIndex, updateRootProvider } 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. If tests are present, regenerate test-utils so it wraps in Redux.\n const vitestConfigPath = path.join(projectPath, PROJECT_PATHS.VITEST_CONFIG);\n if (fileExists(vitestConfigPath)) {\n const pkg = JSON.parse(await readFile(path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON)));\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n await writeTestUtils(projectPath, { redux: true, i18n: !!deps['next-intl'] });\n }\n\n // 8. Format Code\n spinner.text = 'Formatting code...';\n const packageManager = await detectPackageManager(projectPath);\n await runScript(projectPath, packageManager, 'lint:fix');\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 fs from 'node:fs/promises';\nimport path from 'node:path';\nimport degit from 'degit';\nimport type { Ora } from 'ora';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { copyFile, fileExists, readFile, writeFile } from '../../../core/files';\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 { PROJECT_PATHS } from '../../../config/paths';\nimport { fileExists, readFile } from '../../../core/files';\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?.['@reduxjs/toolkit'] ||\n 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 { PROJECT_PATHS } from '../../../config/paths';\nimport { fileExists, readFile, writeFile } from '../../../core/files';\n\nexport const updateProvidersIndex = async (_projectPath: string): Promise<void> => {\n // StoreProvider is intentionally NOT exported from `@/providers` in the current\n // template \u2014 RootProvider imports it via a relative path. Nothing to do here.\n return;\n};\n\nexport const updateRootProvider = async (projectPath: string): Promise<void> => {\n const rootProviderPath = path.join(projectPath, 'src/providers/RootProvider.tsx');\n if (!fileExists(rootProviderPath)) return;\n\n let content = await readFile(rootProviderPath);\n\n const useClientDirective = \"'use client';\";\n const hasUseClient = content.includes(useClientDirective);\n if (hasUseClient) {\n content = content.replace(useClientDirective, '').trim();\n }\n\n // Ensure AppState + StoreProvider imports exist\n if (!content.includes(\"from '@/store'\")) {\n content = `import type { AppState } from '@/store';\\n${content}`;\n }\n if (!content.includes(\"from './StoreProvider'\")) {\n content = `${content.includes(\"from '@/store'\") ? '' : ''}import { StoreProvider } from './StoreProvider';\\n${content}`;\n }\n\n if (hasUseClient) {\n content = `${useClientDirective}\\n${content}`;\n }\n\n // Add preloadedState to props (both the type and the destructured args)\n if (!content.includes('preloadedState')) {\n content = content.replace(\n /children:\\s*React\\.ReactNode;/,\n 'children: React.ReactNode;\\n preloadedState?: Partial<AppState>;',\n );\n // Add to destructuring\n content = content.replace(\n /export const RootProvider = \\(\\{([\\s\\S]*?)\\}:/,\n (_m, inner) => `export const RootProvider = ({${inner}, preloadedState }:`,\n );\n // Clean up duplicate commas that may arise\n content = content\n .replace(/,\\s*,/g, ',')\n .replace(/\\{\\s*,/g, '{ ')\n .replace(/,\\s*\\}/g, ' }');\n }\n\n // Wrap the existing return JSX with StoreProvider\n if (!content.includes('<StoreProvider')) {\n const returnMatch = content.match(/return\\s*\\(\\s*([\\s\\S]*?)\\s*\\);/);\n if (returnMatch) {\n const existingJsx = returnMatch[1];\n content = content.replace(\n returnMatch[0],\n `return (\\n <StoreProvider preloadedState={preloadedState}>\\n ${existingJsx}\\n </StoreProvider>\\n );`,\n );\n }\n }\n\n await writeFile(rootProviderPath, content);\n};\n\nexport const updatePage = async (projectPath: string): Promise<void> => {\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 if (!pagePath) return;\n\n let pageContent = await readFile(pagePath);\n\n if (!pageContent.includes('Counter')) {\n pageContent = `import { Counter } from '@/features/counter';\\n${pageContent}`;\n }\n\n if (!pageContent.includes('<Counter />')) {\n const lastDivIndex = pageContent.lastIndexOf('</div>');\n const lastMainIndex = pageContent.lastIndexOf('</main>');\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=\"mb-4 text-2xl font-bold\">Redux Counter</h2>\\n <Counter />\\n </div>\\n' +\n pageContent.slice(insertIndex);\n await writeFile(pagePath, pageContent);\n }\n }\n};\n", "import { setupRedux } from '../services/setup/redux';\nimport { unwrapJsxChain } from './transforms/unwrap-jsx';\nimport type { FeatureManifest } from './types';\n\n/**\n * Slim manifest for Redux. Detection covers the typical footprint, but the\n * code injections (root reducer, providers chain, page wiring) aren't\n * encoded as `removePattern`s \u2014 `remove` reports them as manual cleanup so\n * the user can confirm before stripping.\n */\nexport const reduxManifest: FeatureManifest = {\n id: 'redux',\n name: 'Redux Toolkit',\n description: 'Redux Toolkit + react-redux + redux-persist + StoreProvider',\n detect: async (projectPath) => {\n const { detectProjectSetup } = await import('../detection');\n return (await detectProjectSetup(projectPath)).hasRedux;\n },\n files: [\n {\n path: 'src/store',\n generated: true,\n isDir: true,\n containsUserContent: true,\n removeHint: 'holds the rootReducer and any slices you registered \u2014 review before deleting',\n },\n { path: 'src/providers/StoreProvider.tsx', generated: true },\n ],\n packages: [\n { name: '@reduxjs/toolkit', kind: 'dependency' },\n { name: 'react-redux', kind: 'dependency' },\n { name: 'redux-persist', kind: 'dependency' },\n ],\n scripts: [],\n injections: [\n {\n file: 'src/providers/RootProvider.tsx',\n description: '<StoreProvider> wrap in RootProvider',\n presence: /<StoreProvider/,\n removePattern: unwrapJsxChain('StoreProvider'),\n },\n ],\n apply: setupRedux,\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../config/paths';\nimport { fileExists, readFile } from '../core/files';\nimport { hasSecurityHeaders, setupSecurityHeaders } from '../services/setup/security-headers';\nimport type { FeatureManifest } from './types';\n\nexport const securityHeadersManifest: FeatureManifest = {\n id: 'security-headers',\n name: 'Security Headers',\n description: 'Hardened HTTP headers in next.config.ts',\n detect: async (projectPath) => {\n const target = path.join(projectPath, PROJECT_PATHS.NEXT_CONFIG);\n if (!fileExists(target)) return false;\n return hasSecurityHeaders(await readFile(target));\n },\n files: [],\n packages: [],\n scripts: [],\n injections: [\n {\n file: PROJECT_PATHS.NEXT_CONFIG,\n description: 'headers() function in next.config.ts',\n presence: /^\\s+headers\\s*:/m,\n removePattern: /\\s+headers:\\s*async\\s*\\(\\)\\s*=>\\s*\\{[\\s\\S]*?\\n\\s{0,2}\\},/m,\n },\n ],\n apply: setupSecurityHeaders,\n};\n", "import path from 'node:path';\nimport pc from 'picocolors';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { startSpinner } from '../../../config/spinner';\nimport { fileExists, readFile, writeFile } from '../../../core/files';\nimport { hasSecurityHeaders, injectSecurityHeaders } from './headers';\n\nexport { hasSecurityHeaders, injectSecurityHeaders, SECURITY_HEADERS } from './headers';\n\nexport const setupSecurityHeaders = async (projectPath: string): Promise<void> => {\n const spinner = startSpinner('Adding security headers to next.config.ts...');\n try {\n const nextConfigPath = path.join(projectPath, PROJECT_PATHS.NEXT_CONFIG);\n if (!fileExists(nextConfigPath)) {\n throw new Error(`${PROJECT_PATHS.NEXT_CONFIG} not found.`);\n }\n\n const content = await readFile(nextConfigPath);\n if (hasSecurityHeaders(content)) {\n spinner.succeed('Security headers already configured.');\n return;\n }\n\n const updated = injectSecurityHeaders(content);\n await writeFile(nextConfigPath, updated);\n\n spinner.succeed(pc.green('Security headers added.'));\n } catch (error) {\n spinner.fail('Failed to add security headers.');\n throw error;\n }\n};\n", "/**\n * Pure transformation logic for the `setupSecurityHeaders` retrofit.\n *\n * Kept separate from `index.ts` so it can be unit-tested with string inputs\n * without touching the filesystem.\n */\n\n/**\n * The header set the starter ships in `next.config.ts`. Single source of truth\n * \u2014 `setupSecurityHeaders` and the manifest (D1) both consume this list.\n */\nexport const SECURITY_HEADERS: ReadonlyArray<{ key: string; value: string }> = [\n { key: 'X-DNS-Prefetch-Control', value: 'on' },\n {\n key: 'Strict-Transport-Security',\n value: 'max-age=63072000; includeSubDomains; preload',\n },\n { key: 'X-XSS-Protection', value: '1; mode=block' },\n { key: 'X-Frame-Options', value: 'SAMEORIGIN' },\n { key: 'X-Content-Type-Options', value: 'nosniff' },\n { key: 'Referrer-Policy', value: 'origin-when-cross-origin' },\n];\n\nconst NEXT_CONFIG_BLOCK_RE = /(const\\s+nextConfig\\s*:\\s*NextConfig\\s*=\\s*\\{)/;\n\n// Matches ` headers:` at the start of an indented line \u2014 the config-key\n// shape, not the `key: 'Permissions-Policy'` string-value shape.\nconst HEADERS_KEY_RE = /^\\s+headers\\s*:/m;\n\nconst buildHeadersBlock = (headers: ReadonlyArray<{ key: string; value: string }>): string => {\n const lines = headers\n .map(({ key, value }) => ` { key: '${key}', value: '${value}' },`)\n .join('\\n');\n\n return `\\n headers: async () => {\n return [\n {\n source: '/:path*',\n headers: [\n${lines}\n ],\n },\n ];\n },`;\n};\n\nexport const hasSecurityHeaders = (content: string): boolean => HEADERS_KEY_RE.test(content);\n\n/**\n * Inject the standard security-headers block into a `next.config.ts` source.\n *\n * - Idempotent: returns the input unchanged if a `headers:` key already exists\n * anywhere in the file (we never overwrite a user-defined header set).\n * - Throws if the canonical `const nextConfig: NextConfig = {` shape is missing\n * \u2014 same contract as the React-Compiler retrofit, so behaviour stays\n * predictable across `setup` services.\n */\nexport const injectSecurityHeaders = (\n content: string,\n headers: ReadonlyArray<{ key: string; value: string }> = SECURITY_HEADERS,\n): string => {\n if (hasSecurityHeaders(content)) {\n return content;\n }\n if (!NEXT_CONFIG_BLOCK_RE.test(content)) {\n throw new Error('Could not locate `const nextConfig: NextConfig = {` in next.config.ts.');\n }\n return content.replace(NEXT_CONFIG_BLOCK_RE, `$1${buildHeadersBlock(headers)}`);\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../config/paths';\nimport { fileExists } from '../core/files';\nimport { setupTests } from '../services/setup/tests';\nimport type { FeatureManifest } from './types';\n\nexport const testsManifest: FeatureManifest = {\n id: 'tests',\n name: 'Tests',\n description: 'Vitest + React Testing Library + jsdom',\n detect: async (projectPath) => fileExists(path.join(projectPath, PROJECT_PATHS.VITEST_CONFIG)),\n files: [\n { path: PROJECT_PATHS.VITEST_CONFIG, generated: true },\n {\n path: 'test',\n generated: true,\n isDir: true,\n containsUserContent: true,\n removeHint:\n 'holds setup.ts / test-utils.tsx and any helpers you added \u2014 review before deleting',\n },\n ],\n packages: [\n { name: 'vitest', kind: 'devDependency' },\n { name: 'jsdom', kind: 'devDependency' },\n { name: '@vitejs/plugin-react', kind: 'devDependency' },\n { name: '@testing-library/dom', kind: 'devDependency' },\n { name: '@testing-library/jest-dom', kind: 'devDependency' },\n { name: '@testing-library/react', kind: 'devDependency' },\n { name: '@testing-library/user-event', kind: 'devDependency' },\n ],\n scripts: [\n { name: 'test', expectedValue: 'vitest run' },\n { name: 'test:watch', expectedValue: 'vitest' },\n ],\n injections: [],\n apply: setupTests,\n};\n", "import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport degit from 'degit';\nimport pc from 'picocolors';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { startSpinner } from '../../../config/spinner';\nimport { copyFile, deleteDirectory, fileExists, readFile, updateJson } from '../../../core/files';\nimport { detectPackageManager, installDevPackages, runScript } from '../../../core/package-manager';\nimport { writeTestUtils } from '../../common/test-utils';\n\nconst TEST_DEVDEPS = [\n 'vitest',\n 'jsdom',\n '@vitejs/plugin-react',\n '@testing-library/dom',\n '@testing-library/jest-dom',\n '@testing-library/react',\n '@testing-library/user-event',\n];\n\nexport const setupTests = async (projectPath: string): Promise<void> => {\n const spinner = startSpinner('Setting up testing (Vitest + RTL)...');\n const tempDir = path.join(projectPath, '.next-maker-temp-tests');\n\n try {\n const vitestConfigPath = path.join(projectPath, PROJECT_PATHS.VITEST_CONFIG);\n if (fileExists(vitestConfigPath)) {\n spinner.fail('Testing is already set up (vitest.config.ts exists).');\n return;\n }\n\n // 1. Fetch the starter to copy vitest.config.ts + test/setup.ts.\n spinner.text = 'Fetching assets from starter repo...';\n const emitter = degit('teispace/nextjs-starter', { cache: false, force: true, verbose: false });\n await emitter.clone(tempDir);\n\n await copyFile(\n path.join(tempDir, PROJECT_PATHS.VITEST_CONFIG),\n path.join(projectPath, PROJECT_PATHS.VITEST_CONFIG),\n );\n\n const testDir = path.join(projectPath, PROJECT_PATHS.TEST_DIR);\n await fs.mkdir(testDir, { recursive: true });\n await copyFile(\n path.join(tempDir, PROJECT_PATHS.TEST_DIR, 'setup.ts'),\n path.join(testDir, 'setup.ts'),\n );\n\n // 2. Generate test-utils matching existing features.\n const packageJsonPath = path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON);\n const pkg = JSON.parse(await readFile(packageJsonPath));\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n const hasRedux = !!(deps['@reduxjs/toolkit'] && deps['react-redux']);\n const hasI18n = !!deps['next-intl'];\n await writeTestUtils(projectPath, { redux: hasRedux, i18n: hasI18n });\n\n // 3. Update package.json: scripts + reinstate `yarn test` in validate.\n await updateJson(packageJsonPath, (p) => {\n p.scripts = p.scripts ?? {};\n p.scripts.test = p.scripts.test ?? 'vitest run';\n p.scripts['test:watch'] = p.scripts['test:watch'] ?? 'vitest';\n p.scripts['test:coverage'] = p.scripts['test:coverage'] ?? 'vitest run --coverage';\n if (\n typeof p.scripts.validate === 'string' &&\n !/\\byarn\\s+test(?![:\\w])/.test(p.scripts.validate)\n ) {\n p.scripts.validate = p.scripts.validate.replace(\n /(\\byarn\\s+check:deprecated\\s*)(&&)/,\n '$1&& yarn test $2',\n );\n }\n return p;\n });\n\n // 4. Install dev deps.\n spinner.text = 'Installing testing devDependencies...';\n const manager = await detectPackageManager(projectPath);\n await installDevPackages(projectPath, manager, TEST_DEVDEPS);\n\n // 5. Format.\n spinner.text = 'Formatting code...';\n await runScript(projectPath, manager, 'lint:fix');\n\n spinner.succeed(pc.green('Testing setup complete.'));\n } catch (error) {\n spinner.fail('Failed to set up testing.');\n throw error;\n } finally {\n await deleteDirectory(tempDir);\n }\n};\n", "import path from 'node:path';\nimport { fileExists } from '../core/files';\nimport { setupValidationScripts } from '../services/setup/validate-scripts';\nimport type { FeatureManifest } from './types';\n\nconst SCRIPT_FILES = ['scripts/sync-env.ts', 'scripts/check-deprecated.ts'] as const;\n\nexport const validateScriptsManifest: FeatureManifest = {\n id: 'validate-scripts',\n name: 'Validation Scripts',\n description: 'sync-env, check-deprecated, and the validate chain',\n detect: async (projectPath) =>\n SCRIPT_FILES.every((rel) => fileExists(path.join(projectPath, rel))),\n files: SCRIPT_FILES.map((p) => ({ path: p, generated: true })),\n packages: [{ name: 'tsx', kind: 'devDependency' }],\n scripts: [\n { name: 'env:sync', expectedValue: 'tsx scripts/sync-env.ts' },\n { name: 'check:deprecated', expectedValue: 'tsx scripts/check-deprecated.ts' },\n { name: 'type-check', expectedValue: 'tsc --noEmit' },\n { name: 'validate' },\n ],\n injections: [],\n apply: setupValidationScripts,\n};\n", "import path from 'node:path';\nimport pc from 'picocolors';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { startSpinner } from '../../../config/spinner';\nimport { fileExists, updateJson, writeFile } from '../../../core/files';\nimport { detectPackageManager, installDevPackages } from '../../../core/package-manager';\nimport { addValidationScripts, type PackageJsonShape } from './package-modifier';\nimport { CHECK_DEPRECATED_SCRIPT, SYNC_ENV_SCRIPT } from './scripts';\n\nexport {\n addValidationScripts,\n type PackageJsonShape,\n} from './package-modifier';\nexport { CHECK_DEPRECATED_SCRIPT, SYNC_ENV_SCRIPT } from './scripts';\n\nconst SCRIPT_TARGETS = [\n { relative: 'scripts/sync-env.ts', content: SYNC_ENV_SCRIPT },\n { relative: 'scripts/check-deprecated.ts', content: CHECK_DEPRECATED_SCRIPT },\n] as const;\n\nexport const setupValidationScripts = async (projectPath: string): Promise<void> => {\n const spinner = startSpinner('Adding validation scripts...');\n try {\n // 1. Write script files (skip when present \u2014 never overwrite user edits)\n let wroteAny = false;\n for (const { relative, content } of SCRIPT_TARGETS) {\n const target = path.join(projectPath, relative);\n if (fileExists(target)) continue;\n await writeFile(target, content);\n wroteAny = true;\n }\n\n // 2. Patch package.json\n const manager = await detectPackageManager(projectPath);\n let needsTsx = false;\n await updateJson<PackageJsonShape>(\n path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON),\n (pkg) => {\n const before = pkg.devDependencies?.tsx;\n const next = addValidationScripts(pkg, manager);\n needsTsx = !before && !!next.devDependencies?.tsx;\n return next;\n },\n );\n\n // 3. Install tsx (only if it was newly added)\n if (needsTsx) {\n spinner.text = 'Installing tsx...';\n await installDevPackages(projectPath, manager, ['tsx']);\n }\n\n spinner.succeed(\n pc.green(\n wroteAny\n ? 'Validation scripts added (env:sync, check:deprecated, validate).'\n : 'Validation scripts already present \u2014 refreshed package.json.',\n ),\n );\n } catch (error) {\n spinner.fail('Failed to add validation scripts.');\n throw error;\n }\n};\n", "import type { PackageManager } from '../../../core/package-manager';\n\n/**\n * Pure modifiers for the package.json `scripts` block \u2014 separated from the\n * service so they can be unit-tested without touching the filesystem.\n */\n\nexport interface PackageJsonShape {\n scripts?: Record<string, string>;\n devDependencies?: Record<string, string>;\n [key: string]: unknown;\n}\n\nconst SCRIPT_RUNNER_PREFIX: Record<PackageManager, string> = {\n npm: 'npm run',\n yarn: 'yarn',\n pnpm: 'pnpm',\n bun: 'bun run',\n};\n\nconst buildValidateChain = (manager: PackageManager): string => {\n const prefix = SCRIPT_RUNNER_PREFIX[manager];\n return ['ci:check', 'type-check', 'check:deprecated', 'test', 'build']\n .map((name) => `${prefix} ${name}`)\n .join(' && ');\n};\n\n/**\n * Add the validation scripts (env:sync, check:deprecated, validate) and the\n * matching tsx/typescript dev-deps, never overwriting a user-defined entry.\n *\n * Returns a *new* package.json object \u2014 callers pass it through `updateJson`\n * which already understands \"function returns the new value\".\n */\nexport const addValidationScripts = (\n pkg: PackageJsonShape,\n manager: PackageManager,\n): PackageJsonShape => {\n const scripts = { ...(pkg.scripts ?? {}) };\n const devDeps = { ...(pkg.devDependencies ?? {}) };\n\n if (!scripts['env:sync']) {\n scripts['env:sync'] = 'tsx scripts/sync-env.ts';\n }\n if (!scripts['check:deprecated']) {\n scripts['check:deprecated'] = 'tsx scripts/check-deprecated.ts';\n }\n if (!scripts['type-check']) {\n scripts['type-check'] = 'tsc --noEmit';\n }\n if (!scripts.validate) {\n scripts.validate = buildValidateChain(manager);\n }\n\n if (!devDeps.tsx && !pkg.dependencies?.hasOwnProperty('tsx')) {\n devDeps.tsx = '*';\n }\n\n return { ...pkg, scripts, devDependencies: devDeps };\n};\n", "/**\n * Source for the two validation scripts the starter ships under `scripts/`.\n *\n * Inlined here (not fetched from the starter via degit) because (a) these\n * scripts are stable and don't drift, (b) we get instant offline retrofits,\n * and (c) the diff between starter and next-maker is small enough to spot\n * during release reviews. If they ever start to differ, switch this module\n * to a degit fetch \u2014 the rest of the service won't need to change.\n */\n\nexport const SYNC_ENV_SCRIPT = `import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nconst checkOnly = process.argv.includes('--check');\n\nconst envPath = path.join(process.cwd(), '.env');\nconst examplePath = path.join(process.cwd(), '.env.example');\n\nif (!fs.existsSync(envPath)) {\n console.log('\u26A0\uFE0F No .env file found. Skipping sync.');\n process.exit(0);\n}\n\nconst envContent = fs.readFileSync(envPath, 'utf-8');\nconst lines = envContent.split('\\\\n');\n\nlet isPublicBlock = false;\n\nconst exampleLines = lines.map((line) => {\n const trimmed = line.trim();\n\n // Preserve empty lines and reset public block state\n if (!trimmed) {\n isPublicBlock = false;\n return line;\n }\n\n // Preserve comments\n if (trimmed.startsWith('#')) {\n if (line.toLowerCase().includes('-public')) {\n isPublicBlock = true;\n }\n return line;\n }\n\n // Parse KEY=VALUE\n const match = line.match(/^([^=]+)=(.*)$/);\n\n if (match) {\n const key = match[1];\n\n // Public marker: explicit \"# -public\" comment, or \"KEY=VAL # -public\"\n if (isPublicBlock || line.toLowerCase().includes('-public')) {\n isPublicBlock = false;\n return line;\n }\n\n isPublicBlock = false;\n return \\`\\${key}=\\`;\n }\n\n isPublicBlock = false;\n return line;\n});\n\nconst newExampleContent = exampleLines.join('\\\\n');\n\nlet currentExampleContent = '';\nif (fs.existsSync(examplePath)) {\n currentExampleContent = fs.readFileSync(examplePath, 'utf-8');\n}\n\nif (currentExampleContent === newExampleContent) {\n console.log('\u2728 .env.example is already up to date');\n process.exit(0);\n}\n\nif (checkOnly) {\n console.error('\u274C .env.example is out of sync with .env. Run \"yarn env:sync\" to update.');\n process.exit(1);\n}\n\nfs.writeFileSync(examplePath, newExampleContent);\nconsole.log('\u2705 Synchronized .env.example with .env');\n`;\n\nexport const CHECK_DEPRECATED_SCRIPT = `/**\n * Walks every identifier in the project and flags any whose resolved TypeScript\n * symbol carries a \\`@deprecated\\` JSDoc tag. Catches deprecated API usage that\n * \\`tsc --noEmit\\` does not surface (deprecations are \"suggestion\"-level, not\n * errors) and that Biome does not yet detect.\n *\n * Exits 1 if any deprecated usage is found (so it can gate CI).\n */\nimport path from 'node:path';\nimport ts from 'typescript';\n\nconst cwd = process.cwd();\nconst configPath = ts.findConfigFile(cwd, ts.sys.fileExists, 'tsconfig.json');\n\nif (!configPath) {\n console.error('tsconfig.json not found');\n process.exit(1);\n}\n\nconst raw = ts.readConfigFile(configPath, ts.sys.readFile).config;\nconst parsed = ts.parseJsonConfigFileContent(raw, ts.sys, path.dirname(configPath));\n\nconst program = ts.createProgram({\n rootNames: parsed.fileNames,\n options: parsed.options,\n});\n\nconst checker = program.getTypeChecker();\n\nfunction isDeprecated(sym: ts.Symbol | undefined): boolean {\n if (!sym) return false;\n return sym.getJsDocTags(checker).some((tag) => tag.name === 'deprecated');\n}\n\nlet hits = 0;\n\nfor (const sourceFile of program.getSourceFiles()) {\n if (sourceFile.fileName.includes('node_modules')) continue;\n if (!sourceFile.fileName.startsWith(cwd)) continue;\n\n const visit = (node: ts.Node): void => {\n if (ts.isIdentifier(node)) {\n const sym = checker.getSymbolAtLocation(node);\n if (isDeprecated(sym)) {\n const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n console.log(\n \\`\\${path.relative(cwd, sourceFile.fileName)}:\\${line + 1}:\\${character + 1} \\${node.text} (@deprecated)\\`,\n );\n hits++;\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n}\n\nif (hits === 0) {\n console.log('\u2713 No deprecated API usage found.');\n process.exit(0);\n}\n\nconsole.log(\\`\\\\n\\${hits} deprecated symbol use(s) found.\\`);\nprocess.exit(1);\n`;\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../config/paths';\nimport { fileExists, readFile, writeFile } from '../core/files';\nimport { detectPackageManager, uninstallPackages } from '../core/package-manager';\nimport type {\n FeatureCheckResult,\n FeatureFinding,\n FeatureManifest,\n PackageRequirement,\n} from './types';\n\ninterface PackageJsonShape {\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n [key: string]: unknown;\n}\n\nconst readPackageJson = async (projectPath: string): Promise<PackageJsonShape | null> => {\n const pkgPath = path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON);\n if (!fileExists(pkgPath)) return null;\n return JSON.parse(await readFile(pkgPath));\n};\n\nconst writePackageJson = async (projectPath: string, pkg: PackageJsonShape): Promise<void> => {\n const pkgPath = path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON);\n await writeFile(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n};\n\nconst depsFor = (pkg: PackageJsonShape, kind: PackageRequirement['kind']): Record<string, string> =>\n (kind === 'dependency' ? pkg.dependencies : pkg.devDependencies) ?? {};\n\n/**\n * Compute drift: walk every piece of the manifest's footprint and report\n * what's missing or mismatched. Returns an empty array when the feature is\n * present and complete.\n */\nexport const checkManifest = async (\n manifest: FeatureManifest,\n projectPath: string,\n): Promise<FeatureCheckResult> => {\n const installed = await manifest.detect(projectPath);\n const drift: FeatureFinding[] = [];\n\n if (!installed) {\n return { manifest, installed: false, drift: [] };\n }\n\n for (const file of manifest.files) {\n const required = file.required !== false;\n if (!required) continue;\n if (!fileExists(path.join(projectPath, file.path))) {\n drift.push({ kind: 'missingFile', file: file.path });\n }\n }\n\n const pkg = await readPackageJson(projectPath);\n if (pkg) {\n for (const dep of manifest.packages) {\n const map = depsFor(pkg, dep.kind);\n if (!map[dep.name]) {\n drift.push({ kind: 'missingPackage', name: dep.name, depKind: dep.kind });\n }\n }\n\n const scripts = pkg.scripts ?? {};\n for (const script of manifest.scripts) {\n const actual = scripts[script.name];\n if (!actual) {\n drift.push({ kind: 'missingScript', name: script.name });\n } else if (script.expectedValue && actual !== script.expectedValue) {\n drift.push({\n kind: 'mismatchedScript',\n name: script.name,\n expected: script.expectedValue,\n actual,\n });\n }\n }\n }\n\n for (const injection of manifest.injections) {\n const filePath = path.join(projectPath, injection.file);\n if (!fileExists(filePath)) {\n drift.push({\n kind: 'missingInjection',\n file: injection.file,\n description: injection.description,\n });\n continue;\n }\n const content = await readFile(filePath);\n if (!injection.presence.test(content)) {\n drift.push({\n kind: 'missingInjection',\n file: injection.file,\n description: injection.description,\n });\n }\n }\n\n return { manifest, installed, drift };\n};\n\nexport interface RemoveSummary {\n filesRemoved: string[];\n packagesUninstalled: string[];\n scriptsRemoved: string[];\n blocksStripped: Array<{ file: string; description: string }>;\n /** Manual-cleanup items the runner couldn't safely remove. */\n manualCleanup: Array<{ file: string; description: string }>;\n}\n\n/**\n * Generic reverse: walk the footprint and undo what we can confidently undo.\n *\n * - Files marked `generated: true` are deleted.\n * - Files marked `generated: false` are left alone (user-owned).\n * - Packages are uninstalled.\n * - Scripts are removed from package.json.\n * - Code blocks with a `removePattern` are stripped; without one, they end\n * up in `manualCleanup` so the caller can prompt the user.\n *\n * The `dryRun` flag computes the summary without touching anything.\n */\nexport const reverseManifest = async (\n manifest: FeatureManifest,\n projectPath: string,\n options: { dryRun?: boolean } = {},\n): Promise<RemoveSummary> => {\n const dryRun = options.dryRun ?? false;\n const summary: RemoveSummary = {\n filesRemoved: [],\n packagesUninstalled: [],\n scriptsRemoved: [],\n blocksStripped: [],\n manualCleanup: [],\n };\n\n // 1. Strip code blocks first \u2014 they reference files/packages we may delete next.\n for (const injection of manifest.injections) {\n const filePath = path.join(projectPath, injection.file);\n if (!fileExists(filePath)) continue;\n if (!injection.removePattern) {\n summary.manualCleanup.push({ file: injection.file, description: injection.description });\n continue;\n }\n const content = await readFile(filePath);\n if (!injection.presence.test(content)) continue;\n\n // RemoveTransform supports two shapes \u2014 RegExp for simple replace, or a\n // function that returns the transformed content (or null to bail out to\n // manual cleanup when the file shape has drifted from expectations).\n let stripped: string;\n if (typeof injection.removePattern === 'function') {\n const out = injection.removePattern(content);\n if (out === null) {\n summary.manualCleanup.push({ file: injection.file, description: injection.description });\n continue;\n }\n stripped = out;\n } else {\n stripped = content.replace(injection.removePattern, '');\n }\n\n if (stripped !== content) {\n if (!dryRun) await writeFile(filePath, stripped);\n summary.blocksStripped.push({ file: injection.file, description: injection.description });\n } else {\n summary.manualCleanup.push({ file: injection.file, description: injection.description });\n }\n }\n\n // 2. Remove files we generated. Directories flagged as\n // `containsUserContent` are NEVER deleted \u2014 they're listed as manual\n // cleanup so the user can migrate their content first. This guards\n // against e.g. `remove i18n` wiping every page under src/app/[locale]/.\n const { rm } = await import('node:fs/promises');\n for (const file of manifest.files) {\n if (!file.generated) continue;\n const target = path.join(projectPath, file.path);\n if (!fileExists(target)) continue;\n if (file.containsUserContent) {\n const description = file.removeHint\n ? `${file.path} \u2014 ${file.removeHint}`\n : `${file.path} (may contain user-authored files; review before deleting)`;\n summary.manualCleanup.push({ file: file.path, description });\n continue;\n }\n if (!dryRun) {\n await rm(target, { recursive: true, force: true });\n }\n summary.filesRemoved.push(file.path);\n }\n\n // 3. Update package.json: scripts + deps.\n const pkg = await readPackageJson(projectPath);\n if (pkg) {\n let touched = false;\n if (pkg.scripts) {\n for (const script of manifest.scripts) {\n if (pkg.scripts[script.name]) {\n if (!dryRun) delete pkg.scripts[script.name];\n summary.scriptsRemoved.push(script.name);\n touched = true;\n }\n }\n }\n\n for (const dep of manifest.packages) {\n const map = depsFor(pkg, dep.kind);\n if (map[dep.name]) {\n summary.packagesUninstalled.push(dep.name);\n }\n }\n\n if (touched && !dryRun) {\n await writePackageJson(projectPath, pkg);\n }\n }\n\n // 4. Run the package manager uninstall (skipped on dry-run).\n if (!dryRun && summary.packagesUninstalled.length > 0) {\n const manager = await detectPackageManager(projectPath);\n await uninstallPackages(projectPath, manager, summary.packagesUninstalled);\n }\n\n return summary;\n};\n", "/**\n * Central registry of feature manifests. `doctor` and `remove` walk this\n * registry; `setup` imports individual manifests when it needs `apply`.\n */\n\nimport { bundleAnalyzerManifest } from './bundle-analyzer.manifest';\nimport { commitizenManifest } from './commitizen.manifest';\nimport { darkThemeManifest } from './dark-theme.manifest';\nimport { httpClientManifest } from './http-client.manifest';\nimport { i18nManifest } from './i18n.manifest';\nimport { reactCompilerManifest } from './react-compiler.manifest';\nimport { reduxManifest } from './redux.manifest';\nimport { securityHeadersManifest } from './security-headers.manifest';\nimport { testsManifest } from './tests.manifest';\nimport type { FeatureManifest } from './types';\nimport { validateScriptsManifest } from './validate-scripts.manifest';\n\nexport type { RemoveSummary } from './runner';\nexport { checkManifest, reverseManifest } from './runner';\nexport type {\n CodeBlockRequirement,\n DepKind,\n FeatureCheckResult,\n FeatureFinding,\n FeatureManifest,\n FileRequirement,\n PackageRequirement,\n ScriptRequirement,\n} from './types';\n\n/** Ordered for sensible doctor output: simple/visible features first. */\nexport const MANIFESTS: ReadonlyArray<FeatureManifest> = [\n securityHeadersManifest,\n validateScriptsManifest,\n commitizenManifest,\n reactCompilerManifest,\n bundleAnalyzerManifest,\n testsManifest,\n darkThemeManifest,\n httpClientManifest,\n reduxManifest,\n i18nManifest,\n];\n\nexport const getManifest = (id: string): FeatureManifest | undefined =>\n MANIFESTS.find((m) => m.id === id);\n\nexport {\n bundleAnalyzerManifest,\n commitizenManifest,\n darkThemeManifest,\n httpClientManifest,\n i18nManifest,\n reactCompilerManifest,\n reduxManifest,\n securityHeadersManifest,\n testsManifest,\n validateScriptsManifest,\n};\n", "import type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport {\n addEnvVar,\n type EnvVarSpec,\n type EnvVarType,\n ensurePublicPrefix,\n} from '../modifiers/env-var.modifier';\n\ninterface EnvCommandOptions {\n type?: string;\n required?: boolean;\n default?: string;\n public?: boolean;\n describe?: string;\n enum?: string;\n}\n\nconst VALID_TYPES: ReadonlySet<EnvVarType> = new Set([\n 'string',\n 'url',\n 'number',\n 'boolean',\n 'enum',\n]);\n\nconst parseType = (raw: string | undefined): EnvVarType => {\n const value = (raw ?? 'string').toLowerCase() as EnvVarType;\n if (!VALID_TYPES.has(value)) {\n throw new Error(`Invalid --type \"${raw}\". Valid: ${Array.from(VALID_TYPES).join(', ')}.`);\n }\n return value;\n};\n\nconst parseEnum = (raw: string | undefined): string[] | undefined => {\n if (!raw) return undefined;\n const values = raw\n .split(',')\n .map((v) => v.trim())\n .filter(Boolean);\n return values.length === 0 ? undefined : values;\n};\n\nexport const registerEnvCommand = (program: Command) => {\n program\n .command('env <NAME>')\n .description('Declare a new environment variable across schema, .env.example, and .env')\n .option('--type <type>', 'Zod type (string|url|number|boolean|enum)', 'string')\n .option('--required', 'Make the variable required (no .optional() / .default())')\n .option('--default <value>', 'Set a default value (mutually exclusive with --required)')\n .option('--public', 'Mark as public (auto-prefix NEXT_PUBLIC_ and tag .env.example)')\n .option('--describe <text>', 'Description (rendered as .describe() and .env.example comment)')\n .option('--enum <list>', 'Comma-separated values when --type=enum (e.g. \"dev,prod\")')\n .action(async (name: string, options: EnvCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\n log(pc.cyan('\\n\uD83D\uDD10 Env Var Generator\\n'));\n\n if (options.required && options.default !== undefined) {\n throw new Error('--required and --default are mutually exclusive.');\n }\n\n const type = parseType(options.type);\n const enumValues = parseEnum(options.enum);\n if (type === 'enum' && (!enumValues || enumValues.length === 0)) {\n throw new Error('--type=enum requires at least one value via --enum a,b,c.');\n }\n\n const spec: EnvVarSpec = {\n name,\n type,\n required: !!options.required,\n default: options.default,\n description: options.describe,\n enumValues,\n public: !!options.public,\n };\n\n spinner.start('Updating schema, .env.example, and .env...');\n const result = await addEnvVar(projectPath, spec);\n spinner.succeed('Env var written');\n\n const fullName = ensurePublicPrefix(spec.name, spec.public);\n log(pc.green(`\\n\u2728 ${fullName} declared.\\n`));\n log(pc.dim('Touched:'));\n log(pc.dim(` ${result.schemaUpdated ? '\u270F\uFE0F ' : '\u23ED '} src/lib/env/schema.ts`));\n log(pc.dim(` ${result.envExampleUpdated ? '\u270F\uFE0F ' : '\u23ED '} .env.example`));\n log(pc.dim(` ${result.envUpdated ? '\u270F\uFE0F ' : '\u23ED '} .env`));\n log('');\n } catch (error) {\n spinner.fail('Env var declaration failed');\n logError(`${error instanceof Error ? error.message : error}`);\n process.exit(1);\n }\n });\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../config/paths';\nimport { fileExists, readFile, writeFile } from '../core/files';\n\n/**\n * Adds a new environment variable across the four files that the starter\n * keeps in sync: `.env.example`, `.env` (when present), the Zod\n * `envSchema`, and the typed config. Each transformation is pure and\n * idempotent so the orchestrator can call them in any order without\n * worrying about duplicate writes.\n */\n\nexport type EnvVarType = 'string' | 'url' | 'number' | 'boolean' | 'enum';\n\nexport interface EnvVarSpec {\n /** UPPER_SNAKE_CASE identifier as it will appear in the schema and `.env`. */\n name: string;\n type: EnvVarType;\n required: boolean;\n /** When set, the schema gets `.default(...)` and `.env`/`.env.example` get this initial value. */\n default?: string;\n description?: string;\n /** Allowed values when `type === 'enum'`. */\n enumValues?: string[];\n /** When true, mark the value as public (visible to the browser via `# -public` and the NEXT_PUBLIC_ prefix). */\n public: boolean;\n}\n\nconst NAME_RE = /^[A-Z][A-Z0-9_]*$/;\n\nexport const validateName = (name: string): void => {\n if (!NAME_RE.test(name)) {\n throw new Error(\n `Invalid env var name \"${name}\". Use UPPER_SNAKE_CASE (e.g. SENTRY_DSN, NEXT_PUBLIC_API_URL).`,\n );\n }\n};\n\nexport const ensurePublicPrefix = (name: string, isPublic: boolean): string => {\n if (!isPublic) return name;\n return name.startsWith('NEXT_PUBLIC_') ? name : `NEXT_PUBLIC_${name}`;\n};\n\nconst formatDefault = (spec: EnvVarSpec): string => {\n if (spec.default === undefined) return '';\n switch (spec.type) {\n case 'number':\n return `.default(${Number(spec.default)})`;\n case 'boolean':\n return `.default(${spec.default === 'true'})`;\n default:\n return `.default('${spec.default.replace(/'/g, \"\\\\'\")}')`;\n }\n};\n\nconst baseSchemaTypeFor = (spec: EnvVarSpec): string => {\n switch (spec.type) {\n case 'url':\n return 'z.url()';\n case 'number':\n return 'z.coerce.number()';\n case 'boolean':\n return 'z.coerce.boolean()';\n case 'enum': {\n const values = spec.enumValues ?? [];\n if (values.length === 0) {\n throw new Error(`Enum env var \"${spec.name}\" requires --enum values.`);\n }\n const formatted = values.map((v) => `'${v.replace(/'/g, \"\\\\'\")}'`).join(', ');\n return `z.enum([${formatted}])`;\n }\n case 'string':\n default:\n return 'z.string()';\n }\n};\n\n/**\n * Build the line that goes inside `envSchema = z.object({ ... })`.\n *\n * Mirrors the starter's house style: numeric/string types get the\n * `preprocess(emptyStringToUndefined, \u2026)` wrapper so empty values in `.env`\n * don't pre-empt zod defaults; enums skip it because they reject empty\n * strings outright anyway.\n */\nexport const buildSchemaEntry = (spec: EnvVarSpec): string => {\n const fullName = ensurePublicPrefix(spec.name, spec.public);\n const base = baseSchemaTypeFor(spec);\n\n let inner = base;\n const hasDefault = spec.default !== undefined;\n const optional = !spec.required && !hasDefault;\n if (hasDefault) inner += formatDefault(spec);\n if (optional && spec.type !== 'enum') inner += '.optional()';\n\n let expression: string;\n if (spec.type === 'enum') {\n expression = inner;\n } else {\n expression = `z.preprocess(emptyStringToUndefined, ${inner})`;\n }\n\n if (spec.description) {\n const escaped = spec.description.replace(/'/g, \"\\\\'\");\n expression += `\\n .describe('${escaped}')`;\n }\n\n return ` ${fullName}: ${expression},`;\n};\n\nconst ENV_SCHEMA_RE = /(export const envSchema\\s*=\\s*z\\.object\\(\\{)([\\s\\S]*?)(\\}\\);?)/;\n\n/**\n * Insert a new entry into `envSchema = z.object({ ... })`. Preserves the\n * existing trailing newline shape and is idempotent.\n */\nexport const injectSchemaEntry = (content: string, spec: EnvVarSpec): string => {\n const fullName = ensurePublicPrefix(spec.name, spec.public);\n const presentRe = new RegExp(`\\\\b${fullName}\\\\s*:`);\n if (presentRe.test(content)) return content;\n\n const match = content.match(ENV_SCHEMA_RE);\n if (!match) {\n throw new Error('Could not locate `export const envSchema = z.object({ \u2026 })` in schema.ts.');\n }\n\n const [, head, body, tail] = match;\n const trimmedBody = body.replace(/\\s+$/, '');\n // Ensure prior entry ends with a comma so we don't end up with `foo: zX\\n NEW`\n const normalisedBody =\n trimmedBody.length === 0 || /,\\s*$/.test(trimmedBody) ? trimmedBody : `${trimmedBody},`;\n const entry = buildSchemaEntry(spec);\n const newBody = `${normalisedBody}\\n${entry}\\n`;\n return content.replace(ENV_SCHEMA_RE, `${head}${newBody}${tail}`);\n};\n\nconst PUBLIC_MARKER_SUFFIX = '# -public';\n\nconst exampleLineFor = (spec: EnvVarSpec): string => {\n const fullName = ensurePublicPrefix(spec.name, spec.public);\n const value = spec.default ?? '';\n const trailing = spec.public ? ` ${PUBLIC_MARKER_SUFFIX}` : '';\n return `${fullName}=${value}${trailing}`;\n};\n\n/**\n * Append a `KEY=` (or `KEY=defaultValue`) line to the .env.example contents.\n * Adds an optional comment line for the description. Idempotent.\n */\nexport const appendEnvExampleEntry = (content: string, spec: EnvVarSpec): string => {\n const fullName = ensurePublicPrefix(spec.name, spec.public);\n const lineRe = new RegExp(`^${fullName}=`, 'm');\n if (lineRe.test(content)) return content;\n\n const trailingNewline = content === '' || content.endsWith('\\n') ? '' : '\\n';\n const blank = content === '' ? '' : '\\n';\n const description = spec.description ? `# ${spec.description}\\n` : '';\n return `${content}${trailingNewline}${blank}${description}${exampleLineFor(spec)}\\n`;\n};\n\n/**\n * Mirror of `appendEnvExampleEntry` for `.env`. Always uses the spec default\n * (or empty) so secrets aren't leaked into the example file by mistake.\n * Idempotent.\n */\nexport const appendEnvEntry = (content: string, spec: EnvVarSpec): string => {\n const fullName = ensurePublicPrefix(spec.name, spec.public);\n const lineRe = new RegExp(`^${fullName}=`, 'm');\n if (lineRe.test(content)) return content;\n\n const trailingNewline = content === '' || content.endsWith('\\n') ? '' : '\\n';\n const value = spec.default ?? '';\n return `${content}${trailingNewline}${fullName}=${value}\\n`;\n};\n\nexport interface AddEnvVarResult {\n schemaUpdated: boolean;\n envExampleUpdated: boolean;\n envUpdated: boolean;\n}\n\n/**\n * Orchestrates the four-file update. Each step is independently idempotent\n * so partial failures are easy to recover from \u2014 re-running picks up where\n * the previous run left off.\n */\nexport const addEnvVar = async (\n projectPath: string,\n spec: EnvVarSpec,\n): Promise<AddEnvVarResult> => {\n validateName(spec.name);\n\n const schemaPath = path.join(projectPath, 'src/lib/env/schema.ts');\n if (!fileExists(schemaPath)) {\n throw new Error(`src/lib/env/schema.ts not found \u2014 run \\`next-maker init\\` first.`);\n }\n\n const schemaBefore = await readFile(schemaPath);\n const schemaAfter = injectSchemaEntry(schemaBefore, spec);\n const schemaUpdated = schemaAfter !== schemaBefore;\n if (schemaUpdated) await writeFile(schemaPath, schemaAfter);\n\n const envExamplePath = path.join(projectPath, PROJECT_PATHS.ENV_EXAMPLE);\n let envExampleUpdated = false;\n if (fileExists(envExamplePath)) {\n const before = await readFile(envExamplePath);\n const after = appendEnvExampleEntry(before, spec);\n envExampleUpdated = after !== before;\n if (envExampleUpdated) await writeFile(envExamplePath, after);\n }\n\n const envPath = path.join(projectPath, '.env');\n let envUpdated = false;\n if (fileExists(envPath)) {\n const before = await readFile(envPath);\n const after = appendEnvEntry(before, spec);\n envUpdated = after !== before;\n if (envUpdated) await writeFile(envPath, after);\n }\n\n return { schemaUpdated, envExampleUpdated, envUpdated };\n};\n", "import path from 'node:path';\nimport type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner, warning } from '../config';\nimport { promptForFaviconSource } from '../prompts/favicon.prompt';\nimport { detectAppDir, runFavicon } from '../services/favicon';\nimport { CSS_NAMED_COLORS } from '../services/favicon/css-colors';\nimport type { FaviconFit, FaviconOptions, FaviconShape } from '../services/favicon/types';\nimport { parseSizes } from '../services/favicon/validate';\n\ninterface RawFaviconCliOptions {\n path?: string;\n out?: string;\n force?: boolean;\n dryRun?: boolean;\n\n icon?: boolean;\n apple?: boolean;\n og?: boolean;\n ogSource?: string;\n twitter?: boolean;\n all?: boolean;\n\n pwa?: boolean;\n pwaInit?: boolean;\n\n shape?: string;\n radius?: string;\n bg?: string;\n padding?: string;\n fit?: string;\n sizes?: string;\n quality?: string;\n}\n\nconst SHAPES: FaviconShape[] = ['square', 'rounded', 'circle', 'squircle'];\nconst FITS: FaviconFit[] = ['contain', 'cover', 'clip'];\n\nconst parseEnumOption = <T extends string>(\n raw: string | undefined,\n allowed: T[],\n fallback: T,\n flag: string,\n): T => {\n if (!raw) return fallback;\n if (!allowed.includes(raw as T)) {\n throw new Error(`Invalid value for --${flag}: '${raw}'. Allowed: ${allowed.join(', ')}`);\n }\n return raw as T;\n};\n\nconst parseNumberOption = (\n raw: string | undefined,\n fallback: number,\n flag: string,\n min: number,\n max: number,\n): number => {\n if (raw === undefined) return fallback;\n const n = Number(raw);\n if (!Number.isFinite(n) || n < min || n > max) {\n throw new Error(\n `Invalid value for --${flag}: '${raw}'. Must be a number between ${min}\u2013${max}.`,\n );\n }\n return n;\n};\n\nexport const registerFaviconCommand = (program: Command) => {\n program\n .command('favicon')\n .description('Generate favicon.ico (and optionally icons, OG image, PWA manifest icons)')\n .option('--path <file>', 'Path to source image (PNG, JPG, JPEG, WebP, SVG, AVIF)')\n .option('--out <dir>', 'Output dir (default: src/app or app)')\n .option('--force', 'Overwrite existing files without prompt', false)\n .option('--dry-run', 'Show what would be written without writing', false)\n .option('--icon', 'Also emit icon.png (512\u00D7512)', false)\n .option('--apple', 'Also emit apple-icon.png (180\u00D7180)', false)\n .option('--og', 'Also emit opengraph-image.png (1200\u00D7630)', false)\n .option('--og-source <file>', 'Use a separate image for the OG/Twitter card')\n .option('--twitter', 'Also emit twitter-image.png (1200\u00D7600)', false)\n .option('--all', 'Shorthand for --icon --apple --og', false)\n .option(\n '--pwa',\n 'Detect PWA setup and emit manifest icons (192/512); errors if not detected',\n false,\n )\n .option('--pwa-init', 'Bootstrap public/manifest.webmanifest with icons', false)\n .option('--shape <shape>', 'square | rounded | circle | squircle', 'square')\n .option('--radius <percent>', 'Corner radius % when shape=rounded (0-50)', '20')\n .option('--bg <color>', 'Background color (hex, css name, or \"transparent\")', 'transparent')\n .option('--padding <percent>', 'Padding around source content (0-30)', '0')\n .option('--fit <fit>', 'How source fits target: contain | cover | clip', 'contain')\n .option('--sizes <list>', 'Comma-separated ICO sizes (default: 16,32,48)')\n .option(\n '--quality <n>',\n 'PNG compression 1-100 (higher = smaller file; PNG is lossless, default: 90)',\n '90',\n )\n .action(async (raw: RawFaviconCliOptions) => {\n try {\n const projectPath = process.cwd();\n\n log(pc.cyan('\\n\uD83C\uDFA8 Favicon Generator\\n'));\n\n const promptResult = await promptForFaviconSource({ source: raw.path });\n\n const outDir = await resolveOutDir(projectPath, raw.out);\n const shape = parseEnumOption(raw.shape, SHAPES, 'square', 'shape');\n const fit = parseEnumOption(raw.fit, FITS, 'contain', 'fit');\n const radius = parseNumberOption(raw.radius, 20, 'radius', 0, 50);\n const padding = parseNumberOption(raw.padding, 0, 'padding', 0, 30);\n const quality = parseNumberOption(raw.quality, 90, 'quality', 1, 100);\n const icoSizes = parseSizes(raw.sizes, [16, 32, 48]);\n const bg = raw.bg ?? 'transparent';\n validateBg(bg);\n\n const all = raw.all === true;\n const options: FaviconOptions = {\n source: promptResult.source,\n outDir,\n force: !!raw.force,\n dryRun: !!raw.dryRun,\n emitIcon: !!raw.icon || all,\n emitApple: !!raw.apple || all,\n emitOg: !!raw.og || all,\n emitTwitter: !!raw.twitter,\n ogSource: raw.ogSource,\n pwa: !!raw.pwa,\n pwaInit: !!raw.pwaInit,\n shape,\n radius,\n bg,\n padding,\n fit,\n icoSizes,\n quality,\n };\n\n spinner.start('Generating favicon assets...');\n const result = await runFavicon(projectPath, options);\n spinner.succeed(options.dryRun ? 'Favicon plan ready' : 'Favicon assets generated');\n\n log('');\n for (const out of result.outputs) {\n const rel = path.relative(projectPath, out.path);\n if (out.skipped) {\n log(pc.yellow(` \u21B7 skipped ${rel} (exists; use --force to overwrite)`));\n } else if (options.dryRun) {\n log(pc.dim(` \uD83D\uDCC4 would write ${rel} (${formatBytes(out.bytes)})`));\n } else {\n log(pc.green(` \u2713 ${rel} `) + pc.dim(`(${formatBytes(out.bytes)})`));\n }\n }\n\n if (result.pwaSnippet) {\n log('');\n log(pc.cyan('Add this to your typed manifest (src/app/manifest.ts):'));\n log(pc.dim(result.pwaSnippet));\n }\n\n log('');\n } catch (err) {\n spinner.fail('Favicon generation failed');\n const message = err instanceof Error ? err.message : String(err);\n logError(message);\n process.exit(1);\n }\n });\n};\n\nconst resolveOutDir = async (projectPath: string, override?: string): Promise<string> => {\n if (override) return path.isAbsolute(override) ? override : path.resolve(projectPath, override);\n const detected = await detectAppDir(projectPath);\n if (detected) return detected;\n warning('Could not detect app/ or src/app/ \u2014 falling back to src/app');\n return path.join(projectPath, 'src', 'app');\n};\n\nconst HEX_RE = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;\nconst FUNCTIONAL_RE = /^(?:rgb|rgba|hsl|hsla)\\(\\s*[\\d.,%\\s/]+\\)$/i;\n\nconst validateBg = (bg: string): void => {\n if (bg === 'transparent') return;\n if (HEX_RE.test(bg)) return;\n if (FUNCTIONAL_RE.test(bg)) return;\n if (CSS_NAMED_COLORS.has(bg.toLowerCase())) return;\n throw new Error(\n `Invalid value for --bg: '${bg}'. Use 'transparent', a hex code (e.g. #0f172a), a CSS color name, or rgb()/rgba()/hsl()/hsla().`,\n );\n};\n\nconst formatBytes = (n: number): string => {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n return `${(n / 1024 / 1024).toFixed(2)} MB`;\n};\n", "import Enquirer from 'enquirer';\n\nconst { prompt } = Enquirer;\n\nexport interface FaviconPromptResult {\n source: string;\n}\n\nexport const promptForFaviconSource = async (\n presets: { source?: string } = {},\n): Promise<FaviconPromptResult> => {\n if (presets.source) return { source: presets.source };\n\n const answer = (await prompt({\n type: 'input',\n name: 'source',\n message: 'Path to source image (PNG/JPG/JPEG/SVG/WebP/AVIF):',\n validate: (value: string) => {\n if (!value) return 'Source path is required';\n return true;\n },\n })) as { source: string };\n\n return { source: answer.source };\n};\n", "import { access, readFile, stat } from 'node:fs/promises';\nimport path from 'node:path';\n\nconst exists = async (p: string): Promise<boolean> => {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n};\n\nconst isDirectory = async (p: string): Promise<boolean> => {\n try {\n return (await stat(p)).isDirectory();\n } catch {\n return false;\n }\n};\n\n/**\n * Resolve the App Router directory for metadata files.\n * Prefers `src/app`, falls back to `app`. Returns absolute path.\n */\nexport const detectAppDir = async (projectPath: string): Promise<string | null> => {\n const candidates = [path.join(projectPath, 'src', 'app'), path.join(projectPath, 'app')];\n for (const candidate of candidates) {\n if (await isDirectory(candidate)) return candidate;\n }\n return null;\n};\n\nexport interface PwaDetection {\n isPwa: boolean;\n /** Path to a static manifest file (json/webmanifest) if present in /public. */\n publicManifestPath?: string;\n /** Path to a typed `manifest.ts`/`manifest.tsx` in app dir if present. */\n appManifestPath?: string;\n /** Detected PWA framework, if any. */\n framework?: 'next-pwa' | '@ducanh2912/next-pwa' | '@serwist/next' | 'serwist';\n}\n\nconst PWA_PACKAGES = ['next-pwa', '@ducanh2912/next-pwa', '@serwist/next', 'serwist'] as const;\n\nexport const detectPwa = async (projectPath: string): Promise<PwaDetection> => {\n const result: PwaDetection = { isPwa: false };\n\n // Static manifest in /public\n const publicCandidates = [\n path.join(projectPath, 'public', 'manifest.json'),\n path.join(projectPath, 'public', 'manifest.webmanifest'),\n path.join(projectPath, 'public', 'site.webmanifest'),\n ];\n for (const p of publicCandidates) {\n if (await exists(p)) {\n result.publicManifestPath = p;\n result.isPwa = true;\n break;\n }\n }\n\n // Typed manifest in app dir\n const appDir = await detectAppDir(projectPath);\n if (appDir) {\n for (const ext of ['ts', 'tsx', 'js']) {\n const candidate = path.join(appDir, `manifest.${ext}`);\n if (await exists(candidate)) {\n result.appManifestPath = candidate;\n result.isPwa = true;\n break;\n }\n }\n }\n\n // Package-based detection\n try {\n const pkg = JSON.parse(await readFile(path.join(projectPath, 'package.json'), 'utf-8'));\n const deps = { ...pkg.dependencies, ...pkg.devDependencies } as Record<string, string>;\n for (const name of PWA_PACKAGES) {\n if (deps[name]) {\n result.framework = name;\n result.isPwa = true;\n break;\n }\n }\n } catch {\n /* no package.json \u2014 skip */\n }\n\n return result;\n};\n", "import { mkdir, readFile, stat, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport sharp from 'sharp';\nimport { detectPwa } from './detect';\nimport { encodeIco, flatColor, renderPng } from './encoders';\nimport {\n buildBootstrapManifest,\n buildIconEntries,\n patchJsonManifest,\n renderManifestSnippet,\n} from './manifest';\nimport type { FaviconOptions, FaviconRunResult, FaviconWriteResult } from './types';\nimport { validateSource } from './validate';\n\nconst fileExists = async (p: string): Promise<boolean> => {\n try {\n await stat(p);\n return true;\n } catch {\n return false;\n }\n};\n\ninterface WriteJob {\n outPath: string;\n bytes: Buffer;\n /** When true, overwrite even if the target exists and --force is not set. */\n alwaysWrite?: boolean;\n}\n\nconst writeAll = async (\n jobs: WriteJob[],\n force: boolean,\n dryRun: boolean,\n): Promise<FaviconWriteResult[]> => {\n const results: FaviconWriteResult[] = [];\n for (const job of jobs) {\n const exists = await fileExists(job.outPath);\n if (exists && !force && !job.alwaysWrite) {\n results.push({ path: job.outPath, bytes: job.bytes.length, skipped: true });\n continue;\n }\n if (!dryRun) {\n await mkdir(path.dirname(job.outPath), { recursive: true });\n await writeFile(job.outPath, job.bytes);\n }\n results.push({ path: job.outPath, bytes: job.bytes.length });\n }\n return results;\n};\n\nexport const runFavicon = async (\n projectPath: string,\n options: FaviconOptions,\n): Promise<FaviconRunResult> => {\n const source = await validateSource(options.source);\n const sourceBuffer = await readFile(source.absolutePath);\n const ogSourceBuffer = options.ogSource\n ? await readFile((await validateSource(options.ogSource)).absolutePath)\n : sourceBuffer;\n\n const jobs: WriteJob[] = [];\n\n // 1. favicon.ico \u2014 always, multi-size, square\n const icoFrames: Buffer[] = [];\n for (const size of options.icoSizes) {\n icoFrames.push(\n await renderPng({\n sourceBuffer,\n size,\n shape: 'square',\n radiusPercent: options.radius,\n bg: options.bg,\n paddingPercent: options.padding,\n fit: options.fit,\n quality: options.quality,\n forceSquare: true,\n }),\n );\n }\n const icoBuffer = await encodeIco(icoFrames);\n jobs.push({ outPath: path.join(options.outDir, 'favicon.ico'), bytes: icoBuffer });\n\n // 2. icon.png (512\u00D7512)\n if (options.emitIcon) {\n const buf = await renderPng({\n sourceBuffer,\n size: 512,\n shape: options.shape,\n radiusPercent: options.radius,\n bg: options.bg,\n paddingPercent: options.padding,\n fit: options.fit,\n quality: options.quality,\n });\n jobs.push({ outPath: path.join(options.outDir, 'icon.png'), bytes: buf });\n }\n\n // 3. apple-icon.png (180\u00D7180, opaque bg per Apple guidelines)\n if (options.emitApple) {\n const appleBg = options.bg === 'transparent' ? '#ffffff' : options.bg;\n const buf = await renderPng({\n sourceBuffer,\n size: 180,\n shape: options.shape,\n radiusPercent: options.radius,\n bg: appleBg,\n paddingPercent: options.padding,\n fit: options.fit,\n quality: options.quality,\n });\n jobs.push({ outPath: path.join(options.outDir, 'apple-icon.png'), bytes: buf });\n }\n\n // 4. opengraph-image.png (1200\u00D7630, contained on bg)\n if (options.emitOg) {\n const buf = await renderOgImage(ogSourceBuffer, options, false);\n jobs.push({ outPath: path.join(options.outDir, 'opengraph-image.png'), bytes: buf });\n }\n\n // 5. twitter-image.png (1200\u00D7600)\n if (options.emitTwitter) {\n const buf = await renderOgImage(ogSourceBuffer, options, true);\n jobs.push({ outPath: path.join(options.outDir, 'twitter-image.png'), bytes: buf });\n }\n\n // 6. PWA icons + manifest\n let pwaSnippet: string | undefined;\n if (options.pwa || options.pwaInit) {\n const pwa = await detectPwa(projectPath);\n if (options.pwa && !pwa.isPwa) {\n throw new Error(\n 'No PWA setup detected. Use --pwa-init to bootstrap a manifest, or set up next-pwa/serwist first.',\n );\n }\n\n const publicDir = path.join(projectPath, 'public');\n const sizes = [192, 512];\n const iconJobs: { src: string; size: number }[] = [];\n for (const size of sizes) {\n const buf = await renderPng({\n sourceBuffer,\n size,\n shape: options.shape,\n radiusPercent: options.radius,\n bg: options.bg,\n paddingPercent: options.padding,\n fit: options.fit,\n quality: options.quality,\n });\n const fileName = `icon-${size}.png`;\n jobs.push({ outPath: path.join(publicDir, fileName), bytes: buf });\n iconJobs.push({ src: `/${fileName}`, size });\n }\n\n const icons = buildIconEntries(iconJobs);\n if (pwa.publicManifestPath) {\n // Patched manifest merges with existing content, so always write it back.\n const next = await patchJsonManifest(pwa.publicManifestPath, icons);\n jobs.push({\n outPath: pwa.publicManifestPath,\n bytes: Buffer.from(next, 'utf-8'),\n alwaysWrite: true,\n });\n } else if (pwa.appManifestPath) {\n pwaSnippet = renderManifestSnippet(icons);\n } else if (options.pwaInit) {\n const bootstrapPath = path.join(publicDir, 'manifest.webmanifest');\n const content = buildBootstrapManifest(path.basename(projectPath) || 'App', '#000000', icons);\n jobs.push({ outPath: bootstrapPath, bytes: Buffer.from(content, 'utf-8') });\n }\n }\n\n const outputs = await writeAll(jobs, options.force, options.dryRun);\n return { outputs, pwaSnippet };\n};\n\nconst renderOgImage = async (\n sourceBuffer: Buffer,\n options: FaviconOptions,\n isTwitter: boolean,\n): Promise<Buffer> => {\n const targetWidth = 1200;\n const targetHeight = isTwitter ? 600 : 630;\n const innerSize = Math.round(\n Math.min(targetWidth, targetHeight) * (1 - (options.padding * 2) / 100),\n );\n\n const inner = await renderPng({\n sourceBuffer,\n size: innerSize,\n shape: options.shape,\n radiusPercent: options.radius,\n bg: 'transparent',\n paddingPercent: 0,\n fit: options.fit,\n quality: options.quality,\n });\n\n const bgColor = options.bg === 'transparent' ? '#ffffff' : options.bg;\n const background = await flatColor(bgColor);\n const offsetLeft = Math.round((targetWidth - innerSize) / 2);\n const offsetTop = Math.round((targetHeight - innerSize) / 2);\n\n return sharp({\n create: {\n width: targetWidth,\n height: targetHeight,\n channels: 4,\n background,\n },\n })\n .composite([{ input: inner, left: offsetLeft, top: offsetTop }])\n .png()\n .toBuffer();\n};\n", "import pngToIco from 'png-to-ico';\nimport sharp from 'sharp';\nimport { buildBackground, buildShapeMask } from './shapes';\nimport type { FaviconFit, FaviconShape } from './types';\n\nexport interface RenderOptions {\n /** Pre-loaded source bytes \u2014 read once by the pipeline and reused per size. */\n sourceBuffer: Buffer;\n size: number;\n shape: FaviconShape;\n radiusPercent: number;\n bg: string;\n paddingPercent: number;\n fit: FaviconFit;\n /** PNG compression level mapped 1..100 \u2192 9..0; lossless, affects file size only. */\n quality: number;\n /** When true, never apply shape clipping (used for ICO frames). */\n forceSquare?: boolean;\n}\n\nexport const renderPng = async (opts: RenderOptions): Promise<Buffer> => {\n const {\n size,\n paddingPercent,\n bg,\n fit,\n shape,\n radiusPercent,\n quality,\n forceSquare,\n sourceBuffer,\n } = opts;\n\n const innerSize = Math.max(1, Math.round(size * (1 - (paddingPercent * 2) / 100)));\n\n const sharpFit = fit === 'cover' ? 'cover' : 'contain';\n const resized = await sharp(sourceBuffer, { density: 384 })\n .resize(innerSize, innerSize, {\n fit: sharpFit,\n background: { r: 0, g: 0, b: 0, alpha: 0 },\n })\n .png()\n .toBuffer();\n\n const offset = Math.round((size - innerSize) / 2);\n const canvasBg = bg === 'transparent' ? { r: 0, g: 0, b: 0, alpha: 0 } : await flatColor(bg);\n\n let composed = await sharp({\n create: {\n width: size,\n height: size,\n channels: 4,\n background: canvasBg,\n },\n })\n .composite([{ input: resized, left: offset, top: offset }])\n .png()\n .toBuffer();\n\n // forceSquare wins absolutely \u2014 ICO frames must stay rectangular regardless of --fit.\n const shouldClip = !forceSquare && (shape !== 'square' || fit === 'clip');\n if (shouldClip) {\n const clipShape: FaviconShape = shape === 'square' ? 'rounded' : shape;\n const mask = Buffer.from(buildShapeMask(clipShape, size, radiusPercent));\n composed = await sharp(composed)\n .composite([{ input: mask, blend: 'dest-in' }])\n .png({ compressionLevel: clampCompression(quality) })\n .toBuffer();\n } else {\n composed = await sharp(composed)\n .png({ compressionLevel: clampCompression(quality) })\n .toBuffer();\n }\n\n return composed;\n};\n\nexport const flatColor = async (color: string): Promise<sharp.Color> => {\n // Use sharp to parse arbitrary CSS color via a tiny SVG \u2192 first pixel.\n const probe = await sharp(Buffer.from(buildBackground(1, color)))\n .raw()\n .toBuffer({ resolveWithObject: true });\n const [r, g, b, a = 255] = probe.data;\n return { r, g, b, alpha: a / 255 };\n};\n\nconst clampCompression = (quality: number): number => {\n // sharp PNG compressionLevel: 0 (fastest, biggest) \u2013 9 (slowest, smallest).\n // Map quality 1..100 inversely: high quality \u2192 high compression for small files.\n const n = Math.round(((100 - quality) / 100) * 9);\n return Math.max(0, Math.min(9, n));\n};\n\n/**\n * Build a multi-size ICO from a set of source PNG buffers.\n */\nexport const encodeIco = async (frames: Buffer[]): Promise<Buffer> => {\n if (frames.length === 0) throw new Error('No frames provided to encodeIco');\n return pngToIco(frames);\n};\n", "import type { FaviconShape } from './types';\n\nconst escapeForXml = (value: string): string =>\n value.replace(/&/g, '&').replace(/\"/g, '"').replace(/</g, '<');\n\n/**\n * Build an SVG mask (white shape on transparent) sized to `size` \u00D7 `size`.\n * Used as a destIn composite over the resized source to clip it to the shape.\n */\nexport const buildShapeMask = (\n shape: FaviconShape,\n size: number,\n radiusPercent: number,\n): string => {\n switch (shape) {\n case 'square':\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${size}\" height=\"${size}\"><rect width=\"${size}\" height=\"${size}\" fill=\"white\"/></svg>`;\n case 'circle': {\n const r = size / 2;\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${size}\" height=\"${size}\"><circle cx=\"${r}\" cy=\"${r}\" r=\"${r}\" fill=\"white\"/></svg>`;\n }\n case 'rounded': {\n const r = Math.round((size * radiusPercent) / 100);\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${size}\" height=\"${size}\"><rect width=\"${size}\" height=\"${size}\" rx=\"${r}\" ry=\"${r}\" fill=\"white\"/></svg>`;\n }\n case 'squircle':\n return buildSquircle(size);\n }\n};\n\n/**\n * iOS-style squircle (superellipse, n\u22484). Approximated with a cubic-bezier path.\n */\nconst buildSquircle = (size: number): string => {\n const s = size;\n const c = s * 0.225; // bezier control offset for a smooth ~iOS squircle\n const path = [\n `M 0 ${c}`,\n `C 0 0 0 0 ${c} 0`,\n `L ${s - c} 0`,\n `C ${s} 0 ${s} 0 ${s} ${c}`,\n `L ${s} ${s - c}`,\n `C ${s} ${s} ${s} ${s} ${s - c} ${s}`,\n `L ${c} ${s}`,\n `C 0 ${s} 0 ${s} 0 ${s - c}`,\n 'Z',\n ].join(' ');\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${s}\" height=\"${s}\"><path d=\"${escapeForXml(path)}\" fill=\"white\"/></svg>`;\n};\n\n/**\n * Build a flat-color background SVG of the given size.\n */\nexport const buildBackground = (size: number, color: string): string =>\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${size}\" height=\"${size}\"><rect width=\"${size}\" height=\"${size}\" fill=\"${escapeForXml(color)}\"/></svg>`;\n", "import { readFile, writeFile } from 'node:fs/promises';\n\nexport interface ManifestIcon {\n src: string;\n sizes: string;\n type: string;\n purpose?: string;\n}\n\nexport const buildIconEntries = (publicPaths: { src: string; size: number }[]): ManifestIcon[] =>\n publicPaths.map(({ src, size }) => ({\n src,\n sizes: `${size}x${size}`,\n type: 'image/png',\n purpose: 'any maskable',\n }));\n\n/**\n * Merge new icons into a JSON manifest, deduping by `src`. Returns the\n * formatted JSON string ready to write back.\n */\nexport const patchJsonManifest = async (\n manifestPath: string,\n icons: ManifestIcon[],\n): Promise<string> => {\n const raw = await readFile(manifestPath, 'utf-8');\n const parsed = JSON.parse(raw) as { icons?: ManifestIcon[]; [key: string]: unknown };\n const existing = Array.isArray(parsed.icons) ? parsed.icons : [];\n const bySrc = new Map<string, ManifestIcon>();\n for (const icon of [...existing, ...icons]) {\n if (icon && typeof icon.src === 'string') bySrc.set(icon.src, icon);\n }\n parsed.icons = [...bySrc.values()];\n return `${JSON.stringify(parsed, null, 2)}\\n`;\n};\n\nexport const writeJsonManifest = async (\n manifestPath: string,\n icons: ManifestIcon[],\n): Promise<void> => {\n const next = await patchJsonManifest(manifestPath, icons);\n await writeFile(manifestPath, next, 'utf-8');\n};\n\n/**\n * Render a snippet the user can paste into a typed `manifest.ts`.\n */\nexport const renderManifestSnippet = (icons: ManifestIcon[]): string => {\n const body = icons\n .map(\n (icon) =>\n ` { src: '${icon.src}', sizes: '${icon.sizes}', type: '${icon.type}'${\n icon.purpose ? `, purpose: '${icon.purpose}'` : ''\n } }`,\n )\n .join(',\\n');\n return `icons: [\\n${body},\\n ],`;\n};\n\n/**\n * Bootstrap a fresh `manifest.webmanifest` for projects without one.\n */\nexport const buildBootstrapManifest = (\n appName: string,\n themeColor: string,\n icons: ManifestIcon[],\n): string => {\n const manifest = {\n name: appName,\n short_name: appName,\n start_url: '/',\n display: 'standalone',\n background_color: '#ffffff',\n theme_color: themeColor,\n icons,\n };\n return `${JSON.stringify(manifest, null, 2)}\\n`;\n};\n", "import { stat } from 'node:fs/promises';\nimport path from 'node:path';\n\nconst SUPPORTED_EXTS = ['.png', '.jpg', '.jpeg', '.webp', '.svg', '.avif'];\n\nexport interface SourceInfo {\n absolutePath: string;\n ext: string;\n bytes: number;\n isVector: boolean;\n}\n\nexport const validateSource = async (source: string): Promise<SourceInfo> => {\n if (!source) throw new Error('Source image path is required (use --path).');\n\n const absolutePath = path.isAbsolute(source) ? source : path.resolve(process.cwd(), source);\n let info: Awaited<ReturnType<typeof stat>>;\n try {\n info = await stat(absolutePath);\n } catch {\n throw new Error(`Source image not found: ${absolutePath}`);\n }\n if (!info.isFile()) throw new Error(`Source is not a file: ${absolutePath}`);\n\n const ext = path.extname(absolutePath).toLowerCase();\n if (!SUPPORTED_EXTS.includes(ext)) {\n throw new Error(`Unsupported source format '${ext}'. Use one of: ${SUPPORTED_EXTS.join(', ')}`);\n }\n\n return { absolutePath, ext, bytes: info.size, isVector: ext === '.svg' };\n};\n\nexport const isHexColor = (value: string): boolean =>\n /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(value);\n\nexport const normalizeBg = (value: string): string => {\n if (value === 'transparent') return value;\n if (isHexColor(value)) return value;\n // Allow CSS named colors as-is \u2014 sharp accepts them via composite over a flat layer.\n return value;\n};\n\nexport const parseSizes = (raw: string | undefined, fallback: number[]): number[] => {\n if (!raw) return fallback;\n const sizes = raw\n .split(',')\n .map((s) => Number.parseInt(s.trim(), 10))\n .filter((n) => Number.isFinite(n) && n > 0 && n <= 1024);\n if (sizes.length === 0) {\n throw new Error(`Invalid --sizes value: '${raw}'. Provide comma-separated positive integers.`);\n }\n return sizes;\n};\n", "/**\n * Standard CSS named colors. Used to validate --bg before passing it to sharp,\n * which silently accepts unknown strings.\n *\n * Source: https://developer.mozilla.org/en-US/docs/Web/CSS/named-color\n */\nexport const CSS_NAMED_COLORS = new Set([\n 'aliceblue',\n 'antiquewhite',\n 'aqua',\n 'aquamarine',\n 'azure',\n 'beige',\n 'bisque',\n 'black',\n 'blanchedalmond',\n 'blue',\n 'blueviolet',\n 'brown',\n 'burlywood',\n 'cadetblue',\n 'chartreuse',\n 'chocolate',\n 'coral',\n 'cornflowerblue',\n 'cornsilk',\n 'crimson',\n 'cyan',\n 'darkblue',\n 'darkcyan',\n 'darkgoldenrod',\n 'darkgray',\n 'darkgreen',\n 'darkgrey',\n 'darkkhaki',\n 'darkmagenta',\n 'darkolivegreen',\n 'darkorange',\n 'darkorchid',\n 'darkred',\n 'darksalmon',\n 'darkseagreen',\n 'darkslateblue',\n 'darkslategray',\n 'darkslategrey',\n 'darkturquoise',\n 'darkviolet',\n 'deeppink',\n 'deepskyblue',\n 'dimgray',\n 'dimgrey',\n 'dodgerblue',\n 'firebrick',\n 'floralwhite',\n 'forestgreen',\n 'fuchsia',\n 'gainsboro',\n 'ghostwhite',\n 'gold',\n 'goldenrod',\n 'gray',\n 'green',\n 'greenyellow',\n 'grey',\n 'honeydew',\n 'hotpink',\n 'indianred',\n 'indigo',\n 'ivory',\n 'khaki',\n 'lavender',\n 'lavenderblush',\n 'lawngreen',\n 'lemonchiffon',\n 'lightblue',\n 'lightcoral',\n 'lightcyan',\n 'lightgoldenrodyellow',\n 'lightgray',\n 'lightgreen',\n 'lightgrey',\n 'lightpink',\n 'lightsalmon',\n 'lightseagreen',\n 'lightskyblue',\n 'lightslategray',\n 'lightslategrey',\n 'lightsteelblue',\n 'lightyellow',\n 'lime',\n 'limegreen',\n 'linen',\n 'magenta',\n 'maroon',\n 'mediumaquamarine',\n 'mediumblue',\n 'mediumorchid',\n 'mediumpurple',\n 'mediumseagreen',\n 'mediumslateblue',\n 'mediumspringgreen',\n 'mediumturquoise',\n 'mediumvioletred',\n 'midnightblue',\n 'mintcream',\n 'mistyrose',\n 'moccasin',\n 'navajowhite',\n 'navy',\n 'oldlace',\n 'olive',\n 'olivedrab',\n 'orange',\n 'orangered',\n 'orchid',\n 'palegoldenrod',\n 'palegreen',\n 'paleturquoise',\n 'palevioletred',\n 'papayawhip',\n 'peachpuff',\n 'peru',\n 'pink',\n 'plum',\n 'powderblue',\n 'purple',\n 'rebeccapurple',\n 'red',\n 'rosybrown',\n 'royalblue',\n 'saddlebrown',\n 'salmon',\n 'sandybrown',\n 'seagreen',\n 'seashell',\n 'sienna',\n 'silver',\n 'skyblue',\n 'slateblue',\n 'slategray',\n 'slategrey',\n 'snow',\n 'springgreen',\n 'steelblue',\n 'tan',\n 'teal',\n 'thistle',\n 'tomato',\n 'turquoise',\n 'violet',\n 'wheat',\n 'white',\n 'whitesmoke',\n 'yellow',\n 'yellowgreen',\n]);\n", "import path from 'node:path';\nimport type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { directoryExists } from '../detection';\nimport { createFeaturePipelineSteps, executePipeline } from '../pipelines';\nimport { promptForFeatureDetails } from '../prompts/feature.prompt';\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 validateFeatureOptions(options);\n\n log(pc.cyan('\\n\uD83C\uDFAF Feature Generator\\n'));\n\n // Detect & prompt\n const steps = createFeaturePipelineSteps();\n spinner.start('Detecting project setup...');\n const { detectProjectSetup } = await import('../detection');\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 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 const basePath = options.path || path.join('src', 'features');\n const featurePath = path.join(projectPath, basePath, featureOptions.featureName);\n\n const exists = await directoryExists(projectPath, featureOptions.featureName, basePath);\n if (exists) {\n logError(`Feature '${featureOptions.featureName}' already exists at ${basePath}!`);\n process.exit(1);\n }\n\n // Execute generation pipeline (generate \u2192 register API \u2192 register reducer)\n await executePipeline(steps.slice(1), {\n projectPath,\n spinner,\n featureName: featureOptions.featureName,\n basePath,\n featurePath,\n createStore: featureOptions.createStore,\n persistStore: featureOptions.persistStore,\n createService: featureOptions.createService,\n httpClient: featureOptions.selectedHttpClient,\n detection,\n });\n\n printFeatureSuccess(featureOptions, basePath);\n } catch (error) {\n spinner.fail('Feature generation failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n\nconst validateFeatureOptions = (options: FeatureCommandOptions) => {\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 if (options.service && !['axios', 'fetch'].includes(options.service)) {\n logError('Invalid --service option. Use: axios or fetch');\n process.exit(1);\n }\n if (options.skipStore && options.store) {\n logError('Cannot use --skip-store and --store together');\n process.exit(1);\n }\n if (options.skipService && options.service) {\n logError('Cannot use --skip-service and --service together');\n process.exit(1);\n }\n};\n\nconst printFeatureSuccess = (\n featureOptions: { featureName: string; createStore: boolean; createService: boolean },\n basePath: string,\n) => {\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};\n", "import path from 'node:path';\nimport type { ProjectDetection } from '../detection';\nimport { detectProjectSetup } from '../detection';\nimport { generateFeature } from '../generators';\nimport { registerApiEndpoints, registerInRootReducer } from '../modifiers';\nimport type { PipelineContext, PipelineStep } from './types';\n\nexport interface FeaturePipelineContext extends PipelineContext {\n featureName: string;\n basePath: string;\n featurePath: string;\n createStore: boolean;\n persistStore: boolean;\n createService: boolean;\n httpClient?: 'axios' | 'fetch';\n detection: ProjectDetection;\n}\n\nexport const createFeaturePipelineSteps = (): PipelineStep<FeaturePipelineContext>[] => [\n {\n name: 'Project setup detected',\n spinnerText: 'Detecting project setup...',\n execute: async (ctx) => {\n ctx.detection = await detectProjectSetup(ctx.projectPath);\n },\n },\n {\n name: 'Feature files generated',\n spinnerText: 'Generating feature files...',\n execute: async (ctx) => {\n await generateFeature({\n name: ctx.featureName,\n outputPath: ctx.featurePath,\n createStore: ctx.createStore,\n persistStore: ctx.persistStore,\n createService: ctx.createService,\n httpClient: ctx.httpClient,\n });\n },\n },\n {\n name: 'API endpoints registered',\n spinnerText: 'Registering API endpoints...',\n shouldSkip: (ctx) => !ctx.createService,\n execute: async (ctx) => {\n await registerApiEndpoints({\n serviceName: ctx.featureName,\n projectPath: ctx.projectPath,\n });\n },\n },\n {\n name: 'Feature registered in rootReducer',\n spinnerText: 'Registering feature in rootReducer...',\n shouldSkip: (ctx) => !ctx.createStore || !ctx.detection.hasRedux,\n execute: async (ctx) => {\n await registerInRootReducer({\n projectPath: ctx.projectPath,\n name: ctx.featureName,\n persist: ctx.persistStore,\n importPath: path.join(ctx.basePath, ctx.featureName, 'store'),\n });\n },\n },\n];\n", "import { readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel } from '../config/utils';\nimport { addToAppApis } from './helpers';\nimport type { RegisterApiOptions } from './types';\n\n/**\n * Register API endpoints for a service in app-apis.ts.\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 let content = await readFile(apiConfigPath, 'utf-8');\n\n // Skip if already registered\n if (content.includes(`${camelName}:`)) {\n return;\n }\n\n // Validate AppApis object exists\n if (!content.match(/export const AppApis = \\{[\\s\\S]*?\\} as const;/)) {\n throw new Error('Could not find AppApis object in app-apis.ts');\n }\n\n // Bare paths \u2014 `getApiBaseUrl()` already prepends `/api/v{n}`.\n const newEndpoint = ` ${camelName}: {\n base: '/${serviceName}',\n getAll: '/${serviceName}',\n },`;\n\n content = addToAppApis(content, newEndpoint);\n await writeFile(apiConfigPath, content);\n } catch (error) {\n throw new Error(`Failed to register API endpoints: ${error}`, { cause: error });\n }\n};\n", "/**\n * Add an import statement after the last existing import in a file.\n * If no imports exist, prepends to the file.\n */\nexport const addImportStatement = (fileContent: string, importStatement: string): string => {\n const importRegex = /import\\s+.*\\s+from\\s+['\"].*['\"];?\\n/g;\n const imports = fileContent.match(importRegex);\n\n if (imports && imports.length > 0) {\n const lastImport = imports[imports.length - 1];\n const lastImportIndex = fileContent.lastIndexOf(lastImport);\n return (\n fileContent.slice(0, lastImportIndex + lastImport.length) +\n importStatement +\n '\\n' +\n fileContent.slice(lastImportIndex + lastImport.length)\n );\n }\n\n return `${importStatement}\\n${fileContent}`;\n};\n\n/**\n * Add a reducer entry to a combineReducers({...}) call.\n */\nexport const addToCombineReducers = (\n fileContent: string,\n reducerKey: string,\n reducerEntry: string,\n): string => {\n const combineReducersRegex = /combineReducers\\(\\{([^}]*)\\}\\)/s;\n const match = fileContent.match(combineReducersRegex);\n\n if (!match) {\n throw new Error('Could not find combineReducers in rootReducer.ts');\n }\n\n const reducersContent = match[1];\n const newEntry = `\\n ${reducerKey}: ${reducerEntry},`;\n const updatedReducersContent = reducersContent.trimEnd() + newEntry;\n\n return fileContent.replace(\n combineReducersRegex,\n `combineReducers({${updatedReducersContent}\\n})`,\n );\n};\n\n/**\n * Insert a new endpoint object before the closing `} as const;` of AppApis.\n */\nexport const addToAppApis = (fileContent: string, endpointBlock: string): string => {\n const insertPosition = fileContent.lastIndexOf('} as const;');\n if (insertPosition === -1) {\n throw new Error('Could not find closing brace of AppApis object');\n }\n\n const beforeClosing = fileContent.substring(0, insertPosition);\n const afterClosing = fileContent.substring(insertPosition);\n\n return `${beforeClosing.trimEnd()}\\n${endpointBlock}\\n${afterClosing}`;\n};\n", "import { readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel } from '../config/utils';\nimport { fileExists } from '../core/files';\n\n/**\n * Add a route to AppPaths in app-paths.ts.\n */\nexport const registerAppPath = async (\n projectPath: string,\n routeName: string,\n routePath: string,\n): Promise<void> => {\n const appPathsFile = path.join(projectPath, 'src', 'lib', 'config', 'app-paths.ts');\n if (!fileExists(appPathsFile)) return;\n\n let content = await readFile(appPathsFile, 'utf-8');\n const camelName = kebabToCamel(routeName);\n\n if (content.includes(`${camelName}:`)) return;\n\n const closingBrace = content.lastIndexOf('} as const;');\n if (closingBrace === -1) return;\n\n const newEntry = ` ${camelName}: '${routePath}',\\n`;\n content = content.slice(0, closingBrace) + newEntry + content.slice(closingBrace);\n\n await writeFile(appPathsFile, content);\n};\n", "import path from 'node:path';\nimport { PROJECT_PATHS } from '../config/paths';\nimport { fileExists, readFile, writeFile } from '../core/files';\nimport { addImportStatement } from './helpers';\n\n/**\n * Modifies the project's `RootProvider.tsx` to wrap `{children}` in a newly\n * generated provider. Two-tier detection:\n * 1. Canonical path: `src/providers/RootProvider.tsx`\n * 2. Heuristic scan of `src/providers/*.tsx` for the file whose JSX\n * contains `{children}` (most projects only have one).\n *\n * Pure transformation logic lives in this module too (`injectProviderIntoChain`,\n * `addProviderToBarrel`) so it can be unit-tested without filesystem.\n */\n\nconst COMPONENT_TAG_RE = (componentName: string): RegExp => new RegExp(`<\\\\s*${componentName}\\\\b`);\n\n/**\n * Insert `<ComponentName>{children}</ComponentName>` as the innermost wrap\n * around `{children}`. Idempotent: returns the input unchanged if the tag\n * is already present.\n */\nexport const injectProviderIntoChain = (content: string, componentName: string): string => {\n if (COMPONENT_TAG_RE(componentName).test(content)) {\n return content;\n }\n\n // Capture the indentation of the `{children}` line so we preserve formatting.\n const childrenLineRe = /^(?<indent>[ \\t]*)\\{children\\}\\s*$/m;\n const match = content.match(childrenLineRe);\n if (!match || match.index === undefined) {\n throw new Error(\n 'Could not locate `{children}` line in RootProvider \u2014 expected a line containing only `{children}`.',\n );\n }\n\n const indent = match.groups?.indent ?? '';\n const innerIndent = `${indent} `;\n const replacement = `${indent}<${componentName}>\\n${innerIndent}{children}\\n${indent}</${componentName}>`;\n\n return content.replace(childrenLineRe, replacement);\n};\n\n/**\n * Append a `export * from './<basename>';` line to the providers barrel,\n * keeping it sorted alphabetically among the other exports. Idempotent.\n */\nexport const addProviderToBarrel = (content: string, fileBaseName: string): string => {\n const exportLine = `export * from './${fileBaseName}';`;\n if (content.includes(exportLine)) return content;\n\n const lines = content.split('\\n');\n const exportLines: string[] = [];\n const others: string[] = [];\n\n for (const line of lines) {\n if (/^export \\* from '\\.\\/.*';\\s*$/.test(line)) {\n exportLines.push(line);\n } else {\n others.push(line);\n }\n }\n\n const merged = [...exportLines, exportLine].sort();\n // Reconstitute: keep non-export lines (likely empty trailing/leading) where\n // they were, but place the sorted export block where the first export was.\n const firstExportIdx = lines.findIndex((l) => /^export \\* from '\\.\\//.test(l));\n if (firstExportIdx === -1) {\n return `${exportLine}\\n${content.replace(/^\\n+/, '')}`;\n }\n\n const before = lines.slice(0, firstExportIdx);\n const afterStart = lines.findIndex(\n (l, idx) => idx > firstExportIdx && !/^export \\* from '\\.\\//.test(l),\n );\n const after = afterStart === -1 ? [] : lines.slice(afterStart);\n\n return [...before, ...merged, ...after].join('\\n');\n};\n\nconst PROVIDER_DIR_REL = PROJECT_PATHS.PROVIDERS;\nconst ROOT_PROVIDER_REL = PROJECT_PATHS.ROOT_PROVIDER;\nconst PROVIDERS_INDEX_REL = PROJECT_PATHS.PROVIDERS_INDEX;\n\n/** Locates the RootProvider file or returns null when none can be confidently identified. */\nexport const findRootProviderFile = async (\n projectPath: string,\n fs: { fileExists: (p: string) => boolean; readFile: (p: string) => Promise<string> } = {\n fileExists,\n readFile,\n },\n): Promise<string | null> => {\n const canonical = path.join(projectPath, ROOT_PROVIDER_REL);\n if (fs.fileExists(canonical)) return canonical;\n\n const dir = path.join(projectPath, PROVIDER_DIR_REL);\n if (!fs.fileExists(dir)) return null;\n\n const { readdir } = await import('node:fs/promises');\n const entries = await readdir(dir).catch(() => [] as string[]);\n const candidates = entries.filter((name) => name.endsWith('.tsx'));\n\n let best: { file: string; depth: number } | null = null;\n for (const entry of candidates) {\n const filePath = path.join(dir, entry);\n const contents = await fs.readFile(filePath);\n if (!/\\{children\\}/.test(contents)) continue;\n // Depth heuristic: number of opening JSX tags before `{children}`.\n const beforeChildren = contents.split('{children}')[0] ?? '';\n const depth = (beforeChildren.match(/<[A-Z][A-Za-z0-9_]*\\b/g) ?? []).length;\n if (!best || depth > best.depth) {\n best = { file: filePath, depth };\n }\n }\n\n return best?.file ?? null;\n};\n\nexport interface RegisterProviderOptions {\n projectPath: string;\n componentName: string;\n fileBaseName: string;\n}\n\nexport const registerProvider = async (\n options: RegisterProviderOptions,\n): Promise<{ rootProviderFile: string | null; barrelFile: string | null }> => {\n const { projectPath, componentName, fileBaseName } = options;\n\n const rootProviderFile = await findRootProviderFile(projectPath);\n if (rootProviderFile) {\n const before = await readFile(rootProviderFile);\n let after = before;\n if (!/from '\\.\\//.test(before) || !before.includes(`{ ${componentName} }`)) {\n after = addImportStatement(after, `import { ${componentName} } from './${fileBaseName}';`);\n }\n after = injectProviderIntoChain(after, componentName);\n if (after !== before) {\n await writeFile(rootProviderFile, after);\n }\n }\n\n const barrelPath = path.join(projectPath, PROVIDERS_INDEX_REL);\n let barrelFile: string | null = null;\n if (fileExists(barrelPath)) {\n const before = await readFile(barrelPath);\n const after = addProviderToBarrel(before, fileBaseName);\n if (after !== before) {\n await writeFile(barrelPath, after);\n }\n barrelFile = barrelPath;\n }\n\n return { rootProviderFile, barrelFile };\n};\n", "import { readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel } from '../config/utils';\nimport { addImportStatement, addToCombineReducers } from './helpers';\nimport type { RegisterReducerOptions } from './types';\n\n/**\n * Register a reducer in rootReducer.ts \u2014 unified handler for both\n * feature-embedded slices (import from /store) and standalone slices.\n */\nexport const registerInRootReducer = async (options: RegisterReducerOptions): Promise<void> => {\n const { projectPath, name, persist, importPath } = options;\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(name);\n const reducerName = `${camelName}Reducer`;\n const persistConfigName = `${camelName}PersistConfig`;\n\n // Convert path to import alias format (src/... -> @/...)\n const aliasPath = importPath.replace(/^src\\//, '@/');\n\n // Build import statement\n const importStatement = persist\n ? `import { ${reducerName}, ${persistConfigName} } from '${aliasPath}';`\n : `import { ${reducerName} } from '${aliasPath}';`;\n\n content = addImportStatement(content, importStatement);\n\n // Build reducer entry\n const reducerEntry = persist\n ? `persistReducer(${persistConfigName}, ${reducerName})`\n : reducerName;\n\n content = addToCombineReducers(content, camelName, reducerEntry);\n\n await writeFile(rootReducerPath, content);\n } catch (error) {\n throw new Error(`Failed to register reducer '${name}' in rootReducer: ${error}`, {\n cause: error,\n });\n }\n};\n", "import { readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { fileExists } from '../core/files';\n\n/**\n * Add a translation namespace to the default (en) translation file.\n */\nexport const addTranslationNamespace = async (\n projectPath: string,\n namespace: string,\n): Promise<void> => {\n const translationFile = path.join(projectPath, 'src', 'i18n', 'translations', 'en.json');\n if (!fileExists(translationFile)) return;\n\n const content = await readFile(translationFile, 'utf-8');\n const json = JSON.parse(content);\n\n if (json[namespace]) return;\n\n json[namespace] = {\n title: namespace,\n description: `${namespace} page description`,\n };\n\n await writeFile(translationFile, `${JSON.stringify(json, null, 2)}\\n`);\n};\n", "import type { PipelineContext, PipelineStep } from './types';\n\n/**\n * Execute a sequence of pipeline steps with spinner feedback.\n * Each step gets the shared context and reports progress via the spinner.\n */\nexport const executePipeline = async <T extends PipelineContext>(\n steps: PipelineStep<T>[],\n context: T,\n): Promise<void> => {\n for (const step of steps) {\n if (step.shouldSkip?.(context)) continue;\n\n context.spinner.start(step.spinnerText);\n\n try {\n await step.execute(context);\n context.spinner.succeed(step.name);\n } catch (error) {\n context.spinner.fail(step.name);\n throw error;\n }\n }\n};\n", "import { generateService } from '../generators';\nimport { registerApiEndpoints } from '../modifiers';\nimport type { PipelineContext, PipelineStep } from './types';\n\nexport interface ServicePipelineContext extends PipelineContext {\n serviceName: string;\n servicePath: string;\n httpClient: 'axios' | 'fetch';\n}\n\nexport const createServicePipelineSteps = (): PipelineStep<ServicePipelineContext>[] => [\n {\n name: 'Service files generated',\n spinnerText: 'Generating service files...',\n execute: async (ctx) => {\n await generateService({\n name: ctx.serviceName,\n outputPath: ctx.servicePath,\n httpClient: ctx.httpClient,\n });\n },\n },\n {\n name: 'API endpoints registered',\n spinnerText: 'Registering API endpoints...',\n execute: async (ctx) => {\n await registerApiEndpoints({\n serviceName: ctx.serviceName,\n projectPath: ctx.projectPath,\n });\n },\n },\n];\n", "import path from 'node:path';\nimport { generateSlice } from '../generators';\nimport { registerInRootReducer } from '../modifiers';\nimport type { PipelineContext, PipelineStep } from './types';\n\nexport interface SlicePipelineContext extends PipelineContext {\n sliceName: string;\n basePath: string;\n slicePath: string;\n persistSlice: boolean;\n}\n\nexport const createSlicePipelineSteps = (): PipelineStep<SlicePipelineContext>[] => [\n {\n name: 'Slice files generated',\n spinnerText: 'Generating slice files...',\n execute: async (ctx) => {\n await generateSlice({\n name: ctx.sliceName,\n outputPath: ctx.slicePath,\n persist: ctx.persistSlice,\n });\n },\n },\n {\n name: 'Slice registered in rootReducer',\n spinnerText: 'Registering slice in rootReducer...',\n execute: async (ctx) => {\n await registerInRootReducer({\n projectPath: ctx.projectPath,\n name: ctx.sliceName,\n persist: ctx.persistSlice,\n importPath: path.join(ctx.basePath, ctx.sliceName),\n });\n },\n },\n];\n", "import Enquirer from 'enquirer';\n\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 path from 'node:path';\nimport type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { kebabToPascal } from '../config/utils';\nimport { detectProjectSetup } from '../detection';\nimport { generateHook, generateTest } from '../generators';\nimport { promptForHookDetails } from '../prompts/hook.prompt';\n\ninterface HookCommandOptions {\n client?: boolean;\n feature?: string;\n test?: boolean;\n noTest?: boolean;\n}\n\nexport const registerHookCommand = (program: Command) => {\n program\n .command('hook [name]')\n .description('Generate a custom React hook')\n .option('--client', \"Add 'use client' directive (default: true)\", true)\n .option('--feature <path>', 'Generate in feature directory (e.g., src/features/auth)')\n .option('--test', 'Also generate a sibling test file')\n .option('--no-test', 'Skip test file generation')\n .action(async (name: string | undefined, options: HookCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\n log(pc.cyan('\\n\uD83E\uDE9D Hook Generator\\n'));\n\n const detection = await detectProjectSetup(projectPath);\n\n const hookOptions = await promptForHookDetails(name);\n const pascalName = kebabToPascal(hookOptions.hookName);\n const hookName = `use${pascalName}`;\n const shouldTest = resolveShouldTest(options, detection.hasTests);\n\n spinner.start('Generating hook...');\n await generateHook({\n name: hookOptions.hookName,\n projectPath,\n isClient: options.client ?? true,\n featurePath: options.feature,\n });\n spinner.succeed('Hook generated');\n\n const hookFile = options.feature\n ? path.join(projectPath, options.feature, 'hooks', `${hookName}.ts`)\n : path.join(projectPath, 'src/hooks', `${hookName}.ts`);\n\n let testFile: string | null = null;\n if (shouldTest) {\n spinner.start('Generating test...');\n testFile = await generateTest({\n projectPath,\n sourceFile: hookFile,\n kind: 'hook',\n symbolName: hookName,\n hookUsesStore: detection.hasRedux && !!options.feature,\n });\n spinner.succeed('Test generated');\n }\n\n const location = options.feature\n ? `${options.feature}/hooks/${hookName}.ts`\n : `src/hooks/${hookName}.ts`;\n\n log(pc.green(`\\n\u2728 Hook '${hookName}' created successfully!\\n`));\n log(pc.dim(` \uD83D\uDCC4 ${location}`));\n if (testFile) log(pc.dim(` \uD83E\uDDEA ${path.relative(projectPath, testFile)}`));\n log('');\n log(pc.cyan('Usage:'));\n const importPath = options.feature\n ? `${options.feature.replace(/^src\\//, '@/')}/hooks/${hookName}`\n : `@/hooks/${hookName}`;\n log(pc.dim(` import { ${hookName} } from '${importPath}';`));\n log('');\n } catch (error) {\n spinner.fail('Hook generation failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n\nconst resolveShouldTest = (\n options: { test?: boolean; noTest?: boolean },\n hasTests: boolean,\n): boolean => {\n if (options.noTest) return false;\n if (options.test) return true;\n return hasTests;\n};\n", "import Enquirer from 'enquirer';\n\nconst { prompt } = Enquirer;\n\nexport interface HookPromptResult {\n hookName: string;\n}\n\nexport const promptForHookDetails = async (name?: string): Promise<HookPromptResult> => {\n if (name) return { hookName: name };\n\n const answers = (await prompt({\n type: 'input',\n name: 'hookName',\n message: 'Hook name (kebab-case, without \"use\" prefix):',\n validate: (value: string) => {\n if (!value) return 'Hook name is required';\n if (!/^[a-z][a-z0-9-]*$/.test(value)) {\n return 'Use lowercase letters, numbers, and hyphens only';\n }\n return true;\n },\n })) as unknown as HookPromptResult;\n\n return answers;\n};\n", "import type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { detectProjectSetup } from '../detection';\nimport { generateLayout } from '../generators/layout.generator';\n\ninterface LayoutCommandOptions {\n group?: boolean;\n at?: string;\n locale?: boolean;\n}\n\nexport const registerLayoutCommand = (program: Command) => {\n program\n .command('layout <segment>')\n .description('Generate a nested layout.tsx (locale-aware when i18n is detected)')\n .option('--group', 'Treat the segment as a route group (wraps it in parens)')\n .option('--at <path>', 'Place the layout under this nested path (kebab-case, slash-separated)')\n .option('--no-locale', 'Skip the locale wrapper even if i18n is detected')\n .action(async (segment: string, options: LayoutCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\n log(pc.cyan('\\n\uD83D\uDCD0 Layout Generator\\n'));\n\n spinner.start('Detecting project setup...');\n const detection = await detectProjectSetup(projectPath);\n spinner.succeed('Project setup detected');\n\n const hasI18n = detection.hasI18n && options.locale !== false;\n log(pc.dim(` i18n: ${hasI18n ? '\u2713' : '\u2717'}\\n`));\n\n spinner.start('Generating layout...');\n const result = await generateLayout({\n segment,\n at: options.at,\n projectPath,\n hasI18n,\n withGroup: !!options.group,\n });\n spinner.succeed('Layout generated');\n\n log(pc.green(`\\n\u2728 ${result.componentName} created!\\n`));\n log(pc.dim(` \uD83D\uDCC4 ${result.displayPath}`));\n log('');\n } catch (error) {\n spinner.fail('Layout generation failed');\n logError(`${error instanceof Error ? error.message : error}`);\n process.exit(1);\n }\n });\n};\n", "import path from 'node:path';\nimport type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { fileExists } from '../core/files';\nimport { detectProjectSetup } from '../detection';\nimport { generateLocale } from '../generators';\nimport { promptForLocaleDetails } from '../prompts/locale.prompt';\n\ninterface LocaleCommandOptions {\n copyTranslations?: boolean;\n}\n\nexport const registerLocaleCommand = (program: Command) => {\n program\n .command('locale [code]')\n .description('Add a new locale/language')\n .option('--copy-translations', 'Copy translations from English instead of empty values')\n .action(async (code: string | undefined, options: LocaleCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\n log(pc.cyan('\\n\uD83C\uDF0D Locale Generator\\n'));\n\n // Check i18n is set up\n spinner.start('Detecting project setup...');\n const detection = await detectProjectSetup(projectPath);\n spinner.succeed('Project setup detected');\n\n if (!detection.hasI18n) {\n spinner.fail('i18n is not set up in this project');\n logError('Please set up internationalization first');\n log(pc.dim('\\nRun: npx @teispace/next-maker setup --i18n\\n'));\n process.exit(1);\n }\n\n // Prompt \u2014 skip questions whose answers were already given via flags.\n const localeOptions = await promptForLocaleDetails(code, {\n copyTranslations: options.copyTranslations,\n });\n\n // Check if locale already exists\n const translationFile = path.join(\n projectPath,\n 'src',\n 'i18n',\n 'translations',\n `${localeOptions.code}.json`,\n );\n if (fileExists(translationFile)) {\n logError(`Locale '${localeOptions.code}' already exists!`);\n process.exit(1);\n }\n\n // Generate\n spinner.start('Adding locale...');\n await generateLocale({\n ...localeOptions,\n projectPath,\n });\n spinner.succeed('Locale added');\n\n // Success\n log(\n pc.green(\n `\\n\u2728 Locale '${localeOptions.code}' (${localeOptions.name}) added successfully!\\n`,\n ),\n );\n log(pc.dim('Updated files:'));\n log(pc.dim(` \uD83D\uDCC4 src/i18n/translations/${localeOptions.code}.json`));\n log(pc.dim(` \uD83D\uDCDD src/types/i18n.ts (SupportedLocale type)`));\n log(pc.dim(` \uD83D\uDCDD src/lib/config/app-locales.ts`));\n log('');\n\n log(pc.cyan('Next steps:'));\n log(pc.dim(` 1. Translate: src/i18n/translations/${localeOptions.code}.json`));\n log(pc.dim(` 2. Visit: http://localhost:3000/${localeOptions.code}`));\n log('');\n } catch (error) {\n spinner.fail('Locale generation failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n", "import Enquirer from 'enquirer';\n\nconst { prompt } = Enquirer;\n\nexport interface LocalePromptResult {\n code: string;\n name: string;\n country: string;\n flag: string;\n copyTranslations: boolean;\n}\n\nexport interface LocalePromptPresets {\n /** When set, the copy-translations prompt is skipped and this value is used. */\n copyTranslations?: boolean;\n}\n\nexport const promptForLocaleDetails = async (\n code?: string,\n presets: LocalePromptPresets = {},\n): Promise<LocalePromptResult> => {\n const questions: any[] = [];\n\n if (!code) {\n questions.push({\n type: 'input',\n name: 'code',\n message: 'Locale code (e.g., es, fr, de):',\n validate: (value: string) => {\n if (!value) return 'Locale code is required';\n if (!/^[a-z]{2}(-[A-Z]{2})?$/.test(value)) {\n return 'Use format: xx or xx-XX (e.g., es, pt-BR)';\n }\n return true;\n },\n });\n }\n\n questions.push(\n {\n type: 'input',\n name: 'name',\n message: 'Language name (e.g., Spanish, French):',\n validate: (value: string) => (value ? true : 'Language name is required'),\n },\n {\n type: 'input',\n name: 'country',\n message: 'Country (e.g., Spain, France):',\n validate: (value: string) => (value ? true : 'Country is required'),\n },\n {\n type: 'input',\n name: 'flag',\n message: 'Flag emoji (e.g., \uD83C\uDDEA\uD83C\uDDF8, \uD83C\uDDEB\uD83C\uDDF7):',\n validate: (value: string) => (value ? true : 'Flag emoji is required'),\n },\n );\n\n if (presets.copyTranslations === undefined) {\n questions.push({\n type: 'confirm',\n name: 'copyTranslations',\n message: 'Copy translations from English? (No = empty values)',\n initial: false,\n });\n }\n\n const answers = (await prompt(questions)) as unknown as Partial<LocalePromptResult>;\n\n return {\n code: code ?? (answers.code as string),\n name: answers.name as string,\n country: answers.country as string,\n flag: answers.flag as string,\n copyTranslations: presets.copyTranslations ?? answers.copyTranslations ?? false,\n };\n};\n", "import path from 'node:path';\nimport type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { kebabToPascal } from '../config/utils';\nimport { detectProjectSetup, directoryExists } from '../detection';\nimport { generatePage } from '../generators';\nimport { addTranslationNamespace, registerAppPath } from '../modifiers';\nimport { promptForPageDetails } from '../prompts/page.prompt';\n\ninterface PageCommandOptions {\n dynamic?: string;\n loading?: boolean;\n error?: boolean;\n}\n\nexport const registerPageCommand = (program: Command) => {\n program\n .command('page [name]')\n .description('Generate a new page/route')\n .option('--dynamic <param>', 'Create dynamic route with parameter (e.g., id)')\n .option('--loading', 'Generate loading.tsx')\n .option('--error', 'Generate error.tsx')\n .action(async (name: string | undefined, options: PageCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\n log(pc.cyan('\\n\uD83D\uDCC4 Page Generator\\n'));\n\n // Detect i18n\n spinner.start('Detecting project setup...');\n const detection = await detectProjectSetup(projectPath);\n spinner.succeed('Project setup detected');\n\n log(pc.dim(` i18n: ${detection.hasI18n ? '\u2713' : '\u2717'}\\n`));\n\n // Prompt \u2014 skip questions whose answers were already given via flags.\n const pageOptions = await promptForPageDetails(name, {\n loading: options.loading,\n error: options.error,\n });\n const pageName = pageOptions.pageName;\n const componentName = kebabToPascal(pageName);\n\n // Check existence\n const baseDir = detection.hasI18n ? 'src/app/[locale]' : 'src/app';\n const exists = await directoryExists(projectPath, pageName, baseDir);\n if (exists) {\n logError(`Page '${pageName}' already exists at ${baseDir}/${pageName}!`);\n process.exit(1);\n }\n\n // Generate\n spinner.start('Generating page files...');\n await generatePage({\n name: pageName,\n projectPath,\n hasI18n: detection.hasI18n,\n dynamic: options.dynamic,\n withLoading: options.loading ?? pageOptions.withLoading,\n withError: options.error ?? pageOptions.withError,\n });\n spinner.succeed('Page files generated');\n\n // Register route in app-paths\n spinner.start('Registering route...');\n const routePath = options.dynamic ? `/${pageName}/[${options.dynamic}]` : `/${pageName}`;\n await registerAppPath(projectPath, pageName, routePath);\n spinner.succeed('Route registered');\n\n // Add translation namespace if i18n\n if (detection.hasI18n) {\n spinner.start('Adding translation namespace...');\n await addTranslationNamespace(projectPath, componentName);\n spinner.succeed('Translation namespace added');\n }\n\n // Success\n const displayPath = options.dynamic\n ? path.join(baseDir, pageName, `[${options.dynamic}]`)\n : path.join(baseDir, pageName);\n\n log(pc.green(`\\n\u2728 Page '${pageName}' created successfully!\\n`));\n log(pc.dim('Generated files:'));\n log(pc.dim(` \uD83D\uDCC2 ${displayPath}/`));\n log(pc.dim(` \u251C\u2500\u2500 page.tsx`));\n if (options.loading ?? pageOptions.withLoading) log(pc.dim(` \u251C\u2500\u2500 loading.tsx`));\n if (options.error ?? pageOptions.withError) log(pc.dim(` \u2514\u2500\u2500 error.tsx`));\n log('');\n\n if (detection.hasI18n) {\n log(pc.cyan('Next steps:'));\n log(\n pc.dim(` 1. Add translations in: src/i18n/translations/en.json \u2192 \"${componentName}\"`),\n );\n log(pc.dim(` 2. Visit: http://localhost:3000/${pageName}`));\n log('');\n }\n } catch (error) {\n spinner.fail('Page generation failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n", "import Enquirer from 'enquirer';\n\nconst { prompt } = Enquirer;\n\nexport interface PagePromptResult {\n pageName: string;\n withLoading: boolean;\n withError: boolean;\n}\n\nexport interface PagePromptPresets {\n /** When set, the loading prompt is skipped and this value is used. */\n loading?: boolean;\n /** When set, the error prompt is skipped and this value is used. */\n error?: boolean;\n}\n\nexport const promptForPageDetails = async (\n name?: string,\n presets: PagePromptPresets = {},\n): Promise<PagePromptResult> => {\n const questions: any[] = [];\n\n if (!name) {\n questions.push({\n type: 'input',\n name: 'pageName',\n message: 'Page name (kebab-case):',\n validate: (value: string) => {\n if (!value) return 'Page name is required';\n if (!/^[a-z][a-z0-9-]*$/.test(value)) {\n return 'Use lowercase letters, numbers, and hyphens only';\n }\n return true;\n },\n });\n }\n\n if (presets.loading === undefined) {\n questions.push({\n type: 'confirm',\n name: 'withLoading',\n message: 'Generate loading.tsx?',\n initial: true,\n });\n }\n\n if (presets.error === undefined) {\n questions.push({\n type: 'confirm',\n name: 'withError',\n message: 'Generate error.tsx?',\n initial: true,\n });\n }\n\n const answers =\n questions.length > 0 ? ((await prompt(questions)) as unknown as Partial<PagePromptResult>) : {};\n\n return {\n pageName: name ?? (answers.pageName as string),\n withLoading: presets.loading ?? answers.withLoading ?? true,\n withError: presets.error ?? answers.withError ?? true,\n };\n};\n", "import path from 'node:path';\nimport type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { generateProvider } from '../generators/provider.generator';\nimport { registerProvider } from '../modifiers/root-provider.modifier';\n\nexport const registerProviderCommand = (program: Command) => {\n program\n .command('provider <name>')\n .description('Generate a context provider in src/providers/ and wire it into RootProvider')\n .action(async (name: string) => {\n try {\n const projectPath = process.cwd();\n\n log(pc.cyan('\\n\uD83D\uDD0C Provider Generator\\n'));\n\n spinner.start('Generating provider...');\n const { componentName, fileBaseName, providerFile } = await generateProvider({\n name,\n projectPath,\n });\n spinner.succeed('Provider generated');\n\n spinner.start('Registering provider in RootProvider and barrel...');\n const { rootProviderFile, barrelFile } = await registerProvider({\n projectPath,\n componentName,\n fileBaseName,\n });\n spinner.succeed('Provider registered');\n\n log(pc.green(`\\n\u2728 ${componentName} created!\\n`));\n log(pc.dim('Generated files:'));\n log(pc.dim(` \uD83D\uDCC4 ${path.relative(projectPath, providerFile)}`));\n if (rootProviderFile) {\n log(pc.dim(` \u270F\uFE0F ${path.relative(projectPath, rootProviderFile)} \u2014 wrapped {children}`));\n } else {\n log(\n pc.yellow('\\n\u26A0\uFE0F Could not locate a RootProvider file. Wire the new provider manually:'),\n );\n log(pc.dim(` <${componentName}>{children}</${componentName}>`));\n }\n if (barrelFile) {\n log(pc.dim(` \u270F\uFE0F ${path.relative(projectPath, barrelFile)} \u2014 added re-export`));\n }\n log('');\n } catch (error) {\n spinner.fail('Provider generation failed');\n logError(`${error instanceof Error ? error.message : error}`);\n process.exit(1);\n }\n });\n};\n", "import type { Command } from 'commander';\nimport Enquirer from 'enquirer';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { checkManifest, getManifest, MANIFESTS, reverseManifest } from '../manifests';\nimport type { RemoveSummary } from '../manifests/runner';\n\nconst { prompt } = Enquirer;\n\ninterface RemoveCommandOptions {\n yes?: boolean;\n dryRun?: boolean;\n}\n\nconst formatSummary = (summary: RemoveSummary): string[] => {\n const lines: string[] = [];\n for (const file of summary.filesRemoved) {\n lines.push(` ${pc.red('-')} delete: ${file}`);\n }\n for (const block of summary.blocksStripped) {\n lines.push(` ${pc.red('-')} strip block: ${block.description} ${pc.dim(`(${block.file})`)}`);\n }\n for (const script of summary.scriptsRemoved) {\n lines.push(` ${pc.red('-')} remove script: ${script}`);\n }\n for (const dep of summary.packagesUninstalled) {\n lines.push(` ${pc.red('-')} uninstall: ${dep}`);\n }\n for (const item of summary.manualCleanup) {\n lines.push(\n ` ${pc.yellow('?')} manual cleanup: ${item.description} ${pc.dim(`(${item.file})`)}`,\n );\n }\n return lines;\n};\n\nconst isEmpty = (s: RemoveSummary): boolean =>\n s.filesRemoved.length === 0 &&\n s.blocksStripped.length === 0 &&\n s.scriptsRemoved.length === 0 &&\n s.packagesUninstalled.length === 0 &&\n s.manualCleanup.length === 0;\n\nexport const registerRemoveCommand = (program: Command) => {\n program\n .command('remove <feature>')\n .alias('uninstall')\n .description('Reverse a feature install (uses the feature manifest)')\n .option('-y, --yes', 'Skip confirmation prompt')\n .option('--dry-run', 'Show what would change without writing')\n .action(async (feature: string, options: RemoveCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\n const manifest = getManifest(feature);\n if (!manifest) {\n throw new Error(\n `Unknown feature \"${feature}\". Valid: ${MANIFESTS.map((m) => m.id).join(', ')}.`,\n );\n }\n\n log(pc.cyan(`\\n\uD83D\uDDD1 Remove ${manifest.name}\\n`));\n\n const detection = await checkManifest(manifest, projectPath);\n if (!detection.installed) {\n log(pc.dim(`${manifest.name} is not installed \u2014 nothing to remove.`));\n return;\n }\n\n spinner.start('Computing changes...');\n const planned = await reverseManifest(manifest, projectPath, { dryRun: true });\n spinner.succeed('Computed plan');\n\n if (isEmpty(planned)) {\n log(pc.yellow('\\n\u26A0\uFE0F Manifest had no removable artifacts. Nothing to do.\\n'));\n return;\n }\n\n log(pc.bold('\\nPlanned changes:\\n'));\n for (const line of formatSummary(planned)) log(line);\n log('');\n\n if (options.dryRun) {\n log(pc.dim('--dry-run set \u2014 exiting without writing.\\n'));\n return;\n }\n\n if (!options.yes) {\n const { confirm } = await prompt<{ confirm: boolean }>({\n type: 'confirm',\n name: 'confirm',\n message: `Apply the changes above to remove ${manifest.name}?`,\n initial: false,\n });\n if (!confirm) {\n log(pc.yellow('\\nAborted.\\n'));\n return;\n }\n }\n\n spinner.start(`Removing ${manifest.name}...`);\n const applied = manifest.remove\n ? (await manifest.remove(projectPath), planned)\n : await reverseManifest(manifest, projectPath);\n spinner.succeed(`${manifest.name} removed`);\n\n log(pc.green(`\\n\u2713 ${manifest.name} removed.`));\n if (applied.manualCleanup.length > 0) {\n log(pc.yellow('\\n\u26A0\uFE0F Manual cleanup still required:'));\n for (const item of applied.manualCleanup) {\n log(` - ${item.description} (${item.file})`);\n }\n }\n log('');\n } catch (error) {\n spinner.fail('Remove failed');\n logError(`${error instanceof Error ? error.message : error}`);\n process.exit(1);\n }\n });\n};\n", "import { existsSync } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { detectProjectSetup, fileExistsAt } from '../detection';\nimport { generateCrudService } from '../generators';\nimport { registerCrudApiEndpoints } from '../modifiers/crud-api-registration.modifier';\nimport { createServicePipelineSteps, executePipeline } from '../pipelines';\nimport { promptForServiceDetails } from '../prompts/service.prompt';\n\ninterface ServiceCommandOptions {\n path?: string;\n axios?: boolean;\n fetch?: boolean;\n crud?: 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 .option('--crud', 'Generate full CRUD service (getAll, getById, create, update, delete)')\n .action(async (name: string | undefined, options: ServiceCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\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 // Detect and validate HTTP clients\n spinner.start('Detecting project setup...');\n const detection = await detectProjectSetup(projectPath);\n spinner.succeed('Project setup detected');\n\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 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 // Prompt and resolve paths\n const serviceOptions = await promptForServiceDetails(\n name,\n options.axios,\n options.fetch,\n detection.httpClient,\n );\n\n const { basePath, servicePath } = resolveServicePaths(\n projectPath,\n serviceOptions.serviceName,\n options.path,\n );\n\n if (!existsSync(servicePath)) {\n await mkdir(servicePath, { recursive: true });\n }\n\n const exists = fileExistsAt(\n projectPath,\n basePath,\n `${serviceOptions.serviceName}.service.ts`,\n );\n if (exists) {\n logError(`Service '${serviceOptions.serviceName}' already exists at ${basePath}!`);\n process.exit(1);\n }\n\n // Execute generation\n if (options.crud) {\n spinner.start('Generating CRUD service files...');\n await generateCrudService({\n name: serviceOptions.serviceName,\n outputPath: servicePath,\n httpClient: serviceOptions.httpClient,\n });\n spinner.succeed('CRUD service files generated');\n\n spinner.start('Registering CRUD API endpoints...');\n await registerCrudApiEndpoints(projectPath, serviceOptions.serviceName);\n spinner.succeed('CRUD API endpoints registered');\n } else {\n await executePipeline(createServicePipelineSteps(), {\n projectPath,\n spinner,\n serviceName: serviceOptions.serviceName,\n servicePath,\n httpClient: serviceOptions.httpClient,\n });\n }\n\n printServiceSuccess(serviceOptions, basePath, !!options.crud);\n } catch (error) {\n spinner.fail('Service generation failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n\nconst resolveServicePaths = (\n projectPath: string,\n serviceName: string,\n customPath?: string,\n): { basePath: string; servicePath: string } => {\n let basePath: string;\n\n if (customPath) {\n const cleanPath = customPath.replace(/^src\\//, '');\n if (cleanPath.startsWith('features/')) {\n const featureName = cleanPath.split('/')[1];\n basePath = path.join('src', 'features', featureName, 'services');\n } else {\n basePath = path.join('src', cleanPath);\n }\n } else {\n basePath = path.join('src', 'features', serviceName, 'services');\n }\n\n return {\n basePath,\n servicePath: path.join(projectPath, basePath),\n };\n};\n\nconst printServiceSuccess = (\n serviceOptions: { serviceName: string; httpClient: string },\n basePath: string,\n isCrud: boolean = false,\n) => {\n const displayPath = path.join(basePath, `${serviceOptions.serviceName}.service.ts`);\n log(\n pc.green(\n `\\n\u2728 ${isCrud ? 'CRUD ' : ''}Service '${serviceOptions.serviceName}' created successfully!\\n`,\n ),\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 if (isCrud) {\n log(pc.dim(` 2. Available methods: getAll, getById, create, update, delete`));\n log(pc.dim(` 3. Update DTO types in the service file`));\n } else {\n log(\n pc.dim(\n ` 2. Use in component: const data = await ${serviceOptions.serviceName}Service.getAll()`,\n ),\n );\n }\n log('');\n};\n", "import { readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel } from '../config/utils';\nimport { crudApiConfigTemplate } from '../generators/templates/crud-service.template';\nimport { addToAppApis } from './helpers';\n\n/**\n * Register CRUD API endpoints for a service in app-apis.ts.\n */\nexport const registerCrudApiEndpoints = async (\n projectPath: string,\n serviceName: string,\n): Promise<void> => {\n const camelName = kebabToCamel(serviceName);\n const apiConfigPath = path.join(projectPath, 'src', 'lib', 'config', 'app-apis.ts');\n\n try {\n let content = await readFile(apiConfigPath, 'utf-8');\n\n if (content.includes(`${camelName}:`)) return;\n\n if (!content.match(/export const AppApis = \\{[\\s\\S]*?\\} as const;/)) {\n throw new Error('Could not find AppApis object in app-apis.ts');\n }\n\n const newEndpoint = crudApiConfigTemplate({ camelName, kebabName: serviceName });\n content = addToAppApis(content, newEndpoint);\n await writeFile(apiConfigPath, content);\n } catch (error) {\n throw new Error(`Failed to register CRUD API endpoints: ${error}`, { cause: error });\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 type { Command } from 'commander';\nimport Enquirer from 'enquirer';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { setupBundleAnalyzer } from '../services/setup/bundle-analyzer';\nimport { setupCommitizen } from '../services/setup/commitizen';\nimport { setupDarkTheme } from '../services/setup/dark-theme';\nimport { setupHttpClient } from '../services/setup/http-client';\nimport { setupI18n } from '../services/setup/i18n';\nimport { setupReactCompiler } from '../services/setup/react-compiler';\nimport { setupRedux } from '../services/setup/redux';\nimport { setupSecurityHeaders } from '../services/setup/security-headers';\nimport { setupTests } from '../services/setup/tests';\nimport { setupValidationScripts } from '../services/setup/validate-scripts';\n\nconst { prompt } = Enquirer;\n\ninterface SetupOptions {\n httpClient?: string;\n darkTheme?: boolean;\n redux?: boolean;\n i18n?: boolean;\n tests?: boolean;\n reactCompiler?: boolean;\n bundleAnalyzer?: boolean;\n securityHeaders?: boolean;\n validateScripts?: boolean;\n commitizen?: 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 + @teispace/next-themes)')\n .option('--redux', 'Setup Redux Toolkit')\n .option('--i18n', 'Setup next-intl for internationalization')\n .option('--tests', 'Setup testing (Vitest + React Testing Library)')\n .option('--react-compiler', 'Enable the React Compiler')\n .option('--bundle-analyzer', 'Add @next/bundle-analyzer')\n .option('--security-headers', 'Add hardened HTTP headers to next.config.ts')\n .option(\n '--validate-scripts',\n 'Add scripts/sync-env.ts, scripts/check-deprecated.ts, and the validate chain',\n )\n .option('--commitizen', 'Add Commitizen with the conventional-changelog adapter')\n .action(async (options: SetupOptions) => {\n try {\n log(pc.cyan('\\n\uD83D\uDD27 Setup Wizard\\n'));\n\n const anyFlag =\n options.httpClient ||\n options.darkTheme ||\n options.redux ||\n options.i18n ||\n options.tests ||\n options.reactCompiler ||\n options.bundleAnalyzer ||\n options.securityHeaders ||\n options.validateScripts ||\n options.commitizen;\n\n if (anyFlag) {\n if (options.httpClient) await setupHttpClient(process.cwd());\n if (options.darkTheme) await setupDarkTheme(process.cwd());\n if (options.redux) await setupRedux(process.cwd());\n if (options.i18n) await setupI18n(process.cwd());\n if (options.tests) await setupTests(process.cwd());\n if (options.reactCompiler) await setupReactCompiler(process.cwd());\n if (options.bundleAnalyzer) await setupBundleAnalyzer(process.cwd());\n if (options.securityHeaders) await setupSecurityHeaders(process.cwd());\n if (options.validateScripts) await setupValidationScripts(process.cwd());\n if (options.commitizen) await setupCommitizen(process.cwd());\n return;\n }\n\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 { name: 'Testing (Vitest + RTL)', value: 'tests' },\n { name: 'React Compiler', value: 'react-compiler' },\n { name: 'Bundle Analyzer', value: 'bundle-analyzer' },\n { name: 'Security Headers', value: 'security-headers' },\n { name: 'Validation Scripts', value: 'validate-scripts' },\n { name: 'Commitizen', value: 'commitizen' },\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 const handlers: Record<string, (cwd: string) => Promise<void>> = {\n 'dark-theme': setupDarkTheme,\n redux: setupRedux,\n 'http-client': setupHttpClient,\n i18n: setupI18n,\n tests: setupTests,\n 'react-compiler': setupReactCompiler,\n 'bundle-analyzer': setupBundleAnalyzer,\n 'security-headers': setupSecurityHeaders,\n 'validate-scripts': setupValidationScripts,\n commitizen: setupCommitizen,\n };\n\n const handler = handlers[feature];\n if (handler) {\n await handler(process.cwd());\n } else {\n log(pc.yellow(`\\n\u26A0\uFE0F ${feature} setup is not implemented yet.`));\n }\n } catch (error) {\n spinner.fail('Setup failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n", "import { existsSync } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { kebabToCamel } from '../config/utils';\nimport { detectProjectSetup, directoryExists } from '../detection';\nimport { generateTest } from '../generators';\nimport { createSlicePipelineSteps, executePipeline } from '../pipelines';\nimport { promptForSliceDetails } from '../prompts/slice.prompt';\n\ninterface SliceCommandOptions {\n path?: string;\n persist?: boolean;\n noPersist?: boolean;\n test?: boolean;\n noTest?: 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 .option('--test', 'Also generate a sibling test file')\n .option('--no-test', 'Skip test file generation')\n .action(async (name: string | undefined, options: SliceCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\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 // Detect and validate Redux\n spinner.start('Detecting project setup...');\n const detection = await detectProjectSetup(projectPath);\n spinner.succeed('Project setup detected');\n\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 // Prompt and resolve paths\n const sliceOptions = await promptForSliceDetails(\n name,\n options.persist,\n options.noPersist === true ? false : undefined,\n );\n\n const { basePath, slicePath } = resolveSlicePaths(\n projectPath,\n sliceOptions.sliceName,\n options.path,\n );\n\n const featureStorePath = path.join(projectPath, basePath);\n if (!existsSync(featureStorePath)) {\n await mkdir(featureStorePath, { recursive: true });\n }\n\n const exists = await directoryExists(projectPath, sliceOptions.sliceName, basePath);\n if (exists) {\n logError(`Slice '${sliceOptions.sliceName}' already exists at ${basePath}!`);\n process.exit(1);\n }\n\n // Execute generation pipeline\n await executePipeline(createSlicePipelineSteps(), {\n projectPath,\n spinner,\n sliceName: sliceOptions.sliceName,\n basePath,\n slicePath,\n persistSlice: sliceOptions.persistSlice,\n });\n\n // Optional sibling test.\n let testFile: string | null = null;\n const shouldTest = resolveShouldTest(options, detection.hasTests);\n if (shouldTest) {\n const sliceFile = path.join(slicePath, `${sliceOptions.sliceName}.slice.ts`);\n spinner.start('Generating test...');\n testFile = await generateTest({\n projectPath,\n sourceFile: sliceFile,\n kind: 'slice',\n symbolName: kebabToCamel(sliceOptions.sliceName),\n });\n spinner.succeed('Test generated');\n }\n\n printSliceSuccess(sliceOptions, basePath, testFile, projectPath);\n } catch (error) {\n spinner.fail('Slice generation failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n\nconst resolveSlicePaths = (\n projectPath: string,\n sliceName: string,\n customPath?: string,\n): { basePath: string; slicePath: string } => {\n let basePath: string;\n\n if (customPath) {\n const cleanPath = customPath.replace(/^src\\//, '');\n if (cleanPath.startsWith('features/')) {\n const featureName = cleanPath.split('/')[1];\n basePath = path.join('src', 'features', featureName, 'store');\n } else {\n basePath = path.join('src', cleanPath);\n }\n } else {\n basePath = path.join('src', 'features', sliceName, 'store');\n }\n\n return {\n basePath,\n slicePath: path.join(projectPath, basePath, sliceName),\n };\n};\n\nconst resolveShouldTest = (\n options: { test?: boolean; noTest?: boolean },\n hasTests: boolean,\n): boolean => {\n if (options.noTest) return false;\n if (options.test) return true;\n return hasTests;\n};\n\nconst printSliceSuccess = (\n sliceOptions: { sliceName: string; persistSlice: boolean },\n basePath: string,\n testFile: string | null,\n projectPath: string,\n) => {\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 if (testFile) log(pc.dim(` \uD83E\uDDEA ${path.relative(projectPath, testFile)}\\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};\n", "import Enquirer from 'enquirer';\n\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 path from 'node:path';\nimport type { Command } from 'commander';\nimport pc from 'picocolors';\nimport { log, logError, spinner } from '../config';\nimport { kebabToCamel, kebabToPascal } from '../config/utils';\nimport { fileExists, readFile } from '../core/files';\nimport { detectProjectSetup } from '../detection';\nimport { generateTest, type TestKind } from '../generators';\n\ninterface TestCommandOptions {\n kind?: string;\n force?: boolean;\n}\n\nexport const registerTestCommand = (program: Command) => {\n program\n .command('test <file>')\n .description(\n 'Generate a sibling test file for an existing component, hook, or slice.\\n' +\n 'Infers the kind from filename/content; pass --kind to override.',\n )\n .option('--kind <kind>', 'Override inferred kind: component | hook | slice')\n .option('--force', 'Overwrite an existing test file')\n .action(async (file: string, options: TestCommandOptions) => {\n try {\n const projectPath = process.cwd();\n const sourceFile = path.isAbsolute(file) ? file : path.join(projectPath, file);\n\n log(pc.cyan('\\n\uD83E\uDDEA Test Generator\\n'));\n\n if (!fileExists(sourceFile)) {\n logError(`Source file not found: ${file}`);\n process.exit(1);\n }\n\n const detection = await detectProjectSetup(projectPath);\n if (!detection.hasTests) {\n logError(\n 'Testing is not installed in this project. Run `next-maker setup --tests` first.',\n );\n process.exit(1);\n }\n\n const content = await readFile(sourceFile);\n const kind = validateKind(options.kind) ?? inferKind(sourceFile, content);\n if (!kind) {\n logError(\n `Could not infer test kind for ${path.basename(sourceFile)}. Pass --kind component|hook|slice.`,\n );\n process.exit(1);\n }\n\n const symbolName = inferSymbolName(sourceFile, kind);\n\n const testPath = getTestPath(sourceFile, kind);\n if (fileExists(testPath) && !options.force) {\n logError(\n `Test file already exists: ${path.relative(projectPath, testPath)}. Use --force to overwrite.`,\n );\n process.exit(1);\n }\n\n spinner.start(`Generating ${kind} test...`);\n const written = await generateTest({\n projectPath,\n sourceFile,\n kind,\n symbolName,\n hasRedux: detection.hasRedux,\n hasI18n: detection.hasI18n,\n hookUsesStore:\n kind === 'hook' && detection.hasRedux && content.includes('useAppSelector'),\n });\n spinner.succeed('Test generated');\n\n log(pc.green(`\\n\u2728 Test '${path.basename(written)}' created.\\n`));\n log(pc.dim(` \uD83E\uDDEA ${path.relative(projectPath, written)}`));\n log('');\n } catch (error) {\n spinner.fail('Test generation failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n\nconst validateKind = (input: string | undefined): TestKind | null => {\n if (!input) return null;\n if (input === 'component' || input === 'hook' || input === 'slice') return input;\n throw new Error(`Invalid --kind: ${input}. Use component | hook | slice.`);\n};\n\nconst inferKind = (sourceFile: string, content: string): TestKind | null => {\n const base = path.basename(sourceFile);\n if (/\\.slice\\.ts$/.test(base)) return 'slice';\n if (/^use[A-Z]/.test(base.replace(/\\.tsx?$/, ''))) return 'hook';\n if (base.endsWith('.tsx')) return 'component';\n // .ts file that's not a slice and not a hook \u2014 check content for signals.\n if (/createSlice\\s*\\(/.test(content)) return 'slice';\n if (/^export\\s+(const|function)\\s+use[A-Z]/m.test(content)) return 'hook';\n return null;\n};\n\nconst inferSymbolName = (sourceFile: string, kind: TestKind): string => {\n const base = path.basename(sourceFile).replace(/\\.(tsx?|jsx?)$/i, '');\n if (kind === 'slice') {\n // counter.slice \u2192 counter\n return kebabToCamel(base.replace(/\\.slice$/, ''));\n }\n if (kind === 'hook') {\n // useCounter.ts \u2192 useCounter; use-counter.ts \u2192 useCounter\n if (/^use[A-Z]/.test(base)) return base;\n return `use${kebabToPascal(base.replace(/^use-?/, ''))}`;\n }\n return kebabToPascal(base);\n};\n\nconst getTestPath = (sourceFile: string, kind: TestKind): string => {\n const dir = path.dirname(sourceFile);\n const base = path.basename(sourceFile).replace(/\\.(tsx?|jsx?)$/i, '');\n const ext = kind === 'component' ? '.tsx' : '.ts';\n return path.join(dir, `${base}.test${ext}`);\n};\n", "import type { Command } from 'commander';\nimport { registerAppCommand } from './app';\nimport { registerComponentCommand } from './component';\nimport { registerDoctorCommand } from './doctor';\nimport { registerEnvCommand } from './env';\nimport { registerFaviconCommand } from './favicon';\nimport { registerFeatureCommand } from './feature';\nimport { registerHookCommand } from './hook';\nimport { registerLayoutCommand } from './layout';\nimport { registerLocaleCommand } from './locale';\nimport { registerPageCommand } from './page';\nimport { registerProviderCommand } from './provider';\nimport { registerRemoveCommand } from './remove';\nimport { registerServiceCommand } from './service';\nimport { registerSetupCommand } from './setup';\nimport { registerSliceCommand } from './slice';\nimport { registerTestCommand } from './test';\n\nexport const registerCommands = (program: Command) => {\n registerAppCommand(program);\n registerSetupCommand(program);\n registerFeatureCommand(program);\n registerSliceCommand(program);\n registerServiceCommand(program);\n registerPageCommand(program);\n registerLayoutCommand(program);\n registerComponentCommand(program);\n registerLocaleCommand(program);\n registerHookCommand(program);\n registerProviderCommand(program);\n registerEnvCommand(program);\n registerFaviconCommand(program);\n registerDoctorCommand(program);\n registerRemoveCommand(program);\n registerTestCommand(program);\n};\n"],
|
|
5
|
+
"mappings": "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c,CAAW,CAC/B,EAEMD,GAAgB,MACpBV,EACAH,EACA6B,IACoB,CAEpB,IAAMC,EAAeD,EAAY,IAAM,IACjCE,EAAY,KAAK,MACrB,KAAK,IAAI,KAAaD,CAAY,GAAK,EAAK9B,EAAQ,QAAU,EAAK,IACrE,EAEMgC,EAAQ,MAAMxB,GAAU,CAC5B,aAAAL,EACA,KAAM4B,EACN,MAAO/B,EAAQ,MACf,cAAeA,EAAQ,OACvB,GAAI,cACJ,eAAgB,EAChB,IAAKA,EAAQ,IACb,QAASA,EAAQ,OACnB,CAAC,EAEKiC,EAAUjC,EAAQ,KAAO,cAAgB,UAAYA,EAAQ,GAC7DkC,EAAa,MAAMC,GAAUF,CAAO,EACpCG,EAAa,KAAK,OAAO,KAAcL,GAAa,CAAC,EACrDM,EAAY,KAAK,OAAOP,EAAeC,GAAa,CAAC,EAE3D,OAAOO,GAAM,CACX,OAAQ,CACN,MAAO,KACP,OAAQR,EACR,SAAU,EACV,WAAAI,CACF,CACF,CAAC,EACE,UAAU,CAAC,CAAE,MAAOF,EAAO,KAAMI,EAAY,IAAKC,CAAU,CAAC,CAAC,EAC9D,IAAI,EACJ,SAAS,CACd,EKjNO,IAAME,GAAmB,IAAI,IAAI,CACtC,YACA,eACA,OACA,aACA,QACA,QACA,SACA,QACA,iBACA,OACA,aACA,QACA,YACA,YACA,aACA,YACA,QACA,iBACA,WACA,UACA,OACA,WACA,WACA,gBACA,WACA,YACA,WACA,YACA,cACA,iBACA,aACA,aACA,UACA,aACA,eACA,gBACA,gBACA,gBACA,gBACA,aACA,WACA,cACA,UACA,UACA,aACA,YACA,cACA,cACA,UACA,YACA,aACA,OACA,YACA,OACA,QACA,cACA,OACA,WACA,UACA,YACA,SACA,QACA,QACA,WACA,gBACA,YACA,eACA,YACA,aACA,YACA,uBACA,YACA,aACA,YACA,YACA,cACA,gBACA,eACA,iBACA,iBACA,iBACA,cACA,OACA,YACA,QACA,UACA,SACA,mBACA,aACA,eACA,eACA,iBACA,kBACA,oBACA,kBACA,kBACA,eACA,YACA,YACA,WACA,cACA,OACA,UACA,QACA,YA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",
|
|
6
|
+
"names": ["existsSync", "fs", "path", "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", "exec", "path", "promisify", "execAsync", "init_injectors", "__esmMin", "init_paths", "init_files", "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", "existsSync", "access", "path", "directoryExists", "fileExistsAt", "init_existence_checker", "__esmMin", "projectPath", "name", "basePath", "fileName", "access", "readFile", "path", "detectProjectSetup", "init_project_detector", "__esmMin", "projectPath", "packageJsonPath", "packageJsonContent", "packageJson", "dependencies", "hasRedux", "hasI18n", "hasAxios", "hasFetch", "axiosClientPath", "fetchClientPath", "httpClient", "hasTests", "error", "detection_exports", "__export", "detectProjectSetup", "directoryExists", "fileExistsAt", "init_detection", "__esmMin", "init_existence_checker", "init_project_detector", "Command", "path", "pc", "setupCancellationHandlers", "options", "logger", "m", "exitOnCancel", "onCancel", "onUncaught", "err", "onRejection", "reason", "pc", "colorMap", "s", "print", "message", "color", "colorFn", "text", "error", "message", "print", "logError", "warning", "log", "message", "print", "printBanner", "ora", "startSpinner", "text", "options", "spinner", "capitalize", "str", "kebabToCamel", "_", "letter", "kebabToPascal", "ora", "spinner", "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", "getDevFlag", "installDevPackages", "installCommand", "flag", "installDevPackage", "uninstallPackages", "getUninstallCommand", "uninstallPackage", "Enquirer", "PROJECT_NAME_RE", "SEMVER_RE", "isValidProjectName", "value", "isValidSemver", "defaultProjectAnswers", "initialName", "overrides", "projectName", "version", "author", "company", "prompt", "promptForProjectDetails", "response", "answers", "baseUrl", "init_files", "path", "writeTestUtils", "projectPath", "features", "content", "pickTemplate", "writeFile", "redux", "i18n", "BOTH", "REDUX_ONLY", "I18N_ONLY", "MINIMAL", "path", "PACKAGES", "init_paths", "init_files", "cleanupBundleAnalyzer", "projectPath", "answers", "nextConfigPath", "path", "PROJECT_PATHS", "fileExists", "content", "readFile", "writeFile", "updateJson", "pkg", "PACKAGES", "init_paths", "init_files", "path", "cleanupDarkMode", "projectPath", "answers", "deleteFile", "PROJECT_PATHS", "removeThemeProviderExport", "removeDarkModeCSS", "removeDarkModeFromLayout", "providersIndexPath", "content", "readFile", "writeFile", "globalsCssPath", "fileExists", "stripDarkModeClasses", "layoutPaths", "layoutPath", "original", "updated", "init_paths", "init_files", "init_injectors", "path", "cleanupHttpClient", "projectPath", "answers", "httpUtilsPath", "PROJECT_PATHS", "keepSecureStorage", "cleanupNoHttpClient", "cleanupFetchClient", "cleanupAxiosClient", "deleteDirectory", "writeFile", "deleteFile", "cleanupHttpTypes", "removeHttpExports", "removeAppApisExport", "removeApiConstants", "removeTypesExports", "content", "readFile", "httpTypesPath", "fileExists", "typesContent", "utilsIndexPath", "configIndexPath", "constantsPath", "typesIndexPath", "init_paths", "init_files", "path", "cleanupI18n", "projectPath", "answers", "deleteI18nFiles", "removeI18nExports", "removeI18nFromNextConfig", "removeI18nFromCounter", "removeI18nFromEnv", "envPath", "PROJECT_PATHS", "fileExists", "content", "readFile", "writeFile", "deleteDirectory", "deleteFile", "typesIndexPath", "configIndexPath", "nextConfigPath", "counterComponentPath", "counterTestPath", "testUtilsPath", "init_paths", "init_files", "path", "cleanupSecureStorage", "projectPath", "answers", "deleteDirectory", "PROJECT_PATHS", "cleanupLicense", "deleteFile", "cleanupChangelog", "cleanupConfig", "cleanupTemplateArtifacts", "path", "init_paths", "init_files", "cleanupReactCompiler", "projectPath", "answers", "nextConfigPath", "path", "PROJECT_PATHS", "fileExists", "content", "readFile", "writeFile", "updateJson", "pkg", "PACKAGES", "init_paths", "init_files", "path", "cleanupRedux", "projectPath", "answers", "deleteDirectory", "PROJECT_PATHS", "deleteFile", "removeStoreProviderExport", "removeCounterFromPages", "providersIndexPath", "content", "readFile", "writeFile", "pagesToClean", "pagePath", "fileExists", "path", "init_paths", "init_files", "TEST_DEVDEPS", "PACKAGES", "cleanupTests", "projectPath", "answers", "deleteFile", "path", "PROJECT_PATHS", "deleteDirectory", "updateJson", "pkg", "dep", "cleanupFeatures", "projectPath", "answers", "spinner", "startSpinner", "cleanupHttpClient", "cleanupSecureStorage", "cleanupRedux", "cleanupDarkMode", "cleanupBundleAnalyzer", "cleanupI18n", "cleanupReactCompiler", "cleanupTests", "cleanupLicense", "cleanupChangelog", "cleanupConfig", "cleanupTemplateArtifacts", "writeTestUtils", "error", "path", "init_paths", "init_files", "configurePackageJson", "projectPath", "answers", "spinner", "startSpinner", "gitRemote", "gitHomepage", "gitIssues", "updateJson", "path", "PROJECT_PATHS", "pkg", "PACKAGES", "error", "readdir", "path", "init_paths", "init_files", "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", "init_paths", "init_files", "path", "generateRootProvider", "projectPath", "answers", "imports", "propsFields", "destructureFields", "jsx", "propsType", "rootProviderContent", "writeFile", "PROJECT_PATHS", "generateLayout", "htmlClasses", "providerPropsLine", "basicLayout", "counterImport", "counterComponent", "basicPage", "degit", "cloneTemplate", "projectPath", "spinner", "startSpinner", "degit", "error", "VALID_PACKAGE_MANAGERS", "validatePackageManagerOverride", "raw", "registerAppCommand", "program", "name", "options", "packageManager", "createApp", "err", "logError", "withStepSpinner", "text", "successText", "fn", "ref", "spinner", "startSpinner", "result", "summariseDefaults", "answers", "features", "log", "pc", "initialName", "flags", "printBanner", "defaultProjectAnswers", "promptForProjectDetails", "projectPath", "path", "fileExists", "active", "performCleanup", "deleteDirectory", "cleanupErr", "handleSignal", "cloneTemplate", "configurePackageJson", "cleanupFeatures", "generateRootProvider", "generateLayout", "setupDevTools", "initializeGit", "installDependencies", "runScript", "envExamplePath", "envPath", "path", "pc", "init_detection", "mkdir", "writeFile", "path", "init_files", "sharedComponentTemplate", "params", "componentName", "isClient", "hasI18n", "ns", "lines", "componentBarrelTemplate", "generateComponent", "options", "name", "projectPath", "isClient", "hasI18n", "featurePath", "componentName", "kebabToPascal", "generateFeatureComponent", "generateSharedComponent", "componentsDir", "path", "mkdir", "writeFile", "sharedComponentTemplate", "_kebabName", "componentDir", "componentBarrelTemplate", "commonIndexPath", "appendExport", "rootIndexPath", "ensureCommonReExport", "filePath", "exportLine", "content", "fileExists", "readFile", "commonExport", "writeFile", "path", "crudServiceTemplate", "params", "camelName", "pascalName", "httpClient", "clientImport", "clientName", "crudApiConfigTemplate", "kebabName", "generateCrudService", "options", "name", "outputPath", "httpClient", "camelName", "kebabToCamel", "pascalName", "kebabToPascal", "writeFile", "path", "crudServiceTemplate", "mkdir", "writeFile", "path", "writeFile", "path", "serviceTemplate", "params", "camelName", "httpClient", "generateService", "options", "name", "outputPath", "httpClient", "camelName", "kebabToCamel", "writeFile", "path", "serviceTemplate", "mkdir", "writeFile", "path", "sliceBarrelTemplate", "params", "sliceName", "withPersist", "featureBarrelTemplate", "featureName", "componentName", "hookName", "withStore", "withService", "persistTemplate", "params", "componentName", "camelName", "typesImportPath", "versionConst", "selectorsTemplate", "params", "componentName", "camelName", "sliceName", "sliceTemplate", "params", "componentName", "camelName", "typesImportPath", "stateTypesTemplate", "params", "componentName", "withStore", "generateSlice", "options", "name", "outputPath", "persist", "typesImportPath", "mkdir", "componentName", "kebabToPascal", "camelName", "kebabToCamel", "writeFile", "path", "stateTypesTemplate", "sliceTemplate", "selectorsTemplate", "persistTemplate", "sliceBarrelTemplate", "componentTemplate", "params", "componentName", "hookName", "hookWithStoreTemplate", "params", "hookName", "componentName", "featureName", "hookWithoutStoreTemplate", "generateFeature", "options", "name", "outputPath", "createStore", "persistStore", "createService", "httpClient", "componentName", "kebabToPascal", "hookName", "dirs", "path", "dir", "mkdir", "writeFile", "componentTemplate", "hookWithStoreTemplate", "hookWithoutStoreTemplate", "stateTypesTemplate", "featureBarrelTemplate", "generateSlice", "generateService", "mkdir", "writeFile", "path", "customHookTemplate", "params", "hookName", "isClient", "lines", "generateHook", "options", "name", "projectPath", "isClient", "featurePath", "hookName", "kebabToPascal", "hooksDir", "path", "mkdir", "writeFile", "customHookTemplate", "mkdir", "path", "init_files", "i18nTemplate", "componentName", "plainTemplate", "layoutTemplate", "hasI18n", "SEGMENT_RE", "SEGMENT_LIST_RE", "validateSegment", "segment", "validateAt", "at", "generateLayout", "options", "projectPath", "hasI18n", "withGroup", "componentName", "kebabToPascal", "leaf", "baseSegments", "targetDir", "path", "layoutFile", "fileExists", "mkdir", "writeFile", "layoutTemplate", "init_files", "copyFile", "readFileFs", "writeFile", "path", "generateLocale", "options", "code", "name", "country", "flag", "projectPath", "copyTranslations", "createTranslationFile", "updateSupportedLocaleType", "updateAppLocalesConfig", "translationsDir", "sourcePath", "destPath", "sourceContent", "sourceJson", "emptyJson", "emptyValues", "obj", "result", "key", "value", "typesPath", "fileExists", "content", "readFile", "localeTypeRegex", "match", "newType", "localeName", "configPath", "closingBracket", "newLocale", "mkdir", "writeFile", "path", "pageTemplate", "params", "componentName", "routePath", "hasI18n", "dynamicPageTemplate", "paramName", "loadingTemplate", "errorTemplate", "generatePage", "options", "name", "projectPath", "hasI18n", "dynamic", "withLoading", "withError", "componentName", "kebabToPascal", "routePath", "baseDir", "pageDir", "path", "mkdir", "pageContent", "dynamicPageTemplate", "pageTemplate", "writeFile", "loadingTemplate", "errorTemplate", "init_paths", "mkdir", "path", "init_files", "ensureSuffix", "name", "suffix", "providerTemplate", "baseName", "componentName", "root", "valueType", "contextName", "hookName", "providerComponentName", "NAME_RE", "toPascal", "name", "kebabToPascal", "generateProvider", "options", "projectPath", "baseName", "componentName", "providerComponentName", "fileBaseName", "providerDir", "path", "PROJECT_PATHS", "providerFile", "fileExists", "mkdir", "writeFile", "providerTemplate", "init_files", "path", "componentTestTemplate", "params", "componentName", "sourceImportPath", "testUtilsImportPath", "hasRedux", "hasI18n", "extraOptions", "optionsBlock", "hookTestTemplate", "hookName", "withStore", "sliceTestTemplate", "camelName", "sliceRef", "generateTest", "options", "projectPath", "sourceFile", "kind", "symbolName", "testDir", "path", "sourceBaseName", "extension", "testFile", "sourceImportPath", "testUtilsImportPath", "relativeImport", "content", "componentTestTemplate", "hookTestTemplate", "sliceTestTemplate", "writeFile", "from", "to", "rel", "Enquirer", "prompt", "promptForComponentDetails", "name", "presets", "questions", "value", "answers", "registerComponentCommand", "program", "name", "options", "projectPath", "log", "pc", "spinner", "detection", "detectProjectSetup", "componentOptions", "promptForComponentDetails", "componentName", "kebabToPascal", "isClient", "hasI18n", "shouldTest", "resolveShouldTest", "generateComponent", "testFile", "componentFile", "path", "generateTest", "location", "error", "logError", "hasTests", "pc", "init_paths", "init_files", "path", "init_paths", "path", "pc", "init_files", "setupBundleAnalyzer", "projectPath", "spinner", "startSpinner", "nextConfigPath", "path", "PROJECT_PATHS", "fileExists", "content", "readFile", "exportDefaultRe", "match", "replacement", "writeFile", "updateJson", "pkg", "installDevPackage", "pc", "error", "removeNamedImport", "content", "symbol", "lines", "out", "defaultRe", "namedRe", "line", "m", "symbols", "s", "filtered", "unwrapJsxChain", "componentName", "openRe", "openIdx", "openIndent", "i", "escapedIndent", "closeRe", "closeIdx", "inner", "merged", "unwrapNextIntlPlugin", "content", "result", "line", "callRe", "unwrapBundleAnalyzer", "removeNamedImport", "blockRe", "bundleAnalyzerManifest", "projectPath", "target", "path", "PROJECT_PATHS", "fileExists", "readFile", "unwrapBundleAnalyzer", "setupBundleAnalyzer", "init_paths", "init_files", "path", "init_paths", "path", "pc", "init_files", "addCommitizen", "pkg", "scripts", "devDeps", "PACKAGES", "missingCommitizenDeps", "missing", "CZRC_CONTENT", "setupCommitizen", "projectPath", "spinner", "startSpinner", "czrcPath", "path", "PROJECT_PATHS", "fileExists", "writeFile", "pkgPath", "beforePkg", "readFile", "missing", "missingCommitizenDeps", "updateJson", "pkg", "addCommitizen", "manager", "detectPackageManager", "installDevPackages", "pc", "error", "commitizenManifest", "projectPath", "fileExists", "path", "PROJECT_PATHS", "setupCommitizen", "init_paths", "init_files", "path", "path", "pc", "init_files", "init_paths", "init_files", "path", "degit", "fetchAssets", "tempDir", "spinner", "copyThemeProvider", "projectPath", "themeProviderPath", "PROJECT_PATHS", "sourceProviderPath", "copyFile", "init_paths", "init_files", "path", "init_paths", "init_files", "path", "findLayoutPath", "projectPath", "possibleLayoutPaths", "PROJECT_PATHS", "p", "fileExists", "readFile", "checkIsAlreadySetup", "projectPath", "themeProviderPath", "path", "PROJECT_PATHS", "globalsCssPath", "packageJsonPath", "fileExists", "packageJson", "readFile", "themesPkg", "validateProjectStructure", "providersIndexPath", "layoutPath", "findLayoutPath", "init_paths", "init_files", "path", "updateProvidersIndex", "projectPath", "providersIndexPath", "PROJECT_PATHS", "providersContent", "readFile", "writeFile", "updateRootProvider", "rootProviderPath", "fileExists", "content", "useClientDirective", "hasUseClient", "_m", "open", "names", "close", "returnMatch", "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", "darkThemeManifest", "projectPath", "fileExists", "path", "PROJECT_PATHS", "unwrapJsxChain", "setupDarkTheme", "fs", "path", "Enquirer", "pc", "init_files", "init_paths", "init_files", "fs", "path", "degit", "fetchAssets", "tempDir", "spinner", "copyHttpClientFiles", "projectPath", "clients", "removeClients", "httpUtilsPath", "PROJECT_PATHS", "tempHttpUtilsPath", "appApisPath", "fileExists", "copyFile", "apiUrlPath", "constantsPath", "content", "readFile", "modified", "writeFile", "storageServicePath", "client", "clientPath", "deleteDirectory", "performFullCleanup", "isFileUsed", "isStringUsed", "errorsDir", "errorFiles", "isAnyErrorUsed", "file", "name", "commonTypesPath", "utilityTypesPath", "init_paths", "init_files", "path", "checkIsAlreadySetup", "projectPath", "fetchClientPath", "PROJECT_PATHS", "axiosClientPath", "hasFetch", "fileExists", "hasAxios", "validateProjectStructure", "missingPaths", "p", "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", "httpClientManifest", "projectPath", "detectProjectSetup", "setupHttpClient", "init_paths", "path", "pc", "init_files", "init_paths", "init_files", "fs", "path", "degit", "fetchAssets", "tempDir", "spinner", "copyI18nFiles", "projectPath", "sourceI18nDir", "destI18nDir", "PROJECT_PATHS", "sourceProxyPath", "destProxyPath", "copyFile", "sourceTypesPath", "destTypesPath", "sourceLocalesPath", "destLocalesPath", "init_paths", "init_files", "path", "checkIsAlreadySetup", "projectPath", "i18nDir", "PROJECT_PATHS", "packageJsonPath", "fileExists", "packageJson", "readFile", "validateProjectStructure", "rootLayoutPath", "localeLayoutPath", "init_paths", "init_files", "fs", "path", "updateNextConfig", "projectPath", "nextConfigPath", "PROJECT_PATHS", "fileExists", "content", "readFile", "exportDefaultRegex", "writeFile", "updateTypesIndex", "typesIndexPath", "updateConfigIndex", "configIndexPath", "updateRootProvider", "rootProviderPath", "useClientDirective", "hasUseClient", "i18nFields", "aliasRe", "inlineRe", "_m", "open", "body", "close", "trimmed", "inner", "existing", "match", "existingParams", "existingTypes", "newParams", "newTypes", "returnMatch", "existingJsx", "wrapped", "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", "vitestConfigPath", "PROJECT_PATHS", "fileExists", "pkg", "readFile", "deps", "hasRedux", "writeTestUtils", "packageManager", "detectPackageManager", "runScript", "pc", "error", "deleteDirectory", "i18nManifest", "projectPath", "detectProjectSetup", "unwrapNextIntlPlugin", "unwrapJsxChain", "setupI18n", "init_paths", "init_files", "path", "init_paths", "path", "pc", "init_files", "setupReactCompiler", "projectPath", "spinner", "startSpinner", "nextConfigPath", "path", "PROJECT_PATHS", "fileExists", "content", "readFile", "configBlock", "writeFile", "installDevPackage", "pc", "error", "reactCompilerManifest", "projectPath", "target", "path", "PROJECT_PATHS", "fileExists", "readFile", "setupReactCompiler", "init_paths", "path", "pc", "init_files", "init_paths", "init_files", "fs", "path", "degit", "fetchAssets", "tempDir", "spinner", "copyReduxFiles", "projectPath", "sourceProviderPath", "destProviderPath", "PROJECT_PATHS", "copyFile", "sourceStoreDir", "destStoreDir", "createCounterFeature", "sourceFeatureDir", "destFeatureDir", "counterComponentPath", "fileExists", "content", "readFile", "writeFile", "init_paths", "init_files", "path", "checkIsAlreadySetup", "projectPath", "storePath", "path", "PROJECT_PATHS", "packageJsonPath", "fileExists", "packageJson", "readFile", "validateProjectStructure", "providersIndexPath", "findLayoutPath", "init_paths", "init_files", "path", "updateProvidersIndex", "_projectPath", "updateRootProvider", "projectPath", "rootProviderPath", "fileExists", "content", "readFile", "useClientDirective", "hasUseClient", "_m", "inner", "returnMatch", "existingJsx", "writeFile", "updatePage", "possiblePagePaths", "PROJECT_PATHS", "pagePath", "p", "pageContent", "lastDivIndex", "lastMainIndex", "insertIndex", "setupRedux", "projectPath", "spinner", "startSpinner", "tempDir", "path", "isSetup", "reason", "checkIsAlreadySetup", "validateProjectStructure", "fetchAssets", "copyReduxFiles", "createCounterFeature", "updateProvidersIndex", "updateRootProvider", "updatePage", "installPackage", "vitestConfigPath", "PROJECT_PATHS", "fileExists", "pkg", "readFile", "deps", "writeTestUtils", "packageManager", "detectPackageManager", "runScript", "pc", "error", "deleteDirectory", "reduxManifest", "projectPath", "detectProjectSetup", "unwrapJsxChain", "setupRedux", "init_paths", "init_files", "path", "init_paths", "path", "pc", "init_files", "SECURITY_HEADERS", "NEXT_CONFIG_BLOCK_RE", "HEADERS_KEY_RE", "buildHeadersBlock", "headers", "key", "value", "hasSecurityHeaders", "content", "injectSecurityHeaders", "setupSecurityHeaders", "projectPath", "spinner", "startSpinner", "nextConfigPath", "path", "PROJECT_PATHS", "fileExists", "content", "readFile", "hasSecurityHeaders", "updated", "injectSecurityHeaders", "writeFile", "pc", "error", "securityHeadersManifest", "projectPath", "target", "path", "PROJECT_PATHS", "fileExists", "hasSecurityHeaders", "readFile", "setupSecurityHeaders", "init_paths", "init_files", "path", "init_paths", "fs", "path", "degit", "pc", "init_files", "TEST_DEVDEPS", "setupTests", "projectPath", "spinner", "startSpinner", "tempDir", "path", "vitestConfigPath", "PROJECT_PATHS", "fileExists", "degit", "copyFile", "testDir", "fs", "packageJsonPath", "pkg", "readFile", "deps", "hasRedux", "hasI18n", "writeTestUtils", "updateJson", "p", "manager", "detectPackageManager", "installDevPackages", "runScript", "pc", "error", "deleteDirectory", "testsManifest", "projectPath", "fileExists", "path", "PROJECT_PATHS", "setupTests", "init_files", "path", "init_paths", "path", "pc", "init_files", "SCRIPT_RUNNER_PREFIX", "buildValidateChain", "manager", "prefix", "name", "addValidationScripts", "pkg", "scripts", "devDeps", "SYNC_ENV_SCRIPT", "CHECK_DEPRECATED_SCRIPT", "SCRIPT_TARGETS", "SYNC_ENV_SCRIPT", "CHECK_DEPRECATED_SCRIPT", "setupValidationScripts", "projectPath", "spinner", "startSpinner", "wroteAny", "relative", "content", "target", "path", "fileExists", "writeFile", "manager", "detectPackageManager", "needsTsx", "updateJson", "PROJECT_PATHS", "pkg", "before", "next", "addValidationScripts", "installDevPackages", "pc", "error", "SCRIPT_FILES", "validateScriptsManifest", "projectPath", "rel", "fileExists", "path", "p", "setupValidationScripts", "init_paths", "init_files", "path", "readPackageJson", "projectPath", "pkgPath", "path", "PROJECT_PATHS", "fileExists", "readFile", "writePackageJson", "pkg", "writeFile", "depsFor", "kind", "checkManifest", "manifest", "installed", "drift", "file", "dep", "scripts", "script", "actual", "injection", "filePath", "content", "reverseManifest", "options", "dryRun", "summary", "stripped", "out", "rm", "target", "description", "touched", "manager", "detectPackageManager", "uninstallPackages", "MANIFESTS", "securityHeadersManifest", "validateScriptsManifest", "commitizenManifest", "reactCompilerManifest", "bundleAnalyzerManifest", "testsManifest", "darkThemeManifest", "httpClientManifest", "reduxManifest", "i18nManifest", "getManifest", "id", "m", "formatFinding", "f", "pc", "summary", "results", "installed", "r", "drifted", "registerDoctorCommand", "program", "options", "projectPath", "targets", "MANIFESTS", "m", "manifest", "checkManifest", "log", "result", "drift", "stats", "error", "logError", "pc", "init_paths", "init_files", "path", "NAME_RE", "validateName", "name", "ensurePublicPrefix", "isPublic", "formatDefault", "spec", "baseSchemaTypeFor", "values", "v", "buildSchemaEntry", "fullName", "inner", "hasDefault", "optional", "expression", "escaped", "ENV_SCHEMA_RE", "injectSchemaEntry", "content", "match", "head", "body", "tail", "trimmedBody", "normalisedBody", "entry", "newBody", "PUBLIC_MARKER_SUFFIX", "exampleLineFor", "value", "trailing", "appendEnvExampleEntry", "trailingNewline", "blank", "description", "appendEnvEntry", "addEnvVar", "projectPath", "schemaPath", "fileExists", "schemaBefore", "readFile", "schemaAfter", "schemaUpdated", "writeFile", "envExamplePath", "PROJECT_PATHS", "envExampleUpdated", "before", "after", "envPath", "envUpdated", "VALID_TYPES", "parseType", "raw", "value", "parseEnum", "values", "v", "registerEnvCommand", "program", "name", "options", "projectPath", "log", "pc", "type", "enumValues", "spec", "spinner", "result", "addEnvVar", "fullName", "ensurePublicPrefix", "error", "logError", "path", "pc", "Enquirer", "prompt", "promptForFaviconSource", "presets", "value", "access", "readFile", "stat", "path", "exists", "p", "isDirectory", "detectAppDir", "projectPath", "candidates", "candidate", "PWA_PACKAGES", "detectPwa", "result", "publicCandidates", "appDir", "ext", "pkg", "deps", "name", "mkdir", "readFile", "stat", "writeFile", "path", "sharp", "pngToIco", "sharp", "escapeForXml", "value", "buildShapeMask", "shape", "size", "radiusPercent", "r", "buildSquircle", "s", "c", "path", "buildBackground", "color", "renderPng", "opts", "size", "paddingPercent", "bg", "fit", "shape", "radiusPercent", "quality", "forceSquare", "sourceBuffer", "innerSize", "sharpFit", "resized", "sharp", "offset", "canvasBg", "flatColor", "composed", "clipShape", "mask", "buildShapeMask", "clampCompression", "color", "probe", "buildBackground", "g", "b", "a", "n", "encodeIco", "frames", "pngToIco", "readFile", "writeFile", "buildIconEntries", "publicPaths", "src", "size", "patchJsonManifest", "manifestPath", "icons", "raw", "parsed", "existing", "bySrc", "icon", "renderManifestSnippet", "icons", "icon", "buildBootstrapManifest", "appName", "themeColor", "stat", "path", "SUPPORTED_EXTS", "validateSource", "source", "absolutePath", "info", "ext", "parseSizes", "raw", "fallback", "sizes", "s", "fileExists", "p", "stat", "writeAll", "jobs", "force", "dryRun", "results", "job", "mkdir", "path", "writeFile", "runFavicon", "projectPath", "options", "source", "validateSource", "sourceBuffer", "readFile", "ogSourceBuffer", "icoFrames", "size", "renderPng", "icoBuffer", "encodeIco", "buf", "appleBg", "renderOgImage", "pwaSnippet", "pwa", "detectPwa", "publicDir", "sizes", "iconJobs", "fileName", "icons", "buildIconEntries", "next", "patchJsonManifest", "renderManifestSnippet", "bootstrapPath", "content", "buildBootstrapManifest", "isTwitter", "targetHeight", "innerSize", "inner", "bgColor", "background", "flatColor", "offsetLeft", "offsetTop", "sharp", "CSS_NAMED_COLORS", "SHAPES", "FITS", "parseEnumOption", "raw", "allowed", "fallback", "flag", "parseNumberOption", "min", "max", "n", "registerFaviconCommand", "program", "projectPath", "log", "pc", "promptResult", "promptForFaviconSource", "outDir", "resolveOutDir", "shape", "fit", "radius", "padding", "quality", "icoSizes", "parseSizes", "bg", "validateBg", "all", "options", "spinner", "result", "runFavicon", "out", "rel", "path", "formatBytes", "err", "message", "logError", "override", "detected", "detectAppDir", "warning", "HEX_RE", "FUNCTIONAL_RE", "CSS_NAMED_COLORS", "path", "pc", "init_detection", "init_detection", "path", "readFile", "writeFile", "path", "addImportStatement", "fileContent", "importStatement", "importRegex", "imports", "lastImport", "lastImportIndex", "addToCombineReducers", "reducerKey", "reducerEntry", "combineReducersRegex", "match", "reducersContent", "newEntry", "updatedReducersContent", "addToAppApis", "endpointBlock", "insertPosition", "beforeClosing", "afterClosing", "registerApiEndpoints", "options", "serviceName", "projectPath", "camelName", "kebabToCamel", "apiConfigPath", "path", "content", "readFile", "newEndpoint", "addToAppApis", "writeFile", "error", "readFile", "writeFile", "path", "init_files", "registerAppPath", "projectPath", "routeName", "routePath", "appPathsFile", "path", "fileExists", "content", "readFile", "camelName", "kebabToCamel", "closingBrace", "newEntry", "writeFile", "init_paths", "init_files", "path", "COMPONENT_TAG_RE", "componentName", "injectProviderIntoChain", "content", "childrenLineRe", "match", "indent", "innerIndent", "replacement", "addProviderToBarrel", "fileBaseName", "exportLine", "lines", "exportLines", "others", "line", "merged", "firstExportIdx", "l", "before", "afterStart", "idx", "after", "PROVIDER_DIR_REL", "PROJECT_PATHS", "ROOT_PROVIDER_REL", "PROVIDERS_INDEX_REL", "findRootProviderFile", "projectPath", "fs", "fileExists", "readFile", "canonical", "path", "dir", "readdir", "candidates", "name", "best", "entry", "filePath", "contents", "depth", "registerProvider", "options", "rootProviderFile", "addImportStatement", "writeFile", "barrelPath", "barrelFile", "readFile", "writeFile", "path", "registerInRootReducer", "options", "projectPath", "name", "persist", "importPath", "rootReducerPath", "path", "content", "readFile", "camelName", "kebabToCamel", "reducerName", "persistConfigName", "aliasPath", "importStatement", "addImportStatement", "reducerEntry", "addToCombineReducers", "writeFile", "error", "init_files", "readFile", "writeFile", "path", "addTranslationNamespace", "projectPath", "namespace", "translationFile", "fileExists", "content", "json", "createFeaturePipelineSteps", "ctx", "detectProjectSetup", "generateFeature", "registerApiEndpoints", "registerInRootReducer", "path", "executePipeline", "steps", "context", "step", "error", "createServicePipelineSteps", "ctx", "generateService", "registerApiEndpoints", "path", "createSlicePipelineSteps", "ctx", "generateSlice", "registerInRootReducer", "path", "Enquirer", "prompt", "promptForFeatureDetails", "featureName", "hasRedux", "httpClient", "skipStore", "storeOption", "skipService", "serviceClient", "questions", "value", "answers", "registerFeatureCommand", "program", "name", "options", "projectPath", "validateFeatureOptions", "log", "pc", "steps", "createFeaturePipelineSteps", "spinner", "detectProjectSetup", "detection", "featureOptions", "promptForFeatureDetails", "basePath", "path", "featurePath", "directoryExists", "logError", "executePipeline", "printFeatureSuccess", "error", "displayPath", "importPath", "path", "pc", "init_detection", "Enquirer", "prompt", "promptForHookDetails", "name", "value", "registerHookCommand", "program", "name", "options", "projectPath", "log", "pc", "detection", "detectProjectSetup", "hookOptions", "promptForHookDetails", "hookName", "kebabToPascal", "shouldTest", "resolveShouldTest", "spinner", "generateHook", "hookFile", "path", "testFile", "generateTest", "location", "importPath", "error", "logError", "hasTests", "pc", "init_detection", "registerLayoutCommand", "program", "segment", "options", "projectPath", "log", "pc", "spinner", "detection", "detectProjectSetup", "hasI18n", "result", "generateLayout", "error", "logError", "path", "pc", "init_files", "init_detection", "Enquirer", "prompt", "promptForLocaleDetails", "code", "presets", "questions", "value", "answers", "registerLocaleCommand", "program", "code", "options", "projectPath", "log", "pc", "spinner", "detection", "detectProjectSetup", "logError", "localeOptions", "promptForLocaleDetails", "translationFile", "path", "fileExists", "generateLocale", "error", "path", "pc", "init_detection", "Enquirer", "prompt", "promptForPageDetails", "name", "presets", "questions", "value", "answers", "registerPageCommand", "program", "name", "options", "projectPath", "log", "pc", "spinner", "detection", "detectProjectSetup", "pageOptions", "promptForPageDetails", "pageName", "componentName", "kebabToPascal", "baseDir", "directoryExists", "logError", "generatePage", "routePath", "registerAppPath", "addTranslationNamespace", "displayPath", "path", "error", "path", "pc", "registerProviderCommand", "program", "name", "projectPath", "log", "pc", "spinner", "componentName", "fileBaseName", "providerFile", "generateProvider", "rootProviderFile", "barrelFile", "registerProvider", "path", "error", "logError", "Enquirer", "pc", "prompt", "Enquirer", "formatSummary", "summary", "lines", "file", "pc", "block", "script", "dep", "item", "isEmpty", "s", "registerRemoveCommand", "program", "feature", "options", "projectPath", "manifest", "getManifest", "MANIFESTS", "m", "log", "checkManifest", "spinner", "planned", "reverseManifest", "line", "confirm", "applied", "error", "logError", "existsSync", "mkdir", "path", "pc", "init_detection", "readFile", "writeFile", "path", "registerCrudApiEndpoints", "projectPath", "serviceName", "camelName", "kebabToCamel", "apiConfigPath", "path", "content", "readFile", "newEndpoint", "crudApiConfigTemplate", "addToAppApis", "writeFile", "error", "enquirer", "promptForServiceDetails", "name", "axiosFlag", "fetchFlag", "availableClients", "serviceName", "input", "httpClient", "registerServiceCommand", "program", "name", "options", "projectPath", "logError", "log", "pc", "spinner", "detection", "detectProjectSetup", "availableClients", "serviceOptions", "promptForServiceDetails", "basePath", "servicePath", "resolveServicePaths", "existsSync", "mkdir", "fileExistsAt", "generateCrudService", "registerCrudApiEndpoints", "executePipeline", "createServicePipelineSteps", "printServiceSuccess", "error", "serviceName", "customPath", "cleanPath", "featureName", "path", "isCrud", "displayPath", "importPath", "Enquirer", "pc", "prompt", "Enquirer", "registerSetupCommand", "program", "options", "log", "pc", "setupHttpClient", "setupDarkTheme", "setupRedux", "setupI18n", "setupTests", "setupReactCompiler", "setupBundleAnalyzer", "setupSecurityHeaders", "setupValidationScripts", "setupCommitizen", "feature", "handler", "error", "spinner", "logError", "existsSync", "mkdir", "path", "pc", "init_detection", "Enquirer", "prompt", "promptForSliceDetails", "sliceName", "persist", "noPersist", "questions", "value", "answers", "registerSliceCommand", "program", "name", "options", "projectPath", "logError", "log", "pc", "spinner", "detection", "detectProjectSetup", "sliceOptions", "promptForSliceDetails", "basePath", "slicePath", "resolveSlicePaths", "featureStorePath", "path", "existsSync", "mkdir", "directoryExists", "executePipeline", "createSlicePipelineSteps", "testFile", "resolveShouldTest", "sliceFile", "generateTest", "kebabToCamel", "printSliceSuccess", "error", "sliceName", "customPath", "cleanPath", "featureName", "hasTests", "displayPath", "importPath", "path", "pc", "init_files", "init_detection", "registerTestCommand", "program", "file", "options", "projectPath", "sourceFile", "path", "log", "pc", "fileExists", "logError", "detection", "detectProjectSetup", "content", "readFile", "kind", "validateKind", "inferKind", "symbolName", "inferSymbolName", "testPath", "getTestPath", "spinner", "written", "generateTest", "error", "input", "base", "kebabToCamel", "kebabToPascal", "dir", "ext", "registerCommands", "program", "registerAppCommand", "registerSetupCommand", "registerFeatureCommand", "registerSliceCommand", "registerServiceCommand", "registerPageCommand", "registerLayoutCommand", "registerComponentCommand", "registerLocaleCommand", "registerHookCommand", "registerProviderCommand", "registerEnvCommand", "registerFaviconCommand", "registerDoctorCommand", "registerRemoveCommand", "registerTestCommand", "originalEmitWarning", "warning", "_type", "_code", "_ctor", "main", "setupCancellationHandlers", "m", "error", "program", "Command", "registerCommands", "err", "message"]
|
|
7
7
|
}
|