@teispace/next-maker 3.0.0 → 3.0.1

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,30 +1,30 @@
1
1
  #!/usr/bin/env node
2
- var Rs=Object.defineProperty;var Re=(e,t)=>()=>(e&&(t=e(e=0)),t);var Ht=(e,t)=>{for(var r in t)Rs(e,r,{get:t[r],enumerable:!0})};import{existsSync as Ut}from"node:fs";import ye from"node:fs/promises";import en from"node:path";var f,g,N,E,w,D,m,P=Re(()=>{"use strict";f=async e=>ye.readFile(e,"utf-8"),g=async(e,t)=>{await ye.mkdir(en.dirname(e),{recursive:!0}),await ye.writeFile(e,t,"utf-8")},N=async(e,t)=>{await ye.mkdir(en.dirname(t),{recursive:!0}),await ye.copyFile(e,t)},E=async e=>{Ut(e)&&await ye.unlink(e)},w=async e=>{Ut(e)&&await ye.rm(e,{recursive:!0,force:!0})},D=async(e,t)=>{let r=await f(e),n=JSON.parse(r),i=t(n);await g(e,JSON.stringify(i,null,2))},m=e=>Ut(e)});var an={};Ht(an,{PROJECT_PATHS:()=>c});var c,S=Re(()=>{"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",SEO_FILE:"src/lib/config/seo.ts",SITEMAP_FILE:"src/app/sitemap.ts",MIDDLEWARE:"src/middleware.ts",PROXY:"src/proxy.ts",I18N_TYPES:"src/types/i18n.ts",HTTP_UTILS:"src/lib/utils/http",HTTP_SHARED:"src/lib/utils/http/shared",HTTP_SERVER_FILE:"src/lib/utils/http/server.ts",HTTP_BUNDLE_SENTINEL_DIR:"src/lib/utils/http/__bundle-sentinel__",HTTP_BUNDLE_SENTINEL_FILE:"src/lib/utils/http/__bundle-sentinel__/client-bundle-sentinel.tsx",WS_UTILS:"src/lib/utils/ws",WS_SLICE_FILE:"src/store/slices/ws.slice.ts",ROOT_REDUCER:"src/store/rootReducer.ts",TEST_SETUP_FILE:"test/setup.ts",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",API_URL_FILE:"src/lib/config/api-url.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",LOCALE_LAYOUT:"src/app/[locale]/layout.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 gn={};Ht(gn,{cleanupHttpTypes:()=>Ie,injectBundleSentinel:()=>fn,installBundleSentinelMount:()=>Kt,isFileUsed:()=>oa,isStringUsed:()=>sa,migrateClientUsages:()=>Xt,removeBundleSentinelMount:()=>He,removeHttpExports:()=>Zt,resolveBundleSentinelLayoutPath:()=>Yt,rewriteSentinelImports:()=>Ne,rewriteServerEntryImports:()=>ke,stripBundleSentinel:()=>Ge,updateConfigIndex:()=>qt,updateHttpIndex:()=>Jt,updateTypesIndex:()=>Wt,updateUtilsIndex:()=>Vt});import{exec as ra}from"node:child_process";import A from"node:path";import{promisify as na}from"node:util";var zt,Jt,Vt,Wt,qt,Ie,Xt,Yt,ia,mn,dn,fn,Ge,Kt,He,Zt,oa,sa,Ne,ke,un,Ue=Re(()=>{"use strict";S();P();zt=na(ra),Jt=async(e,t)=>{let r=A.join(e,c.HTTP_UTILS,"index.ts");if(m(r)){let n=await f(r);n=n.replace(/export .* from '\.\/axios-client';?\n?/g,""),n=n.replace(/export .* from '\.\/fetch-client';?\n?/g,""),t.includes("fetch")&&!n.includes("fetch-client")&&(n+=`export * from './fetch-client';
2
+ var Fs=Object.defineProperty;var Ie=(e,t)=>()=>(e&&(t=e(e=0)),t);var Jt=(e,t)=>{for(var r in t)Fs(e,r,{get:t[r],enumerable:!0})};import{existsSync as Vt}from"node:fs";import Pe from"node:fs/promises";import on from"node:path";var f,g,N,C,w,D,m,P=Ie(()=>{"use strict";f=async e=>Pe.readFile(e,"utf-8"),g=async(e,t)=>{await Pe.mkdir(on.dirname(e),{recursive:!0}),await Pe.writeFile(e,t,"utf-8")},N=async(e,t)=>{await Pe.mkdir(on.dirname(t),{recursive:!0}),await Pe.copyFile(e,t)},C=async e=>{Vt(e)&&await Pe.unlink(e)},w=async e=>{Vt(e)&&await Pe.rm(e,{recursive:!0,force:!0})},D=async(e,t)=>{let r=await f(e),n=JSON.parse(r),i=t(n);await g(e,JSON.stringify(i,null,2))},m=e=>Vt(e)});var dn={};Jt(dn,{PROJECT_PATHS:()=>c});var c,S=Ie(()=>{"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",SEO_FILE:"src/lib/config/seo.ts",SITEMAP_FILE:"src/app/sitemap.ts",MIDDLEWARE:"src/middleware.ts",PROXY:"src/proxy.ts",I18N_TYPES:"src/types/i18n.ts",HTTP_UTILS:"src/lib/utils/http",HTTP_SHARED:"src/lib/utils/http/shared",HTTP_SERVER_FILE:"src/lib/utils/http/server.ts",HTTP_BUNDLE_SENTINEL_DIR:"src/lib/utils/http/__bundle-sentinel__",HTTP_BUNDLE_SENTINEL_FILE:"src/lib/utils/http/__bundle-sentinel__/client-bundle-sentinel.tsx",WS_UTILS:"src/lib/utils/ws",WS_SLICE_FILE:"src/store/slices/ws.slice.ts",ROOT_REDUCER:"src/store/rootReducer.ts",TEST_SETUP_FILE:"test/setup.ts",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",API_URL_FILE:"src/lib/config/api-url.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",LOCALE_LAYOUT:"src/app/[locale]/layout.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 wn={};Jt(wn,{cleanupHttpTypes:()=>ke,injectBundleSentinel:()=>Pn,installBundleSentinelMount:()=>tr,isFileUsed:()=>ga,isStringUsed:()=>ha,migrateClientUsages:()=>Qt,removeBundleSentinelMount:()=>Be,removeHttpExports:()=>rr,resolveBundleSentinelLayoutPath:()=>er,rewriteSentinelImports:()=>Ae,rewriteServerEntryImports:()=>_e,stripBundleSentinel:()=>He,updateConfigIndex:()=>Zt,updateHttpIndex:()=>Xt,updateTypesIndex:()=>Kt,updateUtilsIndex:()=>Yt});import{exec as da}from"node:child_process";import A from"node:path";import{promisify as ua}from"node:util";var qt,Xt,Yt,Kt,Zt,ke,Qt,er,fa,hn,yn,Pn,He,tr,Be,rr,ga,ha,Ae,_e,xn,ze=Ie(()=>{"use strict";S();P();qt=ua(da),Xt=async(e,t)=>{let r=A.join(e,c.HTTP_UTILS,"index.ts");if(m(r)){let n=await f(r);n=n.replace(/export .* from '\.\/axios-client';?\n?/g,""),n=n.replace(/export .* from '\.\/fetch-client';?\n?/g,""),t.includes("fetch")&&!n.includes("fetch-client")&&(n+=`export * from './fetch-client';
3
3
  `),t.includes("axios")&&!n.includes("axios-client")&&(n+=`export * from './axios-client';
4
- `),await g(r,n)}},Vt=async e=>{let t=A.join(e,c.UTILS_INDEX);if(m(t)){let r=await f(t);r.includes("./http")||(r+=`export * from './http';
5
- `,await g(t,r))}},Wt=async e=>{let t=A.join(e,c.TYPES_INDEX);if(m(t)){let r=await f(t);r.includes("./common")||(r+=`export * from './common';
4
+ `),await g(r,n)}},Yt=async e=>{let t=A.join(e,c.UTILS_INDEX);if(m(t)){let r=await f(t);r.includes("./http")||(r+=`export * from './http';
5
+ `,await g(t,r))}},Kt=async e=>{let t=A.join(e,c.TYPES_INDEX);if(m(t)){let r=await f(t);r.includes("./common")||(r+=`export * from './common';
6
6
  `),r.includes("./utility")||(r+=`export * from './utility';
7
- `),await g(t,r)}},qt=async e=>{let t=A.join(e,c.CONFIG_INDEX);if(m(t)){let r=await f(t);r.includes("./app-apis")||(r+=`export * from './app-apis';
8
- `,await g(t,r))}},Ie=async(e,t)=>{let r=A.join(e,c.HTTP_TYPES);if(m(r)){let n=await f(r);t.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,`
7
+ `),await g(t,r)}},Zt=async e=>{let t=A.join(e,c.CONFIG_INDEX);if(m(t)){let r=await f(t);r.includes("./app-apis")||(r+=`export * from './app-apis';
8
+ `,await g(t,r))}},ke=async(e,t)=>{let r=A.join(e,c.HTTP_TYPES);if(m(r)){let n=await f(r);t.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 g(r,n))}},Xt=async(e,t,r)=>{if(t===r)return;let n=t==="fetch"?"fetchClient":"axiosClient",i=r==="fetch"?"fetchClient":"axiosClient",o=t==="fetch"?"fetch-client":"axios-client",s=r==="fetch"?"fetch-client":"axios-client",a=A.join(e,"src");try{let p=`grep -rl "${n}" "${a}" --include="*.ts" --include="*.tsx" || true`,{stdout:u}=await zt(p);if(!u.trim())return;let d=u.trim().split(`
12
- `).filter(h=>h);for(let h of d){if(!m(h))continue;let x=await f(h),$=!1,J=new RegExp(`(import\\s*\\{[^}]*?)\\b${n}\\b([^}]*?\\}\\s*from\\s*['"][^'"]*?/http['"])`,"g");J.test(x)&&(x=x.replace(J,`$1${i}$2`),$=!0);let I=new RegExp(`import\\s+${n}\\s+from\\s+['"]([^'"]*?)/${o}['"]`,"g");I.test(x)&&(x=x.replace(I,`import ${i} from '$1/${s}'`),$=!0);let V=new RegExp(`\\b${n}\\b(?=\\.)`,"g");V.test(x)&&(x=x.replace(V,i),$=!0);let he=new RegExp(`\\b${n}\\b(?![.\\w])`,"g");he.test(x)&&(x=x.replace(he,i),$=!0),$&&await g(h,x)}}catch(p){console.warn("Warning: Could not scan for HTTP client usages:",p)}},Yt=e=>{let t=A.join(e,c.LOCALE_LAYOUT);if(m(t))return t;let r=A.join(e,c.ROOT_LAYOUT);return m(r)?r:null},ia="// Regression sentinel \u2014 see file comment for what this guards.",mn="import { HttpClientBundleSentinel } from '@/lib/utils/http/__bundle-sentinel__/client-bundle-sentinel';",dn="<HttpClientBundleSentinel />",fn=e=>{if(e.includes(dn))return e;let t=e;if(!t.includes(mn)){let o=/(^import\s[^\n]*\n)+/m,s=t.match(o);if(!s)throw new Error("injectBundleSentinel: no `import` lines found \u2014 expected a layout file with at least one import.");let a=t.slice(0,(s.index??0)+s[0].length),p=t.slice((s.index??0)+s[0].length);t=`${a}${ia}
13
- ${mn}
11
+ `,await g(r,n))}},Qt=async(e,t,r)=>{if(t===r)return;let n=t==="fetch"?"fetchClient":"axiosClient",i=r==="fetch"?"fetchClient":"axiosClient",o=t==="fetch"?"fetch-client":"axios-client",s=r==="fetch"?"fetch-client":"axios-client",a=A.join(e,"src");try{let p=`grep -rl "${n}" "${a}" --include="*.ts" --include="*.tsx" || true`,{stdout:u}=await qt(p);if(!u.trim())return;let d=u.trim().split(`
12
+ `).filter(h=>h);for(let h of d){if(!m(h))continue;let x=await f(h),$=!1,V=new RegExp(`(import\\s*\\{[^}]*?)\\b${n}\\b([^}]*?\\}\\s*from\\s*['"][^'"]*?/http['"])`,"g");V.test(x)&&(x=x.replace(V,`$1${i}$2`),$=!0);let I=new RegExp(`import\\s+${n}\\s+from\\s+['"]([^'"]*?)/${o}['"]`,"g");I.test(x)&&(x=x.replace(I,`import ${i} from '$1/${s}'`),$=!0);let W=new RegExp(`\\b${n}\\b(?=\\.)`,"g");W.test(x)&&(x=x.replace(W,i),$=!0);let xe=new RegExp(`\\b${n}\\b(?![.\\w])`,"g");xe.test(x)&&(x=x.replace(xe,i),$=!0),$&&await g(h,x)}}catch(p){console.warn("Warning: Could not scan for HTTP client usages:",p)}},er=e=>{let t=A.join(e,c.LOCALE_LAYOUT);if(m(t))return t;let r=A.join(e,c.ROOT_LAYOUT);return m(r)?r:null},fa="// Regression sentinel \u2014 see file comment for what this guards.",hn="import { HttpClientBundleSentinel } from '@/lib/utils/http/__bundle-sentinel__/client-bundle-sentinel';",yn="<HttpClientBundleSentinel />",Pn=e=>{if(e.includes(yn))return e;let t=e;if(!t.includes(hn)){let o=/(^import\s[^\n]*\n)+/m,s=t.match(o);if(!s)throw new Error("injectBundleSentinel: no `import` lines found \u2014 expected a layout file with at least one import.");let a=t.slice(0,(s.index??0)+s[0].length),p=t.slice((s.index??0)+s[0].length);t=`${a}${fa}
13
+ ${hn}
14
14
  ${p}`}let r=/(<RootProvider\b[^>]*>)\n([ \t]*)/,n=t.match(r);if(!n)throw new Error("injectBundleSentinel: could not locate `<RootProvider \u2026>` opening tag \u2014 layout shape unexpected.");let i=n[2];return t=t.replace(r,`$1
15
- ${i}${dn}
16
- ${i}`),t},Ge=e=>{let t=e,r=/@\/lib\/utils\/http\/__bundle-sentinel__\/client-bundle-sentinel/,n=new RegExp(`(?:^[ \\t]*//[^\\n]*\\n)?^[ \\t]*import[^\\n]*${r.source}[^\\n]*\\n`,"m");return t=t.replace(n,""),t=t.replace(/[ \t]*<HttpClientBundleSentinel\s*\/>\s*\n/,""),t},Kt=async e=>{let t=Yt(e);if(!t)return;let r=await f(t),n=fn(r);n!==r&&await g(t,n)},He=async e=>{let t=Yt(e);if(!t)return;let r=await f(t),n=Ge(r);n!==r&&await g(t,n)},Zt=async e=>{let t=A.join(e,c.UTILS_INDEX);if(m(t)){let n=await f(t);n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http['"];?.*$/gm,""),await g(t,n)}let r=A.join(e,c.TYPES_INDEX);if(m(r)){let n=await f(r),i=A.join(e,c.COMMON_TYPES_DIR);if(!m(i))n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/common['"];?.*$/gm,"");else{let o=A.join(i,"index.ts");if(m(o)){let s=await f(o);s=s.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http\.types['"];?.*$/gm,""),await g(o,s)}}m(A.join(e,c.UTILITY_TYPES_DIR))||(n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/utility['"];?.*$/gm,"")),await g(r,n)}},oa=async(e,t,r=[])=>{let n=A.join(e,"src"),o=`grep -r "from ['\\"].*${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}.*['\\"]" "${n}" --include="*.ts" --include="*.tsx" || true`;try{let{stdout:s}=await zt(o);return s.trim()?s.trim().split(`
17
- `).filter(u=>{let[d]=u.split(":"),h=A.resolve(e,d);return!r.some(x=>!!(h===x||h.startsWith(x+A.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for ${t}:`,s),!0}},sa=async(e,t,r=[])=>{let n=A.join(e,"src"),o=`grep -r "${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}" "${n}" --include="*.ts" --include="*.tsx" || true`;try{let{stdout:s}=await zt(o);return s.trim()?s.trim().split(`
18
- `).filter(u=>{let[d]=u.split(":"),h=A.resolve(e,d);return!r.some(x=>!!(h===x||h.startsWith(x+A.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for string ${t}:`,s),!0}},Ne=async(e,t)=>{let r=A.join(e,c.HTTP_BUNDLE_SENTINEL_FILE);if(!m(r))return;let n=await f(r),i=["toSearchParams"];if(t.includes("axios")&&i.unshift("axiosClient","createAxiosClient"),t.includes("fetch")){let a=i.indexOf("toSearchParams");i.splice(a,0,"createFetchClient","fetchClient")}i.sort();let o=`import {
15
+ ${i}${yn}
16
+ ${i}`),t},He=e=>{let t=e,r=/@\/lib\/utils\/http\/__bundle-sentinel__\/client-bundle-sentinel/,n=new RegExp(`(?:^[ \\t]*//[^\\n]*\\n)?^[ \\t]*import[^\\n]*${r.source}[^\\n]*\\n`,"m");return t=t.replace(n,""),t=t.replace(/[ \t]*<HttpClientBundleSentinel\s*\/>\s*\n/,""),t},tr=async e=>{let t=er(e);if(!t)return;let r=await f(t),n=Pn(r);n!==r&&await g(t,n)},Be=async e=>{let t=er(e);if(!t)return;let r=await f(t),n=He(r);n!==r&&await g(t,n)},rr=async e=>{let t=A.join(e,c.UTILS_INDEX);if(m(t)){let n=await f(t);n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http['"];?.*$/gm,""),await g(t,n)}let r=A.join(e,c.TYPES_INDEX);if(m(r)){let n=await f(r),i=A.join(e,c.COMMON_TYPES_DIR);if(!m(i))n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/common['"];?.*$/gm,"");else{let o=A.join(i,"index.ts");if(m(o)){let s=await f(o);s=s.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http\.types['"];?.*$/gm,""),await g(o,s)}}m(A.join(e,c.UTILITY_TYPES_DIR))||(n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/utility['"];?.*$/gm,"")),await g(r,n)}},ga=async(e,t,r=[])=>{let n=A.join(e,"src"),o=`grep -r "from ['\\"].*${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}.*['\\"]" "${n}" --include="*.ts" --include="*.tsx" || true`;try{let{stdout:s}=await qt(o);return s.trim()?s.trim().split(`
17
+ `).filter(u=>{let[d]=u.split(":"),h=A.resolve(e,d);return!r.some(x=>!!(h===x||h.startsWith(x+A.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for ${t}:`,s),!0}},ha=async(e,t,r=[])=>{let n=A.join(e,"src"),o=`grep -r "${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}" "${n}" --include="*.ts" --include="*.tsx" || true`;try{let{stdout:s}=await qt(o);return s.trim()?s.trim().split(`
18
+ `).filter(u=>{let[d]=u.split(":"),h=A.resolve(e,d);return!r.some(x=>!!(h===x||h.startsWith(x+A.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for string ${t}:`,s),!0}},Ae=async(e,t)=>{let r=A.join(e,c.HTTP_BUNDLE_SENTINEL_FILE);if(!m(r))return;let n=await f(r),i=["toSearchParams"];if(t.includes("axios")&&i.unshift("axiosClient","createAxiosClient"),t.includes("fetch")){let a=i.indexOf("toSearchParams");i.splice(a,0,"createFetchClient","fetchClient")}i.sort();let o=`import {
19
19
  ${i.join(`,
20
20
  `)},
21
21
  } from '@/lib/utils/http';`;n=n.replace(/import\s*\{[^}]*\}\s*from\s*['"]@\/lib\/utils\/http['"];/,o);let s=i.map(a=>` ${a},`).join(`
22
22
  `);n=n.replace(/const __sentinel__ = \{[\s\S]*?\};/,`const __sentinel__ = {
23
23
  ${s}
24
- };`),await g(r,n)},ke=async(e,t)=>{let r=A.join(e,c.HTTP_SERVER_FILE);if(!m(r)||t.length===0)return;let n=await f(r),i=o=>{n=n.replace(o,"")};t.includes("axios")||(i(/^import\s*\{\s*createAxiosClient\s*\}\s*from\s*['"]\.\/axios-client['"];\n?/m),i(/export const axiosClient = createAxiosClient\(\{[\s\S]*?\}\);\n?\n?/),n=un(n,"createAxiosClient")),t.includes("fetch")||(i(/^import\s*\{\s*createFetchClient\s*\}\s*from\s*['"]\.\/fetch-client['"];\n?/m),i(/export const fetchClient = createFetchClient\(\{[\s\S]*?\}\);\n?\n?/),n=un(n,"createFetchClient")),n=n.replace(/\n{3,}/g,`
24
+ };`),await g(r,n)},_e=async(e,t)=>{let r=A.join(e,c.HTTP_SERVER_FILE);if(!m(r)||t.length===0)return;let n=await f(r),i=o=>{n=n.replace(o,"")};t.includes("axios")||(i(/^import\s*\{\s*createAxiosClient\s*\}\s*from\s*['"]\.\/axios-client['"];\n?/m),i(/export const axiosClient = createAxiosClient\(\{[\s\S]*?\}\);\n?\n?/),n=xn(n,"createAxiosClient")),t.includes("fetch")||(i(/^import\s*\{\s*createFetchClient\s*\}\s*from\s*['"]\.\/fetch-client['"];\n?/m),i(/export const fetchClient = createFetchClient\(\{[\s\S]*?\}\);\n?\n?/),n=xn(n,"createFetchClient")),n=n.replace(/\n{3,}/g,`
25
25
 
26
- `),await g(r,n)},un=(e,t)=>{let r=/^export\s*\{([^}]*)\};\n?/m;return e.replace(r,(n,i)=>{let o=i.split(",").map(s=>s.trim()).filter(s=>s.length>0&&s!==t);return o.length===0?"":`export { ${o.join(", ")} };
27
- `})}});import{existsSync as Xa}from"node:fs";import{access as Ya}from"node:fs/promises";import Bn from"node:path";var le,Tt,zn=Re(()=>{"use strict";le=async(e,t,r)=>{try{return await Ya(Bn.join(e,r,t)),!0}catch{return!1}},Tt=(e,t,r)=>Xa(Bn.join(e,t,r))});import{access as bt,readFile as Ka}from"node:fs/promises";import We from"node:path";var F,Jn=Re(()=>{"use strict";F=async e=>{try{let t=We.join(e,"package.json"),r=await Ka(t,"utf-8"),n=JSON.parse(r),i={...n.dependencies,...n.devDependencies},o=!!(i["@reduxjs/toolkit"]&&i["react-redux"]),s=!!i["next-intl"],a=!!i.axios,p=!1,u=We.join(e,"src","lib","utils","http","axios-client");try{await bt(u)}catch{a=!1}let d=We.join(e,"src","lib","utils","http","fetch-client");try{await bt(d),p=!0}catch{p=!1}let h;a&&p?h="both":a?h="axios":p?h="fetch":h="none";let x=!!i.vitest;if(!x)try{await bt(We.join(e,"vitest.config.ts")),x=!0}catch{}let $="none";if(i["socket.io-client"])try{await bt(We.join(e,"src","lib","utils","ws")),$="present"}catch{}return{hasRedux:o,httpClient:h,hasI18n:s,hasTests:x,ws:$}}catch(t){throw new Error(`Failed to detect project setup: ${t}`,{cause:t})}}});var qe={};Ht(qe,{detectProjectSetup:()=>F,directoryExists:()=>le,fileExistsAt:()=>Tt});var H=Re(()=>{"use strict";zn();Jn()});import{Command as Yl}from"commander";import tr from"node:path";import q from"picocolors";function Kr(e){let{logger:t=s=>console.error(s),exitOnCancel:r=process.env.NODE_ENV!=="test"}=e??{},n=()=>{console.log(""),console.log(""),t("Setup cancelled by user"),console.log(""),r&&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){t(`Uncaught exception: ${s.message}`);return}t(`Uncaught exception: ${String(s)}`)},o=s=>{if(s instanceof Error){t(`Unhandled promise rejection: ${s.message}`);return}t(`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 ee from"picocolors";var $s={reset:e=>e,red:ee.red,green:ee.green,yellow:ee.yellow,blue:ee.blue,cyan:ee.cyan,magenta:ee.magenta,white:ee.white,gray:ee.gray,bright:ee.bold,dim:ee.dim};function ae(e,t="reset"){let r=$s[t]??(n=>n);console.log(r(e))}function wt(e){ae(`\u2716 ${e}`,"red")}var v=wt;function Zr(e){ae(`\u26A0 ${e}`,"yellow")}function l(e){ae(e)}function Qr(){console.log(""),ae("\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"),ae("\u2551 \u2551","cyan"),ae("\u2551 \u{1F680} Create Teispace Next.js App \u{1F680} \u2551","cyan"),ae("\u2551 \u2551","cyan"),ae("\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 Is from"ora";function b(e="",t){let r=Is({text:e,...t});return r.start(),r}var Ns=e=>e.charAt(0).toUpperCase()+e.slice(1),j=e=>e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase()),R=e=>Ns(j(e));import ks from"ora";var y=ks();P();import{exec as As}from"node:child_process";import{promisify as _s}from"node:util";var ie=_s(As),tn=async(e,t,r)=>{try{if(await ie("git init",{cwd:e}),await ie("git add .",{cwd:e}),await ie('git commit -m "Initial commit from @teispace/next-maker"',{cwd:e}),t&&(await ie(`git remote add origin ${t}`,{cwd:e}),r)){await ie("git fetch origin",{cwd:e});let n="main";try{await ie("git show-branch origin/main",{cwd:e})}catch{try{await ie("git show-branch origin/master",{cwd:e}),n="master"}catch{n="main"}}await ie(`git merge origin/${n} --allow-unrelated-histories -X ours`,{cwd:e}),await ie(`git push origin HEAD:${n}`,{cwd:e})}}catch(n){console.warn("Failed to initialize git repository",n)}};import{exec as Os}from"node:child_process";import{promisify as Fs}from"node:util";var Le=Fs(Os),rn=async(e,t)=>{let r=`${t} install`;try{await Le(r,{cwd:e})}catch(n){throw new Error(`Failed to install dependencies with ${t}: ${n}`,{cause:n})}},z=async(e,t,r)=>{let n=t==="npm"?`${t} run ${r}`:`${t} ${r}`;try{await Le(n,{cwd:e})}catch(i){console.warn(`Warning: Failed to run script '${r}': ${i}`)}},js=()=>{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"},k=async e=>{let{existsSync:t}=await import("node:fs"),r=await import("node:path");return t(r.join(e,"pnpm-lock.yaml"))?"pnpm":t(r.join(e,"yarn.lock"))?"yarn":t(r.join(e,"bun.lockb"))?"bun":t(r.join(e,"package-lock.json"))?"npm":js()},Ds=async(e,t,r)=>{if(r.length===0)return;let i=`${nn(t)} ${r.join(" ")}`;try{await Le(i,{cwd:e})}catch(o){throw new Error(`Failed to install packages with ${t}: ${o}`,{cause:o})}},nn=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"}},G=async(e,t)=>{let r=await k(e);await Ds(e,r,[t])},Ls=e=>{switch(e){case"npm":return"--save-dev";case"yarn":case"pnpm":case"bun":return"-D";default:return"--save-dev"}},xe=async(e,t,r)=>{if(r.length===0)return;let n=nn(t),i=Ls(t),o=`${n} ${i} ${r.join(" ")}`;try{await Le(o,{cwd:e})}catch(s){throw new Error(`Failed to install dev packages with ${t}: ${s}`,{cause:s})}},vt=async(e,t)=>{let r=await k(e);await xe(e,r,[t])},Bt=async(e,t,r)=>{if(r.length===0)return;let i=`${Ms(t)} ${r.join(" ")}`;try{await Le(i,{cwd:e})}catch(o){throw new Error(`Failed to uninstall packages with ${t}: ${o}`,{cause:o})}},Ms=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"}},$e=async(e,t)=>{let r=await k(e);await Bt(e,r,[t])};import Gs from"enquirer";var Hs=/^[a-z0-9-_]+$/,Us=/^\d+\.\d+\.\d+$/,Bs=e=>Hs.test(e),zs=e=>Us.test(e),on=(e,t={})=>{let r=t.projectName??e??"my-app";if(!Bs(r))throw new Error(`Invalid project name "${r}". Use lowercase letters, digits, hyphens, and underscores only.`);let n=t.version??"0.1.0";if(!zs(n))throw new Error(`Invalid version "${n}". Expected semver (e.g. 0.1.0).`);let i=t.author??"Teispace",o=t.company??i;return{projectName:r,description:t.description??"A Next.js application",author:i,version:n,packageManager:t.packageManager??"yarn",gitRemote:t.gitRemote??"",pushToRemote:t.pushToRemote??!1,gitIssues:t.gitIssues??"",gitHomepage:t.gitHomepage??"",httpClient:t.httpClient??"fetch",reactSecureStorage:t.reactSecureStorage??!0,email:t.email??"support@example.com",company:o,keepTemplates:t.keepTemplates??!1,darkMode:t.darkMode??!0,redux:t.redux??!0,ws:(t.redux??!0)&&(t.ws??!1),i18n:t.i18n??!0,communityFiles:t.communityFiles??[],readme:t.readme??!0,docker:t.docker??!1,containerName:t.containerName,imageName:t.imageName,imageTag:t.imageTag,ci:t.ci??!1,preCommitHooks:t.preCommitHooks??!0,commitizen:t.commitizen??!0,copyEnv:t.copyEnv??!0,tests:t.tests??!0,reactCompiler:t.reactCompiler??!0,bundleAnalyzer:t.bundleAnalyzer??!1}},{prompt:Js}=Gs,sn=async e=>{let t=await Js([{type:"input",name:"projectName",message:"What is the project name?",initial:e||"my-app",skip:!!e,validate:r=>/^[a-z0-9-_]+$/.test(r)?!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:r=>/^\d+\.\d+\.\d+$/.test(r)?!0:"Version must be a valid semantic version (x.y.z)."},{type:"input",name:"email",message:"Support email:",initial:"support@example.com",validate:r=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(r)?!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:r=>r?/^https:\/\/github\.com\/[\w-]+\/[\w.-]+\/issues$/.test(r)?!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:r=>r?/^https:\/\/github\.com\/[\w-]+\/[\w.-]+#readme$/.test(r)?!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 r=this.state?.answers??this.enquirer?.answers??{};return!!(r.httpClient&&r.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:"ws",message:"Do you want to include WebSocket support (socket.io-client + Redux bridge)?",initial:!1,skip:function(){return!(this.state?.answers??this.enquirer?.answers??{}).redux}},{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:r=>/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(r)?!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:r=>/^[a-z0-9]+(?:[._-][a-z0-9]+)*$/.test(r)?!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:r=>/^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,127}$/.test(r)?!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(t.company=t.author,t.ws=!!t.redux&&!!t.ws,t.gitRemote&&!t.gitHomepage){let r=t.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"");t.gitHomepage=`${r}#readme`,t.gitIssues=`${r}/issues`}return t};P();import Vs from"node:path";var ce=async(e,t)=>{let r=Ws(t);await g(Vs.join(e,"test/test-utils.tsx"),r)},Ws=({redux:e,i18n:t})=>e&&t?qs:e?Xs:t?Ys:Ks,qs=`import { type RenderOptions, render } from '@testing-library/react';
26
+ `),await g(r,n)},xn=(e,t)=>{let r=/^export\s*\{([^}]*)\};\n?/m;return e.replace(r,(n,i)=>{let o=i.split(",").map(s=>s.trim()).filter(s=>s.length>0&&s!==t);return o.length===0?"":`export { ${o.join(", ")} };
27
+ `})}});import{existsSync as sc}from"node:fs";import{access as ac}from"node:fs/promises";import Yn from"node:path";var de,It,Kn=Ie(()=>{"use strict";de=async(e,t,r)=>{try{return await ac(Yn.join(e,r,t)),!0}catch{return!1}},It=(e,t,r)=>sc(Yn.join(e,t,r))});import{access as Nt,readFile as cc}from"node:fs/promises";import Xe from"node:path";var F,Zn=Ie(()=>{"use strict";F=async e=>{try{let t=Xe.join(e,"package.json"),r=await cc(t,"utf-8"),n=JSON.parse(r),i={...n.dependencies,...n.devDependencies},o=!!(i["@reduxjs/toolkit"]&&i["react-redux"]),s=!!i["next-intl"],a=!!i.axios,p=!1,u=Xe.join(e,"src","lib","utils","http","axios-client");try{await Nt(u)}catch{a=!1}let d=Xe.join(e,"src","lib","utils","http","fetch-client");try{await Nt(d),p=!0}catch{p=!1}let h;a&&p?h="both":a?h="axios":p?h="fetch":h="none";let x=!!i.vitest;if(!x)try{await Nt(Xe.join(e,"vitest.config.ts")),x=!0}catch{}let $="none";if(i["socket.io-client"])try{await Nt(Xe.join(e,"src","lib","utils","ws")),$="present"}catch{}return{hasRedux:o,httpClient:h,hasI18n:s,hasTests:x,ws:$}}catch(t){throw new Error(`Failed to detect project setup: ${t}`,{cause:t})}}});var Ye={};Jt(Ye,{detectProjectSetup:()=>F,directoryExists:()=>de,fileExistsAt:()=>It});var H=Ie(()=>{"use strict";Kn();Zn()});import{Command as sm}from"commander";var en={name:"@teispace/next-maker",version:"3.0.1",description:"Create a new Teispace Next.js application with interactive setup.",keywords:["nextjs","react","typescript","tailwindcss","starter","template","redux"],type:"module",homepage:"https://github.com/teispace/npm-packages/tree/main/packages/next-maker#readme",bugs:{url:"https://github.com/teispace/npm-packages/issues"},license:"MIT",author:"Teispace",files:["dist","README.md","LICENSE","CHANGELOG.md"],main:"dist/index.js",types:"dist/index.d.ts",bin:"dist/index.js",repository:{type:"git",url:"git+https://github.com/teispace/npm-packages.git",directory:"packages/next-maker"},scripts:{build:"tsx build.ts && tsc --emitDeclarationOnly --outDir dist",start:"node dist/index.js",dev:"tsx --watch src/index.ts",test:"vitest run","test:watch":"vitest"},dependencies:{commander:"^15.0.0",degit:"^3.3.2",enquirer:"^2.4.1",ora:"^9.4.0",picocolors:"^1.1.1","png-to-ico":"^3.0.1",sharp:"^0.34.5"},devDependencies:{"@types/degit":"^2.8.6","@types/node":"^25.9.1",esbuild:"^0.28.0",tsx:"^4.22.3",typescript:"^6.0.3",vitest:"^4.1.7"},engines:{node:">=22.12.0"},publishConfig:{access:"public",registry:"https://registry.npmjs.org/"}};import or from"node:path";import X from"picocolors";function tn(e){let{logger:t=s=>console.error(s),exitOnCancel:r=process.env.NODE_ENV!=="test"}=e??{},n=()=>{console.log(""),console.log(""),t("Setup cancelled by user"),console.log(""),r&&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){t(`Uncaught exception: ${s.message}`);return}t(`Uncaught exception: ${String(s)}`)},o=s=>{if(s instanceof Error){t(`Unhandled promise rejection: ${s.message}`);return}t(`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 te from"picocolors";var Ds={reset:e=>e,red:te.red,green:te.green,yellow:te.yellow,blue:te.blue,cyan:te.cyan,magenta:te.magenta,white:te.white,gray:te.gray,bright:te.bold,dim:te.dim};function pe(e,t="reset"){let r=Ds[t]??(n=>n);console.log(r(e))}function St(e){pe(`\u2716 ${e}`,"red")}var v=St;function rn(e){pe(`\u26A0 ${e}`,"yellow")}function l(e){pe(e)}function nn(){console.log(""),pe("\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"),pe("\u2551 \u2551","cyan"),pe("\u2551 \u{1F680} Create Teispace Next.js App \u{1F680} \u2551","cyan"),pe("\u2551 \u2551","cyan"),pe("\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 Ls from"ora";function b(e="",t){let r=Ls({text:e,...t});return r.start(),r}var Ms=e=>e.charAt(0).toUpperCase()+e.slice(1),j=e=>e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase()),R=e=>Ms(j(e));import Gs from"ora";var y=Gs();P();import{execFile as Us}from"node:child_process";import{promisify as Hs}from"node:util";var Bs=Hs(Us),se=(e,t)=>Bs("git",e,t?{cwd:t}:void 0);function zs(e){let t=e.trim();if(!t||t.startsWith("-"))throw new Error(`Invalid git remote "${e}".`);if(!(/^https?:\/\/\S+$/.test(t)||/^git@[\w.-]+:\S+$/.test(t)||/^ssh:\/\/\S+$/.test(t)||/^[\w.-]+\/[\w.-]+$/.test(t)))throw new Error(`Invalid git remote "${e}". Expected an https/ssh URL or "owner/repo".`)}var sn=async(e,t,r)=>{try{if(await se(["init"],e),await se(["add","."],e),await se(["commit","-m","Initial commit from @teispace/next-maker"],e),t&&(zs(t),await se(["remote","add","origin",t],e),r)){await se(["fetch","origin"],e);let n="main";try{await se(["show-branch","origin/main"],e)}catch{try{await se(["show-branch","origin/master"],e),n="master"}catch{n="main"}}await se(["merge",`origin/${n}`,"--allow-unrelated-histories","-X","ours"],e),await se(["push","origin",`HEAD:${n}`],e)}}catch(n){console.warn("Failed to initialize git repository",n)}};import{exec as Js}from"node:child_process";import{promisify as Vs}from"node:util";var Ge=Vs(Js),an=async(e,t)=>{let r=`${t} install`;try{await Ge(r,{cwd:e})}catch(n){throw new Error(`Failed to install dependencies with ${t}: ${n}`,{cause:n})}},J=async(e,t,r)=>{let n=t==="npm"?`${t} run ${r}`:`${t} ${r}`;try{await Ge(n,{cwd:e})}catch(i){console.warn(`Warning: Failed to run script '${r}': ${i}`)}},Ws=()=>{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"},k=async e=>{let{existsSync:t}=await import("node:fs"),r=await import("node:path");return t(r.join(e,"pnpm-lock.yaml"))?"pnpm":t(r.join(e,"yarn.lock"))?"yarn":t(r.join(e,"bun.lockb"))?"bun":t(r.join(e,"package-lock.json"))?"npm":Ws()},qs=async(e,t,r)=>{if(r.length===0)return;let i=`${cn(t)} ${r.join(" ")}`;try{await Ge(i,{cwd:e})}catch(o){throw new Error(`Failed to install packages with ${t}: ${o}`,{cause:o})}},cn=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"}},G=async(e,t)=>{let r=await k(e);await qs(e,r,[t])},Xs=e=>{switch(e){case"npm":return"--save-dev";case"yarn":case"pnpm":case"bun":return"-D";default:return"--save-dev"}},we=async(e,t,r)=>{if(r.length===0)return;let n=cn(t),i=Xs(t),o=`${n} ${i} ${r.join(" ")}`;try{await Ge(o,{cwd:e})}catch(s){throw new Error(`Failed to install dev packages with ${t}: ${s}`,{cause:s})}},Et=async(e,t)=>{let r=await k(e);await we(e,r,[t])},Wt=async(e,t,r)=>{if(r.length===0)return;let i=`${Ys(t)} ${r.join(" ")}`;try{await Ge(i,{cwd:e})}catch(o){throw new Error(`Failed to uninstall packages with ${t}: ${o}`,{cause:o})}},Ys=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"}},Ne=async(e,t)=>{let r=await k(e);await Wt(e,r,[t])};import Ks from"enquirer";var Zs=/^[a-z0-9-_]+$/,Qs=/^\d+\.\d+\.\d+$/,pn=e=>Zs.test(e),ea=e=>Qs.test(e),ln=(e,t={})=>{let r=t.projectName??e??"my-app";if(!pn(r))throw new Error(`Invalid project name "${r}". Use lowercase letters, digits, hyphens, and underscores only.`);let n=t.version??"0.1.0";if(!ea(n))throw new Error(`Invalid version "${n}". Expected semver (e.g. 0.1.0).`);let i=t.author??"Teispace",o=t.company??i;return{projectName:r,description:t.description??"A Next.js application",author:i,version:n,packageManager:t.packageManager??"yarn",gitRemote:t.gitRemote??"",pushToRemote:t.pushToRemote??!1,gitIssues:t.gitIssues??"",gitHomepage:t.gitHomepage??"",httpClient:t.httpClient??"fetch",reactSecureStorage:t.reactSecureStorage??!0,email:t.email??"support@example.com",company:o,keepTemplates:t.keepTemplates??!1,darkMode:t.darkMode??!0,redux:t.redux??!0,ws:(t.redux??!0)&&(t.ws??!1),i18n:t.i18n??!0,communityFiles:t.communityFiles??[],readme:t.readme??!0,docker:t.docker??!1,containerName:t.containerName,imageName:t.imageName,imageTag:t.imageTag,ci:t.ci??!1,preCommitHooks:t.preCommitHooks??!0,commitizen:t.commitizen??!0,copyEnv:t.copyEnv??!0,tests:t.tests??!0,reactCompiler:t.reactCompiler??!0,bundleAnalyzer:t.bundleAnalyzer??!1}},{prompt:ta}=Ks,mn=async e=>{if(e!==void 0&&!pn(e))throw new Error(`Invalid project name "${e}". Use lowercase letters, digits, hyphens, and underscores only \u2014 no slashes, "..", or absolute paths.`);let t=await ta([{type:"input",name:"projectName",message:"What is the project name?",initial:e||"my-app",skip:!!e,validate:r=>/^[a-z0-9-_]+$/.test(r)?!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:r=>/^\d+\.\d+\.\d+$/.test(r)?!0:"Version must be a valid semantic version (x.y.z)."},{type:"input",name:"email",message:"Support email:",initial:"support@example.com",validate:r=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(r)?!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:r=>r?/^https:\/\/github\.com\/[\w-]+\/[\w.-]+\/issues$/.test(r)?!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:r=>r?/^https:\/\/github\.com\/[\w-]+\/[\w.-]+#readme$/.test(r)?!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 r=this.state?.answers??this.enquirer?.answers??{};return!!(r.httpClient&&r.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:"ws",message:"Do you want to include WebSocket support (socket.io-client + Redux bridge)?",initial:!1,skip:function(){return!(this.state?.answers??this.enquirer?.answers??{}).redux}},{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:r=>/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(r)?!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:r=>/^[a-z0-9]+(?:[._-][a-z0-9]+)*$/.test(r)?!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:r=>/^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,127}$/.test(r)?!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(t.company=t.author,t.ws=!!t.redux&&!!t.ws,t.gitRemote&&!t.gitHomepage){let r=t.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"");t.gitHomepage=`${r}#readme`,t.gitIssues=`${r}/issues`}return t};P();import ra from"node:path";var le=async(e,t)=>{let r=na(t);await g(ra.join(e,"test/test-utils.tsx"),r)},na=({redux:e,i18n:t})=>e&&t?ia:e?oa:t?sa:aa,ia=`import { type RenderOptions, render } from '@testing-library/react';
28
28
  import { NextIntlClientProvider } from 'next-intl';
29
29
  import type { ReactElement, ReactNode } from 'react';
30
30
  import { Provider } from 'react-redux';
@@ -85,7 +85,7 @@ export function renderWithProviders(
85
85
 
86
86
  export * from '@testing-library/react';
87
87
  export { default as userEvent } from '@testing-library/user-event';
88
- `,Xs=`import { type RenderOptions, render } from '@testing-library/react';
88
+ `,oa=`import { type RenderOptions, render } from '@testing-library/react';
89
89
  import type { ReactElement, ReactNode } from 'react';
90
90
  import { Provider } from 'react-redux';
91
91
  import { type AppState, type AppStore, makeStore } from '@/store';
@@ -124,7 +124,7 @@ export function renderWithProviders(
124
124
 
125
125
  export * from '@testing-library/react';
126
126
  export { default as userEvent } from '@testing-library/user-event';
127
- `,Ys=`import { type RenderOptions, render } from '@testing-library/react';
127
+ `,sa=`import { type RenderOptions, render } from '@testing-library/react';
128
128
  import { NextIntlClientProvider } from 'next-intl';
129
129
  import type { ReactElement, ReactNode } from 'react';
130
130
  import type { SupportedLocale } from '@/types/i18n';
@@ -164,7 +164,7 @@ export function renderWithProviders(
164
164
 
165
165
  export * from '@testing-library/react';
166
166
  export { default as userEvent } from '@testing-library/user-event';
167
- `,Ks=`import { type RenderOptions, render } from '@testing-library/react';
167
+ `,aa=`import { type RenderOptions, render } from '@testing-library/react';
168
168
  import type { ReactElement, ReactNode } from 'react';
169
169
 
170
170
  type TestProvidersProps = {
@@ -186,8 +186,8 @@ export function renderWithProviders(ui: ReactElement, options: ExtendedRenderOpt
186
186
 
187
187
  export * from '@testing-library/react';
188
188
  export { default as userEvent } from '@testing-library/user-event';
189
- `;import cn from"node:path";var T={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"};S();P();var pn=async(e,t)=>{if(t.bundleAnalyzer)return;let r=cn.join(e,c.NEXT_CONFIG);if(m(r)){let n=await f(r);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 g(r,n)}await D(cn.join(e,c.PACKAGE_JSON),n=>(n.devDependencies&&delete n.devDependencies[T.NEXT_BUNDLE_ANALYZER],n.scripts&&delete n.scripts.analyze,n))};S();P();import Me from"node:path";var ln=async(e,t)=>{t.darkMode||(await E(Me.join(e,c.THEME_PROVIDER)),await Zs(e),await Qs(e),await ta(e))},Zs=async e=>{let t=Me.join(e,c.PROVIDERS_INDEX),r=await f(t);r=r.replace(/export \* from '\.\/CustomThemeProvider';\n/,""),await g(t,r)},Qs=async e=>{let t=Me.join(e,c.GLOBALS_CSS);if(m(t)){let r=await f(t);r=r.replace(/@custom-variant dark \(.*?\);\n\n/,""),r=r.replace(/@theme \{[\s\S]*?\}\n/,""),await g(t,r)}},ea=e=>e.replace(/\bbg-light\b\s?/g,"").replace(/\bdark:bg-dark\b\s?/g,"").replace(/\s{2,}/g," ").replace(/suppressHydrationWarning=\{true\}/g,""),ta=async e=>{let t=[Me.join(e,c.ROOT_LAYOUT),Me.join(e,"src/app/[locale]/layout.tsx")];for(let r of t)if(m(r)){let n=await f(r),i=ea(n);i!==n&&await g(r,i)}};S();P();Ue();import _ from"node:path";var hn=async(e,t)=>{let r=_.join(e,c.HTTP_UTILS),n=t.httpClient!=="none"||!!t.reactSecureStorage;t.httpClient==="none"?(await He(e),await aa(e,r,n)):t.httpClient==="axios"?(await ca(e,r),await Ne(e,["axios"]),await ke(e,["axios"])):t.httpClient==="fetch"?(await pa(e,r),await Ne(e,["fetch"]),await ke(e,["fetch"])):t.httpClient},aa=async(e,t,r)=>{await w(_.join(e,c.AXIOS_CLIENT)),await w(_.join(e,c.FETCH_CLIENT)),r?(await g(_.join(t,"index.ts"),`export * from './token-store';
190
- `),await E(_.join(e,c.CLIENT_UTILS)),await Ie(e,[])):(await w(t),await la(e),await E(_.join(e,c.APP_APIS)),await ma(e)),await da(e),await w(_.join(e,c.ERRORS_DIR)),r||(await w(_.join(e,c.COMMON_TYPES_DIR)),await w(_.join(e,c.UTILITY_TYPES_DIR)),await ua(e))},ca=async(e,t)=>{await w(_.join(e,c.FETCH_CLIENT));let r=await f(_.join(t,"index.ts"));r=r.replace(/export .* from '\.\/fetch-client';\n/g,""),await g(_.join(t,"index.ts"),r);let n=_.join(e,c.HTTP_TYPES);if(m(n)){let i=await f(n);i=i.replace(/export interface FetchClientOptions \{[\s\S]*?\}\n\n/,""),i=i.replace(/export interface ExtendedRequestInit extends RequestInit \{[\s\S]*?\}\n\n/,""),await g(n,i)}},pa=async(e,t)=>{await w(_.join(e,c.AXIOS_CLIENT));let r=await f(_.join(t,"index.ts"));r=r.replace(/export .* from '\.\/axios-client';\n/g,""),await g(_.join(t,"index.ts"),r),await Ie(e,["fetch"]);let n=_.join(e,c.HTTP_TYPES);if(m(n)){let i=await f(n);i=i.replace(/export interface AxiosClientOptions \{[\s\S]*?\}\n\n/,""),await g(n,i)}},la=async e=>{let t=_.join(e,c.UTILS_INDEX);if(m(t)){let r=await f(t);r=r.replace(/export \* from '\.\/http';\n/,""),await g(t,r)}},ma=async e=>{let t=_.join(e,c.CONFIG_INDEX);if(m(t)){let r=await f(t);r=r.replace(/export \* from '\.\/app-apis';\n/,""),await g(t,r)}},da=async e=>{let t=_.join(e,c.CONSTANTS);if(m(t)){let r=await f(t);r=r.replace(/export const API_RESPONSE_DATA_KEY = 'data';\n/,""),r=r.replace(/export const SAVE_AUTH_TOKENS = false;\n/,""),await g(t,r)}},ua=async e=>{let t=_.join(e,c.TYPES_INDEX);if(m(t)){let r=await f(t);r=r.replace(/export \* from '\.\/utility';\n/,""),r=r.replace(/export \* from '\.\/common';\n/,""),await g(t,r)}};S();P();import W from"node:path";var yn=async(e,t)=>{t.i18n||(await ga(e),await ha(e),await ya(e),await xa(e),await fa(e))},fa=async e=>{let t=W.join(e,c.ENV_EXAMPLE);if(!m(t))return;let r=await f(t);r=r.replace(/#[^\n]*IANA time zone[\s\S]*?DEFAULT_TIMEZONE=[^\n]*\n?/,""),r=r.replace(/#[^\n]*Fallback locale[\s\S]*?DEFAULT_LOCALE=[^\n]*\n?/,""),r=r.replace(/^DEFAULT_TIMEZONE=.*\n?/m,""),r=r.replace(/^DEFAULT_LOCALE=.*\n?/m,""),await g(t,r)},ga=async e=>{await w(W.join(e,c.I18N_DIR)),await w(W.join(e,c.LOCALE_DIR)),await E(W.join(e,c.PROXY)),await E(W.join(e,c.MIDDLEWARE)),await E(W.join(e,c.I18N_TYPES)),await E(W.join(e,c.APP_LOCALES))},ha=async e=>{let t=W.join(e,c.TYPES_INDEX);if(m(t)){let n=await f(t);n=n.replace(/export \* from '\.\/i18n';\n/,""),await g(t,n)}let r=W.join(e,c.CONFIG_INDEX);if(m(r)){let n=await f(r);n=n.replace(/export \* from '\.\/app-locales';\n/,""),await g(r,n)}},ya=async e=>{let t=W.join(e,c.NEXT_CONFIG);if(m(t)){let r=await f(t);r=r.replace(/import createNextIntlPlugin from 'next-intl\/plugin';\n/,""),r=r.replace(/const withNextIntl = createNextIntlPlugin\(\);\n+/,""),r=r.replace(/withNextIntl\(([^)]+)\)/,"$1"),await g(t,r)}},xa=async e=>{let t=W.join(e,c.COUNTER_COMPONENT);if(m(t)){let i=await f(t);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 g(t,i)}let r=W.join(e,"src/features/counter/components/Counter.test.tsx"),n=W.join(e,"test/test-utils.tsx");await E(r),await E(n)};S();P();import pe from"node:path";var xn=async(e,t)=>{t.httpClient!=="none"||t.reactSecureStorage||await w(pe.join(e,c.STORAGE_SERVICE))},Pn=async e=>{await E(pe.join(e,c.LICENSE))},wn=async e=>{await E(pe.join(e,c.CHANGELOG))},vn=async e=>{await E(pe.join(e,c.NVM_RC)),await E(pe.join(e,c.NPM_RC))},Sn=async e=>{await w(pe.join(e,c.CLAUDE_DIR)),await w(pe.join(e,c.DOCS_DIR)),await w(pe.join(e,c.VSCODE_DIR))};import Cn from"node:path";S();P();var En=async(e,t)=>{if(t.reactCompiler)return;let r=Cn.join(e,c.NEXT_CONFIG);if(m(r)){let n=await f(r);n=n.replace(/^\s*reactCompiler:\s*true,?\n/m,""),await g(r,n)}await D(Cn.join(e,c.PACKAGE_JSON),n=>(n.devDependencies&&delete n.devDependencies[T.REACT_COMPILER_BABEL],n))};S();P();import Pe from"node:path";var Tn=async(e,t)=>{t.redux||(await w(Pe.join(e,c.STORE)),await w(Pe.join(e,c.COUNTER_FEATURE)),await E(Pe.join(e,c.STORE_PROVIDER)),await E(Pe.join(e,"test/test-utils.tsx")),await Pa(e),await wa(e))},Pa=async e=>{let t=Pe.join(e,c.PROVIDERS_INDEX),r=await f(t);r=r.replace(/export \* from '\.\/StoreProvider';\n/,""),await g(t,r)},wa=async e=>{let t=[Pe.join(e,c.ROOT_PAGE),Pe.join(e,c.LOCALE_PAGE)];for(let r of t)if(m(r)){let n=await f(r);n=n.replace(/import\s+\{\s*Counter\s*\}\s+from\s+['"]@\/features\/counter['"];\n?/,""),n=n.replace(/<Counter\s*\/>\n?/g,""),await g(r,n)}};S();P();import bn from"node:path";var Rn=async(e,t)=>{if(t.i18n)return;let r=bn.join(e,c.SEO_FILE);m(r)&&await g(r,va);let n=bn.join(e,c.SITEMAP_FILE);m(n)&&await g(n,Sa)},va=`import type { Metadata } from 'next';
189
+ `;import un from"node:path";var T={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"};S();P();var fn=async(e,t)=>{if(t.bundleAnalyzer)return;let r=un.join(e,c.NEXT_CONFIG);if(m(r)){let n=await f(r);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 g(r,n)}await D(un.join(e,c.PACKAGE_JSON),n=>(n.devDependencies&&delete n.devDependencies[T.NEXT_BUNDLE_ANALYZER],n.scripts&&delete n.scripts.analyze,n))};S();P();import Ue from"node:path";var gn=async(e,t)=>{t.darkMode||(await C(Ue.join(e,c.THEME_PROVIDER)),await ca(e),await pa(e),await ma(e))},ca=async e=>{let t=Ue.join(e,c.PROVIDERS_INDEX),r=await f(t);r=r.replace(/export \* from '\.\/CustomThemeProvider';\n/,""),await g(t,r)},pa=async e=>{let t=Ue.join(e,c.GLOBALS_CSS);if(m(t)){let r=await f(t);r=r.replace(/@custom-variant dark \(.*?\);\n\n/,""),r=r.replace(/@theme \{[\s\S]*?\}\n/,""),await g(t,r)}},la=e=>e.replace(/\bbg-light\b\s?/g,"").replace(/\bdark:bg-dark\b\s?/g,"").replace(/\s{2,}/g," ").replace(/suppressHydrationWarning=\{true\}/g,""),ma=async e=>{let t=[Ue.join(e,c.ROOT_LAYOUT),Ue.join(e,"src/app/[locale]/layout.tsx")];for(let r of t)if(m(r)){let n=await f(r),i=la(n);i!==n&&await g(r,i)}};S();P();ze();import _ from"node:path";var vn=async(e,t)=>{let r=_.join(e,c.HTTP_UTILS),n=t.httpClient!=="none"||!!t.reactSecureStorage;t.httpClient==="none"?(await Be(e),await ya(e,r,n)):t.httpClient==="axios"?(await xa(e,r),await Ae(e,["axios"]),await _e(e,["axios"])):t.httpClient==="fetch"?(await Pa(e,r),await Ae(e,["fetch"]),await _e(e,["fetch"])):t.httpClient},ya=async(e,t,r)=>{await w(_.join(e,c.AXIOS_CLIENT)),await w(_.join(e,c.FETCH_CLIENT)),r?(await g(_.join(t,"index.ts"),`export * from './token-store';
190
+ `),await C(_.join(e,c.CLIENT_UTILS)),await ke(e,[])):(await w(t),await wa(e),await C(_.join(e,c.APP_APIS)),await va(e)),await Sa(e),await w(_.join(e,c.ERRORS_DIR)),r||(await w(_.join(e,c.COMMON_TYPES_DIR)),await w(_.join(e,c.UTILITY_TYPES_DIR)),await Ea(e))},xa=async(e,t)=>{await w(_.join(e,c.FETCH_CLIENT));let r=await f(_.join(t,"index.ts"));r=r.replace(/export .* from '\.\/fetch-client';\n/g,""),await g(_.join(t,"index.ts"),r);let n=_.join(e,c.HTTP_TYPES);if(m(n)){let i=await f(n);i=i.replace(/export interface FetchClientOptions \{[\s\S]*?\}\n\n/,""),i=i.replace(/export interface ExtendedRequestInit extends RequestInit \{[\s\S]*?\}\n\n/,""),await g(n,i)}},Pa=async(e,t)=>{await w(_.join(e,c.AXIOS_CLIENT));let r=await f(_.join(t,"index.ts"));r=r.replace(/export .* from '\.\/axios-client';\n/g,""),await g(_.join(t,"index.ts"),r),await ke(e,["fetch"]);let n=_.join(e,c.HTTP_TYPES);if(m(n)){let i=await f(n);i=i.replace(/export interface AxiosClientOptions \{[\s\S]*?\}\n\n/,""),await g(n,i)}},wa=async e=>{let t=_.join(e,c.UTILS_INDEX);if(m(t)){let r=await f(t);r=r.replace(/export \* from '\.\/http';\n/,""),await g(t,r)}},va=async e=>{let t=_.join(e,c.CONFIG_INDEX);if(m(t)){let r=await f(t);r=r.replace(/export \* from '\.\/app-apis';\n/,""),await g(t,r)}},Sa=async e=>{let t=_.join(e,c.CONSTANTS);if(m(t)){let r=await f(t);r=r.replace(/export const API_RESPONSE_DATA_KEY = 'data';\n/,""),r=r.replace(/export const SAVE_AUTH_TOKENS = false;\n/,""),await g(t,r)}},Ea=async e=>{let t=_.join(e,c.TYPES_INDEX);if(m(t)){let r=await f(t);r=r.replace(/export \* from '\.\/utility';\n/,""),r=r.replace(/export \* from '\.\/common';\n/,""),await g(t,r)}};S();P();import q from"node:path";var Sn=async(e,t)=>{t.i18n||(await Ta(e),await ba(e),await Ra(e),await $a(e),await Ca(e))},Ca=async e=>{let t=q.join(e,c.ENV_EXAMPLE);if(!m(t))return;let r=await f(t);r=r.replace(/#[^\n]*IANA time zone[\s\S]*?DEFAULT_TIMEZONE=[^\n]*\n?/,""),r=r.replace(/#[^\n]*Fallback locale[\s\S]*?DEFAULT_LOCALE=[^\n]*\n?/,""),r=r.replace(/^DEFAULT_TIMEZONE=.*\n?/m,""),r=r.replace(/^DEFAULT_LOCALE=.*\n?/m,""),await g(t,r)},Ta=async e=>{await w(q.join(e,c.I18N_DIR)),await w(q.join(e,c.LOCALE_DIR)),await C(q.join(e,c.PROXY)),await C(q.join(e,c.MIDDLEWARE)),await C(q.join(e,c.I18N_TYPES)),await C(q.join(e,c.APP_LOCALES))},ba=async e=>{let t=q.join(e,c.TYPES_INDEX);if(m(t)){let n=await f(t);n=n.replace(/export \* from '\.\/i18n';\n/,""),await g(t,n)}let r=q.join(e,c.CONFIG_INDEX);if(m(r)){let n=await f(r);n=n.replace(/export \* from '\.\/app-locales';\n/,""),await g(r,n)}},Ra=async e=>{let t=q.join(e,c.NEXT_CONFIG);if(m(t)){let r=await f(t);r=r.replace(/import createNextIntlPlugin from 'next-intl\/plugin';\n/,""),r=r.replace(/const withNextIntl = createNextIntlPlugin\(\);\n+/,""),r=r.replace(/withNextIntl\(([^)]+)\)/,"$1"),await g(t,r)}},$a=async e=>{let t=q.join(e,c.COUNTER_COMPONENT);if(m(t)){let i=await f(t);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 g(t,i)}let r=q.join(e,"src/features/counter/components/Counter.test.tsx"),n=q.join(e,"test/test-utils.tsx");await C(r),await C(n)};S();P();import me from"node:path";var En=async(e,t)=>{t.httpClient!=="none"||t.reactSecureStorage||await w(me.join(e,c.STORAGE_SERVICE))},Cn=async e=>{await C(me.join(e,c.LICENSE))},Tn=async e=>{await C(me.join(e,c.CHANGELOG))},bn=async e=>{await C(me.join(e,c.NVM_RC)),await C(me.join(e,c.NPM_RC))},Rn=async e=>{await w(me.join(e,c.CLAUDE_DIR)),await w(me.join(e,c.DOCS_DIR)),await w(me.join(e,c.VSCODE_DIR))};import $n from"node:path";S();P();var In=async(e,t)=>{if(t.reactCompiler)return;let r=$n.join(e,c.NEXT_CONFIG);if(m(r)){let n=await f(r);n=n.replace(/^\s*reactCompiler:\s*true,?\n/m,""),await g(r,n)}await D($n.join(e,c.PACKAGE_JSON),n=>(n.devDependencies&&delete n.devDependencies[T.REACT_COMPILER_BABEL],n))};S();P();import ve from"node:path";var Nn=async(e,t)=>{t.redux||(await w(ve.join(e,c.STORE)),await w(ve.join(e,c.COUNTER_FEATURE)),await C(ve.join(e,c.STORE_PROVIDER)),await C(ve.join(e,"test/test-utils.tsx")),await Ia(e),await Na(e))},Ia=async e=>{let t=ve.join(e,c.PROVIDERS_INDEX),r=await f(t);r=r.replace(/export \* from '\.\/StoreProvider';\n/,""),await g(t,r)},Na=async e=>{let t=[ve.join(e,c.ROOT_PAGE),ve.join(e,c.LOCALE_PAGE)];for(let r of t)if(m(r)){let n=await f(r);n=n.replace(/import\s+\{\s*Counter\s*\}\s+from\s+['"]@\/features\/counter['"];\n?/,""),n=n.replace(/<Counter\s*\/>\n?/g,""),await g(r,n)}};S();P();import kn from"node:path";var An=async(e,t)=>{if(t.i18n)return;let r=kn.join(e,c.SEO_FILE);m(r)&&await g(r,ka);let n=kn.join(e,c.SITEMAP_FILE);m(n)&&await g(n,Aa)},ka=`import type { Metadata } from 'next';
191
191
 
192
192
  import { env } from '@/lib/env';
193
193
 
@@ -254,7 +254,7 @@ export function generateSEOMetadata({
254
254
  }
255
255
 
256
256
  export { APP_NAME, APP_URL };
257
- `,Sa=`import type { MetadataRoute } from 'next';
257
+ `,Aa=`import type { MetadataRoute } from 'next';
258
258
 
259
259
  import { env } from '@/lib/env';
260
260
 
@@ -270,13 +270,13 @@ export default function sitemap(): MetadataRoute.Sitemap {
270
270
  priority: path === '/' ? 1 : 0.8,
271
271
  }));
272
272
  }
273
- `;import St from"node:path";S();P();var Ca=[T.VITEST,T.JSDOM,T.VITE_PLUGIN_REACT,T.TESTING_LIBRARY_DOM,T.TESTING_LIBRARY_JEST_DOM,T.TESTING_LIBRARY_REACT,T.TESTING_LIBRARY_USER_EVENT],$n=async(e,t)=>{t.tests||(await E(St.join(e,c.VITEST_CONFIG)),await w(St.join(e,c.TEST_DIR)),await E(St.join(e,"src/features/counter/components/Counter.test.tsx")),await D(St.join(e,c.PACKAGE_JSON),r=>{if(r.devDependencies)for(let n of Ca)delete r.devDependencies[n];return r.scripts&&(delete r.scripts.test,delete r.scripts["test:watch"],delete r.scripts["test:coverage"],typeof r.scripts.validate=="string"&&(r.scripts.validate=r.scripts.validate.replace(/\s*&&\s*yarn\s+test(?![:\w])/,"").replace(/\byarn\s+test(?![:\w])\s*&&\s*/,""))),r}))};S();P();import Je from"node:path";S();P();import In from"node:path";import{readFile as Ea,writeFile as Ta}from"node:fs/promises";import ba from"node:path";var Be=(e,t)=>{let r=/import\s+.*\s+from\s+['"].*['"];?\n/g,n=e.match(r);if(n&&n.length>0){let i=n[n.length-1],o=e.lastIndexOf(i);return e.slice(0,o+i.length)+t+`
273
+ `;import Ct from"node:path";S();P();var _a=[T.VITEST,T.JSDOM,T.VITE_PLUGIN_REACT,T.TESTING_LIBRARY_DOM,T.TESTING_LIBRARY_JEST_DOM,T.TESTING_LIBRARY_REACT,T.TESTING_LIBRARY_USER_EVENT],_n=async(e,t)=>{t.tests||(await C(Ct.join(e,c.VITEST_CONFIG)),await w(Ct.join(e,c.TEST_DIR)),await C(Ct.join(e,"src/features/counter/components/Counter.test.tsx")),await D(Ct.join(e,c.PACKAGE_JSON),r=>{if(r.devDependencies)for(let n of _a)delete r.devDependencies[n];return r.scripts&&(delete r.scripts.test,delete r.scripts["test:watch"],delete r.scripts["test:coverage"],typeof r.scripts.validate=="string"&&(r.scripts.validate=r.scripts.validate.replace(/\s*&&\s*yarn\s+test(?![:\w])/,"").replace(/\byarn\s+test(?![:\w])\s*&&\s*/,""))),r}))};S();P();import We from"node:path";S();P();import On from"node:path";import{readFile as Oa,writeFile as Fa}from"node:fs/promises";import ja from"node:path";var Je=(e,t)=>{let r=/import\s+.*\s+from\s+['"].*['"];?\n/g,n=e.match(r);if(n&&n.length>0){let i=n[n.length-1],o=e.lastIndexOf(i);return e.slice(0,o+i.length)+t+`
274
274
  `+e.slice(o+i.length)}return`${t}
275
- ${e}`},Qt=(e,t,r)=>{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=`
275
+ ${e}`},nr=(e,t,r)=>{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=`
276
276
  ${t}: ${r},`,a=o.trimEnd()+s;return e.replace(n,`combineReducers({${a}
277
- })`)},ze=(e,t)=>{let r=e.lastIndexOf("} as const;");if(r===-1)throw new Error("Could not find closing brace of AppApis object");let n=e.substring(0,r),i=e.substring(r);return`${n.trimEnd()}
277
+ })`)},Ve=(e,t)=>{let r=e.lastIndexOf("} as const;");if(r===-1)throw new Error("Could not find closing brace of AppApis object");let n=e.substring(0,r),i=e.substring(r);return`${n.trimEnd()}
278
278
  ${t}
279
- ${i}`};var we=async e=>{let{projectPath:t,name:r,persist:n,importPath:i}=e,o=ba.join(t,"src","store","rootReducer.ts");try{let s=await Ea(o,"utf-8"),a=j(r),p=`${a}Reducer`,u=`${a}PersistConfig`,d=i.replace(/^src\//,"@/"),h=n?`import { ${p}, ${u} } from '${d}';`:`import { ${p} } from '${d}';`;s=Be(s,h);let x=n?`persistReducer(${u}, ${p})`:p;s=Qt(s,a,x),await Ta(o,s)}catch(s){throw new Error(`Failed to register reducer '${r}' in rootReducer: ${s}`,{cause:s})}};var Nn="import { attachWsBridge, wsClient } from '@/lib/utils/ws';",Ra=`
279
+ ${i}`};var Se=async e=>{let{projectPath:t,name:r,persist:n,importPath:i}=e,o=ja.join(t,"src","store","rootReducer.ts");try{let s=await Oa(o,"utf-8"),a=j(r),p=`${a}Reducer`,u=`${a}PersistConfig`,d=i.replace(/^src\//,"@/"),h=n?`import { ${p}, ${u} } from '${d}';`:`import { ${p} } from '${d}';`;s=Je(s,h);let x=n?`persistReducer(${u}, ${p})`:p;s=nr(s,a,x),await Fa(o,s)}catch(s){throw new Error(`Failed to register reducer '${r}' in rootReducer: ${s}`,{cause:s})}};var Fn="import { attachWsBridge, wsClient } from '@/lib/utils/ws';",Da=`
280
280
  // Bridge the WS client's lifecycle into the Redux slice exactly once per
281
281
  // store instance. The bridge does not open a connection \u2014 that happens
282
282
  // lazily on first \`useWsEvent\` subscription or an explicit \`connect()\`.
@@ -286,12 +286,12 @@ ${i}`};var we=async e=>{let{projectPath:t,name:r,persist:n,importPath:i}=e,o=ba.
286
286
  if (!store) return;
287
287
  return attachWsBridge(wsClient, store.dispatch);
288
288
  }, []);
289
- `,kn=async e=>{await we({projectPath:e,name:"ws",persist:!1,importPath:"src/store/slices/ws.slice"})},$a=e=>{if(e.includes("from '@/lib/utils/ws'"))return e;let t=e,r=/(^import\s[^\n]*\n)+/m,n=t.match(r);if(!n)throw new Error("injectBridgeMount: no `import` lines found \u2014 expected a StoreProvider with imports.");let i=(n.index??0)+n[0].length;t=`${t.slice(0,i)}${Nn}
290
- ${t.slice(i)}`,t=Aa(t);let o=/(if\s*\(\s*!storeRef\.current\s*\)\s*\{[\s\S]*?\n\s*\})/;if(!t.match(o))throw new Error("injectBridgeMount: could not locate `if (!storeRef.current) { ... }` initializer \u2014 StoreProvider shape unexpected.");return t=t.replace(o,`$1
291
- ${Ra.trimEnd()}
292
- `),t},Ct=e=>{let t=e;return t=t.replace(new RegExp(`${_a(Nn)}\\n?`),""),t=t.replace(/\n(?:[ \t]*\/\/[^\n]*\n)*[ \t]*useEffect\(\(\)\s*=>\s*\{[\s\S]*?attachWsBridge\(wsClient,\s*store\.dispatch\)[\s\S]*?\},\s*\[\]\);\n?/,`
293
- `),/\buseEffect\s*\(/.test(t)||(t=Ia(t)),t},Ia=e=>{let t=/import\s*\{([^}]*)\}\s*from\s*['"]react['"];\n?/,r=e.match(t);if(!r)return e;let n=r[1].split(",").map(o=>o.trim()).filter(o=>o.length>0&&o!=="useEffect");if(n.length===0)return e.replace(t,"");let i=`import { ${n.join(", ")} } from 'react';
294
- `;return e.replace(t,i)},An=async e=>{let t=In.join(e,c.STORE_PROVIDER);if(!m(t))return;let r=await f(t),n=$a(r);n!==r&&await g(t,n)};var _n=async e=>{let t=In.join(e,c.TEST_SETUP_FILE);if(!m(t))return;let r=await f(t),n=!1;r.includes("vi.mock('react-secure-storage'")||(r+=Na,n=!0),r.includes("vi.mock('server-only'")||(r+=ka,n=!0),n&&await g(t,r)},Na=`
289
+ `,jn=async e=>{await Se({projectPath:e,name:"ws",persist:!1,importPath:"src/store/slices/ws.slice"})},La=e=>{if(e.includes("from '@/lib/utils/ws'"))return e;let t=e,r=/(^import\s[^\n]*\n)+/m,n=t.match(r);if(!n)throw new Error("injectBridgeMount: no `import` lines found \u2014 expected a StoreProvider with imports.");let i=(n.index??0)+n[0].length;t=`${t.slice(0,i)}${Fn}
290
+ ${t.slice(i)}`,t=Ha(t);let o=/(if\s*\(\s*!storeRef\.current\s*\)\s*\{[\s\S]*?\n\s*\})/;if(!t.match(o))throw new Error("injectBridgeMount: could not locate `if (!storeRef.current) { ... }` initializer \u2014 StoreProvider shape unexpected.");return t=t.replace(o,`$1
291
+ ${Da.trimEnd()}
292
+ `),t},Tt=e=>{let t=e;return t=t.replace(new RegExp(`${Ba(Fn)}\\n?`),""),t=t.replace(/\n(?:[ \t]*\/\/[^\n]*\n)*[ \t]*useEffect\(\(\)\s*=>\s*\{[\s\S]*?attachWsBridge\(wsClient,\s*store\.dispatch\)[\s\S]*?\},\s*\[\]\);\n?/,`
293
+ `),/\buseEffect\s*\(/.test(t)||(t=Ma(t)),t},Ma=e=>{let t=/import\s*\{([^}]*)\}\s*from\s*['"]react['"];\n?/,r=e.match(t);if(!r)return e;let n=r[1].split(",").map(o=>o.trim()).filter(o=>o.length>0&&o!=="useEffect");if(n.length===0)return e.replace(t,"");let i=`import { ${n.join(", ")} } from 'react';
294
+ `;return e.replace(t,i)},Dn=async e=>{let t=On.join(e,c.STORE_PROVIDER);if(!m(t))return;let r=await f(t),n=La(r);n!==r&&await g(t,n)};var Ln=async e=>{let t=On.join(e,c.TEST_SETUP_FILE);if(!m(t))return;let r=await f(t),n=!1;r.includes("vi.mock('react-secure-storage'")||(r+=Ga,n=!0),r.includes("vi.mock('server-only'")||(r+=Ua,n=!0),n&&await g(t,r)},Ga=`
295
295
  // \`react-secure-storage\` constructs an \`EncryptionService\` at module load
296
296
  // that fingerprints the browser via \`<canvas>.getContext\`. jsdom doesn't
297
297
  // implement canvas, so the import explodes anywhere it's pulled in
@@ -308,15 +308,15 @@ vi.mock('react-secure-storage', () => {
308
308
  },
309
309
  };
310
310
  });
311
- `,ka=`
311
+ `,Ua=`
312
312
  // \`server-only\` throws at module load outside a Next.js server bundle \u2014
313
313
  // the package relies on bundler-level redirect to a no-op file in server
314
314
  // environments. Vitest doesn't do that redirect, so we stub it as a no-op
315
315
  // to let unit tests reach the server-side modules. Production builds are
316
316
  // unaffected; Next.js still routes \`server-only\` to its real implementation.
317
317
  vi.mock('server-only', () => ({}));
318
- `,Aa=e=>{let t=/import\s*\{([^}]*)\}\s*from\s*['"]react['"];/,r=e.match(t);if(!r)return e;let n=r[1];if(/\buseEffect\b/.test(n))return e;let i=n.split(",").map(s=>s.trim()).filter(Boolean);i.push("useEffect"),i.sort();let o=`import { ${i.join(", ")} } from 'react';`;return e.replace(t,o)},_a=e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),Et=e=>{let t=e;return t=t.replace(/^import\s*\{\s*wsReducer\s*\}\s*from\s*['"][^'"]*ws\.slice['"];\n?/m,""),t=t.replace(/^\s*ws:\s*wsReducer,?\n/m,""),t=t.replace(/\/\*\*[^*]*(?:\*(?!\/)[^*]*)*\bws\b[^*]*(?:\*(?!\/)[^*]*)*\bpersistReducer\b[\s\S]*?\*\/\n?/,""),t};var On=async(e,t)=>{t.ws||(await w(Je.join(e,c.WS_UTILS)),await E(Je.join(e,c.WS_SLICE_FILE)),t.redux&&(await Oa(e),await Fa(e)),await ja(e))},Oa=async e=>{let t=Je.join(e,c.ROOT_REDUCER);if(!m(t))return;let r=await f(t),n=Et(r);n!==r&&await g(t,n)},Fa=async e=>{let t=Je.join(e,c.STORE_PROVIDER);if(!m(t))return;let r=await f(t),n=Ct(r);n!==r&&await g(t,n)},ja=async e=>{let t=Je.join(e,c.PACKAGE_JSON);if(!m(t))return;let r=JSON.parse(await f(t));({...r.dependencies,...r.devDependencies})["socket.io-client"]&&await $e(e,"socket.io-client")};var Fn=async(e,t)=>{let r=b("Customizing features...");try{await hn(e,t),await xn(e,t),await On(e,t),await Tn(e,t),await ln(e,t),await pn(e,t),await yn(e,t),await Rn(e,t),await En(e,t),await $n(e,t),await Pn(e),await wn(e),await vn(e),await Sn(e),t.tests&&await ce(e,{redux:t.redux,i18n:t.i18n}),r.succeed("Features customized.")}catch(n){throw r.fail("Failed to customize features."),n}};import Da from"node:path";S();P();var jn=async(e,t)=>{let r=b("Configuring package.json...");try{let n=t.gitRemote,i=t.gitHomepage,o=t.gitIssues;t.gitRemote&&(t.gitRemote.startsWith("git@github.com:")&&(n=t.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 D(Da.join(e,c.PACKAGE_JSON),s=>(s.name=t.projectName,s.version=t.version,s.description=t.description,s.author=t.author,delete s.packageManager,t.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),t.redux||(delete s.dependencies[T.REDUX_TOOLKIT],delete s.dependencies[T.REACT_REDUX],delete s.dependencies[T.REDUX],delete s.dependencies[T.REDUX_PERSIST]),t.httpClient!=="none"||t.reactSecureStorage||delete s.dependencies[T.REACT_SECURE_STORAGE],t.i18n||delete s.dependencies[T.NEXT_INTL],t.darkMode||delete s.dependencies[T.NEXT_THEMES],t.httpClient==="none"?delete s.dependencies[T.AXIOS]:t.httpClient==="fetch"&&delete s.dependencies[T.AXIOS],s)),r.succeed("package.json configured.")}catch(n){throw r.fail("Failed to configure package.json."),n}};import{readdir as Dn}from"node:fs/promises";import O from"node:path";S();P();var Ln=async(e,t)=>{await La(e,t),await Ma(e,t),await Ga(e,t),await Ha(e,t),await Ua(e,t),await Ba(e,t),await za(e,t)},La=async(e,t)=>{t.preCommitHooks||(await w(O.join(e,c.HUSKY_DIR)),await E(O.join(e,c.COMMITLINT_CONFIG)),await E(O.join(e,c.LINTSTAGED_RC)),await D(O.join(e,c.PACKAGE_JSON),r=>(delete r.devDependencies[T.HUSKY],delete r.devDependencies[T.COMMITLINT_CLI],delete r.devDependencies[T.COMMITLINT_CONFIG],delete r.devDependencies[T.LINT_STAGED],delete r.scripts.prepare,delete r.scripts.postinstall,delete r.commitlint,delete r["lint-staged"],r)))},Ma=async(e,t)=>{t.commitizen||(await E(O.join(e,c.CZRC)),await D(O.join(e,c.PACKAGE_JSON),r=>(delete r.devDependencies[T.COMMITIZEN],delete r.devDependencies[T.CZ_CONVENTIONAL_CHANGELOG],delete r.config?.commitizen,r.config&&Object.keys(r.config).length===0&&delete r.config,delete r.scripts.commit,r)))},Ga=async(e,t)=>{t.ci||await w(O.join(e,c.GITHUB_WORKFLOWS))},Ha=async(e,t)=>{let r=O.join(e,c.GITHUB_DIR);if(!t.keepTemplates)await w(O.join(r,c.GITHUB_ISSUE_TEMPLATE)),await E(O.join(r,c.GITHUB_PR_TEMPLATE));else{let n=O.join(r,c.GITHUB_ISSUE_TEMPLATE),i=O.join(r,c.GITHUB_PR_TEMPLATE),o=s=>s.replace(/Teispace/g,t.company).replace(/support@teispace\.com/g,t.email).replace(/Next\.js Starter/g,t.projectName).replace(/\[AUTHOR\]/g,t.author).replace(/\[COMPANY\]/g,t.company).replace(/\[EMAIL\]/g,t.email);if(m(i)){let s=await f(i);s=o(s),await g(i,s)}try{if(m(n)){let s=await Dn(n);for(let a of s){let p=O.join(n,a),u=await f(p);u=o(u),await g(p,u)}}}catch{}}},Ua=async(e,t)=>{let r=[c.CODE_OF_CONDUCT,c.CONTRIBUTING,c.SECURITY];for(let n of r)t.communityFiles.includes(n)||await E(O.join(e,n))},Ba=async(e,t)=>{if(t.docker){let r=O.join(e,c.ENV_EXAMPLE);if(m(r)){let n=await f(r),i=(o,s)=>{let a=new RegExp(`${o}=.*`);a.test(n)?n=n.replace(a,`${o}=${s}`):n+=`${o}=${s}
319
- `};i("CONTAINER_NAME",t.containerName||"next-app"),i("IMAGE_NAME",t.imageName||"nextjs-starter"),i("IMAGE_TAG",t.imageTag||"latest"),await g(r,n)}}else{await E(O.join(e,c.DOCKERFILE)),await E(O.join(e,c.DOCKER_COMPOSE)),await E(O.join(e,c.DOCKERIGNORE));let r=O.join(e,c.ENV_EXAMPLE);if(m(r)){let n=await f(r);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 g(r,n)}}},za=async(e,t)=>{let r=async o=>{let s=await Dn(o,{withFileTypes:!0}),a=[];for(let p of s){let u=O.join(o,p.name);p.isDirectory()&&p.name!=="node_modules"&&p.name!==".git"?a.push(...await r(u)):p.isFile()&&p.name.toLowerCase()==="readme.md"&&a.push(u)}return a},n=await r(e),i=O.join(e,c.README);for(let o of n)o!==i&&await E(o);if(t.readme){let o=`# ${t.projectName}
318
+ `,Ha=e=>{let t=/import\s*\{([^}]*)\}\s*from\s*['"]react['"];/,r=e.match(t);if(!r)return e;let n=r[1];if(/\buseEffect\b/.test(n))return e;let i=n.split(",").map(s=>s.trim()).filter(Boolean);i.push("useEffect"),i.sort();let o=`import { ${i.join(", ")} } from 'react';`;return e.replace(t,o)},Ba=e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),bt=e=>{let t=e;return t=t.replace(/^import\s*\{\s*wsReducer\s*\}\s*from\s*['"][^'"]*ws\.slice['"];\n?/m,""),t=t.replace(/^\s*ws:\s*wsReducer,?\n/m,""),t=t.replace(/\/\*\*[^*]*(?:\*(?!\/)[^*]*)*\bws\b[^*]*(?:\*(?!\/)[^*]*)*\bpersistReducer\b[\s\S]*?\*\/\n?/,""),t};var Mn=async(e,t)=>{t.ws||(await w(We.join(e,c.WS_UTILS)),await C(We.join(e,c.WS_SLICE_FILE)),t.redux&&(await za(e),await Ja(e)),await Va(e))},za=async e=>{let t=We.join(e,c.ROOT_REDUCER);if(!m(t))return;let r=await f(t),n=bt(r);n!==r&&await g(t,n)},Ja=async e=>{let t=We.join(e,c.STORE_PROVIDER);if(!m(t))return;let r=await f(t),n=Tt(r);n!==r&&await g(t,n)},Va=async e=>{let t=We.join(e,c.PACKAGE_JSON);if(!m(t))return;let r=JSON.parse(await f(t));({...r.dependencies,...r.devDependencies})["socket.io-client"]&&await Ne(e,"socket.io-client")};var Gn=async(e,t)=>{let r=b("Customizing features...");try{await vn(e,t),await En(e,t),await Mn(e,t),await Nn(e,t),await gn(e,t),await fn(e,t),await Sn(e,t),await An(e,t),await In(e,t),await _n(e,t),await Cn(e),await Tn(e),await bn(e),await Rn(e),t.tests&&await le(e,{redux:t.redux,i18n:t.i18n}),r.succeed("Features customized.")}catch(n){throw r.fail("Failed to customize features."),n}};import Wa from"node:path";S();P();var Un=async(e,t)=>{let r=b("Configuring package.json...");try{let n=t.gitRemote,i=t.gitHomepage,o=t.gitIssues;t.gitRemote&&(t.gitRemote.startsWith("git@github.com:")&&(n=t.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 D(Wa.join(e,c.PACKAGE_JSON),s=>(s.name=t.projectName,s.version=t.version,s.description=t.description,s.author=t.author,delete s.packageManager,t.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),t.redux||(delete s.dependencies[T.REDUX_TOOLKIT],delete s.dependencies[T.REACT_REDUX],delete s.dependencies[T.REDUX],delete s.dependencies[T.REDUX_PERSIST]),t.httpClient!=="none"||t.reactSecureStorage||delete s.dependencies[T.REACT_SECURE_STORAGE],t.i18n||delete s.dependencies[T.NEXT_INTL],t.darkMode||delete s.dependencies[T.NEXT_THEMES],t.httpClient==="none"?delete s.dependencies[T.AXIOS]:t.httpClient==="fetch"&&delete s.dependencies[T.AXIOS],s)),r.succeed("package.json configured.")}catch(n){throw r.fail("Failed to configure package.json."),n}};import{readdir as Hn}from"node:fs/promises";import O from"node:path";S();P();var Bn=async(e,t)=>{await qa(e,t),await Xa(e,t),await Ya(e,t),await Ka(e,t),await Za(e,t),await Qa(e,t),await ec(e,t)},qa=async(e,t)=>{t.preCommitHooks||(await w(O.join(e,c.HUSKY_DIR)),await C(O.join(e,c.COMMITLINT_CONFIG)),await C(O.join(e,c.LINTSTAGED_RC)),await D(O.join(e,c.PACKAGE_JSON),r=>(delete r.devDependencies[T.HUSKY],delete r.devDependencies[T.COMMITLINT_CLI],delete r.devDependencies[T.COMMITLINT_CONFIG],delete r.devDependencies[T.LINT_STAGED],delete r.scripts.prepare,delete r.scripts.postinstall,delete r.commitlint,delete r["lint-staged"],r)))},Xa=async(e,t)=>{t.commitizen||(await C(O.join(e,c.CZRC)),await D(O.join(e,c.PACKAGE_JSON),r=>(delete r.devDependencies[T.COMMITIZEN],delete r.devDependencies[T.CZ_CONVENTIONAL_CHANGELOG],delete r.config?.commitizen,r.config&&Object.keys(r.config).length===0&&delete r.config,delete r.scripts.commit,r)))},Ya=async(e,t)=>{t.ci||await w(O.join(e,c.GITHUB_WORKFLOWS))},Ka=async(e,t)=>{let r=O.join(e,c.GITHUB_DIR);if(!t.keepTemplates)await w(O.join(r,c.GITHUB_ISSUE_TEMPLATE)),await C(O.join(r,c.GITHUB_PR_TEMPLATE));else{let n=O.join(r,c.GITHUB_ISSUE_TEMPLATE),i=O.join(r,c.GITHUB_PR_TEMPLATE),o=s=>s.replace(/Teispace/g,t.company).replace(/support@teispace\.com/g,t.email).replace(/Next\.js Starter/g,t.projectName).replace(/\[AUTHOR\]/g,t.author).replace(/\[COMPANY\]/g,t.company).replace(/\[EMAIL\]/g,t.email);if(m(i)){let s=await f(i);s=o(s),await g(i,s)}try{if(m(n)){let s=await Hn(n);for(let a of s){let p=O.join(n,a),u=await f(p);u=o(u),await g(p,u)}}}catch{}}},Za=async(e,t)=>{let r=[c.CODE_OF_CONDUCT,c.CONTRIBUTING,c.SECURITY];for(let n of r)t.communityFiles.includes(n)||await C(O.join(e,n))},Qa=async(e,t)=>{if(t.docker){let r=O.join(e,c.ENV_EXAMPLE);if(m(r)){let n=await f(r),i=(o,s)=>{let a=new RegExp(`${o}=.*`);a.test(n)?n=n.replace(a,`${o}=${s}`):n+=`${o}=${s}
319
+ `};i("CONTAINER_NAME",t.containerName||"next-app"),i("IMAGE_NAME",t.imageName||"nextjs-starter"),i("IMAGE_TAG",t.imageTag||"latest"),await g(r,n)}}else{await C(O.join(e,c.DOCKERFILE)),await C(O.join(e,c.DOCKER_COMPOSE)),await C(O.join(e,c.DOCKERIGNORE));let r=O.join(e,c.ENV_EXAMPLE);if(m(r)){let n=await f(r);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 g(r,n)}}},ec=async(e,t)=>{let r=async o=>{let s=await Hn(o,{withFileTypes:!0}),a=[];for(let p of s){let u=O.join(o,p.name);p.isDirectory()&&p.name!=="node_modules"&&p.name!==".git"?a.push(...await r(u)):p.isFile()&&p.name.toLowerCase()==="readme.md"&&a.push(u)}return a},n=await r(e),i=O.join(e,c.README);for(let o of n)o!==i&&await C(o);if(t.readme){let o=`# ${t.projectName}
320
320
 
321
321
  ${t.description}
322
322
 
@@ -329,7 +329,7 @@ ${t.packageManager==="npm"?"npm run dev":`${t.packageManager} dev`}
329
329
  \`\`\`
330
330
 
331
331
  Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
332
- `;await g(i,o)}else await E(i)};S();P();import er from"node:path";var Mn=async(e,t)=>{let r=[];t.i18n&&r.push("import { type AbstractIntlMessages, NextIntlClientProvider } from 'next-intl';"),t.darkMode&&r.push("import { CustomThemeProvider } from '@/providers';"),t.redux&&r.push("import type { AppState } from '@/store';"),t.i18n&&r.push("import type { SupportedLocale } from '@/types/i18n';"),t.redux&&r.push("import { StoreProvider } from './StoreProvider';");let n=["children: React.ReactNode;"],i=["children"];t.i18n&&(n.push("locale: SupportedLocale;"),n.push("messages: AbstractIntlMessages;"),n.push("timeZone: string;"),i.push("locale","messages","timeZone")),t.redux&&(n.push("preloadedState?: Partial<AppState>;"),i.push("preloadedState"));let o="{children}";t.i18n&&(o=`<NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>
332
+ `;await g(i,o)}else await C(i)};S();P();import ir from"node:path";var zn=async(e,t)=>{let r=[];t.i18n&&r.push("import { type AbstractIntlMessages, NextIntlClientProvider } from 'next-intl';"),t.darkMode&&r.push("import { CustomThemeProvider } from '@/providers';"),t.redux&&r.push("import type { AppState } from '@/store';"),t.i18n&&r.push("import type { SupportedLocale } from '@/types/i18n';"),t.redux&&r.push("import { StoreProvider } from './StoreProvider';");let n=["children: React.ReactNode;"],i=["children"];t.i18n&&(n.push("locale: SupportedLocale;"),n.push("messages: AbstractIntlMessages;"),n.push("timeZone: string;"),i.push("locale","messages","timeZone")),t.redux&&(n.push("preloadedState?: Partial<AppState>;"),i.push("preloadedState"));let o="{children}";t.i18n&&(o=`<NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>
333
333
  ${o}
334
334
  </NextIntlClientProvider>`),t.darkMode&&(o=`<CustomThemeProvider>
335
335
  ${o}
@@ -349,7 +349,7 @@ export const RootProvider = ({ ${i.join(", ")} }: RootProviderProps) => {
349
349
  ${o}
350
350
  );
351
351
  };
352
- `;await g(er.join(e,c.ROOT_PROVIDER),a)},Gn=async(e,t)=>{if(t.i18n)return;let r=`\`\${livvic.variable} ${t.darkMode?"bg-light antialiased dark:bg-dark":"antialiased"}\``,n=(t.redux,""),i=t.httpClient!=="none",o=i?`// Regression sentinel \u2014 see file comment for what this guards.
352
+ `;await g(ir.join(e,c.ROOT_PROVIDER),a)},Jn=async(e,t)=>{if(t.i18n)return;let r=`\`\${livvic.variable} ${t.darkMode?"bg-light antialiased dark:bg-dark":"antialiased"}\``,n=(t.redux,""),i=t.httpClient!=="none",o=i?`// Regression sentinel \u2014 see file comment for what this guards.
353
353
  import { HttpClientBundleSentinel } from '@/lib/utils/http/__bundle-sentinel__/client-bundle-sentinel';
354
354
  `:"",s=i?`
355
355
  <HttpClientBundleSentinel />`:"",a=`import type { Metadata } from 'next';
@@ -384,7 +384,7 @@ export default function RootLayout({
384
384
  </html>
385
385
  );
386
386
  }
387
- `;await g(er.join(e,c.ROOT_LAYOUT),a);let p=t.redux?`import { Counter } from '@/features/counter';
387
+ `;await g(ir.join(e,c.ROOT_LAYOUT),a);let p=t.redux?`import { Counter } from '@/features/counter';
388
388
 
389
389
  `:"",u=t.redux?`
390
390
  <Counter />`:"",d=`${p}export default function Home() {
@@ -395,13 +395,13 @@ export default function RootLayout({
395
395
  </div>
396
396
  );
397
397
  }
398
- `;await g(er.join(e,c.ROOT_PAGE),d)};import Ja from"degit";var Hn=async e=>{let t=b("Downloading template...");try{await Ja("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!0}).clone(e),t.succeed("Template downloaded successfully.")}catch(r){throw t.fail("Failed to download template."),r}};var rr=["npm","yarn","pnpm","bun"],Va=e=>{if(e!==void 0){if(!rr.includes(e))throw new Error(`Invalid --package-manager "${e}". Valid: ${rr.join(", ")}.`);return e}},Un=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: ${rr.join(", ")})`).action(async(t,r)=>{try{let n=Va(r.packageManager);await qa(t,{yes:r.yes??!1,packageManager:n})}catch(n){v(`${n instanceof Error?n.message:n}`),process.exit(1)}})},Ve=async(e,t,r,n)=>{let i=b(e);n.current=i;try{let o=await r();return i.succeed(t),o}finally{n.current===i&&(n.current=null)}},Wa=e=>{let t=[];e.darkMode&&t.push("dark mode"),e.redux&&t.push("redux"),e.i18n&&t.push("i18n"),e.tests&&t.push("tests"),e.reactCompiler&&t.push("react-compiler"),e.preCommitHooks&&t.push("pre-commit hooks"),e.commitizen&&t.push("commitizen"),e.httpClient!=="none"&&t.push(`http (${e.httpClient})`),l(q.dim("Defaults applied (run `next-maker remove <feature>` to undo any of them):")),l(q.dim(` package manager : ${e.packageManager}`)),l(q.dim(` features : ${t.join(", ")}`)),l("")},qa=async(e,t)=>{Qr();let r;t.yes?(r=on(e,{packageManager:t.packageManager}),l(q.cyan(`\u2728 Bootstrapping ${r.projectName} with the recommended defaults`)),l(""),Wa(r)):(l("Welcome to the Teispace Next.js App Creator!"),l(""),r=await sn(e),t.packageManager&&(r={...r,packageManager:t.packageManager}));let n=tr.resolve(process.cwd(),r.projectName);m(n)&&(console.error(q.red(`Error: Directory ${r.projectName} already exists.`)),process.exit(1));let i={current:null},o=async()=>{if(m(n)){i.current?.stop(),i.current=null,console.log(q.yellow(`
399
- Cleaning up: Deleting directory ${r.projectName}...`));try{await w(n),console.log(q.green("Cleanup successful."))}catch(a){console.error(q.red(`Failed to clean up directory ${r.projectName}:`),a)}}},s=async()=>{console.log(q.red(`
400
- Process interrupted. Cleaning up...`)),await o(),process.exit(1)};process.on("SIGINT",s),process.on("SIGTERM",s);try{if(await Hn(n),await jn(n,r),await Fn(n,r),await Ve("Generating providers and layout...","Providers and layout generated.",async()=>{await Mn(n,r),await Gn(n,r)},i),await Ve("Setting up developer tools...","Developer tools configured.",()=>Ln(n,r),i),await Ve("Initializing Git...","Git initialized.",()=>tn(n,r.gitRemote,r.pushToRemote),i),await Ve("Installing dependencies...","Dependencies installed.",()=>rn(n,r.packageManager),i),await Ve("Formatting and linting...","Formatted.",()=>z(n,r.packageManager,"lint:fix"),i),r.copyEnv){let a=tr.join(n,".env.example"),p=tr.join(n,".env");m(a)&&await(await import("node:fs/promises")).copyFile(a,p)}process.off("SIGINT",s),process.off("SIGTERM",s),l(""),l(q.green(`\u2728 Project ${r.projectName} created successfully!`)),l(""),l("To get started:"),l(q.cyan(` cd ${r.projectName}`)),l(q.cyan(` ${r.packageManager==="npm"?"npm run dev":`${r.packageManager} dev`}`)),l("")}catch(a){i.current?.fail("Failed to create project."),i.current=null,console.error(a),await o(),process.exit(1)}};import hr from"node:path";import te from"picocolors";H();import{mkdir as Wn,writeFile as ir}from"node:fs/promises";import ve from"node:path";P();var nr=e=>{let{componentName:t,isClient:r,hasI18n:n}=e,i=e.translationNamespace||t,o=[];return(r||n)&&o.push("'use client';"),n&&o.push("import { useTranslations } from 'next-intl';"),o.push(""),o.push(`export function ${t}() {`),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>${t}</h2>`),o.push(" </div>"),o.push(" );")),o.push("}"),o.push(""),o.join(`
401
- `)},Vn=e=>`export { ${e.componentName} } from './${e.componentName}';
402
- `;var or=async e=>{let{name:t,projectPath:r,isClient:n,hasI18n:i,featurePath:o}=e,s=R(t);o?await Za(s,r,o,n,i):await Qa(s,t,r,n,i)},Za=async(e,t,r,n,i)=>{let o=ve.join(t,r,"components");await Wn(o,{recursive:!0}),await ir(ve.join(o,`${e}.tsx`),nr({componentName:e,isClient:n,hasI18n:i}))},Qa=async(e,t,r,n,i)=>{let o=ve.join(r,"src","components","common",e);await Wn(o,{recursive:!0}),await ir(ve.join(o,`${e}.tsx`),nr({componentName:e,isClient:n,hasI18n:i})),await ir(ve.join(o,"index.ts"),Vn({componentName:e}));let s=ve.join(r,"src","components","common","index.ts");await ec(s,`export { ${e} } from './${e}';
403
- `);let a=ve.join(r,"src","components","index.ts");await tc(a)},ec=async(e,t)=>{let r="";m(e)&&(r=await f(e)),r.includes(t.trim())||(r+=t,await g(e,r))},tc=async e=>{let t="";m(e)&&(t=await f(e));let r=`export * from './common';
404
- `;t.includes(r.trim())||(t+=r,await g(e,t))};import{writeFile as rc}from"node:fs/promises";import nc from"node:path";var qn=e=>{let{camelName:t,pascalName:r,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';
398
+ `;await g(ir.join(e,c.ROOT_PAGE),d)};import tc from"degit";var Vn=async e=>{let t=b("Downloading template...");try{await tc("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!0}).clone(e),t.succeed("Template downloaded successfully.")}catch(r){throw t.fail("Failed to download template."),r}};var sr=["npm","yarn","pnpm","bun"],rc=e=>{if(e!==void 0){if(!sr.includes(e))throw new Error(`Invalid --package-manager "${e}". Valid: ${sr.join(", ")}.`);return e}},Wn=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: ${sr.join(", ")})`).action(async(t,r)=>{try{let n=rc(r.packageManager);await ic(t,{yes:r.yes??!1,packageManager:n})}catch(n){v(`${n instanceof Error?n.message:n}`),process.exit(1)}})},qe=async(e,t,r,n)=>{let i=b(e);n.current=i;try{let o=await r();return i.succeed(t),o}finally{n.current===i&&(n.current=null)}},nc=e=>{let t=[];e.darkMode&&t.push("dark mode"),e.redux&&t.push("redux"),e.i18n&&t.push("i18n"),e.tests&&t.push("tests"),e.reactCompiler&&t.push("react-compiler"),e.preCommitHooks&&t.push("pre-commit hooks"),e.commitizen&&t.push("commitizen"),e.httpClient!=="none"&&t.push(`http (${e.httpClient})`),l(X.dim("Defaults applied (run `next-maker remove <feature>` to undo any of them):")),l(X.dim(` package manager : ${e.packageManager}`)),l(X.dim(` features : ${t.join(", ")}`)),l("")},ic=async(e,t)=>{nn();let r;t.yes?(r=ln(e,{packageManager:t.packageManager}),l(X.cyan(`\u2728 Bootstrapping ${r.projectName} with the recommended defaults`)),l(""),nc(r)):(l("Welcome to the Teispace Next.js App Creator!"),l(""),r=await mn(e),t.packageManager&&(r={...r,packageManager:t.packageManager}));let n=or.resolve(process.cwd(),r.projectName);m(n)&&(console.error(X.red(`Error: Directory ${r.projectName} already exists.`)),process.exit(1));let i={current:null},o=async()=>{if(m(n)){i.current?.stop(),i.current=null,console.log(X.yellow(`
399
+ Cleaning up: Deleting directory ${r.projectName}...`));try{await w(n),console.log(X.green("Cleanup successful."))}catch(a){console.error(X.red(`Failed to clean up directory ${r.projectName}:`),a)}}},s=async()=>{console.log(X.red(`
400
+ Process interrupted. Cleaning up...`)),await o(),process.exit(1)};process.on("SIGINT",s),process.on("SIGTERM",s);try{if(await Vn(n),await Un(n,r),await Gn(n,r),await qe("Generating providers and layout...","Providers and layout generated.",async()=>{await zn(n,r),await Jn(n,r)},i),await qe("Setting up developer tools...","Developer tools configured.",()=>Bn(n,r),i),await qe("Initializing Git...","Git initialized.",()=>sn(n,r.gitRemote,r.pushToRemote),i),await qe("Installing dependencies...","Dependencies installed.",()=>an(n,r.packageManager),i),await qe("Formatting and linting...","Formatted.",()=>J(n,r.packageManager,"lint:fix"),i),r.copyEnv){let a=or.join(n,".env.example"),p=or.join(n,".env");m(a)&&await(await import("node:fs/promises")).copyFile(a,p)}process.off("SIGINT",s),process.off("SIGTERM",s),l(""),l(X.green(`\u2728 Project ${r.projectName} created successfully!`)),l(""),l("To get started:"),l(X.cyan(` cd ${r.projectName}`)),l(X.cyan(` ${r.packageManager==="npm"?"npm run dev":`${r.packageManager} dev`}`)),l("")}catch(a){i.current?.fail("Failed to create project."),i.current=null,console.error(a),await o(),process.exit(1)}};import wr from"node:path";import ne from"picocolors";import Rt from"node:path";var qn=/^[A-Za-z][A-Za-z0-9-]*$/,oc=/^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;function Xn(e){return oc.test(e)}function U(e,t="name"){let r=e?.trim();if(!r)throw new Error(`A ${t} is required.`);if(!qn.test(r))throw new Error(`Invalid ${t} "${e}". Use letters, digits, and hyphens only \u2014 no slashes, spaces, "..", or absolute paths.`);if(Xn(r))throw new Error(`Invalid ${t} "${e}". That is a reserved name on Windows.`);return r}function re(e,t="path"){let r=e?.trim();if(!r)throw new Error(`A ${t} is required.`);let n=r.replace(/^\.\//,"");if(n.startsWith("/")||/^[a-zA-Z]:/.test(n))throw new Error(`Invalid ${t} "${e}". Must be a relative path inside the project (no leading "/" or drive letter).`);for(let i of n.split("/")){if(!qn.test(i))throw new Error(`Invalid ${t} "${e}". Each segment must be kebab/camel-case (letters, digits, hyphens), separated by "/" \u2014 no "..", dots, or empty segments.`);if(Xn(i))throw new Error(`Invalid ${t} "${e}". Segment "${i}" is reserved on Windows.`)}return n}function $t(e,...t){let r=Rt.resolve(e),n=Rt.resolve(r,...t),i=Rt.relative(r,n);if(i===""||i===".")return n;if(i.startsWith("..")||Rt.isAbsolute(i))throw new Error(`Refusing to write outside the project directory (resolved path escapes "${r}").`);return n}H();import{mkdir as ei,writeFile as cr}from"node:fs/promises";import Ee from"node:path";P();var ar=e=>{let{componentName:t,isClient:r,hasI18n:n}=e,i=e.translationNamespace||t,o=[];return(r||n)&&o.push("'use client';"),n&&o.push("import { useTranslations } from 'next-intl';"),o.push(""),o.push(`export function ${t}() {`),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>${t}</h2>`),o.push(" </div>"),o.push(" );")),o.push("}"),o.push(""),o.join(`
401
+ `)},Qn=e=>`export { ${e.componentName} } from './${e.componentName}';
402
+ `;var pr=async e=>{let{name:t,projectPath:r,isClient:n,hasI18n:i,featurePath:o}=e,s=R(t);o?await pc(s,r,o,n,i):await lc(s,t,r,n,i)},pc=async(e,t,r,n,i)=>{let o=Ee.join(t,r,"components");await ei(o,{recursive:!0}),await cr(Ee.join(o,`${e}.tsx`),ar({componentName:e,isClient:n,hasI18n:i}))},lc=async(e,t,r,n,i)=>{let o=Ee.join(r,"src","components","common",e);await ei(o,{recursive:!0}),await cr(Ee.join(o,`${e}.tsx`),ar({componentName:e,isClient:n,hasI18n:i})),await cr(Ee.join(o,"index.ts"),Qn({componentName:e}));let s=Ee.join(r,"src","components","common","index.ts");await mc(s,`export { ${e} } from './${e}';
403
+ `);let a=Ee.join(r,"src","components","index.ts");await dc(a)},mc=async(e,t)=>{let r="";m(e)&&(r=await f(e)),r.includes(t.trim())||(r+=t,await g(e,r))},dc=async e=>{let t="";m(e)&&(t=await f(e));let r=`export * from './common';
404
+ `;t.includes(r.trim())||(t+=r,await g(e,t))};import{writeFile as uc}from"node:fs/promises";import fc from"node:path";var ti=e=>{let{camelName:t,pascalName:r,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';
405
405
  ${i}
406
406
  import type { ResultAsync } from '@/types';
407
407
 
@@ -449,14 +449,14 @@ export const ${t}Service = {
449
449
  return ${o}.delete<void>(AppApis.${t}.delete(id));
450
450
  },
451
451
  };
452
- `},Xn=e=>{let{camelName:t,kebabName:r}=e;return` ${t}: {
452
+ `},ri=e=>{let{camelName:t,kebabName:r}=e;return` ${t}: {
453
453
  base: '/${r}',
454
454
  getAll: '/${r}',
455
455
  getById: (id: string) => \`/${r}/\${id}\`,
456
456
  create: '/${r}',
457
457
  update: (id: string) => \`/${r}/\${id}\`,
458
458
  delete: (id: string) => \`/${r}/\${id}\`,
459
- },`};var sr=async e=>{let{name:t,outputPath:r,httpClient:n}=e,i=j(t),o=R(t);await rc(nc.join(r,`${t}.service.ts`),qn({camelName:i,pascalName:o,httpClient:n}))};import{mkdir as ac,writeFile as $t}from"node:fs/promises";import Y from"node:path";import{writeFile as ic}from"node:fs/promises";import oc from"node:path";var Yn=e=>{let{camelName:t,httpClient:r}=e;return`import { AppApis } from '@/lib/config';
459
+ },`};var lr=async e=>{let{name:t,outputPath:r,httpClient:n}=e,i=j(t),o=R(t);await uc(fc.join(r,`${t}.service.ts`),ti({camelName:i,pascalName:o,httpClient:n}))};import{mkdir as xc,writeFile as At}from"node:fs/promises";import K from"node:path";import{writeFile as gc}from"node:fs/promises";import hc from"node:path";var ni=e=>{let{camelName:t,httpClient:r}=e;return`import { AppApis } from '@/lib/config';
460
460
  ${r==="axios"?"import { axiosClient } from '@/lib/utils/http';":"import { fetchClient } from '@/lib/utils/http';"}
461
461
  import type { ResultAsync } from '@/types';
462
462
 
@@ -465,16 +465,16 @@ export const ${t}Service = {
465
465
  return ${r==="axios"?"axiosClient":"fetchClient"}.get<string>(AppApis.${t}.getAll);
466
466
  },
467
467
  };
468
- `};var Xe=async e=>{let{name:t,outputPath:r,httpClient:n}=e,i=j(t);await ic(oc.join(r,`${t}.service.ts`),Yn({camelName:i,httpClient:n}))};import{mkdir as sc,writeFile as Ye}from"node:fs/promises";import Ke from"node:path";var Kn=e=>{let{sliceName:t,withPersist:r}=e;return`export * from './${t}.slice';
468
+ `};var Ke=async e=>{let{name:t,outputPath:r,httpClient:n}=e,i=j(t);await gc(hc.join(r,`${t}.service.ts`),ni({camelName:i,httpClient:n}))};import{mkdir as yc,writeFile as Ze}from"node:fs/promises";import Qe from"node:path";var ii=e=>{let{sliceName:t,withPersist:r}=e;return`export * from './${t}.slice';
469
469
  export * from './${t}.selectors';
470
470
  export * from './${t}.types';${r?`
471
471
  export * from './persist';`:""}
472
- `},Zn=e=>{let{featureName:t,componentName:r,hookName:n,withStore:i,withService:o}=e;return`export { default as ${r} } from './components/${r}';
472
+ `},oi=e=>{let{featureName:t,componentName:r,hookName:n,withStore:i,withService:o}=e;return`export { default as ${r} } from './components/${r}';
473
473
  export { ${n} } from './hooks/${n}';
474
474
  export * from './types/${t}.types';${i?`
475
475
  export * from './store';`:""}${o?`
476
476
  export * from './services/${t}.service';`:""}
477
- `};var Qn=e=>{let{componentName:t,camelName:r,typesImportPath:n}=e,i=`${r.toUpperCase()}_PERSIST_VERSION`;return`import { createMigrate, type PersistConfig, type PersistedState } from 'redux-persist';
477
+ `};var si=e=>{let{componentName:t,camelName:r,typesImportPath:n}=e,i=`${r.toUpperCase()}_PERSIST_VERSION`;return`import { createMigrate, type PersistConfig, type PersistedState } from 'redux-persist';
478
478
  import storage from '@/store/storage';
479
479
  import type { ${t}State } from '${n}';
480
480
 
@@ -494,11 +494,11 @@ export const ${r}PersistConfig: PersistConfig<${t}State> = {
494
494
  // whitelist: ['someField'], // Specify which fields to persist
495
495
  migrate: createMigrate(migrations, { debug: false }),
496
496
  };
497
- `};var ei=e=>{let{componentName:t,camelName:r,sliceName:n}=e;return`import { RootState } from '@/store/rootReducer';
497
+ `};var ai=e=>{let{componentName:t,camelName:r,sliceName:n}=e;return`import { RootState } from '@/store/rootReducer';
498
498
 
499
499
  export const select${t}State = (state: RootState) => state.${r};
500
500
  export { setLoading, setError, resetState } from './${n}.slice';
501
- `};var ti=e=>{let{componentName:t,camelName:r,typesImportPath:n}=e;return`import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
501
+ `};var ci=e=>{let{componentName:t,camelName:r,typesImportPath:n}=e;return`import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
502
502
  import type { ${t}State } from '${n}';
503
503
 
504
504
  const initialState: ${t}State = {
@@ -527,13 +527,13 @@ export const ${r}Slice = createSlice({
527
527
  export const { setLoading, setError, resetState } = ${r}Slice.actions;
528
528
 
529
529
  export const ${r}Reducer = ${r}Slice.reducer;
530
- `};var Rt=e=>{let{componentName:t,withStore:r}=e;return`export interface ${t}State {
530
+ `};var kt=e=>{let{componentName:t,withStore:r}=e;return`export interface ${t}State {
531
531
  ${r?`loading: boolean;
532
532
  error: string | null;
533
533
  // Add your state properties here`:`// Add your state properties here
534
534
  // example: value: string;`}
535
535
  }
536
- `};var Ze=async e=>{let{name:t,outputPath:r,persist:n,typesImportPath:i=`./${t}.types`}=e;await sc(r,{recursive:!0});let o=R(t),s=j(t);await Promise.all([Ye(Ke.join(r,`${t}.types.ts`),Rt({componentName:o,withStore:!0})),Ye(Ke.join(r,`${t}.slice.ts`),ti({componentName:o,camelName:s,typesImportPath:i})),Ye(Ke.join(r,`${t}.selectors.ts`),ei({componentName:o,camelName:s,sliceName:t})),...n?[Ye(Ke.join(r,"persist.ts"),Qn({componentName:o,camelName:s,typesImportPath:i}))]:[],Ye(Ke.join(r,"index.ts"),Kn({sliceName:t,withPersist:n}))])};var ri=e=>{let{componentName:t,hookName:r}=e;return`'use client';
536
+ `};var et=async e=>{let{name:t,outputPath:r,persist:n,typesImportPath:i=`./${t}.types`}=e;await yc(r,{recursive:!0});let o=R(t),s=j(t);await Promise.all([Ze(Qe.join(r,`${t}.types.ts`),kt({componentName:o,withStore:!0})),Ze(Qe.join(r,`${t}.slice.ts`),ci({componentName:o,camelName:s,typesImportPath:i})),Ze(Qe.join(r,`${t}.selectors.ts`),ai({componentName:o,camelName:s,sliceName:t})),...n?[Ze(Qe.join(r,"persist.ts"),si({componentName:o,camelName:s,typesImportPath:i}))]:[],Ze(Qe.join(r,"index.ts"),ii({sliceName:t,withPersist:n}))])};var pi=e=>{let{componentName:t,hookName:r}=e;return`'use client';
537
537
  import { ${r} } from '../hooks/${r}';
538
538
 
539
539
  export function ${t}() {
@@ -548,7 +548,7 @@ export function ${t}() {
548
548
  }
549
549
 
550
550
  export default ${t};
551
- `};var ni=e=>{let{hookName:t,componentName:r,featureName:n}=e;return`'use client';
551
+ `};var li=e=>{let{hookName:t,componentName:r,featureName:n}=e;return`'use client';
552
552
  import { useAppDispatch, useAppSelector } from '@/store/hooks';
553
553
  import { select${r}State, setLoading, setError } from '../store/${n}.selectors';
554
554
 
@@ -570,7 +570,7 @@ export const ${t} = () => {
570
570
  setError: handleSetError,
571
571
  } as const;
572
572
  };
573
- `},ii=e=>{let{hookName:t}=e;return`'use client';
573
+ `},mi=e=>{let{hookName:t}=e;return`'use client';
574
574
  import { useState } from 'react';
575
575
 
576
576
  export const ${t} = () => {
@@ -582,8 +582,8 @@ export const ${t} = () => {
582
582
  // Add your methods here
583
583
  } as const;
584
584
  };
585
- `};var ar=async e=>{let{name:t,outputPath:r,createStore:n,persistStore:i,createService:o,httpClient:s}=e,a=R(t),p=`use${a}`,u=[Y.join(r,"components"),Y.join(r,"hooks"),Y.join(r,"types"),...n?[Y.join(r,"store")]:[],...o?[Y.join(r,"services")]:[]];await Promise.all(u.map(d=>ac(d,{recursive:!0}))),await Promise.all([$t(Y.join(r,"components",`${a}.tsx`),ri({componentName:a,hookName:p})),$t(Y.join(r,"hooks",`${p}.ts`),n?ni({hookName:p,componentName:a,featureName:t}):ii({hookName:p})),$t(Y.join(r,"types",`${t}.types.ts`),Rt({componentName:a,withStore:n})),$t(Y.join(r,"index.ts"),Zn({featureName:t,componentName:a,hookName:p,withStore:n,withService:o}))]),n&&await Ze({name:t,outputPath:Y.join(r,"store"),persist:i,typesImportPath:`../types/${t}.types`}),o&&s&&await Xe({name:t,outputPath:Y.join(r,"services"),httpClient:s})};import{mkdir as cc,writeFile as pc}from"node:fs/promises";import cr from"node:path";var oi=e=>{let{hookName:t,isClient:r}=e,n=[];return r&&n.push("'use client';"),n.push("import { useState, useCallback } from 'react';"),n.push(""),n.push(`export const ${t} = () => {`),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(`
586
- `)};var pr=async e=>{let{name:t,projectPath:r,isClient:n,featurePath:i}=e,s=`use${R(t)}`,a;i?a=cr.join(r,i,"hooks"):a=cr.join(r,"src","hooks"),await cc(a,{recursive:!0}),await pc(cr.join(a,`${s}.ts`),oi({hookName:s,isClient:n}))};import{mkdir as dc}from"node:fs/promises";import It from"node:path";P();var lc=e=>`import { setRequestLocale } from 'next-intl/server';
585
+ `};var mr=async e=>{let{name:t,outputPath:r,createStore:n,persistStore:i,createService:o,httpClient:s}=e,a=R(t),p=`use${a}`,u=[K.join(r,"components"),K.join(r,"hooks"),K.join(r,"types"),...n?[K.join(r,"store")]:[],...o?[K.join(r,"services")]:[]];await Promise.all(u.map(d=>xc(d,{recursive:!0}))),await Promise.all([At(K.join(r,"components",`${a}.tsx`),pi({componentName:a,hookName:p})),At(K.join(r,"hooks",`${p}.ts`),n?li({hookName:p,componentName:a,featureName:t}):mi({hookName:p})),At(K.join(r,"types",`${t}.types.ts`),kt({componentName:a,withStore:n})),At(K.join(r,"index.ts"),oi({featureName:t,componentName:a,hookName:p,withStore:n,withService:o}))]),n&&await et({name:t,outputPath:K.join(r,"store"),persist:i,typesImportPath:`../types/${t}.types`}),o&&s&&await Ke({name:t,outputPath:K.join(r,"services"),httpClient:s})};import{mkdir as Pc,writeFile as wc}from"node:fs/promises";import dr from"node:path";var di=e=>{let{hookName:t,isClient:r}=e,n=[];return r&&n.push("'use client';"),n.push("import { useState, useCallback } from 'react';"),n.push(""),n.push(`export const ${t} = () => {`),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(`
586
+ `)};var ur=async e=>{let{name:t,projectPath:r,isClient:n,featurePath:i}=e,s=`use${R(t)}`,a;i?a=dr.join(r,i,"hooks"):a=dr.join(r,"src","hooks"),await Pc(a,{recursive:!0}),await wc(dr.join(a,`${s}.ts`),di({hookName:s,isClient:n}))};import{mkdir as Ec}from"node:fs/promises";import _t from"node:path";P();var vc=e=>`import { setRequestLocale } from 'next-intl/server';
587
587
  import type { SupportedLocale } from '@/types/i18n';
588
588
 
589
589
  type Props = {
@@ -597,21 +597,21 @@ export default async function ${e}({ children, params }: Props) {
597
597
 
598
598
  return <>{children}</>;
599
599
  }
600
- `,mc=e=>`type Props = {
600
+ `,Sc=e=>`type Props = {
601
601
  children: React.ReactNode;
602
602
  };
603
603
 
604
604
  export default function ${e}({ children }: Props) {
605
605
  return <>{children}</>;
606
606
  }
607
- `,si=({componentName:e,hasI18n:t})=>t?lc(e):mc(e);var uc=/^[a-z][a-z0-9-]*$/,fc=/^[a-z][a-z0-9-]*(\/[a-z][a-z0-9-]*)*$/,gc=e=>{if(!uc.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.`)},hc=e=>{if(!fc.test(e))throw new Error(`Invalid --at path "${e}". Use kebab-case segments separated by "/", e.g. "dashboard/settings".`)},lr=async e=>{let{segment:t,at:r,projectPath:n,hasI18n:i,withGroup:o}=e;gc(t),r&&hc(r);let s=`${R(t)}Layout`,a=o?`(${t})`:t,p=["src","app"];i&&p.push("[locale]"),r&&p.push(...r.split("/")),p.push(a);let u=It.join(n,...p),d=It.join(u,"layout.tsx");if(m(d))throw new Error(`Layout already exists at ${It.relative(n,d)}.`);return await dc(u,{recursive:!0}),await g(d,si({componentName:s,hasI18n:i})),{layoutFile:d,displayPath:It.relative(n,d),componentName:s}};P();import{copyFile as yc,readFile as xc,writeFile as Pc}from"node:fs/promises";import Qe from"node:path";var mr=async e=>{let{code:t,name:r,country:n,flag:i,projectPath:o,copyTranslations:s}=e;await wc(o,t,s),await vc(o,t),await Sc(o,t,r,n,i)},wc=async(e,t,r)=>{let n=Qe.join(e,"src","i18n","translations"),i=Qe.join(n,"en.json"),o=Qe.join(n,`${t}.json`);if(r)await yc(i,o);else{let s=await xc(i,"utf-8"),a=JSON.parse(s),p=ai(a);await Pc(o,`${JSON.stringify(p,null,2)}
608
- `)}},ai=e=>{let t={};for(let[r,n]of Object.entries(e))typeof n=="object"&&n!==null?t[r]=ai(n):t[r]="";return t},vc=async(e,t)=>{let r=Qe.join(e,"src","types","i18n.ts");if(!m(r))return;let n=await f(r),i=/export type SupportedLocale = (.*);/,o=n.match(i);if(o&&!o[1].includes(`'${t}'`)){let s=`${o[1]} | '${t}'`;n=n.replace(i,`export type SupportedLocale = ${s};`),await g(r,n)}},Sc=async(e,t,r,n,i)=>{let o=Qe.join(e,"src","lib","config","app-locales.ts");if(!m(o))return;let s=await f(o);if(s.includes(`locale: '${t}'`))return;let a=s.lastIndexOf("];");if(a===-1)return;let p=` {
607
+ `,ui=({componentName:e,hasI18n:t})=>t?vc(e):Sc(e);var Cc=/^[a-z][a-z0-9-]*$/,Tc=/^[a-z][a-z0-9-]*(\/[a-z][a-z0-9-]*)*$/,bc=e=>{if(!Cc.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.`)},Rc=e=>{if(!Tc.test(e))throw new Error(`Invalid --at path "${e}". Use kebab-case segments separated by "/", e.g. "dashboard/settings".`)},fr=async e=>{let{segment:t,at:r,projectPath:n,hasI18n:i,withGroup:o}=e;bc(t),r&&Rc(r);let s=`${R(t)}Layout`,a=o?`(${t})`:t,p=["src","app"];i&&p.push("[locale]"),r&&p.push(...r.split("/")),p.push(a);let u=_t.join(n,...p),d=_t.join(u,"layout.tsx");if(m(d))throw new Error(`Layout already exists at ${_t.relative(n,d)}.`);return await Ec(u,{recursive:!0}),await g(d,ui({componentName:s,hasI18n:i})),{layoutFile:d,displayPath:_t.relative(n,d),componentName:s}};P();import{copyFile as $c,readFile as Ic,writeFile as Nc}from"node:fs/promises";import tt from"node:path";var gr=async e=>{let{code:t,name:r,country:n,flag:i,projectPath:o,copyTranslations:s}=e;await kc(o,t,s),await Ac(o,t),await _c(o,t,r,n,i)},kc=async(e,t,r)=>{let n=tt.join(e,"src","i18n","translations"),i=tt.join(n,"en.json"),o=tt.join(n,`${t}.json`);if(r)await $c(i,o);else{let s=await Ic(i,"utf-8"),a=JSON.parse(s),p=fi(a);await Nc(o,`${JSON.stringify(p,null,2)}
608
+ `)}},fi=e=>{let t={};for(let[r,n]of Object.entries(e))typeof n=="object"&&n!==null?t[r]=fi(n):t[r]="";return t},Ac=async(e,t)=>{let r=tt.join(e,"src","types","i18n.ts");if(!m(r))return;let n=await f(r),i=/export type SupportedLocale = (.*);/,o=n.match(i);if(o&&!o[1].includes(`'${t}'`)){let s=`${o[1]} | '${t}'`;n=n.replace(i,`export type SupportedLocale = ${s};`),await g(r,n)}},_c=async(e,t,r,n,i)=>{let o=tt.join(e,"src","lib","config","app-locales.ts");if(!m(o))return;let s=await f(o);if(s.includes(`locale: '${t}'`))return;let a=s.lastIndexOf("];");if(a===-1)return;let p=` {
609
609
  name: '${r}',
610
610
  locale: '${t}',
611
611
  flag: '${i}',
612
612
  country: '${n}',
613
613
  },
614
- `;s=s.slice(0,a)+p+s.slice(a),await g(o,s)};import{mkdir as Cc,writeFile as dr}from"node:fs/promises";import et from"node:path";var ci=e=>{let{componentName:t,routePath:r,hasI18n:n}=e;return n?`import { generateSEOMetadata } from '@/lib/config/seo';
614
+ `;s=s.slice(0,a)+p+s.slice(a),await g(o,s)};import{mkdir as Oc,writeFile as hr}from"node:fs/promises";import rt from"node:path";var gi=e=>{let{componentName:t,routePath:r,hasI18n:n}=e;return n?`import { generateSEOMetadata } from '@/lib/config/seo';
615
615
  import type { Metadata } from 'next';
616
616
  import { getTranslations, setRequestLocale } from 'next-intl/server';
617
617
  import type { SupportedLocale } from '@/types/i18n';
@@ -657,7 +657,7 @@ export default function ${t}Page() {
657
657
  </div>
658
658
  );
659
659
  }
660
- `},pi=e=>{let{componentName:t,paramName:r,routePath:n,hasI18n:i}=e;return i?`import { generateSEOMetadata } from '@/lib/config/seo';
660
+ `},hi=e=>{let{componentName:t,paramName:r,routePath:n,hasI18n:i}=e;return i?`import { generateSEOMetadata } from '@/lib/config/seo';
661
661
  import type { Metadata } from 'next';
662
662
  import { getTranslations, setRequestLocale } from 'next-intl/server';
663
663
  import type { SupportedLocale } from '@/types/i18n';
@@ -711,14 +711,14 @@ export default async function ${t}Page(props: Props) {
711
711
  </div>
712
712
  );
713
713
  }
714
- `},li=e=>`export default function ${e.componentName}Loading() {
714
+ `},yi=e=>`export default function ${e.componentName}Loading() {
715
715
  return (
716
716
  <div className="flex h-full items-center justify-center">
717
717
  <p>Loading...</p>
718
718
  </div>
719
719
  );
720
720
  }
721
- `,mi=e=>`'use client';
721
+ `,xi=e=>`'use client';
722
722
 
723
723
  export default function ${e.componentName}Error({
724
724
  error,
@@ -735,7 +735,7 @@ export default function ${e.componentName}Error({
735
735
  </div>
736
736
  );
737
737
  }
738
- `;var ur=async e=>{let{name:t,projectPath:r,hasI18n:n,dynamic:i,withLoading:o=!1,withError:s=!1}=e,a=R(t),p=`/${t}`,u=n?"src/app/[locale]":"src/app",d;i?d=et.join(r,u,t,`[${i}]`):d=et.join(r,u,t),await Cc(d,{recursive:!0});let h=i?pi({componentName:a,routePath:i?`${p}/[${i}]`:p,paramName:i,hasI18n:n}):ci({componentName:a,routePath:p,hasI18n:n});await dr(et.join(d,"page.tsx"),h),o&&await dr(et.join(d,"loading.tsx"),li({componentName:a})),s&&await dr(et.join(d,"error.tsx"),mi({componentName:a}))};S();import{mkdir as Ec}from"node:fs/promises";import fr from"node:path";P();var di=(e,t)=>e.endsWith(t)?e:`${e}${t}`,ui=({baseName:e})=>{let t=di(e,"Provider"),r=t.replace(/Provider$/,""),n=`${r}ContextValue`,i=`${r}Context`,o=`use${r}`;return`'use client';
738
+ `;var yr=async e=>{let{name:t,projectPath:r,hasI18n:n,dynamic:i,withLoading:o=!1,withError:s=!1}=e,a=R(t),p=`/${t}`,u=n?"src/app/[locale]":"src/app",d;i?d=rt.join(r,u,t,`[${i}]`):d=rt.join(r,u,t),await Oc(d,{recursive:!0});let h=i?hi({componentName:a,routePath:i?`${p}/[${i}]`:p,paramName:i,hasI18n:n}):gi({componentName:a,routePath:p,hasI18n:n});await hr(rt.join(d,"page.tsx"),h),o&&await hr(rt.join(d,"loading.tsx"),yi({componentName:a})),s&&await hr(rt.join(d,"error.tsx"),xi({componentName:a}))};S();import{mkdir as Fc}from"node:fs/promises";import xr from"node:path";P();var Pi=(e,t)=>e.endsWith(t)?e:`${e}${t}`,wi=({baseName:e})=>{let t=Pi(e,"Provider"),r=t.replace(/Provider$/,""),n=`${r}ContextValue`,i=`${r}Context`,o=`use${r}`;return`'use client';
739
739
  import { createContext, useContext, useMemo } from 'react';
740
740
 
741
741
  type ${n} = {
@@ -756,7 +756,7 @@ export const ${t} = ({ children }: { children: React.ReactNode }) => {
756
756
  const value = useMemo<${n}>(() => ({}), []);
757
757
  return <${i}.Provider value={value}>{children}</${i}.Provider>;
758
758
  };
759
- `},fi=e=>di(e,"Provider");var Tc=/^[A-Za-z][A-Za-z0-9-]*$/,bc=e=>e.includes("-")?R(e):e.charAt(0).toUpperCase()+e.slice(1),gr=async e=>{let{name:t,projectPath:r}=e;if(!Tc.test(t))throw new Error(`Invalid provider name "${t}". Use kebab-case or PascalCase letters and digits only.`);let n=bc(t).replace(/Provider$/,""),i=fi(n),o=i,s=fr.join(r,c.PROVIDERS),a=fr.join(s,`${o}.tsx`);if(m(a))throw new Error(`Provider already exists at ${fr.relative(r,a)}.`);return await Ec(s,{recursive:!0}),await g(a,ui({baseName:n})),{componentName:i,fileBaseName:o,providerFile:a}};P();import tt from"node:path";var gi=e=>{let{componentName:t,sourceImportPath:r,testUtilsImportPath:n,hasRedux:i,hasI18n:o}=e,s=[];o&&s.push("messages: {}"),i&&s.push("preloadedState: {}");let a=s.length?`, {
759
+ `},vi=e=>Pi(e,"Provider");var jc=/^[A-Za-z][A-Za-z0-9-]*$/,Dc=e=>e.includes("-")?R(e):e.charAt(0).toUpperCase()+e.slice(1),Pr=async e=>{let{name:t,projectPath:r}=e;if(!jc.test(t))throw new Error(`Invalid provider name "${t}". Use kebab-case or PascalCase letters and digits only.`);let n=Dc(t).replace(/Provider$/,""),i=vi(n),o=i,s=xr.join(r,c.PROVIDERS),a=xr.join(s,`${o}.tsx`);if(m(a))throw new Error(`Provider already exists at ${xr.relative(r,a)}.`);return await Fc(s,{recursive:!0}),await g(a,wi({baseName:n})),{componentName:i,fileBaseName:o,providerFile:a}};P();import nt from"node:path";var Si=e=>{let{componentName:t,sourceImportPath:r,testUtilsImportPath:n,hasRedux:i,hasI18n:o}=e,s=[];o&&s.push("messages: {}"),i&&s.push("preloadedState: {}");let a=s.length?`, {
760
760
  ${s.join(`,
761
761
  `)},
762
762
  }`:"";return`import { describe, expect, it } from 'vitest';
@@ -770,7 +770,7 @@ describe('${t}', () => {
770
770
  expect(screen).toBeDefined();
771
771
  });
772
772
  });
773
- `},hi=e=>{let{hookName:t,sourceImportPath:r,withStore:n,testUtilsImportPath:i}=e;return n?`import { renderHook } from '@testing-library/react';
773
+ `},Ei=e=>{let{hookName:t,sourceImportPath:r,withStore:n,testUtilsImportPath:i}=e;return n?`import { renderHook } from '@testing-library/react';
774
774
  import { describe, expect, it } from 'vitest';
775
775
  import { TestProviders } from '${i}';
776
776
  import { ${t} } from '${r}';
@@ -791,7 +791,7 @@ describe('${t}', () => {
791
791
  expect(result.current).toBeDefined();
792
792
  });
793
793
  });
794
- `},yi=e=>{let{camelName:t,sourceImportPath:r}=e,n=`${t}Slice`;return`import { describe, expect, it } from 'vitest';
794
+ `},Ci=e=>{let{camelName:t,sourceImportPath:r}=e,n=`${t}Slice`;return`import { describe, expect, it } from 'vitest';
795
795
  import { ${n}, resetState, setError, setLoading } from '${r}';
796
796
 
797
797
  describe('${n}', () => {
@@ -816,30 +816,30 @@ describe('${n}', () => {
816
816
  expect(next).toEqual(initialState);
817
817
  });
818
818
  });
819
- `};var oe=async e=>{let{projectPath:t,sourceFile:r,kind:n,symbolName:i}=e,o=tt.dirname(r),s=tt.basename(r).replace(/\.(tsx?|jsx?)$/i,""),a=n==="component"?".tsx":".ts",p=tt.join(o,`${s}.test${a}`),u=`./${s}`,d=Rc(o,tt.join(t,"test","test-utils")),h;return n==="component"?h=gi({componentName:i,sourceImportPath:u,testUtilsImportPath:d,hasRedux:!!e.hasRedux,hasI18n:!!e.hasI18n}):n==="hook"?h=hi({hookName:i,sourceImportPath:u,withStore:!!e.hookUsesStore,testUtilsImportPath:e.hookUsesStore?d:void 0}):h=yi({camelName:i,sourceImportPath:u}),await g(p,h),p},Rc=(e,t)=>{let r=tt.relative(e,t).replace(/\\/g,"/");return r.startsWith(".")?r:`./${r}`};import $c from"enquirer";var{prompt:Ic}=$c,xi=async(e,t={})=>{let r=[];e||r.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"}),t.client===void 0&&r.push({type:"confirm",name:"isClient",message:"Add 'use client' directive?",initial:!1});let n=r.length>0?await Ic(r):{};return{componentName:e??n.componentName,isClient:t.client??n.isClient??!1}};var Pi=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(t,r)=>{try{let n=process.cwd();l(te.cyan(`
819
+ `};var ae=async e=>{let{projectPath:t,sourceFile:r,kind:n,symbolName:i}=e,o=nt.dirname(r),s=nt.basename(r).replace(/\.(tsx?|jsx?)$/i,""),a=n==="component"?".tsx":".ts",p=nt.join(o,`${s}.test${a}`),u=`./${s}`,d=Lc(o,nt.join(t,"test","test-utils")),h;return n==="component"?h=Si({componentName:i,sourceImportPath:u,testUtilsImportPath:d,hasRedux:!!e.hasRedux,hasI18n:!!e.hasI18n}):n==="hook"?h=Ei({hookName:i,sourceImportPath:u,withStore:!!e.hookUsesStore,testUtilsImportPath:e.hookUsesStore?d:void 0}):h=Ci({camelName:i,sourceImportPath:u}),await g(p,h),p},Lc=(e,t)=>{let r=nt.relative(e,t).replace(/\\/g,"/");return r.startsWith(".")?r:`./${r}`};import Mc from"enquirer";var{prompt:Gc}=Mc,Ti=async(e,t={})=>{let r=[];e||r.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"}),t.client===void 0&&r.push({type:"confirm",name:"isClient",message:"Add 'use client' directive?",initial:!1});let n=r.length>0?await Gc(r):{};return{componentName:e??n.componentName,isClient:t.client??n.isClient??!1}};var bi=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(t,r)=>{try{let n=process.cwd();l(ne.cyan(`
820
820
  \u{1F9E9} Component Generator
821
- `)),y.start("Detecting project setup...");let i=await F(n);y.succeed("Project setup detected");let o=await xi(t,{client:r.client}),s=R(o.componentName),a=o.isClient,p=r.i18n??!1,u=Nc(r,i.hasTests);y.start("Generating component..."),await or({name:o.componentName,projectPath:n,isClient:a||p,hasI18n:p,featurePath:r.feature}),y.succeed("Component generated");let d=null;if(u){let x=r.feature?hr.join(n,r.feature,"components",`${s}.tsx`):hr.join(n,"src/components/common",s,`${s}.tsx`);y.start("Generating test..."),d=await oe({projectPath:n,sourceFile:x,kind:"component",symbolName:s,hasRedux:i.hasRedux,hasI18n:i.hasI18n}),y.succeed("Test generated")}let h=r.feature?`${r.feature}/components/${s}.tsx`:`src/components/common/${s}/${s}.tsx`;l(te.green(`
821
+ `)),y.start("Detecting project setup...");let i=await F(n);y.succeed("Project setup detected");let o=await Ti(t,{client:r.client});U(o.componentName,"component name"),r.feature&&re(r.feature,"feature path");let s=R(o.componentName),a=o.isClient,p=r.i18n??!1,u=Uc(r,i.hasTests);y.start("Generating component..."),await pr({name:o.componentName,projectPath:n,isClient:a||p,hasI18n:p,featurePath:r.feature}),y.succeed("Component generated");let d=null;if(u){let x=r.feature?wr.join(n,r.feature,"components",`${s}.tsx`):wr.join(n,"src/components/common",s,`${s}.tsx`);y.start("Generating test..."),d=await ae({projectPath:n,sourceFile:x,kind:"component",symbolName:s,hasRedux:i.hasRedux,hasI18n:i.hasI18n}),y.succeed("Test generated")}let h=r.feature?`${r.feature}/components/${s}.tsx`:`src/components/common/${s}/${s}.tsx`;l(ne.green(`
822
822
  \u2728 Component '${s}' created successfully!
823
- `)),l(te.dim(` \u{1F4C4} ${h}`)),r.feature||(l(te.dim(` \u{1F4C4} src/components/common/${s}/index.ts`)),l(te.dim(" \u{1F4DD} Updated src/components/common/index.ts")),l(te.dim(" \u{1F4DD} Updated src/components/index.ts"))),d&&l(te.dim(` \u{1F9EA} ${hr.relative(n,d)}`)),l(""),l(te.cyan("Usage:")),r.feature?l(te.dim(` import { ${s} } from '${r.feature.replace(/^src\//,"@/")}/components/${s}';`)):l(te.dim(` import { ${s} } from '@/components';`)),l("")}catch(n){y.fail("Component generation failed"),v(`${n}`),process.exit(1)}})},Nc=(e,t)=>e.noTest?!1:e.test?!0:t;import L from"picocolors";S();P();import Ac from"node:path";S();import wi from"node:path";import kc from"picocolors";P();var rt=async e=>{let t=b("Adding @next/bundle-analyzer...");try{let r=wi.join(e,c.NEXT_CONFIG);if(!m(r))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await f(r);if(n.includes("@next/bundle-analyzer")){t.fail("@next/bundle-analyzer is already configured.");return}n=`import withBundleAnalyzer from '@next/bundle-analyzer';
823
+ `)),l(ne.dim(` \u{1F4C4} ${h}`)),r.feature||(l(ne.dim(` \u{1F4C4} src/components/common/${s}/index.ts`)),l(ne.dim(" \u{1F4DD} Updated src/components/common/index.ts")),l(ne.dim(" \u{1F4DD} Updated src/components/index.ts"))),d&&l(ne.dim(` \u{1F9EA} ${wr.relative(n,d)}`)),l(""),l(ne.cyan("Usage:")),r.feature?l(ne.dim(` import { ${s} } from '${r.feature.replace(/^src\//,"@/")}/components/${s}';`)):l(ne.dim(` import { ${s} } from '@/components';`)),l("")}catch(n){y.fail("Component generation failed"),v(`${n}`),process.exit(1)}})},Uc=(e,t)=>e.test===!1?!1:e.test===!0?!0:t;import L from"picocolors";S();P();import Bc from"node:path";S();import Ri from"node:path";import Hc from"picocolors";P();var it=async e=>{let t=b("Adding @next/bundle-analyzer...");try{let r=Ri.join(e,c.NEXT_CONFIG);if(!m(r))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await f(r);if(n.includes("@next/bundle-analyzer")){t.fail("@next/bundle-analyzer is already configured.");return}n=`import withBundleAnalyzer from '@next/bundle-analyzer';
824
824
  ${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({
825
825
  enabled: process.env.ANALYZE === 'true',
826
826
  });
827
827
 
828
- export default bundleAnalyzer(${o[1]});`;n=n.replace(i,a),await g(r,n),await D(wi.join(e,c.PACKAGE_JSON),p=>(p.scripts=p.scripts??{},p.scripts.analyze||(p.scripts.analyze="ANALYZE=true next build"),p)),t.text="Installing @next/bundle-analyzer...",await vt(e,"@next/bundle-analyzer"),t.succeed(kc.green("@next/bundle-analyzer configured."))}catch(r){throw t.fail("Failed to add @next/bundle-analyzer."),r}};var yr=(e,t)=>{let r=e.split(`
828
+ export default bundleAnalyzer(${o[1]});`;n=n.replace(i,a),await g(r,n),await D(Ri.join(e,c.PACKAGE_JSON),p=>(p.scripts=p.scripts??{},p.scripts.analyze||(p.scripts.analyze="ANALYZE=true next build"),p)),t.text="Installing @next/bundle-analyzer...",await Et(e,"@next/bundle-analyzer"),t.succeed(Hc.green("@next/bundle-analyzer configured."))}catch(r){throw t.fail("Failed to add @next/bundle-analyzer."),r}};var vr=(e,t)=>{let r=e.split(`
829
829
  `),n=[],i=new RegExp(`^import\\s+${t}\\s+from\\s+['"][^'"]+['"];?\\s*$`),o=/^(import\s+)\{([^}]+)\}(\s+from\s+['"][^'"]+['"];?\s*)$/;for(let s of r){if(i.test(s))continue;let a=s.match(o);if(a){let p=a[2].split(",").map(d=>d.trim()).filter(Boolean),u=p.filter(d=>d.replace(/^type\s+/,"").split(/\s+as\s+/)[0].trim()!==t);if(u.length===0)continue;if(u.length<p.length){n.push(`${a[1]}{ ${u.join(", ")} }${a[3]}`);continue}}n.push(s)}return n.join(`
830
- `)},Ae=e=>t=>{let r=t.split(`
830
+ `)},Oe=e=>t=>{let r=t.split(`
831
831
  `),n=new RegExp(`^([ \\t]*)<${e}\\b`),i=-1,o="";for(let h=0;h<r.length;h++){let x=r[h].match(n);if(x){i=h,o=x[1];break}}if(i===-1||!/>\s*$/.test(r[i]))return null;let s=o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=new RegExp(`^${s}<\\/${e}>\\s*$`),p=-1;for(let h=i+1;h<r.length;h++)if(a.test(r[h])){p=h;break}if(p===-1)return null;let u=r.slice(i+1,p).map(h=>h.startsWith(" ")?h.slice(2):h),d=[...r.slice(0,i),...u,...r.slice(p+1)].join(`
832
- `);return yr(d,e)};var vi=e=>{let t=e.split(`
832
+ `);return vr(d,e)};var $i=e=>{let t=e.split(`
833
833
  `).filter(n=>!/^import\s+createNextIntlPlugin\s+from\s+['"]next-intl\/plugin['"];?\s*$/.test(n)).join(`
834
- `);t=t.replace(/^const\s+withNextIntl\s*=\s*createNextIntlPlugin\([^)]*\);\s*\n?/m,"");let r=/withNextIntl\(\s*((?:[^()]|\([^()]*\))+?)\s*\)/;return r.test(t)?(t=t.replace(r,"$1"),t):null},Si=e=>{let t=yr(e,"withBundleAnalyzer"),r=/^const\s+bundleAnalyzer\s*=\s*withBundleAnalyzer\(\{[\s\S]*?\}\);\s*\n?/m;if(!r.test(t))return null;t=t.replace(r,"");let n=/bundleAnalyzer\(\s*((?:[^()]|\([^()]*\))+?)\s*\)/;return n.test(t)?(t=t.replace(n,"$1"),t):null};var Ci={id:"bundle-analyzer",name:"Bundle Analyzer",description:"@next/bundle-analyzer wrapped around the default export",detect:async e=>{let t=Ac.join(e,c.NEXT_CONFIG);return m(t)?/@next\/bundle-analyzer/.test(await f(t)):!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:Si}],apply:rt};S();P();import Fc from"node:path";S();import Ei from"node:path";import _c from"picocolors";P();var xr=e=>{let t={...e.scripts??{}},r={...e.devDependencies??{}};return t.commit||(t.commit="cz"),r[T.COMMITIZEN]||(r[T.COMMITIZEN]="*"),r[T.CZ_CONVENTIONAL_CHANGELOG]||(r[T.CZ_CONVENTIONAL_CHANGELOG]="*"),{...e,scripts:t,devDependencies:r}},Pr=e=>{let t=e.devDependencies??{},r=[];return t[T.COMMITIZEN]||r.push(T.COMMITIZEN),t[T.CZ_CONVENTIONAL_CHANGELOG]||r.push(T.CZ_CONVENTIONAL_CHANGELOG),r};var Oc=`${JSON.stringify({path:"cz-conventional-changelog"},null,2)}
835
- `,nt=async e=>{let t=b("Setting up Commitizen...");try{let r=Ei.join(e,c.CZRC);m(r)||await g(r,Oc);let n=Ei.join(e,c.PACKAGE_JSON),i=JSON.parse(await f(n)),o=Pr(i);if(await D(n,s=>xr(s)),o.length>0){t.text=`Installing ${o.join(", ")}...`;let s=await k(e);await xe(e,s,o)}t.succeed(_c.green("Commitizen configured. Use `commit` to start a guided commit."))}catch(r){throw t.fail("Failed to set up Commitizen."),r}};var Ti={id:"commitizen",name:"Commitizen",description:"Guided conventional-commit prompt via `commit` script",detect:async e=>m(Fc.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:nt};S();P();import Mc from"node:path";import Dc from"node:path";import Lc from"picocolors";P();S();P();import bi from"node:path";import jc from"degit";var Ri=async(e,t)=>{t.text="Fetching assets from starter repo...",await jc("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},$i=async(e,t)=>{let r=bi.join(e,c.THEME_PROVIDER),n=bi.join(t,"src/providers/CustomThemeProvider.tsx");await N(n,r)};S();P();import it from"node:path";S();P();import Ii from"node:path";var Nt=async e=>{let t=[Ii.join(e,c.ROOT_LAYOUT),Ii.join(e,"src/app/[locale]/layout.tsx")];for(let r of t)if(m(r)&&(await f(r)).includes("<body"))return r;for(let r of t)if(m(r))return r;return""};var Ni=async e=>{let t=it.join(e,c.THEME_PROVIDER),r=it.join(e,c.GLOBALS_CSS),n=it.join(e,"package.json");if(m(t))return{isSetup:!0,reason:"CustomThemeProvider.tsx exists"};if(m(n)){let i=JSON.parse(await f(n)),o="@teispace/next-themes";if(i.dependencies?.[o]||i.devDependencies?.[o])return{isSetup:!0,reason:`${o} is installed`}}return m(r)&&(await f(r)).includes("@custom-variant dark")?{isSetup:!0,reason:"Dark theme CSS found in globals.css"}:{isSetup:!1,reason:""}},ki=async e=>{let t=it.join(e,c.GLOBALS_CSS),r=it.join(e,c.PROVIDERS_INDEX),n=await Nt(e);if(!m(t)||!n||!m(r))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};S();P();import kt from"node:path";var Ai=async e=>{let t=kt.join(e,c.PROVIDERS_INDEX),r=await f(t);r.includes("CustomThemeProvider")||(r+=`export * from './CustomThemeProvider';
836
- `,await g(t,r))},_i=async e=>{let t=kt.join(e,"src/providers/RootProvider.tsx");if(!m(t))return;let r=await f(t),n="'use client';",i=r.includes(n);if(i&&(r=r.replace(n,"").trim()),r.includes("CustomThemeProvider")||(/import\s*\{[^}]*\}\s*from\s*'@\/providers'/.test(r)?r=r.replace(/(import\s*\{)([^}]*)(\}\s*from\s*'@\/providers')/,(o,s,a,p)=>`${s}${a.trim()?`${a.trim()}, CustomThemeProvider `:" CustomThemeProvider "}${p}`):r=`import { CustomThemeProvider } from '@/providers';
834
+ `);t=t.replace(/^const\s+withNextIntl\s*=\s*createNextIntlPlugin\([^)]*\);\s*\n?/m,"");let r=/withNextIntl\(\s*((?:[^()]|\([^()]*\))+?)\s*\)/;return r.test(t)?(t=t.replace(r,"$1"),t):null},Ii=e=>{let t=vr(e,"withBundleAnalyzer"),r=/^const\s+bundleAnalyzer\s*=\s*withBundleAnalyzer\(\{[\s\S]*?\}\);\s*\n?/m;if(!r.test(t))return null;t=t.replace(r,"");let n=/bundleAnalyzer\(\s*((?:[^()]|\([^()]*\))+?)\s*\)/;return n.test(t)?(t=t.replace(n,"$1"),t):null};var Ni={id:"bundle-analyzer",name:"Bundle Analyzer",description:"@next/bundle-analyzer wrapped around the default export",detect:async e=>{let t=Bc.join(e,c.NEXT_CONFIG);return m(t)?/@next\/bundle-analyzer/.test(await f(t)):!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:Ii}],apply:it};S();P();import Vc from"node:path";S();import ki from"node:path";import zc from"picocolors";P();var Sr=e=>{let t={...e.scripts??{}},r={...e.devDependencies??{}};return t.commit||(t.commit="cz"),r[T.COMMITIZEN]||(r[T.COMMITIZEN]="*"),r[T.CZ_CONVENTIONAL_CHANGELOG]||(r[T.CZ_CONVENTIONAL_CHANGELOG]="*"),{...e,scripts:t,devDependencies:r}},Er=e=>{let t=e.devDependencies??{},r=[];return t[T.COMMITIZEN]||r.push(T.COMMITIZEN),t[T.CZ_CONVENTIONAL_CHANGELOG]||r.push(T.CZ_CONVENTIONAL_CHANGELOG),r};var Jc=`${JSON.stringify({path:"cz-conventional-changelog"},null,2)}
835
+ `,ot=async e=>{let t=b("Setting up Commitizen...");try{let r=ki.join(e,c.CZRC);m(r)||await g(r,Jc);let n=ki.join(e,c.PACKAGE_JSON),i=JSON.parse(await f(n)),o=Er(i);if(await D(n,s=>Sr(s)),o.length>0){t.text=`Installing ${o.join(", ")}...`;let s=await k(e);await we(e,s,o)}t.succeed(zc.green("Commitizen configured. Use `commit` to start a guided commit."))}catch(r){throw t.fail("Failed to set up Commitizen."),r}};var Ai={id:"commitizen",name:"Commitizen",description:"Guided conventional-commit prompt via `commit` script",detect:async e=>m(Vc.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:ot};S();P();import Yc from"node:path";import qc from"node:path";import Xc from"picocolors";P();S();P();import _i from"node:path";import Wc from"degit";var Oi=async(e,t)=>{t.text="Fetching assets from starter repo...",await Wc("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Fi=async(e,t)=>{let r=_i.join(e,c.THEME_PROVIDER),n=_i.join(t,"src/providers/CustomThemeProvider.tsx");await N(n,r)};S();P();import st from"node:path";S();P();import ji from"node:path";var Ot=async e=>{let t=[ji.join(e,c.ROOT_LAYOUT),ji.join(e,"src/app/[locale]/layout.tsx")];for(let r of t)if(m(r)&&(await f(r)).includes("<body"))return r;for(let r of t)if(m(r))return r;return""};var Di=async e=>{let t=st.join(e,c.THEME_PROVIDER),r=st.join(e,c.GLOBALS_CSS),n=st.join(e,"package.json");if(m(t))return{isSetup:!0,reason:"CustomThemeProvider.tsx exists"};if(m(n)){let i=JSON.parse(await f(n)),o="@teispace/next-themes";if(i.dependencies?.[o]||i.devDependencies?.[o])return{isSetup:!0,reason:`${o} is installed`}}return m(r)&&(await f(r)).includes("@custom-variant dark")?{isSetup:!0,reason:"Dark theme CSS found in globals.css"}:{isSetup:!1,reason:""}},Li=async e=>{let t=st.join(e,c.GLOBALS_CSS),r=st.join(e,c.PROVIDERS_INDEX),n=await Ot(e);if(!m(t)||!n||!m(r))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};S();P();import Ft from"node:path";var Mi=async e=>{let t=Ft.join(e,c.PROVIDERS_INDEX),r=await f(t);r.includes("CustomThemeProvider")||(r+=`export * from './CustomThemeProvider';
836
+ `,await g(t,r))},Gi=async e=>{let t=Ft.join(e,"src/providers/RootProvider.tsx");if(!m(t))return;let r=await f(t),n="'use client';",i=r.includes(n);if(i&&(r=r.replace(n,"").trim()),r.includes("CustomThemeProvider")||(/import\s*\{[^}]*\}\s*from\s*'@\/providers'/.test(r)?r=r.replace(/(import\s*\{)([^}]*)(\}\s*from\s*'@\/providers')/,(o,s,a,p)=>`${s}${a.trim()?`${a.trim()}, CustomThemeProvider `:" CustomThemeProvider "}${p}`):r=`import { CustomThemeProvider } from '@/providers';
837
837
  ${r}`),i&&(r=`${n}
838
838
  ${r}`),!r.includes("<CustomThemeProvider"))if(r.includes("{children}"))r=r.replace(/\{children\}/,"<CustomThemeProvider>{children}</CustomThemeProvider>");else{let o=r.match(/return\s*\(\s*([\s\S]*?)\s*\);/);o&&(r=r.replace(o[0],`return (
839
839
  <CustomThemeProvider>
840
840
  ${o[1]}
841
841
  </CustomThemeProvider>
842
- );`))}await g(t,r)},Oi=async(e,t)=>{let r=kt.join(e,c.GLOBALS_CSS),n=kt.join(t,"src/styles/globals.css"),i="";if(m(n)){let s=await f(n),a=s.match(/@custom-variant dark \(.*?\);/),p=s.match(/@theme \{[\s\S]*?\}/);a&&(i+=`
842
+ );`))}await g(t,r)},Ui=async(e,t)=>{let r=Ft.join(e,c.GLOBALS_CSS),n=Ft.join(t,"src/styles/globals.css"),i="";if(m(n)){let s=await f(n),a=s.match(/@custom-variant dark \(.*?\);/),p=s.match(/@theme \{[\s\S]*?\}/);a&&(i+=`
843
843
  ${a[0]}
844
844
  `),p&&(i+=`
845
845
  ${p[0]}
@@ -851,24 +851,24 @@ ${p[0]}
851
851
  --color-light: #f5f5f5;
852
852
  }
853
853
  `);let o=await f(r);if(!o.includes("@custom-variant dark")){if(o.includes("@import")){let s=o.lastIndexOf("@import"),a=o.indexOf(`
854
- `,s);o=o.slice(0,a+1)+i+o.slice(a+1)}else o=i+o;await g(r,o)}},Fi=async e=>{let t=await f(e);t.includes("dark:bg-dark")||(t=t.replace(/className="([^"]*)"/,'className="$1 bg-light dark:bg-dark"'),await g(e,t))};var ot=async e=>{let t=b("Setting up Dark Theme..."),r=Dc.join(e,".next-maker-temp");try{let{isSetup:n,reason:i}=await Ni(e);if(n){t.fail(`Dark Theme is already set up (${i}).`);return}let o=await ki(e);await Ri(r,t),await $i(e,r),await Ai(e),await _i(e),await Oi(e,r),await Fi(o),t.text="Installing @teispace/next-themes...",await G(e,"@teispace/next-themes"),t.text="Formatting code...";let s=await k(e);await z(e,s,"lint:fix"),t.succeed(Lc.green("Dark Theme setup successfully!"))}catch(n){throw t.fail("Failed to setup Dark Theme."),n}finally{await w(r)}};var ji={id:"dark-theme",name:"Dark Theme",description:"@teispace/next-themes + CustomThemeProvider",detect:async e=>m(Mc.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:Ae("CustomThemeProvider")}],apply:ot};import Hc from"node:fs/promises";import At from"node:path";import _t from"enquirer";import wr from"picocolors";P();S();P();import X from"node:fs/promises";import C from"node:path";import Gc from"degit";var Di=async(e,t)=>{t.text="Downloading assets from starter repository...",await Gc("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Li=async(e,t,r,n)=>{let i=C.join(e,c.HTTP_UTILS),o=C.join(t,c.HTTP_UTILS);await X.cp(C.join(t,c.ERRORS_DIR),C.join(e,c.ERRORS_DIR),{recursive:!0});let s=C.join(e,c.APP_APIS);m(s)||await N(C.join(t,c.APP_APIS),s);let a=C.join(e,c.API_URL_FILE);m(a)||await N(C.join(t,c.API_URL_FILE),a);let p=C.join(e,c.CONSTANTS);if(!m(p))await N(C.join(t,c.CONSTANTS),p);else{let d=await f(p),h=!1;d.includes("API_RESPONSE_DATA_KEY")||(d+=`
854
+ `,s);o=o.slice(0,a+1)+i+o.slice(a+1)}else o=i+o;await g(r,o)}},Hi=async e=>{let t=await f(e);t.includes("dark:bg-dark")||(t=t.replace(/className="([^"]*)"/,'className="$1 bg-light dark:bg-dark"'),await g(e,t))};var at=async e=>{let t=b("Setting up Dark Theme..."),r=qc.join(e,".next-maker-temp");try{let{isSetup:n,reason:i}=await Di(e);if(n){t.fail(`Dark Theme is already set up (${i}).`);return}let o=await Li(e);await Oi(r,t),await Fi(e,r),await Mi(e),await Gi(e),await Ui(e,r),await Hi(o),t.text="Installing @teispace/next-themes...",await G(e,"@teispace/next-themes"),t.text="Formatting code...";let s=await k(e);await J(e,s,"lint:fix"),t.succeed(Xc.green("Dark Theme setup successfully!"))}catch(n){throw t.fail("Failed to setup Dark Theme."),n}finally{await w(r)}};var Bi={id:"dark-theme",name:"Dark Theme",description:"@teispace/next-themes + CustomThemeProvider",detect:async e=>m(Yc.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:Oe("CustomThemeProvider")}],apply:at};import Zc from"node:fs/promises";import jt from"node:path";import Dt from"enquirer";import Cr from"picocolors";P();S();P();import Y from"node:fs/promises";import E from"node:path";import Kc from"degit";var zi=async(e,t)=>{t.text="Downloading assets from starter repository...",await Kc("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Ji=async(e,t,r,n)=>{let i=E.join(e,c.HTTP_UTILS),o=E.join(t,c.HTTP_UTILS);await Y.cp(E.join(t,c.ERRORS_DIR),E.join(e,c.ERRORS_DIR),{recursive:!0});let s=E.join(e,c.APP_APIS);m(s)||await N(E.join(t,c.APP_APIS),s);let a=E.join(e,c.API_URL_FILE);m(a)||await N(E.join(t,c.API_URL_FILE),a);let p=E.join(e,c.CONSTANTS);if(!m(p))await N(E.join(t,c.CONSTANTS),p);else{let d=await f(p),h=!1;d.includes("API_RESPONSE_DATA_KEY")||(d+=`
855
855
  export const API_RESPONSE_DATA_KEY = 'data';
856
856
  `,h=!0),d.includes("SAVE_AUTH_TOKENS")||(d+=`
857
857
  export const SAVE_AUTH_TOKENS = false;
858
- `,h=!0),h&&await g(p,d)}let u=C.join(e,c.STORAGE_SERVICE);if(m(u)||await X.cp(C.join(t,c.STORAGE_SERVICE),u,{recursive:!0}),await X.cp(C.join(t,c.COMMON_TYPES_DIR),C.join(e,c.COMMON_TYPES_DIR),{recursive:!0}),await X.cp(C.join(t,c.UTILITY_TYPES_DIR),C.join(e,c.UTILITY_TYPES_DIR),{recursive:!0}),await N(C.join(o,"token-store.ts"),C.join(i,"token-store.ts")),await N(C.join(o,"client-utils.ts"),C.join(i,"client-utils.ts")),await X.cp(C.join(t,c.HTTP_SHARED),C.join(e,c.HTTP_SHARED),{recursive:!0,force:!0}),await N(C.join(o,"server.ts"),C.join(i,"server.ts")),await X.cp(C.join(t,c.HTTP_BUNDLE_SENTINEL_DIR),C.join(e,c.HTTP_BUNDLE_SENTINEL_DIR),{recursive:!0,force:!0}),n&&n.length>0)for(let d of n){let h=C.join(e,d==="fetch"?c.FETCH_CLIENT:c.AXIOS_CLIENT);await w(h)}for(let d of r)d==="fetch"?await X.cp(C.join(t,c.FETCH_CLIENT),C.join(e,c.FETCH_CLIENT),{recursive:!0}):await X.cp(C.join(t,c.AXIOS_CLIENT),C.join(e,c.AXIOS_CLIENT),{recursive:!0});await N(C.join(o,"index.ts"),C.join(i,"index.ts")),await N(C.join(t,c.HTTP_TYPES),C.join(e,c.HTTP_TYPES))},Mi=async e=>{let{isFileUsed:t,isStringUsed:r}=await Promise.resolve().then(()=>(Ue(),gn));await w(C.join(e,c.HTTP_UTILS));let n=C.join(e,c.STORAGE_SERVICE);m(n)&&(await r(e,"SecureStorageService",[n])||await w(n));let i=C.join(e,c.API_URL_FILE);m(i)&&(await r(e,"getApiBaseUrl",[i])||await X.unlink(i));let o=C.join(e,c.CONSTANTS);if(m(o)){let u=await f(o),d=!1;await r(e,"API_RESPONSE_DATA_KEY",[o])||(u=u.replace(/export const API_RESPONSE_DATA_KEY = .*;\n?/g,""),d=!0),await r(e,"SAVE_AUTH_TOKENS",[o])||(u=u.replace(/export const SAVE_AUTH_TOKENS = .*;\n?/g,""),d=!0),d&&(u=`${u.replace(/\n\s*\n/g,`
858
+ `,h=!0),h&&await g(p,d)}let u=E.join(e,c.STORAGE_SERVICE);if(m(u)||await Y.cp(E.join(t,c.STORAGE_SERVICE),u,{recursive:!0}),await Y.cp(E.join(t,c.COMMON_TYPES_DIR),E.join(e,c.COMMON_TYPES_DIR),{recursive:!0}),await Y.cp(E.join(t,c.UTILITY_TYPES_DIR),E.join(e,c.UTILITY_TYPES_DIR),{recursive:!0}),await N(E.join(o,"token-store.ts"),E.join(i,"token-store.ts")),await N(E.join(o,"client-utils.ts"),E.join(i,"client-utils.ts")),await Y.cp(E.join(t,c.HTTP_SHARED),E.join(e,c.HTTP_SHARED),{recursive:!0,force:!0}),await N(E.join(o,"server.ts"),E.join(i,"server.ts")),await Y.cp(E.join(t,c.HTTP_BUNDLE_SENTINEL_DIR),E.join(e,c.HTTP_BUNDLE_SENTINEL_DIR),{recursive:!0,force:!0}),n&&n.length>0)for(let d of n){let h=E.join(e,d==="fetch"?c.FETCH_CLIENT:c.AXIOS_CLIENT);await w(h)}for(let d of r)d==="fetch"?await Y.cp(E.join(t,c.FETCH_CLIENT),E.join(e,c.FETCH_CLIENT),{recursive:!0}):await Y.cp(E.join(t,c.AXIOS_CLIENT),E.join(e,c.AXIOS_CLIENT),{recursive:!0});await N(E.join(o,"index.ts"),E.join(i,"index.ts")),await N(E.join(t,c.HTTP_TYPES),E.join(e,c.HTTP_TYPES))},Vi=async e=>{let{isFileUsed:t,isStringUsed:r}=await Promise.resolve().then(()=>(ze(),wn));await w(E.join(e,c.HTTP_UTILS));let n=E.join(e,c.STORAGE_SERVICE);m(n)&&(await r(e,"SecureStorageService",[n])||await w(n));let i=E.join(e,c.API_URL_FILE);m(i)&&(await r(e,"getApiBaseUrl",[i])||await Y.unlink(i));let o=E.join(e,c.CONSTANTS);if(m(o)){let u=await f(o),d=!1;await r(e,"API_RESPONSE_DATA_KEY",[o])||(u=u.replace(/export const API_RESPONSE_DATA_KEY = .*;\n?/g,""),d=!0),await r(e,"SAVE_AUTH_TOKENS",[o])||(u=u.replace(/export const SAVE_AUTH_TOKENS = .*;\n?/g,""),d=!0),d&&(u=`${u.replace(/\n\s*\n/g,`
859
859
 
860
860
  `).trim()}
861
- `,await g(o,u))}let s=C.join(e,c.ERRORS_DIR);if(m(s)){let u=await X.readdir(s),d=!1;for(let h of u){let x=C.parse(h).name;if(await t(e,x,[C.join(s,h)])){d=!0;break}}d||await w(s)}let a=C.join(e,c.COMMON_TYPES_DIR);m(a)&&(await X.readdir(a)).length===0&&await w(a);let p=C.join(e,c.UTILITY_TYPES_DIR);m(p)&&(await X.readdir(p)).length===0&&await w(p)};S();P();import st from"node:path";var Gi=async e=>{let t=st.join(e,c.FETCH_CLIENT_FILE),r=st.join(e,c.AXIOS_CLIENT_FILE),n=m(t),i=m(r);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"}},Hi=async e=>{let r=[st.join(e,"src/lib"),st.join(e,"src/types"),st.join(e,"src/lib/config")].filter(n=>!m(n));if(r.length>0)throw new Error(`Invalid project structure. Missing directories:
861
+ `,await g(o,u))}let s=E.join(e,c.ERRORS_DIR);if(m(s)){let u=await Y.readdir(s),d=!1;for(let h of u){let x=E.parse(h).name;if(await t(e,x,[E.join(s,h)])){d=!0;break}}d||await w(s)}let a=E.join(e,c.COMMON_TYPES_DIR);m(a)&&(await Y.readdir(a)).length===0&&await w(a);let p=E.join(e,c.UTILITY_TYPES_DIR);m(p)&&(await Y.readdir(p)).length===0&&await w(p)};S();P();import ct from"node:path";var Wi=async e=>{let t=ct.join(e,c.FETCH_CLIENT_FILE),r=ct.join(e,c.AXIOS_CLIENT_FILE),n=m(t),i=m(r);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"}},qi=async e=>{let r=[ct.join(e,"src/lib"),ct.join(e,"src/types"),ct.join(e,"src/lib/config")].filter(n=>!m(n));if(r.length>0)throw new Error(`Invalid project structure. Missing directories:
862
862
  ${r.map(n=>`- ${n}`).join(`
863
- `)}`)};Ue();var at=async e=>{let t=b("Checking HTTP Client setup..."),r=At.join(e,".next-maker-temp-http");try{let{status:n,reason:i}=await Gi(e);t.stop();let o=await Uc(n,i);if(o.type==="cancel"){console.log(wr.yellow("Setup cancelled."));return}if(t.start("Setting up HTTP client(s)..."),await Hi(e),await Di(r,t),o.type==="replace"&&o.fromClient&&(t.text="Migrating client usages...",await Xt(e,o.fromClient,o.clients[0])),o.type!=="remove-both"&&o.type!=="remove-one"){t.text="Copying client files...";let $=o.type==="replace"&&o.fromClient?[o.fromClient]:void 0;await Li(e,r,o.clients,$)}if(o.type==="remove-one"||o.type==="remove-both"){t.text="Removing client files...";let{PROJECT_PATHS:$}=await Promise.resolve().then(()=>(S(),an));for(let I of o.clients){let V=At.join(e,I==="fetch"?$.FETCH_CLIENT:$.AXIOS_CLIENT);await w(V)}Ui(n,o).length===0&&(t.text="Performing full cleanup...",await Mi(e),await Zt(e))}let s=Ui(n,o);s.length>0?(t.text="Configuring client...",await Jt(e,s),await Vt(e),await Wt(e),await qt(e),await Kt(e),await Ne(e,s),await ke(e,s)):await He(e),await Ie(e,s),t.text="Managing dependencies...";let a=At.join(e,"package.json"),p=JSON.parse(await Hc.readFile(a,"utf-8")),u={...p.dependencies,...p.devDependencies};s.includes("axios")?u.axios||(t.text="Installing Axios...",await G(e,"axios")):u.axios&&(t.text="Uninstalling Axios...",await $e(e,"axios")),s.length>0?u["server-only"]||(t.text="Installing server-only...",await G(e,"server-only")):u["server-only"]&&(t.text="Uninstalling server-only...",await $e(e,"server-only"));let d=At.join(e,"src/services/storage");s.length>0||m(d)?u["react-secure-storage"]||(t.text="Installing react-secure-storage...",await G(e,"react-secure-storage")):u["react-secure-storage"]&&(t.text="Uninstalling react-secure-storage...",await $e(e,"react-secure-storage")),t.text="Formatting code...";let x=await k(e);await z(e,x,"lint:fix"),t.succeed(wr.green(Bc(o)))}catch(n){throw t.fail("Failed to setup HTTP Client."),n}finally{await w(r)}};async function Uc(e,t){if(e==="none"){let{choice:n}=await _t.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 _t.prompt({type:"select",name:"action",message:`${t}. 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 _t.prompt({type:"select",name:"action",message:`${t}. 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(wr.yellow(`\u2716 ${t}`));let{action:r}=await _t.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 r==="cancel"?{type:"cancel",clients:[]}:r==="remove-fetch"?{type:"remove-one",clients:["fetch"]}:r==="remove-axios"?{type:"remove-one",clients:["axios"]}:r==="remove-both"?{type:"remove-both",clients:["fetch","axios"]}:{type:"cancel",clients:[]}}function Ui(e,t){return t.type==="install"?t.clients:t.type==="add"?[...e==="fetch"?["fetch"]:["axios"],...t.clients]:t.type==="replace"?t.clients:t.type==="remove-one"?e==="both"?t.clients[0]==="fetch"?["axios"]:["fetch"]:[]:[]}function Bc(e){if(e.type==="install")return`HTTP Client (${e.clients.map(r=>r==="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 t=e.fromClient==="fetch"?"Fetch":"Axios",r=e.clients[0]==="fetch"?"Fetch":"Axios";return`Replaced ${t} with ${r} 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!"}Ue();var Bi=/<HttpClientBundleSentinel\s*\/>/,zi={id:"http-client",name:"HTTP Client",description:"Axios and/or Fetch client utilities",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(H(),qe));return(await t(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"},{path:"src/lib/utils/http/shared",generated:!0,isDir:!0},{path:"src/lib/utils/http/server.ts",generated:!0},{path:"src/lib/utils/http/__bundle-sentinel__",generated:!0,isDir:!0},{path:"src/lib/config/api-url.ts",generated:!0}],packages:[],scripts:[],injections:[{file:"src/app/[locale]/layout.tsx",description:"<HttpClientBundleSentinel /> mount in locale layout",presence:Bi,removePattern:Ge},{file:"src/app/layout.tsx",description:"<HttpClientBundleSentinel /> mount in root layout",presence:Bi,removePattern:Ge}],apply:at};S();import vr from"node:path";import Wc from"picocolors";P();S();P();import zc from"node:fs/promises";import me from"node:path";import Jc from"degit";var Ji=async(e,t)=>{t.text="Fetching assets from starter repo...",await Jc("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Vi=async(e,t)=>{let r=me.join(t,"src/i18n"),n=me.join(e,c.I18N_DIR);await zc.cp(r,n,{recursive:!0});let i=me.join(t,"src/proxy.ts"),o=me.join(e,c.PROXY);await N(i,o);let s=me.join(t,"src/types/i18n.ts"),a=me.join(e,c.I18N_TYPES);await N(s,a);let p=me.join(t,"src/lib/config/app-locales.ts"),u=me.join(e,c.APP_LOCALES);await N(p,u)};S();P();import Ot from"node:path";var Wi=async e=>{let t=Ot.join(e,c.I18N_DIR),r=Ot.join(e,"package.json");if(m(t))return{isSetup:!0,reason:"src/i18n directory exists"};if(m(r)){let n=JSON.parse(await f(r));if(n.dependencies?.["next-intl"]||n.devDependencies?.["next-intl"])return{isSetup:!0,reason:"next-intl is installed"}}return{isSetup:!1,reason:""}},qi=async e=>{let t=Ot.join(e,c.ROOT_LAYOUT),r=Ot.join(e,"src/app/[locale]/layout.tsx");if(!m(t)&&!m(r))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx exists.")};S();P();import Vc from"node:fs/promises";import se from"node:path";var Xi=async e=>{let t=se.join(e,c.NEXT_CONFIG);if(m(t)){let r=await f(t);if(!r.includes("createNextIntlPlugin")){r=`import createNextIntlPlugin from 'next-intl/plugin';
863
+ `)}`)};ze();var pt=async e=>{let t=b("Checking HTTP Client setup..."),r=jt.join(e,".next-maker-temp-http");try{let{status:n,reason:i}=await Wi(e);t.stop();let o=await Qc(n,i);if(o.type==="cancel"){console.log(Cr.yellow("Setup cancelled."));return}if(t.start("Setting up HTTP client(s)..."),await qi(e),await zi(r,t),o.type==="replace"&&o.fromClient&&(t.text="Migrating client usages...",await Qt(e,o.fromClient,o.clients[0])),o.type!=="remove-both"&&o.type!=="remove-one"){t.text="Copying client files...";let $=o.type==="replace"&&o.fromClient?[o.fromClient]:void 0;await Ji(e,r,o.clients,$)}if(o.type==="remove-one"||o.type==="remove-both"){t.text="Removing client files...";let{PROJECT_PATHS:$}=await Promise.resolve().then(()=>(S(),dn));for(let I of o.clients){let W=jt.join(e,I==="fetch"?$.FETCH_CLIENT:$.AXIOS_CLIENT);await w(W)}Xi(n,o).length===0&&(t.text="Performing full cleanup...",await Vi(e),await rr(e))}let s=Xi(n,o);s.length>0?(t.text="Configuring client...",await Xt(e,s),await Yt(e),await Kt(e),await Zt(e),await tr(e),await Ae(e,s),await _e(e,s)):await Be(e),await ke(e,s),t.text="Managing dependencies...";let a=jt.join(e,"package.json"),p=JSON.parse(await Zc.readFile(a,"utf-8")),u={...p.dependencies,...p.devDependencies};s.includes("axios")?u.axios||(t.text="Installing Axios...",await G(e,"axios")):u.axios&&(t.text="Uninstalling Axios...",await Ne(e,"axios")),s.length>0?u["server-only"]||(t.text="Installing server-only...",await G(e,"server-only")):u["server-only"]&&(t.text="Uninstalling server-only...",await Ne(e,"server-only"));let d=jt.join(e,"src/services/storage");s.length>0||m(d)?u["react-secure-storage"]||(t.text="Installing react-secure-storage...",await G(e,"react-secure-storage")):u["react-secure-storage"]&&(t.text="Uninstalling react-secure-storage...",await Ne(e,"react-secure-storage")),t.text="Formatting code...";let x=await k(e);await J(e,x,"lint:fix"),t.succeed(Cr.green(ep(o)))}catch(n){throw t.fail("Failed to setup HTTP Client."),n}finally{await w(r)}};async function Qc(e,t){if(e==="none"){let{choice:n}=await Dt.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 Dt.prompt({type:"select",name:"action",message:`${t}. 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 Dt.prompt({type:"select",name:"action",message:`${t}. 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(Cr.yellow(`\u2716 ${t}`));let{action:r}=await Dt.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 r==="cancel"?{type:"cancel",clients:[]}:r==="remove-fetch"?{type:"remove-one",clients:["fetch"]}:r==="remove-axios"?{type:"remove-one",clients:["axios"]}:r==="remove-both"?{type:"remove-both",clients:["fetch","axios"]}:{type:"cancel",clients:[]}}function Xi(e,t){return t.type==="install"?t.clients:t.type==="add"?[...e==="fetch"?["fetch"]:["axios"],...t.clients]:t.type==="replace"?t.clients:t.type==="remove-one"?e==="both"?t.clients[0]==="fetch"?["axios"]:["fetch"]:[]:[]}function ep(e){if(e.type==="install")return`HTTP Client (${e.clients.map(r=>r==="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 t=e.fromClient==="fetch"?"Fetch":"Axios",r=e.clients[0]==="fetch"?"Fetch":"Axios";return`Replaced ${t} with ${r} 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!"}ze();var Yi=/<HttpClientBundleSentinel\s*\/>/,Ki={id:"http-client",name:"HTTP Client",description:"Axios and/or Fetch client utilities",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(H(),Ye));return(await t(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"},{path:"src/lib/utils/http/shared",generated:!0,isDir:!0},{path:"src/lib/utils/http/server.ts",generated:!0},{path:"src/lib/utils/http/__bundle-sentinel__",generated:!0,isDir:!0},{path:"src/lib/config/api-url.ts",generated:!0}],packages:[],scripts:[],injections:[{file:"src/app/[locale]/layout.tsx",description:"<HttpClientBundleSentinel /> mount in locale layout",presence:Yi,removePattern:He},{file:"src/app/layout.tsx",description:"<HttpClientBundleSentinel /> mount in root layout",presence:Yi,removePattern:He}],apply:pt};S();import Tr from"node:path";import ip from"picocolors";P();S();P();import tp from"node:fs/promises";import ue from"node:path";import rp from"degit";var Zi=async(e,t)=>{t.text="Fetching assets from starter repo...",await rp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Qi=async(e,t)=>{let r=ue.join(t,"src/i18n"),n=ue.join(e,c.I18N_DIR);await tp.cp(r,n,{recursive:!0});let i=ue.join(t,"src/proxy.ts"),o=ue.join(e,c.PROXY);await N(i,o);let s=ue.join(t,"src/types/i18n.ts"),a=ue.join(e,c.I18N_TYPES);await N(s,a);let p=ue.join(t,"src/lib/config/app-locales.ts"),u=ue.join(e,c.APP_LOCALES);await N(p,u)};S();P();import Lt from"node:path";var eo=async e=>{let t=Lt.join(e,c.I18N_DIR),r=Lt.join(e,"package.json");if(m(t))return{isSetup:!0,reason:"src/i18n directory exists"};if(m(r)){let n=JSON.parse(await f(r));if(n.dependencies?.["next-intl"]||n.devDependencies?.["next-intl"])return{isSetup:!0,reason:"next-intl is installed"}}return{isSetup:!1,reason:""}},to=async e=>{let t=Lt.join(e,c.ROOT_LAYOUT),r=Lt.join(e,"src/app/[locale]/layout.tsx");if(!m(t)&&!m(r))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx exists.")};S();P();import np from"node:fs/promises";import ce from"node:path";var ro=async e=>{let t=ce.join(e,c.NEXT_CONFIG);if(m(t)){let r=await f(t);if(!r.includes("createNextIntlPlugin")){r=`import createNextIntlPlugin from 'next-intl/plugin';
864
864
  ${r}`;let n=/export default (.*?);/;n.test(r)?r=r.replace(n,`
865
865
  const withNextIntl = createNextIntlPlugin();
866
866
  export default withNextIntl($1);`):(r+=`
867
867
  const withNextIntl = createNextIntlPlugin();
868
868
  `,r+=`export default withNextIntl(nextConfig);
869
- `),await g(t,r)}}},Yi=async e=>{let t=se.join(e,c.TYPES_INDEX);if(m(t)){let r=await f(t);r.includes("./i18n")||(r+=`export * from './i18n';
870
- `,await g(t,r))}},Ki=async e=>{let t=se.join(e,c.CONFIG_INDEX);if(m(t)){let r=await f(t);r.includes("./app-locales")||(r+=`export * from './app-locales';
871
- `,await g(t,r))}},Zi=async e=>{let t=se.join(e,"src/providers/RootProvider.tsx");if(m(t)){let r=await f(t),n="'use client';",i=r.includes(n);if(i&&(r=r.replace(n,"").trim()),r.includes("next-intl")||(r=`import { type AbstractIntlMessages, NextIntlClientProvider } from 'next-intl';
869
+ `),await g(t,r)}}},no=async e=>{let t=ce.join(e,c.TYPES_INDEX);if(m(t)){let r=await f(t);r.includes("./i18n")||(r+=`export * from './i18n';
870
+ `,await g(t,r))}},io=async e=>{let t=ce.join(e,c.CONFIG_INDEX);if(m(t)){let r=await f(t);r.includes("./app-locales")||(r+=`export * from './app-locales';
871
+ `,await g(t,r))}},oo=async e=>{let t=ce.join(e,"src/providers/RootProvider.tsx");if(m(t)){let r=await f(t),n="'use client';",i=r.includes(n);if(i&&(r=r.replace(n,"").trim()),r.includes("next-intl")||(r=`import { type AbstractIntlMessages, NextIntlClientProvider } from 'next-intl';
872
872
  import type { SupportedLocale } from '@/types/i18n';
873
873
  `+r),i&&(r=`${n}
874
874
  ${r}`),!r.includes("locale: SupportedLocale")){let o=` locale: SupportedLocale;
@@ -893,7 +893,7 @@ ${h}`}),r=r.replace(/export const RootProvider = \(\{([\s\S]*?)\}:\s*RootProvide
893
893
  <NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>
894
894
  ${s}
895
895
  </NextIntlClientProvider>
896
- );`)}}await g(t,r)}},Qi=async e=>{let t=se.join(e,c.ROOT_LAYOUT),r=se.join(e,c.ROOT_PAGE),n=se.join(e,"src/app/[locale]");if(await Vc.mkdir(n,{recursive:!0}),m(t)){let i=se.join(n,"layout.tsx"),o=await f(t);if(o.includes("next-intl")||(o=`import { routing } from '@/i18n/routing';
896
+ );`)}}await g(t,r)}},so=async e=>{let t=ce.join(e,c.ROOT_LAYOUT),r=ce.join(e,c.ROOT_PAGE),n=ce.join(e,"src/app/[locale]");if(await np.mkdir(n,{recursive:!0}),m(t)){let i=ce.join(n,"layout.tsx"),o=await f(t);if(o.includes("next-intl")||(o=`import { routing } from '@/i18n/routing';
897
897
  import { hasLocale } from 'next-intl';
898
898
  import { notFound } from 'next/navigation';
899
899
  import { getMessages, getTimeZone, setRequestLocale } from 'next-intl/server';
@@ -915,7 +915,7 @@ export function generateStaticParams() {
915
915
  setRequestLocale(locale);
916
916
 
917
917
  const [messages, timeZone] = await Promise.all([getMessages(), getTimeZone()]);
918
- `+o.slice(h+1)}o=o.replace(/<RootProvider>/,"<RootProvider locale={locale} messages={messages} timeZone={timeZone}>"),o=o.replace(/<html lang="en"/,"<html lang={locale} dir={getLocaleDirection(locale)}")}await g(i,o),await E(t)}if(m(r)){let i=se.join(n,"page.tsx"),o=await f(r);o.includes("next-intl")||(o=`import { SupportedLocale } from '@/types/i18n';
918
+ `+o.slice(h+1)}o=o.replace(/<RootProvider>/,"<RootProvider locale={locale} messages={messages} timeZone={timeZone}>"),o=o.replace(/<html lang="en"/,"<html lang={locale} dir={getLocaleDirection(locale)}")}await g(i,o),await C(t)}if(m(r)){let i=ce.join(n,"page.tsx"),o=await f(r);o.includes("next-intl")||(o=`import { SupportedLocale } from '@/types/i18n';
919
919
  import { setRequestLocale } from 'next-intl/server';
920
920
  ${o}`),o=o.replace(/export default function Home\(\)/,`type Props = {
921
921
  params: Promise<{ locale: string }>;
@@ -924,8 +924,8 @@ ${o}`),o=o.replace(/export default function Home\(\)/,`type Props = {
924
924
  export default async function Home(props: Props)`);let s=o.indexOf("export default async function Home(props: Props) {");if(s!==-1){let a=`
925
925
  const locale = (await props.params).locale as SupportedLocale;
926
926
  setRequestLocale(locale);
927
- `,p=o.indexOf("{",s);o=o.slice(0,p+1)+a+o.slice(p+1)}await g(i,o),await E(r)}};var ct=async e=>{let t=b("Setting up Internationalization (next-intl)..."),r=vr.join(e,".next-maker-temp-i18n");try{let{isSetup:n,reason:i}=await Wi(e);if(n){t.fail(`i18n is already set up (${i}).`);return}await qi(e),await Ji(r,t),t.text="Copying i18n files...",await Vi(e,r),t.text="Configuring project structure...",await Xi(e),await Yi(e),await Ki(e),await Zi(e),t.text="Migrating to [locale] structure...",await Qi(e),t.text="Installing dependencies...",await G(e,"next-intl");let o=vr.join(e,c.VITEST_CONFIG);if(m(o)){let a=JSON.parse(await f(vr.join(e,c.PACKAGE_JSON))),p={...a.dependencies,...a.devDependencies},u=!!(p["@reduxjs/toolkit"]&&p["react-redux"]);await ce(e,{redux:u,i18n:!0})}t.text="Formatting code...";let s=await k(e);await z(e,s,"lint:fix"),t.succeed(Wc.green("Internationalization setup successfully!"))}catch(n){throw t.fail("Failed to setup Internationalization."),n}finally{await w(r)}};var eo={id:"i18n",name:"Internationalization",description:"next-intl with [locale] routing, RootProvider, and proxy.ts",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(H(),qe));return(await t(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:vi},{file:"src/providers/RootProvider.tsx",description:"<NextIntlClientProvider> wrap",presence:/NextIntlClientProvider/,removePattern:Ae("NextIntlClientProvider")}],apply:ct};S();P();import Yc from"node:path";S();import qc from"node:path";import Xc from"picocolors";P();var pt=async e=>{let t=b("Enabling React Compiler...");try{let r=qc.join(e,c.NEXT_CONFIG);if(!m(r))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await f(r);if(n.includes("reactCompiler:")){t.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
928
- reactCompiler: true,`),await g(r,n),t.text="Installing babel-plugin-react-compiler...",await vt(e,"babel-plugin-react-compiler"),t.succeed(Xc.green("React Compiler enabled."))}catch(r){throw t.fail("Failed to enable React Compiler."),r}};var to={id:"react-compiler",name:"React Compiler",description:"reactCompiler: true in next.config.ts + babel-plugin-react-compiler",detect:async e=>{let t=Yc.join(e,c.NEXT_CONFIG);return m(t)?/reactCompiler\s*:\s*true/.test(await f(t)):!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:pt};S();import Er from"node:path";import Zc from"picocolors";P();S();P();import ro from"node:fs/promises";import Se from"node:path";import Kc from"degit";var no=async(e,t)=>{t.text="Fetching assets from starter repo...",await Kc("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},io=async(e,t)=>{let r=Se.join(t,"src/providers/StoreProvider.tsx"),n=Se.join(e,c.STORE_PROVIDER);await N(r,n);let i=Se.join(t,"src/store"),o=Se.join(e,c.STORE);await ro.cp(i,o,{recursive:!0})},oo=async(e,t)=>{let r=Se.join(t,"src/features/counter"),n=Se.join(e,c.COUNTER_FEATURE);await ro.cp(r,n,{recursive:!0});let i=Se.join(n,"components/Counter.tsx");if(await m(i)){let o=await f(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 g(i,o)}};S();P();import Sr from"node:path";var so=async e=>{let t=Sr.join(e,c.STORE),r=Sr.join(e,"package.json");if(m(t))return{isSetup:!0,reason:"src/store directory exists"};if(m(r)){let n=JSON.parse(await f(r));if(n.dependencies?.["@reduxjs/toolkit"]||n.devDependencies?.["@reduxjs/toolkit"])return{isSetup:!0,reason:"@reduxjs/toolkit is installed"}}return{isSetup:!1,reason:""}},ao=async e=>{let t=Sr.join(e,c.PROVIDERS_INDEX);if(!await Nt(e)||!m(t))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx (or src/app/[locale]/layout.tsx) and src/providers/index.ts exist.")};S();P();import Cr from"node:path";var co=async e=>{},po=async e=>{let t=Cr.join(e,"src/providers/RootProvider.tsx");if(!m(t))return;let r=await f(t),n="'use client';",i=r.includes(n);if(i&&(r=r.replace(n,"").trim()),r.includes("from '@/store'")||(r=`import type { AppState } from '@/store';
927
+ `,p=o.indexOf("{",s);o=o.slice(0,p+1)+a+o.slice(p+1)}await g(i,o),await C(r)}};var lt=async e=>{let t=b("Setting up Internationalization (next-intl)..."),r=Tr.join(e,".next-maker-temp-i18n");try{let{isSetup:n,reason:i}=await eo(e);if(n){t.fail(`i18n is already set up (${i}).`);return}await to(e),await Zi(r,t),t.text="Copying i18n files...",await Qi(e,r),t.text="Configuring project structure...",await ro(e),await no(e),await io(e),await oo(e),t.text="Migrating to [locale] structure...",await so(e),t.text="Installing dependencies...",await G(e,"next-intl");let o=Tr.join(e,c.VITEST_CONFIG);if(m(o)){let a=JSON.parse(await f(Tr.join(e,c.PACKAGE_JSON))),p={...a.dependencies,...a.devDependencies},u=!!(p["@reduxjs/toolkit"]&&p["react-redux"]);await le(e,{redux:u,i18n:!0})}t.text="Formatting code...";let s=await k(e);await J(e,s,"lint:fix"),t.succeed(ip.green("Internationalization setup successfully!"))}catch(n){throw t.fail("Failed to setup Internationalization."),n}finally{await w(r)}};var ao={id:"i18n",name:"Internationalization",description:"next-intl with [locale] routing, RootProvider, and proxy.ts",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(H(),Ye));return(await t(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:$i},{file:"src/providers/RootProvider.tsx",description:"<NextIntlClientProvider> wrap",presence:/NextIntlClientProvider/,removePattern:Oe("NextIntlClientProvider")}],apply:lt};S();P();import ap from"node:path";S();import op from"node:path";import sp from"picocolors";P();var mt=async e=>{let t=b("Enabling React Compiler...");try{let r=op.join(e,c.NEXT_CONFIG);if(!m(r))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await f(r);if(n.includes("reactCompiler:")){t.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
928
+ reactCompiler: true,`),await g(r,n),t.text="Installing babel-plugin-react-compiler...",await Et(e,"babel-plugin-react-compiler"),t.succeed(sp.green("React Compiler enabled."))}catch(r){throw t.fail("Failed to enable React Compiler."),r}};var co={id:"react-compiler",name:"React Compiler",description:"reactCompiler: true in next.config.ts + babel-plugin-react-compiler",detect:async e=>{let t=ap.join(e,c.NEXT_CONFIG);return m(t)?/reactCompiler\s*:\s*true/.test(await f(t)):!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:mt};S();import $r from"node:path";import pp from"picocolors";P();S();P();import po from"node:fs/promises";import Ce from"node:path";import cp from"degit";var lo=async(e,t)=>{t.text="Fetching assets from starter repo...",await cp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},mo=async(e,t)=>{let r=Ce.join(t,"src/providers/StoreProvider.tsx"),n=Ce.join(e,c.STORE_PROVIDER);await N(r,n);let i=Ce.join(t,"src/store"),o=Ce.join(e,c.STORE);await po.cp(i,o,{recursive:!0})},uo=async(e,t)=>{let r=Ce.join(t,"src/features/counter"),n=Ce.join(e,c.COUNTER_FEATURE);await po.cp(r,n,{recursive:!0});let i=Ce.join(n,"components/Counter.tsx");if(await m(i)){let o=await f(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 g(i,o)}};S();P();import br from"node:path";var fo=async e=>{let t=br.join(e,c.STORE),r=br.join(e,"package.json");if(m(t))return{isSetup:!0,reason:"src/store directory exists"};if(m(r)){let n=JSON.parse(await f(r));if(n.dependencies?.["@reduxjs/toolkit"]||n.devDependencies?.["@reduxjs/toolkit"])return{isSetup:!0,reason:"@reduxjs/toolkit is installed"}}return{isSetup:!1,reason:""}},go=async e=>{let t=br.join(e,c.PROVIDERS_INDEX);if(!await Ot(e)||!m(t))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx (or src/app/[locale]/layout.tsx) and src/providers/index.ts exist.")};S();P();import Rr from"node:path";var ho=async e=>{},yo=async e=>{let t=Rr.join(e,"src/providers/RootProvider.tsx");if(!m(t))return;let r=await f(t),n="'use client';",i=r.includes(n);if(i&&(r=r.replace(n,"").trim()),r.includes("from '@/store'")||(r=`import type { AppState } from '@/store';
929
929
  ${r}`),r.includes("from './StoreProvider'")||(r=`${r.includes("from '@/store'"),""}import { StoreProvider } from './StoreProvider';
930
930
  ${r}`),i&&(r=`${n}
931
931
  ${r}`),r.includes("preloadedState")||(r=r.replace(/children:\s*React\.ReactNode;/,`children: React.ReactNode;
@@ -933,13 +933,13 @@ ${r}`),r.includes("preloadedState")||(r=r.replace(/children:\s*React\.ReactNode;
933
933
  <StoreProvider preloadedState={preloadedState}>
934
934
  ${s}
935
935
  </StoreProvider>
936
- );`)}}await g(t,r)},lo=async e=>{let t=[Cr.join(e,c.ROOT_PAGE),Cr.join(e,"src/app/[locale]/page.tsx")],r="";for(let i of t)if(m(i)){r=i;break}if(!r)return;let n=await f(r);if(n.includes("Counter")||(n=`import { Counter } from '@/features/counter';
936
+ );`)}}await g(t,r)},xo=async e=>{let t=[Rr.join(e,c.ROOT_PAGE),Rr.join(e,"src/app/[locale]/page.tsx")],r="";for(let i of t)if(m(i)){r=i;break}if(!r)return;let n=await f(r);if(n.includes("Counter")||(n=`import { Counter } from '@/features/counter';
937
937
  ${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)+`
938
938
  <div className="mt-8">
939
939
  <h2 className="mb-4 text-2xl font-bold">Redux Counter</h2>
940
940
  <Counter />
941
941
  </div>
942
- `+n.slice(s),await g(r,n))}};var lt=async e=>{let t=b("Setting up Redux Toolkit..."),r=Er.join(e,".next-maker-temp-redux");try{let{isSetup:n,reason:i}=await so(e);if(n){t.fail(`Redux is already set up (${i}).`);return}await ao(e),await no(r,t),t.text="Copying Redux files...",await io(e,r),t.text="Creating Counter feature...",await oo(e,r),t.text="Updating providers and pages...",await co(e),await po(e),await lo(e),t.text="Installing dependencies...",await G(e,"@reduxjs/toolkit"),await G(e,"react-redux"),await G(e,"redux-persist"),await G(e,"react-secure-storage");let o=Er.join(e,c.VITEST_CONFIG);if(m(o)){let a=JSON.parse(await f(Er.join(e,c.PACKAGE_JSON))),p={...a.dependencies,...a.devDependencies};await ce(e,{redux:!0,i18n:!!p["next-intl"]})}t.text="Formatting code...";let s=await k(e);await z(e,s,"lint:fix"),t.succeed(Zc.green("Redux Toolkit setup successfully!"))}catch(n){throw t.fail("Failed to setup Redux Toolkit."),n}finally{await w(r)}};var mo={id:"redux",name:"Redux Toolkit",description:"Redux Toolkit + react-redux + redux-persist + StoreProvider",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(H(),qe));return(await t(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:Ae("StoreProvider")}],apply:lt};S();P();import np from"node:path";S();import tp from"node:path";import rp from"picocolors";P();var fo=[{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"}],uo=/(const\s+nextConfig\s*:\s*NextConfig\s*=\s*\{)/,Qc=/^\s+headers\s*:/m,ep=e=>`
942
+ `+n.slice(s),await g(r,n))}};var dt=async e=>{let t=b("Setting up Redux Toolkit..."),r=$r.join(e,".next-maker-temp-redux");try{let{isSetup:n,reason:i}=await fo(e);if(n){t.fail(`Redux is already set up (${i}).`);return}await go(e),await lo(r,t),t.text="Copying Redux files...",await mo(e,r),t.text="Creating Counter feature...",await uo(e,r),t.text="Updating providers and pages...",await ho(e),await yo(e),await xo(e),t.text="Installing dependencies...",await G(e,"@reduxjs/toolkit"),await G(e,"react-redux"),await G(e,"redux-persist"),await G(e,"react-secure-storage");let o=$r.join(e,c.VITEST_CONFIG);if(m(o)){let a=JSON.parse(await f($r.join(e,c.PACKAGE_JSON))),p={...a.dependencies,...a.devDependencies};await le(e,{redux:!0,i18n:!!p["next-intl"]})}t.text="Formatting code...";let s=await k(e);await J(e,s,"lint:fix"),t.succeed(pp.green("Redux Toolkit setup successfully!"))}catch(n){throw t.fail("Failed to setup Redux Toolkit."),n}finally{await w(r)}};var Po={id:"redux",name:"Redux Toolkit",description:"Redux Toolkit + react-redux + redux-persist + StoreProvider",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(H(),Ye));return(await t(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:Oe("StoreProvider")}],apply:dt};S();P();import fp from"node:path";S();import dp from"node:path";import up from"picocolors";P();var vo=[{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"}],wo=/(const\s+nextConfig\s*:\s*NextConfig\s*=\s*\{)/,lp=/^\s+headers\s*:/m,mp=e=>`
943
943
  headers: async () => {
944
944
  return [
945
945
  {
@@ -950,7 +950,7 @@ ${e.map(({key:r,value:n})=>` { key: '${r}', value: '${n}' },`).join(`
950
950
  ],
951
951
  },
952
952
  ];
953
- },`,_e=e=>Qc.test(e),Tr=(e,t=fo)=>{if(_e(e))return e;if(!uo.test(e))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");return e.replace(uo,`$1${ep(t)}`)};var mt=async e=>{let t=b("Adding security headers to next.config.ts...");try{let r=tp.join(e,c.NEXT_CONFIG);if(!m(r))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await f(r);if(_e(n)){t.succeed("Security headers already configured.");return}let i=Tr(n);await g(r,i),t.succeed(rp.green("Security headers added."))}catch(r){throw t.fail("Failed to add security headers."),r}};var go={id:"security-headers",name:"Security Headers",description:"Hardened HTTP headers in next.config.ts",detect:async e=>{let t=np.join(e,c.NEXT_CONFIG);return m(t)?_e(await f(t)):!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:mt};S();P();import cp from"node:path";S();import ip from"node:fs/promises";import de from"node:path";import op from"degit";import sp from"picocolors";P();var ap=["vitest","jsdom","@vitejs/plugin-react","@testing-library/dom","@testing-library/jest-dom","@testing-library/react","@testing-library/user-event"],dt=async e=>{let t=b("Setting up testing (Vitest + RTL)..."),r=de.join(e,".next-maker-temp-tests");try{let n=de.join(e,c.VITEST_CONFIG);if(m(n)){t.fail("Testing is already set up (vitest.config.ts exists).");return}t.text="Fetching assets from starter repo...",await op("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(r),await N(de.join(r,c.VITEST_CONFIG),de.join(e,c.VITEST_CONFIG));let o=de.join(e,c.TEST_DIR);await ip.mkdir(o,{recursive:!0}),await N(de.join(r,c.TEST_DIR,"setup.ts"),de.join(o,"setup.ts"));let s=de.join(e,c.PACKAGE_JSON),a=JSON.parse(await f(s)),p={...a.dependencies,...a.devDependencies},u=!!(p["@reduxjs/toolkit"]&&p["react-redux"]),d=!!p["next-intl"];await ce(e,{redux:u,i18n:d}),await D(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)),t.text="Installing testing devDependencies...";let h=await k(e);await xe(e,h,ap),t.text="Formatting code...",await z(e,h,"lint:fix"),t.succeed(sp.green("Testing setup complete."))}catch(n){throw t.fail("Failed to set up testing."),n}finally{await w(r)}};var ho={id:"tests",name:"Tests",description:"Vitest + React Testing Library + jsdom",detect:async e=>m(cp.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:dt};P();import up from"node:path";S();import yo from"node:path";import mp from"picocolors";P();var pp={npm:"npm run",yarn:"yarn",pnpm:"pnpm",bun:"bun run"},lp=e=>{let t=pp[e];return["ci:check","type-check","check:deprecated","test","build"].map(r=>`${t} ${r}`).join(" && ")},br=(e,t)=>{let r={...e.scripts??{}},n={...e.devDependencies??{}};return r["env:sync"]||(r["env:sync"]="tsx scripts/sync-env.ts"),r["check:deprecated"]||(r["check:deprecated"]="tsx scripts/check-deprecated.ts"),r["type-check"]||(r["type-check"]="tsc --noEmit"),r.validate||(r.validate=lp(t)),!n.tsx&&!e.dependencies?.hasOwnProperty("tsx")&&(n.tsx="*"),{...e,scripts:r,devDependencies:n}};var Rr=`import * as fs from 'node:fs';
953
+ },`,Fe=e=>lp.test(e),Ir=(e,t=vo)=>{if(Fe(e))return e;if(!wo.test(e))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");return e.replace(wo,`$1${mp(t)}`)};var ut=async e=>{let t=b("Adding security headers to next.config.ts...");try{let r=dp.join(e,c.NEXT_CONFIG);if(!m(r))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await f(r);if(Fe(n)){t.succeed("Security headers already configured.");return}let i=Ir(n);await g(r,i),t.succeed(up.green("Security headers added."))}catch(r){throw t.fail("Failed to add security headers."),r}};var So={id:"security-headers",name:"Security Headers",description:"Hardened HTTP headers in next.config.ts",detect:async e=>{let t=fp.join(e,c.NEXT_CONFIG);return m(t)?Fe(await f(t)):!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:ut};S();P();import Pp from"node:path";S();import gp from"node:fs/promises";import fe from"node:path";import hp from"degit";import yp from"picocolors";P();var xp=["vitest","jsdom","@vitejs/plugin-react","@testing-library/dom","@testing-library/jest-dom","@testing-library/react","@testing-library/user-event"],ft=async e=>{let t=b("Setting up testing (Vitest + RTL)..."),r=fe.join(e,".next-maker-temp-tests");try{let n=fe.join(e,c.VITEST_CONFIG);if(m(n)){t.fail("Testing is already set up (vitest.config.ts exists).");return}t.text="Fetching assets from starter repo...",await hp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(r),await N(fe.join(r,c.VITEST_CONFIG),fe.join(e,c.VITEST_CONFIG));let o=fe.join(e,c.TEST_DIR);await gp.mkdir(o,{recursive:!0}),await N(fe.join(r,c.TEST_DIR,"setup.ts"),fe.join(o,"setup.ts"));let s=fe.join(e,c.PACKAGE_JSON),a=JSON.parse(await f(s)),p={...a.dependencies,...a.devDependencies},u=!!(p["@reduxjs/toolkit"]&&p["react-redux"]),d=!!p["next-intl"];await le(e,{redux:u,i18n:d}),await D(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)),t.text="Installing testing devDependencies...";let h=await k(e);await we(e,h,xp),t.text="Formatting code...",await J(e,h,"lint:fix"),t.succeed(yp.green("Testing setup complete."))}catch(n){throw t.fail("Failed to set up testing."),n}finally{await w(r)}};var Eo={id:"tests",name:"Tests",description:"Vitest + React Testing Library + jsdom",detect:async e=>m(Pp.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:ft};P();import Cp from"node:path";S();import Co from"node:path";import Sp from"picocolors";P();var wp={npm:"npm run",yarn:"yarn",pnpm:"pnpm",bun:"bun run"},vp=e=>{let t=wp[e];return["ci:check","type-check","check:deprecated","test","build"].map(r=>`${t} ${r}`).join(" && ")},Nr=(e,t)=>{let r={...e.scripts??{}},n={...e.devDependencies??{}};return r["env:sync"]||(r["env:sync"]="tsx scripts/sync-env.ts"),r["check:deprecated"]||(r["check:deprecated"]="tsx scripts/check-deprecated.ts"),r["type-check"]||(r["type-check"]="tsc --noEmit"),r.validate||(r.validate=vp(t)),!n.tsx&&!e.dependencies?.hasOwnProperty("tsx")&&(n.tsx="*"),{...e,scripts:r,devDependencies:n}};var kr=`import * as fs from 'node:fs';
954
954
  import * as path from 'node:path';
955
955
 
956
956
  const checkOnly = process.argv.includes('--check');
@@ -1024,7 +1024,7 @@ if (checkOnly) {
1024
1024
 
1025
1025
  fs.writeFileSync(examplePath, newExampleContent);
1026
1026
  console.log('\u2705 Synchronized .env.example with .env');
1027
- `,$r=`/**
1027
+ `,Ar=`/**
1028
1028
  * Walks every identifier in the project and flags any whose resolved TypeScript
1029
1029
  * symbol carries a \`@deprecated\` JSDoc tag. Catches deprecated API usage that
1030
1030
  * \`tsc --noEmit\` does not surface (deprecations are "suggestion"-level, not
@@ -1088,14 +1088,14 @@ if (hits === 0) {
1088
1088
 
1089
1089
  console.log(\`\\n\${hits} deprecated symbol use(s) found.\`);
1090
1090
  process.exit(1);
1091
- `;var dp=[{relative:"scripts/sync-env.ts",content:Rr},{relative:"scripts/check-deprecated.ts",content:$r}],ut=async e=>{let t=b("Adding validation scripts...");try{let r=!1;for(let{relative:o,content:s}of dp){let a=yo.join(e,o);m(a)||(await g(a,s),r=!0)}let n=await k(e),i=!1;await D(yo.join(e,c.PACKAGE_JSON),o=>{let s=o.devDependencies?.tsx,a=br(o,n);return i=!s&&!!a.devDependencies?.tsx,a}),i&&(t.text="Installing tsx...",await xe(e,n,["tsx"])),t.succeed(mp.green(r?"Validation scripts added (env:sync, check:deprecated, validate).":"Validation scripts already present \u2014 refreshed package.json."))}catch(r){throw t.fail("Failed to add validation scripts."),r}};var xo=["scripts/sync-env.ts","scripts/check-deprecated.ts"],Po={id:"validate-scripts",name:"Validation Scripts",description:"sync-env, check-deprecated, and the validate chain",detect:async e=>xo.every(t=>m(up.join(e,t))),files:xo.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:ut};import{access as yp,readFile as xp}from"node:fs/promises";import To from"node:path";S();import Nr from"node:path";import hp from"picocolors";P();S();P();import Ir from"node:fs/promises";import ft from"node:path";import fp from"degit";var wo=async(e,t)=>{t.text="Downloading assets from starter repository...",await fp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},vo=async(e,t,r)=>{let n=ft.join(e,c.WS_UTILS);await Ir.cp(ft.join(t,c.WS_UTILS),n,{recursive:!0,force:!0});let i=ft.join(e,c.WS_SLICE_FILE);await N(ft.join(t,c.WS_SLICE_FILE),i),r.keepTests||await gp(n)},gp=async e=>{let t=async r=>{let n=await Ir.readdir(r,{withFileTypes:!0});for(let i of n){let o=ft.join(r,i.name);if(i.isDirectory()){if(i.name==="__test-utils__"){await w(o);continue}await t(o)}else i.isFile()&&/\.test\.tsx?$/.test(i.name)&&await Ir.unlink(o)}};await t(e)};S();P();import So from"node:path";var Co=async e=>{let t=So.join(e,c.WS_UTILS);return m(t)?{isSetup:!0,reason:"src/lib/utils/ws/ already exists"}:{isSetup:!1}},Eo=async e=>{let t=[],r=[{rel:"src/lib",label:"src/lib"},{rel:"src/store",label:"src/store (Redux Toolkit not installed?)"},{rel:c.ROOT_REDUCER,label:"src/store/rootReducer.ts (Redux not initialised?)"},{rel:c.STORE_PROVIDER,label:"src/providers/StoreProvider.tsx (Redux not initialised?)"}];for(let{rel:n,label:i}of r)m(So.join(e,n))||t.push(`- ${i}`);if(t.length>0)throw new Error(`WebSocket setup requires Redux Toolkit. Missing:
1091
+ `;var Ep=[{relative:"scripts/sync-env.ts",content:kr},{relative:"scripts/check-deprecated.ts",content:Ar}],gt=async e=>{let t=b("Adding validation scripts...");try{let r=!1;for(let{relative:o,content:s}of Ep){let a=Co.join(e,o);m(a)||(await g(a,s),r=!0)}let n=await k(e),i=!1;await D(Co.join(e,c.PACKAGE_JSON),o=>{let s=o.devDependencies?.tsx,a=Nr(o,n);return i=!s&&!!a.devDependencies?.tsx,a}),i&&(t.text="Installing tsx...",await we(e,n,["tsx"])),t.succeed(Sp.green(r?"Validation scripts added (env:sync, check:deprecated, validate).":"Validation scripts already present \u2014 refreshed package.json."))}catch(r){throw t.fail("Failed to add validation scripts."),r}};var To=["scripts/sync-env.ts","scripts/check-deprecated.ts"],bo={id:"validate-scripts",name:"Validation Scripts",description:"sync-env, check-deprecated, and the validate chain",detect:async e=>To.every(t=>m(Cp.join(e,t))),files:To.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:gt};import{access as $p,readFile as Ip}from"node:fs/promises";import Ao from"node:path";S();import Or from"node:path";import Rp from"picocolors";P();S();P();import _r from"node:fs/promises";import ht from"node:path";import Tp from"degit";var Ro=async(e,t)=>{t.text="Downloading assets from starter repository...",await Tp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},$o=async(e,t,r)=>{let n=ht.join(e,c.WS_UTILS);await _r.cp(ht.join(t,c.WS_UTILS),n,{recursive:!0,force:!0});let i=ht.join(e,c.WS_SLICE_FILE);await N(ht.join(t,c.WS_SLICE_FILE),i),r.keepTests||await bp(n)},bp=async e=>{let t=async r=>{let n=await _r.readdir(r,{withFileTypes:!0});for(let i of n){let o=ht.join(r,i.name);if(i.isDirectory()){if(i.name==="__test-utils__"){await w(o);continue}await t(o)}else i.isFile()&&/\.test\.tsx?$/.test(i.name)&&await _r.unlink(o)}};await t(e)};S();P();import Io from"node:path";var No=async e=>{let t=Io.join(e,c.WS_UTILS);return m(t)?{isSetup:!0,reason:"src/lib/utils/ws/ already exists"}:{isSetup:!1}},ko=async e=>{let t=[],r=[{rel:"src/lib",label:"src/lib"},{rel:"src/store",label:"src/store (Redux Toolkit not installed?)"},{rel:c.ROOT_REDUCER,label:"src/store/rootReducer.ts (Redux not initialised?)"},{rel:c.STORE_PROVIDER,label:"src/providers/StoreProvider.tsx (Redux not initialised?)"}];for(let{rel:n,label:i}of r)m(Io.join(e,n))||t.push(`- ${i}`);if(t.length>0)throw new Error(`WebSocket setup requires Redux Toolkit. Missing:
1092
1092
  ${t.join(`
1093
1093
  `)}
1094
1094
 
1095
- Run \`next-maker setup --redux\` first.`)};var gt=async e=>{let t=b("Setting up WebSocket layer..."),r=Nr.join(e,".next-maker-temp-ws");try{let{isSetup:n,reason:i}=await Co(e);if(n){t.fail(`WebSocket layer is already set up (${i}).`);return}await Eo(e),await wo(r,t),t.text="Copying WebSocket files...";let o=m(Nr.join(e,c.VITEST_CONFIG));await vo(e,r,{keepTests:o}),t.text="Registering wsReducer...",await kn(e),t.text="Mounting WS bridge in StoreProvider...",await An(e),t.text="Ensuring test/setup.ts mocks...",await _n(e),t.text="Installing socket.io-client...";let s=Nr.join(e,c.PACKAGE_JSON),a=JSON.parse(await f(s));({...a.dependencies,...a.devDependencies})["socket.io-client"]||await G(e,"socket.io-client@^4.8.3"),t.text="Formatting code...";let u=await k(e);await z(e,u,"lint:fix"),t.succeed(hp.green("WebSocket layer setup successfully!"))}catch(n){throw t.fail("Failed to setup WebSocket layer."),n}finally{await w(r)}};var Pp=async e=>{try{let t=JSON.parse(await xp(To.join(e,"package.json"),"utf-8"));return{...t.dependencies,...t.devDependencies}["socket.io-client"]?(await yp(To.join(e,"src/lib/utils/ws")),!0):!1}catch{return!1}},bo={id:"ws",name:"WebSocket Client",description:"socket.io-client + lazy WS singleton + Redux slice + hooks",detect:Pp,files:[{path:"src/lib/utils/ws",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds the ws client + any feature event maps you added \u2014 review before deleting"},{path:"src/store/slices/ws.slice.ts",generated:!0}],packages:[{name:"socket.io-client",kind:"dependency"}],scripts:[],injections:[{file:"src/store/rootReducer.ts",description:"wsReducer registration in rootReducer",presence:/ws:\s*wsReducer\b/,removePattern:Et},{file:"src/providers/StoreProvider.tsx",description:"attachWsBridge mount in StoreProvider",presence:/attachWsBridge\(wsClient,\s*store\.dispatch\)/,removePattern:Ct}],apply:gt};S();P();import Oe from"node:path";var Ro=async e=>{let t=Oe.join(e,c.PACKAGE_JSON);return m(t)?JSON.parse(await f(t)):null},wp=async(e,t)=>{let r=Oe.join(e,c.PACKAGE_JSON);await g(r,`${JSON.stringify(t,null,2)}
1096
- `)},$o=(e,t)=>(t==="dependency"?e.dependencies:e.devDependencies)??{},ht=async(e,t)=>{let r=await e.detect(t),n=[];if(!r)return{manifest:e,installed:!1,drift:[]};for(let o of e.files)o.required!==!1&&(m(Oe.join(t,o.path))||n.push({kind:"missingFile",file:o.path}));let i=await Ro(t);if(i){for(let s of e.packages)$o(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=Oe.join(t,o.file);if(!m(s)){n.push({kind:"missingInjection",file:o.file,description:o.description});continue}let a=await f(s);o.presence.test(a)||n.push({kind:"missingInjection",file:o.file,description:o.description})}return{manifest:e,installed:r,drift:n}},Ft=async(e,t,r={})=>{let n=r.dryRun??!1,i={filesRemoved:[],packagesUninstalled:[],scriptsRemoved:[],blocksStripped:[],manualCleanup:[]};for(let a of e.injections){let p=Oe.join(t,a.file);if(!m(p))continue;if(!a.removePattern){i.manualCleanup.push({file:a.file,description:a.description});continue}let u=await f(p);if(!a.presence.test(u))continue;let d;if(typeof a.removePattern=="function"){let h=a.removePattern(u);if(h===null){i.manualCleanup.push({file:a.file,description:a.description});continue}d=h}else d=u.replace(a.removePattern,"");d!==u?(n||await g(p,d),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=Oe.join(t,a.path);if(m(p)){if(a.containsUserContent){let u=a.removeHint?`${a.path} \u2014 ${a.removeHint}`:`${a.path} (may contain user-authored files; review before deleting)`;i.manualCleanup.push({file:a.path,description:u});continue}n||await o(p,{recursive:!0,force:!0}),i.filesRemoved.push(a.path)}}let s=await Ro(t);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)$o(s,p.kind)[p.name]&&i.packagesUninstalled.push(p.name);a&&!n&&await wp(t,s)}if(!n&&i.packagesUninstalled.length>0){let a=await k(t);await Bt(t,a,i.packagesUninstalled)}return i};var Ce=[go,Po,Ti,to,Ci,ho,ji,zi,mo,bo,eo],Io=e=>Ce.find(t=>t.id===e);var vp=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 ${L.dim(e.expected)} but got ${L.dim(e.actual)}`;case"missingInjection":return`missing block in ${e.file}: ${e.description}`}},Sp=e=>{let t=e.filter(n=>n.installed),r=t.filter(n=>n.drift.length>0);return{installedCount:t.length,driftedCount:r.length,cleanCount:t.length-r.length,driftedResults:r}},No=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 t=>{try{let r=process.cwd(),n=t.feature?Ce.filter(s=>s.id===t.feature):Ce;if(t.feature&&n.length===0)throw new Error(`Unknown feature "${t.feature}". Valid: ${Ce.map(s=>s.id).join(", ")}.`);let i=[];for(let s of n)i.push(await ht(s,r));t.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(L.cyan(`
1095
+ Run \`next-maker setup --redux\` first.`)};var yt=async e=>{let t=b("Setting up WebSocket layer..."),r=Or.join(e,".next-maker-temp-ws");try{let{isSetup:n,reason:i}=await No(e);if(n){t.fail(`WebSocket layer is already set up (${i}).`);return}await ko(e),await Ro(r,t),t.text="Copying WebSocket files...";let o=m(Or.join(e,c.VITEST_CONFIG));await $o(e,r,{keepTests:o}),t.text="Registering wsReducer...",await jn(e),t.text="Mounting WS bridge in StoreProvider...",await Dn(e),t.text="Ensuring test/setup.ts mocks...",await Ln(e),t.text="Installing socket.io-client...";let s=Or.join(e,c.PACKAGE_JSON),a=JSON.parse(await f(s));({...a.dependencies,...a.devDependencies})["socket.io-client"]||await G(e,"socket.io-client@^4.8.3"),t.text="Formatting code...";let u=await k(e);await J(e,u,"lint:fix"),t.succeed(Rp.green("WebSocket layer setup successfully!"))}catch(n){throw t.fail("Failed to setup WebSocket layer."),n}finally{await w(r)}};var Np=async e=>{try{let t=JSON.parse(await Ip(Ao.join(e,"package.json"),"utf-8"));return{...t.dependencies,...t.devDependencies}["socket.io-client"]?(await $p(Ao.join(e,"src/lib/utils/ws")),!0):!1}catch{return!1}},_o={id:"ws",name:"WebSocket Client",description:"socket.io-client + lazy WS singleton + Redux slice + hooks",detect:Np,files:[{path:"src/lib/utils/ws",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds the ws client + any feature event maps you added \u2014 review before deleting"},{path:"src/store/slices/ws.slice.ts",generated:!0}],packages:[{name:"socket.io-client",kind:"dependency"}],scripts:[],injections:[{file:"src/store/rootReducer.ts",description:"wsReducer registration in rootReducer",presence:/ws:\s*wsReducer\b/,removePattern:bt},{file:"src/providers/StoreProvider.tsx",description:"attachWsBridge mount in StoreProvider",presence:/attachWsBridge\(wsClient,\s*store\.dispatch\)/,removePattern:Tt}],apply:yt};S();P();import je from"node:path";var Oo=async e=>{let t=je.join(e,c.PACKAGE_JSON);return m(t)?JSON.parse(await f(t)):null},kp=async(e,t)=>{let r=je.join(e,c.PACKAGE_JSON);await g(r,`${JSON.stringify(t,null,2)}
1096
+ `)},Fo=(e,t)=>(t==="dependency"?e.dependencies:e.devDependencies)??{},xt=async(e,t)=>{let r=await e.detect(t),n=[];if(!r)return{manifest:e,installed:!1,drift:[]};for(let o of e.files)o.required!==!1&&(m(je.join(t,o.path))||n.push({kind:"missingFile",file:o.path}));let i=await Oo(t);if(i){for(let s of e.packages)Fo(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=je.join(t,o.file);if(!m(s)){n.push({kind:"missingInjection",file:o.file,description:o.description});continue}let a=await f(s);o.presence.test(a)||n.push({kind:"missingInjection",file:o.file,description:o.description})}return{manifest:e,installed:r,drift:n}},Mt=async(e,t,r={})=>{let n=r.dryRun??!1,i={filesRemoved:[],packagesUninstalled:[],scriptsRemoved:[],blocksStripped:[],manualCleanup:[]};for(let a of e.injections){let p=je.join(t,a.file);if(!m(p))continue;if(!a.removePattern){i.manualCleanup.push({file:a.file,description:a.description});continue}let u=await f(p);if(!a.presence.test(u))continue;let d;if(typeof a.removePattern=="function"){let h=a.removePattern(u);if(h===null){i.manualCleanup.push({file:a.file,description:a.description});continue}d=h}else d=u.replace(a.removePattern,"");d!==u?(n||await g(p,d),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=je.join(t,a.path);if(m(p)){if(a.containsUserContent){let u=a.removeHint?`${a.path} \u2014 ${a.removeHint}`:`${a.path} (may contain user-authored files; review before deleting)`;i.manualCleanup.push({file:a.path,description:u});continue}n||await o(p,{recursive:!0,force:!0}),i.filesRemoved.push(a.path)}}let s=await Oo(t);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)Fo(s,p.kind)[p.name]&&i.packagesUninstalled.push(p.name);a&&!n&&await kp(t,s)}if(!n&&i.packagesUninstalled.length>0){let a=await k(t);await Wt(t,a,i.packagesUninstalled)}return i};var Te=[So,bo,Ai,co,Ni,Eo,Bi,Ki,Po,_o,ao],jo=e=>Te.find(t=>t.id===e);var Ap=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 ${L.dim(e.expected)} but got ${L.dim(e.actual)}`;case"missingInjection":return`missing block in ${e.file}: ${e.description}`}},_p=e=>{let t=e.filter(n=>n.installed),r=t.filter(n=>n.drift.length>0);return{installedCount:t.length,driftedCount:r.length,cleanCount:t.length-r.length,driftedResults:r}},Do=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 t=>{try{let r=process.cwd(),n=t.feature?Te.filter(s=>s.id===t.feature):Te;if(t.feature&&n.length===0)throw new Error(`Unknown feature "${t.feature}". Valid: ${Te.map(s=>s.id).join(", ")}.`);let i=[];for(let s of n)i.push(await xt(s,r));t.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(L.cyan(`
1097
1097
  \u{1FA7A} Project Doctor
1098
- `));for(let s of i){let{manifest:a,installed:p,drift:u}=s;if(!p){l(` ${L.dim("\u2014")} ${L.dim(a.name)} ${L.dim("(not installed)")}`);continue}if(u.length===0){l(` ${L.green("\u2713")} ${a.name}`);continue}l(` ${L.yellow("!")} ${L.bold(a.name)} ${L.dim(`(${u.length} issue${u.length===1?"":"s"})`)}`);for(let d of u)l(` ${L.yellow("\u2022")} ${vp(d)}`)}let o=Sp(i);l(""),l(L.dim(`${o.cleanCount} clean, ${o.driftedCount} drifted, ${i.length-o.installedCount} not installed`)),o.driftedCount===0&&(l(L.green(`
1098
+ `));for(let s of i){let{manifest:a,installed:p,drift:u}=s;if(!p){l(` ${L.dim("\u2014")} ${L.dim(a.name)} ${L.dim("(not installed)")}`);continue}if(u.length===0){l(` ${L.green("\u2713")} ${a.name}`);continue}l(` ${L.yellow("!")} ${L.bold(a.name)} ${L.dim(`(${u.length} issue${u.length===1?"":"s"})`)}`);for(let d of u)l(` ${L.yellow("\u2022")} ${Ap(d)}`)}let o=_p(i);l(""),l(L.dim(`${o.cleanCount} clean, ${o.driftedCount} drifted, ${i.length-o.installedCount} not installed`)),o.driftedCount===0&&(l(L.green(`
1099
1099
  \u2713 No drift detected.
1100
1100
  `)),process.exit(0)),t.fix||(l(L.dim(`
1101
1101
  Run with --fix to re-apply drifted features.
@@ -1103,104 +1103,104 @@ Run with --fix to re-apply drifted features.
1103
1103
  \u{1F527} Applying fixes...
1104
1104
  `));for(let s of o.driftedResults){if(!s.manifest.apply){l(L.yellow(` \u26A0\uFE0F ${s.manifest.name} has no apply() \u2014 skipping.`));continue}try{await s.manifest.apply(r)}catch(a){v(`Failed to fix ${s.manifest.name}: ${a}`)}}l(L.green(`
1105
1105
  \u2713 Doctor finished.
1106
- `))}catch(r){v(`${r instanceof Error?r.message:r}`),process.exit(1)}})};import Fe from"picocolors";S();P();import kr from"node:path";var Cp=/^[A-Z][A-Z0-9_]*$/,Ao=e=>{if(!Cp.test(e))throw new Error(`Invalid env var name "${e}". Use UPPER_SNAKE_CASE (e.g. SENTRY_DSN, NEXT_PUBLIC_API_URL).`)},ue=(e,t)=>t?e.startsWith("NEXT_PUBLIC_")?e:`NEXT_PUBLIC_${e}`:e,Ep=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,"\\'")}')`}},Tp=e=>{switch(e.type){case"url":return"z.url()";case"number":return"z.coerce.number()";case"boolean":return"z.coerce.boolean()";case"enum":{let t=e.enumValues??[];if(t.length===0)throw new Error(`Enum env var "${e.name}" requires --enum values.`);return`z.enum([${t.map(n=>`'${n.replace(/'/g,"\\'")}'`).join(", ")}])`}default:return"z.string()"}},_o=e=>{let t=ue(e.name,e.public),n=Tp(e),i=e.default!==void 0,o=!e.required&&!i;i&&(n+=Ep(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+=`
1107
- .describe('${a}')`}return` ${t}: ${s},`},ko=/(export const envSchema\s*=\s*z\.object\(\{)([\s\S]*?)(\}\);?)/,Oo=(e,t)=>{let r=ue(t.name,t.public);if(new RegExp(`\\b${r}\\s*:`).test(e))return e;let i=e.match(ko);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+$/,""),u=p.length===0||/,\s*$/.test(p)?p:`${p},`,d=_o(t),h=`${u}
1106
+ `))}catch(r){v(`${r instanceof Error?r.message:r}`),process.exit(1)}})};import De from"picocolors";S();P();import Fr from"node:path";var Op=/^[A-Z][A-Z0-9_]*$/,Mo=e=>{if(!Op.test(e))throw new Error(`Invalid env var name "${e}". Use UPPER_SNAKE_CASE (e.g. SENTRY_DSN, NEXT_PUBLIC_API_URL).`)},ge=(e,t)=>t?e.startsWith("NEXT_PUBLIC_")?e:`NEXT_PUBLIC_${e}`:e,Fp=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,"\\'")}')`}},jp=e=>{switch(e.type){case"url":return"z.url()";case"number":return"z.coerce.number()";case"boolean":return"z.coerce.boolean()";case"enum":{let t=e.enumValues??[];if(t.length===0)throw new Error(`Enum env var "${e.name}" requires --enum values.`);return`z.enum([${t.map(n=>`'${n.replace(/'/g,"\\'")}'`).join(", ")}])`}default:return"z.string()"}},Go=e=>{let t=ge(e.name,e.public),n=jp(e),i=e.default!==void 0,o=!e.required&&!i;i&&(n+=Fp(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+=`
1107
+ .describe('${a}')`}return` ${t}: ${s},`},Lo=/(export const envSchema\s*=\s*z\.object\(\{)([\s\S]*?)(\}\);?)/,Uo=(e,t)=>{let r=ge(t.name,t.public);if(new RegExp(`\\b${r}\\s*:`).test(e))return e;let i=e.match(Lo);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+$/,""),u=p.length===0||/,\s*$/.test(p)?p:`${p},`,d=Go(t),h=`${u}
1108
1108
  ${d}
1109
- `;return e.replace(ko,`${o}${h}${a}`)},bp="# -public",Rp=e=>{let t=ue(e.name,e.public),r=e.default??"",n=e.public?` ${bp}`:"";return`${t}=${r}${n}`},Fo=(e,t)=>{let r=ue(t.name,t.public);if(new RegExp(`^${r}=`,"m").test(e))return e;let i=e===""||e.endsWith(`
1109
+ `;return e.replace(Lo,`${o}${h}${a}`)},Dp="# -public",Lp=e=>{let t=ge(e.name,e.public),r=e.default??"",n=e.public?` ${Dp}`:"";return`${t}=${r}${n}`},Ho=(e,t)=>{let r=ge(t.name,t.public);if(new RegExp(`^${r}=`,"m").test(e))return e;let i=e===""||e.endsWith(`
1110
1110
  `)?"":`
1111
1111
  `,o=e===""?"":`
1112
1112
  `,s=t.description?`# ${t.description}
1113
- `:"";return`${e}${i}${o}${s}${Rp(t)}
1114
- `},jo=(e,t)=>{let r=ue(t.name,t.public);if(new RegExp(`^${r}=`,"m").test(e))return e;let i=e===""||e.endsWith(`
1113
+ `:"";return`${e}${i}${o}${s}${Lp(t)}
1114
+ `},Bo=(e,t)=>{let r=ge(t.name,t.public);if(new RegExp(`^${r}=`,"m").test(e))return e;let i=e===""||e.endsWith(`
1115
1115
  `)?"":`
1116
1116
  `,o=t.default??"";return`${e}${i}${r}=${o}
1117
- `},Ar=async(e,t)=>{Ao(t.name);let r=kr.join(e,"src/lib/env/schema.ts");if(!m(r))throw new Error("src/lib/env/schema.ts not found \u2014 run `next-maker init` first.");let n=await f(r),i=Oo(n,t),o=i!==n;o&&await g(r,i);let s=kr.join(e,c.ENV_EXAMPLE),a=!1;if(m(s)){let d=await f(s),h=Fo(d,t);a=h!==d,a&&await g(s,h)}let p=kr.join(e,".env"),u=!1;if(m(p)){let d=await f(p),h=jo(d,t);u=h!==d,u&&await g(p,h)}return{schemaUpdated:o,envExampleUpdated:a,envUpdated:u}};var Do=new Set(["string","url","number","boolean","enum"]),$p=e=>{let t=(e??"string").toLowerCase();if(!Do.has(t))throw new Error(`Invalid --type "${e}". Valid: ${Array.from(Do).join(", ")}.`);return t},Ip=e=>{if(!e)return;let t=e.split(",").map(r=>r.trim()).filter(Boolean);return t.length===0?void 0:t},Lo=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(t,r)=>{try{let n=process.cwd();if(l(Fe.cyan(`
1117
+ `},jr=async(e,t)=>{Mo(t.name);let r=Fr.join(e,"src/lib/env/schema.ts");if(!m(r))throw new Error("src/lib/env/schema.ts not found \u2014 run `next-maker init` first.");let n=await f(r),i=Uo(n,t),o=i!==n;o&&await g(r,i);let s=Fr.join(e,c.ENV_EXAMPLE),a=!1;if(m(s)){let d=await f(s),h=Ho(d,t);a=h!==d,a&&await g(s,h)}let p=Fr.join(e,".env"),u=!1;if(m(p)){let d=await f(p),h=Bo(d,t);u=h!==d,u&&await g(p,h)}return{schemaUpdated:o,envExampleUpdated:a,envUpdated:u}};var zo=new Set(["string","url","number","boolean","enum"]),Mp=e=>{let t=(e??"string").toLowerCase();if(!zo.has(t))throw new Error(`Invalid --type "${e}". Valid: ${Array.from(zo).join(", ")}.`);return t},Gp=e=>{if(!e)return;let t=e.split(",").map(r=>r.trim()).filter(Boolean);return t.length===0?void 0:t},Jo=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(t,r)=>{try{let n=process.cwd();if(l(De.cyan(`
1118
1118
  \u{1F510} Env Var Generator
1119
- `)),r.required&&r.default!==void 0)throw new Error("--required and --default are mutually exclusive.");let i=$p(r.type),o=Ip(r.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:t,type:i,required:!!r.required,default:r.default,description:r.describe,enumValues:o,public:!!r.public};y.start("Updating schema, .env.example, and .env...");let a=await Ar(n,s);y.succeed("Env var written");let p=ue(s.name,s.public);l(Fe.green(`
1119
+ `)),r.required&&r.default!==void 0)throw new Error("--required and --default are mutually exclusive.");let i=Mp(r.type),o=Gp(r.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:t,type:i,required:!!r.required,default:r.default,description:r.describe,enumValues:o,public:!!r.public};y.start("Updating schema, .env.example, and .env...");let a=await jr(n,s);y.succeed("Env var written");let p=ge(s.name,s.public);l(De.green(`
1120
1120
  \u2728 ${p} declared.
1121
- `)),l(Fe.dim("Touched:")),l(Fe.dim(` ${a.schemaUpdated?"\u270F\uFE0F ":"\u23ED "} src/lib/env/schema.ts`)),l(Fe.dim(` ${a.envExampleUpdated?"\u270F\uFE0F ":"\u23ED "} .env.example`)),l(Fe.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 Lt from"node:path";import Te from"picocolors";import Np from"enquirer";var{prompt:kp}=Np,Mo=async(e={})=>e.source?{source:e.source}:{source:(await kp({type:"input",name:"source",message:"Path to source image (PNG/JPG/JPEG/SVG/WebP/AVIF):",validate:r=>r?!0:"Source path is required"})).source};import{access as Ap,readFile as _p,stat as Op}from"node:fs/promises";import Ee from"node:path";var Go=async e=>{try{return await Ap(e),!0}catch{return!1}},Fp=async e=>{try{return(await Op(e)).isDirectory()}catch{return!1}},jt=async e=>{let t=[Ee.join(e,"src","app"),Ee.join(e,"app")];for(let r of t)if(await Fp(r))return r;return null},jp=["next-pwa","@ducanh2912/next-pwa","@serwist/next","serwist"],_r=async e=>{let t={isPwa:!1},r=[Ee.join(e,"public","manifest.json"),Ee.join(e,"public","manifest.webmanifest"),Ee.join(e,"public","site.webmanifest")];for(let i of r)if(await Go(i)){t.publicManifestPath=i,t.isPwa=!0;break}let n=await jt(e);if(n)for(let i of["ts","tsx","js"]){let o=Ee.join(n,`manifest.${i}`);if(await Go(o)){t.appManifestPath=o,t.isPwa=!0;break}}try{let i=JSON.parse(await _p(Ee.join(e,"package.json"),"utf-8")),o={...i.dependencies,...i.devDependencies};for(let s of jp)if(o[s]){t.framework=s,t.isPwa=!0;break}}catch{}return t};import{mkdir as Hp,readFile as Yo,stat as Up,writeFile as Bp}from"node:fs/promises";import re from"node:path";import zp from"sharp";import Lp from"png-to-ico";import yt from"sharp";var Ho=e=>e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;"),Or=(e,t,r)=>{switch(e){case"square":return`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}"><rect width="${t}" height="${t}" fill="white"/></svg>`;case"circle":{let n=t/2;return`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}"><circle cx="${n}" cy="${n}" r="${n}" fill="white"/></svg>`}case"rounded":{let n=Math.round(t*r/100);return`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}"><rect width="${t}" height="${t}" rx="${n}" ry="${n}" fill="white"/></svg>`}case"squircle":return Dp(t)}},Dp=e=>{let t=e,r=t*.225,n=[`M 0 ${r}`,`C 0 0 0 0 ${r} 0`,`L ${t-r} 0`,`C ${t} 0 ${t} 0 ${t} ${r}`,`L ${t} ${t-r}`,`C ${t} ${t} ${t} ${t} ${t-r} ${t}`,`L ${r} ${t}`,`C 0 ${t} 0 ${t} 0 ${t-r}`,"Z"].join(" ");return`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}"><path d="${Ho(n)}" fill="white"/></svg>`},Uo=(e,t)=>`<svg xmlns="http://www.w3.org/2000/svg" width="${e}" height="${e}"><rect width="${e}" height="${e}" fill="${Ho(t)}"/></svg>`;var je=async e=>{let{size:t,paddingPercent:r,bg:n,fit:i,shape:o,radiusPercent:s,quality:a,forceSquare:p,sourceBuffer:u}=e,d=Math.max(1,Math.round(t*(1-r*2/100))),h=i==="cover"?"cover":"contain",x=await yt(u,{density:384}).resize(d,d,{fit:h,background:{r:0,g:0,b:0,alpha:0}}).png().toBuffer(),$=Math.round((t-d)/2),J=n==="transparent"?{r:0,g:0,b:0,alpha:0}:await Fr(n),I=await yt({create:{width:t,height:t,channels:4,background:J}}).composite([{input:x,left:$,top:$}]).png().toBuffer();if(!p&&(o!=="square"||i==="clip")){let he=o==="square"?"rounded":o,bs=Buffer.from(Or(he,t,s));I=await yt(I).composite([{input:bs,blend:"dest-in"}]).png({compressionLevel:Bo(a)}).toBuffer()}else I=await yt(I).png({compressionLevel:Bo(a)}).toBuffer();return I},Fr=async e=>{let t=await yt(Buffer.from(Uo(1,e))).raw().toBuffer({resolveWithObject:!0}),[r,n,i,o=255]=t.data;return{r,g:n,b:i,alpha:o/255}},Bo=e=>{let t=Math.round((100-e)/100*9);return Math.max(0,Math.min(9,t))},zo=async e=>{if(e.length===0)throw new Error("No frames provided to encodeIco");return Lp(e)};import{readFile as Mp,writeFile as Fw}from"node:fs/promises";var Jo=e=>e.map(({src:t,size:r})=>({src:t,sizes:`${r}x${r}`,type:"image/png",purpose:"any maskable"})),Vo=async(e,t)=>{let r=await Mp(e,"utf-8"),n=JSON.parse(r),i=Array.isArray(n.icons)?n.icons:[],o=new Map;for(let s of[...i,...t])s&&typeof s.src=="string"&&o.set(s.src,s);return n.icons=[...o.values()],`${JSON.stringify(n,null,2)}
1122
- `};var Wo=e=>`icons: [
1121
+ `)),l(De.dim("Touched:")),l(De.dim(` ${a.schemaUpdated?"\u270F\uFE0F ":"\u23ED "} src/lib/env/schema.ts`)),l(De.dim(` ${a.envExampleUpdated?"\u270F\uFE0F ":"\u23ED "} .env.example`)),l(De.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 Ht from"node:path";import Re from"picocolors";import Up from"enquirer";var{prompt:Hp}=Up,Vo=async(e={})=>e.source?{source:e.source}:{source:(await Hp({type:"input",name:"source",message:"Path to source image (PNG/JPG/JPEG/SVG/WebP/AVIF):",validate:r=>r?!0:"Source path is required"})).source};import{access as Bp,readFile as zp,stat as Jp}from"node:fs/promises";import be from"node:path";var Wo=async e=>{try{return await Bp(e),!0}catch{return!1}},Vp=async e=>{try{return(await Jp(e)).isDirectory()}catch{return!1}},Gt=async e=>{let t=[be.join(e,"src","app"),be.join(e,"app")];for(let r of t)if(await Vp(r))return r;return null},Wp=["next-pwa","@ducanh2912/next-pwa","@serwist/next","serwist"],Dr=async e=>{let t={isPwa:!1},r=[be.join(e,"public","manifest.json"),be.join(e,"public","manifest.webmanifest"),be.join(e,"public","site.webmanifest")];for(let i of r)if(await Wo(i)){t.publicManifestPath=i,t.isPwa=!0;break}let n=await Gt(e);if(n)for(let i of["ts","tsx","js"]){let o=be.join(n,`manifest.${i}`);if(await Wo(o)){t.appManifestPath=o,t.isPwa=!0;break}}try{let i=JSON.parse(await zp(be.join(e,"package.json"),"utf-8")),o={...i.dependencies,...i.devDependencies};for(let s of Wp)if(o[s]){t.framework=s,t.isPwa=!0;break}}catch{}return t};import{mkdir as Zp,readFile as ns,stat as Qp,writeFile as el}from"node:fs/promises";import ie from"node:path";import tl from"sharp";import Xp from"png-to-ico";import Pt from"sharp";var qo=e=>e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;"),Lr=(e,t,r)=>{switch(e){case"square":return`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}"><rect width="${t}" height="${t}" fill="white"/></svg>`;case"circle":{let n=t/2;return`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}"><circle cx="${n}" cy="${n}" r="${n}" fill="white"/></svg>`}case"rounded":{let n=Math.round(t*r/100);return`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}"><rect width="${t}" height="${t}" rx="${n}" ry="${n}" fill="white"/></svg>`}case"squircle":return qp(t)}},qp=e=>{let t=e,r=t*.225,n=[`M 0 ${r}`,`C 0 0 0 0 ${r} 0`,`L ${t-r} 0`,`C ${t} 0 ${t} 0 ${t} ${r}`,`L ${t} ${t-r}`,`C ${t} ${t} ${t} ${t} ${t-r} ${t}`,`L ${r} ${t}`,`C 0 ${t} 0 ${t} 0 ${t-r}`,"Z"].join(" ");return`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}"><path d="${qo(n)}" fill="white"/></svg>`},Xo=(e,t)=>`<svg xmlns="http://www.w3.org/2000/svg" width="${e}" height="${e}"><rect width="${e}" height="${e}" fill="${qo(t)}"/></svg>`;var Le=async e=>{let{size:t,paddingPercent:r,bg:n,fit:i,shape:o,radiusPercent:s,quality:a,forceSquare:p,sourceBuffer:u}=e,d=Math.max(1,Math.round(t*(1-r*2/100))),h=i==="cover"?"cover":"contain",x=await Pt(u,{density:384}).resize(d,d,{fit:h,background:{r:0,g:0,b:0,alpha:0}}).png().toBuffer(),$=Math.round((t-d)/2),V=n==="transparent"?{r:0,g:0,b:0,alpha:0}:await Mr(n),I=await Pt({create:{width:t,height:t,channels:4,background:V}}).composite([{input:x,left:$,top:$}]).png().toBuffer();if(!p&&(o!=="square"||i==="clip")){let xe=o==="square"?"rounded":o,Os=Buffer.from(Lr(xe,t,s));I=await Pt(I).composite([{input:Os,blend:"dest-in"}]).png({compressionLevel:Yo(a)}).toBuffer()}else I=await Pt(I).png({compressionLevel:Yo(a)}).toBuffer();return I},Mr=async e=>{let t=await Pt(Buffer.from(Xo(1,e))).raw().toBuffer({resolveWithObject:!0}),[r,n,i,o=255]=t.data;return{r,g:n,b:i,alpha:o/255}},Yo=e=>{let t=Math.round((100-e)/100*9);return Math.max(0,Math.min(9,t))},Ko=async e=>{if(e.length===0)throw new Error("No frames provided to encodeIco");return Xp(e)};import{readFile as Yp,writeFile as Xw}from"node:fs/promises";var Zo=e=>e.map(({src:t,size:r})=>({src:t,sizes:`${r}x${r}`,type:"image/png",purpose:"any maskable"})),Qo=async(e,t)=>{let r=await Yp(e,"utf-8"),n=JSON.parse(r),i=Array.isArray(n.icons)?n.icons:[],o=new Map;for(let s of[...i,...t])s&&typeof s.src=="string"&&o.set(s.src,s);return n.icons=[...o.values()],`${JSON.stringify(n,null,2)}
1122
+ `};var es=e=>`icons: [
1123
1123
  ${e.map(r=>` { src: '${r.src}', sizes: '${r.sizes}', type: '${r.type}'${r.purpose?`, purpose: '${r.purpose}'`:""} }`).join(`,
1124
1124
  `)},
1125
- ],`,qo=(e,t,r)=>`${JSON.stringify({name:e,short_name:e,start_url:"/",display:"standalone",background_color:"#ffffff",theme_color:t,icons:r},null,2)}
1126
- `;import{stat as Gp}from"node:fs/promises";import jr from"node:path";var Xo=[".png",".jpg",".jpeg",".webp",".svg",".avif"],Dt=async e=>{if(!e)throw new Error("Source image path is required (use --path).");let t=jr.isAbsolute(e)?e:jr.resolve(process.cwd(),e),r;try{r=await Gp(t)}catch{throw new Error(`Source image not found: ${t}`)}if(!r.isFile())throw new Error(`Source is not a file: ${t}`);let n=jr.extname(t).toLowerCase();if(!Xo.includes(n))throw new Error(`Unsupported source format '${n}'. Use one of: ${Xo.join(", ")}`);return{absolutePath:t,ext:n,bytes:r.size,isVector:n===".svg"}};var Dr=(e,t)=>{if(!e)return t;let r=e.split(",").map(n=>Number.parseInt(n.trim(),10)).filter(n=>Number.isFinite(n)&&n>0&&n<=1024);if(r.length===0)throw new Error(`Invalid --sizes value: '${e}'. Provide comma-separated positive integers.`);return r};var Jp=async e=>{try{return await Up(e),!0}catch{return!1}},Vp=async(e,t,r)=>{let n=[];for(let i of e){if(await Jp(i.outPath)&&!t&&!i.alwaysWrite){n.push({path:i.outPath,bytes:i.bytes.length,skipped:!0});continue}r||(await Hp(re.dirname(i.outPath),{recursive:!0}),await Bp(i.outPath,i.bytes)),n.push({path:i.outPath,bytes:i.bytes.length})}return n},Lr=async(e,t)=>{let r=await Dt(t.source),n=await Yo(r.absolutePath),i=t.ogSource?await Yo((await Dt(t.ogSource)).absolutePath):n,o=[],s=[];for(let d of t.icoSizes)s.push(await je({sourceBuffer:n,size:d,shape:"square",radiusPercent:t.radius,bg:t.bg,paddingPercent:t.padding,fit:t.fit,quality:t.quality,forceSquare:!0}));let a=await zo(s);if(o.push({outPath:re.join(t.outDir,"favicon.ico"),bytes:a}),t.emitIcon){let d=await je({sourceBuffer:n,size:512,shape:t.shape,radiusPercent:t.radius,bg:t.bg,paddingPercent:t.padding,fit:t.fit,quality:t.quality});o.push({outPath:re.join(t.outDir,"icon.png"),bytes:d})}if(t.emitApple){let d=t.bg==="transparent"?"#ffffff":t.bg,h=await je({sourceBuffer:n,size:180,shape:t.shape,radiusPercent:t.radius,bg:d,paddingPercent:t.padding,fit:t.fit,quality:t.quality});o.push({outPath:re.join(t.outDir,"apple-icon.png"),bytes:h})}if(t.emitOg){let d=await Ko(i,t,!1);o.push({outPath:re.join(t.outDir,"opengraph-image.png"),bytes:d})}if(t.emitTwitter){let d=await Ko(i,t,!0);o.push({outPath:re.join(t.outDir,"twitter-image.png"),bytes:d})}let p;if(t.pwa||t.pwaInit){let d=await _r(e);if(t.pwa&&!d.isPwa)throw new Error("No PWA setup detected. Use --pwa-init to bootstrap a manifest, or set up next-pwa/serwist first.");let h=re.join(e,"public"),x=[192,512],$=[];for(let I of x){let V=await je({sourceBuffer:n,size:I,shape:t.shape,radiusPercent:t.radius,bg:t.bg,paddingPercent:t.padding,fit:t.fit,quality:t.quality}),he=`icon-${I}.png`;o.push({outPath:re.join(h,he),bytes:V}),$.push({src:`/${he}`,size:I})}let J=Jo($);if(d.publicManifestPath){let I=await Vo(d.publicManifestPath,J);o.push({outPath:d.publicManifestPath,bytes:Buffer.from(I,"utf-8"),alwaysWrite:!0})}else if(d.appManifestPath)p=Wo(J);else if(t.pwaInit){let I=re.join(h,"manifest.webmanifest"),V=qo(re.basename(e)||"App","#000000",J);o.push({outPath:I,bytes:Buffer.from(V,"utf-8")})}}return{outputs:await Vp(o,t.force,t.dryRun),pwaSnippet:p}},Ko=async(e,t,r)=>{let i=r?600:630,o=Math.round(Math.min(1200,i)*(1-t.padding*2/100)),s=await je({sourceBuffer:e,size:o,shape:t.shape,radiusPercent:t.radius,bg:"transparent",paddingPercent:0,fit:t.fit,quality:t.quality}),a=t.bg==="transparent"?"#ffffff":t.bg,p=await Fr(a),u=Math.round((1200-o)/2),d=Math.round((i-o)/2);return zp({create:{width:1200,height:i,channels:4,background:p}}).composite([{input:s,left:u,top:d}]).png().toBuffer()};var Zo=new Set(["aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkgrey","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","green","greenyellow","grey","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightgrey","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen"]);var Wp=["square","rounded","circle","squircle"],qp=["contain","cover","clip"],Qo=(e,t,r,n)=>{if(!e)return r;if(!t.includes(e))throw new Error(`Invalid value for --${n}: '${e}'. Allowed: ${t.join(", ")}`);return e},Mr=(e,t,r,n,i)=>{if(e===void 0)return t;let o=Number(e);if(!Number.isFinite(o)||o<n||o>i)throw new Error(`Invalid value for --${r}: '${e}'. Must be a number between ${n}\u2013${i}.`);return o},ts=e=>{e.command("favicon").description("Generate favicon.ico (and optionally icons, OG image, PWA manifest icons)").option("--path <file>","Path to source image (PNG, JPG, JPEG, WebP, SVG, AVIF)").option("--out <dir>","Output dir (default: src/app or app)").option("--force","Overwrite existing files without prompt",!1).option("--dry-run","Show what would be written without writing",!1).option("--icon","Also emit icon.png (512\xD7512)",!1).option("--apple","Also emit apple-icon.png (180\xD7180)",!1).option("--og","Also emit opengraph-image.png (1200\xD7630)",!1).option("--og-source <file>","Use a separate image for the OG/Twitter card").option("--twitter","Also emit twitter-image.png (1200\xD7600)",!1).option("--all","Shorthand for --icon --apple --og",!1).option("--pwa","Detect PWA setup and emit manifest icons (192/512); errors if not detected",!1).option("--pwa-init","Bootstrap public/manifest.webmanifest with icons",!1).option("--shape <shape>","square | rounded | circle | squircle","square").option("--radius <percent>","Corner radius % when shape=rounded (0-50)","20").option("--bg <color>",'Background color (hex, css name, or "transparent")',"transparent").option("--padding <percent>","Padding around source content (0-30)","0").option("--fit <fit>","How source fits target: contain | cover | clip","contain").option("--sizes <list>","Comma-separated ICO sizes (default: 16,32,48)").option("--quality <n>","PNG compression 1-100 (higher = smaller file; PNG is lossless, default: 90)","90").action(async t=>{try{let r=process.cwd();l(Te.cyan(`
1125
+ ],`,ts=(e,t,r)=>`${JSON.stringify({name:e,short_name:e,start_url:"/",display:"standalone",background_color:"#ffffff",theme_color:t,icons:r},null,2)}
1126
+ `;import{stat as Kp}from"node:fs/promises";import Gr from"node:path";var rs=[".png",".jpg",".jpeg",".webp",".svg",".avif"],Ut=async e=>{if(!e)throw new Error("Source image path is required (use --path).");let t=Gr.isAbsolute(e)?e:Gr.resolve(process.cwd(),e),r;try{r=await Kp(t)}catch{throw new Error(`Source image not found: ${t}`)}if(!r.isFile())throw new Error(`Source is not a file: ${t}`);let n=Gr.extname(t).toLowerCase();if(!rs.includes(n))throw new Error(`Unsupported source format '${n}'. Use one of: ${rs.join(", ")}`);return{absolutePath:t,ext:n,bytes:r.size,isVector:n===".svg"}};var Ur=(e,t)=>{if(!e)return t;let r=e.split(",").map(n=>Number.parseInt(n.trim(),10)).filter(n=>Number.isFinite(n)&&n>0&&n<=1024);if(r.length===0)throw new Error(`Invalid --sizes value: '${e}'. Provide comma-separated positive integers.`);return r};var rl=async e=>{try{return await Qp(e),!0}catch{return!1}},nl=async(e,t,r)=>{let n=[];for(let i of e){if(await rl(i.outPath)&&!t&&!i.alwaysWrite){n.push({path:i.outPath,bytes:i.bytes.length,skipped:!0});continue}r||(await Zp(ie.dirname(i.outPath),{recursive:!0}),await el(i.outPath,i.bytes)),n.push({path:i.outPath,bytes:i.bytes.length})}return n},Hr=async(e,t)=>{let r=await Ut(t.source),n=await ns(r.absolutePath),i=t.ogSource?await ns((await Ut(t.ogSource)).absolutePath):n,o=[],s=[];for(let d of t.icoSizes)s.push(await Le({sourceBuffer:n,size:d,shape:"square",radiusPercent:t.radius,bg:t.bg,paddingPercent:t.padding,fit:t.fit,quality:t.quality,forceSquare:!0}));let a=await Ko(s);if(o.push({outPath:ie.join(t.outDir,"favicon.ico"),bytes:a}),t.emitIcon){let d=await Le({sourceBuffer:n,size:512,shape:t.shape,radiusPercent:t.radius,bg:t.bg,paddingPercent:t.padding,fit:t.fit,quality:t.quality});o.push({outPath:ie.join(t.outDir,"icon.png"),bytes:d})}if(t.emitApple){let d=t.bg==="transparent"?"#ffffff":t.bg,h=await Le({sourceBuffer:n,size:180,shape:t.shape,radiusPercent:t.radius,bg:d,paddingPercent:t.padding,fit:t.fit,quality:t.quality});o.push({outPath:ie.join(t.outDir,"apple-icon.png"),bytes:h})}if(t.emitOg){let d=await is(i,t,!1);o.push({outPath:ie.join(t.outDir,"opengraph-image.png"),bytes:d})}if(t.emitTwitter){let d=await is(i,t,!0);o.push({outPath:ie.join(t.outDir,"twitter-image.png"),bytes:d})}let p;if(t.pwa||t.pwaInit){let d=await Dr(e);if(t.pwa&&!d.isPwa)throw new Error("No PWA setup detected. Use --pwa-init to bootstrap a manifest, or set up next-pwa/serwist first.");let h=ie.join(e,"public"),x=[192,512],$=[];for(let I of x){let W=await Le({sourceBuffer:n,size:I,shape:t.shape,radiusPercent:t.radius,bg:t.bg,paddingPercent:t.padding,fit:t.fit,quality:t.quality}),xe=`icon-${I}.png`;o.push({outPath:ie.join(h,xe),bytes:W}),$.push({src:`/${xe}`,size:I})}let V=Zo($);if(d.publicManifestPath){let I=await Qo(d.publicManifestPath,V);o.push({outPath:d.publicManifestPath,bytes:Buffer.from(I,"utf-8"),alwaysWrite:!0})}else if(d.appManifestPath)p=es(V);else if(t.pwaInit){let I=ie.join(h,"manifest.webmanifest"),W=ts(ie.basename(e)||"App","#000000",V);o.push({outPath:I,bytes:Buffer.from(W,"utf-8")})}}return{outputs:await nl(o,t.force,t.dryRun),pwaSnippet:p}},is=async(e,t,r)=>{let i=r?600:630,o=Math.round(Math.min(1200,i)*(1-t.padding*2/100)),s=await Le({sourceBuffer:e,size:o,shape:t.shape,radiusPercent:t.radius,bg:"transparent",paddingPercent:0,fit:t.fit,quality:t.quality}),a=t.bg==="transparent"?"#ffffff":t.bg,p=await Mr(a),u=Math.round((1200-o)/2),d=Math.round((i-o)/2);return tl({create:{width:1200,height:i,channels:4,background:p}}).composite([{input:s,left:u,top:d}]).png().toBuffer()};var os=new Set(["aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkgrey","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","green","greenyellow","grey","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightgrey","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen"]);var il=["square","rounded","circle","squircle"],ol=["contain","cover","clip"],ss=(e,t,r,n)=>{if(!e)return r;if(!t.includes(e))throw new Error(`Invalid value for --${n}: '${e}'. Allowed: ${t.join(", ")}`);return e},Br=(e,t,r,n,i)=>{if(e===void 0)return t;let o=Number(e);if(!Number.isFinite(o)||o<n||o>i)throw new Error(`Invalid value for --${r}: '${e}'. Must be a number between ${n}\u2013${i}.`);return o},cs=e=>{e.command("favicon").description("Generate favicon.ico (and optionally icons, OG image, PWA manifest icons)").option("--path <file>","Path to source image (PNG, JPG, JPEG, WebP, SVG, AVIF)").option("--out <dir>","Output dir (default: src/app or app)").option("--force","Overwrite existing files without prompt",!1).option("--dry-run","Show what would be written without writing",!1).option("--icon","Also emit icon.png (512\xD7512)",!1).option("--apple","Also emit apple-icon.png (180\xD7180)",!1).option("--og","Also emit opengraph-image.png (1200\xD7630)",!1).option("--og-source <file>","Use a separate image for the OG/Twitter card").option("--twitter","Also emit twitter-image.png (1200\xD7600)",!1).option("--all","Shorthand for --icon --apple --og",!1).option("--pwa","Detect PWA setup and emit manifest icons (192/512); errors if not detected",!1).option("--pwa-init","Bootstrap public/manifest.webmanifest with icons",!1).option("--shape <shape>","square | rounded | circle | squircle","square").option("--radius <percent>","Corner radius % when shape=rounded (0-50)","20").option("--bg <color>",'Background color (hex, css name, or "transparent")',"transparent").option("--padding <percent>","Padding around source content (0-30)","0").option("--fit <fit>","How source fits target: contain | cover | clip","contain").option("--sizes <list>","Comma-separated ICO sizes (default: 16,32,48)").option("--quality <n>","PNG compression 1-100 (higher = smaller file; PNG is lossless, default: 90)","90").action(async t=>{try{let r=process.cwd();l(Re.cyan(`
1127
1127
  \u{1F3A8} Favicon Generator
1128
- `));let n=await Mo({source:t.path}),i=await Xp(r,t.out),o=Qo(t.shape,Wp,"square","shape"),s=Qo(t.fit,qp,"contain","fit"),a=Mr(t.radius,20,"radius",0,50),p=Mr(t.padding,0,"padding",0,30),u=Mr(t.quality,90,"quality",1,100),d=Dr(t.sizes,[16,32,48]),h=t.bg??"transparent";Zp(h);let x=t.all===!0,$={source:n.source,outDir:i,force:!!t.force,dryRun:!!t.dryRun,emitIcon:!!t.icon||x,emitApple:!!t.apple||x,emitOg:!!t.og||x,emitTwitter:!!t.twitter,ogSource:t.ogSource,pwa:!!t.pwa,pwaInit:!!t.pwaInit,shape:o,radius:a,bg:h,padding:p,fit:s,icoSizes:d,quality:u};y.start("Generating favicon assets...");let J=await Lr(r,$);y.succeed($.dryRun?"Favicon plan ready":"Favicon assets generated"),l("");for(let I of J.outputs){let V=Lt.relative(r,I.path);I.skipped?l(Te.yellow(` \u21B7 skipped ${V} (exists; use --force to overwrite)`)):$.dryRun?l(Te.dim(` \u{1F4C4} would write ${V} (${es(I.bytes)})`)):l(Te.green(` \u2713 ${V} `)+Te.dim(`(${es(I.bytes)})`))}J.pwaSnippet&&(l(""),l(Te.cyan("Add this to your typed manifest (src/app/manifest.ts):")),l(Te.dim(J.pwaSnippet))),l("")}catch(r){y.fail("Favicon generation failed");let n=r instanceof Error?r.message:String(r);v(n),process.exit(1)}})},Xp=async(e,t)=>{if(t)return Lt.isAbsolute(t)?t:Lt.resolve(e,t);let r=await jt(e);return r||(Zr("Could not detect app/ or src/app/ \u2014 falling back to src/app"),Lt.join(e,"src","app"))},Yp=/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/,Kp=/^(?:rgb|rgba|hsl|hsla)\(\s*[\d.,%\s/]+\)$/i,Zp=e=>{if(e!=="transparent"&&!Yp.test(e)&&!Kp.test(e)&&!Zo.has(e.toLowerCase()))throw new Error(`Invalid value for --bg: '${e}'. Use 'transparent', a hex code (e.g. #0f172a), a CSS color name, or rgb()/rgba()/hsl()/hsla().`)},es=e=>e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(2)} MB`;import Vr from"node:path";import M from"picocolors";H();H();import dl from"node:path";import{readFile as Qp,writeFile as el}from"node:fs/promises";import tl from"node:path";var xt=async e=>{let{serviceName:t,projectPath:r}=e,n=j(t),i=tl.join(r,"src","lib","config","app-apis.ts");try{let o=await Qp(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}: {
1128
+ `));let n=await Vo({source:t.path}),i=await sl(r,t.out),o=ss(t.shape,il,"square","shape"),s=ss(t.fit,ol,"contain","fit"),a=Br(t.radius,20,"radius",0,50),p=Br(t.padding,0,"padding",0,30),u=Br(t.quality,90,"quality",1,100),d=Ur(t.sizes,[16,32,48]),h=t.bg??"transparent";pl(h);let x=t.all===!0,$={source:n.source,outDir:i,force:!!t.force,dryRun:!!t.dryRun,emitIcon:!!t.icon||x,emitApple:!!t.apple||x,emitOg:!!t.og||x,emitTwitter:!!t.twitter,ogSource:t.ogSource,pwa:!!t.pwa,pwaInit:!!t.pwaInit,shape:o,radius:a,bg:h,padding:p,fit:s,icoSizes:d,quality:u};y.start("Generating favicon assets...");let V=await Hr(r,$);y.succeed($.dryRun?"Favicon plan ready":"Favicon assets generated"),l("");for(let I of V.outputs){let W=Ht.relative(r,I.path);I.skipped?l(Re.yellow(` \u21B7 skipped ${W} (exists; use --force to overwrite)`)):$.dryRun?l(Re.dim(` \u{1F4C4} would write ${W} (${as(I.bytes)})`)):l(Re.green(` \u2713 ${W} `)+Re.dim(`(${as(I.bytes)})`))}V.pwaSnippet&&(l(""),l(Re.cyan("Add this to your typed manifest (src/app/manifest.ts):")),l(Re.dim(V.pwaSnippet))),l("")}catch(r){y.fail("Favicon generation failed");let n=r instanceof Error?r.message:String(r);v(n),process.exit(1)}})},sl=async(e,t)=>{if(t)return Ht.isAbsolute(t)?t:Ht.resolve(e,t);let r=await Gt(e);return r||(rn("Could not detect app/ or src/app/ \u2014 falling back to src/app"),Ht.join(e,"src","app"))},al=/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/,cl=/^(?:rgb|rgba|hsl|hsla)\(\s*[\d.,%\s/]+\)$/i,pl=e=>{if(e!=="transparent"&&!al.test(e)&&!cl.test(e)&&!os.has(e.toLowerCase()))throw new Error(`Invalid value for --bg: '${e}'. Use 'transparent', a hex code (e.g. #0f172a), a CSS color name, or rgb()/rgba()/hsl()/hsla().`)},as=e=>e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(2)} MB`;import us from"node:path";import M from"picocolors";H();H();import El from"node:path";import{readFile as ll,writeFile as ml}from"node:fs/promises";import dl from"node:path";var wt=async e=>{let{serviceName:t,projectPath:r}=e,n=j(t),i=dl.join(r,"src","lib","config","app-apis.ts");try{let o=await ll(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}: {
1129
1129
  base: '/${t}',
1130
1130
  getAll: '/${t}',
1131
- },`;o=ze(o,s),await el(i,o)}catch(o){throw new Error(`Failed to register API endpoints: ${o}`,{cause:o})}};import{readFile as rl,writeFile as nl}from"node:fs/promises";import il from"node:path";P();var Gr=async(e,t,r)=>{let n=il.join(e,"src","lib","config","app-paths.ts");if(!m(n))return;let i=await rl(n,"utf-8"),o=j(t);if(i.includes(`${o}:`))return;let s=i.lastIndexOf("} as const;");if(s===-1)return;let a=` ${o}: '${r}',
1132
- `;i=i.slice(0,s)+a+i.slice(s),await nl(n,i)};S();P();import Mt from"node:path";var ol=e=>new RegExp(`<\\s*${e}\\b`),rs=(e,t)=>{if(ol(t).test(e))return e;let r=/^(?<indent>[ \t]*)\{children\}\s*$/m,n=e.match(r);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}<${t}>
1131
+ },`;o=Ve(o,s),await ml(i,o)}catch(o){throw new Error(`Failed to register API endpoints: ${o}`,{cause:o})}};import{readFile as ul,writeFile as fl}from"node:fs/promises";import gl from"node:path";P();var zr=async(e,t,r)=>{let n=gl.join(e,"src","lib","config","app-paths.ts");if(!m(n))return;let i=await ul(n,"utf-8"),o=j(t);if(i.includes(`${o}:`))return;let s=i.lastIndexOf("} as const;");if(s===-1)return;let a=` ${o}: '${r}',
1132
+ `;i=i.slice(0,s)+a+i.slice(s),await fl(n,i)};S();P();import Bt from"node:path";var hl=e=>new RegExp(`<\\s*${e}\\b`),ps=(e,t)=>{if(hl(t).test(e))return e;let r=/^(?<indent>[ \t]*)\{children\}\s*$/m,n=e.match(r);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}<${t}>
1133
1133
  ${o}{children}
1134
- ${i}</${t}>`;return e.replace(r,s)},ns=(e,t)=>{let r=`export * from './${t}';`;if(e.includes(r))return e;let n=e.split(`
1134
+ ${i}</${t}>`;return e.replace(r,s)},ls=(e,t)=>{let r=`export * from './${t}';`;if(e.includes(r))return e;let n=e.split(`
1135
1135
  `),i=[],o=[];for(let h of n)/^export \* from '\.\/.*';\s*$/.test(h)?i.push(h):o.push(h);let s=[...i,r].sort(),a=n.findIndex(h=>/^export \* from '\.\//.test(h));if(a===-1)return`${r}
1136
1136
  ${e.replace(/^\n+/,"")}`;let p=n.slice(0,a),u=n.findIndex((h,x)=>x>a&&!/^export \* from '\.\//.test(h)),d=u===-1?[]:n.slice(u);return[...p,...s,...d].join(`
1137
- `)},sl=c.PROVIDERS,al=c.ROOT_PROVIDER,cl=c.PROVIDERS_INDEX,is=async(e,t={fileExists:m,readFile:f})=>{let r=Mt.join(e,al);if(t.fileExists(r))return r;let n=Mt.join(e,sl);if(!t.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 u=Mt.join(n,p),d=await t.readFile(u);if(!/\{children\}/.test(d))continue;let x=((d.split("{children}")[0]??"").match(/<[A-Z][A-Za-z0-9_]*\b/g)??[]).length;(!a||x>a.depth)&&(a={file:u,depth:x})}return a?.file??null},Hr=async e=>{let{projectPath:t,componentName:r,fileBaseName:n}=e,i=await is(t);if(i){let a=await f(i),p=a;(!/from '\.\//.test(a)||!a.includes(`{ ${r} }`))&&(p=Be(p,`import { ${r} } from './${n}';`)),p=rs(p,r),p!==a&&await g(i,p)}let o=Mt.join(t,cl),s=null;if(m(o)){let a=await f(o),p=ns(a,n);p!==a&&await g(o,p),s=o}return{rootProviderFile:i,barrelFile:s}};P();import{readFile as pl,writeFile as ll}from"node:fs/promises";import ml from"node:path";var Ur=async(e,t)=>{let r=ml.join(e,"src","i18n","translations","en.json");if(!m(r))return;let n=await pl(r,"utf-8"),i=JSON.parse(n);i[t]||(i[t]={title:t,description:`${t} page description`},await ll(r,`${JSON.stringify(i,null,2)}
1138
- `))};var Br=()=>[{name:"Project setup detected",spinnerText:"Detecting project setup...",execute:async e=>{e.detection=await F(e.projectPath)}},{name:"Feature files generated",spinnerText:"Generating feature files...",execute:async e=>{await ar({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 xt({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 we({projectPath:e.projectPath,name:e.featureName,persist:e.persistStore,importPath:dl.join(e.basePath,e.featureName,"store")})}}];var be=async(e,t)=>{for(let r of e)if(!r.shouldSkip?.(t)){t.spinner.start(r.spinnerText);try{await r.execute(t),t.spinner.succeed(r.name)}catch(n){throw t.spinner.fail(r.name),n}}};var zr=()=>[{name:"Service files generated",spinnerText:"Generating service files...",execute:async e=>{await Xe({name:e.serviceName,outputPath:e.servicePath,httpClient:e.httpClient})}},{name:"API endpoints registered",spinnerText:"Registering API endpoints...",execute:async e=>{await xt({serviceName:e.serviceName,projectPath:e.projectPath})}}];import ul from"node:path";var Jr=()=>[{name:"Slice files generated",spinnerText:"Generating slice files...",execute:async e=>{await Ze({name:e.sliceName,outputPath:e.slicePath,persist:e.persistSlice})}},{name:"Slice registered in rootReducer",spinnerText:"Registering slice in rootReducer...",execute:async e=>{await we({projectPath:e.projectPath,name:e.sliceName,persist:e.persistSlice,importPath:ul.join(e.basePath,e.sliceName)})}}];import fl from"enquirer";var{prompt:gl}=fl,os=async(e,t,r,n,i,o,s)=>{let a=[];e||a.push({type:"input",name:"featureName",message:"What is the feature name?",initial:"my-feature",validate:u=>/^[a-z0-9-]+$/.test(u)?!0:"Feature name must be lowercase and contain only alphanumeric characters and hyphens."}),t&&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}})),r&&r!=="none"&&o===void 0&&s===void 0&&(a.push({type:"confirm",name:"createService",message:"Generate API service for this feature?",initial:!0}),r==="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 gl(a):{};return{featureName:e||p.featureName,hasRedux:t||!1,createStore:n===!0?!1:i!==void 0?!0:p.createStore||!1,persistStore:i==="persist"?!0:i==="no-persist"?!1:p.persistStore||!1,httpClient:r||"none",createService:o===!0?!1:s!==void 0?!0:p.createService||!1,selectedHttpClient:s||p.selectedHttpClient||(r==="both"?"fetch":r!=="none"?r:void 0)}};var ss=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(t,r)=>{try{let n=process.cwd();hl(r),l(M.cyan(`
1137
+ `)},yl=c.PROVIDERS,xl=c.ROOT_PROVIDER,Pl=c.PROVIDERS_INDEX,ms=async(e,t={fileExists:m,readFile:f})=>{let r=Bt.join(e,xl);if(t.fileExists(r))return r;let n=Bt.join(e,yl);if(!t.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 u=Bt.join(n,p),d=await t.readFile(u);if(!/\{children\}/.test(d))continue;let x=((d.split("{children}")[0]??"").match(/<[A-Z][A-Za-z0-9_]*\b/g)??[]).length;(!a||x>a.depth)&&(a={file:u,depth:x})}return a?.file??null},Jr=async e=>{let{projectPath:t,componentName:r,fileBaseName:n}=e,i=await ms(t);if(i){let a=await f(i),p=a;(!/from '\.\//.test(a)||!a.includes(`{ ${r} }`))&&(p=Je(p,`import { ${r} } from './${n}';`)),p=ps(p,r),p!==a&&await g(i,p)}let o=Bt.join(t,Pl),s=null;if(m(o)){let a=await f(o),p=ls(a,n);p!==a&&await g(o,p),s=o}return{rootProviderFile:i,barrelFile:s}};P();import{readFile as wl,writeFile as vl}from"node:fs/promises";import Sl from"node:path";var Vr=async(e,t)=>{let r=Sl.join(e,"src","i18n","translations","en.json");if(!m(r))return;let n=await wl(r,"utf-8"),i=JSON.parse(n);i[t]||(i[t]={title:t,description:`${t} page description`},await vl(r,`${JSON.stringify(i,null,2)}
1138
+ `))};var Wr=()=>[{name:"Project setup detected",spinnerText:"Detecting project setup...",execute:async e=>{e.detection=await F(e.projectPath)}},{name:"Feature files generated",spinnerText:"Generating feature files...",execute:async e=>{await mr({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 wt({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 Se({projectPath:e.projectPath,name:e.featureName,persist:e.persistStore,importPath:El.join(e.basePath,e.featureName,"store")})}}];var $e=async(e,t)=>{for(let r of e)if(!r.shouldSkip?.(t)){t.spinner.start(r.spinnerText);try{await r.execute(t),t.spinner.succeed(r.name)}catch(n){throw t.spinner.fail(r.name),n}}};var qr=()=>[{name:"Service files generated",spinnerText:"Generating service files...",execute:async e=>{await Ke({name:e.serviceName,outputPath:e.servicePath,httpClient:e.httpClient})}},{name:"API endpoints registered",spinnerText:"Registering API endpoints...",execute:async e=>{await wt({serviceName:e.serviceName,projectPath:e.projectPath})}}];import Cl from"node:path";var Xr=()=>[{name:"Slice files generated",spinnerText:"Generating slice files...",execute:async e=>{await et({name:e.sliceName,outputPath:e.slicePath,persist:e.persistSlice})}},{name:"Slice registered in rootReducer",spinnerText:"Registering slice in rootReducer...",execute:async e=>{await Se({projectPath:e.projectPath,name:e.sliceName,persist:e.persistSlice,importPath:Cl.join(e.basePath,e.sliceName)})}}];import Tl from"enquirer";var{prompt:bl}=Tl,ds=async(e,t,r,n,i,o,s)=>{let a=[];e||a.push({type:"input",name:"featureName",message:"What is the feature name?",initial:"my-feature",validate:u=>/^[a-z0-9-]+$/.test(u)?!0:"Feature name must be lowercase and contain only alphanumeric characters and hyphens."}),t&&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}})),r&&r!=="none"&&o===void 0&&s===void 0&&(a.push({type:"confirm",name:"createService",message:"Generate API service for this feature?",initial:!0}),r==="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 bl(a):{};return{featureName:e||p.featureName,hasRedux:t||!1,createStore:n===!0?!1:i!==void 0?!0:p.createStore||!1,persistStore:i==="persist"?!0:i==="no-persist"?!1:p.persistStore||!1,httpClient:r||"none",createService:o===!0?!1:s!==void 0?!0:p.createService||!1,selectedHttpClient:s||p.selectedHttpClient||(r==="both"?"fetch":r!=="none"?r:void 0)}};var fs=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(t,r)=>{try{let n=process.cwd();Rl(r),l(M.cyan(`
1139
1139
  \u{1F3AF} Feature Generator
1140
- `));let i=Br();y.start("Detecting project setup...");let{detectProjectSetup:o}=await Promise.resolve().then(()=>(H(),qe)),s=await o(n);y.succeed("Project setup detected"),l(M.dim(` Redux: ${s.hasRedux?"\u2713":"\u2717"}`)),l(M.dim(` HTTP Client: ${s.httpClient}`)),l(M.dim(` i18n: ${s.hasI18n?"\u2713":"\u2717"}
1141
- `));let a=await os(t,s.hasRedux,s.httpClient,r.skipStore,r.store,r.skipService,r.service),p=r.path||Vr.join("src","features"),u=Vr.join(n,p,a.featureName);await le(n,a.featureName,p)&&(v(`Feature '${a.featureName}' already exists at ${p}!`),process.exit(1)),await be(i.slice(1),{projectPath:n,spinner:y,featureName:a.featureName,basePath:p,featurePath:u,createStore:a.createStore,persistStore:a.persistStore,createService:a.createService,httpClient:a.selectedHttpClient,detection:s}),yl(a,p)}catch(n){y.fail("Feature generation failed"),v(`${n}`),process.exit(1)}})},hl=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))},yl=(e,t)=>{let r=Vr.join(t,e.featureName);l(M.green(`
1140
+ `));let i=Wr();y.start("Detecting project setup...");let{detectProjectSetup:o}=await Promise.resolve().then(()=>(H(),Ye)),s=await o(n);y.succeed("Project setup detected"),l(M.dim(` Redux: ${s.hasRedux?"\u2713":"\u2717"}`)),l(M.dim(` HTTP Client: ${s.httpClient}`)),l(M.dim(` i18n: ${s.hasI18n?"\u2713":"\u2717"}
1141
+ `));let a=await ds(t,s.hasRedux,s.httpClient,r.skipStore,r.store,r.skipService,r.service);U(a.featureName,"feature name"),r.path&&re(r.path,"path");let p=r.path||us.join("src","features"),u=$t(n,p,a.featureName);await de(n,a.featureName,p)&&(v(`Feature '${a.featureName}' already exists at ${p}!`),process.exit(1)),await $e(i.slice(1),{projectPath:n,spinner:y,featureName:a.featureName,basePath:p,featurePath:u,createStore:a.createStore,persistStore:a.persistStore,createService:a.createService,httpClient:a.selectedHttpClient,detection:s}),$l(a,p)}catch(n){y.fail("Feature generation failed"),v(`${n}`),process.exit(1)}})},Rl=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))},$l=(e,t)=>{let r=us.join(t,e.featureName);l(M.green(`
1142
1142
  \u2728 Feature '${e.featureName}' created successfully!
1143
1143
  `)),l(M.dim("Generated files:")),l(M.dim(` \u{1F4C2} ${r}/`)),l(M.dim(" \u251C\u2500\u2500 components/")),l(M.dim(" \u251C\u2500\u2500 hooks/")),l(M.dim(" \u251C\u2500\u2500 types/")),e.createStore&&l(M.dim(" \u251C\u2500\u2500 store/")),e.createService&&l(M.dim(" \u251C\u2500\u2500 services/")),l(M.dim(` \u2514\u2500\u2500 index.ts
1144
- `)),l(M.cyan("Next steps:"));let n=t.replace(/^src\//,"@/");l(M.dim(` 1. Import and use the feature: import { ${e.featureName} } from '${n}/${e.featureName}'`)),e.createStore&&l(M.dim(` 2. Customize your Redux slice in: ${r}/store/`)),e.createService&&l(M.dim(` 3. Add API methods in: ${r}/services/${e.featureName}.service.ts`)),l("")};import Wr from"node:path";import De from"picocolors";H();import xl from"enquirer";var{prompt:Pl}=xl,as=async e=>e?{hookName:e}:await Pl({type:"input",name:"hookName",message:'Hook name (kebab-case, without "use" prefix):',validate:r=>r?/^[a-z][a-z0-9-]*$/.test(r)?!0:"Use lowercase letters, numbers, and hyphens only":"Hook name is required"});var cs=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(t,r)=>{try{let n=process.cwd();l(De.cyan(`
1144
+ `)),l(M.cyan("Next steps:"));let n=t.replace(/^src\//,"@/");l(M.dim(` 1. Import and use the feature: import { ${e.featureName} } from '${n}/${e.featureName}'`)),e.createStore&&l(M.dim(` 2. Customize your Redux slice in: ${r}/store/`)),e.createService&&l(M.dim(` 3. Add API methods in: ${r}/services/${e.featureName}.service.ts`)),l("")};import Yr from"node:path";import Me from"picocolors";H();import Il from"enquirer";var{prompt:Nl}=Il,gs=async e=>e?{hookName:e}:await Nl({type:"input",name:"hookName",message:'Hook name (kebab-case, without "use" prefix):',validate:r=>r?/^[a-z][a-z0-9-]*$/.test(r)?!0:"Use lowercase letters, numbers, and hyphens only":"Hook name is required"});var hs=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(t,r)=>{try{let n=process.cwd();l(Me.cyan(`
1145
1145
  \u{1FA9D} Hook Generator
1146
- `));let i=await F(n),o=await as(t),a=`use${R(o.hookName)}`,p=wl(r,i.hasTests);y.start("Generating hook..."),await pr({name:o.hookName,projectPath:n,isClient:r.client??!0,featurePath:r.feature}),y.succeed("Hook generated");let u=r.feature?Wr.join(n,r.feature,"hooks",`${a}.ts`):Wr.join(n,"src/hooks",`${a}.ts`),d=null;p&&(y.start("Generating test..."),d=await oe({projectPath:n,sourceFile:u,kind:"hook",symbolName:a,hookUsesStore:i.hasRedux&&!!r.feature}),y.succeed("Test generated"));let h=r.feature?`${r.feature}/hooks/${a}.ts`:`src/hooks/${a}.ts`;l(De.green(`
1146
+ `));let i=await F(n),o=await gs(t);U(o.hookName,"hook name"),r.feature&&re(r.feature,"feature path");let a=`use${R(o.hookName)}`,p=kl(r,i.hasTests);y.start("Generating hook..."),await ur({name:o.hookName,projectPath:n,isClient:r.client??!0,featurePath:r.feature}),y.succeed("Hook generated");let u=r.feature?Yr.join(n,r.feature,"hooks",`${a}.ts`):Yr.join(n,"src/hooks",`${a}.ts`),d=null;p&&(y.start("Generating test..."),d=await ae({projectPath:n,sourceFile:u,kind:"hook",symbolName:a,hookUsesStore:i.hasRedux&&!!r.feature}),y.succeed("Test generated"));let h=r.feature?`${r.feature}/hooks/${a}.ts`:`src/hooks/${a}.ts`;l(Me.green(`
1147
1147
  \u2728 Hook '${a}' created successfully!
1148
- `)),l(De.dim(` \u{1F4C4} ${h}`)),d&&l(De.dim(` \u{1F9EA} ${Wr.relative(n,d)}`)),l(""),l(De.cyan("Usage:"));let x=r.feature?`${r.feature.replace(/^src\//,"@/")}/hooks/${a}`:`@/hooks/${a}`;l(De.dim(` import { ${a} } from '${x}';`)),l("")}catch(n){y.fail("Hook generation failed"),v(`${n}`),process.exit(1)}})},wl=(e,t)=>e.noTest?!1:e.test?!0:t;import Gt from"picocolors";H();var ps=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(t,r)=>{try{let n=process.cwd();l(Gt.cyan(`
1148
+ `)),l(Me.dim(` \u{1F4C4} ${h}`)),d&&l(Me.dim(` \u{1F9EA} ${Yr.relative(n,d)}`)),l(""),l(Me.cyan("Usage:"));let x=r.feature?`${r.feature.replace(/^src\//,"@/")}/hooks/${a}`:`@/hooks/${a}`;l(Me.dim(` import { ${a} } from '${x}';`)),l("")}catch(n){y.fail("Hook generation failed"),v(`${n}`),process.exit(1)}})},kl=(e,t)=>e.test===!1?!1:e.test===!0?!0:t;import zt from"picocolors";H();var ys=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(t,r)=>{try{let n=process.cwd();l(zt.cyan(`
1149
1149
  \u{1F4D0} Layout Generator
1150
- `)),y.start("Detecting project setup...");let i=await F(n);y.succeed("Project setup detected");let o=i.hasI18n&&r.locale!==!1;l(Gt.dim(` i18n: ${o?"\u2713":"\u2717"}
1151
- `)),y.start("Generating layout...");let s=await lr({segment:t,at:r.at,projectPath:n,hasI18n:o,withGroup:!!r.group});y.succeed("Layout generated"),l(Gt.green(`
1150
+ `)),y.start("Detecting project setup...");let i=await F(n);y.succeed("Project setup detected");let o=i.hasI18n&&r.locale!==!1;l(zt.dim(` i18n: ${o?"\u2713":"\u2717"}
1151
+ `)),y.start("Generating layout...");let s=await fr({segment:t,at:r.at,projectPath:n,hasI18n:o,withGroup:!!r.group});y.succeed("Layout generated"),l(zt.green(`
1152
1152
  \u2728 ${s.componentName} created!
1153
- `)),l(Gt.dim(` \u{1F4C4} ${s.displayPath}`)),l("")}catch(n){y.fail("Layout generation failed"),v(`${n instanceof Error?n.message:n}`),process.exit(1)}})};import Cl from"node:path";import ne from"picocolors";P();H();import vl from"enquirer";var{prompt:Sl}=vl,ls=async(e,t={})=>{let r=[];e||r.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"}),r.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"}),t.copyTranslations===void 0&&r.push({type:"confirm",name:"copyTranslations",message:"Copy translations from English? (No = empty values)",initial:!1});let n=await Sl(r);return{code:e??n.code,name:n.name,country:n.country,flag:n.flag,copyTranslations:t.copyTranslations??n.copyTranslations??!1}};var ms=e=>{e.command("locale [code]").description("Add a new locale/language").option("--copy-translations","Copy translations from English instead of empty values").action(async(t,r)=>{try{let n=process.cwd();l(ne.cyan(`
1153
+ `)),l(zt.dim(` \u{1F4C4} ${s.displayPath}`)),l("")}catch(n){y.fail("Layout generation failed"),v(`${n instanceof Error?n.message:n}`),process.exit(1)}})};import oe from"picocolors";P();H();import Al from"enquirer";var{prompt:_l}=Al,xs=async(e,t={})=>{let r=[];e||r.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"}),r.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"}),t.copyTranslations===void 0&&r.push({type:"confirm",name:"copyTranslations",message:"Copy translations from English? (No = empty values)",initial:!1});let n=await _l(r);return{code:e??n.code,name:n.name,country:n.country,flag:n.flag,copyTranslations:t.copyTranslations??n.copyTranslations??!1}};var Ps=e=>{e.command("locale [code]").description("Add a new locale/language").option("--copy-translations","Copy translations from English instead of empty values").action(async(t,r)=>{try{let n=process.cwd();l(oe.cyan(`
1154
1154
  \u{1F30D} Locale Generator
1155
- `)),y.start("Detecting project setup...");let i=await F(n);y.succeed("Project setup detected"),i.hasI18n||(y.fail("i18n is not set up in this project"),v("Please set up internationalization first"),l(ne.dim(`
1155
+ `)),y.start("Detecting project setup...");let i=await F(n);y.succeed("Project setup detected"),i.hasI18n||(y.fail("i18n is not set up in this project"),v("Please set up internationalization first"),l(oe.dim(`
1156
1156
  Run: npx @teispace/next-maker setup --i18n
1157
- `)),process.exit(1));let o=await ls(t,{copyTranslations:r.copyTranslations}),s=Cl.join(n,"src","i18n","translations",`${o.code}.json`);m(s)&&(v(`Locale '${o.code}' already exists!`),process.exit(1)),y.start("Adding locale..."),await mr({...o,projectPath:n}),y.succeed("Locale added"),l(ne.green(`
1157
+ `)),process.exit(1));let o=await xs(t,{copyTranslations:r.copyTranslations});U(o.code,"locale code");let s=$t(n,"src","i18n","translations",`${o.code}.json`);m(s)&&(v(`Locale '${o.code}' already exists!`),process.exit(1)),y.start("Adding locale..."),await gr({...o,projectPath:n}),y.succeed("Locale added"),l(oe.green(`
1158
1158
  \u2728 Locale '${o.code}' (${o.name}) added successfully!
1159
- `)),l(ne.dim("Updated files:")),l(ne.dim(` \u{1F4C4} src/i18n/translations/${o.code}.json`)),l(ne.dim(" \u{1F4DD} src/types/i18n.ts (SupportedLocale type)")),l(ne.dim(" \u{1F4DD} src/lib/config/app-locales.ts")),l(""),l(ne.cyan("Next steps:")),l(ne.dim(` 1. Translate: src/i18n/translations/${o.code}.json`)),l(ne.dim(` 2. Visit: http://localhost:3000/${o.code}`)),l("")}catch(n){y.fail("Locale generation failed"),v(`${n}`),process.exit(1)}})};import us from"node:path";import K from"picocolors";H();import El from"enquirer";var{prompt:Tl}=El,ds=async(e,t={})=>{let r=[];e||r.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"}),t.loading===void 0&&r.push({type:"confirm",name:"withLoading",message:"Generate loading.tsx?",initial:!0}),t.error===void 0&&r.push({type:"confirm",name:"withError",message:"Generate error.tsx?",initial:!0});let n=r.length>0?await Tl(r):{};return{pageName:e??n.pageName,withLoading:t.loading??n.withLoading??!0,withError:t.error??n.withError??!0}};var fs=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(t,r)=>{try{let n=process.cwd();l(K.cyan(`
1159
+ `)),l(oe.dim("Updated files:")),l(oe.dim(` \u{1F4C4} src/i18n/translations/${o.code}.json`)),l(oe.dim(" \u{1F4DD} src/types/i18n.ts (SupportedLocale type)")),l(oe.dim(" \u{1F4DD} src/lib/config/app-locales.ts")),l(""),l(oe.cyan("Next steps:")),l(oe.dim(` 1. Translate: src/i18n/translations/${o.code}.json`)),l(oe.dim(` 2. Visit: http://localhost:3000/${o.code}`)),l("")}catch(n){y.fail("Locale generation failed"),v(`${n}`),process.exit(1)}})};import vs from"node:path";import Z from"picocolors";H();import Ol from"enquirer";var{prompt:Fl}=Ol,ws=async(e,t={})=>{let r=[];e||r.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"}),t.loading===void 0&&r.push({type:"confirm",name:"withLoading",message:"Generate loading.tsx?",initial:!0}),t.error===void 0&&r.push({type:"confirm",name:"withError",message:"Generate error.tsx?",initial:!0});let n=r.length>0?await Fl(r):{};return{pageName:e??n.pageName,withLoading:t.loading??n.withLoading??!0,withError:t.error??n.withError??!0}};var Ss=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(t,r)=>{try{let n=process.cwd();l(Z.cyan(`
1160
1160
  \u{1F4C4} Page Generator
1161
- `)),y.start("Detecting project setup...");let i=await F(n);y.succeed("Project setup detected"),l(K.dim(` i18n: ${i.hasI18n?"\u2713":"\u2717"}
1162
- `));let o=await ds(t,{loading:r.loading,error:r.error}),s=o.pageName,a=R(s),p=i.hasI18n?"src/app/[locale]":"src/app";await le(n,s,p)&&(v(`Page '${s}' already exists at ${p}/${s}!`),process.exit(1)),y.start("Generating page files..."),await ur({name:s,projectPath:n,hasI18n:i.hasI18n,dynamic:r.dynamic,withLoading:r.loading??o.withLoading,withError:r.error??o.withError}),y.succeed("Page files generated"),y.start("Registering route...");let d=r.dynamic?`/${s}/[${r.dynamic}]`:`/${s}`;await Gr(n,s,d),y.succeed("Route registered"),i.hasI18n&&(y.start("Adding translation namespace..."),await Ur(n,a),y.succeed("Translation namespace added"));let h=r.dynamic?us.join(p,s,`[${r.dynamic}]`):us.join(p,s);l(K.green(`
1161
+ `)),y.start("Detecting project setup...");let i=await F(n);y.succeed("Project setup detected"),l(Z.dim(` i18n: ${i.hasI18n?"\u2713":"\u2717"}
1162
+ `));let o=await ws(t,{loading:r.loading,error:r.error}),s=o.pageName;U(s,"page name"),r.dynamic&&U(r.dynamic,"dynamic param");let a=R(s),p=i.hasI18n?"src/app/[locale]":"src/app";await de(n,s,p)&&(v(`Page '${s}' already exists at ${p}/${s}!`),process.exit(1)),y.start("Generating page files..."),await yr({name:s,projectPath:n,hasI18n:i.hasI18n,dynamic:r.dynamic,withLoading:r.loading??o.withLoading,withError:r.error??o.withError}),y.succeed("Page files generated"),y.start("Registering route...");let d=r.dynamic?`/${s}/[${r.dynamic}]`:`/${s}`;await zr(n,s,d),y.succeed("Route registered"),i.hasI18n&&(y.start("Adding translation namespace..."),await Vr(n,a),y.succeed("Translation namespace added"));let h=r.dynamic?vs.join(p,s,`[${r.dynamic}]`):vs.join(p,s);l(Z.green(`
1163
1163
  \u2728 Page '${s}' created successfully!
1164
- `)),l(K.dim("Generated files:")),l(K.dim(` \u{1F4C2} ${h}/`)),l(K.dim(" \u251C\u2500\u2500 page.tsx")),(r.loading??o.withLoading)&&l(K.dim(" \u251C\u2500\u2500 loading.tsx")),(r.error??o.withError)&&l(K.dim(" \u2514\u2500\u2500 error.tsx")),l(""),i.hasI18n&&(l(K.cyan("Next steps:")),l(K.dim(` 1. Add translations in: src/i18n/translations/en.json \u2192 "${a}"`)),l(K.dim(` 2. Visit: http://localhost:3000/${s}`)),l(""))}catch(n){y.fail("Page generation failed"),v(`${n}`),process.exit(1)}})};import qr from"node:path";import fe from"picocolors";var gs=e=>{e.command("provider <name>").description("Generate a context provider in src/providers/ and wire it into RootProvider").action(async t=>{try{let r=process.cwd();l(fe.cyan(`
1164
+ `)),l(Z.dim("Generated files:")),l(Z.dim(` \u{1F4C2} ${h}/`)),l(Z.dim(" \u251C\u2500\u2500 page.tsx")),(r.loading??o.withLoading)&&l(Z.dim(" \u251C\u2500\u2500 loading.tsx")),(r.error??o.withError)&&l(Z.dim(" \u2514\u2500\u2500 error.tsx")),l(""),i.hasI18n&&(l(Z.cyan("Next steps:")),l(Z.dim(` 1. Add translations in: src/i18n/translations/en.json \u2192 "${a}"`)),l(Z.dim(` 2. Visit: http://localhost:3000/${s}`)),l(""))}catch(n){y.fail("Page generation failed"),v(`${n}`),process.exit(1)}})};import Kr from"node:path";import he from"picocolors";var Es=e=>{e.command("provider <name>").description("Generate a context provider in src/providers/ and wire it into RootProvider").action(async t=>{try{let r=process.cwd();l(he.cyan(`
1165
1165
  \u{1F50C} Provider Generator
1166
- `)),y.start("Generating provider...");let{componentName:n,fileBaseName:i,providerFile:o}=await gr({name:t,projectPath:r});y.succeed("Provider generated"),y.start("Registering provider in RootProvider and barrel...");let{rootProviderFile:s,barrelFile:a}=await Hr({projectPath:r,componentName:n,fileBaseName:i});y.succeed("Provider registered"),l(fe.green(`
1166
+ `)),y.start("Generating provider...");let{componentName:n,fileBaseName:i,providerFile:o}=await Pr({name:t,projectPath:r});y.succeed("Provider generated"),y.start("Registering provider in RootProvider and barrel...");let{rootProviderFile:s,barrelFile:a}=await Jr({projectPath:r,componentName:n,fileBaseName:i});y.succeed("Provider registered"),l(he.green(`
1167
1167
  \u2728 ${n} created!
1168
- `)),l(fe.dim("Generated files:")),l(fe.dim(` \u{1F4C4} ${qr.relative(r,o)}`)),s?l(fe.dim(` \u270F\uFE0F ${qr.relative(r,s)} \u2014 wrapped {children}`)):(l(fe.yellow(`
1169
- \u26A0\uFE0F Could not locate a RootProvider file. Wire the new provider manually:`)),l(fe.dim(` <${n}>{children}</${n}>`))),a&&l(fe.dim(` \u270F\uFE0F ${qr.relative(r,a)} \u2014 added re-export`)),l("")}catch(r){y.fail("Provider generation failed"),v(`${r instanceof Error?r.message:r}`),process.exit(1)}})};import bl from"enquirer";import U from"picocolors";var{prompt:Rl}=bl,$l=e=>{let t=[];for(let r of e.filesRemoved)t.push(` ${U.red("-")} delete: ${r}`);for(let r of e.blocksStripped)t.push(` ${U.red("-")} strip block: ${r.description} ${U.dim(`(${r.file})`)}`);for(let r of e.scriptsRemoved)t.push(` ${U.red("-")} remove script: ${r}`);for(let r of e.packagesUninstalled)t.push(` ${U.red("-")} uninstall: ${r}`);for(let r of e.manualCleanup)t.push(` ${U.yellow("?")} manual cleanup: ${r.description} ${U.dim(`(${r.file})`)}`);return t},Il=e=>e.filesRemoved.length===0&&e.blocksStripped.length===0&&e.scriptsRemoved.length===0&&e.packagesUninstalled.length===0&&e.manualCleanup.length===0,hs=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(t,r)=>{try{let n=process.cwd(),i=Io(t);if(!i)throw new Error(`Unknown feature "${t}". Valid: ${Ce.map(p=>p.id).join(", ")}.`);if(l(U.cyan(`
1168
+ `)),l(he.dim("Generated files:")),l(he.dim(` \u{1F4C4} ${Kr.relative(r,o)}`)),s?l(he.dim(` \u270F\uFE0F ${Kr.relative(r,s)} \u2014 wrapped {children}`)):(l(he.yellow(`
1169
+ \u26A0\uFE0F Could not locate a RootProvider file. Wire the new provider manually:`)),l(he.dim(` <${n}>{children}</${n}>`))),a&&l(he.dim(` \u270F\uFE0F ${Kr.relative(r,a)} \u2014 added re-export`)),l("")}catch(r){y.fail("Provider generation failed"),v(`${r instanceof Error?r.message:r}`),process.exit(1)}})};import jl from"enquirer";import B from"picocolors";var{prompt:Dl}=jl,Ll=e=>{let t=[];for(let r of e.filesRemoved)t.push(` ${B.red("-")} delete: ${r}`);for(let r of e.blocksStripped)t.push(` ${B.red("-")} strip block: ${r.description} ${B.dim(`(${r.file})`)}`);for(let r of e.scriptsRemoved)t.push(` ${B.red("-")} remove script: ${r}`);for(let r of e.packagesUninstalled)t.push(` ${B.red("-")} uninstall: ${r}`);for(let r of e.manualCleanup)t.push(` ${B.yellow("?")} manual cleanup: ${r.description} ${B.dim(`(${r.file})`)}`);return t},Ml=e=>e.filesRemoved.length===0&&e.blocksStripped.length===0&&e.scriptsRemoved.length===0&&e.packagesUninstalled.length===0&&e.manualCleanup.length===0,Cs=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(t,r)=>{try{let n=process.cwd(),i=jo(t);if(!i)throw new Error(`Unknown feature "${t}". Valid: ${Te.map(p=>p.id).join(", ")}.`);if(l(B.cyan(`
1170
1170
  \u{1F5D1} Remove ${i.name}
1171
- `)),!(await ht(i,n)).installed){l(U.dim(`${i.name} is not installed \u2014 nothing to remove.`));return}y.start("Computing changes...");let s=await Ft(i,n,{dryRun:!0});if(y.succeed("Computed plan"),Il(s)){l(U.yellow(`
1171
+ `)),!(await xt(i,n)).installed){l(B.dim(`${i.name} is not installed \u2014 nothing to remove.`));return}y.start("Computing changes...");let s=await Mt(i,n,{dryRun:!0});if(y.succeed("Computed plan"),Ml(s)){l(B.yellow(`
1172
1172
  \u26A0\uFE0F Manifest had no removable artifacts. Nothing to do.
1173
- `));return}l(U.bold(`
1173
+ `));return}l(B.bold(`
1174
1174
  Planned changes:
1175
- `));for(let p of $l(s))l(p);if(l(""),r.dryRun){l(U.dim(`--dry-run set \u2014 exiting without writing.
1176
- `));return}if(!r.yes){let{confirm:p}=await Rl({type:"confirm",name:"confirm",message:`Apply the changes above to remove ${i.name}?`,initial:!1});if(!p){l(U.yellow(`
1175
+ `));for(let p of Ll(s))l(p);if(l(""),r.dryRun){l(B.dim(`--dry-run set \u2014 exiting without writing.
1176
+ `));return}if(!r.yes){let{confirm:p}=await Dl({type:"confirm",name:"confirm",message:`Apply the changes above to remove ${i.name}?`,initial:!1});if(!p){l(B.yellow(`
1177
1177
  Aborted.
1178
- `));return}}y.start(`Removing ${i.name}...`);let a=i.remove?(await i.remove(n),s):await Ft(i,n);if(y.succeed(`${i.name} removed`),l(U.green(`
1179
- \u2713 ${i.name} removed.`)),a.manualCleanup.length>0){l(U.yellow(`
1180
- \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 _l}from"node:fs";import{mkdir as Ol}from"node:fs/promises";import Pt from"node:path";import Z from"picocolors";H();import{readFile as Nl,writeFile as kl}from"node:fs/promises";import Al from"node:path";var ys=async(e,t)=>{let r=j(t),n=Al.join(e,"src","lib","config","app-apis.ts");try{let i=await Nl(n,"utf-8");if(i.includes(`${r}:`))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=Xn({camelName:r,kebabName:t});i=ze(i,o),await kl(n,i)}catch(i){throw new Error(`Failed to register CRUD API endpoints: ${i}`,{cause:i})}};import xs from"enquirer";var Ps=async(e,t,r,n)=>{let i=e||(await xs.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 t!==void 0?o="axios":r!==void 0?o="fetch":n==="axios"?o="axios":n==="fetch"?o="fetch":n==="both"?o=(await xs.prompt({type:"select",name:"httpClient",message:"Choose HTTP client:",choices:["axios","fetch"]})).httpClient:o="axios",{serviceName:i,httpClient:o}};var ws=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(t,r)=>{try{let n=process.cwd();r.axios&&r.fetch&&(v("Cannot use --axios and --fetch together"),process.exit(1)),l(Z.cyan(`
1178
+ `));return}}y.start(`Removing ${i.name}...`);let a=i.remove?(await i.remove(n),s):await Mt(i,n);if(y.succeed(`${i.name} removed`),l(B.green(`
1179
+ \u2713 ${i.name} removed.`)),a.manualCleanup.length>0){l(B.yellow(`
1180
+ \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 Bl}from"node:fs";import{mkdir as zl}from"node:fs/promises";import vt from"node:path";import Q from"picocolors";H();import{readFile as Gl,writeFile as Ul}from"node:fs/promises";import Hl from"node:path";var Ts=async(e,t)=>{let r=j(t),n=Hl.join(e,"src","lib","config","app-apis.ts");try{let i=await Gl(n,"utf-8");if(i.includes(`${r}:`))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=ri({camelName:r,kebabName:t});i=Ve(i,o),await Ul(n,i)}catch(i){throw new Error(`Failed to register CRUD API endpoints: ${i}`,{cause:i})}};import bs from"enquirer";var Rs=async(e,t,r,n)=>{let i=e||(await bs.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 t!==void 0?o="axios":r!==void 0?o="fetch":n==="axios"?o="axios":n==="fetch"?o="fetch":n==="both"?o=(await bs.prompt({type:"select",name:"httpClient",message:"Choose HTTP client:",choices:["axios","fetch"]})).httpClient:o="axios",{serviceName:i,httpClient:o}};var $s=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(t,r)=>{try{let n=process.cwd();r.axios&&r.fetch&&(v("Cannot use --axios and --fetch together"),process.exit(1)),l(Q.cyan(`
1181
1181
  \u{1F527} Service Generator
1182
- `)),y.start("Detecting project setup...");let i=await F(n);y.succeed("Project setup detected"),i.httpClient==="none"&&(y.fail("No HTTP client is setup in this project"),v("Please setup either AxiosClient or FetchClient first"),l(Z.dim(`
1182
+ `)),y.start("Detecting project setup...");let i=await F(n);y.succeed("Project setup detected"),i.httpClient==="none"&&(y.fail("No HTTP client is setup in this project"),v("Please setup either AxiosClient or FetchClient first"),l(Q.dim(`
1183
1183
  Check: lib/utils/http/axios-client or lib/utils/http/fetch-client
1184
- `)),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(Z.dim(` HTTP Clients: ${o.join(", ")}
1185
- `));let s=await Ps(t,r.axios,r.fetch,i.httpClient),{basePath:a,servicePath:p}=Fl(n,s.serviceName,r.path);_l(p)||await Ol(p,{recursive:!0}),Tt(n,a,`${s.serviceName}.service.ts`)&&(v(`Service '${s.serviceName}' already exists at ${a}!`),process.exit(1)),r.crud?(y.start("Generating CRUD service files..."),await sr({name:s.serviceName,outputPath:p,httpClient:s.httpClient}),y.succeed("CRUD service files generated"),y.start("Registering CRUD API endpoints..."),await ys(n,s.serviceName),y.succeed("CRUD API endpoints registered")):await be(zr(),{projectPath:n,spinner:y,serviceName:s.serviceName,servicePath:p,httpClient:s.httpClient}),jl(s,a,!!r.crud)}catch(n){y.fail("Service generation failed"),v(`${n}`),process.exit(1)}})},Fl=(e,t,r)=>{let n;if(r){let i=r.replace(/^src\//,"");if(i.startsWith("features/")){let o=i.split("/")[1];n=Pt.join("src","features",o,"services")}else n=Pt.join("src",i)}else n=Pt.join("src","features",t,"services");return{basePath:n,servicePath:Pt.join(e,n)}},jl=(e,t,r=!1)=>{let n=Pt.join(t,`${e.serviceName}.service.ts`);l(Z.green(`
1184
+ `)),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(Q.dim(` HTTP Clients: ${o.join(", ")}
1185
+ `));let s=await Rs(t,r.axios,r.fetch,i.httpClient);U(s.serviceName,"service name"),r.path&&re(r.path,"path");let{basePath:a,servicePath:p}=Jl(n,s.serviceName,r.path);Bl(p)||await zl(p,{recursive:!0}),It(n,a,`${s.serviceName}.service.ts`)&&(v(`Service '${s.serviceName}' already exists at ${a}!`),process.exit(1)),r.crud?(y.start("Generating CRUD service files..."),await lr({name:s.serviceName,outputPath:p,httpClient:s.httpClient}),y.succeed("CRUD service files generated"),y.start("Registering CRUD API endpoints..."),await Ts(n,s.serviceName),y.succeed("CRUD API endpoints registered")):await $e(qr(),{projectPath:n,spinner:y,serviceName:s.serviceName,servicePath:p,httpClient:s.httpClient}),Vl(s,a,!!r.crud)}catch(n){y.fail("Service generation failed"),v(`${n}`),process.exit(1)}})},Jl=(e,t,r)=>{let n;if(r){let i=r.replace(/^src\//,"");if(i.startsWith("features/")){let o=i.split("/")[1];n=vt.join("src","features",o,"services")}else n=vt.join("src",i)}else n=vt.join("src","features",t,"services");return{basePath:n,servicePath:vt.join(e,n)}},Vl=(e,t,r=!1)=>{let n=vt.join(t,`${e.serviceName}.service.ts`);l(Q.green(`
1186
1186
  \u2728 ${r?"CRUD ":""}Service '${e.serviceName}' created successfully!
1187
- `)),l(Z.dim("Generated files:")),l(Z.dim(` \u{1F4C4} ${n}
1188
- `)),l(Z.cyan("Next steps:"));let i=t.replace(/^src\//,"@/");l(Z.dim(` 1. Import service: import { ${e.serviceName}Service } from '${i}/${e.serviceName}.service'`)),r?(l(Z.dim(" 2. Available methods: getAll, getById, create, update, delete")),l(Z.dim(" 3. Update DTO types in the service file"))):l(Z.dim(` 2. Use in component: const data = await ${e.serviceName}Service.getAll()`)),l("")};import Dl from"enquirer";import Xr from"picocolors";var{prompt:Ll}=Dl,vs=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("--ws","Setup WebSocket client (socket.io-client + Redux bridge; requires --redux)").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 t=>{try{if(l(Xr.cyan(`
1187
+ `)),l(Q.dim("Generated files:")),l(Q.dim(` \u{1F4C4} ${n}
1188
+ `)),l(Q.cyan("Next steps:"));let i=t.replace(/^src\//,"@/");l(Q.dim(` 1. Import service: import { ${e.serviceName}Service } from '${i}/${e.serviceName}.service'`)),r?(l(Q.dim(" 2. Available methods: getAll, getById, create, update, delete")),l(Q.dim(" 3. Update DTO types in the service file"))):l(Q.dim(` 2. Use in component: const data = await ${e.serviceName}Service.getAll()`)),l("")};import Wl from"enquirer";import Zr from"picocolors";var{prompt:ql}=Wl,Is=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("--ws","Setup WebSocket client (socket.io-client + Redux bridge; requires --redux)").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 t=>{try{if(l(Zr.cyan(`
1189
1189
  \u{1F527} Setup Wizard
1190
- `)),t.httpClient||t.darkTheme||t.redux||t.ws||t.i18n||t.tests||t.reactCompiler||t.bundleAnalyzer||t.securityHeaders||t.validateScripts||t.commitizen){t.httpClient&&await at(process.cwd()),t.darkTheme&&await ot(process.cwd()),t.redux&&await lt(process.cwd()),t.ws&&await gt(process.cwd()),t.i18n&&await ct(process.cwd()),t.tests&&await dt(process.cwd()),t.reactCompiler&&await pt(process.cwd()),t.bundleAnalyzer&&await rt(process.cwd()),t.securityHeaders&&await mt(process.cwd()),t.validateScripts&&await ut(process.cwd()),t.commitizen&&await nt(process.cwd());return}let i=(await Ll([{type:"select",name:"feature",message:"What would you like to setup?",choices:[{name:"Dark Theme",value:"dark-theme"},{name:"Redux Toolkit",value:"redux"},{name:"WebSocket Client (requires Redux)",value:"ws"},{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(Xr.yellow("Setup cancelled."));return}let s={"dark-theme":ot,redux:lt,ws:gt,"http-client":at,i18n:ct,tests:dt,"react-compiler":pt,"bundle-analyzer":rt,"security-headers":mt,"validate-scripts":ut,commitizen:nt}[i];s?await s(process.cwd()):l(Xr.yellow(`
1191
- \u26A0\uFE0F ${i} setup is not implemented yet.`))}catch(r){y.fail("Setup failed"),v(`${r}`),process.exit(1)}})};import{existsSync as Hl}from"node:fs";import{mkdir as Ul}from"node:fs/promises";import ge from"node:path";import B from"picocolors";H();import Ml from"enquirer";var{prompt:Gl}=Ml,Ss=async(e,t,r)=>{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."}),t===void 0&&r===void 0&&n.push({type:"confirm",name:"persistSlice",message:"Enable persistence for this slice?",initial:!1});let i=n.length>0?await Gl(n):{};return{sliceName:e||i.sliceName,persistSlice:t===!0?!0:r===!1?!1:i.persistSlice||!1}};var Cs=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(t,r)=>{try{let n=process.cwd();r.persist&&r.noPersist===!0&&(v("Cannot use --persist and --no-persist together"),process.exit(1)),l(B.cyan(`
1190
+ `)),t.httpClient||t.darkTheme||t.redux||t.ws||t.i18n||t.tests||t.reactCompiler||t.bundleAnalyzer||t.securityHeaders||t.validateScripts||t.commitizen){t.httpClient&&await pt(process.cwd()),t.darkTheme&&await at(process.cwd()),t.redux&&await dt(process.cwd()),t.ws&&await yt(process.cwd()),t.i18n&&await lt(process.cwd()),t.tests&&await ft(process.cwd()),t.reactCompiler&&await mt(process.cwd()),t.bundleAnalyzer&&await it(process.cwd()),t.securityHeaders&&await ut(process.cwd()),t.validateScripts&&await gt(process.cwd()),t.commitizen&&await ot(process.cwd());return}let i=(await ql([{type:"select",name:"feature",message:"What would you like to setup?",choices:[{name:"Dark Theme",value:"dark-theme"},{name:"Redux Toolkit",value:"redux"},{name:"WebSocket Client (requires Redux)",value:"ws"},{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(Zr.yellow("Setup cancelled."));return}let s={"dark-theme":at,redux:dt,ws:yt,"http-client":pt,i18n:lt,tests:ft,"react-compiler":mt,"bundle-analyzer":it,"security-headers":ut,"validate-scripts":gt,commitizen:ot}[i];s?await s(process.cwd()):l(Zr.yellow(`
1191
+ \u26A0\uFE0F ${i} setup is not implemented yet.`))}catch(r){y.fail("Setup failed"),v(`${r}`),process.exit(1)}})};import{existsSync as Kl}from"node:fs";import{mkdir as Zl}from"node:fs/promises";import ye from"node:path";import z from"picocolors";H();import Xl from"enquirer";var{prompt:Yl}=Xl,Ns=async(e,t)=>{let r=[];e||r.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."}),t===void 0&&r.push({type:"confirm",name:"persistSlice",message:"Enable persistence for this slice?",initial:!1});let n=r.length>0?await Yl(r):{};return{sliceName:e||n.sliceName,persistSlice:t===void 0?n.persistSlice||!1:t}};var ks=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(t,r)=>{try{let n=process.cwd();l(z.cyan(`
1192
1192
  \u{1F527} Slice Generator
1193
- `)),y.start("Detecting project setup...");let i=await F(n);y.succeed("Project setup detected"),i.hasRedux||(y.fail("Redux is not setup in this project"),v("Please install @reduxjs/toolkit and react-redux first"),l(B.dim(`
1193
+ `)),y.start("Detecting project setup...");let i=await F(n);y.succeed("Project setup detected"),i.hasRedux||(y.fail("Redux is not setup in this project"),v("Please install @reduxjs/toolkit and react-redux first"),l(z.dim(`
1194
1194
  Run: npm install @reduxjs/toolkit react-redux
1195
- `)),process.exit(1)),l(B.dim(` Redux: \u2713
1196
- `));let o=await Ss(t,r.persist,r.noPersist===!0?!1:void 0),{basePath:s,slicePath:a}=Bl(n,o.sliceName,r.path),p=ge.join(n,s);Hl(p)||await Ul(p,{recursive:!0}),await le(n,o.sliceName,s)&&(v(`Slice '${o.sliceName}' already exists at ${s}!`),process.exit(1)),await be(Jr(),{projectPath:n,spinner:y,sliceName:o.sliceName,basePath:s,slicePath:a,persistSlice:o.persistSlice});let d=null;if(zl(r,i.hasTests)){let x=ge.join(a,`${o.sliceName}.slice.ts`);y.start("Generating test..."),d=await oe({projectPath:n,sourceFile:x,kind:"slice",symbolName:j(o.sliceName)}),y.succeed("Test generated")}Jl(o,s,d,n)}catch(n){y.fail("Slice generation failed"),v(`${n}`),process.exit(1)}})},Bl=(e,t,r)=>{let n;if(r){let i=r.replace(/^src\//,"");if(i.startsWith("features/")){let o=i.split("/")[1];n=ge.join("src","features",o,"store")}else n=ge.join("src",i)}else n=ge.join("src","features",t,"store");return{basePath:n,slicePath:ge.join(e,n,t)}},zl=(e,t)=>e.noTest?!1:e.test?!0:t,Jl=(e,t,r,n)=>{let i=ge.join(t,e.sliceName);l(B.green(`
1195
+ `)),process.exit(1)),l(z.dim(` Redux: \u2713
1196
+ `));let o=await Ns(t,r.persist);U(o.sliceName,"slice name"),r.path&&re(r.path,"path");let{basePath:s,slicePath:a}=Ql(n,o.sliceName,r.path),p=ye.join(n,s);Kl(p)||await Zl(p,{recursive:!0}),await de(n,o.sliceName,s)&&(v(`Slice '${o.sliceName}' already exists at ${s}!`),process.exit(1)),await $e(Xr(),{projectPath:n,spinner:y,sliceName:o.sliceName,basePath:s,slicePath:a,persistSlice:o.persistSlice});let d=null;if(em(r,i.hasTests)){let x=ye.join(a,`${o.sliceName}.slice.ts`);y.start("Generating test..."),d=await ae({projectPath:n,sourceFile:x,kind:"slice",symbolName:j(o.sliceName)}),y.succeed("Test generated")}tm(o,s,d,n)}catch(n){y.fail("Slice generation failed"),v(`${n}`),process.exit(1)}})},Ql=(e,t,r)=>{let n;if(r){let i=r.replace(/^src\//,"");if(i.startsWith("features/")){let o=i.split("/")[1];n=ye.join("src","features",o,"store")}else n=ye.join("src",i)}else n=ye.join("src","features",t,"store");return{basePath:n,slicePath:ye.join(e,n,t)}},em=(e,t)=>e.test===!1?!1:e.test===!0?!0:t,tm=(e,t,r,n)=>{let i=ye.join(t,e.sliceName);l(z.green(`
1197
1197
  \u2728 Slice '${e.sliceName}' created successfully!
1198
- `)),l(B.dim("Generated files:")),l(B.dim(` \u{1F4C2} ${i}/`)),l(B.dim(` \u251C\u2500\u2500 ${e.sliceName}.slice.ts`)),l(B.dim(` \u251C\u2500\u2500 ${e.sliceName}.selectors.ts`)),e.persistSlice&&l(B.dim(" \u251C\u2500\u2500 persist.ts")),l(B.dim(` \u251C\u2500\u2500 ${e.sliceName}.types.ts`)),l(B.dim(` \u2514\u2500\u2500 index.ts
1199
- `)),r&&l(B.dim(` \u{1F9EA} ${ge.relative(n,r)}
1200
- `)),l(B.cyan("Next steps:"));let o=t.replace(/^src\//,"@/");l(B.dim(` 1. Import actions: import { setLoading, setError } from '${o}/${e.sliceName}'`)),l(B.dim(" 2. Use in component: dispatch(setLoading(true))")),l("")};import Q from"node:path";import Yr from"picocolors";P();H();var Es=e=>{e.command("test <file>").description(`Generate a sibling test file for an existing component, hook, or slice.
1201
- 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(t,r)=>{try{let n=process.cwd(),i=Q.isAbsolute(t)?t:Q.join(n,t);l(Yr.cyan(`
1198
+ `)),l(z.dim("Generated files:")),l(z.dim(` \u{1F4C2} ${i}/`)),l(z.dim(` \u251C\u2500\u2500 ${e.sliceName}.slice.ts`)),l(z.dim(` \u251C\u2500\u2500 ${e.sliceName}.selectors.ts`)),e.persistSlice&&l(z.dim(" \u251C\u2500\u2500 persist.ts")),l(z.dim(` \u251C\u2500\u2500 ${e.sliceName}.types.ts`)),l(z.dim(` \u2514\u2500\u2500 index.ts
1199
+ `)),r&&l(z.dim(` \u{1F9EA} ${ye.relative(n,r)}
1200
+ `)),l(z.cyan("Next steps:"));let o=t.replace(/^src\//,"@/");l(z.dim(` 1. Import actions: import { setLoading, setError } from '${o}/${e.sliceName}'`)),l(z.dim(" 2. Use in component: dispatch(setLoading(true))")),l("")};import ee from"node:path";import Qr from"picocolors";P();H();var As=e=>{e.command("test <file>").description(`Generate a sibling test file for an existing component, hook, or slice.
1201
+ 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(t,r)=>{try{let n=process.cwd(),i=ee.isAbsolute(t)?t:ee.join(n,t);l(Qr.cyan(`
1202
1202
  \u{1F9EA} Test Generator
1203
- `)),m(i)||(v(`Source file not found: ${t}`),process.exit(1));let o=await F(n);o.hasTests||(v("Testing is not installed in this project. Run `next-maker setup --tests` first."),process.exit(1));let s=await f(i),a=Vl(r.kind)??Wl(i,s);a||(v(`Could not infer test kind for ${Q.basename(i)}. Pass --kind component|hook|slice.`),process.exit(1));let p=ql(i,a),u=Xl(i,a);m(u)&&!r.force&&(v(`Test file already exists: ${Q.relative(n,u)}. Use --force to overwrite.`),process.exit(1)),y.start(`Generating ${a} test...`);let d=await oe({projectPath:n,sourceFile:i,kind:a,symbolName:p,hasRedux:o.hasRedux,hasI18n:o.hasI18n,hookUsesStore:a==="hook"&&o.hasRedux&&s.includes("useAppSelector")});y.succeed("Test generated"),l(Yr.green(`
1204
- \u2728 Test '${Q.basename(d)}' created.
1205
- `)),l(Yr.dim(` \u{1F9EA} ${Q.relative(n,d)}`)),l("")}catch(n){y.fail("Test generation failed"),v(`${n}`),process.exit(1)}})},Vl=e=>{if(!e)return null;if(e==="component"||e==="hook"||e==="slice")return e;throw new Error(`Invalid --kind: ${e}. Use component | hook | slice.`)},Wl=(e,t)=>{let r=Q.basename(e);return/\.slice\.ts$/.test(r)?"slice":/^use[A-Z]/.test(r.replace(/\.tsx?$/,""))?"hook":r.endsWith(".tsx")?"component":/createSlice\s*\(/.test(t)?"slice":/^export\s+(const|function)\s+use[A-Z]/m.test(t)?"hook":null},ql=(e,t)=>{let r=Q.basename(e).replace(/\.(tsx?|jsx?)$/i,"");return t==="slice"?j(r.replace(/\.slice$/,"")):t==="hook"?/^use[A-Z]/.test(r)?r:`use${R(r.replace(/^use-?/,""))}`:R(r)},Xl=(e,t)=>{let r=Q.dirname(e),n=Q.basename(e).replace(/\.(tsx?|jsx?)$/i,""),i=t==="component"?".tsx":".ts";return Q.join(r,`${n}.test${i}`)};var Ts=e=>{Un(e),vs(e),ss(e),Cs(e),ws(e),fs(e),ps(e),Pi(e),ms(e),cs(e),gs(e),Lo(e),ts(e),No(e),hs(e),Es(e)};var Kl=process.emitWarning;process.emitWarning=function(e,t,r,n){if(!(typeof e=="string"&&e.includes("--localstorage-file")&&e.includes("was provided without a valid path")))return Kl.apply(process,arguments)};async function Zl(){Kr({logger:t=>wt(t)});let e=new Yl;e.name("next-maker").description("Teispace Next.js Project Generator").version("1.0.0"),Ts(e),e.parse()}Zl().catch(e=>{let t=e&&typeof e=="object"&&"message"in e?e.message:String(e);wt(`Unexpected error: ${t}`)});
1203
+ `)),m(i)||(v(`Source file not found: ${t}`),process.exit(1));let o=await F(n);o.hasTests||(v("Testing is not installed in this project. Run `next-maker setup --tests` first."),process.exit(1));let s=await f(i),a=rm(r.kind)??nm(i,s);a||(v(`Could not infer test kind for ${ee.basename(i)}. Pass --kind component|hook|slice.`),process.exit(1));let p=im(i,a),u=om(i,a);m(u)&&!r.force&&(v(`Test file already exists: ${ee.relative(n,u)}. Use --force to overwrite.`),process.exit(1)),y.start(`Generating ${a} test...`);let d=await ae({projectPath:n,sourceFile:i,kind:a,symbolName:p,hasRedux:o.hasRedux,hasI18n:o.hasI18n,hookUsesStore:a==="hook"&&o.hasRedux&&s.includes("useAppSelector")});y.succeed("Test generated"),l(Qr.green(`
1204
+ \u2728 Test '${ee.basename(d)}' created.
1205
+ `)),l(Qr.dim(` \u{1F9EA} ${ee.relative(n,d)}`)),l("")}catch(n){y.fail("Test generation failed"),v(`${n}`),process.exit(1)}})},rm=e=>{if(!e)return null;if(e==="component"||e==="hook"||e==="slice")return e;throw new Error(`Invalid --kind: ${e}. Use component | hook | slice.`)},nm=(e,t)=>{let r=ee.basename(e);return/\.slice\.ts$/.test(r)?"slice":/^use[A-Z]/.test(r.replace(/\.tsx?$/,""))?"hook":r.endsWith(".tsx")?"component":/createSlice\s*\(/.test(t)?"slice":/^export\s+(const|function)\s+use[A-Z]/m.test(t)?"hook":null},im=(e,t)=>{let r=ee.basename(e).replace(/\.(tsx?|jsx?)$/i,"");return t==="slice"?j(r.replace(/\.slice$/,"")):t==="hook"?/^use[A-Z]/.test(r)?r:`use${R(r.replace(/^use-?/,""))}`:R(r)},om=(e,t)=>{let r=ee.dirname(e),n=ee.basename(e).replace(/\.(tsx?|jsx?)$/i,""),i=t==="component"?".tsx":".ts";return ee.join(r,`${n}.test${i}`)};var _s=e=>{Wn(e),Is(e),fs(e),ks(e),$s(e),Ss(e),ys(e),bi(e),Ps(e),hs(e),Es(e),Jo(e),cs(e),Do(e),Cs(e),As(e)};var am=process.emitWarning;process.emitWarning=function(e,t,r,n){if(!(typeof e=="string"&&e.includes("--localstorage-file")&&e.includes("was provided without a valid path")))return am.apply(process,arguments)};async function cm(){tn({logger:t=>St(t)});let e=new sm;e.name("next-maker").description("Teispace Next.js Project Generator").version(en.version),_s(e),e.parse()}cm().catch(e=>{let t=e&&typeof e=="object"&&"message"in e?e.message:String(e);St(`Unexpected error: ${t}`)});
1206
1206
  //# sourceMappingURL=index.js.map