@teispace/next-maker 3.0.5 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,30 +1,30 @@
1
1
  #!/usr/bin/env node
2
- var Us=Object.defineProperty;var $e=(e,t)=>()=>(e&&(t=e(e=0)),t);var Jt=(e,t)=>{for(var r in t)Us(e,r,{get:t[r],enumerable:!0})};import{existsSync as Wt}from"node:fs";import xe from"node:fs/promises";import pn from"node:path";var f,g,N,C,w,D,m,P=$e(()=>{"use strict";f=async e=>xe.readFile(e,"utf-8"),g=async(e,t)=>{await xe.mkdir(pn.dirname(e),{recursive:!0}),await xe.writeFile(e,t,"utf-8")},N=async(e,t)=>{await xe.mkdir(pn.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 hn={};Jt(hn,{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 Cn={};Jt(Cn,{cleanupHttpTypes:()=>Ne,injectBundleSentinel:()=>En,installBundleSentinelMount:()=>rr,isFileUsed:()=>Ea,isStringUsed:()=>Ca,migrateClientUsages:()=>er,removeBundleSentinelMount:()=>Be,removeHttpExports:()=>nr,resolveBundleSentinelLayoutPath:()=>tr,rewriteSentinelImports:()=>ke,rewriteServerEntryImports:()=>Ae,stripBundleSentinel:()=>He,updateConfigIndex:()=>Qt,updateHttpIndex:()=>Yt,updateTypesIndex:()=>Zt,updateUtilsIndex:()=>Kt});import{execFile as Pa}from"node:child_process";import A from"node:path";import{promisify as wa}from"node:util";async function Xt(e,t,r){try{let{stdout:n}=await va("grep",[...r,"--include=*.ts","--include=*.tsx",e,t]);return n}catch(n){if(n.code===1)return"";throw n}}var va,Yt,Kt,Zt,Qt,Ne,er,tr,Sa,wn,vn,En,He,rr,Be,nr,Ea,Ca,ke,Ae,Sn,ze=$e(()=>{"use strict";S();P();va=wa(Pa);Yt=async(e,t)=>{let r=A.join(e,c.HTTP_UTILS,"index.ts");if(m(r)){let n=await f(r);n=n.replace(/export .* from '\.\/axios-client';?\n?/g,""),n=n.replace(/export .* from '\.\/fetch-client';?\n?/g,""),t.includes("fetch")&&!n.includes("fetch-client")&&(n+=`export * from './fetch-client';
3
- `),t.includes("axios")&&!n.includes("axios-client")&&(n+=`export * from './axios-client';
4
- `),await g(r,n)}},Kt=async e=>{let t=A.join(e,c.UTILS_INDEX);if(m(t)){let r=await f(t);r.includes("./http")||(r+=`export * from './http';
5
- `,await g(t,r))}},Zt=async e=>{let t=A.join(e,c.TYPES_INDEX);if(m(t)){let r=await f(t);r.includes("./common")||(r+=`export * from './common';
2
+ var Ra=Object.defineProperty;var Me=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(i){throw r=[i],i}};var Cr=(e,t)=>{for(var r in t)Ra(e,r,{get:t[r],enumerable:!0})};import{existsSync as Rr}from"node:fs";import be from"node:fs/promises";import Hi from"node:path";var g,h,b,C,v,F,l,w=Me(()=>{"use strict";g=async e=>be.readFile(e,"utf-8"),h=async(e,t)=>{await be.mkdir(Hi.dirname(e),{recursive:!0}),await be.writeFile(e,t,"utf-8")},b=async(e,t)=>{await be.mkdir(Hi.dirname(t),{recursive:!0}),await be.copyFile(e,t)},C=async e=>{Rr(e)&&await be.unlink(e)},v=async e=>{Rr(e)&&await be.rm(e,{recursive:!0,force:!0})},F=async(e,t)=>{let r=await g(e),i=JSON.parse(r),n=t(i);await h(e,JSON.stringify(n,null,2))},l=e=>Rr(e)});var Wi={};Cr(Wi,{PROJECT_PATHS:()=>a});var a,P=Me(()=>{"use strict";a={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={};Cr(tn,{cleanupHttpTypes:()=>Ge,injectBundleSentinel:()=>en,installBundleSentinelMount:()=>Qe,isFileUsed:()=>ac,isStringUsed:()=>cc,migrateClientUsages:()=>Or,removeBundleSentinelMount:()=>et,removeHttpExports:()=>Dr,resolveBundleSentinelLayoutPath:()=>jr,rewriteSentinelImports:()=>xe,rewriteServerEntryImports:()=>we,stripBundleSentinel:()=>Nt,stripSaveAuthTokens:()=>_r,updateConfigIndex:()=>Fr,updateHttpIndex:()=>kr,updateTypesIndex:()=>Ar,updateUtilsIndex:()=>Nr});import{execFile as ic}from"node:child_process";import j from"node:path";import{promisify as nc}from"node:util";async function $r(e,t,r){try{let{stdout:i}=await oc("grep",[...r,"--include=*.ts","--include=*.tsx",e,t]);return i}catch(i){if(i.code===1)return"";throw i}}var oc,kr,Nr,Ar,Fr,Ge,_r,Or,jr,sc,Ki,Zi,en,Nt,Qe,et,Dr,ac,cc,xe,we,Qi,Ue=Me(()=>{"use strict";P();w();oc=nc(ic);kr=async(e,t)=>{let r=j.join(e,a.HTTP_UTILS,"index.ts");if(l(r)){let i=await g(r);i=i.replace(/export .* from '\.\/axios-client';?\n?/g,""),i=i.replace(/export .* from '\.\/fetch-client';?\n?/g,""),t.includes("fetch")&&!i.includes("fetch-client")&&(i+=`export * from './fetch-client';
3
+ `),t.includes("axios")&&!i.includes("axios-client")&&(i+=`export * from './axios-client';
4
+ `),await h(r,i)}},Nr=async e=>{let t=j.join(e,a.UTILS_INDEX);if(l(t)){let r=await g(t);r.includes("./http")||(r+=`export * from './http';
5
+ `,await h(t,r))}},Ar=async e=>{let t=j.join(e,a.TYPES_INDEX);if(l(t)){let r=await g(t);r.includes("./common")||(r+=`export * from './common';
6
6
  `),r.includes("./utility")||(r+=`export * from './utility';
7
- `),await g(t,r)}},Qt=async e=>{let t=A.join(e,c.CONFIG_INDEX);if(m(t)){let r=await f(t);r.includes("./app-apis")||(r+=`export * from './app-apis';
8
- `,await g(t,r))}},Ne=async(e,t)=>{let r=A.join(e,c.HTTP_TYPES);if(m(r)){let n=await f(r);t.includes("axios")||(n=n.replace(/declare module 'axios'\s*\{\s*export interface AxiosRequestConfig\s*\{[\s\S]*?\}\s*\}/g,""),n=`${n.replace(/\n\s*\n/g,`
7
+ `),await h(t,r)}},Fr=async e=>{let t=j.join(e,a.CONFIG_INDEX);if(l(t)){let r=await g(t);r.includes("./app-apis")||(r+=`export * from './app-apis';
8
+ `,await h(t,r))}},Ge=async(e,t)=>{let r=j.join(e,a.HTTP_TYPES);if(l(r)){let i=await g(r);t.includes("axios")||(i=i.replace(/declare module 'axios'\s*\{\s*export interface AxiosRequestConfig\s*\{[\s\S]*?\}\s*\}/g,""),i=`${i.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=A.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),x=!1,I=new RegExp(`(import\\s*\\{[^}]*?)\\b${n}\\b([^}]*?\\}\\s*from\\s*['"][^'"]*?/http['"])`,"g");I.test(h)&&(h=h.replace(I,`$1${i}$2`),x=!0);let G=new RegExp(`import\\s+${n}\\s+from\\s+['"]([^'"]*?)/${o}['"]`,"g");G.test(h)&&(h=h.replace(G,`import ${i} from '$1/${s}'`),x=!0);let R=new RegExp(`\\b${n}\\b(?=\\.)`,"g");R.test(h)&&(h=h.replace(R,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)}},tr=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},Sa="// Regression sentinel \u2014 see file comment for what this guards.",wn="import { HttpClientBundleSentinel } from '@/lib/utils/http/__bundle-sentinel__/client-bundle-sentinel';",vn="<HttpClientBundleSentinel />",En=e=>{if(e.includes(vn))return e;let t=e;if(!t.includes(wn)){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}${Sa}
13
- ${wn}
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}${vn}
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},rr=async e=>{let t=tr(e);if(!t)return;let r=await f(t),n=En(r);n!==r&&await g(t,n)},Be=async e=>{let t=tr(e);if(!t)return;let r=await f(t),n=He(r);n!==r&&await g(t,n)},nr=async e=>{let t=A.join(e,c.UTILS_INDEX);if(m(t)){let n=await f(t);n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http['"];?.*$/gm,""),await g(t,n)}let r=A.join(e,c.TYPES_INDEX);if(m(r)){let n=await f(r),i=A.join(e,c.COMMON_TYPES_DIR);if(!m(i))n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/common['"];?.*$/gm,"");else{let o=A.join(i,"index.ts");if(m(o)){let s=await f(o);s=s.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http\.types['"];?.*$/gm,""),await g(o,s)}}m(A.join(e,c.UTILITY_TYPES_DIR))||(n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/utility['"];?.*$/gm,"")),await g(r,n)}},Ea=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(u=>{let[d]=u.split(":"),h=A.resolve(e,d);return!r.some(x=>!!(h===x||h.startsWith(x+A.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for ${t}:`,s),!0}},Ca=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(":"),u=A.resolve(e,p);return!r.some(d=>!!(u===d||u.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 f(r),i=["toSearchParams"];if(t.includes("axios")&&i.unshift("axiosClient","createAxiosClient"),t.includes("fetch")){let a=i.indexOf("toSearchParams");i.splice(a,0,"createFetchClient","fetchClient")}i.sort();let o=`import {
19
- ${i.join(`,
11
+ `,await h(r,i))}},_r=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},Or=async(e,t,r)=>{if(t===r)return;let i=t==="fetch"?"fetchClient":"axiosClient",n=r==="fetch"?"fetchClient":"axiosClient",o=t==="fetch"?"fetch-client":"axios-client",s=r==="fetch"?"fetch-client":"axios-client",c=j.join(e,"src");try{let p=await $r(i,c,["-r","-l"]);if(!p.trim())return;let u=p.trim().split(`
12
+ `).filter(d=>d);for(let d of u){if(!l(d))continue;let f=await g(d),y=!1,I=new RegExp(`(import\\s*\\{[^}]*?)\\b${i}\\b([^}]*?\\}\\s*from\\s*['"][^'"]*?/http['"])`,"g");I.test(f)&&(f=f.replace(I,`$1${n}$2`),y=!0);let G=new RegExp(`import\\s+${i}\\s+from\\s+['"]([^'"]*?)/${o}['"]`,"g");G.test(f)&&(f=f.replace(G,`import ${n} from '$1/${s}'`),y=!0);let k=new RegExp(`\\b${i}\\b(?=\\.)`,"g");k.test(f)&&(f=f.replace(k,n),y=!0);let K=new RegExp(`\\b${i}\\b(?![.\\w])`,"g");K.test(f)&&(f=f.replace(K,n),y=!0),y&&await h(d,f)}}catch(p){console.warn("Warning: Could not scan for HTTP client usages:",p)}},jr=e=>{let t=j.join(e,a.LOCALE_LAYOUT);if(l(t))return t;let r=j.join(e,a.ROOT_LAYOUT);return l(r)?r:null},sc="// Regression sentinel \u2014 see file comment for what this guards.",Ki="import { HttpClientBundleSentinel } from '@/lib/utils/http/__bundle-sentinel__/client-bundle-sentinel';",Zi="<HttpClientBundleSentinel />",en=e=>{if(e.includes(Zi))return e;let t=e;if(!t.includes(Ki)){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 c=t.slice(0,(s.index??0)+s[0].length),p=t.slice((s.index??0)+s[0].length);t=`${c}${sc}
13
+ ${Ki}
14
+ ${p}`}let r=/(<RootProvider\b[^>]*>)\n([ \t]*)/,i=t.match(r);if(!i)throw new Error("injectBundleSentinel: could not locate `<RootProvider \u2026>` opening tag \u2014 layout shape unexpected.");let n=i[2];return t=t.replace(r,`$1
15
+ ${n}${Zi}
16
+ ${n}`),t},Nt=e=>{let t=e,r=/@\/lib\/utils\/http\/__bundle-sentinel__\/client-bundle-sentinel/,i=new RegExp(`(?:^[ \\t]*//[^\\n]*\\n)?^[ \\t]*import[^\\n]*${r.source}[^\\n]*\\n`,"m");return t=t.replace(i,""),t=t.replace(/[ \t]*<HttpClientBundleSentinel\s*\/>\s*\n/,""),t},Qe=async e=>{let t=jr(e);if(!t)return;let r=await g(t),i=en(r);i!==r&&await h(t,i)},et=async e=>{let t=jr(e);if(!t)return;let r=await g(t),i=Nt(r);i!==r&&await h(t,i)},Dr=async e=>{let t=j.join(e,a.UTILS_INDEX);if(l(t)){let i=await g(t);i=i.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http['"];?.*$/gm,""),await h(t,i)}let r=j.join(e,a.TYPES_INDEX);if(l(r)){let i=await g(r),n=j.join(e,a.COMMON_TYPES_DIR);if(!l(n))i=i.replace(/^\s*export\s+\*\s+from\s+['"]\.\/common['"];?.*$/gm,"");else{let o=j.join(n,"index.ts");if(l(o)){let s=await g(o);s=s.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http\.types['"];?.*$/gm,""),await h(o,s)}}l(j.join(e,a.UTILITY_TYPES_DIR))||(i=i.replace(/^\s*export\s+\*\s+from\s+['"]\.\/utility['"];?.*$/gm,"")),await h(r,i)}},ac=async(e,t,r=[])=>{let i=j.join(e,"src"),o=`from ['"].*${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}.*['"]`;try{let s=await $r(o,i,["-r","-E"]);return s.trim()?s.trim().split(`
17
+ `).filter(u=>{let[d]=u.split(":"),f=j.resolve(e,d);return!r.some(y=>!!(f===y||f.startsWith(y+j.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for ${t}:`,s),!0}},cc=async(e,t,r=[])=>{let i=j.join(e,"src");try{let n=await $r(t,i,["-r","-F"]);return n.trim()?n.trim().split(`
18
+ `).filter(c=>{let[p]=c.split(":"),u=j.resolve(e,p);return!r.some(d=>!!(u===d||u.startsWith(d+j.sep)))}).length>0:!1}catch(n){return console.warn(`Warning: Failed to check usage for string ${t}:`,n),!0}},xe=async(e,t)=>{let r=j.join(e,a.HTTP_BUNDLE_SENTINEL_FILE);if(!l(r))return;let i=await g(r),n=["toSearchParams"];if(t.includes("axios")&&n.unshift("axiosClient","createAxiosClient"),t.includes("fetch")){let c=n.indexOf("toSearchParams");n.splice(c,0,"createFetchClient","fetchClient")}n.sort();let o=`import {
19
+ ${n.join(`,
20
20
  `)},
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
- `);n=n.replace(/const __sentinel__ = \{[\s\S]*?\};/,`const __sentinel__ = {
21
+ } from '@/lib/utils/http';`;i=i.replace(/import\s*\{[^}]*\}\s*from\s*['"]@\/lib\/utils\/http['"];/,o);let s=n.map(c=>` ${c},`).join(`
22
+ `);i=i.replace(/const __sentinel__ = \{[\s\S]*?\};/,`const __sentinel__ = {
23
23
  ${s}
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 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=Sn(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=Sn(n,"createFetchClient")),n=n.replace(/\n{3,}/g,`
24
+ };`),await h(r,i)},we=async(e,t)=>{let r=j.join(e,a.HTTP_SERVER_FILE);if(!l(r)||t.length===0)return;let i=await g(r),n=o=>{i=i.replace(o,"")};t.includes("axios")||(n(/^import\s*\{\s*createAxiosClient\s*\}\s*from\s*['"]\.\/axios-client['"];\n?/m),n(/export const axiosClient = createAxiosClient\(\{[\s\S]*?\}\);\n?\n?/),i=Qi(i,"createAxiosClient")),t.includes("fetch")||(n(/^import\s*\{\s*createFetchClient\s*\}\s*from\s*['"]\.\/fetch-client['"];\n?/m),n(/export const fetchClient = createFetchClient\(\{[\s\S]*?\}\);\n?\n?/),i=Qi(i,"createFetchClient")),i=i.replace(/\n{3,}/g,`
25
25
 
26
- `),await g(r,n)},Sn=(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 fc}from"node:fs";import{access as gc}from"node:fs/promises";import ei from"node:path";var ue,Pt,ti=$e(()=>{"use strict";ue=async(e,t,r)=>{try{return await gc(ei.join(e,r,t)),!0}catch{return!1}},Pt=(e,t,r)=>fc(ei.join(e,t,r))});import{access as wt,readFile as hc}from"node:fs/promises";import Xe from"node:path";var F,ri=$e(()=>{"use strict";F=async e=>{try{let t=Xe.join(e,"package.json"),r=await hc(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 x=!!i.vitest;if(!x)try{await wt(Xe.join(e,"vitest.config.ts")),x=!0}catch{}let I="none";if(i["socket.io-client"])try{await wt(Xe.join(e,"src","lib","utils","ws")),I="present"}catch{}return{hasRedux:o,httpClient:h,hasI18n:s,hasTests:x,ws:I}}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";ti();ri()});import{Command as hm}from"commander";var nn={name:"@teispace/next-maker",version:"3.0.5",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 on(e){return Me.add(e),()=>Me.delete(e)}function sn(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 Bs={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=Bs[t]??(n=>n);console.log(r(e))}function dt(e){le(`\u2716 ${e}`,"red")}var v=dt;function an(e){le(`\u26A0 ${e}`,"yellow")}function l(e){le(e)}function cn(){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 zs from"ora";function b(e="",t){let r=zs({text:e,...t});return r.start(),r}var Vs=e=>e.charAt(0).toUpperCase()+e.slice(1),j=e=>e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase()),$=e=>Vs(j(e));import Js from"ora";var y=Js();P();import{execFile as Ws}from"node:child_process";import{promisify as qs}from"node:util";var Xs=qs(Ws),se=(e,t)=>Xs("git",e,t?{cwd:t}:void 0);function Ys(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 ln=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&&(Ys(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 Ks}from"node:child_process";import{promisify as Zs}from"node:util";var Qs=Zs(Ks),Ge=(e,t,r)=>Qs(e,t,{cwd:r}),mn=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}`)}},ea=()=>{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":ea()},ta=async(e,t,r)=>{if(r.length!==0)try{await Ge(t,[...dn(t),...r],e)}catch(n){throw new Error(`Failed to install packages with ${t}: ${n}`,{cause:n})}},dn=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 ta(e,r,[t])},ra=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,[...dn(t),ra(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,[...na(t),...r],e)}catch(n){throw new Error(`Failed to uninstall packages with ${t}: ${n}`,{cause:n})}},na=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 ia from"enquirer";var oa=/^[a-z0-9-_]+$/,sa=/^\d+\.\d+\.\d+$/,un=e=>oa.test(e),aa=e=>sa.test(e),fn=(e,t={})=>{let r=t.projectName??e??"my-app";if(!un(r))throw new Error(`Invalid project name "${r}". Use lowercase letters, digits, hyphens, and underscores only.`);let n=t.version??"0.1.0";if(!aa(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:ca}=ia,gn=async e=>{if(e!==void 0&&!un(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 ca([{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 pa from"node:path";var me=async(e,t)=>{let r=la(t);await g(pa.join(e,"test/test-utils.tsx"),r)},la=({redux:e,i18n:t})=>e&&t?ma:e?da:t?ua:fa,ma=`import { type RenderOptions, render } from '@testing-library/react';
26
+ `),await h(r,i)},Qi=(e,t)=>{let r=/^export\s*\{([^}]*)\};\n?/m;return e.replace(r,(i,n)=>{let o=n.split(",").map(s=>s.trim()).filter(s=>s.length>0&&s!==t);return o.length===0?"":`export { ${o.join(", ")} };
27
+ `})}});import{existsSync as Zc}from"node:fs";import{access as Qc}from"node:fs/promises";import $n from"node:path";var ve,Ht,kn=Me(()=>{"use strict";ve=async(e,t,r)=>{try{return await Qc($n.join(e,r,t)),!0}catch{return!1}},Ht=(e,t,r)=>Zc($n.join(e,t,r))});import{access as Gt,readFile as ep}from"node:fs/promises";import ot from"node:path";var M,Nn=Me(()=>{"use strict";M=async e=>{try{let t=ot.join(e,"package.json"),r=await ep(t,"utf-8"),i=JSON.parse(r),n={...i.dependencies,...i.devDependencies},o=!!(n["@reduxjs/toolkit"]&&n["react-redux"]),s=!!n["next-intl"],c=!!n.axios,p=!1,u=ot.join(e,"src","lib","utils","http","axios-client");try{await Gt(u)}catch{c=!1}let d=ot.join(e,"src","lib","utils","http","fetch-client");try{await Gt(d),p=!0}catch{p=!1}let f;c&&p?f="both":c?f="axios":p?f="fetch":f="none";let y=!!n.vitest;if(!y)try{await Gt(ot.join(e,"vitest.config.ts")),y=!0}catch{}let I="none";if(n["socket.io-client"])try{await Gt(ot.join(e,"src","lib","utils","ws")),I="present"}catch{}return{hasRedux:o,httpClient:f,hasI18n:s,hasTests:y,ws:I}}catch(t){throw new Error(`Failed to detect project setup: ${t}`,{cause:t})}}});var st={};Cr(st,{detectProjectSetup:()=>M,directoryExists:()=>ve,fileExistsAt:()=>Ht});var W=Me(()=>{"use strict";kn();Nn()});import{Command as Cd}from"commander";var Oi={name:"@teispace/next-maker",version:"4.0.0",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.8.0",enquirer:"^2.4.1",ora:"^9.4.1",picocolors:"^1.1.1","png-to-ico":"^3.0.2",sharp:"^0.35.3"},devDependencies:{"@types/degit":"^2.8.6","@types/node":"^26.2.0",esbuild:"^0.28.2",tsx:"^4.23.12",typescript:"^6.0.3",vitest:"^4.1.11"},engines:{node:">=24.0.0"},publishConfig:{access:"public",registry:"https://registry.npmjs.org/"}};import Hr from"node:path";import Q from"picocolors";var Ye=new Set;function ji(e){return Ye.add(e),()=>Ye.delete(e)}function Di(e){let{logger:t=p=>console.error(p),exitOnCancel:r=process.env.NODE_ENV!=="test"}=e??{},i=!1,n=async()=>{let p=[...Ye];Ye.clear();for(let u of p)try{await u()}catch(d){t(`Cleanup failed: ${d instanceof Error?d.message:String(d)}`)}},o=()=>{if(i){r&&process.exit(130);return}i=!0;let p=Ye.size>0;n().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)}`)},c=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",c),()=>{process.off("SIGINT",o),process.off("SIGTERM",o),process.off("uncaughtException",s),process.off("unhandledRejection",c)}}import se from"picocolors";var Ia={reset:e=>e,red:se.red,green:se.green,yellow:se.yellow,blue:se.blue,cyan:se.cyan,magenta:se.magenta,white:se.white,gray:se.gray,bright:se.bold,dim:se.dim};function ye(e,t="reset"){let r=Ia[t]??(i=>i);console.log(r(e))}function $t(e){ye(`\u2716 ${e}`,"red")}var E=$t;function Li(e){ye(`\u26A0 ${e}`,"yellow")}function m(e){ye(e)}function Mi(){console.log(""),ye("\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"),ye("\u2551 \u2551","cyan"),ye("\u2551 \u{1F680} Create Teispace Next.js App \u{1F680} \u2551","cyan"),ye("\u2551 \u2551","cyan"),ye("\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 $a from"ora";function S(e="",t){let r=$a({text:e,...t});return r.start(),r}var ka=e=>e.charAt(0).toUpperCase()+e.slice(1),H=e=>e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase()),N=e=>ka(H(e));import Na from"ora";var x=Na();w();import{execFile as Aa}from"node:child_process";import{promisify as Fa}from"node:util";var _a=Fa(Aa),de=(e,t)=>_a("git",e,t?{cwd:t}:void 0);function Oa(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 Gi=async(e,t,r)=>{try{if(await de(["init"],e),await de(["add","."],e),await de(["commit","-m","Initial commit from @teispace/next-maker"],e),t&&(Oa(t),await de(["remote","add","origin",t],e),r)){await de(["fetch","origin"],e);let i="main";try{await de(["show-branch","origin/main"],e)}catch{try{await de(["show-branch","origin/master"],e),i="master"}catch{i="main"}}await de(["merge",`origin/${i}`,"--allow-unrelated-histories","-X","ours"],e),await de(["push","origin",`HEAD:${i}`],e)}}catch(i){console.warn("Failed to initialize git repository",i)}};import{execFile as ja}from"node:child_process";import{promisify as Da}from"node:util";var La=Da(ja),Ke=(e,t,r)=>La(e,t,{cwd:r}),Ui=async(e,t)=>{try{await Ke(t,["install"],e)}catch(r){throw new Error(`Failed to install dependencies with ${t}: ${r}`,{cause:r})}},Y=async(e,t,r)=>{let i=t==="npm"?["run",r]:[r];try{await Ke(t,i,e)}catch(n){console.warn(`Warning: Failed to run script '${r}': ${n}`)}},Ma=()=>{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"},A=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":Ma()},br=async(e,t,r)=>{if(r.length!==0)try{await Ke(t,[...Bi(t),...r],e)}catch(i){throw new Error(`Failed to install packages with ${t}: ${i}`,{cause:i})}},Bi=e=>{switch(e){case"npm":return["install"];case"yarn":return["add"];case"pnpm":return["add"];case"bun":return["add"];default:return["install"]}},z=async(e,t)=>{let r=await A(e);await br(e,r,[t])},Ha=e=>{switch(e){case"npm":return"--save-dev";case"yarn":case"pnpm":case"bun":return"-D";default:return"--save-dev"}},ue=async(e,t,r)=>{if(r.length!==0)try{await Ke(t,[...Bi(t),Ha(t),...r],e)}catch(i){throw new Error(`Failed to install dev packages with ${t}: ${i}`,{cause:i})}},kt=async(e,t)=>{let r=await A(e);await ue(e,r,[t])},Ir=async(e,t,r)=>{if(r.length!==0)try{await Ke(t,[...Ga(t),...r],e)}catch(i){throw new Error(`Failed to uninstall packages with ${t}: ${i}`,{cause:i})}},Ga=e=>{switch(e){case"npm":return["uninstall"];case"yarn":return["remove"];case"pnpm":return["remove"];case"bun":return["remove"];default:return["uninstall"]}},He=async(e,t)=>{let r=await A(e);await Ir(e,r,[t])};import Ua from"enquirer";var Ba=/^[a-z0-9-_]+$/,za=/^\d+\.\d+\.\d+$/,zi=e=>Ba.test(e),Va=e=>za.test(e),Vi=(e,t={})=>{let r=t.projectName??e??"my-app";if(!zi(r))throw new Error(`Invalid project name "${r}". Use lowercase letters, digits, hyphens, and underscores only.`);let i=t.version??"0.1.0";if(!Va(i))throw new Error(`Invalid version "${i}". Expected semver (e.g. 0.1.0).`);let n=t.author??"Teispace",o=t.company??n;return{projectName:r,description:t.description??"A Next.js application",author:n,version:i,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:Ja}=Ua,Ji=async e=>{if(e!==void 0&&!zi(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 Ja([{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};w();import Wa from"node:path";var ae=async(e,t)=>{let r=qa(t);await h(Wa.join(e,"test/test-utils.tsx"),r)},qa=({redux:e,i18n:t})=>e&&t?Xa:e?Ya:t?Ka:Za,Xa=`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
- `,da=`import { type RenderOptions, render } from '@testing-library/react';
88
+ `,Ya=`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
- `,ua=`import { type RenderOptions, render } from '@testing-library/react';
127
+ `,Ka=`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
- `,fa=`import { type RenderOptions, render } from '@testing-library/react';
167
+ `,Za=`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 yn 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 xn=async(e,t)=>{if(t.bundleAnalyzer)return;let r=yn.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(yn.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 Pn=async(e,t)=>{t.darkMode||(await C(Ue.join(e,c.THEME_PROVIDER)),await ga(e),await ha(e),await xa(e))},ga=async e=>{let t=Ue.join(e,c.PROVIDERS_INDEX),r=await f(t);r=r.replace(/export \* from '\.\/CustomThemeProvider';\n/,""),await g(t,r)},ha=async e=>{let t=Ue.join(e,c.GLOBALS_CSS);if(m(t)){let r=await f(t);r=r.replace(/@custom-variant dark \(.*?\);\n\n/,""),r=r.replace(/@theme \{[\s\S]*?\}\n/,""),await g(t,r)}},ya=e=>e.replace(/\bbg-light\b\s?/g,"").replace(/\bdark:bg-dark\b\s?/g,"").replace(/\s{2,}/g," ").replace(/suppressHydrationWarning=\{true\}/g,""),xa=async e=>{let t=[Ue.join(e,c.ROOT_LAYOUT),Ue.join(e,"src/app/[locale]/layout.tsx")];for(let r of t)if(m(r)){let n=await f(r),i=ya(n);i!==n&&await g(r,i)}};S();P();ze();import _ from"node:path";var Tn=async(e,t)=>{let r=_.join(e,c.HTTP_UTILS),n=t.httpClient!=="none"||!!t.reactSecureStorage;t.httpClient==="none"?(await Be(e),await Ta(e,r,n)):t.httpClient==="axios"?(await ba(e,r),await ke(e,["axios"]),await Ae(e,["axios"])):t.httpClient==="fetch"?(await Ra(e,r),await ke(e,["fetch"]),await Ae(e,["fetch"])):t.httpClient},Ta=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 $a(e),await C(_.join(e,c.APP_APIS)),await Ia(e)),await Na(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 ka(e))},ba=async(e,t)=>{await w(_.join(e,c.FETCH_CLIENT));let r=await f(_.join(t,"index.ts"));r=r.replace(/export .* from '\.\/fetch-client';\n/g,""),await g(_.join(t,"index.ts"),r);let n=_.join(e,c.HTTP_TYPES);if(m(n)){let i=await f(n);i=i.replace(/export interface FetchClientOptions \{[\s\S]*?\}\n\n/,""),i=i.replace(/export interface ExtendedRequestInit extends RequestInit \{[\s\S]*?\}\n\n/,""),await g(n,i)}},Ra=async(e,t)=>{await w(_.join(e,c.AXIOS_CLIENT));let r=await f(_.join(t,"index.ts"));r=r.replace(/export .* from '\.\/axios-client';\n/g,""),await g(_.join(t,"index.ts"),r),await Ne(e,["fetch"]);let n=_.join(e,c.HTTP_TYPES);if(m(n)){let i=await f(n);i=i.replace(/export interface AxiosClientOptions \{[\s\S]*?\}\n\n/,""),await g(n,i)}},$a=async e=>{let t=_.join(e,c.UTILS_INDEX);if(m(t)){let r=await f(t);r=r.replace(/export \* from '\.\/http';\n/,""),await g(t,r)}},Ia=async e=>{let t=_.join(e,c.CONFIG_INDEX);if(m(t)){let r=await f(t);r=r.replace(/export \* from '\.\/app-apis';\n/,""),await g(t,r)}},Na=async e=>{let t=_.join(e,c.CONSTANTS);if(m(t)){let r=await f(t);r=r.replace(/export const API_RESPONSE_DATA_KEY = 'data';\n/,""),r=r.replace(/export const SAVE_AUTH_TOKENS = false;\n/,""),await g(t,r)}},ka=async e=>{let t=_.join(e,c.TYPES_INDEX);if(m(t)){let r=await f(t);r=r.replace(/export \* from '\.\/utility';\n/,""),r=r.replace(/export \* from '\.\/common';\n/,""),await g(t,r)}};S();P();import q from"node:path";var bn=async(e,t)=>{t.i18n||(await _a(e),await Oa(e),await Fa(e),await ja(e),await Aa(e))},Aa=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)},_a=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))},Oa=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)}},Fa=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)}},ja=async e=>{let t=q.join(e,c.COUNTER_COMPONENT);if(m(t)){let i=await f(t);i=i.replace(/import\s+\{\s*useTranslations\s*\}\s+from\s+['"]next-intl['"];\n/,""),i=i.replace(/\s*const\s+t\s*=\s*useTranslations\(['"]Count['"]\);\n/,""),i=i.replace(/\{t\('currentCount',\s*\{\s*count:\s*value\s*\}\)\}/g,"Current Count: {value}"),i=i.replace(/\{t\(['"]increment['"]\)\}/g,"Increment"),i=i.replace(/\{t\(['"]decrement['"]\)\}/g,"Decrement"),i=i.replace(/\{t\(['"]reset['"]\)\}/g,"Reset"),await g(t,i)}let r=q.join(e,"src/features/counter/components/Counter.test.tsx"),n=q.join(e,"test/test-utils.tsx");await C(r),await C(n)};S();P();import de from"node:path";var Rn=async(e,t)=>{t.httpClient!=="none"||t.reactSecureStorage||await w(de.join(e,c.STORAGE_SERVICE))},$n=async e=>{await C(de.join(e,c.LICENSE))},In=async e=>{await C(de.join(e,c.CHANGELOG))},Nn=async e=>{await C(de.join(e,c.NVM_RC)),await C(de.join(e,c.NPM_RC))},kn=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 An from"node:path";S();P();var _n=async(e,t)=>{if(t.reactCompiler)return;let r=An.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(An.join(e,c.PACKAGE_JSON),n=>(n.devDependencies&&delete n.devDependencies[T.REACT_COMPILER_BABEL],n))};S();P();import we from"node:path";var On=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 Da(e),await La(e))},Da=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)},La=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();P();import Fn from"node:path";var jn=async(e,t)=>{if(t.i18n)return;let r=Fn.join(e,c.SEO_FILE);m(r)&&await g(r,Ma);let n=Fn.join(e,c.SITEMAP_FILE);m(n)&&await g(n,Ga)},Ma=`import type { Metadata } from 'next';
189
+ `;import qi from"node:path";var R={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"};P();w();var Xi=async(e,t)=>{if(t.bundleAnalyzer)return;let r=qi.join(e,a.NEXT_CONFIG);if(l(r)){let i=await g(r);i=i.replace(/import\s+withBundleAnalyzer\s+from\s+'@next\/bundle-analyzer';\n/,""),i=i.replace(/const\s+bundleAnalyzer\s*=\s*withBundleAnalyzer\(\{[\s\S]*?\}\);\n+/,""),i=i.replace(/bundleAnalyzer\(([^)]*)\)/,"$1"),await h(r,i)}await F(qi.join(e,a.PACKAGE_JSON),i=>(i.devDependencies&&delete i.devDependencies[R.NEXT_BUNDLE_ANALYZER],i.scripts&&delete i.scripts.analyze,i))};P();w();import Ze from"node:path";var Yi=async(e,t)=>{t.darkMode||(await C(Ze.join(e,a.THEME_PROVIDER)),await Qa(e),await ec(e),await rc(e))},Qa=async e=>{let t=Ze.join(e,a.PROVIDERS_INDEX),r=await g(t);r=r.replace(/export \* from '\.\/CustomThemeProvider';\n/,""),await h(t,r)},ec=async e=>{let t=Ze.join(e,a.GLOBALS_CSS);if(l(t)){let r=await g(t);r=r.replace(/@custom-variant dark \(.*?\);\n\n/,""),r=r.replace(/@theme \{[\s\S]*?\}\n/,""),await h(t,r)}},tc=e=>e.replace(/\bbg-light\b\s?/g,"").replace(/\bdark:bg-dark\b\s?/g,"").replace(/\s{2,}/g," ").replace(/suppressHydrationWarning=\{true\}/g,""),rc=async e=>{let t=[Ze.join(e,a.ROOT_LAYOUT),Ze.join(e,"src/app/[locale]/layout.tsx")];for(let r of t)if(l(r)){let i=await g(r),n=tc(i);n!==i&&await h(r,n)}};P();w();Ue();import D from"node:path";var rn=async(e,t)=>{let r=D.join(e,a.HTTP_UTILS),i=t.httpClient!=="none"||!!t.reactSecureStorage;t.httpClient==="none"?(await et(e),await pc(e,r,i)):t.httpClient==="axios"?(await lc(e,r),await xe(e,["axios"]),await we(e,["axios"])):t.httpClient==="fetch"?(await mc(e,r),await xe(e,["fetch"]),await we(e,["fetch"])):t.httpClient},pc=async(e,t,r)=>{await v(D.join(e,a.AXIOS_CLIENT)),await v(D.join(e,a.FETCH_CLIENT)),r?(await h(D.join(t,"index.ts"),`export * from './token-store';
190
+ `),await C(D.join(e,a.CLIENT_UTILS)),await Ge(e,[])):(await v(t),await dc(e),await C(D.join(e,a.APP_APIS)),await uc(e)),await fc(e),await v(D.join(e,a.ERRORS_DIR)),r||(await v(D.join(e,a.COMMON_TYPES_DIR)),await v(D.join(e,a.UTILITY_TYPES_DIR)),await gc(e))},lc=async(e,t)=>{await v(D.join(e,a.FETCH_CLIENT));let r=await g(D.join(t,"index.ts"));r=r.replace(/export .* from '\.\/fetch-client';\n/g,""),await h(D.join(t,"index.ts"),r);let i=D.join(e,a.HTTP_TYPES);if(l(i)){let n=await g(i);n=n.replace(/export interface FetchClientOptions \{[\s\S]*?\}\n\n/,""),n=n.replace(/export interface ExtendedRequestInit extends RequestInit \{[\s\S]*?\}\n\n/,""),await h(i,n)}},mc=async(e,t)=>{await v(D.join(e,a.AXIOS_CLIENT));let r=await g(D.join(t,"index.ts"));r=r.replace(/export .* from '\.\/axios-client';\n/g,""),await h(D.join(t,"index.ts"),r),await Ge(e,["fetch"]);let i=D.join(e,a.HTTP_TYPES);if(l(i)){let n=await g(i);n=n.replace(/export interface AxiosClientOptions \{[\s\S]*?\}\n\n/,""),await h(i,n)}},dc=async e=>{let t=D.join(e,a.UTILS_INDEX);if(l(t)){let r=await g(t);r=r.replace(/export \* from '\.\/http';\n/,""),await h(t,r)}},uc=async e=>{let t=D.join(e,a.CONFIG_INDEX);if(l(t)){let r=await g(t);r=r.replace(/export \* from '\.\/app-apis';\n/,""),await h(t,r)}},fc=async e=>{let t=D.join(e,a.CONSTANTS);if(l(t)){let r=await g(t);r=r.replace(/export const API_RESPONSE_DATA_KEY = 'data';\n/,""),r=_r(r),await h(t,r)}},gc=async e=>{let t=D.join(e,a.TYPES_INDEX);if(l(t)){let r=await g(t);r=r.replace(/export \* from '\.\/utility';\n/,""),r=r.replace(/export \* from '\.\/common';\n/,""),await h(t,r)}};P();w();import Z from"node:path";var nn=async(e,t)=>{t.i18n||(await yc(e),await xc(e),await wc(e),await Pc(e),await hc(e))},hc=async e=>{let t=Z.join(e,a.ENV_EXAMPLE);if(!l(t))return;let r=await g(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 h(t,r)},yc=async e=>{await v(Z.join(e,a.I18N_DIR)),await v(Z.join(e,a.LOCALE_DIR)),await C(Z.join(e,a.PROXY)),await C(Z.join(e,a.MIDDLEWARE)),await C(Z.join(e,a.I18N_TYPES)),await C(Z.join(e,a.APP_LOCALES))},xc=async e=>{let t=Z.join(e,a.TYPES_INDEX);if(l(t)){let i=await g(t);i=i.replace(/export \* from '\.\/i18n';\n/,""),await h(t,i)}let r=Z.join(e,a.CONFIG_INDEX);if(l(r)){let i=await g(r);i=i.replace(/export \* from '\.\/app-locales';\n/,""),await h(r,i)}},wc=async e=>{let t=Z.join(e,a.NEXT_CONFIG);if(l(t)){let r=await g(t);r=r.replace(/import createNextIntlPlugin from 'next-intl\/plugin';\n/,""),r=r.replace(/const withNextIntl = createNextIntlPlugin\(\);\n+/,""),r=r.replace(/withNextIntl\(([^)]+)\)/,"$1"),await h(t,r)}},Pc=async e=>{let t=Z.join(e,a.COUNTER_COMPONENT);if(l(t)){let n=await g(t);n=n.replace(/import\s+\{\s*useTranslations\s*\}\s+from\s+['"]next-intl['"];\n/,""),n=n.replace(/\s*const\s+t\s*=\s*useTranslations\(['"]Count['"]\);\n/,""),n=n.replace(/\{t\('currentCount',\s*\{\s*count:\s*value\s*\}\)\}/g,"Current Count: {value}"),n=n.replace(/\{t\(['"]increment['"]\)\}/g,"Increment"),n=n.replace(/\{t\(['"]decrement['"]\)\}/g,"Decrement"),n=n.replace(/\{t\(['"]reset['"]\)\}/g,"Reset"),await h(t,n)}let r=Z.join(e,"src/features/counter/components/Counter.test.tsx"),i=Z.join(e,"test/test-utils.tsx");await C(r),await C(i)};P();w();import Pe from"node:path";var on=async(e,t)=>{t.httpClient!=="none"||t.reactSecureStorage||await v(Pe.join(e,a.STORAGE_SERVICE))},sn=async e=>{await C(Pe.join(e,a.LICENSE))},an=async e=>{await C(Pe.join(e,a.CHANGELOG))},cn=async e=>{await C(Pe.join(e,a.NVM_RC)),await C(Pe.join(e,a.NPM_RC))},pn=async e=>{await v(Pe.join(e,a.CLAUDE_DIR)),await v(Pe.join(e,a.DOCS_DIR)),await v(Pe.join(e,a.VSCODE_DIR))};import ln from"node:path";P();w();var mn=async(e,t)=>{if(t.reactCompiler)return;let r=ln.join(e,a.NEXT_CONFIG);if(l(r)){let i=await g(r);i=i.replace(/^\s*reactCompiler:\s*true,?\n/m,""),await h(r,i)}await F(ln.join(e,a.PACKAGE_JSON),i=>(i.devDependencies&&delete i.devDependencies[R.REACT_COMPILER_BABEL],i))};P();w();import Ie from"node:path";var dn=async(e,t)=>{t.redux||(await v(Ie.join(e,a.STORE)),await v(Ie.join(e,a.COUNTER_FEATURE)),await C(Ie.join(e,a.STORE_PROVIDER)),await C(Ie.join(e,"test/test-utils.tsx")),await vc(e),await Sc(e))},vc=async e=>{let t=Ie.join(e,a.PROVIDERS_INDEX),r=await g(t);r=r.replace(/export \* from '\.\/StoreProvider';\n/,""),await h(t,r)},Sc=async e=>{let t=[Ie.join(e,a.ROOT_PAGE),Ie.join(e,a.LOCALE_PAGE)];for(let r of t)if(l(r)){let i=await g(r);i=i.replace(/import\s+\{\s*Counter\s*\}\s+from\s+['"]@\/features\/counter['"];\n?/,""),i=i.replace(/<Counter\s*\/>\n?/g,""),await h(r,i)}};P();w();import un from"node:path";var fn=async(e,t)=>{if(t.i18n)return;let r=un.join(e,a.SEO_FILE);l(r)&&await h(r,Ec);let i=un.join(e,a.SITEMAP_FILE);l(i)&&await h(i,Tc)},Ec=`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
- `,Ga=`import type { MetadataRoute } from 'next';
257
+ `,Tc=`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();P();var Ua=[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],Dn=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 Ua)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 Ln from"node:path";import{readFile as Ha,writeFile as Ba}from"node:fs/promises";import za 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
- `+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=`
276
- ${t}: ${r},`,a=o.trimEnd()+s;return e.replace(n,`combineReducers({${a}
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()}
273
+ `;import At from"node:path";P();w();var Cc=[R.VITEST,R.JSDOM,R.VITE_PLUGIN_REACT,R.TESTING_LIBRARY_DOM,R.TESTING_LIBRARY_JEST_DOM,R.TESTING_LIBRARY_REACT,R.TESTING_LIBRARY_USER_EVENT],gn=async(e,t)=>{t.tests||(await C(At.join(e,a.VITEST_CONFIG)),await v(At.join(e,a.TEST_DIR)),await C(At.join(e,"src/features/counter/components/Counter.test.tsx")),await F(At.join(e,a.PACKAGE_JSON),r=>{if(r.devDependencies)for(let i of Cc)delete r.devDependencies[i];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}))};P();w();import it from"node:path";P();w();import hn from"node:path";import{readFile as Rc,writeFile as bc}from"node:fs/promises";import Ic from"node:path";var tt=(e,t)=>{let r=/import\s+.*\s+from\s+['"].*['"];?\n/g,i=e.match(r);if(i&&i.length>0){let n=i[i.length-1],o=e.lastIndexOf(n);return e.slice(0,o+n.length)+t+`
274
+ `+e.slice(o+n.length)}return`${t}
275
+ ${e}`},Lr=(e,t,r)=>{let i=/combineReducers\(\{([^}]*)\}\)/s,n=e.match(i);if(!n)throw new Error("Could not find combineReducers in rootReducer.ts");let o=n[1],s=`
276
+ ${t}: ${r},`,c=o.trimEnd()+s;return e.replace(i,`combineReducers({${c}
277
+ })`)},rt=(e,t)=>{let r=e.lastIndexOf("} as const;");if(r===-1)throw new Error("Could not find closing brace of AppApis object");let i=e.substring(0,r),n=e.substring(r);return`${i.trimEnd()}
278
278
  ${t}
279
- ${i}`};var ve=async e=>{let{projectPath:t,name:r,persist:n,importPath:i}=e,o=za.join(t,"src","store","rootReducer.ts");try{let s=await Ha(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=Ve(s,h);let x=n?`persistReducer(${u}, ${p})`:p;s=ir(s,a,x),await Ba(o,s)}catch(s){throw new Error(`Failed to register reducer '${r}' in rootReducer: ${s}`,{cause:s})}};var Mn="import { attachWsBridge, wsClient } from '@/lib/utils/ws';",Va=`
279
+ ${n}`};var $e=async e=>{let{projectPath:t,name:r,persist:i,importPath:n}=e,o=Ic.join(t,"src","store","rootReducer.ts");try{let s=await Rc(o,"utf-8"),c=H(r),p=`${c}Reducer`,u=`${c}PersistConfig`,d=n.replace(/^src\//,"@/"),f=i?`import { ${p}, ${u} } from '${d}';`:`import { ${p} } from '${d}';`;s=tt(s,f);let y=i?`persistReducer(${u}, ${p})`:p;s=Lr(s,c,y),await bc(o,s)}catch(s){throw new Error(`Failed to register reducer '${r}' in rootReducer: ${s}`,{cause:s})}};var yn="import { attachWsBridge, wsClient } from '@/lib/utils/ws';",$c=`
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=za.
286
286
  if (!store) return;
287
287
  return attachWsBridge(wsClient, store.dispatch);
288
288
  }, []);
289
- `,Gn=async e=>{await ve({projectPath:e,name:"ws",persist:!1,importPath:"src/store/slices/ws.slice"})},Ja=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)}${Mn}
290
- ${t.slice(i)}`,t=Ya(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
- ${Va.trimEnd()}
292
- `),t},gt=e=>{let t=e;return t=t.replace(new RegExp(`${Ka(Mn)}\\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=Wa(t)),t},Wa=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=Ln.join(e,c.STORE_PROVIDER);if(!m(t))return;let r=await f(t),n=Ja(r);n!==r&&await g(t,n)};var Hn=async e=>{let t=Ln.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+=qa,n=!0),r.includes("vi.mock('server-only'")||(r+=Xa,n=!0),n&&await g(t,r)},qa=`
289
+ `,Ft=async e=>{await $e({projectPath:e,name:"ws",persist:!1,importPath:"src/store/slices/ws.slice"})},kc=e=>{if(e.includes("from '@/lib/utils/ws'"))return e;let t=e,r=/(^import\s[^\n]*\n)+/m,i=t.match(r);if(!i)throw new Error("injectBridgeMount: no `import` lines found \u2014 expected a StoreProvider with imports.");let n=(i.index??0)+i[0].length;t=`${t.slice(0,n)}${yn}
290
+ ${t.slice(n)}`,t=_c(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
+ ${$c.trimEnd()}
292
+ `),t},_t=e=>{let t=e;return t=t.replace(new RegExp(`${Oc(yn)}\\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=Nc(t)),t},Nc=e=>{let t=/import\s*\{([^}]*)\}\s*from\s*['"]react['"];\n?/,r=e.match(t);if(!r)return e;let i=r[1].split(",").map(o=>o.trim()).filter(o=>o.length>0&&o!=="useEffect");if(i.length===0)return e.replace(t,"");let n=`import { ${i.join(", ")} } from 'react';
294
+ `;return e.replace(t,n)},Ot=async e=>{let t=hn.join(e,a.STORE_PROVIDER);if(!l(t))return;let r=await g(t),i=kc(r);i!==r&&await h(t,i)};var jt=async e=>{let t=hn.join(e,a.TEST_SETUP_FILE);if(!l(t))return;let r=await g(t),i=!1;r.includes("vi.mock('react-secure-storage'")||(r+=Ac,i=!0),r.includes("vi.mock('server-only'")||(r+=Fc,i=!0),i&&await h(t,r)},Ac=`
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
- `,Xa=`
311
+ `,Fc=`
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
- `,Ya=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)},Ka=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 Bn=async(e,t)=>{t.ws||(await w(We.join(e,c.WS_UTILS)),await C(We.join(e,c.WS_SLICE_FILE)),t.redux&&(await Za(e),await Qa(e)),await ec(e))},Za=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)},Qa=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)},ec=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 zn=async(e,t)=>{let r=b("Customizing features...");try{await Tn(e,t),await Rn(e,t),await Bn(e,t),await On(e,t),await Pn(e,t),await xn(e,t),await bn(e,t),await jn(e,t),await _n(e,t),await Dn(e,t),await $n(e),await In(e),await Nn(e),await kn(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 tc from"node:path";S();P();var Vn=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(tc.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 O from"node:path";S();P();var Wn=async(e,t)=>{await rc(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)},rc=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)))},nc=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)))},ic=async(e,t)=>{t.ci||await w(O.join(e,c.GITHUB_WORKFLOWS))},oc=async(e,t)=>{let r=O.join(e,c.GITHUB_DIR);if(!t.keepTemplates)await w(O.join(r,c.GITHUB_ISSUE_TEMPLATE)),await C(O.join(r,c.GITHUB_PR_TEMPLATE));else{let n=O.join(r,c.GITHUB_ISSUE_TEMPLATE),i=O.join(r,c.GITHUB_PR_TEMPLATE),o=s=>s.replace(/Teispace/g,t.company).replace(/support@teispace\.com/g,t.email).replace(/Next\.js Starter/g,t.projectName).replace(/\[AUTHOR\]/g,t.author).replace(/\[COMPANY\]/g,t.company).replace(/\[EMAIL\]/g,t.email);if(m(i)){let s=await f(i);s=o(s),await g(i,s)}try{if(m(n)){let s=await Jn(n);for(let a of s){let p=O.join(n,a),u=await f(p);u=o(u),await g(p,u)}}}catch{}}},sc=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))},ac=async(e,t)=>{if(t.docker){let r=O.join(e,c.ENV_EXAMPLE);if(m(r)){let n=await f(r),i=(o,s)=>{let a=new RegExp(`${o}=.*`);a.test(n)?n=n.replace(a,`${o}=${s}`):n+=`${o}=${s}
319
- `};i("CONTAINER_NAME",t.containerName||"next-app"),i("IMAGE_NAME",t.imageName||"nextjs-starter"),i("IMAGE_TAG",t.imageTag||"latest"),await g(r,n)}}else{await C(O.join(e,c.DOCKERFILE)),await C(O.join(e,c.DOCKER_COMPOSE)),await C(O.join(e,c.DOCKERIGNORE));let r=O.join(e,c.ENV_EXAMPLE);if(m(r)){let n=await f(r);n=n.replace(/# Docker Compose Configuration\n/,""),n=n.replace(/CONTAINER_NAME=.*\n/,""),n=n.replace(/IMAGE_NAME=.*\n/,""),n=n.replace(/IMAGE_TAG=.*\n/,""),await g(r,n)}}},cc=async(e,t)=>{let r=async o=>{let s=await Jn(o,{withFileTypes:!0}),a=[];for(let p of s){let u=O.join(o,p.name);p.isDirectory()&&p.name!=="node_modules"&&p.name!==".git"?a.push(...await r(u)):p.isFile()&&p.name.toLowerCase()==="readme.md"&&a.push(u)}return a},n=await r(e),i=O.join(e,c.README);for(let o of n)o!==i&&await C(o);if(t.readme){let o=`# ${t.projectName}
318
+ `,_c=e=>{let t=/import\s*\{([^}]*)\}\s*from\s*['"]react['"];/,r=e.match(t);if(!r)return e;let i=r[1];if(/\buseEffect\b/.test(i))return e;let n=i.split(",").map(s=>s.trim()).filter(Boolean);n.push("useEffect"),n.sort();let o=`import { ${n.join(", ")} } from 'react';`;return e.replace(t,o)},Oc=e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),Dt=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 xn=async(e,t)=>{t.ws||(await v(it.join(e,a.WS_UTILS)),await C(it.join(e,a.WS_SLICE_FILE)),t.redux&&(await jc(e),await Dc(e)),await Lc(e))},jc=async e=>{let t=it.join(e,a.ROOT_REDUCER);if(!l(t))return;let r=await g(t),i=Dt(r);i!==r&&await h(t,i)},Dc=async e=>{let t=it.join(e,a.STORE_PROVIDER);if(!l(t))return;let r=await g(t),i=_t(r);i!==r&&await h(t,i)},Lc=async e=>{let t=it.join(e,a.PACKAGE_JSON);if(!l(t))return;let r=JSON.parse(await g(t));({...r.dependencies,...r.devDependencies})["socket.io-client"]&&await He(e,"socket.io-client")};var wn=async(e,t)=>{let r=S("Customizing features...");try{await rn(e,t),await on(e,t),await xn(e,t),await dn(e,t),await Yi(e,t),await Xi(e,t),await nn(e,t),await fn(e,t),await mn(e,t),await gn(e,t),await sn(e),await an(e),await cn(e),await pn(e),t.tests&&await ae(e,{redux:t.redux,i18n:t.i18n}),r.succeed("Features customized.")}catch(i){throw r.fail("Failed to customize features."),i}};import Mc from"node:path";P();w();var Pn=async(e,t)=>{let r=S("Configuring package.json...");try{let i=t.gitRemote,n=t.gitHomepage,o=t.gitIssues;t.gitRemote&&(t.gitRemote.startsWith("git@github.com:")&&(i=t.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"")),n||(n=`${i.replace(/\.git$/,"")}#readme`),o||(o=`${i.replace(/\.git$/,"")}/issues`),i.endsWith(".git")||(i=`${i}.git`)),await F(Mc.join(e,a.PACKAGE_JSON),s=>(s.name=t.projectName,s.version=t.version,s.description=t.description,s.author=t.author,delete s.packageManager,t.gitRemote?(n&&(s.homepage=n),o&&(s.bugs={url:o}),i&&(s.repository={type:"git",url:i})):(delete s.homepage,delete s.bugs,delete s.repository),t.redux||(delete s.dependencies[R.REDUX_TOOLKIT],delete s.dependencies[R.REACT_REDUX],delete s.dependencies[R.REDUX],delete s.dependencies[R.REDUX_PERSIST]),t.httpClient!=="none"||t.reactSecureStorage||delete s.dependencies[R.REACT_SECURE_STORAGE],t.i18n||delete s.dependencies[R.NEXT_INTL],t.darkMode||delete s.dependencies[R.NEXT_THEMES],t.httpClient==="none"?delete s.dependencies[R.AXIOS]:t.httpClient==="fetch"&&delete s.dependencies[R.AXIOS],s)),r.succeed("package.json configured.")}catch(i){throw r.fail("Failed to configure package.json."),i}};import{readdir as vn}from"node:fs/promises";import L from"node:path";P();w();var Sn=async(e,t)=>{await Hc(e,t),await Gc(e,t),await Uc(e,t),await Bc(e,t),await zc(e,t),await Vc(e,t),await Jc(e,t)},Hc=async(e,t)=>{t.preCommitHooks||(await v(L.join(e,a.HUSKY_DIR)),await C(L.join(e,a.COMMITLINT_CONFIG)),await C(L.join(e,a.LINTSTAGED_RC)),await F(L.join(e,a.PACKAGE_JSON),r=>(delete r.devDependencies[R.HUSKY],delete r.devDependencies[R.COMMITLINT_CLI],delete r.devDependencies[R.COMMITLINT_CONFIG],delete r.devDependencies[R.LINT_STAGED],delete r.scripts.prepare,delete r.scripts.postinstall,delete r.commitlint,delete r["lint-staged"],r)))},Gc=async(e,t)=>{t.commitizen||(await C(L.join(e,a.CZRC)),await F(L.join(e,a.PACKAGE_JSON),r=>(delete r.devDependencies[R.COMMITIZEN],delete r.devDependencies[R.CZ_CONVENTIONAL_CHANGELOG],delete r.config?.commitizen,r.config&&Object.keys(r.config).length===0&&delete r.config,delete r.scripts.commit,r)))},Uc=async(e,t)=>{t.ci||await v(L.join(e,a.GITHUB_WORKFLOWS))},Bc=async(e,t)=>{let r=L.join(e,a.GITHUB_DIR);if(!t.keepTemplates)await v(L.join(r,a.GITHUB_ISSUE_TEMPLATE)),await C(L.join(r,a.GITHUB_PR_TEMPLATE));else{let i=L.join(r,a.GITHUB_ISSUE_TEMPLATE),n=L.join(r,a.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(l(n)){let s=await g(n);s=o(s),await h(n,s)}try{if(l(i)){let s=await vn(i);for(let c of s){let p=L.join(i,c),u=await g(p);u=o(u),await h(p,u)}}}catch{}}},zc=async(e,t)=>{let r=[a.CODE_OF_CONDUCT,a.CONTRIBUTING,a.SECURITY];for(let i of r)t.communityFiles.includes(i)||await C(L.join(e,i))},Vc=async(e,t)=>{if(t.docker){let r=L.join(e,a.ENV_EXAMPLE);if(l(r)){let i=await g(r),n=(o,s)=>{let c=new RegExp(`${o}=.*`);c.test(i)?i=i.replace(c,`${o}=${s}`):i+=`${o}=${s}
319
+ `};n("CONTAINER_NAME",t.containerName||"next-app"),n("IMAGE_NAME",t.imageName||"nextjs-starter"),n("IMAGE_TAG",t.imageTag||"latest"),await h(r,i)}}else{await C(L.join(e,a.DOCKERFILE)),await C(L.join(e,a.DOCKER_COMPOSE)),await C(L.join(e,a.DOCKERIGNORE));let r=L.join(e,a.ENV_EXAMPLE);if(l(r)){let i=await g(r);i=i.replace(/# Docker Compose Configuration\n/,""),i=i.replace(/CONTAINER_NAME=.*\n/,""),i=i.replace(/IMAGE_NAME=.*\n/,""),i=i.replace(/IMAGE_TAG=.*\n/,""),await h(r,i)}}},Jc=async(e,t)=>{let r=async o=>{let s=await vn(o,{withFileTypes:!0}),c=[];for(let p of s){let u=L.join(o,p.name);p.isDirectory()&&p.name!=="node_modules"&&p.name!==".git"?c.push(...await r(u)):p.isFile()&&p.name.toLowerCase()==="readme.md"&&c.push(u)}return c},i=await r(e),n=L.join(e,a.README);for(let o of i)o!==n&&await C(o);if(t.readme){let o=`# ${t.projectName}
320
320
 
321
321
  ${t.description}
322
322
 
@@ -329,30 +329,30 @@ ${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();P();import or from"node:path";var qn=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 h(n,o)}else await C(n)};P();w();import Mr from"node:path";var En=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 i=["children: React.ReactNode;"],n=["children"];t.i18n&&(i.push("locale: SupportedLocale;"),i.push("messages: AbstractIntlMessages;"),i.push("timeZone: string;"),n.push("locale","messages","timeZone")),t.redux&&(i.push("preloadedState?: Partial<AppState>;"),n.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}
336
336
  </CustomThemeProvider>`),t.redux&&(o=`<StoreProvider preloadedState={preloadedState}>
337
337
  ${o}
338
338
  </StoreProvider>`),o==="{children}"&&(o="<>{children}</>");let s=`type RootProviderProps = {
339
- ${n.join(`
339
+ ${i.join(`
340
340
  `)}
341
- };`,a=`'use client';
341
+ };`,c=`'use client';
342
342
  ${r.join(`
343
343
  `)}
344
344
 
345
345
  ${s}
346
346
 
347
- export const RootProvider = ({ ${i.join(", ")} }: RootProviderProps) => {
347
+ export const RootProvider = ({ ${n.join(", ")} }: RootProviderProps) => {
348
348
  return (
349
349
  ${o}
350
350
  );
351
351
  };
352
- `;await g(or.join(e,c.ROOT_PROVIDER),a)},Xn=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 h(Mr.join(e,a.ROOT_PROVIDER),c)},Tn=async(e,t)=>{if(t.i18n)return;let r=`\`\${livvic.variable} ${t.darkMode?"bg-light antialiased dark:bg-dark":"antialiased"}\``,i=(t.redux,""),n=t.httpClient!=="none",o=n?`// Regression sentinel \u2014 see file comment for what this guards.
353
353
  import { HttpClientBundleSentinel } from '@/lib/utils/http/__bundle-sentinel__/client-bundle-sentinel';
354
- `:"",s=i?`
355
- <HttpClientBundleSentinel />`:"",a=`import type { Metadata } from 'next';
354
+ `:"",s=n?`
355
+ <HttpClientBundleSentinel />`:"",c=`import type { Metadata } from 'next';
356
356
  import '@/styles/globals.css';
357
357
  import { Livvic } from 'next/font/google';
358
358
  ${o}import { RootProvider } from '@/providers';
@@ -377,14 +377,14 @@ export default function RootLayout({
377
377
  return (
378
378
  <html lang="en"${t.darkMode?" suppressHydrationWarning={true}":""}>
379
379
  <body className={${r}}>
380
- <RootProvider${n}>${s}
380
+ <RootProvider${i}>${s}
381
381
  {children}
382
382
  </RootProvider>
383
383
  </body>
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 h(Mr.join(e,a.ROOT_LAYOUT),c);let p=t.redux?`import { Counter } from '@/features/counter';
388
388
 
389
389
  `:"",u=t.redux?`
390
390
  <Counter />`:"",d=`${p}export default function Home() {
@@ -395,14 +395,14 @@ export default function RootLayout({
395
395
  </div>
396
396
  );
397
397
  }
398
- `;await g(or.join(e,c.ROOT_PAGE),d)};import pc from"degit";var Yn=async e=>{let t=b("Downloading template...");try{await pc("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"],lc=e=>{if(e!==void 0){if(!ar.includes(e))throw new Error(`Invalid --package-manager "${e}". Valid: ${ar.join(", ")}.`);return e}},Kn=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=lc(r.packageManager);await dc(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)}},mc=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("")},dc=async(e,t)=>{cn();let r;t.yes?(r=fn(e,{packageManager:t.packageManager}),l(X.cyan(`\u2728 Bootstrapping ${r.projectName} with the recommended defaults`)),l(""),mc(r)):(l("Welcome to the Teispace Next.js App Creator!"),l(""),r=await gn(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=on(async()=>{console.log(X.red(`
400
- Process interrupted. Cleaning up...`)),await o()});try{if(await Yn(n),await Vn(n,r),await zn(n,r),await qe("Generating providers and layout...","Providers and layout generated.",async()=>{await qn(n,r),await Xn(n,r)},i),await qe("Setting up developer tools...","Developer tools configured.",()=>Wn(n,r),i),await qe("Initializing Git...","Git initialized.",()=>ln(n,r.gitRemote,r.pushToRemote),i),await qe("Installing dependencies...","Dependencies installed.",()=>mn(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 Zn=/^[A-Za-z][A-Za-z0-9-]*$/,uc=/^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;function Qn(e){return uc.test(e)}function H(e,t="name"){let r=e?.trim();if(!r)throw new Error(`A ${t} is required.`);if(!Zn.test(r))throw new Error(`Invalid ${t} "${e}". Use letters, digits, and hyphens only \u2014 no slashes, spaces, "..", or absolute paths.`);if(Qn(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(!Zn.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(Qn(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 ii,writeFile as pr}from"node:fs/promises";import Se from"node:path";P();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
- `)},ni=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=$(t);o?await yc(s,r,o,n,i):await xc(s,t,r,n,i)},yc=async(e,t,r,n,i)=>{let o=Se.join(t,r,"components");await ii(o,{recursive:!0}),await pr(Se.join(o,`${e}.tsx`),cr({componentName:e,isClient:n,hasI18n:i}))},xc=async(e,t,r,n,i)=>{let o=Se.join(r,"src","components","common",e);await ii(o,{recursive:!0}),await pr(Se.join(o,`${e}.tsx`),cr({componentName:e,isClient:n,hasI18n:i})),await pr(Se.join(o,"index.ts"),ni({componentName:e}));let s=Se.join(r,"src","components","common","index.ts");await Pc(s,`export { ${e} } from './${e}';
403
- `);let a=Se.join(r,"src","components","index.ts");await wc(a)},Pc=async(e,t)=>{let r="";m(e)&&(r=await f(e)),r.includes(t.trim())||(r+=t,await g(e,r))},wc=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 vc}from"node:fs/promises";import Sc from"node:path";var oi=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
- ${i}
398
+ `;await h(Mr.join(e,a.ROOT_PAGE),d)};import Wc from"degit";var Cn=async e=>{let t=S("Downloading template...");try{await Wc("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 Gr=["npm","yarn","pnpm","bun"],qc=e=>{if(e!==void 0){if(!Gr.includes(e))throw new Error(`Invalid --package-manager "${e}". Valid: ${Gr.join(", ")}.`);return e}},Rn=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: ${Gr.join(", ")})`).action(async(t,r)=>{try{let i=qc(r.packageManager);await Yc(t,{yes:r.yes??!1,packageManager:i})}catch(i){E(`${i instanceof Error?i.message:i}`),process.exit(1)}})},nt=async(e,t,r,i)=>{let n=S(e);i.current=n;try{let o=await r();return n.succeed(t),o}finally{i.current===n&&(i.current=null)}},Xc=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})`),m(Q.dim("Defaults applied (run `next-maker remove <feature>` to undo any of them):")),m(Q.dim(` package manager : ${e.packageManager}`)),m(Q.dim(` features : ${t.join(", ")}`)),m("")},Yc=async(e,t)=>{Mi();let r;t.yes?(r=Vi(e,{packageManager:t.packageManager}),m(Q.cyan(`\u2728 Bootstrapping ${r.projectName} with the recommended defaults`)),m(""),Xc(r)):(m("Welcome to the Teispace Next.js App Creator!"),m(""),r=await Ji(e),t.packageManager&&(r={...r,packageManager:t.packageManager}));let i=Hr.resolve(process.cwd(),r.projectName);l(i)&&(console.error(Q.red(`Error: Directory ${r.projectName} already exists.`)),process.exit(1));let n={current:null},o=async()=>{if(l(i)){n.current?.stop(),n.current=null,console.log(Q.yellow(`
399
+ Cleaning up: Deleting directory ${r.projectName}...`));try{await v(i),console.log(Q.green("Cleanup successful."))}catch(c){console.error(Q.red(`Failed to clean up directory ${r.projectName}:`),c)}}},s=ji(async()=>{console.log(Q.red(`
400
+ Process interrupted. Cleaning up...`)),await o()});try{if(await Cn(i),await Pn(i,r),await wn(i,r),await nt("Generating providers and layout...","Providers and layout generated.",async()=>{await En(i,r),await Tn(i,r)},n),await nt("Setting up developer tools...","Developer tools configured.",()=>Sn(i,r),n),await nt("Initializing Git...","Git initialized.",()=>Gi(i,r.gitRemote,r.pushToRemote),n),await nt("Installing dependencies...","Dependencies installed.",()=>Ui(i,r.packageManager),n),await nt("Formatting and linting...","Formatted.",()=>Y(i,r.packageManager,"lint:fix"),n),r.copyEnv){let c=Hr.join(i,".env.example"),p=Hr.join(i,".env");l(c)&&await(await import("node:fs/promises")).copyFile(c,p)}s(),m(""),m(Q.green(`\u2728 Project ${r.projectName} created successfully!`)),m(""),m("To get started:"),m(Q.cyan(` cd ${r.projectName}`)),m(Q.cyan(` ${r.packageManager==="npm"?"npm run dev":`${r.packageManager} dev`}`)),m("")}catch(c){s(),n.current?.fail("Failed to create project."),n.current=null,console.error(c),await o(),process.exit(1)}};import ti from"node:path";import pe from"picocolors";import Lt from"node:path";var bn=/^[A-Za-z][A-Za-z0-9-]*$/,Kc=/^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;function In(e){return Kc.test(e)}function J(e,t="name"){let r=e?.trim();if(!r)throw new Error(`A ${t} is required.`);if(!bn.test(r))throw new Error(`Invalid ${t} "${e}". Use letters, digits, and hyphens only \u2014 no slashes, spaces, "..", or absolute paths.`);if(In(r))throw new Error(`Invalid ${t} "${e}". That is a reserved name on Windows.`);return r}function ce(e,t="path"){let r=e?.trim();if(!r)throw new Error(`A ${t} is required.`);let i=r.replace(/^\.\//,"");if(i.startsWith("/")||/^[a-zA-Z]:/.test(i))throw new Error(`Invalid ${t} "${e}". Must be a relative path inside the project (no leading "/" or drive letter).`);for(let n of i.split("/")){if(!bn.test(n))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(In(n))throw new Error(`Invalid ${t} "${e}". Segment "${n}" is reserved on Windows.`)}return i}function Mt(e,...t){let r=Lt.resolve(e),i=Lt.resolve(r,...t),n=Lt.relative(r,i);if(n===""||n===".")return i;if(n.startsWith("..")||Lt.isAbsolute(n))throw new Error(`Refusing to write outside the project directory (resolved path escapes "${r}").`);return i}W();import{mkdir as Fn,writeFile as Br}from"node:fs/promises";import ke from"node:path";w();var Ur=e=>{let{componentName:t,isClient:r,hasI18n:i}=e,n=e.translationNamespace||t,o=[];return(r||i)&&o.push("'use client';"),i&&o.push("import { useTranslations } from 'next-intl';"),o.push(""),o.push(`export function ${t}() {`),i?(o.push(` const t = useTranslations('${n}');`),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
+ `)},An=e=>`export { ${e.componentName} } from './${e.componentName}';
402
+ `;var zr=async e=>{let{name:t,projectPath:r,isClient:i,hasI18n:n,featurePath:o}=e,s=N(t);o?await tp(s,r,o,i,n):await rp(s,t,r,i,n)},tp=async(e,t,r,i,n)=>{let o=ke.join(t,r,"components");await Fn(o,{recursive:!0}),await Br(ke.join(o,`${e}.tsx`),Ur({componentName:e,isClient:i,hasI18n:n}))},rp=async(e,t,r,i,n)=>{let o=ke.join(r,"src","components","common",e);await Fn(o,{recursive:!0}),await Br(ke.join(o,`${e}.tsx`),Ur({componentName:e,isClient:i,hasI18n:n})),await Br(ke.join(o,"index.ts"),An({componentName:e}));let s=ke.join(r,"src","components","common","index.ts");await ip(s,`export { ${e} } from './${e}';
403
+ `);let c=ke.join(r,"src","components","index.ts");await np(c)},ip=async(e,t)=>{let r="";l(e)&&(r=await g(e)),r.includes(t.trim())||(r+=t,await h(e,r))},np=async e=>{let t="";l(e)&&(t=await g(e));let r=`export * from './common';
404
+ `;t.includes(r.trim())||(t+=r,await h(e,t))};import{writeFile as op}from"node:fs/promises";import sp from"node:path";var _n=e=>{let{camelName:t,pascalName:r,httpClient:i}=e,n=i==="axios"?"import { axiosClient } from '@/lib/utils/http';":"import { fetchClient } from '@/lib/utils/http';",o=i==="axios"?"axiosClient":"fetchClient";return`import { AppApis } from '@/lib/config';
405
+ ${n}
406
406
  import type { ResultAsync } from '@/types';
407
407
 
408
408
  /**
@@ -449,14 +449,14 @@ export const ${t}Service = {
449
449
  return ${o}.delete<void>(AppApis.${t}.delete(id));
450
450
  },
451
451
  };
452
- `},si=e=>{let{camelName:t,kebabName:r}=e;return` ${t}: {
452
+ `},On=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=$(t);await vc(Sc.join(r,`${t}.service.ts`),oi({camelName:i,pascalName:o,httpClient:n}))};import{mkdir as bc,writeFile as St}from"node:fs/promises";import K from"node:path";import{writeFile as Ec}from"node:fs/promises";import Cc from"node:path";var ai=e=>{let{camelName:t,httpClient:r}=e;return`import { AppApis } from '@/lib/config';
459
+ },`};var Vr=async e=>{let{name:t,outputPath:r,httpClient:i}=e,n=H(t),o=N(t);await op(sp.join(r,`${t}.service.ts`),_n({camelName:n,pascalName:o,httpClient:i}))};import{mkdir as lp,writeFile as Bt}from"node:fs/promises";import re from"node:path";import{writeFile as ap}from"node:fs/promises";import cp from"node:path";var jn=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,23 +465,23 @@ 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 Ec(Cc.join(r,`${t}.service.ts`),ai({camelName:i,httpClient:n}))};import{mkdir as Tc,writeFile as Ze}from"node:fs/promises";import Qe from"node:path";var ci=e=>{let{sliceName:t,withPersist:r}=e;return`export * from './${t}.slice';
468
+ `};var at=async e=>{let{name:t,outputPath:r,httpClient:i}=e,n=H(t);await ap(cp.join(r,`${t}.service.ts`),jn({camelName:n,httpClient:i}))};import{mkdir as pp,writeFile as ct}from"node:fs/promises";import pt from"node:path";var Dn=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
- `},pi=e=>{let{featureName:t,componentName:r,hookName:n,withStore:i,withService:o}=e;return`export { default as ${r} } from './components/${r}';
473
- export { ${n} } from './hooks/${n}';
474
- export * from './types/${t}.types';${i?`
472
+ `},Ln=e=>{let{featureName:t,componentName:r,hookName:i,withStore:n,withService:o}=e;return`export { default as ${r} } from './components/${r}';
473
+ export { ${i} } from './hooks/${i}';
474
+ export * from './types/${t}.types';${n?`
475
475
  export * from './store';`:""}${o?`
476
476
  export * from './services/${t}.service';`:""}
477
- `};var li=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 Mn=e=>{let{componentName:t,camelName:r,typesImportPath:i}=e,n=`${r.toUpperCase()}_PERSIST_VERSION`;return`import { createMigrate, type PersistConfig, type PersistedState } from 'redux-persist';
478
478
  import storage from '@/store/storage';
479
- import type { ${t}State } from '${n}';
479
+ import type { ${t}State } from '${i}';
480
480
 
481
- const ${i} = 1;
481
+ const ${n} = 1;
482
482
 
483
483
  const migrations = {
484
- // Bump ${i} and add a migration here when ${t}State's
484
+ // Bump ${n} and add a migration here when ${t}State's
485
485
  // shape changes. Receives the previously-persisted state, returns the new
486
486
  // shape. Returning \`undefined\` discards stale state.
487
487
  // 2: (state) => ({ ...state, newField: defaultValue }),
@@ -490,16 +490,16 @@ const migrations = {
490
490
  export const ${r}PersistConfig: PersistConfig<${t}State> = {
491
491
  key: '${r}',
492
492
  storage,
493
- version: ${i},
493
+ version: ${n},
494
494
  // whitelist: ['someField'], // Specify which fields to persist
495
495
  migrate: createMigrate(migrations, { debug: false }),
496
496
  };
497
- `};var mi=e=>{let{componentName:t,camelName:r,sliceName:n}=e;return`import { RootState } from '@/store/rootReducer';
497
+ `};var Hn=e=>{let{componentName:t,camelName:r,sliceName:i}=e;return`import { RootState } from '@/store/rootReducer';
498
498
 
499
499
  export const select${t}State = (state: RootState) => state.${r};
500
- export { setLoading, setError, resetState } from './${n}.slice';
501
- `};var di=e=>{let{componentName:t,camelName:r,typesImportPath:n}=e;return`import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
502
- import type { ${t}State } from '${n}';
500
+ export { setLoading, setError, resetState } from './${i}.slice';
501
+ `};var Gn=e=>{let{componentName:t,camelName:r,typesImportPath:i}=e;return`import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
502
+ import type { ${t}State } from '${i}';
503
503
 
504
504
  const initialState: ${t}State = {
505
505
  loading: false,
@@ -527,13 +527,13 @@ export const ${r}Slice = createSlice({
527
527
  export const { setLoading, setError, resetState } = ${r}Slice.actions;
528
528
 
529
529
  export const ${r}Reducer = ${r}Slice.reducer;
530
- `};var vt=e=>{let{componentName:t,withStore:r}=e;return`export interface ${t}State {
530
+ `};var Ut=e=>{let{componentName:t,withStore:r}=e;return`export interface ${t}State {
531
531
  ${r?`loading: boolean;
532
532
  error: string | null;
533
533
  // Add your state properties here`:`// Add your state properties here
534
534
  // example: value: string;`}
535
535
  }
536
- `};var et=async e=>{let{name:t,outputPath:r,persist:n,typesImportPath:i=`./${t}.types`}=e;await Tc(r,{recursive:!0});let o=$(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`),di({componentName:o,camelName:s,typesImportPath:i})),Ze(Qe.join(r,`${t}.selectors.ts`),mi({componentName:o,camelName:s,sliceName:t})),...n?[Ze(Qe.join(r,"persist.ts"),li({componentName:o,camelName:s,typesImportPath:i}))]:[],Ze(Qe.join(r,"index.ts"),ci({sliceName:t,withPersist:n}))])};var ui=e=>{let{componentName:t,hookName:r}=e;return`'use client';
536
+ `};var lt=async e=>{let{name:t,outputPath:r,persist:i,typesImportPath:n=`./${t}.types`}=e;await pp(r,{recursive:!0});let o=N(t),s=H(t);await Promise.all([ct(pt.join(r,`${t}.types.ts`),Ut({componentName:o,withStore:!0})),ct(pt.join(r,`${t}.slice.ts`),Gn({componentName:o,camelName:s,typesImportPath:n})),ct(pt.join(r,`${t}.selectors.ts`),Hn({componentName:o,camelName:s,sliceName:t})),...i?[ct(pt.join(r,"persist.ts"),Mn({componentName:o,camelName:s,typesImportPath:n}))]:[],ct(pt.join(r,"index.ts"),Dn({sliceName:t,withPersist:i}))])};var Un=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,9 +548,9 @@ export function ${t}() {
548
548
  }
