@teispace/next-maker 1.17.1 → 1.19.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/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var di=Object.defineProperty;var Pe=(e,r)=>()=>(e&&(r=e(e=0)),r);var St=(e,r)=>{for(var t in r)di(e,t,{get:r[t],enumerable:!0})};import{existsSync as wt}from"node:fs";import de from"node:fs/promises";import Tr from"node:path";var u,f,_,T,S,k,m,P=Pe(()=>{"use strict";u=async e=>de.readFile(e,"utf-8"),f=async(e,r)=>{await de.mkdir(Tr.dirname(e),{recursive:!0}),await de.writeFile(e,r,"utf-8")},_=async(e,r)=>{await de.mkdir(Tr.dirname(r),{recursive:!0}),await de.copyFile(e,r)},T=async e=>{wt(e)&&await de.unlink(e)},S=async e=>{wt(e)&&await de.rm(e,{recursive:!0,force:!0})},k=async(e,r)=>{let t=await u(e),n=JSON.parse(t),i=r(n);await f(e,JSON.stringify(i,null,2))},m=e=>wt(e)});var Nr={};St(Nr,{PROJECT_PATHS:()=>c});var c,w=Pe(()=>{"use strict";c={NEXT_CONFIG:"next.config.ts",POSTCSS_CONFIG:"postcss.config.mjs",BIOME_CONFIG:"biome.json",VITEST_CONFIG:"vitest.config.ts",TEST_DIR:"test",TS_CONFIG:"tsconfig.json",PACKAGE_JSON:"package.json",ENV_EXAMPLE:".env.example",GITIGNORE:".gitignore",README:"README.md",LICENSE:"LICENSE",CHANGELOG:"CHANGELOG.md",NVM_RC:".nvmrc",NPM_RC:".npmrc",AGENTS_MD:"AGENTS.md",CLAUDE_MD:"CLAUDE.md",SRC:"src",APP:"src/app",COMPONENTS:"src/components",LIB:"src/lib",PROVIDERS:"src/providers",STYLES:"src/styles",TYPES:"src/types",UTILS:"src/lib/utils",HOOKS:"src/hooks",SERVICES:"src/services",STORE:"src/store",I18N:"src/i18n",GLOBALS_CSS:"src/styles/globals.css",ROOT_LAYOUT:"src/app/layout.tsx",ROOT_PAGE:"src/app/page.tsx",ROOT_PROVIDER:"src/providers/RootProvider.tsx",PROVIDERS_INDEX:"src/providers/index.ts",COMPONENTS_INDEX:"src/components/index.ts",TYPES_INDEX:"src/types/index.ts",UTILS_INDEX:"src/lib/utils/index.ts",CONFIG_INDEX:"src/lib/config/index.ts",CONSTANTS:"src/lib/config/constants.ts",APP_LOCALES:"src/lib/config/app-locales.ts",MIDDLEWARE:"src/middleware.ts",PROXY:"src/proxy.ts",I18N_TYPES:"src/types/i18n.ts",HTTP_UTILS:"src/lib/utils/http",AXIOS_CLIENT:"src/lib/utils/http/axios-client",FETCH_CLIENT:"src/lib/utils/http/fetch-client",AXIOS_CLIENT_FILE:"src/lib/utils/http/axios-client/index.ts",FETCH_CLIENT_FILE:"src/lib/utils/http/fetch-client/index.ts",CLIENT_UTILS:"src/lib/utils/http/client-utils.ts",APP_APIS:"src/lib/config/app-apis.ts",STORAGE_SERVICE:"src/services/storage",COUNTER_FEATURE:"src/features/counter",I18N_DIR:"src/i18n",LOCALE_DIR:"src/app/[locale]",ERRORS_DIR:"src/lib/errors",UTILITY_TYPES_DIR:"src/types/utility",COMMON_TYPES_DIR:"src/types/common",HTTP_TYPES:"src/types/common/http.types.ts",GITHUB_DIR:".github",HUSKY_DIR:".husky",STORE_PROVIDER:"src/providers/StoreProvider.tsx",THEME_PROVIDER:"src/providers/CustomThemeProvider.tsx",COUNTER_COMPONENT:"src/features/counter/components/Counter.tsx",LOCALE_PAGE:"src/app/[locale]/page.tsx",COMMITLINT_CONFIG:"commitlint.config.mjs",LINTSTAGED_RC:".lintstagedrc.mjs",CZRC:".czrc",DOCKERIGNORE:".dockerignore",DOCKERFILE:"Dockerfile",DOCKER_COMPOSE:"docker-compose.yml",GITHUB_WORKFLOWS:".github/workflows",GITHUB_ISSUE_TEMPLATE:"ISSUE_TEMPLATE",GITHUB_PR_TEMPLATE:"PULL_REQUEST_TEMPLATE.md",CODE_OF_CONDUCT:"CODE_OF_CONDUCT.md",CONTRIBUTING:"CONTRIBUTING.md",SECURITY:"SECURITY.md",SCRIPTS_DIR:"scripts",DOCS_DIR:"docs",CLAUDE_DIR:".claude",VSCODE_DIR:".vscode"}});var Or={};St(Or,{cleanupHttpTypes:()=>ve,isFileUsed:()=>Mi,isStringUsed:()=>Gi,migrateClientUsages:()=>It,removeHttpExports:()=>At,updateConfigIndex:()=>Nt,updateHttpIndex:()=>Rt,updateTypesIndex:()=>bt,updateUtilsIndex:()=>$t});import{exec as Di}from"node:child_process";import F from"node:path";import{promisify as Li}from"node:util";var Et,Rt,$t,bt,Nt,ve,It,At,Mi,Gi,it=Pe(()=>{"use strict";w();P();Et=Li(Di),Rt=async(e,r)=>{let t=F.join(e,c.HTTP_UTILS,"index.ts");if(m(t)){let n=await u(t);n=n.replace(/export .* from '\.\/axios-client';?\n?/g,""),n=n.replace(/export .* from '\.\/fetch-client';?\n?/g,""),r.includes("fetch")&&!n.includes("fetch-client")&&(n+=`export * from './fetch-client';
2
+ var fi=Object.defineProperty;var Pe=(e,r)=>()=>(e&&(r=e(e=0)),r);var St=(e,r)=>{for(var t in r)fi(e,t,{get:r[t],enumerable:!0})};import{existsSync as wt}from"node:fs";import de from"node:fs/promises";import Er from"node:path";var u,f,_,T,S,k,m,P=Pe(()=>{"use strict";u=async e=>de.readFile(e,"utf-8"),f=async(e,r)=>{await de.mkdir(Er.dirname(e),{recursive:!0}),await de.writeFile(e,r,"utf-8")},_=async(e,r)=>{await de.mkdir(Er.dirname(r),{recursive:!0}),await de.copyFile(e,r)},T=async e=>{wt(e)&&await de.unlink(e)},S=async e=>{wt(e)&&await de.rm(e,{recursive:!0,force:!0})},k=async(e,r)=>{let t=await u(e),n=JSON.parse(t),o=r(n);await f(e,JSON.stringify(o,null,2))},m=e=>wt(e)});var Ar={};St(Ar,{PROJECT_PATHS:()=>c});var c,w=Pe(()=>{"use strict";c={NEXT_CONFIG:"next.config.ts",POSTCSS_CONFIG:"postcss.config.mjs",BIOME_CONFIG:"biome.json",VITEST_CONFIG:"vitest.config.ts",TEST_DIR:"test",TS_CONFIG:"tsconfig.json",PACKAGE_JSON:"package.json",ENV_EXAMPLE:".env.example",GITIGNORE:".gitignore",README:"README.md",LICENSE:"LICENSE",CHANGELOG:"CHANGELOG.md",NVM_RC:".nvmrc",NPM_RC:".npmrc",AGENTS_MD:"AGENTS.md",CLAUDE_MD:"CLAUDE.md",SRC:"src",APP:"src/app",COMPONENTS:"src/components",LIB:"src/lib",PROVIDERS:"src/providers",STYLES:"src/styles",TYPES:"src/types",UTILS:"src/lib/utils",HOOKS:"src/hooks",SERVICES:"src/services",STORE:"src/store",I18N:"src/i18n",GLOBALS_CSS:"src/styles/globals.css",ROOT_LAYOUT:"src/app/layout.tsx",ROOT_PAGE:"src/app/page.tsx",ROOT_PROVIDER:"src/providers/RootProvider.tsx",PROVIDERS_INDEX:"src/providers/index.ts",COMPONENTS_INDEX:"src/components/index.ts",TYPES_INDEX:"src/types/index.ts",UTILS_INDEX:"src/lib/utils/index.ts",CONFIG_INDEX:"src/lib/config/index.ts",CONSTANTS:"src/lib/config/constants.ts",APP_LOCALES:"src/lib/config/app-locales.ts",MIDDLEWARE:"src/middleware.ts",PROXY:"src/proxy.ts",I18N_TYPES:"src/types/i18n.ts",HTTP_UTILS:"src/lib/utils/http",AXIOS_CLIENT:"src/lib/utils/http/axios-client",FETCH_CLIENT:"src/lib/utils/http/fetch-client",AXIOS_CLIENT_FILE:"src/lib/utils/http/axios-client/index.ts",FETCH_CLIENT_FILE:"src/lib/utils/http/fetch-client/index.ts",CLIENT_UTILS:"src/lib/utils/http/client-utils.ts",APP_APIS:"src/lib/config/app-apis.ts",STORAGE_SERVICE:"src/services/storage",COUNTER_FEATURE:"src/features/counter",I18N_DIR:"src/i18n",LOCALE_DIR:"src/app/[locale]",ERRORS_DIR:"src/lib/errors",UTILITY_TYPES_DIR:"src/types/utility",COMMON_TYPES_DIR:"src/types/common",HTTP_TYPES:"src/types/common/http.types.ts",GITHUB_DIR:".github",HUSKY_DIR:".husky",STORE_PROVIDER:"src/providers/StoreProvider.tsx",THEME_PROVIDER:"src/providers/CustomThemeProvider.tsx",COUNTER_COMPONENT:"src/features/counter/components/Counter.tsx",LOCALE_PAGE:"src/app/[locale]/page.tsx",COMMITLINT_CONFIG:"commitlint.config.mjs",LINTSTAGED_RC:".lintstagedrc.mjs",CZRC:".czrc",DOCKERIGNORE:".dockerignore",DOCKERFILE:"Dockerfile",DOCKER_COMPOSE:"docker-compose.yml",GITHUB_WORKFLOWS:".github/workflows",GITHUB_ISSUE_TEMPLATE:"ISSUE_TEMPLATE",GITHUB_PR_TEMPLATE:"PULL_REQUEST_TEMPLATE.md",CODE_OF_CONDUCT:"CODE_OF_CONDUCT.md",CONTRIBUTING:"CONTRIBUTING.md",SECURITY:"SECURITY.md",SCRIPTS_DIR:"scripts",DOCS_DIR:"docs",CLAUDE_DIR:".claude",VSCODE_DIR:".vscode"}});var Fr={};St(Fr,{cleanupHttpTypes:()=>ve,isFileUsed:()=>Ji,isStringUsed:()=>Bi,migrateClientUsages:()=>It,removeHttpExports:()=>At,updateConfigIndex:()=>Nt,updateHttpIndex:()=>Rt,updateTypesIndex:()=>bt,updateUtilsIndex:()=>$t});import{exec as zi}from"node:child_process";import F from"node:path";import{promisify as Vi}from"node:util";var Et,Rt,$t,bt,Nt,ve,It,At,Ji,Bi,it=Pe(()=>{"use strict";w();P();Et=Vi(zi),Rt=async(e,r)=>{let t=F.join(e,c.HTTP_UTILS,"index.ts");if(m(t)){let n=await u(t);n=n.replace(/export .* from '\.\/axios-client';?\n?/g,""),n=n.replace(/export .* from '\.\/fetch-client';?\n?/g,""),r.includes("fetch")&&!n.includes("fetch-client")&&(n+=`export * from './fetch-client';
3
3
  `),r.includes("axios")&&!n.includes("axios-client")&&(n+=`export * from './axios-client';
4
4
  `),await f(t,n)}},$t=async e=>{let r=F.join(e,c.UTILS_INDEX);if(m(r)){let t=await u(r);t.includes("./http")||(t+=`export * from './http';
5
5
  `,await f(r,t))}},bt=async e=>{let r=F.join(e,c.TYPES_INDEX);if(m(r)){let t=await u(r);t.includes("./common")||(t+=`export * from './common';
@@ -8,10 +8,10 @@ var di=Object.defineProperty;var Pe=(e,r)=>()=>(e&&(r=e(e=0)),r);var St=(e,r)=>{
8
8
  `,await f(r,t))}},ve=async(e,r)=>{let t=F.join(e,c.HTTP_TYPES);if(m(t)){let n=await u(t);r.includes("axios")||(n=n.replace(/declare module 'axios'\s*\{\s*export interface AxiosRequestConfig\s*\{[\s\S]*?\}\s*\}/g,""),n=`${n.replace(/\n\s*\n/g,`
9
9
 
10
10
  `).trim()}
11
- `,await f(t,n))}},It=async(e,r,t)=>{if(r===t)return;let n=r==="fetch"?"fetchClient":"axiosClient",i=t==="fetch"?"fetchClient":"axiosClient",o=r==="fetch"?"fetch-client":"axios-client",s=t==="fetch"?"fetch-client":"axios-client",a=F.join(e,"src");try{let p=`grep -rl "${n}" "${a}" --include="*.ts" --include="*.tsx" || true`,{stdout:d}=await Et(p);if(!d.trim())return;let g=d.trim().split(`
12
- `).filter(h=>h);for(let h of g){if(!m(h))continue;let y=await u(h),Y=!1,vt=new RegExp(`(import\\s*\\{[^}]*?)\\b${n}\\b([^}]*?\\}\\s*from\\s*['"][^'"]*?/http['"])`,"g");vt.test(y)&&(y=y.replace(vt,`$1${i}$2`),Y=!0);let tt=new RegExp(`import\\s+${n}\\s+from\\s+['"]([^'"]*?)/${o}['"]`,"g");tt.test(y)&&(y=y.replace(tt,`import ${i} from '$1/${s}'`),Y=!0);let rt=new RegExp(`\\b${n}\\b(?=\\.)`,"g");rt.test(y)&&(y=y.replace(rt,i),Y=!0);let Sr=new RegExp(`\\b${n}\\b(?![.\\w])`,"g");Sr.test(y)&&(y=y.replace(Sr,i),Y=!0),Y&&await f(h,y)}}catch(p){console.warn("Warning: Could not scan for HTTP client usages:",p)}},At=async e=>{let r=F.join(e,c.UTILS_INDEX);if(m(r)){let n=await u(r);n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http['"];?.*$/gm,""),await f(r,n)}let t=F.join(e,c.TYPES_INDEX);if(m(t)){let n=await u(t),i=F.join(e,c.COMMON_TYPES_DIR);if(!m(i))n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/common['"];?.*$/gm,"");else{let o=F.join(i,"index.ts");if(m(o)){let s=await u(o);s=s.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http\.types['"];?.*$/gm,""),await f(o,s)}}m(F.join(e,c.UTILITY_TYPES_DIR))||(n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/utility['"];?.*$/gm,"")),await f(t,n)}},Mi=async(e,r,t=[])=>{let n=F.join(e,"src"),o=`grep -r "from ['\\"].*${r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}.*['\\"]" "${n}" --include="*.ts" --include="*.tsx" || true`;try{let{stdout:s}=await Et(o);return s.trim()?s.trim().split(`
13
- `).filter(d=>{let[g]=d.split(":"),h=F.resolve(e,g);return!t.some(y=>!!(h===y||h.startsWith(y+F.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for ${r}:`,s),!0}},Gi=async(e,r,t=[])=>{let n=F.join(e,"src"),o=`grep -r "${r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}" "${n}" --include="*.ts" --include="*.tsx" || true`;try{let{stdout:s}=await Et(o);return s.trim()?s.trim().split(`
14
- `).filter(d=>{let[g]=d.split(":"),h=F.resolve(e,g);return!t.some(y=>!!(h===y||h.startsWith(y+F.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for string ${r}:`,s),!0}}});import{existsSync as ds}from"node:fs";import{access as us}from"node:fs/promises";import Qr from"node:path";var ie,at,en=Pe(()=>{"use strict";ie=async(e,r,t)=>{try{return await us(Qr.join(e,t,r)),!0}catch{return!1}},at=(e,r,t)=>ds(Qr.join(e,r,t))});import{access as _t,readFile as fs}from"node:fs/promises";import ct from"node:path";var I,tn=Pe(()=>{"use strict";I=async e=>{try{let r=ct.join(e,"package.json"),t=await fs(r,"utf-8"),n=JSON.parse(t),i={...n.dependencies,...n.devDependencies},o=!!(i["@reduxjs/toolkit"]&&i["react-redux"]),s=!!i["next-intl"],a=!!i.axios,p=!1,d=ct.join(e,"src","lib","utils","http","axios-client");try{await _t(d)}catch{a=!1}let g=ct.join(e,"src","lib","utils","http","fetch-client");try{await _t(g),p=!0}catch{p=!1}let h;a&&p?h="both":a?h="axios":p?h="fetch":h="none";let y=!!i.vitest;if(!y)try{await _t(ct.join(e,"vitest.config.ts")),y=!0}catch{}return{hasRedux:o,httpClient:h,hasI18n:s,hasTests:y}}catch(r){throw new Error(`Failed to detect project setup: ${r}`,{cause:r})}}});var Ne={};St(Ne,{detectProjectSetup:()=>I,directoryExists:()=>ie,fileExistsAt:()=>at});var L=Pe(()=>{"use strict";en();tn()});import{Command as Hc}from"commander";import Ot from"node:path";import oe from"picocolors";function wr(e){let{logger:r=s=>console.error(s),exitOnCancel:t=process.env.NODE_ENV!=="test"}=e??{},n=()=>{console.log(""),console.log(""),r("Setup cancelled by user"),console.log(""),t&&process.exit(0)},i=s=>{if(s!==null&&typeof s=="object"&&"code"in s&&s.code==="ERR_USE_AFTER_CLOSE"){n();return}if(s instanceof Error){r(`Uncaught exception: ${s.message}`);return}r(`Uncaught exception: ${String(s)}`)},o=s=>{if(s instanceof Error){r(`Unhandled promise rejection: ${s.message}`);return}r(`Unhandled promise rejection: ${String(s)}`)};return process.on("SIGINT",n),process.on("SIGTERM",n),process.on("uncaughtException",i),process.on("unhandledRejection",o),()=>{process.off("SIGINT",n),process.off("SIGTERM",n),process.off("uncaughtException",i),process.off("unhandledRejection",o)}}import K from"picocolors";var ui={reset:e=>e,red:K.red,green:K.green,yellow:K.yellow,blue:K.blue,cyan:K.cyan,magenta:K.magenta,white:K.white,gray:K.gray,bright:K.bold,dim:K.dim};function me(e,r="reset"){let t=ui[r]??(n=>n);console.log(t(e))}function nt(e){me(`\u2716 ${e}`,"red")}var v=nt;function l(e){me(e)}function Cr(){console.log(""),me("\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"),me("\u2551 \u2551","cyan"),me("\u2551 \u{1F680} Create Teispace Next.js App \u{1F680} \u2551","cyan"),me("\u2551 \u2551","cyan"),me("\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"),console.log("")}import fi from"ora";function R(e="",r){let t=fi({text:e,...r});return t.start(),t}var gi=e=>e.charAt(0).toUpperCase()+e.slice(1),A=e=>e.replace(/-([a-z])/g,(r,t)=>t.toUpperCase()),$=e=>gi(A(e));import hi from"ora";var x=hi();P();import{exec as xi}from"node:child_process";import{promisify as yi}from"node:util";var Z=yi(xi),Er=async(e,r,t)=>{try{if(await Z("git init",{cwd:e}),await Z("git add .",{cwd:e}),await Z('git commit -m "Initial commit from @teispace/next-maker"',{cwd:e}),r&&(await Z(`git remote add origin ${r}`,{cwd:e}),t)){await Z("git fetch origin",{cwd:e});let n="main";try{await Z("git show-branch origin/main",{cwd:e})}catch{try{await Z("git show-branch origin/master",{cwd:e}),n="master"}catch{n="main"}}await Z(`git merge origin/${n} --allow-unrelated-histories -X ours`,{cwd:e}),await Z(`git push origin HEAD:${n}`,{cwd:e})}}catch(n){console.warn("Failed to initialize git repository",n)}};import{exec as Pi}from"node:child_process";import{promisify as vi}from"node:util";var Re=vi(Pi),Rr=async(e,r)=>{let t=`${r} install`;try{await Re(t,{cwd:e})}catch(n){throw new Error(`Failed to install dependencies with ${r}: ${n}`,{cause:n})}},U=async(e,r,t)=>{let n=r==="npm"?`${r} run ${t}`:`${r} ${t}`;try{await Re(n,{cwd:e})}catch(i){console.warn(`Warning: Failed to run script '${t}': ${i}`)}},Si=()=>{let e=process.env.npm_config_user_agent;if(e){if(e.startsWith("yarn"))return"yarn";if(e.startsWith("pnpm"))return"pnpm";if(e.startsWith("bun"))return"bun"}return"npm"},O=async e=>{let{existsSync:r}=await import("node:fs"),t=await import("node:path");return r(t.join(e,"pnpm-lock.yaml"))?"pnpm":r(t.join(e,"yarn.lock"))?"yarn":r(t.join(e,"bun.lockb"))?"bun":r(t.join(e,"package-lock.json"))?"npm":Si()},wi=async(e,r,t)=>{if(t.length===0)return;let i=`${$r(r)} ${t.join(" ")}`;try{await Re(i,{cwd:e})}catch(o){throw new Error(`Failed to install packages with ${r}: ${o}`,{cause:o})}},$r=e=>{switch(e){case"npm":return"npm install";case"yarn":return"yarn add";case"pnpm":return"pnpm add";case"bun":return"bun add";default:return"npm install"}},z=async(e,r)=>{let t=await O(e);await wi(e,t,[r])},Ci=e=>{switch(e){case"npm":return"--save-dev";case"yarn":case"pnpm":case"bun":return"-D";default:return"--save-dev"}},ue=async(e,r,t)=>{if(t.length===0)return;let n=$r(r),i=Ci(r),o=`${n} ${i} ${t.join(" ")}`;try{await Re(o,{cwd:e})}catch(s){throw new Error(`Failed to install dev packages with ${r}: ${s}`,{cause:s})}},ot=async(e,r)=>{let t=await O(e);await ue(e,t,[r])},Ct=async(e,r,t)=>{if(t.length===0)return;let i=`${Ti(r)} ${t.join(" ")}`;try{await Re(i,{cwd:e})}catch(o){throw new Error(`Failed to uninstall packages with ${r}: ${o}`,{cause:o})}},Ti=e=>{switch(e){case"npm":return"npm uninstall";case"yarn":return"yarn remove";case"pnpm":return"pnpm remove";case"bun":return"bun remove";default:return"npm uninstall"}},Tt=async(e,r)=>{let t=await O(e);await Ct(e,t,[r])};import Ei from"enquirer";var{prompt:Ri}=Ei,br=async e=>{let r=await Ri([{type:"input",name:"projectName",message:"What is the project name?",initial:e||"my-app",skip:!!e,validate:t=>/^[a-z0-9-_]+$/.test(t)?!0:"Project name must be lowercase and contain only alphanumeric characters, hyphens, and underscores."},{type:"input",name:"description",message:"Project description:",initial:"A Next.js application"},{type:"input",name:"author",message:"Author:",initial:"Teispace"},{type:"input",name:"version",message:"Version:",initial:"0.1.0",validate:t=>/^\d+\.\d+\.\d+$/.test(t)?!0:"Version must be a valid semantic version (x.y.z)."},{type:"input",name:"email",message:"Support email:",initial:"support@example.com",validate:t=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)?!0:"Please enter a valid email address."},{type:"select",name:"packageManager",message:"Which package manager would you like to use?",choices:["npm","yarn","pnpm","bun"],initial:1},{type:"input",name:"gitRemote",message:"GitHub repository URL (optional):",initial:""},{type:"confirm",name:"pushToRemote",message:"Would you like to push the changes to the remote repository?",initial:!0,skip:function(){return!this.state?.answers?.gitRemote}},{type:"input",name:"gitIssues",message:"GitHub issues URL (optional):",initial:"",skip:function(){return!this.state?.answers?.gitRemote},validate:t=>t?/^https:\/\/github\.com\/[\w-]+\/[\w.-]+\/issues$/.test(t)?!0:"Please enter a valid GitHub issues URL (e.g., https://github.com/user/repo/issues)":!0},{type:"input",name:"gitHomepage",message:"GitHub homepage URL (optional):",initial:"",skip:function(){return!this.state?.answers?.gitRemote},validate:t=>t?/^https:\/\/github\.com\/[\w-]+\/[\w.-]+#readme$/.test(t)?!0:"Please enter a valid GitHub homepage URL (e.g., https://github.com/user/repo#readme)":!0},{type:"confirm",name:"keepTemplates",message:"Do you want to keep GitHub issue and pull request templates?",initial:!1},{type:"select",name:"httpClient",message:"Which HTTP client do you want to use?",choices:["axios","fetch","both","none"],initial:1},{type:"confirm",name:"reactSecureStorage",message:"Do you want to include react-secure-storage?",initial:!0,skip:function(){let t=this.state?.answers??this.enquirer?.answers??{};return!!(t.httpClient&&t.httpClient!=="none")}},{type:"confirm",name:"darkMode",message:"Do you want to include Dark Mode (Tailwind + @teispace/next-themes)?",initial:!0},{type:"confirm",name:"redux",message:"Do you want to include Redux Toolkit?",initial:!0},{type:"confirm",name:"i18n",message:"Do you want to include Internationalization (next-intl)?",initial:!0},{type:"confirm",name:"tests",message:"Do you want to include testing setup (Vitest + React Testing Library)?",initial:!0},{type:"confirm",name:"reactCompiler",message:"Do you want to enable the React Compiler?",initial:!0},{type:"confirm",name:"bundleAnalyzer",message:"Do you want to include @next/bundle-analyzer?",initial:!1},{type:"multiselect",name:"communityFiles",message:"Select community files to include:",choices:[{name:"CODE_OF_CONDUCT.md",value:"CODE_OF_CONDUCT.md"},{name:"CONTRIBUTING.md",value:"CONTRIBUTING.md"},{name:"SECURITY.md",value:"SECURITY.md"}],initial:[]},{type:"confirm",name:"readme",message:"Do you want to create a README.md?",initial:!0},{type:"confirm",name:"docker",message:"Do you want to include Docker configuration?",initial:!1},{type:"input",name:"containerName",message:"Docker Container Name:",initial:"next-app",skip:function(){return!(this.state?.answers??this.enquirer?.answers??{}).docker},validate:t=>/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(t)?!0:"Invalid Docker container name."},{type:"input",name:"imageName",message:"Docker Image Name:",initial:"nextjs-starter",skip:function(){return!(this.state?.answers??this.enquirer?.answers??{}).docker},validate:t=>/^[a-z0-9]+(?:[._-][a-z0-9]+)*$/.test(t)?!0:"Invalid Docker image name (must be lowercase)."},{type:"input",name:"imageTag",message:"Docker Image Tag:",initial:"latest",skip:function(){return!(this.state?.answers??this.enquirer?.answers??{}).docker},validate:t=>/^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,127}$/.test(t)?!0:"Invalid Docker image tag."},{type:"confirm",name:"ci",message:"Do you want to include GitHub Actions (CI/CD)?",initial:!1},{type:"confirm",name:"preCommitHooks",message:"Do you want to setup pre-commit hooks (Husky, Commitlint, Lint-staged)?",initial:!0},{type:"confirm",name:"commitizen",message:"Do you want to setup Commitizen?",initial:!0},{type:"confirm",name:"copyEnv",message:"Want to copy .env.example to .env?",initial:!0}]);if(r.company=r.author,r.gitRemote&&!r.gitHomepage){let t=r.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"");r.gitHomepage=`${t}#readme`,r.gitIssues=`${t}/issues`}return r};P();import $i from"node:path";var re=async(e,r)=>{let t=bi(r);await f($i.join(e,"test/test-utils.tsx"),t)},bi=({redux:e,i18n:r})=>e&&r?Ni:e?Ii:r?Ai:ki,Ni=`import { type RenderOptions, render } from '@testing-library/react';
11
+ `,await f(t,n))}},It=async(e,r,t)=>{if(r===t)return;let n=r==="fetch"?"fetchClient":"axiosClient",o=t==="fetch"?"fetchClient":"axiosClient",i=r==="fetch"?"fetch-client":"axios-client",s=t==="fetch"?"fetch-client":"axios-client",a=F.join(e,"src");try{let p=`grep -rl "${n}" "${a}" --include="*.ts" --include="*.tsx" || true`,{stdout:d}=await Et(p);if(!d.trim())return;let g=d.trim().split(`
12
+ `).filter(h=>h);for(let h of g){if(!m(h))continue;let x=await u(h),K=!1,vt=new RegExp(`(import\\s*\\{[^}]*?)\\b${n}\\b([^}]*?\\}\\s*from\\s*['"][^'"]*?/http['"])`,"g");vt.test(x)&&(x=x.replace(vt,`$1${o}$2`),K=!0);let tt=new RegExp(`import\\s+${n}\\s+from\\s+['"]([^'"]*?)/${i}['"]`,"g");tt.test(x)&&(x=x.replace(tt,`import ${o} from '$1/${s}'`),K=!0);let rt=new RegExp(`\\b${n}\\b(?=\\.)`,"g");rt.test(x)&&(x=x.replace(rt,o),K=!0);let wr=new RegExp(`\\b${n}\\b(?![.\\w])`,"g");wr.test(x)&&(x=x.replace(wr,o),K=!0),K&&await f(h,x)}}catch(p){console.warn("Warning: Could not scan for HTTP client usages:",p)}},At=async e=>{let r=F.join(e,c.UTILS_INDEX);if(m(r)){let n=await u(r);n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http['"];?.*$/gm,""),await f(r,n)}let t=F.join(e,c.TYPES_INDEX);if(m(t)){let n=await u(t),o=F.join(e,c.COMMON_TYPES_DIR);if(!m(o))n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/common['"];?.*$/gm,"");else{let i=F.join(o,"index.ts");if(m(i)){let s=await u(i);s=s.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http\.types['"];?.*$/gm,""),await f(i,s)}}m(F.join(e,c.UTILITY_TYPES_DIR))||(n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/utility['"];?.*$/gm,"")),await f(t,n)}},Ji=async(e,r,t=[])=>{let n=F.join(e,"src"),i=`grep -r "from ['\\"].*${r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}.*['\\"]" "${n}" --include="*.ts" --include="*.tsx" || true`;try{let{stdout:s}=await Et(i);return s.trim()?s.trim().split(`
13
+ `).filter(d=>{let[g]=d.split(":"),h=F.resolve(e,g);return!t.some(x=>!!(h===x||h.startsWith(x+F.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for ${r}:`,s),!0}},Bi=async(e,r,t=[])=>{let n=F.join(e,"src"),i=`grep -r "${r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}" "${n}" --include="*.ts" --include="*.tsx" || true`;try{let{stdout:s}=await Et(i);return s.trim()?s.trim().split(`
14
+ `).filter(d=>{let[g]=d.split(":"),h=F.resolve(e,g);return!t.some(x=>!!(h===x||h.startsWith(x+F.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for string ${r}:`,s),!0}}});import{existsSync as vs}from"node:fs";import{access as Ss}from"node:fs/promises";import tn from"node:path";var ie,at,rn=Pe(()=>{"use strict";ie=async(e,r,t)=>{try{return await Ss(tn.join(e,t,r)),!0}catch{return!1}},at=(e,r,t)=>vs(tn.join(e,r,t))});import{access as Ft,readFile as ws}from"node:fs/promises";import ct from"node:path";var I,nn=Pe(()=>{"use strict";I=async e=>{try{let r=ct.join(e,"package.json"),t=await ws(r,"utf-8"),n=JSON.parse(t),o={...n.dependencies,...n.devDependencies},i=!!(o["@reduxjs/toolkit"]&&o["react-redux"]),s=!!o["next-intl"],a=!!o.axios,p=!1,d=ct.join(e,"src","lib","utils","http","axios-client");try{await Ft(d)}catch{a=!1}let g=ct.join(e,"src","lib","utils","http","fetch-client");try{await Ft(g),p=!0}catch{p=!1}let h;a&&p?h="both":a?h="axios":p?h="fetch":h="none";let x=!!o.vitest;if(!x)try{await Ft(ct.join(e,"vitest.config.ts")),x=!0}catch{}return{hasRedux:i,httpClient:h,hasI18n:s,hasTests:x}}catch(r){throw new Error(`Failed to detect project setup: ${r}`,{cause:r})}}});var Ne={};St(Ne,{detectProjectSetup:()=>I,directoryExists:()=>ie,fileExistsAt:()=>at});var L=Pe(()=>{"use strict";rn();nn()});import{Command as Kc}from"commander";import Ot from"node:path";import V from"picocolors";function Cr(e){let{logger:r=s=>console.error(s),exitOnCancel:t=process.env.NODE_ENV!=="test"}=e??{},n=()=>{console.log(""),console.log(""),r("Setup cancelled by user"),console.log(""),t&&process.exit(0)},o=s=>{if(s!==null&&typeof s=="object"&&"code"in s&&s.code==="ERR_USE_AFTER_CLOSE"){n();return}if(s instanceof Error){r(`Uncaught exception: ${s.message}`);return}r(`Uncaught exception: ${String(s)}`)},i=s=>{if(s instanceof Error){r(`Unhandled promise rejection: ${s.message}`);return}r(`Unhandled promise rejection: ${String(s)}`)};return process.on("SIGINT",n),process.on("SIGTERM",n),process.on("uncaughtException",o),process.on("unhandledRejection",i),()=>{process.off("SIGINT",n),process.off("SIGTERM",n),process.off("uncaughtException",o),process.off("unhandledRejection",i)}}import q from"picocolors";var gi={reset:e=>e,red:q.red,green:q.green,yellow:q.yellow,blue:q.blue,cyan:q.cyan,magenta:q.magenta,white:q.white,gray:q.gray,bright:q.bold,dim:q.dim};function me(e,r="reset"){let t=gi[r]??(n=>n);console.log(t(e))}function nt(e){me(`\u2716 ${e}`,"red")}var v=nt;function l(e){me(e)}function Tr(){console.log(""),me("\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"),me("\u2551 \u2551","cyan"),me("\u2551 \u{1F680} Create Teispace Next.js App \u{1F680} \u2551","cyan"),me("\u2551 \u2551","cyan"),me("\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"),console.log("")}import hi from"ora";function R(e="",r){let t=hi({text:e,...r});return t.start(),t}var yi=e=>e.charAt(0).toUpperCase()+e.slice(1),A=e=>e.replace(/-([a-z])/g,(r,t)=>t.toUpperCase()),$=e=>yi(A(e));import xi from"ora";var y=xi();P();import{exec as Pi}from"node:child_process";import{promisify as vi}from"node:util";var Q=vi(Pi),Rr=async(e,r,t)=>{try{if(await Q("git init",{cwd:e}),await Q("git add .",{cwd:e}),await Q('git commit -m "Initial commit from @teispace/next-maker"',{cwd:e}),r&&(await Q(`git remote add origin ${r}`,{cwd:e}),t)){await Q("git fetch origin",{cwd:e});let n="main";try{await Q("git show-branch origin/main",{cwd:e})}catch{try{await Q("git show-branch origin/master",{cwd:e}),n="master"}catch{n="main"}}await Q(`git merge origin/${n} --allow-unrelated-histories -X ours`,{cwd:e}),await Q(`git push origin HEAD:${n}`,{cwd:e})}}catch(n){console.warn("Failed to initialize git repository",n)}};import{exec as Si}from"node:child_process";import{promisify as wi}from"node:util";var Re=wi(Si),$r=async(e,r)=>{let t=`${r} install`;try{await Re(t,{cwd:e})}catch(n){throw new Error(`Failed to install dependencies with ${r}: ${n}`,{cause:n})}},U=async(e,r,t)=>{let n=r==="npm"?`${r} run ${t}`:`${r} ${t}`;try{await Re(n,{cwd:e})}catch(o){console.warn(`Warning: Failed to run script '${t}': ${o}`)}},Ci=()=>{let e=process.env.npm_config_user_agent;if(e){if(e.startsWith("yarn"))return"yarn";if(e.startsWith("pnpm"))return"pnpm";if(e.startsWith("bun"))return"bun"}return"npm"},O=async e=>{let{existsSync:r}=await import("node:fs"),t=await import("node:path");return r(t.join(e,"pnpm-lock.yaml"))?"pnpm":r(t.join(e,"yarn.lock"))?"yarn":r(t.join(e,"bun.lockb"))?"bun":r(t.join(e,"package-lock.json"))?"npm":Ci()},Ti=async(e,r,t)=>{if(t.length===0)return;let o=`${br(r)} ${t.join(" ")}`;try{await Re(o,{cwd:e})}catch(i){throw new Error(`Failed to install packages with ${r}: ${i}`,{cause:i})}},br=e=>{switch(e){case"npm":return"npm install";case"yarn":return"yarn add";case"pnpm":return"pnpm add";case"bun":return"bun add";default:return"npm install"}},z=async(e,r)=>{let t=await O(e);await Ti(e,t,[r])},Ei=e=>{switch(e){case"npm":return"--save-dev";case"yarn":case"pnpm":case"bun":return"-D";default:return"--save-dev"}},ue=async(e,r,t)=>{if(t.length===0)return;let n=br(r),o=Ei(r),i=`${n} ${o} ${t.join(" ")}`;try{await Re(i,{cwd:e})}catch(s){throw new Error(`Failed to install dev packages with ${r}: ${s}`,{cause:s})}},ot=async(e,r)=>{let t=await O(e);await ue(e,t,[r])},Ct=async(e,r,t)=>{if(t.length===0)return;let o=`${Ri(r)} ${t.join(" ")}`;try{await Re(o,{cwd:e})}catch(i){throw new Error(`Failed to uninstall packages with ${r}: ${i}`,{cause:i})}},Ri=e=>{switch(e){case"npm":return"npm uninstall";case"yarn":return"yarn remove";case"pnpm":return"pnpm remove";case"bun":return"bun remove";default:return"npm uninstall"}},Tt=async(e,r)=>{let t=await O(e);await Ct(e,t,[r])};import $i from"enquirer";var bi=/^[a-z0-9-_]+$/,Ni=/^\d+\.\d+\.\d+$/,Ii=e=>bi.test(e),Ai=e=>Ni.test(e),Nr=(e,r={})=>{let t=r.projectName??e??"my-app";if(!Ii(t))throw new Error(`Invalid project name "${t}". Use lowercase letters, digits, hyphens, and underscores only.`);let n=r.version??"0.1.0";if(!Ai(n))throw new Error(`Invalid version "${n}". Expected semver (e.g. 0.1.0).`);let o=r.author??"Teispace",i=r.company??o;return{projectName:t,description:r.description??"A Next.js application",author:o,version:n,packageManager:r.packageManager??"yarn",gitRemote:r.gitRemote??"",pushToRemote:r.pushToRemote??!1,gitIssues:r.gitIssues??"",gitHomepage:r.gitHomepage??"",httpClient:r.httpClient??"fetch",reactSecureStorage:r.reactSecureStorage??!0,email:r.email??"support@example.com",company:i,keepTemplates:r.keepTemplates??!1,darkMode:r.darkMode??!0,redux:r.redux??!0,i18n:r.i18n??!0,communityFiles:r.communityFiles??[],readme:r.readme??!0,docker:r.docker??!1,containerName:r.containerName,imageName:r.imageName,imageTag:r.imageTag,ci:r.ci??!1,preCommitHooks:r.preCommitHooks??!0,commitizen:r.commitizen??!0,copyEnv:r.copyEnv??!0,tests:r.tests??!0,reactCompiler:r.reactCompiler??!0,bundleAnalyzer:r.bundleAnalyzer??!1}},{prompt:ki}=$i,Ir=async e=>{let r=await ki([{type:"input",name:"projectName",message:"What is the project name?",initial:e||"my-app",skip:!!e,validate:t=>/^[a-z0-9-_]+$/.test(t)?!0:"Project name must be lowercase and contain only alphanumeric characters, hyphens, and underscores."},{type:"input",name:"description",message:"Project description:",initial:"A Next.js application"},{type:"input",name:"author",message:"Author:",initial:"Teispace"},{type:"input",name:"version",message:"Version:",initial:"0.1.0",validate:t=>/^\d+\.\d+\.\d+$/.test(t)?!0:"Version must be a valid semantic version (x.y.z)."},{type:"input",name:"email",message:"Support email:",initial:"support@example.com",validate:t=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)?!0:"Please enter a valid email address."},{type:"select",name:"packageManager",message:"Which package manager would you like to use?",choices:["npm","yarn","pnpm","bun"],initial:1},{type:"input",name:"gitRemote",message:"GitHub repository URL (optional):",initial:""},{type:"confirm",name:"pushToRemote",message:"Would you like to push the changes to the remote repository?",initial:!0,skip:function(){return!this.state?.answers?.gitRemote}},{type:"input",name:"gitIssues",message:"GitHub issues URL (optional):",initial:"",skip:function(){return!this.state?.answers?.gitRemote},validate:t=>t?/^https:\/\/github\.com\/[\w-]+\/[\w.-]+\/issues$/.test(t)?!0:"Please enter a valid GitHub issues URL (e.g., https://github.com/user/repo/issues)":!0},{type:"input",name:"gitHomepage",message:"GitHub homepage URL (optional):",initial:"",skip:function(){return!this.state?.answers?.gitRemote},validate:t=>t?/^https:\/\/github\.com\/[\w-]+\/[\w.-]+#readme$/.test(t)?!0:"Please enter a valid GitHub homepage URL (e.g., https://github.com/user/repo#readme)":!0},{type:"confirm",name:"keepTemplates",message:"Do you want to keep GitHub issue and pull request templates?",initial:!1},{type:"select",name:"httpClient",message:"Which HTTP client do you want to use?",choices:["axios","fetch","both","none"],initial:1},{type:"confirm",name:"reactSecureStorage",message:"Do you want to include react-secure-storage?",initial:!0,skip:function(){let t=this.state?.answers??this.enquirer?.answers??{};return!!(t.httpClient&&t.httpClient!=="none")}},{type:"confirm",name:"darkMode",message:"Do you want to include Dark Mode (Tailwind + @teispace/next-themes)?",initial:!0},{type:"confirm",name:"redux",message:"Do you want to include Redux Toolkit?",initial:!0},{type:"confirm",name:"i18n",message:"Do you want to include Internationalization (next-intl)?",initial:!0},{type:"confirm",name:"tests",message:"Do you want to include testing setup (Vitest + React Testing Library)?",initial:!0},{type:"confirm",name:"reactCompiler",message:"Do you want to enable the React Compiler?",initial:!0},{type:"confirm",name:"bundleAnalyzer",message:"Do you want to include @next/bundle-analyzer?",initial:!1},{type:"multiselect",name:"communityFiles",message:"Select community files to include:",choices:[{name:"CODE_OF_CONDUCT.md",value:"CODE_OF_CONDUCT.md"},{name:"CONTRIBUTING.md",value:"CONTRIBUTING.md"},{name:"SECURITY.md",value:"SECURITY.md"}],initial:[]},{type:"confirm",name:"readme",message:"Do you want to create a README.md?",initial:!0},{type:"confirm",name:"docker",message:"Do you want to include Docker configuration?",initial:!1},{type:"input",name:"containerName",message:"Docker Container Name:",initial:"next-app",skip:function(){return!(this.state?.answers??this.enquirer?.answers??{}).docker},validate:t=>/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(t)?!0:"Invalid Docker container name."},{type:"input",name:"imageName",message:"Docker Image Name:",initial:"nextjs-starter",skip:function(){return!(this.state?.answers??this.enquirer?.answers??{}).docker},validate:t=>/^[a-z0-9]+(?:[._-][a-z0-9]+)*$/.test(t)?!0:"Invalid Docker image name (must be lowercase)."},{type:"input",name:"imageTag",message:"Docker Image Tag:",initial:"latest",skip:function(){return!(this.state?.answers??this.enquirer?.answers??{}).docker},validate:t=>/^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,127}$/.test(t)?!0:"Invalid Docker image tag."},{type:"confirm",name:"ci",message:"Do you want to include GitHub Actions (CI/CD)?",initial:!1},{type:"confirm",name:"preCommitHooks",message:"Do you want to setup pre-commit hooks (Husky, Commitlint, Lint-staged)?",initial:!0},{type:"confirm",name:"commitizen",message:"Do you want to setup Commitizen?",initial:!0},{type:"confirm",name:"copyEnv",message:"Want to copy .env.example to .env?",initial:!0}]);if(r.company=r.author,r.gitRemote&&!r.gitHomepage){let t=r.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"");r.gitHomepage=`${t}#readme`,r.gitIssues=`${t}/issues`}return r};P();import Oi from"node:path";var ne=async(e,r)=>{let t=_i(r);await f(Oi.join(e,"test/test-utils.tsx"),t)},_i=({redux:e,i18n:r})=>e&&r?Fi:e?ji:r?Di:Li,Fi=`import { type RenderOptions, render } from '@testing-library/react';
15
15
  import { NextIntlClientProvider } from 'next-intl';
16
16
  import type { ReactElement, ReactNode } from 'react';
17
17
  import { Provider } from 'react-redux';
@@ -72,7 +72,7 @@ export function renderWithProviders(
72
72
 
73
73
  export * from '@testing-library/react';
74
74
  export { default as userEvent } from '@testing-library/user-event';
75
- `,Ii=`import { type RenderOptions, render } from '@testing-library/react';
75
+ `,ji=`import { type RenderOptions, render } from '@testing-library/react';
76
76
  import type { ReactElement, ReactNode } from 'react';
77
77
  import { Provider } from 'react-redux';
78
78
  import { type AppState, type AppStore, makeStore } from '@/store';
@@ -111,7 +111,7 @@ export function renderWithProviders(
111
111
 
112
112
  export * from '@testing-library/react';
113
113
  export { default as userEvent } from '@testing-library/user-event';
114
- `,Ai=`import { type RenderOptions, render } from '@testing-library/react';
114
+ `,Di=`import { type RenderOptions, render } from '@testing-library/react';
115
115
  import { NextIntlClientProvider } from 'next-intl';
116
116
  import type { ReactElement, ReactNode } from 'react';
117
117
  import type { SupportedLocale } from '@/types/i18n';
@@ -151,7 +151,7 @@ export function renderWithProviders(
151
151
 
152
152
  export * from '@testing-library/react';
153
153
  export { default as userEvent } from '@testing-library/user-event';
154
- `,ki=`import { type RenderOptions, render } from '@testing-library/react';
154
+ `,Li=`import { type RenderOptions, render } from '@testing-library/react';
155
155
  import type { ReactElement, ReactNode } from 'react';
156
156
 
157
157
  type TestProvidersProps = {
@@ -173,9 +173,9 @@ export function renderWithProviders(ui: ReactElement, options: ExtendedRenderOpt
173
173
 
174
174
  export * from '@testing-library/react';
175
175
  export { default as userEvent } from '@testing-library/user-event';
176
- `;import Ir from"node:path";var C={REDUX_TOOLKIT:"@reduxjs/toolkit",REACT_REDUX:"react-redux",REDUX:"redux",REDUX_PERSIST:"redux-persist",REACT_SECURE_STORAGE:"react-secure-storage",NEXT_INTL:"next-intl",NEXT_THEMES:"@teispace/next-themes",AXIOS:"axios",HUSKY:"husky",COMMITLINT_CLI:"@commitlint/cli",COMMITLINT_CONFIG:"@commitlint/config-conventional",LINT_STAGED:"lint-staged",COMMITIZEN:"commitizen",CZ_CONVENTIONAL_CHANGELOG:"cz-conventional-changelog",VITEST:"vitest",JSDOM:"jsdom",VITE_PLUGIN_REACT:"@vitejs/plugin-react",TESTING_LIBRARY_DOM:"@testing-library/dom",TESTING_LIBRARY_JEST_DOM:"@testing-library/jest-dom",TESTING_LIBRARY_REACT:"@testing-library/react",TESTING_LIBRARY_USER_EVENT:"@testing-library/user-event",REACT_COMPILER_BABEL:"babel-plugin-react-compiler",NEXT_BUNDLE_ANALYZER:"@next/bundle-analyzer"};w();P();var Ar=async(e,r)=>{if(r.bundleAnalyzer)return;let t=Ir.join(e,c.NEXT_CONFIG);if(m(t)){let n=await u(t);n=n.replace(/import\s+withBundleAnalyzer\s+from\s+'@next\/bundle-analyzer';\n/,""),n=n.replace(/const\s+bundleAnalyzer\s*=\s*withBundleAnalyzer\(\{[\s\S]*?\}\);\n+/,""),n=n.replace(/bundleAnalyzer\(([^)]*)\)/,"$1"),await f(t,n)}await k(Ir.join(e,c.PACKAGE_JSON),n=>(n.devDependencies&&delete n.devDependencies[C.NEXT_BUNDLE_ANALYZER],n.scripts&&delete n.scripts.analyze,n))};w();P();import $e from"node:path";var kr=async(e,r)=>{r.darkMode||(await T($e.join(e,c.THEME_PROVIDER)),await Oi(e),await _i(e),await ji(e))},Oi=async e=>{let r=$e.join(e,c.PROVIDERS_INDEX),t=await u(r);t=t.replace(/export \* from '\.\/CustomThemeProvider';\n/,""),await f(r,t)},_i=async e=>{let r=$e.join(e,c.GLOBALS_CSS);if(m(r)){let t=await u(r);t=t.replace(/@custom-variant dark \(.*?\);\n\n/,""),t=t.replace(/@theme \{[\s\S]*?\}\n/,""),await f(r,t)}},Fi=e=>e.replace(/\bbg-light\b\s?/g,"").replace(/\bdark:bg-dark\b\s?/g,"").replace(/\s{2,}/g," ").replace(/suppressHydrationWarning=\{true\}/g,""),ji=async e=>{let r=[$e.join(e,c.ROOT_LAYOUT),$e.join(e,"src/app/[locale]/layout.tsx")];for(let t of r)if(m(t)){let n=await u(t),i=Fi(n);i!==n&&await f(t,i)}};w();P();it();import b from"node:path";var _r=async(e,r)=>{let t=b.join(e,c.HTTP_UTILS),n=r.httpClient!=="none"||!!r.reactSecureStorage;r.httpClient==="none"?await Hi(e,t,n):r.httpClient==="axios"?await Ui(e,t):r.httpClient==="fetch"&&await zi(e,t)},Hi=async(e,r,t)=>{await S(b.join(e,c.AXIOS_CLIENT)),await S(b.join(e,c.FETCH_CLIENT)),t?(await f(b.join(r,"index.ts"),`export * from './token-store';
177
- `),await T(b.join(e,c.CLIENT_UTILS)),await ve(e,[])):(await S(r),await Vi(e),await T(b.join(e,c.APP_APIS)),await Ji(e)),await Bi(e),await S(b.join(e,c.ERRORS_DIR)),t||(await S(b.join(e,c.COMMON_TYPES_DIR)),await S(b.join(e,c.UTILITY_TYPES_DIR)),await Xi(e))},Ui=async(e,r)=>{await S(b.join(e,c.FETCH_CLIENT));let t=await u(b.join(r,"index.ts"));t=t.replace(/export .* from '\.\/fetch-client';\n/g,""),await f(b.join(r,"index.ts"),t);let n=b.join(e,c.HTTP_TYPES);if(m(n)){let i=await u(n);i=i.replace(/export interface FetchClientOptions \{[\s\S]*?\}\n\n/,""),i=i.replace(/export interface ExtendedRequestInit extends RequestInit \{[\s\S]*?\}\n\n/,""),await f(n,i)}},zi=async(e,r)=>{await S(b.join(e,c.AXIOS_CLIENT));let t=await u(b.join(r,"index.ts"));t=t.replace(/export .* from '\.\/axios-client';\n/g,""),await f(b.join(r,"index.ts"),t),await ve(e,["fetch"]);let n=b.join(e,c.HTTP_TYPES);if(m(n)){let i=await u(n);i=i.replace(/export interface AxiosClientOptions \{[\s\S]*?\}\n\n/,""),await f(n,i)}},Vi=async e=>{let r=b.join(e,c.UTILS_INDEX);if(m(r)){let t=await u(r);t=t.replace(/export \* from '\.\/http';\n/,""),await f(r,t)}},Ji=async e=>{let r=b.join(e,c.CONFIG_INDEX);if(m(r)){let t=await u(r);t=t.replace(/export \* from '\.\/app-apis';\n/,""),await f(r,t)}},Bi=async e=>{let r=b.join(e,c.CONSTANTS);if(m(r)){let t=await u(r);t=t.replace(/export const API_RESPONSE_DATA_KEY = 'data';\n/,""),t=t.replace(/export const SAVE_AUTH_TOKENS = false;\n/,""),await f(r,t)}},Xi=async e=>{let r=b.join(e,c.TYPES_INDEX);if(m(r)){let t=await u(r);t=t.replace(/export \* from '\.\/utility';\n/,""),t=t.replace(/export \* from '\.\/common';\n/,""),await f(r,t)}};w();P();import H from"node:path";var Fr=async(e,r)=>{r.i18n||(await Ki(e),await qi(e),await Wi(e),await Zi(e),await Yi(e))},Yi=async e=>{let r=H.join(e,c.ENV_EXAMPLE);if(!m(r))return;let t=await u(r);t=t.replace(/#[^\n]*IANA time zone[\s\S]*?DEFAULT_TIMEZONE=[^\n]*\n?/,""),t=t.replace(/#[^\n]*Fallback locale[\s\S]*?DEFAULT_LOCALE=[^\n]*\n?/,""),t=t.replace(/^DEFAULT_TIMEZONE=.*\n?/m,""),t=t.replace(/^DEFAULT_LOCALE=.*\n?/m,""),await f(r,t)},Ki=async e=>{await S(H.join(e,c.I18N_DIR)),await S(H.join(e,c.LOCALE_DIR)),await T(H.join(e,c.PROXY)),await T(H.join(e,c.MIDDLEWARE)),await T(H.join(e,c.I18N_TYPES)),await T(H.join(e,c.APP_LOCALES))},qi=async e=>{let r=H.join(e,c.TYPES_INDEX);if(m(r)){let n=await u(r);n=n.replace(/export \* from '\.\/i18n';\n/,""),await f(r,n)}let t=H.join(e,c.CONFIG_INDEX);if(m(t)){let n=await u(t);n=n.replace(/export \* from '\.\/app-locales';\n/,""),await f(t,n)}},Wi=async e=>{let r=H.join(e,c.NEXT_CONFIG);if(m(r)){let t=await u(r);t=t.replace(/import createNextIntlPlugin from 'next-intl\/plugin';\n/,""),t=t.replace(/const withNextIntl = createNextIntlPlugin\(\);\n+/,""),t=t.replace(/withNextIntl\(([^)]+)\)/,"$1"),await f(r,t)}},Zi=async e=>{let r=H.join(e,c.COUNTER_COMPONENT);if(m(r)){let i=await u(r);i=i.replace(/import\s+\{\s*useTranslations\s*\}\s+from\s+['"]next-intl['"];\n/,""),i=i.replace(/\s*const\s+t\s*=\s*useTranslations\(['"]Count['"]\);\n/,""),i=i.replace(/\{t\('currentCount',\s*\{\s*count:\s*value\s*\}\)\}/g,"Current Count: {value}"),i=i.replace(/\{t\(['"]increment['"]\)\}/g,"Increment"),i=i.replace(/\{t\(['"]decrement['"]\)\}/g,"Decrement"),i=i.replace(/\{t\(['"]reset['"]\)\}/g,"Reset"),await f(r,i)}let t=H.join(e,"src/features/counter/components/Counter.test.tsx"),n=H.join(e,"test/test-utils.tsx");await T(t),await T(n)};w();P();import ne from"node:path";var jr=async(e,r)=>{r.httpClient!=="none"||r.reactSecureStorage||await S(ne.join(e,c.STORAGE_SERVICE))},Dr=async e=>{await T(ne.join(e,c.LICENSE))},Lr=async e=>{await T(ne.join(e,c.CHANGELOG))},Mr=async e=>{await T(ne.join(e,c.NVM_RC)),await T(ne.join(e,c.NPM_RC))},Gr=async e=>{await S(ne.join(e,c.CLAUDE_DIR)),await S(ne.join(e,c.DOCS_DIR)),await S(ne.join(e,c.VSCODE_DIR))};import Hr from"node:path";w();P();var Ur=async(e,r)=>{if(r.reactCompiler)return;let t=Hr.join(e,c.NEXT_CONFIG);if(m(t)){let n=await u(t);n=n.replace(/^\s*reactCompiler:\s*true,?\n/m,""),await f(t,n)}await k(Hr.join(e,c.PACKAGE_JSON),n=>(n.devDependencies&&delete n.devDependencies[C.REACT_COMPILER_BABEL],n))};w();P();import fe from"node:path";var zr=async(e,r)=>{r.redux||(await S(fe.join(e,c.STORE)),await S(fe.join(e,c.COUNTER_FEATURE)),await T(fe.join(e,c.STORE_PROVIDER)),await T(fe.join(e,"test/test-utils.tsx")),await Qi(e),await es(e))},Qi=async e=>{let r=fe.join(e,c.PROVIDERS_INDEX),t=await u(r);t=t.replace(/export \* from '\.\/StoreProvider';\n/,""),await f(r,t)},es=async e=>{let r=[fe.join(e,c.ROOT_PAGE),fe.join(e,c.LOCALE_PAGE)];for(let t of r)if(m(t)){let n=await u(t);n=n.replace(/import\s+\{\s*Counter\s*\}\s+from\s+['"]@\/features\/counter['"];\n?/,""),n=n.replace(/<Counter\s*\/>\n?/g,""),await f(t,n)}};import st from"node:path";w();P();var ts=[C.VITEST,C.JSDOM,C.VITE_PLUGIN_REACT,C.TESTING_LIBRARY_DOM,C.TESTING_LIBRARY_JEST_DOM,C.TESTING_LIBRARY_REACT,C.TESTING_LIBRARY_USER_EVENT],Vr=async(e,r)=>{r.tests||(await T(st.join(e,c.VITEST_CONFIG)),await S(st.join(e,c.TEST_DIR)),await T(st.join(e,"src/features/counter/components/Counter.test.tsx")),await k(st.join(e,c.PACKAGE_JSON),t=>{if(t.devDependencies)for(let n of ts)delete t.devDependencies[n];return t.scripts&&(delete t.scripts.test,delete t.scripts["test:watch"],delete t.scripts["test:coverage"],typeof t.scripts.validate=="string"&&(t.scripts.validate=t.scripts.validate.replace(/\s*&&\s*yarn\s+test(?![:\w])/,"").replace(/\byarn\s+test(?![:\w])\s*&&\s*/,""))),t}))};var Jr=async(e,r)=>{let t=R("Customizing features...");try{await _r(e,r),await jr(e,r),await zr(e,r),await kr(e,r),await Ar(e,r),await Fr(e,r),await Ur(e,r),await Vr(e,r),await Dr(e),await Lr(e),await Mr(e),await Gr(e),r.tests&&await re(e,{redux:r.redux,i18n:r.i18n}),t.succeed("Features customized.")}catch(n){throw t.fail("Failed to customize features."),n}};import rs from"node:path";w();P();var Br=async(e,r)=>{let t=R("Configuring package.json...");try{let n=r.gitRemote,i=r.gitHomepage,o=r.gitIssues;r.gitRemote&&(r.gitRemote.startsWith("git@github.com:")&&(n=r.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"")),i||(i=`${n.replace(/\.git$/,"")}#readme`),o||(o=`${n.replace(/\.git$/,"")}/issues`),n.endsWith(".git")||(n=`${n}.git`)),await k(rs.join(e,c.PACKAGE_JSON),s=>(s.name=r.projectName,s.version=r.version,s.description=r.description,s.author=r.author,delete s.packageManager,r.gitRemote?(i&&(s.homepage=i),o&&(s.bugs={url:o}),n&&(s.repository={type:"git",url:n})):(delete s.homepage,delete s.bugs,delete s.repository),r.redux||(delete s.dependencies[C.REDUX_TOOLKIT],delete s.dependencies[C.REACT_REDUX],delete s.dependencies[C.REDUX],delete s.dependencies[C.REDUX_PERSIST]),r.httpClient!=="none"||r.reactSecureStorage||delete s.dependencies[C.REACT_SECURE_STORAGE],r.i18n||delete s.dependencies[C.NEXT_INTL],r.darkMode||delete s.dependencies[C.NEXT_THEMES],r.httpClient==="none"?delete s.dependencies[C.AXIOS]:r.httpClient==="fetch"&&delete s.dependencies[C.AXIOS],s)),t.succeed("package.json configured.")}catch(n){throw t.fail("Failed to configure package.json."),n}};import{readdir as Xr}from"node:fs/promises";import N from"node:path";w();P();var Yr=async(e,r)=>{await ns(e,r),await os(e,r),await is(e,r),await ss(e,r),await as(e,r),await cs(e,r),await ps(e,r)},ns=async(e,r)=>{r.preCommitHooks||(await S(N.join(e,c.HUSKY_DIR)),await T(N.join(e,c.COMMITLINT_CONFIG)),await T(N.join(e,c.LINTSTAGED_RC)),await k(N.join(e,c.PACKAGE_JSON),t=>(delete t.devDependencies[C.HUSKY],delete t.devDependencies[C.COMMITLINT_CLI],delete t.devDependencies[C.COMMITLINT_CONFIG],delete t.devDependencies[C.LINT_STAGED],delete t.scripts.prepare,delete t.scripts.postinstall,delete t.commitlint,delete t["lint-staged"],t)))},os=async(e,r)=>{r.commitizen||(await T(N.join(e,c.CZRC)),await k(N.join(e,c.PACKAGE_JSON),t=>(delete t.devDependencies[C.COMMITIZEN],delete t.devDependencies[C.CZ_CONVENTIONAL_CHANGELOG],delete t.config?.commitizen,t.config&&Object.keys(t.config).length===0&&delete t.config,delete t.scripts.commit,t)))},is=async(e,r)=>{r.ci||await S(N.join(e,c.GITHUB_WORKFLOWS))},ss=async(e,r)=>{let t=N.join(e,c.GITHUB_DIR);if(!r.keepTemplates)await S(N.join(t,c.GITHUB_ISSUE_TEMPLATE)),await T(N.join(t,c.GITHUB_PR_TEMPLATE));else{let n=N.join(t,c.GITHUB_ISSUE_TEMPLATE),i=N.join(t,c.GITHUB_PR_TEMPLATE),o=s=>s.replace(/Teispace/g,r.company).replace(/support@teispace\.com/g,r.email).replace(/Next\.js Starter/g,r.projectName).replace(/\[AUTHOR\]/g,r.author).replace(/\[COMPANY\]/g,r.company).replace(/\[EMAIL\]/g,r.email);if(m(i)){let s=await u(i);s=o(s),await f(i,s)}try{if(m(n)){let s=await Xr(n);for(let a of s){let p=N.join(n,a),d=await u(p);d=o(d),await f(p,d)}}}catch{}}},as=async(e,r)=>{let t=[c.CODE_OF_CONDUCT,c.CONTRIBUTING,c.SECURITY];for(let n of t)r.communityFiles.includes(n)||await T(N.join(e,n))},cs=async(e,r)=>{if(r.docker){let t=N.join(e,c.ENV_EXAMPLE);if(m(t)){let n=await u(t),i=(o,s)=>{let a=new RegExp(`${o}=.*`);a.test(n)?n=n.replace(a,`${o}=${s}`):n+=`${o}=${s}
178
- `};i("CONTAINER_NAME",r.containerName||"next-app"),i("IMAGE_NAME",r.imageName||"nextjs-starter"),i("IMAGE_TAG",r.imageTag||"latest"),await f(t,n)}}else{await T(N.join(e,c.DOCKERFILE)),await T(N.join(e,c.DOCKER_COMPOSE)),await T(N.join(e,c.DOCKERIGNORE));let t=N.join(e,c.ENV_EXAMPLE);if(m(t)){let n=await u(t);n=n.replace(/# Docker Compose Configuration\n/,""),n=n.replace(/CONTAINER_NAME=.*\n/,""),n=n.replace(/IMAGE_NAME=.*\n/,""),n=n.replace(/IMAGE_TAG=.*\n/,""),await f(t,n)}}},ps=async(e,r)=>{let t=async o=>{let s=await Xr(o,{withFileTypes:!0}),a=[];for(let p of s){let d=N.join(o,p.name);p.isDirectory()&&p.name!=="node_modules"&&p.name!==".git"?a.push(...await t(d)):p.isFile()&&p.name.toLowerCase()==="readme.md"&&a.push(d)}return a},n=await t(e),i=N.join(e,c.README);for(let o of n)o!==i&&await T(o);if(r.readme){let o=`# ${r.projectName}
176
+ `;import kr from"node:path";var C={REDUX_TOOLKIT:"@reduxjs/toolkit",REACT_REDUX:"react-redux",REDUX:"redux",REDUX_PERSIST:"redux-persist",REACT_SECURE_STORAGE:"react-secure-storage",NEXT_INTL:"next-intl",NEXT_THEMES:"@teispace/next-themes",AXIOS:"axios",HUSKY:"husky",COMMITLINT_CLI:"@commitlint/cli",COMMITLINT_CONFIG:"@commitlint/config-conventional",LINT_STAGED:"lint-staged",COMMITIZEN:"commitizen",CZ_CONVENTIONAL_CHANGELOG:"cz-conventional-changelog",VITEST:"vitest",JSDOM:"jsdom",VITE_PLUGIN_REACT:"@vitejs/plugin-react",TESTING_LIBRARY_DOM:"@testing-library/dom",TESTING_LIBRARY_JEST_DOM:"@testing-library/jest-dom",TESTING_LIBRARY_REACT:"@testing-library/react",TESTING_LIBRARY_USER_EVENT:"@testing-library/user-event",REACT_COMPILER_BABEL:"babel-plugin-react-compiler",NEXT_BUNDLE_ANALYZER:"@next/bundle-analyzer"};w();P();var Or=async(e,r)=>{if(r.bundleAnalyzer)return;let t=kr.join(e,c.NEXT_CONFIG);if(m(t)){let n=await u(t);n=n.replace(/import\s+withBundleAnalyzer\s+from\s+'@next\/bundle-analyzer';\n/,""),n=n.replace(/const\s+bundleAnalyzer\s*=\s*withBundleAnalyzer\(\{[\s\S]*?\}\);\n+/,""),n=n.replace(/bundleAnalyzer\(([^)]*)\)/,"$1"),await f(t,n)}await k(kr.join(e,c.PACKAGE_JSON),n=>(n.devDependencies&&delete n.devDependencies[C.NEXT_BUNDLE_ANALYZER],n.scripts&&delete n.scripts.analyze,n))};w();P();import $e from"node:path";var _r=async(e,r)=>{r.darkMode||(await T($e.join(e,c.THEME_PROVIDER)),await Mi(e),await Gi(e),await Ui(e))},Mi=async e=>{let r=$e.join(e,c.PROVIDERS_INDEX),t=await u(r);t=t.replace(/export \* from '\.\/CustomThemeProvider';\n/,""),await f(r,t)},Gi=async e=>{let r=$e.join(e,c.GLOBALS_CSS);if(m(r)){let t=await u(r);t=t.replace(/@custom-variant dark \(.*?\);\n\n/,""),t=t.replace(/@theme \{[\s\S]*?\}\n/,""),await f(r,t)}},Hi=e=>e.replace(/\bbg-light\b\s?/g,"").replace(/\bdark:bg-dark\b\s?/g,"").replace(/\s{2,}/g," ").replace(/suppressHydrationWarning=\{true\}/g,""),Ui=async e=>{let r=[$e.join(e,c.ROOT_LAYOUT),$e.join(e,"src/app/[locale]/layout.tsx")];for(let t of r)if(m(t)){let n=await u(t),o=Hi(n);o!==n&&await f(t,o)}};w();P();it();import b from"node:path";var jr=async(e,r)=>{let t=b.join(e,c.HTTP_UTILS),n=r.httpClient!=="none"||!!r.reactSecureStorage;r.httpClient==="none"?await Xi(e,t,n):r.httpClient==="axios"?await Yi(e,t):r.httpClient==="fetch"&&await Ki(e,t)},Xi=async(e,r,t)=>{await S(b.join(e,c.AXIOS_CLIENT)),await S(b.join(e,c.FETCH_CLIENT)),t?(await f(b.join(r,"index.ts"),`export * from './token-store';
177
+ `),await T(b.join(e,c.CLIENT_UTILS)),await ve(e,[])):(await S(r),await qi(e),await T(b.join(e,c.APP_APIS)),await Wi(e)),await Zi(e),await S(b.join(e,c.ERRORS_DIR)),t||(await S(b.join(e,c.COMMON_TYPES_DIR)),await S(b.join(e,c.UTILITY_TYPES_DIR)),await Qi(e))},Yi=async(e,r)=>{await S(b.join(e,c.FETCH_CLIENT));let t=await u(b.join(r,"index.ts"));t=t.replace(/export .* from '\.\/fetch-client';\n/g,""),await f(b.join(r,"index.ts"),t);let n=b.join(e,c.HTTP_TYPES);if(m(n)){let o=await u(n);o=o.replace(/export interface FetchClientOptions \{[\s\S]*?\}\n\n/,""),o=o.replace(/export interface ExtendedRequestInit extends RequestInit \{[\s\S]*?\}\n\n/,""),await f(n,o)}},Ki=async(e,r)=>{await S(b.join(e,c.AXIOS_CLIENT));let t=await u(b.join(r,"index.ts"));t=t.replace(/export .* from '\.\/axios-client';\n/g,""),await f(b.join(r,"index.ts"),t),await ve(e,["fetch"]);let n=b.join(e,c.HTTP_TYPES);if(m(n)){let o=await u(n);o=o.replace(/export interface AxiosClientOptions \{[\s\S]*?\}\n\n/,""),await f(n,o)}},qi=async e=>{let r=b.join(e,c.UTILS_INDEX);if(m(r)){let t=await u(r);t=t.replace(/export \* from '\.\/http';\n/,""),await f(r,t)}},Wi=async e=>{let r=b.join(e,c.CONFIG_INDEX);if(m(r)){let t=await u(r);t=t.replace(/export \* from '\.\/app-apis';\n/,""),await f(r,t)}},Zi=async e=>{let r=b.join(e,c.CONSTANTS);if(m(r)){let t=await u(r);t=t.replace(/export const API_RESPONSE_DATA_KEY = 'data';\n/,""),t=t.replace(/export const SAVE_AUTH_TOKENS = false;\n/,""),await f(r,t)}},Qi=async e=>{let r=b.join(e,c.TYPES_INDEX);if(m(r)){let t=await u(r);t=t.replace(/export \* from '\.\/utility';\n/,""),t=t.replace(/export \* from '\.\/common';\n/,""),await f(r,t)}};w();P();import H from"node:path";var Dr=async(e,r)=>{r.i18n||(await ts(e),await rs(e),await ns(e),await os(e),await es(e))},es=async e=>{let r=H.join(e,c.ENV_EXAMPLE);if(!m(r))return;let t=await u(r);t=t.replace(/#[^\n]*IANA time zone[\s\S]*?DEFAULT_TIMEZONE=[^\n]*\n?/,""),t=t.replace(/#[^\n]*Fallback locale[\s\S]*?DEFAULT_LOCALE=[^\n]*\n?/,""),t=t.replace(/^DEFAULT_TIMEZONE=.*\n?/m,""),t=t.replace(/^DEFAULT_LOCALE=.*\n?/m,""),await f(r,t)},ts=async e=>{await S(H.join(e,c.I18N_DIR)),await S(H.join(e,c.LOCALE_DIR)),await T(H.join(e,c.PROXY)),await T(H.join(e,c.MIDDLEWARE)),await T(H.join(e,c.I18N_TYPES)),await T(H.join(e,c.APP_LOCALES))},rs=async e=>{let r=H.join(e,c.TYPES_INDEX);if(m(r)){let n=await u(r);n=n.replace(/export \* from '\.\/i18n';\n/,""),await f(r,n)}let t=H.join(e,c.CONFIG_INDEX);if(m(t)){let n=await u(t);n=n.replace(/export \* from '\.\/app-locales';\n/,""),await f(t,n)}},ns=async e=>{let r=H.join(e,c.NEXT_CONFIG);if(m(r)){let t=await u(r);t=t.replace(/import createNextIntlPlugin from 'next-intl\/plugin';\n/,""),t=t.replace(/const withNextIntl = createNextIntlPlugin\(\);\n+/,""),t=t.replace(/withNextIntl\(([^)]+)\)/,"$1"),await f(r,t)}},os=async e=>{let r=H.join(e,c.COUNTER_COMPONENT);if(m(r)){let o=await u(r);o=o.replace(/import\s+\{\s*useTranslations\s*\}\s+from\s+['"]next-intl['"];\n/,""),o=o.replace(/\s*const\s+t\s*=\s*useTranslations\(['"]Count['"]\);\n/,""),o=o.replace(/\{t\('currentCount',\s*\{\s*count:\s*value\s*\}\)\}/g,"Current Count: {value}"),o=o.replace(/\{t\(['"]increment['"]\)\}/g,"Increment"),o=o.replace(/\{t\(['"]decrement['"]\)\}/g,"Decrement"),o=o.replace(/\{t\(['"]reset['"]\)\}/g,"Reset"),await f(r,o)}let t=H.join(e,"src/features/counter/components/Counter.test.tsx"),n=H.join(e,"test/test-utils.tsx");await T(t),await T(n)};w();P();import oe from"node:path";var Lr=async(e,r)=>{r.httpClient!=="none"||r.reactSecureStorage||await S(oe.join(e,c.STORAGE_SERVICE))},Mr=async e=>{await T(oe.join(e,c.LICENSE))},Gr=async e=>{await T(oe.join(e,c.CHANGELOG))},Hr=async e=>{await T(oe.join(e,c.NVM_RC)),await T(oe.join(e,c.NPM_RC))},Ur=async e=>{await S(oe.join(e,c.CLAUDE_DIR)),await S(oe.join(e,c.DOCS_DIR)),await S(oe.join(e,c.VSCODE_DIR))};import zr from"node:path";w();P();var Vr=async(e,r)=>{if(r.reactCompiler)return;let t=zr.join(e,c.NEXT_CONFIG);if(m(t)){let n=await u(t);n=n.replace(/^\s*reactCompiler:\s*true,?\n/m,""),await f(t,n)}await k(zr.join(e,c.PACKAGE_JSON),n=>(n.devDependencies&&delete n.devDependencies[C.REACT_COMPILER_BABEL],n))};w();P();import fe from"node:path";var Jr=async(e,r)=>{r.redux||(await S(fe.join(e,c.STORE)),await S(fe.join(e,c.COUNTER_FEATURE)),await T(fe.join(e,c.STORE_PROVIDER)),await T(fe.join(e,"test/test-utils.tsx")),await is(e),await ss(e))},is=async e=>{let r=fe.join(e,c.PROVIDERS_INDEX),t=await u(r);t=t.replace(/export \* from '\.\/StoreProvider';\n/,""),await f(r,t)},ss=async e=>{let r=[fe.join(e,c.ROOT_PAGE),fe.join(e,c.LOCALE_PAGE)];for(let t of r)if(m(t)){let n=await u(t);n=n.replace(/import\s+\{\s*Counter\s*\}\s+from\s+['"]@\/features\/counter['"];\n?/,""),n=n.replace(/<Counter\s*\/>\n?/g,""),await f(t,n)}};import st from"node:path";w();P();var as=[C.VITEST,C.JSDOM,C.VITE_PLUGIN_REACT,C.TESTING_LIBRARY_DOM,C.TESTING_LIBRARY_JEST_DOM,C.TESTING_LIBRARY_REACT,C.TESTING_LIBRARY_USER_EVENT],Br=async(e,r)=>{r.tests||(await T(st.join(e,c.VITEST_CONFIG)),await S(st.join(e,c.TEST_DIR)),await T(st.join(e,"src/features/counter/components/Counter.test.tsx")),await k(st.join(e,c.PACKAGE_JSON),t=>{if(t.devDependencies)for(let n of as)delete t.devDependencies[n];return t.scripts&&(delete t.scripts.test,delete t.scripts["test:watch"],delete t.scripts["test:coverage"],typeof t.scripts.validate=="string"&&(t.scripts.validate=t.scripts.validate.replace(/\s*&&\s*yarn\s+test(?![:\w])/,"").replace(/\byarn\s+test(?![:\w])\s*&&\s*/,""))),t}))};var Xr=async(e,r)=>{let t=R("Customizing features...");try{await jr(e,r),await Lr(e,r),await Jr(e,r),await _r(e,r),await Or(e,r),await Dr(e,r),await Vr(e,r),await Br(e,r),await Mr(e),await Gr(e),await Hr(e),await Ur(e),r.tests&&await ne(e,{redux:r.redux,i18n:r.i18n}),t.succeed("Features customized.")}catch(n){throw t.fail("Failed to customize features."),n}};import cs from"node:path";w();P();var Yr=async(e,r)=>{let t=R("Configuring package.json...");try{let n=r.gitRemote,o=r.gitHomepage,i=r.gitIssues;r.gitRemote&&(r.gitRemote.startsWith("git@github.com:")&&(n=r.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"")),o||(o=`${n.replace(/\.git$/,"")}#readme`),i||(i=`${n.replace(/\.git$/,"")}/issues`),n.endsWith(".git")||(n=`${n}.git`)),await k(cs.join(e,c.PACKAGE_JSON),s=>(s.name=r.projectName,s.version=r.version,s.description=r.description,s.author=r.author,delete s.packageManager,r.gitRemote?(o&&(s.homepage=o),i&&(s.bugs={url:i}),n&&(s.repository={type:"git",url:n})):(delete s.homepage,delete s.bugs,delete s.repository),r.redux||(delete s.dependencies[C.REDUX_TOOLKIT],delete s.dependencies[C.REACT_REDUX],delete s.dependencies[C.REDUX],delete s.dependencies[C.REDUX_PERSIST]),r.httpClient!=="none"||r.reactSecureStorage||delete s.dependencies[C.REACT_SECURE_STORAGE],r.i18n||delete s.dependencies[C.NEXT_INTL],r.darkMode||delete s.dependencies[C.NEXT_THEMES],r.httpClient==="none"?delete s.dependencies[C.AXIOS]:r.httpClient==="fetch"&&delete s.dependencies[C.AXIOS],s)),t.succeed("package.json configured.")}catch(n){throw t.fail("Failed to configure package.json."),n}};import{readdir as Kr}from"node:fs/promises";import N from"node:path";w();P();var qr=async(e,r)=>{await ps(e,r),await ls(e,r),await ms(e,r),await ds(e,r),await us(e,r),await fs(e,r),await gs(e,r)},ps=async(e,r)=>{r.preCommitHooks||(await S(N.join(e,c.HUSKY_DIR)),await T(N.join(e,c.COMMITLINT_CONFIG)),await T(N.join(e,c.LINTSTAGED_RC)),await k(N.join(e,c.PACKAGE_JSON),t=>(delete t.devDependencies[C.HUSKY],delete t.devDependencies[C.COMMITLINT_CLI],delete t.devDependencies[C.COMMITLINT_CONFIG],delete t.devDependencies[C.LINT_STAGED],delete t.scripts.prepare,delete t.scripts.postinstall,delete t.commitlint,delete t["lint-staged"],t)))},ls=async(e,r)=>{r.commitizen||(await T(N.join(e,c.CZRC)),await k(N.join(e,c.PACKAGE_JSON),t=>(delete t.devDependencies[C.COMMITIZEN],delete t.devDependencies[C.CZ_CONVENTIONAL_CHANGELOG],delete t.config?.commitizen,t.config&&Object.keys(t.config).length===0&&delete t.config,delete t.scripts.commit,t)))},ms=async(e,r)=>{r.ci||await S(N.join(e,c.GITHUB_WORKFLOWS))},ds=async(e,r)=>{let t=N.join(e,c.GITHUB_DIR);if(!r.keepTemplates)await S(N.join(t,c.GITHUB_ISSUE_TEMPLATE)),await T(N.join(t,c.GITHUB_PR_TEMPLATE));else{let n=N.join(t,c.GITHUB_ISSUE_TEMPLATE),o=N.join(t,c.GITHUB_PR_TEMPLATE),i=s=>s.replace(/Teispace/g,r.company).replace(/support@teispace\.com/g,r.email).replace(/Next\.js Starter/g,r.projectName).replace(/\[AUTHOR\]/g,r.author).replace(/\[COMPANY\]/g,r.company).replace(/\[EMAIL\]/g,r.email);if(m(o)){let s=await u(o);s=i(s),await f(o,s)}try{if(m(n)){let s=await Kr(n);for(let a of s){let p=N.join(n,a),d=await u(p);d=i(d),await f(p,d)}}}catch{}}},us=async(e,r)=>{let t=[c.CODE_OF_CONDUCT,c.CONTRIBUTING,c.SECURITY];for(let n of t)r.communityFiles.includes(n)||await T(N.join(e,n))},fs=async(e,r)=>{if(r.docker){let t=N.join(e,c.ENV_EXAMPLE);if(m(t)){let n=await u(t),o=(i,s)=>{let a=new RegExp(`${i}=.*`);a.test(n)?n=n.replace(a,`${i}=${s}`):n+=`${i}=${s}
178
+ `};o("CONTAINER_NAME",r.containerName||"next-app"),o("IMAGE_NAME",r.imageName||"nextjs-starter"),o("IMAGE_TAG",r.imageTag||"latest"),await f(t,n)}}else{await T(N.join(e,c.DOCKERFILE)),await T(N.join(e,c.DOCKER_COMPOSE)),await T(N.join(e,c.DOCKERIGNORE));let t=N.join(e,c.ENV_EXAMPLE);if(m(t)){let n=await u(t);n=n.replace(/# Docker Compose Configuration\n/,""),n=n.replace(/CONTAINER_NAME=.*\n/,""),n=n.replace(/IMAGE_NAME=.*\n/,""),n=n.replace(/IMAGE_TAG=.*\n/,""),await f(t,n)}}},gs=async(e,r)=>{let t=async i=>{let s=await Kr(i,{withFileTypes:!0}),a=[];for(let p of s){let d=N.join(i,p.name);p.isDirectory()&&p.name!=="node_modules"&&p.name!==".git"?a.push(...await t(d)):p.isFile()&&p.name.toLowerCase()==="readme.md"&&a.push(d)}return a},n=await t(e),o=N.join(e,c.README);for(let i of n)i!==o&&await T(i);if(r.readme){let i=`# ${r.projectName}
179
179
 
180
180
  ${r.description}
181
181
 
@@ -188,13 +188,13 @@ ${r.packageManager==="npm"?"npm run dev":`${r.packageManager} dev`}
188
188
  \`\`\`
189
189
 
190
190
  Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
191
- `;await f(i,o)}else await T(i)};w();P();import kt from"node:path";var Kr=async(e,r)=>{let t=[];r.i18n&&t.push("import { type AbstractIntlMessages, NextIntlClientProvider } from 'next-intl';"),r.darkMode&&t.push("import { CustomThemeProvider } from '@/providers';"),r.redux&&t.push("import type { AppState } from '@/store';"),r.i18n&&t.push("import type { SupportedLocale } from '@/types/i18n';"),r.redux&&t.push("import { StoreProvider } from './StoreProvider';");let n=["children: React.ReactNode;"],i=["children"];r.i18n&&(n.push("locale: SupportedLocale;"),n.push("messages: AbstractIntlMessages;"),n.push("timeZone: string;"),i.push("locale","messages","timeZone")),r.redux&&(n.push("preloadedState?: Partial<AppState>;"),i.push("preloadedState"));let o="{children}";r.i18n&&(o=`<NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>
192
- ${o}
193
- </NextIntlClientProvider>`),r.darkMode&&(o=`<CustomThemeProvider>
194
- ${o}
195
- </CustomThemeProvider>`),r.redux&&(o=`<StoreProvider preloadedState={preloadedState}>
196
- ${o}
197
- </StoreProvider>`),o==="{children}"&&(o="<>{children}</>");let s=`type RootProviderProps = {
191
+ `;await f(o,i)}else await T(o)};w();P();import kt from"node:path";var Wr=async(e,r)=>{let t=[];r.i18n&&t.push("import { type AbstractIntlMessages, NextIntlClientProvider } from 'next-intl';"),r.darkMode&&t.push("import { CustomThemeProvider } from '@/providers';"),r.redux&&t.push("import type { AppState } from '@/store';"),r.i18n&&t.push("import type { SupportedLocale } from '@/types/i18n';"),r.redux&&t.push("import { StoreProvider } from './StoreProvider';");let n=["children: React.ReactNode;"],o=["children"];r.i18n&&(n.push("locale: SupportedLocale;"),n.push("messages: AbstractIntlMessages;"),n.push("timeZone: string;"),o.push("locale","messages","timeZone")),r.redux&&(n.push("preloadedState?: Partial<AppState>;"),o.push("preloadedState"));let i="{children}";r.i18n&&(i=`<NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>
192
+ ${i}
193
+ </NextIntlClientProvider>`),r.darkMode&&(i=`<CustomThemeProvider>
194
+ ${i}
195
+ </CustomThemeProvider>`),r.redux&&(i=`<StoreProvider preloadedState={preloadedState}>
196
+ ${i}
197
+ </StoreProvider>`),i==="{children}"&&(i="<>{children}</>");let s=`type RootProviderProps = {
198
198
  ${n.join(`
199
199
  `)}
200
200
  };`,a=`'use client';
@@ -203,12 +203,12 @@ ${t.join(`
203
203
 
204
204
  ${s}
205
205
 
206
- export const RootProvider = ({ ${i.join(", ")} }: RootProviderProps) => {
206
+ export const RootProvider = ({ ${o.join(", ")} }: RootProviderProps) => {
207
207
  return (
208
- ${o}
208
+ ${i}
209
209
  );
210
210
  };
211
- `;await f(kt.join(e,c.ROOT_PROVIDER),a)},qr=async(e,r)=>{if(r.i18n)return;let t=`\`\${livvic.variable} ${r.darkMode?"bg-light antialiased dark:bg-dark":"antialiased"}\``,n=(r.redux,""),i=`import type { Metadata } from 'next';
211
+ `;await f(kt.join(e,c.ROOT_PROVIDER),a)},Zr=async(e,r)=>{if(r.i18n)return;let t=`\`\${livvic.variable} ${r.darkMode?"bg-light antialiased dark:bg-dark":"antialiased"}\``,n=(r.redux,""),o=`import type { Metadata } from 'next';
212
212
  import '@/styles/globals.css';
213
213
  import { Livvic } from 'next/font/google';
214
214
  import { RootProvider } from '@/providers';
@@ -240,10 +240,10 @@ export default function RootLayout({
240
240
  </html>
241
241
  );
242
242
  }
243
- `;await f(kt.join(e,c.ROOT_LAYOUT),i);let o=r.redux?`import { Counter } from '@/features/counter';
243
+ `;await f(kt.join(e,c.ROOT_LAYOUT),o);let i=r.redux?`import { Counter } from '@/features/counter';
244
244
 
245
245
  `:"",s=r.redux?`
246
- <Counter />`:"",a=`${o}export default function Home() {
246
+ <Counter />`:"",a=`${i}export default function Home() {
247
247
  return (
248
248
  <div className="flex min-h-screen flex-col items-center justify-center p-24">
249
249
  <h1 className="text-4xl font-bold">Welcome to ${r.projectName}</h1>
@@ -251,14 +251,14 @@ export default function RootLayout({
251
251
  </div>
252
252
  );
253
253
  }
254
- `;await f(kt.join(e,c.ROOT_PAGE),a)};import ls from"degit";var Wr=async e=>{let r=R("Downloading template...");try{await ls("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!0}).clone(e),r.succeed("Template downloaded successfully.")}catch(t){throw r.fail("Failed to download template."),t}};var Zr=e=>{e.command("init").description("Initialize a new Next.js project").argument("[name]","Project name").action(async r=>{await ms(r)})},be=async(e,r,t,n)=>{let i=R(e);n.current=i;try{let o=await t();return i.succeed(r),o}finally{n.current===i&&(n.current=null)}},ms=async e=>{Cr(),l("Welcome to the Teispace Next.js App Creator!"),l("");let r=await br(e),t=Ot.resolve(process.cwd(),r.projectName);m(t)&&(console.error(oe.red(`Error: Directory ${r.projectName} already exists.`)),process.exit(1));let n={current:null},i=async()=>{if(m(t)){n.current?.stop(),n.current=null,console.log(oe.yellow(`
255
- Cleaning up: Deleting directory ${r.projectName}...`));try{await S(t),console.log(oe.green("Cleanup successful."))}catch(s){console.error(oe.red(`Failed to clean up directory ${r.projectName}:`),s)}}},o=async()=>{console.log(oe.red(`
256
- Process interrupted. Cleaning up...`)),await i(),process.exit(1)};process.on("SIGINT",o),process.on("SIGTERM",o);try{if(await Wr(t),await Br(t,r),await Jr(t,r),await be("Generating providers and layout...","Providers and layout generated.",async()=>{await Kr(t,r),await qr(t,r)},n),await be("Setting up developer tools...","Developer tools configured.",()=>Yr(t,r),n),await be("Initializing Git...","Git initialized.",()=>Er(t,r.gitRemote,r.pushToRemote),n),await be("Installing dependencies...","Dependencies installed.",()=>Rr(t,r.packageManager),n),await be("Formatting and linting...","Formatted.",()=>U(t,r.packageManager,"lint:fix"),n),r.copyEnv){let s=Ot.join(t,".env.example"),a=Ot.join(t,".env");m(s)&&await(await import("node:fs/promises")).copyFile(s,a)}process.off("SIGINT",o),process.off("SIGTERM",o),l(""),l(oe.green(`\u2728 Project ${r.projectName} created successfully!`)),l(""),l("To get started:"),l(oe.cyan(` cd ${r.projectName}`)),l(oe.cyan(` ${r.packageManager==="npm"?"npm run dev":`${r.packageManager} dev`}`)),l("")}catch(s){n.current?.fail("Failed to create project."),n.current=null,console.error(s),await i(),process.exit(1)}};import Yt from"node:path";import q from"picocolors";L();import{mkdir as nn,writeFile as jt}from"node:fs/promises";import ge from"node:path";P();var Ft=e=>{let{componentName:r,isClient:t,hasI18n:n}=e,i=e.translationNamespace||r,o=[];return(t||n)&&o.push("'use client';"),n&&o.push("import { useTranslations } from 'next-intl';"),o.push(""),o.push(`export function ${r}() {`),n?(o.push(` const t = useTranslations('${i}');`),o.push(""),o.push(" return ("),o.push(" <div>"),o.push(" <h2>{t('title')}</h2>"),o.push(" </div>"),o.push(" );")):(o.push(" return ("),o.push(" <div>"),o.push(` <h2>${r}</h2>`),o.push(" </div>"),o.push(" );")),o.push("}"),o.push(""),o.join(`
257
- `)},rn=e=>`export { ${e.componentName} } from './${e.componentName}';
258
- `;var Dt=async e=>{let{name:r,projectPath:t,isClient:n,hasI18n:i,featurePath:o}=e,s=$(r);o?await gs(s,t,o,n,i):await hs(s,r,t,n,i)},gs=async(e,r,t,n,i)=>{let o=ge.join(r,t,"components");await nn(o,{recursive:!0}),await jt(ge.join(o,`${e}.tsx`),Ft({componentName:e,isClient:n,hasI18n:i}))},hs=async(e,r,t,n,i)=>{let o=ge.join(t,"src","components","common",e);await nn(o,{recursive:!0}),await jt(ge.join(o,`${e}.tsx`),Ft({componentName:e,isClient:n,hasI18n:i})),await jt(ge.join(o,"index.ts"),rn({componentName:e}));let s=ge.join(t,"src","components","common","index.ts");await xs(s,`export { ${e} } from './${e}';
259
- `);let a=ge.join(t,"src","components","index.ts");await ys(a)},xs=async(e,r)=>{let t="";m(e)&&(t=await u(e)),t.includes(r.trim())||(t+=r,await f(e,t))},ys=async e=>{let r="";m(e)&&(r=await u(e));let t=`export * from './common';
260
- `;r.includes(t.trim())||(r+=t,await f(e,r))};import{writeFile as Ps}from"node:fs/promises";import vs from"node:path";var on=e=>{let{camelName:r,pascalName:t,httpClient:n}=e,i=n==="axios"?"import { axiosClient } from '@/lib/utils/http';":"import { fetchClient } from '@/lib/utils/http';",o=n==="axios"?"axiosClient":"fetchClient";return`import { AppApis } from '@/lib/config';
261
- ${i}
254
+ `;await f(kt.join(e,c.ROOT_PAGE),a)};import hs from"degit";var Qr=async e=>{let r=R("Downloading template...");try{await hs("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!0}).clone(e),r.succeed("Template downloaded successfully.")}catch(t){throw r.fail("Failed to download template."),t}};var _t=["npm","yarn","pnpm","bun"],ys=e=>{if(e!==void 0){if(!_t.includes(e))throw new Error(`Invalid --package-manager "${e}". Valid: ${_t.join(", ")}.`);return e}},en=e=>{e.command("init").description("Initialize a new Next.js project").argument("[name]","Project name").option("-y, --yes","Skip all prompts and use the recommended production defaults").option("--package-manager <pm>",`Override the package manager (one of: ${_t.join(", ")})`).action(async(r,t)=>{try{let n=ys(t.packageManager);await Ps(r,{yes:t.yes??!1,packageManager:n})}catch(n){v(`${n instanceof Error?n.message:n}`),process.exit(1)}})},be=async(e,r,t,n)=>{let o=R(e);n.current=o;try{let i=await t();return o.succeed(r),i}finally{n.current===o&&(n.current=null)}},xs=e=>{let r=[];e.darkMode&&r.push("dark mode"),e.redux&&r.push("redux"),e.i18n&&r.push("i18n"),e.tests&&r.push("tests"),e.reactCompiler&&r.push("react-compiler"),e.preCommitHooks&&r.push("pre-commit hooks"),e.commitizen&&r.push("commitizen"),e.httpClient!=="none"&&r.push(`http (${e.httpClient})`),l(V.dim("Defaults applied (run `next-maker remove <feature>` to undo any of them):")),l(V.dim(` package manager : ${e.packageManager}`)),l(V.dim(` features : ${r.join(", ")}`)),l("")},Ps=async(e,r)=>{Tr();let t;r.yes?(t=Nr(e,{packageManager:r.packageManager}),l(V.cyan(`\u2728 Bootstrapping ${t.projectName} with the recommended defaults`)),l(""),xs(t)):(l("Welcome to the Teispace Next.js App Creator!"),l(""),t=await Ir(e),r.packageManager&&(t={...t,packageManager:r.packageManager}));let n=Ot.resolve(process.cwd(),t.projectName);m(n)&&(console.error(V.red(`Error: Directory ${t.projectName} already exists.`)),process.exit(1));let o={current:null},i=async()=>{if(m(n)){o.current?.stop(),o.current=null,console.log(V.yellow(`
255
+ Cleaning up: Deleting directory ${t.projectName}...`));try{await S(n),console.log(V.green("Cleanup successful."))}catch(a){console.error(V.red(`Failed to clean up directory ${t.projectName}:`),a)}}},s=async()=>{console.log(V.red(`
256
+ Process interrupted. Cleaning up...`)),await i(),process.exit(1)};process.on("SIGINT",s),process.on("SIGTERM",s);try{if(await Qr(n),await Yr(n,t),await Xr(n,t),await be("Generating providers and layout...","Providers and layout generated.",async()=>{await Wr(n,t),await Zr(n,t)},o),await be("Setting up developer tools...","Developer tools configured.",()=>qr(n,t),o),await be("Initializing Git...","Git initialized.",()=>Rr(n,t.gitRemote,t.pushToRemote),o),await be("Installing dependencies...","Dependencies installed.",()=>$r(n,t.packageManager),o),await be("Formatting and linting...","Formatted.",()=>U(n,t.packageManager,"lint:fix"),o),t.copyEnv){let a=Ot.join(n,".env.example"),p=Ot.join(n,".env");m(a)&&await(await import("node:fs/promises")).copyFile(a,p)}process.off("SIGINT",s),process.off("SIGTERM",s),l(""),l(V.green(`\u2728 Project ${t.projectName} created successfully!`)),l(""),l("To get started:"),l(V.cyan(` cd ${t.projectName}`)),l(V.cyan(` ${t.packageManager==="npm"?"npm run dev":`${t.packageManager} dev`}`)),l("")}catch(a){o.current?.fail("Failed to create project."),o.current=null,console.error(a),await i(),process.exit(1)}};import Kt from"node:path";import W from"picocolors";L();import{mkdir as sn,writeFile as Dt}from"node:fs/promises";import ge from"node:path";P();var jt=e=>{let{componentName:r,isClient:t,hasI18n:n}=e,o=e.translationNamespace||r,i=[];return(t||n)&&i.push("'use client';"),n&&i.push("import { useTranslations } from 'next-intl';"),i.push(""),i.push(`export function ${r}() {`),n?(i.push(` const t = useTranslations('${o}');`),i.push(""),i.push(" return ("),i.push(" <div>"),i.push(" <h2>{t('title')}</h2>"),i.push(" </div>"),i.push(" );")):(i.push(" return ("),i.push(" <div>"),i.push(` <h2>${r}</h2>`),i.push(" </div>"),i.push(" );")),i.push("}"),i.push(""),i.join(`
257
+ `)},on=e=>`export { ${e.componentName} } from './${e.componentName}';
258
+ `;var Lt=async e=>{let{name:r,projectPath:t,isClient:n,hasI18n:o,featurePath:i}=e,s=$(r);i?await Cs(s,t,i,n,o):await Ts(s,r,t,n,o)},Cs=async(e,r,t,n,o)=>{let i=ge.join(r,t,"components");await sn(i,{recursive:!0}),await Dt(ge.join(i,`${e}.tsx`),jt({componentName:e,isClient:n,hasI18n:o}))},Ts=async(e,r,t,n,o)=>{let i=ge.join(t,"src","components","common",e);await sn(i,{recursive:!0}),await Dt(ge.join(i,`${e}.tsx`),jt({componentName:e,isClient:n,hasI18n:o})),await Dt(ge.join(i,"index.ts"),on({componentName:e}));let s=ge.join(t,"src","components","common","index.ts");await Es(s,`export { ${e} } from './${e}';
259
+ `);let a=ge.join(t,"src","components","index.ts");await Rs(a)},Es=async(e,r)=>{let t="";m(e)&&(t=await u(e)),t.includes(r.trim())||(t+=r,await f(e,t))},Rs=async e=>{let r="";m(e)&&(r=await u(e));let t=`export * from './common';
260
+ `;r.includes(t.trim())||(r+=t,await f(e,r))};import{writeFile as $s}from"node:fs/promises";import bs from"node:path";var an=e=>{let{camelName:r,pascalName:t,httpClient:n}=e,o=n==="axios"?"import { axiosClient } from '@/lib/utils/http';":"import { fetchClient } from '@/lib/utils/http';",i=n==="axios"?"axiosClient":"fetchClient";return`import { AppApis } from '@/lib/config';
261
+ ${o}
262
262
  import type { ResultAsync } from '@/types';
263
263
 
264
264
  /**
@@ -286,33 +286,33 @@ export interface Update${t}Dto {
286
286
 
287
287
  export const ${r}Service = {
288
288
  getAll: (): ResultAsync<${t}Summary[]> => {
289
- return ${o}.get<${t}Summary[]>(AppApis.${r}.getAll);
289
+ return ${i}.get<${t}Summary[]>(AppApis.${r}.getAll);
290
290
  },
291
291
 
292
292
  getById: (id: string): ResultAsync<${t}Detail> => {
293
- return ${o}.get<${t}Detail>(AppApis.${r}.getById(id));
293
+ return ${i}.get<${t}Detail>(AppApis.${r}.getById(id));
294
294
  },
295
295
 
296
296
  create: (data: Create${t}Dto): ResultAsync<${t}Detail> => {
297
- return ${o}.post<${t}Detail>(AppApis.${r}.create, data);
297
+ return ${i}.post<${t}Detail>(AppApis.${r}.create, data);
298
298
  },
299
299
 
300
300
  update: (id: string, data: Update${t}Dto): ResultAsync<${t}Detail> => {
301
- return ${o}.patch<${t}Detail>(AppApis.${r}.update(id), data);
301
+ return ${i}.patch<${t}Detail>(AppApis.${r}.update(id), data);
302
302
  },
303
303
 
304
304
  delete: (id: string): ResultAsync<void> => {
305
- return ${o}.delete<void>(AppApis.${r}.delete(id));
305
+ return ${i}.delete<void>(AppApis.${r}.delete(id));
306
306
  },
307
307
  };
308
- `},sn=e=>{let{camelName:r,kebabName:t}=e;return` ${r}: {
308
+ `},cn=e=>{let{camelName:r,kebabName:t}=e;return` ${r}: {
309
309
  base: \`\${API_PREFIX}/${t}\`,
310
310
  getAll: \`\${API_PREFIX}/${t}\`,
311
311
  getById: (id: string) => \`\${API_PREFIX}/${t}/\${id}\`,
312
312
  create: \`\${API_PREFIX}/${t}\`,
313
313
  update: (id: string) => \`\${API_PREFIX}/${t}/\${id}\`,
314
314
  delete: (id: string) => \`\${API_PREFIX}/${t}/\${id}\`,
315
- },`};var Lt=async e=>{let{name:r,outputPath:t,httpClient:n}=e,i=A(r),o=$(r);await Ps(vs.join(t,`${r}.service.ts`),on({camelName:i,pascalName:o,httpClient:n}))};import{mkdir as Ts,writeFile as lt}from"node:fs/promises";import V from"node:path";import{writeFile as Ss}from"node:fs/promises";import ws from"node:path";var an=e=>{let{camelName:r,httpClient:t}=e;return`import { AppApis } from '@/lib/config';
315
+ },`};var Mt=async e=>{let{name:r,outputPath:t,httpClient:n}=e,o=A(r),i=$(r);await $s(bs.join(t,`${r}.service.ts`),an({camelName:o,pascalName:i,httpClient:n}))};import{mkdir as ks,writeFile as lt}from"node:fs/promises";import J from"node:path";import{writeFile as Ns}from"node:fs/promises";import Is from"node:path";var pn=e=>{let{camelName:r,httpClient:t}=e;return`import { AppApis } from '@/lib/config';
316
316
  ${t==="axios"?"import { axiosClient } from '@/lib/utils/http';":"import { fetchClient } from '@/lib/utils/http';"}
317
317
  import type { ResultAsync } from '@/types';
318
318
 
@@ -321,29 +321,40 @@ export const ${r}Service = {
321
321
  return ${t==="axios"?"axiosClient":"fetchClient"}.get<string>(AppApis.${r}.getAll);
322
322
  },
323
323
  };
324
- `};var Ie=async e=>{let{name:r,outputPath:t,httpClient:n}=e,i=A(r);await Ss(ws.join(t,`${r}.service.ts`),an({camelName:i,httpClient:n}))};import{mkdir as Cs,writeFile as Ae}from"node:fs/promises";import ke from"node:path";var cn=e=>{let{sliceName:r,withPersist:t}=e;return`export * from './${r}.slice';
324
+ `};var Ie=async e=>{let{name:r,outputPath:t,httpClient:n}=e,o=A(r);await Ns(Is.join(t,`${r}.service.ts`),pn({camelName:o,httpClient:n}))};import{mkdir as As,writeFile as Ae}from"node:fs/promises";import ke from"node:path";var ln=e=>{let{sliceName:r,withPersist:t}=e;return`export * from './${r}.slice';
325
325
  export * from './${r}.selectors';
326
326
  export * from './${r}.types';${t?`
327
327
  export * from './persist';`:""}
328
- `},pn=e=>{let{featureName:r,componentName:t,hookName:n,withStore:i,withService:o}=e;return`export { default as ${t} } from './components/${t}';
328
+ `},mn=e=>{let{featureName:r,componentName:t,hookName:n,withStore:o,withService:i}=e;return`export { default as ${t} } from './components/${t}';
329
329
  export { ${n} } from './hooks/${n}';
330
- export * from './types/${r}.types';${i?`
331
- export * from './store';`:""}${o?`
330
+ export * from './types/${r}.types';${o?`
331
+ export * from './store';`:""}${i?`
332
332
  export * from './services/${r}.service';`:""}
333
- `};var ln=e=>{let{componentName:r,camelName:t,typesImportPath:n}=e;return`import type { PersistConfig } from 'redux-persist';
334
- import storage from 'redux-persist/lib/storage';
333
+ `};var dn=e=>{let{componentName:r,camelName:t,typesImportPath:n}=e,o=`${t.toUpperCase()}_PERSIST_VERSION`;return`import { createMigrate, type PersistConfig, type PersistedState } from 'redux-persist';
334
+ import storage from '@/store/storage';
335
335
  import type { ${r}State } from '${n}';
336
336
 
337
+ const ${o} = 1;
338
+
339
+ const migrations = {
340
+ // Bump ${o} and add a migration here when ${r}State's
341
+ // shape changes. Receives the previously-persisted state, returns the new
342
+ // shape. Returning \`undefined\` discards stale state.
343
+ // 2: (state) => ({ ...state, newField: defaultValue }),
344
+ } satisfies Record<number, (state: PersistedState) => PersistedState>;
345
+
337
346
  export const ${t}PersistConfig: PersistConfig<${r}State> = {
338
347
  key: '${t}',
339
348
  storage,
349
+ version: ${o},
340
350
  // whitelist: ['someField'], // Specify which fields to persist
351
+ migrate: createMigrate(migrations, { debug: false }),
341
352
  };
342
- `};var mn=e=>{let{componentName:r,camelName:t,sliceName:n}=e;return`import { RootState } from '@/store/rootReducer';
353
+ `};var un=e=>{let{componentName:r,camelName:t,sliceName:n}=e;return`import { RootState } from '@/store/rootReducer';
343
354
 
344
355
  export const select${r}State = (state: RootState) => state.${t};
345
356
  export { setLoading, setError, resetState } from './${n}.slice';
346
- `};var dn=e=>{let{componentName:r,camelName:t,typesImportPath:n}=e;return`import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
357
+ `};var fn=e=>{let{componentName:r,camelName:t,typesImportPath:n}=e;return`import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
347
358
  import type { ${r}State } from '${n}';
348
359
 
349
360
  const initialState: ${r}State = {
@@ -378,7 +389,7 @@ export const ${t}Reducer = ${t}Slice.reducer;
378
389
  // Add your state properties here`:`// Add your state properties here
379
390
  // example: value: string;`}
380
391
  }
381
- `};var Oe=async e=>{let{name:r,outputPath:t,persist:n,typesImportPath:i=`./${r}.types`}=e;await Cs(t,{recursive:!0});let o=$(r),s=A(r);await Promise.all([Ae(ke.join(t,`${r}.types.ts`),pt({componentName:o,withStore:!0})),Ae(ke.join(t,`${r}.slice.ts`),dn({componentName:o,camelName:s,typesImportPath:i})),Ae(ke.join(t,`${r}.selectors.ts`),mn({componentName:o,camelName:s,sliceName:r})),...n?[Ae(ke.join(t,"persist.ts"),ln({componentName:o,camelName:s,typesImportPath:i}))]:[],Ae(ke.join(t,"index.ts"),cn({sliceName:r,withPersist:n}))])};var un=e=>{let{componentName:r,hookName:t}=e;return`'use client';
392
+ `};var Oe=async e=>{let{name:r,outputPath:t,persist:n,typesImportPath:o=`./${r}.types`}=e;await As(t,{recursive:!0});let i=$(r),s=A(r);await Promise.all([Ae(ke.join(t,`${r}.types.ts`),pt({componentName:i,withStore:!0})),Ae(ke.join(t,`${r}.slice.ts`),fn({componentName:i,camelName:s,typesImportPath:o})),Ae(ke.join(t,`${r}.selectors.ts`),un({componentName:i,camelName:s,sliceName:r})),...n?[Ae(ke.join(t,"persist.ts"),dn({componentName:i,camelName:s,typesImportPath:o}))]:[],Ae(ke.join(t,"index.ts"),ln({sliceName:r,withPersist:n}))])};var gn=e=>{let{componentName:r,hookName:t}=e;return`'use client';
382
393
  import { ${t} } from '../hooks/${t}';
383
394
 
384
395
  export function ${r}() {
@@ -393,7 +404,7 @@ export function ${r}() {
393
404
  }
394
405
 
395
406
  export default ${r};
396
- `};var fn=e=>{let{hookName:r,componentName:t,featureName:n}=e;return`'use client';
407
+ `};var hn=e=>{let{hookName:r,componentName:t,featureName:n}=e;return`'use client';
397
408
  import { useAppDispatch, useAppSelector } from '@/store/hooks';
398
409
  import { select${t}State, setLoading, setError } from '../store/${n}.selectors';
399
410
 
@@ -417,7 +428,7 @@ export const ${r} = () => {
417
428
  setError: handleSetError,
418
429
  } as const;
419
430
  };
420
- `},gn=e=>{let{hookName:r}=e;return`'use client';
431
+ `},yn=e=>{let{hookName:r}=e;return`'use client';
421
432
  import { useState } from 'react';
422
433
 
423
434
  export const ${r} = () => {
@@ -429,8 +440,8 @@ export const ${r} = () => {
429
440
  // Add your methods here
430
441
  } as const;
431
442
  };
432
- `};var Mt=async e=>{let{name:r,outputPath:t,createStore:n,persistStore:i,createService:o,httpClient:s}=e,a=$(r),p=`use${a}`,d=[V.join(t,"components"),V.join(t,"hooks"),V.join(t,"types"),...n?[V.join(t,"store")]:[],...o?[V.join(t,"services")]:[]];await Promise.all(d.map(g=>Ts(g,{recursive:!0}))),await Promise.all([lt(V.join(t,"components",`${a}.tsx`),un({componentName:a,hookName:p})),lt(V.join(t,"hooks",`${p}.ts`),n?fn({hookName:p,componentName:a,featureName:r}):gn({hookName:p})),lt(V.join(t,"types",`${r}.types.ts`),pt({componentName:a,withStore:n})),lt(V.join(t,"index.ts"),pn({featureName:r,componentName:a,hookName:p,withStore:n,withService:o}))]),n&&await Oe({name:r,outputPath:V.join(t,"store"),persist:i,typesImportPath:`../types/${r}.types`}),o&&s&&await Ie({name:r,outputPath:V.join(t,"services"),httpClient:s})};import{mkdir as Es,writeFile as Rs}from"node:fs/promises";import Gt from"node:path";var hn=e=>{let{hookName:r,isClient:t}=e,n=[];return t&&n.push("'use client';"),n.push("import { useState, useCallback } from 'react';"),n.push(""),n.push(`export const ${r} = () => {`),n.push(" const [loading, setLoading] = useState(false);"),n.push(" const [error, setError] = useState<string | null>(null);"),n.push(""),n.push(" const execute = useCallback(async () => {"),n.push(" setLoading(true);"),n.push(" setError(null);"),n.push(" try {"),n.push(" // Add your logic here"),n.push(" } catch (err) {"),n.push(" setError(err instanceof Error ? err.message : 'An error occurred');"),n.push(" } finally {"),n.push(" setLoading(false);"),n.push(" }"),n.push(" }, []);"),n.push(""),n.push(" return {"),n.push(" loading,"),n.push(" error,"),n.push(" execute,"),n.push(" } as const;"),n.push("};"),n.push(""),n.join(`
433
- `)};var Ht=async e=>{let{name:r,projectPath:t,isClient:n,featurePath:i}=e,s=`use${$(r)}`,a;i?a=Gt.join(t,i,"hooks"):a=Gt.join(t,"src","hooks"),await Es(a,{recursive:!0}),await Rs(Gt.join(a,`${s}.ts`),hn({hookName:s,isClient:n}))};import{mkdir as Ns}from"node:fs/promises";import mt from"node:path";P();var $s=e=>`import { setRequestLocale } from 'next-intl/server';
443
+ `};var Gt=async e=>{let{name:r,outputPath:t,createStore:n,persistStore:o,createService:i,httpClient:s}=e,a=$(r),p=`use${a}`,d=[J.join(t,"components"),J.join(t,"hooks"),J.join(t,"types"),...n?[J.join(t,"store")]:[],...i?[J.join(t,"services")]:[]];await Promise.all(d.map(g=>ks(g,{recursive:!0}))),await Promise.all([lt(J.join(t,"components",`${a}.tsx`),gn({componentName:a,hookName:p})),lt(J.join(t,"hooks",`${p}.ts`),n?hn({hookName:p,componentName:a,featureName:r}):yn({hookName:p})),lt(J.join(t,"types",`${r}.types.ts`),pt({componentName:a,withStore:n})),lt(J.join(t,"index.ts"),mn({featureName:r,componentName:a,hookName:p,withStore:n,withService:i}))]),n&&await Oe({name:r,outputPath:J.join(t,"store"),persist:o,typesImportPath:`../types/${r}.types`}),i&&s&&await Ie({name:r,outputPath:J.join(t,"services"),httpClient:s})};import{mkdir as Os,writeFile as _s}from"node:fs/promises";import Ht from"node:path";var xn=e=>{let{hookName:r,isClient:t}=e,n=[];return t&&n.push("'use client';"),n.push("import { useState, useCallback } from 'react';"),n.push(""),n.push(`export const ${r} = () => {`),n.push(" const [loading, setLoading] = useState(false);"),n.push(" const [error, setError] = useState<string | null>(null);"),n.push(""),n.push(" const execute = useCallback(async () => {"),n.push(" setLoading(true);"),n.push(" setError(null);"),n.push(" try {"),n.push(" // Add your logic here"),n.push(" } catch (err) {"),n.push(" setError(err instanceof Error ? err.message : 'An error occurred');"),n.push(" } finally {"),n.push(" setLoading(false);"),n.push(" }"),n.push(" }, []);"),n.push(""),n.push(" return {"),n.push(" loading,"),n.push(" error,"),n.push(" execute,"),n.push(" } as const;"),n.push("};"),n.push(""),n.join(`
444
+ `)};var Ut=async e=>{let{name:r,projectPath:t,isClient:n,featurePath:o}=e,s=`use${$(r)}`,a;o?a=Ht.join(t,o,"hooks"):a=Ht.join(t,"src","hooks"),await Os(a,{recursive:!0}),await _s(Ht.join(a,`${s}.ts`),xn({hookName:s,isClient:n}))};import{mkdir as Ds}from"node:fs/promises";import mt from"node:path";P();var Fs=e=>`import { setRequestLocale } from 'next-intl/server';
434
445
  import type { SupportedLocale } from '@/types/i18n';
435
446
 
436
447
  type Props = {
@@ -444,21 +455,21 @@ export default async function ${e}({ children, params }: Props) {
444
455
 
445
456
  return <>{children}</>;
446
457
  }
447
- `,bs=e=>`type Props = {
458
+ `,js=e=>`type Props = {
448
459
  children: React.ReactNode;
449
460
  };
450
461
 
451
462
  export default function ${e}({ children }: Props) {
452
463
  return <>{children}</>;
453
464
  }
454
- `,xn=({componentName:e,hasI18n:r})=>r?$s(e):bs(e);var Is=/^[a-z][a-z0-9-]*$/,As=/^[a-z][a-z0-9-]*(\/[a-z][a-z0-9-]*)*$/,ks=e=>{if(!Is.test(e))throw new Error(`Invalid layout segment "${e}". Use kebab-case letters, digits, and hyphens. For route groups pass --group instead of wrapping in parens.`)},Os=e=>{if(!As.test(e))throw new Error(`Invalid --at path "${e}". Use kebab-case segments separated by "/", e.g. "dashboard/settings".`)},Ut=async e=>{let{segment:r,at:t,projectPath:n,hasI18n:i,withGroup:o}=e;ks(r),t&&Os(t);let s=`${$(r)}Layout`,a=o?`(${r})`:r,p=["src","app"];i&&p.push("[locale]"),t&&p.push(...t.split("/")),p.push(a);let d=mt.join(n,...p),g=mt.join(d,"layout.tsx");if(m(g))throw new Error(`Layout already exists at ${mt.relative(n,g)}.`);return await Ns(d,{recursive:!0}),await f(g,xn({componentName:s,hasI18n:i})),{layoutFile:g,displayPath:mt.relative(n,g),componentName:s}};P();import{copyFile as _s,readFile as Fs,writeFile as js}from"node:fs/promises";import _e from"node:path";var zt=async e=>{let{code:r,name:t,country:n,flag:i,projectPath:o,copyTranslations:s}=e;await Ds(o,r,s),await Ls(o,r),await Ms(o,r,t,n,i)},Ds=async(e,r,t)=>{let n=_e.join(e,"src","i18n","translations"),i=_e.join(n,"en.json"),o=_e.join(n,`${r}.json`);if(t)await _s(i,o);else{let s=await Fs(i,"utf-8"),a=JSON.parse(s),p=yn(a);await js(o,`${JSON.stringify(p,null,2)}
455
- `)}},yn=e=>{let r={};for(let[t,n]of Object.entries(e))typeof n=="object"&&n!==null?r[t]=yn(n):r[t]="";return r},Ls=async(e,r)=>{let t=_e.join(e,"src","types","i18n.ts");if(!m(t))return;let n=await u(t),i=/export type SupportedLocale = (.*);/,o=n.match(i);if(o&&!o[1].includes(`'${r}'`)){let s=`${o[1]} | '${r}'`;n=n.replace(i,`export type SupportedLocale = ${s};`),await f(t,n)}},Ms=async(e,r,t,n,i)=>{let o=_e.join(e,"src","lib","config","app-locales.ts");if(!m(o))return;let s=await u(o);if(s.includes(`locale: '${r}'`))return;let a=s.lastIndexOf("];");if(a===-1)return;let p=` {
465
+ `,Pn=({componentName:e,hasI18n:r})=>r?Fs(e):js(e);var Ls=/^[a-z][a-z0-9-]*$/,Ms=/^[a-z][a-z0-9-]*(\/[a-z][a-z0-9-]*)*$/,Gs=e=>{if(!Ls.test(e))throw new Error(`Invalid layout segment "${e}". Use kebab-case letters, digits, and hyphens. For route groups pass --group instead of wrapping in parens.`)},Hs=e=>{if(!Ms.test(e))throw new Error(`Invalid --at path "${e}". Use kebab-case segments separated by "/", e.g. "dashboard/settings".`)},zt=async e=>{let{segment:r,at:t,projectPath:n,hasI18n:o,withGroup:i}=e;Gs(r),t&&Hs(t);let s=`${$(r)}Layout`,a=i?`(${r})`:r,p=["src","app"];o&&p.push("[locale]"),t&&p.push(...t.split("/")),p.push(a);let d=mt.join(n,...p),g=mt.join(d,"layout.tsx");if(m(g))throw new Error(`Layout already exists at ${mt.relative(n,g)}.`);return await Ds(d,{recursive:!0}),await f(g,Pn({componentName:s,hasI18n:o})),{layoutFile:g,displayPath:mt.relative(n,g),componentName:s}};P();import{copyFile as Us,readFile as zs,writeFile as Vs}from"node:fs/promises";import _e from"node:path";var Vt=async e=>{let{code:r,name:t,country:n,flag:o,projectPath:i,copyTranslations:s}=e;await Js(i,r,s),await Bs(i,r),await Xs(i,r,t,n,o)},Js=async(e,r,t)=>{let n=_e.join(e,"src","i18n","translations"),o=_e.join(n,"en.json"),i=_e.join(n,`${r}.json`);if(t)await Us(o,i);else{let s=await zs(o,"utf-8"),a=JSON.parse(s),p=vn(a);await Vs(i,`${JSON.stringify(p,null,2)}
466
+ `)}},vn=e=>{let r={};for(let[t,n]of Object.entries(e))typeof n=="object"&&n!==null?r[t]=vn(n):r[t]="";return r},Bs=async(e,r)=>{let t=_e.join(e,"src","types","i18n.ts");if(!m(t))return;let n=await u(t),o=/export type SupportedLocale = (.*);/,i=n.match(o);if(i&&!i[1].includes(`'${r}'`)){let s=`${i[1]} | '${r}'`;n=n.replace(o,`export type SupportedLocale = ${s};`),await f(t,n)}},Xs=async(e,r,t,n,o)=>{let i=_e.join(e,"src","lib","config","app-locales.ts");if(!m(i))return;let s=await u(i);if(s.includes(`locale: '${r}'`))return;let a=s.lastIndexOf("];");if(a===-1)return;let p=` {
456
467
  name: '${t}',
457
468
  locale: '${r}',
458
- flag: '${i}',
469
+ flag: '${o}',
459
470
  country: '${n}',
460
471
  },
461
- `;s=s.slice(0,a)+p+s.slice(a),await f(o,s)};import{mkdir as Gs,writeFile as Vt}from"node:fs/promises";import Fe from"node:path";var Pn=e=>{let{componentName:r,routePath:t,hasI18n:n}=e;return n?`import { generateSEOMetadata } from '@/lib/config/seo';
472
+ `;s=s.slice(0,a)+p+s.slice(a),await f(i,s)};import{mkdir as Ys,writeFile as Jt}from"node:fs/promises";import Fe from"node:path";var Sn=e=>{let{componentName:r,routePath:t,hasI18n:n}=e;return n?`import { generateSEOMetadata } from '@/lib/config/seo';
462
473
  import type { Metadata } from 'next';
463
474
  import { getTranslations, setRequestLocale } from 'next-intl/server';
464
475
  import type { SupportedLocale } from '@/types/i18n';
@@ -504,7 +515,7 @@ export default function ${r}Page() {
504
515
  </div>
505
516
  );
506
517
  }
507
- `},vn=e=>{let{componentName:r,paramName:t,routePath:n,hasI18n:i}=e;return i?`import { generateSEOMetadata } from '@/lib/config/seo';
518
+ `},wn=e=>{let{componentName:r,paramName:t,routePath:n,hasI18n:o}=e;return o?`import { generateSEOMetadata } from '@/lib/config/seo';
508
519
  import type { Metadata } from 'next';
509
520
  import { getTranslations, setRequestLocale } from 'next-intl/server';
510
521
  import type { SupportedLocale } from '@/types/i18n';
@@ -558,14 +569,14 @@ export default async function ${r}Page(props: Props) {
558
569
  </div>
559
570
  );
560
571
  }
561
- `},Sn=e=>`export default function ${e.componentName}Loading() {
572
+ `},Cn=e=>`export default function ${e.componentName}Loading() {
562
573
  return (
563
574
  <div className="flex h-full items-center justify-center">
564
575
  <p>Loading...</p>
565
576
  </div>
566
577
  );
567
578
  }
568
- `,wn=e=>`'use client';
579
+ `,Tn=e=>`'use client';
569
580
 
570
581
  export default function ${e.componentName}Error({
571
582
  error,
@@ -582,28 +593,28 @@ export default function ${e.componentName}Error({
582
593
  </div>
583
594
  );
584
595
  }
585
- `;var Jt=async e=>{let{name:r,projectPath:t,hasI18n:n,dynamic:i,withLoading:o=!1,withError:s=!1}=e,a=$(r),p=`/${r}`,d=n?"src/app/[locale]":"src/app",g;i?g=Fe.join(t,d,r,`[${i}]`):g=Fe.join(t,d,r),await Gs(g,{recursive:!0});let h=i?vn({componentName:a,routePath:i?`${p}/[${i}]`:p,paramName:i,hasI18n:n}):Pn({componentName:a,routePath:p,hasI18n:n});await Vt(Fe.join(g,"page.tsx"),h),o&&await Vt(Fe.join(g,"loading.tsx"),Sn({componentName:a})),s&&await Vt(Fe.join(g,"error.tsx"),wn({componentName:a}))};w();import{mkdir as Hs}from"node:fs/promises";import Bt from"node:path";P();var Cn=(e,r)=>e.endsWith(r)?e:`${e}${r}`,Tn=({baseName:e})=>{let r=Cn(e,"Provider"),t=r.replace(/Provider$/,""),n=`${t}ContextValue`,i=`${t}Context`,o=`use${t}`;return`'use client';
596
+ `;var Bt=async e=>{let{name:r,projectPath:t,hasI18n:n,dynamic:o,withLoading:i=!1,withError:s=!1}=e,a=$(r),p=`/${r}`,d=n?"src/app/[locale]":"src/app",g;o?g=Fe.join(t,d,r,`[${o}]`):g=Fe.join(t,d,r),await Ys(g,{recursive:!0});let h=o?wn({componentName:a,routePath:o?`${p}/[${o}]`:p,paramName:o,hasI18n:n}):Sn({componentName:a,routePath:p,hasI18n:n});await Jt(Fe.join(g,"page.tsx"),h),i&&await Jt(Fe.join(g,"loading.tsx"),Cn({componentName:a})),s&&await Jt(Fe.join(g,"error.tsx"),Tn({componentName:a}))};w();import{mkdir as Ks}from"node:fs/promises";import Xt from"node:path";P();var En=(e,r)=>e.endsWith(r)?e:`${e}${r}`,Rn=({baseName:e})=>{let r=En(e,"Provider"),t=r.replace(/Provider$/,""),n=`${t}ContextValue`,o=`${t}Context`,i=`use${t}`;return`'use client';
586
597
  import { createContext, useContext, useMemo } from 'react';
587
598
 
588
599
  type ${n} = {
589
600
  // TODO: declare context value fields
590
601
  };
591
602
 
592
- const ${i} = createContext<${n} | null>(null);
603
+ const ${o} = createContext<${n} | null>(null);
593
604
 
594
- export const ${o} = (): ${n} => {
595
- const ctx = useContext(${i});
605
+ export const ${i} = (): ${n} => {
606
+ const ctx = useContext(${o});
596
607
  if (!ctx) {
597
- throw new Error('${o} must be used within ${r}');
608
+ throw new Error('${i} must be used within ${r}');
598
609
  }
599
610
  return ctx;
600
611
  };
601
612
 
602
613
  export const ${r} = ({ children }: { children: React.ReactNode }) => {
603
614
  const value = useMemo<${n}>(() => ({}), []);
604
- return <${i}.Provider value={value}>{children}</${i}.Provider>;
615
+ return <${o}.Provider value={value}>{children}</${o}.Provider>;
605
616
  };
606
- `},En=e=>Cn(e,"Provider");var Us=/^[A-Za-z][A-Za-z0-9-]*$/,zs=e=>e.includes("-")?$(e):e.charAt(0).toUpperCase()+e.slice(1),Xt=async e=>{let{name:r,projectPath:t}=e;if(!Us.test(r))throw new Error(`Invalid provider name "${r}". Use kebab-case or PascalCase letters and digits only.`);let n=zs(r).replace(/Provider$/,""),i=En(n),o=i,s=Bt.join(t,c.PROVIDERS),a=Bt.join(s,`${o}.tsx`);if(m(a))throw new Error(`Provider already exists at ${Bt.relative(t,a)}.`);return await Hs(s,{recursive:!0}),await f(a,Tn({baseName:n})),{componentName:i,fileBaseName:o,providerFile:a}};P();import je from"node:path";var Rn=e=>{let{componentName:r,sourceImportPath:t,testUtilsImportPath:n,hasRedux:i,hasI18n:o}=e,s=[];o&&s.push("messages: {}"),i&&s.push("preloadedState: {}");let a=s.length?`, {
617
+ `},$n=e=>En(e,"Provider");var qs=/^[A-Za-z][A-Za-z0-9-]*$/,Ws=e=>e.includes("-")?$(e):e.charAt(0).toUpperCase()+e.slice(1),Yt=async e=>{let{name:r,projectPath:t}=e;if(!qs.test(r))throw new Error(`Invalid provider name "${r}". Use kebab-case or PascalCase letters and digits only.`);let n=Ws(r).replace(/Provider$/,""),o=$n(n),i=o,s=Xt.join(t,c.PROVIDERS),a=Xt.join(s,`${i}.tsx`);if(m(a))throw new Error(`Provider already exists at ${Xt.relative(t,a)}.`);return await Ks(s,{recursive:!0}),await f(a,Rn({baseName:n})),{componentName:o,fileBaseName:i,providerFile:a}};P();import je from"node:path";var bn=e=>{let{componentName:r,sourceImportPath:t,testUtilsImportPath:n,hasRedux:o,hasI18n:i}=e,s=[];i&&s.push("messages: {}"),o&&s.push("preloadedState: {}");let a=s.length?`, {
607
618
  ${s.join(`,
608
619
  `)},
609
620
  }`:"";return`import { describe, expect, it } from 'vitest';
@@ -617,9 +628,9 @@ describe('${r}', () => {
617
628
  expect(screen).toBeDefined();
618
629
  });
619
630
  });
620
- `},$n=e=>{let{hookName:r,sourceImportPath:t,withStore:n,testUtilsImportPath:i}=e;return n?`import { renderHook } from '@testing-library/react';
631
+ `},Nn=e=>{let{hookName:r,sourceImportPath:t,withStore:n,testUtilsImportPath:o}=e;return n?`import { renderHook } from '@testing-library/react';
621
632
  import { describe, expect, it } from 'vitest';
622
- import { TestProviders } from '${i}';
633
+ import { TestProviders } from '${o}';
623
634
  import { ${r} } from '${t}';
624
635
 
625
636
  describe('${r}', () => {
@@ -638,7 +649,7 @@ describe('${r}', () => {
638
649
  expect(result.current).toBeDefined();
639
650
  });
640
651
  });
641
- `},bn=e=>{let{camelName:r,sourceImportPath:t}=e,n=`${r}Slice`;return`import { describe, expect, it } from 'vitest';
652
+ `},In=e=>{let{camelName:r,sourceImportPath:t}=e,n=`${r}Slice`;return`import { describe, expect, it } from 'vitest';
642
653
  import { ${n}, resetState, setError, setLoading } from '${t}';
643
654
 
644
655
  describe('${n}', () => {
@@ -663,95 +674,96 @@ describe('${n}', () => {
663
674
  expect(next).toEqual(initialState);
664
675
  });
665
676
  });
666
- `};var Q=async e=>{let{projectPath:r,sourceFile:t,kind:n,symbolName:i}=e,o=je.dirname(t),s=je.basename(t).replace(/\.(tsx?|jsx?)$/i,""),a=n==="component"?".tsx":".ts",p=je.join(o,`${s}.test${a}`),d=`./${s}`,g=Vs(o,je.join(r,"test","test-utils")),h;return n==="component"?h=Rn({componentName:i,sourceImportPath:d,testUtilsImportPath:g,hasRedux:!!e.hasRedux,hasI18n:!!e.hasI18n}):n==="hook"?h=$n({hookName:i,sourceImportPath:d,withStore:!!e.hookUsesStore,testUtilsImportPath:e.hookUsesStore?g:void 0}):h=bn({camelName:i,sourceImportPath:d}),await f(p,h),p},Vs=(e,r)=>{let t=je.relative(e,r).replace(/\\/g,"/");return t.startsWith(".")?t:`./${t}`};import Js from"enquirer";var{prompt:Bs}=Js,Nn=async(e,r={})=>{let t=[];e||t.push({type:"input",name:"componentName",message:"Component name (kebab-case):",validate:i=>i?/^[a-z][a-z0-9-]*$/.test(i)?!0:"Use lowercase letters, numbers, and hyphens only":"Component name is required"}),r.client===void 0&&t.push({type:"confirm",name:"isClient",message:"Add 'use client' directive?",initial:!1});let n=t.length>0?await Bs(t):{};return{componentName:e??n.componentName,isClient:r.client??n.isClient??!1}};var In=e=>{e.command("component [name]").description("Generate a shared component").option("--client","Add 'use client' directive").option("--i18n","Add useTranslations hook").option("--feature <path>","Generate in feature directory (e.g., src/features/auth)").option("--test","Also generate a sibling test file").option("--no-test","Skip test file generation").action(async(r,t)=>{try{let n=process.cwd();l(q.cyan(`
677
+ `};var ee=async e=>{let{projectPath:r,sourceFile:t,kind:n,symbolName:o}=e,i=je.dirname(t),s=je.basename(t).replace(/\.(tsx?|jsx?)$/i,""),a=n==="component"?".tsx":".ts",p=je.join(i,`${s}.test${a}`),d=`./${s}`,g=Zs(i,je.join(r,"test","test-utils")),h;return n==="component"?h=bn({componentName:o,sourceImportPath:d,testUtilsImportPath:g,hasRedux:!!e.hasRedux,hasI18n:!!e.hasI18n}):n==="hook"?h=Nn({hookName:o,sourceImportPath:d,withStore:!!e.hookUsesStore,testUtilsImportPath:e.hookUsesStore?g:void 0}):h=In({camelName:o,sourceImportPath:d}),await f(p,h),p},Zs=(e,r)=>{let t=je.relative(e,r).replace(/\\/g,"/");return t.startsWith(".")?t:`./${t}`};import Qs from"enquirer";var{prompt:ea}=Qs,An=async(e,r={})=>{let t=[];e||t.push({type:"input",name:"componentName",message:"Component name (kebab-case):",validate:o=>o?/^[a-z][a-z0-9-]*$/.test(o)?!0:"Use lowercase letters, numbers, and hyphens only":"Component name is required"}),r.client===void 0&&t.push({type:"confirm",name:"isClient",message:"Add 'use client' directive?",initial:!1});let n=t.length>0?await ea(t):{};return{componentName:e??n.componentName,isClient:r.client??n.isClient??!1}};var kn=e=>{e.command("component [name]").description("Generate a shared component").option("--client","Add 'use client' directive").option("--i18n","Add useTranslations hook").option("--feature <path>","Generate in feature directory (e.g., src/features/auth)").option("--test","Also generate a sibling test file").option("--no-test","Skip test file generation").action(async(r,t)=>{try{let n=process.cwd();l(W.cyan(`
667
678
  \u{1F9E9} Component Generator
668
- `)),x.start("Detecting project setup...");let i=await I(n);x.succeed("Project setup detected");let o=await Nn(r,{client:t.client}),s=$(o.componentName),a=o.isClient,p=t.i18n??!1,d=Xs(t,i.hasTests);x.start("Generating component..."),await Dt({name:o.componentName,projectPath:n,isClient:a||p,hasI18n:p,featurePath:t.feature}),x.succeed("Component generated");let g=null;if(d){let y=t.feature?Yt.join(n,t.feature,"components",`${s}.tsx`):Yt.join(n,"src/components/common",s,`${s}.tsx`);x.start("Generating test..."),g=await Q({projectPath:n,sourceFile:y,kind:"component",symbolName:s,hasRedux:i.hasRedux,hasI18n:i.hasI18n}),x.succeed("Test generated")}let h=t.feature?`${t.feature}/components/${s}.tsx`:`src/components/common/${s}/${s}.tsx`;l(q.green(`
679
+ `)),y.start("Detecting project setup...");let o=await I(n);y.succeed("Project setup detected");let i=await An(r,{client:t.client}),s=$(i.componentName),a=i.isClient,p=t.i18n??!1,d=ta(t,o.hasTests);y.start("Generating component..."),await Lt({name:i.componentName,projectPath:n,isClient:a||p,hasI18n:p,featurePath:t.feature}),y.succeed("Component generated");let g=null;if(d){let x=t.feature?Kt.join(n,t.feature,"components",`${s}.tsx`):Kt.join(n,"src/components/common",s,`${s}.tsx`);y.start("Generating test..."),g=await ee({projectPath:n,sourceFile:x,kind:"component",symbolName:s,hasRedux:o.hasRedux,hasI18n:o.hasI18n}),y.succeed("Test generated")}let h=t.feature?`${t.feature}/components/${s}.tsx`:`src/components/common/${s}/${s}.tsx`;l(W.green(`
669
680
  \u2728 Component '${s}' created successfully!
670
- `)),l(q.dim(` \u{1F4C4} ${h}`)),t.feature||(l(q.dim(` \u{1F4C4} src/components/common/${s}/index.ts`)),l(q.dim(" \u{1F4DD} Updated src/components/common/index.ts")),l(q.dim(" \u{1F4DD} Updated src/components/index.ts"))),g&&l(q.dim(` \u{1F9EA} ${Yt.relative(n,g)}`)),l(""),l(q.cyan("Usage:")),t.feature?l(q.dim(` import { ${s} } from '${t.feature.replace(/^src\//,"@/")}/components/${s}';`)):l(q.dim(` import { ${s} } from '@/components';`)),l("")}catch(n){x.fail("Component generation failed"),v(`${n}`),process.exit(1)}})},Xs=(e,r)=>e.noTest?!1:e.test?!0:r;import j from"picocolors";w();P();import Ks from"node:path";w();import An from"node:path";import Ys from"picocolors";P();var De=async e=>{let r=R("Adding @next/bundle-analyzer...");try{let t=An.join(e,c.NEXT_CONFIG);if(!m(t))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await u(t);if(n.includes("@next/bundle-analyzer")){r.fail("@next/bundle-analyzer is already configured.");return}n=`import withBundleAnalyzer from '@next/bundle-analyzer';
671
- ${n}`;let i=/export default (.*?);/,o=n.match(i);if(!o)throw new Error("Could not locate `export default` in next.config.ts.");let a=`const bundleAnalyzer = withBundleAnalyzer({
681
+ `)),l(W.dim(` \u{1F4C4} ${h}`)),t.feature||(l(W.dim(` \u{1F4C4} src/components/common/${s}/index.ts`)),l(W.dim(" \u{1F4DD} Updated src/components/common/index.ts")),l(W.dim(" \u{1F4DD} Updated src/components/index.ts"))),g&&l(W.dim(` \u{1F9EA} ${Kt.relative(n,g)}`)),l(""),l(W.cyan("Usage:")),t.feature?l(W.dim(` import { ${s} } from '${t.feature.replace(/^src\//,"@/")}/components/${s}';`)):l(W.dim(` import { ${s} } from '@/components';`)),l("")}catch(n){y.fail("Component generation failed"),v(`${n}`),process.exit(1)}})},ta=(e,r)=>e.noTest?!1:e.test?!0:r;import j from"picocolors";w();P();import na from"node:path";w();import On from"node:path";import ra from"picocolors";P();var De=async e=>{let r=R("Adding @next/bundle-analyzer...");try{let t=On.join(e,c.NEXT_CONFIG);if(!m(t))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await u(t);if(n.includes("@next/bundle-analyzer")){r.fail("@next/bundle-analyzer is already configured.");return}n=`import withBundleAnalyzer from '@next/bundle-analyzer';
682
+ ${n}`;let o=/export default (.*?);/,i=n.match(o);if(!i)throw new Error("Could not locate `export default` in next.config.ts.");let a=`const bundleAnalyzer = withBundleAnalyzer({
672
683
  enabled: process.env.ANALYZE === 'true',
673
684
  });
674
685
 
675
- export default bundleAnalyzer(${o[1]});`;n=n.replace(i,a),await f(t,n),await k(An.join(e,c.PACKAGE_JSON),p=>(p.scripts=p.scripts??{},p.scripts.analyze||(p.scripts.analyze="ANALYZE=true next build"),p)),r.text="Installing @next/bundle-analyzer...",await ot(e,"@next/bundle-analyzer"),r.succeed(Ys.green("@next/bundle-analyzer configured."))}catch(t){throw r.fail("Failed to add @next/bundle-analyzer."),t}};var Kt=(e,r)=>{let t=e.split(`
676
- `),n=[],i=new RegExp(`^import\\s+${r}\\s+from\\s+['"][^'"]+['"];?\\s*$`),o=/^(import\s+)\{([^}]+)\}(\s+from\s+['"][^'"]+['"];?\s*)$/;for(let s of t){if(i.test(s))continue;let a=s.match(o);if(a){let p=a[2].split(",").map(g=>g.trim()).filter(Boolean),d=p.filter(g=>g.replace(/^type\s+/,"").split(/\s+as\s+/)[0].trim()!==r);if(d.length===0)continue;if(d.length<p.length){n.push(`${a[1]}{ ${d.join(", ")} }${a[3]}`);continue}}n.push(s)}return n.join(`
686
+ export default bundleAnalyzer(${i[1]});`;n=n.replace(o,a),await f(t,n),await k(On.join(e,c.PACKAGE_JSON),p=>(p.scripts=p.scripts??{},p.scripts.analyze||(p.scripts.analyze="ANALYZE=true next build"),p)),r.text="Installing @next/bundle-analyzer...",await ot(e,"@next/bundle-analyzer"),r.succeed(ra.green("@next/bundle-analyzer configured."))}catch(t){throw r.fail("Failed to add @next/bundle-analyzer."),t}};var qt=(e,r)=>{let t=e.split(`
687
+ `),n=[],o=new RegExp(`^import\\s+${r}\\s+from\\s+['"][^'"]+['"];?\\s*$`),i=/^(import\s+)\{([^}]+)\}(\s+from\s+['"][^'"]+['"];?\s*)$/;for(let s of t){if(o.test(s))continue;let a=s.match(i);if(a){let p=a[2].split(",").map(g=>g.trim()).filter(Boolean),d=p.filter(g=>g.replace(/^type\s+/,"").split(/\s+as\s+/)[0].trim()!==r);if(d.length===0)continue;if(d.length<p.length){n.push(`${a[1]}{ ${d.join(", ")} }${a[3]}`);continue}}n.push(s)}return n.join(`
677
688
  `)},Se=e=>r=>{let t=r.split(`
678
- `),n=new RegExp(`^([ \\t]*)<${e}\\b`),i=-1,o="";for(let h=0;h<t.length;h++){let y=t[h].match(n);if(y){i=h,o=y[1];break}}if(i===-1||!/>\s*$/.test(t[i]))return null;let s=o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=new RegExp(`^${s}<\\/${e}>\\s*$`),p=-1;for(let h=i+1;h<t.length;h++)if(a.test(t[h])){p=h;break}if(p===-1)return null;let d=t.slice(i+1,p).map(h=>h.startsWith(" ")?h.slice(2):h),g=[...t.slice(0,i),...d,...t.slice(p+1)].join(`
679
- `);return Kt(g,e)};var kn=e=>{let r=e.split(`
689
+ `),n=new RegExp(`^([ \\t]*)<${e}\\b`),o=-1,i="";for(let h=0;h<t.length;h++){let x=t[h].match(n);if(x){o=h,i=x[1];break}}if(o===-1||!/>\s*$/.test(t[o]))return null;let s=i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=new RegExp(`^${s}<\\/${e}>\\s*$`),p=-1;for(let h=o+1;h<t.length;h++)if(a.test(t[h])){p=h;break}if(p===-1)return null;let d=t.slice(o+1,p).map(h=>h.startsWith(" ")?h.slice(2):h),g=[...t.slice(0,o),...d,...t.slice(p+1)].join(`
690
+ `);return qt(g,e)};var _n=e=>{let r=e.split(`
680
691
  `).filter(n=>!/^import\s+createNextIntlPlugin\s+from\s+['"]next-intl\/plugin['"];?\s*$/.test(n)).join(`
681
- `);r=r.replace(/^const\s+withNextIntl\s*=\s*createNextIntlPlugin\([^)]*\);\s*\n?/m,"");let t=/withNextIntl\(\s*((?:[^()]|\([^()]*\))+?)\s*\)/;return t.test(r)?(r=r.replace(t,"$1"),r):null},On=e=>{let r=Kt(e,"withBundleAnalyzer"),t=/^const\s+bundleAnalyzer\s*=\s*withBundleAnalyzer\(\{[\s\S]*?\}\);\s*\n?/m;if(!t.test(r))return null;r=r.replace(t,"");let n=/bundleAnalyzer\(\s*((?:[^()]|\([^()]*\))+?)\s*\)/;return n.test(r)?(r=r.replace(n,"$1"),r):null};var _n={id:"bundle-analyzer",name:"Bundle Analyzer",description:"@next/bundle-analyzer wrapped around the default export",detect:async e=>{let r=Ks.join(e,c.NEXT_CONFIG);return m(r)?/@next\/bundle-analyzer/.test(await u(r)):!1},files:[],packages:[{name:"@next/bundle-analyzer",kind:"devDependency"}],scripts:[{name:"analyze",expectedValue:"ANALYZE=true next build"}],injections:[{file:c.NEXT_CONFIG,description:"withBundleAnalyzer import + wrapping",presence:/@next\/bundle-analyzer/,removePattern:On}],apply:De};w();P();import Zs from"node:path";w();import Fn from"node:path";import qs from"picocolors";P();var qt=e=>{let r={...e.scripts??{}},t={...e.devDependencies??{}};return r.commit||(r.commit="cz"),t[C.COMMITIZEN]||(t[C.COMMITIZEN]="*"),t[C.CZ_CONVENTIONAL_CHANGELOG]||(t[C.CZ_CONVENTIONAL_CHANGELOG]="*"),{...e,scripts:r,devDependencies:t}},Wt=e=>{let r=e.devDependencies??{},t=[];return r[C.COMMITIZEN]||t.push(C.COMMITIZEN),r[C.CZ_CONVENTIONAL_CHANGELOG]||t.push(C.CZ_CONVENTIONAL_CHANGELOG),t};var Ws=`${JSON.stringify({path:"cz-conventional-changelog"},null,2)}
682
- `,Le=async e=>{let r=R("Setting up Commitizen...");try{let t=Fn.join(e,c.CZRC);m(t)||await f(t,Ws);let n=Fn.join(e,c.PACKAGE_JSON),i=JSON.parse(await u(n)),o=Wt(i);if(await k(n,s=>qt(s)),o.length>0){r.text=`Installing ${o.join(", ")}...`;let s=await O(e);await ue(e,s,o)}r.succeed(qs.green("Commitizen configured. Use `commit` to start a guided commit."))}catch(t){throw r.fail("Failed to set up Commitizen."),t}};var jn={id:"commitizen",name:"Commitizen",description:"Guided conventional-commit prompt via `commit` script",detect:async e=>m(Zs.join(e,c.CZRC)),files:[{path:c.CZRC,generated:!0}],packages:[{name:"commitizen",kind:"devDependency"},{name:"cz-conventional-changelog",kind:"devDependency"}],scripts:[{name:"commit",expectedValue:"cz"}],injections:[],apply:Le};w();P();import ra from"node:path";import ea from"node:path";import ta from"picocolors";P();w();P();import Dn from"node:path";import Qs from"degit";var Ln=async(e,r)=>{r.text="Fetching assets from starter repo...",await Qs("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Mn=async(e,r)=>{let t=Dn.join(e,c.THEME_PROVIDER),n=Dn.join(r,"src/providers/CustomThemeProvider.tsx");await _(n,t)};w();P();import Me from"node:path";w();P();import Gn from"node:path";var dt=async e=>{let r=[Gn.join(e,c.ROOT_LAYOUT),Gn.join(e,"src/app/[locale]/layout.tsx")];for(let t of r)if(m(t)&&(await u(t)).includes("<body"))return t;for(let t of r)if(m(t))return t;return""};var Hn=async e=>{let r=Me.join(e,c.THEME_PROVIDER),t=Me.join(e,c.GLOBALS_CSS),n=Me.join(e,"package.json");if(m(r))return{isSetup:!0,reason:"CustomThemeProvider.tsx exists"};if(m(n)){let i=JSON.parse(await u(n)),o="@teispace/next-themes";if(i.dependencies?.[o]||i.devDependencies?.[o])return{isSetup:!0,reason:`${o} is installed`}}return m(t)&&(await u(t)).includes("@custom-variant dark")?{isSetup:!0,reason:"Dark theme CSS found in globals.css"}:{isSetup:!1,reason:""}},Un=async e=>{let r=Me.join(e,c.GLOBALS_CSS),t=Me.join(e,c.PROVIDERS_INDEX),n=await dt(e);if(!m(r)||!n||!m(t))throw new Error("Project structure mismatch. Ensure src/styles/globals.css, src/app/layout.tsx (or src/app/[locale]/layout.tsx), and src/providers/index.ts exist.");return n};w();P();import ut from"node:path";var zn=async e=>{let r=ut.join(e,c.PROVIDERS_INDEX),t=await u(r);t.includes("CustomThemeProvider")||(t+=`export * from './CustomThemeProvider';
683
- `,await f(r,t))},Vn=async e=>{let r=ut.join(e,"src/providers/RootProvider.tsx");if(!m(r))return;let t=await u(r),n="'use client';",i=t.includes(n);if(i&&(t=t.replace(n,"").trim()),t.includes("CustomThemeProvider")||(/import\s*\{[^}]*\}\s*from\s*'@\/providers'/.test(t)?t=t.replace(/(import\s*\{)([^}]*)(\}\s*from\s*'@\/providers')/,(o,s,a,p)=>`${s}${a.trim()?`${a.trim()}, CustomThemeProvider `:" CustomThemeProvider "}${p}`):t=`import { CustomThemeProvider } from '@/providers';
684
- ${t}`),i&&(t=`${n}
685
- ${t}`),!t.includes("<CustomThemeProvider"))if(t.includes("{children}"))t=t.replace(/\{children\}/,"<CustomThemeProvider>{children}</CustomThemeProvider>");else{let o=t.match(/return\s*\(\s*([\s\S]*?)\s*\);/);o&&(t=t.replace(o[0],`return (
692
+ `);r=r.replace(/^const\s+withNextIntl\s*=\s*createNextIntlPlugin\([^)]*\);\s*\n?/m,"");let t=/withNextIntl\(\s*((?:[^()]|\([^()]*\))+?)\s*\)/;return t.test(r)?(r=r.replace(t,"$1"),r):null},Fn=e=>{let r=qt(e,"withBundleAnalyzer"),t=/^const\s+bundleAnalyzer\s*=\s*withBundleAnalyzer\(\{[\s\S]*?\}\);\s*\n?/m;if(!t.test(r))return null;r=r.replace(t,"");let n=/bundleAnalyzer\(\s*((?:[^()]|\([^()]*\))+?)\s*\)/;return n.test(r)?(r=r.replace(n,"$1"),r):null};var jn={id:"bundle-analyzer",name:"Bundle Analyzer",description:"@next/bundle-analyzer wrapped around the default export",detect:async e=>{let r=na.join(e,c.NEXT_CONFIG);return m(r)?/@next\/bundle-analyzer/.test(await u(r)):!1},files:[],packages:[{name:"@next/bundle-analyzer",kind:"devDependency"}],scripts:[{name:"analyze",expectedValue:"ANALYZE=true next build"}],injections:[{file:c.NEXT_CONFIG,description:"withBundleAnalyzer import + wrapping",presence:/@next\/bundle-analyzer/,removePattern:Fn}],apply:De};w();P();import sa from"node:path";w();import Dn from"node:path";import oa from"picocolors";P();var Wt=e=>{let r={...e.scripts??{}},t={...e.devDependencies??{}};return r.commit||(r.commit="cz"),t[C.COMMITIZEN]||(t[C.COMMITIZEN]="*"),t[C.CZ_CONVENTIONAL_CHANGELOG]||(t[C.CZ_CONVENTIONAL_CHANGELOG]="*"),{...e,scripts:r,devDependencies:t}},Zt=e=>{let r=e.devDependencies??{},t=[];return r[C.COMMITIZEN]||t.push(C.COMMITIZEN),r[C.CZ_CONVENTIONAL_CHANGELOG]||t.push(C.CZ_CONVENTIONAL_CHANGELOG),t};var ia=`${JSON.stringify({path:"cz-conventional-changelog"},null,2)}
693
+ `,Le=async e=>{let r=R("Setting up Commitizen...");try{let t=Dn.join(e,c.CZRC);m(t)||await f(t,ia);let n=Dn.join(e,c.PACKAGE_JSON),o=JSON.parse(await u(n)),i=Zt(o);if(await k(n,s=>Wt(s)),i.length>0){r.text=`Installing ${i.join(", ")}...`;let s=await O(e);await ue(e,s,i)}r.succeed(oa.green("Commitizen configured. Use `commit` to start a guided commit."))}catch(t){throw r.fail("Failed to set up Commitizen."),t}};var Ln={id:"commitizen",name:"Commitizen",description:"Guided conventional-commit prompt via `commit` script",detect:async e=>m(sa.join(e,c.CZRC)),files:[{path:c.CZRC,generated:!0}],packages:[{name:"commitizen",kind:"devDependency"},{name:"cz-conventional-changelog",kind:"devDependency"}],scripts:[{name:"commit",expectedValue:"cz"}],injections:[],apply:Le};w();P();import la from"node:path";import ca from"node:path";import pa from"picocolors";P();w();P();import Mn from"node:path";import aa from"degit";var Gn=async(e,r)=>{r.text="Fetching assets from starter repo...",await aa("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Hn=async(e,r)=>{let t=Mn.join(e,c.THEME_PROVIDER),n=Mn.join(r,"src/providers/CustomThemeProvider.tsx");await _(n,t)};w();P();import Me from"node:path";w();P();import Un from"node:path";var dt=async e=>{let r=[Un.join(e,c.ROOT_LAYOUT),Un.join(e,"src/app/[locale]/layout.tsx")];for(let t of r)if(m(t)&&(await u(t)).includes("<body"))return t;for(let t of r)if(m(t))return t;return""};var zn=async e=>{let r=Me.join(e,c.THEME_PROVIDER),t=Me.join(e,c.GLOBALS_CSS),n=Me.join(e,"package.json");if(m(r))return{isSetup:!0,reason:"CustomThemeProvider.tsx exists"};if(m(n)){let o=JSON.parse(await u(n)),i="@teispace/next-themes";if(o.dependencies?.[i]||o.devDependencies?.[i])return{isSetup:!0,reason:`${i} is installed`}}return m(t)&&(await u(t)).includes("@custom-variant dark")?{isSetup:!0,reason:"Dark theme CSS found in globals.css"}:{isSetup:!1,reason:""}},Vn=async e=>{let r=Me.join(e,c.GLOBALS_CSS),t=Me.join(e,c.PROVIDERS_INDEX),n=await dt(e);if(!m(r)||!n||!m(t))throw new Error("Project structure mismatch. Ensure src/styles/globals.css, src/app/layout.tsx (or src/app/[locale]/layout.tsx), and src/providers/index.ts exist.");return n};w();P();import ut from"node:path";var Jn=async e=>{let r=ut.join(e,c.PROVIDERS_INDEX),t=await u(r);t.includes("CustomThemeProvider")||(t+=`export * from './CustomThemeProvider';
694
+ `,await f(r,t))},Bn=async e=>{let r=ut.join(e,"src/providers/RootProvider.tsx");if(!m(r))return;let t=await u(r),n="'use client';",o=t.includes(n);if(o&&(t=t.replace(n,"").trim()),t.includes("CustomThemeProvider")||(/import\s*\{[^}]*\}\s*from\s*'@\/providers'/.test(t)?t=t.replace(/(import\s*\{)([^}]*)(\}\s*from\s*'@\/providers')/,(i,s,a,p)=>`${s}${a.trim()?`${a.trim()}, CustomThemeProvider `:" CustomThemeProvider "}${p}`):t=`import { CustomThemeProvider } from '@/providers';
695
+ ${t}`),o&&(t=`${n}
696
+ ${t}`),!t.includes("<CustomThemeProvider"))if(t.includes("{children}"))t=t.replace(/\{children\}/,"<CustomThemeProvider>{children}</CustomThemeProvider>");else{let i=t.match(/return\s*\(\s*([\s\S]*?)\s*\);/);i&&(t=t.replace(i[0],`return (
686
697
  <CustomThemeProvider>
687
- ${o[1]}
698
+ ${i[1]}
688
699
  </CustomThemeProvider>
689
- );`))}await f(r,t)},Jn=async(e,r)=>{let t=ut.join(e,c.GLOBALS_CSS),n=ut.join(r,"src/styles/globals.css"),i="";if(m(n)){let s=await u(n),a=s.match(/@custom-variant dark \(.*?\);/),p=s.match(/@theme \{[\s\S]*?\}/);a&&(i+=`
700
+ );`))}await f(r,t)},Xn=async(e,r)=>{let t=ut.join(e,c.GLOBALS_CSS),n=ut.join(r,"src/styles/globals.css"),o="";if(m(n)){let s=await u(n),a=s.match(/@custom-variant dark \(.*?\);/),p=s.match(/@theme \{[\s\S]*?\}/);a&&(o+=`
690
701
  ${a[0]}
691
- `),p&&(i+=`
702
+ `),p&&(o+=`
692
703
  ${p[0]}
693
- `)}i||(i=`
704
+ `)}o||(o=`
694
705
  @custom-variant dark (&:where(.dark, .dark *));
695
706
 
696
707
  @theme {
697
708
  --color-dark: #202938;
698
709
  --color-light: #f5f5f5;
699
710
  }
700
- `);let o=await u(t);if(!o.includes("@custom-variant dark")){if(o.includes("@import")){let s=o.lastIndexOf("@import"),a=o.indexOf(`
701
- `,s);o=o.slice(0,a+1)+i+o.slice(a+1)}else o=i+o;await f(t,o)}},Bn=async e=>{let r=await u(e);r.includes("dark:bg-dark")||(r=r.replace(/className="([^"]*)"/,'className="$1 bg-light dark:bg-dark"'),await f(e,r))};var Ge=async e=>{let r=R("Setting up Dark Theme..."),t=ea.join(e,".next-maker-temp");try{let{isSetup:n,reason:i}=await Hn(e);if(n){r.fail(`Dark Theme is already set up (${i}).`);return}let o=await Un(e);await Ln(t,r),await Mn(e,t),await zn(e),await Vn(e),await Jn(e,t),await Bn(o),r.text="Installing @teispace/next-themes...",await z(e,"@teispace/next-themes"),r.text="Formatting code...";let s=await O(e);await U(e,s,"lint:fix"),r.succeed(ta.green("Dark Theme setup successfully!"))}catch(n){throw r.fail("Failed to setup Dark Theme."),n}finally{await S(t)}};var Xn={id:"dark-theme",name:"Dark Theme",description:"@teispace/next-themes + CustomThemeProvider",detect:async e=>m(ra.join(e,c.THEME_PROVIDER)),files:[{path:c.THEME_PROVIDER,generated:!0}],packages:[{name:"@teispace/next-themes",kind:"dependency"}],scripts:[],injections:[{file:"src/providers/RootProvider.tsx",description:"<CustomThemeProvider> wrap",presence:/CustomThemeProvider/,removePattern:Se("CustomThemeProvider")}],apply:Ge};import oa from"node:fs/promises";import ft from"node:path";import gt from"enquirer";import Zt from"picocolors";P();w();P();import ee from"node:fs/promises";import E from"node:path";import na from"degit";var Yn=async(e,r)=>{r.text="Downloading assets from starter repository...",await na("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Kn=async(e,r,t,n)=>{let i=E.join(e,c.HTTP_UTILS),o=E.join(r,c.HTTP_UTILS);await ee.cp(E.join(r,c.ERRORS_DIR),E.join(e,c.ERRORS_DIR),{recursive:!0});let s=E.join(e,c.APP_APIS);m(s)||await _(E.join(r,c.APP_APIS),s);let a=E.join(e,c.CONSTANTS);if(!m(a))await _(E.join(r,c.CONSTANTS),a);else{let d=await u(a),g=!1;d.includes("API_RESPONSE_DATA_KEY")||(d+=`
711
+ `);let i=await u(t);if(!i.includes("@custom-variant dark")){if(i.includes("@import")){let s=i.lastIndexOf("@import"),a=i.indexOf(`
712
+ `,s);i=i.slice(0,a+1)+o+i.slice(a+1)}else i=o+i;await f(t,i)}},Yn=async e=>{let r=await u(e);r.includes("dark:bg-dark")||(r=r.replace(/className="([^"]*)"/,'className="$1 bg-light dark:bg-dark"'),await f(e,r))};var Ge=async e=>{let r=R("Setting up Dark Theme..."),t=ca.join(e,".next-maker-temp");try{let{isSetup:n,reason:o}=await zn(e);if(n){r.fail(`Dark Theme is already set up (${o}).`);return}let i=await Vn(e);await Gn(t,r),await Hn(e,t),await Jn(e),await Bn(e),await Xn(e,t),await Yn(i),r.text="Installing @teispace/next-themes...",await z(e,"@teispace/next-themes"),r.text="Formatting code...";let s=await O(e);await U(e,s,"lint:fix"),r.succeed(pa.green("Dark Theme setup successfully!"))}catch(n){throw r.fail("Failed to setup Dark Theme."),n}finally{await S(t)}};var Kn={id:"dark-theme",name:"Dark Theme",description:"@teispace/next-themes + CustomThemeProvider",detect:async e=>m(la.join(e,c.THEME_PROVIDER)),files:[{path:c.THEME_PROVIDER,generated:!0}],packages:[{name:"@teispace/next-themes",kind:"dependency"}],scripts:[],injections:[{file:"src/providers/RootProvider.tsx",description:"<CustomThemeProvider> wrap",presence:/CustomThemeProvider/,removePattern:Se("CustomThemeProvider")}],apply:Ge};import da from"node:fs/promises";import ft from"node:path";import gt from"enquirer";import Qt from"picocolors";P();w();P();import te from"node:fs/promises";import E from"node:path";import ma from"degit";var qn=async(e,r)=>{r.text="Downloading assets from starter repository...",await ma("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Wn=async(e,r,t,n)=>{let o=E.join(e,c.HTTP_UTILS),i=E.join(r,c.HTTP_UTILS);await te.cp(E.join(r,c.ERRORS_DIR),E.join(e,c.ERRORS_DIR),{recursive:!0});let s=E.join(e,c.APP_APIS);m(s)||await _(E.join(r,c.APP_APIS),s);let a=E.join(e,c.CONSTANTS);if(!m(a))await _(E.join(r,c.CONSTANTS),a);else{let d=await u(a),g=!1;d.includes("API_RESPONSE_DATA_KEY")||(d+=`
702
713
  export const API_RESPONSE_DATA_KEY = 'data';
703
714
  `,g=!0),d.includes("SAVE_AUTH_TOKENS")||(d+=`
704
715
  export const SAVE_AUTH_TOKENS = false;
705
- `,g=!0),g&&await f(a,d)}let p=E.join(e,c.STORAGE_SERVICE);if(m(p)||await ee.cp(E.join(r,c.STORAGE_SERVICE),p,{recursive:!0}),await ee.cp(E.join(r,c.COMMON_TYPES_DIR),E.join(e,c.COMMON_TYPES_DIR),{recursive:!0}),await ee.cp(E.join(r,c.UTILITY_TYPES_DIR),E.join(e,c.UTILITY_TYPES_DIR),{recursive:!0}),await _(E.join(o,"token-store.ts"),E.join(i,"token-store.ts")),await _(E.join(o,"client-utils.ts"),E.join(i,"client-utils.ts")),n&&n.length>0)for(let d of n){let g=E.join(e,d==="fetch"?c.FETCH_CLIENT:c.AXIOS_CLIENT);await S(g)}for(let d of t)d==="fetch"?await ee.cp(E.join(r,c.FETCH_CLIENT),E.join(e,c.FETCH_CLIENT),{recursive:!0}):await ee.cp(E.join(r,c.AXIOS_CLIENT),E.join(e,c.AXIOS_CLIENT),{recursive:!0});await _(E.join(o,"index.ts"),E.join(i,"index.ts")),await _(E.join(r,c.HTTP_TYPES),E.join(e,c.HTTP_TYPES))},qn=async e=>{let{isFileUsed:r,isStringUsed:t}=await Promise.resolve().then(()=>(it(),Or));await S(E.join(e,c.HTTP_UTILS));let n=E.join(e,c.STORAGE_SERVICE);m(n)&&(await t(e,"SecureStorageService",[n])||await S(n));let i=E.join(e,c.CONSTANTS);if(m(i)){let p=await u(i),d=!1;await t(e,"API_RESPONSE_DATA_KEY",[i])||(p=p.replace(/export const API_RESPONSE_DATA_KEY = .*;\n?/g,""),d=!0),await t(e,"SAVE_AUTH_TOKENS",[i])||(p=p.replace(/export const SAVE_AUTH_TOKENS = .*;\n?/g,""),d=!0),d&&(p=`${p.replace(/\n\s*\n/g,`
716
+ `,g=!0),g&&await f(a,d)}let p=E.join(e,c.STORAGE_SERVICE);if(m(p)||await te.cp(E.join(r,c.STORAGE_SERVICE),p,{recursive:!0}),await te.cp(E.join(r,c.COMMON_TYPES_DIR),E.join(e,c.COMMON_TYPES_DIR),{recursive:!0}),await te.cp(E.join(r,c.UTILITY_TYPES_DIR),E.join(e,c.UTILITY_TYPES_DIR),{recursive:!0}),await _(E.join(i,"token-store.ts"),E.join(o,"token-store.ts")),await _(E.join(i,"client-utils.ts"),E.join(o,"client-utils.ts")),n&&n.length>0)for(let d of n){let g=E.join(e,d==="fetch"?c.FETCH_CLIENT:c.AXIOS_CLIENT);await S(g)}for(let d of t)d==="fetch"?await te.cp(E.join(r,c.FETCH_CLIENT),E.join(e,c.FETCH_CLIENT),{recursive:!0}):await te.cp(E.join(r,c.AXIOS_CLIENT),E.join(e,c.AXIOS_CLIENT),{recursive:!0});await _(E.join(i,"index.ts"),E.join(o,"index.ts")),await _(E.join(r,c.HTTP_TYPES),E.join(e,c.HTTP_TYPES))},Zn=async e=>{let{isFileUsed:r,isStringUsed:t}=await Promise.resolve().then(()=>(it(),Fr));await S(E.join(e,c.HTTP_UTILS));let n=E.join(e,c.STORAGE_SERVICE);m(n)&&(await t(e,"SecureStorageService",[n])||await S(n));let o=E.join(e,c.CONSTANTS);if(m(o)){let p=await u(o),d=!1;await t(e,"API_RESPONSE_DATA_KEY",[o])||(p=p.replace(/export const API_RESPONSE_DATA_KEY = .*;\n?/g,""),d=!0),await t(e,"SAVE_AUTH_TOKENS",[o])||(p=p.replace(/export const SAVE_AUTH_TOKENS = .*;\n?/g,""),d=!0),d&&(p=`${p.replace(/\n\s*\n/g,`
706
717
 
707
718
  `).trim()}
708
- `,await f(i,p))}let o=E.join(e,c.ERRORS_DIR);if(m(o)){let p=await ee.readdir(o),d=!1;for(let g of p){let h=E.parse(g).name;if(await r(e,h,[E.join(o,g)])){d=!0;break}}d||await S(o)}let s=E.join(e,c.COMMON_TYPES_DIR);m(s)&&(await ee.readdir(s)).length===0&&await S(s);let a=E.join(e,c.UTILITY_TYPES_DIR);m(a)&&(await ee.readdir(a)).length===0&&await S(a)};w();P();import He from"node:path";var Wn=async e=>{let r=He.join(e,c.FETCH_CLIENT_FILE),t=He.join(e,c.AXIOS_CLIENT_FILE),n=m(r),i=m(t);return n&&i?{status:"both",reason:"Both Fetch and Axios clients are detected"}:n?{status:"fetch",reason:"Fetch client is already setup"}:i?{status:"axios",reason:"Axios client is already setup"}:{status:"none"}},Zn=async e=>{let t=[He.join(e,"src/lib"),He.join(e,"src/types"),He.join(e,"src/lib/config")].filter(n=>!m(n));if(t.length>0)throw new Error(`Invalid project structure. Missing directories:
719
+ `,await f(o,p))}let i=E.join(e,c.ERRORS_DIR);if(m(i)){let p=await te.readdir(i),d=!1;for(let g of p){let h=E.parse(g).name;if(await r(e,h,[E.join(i,g)])){d=!0;break}}d||await S(i)}let s=E.join(e,c.COMMON_TYPES_DIR);m(s)&&(await te.readdir(s)).length===0&&await S(s);let a=E.join(e,c.UTILITY_TYPES_DIR);m(a)&&(await te.readdir(a)).length===0&&await S(a)};w();P();import He from"node:path";var Qn=async e=>{let r=He.join(e,c.FETCH_CLIENT_FILE),t=He.join(e,c.AXIOS_CLIENT_FILE),n=m(r),o=m(t);return n&&o?{status:"both",reason:"Both Fetch and Axios clients are detected"}:n?{status:"fetch",reason:"Fetch client is already setup"}:o?{status:"axios",reason:"Axios client is already setup"}:{status:"none"}},eo=async e=>{let t=[He.join(e,"src/lib"),He.join(e,"src/types"),He.join(e,"src/lib/config")].filter(n=>!m(n));if(t.length>0)throw new Error(`Invalid project structure. Missing directories:
709
720
  ${t.map(n=>`- ${n}`).join(`
710
- `)}`)};it();var Ue=async e=>{let r=R("Checking HTTP Client setup..."),t=ft.join(e,".next-maker-temp-http");try{let{status:n,reason:i}=await Wn(e);r.stop();let o=await ia(n,i);if(o.type==="cancel"){console.log(Zt.yellow("Setup cancelled."));return}if(r.start("Setting up HTTP client(s)..."),await Zn(e),await Yn(t,r),o.type==="replace"&&o.fromClient&&(r.text="Migrating client usages...",await It(e,o.fromClient,o.clients[0])),o.type!=="remove-both"&&o.type!=="remove-one"){r.text="Copying client files...";let Y=o.type==="replace"&&o.fromClient?[o.fromClient]:void 0;await Kn(e,t,o.clients,Y)}if(o.type==="remove-one"||o.type==="remove-both"){r.text="Removing client files...";let{PROJECT_PATHS:Y}=await Promise.resolve().then(()=>(w(),Nr));for(let tt of o.clients){let rt=ft.join(e,tt==="fetch"?Y.FETCH_CLIENT:Y.AXIOS_CLIENT);await S(rt)}Qn(n,o).length===0&&(r.text="Performing full cleanup...",await qn(e),await At(e))}let s=Qn(n,o);s.length>0&&(r.text="Configuring client...",await Rt(e,s),await $t(e),await bt(e),await Nt(e)),await ve(e,s),r.text="Managing dependencies...";let a=ft.join(e,"package.json"),p=JSON.parse(await oa.readFile(a,"utf-8")),d={...p.dependencies,...p.devDependencies};s.includes("axios")?d.axios||(r.text="Installing Axios...",await z(e,"axios")):d.axios&&(r.text="Uninstalling Axios...",await Tt(e,"axios"));let g=ft.join(e,"src/services/storage");s.length>0||m(g)?d["react-secure-storage"]||(r.text="Installing react-secure-storage...",await z(e,"react-secure-storage")):d["react-secure-storage"]&&(r.text="Uninstalling react-secure-storage...",await Tt(e,"react-secure-storage")),r.text="Formatting code...";let y=await O(e);await U(e,y,"lint:fix"),r.succeed(Zt.green(sa(o)))}catch(n){throw r.fail("Failed to setup HTTP Client."),n}finally{await S(t)}};async function ia(e,r){if(e==="none"){let{choice:n}=await gt.prompt({type:"select",name:"choice",message:"Which HTTP client(s) do you want to setup?",choices:[{name:"fetch",message:"Fetch (Native)"},{name:"axios",message:"Axios"},{name:"both",message:"Both (Fetch + Axios)"}]});return n==="both"?{type:"install",clients:["fetch","axios"]}:{type:"install",clients:[n]}}if(e==="fetch"){let{action:n}=await gt.prompt({type:"select",name:"action",message:`${r}. What would you like to do?`,choices:[{name:"cancel",message:"Keep Fetch only (cancel)"},{name:"add",message:"Add Axios (have both)"},{name:"replace",message:"Replace with Axios only"},{name:"remove",message:"Remove Fetch"}]});if(n==="cancel")return{type:"cancel",clients:[]};if(n==="add")return{type:"add",clients:["axios"]};if(n==="replace")return{type:"replace",clients:["axios"],fromClient:"fetch"};if(n==="remove")return{type:"remove-one",clients:["fetch"]}}if(e==="axios"){let{action:n}=await gt.prompt({type:"select",name:"action",message:`${r}. What would you like to do?`,choices:[{name:"cancel",message:"Keep Axios only (cancel)"},{name:"add",message:"Add Fetch (have both)"},{name:"replace",message:"Replace with Fetch only"},{name:"remove",message:"Remove Axios"}]});if(n==="cancel")return{type:"cancel",clients:[]};if(n==="add")return{type:"add",clients:["fetch"]};if(n==="replace")return{type:"replace",clients:["fetch"],fromClient:"axios"};if(n==="remove")return{type:"remove-one",clients:["axios"]}}console.log(Zt.yellow(`\u2716 ${r}`));let{action:t}=await gt.prompt({type:"select",name:"action",message:"What would you like to do?",choices:[{name:"cancel",message:"Keep both (cancel)"},{name:"remove-fetch",message:"Remove Fetch (keep Axios)"},{name:"remove-axios",message:"Remove Axios (keep Fetch)"},{name:"remove-both",message:"Remove both"}]});return t==="cancel"?{type:"cancel",clients:[]}:t==="remove-fetch"?{type:"remove-one",clients:["fetch"]}:t==="remove-axios"?{type:"remove-one",clients:["axios"]}:t==="remove-both"?{type:"remove-both",clients:["fetch","axios"]}:{type:"cancel",clients:[]}}function Qn(e,r){return r.type==="install"?r.clients:r.type==="add"?[...e==="fetch"?["fetch"]:["axios"],...r.clients]:r.type==="replace"?r.clients:r.type==="remove-one"?e==="both"?r.clients[0]==="fetch"?["axios"]:["fetch"]:[]:[]}function sa(e){if(e.type==="install")return`HTTP Client (${e.clients.map(t=>t==="fetch"?"Fetch":"Axios").join(" + ")}) setup successfully!`;if(e.type==="add")return`${e.clients[0]==="fetch"?"Fetch":"Axios"} client added successfully! Both clients are now available.`;if(e.type==="replace"){let r=e.fromClient==="fetch"?"Fetch":"Axios",t=e.clients[0]==="fetch"?"Fetch":"Axios";return`Replaced ${r} with ${t} successfully! Imports automatically migrated.`}return e.type==="remove-one"?`${e.clients[0]==="fetch"?"Fetch":"Axios"} client removed successfully!`:e.type==="remove-both"?"Both HTTP clients removed successfully!":"HTTP Client setup completed!"}var eo={id:"http-client",name:"HTTP Client",description:"Axios and/or Fetch client utilities",detect:async e=>{let{detectProjectSetup:r}=await Promise.resolve().then(()=>(L(),Ne));return(await r(e)).httpClient!=="none"},files:[{path:"src/lib/utils/http",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds the http client + any service modules you wired through it \u2014 review before deleting"}],packages:[],scripts:[],injections:[],apply:Ue};w();import Qt from"node:path";import la from"picocolors";P();w();P();import aa from"node:fs/promises";import se from"node:path";import ca from"degit";var to=async(e,r)=>{r.text="Fetching assets from starter repo...",await ca("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},ro=async(e,r)=>{let t=se.join(r,"src/i18n"),n=se.join(e,c.I18N_DIR);await aa.cp(t,n,{recursive:!0});let i=se.join(r,"src/proxy.ts"),o=se.join(e,c.PROXY);await _(i,o);let s=se.join(r,"src/types/i18n.ts"),a=se.join(e,c.I18N_TYPES);await _(s,a);let p=se.join(r,"src/lib/config/app-locales.ts"),d=se.join(e,c.APP_LOCALES);await _(p,d)};w();P();import ht from"node:path";var no=async e=>{let r=ht.join(e,c.I18N_DIR),t=ht.join(e,"package.json");if(m(r))return{isSetup:!0,reason:"src/i18n directory exists"};if(m(t)){let n=JSON.parse(await u(t));if(n.dependencies?.["next-intl"]||n.devDependencies?.["next-intl"])return{isSetup:!0,reason:"next-intl is installed"}}return{isSetup:!1,reason:""}},oo=async e=>{let r=ht.join(e,c.ROOT_LAYOUT),t=ht.join(e,"src/app/[locale]/layout.tsx");if(!m(r)&&!m(t))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx exists.")};w();P();import pa from"node:fs/promises";import te from"node:path";var io=async e=>{let r=te.join(e,c.NEXT_CONFIG);if(m(r)){let t=await u(r);if(!t.includes("createNextIntlPlugin")){t=`import createNextIntlPlugin from 'next-intl/plugin';
721
+ `)}`)};it();var Ue=async e=>{let r=R("Checking HTTP Client setup..."),t=ft.join(e,".next-maker-temp-http");try{let{status:n,reason:o}=await Qn(e);r.stop();let i=await ua(n,o);if(i.type==="cancel"){console.log(Qt.yellow("Setup cancelled."));return}if(r.start("Setting up HTTP client(s)..."),await eo(e),await qn(t,r),i.type==="replace"&&i.fromClient&&(r.text="Migrating client usages...",await It(e,i.fromClient,i.clients[0])),i.type!=="remove-both"&&i.type!=="remove-one"){r.text="Copying client files...";let K=i.type==="replace"&&i.fromClient?[i.fromClient]:void 0;await Wn(e,t,i.clients,K)}if(i.type==="remove-one"||i.type==="remove-both"){r.text="Removing client files...";let{PROJECT_PATHS:K}=await Promise.resolve().then(()=>(w(),Ar));for(let tt of i.clients){let rt=ft.join(e,tt==="fetch"?K.FETCH_CLIENT:K.AXIOS_CLIENT);await S(rt)}to(n,i).length===0&&(r.text="Performing full cleanup...",await Zn(e),await At(e))}let s=to(n,i);s.length>0&&(r.text="Configuring client...",await Rt(e,s),await $t(e),await bt(e),await Nt(e)),await ve(e,s),r.text="Managing dependencies...";let a=ft.join(e,"package.json"),p=JSON.parse(await da.readFile(a,"utf-8")),d={...p.dependencies,...p.devDependencies};s.includes("axios")?d.axios||(r.text="Installing Axios...",await z(e,"axios")):d.axios&&(r.text="Uninstalling Axios...",await Tt(e,"axios"));let g=ft.join(e,"src/services/storage");s.length>0||m(g)?d["react-secure-storage"]||(r.text="Installing react-secure-storage...",await z(e,"react-secure-storage")):d["react-secure-storage"]&&(r.text="Uninstalling react-secure-storage...",await Tt(e,"react-secure-storage")),r.text="Formatting code...";let x=await O(e);await U(e,x,"lint:fix"),r.succeed(Qt.green(fa(i)))}catch(n){throw r.fail("Failed to setup HTTP Client."),n}finally{await S(t)}};async function ua(e,r){if(e==="none"){let{choice:n}=await gt.prompt({type:"select",name:"choice",message:"Which HTTP client(s) do you want to setup?",choices:[{name:"fetch",message:"Fetch (Native)"},{name:"axios",message:"Axios"},{name:"both",message:"Both (Fetch + Axios)"}]});return n==="both"?{type:"install",clients:["fetch","axios"]}:{type:"install",clients:[n]}}if(e==="fetch"){let{action:n}=await gt.prompt({type:"select",name:"action",message:`${r}. What would you like to do?`,choices:[{name:"cancel",message:"Keep Fetch only (cancel)"},{name:"add",message:"Add Axios (have both)"},{name:"replace",message:"Replace with Axios only"},{name:"remove",message:"Remove Fetch"}]});if(n==="cancel")return{type:"cancel",clients:[]};if(n==="add")return{type:"add",clients:["axios"]};if(n==="replace")return{type:"replace",clients:["axios"],fromClient:"fetch"};if(n==="remove")return{type:"remove-one",clients:["fetch"]}}if(e==="axios"){let{action:n}=await gt.prompt({type:"select",name:"action",message:`${r}. What would you like to do?`,choices:[{name:"cancel",message:"Keep Axios only (cancel)"},{name:"add",message:"Add Fetch (have both)"},{name:"replace",message:"Replace with Fetch only"},{name:"remove",message:"Remove Axios"}]});if(n==="cancel")return{type:"cancel",clients:[]};if(n==="add")return{type:"add",clients:["fetch"]};if(n==="replace")return{type:"replace",clients:["fetch"],fromClient:"axios"};if(n==="remove")return{type:"remove-one",clients:["axios"]}}console.log(Qt.yellow(`\u2716 ${r}`));let{action:t}=await gt.prompt({type:"select",name:"action",message:"What would you like to do?",choices:[{name:"cancel",message:"Keep both (cancel)"},{name:"remove-fetch",message:"Remove Fetch (keep Axios)"},{name:"remove-axios",message:"Remove Axios (keep Fetch)"},{name:"remove-both",message:"Remove both"}]});return t==="cancel"?{type:"cancel",clients:[]}:t==="remove-fetch"?{type:"remove-one",clients:["fetch"]}:t==="remove-axios"?{type:"remove-one",clients:["axios"]}:t==="remove-both"?{type:"remove-both",clients:["fetch","axios"]}:{type:"cancel",clients:[]}}function to(e,r){return r.type==="install"?r.clients:r.type==="add"?[...e==="fetch"?["fetch"]:["axios"],...r.clients]:r.type==="replace"?r.clients:r.type==="remove-one"?e==="both"?r.clients[0]==="fetch"?["axios"]:["fetch"]:[]:[]}function fa(e){if(e.type==="install")return`HTTP Client (${e.clients.map(t=>t==="fetch"?"Fetch":"Axios").join(" + ")}) setup successfully!`;if(e.type==="add")return`${e.clients[0]==="fetch"?"Fetch":"Axios"} client added successfully! Both clients are now available.`;if(e.type==="replace"){let r=e.fromClient==="fetch"?"Fetch":"Axios",t=e.clients[0]==="fetch"?"Fetch":"Axios";return`Replaced ${r} with ${t} successfully! Imports automatically migrated.`}return e.type==="remove-one"?`${e.clients[0]==="fetch"?"Fetch":"Axios"} client removed successfully!`:e.type==="remove-both"?"Both HTTP clients removed successfully!":"HTTP Client setup completed!"}var ro={id:"http-client",name:"HTTP Client",description:"Axios and/or Fetch client utilities",detect:async e=>{let{detectProjectSetup:r}=await Promise.resolve().then(()=>(L(),Ne));return(await r(e)).httpClient!=="none"},files:[{path:"src/lib/utils/http",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds the http client + any service modules you wired through it \u2014 review before deleting"}],packages:[],scripts:[],injections:[],apply:Ue};w();import er from"node:path";import xa from"picocolors";P();w();P();import ga from"node:fs/promises";import se from"node:path";import ha from"degit";var no=async(e,r)=>{r.text="Fetching assets from starter repo...",await ha("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},oo=async(e,r)=>{let t=se.join(r,"src/i18n"),n=se.join(e,c.I18N_DIR);await ga.cp(t,n,{recursive:!0});let o=se.join(r,"src/proxy.ts"),i=se.join(e,c.PROXY);await _(o,i);let s=se.join(r,"src/types/i18n.ts"),a=se.join(e,c.I18N_TYPES);await _(s,a);let p=se.join(r,"src/lib/config/app-locales.ts"),d=se.join(e,c.APP_LOCALES);await _(p,d)};w();P();import ht from"node:path";var io=async e=>{let r=ht.join(e,c.I18N_DIR),t=ht.join(e,"package.json");if(m(r))return{isSetup:!0,reason:"src/i18n directory exists"};if(m(t)){let n=JSON.parse(await u(t));if(n.dependencies?.["next-intl"]||n.devDependencies?.["next-intl"])return{isSetup:!0,reason:"next-intl is installed"}}return{isSetup:!1,reason:""}},so=async e=>{let r=ht.join(e,c.ROOT_LAYOUT),t=ht.join(e,"src/app/[locale]/layout.tsx");if(!m(r)&&!m(t))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx exists.")};w();P();import ya from"node:fs/promises";import re from"node:path";var ao=async e=>{let r=re.join(e,c.NEXT_CONFIG);if(m(r)){let t=await u(r);if(!t.includes("createNextIntlPlugin")){t=`import createNextIntlPlugin from 'next-intl/plugin';
711
722
  ${t}`;let n=/export default (.*?);/;n.test(t)?t=t.replace(n,`
712
723
  const withNextIntl = createNextIntlPlugin();
713
724
  export default withNextIntl($1);`):(t+=`
714
725
  const withNextIntl = createNextIntlPlugin();
715
726
  `,t+=`export default withNextIntl(nextConfig);
716
- `),await f(r,t)}}},so=async e=>{let r=te.join(e,c.TYPES_INDEX);if(m(r)){let t=await u(r);t.includes("./i18n")||(t+=`export * from './i18n';
717
- `,await f(r,t))}},ao=async e=>{let r=te.join(e,c.CONFIG_INDEX);if(m(r)){let t=await u(r);t.includes("./app-locales")||(t+=`export * from './app-locales';
718
- `,await f(r,t))}},co=async e=>{let r=te.join(e,"src/providers/RootProvider.tsx");if(m(r)){let t=await u(r),n="'use client';",i=t.includes(n);if(i&&(t=t.replace(n,"").trim()),t.includes("next-intl")||(t=`import { type AbstractIntlMessages, NextIntlClientProvider } from 'next-intl';
727
+ `),await f(r,t)}}},co=async e=>{let r=re.join(e,c.TYPES_INDEX);if(m(r)){let t=await u(r);t.includes("./i18n")||(t+=`export * from './i18n';
728
+ `,await f(r,t))}},po=async e=>{let r=re.join(e,c.CONFIG_INDEX);if(m(r)){let t=await u(r);t.includes("./app-locales")||(t+=`export * from './app-locales';
729
+ `,await f(r,t))}},lo=async e=>{let r=re.join(e,"src/providers/RootProvider.tsx");if(m(r)){let t=await u(r),n="'use client';",o=t.includes(n);if(o&&(t=t.replace(n,"").trim()),t.includes("next-intl")||(t=`import { type AbstractIntlMessages, NextIntlClientProvider } from 'next-intl';
719
730
  import type { SupportedLocale } from '@/types/i18n';
720
- `+t),i&&(t=`${n}
721
- ${t}`),!t.includes("locale: SupportedLocale")){let o=` locale: SupportedLocale;
731
+ `+t),o&&(t=`${n}
732
+ ${t}`),!t.includes("locale: SupportedLocale")){let i=` locale: SupportedLocale;
722
733
  messages: AbstractIntlMessages;
723
- timeZone: string;`,s=/(type\s+RootProviderProps\s*=\s*\{)([\s\S]*?)(\};?)/,a=/export const RootProvider = \(\{([\s\S]*?)\}: \{([\s\S]*?)\}\) => \{/;if(s.test(t))t=t.replace(s,(p,d,g,h)=>{let y=g.replace(/\s+$/,"");return`${d}${y}
724
- ${o}
734
+ timeZone: string;`,s=/(type\s+RootProviderProps\s*=\s*\{)([\s\S]*?)(\};?)/,a=/export const RootProvider = \(\{([\s\S]*?)\}: \{([\s\S]*?)\}\) => \{/;if(s.test(t))t=t.replace(s,(p,d,g,h)=>{let x=g.replace(/\s+$/,"");return`${d}${x}
735
+ ${i}
725
736
  ${h}`}),t=t.replace(/export const RootProvider = \(\{([\s\S]*?)\}:\s*RootProviderProps\)/,(p,d)=>{let g=d.trim().replace(/,$/,"");return`export const RootProvider = ({ ${g?`${g}, `:""}locale, messages, timeZone }: RootProviderProps)`});else{let p=t.match(a);if(p){let d=p[1].trim().replace(/,$/,""),g=p[2].trim().replace(/;$/,""),h=`
726
737
  ${d?`${d},
727
738
  `:""}locale,
728
739
  messages,
729
- timeZone,`,y=`
740
+ timeZone,`,x=`
730
741
  ${g?`${g};
731
742
  `:""}locale: SupportedLocale;
732
743
  messages: AbstractIntlMessages;
733
744
  timeZone: string;`;t=t.replace(p[0],`export const RootProvider = ({${h}
734
- }: {${y}
735
- }) => {`)}}}if(!t.includes("<NextIntlClientProvider")){let o=t.match(/return\s*(?:\(\s*)?([\s\S]*?)(?:\s*\))?;/);if(o){let s=o[1],a=`<NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>
745
+ }: {${x}
746
+ }) => {`)}}}if(!t.includes("<NextIntlClientProvider")){let i=t.match(/return\s*(?:\(\s*)?([\s\S]*?)(?:\s*\))?;/);if(i){let s=i[1],a=`<NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>
736
747
  {children}
737
- </NextIntlClientProvider>`;if(s.includes("{children}")){let p=s.replace("{children}",a);t=t.replace(o[0],`return (
748
+ </NextIntlClientProvider>`;if(s.includes("{children}")){let p=s.replace("{children}",a);t=t.replace(i[0],`return (
738
749
  ${p}
739
- );`)}else t=t.replace(o[0],`return (
750
+ );`)}else t=t.replace(i[0],`return (
740
751
  <NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>
741
752
  ${s}
742
753
  </NextIntlClientProvider>
743
- );`)}}await f(r,t)}},po=async e=>{let r=te.join(e,c.ROOT_LAYOUT),t=te.join(e,c.ROOT_PAGE),n=te.join(e,"src/app/[locale]");if(await pa.mkdir(n,{recursive:!0}),m(r)){let i=te.join(n,"layout.tsx"),o=await u(r);if(o.includes("next-intl")||(o=`import { routing } from '@/i18n/routing';
754
+ );`)}}await f(r,t)}},mo=async e=>{let r=re.join(e,c.ROOT_LAYOUT),t=re.join(e,c.ROOT_PAGE),n=re.join(e,"src/app/[locale]");if(await ya.mkdir(n,{recursive:!0}),m(r)){let o=re.join(n,"layout.tsx"),i=await u(r);if(i.includes("next-intl")||(i=`import { routing } from '@/i18n/routing';
744
755
  import { hasLocale } from 'next-intl';
745
756
  import { notFound } from 'next/navigation';
746
757
  import { getMessages, getTimeZone, setRequestLocale } from 'next-intl/server';
747
- ${o}`),!o.includes("generateStaticParams")){let p=o.indexOf("};",o.indexOf("export const metadata"));if(p!==-1){let d=p+2;o=o.slice(0,d)+`
758
+ import { getLocaleDirection } from '@/lib/config/app-locales';
759
+ ${i}`),!i.includes("generateStaticParams")){let p=i.indexOf("};",i.indexOf("export const metadata"));if(p!==-1){let d=p+2;i=i.slice(0,d)+`
748
760
 
749
761
  export function generateStaticParams() {
750
762
  return routing.locales.map((locale) => ({ locale }));
751
- }`+o.slice(d)}}o=o.replace(/Readonly<\{\s*children:\s*React\.ReactNode;\s*}>/,`Readonly<{
763
+ }`+i.slice(d)}}i=i.replace(/Readonly<\{\s*children:\s*React\.ReactNode;\s*}>/,`Readonly<{
752
764
  children: React.ReactNode;
753
765
  params: Promise<{ locale: string }>;
754
- }>`);let s=/export default (async )?function RootLayout\(\{\s*children,?\s*\}\s*:/,a=o.match(s);if(a){a[1]||(o=o.replace("export default function","export default async function")),o=o.replace(/export default (async )?function RootLayout\(\{\s*children,?\s*\}\s*:/,"export default async function RootLayout({ children, params }:");let d=/export default async function RootLayout[\s\S]*?\)\s*\{/,g=o.match(d);if(g&&g.index!==void 0){let h=g.index+g[0].length-1;o=o.slice(0,h+1)+`
766
+ }>`);let s=/export default (async )?function RootLayout\(\{\s*children,?\s*\}\s*:/,a=i.match(s);if(a){a[1]||(i=i.replace("export default function","export default async function")),i=i.replace(/export default (async )?function RootLayout\(\{\s*children,?\s*\}\s*:/,"export default async function RootLayout({ children, params }:");let d=/export default async function RootLayout[\s\S]*?\)\s*\{/,g=i.match(d);if(g&&g.index!==void 0){let h=g.index+g[0].length-1;i=i.slice(0,h+1)+`
755
767
  const { locale } = await params;
756
768
 
757
769
  if (!hasLocale(routing.locales, locale)) {
@@ -761,31 +773,31 @@ export function generateStaticParams() {
761
773
  setRequestLocale(locale);
762
774
 
763
775
  const [messages, timeZone] = await Promise.all([getMessages(), getTimeZone()]);
764
- `+o.slice(h+1)}o=o.replace(/<RootProvider>/,"<RootProvider locale={locale} messages={messages} timeZone={timeZone}>"),o=o.replace(/<html lang="en"/,"<html lang={locale}")}await f(i,o),await T(r)}if(m(t)){let i=te.join(n,"page.tsx"),o=await u(t);o.includes("next-intl")||(o=`import { SupportedLocale } from '@/types/i18n';
776
+ `+i.slice(h+1)}i=i.replace(/<RootProvider>/,"<RootProvider locale={locale} messages={messages} timeZone={timeZone}>"),i=i.replace(/<html lang="en"/,"<html lang={locale} dir={getLocaleDirection(locale)}")}await f(o,i),await T(r)}if(m(t)){let o=re.join(n,"page.tsx"),i=await u(t);i.includes("next-intl")||(i=`import { SupportedLocale } from '@/types/i18n';
765
777
  import { setRequestLocale } from 'next-intl/server';
766
- ${o}`),o=o.replace(/export default function Home\(\)/,`type Props = {
778
+ ${i}`),i=i.replace(/export default function Home\(\)/,`type Props = {
767
779
  params: Promise<{ locale: string }>;
768
780
  };
769
781
 
770
- export default async function Home(props: Props)`);let s=o.indexOf("export default async function Home(props: Props) {");if(s!==-1){let a=`
782
+ export default async function Home(props: Props)`);let s=i.indexOf("export default async function Home(props: Props) {");if(s!==-1){let a=`
771
783
  const locale = (await props.params).locale as SupportedLocale;
772
784
  setRequestLocale(locale);
773
- `,p=o.indexOf("{",s);o=o.slice(0,p+1)+a+o.slice(p+1)}await f(i,o),await T(t)}};var ze=async e=>{let r=R("Setting up Internationalization (next-intl)..."),t=Qt.join(e,".next-maker-temp-i18n");try{let{isSetup:n,reason:i}=await no(e);if(n){r.fail(`i18n is already set up (${i}).`);return}await oo(e),await to(t,r),r.text="Copying i18n files...",await ro(e,t),r.text="Configuring project structure...",await io(e),await so(e),await ao(e),await co(e),r.text="Migrating to [locale] structure...",await po(e),r.text="Installing dependencies...",await z(e,"next-intl");let o=Qt.join(e,c.VITEST_CONFIG);if(m(o)){let a=JSON.parse(await u(Qt.join(e,c.PACKAGE_JSON))),p={...a.dependencies,...a.devDependencies},d=!!(p["@reduxjs/toolkit"]&&p["react-redux"]);await re(e,{redux:d,i18n:!0})}r.text="Formatting code...";let s=await O(e);await U(e,s,"lint:fix"),r.succeed(la.green("Internationalization setup successfully!"))}catch(n){throw r.fail("Failed to setup Internationalization."),n}finally{await S(t)}};var lo={id:"i18n",name:"Internationalization",description:"next-intl with [locale] routing, RootProvider, and proxy.ts",detect:async e=>{let{detectProjectSetup:r}=await Promise.resolve().then(()=>(L(),Ne));return(await r(e)).hasI18n},files:[{path:"src/i18n",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds your translation JSON files \u2014 copy any you want to keep, then delete by hand"},{path:"src/proxy.ts",generated:!0},{path:"src/app/[locale]",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds every page you generated under the locale segment \u2014 move them to src/app/ before deleting"}],packages:[{name:"next-intl",kind:"dependency"}],scripts:[],injections:[{file:"next.config.ts",description:"createNextIntlPlugin wrap in next.config.ts",presence:/next-intl\/plugin/,removePattern:kn},{file:"src/providers/RootProvider.tsx",description:"<NextIntlClientProvider> wrap",presence:/NextIntlClientProvider/,removePattern:Se("NextIntlClientProvider")}],apply:ze};w();P();import ua from"node:path";w();import ma from"node:path";import da from"picocolors";P();var Ve=async e=>{let r=R("Enabling React Compiler...");try{let t=ma.join(e,c.NEXT_CONFIG);if(!m(t))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await u(t);if(n.includes("reactCompiler:")){r.fail("React Compiler is already configured in next.config.ts.");return}let i=/(const\s+nextConfig\s*:\s*NextConfig\s*=\s*\{)/;if(!i.test(n))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");n=n.replace(i,`$1
774
- reactCompiler: true,`),await f(t,n),r.text="Installing babel-plugin-react-compiler...",await ot(e,"babel-plugin-react-compiler"),r.succeed(da.green("React Compiler enabled."))}catch(t){throw r.fail("Failed to enable React Compiler."),t}};var mo={id:"react-compiler",name:"React Compiler",description:"reactCompiler: true in next.config.ts + babel-plugin-react-compiler",detect:async e=>{let r=ua.join(e,c.NEXT_CONFIG);return m(r)?/reactCompiler\s*:\s*true/.test(await u(r)):!1},files:[],packages:[{name:"babel-plugin-react-compiler",kind:"devDependency"}],scripts:[],injections:[{file:c.NEXT_CONFIG,description:"`reactCompiler: true` flag",presence:/reactCompiler\s*:\s*true/,removePattern:/\n\s*reactCompiler:\s*true,?/}],apply:Ve};w();import rr from"node:path";import ga from"picocolors";P();w();P();import uo from"node:fs/promises";import he from"node:path";import fa from"degit";var fo=async(e,r)=>{r.text="Fetching assets from starter repo...",await fa("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},go=async(e,r)=>{let t=he.join(r,"src/providers/StoreProvider.tsx"),n=he.join(e,c.STORE_PROVIDER);await _(t,n);let i=he.join(r,"src/store"),o=he.join(e,c.STORE);await uo.cp(i,o,{recursive:!0})},ho=async(e,r)=>{let t=he.join(r,"src/features/counter"),n=he.join(e,c.COUNTER_FEATURE);await uo.cp(t,n,{recursive:!0});let i=he.join(n,"components/Counter.tsx");if(await m(i)){let o=await u(i);o=o.replace(/import \{ useTranslations \} from 'next-intl';\n?/,""),o=o.replace(/const t = useTranslations\('Count'\);\n?/,""),o=o.replace(/\{t\('currentCount', \{ count: value \}\)\}/g,"Current Count: {value}"),o=o.replace(/\{t\('increment'\)\}/g,"Increment"),o=o.replace(/\{t\('decrement'\)\}/g,"Decrement"),o=o.replace(/\{t\('reset'\)\}/g,"Reset"),await f(i,o)}};w();P();import er from"node:path";var xo=async e=>{let r=er.join(e,c.STORE),t=er.join(e,"package.json");if(m(r))return{isSetup:!0,reason:"src/store directory exists"};if(m(t)){let n=JSON.parse(await u(t));if(n.dependencies?.["@reduxjs/toolkit"]||n.devDependencies?.["@reduxjs/toolkit"])return{isSetup:!0,reason:"@reduxjs/toolkit is installed"}}return{isSetup:!1,reason:""}},yo=async e=>{let r=er.join(e,c.PROVIDERS_INDEX);if(!await dt(e)||!m(r))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx (or src/app/[locale]/layout.tsx) and src/providers/index.ts exist.")};w();P();import tr from"node:path";var Po=async e=>{},vo=async e=>{let r=tr.join(e,"src/providers/RootProvider.tsx");if(!m(r))return;let t=await u(r),n="'use client';",i=t.includes(n);if(i&&(t=t.replace(n,"").trim()),t.includes("from '@/store'")||(t=`import type { AppState } from '@/store';
785
+ `,p=i.indexOf("{",s);i=i.slice(0,p+1)+a+i.slice(p+1)}await f(o,i),await T(t)}};var ze=async e=>{let r=R("Setting up Internationalization (next-intl)..."),t=er.join(e,".next-maker-temp-i18n");try{let{isSetup:n,reason:o}=await io(e);if(n){r.fail(`i18n is already set up (${o}).`);return}await so(e),await no(t,r),r.text="Copying i18n files...",await oo(e,t),r.text="Configuring project structure...",await ao(e),await co(e),await po(e),await lo(e),r.text="Migrating to [locale] structure...",await mo(e),r.text="Installing dependencies...",await z(e,"next-intl");let i=er.join(e,c.VITEST_CONFIG);if(m(i)){let a=JSON.parse(await u(er.join(e,c.PACKAGE_JSON))),p={...a.dependencies,...a.devDependencies},d=!!(p["@reduxjs/toolkit"]&&p["react-redux"]);await ne(e,{redux:d,i18n:!0})}r.text="Formatting code...";let s=await O(e);await U(e,s,"lint:fix"),r.succeed(xa.green("Internationalization setup successfully!"))}catch(n){throw r.fail("Failed to setup Internationalization."),n}finally{await S(t)}};var uo={id:"i18n",name:"Internationalization",description:"next-intl with [locale] routing, RootProvider, and proxy.ts",detect:async e=>{let{detectProjectSetup:r}=await Promise.resolve().then(()=>(L(),Ne));return(await r(e)).hasI18n},files:[{path:"src/i18n",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds your translation JSON files \u2014 copy any you want to keep, then delete by hand"},{path:"src/proxy.ts",generated:!0},{path:"src/app/[locale]",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds every page you generated under the locale segment \u2014 move them to src/app/ before deleting"}],packages:[{name:"next-intl",kind:"dependency"}],scripts:[],injections:[{file:"next.config.ts",description:"createNextIntlPlugin wrap in next.config.ts",presence:/next-intl\/plugin/,removePattern:_n},{file:"src/providers/RootProvider.tsx",description:"<NextIntlClientProvider> wrap",presence:/NextIntlClientProvider/,removePattern:Se("NextIntlClientProvider")}],apply:ze};w();P();import Sa from"node:path";w();import Pa from"node:path";import va from"picocolors";P();var Ve=async e=>{let r=R("Enabling React Compiler...");try{let t=Pa.join(e,c.NEXT_CONFIG);if(!m(t))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await u(t);if(n.includes("reactCompiler:")){r.fail("React Compiler is already configured in next.config.ts.");return}let o=/(const\s+nextConfig\s*:\s*NextConfig\s*=\s*\{)/;if(!o.test(n))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");n=n.replace(o,`$1
786
+ reactCompiler: true,`),await f(t,n),r.text="Installing babel-plugin-react-compiler...",await ot(e,"babel-plugin-react-compiler"),r.succeed(va.green("React Compiler enabled."))}catch(t){throw r.fail("Failed to enable React Compiler."),t}};var fo={id:"react-compiler",name:"React Compiler",description:"reactCompiler: true in next.config.ts + babel-plugin-react-compiler",detect:async e=>{let r=Sa.join(e,c.NEXT_CONFIG);return m(r)?/reactCompiler\s*:\s*true/.test(await u(r)):!1},files:[],packages:[{name:"babel-plugin-react-compiler",kind:"devDependency"}],scripts:[],injections:[{file:c.NEXT_CONFIG,description:"`reactCompiler: true` flag",presence:/reactCompiler\s*:\s*true/,removePattern:/\n\s*reactCompiler:\s*true,?/}],apply:Ve};w();import nr from"node:path";import Ca from"picocolors";P();w();P();import go from"node:fs/promises";import he from"node:path";import wa from"degit";var ho=async(e,r)=>{r.text="Fetching assets from starter repo...",await wa("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},yo=async(e,r)=>{let t=he.join(r,"src/providers/StoreProvider.tsx"),n=he.join(e,c.STORE_PROVIDER);await _(t,n);let o=he.join(r,"src/store"),i=he.join(e,c.STORE);await go.cp(o,i,{recursive:!0})},xo=async(e,r)=>{let t=he.join(r,"src/features/counter"),n=he.join(e,c.COUNTER_FEATURE);await go.cp(t,n,{recursive:!0});let o=he.join(n,"components/Counter.tsx");if(await m(o)){let i=await u(o);i=i.replace(/import \{ useTranslations \} from 'next-intl';\n?/,""),i=i.replace(/const t = useTranslations\('Count'\);\n?/,""),i=i.replace(/\{t\('currentCount', \{ count: value \}\)\}/g,"Current Count: {value}"),i=i.replace(/\{t\('increment'\)\}/g,"Increment"),i=i.replace(/\{t\('decrement'\)\}/g,"Decrement"),i=i.replace(/\{t\('reset'\)\}/g,"Reset"),await f(o,i)}};w();P();import tr from"node:path";var Po=async e=>{let r=tr.join(e,c.STORE),t=tr.join(e,"package.json");if(m(r))return{isSetup:!0,reason:"src/store directory exists"};if(m(t)){let n=JSON.parse(await u(t));if(n.dependencies?.["@reduxjs/toolkit"]||n.devDependencies?.["@reduxjs/toolkit"])return{isSetup:!0,reason:"@reduxjs/toolkit is installed"}}return{isSetup:!1,reason:""}},vo=async e=>{let r=tr.join(e,c.PROVIDERS_INDEX);if(!await dt(e)||!m(r))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx (or src/app/[locale]/layout.tsx) and src/providers/index.ts exist.")};w();P();import rr from"node:path";var So=async e=>{},wo=async e=>{let r=rr.join(e,"src/providers/RootProvider.tsx");if(!m(r))return;let t=await u(r),n="'use client';",o=t.includes(n);if(o&&(t=t.replace(n,"").trim()),t.includes("from '@/store'")||(t=`import type { AppState } from '@/store';
775
787
  ${t}`),t.includes("from './StoreProvider'")||(t=`${t.includes("from '@/store'"),""}import { StoreProvider } from './StoreProvider';
776
- ${t}`),i&&(t=`${n}
788
+ ${t}`),o&&(t=`${n}
777
789
  ${t}`),t.includes("preloadedState")||(t=t.replace(/children:\s*React\.ReactNode;/,`children: React.ReactNode;
778
- preloadedState?: Partial<AppState>;`),t=t.replace(/export const RootProvider = \(\{([\s\S]*?)\}:/,(o,s)=>`export const RootProvider = ({${s}, preloadedState }:`),t=t.replace(/,\s*,/g,",").replace(/\{\s*,/g,"{ ").replace(/,\s*\}/g," }")),!t.includes("<StoreProvider")){let o=t.match(/return\s*\(\s*([\s\S]*?)\s*\);/);if(o){let s=o[1];t=t.replace(o[0],`return (
790
+ preloadedState?: Partial<AppState>;`),t=t.replace(/export const RootProvider = \(\{([\s\S]*?)\}:/,(i,s)=>`export const RootProvider = ({${s}, preloadedState }:`),t=t.replace(/,\s*,/g,",").replace(/\{\s*,/g,"{ ").replace(/,\s*\}/g," }")),!t.includes("<StoreProvider")){let i=t.match(/return\s*\(\s*([\s\S]*?)\s*\);/);if(i){let s=i[1];t=t.replace(i[0],`return (
779
791
  <StoreProvider preloadedState={preloadedState}>
780
792
  ${s}
781
793
  </StoreProvider>
782
- );`)}}await f(r,t)},So=async e=>{let r=[tr.join(e,c.ROOT_PAGE),tr.join(e,"src/app/[locale]/page.tsx")],t="";for(let i of r)if(m(i)){t=i;break}if(!t)return;let n=await u(t);if(n.includes("Counter")||(n=`import { Counter } from '@/features/counter';
783
- ${n}`),!n.includes("<Counter />")){let i=n.lastIndexOf("</div>"),o=n.lastIndexOf("</main>"),s=o!==-1?o:i;s!==-1&&(n=n.slice(0,s)+`
794
+ );`)}}await f(r,t)},Co=async e=>{let r=[rr.join(e,c.ROOT_PAGE),rr.join(e,"src/app/[locale]/page.tsx")],t="";for(let o of r)if(m(o)){t=o;break}if(!t)return;let n=await u(t);if(n.includes("Counter")||(n=`import { Counter } from '@/features/counter';
795
+ ${n}`),!n.includes("<Counter />")){let o=n.lastIndexOf("</div>"),i=n.lastIndexOf("</main>"),s=i!==-1?i:o;s!==-1&&(n=n.slice(0,s)+`
784
796
  <div className="mt-8">
785
797
  <h2 className="mb-4 text-2xl font-bold">Redux Counter</h2>
786
798
  <Counter />
787
799
  </div>
788
- `+n.slice(s),await f(t,n))}};var Je=async e=>{let r=R("Setting up Redux Toolkit..."),t=rr.join(e,".next-maker-temp-redux");try{let{isSetup:n,reason:i}=await xo(e);if(n){r.fail(`Redux is already set up (${i}).`);return}await yo(e),await fo(t,r),r.text="Copying Redux files...",await go(e,t),r.text="Creating Counter feature...",await ho(e,t),r.text="Updating providers and pages...",await Po(e),await vo(e),await So(e),r.text="Installing dependencies...",await z(e,"@reduxjs/toolkit"),await z(e,"react-redux"),await z(e,"redux-persist"),await z(e,"react-secure-storage");let o=rr.join(e,c.VITEST_CONFIG);if(m(o)){let a=JSON.parse(await u(rr.join(e,c.PACKAGE_JSON))),p={...a.dependencies,...a.devDependencies};await re(e,{redux:!0,i18n:!!p["next-intl"]})}r.text="Formatting code...";let s=await O(e);await U(e,s,"lint:fix"),r.succeed(ga.green("Redux Toolkit setup successfully!"))}catch(n){throw r.fail("Failed to setup Redux Toolkit."),n}finally{await S(t)}};var wo={id:"redux",name:"Redux Toolkit",description:"Redux Toolkit + react-redux + redux-persist + StoreProvider",detect:async e=>{let{detectProjectSetup:r}=await Promise.resolve().then(()=>(L(),Ne));return(await r(e)).hasRedux},files:[{path:"src/store",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds the rootReducer and any slices you registered \u2014 review before deleting"},{path:"src/providers/StoreProvider.tsx",generated:!0}],packages:[{name:"@reduxjs/toolkit",kind:"dependency"},{name:"react-redux",kind:"dependency"},{name:"redux-persist",kind:"dependency"}],scripts:[],injections:[{file:"src/providers/RootProvider.tsx",description:"<StoreProvider> wrap in RootProvider",presence:/<StoreProvider/,removePattern:Se("StoreProvider")}],apply:Je};w();P();import va from"node:path";w();import ya from"node:path";import Pa from"picocolors";P();var To=[{key:"X-DNS-Prefetch-Control",value:"on"},{key:"Strict-Transport-Security",value:"max-age=63072000; includeSubDomains; preload"},{key:"X-XSS-Protection",value:"1; mode=block"},{key:"X-Frame-Options",value:"SAMEORIGIN"},{key:"X-Content-Type-Options",value:"nosniff"},{key:"Referrer-Policy",value:"origin-when-cross-origin"}],Co=/(const\s+nextConfig\s*:\s*NextConfig\s*=\s*\{)/,ha=/^\s+headers\s*:/m,xa=e=>`
800
+ `+n.slice(s),await f(t,n))}};var Je=async e=>{let r=R("Setting up Redux Toolkit..."),t=nr.join(e,".next-maker-temp-redux");try{let{isSetup:n,reason:o}=await Po(e);if(n){r.fail(`Redux is already set up (${o}).`);return}await vo(e),await ho(t,r),r.text="Copying Redux files...",await yo(e,t),r.text="Creating Counter feature...",await xo(e,t),r.text="Updating providers and pages...",await So(e),await wo(e),await Co(e),r.text="Installing dependencies...",await z(e,"@reduxjs/toolkit"),await z(e,"react-redux"),await z(e,"redux-persist"),await z(e,"react-secure-storage");let i=nr.join(e,c.VITEST_CONFIG);if(m(i)){let a=JSON.parse(await u(nr.join(e,c.PACKAGE_JSON))),p={...a.dependencies,...a.devDependencies};await ne(e,{redux:!0,i18n:!!p["next-intl"]})}r.text="Formatting code...";let s=await O(e);await U(e,s,"lint:fix"),r.succeed(Ca.green("Redux Toolkit setup successfully!"))}catch(n){throw r.fail("Failed to setup Redux Toolkit."),n}finally{await S(t)}};var To={id:"redux",name:"Redux Toolkit",description:"Redux Toolkit + react-redux + redux-persist + StoreProvider",detect:async e=>{let{detectProjectSetup:r}=await Promise.resolve().then(()=>(L(),Ne));return(await r(e)).hasRedux},files:[{path:"src/store",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds the rootReducer and any slices you registered \u2014 review before deleting"},{path:"src/providers/StoreProvider.tsx",generated:!0}],packages:[{name:"@reduxjs/toolkit",kind:"dependency"},{name:"react-redux",kind:"dependency"},{name:"redux-persist",kind:"dependency"}],scripts:[],injections:[{file:"src/providers/RootProvider.tsx",description:"<StoreProvider> wrap in RootProvider",presence:/<StoreProvider/,removePattern:Se("StoreProvider")}],apply:Je};w();P();import ba from"node:path";w();import Ra from"node:path";import $a from"picocolors";P();var Ro=[{key:"X-DNS-Prefetch-Control",value:"on"},{key:"Strict-Transport-Security",value:"max-age=63072000; includeSubDomains; preload"},{key:"X-XSS-Protection",value:"1; mode=block"},{key:"X-Frame-Options",value:"SAMEORIGIN"},{key:"X-Content-Type-Options",value:"nosniff"},{key:"Referrer-Policy",value:"origin-when-cross-origin"}],Eo=/(const\s+nextConfig\s*:\s*NextConfig\s*=\s*\{)/,Ta=/^\s+headers\s*:/m,Ea=e=>`
789
801
  headers: async () => {
790
802
  return [
791
803
  {
@@ -796,9 +808,11 @@ ${e.map(({key:t,value:n})=>` { key: '${t}', value: '${n}' },`).join(`
796
808
  ],
797
809
  },
798
810
  ];
799
- },`,we=e=>ha.test(e),nr=(e,r=To)=>{if(we(e))return e;if(!Co.test(e))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");return e.replace(Co,`$1${xa(r)}`)};var Be=async e=>{let r=R("Adding security headers to next.config.ts...");try{let t=ya.join(e,c.NEXT_CONFIG);if(!m(t))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await u(t);if(we(n)){r.succeed("Security headers already configured.");return}let i=nr(n);await f(t,i),r.succeed(Pa.green("Security headers added."))}catch(t){throw r.fail("Failed to add security headers."),t}};var Eo={id:"security-headers",name:"Security Headers",description:"Hardened HTTP headers in next.config.ts",detect:async e=>{let r=va.join(e,c.NEXT_CONFIG);return m(r)?we(await u(r)):!1},files:[],packages:[],scripts:[],injections:[{file:c.NEXT_CONFIG,description:"headers() function in next.config.ts",presence:/^\s+headers\s*:/m,removePattern:/\s+headers:\s*async\s*\(\)\s*=>\s*\{[\s\S]*?\n\s{0,2}\},/m}],apply:Be};w();P();import Ea from"node:path";w();import Sa from"node:fs/promises";import ae from"node:path";import wa from"degit";import Ca from"picocolors";P();var Ta=["vitest","jsdom","@vitejs/plugin-react","@testing-library/dom","@testing-library/jest-dom","@testing-library/react","@testing-library/user-event"],Xe=async e=>{let r=R("Setting up testing (Vitest + RTL)..."),t=ae.join(e,".next-maker-temp-tests");try{let n=ae.join(e,c.VITEST_CONFIG);if(m(n)){r.fail("Testing is already set up (vitest.config.ts exists).");return}r.text="Fetching assets from starter repo...",await wa("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(t),await _(ae.join(t,c.VITEST_CONFIG),ae.join(e,c.VITEST_CONFIG));let o=ae.join(e,c.TEST_DIR);await Sa.mkdir(o,{recursive:!0}),await _(ae.join(t,c.TEST_DIR,"setup.ts"),ae.join(o,"setup.ts"));let s=ae.join(e,c.PACKAGE_JSON),a=JSON.parse(await u(s)),p={...a.dependencies,...a.devDependencies},d=!!(p["@reduxjs/toolkit"]&&p["react-redux"]),g=!!p["next-intl"];await re(e,{redux:d,i18n:g}),await k(s,y=>(y.scripts=y.scripts??{},y.scripts.test=y.scripts.test??"vitest run",y.scripts["test:watch"]=y.scripts["test:watch"]??"vitest",y.scripts["test:coverage"]=y.scripts["test:coverage"]??"vitest run --coverage",typeof y.scripts.validate=="string"&&!/\byarn\s+test(?![:\w])/.test(y.scripts.validate)&&(y.scripts.validate=y.scripts.validate.replace(/(\byarn\s+check:deprecated\s*)(&&)/,"$1&& yarn test $2")),y)),r.text="Installing testing devDependencies...";let h=await O(e);await ue(e,h,Ta),r.text="Formatting code...",await U(e,h,"lint:fix"),r.succeed(Ca.green("Testing setup complete."))}catch(n){throw r.fail("Failed to set up testing."),n}finally{await S(t)}};var Ro={id:"tests",name:"Tests",description:"Vitest + React Testing Library + jsdom",detect:async e=>m(Ea.join(e,c.VITEST_CONFIG)),files:[{path:c.VITEST_CONFIG,generated:!0},{path:"test",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds setup.ts / test-utils.tsx and any helpers you added \u2014 review before deleting"}],packages:[{name:"vitest",kind:"devDependency"},{name:"jsdom",kind:"devDependency"},{name:"@vitejs/plugin-react",kind:"devDependency"},{name:"@testing-library/dom",kind:"devDependency"},{name:"@testing-library/jest-dom",kind:"devDependency"},{name:"@testing-library/react",kind:"devDependency"},{name:"@testing-library/user-event",kind:"devDependency"}],scripts:[{name:"test",expectedValue:"vitest run"},{name:"test:watch",expectedValue:"vitest"}],injections:[],apply:Xe};P();import Ia from"node:path";w();import $o from"node:path";import ba from"picocolors";P();var Ra={npm:"npm run",yarn:"yarn",pnpm:"pnpm",bun:"bun run"},$a=e=>{let r=Ra[e];return["ci:check","type-check","check:deprecated","test","build"].map(t=>`${r} ${t}`).join(" && ")},or=(e,r)=>{let t={...e.scripts??{}},n={...e.devDependencies??{}};return t["env:sync"]||(t["env:sync"]="tsx scripts/sync-env.ts"),t["check:deprecated"]||(t["check:deprecated"]="tsx scripts/check-deprecated.ts"),t["type-check"]||(t["type-check"]="tsc --noEmit"),t.validate||(t.validate=$a(r)),!n.tsx&&!e.dependencies?.hasOwnProperty("tsx")&&(n.tsx="*"),{...e,scripts:t,devDependencies:n}};var ir=`import * as fs from 'node:fs';
811
+ },`,we=e=>Ta.test(e),or=(e,r=Ro)=>{if(we(e))return e;if(!Eo.test(e))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");return e.replace(Eo,`$1${Ea(r)}`)};var Be=async e=>{let r=R("Adding security headers to next.config.ts...");try{let t=Ra.join(e,c.NEXT_CONFIG);if(!m(t))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await u(t);if(we(n)){r.succeed("Security headers already configured.");return}let o=or(n);await f(t,o),r.succeed($a.green("Security headers added."))}catch(t){throw r.fail("Failed to add security headers."),t}};var $o={id:"security-headers",name:"Security Headers",description:"Hardened HTTP headers in next.config.ts",detect:async e=>{let r=ba.join(e,c.NEXT_CONFIG);return m(r)?we(await u(r)):!1},files:[],packages:[],scripts:[],injections:[{file:c.NEXT_CONFIG,description:"headers() function in next.config.ts",presence:/^\s+headers\s*:/m,removePattern:/\s+headers:\s*async\s*\(\)\s*=>\s*\{[\s\S]*?\n\s{0,2}\},/m}],apply:Be};w();P();import Oa from"node:path";w();import Na from"node:fs/promises";import ae from"node:path";import Ia from"degit";import Aa from"picocolors";P();var ka=["vitest","jsdom","@vitejs/plugin-react","@testing-library/dom","@testing-library/jest-dom","@testing-library/react","@testing-library/user-event"],Xe=async e=>{let r=R("Setting up testing (Vitest + RTL)..."),t=ae.join(e,".next-maker-temp-tests");try{let n=ae.join(e,c.VITEST_CONFIG);if(m(n)){r.fail("Testing is already set up (vitest.config.ts exists).");return}r.text="Fetching assets from starter repo...",await Ia("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(t),await _(ae.join(t,c.VITEST_CONFIG),ae.join(e,c.VITEST_CONFIG));let i=ae.join(e,c.TEST_DIR);await Na.mkdir(i,{recursive:!0}),await _(ae.join(t,c.TEST_DIR,"setup.ts"),ae.join(i,"setup.ts"));let s=ae.join(e,c.PACKAGE_JSON),a=JSON.parse(await u(s)),p={...a.dependencies,...a.devDependencies},d=!!(p["@reduxjs/toolkit"]&&p["react-redux"]),g=!!p["next-intl"];await ne(e,{redux:d,i18n:g}),await k(s,x=>(x.scripts=x.scripts??{},x.scripts.test=x.scripts.test??"vitest run",x.scripts["test:watch"]=x.scripts["test:watch"]??"vitest",x.scripts["test:coverage"]=x.scripts["test:coverage"]??"vitest run --coverage",typeof x.scripts.validate=="string"&&!/\byarn\s+test(?![:\w])/.test(x.scripts.validate)&&(x.scripts.validate=x.scripts.validate.replace(/(\byarn\s+check:deprecated\s*)(&&)/,"$1&& yarn test $2")),x)),r.text="Installing testing devDependencies...";let h=await O(e);await ue(e,h,ka),r.text="Formatting code...",await U(e,h,"lint:fix"),r.succeed(Aa.green("Testing setup complete."))}catch(n){throw r.fail("Failed to set up testing."),n}finally{await S(t)}};var bo={id:"tests",name:"Tests",description:"Vitest + React Testing Library + jsdom",detect:async e=>m(Oa.join(e,c.VITEST_CONFIG)),files:[{path:c.VITEST_CONFIG,generated:!0},{path:"test",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds setup.ts / test-utils.tsx and any helpers you added \u2014 review before deleting"}],packages:[{name:"vitest",kind:"devDependency"},{name:"jsdom",kind:"devDependency"},{name:"@vitejs/plugin-react",kind:"devDependency"},{name:"@testing-library/dom",kind:"devDependency"},{name:"@testing-library/jest-dom",kind:"devDependency"},{name:"@testing-library/react",kind:"devDependency"},{name:"@testing-library/user-event",kind:"devDependency"}],scripts:[{name:"test",expectedValue:"vitest run"},{name:"test:watch",expectedValue:"vitest"}],injections:[],apply:Xe};P();import La from"node:path";w();import No from"node:path";import ja from"picocolors";P();var _a={npm:"npm run",yarn:"yarn",pnpm:"pnpm",bun:"bun run"},Fa=e=>{let r=_a[e];return["ci:check","type-check","check:deprecated","test","build"].map(t=>`${r} ${t}`).join(" && ")},ir=(e,r)=>{let t={...e.scripts??{}},n={...e.devDependencies??{}};return t["env:sync"]||(t["env:sync"]="tsx scripts/sync-env.ts"),t["check:deprecated"]||(t["check:deprecated"]="tsx scripts/check-deprecated.ts"),t["type-check"]||(t["type-check"]="tsc --noEmit"),t.validate||(t.validate=Fa(r)),!n.tsx&&!e.dependencies?.hasOwnProperty("tsx")&&(n.tsx="*"),{...e,scripts:t,devDependencies:n}};var sr=`import * as fs from 'node:fs';
800
812
  import * as path from 'node:path';
801
813
 
814
+ const checkOnly = process.argv.includes('--check');
815
+
802
816
  const envPath = path.join(process.cwd(), '.env');
803
817
  const examplePath = path.join(process.cwd(), '.env.example');
804
818
 
@@ -856,13 +870,19 @@ if (fs.existsSync(examplePath)) {
856
870
  currentExampleContent = fs.readFileSync(examplePath, 'utf-8');
857
871
  }
858
872
 
859
- if (currentExampleContent !== newExampleContent) {
860
- fs.writeFileSync(examplePath, newExampleContent);
861
- console.log('\u2705 Synchronized .env.example with .env');
862
- } else {
873
+ if (currentExampleContent === newExampleContent) {
863
874
  console.log('\u2728 .env.example is already up to date');
875
+ process.exit(0);
876
+ }
877
+
878
+ if (checkOnly) {
879
+ console.error('\u274C .env.example is out of sync with .env. Run "yarn env:sync" to update.');
880
+ process.exit(1);
864
881
  }
865
- `,sr=`/**
882
+
883
+ fs.writeFileSync(examplePath, newExampleContent);
884
+ console.log('\u2705 Synchronized .env.example with .env');
885
+ `,ar=`/**
866
886
  * Walks every identifier in the project and flags any whose resolved TypeScript
867
887
  * symbol carries a \`@deprecated\` JSDoc tag. Catches deprecated API usage that
868
888
  * \`tsc --noEmit\` does not surface (deprecations are "suggestion"-level, not
@@ -926,114 +946,114 @@ if (hits === 0) {
926
946
 
927
947
  console.log(\`\\n\${hits} deprecated symbol use(s) found.\`);
928
948
  process.exit(1);
929
- `;var Na=[{relative:"scripts/sync-env.ts",content:ir},{relative:"scripts/check-deprecated.ts",content:sr}],Ye=async e=>{let r=R("Adding validation scripts...");try{let t=!1;for(let{relative:o,content:s}of Na){let a=$o.join(e,o);m(a)||(await f(a,s),t=!0)}let n=await O(e),i=!1;await k($o.join(e,c.PACKAGE_JSON),o=>{let s=o.devDependencies?.tsx,a=or(o,n);return i=!s&&!!a.devDependencies?.tsx,a}),i&&(r.text="Installing tsx...",await ue(e,n,["tsx"])),r.succeed(ba.green(t?"Validation scripts added (env:sync, check:deprecated, validate).":"Validation scripts already present \u2014 refreshed package.json."))}catch(t){throw r.fail("Failed to add validation scripts."),t}};var bo=["scripts/sync-env.ts","scripts/check-deprecated.ts"],No={id:"validate-scripts",name:"Validation Scripts",description:"sync-env, check-deprecated, and the validate chain",detect:async e=>bo.every(r=>m(Ia.join(e,r))),files:bo.map(e=>({path:e,generated:!0})),packages:[{name:"tsx",kind:"devDependency"}],scripts:[{name:"env:sync",expectedValue:"tsx scripts/sync-env.ts"},{name:"check:deprecated",expectedValue:"tsx scripts/check-deprecated.ts"},{name:"type-check",expectedValue:"tsc --noEmit"},{name:"validate"}],injections:[],apply:Ye};w();P();import Ce from"node:path";var Io=async e=>{let r=Ce.join(e,c.PACKAGE_JSON);return m(r)?JSON.parse(await u(r)):null},Aa=async(e,r)=>{let t=Ce.join(e,c.PACKAGE_JSON);await f(t,`${JSON.stringify(r,null,2)}
930
- `)},Ao=(e,r)=>(r==="dependency"?e.dependencies:e.devDependencies)??{},Ke=async(e,r)=>{let t=await e.detect(r),n=[];if(!t)return{manifest:e,installed:!1,drift:[]};for(let o of e.files)o.required!==!1&&(m(Ce.join(r,o.path))||n.push({kind:"missingFile",file:o.path}));let i=await Io(r);if(i){for(let s of e.packages)Ao(i,s.kind)[s.name]||n.push({kind:"missingPackage",name:s.name,depKind:s.kind});let o=i.scripts??{};for(let s of e.scripts){let a=o[s.name];a?s.expectedValue&&a!==s.expectedValue&&n.push({kind:"mismatchedScript",name:s.name,expected:s.expectedValue,actual:a}):n.push({kind:"missingScript",name:s.name})}}for(let o of e.injections){let s=Ce.join(r,o.file);if(!m(s)){n.push({kind:"missingInjection",file:o.file,description:o.description});continue}let a=await u(s);o.presence.test(a)||n.push({kind:"missingInjection",file:o.file,description:o.description})}return{manifest:e,installed:t,drift:n}},xt=async(e,r,t={})=>{let n=t.dryRun??!1,i={filesRemoved:[],packagesUninstalled:[],scriptsRemoved:[],blocksStripped:[],manualCleanup:[]};for(let a of e.injections){let p=Ce.join(r,a.file);if(!m(p))continue;if(!a.removePattern){i.manualCleanup.push({file:a.file,description:a.description});continue}let d=await u(p);if(!a.presence.test(d))continue;let g;if(typeof a.removePattern=="function"){let h=a.removePattern(d);if(h===null){i.manualCleanup.push({file:a.file,description:a.description});continue}g=h}else g=d.replace(a.removePattern,"");g!==d?(n||await f(p,g),i.blocksStripped.push({file:a.file,description:a.description})):i.manualCleanup.push({file:a.file,description:a.description})}let{rm:o}=await import("node:fs/promises");for(let a of e.files){if(!a.generated)continue;let p=Ce.join(r,a.path);if(m(p)){if(a.containsUserContent){let d=a.removeHint?`${a.path} \u2014 ${a.removeHint}`:`${a.path} (may contain user-authored files; review before deleting)`;i.manualCleanup.push({file:a.path,description:d});continue}n||await o(p,{recursive:!0,force:!0}),i.filesRemoved.push(a.path)}}let s=await Io(r);if(s){let a=!1;if(s.scripts)for(let p of e.scripts)s.scripts[p.name]&&(n||delete s.scripts[p.name],i.scriptsRemoved.push(p.name),a=!0);for(let p of e.packages)Ao(s,p.kind)[p.name]&&i.packagesUninstalled.push(p.name);a&&!n&&await Aa(r,s)}if(!n&&i.packagesUninstalled.length>0){let a=await O(r);await Ct(r,a,i.packagesUninstalled)}return i};var xe=[Eo,No,jn,mo,_n,Ro,Xn,eo,wo,lo],ko=e=>xe.find(r=>r.id===e);var ka=e=>{switch(e.kind){case"missingFile":return`missing file: ${e.file}`;case"missingPackage":return`missing ${e.depKind==="dependency"?"dep":"devDep"}: ${e.name}`;case"missingScript":return`missing script: ${e.name}`;case"mismatchedScript":return`script "${e.name}" expected ${j.dim(e.expected)} but got ${j.dim(e.actual)}`;case"missingInjection":return`missing block in ${e.file}: ${e.description}`}},Oa=e=>{let r=e.filter(n=>n.installed),t=r.filter(n=>n.drift.length>0);return{installedCount:r.length,driftedCount:t.length,cleanCount:r.length-t.length,driftedResults:t}},Oo=e=>{e.command("doctor").description("Diagnose drift between the project and known feature manifests").option("--fix","Re-apply manifests that report drift (idempotent)").option("--feature <id>","Only check this manifest id (e.g. redux, security-headers)").option("--json","Print machine-readable JSON instead of the human report").action(async r=>{try{let t=process.cwd(),n=r.feature?xe.filter(s=>s.id===r.feature):xe;if(r.feature&&n.length===0)throw new Error(`Unknown feature "${r.feature}". Valid: ${xe.map(s=>s.id).join(", ")}.`);let i=[];for(let s of n)i.push(await Ke(s,t));r.json&&(l(JSON.stringify(i.map(s=>({id:s.manifest.id,name:s.manifest.name,installed:s.installed,drift:s.drift})),null,2)),process.exit(i.some(s=>s.drift.length>0)?1:0)),l(j.cyan(`
949
+ `;var Da=[{relative:"scripts/sync-env.ts",content:sr},{relative:"scripts/check-deprecated.ts",content:ar}],Ye=async e=>{let r=R("Adding validation scripts...");try{let t=!1;for(let{relative:i,content:s}of Da){let a=No.join(e,i);m(a)||(await f(a,s),t=!0)}let n=await O(e),o=!1;await k(No.join(e,c.PACKAGE_JSON),i=>{let s=i.devDependencies?.tsx,a=ir(i,n);return o=!s&&!!a.devDependencies?.tsx,a}),o&&(r.text="Installing tsx...",await ue(e,n,["tsx"])),r.succeed(ja.green(t?"Validation scripts added (env:sync, check:deprecated, validate).":"Validation scripts already present \u2014 refreshed package.json."))}catch(t){throw r.fail("Failed to add validation scripts."),t}};var Io=["scripts/sync-env.ts","scripts/check-deprecated.ts"],Ao={id:"validate-scripts",name:"Validation Scripts",description:"sync-env, check-deprecated, and the validate chain",detect:async e=>Io.every(r=>m(La.join(e,r))),files:Io.map(e=>({path:e,generated:!0})),packages:[{name:"tsx",kind:"devDependency"}],scripts:[{name:"env:sync",expectedValue:"tsx scripts/sync-env.ts"},{name:"check:deprecated",expectedValue:"tsx scripts/check-deprecated.ts"},{name:"type-check",expectedValue:"tsc --noEmit"},{name:"validate"}],injections:[],apply:Ye};w();P();import Ce from"node:path";var ko=async e=>{let r=Ce.join(e,c.PACKAGE_JSON);return m(r)?JSON.parse(await u(r)):null},Ma=async(e,r)=>{let t=Ce.join(e,c.PACKAGE_JSON);await f(t,`${JSON.stringify(r,null,2)}
950
+ `)},Oo=(e,r)=>(r==="dependency"?e.dependencies:e.devDependencies)??{},Ke=async(e,r)=>{let t=await e.detect(r),n=[];if(!t)return{manifest:e,installed:!1,drift:[]};for(let i of e.files)i.required!==!1&&(m(Ce.join(r,i.path))||n.push({kind:"missingFile",file:i.path}));let o=await ko(r);if(o){for(let s of e.packages)Oo(o,s.kind)[s.name]||n.push({kind:"missingPackage",name:s.name,depKind:s.kind});let i=o.scripts??{};for(let s of e.scripts){let a=i[s.name];a?s.expectedValue&&a!==s.expectedValue&&n.push({kind:"mismatchedScript",name:s.name,expected:s.expectedValue,actual:a}):n.push({kind:"missingScript",name:s.name})}}for(let i of e.injections){let s=Ce.join(r,i.file);if(!m(s)){n.push({kind:"missingInjection",file:i.file,description:i.description});continue}let a=await u(s);i.presence.test(a)||n.push({kind:"missingInjection",file:i.file,description:i.description})}return{manifest:e,installed:t,drift:n}},yt=async(e,r,t={})=>{let n=t.dryRun??!1,o={filesRemoved:[],packagesUninstalled:[],scriptsRemoved:[],blocksStripped:[],manualCleanup:[]};for(let a of e.injections){let p=Ce.join(r,a.file);if(!m(p))continue;if(!a.removePattern){o.manualCleanup.push({file:a.file,description:a.description});continue}let d=await u(p);if(!a.presence.test(d))continue;let g;if(typeof a.removePattern=="function"){let h=a.removePattern(d);if(h===null){o.manualCleanup.push({file:a.file,description:a.description});continue}g=h}else g=d.replace(a.removePattern,"");g!==d?(n||await f(p,g),o.blocksStripped.push({file:a.file,description:a.description})):o.manualCleanup.push({file:a.file,description:a.description})}let{rm:i}=await import("node:fs/promises");for(let a of e.files){if(!a.generated)continue;let p=Ce.join(r,a.path);if(m(p)){if(a.containsUserContent){let d=a.removeHint?`${a.path} \u2014 ${a.removeHint}`:`${a.path} (may contain user-authored files; review before deleting)`;o.manualCleanup.push({file:a.path,description:d});continue}n||await i(p,{recursive:!0,force:!0}),o.filesRemoved.push(a.path)}}let s=await ko(r);if(s){let a=!1;if(s.scripts)for(let p of e.scripts)s.scripts[p.name]&&(n||delete s.scripts[p.name],o.scriptsRemoved.push(p.name),a=!0);for(let p of e.packages)Oo(s,p.kind)[p.name]&&o.packagesUninstalled.push(p.name);a&&!n&&await Ma(r,s)}if(!n&&o.packagesUninstalled.length>0){let a=await O(r);await Ct(r,a,o.packagesUninstalled)}return o};var ye=[$o,Ao,Ln,fo,jn,bo,Kn,ro,To,uo],_o=e=>ye.find(r=>r.id===e);var Ga=e=>{switch(e.kind){case"missingFile":return`missing file: ${e.file}`;case"missingPackage":return`missing ${e.depKind==="dependency"?"dep":"devDep"}: ${e.name}`;case"missingScript":return`missing script: ${e.name}`;case"mismatchedScript":return`script "${e.name}" expected ${j.dim(e.expected)} but got ${j.dim(e.actual)}`;case"missingInjection":return`missing block in ${e.file}: ${e.description}`}},Ha=e=>{let r=e.filter(n=>n.installed),t=r.filter(n=>n.drift.length>0);return{installedCount:r.length,driftedCount:t.length,cleanCount:r.length-t.length,driftedResults:t}},Fo=e=>{e.command("doctor").description("Diagnose drift between the project and known feature manifests").option("--fix","Re-apply manifests that report drift (idempotent)").option("--feature <id>","Only check this manifest id (e.g. redux, security-headers)").option("--json","Print machine-readable JSON instead of the human report").action(async r=>{try{let t=process.cwd(),n=r.feature?ye.filter(s=>s.id===r.feature):ye;if(r.feature&&n.length===0)throw new Error(`Unknown feature "${r.feature}". Valid: ${ye.map(s=>s.id).join(", ")}.`);let o=[];for(let s of n)o.push(await Ke(s,t));r.json&&(l(JSON.stringify(o.map(s=>({id:s.manifest.id,name:s.manifest.name,installed:s.installed,drift:s.drift})),null,2)),process.exit(o.some(s=>s.drift.length>0)?1:0)),l(j.cyan(`
931
951
  \u{1FA7A} Project Doctor
932
- `));for(let s of i){let{manifest:a,installed:p,drift:d}=s;if(!p){l(` ${j.dim("\u2014")} ${j.dim(a.name)} ${j.dim("(not installed)")}`);continue}if(d.length===0){l(` ${j.green("\u2713")} ${a.name}`);continue}l(` ${j.yellow("!")} ${j.bold(a.name)} ${j.dim(`(${d.length} issue${d.length===1?"":"s"})`)}`);for(let g of d)l(` ${j.yellow("\u2022")} ${ka(g)}`)}let o=Oa(i);l(""),l(j.dim(`${o.cleanCount} clean, ${o.driftedCount} drifted, ${i.length-o.installedCount} not installed`)),o.driftedCount===0&&(l(j.green(`
952
+ `));for(let s of o){let{manifest:a,installed:p,drift:d}=s;if(!p){l(` ${j.dim("\u2014")} ${j.dim(a.name)} ${j.dim("(not installed)")}`);continue}if(d.length===0){l(` ${j.green("\u2713")} ${a.name}`);continue}l(` ${j.yellow("!")} ${j.bold(a.name)} ${j.dim(`(${d.length} issue${d.length===1?"":"s"})`)}`);for(let g of d)l(` ${j.yellow("\u2022")} ${Ga(g)}`)}let i=Ha(o);l(""),l(j.dim(`${i.cleanCount} clean, ${i.driftedCount} drifted, ${o.length-i.installedCount} not installed`)),i.driftedCount===0&&(l(j.green(`
933
953
  \u2713 No drift detected.
934
954
  `)),process.exit(0)),r.fix||(l(j.dim(`
935
955
  Run with --fix to re-apply drifted features.
936
956
  `)),process.exit(1)),l(j.cyan(`
937
957
  \u{1F527} Applying fixes...
938
- `));for(let s of o.driftedResults){if(!s.manifest.apply){l(j.yellow(` \u26A0\uFE0F ${s.manifest.name} has no apply() \u2014 skipping.`));continue}try{await s.manifest.apply(t)}catch(a){v(`Failed to fix ${s.manifest.name}: ${a}`)}}l(j.green(`
958
+ `));for(let s of i.driftedResults){if(!s.manifest.apply){l(j.yellow(` \u26A0\uFE0F ${s.manifest.name} has no apply() \u2014 skipping.`));continue}try{await s.manifest.apply(t)}catch(a){v(`Failed to fix ${s.manifest.name}: ${a}`)}}l(j.green(`
939
959
  \u2713 Doctor finished.
940
- `))}catch(t){v(`${t instanceof Error?t.message:t}`),process.exit(1)}})};import Te from"picocolors";w();P();import ar from"node:path";var _a=/^[A-Z][A-Z0-9_]*$/,Fo=e=>{if(!_a.test(e))throw new Error(`Invalid env var name "${e}". Use UPPER_SNAKE_CASE (e.g. SENTRY_DSN, NEXT_PUBLIC_API_URL).`)},ce=(e,r)=>r?e.startsWith("NEXT_PUBLIC_")?e:`NEXT_PUBLIC_${e}`:e,Fa=e=>{if(e.default===void 0)return"";switch(e.type){case"number":return`.default(${Number(e.default)})`;case"boolean":return`.default(${e.default==="true"})`;default:return`.default('${e.default.replace(/'/g,"\\'")}')`}},ja=e=>{switch(e.type){case"url":return"z.url()";case"number":return"z.coerce.number()";case"boolean":return"z.coerce.boolean()";case"enum":{let r=e.enumValues??[];if(r.length===0)throw new Error(`Enum env var "${e.name}" requires --enum values.`);return`z.enum([${r.map(n=>`'${n.replace(/'/g,"\\'")}'`).join(", ")}])`}default:return"z.string()"}},jo=e=>{let r=ce(e.name,e.public),n=ja(e),i=e.default!==void 0,o=!e.required&&!i;i&&(n+=Fa(e)),o&&e.type!=="enum"&&(n+=".optional()");let s;if(e.type==="enum"?s=n:s=`z.preprocess(emptyStringToUndefined, ${n})`,e.description){let a=e.description.replace(/'/g,"\\'");s+=`
941
- .describe('${a}')`}return` ${r}: ${s},`},_o=/(export const envSchema\s*=\s*z\.object\(\{)([\s\S]*?)(\}\);?)/,Do=(e,r)=>{let t=ce(r.name,r.public);if(new RegExp(`\\b${t}\\s*:`).test(e))return e;let i=e.match(_o);if(!i)throw new Error("Could not locate `export const envSchema = z.object({ \u2026 })` in schema.ts.");let[,o,s,a]=i,p=s.replace(/\s+$/,""),d=p.length===0||/,\s*$/.test(p)?p:`${p},`,g=jo(r),h=`${d}
960
+ `))}catch(t){v(`${t instanceof Error?t.message:t}`),process.exit(1)}})};import Te from"picocolors";w();P();import cr from"node:path";var Ua=/^[A-Z][A-Z0-9_]*$/,Do=e=>{if(!Ua.test(e))throw new Error(`Invalid env var name "${e}". Use UPPER_SNAKE_CASE (e.g. SENTRY_DSN, NEXT_PUBLIC_API_URL).`)},ce=(e,r)=>r?e.startsWith("NEXT_PUBLIC_")?e:`NEXT_PUBLIC_${e}`:e,za=e=>{if(e.default===void 0)return"";switch(e.type){case"number":return`.default(${Number(e.default)})`;case"boolean":return`.default(${e.default==="true"})`;default:return`.default('${e.default.replace(/'/g,"\\'")}')`}},Va=e=>{switch(e.type){case"url":return"z.url()";case"number":return"z.coerce.number()";case"boolean":return"z.coerce.boolean()";case"enum":{let r=e.enumValues??[];if(r.length===0)throw new Error(`Enum env var "${e.name}" requires --enum values.`);return`z.enum([${r.map(n=>`'${n.replace(/'/g,"\\'")}'`).join(", ")}])`}default:return"z.string()"}},Lo=e=>{let r=ce(e.name,e.public),n=Va(e),o=e.default!==void 0,i=!e.required&&!o;o&&(n+=za(e)),i&&e.type!=="enum"&&(n+=".optional()");let s;if(e.type==="enum"?s=n:s=`z.preprocess(emptyStringToUndefined, ${n})`,e.description){let a=e.description.replace(/'/g,"\\'");s+=`
961
+ .describe('${a}')`}return` ${r}: ${s},`},jo=/(export const envSchema\s*=\s*z\.object\(\{)([\s\S]*?)(\}\);?)/,Mo=(e,r)=>{let t=ce(r.name,r.public);if(new RegExp(`\\b${t}\\s*:`).test(e))return e;let o=e.match(jo);if(!o)throw new Error("Could not locate `export const envSchema = z.object({ \u2026 })` in schema.ts.");let[,i,s,a]=o,p=s.replace(/\s+$/,""),d=p.length===0||/,\s*$/.test(p)?p:`${p},`,g=Lo(r),h=`${d}
942
962
  ${g}
943
- `;return e.replace(_o,`${o}${h}${a}`)},Da="# -public",La=e=>{let r=ce(e.name,e.public),t=e.default??"",n=e.public?` ${Da}`:"";return`${r}=${t}${n}`},Lo=(e,r)=>{let t=ce(r.name,r.public);if(new RegExp(`^${t}=`,"m").test(e))return e;let i=e===""||e.endsWith(`
963
+ `;return e.replace(jo,`${i}${h}${a}`)},Ja="# -public",Ba=e=>{let r=ce(e.name,e.public),t=e.default??"",n=e.public?` ${Ja}`:"";return`${r}=${t}${n}`},Go=(e,r)=>{let t=ce(r.name,r.public);if(new RegExp(`^${t}=`,"m").test(e))return e;let o=e===""||e.endsWith(`
944
964
  `)?"":`
945
- `,o=e===""?"":`
965
+ `,i=e===""?"":`
946
966
  `,s=r.description?`# ${r.description}
947
- `:"";return`${e}${i}${o}${s}${La(r)}
948
- `},Mo=(e,r)=>{let t=ce(r.name,r.public);if(new RegExp(`^${t}=`,"m").test(e))return e;let i=e===""||e.endsWith(`
967
+ `:"";return`${e}${o}${i}${s}${Ba(r)}
968
+ `},Ho=(e,r)=>{let t=ce(r.name,r.public);if(new RegExp(`^${t}=`,"m").test(e))return e;let o=e===""||e.endsWith(`
949
969
  `)?"":`
950
- `,o=r.default??"";return`${e}${i}${t}=${o}
951
- `},cr=async(e,r)=>{Fo(r.name);let t=ar.join(e,"src/lib/env/schema.ts");if(!m(t))throw new Error("src/lib/env/schema.ts not found \u2014 run `next-maker init` first.");let n=await u(t),i=Do(n,r),o=i!==n;o&&await f(t,i);let s=ar.join(e,c.ENV_EXAMPLE),a=!1;if(m(s)){let g=await u(s),h=Lo(g,r);a=h!==g,a&&await f(s,h)}let p=ar.join(e,".env"),d=!1;if(m(p)){let g=await u(p),h=Mo(g,r);d=h!==g,d&&await f(p,h)}return{schemaUpdated:o,envExampleUpdated:a,envUpdated:d}};var Go=new Set(["string","url","number","boolean","enum"]),Ma=e=>{let r=(e??"string").toLowerCase();if(!Go.has(r))throw new Error(`Invalid --type "${e}". Valid: ${Array.from(Go).join(", ")}.`);return r},Ga=e=>{if(!e)return;let r=e.split(",").map(t=>t.trim()).filter(Boolean);return r.length===0?void 0:r},Ho=e=>{e.command("env <NAME>").description("Declare a new environment variable across schema, .env.example, and .env").option("--type <type>","Zod type (string|url|number|boolean|enum)","string").option("--required","Make the variable required (no .optional() / .default())").option("--default <value>","Set a default value (mutually exclusive with --required)").option("--public","Mark as public (auto-prefix NEXT_PUBLIC_ and tag .env.example)").option("--describe <text>","Description (rendered as .describe() and .env.example comment)").option("--enum <list>",'Comma-separated values when --type=enum (e.g. "dev,prod")').action(async(r,t)=>{try{let n=process.cwd();if(l(Te.cyan(`
970
+ `,i=r.default??"";return`${e}${o}${t}=${i}
971
+ `},pr=async(e,r)=>{Do(r.name);let t=cr.join(e,"src/lib/env/schema.ts");if(!m(t))throw new Error("src/lib/env/schema.ts not found \u2014 run `next-maker init` first.");let n=await u(t),o=Mo(n,r),i=o!==n;i&&await f(t,o);let s=cr.join(e,c.ENV_EXAMPLE),a=!1;if(m(s)){let g=await u(s),h=Go(g,r);a=h!==g,a&&await f(s,h)}let p=cr.join(e,".env"),d=!1;if(m(p)){let g=await u(p),h=Ho(g,r);d=h!==g,d&&await f(p,h)}return{schemaUpdated:i,envExampleUpdated:a,envUpdated:d}};var Uo=new Set(["string","url","number","boolean","enum"]),Xa=e=>{let r=(e??"string").toLowerCase();if(!Uo.has(r))throw new Error(`Invalid --type "${e}". Valid: ${Array.from(Uo).join(", ")}.`);return r},Ya=e=>{if(!e)return;let r=e.split(",").map(t=>t.trim()).filter(Boolean);return r.length===0?void 0:r},zo=e=>{e.command("env <NAME>").description("Declare a new environment variable across schema, .env.example, and .env").option("--type <type>","Zod type (string|url|number|boolean|enum)","string").option("--required","Make the variable required (no .optional() / .default())").option("--default <value>","Set a default value (mutually exclusive with --required)").option("--public","Mark as public (auto-prefix NEXT_PUBLIC_ and tag .env.example)").option("--describe <text>","Description (rendered as .describe() and .env.example comment)").option("--enum <list>",'Comma-separated values when --type=enum (e.g. "dev,prod")').action(async(r,t)=>{try{let n=process.cwd();if(l(Te.cyan(`
952
972
  \u{1F510} Env Var Generator
953
- `)),t.required&&t.default!==void 0)throw new Error("--required and --default are mutually exclusive.");let i=Ma(t.type),o=Ga(t.enum);if(i==="enum"&&(!o||o.length===0))throw new Error("--type=enum requires at least one value via --enum a,b,c.");let s={name:r,type:i,required:!!t.required,default:t.default,description:t.describe,enumValues:o,public:!!t.public};x.start("Updating schema, .env.example, and .env...");let a=await cr(n,s);x.succeed("Env var written");let p=ce(s.name,s.public);l(Te.green(`
973
+ `)),t.required&&t.default!==void 0)throw new Error("--required and --default are mutually exclusive.");let o=Xa(t.type),i=Ya(t.enum);if(o==="enum"&&(!i||i.length===0))throw new Error("--type=enum requires at least one value via --enum a,b,c.");let s={name:r,type:o,required:!!t.required,default:t.default,description:t.describe,enumValues:i,public:!!t.public};y.start("Updating schema, .env.example, and .env...");let a=await pr(n,s);y.succeed("Env var written");let p=ce(s.name,s.public);l(Te.green(`
954
974
  \u2728 ${p} declared.
955
- `)),l(Te.dim("Touched:")),l(Te.dim(` ${a.schemaUpdated?"\u270F\uFE0F ":"\u23ED "} src/lib/env/schema.ts`)),l(Te.dim(` ${a.envExampleUpdated?"\u270F\uFE0F ":"\u23ED "} .env.example`)),l(Te.dim(` ${a.envUpdated?"\u270F\uFE0F ":"\u23ED "} .env`)),l("")}catch(n){x.fail("Env var declaration failed"),v(`${n instanceof Error?n.message:n}`),process.exit(1)}})};import hr from"node:path";import D from"picocolors";L();L();import nc from"node:path";import{readFile as Ha,writeFile as Ua}from"node:fs/promises";import za from"node:path";var qe=(e,r)=>{let t=/import\s+.*\s+from\s+['"].*['"];?\n/g,n=e.match(t);if(n&&n.length>0){let i=n[n.length-1],o=e.lastIndexOf(i);return e.slice(0,o+i.length)+r+`
956
- `+e.slice(o+i.length)}return`${r}
957
- ${e}`},pr=(e,r,t)=>{let n=/combineReducers\(\{([^}]*)\}\)/s,i=e.match(n);if(!i)throw new Error("Could not find combineReducers in rootReducer.ts");let o=i[1],s=`
958
- ${r}: ${t},`,a=o.trimEnd()+s;return e.replace(n,`combineReducers({${a}
959
- })`)},We=(e,r)=>{let t=e.lastIndexOf("} as const;");if(t===-1)throw new Error("Could not find closing brace of AppApis object");let n=e.substring(0,t),i=e.substring(t);return`${n.trimEnd()}
975
+ `)),l(Te.dim("Touched:")),l(Te.dim(` ${a.schemaUpdated?"\u270F\uFE0F ":"\u23ED "} src/lib/env/schema.ts`)),l(Te.dim(` ${a.envExampleUpdated?"\u270F\uFE0F ":"\u23ED "} .env.example`)),l(Te.dim(` ${a.envUpdated?"\u270F\uFE0F ":"\u23ED "} .env`)),l("")}catch(n){y.fail("Env var declaration failed"),v(`${n instanceof Error?n.message:n}`),process.exit(1)}})};import yr from"node:path";import D from"picocolors";L();L();import mc from"node:path";import{readFile as Ka,writeFile as qa}from"node:fs/promises";import Wa from"node:path";var qe=(e,r)=>{let t=/import\s+.*\s+from\s+['"].*['"];?\n/g,n=e.match(t);if(n&&n.length>0){let o=n[n.length-1],i=e.lastIndexOf(o);return e.slice(0,i+o.length)+r+`
976
+ `+e.slice(i+o.length)}return`${r}
977
+ ${e}`},lr=(e,r,t)=>{let n=/combineReducers\(\{([^}]*)\}\)/s,o=e.match(n);if(!o)throw new Error("Could not find combineReducers in rootReducer.ts");let i=o[1],s=`
978
+ ${r}: ${t},`,a=i.trimEnd()+s;return e.replace(n,`combineReducers({${a}
979
+ })`)},We=(e,r)=>{let t=e.lastIndexOf("} as const;");if(t===-1)throw new Error("Could not find closing brace of AppApis object");let n=e.substring(0,t),o=e.substring(t);return`${n.trimEnd()}
960
980
  ${r}
961
- ${i}`};var Ze=async e=>{let{serviceName:r,projectPath:t}=e,n=A(r),i=za.join(t,"src","lib","config","app-apis.ts");try{let o=await Ha(i,"utf-8");if(o.includes(`${n}:`))return;if(!o.match(/export const AppApis = \{[\s\S]*?\} as const;/))throw new Error("Could not find AppApis object in app-apis.ts");let s=` ${n}: {
981
+ ${o}`};var Ze=async e=>{let{serviceName:r,projectPath:t}=e,n=A(r),o=Wa.join(t,"src","lib","config","app-apis.ts");try{let i=await Ka(o,"utf-8");if(i.includes(`${n}:`))return;if(!i.match(/export const AppApis = \{[\s\S]*?\} as const;/))throw new Error("Could not find AppApis object in app-apis.ts");let s=` ${n}: {
962
982
  base: \`\${API_PREFIX}/${r}\`,
963
983
  getAll: \`\${API_PREFIX}/${r}\`,
964
- },`;o=We(o,s),await Ua(i,o)}catch(o){throw new Error(`Failed to register API endpoints: ${o}`,{cause:o})}};import{readFile as Va,writeFile as Ja}from"node:fs/promises";import Ba from"node:path";P();var lr=async(e,r,t)=>{let n=Ba.join(e,"src","lib","config","app-paths.ts");if(!m(n))return;let i=await Va(n,"utf-8"),o=A(r);if(i.includes(`${o}:`))return;let s=i.lastIndexOf("} as const;");if(s===-1)return;let a=` ${o}: '${t}',
965
- `;i=i.slice(0,s)+a+i.slice(s),await Ja(n,i)};w();P();import yt from"node:path";var Xa=e=>new RegExp(`<\\s*${e}\\b`),Uo=(e,r)=>{if(Xa(r).test(e))return e;let t=/^(?<indent>[ \t]*)\{children\}\s*$/m,n=e.match(t);if(!n||n.index===void 0)throw new Error("Could not locate `{children}` line in RootProvider \u2014 expected a line containing only `{children}`.");let i=n.groups?.indent??"",o=`${i} `,s=`${i}<${r}>
966
- ${o}{children}
967
- ${i}</${r}>`;return e.replace(t,s)},zo=(e,r)=>{let t=`export * from './${r}';`;if(e.includes(t))return e;let n=e.split(`
968
- `),i=[],o=[];for(let h of n)/^export \* from '\.\/.*';\s*$/.test(h)?i.push(h):o.push(h);let s=[...i,t].sort(),a=n.findIndex(h=>/^export \* from '\.\//.test(h));if(a===-1)return`${t}
969
- ${e.replace(/^\n+/,"")}`;let p=n.slice(0,a),d=n.findIndex((h,y)=>y>a&&!/^export \* from '\.\//.test(h)),g=d===-1?[]:n.slice(d);return[...p,...s,...g].join(`
970
- `)},Ya=c.PROVIDERS,Ka=c.ROOT_PROVIDER,qa=c.PROVIDERS_INDEX,Vo=async(e,r={fileExists:m,readFile:u})=>{let t=yt.join(e,Ka);if(r.fileExists(t))return t;let n=yt.join(e,Ya);if(!r.fileExists(n))return null;let{readdir:i}=await import("node:fs/promises"),s=(await i(n).catch(()=>[])).filter(p=>p.endsWith(".tsx")),a=null;for(let p of s){let d=yt.join(n,p),g=await r.readFile(d);if(!/\{children\}/.test(g))continue;let y=((g.split("{children}")[0]??"").match(/<[A-Z][A-Za-z0-9_]*\b/g)??[]).length;(!a||y>a.depth)&&(a={file:d,depth:y})}return a?.file??null},mr=async e=>{let{projectPath:r,componentName:t,fileBaseName:n}=e,i=await Vo(r);if(i){let a=await u(i),p=a;(!/from '\.\//.test(a)||!a.includes(`{ ${t} }`))&&(p=qe(p,`import { ${t} } from './${n}';`)),p=Uo(p,t),p!==a&&await f(i,p)}let o=yt.join(r,qa),s=null;if(m(o)){let a=await u(o),p=zo(a,n);p!==a&&await f(o,p),s=o}return{rootProviderFile:i,barrelFile:s}};import{readFile as Wa,writeFile as Za}from"node:fs/promises";import Qa from"node:path";var Qe=async e=>{let{projectPath:r,name:t,persist:n,importPath:i}=e,o=Qa.join(r,"src","store","rootReducer.ts");try{let s=await Wa(o,"utf-8"),a=A(t),p=`${a}Reducer`,d=`${a}PersistConfig`,g=i.replace(/^src\//,"@/"),h=n?`import { ${p}, ${d} } from '${g}';`:`import { ${p} } from '${g}';`;s=qe(s,h);let y=n?`persistReducer(${d}, ${p})`:p;s=pr(s,a,y),await Za(o,s)}catch(s){throw new Error(`Failed to register reducer '${t}' in rootReducer: ${s}`,{cause:s})}};P();import{readFile as ec,writeFile as tc}from"node:fs/promises";import rc from"node:path";var dr=async(e,r)=>{let t=rc.join(e,"src","i18n","translations","en.json");if(!m(t))return;let n=await ec(t,"utf-8"),i=JSON.parse(n);i[r]||(i[r]={title:r,description:`${r} page description`},await tc(t,`${JSON.stringify(i,null,2)}
971
- `))};var ur=()=>[{name:"Project setup detected",spinnerText:"Detecting project setup...",execute:async e=>{e.detection=await I(e.projectPath)}},{name:"Feature files generated",spinnerText:"Generating feature files...",execute:async e=>{await Mt({name:e.featureName,outputPath:e.featurePath,createStore:e.createStore,persistStore:e.persistStore,createService:e.createService,httpClient:e.httpClient})}},{name:"API endpoints registered",spinnerText:"Registering API endpoints...",shouldSkip:e=>!e.createService,execute:async e=>{await Ze({serviceName:e.featureName,projectPath:e.projectPath})}},{name:"Feature registered in rootReducer",spinnerText:"Registering feature in rootReducer...",shouldSkip:e=>!e.createStore||!e.detection.hasRedux,execute:async e=>{await Qe({projectPath:e.projectPath,name:e.featureName,persist:e.persistStore,importPath:nc.join(e.basePath,e.featureName,"store")})}}];var ye=async(e,r)=>{for(let t of e)if(!t.shouldSkip?.(r)){r.spinner.start(t.spinnerText);try{await t.execute(r),r.spinner.succeed(t.name)}catch(n){throw r.spinner.fail(t.name),n}}};var fr=()=>[{name:"Service files generated",spinnerText:"Generating service files...",execute:async e=>{await Ie({name:e.serviceName,outputPath:e.servicePath,httpClient:e.httpClient})}},{name:"API endpoints registered",spinnerText:"Registering API endpoints...",execute:async e=>{await Ze({serviceName:e.serviceName,projectPath:e.projectPath})}}];import oc from"node:path";var gr=()=>[{name:"Slice files generated",spinnerText:"Generating slice files...",execute:async e=>{await Oe({name:e.sliceName,outputPath:e.slicePath,persist:e.persistSlice})}},{name:"Slice registered in rootReducer",spinnerText:"Registering slice in rootReducer...",execute:async e=>{await Qe({projectPath:e.projectPath,name:e.sliceName,persist:e.persistSlice,importPath:oc.join(e.basePath,e.sliceName)})}}];import ic from"enquirer";var{prompt:sc}=ic,Jo=async(e,r,t,n,i,o,s)=>{let a=[];e||a.push({type:"input",name:"featureName",message:"What is the feature name?",initial:"my-feature",validate:d=>/^[a-z0-9-]+$/.test(d)?!0:"Feature name must be lowercase and contain only alphanumeric characters and hyphens."}),r&&n===void 0&&i===void 0&&(a.push({type:"confirm",name:"createStore",message:"Generate Redux store for this feature?",initial:!0}),a.push({type:"confirm",name:"persistStore",message:"Enable persistence for this store?",initial:!1,skip(){return!this.state.answers.createStore}})),t&&t!=="none"&&o===void 0&&s===void 0&&(a.push({type:"confirm",name:"createService",message:"Generate API service for this feature?",initial:!0}),t==="both"&&a.push({type:"select",name:"selectedHttpClient",message:"Which HTTP client to use for the service?",choices:["fetch","axios"],initial:0,skip(){return!this.state.answers.createService}}));let p=a.length>0?await sc(a):{};return{featureName:e||p.featureName,hasRedux:r||!1,createStore:n===!0?!1:i!==void 0?!0:p.createStore||!1,persistStore:i==="persist"?!0:i==="no-persist"?!1:p.persistStore||!1,httpClient:t||"none",createService:o===!0?!1:s!==void 0?!0:p.createService||!1,selectedHttpClient:s||p.selectedHttpClient||(t==="both"?"fetch":t!=="none"?t:void 0)}};var Bo=e=>{e.command("feature [name]").description("Generate a new feature module").option("--skip-store","Skip Redux store generation").option("--store <type>","Generate Redux store with persistence option (persist|no-persist)").option("--skip-service","Skip API service generation").option("--service <client>","Generate API service with specific HTTP client (axios|fetch)").option("--path <path>","Custom path for feature generation (default: src/features)").action(async(r,t)=>{try{let n=process.cwd();ac(t),l(D.cyan(`
984
+ },`;i=We(i,s),await qa(o,i)}catch(i){throw new Error(`Failed to register API endpoints: ${i}`,{cause:i})}};import{readFile as Za,writeFile as Qa}from"node:fs/promises";import ec from"node:path";P();var mr=async(e,r,t)=>{let n=ec.join(e,"src","lib","config","app-paths.ts");if(!m(n))return;let o=await Za(n,"utf-8"),i=A(r);if(o.includes(`${i}:`))return;let s=o.lastIndexOf("} as const;");if(s===-1)return;let a=` ${i}: '${t}',
985
+ `;o=o.slice(0,s)+a+o.slice(s),await Qa(n,o)};w();P();import xt from"node:path";var tc=e=>new RegExp(`<\\s*${e}\\b`),Vo=(e,r)=>{if(tc(r).test(e))return e;let t=/^(?<indent>[ \t]*)\{children\}\s*$/m,n=e.match(t);if(!n||n.index===void 0)throw new Error("Could not locate `{children}` line in RootProvider \u2014 expected a line containing only `{children}`.");let o=n.groups?.indent??"",i=`${o} `,s=`${o}<${r}>
986
+ ${i}{children}
987
+ ${o}</${r}>`;return e.replace(t,s)},Jo=(e,r)=>{let t=`export * from './${r}';`;if(e.includes(t))return e;let n=e.split(`
988
+ `),o=[],i=[];for(let h of n)/^export \* from '\.\/.*';\s*$/.test(h)?o.push(h):i.push(h);let s=[...o,t].sort(),a=n.findIndex(h=>/^export \* from '\.\//.test(h));if(a===-1)return`${t}
989
+ ${e.replace(/^\n+/,"")}`;let p=n.slice(0,a),d=n.findIndex((h,x)=>x>a&&!/^export \* from '\.\//.test(h)),g=d===-1?[]:n.slice(d);return[...p,...s,...g].join(`
990
+ `)},rc=c.PROVIDERS,nc=c.ROOT_PROVIDER,oc=c.PROVIDERS_INDEX,Bo=async(e,r={fileExists:m,readFile:u})=>{let t=xt.join(e,nc);if(r.fileExists(t))return t;let n=xt.join(e,rc);if(!r.fileExists(n))return null;let{readdir:o}=await import("node:fs/promises"),s=(await o(n).catch(()=>[])).filter(p=>p.endsWith(".tsx")),a=null;for(let p of s){let d=xt.join(n,p),g=await r.readFile(d);if(!/\{children\}/.test(g))continue;let x=((g.split("{children}")[0]??"").match(/<[A-Z][A-Za-z0-9_]*\b/g)??[]).length;(!a||x>a.depth)&&(a={file:d,depth:x})}return a?.file??null},dr=async e=>{let{projectPath:r,componentName:t,fileBaseName:n}=e,o=await Bo(r);if(o){let a=await u(o),p=a;(!/from '\.\//.test(a)||!a.includes(`{ ${t} }`))&&(p=qe(p,`import { ${t} } from './${n}';`)),p=Vo(p,t),p!==a&&await f(o,p)}let i=xt.join(r,oc),s=null;if(m(i)){let a=await u(i),p=Jo(a,n);p!==a&&await f(i,p),s=i}return{rootProviderFile:o,barrelFile:s}};import{readFile as ic,writeFile as sc}from"node:fs/promises";import ac from"node:path";var Qe=async e=>{let{projectPath:r,name:t,persist:n,importPath:o}=e,i=ac.join(r,"src","store","rootReducer.ts");try{let s=await ic(i,"utf-8"),a=A(t),p=`${a}Reducer`,d=`${a}PersistConfig`,g=o.replace(/^src\//,"@/"),h=n?`import { ${p}, ${d} } from '${g}';`:`import { ${p} } from '${g}';`;s=qe(s,h);let x=n?`persistReducer(${d}, ${p})`:p;s=lr(s,a,x),await sc(i,s)}catch(s){throw new Error(`Failed to register reducer '${t}' in rootReducer: ${s}`,{cause:s})}};P();import{readFile as cc,writeFile as pc}from"node:fs/promises";import lc from"node:path";var ur=async(e,r)=>{let t=lc.join(e,"src","i18n","translations","en.json");if(!m(t))return;let n=await cc(t,"utf-8"),o=JSON.parse(n);o[r]||(o[r]={title:r,description:`${r} page description`},await pc(t,`${JSON.stringify(o,null,2)}
991
+ `))};var fr=()=>[{name:"Project setup detected",spinnerText:"Detecting project setup...",execute:async e=>{e.detection=await I(e.projectPath)}},{name:"Feature files generated",spinnerText:"Generating feature files...",execute:async e=>{await Gt({name:e.featureName,outputPath:e.featurePath,createStore:e.createStore,persistStore:e.persistStore,createService:e.createService,httpClient:e.httpClient})}},{name:"API endpoints registered",spinnerText:"Registering API endpoints...",shouldSkip:e=>!e.createService,execute:async e=>{await Ze({serviceName:e.featureName,projectPath:e.projectPath})}},{name:"Feature registered in rootReducer",spinnerText:"Registering feature in rootReducer...",shouldSkip:e=>!e.createStore||!e.detection.hasRedux,execute:async e=>{await Qe({projectPath:e.projectPath,name:e.featureName,persist:e.persistStore,importPath:mc.join(e.basePath,e.featureName,"store")})}}];var xe=async(e,r)=>{for(let t of e)if(!t.shouldSkip?.(r)){r.spinner.start(t.spinnerText);try{await t.execute(r),r.spinner.succeed(t.name)}catch(n){throw r.spinner.fail(t.name),n}}};var gr=()=>[{name:"Service files generated",spinnerText:"Generating service files...",execute:async e=>{await Ie({name:e.serviceName,outputPath:e.servicePath,httpClient:e.httpClient})}},{name:"API endpoints registered",spinnerText:"Registering API endpoints...",execute:async e=>{await Ze({serviceName:e.serviceName,projectPath:e.projectPath})}}];import dc from"node:path";var hr=()=>[{name:"Slice files generated",spinnerText:"Generating slice files...",execute:async e=>{await Oe({name:e.sliceName,outputPath:e.slicePath,persist:e.persistSlice})}},{name:"Slice registered in rootReducer",spinnerText:"Registering slice in rootReducer...",execute:async e=>{await Qe({projectPath:e.projectPath,name:e.sliceName,persist:e.persistSlice,importPath:dc.join(e.basePath,e.sliceName)})}}];import uc from"enquirer";var{prompt:fc}=uc,Xo=async(e,r,t,n,o,i,s)=>{let a=[];e||a.push({type:"input",name:"featureName",message:"What is the feature name?",initial:"my-feature",validate:d=>/^[a-z0-9-]+$/.test(d)?!0:"Feature name must be lowercase and contain only alphanumeric characters and hyphens."}),r&&n===void 0&&o===void 0&&(a.push({type:"confirm",name:"createStore",message:"Generate Redux store for this feature?",initial:!0}),a.push({type:"confirm",name:"persistStore",message:"Enable persistence for this store?",initial:!1,skip(){return!this.state.answers.createStore}})),t&&t!=="none"&&i===void 0&&s===void 0&&(a.push({type:"confirm",name:"createService",message:"Generate API service for this feature?",initial:!0}),t==="both"&&a.push({type:"select",name:"selectedHttpClient",message:"Which HTTP client to use for the service?",choices:["fetch","axios"],initial:0,skip(){return!this.state.answers.createService}}));let p=a.length>0?await fc(a):{};return{featureName:e||p.featureName,hasRedux:r||!1,createStore:n===!0?!1:o!==void 0?!0:p.createStore||!1,persistStore:o==="persist"?!0:o==="no-persist"?!1:p.persistStore||!1,httpClient:t||"none",createService:i===!0?!1:s!==void 0?!0:p.createService||!1,selectedHttpClient:s||p.selectedHttpClient||(t==="both"?"fetch":t!=="none"?t:void 0)}};var Yo=e=>{e.command("feature [name]").description("Generate a new feature module").option("--skip-store","Skip Redux store generation").option("--store <type>","Generate Redux store with persistence option (persist|no-persist)").option("--skip-service","Skip API service generation").option("--service <client>","Generate API service with specific HTTP client (axios|fetch)").option("--path <path>","Custom path for feature generation (default: src/features)").action(async(r,t)=>{try{let n=process.cwd();gc(t),l(D.cyan(`
972
992
  \u{1F3AF} Feature Generator
973
- `));let i=ur();x.start("Detecting project setup...");let{detectProjectSetup:o}=await Promise.resolve().then(()=>(L(),Ne)),s=await o(n);x.succeed("Project setup detected"),l(D.dim(` Redux: ${s.hasRedux?"\u2713":"\u2717"}`)),l(D.dim(` HTTP Client: ${s.httpClient}`)),l(D.dim(` i18n: ${s.hasI18n?"\u2713":"\u2717"}
974
- `));let a=await Jo(r,s.hasRedux,s.httpClient,t.skipStore,t.store,t.skipService,t.service),p=t.path||hr.join("src","features"),d=hr.join(n,p,a.featureName);await ie(n,a.featureName,p)&&(v(`Feature '${a.featureName}' already exists at ${p}!`),process.exit(1)),await ye(i.slice(1),{projectPath:n,spinner:x,featureName:a.featureName,basePath:p,featurePath:d,createStore:a.createStore,persistStore:a.persistStore,createService:a.createService,httpClient:a.selectedHttpClient,detection:s}),cc(a,p)}catch(n){x.fail("Feature generation failed"),v(`${n}`),process.exit(1)}})},ac=e=>{e.store&&!["persist","no-persist"].includes(e.store)&&(v("Invalid --store option. Use: persist or no-persist"),process.exit(1)),e.service&&!["axios","fetch"].includes(e.service)&&(v("Invalid --service option. Use: axios or fetch"),process.exit(1)),e.skipStore&&e.store&&(v("Cannot use --skip-store and --store together"),process.exit(1)),e.skipService&&e.service&&(v("Cannot use --skip-service and --service together"),process.exit(1))},cc=(e,r)=>{let t=hr.join(r,e.featureName);l(D.green(`
993
+ `));let o=fr();y.start("Detecting project setup...");let{detectProjectSetup:i}=await Promise.resolve().then(()=>(L(),Ne)),s=await i(n);y.succeed("Project setup detected"),l(D.dim(` Redux: ${s.hasRedux?"\u2713":"\u2717"}`)),l(D.dim(` HTTP Client: ${s.httpClient}`)),l(D.dim(` i18n: ${s.hasI18n?"\u2713":"\u2717"}
994
+ `));let a=await Xo(r,s.hasRedux,s.httpClient,t.skipStore,t.store,t.skipService,t.service),p=t.path||yr.join("src","features"),d=yr.join(n,p,a.featureName);await ie(n,a.featureName,p)&&(v(`Feature '${a.featureName}' already exists at ${p}!`),process.exit(1)),await xe(o.slice(1),{projectPath:n,spinner:y,featureName:a.featureName,basePath:p,featurePath:d,createStore:a.createStore,persistStore:a.persistStore,createService:a.createService,httpClient:a.selectedHttpClient,detection:s}),hc(a,p)}catch(n){y.fail("Feature generation failed"),v(`${n}`),process.exit(1)}})},gc=e=>{e.store&&!["persist","no-persist"].includes(e.store)&&(v("Invalid --store option. Use: persist or no-persist"),process.exit(1)),e.service&&!["axios","fetch"].includes(e.service)&&(v("Invalid --service option. Use: axios or fetch"),process.exit(1)),e.skipStore&&e.store&&(v("Cannot use --skip-store and --store together"),process.exit(1)),e.skipService&&e.service&&(v("Cannot use --skip-service and --service together"),process.exit(1))},hc=(e,r)=>{let t=yr.join(r,e.featureName);l(D.green(`
975
995
  \u2728 Feature '${e.featureName}' created successfully!
976
996
  `)),l(D.dim("Generated files:")),l(D.dim(` \u{1F4C2} ${t}/`)),l(D.dim(" \u251C\u2500\u2500 components/")),l(D.dim(" \u251C\u2500\u2500 hooks/")),l(D.dim(" \u251C\u2500\u2500 types/")),e.createStore&&l(D.dim(" \u251C\u2500\u2500 store/")),e.createService&&l(D.dim(" \u251C\u2500\u2500 services/")),l(D.dim(` \u2514\u2500\u2500 index.ts
977
- `)),l(D.cyan("Next steps:"));let n=r.replace(/^src\//,"@/");l(D.dim(` 1. Import and use the feature: import { ${e.featureName} } from '${n}/${e.featureName}'`)),e.createStore&&l(D.dim(` 2. Customize your Redux slice in: ${t}/store/`)),e.createService&&l(D.dim(` 3. Add API methods in: ${t}/services/${e.featureName}.service.ts`)),l("")};import xr from"node:path";import Ee from"picocolors";L();import pc from"enquirer";var{prompt:lc}=pc,Xo=async e=>e?{hookName:e}:await lc({type:"input",name:"hookName",message:'Hook name (kebab-case, without "use" prefix):',validate:t=>t?/^[a-z][a-z0-9-]*$/.test(t)?!0:"Use lowercase letters, numbers, and hyphens only":"Hook name is required"});var Yo=e=>{e.command("hook [name]").description("Generate a custom React hook").option("--client","Add 'use client' directive (default: true)",!0).option("--feature <path>","Generate in feature directory (e.g., src/features/auth)").option("--test","Also generate a sibling test file").option("--no-test","Skip test file generation").action(async(r,t)=>{try{let n=process.cwd();l(Ee.cyan(`
997
+ `)),l(D.cyan("Next steps:"));let n=r.replace(/^src\//,"@/");l(D.dim(` 1. Import and use the feature: import { ${e.featureName} } from '${n}/${e.featureName}'`)),e.createStore&&l(D.dim(` 2. Customize your Redux slice in: ${t}/store/`)),e.createService&&l(D.dim(` 3. Add API methods in: ${t}/services/${e.featureName}.service.ts`)),l("")};import xr from"node:path";import Ee from"picocolors";L();import yc from"enquirer";var{prompt:xc}=yc,Ko=async e=>e?{hookName:e}:await xc({type:"input",name:"hookName",message:'Hook name (kebab-case, without "use" prefix):',validate:t=>t?/^[a-z][a-z0-9-]*$/.test(t)?!0:"Use lowercase letters, numbers, and hyphens only":"Hook name is required"});var qo=e=>{e.command("hook [name]").description("Generate a custom React hook").option("--client","Add 'use client' directive (default: true)",!0).option("--feature <path>","Generate in feature directory (e.g., src/features/auth)").option("--test","Also generate a sibling test file").option("--no-test","Skip test file generation").action(async(r,t)=>{try{let n=process.cwd();l(Ee.cyan(`
978
998
  \u{1FA9D} Hook Generator
979
- `));let i=await I(n),o=await Xo(r),a=`use${$(o.hookName)}`,p=mc(t,i.hasTests);x.start("Generating hook..."),await Ht({name:o.hookName,projectPath:n,isClient:t.client??!0,featurePath:t.feature}),x.succeed("Hook generated");let d=t.feature?xr.join(n,t.feature,"hooks",`${a}.ts`):xr.join(n,"src/hooks",`${a}.ts`),g=null;p&&(x.start("Generating test..."),g=await Q({projectPath:n,sourceFile:d,kind:"hook",symbolName:a,hookUsesStore:i.hasRedux&&!!t.feature}),x.succeed("Test generated"));let h=t.feature?`${t.feature}/hooks/${a}.ts`:`src/hooks/${a}.ts`;l(Ee.green(`
999
+ `));let o=await I(n),i=await Ko(r),a=`use${$(i.hookName)}`,p=Pc(t,o.hasTests);y.start("Generating hook..."),await Ut({name:i.hookName,projectPath:n,isClient:t.client??!0,featurePath:t.feature}),y.succeed("Hook generated");let d=t.feature?xr.join(n,t.feature,"hooks",`${a}.ts`):xr.join(n,"src/hooks",`${a}.ts`),g=null;p&&(y.start("Generating test..."),g=await ee({projectPath:n,sourceFile:d,kind:"hook",symbolName:a,hookUsesStore:o.hasRedux&&!!t.feature}),y.succeed("Test generated"));let h=t.feature?`${t.feature}/hooks/${a}.ts`:`src/hooks/${a}.ts`;l(Ee.green(`
980
1000
  \u2728 Hook '${a}' created successfully!
981
- `)),l(Ee.dim(` \u{1F4C4} ${h}`)),g&&l(Ee.dim(` \u{1F9EA} ${xr.relative(n,g)}`)),l(""),l(Ee.cyan("Usage:"));let y=t.feature?`${t.feature.replace(/^src\//,"@/")}/hooks/${a}`:`@/hooks/${a}`;l(Ee.dim(` import { ${a} } from '${y}';`)),l("")}catch(n){x.fail("Hook generation failed"),v(`${n}`),process.exit(1)}})},mc=(e,r)=>e.noTest?!1:e.test?!0:r;import Pt from"picocolors";L();var Ko=e=>{e.command("layout <segment>").description("Generate a nested layout.tsx (locale-aware when i18n is detected)").option("--group","Treat the segment as a route group (wraps it in parens)").option("--at <path>","Place the layout under this nested path (kebab-case, slash-separated)").option("--no-locale","Skip the locale wrapper even if i18n is detected").action(async(r,t)=>{try{let n=process.cwd();l(Pt.cyan(`
1001
+ `)),l(Ee.dim(` \u{1F4C4} ${h}`)),g&&l(Ee.dim(` \u{1F9EA} ${xr.relative(n,g)}`)),l(""),l(Ee.cyan("Usage:"));let x=t.feature?`${t.feature.replace(/^src\//,"@/")}/hooks/${a}`:`@/hooks/${a}`;l(Ee.dim(` import { ${a} } from '${x}';`)),l("")}catch(n){y.fail("Hook generation failed"),v(`${n}`),process.exit(1)}})},Pc=(e,r)=>e.noTest?!1:e.test?!0:r;import Pt from"picocolors";L();var Wo=e=>{e.command("layout <segment>").description("Generate a nested layout.tsx (locale-aware when i18n is detected)").option("--group","Treat the segment as a route group (wraps it in parens)").option("--at <path>","Place the layout under this nested path (kebab-case, slash-separated)").option("--no-locale","Skip the locale wrapper even if i18n is detected").action(async(r,t)=>{try{let n=process.cwd();l(Pt.cyan(`
982
1002
  \u{1F4D0} Layout Generator
983
- `)),x.start("Detecting project setup...");let i=await I(n);x.succeed("Project setup detected");let o=i.hasI18n&&t.locale!==!1;l(Pt.dim(` i18n: ${o?"\u2713":"\u2717"}
984
- `)),x.start("Generating layout...");let s=await Ut({segment:r,at:t.at,projectPath:n,hasI18n:o,withGroup:!!t.group});x.succeed("Layout generated"),l(Pt.green(`
1003
+ `)),y.start("Detecting project setup...");let o=await I(n);y.succeed("Project setup detected");let i=o.hasI18n&&t.locale!==!1;l(Pt.dim(` i18n: ${i?"\u2713":"\u2717"}
1004
+ `)),y.start("Generating layout...");let s=await zt({segment:r,at:t.at,projectPath:n,hasI18n:i,withGroup:!!t.group});y.succeed("Layout generated"),l(Pt.green(`
985
1005
  \u2728 ${s.componentName} created!
986
- `)),l(Pt.dim(` \u{1F4C4} ${s.displayPath}`)),l("")}catch(n){x.fail("Layout generation failed"),v(`${n instanceof Error?n.message:n}`),process.exit(1)}})};import fc from"node:path";import W from"picocolors";P();L();import dc from"enquirer";var{prompt:uc}=dc,qo=async(e,r={})=>{let t=[];e||t.push({type:"input",name:"code",message:"Locale code (e.g., es, fr, de):",validate:i=>i?/^[a-z]{2}(-[A-Z]{2})?$/.test(i)?!0:"Use format: xx or xx-XX (e.g., es, pt-BR)":"Locale code is required"}),t.push({type:"input",name:"name",message:"Language name (e.g., Spanish, French):",validate:i=>i?!0:"Language name is required"},{type:"input",name:"country",message:"Country (e.g., Spain, France):",validate:i=>i?!0:"Country is required"},{type:"input",name:"flag",message:"Flag emoji (e.g., \u{1F1EA}\u{1F1F8}, \u{1F1EB}\u{1F1F7}):",validate:i=>i?!0:"Flag emoji is required"}),r.copyTranslations===void 0&&t.push({type:"confirm",name:"copyTranslations",message:"Copy translations from English? (No = empty values)",initial:!1});let n=await uc(t);return{code:e??n.code,name:n.name,country:n.country,flag:n.flag,copyTranslations:r.copyTranslations??n.copyTranslations??!1}};var Wo=e=>{e.command("locale [code]").description("Add a new locale/language").option("--copy-translations","Copy translations from English instead of empty values").action(async(r,t)=>{try{let n=process.cwd();l(W.cyan(`
1006
+ `)),l(Pt.dim(` \u{1F4C4} ${s.displayPath}`)),l("")}catch(n){y.fail("Layout generation failed"),v(`${n instanceof Error?n.message:n}`),process.exit(1)}})};import wc from"node:path";import Z from"picocolors";P();L();import vc from"enquirer";var{prompt:Sc}=vc,Zo=async(e,r={})=>{let t=[];e||t.push({type:"input",name:"code",message:"Locale code (e.g., es, fr, de):",validate:o=>o?/^[a-z]{2}(-[A-Z]{2})?$/.test(o)?!0:"Use format: xx or xx-XX (e.g., es, pt-BR)":"Locale code is required"}),t.push({type:"input",name:"name",message:"Language name (e.g., Spanish, French):",validate:o=>o?!0:"Language name is required"},{type:"input",name:"country",message:"Country (e.g., Spain, France):",validate:o=>o?!0:"Country is required"},{type:"input",name:"flag",message:"Flag emoji (e.g., \u{1F1EA}\u{1F1F8}, \u{1F1EB}\u{1F1F7}):",validate:o=>o?!0:"Flag emoji is required"}),r.copyTranslations===void 0&&t.push({type:"confirm",name:"copyTranslations",message:"Copy translations from English? (No = empty values)",initial:!1});let n=await Sc(t);return{code:e??n.code,name:n.name,country:n.country,flag:n.flag,copyTranslations:r.copyTranslations??n.copyTranslations??!1}};var Qo=e=>{e.command("locale [code]").description("Add a new locale/language").option("--copy-translations","Copy translations from English instead of empty values").action(async(r,t)=>{try{let n=process.cwd();l(Z.cyan(`
987
1007
  \u{1F30D} Locale Generator
988
- `)),x.start("Detecting project setup...");let i=await I(n);x.succeed("Project setup detected"),i.hasI18n||(x.fail("i18n is not set up in this project"),v("Please set up internationalization first"),l(W.dim(`
1008
+ `)),y.start("Detecting project setup...");let o=await I(n);y.succeed("Project setup detected"),o.hasI18n||(y.fail("i18n is not set up in this project"),v("Please set up internationalization first"),l(Z.dim(`
989
1009
  Run: npx @teispace/next-maker setup --i18n
990
- `)),process.exit(1));let o=await qo(r,{copyTranslations:t.copyTranslations}),s=fc.join(n,"src","i18n","translations",`${o.code}.json`);m(s)&&(v(`Locale '${o.code}' already exists!`),process.exit(1)),x.start("Adding locale..."),await zt({...o,projectPath:n}),x.succeed("Locale added"),l(W.green(`
991
- \u2728 Locale '${o.code}' (${o.name}) added successfully!
992
- `)),l(W.dim("Updated files:")),l(W.dim(` \u{1F4C4} src/i18n/translations/${o.code}.json`)),l(W.dim(" \u{1F4DD} src/types/i18n.ts (SupportedLocale type)")),l(W.dim(" \u{1F4DD} src/lib/config/app-locales.ts")),l(""),l(W.cyan("Next steps:")),l(W.dim(` 1. Translate: src/i18n/translations/${o.code}.json`)),l(W.dim(` 2. Visit: http://localhost:3000/${o.code}`)),l("")}catch(n){x.fail("Locale generation failed"),v(`${n}`),process.exit(1)}})};import Qo from"node:path";import J from"picocolors";L();import gc from"enquirer";var{prompt:hc}=gc,Zo=async(e,r={})=>{let t=[];e||t.push({type:"input",name:"pageName",message:"Page name (kebab-case):",validate:i=>i?/^[a-z][a-z0-9-]*$/.test(i)?!0:"Use lowercase letters, numbers, and hyphens only":"Page name is required"}),r.loading===void 0&&t.push({type:"confirm",name:"withLoading",message:"Generate loading.tsx?",initial:!0}),r.error===void 0&&t.push({type:"confirm",name:"withError",message:"Generate error.tsx?",initial:!0});let n=t.length>0?await hc(t):{};return{pageName:e??n.pageName,withLoading:r.loading??n.withLoading??!0,withError:r.error??n.withError??!0}};var ei=e=>{e.command("page [name]").description("Generate a new page/route").option("--dynamic <param>","Create dynamic route with parameter (e.g., id)").option("--loading","Generate loading.tsx").option("--error","Generate error.tsx").action(async(r,t)=>{try{let n=process.cwd();l(J.cyan(`
1010
+ `)),process.exit(1));let i=await Zo(r,{copyTranslations:t.copyTranslations}),s=wc.join(n,"src","i18n","translations",`${i.code}.json`);m(s)&&(v(`Locale '${i.code}' already exists!`),process.exit(1)),y.start("Adding locale..."),await Vt({...i,projectPath:n}),y.succeed("Locale added"),l(Z.green(`
1011
+ \u2728 Locale '${i.code}' (${i.name}) added successfully!
1012
+ `)),l(Z.dim("Updated files:")),l(Z.dim(` \u{1F4C4} src/i18n/translations/${i.code}.json`)),l(Z.dim(" \u{1F4DD} src/types/i18n.ts (SupportedLocale type)")),l(Z.dim(" \u{1F4DD} src/lib/config/app-locales.ts")),l(""),l(Z.cyan("Next steps:")),l(Z.dim(` 1. Translate: src/i18n/translations/${i.code}.json`)),l(Z.dim(` 2. Visit: http://localhost:3000/${i.code}`)),l("")}catch(n){y.fail("Locale generation failed"),v(`${n}`),process.exit(1)}})};import ti from"node:path";import B from"picocolors";L();import Cc from"enquirer";var{prompt:Tc}=Cc,ei=async(e,r={})=>{let t=[];e||t.push({type:"input",name:"pageName",message:"Page name (kebab-case):",validate:o=>o?/^[a-z][a-z0-9-]*$/.test(o)?!0:"Use lowercase letters, numbers, and hyphens only":"Page name is required"}),r.loading===void 0&&t.push({type:"confirm",name:"withLoading",message:"Generate loading.tsx?",initial:!0}),r.error===void 0&&t.push({type:"confirm",name:"withError",message:"Generate error.tsx?",initial:!0});let n=t.length>0?await Tc(t):{};return{pageName:e??n.pageName,withLoading:r.loading??n.withLoading??!0,withError:r.error??n.withError??!0}};var ri=e=>{e.command("page [name]").description("Generate a new page/route").option("--dynamic <param>","Create dynamic route with parameter (e.g., id)").option("--loading","Generate loading.tsx").option("--error","Generate error.tsx").action(async(r,t)=>{try{let n=process.cwd();l(B.cyan(`
993
1013
  \u{1F4C4} Page Generator
994
- `)),x.start("Detecting project setup...");let i=await I(n);x.succeed("Project setup detected"),l(J.dim(` i18n: ${i.hasI18n?"\u2713":"\u2717"}
995
- `));let o=await Zo(r,{loading:t.loading,error:t.error}),s=o.pageName,a=$(s),p=i.hasI18n?"src/app/[locale]":"src/app";await ie(n,s,p)&&(v(`Page '${s}' already exists at ${p}/${s}!`),process.exit(1)),x.start("Generating page files..."),await Jt({name:s,projectPath:n,hasI18n:i.hasI18n,dynamic:t.dynamic,withLoading:t.loading??o.withLoading,withError:t.error??o.withError}),x.succeed("Page files generated"),x.start("Registering route...");let g=t.dynamic?`/${s}/[${t.dynamic}]`:`/${s}`;await lr(n,s,g),x.succeed("Route registered"),i.hasI18n&&(x.start("Adding translation namespace..."),await dr(n,a),x.succeed("Translation namespace added"));let h=t.dynamic?Qo.join(p,s,`[${t.dynamic}]`):Qo.join(p,s);l(J.green(`
1014
+ `)),y.start("Detecting project setup...");let o=await I(n);y.succeed("Project setup detected"),l(B.dim(` i18n: ${o.hasI18n?"\u2713":"\u2717"}
1015
+ `));let i=await ei(r,{loading:t.loading,error:t.error}),s=i.pageName,a=$(s),p=o.hasI18n?"src/app/[locale]":"src/app";await ie(n,s,p)&&(v(`Page '${s}' already exists at ${p}/${s}!`),process.exit(1)),y.start("Generating page files..."),await Bt({name:s,projectPath:n,hasI18n:o.hasI18n,dynamic:t.dynamic,withLoading:t.loading??i.withLoading,withError:t.error??i.withError}),y.succeed("Page files generated"),y.start("Registering route...");let g=t.dynamic?`/${s}/[${t.dynamic}]`:`/${s}`;await mr(n,s,g),y.succeed("Route registered"),o.hasI18n&&(y.start("Adding translation namespace..."),await ur(n,a),y.succeed("Translation namespace added"));let h=t.dynamic?ti.join(p,s,`[${t.dynamic}]`):ti.join(p,s);l(B.green(`
996
1016
  \u2728 Page '${s}' created successfully!
997
- `)),l(J.dim("Generated files:")),l(J.dim(` \u{1F4C2} ${h}/`)),l(J.dim(" \u251C\u2500\u2500 page.tsx")),(t.loading??o.withLoading)&&l(J.dim(" \u251C\u2500\u2500 loading.tsx")),(t.error??o.withError)&&l(J.dim(" \u2514\u2500\u2500 error.tsx")),l(""),i.hasI18n&&(l(J.cyan("Next steps:")),l(J.dim(` 1. Add translations in: src/i18n/translations/en.json \u2192 "${a}"`)),l(J.dim(` 2. Visit: http://localhost:3000/${s}`)),l(""))}catch(n){x.fail("Page generation failed"),v(`${n}`),process.exit(1)}})};import yr from"node:path";import pe from"picocolors";var ti=e=>{e.command("provider <name>").description("Generate a context provider in src/providers/ and wire it into RootProvider").action(async r=>{try{let t=process.cwd();l(pe.cyan(`
1017
+ `)),l(B.dim("Generated files:")),l(B.dim(` \u{1F4C2} ${h}/`)),l(B.dim(" \u251C\u2500\u2500 page.tsx")),(t.loading??i.withLoading)&&l(B.dim(" \u251C\u2500\u2500 loading.tsx")),(t.error??i.withError)&&l(B.dim(" \u2514\u2500\u2500 error.tsx")),l(""),o.hasI18n&&(l(B.cyan("Next steps:")),l(B.dim(` 1. Add translations in: src/i18n/translations/en.json \u2192 "${a}"`)),l(B.dim(` 2. Visit: http://localhost:3000/${s}`)),l(""))}catch(n){y.fail("Page generation failed"),v(`${n}`),process.exit(1)}})};import Pr from"node:path";import pe from"picocolors";var ni=e=>{e.command("provider <name>").description("Generate a context provider in src/providers/ and wire it into RootProvider").action(async r=>{try{let t=process.cwd();l(pe.cyan(`
998
1018
  \u{1F50C} Provider Generator
999
- `)),x.start("Generating provider...");let{componentName:n,fileBaseName:i,providerFile:o}=await Xt({name:r,projectPath:t});x.succeed("Provider generated"),x.start("Registering provider in RootProvider and barrel...");let{rootProviderFile:s,barrelFile:a}=await mr({projectPath:t,componentName:n,fileBaseName:i});x.succeed("Provider registered"),l(pe.green(`
1019
+ `)),y.start("Generating provider...");let{componentName:n,fileBaseName:o,providerFile:i}=await Yt({name:r,projectPath:t});y.succeed("Provider generated"),y.start("Registering provider in RootProvider and barrel...");let{rootProviderFile:s,barrelFile:a}=await dr({projectPath:t,componentName:n,fileBaseName:o});y.succeed("Provider registered"),l(pe.green(`
1000
1020
  \u2728 ${n} created!
1001
- `)),l(pe.dim("Generated files:")),l(pe.dim(` \u{1F4C4} ${yr.relative(t,o)}`)),s?l(pe.dim(` \u270F\uFE0F ${yr.relative(t,s)} \u2014 wrapped {children}`)):(l(pe.yellow(`
1002
- \u26A0\uFE0F Could not locate a RootProvider file. Wire the new provider manually:`)),l(pe.dim(` <${n}>{children}</${n}>`))),a&&l(pe.dim(` \u270F\uFE0F ${yr.relative(t,a)} \u2014 added re-export`)),l("")}catch(t){x.fail("Provider generation failed"),v(`${t instanceof Error?t.message:t}`),process.exit(1)}})};import xc from"enquirer";import M from"picocolors";var{prompt:yc}=xc,Pc=e=>{let r=[];for(let t of e.filesRemoved)r.push(` ${M.red("-")} delete: ${t}`);for(let t of e.blocksStripped)r.push(` ${M.red("-")} strip block: ${t.description} ${M.dim(`(${t.file})`)}`);for(let t of e.scriptsRemoved)r.push(` ${M.red("-")} remove script: ${t}`);for(let t of e.packagesUninstalled)r.push(` ${M.red("-")} uninstall: ${t}`);for(let t of e.manualCleanup)r.push(` ${M.yellow("?")} manual cleanup: ${t.description} ${M.dim(`(${t.file})`)}`);return r},vc=e=>e.filesRemoved.length===0&&e.blocksStripped.length===0&&e.scriptsRemoved.length===0&&e.packagesUninstalled.length===0&&e.manualCleanup.length===0,ri=e=>{e.command("remove <feature>").alias("uninstall").description("Reverse a feature install (uses the feature manifest)").option("-y, --yes","Skip confirmation prompt").option("--dry-run","Show what would change without writing").action(async(r,t)=>{try{let n=process.cwd(),i=ko(r);if(!i)throw new Error(`Unknown feature "${r}". Valid: ${xe.map(p=>p.id).join(", ")}.`);if(l(M.cyan(`
1003
- \u{1F5D1} Remove ${i.name}
1004
- `)),!(await Ke(i,n)).installed){l(M.dim(`${i.name} is not installed \u2014 nothing to remove.`));return}x.start("Computing changes...");let s=await xt(i,n,{dryRun:!0});if(x.succeed("Computed plan"),vc(s)){l(M.yellow(`
1021
+ `)),l(pe.dim("Generated files:")),l(pe.dim(` \u{1F4C4} ${Pr.relative(t,i)}`)),s?l(pe.dim(` \u270F\uFE0F ${Pr.relative(t,s)} \u2014 wrapped {children}`)):(l(pe.yellow(`
1022
+ \u26A0\uFE0F Could not locate a RootProvider file. Wire the new provider manually:`)),l(pe.dim(` <${n}>{children}</${n}>`))),a&&l(pe.dim(` \u270F\uFE0F ${Pr.relative(t,a)} \u2014 added re-export`)),l("")}catch(t){y.fail("Provider generation failed"),v(`${t instanceof Error?t.message:t}`),process.exit(1)}})};import Ec from"enquirer";import M from"picocolors";var{prompt:Rc}=Ec,$c=e=>{let r=[];for(let t of e.filesRemoved)r.push(` ${M.red("-")} delete: ${t}`);for(let t of e.blocksStripped)r.push(` ${M.red("-")} strip block: ${t.description} ${M.dim(`(${t.file})`)}`);for(let t of e.scriptsRemoved)r.push(` ${M.red("-")} remove script: ${t}`);for(let t of e.packagesUninstalled)r.push(` ${M.red("-")} uninstall: ${t}`);for(let t of e.manualCleanup)r.push(` ${M.yellow("?")} manual cleanup: ${t.description} ${M.dim(`(${t.file})`)}`);return r},bc=e=>e.filesRemoved.length===0&&e.blocksStripped.length===0&&e.scriptsRemoved.length===0&&e.packagesUninstalled.length===0&&e.manualCleanup.length===0,oi=e=>{e.command("remove <feature>").alias("uninstall").description("Reverse a feature install (uses the feature manifest)").option("-y, --yes","Skip confirmation prompt").option("--dry-run","Show what would change without writing").action(async(r,t)=>{try{let n=process.cwd(),o=_o(r);if(!o)throw new Error(`Unknown feature "${r}". Valid: ${ye.map(p=>p.id).join(", ")}.`);if(l(M.cyan(`
1023
+ \u{1F5D1} Remove ${o.name}
1024
+ `)),!(await Ke(o,n)).installed){l(M.dim(`${o.name} is not installed \u2014 nothing to remove.`));return}y.start("Computing changes...");let s=await yt(o,n,{dryRun:!0});if(y.succeed("Computed plan"),bc(s)){l(M.yellow(`
1005
1025
  \u26A0\uFE0F Manifest had no removable artifacts. Nothing to do.
1006
1026
  `));return}l(M.bold(`
1007
1027
  Planned changes:
1008
- `));for(let p of Pc(s))l(p);if(l(""),t.dryRun){l(M.dim(`--dry-run set \u2014 exiting without writing.
1009
- `));return}if(!t.yes){let{confirm:p}=await yc({type:"confirm",name:"confirm",message:`Apply the changes above to remove ${i.name}?`,initial:!1});if(!p){l(M.yellow(`
1028
+ `));for(let p of $c(s))l(p);if(l(""),t.dryRun){l(M.dim(`--dry-run set \u2014 exiting without writing.
1029
+ `));return}if(!t.yes){let{confirm:p}=await Rc({type:"confirm",name:"confirm",message:`Apply the changes above to remove ${o.name}?`,initial:!1});if(!p){l(M.yellow(`
1010
1030
  Aborted.
1011
- `));return}}x.start(`Removing ${i.name}...`);let a=i.remove?(await i.remove(n),s):await xt(i,n);if(x.succeed(`${i.name} removed`),l(M.green(`
1012
- \u2713 ${i.name} removed.`)),a.manualCleanup.length>0){l(M.yellow(`
1013
- \u26A0\uFE0F Manual cleanup still required:`));for(let p of a.manualCleanup)l(` - ${p.description} (${p.file})`)}l("")}catch(n){x.fail("Remove failed"),v(`${n instanceof Error?n.message:n}`),process.exit(1)}})};import{existsSync as Tc}from"node:fs";import{mkdir as Ec}from"node:fs/promises";import et from"node:path";import B from"picocolors";L();import{readFile as Sc,writeFile as wc}from"node:fs/promises";import Cc from"node:path";var ni=async(e,r)=>{let t=A(r),n=Cc.join(e,"src","lib","config","app-apis.ts");try{let i=await Sc(n,"utf-8");if(i.includes(`${t}:`))return;if(!i.match(/export const AppApis = \{[\s\S]*?\} as const;/))throw new Error("Could not find AppApis object in app-apis.ts");let o=sn({camelName:t,kebabName:r});i=We(i,o),await wc(n,i)}catch(i){throw new Error(`Failed to register CRUD API endpoints: ${i}`,{cause:i})}};import oi from"enquirer";var ii=async(e,r,t,n)=>{let i=e||(await oi.prompt({type:"input",name:"serviceName",message:"Service name (kebab-case):",validate:s=>s?/^[a-z0-9-]+$/.test(s)?!0:"Service name must be lowercase with hyphens only":"Service name is required"})).serviceName,o;return r!==void 0?o="axios":t!==void 0?o="fetch":n==="axios"?o="axios":n==="fetch"?o="fetch":n==="both"?o=(await oi.prompt({type:"select",name:"httpClient",message:"Choose HTTP client:",choices:["axios","fetch"]})).httpClient:o="axios",{serviceName:i,httpClient:o}};var si=e=>{e.command("service [name]").description("Generate an API service").option("--path <path>","Custom path for service generation (default: create new feature)").option("--axios","Use Axios HTTP client").option("--fetch","Use Fetch HTTP client").option("--crud","Generate full CRUD service (getAll, getById, create, update, delete)").action(async(r,t)=>{try{let n=process.cwd();t.axios&&t.fetch&&(v("Cannot use --axios and --fetch together"),process.exit(1)),l(B.cyan(`
1031
+ `));return}}y.start(`Removing ${o.name}...`);let a=o.remove?(await o.remove(n),s):await yt(o,n);if(y.succeed(`${o.name} removed`),l(M.green(`
1032
+ \u2713 ${o.name} removed.`)),a.manualCleanup.length>0){l(M.yellow(`
1033
+ \u26A0\uFE0F Manual cleanup still required:`));for(let p of a.manualCleanup)l(` - ${p.description} (${p.file})`)}l("")}catch(n){y.fail("Remove failed"),v(`${n instanceof Error?n.message:n}`),process.exit(1)}})};import{existsSync as kc}from"node:fs";import{mkdir as Oc}from"node:fs/promises";import et from"node:path";import X from"picocolors";L();import{readFile as Nc,writeFile as Ic}from"node:fs/promises";import Ac from"node:path";var ii=async(e,r)=>{let t=A(r),n=Ac.join(e,"src","lib","config","app-apis.ts");try{let o=await Nc(n,"utf-8");if(o.includes(`${t}:`))return;if(!o.match(/export const AppApis = \{[\s\S]*?\} as const;/))throw new Error("Could not find AppApis object in app-apis.ts");let i=cn({camelName:t,kebabName:r});o=We(o,i),await Ic(n,o)}catch(o){throw new Error(`Failed to register CRUD API endpoints: ${o}`,{cause:o})}};import si from"enquirer";var ai=async(e,r,t,n)=>{let o=e||(await si.prompt({type:"input",name:"serviceName",message:"Service name (kebab-case):",validate:s=>s?/^[a-z0-9-]+$/.test(s)?!0:"Service name must be lowercase with hyphens only":"Service name is required"})).serviceName,i;return r!==void 0?i="axios":t!==void 0?i="fetch":n==="axios"?i="axios":n==="fetch"?i="fetch":n==="both"?i=(await si.prompt({type:"select",name:"httpClient",message:"Choose HTTP client:",choices:["axios","fetch"]})).httpClient:i="axios",{serviceName:o,httpClient:i}};var ci=e=>{e.command("service [name]").description("Generate an API service").option("--path <path>","Custom path for service generation (default: create new feature)").option("--axios","Use Axios HTTP client").option("--fetch","Use Fetch HTTP client").option("--crud","Generate full CRUD service (getAll, getById, create, update, delete)").action(async(r,t)=>{try{let n=process.cwd();t.axios&&t.fetch&&(v("Cannot use --axios and --fetch together"),process.exit(1)),l(X.cyan(`
1014
1034
  \u{1F527} Service Generator
1015
- `)),x.start("Detecting project setup...");let i=await I(n);x.succeed("Project setup detected"),i.httpClient==="none"&&(x.fail("No HTTP client is setup in this project"),v("Please setup either AxiosClient or FetchClient first"),l(B.dim(`
1035
+ `)),y.start("Detecting project setup...");let o=await I(n);y.succeed("Project setup detected"),o.httpClient==="none"&&(y.fail("No HTTP client is setup in this project"),v("Please setup either AxiosClient or FetchClient first"),l(X.dim(`
1016
1036
  Check: lib/utils/http/axios-client or lib/utils/http/fetch-client
1017
- `)),process.exit(1));let o=[];(i.httpClient==="axios"||i.httpClient==="both")&&o.push("Axios \u2713"),(i.httpClient==="fetch"||i.httpClient==="both")&&o.push("Fetch \u2713"),l(B.dim(` HTTP Clients: ${o.join(", ")}
1018
- `));let s=await ii(r,t.axios,t.fetch,i.httpClient),{basePath:a,servicePath:p}=Rc(n,s.serviceName,t.path);Tc(p)||await Ec(p,{recursive:!0}),at(n,a,`${s.serviceName}.service.ts`)&&(v(`Service '${s.serviceName}' already exists at ${a}!`),process.exit(1)),t.crud?(x.start("Generating CRUD service files..."),await Lt({name:s.serviceName,outputPath:p,httpClient:s.httpClient}),x.succeed("CRUD service files generated"),x.start("Registering CRUD API endpoints..."),await ni(n,s.serviceName),x.succeed("CRUD API endpoints registered")):await ye(fr(),{projectPath:n,spinner:x,serviceName:s.serviceName,servicePath:p,httpClient:s.httpClient}),$c(s,a,!!t.crud)}catch(n){x.fail("Service generation failed"),v(`${n}`),process.exit(1)}})},Rc=(e,r,t)=>{let n;if(t){let i=t.replace(/^src\//,"");if(i.startsWith("features/")){let o=i.split("/")[1];n=et.join("src","features",o,"services")}else n=et.join("src",i)}else n=et.join("src","features",r,"services");return{basePath:n,servicePath:et.join(e,n)}},$c=(e,r,t=!1)=>{let n=et.join(r,`${e.serviceName}.service.ts`);l(B.green(`
1037
+ `)),process.exit(1));let i=[];(o.httpClient==="axios"||o.httpClient==="both")&&i.push("Axios \u2713"),(o.httpClient==="fetch"||o.httpClient==="both")&&i.push("Fetch \u2713"),l(X.dim(` HTTP Clients: ${i.join(", ")}
1038
+ `));let s=await ai(r,t.axios,t.fetch,o.httpClient),{basePath:a,servicePath:p}=_c(n,s.serviceName,t.path);kc(p)||await Oc(p,{recursive:!0}),at(n,a,`${s.serviceName}.service.ts`)&&(v(`Service '${s.serviceName}' already exists at ${a}!`),process.exit(1)),t.crud?(y.start("Generating CRUD service files..."),await Mt({name:s.serviceName,outputPath:p,httpClient:s.httpClient}),y.succeed("CRUD service files generated"),y.start("Registering CRUD API endpoints..."),await ii(n,s.serviceName),y.succeed("CRUD API endpoints registered")):await xe(gr(),{projectPath:n,spinner:y,serviceName:s.serviceName,servicePath:p,httpClient:s.httpClient}),Fc(s,a,!!t.crud)}catch(n){y.fail("Service generation failed"),v(`${n}`),process.exit(1)}})},_c=(e,r,t)=>{let n;if(t){let o=t.replace(/^src\//,"");if(o.startsWith("features/")){let i=o.split("/")[1];n=et.join("src","features",i,"services")}else n=et.join("src",o)}else n=et.join("src","features",r,"services");return{basePath:n,servicePath:et.join(e,n)}},Fc=(e,r,t=!1)=>{let n=et.join(r,`${e.serviceName}.service.ts`);l(X.green(`
1019
1039
  \u2728 ${t?"CRUD ":""}Service '${e.serviceName}' created successfully!
1020
- `)),l(B.dim("Generated files:")),l(B.dim(` \u{1F4C4} ${n}
1021
- `)),l(B.cyan("Next steps:"));let i=r.replace(/^src\//,"@/");l(B.dim(` 1. Import service: import { ${e.serviceName}Service } from '${i}/${e.serviceName}.service'`)),t?(l(B.dim(" 2. Available methods: getAll, getById, create, update, delete")),l(B.dim(" 3. Update DTO types in the service file"))):l(B.dim(` 2. Use in component: const data = await ${e.serviceName}Service.getAll()`)),l("")};import bc from"enquirer";import Pr from"picocolors";var{prompt:Nc}=bc,ai=e=>{e.command("setup").description("Setup features in an existing Next.js project").option("--http-client","Setup HTTP client (axios|fetch)").option("--dark-theme","Setup Dark Theme (Tailwind + @teispace/next-themes)").option("--redux","Setup Redux Toolkit").option("--i18n","Setup next-intl for internationalization").option("--tests","Setup testing (Vitest + React Testing Library)").option("--react-compiler","Enable the React Compiler").option("--bundle-analyzer","Add @next/bundle-analyzer").option("--security-headers","Add hardened HTTP headers to next.config.ts").option("--validate-scripts","Add scripts/sync-env.ts, scripts/check-deprecated.ts, and the validate chain").option("--commitizen","Add Commitizen with the conventional-changelog adapter").action(async r=>{try{if(l(Pr.cyan(`
1040
+ `)),l(X.dim("Generated files:")),l(X.dim(` \u{1F4C4} ${n}
1041
+ `)),l(X.cyan("Next steps:"));let o=r.replace(/^src\//,"@/");l(X.dim(` 1. Import service: import { ${e.serviceName}Service } from '${o}/${e.serviceName}.service'`)),t?(l(X.dim(" 2. Available methods: getAll, getById, create, update, delete")),l(X.dim(" 3. Update DTO types in the service file"))):l(X.dim(` 2. Use in component: const data = await ${e.serviceName}Service.getAll()`)),l("")};import jc from"enquirer";import vr from"picocolors";var{prompt:Dc}=jc,pi=e=>{e.command("setup").description("Setup features in an existing Next.js project").option("--http-client","Setup HTTP client (axios|fetch)").option("--dark-theme","Setup Dark Theme (Tailwind + @teispace/next-themes)").option("--redux","Setup Redux Toolkit").option("--i18n","Setup next-intl for internationalization").option("--tests","Setup testing (Vitest + React Testing Library)").option("--react-compiler","Enable the React Compiler").option("--bundle-analyzer","Add @next/bundle-analyzer").option("--security-headers","Add hardened HTTP headers to next.config.ts").option("--validate-scripts","Add scripts/sync-env.ts, scripts/check-deprecated.ts, and the validate chain").option("--commitizen","Add Commitizen with the conventional-changelog adapter").action(async r=>{try{if(l(vr.cyan(`
1022
1042
  \u{1F527} Setup Wizard
1023
- `)),r.httpClient||r.darkTheme||r.redux||r.i18n||r.tests||r.reactCompiler||r.bundleAnalyzer||r.securityHeaders||r.validateScripts||r.commitizen){r.httpClient&&await Ue(process.cwd()),r.darkTheme&&await Ge(process.cwd()),r.redux&&await Je(process.cwd()),r.i18n&&await ze(process.cwd()),r.tests&&await Xe(process.cwd()),r.reactCompiler&&await Ve(process.cwd()),r.bundleAnalyzer&&await De(process.cwd()),r.securityHeaders&&await Be(process.cwd()),r.validateScripts&&await Ye(process.cwd()),r.commitizen&&await Le(process.cwd());return}let i=(await Nc([{type:"select",name:"feature",message:"What would you like to setup?",choices:[{name:"Dark Theme",value:"dark-theme"},{name:"Redux Toolkit",value:"redux"},{name:"HTTP Client (Axios/Fetch)",value:"http-client"},{name:"Internationalization (next-intl)",value:"i18n"},{name:"Testing (Vitest + RTL)",value:"tests"},{name:"React Compiler",value:"react-compiler"},{name:"Bundle Analyzer",value:"bundle-analyzer"},{name:"Security Headers",value:"security-headers"},{name:"Validation Scripts",value:"validate-scripts"},{name:"Commitizen",value:"commitizen"},"Cancel"]}])).feature;if(i==="Cancel"){l(Pr.yellow("Setup cancelled."));return}let s={"dark-theme":Ge,redux:Je,"http-client":Ue,i18n:ze,tests:Xe,"react-compiler":Ve,"bundle-analyzer":De,"security-headers":Be,"validate-scripts":Ye,commitizen:Le}[i];s?await s(process.cwd()):l(Pr.yellow(`
1024
- \u26A0\uFE0F ${i} setup is not implemented yet.`))}catch(t){x.fail("Setup failed"),v(`${t}`),process.exit(1)}})};import{existsSync as kc}from"node:fs";import{mkdir as Oc}from"node:fs/promises";import le from"node:path";import G from"picocolors";L();import Ic from"enquirer";var{prompt:Ac}=Ic,ci=async(e,r,t)=>{let n=[];e||n.push({type:"input",name:"sliceName",message:"What is the slice name?",initial:"my-slice",validate:o=>/^[a-z0-9-]+$/.test(o)?!0:"Slice name must be lowercase and contain only alphanumeric characters and hyphens."}),r===void 0&&t===void 0&&n.push({type:"confirm",name:"persistSlice",message:"Enable persistence for this slice?",initial:!1});let i=n.length>0?await Ac(n):{};return{sliceName:e||i.sliceName,persistSlice:r===!0?!0:t===!1?!1:i.persistSlice||!1}};var pi=e=>{e.command("slice [name]").description("Generate a Redux slice").option("--path <path>","Custom path for slice generation (default: create new feature)").option("--persist","Enable persistence for this slice").option("--no-persist","Disable persistence for this slice").option("--test","Also generate a sibling test file").option("--no-test","Skip test file generation").action(async(r,t)=>{try{let n=process.cwd();t.persist&&t.noPersist===!0&&(v("Cannot use --persist and --no-persist together"),process.exit(1)),l(G.cyan(`
1043
+ `)),r.httpClient||r.darkTheme||r.redux||r.i18n||r.tests||r.reactCompiler||r.bundleAnalyzer||r.securityHeaders||r.validateScripts||r.commitizen){r.httpClient&&await Ue(process.cwd()),r.darkTheme&&await Ge(process.cwd()),r.redux&&await Je(process.cwd()),r.i18n&&await ze(process.cwd()),r.tests&&await Xe(process.cwd()),r.reactCompiler&&await Ve(process.cwd()),r.bundleAnalyzer&&await De(process.cwd()),r.securityHeaders&&await Be(process.cwd()),r.validateScripts&&await Ye(process.cwd()),r.commitizen&&await Le(process.cwd());return}let o=(await Dc([{type:"select",name:"feature",message:"What would you like to setup?",choices:[{name:"Dark Theme",value:"dark-theme"},{name:"Redux Toolkit",value:"redux"},{name:"HTTP Client (Axios/Fetch)",value:"http-client"},{name:"Internationalization (next-intl)",value:"i18n"},{name:"Testing (Vitest + RTL)",value:"tests"},{name:"React Compiler",value:"react-compiler"},{name:"Bundle Analyzer",value:"bundle-analyzer"},{name:"Security Headers",value:"security-headers"},{name:"Validation Scripts",value:"validate-scripts"},{name:"Commitizen",value:"commitizen"},"Cancel"]}])).feature;if(o==="Cancel"){l(vr.yellow("Setup cancelled."));return}let s={"dark-theme":Ge,redux:Je,"http-client":Ue,i18n:ze,tests:Xe,"react-compiler":Ve,"bundle-analyzer":De,"security-headers":Be,"validate-scripts":Ye,commitizen:Le}[o];s?await s(process.cwd()):l(vr.yellow(`
1044
+ \u26A0\uFE0F ${o} setup is not implemented yet.`))}catch(t){y.fail("Setup failed"),v(`${t}`),process.exit(1)}})};import{existsSync as Gc}from"node:fs";import{mkdir as Hc}from"node:fs/promises";import le from"node:path";import G from"picocolors";L();import Lc from"enquirer";var{prompt:Mc}=Lc,li=async(e,r,t)=>{let n=[];e||n.push({type:"input",name:"sliceName",message:"What is the slice name?",initial:"my-slice",validate:i=>/^[a-z0-9-]+$/.test(i)?!0:"Slice name must be lowercase and contain only alphanumeric characters and hyphens."}),r===void 0&&t===void 0&&n.push({type:"confirm",name:"persistSlice",message:"Enable persistence for this slice?",initial:!1});let o=n.length>0?await Mc(n):{};return{sliceName:e||o.sliceName,persistSlice:r===!0?!0:t===!1?!1:o.persistSlice||!1}};var mi=e=>{e.command("slice [name]").description("Generate a Redux slice").option("--path <path>","Custom path for slice generation (default: create new feature)").option("--persist","Enable persistence for this slice").option("--no-persist","Disable persistence for this slice").option("--test","Also generate a sibling test file").option("--no-test","Skip test file generation").action(async(r,t)=>{try{let n=process.cwd();t.persist&&t.noPersist===!0&&(v("Cannot use --persist and --no-persist together"),process.exit(1)),l(G.cyan(`
1025
1045
  \u{1F527} Slice Generator
1026
- `)),x.start("Detecting project setup...");let i=await I(n);x.succeed("Project setup detected"),i.hasRedux||(x.fail("Redux is not setup in this project"),v("Please install @reduxjs/toolkit and react-redux first"),l(G.dim(`
1046
+ `)),y.start("Detecting project setup...");let o=await I(n);y.succeed("Project setup detected"),o.hasRedux||(y.fail("Redux is not setup in this project"),v("Please install @reduxjs/toolkit and react-redux first"),l(G.dim(`
1027
1047
  Run: npm install @reduxjs/toolkit react-redux
1028
1048
  `)),process.exit(1)),l(G.dim(` Redux: \u2713
1029
- `));let o=await ci(r,t.persist,t.noPersist===!0?!1:void 0),{basePath:s,slicePath:a}=_c(n,o.sliceName,t.path),p=le.join(n,s);kc(p)||await Oc(p,{recursive:!0}),await ie(n,o.sliceName,s)&&(v(`Slice '${o.sliceName}' already exists at ${s}!`),process.exit(1)),await ye(gr(),{projectPath:n,spinner:x,sliceName:o.sliceName,basePath:s,slicePath:a,persistSlice:o.persistSlice});let g=null;if(Fc(t,i.hasTests)){let y=le.join(a,`${o.sliceName}.slice.ts`);x.start("Generating test..."),g=await Q({projectPath:n,sourceFile:y,kind:"slice",symbolName:A(o.sliceName)}),x.succeed("Test generated")}jc(o,s,g,n)}catch(n){x.fail("Slice generation failed"),v(`${n}`),process.exit(1)}})},_c=(e,r,t)=>{let n;if(t){let i=t.replace(/^src\//,"");if(i.startsWith("features/")){let o=i.split("/")[1];n=le.join("src","features",o,"store")}else n=le.join("src",i)}else n=le.join("src","features",r,"store");return{basePath:n,slicePath:le.join(e,n,r)}},Fc=(e,r)=>e.noTest?!1:e.test?!0:r,jc=(e,r,t,n)=>{let i=le.join(r,e.sliceName);l(G.green(`
1049
+ `));let i=await li(r,t.persist,t.noPersist===!0?!1:void 0),{basePath:s,slicePath:a}=Uc(n,i.sliceName,t.path),p=le.join(n,s);Gc(p)||await Hc(p,{recursive:!0}),await ie(n,i.sliceName,s)&&(v(`Slice '${i.sliceName}' already exists at ${s}!`),process.exit(1)),await xe(hr(),{projectPath:n,spinner:y,sliceName:i.sliceName,basePath:s,slicePath:a,persistSlice:i.persistSlice});let g=null;if(zc(t,o.hasTests)){let x=le.join(a,`${i.sliceName}.slice.ts`);y.start("Generating test..."),g=await ee({projectPath:n,sourceFile:x,kind:"slice",symbolName:A(i.sliceName)}),y.succeed("Test generated")}Vc(i,s,g,n)}catch(n){y.fail("Slice generation failed"),v(`${n}`),process.exit(1)}})},Uc=(e,r,t)=>{let n;if(t){let o=t.replace(/^src\//,"");if(o.startsWith("features/")){let i=o.split("/")[1];n=le.join("src","features",i,"store")}else n=le.join("src",o)}else n=le.join("src","features",r,"store");return{basePath:n,slicePath:le.join(e,n,r)}},zc=(e,r)=>e.noTest?!1:e.test?!0:r,Vc=(e,r,t,n)=>{let o=le.join(r,e.sliceName);l(G.green(`
1030
1050
  \u2728 Slice '${e.sliceName}' created successfully!
1031
- `)),l(G.dim("Generated files:")),l(G.dim(` \u{1F4C2} ${i}/`)),l(G.dim(` \u251C\u2500\u2500 ${e.sliceName}.slice.ts`)),l(G.dim(` \u251C\u2500\u2500 ${e.sliceName}.selectors.ts`)),e.persistSlice&&l(G.dim(" \u251C\u2500\u2500 persist.ts")),l(G.dim(` \u251C\u2500\u2500 ${e.sliceName}.types.ts`)),l(G.dim(` \u2514\u2500\u2500 index.ts
1051
+ `)),l(G.dim("Generated files:")),l(G.dim(` \u{1F4C2} ${o}/`)),l(G.dim(` \u251C\u2500\u2500 ${e.sliceName}.slice.ts`)),l(G.dim(` \u251C\u2500\u2500 ${e.sliceName}.selectors.ts`)),e.persistSlice&&l(G.dim(" \u251C\u2500\u2500 persist.ts")),l(G.dim(` \u251C\u2500\u2500 ${e.sliceName}.types.ts`)),l(G.dim(` \u2514\u2500\u2500 index.ts
1032
1052
  `)),t&&l(G.dim(` \u{1F9EA} ${le.relative(n,t)}
1033
- `)),l(G.cyan("Next steps:"));let o=r.replace(/^src\//,"@/");l(G.dim(` 1. Import actions: import { setLoading, setError } from '${o}/${e.sliceName}'`)),l(G.dim(" 2. Use in component: dispatch(setLoading(true))")),l("")};import X from"node:path";import vr from"picocolors";P();L();var li=e=>{e.command("test <file>").description(`Generate a sibling test file for an existing component, hook, or slice.
1034
- Infers the kind from filename/content; pass --kind to override.`).option("--kind <kind>","Override inferred kind: component | hook | slice").option("--force","Overwrite an existing test file").action(async(r,t)=>{try{let n=process.cwd(),i=X.isAbsolute(r)?r:X.join(n,r);l(vr.cyan(`
1053
+ `)),l(G.cyan("Next steps:"));let i=r.replace(/^src\//,"@/");l(G.dim(` 1. Import actions: import { setLoading, setError } from '${i}/${e.sliceName}'`)),l(G.dim(" 2. Use in component: dispatch(setLoading(true))")),l("")};import Y from"node:path";import Sr from"picocolors";P();L();var di=e=>{e.command("test <file>").description(`Generate a sibling test file for an existing component, hook, or slice.
1054
+ Infers the kind from filename/content; pass --kind to override.`).option("--kind <kind>","Override inferred kind: component | hook | slice").option("--force","Overwrite an existing test file").action(async(r,t)=>{try{let n=process.cwd(),o=Y.isAbsolute(r)?r:Y.join(n,r);l(Sr.cyan(`
1035
1055
  \u{1F9EA} Test Generator
1036
- `)),m(i)||(v(`Source file not found: ${r}`),process.exit(1));let o=await I(n);o.hasTests||(v("Testing is not installed in this project. Run `next-maker setup --tests` first."),process.exit(1));let s=await u(i),a=Dc(t.kind)??Lc(i,s);a||(v(`Could not infer test kind for ${X.basename(i)}. Pass --kind component|hook|slice.`),process.exit(1));let p=Mc(i,a),d=Gc(i,a);m(d)&&!t.force&&(v(`Test file already exists: ${X.relative(n,d)}. Use --force to overwrite.`),process.exit(1)),x.start(`Generating ${a} test...`);let g=await Q({projectPath:n,sourceFile:i,kind:a,symbolName:p,hasRedux:o.hasRedux,hasI18n:o.hasI18n,hookUsesStore:a==="hook"&&o.hasRedux&&s.includes("useAppSelector")});x.succeed("Test generated"),l(vr.green(`
1037
- \u2728 Test '${X.basename(g)}' created.
1038
- `)),l(vr.dim(` \u{1F9EA} ${X.relative(n,g)}`)),l("")}catch(n){x.fail("Test generation failed"),v(`${n}`),process.exit(1)}})},Dc=e=>{if(!e)return null;if(e==="component"||e==="hook"||e==="slice")return e;throw new Error(`Invalid --kind: ${e}. Use component | hook | slice.`)},Lc=(e,r)=>{let t=X.basename(e);return/\.slice\.ts$/.test(t)?"slice":/^use[A-Z]/.test(t.replace(/\.tsx?$/,""))?"hook":t.endsWith(".tsx")?"component":/createSlice\s*\(/.test(r)?"slice":/^export\s+(const|function)\s+use[A-Z]/m.test(r)?"hook":null},Mc=(e,r)=>{let t=X.basename(e).replace(/\.(tsx?|jsx?)$/i,"");return r==="slice"?A(t.replace(/\.slice$/,"")):r==="hook"?/^use[A-Z]/.test(t)?t:`use${$(t.replace(/^use-?/,""))}`:$(t)},Gc=(e,r)=>{let t=X.dirname(e),n=X.basename(e).replace(/\.(tsx?|jsx?)$/i,""),i=r==="component"?".tsx":".ts";return X.join(t,`${n}.test${i}`)};var mi=e=>{Zr(e),ai(e),Bo(e),pi(e),si(e),ei(e),Ko(e),In(e),Wo(e),Yo(e),ti(e),Ho(e),Oo(e),ri(e),li(e)};var Uc=process.emitWarning;process.emitWarning=function(e,r,t,n){if(!(typeof e=="string"&&e.includes("--localstorage-file")&&e.includes("was provided without a valid path")))return Uc.apply(process,arguments)};async function zc(){wr({logger:r=>nt(r)});let e=new Hc;e.name("next-maker").description("Teispace Next.js Project Generator").version("1.0.0"),mi(e),e.parse()}zc().catch(e=>{let r=e&&typeof e=="object"&&"message"in e?e.message:String(e);nt(`Unexpected error: ${r}`)});
1056
+ `)),m(o)||(v(`Source file not found: ${r}`),process.exit(1));let i=await I(n);i.hasTests||(v("Testing is not installed in this project. Run `next-maker setup --tests` first."),process.exit(1));let s=await u(o),a=Jc(t.kind)??Bc(o,s);a||(v(`Could not infer test kind for ${Y.basename(o)}. Pass --kind component|hook|slice.`),process.exit(1));let p=Xc(o,a),d=Yc(o,a);m(d)&&!t.force&&(v(`Test file already exists: ${Y.relative(n,d)}. Use --force to overwrite.`),process.exit(1)),y.start(`Generating ${a} test...`);let g=await ee({projectPath:n,sourceFile:o,kind:a,symbolName:p,hasRedux:i.hasRedux,hasI18n:i.hasI18n,hookUsesStore:a==="hook"&&i.hasRedux&&s.includes("useAppSelector")});y.succeed("Test generated"),l(Sr.green(`
1057
+ \u2728 Test '${Y.basename(g)}' created.
1058
+ `)),l(Sr.dim(` \u{1F9EA} ${Y.relative(n,g)}`)),l("")}catch(n){y.fail("Test generation failed"),v(`${n}`),process.exit(1)}})},Jc=e=>{if(!e)return null;if(e==="component"||e==="hook"||e==="slice")return e;throw new Error(`Invalid --kind: ${e}. Use component | hook | slice.`)},Bc=(e,r)=>{let t=Y.basename(e);return/\.slice\.ts$/.test(t)?"slice":/^use[A-Z]/.test(t.replace(/\.tsx?$/,""))?"hook":t.endsWith(".tsx")?"component":/createSlice\s*\(/.test(r)?"slice":/^export\s+(const|function)\s+use[A-Z]/m.test(r)?"hook":null},Xc=(e,r)=>{let t=Y.basename(e).replace(/\.(tsx?|jsx?)$/i,"");return r==="slice"?A(t.replace(/\.slice$/,"")):r==="hook"?/^use[A-Z]/.test(t)?t:`use${$(t.replace(/^use-?/,""))}`:$(t)},Yc=(e,r)=>{let t=Y.dirname(e),n=Y.basename(e).replace(/\.(tsx?|jsx?)$/i,""),o=r==="component"?".tsx":".ts";return Y.join(t,`${n}.test${o}`)};var ui=e=>{en(e),pi(e),Yo(e),mi(e),ci(e),ri(e),Wo(e),kn(e),Qo(e),qo(e),ni(e),zo(e),Fo(e),oi(e),di(e)};var qc=process.emitWarning;process.emitWarning=function(e,r,t,n){if(!(typeof e=="string"&&e.includes("--localstorage-file")&&e.includes("was provided without a valid path")))return qc.apply(process,arguments)};async function Wc(){Cr({logger:r=>nt(r)});let e=new Kc;e.name("next-maker").description("Teispace Next.js Project Generator").version("1.0.0"),ui(e),e.parse()}Wc().catch(e=>{let r=e&&typeof e=="object"&&"message"in e?e.message:String(e);nt(`Unexpected error: ${r}`)});
1039
1059
  //# sourceMappingURL=index.js.map