@teispace/next-maker 3.0.4 → 3.0.6

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/index.js +167 -167
  3. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -1,30 +1,30 @@
1
1
  #!/usr/bin/env node
2
- var Ls=Object.defineProperty;var $e=(e,t)=>()=>(e&&(t=e(e=0)),t);var Vt=(e,t)=>{for(var r in t)Ls(e,r,{get:t[r],enumerable:!0})};import{existsSync as Wt}from"node:fs";import xe from"node:fs/promises";import cn from"node:path";var f,g,I,C,w,D,m,x=$e(()=>{"use strict";f=async e=>xe.readFile(e,"utf-8"),g=async(e,t)=>{await xe.mkdir(cn.dirname(e),{recursive:!0}),await xe.writeFile(e,t,"utf-8")},I=async(e,t)=>{await xe.mkdir(cn.dirname(t),{recursive:!0}),await xe.copyFile(e,t)},C=async e=>{Wt(e)&&await xe.unlink(e)},w=async e=>{Wt(e)&&await xe.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=>Wt(e)});var gn={};Vt(gn,{PROJECT_PATHS:()=>c});var c,S=$e(()=>{"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 En={};Vt(En,{cleanupHttpTypes:()=>Ne,injectBundleSentinel:()=>Sn,installBundleSentinelMount:()=>rr,isFileUsed:()=>wa,isStringUsed:()=>va,migrateClientUsages:()=>er,removeBundleSentinelMount:()=>Be,removeHttpExports:()=>nr,resolveBundleSentinelLayoutPath:()=>tr,rewriteSentinelImports:()=>ke,rewriteServerEntryImports:()=>Ae,stripBundleSentinel:()=>Ge,updateConfigIndex:()=>Qt,updateHttpIndex:()=>Yt,updateTypesIndex:()=>Zt,updateUtilsIndex:()=>Kt});import{execFile as ha}from"node:child_process";import k from"node:path";import{promisify as ya}from"node:util";async function Xt(e,t,r){try{let{stdout:n}=await xa("grep",[...r,"--include=*.ts","--include=*.tsx",e,t]);return n}catch(n){if(n.code===1)return"";throw n}}var xa,Yt,Kt,Zt,Qt,Ne,er,tr,Pa,Pn,wn,Sn,Ge,rr,Be,nr,wa,va,ke,Ae,vn,ze=$e(()=>{"use strict";S();x();xa=ya(ha);Yt=async(e,t)=>{let r=k.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 Hs=Object.defineProperty;var $e=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(n){throw r=[n],n}};var Jt=(e,t)=>{for(var r in t)Hs(e,r,{get:t[r],enumerable:!0})};import{existsSync as Wt}from"node:fs";import xe from"node:fs/promises";import ln from"node:path";var u,g,N,C,w,D,m,P=$e(()=>{"use strict";u=async e=>xe.readFile(e,"utf-8"),g=async(e,t)=>{await xe.mkdir(ln.dirname(e),{recursive:!0}),await xe.writeFile(e,t,"utf-8")},N=async(e,t)=>{await xe.mkdir(ln.dirname(t),{recursive:!0}),await xe.copyFile(e,t)},C=async e=>{Wt(e)&&await xe.unlink(e)},w=async e=>{Wt(e)&&await xe.rm(e,{recursive:!0,force:!0})},D=async(e,t)=>{let r=await u(e),n=JSON.parse(r),i=t(n);await g(e,JSON.stringify(i,null,2))},m=e=>Wt(e)});var yn={};Jt(yn,{PROJECT_PATHS:()=>c});var c,S=$e(()=>{"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 Tn={};Jt(Tn,{cleanupHttpTypes:()=>Ne,injectBundleSentinel:()=>Cn,installBundleSentinelMount:()=>nr,isFileUsed:()=>Ca,isStringUsed:()=>Ta,migrateClientUsages:()=>tr,removeBundleSentinelMount:()=>Be,removeHttpExports:()=>ir,resolveBundleSentinelLayoutPath:()=>rr,rewriteSentinelImports:()=>ke,rewriteServerEntryImports:()=>Ae,stripBundleSentinel:()=>He,stripSaveAuthTokens:()=>er,updateConfigIndex:()=>Qt,updateHttpIndex:()=>Yt,updateTypesIndex:()=>Zt,updateUtilsIndex:()=>Kt});import{execFile as wa}from"node:child_process";import A from"node:path";import{promisify as va}from"node:util";async function Xt(e,t,r){try{let{stdout:n}=await Sa("grep",[...r,"--include=*.ts","--include=*.tsx",e,t]);return n}catch(n){if(n.code===1)return"";throw n}}var Sa,Yt,Kt,Zt,Qt,Ne,er,tr,rr,Ea,vn,Sn,Cn,He,nr,Be,ir,Ca,Ta,ke,Ae,En,ze=$e(()=>{"use strict";S();P();Sa=va(wa);Yt=async(e,t)=>{let r=A.join(e,c.HTTP_UTILS,"index.ts");if(m(r)){let n=await u(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)}},Kt=async e=>{let t=k.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))}},Zt=async e=>{let t=k.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)}},Kt=async e=>{let t=A.join(e,c.UTILS_INDEX);if(m(t)){let r=await u(t);r.includes("./http")||(r+=`export * from './http';
5
+ `,await g(t,r))}},Zt=async e=>{let t=A.join(e,c.TYPES_INDEX);if(m(t)){let r=await u(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=k.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))}},Ne=async(e,t)=>{let r=k.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)}},Qt=async e=>{let t=A.join(e,c.CONFIG_INDEX);if(m(t)){let r=await u(t);r.includes("./app-apis")||(r+=`export * from './app-apis';
8
+ `,await g(t,r))}},Ne=async(e,t)=>{let r=A.join(e,c.HTTP_TYPES);if(m(r)){let n=await u(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))}},er=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=k.join(e,"src");try{let p=await Xt(n,a,["-r","-l"]);if(!p.trim())return;let u=p.trim().split(`
12
- `).filter(d=>d);for(let d of u){if(!m(d))continue;let h=await f(d),P=!1,O=new RegExp(`(import\\s*\\{[^}]*?)\\b${n}\\b([^}]*?\\}\\s*from\\s*['"][^'"]*?/http['"])`,"g");O.test(h)&&(h=h.replace(O,`$1${i}$2`),P=!0);let V=new RegExp(`import\\s+${n}\\s+from\\s+['"]([^'"]*?)/${o}['"]`,"g");V.test(h)&&(h=h.replace(V,`import ${i} from '$1/${s}'`),P=!0);let $=new RegExp(`\\b${n}\\b(?=\\.)`,"g");$.test(h)&&(h=h.replace($,i),P=!0);let W=new RegExp(`\\b${n}\\b(?![.\\w])`,"g");W.test(h)&&(h=h.replace(W,i),P=!0),P&&await g(d,h)}}catch(p){console.warn("Warning: Could not scan for HTTP client usages:",p)}},tr=e=>{let t=k.join(e,c.LOCALE_LAYOUT);if(m(t))return t;let r=k.join(e,c.ROOT_LAYOUT);return m(r)?r:null},Pa="// Regression sentinel \u2014 see file comment for what this guards.",Pn="import { HttpClientBundleSentinel } from '@/lib/utils/http/__bundle-sentinel__/client-bundle-sentinel';",wn="<HttpClientBundleSentinel />",Sn=e=>{if(e.includes(wn))return e;let t=e;if(!t.includes(Pn)){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}${Pa}
13
- ${Pn}
11
+ `,await g(r,n))}},er=e=>{let t=e;return t=t.replace(/\/\*\*(?:[^*]|\*(?!\/))*?\*\/\n(?=(?:export\s+)?const\s+BEARER_ALLOWED_ENVS\b)/,""),t=t.replace(/^(?:export\s+)?const\s+BEARER_ALLOWED_ENVS\s*=[\s\S]*?;\n?/m,""),t=t.replace(/^export const SAVE_AUTH_TOKENS\s*=.*;\n?/m,""),t},tr=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=await Xt(n,a,["-r","-l"]);if(!p.trim())return;let f=p.trim().split(`
12
+ `).filter(d=>d);for(let d of f){if(!m(d))continue;let h=await u(d),x=!1,R=new RegExp(`(import\\s*\\{[^}]*?)\\b${n}\\b([^}]*?\\}\\s*from\\s*['"][^'"]*?/http['"])`,"g");R.test(h)&&(h=h.replace(R,`$1${i}$2`),x=!0);let L=new RegExp(`import\\s+${n}\\s+from\\s+['"]([^'"]*?)/${o}['"]`,"g");L.test(h)&&(h=h.replace(L,`import ${i} from '$1/${s}'`),x=!0);let $=new RegExp(`\\b${n}\\b(?=\\.)`,"g");$.test(h)&&(h=h.replace($,i),x=!0);let W=new RegExp(`\\b${n}\\b(?![.\\w])`,"g");W.test(h)&&(h=h.replace(W,i),x=!0),x&&await g(d,h)}}catch(p){console.warn("Warning: Could not scan for HTTP client usages:",p)}},rr=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},Ea="// Regression sentinel \u2014 see file comment for what this guards.",vn="import { HttpClientBundleSentinel } from '@/lib/utils/http/__bundle-sentinel__/client-bundle-sentinel';",Sn="<HttpClientBundleSentinel />",Cn=e=>{if(e.includes(Sn))return e;let t=e;if(!t.includes(vn)){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}${Ea}
13
+ ${vn}
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}${wn}
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},rr=async e=>{let t=tr(e);if(!t)return;let r=await f(t),n=Sn(r);n!==r&&await g(t,n)},Be=async e=>{let t=tr(e);if(!t)return;let r=await f(t),n=Ge(r);n!==r&&await g(t,n)},nr=async e=>{let t=k.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=k.join(e,c.TYPES_INDEX);if(m(r)){let n=await f(r),i=k.join(e,c.COMMON_TYPES_DIR);if(!m(i))n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/common['"];?.*$/gm,"");else{let o=k.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(k.join(e,c.UTILITY_TYPES_DIR))||(n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/utility['"];?.*$/gm,"")),await g(r,n)}},wa=async(e,t,r=[])=>{let n=k.join(e,"src"),o=`from ['"].*${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}.*['"]`;try{let s=await Xt(o,n,["-r","-E"]);return s.trim()?s.trim().split(`
17
- `).filter(u=>{let[d]=u.split(":"),h=k.resolve(e,d);return!r.some(P=>!!(h===P||h.startsWith(P+k.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for ${t}:`,s),!0}},va=async(e,t,r=[])=>{let n=k.join(e,"src");try{let i=await Xt(t,n,["-r","-F"]);return i.trim()?i.trim().split(`
18
- `).filter(a=>{let[p]=a.split(":"),u=k.resolve(e,p);return!r.some(d=>!!(u===d||u.startsWith(d+k.sep)))}).length>0:!1}catch(i){return console.warn(`Warning: Failed to check usage for string ${t}:`,i),!0}},ke=async(e,t)=>{let r=k.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}${Sn}
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},nr=async e=>{let t=rr(e);if(!t)return;let r=await u(t),n=Cn(r);n!==r&&await g(t,n)},Be=async e=>{let t=rr(e);if(!t)return;let r=await u(t),n=He(r);n!==r&&await g(t,n)},ir=async e=>{let t=A.join(e,c.UTILS_INDEX);if(m(t)){let n=await u(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 u(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 u(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)}},Ca=async(e,t,r=[])=>{let n=A.join(e,"src"),o=`from ['"].*${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}.*['"]`;try{let s=await Xt(o,n,["-r","-E"]);return s.trim()?s.trim().split(`
17
+ `).filter(f=>{let[d]=f.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}},Ta=async(e,t,r=[])=>{let n=A.join(e,"src");try{let i=await Xt(t,n,["-r","-F"]);return i.trim()?i.trim().split(`
18
+ `).filter(a=>{let[p]=a.split(":"),f=A.resolve(e,p);return!r.some(d=>!!(f===d||f.startsWith(d+A.sep)))}).length>0:!1}catch(i){return console.warn(`Warning: Failed to check usage for string ${t}:`,i),!0}},ke=async(e,t)=>{let r=A.join(e,c.HTTP_BUNDLE_SENTINEL_FILE);if(!m(r))return;let n=await u(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)},Ae=async(e,t)=>{let r=k.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=vn(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=vn(n,"createFetchClient")),n=n.replace(/\n{3,}/g,`
24
+ };`),await g(r,n)},Ae=async(e,t)=>{let r=A.join(e,c.HTTP_SERVER_FILE);if(!m(r)||t.length===0)return;let n=await u(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=En(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=En(n,"createFetchClient")),n=n.replace(/\n{3,}/g,`
25
25
 
26
- `),await g(r,n)},vn=(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 mc}from"node:fs";import{access as dc}from"node:fs/promises";import Qn from"node:path";var de,Pt,ei=$e(()=>{"use strict";de=async(e,t,r)=>{try{return await dc(Qn.join(e,r,t)),!0}catch{return!1}},Pt=(e,t,r)=>mc(Qn.join(e,t,r))});import{access as wt,readFile as uc}from"node:fs/promises";import Xe from"node:path";var F,ti=$e(()=>{"use strict";F=async e=>{try{let t=Xe.join(e,"package.json"),r=await uc(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 wt(u)}catch{a=!1}let d=Xe.join(e,"src","lib","utils","http","fetch-client");try{await wt(d),p=!0}catch{p=!1}let h;a&&p?h="both":a?h="axios":p?h="fetch":h="none";let P=!!i.vitest;if(!P)try{await wt(Xe.join(e,"vitest.config.ts")),P=!0}catch{}let O="none";if(i["socket.io-client"])try{await wt(Xe.join(e,"src","lib","utils","ws")),O="present"}catch{}return{hasRedux:o,httpClient:h,hasI18n:s,hasTests:P,ws:O}}catch(t){throw new Error(`Failed to detect project setup: ${t}`,{cause:t})}}});var Ye={};Vt(Ye,{detectProjectSetup:()=>F,directoryExists:()=>de,fileExistsAt:()=>Pt});var G=$e(()=>{"use strict";ei();ti()});import{Command as dm}from"commander";var rn={name:"@teispace/next-maker",version:"3.0.4",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"],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",start:"node dist/index.js",dev:"tsx --watch src/index.ts",test:"vitest run","test:watch":"vitest","test:cov":"vitest run --coverage","type-check":"tsc --noEmit",clean:"rm -rf dist",prepublishOnly:"yarn clean && yarn build"},dependencies:{commander:"^15.0.0",degit:"^3.4.7",enquirer:"^2.4.1",ora:"^9.4.0",picocolors:"^1.1.1","png-to-ico":"^3.0.1",sharp:"^0.35.2"},devDependencies:{"@types/degit":"^2.8.6","@types/node":"^26.0.0",esbuild:"^0.28.0",tsx:"^4.22.4",typescript:"^6.0.3",vitest:"^4.1.9"},engines:{node:">=24.0.0"},publishConfig:{access:"public",registry:"https://registry.npmjs.org/"}};import sr from"node:path";import X from"picocolors";var Me=new Set;function nn(e){return Me.add(e),()=>Me.delete(e)}function on(e){let{logger:t=p=>console.error(p),exitOnCancel:r=process.env.NODE_ENV!=="test"}=e??{},n=!1,i=async()=>{let p=[...Me];Me.clear();for(let u of p)try{await u()}catch(d){t(`Cleanup failed: ${d instanceof Error?d.message:String(d)}`)}},o=()=>{if(n){r&&process.exit(130);return}n=!0;let p=Me.size>0;i().then(()=>{console.log(""),t("Setup cancelled by user"),console.log(""),r&&process.exit(p?130:0)})},s=p=>{if(p!==null&&typeof p=="object"&&"code"in p&&p.code==="ERR_USE_AFTER_CLOSE"){o();return}if(p instanceof Error){t(`Uncaught exception: ${p.message}`);return}t(`Uncaught exception: ${String(p)}`)},a=p=>{if(p instanceof Error){t(`Unhandled promise rejection: ${p.message}`);return}t(`Unhandled promise rejection: ${String(p)}`)};return process.on("SIGINT",o),process.on("SIGTERM",o),process.on("uncaughtException",s),process.on("unhandledRejection",a),()=>{process.off("SIGINT",o),process.off("SIGTERM",o),process.off("uncaughtException",s),process.off("unhandledRejection",a)}}import te from"picocolors";var Us={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=Us[t]??(n=>n);console.log(r(e))}function dt(e){pe(`\u2716 ${e}`,"red")}var v=dt;function sn(e){pe(`\u26A0 ${e}`,"yellow")}function l(e){pe(e)}function an(){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 Hs from"ora";function b(e="",t){let r=Hs({text:e,...t});return r.start(),r}var Gs=e=>e.charAt(0).toUpperCase()+e.slice(1),j=e=>e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase()),R=e=>Gs(j(e));import Bs from"ora";var y=Bs();x();import{execFile as zs}from"node:child_process";import{promisify as Js}from"node:util";var Vs=Js(zs),se=(e,t)=>Vs("git",e,t?{cwd:t}:void 0);function Ws(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 pn=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&&(Ws(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{execFile as qs}from"node:child_process";import{promisify as Xs}from"node:util";var Ys=Xs(qs),Ue=(e,t,r)=>Ys(e,t,{cwd:r}),ln=async(e,t)=>{try{await Ue(t,["install"],e)}catch(r){throw new Error(`Failed to install dependencies with ${t}: ${r}`,{cause:r})}},J=async(e,t,r)=>{let n=t==="npm"?["run",r]:[r];try{await Ue(t,n,e)}catch(i){console.warn(`Warning: Failed to run script '${r}': ${i}`)}},Ks=()=>{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"},N=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":Ks()},Zs=async(e,t,r)=>{if(r.length!==0)try{await Ue(t,[...mn(t),...r],e)}catch(n){throw new Error(`Failed to install packages with ${t}: ${n}`,{cause:n})}},mn=e=>{switch(e){case"npm":return["install"];case"yarn":return["add"];case"pnpm":return["add"];case"bun":return["add"];default:return["install"]}},U=async(e,t)=>{let r=await N(e);await Zs(e,r,[t])},Qs=e=>{switch(e){case"npm":return"--save-dev";case"yarn":case"pnpm":case"bun":return"-D";default:return"--save-dev"}},Pe=async(e,t,r)=>{if(r.length!==0)try{await Ue(t,[...mn(t),Qs(t),...r],e)}catch(n){throw new Error(`Failed to install dev packages with ${t}: ${n}`,{cause:n})}},ut=async(e,t)=>{let r=await N(e);await Pe(e,r,[t])},qt=async(e,t,r)=>{if(r.length!==0)try{await Ue(t,[...ea(t),...r],e)}catch(n){throw new Error(`Failed to uninstall packages with ${t}: ${n}`,{cause:n})}},ea=e=>{switch(e){case"npm":return["uninstall"];case"yarn":return["remove"];case"pnpm":return["remove"];case"bun":return["remove"];default:return["uninstall"]}},Ie=async(e,t)=>{let r=await N(e);await qt(e,r,[t])};import ta from"enquirer";var ra=/^[a-z0-9-_]+$/,na=/^\d+\.\d+\.\d+$/,dn=e=>ra.test(e),ia=e=>na.test(e),un=(e,t={})=>{let r=t.projectName??e??"my-app";if(!dn(r))throw new Error(`Invalid project name "${r}". Use lowercase letters, digits, hyphens, and underscores only.`);let n=t.version??"0.1.0";if(!ia(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:oa}=ta,fn=async e=>{if(e!==void 0&&!dn(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 oa([{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};x();import sa from"node:path";var le=async(e,t)=>{let r=aa(t);await g(sa.join(e,"test/test-utils.tsx"),r)},aa=({redux:e,i18n:t})=>e&&t?ca:e?pa:t?la:ma,ca=`import { type RenderOptions, render } from '@testing-library/react';
26
+ `),await g(r,n)},En=(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 gc}from"node:fs";import{access as hc}from"node:fs/promises";import ti from"node:path";var ue,Pt,ri=$e(()=>{"use strict";ue=async(e,t,r)=>{try{return await hc(ti.join(e,r,t)),!0}catch{return!1}},Pt=(e,t,r)=>gc(ti.join(e,t,r))});import{access as wt,readFile as yc}from"node:fs/promises";import Xe from"node:path";var F,ni=$e(()=>{"use strict";F=async e=>{try{let t=Xe.join(e,"package.json"),r=await yc(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,f=Xe.join(e,"src","lib","utils","http","axios-client");try{await wt(f)}catch{a=!1}let d=Xe.join(e,"src","lib","utils","http","fetch-client");try{await wt(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 wt(Xe.join(e,"vitest.config.ts")),x=!0}catch{}let R="none";if(i["socket.io-client"])try{await wt(Xe.join(e,"src","lib","utils","ws")),R="present"}catch{}return{hasRedux:o,httpClient:h,hasI18n:s,hasTests:x,ws:R}}catch(t){throw new Error(`Failed to detect project setup: ${t}`,{cause:t})}}});var Ye={};Jt(Ye,{detectProjectSetup:()=>F,directoryExists:()=>ue,fileExistsAt:()=>Pt});var B=$e(()=>{"use strict";ri();ni()});import{Command as ym}from"commander";var on={name:"@teispace/next-maker",version:"3.0.6",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"],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",start:"node dist/index.js",dev:"tsx --watch src/index.ts",test:"vitest run","test:watch":"vitest","test:cov":"vitest run --coverage","type-check":"tsc --noEmit",clean:"rm -rf dist",prepublishOnly:"yarn clean && yarn build"},dependencies:{commander:"^15.0.0",degit:"^3.4.7",enquirer:"^2.4.1",ora:"^9.4.1",picocolors:"^1.1.1","png-to-ico":"^3.0.1",sharp:"^0.35.2"},devDependencies:{"@types/degit":"^2.8.6","@types/node":"^26.0.1",esbuild:"^0.28.1",tsx:"^4.22.4",typescript:"^6.0.3",vitest:"^4.1.9"},engines:{node:">=24.0.0"},publishConfig:{access:"public",registry:"https://registry.npmjs.org/"}};import ar from"node:path";import X from"picocolors";var Me=new Set;function sn(e){return Me.add(e),()=>Me.delete(e)}function an(e){let{logger:t=p=>console.error(p),exitOnCancel:r=process.env.NODE_ENV!=="test"}=e??{},n=!1,i=async()=>{let p=[...Me];Me.clear();for(let f of p)try{await f()}catch(d){t(`Cleanup failed: ${d instanceof Error?d.message:String(d)}`)}},o=()=>{if(n){r&&process.exit(130);return}n=!0;let p=Me.size>0;i().then(()=>{console.log(""),t("Setup cancelled by user"),console.log(""),r&&process.exit(p?130:0)})},s=p=>{if(p!==null&&typeof p=="object"&&"code"in p&&p.code==="ERR_USE_AFTER_CLOSE"){o();return}if(p instanceof Error){t(`Uncaught exception: ${p.message}`);return}t(`Uncaught exception: ${String(p)}`)},a=p=>{if(p instanceof Error){t(`Unhandled promise rejection: ${p.message}`);return}t(`Unhandled promise rejection: ${String(p)}`)};return process.on("SIGINT",o),process.on("SIGTERM",o),process.on("uncaughtException",s),process.on("unhandledRejection",a),()=>{process.off("SIGINT",o),process.off("SIGTERM",o),process.off("uncaughtException",s),process.off("unhandledRejection",a)}}import te from"picocolors";var zs={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 le(e,t="reset"){let r=zs[t]??(n=>n);console.log(r(e))}function dt(e){le(`\u2716 ${e}`,"red")}var v=dt;function cn(e){le(`\u26A0 ${e}`,"yellow")}function l(e){le(e)}function pn(){console.log(""),le("\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"),le("\u2551 \u2551","cyan"),le("\u2551 \u{1F680} Create Teispace Next.js App \u{1F680} \u2551","cyan"),le("\u2551 \u2551","cyan"),le("\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 Vs from"ora";function b(e="",t){let r=Vs({text:e,...t});return r.start(),r}var Js=e=>e.charAt(0).toUpperCase()+e.slice(1),j=e=>e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase()),I=e=>Js(j(e));import Ws from"ora";var y=Ws();P();import{execFile as qs}from"node:child_process";import{promisify as Xs}from"node:util";var Ys=Xs(qs),se=(e,t)=>Ys("git",e,t?{cwd:t}:void 0);function Ks(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 mn=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&&(Ks(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{execFile as Zs}from"node:child_process";import{promisify as Qs}from"node:util";var ea=Qs(Zs),Ge=(e,t,r)=>ea(e,t,{cwd:r}),dn=async(e,t)=>{try{await Ge(t,["install"],e)}catch(r){throw new Error(`Failed to install dependencies with ${t}: ${r}`,{cause:r})}},J=async(e,t,r)=>{let n=t==="npm"?["run",r]:[r];try{await Ge(t,n,e)}catch(i){console.warn(`Warning: Failed to run script '${r}': ${i}`)}},ta=()=>{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":ta()},ra=async(e,t,r)=>{if(r.length!==0)try{await Ge(t,[...un(t),...r],e)}catch(n){throw new Error(`Failed to install packages with ${t}: ${n}`,{cause:n})}},un=e=>{switch(e){case"npm":return["install"];case"yarn":return["add"];case"pnpm":return["add"];case"bun":return["add"];default:return["install"]}},U=async(e,t)=>{let r=await k(e);await ra(e,r,[t])},na=e=>{switch(e){case"npm":return"--save-dev";case"yarn":case"pnpm":case"bun":return"-D";default:return"--save-dev"}},Pe=async(e,t,r)=>{if(r.length!==0)try{await Ge(t,[...un(t),na(t),...r],e)}catch(n){throw new Error(`Failed to install dev packages with ${t}: ${n}`,{cause:n})}},ut=async(e,t)=>{let r=await k(e);await Pe(e,r,[t])},qt=async(e,t,r)=>{if(r.length!==0)try{await Ge(t,[...ia(t),...r],e)}catch(n){throw new Error(`Failed to uninstall packages with ${t}: ${n}`,{cause:n})}},ia=e=>{switch(e){case"npm":return["uninstall"];case"yarn":return["remove"];case"pnpm":return["remove"];case"bun":return["remove"];default:return["uninstall"]}},Ie=async(e,t)=>{let r=await k(e);await qt(e,r,[t])};import oa from"enquirer";var sa=/^[a-z0-9-_]+$/,aa=/^\d+\.\d+\.\d+$/,fn=e=>sa.test(e),ca=e=>aa.test(e),gn=(e,t={})=>{let r=t.projectName??e??"my-app";if(!fn(r))throw new Error(`Invalid project name "${r}". Use lowercase letters, digits, hyphens, and underscores only.`);let n=t.version??"0.1.0";if(!ca(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:pa}=oa,hn=async e=>{if(e!==void 0&&!fn(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 pa([{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 la from"node:path";var me=async(e,t)=>{let r=ma(t);await g(la.join(e,"test/test-utils.tsx"),r)},ma=({redux:e,i18n:t})=>e&&t?da:e?ua:t?fa:ga,da=`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
- `,pa=`import { type RenderOptions, render } from '@testing-library/react';
88
+ `,ua=`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
- `,la=`import { type RenderOptions, render } from '@testing-library/react';
127
+ `,fa=`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
- `,ma=`import { type RenderOptions, render } from '@testing-library/react';
167
+ `,ga=`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 hn 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();x();var yn=async(e,t)=>{if(t.bundleAnalyzer)return;let r=hn.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(hn.join(e,c.PACKAGE_JSON),n=>(n.devDependencies&&delete n.devDependencies[T.NEXT_BUNDLE_ANALYZER],n.scripts&&delete n.scripts.analyze,n))};S();x();import He from"node:path";var xn=async(e,t)=>{t.darkMode||(await C(He.join(e,c.THEME_PROVIDER)),await da(e),await ua(e),await ga(e))},da=async e=>{let t=He.join(e,c.PROVIDERS_INDEX),r=await f(t);r=r.replace(/export \* from '\.\/CustomThemeProvider';\n/,""),await g(t,r)},ua=async e=>{let t=He.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)}},fa=e=>e.replace(/\bbg-light\b\s?/g,"").replace(/\bdark:bg-dark\b\s?/g,"").replace(/\s{2,}/g," ").replace(/suppressHydrationWarning=\{true\}/g,""),ga=async e=>{let t=[He.join(e,c.ROOT_LAYOUT),He.join(e,"src/app/[locale]/layout.tsx")];for(let r of t)if(m(r)){let n=await f(r),i=fa(n);i!==n&&await g(r,i)}};S();x();ze();import A from"node:path";var Cn=async(e,t)=>{let r=A.join(e,c.HTTP_UTILS),n=t.httpClient!=="none"||!!t.reactSecureStorage;t.httpClient==="none"?(await Be(e),await Sa(e,r,n)):t.httpClient==="axios"?(await Ea(e,r),await ke(e,["axios"]),await Ae(e,["axios"])):t.httpClient==="fetch"?(await Ca(e,r),await ke(e,["fetch"]),await Ae(e,["fetch"])):t.httpClient},Sa=async(e,t,r)=>{await w(A.join(e,c.AXIOS_CLIENT)),await w(A.join(e,c.FETCH_CLIENT)),r?(await g(A.join(t,"index.ts"),`export * from './token-store';
190
- `),await C(A.join(e,c.CLIENT_UTILS)),await Ne(e,[])):(await w(t),await Ta(e),await C(A.join(e,c.APP_APIS)),await ba(e)),await Ra(e),await w(A.join(e,c.ERRORS_DIR)),r||(await w(A.join(e,c.COMMON_TYPES_DIR)),await w(A.join(e,c.UTILITY_TYPES_DIR)),await $a(e))},Ea=async(e,t)=>{await w(A.join(e,c.FETCH_CLIENT));let r=await f(A.join(t,"index.ts"));r=r.replace(/export .* from '\.\/fetch-client';\n/g,""),await g(A.join(t,"index.ts"),r);let n=A.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)}},Ca=async(e,t)=>{await w(A.join(e,c.AXIOS_CLIENT));let r=await f(A.join(t,"index.ts"));r=r.replace(/export .* from '\.\/axios-client';\n/g,""),await g(A.join(t,"index.ts"),r),await Ne(e,["fetch"]);let n=A.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)}},Ta=async e=>{let t=A.join(e,c.UTILS_INDEX);if(m(t)){let r=await f(t);r=r.replace(/export \* from '\.\/http';\n/,""),await g(t,r)}},ba=async e=>{let t=A.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)}},Ra=async e=>{let t=A.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)}},$a=async e=>{let t=A.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();x();import q from"node:path";var Tn=async(e,t)=>{t.i18n||(await Na(e),await ka(e),await Aa(e),await _a(e),await Ia(e))},Ia=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)},Na=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))},ka=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)}},Aa=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();x();import me from"node:path";var bn=async(e,t)=>{t.httpClient!=="none"||t.reactSecureStorage||await w(me.join(e,c.STORAGE_SERVICE))},Rn=async e=>{await C(me.join(e,c.LICENSE))},$n=async e=>{await C(me.join(e,c.CHANGELOG))},In=async e=>{await C(me.join(e,c.NVM_RC)),await C(me.join(e,c.NPM_RC))},Nn=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 kn from"node:path";S();x();var An=async(e,t)=>{if(t.reactCompiler)return;let r=kn.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(kn.join(e,c.PACKAGE_JSON),n=>(n.devDependencies&&delete n.devDependencies[T.REACT_COMPILER_BABEL],n))};S();x();import we from"node:path";var _n=async(e,t)=>{t.redux||(await w(we.join(e,c.STORE)),await w(we.join(e,c.COUNTER_FEATURE)),await C(we.join(e,c.STORE_PROVIDER)),await C(we.join(e,"test/test-utils.tsx")),await Oa(e),await Fa(e))},Oa=async e=>{let t=we.join(e,c.PROVIDERS_INDEX),r=await f(t);r=r.replace(/export \* from '\.\/StoreProvider';\n/,""),await g(t,r)},Fa=async e=>{let t=[we.join(e,c.ROOT_PAGE),we.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();x();import On from"node:path";var Fn=async(e,t)=>{if(t.i18n)return;let r=On.join(e,c.SEO_FILE);m(r)&&await g(r,ja);let n=On.join(e,c.SITEMAP_FILE);m(n)&&await g(n,Da)},ja=`import type { Metadata } from 'next';
189
+ `;import xn 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=xn.join(e,c.NEXT_CONFIG);if(m(r)){let n=await u(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(xn.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 wn=async(e,t)=>{t.darkMode||(await C(Ue.join(e,c.THEME_PROVIDER)),await ha(e),await ya(e),await Pa(e))},ha=async e=>{let t=Ue.join(e,c.PROVIDERS_INDEX),r=await u(t);r=r.replace(/export \* from '\.\/CustomThemeProvider';\n/,""),await g(t,r)},ya=async e=>{let t=Ue.join(e,c.GLOBALS_CSS);if(m(t)){let r=await u(t);r=r.replace(/@custom-variant dark \(.*?\);\n\n/,""),r=r.replace(/@theme \{[\s\S]*?\}\n/,""),await g(t,r)}},xa=e=>e.replace(/\bbg-light\b\s?/g,"").replace(/\bdark:bg-dark\b\s?/g,"").replace(/\s{2,}/g," ").replace(/suppressHydrationWarning=\{true\}/g,""),Pa=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 u(r),i=xa(n);i!==n&&await g(r,i)}};S();P();ze();import _ from"node:path";var bn=async(e,t)=>{let r=_.join(e,c.HTTP_UTILS),n=t.httpClient!=="none"||!!t.reactSecureStorage;t.httpClient==="none"?(await Be(e),await ba(e,r,n)):t.httpClient==="axios"?(await Ra(e,r),await ke(e,["axios"]),await Ae(e,["axios"])):t.httpClient==="fetch"?(await $a(e,r),await ke(e,["fetch"]),await Ae(e,["fetch"])):t.httpClient},ba=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 Ne(e,[])):(await w(t),await Ia(e),await C(_.join(e,c.APP_APIS)),await Na(e)),await ka(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 Aa(e))},Ra=async(e,t)=>{await w(_.join(e,c.FETCH_CLIENT));let r=await u(_.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 u(n);i=i.replace(/export interface FetchClientOptions \{[\s\S]*?\}\n\n/,""),i=i.replace(/export interface ExtendedRequestInit extends RequestInit \{[\s\S]*?\}\n\n/,""),await g(n,i)}},$a=async(e,t)=>{await w(_.join(e,c.AXIOS_CLIENT));let r=await u(_.join(t,"index.ts"));r=r.replace(/export .* from '\.\/axios-client';\n/g,""),await g(_.join(t,"index.ts"),r),await Ne(e,["fetch"]);let n=_.join(e,c.HTTP_TYPES);if(m(n)){let i=await u(n);i=i.replace(/export interface AxiosClientOptions \{[\s\S]*?\}\n\n/,""),await g(n,i)}},Ia=async e=>{let t=_.join(e,c.UTILS_INDEX);if(m(t)){let r=await u(t);r=r.replace(/export \* from '\.\/http';\n/,""),await g(t,r)}},Na=async e=>{let t=_.join(e,c.CONFIG_INDEX);if(m(t)){let r=await u(t);r=r.replace(/export \* from '\.\/app-apis';\n/,""),await g(t,r)}},ka=async e=>{let t=_.join(e,c.CONSTANTS);if(m(t)){let r=await u(t);r=r.replace(/export const API_RESPONSE_DATA_KEY = 'data';\n/,""),r=er(r),await g(t,r)}},Aa=async e=>{let t=_.join(e,c.TYPES_INDEX);if(m(t)){let r=await u(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 Rn=async(e,t)=>{t.i18n||(await Oa(e),await Fa(e),await ja(e),await Da(e),await _a(e))},_a=async e=>{let t=q.join(e,c.ENV_EXAMPLE);if(!m(t))return;let r=await u(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)},Oa=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))},Fa=async e=>{let t=q.join(e,c.TYPES_INDEX);if(m(t)){let n=await u(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 u(r);n=n.replace(/export \* from '\.\/app-locales';\n/,""),await g(r,n)}},ja=async e=>{let t=q.join(e,c.NEXT_CONFIG);if(m(t)){let r=await u(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)}},Da=async e=>{let t=q.join(e,c.COUNTER_COMPONENT);if(m(t)){let i=await u(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 de from"node:path";var $n=async(e,t)=>{t.httpClient!=="none"||t.reactSecureStorage||await w(de.join(e,c.STORAGE_SERVICE))},In=async e=>{await C(de.join(e,c.LICENSE))},Nn=async e=>{await C(de.join(e,c.CHANGELOG))},kn=async e=>{await C(de.join(e,c.NVM_RC)),await C(de.join(e,c.NPM_RC))},An=async e=>{await w(de.join(e,c.CLAUDE_DIR)),await w(de.join(e,c.DOCS_DIR)),await w(de.join(e,c.VSCODE_DIR))};import _n from"node:path";S();P();var On=async(e,t)=>{if(t.reactCompiler)return;let r=_n.join(e,c.NEXT_CONFIG);if(m(r)){let n=await u(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 we from"node:path";var Fn=async(e,t)=>{t.redux||(await w(we.join(e,c.STORE)),await w(we.join(e,c.COUNTER_FEATURE)),await C(we.join(e,c.STORE_PROVIDER)),await C(we.join(e,"test/test-utils.tsx")),await La(e),await Ma(e))},La=async e=>{let t=we.join(e,c.PROVIDERS_INDEX),r=await u(t);r=r.replace(/export \* from '\.\/StoreProvider';\n/,""),await g(t,r)},Ma=async e=>{let t=[we.join(e,c.ROOT_PAGE),we.join(e,c.LOCALE_PAGE)];for(let r of t)if(m(r)){let n=await u(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 jn from"node:path";var Dn=async(e,t)=>{if(t.i18n)return;let r=jn.join(e,c.SEO_FILE);m(r)&&await g(r,Ga);let n=jn.join(e,c.SITEMAP_FILE);m(n)&&await g(n,Ua)},Ga=`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
- `,Da=`import type { MetadataRoute } from 'next';
257
+ `,Ua=`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 ft from"node:path";S();x();var La=[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],jn=async(e,t)=>{t.tests||(await C(ft.join(e,c.VITEST_CONFIG)),await w(ft.join(e,c.TEST_DIR)),await C(ft.join(e,"src/features/counter/components/Counter.test.tsx")),await D(ft.join(e,c.PACKAGE_JSON),r=>{if(r.devDependencies)for(let n of La)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();x();import We from"node:path";S();x();import Dn from"node:path";import{readFile as Ma,writeFile as Ua}from"node:fs/promises";import Ha 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+`
273
+ `;import ft from"node:path";S();P();var Ha=[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],Ln=async(e,t)=>{t.tests||(await C(ft.join(e,c.VITEST_CONFIG)),await w(ft.join(e,c.TEST_DIR)),await C(ft.join(e,"src/features/counter/components/Counter.test.tsx")),await D(ft.join(e,c.PACKAGE_JSON),r=>{if(r.devDependencies)for(let n of Ha)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 Mn from"node:path";import{readFile as Ba,writeFile as za}from"node:fs/promises";import Va from"node:path";var Ve=(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}`},ir=(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}`},or=(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
- })`)},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()}
277
+ })`)},Je=(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 ve=async e=>{let{projectPath:t,name:r,persist:n,importPath:i}=e,o=Ha.join(t,"src","store","rootReducer.ts");try{let s=await Ma(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 P=n?`persistReducer(${u}, ${p})`:p;s=ir(s,a,P),await Ua(o,s)}catch(s){throw new Error(`Failed to register reducer '${r}' in rootReducer: ${s}`,{cause:s})}};var Ln="import { attachWsBridge, wsClient } from '@/lib/utils/ws';",Ga=`
279
+ ${i}`};var ve=async e=>{let{projectPath:t,name:r,persist:n,importPath:i}=e,o=Va.join(t,"src","store","rootReducer.ts");try{let s=await Ba(o,"utf-8"),a=j(r),p=`${a}Reducer`,f=`${a}PersistConfig`,d=i.replace(/^src\//,"@/"),h=n?`import { ${p}, ${f} } from '${d}';`:`import { ${p} } from '${d}';`;s=Ve(s,h);let x=n?`persistReducer(${f}, ${p})`:p;s=or(s,a,x),await za(o,s)}catch(s){throw new Error(`Failed to register reducer '${r}' in rootReducer: ${s}`,{cause:s})}};var Gn="import { attachWsBridge, wsClient } from '@/lib/utils/ws';",Ja=`
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 ve=async e=>{let{projectPath:t,name:r,persist:n,importPath:i}=e,o=Ha.
286
286
  if (!store) return;
287
287
  return attachWsBridge(wsClient, store.dispatch);
288
288
  }, []);
289
- `,Mn=async e=>{await ve({projectPath:e,name:"ws",persist:!1,importPath:"src/store/slices/ws.slice"})},Ba=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)}${Ln}
290
- ${t.slice(i)}`,t=Wa(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
- ${Ga.trimEnd()}
292
- `),t},gt=e=>{let t=e;return t=t.replace(new RegExp(`${qa(Ln)}\\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=za(t)),t},za=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)},Un=async e=>{let t=Dn.join(e,c.STORE_PROVIDER);if(!m(t))return;let r=await f(t),n=Ba(r);n!==r&&await g(t,n)};var Hn=async e=>{let t=Dn.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+=Ja,n=!0),r.includes("vi.mock('server-only'")||(r+=Va,n=!0),n&&await g(t,r)},Ja=`
289
+ `,Un=async e=>{await ve({projectPath:e,name:"ws",persist:!1,importPath:"src/store/slices/ws.slice"})},Wa=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)}${Gn}
290
+ ${t.slice(i)}`,t=Ka(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
+ ${Ja.trimEnd()}
292
+ `),t},gt=e=>{let t=e;return t=t.replace(new RegExp(`${Za(Gn)}\\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=qa(t)),t},qa=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)},Hn=async e=>{let t=Mn.join(e,c.STORE_PROVIDER);if(!m(t))return;let r=await u(t),n=Wa(r);n!==r&&await g(t,n)};var Bn=async e=>{let t=Mn.join(e,c.TEST_SETUP_FILE);if(!m(t))return;let r=await u(t),n=!1;r.includes("vi.mock('react-secure-storage'")||(r+=Xa,n=!0),r.includes("vi.mock('server-only'")||(r+=Ya,n=!0),n&&await g(t,r)},Xa=`
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
- `,Va=`
311
+ `,Ya=`
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
- `,Wa=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)},qa=e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),ht=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 Gn=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 Xa(e),await Ya(e)),await Ka(e))},Xa=async e=>{let t=We.join(e,c.ROOT_REDUCER);if(!m(t))return;let r=await f(t),n=ht(r);n!==r&&await g(t,n)},Ya=async e=>{let t=We.join(e,c.STORE_PROVIDER);if(!m(t))return;let r=await f(t),n=gt(r);n!==r&&await g(t,n)},Ka=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 Ie(e,"socket.io-client")};var Bn=async(e,t)=>{let r=b("Customizing features...");try{await Cn(e,t),await bn(e,t),await Gn(e,t),await _n(e,t),await xn(e,t),await yn(e,t),await Tn(e,t),await Fn(e,t),await An(e,t),await jn(e,t),await Rn(e),await $n(e),await In(e),await Nn(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 Za from"node:path";S();x();var zn=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(Za.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 Jn}from"node:fs/promises";import _ from"node:path";S();x();var Vn=async(e,t)=>{await Qa(e,t),await ec(e,t),await tc(e,t),await rc(e,t),await nc(e,t),await ic(e,t),await oc(e,t)},Qa=async(e,t)=>{t.preCommitHooks||(await w(_.join(e,c.HUSKY_DIR)),await C(_.join(e,c.COMMITLINT_CONFIG)),await C(_.join(e,c.LINTSTAGED_RC)),await D(_.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)))},ec=async(e,t)=>{t.commitizen||(await C(_.join(e,c.CZRC)),await D(_.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)))},tc=async(e,t)=>{t.ci||await w(_.join(e,c.GITHUB_WORKFLOWS))},rc=async(e,t)=>{let r=_.join(e,c.GITHUB_DIR);if(!t.keepTemplates)await w(_.join(r,c.GITHUB_ISSUE_TEMPLATE)),await C(_.join(r,c.GITHUB_PR_TEMPLATE));else{let n=_.join(r,c.GITHUB_ISSUE_TEMPLATE),i=_.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 Jn(n);for(let a of s){let p=_.join(n,a),u=await f(p);u=o(u),await g(p,u)}}}catch{}}},nc=async(e,t)=>{let r=[c.CODE_OF_CONDUCT,c.CONTRIBUTING,c.SECURITY];for(let n of r)t.communityFiles.includes(n)||await C(_.join(e,n))},ic=async(e,t)=>{if(t.docker){let r=_.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(_.join(e,c.DOCKERFILE)),await C(_.join(e,c.DOCKER_COMPOSE)),await C(_.join(e,c.DOCKERIGNORE));let r=_.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)}}},oc=async(e,t)=>{let r=async o=>{let s=await Jn(o,{withFileTypes:!0}),a=[];for(let p of s){let u=_.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=_.join(e,c.README);for(let o of n)o!==i&&await C(o);if(t.readme){let o=`# ${t.projectName}
318
+ `,Ka=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)},Za=e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),ht=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 zn=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 Qa(e),await ec(e)),await tc(e))},Qa=async e=>{let t=We.join(e,c.ROOT_REDUCER);if(!m(t))return;let r=await u(t),n=ht(r);n!==r&&await g(t,n)},ec=async e=>{let t=We.join(e,c.STORE_PROVIDER);if(!m(t))return;let r=await u(t),n=gt(r);n!==r&&await g(t,n)},tc=async e=>{let t=We.join(e,c.PACKAGE_JSON);if(!m(t))return;let r=JSON.parse(await u(t));({...r.dependencies,...r.devDependencies})["socket.io-client"]&&await Ie(e,"socket.io-client")};var Vn=async(e,t)=>{let r=b("Customizing features...");try{await bn(e,t),await $n(e,t),await zn(e,t),await Fn(e,t),await wn(e,t),await Pn(e,t),await Rn(e,t),await Dn(e,t),await On(e,t),await Ln(e,t),await In(e),await Nn(e),await kn(e),await An(e),t.tests&&await me(e,{redux:t.redux,i18n:t.i18n}),r.succeed("Features customized.")}catch(n){throw r.fail("Failed to customize features."),n}};import rc 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(rc.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 Wn}from"node:fs/promises";import O from"node:path";S();P();var qn=async(e,t)=>{await nc(e,t),await ic(e,t),await oc(e,t),await sc(e,t),await ac(e,t),await cc(e,t),await pc(e,t)},nc=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)))},ic=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)))},oc=async(e,t)=>{t.ci||await w(O.join(e,c.GITHUB_WORKFLOWS))},sc=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 u(i);s=o(s),await g(i,s)}try{if(m(n)){let s=await Wn(n);for(let a of s){let p=O.join(n,a),f=await u(p);f=o(f),await g(p,f)}}}catch{}}},ac=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))},cc=async(e,t)=>{if(t.docker){let r=O.join(e,c.ENV_EXAMPLE);if(m(r)){let n=await u(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 u(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)}}},pc=async(e,t)=>{let r=async o=>{let s=await Wn(o,{withFileTypes:!0}),a=[];for(let p of s){let f=O.join(o,p.name);p.isDirectory()&&p.name!=="node_modules"&&p.name!==".git"?a.push(...await r(f)):p.isFile()&&p.name.toLowerCase()==="readme.md"&&a.push(f)}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 C(i)};S();x();import or from"node:path";var Wn=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 sr from"node:path";var Xn=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(or.join(e,c.ROOT_PROVIDER),a)},qn=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(sr.join(e,c.ROOT_PROVIDER),a)},Yn=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,24 +384,24 @@ export default function RootLayout({
384
384
  </html>
385
385
  );
386
386
  }
387
- `;await g(or.join(e,c.ROOT_LAYOUT),a);let p=t.redux?`import { Counter } from '@/features/counter';
387
+ `;await g(sr.join(e,c.ROOT_LAYOUT),a);let p=t.redux?`import { Counter } from '@/features/counter';
388
388
 
389
- `:"",u=t.redux?`
389
+ `:"",f=t.redux?`
390
390
  <Counter />`:"",d=`${p}export default function Home() {
391
391
  return (
392
392
  <div className="flex min-h-screen flex-col items-center justify-center p-24">
393
393
  <h1 className="text-4xl font-bold">Welcome to ${t.projectName}</h1>
394
- <p className="mt-4 text-xl">Get started by editing src/app/page.tsx</p>${u}
394
+ <p className="mt-4 text-xl">Get started by editing src/app/page.tsx</p>${f}
395
395
  </div>
396
396
  );
397
397
  }
398
- `;await g(or.join(e,c.ROOT_PAGE),d)};import sc from"degit";var Xn=async e=>{let t=b("Downloading template...");try{await sc("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 ar=["npm","yarn","pnpm","bun"],ac=e=>{if(e!==void 0){if(!ar.includes(e))throw new Error(`Invalid --package-manager "${e}". Valid: ${ar.join(", ")}.`);return e}},Yn=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: ${ar.join(", ")})`).action(async(t,r)=>{try{let n=ac(r.packageManager);await pc(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)}},cc=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("")},pc=async(e,t)=>{an();let r;t.yes?(r=un(e,{packageManager:t.packageManager}),l(X.cyan(`\u2728 Bootstrapping ${r.projectName} with the recommended defaults`)),l(""),cc(r)):(l("Welcome to the Teispace Next.js App Creator!"),l(""),r=await fn(e),t.packageManager&&(r={...r,packageManager:t.packageManager}));let n=sr.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=nn(async()=>{console.log(X.red(`
400
- Process interrupted. Cleaning up...`)),await o()});try{if(await Xn(n),await zn(n,r),await Bn(n,r),await qe("Generating providers and layout...","Providers and layout generated.",async()=>{await Wn(n,r),await qn(n,r)},i),await qe("Setting up developer tools...","Developer tools configured.",()=>Vn(n,r),i),await qe("Initializing Git...","Git initialized.",()=>pn(n,r.gitRemote,r.pushToRemote),i),await qe("Installing dependencies...","Dependencies installed.",()=>ln(n,r.packageManager),i),await qe("Formatting and linting...","Formatted.",()=>J(n,r.packageManager,"lint:fix"),i),r.copyEnv){let a=sr.join(n,".env.example"),p=sr.join(n,".env");m(a)&&await(await import("node:fs/promises")).copyFile(a,p)}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){s(),i.current?.fail("Failed to create project."),i.current=null,console.error(a),await o(),process.exit(1)}};import vr from"node:path";import ne from"picocolors";import yt from"node:path";var Kn=/^[A-Za-z][A-Za-z0-9-]*$/,lc=/^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;function Zn(e){return lc.test(e)}function H(e,t="name"){let r=e?.trim();if(!r)throw new Error(`A ${t} is required.`);if(!Kn.test(r))throw new Error(`Invalid ${t} "${e}". Use letters, digits, and hyphens only \u2014 no slashes, spaces, "..", or absolute paths.`);if(Zn(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(!Kn.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(Zn(i))throw new Error(`Invalid ${t} "${e}". Segment "${i}" is reserved on Windows.`)}return n}function xt(e,...t){let r=yt.resolve(e),n=yt.resolve(r,...t),i=yt.relative(r,n);if(i===""||i===".")return n;if(i.startsWith("..")||yt.isAbsolute(i))throw new Error(`Refusing to write outside the project directory (resolved path escapes "${r}").`);return n}G();import{mkdir as ni,writeFile as pr}from"node:fs/promises";import Se from"node:path";x();var cr=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
- `)},ri=e=>`export { ${e.componentName} } from './${e.componentName}';
402
- `;var lr=async e=>{let{name:t,projectPath:r,isClient:n,hasI18n:i,featurePath:o}=e,s=R(t);o?await fc(s,r,o,n,i):await gc(s,t,r,n,i)},fc=async(e,t,r,n,i)=>{let o=Se.join(t,r,"components");await ni(o,{recursive:!0}),await pr(Se.join(o,`${e}.tsx`),cr({componentName:e,isClient:n,hasI18n:i}))},gc=async(e,t,r,n,i)=>{let o=Se.join(r,"src","components","common",e);await ni(o,{recursive:!0}),await pr(Se.join(o,`${e}.tsx`),cr({componentName:e,isClient:n,hasI18n:i})),await pr(Se.join(o,"index.ts"),ri({componentName:e}));let s=Se.join(r,"src","components","common","index.ts");await hc(s,`export { ${e} } from './${e}';
403
- `);let a=Se.join(r,"src","components","index.ts");await yc(a)},hc=async(e,t)=>{let r="";m(e)&&(r=await f(e)),r.includes(t.trim())||(r+=t,await g(e,r))},yc=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 xc}from"node:fs/promises";import Pc from"node:path";var ii=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(sr.join(e,c.ROOT_PAGE),d)};import lc from"degit";var Kn=async e=>{let t=b("Downloading template...");try{await lc("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 cr=["npm","yarn","pnpm","bun"],mc=e=>{if(e!==void 0){if(!cr.includes(e))throw new Error(`Invalid --package-manager "${e}". Valid: ${cr.join(", ")}.`);return e}},Zn=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: ${cr.join(", ")})`).action(async(t,r)=>{try{let n=mc(r.packageManager);await uc(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)}},dc=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("")},uc=async(e,t)=>{pn();let r;t.yes?(r=gn(e,{packageManager:t.packageManager}),l(X.cyan(`\u2728 Bootstrapping ${r.projectName} with the recommended defaults`)),l(""),dc(r)):(l("Welcome to the Teispace Next.js App Creator!"),l(""),r=await hn(e),t.packageManager&&(r={...r,packageManager:t.packageManager}));let n=ar.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=sn(async()=>{console.log(X.red(`
400
+ Process interrupted. Cleaning up...`)),await o()});try{if(await Kn(n),await Jn(n,r),await Vn(n,r),await qe("Generating providers and layout...","Providers and layout generated.",async()=>{await Xn(n,r),await Yn(n,r)},i),await qe("Setting up developer tools...","Developer tools configured.",()=>qn(n,r),i),await qe("Initializing Git...","Git initialized.",()=>mn(n,r.gitRemote,r.pushToRemote),i),await qe("Installing dependencies...","Dependencies installed.",()=>dn(n,r.packageManager),i),await qe("Formatting and linting...","Formatted.",()=>J(n,r.packageManager,"lint:fix"),i),r.copyEnv){let a=ar.join(n,".env.example"),p=ar.join(n,".env");m(a)&&await(await import("node:fs/promises")).copyFile(a,p)}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){s(),i.current?.fail("Failed to create project."),i.current=null,console.error(a),await o(),process.exit(1)}};import Sr from"node:path";import ne from"picocolors";import yt from"node:path";var Qn=/^[A-Za-z][A-Za-z0-9-]*$/,fc=/^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;function ei(e){return fc.test(e)}function H(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(ei(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(ei(i))throw new Error(`Invalid ${t} "${e}". Segment "${i}" is reserved on Windows.`)}return n}function xt(e,...t){let r=yt.resolve(e),n=yt.resolve(r,...t),i=yt.relative(r,n);if(i===""||i===".")return n;if(i.startsWith("..")||yt.isAbsolute(i))throw new Error(`Refusing to write outside the project directory (resolved path escapes "${r}").`);return n}B();import{mkdir as oi,writeFile as lr}from"node:fs/promises";import Se from"node:path";P();var pr=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
+ `)},ii=e=>`export { ${e.componentName} } from './${e.componentName}';
402
+ `;var mr=async e=>{let{name:t,projectPath:r,isClient:n,hasI18n:i,featurePath:o}=e,s=I(t);o?await xc(s,r,o,n,i):await Pc(s,t,r,n,i)},xc=async(e,t,r,n,i)=>{let o=Se.join(t,r,"components");await oi(o,{recursive:!0}),await lr(Se.join(o,`${e}.tsx`),pr({componentName:e,isClient:n,hasI18n:i}))},Pc=async(e,t,r,n,i)=>{let o=Se.join(r,"src","components","common",e);await oi(o,{recursive:!0}),await lr(Se.join(o,`${e}.tsx`),pr({componentName:e,isClient:n,hasI18n:i})),await lr(Se.join(o,"index.ts"),ii({componentName:e}));let s=Se.join(r,"src","components","common","index.ts");await wc(s,`export { ${e} } from './${e}';
403
+ `);let a=Se.join(r,"src","components","index.ts");await vc(a)},wc=async(e,t)=>{let r="";m(e)&&(r=await u(e)),r.includes(t.trim())||(r+=t,await g(e,r))},vc=async e=>{let t="";m(e)&&(t=await u(e));let r=`export * from './common';
404
+ `;t.includes(r.trim())||(t+=r,await g(e,t))};import{writeFile as Sc}from"node:fs/promises";import Ec from"node:path";var si=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
- `},oi=e=>{let{camelName:t,kebabName:r}=e;return` ${t}: {
452
+ `},ai=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 mr=async e=>{let{name:t,outputPath:r,httpClient:n}=e,i=j(t),o=R(t);await xc(Pc.join(r,`${t}.service.ts`),ii({camelName:i,pascalName:o,httpClient:n}))};import{mkdir as Ec,writeFile as St}from"node:fs/promises";import K from"node:path";import{writeFile as wc}from"node:fs/promises";import vc from"node:path";var si=e=>{let{camelName:t,httpClient:r}=e;return`import { AppApis } from '@/lib/config';
459
+ },`};var dr=async e=>{let{name:t,outputPath:r,httpClient:n}=e,i=j(t),o=I(t);await Sc(Ec.join(r,`${t}.service.ts`),si({camelName:i,pascalName:o,httpClient:n}))};import{mkdir as Rc,writeFile as St}from"node:fs/promises";import K from"node:path";import{writeFile as Cc}from"node:fs/promises";import Tc from"node:path";var ci=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 Ke=async e=>{let{name:t,outputPath:r,httpClient:n}=e,i=j(t);await wc(vc.join(r,`${t}.service.ts`),si({camelName:i,httpClient:n}))};import{mkdir as Sc,writeFile as Ze}from"node:fs/promises";import Qe from"node:path";var ai=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 Cc(Tc.join(r,`${t}.service.ts`),ci({camelName:i,httpClient:n}))};import{mkdir as bc,writeFile as Ze}from"node:fs/promises";import Qe from"node:path";var pi=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
- `},ci=e=>{let{featureName:t,componentName:r,hookName:n,withStore:i,withService:o}=e;return`export { default as ${r} } from './components/${r}';
472
+ `},li=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 pi=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 mi=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 li=e=>{let{componentName:t,camelName:r,sliceName:n}=e;return`import { RootState } from '@/store/rootReducer';
497
+ `};var di=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 mi=e=>{let{componentName:t,camelName:r,typesImportPath:n}=e;return`import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
501
+ `};var ui=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 = {
@@ -533,7 +533,7 @@ export const ${r}Reducer = ${r}Slice.reducer;
533
533
  // Add your state properties here`:`// Add your state properties here
534
534
  // example: value: string;`}
535
535
  }
536
- `};var et=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([Ze(Qe.join(r,`${t}.types.ts`),vt({componentName:o,withStore:!0})),Ze(Qe.join(r,`${t}.slice.ts`),mi({componentName:o,camelName:s,typesImportPath:i})),Ze(Qe.join(r,`${t}.selectors.ts`),li({componentName:o,camelName:s,sliceName:t})),...n?[Ze(Qe.join(r,"persist.ts"),pi({componentName:o,camelName:s,typesImportPath:i}))]:[],Ze(Qe.join(r,"index.ts"),ai({sliceName:t,withPersist:n}))])};var di=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 bc(r,{recursive:!0});let o=I(t),s=j(t);await Promise.all([Ze(Qe.join(r,`${t}.types.ts`),vt({componentName:o,withStore:!0})),Ze(Qe.join(r,`${t}.slice.ts`),ui({componentName:o,camelName:s,typesImportPath:i})),Ze(Qe.join(r,`${t}.selectors.ts`),di({componentName:o,camelName:s,sliceName:t})),...n?[Ze(Qe.join(r,"persist.ts"),mi({componentName:o,camelName:s,typesImportPath:i}))]:[],Ze(Qe.join(r,"index.ts"),pi({sliceName:t,withPersist:n}))])};var fi=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 ui=e=>{let{hookName:t,componentName:r,featureName:n}=e;return`'use client';
551
+ `};var gi=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
- `},fi=e=>{let{hookName:t}=e;return`'use client';
573
+ `},hi=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 dr=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=>Ec(d,{recursive:!0}))),await Promise.all([St(K.join(r,"components",`${a}.tsx`),di({componentName:a,hookName:p})),St(K.join(r,"hooks",`${p}.ts`),n?ui({hookName:p,componentName:a,featureName:t}):fi({hookName:p})),St(K.join(r,"types",`${t}.types.ts`),vt({componentName:a,withStore:n})),St(K.join(r,"index.ts"),ci({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 Cc,writeFile as Tc}from"node:fs/promises";import ur from"node:path";var gi=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 fr=async e=>{let{name:t,projectPath:r,isClient:n,featurePath:i}=e,s=`use${R(t)}`,a;i?a=ur.join(r,i,"hooks"):a=ur.join(r,"src","hooks"),await Cc(a,{recursive:!0}),await Tc(ur.join(a,`${s}.ts`),gi({hookName:s,isClient:n}))};import{mkdir as $c}from"node:fs/promises";import Et from"node:path";x();var bc=e=>`import { setRequestLocale } from 'next-intl/server';
585
+ `};var ur=async e=>{let{name:t,outputPath:r,createStore:n,persistStore:i,createService:o,httpClient:s}=e,a=I(t),p=`use${a}`,f=[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(f.map(d=>Rc(d,{recursive:!0}))),await Promise.all([St(K.join(r,"components",`${a}.tsx`),fi({componentName:a,hookName:p})),St(K.join(r,"hooks",`${p}.ts`),n?gi({hookName:p,componentName:a,featureName:t}):hi({hookName:p})),St(K.join(r,"types",`${t}.types.ts`),vt({componentName:a,withStore:n})),St(K.join(r,"index.ts"),li({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 $c,writeFile as Ic}from"node:fs/promises";import fr from"node:path";var yi=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 gr=async e=>{let{name:t,projectPath:r,isClient:n,featurePath:i}=e,s=`use${I(t)}`,a;i?a=fr.join(r,i,"hooks"):a=fr.join(r,"src","hooks"),await $c(a,{recursive:!0}),await Ic(fr.join(a,`${s}.ts`),yi({hookName:s,isClient:n}))};import{mkdir as Ac}from"node:fs/promises";import Et from"node:path";P();var Nc=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
- `,Rc=e=>`type Props = {
600
+ `,kc=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
- `,hi=({componentName:e,hasI18n:t})=>t?bc(e):Rc(e);var Ic=/^[a-z][a-z0-9-]*$/,Nc=/^[a-z][a-z0-9-]*(\/[a-z][a-z0-9-]*)*$/,kc=e=>{if(!Ic.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.`)},Ac=e=>{if(!Nc.test(e))throw new Error(`Invalid --at path "${e}". Use kebab-case segments separated by "/", e.g. "dashboard/settings".`)},gr=async e=>{let{segment:t,at:r,projectPath:n,hasI18n:i,withGroup:o}=e;kc(t),r&&Ac(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=Et.join(n,...p),d=Et.join(u,"layout.tsx");if(m(d))throw new Error(`Layout already exists at ${Et.relative(n,d)}.`);return await $c(u,{recursive:!0}),await g(d,hi({componentName:s,hasI18n:i})),{layoutFile:d,displayPath:Et.relative(n,d),componentName:s}};x();import{copyFile as _c,readFile as Oc,writeFile as Fc}from"node:fs/promises";import tt from"node:path";var hr=async e=>{let{code:t,name:r,country:n,flag:i,projectPath:o,copyTranslations:s}=e;await jc(o,t,s),await Dc(o,t),await Lc(o,t,r,n,i)},jc=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 Oc(i,"utf-8"),a=JSON.parse(s),p=yi(a);await Fc(o,`${JSON.stringify(p,null,2)}
608
- `)}},yi=e=>{let t={};for(let[r,n]of Object.entries(e))typeof n=="object"&&n!==null?t[r]=yi(n):t[r]="";return t},Dc=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)}},Lc=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=` {
607
+ `,xi=({componentName:e,hasI18n:t})=>t?Nc(e):kc(e);var _c=/^[a-z][a-z0-9-]*$/,Oc=/^[a-z][a-z0-9-]*(\/[a-z][a-z0-9-]*)*$/,Fc=e=>{if(!_c.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.`)},jc=e=>{if(!Oc.test(e))throw new Error(`Invalid --at path "${e}". Use kebab-case segments separated by "/", e.g. "dashboard/settings".`)},hr=async e=>{let{segment:t,at:r,projectPath:n,hasI18n:i,withGroup:o}=e;Fc(t),r&&jc(r);let s=`${I(t)}Layout`,a=o?`(${t})`:t,p=["src","app"];i&&p.push("[locale]"),r&&p.push(...r.split("/")),p.push(a);let f=Et.join(n,...p),d=Et.join(f,"layout.tsx");if(m(d))throw new Error(`Layout already exists at ${Et.relative(n,d)}.`);return await Ac(f,{recursive:!0}),await g(d,xi({componentName:s,hasI18n:i})),{layoutFile:d,displayPath:Et.relative(n,d),componentName:s}};P();import{copyFile as Dc,readFile as Lc,writeFile as Mc}from"node:fs/promises";import tt from"node:path";var yr=async e=>{let{code:t,name:r,country:n,flag:i,projectPath:o,copyTranslations:s}=e;await Gc(o,t,s),await Uc(o,t),await Hc(o,t,r,n,i)},Gc=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 Dc(i,o);else{let s=await Lc(i,"utf-8"),a=JSON.parse(s),p=Pi(a);await Mc(o,`${JSON.stringify(p,null,2)}
608
+ `)}},Pi=e=>{let t={};for(let[r,n]of Object.entries(e))typeof n=="object"&&n!==null?t[r]=Pi(n):t[r]="";return t},Uc=async(e,t)=>{let r=tt.join(e,"src","types","i18n.ts");if(!m(r))return;let n=await u(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)}},Hc=async(e,t,r,n,i)=>{let o=tt.join(e,"src","lib","config","app-locales.ts");if(!m(o))return;let s=await u(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 Mc,writeFile as yr}from"node:fs/promises";import rt from"node:path";var xi=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 Bc,writeFile as xr}from"node:fs/promises";import rt from"node:path";var wi=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
+ `},vi=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
- `},wi=e=>`export default function ${e.componentName}Loading() {
714
+ `},Si=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
- `,vi=e=>`'use client';
721
+ `,Ei=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 xr=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 Mc(d,{recursive:!0});let h=i?Pi({componentName:a,routePath:i?`${p}/[${i}]`:p,paramName:i,hasI18n:n}):xi({componentName:a,routePath:p,hasI18n:n});await yr(rt.join(d,"page.tsx"),h),o&&await yr(rt.join(d,"loading.tsx"),wi({componentName:a})),s&&await yr(rt.join(d,"error.tsx"),vi({componentName:a}))};S();import{mkdir as Uc}from"node:fs/promises";import Pr from"node:path";x();var Si=(e,t)=>e.endsWith(t)?e:`${e}${t}`,Ei=({baseName:e})=>{let t=Si(e,"Provider"),r=t.replace(/Provider$/,""),n=`${r}ContextValue`,i=`${r}Context`,o=`use${r}`;return`'use client';
738
+ `;var Pr=async e=>{let{name:t,projectPath:r,hasI18n:n,dynamic:i,withLoading:o=!1,withError:s=!1}=e,a=I(t),p=`/${t}`,f=n?"src/app/[locale]":"src/app",d;i?d=rt.join(r,f,t,`[${i}]`):d=rt.join(r,f,t),await Bc(d,{recursive:!0});let h=i?vi({componentName:a,routePath:i?`${p}/[${i}]`:p,paramName:i,hasI18n:n}):wi({componentName:a,routePath:p,hasI18n:n});await xr(rt.join(d,"page.tsx"),h),o&&await xr(rt.join(d,"loading.tsx"),Si({componentName:a})),s&&await xr(rt.join(d,"error.tsx"),Ei({componentName:a}))};S();import{mkdir as zc}from"node:fs/promises";import wr from"node:path";P();var Ci=(e,t)=>e.endsWith(t)?e:`${e}${t}`,Ti=({baseName:e})=>{let t=Ci(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
- `},Ci=e=>Si(e,"Provider");var Hc=/^[A-Za-z][A-Za-z0-9-]*$/,Gc=e=>e.includes("-")?R(e):e.charAt(0).toUpperCase()+e.slice(1),wr=async e=>{let{name:t,projectPath:r}=e;if(!Hc.test(t))throw new Error(`Invalid provider name "${t}". Use kebab-case or PascalCase letters and digits only.`);let n=Gc(t).replace(/Provider$/,""),i=Ci(n),o=i,s=Pr.join(r,c.PROVIDERS),a=Pr.join(s,`${o}.tsx`);if(m(a))throw new Error(`Provider already exists at ${Pr.relative(r,a)}.`);return await Uc(s,{recursive:!0}),await g(a,Ei({baseName:n})),{componentName:i,fileBaseName:o,providerFile:a}};x();import nt from"node:path";var Ti=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
+ `},bi=e=>Ci(e,"Provider");var Vc=/^[A-Za-z][A-Za-z0-9-]*$/,Jc=e=>e.includes("-")?I(e):e.charAt(0).toUpperCase()+e.slice(1),vr=async e=>{let{name:t,projectPath:r}=e;if(!Vc.test(t))throw new Error(`Invalid provider name "${t}". Use kebab-case or PascalCase letters and digits only.`);let n=Jc(t).replace(/Provider$/,""),i=bi(n),o=i,s=wr.join(r,c.PROVIDERS),a=wr.join(s,`${o}.tsx`);if(m(a))throw new Error(`Provider already exists at ${wr.relative(r,a)}.`);return await zc(s,{recursive:!0}),await g(a,Ti({baseName:n})),{componentName:i,fileBaseName:o,providerFile:a}};P();import nt from"node:path";var Ri=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
- `},bi=e=>{let{hookName:t,sourceImportPath:r,withStore:n,testUtilsImportPath:i}=e;return n?`import { renderHook } from '@testing-library/react';
773
+ `},$i=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
- `},Ri=e=>{let{camelName:t,sourceImportPath:r}=e,n=`${t}Slice`;return`import { describe, expect, it } from 'vitest';
794
+ `},Ii=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 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=Bc(o,nt.join(t,"test","test-utils")),h;return n==="component"?h=Ti({componentName:i,sourceImportPath:u,testUtilsImportPath:d,hasRedux:!!e.hasRedux,hasI18n:!!e.hasI18n}):n==="hook"?h=bi({hookName:i,sourceImportPath:u,withStore:!!e.hookUsesStore,testUtilsImportPath:e.hookUsesStore?d:void 0}):h=Ri({camelName:i,sourceImportPath:u}),await g(p,h),p},Bc=(e,t)=>{let r=nt.relative(e,t).replace(/\\/g,"/");return r.startsWith(".")?r:`./${r}`};import zc from"enquirer";var{prompt:Jc}=zc,$i=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 Jc(r):{};return{componentName:e??n.componentName,isClient:t.client??n.isClient??!1}};var Ii=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(`
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}`),f=`./${s}`,d=Wc(o,nt.join(t,"test","test-utils")),h;return n==="component"?h=Ri({componentName:i,sourceImportPath:f,testUtilsImportPath:d,hasRedux:!!e.hasRedux,hasI18n:!!e.hasI18n}):n==="hook"?h=$i({hookName:i,sourceImportPath:f,withStore:!!e.hookUsesStore,testUtilsImportPath:e.hookUsesStore?d:void 0}):h=Ii({camelName:i,sourceImportPath:f}),await g(p,h),p},Wc=(e,t)=>{let r=nt.relative(e,t).replace(/\\/g,"/");return r.startsWith(".")?r:`./${r}`};import qc from"enquirer";var{prompt:Xc}=qc,Ni=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 Xc(r):{};return{componentName:e??n.componentName,isClient:t.client??n.isClient??!1}};var ki=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 $i(t,{client:r.client});H(o.componentName,"component name"),r.feature&&re(r.feature,"feature path");let s=R(o.componentName),a=o.isClient,p=r.i18n??!1,u=Vc(r,i.hasTests);y.start("Generating component..."),await lr({name:o.componentName,projectPath:n,isClient:a||p,hasI18n:p,featurePath:r.feature}),y.succeed("Component generated");let d=null;if(u){let P=r.feature?vr.join(n,r.feature,"components",`${s}.tsx`):vr.join(n,"src/components/common",s,`${s}.tsx`);y.start("Generating test..."),d=await ae({projectPath:n,sourceFile:P,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(`
821
+ `)),y.start("Detecting project setup...");let i=await F(n);y.succeed("Project setup detected");let o=await Ni(t,{client:r.client});H(o.componentName,"component name"),r.feature&&re(r.feature,"feature path");let s=I(o.componentName),a=o.isClient,p=r.i18n??!1,f=Yc(r,i.hasTests);y.start("Generating component..."),await mr({name:o.componentName,projectPath:n,isClient:a||p,hasI18n:p,featurePath:r.feature}),y.succeed("Component generated");let d=null;if(f){let x=r.feature?Sr.join(n,r.feature,"components",`${s}.tsx`):Sr.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(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} ${vr.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)}})},Vc=(e,t)=>e.test===!1?!1:e.test===!0?!0:t;import L from"picocolors";S();x();import qc from"node:path";S();import Ni from"node:path";import Wc from"picocolors";x();var Ct=async e=>{let t=b("Adding @next/bundle-analyzer...");try{let r=Ni.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} ${Sr.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)}})},Yc=(e,t)=>e.test===!1?!1:e.test===!0?!0:t;import M from"picocolors";S();P();import Zc from"node:path";S();import Ai from"node:path";import Kc from"picocolors";P();var Ct=async e=>{let t=b("Adding @next/bundle-analyzer...");try{let r=Ai.join(e,c.NEXT_CONFIG);if(!m(r))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await u(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(Ni.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 ut(e,"@next/bundle-analyzer"),t.succeed(Wc.green("@next/bundle-analyzer configured."))}catch(r){throw t.fail("Failed to add @next/bundle-analyzer."),r}};var Sr=(e,t)=>{let r=e.split(`
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(`
828
+ export default bundleAnalyzer(${o[1]});`;n=n.replace(i,a),await g(r,n),await D(Ai.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 ut(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 Er=(e,t)=>{let r=e.split(`
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),f=p.filter(d=>d.replace(/^type\s+/,"").split(/\s+as\s+/)[0].trim()!==t);if(f.length===0)continue;if(f.length<p.length){n.push(`${a[1]}{ ${f.join(", ")} }${a[3]}`);continue}}n.push(s)}return n.join(`
830
830
  `)},_e=e=>t=>{let r=t.split(`
831
- `),n=new RegExp(`^([ \\t]*)<${e}\\b`),i=-1,o="";for(let h=0;h<r.length;h++){let P=r[h].match(n);if(P){i=h,o=P[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 Sr(d,e)};var ki=e=>{let t=e.split(`
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 f=r.slice(i+1,p).map(h=>h.startsWith(" ")?h.slice(2):h),d=[...r.slice(0,i),...f,...r.slice(p+1)].join(`
832
+ `);return Er(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},Ai=e=>{let t=Sr(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 _i={id:"bundle-analyzer",name:"Bundle Analyzer",description:"@next/bundle-analyzer wrapped around the default export",detect:async e=>{let t=qc.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:Ai}],apply:Ct};S();x();import Kc from"node:path";S();import Oi from"node:path";import Xc from"picocolors";x();var Er=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}},Cr=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 Yc=`${JSON.stringify({path:"cz-conventional-changelog"},null,2)}
835
- `,Tt=async e=>{let t=b("Setting up Commitizen...");try{let r=Oi.join(e,c.CZRC);m(r)||await g(r,Yc);let n=Oi.join(e,c.PACKAGE_JSON),i=JSON.parse(await f(n)),o=Cr(i);if(await D(n,s=>Er(s)),o.length>0){t.text=`Installing ${o.join(", ")}...`;let s=await N(e);await Pe(e,s,o)}t.succeed(Xc.green("Commitizen configured. Use `commit` to start a guided commit."))}catch(r){throw t.fail("Failed to set up Commitizen."),r}};var Fi={id:"commitizen",name:"Commitizen",description:"Guided conventional-commit prompt via `commit` script",detect:async e=>m(Kc.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:Tt};S();x();import tp from"node:path";import Qc from"node:path";import ep from"picocolors";x();S();x();import ji from"node:path";import Zc from"degit";var Di=async(e,t)=>{t.text="Fetching assets from starter repo...",await Zc("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Li=async(e,t)=>{let r=ji.join(e,c.THEME_PROVIDER),n=ji.join(t,"src/providers/CustomThemeProvider.tsx");await I(n,r)};S();x();import it from"node:path";S();x();import Mi from"node:path";var bt=async e=>{let t=[Mi.join(e,c.ROOT_LAYOUT),Mi.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 Ui=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:""}},Hi=async e=>{let t=it.join(e,c.GLOBALS_CSS),r=it.join(e,c.PROVIDERS_INDEX),n=await bt(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();x();import Rt from"node:path";var Gi=async e=>{let t=Rt.join(e,c.PROVIDERS_INDEX),r=await f(t);r.includes("CustomThemeProvider")||(r+=`export * from './CustomThemeProvider';
836
- `,await g(t,r))},Bi=async e=>{let t=Rt.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},Oi=e=>{let t=Er(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 Fi={id:"bundle-analyzer",name:"Bundle Analyzer",description:"@next/bundle-analyzer wrapped around the default export",detect:async e=>{let t=Zc.join(e,c.NEXT_CONFIG);return m(t)?/@next\/bundle-analyzer/.test(await u(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:Oi}],apply:Ct};S();P();import tp from"node:path";S();import ji from"node:path";import Qc from"picocolors";P();var Cr=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}},Tr=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 ep=`${JSON.stringify({path:"cz-conventional-changelog"},null,2)}
835
+ `,Tt=async e=>{let t=b("Setting up Commitizen...");try{let r=ji.join(e,c.CZRC);m(r)||await g(r,ep);let n=ji.join(e,c.PACKAGE_JSON),i=JSON.parse(await u(n)),o=Tr(i);if(await D(n,s=>Cr(s)),o.length>0){t.text=`Installing ${o.join(", ")}...`;let s=await k(e);await Pe(e,s,o)}t.succeed(Qc.green("Commitizen configured. Use `commit` to start a guided commit."))}catch(r){throw t.fail("Failed to set up Commitizen."),r}};var Di={id:"commitizen",name:"Commitizen",description:"Guided conventional-commit prompt via `commit` script",detect:async e=>m(tp.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:Tt};S();P();import op from"node:path";import np from"node:path";import ip from"picocolors";P();S();P();import Li from"node:path";import rp from"degit";var Mi=async(e,t)=>{t.text="Fetching assets from starter repo...",await rp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Gi=async(e,t)=>{let r=Li.join(e,c.THEME_PROVIDER),n=Li.join(t,"src/providers/CustomThemeProvider.tsx");await N(n,r)};S();P();import it from"node:path";S();P();import Ui from"node:path";var bt=async e=>{let t=[Ui.join(e,c.ROOT_LAYOUT),Ui.join(e,"src/app/[locale]/layout.tsx")];for(let r of t)if(m(r)&&(await u(r)).includes("<body"))return r;for(let r of t)if(m(r))return r;return""};var Hi=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 u(n)),o="@teispace/next-themes";if(i.dependencies?.[o]||i.devDependencies?.[o])return{isSetup:!0,reason:`${o} is installed`}}return m(r)&&(await u(r)).includes("@custom-variant dark")?{isSetup:!0,reason:"Dark theme CSS found in globals.css"}:{isSetup:!1,reason:""}},Bi=async e=>{let t=it.join(e,c.GLOBALS_CSS),r=it.join(e,c.PROVIDERS_INDEX),n=await bt(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 Rt from"node:path";var zi=async e=>{let t=Rt.join(e,c.PROVIDERS_INDEX),r=await u(t);r.includes("CustomThemeProvider")||(r+=`export * from './CustomThemeProvider';
836
+ `,await g(t,r))},Vi=async e=>{let t=Rt.join(e,"src/providers/RootProvider.tsx");if(!m(t))return;let r=await u(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)},zi=async(e,t)=>{let r=Rt.join(e,c.GLOBALS_CSS),n=Rt.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)},Ji=async(e,t)=>{let r=Rt.join(e,c.GLOBALS_CSS),n=Rt.join(t,"src/styles/globals.css"),i="";if(m(n)){let s=await u(n),a=s.match(/@custom-variant dark \(.*?\);/),p=s.match(/@theme \{[\s\S]*?\}/);a&&(i+=`
843
843
  ${a[0]}
844
844
  `),p&&(i+=`
845
845
  ${p[0]}
@@ -850,41 +850,41 @@ ${p[0]}
850
850
  --color-dark: #202938;
851
851
  --color-light: #f5f5f5;
852
852
  }
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)}},Ji=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 $t=async e=>{let t=b("Setting up Dark Theme..."),r=Qc.join(e,".next-maker-temp");try{let{isSetup:n,reason:i}=await Ui(e);if(n){t.fail(`Dark Theme is already set up (${i}).`);return}let o=await Hi(e);await Di(r,t),await Li(e,r),await Gi(e),await Bi(e),await zi(e,r),await Ji(o),t.text="Installing @teispace/next-themes...",await U(e,"@teispace/next-themes"),t.text="Formatting code...";let s=await N(e);await J(e,s,"lint:fix"),t.succeed(ep.green("Dark Theme setup successfully!"))}catch(n){throw t.fail("Failed to setup Dark Theme."),n}finally{await w(r)}};var Vi={id:"dark-theme",name:"Dark Theme",description:"@teispace/next-themes + CustomThemeProvider",detect:async e=>m(tp.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:_e("CustomThemeProvider")}],apply:$t};import np from"node:fs/promises";import It from"node:path";import Nt from"enquirer";import Tr from"picocolors";x();S();x();import Y from"node:fs/promises";import E from"node:path";import rp from"degit";var Wi=async(e,t)=>{t.text="Downloading assets from starter repository...",await rp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},qi=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 I(E.join(t,c.APP_APIS),s);let a=E.join(e,c.API_URL_FILE);m(a)||await I(E.join(t,c.API_URL_FILE),a);let p=E.join(e,c.CONSTANTS);if(!m(p))await I(E.join(t,c.CONSTANTS),p);else{let d=await f(p),h=!1;d.includes("API_RESPONSE_DATA_KEY")||(d+=`
853
+ `);let o=await u(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)}},Wi=async e=>{let t=await u(e);t.includes("dark:bg-dark")||(t=t.replace(/className="([^"]*)"/,'className="$1 bg-light dark:bg-dark"'),await g(e,t))};var $t=async e=>{let t=b("Setting up Dark Theme..."),r=np.join(e,".next-maker-temp");try{let{isSetup:n,reason:i}=await Hi(e);if(n){t.fail(`Dark Theme is already set up (${i}).`);return}let o=await Bi(e);await Mi(r,t),await Gi(e,r),await zi(e),await Vi(e),await Ji(e,r),await Wi(o),t.text="Installing @teispace/next-themes...",await U(e,"@teispace/next-themes"),t.text="Formatting code...";let s=await k(e);await J(e,s,"lint:fix"),t.succeed(ip.green("Dark Theme setup successfully!"))}catch(n){throw t.fail("Failed to setup Dark Theme."),n}finally{await w(r)}};var qi={id:"dark-theme",name:"Dark Theme",description:"@teispace/next-themes + CustomThemeProvider",detect:async e=>m(op.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:_e("CustomThemeProvider")}],apply:$t};import ap from"node:fs/promises";import It from"node:path";import Nt from"enquirer";import br from"picocolors";P();S();P();import Y from"node:fs/promises";import E from"node:path";import sp from"degit";var Xi=async(e,t)=>{t.text="Downloading assets from starter repository...",await sp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Yi=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 u(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=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 I(E.join(o,"token-store.ts"),E.join(i,"token-store.ts")),await I(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 I(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 I(E.join(o,"index.ts"),E.join(i,"index.ts")),await I(E.join(t,c.HTTP_TYPES),E.join(e,c.HTTP_TYPES))},Xi=async e=>{let{isFileUsed:t,isStringUsed:r}=await Promise.resolve().then(()=>(ze(),En));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,`
858
+ `,h=!0),h&&await g(p,d)}let f=E.join(e,c.STORAGE_SERVICE);if(m(f)||await Y.cp(E.join(t,c.STORAGE_SERVICE),f,{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))},Ki=async e=>{let{isFileUsed:t,isStringUsed:r,stripSaveAuthTokens:n}=await Promise.resolve().then(()=>(ze(),Tn));await w(E.join(e,c.HTTP_UTILS));let i=E.join(e,c.STORAGE_SERVICE);m(i)&&(await r(e,"SecureStorageService",[i])||await w(i));let o=E.join(e,c.API_URL_FILE);m(o)&&(await r(e,"getApiBaseUrl",[o])||await Y.unlink(o));let s=E.join(e,c.CONSTANTS);if(m(s)){let d=await u(s),h=!1;if(await r(e,"API_RESPONSE_DATA_KEY",[s])||(d=d.replace(/export const API_RESPONSE_DATA_KEY = .*;\n?/g,""),h=!0),!await r(e,"SAVE_AUTH_TOKENS",[s])){let L=n(d);L!==d&&(d=L,h=!0)}h&&(d=`${d.replace(/\n\s*\n/g,`
859
859
 
860
860
  `).trim()}
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 P=E.parse(h).name;if(await t(e,P,[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();x();import ot from"node:path";var Yi=async e=>{let t=ot.join(e,c.FETCH_CLIENT_FILE),r=ot.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"}},Ki=async e=>{let r=[ot.join(e,"src/lib"),ot.join(e,"src/types"),ot.join(e,"src/lib/config")].filter(n=>!m(n));if(r.length>0)throw new Error(`Invalid project structure. Missing directories:
861
+ `,await g(s,d))}let a=E.join(e,c.ERRORS_DIR);if(m(a)){let d=await Y.readdir(a),h=!1;for(let x of d){let R=E.parse(x).name;if(await t(e,R,[E.join(a,x)])){h=!0;break}}h||await w(a)}let p=E.join(e,c.COMMON_TYPES_DIR);m(p)&&(await Y.readdir(p)).length===0&&await w(p);let f=E.join(e,c.UTILITY_TYPES_DIR);m(f)&&(await Y.readdir(f)).length===0&&await w(f)};S();P();import ot from"node:path";var Zi=async e=>{let t=ot.join(e,c.FETCH_CLIENT_FILE),r=ot.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=[ot.join(e,"src/lib"),ot.join(e,"src/types"),ot.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
- `)}`)};ze();var kt=async e=>{let t=b("Checking HTTP Client setup..."),r=It.join(e,".next-maker-temp-http");try{let{status:n,reason:i}=await Yi(e);t.stop();let o=await ip(n,i);if(o.type==="cancel"){console.log(Tr.yellow("Setup cancelled."));return}if(t.start("Setting up HTTP client(s)..."),await Ki(e),await Wi(r,t),o.type==="replace"&&o.fromClient&&(t.text="Migrating client usages...",await er(e,o.fromClient,o.clients[0])),o.type!=="remove-both"&&o.type!=="remove-one"){t.text="Copying client files...";let O=o.type==="replace"&&o.fromClient?[o.fromClient]:void 0;await qi(e,r,o.clients,O)}if(o.type==="remove-one"||o.type==="remove-both"){t.text="Removing client files...";let{PROJECT_PATHS:O}=await Promise.resolve().then(()=>(S(),gn));for(let $ of o.clients){let W=It.join(e,$==="fetch"?O.FETCH_CLIENT:O.AXIOS_CLIENT);await w(W)}Zi(n,o).length===0&&(t.text="Performing full cleanup...",await Xi(e),await nr(e))}let s=Zi(n,o);s.length>0?(t.text="Configuring client...",await Yt(e,s),await Kt(e),await Zt(e),await Qt(e),await rr(e),await ke(e,s),await Ae(e,s)):await Be(e),await Ne(e,s),t.text="Managing dependencies...";let a=It.join(e,"package.json"),p=JSON.parse(await np.readFile(a,"utf-8")),u={...p.dependencies,...p.devDependencies};s.includes("axios")?u.axios||(t.text="Installing Axios...",await U(e,"axios")):u.axios&&(t.text="Uninstalling Axios...",await Ie(e,"axios")),s.length>0?u["server-only"]||(t.text="Installing server-only...",await U(e,"server-only")):u["server-only"]&&(t.text="Uninstalling server-only...",await Ie(e,"server-only"));let d=It.join(e,"src/services/storage");s.length>0||m(d)?u["react-secure-storage"]||(t.text="Installing react-secure-storage...",await U(e,"react-secure-storage")):u["react-secure-storage"]&&(t.text="Uninstalling react-secure-storage...",await Ie(e,"react-secure-storage")),t.text="Formatting code...";let P=await N(e);await J(e,P,"lint:fix"),t.succeed(Tr.green(op(o)))}catch(n){throw t.fail("Failed to setup HTTP Client."),n}finally{await w(r)}};async function ip(e,t){if(e==="none"){let{choice:n}=await Nt.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 Nt.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 Nt.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(Tr.yellow(`\u2716 ${t}`));let{action:r}=await Nt.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 Zi(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 op(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 Qi=/<HttpClientBundleSentinel\s*\/>/,eo={id:"http-client",name:"HTTP Client",description:"Axios and/or Fetch client utilities",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(G(),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:Qi,removePattern:Ge},{file:"src/app/layout.tsx",description:"<HttpClientBundleSentinel /> mount in root layout",presence:Qi,removePattern:Ge}],apply:kt};S();import br from"node:path";import pp from"picocolors";x();S();x();import sp from"node:fs/promises";import ue from"node:path";import ap from"degit";var to=async(e,t)=>{t.text="Fetching assets from starter repo...",await ap("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},ro=async(e,t)=>{let r=ue.join(t,"src/i18n"),n=ue.join(e,c.I18N_DIR);await sp.cp(r,n,{recursive:!0});let i=ue.join(t,"src/proxy.ts"),o=ue.join(e,c.PROXY);await I(i,o);let s=ue.join(t,"src/types/i18n.ts"),a=ue.join(e,c.I18N_TYPES);await I(s,a);let p=ue.join(t,"src/lib/config/app-locales.ts"),u=ue.join(e,c.APP_LOCALES);await I(p,u)};S();x();import At from"node:path";var no=async e=>{let t=At.join(e,c.I18N_DIR),r=At.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:""}},io=async e=>{let t=At.join(e,c.ROOT_LAYOUT),r=At.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();x();import cp from"node:fs/promises";import ce from"node:path";var oo=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';
863
+ `)}`)};ze();var kt=async e=>{let t=b("Checking HTTP Client setup..."),r=It.join(e,".next-maker-temp-http");try{let{status:n,reason:i}=await Zi(e);t.stop();let o=await cp(n,i);if(o.type==="cancel"){console.log(br.yellow("Setup cancelled."));return}if(t.start("Setting up HTTP client(s)..."),await Qi(e),await Xi(r,t),o.type==="replace"&&o.fromClient&&(t.text="Migrating client usages...",await tr(e,o.fromClient,o.clients[0])),o.type!=="remove-both"&&o.type!=="remove-one"){t.text="Copying client files...";let R=o.type==="replace"&&o.fromClient?[o.fromClient]:void 0;await Yi(e,r,o.clients,R)}if(o.type==="remove-one"||o.type==="remove-both"){t.text="Removing client files...";let{PROJECT_PATHS:R}=await Promise.resolve().then(()=>(S(),yn));for(let $ of o.clients){let W=It.join(e,$==="fetch"?R.FETCH_CLIENT:R.AXIOS_CLIENT);await w(W)}eo(n,o).length===0&&(t.text="Performing full cleanup...",await Ki(e),await ir(e))}let s=eo(n,o);s.length>0?(t.text="Configuring client...",await Yt(e,s),await Kt(e),await Zt(e),await Qt(e),await nr(e),await ke(e,s),await Ae(e,s)):await Be(e),await Ne(e,s),t.text="Managing dependencies...";let a=It.join(e,"package.json"),p=JSON.parse(await ap.readFile(a,"utf-8")),f={...p.dependencies,...p.devDependencies};s.includes("axios")?f.axios||(t.text="Installing Axios...",await U(e,"axios")):f.axios&&(t.text="Uninstalling Axios...",await Ie(e,"axios")),s.length>0?f["server-only"]||(t.text="Installing server-only...",await U(e,"server-only")):f["server-only"]&&(t.text="Uninstalling server-only...",await Ie(e,"server-only"));let d=It.join(e,"src/services/storage");s.length>0||m(d)?f["react-secure-storage"]||(t.text="Installing react-secure-storage...",await U(e,"react-secure-storage")):f["react-secure-storage"]&&(t.text="Uninstalling react-secure-storage...",await Ie(e,"react-secure-storage")),t.text="Formatting code...";let x=await k(e);await J(e,x,"lint:fix"),t.succeed(br.green(pp(o)))}catch(n){throw t.fail("Failed to setup HTTP Client."),n}finally{await w(r)}};async function cp(e,t){if(e==="none"){let{choice:n}=await Nt.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 Nt.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 Nt.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(br.yellow(`\u2716 ${t}`));let{action:r}=await Nt.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 eo(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 pp(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 to=/<HttpClientBundleSentinel\s*\/>/,ro={id:"http-client",name:"HTTP Client",description:"Axios and/or Fetch client utilities",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(B(),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:to,removePattern:He},{file:"src/app/layout.tsx",description:"<HttpClientBundleSentinel /> mount in root layout",presence:to,removePattern:He}],apply:kt};S();import Rr from"node:path";import up from"picocolors";P();S();P();import lp from"node:fs/promises";import fe from"node:path";import mp from"degit";var no=async(e,t)=>{t.text="Fetching assets from starter repo...",await mp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},io=async(e,t)=>{let r=fe.join(t,"src/i18n"),n=fe.join(e,c.I18N_DIR);await lp.cp(r,n,{recursive:!0});let i=fe.join(t,"src/proxy.ts"),o=fe.join(e,c.PROXY);await N(i,o);let s=fe.join(t,"src/types/i18n.ts"),a=fe.join(e,c.I18N_TYPES);await N(s,a);let p=fe.join(t,"src/lib/config/app-locales.ts"),f=fe.join(e,c.APP_LOCALES);await N(p,f)};S();P();import At from"node:path";var oo=async e=>{let t=At.join(e,c.I18N_DIR),r=At.join(e,"package.json");if(m(t))return{isSetup:!0,reason:"src/i18n directory exists"};if(m(r)){let n=JSON.parse(await u(r));if(n.dependencies?.["next-intl"]||n.devDependencies?.["next-intl"])return{isSetup:!0,reason:"next-intl is installed"}}return{isSetup:!1,reason:""}},so=async e=>{let t=At.join(e,c.ROOT_LAYOUT),r=At.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 dp from"node:fs/promises";import ce from"node:path";var ao=async e=>{let t=ce.join(e,c.NEXT_CONFIG);if(m(t)){let r=await u(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)}}},so=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))}},ao=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))}},co=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';
869
+ `),await g(t,r)}}},co=async e=>{let t=ce.join(e,c.TYPES_INDEX);if(m(t)){let r=await u(t);r.includes("./i18n")||(r+=`export * from './i18n';
870
+ `,await g(t,r))}},po=async e=>{let t=ce.join(e,c.CONFIG_INDEX);if(m(t)){let r=await u(t);r.includes("./app-locales")||(r+=`export * from './app-locales';
871
+ `,await g(t,r))}},lo=async e=>{let t=ce.join(e,"src/providers/RootProvider.tsx");if(m(t)){let r=await u(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;
875
875
  messages: AbstractIntlMessages;
876
- timeZone: string;`,s=/(type\s+RootProviderProps\s*=\s*\{)([\s\S]*?)(\};?)/,a=/export const RootProvider = \(\{([\s\S]*?)\}: \{([\s\S]*?)\}\) => \{/;if(s.test(r))r=r.replace(s,(p,u,d,h)=>{let P=d.replace(/\s+$/,"");return`${u}${P}
876
+ timeZone: string;`,s=/(type\s+RootProviderProps\s*=\s*\{)([\s\S]*?)(\};?)/,a=/export const RootProvider = \(\{([\s\S]*?)\}: \{([\s\S]*?)\}\) => \{/;if(s.test(r))r=r.replace(s,(p,f,d,h)=>{let x=d.replace(/\s+$/,"");return`${f}${x}
877
877
  ${o}
878
- ${h}`}),r=r.replace(/export const RootProvider = \(\{([\s\S]*?)\}:\s*RootProviderProps\)/,(p,u)=>{let d=u.trim().replace(/,$/,"");return`export const RootProvider = ({ ${d?`${d}, `:""}locale, messages, timeZone }: RootProviderProps)`});else{let p=r.match(a);if(p){let u=p[1].trim().replace(/,$/,""),d=p[2].trim().replace(/;$/,""),h=`
879
- ${u?`${u},
878
+ ${h}`}),r=r.replace(/export const RootProvider = \(\{([\s\S]*?)\}:\s*RootProviderProps\)/,(p,f)=>{let d=f.trim().replace(/,$/,"");return`export const RootProvider = ({ ${d?`${d}, `:""}locale, messages, timeZone }: RootProviderProps)`});else{let p=r.match(a);if(p){let f=p[1].trim().replace(/,$/,""),d=p[2].trim().replace(/;$/,""),h=`
879
+ ${f?`${f},
880
880
  `:""}locale,
881
881
  messages,
882
- timeZone,`,P=`
882
+ timeZone,`,x=`
883
883
  ${d?`${d};
884
884
  `:""}locale: SupportedLocale;
885
885
  messages: AbstractIntlMessages;
886
886
  timeZone: string;`;r=r.replace(p[0],`export const RootProvider = ({${h}
887
- }: {${P}
887
+ }: {${x}
888
888
  }) => {`)}}}if(!r.includes("<NextIntlClientProvider")){let o=r.match(/return\s*(?:\(\s*)?([\s\S]*?)(?:\s*\))?;/);if(o){let s=o[1],a=`<NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>
889
889
  {children}
890
890
  </NextIntlClientProvider>`;if(s.includes("{children}")){let p=s.replace("{children}",a);r=r.replace(o[0],`return (
@@ -893,19 +893,19 @@ ${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)}},po=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 cp.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';
896
+ );`)}}await g(t,r)}},mo=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 dp.mkdir(n,{recursive:!0}),m(t)){let i=ce.join(n,"layout.tsx"),o=await u(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';
900
900
  import { getLocaleDirection } from '@/lib/config/app-locales';
901
- ${o}`),!o.includes("generateStaticParams")){let p=o.indexOf("};",o.indexOf("export const metadata"));if(p!==-1){let u=p+2;o=o.slice(0,u)+`
901
+ ${o}`),!o.includes("generateStaticParams")){let p=o.indexOf("};",o.indexOf("export const metadata"));if(p!==-1){let f=p+2;o=o.slice(0,f)+`
902
902
 
903
903
  export function generateStaticParams() {
904
904
  return routing.locales.map((locale) => ({ locale }));
905
- }`+o.slice(u)}}o=o.replace(/Readonly<\{\s*children:\s*React\.ReactNode;\s*}>/,`Readonly<{
905
+ }`+o.slice(f)}}o=o.replace(/Readonly<\{\s*children:\s*React\.ReactNode;\s*}>/,`Readonly<{
906
906
  children: React.ReactNode;
907
907
  params: Promise<{ locale: string }>;
908
- }>`);let s=/export default (async )?function RootLayout\(\{\s*children,?\s*\}\s*:/,a=o.match(s);if(a){a[1]||(o=o.replace("export default function","export default async function")),o=o.replace(/export default (async )?function RootLayout\(\{\s*children,?\s*\}\s*:/,"export default async function RootLayout({ children, params }:");let u=/export default async function RootLayout[\s\S]*?\)\s*\{/,d=o.match(u);if(d&&d.index!==void 0){let h=d.index+d[0].length-1;o=o.slice(0,h+1)+`
908
+ }>`);let s=/export default (async )?function RootLayout\(\{\s*children,?\s*\}\s*:/,a=o.match(s);if(a){a[1]||(o=o.replace("export default function","export default async function")),o=o.replace(/export default (async )?function RootLayout\(\{\s*children,?\s*\}\s*:/,"export default async function RootLayout({ children, params }:");let f=/export default async function RootLayout[\s\S]*?\)\s*\{/,d=o.match(f);if(d&&d.index!==void 0){let h=d.index+d[0].length-1;o=o.slice(0,h+1)+`
909
909
  const { locale } = await params;
910
910
 
911
911
  if (!hasLocale(routing.locales, locale)) {
@@ -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 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';
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 u(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 C(r)}};var _t=async e=>{let t=b("Setting up Internationalization (next-intl)..."),r=br.join(e,".next-maker-temp-i18n");try{let{isSetup:n,reason:i}=await no(e);if(n){t.fail(`i18n is already set up (${i}).`);return}await io(e),await to(r,t),t.text="Copying i18n files...",await ro(e,r),t.text="Configuring project structure...",await oo(e),await so(e),await ao(e),await co(e),t.text="Migrating to [locale] structure...",await po(e),t.text="Installing dependencies...",await U(e,"next-intl");let o=br.join(e,c.VITEST_CONFIG);if(m(o)){let a=JSON.parse(await f(br.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 N(e);await J(e,s,"lint:fix"),t.succeed(pp.green("Internationalization setup successfully!"))}catch(n){throw t.fail("Failed to setup Internationalization."),n}finally{await w(r)}};var lo={id:"i18n",name:"Internationalization",description:"next-intl with [locale] routing, RootProvider, and proxy.ts",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(G(),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:ki},{file:"src/providers/RootProvider.tsx",description:"<NextIntlClientProvider> wrap",presence:/NextIntlClientProvider/,removePattern:_e("NextIntlClientProvider")}],apply:_t};S();x();import dp from"node:path";S();import lp from"node:path";import mp from"picocolors";x();var Ot=async e=>{let t=b("Enabling React Compiler...");try{let r=lp.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 ut(e,"babel-plugin-react-compiler"),t.succeed(mp.green("React Compiler enabled."))}catch(r){throw t.fail("Failed to enable React Compiler."),r}};var mo={id:"react-compiler",name:"React Compiler",description:"reactCompiler: true in next.config.ts + babel-plugin-react-compiler",detect:async e=>{let t=dp.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:Ot};S();import Ir from"node:path";import fp from"picocolors";x();S();x();import uo from"node:fs/promises";import Ee from"node:path";import up from"degit";var fo=async(e,t)=>{t.text="Fetching assets from starter repo...",await up("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},go=async(e,t)=>{let r=Ee.join(t,"src/providers/StoreProvider.tsx"),n=Ee.join(e,c.STORE_PROVIDER);await I(r,n);let i=Ee.join(t,"src/store"),o=Ee.join(e,c.STORE);await uo.cp(i,o,{recursive:!0})},ho=async(e,t)=>{let r=Ee.join(t,"src/features/counter"),n=Ee.join(e,c.COUNTER_FEATURE);await uo.cp(r,n,{recursive:!0});let i=Ee.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();x();import Rr from"node:path";var yo=async e=>{let t=Rr.join(e,c.STORE),r=Rr.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:""}},xo=async e=>{let t=Rr.join(e,c.PROVIDERS_INDEX);if(!await bt(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();x();import $r from"node:path";var Po=async e=>{},wo=async e=>{let t=$r.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 _t=async e=>{let t=b("Setting up Internationalization (next-intl)..."),r=Rr.join(e,".next-maker-temp-i18n");try{let{isSetup:n,reason:i}=await oo(e);if(n){t.fail(`i18n is already set up (${i}).`);return}await so(e),await no(r,t),t.text="Copying i18n files...",await io(e,r),t.text="Configuring project structure...",await ao(e),await co(e),await po(e),await lo(e),t.text="Migrating to [locale] structure...",await mo(e),t.text="Installing dependencies...",await U(e,"next-intl");let o=Rr.join(e,c.VITEST_CONFIG);if(m(o)){let a=JSON.parse(await u(Rr.join(e,c.PACKAGE_JSON))),p={...a.dependencies,...a.devDependencies},f=!!(p["@reduxjs/toolkit"]&&p["react-redux"]);await me(e,{redux:f,i18n:!0})}t.text="Formatting code...";let s=await k(e);await J(e,s,"lint:fix"),t.succeed(up.green("Internationalization setup successfully!"))}catch(n){throw t.fail("Failed to setup Internationalization."),n}finally{await w(r)}};var uo={id:"i18n",name:"Internationalization",description:"next-intl with [locale] routing, RootProvider, and proxy.ts",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(B(),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:_e("NextIntlClientProvider")}],apply:_t};S();P();import hp from"node:path";S();import fp from"node:path";import gp from"picocolors";P();var Ot=async e=>{let t=b("Enabling React Compiler...");try{let r=fp.join(e,c.NEXT_CONFIG);if(!m(r))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await u(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 ut(e,"babel-plugin-react-compiler"),t.succeed(gp.green("React Compiler enabled."))}catch(r){throw t.fail("Failed to enable React Compiler."),r}};var fo={id:"react-compiler",name:"React Compiler",description:"reactCompiler: true in next.config.ts + babel-plugin-react-compiler",detect:async e=>{let t=hp.join(e,c.NEXT_CONFIG);return m(t)?/reactCompiler\s*:\s*true/.test(await u(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:Ot};S();import Nr from"node:path";import xp from"picocolors";P();S();P();import go from"node:fs/promises";import Ee from"node:path";import yp from"degit";var ho=async(e,t)=>{t.text="Fetching assets from starter repo...",await yp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},yo=async(e,t)=>{let r=Ee.join(t,"src/providers/StoreProvider.tsx"),n=Ee.join(e,c.STORE_PROVIDER);await N(r,n);let i=Ee.join(t,"src/store"),o=Ee.join(e,c.STORE);await go.cp(i,o,{recursive:!0})},xo=async(e,t)=>{let r=Ee.join(t,"src/features/counter"),n=Ee.join(e,c.COUNTER_FEATURE);await go.cp(r,n,{recursive:!0});let i=Ee.join(n,"components/Counter.tsx");if(await m(i)){let o=await u(i);o=o.replace(/import \{ useTranslations \} from 'next-intl';\n?/,""),o=o.replace(/const t = useTranslations\('Count'\);\n?/,""),o=o.replace(/\{t\('currentCount', \{ count: value \}\)\}/g,"Current Count: {value}"),o=o.replace(/\{t\('increment'\)\}/g,"Increment"),o=o.replace(/\{t\('decrement'\)\}/g,"Decrement"),o=o.replace(/\{t\('reset'\)\}/g,"Reset"),await g(i,o)}};S();P();import $r from"node:path";var Po=async e=>{let t=$r.join(e,c.STORE),r=$r.join(e,"package.json");if(m(t))return{isSetup:!0,reason:"src/store directory exists"};if(m(r)){let n=JSON.parse(await u(r));if(n.dependencies?.["@reduxjs/toolkit"]||n.devDependencies?.["@reduxjs/toolkit"])return{isSetup:!0,reason:"@reduxjs/toolkit is installed"}}return{isSetup:!1,reason:""}},wo=async e=>{let t=$r.join(e,c.PROVIDERS_INDEX);if(!await bt(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 Ir from"node:path";var vo=async e=>{},So=async e=>{let t=Ir.join(e,"src/providers/RootProvider.tsx");if(!m(t))return;let r=await u(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)},vo=async e=>{let t=[$r.join(e,c.ROOT_PAGE),$r.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)},Eo=async e=>{let t=[Ir.join(e,c.ROOT_PAGE),Ir.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 u(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 Ft=async e=>{let t=b("Setting up Redux Toolkit..."),r=Ir.join(e,".next-maker-temp-redux");try{let{isSetup:n,reason:i}=await yo(e);if(n){t.fail(`Redux is already set up (${i}).`);return}await xo(e),await fo(r,t),t.text="Copying Redux files...",await go(e,r),t.text="Creating Counter feature...",await ho(e,r),t.text="Updating providers and pages...",await Po(e),await wo(e),await vo(e),t.text="Installing dependencies...",await U(e,"@reduxjs/toolkit"),await U(e,"react-redux"),await U(e,"redux-persist"),await U(e,"react-secure-storage");let o=Ir.join(e,c.VITEST_CONFIG);if(m(o)){let a=JSON.parse(await f(Ir.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 N(e);await J(e,s,"lint:fix"),t.succeed(fp.green("Redux Toolkit setup successfully!"))}catch(n){throw t.fail("Failed to setup Redux Toolkit."),n}finally{await w(r)}};var So={id:"redux",name:"Redux Toolkit",description:"Redux Toolkit + react-redux + redux-persist + StoreProvider",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(G(),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:_e("StoreProvider")}],apply:Ft};S();x();import Pp from"node:path";S();import yp from"node:path";import xp from"picocolors";x();var Co=[{key:"X-DNS-Prefetch-Control",value:"on"},{key:"Strict-Transport-Security",value:"max-age=63072000; includeSubDomains; preload"},{key:"X-XSS-Protection",value:"1; mode=block"},{key:"X-Frame-Options",value:"SAMEORIGIN"},{key:"X-Content-Type-Options",value:"nosniff"},{key:"Referrer-Policy",value:"origin-when-cross-origin"}],Eo=/(const\s+nextConfig\s*:\s*NextConfig\s*=\s*\{)/,gp=/^\s+headers\s*:/m,hp=e=>`
942
+ `+n.slice(s),await g(r,n))}};var Ft=async e=>{let t=b("Setting up Redux Toolkit..."),r=Nr.join(e,".next-maker-temp-redux");try{let{isSetup:n,reason:i}=await Po(e);if(n){t.fail(`Redux is already set up (${i}).`);return}await wo(e),await ho(r,t),t.text="Copying Redux files...",await yo(e,r),t.text="Creating Counter feature...",await xo(e,r),t.text="Updating providers and pages...",await vo(e),await So(e),await Eo(e),t.text="Installing dependencies...",await U(e,"@reduxjs/toolkit"),await U(e,"react-redux"),await U(e,"redux-persist"),await U(e,"react-secure-storage");let o=Nr.join(e,c.VITEST_CONFIG);if(m(o)){let a=JSON.parse(await u(Nr.join(e,c.PACKAGE_JSON))),p={...a.dependencies,...a.devDependencies};await me(e,{redux:!0,i18n:!!p["next-intl"]})}t.text="Formatting code...";let s=await k(e);await J(e,s,"lint:fix"),t.succeed(xp.green("Redux Toolkit setup successfully!"))}catch(n){throw t.fail("Failed to setup Redux Toolkit."),n}finally{await w(r)}};var Co={id:"redux",name:"Redux Toolkit",description:"Redux Toolkit + react-redux + redux-persist + StoreProvider",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(B(),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:_e("StoreProvider")}],apply:Ft};S();P();import Ep from"node:path";S();import vp from"node:path";import Sp from"picocolors";P();var bo=[{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"}],To=/(const\s+nextConfig\s*:\s*NextConfig\s*=\s*\{)/,Pp=/^\s+headers\s*:/m,wp=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
- },`,Oe=e=>gp.test(e),Nr=(e,t=Co)=>{if(Oe(e))return e;if(!Eo.test(e))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");return e.replace(Eo,`$1${hp(t)}`)};var jt=async e=>{let t=b("Adding security headers to next.config.ts...");try{let r=yp.join(e,c.NEXT_CONFIG);if(!m(r))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await f(r);if(Oe(n)){t.succeed("Security headers already configured.");return}let i=Nr(n);await g(r,i),t.succeed(xp.green("Security headers added."))}catch(r){throw t.fail("Failed to add security headers."),r}};var To={id:"security-headers",name:"Security Headers",description:"Hardened HTTP headers in next.config.ts",detect:async e=>{let t=Pp.join(e,c.NEXT_CONFIG);return m(t)?Oe(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:jt};S();x();import Cp from"node:path";S();import wp from"node:fs/promises";import fe from"node:path";import vp from"degit";import Sp from"picocolors";x();var Ep=["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=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 vp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(r),await I(fe.join(r,c.VITEST_CONFIG),fe.join(e,c.VITEST_CONFIG));let o=fe.join(e,c.TEST_DIR);await wp.mkdir(o,{recursive:!0}),await I(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,P=>(P.scripts=P.scripts??{},P.scripts.test=P.scripts.test??"vitest run",P.scripts["test:watch"]=P.scripts["test:watch"]??"vitest",P.scripts["test:coverage"]=P.scripts["test:coverage"]??"vitest run --coverage",typeof P.scripts.validate=="string"&&!/\byarn\s+test(?![:\w])/.test(P.scripts.validate)&&(P.scripts.validate=P.scripts.validate.replace(/(\byarn\s+check:deprecated\s*)(&&)/,"$1&& yarn test $2")),P)),t.text="Installing testing devDependencies...";let h=await N(e);await Pe(e,h,Ep),t.text="Formatting code...",await J(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 bo={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};x();import Ip from"node:path";S();import Ro from"node:path";import Rp from"picocolors";x();var Tp={npm:"npm run",yarn:"yarn",pnpm:"pnpm",bun:"bun run"},bp=e=>{let t=Tp[e];return["ci:check","type-check","check:deprecated","test","build"].map(r=>`${t} ${r}`).join(" && ")},kr=(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=bp(t)),!n.tsx&&!Object.hasOwn(e.dependencies??{},"tsx")&&(n.tsx="*"),{...e,scripts:r,devDependencies:n}};var Ar=`import * as fs from 'node:fs';
953
+ },`,Oe=e=>Pp.test(e),kr=(e,t=bo)=>{if(Oe(e))return e;if(!To.test(e))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");return e.replace(To,`$1${wp(t)}`)};var jt=async e=>{let t=b("Adding security headers to next.config.ts...");try{let r=vp.join(e,c.NEXT_CONFIG);if(!m(r))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await u(r);if(Oe(n)){t.succeed("Security headers already configured.");return}let i=kr(n);await g(r,i),t.succeed(Sp.green("Security headers added."))}catch(r){throw t.fail("Failed to add security headers."),r}};var Ro={id:"security-headers",name:"Security Headers",description:"Hardened HTTP headers in next.config.ts",detect:async e=>{let t=Ep.join(e,c.NEXT_CONFIG);return m(t)?Oe(await u(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:jt};S();P();import $p from"node:path";S();import Cp from"node:fs/promises";import ge from"node:path";import Tp from"degit";import bp from"picocolors";P();var Rp=["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=ge.join(e,".next-maker-temp-tests");try{let n=ge.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 Tp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(r),await N(ge.join(r,c.VITEST_CONFIG),ge.join(e,c.VITEST_CONFIG));let o=ge.join(e,c.TEST_DIR);await Cp.mkdir(o,{recursive:!0}),await N(ge.join(r,c.TEST_DIR,"setup.ts"),ge.join(o,"setup.ts"));let s=ge.join(e,c.PACKAGE_JSON),a=JSON.parse(await u(s)),p={...a.dependencies,...a.devDependencies},f=!!(p["@reduxjs/toolkit"]&&p["react-redux"]),d=!!p["next-intl"];await me(e,{redux:f,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 Pe(e,h,Rp),t.text="Formatting code...",await J(e,h,"lint:fix"),t.succeed(bp.green("Testing setup complete."))}catch(n){throw t.fail("Failed to set up testing."),n}finally{await w(r)}};var $o={id:"tests",name:"Tests",description:"Vitest + React Testing Library + jsdom",detect:async e=>m($p.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 _p from"node:path";S();import Io from"node:path";import kp from"picocolors";P();var Ip={npm:"npm run",yarn:"yarn",pnpm:"pnpm",bun:"bun run"},Np=e=>{let t=Ip[e];return["ci:check","type-check","check:deprecated","test","build"].map(r=>`${t} ${r}`).join(" && ")},Ar=(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=Np(t)),!n.tsx&&!Object.hasOwn(e.dependencies??{},"tsx")&&(n.tsx="*"),{...e,scripts:r,devDependencies:n}};var _r=`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
+ `,Or=`/**
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,118 +1088,118 @@ if (hits === 0) {
1088
1088
 
1089
1089
  console.log(\`\\n\${hits} deprecated symbol use(s) found.\`);
1090
1090
  process.exit(1);
1091
- `;var $p=[{relative:"scripts/sync-env.ts",content:Ar},{relative:"scripts/check-deprecated.ts",content:_r}],Lt=async e=>{let t=b("Adding validation scripts...");try{let r=!1;for(let{relative:o,content:s}of $p){let a=Ro.join(e,o);m(a)||(await g(a,s),r=!0)}let n=await N(e),i=!1;await D(Ro.join(e,c.PACKAGE_JSON),o=>{let s=o.devDependencies?.tsx,a=kr(o,n);return i=!s&&!!a.devDependencies?.tsx,a}),i&&(t.text="Installing tsx...",await Pe(e,n,["tsx"])),t.succeed(Rp.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 $o=["scripts/sync-env.ts","scripts/check-deprecated.ts"],Io={id:"validate-scripts",name:"Validation Scripts",description:"sync-env, check-deprecated, and the validate chain",detect:async e=>$o.every(t=>m(Ip.join(e,t))),files:$o.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:Lt};import{access as _p,readFile as Op}from"node:fs/promises";import Fo from"node:path";S();import Fr from"node:path";import Ap from"picocolors";x();S();x();import Or from"node:fs/promises";import st from"node:path";import Np from"degit";var No=async(e,t)=>{t.text="Downloading assets from starter repository...",await Np("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},ko=async(e,t,r)=>{let n=st.join(e,c.WS_UTILS);await Or.cp(st.join(t,c.WS_UTILS),n,{recursive:!0,force:!0});let i=st.join(e,c.WS_SLICE_FILE);await I(st.join(t,c.WS_SLICE_FILE),i),r.keepTests||await kp(n)},kp=async e=>{let t=async r=>{let n=await Or.readdir(r,{withFileTypes:!0});for(let i of n){let o=st.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 Or.unlink(o)}};await t(e)};S();x();import Ao from"node:path";var _o=async e=>{let t=Ao.join(e,c.WS_UTILS);return m(t)?{isSetup:!0,reason:"src/lib/utils/ws/ already exists"}:{isSetup:!1}},Oo=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(Ao.join(e,n))||t.push(`- ${i}`);if(t.length>0)throw new Error(`WebSocket setup requires Redux Toolkit. Missing:
1091
+ `;var Ap=[{relative:"scripts/sync-env.ts",content:_r},{relative:"scripts/check-deprecated.ts",content:Or}],Lt=async e=>{let t=b("Adding validation scripts...");try{let r=!1;for(let{relative:o,content:s}of Ap){let a=Io.join(e,o);m(a)||(await g(a,s),r=!0)}let n=await k(e),i=!1;await D(Io.join(e,c.PACKAGE_JSON),o=>{let s=o.devDependencies?.tsx,a=Ar(o,n);return i=!s&&!!a.devDependencies?.tsx,a}),i&&(t.text="Installing tsx...",await Pe(e,n,["tsx"])),t.succeed(kp.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 No=["scripts/sync-env.ts","scripts/check-deprecated.ts"],ko={id:"validate-scripts",name:"Validation Scripts",description:"sync-env, check-deprecated, and the validate chain",detect:async e=>No.every(t=>m(_p.join(e,t))),files:No.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:Lt};import{access as Dp,readFile as Lp}from"node:fs/promises";import Do from"node:path";S();import jr from"node:path";import jp from"picocolors";P();S();P();import Fr from"node:fs/promises";import st from"node:path";import Op from"degit";var Ao=async(e,t)=>{t.text="Downloading assets from starter repository...",await Op("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},_o=async(e,t,r)=>{let n=st.join(e,c.WS_UTILS);await Fr.cp(st.join(t,c.WS_UTILS),n,{recursive:!0,force:!0});let i=st.join(e,c.WS_SLICE_FILE);await N(st.join(t,c.WS_SLICE_FILE),i),r.keepTests||await Fp(n)},Fp=async e=>{let t=async r=>{let n=await Fr.readdir(r,{withFileTypes:!0});for(let i of n){let o=st.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 Fr.unlink(o)}};await t(e)};S();P();import Oo from"node:path";var Fo=async e=>{let t=Oo.join(e,c.WS_UTILS);return m(t)?{isSetup:!0,reason:"src/lib/utils/ws/ already exists"}:{isSetup:!1}},jo=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(Oo.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 Mt=async e=>{let t=b("Setting up WebSocket layer..."),r=Fr.join(e,".next-maker-temp-ws");try{let{isSetup:n,reason:i}=await _o(e);if(n){t.fail(`WebSocket layer is already set up (${i}).`);return}await Oo(e),await No(r,t),t.text="Copying WebSocket files...";let o=m(Fr.join(e,c.VITEST_CONFIG));await ko(e,r,{keepTests:o}),t.text="Registering wsReducer...",await Mn(e),t.text="Mounting WS bridge in StoreProvider...",await Un(e),t.text="Ensuring test/setup.ts mocks...",await Hn(e),t.text="Installing socket.io-client...";let s=Fr.join(e,c.PACKAGE_JSON),a=JSON.parse(await f(s));({...a.dependencies,...a.devDependencies})["socket.io-client"]||await U(e,"socket.io-client@^4.8.3"),t.text="Formatting code...";let u=await N(e);await J(e,u,"lint:fix"),t.succeed(Ap.green("WebSocket layer setup successfully!"))}catch(n){throw t.fail("Failed to setup WebSocket layer."),n}finally{await w(r)}};var Fp=async e=>{try{let t=JSON.parse(await Op(Fo.join(e,"package.json"),"utf-8"));return{...t.dependencies,...t.devDependencies}["socket.io-client"]?(await _p(Fo.join(e,"src/lib/utils/ws")),!0):!1}catch{return!1}},jo={id:"ws",name:"WebSocket Client",description:"socket.io-client + lazy WS singleton + Redux slice + hooks",detect:Fp,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:ht},{file:"src/providers/StoreProvider.tsx",description:"attachWsBridge mount in StoreProvider",presence:/attachWsBridge\(wsClient,\s*store\.dispatch\)/,removePattern:gt}],apply:Mt};S();x();import Fe from"node:path";var Do=async e=>{let t=Fe.join(e,c.PACKAGE_JSON);return m(t)?JSON.parse(await f(t)):null},jp=async(e,t)=>{let r=Fe.join(e,c.PACKAGE_JSON);await g(r,`${JSON.stringify(t,null,2)}
1096
- `)},Lo=(e,t)=>(t==="dependency"?e.dependencies:e.devDependencies)??{},at=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(Fe.join(t,o.path))||n.push({kind:"missingFile",file:o.path}));let i=await Do(t);if(i){for(let s of e.packages)Lo(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=Fe.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}},Ut=async(e,t,r={})=>{let n=r.dryRun??!1,i={filesRemoved:[],packagesUninstalled:[],scriptsRemoved:[],blocksStripped:[],manualCleanup:[]};for(let a of e.injections){let p=Fe.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=Fe.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 Do(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)Lo(s,p.kind)[p.name]&&i.packagesUninstalled.push(p.name);a&&!n&&await jp(t,s)}if(!n&&i.packagesUninstalled.length>0){let a=await N(t);await qt(t,a,i.packagesUninstalled)}return i};var Ce=[To,Io,Fi,mo,_i,bo,Vi,eo,So,jo,lo],Mo=e=>Ce.find(t=>t.id===e);var Dp=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}`}},Lp=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}},Uo=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 at(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 Mt=async e=>{let t=b("Setting up WebSocket layer..."),r=jr.join(e,".next-maker-temp-ws");try{let{isSetup:n,reason:i}=await Fo(e);if(n){t.fail(`WebSocket layer is already set up (${i}).`);return}await jo(e),await Ao(r,t),t.text="Copying WebSocket files...";let o=m(jr.join(e,c.VITEST_CONFIG));await _o(e,r,{keepTests:o}),t.text="Registering wsReducer...",await Un(e),t.text="Mounting WS bridge in StoreProvider...",await Hn(e),t.text="Ensuring test/setup.ts mocks...",await Bn(e),t.text="Installing socket.io-client...";let s=jr.join(e,c.PACKAGE_JSON),a=JSON.parse(await u(s));({...a.dependencies,...a.devDependencies})["socket.io-client"]||await U(e,"socket.io-client@^4.8.3"),t.text="Formatting code...";let f=await k(e);await J(e,f,"lint:fix"),t.succeed(jp.green("WebSocket layer setup successfully!"))}catch(n){throw t.fail("Failed to setup WebSocket layer."),n}finally{await w(r)}};var Mp=async e=>{try{let t=JSON.parse(await Lp(Do.join(e,"package.json"),"utf-8"));return{...t.dependencies,...t.devDependencies}["socket.io-client"]?(await Dp(Do.join(e,"src/lib/utils/ws")),!0):!1}catch{return!1}},Lo={id:"ws",name:"WebSocket Client",description:"socket.io-client + lazy WS singleton + Redux slice + hooks",detect:Mp,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:ht},{file:"src/providers/StoreProvider.tsx",description:"attachWsBridge mount in StoreProvider",presence:/attachWsBridge\(wsClient,\s*store\.dispatch\)/,removePattern:gt}],apply:Mt};S();P();import Fe from"node:path";var Mo=async e=>{let t=Fe.join(e,c.PACKAGE_JSON);return m(t)?JSON.parse(await u(t)):null},Gp=async(e,t)=>{let r=Fe.join(e,c.PACKAGE_JSON);await g(r,`${JSON.stringify(t,null,2)}
1096
+ `)},Go=(e,t)=>(t==="dependency"?e.dependencies:e.devDependencies)??{},at=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(Fe.join(t,o.path))||n.push({kind:"missingFile",file:o.path}));let i=await Mo(t);if(i){for(let s of e.packages)Go(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=Fe.join(t,o.file);if(!m(s)){n.push({kind:"missingInjection",file:o.file,description:o.description});continue}let a=await u(s);o.presence.test(a)||n.push({kind:"missingInjection",file:o.file,description:o.description})}return{manifest:e,installed:r,drift:n}},Gt=async(e,t,r={})=>{let n=r.dryRun??!1,i={filesRemoved:[],packagesUninstalled:[],scriptsRemoved:[],blocksStripped:[],manualCleanup:[]};for(let a of e.injections){let p=Fe.join(t,a.file);if(!m(p))continue;if(!a.removePattern){i.manualCleanup.push({file:a.file,description:a.description});continue}let f=await u(p);if(!a.presence.test(f))continue;let d;if(typeof a.removePattern=="function"){let h=a.removePattern(f);if(h===null){i.manualCleanup.push({file:a.file,description:a.description});continue}d=h}else d=f.replace(a.removePattern,"");d!==f?(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=Fe.join(t,a.path);if(m(p)){if(a.containsUserContent){let f=a.removeHint?`${a.path} \u2014 ${a.removeHint}`:`${a.path} (may contain user-authored files; review before deleting)`;i.manualCleanup.push({file:a.path,description:f});continue}n||await o(p,{recursive:!0,force:!0}),i.filesRemoved.push(a.path)}}let s=await Mo(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)Go(s,p.kind)[p.name]&&i.packagesUninstalled.push(p.name);a&&!n&&await Gp(t,s)}if(!n&&i.packagesUninstalled.length>0){let a=await k(t);await qt(t,a,i.packagesUninstalled)}return i};var Ce=[Ro,ko,Di,fo,Fi,$o,qi,ro,Co,Lo,uo],Uo=e=>Ce.find(t=>t.id===e);var Up=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 ${M.dim(e.expected)} but got ${M.dim(e.actual)}`;case"missingInjection":return`missing block in ${e.file}: ${e.description}`}},Hp=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}},Ho=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 at(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(M.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")} ${Dp(d)}`)}let o=Lp(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:f}=s;if(!p){l(` ${M.dim("\u2014")} ${M.dim(a.name)} ${M.dim("(not installed)")}`);continue}if(f.length===0){l(` ${M.green("\u2713")} ${a.name}`);continue}l(` ${M.yellow("!")} ${M.bold(a.name)} ${M.dim(`(${f.length} issue${f.length===1?"":"s"})`)}`);for(let d of f)l(` ${M.yellow("\u2022")} ${Up(d)}`)}let o=Hp(i);l(""),l(M.dim(`${o.cleanCount} clean, ${o.driftedCount} drifted, ${i.length-o.installedCount} not installed`)),o.driftedCount===0&&(l(M.green(`
1099
1099
  \u2713 No drift detected.
1100
- `)),process.exit(0)),t.fix||(l(L.dim(`
1100
+ `)),process.exit(0)),t.fix||(l(M.dim(`
1101
1101
  Run with --fix to re-apply drifted features.
1102
- `)),process.exit(1)),l(L.cyan(`
1102
+ `)),process.exit(1)),l(M.cyan(`
1103
1103
  \u{1F527} Applying fixes...
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(`
1104
+ `));for(let s of o.driftedResults){if(!s.manifest.apply){l(M.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(M.green(`
1105
1105
  \u2713 Doctor finished.
1106
- `))}catch(r){v(`${r instanceof Error?r.message:r}`),process.exit(1)}})};import je from"picocolors";S();x();import jr from"node:path";var Mp=/^[A-Z][A-Z0-9_]*$/,Go=e=>{if(!Mp.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,Up=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,"\\'")}')`}},Hp=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()"}},Bo=e=>{let t=ge(e.name,e.public),n=Hp(e),i=e.default!==void 0,o=!e.required&&!i;i&&(n+=Up(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},`},Ho=/(export const envSchema\s*=\s*z\.object\(\{)([\s\S]*?)(\}\);?)/,zo=(e,t)=>{let r=ge(t.name,t.public);if(new RegExp(`\\b${r}\\s*:`).test(e))return e;let i=e.match(Ho);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=Bo(t),h=`${u}
1108
- ${d}
1109
- `;return e.replace(Ho,`${o}${h}${a}`)},Gp="# -public",Bp=e=>{let t=ge(e.name,e.public),r=e.default??"",n=e.public?` ${Gp}`:"";return`${t}=${r}${n}`},Jo=(e,t)=>{let r=ge(t.name,t.public);if(new RegExp(`^${r}=`,"m").test(e))return e;let i=e===""||e.endsWith(`
1106
+ `))}catch(r){v(`${r instanceof Error?r.message:r}`),process.exit(1)}})};import je from"picocolors";S();P();import Dr from"node:path";var Bp=/^[A-Z][A-Z0-9_]*$/,Vo=e=>{if(!Bp.test(e))throw new Error(`Invalid env var name "${e}". Use UPPER_SNAKE_CASE (e.g. SENTRY_DSN, NEXT_PUBLIC_API_URL).`)},pe=(e,t)=>t?e.startsWith("NEXT_PUBLIC_")?e:`NEXT_PUBLIC_${e}`:e,Lr=e=>e.public?"client":"server",zp=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,"\\'")}')`}},Vp=e=>{switch(e.type){case"url":return"e.url()";case"number":return"e.number()";case"boolean":return"e.boolean()";case"enum":{let t=e.enumValues??[];if(t.length===0)throw new Error(`Enum env var "${e.name}" requires --enum values.`);return`e.enum([${t.map(n=>`'${n.replace(/'/g,"\\'")}'`).join(", ")}])`}default:return"e.string()"}},Jo=e=>{let t=pe(e.name,e.public),r=Vp(e),n=e.default!==void 0,i=!e.required&&!n;if(n&&(r+=zp(e)),i&&(r+=".optional()"),e.description){let o=e.description.replace(/'/g,"\\'");r+=`
1107
+ .describe('${o}')`}return` ${t}: ${r},`},Wo=e=>{let t=pe(e.name,e.public);return` ${t}: process.env.${t},`},Jp=e=>new RegExp(`(${e}:\\s*\\{)([\\s\\S]*?)(\\n\\s*\\})`),Bo=/(runtimeEnv:\s*\{)([\s\S]*?)(\n\s*\})/,zo=(e,t,r,n)=>{let i=t.replace(/\s+$/,""),o=i.length===0||/,\s*$/.test(i)?i:`${i},`;return`${e}${o}
1108
+ ${n}
1109
+ ${r.replace(/^\n/,"")}`},qo=(e,t)=>{let r=pe(t.name,t.public),n=Lr(t);if(new RegExp(`\\b${r}\\s*:`).test(e))return e;if(!/defineEnv\(\{/.test(e))throw new Error("Could not locate `defineEnv({ \u2026 })` in src/lib/env/index.ts. Is this a @teispace/env project?");let o=Jp(n),s=e.match(o);if(!s)throw new Error(`Could not locate the \`${n}: { \u2026 }\` group in src/lib/env/index.ts.`);let[,a,p,f]=s,d=Jo(t),h=e.replace(o,zo(a,p,f,d)),x=h.match(Bo);if(!x)throw new Error("Could not locate the `runtimeEnv: { \u2026 }` map in src/lib/env/index.ts.");let[,R,L,$]=x;return h=h.replace(Bo,zo(R,L,$,Wo(t))),h},Wp="# -public",qp=e=>{let t=pe(e.name,e.public),r=e.default??"",n=e.public?` ${Wp}`:"";return`${t}=${r}${n}`},Xo=(e,t)=>{let r=pe(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}${Bp(t)}
1114
- `},Vo=(e,t)=>{let r=ge(t.name,t.public);if(new RegExp(`^${r}=`,"m").test(e))return e;let i=e===""||e.endsWith(`
1113
+ `:"";return`${e}${i}${o}${s}${qp(t)}
1114
+ `},Yo=(e,t)=>{let r=pe(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
- `},Dr=async(e,t)=>{Go(t.name);let r=jr.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=zo(n,t),o=i!==n;o&&await g(r,i);let s=jr.join(e,c.ENV_EXAMPLE),a=!1;if(m(s)){let d=await f(s),h=Jo(d,t);a=h!==d,a&&await g(s,h)}let p=jr.join(e,".env"),u=!1;if(m(p)){let d=await f(p),h=Vo(d,t);u=h!==d,u&&await g(p,h)}return{schemaUpdated:o,envExampleUpdated:a,envUpdated:u}};var Wo=new Set(["string","url","number","boolean","enum"]),zp=e=>{let t=(e??"string").toLowerCase();if(!Wo.has(t))throw new Error(`Invalid --type "${e}". Valid: ${Array.from(Wo).join(", ")}.`);return t},Jp=e=>{if(!e)return;let t=e.split(",").map(r=>r.trim()).filter(Boolean);return t.length===0?void 0:t},qo=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(je.cyan(`
1117
+ `},Mr=async(e,t)=>{Vo(t.name);let r=Dr.join(e,"src/lib/env/index.ts");if(!m(r))throw new Error("src/lib/env/index.ts not found \u2014 run `next-maker init` first.");let n=await u(r),i=qo(n,t),o=i!==n;o&&await g(r,i);let s=Dr.join(e,c.ENV_EXAMPLE),a=!1;if(m(s)){let d=await u(s),h=Xo(d,t);a=h!==d,a&&await g(s,h)}let p=Dr.join(e,".env"),f=!1;if(m(p)){let d=await u(p),h=Yo(d,t);f=h!==d,f&&await g(p,h)}return{schemaUpdated:o,envExampleUpdated:a,envUpdated:f,group:Lr(t)}};var Ko=new Set(["string","url","number","boolean","enum"]),Xp=e=>{let t=(e??"string").toLowerCase();if(!Ko.has(t))throw new Error(`Invalid --type "${e}". Valid: ${Array.from(Ko).join(", ")}.`);return t},Yp=e=>{if(!e)return;let t=e.split(",").map(r=>r.trim()).filter(Boolean);return t.length===0?void 0:t},Zo=e=>{e.command("env <NAME>").description("Declare a new environment variable across src/lib/env/index.ts, .env.example, and .env").option("--type <type>","Coercer 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: place in the client group, auto-prefix NEXT_PUBLIC_, 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(je.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=zp(r.type),o=Jp(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 Dr(n,s);y.succeed("Env var written");let p=ge(s.name,s.public);l(je.green(`
1120
- \u2728 ${p} declared.
1121
- `)),l(je.dim("Touched:")),l(je.dim(` ${a.schemaUpdated?"\u270F\uFE0F ":"\u23ED "} src/lib/env/schema.ts`)),l(je.dim(` ${a.envExampleUpdated?"\u270F\uFE0F ":"\u23ED "} .env.example`)),l(je.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 Bt from"node:path";import be from"picocolors";import Vp from"enquirer";var{prompt:Wp}=Vp,Xo=async(e={})=>e.source?{source:e.source}:{source:(await Wp({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 qp,readFile as Xp,stat as Yp}from"node:fs/promises";import Te from"node:path";var Yo=async e=>{try{return await qp(e),!0}catch{return!1}},Kp=async e=>{try{return(await Yp(e)).isDirectory()}catch{return!1}},Ht=async e=>{let t=[Te.join(e,"src","app"),Te.join(e,"app")];for(let r of t)if(await Kp(r))return r;return null},Zp=["next-pwa","@ducanh2912/next-pwa","@serwist/next","serwist"],Lr=async e=>{let t={isPwa:!1},r=[Te.join(e,"public","manifest.json"),Te.join(e,"public","manifest.webmanifest"),Te.join(e,"public","site.webmanifest")];for(let i of r)if(await Yo(i)){t.publicManifestPath=i,t.isPwa=!0;break}let n=await Ht(e);if(n)for(let i of["ts","tsx","js"]){let o=Te.join(n,`manifest.${i}`);if(await Yo(o)){t.appManifestPath=o,t.isPwa=!0;break}}try{let i=JSON.parse(await Xp(Te.join(e,"package.json"),"utf-8")),o={...i.dependencies,...i.devDependencies};for(let s of Zp)if(o[s]){t.framework=s,t.isPwa=!0;break}}catch{}return t};import{mkdir as nl,readFile as ss,stat as il,writeFile as ol}from"node:fs/promises";import ie from"node:path";import sl from"sharp";import el from"png-to-ico";import ct from"sharp";var Ko=e=>e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;"),Mr=(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="${Ko(n)}" fill="white"/></svg>`},Zo=(e,t)=>`<svg xmlns="http://www.w3.org/2000/svg" width="${e}" height="${e}"><rect width="${e}" height="${e}" fill="${Ko(t)}"/></svg>`;var De=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",P=await ct(u,{density:384}).resize(d,d,{fit:h,background:{r:0,g:0,b:0,alpha:0}}).png().toBuffer(),O=Math.round((t-d)/2),V=n==="transparent"?{r:0,g:0,b:0,alpha:0}:await Ur(n),$=await ct({create:{width:t,height:t,channels:4,background:V}}).composite([{input:P,left:O,top:O}]).png().toBuffer();if(!p&&(o!=="square"||i==="clip")){let mt=o==="square"?"rounded":o,Ds=Buffer.from(Mr(mt,t,s));$=await ct($).composite([{input:Ds,blend:"dest-in"}]).png({compressionLevel:Qo(a)}).toBuffer()}else $=await ct($).png({compressionLevel:Qo(a)}).toBuffer();return $},Ur=async e=>{let t=await ct(Buffer.from(Zo(1,e))).raw().toBuffer({resolveWithObject:!0}),[r,n,i,o=255]=t.data;return{r,g:n,b:i,alpha:o/255}},Qo=e=>{let t=Math.round((100-e)/100*9);return Math.max(0,Math.min(9,t))},es=async e=>{if(e.length===0)throw new Error("No frames provided to encodeIco");return el(e)};import{readFile as tl,writeFile as rv}from"node:fs/promises";var ts=e=>e.map(({src:t,size:r})=>({src:t,sizes:`${r}x${r}`,type:"image/png",purpose:"any maskable"})),rs=async(e,t)=>{let r=await tl(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 ns=e=>`icons: [
1119
+ `)),r.required&&r.default!==void 0)throw new Error("--required and --default are mutually exclusive.");let i=Xp(r.type),o=Yp(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 src/lib/env/index.ts, .env.example, and .env...");let a=await Mr(n,s);y.succeed("Env var written");let p=pe(s.name,s.public);l(je.green(`
1120
+ \u2728 ${p} declared in the ${a.group} group.
1121
+ `)),l(je.dim("Touched:")),l(je.dim(` ${a.schemaUpdated?"\u270F\uFE0F ":"\u23ED "} src/lib/env/index.ts`)),l(je.dim(` ${a.envExampleUpdated?"\u270F\uFE0F ":"\u23ED "} .env.example`)),l(je.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 Bt from"node:path";import be from"picocolors";import Kp from"enquirer";var{prompt:Zp}=Kp,Qo=async(e={})=>e.source?{source:e.source}:{source:(await Zp({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 Qp,readFile as el,stat as tl}from"node:fs/promises";import Te from"node:path";var es=async e=>{try{return await Qp(e),!0}catch{return!1}},rl=async e=>{try{return(await tl(e)).isDirectory()}catch{return!1}},Ut=async e=>{let t=[Te.join(e,"src","app"),Te.join(e,"app")];for(let r of t)if(await rl(r))return r;return null},nl=["next-pwa","@ducanh2912/next-pwa","@serwist/next","serwist"],Gr=async e=>{let t={isPwa:!1},r=[Te.join(e,"public","manifest.json"),Te.join(e,"public","manifest.webmanifest"),Te.join(e,"public","site.webmanifest")];for(let i of r)if(await es(i)){t.publicManifestPath=i,t.isPwa=!0;break}let n=await Ut(e);if(n)for(let i of["ts","tsx","js"]){let o=Te.join(n,`manifest.${i}`);if(await es(o)){t.appManifestPath=o,t.isPwa=!0;break}}try{let i=JSON.parse(await el(Te.join(e,"package.json"),"utf-8")),o={...i.dependencies,...i.devDependencies};for(let s of nl)if(o[s]){t.framework=s,t.isPwa=!0;break}}catch{}return t};import{mkdir as cl,readFile as ls,stat as pl,writeFile as ll}from"node:fs/promises";import ie from"node:path";import ml from"sharp";import ol from"png-to-ico";import ct from"sharp";var ts=e=>e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;"),Ur=(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 il(t)}},il=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="${ts(n)}" fill="white"/></svg>`},rs=(e,t)=>`<svg xmlns="http://www.w3.org/2000/svg" width="${e}" height="${e}"><rect width="${e}" height="${e}" fill="${ts(t)}"/></svg>`;var De=async e=>{let{size:t,paddingPercent:r,bg:n,fit:i,shape:o,radiusPercent:s,quality:a,forceSquare:p,sourceBuffer:f}=e,d=Math.max(1,Math.round(t*(1-r*2/100))),h=i==="cover"?"cover":"contain",x=await ct(f,{density:384}).resize(d,d,{fit:h,background:{r:0,g:0,b:0,alpha:0}}).png().toBuffer(),R=Math.round((t-d)/2),L=n==="transparent"?{r:0,g:0,b:0,alpha:0}:await Hr(n),$=await ct({create:{width:t,height:t,channels:4,background:L}}).composite([{input:x,left:R,top:R}]).png().toBuffer();if(!p&&(o!=="square"||i==="clip")){let mt=o==="square"?"rounded":o,Us=Buffer.from(Ur(mt,t,s));$=await ct($).composite([{input:Us,blend:"dest-in"}]).png({compressionLevel:ns(a)}).toBuffer()}else $=await ct($).png({compressionLevel:ns(a)}).toBuffer();return $},Hr=async e=>{let t=await ct(Buffer.from(rs(1,e))).raw().toBuffer({resolveWithObject:!0}),[r,n,i,o=255]=t.data;return{r,g:n,b:i,alpha:o/255}},ns=e=>{let t=Math.round((100-e)/100*9);return Math.max(0,Math.min(9,t))},is=async e=>{if(e.length===0)throw new Error("No frames provided to encodeIco");return ol(e)};import{readFile as sl,writeFile as av}from"node:fs/promises";var os=e=>e.map(({src:t,size:r})=>({src:t,sizes:`${r}x${r}`,type:"image/png",purpose:"any maskable"})),ss=async(e,t)=>{let r=await sl(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 as=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
- ],`,is=(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 rl}from"node:fs/promises";import Hr from"node:path";var os=[".png",".jpg",".jpeg",".webp",".svg",".avif"],Gt=async e=>{if(!e)throw new Error("Source image path is required (use --path).");let t=Hr.isAbsolute(e)?e:Hr.resolve(process.cwd(),e),r;try{r=await rl(t)}catch{throw new Error(`Source image not found: ${t}`)}if(!r.isFile())throw new Error(`Source is not a file: ${t}`);let n=Hr.extname(t).toLowerCase();if(!os.includes(n))throw new Error(`Unsupported source format '${n}'. Use one of: ${os.join(", ")}`);return{absolutePath:t,ext:n,bytes:r.size,isVector:n===".svg"}};var Gr=(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 al=async e=>{try{return await il(e),!0}catch{return!1}},cl=async(e,t,r)=>{let n=[];for(let i of e){if(await al(i.outPath)&&!t&&!i.alwaysWrite){n.push({path:i.outPath,bytes:i.bytes.length,skipped:!0});continue}r||(await nl(ie.dirname(i.outPath),{recursive:!0}),await ol(i.outPath,i.bytes)),n.push({path:i.outPath,bytes:i.bytes.length})}return n},Br=async(e,t)=>{let r=await Gt(t.source),n=await ss(r.absolutePath),i=t.ogSource?await ss((await Gt(t.ogSource)).absolutePath):n,o=[],s=[];for(let d of t.icoSizes)s.push(await De({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 es(s);if(o.push({outPath:ie.join(t.outDir,"favicon.ico"),bytes:a}),t.emitIcon){let d=await De({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 De({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 as(i,t,!1);o.push({outPath:ie.join(t.outDir,"opengraph-image.png"),bytes:d})}if(t.emitTwitter){let d=await as(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 Lr(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"),P=[192,512],O=[];for(let $ of P){let W=await De({sourceBuffer:n,size:$,shape:t.shape,radiusPercent:t.radius,bg:t.bg,paddingPercent:t.padding,fit:t.fit,quality:t.quality}),mt=`icon-${$}.png`;o.push({outPath:ie.join(h,mt),bytes:W}),O.push({src:`/${mt}`,size:$})}let V=ts(O);if(d.publicManifestPath){let $=await rs(d.publicManifestPath,V);o.push({outPath:d.publicManifestPath,bytes:Buffer.from($,"utf-8"),alwaysWrite:!0})}else if(d.appManifestPath)p=ns(V);else if(t.pwaInit){let $=ie.join(h,"manifest.webmanifest"),W=is(ie.basename(e)||"App","#000000",V);o.push({outPath:$,bytes:Buffer.from(W,"utf-8")})}}return{outputs:await cl(o,t.force,t.dryRun),pwaSnippet:p}},as=async(e,t,r)=>{let i=r?600:630,o=Math.round(Math.min(1200,i)*(1-t.padding*2/100)),s=await De({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 Ur(a),u=Math.round((1200-o)/2),d=Math.round((i-o)/2);return sl({create:{width:1200,height:i,channels:4,background:p}}).composite([{input:s,left:u,top:d}]).png().toBuffer()};var cs=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 pl=["square","rounded","circle","squircle"],ll=["contain","cover","clip"],ps=(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},zr=(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},ms=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(be.cyan(`
1125
+ ],`,cs=(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 al}from"node:fs/promises";import Br from"node:path";var ps=[".png",".jpg",".jpeg",".webp",".svg",".avif"],Ht=async e=>{if(!e)throw new Error("Source image path is required (use --path).");let t=Br.isAbsolute(e)?e:Br.resolve(process.cwd(),e),r;try{r=await al(t)}catch{throw new Error(`Source image not found: ${t}`)}if(!r.isFile())throw new Error(`Source is not a file: ${t}`);let n=Br.extname(t).toLowerCase();if(!ps.includes(n))throw new Error(`Unsupported source format '${n}'. Use one of: ${ps.join(", ")}`);return{absolutePath:t,ext:n,bytes:r.size,isVector:n===".svg"}};var zr=(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 dl=async e=>{try{return await pl(e),!0}catch{return!1}},ul=async(e,t,r)=>{let n=[];for(let i of e){if(await dl(i.outPath)&&!t&&!i.alwaysWrite){n.push({path:i.outPath,bytes:i.bytes.length,skipped:!0});continue}r||(await cl(ie.dirname(i.outPath),{recursive:!0}),await ll(i.outPath,i.bytes)),n.push({path:i.outPath,bytes:i.bytes.length})}return n},Vr=async(e,t)=>{let r=await Ht(t.source),n=await ls(r.absolutePath),i=t.ogSource?await ls((await Ht(t.ogSource)).absolutePath):n,o=[],s=[];for(let d of t.icoSizes)s.push(await De({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 is(s);if(o.push({outPath:ie.join(t.outDir,"favicon.ico"),bytes:a}),t.emitIcon){let d=await De({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 De({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 ms(i,t,!1);o.push({outPath:ie.join(t.outDir,"opengraph-image.png"),bytes:d})}if(t.emitTwitter){let d=await ms(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 Gr(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],R=[];for(let $ of x){let W=await De({sourceBuffer:n,size:$,shape:t.shape,radiusPercent:t.radius,bg:t.bg,paddingPercent:t.padding,fit:t.fit,quality:t.quality}),mt=`icon-${$}.png`;o.push({outPath:ie.join(h,mt),bytes:W}),R.push({src:`/${mt}`,size:$})}let L=os(R);if(d.publicManifestPath){let $=await ss(d.publicManifestPath,L);o.push({outPath:d.publicManifestPath,bytes:Buffer.from($,"utf-8"),alwaysWrite:!0})}else if(d.appManifestPath)p=as(L);else if(t.pwaInit){let $=ie.join(h,"manifest.webmanifest"),W=cs(ie.basename(e)||"App","#000000",L);o.push({outPath:$,bytes:Buffer.from(W,"utf-8")})}}return{outputs:await ul(o,t.force,t.dryRun),pwaSnippet:p}},ms=async(e,t,r)=>{let i=r?600:630,o=Math.round(Math.min(1200,i)*(1-t.padding*2/100)),s=await De({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 Hr(a),f=Math.round((1200-o)/2),d=Math.round((i-o)/2);return ml({create:{width:1200,height:i,channels:4,background:p}}).composite([{input:s,left:f,top:d}]).png().toBuffer()};var ds=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 fl=["square","rounded","circle","squircle"],gl=["contain","cover","clip"],us=(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},Jr=(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},gs=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(be.cyan(`
1127
1127
  \u{1F3A8} Favicon Generator
1128
- `));let n=await Xo({source:t.path}),i=await ml(r,t.out),o=ps(t.shape,pl,"square","shape"),s=ps(t.fit,ll,"contain","fit"),a=zr(t.radius,20,"radius",0,50),p=zr(t.padding,0,"padding",0,30),u=zr(t.quality,90,"quality",1,100),d=Gr(t.sizes,[16,32,48]),h=t.bg??"transparent";fl(h);let P=t.all===!0,O={source:n.source,outDir:i,force:!!t.force,dryRun:!!t.dryRun,emitIcon:!!t.icon||P,emitApple:!!t.apple||P,emitOg:!!t.og||P,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 Br(r,O);y.succeed(O.dryRun?"Favicon plan ready":"Favicon assets generated"),l("");for(let $ of V.outputs){let W=Bt.relative(r,$.path);$.skipped?l(be.yellow(` \u21B7 skipped ${W} (exists; use --force to overwrite)`)):O.dryRun?l(be.dim(` \u{1F4C4} would write ${W} (${ls($.bytes)})`)):l(be.green(` \u2713 ${W} `)+be.dim(`(${ls($.bytes)})`))}V.pwaSnippet&&(l(""),l(be.cyan("Add this to your typed manifest (src/app/manifest.ts):")),l(be.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)}})},ml=async(e,t)=>{if(t)return Bt.isAbsolute(t)?t:Bt.resolve(e,t);let r=await Ht(e);return r||(sn("Could not detect app/ or src/app/ \u2014 falling back to src/app"),Bt.join(e,"src","app"))},dl=/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/,ul=/^(?:rgb|rgba|hsl|hsla)\(\s*[\d.,%\s/]+\)$/i,fl=e=>{if(e!=="transparent"&&!dl.test(e)&&!ul.test(e)&&!cs.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().`)},ls=e=>e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(2)} MB`;import hs from"node:path";import M from"picocolors";G();G();import $l from"node:path";import{readFile as gl,writeFile as hl}from"node:fs/promises";import yl from"node:path";var pt=async e=>{let{serviceName:t,projectPath:r}=e,n=j(t),i=yl.join(r,"src","lib","config","app-apis.ts");try{let o=await gl(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 Qo({source:t.path}),i=await hl(r,t.out),o=us(t.shape,fl,"square","shape"),s=us(t.fit,gl,"contain","fit"),a=Jr(t.radius,20,"radius",0,50),p=Jr(t.padding,0,"padding",0,30),f=Jr(t.quality,90,"quality",1,100),d=zr(t.sizes,[16,32,48]),h=t.bg??"transparent";Pl(h);let x=t.all===!0,R={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:f};y.start("Generating favicon assets...");let L=await Vr(r,R);y.succeed(R.dryRun?"Favicon plan ready":"Favicon assets generated"),l("");for(let $ of L.outputs){let W=Bt.relative(r,$.path);$.skipped?l(be.yellow(` \u21B7 skipped ${W} (exists; use --force to overwrite)`)):R.dryRun?l(be.dim(` \u{1F4C4} would write ${W} (${fs($.bytes)})`)):l(be.green(` \u2713 ${W} `)+be.dim(`(${fs($.bytes)})`))}L.pwaSnippet&&(l(""),l(be.cyan("Add this to your typed manifest (src/app/manifest.ts):")),l(be.dim(L.pwaSnippet))),l("")}catch(r){y.fail("Favicon generation failed");let n=r instanceof Error?r.message:String(r);v(n),process.exit(1)}})},hl=async(e,t)=>{if(t)return Bt.isAbsolute(t)?t:Bt.resolve(e,t);let r=await Ut(e);return r||(cn("Could not detect app/ or src/app/ \u2014 falling back to src/app"),Bt.join(e,"src","app"))},yl=/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/,xl=/^(?:rgb|rgba|hsl|hsla)\(\s*[\d.,%\s/]+\)$/i,Pl=e=>{if(e!=="transparent"&&!yl.test(e)&&!xl.test(e)&&!ds.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().`)},fs=e=>e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(2)} MB`;import ws from"node:path";import G from"picocolors";B();B();import _l from"node:path";import{readFile as wl,writeFile as vl}from"node:fs/promises";import Sl from"node:path";var pt=async e=>{let{serviceName:t,projectPath:r}=e,n=j(t),i=Sl.join(r,"src","lib","config","app-apis.ts");try{let o=await wl(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=Ve(o,s),await hl(i,o)}catch(o){throw new Error(`Failed to register API endpoints: ${o}`,{cause:o})}};import{readFile as xl,writeFile as Pl}from"node:fs/promises";import wl from"node:path";x();var Jr=async(e,t,r)=>{let n=wl.join(e,"src","lib","config","app-paths.ts");if(!m(n))return;let i=await xl(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 Pl(n,i)};S();x();import zt from"node:path";var vl=e=>new RegExp(`<\\s*${e}\\b`),ds=(e,t)=>{if(vl(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=Je(o,s),await vl(i,o)}catch(o){throw new Error(`Failed to register API endpoints: ${o}`,{cause:o})}};import{readFile as El,writeFile as Cl}from"node:fs/promises";import Tl from"node:path";P();var Wr=async(e,t,r)=>{let n=Tl.join(e,"src","lib","config","app-paths.ts");if(!m(n))return;let i=await El(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 Cl(n,i)};S();P();import zt from"node:path";var bl=e=>new RegExp(`<\\s*${e}\\b`),hs=(e,t)=>{if(bl(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)},us=(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)},ys=(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
- ${e.replace(/^\n+/,"")}`;let p=n.slice(0,a),u=n.findIndex((h,P)=>P>a&&!/^export \* from '\.\//.test(h)),d=u===-1?[]:n.slice(u);return[...p,...s,...d].join(`
1137
- `)},Sl=c.PROVIDERS,El=c.ROOT_PROVIDER,Cl=c.PROVIDERS_INDEX,fs=async(e,t={fileExists:m,readFile:f})=>{let r=zt.join(e,El);if(t.fileExists(r))return r;let n=zt.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=zt.join(n,p),d=await t.readFile(u);if(!/\{children\}/.test(d))continue;let P=((d.split("{children}")[0]??"").match(/<[A-Z][A-Za-z0-9_]*\b/g)??[]).length;(!a||P>a.depth)&&(a={file:u,depth:P})}return a?.file??null},Vr=async e=>{let{projectPath:t,componentName:r,fileBaseName:n}=e,i=await fs(t);if(i){let a=await f(i),p=a;(!/from '\.\//.test(a)||!a.includes(`{ ${r} }`))&&(p=Je(p,`import { ${r} } from './${n}';`)),p=ds(p,r),p!==a&&await g(i,p)}let o=zt.join(t,Cl),s=null;if(m(o)){let a=await f(o),p=us(a,n);p!==a&&await g(o,p),s=o}return{rootProviderFile:i,barrelFile:s}};x();import{readFile as Tl,writeFile as bl}from"node:fs/promises";import Rl from"node:path";var Wr=async(e,t)=>{let r=Rl.join(e,"src","i18n","translations","en.json");if(!m(r))return;let n=await Tl(r,"utf-8"),i=JSON.parse(n);i[t]||(i[t]={title:t,description:`${t} page description`},await bl(r,`${JSON.stringify(i,null,2)}
1138
- `))};var qr=()=>[{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 dr({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 pt({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 ve({projectPath:e.projectPath,name:e.featureName,persist:e.persistStore,importPath:$l.join(e.basePath,e.featureName,"store")})}}];var Re=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 Xr=()=>[{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 pt({serviceName:e.serviceName,projectPath:e.projectPath})}}];import Il from"node:path";var Yr=()=>[{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 ve({projectPath:e.projectPath,name:e.sliceName,persist:e.persistSlice,importPath:Il.join(e.basePath,e.sliceName)})}}];import Nl from"enquirer";var{prompt:kl}=Nl,gs=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 kl(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 ys=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();Al(r),l(M.cyan(`
1136
+ ${e.replace(/^\n+/,"")}`;let p=n.slice(0,a),f=n.findIndex((h,x)=>x>a&&!/^export \* from '\.\//.test(h)),d=f===-1?[]:n.slice(f);return[...p,...s,...d].join(`
1137
+ `)},Rl=c.PROVIDERS,$l=c.ROOT_PROVIDER,Il=c.PROVIDERS_INDEX,xs=async(e,t={fileExists:m,readFile:u})=>{let r=zt.join(e,$l);if(t.fileExists(r))return r;let n=zt.join(e,Rl);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 f=zt.join(n,p),d=await t.readFile(f);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:f,depth:x})}return a?.file??null},qr=async e=>{let{projectPath:t,componentName:r,fileBaseName:n}=e,i=await xs(t);if(i){let a=await u(i),p=a;(!/from '\.\//.test(a)||!a.includes(`{ ${r} }`))&&(p=Ve(p,`import { ${r} } from './${n}';`)),p=hs(p,r),p!==a&&await g(i,p)}let o=zt.join(t,Il),s=null;if(m(o)){let a=await u(o),p=ys(a,n);p!==a&&await g(o,p),s=o}return{rootProviderFile:i,barrelFile:s}};P();import{readFile as Nl,writeFile as kl}from"node:fs/promises";import Al from"node:path";var Xr=async(e,t)=>{let r=Al.join(e,"src","i18n","translations","en.json");if(!m(r))return;let n=await Nl(r,"utf-8"),i=JSON.parse(n);i[t]||(i[t]={title:t,description:`${t} page description`},await kl(r,`${JSON.stringify(i,null,2)}
1138
+ `))};var Yr=()=>[{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 ur({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 pt({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 ve({projectPath:e.projectPath,name:e.featureName,persist:e.persistStore,importPath:_l.join(e.basePath,e.featureName,"store")})}}];var Re=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 Kr=()=>[{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 pt({serviceName:e.serviceName,projectPath:e.projectPath})}}];import Ol from"node:path";var Zr=()=>[{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 ve({projectPath:e.projectPath,name:e.sliceName,persist:e.persistSlice,importPath:Ol.join(e.basePath,e.sliceName)})}}];import Fl from"enquirer";var{prompt:jl}=Fl,Ps=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:f=>/^[a-z0-9-]+$/.test(f)?!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 jl(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 vs=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();Dl(r),l(G.cyan(`
1139
1139
  \u{1F3AF} Feature Generator
1140
- `));let i=qr();y.start("Detecting project setup...");let{detectProjectSetup:o}=await Promise.resolve().then(()=>(G(),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 gs(t,s.hasRedux,s.httpClient,r.skipStore,r.store,r.skipService,r.service);H(a.featureName,"feature name"),r.path&&re(r.path,"path");let p=r.path||hs.join("src","features"),u=xt(n,p,a.featureName);await de(n,a.featureName,p)&&(v(`Feature '${a.featureName}' already exists at ${p}!`),process.exit(1)),await Re(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)}})},Al=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=hs.join(t,e.featureName);l(M.green(`
1140
+ `));let i=Yr();y.start("Detecting project setup...");let{detectProjectSetup:o}=await Promise.resolve().then(()=>(B(),Ye)),s=await o(n);y.succeed("Project setup detected"),l(G.dim(` Redux: ${s.hasRedux?"\u2713":"\u2717"}`)),l(G.dim(` HTTP Client: ${s.httpClient}`)),l(G.dim(` i18n: ${s.hasI18n?"\u2713":"\u2717"}
1141
+ `));let a=await Ps(t,s.hasRedux,s.httpClient,r.skipStore,r.store,r.skipService,r.service);H(a.featureName,"feature name"),r.path&&re(r.path,"path");let p=r.path||ws.join("src","features"),f=xt(n,p,a.featureName);await ue(n,a.featureName,p)&&(v(`Feature '${a.featureName}' already exists at ${p}!`),process.exit(1)),await Re(i.slice(1),{projectPath:n,spinner:y,featureName:a.featureName,basePath:p,featurePath:f,createStore:a.createStore,persistStore:a.persistStore,createService:a.createService,httpClient:a.selectedHttpClient,detection:s}),Ll(a,p)}catch(n){y.fail("Feature generation failed"),v(`${n}`),process.exit(1)}})},Dl=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))},Ll=(e,t)=>{let r=ws.join(t,e.featureName);l(G.green(`
1142
1142
  \u2728 Feature '${e.featureName}' created successfully!
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 Kr from"node:path";import Le from"picocolors";G();import Ol from"enquirer";var{prompt:Fl}=Ol,xs=async e=>e?{hookName:e}:await Fl({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 Ps=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(Le.cyan(`
1143
+ `)),l(G.dim("Generated files:")),l(G.dim(` \u{1F4C2} ${r}/`)),l(G.dim(" \u251C\u2500\u2500 components/")),l(G.dim(" \u251C\u2500\u2500 hooks/")),l(G.dim(" \u251C\u2500\u2500 types/")),e.createStore&&l(G.dim(" \u251C\u2500\u2500 store/")),e.createService&&l(G.dim(" \u251C\u2500\u2500 services/")),l(G.dim(` \u2514\u2500\u2500 index.ts
1144
+ `)),l(G.cyan("Next steps:"));let n=t.replace(/^src\//,"@/");l(G.dim(` 1. Import and use the feature: import { ${e.featureName} } from '${n}/${e.featureName}'`)),e.createStore&&l(G.dim(` 2. Customize your Redux slice in: ${r}/store/`)),e.createService&&l(G.dim(` 3. Add API methods in: ${r}/services/${e.featureName}.service.ts`)),l("")};import Qr from"node:path";import Le from"picocolors";B();import Ml from"enquirer";var{prompt:Gl}=Ml,Ss=async e=>e?{hookName:e}:await Gl({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 Es=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(Le.cyan(`
1145
1145
  \u{1FA9D} Hook Generator
1146
- `));let i=await F(n),o=await xs(t);H(o.hookName,"hook name"),r.feature&&re(r.feature,"feature path");let a=`use${R(o.hookName)}`,p=jl(r,i.hasTests);y.start("Generating hook..."),await fr({name:o.hookName,projectPath:n,isClient:r.client??!0,featurePath:r.feature}),y.succeed("Hook generated");let u=r.feature?Kr.join(n,r.feature,"hooks",`${a}.ts`):Kr.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(Le.green(`
1146
+ `));let i=await F(n),o=await Ss(t);H(o.hookName,"hook name"),r.feature&&re(r.feature,"feature path");let a=`use${I(o.hookName)}`,p=Ul(r,i.hasTests);y.start("Generating hook..."),await gr({name:o.hookName,projectPath:n,isClient:r.client??!0,featurePath:r.feature}),y.succeed("Hook generated");let f=r.feature?Qr.join(n,r.feature,"hooks",`${a}.ts`):Qr.join(n,"src/hooks",`${a}.ts`),d=null;p&&(y.start("Generating test..."),d=await ae({projectPath:n,sourceFile:f,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(Le.green(`
1147
1147
  \u2728 Hook '${a}' created successfully!
1148
- `)),l(Le.dim(` \u{1F4C4} ${h}`)),d&&l(Le.dim(` \u{1F9EA} ${Kr.relative(n,d)}`)),l(""),l(Le.cyan("Usage:"));let P=r.feature?`${r.feature.replace(/^src\//,"@/")}/hooks/${a}`:`@/hooks/${a}`;l(Le.dim(` import { ${a} } from '${P}';`)),l("")}catch(n){y.fail("Hook generation failed"),v(`${n}`),process.exit(1)}})},jl=(e,t)=>e.test===!1?!1:e.test===!0?!0:t;import Jt from"picocolors";G();var ws=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(Jt.cyan(`
1148
+ `)),l(Le.dim(` \u{1F4C4} ${h}`)),d&&l(Le.dim(` \u{1F9EA} ${Qr.relative(n,d)}`)),l(""),l(Le.cyan("Usage:"));let x=r.feature?`${r.feature.replace(/^src\//,"@/")}/hooks/${a}`:`@/hooks/${a}`;l(Le.dim(` import { ${a} } from '${x}';`)),l("")}catch(n){y.fail("Hook generation failed"),v(`${n}`),process.exit(1)}})},Ul=(e,t)=>e.test===!1?!1:e.test===!0?!0:t;import Vt from"picocolors";B();var Cs=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(Vt.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(Jt.dim(` i18n: ${o?"\u2713":"\u2717"}
1151
- `)),y.start("Generating layout...");let s=await gr({segment:t,at:r.at,projectPath:n,hasI18n:o,withGroup:!!r.group});y.succeed("Layout generated"),l(Jt.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(Vt.dim(` i18n: ${o?"\u2713":"\u2717"}
1151
+ `)),y.start("Generating layout...");let s=await hr({segment:t,at:r.at,projectPath:n,hasI18n:o,withGroup:!!r.group});y.succeed("Layout generated"),l(Vt.green(`
1152
1152
  \u2728 ${s.componentName} created!
1153
- `)),l(Jt.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";x();G();import Dl from"enquirer";var{prompt:Ll}=Dl,vs=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 Ll(r);return{code:e??n.code,name:n.name,country:n.country,flag:n.flag,copyTranslations:t.copyTranslations??n.copyTranslations??!1}};var Ss=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(`
1153
+ `)),l(Vt.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();B();import Hl from"enquirer";var{prompt:Bl}=Hl,Ts=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 Bl(r);return{code:e??n.code,name:n.name,country:n.country,flag:n.flag,copyTranslations:t.copyTranslations??n.copyTranslations??!1}};var bs=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
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 vs(t,{copyTranslations:r.copyTranslations});H(o.code,"locale code");let s=xt(n,"src","i18n","translations",`${o.code}.json`);m(s)&&(v(`Locale '${o.code}' already exists!`),process.exit(1)),y.start("Adding locale..."),await hr({...o,projectPath:n}),y.succeed("Locale added"),l(oe.green(`
1157
+ `)),process.exit(1));let o=await Ts(t,{copyTranslations:r.copyTranslations});H(o.code,"locale code");let s=xt(n,"src","i18n","translations",`${o.code}.json`);m(s)&&(v(`Locale '${o.code}' already exists!`),process.exit(1)),y.start("Adding locale..."),await yr({...o,projectPath:n}),y.succeed("Locale added"),l(oe.green(`
1158
1158
  \u2728 Locale '${o.code}' (${o.name}) added successfully!
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 Cs from"node:path";import Z from"picocolors";G();import Ml from"enquirer";var{prompt:Ul}=Ml,Es=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 Ul(r):{};return{pageName:e??n.pageName,withLoading:t.loading??n.withLoading??!0,withError:t.error??n.withError??!0}};var Ts=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(`
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 $s from"node:path";import Z from"picocolors";B();import zl from"enquirer";var{prompt:Vl}=zl,Rs=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 Vl(r):{};return{pageName:e??n.pageName,withLoading:t.loading??n.withLoading??!0,withError:t.error??n.withError??!0}};var Is=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
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 Es(t,{loading:r.loading,error:r.error}),s=o.pageName;H(s,"page name"),r.dynamic&&H(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 xr({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 Jr(n,s,d),y.succeed("Route registered"),i.hasI18n&&(y.start("Adding translation namespace..."),await Wr(n,a),y.succeed("Translation namespace added"));let h=r.dynamic?Cs.join(p,s,`[${r.dynamic}]`):Cs.join(p,s);l(Z.green(`
1162
+ `));let o=await Rs(t,{loading:r.loading,error:r.error}),s=o.pageName;H(s,"page name"),r.dynamic&&H(r.dynamic,"dynamic param");let a=I(s),p=i.hasI18n?"src/app/[locale]":"src/app";await ue(n,s,p)&&(v(`Page '${s}' already exists at ${p}/${s}!`),process.exit(1)),y.start("Generating page files..."),await Pr({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 Wr(n,s,d),y.succeed("Route registered"),i.hasI18n&&(y.start("Adding translation namespace..."),await Xr(n,a),y.succeed("Translation namespace added"));let h=r.dynamic?$s.join(p,s,`[${r.dynamic}]`):$s.join(p,s);l(Z.green(`
1163
1163
  \u2728 Page '${s}' created successfully!
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 Zr from"node:path";import he from"picocolors";var bs=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(`
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 en from"node:path";import he from"picocolors";var Ns=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 wr({name:t,projectPath:r});y.succeed("Provider generated"),y.start("Registering provider in RootProvider and barrel...");let{rootProviderFile:s,barrelFile:a}=await Vr({projectPath:r,componentName:n,fileBaseName:i});y.succeed("Provider registered"),l(he.green(`
1166
+ `)),y.start("Generating provider...");let{componentName:n,fileBaseName:i,providerFile:o}=await vr({name:t,projectPath:r});y.succeed("Provider generated"),y.start("Registering provider in RootProvider and barrel...");let{rootProviderFile:s,barrelFile:a}=await qr({projectPath:r,componentName:n,fileBaseName:i});y.succeed("Provider registered"),l(he.green(`
1167
1167
  \u2728 ${n} created!
1168
- `)),l(he.dim("Generated files:")),l(he.dim(` \u{1F4C4} ${Zr.relative(r,o)}`)),s?l(he.dim(` \u270F\uFE0F ${Zr.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 ${Zr.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 Hl from"enquirer";import B from"picocolors";var{prompt:Gl}=Hl,Bl=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},zl=e=>e.filesRemoved.length===0&&e.blocksStripped.length===0&&e.scriptsRemoved.length===0&&e.packagesUninstalled.length===0&&e.manualCleanup.length===0,Rs=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=Mo(t);if(!i)throw new Error(`Unknown feature "${t}". Valid: ${Ce.map(p=>p.id).join(", ")}.`);if(l(B.cyan(`
1168
+ `)),l(he.dim("Generated files:")),l(he.dim(` \u{1F4C4} ${en.relative(r,o)}`)),s?l(he.dim(` \u270F\uFE0F ${en.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 ${en.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 z from"picocolors";var{prompt:Wl}=Jl,ql=e=>{let t=[];for(let r of e.filesRemoved)t.push(` ${z.red("-")} delete: ${r}`);for(let r of e.blocksStripped)t.push(` ${z.red("-")} strip block: ${r.description} ${z.dim(`(${r.file})`)}`);for(let r of e.scriptsRemoved)t.push(` ${z.red("-")} remove script: ${r}`);for(let r of e.packagesUninstalled)t.push(` ${z.red("-")} uninstall: ${r}`);for(let r of e.manualCleanup)t.push(` ${z.yellow("?")} manual cleanup: ${r.description} ${z.dim(`(${r.file})`)}`);return t},Xl=e=>e.filesRemoved.length===0&&e.blocksStripped.length===0&&e.scriptsRemoved.length===0&&e.packagesUninstalled.length===0&&e.manualCleanup.length===0,ks=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=Uo(t);if(!i)throw new Error(`Unknown feature "${t}". Valid: ${Ce.map(p=>p.id).join(", ")}.`);if(l(z.cyan(`
1170
1170
  \u{1F5D1} Remove ${i.name}
1171
- `)),!(await at(i,n)).installed){l(B.dim(`${i.name} is not installed \u2014 nothing to remove.`));return}y.start("Computing changes...");let s=await Ut(i,n,{dryRun:!0});if(y.succeed("Computed plan"),zl(s)){l(B.yellow(`
1171
+ `)),!(await at(i,n)).installed){l(z.dim(`${i.name} is not installed \u2014 nothing to remove.`));return}y.start("Computing changes...");let s=await Gt(i,n,{dryRun:!0});if(y.succeed("Computed plan"),Xl(s)){l(z.yellow(`
1172
1172
  \u26A0\uFE0F Manifest had no removable artifacts. Nothing to do.
1173
- `));return}l(B.bold(`
1173
+ `));return}l(z.bold(`
1174
1174
  Planned changes:
1175
- `));for(let p of Bl(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 Gl({type:"confirm",name:"confirm",message:`Apply the changes above to remove ${i.name}?`,initial:!1});if(!p){l(B.yellow(`
1175
+ `));for(let p of ql(s))l(p);if(l(""),r.dryRun){l(z.dim(`--dry-run set \u2014 exiting without writing.
1176
+ `));return}if(!r.yes){let{confirm:p}=await Wl({type:"confirm",name:"confirm",message:`Apply the changes above to remove ${i.name}?`,initial:!1});if(!p){l(z.yellow(`
1177
1177
  Aborted.
1178
- `));return}}y.start(`Removing ${i.name}...`);let a;if(i.remove?(await i.remove(n),a=s):a=await Ut(i,n),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 ql}from"node:fs";import{mkdir as Xl}from"node:fs/promises";import lt from"node:path";import Q from"picocolors";G();import{readFile as Jl,writeFile as Vl}from"node:fs/promises";import Wl from"node:path";var $s=async(e,t)=>{let r=j(t),n=Wl.join(e,"src","lib","config","app-apis.ts");try{let i=await Jl(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=oi({camelName:r,kebabName:t});i=Ve(i,o),await Vl(n,i)}catch(i){throw new Error(`Failed to register CRUD API endpoints: ${i}`,{cause:i})}};import Is from"enquirer";var Ns=async(e,t,r,n)=>{let i=e||(await Is.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 Is.prompt({type:"select",name:"httpClient",message:"Choose HTTP client:",choices:["axios","fetch"]})).httpClient:o="axios",{serviceName:i,httpClient:o}};var ks=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(`
1178
+ `));return}}y.start(`Removing ${i.name}...`);let a;if(i.remove?(await i.remove(n),a=s):a=await Gt(i,n),y.succeed(`${i.name} removed`),l(z.green(`
1179
+ \u2713 ${i.name} removed.`)),a.manualCleanup.length>0){l(z.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 Ql}from"node:fs";import{mkdir as em}from"node:fs/promises";import lt from"node:path";import Q from"picocolors";B();import{readFile as Yl,writeFile as Kl}from"node:fs/promises";import Zl from"node:path";var As=async(e,t)=>{let r=j(t),n=Zl.join(e,"src","lib","config","app-apis.ts");try{let i=await Yl(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=ai({camelName:r,kebabName:t});i=Je(i,o),await Kl(n,i)}catch(i){throw new Error(`Failed to register CRUD API endpoints: ${i}`,{cause:i})}};import _s from"enquirer";var Os=async(e,t,r,n)=>{let i=e||(await _s.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 _s.prompt({type:"select",name:"httpClient",message:"Choose HTTP client:",choices:["axios","fetch"]})).httpClient:o="axios",{serviceName:i,httpClient:o}};var Fs=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
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
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 Ns(t,r.axios,r.fetch,i.httpClient);H(s.serviceName,"service name"),r.path&&re(r.path,"path");let{basePath:a,servicePath:p}=Yl(n,s.serviceName,r.path);ql(p)||await Xl(p,{recursive:!0}),Pt(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 mr({name:s.serviceName,outputPath:p,httpClient:s.httpClient}),y.succeed("CRUD service files generated"),y.start("Registering CRUD API endpoints..."),await $s(n,s.serviceName),y.succeed("CRUD API endpoints registered")):await Re(Xr(),{projectPath:n,spinner:y,serviceName:s.serviceName,servicePath:p,httpClient:s.httpClient}),Kl(s,a,!!r.crud)}catch(n){y.fail("Service generation failed"),v(`${n}`),process.exit(1)}})},Yl=(e,t,r)=>{let n;if(r){let i=r.replace(/^src\//,"");if(i.startsWith("features/")){let o=i.split("/")[1];n=lt.join("src","features",o,"services")}else n=lt.join("src",i)}else n=lt.join("src","features",t,"services");return{basePath:n,servicePath:lt.join(e,n)}},Kl=(e,t,r=!1)=>{let n=lt.join(t,`${e.serviceName}.service.ts`);l(Q.green(`
1185
+ `));let s=await Os(t,r.axios,r.fetch,i.httpClient);H(s.serviceName,"service name"),r.path&&re(r.path,"path");let{basePath:a,servicePath:p}=tm(n,s.serviceName,r.path);Ql(p)||await em(p,{recursive:!0}),Pt(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 dr({name:s.serviceName,outputPath:p,httpClient:s.httpClient}),y.succeed("CRUD service files generated"),y.start("Registering CRUD API endpoints..."),await As(n,s.serviceName),y.succeed("CRUD API endpoints registered")):await Re(Kr(),{projectPath:n,spinner:y,serviceName:s.serviceName,servicePath:p,httpClient:s.httpClient}),rm(s,a,!!r.crud)}catch(n){y.fail("Service generation failed"),v(`${n}`),process.exit(1)}})},tm=(e,t,r)=>{let n;if(r){let i=r.replace(/^src\//,"");if(i.startsWith("features/")){let o=i.split("/")[1];n=lt.join("src","features",o,"services")}else n=lt.join("src",i)}else n=lt.join("src","features",t,"services");return{basePath:n,servicePath:lt.join(e,n)}},rm=(e,t,r=!1)=>{let n=lt.join(t,`${e.serviceName}.service.ts`);l(Q.green(`
1186
1186
  \u2728 ${r?"CRUD ":""}Service '${e.serviceName}' created successfully!
1187
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 Zl from"enquirer";import Qr from"picocolors";var{prompt:Ql}=Zl,en=[{key:"http-client",label:"HTTP Client (Axios/Fetch)",flag:"httpClient",handler:kt},{key:"dark-theme",label:"Dark Theme",flag:"darkTheme",handler:$t},{key:"redux",label:"Redux Toolkit",flag:"redux",handler:Ft},{key:"ws",label:"WebSocket Client (requires Redux)",flag:"ws",handler:Mt},{key:"i18n",label:"Internationalization (next-intl)",flag:"i18n",handler:_t},{key:"tests",label:"Testing (Vitest + RTL)",flag:"tests",handler:Dt},{key:"react-compiler",label:"React Compiler",flag:"reactCompiler",handler:Ot},{key:"bundle-analyzer",label:"Bundle Analyzer",flag:"bundleAnalyzer",handler:Ct},{key:"security-headers",label:"Security Headers",flag:"securityHeaders",handler:jt},{key:"validate-scripts",label:"Validation Scripts",flag:"validateScripts",handler:Lt},{key:"commitizen",label:"Commitizen",flag:"commitizen",handler:Tt}],em=async(e,t={})=>{let r=t.promptFn??Ql,n=t.cwd??(()=>process.cwd());l(Qr.cyan(`
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 nm from"enquirer";import tn from"picocolors";var{prompt:im}=nm,rn=[{key:"http-client",label:"HTTP Client (Axios/Fetch)",flag:"httpClient",handler:kt},{key:"dark-theme",label:"Dark Theme",flag:"darkTheme",handler:$t},{key:"redux",label:"Redux Toolkit",flag:"redux",handler:Ft},{key:"ws",label:"WebSocket Client (requires Redux)",flag:"ws",handler:Mt},{key:"i18n",label:"Internationalization (next-intl)",flag:"i18n",handler:_t},{key:"tests",label:"Testing (Vitest + RTL)",flag:"tests",handler:Dt},{key:"react-compiler",label:"React Compiler",flag:"reactCompiler",handler:Ot},{key:"bundle-analyzer",label:"Bundle Analyzer",flag:"bundleAnalyzer",handler:Ct},{key:"security-headers",label:"Security Headers",flag:"securityHeaders",handler:jt},{key:"validate-scripts",label:"Validation Scripts",flag:"validateScripts",handler:Lt},{key:"commitizen",label:"Commitizen",flag:"commitizen",handler:Tt}],om=async(e,t={})=>{let r=t.promptFn??im,n=t.cwd??(()=>process.cwd());l(tn.cyan(`
1189
1189
  \u{1F527} Setup Wizard
1190
- `));let i=en.filter(p=>!!e[p.flag]);if(i.length>0){for(let p of i)await p.handler(n());return i.length===1?i[0].key:"multiple"}let s=(await r([{type:"select",name:"feature",message:"What would you like to setup?",choices:[...en.map(p=>({name:p.key,message:p.label})),{name:"cancel",message:"Cancel"}]}])).feature;if(s==="cancel")return l(Qr.yellow("Setup cancelled.")),null;let a=en.find(p=>p.key===s);return a?(await a.handler(n()),a.key):(l(Qr.yellow(`
1191
- \u26A0\uFE0F ${s} setup is not implemented yet.`)),null)},As=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{await em(t)}catch(r){y.fail("Setup failed"),v(`${r}`),process.exit(1)}})};import{existsSync as nm}from"node:fs";import{mkdir as im}from"node:fs/promises";import ye from"node:path";import z from"picocolors";G();import tm from"enquirer";var{prompt:rm}=tm,_s=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 rm(r):{};return{sliceName:e||n.sliceName,persistSlice:t===void 0?n.persistSlice||!1:t}};var Os=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(`
1190
+ `));let i=rn.filter(p=>!!e[p.flag]);if(i.length>0){for(let p of i)await p.handler(n());return i.length===1?i[0].key:"multiple"}let s=(await r([{type:"select",name:"feature",message:"What would you like to setup?",choices:[...rn.map(p=>({name:p.key,message:p.label})),{name:"cancel",message:"Cancel"}]}])).feature;if(s==="cancel")return l(tn.yellow("Setup cancelled.")),null;let a=rn.find(p=>p.key===s);return a?(await a.handler(n()),a.key):(l(tn.yellow(`
1191
+ \u26A0\uFE0F ${s} setup is not implemented yet.`)),null)},js=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{await om(t)}catch(r){y.fail("Setup failed"),v(`${r}`),process.exit(1)}})};import{existsSync as cm}from"node:fs";import{mkdir as pm}from"node:fs/promises";import ye from"node:path";import V from"picocolors";B();import sm from"enquirer";var{prompt:am}=sm,Ds=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 am(r):{};return{sliceName:e||n.sliceName,persistSlice:t===void 0?n.persistSlice||!1:t}};var Ls=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(V.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(z.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(V.dim(`
1194
1194
  Run: npm install @reduxjs/toolkit react-redux
1195
- `)),process.exit(1)),l(z.dim(` Redux: \u2713
1196
- `));let o=await _s(t,r.persist);H(o.sliceName,"slice name"),r.path&&re(r.path,"path");let{basePath:s,slicePath:a}=om(n,o.sliceName,r.path),p=ye.join(n,s);nm(p)||await im(p,{recursive:!0}),await de(n,o.sliceName,s)&&(v(`Slice '${o.sliceName}' already exists at ${s}!`),process.exit(1)),await Re(Yr(),{projectPath:n,spinner:y,sliceName:o.sliceName,basePath:s,slicePath:a,persistSlice:o.persistSlice});let d=null;if(sm(r,i.hasTests)){let P=ye.join(a,`${o.sliceName}.slice.ts`);y.start("Generating test..."),d=await ae({projectPath:n,sourceFile:P,kind:"slice",symbolName:j(o.sliceName)}),y.succeed("Test generated")}am(o,s,d,n)}catch(n){y.fail("Slice generation failed"),v(`${n}`),process.exit(1)}})},om=(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)}},sm=(e,t)=>e.test===!1?!1:e.test===!0?!0:t,am=(e,t,r,n)=>{let i=ye.join(t,e.sliceName);l(z.green(`
1195
+ `)),process.exit(1)),l(V.dim(` Redux: \u2713
1196
+ `));let o=await Ds(t,r.persist);H(o.sliceName,"slice name"),r.path&&re(r.path,"path");let{basePath:s,slicePath:a}=lm(n,o.sliceName,r.path),p=ye.join(n,s);cm(p)||await pm(p,{recursive:!0}),await ue(n,o.sliceName,s)&&(v(`Slice '${o.sliceName}' already exists at ${s}!`),process.exit(1)),await Re(Zr(),{projectPath:n,spinner:y,sliceName:o.sliceName,basePath:s,slicePath:a,persistSlice:o.persistSlice});let d=null;if(mm(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")}dm(o,s,d,n)}catch(n){y.fail("Slice generation failed"),v(`${n}`),process.exit(1)}})},lm=(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)}},mm=(e,t)=>e.test===!1?!1:e.test===!0?!0:t,dm=(e,t,r,n)=>{let i=ye.join(t,e.sliceName);l(V.green(`
1197
1197
  \u2728 Slice '${e.sliceName}' created successfully!
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 tn from"picocolors";x();G();var Fs=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(tn.cyan(`
1198
+ `)),l(V.dim("Generated files:")),l(V.dim(` \u{1F4C2} ${i}/`)),l(V.dim(` \u251C\u2500\u2500 ${e.sliceName}.slice.ts`)),l(V.dim(` \u251C\u2500\u2500 ${e.sliceName}.selectors.ts`)),e.persistSlice&&l(V.dim(" \u251C\u2500\u2500 persist.ts")),l(V.dim(` \u251C\u2500\u2500 ${e.sliceName}.types.ts`)),l(V.dim(` \u2514\u2500\u2500 index.ts
1199
+ `)),r&&l(V.dim(` \u{1F9EA} ${ye.relative(n,r)}
1200
+ `)),l(V.cyan("Next steps:"));let o=t.replace(/^src\//,"@/");l(V.dim(` 1. Import actions: import { setLoading, setError } from '${o}/${e.sliceName}'`)),l(V.dim(" 2. Use in component: dispatch(setLoading(true))")),l("")};import ee from"node:path";import nn from"picocolors";P();B();var Ms=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(nn.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=cm(r.kind)??pm(i,s);a||(v(`Could not infer test kind for ${ee.basename(i)}. Pass --kind component|hook|slice.`),process.exit(1));let p=lm(i,a),u=mm(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(tn.green(`
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 u(i),a=um(r.kind)??fm(i,s);a||(v(`Could not infer test kind for ${ee.basename(i)}. Pass --kind component|hook|slice.`),process.exit(1));let p=gm(i,a),f=hm(i,a);m(f)&&!r.force&&(v(`Test file already exists: ${ee.relative(n,f)}. 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(nn.green(`
1204
1204
  \u2728 Test '${ee.basename(d)}' created.
1205
- `)),l(tn.dim(` \u{1F9EA} ${ee.relative(n,d)}`)),l("")}catch(n){y.fail("Test generation failed"),v(`${n}`),process.exit(1)}})},cm=e=>{if(!e)return null;if(e==="component"||e==="hook"||e==="slice")return e;throw new Error(`Invalid --kind: ${e}. Use component | hook | slice.`)},pm=(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},lm=(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)},mm=(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 js=e=>{Yn(e),As(e),ys(e),Os(e),ks(e),Ts(e),ws(e),Ii(e),Ss(e),Ps(e),bs(e),qo(e),ms(e),Uo(e),Rs(e),Fs(e)};var um=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 um.apply(process,arguments)};async function fm(){on({logger:t=>dt(t)});let e=new dm;e.name("next-maker").description("Teispace Next.js Project Generator").version(rn.version),js(e),e.parse()}fm().catch(e=>{let t=e&&typeof e=="object"&&"message"in e?e.message:String(e);dt(`Unexpected error: ${t}`)});
1205
+ `)),l(nn.dim(` \u{1F9EA} ${ee.relative(n,d)}`)),l("")}catch(n){y.fail("Test generation failed"),v(`${n}`),process.exit(1)}})},um=e=>{if(!e)return null;if(e==="component"||e==="hook"||e==="slice")return e;throw new Error(`Invalid --kind: ${e}. Use component | hook | slice.`)},fm=(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},gm=(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${I(r.replace(/^use-?/,""))}`:I(r)},hm=(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 Gs=e=>{Zn(e),js(e),vs(e),Ls(e),Fs(e),Is(e),Cs(e),ki(e),bs(e),Es(e),Ns(e),Zo(e),gs(e),Ho(e),ks(e),Ms(e)};var xm=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 xm.apply(process,arguments)};async function Pm(){an({logger:t=>dt(t)});let e=new ym;e.name("next-maker").description("Teispace Next.js Project Generator").version(on.version),Gs(e),e.parse()}Pm().catch(e=>{let t=e&&typeof e=="object"&&"message"in e?e.message:String(e);dt(`Unexpected error: ${t}`)});