549
549
 
550
550
  export default ${t};
551
- `};var fi=e=>{let{hookName:t,componentName:r,featureName:n}=e;return`'use client';
551
+ `};var Bn=e=>{let{hookName:t,componentName:r,featureName:i}=e;return`'use client';
552
552
  import { useAppDispatch, useAppSelector } from '@/store/hooks';
553
- import { select${r}State, setLoading, setError } from '../store/${n}.selectors';
553
+ import { select${r}State, setLoading, setError } from '../store/${i}.selectors';
554
554
 
555
555
  export const ${t} = () => {
556
556
  const dispatch = useAppDispatch();
@@ -570,7 +570,7 @@ export const ${t} = () => {
570
570
  setError: handleSetError,
571
571
  } as const;
572
572
  };
573
- `},gi=e=>{let{hookName:t}=e;return`'use client';
573
+ `},zn=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=$(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=>bc(d,{recursive:!0}))),await Promise.all([St(K.join(r,"components",`${a}.tsx`),ui({componentName:a,hookName:p})),St(K.join(r,"hooks",`${p}.ts`),n?fi({hookName:p,componentName:a,featureName:t}):gi({hookName:p})),St(K.join(r,"types",`${t}.types.ts`),vt({componentName:a,withStore:n})),St(K.join(r,"index.ts"),pi({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 Rc,writeFile as $c}from"node:fs/promises";import ur from"node:path";var hi=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${$(t)}`,a;i?a=ur.join(r,i,"hooks"):a=ur.join(r,"src","hooks"),await Rc(a,{recursive:!0}),await $c(ur.join(a,`${s}.ts`),hi({hookName:s,isClient:n}))};import{mkdir as kc}from"node:fs/promises";import Et from"node:path";P();var Ic=e=>`import { setRequestLocale } from 'next-intl/server';
585
+ `};var Jr=async e=>{let{name:t,outputPath:r,createStore:i,persistStore:n,createService:o,httpClient:s}=e,c=N(t),p=`use${c}`,u=[re.join(r,"components"),re.join(r,"hooks"),re.join(r,"types"),...i?[re.join(r,"store")]:[],...o?[re.join(r,"services")]:[]];await Promise.all(u.map(d=>lp(d,{recursive:!0}))),await Promise.all([Bt(re.join(r,"components",`${c}.tsx`),Un({componentName:c,hookName:p})),Bt(re.join(r,"hooks",`${p}.ts`),i?Bn({hookName:p,componentName:c,featureName:t}):zn({hookName:p})),Bt(re.join(r,"types",`${t}.types.ts`),Ut({componentName:c,withStore:i})),Bt(re.join(r,"index.ts"),Ln({featureName:t,componentName:c,hookName:p,withStore:i,withService:o}))]),i&&await lt({name:t,outputPath:re.join(r,"store"),persist:n,typesImportPath:`../types/${t}.types`}),o&&s&&await at({name:t,outputPath:re.join(r,"services"),httpClient:s})};import{mkdir as mp,writeFile as dp}from"node:fs/promises";import Wr from"node:path";var Vn=e=>{let{hookName:t,isClient:r}=e,i=[];return r&&i.push("'use client';"),i.push("import { useState, useCallback } from 'react';"),i.push(""),i.push(`export const ${t} = () => {`),i.push(" const [loading, setLoading] = useState(false);"),i.push(" const [error, setError] = useState<string | null>(null);"),i.push(""),i.push(" const execute = useCallback(async () => {"),i.push(" setLoading(true);"),i.push(" setError(null);"),i.push(" try {"),i.push(" // Add your logic here"),i.push(" } catch (err) {"),i.push(" setError(err instanceof Error ? err.message : 'An error occurred');"),i.push(" } finally {"),i.push(" setLoading(false);"),i.push(" }"),i.push(" }, []);"),i.push(""),i.push(" return {"),i.push(" loading,"),i.push(" error,"),i.push(" execute,"),i.push(" } as const;"),i.push("};"),i.push(""),i.join(`
586
+ `)};var qr=async e=>{let{name:t,projectPath:r,isClient:i,featurePath:n}=e,s=`use${N(t)}`,c;n?c=Wr.join(r,n,"hooks"):c=Wr.join(r,"src","hooks"),await mp(c,{recursive:!0}),await dp(Wr.join(c,`${s}.ts`),Vn({hookName:s,isClient:i}))};import{mkdir as gp}from"node:fs/promises";import zt from"node:path";w();var up=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
- `,Nc=e=>`type Props = {
600
+ `,fp=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
- `,yi=({componentName:e,hasI18n:t})=>t?Ic(e):Nc(e);var Ac=/^[a-z][a-z0-9-]*$/,_c=/^[a-z][a-z0-9-]*(\/[a-z][a-z0-9-]*)*$/,Oc=e=>{if(!Ac.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.`)},Fc=e=>{if(!_c.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;Oc(t),r&&Fc(r);let s=`${$(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 kc(u,{recursive:!0}),await g(d,yi({componentName:s,hasI18n:i})),{layoutFile:d,displayPath:Et.relative(n,d),componentName:s}};P();import{copyFile as jc,readFile as Dc,writeFile as Lc}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 Mc(o,t,s),await Gc(o,t),await Uc(o,t,r,n,i)},Mc=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 jc(i,o);else{let s=await Dc(i,"utf-8"),a=JSON.parse(s),p=xi(a);await Lc(o,`${JSON.stringify(p,null,2)}
608
- `)}},xi=e=>{let t={};for(let[r,n]of Object.entries(e))typeof n=="object"&&n!==null?t[r]=xi(n):t[r]="";return t},Gc=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)}},Uc=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
+ `,Jn=({componentName:e,hasI18n:t})=>t?up(e):fp(e);var hp=/^[a-z][a-z0-9-]*$/,yp=/^[a-z][a-z0-9-]*(\/[a-z][a-z0-9-]*)*$/,xp=e=>{if(!hp.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.`)},wp=e=>{if(!yp.test(e))throw new Error(`Invalid --at path "${e}". Use kebab-case segments separated by "/", e.g. "dashboard/settings".`)},Xr=async e=>{let{segment:t,at:r,projectPath:i,hasI18n:n,withGroup:o}=e;xp(t),r&&wp(r);let s=`${N(t)}Layout`,c=o?`(${t})`:t,p=["src","app"];n&&p.push("[locale]"),r&&p.push(...r.split("/")),p.push(c);let u=zt.join(i,...p),d=zt.join(u,"layout.tsx");if(l(d))throw new Error(`Layout already exists at ${zt.relative(i,d)}.`);return await gp(u,{recursive:!0}),await h(d,Jn({componentName:s,hasI18n:n})),{layoutFile:d,displayPath:zt.relative(i,d),componentName:s}};w();import{copyFile as Pp,readFile as vp,writeFile as Sp}from"node:fs/promises";import mt from"node:path";var Yr=async e=>{let{code:t,name:r,country:i,flag:n,projectPath:o,copyTranslations:s}=e;await Ep(o,t,s),await Tp(o,t),await Cp(o,t,r,i,n)},Ep=async(e,t,r)=>{let i=mt.join(e,"src","i18n","translations"),n=mt.join(i,"en.json"),o=mt.join(i,`${t}.json`);if(r)await Pp(n,o);else{let s=await vp(n,"utf-8"),c=JSON.parse(s),p=Wn(c);await Sp(o,`${JSON.stringify(p,null,2)}
608
+ `)}},Wn=e=>{let t={};for(let[r,i]of Object.entries(e))typeof i=="object"&&i!==null?t[r]=Wn(i):t[r]="";return t},Tp=async(e,t)=>{let r=mt.join(e,"src","types","i18n.ts");if(!l(r))return;let i=await g(r),n=/export type SupportedLocale = (.*);/,o=i.match(n);if(o&&!o[1].includes(`'${t}'`)){let s=`${o[1]} | '${t}'`;i=i.replace(n,`export type SupportedLocale = ${s};`),await h(r,i)}},Cp=async(e,t,r,i,n)=>{let o=mt.join(e,"src","lib","config","app-locales.ts");if(!l(o))return;let s=await g(o);if(s.includes(`locale: '${t}'`))return;let c=s.lastIndexOf("];");if(c===-1)return;let p=` {
609
609
  name: '${r}',
610
610
  locale: '${t}',
611
- flag: '${i}',
612
- country: '${n}',
611
+ flag: '${n}',
612
+ country: '${i}',
613
613
  },
614
- `;s=s.slice(0,a)+p+s.slice(a),await g(o,s)};import{mkdir as Hc,writeFile as yr}from"node:fs/promises";import rt from"node:path";var Pi=e=>{let{componentName:t,routePath:r,hasI18n:n}=e;return n?`import { generateSEOMetadata } from '@/lib/config/seo';
614
+ `;s=s.slice(0,c)+p+s.slice(c),await h(o,s)};import{mkdir as Rp,writeFile as Kr}from"node:fs/promises";import dt from"node:path";var qn=e=>{let{componentName:t,routePath:r,hasI18n:i}=e;return i?`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
- `},wi=e=>{let{componentName:t,paramName:r,routePath:n,hasI18n:i}=e;return i?`import { generateSEOMetadata } from '@/lib/config/seo';
660
+ `},Xn=e=>{let{componentName:t,paramName:r,routePath:i,hasI18n:n}=e;return n?`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';
@@ -673,7 +673,7 @@ export async function generateMetadata(props: Props): Promise<Metadata> {
673
673
  return generateSEOMetadata({
674
674
  title: t('title'),
675
675
  description: t('description'),
676
- path: '${n}',
676
+ path: '${i}',
677
677
  });
678
678
  }
679
679
 
@@ -711,14 +711,14 @@ export default async function ${t}Page(props: Props) {
711
711
  </div>
712
712
  );
713
713
  }
714
- `},vi=e=>`export default function ${e.componentName}Loading() {
714
+ `},Yn=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
- `,Si=e=>`'use client';
721
+ `,Kn=e=>`'use client';
722
722
 
