@teispace/next-maker 3.0.6 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,30 +1,30 @@
1
1
  #!/usr/bin/env node
2
- var Hs=Object.defineProperty;var $e=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(n){throw r=[n],n}};var Jt=(e,t)=>{for(var r in t)Hs(e,r,{get:t[r],enumerable:!0})};import{existsSync as Wt}from"node:fs";import xe from"node:fs/promises";import ln from"node:path";var u,g,N,C,w,D,m,P=$e(()=>{"use strict";u=async e=>xe.readFile(e,"utf-8"),g=async(e,t)=>{await xe.mkdir(ln.dirname(e),{recursive:!0}),await xe.writeFile(e,t,"utf-8")},N=async(e,t)=>{await xe.mkdir(ln.dirname(t),{recursive:!0}),await xe.copyFile(e,t)},C=async e=>{Wt(e)&&await xe.unlink(e)},w=async e=>{Wt(e)&&await xe.rm(e,{recursive:!0,force:!0})},D=async(e,t)=>{let r=await u(e),n=JSON.parse(r),i=t(n);await g(e,JSON.stringify(i,null,2))},m=e=>Wt(e)});var yn={};Jt(yn,{PROJECT_PATHS:()=>c});var c,S=$e(()=>{"use strict";c={NEXT_CONFIG:"next.config.ts",POSTCSS_CONFIG:"postcss.config.mjs",BIOME_CONFIG:"biome.json",VITEST_CONFIG:"vitest.config.ts",TEST_DIR:"test",TS_CONFIG:"tsconfig.json",PACKAGE_JSON:"package.json",ENV_EXAMPLE:".env.example",GITIGNORE:".gitignore",README:"README.md",LICENSE:"LICENSE",CHANGELOG:"CHANGELOG.md",NVM_RC:".nvmrc",NPM_RC:".npmrc",AGENTS_MD:"AGENTS.md",CLAUDE_MD:"CLAUDE.md",SRC:"src",APP:"src/app",COMPONENTS:"src/components",LIB:"src/lib",PROVIDERS:"src/providers",STYLES:"src/styles",TYPES:"src/types",UTILS:"src/lib/utils",HOOKS:"src/hooks",SERVICES:"src/services",STORE:"src/store",I18N:"src/i18n",GLOBALS_CSS:"src/styles/globals.css",ROOT_LAYOUT:"src/app/layout.tsx",ROOT_PAGE:"src/app/page.tsx",ROOT_PROVIDER:"src/providers/RootProvider.tsx",PROVIDERS_INDEX:"src/providers/index.ts",COMPONENTS_INDEX:"src/components/index.ts",TYPES_INDEX:"src/types/index.ts",UTILS_INDEX:"src/lib/utils/index.ts",CONFIG_INDEX:"src/lib/config/index.ts",CONSTANTS:"src/lib/config/constants.ts",APP_LOCALES:"src/lib/config/app-locales.ts",SEO_FILE:"src/lib/config/seo.ts",SITEMAP_FILE:"src/app/sitemap.ts",MIDDLEWARE:"src/middleware.ts",PROXY:"src/proxy.ts",I18N_TYPES:"src/types/i18n.ts",HTTP_UTILS:"src/lib/utils/http",HTTP_SHARED:"src/lib/utils/http/shared",HTTP_SERVER_FILE:"src/lib/utils/http/server.ts",HTTP_BUNDLE_SENTINEL_DIR:"src/lib/utils/http/__bundle-sentinel__",HTTP_BUNDLE_SENTINEL_FILE:"src/lib/utils/http/__bundle-sentinel__/client-bundle-sentinel.tsx",WS_UTILS:"src/lib/utils/ws",WS_SLICE_FILE:"src/store/slices/ws.slice.ts",ROOT_REDUCER:"src/store/rootReducer.ts",TEST_SETUP_FILE:"test/setup.ts",AXIOS_CLIENT:"src/lib/utils/http/axios-client",FETCH_CLIENT:"src/lib/utils/http/fetch-client",AXIOS_CLIENT_FILE:"src/lib/utils/http/axios-client/index.ts",FETCH_CLIENT_FILE:"src/lib/utils/http/fetch-client/index.ts",CLIENT_UTILS:"src/lib/utils/http/client-utils.ts",APP_APIS:"src/lib/config/app-apis.ts",API_URL_FILE:"src/lib/config/api-url.ts",STORAGE_SERVICE:"src/services/storage",COUNTER_FEATURE:"src/features/counter",I18N_DIR:"src/i18n",LOCALE_DIR:"src/app/[locale]",ERRORS_DIR:"src/lib/errors",UTILITY_TYPES_DIR:"src/types/utility",COMMON_TYPES_DIR:"src/types/common",HTTP_TYPES:"src/types/common/http.types.ts",GITHUB_DIR:".github",HUSKY_DIR:".husky",STORE_PROVIDER:"src/providers/StoreProvider.tsx",THEME_PROVIDER:"src/providers/CustomThemeProvider.tsx",COUNTER_COMPONENT:"src/features/counter/components/Counter.tsx",LOCALE_PAGE:"src/app/[locale]/page.tsx",LOCALE_LAYOUT:"src/app/[locale]/layout.tsx",COMMITLINT_CONFIG:"commitlint.config.mjs",LINTSTAGED_RC:".lintstagedrc.mjs",CZRC:".czrc",DOCKERIGNORE:".dockerignore",DOCKERFILE:"Dockerfile",DOCKER_COMPOSE:"docker-compose.yml",GITHUB_WORKFLOWS:".github/workflows",GITHUB_ISSUE_TEMPLATE:"ISSUE_TEMPLATE",GITHUB_PR_TEMPLATE:"PULL_REQUEST_TEMPLATE.md",CODE_OF_CONDUCT:"CODE_OF_CONDUCT.md",CONTRIBUTING:"CONTRIBUTING.md",SECURITY:"SECURITY.md",SCRIPTS_DIR:"scripts",DOCS_DIR:"docs",CLAUDE_DIR:".claude",VSCODE_DIR:".vscode"}});var Tn={};Jt(Tn,{cleanupHttpTypes:()=>Ne,injectBundleSentinel:()=>Cn,installBundleSentinelMount:()=>nr,isFileUsed:()=>Ca,isStringUsed:()=>Ta,migrateClientUsages:()=>tr,removeBundleSentinelMount:()=>Be,removeHttpExports:()=>ir,resolveBundleSentinelLayoutPath:()=>rr,rewriteSentinelImports:()=>ke,rewriteServerEntryImports:()=>Ae,stripBundleSentinel:()=>He,stripSaveAuthTokens:()=>er,updateConfigIndex:()=>Qt,updateHttpIndex:()=>Yt,updateTypesIndex:()=>Zt,updateUtilsIndex:()=>Kt});import{execFile as wa}from"node:child_process";import A from"node:path";import{promisify as va}from"node:util";async function Xt(e,t,r){try{let{stdout:n}=await Sa("grep",[...r,"--include=*.ts","--include=*.tsx",e,t]);return n}catch(n){if(n.code===1)return"";throw n}}var Sa,Yt,Kt,Zt,Qt,Ne,er,tr,rr,Ea,vn,Sn,Cn,He,nr,Be,ir,Ca,Ta,ke,Ae,En,ze=$e(()=>{"use strict";S();P();Sa=va(wa);Yt=async(e,t)=>{let r=A.join(e,c.HTTP_UTILS,"index.ts");if(m(r)){let n=await u(r);n=n.replace(/export .* from '\.\/axios-client';?\n?/g,""),n=n.replace(/export .* from '\.\/fetch-client';?\n?/g,""),t.includes("fetch")&&!n.includes("fetch-client")&&(n+=`export * from './fetch-client';
3
- `),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 u(t);r.includes("./http")||(r+=`export * from './http';
5
- `,await g(t,r))}},Zt=async e=>{let t=A.join(e,c.TYPES_INDEX);if(m(t)){let r=await u(t);r.includes("./common")||(r+=`export * from './common';
2
+ var ka=Object.defineProperty;var Ge=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(i){throw r=[i],i}};var Rr=(e,t)=>{for(var r in t)ka(e,r,{get:t[r],enumerable:!0})};import{existsSync as br}from"node:fs";import Ie from"node:fs/promises";import Hi from"node:path";var g,h,b,C,v,_,l,w=Ge(()=>{"use strict";g=async e=>Ie.readFile(e,"utf-8"),h=async(e,t)=>{await Ie.mkdir(Hi.dirname(e),{recursive:!0}),await Ie.writeFile(e,t,"utf-8")},b=async(e,t)=>{await Ie.mkdir(Hi.dirname(t),{recursive:!0}),await Ie.copyFile(e,t)},C=async e=>{br(e)&&await Ie.unlink(e)},v=async e=>{br(e)&&await Ie.rm(e,{recursive:!0,force:!0})},_=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=>br(e)});var qi={};Rr(qi,{PROJECT_PATHS:()=>a});var a,P=Ge(()=>{"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",WS_SLICE_TEST_FILE:"src/store/slices/ws.slice.test.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 rn={};Rr(rn,{cleanupHttpTypes:()=>Ue,injectBundleSentinel:()=>tn,installBundleSentinelMount:()=>tt,isFileUsed:()=>mc,isStringUsed:()=>dc,migrateClientUsages:()=>Dr,removeBundleSentinelMount:()=>rt,removeHttpExports:()=>Lr,resolveBundleSentinelLayoutPath:()=>jr,rewriteSentinelImports:()=>we,rewriteServerEntryImports:()=>Pe,stripBundleSentinel:()=>_t,stripSaveAuthTokens:()=>Or,updateConfigIndex:()=>Fr,updateHttpIndex:()=>Nr,updateTypesIndex:()=>_r,updateUtilsIndex:()=>Ar});import{execFile as ac}from"node:child_process";import D from"node:path";import{promisify as cc}from"node:util";async function kr(e,t,r){try{let{stdout:i}=await pc("grep",[...r,"--include=*.ts","--include=*.tsx",e,t]);return i}catch(i){if(i.code===1)return"";throw i}}var pc,Nr,Ar,_r,Fr,Ue,Or,Dr,jr,lc,Zi,Qi,tn,_t,tt,rt,Lr,mc,dc,we,Pe,en,Be=Ge(()=>{"use strict";P();w();pc=cc(ac);Nr=async(e,t)=>{let r=D.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)}},Ar=async e=>{let t=D.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))}},_r=async e=>{let t=D.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 u(t);r.includes("./app-apis")||(r+=`export * from './app-apis';
8
- `,await g(t,r))}},Ne=async(e,t)=>{let r=A.join(e,c.HTTP_TYPES);if(m(r)){let n=await u(r);t.includes("axios")||(n=n.replace(/declare module 'axios'\s*\{\s*export interface AxiosRequestConfig\s*\{[\s\S]*?\}\s*\}/g,""),n=`${n.replace(/\n\s*\n/g,`
7
+ `),await h(t,r)}},Fr=async e=>{let t=D.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))}},Ue=async(e,t)=>{let r=D.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=e=>{let t=e;return t=t.replace(/\/\*\*(?:[^*]|\*(?!\/))*?\*\/\n(?=(?:export\s+)?const\s+BEARER_ALLOWED_ENVS\b)/,""),t=t.replace(/^(?:export\s+)?const\s+BEARER_ALLOWED_ENVS\s*=[\s\S]*?;\n?/m,""),t=t.replace(/^export const SAVE_AUTH_TOKENS\s*=.*;\n?/m,""),t},tr=async(e,t,r)=>{if(t===r)return;let n=t==="fetch"?"fetchClient":"axiosClient",i=r==="fetch"?"fetchClient":"axiosClient",o=t==="fetch"?"fetch-client":"axios-client",s=r==="fetch"?"fetch-client":"axios-client",a=A.join(e,"src");try{let p=await Xt(n,a,["-r","-l"]);if(!p.trim())return;let f=p.trim().split(`
12
- `).filter(d=>d);for(let d of f){if(!m(d))continue;let h=await u(d),x=!1,R=new RegExp(`(import\\s*\\{[^}]*?)\\b${n}\\b([^}]*?\\}\\s*from\\s*['"][^'"]*?/http['"])`,"g");R.test(h)&&(h=h.replace(R,`$1${i}$2`),x=!0);let L=new RegExp(`import\\s+${n}\\s+from\\s+['"]([^'"]*?)/${o}['"]`,"g");L.test(h)&&(h=h.replace(L,`import ${i} from '$1/${s}'`),x=!0);let $=new RegExp(`\\b${n}\\b(?=\\.)`,"g");$.test(h)&&(h=h.replace($,i),x=!0);let W=new RegExp(`\\b${n}\\b(?![.\\w])`,"g");W.test(h)&&(h=h.replace(W,i),x=!0),x&&await g(d,h)}}catch(p){console.warn("Warning: Could not scan for HTTP client usages:",p)}},rr=e=>{let t=A.join(e,c.LOCALE_LAYOUT);if(m(t))return t;let r=A.join(e,c.ROOT_LAYOUT);return m(r)?r:null},Ea="// Regression sentinel \u2014 see file comment for what this guards.",vn="import { HttpClientBundleSentinel } from '@/lib/utils/http/__bundle-sentinel__/client-bundle-sentinel';",Sn="<HttpClientBundleSentinel />",Cn=e=>{if(e.includes(Sn))return e;let t=e;if(!t.includes(vn)){let o=/(^import\s[^\n]*\n)+/m,s=t.match(o);if(!s)throw new Error("injectBundleSentinel: no `import` lines found \u2014 expected a layout file with at least one import.");let a=t.slice(0,(s.index??0)+s[0].length),p=t.slice((s.index??0)+s[0].length);t=`${a}${Ea}
13
- ${vn}
14
- ${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}${Sn}
16
- ${i}`),t},He=e=>{let t=e,r=/@\/lib\/utils\/http\/__bundle-sentinel__\/client-bundle-sentinel/,n=new RegExp(`(?:^[ \\t]*//[^\\n]*\\n)?^[ \\t]*import[^\\n]*${r.source}[^\\n]*\\n`,"m");return t=t.replace(n,""),t=t.replace(/[ \t]*<HttpClientBundleSentinel\s*\/>\s*\n/,""),t},nr=async e=>{let t=rr(e);if(!t)return;let r=await u(t),n=Cn(r);n!==r&&await g(t,n)},Be=async e=>{let t=rr(e);if(!t)return;let r=await u(t),n=He(r);n!==r&&await g(t,n)},ir=async e=>{let t=A.join(e,c.UTILS_INDEX);if(m(t)){let n=await u(t);n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http['"];?.*$/gm,""),await g(t,n)}let r=A.join(e,c.TYPES_INDEX);if(m(r)){let n=await u(r),i=A.join(e,c.COMMON_TYPES_DIR);if(!m(i))n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/common['"];?.*$/gm,"");else{let o=A.join(i,"index.ts");if(m(o)){let s=await u(o);s=s.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http\.types['"];?.*$/gm,""),await g(o,s)}}m(A.join(e,c.UTILITY_TYPES_DIR))||(n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/utility['"];?.*$/gm,"")),await g(r,n)}},Ca=async(e,t,r=[])=>{let n=A.join(e,"src"),o=`from ['"].*${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}.*['"]`;try{let s=await Xt(o,n,["-r","-E"]);return s.trim()?s.trim().split(`
17
- `).filter(f=>{let[d]=f.split(":"),h=A.resolve(e,d);return!r.some(x=>!!(h===x||h.startsWith(x+A.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for ${t}:`,s),!0}},Ta=async(e,t,r=[])=>{let n=A.join(e,"src");try{let i=await Xt(t,n,["-r","-F"]);return i.trim()?i.trim().split(`
18
- `).filter(a=>{let[p]=a.split(":"),f=A.resolve(e,p);return!r.some(d=>!!(f===d||f.startsWith(d+A.sep)))}).length>0:!1}catch(i){return console.warn(`Warning: Failed to check usage for string ${t}:`,i),!0}},ke=async(e,t)=>{let r=A.join(e,c.HTTP_BUNDLE_SENTINEL_FILE);if(!m(r))return;let n=await u(r),i=["toSearchParams"];if(t.includes("axios")&&i.unshift("axiosClient","createAxiosClient"),t.includes("fetch")){let a=i.indexOf("toSearchParams");i.splice(a,0,"createFetchClient","fetchClient")}i.sort();let o=`import {
19
- ${i.join(`,
11
+ `,await h(r,i))}},Or=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},Dr=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=D.join(e,"src");try{let p=await kr(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),x=!1,I=new RegExp(`(import\\s*\\{[^}]*?)\\b${i}\\b([^}]*?\\}\\s*from\\s*['"][^'"]*?/http['"])`,"g");I.test(f)&&(f=f.replace(I,`$1${n}$2`),x=!0);let H=new RegExp(`import\\s+${i}\\s+from\\s+['"]([^'"]*?)/${o}['"]`,"g");H.test(f)&&(f=f.replace(H,`import ${n} from '$1/${s}'`),x=!0);let k=new RegExp(`\\b${i}\\b(?=\\.)`,"g");k.test(f)&&(f=f.replace(k,n),x=!0);let Z=new RegExp(`\\b${i}\\b(?![.\\w])`,"g");Z.test(f)&&(f=f.replace(Z,n),x=!0),x&&await h(d,f)}}catch(p){console.warn("Warning: Could not scan for HTTP client usages:",p)}},jr=e=>{let t=D.join(e,a.LOCALE_LAYOUT);if(l(t))return t;let r=D.join(e,a.ROOT_LAYOUT);return l(r)?r:null},lc="// Regression sentinel \u2014 see file comment for what this guards.",Zi="import { HttpClientBundleSentinel } from '@/lib/utils/http/__bundle-sentinel__/client-bundle-sentinel';",Qi="<HttpClientBundleSentinel />",tn=e=>{if(e.includes(Qi))return e;let t=e;if(!t.includes(Zi)){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}${lc}
13
+ ${Zi}
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}${Qi}
16
+ ${n}`),t},_t=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},tt=async e=>{let t=jr(e);if(!t)return;let r=await g(t),i=tn(r);i!==r&&await h(t,i)},rt=async e=>{let t=jr(e);if(!t)return;let r=await g(t),i=_t(r);i!==r&&await h(t,i)},Lr=async e=>{let t=D.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=D.join(e,a.TYPES_INDEX);if(l(r)){let i=await g(r),n=D.join(e,a.COMMON_TYPES_DIR);if(!l(n))i=i.replace(/^\s*export\s+\*\s+from\s+['"]\.\/common['"];?.*$/gm,"");else{let o=D.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(D.join(e,a.UTILITY_TYPES_DIR))||(i=i.replace(/^\s*export\s+\*\s+from\s+['"]\.\/utility['"];?.*$/gm,"")),await h(r,i)}},mc=async(e,t,r=[])=>{let i=D.join(e,"src"),o=`from ['"].*${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}.*['"]`;try{let s=await kr(o,i,["-r","-E"]);return s.trim()?s.trim().split(`
17
+ `).filter(u=>{let[d]=u.split(":"),f=D.resolve(e,d);return!r.some(x=>!!(f===x||f.startsWith(x+D.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for ${t}:`,s),!0}},dc=async(e,t,r=[])=>{let i=D.join(e,"src");try{let n=await kr(t,i,["-r","-F"]);return n.trim()?n.trim().split(`
18
+ `).filter(c=>{let[p]=c.split(":"),u=D.resolve(e,p);return!r.some(d=>!!(u===d||u.startsWith(d+D.sep)))}).length>0:!1}catch(n){return console.warn(`Warning: Failed to check usage for string ${t}:`,n),!0}},we=async(e,t)=>{let r=D.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 u(r),i=o=>{n=n.replace(o,"")};t.includes("axios")||(i(/^import\s*\{\s*createAxiosClient\s*\}\s*from\s*['"]\.\/axios-client['"];\n?/m),i(/export const axiosClient = createAxiosClient\(\{[\s\S]*?\}\);\n?\n?/),n=En(n,"createAxiosClient")),t.includes("fetch")||(i(/^import\s*\{\s*createFetchClient\s*\}\s*from\s*['"]\.\/fetch-client['"];\n?/m),i(/export const fetchClient = createFetchClient\(\{[\s\S]*?\}\);\n?\n?/),n=En(n,"createFetchClient")),n=n.replace(/\n{3,}/g,`
24
+ };`),await h(r,i)},Pe=async(e,t)=>{let r=D.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=en(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=en(i,"createFetchClient")),i=i.replace(/\n{3,}/g,`
25
25
 
26
- `),await g(r,n)},En=(e,t)=>{let r=/^export\s*\{([^}]*)\};\n?/m;return e.replace(r,(n,i)=>{let o=i.split(",").map(s=>s.trim()).filter(s=>s.length>0&&s!==t);return o.length===0?"":`export { ${o.join(", ")} };
27
- `})}});import{existsSync as gc}from"node:fs";import{access as hc}from"node:fs/promises";import ti from"node:path";var ue,Pt,ri=$e(()=>{"use strict";ue=async(e,t,r)=>{try{return await hc(ti.join(e,r,t)),!0}catch{return!1}},Pt=(e,t,r)=>gc(ti.join(e,t,r))});import{access as wt,readFile as yc}from"node:fs/promises";import Xe from"node:path";var F,ni=$e(()=>{"use strict";F=async e=>{try{let t=Xe.join(e,"package.json"),r=await yc(t,"utf-8"),n=JSON.parse(r),i={...n.dependencies,...n.devDependencies},o=!!(i["@reduxjs/toolkit"]&&i["react-redux"]),s=!!i["next-intl"],a=!!i.axios,p=!1,f=Xe.join(e,"src","lib","utils","http","axios-client");try{await wt(f)}catch{a=!1}let d=Xe.join(e,"src","lib","utils","http","fetch-client");try{await wt(d),p=!0}catch{p=!1}let h;a&&p?h="both":a?h="axios":p?h="fetch":h="none";let x=!!i.vitest;if(!x)try{await wt(Xe.join(e,"vitest.config.ts")),x=!0}catch{}let R="none";if(i["socket.io-client"])try{await wt(Xe.join(e,"src","lib","utils","ws")),R="present"}catch{}return{hasRedux:o,httpClient:h,hasI18n:s,hasTests:x,ws:R}}catch(t){throw new Error(`Failed to detect project setup: ${t}`,{cause:t})}}});var Ye={};Jt(Ye,{detectProjectSetup:()=>F,directoryExists:()=>ue,fileExistsAt:()=>Pt});var B=$e(()=>{"use strict";ri();ni()});import{Command as ym}from"commander";var on={name:"@teispace/next-maker",version:"3.0.6",description:"Create a new Teispace Next.js application with interactive setup.",keywords:["nextjs","react","typescript","tailwindcss","starter","template","redux"],type:"module",homepage:"https://github.com/teispace/npm-packages/tree/main/packages/next-maker#readme",bugs:{url:"https://github.com/teispace/npm-packages/issues"},license:"MIT",author:"Teispace",files:["dist","README.md","LICENSE","CHANGELOG.md"],bin:"dist/index.js",repository:{type:"git",url:"git+https://github.com/teispace/npm-packages.git",directory:"packages/next-maker"},scripts:{build:"tsx build.ts",start:"node dist/index.js",dev:"tsx --watch src/index.ts",test:"vitest run","test:watch":"vitest","test:cov":"vitest run --coverage","type-check":"tsc --noEmit",clean:"rm -rf dist",prepublishOnly:"yarn clean && yarn build"},dependencies:{commander:"^15.0.0",degit:"^3.4.7",enquirer:"^2.4.1",ora:"^9.4.1",picocolors:"^1.1.1","png-to-ico":"^3.0.1",sharp:"^0.35.2"},devDependencies:{"@types/degit":"^2.8.6","@types/node":"^26.0.1",esbuild:"^0.28.1",tsx:"^4.22.4",typescript:"^6.0.3",vitest:"^4.1.9"},engines:{node:">=24.0.0"},publishConfig:{access:"public",registry:"https://registry.npmjs.org/"}};import ar from"node:path";import X from"picocolors";var Me=new Set;function sn(e){return Me.add(e),()=>Me.delete(e)}function an(e){let{logger:t=p=>console.error(p),exitOnCancel:r=process.env.NODE_ENV!=="test"}=e??{},n=!1,i=async()=>{let p=[...Me];Me.clear();for(let f of p)try{await f()}catch(d){t(`Cleanup failed: ${d instanceof Error?d.message:String(d)}`)}},o=()=>{if(n){r&&process.exit(130);return}n=!0;let p=Me.size>0;i().then(()=>{console.log(""),t("Setup cancelled by user"),console.log(""),r&&process.exit(p?130:0)})},s=p=>{if(p!==null&&typeof p=="object"&&"code"in p&&p.code==="ERR_USE_AFTER_CLOSE"){o();return}if(p instanceof Error){t(`Uncaught exception: ${p.message}`);return}t(`Uncaught exception: ${String(p)}`)},a=p=>{if(p instanceof Error){t(`Unhandled promise rejection: ${p.message}`);return}t(`Unhandled promise rejection: ${String(p)}`)};return process.on("SIGINT",o),process.on("SIGTERM",o),process.on("uncaughtException",s),process.on("unhandledRejection",a),()=>{process.off("SIGINT",o),process.off("SIGTERM",o),process.off("uncaughtException",s),process.off("unhandledRejection",a)}}import te from"picocolors";var zs={reset:e=>e,red:te.red,green:te.green,yellow:te.yellow,blue:te.blue,cyan:te.cyan,magenta:te.magenta,white:te.white,gray:te.gray,bright:te.bold,dim:te.dim};function le(e,t="reset"){let r=zs[t]??(n=>n);console.log(r(e))}function dt(e){le(`\u2716 ${e}`,"red")}var v=dt;function cn(e){le(`\u26A0 ${e}`,"yellow")}function l(e){le(e)}function pn(){console.log(""),le("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557","cyan"),le("\u2551 \u2551","cyan"),le("\u2551 \u{1F680} Create Teispace Next.js App \u{1F680} \u2551","cyan"),le("\u2551 \u2551","cyan"),le("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D","cyan"),console.log("")}import Vs from"ora";function b(e="",t){let r=Vs({text:e,...t});return r.start(),r}var Js=e=>e.charAt(0).toUpperCase()+e.slice(1),j=e=>e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase()),I=e=>Js(j(e));import Ws from"ora";var y=Ws();P();import{execFile as qs}from"node:child_process";import{promisify as Xs}from"node:util";var Ys=Xs(qs),se=(e,t)=>Ys("git",e,t?{cwd:t}:void 0);function Ks(e){let t=e.trim();if(!t||t.startsWith("-"))throw new Error(`Invalid git remote "${e}".`);if(!(/^https?:\/\/\S+$/.test(t)||/^git@[\w.-]+:\S+$/.test(t)||/^ssh:\/\/\S+$/.test(t)||/^[\w.-]+\/[\w.-]+$/.test(t)))throw new Error(`Invalid git remote "${e}". Expected an https/ssh URL or "owner/repo".`)}var mn=async(e,t,r)=>{try{if(await se(["init"],e),await se(["add","."],e),await se(["commit","-m","Initial commit from @teispace/next-maker"],e),t&&(Ks(t),await se(["remote","add","origin",t],e),r)){await se(["fetch","origin"],e);let n="main";try{await se(["show-branch","origin/main"],e)}catch{try{await se(["show-branch","origin/master"],e),n="master"}catch{n="main"}}await se(["merge",`origin/${n}`,"--allow-unrelated-histories","-X","ours"],e),await se(["push","origin",`HEAD:${n}`],e)}}catch(n){console.warn("Failed to initialize git repository",n)}};import{execFile as Zs}from"node:child_process";import{promisify as Qs}from"node:util";var ea=Qs(Zs),Ge=(e,t,r)=>ea(e,t,{cwd:r}),dn=async(e,t)=>{try{await Ge(t,["install"],e)}catch(r){throw new Error(`Failed to install dependencies with ${t}: ${r}`,{cause:r})}},J=async(e,t,r)=>{let n=t==="npm"?["run",r]:[r];try{await Ge(t,n,e)}catch(i){console.warn(`Warning: Failed to run script '${r}': ${i}`)}},ta=()=>{let e=process.env.npm_config_user_agent;if(e){if(e.startsWith("yarn"))return"yarn";if(e.startsWith("pnpm"))return"pnpm";if(e.startsWith("bun"))return"bun"}return"npm"},k=async e=>{let{existsSync:t}=await import("node:fs"),r=await import("node:path");return t(r.join(e,"pnpm-lock.yaml"))?"pnpm":t(r.join(e,"yarn.lock"))?"yarn":t(r.join(e,"bun.lockb"))?"bun":t(r.join(e,"package-lock.json"))?"npm":ta()},ra=async(e,t,r)=>{if(r.length!==0)try{await Ge(t,[...un(t),...r],e)}catch(n){throw new Error(`Failed to install packages with ${t}: ${n}`,{cause:n})}},un=e=>{switch(e){case"npm":return["install"];case"yarn":return["add"];case"pnpm":return["add"];case"bun":return["add"];default:return["install"]}},U=async(e,t)=>{let r=await k(e);await ra(e,r,[t])},na=e=>{switch(e){case"npm":return"--save-dev";case"yarn":case"pnpm":case"bun":return"-D";default:return"--save-dev"}},Pe=async(e,t,r)=>{if(r.length!==0)try{await Ge(t,[...un(t),na(t),...r],e)}catch(n){throw new Error(`Failed to install dev packages with ${t}: ${n}`,{cause:n})}},ut=async(e,t)=>{let r=await k(e);await Pe(e,r,[t])},qt=async(e,t,r)=>{if(r.length!==0)try{await Ge(t,[...ia(t),...r],e)}catch(n){throw new Error(`Failed to uninstall packages with ${t}: ${n}`,{cause:n})}},ia=e=>{switch(e){case"npm":return["uninstall"];case"yarn":return["remove"];case"pnpm":return["remove"];case"bun":return["remove"];default:return["uninstall"]}},Ie=async(e,t)=>{let r=await k(e);await qt(e,r,[t])};import oa from"enquirer";var sa=/^[a-z0-9-_]+$/,aa=/^\d+\.\d+\.\d+$/,fn=e=>sa.test(e),ca=e=>aa.test(e),gn=(e,t={})=>{let r=t.projectName??e??"my-app";if(!fn(r))throw new Error(`Invalid project name "${r}". Use lowercase letters, digits, hyphens, and underscores only.`);let n=t.version??"0.1.0";if(!ca(n))throw new Error(`Invalid version "${n}". Expected semver (e.g. 0.1.0).`);let i=t.author??"Teispace",o=t.company??i;return{projectName:r,description:t.description??"A Next.js application",author:i,version:n,packageManager:t.packageManager??"yarn",gitRemote:t.gitRemote??"",pushToRemote:t.pushToRemote??!1,gitIssues:t.gitIssues??"",gitHomepage:t.gitHomepage??"",httpClient:t.httpClient??"fetch",reactSecureStorage:t.reactSecureStorage??!0,email:t.email??"support@example.com",company:o,keepTemplates:t.keepTemplates??!1,darkMode:t.darkMode??!0,redux:t.redux??!0,ws:(t.redux??!0)&&(t.ws??!1),i18n:t.i18n??!0,communityFiles:t.communityFiles??[],readme:t.readme??!0,docker:t.docker??!1,containerName:t.containerName,imageName:t.imageName,imageTag:t.imageTag,ci:t.ci??!1,preCommitHooks:t.preCommitHooks??!0,commitizen:t.commitizen??!0,copyEnv:t.copyEnv??!0,tests:t.tests??!0,reactCompiler:t.reactCompiler??!0,bundleAnalyzer:t.bundleAnalyzer??!1}},{prompt:pa}=oa,hn=async e=>{if(e!==void 0&&!fn(e))throw new Error(`Invalid project name "${e}". Use lowercase letters, digits, hyphens, and underscores only \u2014 no slashes, "..", or absolute paths.`);let t=await pa([{type:"input",name:"projectName",message:"What is the project name?",initial:e||"my-app",skip:!!e,validate:r=>/^[a-z0-9-_]+$/.test(r)?!0:"Project name must be lowercase and contain only alphanumeric characters, hyphens, and underscores."},{type:"input",name:"description",message:"Project description:",initial:"A Next.js application"},{type:"input",name:"author",message:"Author:",initial:"Teispace"},{type:"input",name:"version",message:"Version:",initial:"0.1.0",validate:r=>/^\d+\.\d+\.\d+$/.test(r)?!0:"Version must be a valid semantic version (x.y.z)."},{type:"input",name:"email",message:"Support email:",initial:"support@example.com",validate:r=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(r)?!0:"Please enter a valid email address."},{type:"select",name:"packageManager",message:"Which package manager would you like to use?",choices:["npm","yarn","pnpm","bun"],initial:1},{type:"input",name:"gitRemote",message:"GitHub repository URL (optional):",initial:""},{type:"confirm",name:"pushToRemote",message:"Would you like to push the changes to the remote repository?",initial:!0,skip:function(){return!this.state?.answers?.gitRemote}},{type:"input",name:"gitIssues",message:"GitHub issues URL (optional):",initial:"",skip:function(){return!this.state?.answers?.gitRemote},validate:r=>r?/^https:\/\/github\.com\/[\w-]+\/[\w.-]+\/issues$/.test(r)?!0:"Please enter a valid GitHub issues URL (e.g., https://github.com/user/repo/issues)":!0},{type:"input",name:"gitHomepage",message:"GitHub homepage URL (optional):",initial:"",skip:function(){return!this.state?.answers?.gitRemote},validate:r=>r?/^https:\/\/github\.com\/[\w-]+\/[\w.-]+#readme$/.test(r)?!0:"Please enter a valid GitHub homepage URL (e.g., https://github.com/user/repo#readme)":!0},{type:"confirm",name:"keepTemplates",message:"Do you want to keep GitHub issue and pull request templates?",initial:!1},{type:"select",name:"httpClient",message:"Which HTTP client do you want to use?",choices:["axios","fetch","both","none"],initial:1},{type:"confirm",name:"reactSecureStorage",message:"Do you want to include react-secure-storage?",initial:!0,skip:function(){let r=this.state?.answers??this.enquirer?.answers??{};return!!(r.httpClient&&r.httpClient!=="none")}},{type:"confirm",name:"darkMode",message:"Do you want to include Dark Mode (Tailwind + @teispace/next-themes)?",initial:!0},{type:"confirm",name:"redux",message:"Do you want to include Redux Toolkit?",initial:!0},{type:"confirm",name:"ws",message:"Do you want to include WebSocket support (socket.io-client + Redux bridge)?",initial:!1,skip:function(){return!(this.state?.answers??this.enquirer?.answers??{}).redux}},{type:"confirm",name:"i18n",message:"Do you want to include Internationalization (next-intl)?",initial:!0},{type:"confirm",name:"tests",message:"Do you want to include testing setup (Vitest + React Testing Library)?",initial:!0},{type:"confirm",name:"reactCompiler",message:"Do you want to enable the React Compiler?",initial:!0},{type:"confirm",name:"bundleAnalyzer",message:"Do you want to include @next/bundle-analyzer?",initial:!1},{type:"multiselect",name:"communityFiles",message:"Select community files to include:",choices:[{name:"CODE_OF_CONDUCT.md",value:"CODE_OF_CONDUCT.md"},{name:"CONTRIBUTING.md",value:"CONTRIBUTING.md"},{name:"SECURITY.md",value:"SECURITY.md"}],initial:[]},{type:"confirm",name:"readme",message:"Do you want to create a README.md?",initial:!0},{type:"confirm",name:"docker",message:"Do you want to include Docker configuration?",initial:!1},{type:"input",name:"containerName",message:"Docker Container Name:",initial:"next-app",skip:function(){return!(this.state?.answers??this.enquirer?.answers??{}).docker},validate:r=>/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(r)?!0:"Invalid Docker container name."},{type:"input",name:"imageName",message:"Docker Image Name:",initial:"nextjs-starter",skip:function(){return!(this.state?.answers??this.enquirer?.answers??{}).docker},validate:r=>/^[a-z0-9]+(?:[._-][a-z0-9]+)*$/.test(r)?!0:"Invalid Docker image name (must be lowercase)."},{type:"input",name:"imageTag",message:"Docker Image Tag:",initial:"latest",skip:function(){return!(this.state?.answers??this.enquirer?.answers??{}).docker},validate:r=>/^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,127}$/.test(r)?!0:"Invalid Docker image tag."},{type:"confirm",name:"ci",message:"Do you want to include GitHub Actions (CI/CD)?",initial:!1},{type:"confirm",name:"preCommitHooks",message:"Do you want to setup pre-commit hooks (Husky, Commitlint, Lint-staged)?",initial:!0},{type:"confirm",name:"commitizen",message:"Do you want to setup Commitizen?",initial:!0},{type:"confirm",name:"copyEnv",message:"Want to copy .env.example to .env?",initial:!0}]);if(t.company=t.author,t.ws=!!t.redux&&!!t.ws,t.gitRemote&&!t.gitHomepage){let r=t.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"");t.gitHomepage=`${r}#readme`,t.gitIssues=`${r}/issues`}return t};P();import la from"node:path";var me=async(e,t)=>{let r=ma(t);await g(la.join(e,"test/test-utils.tsx"),r)},ma=({redux:e,i18n:t})=>e&&t?da:e?ua:t?fa:ga,da=`import { type RenderOptions, render } from '@testing-library/react';
26
+ `),await h(r,i)},en=(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 np}from"node:fs";import{access as op}from"node:fs/promises";import _n from"node:path";var Se,Ht,Fn=Ge(()=>{"use strict";Se=async(e,t,r)=>{try{return await op(_n.join(e,r,t)),!0}catch{return!1}},Ht=(e,t,r)=>np(_n.join(e,t,r))});import{access as Ut,readFile as sp}from"node:fs/promises";import at from"node:path";var M,On=Ge(()=>{"use strict";M=async e=>{try{let t=at.join(e,"package.json"),r=await sp(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=at.join(e,"src","lib","utils","http","axios-client");try{await Ut(u)}catch{c=!1}let d=at.join(e,"src","lib","utils","http","fetch-client");try{await Ut(d),p=!0}catch{p=!1}let f;c&&p?f="both":c?f="axios":p?f="fetch":f="none";let x=!!n.vitest;if(!x)try{await Ut(at.join(e,"vitest.config.ts")),x=!0}catch{}let I="none";if(n["socket.io-client"])try{await Ut(at.join(e,"src","lib","utils","ws")),I="present"}catch{}return{hasRedux:o,httpClient:f,hasI18n:s,hasTests:x,ws:I}}catch(t){throw new Error(`Failed to detect project setup: ${t}`,{cause:t})}}});var ct={};Rr(ct,{detectProjectSetup:()=>M,directoryExists:()=>Se,fileExistsAt:()=>Ht});var q=Ge(()=>{"use strict";Fn();On()});import{Command as Td}from"commander";var Di={name:"@teispace/next-maker",version:"4.0.1",description:"Create a new Teispace Next.js application with interactive setup.",keywords:["nextjs","react","typescript","tailwindcss","starter","template","redux"],type:"module",homepage:"https://github.com/teispace/npm-packages/tree/main/packages/next-maker#readme",bugs:{url:"https://github.com/teispace/npm-packages/issues"},license:"MIT",author:"Teispace",files:["dist","README.md","LICENSE","CHANGELOG.md"],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 ee from"picocolors";var Ze=new Set;function ji(e){return Ze.add(e),()=>Ze.delete(e)}function Li(e){let{logger:t=p=>console.error(p),exitOnCancel:r=process.env.NODE_ENV!=="test"}=e??{},i=!1,n=async()=>{let p=[...Ze];Ze.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=Ze.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 ae from"picocolors";var Aa={reset:e=>e,red:ae.red,green:ae.green,yellow:ae.yellow,blue:ae.blue,cyan:ae.cyan,magenta:ae.magenta,white:ae.white,gray:ae.gray,bright:ae.bold,dim:ae.dim};function xe(e,t="reset"){let r=Aa[t]??(i=>i);console.log(r(e))}function Nt(e){xe(`\u2716 ${e}`,"red")}var E=Nt;function Mi(e){xe(`\u26A0 ${e}`,"yellow")}function m(e){xe(e)}function Gi(){console.log(""),xe("\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"),xe("\u2551 \u2551","cyan"),xe("\u2551 \u{1F680} Create Teispace Next.js App \u{1F680} \u2551","cyan"),xe("\u2551 \u2551","cyan"),xe("\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 Fa=e=>e.charAt(0).toUpperCase()+e.slice(1),G=e=>e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase()),N=e=>Fa(G(e));import Oa from"ora";var y=Oa();w();import{execFile as Da}from"node:child_process";import{promisify as ja}from"node:util";var La=ja(Da),ue=(e,t)=>La("git",e,t?{cwd:t}:void 0);function Ma(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 Ui=async(e,t,r)=>{try{if(await ue(["init"],e),await ue(["add","."],e),await ue(["commit","-m","Initial commit from @teispace/next-maker"],e),t&&(Ma(t),await ue(["remote","add","origin",t],e),r)){await ue(["fetch","origin"],e);let i="main";try{await ue(["show-branch","origin/main"],e)}catch{try{await ue(["show-branch","origin/master"],e),i="master"}catch{i="main"}}await ue(["merge",`origin/${i}`,"--allow-unrelated-histories","-X","ours"],e),await ue(["push","origin",`HEAD:${i}`],e)}}catch(i){console.warn("Failed to initialize git repository",i)}};import{execFile as Ga}from"node:child_process";import{promisify as Ha}from"node:util";var Ua=Ha(Ga),Qe=(e,t,r)=>Ua(e,t,{cwd:r}),Bi=async(e,t)=>{try{await Qe(t,["install"],e)}catch(r){throw new Error(`Failed to install dependencies with ${t}: ${r}`,{cause:r})}},K=async(e,t,r)=>{let i=t==="npm"?["run",r]:[r];try{await Qe(t,i,e)}catch(n){console.warn(`Warning: Failed to run script '${r}': ${n}`)}},Ba=()=>{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":Ba()},Ir=async(e,t,r)=>{if(r.length!==0)try{await Qe(t,[...zi(t),...r],e)}catch(i){throw new Error(`Failed to install packages with ${t}: ${i}`,{cause:i})}},zi=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 Ir(e,r,[t])},za=e=>{switch(e){case"npm":return"--save-dev";case"yarn":case"pnpm":case"bun":return"-D";default:return"--save-dev"}},fe=async(e,t,r)=>{if(r.length!==0)try{await Qe(t,[...zi(t),za(t),...r],e)}catch(i){throw new Error(`Failed to install dev packages with ${t}: ${i}`,{cause:i})}},At=async(e,t)=>{let r=await A(e);await fe(e,r,[t])},$r=async(e,t,r)=>{if(r.length!==0)try{await Qe(t,[...Va(t),...r],e)}catch(i){throw new Error(`Failed to uninstall packages with ${t}: ${i}`,{cause:i})}},Va=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 $r(e,r,[t])};import Ja from"enquirer";var Wa=/^[a-z0-9-_]+$/,qa=/^\d+\.\d+\.\d+$/,Vi=e=>Wa.test(e),Xa=e=>qa.test(e),Ji=(e,t={})=>{let r=t.projectName??e??"my-app";if(!Vi(r))throw new Error(`Invalid project name "${r}". Use lowercase letters, digits, hyphens, and underscores only.`);let i=t.version??"0.1.0";if(!Xa(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:Ya}=Ja,Wi=async e=>{if(e!==void 0&&!Vi(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 Ya([{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 Ka from"node:path";var ce=async(e,t)=>{let r=Za(t);await h(Ka.join(e,"test/test-utils.tsx"),r)},Za=({redux:e,i18n:t})=>e&&t?Qa:e?ec:t?tc:rc,Qa=`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
- `,ua=`import { type RenderOptions, render } from '@testing-library/react';
88
+ `,ec=`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
- `,fa=`import { type RenderOptions, render } from '@testing-library/react';
127
+ `,tc=`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
- `,ga=`import { type RenderOptions, render } from '@testing-library/react';
167
+ `,rc=`import { type RenderOptions, render } from '@testing-library/react';
168
168
  import type { ReactElement, ReactNode } from 'react';
169
169
 
170
170
  type TestProvidersProps = {
@@ -186,13 +186,15 @@ 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 xn from"node:path";var T={REDUX_TOOLKIT:"@reduxjs/toolkit",REACT_REDUX:"react-redux",REDUX:"redux",REDUX_PERSIST:"redux-persist",REACT_SECURE_STORAGE:"react-secure-storage",NEXT_INTL:"next-intl",NEXT_THEMES:"@teispace/next-themes",AXIOS:"axios",HUSKY:"husky",COMMITLINT_CLI:"@commitlint/cli",COMMITLINT_CONFIG:"@commitlint/config-conventional",LINT_STAGED:"lint-staged",COMMITIZEN:"commitizen",CZ_CONVENTIONAL_CHANGELOG:"cz-conventional-changelog",VITEST:"vitest",JSDOM:"jsdom",VITE_PLUGIN_REACT:"@vitejs/plugin-react",TESTING_LIBRARY_DOM:"@testing-library/dom",TESTING_LIBRARY_JEST_DOM:"@testing-library/jest-dom",TESTING_LIBRARY_REACT:"@testing-library/react",TESTING_LIBRARY_USER_EVENT:"@testing-library/user-event",REACT_COMPILER_BABEL:"babel-plugin-react-compiler",NEXT_BUNDLE_ANALYZER:"@next/bundle-analyzer"};S();P();var Pn=async(e,t)=>{if(t.bundleAnalyzer)return;let r=xn.join(e,c.NEXT_CONFIG);if(m(r)){let n=await u(r);n=n.replace(/import\s+withBundleAnalyzer\s+from\s+'@next\/bundle-analyzer';\n/,""),n=n.replace(/const\s+bundleAnalyzer\s*=\s*withBundleAnalyzer\(\{[\s\S]*?\}\);\n+/,""),n=n.replace(/bundleAnalyzer\(([^)]*)\)/,"$1"),await g(r,n)}await D(xn.join(e,c.PACKAGE_JSON),n=>(n.devDependencies&&delete n.devDependencies[T.NEXT_BUNDLE_ANALYZER],n.scripts&&delete n.scripts.analyze,n))};S();P();import Ue from"node:path";var wn=async(e,t)=>{t.darkMode||(await C(Ue.join(e,c.THEME_PROVIDER)),await ha(e),await ya(e),await Pa(e))},ha=async e=>{let t=Ue.join(e,c.PROVIDERS_INDEX),r=await u(t);r=r.replace(/export \* from '\.\/CustomThemeProvider';\n/,""),await g(t,r)},ya=async e=>{let t=Ue.join(e,c.GLOBALS_CSS);if(m(t)){let r=await u(t);r=r.replace(/@custom-variant dark \(.*?\);\n\n/,""),r=r.replace(/@theme \{[\s\S]*?\}\n/,""),await g(t,r)}},xa=e=>e.replace(/\bbg-light\b\s?/g,"").replace(/\bdark:bg-dark\b\s?/g,"").replace(/\s{2,}/g," ").replace(/suppressHydrationWarning=\{true\}/g,""),Pa=async e=>{let t=[Ue.join(e,c.ROOT_LAYOUT),Ue.join(e,"src/app/[locale]/layout.tsx")];for(let r of t)if(m(r)){let n=await u(r),i=xa(n);i!==n&&await g(r,i)}};S();P();ze();import _ from"node:path";var bn=async(e,t)=>{let r=_.join(e,c.HTTP_UTILS),n=t.httpClient!=="none"||!!t.reactSecureStorage;t.httpClient==="none"?(await Be(e),await ba(e,r,n)):t.httpClient==="axios"?(await Ra(e,r),await ke(e,["axios"]),await Ae(e,["axios"])):t.httpClient==="fetch"?(await $a(e,r),await ke(e,["fetch"]),await Ae(e,["fetch"])):t.httpClient},ba=async(e,t,r)=>{await w(_.join(e,c.AXIOS_CLIENT)),await w(_.join(e,c.FETCH_CLIENT)),r?(await g(_.join(t,"index.ts"),`export * from './token-store';
190
- `),await C(_.join(e,c.CLIENT_UTILS)),await Ne(e,[])):(await w(t),await Ia(e),await C(_.join(e,c.APP_APIS)),await Na(e)),await ka(e),await w(_.join(e,c.ERRORS_DIR)),r||(await w(_.join(e,c.COMMON_TYPES_DIR)),await w(_.join(e,c.UTILITY_TYPES_DIR)),await Aa(e))},Ra=async(e,t)=>{await w(_.join(e,c.FETCH_CLIENT));let r=await u(_.join(t,"index.ts"));r=r.replace(/export .* from '\.\/fetch-client';\n/g,""),await g(_.join(t,"index.ts"),r);let n=_.join(e,c.HTTP_TYPES);if(m(n)){let i=await u(n);i=i.replace(/export interface FetchClientOptions \{[\s\S]*?\}\n\n/,""),i=i.replace(/export interface ExtendedRequestInit extends RequestInit \{[\s\S]*?\}\n\n/,""),await g(n,i)}},$a=async(e,t)=>{await w(_.join(e,c.AXIOS_CLIENT));let r=await u(_.join(t,"index.ts"));r=r.replace(/export .* from '\.\/axios-client';\n/g,""),await g(_.join(t,"index.ts"),r),await Ne(e,["fetch"]);let n=_.join(e,c.HTTP_TYPES);if(m(n)){let i=await u(n);i=i.replace(/export interface AxiosClientOptions \{[\s\S]*?\}\n\n/,""),await g(n,i)}},Ia=async e=>{let t=_.join(e,c.UTILS_INDEX);if(m(t)){let r=await u(t);r=r.replace(/export \* from '\.\/http';\n/,""),await g(t,r)}},Na=async e=>{let t=_.join(e,c.CONFIG_INDEX);if(m(t)){let r=await u(t);r=r.replace(/export \* from '\.\/app-apis';\n/,""),await g(t,r)}},ka=async e=>{let t=_.join(e,c.CONSTANTS);if(m(t)){let r=await u(t);r=r.replace(/export const API_RESPONSE_DATA_KEY = 'data';\n/,""),r=er(r),await g(t,r)}},Aa=async e=>{let t=_.join(e,c.TYPES_INDEX);if(m(t)){let r=await u(t);r=r.replace(/export \* from '\.\/utility';\n/,""),r=r.replace(/export \* from '\.\/common';\n/,""),await g(t,r)}};S();P();import q from"node:path";var Rn=async(e,t)=>{t.i18n||(await Oa(e),await Fa(e),await ja(e),await Da(e),await _a(e))},_a=async e=>{let t=q.join(e,c.ENV_EXAMPLE);if(!m(t))return;let r=await u(t);r=r.replace(/#[^\n]*IANA time zone[\s\S]*?DEFAULT_TIMEZONE=[^\n]*\n?/,""),r=r.replace(/#[^\n]*Fallback locale[\s\S]*?DEFAULT_LOCALE=[^\n]*\n?/,""),r=r.replace(/^DEFAULT_TIMEZONE=.*\n?/m,""),r=r.replace(/^DEFAULT_LOCALE=.*\n?/m,""),await g(t,r)},Oa=async e=>{await w(q.join(e,c.I18N_DIR)),await w(q.join(e,c.LOCALE_DIR)),await C(q.join(e,c.PROXY)),await C(q.join(e,c.MIDDLEWARE)),await C(q.join(e,c.I18N_TYPES)),await C(q.join(e,c.APP_LOCALES))},Fa=async e=>{let t=q.join(e,c.TYPES_INDEX);if(m(t)){let n=await u(t);n=n.replace(/export \* from '\.\/i18n';\n/,""),await g(t,n)}let r=q.join(e,c.CONFIG_INDEX);if(m(r)){let n=await u(r);n=n.replace(/export \* from '\.\/app-locales';\n/,""),await g(r,n)}},ja=async e=>{let t=q.join(e,c.NEXT_CONFIG);if(m(t)){let r=await u(t);r=r.replace(/import createNextIntlPlugin from 'next-intl\/plugin';\n/,""),r=r.replace(/const withNextIntl = createNextIntlPlugin\(\);\n+/,""),r=r.replace(/withNextIntl\(([^)]+)\)/,"$1"),await g(t,r)}},Da=async e=>{let t=q.join(e,c.COUNTER_COMPONENT);if(m(t)){let i=await u(t);i=i.replace(/import\s+\{\s*useTranslations\s*\}\s+from\s+['"]next-intl['"];\n/,""),i=i.replace(/\s*const\s+t\s*=\s*useTranslations\(['"]Count['"]\);\n/,""),i=i.replace(/\{t\('currentCount',\s*\{\s*count:\s*value\s*\}\)\}/g,"Current Count: {value}"),i=i.replace(/\{t\(['"]increment['"]\)\}/g,"Increment"),i=i.replace(/\{t\(['"]decrement['"]\)\}/g,"Decrement"),i=i.replace(/\{t\(['"]reset['"]\)\}/g,"Reset"),await g(t,i)}let r=q.join(e,"src/features/counter/components/Counter.test.tsx"),n=q.join(e,"test/test-utils.tsx");await C(r),await C(n)};S();P();import de from"node:path";var $n=async(e,t)=>{t.httpClient!=="none"||t.reactSecureStorage||await w(de.join(e,c.STORAGE_SERVICE))},In=async e=>{await C(de.join(e,c.LICENSE))},Nn=async e=>{await C(de.join(e,c.CHANGELOG))},kn=async e=>{await C(de.join(e,c.NVM_RC)),await C(de.join(e,c.NPM_RC))},An=async e=>{await w(de.join(e,c.CLAUDE_DIR)),await w(de.join(e,c.DOCS_DIR)),await w(de.join(e,c.VSCODE_DIR))};import _n from"node:path";S();P();var On=async(e,t)=>{if(t.reactCompiler)return;let r=_n.join(e,c.NEXT_CONFIG);if(m(r)){let n=await u(r);n=n.replace(/^\s*reactCompiler:\s*true,?\n/m,""),await g(r,n)}await D(_n.join(e,c.PACKAGE_JSON),n=>(n.devDependencies&&delete n.devDependencies[T.REACT_COMPILER_BABEL],n))};S();P();import we from"node:path";var Fn=async(e,t)=>{t.redux||(await w(we.join(e,c.STORE)),await w(we.join(e,c.COUNTER_FEATURE)),await C(we.join(e,c.STORE_PROVIDER)),await C(we.join(e,"test/test-utils.tsx")),await La(e),await Ma(e))},La=async e=>{let t=we.join(e,c.PROVIDERS_INDEX),r=await u(t);r=r.replace(/export \* from '\.\/StoreProvider';\n/,""),await g(t,r)},Ma=async e=>{let t=[we.join(e,c.ROOT_PAGE),we.join(e,c.LOCALE_PAGE)];for(let r of t)if(m(r)){let n=await u(r);n=n.replace(/import\s+\{\s*Counter\s*\}\s+from\s+['"]@\/features\/counter['"];\n?/,""),n=n.replace(/<Counter\s*\/>\n?/g,""),await g(r,n)}};S();P();import jn from"node:path";var Dn=async(e,t)=>{if(t.i18n)return;let r=jn.join(e,c.SEO_FILE);m(r)&&await g(r,Ga);let n=jn.join(e,c.SITEMAP_FILE);m(n)&&await g(n,Ua)},Ga=`import type { Metadata } from 'next';
189
+ `;import Xi 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 Yi=async(e,t)=>{if(t.bundleAnalyzer)return;let r=Xi.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 _(Xi.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 et from"node:path";var Ki=async(e,t)=>{t.darkMode||(await C(et.join(e,a.THEME_PROVIDER)),await ic(e),await nc(e),await sc(e))},ic=async e=>{let t=et.join(e,a.PROVIDERS_INDEX),r=await g(t);r=r.replace(/export \* from '\.\/CustomThemeProvider';\n/,""),await h(t,r)},nc=async e=>{let t=et.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)}},oc=e=>e.replace(/\bbg-light\b\s?/g,"").replace(/\bdark:bg-dark\b\s?/g,"").replace(/\s{2,}/g," ").replace(/suppressHydrationWarning=\{true\}/g,""),sc=async e=>{let t=[et.join(e,a.ROOT_LAYOUT),et.join(e,"src/app/[locale]/layout.tsx")];for(let r of t)if(l(r)){let i=await g(r),n=oc(i);n!==i&&await h(r,n)}};P();w();Be();import j from"node:path";var nn=async(e,t)=>{let r=j.join(e,a.HTTP_UTILS),i=t.httpClient!=="none"||!!t.reactSecureStorage;t.httpClient==="none"?(await rt(e),await uc(e,r,i)):t.httpClient==="axios"?(await fc(e,r),await we(e,["axios"]),await Pe(e,["axios"])):t.httpClient==="fetch"?(await gc(e,r),await we(e,["fetch"]),await Pe(e,["fetch"])):t.httpClient},uc=async(e,t,r)=>{await v(j.join(e,a.AXIOS_CLIENT)),await v(j.join(e,a.FETCH_CLIENT)),r?(await h(j.join(t,"index.ts"),`export * from './token-store';
190
+ `),await C(j.join(e,a.CLIENT_UTILS)),await Ue(e,[])):(await v(t),await hc(e),await C(j.join(e,a.APP_APIS)),await yc(e)),await xc(e),await v(j.join(e,a.ERRORS_DIR)),r||(await v(j.join(e,a.COMMON_TYPES_DIR)),await v(j.join(e,a.UTILITY_TYPES_DIR)),await wc(e))},fc=async(e,t)=>{await v(j.join(e,a.FETCH_CLIENT));let r=await g(j.join(t,"index.ts"));r=r.replace(/export .* from '\.\/fetch-client';\n/g,""),await h(j.join(t,"index.ts"),r);let i=j.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)}},gc=async(e,t)=>{await v(j.join(e,a.AXIOS_CLIENT));let r=await g(j.join(t,"index.ts"));r=r.replace(/export .* from '\.\/axios-client';\n/g,""),await h(j.join(t,"index.ts"),r),await Ue(e,["fetch"]);let i=j.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)}},hc=async e=>{let t=j.join(e,a.UTILS_INDEX);if(l(t)){let r=await g(t);r=r.replace(/export \* from '\.\/http';\n/,""),await h(t,r)}},yc=async e=>{let t=j.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)}},xc=async e=>{let t=j.join(e,a.CONSTANTS);if(l(t)){let r=await g(t);r=r.replace(/export const API_RESPONSE_DATA_KEY = 'data';\n/,""),r=Or(r),await h(t,r)}},wc=async e=>{let t=j.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 Q from"node:path";var on=async(e,t)=>{t.i18n||(await vc(e),await Sc(e),await Ec(e),await Tc(e),await Pc(e))},Pc=async e=>{let t=Q.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)},vc=async e=>{await v(Q.join(e,a.I18N_DIR)),await v(Q.join(e,a.LOCALE_DIR)),await C(Q.join(e,a.PROXY)),await C(Q.join(e,a.MIDDLEWARE)),await C(Q.join(e,a.I18N_TYPES)),await C(Q.join(e,a.APP_LOCALES))},Sc=async e=>{let t=Q.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=Q.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)}},Ec=async e=>{let t=Q.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)}},Tc=async e=>{let t=Q.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=Q.join(e,"src/features/counter/components/Counter.test.tsx"),i=Q.join(e,"test/test-utils.tsx");await C(r),await C(i)};P();w();import ve from"node:path";var sn=async(e,t)=>{t.httpClient!=="none"||t.reactSecureStorage||await v(ve.join(e,a.STORAGE_SERVICE))},an=async e=>{await C(ve.join(e,a.LICENSE))},cn=async e=>{await C(ve.join(e,a.CHANGELOG))},pn=async e=>{await C(ve.join(e,a.NVM_RC)),await C(ve.join(e,a.NPM_RC))},ln=async e=>{await v(ve.join(e,a.CLAUDE_DIR)),await v(ve.join(e,a.DOCS_DIR)),await v(ve.join(e,a.VSCODE_DIR))};import mn from"node:path";P();w();var dn=async(e,t)=>{if(t.reactCompiler)return;let r=mn.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 _(mn.join(e,a.PACKAGE_JSON),i=>(i.devDependencies&&delete i.devDependencies[R.REACT_COMPILER_BABEL],i))};P();w();import $e from"node:path";var un=async(e,t)=>{t.redux||(await v($e.join(e,a.STORE)),await v($e.join(e,a.COUNTER_FEATURE)),await C($e.join(e,a.STORE_PROVIDER)),await C($e.join(e,"test/test-utils.tsx")),await Cc(e),await Rc(e))},Cc=async e=>{let t=$e.join(e,a.PROVIDERS_INDEX),r=await g(t);r=r.replace(/export \* from '\.\/StoreProvider';\n/,""),await h(t,r)},Rc=async e=>{let t=[$e.join(e,a.ROOT_PAGE),$e.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 fn from"node:path";var gn=async(e,t)=>{if(t.i18n)return;let r=fn.join(e,a.SEO_FILE);l(r)&&await h(r,bc);let i=fn.join(e,a.SITEMAP_FILE);l(i)&&await h(i,Ic)},bc=`import type { Metadata } from 'next';
191
191
 
192
192
  import { env } from '@/lib/env';
193
193
 
194
194
  const APP_URL = env.NEXT_PUBLIC_APP_URL;
195
195
  const APP_NAME = 'Nextjs Starter';
196
+ /** Route served by \`src/app/opengraph-image.tsx\`; relative so \`metadataBase\` resolves it. */
197
+ const DEFAULT_OG_IMAGE_PATH = '/opengraph-image';
196
198
 
197
199
  type SEOParams = {
198
200
  title: string;
@@ -210,7 +212,7 @@ export function generateSEOMetadata({
210
212
  noIndex = false,
211
213
  }: SEOParams): Metadata {
212
214
  const url = \`\${APP_URL}\${path}\`;
213
- const ogImage = image || \`\${APP_URL}/og-image.png\`;
215
+ const ogImage = image ?? DEFAULT_OG_IMAGE_PATH;
214
216
 
215
217
  return {
216
218
  title,
@@ -253,8 +255,8 @@ export function generateSEOMetadata({
253
255
  };
254
256
  }
255
257
 
256
- export { APP_NAME, APP_URL };
257
- `,Ua=`import type { MetadataRoute } from 'next';
258
+ export { APP_NAME, APP_URL, DEFAULT_OG_IMAGE_PATH };
259
+ `,Ic=`import type { MetadataRoute } from 'next';
258
260
 
259
261
  import { env } from '@/lib/env';
260
262
 
@@ -270,13 +272,13 @@ export default function sitemap(): MetadataRoute.Sitemap {
270
272
  priority: path === '/' ? 1 : 0.8,
271
273
  }));
272
274
  }
273
- `;import ft from"node:path";S();P();var Ha=[T.VITEST,T.JSDOM,T.VITE_PLUGIN_REACT,T.TESTING_LIBRARY_DOM,T.TESTING_LIBRARY_JEST_DOM,T.TESTING_LIBRARY_REACT,T.TESTING_LIBRARY_USER_EVENT],Ln=async(e,t)=>{t.tests||(await C(ft.join(e,c.VITEST_CONFIG)),await w(ft.join(e,c.TEST_DIR)),await C(ft.join(e,"src/features/counter/components/Counter.test.tsx")),await D(ft.join(e,c.PACKAGE_JSON),r=>{if(r.devDependencies)for(let n of Ha)delete r.devDependencies[n];return r.scripts&&(delete r.scripts.test,delete r.scripts["test:watch"],delete r.scripts["test:coverage"],typeof r.scripts.validate=="string"&&(r.scripts.validate=r.scripts.validate.replace(/\s*&&\s*yarn\s+test(?![:\w])/,"").replace(/\byarn\s+test(?![:\w])\s*&&\s*/,""))),r}))};S();P();import We from"node:path";S();P();import Mn from"node:path";import{readFile as Ba,writeFile as za}from"node:fs/promises";import Va from"node:path";var Ve=(e,t)=>{let r=/import\s+.*\s+from\s+['"].*['"];?\n/g,n=e.match(r);if(n&&n.length>0){let i=n[n.length-1],o=e.lastIndexOf(i);return e.slice(0,o+i.length)+t+`
274
- `+e.slice(o+i.length)}return`${t}
275
- ${e}`},or=(e,t,r)=>{let n=/combineReducers\(\{([^}]*)\}\)/s,i=e.match(n);if(!i)throw new Error("Could not find combineReducers in rootReducer.ts");let o=i[1],s=`
276
- ${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()}
275
+ `;import $c from"node:fs/promises";import it from"node:path";P();w();var kc=[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],hn=async e=>{let t;try{t=await $c.readdir(e,{withFileTypes:!0})}catch{return}for(let r of t){let i=it.join(e,r.name);if(r.isDirectory()){if(r.name==="__test-utils__"||r.name==="__tests__"){await v(i);continue}await hn(i)}else r.isFile()&&/\.(test|spec)\.tsx?$/.test(r.name)&&await C(i)}},yn=async(e,t)=>{t.tests||(await C(it.join(e,a.VITEST_CONFIG)),await v(it.join(e,a.TEST_DIR)),await hn(it.join(e,a.SRC)),await _(it.join(e,a.PACKAGE_JSON),r=>{if(r.devDependencies)for(let i of kc)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 ze from"node:path";P();w();import xn from"node:path";import{readFile as Nc,writeFile as Ac}from"node:fs/promises";import _c from"node:path";var nt=(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+`
276
+ `+e.slice(o+n.length)}return`${t}
277
+ ${e}`},Mr=(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=`
278
+ ${t}: ${r},`,c=o.trimEnd()+s;return e.replace(i,`combineReducers({${c}
279
+ })`)},ot=(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
280
  ${t}
279
- ${i}`};var ve=async e=>{let{projectPath:t,name:r,persist:n,importPath:i}=e,o=Va.join(t,"src","store","rootReducer.ts");try{let s=await Ba(o,"utf-8"),a=j(r),p=`${a}Reducer`,f=`${a}PersistConfig`,d=i.replace(/^src\//,"@/"),h=n?`import { ${p}, ${f} } from '${d}';`:`import { ${p} } from '${d}';`;s=Ve(s,h);let x=n?`persistReducer(${f}, ${p})`:p;s=or(s,a,x),await za(o,s)}catch(s){throw new Error(`Failed to register reducer '${r}' in rootReducer: ${s}`,{cause:s})}};var Gn="import { attachWsBridge, wsClient } from '@/lib/utils/ws';",Ja=`
281
+ ${n}`};var ke=async e=>{let{projectPath:t,name:r,persist:i,importPath:n}=e,o=_c.join(t,"src","store","rootReducer.ts");try{let s=await Nc(o,"utf-8"),c=G(r),p=`${c}Reducer`,u=`${c}PersistConfig`,d=n.replace(/^src\//,"@/"),f=i?`import { ${p}, ${u} } from '${d}';`:`import { ${p} } from '${d}';`;s=nt(s,f);let x=i?`persistReducer(${u}, ${p})`:p;s=Mr(s,c,x),await Ac(o,s)}catch(s){throw new Error(`Failed to register reducer '${r}' in rootReducer: ${s}`,{cause:s})}};var wn="import { attachWsBridge, wsClient } from '@/lib/utils/ws';",Fc=`
280
282
  // Bridge the WS client's lifecycle into the Redux slice exactly once per
281
283
  // store instance. The bridge does not open a connection \u2014 that happens
282
284
  // lazily on first \`useWsEvent\` subscription or an explicit \`connect()\`.
@@ -286,12 +288,12 @@ ${i}`};var ve=async e=>{let{projectPath:t,name:r,persist:n,importPath:i}=e,o=Va.
286
288
  if (!store) return;
287
289
  return attachWsBridge(wsClient, store.dispatch);
288
290
  }, []);
289
- `,Un=async e=>{await ve({projectPath:e,name:"ws",persist:!1,importPath:"src/store/slices/ws.slice"})},Wa=e=>{if(e.includes("from '@/lib/utils/ws'"))return e;let t=e,r=/(^import\s[^\n]*\n)+/m,n=t.match(r);if(!n)throw new Error("injectBridgeMount: no `import` lines found \u2014 expected a StoreProvider with imports.");let i=(n.index??0)+n[0].length;t=`${t.slice(0,i)}${Gn}
290
- ${t.slice(i)}`,t=Ka(t);let o=/(if\s*\(\s*!storeRef\.current\s*\)\s*\{[\s\S]*?\n\s*\})/;if(!t.match(o))throw new Error("injectBridgeMount: could not locate `if (!storeRef.current) { ... }` initializer \u2014 StoreProvider shape unexpected.");return t=t.replace(o,`$1
291
- ${Ja.trimEnd()}
292
- `),t},gt=e=>{let t=e;return t=t.replace(new RegExp(`${Za(Gn)}\\n?`),""),t=t.replace(/\n(?:[ \t]*\/\/[^\n]*\n)*[ \t]*useEffect\(\(\)\s*=>\s*\{[\s\S]*?attachWsBridge\(wsClient,\s*store\.dispatch\)[\s\S]*?\},\s*\[\]\);\n?/,`
293
- `),/\buseEffect\s*\(/.test(t)||(t=qa(t)),t},qa=e=>{let t=/import\s*\{([^}]*)\}\s*from\s*['"]react['"];\n?/,r=e.match(t);if(!r)return e;let n=r[1].split(",").map(o=>o.trim()).filter(o=>o.length>0&&o!=="useEffect");if(n.length===0)return e.replace(t,"");let i=`import { ${n.join(", ")} } from 'react';
294
- `;return e.replace(t,i)},Hn=async e=>{let t=Mn.join(e,c.STORE_PROVIDER);if(!m(t))return;let r=await u(t),n=Wa(r);n!==r&&await g(t,n)};var Bn=async e=>{let t=Mn.join(e,c.TEST_SETUP_FILE);if(!m(t))return;let r=await u(t),n=!1;r.includes("vi.mock('react-secure-storage'")||(r+=Xa,n=!0),r.includes("vi.mock('server-only'")||(r+=Ya,n=!0),n&&await g(t,r)},Xa=`
291
+ `,Ft=async e=>{await ke({projectPath:e,name:"ws",persist:!1,importPath:"src/store/slices/ws.slice"})},Oc=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)}${wn}
292
+ ${t.slice(n)}`,t=Mc(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
293
+ ${Fc.trimEnd()}
294
+ `),t},Ot=e=>{let t=e;return t=t.replace(new RegExp(`${Gc(wn)}\\n?`),""),t=t.replace(/\n(?:[ \t]*\/\/[^\n]*\n)*[ \t]*useEffect\(\(\)\s*=>\s*\{[\s\S]*?attachWsBridge\(wsClient,\s*store\.dispatch\)[\s\S]*?\},\s*\[\]\);\n?/,`
295
+ `),/\buseEffect\s*\(/.test(t)||(t=Dc(t)),t},Dc=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';
296
+ `;return e.replace(t,n)},Dt=async e=>{let t=xn.join(e,a.STORE_PROVIDER);if(!l(t))return;let r=await g(t),i=Oc(r);i!==r&&await h(t,i)};var jt=async e=>{let t=xn.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+=jc,i=!0),r.includes("vi.mock('server-only'")||(r+=Lc,i=!0),i&&await h(t,r)},jc=`
295
297
  // \`react-secure-storage\` constructs an \`EncryptionService\` at module load
296
298
  // that fingerprints the browser via \`<canvas>.getContext\`. jsdom doesn't
297
299
  // implement canvas, so the import explodes anywhere it's pulled in
@@ -308,15 +310,15 @@ vi.mock('react-secure-storage', () => {
308
310
  },
309
311
  };
310
312
  });
311
- `,Ya=`
313
+ `,Lc=`
312
314
  // \`server-only\` throws at module load outside a Next.js server bundle \u2014
313
315
  // the package relies on bundler-level redirect to a no-op file in server
314
316
  // environments. Vitest doesn't do that redirect, so we stub it as a no-op
315
317
  // to let unit tests reach the server-side modules. Production builds are
316
318
  // unaffected; Next.js still routes \`server-only\` to its real implementation.
317
319
  vi.mock('server-only', () => ({}));
318
- `,Ka=e=>{let t=/import\s*\{([^}]*)\}\s*from\s*['"]react['"];/,r=e.match(t);if(!r)return e;let n=r[1];if(/\buseEffect\b/.test(n))return e;let i=n.split(",").map(s=>s.trim()).filter(Boolean);i.push("useEffect"),i.sort();let o=`import { ${i.join(", ")} } from 'react';`;return e.replace(t,o)},Za=e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),ht=e=>{let t=e;return t=t.replace(/^import\s*\{\s*wsReducer\s*\}\s*from\s*['"][^'"]*ws\.slice['"];\n?/m,""),t=t.replace(/^\s*ws:\s*wsReducer,?\n/m,""),t=t.replace(/\/\*\*[^*]*(?:\*(?!\/)[^*]*)*\bws\b[^*]*(?:\*(?!\/)[^*]*)*\bpersistReducer\b[\s\S]*?\*\/\n?/,""),t};var zn=async(e,t)=>{t.ws||(await w(We.join(e,c.WS_UTILS)),await C(We.join(e,c.WS_SLICE_FILE)),t.redux&&(await Qa(e),await ec(e)),await tc(e))},Qa=async e=>{let t=We.join(e,c.ROOT_REDUCER);if(!m(t))return;let r=await u(t),n=ht(r);n!==r&&await g(t,n)},ec=async e=>{let t=We.join(e,c.STORE_PROVIDER);if(!m(t))return;let r=await u(t),n=gt(r);n!==r&&await g(t,n)},tc=async e=>{let t=We.join(e,c.PACKAGE_JSON);if(!m(t))return;let r=JSON.parse(await u(t));({...r.dependencies,...r.devDependencies})["socket.io-client"]&&await Ie(e,"socket.io-client")};var Vn=async(e,t)=>{let r=b("Customizing features...");try{await bn(e,t),await $n(e,t),await zn(e,t),await Fn(e,t),await wn(e,t),await Pn(e,t),await Rn(e,t),await Dn(e,t),await On(e,t),await Ln(e,t),await In(e),await Nn(e),await kn(e),await An(e),t.tests&&await me(e,{redux:t.redux,i18n:t.i18n}),r.succeed("Features customized.")}catch(n){throw r.fail("Failed to customize features."),n}};import rc from"node:path";S();P();var Jn=async(e,t)=>{let r=b("Configuring package.json...");try{let n=t.gitRemote,i=t.gitHomepage,o=t.gitIssues;t.gitRemote&&(t.gitRemote.startsWith("git@github.com:")&&(n=t.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"")),i||(i=`${n.replace(/\.git$/,"")}#readme`),o||(o=`${n.replace(/\.git$/,"")}/issues`),n.endsWith(".git")||(n=`${n}.git`)),await D(rc.join(e,c.PACKAGE_JSON),s=>(s.name=t.projectName,s.version=t.version,s.description=t.description,s.author=t.author,delete s.packageManager,t.gitRemote?(i&&(s.homepage=i),o&&(s.bugs={url:o}),n&&(s.repository={type:"git",url:n})):(delete s.homepage,delete s.bugs,delete s.repository),t.redux||(delete s.dependencies[T.REDUX_TOOLKIT],delete s.dependencies[T.REACT_REDUX],delete s.dependencies[T.REDUX],delete s.dependencies[T.REDUX_PERSIST]),t.httpClient!=="none"||t.reactSecureStorage||delete s.dependencies[T.REACT_SECURE_STORAGE],t.i18n||delete s.dependencies[T.NEXT_INTL],t.darkMode||delete s.dependencies[T.NEXT_THEMES],t.httpClient==="none"?delete s.dependencies[T.AXIOS]:t.httpClient==="fetch"&&delete s.dependencies[T.AXIOS],s)),r.succeed("package.json configured.")}catch(n){throw r.fail("Failed to configure package.json."),n}};import{readdir as Wn}from"node:fs/promises";import O from"node:path";S();P();var qn=async(e,t)=>{await nc(e,t),await ic(e,t),await oc(e,t),await sc(e,t),await ac(e,t),await cc(e,t),await pc(e,t)},nc=async(e,t)=>{t.preCommitHooks||(await w(O.join(e,c.HUSKY_DIR)),await C(O.join(e,c.COMMITLINT_CONFIG)),await C(O.join(e,c.LINTSTAGED_RC)),await D(O.join(e,c.PACKAGE_JSON),r=>(delete r.devDependencies[T.HUSKY],delete r.devDependencies[T.COMMITLINT_CLI],delete r.devDependencies[T.COMMITLINT_CONFIG],delete r.devDependencies[T.LINT_STAGED],delete r.scripts.prepare,delete r.scripts.postinstall,delete r.commitlint,delete r["lint-staged"],r)))},ic=async(e,t)=>{t.commitizen||(await C(O.join(e,c.CZRC)),await D(O.join(e,c.PACKAGE_JSON),r=>(delete r.devDependencies[T.COMMITIZEN],delete r.devDependencies[T.CZ_CONVENTIONAL_CHANGELOG],delete r.config?.commitizen,r.config&&Object.keys(r.config).length===0&&delete r.config,delete r.scripts.commit,r)))},oc=async(e,t)=>{t.ci||await w(O.join(e,c.GITHUB_WORKFLOWS))},sc=async(e,t)=>{let r=O.join(e,c.GITHUB_DIR);if(!t.keepTemplates)await w(O.join(r,c.GITHUB_ISSUE_TEMPLATE)),await C(O.join(r,c.GITHUB_PR_TEMPLATE));else{let n=O.join(r,c.GITHUB_ISSUE_TEMPLATE),i=O.join(r,c.GITHUB_PR_TEMPLATE),o=s=>s.replace(/Teispace/g,t.company).replace(/support@teispace\.com/g,t.email).replace(/Next\.js Starter/g,t.projectName).replace(/\[AUTHOR\]/g,t.author).replace(/\[COMPANY\]/g,t.company).replace(/\[EMAIL\]/g,t.email);if(m(i)){let s=await u(i);s=o(s),await g(i,s)}try{if(m(n)){let s=await Wn(n);for(let a of s){let p=O.join(n,a),f=await u(p);f=o(f),await g(p,f)}}}catch{}}},ac=async(e,t)=>{let r=[c.CODE_OF_CONDUCT,c.CONTRIBUTING,c.SECURITY];for(let n of r)t.communityFiles.includes(n)||await C(O.join(e,n))},cc=async(e,t)=>{if(t.docker){let r=O.join(e,c.ENV_EXAMPLE);if(m(r)){let n=await u(r),i=(o,s)=>{let a=new RegExp(`${o}=.*`);a.test(n)?n=n.replace(a,`${o}=${s}`):n+=`${o}=${s}
319
- `};i("CONTAINER_NAME",t.containerName||"next-app"),i("IMAGE_NAME",t.imageName||"nextjs-starter"),i("IMAGE_TAG",t.imageTag||"latest"),await g(r,n)}}else{await C(O.join(e,c.DOCKERFILE)),await C(O.join(e,c.DOCKER_COMPOSE)),await C(O.join(e,c.DOCKERIGNORE));let r=O.join(e,c.ENV_EXAMPLE);if(m(r)){let n=await u(r);n=n.replace(/# Docker Compose Configuration\n/,""),n=n.replace(/CONTAINER_NAME=.*\n/,""),n=n.replace(/IMAGE_NAME=.*\n/,""),n=n.replace(/IMAGE_TAG=.*\n/,""),await g(r,n)}}},pc=async(e,t)=>{let r=async o=>{let s=await Wn(o,{withFileTypes:!0}),a=[];for(let p of s){let f=O.join(o,p.name);p.isDirectory()&&p.name!=="node_modules"&&p.name!==".git"?a.push(...await r(f)):p.isFile()&&p.name.toLowerCase()==="readme.md"&&a.push(f)}return a},n=await r(e),i=O.join(e,c.README);for(let o of n)o!==i&&await C(o);if(t.readme){let o=`# ${t.projectName}
320
+ `,Mc=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)},Gc=e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),Lt=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 Pn=async(e,t)=>{t.ws||(await v(ze.join(e,a.WS_UTILS)),await C(ze.join(e,a.WS_SLICE_FILE)),await C(ze.join(e,a.WS_SLICE_TEST_FILE)),t.redux&&(await Hc(e),await Uc(e)),await Bc(e))},Hc=async e=>{let t=ze.join(e,a.ROOT_REDUCER);if(!l(t))return;let r=await g(t),i=Lt(r);i!==r&&await h(t,i)},Uc=async e=>{let t=ze.join(e,a.STORE_PROVIDER);if(!l(t))return;let r=await g(t),i=Ot(r);i!==r&&await h(t,i)},Bc=async e=>{let t=ze.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 vn=async(e,t)=>{let r=S("Customizing features...");try{await nn(e,t),await sn(e,t),await Pn(e,t),await un(e,t),await Ki(e,t),await Yi(e,t),await on(e,t),await gn(e,t),await dn(e,t),await yn(e,t),await an(e),await cn(e),await pn(e),await ln(e),t.tests&&await ce(e,{redux:t.redux,i18n:t.i18n}),r.succeed("Features customized.")}catch(i){throw r.fail("Failed to customize features."),i}};import zc from"node:path";P();w();var Sn=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 _(zc.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 En}from"node:fs/promises";import L from"node:path";P();w();var Tn=async(e,t)=>{await Vc(e,t),await Jc(e,t),await Wc(e,t),await qc(e,t),await Xc(e,t),await Yc(e,t),await Kc(e,t)},Vc=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 _(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)))},Jc=async(e,t)=>{t.commitizen||(await C(L.join(e,a.CZRC)),await _(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)))},Wc=async(e,t)=>{t.ci||await v(L.join(e,a.GITHUB_WORKFLOWS))},qc=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 En(i);for(let c of s){let p=L.join(i,c),u=await g(p);u=o(u),await h(p,u)}}}catch{}}},Xc=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))},Yc=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}
321
+ `};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)}}},Kc=async(e,t)=>{let r=async o=>{let s=await En(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
322
 
321
323
  ${t.description}
322
324
 
@@ -329,30 +331,30 @@ ${t.packageManager==="npm"?"npm run dev":`${t.packageManager} dev`}
329
331
  \`\`\`
330
332
 
331
333
  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 sr from"node:path";var Xn=async(e,t)=>{let r=[];t.i18n&&r.push("import { type AbstractIntlMessages, NextIntlClientProvider } from 'next-intl';"),t.darkMode&&r.push("import { CustomThemeProvider } from '@/providers';"),t.redux&&r.push("import type { AppState } from '@/store';"),t.i18n&&r.push("import type { SupportedLocale } from '@/types/i18n';"),t.redux&&r.push("import { StoreProvider } from './StoreProvider';");let n=["children: React.ReactNode;"],i=["children"];t.i18n&&(n.push("locale: SupportedLocale;"),n.push("messages: AbstractIntlMessages;"),n.push("timeZone: string;"),i.push("locale","messages","timeZone")),t.redux&&(n.push("preloadedState?: Partial<AppState>;"),i.push("preloadedState"));let o="{children}";t.i18n&&(o=`<NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>
334
+ `;await h(n,o)}else await C(n)};P();w();import Gr from"node:path";var Cn=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
335
  ${o}
334
336
  </NextIntlClientProvider>`),t.darkMode&&(o=`<CustomThemeProvider>
335
337
  ${o}
336
338
  </CustomThemeProvider>`),t.redux&&(o=`<StoreProvider preloadedState={preloadedState}>
337
339
  ${o}
338
340
  </StoreProvider>`),o==="{children}"&&(o="<>{children}</>");let s=`type RootProviderProps = {
339
- ${n.join(`
341
+ ${i.join(`
340
342
  `)}
341
- };`,a=`'use client';
343
+ };`,c=`'use client';
342
344
  ${r.join(`
343
345
  `)}
344
346
 
345
347
  ${s}
346
348
 
347
- export const RootProvider = ({ ${i.join(", ")} }: RootProviderProps) => {
349
+ export const RootProvider = ({ ${n.join(", ")} }: RootProviderProps) => {
348
350
  return (
349
351
  ${o}
350
352
  );
351
353
  };
352
- `;await g(sr.join(e,c.ROOT_PROVIDER),a)},Yn=async(e,t)=>{if(t.i18n)return;let r=`\`\${livvic.variable} ${t.darkMode?"bg-light antialiased dark:bg-dark":"antialiased"}\``,n=(t.redux,""),i=t.httpClient!=="none",o=i?`// Regression sentinel \u2014 see file comment for what this guards.
354
+ `;await h(Gr.join(e,a.ROOT_PROVIDER),c)},Rn=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
355
  import { HttpClientBundleSentinel } from '@/lib/utils/http/__bundle-sentinel__/client-bundle-sentinel';
354
- `:"",s=i?`
355
- <HttpClientBundleSentinel />`:"",a=`import type { Metadata } from 'next';
356
+ `:"",s=n?`
357
+ <HttpClientBundleSentinel />`:"",c=`import type { Metadata } from 'next';
356
358
  import '@/styles/globals.css';
357
359
  import { Livvic } from 'next/font/google';
358
360
  ${o}import { RootProvider } from '@/providers';
@@ -377,32 +379,32 @@ export default function RootLayout({
377
379
  return (
378
380
  <html lang="en"${t.darkMode?" suppressHydrationWarning={true}":""}>
379
381
  <body className={${r}}>
380
- <RootProvider${n}>${s}
382
+ <RootProvider${i}>${s}
381
383
  {children}
382
384
  </RootProvider>
383
385
  </body>
384
386
  </html>
385
387
  );
386
388
  }
387
- `;await g(sr.join(e,c.ROOT_LAYOUT),a);let p=t.redux?`import { Counter } from '@/features/counter';
389
+ `;await h(Gr.join(e,a.ROOT_LAYOUT),c);let p=t.redux?`import { Counter } from '@/features/counter';
388
390
 
389
- `:"",f=t.redux?`
391
+ `:"",u=t.redux?`
390
392
  <Counter />`:"",d=`${p}export default function Home() {
391
393
  return (
392
394
  <div className="flex min-h-screen flex-col items-center justify-center p-24">
393
395
  <h1 className="text-4xl font-bold">Welcome to ${t.projectName}</h1>
394
- <p className="mt-4 text-xl">Get started by editing src/app/page.tsx</p>${f}
396
+ <p className="mt-4 text-xl">Get started by editing src/app/page.tsx</p>${u}
395
397
  </div>
396
398
  );
397
399
  }
398
- `;await g(sr.join(e,c.ROOT_PAGE),d)};import lc from"degit";var Kn=async e=>{let t=b("Downloading template...");try{await lc("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!0}).clone(e),t.succeed("Template downloaded successfully.")}catch(r){throw t.fail("Failed to download template."),r}};var cr=["npm","yarn","pnpm","bun"],mc=e=>{if(e!==void 0){if(!cr.includes(e))throw new Error(`Invalid --package-manager "${e}". Valid: ${cr.join(", ")}.`);return e}},Zn=e=>{e.command("init").description("Initialize a new Next.js project").argument("[name]","Project name").option("-y, --yes","Skip all prompts and use the recommended production defaults").option("--package-manager <pm>",`Override the package manager (one of: ${cr.join(", ")})`).action(async(t,r)=>{try{let n=mc(r.packageManager);await uc(t,{yes:r.yes??!1,packageManager:n})}catch(n){v(`${n instanceof Error?n.message:n}`),process.exit(1)}})},qe=async(e,t,r,n)=>{let i=b(e);n.current=i;try{let o=await r();return i.succeed(t),o}finally{n.current===i&&(n.current=null)}},dc=e=>{let t=[];e.darkMode&&t.push("dark mode"),e.redux&&t.push("redux"),e.i18n&&t.push("i18n"),e.tests&&t.push("tests"),e.reactCompiler&&t.push("react-compiler"),e.preCommitHooks&&t.push("pre-commit hooks"),e.commitizen&&t.push("commitizen"),e.httpClient!=="none"&&t.push(`http (${e.httpClient})`),l(X.dim("Defaults applied (run `next-maker remove <feature>` to undo any of them):")),l(X.dim(` package manager : ${e.packageManager}`)),l(X.dim(` features : ${t.join(", ")}`)),l("")},uc=async(e,t)=>{pn();let r;t.yes?(r=gn(e,{packageManager:t.packageManager}),l(X.cyan(`\u2728 Bootstrapping ${r.projectName} with the recommended defaults`)),l(""),dc(r)):(l("Welcome to the Teispace Next.js App Creator!"),l(""),r=await hn(e),t.packageManager&&(r={...r,packageManager:t.packageManager}));let n=ar.resolve(process.cwd(),r.projectName);m(n)&&(console.error(X.red(`Error: Directory ${r.projectName} already exists.`)),process.exit(1));let i={current:null},o=async()=>{if(m(n)){i.current?.stop(),i.current=null,console.log(X.yellow(`
399
- Cleaning up: Deleting directory ${r.projectName}...`));try{await w(n),console.log(X.green("Cleanup successful."))}catch(a){console.error(X.red(`Failed to clean up directory ${r.projectName}:`),a)}}},s=sn(async()=>{console.log(X.red(`
400
- Process interrupted. Cleaning up...`)),await o()});try{if(await Kn(n),await Jn(n,r),await Vn(n,r),await qe("Generating providers and layout...","Providers and layout generated.",async()=>{await Xn(n,r),await Yn(n,r)},i),await qe("Setting up developer tools...","Developer tools configured.",()=>qn(n,r),i),await qe("Initializing Git...","Git initialized.",()=>mn(n,r.gitRemote,r.pushToRemote),i),await qe("Installing dependencies...","Dependencies installed.",()=>dn(n,r.packageManager),i),await qe("Formatting and linting...","Formatted.",()=>J(n,r.packageManager,"lint:fix"),i),r.copyEnv){let a=ar.join(n,".env.example"),p=ar.join(n,".env");m(a)&&await(await import("node:fs/promises")).copyFile(a,p)}s(),l(""),l(X.green(`\u2728 Project ${r.projectName} created successfully!`)),l(""),l("To get started:"),l(X.cyan(` cd ${r.projectName}`)),l(X.cyan(` ${r.packageManager==="npm"?"npm run dev":`${r.packageManager} dev`}`)),l("")}catch(a){s(),i.current?.fail("Failed to create project."),i.current=null,console.error(a),await o(),process.exit(1)}};import Sr from"node:path";import ne from"picocolors";import yt from"node:path";var Qn=/^[A-Za-z][A-Za-z0-9-]*$/,fc=/^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;function ei(e){return fc.test(e)}function H(e,t="name"){let r=e?.trim();if(!r)throw new Error(`A ${t} is required.`);if(!Qn.test(r))throw new Error(`Invalid ${t} "${e}". Use letters, digits, and hyphens only \u2014 no slashes, spaces, "..", or absolute paths.`);if(ei(r))throw new Error(`Invalid ${t} "${e}". That is a reserved name on Windows.`);return r}function re(e,t="path"){let r=e?.trim();if(!r)throw new Error(`A ${t} is required.`);let n=r.replace(/^\.\//,"");if(n.startsWith("/")||/^[a-zA-Z]:/.test(n))throw new Error(`Invalid ${t} "${e}". Must be a relative path inside the project (no leading "/" or drive letter).`);for(let i of n.split("/")){if(!Qn.test(i))throw new Error(`Invalid ${t} "${e}". Each segment must be kebab/camel-case (letters, digits, hyphens), separated by "/" \u2014 no "..", dots, or empty segments.`);if(ei(i))throw new Error(`Invalid ${t} "${e}". Segment "${i}" is reserved on Windows.`)}return n}function xt(e,...t){let r=yt.resolve(e),n=yt.resolve(r,...t),i=yt.relative(r,n);if(i===""||i===".")return n;if(i.startsWith("..")||yt.isAbsolute(i))throw new Error(`Refusing to write outside the project directory (resolved path escapes "${r}").`);return n}B();import{mkdir as oi,writeFile as lr}from"node:fs/promises";import Se from"node:path";P();var pr=e=>{let{componentName:t,isClient:r,hasI18n:n}=e,i=e.translationNamespace||t,o=[];return(r||n)&&o.push("'use client';"),n&&o.push("import { useTranslations } from 'next-intl';"),o.push(""),o.push(`export function ${t}() {`),n?(o.push(` const t = useTranslations('${i}');`),o.push(""),o.push(" return ("),o.push(" <div>"),o.push(" <h2>{t('title')}</h2>"),o.push(" </div>"),o.push(" );")):(o.push(" return ("),o.push(" <div>"),o.push(` <h2>${t}</h2>`),o.push(" </div>"),o.push(" );")),o.push("}"),o.push(""),o.join(`
401
- `)},ii=e=>`export { ${e.componentName} } from './${e.componentName}';
402
- `;var mr=async e=>{let{name:t,projectPath:r,isClient:n,hasI18n:i,featurePath:o}=e,s=I(t);o?await xc(s,r,o,n,i):await Pc(s,t,r,n,i)},xc=async(e,t,r,n,i)=>{let o=Se.join(t,r,"components");await oi(o,{recursive:!0}),await lr(Se.join(o,`${e}.tsx`),pr({componentName:e,isClient:n,hasI18n:i}))},Pc=async(e,t,r,n,i)=>{let o=Se.join(r,"src","components","common",e);await oi(o,{recursive:!0}),await lr(Se.join(o,`${e}.tsx`),pr({componentName:e,isClient:n,hasI18n:i})),await lr(Se.join(o,"index.ts"),ii({componentName:e}));let s=Se.join(r,"src","components","common","index.ts");await wc(s,`export { ${e} } from './${e}';
403
- `);let a=Se.join(r,"src","components","index.ts");await vc(a)},wc=async(e,t)=>{let r="";m(e)&&(r=await u(e)),r.includes(t.trim())||(r+=t,await g(e,r))},vc=async e=>{let t="";m(e)&&(t=await u(e));let r=`export * from './common';
404
- `;t.includes(r.trim())||(t+=r,await g(e,t))};import{writeFile as Sc}from"node:fs/promises";import Ec from"node:path";var si=e=>{let{camelName:t,pascalName:r,httpClient:n}=e,i=n==="axios"?"import { axiosClient } from '@/lib/utils/http';":"import { fetchClient } from '@/lib/utils/http';",o=n==="axios"?"axiosClient":"fetchClient";return`import { AppApis } from '@/lib/config';
405
- ${i}
400
+ `;await h(Gr.join(e,a.ROOT_PAGE),d)};import Zc from"degit";var bn="teispace/nextjs-starter",In="v1.1.0",Qc=()=>In==="main"?bn:`${bn}#${In}`,J=async(e,t={})=>{await Zc(Qc(),{cache:!1,force:!0,verbose:t.verbose??!1}).clone(e)};var $n=async e=>{let t=S("Downloading template...");try{await J(e,{verbose:!0}),t.succeed("Template downloaded successfully.")}catch(r){throw t.fail("Failed to download template."),r}};var Ur=["npm","yarn","pnpm","bun"],ep=e=>{if(e!==void 0){if(!Ur.includes(e))throw new Error(`Invalid --package-manager "${e}". Valid: ${Ur.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: ${Ur.join(", ")})`).action(async(t,r)=>{try{let i=ep(r.packageManager);await rp(t,{yes:r.yes??!1,packageManager:i})}catch(i){E(`${i instanceof Error?i.message:i}`),process.exit(1)}})},st=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)}},tp=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(ee.dim("Defaults applied (run `next-maker remove <feature>` to undo any of them):")),m(ee.dim(` package manager : ${e.packageManager}`)),m(ee.dim(` features : ${t.join(", ")}`)),m("")},rp=async(e,t)=>{Gi();let r;t.yes?(r=Ji(e,{packageManager:t.packageManager}),m(ee.cyan(`\u2728 Bootstrapping ${r.projectName} with the recommended defaults`)),m(""),tp(r)):(m("Welcome to the Teispace Next.js App Creator!"),m(""),r=await Wi(e),t.packageManager&&(r={...r,packageManager:t.packageManager}));let i=Hr.resolve(process.cwd(),r.projectName);l(i)&&(console.error(ee.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(ee.yellow(`
401
+ Cleaning up: Deleting directory ${r.projectName}...`));try{await v(i),console.log(ee.green("Cleanup successful."))}catch(c){console.error(ee.red(`Failed to clean up directory ${r.projectName}:`),c)}}},s=ji(async()=>{console.log(ee.red(`
402
+ Process interrupted. Cleaning up...`)),await o()});try{if(await $n(i),await Sn(i,r),await vn(i,r),await st("Generating providers and layout...","Providers and layout generated.",async()=>{await Cn(i,r),await Rn(i,r)},n),await st("Setting up developer tools...","Developer tools configured.",()=>Tn(i,r),n),await st("Initializing Git...","Git initialized.",()=>Ui(i,r.gitRemote,r.pushToRemote),n),await st("Installing dependencies...","Dependencies installed.",()=>Bi(i,r.packageManager),n),await st("Formatting and linting...","Formatted.",()=>K(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(ee.green(`\u2728 Project ${r.projectName} created successfully!`)),m(""),m("To get started:"),m(ee.cyan(` cd ${r.projectName}`)),m(ee.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 ri from"node:path";import le from"picocolors";import Mt from"node:path";var Nn=/^[A-Za-z][A-Za-z0-9-]*$/,ip=/^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;function An(e){return ip.test(e)}function W(e,t="name"){let r=e?.trim();if(!r)throw new Error(`A ${t} is required.`);if(!Nn.test(r))throw new Error(`Invalid ${t} "${e}". Use letters, digits, and hyphens only \u2014 no slashes, spaces, "..", or absolute paths.`);if(An(r))throw new Error(`Invalid ${t} "${e}". That is a reserved name on Windows.`);return r}function pe(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(!Nn.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(An(n))throw new Error(`Invalid ${t} "${e}". Segment "${n}" is reserved on Windows.`)}return i}function Gt(e,...t){let r=Mt.resolve(e),i=Mt.resolve(r,...t),n=Mt.relative(r,i);if(n===""||n===".")return i;if(n.startsWith("..")||Mt.isAbsolute(n))throw new Error(`Refusing to write outside the project directory (resolved path escapes "${r}").`);return i}q();import{mkdir as jn,writeFile as zr}from"node:fs/promises";import Ne from"node:path";w();var Br=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(`
403
+ `)},Dn=e=>`export { ${e.componentName} } from './${e.componentName}';
404
+ `;var Vr=async e=>{let{name:t,projectPath:r,isClient:i,hasI18n:n,featurePath:o}=e,s=N(t);o?await ap(s,r,o,i,n):await cp(s,t,r,i,n)},ap=async(e,t,r,i,n)=>{let o=Ne.join(t,r,"components");await jn(o,{recursive:!0}),await zr(Ne.join(o,`${e}.tsx`),Br({componentName:e,isClient:i,hasI18n:n}))},cp=async(e,t,r,i,n)=>{let o=Ne.join(r,"src","components","common",e);await jn(o,{recursive:!0}),await zr(Ne.join(o,`${e}.tsx`),Br({componentName:e,isClient:i,hasI18n:n})),await zr(Ne.join(o,"index.ts"),Dn({componentName:e}));let s=Ne.join(r,"src","components","common","index.ts");await pp(s,`export { ${e} } from './${e}';
405
+ `);let c=Ne.join(r,"src","components","index.ts");await lp(c)},pp=async(e,t)=>{let r="";l(e)&&(r=await g(e)),r.includes(t.trim())||(r+=t,await h(e,r))},lp=async e=>{let t="";l(e)&&(t=await g(e));let r=`export * from './common';
406
+ `;t.includes(r.trim())||(t+=r,await h(e,t))};import{writeFile as mp}from"node:fs/promises";import dp from"node:path";var Ln=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';
407
+ ${n}
406
408
  import type { ResultAsync } from '@/types';
407
409
 
408
410
  /**
@@ -449,14 +451,14 @@ export const ${t}Service = {
449
451
  return ${o}.delete<void>(AppApis.${t}.delete(id));
450
452
  },
451
453
  };
452
- `},ai=e=>{let{camelName:t,kebabName:r}=e;return` ${t}: {
454
+ `},Mn=e=>{let{camelName:t,kebabName:r}=e;return` ${t}: {
453
455
  base: '/${r}',
454
456
  getAll: '/${r}',
455
457
  getById: (id: string) => \`/${r}/\${id}\`,
456
458
  create: '/${r}',
457
459
  update: (id: string) => \`/${r}/\${id}\`,
458
460
  delete: (id: string) => \`/${r}/\${id}\`,
459
- },`};var dr=async e=>{let{name:t,outputPath:r,httpClient:n}=e,i=j(t),o=I(t);await Sc(Ec.join(r,`${t}.service.ts`),si({camelName:i,pascalName:o,httpClient:n}))};import{mkdir as Rc,writeFile as St}from"node:fs/promises";import K from"node:path";import{writeFile as Cc}from"node:fs/promises";import Tc from"node:path";var ci=e=>{let{camelName:t,httpClient:r}=e;return`import { AppApis } from '@/lib/config';
461
+ },`};var Jr=async e=>{let{name:t,outputPath:r,httpClient:i}=e,n=G(t),o=N(t);await mp(dp.join(r,`${t}.service.ts`),Ln({camelName:n,pascalName:o,httpClient:i}))};import{mkdir as hp,writeFile as zt}from"node:fs/promises";import ie from"node:path";import{writeFile as up}from"node:fs/promises";import fp from"node:path";var Gn=e=>{let{camelName:t,httpClient:r}=e;return`import { AppApis } from '@/lib/config';
460
462
  ${r==="axios"?"import { axiosClient } from '@/lib/utils/http';":"import { fetchClient } from '@/lib/utils/http';"}
461
463
  import type { ResultAsync } from '@/types';
462
464
 
@@ -465,23 +467,23 @@ export const ${t}Service = {
465
467
  return ${r==="axios"?"axiosClient":"fetchClient"}.get<string>(AppApis.${t}.getAll);
466
468
  },
467
469
  };
468
- `};var Ke=async e=>{let{name:t,outputPath:r,httpClient:n}=e,i=j(t);await Cc(Tc.join(r,`${t}.service.ts`),ci({camelName:i,httpClient:n}))};import{mkdir as bc,writeFile as Ze}from"node:fs/promises";import Qe from"node:path";var pi=e=>{let{sliceName:t,withPersist:r}=e;return`export * from './${t}.slice';
470
+ `};var pt=async e=>{let{name:t,outputPath:r,httpClient:i}=e,n=G(t);await up(fp.join(r,`${t}.service.ts`),Gn({camelName:n,httpClient:i}))};import{mkdir as gp,writeFile as lt}from"node:fs/promises";import mt from"node:path";var Hn=e=>{let{sliceName:t,withPersist:r}=e;return`export * from './${t}.slice';
469
471
  export * from './${t}.selectors';
470
472
  export * from './${t}.types';${r?`
471
473
  export * from './persist';`:""}
472
- `},li=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?`
474
+ `},Un=e=>{let{featureName:t,componentName:r,hookName:i,withStore:n,withService:o}=e;return`export { default as ${r} } from './components/${r}';
475
+ export { ${i} } from './hooks/${i}';
476
+ export * from './types/${t}.types';${n?`
475
477
  export * from './store';`:""}${o?`
476
478
  export * from './services/${t}.service';`:""}
477
- `};var mi=e=>{let{componentName:t,camelName:r,typesImportPath:n}=e,i=`${r.toUpperCase()}_PERSIST_VERSION`;return`import { createMigrate, type PersistConfig, type PersistedState } from 'redux-persist';
479
+ `};var Bn=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
480
  import storage from '@/store/storage';
479
- import type { ${t}State } from '${n}';
481
+ import type { ${t}State } from '${i}';
480
482
 
481
- const ${i} = 1;
483
+ const ${n} = 1;
482
484
 
483
485
  const migrations = {
484
- // Bump ${i} and add a migration here when ${t}State's
486
+ // Bump ${n} and add a migration here when ${t}State's
485
487
  // shape changes. Receives the previously-persisted state, returns the new
486
488
  // shape. Returning \`undefined\` discards stale state.
487
489
  // 2: (state) => ({ ...state, newField: defaultValue }),
@@ -490,16 +492,16 @@ const migrations = {
490
492
  export const ${r}PersistConfig: PersistConfig<${t}State> = {
491
493
  key: '${r}',
492
494
  storage,
493
- version: ${i},
495
+ version: ${n},
494
496
  // whitelist: ['someField'], // Specify which fields to persist
495
497
  migrate: createMigrate(migrations, { debug: false }),
496
498
  };
497
- `};var di=e=>{let{componentName:t,camelName:r,sliceName:n}=e;return`import { RootState } from '@/store/rootReducer';
499
+ `};var zn=e=>{let{componentName:t,camelName:r,sliceName:i}=e;return`import { RootState } from '@/store/rootReducer';
498
500
 
499
501
  export const select${t}State = (state: RootState) => state.${r};
500
- export { setLoading, setError, resetState } from './${n}.slice';
501
- `};var ui=e=>{let{componentName:t,camelName:r,typesImportPath:n}=e;return`import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
502
- import type { ${t}State } from '${n}';
502
+ export { setLoading, setError, resetState } from './${i}.slice';
503
+ `};var Vn=e=>{let{componentName:t,camelName:r,typesImportPath:i}=e;return`import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
504
+ import type { ${t}State } from '${i}';
503
505
 
504
506
  const initialState: ${t}State = {
505
507
  loading: false,
@@ -527,13 +529,13 @@ export const ${r}Slice = createSlice({
527
529
  export const { setLoading, setError, resetState } = ${r}Slice.actions;
528
530
 
529
531
  export const ${r}Reducer = ${r}Slice.reducer;
530
- `};var vt=e=>{let{componentName:t,withStore:r}=e;return`export interface ${t}State {
532
+ `};var Bt=e=>{let{componentName:t,withStore:r}=e;return`export interface ${t}State {
531
533
  ${r?`loading: boolean;
532
534
  error: string | null;
533
535
  // Add your state properties here`:`// Add your state properties here
534
536
  // example: value: string;`}
535
537
  }
536
- `};var et=async e=>{let{name:t,outputPath:r,persist:n,typesImportPath:i=`./${t}.types`}=e;await bc(r,{recursive:!0});let o=I(t),s=j(t);await Promise.all([Ze(Qe.join(r,`${t}.types.ts`),vt({componentName:o,withStore:!0})),Ze(Qe.join(r,`${t}.slice.ts`),ui({componentName:o,camelName:s,typesImportPath:i})),Ze(Qe.join(r,`${t}.selectors.ts`),di({componentName:o,camelName:s,sliceName:t})),...n?[Ze(Qe.join(r,"persist.ts"),mi({componentName:o,camelName:s,typesImportPath:i}))]:[],Ze(Qe.join(r,"index.ts"),pi({sliceName:t,withPersist:n}))])};var fi=e=>{let{componentName:t,hookName:r}=e;return`'use client';
538
+ `};var dt=async e=>{let{name:t,outputPath:r,persist:i,typesImportPath:n=`./${t}.types`}=e;await gp(r,{recursive:!0});let o=N(t),s=G(t);await Promise.all([lt(mt.join(r,`${t}.types.ts`),Bt({componentName:o,withStore:!0})),lt(mt.join(r,`${t}.slice.ts`),Vn({componentName:o,camelName:s,typesImportPath:n})),lt(mt.join(r,`${t}.selectors.ts`),zn({componentName:o,camelName:s,sliceName:t})),...i?[lt(mt.join(r,"persist.ts"),Bn({componentName:o,camelName:s,typesImportPath:n}))]:[],lt(mt.join(r,"index.ts"),Hn({sliceName:t,withPersist:i}))])};var Jn=e=>{let{componentName:t,hookName:r}=e;return`'use client';
537
539
  import { ${r} } from '../hooks/${r}';
538
540
 
539
541
  export function ${t}() {
@@ -548,9 +550,9 @@ export function ${t}() {
548
550
  }
549
551
 
550
552
  export default ${t};
551
- `};var gi=e=>{let{hookName:t,componentName:r,featureName:n}=e;return`'use client';
553
+ `};var Wn=e=>{let{hookName:t,componentName:r,featureName:i}=e;return`'use client';
552
554
  import { useAppDispatch, useAppSelector } from '@/store/hooks';
553
- import { select${r}State, setLoading, setError } from '../store/${n}.selectors';
555
+ import { select${r}State, setLoading, setError } from '../store/${i}.selectors';
554
556
 
555
557
  export const ${t} = () => {
556
558
  const dispatch = useAppDispatch();
@@ -570,7 +572,7 @@ export const ${t} = () => {
570
572
  setError: handleSetError,
571
573
  } as const;
572
574
  };
573
- `},hi=e=>{let{hookName:t}=e;return`'use client';
575
+ `},qn=e=>{let{hookName:t}=e;return`'use client';
574
576
  import { useState } from 'react';
575
577
 
576
578
  export const ${t} = () => {
@@ -582,8 +584,8 @@ export const ${t} = () => {
582
584
  // Add your methods here
583
585
  } as const;
584
586
  };
585
- `};var ur=async e=>{let{name:t,outputPath:r,createStore:n,persistStore:i,createService:o,httpClient:s}=e,a=I(t),p=`use${a}`,f=[K.join(r,"components"),K.join(r,"hooks"),K.join(r,"types"),...n?[K.join(r,"store")]:[],...o?[K.join(r,"services")]:[]];await Promise.all(f.map(d=>Rc(d,{recursive:!0}))),await Promise.all([St(K.join(r,"components",`${a}.tsx`),fi({componentName:a,hookName:p})),St(K.join(r,"hooks",`${p}.ts`),n?gi({hookName:p,componentName:a,featureName:t}):hi({hookName:p})),St(K.join(r,"types",`${t}.types.ts`),vt({componentName:a,withStore:n})),St(K.join(r,"index.ts"),li({featureName:t,componentName:a,hookName:p,withStore:n,withService:o}))]),n&&await et({name:t,outputPath:K.join(r,"store"),persist:i,typesImportPath:`../types/${t}.types`}),o&&s&&await Ke({name:t,outputPath:K.join(r,"services"),httpClient:s})};import{mkdir as $c,writeFile as Ic}from"node:fs/promises";import fr from"node:path";var yi=e=>{let{hookName:t,isClient:r}=e,n=[];return r&&n.push("'use client';"),n.push("import { useState, useCallback } from 'react';"),n.push(""),n.push(`export const ${t} = () => {`),n.push(" const [loading, setLoading] = useState(false);"),n.push(" const [error, setError] = useState<string | null>(null);"),n.push(""),n.push(" const execute = useCallback(async () => {"),n.push(" setLoading(true);"),n.push(" setError(null);"),n.push(" try {"),n.push(" // Add your logic here"),n.push(" } catch (err) {"),n.push(" setError(err instanceof Error ? err.message : 'An error occurred');"),n.push(" } finally {"),n.push(" setLoading(false);"),n.push(" }"),n.push(" }, []);"),n.push(""),n.push(" return {"),n.push(" loading,"),n.push(" error,"),n.push(" execute,"),n.push(" } as const;"),n.push("};"),n.push(""),n.join(`
586
- `)};var gr=async e=>{let{name:t,projectPath:r,isClient:n,featurePath:i}=e,s=`use${I(t)}`,a;i?a=fr.join(r,i,"hooks"):a=fr.join(r,"src","hooks"),await $c(a,{recursive:!0}),await Ic(fr.join(a,`${s}.ts`),yi({hookName:s,isClient:n}))};import{mkdir as Ac}from"node:fs/promises";import Et from"node:path";P();var Nc=e=>`import { setRequestLocale } from 'next-intl/server';
587
+ `};var Wr=async e=>{let{name:t,outputPath:r,createStore:i,persistStore:n,createService:o,httpClient:s}=e,c=N(t),p=`use${c}`,u=[ie.join(r,"components"),ie.join(r,"hooks"),ie.join(r,"types"),...i?[ie.join(r,"store")]:[],...o?[ie.join(r,"services")]:[]];await Promise.all(u.map(d=>hp(d,{recursive:!0}))),await Promise.all([zt(ie.join(r,"components",`${c}.tsx`),Jn({componentName:c,hookName:p})),zt(ie.join(r,"hooks",`${p}.ts`),i?Wn({hookName:p,componentName:c,featureName:t}):qn({hookName:p})),zt(ie.join(r,"types",`${t}.types.ts`),Bt({componentName:c,withStore:i})),zt(ie.join(r,"index.ts"),Un({featureName:t,componentName:c,hookName:p,withStore:i,withService:o}))]),i&&await dt({name:t,outputPath:ie.join(r,"store"),persist:n,typesImportPath:`../types/${t}.types`}),o&&s&&await pt({name:t,outputPath:ie.join(r,"services"),httpClient:s})};import{mkdir as yp,writeFile as xp}from"node:fs/promises";import qr from"node:path";var Xn=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(`
588
+ `)};var Xr=async e=>{let{name:t,projectPath:r,isClient:i,featurePath:n}=e,s=`use${N(t)}`,c;n?c=qr.join(r,n,"hooks"):c=qr.join(r,"src","hooks"),await yp(c,{recursive:!0}),await xp(qr.join(c,`${s}.ts`),Xn({hookName:s,isClient:i}))};import{mkdir as vp}from"node:fs/promises";import Vt from"node:path";w();var wp=e=>`import { setRequestLocale } from 'next-intl/server';
587
589
  import type { SupportedLocale } from '@/types/i18n';
588
590
 
589
591
  type Props = {
@@ -597,21 +599,21 @@ export default async function ${e}({ children, params }: Props) {
597
599
 
598
600
  return <>{children}</>;
599
601
  }
600
- `,kc=e=>`type Props = {
602
+ `,Pp=e=>`type Props = {
601
603
  children: React.ReactNode;
602
604
  };
603
605
 
604
606
  export default function ${e}({ children }: Props) {
605
607
  return <>{children}</>;
606
608
  }
607
- `,xi=({componentName:e,hasI18n:t})=>t?Nc(e):kc(e);var _c=/^[a-z][a-z0-9-]*$/,Oc=/^[a-z][a-z0-9-]*(\/[a-z][a-z0-9-]*)*$/,Fc=e=>{if(!_c.test(e))throw new Error(`Invalid layout segment "${e}". Use kebab-case letters, digits, and hyphens. For route groups pass --group instead of wrapping in parens.`)},jc=e=>{if(!Oc.test(e))throw new Error(`Invalid --at path "${e}". Use kebab-case segments separated by "/", e.g. "dashboard/settings".`)},hr=async e=>{let{segment:t,at:r,projectPath:n,hasI18n:i,withGroup:o}=e;Fc(t),r&&jc(r);let s=`${I(t)}Layout`,a=o?`(${t})`:t,p=["src","app"];i&&p.push("[locale]"),r&&p.push(...r.split("/")),p.push(a);let f=Et.join(n,...p),d=Et.join(f,"layout.tsx");if(m(d))throw new Error(`Layout already exists at ${Et.relative(n,d)}.`);return await Ac(f,{recursive:!0}),await g(d,xi({componentName:s,hasI18n:i})),{layoutFile:d,displayPath:Et.relative(n,d),componentName:s}};P();import{copyFile as Dc,readFile as Lc,writeFile as Mc}from"node:fs/promises";import tt from"node:path";var yr=async e=>{let{code:t,name:r,country:n,flag:i,projectPath:o,copyTranslations:s}=e;await Gc(o,t,s),await Uc(o,t),await Hc(o,t,r,n,i)},Gc=async(e,t,r)=>{let n=tt.join(e,"src","i18n","translations"),i=tt.join(n,"en.json"),o=tt.join(n,`${t}.json`);if(r)await Dc(i,o);else{let s=await Lc(i,"utf-8"),a=JSON.parse(s),p=Pi(a);await Mc(o,`${JSON.stringify(p,null,2)}
608
- `)}},Pi=e=>{let t={};for(let[r,n]of Object.entries(e))typeof n=="object"&&n!==null?t[r]=Pi(n):t[r]="";return t},Uc=async(e,t)=>{let r=tt.join(e,"src","types","i18n.ts");if(!m(r))return;let n=await u(r),i=/export type SupportedLocale = (.*);/,o=n.match(i);if(o&&!o[1].includes(`'${t}'`)){let s=`${o[1]} | '${t}'`;n=n.replace(i,`export type SupportedLocale = ${s};`),await g(r,n)}},Hc=async(e,t,r,n,i)=>{let o=tt.join(e,"src","lib","config","app-locales.ts");if(!m(o))return;let s=await u(o);if(s.includes(`locale: '${t}'`))return;let a=s.lastIndexOf("];");if(a===-1)return;let p=` {
609
+ `,Yn=({componentName:e,hasI18n:t})=>t?wp(e):Pp(e);var Sp=/^[a-z][a-z0-9-]*$/,Ep=/^[a-z][a-z0-9-]*(\/[a-z][a-z0-9-]*)*$/,Tp=e=>{if(!Sp.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.`)},Cp=e=>{if(!Ep.test(e))throw new Error(`Invalid --at path "${e}". Use kebab-case segments separated by "/", e.g. "dashboard/settings".`)},Yr=async e=>{let{segment:t,at:r,projectPath:i,hasI18n:n,withGroup:o}=e;Tp(t),r&&Cp(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=Vt.join(i,...p),d=Vt.join(u,"layout.tsx");if(l(d))throw new Error(`Layout already exists at ${Vt.relative(i,d)}.`);return await vp(u,{recursive:!0}),await h(d,Yn({componentName:s,hasI18n:n})),{layoutFile:d,displayPath:Vt.relative(i,d),componentName:s}};w();import{copyFile as Rp,readFile as bp,writeFile as Ip}from"node:fs/promises";import ut from"node:path";var Kr=async e=>{let{code:t,name:r,country:i,flag:n,projectPath:o,copyTranslations:s}=e;await $p(o,t,s),await kp(o,t),await Np(o,t,r,i,n)},$p=async(e,t,r)=>{let i=ut.join(e,"src","i18n","translations"),n=ut.join(i,"en.json"),o=ut.join(i,`${t}.json`);if(r)await Rp(n,o);else{let s=await bp(n,"utf-8"),c=JSON.parse(s),p=Kn(c);await Ip(o,`${JSON.stringify(p,null,2)}
610
+ `)}},Kn=e=>{let t={};for(let[r,i]of Object.entries(e))typeof i=="object"&&i!==null?t[r]=Kn(i):t[r]="";return t},kp=async(e,t)=>{let r=ut.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)}},Np=async(e,t,r,i,n)=>{let o=ut.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
611
  name: '${r}',
610
612
  locale: '${t}',
611
- flag: '${i}',
612
- country: '${n}',
613
+ flag: '${n}',
614
+ country: '${i}',
613
615
  },
614
- `;s=s.slice(0,a)+p+s.slice(a),await g(o,s)};import{mkdir as Bc,writeFile as xr}from"node:fs/promises";import rt from"node:path";var wi=e=>{let{componentName:t,routePath:r,hasI18n:n}=e;return n?`import { generateSEOMetadata } from '@/lib/config/seo';
616
+ `;s=s.slice(0,c)+p+s.slice(c),await h(o,s)};import{mkdir as Ap,writeFile as Zr}from"node:fs/promises";import ft from"node:path";var Zn=e=>{let{componentName:t,routePath:r,hasI18n:i}=e;return i?`import { generateSEOMetadata } from '@/lib/config/seo';
615
617
  import type { Metadata } from 'next';
616
618
  import { getTranslations, setRequestLocale } from 'next-intl/server';
617
619
  import type { SupportedLocale } from '@/types/i18n';
@@ -657,7 +659,7 @@ export default function ${t}Page() {
657
659
  </div>
658
660
  );
659
661
  }
660
- `},vi=e=>{let{componentName:t,paramName:r,routePath:n,hasI18n:i}=e;return i?`import { generateSEOMetadata } from '@/lib/config/seo';
662
+ `},Qn=e=>{let{componentName:t,paramName:r,routePath:i,hasI18n:n}=e;return n?`import { generateSEOMetadata } from '@/lib/config/seo';
661
663
  import type { Metadata } from 'next';
662
664
  import { getTranslations, setRequestLocale } from 'next-intl/server';
663
665
  import type { SupportedLocale } from '@/types/i18n';
@@ -673,7 +675,7 @@ export async function generateMetadata(props: Props): Promise<Metadata> {
673
675
  return generateSEOMetadata({
674
676
  title: t('title'),
675
677
  description: t('description'),
676
- path: '${n}',
678
+ path: '${i}',
677
679
  });
678
680
  }
679
681
 
@@ -711,14 +713,14 @@ export default async function ${t}Page(props: Props) {
711
713
  </div>
712
714
  );
713
715
  }
714
- `},Si=e=>`export default function ${e.componentName}Loading() {
716
+ `},eo=e=>`export default function ${e.componentName}Loading() {
715
717
  return (
716
718
  <div className="flex h-full items-center justify-center">
717
719
  <p>Loading...</p>
718
720
  </div>
719
721
  );
720
722
  }
721
- `,Ei=e=>`'use client';
723
+ `,to=e=>`'use client';
722
724
 
723
725
  export default function ${e.componentName}Error({
724
726
  error,
@@ -735,17 +737,17 @@ export default function ${e.componentName}Error({
735
737
  </div>
736
738
  );
737
739
  }
738
- `;var Pr=async e=>{let{name:t,projectPath:r,hasI18n:n,dynamic:i,withLoading:o=!1,withError:s=!1}=e,a=I(t),p=`/${t}`,f=n?"src/app/[locale]":"src/app",d;i?d=rt.join(r,f,t,`[${i}]`):d=rt.join(r,f,t),await Bc(d,{recursive:!0});let h=i?vi({componentName:a,routePath:i?`${p}/[${i}]`:p,paramName:i,hasI18n:n}):wi({componentName:a,routePath:p,hasI18n:n});await xr(rt.join(d,"page.tsx"),h),o&&await xr(rt.join(d,"loading.tsx"),Si({componentName:a})),s&&await xr(rt.join(d,"error.tsx"),Ei({componentName:a}))};S();import{mkdir as zc}from"node:fs/promises";import wr from"node:path";P();var Ci=(e,t)=>e.endsWith(t)?e:`${e}${t}`,Ti=({baseName:e})=>{let t=Ci(e,"Provider"),r=t.replace(/Provider$/,""),n=`${r}ContextValue`,i=`${r}Context`,o=`use${r}`;return`'use client';
740
+ `;var Qr=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=ft.join(r,u,t,`[${n}]`):d=ft.join(r,u,t),await Ap(d,{recursive:!0});let f=n?Qn({componentName:c,routePath:n?`${p}/[${n}]`:p,paramName:n,hasI18n:i}):Zn({componentName:c,routePath:p,hasI18n:i});await Zr(ft.join(d,"page.tsx"),f),o&&await Zr(ft.join(d,"loading.tsx"),eo({componentName:c})),s&&await Zr(ft.join(d,"error.tsx"),to({componentName:c}))};P();import{mkdir as _p}from"node:fs/promises";import ei from"node:path";w();var ro=(e,t)=>e.endsWith(t)?e:`${e}${t}`,io=({baseName:e})=>{let t=ro(e,"Provider"),r=t.replace(/Provider$/,""),i=`${r}ContextValue`,n=`${r}Context`,o=`use${r}`;return`'use client';
739
741
  import { createContext, useContext, useMemo } from 'react';
740
742
 
741
- type ${n} = {
743
+ type ${i} = {
742
744
  // TODO: declare context value fields
743
745
  };
744
746
 
745
- const ${i} = createContext<${n} | null>(null);
747
+ const ${n} = createContext<${i} | null>(null);
746
748
 
747
- export const ${o} = (): ${n} => {
748
- const ctx = useContext(${i});
749
+ export const ${o} = (): ${i} => {
750
+ const ctx = useContext(${n});
749
751
  if (!ctx) {
750
752
  throw new Error('${o} must be used within ${t}');
751
753
  }
@@ -753,26 +755,26 @@ export const ${o} = (): ${n} => {
753
755
  };
754
756
 
755
757
  export const ${t} = ({ children }: { children: React.ReactNode }) => {
756
- const value = useMemo<${n}>(() => ({}), []);
757
- return <${i}.Provider value={value}>{children}</${i}.Provider>;
758
+ const value = useMemo<${i}>(() => ({}), []);
759
+ return <${n}.Provider value={value}>{children}</${n}.Provider>;
758
760
  };
759
- `},bi=e=>Ci(e,"Provider");var Vc=/^[A-Za-z][A-Za-z0-9-]*$/,Jc=e=>e.includes("-")?I(e):e.charAt(0).toUpperCase()+e.slice(1),vr=async e=>{let{name:t,projectPath:r}=e;if(!Vc.test(t))throw new Error(`Invalid provider name "${t}". Use kebab-case or PascalCase letters and digits only.`);let n=Jc(t).replace(/Provider$/,""),i=bi(n),o=i,s=wr.join(r,c.PROVIDERS),a=wr.join(s,`${o}.tsx`);if(m(a))throw new Error(`Provider already exists at ${wr.relative(r,a)}.`);return await zc(s,{recursive:!0}),await g(a,Ti({baseName:n})),{componentName:i,fileBaseName:o,providerFile:a}};P();import nt from"node:path";var Ri=e=>{let{componentName:t,sourceImportPath:r,testUtilsImportPath:n,hasRedux:i,hasI18n:o}=e,s=[];o&&s.push("messages: {}"),i&&s.push("preloadedState: {}");let a=s.length?`, {
761
+ `},no=e=>ro(e,"Provider");var Fp=/^[A-Za-z][A-Za-z0-9-]*$/,Op=e=>e.includes("-")?N(e):e.charAt(0).toUpperCase()+e.slice(1),ti=async e=>{let{name:t,projectPath:r}=e;if(!Fp.test(t))throw new Error(`Invalid provider name "${t}". Use kebab-case or PascalCase letters and digits only.`);let i=Op(t).replace(/Provider$/,""),n=no(i),o=n,s=ei.join(r,a.PROVIDERS),c=ei.join(s,`${o}.tsx`);if(l(c))throw new Error(`Provider already exists at ${ei.relative(r,c)}.`);return await _p(s,{recursive:!0}),await h(c,io({baseName:i})),{componentName:n,fileBaseName:o,providerFile:c}};w();import gt from"node:path";var oo=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
762
  ${s.join(`,
761
763
  `)},
762
764
  }`:"";return`import { describe, expect, it } from 'vitest';
763
- import { renderWithProviders, screen } from '${n}';
765
+ import { renderWithProviders, screen } from '${i}';
764
766
  import { ${t} } from '${r}';
765
767
 
766
768
  describe('${t}', () => {
767
769
  it('renders without crashing', () => {
768
- renderWithProviders(<${t} />${a});
770
+ renderWithProviders(<${t} />${c});
769
771
  // TODO: assert something meaningful about the rendered output.
770
772
  expect(screen).toBeDefined();
771
773
  });
772
774
  });
773
- `},$i=e=>{let{hookName:t,sourceImportPath:r,withStore:n,testUtilsImportPath:i}=e;return n?`import { renderHook } from '@testing-library/react';
775
+ `},so=e=>{let{hookName:t,sourceImportPath:r,withStore:i,testUtilsImportPath:n}=e;return i?`import { renderHook } from '@testing-library/react';
774
776
  import { describe, expect, it } from 'vitest';
775
- import { TestProviders } from '${i}';
777
+ import { TestProviders } from '${n}';
776
778
  import { ${t} } from '${r}';
777
779
 
778
780
  describe('${t}', () => {
@@ -791,121 +793,121 @@ describe('${t}', () => {
791
793
  expect(result.current).toBeDefined();
792
794
  });
793
795
  });
794
- `},Ii=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}';
796
+ `},ao=e=>{let{camelName:t,sourceImportPath:r}=e,i=`${t}Slice`;return`import { describe, expect, it } from 'vitest';
797
+ import { ${i}, resetState, setError, setLoading } from '${r}';
796
798
 
797
- describe('${n}', () => {
799
+ describe('${i}', () => {
798
800
  const initialState = { loading: false, error: null } as const;
799
801
 
800
802
  it('returns the initial state', () => {
801
- expect(${n}.reducer(undefined, { type: '@@INIT' })).toEqual(initialState);
803
+ expect(${i}.reducer(undefined, { type: '@@INIT' })).toEqual(initialState);
802
804
  });
803
805
 
804
806
  it('handles setLoading', () => {
805
- const next = ${n}.reducer(initialState, setLoading(true));
807
+ const next = ${i}.reducer(initialState, setLoading(true));
806
808
  expect(next.loading).toBe(true);
807
809
  });
808
810
 
809
811
  it('handles setError', () => {
810
- const next = ${n}.reducer(initialState, setError('boom'));
812
+ const next = ${i}.reducer(initialState, setError('boom'));
811
813
  expect(next.error).toBe('boom');
812
814
  });
813
815
 
814
816
  it('handles resetState', () => {
815
- const next = ${n}.reducer({ loading: true, error: 'boom' }, resetState());
817
+ const next = ${i}.reducer({ loading: true, error: 'boom' }, resetState());
816
818
  expect(next).toEqual(initialState);
817
819
  });
818
820
  });
819
- `};var ae=async e=>{let{projectPath:t,sourceFile:r,kind:n,symbolName:i}=e,o=nt.dirname(r),s=nt.basename(r).replace(/\.(tsx?|jsx?)$/i,""),a=n==="component"?".tsx":".ts",p=nt.join(o,`${s}.test${a}`),f=`./${s}`,d=Wc(o,nt.join(t,"test","test-utils")),h;return n==="component"?h=Ri({componentName:i,sourceImportPath:f,testUtilsImportPath:d,hasRedux:!!e.hasRedux,hasI18n:!!e.hasI18n}):n==="hook"?h=$i({hookName:i,sourceImportPath:f,withStore:!!e.hookUsesStore,testUtilsImportPath:e.hookUsesStore?d:void 0}):h=Ii({camelName:i,sourceImportPath:f}),await g(p,h),p},Wc=(e,t)=>{let r=nt.relative(e,t).replace(/\\/g,"/");return r.startsWith(".")?r:`./${r}`};import qc from"enquirer";var{prompt:Xc}=qc,Ni=async(e,t={})=>{let r=[];e||r.push({type:"input",name:"componentName",message:"Component name (kebab-case):",validate:i=>i?/^[a-z][a-z0-9-]*$/.test(i)?!0:"Use lowercase letters, numbers, and hyphens only":"Component name is required"}),t.client===void 0&&r.push({type:"confirm",name:"isClient",message:"Add 'use client' directive?",initial:!1});let n=r.length>0?await Xc(r):{};return{componentName:e??n.componentName,isClient:t.client??n.isClient??!1}};var ki=e=>{e.command("component [name]").description("Generate a shared component").option("--client","Add 'use client' directive").option("--i18n","Add useTranslations hook").option("--feature <path>","Generate in feature directory (e.g., src/features/auth)").option("--test","Also generate a sibling test file").option("--no-test","Skip test file generation").action(async(t,r)=>{try{let n=process.cwd();l(ne.cyan(`
821
+ `};var ge=async e=>{let{projectPath:t,sourceFile:r,kind:i,symbolName:n}=e,o=gt.dirname(r),s=gt.basename(r).replace(/\.(tsx?|jsx?)$/i,""),c=i==="component"?".tsx":".ts",p=gt.join(o,`${s}.test${c}`),u=`./${s}`,d=Dp(o,gt.join(t,"test","test-utils")),f;return i==="component"?f=oo({componentName:n,sourceImportPath:u,testUtilsImportPath:d,hasRedux:!!e.hasRedux,hasI18n:!!e.hasI18n}):i==="hook"?f=so({hookName:n,sourceImportPath:u,withStore:!!e.hookUsesStore,testUtilsImportPath:e.hookUsesStore?d:void 0}):f=ao({camelName:n,sourceImportPath:u}),await h(p,f),p},Dp=(e,t)=>{let r=gt.relative(e,t).replace(/\\/g,"/");return r.startsWith(".")?r:`./${r}`};import jp from"enquirer";var{prompt:Lp}=jp,co=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 Lp(r):{};return{componentName:e??i.componentName,isClient:t.client??i.isClient??!1}};var po=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(le.cyan(`
820
822
  \u{1F9E9} Component Generator
821
- `)),y.start("Detecting project setup...");let i=await F(n);y.succeed("Project setup detected");let o=await Ni(t,{client:r.client});H(o.componentName,"component name"),r.feature&&re(r.feature,"feature path");let s=I(o.componentName),a=o.isClient,p=r.i18n??!1,f=Yc(r,i.hasTests);y.start("Generating component..."),await mr({name:o.componentName,projectPath:n,isClient:a||p,hasI18n:p,featurePath:r.feature}),y.succeed("Component generated");let d=null;if(f){let x=r.feature?Sr.join(n,r.feature,"components",`${s}.tsx`):Sr.join(n,"src/components/common",s,`${s}.tsx`);y.start("Generating test..."),d=await ae({projectPath:n,sourceFile:x,kind:"component",symbolName:s,hasRedux:i.hasRedux,hasI18n:i.hasI18n}),y.succeed("Test generated")}let h=r.feature?`${r.feature}/components/${s}.tsx`:`src/components/common/${s}/${s}.tsx`;l(ne.green(`
823
+ `)),y.start("Detecting project setup...");let n=await M(i);y.succeed("Project setup detected");let o=await co(t,{client:r.client});W(o.componentName,"component name"),r.feature&&pe(r.feature,"feature path");let s=N(o.componentName),c=o.isClient,p=r.i18n??!1,u=Mp(r,n.hasTests);y.start("Generating component..."),await Vr({name:o.componentName,projectPath:i,isClient:c||p,hasI18n:p,featurePath:r.feature}),y.succeed("Component generated");let d=null;if(u){let x=r.feature?ri.join(i,r.feature,"components",`${s}.tsx`):ri.join(i,"src/components/common",s,`${s}.tsx`);y.start("Generating test..."),d=await ge({projectPath:i,sourceFile:x,kind:"component",symbolName:s,hasRedux:n.hasRedux,hasI18n:n.hasI18n}),y.succeed("Test generated")}let f=r.feature?`${r.feature}/components/${s}.tsx`:`src/components/common/${s}/${s}.tsx`;m(le.green(`
822
824
  \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} ${Sr.relative(n,d)}`)),l(""),l(ne.cyan("Usage:")),r.feature?l(ne.dim(` import { ${s} } from '${r.feature.replace(/^src\//,"@/")}/components/${s}';`)):l(ne.dim(` import { ${s} } from '@/components';`)),l("")}catch(n){y.fail("Component generation failed"),v(`${n}`),process.exit(1)}})},Yc=(e,t)=>e.test===!1?!1:e.test===!0?!0:t;import M from"picocolors";S();P();import Zc from"node:path";S();import Ai from"node:path";import Kc from"picocolors";P();var Ct=async e=>{let t=b("Adding @next/bundle-analyzer...");try{let r=Ai.join(e,c.NEXT_CONFIG);if(!m(r))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await u(r);if(n.includes("@next/bundle-analyzer")){t.fail("@next/bundle-analyzer is already configured.");return}n=`import withBundleAnalyzer from '@next/bundle-analyzer';
824
- ${n}`;let i=/export default (.*?);/,o=n.match(i);if(!o)throw new Error("Could not locate `export default` in next.config.ts.");let a=`const bundleAnalyzer = withBundleAnalyzer({
825
+ `)),m(le.dim(` \u{1F4C4} ${f}`)),r.feature||(m(le.dim(` \u{1F4C4} src/components/common/${s}/index.ts`)),m(le.dim(" \u{1F4DD} Updated src/components/common/index.ts")),m(le.dim(" \u{1F4DD} Updated src/components/index.ts"))),d&&m(le.dim(` \u{1F9EA} ${ri.relative(i,d)}`)),m(""),m(le.cyan("Usage:")),r.feature?m(le.dim(` import { ${s} } from '${r.feature.replace(/^src\//,"@/")}/components/${s}';`)):m(le.dim(` import { ${s} } from '@/components';`)),m("")}catch(i){y.fail("Component generation failed"),E(`${i}`),process.exit(1)}})},Mp=(e,t)=>e.test===!1?!1:e.test===!0?!0:t;import $ from"picocolors";P();w();import Vp from"node:path";P();import mo from"node:path";import Gp from"picocolors";w();var lo=/export default (.*?);/,ii="ANALYZE=true next build",Jt=e=>e.includes("@next/bundle-analyzer"),ht=e=>{if(Jt(e))return e;let t=`import withBundleAnalyzer from '@next/bundle-analyzer';
826
+ ${e}`,r=t.match(lo);if(!r)throw new Error("Could not locate `export default` in next.config.ts.");let n=`const bundleAnalyzer = withBundleAnalyzer({
825
827
  enabled: process.env.ANALYZE === 'true',
826
828
  });
827
829
 
828
- export default bundleAnalyzer(${o[1]});`;n=n.replace(i,a),await g(r,n),await D(Ai.join(e,c.PACKAGE_JSON),p=>(p.scripts=p.scripts??{},p.scripts.analyze||(p.scripts.analyze="ANALYZE=true next build"),p)),t.text="Installing @next/bundle-analyzer...",await ut(e,"@next/bundle-analyzer"),t.succeed(Kc.green("@next/bundle-analyzer configured."))}catch(r){throw t.fail("Failed to add @next/bundle-analyzer."),r}};var Er=(e,t)=>{let r=e.split(`
829
- `),n=[],i=new RegExp(`^import\\s+${t}\\s+from\\s+['"][^'"]+['"];?\\s*$`),o=/^(import\s+)\{([^}]+)\}(\s+from\s+['"][^'"]+['"];?\s*)$/;for(let s of r){if(i.test(s))continue;let a=s.match(o);if(a){let p=a[2].split(",").map(d=>d.trim()).filter(Boolean),f=p.filter(d=>d.replace(/^type\s+/,"").split(/\s+as\s+/)[0].trim()!==t);if(f.length===0)continue;if(f.length<p.length){n.push(`${a[1]}{ ${f.join(", ")} }${a[3]}`);continue}}n.push(s)}return n.join(`
830
- `)},_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 f=r.slice(i+1,p).map(h=>h.startsWith(" ")?h.slice(2):h),d=[...r.slice(0,i),...f,...r.slice(p+1)].join(`
832
- `);return Er(d,e)};var _i=e=>{let t=e.split(`
833
- `).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},Oi=e=>{let t=Er(e,"withBundleAnalyzer"),r=/^const\s+bundleAnalyzer\s*=\s*withBundleAnalyzer\(\{[\s\S]*?\}\);\s*\n?/m;if(!r.test(t))return null;t=t.replace(r,"");let n=/bundleAnalyzer\(\s*((?:[^()]|\([^()]*\))+?)\s*\)/;return n.test(t)?(t=t.replace(n,"$1"),t):null};var Fi={id:"bundle-analyzer",name:"Bundle Analyzer",description:"@next/bundle-analyzer wrapped around the default export",detect:async e=>{let t=Zc.join(e,c.NEXT_CONFIG);return m(t)?/@next\/bundle-analyzer/.test(await u(t)):!1},files:[],packages:[{name:"@next/bundle-analyzer",kind:"devDependency"}],scripts:[{name:"analyze",expectedValue:"ANALYZE=true next build"}],injections:[{file:c.NEXT_CONFIG,description:"withBundleAnalyzer import + wrapping",presence:/@next\/bundle-analyzer/,removePattern:Oi}],apply:Ct};S();P();import tp from"node:path";S();import ji from"node:path";import Qc from"picocolors";P();var Cr=e=>{let t={...e.scripts??{}},r={...e.devDependencies??{}};return t.commit||(t.commit="cz"),r[T.COMMITIZEN]||(r[T.COMMITIZEN]="*"),r[T.CZ_CONVENTIONAL_CHANGELOG]||(r[T.CZ_CONVENTIONAL_CHANGELOG]="*"),{...e,scripts:t,devDependencies:r}},Tr=e=>{let t=e.devDependencies??{},r=[];return t[T.COMMITIZEN]||r.push(T.COMMITIZEN),t[T.CZ_CONVENTIONAL_CHANGELOG]||r.push(T.CZ_CONVENTIONAL_CHANGELOG),r};var ep=`${JSON.stringify({path:"cz-conventional-changelog"},null,2)}
835
- `,Tt=async e=>{let t=b("Setting up Commitizen...");try{let r=ji.join(e,c.CZRC);m(r)||await g(r,ep);let n=ji.join(e,c.PACKAGE_JSON),i=JSON.parse(await u(n)),o=Tr(i);if(await D(n,s=>Cr(s)),o.length>0){t.text=`Installing ${o.join(", ")}...`;let s=await k(e);await Pe(e,s,o)}t.succeed(Qc.green("Commitizen configured. Use `commit` to start a guided commit."))}catch(r){throw t.fail("Failed to set up Commitizen."),r}};var Di={id:"commitizen",name:"Commitizen",description:"Guided conventional-commit prompt via `commit` script",detect:async e=>m(tp.join(e,c.CZRC)),files:[{path:c.CZRC,generated:!0}],packages:[{name:"commitizen",kind:"devDependency"},{name:"cz-conventional-changelog",kind:"devDependency"}],scripts:[{name:"commit",expectedValue:"cz"}],injections:[],apply:Tt};S();P();import op from"node:path";import np from"node:path";import ip from"picocolors";P();S();P();import Li from"node:path";import rp from"degit";var Mi=async(e,t)=>{t.text="Fetching assets from starter repo...",await rp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Gi=async(e,t)=>{let r=Li.join(e,c.THEME_PROVIDER),n=Li.join(t,"src/providers/CustomThemeProvider.tsx");await N(n,r)};S();P();import it from"node:path";S();P();import Ui from"node:path";var bt=async e=>{let t=[Ui.join(e,c.ROOT_LAYOUT),Ui.join(e,"src/app/[locale]/layout.tsx")];for(let r of t)if(m(r)&&(await u(r)).includes("<body"))return r;for(let r of t)if(m(r))return r;return""};var Hi=async e=>{let t=it.join(e,c.THEME_PROVIDER),r=it.join(e,c.GLOBALS_CSS),n=it.join(e,"package.json");if(m(t))return{isSetup:!0,reason:"CustomThemeProvider.tsx exists"};if(m(n)){let i=JSON.parse(await u(n)),o="@teispace/next-themes";if(i.dependencies?.[o]||i.devDependencies?.[o])return{isSetup:!0,reason:`${o} is installed`}}return m(r)&&(await u(r)).includes("@custom-variant dark")?{isSetup:!0,reason:"Dark theme CSS found in globals.css"}:{isSetup:!1,reason:""}},Bi=async e=>{let t=it.join(e,c.GLOBALS_CSS),r=it.join(e,c.PROVIDERS_INDEX),n=await bt(e);if(!m(t)||!n||!m(r))throw new Error("Project structure mismatch. Ensure src/styles/globals.css, src/app/layout.tsx (or src/app/[locale]/layout.tsx), and src/providers/index.ts exist.");return n};S();P();import Rt from"node:path";var zi=async e=>{let t=Rt.join(e,c.PROVIDERS_INDEX),r=await u(t);r.includes("CustomThemeProvider")||(r+=`export * from './CustomThemeProvider';
836
- `,await g(t,r))},Vi=async e=>{let t=Rt.join(e,"src/providers/RootProvider.tsx");if(!m(t))return;let r=await u(t),n="'use client';",i=r.includes(n);if(i&&(r=r.replace(n,"").trim()),r.includes("CustomThemeProvider")||(/import\s*\{[^}]*\}\s*from\s*'@\/providers'/.test(r)?r=r.replace(/(import\s*\{)([^}]*)(\}\s*from\s*'@\/providers')/,(o,s,a,p)=>`${s}${a.trim()?`${a.trim()}, CustomThemeProvider `:" CustomThemeProvider "}${p}`):r=`import { CustomThemeProvider } from '@/providers';
837
- ${r}`),i&&(r=`${n}
830
+ export default bundleAnalyzer(${r[1]});`;return t.replace(lo,n)};var Wt=async e=>{let t=S("Adding @next/bundle-analyzer...");try{let r=mo.join(e,a.NEXT_CONFIG);if(!l(r))throw new Error(`${a.NEXT_CONFIG} not found.`);let i=await g(r);if(Jt(i)){t.fail("@next/bundle-analyzer is already configured.");return}await h(r,ht(i)),await _(mo.join(e,a.PACKAGE_JSON),n=>(n.scripts=n.scripts??{},n.scripts.analyze||(n.scripts.analyze=ii),n)),t.text="Installing @next/bundle-analyzer...",await At(e,"@next/bundle-analyzer"),t.succeed(Gp.green("@next/bundle-analyzer configured."))}catch(r){throw t.fail("Failed to add @next/bundle-analyzer."),r}};P();import Bp from"node:path";import zp from"picocolors";w();P();import Hp from"node:path";w();var qt=(e,t)=>e.filter(r=>r.kind==="missingPackage"&&r.depKind===t).map(r=>r.name),Up=e=>e.filter(t=>t.kind==="missingFile").map(t=>t.file),F=(e,t)=>Up(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=qt(t,"dependency"),i=qt(t,"devDependency");if(r.length===0&&i.length===0)return[];let n=await A(e);return r.length>0&&await Ir(e,n,r),i.length>0&&await fe(e,n,i),[...r,...i]},Ee=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=Hp.join(e,a.PACKAGE_JSON);return l(i)?(await _(i,n=>{let o={...n.scripts??{}};for(let[s,c]of r)o[s]=c;return{...n,scripts:o}}),[...r.keys()]):[]},te=async(e,t)=>{await J(e);try{return await t(e)}finally{await v(e)}};var uo=async(e,t)=>{let r=S("Repairing Bundle Analyzer...");try{if(U(t,a.NEXT_CONFIG)){let s=Bp.join(e,a.NEXT_CONFIG);if(l(s)){let c=await g(s),p=ht(c);p!==c&&await h(s,p)}}let i=await B(e,t),n=await Ee(e,t),o=[i.length>0?`reinstalled ${i.join(", ")}`:null,n.length>0?`restored ${n.join(", ")}`:null].filter(Boolean);r.succeed(zp.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 ni=(e,t)=>{let r=e.split(`
831
+ `),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(`
832
+ `)},Ve=e=>t=>{let r=t.split(`
833
+ `),i=new RegExp(`^([ \\t]*)<${e}\\b`),n=-1,o="";for(let f=0;f<r.length;f++){let x=r[f].match(i);if(x){n=f,o=x[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(`
834
+ `);return ni(d,e)};var fo=e=>{let t=e.split(`
835
+ `).filter(i=>!/^import\s+createNextIntlPlugin\s+from\s+['"]next-intl\/plugin['"];?\s*$/.test(i)).join(`
836
+ `);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},go=e=>{let t=ni(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 ho={id:"bundle-analyzer",name:"Bundle Analyzer",description:"@next/bundle-analyzer wrapped around the default export",detect:async e=>{let t=Vp.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:go}],apply:O(Wt,uo)};P();w();import Xp from"node:path";P();import yo from"node:path";import Jp from"picocolors";w();var yt=`${JSON.stringify({path:"cz-conventional-changelog"},null,2)}
837
+ `;var oi=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}},si=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 Xt=async e=>{let t=S("Setting up Commitizen...");try{let r=yo.join(e,a.CZRC);l(r)||await h(r,yt);let i=yo.join(e,a.PACKAGE_JSON),n=JSON.parse(await g(i)),o=si(n);if(await _(i,s=>oi(s)),o.length>0){t.text=`Installing ${o.join(", ")}...`;let s=await A(e);await fe(e,s,o)}t.succeed(Jp.green("Commitizen configured. Use `commit` to start a guided commit."))}catch(r){throw t.fail("Failed to set up Commitizen."),r}};P();import Wp from"node:path";import qp from"picocolors";w();var xo=async(e,t)=>{let r=S("Repairing Commitizen...");try{let i=!1;if(F(t,a.CZRC)){let c=Wp.join(e,a.CZRC);l(c)||(await h(c,yt),i=!0)}let n=await B(e,t),o=await Ee(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(qp.green(s.length>0?`Commitizen repaired (${s.join("; ")}).`:"Commitizen repaired."))}catch(i){throw r.fail("Failed to repair Commitizen."),i}};var wo={id:"commitizen",name:"Commitizen",description:"Guided conventional-commit prompt via `commit` script",detect:async e=>l(Xp.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(Xt,xo)};P();w();import el from"node:path";import Yp from"node:path";import Kp from"picocolors";w();P();import Po from"node:path";w();var vo=async(e,t)=>{t.text="Fetching assets from starter repo...",await J(e)},So=async(e,t)=>{let r=Po.join(e,a.THEME_PROVIDER),i=Po.join(t,"src/providers/CustomThemeProvider.tsx");await b(i,r)};P();w();import xt from"node:path";P();w();import Eo from"node:path";var Yt=async e=>{let t=[Eo.join(e,a.ROOT_LAYOUT),Eo.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 To=async e=>{let t=xt.join(e,a.THEME_PROVIDER),r=xt.join(e,a.GLOBALS_CSS),i=xt.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:""}},Co=async e=>{let t=xt.join(e,a.GLOBALS_CSS),r=xt.join(e,a.PROVIDERS_INDEX),i=await Yt(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 Kt from"node:path";var Zt=async e=>{let t=Kt.join(e,a.PROVIDERS_INDEX),r=await g(t);r.includes("CustomThemeProvider")||(r+=`export * from './CustomThemeProvider';
838
+ `,await h(t,r))},Qt=async e=>{let t=Kt.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';
839
+ ${r}`),n&&(r=`${i}
838
840
  ${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
841
  <CustomThemeProvider>
840
842
  ${o[1]}
841
843
  </CustomThemeProvider>
842
- );`))}await g(t,r)},Ji=async(e,t)=>{let r=Rt.join(e,c.GLOBALS_CSS),n=Rt.join(t,"src/styles/globals.css"),i="";if(m(n)){let s=await u(n),a=s.match(/@custom-variant dark \(.*?\);/),p=s.match(/@theme \{[\s\S]*?\}/);a&&(i+=`
843
- ${a[0]}
844
- `),p&&(i+=`
844
+ );`))}await h(t,r)},Ro=async(e,t)=>{let r=Kt.join(e,a.GLOBALS_CSS),i=Kt.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+=`
845
+ ${c[0]}
846
+ `),p&&(n+=`
845
847
  ${p[0]}
846
- `)}i||(i=`
848
+ `)}n||(n=`
847
849
  @custom-variant dark (&:where(.dark, .dark *));
848
850
 
849
851
  @theme {
850
852
  --color-dark: #202938;
851
853
  --color-light: #f5f5f5;
852
854
  }
853
- `);let o=await u(r);if(!o.includes("@custom-variant dark")){if(o.includes("@import")){let s=o.lastIndexOf("@import"),a=o.indexOf(`
854
- `,s);o=o.slice(0,a+1)+i+o.slice(a+1)}else o=i+o;await g(r,o)}},Wi=async e=>{let t=await u(e);t.includes("dark:bg-dark")||(t=t.replace(/className="([^"]*)"/,'className="$1 bg-light dark:bg-dark"'),await g(e,t))};var $t=async e=>{let t=b("Setting up Dark Theme..."),r=np.join(e,".next-maker-temp");try{let{isSetup:n,reason:i}=await Hi(e);if(n){t.fail(`Dark Theme is already set up (${i}).`);return}let o=await Bi(e);await Mi(r,t),await Gi(e,r),await zi(e),await Vi(e),await Ji(e,r),await Wi(o),t.text="Installing @teispace/next-themes...",await U(e,"@teispace/next-themes"),t.text="Formatting code...";let s=await k(e);await J(e,s,"lint:fix"),t.succeed(ip.green("Dark Theme setup successfully!"))}catch(n){throw t.fail("Failed to setup Dark Theme."),n}finally{await w(r)}};var qi={id:"dark-theme",name:"Dark Theme",description:"@teispace/next-themes + CustomThemeProvider",detect:async e=>m(op.join(e,c.THEME_PROVIDER)),files:[{path:c.THEME_PROVIDER,generated:!0}],packages:[{name:"@teispace/next-themes",kind:"dependency"}],scripts:[],injections:[{file:"src/providers/RootProvider.tsx",description:"<CustomThemeProvider> wrap",presence:/CustomThemeProvider/,removePattern:_e("CustomThemeProvider")}],apply:$t};import ap from"node:fs/promises";import It from"node:path";import Nt from"enquirer";import br from"picocolors";P();S();P();import Y from"node:fs/promises";import E from"node:path";import sp from"degit";var Xi=async(e,t)=>{t.text="Downloading assets from starter repository...",await sp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Yi=async(e,t,r,n)=>{let i=E.join(e,c.HTTP_UTILS),o=E.join(t,c.HTTP_UTILS);await Y.cp(E.join(t,c.ERRORS_DIR),E.join(e,c.ERRORS_DIR),{recursive:!0});let s=E.join(e,c.APP_APIS);m(s)||await N(E.join(t,c.APP_APIS),s);let a=E.join(e,c.API_URL_FILE);m(a)||await N(E.join(t,c.API_URL_FILE),a);let p=E.join(e,c.CONSTANTS);if(!m(p))await N(E.join(t,c.CONSTANTS),p);else{let d=await u(p),h=!1;d.includes("API_RESPONSE_DATA_KEY")||(d+=`
855
+ `);let o=await g(r);if(!o.includes("@custom-variant dark")){if(o.includes("@import")){let s=o.lastIndexOf("@import"),c=o.indexOf(`
856
+ `,s);o=o.slice(0,c+1)+n+o.slice(c+1)}else o=n+o;await h(r,o)}},bo=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 er=async e=>{let t=S("Setting up Dark Theme..."),r=Yp.join(e,".next-maker-temp");try{let{isSetup:i,reason:n}=await To(e);if(i){t.fail(`Dark Theme is already set up (${n}).`);return}let o=await Co(e);await vo(r,t),await So(e,r),await Zt(e),await Qt(e),await Ro(e,r),await bo(o),t.text="Installing @teispace/next-themes...",await z(e,"@teispace/next-themes"),t.text="Formatting code...";let s=await A(e);await K(e,s,"lint:fix"),t.succeed(Kp.green("Dark Theme setup successfully!"))}catch(i){throw t.fail("Failed to setup Dark Theme."),i}finally{await v(r)}};P();import tr from"node:path";import Zp from"picocolors";w();var Qp="src/providers/RootProvider.tsx",Io=async(e,t)=>{let r=S("Repairing Dark Theme..."),i=tr.join(e,".next-maker-temp-dark-theme-repair");try{let n=tr.join(e,a.THEME_PROVIDER),o=[];F(t,a.THEME_PROVIDER)&&!l(n)&&(r.text="Fetching CustomThemeProvider from starter repo...",await te(i,async p=>{await b(tr.join(p,a.THEME_PROVIDER),n)}),o.push(a.THEME_PROVIDER)),U(t,Qp)&&(r.text="Restoring <CustomThemeProvider> wrap...",l(tr.join(e,a.PROVIDERS_INDEX))&&await Zt(e),await Qt(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(Zp.green(c.length>0?`Dark Theme repaired (${c.join("; ")}).`:"Dark Theme repaired."))}catch(n){throw r.fail("Failed to repair Dark Theme."),n}};var $o={id:"dark-theme",name:"Dark Theme",description:"@teispace/next-themes + CustomThemeProvider",detect:async e=>l(el.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:Ve("CustomThemeProvider")}],apply:O(er,Io)};import tl from"node:fs/promises";import ir from"node:path";import nr from"enquirer";import ai from"picocolors";w();P();import re from"node:fs/promises";import T from"node:path";w();var ko=async(e,t)=>{t.text="Downloading assets from starter repository...",await J(e)},No=async(e,t,r,i)=>{let n=T.join(e,a.HTTP_UTILS),o=T.join(t,a.HTTP_UTILS);await re.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
857
  export const API_RESPONSE_DATA_KEY = 'data';
856
- `,h=!0),d.includes("SAVE_AUTH_TOKENS")||(d+=`
858
+ `,f=!0),d.includes("SAVE_AUTH_TOKENS")||(d+=`
857
859
  export const SAVE_AUTH_TOKENS = false;
858
- `,h=!0),h&&await g(p,d)}let f=E.join(e,c.STORAGE_SERVICE);if(m(f)||await Y.cp(E.join(t,c.STORAGE_SERVICE),f,{recursive:!0}),await Y.cp(E.join(t,c.COMMON_TYPES_DIR),E.join(e,c.COMMON_TYPES_DIR),{recursive:!0}),await Y.cp(E.join(t,c.UTILITY_TYPES_DIR),E.join(e,c.UTILITY_TYPES_DIR),{recursive:!0}),await N(E.join(o,"token-store.ts"),E.join(i,"token-store.ts")),await N(E.join(o,"client-utils.ts"),E.join(i,"client-utils.ts")),await Y.cp(E.join(t,c.HTTP_SHARED),E.join(e,c.HTTP_SHARED),{recursive:!0,force:!0}),await N(E.join(o,"server.ts"),E.join(i,"server.ts")),await Y.cp(E.join(t,c.HTTP_BUNDLE_SENTINEL_DIR),E.join(e,c.HTTP_BUNDLE_SENTINEL_DIR),{recursive:!0,force:!0}),n&&n.length>0)for(let d of n){let h=E.join(e,d==="fetch"?c.FETCH_CLIENT:c.AXIOS_CLIENT);await w(h)}for(let d of r)d==="fetch"?await Y.cp(E.join(t,c.FETCH_CLIENT),E.join(e,c.FETCH_CLIENT),{recursive:!0}):await Y.cp(E.join(t,c.AXIOS_CLIENT),E.join(e,c.AXIOS_CLIENT),{recursive:!0});await N(E.join(o,"index.ts"),E.join(i,"index.ts")),await N(E.join(t,c.HTTP_TYPES),E.join(e,c.HTTP_TYPES))},Ki=async e=>{let{isFileUsed:t,isStringUsed:r,stripSaveAuthTokens:n}=await Promise.resolve().then(()=>(ze(),Tn));await w(E.join(e,c.HTTP_UTILS));let i=E.join(e,c.STORAGE_SERVICE);m(i)&&(await r(e,"SecureStorageService",[i])||await w(i));let o=E.join(e,c.API_URL_FILE);m(o)&&(await r(e,"getApiBaseUrl",[o])||await Y.unlink(o));let s=E.join(e,c.CONSTANTS);if(m(s)){let d=await u(s),h=!1;if(await r(e,"API_RESPONSE_DATA_KEY",[s])||(d=d.replace(/export const API_RESPONSE_DATA_KEY = .*;\n?/g,""),h=!0),!await r(e,"SAVE_AUTH_TOKENS",[s])){let L=n(d);L!==d&&(d=L,h=!0)}h&&(d=`${d.replace(/\n\s*\n/g,`
860
+ `,f=!0),f&&await h(p,d)}let u=T.join(e,a.STORAGE_SERVICE);if(l(u)||await re.cp(T.join(t,a.STORAGE_SERVICE),u,{recursive:!0}),await re.cp(T.join(t,a.COMMON_TYPES_DIR),T.join(e,a.COMMON_TYPES_DIR),{recursive:!0}),await re.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 re.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 re.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 re.cp(T.join(t,a.FETCH_CLIENT),T.join(e,a.FETCH_CLIENT),{recursive:!0}):await re.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))},Ao=async e=>{let{isFileUsed:t,isStringUsed:r,stripSaveAuthTokens:i}=await Promise.resolve().then(()=>(Be(),rn));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 re.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 H=i(d);H!==d&&(d=H,f=!0)}f&&(d=`${d.replace(/\n\s*\n/g,`
859
861
 
860
862
  `).trim()}
861
- `,await g(s,d))}let a=E.join(e,c.ERRORS_DIR);if(m(a)){let d=await Y.readdir(a),h=!1;for(let x of d){let R=E.parse(x).name;if(await t(e,R,[E.join(a,x)])){h=!0;break}}h||await w(a)}let p=E.join(e,c.COMMON_TYPES_DIR);m(p)&&(await Y.readdir(p)).length===0&&await w(p);let f=E.join(e,c.UTILITY_TYPES_DIR);m(f)&&(await Y.readdir(f)).length===0&&await w(f)};S();P();import ot from"node:path";var Zi=async e=>{let t=ot.join(e,c.FETCH_CLIENT_FILE),r=ot.join(e,c.AXIOS_CLIENT_FILE),n=m(t),i=m(r);return n&&i?{status:"both",reason:"Both Fetch and Axios clients are detected"}:n?{status:"fetch",reason:"Fetch client is already setup"}:i?{status:"axios",reason:"Axios client is already setup"}:{status:"none"}},Qi=async e=>{let r=[ot.join(e,"src/lib"),ot.join(e,"src/types"),ot.join(e,"src/lib/config")].filter(n=>!m(n));if(r.length>0)throw new Error(`Invalid project structure. Missing directories:
862
- ${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 Zi(e);t.stop();let o=await cp(n,i);if(o.type==="cancel"){console.log(br.yellow("Setup cancelled."));return}if(t.start("Setting up HTTP client(s)..."),await Qi(e),await Xi(r,t),o.type==="replace"&&o.fromClient&&(t.text="Migrating client usages...",await tr(e,o.fromClient,o.clients[0])),o.type!=="remove-both"&&o.type!=="remove-one"){t.text="Copying client files...";let R=o.type==="replace"&&o.fromClient?[o.fromClient]:void 0;await Yi(e,r,o.clients,R)}if(o.type==="remove-one"||o.type==="remove-both"){t.text="Removing client files...";let{PROJECT_PATHS:R}=await Promise.resolve().then(()=>(S(),yn));for(let $ of o.clients){let W=It.join(e,$==="fetch"?R.FETCH_CLIENT:R.AXIOS_CLIENT);await w(W)}eo(n,o).length===0&&(t.text="Performing full cleanup...",await Ki(e),await ir(e))}let s=eo(n,o);s.length>0?(t.text="Configuring client...",await Yt(e,s),await Kt(e),await Zt(e),await Qt(e),await nr(e),await ke(e,s),await Ae(e,s)):await Be(e),await Ne(e,s),t.text="Managing dependencies...";let a=It.join(e,"package.json"),p=JSON.parse(await ap.readFile(a,"utf-8")),f={...p.dependencies,...p.devDependencies};s.includes("axios")?f.axios||(t.text="Installing Axios...",await U(e,"axios")):f.axios&&(t.text="Uninstalling Axios...",await Ie(e,"axios")),s.length>0?f["server-only"]||(t.text="Installing server-only...",await U(e,"server-only")):f["server-only"]&&(t.text="Uninstalling server-only...",await Ie(e,"server-only"));let d=It.join(e,"src/services/storage");s.length>0||m(d)?f["react-secure-storage"]||(t.text="Installing react-secure-storage...",await U(e,"react-secure-storage")):f["react-secure-storage"]&&(t.text="Uninstalling react-secure-storage...",await Ie(e,"react-secure-storage")),t.text="Formatting code...";let x=await k(e);await J(e,x,"lint:fix"),t.succeed(br.green(pp(o)))}catch(n){throw t.fail("Failed to setup HTTP Client."),n}finally{await w(r)}};async function cp(e,t){if(e==="none"){let{choice:n}=await Nt.prompt({type:"select",name:"choice",message:"Which HTTP client(s) do you want to setup?",choices:[{name:"fetch",message:"Fetch (Native)"},{name:"axios",message:"Axios"},{name:"both",message:"Both (Fetch + Axios)"}]});return n==="both"?{type:"install",clients:["fetch","axios"]}:{type:"install",clients:[n]}}if(e==="fetch"){let{action:n}=await Nt.prompt({type:"select",name:"action",message:`${t}. What would you like to do?`,choices:[{name:"cancel",message:"Keep Fetch only (cancel)"},{name:"add",message:"Add Axios (have both)"},{name:"replace",message:"Replace with Axios only"},{name:"remove",message:"Remove Fetch"}]});if(n==="cancel")return{type:"cancel",clients:[]};if(n==="add")return{type:"add",clients:["axios"]};if(n==="replace")return{type:"replace",clients:["axios"],fromClient:"fetch"};if(n==="remove")return{type:"remove-one",clients:["fetch"]}}if(e==="axios"){let{action:n}=await Nt.prompt({type:"select",name:"action",message:`${t}. What would you like to do?`,choices:[{name:"cancel",message:"Keep Axios only (cancel)"},{name:"add",message:"Add Fetch (have both)"},{name:"replace",message:"Replace with Fetch only"},{name:"remove",message:"Remove Axios"}]});if(n==="cancel")return{type:"cancel",clients:[]};if(n==="add")return{type:"add",clients:["fetch"]};if(n==="replace")return{type:"replace",clients:["fetch"],fromClient:"axios"};if(n==="remove")return{type:"remove-one",clients:["axios"]}}console.log(br.yellow(`\u2716 ${t}`));let{action:r}=await Nt.prompt({type:"select",name:"action",message:"What would you like to do?",choices:[{name:"cancel",message:"Keep both (cancel)"},{name:"remove-fetch",message:"Remove Fetch (keep Axios)"},{name:"remove-axios",message:"Remove Axios (keep Fetch)"},{name:"remove-both",message:"Remove both"}]});return r==="cancel"?{type:"cancel",clients:[]}:r==="remove-fetch"?{type:"remove-one",clients:["fetch"]}:r==="remove-axios"?{type:"remove-one",clients:["axios"]}:r==="remove-both"?{type:"remove-both",clients:["fetch","axios"]}:{type:"cancel",clients:[]}}function eo(e,t){return t.type==="install"?t.clients:t.type==="add"?[...e==="fetch"?["fetch"]:["axios"],...t.clients]:t.type==="replace"?t.clients:t.type==="remove-one"?e==="both"?t.clients[0]==="fetch"?["axios"]:["fetch"]:[]:[]}function pp(e){if(e.type==="install")return`HTTP Client (${e.clients.map(r=>r==="fetch"?"Fetch":"Axios").join(" + ")}) setup successfully!`;if(e.type==="add")return`${e.clients[0]==="fetch"?"Fetch":"Axios"} client added successfully! Both clients are now available.`;if(e.type==="replace"){let t=e.fromClient==="fetch"?"Fetch":"Axios",r=e.clients[0]==="fetch"?"Fetch":"Axios";return`Replaced ${t} with ${r} successfully! Imports automatically migrated.`}return e.type==="remove-one"?`${e.clients[0]==="fetch"?"Fetch":"Axios"} client removed successfully!`:e.type==="remove-both"?"Both HTTP clients removed successfully!":"HTTP Client setup completed!"}ze();var to=/<HttpClientBundleSentinel\s*\/>/,ro={id:"http-client",name:"HTTP Client",description:"Axios and/or Fetch client utilities",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(B(),Ye));return(await t(e)).httpClient!=="none"},files:[{path:"src/lib/utils/http",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds the http client + any service modules you wired through it \u2014 review before deleting"},{path:"src/lib/utils/http/shared",generated:!0,isDir:!0},{path:"src/lib/utils/http/server.ts",generated:!0},{path:"src/lib/utils/http/__bundle-sentinel__",generated:!0,isDir:!0},{path:"src/lib/config/api-url.ts",generated:!0}],packages:[],scripts:[],injections:[{file:"src/app/[locale]/layout.tsx",description:"<HttpClientBundleSentinel /> mount in locale layout",presence:to,removePattern:He},{file:"src/app/layout.tsx",description:"<HttpClientBundleSentinel /> mount in root layout",presence:to,removePattern:He}],apply:kt};S();import Rr from"node:path";import up from"picocolors";P();S();P();import lp from"node:fs/promises";import fe from"node:path";import mp from"degit";var no=async(e,t)=>{t.text="Fetching assets from starter repo...",await mp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},io=async(e,t)=>{let r=fe.join(t,"src/i18n"),n=fe.join(e,c.I18N_DIR);await lp.cp(r,n,{recursive:!0});let i=fe.join(t,"src/proxy.ts"),o=fe.join(e,c.PROXY);await N(i,o);let s=fe.join(t,"src/types/i18n.ts"),a=fe.join(e,c.I18N_TYPES);await N(s,a);let p=fe.join(t,"src/lib/config/app-locales.ts"),f=fe.join(e,c.APP_LOCALES);await N(p,f)};S();P();import At from"node:path";var oo=async e=>{let t=At.join(e,c.I18N_DIR),r=At.join(e,"package.json");if(m(t))return{isSetup:!0,reason:"src/i18n directory exists"};if(m(r)){let n=JSON.parse(await u(r));if(n.dependencies?.["next-intl"]||n.devDependencies?.["next-intl"])return{isSetup:!0,reason:"next-intl is installed"}}return{isSetup:!1,reason:""}},so=async e=>{let t=At.join(e,c.ROOT_LAYOUT),r=At.join(e,"src/app/[locale]/layout.tsx");if(!m(t)&&!m(r))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx exists.")};S();P();import dp from"node:fs/promises";import ce from"node:path";var ao=async e=>{let t=ce.join(e,c.NEXT_CONFIG);if(m(t)){let r=await u(t);if(!r.includes("createNextIntlPlugin")){r=`import createNextIntlPlugin from 'next-intl/plugin';
864
- ${r}`;let n=/export default (.*?);/;n.test(r)?r=r.replace(n,`
863
+ `,await h(s,d))}let c=T.join(e,a.ERRORS_DIR);if(l(c)){let d=await re.readdir(c),f=!1;for(let x of d){let I=T.parse(x).name;if(await t(e,I,[T.join(c,x)])){f=!0;break}}f||await v(c)}let p=T.join(e,a.COMMON_TYPES_DIR);l(p)&&(await re.readdir(p)).length===0&&await v(p);let u=T.join(e,a.UTILITY_TYPES_DIR);l(u)&&(await re.readdir(u)).length===0&&await v(u)};P();w();import wt from"node:path";var rr=async e=>{let t=wt.join(e,a.FETCH_CLIENT_FILE),r=wt.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=[wt.join(e,"src/lib"),wt.join(e,"src/types"),wt.join(e,"src/lib/config")].filter(i=>!l(i));if(r.length>0)throw new Error(`Invalid project structure. Missing directories:
864
+ ${r.map(i=>`- ${i}`).join(`
865
+ `)}`)};Be();var or=async e=>{let t=S("Checking HTTP Client setup..."),r=ir.join(e,".next-maker-temp-http");try{let{status:i,reason:n}=await rr(e);t.stop();let o=await rl(i,n);if(o.type==="cancel"){console.log(ai.yellow("Setup cancelled."));return}if(t.start("Setting up HTTP client(s)..."),await _o(e),await ko(r,t),o.type==="replace"&&o.fromClient&&(t.text="Migrating client usages...",await Dr(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 No(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(),qi));for(let k of o.clients){let Z=ir.join(e,k==="fetch"?I.FETCH_CLIENT:I.AXIOS_CLIENT);await v(Z)}Fo(i,o).length===0&&(t.text="Performing full cleanup...",await Ao(e),await Lr(e))}let s=Fo(i,o);s.length>0?(t.text="Configuring client...",await Nr(e,s),await Ar(e),await _r(e),await Fr(e),await tt(e),await we(e,s),await Pe(e,s)):await rt(e),await Ue(e,s),t.text="Managing dependencies...";let c=ir.join(e,"package.json"),p=JSON.parse(await tl.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=ir.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 x=await A(e);await K(e,x,"lint:fix"),t.succeed(ai.green(il(o)))}catch(i){throw t.fail("Failed to setup HTTP Client."),i}finally{await v(r)}};async function rl(e,t){if(e==="none"){let{choice:i}=await nr.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 nr.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 nr.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(ai.yellow(`\u2716 ${t}`));let{action:r}=await nr.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 Fo(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 il(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!"}Be();P();import nl from"node:fs/promises";import Ae from"node:path";import ol from"picocolors";w();Be();var Oo=async(e,t)=>{let r=S("Repairing HTTP Client..."),i=Ae.join(e,".next-maker-temp-http-repair");try{let{status:n}=await rr(e),o=n==="both"?["fetch","axios"]:n==="none"?[]:[n],s=[a.HTTP_SHARED,a.HTTP_BUNDLE_SENTINEL_DIR].filter(f=>F(t,f)&&!l(Ae.join(e,f))),c=[a.HTTP_SERVER_FILE,a.API_URL_FILE].filter(f=>F(t,f)&&!l(Ae.join(e,f))),p=[];(s.length>0||c.length>0)&&(r.text="Fetching assets from starter repo...",await te(i,async f=>{for(let x of s)await nl.cp(Ae.join(f,x),Ae.join(e,x),{recursive:!0,force:!0}),p.push(x);for(let x of c)await b(Ae.join(f,x),Ae.join(e,x)),p.push(x)}),o.length>0&&(await we(e,o),await Pe(e,o))),U(t)&&(r.text="Re-mounting the bundle sentinel...",await tt(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(ol.green(d.length>0?`HTTP Client repaired (${d.join("; ")}).`:"HTTP Client repaired."))}catch(n){throw r.fail("Failed to repair HTTP Client."),n}};var sl=/<HttpClientBundleSentinel\s*\/>/,Do={id:"http-client",name:"HTTP Client",description:"Axios and/or Fetch client utilities",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(q(),ct));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:sl,removePattern:_t}],apply:O(or,Oo)};P();import ci from"node:path";import pl from"picocolors";w();P();import al from"node:fs/promises";import Te from"node:path";w();var jo=async(e,t)=>{t.text="Fetching assets from starter repo...",await J(e)},Lo=async(e,t)=>{let r=Te.join(t,"src/i18n"),i=Te.join(e,a.I18N_DIR);await al.cp(r,i,{recursive:!0});let n=Te.join(t,"src/proxy.ts"),o=Te.join(e,a.PROXY);await b(n,o);let s=Te.join(t,"src/types/i18n.ts"),c=Te.join(e,a.I18N_TYPES);await b(s,c);let p=Te.join(t,"src/lib/config/app-locales.ts"),u=Te.join(e,a.APP_LOCALES);await b(p,u)};P();w();import sr from"node:path";var Mo=async e=>{let t=sr.join(e,a.I18N_DIR),r=sr.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:""}},Go=async e=>{let t=sr.join(e,a.ROOT_LAYOUT),r=sr.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 cl from"node:fs/promises";import he from"node:path";var ar=async e=>{let t=he.join(e,a.NEXT_CONFIG);if(l(t)){let r=await g(t);if(!r.includes("createNextIntlPlugin")){r=`import createNextIntlPlugin from 'next-intl/plugin';
866
+ ${r}`;let i=/export default (.*?);/;i.test(r)?r=r.replace(i,`
865
867
  const withNextIntl = createNextIntlPlugin();
866
868
  export default withNextIntl($1);`):(r+=`
867
869
  const withNextIntl = createNextIntlPlugin();
868
870
  `,r+=`export default withNextIntl(nextConfig);
869
- `),await g(t,r)}}},co=async e=>{let t=ce.join(e,c.TYPES_INDEX);if(m(t)){let r=await u(t);r.includes("./i18n")||(r+=`export * from './i18n';
870
- `,await g(t,r))}},po=async e=>{let t=ce.join(e,c.CONFIG_INDEX);if(m(t)){let r=await u(t);r.includes("./app-locales")||(r+=`export * from './app-locales';
871
- `,await g(t,r))}},lo=async e=>{let t=ce.join(e,"src/providers/RootProvider.tsx");if(m(t)){let r=await u(t),n="'use client';",i=r.includes(n);if(i&&(r=r.replace(n,"").trim()),r.includes("next-intl")||(r=`import { type AbstractIntlMessages, NextIntlClientProvider } from 'next-intl';
871
+ `),await h(t,r)}}},cr=async e=>{let t=he.join(e,a.TYPES_INDEX);if(l(t)){let r=await g(t);r.includes("./i18n")||(r+=`export * from './i18n';
872
+ `,await h(t,r))}},pr=async e=>{let t=he.join(e,a.CONFIG_INDEX);if(l(t)){let r=await g(t);r.includes("./app-locales")||(r+=`export * from './app-locales';
873
+ `,await h(t,r))}},lr=async e=>{let t=he.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
874
  import type { SupportedLocale } from '@/types/i18n';
873
- `+r),i&&(r=`${n}
875
+ `+r),n&&(r=`${i}
874
876
  ${r}`),!r.includes("locale: SupportedLocale")){let o=` locale: SupportedLocale;
875
877
  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,f,d,h)=>{let x=d.replace(/\s+$/,"");return`${f}${x}
878
+ 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 x=d.replace(/\s+$/,"");return`${u}${x}
877
879
  ${o}
878
- ${h}`}),r=r.replace(/export const RootProvider = \(\{([\s\S]*?)\}:\s*RootProviderProps\)/,(p,f)=>{let d=f.trim().replace(/,$/,"");return`export const RootProvider = ({ ${d?`${d}, `:""}locale, messages, timeZone }: RootProviderProps)`});else{let p=r.match(a);if(p){let f=p[1].trim().replace(/,$/,""),d=p[2].trim().replace(/;$/,""),h=`
879
- ${f?`${f},
880
+ ${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=`
881
+ ${u?`${u},
880
882
  `:""}locale,
881
883
  messages,
882
884
  timeZone,`,x=`
883
885
  ${d?`${d};
884
886
  `:""}locale: SupportedLocale;
885
887
  messages: AbstractIntlMessages;
886
- timeZone: string;`;r=r.replace(p[0],`export const RootProvider = ({${h}
888
+ timeZone: string;`;r=r.replace(p[0],`export const RootProvider = ({${f}
887
889
  }: {${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}>
890
+ }) => {`)}}}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
891
  {children}
890
- </NextIntlClientProvider>`;if(s.includes("{children}")){let p=s.replace("{children}",a);r=r.replace(o[0],`return (
892
+ </NextIntlClientProvider>`;if(s.includes("{children}")){let p=s.replace("{children}",c);r=r.replace(o[0],`return (
891
893
  ${p}
892
894
  );`)}else r=r.replace(o[0],`return (
893
895
  <NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>
894
896
  ${s}
895
897
  </NextIntlClientProvider>
896
- );`)}}await g(t,r)}},mo=async e=>{let t=ce.join(e,c.ROOT_LAYOUT),r=ce.join(e,c.ROOT_PAGE),n=ce.join(e,"src/app/[locale]");if(await dp.mkdir(n,{recursive:!0}),m(t)){let i=ce.join(n,"layout.tsx"),o=await u(t);if(o.includes("next-intl")||(o=`import { routing } from '@/i18n/routing';
898
+ );`)}}await h(t,r)}},Ho=async e=>{let t=he.join(e,a.ROOT_LAYOUT),r=he.join(e,a.ROOT_PAGE),i=he.join(e,"src/app/[locale]");if(await cl.mkdir(i,{recursive:!0}),l(t)){let n=he.join(i,"layout.tsx"),o=await g(t);if(o.includes("next-intl")||(o=`import { routing } from '@/i18n/routing';
897
899
  import { hasLocale } from 'next-intl';
898
900
  import { notFound } from 'next/navigation';
899
901
  import { getMessages, getTimeZone, setRequestLocale } from 'next-intl/server';
900
902
  import { getLocaleDirection } from '@/lib/config/app-locales';
901
- ${o}`),!o.includes("generateStaticParams")){let p=o.indexOf("};",o.indexOf("export const metadata"));if(p!==-1){let f=p+2;o=o.slice(0,f)+`
903
+ ${o}`),!o.includes("generateStaticParams")){let p=o.indexOf("};",o.indexOf("export const metadata"));if(p!==-1){let u=p+2;o=o.slice(0,u)+`
902
904
 
903
905
  export function generateStaticParams() {
904
906
  return routing.locales.map((locale) => ({ locale }));
905
- }`+o.slice(f)}}o=o.replace(/Readonly<\{\s*children:\s*React\.ReactNode;\s*}>/,`Readonly<{
907
+ }`+o.slice(u)}}o=o.replace(/Readonly<\{\s*children:\s*React\.ReactNode;\s*}>/,`Readonly<{
906
908
  children: React.ReactNode;
907
909
  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 f=/export default async function RootLayout[\s\S]*?\)\s*\{/,d=o.match(f);if(d&&d.index!==void 0){let h=d.index+d[0].length-1;o=o.slice(0,h+1)+`
910
+ }>`);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
911
  const { locale } = await params;
910
912
 
911
913
  if (!hasLocale(routing.locales, locale)) {
@@ -915,42 +917,42 @@ export function generateStaticParams() {
915
917
  setRequestLocale(locale);
916
918
 
917
919
  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 u(r);o.includes("next-intl")||(o=`import { SupportedLocale } from '@/types/i18n';
920
+ `+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=he.join(i,"page.tsx"),o=await g(r);o.includes("next-intl")||(o=`import { SupportedLocale } from '@/types/i18n';
919
921
  import { setRequestLocale } from 'next-intl/server';
920
922
  ${o}`),o=o.replace(/export default function Home\(\)/,`type Props = {
921
923
  params: Promise<{ locale: string }>;
922
924
  };
923
925
 
924
- export default async function Home(props: Props)`);let s=o.indexOf("export default async function Home(props: Props) {");if(s!==-1){let a=`
926
+ export default async function Home(props: Props)`);let s=o.indexOf("export default async function Home(props: Props) {");if(s!==-1){let c=`
925
927
  const locale = (await props.params).locale as SupportedLocale;
926
928
  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=Rr.join(e,".next-maker-temp-i18n");try{let{isSetup:n,reason:i}=await oo(e);if(n){t.fail(`i18n is already set up (${i}).`);return}await so(e),await no(r,t),t.text="Copying i18n files...",await io(e,r),t.text="Configuring project structure...",await ao(e),await co(e),await po(e),await lo(e),t.text="Migrating to [locale] structure...",await mo(e),t.text="Installing dependencies...",await U(e,"next-intl");let o=Rr.join(e,c.VITEST_CONFIG);if(m(o)){let a=JSON.parse(await u(Rr.join(e,c.PACKAGE_JSON))),p={...a.dependencies,...a.devDependencies},f=!!(p["@reduxjs/toolkit"]&&p["react-redux"]);await me(e,{redux:f,i18n:!0})}t.text="Formatting code...";let s=await k(e);await J(e,s,"lint:fix"),t.succeed(up.green("Internationalization setup successfully!"))}catch(n){throw t.fail("Failed to setup Internationalization."),n}finally{await w(r)}};var uo={id:"i18n",name:"Internationalization",description:"next-intl with [locale] routing, RootProvider, and proxy.ts",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(B(),Ye));return(await t(e)).hasI18n},files:[{path:"src/i18n",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds your translation JSON files \u2014 copy any you want to keep, then delete by hand"},{path:"src/proxy.ts",generated:!0},{path:"src/app/[locale]",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds every page you generated under the locale segment \u2014 move them to src/app/ before deleting"}],packages:[{name:"next-intl",kind:"dependency"}],scripts:[],injections:[{file:"next.config.ts",description:"createNextIntlPlugin wrap in next.config.ts",presence:/next-intl\/plugin/,removePattern:_i},{file:"src/providers/RootProvider.tsx",description:"<NextIntlClientProvider> wrap",presence:/NextIntlClientProvider/,removePattern:_e("NextIntlClientProvider")}],apply:_t};S();P();import hp from"node:path";S();import fp from"node:path";import gp from"picocolors";P();var Ot=async e=>{let t=b("Enabling React Compiler...");try{let r=fp.join(e,c.NEXT_CONFIG);if(!m(r))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await u(r);if(n.includes("reactCompiler:")){t.fail("React Compiler is already configured in next.config.ts.");return}let i=/(const\s+nextConfig\s*:\s*NextConfig\s*=\s*\{)/;if(!i.test(n))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");n=n.replace(i,`$1
928
- reactCompiler: true,`),await g(r,n),t.text="Installing babel-plugin-react-compiler...",await ut(e,"babel-plugin-react-compiler"),t.succeed(gp.green("React Compiler enabled."))}catch(r){throw t.fail("Failed to enable React Compiler."),r}};var fo={id:"react-compiler",name:"React Compiler",description:"reactCompiler: true in next.config.ts + babel-plugin-react-compiler",detect:async e=>{let t=hp.join(e,c.NEXT_CONFIG);return m(t)?/reactCompiler\s*:\s*true/.test(await u(t)):!1},files:[],packages:[{name:"babel-plugin-react-compiler",kind:"devDependency"}],scripts:[],injections:[{file:c.NEXT_CONFIG,description:"`reactCompiler: true` flag",presence:/reactCompiler\s*:\s*true/,removePattern:/\n\s*reactCompiler:\s*true,?/}],apply:Ot};S();import Nr from"node:path";import xp from"picocolors";P();S();P();import go from"node:fs/promises";import Ee from"node:path";import yp from"degit";var ho=async(e,t)=>{t.text="Fetching assets from starter repo...",await yp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},yo=async(e,t)=>{let r=Ee.join(t,"src/providers/StoreProvider.tsx"),n=Ee.join(e,c.STORE_PROVIDER);await N(r,n);let i=Ee.join(t,"src/store"),o=Ee.join(e,c.STORE);await go.cp(i,o,{recursive:!0})},xo=async(e,t)=>{let r=Ee.join(t,"src/features/counter"),n=Ee.join(e,c.COUNTER_FEATURE);await go.cp(r,n,{recursive:!0});let i=Ee.join(n,"components/Counter.tsx");if(await m(i)){let o=await u(i);o=o.replace(/import \{ useTranslations \} from 'next-intl';\n?/,""),o=o.replace(/const t = useTranslations\('Count'\);\n?/,""),o=o.replace(/\{t\('currentCount', \{ count: value \}\)\}/g,"Current Count: {value}"),o=o.replace(/\{t\('increment'\)\}/g,"Increment"),o=o.replace(/\{t\('decrement'\)\}/g,"Decrement"),o=o.replace(/\{t\('reset'\)\}/g,"Reset"),await g(i,o)}};S();P();import $r from"node:path";var Po=async e=>{let t=$r.join(e,c.STORE),r=$r.join(e,"package.json");if(m(t))return{isSetup:!0,reason:"src/store directory exists"};if(m(r)){let n=JSON.parse(await u(r));if(n.dependencies?.["@reduxjs/toolkit"]||n.devDependencies?.["@reduxjs/toolkit"])return{isSetup:!0,reason:"@reduxjs/toolkit is installed"}}return{isSetup:!1,reason:""}},wo=async e=>{let t=$r.join(e,c.PROVIDERS_INDEX);if(!await bt(e)||!m(t))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx (or src/app/[locale]/layout.tsx) and src/providers/index.ts exist.")};S();P();import Ir from"node:path";var vo=async e=>{},So=async e=>{let t=Ir.join(e,"src/providers/RootProvider.tsx");if(!m(t))return;let r=await u(t),n="'use client';",i=r.includes(n);if(i&&(r=r.replace(n,"").trim()),r.includes("from '@/store'")||(r=`import type { AppState } from '@/store';
929
+ `,p=o.indexOf("{",s);o=o.slice(0,p+1)+c+o.slice(p+1)}await h(n,o),await C(r)}};var mr=async e=>{let t=S("Setting up Internationalization (next-intl)..."),r=ci.join(e,".next-maker-temp-i18n");try{let{isSetup:i,reason:n}=await Mo(e);if(i){t.fail(`i18n is already set up (${n}).`);return}await Go(e),await jo(r,t),t.text="Copying i18n files...",await Lo(e,r),t.text="Configuring project structure...",await ar(e),await cr(e),await pr(e),await lr(e),t.text="Migrating to [locale] structure...",await Ho(e),t.text="Installing dependencies...",await z(e,"next-intl");let o=ci.join(e,a.VITEST_CONFIG);if(l(o)){let c=JSON.parse(await g(ci.join(e,a.PACKAGE_JSON))),p={...c.dependencies,...c.devDependencies},u=!!(p["@reduxjs/toolkit"]&&p["react-redux"]);await ce(e,{redux:u,i18n:!0})}t.text="Formatting code...";let s=await A(e);await K(e,s,"lint:fix"),t.succeed(pl.green("Internationalization setup successfully!"))}catch(i){throw t.fail("Failed to setup Internationalization."),i}finally{await v(r)}};P();import ll from"node:fs/promises";import Pt from"node:path";import Uo from"picocolors";w();var ml="src/providers/RootProvider.tsx",Bo=async(e,t)=>{let r=S("Repairing Internationalization..."),i=Pt.join(e,".next-maker-temp-i18n-repair");try{let n=Pt.join(e,a.I18N_DIR),o=Pt.join(e,a.PROXY),s=F(t,a.I18N_DIR)&&!l(n),c=F(t,a.PROXY)&&!l(o),p=[];(s||c)&&(r.text="Fetching assets from starter repo...",await te(i,async x=>{s&&(await ll.cp(Pt.join(x,a.I18N_DIR),n,{recursive:!0}),p.push(a.I18N_DIR)),c&&(await b(Pt.join(x,a.PROXY),o),p.push(a.PROXY))})),U(t,a.NEXT_CONFIG)&&(r.text="Restoring the next-intl plugin wrap...",await ar(e),p.push("createNextIntlPlugin wrap")),U(t,ml)&&(r.text="Restoring <NextIntlClientProvider>...",await lr(e),p.push("<NextIntlClientProvider> wrap")),p.length>0&&(await cr(e),await pr(e)),r.text="Restoring dependencies...";let u=await B(e,t),d=F(t,a.LOCALE_DIR),f=[p.length>0?`restored ${p.join(", ")}`:null,u.length>0?`reinstalled ${u.join(", ")}`:null].filter(Boolean);r.succeed(Uo.green(f.length>0?`Internationalization repaired (${f.join("; ")}).`:"Internationalization repaired.")),d&&console.log(Uo.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 zo={id:"i18n",name:"Internationalization",description:"next-intl with [locale] routing, RootProvider, and proxy.ts",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(q(),ct));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:fo},{file:"src/providers/RootProvider.tsx",description:"<NextIntlClientProvider> wrap",presence:/NextIntlClientProvider/,removePattern:Ve("NextIntlClientProvider")}],apply:O(mr,Bo)};P();w();import hl from"node:path";P();import dl from"node:path";import ul from"picocolors";w();var Vo=/(const\s+nextConfig\s*:\s*NextConfig\s*=\s*\{)/,dr=e=>/reactCompiler\s*:/.test(e),vt=e=>{if(dr(e))return e;if(!Vo.test(e))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");return e.replace(Vo,`$1
930
+ reactCompiler: true,`)};var ur=async e=>{let t=S("Enabling React Compiler...");try{let r=dl.join(e,a.NEXT_CONFIG);if(!l(r))throw new Error(`${a.NEXT_CONFIG} not found.`);let i=await g(r);if(dr(i)){t.fail("React Compiler is already configured in next.config.ts.");return}await h(r,vt(i)),t.text="Installing babel-plugin-react-compiler...",await At(e,"babel-plugin-react-compiler"),t.succeed(ul.green("React Compiler enabled."))}catch(r){throw t.fail("Failed to enable React Compiler."),r}};P();import fl from"node:path";import gl from"picocolors";w();var Jo=async(e,t)=>{let r=S("Repairing React Compiler...");try{if(U(t,a.NEXT_CONFIG)){let n=fl.join(e,a.NEXT_CONFIG);if(l(n)){let o=await g(n),s=vt(o);s!==o&&await h(n,s)}}let i=await B(e,t);r.succeed(gl.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 Wo={id:"react-compiler",name:"React Compiler",description:"reactCompiler: true in next.config.ts + babel-plugin-react-compiler",detect:async e=>{let t=hl.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(ur,Jo)};P();import mi from"node:path";import yl from"picocolors";w();P();import qo from"node:fs/promises";import _e from"node:path";w();var Xo=async(e,t)=>{t.text="Fetching assets from starter repo...",await J(e)},Yo=async(e,t)=>{let r=_e.join(t,"src/providers/StoreProvider.tsx"),i=_e.join(e,a.STORE_PROVIDER);await b(r,i);let n=_e.join(t,"src/store"),o=_e.join(e,a.STORE);await qo.cp(n,o,{recursive:!0})},Ko=async(e,t)=>{let r=_e.join(t,"src/features/counter"),i=_e.join(e,a.COUNTER_FEATURE);await qo.cp(r,i,{recursive:!0});let n=_e.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 pi from"node:path";var Zo=async e=>{let t=pi.join(e,a.STORE),r=pi.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:""}},Qo=async e=>{let t=pi.join(e,a.PROVIDERS_INDEX);if(!await Yt(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 li from"node:path";var es=async e=>{},fr=async e=>{let t=li.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
931
  ${r}`),r.includes("from './StoreProvider'")||(r=`${r.includes("from '@/store'"),""}import { StoreProvider } from './StoreProvider';
930
- ${r}`),i&&(r=`${n}
932
+ ${r}`),n&&(r=`${i}
931
933
  ${r}`),r.includes("preloadedState")||(r=r.replace(/children:\s*React\.ReactNode;/,`children: React.ReactNode;
932
934
  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
935
  <StoreProvider preloadedState={preloadedState}>
934
936
  ${s}
935
937
  </StoreProvider>
936
- );`)}}await g(t,r)},Eo=async e=>{let t=[Ir.join(e,c.ROOT_PAGE),Ir.join(e,"src/app/[locale]/page.tsx")],r="";for(let i of t)if(m(i)){r=i;break}if(!r)return;let n=await u(r);if(n.includes("Counter")||(n=`import { Counter } from '@/features/counter';
937
- ${n}`),!n.includes("<Counter />")){let i=n.lastIndexOf("</div>"),o=n.lastIndexOf("</main>"),s=o!==-1?o:i;s!==-1&&(n=n.slice(0,s)+`
938
+ );`)}}await h(t,r)},ts=async e=>{let t=[li.join(e,a.ROOT_PAGE),li.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';
939
+ ${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
940
  <div className="mt-8">
939
941
  <h2 className="mb-4 text-2xl font-bold">Redux Counter</h2>
940
942
  <Counter />
941
943
  </div>
942
- `+n.slice(s),await g(r,n))}};var Ft=async e=>{let t=b("Setting up Redux Toolkit..."),r=Nr.join(e,".next-maker-temp-redux");try{let{isSetup:n,reason:i}=await Po(e);if(n){t.fail(`Redux is already set up (${i}).`);return}await wo(e),await ho(r,t),t.text="Copying Redux files...",await yo(e,r),t.text="Creating Counter feature...",await xo(e,r),t.text="Updating providers and pages...",await vo(e),await So(e),await Eo(e),t.text="Installing dependencies...",await U(e,"@reduxjs/toolkit"),await U(e,"react-redux"),await U(e,"redux-persist"),await U(e,"react-secure-storage");let o=Nr.join(e,c.VITEST_CONFIG);if(m(o)){let a=JSON.parse(await u(Nr.join(e,c.PACKAGE_JSON))),p={...a.dependencies,...a.devDependencies};await me(e,{redux:!0,i18n:!!p["next-intl"]})}t.text="Formatting code...";let s=await k(e);await J(e,s,"lint:fix"),t.succeed(xp.green("Redux Toolkit setup successfully!"))}catch(n){throw t.fail("Failed to setup Redux Toolkit."),n}finally{await w(r)}};var Co={id:"redux",name:"Redux Toolkit",description:"Redux Toolkit + react-redux + redux-persist + StoreProvider",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(B(),Ye));return(await t(e)).hasRedux},files:[{path:"src/store",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds the rootReducer and any slices you registered \u2014 review before deleting"},{path:"src/providers/StoreProvider.tsx",generated:!0}],packages:[{name:"@reduxjs/toolkit",kind:"dependency"},{name:"react-redux",kind:"dependency"},{name:"redux-persist",kind:"dependency"}],scripts:[],injections:[{file:"src/providers/RootProvider.tsx",description:"<StoreProvider> wrap in RootProvider",presence:/<StoreProvider/,removePattern:_e("StoreProvider")}],apply:Ft};S();P();import Ep from"node:path";S();import vp from"node:path";import Sp from"picocolors";P();var bo=[{key:"X-DNS-Prefetch-Control",value:"on"},{key:"Strict-Transport-Security",value:"max-age=63072000; includeSubDomains; preload"},{key:"X-XSS-Protection",value:"1; mode=block"},{key:"X-Frame-Options",value:"SAMEORIGIN"},{key:"X-Content-Type-Options",value:"nosniff"},{key:"Referrer-Policy",value:"origin-when-cross-origin"}],To=/(const\s+nextConfig\s*:\s*NextConfig\s*=\s*\{)/,Pp=/^\s+headers\s*:/m,wp=e=>`
944
+ `+i.slice(s),await h(r,i))}};var gr=async e=>{let t=S("Setting up Redux Toolkit..."),r=mi.join(e,".next-maker-temp-redux");try{let{isSetup:i,reason:n}=await Zo(e);if(i){t.fail(`Redux is already set up (${n}).`);return}await Qo(e),await Xo(r,t),t.text="Copying Redux files...",await Yo(e,r),t.text="Creating Counter feature...",await Ko(e,r),t.text="Updating providers and pages...",await es(e),await fr(e),await ts(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=mi.join(e,a.VITEST_CONFIG);if(l(o)){let c=JSON.parse(await g(mi.join(e,a.PACKAGE_JSON))),p={...c.dependencies,...c.devDependencies};await ce(e,{redux:!0,i18n:!!p["next-intl"]})}t.text="Formatting code...";let s=await A(e);await K(e,s,"lint:fix"),t.succeed(yl.green("Redux Toolkit setup successfully!"))}catch(i){throw t.fail("Failed to setup Redux Toolkit."),i}finally{await v(r)}};P();import xl from"node:fs/promises";import St from"node:path";import wl from"picocolors";w();var Pl="src/providers/RootProvider.tsx",rs=async(e,t)=>{let r=S("Repairing Redux Toolkit..."),i=St.join(e,".next-maker-temp-redux-repair");try{let n=St.join(e,a.STORE),o=St.join(e,a.STORE_PROVIDER),s=F(t,a.STORE)&&!l(n),c=F(t,a.STORE_PROVIDER)&&!l(o),p=[];(s||c)&&(r.text="Fetching assets from starter repo...",await te(i,async f=>{s&&(await xl.cp(St.join(f,a.STORE),n,{recursive:!0}),p.push(a.STORE)),c&&(await b(St.join(f,a.STORE_PROVIDER),o),p.push(a.STORE_PROVIDER))})),U(t,Pl)&&(r.text="Restoring <StoreProvider> wrap...",await fr(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(wl.green(d.length>0?`Redux Toolkit repaired (${d.join("; ")}).`:"Redux Toolkit repaired."))}catch(n){throw r.fail("Failed to repair Redux Toolkit."),n}};var is={id:"redux",name:"Redux Toolkit",description:"Redux Toolkit + react-redux + redux-persist + StoreProvider",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(q(),ct));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:Ve("StoreProvider")}],apply:O(gr,rs)};P();w();import bl from"node:path";P();import El from"node:path";import Tl from"picocolors";w();var os=[{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"}],ns=/(const\s+nextConfig\s*:\s*NextConfig\s*=\s*\{)/,vl=/^\s+headers\s*:/m,Sl=e=>`
943
945
  headers: async () => {
944
946
  return [
945
947
  {
946
948
  source: '/:path*',
947
949
  headers: [
948
- ${e.map(({key:r,value:n})=>` { key: '${r}', value: '${n}' },`).join(`
950
+ ${e.map(({key:r,value:i})=>` { key: '${r}', value: '${i}' },`).join(`
949
951
  `)}
950
952
  ],
951
953
  },
952
954
  ];
953
- },`,Oe=e=>Pp.test(e),kr=(e,t=bo)=>{if(Oe(e))return e;if(!To.test(e))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");return e.replace(To,`$1${wp(t)}`)};var jt=async e=>{let t=b("Adding security headers to next.config.ts...");try{let r=vp.join(e,c.NEXT_CONFIG);if(!m(r))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await u(r);if(Oe(n)){t.succeed("Security headers already configured.");return}let i=kr(n);await g(r,i),t.succeed(Sp.green("Security headers added."))}catch(r){throw t.fail("Failed to add security headers."),r}};var Ro={id:"security-headers",name:"Security Headers",description:"Hardened HTTP headers in next.config.ts",detect:async e=>{let t=Ep.join(e,c.NEXT_CONFIG);return m(t)?Oe(await u(t)):!1},files:[],packages:[],scripts:[],injections:[{file:c.NEXT_CONFIG,description:"headers() function in next.config.ts",presence:/^\s+headers\s*:/m,removePattern:/\s+headers:\s*async\s*\(\)\s*=>\s*\{[\s\S]*?\n\s{0,2}\},/m}],apply:jt};S();P();import $p from"node:path";S();import Cp from"node:fs/promises";import ge from"node:path";import Tp from"degit";import bp from"picocolors";P();var Rp=["vitest","jsdom","@vitejs/plugin-react","@testing-library/dom","@testing-library/jest-dom","@testing-library/react","@testing-library/user-event"],Dt=async e=>{let t=b("Setting up testing (Vitest + RTL)..."),r=ge.join(e,".next-maker-temp-tests");try{let n=ge.join(e,c.VITEST_CONFIG);if(m(n)){t.fail("Testing is already set up (vitest.config.ts exists).");return}t.text="Fetching assets from starter repo...",await Tp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(r),await N(ge.join(r,c.VITEST_CONFIG),ge.join(e,c.VITEST_CONFIG));let o=ge.join(e,c.TEST_DIR);await Cp.mkdir(o,{recursive:!0}),await N(ge.join(r,c.TEST_DIR,"setup.ts"),ge.join(o,"setup.ts"));let s=ge.join(e,c.PACKAGE_JSON),a=JSON.parse(await u(s)),p={...a.dependencies,...a.devDependencies},f=!!(p["@reduxjs/toolkit"]&&p["react-redux"]),d=!!p["next-intl"];await me(e,{redux:f,i18n:d}),await D(s,x=>(x.scripts=x.scripts??{},x.scripts.test=x.scripts.test??"vitest run",x.scripts["test:watch"]=x.scripts["test:watch"]??"vitest",x.scripts["test:coverage"]=x.scripts["test:coverage"]??"vitest run --coverage",typeof x.scripts.validate=="string"&&!/\byarn\s+test(?![:\w])/.test(x.scripts.validate)&&(x.scripts.validate=x.scripts.validate.replace(/(\byarn\s+check:deprecated\s*)(&&)/,"$1&& yarn test $2")),x)),t.text="Installing testing devDependencies...";let h=await k(e);await Pe(e,h,Rp),t.text="Formatting code...",await J(e,h,"lint:fix"),t.succeed(bp.green("Testing setup complete."))}catch(n){throw t.fail("Failed to set up testing."),n}finally{await w(r)}};var $o={id:"tests",name:"Tests",description:"Vitest + React Testing Library + jsdom",detect:async e=>m($p.join(e,c.VITEST_CONFIG)),files:[{path:c.VITEST_CONFIG,generated:!0},{path:"test",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds setup.ts / test-utils.tsx and any helpers you added \u2014 review before deleting"}],packages:[{name:"vitest",kind:"devDependency"},{name:"jsdom",kind:"devDependency"},{name:"@vitejs/plugin-react",kind:"devDependency"},{name:"@testing-library/dom",kind:"devDependency"},{name:"@testing-library/jest-dom",kind:"devDependency"},{name:"@testing-library/react",kind:"devDependency"},{name:"@testing-library/user-event",kind:"devDependency"}],scripts:[{name:"test",expectedValue:"vitest run"},{name:"test:watch",expectedValue:"vitest"}],injections:[],apply:Dt};P();import _p from"node:path";S();import Io from"node:path";import kp from"picocolors";P();var Ip={npm:"npm run",yarn:"yarn",pnpm:"pnpm",bun:"bun run"},Np=e=>{let t=Ip[e];return["ci:check","type-check","check:deprecated","test","build"].map(r=>`${t} ${r}`).join(" && ")},Ar=(e,t)=>{let r={...e.scripts??{}},n={...e.devDependencies??{}};return r["env:sync"]||(r["env:sync"]="tsx scripts/sync-env.ts"),r["check:deprecated"]||(r["check:deprecated"]="tsx scripts/check-deprecated.ts"),r["type-check"]||(r["type-check"]="tsc --noEmit"),r.validate||(r.validate=Np(t)),!n.tsx&&!Object.hasOwn(e.dependencies??{},"tsx")&&(n.tsx="*"),{...e,scripts:r,devDependencies:n}};var _r=`import * as fs from 'node:fs';
955
+ },`,Je=e=>vl.test(e),Et=(e,t=os)=>{if(Je(e))return e;if(!ns.test(e))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");return e.replace(ns,`$1${Sl(t)}`)};var hr=async e=>{let t=S("Adding security headers to next.config.ts...");try{let r=El.join(e,a.NEXT_CONFIG);if(!l(r))throw new Error(`${a.NEXT_CONFIG} not found.`);let i=await g(r);if(Je(i)){t.succeed("Security headers already configured.");return}let n=Et(i);await h(r,n),t.succeed(Tl.green("Security headers added."))}catch(r){throw t.fail("Failed to add security headers."),r}};P();import Cl from"node:path";import Rl from"picocolors";w();var ss=async(e,t)=>{if(!U(t,a.NEXT_CONFIG))return;let r=S("Repairing security headers...");try{let i=Cl.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=Et(n);o!==n&&await h(i,o),r.succeed(Rl.green("Security headers restored."))}catch(i){throw r.fail("Failed to repair security headers."),i}};var as={id:"security-headers",name:"Security Headers",description:"Hardened HTTP headers in next.config.ts",detect:async e=>{let t=bl.join(e,a.NEXT_CONFIG);return l(t)?Je(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(hr,ss)};P();w();import Al from"node:path";P();import Il from"node:fs/promises";import Ce from"node:path";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"],yr=async e=>{let t=S("Setting up testing (Vitest + RTL)..."),r=Ce.join(e,".next-maker-temp-tests");try{let i=Ce.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 J(r),await b(Ce.join(r,a.VITEST_CONFIG),Ce.join(e,a.VITEST_CONFIG));let n=Ce.join(e,a.TEST_DIR);await Il.mkdir(n,{recursive:!0}),await b(Ce.join(r,a.TEST_DIR,"setup.ts"),Ce.join(n,"setup.ts"));let o=Ce.join(e,a.PACKAGE_JSON),s=JSON.parse(await g(o)),c={...s.dependencies,...s.devDependencies},p=!!(c["@reduxjs/toolkit"]&&c["react-redux"]),u=!!c["next-intl"];await ce(e,{redux:p,i18n:u}),await _(o,f=>(f.scripts=f.scripts??{},f.scripts.test=f.scripts.test??"vitest run",f.scripts["test:watch"]=f.scripts["test:watch"]??"vitest",f.scripts["test:coverage"]=f.scripts["test:coverage"]??"vitest run --coverage",typeof f.scripts.validate=="string"&&!/\byarn\s+test(?![:\w])/.test(f.scripts.validate)&&(f.scripts.validate=f.scripts.validate.replace(/(\byarn\s+check:deprecated\s*)(&&)/,"$1&& yarn test $2")),f)),t.text="Installing testing devDependencies...";let d=await A(e);await fe(e,d,kl),t.text="Formatting code...",await K(e,d,"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 cs=async(e,t)=>{let r=S("Repairing testing setup..."),i=Fe.join(e,".next-maker-temp-tests-repair");try{let n=F(t,a.VITEST_CONFIG)&&!l(Fe.join(e,a.VITEST_CONFIG)),o=Fe.join(e,a.TEST_SETUP_FILE),s=F(t,a.TEST_DIR)&&!l(o),c=[];if((n||s)&&(r.text="Fetching assets from starter repo...",await te(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),x=l(f)?JSON.parse(await g(f)):{},I={...x.dependencies,...x.devDependencies};await ce(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 Ee(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 ps={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(yr,cs)};w();import jl from"node:path";P();import ds from"node:path";import Ol from"picocolors";w();var _l={npm:"npm run",yarn:"yarn",pnpm:"pnpm",bun:"bun run"},Fl=e=>{let t=_l[e];return["ci:check","type-check","check:deprecated","test","build"].map(r=>`${t} ${r}`).join(" && ")},Tt=(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=Fl(t)),!i.tsx&&!Object.hasOwn(e.dependencies??{},"tsx")&&(i.tsx="*"),{...e,scripts:r,devDependencies:i}};var ls=`import * as fs from 'node:fs';
954
956
  import * as path from 'node:path';
955
957
 
956
958
  const checkOnly = process.argv.includes('--check');
@@ -1024,7 +1026,7 @@ if (checkOnly) {
1024
1026
 
1025
1027
  fs.writeFileSync(examplePath, newExampleContent);
1026
1028
  console.log('\u2705 Synchronized .env.example with .env');
1027
- `,Or=`/**
1029
+ `,ms=`/**
1028
1030
  * Walks every identifier in the project and flags any whose resolved TypeScript
1029
1031
  * symbol carries a \`@deprecated\` JSDoc tag. Catches deprecated API usage that
1030
1032
  * \`tsc --noEmit\` does not surface (deprecations are "suggestion"-level, not
@@ -1088,118 +1090,120 @@ if (hits === 0) {
1088
1090
 
1089
1091
  console.log(\`\\n\${hits} deprecated symbol use(s) found.\`);
1090
1092
  process.exit(1);
1091
- `;var Ap=[{relative:"scripts/sync-env.ts",content:_r},{relative:"scripts/check-deprecated.ts",content:Or}],Lt=async e=>{let t=b("Adding validation scripts...");try{let r=!1;for(let{relative:o,content:s}of Ap){let a=Io.join(e,o);m(a)||(await g(a,s),r=!0)}let n=await k(e),i=!1;await D(Io.join(e,c.PACKAGE_JSON),o=>{let s=o.devDependencies?.tsx,a=Ar(o,n);return i=!s&&!!a.devDependencies?.tsx,a}),i&&(t.text="Installing tsx...",await Pe(e,n,["tsx"])),t.succeed(kp.green(r?"Validation scripts added (env:sync, check:deprecated, validate).":"Validation scripts already present \u2014 refreshed package.json."))}catch(r){throw t.fail("Failed to add validation scripts."),r}};var No=["scripts/sync-env.ts","scripts/check-deprecated.ts"],ko={id:"validate-scripts",name:"Validation Scripts",description:"sync-env, check-deprecated, and the validate chain",detect:async e=>No.every(t=>m(_p.join(e,t))),files:No.map(e=>({path:e,generated:!0})),packages:[{name:"tsx",kind:"devDependency"}],scripts:[{name:"env:sync",expectedValue:"tsx scripts/sync-env.ts"},{name:"check:deprecated",expectedValue:"tsx scripts/check-deprecated.ts"},{name:"type-check",expectedValue:"tsc --noEmit"},{name:"validate"}],injections:[],apply:Lt};import{access as Dp,readFile as Lp}from"node:fs/promises";import Do from"node:path";S();import jr from"node:path";import jp from"picocolors";P();S();P();import Fr from"node:fs/promises";import st from"node:path";import Op from"degit";var Ao=async(e,t)=>{t.text="Downloading assets from starter repository...",await Op("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},_o=async(e,t,r)=>{let n=st.join(e,c.WS_UTILS);await Fr.cp(st.join(t,c.WS_UTILS),n,{recursive:!0,force:!0});let i=st.join(e,c.WS_SLICE_FILE);await N(st.join(t,c.WS_SLICE_FILE),i),r.keepTests||await Fp(n)},Fp=async e=>{let t=async r=>{let n=await Fr.readdir(r,{withFileTypes:!0});for(let i of n){let o=st.join(r,i.name);if(i.isDirectory()){if(i.name==="__test-utils__"){await w(o);continue}await t(o)}else i.isFile()&&/\.test\.tsx?$/.test(i.name)&&await Fr.unlink(o)}};await t(e)};S();P();import Oo from"node:path";var Fo=async e=>{let t=Oo.join(e,c.WS_UTILS);return m(t)?{isSetup:!0,reason:"src/lib/utils/ws/ already exists"}:{isSetup:!1}},jo=async e=>{let t=[],r=[{rel:"src/lib",label:"src/lib"},{rel:"src/store",label:"src/store (Redux Toolkit not installed?)"},{rel:c.ROOT_REDUCER,label:"src/store/rootReducer.ts (Redux not initialised?)"},{rel:c.STORE_PROVIDER,label:"src/providers/StoreProvider.tsx (Redux not initialised?)"}];for(let{rel:n,label:i}of r)m(Oo.join(e,n))||t.push(`- ${i}`);if(t.length>0)throw new Error(`WebSocket setup requires Redux Toolkit. Missing:
1093
+ `,Ct=[{relative:"scripts/sync-env.ts",content:ls},{relative:"scripts/check-deprecated.ts",content:ms}];var xr=async e=>{let t=S("Adding validation scripts...");try{let r=!1;for(let{relative:o,content:s}of Ct){let c=ds.join(e,o);l(c)||(await h(c,s),r=!0)}let i=await A(e),n=!1;await _(ds.join(e,a.PACKAGE_JSON),o=>{let s=o.devDependencies?.tsx,c=Tt(o,i);return n=!s&&!!c.devDependencies?.tsx,c}),n&&(t.text="Installing tsx...",await fe(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 us from"node:path";import Dl from"picocolors";w();var fs=async(e,t)=>{let r=S("Repairing validation scripts...");try{let i=[];for(let{relative:p,content:u}of Ct){if(!F(t,p))continue;let d=us.join(e,p);l(d)||(await h(d,u),i.push(p))}let n=await B(e,t),o=us.join(e,a.PACKAGE_JSON);if(l(o)){let p=await A(e);await _(o,u=>Tt(u,p))}let s=await Ee(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(Dl.green(c.length>0?`Validation scripts repaired (${c.join("; ")}).`:"Validation scripts repaired."))}catch(i){throw r.fail("Failed to repair validation scripts."),i}};var gs=["scripts/sync-env.ts","scripts/check-deprecated.ts"],hs={id:"validate-scripts",name:"Validation Scripts",description:"sync-env, check-deprecated, and the validate chain",detect:async e=>gs.every(t=>l(jl.join(e,t))),files:gs.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(xr,fs)};import{access as Ul,readFile as Bl}from"node:fs/promises";import Es from"node:path";P();import fi from"node:path";import Ll from"picocolors";w();P();import di from"node:fs/promises";import Rt from"node:path";w();var ys=async(e,t)=>{t.text="Downloading assets from starter repository...",await J(e)},xs=async(e,t,r)=>{let i=Rt.join(e,a.WS_UTILS);await di.cp(Rt.join(t,a.WS_UTILS),i,{recursive:!0,force:!0});let n=Rt.join(e,a.WS_SLICE_FILE);await b(Rt.join(t,a.WS_SLICE_FILE),n),r.keepTests||await ui(i)},ui=async e=>{let t=async r=>{let i=await di.readdir(r,{withFileTypes:!0});for(let n of i){let o=Rt.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 di.unlink(o)}};await t(e)};P();w();import ws from"node:path";var Ps=async e=>{let t=ws.join(e,a.WS_UTILS);return l(t)?{isSetup:!0,reason:"src/lib/utils/ws/ already exists"}:{isSetup:!1}},vs=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(ws.join(e,i))||t.push(`- ${n}`);if(t.length>0)throw new Error(`WebSocket setup requires Redux Toolkit. Missing:
1092
1094
  ${t.join(`
1093
1095
  `)}
1094
1096
 
1095
- Run \`next-maker setup --redux\` first.`)};var Mt=async e=>{let t=b("Setting up WebSocket layer..."),r=jr.join(e,".next-maker-temp-ws");try{let{isSetup:n,reason:i}=await Fo(e);if(n){t.fail(`WebSocket layer is already set up (${i}).`);return}await jo(e),await Ao(r,t),t.text="Copying WebSocket files...";let o=m(jr.join(e,c.VITEST_CONFIG));await _o(e,r,{keepTests:o}),t.text="Registering wsReducer...",await Un(e),t.text="Mounting WS bridge in StoreProvider...",await Hn(e),t.text="Ensuring test/setup.ts mocks...",await Bn(e),t.text="Installing socket.io-client...";let s=jr.join(e,c.PACKAGE_JSON),a=JSON.parse(await u(s));({...a.dependencies,...a.devDependencies})["socket.io-client"]||await U(e,"socket.io-client@^4.8.3"),t.text="Formatting code...";let f=await k(e);await J(e,f,"lint:fix"),t.succeed(jp.green("WebSocket layer setup successfully!"))}catch(n){throw t.fail("Failed to setup WebSocket layer."),n}finally{await w(r)}};var Mp=async e=>{try{let t=JSON.parse(await Lp(Do.join(e,"package.json"),"utf-8"));return{...t.dependencies,...t.devDependencies}["socket.io-client"]?(await Dp(Do.join(e,"src/lib/utils/ws")),!0):!1}catch{return!1}},Lo={id:"ws",name:"WebSocket Client",description:"socket.io-client + lazy WS singleton + Redux slice + hooks",detect:Mp,files:[{path:"src/lib/utils/ws",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds the ws client + any feature event maps you added \u2014 review before deleting"},{path:"src/store/slices/ws.slice.ts",generated:!0}],packages:[{name:"socket.io-client",kind:"dependency"}],scripts:[],injections:[{file:"src/store/rootReducer.ts",description:"wsReducer registration in rootReducer",presence:/ws:\s*wsReducer\b/,removePattern:ht},{file:"src/providers/StoreProvider.tsx",description:"attachWsBridge mount in StoreProvider",presence:/attachWsBridge\(wsClient,\s*store\.dispatch\)/,removePattern:gt}],apply:Mt};S();P();import Fe from"node:path";var Mo=async e=>{let t=Fe.join(e,c.PACKAGE_JSON);return m(t)?JSON.parse(await u(t)):null},Gp=async(e,t)=>{let r=Fe.join(e,c.PACKAGE_JSON);await g(r,`${JSON.stringify(t,null,2)}
1096
- `)},Go=(e,t)=>(t==="dependency"?e.dependencies:e.devDependencies)??{},at=async(e,t)=>{let r=await e.detect(t),n=[];if(!r)return{manifest:e,installed:!1,drift:[]};for(let o of e.files)o.required!==!1&&(m(Fe.join(t,o.path))||n.push({kind:"missingFile",file:o.path}));let i=await Mo(t);if(i){for(let s of e.packages)Go(i,s.kind)[s.name]||n.push({kind:"missingPackage",name:s.name,depKind:s.kind});let o=i.scripts??{};for(let s of e.scripts){let a=o[s.name];a?s.expectedValue&&a!==s.expectedValue&&n.push({kind:"mismatchedScript",name:s.name,expected:s.expectedValue,actual:a}):n.push({kind:"missingScript",name:s.name})}}for(let o of e.injections){let s=Fe.join(t,o.file);if(!m(s)){n.push({kind:"missingInjection",file:o.file,description:o.description});continue}let a=await u(s);o.presence.test(a)||n.push({kind:"missingInjection",file:o.file,description:o.description})}return{manifest:e,installed:r,drift:n}},Gt=async(e,t,r={})=>{let n=r.dryRun??!1,i={filesRemoved:[],packagesUninstalled:[],scriptsRemoved:[],blocksStripped:[],manualCleanup:[]};for(let a of e.injections){let p=Fe.join(t,a.file);if(!m(p))continue;if(!a.removePattern){i.manualCleanup.push({file:a.file,description:a.description});continue}let f=await u(p);if(!a.presence.test(f))continue;let d;if(typeof a.removePattern=="function"){let h=a.removePattern(f);if(h===null){i.manualCleanup.push({file:a.file,description:a.description});continue}d=h}else d=f.replace(a.removePattern,"");d!==f?(n||await g(p,d),i.blocksStripped.push({file:a.file,description:a.description})):i.manualCleanup.push({file:a.file,description:a.description})}let{rm:o}=await import("node:fs/promises");for(let a of e.files){if(!a.generated)continue;let p=Fe.join(t,a.path);if(m(p)){if(a.containsUserContent){let f=a.removeHint?`${a.path} \u2014 ${a.removeHint}`:`${a.path} (may contain user-authored files; review before deleting)`;i.manualCleanup.push({file:a.path,description:f});continue}n||await o(p,{recursive:!0,force:!0}),i.filesRemoved.push(a.path)}}let s=await Mo(t);if(s){let a=!1;if(s.scripts)for(let p of e.scripts)s.scripts[p.name]&&(n||delete s.scripts[p.name],i.scriptsRemoved.push(p.name),a=!0);for(let p of e.packages)Go(s,p.kind)[p.name]&&i.packagesUninstalled.push(p.name);a&&!n&&await Gp(t,s)}if(!n&&i.packagesUninstalled.length>0){let a=await k(t);await qt(t,a,i.packagesUninstalled)}return i};var Ce=[Ro,ko,Di,fo,Fi,$o,qi,ro,Co,Lo,uo],Uo=e=>Ce.find(t=>t.id===e);var Up=e=>{switch(e.kind){case"missingFile":return`missing file: ${e.file}`;case"missingPackage":return`missing ${e.depKind==="dependency"?"dep":"devDep"}: ${e.name}`;case"missingScript":return`missing script: ${e.name}`;case"mismatchedScript":return`script "${e.name}" expected ${M.dim(e.expected)} but got ${M.dim(e.actual)}`;case"missingInjection":return`missing block in ${e.file}: ${e.description}`}},Hp=e=>{let t=e.filter(n=>n.installed),r=t.filter(n=>n.drift.length>0);return{installedCount:t.length,driftedCount:r.length,cleanCount:t.length-r.length,driftedResults:r}},Ho=e=>{e.command("doctor").description("Diagnose drift between the project and known feature manifests").option("--fix","Re-apply manifests that report drift (idempotent)").option("--feature <id>","Only check this manifest id (e.g. redux, security-headers)").option("--json","Print machine-readable JSON instead of the human report").action(async t=>{try{let r=process.cwd(),n=t.feature?Ce.filter(s=>s.id===t.feature):Ce;if(t.feature&&n.length===0)throw new Error(`Unknown feature "${t.feature}". Valid: ${Ce.map(s=>s.id).join(", ")}.`);let i=[];for(let s of n)i.push(await at(s,r));t.json&&(l(JSON.stringify(i.map(s=>({id:s.manifest.id,name:s.manifest.name,installed:s.installed,drift:s.drift})),null,2)),process.exit(i.some(s=>s.drift.length>0)?1:0)),l(M.cyan(`
1097
+ Run \`next-maker setup --redux\` first.`)};var wr=async e=>{let t=S("Setting up WebSocket layer..."),r=fi.join(e,".next-maker-temp-ws");try{let{isSetup:i,reason:n}=await Ps(e);if(i){t.fail(`WebSocket layer is already set up (${n}).`);return}await vs(e),await ys(r,t),t.text="Copying WebSocket files...";let o=l(fi.join(e,a.VITEST_CONFIG));await xs(e,r,{keepTests:o}),t.text="Registering wsReducer...",await Ft(e),t.text="Mounting WS bridge in StoreProvider...",await Dt(e),t.text="Ensuring test/setup.ts mocks...",await jt(e),t.text="Installing socket.io-client...";let s=fi.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 K(e,u,"lint:fix"),t.succeed(Ll.green("WebSocket layer setup successfully!"))}catch(i){throw t.fail("Failed to setup WebSocket layer."),i}finally{await v(r)}};P();import Ml from"node:fs/promises";import We from"node:path";import Gl from"picocolors";w();var Hl="socket.io-client@^4.8.3",Ss=async(e,t)=>{let r=S("Repairing WebSocket layer..."),i=We.join(e,".next-maker-temp-ws-repair");try{let n=We.join(e,a.WS_UTILS),o=We.join(e,a.WS_SLICE_FILE),s=F(t,a.WS_UTILS)&&!l(n),c=F(t,a.WS_SLICE_FILE)&&!l(o),p=[];if(s||c){r.text="Fetching assets from starter repo...";let f=l(We.join(e,a.VITEST_CONFIG));await te(i,async x=>{s&&(await Ml.cp(We.join(x,a.WS_UTILS),n,{recursive:!0,force:!0}),f||await ui(n),p.push(a.WS_UTILS)),c&&(await b(We.join(x,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 Dt(e),p.push("attachWsBridge mount")),await jt(e);let u=[];qt(t,"dependency").includes("socket.io-client")&&(r.text="Installing socket.io-client...",await z(e,Hl),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 zl=async e=>{try{let t=JSON.parse(await Bl(Es.join(e,"package.json"),"utf-8"));return{...t.dependencies,...t.devDependencies}["socket.io-client"]?(await Ul(Es.join(e,"src/lib/utils/ws")),!0):!1}catch{return!1}},Ts={id:"ws",name:"WebSocket Client",description:"socket.io-client + lazy WS singleton + Redux slice + hooks",detect:zl,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:Lt},{file:"src/providers/StoreProvider.tsx",description:"attachWsBridge mount in StoreProvider",presence:/attachWsBridge\(wsClient,\s*store\.dispatch\)/,removePattern:Ot}],apply:O(wr,Ss)};P();w();import Oe from"node:path";var Cs=async e=>{let t=Oe.join(e,a.PACKAGE_JSON);return l(t)?JSON.parse(await g(t)):null},Vl=async(e,t)=>{let r=Oe.join(e,a.PACKAGE_JSON);await h(r,`${JSON.stringify(t,null,2)}
1098
+ `)},Rs=(e,t)=>(t==="dependency"?e.dependencies:e.devDependencies)??{},bs=e=>[e.file,...e.alternativeFiles??[]],qe=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(Oe.join(t,o.path))||i.push({kind:"missingFile",file:o.path}));let n=await Cs(t);if(n){for(let s of e.packages)Rs(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=bs(o).filter(u=>l(Oe.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(Oe.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}},Pr=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 bs(c)){let u=Oe.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 x=c.removePattern(d);if(x===null){n.manualCleanup.push({file:p,description:c.description});continue}f=x}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=Oe.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 Cs(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)Rs(s,p.kind)[p.name]&&n.packagesUninstalled.push(p.name);c&&!i&&await Vl(t,s)}if(!i&&n.packagesUninstalled.length>0){let c=await A(t);await $r(t,c,n.packagesUninstalled)}return n};var De=[as,hs,wo,Wo,ho,ps,$o,Do,is,Ts,zo],Is=e=>De.find(t=>t.id===e);var $s=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}`}},Jl=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}},Wl={fixed:$.green("\u2713"),stillDrifted:$.red("\u2717"),noApply:$.yellow("\u26A0\uFE0F")},ql={fixed:$.green("FIXED"),stillDrifted:$.red("STILL DRIFTED"),noApply:$.yellow("NO AUTOMATIC FIX AVAILABLE")},Xl=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 qe(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},ks=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?De.filter(u=>u.id===t.feature):De;if(t.feature&&i.length===0)throw new Error(`Unknown feature "${t.feature}". Valid: ${De.map(u=>u.id).join(", ")}.`);let n=[];for(let u of i)n.push(await qe(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
1099
  \u{1FA7A} Project Doctor
1098
- `));for(let s of i){let{manifest:a,installed:p,drift:f}=s;if(!p){l(` ${M.dim("\u2014")} ${M.dim(a.name)} ${M.dim("(not installed)")}`);continue}if(f.length===0){l(` ${M.green("\u2713")} ${a.name}`);continue}l(` ${M.yellow("!")} ${M.bold(a.name)} ${M.dim(`(${f.length} issue${f.length===1?"":"s"})`)}`);for(let d of f)l(` ${M.yellow("\u2022")} ${Up(d)}`)}let o=Hp(i);l(""),l(M.dim(`${o.cleanCount} clean, ${o.driftedCount} drifted, ${i.length-o.installedCount} not installed`)),o.driftedCount===0&&(l(M.green(`
1100
+ `));for(let u of n){let{manifest:d,installed:f,drift:x}=u;if(!f){m(` ${$.dim("\u2014")} ${$.dim(d.name)} ${$.dim("(not installed)")}`);continue}if(x.length===0){m(` ${$.green("\u2713")} ${d.name}`);continue}m(` ${$.yellow("!")} ${$.bold(d.name)} ${$.dim(`(${x.length} issue${x.length===1?"":"s"})`)}`);for(let I of x)m(` ${$.yellow("\u2022")} ${$s(I)}`)}let o=Jl(n);m(""),m($.dim(`${o.cleanCount} clean, ${o.driftedCount} drifted, ${n.length-o.installedCount} not installed`)),o.driftedCount===0&&(m($.green(`
1099
1101
  \u2713 No drift detected.
1100
- `)),process.exit(0)),t.fix||(l(M.dim(`
1102
+ `)),process.exit(0)),t.fix||(m($.dim(`
1101
1103
  Run with --fix to re-apply drifted features.
1102
- `)),process.exit(1)),l(M.cyan(`
1104
+ `)),process.exit(1)),m($.cyan(`
1103
1105
  \u{1F527} Applying fixes...
1104
- `));for(let s of o.driftedResults){if(!s.manifest.apply){l(M.yellow(` \u26A0\uFE0F ${s.manifest.name} has no apply() \u2014 skipping.`));continue}try{await s.manifest.apply(r)}catch(a){v(`Failed to fix ${s.manifest.name}: ${a}`)}}l(M.green(`
1105
- \u2713 Doctor finished.
1106
- `))}catch(r){v(`${r instanceof Error?r.message:r}`),process.exit(1)}})};import je from"picocolors";S();P();import Dr from"node:path";var Bp=/^[A-Z][A-Z0-9_]*$/,Vo=e=>{if(!Bp.test(e))throw new Error(`Invalid env var name "${e}". Use UPPER_SNAKE_CASE (e.g. SENTRY_DSN, NEXT_PUBLIC_API_URL).`)},pe=(e,t)=>t?e.startsWith("NEXT_PUBLIC_")?e:`NEXT_PUBLIC_${e}`:e,Lr=e=>e.public?"client":"server",zp=e=>{if(e.default===void 0)return"";switch(e.type){case"number":return`.default(${Number(e.default)})`;case"boolean":return`.default(${e.default==="true"})`;default:return`.default('${e.default.replace(/'/g,"\\'")}')`}},Vp=e=>{switch(e.type){case"url":return"e.url()";case"number":return"e.number()";case"boolean":return"e.boolean()";case"enum":{let t=e.enumValues??[];if(t.length===0)throw new Error(`Enum env var "${e.name}" requires --enum values.`);return`e.enum([${t.map(n=>`'${n.replace(/'/g,"\\'")}'`).join(", ")}])`}default:return"e.string()"}},Jo=e=>{let t=pe(e.name,e.public),r=Vp(e),n=e.default!==void 0,i=!e.required&&!n;if(n&&(r+=zp(e)),i&&(r+=".optional()"),e.description){let o=e.description.replace(/'/g,"\\'");r+=`
1107
- .describe('${o}')`}return` ${t}: ${r},`},Wo=e=>{let t=pe(e.name,e.public);return` ${t}: process.env.${t},`},Jp=e=>new RegExp(`(${e}:\\s*\\{)([\\s\\S]*?)(\\n\\s*\\})`),Bo=/(runtimeEnv:\s*\{)([\s\S]*?)(\n\s*\})/,zo=(e,t,r,n)=>{let i=t.replace(/\s+$/,""),o=i.length===0||/,\s*$/.test(i)?i:`${i},`;return`${e}${o}
1108
- ${n}
1109
- ${r.replace(/^\n/,"")}`},qo=(e,t)=>{let r=pe(t.name,t.public),n=Lr(t);if(new RegExp(`\\b${r}\\s*:`).test(e))return e;if(!/defineEnv\(\{/.test(e))throw new Error("Could not locate `defineEnv({ \u2026 })` in src/lib/env/index.ts. Is this a @teispace/env project?");let o=Jp(n),s=e.match(o);if(!s)throw new Error(`Could not locate the \`${n}: { \u2026 }\` group in src/lib/env/index.ts.`);let[,a,p,f]=s,d=Jo(t),h=e.replace(o,zo(a,p,f,d)),x=h.match(Bo);if(!x)throw new Error("Could not locate the `runtimeEnv: { \u2026 }` map in src/lib/env/index.ts.");let[,R,L,$]=x;return h=h.replace(Bo,zo(R,L,$,Wo(t))),h},Wp="# -public",qp=e=>{let t=pe(e.name,e.public),r=e.default??"",n=e.public?` ${Wp}`:"";return`${t}=${r}${n}`},Xo=(e,t)=>{let r=pe(t.name,t.public);if(new RegExp(`^${r}=`,"m").test(e))return e;let i=e===""||e.endsWith(`
1106
+ `));let s=await Xl(o.driftedResults,r);m("");for(let u of s){m(` ${Wl[u.status]} ${u.name} ${ql[u.status]}`);for(let d of u.remaining)m(` ${$.yellow("\u2022")} ${$s(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(`
1107
+ ! Doctor could not fix everything.
1108
+ `)),process.exit(1)),m($.green(`
1109
+ \u2713 All drift fixed.
1110
+ `)),process.exit(0)}catch(r){E(`${r instanceof Error?r.message:r}`),process.exit(1)}})};import Xe from"picocolors";P();w();import gi from"node:path";var Yl=/^[A-Z][A-Z0-9_]*$/,_s=e=>{if(!Yl.test(e))throw new Error(`Invalid env var name "${e}". Use UPPER_SNAKE_CASE (e.g. SENTRY_DSN, NEXT_PUBLIC_API_URL).`)},ye=(e,t)=>t?e.startsWith("NEXT_PUBLIC_")?e:`NEXT_PUBLIC_${e}`:e,hi=e=>e.public?"client":"server",Kl=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,"\\'")}')`}},Zl=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()"}},Fs=e=>{let t=ye(e.name,e.public),r=Zl(e),i=e.default!==void 0,n=!e.required&&!i;if(i&&(r+=Kl(e)),n&&(r+=".optional()"),e.description){let o=e.description.replace(/'/g,"\\'");r+=`
1111
+ .describe('${o}')`}return` ${t}: ${r},`},Os=e=>{let t=ye(e.name,e.public);return` ${t}: process.env.${t},`},Ql=e=>new RegExp(`(${e}:\\s*\\{)([\\s\\S]*?)(\\n\\s*\\})`),Ns=/(runtimeEnv:\s*\{)([\s\S]*?)(\n\s*\})/,As=(e,t,r,i)=>{let n=t.replace(/\s+$/,""),o=n.length===0||/,\s*$/.test(n)?n:`${n},`;return`${e}${o}
1112
+ ${i}
1113
+ ${r.replace(/^\n/,"")}`},Ds=(e,t)=>{let r=ye(t.name,t.public),i=hi(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=Ql(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=Fs(t),f=e.replace(o,As(c,p,u,d)),x=f.match(Ns);if(!x)throw new Error("Could not locate the `runtimeEnv: { \u2026 }` map in src/lib/env/index.ts.");let[,I,H,k]=x;return f=f.replace(Ns,As(I,H,k,Os(t))),f},em="# -public",tm=e=>{let t=ye(e.name,e.public),r=e.default??"",i=e.public?` ${em}`:"";return`${t}=${r}${i}`},js=(e,t)=>{let r=ye(t.name,t.public);if(new RegExp(`^${r}=`,"m").test(e))return e;let n=e===""||e.endsWith(`
1110
1114
  `)?"":`
1111
1115
  `,o=e===""?"":`
1112
1116
  `,s=t.description?`# ${t.description}
1113
- `:"";return`${e}${i}${o}${s}${qp(t)}
1114
- `},Yo=(e,t)=>{let r=pe(t.name,t.public);if(new RegExp(`^${r}=`,"m").test(e))return e;let i=e===""||e.endsWith(`
1117
+ `:"";return`${e}${n}${o}${s}${tm(t)}
1118
+ `},Ls=(e,t)=>{let r=ye(t.name,t.public);if(new RegExp(`^${r}=`,"m").test(e))return e;let n=e===""||e.endsWith(`
1115
1119
  `)?"":`
1116
- `,o=t.default??"";return`${e}${i}${r}=${o}
1117
- `},Mr=async(e,t)=>{Vo(t.name);let r=Dr.join(e,"src/lib/env/index.ts");if(!m(r))throw new Error("src/lib/env/index.ts not found \u2014 run `next-maker init` first.");let n=await u(r),i=qo(n,t),o=i!==n;o&&await g(r,i);let s=Dr.join(e,c.ENV_EXAMPLE),a=!1;if(m(s)){let d=await u(s),h=Xo(d,t);a=h!==d,a&&await g(s,h)}let p=Dr.join(e,".env"),f=!1;if(m(p)){let d=await u(p),h=Yo(d,t);f=h!==d,f&&await g(p,h)}return{schemaUpdated:o,envExampleUpdated:a,envUpdated:f,group:Lr(t)}};var Ko=new Set(["string","url","number","boolean","enum"]),Xp=e=>{let t=(e??"string").toLowerCase();if(!Ko.has(t))throw new Error(`Invalid --type "${e}". Valid: ${Array.from(Ko).join(", ")}.`);return t},Yp=e=>{if(!e)return;let t=e.split(",").map(r=>r.trim()).filter(Boolean);return t.length===0?void 0:t},Zo=e=>{e.command("env <NAME>").description("Declare a new environment variable across src/lib/env/index.ts, .env.example, and .env").option("--type <type>","Coercer type (string|url|number|boolean|enum)","string").option("--required","Make the variable required (no .optional() / .default())").option("--default <value>","Set a default value (mutually exclusive with --required)").option("--public","Mark as public: place in the client group, auto-prefix NEXT_PUBLIC_, tag .env.example").option("--describe <text>","Description (rendered as .describe() and .env.example comment)").option("--enum <list>",'Comma-separated values when --type=enum (e.g. "dev,prod")').action(async(t,r)=>{try{let n=process.cwd();if(l(je.cyan(`
1120
+ `,o=t.default??"";return`${e}${n}${r}=${o}
1121
+ `},yi=async(e,t)=>{_s(t.name);let r=gi.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=Ds(i,t),o=n!==i;o&&await h(r,n);let s=gi.join(e,a.ENV_EXAMPLE),c=!1;if(l(s)){let d=await g(s),f=js(d,t);c=f!==d,c&&await h(s,f)}let p=gi.join(e,".env"),u=!1;if(l(p)){let d=await g(p),f=Ls(d,t);u=f!==d,u&&await h(p,f)}return{schemaUpdated:o,envExampleUpdated:c,envUpdated:u,group:hi(t)}};var Ms=new Set(["string","url","number","boolean","enum"]),rm=e=>{let t=(e??"string").toLowerCase();if(!Ms.has(t))throw new Error(`Invalid --type "${e}". Valid: ${Array.from(Ms).join(", ")}.`);return t},im=e=>{if(!e)return;let t=e.split(",").map(r=>r.trim()).filter(Boolean);return t.length===0?void 0:t},Gs=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(Xe.cyan(`
1118
1122
  \u{1F510} Env Var Generator
1119
- `)),r.required&&r.default!==void 0)throw new Error("--required and --default are mutually exclusive.");let i=Xp(r.type),o=Yp(r.enum);if(i==="enum"&&(!o||o.length===0))throw new Error("--type=enum requires at least one value via --enum a,b,c.");let s={name:t,type:i,required:!!r.required,default:r.default,description:r.describe,enumValues:o,public:!!r.public};y.start("Updating src/lib/env/index.ts, .env.example, and .env...");let a=await Mr(n,s);y.succeed("Env var written");let p=pe(s.name,s.public);l(je.green(`
1120
- \u2728 ${p} declared in the ${a.group} group.
1121
- `)),l(je.dim("Touched:")),l(je.dim(` ${a.schemaUpdated?"\u270F\uFE0F ":"\u23ED "} src/lib/env/index.ts`)),l(je.dim(` ${a.envExampleUpdated?"\u270F\uFE0F ":"\u23ED "} .env.example`)),l(je.dim(` ${a.envUpdated?"\u270F\uFE0F ":"\u23ED "} .env`)),l("")}catch(n){y.fail("Env var declaration failed"),v(`${n instanceof Error?n.message:n}`),process.exit(1)}})};import Bt from"node:path";import be from"picocolors";import Kp from"enquirer";var{prompt:Zp}=Kp,Qo=async(e={})=>e.source?{source:e.source}:{source:(await Zp({type:"input",name:"source",message:"Path to source image (PNG/JPG/JPEG/SVG/WebP/AVIF):",validate:r=>r?!0:"Source path is required"})).source};import{access as Qp,readFile as el,stat as tl}from"node:fs/promises";import Te from"node:path";var es=async e=>{try{return await Qp(e),!0}catch{return!1}},rl=async e=>{try{return(await tl(e)).isDirectory()}catch{return!1}},Ut=async e=>{let t=[Te.join(e,"src","app"),Te.join(e,"app")];for(let r of t)if(await rl(r))return r;return null},nl=["next-pwa","@ducanh2912/next-pwa","@serwist/next","serwist"],Gr=async e=>{let t={isPwa:!1},r=[Te.join(e,"public","manifest.json"),Te.join(e,"public","manifest.webmanifest"),Te.join(e,"public","site.webmanifest")];for(let i of r)if(await es(i)){t.publicManifestPath=i,t.isPwa=!0;break}let n=await Ut(e);if(n)for(let i of["ts","tsx","js"]){let o=Te.join(n,`manifest.${i}`);if(await es(o)){t.appManifestPath=o,t.isPwa=!0;break}}try{let i=JSON.parse(await el(Te.join(e,"package.json"),"utf-8")),o={...i.dependencies,...i.devDependencies};for(let s of nl)if(o[s]){t.framework=s,t.isPwa=!0;break}}catch{}return t};import{mkdir as cl,readFile as ls,stat as pl,writeFile as ll}from"node:fs/promises";import ie from"node:path";import ml from"sharp";import ol from"png-to-ico";import ct from"sharp";var ts=e=>e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;"),Ur=(e,t,r)=>{switch(e){case"square":return`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}"><rect width="${t}" height="${t}" fill="white"/></svg>`;case"circle":{let n=t/2;return`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}"><circle cx="${n}" cy="${n}" r="${n}" fill="white"/></svg>`}case"rounded":{let n=Math.round(t*r/100);return`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}"><rect width="${t}" height="${t}" rx="${n}" ry="${n}" fill="white"/></svg>`}case"squircle":return il(t)}},il=e=>{let t=e,r=t*.225,n=[`M 0 ${r}`,`C 0 0 0 0 ${r} 0`,`L ${t-r} 0`,`C ${t} 0 ${t} 0 ${t} ${r}`,`L ${t} ${t-r}`,`C ${t} ${t} ${t} ${t} ${t-r} ${t}`,`L ${r} ${t}`,`C 0 ${t} 0 ${t} 0 ${t-r}`,"Z"].join(" ");return`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}"><path d="${ts(n)}" fill="white"/></svg>`},rs=(e,t)=>`<svg xmlns="http://www.w3.org/2000/svg" width="${e}" height="${e}"><rect width="${e}" height="${e}" fill="${ts(t)}"/></svg>`;var De=async e=>{let{size:t,paddingPercent:r,bg:n,fit:i,shape:o,radiusPercent:s,quality:a,forceSquare:p,sourceBuffer:f}=e,d=Math.max(1,Math.round(t*(1-r*2/100))),h=i==="cover"?"cover":"contain",x=await ct(f,{density:384}).resize(d,d,{fit:h,background:{r:0,g:0,b:0,alpha:0}}).png().toBuffer(),R=Math.round((t-d)/2),L=n==="transparent"?{r:0,g:0,b:0,alpha:0}:await Hr(n),$=await ct({create:{width:t,height:t,channels:4,background:L}}).composite([{input:x,left:R,top:R}]).png().toBuffer();if(!p&&(o!=="square"||i==="clip")){let mt=o==="square"?"rounded":o,Us=Buffer.from(Ur(mt,t,s));$=await ct($).composite([{input:Us,blend:"dest-in"}]).png({compressionLevel:ns(a)}).toBuffer()}else $=await ct($).png({compressionLevel:ns(a)}).toBuffer();return $},Hr=async e=>{let t=await ct(Buffer.from(rs(1,e))).raw().toBuffer({resolveWithObject:!0}),[r,n,i,o=255]=t.data;return{r,g:n,b:i,alpha:o/255}},ns=e=>{let t=Math.round((100-e)/100*9);return Math.max(0,Math.min(9,t))},is=async e=>{if(e.length===0)throw new Error("No frames provided to encodeIco");return ol(e)};import{readFile as sl,writeFile as av}from"node:fs/promises";var os=e=>e.map(({src:t,size:r})=>({src:t,sizes:`${r}x${r}`,type:"image/png",purpose:"any maskable"})),ss=async(e,t)=>{let r=await sl(e,"utf-8"),n=JSON.parse(r),i=Array.isArray(n.icons)?n.icons:[],o=new Map;for(let s of[...i,...t])s&&typeof s.src=="string"&&o.set(s.src,s);return n.icons=[...o.values()],`${JSON.stringify(n,null,2)}
1122
- `};var as=e=>`icons: [
1123
+ `)),r.required&&r.default!==void 0)throw new Error("--required and --default are mutually exclusive.");let n=rm(r.type),o=im(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};y.start("Updating src/lib/env/index.ts, .env.example, and .env...");let c=await yi(i,s);y.succeed("Env var written");let p=ye(s.name,s.public);m(Xe.green(`
1124
+ \u2728 ${p} declared in the ${c.group} group.
1125
+ `)),m(Xe.dim("Touched:")),m(Xe.dim(` ${c.schemaUpdated?"\u270F\uFE0F ":"\u23ED "} src/lib/env/index.ts`)),m(Xe.dim(` ${c.envExampleUpdated?"\u270F\uFE0F ":"\u23ED "} .env.example`)),m(Xe.dim(` ${c.envUpdated?"\u270F\uFE0F ":"\u23ED "} .env`)),m("")}catch(i){y.fail("Env var declaration failed"),E(`${i instanceof Error?i.message:i}`),process.exit(1)}})};import Er from"node:path";import Le from"picocolors";import nm from"enquirer";var{prompt:om}=nm,Hs=async(e={})=>e.source?{source:e.source}:{source:(await om({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 sm,readFile as am,stat as cm}from"node:fs/promises";import je from"node:path";var Us=async e=>{try{return await sm(e),!0}catch{return!1}},pm=async e=>{try{return(await cm(e)).isDirectory()}catch{return!1}},vr=async e=>{let t=[je.join(e,"src","app"),je.join(e,"app")];for(let r of t)if(await pm(r))return r;return null},lm=["next-pwa","@ducanh2912/next-pwa","@serwist/next","serwist"],xi=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 Us(n)){t.publicManifestPath=n,t.isPwa=!0;break}let i=await vr(e);if(i)for(let n of["ts","tsx","js"]){let o=je.join(i,`manifest.${n}`);if(await Us(o)){t.appManifestPath=o,t.isPwa=!0;break}}try{let n=JSON.parse(await am(je.join(e,"package.json"),"utf-8")),o={...n.dependencies,...n.devDependencies};for(let s of lm)if(o[s]){t.framework=s,t.isPwa=!0;break}}catch{}return t};import{mkdir as gm,readFile as Zs,stat as hm,writeFile as ym}from"node:fs/promises";import me from"node:path";import xm from"sharp";import dm from"png-to-ico";import bt from"sharp";var Bs=e=>e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;"),wi=(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 mm(t)}},mm=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="${Bs(i)}" fill="white"/></svg>`},zs=(e,t)=>`<svg xmlns="http://www.w3.org/2000/svg" width="${e}" height="${e}"><rect width="${e}" height="${e}" fill="${Bs(t)}"/></svg>`;var Ye=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",x=await bt(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),H=i==="transparent"?{r:0,g:0,b:0,alpha:0}:await Pi(i),k=await bt({create:{width:t,height:t,channels:4,background:H}}).composite([{input:x,left:I,top:I}]).png().toBuffer();if(!p&&(o!=="square"||n==="clip")){let kt=o==="square"?"rounded":o,$a=Buffer.from(wi(kt,t,s));k=await bt(k).composite([{input:$a,blend:"dest-in"}]).png({compressionLevel:Vs(c)}).toBuffer()}else k=await bt(k).png({compressionLevel:Vs(c)}).toBuffer();return k},Pi=async e=>{let t=await bt(Buffer.from(zs(1,e))).raw().toBuffer({resolveWithObject:!0}),[r,i,n,o=255]=t.data;return{r,g:i,b:n,alpha:o/255}},Vs=e=>{let t=Math.round((100-e)/100*9);return Math.max(0,Math.min(9,t))},Js=async e=>{if(e.length===0)throw new Error("No frames provided to encodeIco");return dm(e)};import{readFile as um,writeFile as zT}from"node:fs/promises";var Ws=e=>e.map(({src:t,size:r})=>({src:t,sizes:`${r}x${r}`,type:"image/png",purpose:"any maskable"})),qs=async(e,t)=>{let r=await um(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)}
1126
+ `};var Xs=e=>`icons: [
1123
1127
  ${e.map(r=>` { src: '${r.src}', sizes: '${r.sizes}', type: '${r.type}'${r.purpose?`, purpose: '${r.purpose}'`:""} }`).join(`,
1124
1128
  `)},
1125
- ],`,cs=(e,t,r)=>`${JSON.stringify({name:e,short_name:e,start_url:"/",display:"standalone",background_color:"#ffffff",theme_color:t,icons:r},null,2)}
1126
- `;import{stat as al}from"node:fs/promises";import Br from"node:path";var ps=[".png",".jpg",".jpeg",".webp",".svg",".avif"],Ht=async e=>{if(!e)throw new Error("Source image path is required (use --path).");let t=Br.isAbsolute(e)?e:Br.resolve(process.cwd(),e),r;try{r=await al(t)}catch{throw new Error(`Source image not found: ${t}`)}if(!r.isFile())throw new Error(`Source is not a file: ${t}`);let n=Br.extname(t).toLowerCase();if(!ps.includes(n))throw new Error(`Unsupported source format '${n}'. Use one of: ${ps.join(", ")}`);return{absolutePath:t,ext:n,bytes:r.size,isVector:n===".svg"}};var zr=(e,t)=>{if(!e)return t;let r=e.split(",").map(n=>Number.parseInt(n.trim(),10)).filter(n=>Number.isFinite(n)&&n>0&&n<=1024);if(r.length===0)throw new Error(`Invalid --sizes value: '${e}'. Provide comma-separated positive integers.`);return r};var dl=async e=>{try{return await pl(e),!0}catch{return!1}},ul=async(e,t,r)=>{let n=[];for(let i of e){if(await dl(i.outPath)&&!t&&!i.alwaysWrite){n.push({path:i.outPath,bytes:i.bytes.length,skipped:!0});continue}r||(await cl(ie.dirname(i.outPath),{recursive:!0}),await ll(i.outPath,i.bytes)),n.push({path:i.outPath,bytes:i.bytes.length})}return n},Vr=async(e,t)=>{let r=await Ht(t.source),n=await ls(r.absolutePath),i=t.ogSource?await ls((await Ht(t.ogSource)).absolutePath):n,o=[],s=[];for(let d of t.icoSizes)s.push(await De({sourceBuffer:n,size:d,shape:"square",radiusPercent:t.radius,bg:t.bg,paddingPercent:t.padding,fit:t.fit,quality:t.quality,forceSquare:!0}));let a=await is(s);if(o.push({outPath:ie.join(t.outDir,"favicon.ico"),bytes:a}),t.emitIcon){let d=await De({sourceBuffer:n,size:512,shape:t.shape,radiusPercent:t.radius,bg:t.bg,paddingPercent:t.padding,fit:t.fit,quality:t.quality});o.push({outPath:ie.join(t.outDir,"icon.png"),bytes:d})}if(t.emitApple){let d=t.bg==="transparent"?"#ffffff":t.bg,h=await De({sourceBuffer:n,size:180,shape:t.shape,radiusPercent:t.radius,bg:d,paddingPercent:t.padding,fit:t.fit,quality:t.quality});o.push({outPath:ie.join(t.outDir,"apple-icon.png"),bytes:h})}if(t.emitOg){let d=await ms(i,t,!1);o.push({outPath:ie.join(t.outDir,"opengraph-image.png"),bytes:d})}if(t.emitTwitter){let d=await ms(i,t,!0);o.push({outPath:ie.join(t.outDir,"twitter-image.png"),bytes:d})}let p;if(t.pwa||t.pwaInit){let d=await Gr(e);if(t.pwa&&!d.isPwa)throw new Error("No PWA setup detected. Use --pwa-init to bootstrap a manifest, or set up next-pwa/serwist first.");let h=ie.join(e,"public"),x=[192,512],R=[];for(let $ of x){let W=await De({sourceBuffer:n,size:$,shape:t.shape,radiusPercent:t.radius,bg:t.bg,paddingPercent:t.padding,fit:t.fit,quality:t.quality}),mt=`icon-${$}.png`;o.push({outPath:ie.join(h,mt),bytes:W}),R.push({src:`/${mt}`,size:$})}let L=os(R);if(d.publicManifestPath){let $=await ss(d.publicManifestPath,L);o.push({outPath:d.publicManifestPath,bytes:Buffer.from($,"utf-8"),alwaysWrite:!0})}else if(d.appManifestPath)p=as(L);else if(t.pwaInit){let $=ie.join(h,"manifest.webmanifest"),W=cs(ie.basename(e)||"App","#000000",L);o.push({outPath:$,bytes:Buffer.from(W,"utf-8")})}}return{outputs:await ul(o,t.force,t.dryRun),pwaSnippet:p}},ms=async(e,t,r)=>{let i=r?600:630,o=Math.round(Math.min(1200,i)*(1-t.padding*2/100)),s=await De({sourceBuffer:e,size:o,shape:t.shape,radiusPercent:t.radius,bg:"transparent",paddingPercent:0,fit:t.fit,quality:t.quality}),a=t.bg==="transparent"?"#ffffff":t.bg,p=await Hr(a),f=Math.round((1200-o)/2),d=Math.round((i-o)/2);return ml({create:{width:1200,height:i,channels:4,background:p}}).composite([{input:s,left:f,top:d}]).png().toBuffer()};var ds=new Set(["aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkgrey","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","green","greenyellow","grey","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightgrey","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen"]);var fl=["square","rounded","circle","squircle"],gl=["contain","cover","clip"],us=(e,t,r,n)=>{if(!e)return r;if(!t.includes(e))throw new Error(`Invalid value for --${n}: '${e}'. Allowed: ${t.join(", ")}`);return e},Jr=(e,t,r,n,i)=>{if(e===void 0)return t;let o=Number(e);if(!Number.isFinite(o)||o<n||o>i)throw new Error(`Invalid value for --${r}: '${e}'. Must be a number between ${n}\u2013${i}.`);return o},gs=e=>{e.command("favicon").description("Generate favicon.ico (and optionally icons, OG image, PWA manifest icons)").option("--path <file>","Path to source image (PNG, JPG, JPEG, WebP, SVG, AVIF)").option("--out <dir>","Output dir (default: src/app or app)").option("--force","Overwrite existing files without prompt",!1).option("--dry-run","Show what would be written without writing",!1).option("--icon","Also emit icon.png (512\xD7512)",!1).option("--apple","Also emit apple-icon.png (180\xD7180)",!1).option("--og","Also emit opengraph-image.png (1200\xD7630)",!1).option("--og-source <file>","Use a separate image for the OG/Twitter card").option("--twitter","Also emit twitter-image.png (1200\xD7600)",!1).option("--all","Shorthand for --icon --apple --og",!1).option("--pwa","Detect PWA setup and emit manifest icons (192/512); errors if not detected",!1).option("--pwa-init","Bootstrap public/manifest.webmanifest with icons",!1).option("--shape <shape>","square | rounded | circle | squircle","square").option("--radius <percent>","Corner radius % when shape=rounded (0-50)","20").option("--bg <color>",'Background color (hex, css name, or "transparent")',"transparent").option("--padding <percent>","Padding around source content (0-30)","0").option("--fit <fit>","How source fits target: contain | cover | clip","contain").option("--sizes <list>","Comma-separated ICO sizes (default: 16,32,48)").option("--quality <n>","PNG compression 1-100 (higher = smaller file; PNG is lossless, default: 90)","90").action(async t=>{try{let r=process.cwd();l(be.cyan(`
1129
+ ],`,Ys=(e,t,r)=>`${JSON.stringify({name:e,short_name:e,start_url:"/",display:"standalone",background_color:"#ffffff",theme_color:t,icons:r},null,2)}
1130
+ `;import{stat as fm}from"node:fs/promises";import vi from"node:path";var Ks=[".png",".jpg",".jpeg",".webp",".svg",".avif"],Sr=async e=>{if(!e)throw new Error("Source image path is required (use --path).");let t=vi.isAbsolute(e)?e:vi.resolve(process.cwd(),e),r;try{r=await fm(t)}catch{throw new Error(`Source image not found: ${t}`)}if(!r.isFile())throw new Error(`Source is not a file: ${t}`);let i=vi.extname(t).toLowerCase();if(!Ks.includes(i))throw new Error(`Unsupported source format '${i}'. Use one of: ${Ks.join(", ")}`);return{absolutePath:t,ext:i,bytes:r.size,isVector:i===".svg"}};var Si=(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 wm=async e=>{try{return await hm(e),!0}catch{return!1}},Pm=async(e,t,r)=>{let i=[];for(let n of e){if(await wm(n.outPath)&&!t&&!n.alwaysWrite){i.push({path:n.outPath,bytes:n.bytes.length,skipped:!0});continue}r||(await gm(me.dirname(n.outPath),{recursive:!0}),await ym(n.outPath,n.bytes)),i.push({path:n.outPath,bytes:n.bytes.length})}return i},Ei=async(e,t)=>{let r=await Sr(t.source),i=await Zs(r.absolutePath),n=t.ogSource?await Zs((await Sr(t.ogSource)).absolutePath):i,o=[],s=[];for(let d of t.icoSizes)s.push(await Ye({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 Js(s);if(o.push({outPath:me.join(t.outDir,"favicon.ico"),bytes:c}),t.emitIcon){let d=await Ye({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:me.join(t.outDir,"icon.png"),bytes:d})}if(t.emitApple){let d=t.bg==="transparent"?"#ffffff":t.bg,f=await Ye({sourceBuffer:i,size:180,shape:t.shape,radiusPercent:t.radius,bg:d,paddingPercent:t.padding,fit:t.fit,quality:t.quality});o.push({outPath:me.join(t.outDir,"apple-icon.png"),bytes:f})}if(t.emitOg){let d=await Qs(n,t,!1);o.push({outPath:me.join(t.outDir,"opengraph-image.png"),bytes:d})}if(t.emitTwitter){let d=await Qs(n,t,!0);o.push({outPath:me.join(t.outDir,"twitter-image.png"),bytes:d})}let p;if(t.pwa||t.pwaInit){let d=await xi(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=me.join(e,"public"),x=[192,512],I=[];for(let k of x){let Z=await Ye({sourceBuffer:i,size:k,shape:t.shape,radiusPercent:t.radius,bg:t.bg,paddingPercent:t.padding,fit:t.fit,quality:t.quality}),kt=`icon-${k}.png`;o.push({outPath:me.join(f,kt),bytes:Z}),I.push({src:`/${kt}`,size:k})}let H=Ws(I);if(d.publicManifestPath){let k=await qs(d.publicManifestPath,H);o.push({outPath:d.publicManifestPath,bytes:Buffer.from(k,"utf-8"),alwaysWrite:!0})}else if(d.appManifestPath)p=Xs(H);else if(t.pwaInit){let k=me.join(f,"manifest.webmanifest"),Z=Ys(me.basename(e)||"App","#000000",H);o.push({outPath:k,bytes:Buffer.from(Z,"utf-8")})}}return{outputs:await Pm(o,t.force,t.dryRun),pwaSnippet:p}},Qs=async(e,t,r)=>{let n=r?600:630,o=Math.round(Math.min(1200,n)*(1-t.padding*2/100)),s=await Ye({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 Pi(c),u=Math.round((1200-o)/2),d=Math.round((n-o)/2);return xm({create:{width:1200,height:n,channels:4,background:p}}).composite([{input:s,left:u,top:d}]).png().toBuffer()};var ea=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 vm=["square","rounded","circle","squircle"],Sm=["contain","cover","clip"],ta=(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},Ti=(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},ia=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(Le.cyan(`
1127
1131
  \u{1F3A8} Favicon Generator
1128
- `));let n=await Qo({source:t.path}),i=await hl(r,t.out),o=us(t.shape,fl,"square","shape"),s=us(t.fit,gl,"contain","fit"),a=Jr(t.radius,20,"radius",0,50),p=Jr(t.padding,0,"padding",0,30),f=Jr(t.quality,90,"quality",1,100),d=zr(t.sizes,[16,32,48]),h=t.bg??"transparent";Pl(h);let x=t.all===!0,R={source:n.source,outDir:i,force:!!t.force,dryRun:!!t.dryRun,emitIcon:!!t.icon||x,emitApple:!!t.apple||x,emitOg:!!t.og||x,emitTwitter:!!t.twitter,ogSource:t.ogSource,pwa:!!t.pwa,pwaInit:!!t.pwaInit,shape:o,radius:a,bg:h,padding:p,fit:s,icoSizes:d,quality:f};y.start("Generating favicon assets...");let L=await Vr(r,R);y.succeed(R.dryRun?"Favicon plan ready":"Favicon assets generated"),l("");for(let $ of L.outputs){let W=Bt.relative(r,$.path);$.skipped?l(be.yellow(` \u21B7 skipped ${W} (exists; use --force to overwrite)`)):R.dryRun?l(be.dim(` \u{1F4C4} would write ${W} (${fs($.bytes)})`)):l(be.green(` \u2713 ${W} `)+be.dim(`(${fs($.bytes)})`))}L.pwaSnippet&&(l(""),l(be.cyan("Add this to your typed manifest (src/app/manifest.ts):")),l(be.dim(L.pwaSnippet))),l("")}catch(r){y.fail("Favicon generation failed");let n=r instanceof Error?r.message:String(r);v(n),process.exit(1)}})},hl=async(e,t)=>{if(t)return Bt.isAbsolute(t)?t:Bt.resolve(e,t);let r=await Ut(e);return r||(cn("Could not detect app/ or src/app/ \u2014 falling back to src/app"),Bt.join(e,"src","app"))},yl=/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/,xl=/^(?:rgb|rgba|hsl|hsla)\(\s*[\d.,%\s/]+\)$/i,Pl=e=>{if(e!=="transparent"&&!yl.test(e)&&!xl.test(e)&&!ds.has(e.toLowerCase()))throw new Error(`Invalid value for --bg: '${e}'. Use 'transparent', a hex code (e.g. #0f172a), a CSS color name, or rgb()/rgba()/hsl()/hsla().`)},fs=e=>e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(2)} MB`;import ws from"node:path";import G from"picocolors";B();B();import _l from"node:path";import{readFile as wl,writeFile as vl}from"node:fs/promises";import Sl from"node:path";var pt=async e=>{let{serviceName:t,projectPath:r}=e,n=j(t),i=Sl.join(r,"src","lib","config","app-apis.ts");try{let o=await wl(i,"utf-8");if(o.includes(`${n}:`))return;if(!o.match(/export const AppApis = \{[\s\S]*?\} as const;/))throw new Error("Could not find AppApis object in app-apis.ts");let s=` ${n}: {
1132
+ `));let i=await Hs({source:t.path}),n=await Em(r,t.out),o=ta(t.shape,vm,"square","shape"),s=ta(t.fit,Sm,"contain","fit"),c=Ti(t.radius,20,"radius",0,50),p=Ti(t.padding,0,"padding",0,30),u=Ti(t.quality,90,"quality",1,100),d=Si(t.sizes,[16,32,48]),f=t.bg??"transparent";Rm(f);let x=t.all===!0,I={source:i.source,outDir:n,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:c,bg:f,padding:p,fit:s,icoSizes:d,quality:u};y.start("Generating favicon assets...");let H=await Ei(r,I);y.succeed(I.dryRun?"Favicon plan ready":"Favicon assets generated"),m("");for(let k of H.outputs){let Z=Er.relative(r,k.path);k.skipped?m(Le.yellow(` \u21B7 skipped ${Z} (exists; use --force to overwrite)`)):I.dryRun?m(Le.dim(` \u{1F4C4} would write ${Z} (${ra(k.bytes)})`)):m(Le.green(` \u2713 ${Z} `)+Le.dim(`(${ra(k.bytes)})`))}H.pwaSnippet&&(m(""),m(Le.cyan("Add this to your typed manifest (src/app/manifest.ts):")),m(Le.dim(H.pwaSnippet))),m("")}catch(r){y.fail("Favicon generation failed");let i=r instanceof Error?r.message:String(r);E(i),process.exit(1)}})},Em=async(e,t)=>{if(t)return Er.isAbsolute(t)?t:Er.resolve(e,t);let r=await vr(e);return r||(Mi("Could not detect app/ or src/app/ \u2014 falling back to src/app"),Er.join(e,"src","app"))},Tm=/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/,Cm=/^(?:rgb|rgba|hsl|hsla)\(\s*[\d.,%\s/]+\)$/i,Rm=e=>{if(e!=="transparent"&&!Tm.test(e)&&!Cm.test(e)&&!ea.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().`)},ra=e=>e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(2)} MB`;import ca from"node:path";import V from"picocolors";q();q();import Gm from"node:path";import{readFile as bm,writeFile as Im}from"node:fs/promises";import $m from"node:path";var It=async e=>{let{serviceName:t,projectPath:r}=e,i=G(t),n=$m.join(r,"src","lib","config","app-apis.ts");try{let o=await bm(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
1133
  base: '/${t}',
1130
1134
  getAll: '/${t}',
1131
- },`;o=Je(o,s),await vl(i,o)}catch(o){throw new Error(`Failed to register API endpoints: ${o}`,{cause:o})}};import{readFile as El,writeFile as Cl}from"node:fs/promises";import Tl from"node:path";P();var Wr=async(e,t,r)=>{let n=Tl.join(e,"src","lib","config","app-paths.ts");if(!m(n))return;let i=await El(n,"utf-8"),o=j(t);if(i.includes(`${o}:`))return;let s=i.lastIndexOf("} as const;");if(s===-1)return;let a=` ${o}: '${r}',
1132
- `;i=i.slice(0,s)+a+i.slice(s),await Cl(n,i)};S();P();import zt from"node:path";var bl=e=>new RegExp(`<\\s*${e}\\b`),hs=(e,t)=>{if(bl(t).test(e))return e;let r=/^(?<indent>[ \t]*)\{children\}\s*$/m,n=e.match(r);if(!n||n.index===void 0)throw new Error("Could not locate `{children}` line in RootProvider \u2014 expected a line containing only `{children}`.");let i=n.groups?.indent??"",o=`${i} `,s=`${i}<${t}>
1135
+ },`;o=ot(o,s),await Im(n,o)}catch(o){throw new Error(`Failed to register API endpoints: ${o}`,{cause:o})}};import{readFile as km,writeFile as Nm}from"node:fs/promises";import Am from"node:path";w();var Ci=async(e,t,r)=>{let i=Am.join(e,"src","lib","config","app-paths.ts");if(!l(i))return;let n=await km(i,"utf-8"),o=G(t);if(n.includes(`${o}:`))return;let s=n.lastIndexOf("} as const;");if(s===-1)return;let c=` ${o}: '${r}',
1136
+ `;n=n.slice(0,s)+c+n.slice(s),await Nm(i,n)};P();w();import Tr from"node:path";var _m=e=>new RegExp(`<\\s*${e}\\b`),na=(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
1137
  ${o}{children}
1134
- ${i}</${t}>`;return e.replace(r,s)},ys=(e,t)=>{let r=`export * from './${t}';`;if(e.includes(r))return e;let n=e.split(`
1135
- `),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),f=n.findIndex((h,x)=>x>a&&!/^export \* from '\.\//.test(h)),d=f===-1?[]:n.slice(f);return[...p,...s,...d].join(`
1137
- `)},Rl=c.PROVIDERS,$l=c.ROOT_PROVIDER,Il=c.PROVIDERS_INDEX,xs=async(e,t={fileExists:m,readFile:u})=>{let r=zt.join(e,$l);if(t.fileExists(r))return r;let n=zt.join(e,Rl);if(!t.fileExists(n))return null;let{readdir:i}=await import("node:fs/promises"),s=(await i(n).catch(()=>[])).filter(p=>p.endsWith(".tsx")),a=null;for(let p of s){let f=zt.join(n,p),d=await t.readFile(f);if(!/\{children\}/.test(d))continue;let x=((d.split("{children}")[0]??"").match(/<[A-Z][A-Za-z0-9_]*\b/g)??[]).length;(!a||x>a.depth)&&(a={file:f,depth:x})}return a?.file??null},qr=async e=>{let{projectPath:t,componentName:r,fileBaseName:n}=e,i=await xs(t);if(i){let a=await u(i),p=a;(!/from '\.\//.test(a)||!a.includes(`{ ${r} }`))&&(p=Ve(p,`import { ${r} } from './${n}';`)),p=hs(p,r),p!==a&&await g(i,p)}let o=zt.join(t,Il),s=null;if(m(o)){let a=await u(o),p=ys(a,n);p!==a&&await g(o,p),s=o}return{rootProviderFile:i,barrelFile:s}};P();import{readFile as Nl,writeFile as kl}from"node:fs/promises";import Al from"node:path";var Xr=async(e,t)=>{let r=Al.join(e,"src","i18n","translations","en.json");if(!m(r))return;let n=await Nl(r,"utf-8"),i=JSON.parse(n);i[t]||(i[t]={title:t,description:`${t} page description`},await kl(r,`${JSON.stringify(i,null,2)}
1138
- `))};var Yr=()=>[{name:"Project setup detected",spinnerText:"Detecting project setup...",execute:async e=>{e.detection=await F(e.projectPath)}},{name:"Feature files generated",spinnerText:"Generating feature files...",execute:async e=>{await ur({name:e.featureName,outputPath:e.featurePath,createStore:e.createStore,persistStore:e.persistStore,createService:e.createService,httpClient:e.httpClient})}},{name:"API endpoints registered",spinnerText:"Registering API endpoints...",shouldSkip:e=>!e.createService,execute:async e=>{await pt({serviceName:e.featureName,projectPath:e.projectPath})}},{name:"Feature registered in rootReducer",spinnerText:"Registering feature in rootReducer...",shouldSkip:e=>!e.createStore||!e.detection.hasRedux,execute:async e=>{await ve({projectPath:e.projectPath,name:e.featureName,persist:e.persistStore,importPath:_l.join(e.basePath,e.featureName,"store")})}}];var Re=async(e,t)=>{for(let r of e)if(!r.shouldSkip?.(t)){t.spinner.start(r.spinnerText);try{await r.execute(t),t.spinner.succeed(r.name)}catch(n){throw t.spinner.fail(r.name),n}}};var Kr=()=>[{name:"Service files generated",spinnerText:"Generating service files...",execute:async e=>{await Ke({name:e.serviceName,outputPath:e.servicePath,httpClient:e.httpClient})}},{name:"API endpoints registered",spinnerText:"Registering API endpoints...",execute:async e=>{await pt({serviceName:e.serviceName,projectPath:e.projectPath})}}];import Ol from"node:path";var Zr=()=>[{name:"Slice files generated",spinnerText:"Generating slice files...",execute:async e=>{await et({name:e.sliceName,outputPath:e.slicePath,persist:e.persistSlice})}},{name:"Slice registered in rootReducer",spinnerText:"Registering slice in rootReducer...",execute:async e=>{await ve({projectPath:e.projectPath,name:e.sliceName,persist:e.persistSlice,importPath:Ol.join(e.basePath,e.sliceName)})}}];import Fl from"enquirer";var{prompt:jl}=Fl,Ps=async(e,t,r,n,i,o,s)=>{let a=[];e||a.push({type:"input",name:"featureName",message:"What is the feature name?",initial:"my-feature",validate:f=>/^[a-z0-9-]+$/.test(f)?!0:"Feature name must be lowercase and contain only alphanumeric characters and hyphens."}),t&&n===void 0&&i===void 0&&(a.push({type:"confirm",name:"createStore",message:"Generate Redux store for this feature?",initial:!0}),a.push({type:"confirm",name:"persistStore",message:"Enable persistence for this store?",initial:!1,skip(){return!this.state.answers.createStore}})),r&&r!=="none"&&o===void 0&&s===void 0&&(a.push({type:"confirm",name:"createService",message:"Generate API service for this feature?",initial:!0}),r==="both"&&a.push({type:"select",name:"selectedHttpClient",message:"Which HTTP client to use for the service?",choices:["fetch","axios"],initial:0,skip(){return!this.state.answers.createService}}));let p=a.length>0?await jl(a):{};return{featureName:e||p.featureName,hasRedux:t||!1,createStore:n===!0?!1:i!==void 0?!0:p.createStore||!1,persistStore:i==="persist"?!0:i==="no-persist"?!1:p.persistStore||!1,httpClient:r||"none",createService:o===!0?!1:s!==void 0?!0:p.createService||!1,selectedHttpClient:s||p.selectedHttpClient||(r==="both"?"fetch":r!=="none"?r:void 0)}};var vs=e=>{e.command("feature [name]").description("Generate a new feature module").option("--skip-store","Skip Redux store generation").option("--store <type>","Generate Redux store with persistence option (persist|no-persist)").option("--skip-service","Skip API service generation").option("--service <client>","Generate API service with specific HTTP client (axios|fetch)").option("--path <path>","Custom path for feature generation (default: src/features)").action(async(t,r)=>{try{let n=process.cwd();Dl(r),l(G.cyan(`
1138
+ ${n}</${t}>`;return e.replace(r,s)},oa=(e,t)=>{let r=`export * from './${t}';`;if(e.includes(r))return e;let i=e.split(`
1139
+ `),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}
1140
+ ${e.replace(/^\n+/,"")}`;let p=i.slice(0,c),u=i.findIndex((f,x)=>x>c&&!/^export \* from '\.\//.test(f)),d=u===-1?[]:i.slice(u);return[...p,...s,...d].join(`
1141
+ `)},Fm=a.PROVIDERS,Om=a.ROOT_PROVIDER,Dm=a.PROVIDERS_INDEX,sa=async(e,t={fileExists:l,readFile:g})=>{let r=Tr.join(e,Om);if(t.fileExists(r))return r;let i=Tr.join(e,Fm);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=Tr.join(i,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;(!c||x>c.depth)&&(c={file:u,depth:x})}return c?.file??null},Ri=async e=>{let{projectPath:t,componentName:r,fileBaseName:i}=e,n=await sa(t);if(n){let c=await g(n),p=c;(!/from '\.\//.test(c)||!c.includes(`{ ${r} }`))&&(p=nt(p,`import { ${r} } from './${i}';`)),p=na(p,r),p!==c&&await h(n,p)}let o=Tr.join(t,Dm),s=null;if(l(o)){let c=await g(o),p=oa(c,i);p!==c&&await h(o,p),s=o}return{rootProviderFile:n,barrelFile:s}};w();import{readFile as jm,writeFile as Lm}from"node:fs/promises";import Mm from"node:path";var bi=async(e,t)=>{let r=Mm.join(e,"src","i18n","translations","en.json");if(!l(r))return;let i=await jm(r,"utf-8"),n=JSON.parse(i);n[t]||(n[t]={title:t,description:`${t} page description`},await Lm(r,`${JSON.stringify(n,null,2)}
1142
+ `))};var Ii=()=>[{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 Wr({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 It({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 ke({projectPath:e.projectPath,name:e.featureName,persist:e.persistStore,importPath:Gm.join(e.basePath,e.featureName,"store")})}}];var Me=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 $i=()=>[{name:"Service files generated",spinnerText:"Generating service files...",execute:async e=>{await pt({name:e.serviceName,outputPath:e.servicePath,httpClient:e.httpClient})}},{name:"API endpoints registered",spinnerText:"Registering API endpoints...",execute:async e=>{await It({serviceName:e.serviceName,projectPath:e.projectPath})}}];import Hm from"node:path";var ki=()=>[{name:"Slice files generated",spinnerText:"Generating slice files...",execute:async e=>{await dt({name:e.sliceName,outputPath:e.slicePath,persist:e.persistSlice})}},{name:"Slice registered in rootReducer",spinnerText:"Registering slice in rootReducer...",execute:async e=>{await ke({projectPath:e.projectPath,name:e.sliceName,persist:e.persistSlice,importPath:Hm.join(e.basePath,e.sliceName)})}}];import Um from"enquirer";var{prompt:Bm}=Um,aa=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 Bm(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 pa=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();zm(r),m(V.cyan(`
1139
1143
  \u{1F3AF} Feature Generator
1140
- `));let i=Yr();y.start("Detecting project setup...");let{detectProjectSetup:o}=await Promise.resolve().then(()=>(B(),Ye)),s=await o(n);y.succeed("Project setup detected"),l(G.dim(` Redux: ${s.hasRedux?"\u2713":"\u2717"}`)),l(G.dim(` HTTP Client: ${s.httpClient}`)),l(G.dim(` i18n: ${s.hasI18n?"\u2713":"\u2717"}
1141
- `));let a=await Ps(t,s.hasRedux,s.httpClient,r.skipStore,r.store,r.skipService,r.service);H(a.featureName,"feature name"),r.path&&re(r.path,"path");let p=r.path||ws.join("src","features"),f=xt(n,p,a.featureName);await ue(n,a.featureName,p)&&(v(`Feature '${a.featureName}' already exists at ${p}!`),process.exit(1)),await Re(i.slice(1),{projectPath:n,spinner:y,featureName:a.featureName,basePath:p,featurePath:f,createStore:a.createStore,persistStore:a.persistStore,createService:a.createService,httpClient:a.selectedHttpClient,detection:s}),Ll(a,p)}catch(n){y.fail("Feature generation failed"),v(`${n}`),process.exit(1)}})},Dl=e=>{e.store&&!["persist","no-persist"].includes(e.store)&&(v("Invalid --store option. Use: persist or no-persist"),process.exit(1)),e.service&&!["axios","fetch"].includes(e.service)&&(v("Invalid --service option. Use: axios or fetch"),process.exit(1)),e.skipStore&&e.store&&(v("Cannot use --skip-store and --store together"),process.exit(1)),e.skipService&&e.service&&(v("Cannot use --skip-service and --service together"),process.exit(1))},Ll=(e,t)=>{let r=ws.join(t,e.featureName);l(G.green(`
1144
+ `));let n=Ii();y.start("Detecting project setup...");let{detectProjectSetup:o}=await Promise.resolve().then(()=>(q(),ct)),s=await o(i);y.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"}
1145
+ `));let c=await aa(t,s.hasRedux,s.httpClient,r.skipStore,r.store,r.skipService,r.service);W(c.featureName,"feature name"),r.path&&pe(r.path,"path");let p=r.path||ca.join("src","features"),u=Gt(i,p,c.featureName);await Se(i,c.featureName,p)&&(E(`Feature '${c.featureName}' already exists at ${p}!`),process.exit(1)),await Me(n.slice(1),{projectPath:i,spinner:y,featureName:c.featureName,basePath:p,featurePath:u,createStore:c.createStore,persistStore:c.persistStore,createService:c.createService,httpClient:c.selectedHttpClient,detection:s}),Vm(c,p)}catch(i){y.fail("Feature generation failed"),E(`${i}`),process.exit(1)}})},zm=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))},Vm=(e,t)=>{let r=ca.join(t,e.featureName);m(V.green(`
1142
1146
  \u2728 Feature '${e.featureName}' created successfully!
1143
- `)),l(G.dim("Generated files:")),l(G.dim(` \u{1F4C2} ${r}/`)),l(G.dim(" \u251C\u2500\u2500 components/")),l(G.dim(" \u251C\u2500\u2500 hooks/")),l(G.dim(" \u251C\u2500\u2500 types/")),e.createStore&&l(G.dim(" \u251C\u2500\u2500 store/")),e.createService&&l(G.dim(" \u251C\u2500\u2500 services/")),l(G.dim(` \u2514\u2500\u2500 index.ts
1144
- `)),l(G.cyan("Next steps:"));let n=t.replace(/^src\//,"@/");l(G.dim(` 1. Import and use the feature: import { ${e.featureName} } from '${n}/${e.featureName}'`)),e.createStore&&l(G.dim(` 2. Customize your Redux slice in: ${r}/store/`)),e.createService&&l(G.dim(` 3. Add API methods in: ${r}/services/${e.featureName}.service.ts`)),l("")};import Qr from"node:path";import Le from"picocolors";B();import Ml from"enquirer";var{prompt:Gl}=Ml,Ss=async e=>e?{hookName:e}:await Gl({type:"input",name:"hookName",message:'Hook name (kebab-case, without "use" prefix):',validate:r=>r?/^[a-z][a-z0-9-]*$/.test(r)?!0:"Use lowercase letters, numbers, and hyphens only":"Hook name is required"});var Es=e=>{e.command("hook [name]").description("Generate a custom React hook").option("--client","Add 'use client' directive (default: true)",!0).option("--feature <path>","Generate in feature directory (e.g., src/features/auth)").option("--test","Also generate a sibling test file").option("--no-test","Skip test file generation").action(async(t,r)=>{try{let n=process.cwd();l(Le.cyan(`
1147
+ `)),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
1148
+ `)),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 Ni from"node:path";import Ke from"picocolors";q();import Jm from"enquirer";var{prompt:Wm}=Jm,la=async e=>e?{hookName:e}:await Wm({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 ma=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(Ke.cyan(`
1145
1149
  \u{1FA9D} Hook Generator
1146
- `));let i=await F(n),o=await Ss(t);H(o.hookName,"hook name"),r.feature&&re(r.feature,"feature path");let a=`use${I(o.hookName)}`,p=Ul(r,i.hasTests);y.start("Generating hook..."),await gr({name:o.hookName,projectPath:n,isClient:r.client??!0,featurePath:r.feature}),y.succeed("Hook generated");let f=r.feature?Qr.join(n,r.feature,"hooks",`${a}.ts`):Qr.join(n,"src/hooks",`${a}.ts`),d=null;p&&(y.start("Generating test..."),d=await ae({projectPath:n,sourceFile:f,kind:"hook",symbolName:a,hookUsesStore:i.hasRedux&&!!r.feature}),y.succeed("Test generated"));let h=r.feature?`${r.feature}/hooks/${a}.ts`:`src/hooks/${a}.ts`;l(Le.green(`
1147
- \u2728 Hook '${a}' created successfully!
1148
- `)),l(Le.dim(` \u{1F4C4} ${h}`)),d&&l(Le.dim(` \u{1F9EA} ${Qr.relative(n,d)}`)),l(""),l(Le.cyan("Usage:"));let x=r.feature?`${r.feature.replace(/^src\//,"@/")}/hooks/${a}`:`@/hooks/${a}`;l(Le.dim(` import { ${a} } from '${x}';`)),l("")}catch(n){y.fail("Hook generation failed"),v(`${n}`),process.exit(1)}})},Ul=(e,t)=>e.test===!1?!1:e.test===!0?!0:t;import Vt from"picocolors";B();var Cs=e=>{e.command("layout <segment>").description("Generate a nested layout.tsx (locale-aware when i18n is detected)").option("--group","Treat the segment as a route group (wraps it in parens)").option("--at <path>","Place the layout under this nested path (kebab-case, slash-separated)").option("--no-locale","Skip the locale wrapper even if i18n is detected").action(async(t,r)=>{try{let n=process.cwd();l(Vt.cyan(`
1150
+ `));let n=await M(i),o=await la(t);W(o.hookName,"hook name"),r.feature&&pe(r.feature,"feature path");let c=`use${N(o.hookName)}`,p=qm(r,n.hasTests);y.start("Generating hook..."),await Xr({name:o.hookName,projectPath:i,isClient:r.client??!0,featurePath:r.feature}),y.succeed("Hook generated");let u=r.feature?Ni.join(i,r.feature,"hooks",`${c}.ts`):Ni.join(i,"src/hooks",`${c}.ts`),d=null;p&&(y.start("Generating test..."),d=await ge({projectPath:i,sourceFile:u,kind:"hook",symbolName:c,hookUsesStore:n.hasRedux&&!!r.feature}),y.succeed("Test generated"));let f=r.feature?`${r.feature}/hooks/${c}.ts`:`src/hooks/${c}.ts`;m(Ke.green(`
1151
+ \u2728 Hook '${c}' created successfully!
1152
+ `)),m(Ke.dim(` \u{1F4C4} ${f}`)),d&&m(Ke.dim(` \u{1F9EA} ${Ni.relative(i,d)}`)),m(""),m(Ke.cyan("Usage:"));let x=r.feature?`${r.feature.replace(/^src\//,"@/")}/hooks/${c}`:`@/hooks/${c}`;m(Ke.dim(` import { ${c} } from '${x}';`)),m("")}catch(i){y.fail("Hook generation failed"),E(`${i}`),process.exit(1)}})},qm=(e,t)=>e.test===!1?!1:e.test===!0?!0:t;import Cr from"picocolors";q();var da=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(Cr.cyan(`
1149
1153
  \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 hr({segment:t,at:r.at,projectPath:n,hasI18n:o,withGroup:!!r.group});y.succeed("Layout generated"),l(Vt.green(`
1154
+ `)),y.start("Detecting project setup...");let n=await M(i);y.succeed("Project setup detected");let o=n.hasI18n&&r.locale!==!1;m(Cr.dim(` i18n: ${o?"\u2713":"\u2717"}
1155
+ `)),y.start("Generating layout...");let s=await Yr({segment:t,at:r.at,projectPath:i,hasI18n:o,withGroup:!!r.group});y.succeed("Layout generated"),m(Cr.green(`
1152
1156
  \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 Hl from"enquirer";var{prompt:Bl}=Hl,Ts=async(e,t={})=>{let r=[];e||r.push({type:"input",name:"code",message:"Locale code (e.g., es, fr, de):",validate:i=>i?/^[a-z]{2}(-[A-Z]{2})?$/.test(i)?!0:"Use format: xx or xx-XX (e.g., es, pt-BR)":"Locale code is required"}),r.push({type:"input",name:"name",message:"Language name (e.g., Spanish, French):",validate:i=>i?!0:"Language name is required"},{type:"input",name:"country",message:"Country (e.g., Spain, France):",validate:i=>i?!0:"Country is required"},{type:"input",name:"flag",message:"Flag emoji (e.g., \u{1F1EA}\u{1F1F8}, \u{1F1EB}\u{1F1F7}):",validate:i=>i?!0:"Flag emoji is required"}),t.copyTranslations===void 0&&r.push({type:"confirm",name:"copyTranslations",message:"Copy translations from English? (No = empty values)",initial:!1});let n=await Bl(r);return{code:e??n.code,name:n.name,country:n.country,flag:n.flag,copyTranslations:t.copyTranslations??n.copyTranslations??!1}};var bs=e=>{e.command("locale [code]").description("Add a new locale/language").option("--copy-translations","Copy translations from English instead of empty values").action(async(t,r)=>{try{let n=process.cwd();l(oe.cyan(`
1157
+ `)),m(Cr.dim(` \u{1F4C4} ${s.displayPath}`)),m("")}catch(i){y.fail("Layout generation failed"),E(`${i instanceof Error?i.message:i}`),process.exit(1)}})};import de from"picocolors";w();q();import Xm from"enquirer";var{prompt:Ym}=Xm,ua=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 Ym(r);return{code:e??i.code,name:i.name,country:i.country,flag:i.flag,copyTranslations:t.copyTranslations??i.copyTranslations??!1}};var fa=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(de.cyan(`
1154
1158
  \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(`
1159
+ `)),y.start("Detecting project setup...");let n=await M(i);y.succeed("Project setup detected"),n.hasI18n||(y.fail("i18n is not set up in this project"),E("Please set up internationalization first"),m(de.dim(`
1156
1160
  Run: npx @teispace/next-maker setup --i18n
1157
- `)),process.exit(1));let o=await Ts(t,{copyTranslations:r.copyTranslations});H(o.code,"locale code");let s=xt(n,"src","i18n","translations",`${o.code}.json`);m(s)&&(v(`Locale '${o.code}' already exists!`),process.exit(1)),y.start("Adding locale..."),await yr({...o,projectPath:n}),y.succeed("Locale added"),l(oe.green(`
1161
+ `)),process.exit(1));let o=await ua(t,{copyTranslations:r.copyTranslations});W(o.code,"locale code");let s=Gt(i,"src","i18n","translations",`${o.code}.json`);l(s)&&(E(`Locale '${o.code}' already exists!`),process.exit(1)),y.start("Adding locale..."),await Kr({...o,projectPath:i}),y.succeed("Locale added"),m(de.green(`
1158
1162
  \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 $s from"node:path";import Z from"picocolors";B();import zl from"enquirer";var{prompt:Vl}=zl,Rs=async(e,t={})=>{let r=[];e||r.push({type:"input",name:"pageName",message:"Page name (kebab-case):",validate:i=>i?/^[a-z][a-z0-9-]*$/.test(i)?!0:"Use lowercase letters, numbers, and hyphens only":"Page name is required"}),t.loading===void 0&&r.push({type:"confirm",name:"withLoading",message:"Generate loading.tsx?",initial:!0}),t.error===void 0&&r.push({type:"confirm",name:"withError",message:"Generate error.tsx?",initial:!0});let n=r.length>0?await Vl(r):{};return{pageName:e??n.pageName,withLoading:t.loading??n.withLoading??!0,withError:t.error??n.withError??!0}};var Is=e=>{e.command("page [name]").description("Generate a new page/route").option("--dynamic <param>","Create dynamic route with parameter (e.g., id)").option("--loading","Generate loading.tsx").option("--error","Generate error.tsx").action(async(t,r)=>{try{let n=process.cwd();l(Z.cyan(`
1163
+ `)),m(de.dim("Updated files:")),m(de.dim(` \u{1F4C4} src/i18n/translations/${o.code}.json`)),m(de.dim(" \u{1F4DD} src/types/i18n.ts (SupportedLocale type)")),m(de.dim(" \u{1F4DD} src/lib/config/app-locales.ts")),m(""),m(de.cyan("Next steps:")),m(de.dim(` 1. Translate: src/i18n/translations/${o.code}.json`)),m(de.dim(` 2. Visit: http://localhost:3000/${o.code}`)),m("")}catch(i){y.fail("Locale generation failed"),E(`${i}`),process.exit(1)}})};import ha from"node:path";import ne from"picocolors";q();import Km from"enquirer";var{prompt:Zm}=Km,ga=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 Zm(r):{};return{pageName:e??i.pageName,withLoading:t.loading??i.withLoading??!0,withError:t.error??i.withError??!0}};var ya=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(ne.cyan(`
1160
1164
  \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 Rs(t,{loading:r.loading,error:r.error}),s=o.pageName;H(s,"page name"),r.dynamic&&H(r.dynamic,"dynamic param");let a=I(s),p=i.hasI18n?"src/app/[locale]":"src/app";await ue(n,s,p)&&(v(`Page '${s}' already exists at ${p}/${s}!`),process.exit(1)),y.start("Generating page files..."),await Pr({name:s,projectPath:n,hasI18n:i.hasI18n,dynamic:r.dynamic,withLoading:r.loading??o.withLoading,withError:r.error??o.withError}),y.succeed("Page files generated"),y.start("Registering route...");let d=r.dynamic?`/${s}/[${r.dynamic}]`:`/${s}`;await Wr(n,s,d),y.succeed("Route registered"),i.hasI18n&&(y.start("Adding translation namespace..."),await Xr(n,a),y.succeed("Translation namespace added"));let h=r.dynamic?$s.join(p,s,`[${r.dynamic}]`):$s.join(p,s);l(Z.green(`
1165
+ `)),y.start("Detecting project setup...");let n=await M(i);y.succeed("Project setup detected"),m(ne.dim(` i18n: ${n.hasI18n?"\u2713":"\u2717"}
1166
+ `));let o=await ga(t,{loading:r.loading,error:r.error}),s=o.pageName;W(s,"page name"),r.dynamic&&W(r.dynamic,"dynamic param");let c=N(s),p=n.hasI18n?"src/app/[locale]":"src/app";await Se(i,s,p)&&(E(`Page '${s}' already exists at ${p}/${s}!`),process.exit(1)),y.start("Generating page files..."),await Qr({name:s,projectPath:i,hasI18n:n.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 Ci(i,s,d),y.succeed("Route registered"),n.hasI18n&&(y.start("Adding translation namespace..."),await bi(i,c),y.succeed("Translation namespace added"));let f=r.dynamic?ha.join(p,s,`[${r.dynamic}]`):ha.join(p,s);m(ne.green(`
1163
1167
  \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 en from"node:path";import he from"picocolors";var Ns=e=>{e.command("provider <name>").description("Generate a context provider in src/providers/ and wire it into RootProvider").action(async t=>{try{let r=process.cwd();l(he.cyan(`
1168
+ `)),m(ne.dim("Generated files:")),m(ne.dim(` \u{1F4C2} ${f}/`)),m(ne.dim(" \u251C\u2500\u2500 page.tsx")),(r.loading??o.withLoading)&&m(ne.dim(" \u251C\u2500\u2500 loading.tsx")),(r.error??o.withError)&&m(ne.dim(" \u2514\u2500\u2500 error.tsx")),m(""),n.hasI18n&&(m(ne.cyan("Next steps:")),m(ne.dim(` 1. Add translations in: src/i18n/translations/en.json \u2192 "${c}"`)),m(ne.dim(` 2. Visit: http://localhost:3000/${s}`)),m(""))}catch(i){y.fail("Page generation failed"),E(`${i}`),process.exit(1)}})};import Ai from"node:path";import Re from"picocolors";var xa=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(Re.cyan(`
1165
1169
  \u{1F50C} Provider Generator
1166
- `)),y.start("Generating provider...");let{componentName:n,fileBaseName:i,providerFile:o}=await vr({name:t,projectPath:r});y.succeed("Provider generated"),y.start("Registering provider in RootProvider and barrel...");let{rootProviderFile:s,barrelFile:a}=await qr({projectPath:r,componentName:n,fileBaseName:i});y.succeed("Provider registered"),l(he.green(`
1167
- \u2728 ${n} created!
1168
- `)),l(he.dim("Generated files:")),l(he.dim(` \u{1F4C4} ${en.relative(r,o)}`)),s?l(he.dim(` \u270F\uFE0F ${en.relative(r,s)} \u2014 wrapped {children}`)):(l(he.yellow(`
1169
- \u26A0\uFE0F Could not locate a RootProvider file. Wire the new provider manually:`)),l(he.dim(` <${n}>{children}</${n}>`))),a&&l(he.dim(` \u270F\uFE0F ${en.relative(r,a)} \u2014 added re-export`)),l("")}catch(r){y.fail("Provider generation failed"),v(`${r instanceof Error?r.message:r}`),process.exit(1)}})};import Jl from"enquirer";import z from"picocolors";var{prompt:Wl}=Jl,ql=e=>{let t=[];for(let r of e.filesRemoved)t.push(` ${z.red("-")} delete: ${r}`);for(let r of e.blocksStripped)t.push(` ${z.red("-")} strip block: ${r.description} ${z.dim(`(${r.file})`)}`);for(let r of e.scriptsRemoved)t.push(` ${z.red("-")} remove script: ${r}`);for(let r of e.packagesUninstalled)t.push(` ${z.red("-")} uninstall: ${r}`);for(let r of e.manualCleanup)t.push(` ${z.yellow("?")} manual cleanup: ${r.description} ${z.dim(`(${r.file})`)}`);return t},Xl=e=>e.filesRemoved.length===0&&e.blocksStripped.length===0&&e.scriptsRemoved.length===0&&e.packagesUninstalled.length===0&&e.manualCleanup.length===0,ks=e=>{e.command("remove <feature>").alias("uninstall").description("Reverse a feature install (uses the feature manifest)").option("-y, --yes","Skip confirmation prompt").option("--dry-run","Show what would change without writing").action(async(t,r)=>{try{let n=process.cwd(),i=Uo(t);if(!i)throw new Error(`Unknown feature "${t}". Valid: ${Ce.map(p=>p.id).join(", ")}.`);if(l(z.cyan(`
1170
- \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"),Xl(s)){l(z.yellow(`
1170
+ `)),y.start("Generating provider...");let{componentName:i,fileBaseName:n,providerFile:o}=await ti({name:t,projectPath:r});y.succeed("Provider generated"),y.start("Registering provider in RootProvider and barrel...");let{rootProviderFile:s,barrelFile:c}=await Ri({projectPath:r,componentName:i,fileBaseName:n});y.succeed("Provider registered"),m(Re.green(`
1171
+ \u2728 ${i} created!
1172
+ `)),m(Re.dim("Generated files:")),m(Re.dim(` \u{1F4C4} ${Ai.relative(r,o)}`)),s?m(Re.dim(` \u270F\uFE0F ${Ai.relative(r,s)} \u2014 wrapped {children}`)):(m(Re.yellow(`
1173
+ \u26A0\uFE0F Could not locate a RootProvider file. Wire the new provider manually:`)),m(Re.dim(` <${i}>{children}</${i}>`))),c&&m(Re.dim(` \u270F\uFE0F ${Ai.relative(r,c)} \u2014 added re-export`)),m("")}catch(r){y.fail("Provider generation failed"),E(`${r instanceof Error?r.message:r}`),process.exit(1)}})};import Qm from"enquirer";import X from"picocolors";var{prompt:ed}=Qm,td=e=>{let t=[];for(let r of e.filesRemoved)t.push(` ${X.red("-")} delete: ${r}`);for(let r of e.blocksStripped)t.push(` ${X.red("-")} strip block: ${r.description} ${X.dim(`(${r.file})`)}`);for(let r of e.scriptsRemoved)t.push(` ${X.red("-")} remove script: ${r}`);for(let r of e.packagesUninstalled)t.push(` ${X.red("-")} uninstall: ${r}`);for(let r of e.manualCleanup)t.push(` ${X.yellow("?")} manual cleanup: ${r.description} ${X.dim(`(${r.file})`)}`);return t},rd=e=>e.filesRemoved.length===0&&e.blocksStripped.length===0&&e.scriptsRemoved.length===0&&e.packagesUninstalled.length===0&&e.manualCleanup.length===0,wa=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=Is(t);if(!n)throw new Error(`Unknown feature "${t}". Valid: ${De.map(p=>p.id).join(", ")}.`);if(m(X.cyan(`
1174
+ \u{1F5D1} Remove ${n.name}
1175
+ `)),!(await qe(n,i)).installed){m(X.dim(`${n.name} is not installed \u2014 nothing to remove.`));return}y.start("Computing changes...");let s=await Pr(n,i,{dryRun:!0});if(y.succeed("Computed plan"),rd(s)){m(X.yellow(`
1172
1176
  \u26A0\uFE0F Manifest had no removable artifacts. Nothing to do.
1173
- `));return}l(z.bold(`
1177
+ `));return}m(X.bold(`
1174
1178
  Planned changes:
1175
- `));for(let p of ql(s))l(p);if(l(""),r.dryRun){l(z.dim(`--dry-run set \u2014 exiting without writing.
1176
- `));return}if(!r.yes){let{confirm:p}=await Wl({type:"confirm",name:"confirm",message:`Apply the changes above to remove ${i.name}?`,initial:!1});if(!p){l(z.yellow(`
1179
+ `));for(let p of td(s))m(p);if(m(""),r.dryRun){m(X.dim(`--dry-run set \u2014 exiting without writing.
1180
+ `));return}if(!r.yes){let{confirm:p}=await ed({type:"confirm",name:"confirm",message:`Apply the changes above to remove ${n.name}?`,initial:!1});if(!p){m(X.yellow(`
1177
1181
  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 Ql}from"node:fs";import{mkdir as em}from"node:fs/promises";import lt from"node:path";import Q from"picocolors";B();import{readFile as Yl,writeFile as Kl}from"node:fs/promises";import Zl from"node:path";var As=async(e,t)=>{let r=j(t),n=Zl.join(e,"src","lib","config","app-apis.ts");try{let i=await Yl(n,"utf-8");if(i.includes(`${r}:`))return;if(!i.match(/export const AppApis = \{[\s\S]*?\} as const;/))throw new Error("Could not find AppApis object in app-apis.ts");let o=ai({camelName:r,kebabName:t});i=Je(i,o),await Kl(n,i)}catch(i){throw new Error(`Failed to register CRUD API endpoints: ${i}`,{cause:i})}};import _s from"enquirer";var Os=async(e,t,r,n)=>{let i=e||(await _s.prompt({type:"input",name:"serviceName",message:"Service name (kebab-case):",validate:s=>s?/^[a-z0-9-]+$/.test(s)?!0:"Service name must be lowercase with hyphens only":"Service name is required"})).serviceName,o;return t!==void 0?o="axios":r!==void 0?o="fetch":n==="axios"?o="axios":n==="fetch"?o="fetch":n==="both"?o=(await _s.prompt({type:"select",name:"httpClient",message:"Choose HTTP client:",choices:["axios","fetch"]})).httpClient:o="axios",{serviceName:i,httpClient:o}};var Fs=e=>{e.command("service [name]").description("Generate an API service").option("--path <path>","Custom path for service generation (default: create new feature)").option("--axios","Use Axios HTTP client").option("--fetch","Use Fetch HTTP client").option("--crud","Generate full CRUD service (getAll, getById, create, update, delete)").action(async(t,r)=>{try{let n=process.cwd();r.axios&&r.fetch&&(v("Cannot use --axios and --fetch together"),process.exit(1)),l(Q.cyan(`
1182
+ `));return}}y.start(`Removing ${n.name}...`);let c;if(n.remove?(await n.remove(i),c=s):c=await Pr(n,i),y.succeed(`${n.name} removed`),m(X.green(`
1183
+ \u2713 ${n.name} removed.`)),c.manualCleanup.length>0){m(X.yellow(`
1184
+ \u26A0\uFE0F Manual cleanup still required:`));for(let p of c.manualCleanup)m(` - ${p.description} (${p.file})`)}m("")}catch(i){y.fail("Remove failed"),E(`${i instanceof Error?i.message:i}`),process.exit(1)}})};import{existsSync as sd}from"node:fs";import{mkdir as ad}from"node:fs/promises";import $t from"node:path";import oe from"picocolors";q();import{readFile as id,writeFile as nd}from"node:fs/promises";import od from"node:path";var Pa=async(e,t)=>{let r=G(t),i=od.join(e,"src","lib","config","app-apis.ts");try{let n=await id(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=Mn({camelName:r,kebabName:t});n=ot(n,o),await nd(i,n)}catch(n){throw new Error(`Failed to register CRUD API endpoints: ${n}`,{cause:n})}};import va from"enquirer";var Sa=async(e,t,r,i)=>{let n=e||(await va.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 va.prompt({type:"select",name:"httpClient",message:"Choose HTTP client:",choices:["axios","fetch"]})).httpClient:o="axios",{serviceName:n,httpClient:o}};var Ea=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(oe.cyan(`
1181
1185
  \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(`
1186
+ `)),y.start("Detecting project setup...");let n=await M(i);y.succeed("Project setup detected"),n.httpClient==="none"&&(y.fail("No HTTP client is setup in this project"),E("Please setup either AxiosClient or FetchClient first"),m(oe.dim(`
1183
1187
  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 Os(t,r.axios,r.fetch,i.httpClient);H(s.serviceName,"service name"),r.path&&re(r.path,"path");let{basePath:a,servicePath:p}=tm(n,s.serviceName,r.path);Ql(p)||await em(p,{recursive:!0}),Pt(n,a,`${s.serviceName}.service.ts`)&&(v(`Service '${s.serviceName}' already exists at ${a}!`),process.exit(1)),r.crud?(y.start("Generating CRUD service files..."),await dr({name:s.serviceName,outputPath:p,httpClient:s.httpClient}),y.succeed("CRUD service files generated"),y.start("Registering CRUD API endpoints..."),await As(n,s.serviceName),y.succeed("CRUD API endpoints registered")):await Re(Kr(),{projectPath:n,spinner:y,serviceName:s.serviceName,servicePath:p,httpClient:s.httpClient}),rm(s,a,!!r.crud)}catch(n){y.fail("Service generation failed"),v(`${n}`),process.exit(1)}})},tm=(e,t,r)=>{let n;if(r){let i=r.replace(/^src\//,"");if(i.startsWith("features/")){let o=i.split("/")[1];n=lt.join("src","features",o,"services")}else n=lt.join("src",i)}else n=lt.join("src","features",t,"services");return{basePath:n,servicePath:lt.join(e,n)}},rm=(e,t,r=!1)=>{let n=lt.join(t,`${e.serviceName}.service.ts`);l(Q.green(`
1188
+ `)),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(oe.dim(` HTTP Clients: ${o.join(", ")}
1189
+ `));let s=await Sa(t,r.axios,r.fetch,n.httpClient);W(s.serviceName,"service name"),r.path&&pe(r.path,"path");let{basePath:c,servicePath:p}=cd(i,s.serviceName,r.path);sd(p)||await ad(p,{recursive:!0}),Ht(i,c,`${s.serviceName}.service.ts`)&&(E(`Service '${s.serviceName}' already exists at ${c}!`),process.exit(1)),r.crud?(y.start("Generating CRUD service files..."),await Jr({name:s.serviceName,outputPath:p,httpClient:s.httpClient}),y.succeed("CRUD service files generated"),y.start("Registering CRUD API endpoints..."),await Pa(i,s.serviceName),y.succeed("CRUD API endpoints registered")):await Me($i(),{projectPath:i,spinner:y,serviceName:s.serviceName,servicePath:p,httpClient:s.httpClient}),pd(s,c,!!r.crud)}catch(i){y.fail("Service generation failed"),E(`${i}`),process.exit(1)}})},cd=(e,t,r)=>{let i;if(r){let n=r.replace(/^src\//,"");if(n.startsWith("features/")){let o=n.split("/")[1];i=$t.join("src","features",o,"services")}else i=$t.join("src",n)}else i=$t.join("src","features",t,"services");return{basePath:i,servicePath:$t.join(e,i)}},pd=(e,t,r=!1)=>{let i=$t.join(t,`${e.serviceName}.service.ts`);m(oe.green(`
1186
1190
  \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 nm from"enquirer";import tn from"picocolors";var{prompt:im}=nm,rn=[{key:"http-client",label:"HTTP Client (Axios/Fetch)",flag:"httpClient",handler:kt},{key:"dark-theme",label:"Dark Theme",flag:"darkTheme",handler:$t},{key:"redux",label:"Redux Toolkit",flag:"redux",handler:Ft},{key:"ws",label:"WebSocket Client (requires Redux)",flag:"ws",handler:Mt},{key:"i18n",label:"Internationalization (next-intl)",flag:"i18n",handler:_t},{key:"tests",label:"Testing (Vitest + RTL)",flag:"tests",handler:Dt},{key:"react-compiler",label:"React Compiler",flag:"reactCompiler",handler:Ot},{key:"bundle-analyzer",label:"Bundle Analyzer",flag:"bundleAnalyzer",handler:Ct},{key:"security-headers",label:"Security Headers",flag:"securityHeaders",handler:jt},{key:"validate-scripts",label:"Validation Scripts",flag:"validateScripts",handler:Lt},{key:"commitizen",label:"Commitizen",flag:"commitizen",handler:Tt}],om=async(e,t={})=>{let r=t.promptFn??im,n=t.cwd??(()=>process.cwd());l(tn.cyan(`
1191
+ `)),m(oe.dim("Generated files:")),m(oe.dim(` \u{1F4C4} ${i}
1192
+ `)),m(oe.cyan("Next steps:"));let n=t.replace(/^src\//,"@/");m(oe.dim(` 1. Import service: import { ${e.serviceName}Service } from '${n}/${e.serviceName}.service'`)),r?(m(oe.dim(" 2. Available methods: getAll, getById, create, update, delete")),m(oe.dim(" 3. Update DTO types in the service file"))):m(oe.dim(` 2. Use in component: const data = await ${e.serviceName}Service.getAll()`)),m("")};import ld from"enquirer";import _i from"picocolors";var{prompt:md}=ld,Fi=[{key:"http-client",label:"HTTP Client (Axios/Fetch)",flag:"httpClient",handler:or},{key:"dark-theme",label:"Dark Theme",flag:"darkTheme",handler:er},{key:"redux",label:"Redux Toolkit",flag:"redux",handler:gr},{key:"ws",label:"WebSocket Client (requires Redux)",flag:"ws",handler:wr},{key:"i18n",label:"Internationalization (next-intl)",flag:"i18n",handler:mr},{key:"tests",label:"Testing (Vitest + RTL)",flag:"tests",handler:yr},{key:"react-compiler",label:"React Compiler",flag:"reactCompiler",handler:ur},{key:"bundle-analyzer",label:"Bundle Analyzer",flag:"bundleAnalyzer",handler:Wt},{key:"security-headers",label:"Security Headers",flag:"securityHeaders",handler:hr},{key:"validate-scripts",label:"Validation Scripts",flag:"validateScripts",handler:xr},{key:"commitizen",label:"Commitizen",flag:"commitizen",handler:Xt}],dd=async(e,t={})=>{let r=t.promptFn??md,i=t.cwd??(()=>process.cwd());m(_i.cyan(`
1189
1193
  \u{1F527} Setup Wizard
1190
- `));let i=rn.filter(p=>!!e[p.flag]);if(i.length>0){for(let p of i)await p.handler(n());return i.length===1?i[0].key:"multiple"}let s=(await r([{type:"select",name:"feature",message:"What would you like to setup?",choices:[...rn.map(p=>({name:p.key,message:p.label})),{name:"cancel",message:"Cancel"}]}])).feature;if(s==="cancel")return l(tn.yellow("Setup cancelled.")),null;let a=rn.find(p=>p.key===s);return a?(await a.handler(n()),a.key):(l(tn.yellow(`
1191
- \u26A0\uFE0F ${s} setup is not implemented yet.`)),null)},js=e=>{e.command("setup").description("Setup features in an existing Next.js project").option("--http-client","Setup HTTP client (axios|fetch)").option("--dark-theme","Setup Dark Theme (Tailwind + @teispace/next-themes)").option("--redux","Setup Redux Toolkit").option("--ws","Setup WebSocket client (socket.io-client + Redux bridge; requires --redux)").option("--i18n","Setup next-intl for internationalization").option("--tests","Setup testing (Vitest + React Testing Library)").option("--react-compiler","Enable the React Compiler").option("--bundle-analyzer","Add @next/bundle-analyzer").option("--security-headers","Add hardened HTTP headers to next.config.ts").option("--validate-scripts","Add scripts/sync-env.ts, scripts/check-deprecated.ts, and the validate chain").option("--commitizen","Add Commitizen with the conventional-changelog adapter").action(async t=>{try{await om(t)}catch(r){y.fail("Setup failed"),v(`${r}`),process.exit(1)}})};import{existsSync as cm}from"node:fs";import{mkdir as pm}from"node:fs/promises";import ye from"node:path";import V from"picocolors";B();import sm from"enquirer";var{prompt:am}=sm,Ds=async(e,t)=>{let r=[];e||r.push({type:"input",name:"sliceName",message:"What is the slice name?",initial:"my-slice",validate:i=>/^[a-z0-9-]+$/.test(i)?!0:"Slice name must be lowercase and contain only alphanumeric characters and hyphens."}),t===void 0&&r.push({type:"confirm",name:"persistSlice",message:"Enable persistence for this slice?",initial:!1});let n=r.length>0?await am(r):{};return{sliceName:e||n.sliceName,persistSlice:t===void 0?n.persistSlice||!1:t}};var Ls=e=>{e.command("slice [name]").description("Generate a Redux slice").option("--path <path>","Custom path for slice generation (default: create new feature)").option("--persist","Enable persistence for this slice").option("--no-persist","Disable persistence for this slice").option("--test","Also generate a sibling test file").option("--no-test","Skip test file generation").action(async(t,r)=>{try{let n=process.cwd();l(V.cyan(`
1194
+ `));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(_i.yellow("Setup cancelled.")),null;let c=Fi.find(p=>p.key===s);return c?(await c.handler(i()),c.key):(m(_i.yellow(`
1195
+ \u26A0\uFE0F ${s} setup is not implemented yet.`)),null)},Ta=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 dd(t)}catch(r){y.fail("Setup failed"),E(`${r}`),process.exit(1)}})};import{existsSync as gd}from"node:fs";import{mkdir as hd}from"node:fs/promises";import be from"node:path";import Y from"picocolors";q();import ud from"enquirer";var{prompt:fd}=ud,Ca=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 fd(r):{};return{sliceName:e||i.sliceName,persistSlice:t===void 0?i.persistSlice||!1:t}};var Ra=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(Y.cyan(`
1192
1196
  \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(`
1197
+ `)),y.start("Detecting project setup...");let n=await M(i);y.succeed("Project setup detected"),n.hasRedux||(y.fail("Redux is not setup in this project"),E("Please install @reduxjs/toolkit and react-redux first"),m(Y.dim(`
1194
1198
  Run: npm install @reduxjs/toolkit react-redux
1195
- `)),process.exit(1)),l(V.dim(` Redux: \u2713
1196
- `));let o=await Ds(t,r.persist);H(o.sliceName,"slice name"),r.path&&re(r.path,"path");let{basePath:s,slicePath:a}=lm(n,o.sliceName,r.path),p=ye.join(n,s);cm(p)||await pm(p,{recursive:!0}),await ue(n,o.sliceName,s)&&(v(`Slice '${o.sliceName}' already exists at ${s}!`),process.exit(1)),await Re(Zr(),{projectPath:n,spinner:y,sliceName:o.sliceName,basePath:s,slicePath:a,persistSlice:o.persistSlice});let d=null;if(mm(r,i.hasTests)){let x=ye.join(a,`${o.sliceName}.slice.ts`);y.start("Generating test..."),d=await ae({projectPath:n,sourceFile:x,kind:"slice",symbolName:j(o.sliceName)}),y.succeed("Test generated")}dm(o,s,d,n)}catch(n){y.fail("Slice generation failed"),v(`${n}`),process.exit(1)}})},lm=(e,t,r)=>{let n;if(r){let i=r.replace(/^src\//,"");if(i.startsWith("features/")){let o=i.split("/")[1];n=ye.join("src","features",o,"store")}else n=ye.join("src",i)}else n=ye.join("src","features",t,"store");return{basePath:n,slicePath:ye.join(e,n,t)}},mm=(e,t)=>e.test===!1?!1:e.test===!0?!0:t,dm=(e,t,r,n)=>{let i=ye.join(t,e.sliceName);l(V.green(`
1199
+ `)),process.exit(1)),m(Y.dim(` Redux: \u2713
1200
+ `));let o=await Ca(t,r.persist);W(o.sliceName,"slice name"),r.path&&pe(r.path,"path");let{basePath:s,slicePath:c}=yd(i,o.sliceName,r.path),p=be.join(i,s);gd(p)||await hd(p,{recursive:!0}),await Se(i,o.sliceName,s)&&(E(`Slice '${o.sliceName}' already exists at ${s}!`),process.exit(1)),await Me(ki(),{projectPath:i,spinner:y,sliceName:o.sliceName,basePath:s,slicePath:c,persistSlice:o.persistSlice});let d=null;if(xd(r,n.hasTests)){let x=be.join(c,`${o.sliceName}.slice.ts`);y.start("Generating test..."),d=await ge({projectPath:i,sourceFile:x,kind:"slice",symbolName:G(o.sliceName)}),y.succeed("Test generated")}wd(o,s,d,i)}catch(i){y.fail("Slice generation failed"),E(`${i}`),process.exit(1)}})},yd=(e,t,r)=>{let i;if(r){let n=r.replace(/^src\//,"");if(n.startsWith("features/")){let o=n.split("/")[1];i=be.join("src","features",o,"store")}else i=be.join("src",n)}else i=be.join("src","features",t,"store");return{basePath:i,slicePath:be.join(e,i,t)}},xd=(e,t)=>e.test===!1?!1:e.test===!0?!0:t,wd=(e,t,r,i)=>{let n=be.join(t,e.sliceName);m(Y.green(`
1197
1201
  \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 nn from"picocolors";P();B();var Ms=e=>{e.command("test <file>").description(`Generate a sibling test file for an existing component, hook, or slice.
1201
- Infers the kind from filename/content; pass --kind to override.`).option("--kind <kind>","Override inferred kind: component | hook | slice").option("--force","Overwrite an existing test file").action(async(t,r)=>{try{let n=process.cwd(),i=ee.isAbsolute(t)?t:ee.join(n,t);l(nn.cyan(`
1202
+ `)),m(Y.dim("Generated files:")),m(Y.dim(` \u{1F4C2} ${n}/`)),m(Y.dim(` \u251C\u2500\u2500 ${e.sliceName}.slice.ts`)),m(Y.dim(` \u251C\u2500\u2500 ${e.sliceName}.selectors.ts`)),e.persistSlice&&m(Y.dim(" \u251C\u2500\u2500 persist.ts")),m(Y.dim(` \u251C\u2500\u2500 ${e.sliceName}.types.ts`)),m(Y.dim(` \u2514\u2500\u2500 index.ts
1203
+ `)),r&&m(Y.dim(` \u{1F9EA} ${be.relative(i,r)}
1204
+ `)),m(Y.cyan("Next steps:"));let o=t.replace(/^src\//,"@/");m(Y.dim(` 1. Import actions: import { setLoading, setError } from '${o}/${e.sliceName}'`)),m(Y.dim(" 2. Use in component: dispatch(setLoading(true))")),m("")};import se from"node:path";import Oi from"picocolors";w();q();var ba=e=>{e.command("test <file>").description(`Generate a sibling test file for an existing component, hook, or slice.
1205
+ 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=se.isAbsolute(t)?t:se.join(i,t);m(Oi.cyan(`
1202
1206
  \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 u(i),a=um(r.kind)??fm(i,s);a||(v(`Could not infer test kind for ${ee.basename(i)}. Pass --kind component|hook|slice.`),process.exit(1));let p=gm(i,a),f=hm(i,a);m(f)&&!r.force&&(v(`Test file already exists: ${ee.relative(n,f)}. Use --force to overwrite.`),process.exit(1)),y.start(`Generating ${a} test...`);let d=await ae({projectPath:n,sourceFile:i,kind:a,symbolName:p,hasRedux:o.hasRedux,hasI18n:o.hasI18n,hookUsesStore:a==="hook"&&o.hasRedux&&s.includes("useAppSelector")});y.succeed("Test generated"),l(nn.green(`
1204
- \u2728 Test '${ee.basename(d)}' created.
1205
- `)),l(nn.dim(` \u{1F9EA} ${ee.relative(n,d)}`)),l("")}catch(n){y.fail("Test generation failed"),v(`${n}`),process.exit(1)}})},um=e=>{if(!e)return null;if(e==="component"||e==="hook"||e==="slice")return e;throw new Error(`Invalid --kind: ${e}. Use component | hook | slice.`)},fm=(e,t)=>{let r=ee.basename(e);return/\.slice\.ts$/.test(r)?"slice":/^use[A-Z]/.test(r.replace(/\.tsx?$/,""))?"hook":r.endsWith(".tsx")?"component":/createSlice\s*\(/.test(t)?"slice":/^export\s+(const|function)\s+use[A-Z]/m.test(t)?"hook":null},gm=(e,t)=>{let r=ee.basename(e).replace(/\.(tsx?|jsx?)$/i,"");return t==="slice"?j(r.replace(/\.slice$/,"")):t==="hook"?/^use[A-Z]/.test(r)?r:`use${I(r.replace(/^use-?/,""))}`:I(r)},hm=(e,t)=>{let r=ee.dirname(e),n=ee.basename(e).replace(/\.(tsx?|jsx?)$/i,""),i=t==="component"?".tsx":".ts";return ee.join(r,`${n}.test${i}`)};var Gs=e=>{Zn(e),js(e),vs(e),Ls(e),Fs(e),Is(e),Cs(e),ki(e),bs(e),Es(e),Ns(e),Zo(e),gs(e),Ho(e),ks(e),Ms(e)};var xm=process.emitWarning;process.emitWarning=function(e,t,r,n){if(!(typeof e=="string"&&e.includes("--localstorage-file")&&e.includes("was provided without a valid path")))return xm.apply(process,arguments)};async function Pm(){an({logger:t=>dt(t)});let e=new ym;e.name("next-maker").description("Teispace Next.js Project Generator").version(on.version),Gs(e),e.parse()}Pm().catch(e=>{let t=e&&typeof e=="object"&&"message"in e?e.message:String(e);dt(`Unexpected error: ${t}`)});
1207
+ `)),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=Pd(r.kind)??vd(n,s);c||(E(`Could not infer test kind for ${se.basename(n)}. Pass --kind component|hook|slice.`),process.exit(1));let p=Sd(n,c),u=Ed(n,c);l(u)&&!r.force&&(E(`Test file already exists: ${se.relative(i,u)}. Use --force to overwrite.`),process.exit(1)),y.start(`Generating ${c} test...`);let d=await ge({projectPath:i,sourceFile:n,kind:c,symbolName:p,hasRedux:o.hasRedux,hasI18n:o.hasI18n,hookUsesStore:c==="hook"&&o.hasRedux&&s.includes("useAppSelector")});y.succeed("Test generated"),m(Oi.green(`
1208
+ \u2728 Test '${se.basename(d)}' created.
1209
+ `)),m(Oi.dim(` \u{1F9EA} ${se.relative(i,d)}`)),m("")}catch(i){y.fail("Test generation failed"),E(`${i}`),process.exit(1)}})},Pd=e=>{if(!e)return null;if(e==="component"||e==="hook"||e==="slice")return e;throw new Error(`Invalid --kind: ${e}. Use component | hook | slice.`)},vd=(e,t)=>{let r=se.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},Sd=(e,t)=>{let r=se.basename(e).replace(/\.(tsx?|jsx?)$/i,"");return t==="slice"?G(r.replace(/\.slice$/,"")):t==="hook"?/^use[A-Z]/.test(r)?r:`use${N(r.replace(/^use-?/,""))}`:N(r)},Ed=(e,t)=>{let r=se.dirname(e),i=se.basename(e).replace(/\.(tsx?|jsx?)$/i,""),n=t==="component"?".tsx":".ts";return se.join(r,`${i}.test${n}`)};var Ia=e=>{kn(e),Ta(e),pa(e),Ra(e),Ea(e),ya(e),da(e),po(e),fa(e),ma(e),xa(e),Gs(e),ia(e),ks(e),wa(e),ba(e)};var Cd=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 Cd.apply(process,arguments)};async function Rd(){Li({logger:t=>Nt(t)});let e=new Td;e.name("next-maker").description("Teispace Next.js Project Generator").version(Di.version),Ia(e),e.parse()}Rd().catch(e=>{let t=e&&typeof e=="object"&&"message"in e?e.message:String(e);Nt(`Unexpected error: ${t}`)});