723
723
  export default function ${e.componentName}Error({
724
724
  error,
@@ -735,17 +735,17 @@ 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=$(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 Hc(d,{recursive:!0});let h=i?wi({componentName:a,routePath:i?`${p}/[${i}]`:p,paramName:i,hasI18n:n}):Pi({componentName:a,routePath:p,hasI18n:n});await yr(rt.join(d,"page.tsx"),h),o&&await yr(rt.join(d,"loading.tsx"),vi({componentName:a})),s&&await yr(rt.join(d,"error.tsx"),Si({componentName:a}))};S();import{mkdir as Bc}from"node:fs/promises";import Pr from"node:path";P();var Ei=(e,t)=>e.endsWith(t)?e:`${e}${t}`,Ci=({baseName:e})=>{let t=Ei(e,"Provider"),r=t.replace(/Provider$/,""),n=`${r}ContextValue`,i=`${r}Context`,o=`use${r}`;return`'use client';
738
+ `;var Zr=async e=>{let{name:t,projectPath:r,hasI18n:i,dynamic:n,withLoading:o=!1,withError:s=!1}=e,c=N(t),p=`/${t}`,u=i?"src/app/[locale]":"src/app",d;n?d=dt.join(r,u,t,`[${n}]`):d=dt.join(r,u,t),await Rp(d,{recursive:!0});let f=n?Xn({componentName:c,routePath:n?`${p}/[${n}]`:p,paramName:n,hasI18n:i}):qn({componentName:c,routePath:p,hasI18n:i});await Kr(dt.join(d,"page.tsx"),f),o&&await Kr(dt.join(d,"loading.tsx"),Yn({componentName:c})),s&&await Kr(dt.join(d,"error.tsx"),Kn({componentName:c}))};P();import{mkdir as bp}from"node:fs/promises";import Qr from"node:path";w();var Zn=(e,t)=>e.endsWith(t)?e:`${e}${t}`,Qn=({baseName:e})=>{let t=Zn(e,"Provider"),r=t.replace(/Provider$/,""),i=`${r}ContextValue`,n=`${r}Context`,o=`use${r}`;return`'use client';
739
739
  import { createContext, useContext, useMemo } from 'react';
740
740
 
741
- type ${n} = {
741
+ type ${i} = {
742
742
  // TODO: declare context value fields
743
743
  };
744
744
 
745
- const ${i} = createContext<${n} | null>(null);
745
+ const ${n} = createContext<${i} | null>(null);
746
746
 
747
- export const ${o} = (): ${n} => {
748
- const ctx = useContext(${i});
747
+ export const ${o} = (): ${i} => {
748
+ const ctx = useContext(${n});
749
749
  if (!ctx) {
750
750
  throw new Error('${o} must be used within ${t}');
751
751
  }
@@ -753,26 +753,26 @@ export const ${o} = (): ${n} => {
753
753
  };
754
754
 
755
755
  export const ${t} = ({ children }: { children: React.ReactNode }) => {
756
- const value = useMemo<${n}>(() => ({}), []);
757
- return <${i}.Provider value={value}>{children}</${i}.Provider>;
756
+ const value = useMemo<${i}>(() => ({}), []);
757
+ return <${n}.Provider value={value}>{children}</${n}.Provider>;
758
758
  };
759
- `},Ti=e=>Ei(e,"Provider");var zc=/^[A-Za-z][A-Za-z0-9-]*$/,Vc=e=>e.includes("-")?$(e):e.charAt(0).toUpperCase()+e.slice(1),wr=async e=>{let{name:t,projectPath:r}=e;if(!zc.test(t))throw new Error(`Invalid provider name "${t}". Use kebab-case or PascalCase letters and digits only.`);let n=Vc(t).replace(/Provider$/,""),i=Ti(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 Bc(s,{recursive:!0}),await g(a,Ci({baseName:n})),{componentName:i,fileBaseName:o,providerFile:a}};P();import nt from"node:path";var bi=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
+ `},eo=e=>Zn(e,"Provider");var Ip=/^[A-Za-z][A-Za-z0-9-]*$/,$p=e=>e.includes("-")?N(e):e.charAt(0).toUpperCase()+e.slice(1),ei=async e=>{let{name:t,projectPath:r}=e;if(!Ip.test(t))throw new Error(`Invalid provider name "${t}". Use kebab-case or PascalCase letters and digits only.`);let i=$p(t).replace(/Provider$/,""),n=eo(i),o=n,s=Qr.join(r,a.PROVIDERS),c=Qr.join(s,`${o}.tsx`);if(l(c))throw new Error(`Provider already exists at ${Qr.relative(r,c)}.`);return await bp(s,{recursive:!0}),await h(c,Qn({baseName:i})),{componentName:n,fileBaseName:o,providerFile:c}};w();import ut from"node:path";var to=e=>{let{componentName:t,sourceImportPath:r,testUtilsImportPath:i,hasRedux:n,hasI18n:o}=e,s=[];o&&s.push("messages: {}"),n&&s.push("preloadedState: {}");let c=s.length?`, {
760
760
  ${s.join(`,
761
761
  `)},
762
762
  }`:"";return`import { describe, expect, it } from 'vitest';
763
- import { renderWithProviders, screen } from '${n}';
763
+ import { renderWithProviders, screen } from '${i}';
764
764
  import { ${t} } from '${r}';
765
765
 
766
766
  describe('${t}', () => {
767
767
  it('renders without crashing', () => {
768
- renderWithProviders(<${t} />${a});
768
+ renderWithProviders(<${t} />${c});
769
769
  // TODO: assert something meaningful about the rendered output.
770
770
  expect(screen).toBeDefined();
771
771
  });
772
772
  });
773
- `},Ri=e=>{let{hookName:t,sourceImportPath:r,withStore:n,testUtilsImportPath:i}=e;return n?`import { renderHook } from '@testing-library/react';
773
+ `},ro=e=>{let{hookName:t,sourceImportPath:r,withStore:i,testUtilsImportPath:n}=e;return i?`import { renderHook } from '@testing-library/react';
774
774
  import { describe, expect, it } from 'vitest';
775
- import { TestProviders } from '${i}';
775
+ import { TestProviders } from '${n}';
776
776
  import { ${t} } from '${r}';
777
777
 
778
778
  describe('${t}', () => {
@@ -791,109 +791,109 @@ describe('${t}', () => {
791
791
  expect(result.current).toBeDefined();
792
792
  });
793
793
  });
794
- `},$i=e=>{let{camelName:t,sourceImportPath:r}=e,n=`${t}Slice`;return`import { describe, expect, it } from 'vitest';
795
- import { ${n}, resetState, setError, setLoading } from '${r}';
794
+ `},io=e=>{let{camelName:t,sourceImportPath:r}=e,i=`${t}Slice`;return`import { describe, expect, it } from 'vitest';
795
+ import { ${i}, resetState, setError, setLoading } from '${r}';
796
796
 
797
- describe('${n}', () => {
797
+ describe('${i}', () => {
798
798
  const initialState = { loading: false, error: null } as const;
799
799
 
800
800
  it('returns the initial state', () => {
801
- expect(${n}.reducer(undefined, { type: '@@INIT' })).toEqual(initialState);
801
+ expect(${i}.reducer(undefined, { type: '@@INIT' })).toEqual(initialState);
802
802
  });
803
803
 
804
804
  it('handles setLoading', () => {
805
- const next = ${n}.reducer(initialState, setLoading(true));
805
+ const next = ${i}.reducer(initialState, setLoading(true));
806
806
  expect(next.loading).toBe(true);
807
807
  });
808
808
 
809
809
  it('handles setError', () => {
810
- const next = ${n}.reducer(initialState, setError('boom'));
810
+ const next = ${i}.reducer(initialState, setError('boom'));
811
811
  expect(next.error).toBe('boom');
812
812
  });
813
813
 
814
814
  it('handles resetState', () => {
815
- const next = ${n}.reducer({ loading: true, error: 'boom' }, resetState());
815
+ const next = ${i}.reducer({ loading: true, error: 'boom' }, resetState());
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=Jc(o,nt.join(t,"test","test-utils")),h;return n==="component"?h=bi({componentName:i,sourceImportPath:u,testUtilsImportPath:d,hasRedux:!!e.hasRedux,hasI18n:!!e.hasI18n}):n==="hook"?h=Ri({hookName:i,sourceImportPath:u,withStore:!!e.hookUsesStore,testUtilsImportPath:e.hookUsesStore?d:void 0}):h=$i({camelName:i,sourceImportPath:u}),await g(p,h),p},Jc=(e,t)=>{let r=nt.relative(e,t).replace(/\\/g,"/");return r.startsWith(".")?r:`./${r}`};import Wc from"enquirer";var{prompt:qc}=Wc,Ii=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 qc(r):{};return{componentName:e??n.componentName,isClient:t.client??n.isClient??!1}};var Ni=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 fe=async e=>{let{projectPath:t,sourceFile:r,kind:i,symbolName:n}=e,o=ut.dirname(r),s=ut.basename(r).replace(/\.(tsx?|jsx?)$/i,""),c=i==="component"?".tsx":".ts",p=ut.join(o,`${s}.test${c}`),u=`./${s}`,d=kp(o,ut.join(t,"test","test-utils")),f;return i==="component"?f=to({componentName:n,sourceImportPath:u,testUtilsImportPath:d,hasRedux:!!e.hasRedux,hasI18n:!!e.hasI18n}):i==="hook"?f=ro({hookName:n,sourceImportPath:u,withStore:!!e.hookUsesStore,testUtilsImportPath:e.hookUsesStore?d:void 0}):f=io({camelName:n,sourceImportPath:u}),await h(p,f),p},kp=(e,t)=>{let r=ut.relative(e,t).replace(/\\/g,"/");return r.startsWith(".")?r:`./${r}`};import Np from"enquirer";var{prompt:Ap}=Np,no=async(e,t={})=>{let r=[];e||r.push({type:"input",name:"componentName",message:"Component name (kebab-case):",validate:n=>n?/^[a-z][a-z0-9-]*$/.test(n)?!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 i=r.length>0?await Ap(r):{};return{componentName:e??i.componentName,isClient:t.client??i.isClient??!1}};var oo=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 i=process.cwd();m(pe.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 Ii(t,{client:r.client});H(o.componentName,"component name"),r.feature&&re(r.feature,"feature path");let s=$(o.componentName),a=o.isClient,p=r.i18n??!1,u=Xc(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 x=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: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(`
821
+ `)),x.start("Detecting project setup...");let n=await M(i);x.succeed("Project setup detected");let o=await no(t,{client:r.client});J(o.componentName,"component name"),r.feature&&ce(r.feature,"feature path");let s=N(o.componentName),c=o.isClient,p=r.i18n??!1,u=Fp(r,n.hasTests);x.start("Generating component..."),await zr({name:o.componentName,projectPath:i,isClient:c||p,hasI18n:p,featurePath:r.feature}),x.succeed("Component generated");let d=null;if(u){let y=r.feature?ti.join(i,r.feature,"components",`${s}.tsx`):ti.join(i,"src/components/common",s,`${s}.tsx`);x.start("Generating test..."),d=await fe({projectPath:i,sourceFile:y,kind:"component",symbolName:s,hasRedux:n.hasRedux,hasI18n:n.hasI18n}),x.succeed("Test generated")}let f=r.feature?`${r.feature}/components/${s}.tsx`:`src/components/common/${s}/${s}.tsx`;m(pe.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)}})},Xc=(e,t)=>e.test===!1?!1:e.test===!0?!0:t;import L from"picocolors";S();P();import Kc from"node:path";S();import ki from"node:path";import Yc from"picocolors";P();var Ct=async e=>{let t=b("Adding @next/bundle-analyzer...");try{let r=ki.join(e,c.NEXT_CONFIG);if(!m(r))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await f(r);if(n.includes("@next/bundle-analyzer")){t.fail("@next/bundle-analyzer is already configured.");return}n=`import withBundleAnalyzer from '@next/bundle-analyzer';
824
- ${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({
823
+ `)),m(pe.dim(` \u{1F4C4} ${f}`)),r.feature||(m(pe.dim(` \u{1F4C4} src/components/common/${s}/index.ts`)),m(pe.dim(" \u{1F4DD} Updated src/components/common/index.ts")),m(pe.dim(" \u{1F4DD} Updated src/components/index.ts"))),d&&m(pe.dim(` \u{1F9EA} ${ti.relative(i,d)}`)),m(""),m(pe.cyan("Usage:")),r.feature?m(pe.dim(` import { ${s} } from '${r.feature.replace(/^src\//,"@/")}/components/${s}';`)):m(pe.dim(` import { ${s} } from '@/components';`)),m("")}catch(i){x.fail("Component generation failed"),E(`${i}`),process.exit(1)}})},Fp=(e,t)=>e.test===!1?!1:e.test===!0?!0:t;import $ from"picocolors";P();w();import Hp from"node:path";P();import ao from"node:path";import _p from"picocolors";w();var so=/export default (.*?);/,ri="ANALYZE=true next build",Vt=e=>e.includes("@next/bundle-analyzer"),ft=e=>{if(Vt(e))return e;let t=`import withBundleAnalyzer from '@next/bundle-analyzer';
824
+ ${e}`,r=t.match(so);if(!r)throw new Error("Could not locate `export default` in next.config.ts.");let n=`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(ki.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(Yc.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(`
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 x=r[h].match(n);if(x){i=h,o=x[1];break}}if(i===-1||!/>\s*$/.test(r[i]))return null;let s=o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=new RegExp(`^${s}<\\/${e}>\\s*$`),p=-1;for(let h=i+1;h<r.length;h++)if(a.test(r[h])){p=h;break}if(p===-1)return null;let u=r.slice(i+1,p).map(h=>h.startsWith(" ")?h.slice(2):h),d=[...r.slice(0,i),...u,...r.slice(p+1)].join(`
832
- `);return Sr(d,e)};var Ai=e=>{let t=e.split(`
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},_i=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 Oi={id:"bundle-analyzer",name:"Bundle Analyzer",description:"@next/bundle-analyzer wrapped around the default export",detect:async e=>{let t=Kc.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:_i}],apply:Ct};S();P();import ep from"node:path";S();import Fi from"node:path";import Zc from"picocolors";P();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 Qc=`${JSON.stringify({path:"cz-conventional-changelog"},null,2)}
835
- `,Tt=async e=>{let t=b("Setting up Commitizen...");try{let r=Fi.join(e,c.CZRC);m(r)||await g(r,Qc);let n=Fi.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 k(e);await Pe(e,s,o)}t.succeed(Zc.green("Commitizen configured. Use `commit` to start a guided commit."))}catch(r){throw t.fail("Failed to set up Commitizen."),r}};var ji={id:"commitizen",name:"Commitizen",description:"Guided conventional-commit prompt via `commit` script",detect:async e=>m(ep.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 ip from"node:path";import rp from"node:path";import np from"picocolors";P();S();P();import Di from"node:path";import tp from"degit";var Li=async(e,t)=>{t.text="Fetching assets from starter repo...",await tp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Mi=async(e,t)=>{let r=Di.join(e,c.THEME_PROVIDER),n=Di.join(t,"src/providers/CustomThemeProvider.tsx");await N(n,r)};S();P();import it from"node:path";S();P();import Gi from"node:path";var bt=async e=>{let t=[Gi.join(e,c.ROOT_LAYOUT),Gi.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();P();import Rt from"node:path";var Bi=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))},zi=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';
837
- ${r}`),i&&(r=`${n}
828
+ export default bundleAnalyzer(${r[1]});`;return t.replace(so,n)};var Jt=async e=>{let t=S("Adding @next/bundle-analyzer...");try{let r=ao.join(e,a.NEXT_CONFIG);if(!l(r))throw new Error(`${a.NEXT_CONFIG} not found.`);let i=await g(r);if(Vt(i)){t.fail("@next/bundle-analyzer is already configured.");return}await h(r,ft(i)),await F(ao.join(e,a.PACKAGE_JSON),n=>(n.scripts=n.scripts??{},n.scripts.analyze||(n.scripts.analyze=ri),n)),t.text="Installing @next/bundle-analyzer...",await kt(e,"@next/bundle-analyzer"),t.succeed(_p.green("@next/bundle-analyzer configured."))}catch(r){throw t.fail("Failed to add @next/bundle-analyzer."),r}};P();import Lp from"node:path";import Mp from"picocolors";w();P();w();import Op from"node:path";import jp from"degit";var Wt=(e,t)=>e.filter(r=>r.kind==="missingPackage"&&r.depKind===t).map(r=>r.name),Dp=e=>e.filter(t=>t.kind==="missingFile").map(t=>t.file),_=(e,t)=>Dp(e).some(r=>r===t||r.startsWith(`${t}/`));var U=(e,t)=>e.some(r=>r.kind==="missingInjection"&&(t===void 0||r.file===t)),B=async(e,t)=>{let r=Wt(t,"dependency"),i=Wt(t,"devDependency");if(r.length===0&&i.length===0)return[];let n=await A(e);return r.length>0&&await br(e,n,r),i.length>0&&await ue(e,n,i),[...r,...i]},Se=async(e,t)=>{let r=new Map;for(let n of t)(n.kind==="missingScript"&&n.expected||n.kind==="mismatchedScript")&&r.set(n.name,n.expected);if(r.size===0)return[];let i=Op.join(e,a.PACKAGE_JSON);return l(i)?(await F(i,n=>{let o={...n.scripts??{}};for(let[s,c]of r)o[s]=c;return{...n,scripts:o}}),[...r.keys()]):[]},ee=async(e,t)=>{await jp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e);try{return await t(e)}finally{await v(e)}};var co=async(e,t)=>{let r=S("Repairing Bundle Analyzer...");try{if(U(t,a.NEXT_CONFIG)){let s=Lp.join(e,a.NEXT_CONFIG);if(l(s)){let c=await g(s),p=ft(c);p!==c&&await h(s,p)}}let i=await B(e,t),n=await Se(e,t),o=[i.length>0?`reinstalled ${i.join(", ")}`:null,n.length>0?`restored ${n.join(", ")}`:null].filter(Boolean);r.succeed(Mp.green(o.length>0?`Bundle Analyzer repaired (${o.join("; ")}).`:"Bundle Analyzer repaired."))}catch(i){throw r.fail("Failed to repair Bundle Analyzer."),i}};var O=(e,t)=>async(r,i)=>{if(i&&i.length>0){await t(r,i);return}await e(r)};var ii=(e,t)=>{let r=e.split(`
829
+ `),i=[],n=new RegExp(`^import\\s+${t}\\s+from\\s+['"][^'"]+['"];?\\s*$`),o=/^(import\s+)\{([^}]+)\}(\s+from\s+['"][^'"]+['"];?\s*)$/;for(let s of r){if(n.test(s))continue;let c=s.match(o);if(c){let p=c[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){i.push(`${c[1]}{ ${u.join(", ")} }${c[3]}`);continue}}i.push(s)}return i.join(`
830
+ `)},Be=e=>t=>{let r=t.split(`
831
+ `),i=new RegExp(`^([ \\t]*)<${e}\\b`),n=-1,o="";for(let f=0;f<r.length;f++){let y=r[f].match(i);if(y){n=f,o=y[1];break}}if(n===-1||!/>\s*$/.test(r[n]))return null;let s=o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),c=new RegExp(`^${s}<\\/${e}>\\s*$`),p=-1;for(let f=n+1;f<r.length;f++)if(c.test(r[f])){p=f;break}if(p===-1)return null;let u=r.slice(n+1,p).map(f=>f.startsWith(" ")?f.slice(2):f),d=[...r.slice(0,n),...u,...r.slice(p+1)].join(`
832
+ `);return ii(d,e)};var po=e=>{let t=e.split(`
833
+ `).filter(i=>!/^import\s+createNextIntlPlugin\s+from\s+['"]next-intl\/plugin['"];?\s*$/.test(i)).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},lo=e=>{let t=ii(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 i=/bundleAnalyzer\(\s*((?:[^()]|\([^()]*\))+?)\s*\)/;return i.test(t)?(t=t.replace(i,"$1"),t):null};var mo={id:"bundle-analyzer",name:"Bundle Analyzer",description:"@next/bundle-analyzer wrapped around the default export",detect:async e=>{let t=Hp.join(e,a.NEXT_CONFIG);return l(t)?/@next\/bundle-analyzer/.test(await g(t)):!1},files:[],packages:[{name:"@next/bundle-analyzer",kind:"devDependency"}],scripts:[{name:"analyze",expectedValue:"ANALYZE=true next build"}],injections:[{file:a.NEXT_CONFIG,description:"withBundleAnalyzer import + wrapping",presence:/@next\/bundle-analyzer/,removePattern:lo}],apply:O(Jt,co)};P();w();import zp from"node:path";P();import uo from"node:path";import Gp from"picocolors";w();var gt=`${JSON.stringify({path:"cz-conventional-changelog"},null,2)}
835
+ `;var ni=e=>{let t={...e.scripts??{}},r={...e.devDependencies??{}};return t.commit||(t.commit="cz"),r[R.COMMITIZEN]||(r[R.COMMITIZEN]="*"),r[R.CZ_CONVENTIONAL_CHANGELOG]||(r[R.CZ_CONVENTIONAL_CHANGELOG]="*"),{...e,scripts:t,devDependencies:r}},oi=e=>{let t=e.devDependencies??{},r=[];return t[R.COMMITIZEN]||r.push(R.COMMITIZEN),t[R.CZ_CONVENTIONAL_CHANGELOG]||r.push(R.CZ_CONVENTIONAL_CHANGELOG),r};var qt=async e=>{let t=S("Setting up Commitizen...");try{let r=uo.join(e,a.CZRC);l(r)||await h(r,gt);let i=uo.join(e,a.PACKAGE_JSON),n=JSON.parse(await g(i)),o=oi(n);if(await F(i,s=>ni(s)),o.length>0){t.text=`Installing ${o.join(", ")}...`;let s=await A(e);await ue(e,s,o)}t.succeed(Gp.green("Commitizen configured. Use `commit` to start a guided commit."))}catch(r){throw t.fail("Failed to set up Commitizen."),r}};P();import Up from"node:path";import Bp from"picocolors";w();var fo=async(e,t)=>{let r=S("Repairing Commitizen...");try{let i=!1;if(_(t,a.CZRC)){let c=Up.join(e,a.CZRC);l(c)||(await h(c,gt),i=!0)}let n=await B(e,t),o=await Se(e,t),s=[i?`rewrote ${a.CZRC}`:null,n.length>0?`reinstalled ${n.join(", ")}`:null,o.length>0?`restored ${o.join(", ")}`:null].filter(Boolean);r.succeed(Bp.green(s.length>0?`Commitizen repaired (${s.join("; ")}).`:"Commitizen repaired."))}catch(i){throw r.fail("Failed to repair Commitizen."),i}};var go={id:"commitizen",name:"Commitizen",description:"Guided conventional-commit prompt via `commit` script",detect:async e=>l(zp.join(e,a.CZRC)),files:[{path:a.CZRC,generated:!0}],packages:[{name:"commitizen",kind:"devDependency"},{name:"cz-conventional-changelog",kind:"devDependency"}],scripts:[{name:"commit",expectedValue:"cz"}],injections:[],apply:O(qt,fo)};P();w();import Yp from"node:path";import Jp from"node:path";import Wp from"picocolors";w();P();w();import ho from"node:path";import Vp from"degit";var yo=async(e,t)=>{t.text="Fetching assets from starter repo...",await Vp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},xo=async(e,t)=>{let r=ho.join(e,a.THEME_PROVIDER),i=ho.join(t,"src/providers/CustomThemeProvider.tsx");await b(i,r)};P();w();import ht from"node:path";P();w();import wo from"node:path";var Xt=async e=>{let t=[wo.join(e,a.ROOT_LAYOUT),wo.join(e,"src/app/[locale]/layout.tsx")];for(let r of t)if(l(r)&&(await g(r)).includes("<body"))return r;for(let r of t)if(l(r))return r;return""};var Po=async e=>{let t=ht.join(e,a.THEME_PROVIDER),r=ht.join(e,a.GLOBALS_CSS),i=ht.join(e,"package.json");if(l(t))return{isSetup:!0,reason:"CustomThemeProvider.tsx exists"};if(l(i)){let n=JSON.parse(await g(i)),o="@teispace/next-themes";if(n.dependencies?.[o]||n.devDependencies?.[o])return{isSetup:!0,reason:`${o} is installed`}}return l(r)&&(await g(r)).includes("@custom-variant dark")?{isSetup:!0,reason:"Dark theme CSS found in globals.css"}:{isSetup:!1,reason:""}},vo=async e=>{let t=ht.join(e,a.GLOBALS_CSS),r=ht.join(e,a.PROVIDERS_INDEX),i=await Xt(e);if(!l(t)||!i||!l(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 i};P();w();import Yt from"node:path";var Kt=async e=>{let t=Yt.join(e,a.PROVIDERS_INDEX),r=await g(t);r.includes("CustomThemeProvider")||(r+=`export * from './CustomThemeProvider';
836
+ `,await h(t,r))},Zt=async e=>{let t=Yt.join(e,"src/providers/RootProvider.tsx");if(!l(t))return;let r=await g(t),i="'use client';",n=r.includes(i);if(n&&(r=r.replace(i,"").trim()),r.includes("CustomThemeProvider")||(/import\s*\{[^}]*\}\s*from\s*'@\/providers'/.test(r)?r=r.replace(/(import\s*\{)([^}]*)(\}\s*from\s*'@\/providers')/,(o,s,c,p)=>`${s}${c.trim()?`${c.trim()}, CustomThemeProvider `:" CustomThemeProvider "}${p}`):r=`import { CustomThemeProvider } from '@/providers';
837
+ ${r}`),n&&(r=`${i}
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)},Vi=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+=`
843
- ${a[0]}
844
- `),p&&(i+=`
842
+ );`))}await h(t,r)},So=async(e,t)=>{let r=Yt.join(e,a.GLOBALS_CSS),i=Yt.join(t,"src/styles/globals.css"),n="";if(l(i)){let s=await g(i),c=s.match(/@custom-variant dark \(.*?\);/),p=s.match(/@theme \{[\s\S]*?\}/);c&&(n+=`
843
+ ${c[0]}
844
+ `),p&&(n+=`
845
845
  ${p[0]}
846
- `)}i||(i=`
846
+ `)}n||(n=`
847
847
  @custom-variant dark (&:where(.dark, .dark *));
848
848
 
849
849
  @theme {
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=rp.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 Li(r,t),await Mi(e,r),await Bi(e),await zi(e),await Vi(e,r),await Ji(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(np.green("Dark Theme setup successfully!"))}catch(n){throw t.fail("Failed to setup Dark Theme."),n}finally{await w(r)}};var Wi={id:"dark-theme",name:"Dark Theme",description:"@teispace/next-themes + CustomThemeProvider",detect:async e=>m(ip.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 sp from"node:fs/promises";import It from"node:path";import Nt from"enquirer";import Tr from"picocolors";P();S();P();import Y from"node:fs/promises";import E from"node:path";import op from"degit";var qi=async(e,t)=>{t.text="Downloading assets from starter repository...",await op("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Xi=async(e,t,r,n)=>{let i=E.join(e,c.HTTP_UTILS),o=E.join(t,c.HTTP_UTILS);await Y.cp(E.join(t,c.ERRORS_DIR),E.join(e,c.ERRORS_DIR),{recursive:!0});let s=E.join(e,c.APP_APIS);m(s)||await N(E.join(t,c.APP_APIS),s);let a=E.join(e,c.API_URL_FILE);m(a)||await N(E.join(t,c.API_URL_FILE),a);let p=E.join(e,c.CONSTANTS);if(!m(p))await N(E.join(t,c.CONSTANTS),p);else{let d=await f(p),h=!1;d.includes("API_RESPONSE_DATA_KEY")||(d+=`
853
+ `);let o=await g(r);if(!o.includes("@custom-variant dark")){if(o.includes("@import")){let s=o.lastIndexOf("@import"),c=o.indexOf(`
854
+ `,s);o=o.slice(0,c+1)+n+o.slice(c+1)}else o=n+o;await h(r,o)}},Eo=async e=>{let t=await g(e);t.includes("dark:bg-dark")||(t=t.replace(/className="([^"]*)"/,'className="$1 bg-light dark:bg-dark"'),await h(e,t))};var Qt=async e=>{let t=S("Setting up Dark Theme..."),r=Jp.join(e,".next-maker-temp");try{let{isSetup:i,reason:n}=await Po(e);if(i){t.fail(`Dark Theme is already set up (${n}).`);return}let o=await vo(e);await yo(r,t),await xo(e,r),await Kt(e),await Zt(e),await So(e,r),await Eo(o),t.text="Installing @teispace/next-themes...",await z(e,"@teispace/next-themes"),t.text="Formatting code...";let s=await A(e);await Y(e,s,"lint:fix"),t.succeed(Wp.green("Dark Theme setup successfully!"))}catch(i){throw t.fail("Failed to setup Dark Theme."),i}finally{await v(r)}};P();import er from"node:path";import qp from"picocolors";w();var Xp="src/providers/RootProvider.tsx",To=async(e,t)=>{let r=S("Repairing Dark Theme..."),i=er.join(e,".next-maker-temp-dark-theme-repair");try{let n=er.join(e,a.THEME_PROVIDER),o=[];_(t,a.THEME_PROVIDER)&&!l(n)&&(r.text="Fetching CustomThemeProvider from starter repo...",await ee(i,async p=>{await b(er.join(p,a.THEME_PROVIDER),n)}),o.push(a.THEME_PROVIDER)),U(t,Xp)&&(r.text="Restoring <CustomThemeProvider> wrap...",l(er.join(e,a.PROVIDERS_INDEX))&&await Kt(e),await Zt(e),o.push("<CustomThemeProvider> wrap")),r.text="Restoring dependencies...";let s=await B(e,t),c=[o.length>0?`restored ${o.join(", ")}`:null,s.length>0?`reinstalled ${s.join(", ")}`:null].filter(Boolean);r.succeed(qp.green(c.length>0?`Dark Theme repaired (${c.join("; ")}).`:"Dark Theme repaired."))}catch(n){throw r.fail("Failed to repair Dark Theme."),n}};var Co={id:"dark-theme",name:"Dark Theme",description:"@teispace/next-themes + CustomThemeProvider",detect:async e=>l(Yp.join(e,a.THEME_PROVIDER)),files:[{path:a.THEME_PROVIDER,generated:!0}],packages:[{name:"@teispace/next-themes",kind:"dependency"}],scripts:[],injections:[{file:"src/providers/RootProvider.tsx",description:"<CustomThemeProvider> wrap",presence:/CustomThemeProvider/,removePattern:Be("CustomThemeProvider")}],apply:O(Qt,To)};import Zp from"node:fs/promises";import rr from"node:path";import ir from"enquirer";import si from"picocolors";w();P();w();import te from"node:fs/promises";import T from"node:path";import Kp from"degit";var Ro=async(e,t)=>{t.text="Downloading assets from starter repository...",await Kp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},bo=async(e,t,r,i)=>{let n=T.join(e,a.HTTP_UTILS),o=T.join(t,a.HTTP_UTILS);await te.cp(T.join(t,a.ERRORS_DIR),T.join(e,a.ERRORS_DIR),{recursive:!0});let s=T.join(e,a.APP_APIS);l(s)||await b(T.join(t,a.APP_APIS),s);let c=T.join(e,a.API_URL_FILE);l(c)||await b(T.join(t,a.API_URL_FILE),c);let p=T.join(e,a.CONSTANTS);if(!l(p))await b(T.join(t,a.CONSTANTS),p);else{let d=await g(p),f=!1;d.includes("API_RESPONSE_DATA_KEY")||(d+=`
855
855
  export const API_RESPONSE_DATA_KEY = 'data';
856
- `,h=!0),d.includes("SAVE_AUTH_TOKENS")||(d+=`
856
+ `,f=!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 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))},Yi=async e=>{let{isFileUsed:t,isStringUsed:r}=await Promise.resolve().then(()=>(ze(),Cn));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
+ `,f=!0),f&&await h(p,d)}let u=T.join(e,a.STORAGE_SERVICE);if(l(u)||await te.cp(T.join(t,a.STORAGE_SERVICE),u,{recursive:!0}),await te.cp(T.join(t,a.COMMON_TYPES_DIR),T.join(e,a.COMMON_TYPES_DIR),{recursive:!0}),await te.cp(T.join(t,a.UTILITY_TYPES_DIR),T.join(e,a.UTILITY_TYPES_DIR),{recursive:!0}),await b(T.join(o,"token-store.ts"),T.join(n,"token-store.ts")),await b(T.join(o,"client-utils.ts"),T.join(n,"client-utils.ts")),await te.cp(T.join(t,a.HTTP_SHARED),T.join(e,a.HTTP_SHARED),{recursive:!0,force:!0}),await b(T.join(o,"server.ts"),T.join(n,"server.ts")),await te.cp(T.join(t,a.HTTP_BUNDLE_SENTINEL_DIR),T.join(e,a.HTTP_BUNDLE_SENTINEL_DIR),{recursive:!0,force:!0}),i&&i.length>0)for(let d of i){let f=T.join(e,d==="fetch"?a.FETCH_CLIENT:a.AXIOS_CLIENT);await v(f)}for(let d of r)d==="fetch"?await te.cp(T.join(t,a.FETCH_CLIENT),T.join(e,a.FETCH_CLIENT),{recursive:!0}):await te.cp(T.join(t,a.AXIOS_CLIENT),T.join(e,a.AXIOS_CLIENT),{recursive:!0});await b(T.join(o,"index.ts"),T.join(n,"index.ts")),await b(T.join(t,a.HTTP_TYPES),T.join(e,a.HTTP_TYPES))},Io=async e=>{let{isFileUsed:t,isStringUsed:r,stripSaveAuthTokens:i}=await Promise.resolve().then(()=>(Ue(),tn));await v(T.join(e,a.HTTP_UTILS));let n=T.join(e,a.STORAGE_SERVICE);l(n)&&(await r(e,"SecureStorageService",[n])||await v(n));let o=T.join(e,a.API_URL_FILE);l(o)&&(await r(e,"getApiBaseUrl",[o])||await te.unlink(o));let s=T.join(e,a.CONSTANTS);if(l(s)){let d=await g(s),f=!1;if(await r(e,"API_RESPONSE_DATA_KEY",[s])||(d=d.replace(/export const API_RESPONSE_DATA_KEY = .*;\n?/g,""),f=!0),!await r(e,"SAVE_AUTH_TOKENS",[s])){let G=i(d);G!==d&&(d=G,f=!0)}f&&(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 x=E.parse(h).name;if(await t(e,x,[E.join(s,h)])){d=!0;break}}d||await w(s)}let a=E.join(e,c.COMMON_TYPES_DIR);m(a)&&(await Y.readdir(a)).length===0&&await w(a);let p=E.join(e,c.UTILITY_TYPES_DIR);m(p)&&(await Y.readdir(p)).length===0&&await w(p)};S();P();import ot from"node:path";var Ki=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"}},Zi=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
- ${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 Ki(e);t.stop();let o=await ap(n,i);if(o.type==="cancel"){console.log(Tr.yellow("Setup cancelled."));return}if(t.start("Setting up HTTP client(s)..."),await Zi(e),await qi(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 I=o.type==="replace"&&o.fromClient?[o.fromClient]:void 0;await Xi(e,r,o.clients,I)}if(o.type==="remove-one"||o.type==="remove-both"){t.text="Removing client files...";let{PROJECT_PATHS:I}=await Promise.resolve().then(()=>(S(),hn));for(let R of o.clients){let W=It.join(e,R==="fetch"?I.FETCH_CLIENT:I.AXIOS_CLIENT);await w(W)}Qi(n,o).length===0&&(t.text="Performing full cleanup...",await Yi(e),await nr(e))}let s=Qi(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 sp.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 x=await k(e);await J(e,x,"lint:fix"),t.succeed(Tr.green(cp(o)))}catch(n){throw t.fail("Failed to setup HTTP Client."),n}finally{await w(r)}};async function ap(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 Qi(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 cp(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 eo=/<HttpClientBundleSentinel\s*\/>/,to={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:eo,removePattern:He},{file:"src/app/layout.tsx",description:"<HttpClientBundleSentinel /> mount in root layout",presence:eo,removePattern:He}],apply:kt};S();import br from"node:path";import dp from"picocolors";P();S();P();import pp from"node:fs/promises";import fe from"node:path";import lp from"degit";var ro=async(e,t)=>{t.text="Fetching assets from starter repo...",await lp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},no=async(e,t)=>{let r=fe.join(t,"src/i18n"),n=fe.join(e,c.I18N_DIR);await pp.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"),u=fe.join(e,c.APP_LOCALES);await N(p,u)};S();P();import At from"node:path";var io=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:""}},oo=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 mp from"node:fs/promises";import ce from"node:path";var so=async e=>{let t=ce.join(e,c.NEXT_CONFIG);if(m(t)){let r=await f(t);if(!r.includes("createNextIntlPlugin")){r=`import createNextIntlPlugin from 'next-intl/plugin';
864
- ${r}`;let n=/export default (.*?);/;n.test(r)?r=r.replace(n,`
861
+ `,await h(s,d))}let c=T.join(e,a.ERRORS_DIR);if(l(c)){let d=await te.readdir(c),f=!1;for(let y of d){let I=T.parse(y).name;if(await t(e,I,[T.join(c,y)])){f=!0;break}}f||await v(c)}let p=T.join(e,a.COMMON_TYPES_DIR);l(p)&&(await te.readdir(p)).length===0&&await v(p);let u=T.join(e,a.UTILITY_TYPES_DIR);l(u)&&(await te.readdir(u)).length===0&&await v(u)};P();w();import yt from"node:path";var tr=async e=>{let t=yt.join(e,a.FETCH_CLIENT_FILE),r=yt.join(e,a.AXIOS_CLIENT_FILE),i=l(t),n=l(r);return i&&n?{status:"both",reason:"Both Fetch and Axios clients are detected"}:i?{status:"fetch",reason:"Fetch client is already setup"}:n?{status:"axios",reason:"Axios client is already setup"}:{status:"none"}},$o=async e=>{let r=[yt.join(e,"src/lib"),yt.join(e,"src/types"),yt.join(e,"src/lib/config")].filter(i=>!l(i));if(r.length>0)throw new Error(`Invalid project structure. Missing directories:
862
+ ${r.map(i=>`- ${i}`).join(`
863
+ `)}`)};Ue();var nr=async e=>{let t=S("Checking HTTP Client setup..."),r=rr.join(e,".next-maker-temp-http");try{let{status:i,reason:n}=await tr(e);t.stop();let o=await Qp(i,n);if(o.type==="cancel"){console.log(si.yellow("Setup cancelled."));return}if(t.start("Setting up HTTP client(s)..."),await $o(e),await Ro(r,t),o.type==="replace"&&o.fromClient&&(t.text="Migrating client usages...",await Or(e,o.fromClient,o.clients[0])),o.type!=="remove-both"&&o.type!=="remove-one"){t.text="Copying client files...";let I=o.type==="replace"&&o.fromClient?[o.fromClient]:void 0;await bo(e,r,o.clients,I)}if(o.type==="remove-one"||o.type==="remove-both"){t.text="Removing client files...";let{PROJECT_PATHS:I}=await Promise.resolve().then(()=>(P(),Wi));for(let k of o.clients){let K=rr.join(e,k==="fetch"?I.FETCH_CLIENT:I.AXIOS_CLIENT);await v(K)}ko(i,o).length===0&&(t.text="Performing full cleanup...",await Io(e),await Dr(e))}let s=ko(i,o);s.length>0?(t.text="Configuring client...",await kr(e,s),await Nr(e),await Ar(e),await Fr(e),await Qe(e),await xe(e,s),await we(e,s)):await et(e),await Ge(e,s),t.text="Managing dependencies...";let c=rr.join(e,"package.json"),p=JSON.parse(await Zp.readFile(c,"utf-8")),u={...p.dependencies,...p.devDependencies};s.includes("axios")?u.axios||(t.text="Installing Axios...",await z(e,"axios")):u.axios&&(t.text="Uninstalling Axios...",await He(e,"axios")),s.length>0?u["server-only"]||(t.text="Installing server-only...",await z(e,"server-only")):u["server-only"]&&(t.text="Uninstalling server-only...",await He(e,"server-only"));let d=rr.join(e,"src/services/storage");s.length>0||l(d)?u["react-secure-storage"]||(t.text="Installing react-secure-storage...",await z(e,"react-secure-storage")):u["react-secure-storage"]&&(t.text="Uninstalling react-secure-storage...",await He(e,"react-secure-storage")),t.text="Formatting code...";let y=await A(e);await Y(e,y,"lint:fix"),t.succeed(si.green(el(o)))}catch(i){throw t.fail("Failed to setup HTTP Client."),i}finally{await v(r)}};async function Qp(e,t){if(e==="none"){let{choice:i}=await ir.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 i==="both"?{type:"install",clients:["fetch","axios"]}:{type:"install",clients:[i]}}if(e==="fetch"){let{action:i}=await ir.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(i==="cancel")return{type:"cancel",clients:[]};if(i==="add")return{type:"add",clients:["axios"]};if(i==="replace")return{type:"replace",clients:["axios"],fromClient:"fetch"};if(i==="remove")return{type:"remove-one",clients:["fetch"]}}if(e==="axios"){let{action:i}=await ir.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(i==="cancel")return{type:"cancel",clients:[]};if(i==="add")return{type:"add",clients:["fetch"]};if(i==="replace")return{type:"replace",clients:["fetch"],fromClient:"axios"};if(i==="remove")return{type:"remove-one",clients:["axios"]}}console.log(si.yellow(`\u2716 ${t}`));let{action:r}=await ir.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 ko(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 el(e){if(e.type==="install")return`HTTP Client (${e.clients.map(r=>r==="fetch"?"Fetch":"Axios").join(" + ")}) setup successfully!`;if(e.type==="add")return`${e.clients[0]==="fetch"?"Fetch":"Axios"} client added successfully! Both clients are now available.`;if(e.type==="replace"){let t=e.fromClient==="fetch"?"Fetch":"Axios",r=e.clients[0]==="fetch"?"Fetch":"Axios";return`Replaced ${t} with ${r} successfully! Imports automatically migrated.`}return e.type==="remove-one"?`${e.clients[0]==="fetch"?"Fetch":"Axios"} client removed successfully!`:e.type==="remove-both"?"Both HTTP clients removed successfully!":"HTTP Client setup completed!"}Ue();P();import tl from"node:fs/promises";import Ne from"node:path";import rl from"picocolors";w();Ue();var No=async(e,t)=>{let r=S("Repairing HTTP Client..."),i=Ne.join(e,".next-maker-temp-http-repair");try{let{status:n}=await tr(e),o=n==="both"?["fetch","axios"]:n==="none"?[]:[n],s=[a.HTTP_SHARED,a.HTTP_BUNDLE_SENTINEL_DIR].filter(f=>_(t,f)&&!l(Ne.join(e,f))),c=[a.HTTP_SERVER_FILE,a.API_URL_FILE].filter(f=>_(t,f)&&!l(Ne.join(e,f))),p=[];(s.length>0||c.length>0)&&(r.text="Fetching assets from starter repo...",await ee(i,async f=>{for(let y of s)await tl.cp(Ne.join(f,y),Ne.join(e,y),{recursive:!0,force:!0}),p.push(y);for(let y of c)await b(Ne.join(f,y),Ne.join(e,y)),p.push(y)}),o.length>0&&(await xe(e,o),await we(e,o))),U(t)&&(r.text="Re-mounting the bundle sentinel...",await Qe(e),p.push("<HttpClientBundleSentinel /> mount"));let u=await B(e,t),d=[p.length>0?`restored ${p.join(", ")}`:null,u.length>0?`reinstalled ${u.join(", ")}`:null].filter(Boolean);r.succeed(rl.green(d.length>0?`HTTP Client repaired (${d.join("; ")}).`:"HTTP Client repaired."))}catch(n){throw r.fail("Failed to repair HTTP Client."),n}};var il=/<HttpClientBundleSentinel\s*\/>/,Ao={id:"http-client",name:"HTTP Client",description:"Axios and/or Fetch client utilities",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(W(),st));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",alternativeFiles:["src/app/layout.tsx"],description:"<HttpClientBundleSentinel /> mount in the app layout",presence:il,removePattern:Nt}],apply:O(nr,No)};P();import ai from"node:path";import al from"picocolors";w();P();w();import nl from"node:fs/promises";import Ee from"node:path";import ol from"degit";var Fo=async(e,t)=>{t.text="Fetching assets from starter repo...",await ol("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},_o=async(e,t)=>{let r=Ee.join(t,"src/i18n"),i=Ee.join(e,a.I18N_DIR);await nl.cp(r,i,{recursive:!0});let n=Ee.join(t,"src/proxy.ts"),o=Ee.join(e,a.PROXY);await b(n,o);let s=Ee.join(t,"src/types/i18n.ts"),c=Ee.join(e,a.I18N_TYPES);await b(s,c);let p=Ee.join(t,"src/lib/config/app-locales.ts"),u=Ee.join(e,a.APP_LOCALES);await b(p,u)};P();w();import or from"node:path";var Oo=async e=>{let t=or.join(e,a.I18N_DIR),r=or.join(e,"package.json");if(l(t))return{isSetup:!0,reason:"src/i18n directory exists"};if(l(r)){let i=JSON.parse(await g(r));if(i.dependencies?.["next-intl"]||i.devDependencies?.["next-intl"])return{isSetup:!0,reason:"next-intl is installed"}}return{isSetup:!1,reason:""}},jo=async e=>{let t=or.join(e,a.ROOT_LAYOUT),r=or.join(e,"src/app/[locale]/layout.tsx");if(!l(t)&&!l(r))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx exists.")};P();w();import sl from"node:fs/promises";import ge from"node:path";var sr=async e=>{let t=ge.join(e,a.NEXT_CONFIG);if(l(t)){let r=await g(t);if(!r.includes("createNextIntlPlugin")){r=`import createNextIntlPlugin from 'next-intl/plugin';
864
+ ${r}`;let i=/export default (.*?);/;i.test(r)?r=r.replace(i,`
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)}}},ao=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))}},co=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))}},po=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 h(t,r)}}},ar=async e=>{let t=ge.join(e,a.TYPES_INDEX);if(l(t)){let r=await g(t);r.includes("./i18n")||(r+=`export * from './i18n';
870
+ `,await h(t,r))}},cr=async e=>{let t=ge.join(e,a.CONFIG_INDEX);if(l(t)){let r=await g(t);r.includes("./app-locales")||(r+=`export * from './app-locales';
871
+ `,await h(t,r))}},pr=async e=>{let t=ge.join(e,"src/providers/RootProvider.tsx");if(l(t)){let r=await g(t),i="'use client';",n=r.includes(i);if(n&&(r=r.replace(i,"").trim()),r.includes("next-intl")||(r=`import { type AbstractIntlMessages, NextIntlClientProvider } from 'next-intl';
872
872
  import type { SupportedLocale } from '@/types/i18n';
873
- `+r),i&&(r=`${n}
873
+ `+r),n&&(r=`${i}
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 x=d.replace(/\s+$/,"");return`${u}${x}
876
+ timeZone: string;`,s=/(type\s+RootProviderProps\s*=\s*\{)([\s\S]*?)(\};?)/,c=/export const RootProvider = \(\{([\s\S]*?)\}: \{([\s\S]*?)\}\) => \{/;if(s.test(r))r=r.replace(s,(p,u,d,f)=>{let y=d.replace(/\s+$/,"");return`${u}${y}
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=`
878
+ ${f}`}),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(c);if(p){let u=p[1].trim().replace(/,$/,""),d=p[2].trim().replace(/;$/,""),f=`
879
879
  ${u?`${u},
880
880
  `:""}locale,
881
881
  messages,
882
- timeZone,`,x=`
882
+ timeZone,`,y=`
883
883
  ${d?`${d};
884
884
  `:""}locale: SupportedLocale;
885
885
  messages: AbstractIntlMessages;
886
- timeZone: string;`;r=r.replace(p[0],`export const RootProvider = ({${h}
887
- }: {${x}
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}>
886
+ timeZone: string;`;r=r.replace(p[0],`export const RootProvider = ({${f}
887
+ }: {${y}
888
+ }) => {`)}}}if(!r.includes("<NextIntlClientProvider")){let o=r.match(/return\s*(?:\(\s*)?([\s\S]*?)(?:\s*\))?;/);if(o){let s=o[1],c=`<NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>
889
889
  {children}
890
- </NextIntlClientProvider>`;if(s.includes("{children}")){let p=s.replace("{children}",a);r=r.replace(o[0],`return (
890
+ </NextIntlClientProvider>`;if(s.includes("{children}")){let p=s.replace("{children}",c);r=r.replace(o[0],`return (
891
891
  ${p}
892
892
  );`)}else r=r.replace(o[0],`return (
893
893
  <NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>
894
894
  ${s}
895
895
  </NextIntlClientProvider>
896
- );`)}}await g(t,r)}},lo=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 mp.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 h(t,r)}},Do=async e=>{let t=ge.join(e,a.ROOT_LAYOUT),r=ge.join(e,a.ROOT_PAGE),i=ge.join(e,"src/app/[locale]");if(await sl.mkdir(i,{recursive:!0}),l(t)){let n=ge.join(i,"layout.tsx"),o=await g(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';
@@ -905,7 +905,7 @@ export function generateStaticParams() {
905
905
  }`+o.slice(u)}}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*:/,c=o.match(s);if(c){c[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 f=d.index+d[0].length-1;o=o.slice(0,f+1)+`
909
909
  const { locale } = await params;
910
910
 
911
911
  if (!hasLocale(routing.locales, locale)) {
@@ -915,42 +915,42 @@ 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(f+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 h(n,o),await C(t)}if(l(r)){let n=ge.join(i,"page.tsx"),o=await g(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 }>;
922
922
  };
923
923
 
924
- export default async function Home(props: Props)`);let s=o.indexOf("export default async function Home(props: Props) {");if(s!==-1){let a=`
924
+ export default async function Home(props: Props)`);let s=o.indexOf("export default async function Home(props: Props) {");if(s!==-1){let c=`
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 io(e);if(n){t.fail(`i18n is already set up (${i}).`);return}await oo(e),await ro(r,t),t.text="Copying i18n files...",await no(e,r),t.text="Configuring project structure...",await so(e),await ao(e),await co(e),await po(e),t.text="Migrating to [locale] structure...",await lo(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 me(e,{redux:u,i18n:!0})}t.text="Formatting code...";let s=await k(e);await J(e,s,"lint:fix"),t.succeed(dp.green("Internationalization setup successfully!"))}catch(n){throw t.fail("Failed to setup Internationalization."),n}finally{await w(r)}};var mo={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:Ai},{file:"src/providers/RootProvider.tsx",description:"<NextIntlClientProvider> wrap",presence:/NextIntlClientProvider/,removePattern:_e("NextIntlClientProvider")}],apply:_t};S();P();import gp from"node:path";S();import up from"node:path";import fp from"picocolors";P();var Ot=async e=>{let t=b("Enabling React Compiler...");try{let r=up.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(fp.green("React Compiler enabled."))}catch(r){throw t.fail("Failed to enable React Compiler."),r}};var uo={id:"react-compiler",name:"React Compiler",description:"reactCompiler: true in next.config.ts + babel-plugin-react-compiler",detect:async e=>{let t=gp.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 yp from"picocolors";P();S();P();import fo from"node:fs/promises";import Ee from"node:path";import hp from"degit";var go=async(e,t)=>{t.text="Fetching assets from starter repo...",await hp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},ho=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 fo.cp(i,o,{recursive:!0})},yo=async(e,t)=>{let r=Ee.join(t,"src/features/counter"),n=Ee.join(e,c.COUNTER_FEATURE);await fo.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();P();import Rr from"node:path";var xo=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:""}},Po=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();P();import $r from"node:path";var wo=async e=>{},vo=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)+c+o.slice(p+1)}await h(n,o),await C(r)}};var lr=async e=>{let t=S("Setting up Internationalization (next-intl)..."),r=ai.join(e,".next-maker-temp-i18n");try{let{isSetup:i,reason:n}=await Oo(e);if(i){t.fail(`i18n is already set up (${n}).`);return}await jo(e),await Fo(r,t),t.text="Copying i18n files...",await _o(e,r),t.text="Configuring project structure...",await sr(e),await ar(e),await cr(e),await pr(e),t.text="Migrating to [locale] structure...",await Do(e),t.text="Installing dependencies...",await z(e,"next-intl");let o=ai.join(e,a.VITEST_CONFIG);if(l(o)){let c=JSON.parse(await g(ai.join(e,a.PACKAGE_JSON))),p={...c.dependencies,...c.devDependencies},u=!!(p["@reduxjs/toolkit"]&&p["react-redux"]);await ae(e,{redux:u,i18n:!0})}t.text="Formatting code...";let s=await A(e);await Y(e,s,"lint:fix"),t.succeed(al.green("Internationalization setup successfully!"))}catch(i){throw t.fail("Failed to setup Internationalization."),i}finally{await v(r)}};P();import cl from"node:fs/promises";import xt from"node:path";import Lo from"picocolors";w();var pl="src/providers/RootProvider.tsx",Mo=async(e,t)=>{let r=S("Repairing Internationalization..."),i=xt.join(e,".next-maker-temp-i18n-repair");try{let n=xt.join(e,a.I18N_DIR),o=xt.join(e,a.PROXY),s=_(t,a.I18N_DIR)&&!l(n),c=_(t,a.PROXY)&&!l(o),p=[];(s||c)&&(r.text="Fetching assets from starter repo...",await ee(i,async y=>{s&&(await cl.cp(xt.join(y,a.I18N_DIR),n,{recursive:!0}),p.push(a.I18N_DIR)),c&&(await b(xt.join(y,a.PROXY),o),p.push(a.PROXY))})),U(t,a.NEXT_CONFIG)&&(r.text="Restoring the next-intl plugin wrap...",await sr(e),p.push("createNextIntlPlugin wrap")),U(t,pl)&&(r.text="Restoring <NextIntlClientProvider>...",await pr(e),p.push("<NextIntlClientProvider> wrap")),p.length>0&&(await ar(e),await cr(e)),r.text="Restoring dependencies...";let u=await B(e,t),d=_(t,a.LOCALE_DIR),f=[p.length>0?`restored ${p.join(", ")}`:null,u.length>0?`reinstalled ${u.join(", ")}`:null].filter(Boolean);r.succeed(Lo.green(f.length>0?`Internationalization repaired (${f.join("; ")}).`:"Internationalization repaired.")),d&&console.log(Lo.yellow(` \u26A0\uFE0F ${a.LOCALE_DIR} is missing. Recreating it means moving your app-router pages, so it is left for you: run \`next-maker setup --i18n\` on a clean tree, or move your pages under ${a.LOCALE_DIR}/ by hand.`))}catch(n){throw r.fail("Failed to repair Internationalization."),n}};var Ho={id:"i18n",name:"Internationalization",description:"next-intl with [locale] routing, RootProvider, and proxy.ts",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(W(),st));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:po},{file:"src/providers/RootProvider.tsx",description:"<NextIntlClientProvider> wrap",presence:/NextIntlClientProvider/,removePattern:Be("NextIntlClientProvider")}],apply:O(lr,Mo)};P();w();import fl from"node:path";P();import ll from"node:path";import ml from"picocolors";w();var Go=/(const\s+nextConfig\s*:\s*NextConfig\s*=\s*\{)/,mr=e=>/reactCompiler\s*:/.test(e),wt=e=>{if(mr(e))return e;if(!Go.test(e))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");return e.replace(Go,`$1
928
+ reactCompiler: true,`)};var dr=async e=>{let t=S("Enabling React Compiler...");try{let r=ll.join(e,a.NEXT_CONFIG);if(!l(r))throw new Error(`${a.NEXT_CONFIG} not found.`);let i=await g(r);if(mr(i)){t.fail("React Compiler is already configured in next.config.ts.");return}await h(r,wt(i)),t.text="Installing babel-plugin-react-compiler...",await kt(e,"babel-plugin-react-compiler"),t.succeed(ml.green("React Compiler enabled."))}catch(r){throw t.fail("Failed to enable React Compiler."),r}};P();import dl from"node:path";import ul from"picocolors";w();var Uo=async(e,t)=>{let r=S("Repairing React Compiler...");try{if(U(t,a.NEXT_CONFIG)){let n=dl.join(e,a.NEXT_CONFIG);if(l(n)){let o=await g(n),s=wt(o);s!==o&&await h(n,s)}}let i=await B(e,t);r.succeed(ul.green(i.length>0?`React Compiler repaired (reinstalled ${i.join(", ")}).`:"React Compiler repaired."))}catch(i){throw r.fail("Failed to repair React Compiler."),i}};var Bo={id:"react-compiler",name:"React Compiler",description:"reactCompiler: true in next.config.ts + babel-plugin-react-compiler",detect:async e=>{let t=fl.join(e,a.NEXT_CONFIG);return l(t)?/reactCompiler\s*:\s*true/.test(await g(t)):!1},files:[],packages:[{name:"babel-plugin-react-compiler",kind:"devDependency"}],scripts:[],injections:[{file:a.NEXT_CONFIG,description:"`reactCompiler: true` flag",presence:/reactCompiler\s*:\s*true/,removePattern:/\n\s*reactCompiler:\s*true,?/}],apply:O(dr,Uo)};P();import li from"node:path";import hl from"picocolors";w();P();w();import zo from"node:fs/promises";import Ae from"node:path";import gl from"degit";var Vo=async(e,t)=>{t.text="Fetching assets from starter repo...",await gl("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Jo=async(e,t)=>{let r=Ae.join(t,"src/providers/StoreProvider.tsx"),i=Ae.join(e,a.STORE_PROVIDER);await b(r,i);let n=Ae.join(t,"src/store"),o=Ae.join(e,a.STORE);await zo.cp(n,o,{recursive:!0})},Wo=async(e,t)=>{let r=Ae.join(t,"src/features/counter"),i=Ae.join(e,a.COUNTER_FEATURE);await zo.cp(r,i,{recursive:!0});let n=Ae.join(i,"components/Counter.tsx");if(await l(n)){let o=await g(n);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 h(n,o)}};P();w();import ci from"node:path";var qo=async e=>{let t=ci.join(e,a.STORE),r=ci.join(e,"package.json");if(l(t))return{isSetup:!0,reason:"src/store directory exists"};if(l(r)){let i=JSON.parse(await g(r));if(i.dependencies?.["@reduxjs/toolkit"]||i.devDependencies?.["@reduxjs/toolkit"])return{isSetup:!0,reason:"@reduxjs/toolkit is installed"}}return{isSetup:!1,reason:""}},Xo=async e=>{let t=ci.join(e,a.PROVIDERS_INDEX);if(!await Xt(e)||!l(t))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx (or src/app/[locale]/layout.tsx) and src/providers/index.ts exist.")};P();w();import pi from"node:path";var Yo=async e=>{},ur=async e=>{let t=pi.join(e,"src/providers/RootProvider.tsx");if(!l(t))return;let r=await g(t),i="'use client';",n=r.includes(i);if(n&&(r=r.replace(i,"").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
- ${r}`),i&&(r=`${n}
930
+ ${r}`),n&&(r=`${i}
931
931
  ${r}`),r.includes("preloadedState")||(r=r.replace(/children:\s*React\.ReactNode;/,`children: React.ReactNode;
932
932
  preloadedState?: Partial<AppState>;`),r=r.replace(/export const RootProvider = \(\{([\s\S]*?)\}:/,(o,s)=>`export const RootProvider = ({${s}, preloadedState }:`),r=r.replace(/,\s*,/g,",").replace(/\{\s*,/g,"{ ").replace(/,\s*\}/g," }")),!r.includes("<StoreProvider")){let o=r.match(/return\s*\(\s*([\s\S]*?)\s*\);/);if(o){let s=o[1];r=r.replace(o[0],`return (
933
933
  <StoreProvider preloadedState={preloadedState}>
934
934
  ${s}
935
935
  </StoreProvider>
936
- );`)}}await g(t,r)},So=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';
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)+`
936
+ );`)}}await h(t,r)},Ko=async e=>{let t=[pi.join(e,a.ROOT_PAGE),pi.join(e,"src/app/[locale]/page.tsx")],r="";for(let n of t)if(l(n)){r=n;break}if(!r)return;let i=await g(r);if(i.includes("Counter")||(i=`import { Counter } from '@/features/counter';
937
+ ${i}`),!i.includes("<Counter />")){let n=i.lastIndexOf("</div>"),o=i.lastIndexOf("</main>"),s=o!==-1?o:n;s!==-1&&(i=i.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 xo(e);if(n){t.fail(`Redux is already set up (${i}).`);return}await Po(e),await go(r,t),t.text="Copying Redux files...",await ho(e,r),t.text="Creating Counter feature...",await yo(e,r),t.text="Updating providers and pages...",await wo(e),await vo(e),await So(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 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(yp.green("Redux Toolkit setup successfully!"))}catch(n){throw t.fail("Failed to setup Redux Toolkit."),n}finally{await w(r)}};var Eo={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 Sp from"node:path";S();import wp from"node:path";import vp from"picocolors";P();var To=[{key:"X-DNS-Prefetch-Control",value:"on"},{key:"Strict-Transport-Security",value:"max-age=63072000; includeSubDomains; preload"},{key:"X-XSS-Protection",value:"1; mode=block"},{key:"X-Frame-Options",value:"SAMEORIGIN"},{key:"X-Content-Type-Options",value:"nosniff"},{key:"Referrer-Policy",value:"origin-when-cross-origin"}],Co=/(const\s+nextConfig\s*:\s*NextConfig\s*=\s*\{)/,xp=/^\s+headers\s*:/m,Pp=e=>`
942
+ `+i.slice(s),await h(r,i))}};var fr=async e=>{let t=S("Setting up Redux Toolkit..."),r=li.join(e,".next-maker-temp-redux");try{let{isSetup:i,reason:n}=await qo(e);if(i){t.fail(`Redux is already set up (${n}).`);return}await Xo(e),await Vo(r,t),t.text="Copying Redux files...",await Jo(e,r),t.text="Creating Counter feature...",await Wo(e,r),t.text="Updating providers and pages...",await Yo(e),await ur(e),await Ko(e),t.text="Installing dependencies...",await z(e,"@reduxjs/toolkit"),await z(e,"react-redux"),await z(e,"redux-persist"),await z(e,"react-secure-storage");let o=li.join(e,a.VITEST_CONFIG);if(l(o)){let c=JSON.parse(await g(li.join(e,a.PACKAGE_JSON))),p={...c.dependencies,...c.devDependencies};await ae(e,{redux:!0,i18n:!!p["next-intl"]})}t.text="Formatting code...";let s=await A(e);await Y(e,s,"lint:fix"),t.succeed(hl.green("Redux Toolkit setup successfully!"))}catch(i){throw t.fail("Failed to setup Redux Toolkit."),i}finally{await v(r)}};P();import yl from"node:fs/promises";import Pt from"node:path";import xl from"picocolors";w();var wl="src/providers/RootProvider.tsx",Zo=async(e,t)=>{let r=S("Repairing Redux Toolkit..."),i=Pt.join(e,".next-maker-temp-redux-repair");try{let n=Pt.join(e,a.STORE),o=Pt.join(e,a.STORE_PROVIDER),s=_(t,a.STORE)&&!l(n),c=_(t,a.STORE_PROVIDER)&&!l(o),p=[];(s||c)&&(r.text="Fetching assets from starter repo...",await ee(i,async f=>{s&&(await yl.cp(Pt.join(f,a.STORE),n,{recursive:!0}),p.push(a.STORE)),c&&(await b(Pt.join(f,a.STORE_PROVIDER),o),p.push(a.STORE_PROVIDER))})),U(t,wl)&&(r.text="Restoring <StoreProvider> wrap...",await ur(e),p.push("<StoreProvider> wrap")),r.text="Restoring dependencies...";let u=await B(e,t),d=[p.length>0?`restored ${p.join(", ")}`:null,u.length>0?`reinstalled ${u.join(", ")}`:null].filter(Boolean);r.succeed(xl.green(d.length>0?`Redux Toolkit repaired (${d.join("; ")}).`:"Redux Toolkit repaired."))}catch(n){throw r.fail("Failed to repair Redux Toolkit."),n}};var Qo={id:"redux",name:"Redux Toolkit",description:"Redux Toolkit + react-redux + redux-persist + StoreProvider",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(W(),st));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:Be("StoreProvider")}],apply:O(fr,Zo)};P();w();import Rl from"node:path";P();import Sl from"node:path";import El from"picocolors";w();var ts=[{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"}],es=/(const\s+nextConfig\s*:\s*NextConfig\s*=\s*\{)/,Pl=/^\s+headers\s*:/m,vl=e=>`
943
943
  headers: async () => {
944
944
  return [
945
945
  {
946
946
  source: '/:path*',
947
947
  headers: [
948
- ${e.map(({key:r,value:n})=>` { key: '${r}', value: '${n}' },`).join(`
948
+ ${e.map(({key:r,value:i})=>` { key: '${r}', value: '${i}' },`).join(`
949
949
  `)}
950
950
  ],
951
951
  },
952
952
  ];
953
- },`,Oe=e=>xp.test(e),Nr=(e,t=To)=>{if(Oe(e))return e;if(!Co.test(e))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");return e.replace(Co,`$1${Pp(t)}`)};var jt=async e=>{let t=b("Adding security headers to next.config.ts...");try{let r=wp.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(vp.green("Security headers added."))}catch(r){throw t.fail("Failed to add security headers."),r}};var bo={id:"security-headers",name:"Security Headers",description:"Hardened HTTP headers in next.config.ts",detect:async e=>{let t=Sp.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();P();import Rp from"node:path";S();import Ep from"node:fs/promises";import ge from"node:path";import Cp from"degit";import Tp from"picocolors";P();var bp=["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 Cp("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 Ep.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 f(s)),p={...a.dependencies,...a.devDependencies},u=!!(p["@reduxjs/toolkit"]&&p["react-redux"]),d=!!p["next-intl"];await me(e,{redux:u,i18n:d}),await D(s,x=>(x.scripts=x.scripts??{},x.scripts.test=x.scripts.test??"vitest run",x.scripts["test:watch"]=x.scripts["test:watch"]??"vitest",x.scripts["test:coverage"]=x.scripts["test:coverage"]??"vitest run --coverage",typeof x.scripts.validate=="string"&&!/\byarn\s+test(?![:\w])/.test(x.scripts.validate)&&(x.scripts.validate=x.scripts.validate.replace(/(\byarn\s+check:deprecated\s*)(&&)/,"$1&& yarn test $2")),x)),t.text="Installing testing devDependencies...";let h=await k(e);await Pe(e,h,bp),t.text="Formatting code...",await J(e,h,"lint:fix"),t.succeed(Tp.green("Testing setup complete."))}catch(n){throw t.fail("Failed to set up testing."),n}finally{await w(r)}};var Ro={id:"tests",name:"Tests",description:"Vitest + React Testing Library + jsdom",detect:async e=>m(Rp.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 Ap from"node:path";S();import $o from"node:path";import Np from"picocolors";P();var $p={npm:"npm run",yarn:"yarn",pnpm:"pnpm",bun:"bun run"},Ip=e=>{let t=$p[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=Ip(t)),!n.tsx&&!Object.hasOwn(e.dependencies??{},"tsx")&&(n.tsx="*"),{...e,scripts:r,devDependencies:n}};var Ar=`import * as fs from 'node:fs';
953
+ },`,ze=e=>Pl.test(e),vt=(e,t=ts)=>{if(ze(e))return e;if(!es.test(e))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");return e.replace(es,`$1${vl(t)}`)};var gr=async e=>{let t=S("Adding security headers to next.config.ts...");try{let r=Sl.join(e,a.NEXT_CONFIG);if(!l(r))throw new Error(`${a.NEXT_CONFIG} not found.`);let i=await g(r);if(ze(i)){t.succeed("Security headers already configured.");return}let n=vt(i);await h(r,n),t.succeed(El.green("Security headers added."))}catch(r){throw t.fail("Failed to add security headers."),r}};P();import Tl from"node:path";import Cl from"picocolors";w();var rs=async(e,t)=>{if(!U(t,a.NEXT_CONFIG))return;let r=S("Repairing security headers...");try{let i=Tl.join(e,a.NEXT_CONFIG);if(!l(i)){r.fail(`${a.NEXT_CONFIG} not found \u2014 cannot restore security headers.`);return}let n=await g(i),o=vt(n);o!==n&&await h(i,o),r.succeed(Cl.green("Security headers restored."))}catch(i){throw r.fail("Failed to repair security headers."),i}};var is={id:"security-headers",name:"Security Headers",description:"Hardened HTTP headers in next.config.ts",detect:async e=>{let t=Rl.join(e,a.NEXT_CONFIG);return l(t)?ze(await g(t)):!1},files:[],packages:[],scripts:[],injections:[{file:a.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:O(gr,rs)};P();w();import Al from"node:path";P();import bl from"node:fs/promises";import Te from"node:path";import Il from"degit";import $l from"picocolors";w();var kl=["vitest","jsdom","@vitejs/plugin-react","@testing-library/dom","@testing-library/jest-dom","@testing-library/react","@testing-library/user-event"],hr=async e=>{let t=S("Setting up testing (Vitest + RTL)..."),r=Te.join(e,".next-maker-temp-tests");try{let i=Te.join(e,a.VITEST_CONFIG);if(l(i)){t.fail("Testing is already set up (vitest.config.ts exists).");return}t.text="Fetching assets from starter repo...",await Il("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(r),await b(Te.join(r,a.VITEST_CONFIG),Te.join(e,a.VITEST_CONFIG));let o=Te.join(e,a.TEST_DIR);await bl.mkdir(o,{recursive:!0}),await b(Te.join(r,a.TEST_DIR,"setup.ts"),Te.join(o,"setup.ts"));let s=Te.join(e,a.PACKAGE_JSON),c=JSON.parse(await g(s)),p={...c.dependencies,...c.devDependencies},u=!!(p["@reduxjs/toolkit"]&&p["react-redux"]),d=!!p["next-intl"];await ae(e,{redux:u,i18n:d}),await F(s,y=>(y.scripts=y.scripts??{},y.scripts.test=y.scripts.test??"vitest run",y.scripts["test:watch"]=y.scripts["test:watch"]??"vitest",y.scripts["test:coverage"]=y.scripts["test:coverage"]??"vitest run --coverage",typeof y.scripts.validate=="string"&&!/\byarn\s+test(?![:\w])/.test(y.scripts.validate)&&(y.scripts.validate=y.scripts.validate.replace(/(\byarn\s+check:deprecated\s*)(&&)/,"$1&& yarn test $2")),y)),t.text="Installing testing devDependencies...";let f=await A(e);await ue(e,f,kl),t.text="Formatting code...",await Y(e,f,"lint:fix"),t.succeed($l.green("Testing setup complete."))}catch(i){throw t.fail("Failed to set up testing."),i}finally{await v(r)}};P();import Fe from"node:path";import Nl from"picocolors";w();var ns=async(e,t)=>{let r=S("Repairing testing setup..."),i=Fe.join(e,".next-maker-temp-tests-repair");try{let n=_(t,a.VITEST_CONFIG)&&!l(Fe.join(e,a.VITEST_CONFIG)),o=Fe.join(e,a.TEST_SETUP_FILE),s=_(t,a.TEST_DIR)&&!l(o),c=[];if((n||s)&&(r.text="Fetching assets from starter repo...",await ee(i,async f=>{n&&(await b(Fe.join(f,a.VITEST_CONFIG),Fe.join(e,a.VITEST_CONFIG)),c.push(a.VITEST_CONFIG)),s&&(await b(Fe.join(f,a.TEST_SETUP_FILE),o),c.push(a.TEST_SETUP_FILE))}),s)){let f=Fe.join(e,a.PACKAGE_JSON),y=l(f)?JSON.parse(await g(f)):{},I={...y.dependencies,...y.devDependencies};await ae(e,{redux:!!(I["@reduxjs/toolkit"]&&I["react-redux"]),i18n:!!I["next-intl"]}),c.push("test/test-utils.tsx")}r.text="Restoring testing dependencies...";let p=await B(e,t),u=await Se(e,t),d=[c.length>0?`restored ${c.join(", ")}`:null,p.length>0?`reinstalled ${p.join(", ")}`:null,u.length>0?`reset ${u.join(", ")}`:null].filter(Boolean);r.succeed(Nl.green(d.length>0?`Testing setup repaired (${d.join("; ")}).`:"Testing setup repaired."))}catch(n){throw r.fail("Failed to repair testing setup."),n}};var os={id:"tests",name:"Tests",description:"Vitest + React Testing Library + jsdom",detect:async e=>l(Al.join(e,a.VITEST_CONFIG)),files:[{path:a.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:O(hr,ns)};w();import Dl from"node:path";P();import cs from"node:path";import Ol from"picocolors";w();var Fl={npm:"npm run",yarn:"yarn",pnpm:"pnpm",bun:"bun run"},_l=e=>{let t=Fl[e];return["ci:check","type-check","check:deprecated","test","build"].map(r=>`${t} ${r}`).join(" && ")},St=(e,t)=>{let r={...e.scripts??{}},i={...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=_l(t)),!i.tsx&&!Object.hasOwn(e.dependencies??{},"tsx")&&(i.tsx="*"),{...e,scripts:r,devDependencies:i}};var ss=`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
+ `,as=`/**
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,120 @@ if (hits === 0) {
1088
1088
 
1089
1089
  console.log(\`\\n\${hits} deprecated symbol use(s) found.\`);
1090
1090
  process.exit(1);
1091
- `;var kp=[{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 kp){let a=$o.join(e,o);m(a)||(await g(a,s),r=!0)}let n=await k(e),i=!1;await D($o.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(Np.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 Io=["scripts/sync-env.ts","scripts/check-deprecated.ts"],No={id:"validate-scripts",name:"Validation Scripts",description:"sync-env, check-deprecated, and the validate chain",detect:async e=>Io.every(t=>m(Ap.join(e,t))),files:Io.map(e=>({path:e,generated:!0})),packages:[{name:"tsx",kind:"devDependency"}],scripts:[{name:"env:sync",expectedValue:"tsx scripts/sync-env.ts"},{name:"check:deprecated",expectedValue:"tsx scripts/check-deprecated.ts"},{name:"type-check",expectedValue:"tsc --noEmit"},{name:"validate"}],injections:[],apply:Lt};import{access as jp,readFile as Dp}from"node:fs/promises";import jo from"node:path";S();import Fr from"node:path";import Fp from"picocolors";P();S();P();import Or from"node:fs/promises";import st from"node:path";import _p from"degit";var ko=async(e,t)=>{t.text="Downloading assets from starter repository...",await _p("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Ao=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 N(st.join(t,c.WS_SLICE_FILE),i),r.keepTests||await Op(n)},Op=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();P();import _o from"node:path";var Oo=async e=>{let t=_o.join(e,c.WS_UTILS);return m(t)?{isSetup:!0,reason:"src/lib/utils/ws/ already exists"}:{isSetup:!1}},Fo=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(_o.join(e,n))||t.push(`- ${i}`);if(t.length>0)throw new Error(`WebSocket setup requires Redux Toolkit. Missing:
1091
+ `,Et=[{relative:"scripts/sync-env.ts",content:ss},{relative:"scripts/check-deprecated.ts",content:as}];var yr=async e=>{let t=S("Adding validation scripts...");try{let r=!1;for(let{relative:o,content:s}of Et){let c=cs.join(e,o);l(c)||(await h(c,s),r=!0)}let i=await A(e),n=!1;await F(cs.join(e,a.PACKAGE_JSON),o=>{let s=o.devDependencies?.tsx,c=St(o,i);return n=!s&&!!c.devDependencies?.tsx,c}),n&&(t.text="Installing tsx...",await ue(e,i,["tsx"])),t.succeed(Ol.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}};P();import ps from"node:path";import jl from"picocolors";w();var ls=async(e,t)=>{let r=S("Repairing validation scripts...");try{let i=[];for(let{relative:p,content:u}of Et){if(!_(t,p))continue;let d=ps.join(e,p);l(d)||(await h(d,u),i.push(p))}let n=await B(e,t),o=ps.join(e,a.PACKAGE_JSON);if(l(o)){let p=await A(e);await F(o,u=>St(u,p))}let s=await Se(e,t),c=[i.length>0?`rewrote ${i.join(", ")}`:null,n.length>0?`reinstalled ${n.join(", ")}`:null,s.length>0?`reset ${s.join(", ")}`:null].filter(Boolean);r.succeed(jl.green(c.length>0?`Validation scripts repaired (${c.join("; ")}).`:"Validation scripts repaired."))}catch(i){throw r.fail("Failed to repair validation scripts."),i}};var ms=["scripts/sync-env.ts","scripts/check-deprecated.ts"],ds={id:"validate-scripts",name:"Validation Scripts",description:"sync-env, check-deprecated, and the validate chain",detect:async e=>ms.every(t=>l(Dl.join(e,t))),files:ms.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:O(yr,ls)};import{access as Bl,readFile as zl}from"node:fs/promises";import ws from"node:path";P();import ui from"node:path";import Ml from"picocolors";w();P();w();import mi from"node:fs/promises";import Tt from"node:path";import Ll from"degit";var us=async(e,t)=>{t.text="Downloading assets from starter repository...",await Ll("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},fs=async(e,t,r)=>{let i=Tt.join(e,a.WS_UTILS);await mi.cp(Tt.join(t,a.WS_UTILS),i,{recursive:!0,force:!0});let n=Tt.join(e,a.WS_SLICE_FILE);await b(Tt.join(t,a.WS_SLICE_FILE),n),r.keepTests||await di(i)},di=async e=>{let t=async r=>{let i=await mi.readdir(r,{withFileTypes:!0});for(let n of i){let o=Tt.join(r,n.name);if(n.isDirectory()){if(n.name==="__test-utils__"){await v(o);continue}await t(o)}else n.isFile()&&/\.test\.tsx?$/.test(n.name)&&await mi.unlink(o)}};await t(e)};P();w();import gs from"node:path";var hs=async e=>{let t=gs.join(e,a.WS_UTILS);return l(t)?{isSetup:!0,reason:"src/lib/utils/ws/ already exists"}:{isSetup:!1}},ys=async e=>{let t=[],r=[{rel:"src/lib",label:"src/lib"},{rel:"src/store",label:"src/store (Redux Toolkit not installed?)"},{rel:a.ROOT_REDUCER,label:"src/store/rootReducer.ts (Redux not initialised?)"},{rel:a.STORE_PROVIDER,label:"src/providers/StoreProvider.tsx (Redux not initialised?)"}];for(let{rel:i,label:n}of r)l(gs.join(e,i))||t.push(`- ${n}`);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 Oo(e);if(n){t.fail(`WebSocket layer is already set up (${i}).`);return}await Fo(e),await ko(r,t),t.text="Copying WebSocket files...";let o=m(Fr.join(e,c.VITEST_CONFIG));await Ao(e,r,{keepTests:o}),t.text="Registering wsReducer...",await Gn(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 k(e);await J(e,u,"lint:fix"),t.succeed(Fp.green("WebSocket layer setup successfully!"))}catch(n){throw t.fail("Failed to setup WebSocket layer."),n}finally{await w(r)}};var Lp=async e=>{try{let t=JSON.parse(await Dp(jo.join(e,"package.json"),"utf-8"));return{...t.dependencies,...t.devDependencies}["socket.io-client"]?(await jp(jo.join(e,"src/lib/utils/ws")),!0):!1}catch{return!1}},Do={id:"ws",name:"WebSocket Client",description:"socket.io-client + lazy WS singleton + Redux slice + hooks",detect:Lp,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 Lo=async e=>{let t=Fe.join(e,c.PACKAGE_JSON);return m(t)?JSON.parse(await f(t)):null},Mp=async(e,t)=>{let r=Fe.join(e,c.PACKAGE_JSON);await g(r,`${JSON.stringify(t,null,2)}
1096
- `)},Mo=(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 Lo(t);if(i){for(let s of e.packages)Mo(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}},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 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 Lo(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)Mo(s,p.kind)[p.name]&&i.packagesUninstalled.push(p.name);a&&!n&&await Mp(t,s)}if(!n&&i.packagesUninstalled.length>0){let a=await k(t);await qt(t,a,i.packagesUninstalled)}return i};var Ce=[bo,No,ji,uo,Oi,Ro,Wi,to,Eo,Do,mo],Go=e=>Ce.find(t=>t.id===e);var Gp=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}`}},Up=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 xr=async e=>{let t=S("Setting up WebSocket layer..."),r=ui.join(e,".next-maker-temp-ws");try{let{isSetup:i,reason:n}=await hs(e);if(i){t.fail(`WebSocket layer is already set up (${n}).`);return}await ys(e),await us(r,t),t.text="Copying WebSocket files...";let o=l(ui.join(e,a.VITEST_CONFIG));await fs(e,r,{keepTests:o}),t.text="Registering wsReducer...",await Ft(e),t.text="Mounting WS bridge in StoreProvider...",await Ot(e),t.text="Ensuring test/setup.ts mocks...",await jt(e),t.text="Installing socket.io-client...";let s=ui.join(e,a.PACKAGE_JSON),c=JSON.parse(await g(s));({...c.dependencies,...c.devDependencies})["socket.io-client"]||await z(e,"socket.io-client@^4.8.3"),t.text="Formatting code...";let u=await A(e);await Y(e,u,"lint:fix"),t.succeed(Ml.green("WebSocket layer setup successfully!"))}catch(i){throw t.fail("Failed to setup WebSocket layer."),i}finally{await v(r)}};P();import Hl from"node:fs/promises";import Ve from"node:path";import Gl from"picocolors";w();var Ul="socket.io-client@^4.8.3",xs=async(e,t)=>{let r=S("Repairing WebSocket layer..."),i=Ve.join(e,".next-maker-temp-ws-repair");try{let n=Ve.join(e,a.WS_UTILS),o=Ve.join(e,a.WS_SLICE_FILE),s=_(t,a.WS_UTILS)&&!l(n),c=_(t,a.WS_SLICE_FILE)&&!l(o),p=[];if(s||c){r.text="Fetching assets from starter repo...";let f=l(Ve.join(e,a.VITEST_CONFIG));await ee(i,async y=>{s&&(await Hl.cp(Ve.join(y,a.WS_UTILS),n,{recursive:!0,force:!0}),f||await di(n),p.push(a.WS_UTILS)),c&&(await b(Ve.join(y,a.WS_SLICE_FILE),o),p.push(a.WS_SLICE_FILE))})}U(t,a.ROOT_REDUCER)&&(r.text="Re-registering wsReducer...",await Ft(e),p.push("wsReducer registration")),U(t,a.STORE_PROVIDER)&&(r.text="Re-mounting the WS bridge...",await Ot(e),p.push("attachWsBridge mount")),await jt(e);let u=[];Wt(t,"dependency").includes("socket.io-client")&&(r.text="Installing socket.io-client...",await z(e,Ul),u.push("socket.io-client"));let d=[p.length>0?`restored ${p.join(", ")}`:null,u.length>0?`reinstalled ${u.join(", ")}`:null].filter(Boolean);r.succeed(Gl.green(d.length>0?`WebSocket layer repaired (${d.join("; ")}).`:"WebSocket layer repaired."))}catch(n){throw r.fail("Failed to repair WebSocket layer."),n}};var Vl=async e=>{try{let t=JSON.parse(await zl(ws.join(e,"package.json"),"utf-8"));return{...t.dependencies,...t.devDependencies}["socket.io-client"]?(await Bl(ws.join(e,"src/lib/utils/ws")),!0):!1}catch{return!1}},Ps={id:"ws",name:"WebSocket Client",description:"socket.io-client + lazy WS singleton + Redux slice + hooks",detect:Vl,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:Dt},{file:"src/providers/StoreProvider.tsx",description:"attachWsBridge mount in StoreProvider",presence:/attachWsBridge\(wsClient,\s*store\.dispatch\)/,removePattern:_t}],apply:O(xr,xs)};P();w();import _e from"node:path";var vs=async e=>{let t=_e.join(e,a.PACKAGE_JSON);return l(t)?JSON.parse(await g(t)):null},Jl=async(e,t)=>{let r=_e.join(e,a.PACKAGE_JSON);await h(r,`${JSON.stringify(t,null,2)}
1096
+ `)},Ss=(e,t)=>(t==="dependency"?e.dependencies:e.devDependencies)??{},Es=e=>[e.file,...e.alternativeFiles??[]],Je=async(e,t)=>{let r=await e.detect(t),i=[];if(!r)return{manifest:e,installed:!1,drift:[]};for(let o of e.files)o.required!==!1&&(l(_e.join(t,o.path))||i.push({kind:"missingFile",file:o.path}));let n=await vs(t);if(n){for(let s of e.packages)Ss(n,s.kind)[s.name]||i.push({kind:"missingPackage",name:s.name,depKind:s.kind});let o=n.scripts??{};for(let s of e.scripts){let c=o[s.name];c?s.expectedValue&&c!==s.expectedValue&&i.push({kind:"mismatchedScript",name:s.name,expected:s.expectedValue,actual:c}):i.push({kind:"missingScript",name:s.name,expected:s.expectedValue})}}for(let o of e.injections){let c=Es(o).filter(u=>l(_e.join(t,u)));if(c.length===0){i.push({kind:"missingInjection",file:o.file,description:o.description});continue}let p=!1;for(let u of c){let d=await g(_e.join(t,u));if(o.presence.test(d)){p=!0;break}}p||i.push({kind:"missingInjection",file:c[0],description:o.description})}return{manifest:e,installed:r,drift:i}},wr=async(e,t,r={})=>{let i=r.dryRun??!1,n={filesRemoved:[],packagesUninstalled:[],scriptsRemoved:[],blocksStripped:[],manualCleanup:[]};for(let c of e.injections)for(let p of Es(c)){let u=_e.join(t,p);if(!l(u))continue;if(!c.removePattern){n.manualCleanup.push({file:p,description:c.description});continue}let d=await g(u);if(!c.presence.test(d))continue;let f;if(typeof c.removePattern=="function"){let y=c.removePattern(d);if(y===null){n.manualCleanup.push({file:p,description:c.description});continue}f=y}else f=d.replace(c.removePattern,"");f!==d?(i||await h(u,f),n.blocksStripped.push({file:p,description:c.description})):n.manualCleanup.push({file:p,description:c.description})}let{rm:o}=await import("node:fs/promises");for(let c of e.files){if(!c.generated)continue;let p=_e.join(t,c.path);if(l(p)){if(c.containsUserContent){let u=c.removeHint?`${c.path} \u2014 ${c.removeHint}`:`${c.path} (may contain user-authored files; review before deleting)`;n.manualCleanup.push({file:c.path,description:u});continue}i||await o(p,{recursive:!0,force:!0}),n.filesRemoved.push(c.path)}}let s=await vs(t);if(s){let c=!1;if(s.scripts)for(let p of e.scripts)s.scripts[p.name]&&(i||delete s.scripts[p.name],n.scriptsRemoved.push(p.name),c=!0);for(let p of e.packages)Ss(s,p.kind)[p.name]&&n.packagesUninstalled.push(p.name);c&&!i&&await Jl(t,s)}if(!i&&n.packagesUninstalled.length>0){let c=await A(t);await Ir(t,c,n.packagesUninstalled)}return n};var Oe=[is,ds,go,Bo,mo,os,Co,Ao,Qo,Ps,Ho],Ts=e=>Oe.find(t=>t.id===e);var Cs=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 ${$.dim(e.expected)} but got ${$.dim(e.actual)}`;case"missingInjection":return`missing block in ${e.file}: ${e.description}`}},Wl=e=>{let t=e.filter(i=>i.installed),r=t.filter(i=>i.drift.length>0);return{installedCount:t.length,driftedCount:r.length,cleanCount:t.length-r.length,driftedResults:r}},ql={fixed:$.green("\u2713"),stillDrifted:$.red("\u2717"),noApply:$.yellow("\u26A0\uFE0F")},Xl={fixed:$.green("FIXED"),stillDrifted:$.red("STILL DRIFTED"),noApply:$.yellow("NO AUTOMATIC FIX AVAILABLE")},Yl=async(e,t)=>{let r=[];for(let i of e){let{manifest:n,drift:o}=i;if(!n.apply){r.push({id:n.id,name:n.name,status:"noApply",remaining:o});continue}let s;try{await n.apply(t,o)}catch(p){s=p instanceof Error?p.message:String(p)}let c=await Je(n,t);r.push({id:n.id,name:n.name,status:c.drift.length===0&&!s?"fixed":"stillDrifted",remaining:c.drift,error:s})}return r},Rs=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(),i=t.feature?Oe.filter(u=>u.id===t.feature):Oe;if(t.feature&&i.length===0)throw new Error(`Unknown feature "${t.feature}". Valid: ${Oe.map(u=>u.id).join(", ")}.`);let n=[];for(let u of i)n.push(await Je(u,r));t.json&&(m(JSON.stringify(n.map(u=>({id:u.manifest.id,name:u.manifest.name,installed:u.installed,drift:u.drift})),null,2)),process.exit(n.some(u=>u.drift.length>0)?1:0)),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")} ${Gp(d)}`)}let o=Up(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 u of n){let{manifest:d,installed:f,drift:y}=u;if(!f){m(` ${$.dim("\u2014")} ${$.dim(d.name)} ${$.dim("(not installed)")}`);continue}if(y.length===0){m(` ${$.green("\u2713")} ${d.name}`);continue}m(` ${$.yellow("!")} ${$.bold(d.name)} ${$.dim(`(${y.length} issue${y.length===1?"":"s"})`)}`);for(let I of y)m(` ${$.yellow("\u2022")} ${Cs(I)}`)}let o=Wl(n);m(""),m($.dim(`${o.cleanCount} clean, ${o.driftedCount} drifted, ${n.length-o.installedCount} not installed`)),o.driftedCount===0&&(m($.green(`
1099
1099
  \u2713 No drift detected.
1100
- `)),process.exit(0)),t.fix||(l(L.dim(`
1100
+ `)),process.exit(0)),t.fix||(m($.dim(`
1101
1101
  Run with --fix to re-apply drifted features.
1102
- `)),process.exit(1)),l(L.cyan(`
1102
+ `)),process.exit(1)),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(`
1105
- \u2713 Doctor finished.
1106
- `))}catch(r){v(`${r instanceof Error?r.message:r}`),process.exit(1)}})};import je from"picocolors";S();P();import jr from"node:path";var Hp=/^[A-Z][A-Z0-9_]*$/,zo=e=>{if(!Hp.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,Dr=e=>e.public?"client":"server",Bp=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,"\\'")}')`}},zp=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()"}},Vo=e=>{let t=pe(e.name,e.public),r=zp(e),n=e.default!==void 0,i=!e.required&&!n;if(n&&(r+=Bp(e)),i&&(r+=".optional()"),e.description){let o=e.description.replace(/'/g,"\\'");r+=`
1107
- .describe('${o}')`}return` ${t}: ${r},`},Jo=e=>{let t=pe(e.name,e.public);return` ${t}: process.env.${t},`},Vp=e=>new RegExp(`(${e}:\\s*\\{)([\\s\\S]*?)(\\n\\s*\\})`),Ho=/(runtimeEnv:\s*\{)([\s\S]*?)(\n\s*\})/,Bo=(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/,"")}`},Wo=(e,t)=>{let r=pe(t.name,t.public),n=Dr(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=Vp(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,u]=s,d=Vo(t),h=e.replace(o,Bo(a,p,u,d)),x=h.match(Ho);if(!x)throw new Error("Could not locate the `runtimeEnv: { \u2026 }` map in src/lib/env/index.ts.");let[,I,G,R]=x;return h=h.replace(Ho,Bo(I,G,R,Jo(t))),h},Jp="# -public",Wp=e=>{let t=pe(e.name,e.public),r=e.default??"",n=e.public?` ${Jp}`:"";return`${t}=${r}${n}`},qo=(e,t)=>{let r=pe(t.name,t.public);if(new RegExp(`^${r}=`,"m").test(e))return e;let i=e===""||e.endsWith(`
1104
+ `));let s=await Yl(o.driftedResults,r);m("");for(let u of s){m(` ${ql[u.status]} ${u.name} ${Xl[u.status]}`);for(let d of u.remaining)m(` ${$.yellow("\u2022")} ${Cs(d)}`);u.error&&m(` ${$.red("\u2022")} ${u.error}`)}let c=s.filter(u=>u.status==="fixed").length,p=s.length-c;m(""),m($.dim(`${c} fixed, ${p} still drifted`)),p>0&&(m($.yellow(`
1105
+ ! Doctor could not fix everything.
1106
+ `)),process.exit(1)),m($.green(`
1107
+ \u2713 All drift fixed.
1108
+ `)),process.exit(0)}catch(r){E(`${r instanceof Error?r.message:r}`),process.exit(1)}})};import We from"picocolors";P();w();import fi from"node:path";var Kl=/^[A-Z][A-Z0-9_]*$/,$s=e=>{if(!Kl.test(e))throw new Error(`Invalid env var name "${e}". Use UPPER_SNAKE_CASE (e.g. SENTRY_DSN, NEXT_PUBLIC_API_URL).`)},he=(e,t)=>t?e.startsWith("NEXT_PUBLIC_")?e:`NEXT_PUBLIC_${e}`:e,gi=e=>e.public?"client":"server",Zl=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,"\\'")}')`}},Ql=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(i=>`'${i.replace(/'/g,"\\'")}'`).join(", ")}])`}default:return"e.string()"}},ks=e=>{let t=he(e.name,e.public),r=Ql(e),i=e.default!==void 0,n=!e.required&&!i;if(i&&(r+=Zl(e)),n&&(r+=".optional()"),e.description){let o=e.description.replace(/'/g,"\\'");r+=`
1109
+ .describe('${o}')`}return` ${t}: ${r},`},Ns=e=>{let t=he(e.name,e.public);return` ${t}: process.env.${t},`},em=e=>new RegExp(`(${e}:\\s*\\{)([\\s\\S]*?)(\\n\\s*\\})`),bs=/(runtimeEnv:\s*\{)([\s\S]*?)(\n\s*\})/,Is=(e,t,r,i)=>{let n=t.replace(/\s+$/,""),o=n.length===0||/,\s*$/.test(n)?n:`${n},`;return`${e}${o}
1110
+ ${i}
1111
+ ${r.replace(/^\n/,"")}`},As=(e,t)=>{let r=he(t.name,t.public),i=gi(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=em(i),s=e.match(o);if(!s)throw new Error(`Could not locate the \`${i}: { \u2026 }\` group in src/lib/env/index.ts.`);let[,c,p,u]=s,d=ks(t),f=e.replace(o,Is(c,p,u,d)),y=f.match(bs);if(!y)throw new Error("Could not locate the `runtimeEnv: { \u2026 }` map in src/lib/env/index.ts.");let[,I,G,k]=y;return f=f.replace(bs,Is(I,G,k,Ns(t))),f},tm="# -public",rm=e=>{let t=he(e.name,e.public),r=e.default??"",i=e.public?` ${tm}`:"";return`${t}=${r}${i}`},Fs=(e,t)=>{let r=he(t.name,t.public);if(new RegExp(`^${r}=`,"m").test(e))return e;let n=e===""||e.endsWith(`
1110
1112
  `)?"":`
1111
1113
  `,o=e===""?"":`
1112
1114
  `,s=t.description?`# ${t.description}
1113
- `:"";return`${e}${i}${o}${s}${Wp(t)}
1114
- `},Xo=(e,t)=>{let r=pe(t.name,t.public);if(new RegExp(`^${r}=`,"m").test(e))return e;let i=e===""||e.endsWith(`
1115
+ `:"";return`${e}${n}${o}${s}${rm(t)}
1116
+ `},_s=(e,t)=>{let r=he(t.name,t.public);if(new RegExp(`^${r}=`,"m").test(e))return e;let n=e===""||e.endsWith(`
1115
1117
  `)?"":`
1116
- `,o=t.default??"";return`${e}${i}${r}=${o}
1117
- `},Lr=async(e,t)=>{zo(t.name);let r=jr.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 f(r),i=Wo(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=qo(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=Xo(d,t);u=h!==d,u&&await g(p,h)}return{schemaUpdated:o,envExampleUpdated:a,envUpdated:u,group:Dr(t)}};var Yo=new Set(["string","url","number","boolean","enum"]),qp=e=>{let t=(e??"string").toLowerCase();if(!Yo.has(t))throw new Error(`Invalid --type "${e}". Valid: ${Array.from(Yo).join(", ")}.`);return t},Xp=e=>{if(!e)return;let t=e.split(",").map(r=>r.trim()).filter(Boolean);return t.length===0?void 0:t},Ko=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
+ `,o=t.default??"";return`${e}${n}${r}=${o}
1119
+ `},hi=async(e,t)=>{$s(t.name);let r=fi.join(e,"src/lib/env/index.ts");if(!l(r))throw new Error("src/lib/env/index.ts not found \u2014 run `next-maker init` first.");let i=await g(r),n=As(i,t),o=n!==i;o&&await h(r,n);let s=fi.join(e,a.ENV_EXAMPLE),c=!1;if(l(s)){let d=await g(s),f=Fs(d,t);c=f!==d,c&&await h(s,f)}let p=fi.join(e,".env"),u=!1;if(l(p)){let d=await g(p),f=_s(d,t);u=f!==d,u&&await h(p,f)}return{schemaUpdated:o,envExampleUpdated:c,envUpdated:u,group:gi(t)}};var Os=new Set(["string","url","number","boolean","enum"]),im=e=>{let t=(e??"string").toLowerCase();if(!Os.has(t))throw new Error(`Invalid --type "${e}". Valid: ${Array.from(Os).join(", ")}.`);return t},nm=e=>{if(!e)return;let t=e.split(",").map(r=>r.trim()).filter(Boolean);return t.length===0?void 0:t},js=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 i=process.cwd();if(m(We.cyan(`
1118
1120
  \u{1F510} Env Var Generator
1119
- `)),r.required&&r.default!==void 0)throw new Error("--required and --default are mutually exclusive.");let i=qp(r.type),o=Xp(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 Lr(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 Yp from"enquirer";var{prompt:Kp}=Yp,Zo=async(e={})=>e.source?{source:e.source}:{source:(await Kp({type:"input",name:"source",message:"Path to source image (PNG/JPG/JPEG/SVG/WebP/AVIF):",validate:r=>r?!0:"Source path is required"})).source};import{access as Zp,readFile as Qp,stat as el}from"node:fs/promises";import Te from"node:path";var Qo=async e=>{try{return await Zp(e),!0}catch{return!1}},tl=async e=>{try{return(await el(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 tl(r))return r;return null},rl=["next-pwa","@ducanh2912/next-pwa","@serwist/next","serwist"],Mr=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 Qo(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 Qo(o)){t.appManifestPath=o,t.isPwa=!0;break}}try{let i=JSON.parse(await Qp(Te.join(e,"package.json"),"utf-8")),o={...i.dependencies,...i.devDependencies};for(let s of rl)if(o[s]){t.framework=s,t.isPwa=!0;break}}catch{}return t};import{mkdir as al,readFile as ps,stat as cl,writeFile as pl}from"node:fs/promises";import ie from"node:path";import ll from"sharp";import il from"png-to-ico";import ct from"sharp";var es=e=>e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;"),Gr=(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 nl(t)}},nl=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="${es(n)}" fill="white"/></svg>`},ts=(e,t)=>`<svg xmlns="http://www.w3.org/2000/svg" width="${e}" height="${e}"><rect width="${e}" height="${e}" fill="${es(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",x=await ct(u,{density:384}).resize(d,d,{fit:h,background:{r:0,g:0,b:0,alpha:0}}).png().toBuffer(),I=Math.round((t-d)/2),G=n==="transparent"?{r:0,g:0,b:0,alpha:0}:await Ur(n),R=await ct({create:{width:t,height:t,channels:4,background:G}}).composite([{input:x,left:I,top:I}]).png().toBuffer();if(!p&&(o!=="square"||i==="clip")){let mt=o==="square"?"rounded":o,Gs=Buffer.from(Gr(mt,t,s));R=await ct(R).composite([{input:Gs,blend:"dest-in"}]).png({compressionLevel:rs(a)}).toBuffer()}else R=await ct(R).png({compressionLevel:rs(a)}).toBuffer();return R},Ur=async e=>{let t=await ct(Buffer.from(ts(1,e))).raw().toBuffer({resolveWithObject:!0}),[r,n,i,o=255]=t.data;return{r,g:n,b:i,alpha:o/255}},rs=e=>{let t=Math.round((100-e)/100*9);return Math.max(0,Math.min(9,t))},ns=async e=>{if(e.length===0)throw new Error("No frames provided to encodeIco");return il(e)};import{readFile as ol,writeFile as sv}from"node:fs/promises";var is=e=>e.map(({src:t,size:r})=>({src:t,sizes:`${r}x${r}`,type:"image/png",purpose:"any maskable"})),os=async(e,t)=>{let r=await ol(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 ss=e=>`icons: [
1121
+ `)),r.required&&r.default!==void 0)throw new Error("--required and --default are mutually exclusive.");let n=im(r.type),o=nm(r.enum);if(n==="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:n,required:!!r.required,default:r.default,description:r.describe,enumValues:o,public:!!r.public};x.start("Updating src/lib/env/index.ts, .env.example, and .env...");let c=await hi(i,s);x.succeed("Env var written");let p=he(s.name,s.public);m(We.green(`
1122
+ \u2728 ${p} declared in the ${c.group} group.
1123
+ `)),m(We.dim("Touched:")),m(We.dim(` ${c.schemaUpdated?"\u270F\uFE0F ":"\u23ED "} src/lib/env/index.ts`)),m(We.dim(` ${c.envExampleUpdated?"\u270F\uFE0F ":"\u23ED "} .env.example`)),m(We.dim(` ${c.envUpdated?"\u270F\uFE0F ":"\u23ED "} .env`)),m("")}catch(i){x.fail("Env var declaration failed"),E(`${i instanceof Error?i.message:i}`),process.exit(1)}})};import Sr from"node:path";import De from"picocolors";import om from"enquirer";var{prompt:sm}=om,Ds=async(e={})=>e.source?{source:e.source}:{source:(await sm({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 am,readFile as cm,stat as pm}from"node:fs/promises";import je from"node:path";var Ls=async e=>{try{return await am(e),!0}catch{return!1}},lm=async e=>{try{return(await pm(e)).isDirectory()}catch{return!1}},Pr=async e=>{let t=[je.join(e,"src","app"),je.join(e,"app")];for(let r of t)if(await lm(r))return r;return null},mm=["next-pwa","@ducanh2912/next-pwa","@serwist/next","serwist"],yi=async e=>{let t={isPwa:!1},r=[je.join(e,"public","manifest.json"),je.join(e,"public","manifest.webmanifest"),je.join(e,"public","site.webmanifest")];for(let n of r)if(await Ls(n)){t.publicManifestPath=n,t.isPwa=!0;break}let i=await Pr(e);if(i)for(let n of["ts","tsx","js"]){let o=je.join(i,`manifest.${n}`);if(await Ls(o)){t.appManifestPath=o,t.isPwa=!0;break}}try{let n=JSON.parse(await cm(je.join(e,"package.json"),"utf-8")),o={...n.dependencies,...n.devDependencies};for(let s of mm)if(o[s]){t.framework=s,t.isPwa=!0;break}}catch{}return t};import{mkdir as hm,readFile as qs,stat as ym,writeFile as xm}from"node:fs/promises";import le from"node:path";import wm from"sharp";import um from"png-to-ico";import Ct from"sharp";var Ms=e=>e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;"),xi=(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 i=t/2;return`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}"><circle cx="${i}" cy="${i}" r="${i}" fill="white"/></svg>`}case"rounded":{let i=Math.round(t*r/100);return`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}"><rect width="${t}" height="${t}" rx="${i}" ry="${i}" fill="white"/></svg>`}case"squircle":return dm(t)}},dm=e=>{let t=e,r=t*.225,i=[`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="${Ms(i)}" fill="white"/></svg>`},Hs=(e,t)=>`<svg xmlns="http://www.w3.org/2000/svg" width="${e}" height="${e}"><rect width="${e}" height="${e}" fill="${Ms(t)}"/></svg>`;var qe=async e=>{let{size:t,paddingPercent:r,bg:i,fit:n,shape:o,radiusPercent:s,quality:c,forceSquare:p,sourceBuffer:u}=e,d=Math.max(1,Math.round(t*(1-r*2/100))),f=n==="cover"?"cover":"contain",y=await Ct(u,{density:384}).resize(d,d,{fit:f,background:{r:0,g:0,b:0,alpha:0}}).png().toBuffer(),I=Math.round((t-d)/2),G=i==="transparent"?{r:0,g:0,b:0,alpha:0}:await wi(i),k=await Ct({create:{width:t,height:t,channels:4,background:G}}).composite([{input:y,left:I,top:I}]).png().toBuffer();if(!p&&(o!=="square"||n==="clip")){let It=o==="square"?"rounded":o,Ca=Buffer.from(xi(It,t,s));k=await Ct(k).composite([{input:Ca,blend:"dest-in"}]).png({compressionLevel:Gs(c)}).toBuffer()}else k=await Ct(k).png({compressionLevel:Gs(c)}).toBuffer();return k},wi=async e=>{let t=await Ct(Buffer.from(Hs(1,e))).raw().toBuffer({resolveWithObject:!0}),[r,i,n,o=255]=t.data;return{r,g:i,b:n,alpha:o/255}},Gs=e=>{let t=Math.round((100-e)/100*9);return Math.max(0,Math.min(9,t))},Us=async e=>{if(e.length===0)throw new Error("No frames provided to encodeIco");return um(e)};import{readFile as fm,writeFile as UT}from"node:fs/promises";var Bs=e=>e.map(({src:t,size:r})=>({src:t,sizes:`${r}x${r}`,type:"image/png",purpose:"any maskable"})),zs=async(e,t)=>{let r=await fm(e,"utf-8"),i=JSON.parse(r),n=Array.isArray(i.icons)?i.icons:[],o=new Map;for(let s of[...n,...t])s&&typeof s.src=="string"&&o.set(s.src,s);return i.icons=[...o.values()],`${JSON.stringify(i,null,2)}
1124
+ `};var Vs=e=>`icons: [
1123
1125
  ${e.map(r=>` { src: '${r.src}', sizes: '${r.sizes}', type: '${r.type}'${r.purpose?`, purpose: '${r.purpose}'`:""} }`).join(`,
1124
1126
  `)},
1125
- ],`,as=(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 sl}from"node:fs/promises";import Hr from"node:path";var cs=[".png",".jpg",".jpeg",".webp",".svg",".avif"],Ht=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 sl(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(!cs.includes(n))throw new Error(`Unsupported source format '${n}'. Use one of: ${cs.join(", ")}`);return{absolutePath:t,ext:n,bytes:r.size,isVector:n===".svg"}};var Br=(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 ml=async e=>{try{return await cl(e),!0}catch{return!1}},dl=async(e,t,r)=>{let n=[];for(let i of e){if(await ml(i.outPath)&&!t&&!i.alwaysWrite){n.push({path:i.outPath,bytes:i.bytes.length,skipped:!0});continue}r||(await al(ie.dirname(i.outPath),{recursive:!0}),await pl(i.outPath,i.bytes)),n.push({path:i.outPath,bytes:i.bytes.length})}return n},zr=async(e,t)=>{let r=await Ht(t.source),n=await ps(r.absolutePath),i=t.ogSource?await ps((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 ns(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 ls(i,t,!1);o.push({outPath:ie.join(t.outDir,"opengraph-image.png"),bytes:d})}if(t.emitTwitter){let d=await ls(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 Mr(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],I=[];for(let R of x){let W=await De({sourceBuffer:n,size:R,shape:t.shape,radiusPercent:t.radius,bg:t.bg,paddingPercent:t.padding,fit:t.fit,quality:t.quality}),mt=`icon-${R}.png`;o.push({outPath:ie.join(h,mt),bytes:W}),I.push({src:`/${mt}`,size:R})}let G=is(I);if(d.publicManifestPath){let R=await os(d.publicManifestPath,G);o.push({outPath:d.publicManifestPath,bytes:Buffer.from(R,"utf-8"),alwaysWrite:!0})}else if(d.appManifestPath)p=ss(G);else if(t.pwaInit){let R=ie.join(h,"manifest.webmanifest"),W=as(ie.basename(e)||"App","#000000",G);o.push({outPath:R,bytes:Buffer.from(W,"utf-8")})}}return{outputs:await dl(o,t.force,t.dryRun),pwaSnippet:p}},ls=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 ll({create:{width:1200,height:i,channels:4,background:p}}).composite([{input:s,left:u,top:d}]).png().toBuffer()};var ms=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 ul=["square","rounded","circle","squircle"],fl=["contain","cover","clip"],ds=(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},Vr=(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},fs=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
+ ],`,Js=(e,t,r)=>`${JSON.stringify({name:e,short_name:e,start_url:"/",display:"standalone",background_color:"#ffffff",theme_color:t,icons:r},null,2)}
1128
+ `;import{stat as gm}from"node:fs/promises";import Pi from"node:path";var Ws=[".png",".jpg",".jpeg",".webp",".svg",".avif"],vr=async e=>{if(!e)throw new Error("Source image path is required (use --path).");let t=Pi.isAbsolute(e)?e:Pi.resolve(process.cwd(),e),r;try{r=await gm(t)}catch{throw new Error(`Source image not found: ${t}`)}if(!r.isFile())throw new Error(`Source is not a file: ${t}`);let i=Pi.extname(t).toLowerCase();if(!Ws.includes(i))throw new Error(`Unsupported source format '${i}'. Use one of: ${Ws.join(", ")}`);return{absolutePath:t,ext:i,bytes:r.size,isVector:i===".svg"}};var vi=(e,t)=>{if(!e)return t;let r=e.split(",").map(i=>Number.parseInt(i.trim(),10)).filter(i=>Number.isFinite(i)&&i>0&&i<=1024);if(r.length===0)throw new Error(`Invalid --sizes value: '${e}'. Provide comma-separated positive integers.`);return r};var Pm=async e=>{try{return await ym(e),!0}catch{return!1}},vm=async(e,t,r)=>{let i=[];for(let n of e){if(await Pm(n.outPath)&&!t&&!n.alwaysWrite){i.push({path:n.outPath,bytes:n.bytes.length,skipped:!0});continue}r||(await hm(le.dirname(n.outPath),{recursive:!0}),await xm(n.outPath,n.bytes)),i.push({path:n.outPath,bytes:n.bytes.length})}return i},Si=async(e,t)=>{let r=await vr(t.source),i=await qs(r.absolutePath),n=t.ogSource?await qs((await vr(t.ogSource)).absolutePath):i,o=[],s=[];for(let d of t.icoSizes)s.push(await qe({sourceBuffer:i,size:d,shape:"square",radiusPercent:t.radius,bg:t.bg,paddingPercent:t.padding,fit:t.fit,quality:t.quality,forceSquare:!0}));let c=await Us(s);if(o.push({outPath:le.join(t.outDir,"favicon.ico"),bytes:c}),t.emitIcon){let d=await qe({sourceBuffer:i,size:512,shape:t.shape,radiusPercent:t.radius,bg:t.bg,paddingPercent:t.padding,fit:t.fit,quality:t.quality});o.push({outPath:le.join(t.outDir,"icon.png"),bytes:d})}if(t.emitApple){let d=t.bg==="transparent"?"#ffffff":t.bg,f=await qe({sourceBuffer:i,size:180,shape:t.shape,radiusPercent:t.radius,bg:d,paddingPercent:t.padding,fit:t.fit,quality:t.quality});o.push({outPath:le.join(t.outDir,"apple-icon.png"),bytes:f})}if(t.emitOg){let d=await Xs(n,t,!1);o.push({outPath:le.join(t.outDir,"opengraph-image.png"),bytes:d})}if(t.emitTwitter){let d=await Xs(n,t,!0);o.push({outPath:le.join(t.outDir,"twitter-image.png"),bytes:d})}let p;if(t.pwa||t.pwaInit){let d=await yi(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 f=le.join(e,"public"),y=[192,512],I=[];for(let k of y){let K=await qe({sourceBuffer:i,size:k,shape:t.shape,radiusPercent:t.radius,bg:t.bg,paddingPercent:t.padding,fit:t.fit,quality:t.quality}),It=`icon-${k}.png`;o.push({outPath:le.join(f,It),bytes:K}),I.push({src:`/${It}`,size:k})}let G=Bs(I);if(d.publicManifestPath){let k=await zs(d.publicManifestPath,G);o.push({outPath:d.publicManifestPath,bytes:Buffer.from(k,"utf-8"),alwaysWrite:!0})}else if(d.appManifestPath)p=Vs(G);else if(t.pwaInit){let k=le.join(f,"manifest.webmanifest"),K=Js(le.basename(e)||"App","#000000",G);o.push({outPath:k,bytes:Buffer.from(K,"utf-8")})}}return{outputs:await vm(o,t.force,t.dryRun),pwaSnippet:p}},Xs=async(e,t,r)=>{let n=r?600:630,o=Math.round(Math.min(1200,n)*(1-t.padding*2/100)),s=await qe({sourceBuffer:e,size:o,shape:t.shape,radiusPercent:t.radius,bg:"transparent",paddingPercent:0,fit:t.fit,quality:t.quality}),c=t.bg==="transparent"?"#ffffff":t.bg,p=await wi(c),u=Math.round((1200-o)/2),d=Math.round((n-o)/2);return wm({create:{width:1200,height:n,channels:4,background:p}}).composite([{input:s,left:u,top:d}]).png().toBuffer()};var Ys=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 Sm=["square","rounded","circle","squircle"],Em=["contain","cover","clip"],Ks=(e,t,r,i)=>{if(!e)return r;if(!t.includes(e))throw new Error(`Invalid value for --${i}: '${e}'. Allowed: ${t.join(", ")}`);return e},Ei=(e,t,r,i,n)=>{if(e===void 0)return t;let o=Number(e);if(!Number.isFinite(o)||o<i||o>n)throw new Error(`Invalid value for --${r}: '${e}'. Must be a number between ${i}\u2013${n}.`);return o},Qs=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();m(De.cyan(`
1127
1129
  \u{1F3A8} Favicon Generator
1128
- `));let n=await Zo({source:t.path}),i=await gl(r,t.out),o=ds(t.shape,ul,"square","shape"),s=ds(t.fit,fl,"contain","fit"),a=Vr(t.radius,20,"radius",0,50),p=Vr(t.padding,0,"padding",0,30),u=Vr(t.quality,90,"quality",1,100),d=Br(t.sizes,[16,32,48]),h=t.bg??"transparent";xl(h);let x=t.all===!0,I={source:n.source,outDir:i,force:!!t.force,dryRun:!!t.dryRun,emitIcon:!!t.icon||x,emitApple:!!t.apple||x,emitOg:!!t.og||x,emitTwitter:!!t.twitter,ogSource:t.ogSource,pwa:!!t.pwa,pwaInit:!!t.pwaInit,shape:o,radius:a,bg:h,padding:p,fit:s,icoSizes:d,quality:u};y.start("Generating favicon assets...");let G=await zr(r,I);y.succeed(I.dryRun?"Favicon plan ready":"Favicon assets generated"),l("");for(let R of G.outputs){let W=Bt.relative(r,R.path);R.skipped?l(be.yellow(` \u21B7 skipped ${W} (exists; use --force to overwrite)`)):I.dryRun?l(be.dim(` \u{1F4C4} would write ${W} (${us(R.bytes)})`)):l(be.green(` \u2713 ${W} `)+be.dim(`(${us(R.bytes)})`))}G.pwaSnippet&&(l(""),l(be.cyan("Add this to your typed manifest (src/app/manifest.ts):")),l(be.dim(G.pwaSnippet))),l("")}catch(r){y.fail("Favicon generation failed");let n=r instanceof Error?r.message:String(r);v(n),process.exit(1)}})},gl=async(e,t)=>{if(t)return Bt.isAbsolute(t)?t:Bt.resolve(e,t);let r=await Ut(e);return r||(an("Could not detect app/ or src/app/ \u2014 falling back to src/app"),Bt.join(e,"src","app"))},hl=/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/,yl=/^(?:rgb|rgba|hsl|hsla)\(\s*[\d.,%\s/]+\)$/i,xl=e=>{if(e!=="transparent"&&!hl.test(e)&&!yl.test(e)&&!ms.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().`)},us=e=>e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(2)} MB`;import Ps from"node:path";import M from"picocolors";B();B();import Al from"node:path";import{readFile as Pl,writeFile as wl}from"node:fs/promises";import vl from"node:path";var pt=async e=>{let{serviceName:t,projectPath:r}=e,n=j(t),i=vl.join(r,"src","lib","config","app-apis.ts");try{let o=await Pl(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}: {
1130
+ `));let i=await Ds({source:t.path}),n=await Tm(r,t.out),o=Ks(t.shape,Sm,"square","shape"),s=Ks(t.fit,Em,"contain","fit"),c=Ei(t.radius,20,"radius",0,50),p=Ei(t.padding,0,"padding",0,30),u=Ei(t.quality,90,"quality",1,100),d=vi(t.sizes,[16,32,48]),f=t.bg??"transparent";bm(f);let y=t.all===!0,I={source:i.source,outDir:n,force:!!t.force,dryRun:!!t.dryRun,emitIcon:!!t.icon||y,emitApple:!!t.apple||y,emitOg:!!t.og||y,emitTwitter:!!t.twitter,ogSource:t.ogSource,pwa:!!t.pwa,pwaInit:!!t.pwaInit,shape:o,radius:c,bg:f,padding:p,fit:s,icoSizes:d,quality:u};x.start("Generating favicon assets...");let G=await Si(r,I);x.succeed(I.dryRun?"Favicon plan ready":"Favicon assets generated"),m("");for(let k of G.outputs){let K=Sr.relative(r,k.path);k.skipped?m(De.yellow(` \u21B7 skipped ${K} (exists; use --force to overwrite)`)):I.dryRun?m(De.dim(` \u{1F4C4} would write ${K} (${Zs(k.bytes)})`)):m(De.green(` \u2713 ${K} `)+De.dim(`(${Zs(k.bytes)})`))}G.pwaSnippet&&(m(""),m(De.cyan("Add this to your typed manifest (src/app/manifest.ts):")),m(De.dim(G.pwaSnippet))),m("")}catch(r){x.fail("Favicon generation failed");let i=r instanceof Error?r.message:String(r);E(i),process.exit(1)}})},Tm=async(e,t)=>{if(t)return Sr.isAbsolute(t)?t:Sr.resolve(e,t);let r=await Pr(e);return r||(Li("Could not detect app/ or src/app/ \u2014 falling back to src/app"),Sr.join(e,"src","app"))},Cm=/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/,Rm=/^(?:rgb|rgba|hsl|hsla)\(\s*[\d.,%\s/]+\)$/i,bm=e=>{if(e!=="transparent"&&!Cm.test(e)&&!Rm.test(e)&&!Ys.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().`)},Zs=e=>e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(2)} MB`;import na from"node:path";import V from"picocolors";W();W();import Gm from"node:path";import{readFile as Im,writeFile as $m}from"node:fs/promises";import km from"node:path";var Rt=async e=>{let{serviceName:t,projectPath:r}=e,i=H(t),n=km.join(r,"src","lib","config","app-apis.ts");try{let o=await Im(n,"utf-8");if(o.includes(`${i}:`))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=` ${i}: {
1129
1131
  base: '/${t}',
1130
1132
  getAll: '/${t}',
1131
- },`;o=Je(o,s),await wl(i,o)}catch(o){throw new Error(`Failed to register API endpoints: ${o}`,{cause:o})}};import{readFile as Sl,writeFile as El}from"node:fs/promises";import Cl from"node:path";P();var Jr=async(e,t,r)=>{let n=Cl.join(e,"src","lib","config","app-paths.ts");if(!m(n))return;let i=await Sl(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 El(n,i)};S();P();import zt from"node:path";var Tl=e=>new RegExp(`<\\s*${e}\\b`),gs=(e,t)=>{if(Tl(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
+ },`;o=rt(o,s),await $m(n,o)}catch(o){throw new Error(`Failed to register API endpoints: ${o}`,{cause:o})}};import{readFile as Nm,writeFile as Am}from"node:fs/promises";import Fm from"node:path";w();var Ti=async(e,t,r)=>{let i=Fm.join(e,"src","lib","config","app-paths.ts");if(!l(i))return;let n=await Nm(i,"utf-8"),o=H(t);if(n.includes(`${o}:`))return;let s=n.lastIndexOf("} as const;");if(s===-1)return;let c=` ${o}: '${r}',
1134
+ `;n=n.slice(0,s)+c+n.slice(s),await Am(i,n)};P();w();import Er from"node:path";var _m=e=>new RegExp(`<\\s*${e}\\b`),ea=(e,t)=>{if(_m(t).test(e))return e;let r=/^(?<indent>[ \t]*)\{children\}\s*$/m,i=e.match(r);if(!i||i.index===void 0)throw new Error("Could not locate `{children}` line in RootProvider \u2014 expected a line containing only `{children}`.");let n=i.groups?.indent??"",o=`${n} `,s=`${n}<${t}>
1133
1135
  ${o}{children}
1134
- ${i}</${t}>`;return e.replace(r,s)},hs=(e,t)=>{let r=`export * from './${t}';`;if(e.includes(r))return e;let n=e.split(`
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,x)=>x>a&&!/^export \* from '\.\//.test(h)),d=u===-1?[]:n.slice(u);return[...p,...s,...d].join(`
1137
- `)},bl=c.PROVIDERS,Rl=c.ROOT_PROVIDER,$l=c.PROVIDERS_INDEX,ys=async(e,t={fileExists:m,readFile:f})=>{let r=zt.join(e,Rl);if(t.fileExists(r))return r;let n=zt.join(e,bl);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 x=((d.split("{children}")[0]??"").match(/<[A-Z][A-Za-z0-9_]*\b/g)??[]).length;(!a||x>a.depth)&&(a={file:u,depth:x})}return a?.file??null},Wr=async e=>{let{projectPath:t,componentName:r,fileBaseName:n}=e,i=await ys(t);if(i){let a=await f(i),p=a;(!/from '\.\//.test(a)||!a.includes(`{ ${r} }`))&&(p=Ve(p,`import { ${r} } from './${n}';`)),p=gs(p,r),p!==a&&await g(i,p)}let o=zt.join(t,$l),s=null;if(m(o)){let a=await f(o),p=hs(a,n);p!==a&&await g(o,p),s=o}return{rootProviderFile:i,barrelFile:s}};P();import{readFile as Il,writeFile as Nl}from"node:fs/promises";import kl from"node:path";var qr=async(e,t)=>{let r=kl.join(e,"src","i18n","translations","en.json");if(!m(r))return;let n=await Il(r,"utf-8"),i=JSON.parse(n);i[t]||(i[t]={title:t,description:`${t} page description`},await Nl(r,`${JSON.stringify(i,null,2)}
1138
- `))};var Xr=()=>[{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:Al.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 Yr=()=>[{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 _l from"node:path";var Kr=()=>[{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:_l.join(e.basePath,e.sliceName)})}}];import Ol from"enquirer";var{prompt:Fl}=Ol,xs=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 Fl(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 ws=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();jl(r),l(M.cyan(`
1136
+ ${n}</${t}>`;return e.replace(r,s)},ta=(e,t)=>{let r=`export * from './${t}';`;if(e.includes(r))return e;let i=e.split(`
1137
+ `),n=[],o=[];for(let f of i)/^export \* from '\.\/.*';\s*$/.test(f)?n.push(f):o.push(f);let s=[...n,r].sort(),c=i.findIndex(f=>/^export \* from '\.\//.test(f));if(c===-1)return`${r}
1138
+ ${e.replace(/^\n+/,"")}`;let p=i.slice(0,c),u=i.findIndex((f,y)=>y>c&&!/^export \* from '\.\//.test(f)),d=u===-1?[]:i.slice(u);return[...p,...s,...d].join(`
1139
+ `)},Om=a.PROVIDERS,jm=a.ROOT_PROVIDER,Dm=a.PROVIDERS_INDEX,ra=async(e,t={fileExists:l,readFile:g})=>{let r=Er.join(e,jm);if(t.fileExists(r))return r;let i=Er.join(e,Om);if(!t.fileExists(i))return null;let{readdir:n}=await import("node:fs/promises"),s=(await n(i).catch(()=>[])).filter(p=>p.endsWith(".tsx")),c=null;for(let p of s){let u=Er.join(i,p),d=await t.readFile(u);if(!/\{children\}/.test(d))continue;let y=((d.split("{children}")[0]??"").match(/<[A-Z][A-Za-z0-9_]*\b/g)??[]).length;(!c||y>c.depth)&&(c={file:u,depth:y})}return c?.file??null},Ci=async e=>{let{projectPath:t,componentName:r,fileBaseName:i}=e,n=await ra(t);if(n){let c=await g(n),p=c;(!/from '\.\//.test(c)||!c.includes(`{ ${r} }`))&&(p=tt(p,`import { ${r} } from './${i}';`)),p=ea(p,r),p!==c&&await h(n,p)}let o=Er.join(t,Dm),s=null;if(l(o)){let c=await g(o),p=ta(c,i);p!==c&&await h(o,p),s=o}return{rootProviderFile:n,barrelFile:s}};w();import{readFile as Lm,writeFile as Mm}from"node:fs/promises";import Hm from"node:path";var Ri=async(e,t)=>{let r=Hm.join(e,"src","i18n","translations","en.json");if(!l(r))return;let i=await Lm(r,"utf-8"),n=JSON.parse(i);n[t]||(n[t]={title:t,description:`${t} page description`},await Mm(r,`${JSON.stringify(n,null,2)}
1140
+ `))};var bi=()=>[{name:"Project setup detected",spinnerText:"Detecting project setup...",execute:async e=>{e.detection=await M(e.projectPath)}},{name:"Feature files generated",spinnerText:"Generating feature files...",execute:async e=>{await Jr({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 Rt({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 $e({projectPath:e.projectPath,name:e.featureName,persist:e.persistStore,importPath:Gm.join(e.basePath,e.featureName,"store")})}}];var Le=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(i){throw t.spinner.fail(r.name),i}}};var Ii=()=>[{name:"Service files generated",spinnerText:"Generating service files...",execute:async e=>{await at({name:e.serviceName,outputPath:e.servicePath,httpClient:e.httpClient})}},{name:"API endpoints registered",spinnerText:"Registering API endpoints...",execute:async e=>{await Rt({serviceName:e.serviceName,projectPath:e.projectPath})}}];import Um from"node:path";var $i=()=>[{name:"Slice files generated",spinnerText:"Generating slice files...",execute:async e=>{await lt({name:e.sliceName,outputPath:e.slicePath,persist:e.persistSlice})}},{name:"Slice registered in rootReducer",spinnerText:"Registering slice in rootReducer...",execute:async e=>{await $e({projectPath:e.projectPath,name:e.sliceName,persist:e.persistSlice,importPath:Um.join(e.basePath,e.sliceName)})}}];import Bm from"enquirer";var{prompt:zm}=Bm,ia=async(e,t,r,i,n,o,s)=>{let c=[];e||c.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&&i===void 0&&n===void 0&&(c.push({type:"confirm",name:"createStore",message:"Generate Redux store for this feature?",initial:!0}),c.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&&(c.push({type:"confirm",name:"createService",message:"Generate API service for this feature?",initial:!0}),r==="both"&&c.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=c.length>0?await zm(c):{};return{featureName:e||p.featureName,hasRedux:t||!1,createStore:i===!0?!1:n!==void 0?!0:p.createStore||!1,persistStore:n==="persist"?!0:n==="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 oa=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 i=process.cwd();Vm(r),m(V.cyan(`
1139
1141
  \u{1F3AF} Feature Generator
1140
- `));let i=Xr();y.start("Detecting project setup...");let{detectProjectSetup:o}=await Promise.resolve().then(()=>(B(),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 xs(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||Ps.join("src","features"),u=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:u,createStore:a.createStore,persistStore:a.persistStore,createService:a.createService,httpClient:a.selectedHttpClient,detection:s}),Dl(a,p)}catch(n){y.fail("Feature generation failed"),v(`${n}`),process.exit(1)}})},jl=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))},Dl=(e,t)=>{let r=Ps.join(t,e.featureName);l(M.green(`
1142
+ `));let n=bi();x.start("Detecting project setup...");let{detectProjectSetup:o}=await Promise.resolve().then(()=>(W(),st)),s=await o(i);x.succeed("Project setup detected"),m(V.dim(` Redux: ${s.hasRedux?"\u2713":"\u2717"}`)),m(V.dim(` HTTP Client: ${s.httpClient}`)),m(V.dim(` i18n: ${s.hasI18n?"\u2713":"\u2717"}
1143
+ `));let c=await ia(t,s.hasRedux,s.httpClient,r.skipStore,r.store,r.skipService,r.service);J(c.featureName,"feature name"),r.path&&ce(r.path,"path");let p=r.path||na.join("src","features"),u=Mt(i,p,c.featureName);await ve(i,c.featureName,p)&&(E(`Feature '${c.featureName}' already exists at ${p}!`),process.exit(1)),await Le(n.slice(1),{projectPath:i,spinner:x,featureName:c.featureName,basePath:p,featurePath:u,createStore:c.createStore,persistStore:c.persistStore,createService:c.createService,httpClient:c.selectedHttpClient,detection:s}),Jm(c,p)}catch(i){x.fail("Feature generation failed"),E(`${i}`),process.exit(1)}})},Vm=e=>{e.store&&!["persist","no-persist"].includes(e.store)&&(E("Invalid --store option. Use: persist or no-persist"),process.exit(1)),e.service&&!["axios","fetch"].includes(e.service)&&(E("Invalid --service option. Use: axios or fetch"),process.exit(1)),e.skipStore&&e.store&&(E("Cannot use --skip-store and --store together"),process.exit(1)),e.skipService&&e.service&&(E("Cannot use --skip-service and --service together"),process.exit(1))},Jm=(e,t)=>{let r=na.join(t,e.featureName);m(V.green(`
1142
1144
  \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 Zr from"node:path";import Le from"picocolors";B();import Ll from"enquirer";var{prompt:Ml}=Ll,vs=async e=>e?{hookName:e}:await Ml({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 Ss=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
+ `)),m(V.dim("Generated files:")),m(V.dim(` \u{1F4C2} ${r}/`)),m(V.dim(" \u251C\u2500\u2500 components/")),m(V.dim(" \u251C\u2500\u2500 hooks/")),m(V.dim(" \u251C\u2500\u2500 types/")),e.createStore&&m(V.dim(" \u251C\u2500\u2500 store/")),e.createService&&m(V.dim(" \u251C\u2500\u2500 services/")),m(V.dim(` \u2514\u2500\u2500 index.ts
1146
+ `)),m(V.cyan("Next steps:"));let i=t.replace(/^src\//,"@/");m(V.dim(` 1. Import and use the feature: import { ${e.featureName} } from '${i}/${e.featureName}'`)),e.createStore&&m(V.dim(` 2. Customize your Redux slice in: ${r}/store/`)),e.createService&&m(V.dim(` 3. Add API methods in: ${r}/services/${e.featureName}.service.ts`)),m("")};import ki from"node:path";import Xe from"picocolors";W();import Wm from"enquirer";var{prompt:qm}=Wm,sa=async e=>e?{hookName:e}:await qm({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 aa=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 i=process.cwd();m(Xe.cyan(`
1145
1147
  \u{1FA9D} Hook Generator
1146
- `));let i=await F(n),o=await vs(t);H(o.hookName,"hook name"),r.feature&&re(r.feature,"feature path");let a=`use${$(o.hookName)}`,p=Gl(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?Zr.join(n,r.feature,"hooks",`${a}.ts`):Zr.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(`
1147
- \u2728 Hook '${a}' created successfully!
1148
- `)),l(Le.dim(` \u{1F4C4} ${h}`)),d&&l(Le.dim(` \u{1F9EA} ${Zr.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)}})},Gl=(e,t)=>e.test===!1?!1:e.test===!0?!0:t;import Vt from"picocolors";B();var Es=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(`
1148
+ `));let n=await M(i),o=await sa(t);J(o.hookName,"hook name"),r.feature&&ce(r.feature,"feature path");let c=`use${N(o.hookName)}`,p=Xm(r,n.hasTests);x.start("Generating hook..."),await qr({name:o.hookName,projectPath:i,isClient:r.client??!0,featurePath:r.feature}),x.succeed("Hook generated");let u=r.feature?ki.join(i,r.feature,"hooks",`${c}.ts`):ki.join(i,"src/hooks",`${c}.ts`),d=null;p&&(x.start("Generating test..."),d=await fe({projectPath:i,sourceFile:u,kind:"hook",symbolName:c,hookUsesStore:n.hasRedux&&!!r.feature}),x.succeed("Test generated"));let f=r.feature?`${r.feature}/hooks/${c}.ts`:`src/hooks/${c}.ts`;m(Xe.green(`
1149
+ \u2728 Hook '${c}' created successfully!
1150
+ `)),m(Xe.dim(` \u{1F4C4} ${f}`)),d&&m(Xe.dim(` \u{1F9EA} ${ki.relative(i,d)}`)),m(""),m(Xe.cyan("Usage:"));let y=r.feature?`${r.feature.replace(/^src\//,"@/")}/hooks/${c}`:`@/hooks/${c}`;m(Xe.dim(` import { ${c} } from '${y}';`)),m("")}catch(i){x.fail("Hook generation failed"),E(`${i}`),process.exit(1)}})},Xm=(e,t)=>e.test===!1?!1:e.test===!0?!0:t;import Tr from"picocolors";W();var ca=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 i=process.cwd();m(Tr.cyan(`
1149
1151
  \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(Vt.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(Vt.green(`
1152
+ `)),x.start("Detecting project setup...");let n=await M(i);x.succeed("Project setup detected");let o=n.hasI18n&&r.locale!==!1;m(Tr.dim(` i18n: ${o?"\u2713":"\u2717"}
1153
+ `)),x.start("Generating layout...");let s=await Xr({segment:t,at:r.at,projectPath:i,hasI18n:o,withGroup:!!r.group});x.succeed("Layout generated"),m(Tr.green(`
1152
1154
  \u2728 ${s.componentName} created!
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 Ul from"enquirer";var{prompt:Hl}=Ul,Cs=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 Hl(r);return{code:e??n.code,name:n.name,country:n.country,flag:n.flag,copyTranslations:t.copyTranslations??n.copyTranslations??!1}};var Ts=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(`
1155
+ `)),m(Tr.dim(` \u{1F4C4} ${s.displayPath}`)),m("")}catch(i){x.fail("Layout generation failed"),E(`${i instanceof Error?i.message:i}`),process.exit(1)}})};import me from"picocolors";w();W();import Ym from"enquirer";var{prompt:Km}=Ym,pa=async(e,t={})=>{let r=[];e||r.push({type:"input",name:"code",message:"Locale code (e.g., es, fr, de):",validate:n=>n?/^[a-z]{2}(-[A-Z]{2})?$/.test(n)?!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:n=>n?!0:"Language name is required"},{type:"input",name:"country",message:"Country (e.g., Spain, France):",validate:n=>n?!0:"Country is required"},{type:"input",name:"flag",message:"Flag emoji (e.g., \u{1F1EA}\u{1F1F8}, \u{1F1EB}\u{1F1F7}):",validate:n=>n?!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 i=await Km(r);return{code:e??i.code,name:i.name,country:i.country,flag:i.flag,copyTranslations:t.copyTranslations??i.copyTranslations??!1}};var la=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 i=process.cwd();m(me.cyan(`
1154
1156
  \u{1F30D} Locale Generator
1155
- `)),y.start("Detecting project setup...");let i=await F(n);y.succeed("Project setup detected"),i.hasI18n||(y.fail("i18n is not set up in this project"),v("Please set up internationalization first"),l(oe.dim(`
1157
+ `)),x.start("Detecting project setup...");let n=await M(i);x.succeed("Project setup detected"),n.hasI18n||(x.fail("i18n is not set up in this project"),E("Please set up internationalization first"),m(me.dim(`
1156
1158
  Run: npx @teispace/next-maker setup --i18n
1157
- `)),process.exit(1));let o=await Cs(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(`
1159
+ `)),process.exit(1));let o=await pa(t,{copyTranslations:r.copyTranslations});J(o.code,"locale code");let s=Mt(i,"src","i18n","translations",`${o.code}.json`);l(s)&&(E(`Locale '${o.code}' already exists!`),process.exit(1)),x.start("Adding locale..."),await Yr({...o,projectPath:i}),x.succeed("Locale added"),m(me.green(`
1158
1160
  \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 Rs from"node:path";import Z from"picocolors";B();import Bl from"enquirer";var{prompt:zl}=Bl,bs=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 zl(r):{};return{pageName:e??n.pageName,withLoading:t.loading??n.withLoading??!0,withError:t.error??n.withError??!0}};var $s=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(`
1161
+ `)),m(me.dim("Updated files:")),m(me.dim(` \u{1F4C4} src/i18n/translations/${o.code}.json`)),m(me.dim(" \u{1F4DD} src/types/i18n.ts (SupportedLocale type)")),m(me.dim(" \u{1F4DD} src/lib/config/app-locales.ts")),m(""),m(me.cyan("Next steps:")),m(me.dim(` 1. Translate: src/i18n/translations/${o.code}.json`)),m(me.dim(` 2. Visit: http://localhost:3000/${o.code}`)),m("")}catch(i){x.fail("Locale generation failed"),E(`${i}`),process.exit(1)}})};import da from"node:path";import ie from"picocolors";W();import Zm from"enquirer";var{prompt:Qm}=Zm,ma=async(e,t={})=>{let r=[];e||r.push({type:"input",name:"pageName",message:"Page name (kebab-case):",validate:n=>n?/^[a-z][a-z0-9-]*$/.test(n)?!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 i=r.length>0?await Qm(r):{};return{pageName:e??i.pageName,withLoading:t.loading??i.withLoading??!0,withError:t.error??i.withError??!0}};var ua=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 i=process.cwd();m(ie.cyan(`
1160
1162
  \u{1F4C4} Page Generator
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 bs(t,{loading:r.loading,error:r.error}),s=o.pageName;H(s,"page name"),r.dynamic&&H(r.dynamic,"dynamic param");let a=$(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 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 qr(n,a),y.succeed("Translation namespace added"));let h=r.dynamic?Rs.join(p,s,`[${r.dynamic}]`):Rs.join(p,s);l(Z.green(`
1163
+ `)),x.start("Detecting project setup...");let n=await M(i);x.succeed("Project setup detected"),m(ie.dim(` i18n: ${n.hasI18n?"\u2713":"\u2717"}
1164
+ `));let o=await ma(t,{loading:r.loading,error:r.error}),s=o.pageName;J(s,"page name"),r.dynamic&&J(r.dynamic,"dynamic param");let c=N(s),p=n.hasI18n?"src/app/[locale]":"src/app";await ve(i,s,p)&&(E(`Page '${s}' already exists at ${p}/${s}!`),process.exit(1)),x.start("Generating page files..."),await Zr({name:s,projectPath:i,hasI18n:n.hasI18n,dynamic:r.dynamic,withLoading:r.loading??o.withLoading,withError:r.error??o.withError}),x.succeed("Page files generated"),x.start("Registering route...");let d=r.dynamic?`/${s}/[${r.dynamic}]`:`/${s}`;await Ti(i,s,d),x.succeed("Route registered"),n.hasI18n&&(x.start("Adding translation namespace..."),await Ri(i,c),x.succeed("Translation namespace added"));let f=r.dynamic?da.join(p,s,`[${r.dynamic}]`):da.join(p,s);m(ie.green(`
1163
1165
  \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 Qr from"node:path";import he from"picocolors";var Is=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(`
1166
+ `)),m(ie.dim("Generated files:")),m(ie.dim(` \u{1F4C2} ${f}/`)),m(ie.dim(" \u251C\u2500\u2500 page.tsx")),(r.loading??o.withLoading)&&m(ie.dim(" \u251C\u2500\u2500 loading.tsx")),(r.error??o.withError)&&m(ie.dim(" \u2514\u2500\u2500 error.tsx")),m(""),n.hasI18n&&(m(ie.cyan("Next steps:")),m(ie.dim(` 1. Add translations in: src/i18n/translations/en.json \u2192 "${c}"`)),m(ie.dim(` 2. Visit: http://localhost:3000/${s}`)),m(""))}catch(i){x.fail("Page generation failed"),E(`${i}`),process.exit(1)}})};import Ni from"node:path";import Ce from"picocolors";var fa=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();m(Ce.cyan(`
1165
1167
  \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 Wr({projectPath:r,componentName:n,fileBaseName:i});y.succeed("Provider registered"),l(he.green(`
1167
- \u2728 ${n} created!
1168
- `)),l(he.dim("Generated files:")),l(he.dim(` \u{1F4C4} ${Qr.relative(r,o)}`)),s?l(he.dim(` \u270F\uFE0F ${Qr.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 ${Qr.relative(r,a)} \u2014 added re-export`)),l("")}catch(r){y.fail("Provider generation failed"),v(`${r instanceof Error?r.message:r}`),process.exit(1)}})};import Vl from"enquirer";import z from"picocolors";var{prompt:Jl}=Vl,Wl=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},ql=e=>e.filesRemoved.length===0&&e.blocksStripped.length===0&&e.scriptsRemoved.length===0&&e.packagesUninstalled.length===0&&e.manualCleanup.length===0,Ns=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=Go(t);if(!i)throw new Error(`Unknown feature "${t}". Valid: ${Ce.map(p=>p.id).join(", ")}.`);if(l(z.cyan(`
1170
- \u{1F5D1} Remove ${i.name}
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"),ql(s)){l(z.yellow(`
1168
+ `)),x.start("Generating provider...");let{componentName:i,fileBaseName:n,providerFile:o}=await ei({name:t,projectPath:r});x.succeed("Provider generated"),x.start("Registering provider in RootProvider and barrel...");let{rootProviderFile:s,barrelFile:c}=await Ci({projectPath:r,componentName:i,fileBaseName:n});x.succeed("Provider registered"),m(Ce.green(`
1169
+ \u2728 ${i} created!
1170
+ `)),m(Ce.dim("Generated files:")),m(Ce.dim(` \u{1F4C4} ${Ni.relative(r,o)}`)),s?m(Ce.dim(` \u270F\uFE0F ${Ni.relative(r,s)} \u2014 wrapped {children}`)):(m(Ce.yellow(`
1171
+ \u26A0\uFE0F Could not locate a RootProvider file. Wire the new provider manually:`)),m(Ce.dim(` <${i}>{children}</${i}>`))),c&&m(Ce.dim(` \u270F\uFE0F ${Ni.relative(r,c)} \u2014 added re-export`)),m("")}catch(r){x.fail("Provider generation failed"),E(`${r instanceof Error?r.message:r}`),process.exit(1)}})};import ed from"enquirer";import q from"picocolors";var{prompt:td}=ed,rd=e=>{let t=[];for(let r of e.filesRemoved)t.push(` ${q.red("-")} delete: ${r}`);for(let r of e.blocksStripped)t.push(` ${q.red("-")} strip block: ${r.description} ${q.dim(`(${r.file})`)}`);for(let r of e.scriptsRemoved)t.push(` ${q.red("-")} remove script: ${r}`);for(let r of e.packagesUninstalled)t.push(` ${q.red("-")} uninstall: ${r}`);for(let r of e.manualCleanup)t.push(` ${q.yellow("?")} manual cleanup: ${r.description} ${q.dim(`(${r.file})`)}`);return t},id=e=>e.filesRemoved.length===0&&e.blocksStripped.length===0&&e.scriptsRemoved.length===0&&e.packagesUninstalled.length===0&&e.manualCleanup.length===0,ga=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 i=process.cwd(),n=Ts(t);if(!n)throw new Error(`Unknown feature "${t}". Valid: ${Oe.map(p=>p.id).join(", ")}.`);if(m(q.cyan(`
1172
+ \u{1F5D1} Remove ${n.name}
1173
+ `)),!(await Je(n,i)).installed){m(q.dim(`${n.name} is not installed \u2014 nothing to remove.`));return}x.start("Computing changes...");let s=await wr(n,i,{dryRun:!0});if(x.succeed("Computed plan"),id(s)){m(q.yellow(`
1172
1174
  \u26A0\uFE0F Manifest had no removable artifacts. Nothing to do.
1173
- `));return}l(z.bold(`
1175
+ `));return}m(q.bold(`
1174
1176
  Planned changes:
1175
- `));for(let p of Wl(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 Jl({type:"confirm",name:"confirm",message:`Apply the changes above to remove ${i.name}?`,initial:!1});if(!p){l(z.yellow(`
1177
+ `));for(let p of rd(s))m(p);if(m(""),r.dryRun){m(q.dim(`--dry-run set \u2014 exiting without writing.
1178
+ `));return}if(!r.yes){let{confirm:p}=await td({type:"confirm",name:"confirm",message:`Apply the changes above to remove ${n.name}?`,initial:!1});if(!p){m(q.yellow(`
1177
1179
  Aborted.
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 Zl}from"node:fs";import{mkdir as Ql}from"node:fs/promises";import lt from"node:path";import Q from"picocolors";B();import{readFile as Xl,writeFile as Yl}from"node:fs/promises";import Kl from"node:path";var ks=async(e,t)=>{let r=j(t),n=Kl.join(e,"src","lib","config","app-apis.ts");try{let i=await Xl(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=si({camelName:r,kebabName:t});i=Je(i,o),await Yl(n,i)}catch(i){throw new Error(`Failed to register CRUD API endpoints: ${i}`,{cause:i})}};import As from"enquirer";var _s=async(e,t,r,n)=>{let i=e||(await As.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 As.prompt({type:"select",name:"httpClient",message:"Choose HTTP client:",choices:["axios","fetch"]})).httpClient:o="axios",{serviceName:i,httpClient:o}};var Os=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(`
1180
+ `));return}}x.start(`Removing ${n.name}...`);let c;if(n.remove?(await n.remove(i),c=s):c=await wr(n,i),x.succeed(`${n.name} removed`),m(q.green(`
1181
+ \u2713 ${n.name} removed.`)),c.manualCleanup.length>0){m(q.yellow(`
1182
+ \u26A0\uFE0F Manual cleanup still required:`));for(let p of c.manualCleanup)m(` - ${p.description} (${p.file})`)}m("")}catch(i){x.fail("Remove failed"),E(`${i instanceof Error?i.message:i}`),process.exit(1)}})};import{existsSync as ad}from"node:fs";import{mkdir as cd}from"node:fs/promises";import bt from"node:path";import ne from"picocolors";W();import{readFile as nd,writeFile as od}from"node:fs/promises";import sd from"node:path";var ha=async(e,t)=>{let r=H(t),i=sd.join(e,"src","lib","config","app-apis.ts");try{let n=await nd(i,"utf-8");if(n.includes(`${r}:`))return;if(!n.match(/export const AppApis = \{[\s\S]*?\} as const;/))throw new Error("Could not find AppApis object in app-apis.ts");let o=On({camelName:r,kebabName:t});n=rt(n,o),await od(i,n)}catch(n){throw new Error(`Failed to register CRUD API endpoints: ${n}`,{cause:n})}};import ya from"enquirer";var xa=async(e,t,r,i)=>{let n=e||(await ya.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":i==="axios"?o="axios":i==="fetch"?o="fetch":i==="both"?o=(await ya.prompt({type:"select",name:"httpClient",message:"Choose HTTP client:",choices:["axios","fetch"]})).httpClient:o="axios",{serviceName:n,httpClient:o}};var wa=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 i=process.cwd();r.axios&&r.fetch&&(E("Cannot use --axios and --fetch together"),process.exit(1)),m(ne.cyan(`
1181
1183
  \u{1F527} Service Generator
1182
- `)),y.start("Detecting project setup...");let i=await F(n);y.succeed("Project setup detected"),i.httpClient==="none"&&(y.fail("No HTTP client is setup in this project"),v("Please setup either AxiosClient or FetchClient first"),l(Q.dim(`
1184
+ `)),x.start("Detecting project setup...");let n=await M(i);x.succeed("Project setup detected"),n.httpClient==="none"&&(x.fail("No HTTP client is setup in this project"),E("Please setup either AxiosClient or FetchClient first"),m(ne.dim(`
1183
1185
  Check: lib/utils/http/axios-client or lib/utils/http/fetch-client
1184
- `)),process.exit(1));let o=[];(i.httpClient==="axios"||i.httpClient==="both")&&o.push("Axios \u2713"),(i.httpClient==="fetch"||i.httpClient==="both")&&o.push("Fetch \u2713"),l(Q.dim(` HTTP Clients: ${o.join(", ")}
1185
- `));let s=await _s(t,r.axios,r.fetch,i.httpClient);H(s.serviceName,"service name"),r.path&&re(r.path,"path");let{basePath:a,servicePath:p}=em(n,s.serviceName,r.path);Zl(p)||await Ql(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 ks(n,s.serviceName),y.succeed("CRUD API endpoints registered")):await Re(Yr(),{projectPath:n,spinner:y,serviceName:s.serviceName,servicePath:p,httpClient:s.httpClient}),tm(s,a,!!r.crud)}catch(n){y.fail("Service generation failed"),v(`${n}`),process.exit(1)}})},em=(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)}},tm=(e,t,r=!1)=>{let n=lt.join(t,`${e.serviceName}.service.ts`);l(Q.green(`
1186
+ `)),process.exit(1));let o=[];(n.httpClient==="axios"||n.httpClient==="both")&&o.push("Axios \u2713"),(n.httpClient==="fetch"||n.httpClient==="both")&&o.push("Fetch \u2713"),m(ne.dim(` HTTP Clients: ${o.join(", ")}
1187
+ `));let s=await xa(t,r.axios,r.fetch,n.httpClient);J(s.serviceName,"service name"),r.path&&ce(r.path,"path");let{basePath:c,servicePath:p}=pd(i,s.serviceName,r.path);ad(p)||await cd(p,{recursive:!0}),Ht(i,c,`${s.serviceName}.service.ts`)&&(E(`Service '${s.serviceName}' already exists at ${c}!`),process.exit(1)),r.crud?(x.start("Generating CRUD service files..."),await Vr({name:s.serviceName,outputPath:p,httpClient:s.httpClient}),x.succeed("CRUD service files generated"),x.start("Registering CRUD API endpoints..."),await ha(i,s.serviceName),x.succeed("CRUD API endpoints registered")):await Le(Ii(),{projectPath:i,spinner:x,serviceName:s.serviceName,servicePath:p,httpClient:s.httpClient}),ld(s,c,!!r.crud)}catch(i){x.fail("Service generation failed"),E(`${i}`),process.exit(1)}})},pd=(e,t,r)=>{let i;if(r){let n=r.replace(/^src\//,"");if(n.startsWith("features/")){let o=n.split("/")[1];i=bt.join("src","features",o,"services")}else i=bt.join("src",n)}else i=bt.join("src","features",t,"services");return{basePath:i,servicePath:bt.join(e,i)}},ld=(e,t,r=!1)=>{let i=bt.join(t,`${e.serviceName}.service.ts`);m(ne.green(`
1186
1188
  \u2728 ${r?"CRUD ":""}Service '${e.serviceName}' created successfully!
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 rm from"enquirer";import en from"picocolors";var{prompt:nm}=rm,tn=[{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}],im=async(e,t={})=>{let r=t.promptFn??nm,n=t.cwd??(()=>process.cwd());l(en.cyan(`
1189
+ `)),m(ne.dim("Generated files:")),m(ne.dim(` \u{1F4C4} ${i}
1190
+ `)),m(ne.cyan("Next steps:"));let n=t.replace(/^src\//,"@/");m(ne.dim(` 1. Import service: import { ${e.serviceName}Service } from '${n}/${e.serviceName}.service'`)),r?(m(ne.dim(" 2. Available methods: getAll, getById, create, update, delete")),m(ne.dim(" 3. Update DTO types in the service file"))):m(ne.dim(` 2. Use in component: const data = await ${e.serviceName}Service.getAll()`)),m("")};import md from"enquirer";import Ai from"picocolors";var{prompt:dd}=md,Fi=[{key:"http-client",label:"HTTP Client (Axios/Fetch)",flag:"httpClient",handler:nr},{key:"dark-theme",label:"Dark Theme",flag:"darkTheme",handler:Qt},{key:"redux",label:"Redux Toolkit",flag:"redux",handler:fr},{key:"ws",label:"WebSocket Client (requires Redux)",flag:"ws",handler:xr},{key:"i18n",label:"Internationalization (next-intl)",flag:"i18n",handler:lr},{key:"tests",label:"Testing (Vitest + RTL)",flag:"tests",handler:hr},{key:"react-compiler",label:"React Compiler",flag:"reactCompiler",handler:dr},{key:"bundle-analyzer",label:"Bundle Analyzer",flag:"bundleAnalyzer",handler:Jt},{key:"security-headers",label:"Security Headers",flag:"securityHeaders",handler:gr},{key:"validate-scripts",label:"Validation Scripts",flag:"validateScripts",handler:yr},{key:"commitizen",label:"Commitizen",flag:"commitizen",handler:qt}],ud=async(e,t={})=>{let r=t.promptFn??dd,i=t.cwd??(()=>process.cwd());m(Ai.cyan(`
1189
1191
  \u{1F527} Setup Wizard
1190
- `));let i=tn.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:[...tn.map(p=>({name:p.key,message:p.label})),{name:"cancel",message:"Cancel"}]}])).feature;if(s==="cancel")return l(en.yellow("Setup cancelled.")),null;let a=tn.find(p=>p.key===s);return a?(await a.handler(n()),a.key):(l(en.yellow(`
1191
- \u26A0\uFE0F ${s} setup is not implemented yet.`)),null)},Fs=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 im(t)}catch(r){y.fail("Setup failed"),v(`${r}`),process.exit(1)}})};import{existsSync as am}from"node:fs";import{mkdir as cm}from"node:fs/promises";import ye from"node:path";import V from"picocolors";B();import om from"enquirer";var{prompt:sm}=om,js=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 sm(r):{};return{sliceName:e||n.sliceName,persistSlice:t===void 0?n.persistSlice||!1:t}};var Ds=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
+ `));let n=Fi.filter(p=>!!e[p.flag]);if(n.length>0){for(let p of n)await p.handler(i());return n.length===1?n[0].key:"multiple"}let s=(await r([{type:"select",name:"feature",message:"What would you like to setup?",choices:[...Fi.map(p=>({name:p.key,message:p.label})),{name:"cancel",message:"Cancel"}]}])).feature;if(s==="cancel")return m(Ai.yellow("Setup cancelled.")),null;let c=Fi.find(p=>p.key===s);return c?(await c.handler(i()),c.key):(m(Ai.yellow(`
1193
+ \u26A0\uFE0F ${s} setup is not implemented yet.`)),null)},Pa=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 ud(t)}catch(r){x.fail("Setup failed"),E(`${r}`),process.exit(1)}})};import{existsSync as hd}from"node:fs";import{mkdir as yd}from"node:fs/promises";import Re from"node:path";import X from"picocolors";W();import fd from"enquirer";var{prompt:gd}=fd,va=async(e,t)=>{let r=[];e||r.push({type:"input",name:"sliceName",message:"What is the slice name?",initial:"my-slice",validate:n=>/^[a-z0-9-]+$/.test(n)?!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 i=r.length>0?await gd(r):{};return{sliceName:e||i.sliceName,persistSlice:t===void 0?i.persistSlice||!1:t}};var Sa=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 i=process.cwd();m(X.cyan(`
1192
1194
  \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(V.dim(`
1195
+ `)),x.start("Detecting project setup...");let n=await M(i);x.succeed("Project setup detected"),n.hasRedux||(x.fail("Redux is not setup in this project"),E("Please install @reduxjs/toolkit and react-redux first"),m(X.dim(`
1194
1196
  Run: npm install @reduxjs/toolkit react-redux
1195
- `)),process.exit(1)),l(V.dim(` Redux: \u2713
1196
- `));let o=await js(t,r.persist);H(o.sliceName,"slice name"),r.path&&re(r.path,"path");let{basePath:s,slicePath:a}=pm(n,o.sliceName,r.path),p=ye.join(n,s);am(p)||await cm(p,{recursive:!0}),await ue(n,o.sliceName,s)&&(v(`Slice '${o.sliceName}' already exists at ${s}!`),process.exit(1)),await Re(Kr(),{projectPath:n,spinner:y,sliceName:o.sliceName,basePath:s,slicePath:a,persistSlice:o.persistSlice});let d=null;if(lm(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")}mm(o,s,d,n)}catch(n){y.fail("Slice generation failed"),v(`${n}`),process.exit(1)}})},pm=(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)}},lm=(e,t)=>e.test===!1?!1:e.test===!0?!0:t,mm=(e,t,r,n)=>{let i=ye.join(t,e.sliceName);l(V.green(`
1197
+ `)),process.exit(1)),m(X.dim(` Redux: \u2713
1198
+ `));let o=await va(t,r.persist);J(o.sliceName,"slice name"),r.path&&ce(r.path,"path");let{basePath:s,slicePath:c}=xd(i,o.sliceName,r.path),p=Re.join(i,s);hd(p)||await yd(p,{recursive:!0}),await ve(i,o.sliceName,s)&&(E(`Slice '${o.sliceName}' already exists at ${s}!`),process.exit(1)),await Le($i(),{projectPath:i,spinner:x,sliceName:o.sliceName,basePath:s,slicePath:c,persistSlice:o.persistSlice});let d=null;if(wd(r,n.hasTests)){let y=Re.join(c,`${o.sliceName}.slice.ts`);x.start("Generating test..."),d=await fe({projectPath:i,sourceFile:y,kind:"slice",symbolName:H(o.sliceName)}),x.succeed("Test generated")}Pd(o,s,d,i)}catch(i){x.fail("Slice generation failed"),E(`${i}`),process.exit(1)}})},xd=(e,t,r)=>{let i;if(r){let n=r.replace(/^src\//,"");if(n.startsWith("features/")){let o=n.split("/")[1];i=Re.join("src","features",o,"store")}else i=Re.join("src",n)}else i=Re.join("src","features",t,"store");return{basePath:i,slicePath:Re.join(e,i,t)}},wd=(e,t)=>e.test===!1?!1:e.test===!0?!0:t,Pd=(e,t,r,i)=>{let n=Re.join(t,e.sliceName);m(X.green(`
1197
1199
  \u2728 Slice '${e.sliceName}' created successfully!
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 rn from"picocolors";P();B();var Ls=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(rn.cyan(`
1200
+ `)),m(X.dim("Generated files:")),m(X.dim(` \u{1F4C2} ${n}/`)),m(X.dim(` \u251C\u2500\u2500 ${e.sliceName}.slice.ts`)),m(X.dim(` \u251C\u2500\u2500 ${e.sliceName}.selectors.ts`)),e.persistSlice&&m(X.dim(" \u251C\u2500\u2500 persist.ts")),m(X.dim(` \u251C\u2500\u2500 ${e.sliceName}.types.ts`)),m(X.dim(` \u2514\u2500\u2500 index.ts
1201
+ `)),r&&m(X.dim(` \u{1F9EA} ${Re.relative(i,r)}
1202
+ `)),m(X.cyan("Next steps:"));let o=t.replace(/^src\//,"@/");m(X.dim(` 1. Import actions: import { setLoading, setError } from '${o}/${e.sliceName}'`)),m(X.dim(" 2. Use in component: dispatch(setLoading(true))")),m("")};import oe from"node:path";import _i from"picocolors";w();W();var Ea=e=>{e.command("test <file>").description(`Generate a sibling test file for an existing component, hook, or slice.
1203
+ 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 i=process.cwd(),n=oe.isAbsolute(t)?t:oe.join(i,t);m(_i.cyan(`
1202
1204
  \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=dm(r.kind)??um(i,s);a||(v(`Could not infer test kind for ${ee.basename(i)}. Pass --kind component|hook|slice.`),process.exit(1));let p=fm(i,a),u=gm(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(rn.green(`
1204
- \u2728 Test '${ee.basename(d)}' created.
1205
- `)),l(rn.dim(` \u{1F9EA} ${ee.relative(n,d)}`)),l("")}catch(n){y.fail("Test generation failed"),v(`${n}`),process.exit(1)}})},dm=e=>{if(!e)return null;if(e==="component"||e==="hook"||e==="slice")return e;throw new Error(`Invalid --kind: ${e}. Use component | hook | slice.`)},um=(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},fm=(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.replace(/^use-?/,""))}`:$(r)},gm=(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 Ms=e=>{Kn(e),Fs(e),ws(e),Ds(e),Os(e),$s(e),Es(e),Ni(e),Ts(e),Ss(e),Is(e),Ko(e),fs(e),Uo(e),Ns(e),Ls(e)};var ym=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 ym.apply(process,arguments)};async function xm(){sn({logger:t=>dt(t)});let e=new hm;e.name("next-maker").description("Teispace Next.js Project Generator").version(nn.version),Ms(e),e.parse()}xm().catch(e=>{let t=e&&typeof e=="object"&&"message"in e?e.message:String(e);dt(`Unexpected error: ${t}`)});
1205
+ `)),l(n)||(E(`Source file not found: ${t}`),process.exit(1));let o=await M(i);o.hasTests||(E("Testing is not installed in this project. Run `next-maker setup --tests` first."),process.exit(1));let s=await g(n),c=vd(r.kind)??Sd(n,s);c||(E(`Could not infer test kind for ${oe.basename(n)}. Pass --kind component|hook|slice.`),process.exit(1));let p=Ed(n,c),u=Td(n,c);l(u)&&!r.force&&(E(`Test file already exists: ${oe.relative(i,u)}. Use --force to overwrite.`),process.exit(1)),x.start(`Generating ${c} test...`);let d=await fe({projectPath:i,sourceFile:n,kind:c,symbolName:p,hasRedux:o.hasRedux,hasI18n:o.hasI18n,hookUsesStore:c==="hook"&&o.hasRedux&&s.includes("useAppSelector")});x.succeed("Test generated"),m(_i.green(`
1206
+ \u2728 Test '${oe.basename(d)}' created.
1207
+ `)),m(_i.dim(` \u{1F9EA} ${oe.relative(i,d)}`)),m("")}catch(i){x.fail("Test generation failed"),E(`${i}`),process.exit(1)}})},vd=e=>{if(!e)return null;if(e==="component"||e==="hook"||e==="slice")return e;throw new Error(`Invalid --kind: ${e}. Use component | hook | slice.`)},Sd=(e,t)=>{let r=oe.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},Ed=(e,t)=>{let r=oe.basename(e).replace(/\.(tsx?|jsx?)$/i,"");return t==="slice"?H(r.replace(/\.slice$/,"")):t==="hook"?/^use[A-Z]/.test(r)?r:`use${N(r.replace(/^use-?/,""))}`:N(r)},Td=(e,t)=>{let r=oe.dirname(e),i=oe.basename(e).replace(/\.(tsx?|jsx?)$/i,""),n=t==="component"?".tsx":".ts";return oe.join(r,`${i}.test${n}`)};var Ta=e=>{Rn(e),Pa(e),oa(e),Sa(e),wa(e),ua(e),ca(e),oo(e),la(e),aa(e),fa(e),js(e),Qs(e),Rs(e),ga(e),Ea(e)};var Rd=process.emitWarning;process.emitWarning=function(e,t,r,i){if(!(typeof e=="string"&&e.includes("--localstorage-file")&&e.includes("was provided without a valid path")))return Rd.apply(process,arguments)};async function bd(){Di({logger:t=>$t(t)});let e=new Cd;e.name("next-maker").description("Teispace Next.js Project Generator").version(Oi.version),Ta(e),e.parse()}bd().catch(e=>{let t=e&&typeof e=="object"&&"message"in e?e.message:String(e);$t(`Unexpected error: ${t}`)});