@teispace/next-maker 2.0.0 → 2.1.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.
Files changed (36) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +42 -7
  3. package/dist/index.js +342 -200
  4. package/dist/index.js.map +4 -4
  5. package/dist/src/commands/setup.d.ts.map +1 -1
  6. package/dist/src/config/paths.d.ts +10 -0
  7. package/dist/src/config/paths.d.ts.map +1 -1
  8. package/dist/src/detection/project.detector.d.ts +7 -0
  9. package/dist/src/detection/project.detector.d.ts.map +1 -1
  10. package/dist/src/manifests/http-client.manifest.d.ts.map +1 -1
  11. package/dist/src/manifests/index.d.ts +2 -1
  12. package/dist/src/manifests/index.d.ts.map +1 -1
  13. package/dist/src/manifests/ws.manifest.d.ts +3 -0
  14. package/dist/src/manifests/ws.manifest.d.ts.map +1 -0
  15. package/dist/src/prompts/create-app.prompt.d.ts +6 -0
  16. package/dist/src/prompts/create-app.prompt.d.ts.map +1 -1
  17. package/dist/src/services/init/cleanup/http.cleanup.d.ts.map +1 -1
  18. package/dist/src/services/init/cleanup/index.d.ts.map +1 -1
  19. package/dist/src/services/init/cleanup/seo.cleanup.d.ts +15 -0
  20. package/dist/src/services/init/cleanup/seo.cleanup.d.ts.map +1 -0
  21. package/dist/src/services/init/cleanup/ws.cleanup.d.ts +15 -0
  22. package/dist/src/services/init/cleanup/ws.cleanup.d.ts.map +1 -0
  23. package/dist/src/services/init/providers.service.d.ts.map +1 -1
  24. package/dist/src/services/setup/http-client/assets.d.ts.map +1 -1
  25. package/dist/src/services/setup/http-client/index.d.ts.map +1 -1
  26. package/dist/src/services/setup/http-client/injectors.d.ts +72 -0
  27. package/dist/src/services/setup/http-client/injectors.d.ts.map +1 -1
  28. package/dist/src/services/setup/ws/assets.d.ts +21 -0
  29. package/dist/src/services/setup/ws/assets.d.ts.map +1 -0
  30. package/dist/src/services/setup/ws/checks.d.ts +18 -0
  31. package/dist/src/services/setup/ws/checks.d.ts.map +1 -0
  32. package/dist/src/services/setup/ws/index.d.ts +21 -0
  33. package/dist/src/services/setup/ws/index.d.ts.map +1 -0
  34. package/dist/src/services/setup/ws/injectors.d.ts +57 -0
  35. package/dist/src/services/setup/ws/injectors.d.ts.map +1 -0
  36. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,17 +1,30 @@
1
1
  #!/usr/bin/env node
2
- var Xi=Object.defineProperty;var be=(e,t)=>()=>(e&&(t=e(e=0)),t);var kt=(e,t)=>{for(var r in t)Xi(e,r,{get:t[r],enumerable:!0})};import{existsSync as At}from"node:fs";import ye from"node:fs/promises";import Hr from"node:path";var f,g,F,E,w,_,m,P=be(()=>{"use strict";f=async e=>ye.readFile(e,"utf-8"),g=async(e,t)=>{await ye.mkdir(Hr.dirname(e),{recursive:!0}),await ye.writeFile(e,t,"utf-8")},F=async(e,t)=>{await ye.mkdir(Hr.dirname(t),{recursive:!0}),await ye.copyFile(e,t)},E=async e=>{At(e)&&await ye.unlink(e)},w=async e=>{At(e)&&await ye.rm(e,{recursive:!0,force:!0})},_=async(e,t)=>{let r=await f(e),n=JSON.parse(r),o=t(n);await g(e,JSON.stringify(o,null,2))},m=e=>At(e)});var qr={};kt(qr,{PROJECT_PATHS:()=>c});var c,S=be(()=>{"use strict";c={NEXT_CONFIG:"next.config.ts",POSTCSS_CONFIG:"postcss.config.mjs",BIOME_CONFIG:"biome.json",VITEST_CONFIG:"vitest.config.ts",TEST_DIR:"test",TS_CONFIG:"tsconfig.json",PACKAGE_JSON:"package.json",ENV_EXAMPLE:".env.example",GITIGNORE:".gitignore",README:"README.md",LICENSE:"LICENSE",CHANGELOG:"CHANGELOG.md",NVM_RC:".nvmrc",NPM_RC:".npmrc",AGENTS_MD:"AGENTS.md",CLAUDE_MD:"CLAUDE.md",SRC:"src",APP:"src/app",COMPONENTS:"src/components",LIB:"src/lib",PROVIDERS:"src/providers",STYLES:"src/styles",TYPES:"src/types",UTILS:"src/lib/utils",HOOKS:"src/hooks",SERVICES:"src/services",STORE:"src/store",I18N:"src/i18n",GLOBALS_CSS:"src/styles/globals.css",ROOT_LAYOUT:"src/app/layout.tsx",ROOT_PAGE:"src/app/page.tsx",ROOT_PROVIDER:"src/providers/RootProvider.tsx",PROVIDERS_INDEX:"src/providers/index.ts",COMPONENTS_INDEX:"src/components/index.ts",TYPES_INDEX:"src/types/index.ts",UTILS_INDEX:"src/lib/utils/index.ts",CONFIG_INDEX:"src/lib/config/index.ts",CONSTANTS:"src/lib/config/constants.ts",APP_LOCALES:"src/lib/config/app-locales.ts",MIDDLEWARE:"src/middleware.ts",PROXY:"src/proxy.ts",I18N_TYPES:"src/types/i18n.ts",HTTP_UTILS:"src/lib/utils/http",HTTP_SHARED:"src/lib/utils/http/shared",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",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 Kr={};kt(Kr,{cleanupHttpTypes:()=>Re,isFileUsed:()=>Es,isStringUsed:()=>bs,migrateClientUsages:()=>Mt,removeHttpExports:()=>Gt,updateConfigIndex:()=>Lt,updateHttpIndex:()=>_t,updateTypesIndex:()=>Dt,updateUtilsIndex:()=>jt});import{exec as Cs}from"node:child_process";import D from"node:path";import{promisify as Ts}from"node:util";var Ft,_t,jt,Dt,Lt,Re,Mt,Gt,Es,bs,ut=be(()=>{"use strict";S();P();Ft=Ts(Cs),_t=async(e,t)=>{let r=D.join(e,c.HTTP_UTILS,"index.ts");if(m(r)){let n=await f(r);n=n.replace(/export .* from '\.\/axios-client';?\n?/g,""),n=n.replace(/export .* from '\.\/fetch-client';?\n?/g,""),t.includes("fetch")&&!n.includes("fetch-client")&&(n+=`export * from './fetch-client';
2
+ var Rs=Object.defineProperty;var Re=(e,t)=>()=>(e&&(t=e(e=0)),t);var Ht=(e,t)=>{for(var r in t)Rs(e,r,{get:t[r],enumerable:!0})};import{existsSync as Ut}from"node:fs";import ye from"node:fs/promises";import en from"node:path";var f,g,N,E,w,D,m,P=Re(()=>{"use strict";f=async e=>ye.readFile(e,"utf-8"),g=async(e,t)=>{await ye.mkdir(en.dirname(e),{recursive:!0}),await ye.writeFile(e,t,"utf-8")},N=async(e,t)=>{await ye.mkdir(en.dirname(t),{recursive:!0}),await ye.copyFile(e,t)},E=async e=>{Ut(e)&&await ye.unlink(e)},w=async e=>{Ut(e)&&await ye.rm(e,{recursive:!0,force:!0})},D=async(e,t)=>{let r=await f(e),n=JSON.parse(r),i=t(n);await g(e,JSON.stringify(i,null,2))},m=e=>Ut(e)});var an={};Ht(an,{PROJECT_PATHS:()=>c});var c,S=Re(()=>{"use strict";c={NEXT_CONFIG:"next.config.ts",POSTCSS_CONFIG:"postcss.config.mjs",BIOME_CONFIG:"biome.json",VITEST_CONFIG:"vitest.config.ts",TEST_DIR:"test",TS_CONFIG:"tsconfig.json",PACKAGE_JSON:"package.json",ENV_EXAMPLE:".env.example",GITIGNORE:".gitignore",README:"README.md",LICENSE:"LICENSE",CHANGELOG:"CHANGELOG.md",NVM_RC:".nvmrc",NPM_RC:".npmrc",AGENTS_MD:"AGENTS.md",CLAUDE_MD:"CLAUDE.md",SRC:"src",APP:"src/app",COMPONENTS:"src/components",LIB:"src/lib",PROVIDERS:"src/providers",STYLES:"src/styles",TYPES:"src/types",UTILS:"src/lib/utils",HOOKS:"src/hooks",SERVICES:"src/services",STORE:"src/store",I18N:"src/i18n",GLOBALS_CSS:"src/styles/globals.css",ROOT_LAYOUT:"src/app/layout.tsx",ROOT_PAGE:"src/app/page.tsx",ROOT_PROVIDER:"src/providers/RootProvider.tsx",PROVIDERS_INDEX:"src/providers/index.ts",COMPONENTS_INDEX:"src/components/index.ts",TYPES_INDEX:"src/types/index.ts",UTILS_INDEX:"src/lib/utils/index.ts",CONFIG_INDEX:"src/lib/config/index.ts",CONSTANTS:"src/lib/config/constants.ts",APP_LOCALES:"src/lib/config/app-locales.ts",SEO_FILE:"src/lib/config/seo.ts",SITEMAP_FILE:"src/app/sitemap.ts",MIDDLEWARE:"src/middleware.ts",PROXY:"src/proxy.ts",I18N_TYPES:"src/types/i18n.ts",HTTP_UTILS:"src/lib/utils/http",HTTP_SHARED:"src/lib/utils/http/shared",HTTP_SERVER_FILE:"src/lib/utils/http/server.ts",HTTP_BUNDLE_SENTINEL_DIR:"src/lib/utils/http/__bundle-sentinel__",HTTP_BUNDLE_SENTINEL_FILE:"src/lib/utils/http/__bundle-sentinel__/client-bundle-sentinel.tsx",WS_UTILS:"src/lib/utils/ws",WS_SLICE_FILE:"src/store/slices/ws.slice.ts",ROOT_REDUCER:"src/store/rootReducer.ts",TEST_SETUP_FILE:"test/setup.ts",AXIOS_CLIENT:"src/lib/utils/http/axios-client",FETCH_CLIENT:"src/lib/utils/http/fetch-client",AXIOS_CLIENT_FILE:"src/lib/utils/http/axios-client/index.ts",FETCH_CLIENT_FILE:"src/lib/utils/http/fetch-client/index.ts",CLIENT_UTILS:"src/lib/utils/http/client-utils.ts",APP_APIS:"src/lib/config/app-apis.ts",API_URL_FILE:"src/lib/config/api-url.ts",STORAGE_SERVICE:"src/services/storage",COUNTER_FEATURE:"src/features/counter",I18N_DIR:"src/i18n",LOCALE_DIR:"src/app/[locale]",ERRORS_DIR:"src/lib/errors",UTILITY_TYPES_DIR:"src/types/utility",COMMON_TYPES_DIR:"src/types/common",HTTP_TYPES:"src/types/common/http.types.ts",GITHUB_DIR:".github",HUSKY_DIR:".husky",STORE_PROVIDER:"src/providers/StoreProvider.tsx",THEME_PROVIDER:"src/providers/CustomThemeProvider.tsx",COUNTER_COMPONENT:"src/features/counter/components/Counter.tsx",LOCALE_PAGE:"src/app/[locale]/page.tsx",LOCALE_LAYOUT:"src/app/[locale]/layout.tsx",COMMITLINT_CONFIG:"commitlint.config.mjs",LINTSTAGED_RC:".lintstagedrc.mjs",CZRC:".czrc",DOCKERIGNORE:".dockerignore",DOCKERFILE:"Dockerfile",DOCKER_COMPOSE:"docker-compose.yml",GITHUB_WORKFLOWS:".github/workflows",GITHUB_ISSUE_TEMPLATE:"ISSUE_TEMPLATE",GITHUB_PR_TEMPLATE:"PULL_REQUEST_TEMPLATE.md",CODE_OF_CONDUCT:"CODE_OF_CONDUCT.md",CONTRIBUTING:"CONTRIBUTING.md",SECURITY:"SECURITY.md",SCRIPTS_DIR:"scripts",DOCS_DIR:"docs",CLAUDE_DIR:".claude",VSCODE_DIR:".vscode"}});var gn={};Ht(gn,{cleanupHttpTypes:()=>Ie,injectBundleSentinel:()=>fn,installBundleSentinelMount:()=>Kt,isFileUsed:()=>oa,isStringUsed:()=>sa,migrateClientUsages:()=>Xt,removeBundleSentinelMount:()=>He,removeHttpExports:()=>Zt,resolveBundleSentinelLayoutPath:()=>Yt,rewriteSentinelImports:()=>Ne,rewriteServerEntryImports:()=>ke,stripBundleSentinel:()=>Ge,updateConfigIndex:()=>qt,updateHttpIndex:()=>Jt,updateTypesIndex:()=>Wt,updateUtilsIndex:()=>Vt});import{exec as ra}from"node:child_process";import A from"node:path";import{promisify as na}from"node:util";var zt,Jt,Vt,Wt,qt,Ie,Xt,Yt,ia,mn,dn,fn,Ge,Kt,He,Zt,oa,sa,Ne,ke,un,Ue=Re(()=>{"use strict";S();P();zt=na(ra),Jt=async(e,t)=>{let r=A.join(e,c.HTTP_UTILS,"index.ts");if(m(r)){let n=await f(r);n=n.replace(/export .* from '\.\/axios-client';?\n?/g,""),n=n.replace(/export .* from '\.\/fetch-client';?\n?/g,""),t.includes("fetch")&&!n.includes("fetch-client")&&(n+=`export * from './fetch-client';
3
3
  `),t.includes("axios")&&!n.includes("axios-client")&&(n+=`export * from './axios-client';
4
- `),await g(r,n)}},jt=async e=>{let t=D.join(e,c.UTILS_INDEX);if(m(t)){let r=await f(t);r.includes("./http")||(r+=`export * from './http';
5
- `,await g(t,r))}},Dt=async e=>{let t=D.join(e,c.TYPES_INDEX);if(m(t)){let r=await f(t);r.includes("./common")||(r+=`export * from './common';
4
+ `),await g(r,n)}},Vt=async e=>{let t=A.join(e,c.UTILS_INDEX);if(m(t)){let r=await f(t);r.includes("./http")||(r+=`export * from './http';
5
+ `,await g(t,r))}},Wt=async e=>{let t=A.join(e,c.TYPES_INDEX);if(m(t)){let r=await f(t);r.includes("./common")||(r+=`export * from './common';
6
6
  `),r.includes("./utility")||(r+=`export * from './utility';
7
- `),await g(t,r)}},Lt=async e=>{let t=D.join(e,c.CONFIG_INDEX);if(m(t)){let r=await f(t);r.includes("./app-apis")||(r+=`export * from './app-apis';
8
- `,await g(t,r))}},Re=async(e,t)=>{let r=D.join(e,c.HTTP_TYPES);if(m(r)){let n=await f(r);t.includes("axios")||(n=n.replace(/declare module 'axios'\s*\{\s*export interface AxiosRequestConfig\s*\{[\s\S]*?\}\s*\}/g,""),n=`${n.replace(/\n\s*\n/g,`
7
+ `),await g(t,r)}},qt=async e=>{let t=A.join(e,c.CONFIG_INDEX);if(m(t)){let r=await f(t);r.includes("./app-apis")||(r+=`export * from './app-apis';
8
+ `,await g(t,r))}},Ie=async(e,t)=>{let r=A.join(e,c.HTTP_TYPES);if(m(r)){let n=await f(r);t.includes("axios")||(n=n.replace(/declare module 'axios'\s*\{\s*export interface AxiosRequestConfig\s*\{[\s\S]*?\}\s*\}/g,""),n=`${n.replace(/\n\s*\n/g,`
9
9
 
10
10
  `).trim()}
11
- `,await g(r,n))}},Mt=async(e,t,r)=>{if(t===r)return;let n=t==="fetch"?"fetchClient":"axiosClient",o=r==="fetch"?"fetchClient":"axiosClient",i=t==="fetch"?"fetch-client":"axios-client",s=r==="fetch"?"fetch-client":"axios-client",a=D.join(e,"src");try{let p=`grep -rl "${n}" "${a}" --include="*.ts" --include="*.tsx" || true`,{stdout:u}=await Ft(p);if(!u.trim())return;let d=u.trim().split(`
12
- `).filter(h=>h);for(let h of d){if(!m(h))continue;let x=await f(h),k=!1,z=new RegExp(`(import\\s*\\{[^}]*?)\\b${n}\\b([^}]*?\\}\\s*from\\s*['"][^'"]*?/http['"])`,"g");z.test(x)&&(x=x.replace(z,`$1${o}$2`),k=!0);let $=new RegExp(`import\\s+${n}\\s+from\\s+['"]([^'"]*?)/${i}['"]`,"g");$.test(x)&&(x=x.replace($,`import ${o} from '$1/${s}'`),k=!0);let J=new RegExp(`\\b${n}\\b(?=\\.)`,"g");J.test(x)&&(x=x.replace(J,o),k=!0);let he=new RegExp(`\\b${n}\\b(?![.\\w])`,"g");he.test(x)&&(x=x.replace(he,o),k=!0),k&&await g(h,x)}}catch(p){console.warn("Warning: Could not scan for HTTP client usages:",p)}},Gt=async e=>{let t=D.join(e,c.UTILS_INDEX);if(m(t)){let n=await f(t);n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http['"];?.*$/gm,""),await g(t,n)}let r=D.join(e,c.TYPES_INDEX);if(m(r)){let n=await f(r),o=D.join(e,c.COMMON_TYPES_DIR);if(!m(o))n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/common['"];?.*$/gm,"");else{let i=D.join(o,"index.ts");if(m(i)){let s=await f(i);s=s.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http\.types['"];?.*$/gm,""),await g(i,s)}}m(D.join(e,c.UTILITY_TYPES_DIR))||(n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/utility['"];?.*$/gm,"")),await g(r,n)}},Es=async(e,t,r=[])=>{let n=D.join(e,"src"),i=`grep -r "from ['\\"].*${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}.*['\\"]" "${n}" --include="*.ts" --include="*.tsx" || true`;try{let{stdout:s}=await Ft(i);return s.trim()?s.trim().split(`
13
- `).filter(u=>{let[d]=u.split(":"),h=D.resolve(e,d);return!r.some(x=>!!(h===x||h.startsWith(x+D.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for ${t}:`,s),!0}},bs=async(e,t,r=[])=>{let n=D.join(e,"src"),i=`grep -r "${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}" "${n}" --include="*.ts" --include="*.tsx" || true`;try{let{stdout:s}=await Ft(i);return s.trim()?s.trim().split(`
14
- `).filter(u=>{let[d]=u.split(":"),h=D.resolve(e,d);return!r.some(x=>!!(h===x||h.startsWith(x+D.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for string ${t}:`,s),!0}}});import{existsSync as ea}from"node:fs";import{access as ta}from"node:fs/promises";import xn from"node:path";var le,gt,Pn=be(()=>{"use strict";le=async(e,t,r)=>{try{return await ta(xn.join(e,r,t)),!0}catch{return!1}},gt=(e,t,r)=>ea(xn.join(e,t,r))});import{access as Jt,readFile as ra}from"node:fs/promises";import ht from"node:path";var A,vn=be(()=>{"use strict";A=async e=>{try{let t=ht.join(e,"package.json"),r=await ra(t,"utf-8"),n=JSON.parse(r),o={...n.dependencies,...n.devDependencies},i=!!(o["@reduxjs/toolkit"]&&o["react-redux"]),s=!!o["next-intl"],a=!!o.axios,p=!1,u=ht.join(e,"src","lib","utils","http","axios-client");try{await Jt(u)}catch{a=!1}let d=ht.join(e,"src","lib","utils","http","fetch-client");try{await Jt(d),p=!0}catch{p=!1}let h;a&&p?h="both":a?h="axios":p?h="fetch":h="none";let x=!!o.vitest;if(!x)try{await Jt(ht.join(e,"vitest.config.ts")),x=!0}catch{}return{hasRedux:i,httpClient:h,hasI18n:s,hasTests:x}}catch(t){throw new Error(`Failed to detect project setup: ${t}`,{cause:t})}}});var De={};kt(De,{detectProjectSetup:()=>A,directoryExists:()=>le,fileExistsAt:()=>gt});var G=be(()=>{"use strict";Pn();vn()});import{Command as Zp}from"commander";import Ut from"node:path";import X from"picocolors";function Lr(e){let{logger:t=s=>console.error(s),exitOnCancel:r=process.env.NODE_ENV!=="test"}=e??{},n=()=>{console.log(""),console.log(""),t("Setup cancelled by user"),console.log(""),r&&process.exit(0)},o=s=>{if(s!==null&&typeof s=="object"&&"code"in s&&s.code==="ERR_USE_AFTER_CLOSE"){n();return}if(s instanceof Error){t(`Uncaught exception: ${s.message}`);return}t(`Uncaught exception: ${String(s)}`)},i=s=>{if(s instanceof Error){t(`Unhandled promise rejection: ${s.message}`);return}t(`Unhandled promise rejection: ${String(s)}`)};return process.on("SIGINT",n),process.on("SIGTERM",n),process.on("uncaughtException",o),process.on("unhandledRejection",i),()=>{process.off("SIGINT",n),process.off("SIGTERM",n),process.off("uncaughtException",o),process.off("unhandledRejection",i)}}import ee from"picocolors";var Wi={reset:e=>e,red:ee.red,green:ee.green,yellow:ee.yellow,blue:ee.blue,cyan:ee.cyan,magenta:ee.magenta,white:ee.white,gray:ee.gray,bright:ee.bold,dim:ee.dim};function ae(e,t="reset"){let r=Wi[t]??(n=>n);console.log(r(e))}function lt(e){ae(`\u2716 ${e}`,"red")}var v=lt;function Mr(e){ae(`\u26A0 ${e}`,"yellow")}function l(e){ae(e)}function Gr(){console.log(""),ae("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557","cyan"),ae("\u2551 \u2551","cyan"),ae("\u2551 \u{1F680} Create Teispace Next.js App \u{1F680} \u2551","cyan"),ae("\u2551 \u2551","cyan"),ae("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D","cyan"),console.log("")}import Yi from"ora";function b(e="",t){let r=Yi({text:e,...t});return r.start(),r}var Ki=e=>e.charAt(0).toUpperCase()+e.slice(1),O=e=>e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase()),R=e=>Ki(O(e));import Zi from"ora";var y=Zi();P();import{exec as Qi}from"node:child_process";import{promisify as es}from"node:util";var oe=es(Qi),Ur=async(e,t,r)=>{try{if(await oe("git init",{cwd:e}),await oe("git add .",{cwd:e}),await oe('git commit -m "Initial commit from @teispace/next-maker"',{cwd:e}),t&&(await oe(`git remote add origin ${t}`,{cwd:e}),r)){await oe("git fetch origin",{cwd:e});let n="main";try{await oe("git show-branch origin/main",{cwd:e})}catch{try{await oe("git show-branch origin/master",{cwd:e}),n="master"}catch{n="main"}}await oe(`git merge origin/${n} --allow-unrelated-histories -X ours`,{cwd:e}),await oe(`git push origin HEAD:${n}`,{cwd:e})}}catch(n){console.warn("Failed to initialize git repository",n)}};import{exec as ts}from"node:child_process";import{promisify as rs}from"node:util";var Fe=rs(ts),zr=async(e,t)=>{let r=`${t} install`;try{await Fe(r,{cwd:e})}catch(n){throw new Error(`Failed to install dependencies with ${t}: ${n}`,{cause:n})}},q=async(e,t,r)=>{let n=t==="npm"?`${t} run ${r}`:`${t} ${r}`;try{await Fe(n,{cwd:e})}catch(o){console.warn(`Warning: Failed to run script '${r}': ${o}`)}},ns=()=>{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"},j=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":ns()},os=async(e,t,r)=>{if(r.length===0)return;let o=`${Jr(t)} ${r.join(" ")}`;try{await Fe(o,{cwd:e})}catch(i){throw new Error(`Failed to install packages with ${t}: ${i}`,{cause:i})}},Jr=e=>{switch(e){case"npm":return"npm install";case"yarn":return"yarn add";case"pnpm":return"pnpm add";case"bun":return"bun add";default:return"npm install"}},V=async(e,t)=>{let r=await j(e);await os(e,r,[t])},is=e=>{switch(e){case"npm":return"--save-dev";case"yarn":case"pnpm":case"bun":return"-D";default:return"--save-dev"}},xe=async(e,t,r)=>{if(r.length===0)return;let n=Jr(t),o=is(t),i=`${n} ${o} ${r.join(" ")}`;try{await Fe(i,{cwd:e})}catch(s){throw new Error(`Failed to install dev packages with ${t}: ${s}`,{cause:s})}},mt=async(e,t)=>{let r=await j(e);await xe(e,r,[t])},Ot=async(e,t,r)=>{if(r.length===0)return;let o=`${ss(t)} ${r.join(" ")}`;try{await Fe(o,{cwd:e})}catch(i){throw new Error(`Failed to uninstall packages with ${t}: ${i}`,{cause:i})}},ss=e=>{switch(e){case"npm":return"npm uninstall";case"yarn":return"yarn remove";case"pnpm":return"pnpm remove";case"bun":return"bun remove";default:return"npm uninstall"}},dt=async(e,t)=>{let r=await j(e);await Ot(e,r,[t])};import as from"enquirer";var cs=/^[a-z0-9-_]+$/,ps=/^\d+\.\d+\.\d+$/,ls=e=>cs.test(e),ms=e=>ps.test(e),Vr=(e,t={})=>{let r=t.projectName??e??"my-app";if(!ls(r))throw new Error(`Invalid project name "${r}". Use lowercase letters, digits, hyphens, and underscores only.`);let n=t.version??"0.1.0";if(!ms(n))throw new Error(`Invalid version "${n}". Expected semver (e.g. 0.1.0).`);let o=t.author??"Teispace",i=t.company??o;return{projectName:r,description:t.description??"A Next.js application",author:o,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:i,keepTemplates:t.keepTemplates??!1,darkMode:t.darkMode??!0,redux:t.redux??!0,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:ds}=as,Br=async e=>{let t=await ds([{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:"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.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 us from"node:path";var ce=async(e,t)=>{let r=fs(t);await g(us.join(e,"test/test-utils.tsx"),r)},fs=({redux:e,i18n:t})=>e&&t?gs:e?hs:t?ys:xs,gs=`import { type RenderOptions, render } from '@testing-library/react';
11
+ `,await g(r,n))}},Xt=async(e,t,r)=>{if(t===r)return;let n=t==="fetch"?"fetchClient":"axiosClient",i=r==="fetch"?"fetchClient":"axiosClient",o=t==="fetch"?"fetch-client":"axios-client",s=r==="fetch"?"fetch-client":"axios-client",a=A.join(e,"src");try{let p=`grep -rl "${n}" "${a}" --include="*.ts" --include="*.tsx" || true`,{stdout:u}=await zt(p);if(!u.trim())return;let d=u.trim().split(`
12
+ `).filter(h=>h);for(let h of d){if(!m(h))continue;let x=await f(h),$=!1,J=new RegExp(`(import\\s*\\{[^}]*?)\\b${n}\\b([^}]*?\\}\\s*from\\s*['"][^'"]*?/http['"])`,"g");J.test(x)&&(x=x.replace(J,`$1${i}$2`),$=!0);let I=new RegExp(`import\\s+${n}\\s+from\\s+['"]([^'"]*?)/${o}['"]`,"g");I.test(x)&&(x=x.replace(I,`import ${i} from '$1/${s}'`),$=!0);let V=new RegExp(`\\b${n}\\b(?=\\.)`,"g");V.test(x)&&(x=x.replace(V,i),$=!0);let he=new RegExp(`\\b${n}\\b(?![.\\w])`,"g");he.test(x)&&(x=x.replace(he,i),$=!0),$&&await g(h,x)}}catch(p){console.warn("Warning: Could not scan for HTTP client usages:",p)}},Yt=e=>{let t=A.join(e,c.LOCALE_LAYOUT);if(m(t))return t;let r=A.join(e,c.ROOT_LAYOUT);return m(r)?r:null},ia="// Regression sentinel \u2014 see file comment for what this guards.",mn="import { HttpClientBundleSentinel } from '@/lib/utils/http/__bundle-sentinel__/client-bundle-sentinel';",dn="<HttpClientBundleSentinel />",fn=e=>{if(e.includes(dn))return e;let t=e;if(!t.includes(mn)){let o=/(^import\s[^\n]*\n)+/m,s=t.match(o);if(!s)throw new Error("injectBundleSentinel: no `import` lines found \u2014 expected a layout file with at least one import.");let a=t.slice(0,(s.index??0)+s[0].length),p=t.slice((s.index??0)+s[0].length);t=`${a}${ia}
13
+ ${mn}
14
+ ${p}`}let r=/(<RootProvider\b[^>]*>)\n([ \t]*)/,n=t.match(r);if(!n)throw new Error("injectBundleSentinel: could not locate `<RootProvider \u2026>` opening tag \u2014 layout shape unexpected.");let i=n[2];return t=t.replace(r,`$1
15
+ ${i}${dn}
16
+ ${i}`),t},Ge=e=>{let t=e,r=/@\/lib\/utils\/http\/__bundle-sentinel__\/client-bundle-sentinel/,n=new RegExp(`(?:^[ \\t]*//[^\\n]*\\n)?^[ \\t]*import[^\\n]*${r.source}[^\\n]*\\n`,"m");return t=t.replace(n,""),t=t.replace(/[ \t]*<HttpClientBundleSentinel\s*\/>\s*\n/,""),t},Kt=async e=>{let t=Yt(e);if(!t)return;let r=await f(t),n=fn(r);n!==r&&await g(t,n)},He=async e=>{let t=Yt(e);if(!t)return;let r=await f(t),n=Ge(r);n!==r&&await g(t,n)},Zt=async e=>{let t=A.join(e,c.UTILS_INDEX);if(m(t)){let n=await f(t);n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http['"];?.*$/gm,""),await g(t,n)}let r=A.join(e,c.TYPES_INDEX);if(m(r)){let n=await f(r),i=A.join(e,c.COMMON_TYPES_DIR);if(!m(i))n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/common['"];?.*$/gm,"");else{let o=A.join(i,"index.ts");if(m(o)){let s=await f(o);s=s.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http\.types['"];?.*$/gm,""),await g(o,s)}}m(A.join(e,c.UTILITY_TYPES_DIR))||(n=n.replace(/^\s*export\s+\*\s+from\s+['"]\.\/utility['"];?.*$/gm,"")),await g(r,n)}},oa=async(e,t,r=[])=>{let n=A.join(e,"src"),o=`grep -r "from ['\\"].*${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}.*['\\"]" "${n}" --include="*.ts" --include="*.tsx" || true`;try{let{stdout:s}=await zt(o);return s.trim()?s.trim().split(`
17
+ `).filter(u=>{let[d]=u.split(":"),h=A.resolve(e,d);return!r.some(x=>!!(h===x||h.startsWith(x+A.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for ${t}:`,s),!0}},sa=async(e,t,r=[])=>{let n=A.join(e,"src"),o=`grep -r "${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}" "${n}" --include="*.ts" --include="*.tsx" || true`;try{let{stdout:s}=await zt(o);return s.trim()?s.trim().split(`
18
+ `).filter(u=>{let[d]=u.split(":"),h=A.resolve(e,d);return!r.some(x=>!!(h===x||h.startsWith(x+A.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for string ${t}:`,s),!0}},Ne=async(e,t)=>{let r=A.join(e,c.HTTP_BUNDLE_SENTINEL_FILE);if(!m(r))return;let n=await f(r),i=["toSearchParams"];if(t.includes("axios")&&i.unshift("axiosClient","createAxiosClient"),t.includes("fetch")){let a=i.indexOf("toSearchParams");i.splice(a,0,"createFetchClient","fetchClient")}i.sort();let o=`import {
19
+ ${i.join(`,
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__ = {
23
+ ${s}
24
+ };`),await g(r,n)},ke=async(e,t)=>{let r=A.join(e,c.HTTP_SERVER_FILE);if(!m(r)||t.length===0)return;let n=await f(r),i=o=>{n=n.replace(o,"")};t.includes("axios")||(i(/^import\s*\{\s*createAxiosClient\s*\}\s*from\s*['"]\.\/axios-client['"];\n?/m),i(/export const axiosClient = createAxiosClient\(\{[\s\S]*?\}\);\n?\n?/),n=un(n,"createAxiosClient")),t.includes("fetch")||(i(/^import\s*\{\s*createFetchClient\s*\}\s*from\s*['"]\.\/fetch-client['"];\n?/m),i(/export const fetchClient = createFetchClient\(\{[\s\S]*?\}\);\n?\n?/),n=un(n,"createFetchClient")),n=n.replace(/\n{3,}/g,`
25
+
26
+ `),await g(r,n)},un=(e,t)=>{let r=/^export\s*\{([^}]*)\};\n?/m;return e.replace(r,(n,i)=>{let o=i.split(",").map(s=>s.trim()).filter(s=>s.length>0&&s!==t);return o.length===0?"":`export { ${o.join(", ")} };
27
+ `})}});import{existsSync as Xa}from"node:fs";import{access as Ya}from"node:fs/promises";import Bn from"node:path";var le,Tt,zn=Re(()=>{"use strict";le=async(e,t,r)=>{try{return await Ya(Bn.join(e,r,t)),!0}catch{return!1}},Tt=(e,t,r)=>Xa(Bn.join(e,t,r))});import{access as bt,readFile as Ka}from"node:fs/promises";import We from"node:path";var F,Jn=Re(()=>{"use strict";F=async e=>{try{let t=We.join(e,"package.json"),r=await Ka(t,"utf-8"),n=JSON.parse(r),i={...n.dependencies,...n.devDependencies},o=!!(i["@reduxjs/toolkit"]&&i["react-redux"]),s=!!i["next-intl"],a=!!i.axios,p=!1,u=We.join(e,"src","lib","utils","http","axios-client");try{await bt(u)}catch{a=!1}let d=We.join(e,"src","lib","utils","http","fetch-client");try{await bt(d),p=!0}catch{p=!1}let h;a&&p?h="both":a?h="axios":p?h="fetch":h="none";let x=!!i.vitest;if(!x)try{await bt(We.join(e,"vitest.config.ts")),x=!0}catch{}let $="none";if(i["socket.io-client"])try{await bt(We.join(e,"src","lib","utils","ws")),$="present"}catch{}return{hasRedux:o,httpClient:h,hasI18n:s,hasTests:x,ws:$}}catch(t){throw new Error(`Failed to detect project setup: ${t}`,{cause:t})}}});var qe={};Ht(qe,{detectProjectSetup:()=>F,directoryExists:()=>le,fileExistsAt:()=>Tt});var H=Re(()=>{"use strict";zn();Jn()});import{Command as Yl}from"commander";import tr from"node:path";import q from"picocolors";function Kr(e){let{logger:t=s=>console.error(s),exitOnCancel:r=process.env.NODE_ENV!=="test"}=e??{},n=()=>{console.log(""),console.log(""),t("Setup cancelled by user"),console.log(""),r&&process.exit(0)},i=s=>{if(s!==null&&typeof s=="object"&&"code"in s&&s.code==="ERR_USE_AFTER_CLOSE"){n();return}if(s instanceof Error){t(`Uncaught exception: ${s.message}`);return}t(`Uncaught exception: ${String(s)}`)},o=s=>{if(s instanceof Error){t(`Unhandled promise rejection: ${s.message}`);return}t(`Unhandled promise rejection: ${String(s)}`)};return process.on("SIGINT",n),process.on("SIGTERM",n),process.on("uncaughtException",i),process.on("unhandledRejection",o),()=>{process.off("SIGINT",n),process.off("SIGTERM",n),process.off("uncaughtException",i),process.off("unhandledRejection",o)}}import ee from"picocolors";var $s={reset:e=>e,red:ee.red,green:ee.green,yellow:ee.yellow,blue:ee.blue,cyan:ee.cyan,magenta:ee.magenta,white:ee.white,gray:ee.gray,bright:ee.bold,dim:ee.dim};function ae(e,t="reset"){let r=$s[t]??(n=>n);console.log(r(e))}function wt(e){ae(`\u2716 ${e}`,"red")}var v=wt;function Zr(e){ae(`\u26A0 ${e}`,"yellow")}function l(e){ae(e)}function Qr(){console.log(""),ae("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557","cyan"),ae("\u2551 \u2551","cyan"),ae("\u2551 \u{1F680} Create Teispace Next.js App \u{1F680} \u2551","cyan"),ae("\u2551 \u2551","cyan"),ae("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D","cyan"),console.log("")}import Is from"ora";function b(e="",t){let r=Is({text:e,...t});return r.start(),r}var Ns=e=>e.charAt(0).toUpperCase()+e.slice(1),j=e=>e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase()),R=e=>Ns(j(e));import ks from"ora";var y=ks();P();import{exec as As}from"node:child_process";import{promisify as _s}from"node:util";var ie=_s(As),tn=async(e,t,r)=>{try{if(await ie("git init",{cwd:e}),await ie("git add .",{cwd:e}),await ie('git commit -m "Initial commit from @teispace/next-maker"',{cwd:e}),t&&(await ie(`git remote add origin ${t}`,{cwd:e}),r)){await ie("git fetch origin",{cwd:e});let n="main";try{await ie("git show-branch origin/main",{cwd:e})}catch{try{await ie("git show-branch origin/master",{cwd:e}),n="master"}catch{n="main"}}await ie(`git merge origin/${n} --allow-unrelated-histories -X ours`,{cwd:e}),await ie(`git push origin HEAD:${n}`,{cwd:e})}}catch(n){console.warn("Failed to initialize git repository",n)}};import{exec as Os}from"node:child_process";import{promisify as Fs}from"node:util";var Le=Fs(Os),rn=async(e,t)=>{let r=`${t} install`;try{await Le(r,{cwd:e})}catch(n){throw new Error(`Failed to install dependencies with ${t}: ${n}`,{cause:n})}},z=async(e,t,r)=>{let n=t==="npm"?`${t} run ${r}`:`${t} ${r}`;try{await Le(n,{cwd:e})}catch(i){console.warn(`Warning: Failed to run script '${r}': ${i}`)}},js=()=>{let e=process.env.npm_config_user_agent;if(e){if(e.startsWith("yarn"))return"yarn";if(e.startsWith("pnpm"))return"pnpm";if(e.startsWith("bun"))return"bun"}return"npm"},k=async e=>{let{existsSync:t}=await import("node:fs"),r=await import("node:path");return t(r.join(e,"pnpm-lock.yaml"))?"pnpm":t(r.join(e,"yarn.lock"))?"yarn":t(r.join(e,"bun.lockb"))?"bun":t(r.join(e,"package-lock.json"))?"npm":js()},Ds=async(e,t,r)=>{if(r.length===0)return;let i=`${nn(t)} ${r.join(" ")}`;try{await Le(i,{cwd:e})}catch(o){throw new Error(`Failed to install packages with ${t}: ${o}`,{cause:o})}},nn=e=>{switch(e){case"npm":return"npm install";case"yarn":return"yarn add";case"pnpm":return"pnpm add";case"bun":return"bun add";default:return"npm install"}},G=async(e,t)=>{let r=await k(e);await Ds(e,r,[t])},Ls=e=>{switch(e){case"npm":return"--save-dev";case"yarn":case"pnpm":case"bun":return"-D";default:return"--save-dev"}},xe=async(e,t,r)=>{if(r.length===0)return;let n=nn(t),i=Ls(t),o=`${n} ${i} ${r.join(" ")}`;try{await Le(o,{cwd:e})}catch(s){throw new Error(`Failed to install dev packages with ${t}: ${s}`,{cause:s})}},vt=async(e,t)=>{let r=await k(e);await xe(e,r,[t])},Bt=async(e,t,r)=>{if(r.length===0)return;let i=`${Ms(t)} ${r.join(" ")}`;try{await Le(i,{cwd:e})}catch(o){throw new Error(`Failed to uninstall packages with ${t}: ${o}`,{cause:o})}},Ms=e=>{switch(e){case"npm":return"npm uninstall";case"yarn":return"yarn remove";case"pnpm":return"pnpm remove";case"bun":return"bun remove";default:return"npm uninstall"}},$e=async(e,t)=>{let r=await k(e);await Bt(e,r,[t])};import Gs from"enquirer";var Hs=/^[a-z0-9-_]+$/,Us=/^\d+\.\d+\.\d+$/,Bs=e=>Hs.test(e),zs=e=>Us.test(e),on=(e,t={})=>{let r=t.projectName??e??"my-app";if(!Bs(r))throw new Error(`Invalid project name "${r}". Use lowercase letters, digits, hyphens, and underscores only.`);let n=t.version??"0.1.0";if(!zs(n))throw new Error(`Invalid version "${n}". Expected semver (e.g. 0.1.0).`);let i=t.author??"Teispace",o=t.company??i;return{projectName:r,description:t.description??"A Next.js application",author:i,version:n,packageManager:t.packageManager??"yarn",gitRemote:t.gitRemote??"",pushToRemote:t.pushToRemote??!1,gitIssues:t.gitIssues??"",gitHomepage:t.gitHomepage??"",httpClient:t.httpClient??"fetch",reactSecureStorage:t.reactSecureStorage??!0,email:t.email??"support@example.com",company:o,keepTemplates:t.keepTemplates??!1,darkMode:t.darkMode??!0,redux:t.redux??!0,ws:(t.redux??!0)&&(t.ws??!1),i18n:t.i18n??!0,communityFiles:t.communityFiles??[],readme:t.readme??!0,docker:t.docker??!1,containerName:t.containerName,imageName:t.imageName,imageTag:t.imageTag,ci:t.ci??!1,preCommitHooks:t.preCommitHooks??!0,commitizen:t.commitizen??!0,copyEnv:t.copyEnv??!0,tests:t.tests??!0,reactCompiler:t.reactCompiler??!0,bundleAnalyzer:t.bundleAnalyzer??!1}},{prompt:Js}=Gs,sn=async e=>{let t=await Js([{type:"input",name:"projectName",message:"What is the project name?",initial:e||"my-app",skip:!!e,validate:r=>/^[a-z0-9-_]+$/.test(r)?!0:"Project name must be lowercase and contain only alphanumeric characters, hyphens, and underscores."},{type:"input",name:"description",message:"Project description:",initial:"A Next.js application"},{type:"input",name:"author",message:"Author:",initial:"Teispace"},{type:"input",name:"version",message:"Version:",initial:"0.1.0",validate:r=>/^\d+\.\d+\.\d+$/.test(r)?!0:"Version must be a valid semantic version (x.y.z)."},{type:"input",name:"email",message:"Support email:",initial:"support@example.com",validate:r=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(r)?!0:"Please enter a valid email address."},{type:"select",name:"packageManager",message:"Which package manager would you like to use?",choices:["npm","yarn","pnpm","bun"],initial:1},{type:"input",name:"gitRemote",message:"GitHub repository URL (optional):",initial:""},{type:"confirm",name:"pushToRemote",message:"Would you like to push the changes to the remote repository?",initial:!0,skip:function(){return!this.state?.answers?.gitRemote}},{type:"input",name:"gitIssues",message:"GitHub issues URL (optional):",initial:"",skip:function(){return!this.state?.answers?.gitRemote},validate:r=>r?/^https:\/\/github\.com\/[\w-]+\/[\w.-]+\/issues$/.test(r)?!0:"Please enter a valid GitHub issues URL (e.g., https://github.com/user/repo/issues)":!0},{type:"input",name:"gitHomepage",message:"GitHub homepage URL (optional):",initial:"",skip:function(){return!this.state?.answers?.gitRemote},validate:r=>r?/^https:\/\/github\.com\/[\w-]+\/[\w.-]+#readme$/.test(r)?!0:"Please enter a valid GitHub homepage URL (e.g., https://github.com/user/repo#readme)":!0},{type:"confirm",name:"keepTemplates",message:"Do you want to keep GitHub issue and pull request templates?",initial:!1},{type:"select",name:"httpClient",message:"Which HTTP client do you want to use?",choices:["axios","fetch","both","none"],initial:1},{type:"confirm",name:"reactSecureStorage",message:"Do you want to include react-secure-storage?",initial:!0,skip:function(){let r=this.state?.answers??this.enquirer?.answers??{};return!!(r.httpClient&&r.httpClient!=="none")}},{type:"confirm",name:"darkMode",message:"Do you want to include Dark Mode (Tailwind + @teispace/next-themes)?",initial:!0},{type:"confirm",name:"redux",message:"Do you want to include Redux Toolkit?",initial:!0},{type:"confirm",name:"ws",message:"Do you want to include WebSocket support (socket.io-client + Redux bridge)?",initial:!1,skip:function(){return!(this.state?.answers??this.enquirer?.answers??{}).redux}},{type:"confirm",name:"i18n",message:"Do you want to include Internationalization (next-intl)?",initial:!0},{type:"confirm",name:"tests",message:"Do you want to include testing setup (Vitest + React Testing Library)?",initial:!0},{type:"confirm",name:"reactCompiler",message:"Do you want to enable the React Compiler?",initial:!0},{type:"confirm",name:"bundleAnalyzer",message:"Do you want to include @next/bundle-analyzer?",initial:!1},{type:"multiselect",name:"communityFiles",message:"Select community files to include:",choices:[{name:"CODE_OF_CONDUCT.md",value:"CODE_OF_CONDUCT.md"},{name:"CONTRIBUTING.md",value:"CONTRIBUTING.md"},{name:"SECURITY.md",value:"SECURITY.md"}],initial:[]},{type:"confirm",name:"readme",message:"Do you want to create a README.md?",initial:!0},{type:"confirm",name:"docker",message:"Do you want to include Docker configuration?",initial:!1},{type:"input",name:"containerName",message:"Docker Container Name:",initial:"next-app",skip:function(){return!(this.state?.answers??this.enquirer?.answers??{}).docker},validate:r=>/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(r)?!0:"Invalid Docker container name."},{type:"input",name:"imageName",message:"Docker Image Name:",initial:"nextjs-starter",skip:function(){return!(this.state?.answers??this.enquirer?.answers??{}).docker},validate:r=>/^[a-z0-9]+(?:[._-][a-z0-9]+)*$/.test(r)?!0:"Invalid Docker image name (must be lowercase)."},{type:"input",name:"imageTag",message:"Docker Image Tag:",initial:"latest",skip:function(){return!(this.state?.answers??this.enquirer?.answers??{}).docker},validate:r=>/^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,127}$/.test(r)?!0:"Invalid Docker image tag."},{type:"confirm",name:"ci",message:"Do you want to include GitHub Actions (CI/CD)?",initial:!1},{type:"confirm",name:"preCommitHooks",message:"Do you want to setup pre-commit hooks (Husky, Commitlint, Lint-staged)?",initial:!0},{type:"confirm",name:"commitizen",message:"Do you want to setup Commitizen?",initial:!0},{type:"confirm",name:"copyEnv",message:"Want to copy .env.example to .env?",initial:!0}]);if(t.company=t.author,t.ws=!!t.redux&&!!t.ws,t.gitRemote&&!t.gitHomepage){let r=t.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"");t.gitHomepage=`${r}#readme`,t.gitIssues=`${r}/issues`}return t};P();import Vs from"node:path";var ce=async(e,t)=>{let r=Ws(t);await g(Vs.join(e,"test/test-utils.tsx"),r)},Ws=({redux:e,i18n:t})=>e&&t?qs:e?Xs:t?Ys:Ks,qs=`import { type RenderOptions, render } from '@testing-library/react';
15
28
  import { NextIntlClientProvider } from 'next-intl';
16
29
  import type { ReactElement, ReactNode } from 'react';
17
30
  import { Provider } from 'react-redux';
@@ -72,7 +85,7 @@ export function renderWithProviders(
72
85
 
73
86
  export * from '@testing-library/react';
74
87
  export { default as userEvent } from '@testing-library/user-event';
75
- `,hs=`import { type RenderOptions, render } from '@testing-library/react';
88
+ `,Xs=`import { type RenderOptions, render } from '@testing-library/react';
76
89
  import type { ReactElement, ReactNode } from 'react';
77
90
  import { Provider } from 'react-redux';
78
91
  import { type AppState, type AppStore, makeStore } from '@/store';
@@ -111,7 +124,7 @@ export function renderWithProviders(
111
124
 
112
125
  export * from '@testing-library/react';
113
126
  export { default as userEvent } from '@testing-library/user-event';
114
- `,ys=`import { type RenderOptions, render } from '@testing-library/react';
127
+ `,Ys=`import { type RenderOptions, render } from '@testing-library/react';
115
128
  import { NextIntlClientProvider } from 'next-intl';
116
129
  import type { ReactElement, ReactNode } from 'react';
117
130
  import type { SupportedLocale } from '@/types/i18n';
@@ -151,7 +164,7 @@ export function renderWithProviders(
151
164
 
152
165
  export * from '@testing-library/react';
153
166
  export { default as userEvent } from '@testing-library/user-event';
154
- `,xs=`import { type RenderOptions, render } from '@testing-library/react';
167
+ `,Ks=`import { type RenderOptions, render } from '@testing-library/react';
155
168
  import type { ReactElement, ReactNode } from 'react';
156
169
 
157
170
  type TestProvidersProps = {
@@ -173,9 +186,137 @@ export function renderWithProviders(ui: ReactElement, options: ExtendedRenderOpt
173
186
 
174
187
  export * from '@testing-library/react';
175
188
  export { default as userEvent } from '@testing-library/user-event';
176
- `;import Xr 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 Wr=async(e,t)=>{if(t.bundleAnalyzer)return;let r=Xr.join(e,c.NEXT_CONFIG);if(m(r)){let n=await f(r);n=n.replace(/import\s+withBundleAnalyzer\s+from\s+'@next\/bundle-analyzer';\n/,""),n=n.replace(/const\s+bundleAnalyzer\s*=\s*withBundleAnalyzer\(\{[\s\S]*?\}\);\n+/,""),n=n.replace(/bundleAnalyzer\(([^)]*)\)/,"$1"),await g(r,n)}await _(Xr.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 _e from"node:path";var Yr=async(e,t)=>{t.darkMode||(await E(_e.join(e,c.THEME_PROVIDER)),await Ps(e),await vs(e),await Ss(e))},Ps=async e=>{let t=_e.join(e,c.PROVIDERS_INDEX),r=await f(t);r=r.replace(/export \* from '\.\/CustomThemeProvider';\n/,""),await g(t,r)},vs=async e=>{let t=_e.join(e,c.GLOBALS_CSS);if(m(t)){let r=await f(t);r=r.replace(/@custom-variant dark \(.*?\);\n\n/,""),r=r.replace(/@theme \{[\s\S]*?\}\n/,""),await g(t,r)}},ws=e=>e.replace(/\bbg-light\b\s?/g,"").replace(/\bdark:bg-dark\b\s?/g,"").replace(/\s{2,}/g," ").replace(/suppressHydrationWarning=\{true\}/g,""),Ss=async e=>{let t=[_e.join(e,c.ROOT_LAYOUT),_e.join(e,"src/app/[locale]/layout.tsx")];for(let r of t)if(m(r)){let n=await f(r),o=ws(n);o!==n&&await g(r,o)}};S();P();ut();import I from"node:path";var Zr=async(e,t)=>{let r=I.join(e,c.HTTP_UTILS),n=t.httpClient!=="none"||!!t.reactSecureStorage;t.httpClient==="none"?await Rs(e,r,n):t.httpClient==="axios"?await $s(e,r):t.httpClient==="fetch"&&await Is(e,r)},Rs=async(e,t,r)=>{await w(I.join(e,c.AXIOS_CLIENT)),await w(I.join(e,c.FETCH_CLIENT)),r?(await g(I.join(t,"index.ts"),`export * from './token-store';
177
- `),await E(I.join(e,c.CLIENT_UTILS)),await Re(e,[])):(await w(t),await Ns(e),await E(I.join(e,c.APP_APIS)),await ks(e)),await As(e),await w(I.join(e,c.ERRORS_DIR)),r||(await w(I.join(e,c.COMMON_TYPES_DIR)),await w(I.join(e,c.UTILITY_TYPES_DIR)),await Os(e))},$s=async(e,t)=>{await w(I.join(e,c.FETCH_CLIENT));let r=await f(I.join(t,"index.ts"));r=r.replace(/export .* from '\.\/fetch-client';\n/g,""),await g(I.join(t,"index.ts"),r);let n=I.join(e,c.HTTP_TYPES);if(m(n)){let o=await f(n);o=o.replace(/export interface FetchClientOptions \{[\s\S]*?\}\n\n/,""),o=o.replace(/export interface ExtendedRequestInit extends RequestInit \{[\s\S]*?\}\n\n/,""),await g(n,o)}},Is=async(e,t)=>{await w(I.join(e,c.AXIOS_CLIENT));let r=await f(I.join(t,"index.ts"));r=r.replace(/export .* from '\.\/axios-client';\n/g,""),await g(I.join(t,"index.ts"),r),await Re(e,["fetch"]);let n=I.join(e,c.HTTP_TYPES);if(m(n)){let o=await f(n);o=o.replace(/export interface AxiosClientOptions \{[\s\S]*?\}\n\n/,""),await g(n,o)}},Ns=async e=>{let t=I.join(e,c.UTILS_INDEX);if(m(t)){let r=await f(t);r=r.replace(/export \* from '\.\/http';\n/,""),await g(t,r)}},ks=async e=>{let t=I.join(e,c.CONFIG_INDEX);if(m(t)){let r=await f(t);r=r.replace(/export \* from '\.\/app-apis';\n/,""),await g(t,r)}},As=async e=>{let t=I.join(e,c.CONSTANTS);if(m(t)){let r=await f(t);r=r.replace(/export const API_RESPONSE_DATA_KEY = 'data';\n/,""),r=r.replace(/export const SAVE_AUTH_TOKENS = false;\n/,""),await g(t,r)}},Os=async e=>{let t=I.join(e,c.TYPES_INDEX);if(m(t)){let r=await f(t);r=r.replace(/export \* from '\.\/utility';\n/,""),r=r.replace(/export \* from '\.\/common';\n/,""),await g(t,r)}};S();P();import B from"node:path";var Qr=async(e,t)=>{t.i18n||(await _s(e),await js(e),await Ds(e),await Ls(e),await Fs(e))},Fs=async e=>{let t=B.join(e,c.ENV_EXAMPLE);if(!m(t))return;let r=await f(t);r=r.replace(/#[^\n]*IANA time zone[\s\S]*?DEFAULT_TIMEZONE=[^\n]*\n?/,""),r=r.replace(/#[^\n]*Fallback locale[\s\S]*?DEFAULT_LOCALE=[^\n]*\n?/,""),r=r.replace(/^DEFAULT_TIMEZONE=.*\n?/m,""),r=r.replace(/^DEFAULT_LOCALE=.*\n?/m,""),await g(t,r)},_s=async e=>{await w(B.join(e,c.I18N_DIR)),await w(B.join(e,c.LOCALE_DIR)),await E(B.join(e,c.PROXY)),await E(B.join(e,c.MIDDLEWARE)),await E(B.join(e,c.I18N_TYPES)),await E(B.join(e,c.APP_LOCALES))},js=async e=>{let t=B.join(e,c.TYPES_INDEX);if(m(t)){let n=await f(t);n=n.replace(/export \* from '\.\/i18n';\n/,""),await g(t,n)}let r=B.join(e,c.CONFIG_INDEX);if(m(r)){let n=await f(r);n=n.replace(/export \* from '\.\/app-locales';\n/,""),await g(r,n)}},Ds=async e=>{let t=B.join(e,c.NEXT_CONFIG);if(m(t)){let r=await f(t);r=r.replace(/import createNextIntlPlugin from 'next-intl\/plugin';\n/,""),r=r.replace(/const withNextIntl = createNextIntlPlugin\(\);\n+/,""),r=r.replace(/withNextIntl\(([^)]+)\)/,"$1"),await g(t,r)}},Ls=async e=>{let t=B.join(e,c.COUNTER_COMPONENT);if(m(t)){let o=await f(t);o=o.replace(/import\s+\{\s*useTranslations\s*\}\s+from\s+['"]next-intl['"];\n/,""),o=o.replace(/\s*const\s+t\s*=\s*useTranslations\(['"]Count['"]\);\n/,""),o=o.replace(/\{t\('currentCount',\s*\{\s*count:\s*value\s*\}\)\}/g,"Current Count: {value}"),o=o.replace(/\{t\(['"]increment['"]\)\}/g,"Increment"),o=o.replace(/\{t\(['"]decrement['"]\)\}/g,"Decrement"),o=o.replace(/\{t\(['"]reset['"]\)\}/g,"Reset"),await g(t,o)}let r=B.join(e,"src/features/counter/components/Counter.test.tsx"),n=B.join(e,"test/test-utils.tsx");await E(r),await E(n)};S();P();import pe from"node:path";var en=async(e,t)=>{t.httpClient!=="none"||t.reactSecureStorage||await w(pe.join(e,c.STORAGE_SERVICE))},tn=async e=>{await E(pe.join(e,c.LICENSE))},rn=async e=>{await E(pe.join(e,c.CHANGELOG))},nn=async e=>{await E(pe.join(e,c.NVM_RC)),await E(pe.join(e,c.NPM_RC))},on=async e=>{await w(pe.join(e,c.CLAUDE_DIR)),await w(pe.join(e,c.DOCS_DIR)),await w(pe.join(e,c.VSCODE_DIR))};import sn from"node:path";S();P();var an=async(e,t)=>{if(t.reactCompiler)return;let r=sn.join(e,c.NEXT_CONFIG);if(m(r)){let n=await f(r);n=n.replace(/^\s*reactCompiler:\s*true,?\n/m,""),await g(r,n)}await _(sn.join(e,c.PACKAGE_JSON),n=>(n.devDependencies&&delete n.devDependencies[T.REACT_COMPILER_BABEL],n))};S();P();import Pe from"node:path";var cn=async(e,t)=>{t.redux||(await w(Pe.join(e,c.STORE)),await w(Pe.join(e,c.COUNTER_FEATURE)),await E(Pe.join(e,c.STORE_PROVIDER)),await E(Pe.join(e,"test/test-utils.tsx")),await Ms(e),await Gs(e))},Ms=async e=>{let t=Pe.join(e,c.PROVIDERS_INDEX),r=await f(t);r=r.replace(/export \* from '\.\/StoreProvider';\n/,""),await g(t,r)},Gs=async e=>{let t=[Pe.join(e,c.ROOT_PAGE),Pe.join(e,c.LOCALE_PAGE)];for(let r of t)if(m(r)){let n=await f(r);n=n.replace(/import\s+\{\s*Counter\s*\}\s+from\s+['"]@\/features\/counter['"];\n?/,""),n=n.replace(/<Counter\s*\/>\n?/g,""),await g(r,n)}};import ft from"node:path";S();P();var Hs=[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],pn=async(e,t)=>{t.tests||(await E(ft.join(e,c.VITEST_CONFIG)),await w(ft.join(e,c.TEST_DIR)),await E(ft.join(e,"src/features/counter/components/Counter.test.tsx")),await _(ft.join(e,c.PACKAGE_JSON),r=>{if(r.devDependencies)for(let n of Hs)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}))};var ln=async(e,t)=>{let r=b("Customizing features...");try{await Zr(e,t),await en(e,t),await cn(e,t),await Yr(e,t),await Wr(e,t),await Qr(e,t),await an(e,t),await pn(e,t),await tn(e),await rn(e),await nn(e),await on(e),t.tests&&await ce(e,{redux:t.redux,i18n:t.i18n}),r.succeed("Features customized.")}catch(n){throw r.fail("Failed to customize features."),n}};import Us from"node:path";S();P();var mn=async(e,t)=>{let r=b("Configuring package.json...");try{let n=t.gitRemote,o=t.gitHomepage,i=t.gitIssues;t.gitRemote&&(t.gitRemote.startsWith("git@github.com:")&&(n=t.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"")),o||(o=`${n.replace(/\.git$/,"")}#readme`),i||(i=`${n.replace(/\.git$/,"")}/issues`),n.endsWith(".git")||(n=`${n}.git`)),await _(Us.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?(o&&(s.homepage=o),i&&(s.bugs={url:i}),n&&(s.repository={type:"git",url:n})):(delete s.homepage,delete s.bugs,delete s.repository),t.redux||(delete s.dependencies[T.REDUX_TOOLKIT],delete s.dependencies[T.REACT_REDUX],delete s.dependencies[T.REDUX],delete s.dependencies[T.REDUX_PERSIST]),t.httpClient!=="none"||t.reactSecureStorage||delete s.dependencies[T.REACT_SECURE_STORAGE],t.i18n||delete s.dependencies[T.NEXT_INTL],t.darkMode||delete s.dependencies[T.NEXT_THEMES],t.httpClient==="none"?delete s.dependencies[T.AXIOS]:t.httpClient==="fetch"&&delete s.dependencies[T.AXIOS],s)),r.succeed("package.json configured.")}catch(n){throw r.fail("Failed to configure package.json."),n}};import{readdir as dn}from"node:fs/promises";import N from"node:path";S();P();var un=async(e,t)=>{await zs(e,t),await Js(e,t),await Vs(e,t),await Bs(e,t),await qs(e,t),await Xs(e,t),await Ws(e,t)},zs=async(e,t)=>{t.preCommitHooks||(await w(N.join(e,c.HUSKY_DIR)),await E(N.join(e,c.COMMITLINT_CONFIG)),await E(N.join(e,c.LINTSTAGED_RC)),await _(N.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)))},Js=async(e,t)=>{t.commitizen||(await E(N.join(e,c.CZRC)),await _(N.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)))},Vs=async(e,t)=>{t.ci||await w(N.join(e,c.GITHUB_WORKFLOWS))},Bs=async(e,t)=>{let r=N.join(e,c.GITHUB_DIR);if(!t.keepTemplates)await w(N.join(r,c.GITHUB_ISSUE_TEMPLATE)),await E(N.join(r,c.GITHUB_PR_TEMPLATE));else{let n=N.join(r,c.GITHUB_ISSUE_TEMPLATE),o=N.join(r,c.GITHUB_PR_TEMPLATE),i=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(o)){let s=await f(o);s=i(s),await g(o,s)}try{if(m(n)){let s=await dn(n);for(let a of s){let p=N.join(n,a),u=await f(p);u=i(u),await g(p,u)}}}catch{}}},qs=async(e,t)=>{let r=[c.CODE_OF_CONDUCT,c.CONTRIBUTING,c.SECURITY];for(let n of r)t.communityFiles.includes(n)||await E(N.join(e,n))},Xs=async(e,t)=>{if(t.docker){let r=N.join(e,c.ENV_EXAMPLE);if(m(r)){let n=await f(r),o=(i,s)=>{let a=new RegExp(`${i}=.*`);a.test(n)?n=n.replace(a,`${i}=${s}`):n+=`${i}=${s}
178
- `};o("CONTAINER_NAME",t.containerName||"next-app"),o("IMAGE_NAME",t.imageName||"nextjs-starter"),o("IMAGE_TAG",t.imageTag||"latest"),await g(r,n)}}else{await E(N.join(e,c.DOCKERFILE)),await E(N.join(e,c.DOCKER_COMPOSE)),await E(N.join(e,c.DOCKERIGNORE));let r=N.join(e,c.ENV_EXAMPLE);if(m(r)){let n=await f(r);n=n.replace(/# Docker Compose Configuration\n/,""),n=n.replace(/CONTAINER_NAME=.*\n/,""),n=n.replace(/IMAGE_NAME=.*\n/,""),n=n.replace(/IMAGE_TAG=.*\n/,""),await g(r,n)}}},Ws=async(e,t)=>{let r=async i=>{let s=await dn(i,{withFileTypes:!0}),a=[];for(let p of s){let u=N.join(i,p.name);p.isDirectory()&&p.name!=="node_modules"&&p.name!==".git"?a.push(...await r(u)):p.isFile()&&p.name.toLowerCase()==="readme.md"&&a.push(u)}return a},n=await r(e),o=N.join(e,c.README);for(let i of n)i!==o&&await E(i);if(t.readme){let i=`# ${t.projectName}
189
+ `;import cn from"node:path";var T={REDUX_TOOLKIT:"@reduxjs/toolkit",REACT_REDUX:"react-redux",REDUX:"redux",REDUX_PERSIST:"redux-persist",REACT_SECURE_STORAGE:"react-secure-storage",NEXT_INTL:"next-intl",NEXT_THEMES:"@teispace/next-themes",AXIOS:"axios",HUSKY:"husky",COMMITLINT_CLI:"@commitlint/cli",COMMITLINT_CONFIG:"@commitlint/config-conventional",LINT_STAGED:"lint-staged",COMMITIZEN:"commitizen",CZ_CONVENTIONAL_CHANGELOG:"cz-conventional-changelog",VITEST:"vitest",JSDOM:"jsdom",VITE_PLUGIN_REACT:"@vitejs/plugin-react",TESTING_LIBRARY_DOM:"@testing-library/dom",TESTING_LIBRARY_JEST_DOM:"@testing-library/jest-dom",TESTING_LIBRARY_REACT:"@testing-library/react",TESTING_LIBRARY_USER_EVENT:"@testing-library/user-event",REACT_COMPILER_BABEL:"babel-plugin-react-compiler",NEXT_BUNDLE_ANALYZER:"@next/bundle-analyzer"};S();P();var pn=async(e,t)=>{if(t.bundleAnalyzer)return;let r=cn.join(e,c.NEXT_CONFIG);if(m(r)){let n=await f(r);n=n.replace(/import\s+withBundleAnalyzer\s+from\s+'@next\/bundle-analyzer';\n/,""),n=n.replace(/const\s+bundleAnalyzer\s*=\s*withBundleAnalyzer\(\{[\s\S]*?\}\);\n+/,""),n=n.replace(/bundleAnalyzer\(([^)]*)\)/,"$1"),await g(r,n)}await D(cn.join(e,c.PACKAGE_JSON),n=>(n.devDependencies&&delete n.devDependencies[T.NEXT_BUNDLE_ANALYZER],n.scripts&&delete n.scripts.analyze,n))};S();P();import Me from"node:path";var ln=async(e,t)=>{t.darkMode||(await E(Me.join(e,c.THEME_PROVIDER)),await Zs(e),await Qs(e),await ta(e))},Zs=async e=>{let t=Me.join(e,c.PROVIDERS_INDEX),r=await f(t);r=r.replace(/export \* from '\.\/CustomThemeProvider';\n/,""),await g(t,r)},Qs=async e=>{let t=Me.join(e,c.GLOBALS_CSS);if(m(t)){let r=await f(t);r=r.replace(/@custom-variant dark \(.*?\);\n\n/,""),r=r.replace(/@theme \{[\s\S]*?\}\n/,""),await g(t,r)}},ea=e=>e.replace(/\bbg-light\b\s?/g,"").replace(/\bdark:bg-dark\b\s?/g,"").replace(/\s{2,}/g," ").replace(/suppressHydrationWarning=\{true\}/g,""),ta=async e=>{let t=[Me.join(e,c.ROOT_LAYOUT),Me.join(e,"src/app/[locale]/layout.tsx")];for(let r of t)if(m(r)){let n=await f(r),i=ea(n);i!==n&&await g(r,i)}};S();P();Ue();import _ from"node:path";var hn=async(e,t)=>{let r=_.join(e,c.HTTP_UTILS),n=t.httpClient!=="none"||!!t.reactSecureStorage;t.httpClient==="none"?(await He(e),await aa(e,r,n)):t.httpClient==="axios"?(await ca(e,r),await Ne(e,["axios"]),await ke(e,["axios"])):t.httpClient==="fetch"?(await pa(e,r),await Ne(e,["fetch"]),await ke(e,["fetch"])):t.httpClient},aa=async(e,t,r)=>{await w(_.join(e,c.AXIOS_CLIENT)),await w(_.join(e,c.FETCH_CLIENT)),r?(await g(_.join(t,"index.ts"),`export * from './token-store';
190
+ `),await E(_.join(e,c.CLIENT_UTILS)),await Ie(e,[])):(await w(t),await la(e),await E(_.join(e,c.APP_APIS)),await ma(e)),await da(e),await w(_.join(e,c.ERRORS_DIR)),r||(await w(_.join(e,c.COMMON_TYPES_DIR)),await w(_.join(e,c.UTILITY_TYPES_DIR)),await ua(e))},ca=async(e,t)=>{await w(_.join(e,c.FETCH_CLIENT));let r=await f(_.join(t,"index.ts"));r=r.replace(/export .* from '\.\/fetch-client';\n/g,""),await g(_.join(t,"index.ts"),r);let n=_.join(e,c.HTTP_TYPES);if(m(n)){let i=await f(n);i=i.replace(/export interface FetchClientOptions \{[\s\S]*?\}\n\n/,""),i=i.replace(/export interface ExtendedRequestInit extends RequestInit \{[\s\S]*?\}\n\n/,""),await g(n,i)}},pa=async(e,t)=>{await w(_.join(e,c.AXIOS_CLIENT));let r=await f(_.join(t,"index.ts"));r=r.replace(/export .* from '\.\/axios-client';\n/g,""),await g(_.join(t,"index.ts"),r),await Ie(e,["fetch"]);let n=_.join(e,c.HTTP_TYPES);if(m(n)){let i=await f(n);i=i.replace(/export interface AxiosClientOptions \{[\s\S]*?\}\n\n/,""),await g(n,i)}},la=async e=>{let t=_.join(e,c.UTILS_INDEX);if(m(t)){let r=await f(t);r=r.replace(/export \* from '\.\/http';\n/,""),await g(t,r)}},ma=async e=>{let t=_.join(e,c.CONFIG_INDEX);if(m(t)){let r=await f(t);r=r.replace(/export \* from '\.\/app-apis';\n/,""),await g(t,r)}},da=async e=>{let t=_.join(e,c.CONSTANTS);if(m(t)){let r=await f(t);r=r.replace(/export const API_RESPONSE_DATA_KEY = 'data';\n/,""),r=r.replace(/export const SAVE_AUTH_TOKENS = false;\n/,""),await g(t,r)}},ua=async e=>{let t=_.join(e,c.TYPES_INDEX);if(m(t)){let r=await f(t);r=r.replace(/export \* from '\.\/utility';\n/,""),r=r.replace(/export \* from '\.\/common';\n/,""),await g(t,r)}};S();P();import W from"node:path";var yn=async(e,t)=>{t.i18n||(await ga(e),await ha(e),await ya(e),await xa(e),await fa(e))},fa=async e=>{let t=W.join(e,c.ENV_EXAMPLE);if(!m(t))return;let r=await f(t);r=r.replace(/#[^\n]*IANA time zone[\s\S]*?DEFAULT_TIMEZONE=[^\n]*\n?/,""),r=r.replace(/#[^\n]*Fallback locale[\s\S]*?DEFAULT_LOCALE=[^\n]*\n?/,""),r=r.replace(/^DEFAULT_TIMEZONE=.*\n?/m,""),r=r.replace(/^DEFAULT_LOCALE=.*\n?/m,""),await g(t,r)},ga=async e=>{await w(W.join(e,c.I18N_DIR)),await w(W.join(e,c.LOCALE_DIR)),await E(W.join(e,c.PROXY)),await E(W.join(e,c.MIDDLEWARE)),await E(W.join(e,c.I18N_TYPES)),await E(W.join(e,c.APP_LOCALES))},ha=async e=>{let t=W.join(e,c.TYPES_INDEX);if(m(t)){let n=await f(t);n=n.replace(/export \* from '\.\/i18n';\n/,""),await g(t,n)}let r=W.join(e,c.CONFIG_INDEX);if(m(r)){let n=await f(r);n=n.replace(/export \* from '\.\/app-locales';\n/,""),await g(r,n)}},ya=async e=>{let t=W.join(e,c.NEXT_CONFIG);if(m(t)){let r=await f(t);r=r.replace(/import createNextIntlPlugin from 'next-intl\/plugin';\n/,""),r=r.replace(/const withNextIntl = createNextIntlPlugin\(\);\n+/,""),r=r.replace(/withNextIntl\(([^)]+)\)/,"$1"),await g(t,r)}},xa=async e=>{let t=W.join(e,c.COUNTER_COMPONENT);if(m(t)){let i=await f(t);i=i.replace(/import\s+\{\s*useTranslations\s*\}\s+from\s+['"]next-intl['"];\n/,""),i=i.replace(/\s*const\s+t\s*=\s*useTranslations\(['"]Count['"]\);\n/,""),i=i.replace(/\{t\('currentCount',\s*\{\s*count:\s*value\s*\}\)\}/g,"Current Count: {value}"),i=i.replace(/\{t\(['"]increment['"]\)\}/g,"Increment"),i=i.replace(/\{t\(['"]decrement['"]\)\}/g,"Decrement"),i=i.replace(/\{t\(['"]reset['"]\)\}/g,"Reset"),await g(t,i)}let r=W.join(e,"src/features/counter/components/Counter.test.tsx"),n=W.join(e,"test/test-utils.tsx");await E(r),await E(n)};S();P();import pe from"node:path";var xn=async(e,t)=>{t.httpClient!=="none"||t.reactSecureStorage||await w(pe.join(e,c.STORAGE_SERVICE))},Pn=async e=>{await E(pe.join(e,c.LICENSE))},wn=async e=>{await E(pe.join(e,c.CHANGELOG))},vn=async e=>{await E(pe.join(e,c.NVM_RC)),await E(pe.join(e,c.NPM_RC))},Sn=async e=>{await w(pe.join(e,c.CLAUDE_DIR)),await w(pe.join(e,c.DOCS_DIR)),await w(pe.join(e,c.VSCODE_DIR))};import Cn from"node:path";S();P();var En=async(e,t)=>{if(t.reactCompiler)return;let r=Cn.join(e,c.NEXT_CONFIG);if(m(r)){let n=await f(r);n=n.replace(/^\s*reactCompiler:\s*true,?\n/m,""),await g(r,n)}await D(Cn.join(e,c.PACKAGE_JSON),n=>(n.devDependencies&&delete n.devDependencies[T.REACT_COMPILER_BABEL],n))};S();P();import Pe from"node:path";var Tn=async(e,t)=>{t.redux||(await w(Pe.join(e,c.STORE)),await w(Pe.join(e,c.COUNTER_FEATURE)),await E(Pe.join(e,c.STORE_PROVIDER)),await E(Pe.join(e,"test/test-utils.tsx")),await Pa(e),await wa(e))},Pa=async e=>{let t=Pe.join(e,c.PROVIDERS_INDEX),r=await f(t);r=r.replace(/export \* from '\.\/StoreProvider';\n/,""),await g(t,r)},wa=async e=>{let t=[Pe.join(e,c.ROOT_PAGE),Pe.join(e,c.LOCALE_PAGE)];for(let r of t)if(m(r)){let n=await f(r);n=n.replace(/import\s+\{\s*Counter\s*\}\s+from\s+['"]@\/features\/counter['"];\n?/,""),n=n.replace(/<Counter\s*\/>\n?/g,""),await g(r,n)}};S();P();import bn from"node:path";var Rn=async(e,t)=>{if(t.i18n)return;let r=bn.join(e,c.SEO_FILE);m(r)&&await g(r,va);let n=bn.join(e,c.SITEMAP_FILE);m(n)&&await g(n,Sa)},va=`import type { Metadata } from 'next';
191
+
192
+ import { env } from '@/lib/env';
193
+
194
+ const APP_URL = env.NEXT_PUBLIC_APP_URL;
195
+ const APP_NAME = 'Nextjs Starter';
196
+
197
+ type SEOParams = {
198
+ title: string;
199
+ description: string;
200
+ path?: string;
201
+ image?: string;
202
+ noIndex?: boolean;
203
+ };
204
+
205
+ export function generateSEOMetadata({
206
+ title,
207
+ description,
208
+ path = '',
209
+ image,
210
+ noIndex = false,
211
+ }: SEOParams): Metadata {
212
+ const url = \`\${APP_URL}\${path}\`;
213
+ const ogImage = image || \`\${APP_URL}/og-image.png\`;
214
+
215
+ return {
216
+ title,
217
+ description,
218
+ metadataBase: new URL(APP_URL),
219
+ alternates: {
220
+ canonical: url,
221
+ },
222
+ openGraph: {
223
+ type: 'website',
224
+ title,
225
+ description,
226
+ url,
227
+ siteName: APP_NAME,
228
+ images: [
229
+ {
230
+ url: ogImage,
231
+ width: 1200,
232
+ height: 630,
233
+ alt: title,
234
+ },
235
+ ],
236
+ locale: 'en_US',
237
+ },
238
+ twitter: {
239
+ card: 'summary_large_image',
240
+ title,
241
+ description,
242
+ images: [ogImage],
243
+ },
244
+ robots: noIndex
245
+ ? { index: false, follow: false }
246
+ : {
247
+ index: true,
248
+ follow: true,
249
+ 'max-video-preview': -1,
250
+ 'max-image-preview': 'large' as const,
251
+ 'max-snippet': -1,
252
+ },
253
+ };
254
+ }
255
+
256
+ export { APP_NAME, APP_URL };
257
+ `,Sa=`import type { MetadataRoute } from 'next';
258
+
259
+ import { env } from '@/lib/env';
260
+
261
+ const APP_URL = env.NEXT_PUBLIC_APP_URL;
262
+
263
+ export default function sitemap(): MetadataRoute.Sitemap {
264
+ const paths = ['/'];
265
+
266
+ return paths.map((path) => ({
267
+ url: \`\${APP_URL}\${path}\`,
268
+ lastModified: new Date(),
269
+ changeFrequency: 'monthly' as const,
270
+ priority: path === '/' ? 1 : 0.8,
271
+ }));
272
+ }
273
+ `;import St from"node:path";S();P();var Ca=[T.VITEST,T.JSDOM,T.VITE_PLUGIN_REACT,T.TESTING_LIBRARY_DOM,T.TESTING_LIBRARY_JEST_DOM,T.TESTING_LIBRARY_REACT,T.TESTING_LIBRARY_USER_EVENT],$n=async(e,t)=>{t.tests||(await E(St.join(e,c.VITEST_CONFIG)),await w(St.join(e,c.TEST_DIR)),await E(St.join(e,"src/features/counter/components/Counter.test.tsx")),await D(St.join(e,c.PACKAGE_JSON),r=>{if(r.devDependencies)for(let n of Ca)delete r.devDependencies[n];return r.scripts&&(delete r.scripts.test,delete r.scripts["test:watch"],delete r.scripts["test:coverage"],typeof r.scripts.validate=="string"&&(r.scripts.validate=r.scripts.validate.replace(/\s*&&\s*yarn\s+test(?![:\w])/,"").replace(/\byarn\s+test(?![:\w])\s*&&\s*/,""))),r}))};S();P();import Je from"node:path";S();P();import In from"node:path";import{readFile as Ea,writeFile as Ta}from"node:fs/promises";import ba from"node:path";var Be=(e,t)=>{let r=/import\s+.*\s+from\s+['"].*['"];?\n/g,n=e.match(r);if(n&&n.length>0){let i=n[n.length-1],o=e.lastIndexOf(i);return e.slice(0,o+i.length)+t+`
274
+ `+e.slice(o+i.length)}return`${t}
275
+ ${e}`},Qt=(e,t,r)=>{let n=/combineReducers\(\{([^}]*)\}\)/s,i=e.match(n);if(!i)throw new Error("Could not find combineReducers in rootReducer.ts");let o=i[1],s=`
276
+ ${t}: ${r},`,a=o.trimEnd()+s;return e.replace(n,`combineReducers({${a}
277
+ })`)},ze=(e,t)=>{let r=e.lastIndexOf("} as const;");if(r===-1)throw new Error("Could not find closing brace of AppApis object");let n=e.substring(0,r),i=e.substring(r);return`${n.trimEnd()}
278
+ ${t}
279
+ ${i}`};var we=async e=>{let{projectPath:t,name:r,persist:n,importPath:i}=e,o=ba.join(t,"src","store","rootReducer.ts");try{let s=await Ea(o,"utf-8"),a=j(r),p=`${a}Reducer`,u=`${a}PersistConfig`,d=i.replace(/^src\//,"@/"),h=n?`import { ${p}, ${u} } from '${d}';`:`import { ${p} } from '${d}';`;s=Be(s,h);let x=n?`persistReducer(${u}, ${p})`:p;s=Qt(s,a,x),await Ta(o,s)}catch(s){throw new Error(`Failed to register reducer '${r}' in rootReducer: ${s}`,{cause:s})}};var Nn="import { attachWsBridge, wsClient } from '@/lib/utils/ws';",Ra=`
280
+ // Bridge the WS client's lifecycle into the Redux slice exactly once per
281
+ // store instance. The bridge does not open a connection \u2014 that happens
282
+ // lazily on first \`useWsEvent\` subscription or an explicit \`connect()\`.
283
+ // Effect runs in the browser only, so the SSR boundary is safe.
284
+ useEffect(() => {
285
+ const store = storeRef.current;
286
+ if (!store) return;
287
+ return attachWsBridge(wsClient, store.dispatch);
288
+ }, []);
289
+ `,kn=async e=>{await we({projectPath:e,name:"ws",persist:!1,importPath:"src/store/slices/ws.slice"})},$a=e=>{if(e.includes("from '@/lib/utils/ws'"))return e;let t=e,r=/(^import\s[^\n]*\n)+/m,n=t.match(r);if(!n)throw new Error("injectBridgeMount: no `import` lines found \u2014 expected a StoreProvider with imports.");let i=(n.index??0)+n[0].length;t=`${t.slice(0,i)}${Nn}
290
+ ${t.slice(i)}`,t=Aa(t);let o=/(if\s*\(\s*!storeRef\.current\s*\)\s*\{[\s\S]*?\n\s*\})/;if(!t.match(o))throw new Error("injectBridgeMount: could not locate `if (!storeRef.current) { ... }` initializer \u2014 StoreProvider shape unexpected.");return t=t.replace(o,`$1
291
+ ${Ra.trimEnd()}
292
+ `),t},Ct=e=>{let t=e;return t=t.replace(new RegExp(`${_a(Nn)}\\n?`),""),t=t.replace(/\n(?:[ \t]*\/\/[^\n]*\n)*[ \t]*useEffect\(\(\)\s*=>\s*\{[\s\S]*?attachWsBridge\(wsClient,\s*store\.dispatch\)[\s\S]*?\},\s*\[\]\);\n?/,`
293
+ `),/\buseEffect\s*\(/.test(t)||(t=Ia(t)),t},Ia=e=>{let t=/import\s*\{([^}]*)\}\s*from\s*['"]react['"];\n?/,r=e.match(t);if(!r)return e;let n=r[1].split(",").map(o=>o.trim()).filter(o=>o.length>0&&o!=="useEffect");if(n.length===0)return e.replace(t,"");let i=`import { ${n.join(", ")} } from 'react';
294
+ `;return e.replace(t,i)},An=async e=>{let t=In.join(e,c.STORE_PROVIDER);if(!m(t))return;let r=await f(t),n=$a(r);n!==r&&await g(t,n)};var _n=async e=>{let t=In.join(e,c.TEST_SETUP_FILE);if(!m(t))return;let r=await f(t),n=!1;r.includes("vi.mock('react-secure-storage'")||(r+=Na,n=!0),r.includes("vi.mock('server-only'")||(r+=ka,n=!0),n&&await g(t,r)},Na=`
295
+ // \`react-secure-storage\` constructs an \`EncryptionService\` at module load
296
+ // that fingerprints the browser via \`<canvas>.getContext\`. jsdom doesn't
297
+ // implement canvas, so the import explodes anywhere it's pulled in
298
+ // transitively (HTTP token store, WS auth carrier, etc.). Stub it globally \u2014
299
+ // tests that need real behaviour are integration tests, not unit tests.
300
+ vi.mock('react-secure-storage', () => {
301
+ const store = new Map<string, unknown>();
302
+ return {
303
+ default: {
304
+ setItem: (k: string, v: unknown) => store.set(k, v),
305
+ getItem: (k: string) => store.get(k) ?? null,
306
+ removeItem: (k: string) => store.delete(k),
307
+ clear: () => store.clear(),
308
+ },
309
+ };
310
+ });
311
+ `,ka=`
312
+ // \`server-only\` throws at module load outside a Next.js server bundle \u2014
313
+ // the package relies on bundler-level redirect to a no-op file in server
314
+ // environments. Vitest doesn't do that redirect, so we stub it as a no-op
315
+ // to let unit tests reach the server-side modules. Production builds are
316
+ // unaffected; Next.js still routes \`server-only\` to its real implementation.
317
+ vi.mock('server-only', () => ({}));
318
+ `,Aa=e=>{let t=/import\s*\{([^}]*)\}\s*from\s*['"]react['"];/,r=e.match(t);if(!r)return e;let n=r[1];if(/\buseEffect\b/.test(n))return e;let i=n.split(",").map(s=>s.trim()).filter(Boolean);i.push("useEffect"),i.sort();let o=`import { ${i.join(", ")} } from 'react';`;return e.replace(t,o)},_a=e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),Et=e=>{let t=e;return t=t.replace(/^import\s*\{\s*wsReducer\s*\}\s*from\s*['"][^'"]*ws\.slice['"];\n?/m,""),t=t.replace(/^\s*ws:\s*wsReducer,?\n/m,""),t=t.replace(/\/\*\*[^*]*(?:\*(?!\/)[^*]*)*\bws\b[^*]*(?:\*(?!\/)[^*]*)*\bpersistReducer\b[\s\S]*?\*\/\n?/,""),t};var On=async(e,t)=>{t.ws||(await w(Je.join(e,c.WS_UTILS)),await E(Je.join(e,c.WS_SLICE_FILE)),t.redux&&(await Oa(e),await Fa(e)),await ja(e))},Oa=async e=>{let t=Je.join(e,c.ROOT_REDUCER);if(!m(t))return;let r=await f(t),n=Et(r);n!==r&&await g(t,n)},Fa=async e=>{let t=Je.join(e,c.STORE_PROVIDER);if(!m(t))return;let r=await f(t),n=Ct(r);n!==r&&await g(t,n)},ja=async e=>{let t=Je.join(e,c.PACKAGE_JSON);if(!m(t))return;let r=JSON.parse(await f(t));({...r.dependencies,...r.devDependencies})["socket.io-client"]&&await $e(e,"socket.io-client")};var Fn=async(e,t)=>{let r=b("Customizing features...");try{await hn(e,t),await xn(e,t),await On(e,t),await Tn(e,t),await ln(e,t),await pn(e,t),await yn(e,t),await Rn(e,t),await En(e,t),await $n(e,t),await Pn(e),await wn(e),await vn(e),await Sn(e),t.tests&&await ce(e,{redux:t.redux,i18n:t.i18n}),r.succeed("Features customized.")}catch(n){throw r.fail("Failed to customize features."),n}};import Da from"node:path";S();P();var jn=async(e,t)=>{let r=b("Configuring package.json...");try{let n=t.gitRemote,i=t.gitHomepage,o=t.gitIssues;t.gitRemote&&(t.gitRemote.startsWith("git@github.com:")&&(n=t.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"")),i||(i=`${n.replace(/\.git$/,"")}#readme`),o||(o=`${n.replace(/\.git$/,"")}/issues`),n.endsWith(".git")||(n=`${n}.git`)),await D(Da.join(e,c.PACKAGE_JSON),s=>(s.name=t.projectName,s.version=t.version,s.description=t.description,s.author=t.author,delete s.packageManager,t.gitRemote?(i&&(s.homepage=i),o&&(s.bugs={url:o}),n&&(s.repository={type:"git",url:n})):(delete s.homepage,delete s.bugs,delete s.repository),t.redux||(delete s.dependencies[T.REDUX_TOOLKIT],delete s.dependencies[T.REACT_REDUX],delete s.dependencies[T.REDUX],delete s.dependencies[T.REDUX_PERSIST]),t.httpClient!=="none"||t.reactSecureStorage||delete s.dependencies[T.REACT_SECURE_STORAGE],t.i18n||delete s.dependencies[T.NEXT_INTL],t.darkMode||delete s.dependencies[T.NEXT_THEMES],t.httpClient==="none"?delete s.dependencies[T.AXIOS]:t.httpClient==="fetch"&&delete s.dependencies[T.AXIOS],s)),r.succeed("package.json configured.")}catch(n){throw r.fail("Failed to configure package.json."),n}};import{readdir as Dn}from"node:fs/promises";import O from"node:path";S();P();var Ln=async(e,t)=>{await La(e,t),await Ma(e,t),await Ga(e,t),await Ha(e,t),await Ua(e,t),await Ba(e,t),await za(e,t)},La=async(e,t)=>{t.preCommitHooks||(await w(O.join(e,c.HUSKY_DIR)),await E(O.join(e,c.COMMITLINT_CONFIG)),await E(O.join(e,c.LINTSTAGED_RC)),await D(O.join(e,c.PACKAGE_JSON),r=>(delete r.devDependencies[T.HUSKY],delete r.devDependencies[T.COMMITLINT_CLI],delete r.devDependencies[T.COMMITLINT_CONFIG],delete r.devDependencies[T.LINT_STAGED],delete r.scripts.prepare,delete r.scripts.postinstall,delete r.commitlint,delete r["lint-staged"],r)))},Ma=async(e,t)=>{t.commitizen||(await E(O.join(e,c.CZRC)),await D(O.join(e,c.PACKAGE_JSON),r=>(delete r.devDependencies[T.COMMITIZEN],delete r.devDependencies[T.CZ_CONVENTIONAL_CHANGELOG],delete r.config?.commitizen,r.config&&Object.keys(r.config).length===0&&delete r.config,delete r.scripts.commit,r)))},Ga=async(e,t)=>{t.ci||await w(O.join(e,c.GITHUB_WORKFLOWS))},Ha=async(e,t)=>{let r=O.join(e,c.GITHUB_DIR);if(!t.keepTemplates)await w(O.join(r,c.GITHUB_ISSUE_TEMPLATE)),await E(O.join(r,c.GITHUB_PR_TEMPLATE));else{let n=O.join(r,c.GITHUB_ISSUE_TEMPLATE),i=O.join(r,c.GITHUB_PR_TEMPLATE),o=s=>s.replace(/Teispace/g,t.company).replace(/support@teispace\.com/g,t.email).replace(/Next\.js Starter/g,t.projectName).replace(/\[AUTHOR\]/g,t.author).replace(/\[COMPANY\]/g,t.company).replace(/\[EMAIL\]/g,t.email);if(m(i)){let s=await f(i);s=o(s),await g(i,s)}try{if(m(n)){let s=await Dn(n);for(let a of s){let p=O.join(n,a),u=await f(p);u=o(u),await g(p,u)}}}catch{}}},Ua=async(e,t)=>{let r=[c.CODE_OF_CONDUCT,c.CONTRIBUTING,c.SECURITY];for(let n of r)t.communityFiles.includes(n)||await E(O.join(e,n))},Ba=async(e,t)=>{if(t.docker){let r=O.join(e,c.ENV_EXAMPLE);if(m(r)){let n=await f(r),i=(o,s)=>{let a=new RegExp(`${o}=.*`);a.test(n)?n=n.replace(a,`${o}=${s}`):n+=`${o}=${s}
319
+ `};i("CONTAINER_NAME",t.containerName||"next-app"),i("IMAGE_NAME",t.imageName||"nextjs-starter"),i("IMAGE_TAG",t.imageTag||"latest"),await g(r,n)}}else{await E(O.join(e,c.DOCKERFILE)),await E(O.join(e,c.DOCKER_COMPOSE)),await E(O.join(e,c.DOCKERIGNORE));let r=O.join(e,c.ENV_EXAMPLE);if(m(r)){let n=await f(r);n=n.replace(/# Docker Compose Configuration\n/,""),n=n.replace(/CONTAINER_NAME=.*\n/,""),n=n.replace(/IMAGE_NAME=.*\n/,""),n=n.replace(/IMAGE_TAG=.*\n/,""),await g(r,n)}}},za=async(e,t)=>{let r=async o=>{let s=await Dn(o,{withFileTypes:!0}),a=[];for(let p of s){let u=O.join(o,p.name);p.isDirectory()&&p.name!=="node_modules"&&p.name!==".git"?a.push(...await r(u)):p.isFile()&&p.name.toLowerCase()==="readme.md"&&a.push(u)}return a},n=await r(e),i=O.join(e,c.README);for(let o of n)o!==i&&await E(o);if(t.readme){let o=`# ${t.projectName}
179
320
 
180
321
  ${t.description}
181
322
 
@@ -188,13 +329,13 @@ ${t.packageManager==="npm"?"npm run dev":`${t.packageManager} dev`}
188
329
  \`\`\`
189
330
 
190
331
  Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
191
- `;await g(o,i)}else await E(o)};S();P();import Ht from"node:path";var fn=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;"],o=["children"];t.i18n&&(n.push("locale: SupportedLocale;"),n.push("messages: AbstractIntlMessages;"),n.push("timeZone: string;"),o.push("locale","messages","timeZone")),t.redux&&(n.push("preloadedState?: Partial<AppState>;"),o.push("preloadedState"));let i="{children}";t.i18n&&(i=`<NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>
192
- ${i}
193
- </NextIntlClientProvider>`),t.darkMode&&(i=`<CustomThemeProvider>
194
- ${i}
195
- </CustomThemeProvider>`),t.redux&&(i=`<StoreProvider preloadedState={preloadedState}>
196
- ${i}
197
- </StoreProvider>`),i==="{children}"&&(i="<>{children}</>");let s=`type RootProviderProps = {
332
+ `;await g(i,o)}else await E(i)};S();P();import er from"node:path";var Mn=async(e,t)=>{let r=[];t.i18n&&r.push("import { type AbstractIntlMessages, NextIntlClientProvider } from 'next-intl';"),t.darkMode&&r.push("import { CustomThemeProvider } from '@/providers';"),t.redux&&r.push("import type { AppState } from '@/store';"),t.i18n&&r.push("import type { SupportedLocale } from '@/types/i18n';"),t.redux&&r.push("import { StoreProvider } from './StoreProvider';");let n=["children: React.ReactNode;"],i=["children"];t.i18n&&(n.push("locale: SupportedLocale;"),n.push("messages: AbstractIntlMessages;"),n.push("timeZone: string;"),i.push("locale","messages","timeZone")),t.redux&&(n.push("preloadedState?: Partial<AppState>;"),i.push("preloadedState"));let o="{children}";t.i18n&&(o=`<NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>
333
+ ${o}
334
+ </NextIntlClientProvider>`),t.darkMode&&(o=`<CustomThemeProvider>
335
+ ${o}
336
+ </CustomThemeProvider>`),t.redux&&(o=`<StoreProvider preloadedState={preloadedState}>
337
+ ${o}
338
+ </StoreProvider>`),o==="{children}"&&(o="<>{children}</>");let s=`type RootProviderProps = {
198
339
  ${n.join(`
199
340
  `)}
200
341
  };`,a=`'use client';
@@ -203,15 +344,18 @@ ${r.join(`
203
344
 
204
345
  ${s}
205
346
 
206
- export const RootProvider = ({ ${o.join(", ")} }: RootProviderProps) => {
347
+ export const RootProvider = ({ ${i.join(", ")} }: RootProviderProps) => {
207
348
  return (
208
- ${i}
349
+ ${o}
209
350
  );
210
351
  };
211
- `;await g(Ht.join(e,c.ROOT_PROVIDER),a)},gn=async(e,t)=>{if(t.i18n)return;let r=`\`\${livvic.variable} ${t.darkMode?"bg-light antialiased dark:bg-dark":"antialiased"}\``,n=(t.redux,""),o=`import type { Metadata } from 'next';
352
+ `;await g(er.join(e,c.ROOT_PROVIDER),a)},Gn=async(e,t)=>{if(t.i18n)return;let r=`\`\${livvic.variable} ${t.darkMode?"bg-light antialiased dark:bg-dark":"antialiased"}\``,n=(t.redux,""),i=t.httpClient!=="none",o=i?`// Regression sentinel \u2014 see file comment for what this guards.
353
+ import { HttpClientBundleSentinel } from '@/lib/utils/http/__bundle-sentinel__/client-bundle-sentinel';
354
+ `:"",s=i?`
355
+ <HttpClientBundleSentinel />`:"",a=`import type { Metadata } from 'next';
212
356
  import '@/styles/globals.css';
213
357
  import { Livvic } from 'next/font/google';
214
- import { RootProvider } from '@/providers';
358
+ ${o}import { RootProvider } from '@/providers';
215
359
 
216
360
  const livvic = Livvic({
217
361
  subsets: ['latin'],
@@ -233,32 +377,32 @@ export default function RootLayout({
233
377
  return (
234
378
  <html lang="en"${t.darkMode?" suppressHydrationWarning={true}":""}>
235
379
  <body className={${r}}>
236
- <RootProvider${n}>
380
+ <RootProvider${n}>${s}
237
381
  {children}
238
382
  </RootProvider>
239
383
  </body>
240
384
  </html>
241
385
  );
242
386
  }
243
- `;await g(Ht.join(e,c.ROOT_LAYOUT),o);let i=t.redux?`import { Counter } from '@/features/counter';
387
+ `;await g(er.join(e,c.ROOT_LAYOUT),a);let p=t.redux?`import { Counter } from '@/features/counter';
244
388
 
245
- `:"",s=t.redux?`
246
- <Counter />`:"",a=`${i}export default function Home() {
389
+ `:"",u=t.redux?`
390
+ <Counter />`:"",d=`${p}export default function Home() {
247
391
  return (
248
392
  <div className="flex min-h-screen flex-col items-center justify-center p-24">
249
393
  <h1 className="text-4xl font-bold">Welcome to ${t.projectName}</h1>
250
- <p className="mt-4 text-xl">Get started by editing src/app/page.tsx</p>${s}
394
+ <p className="mt-4 text-xl">Get started by editing src/app/page.tsx</p>${u}
251
395
  </div>
252
396
  );
253
397
  }
254
- `;await g(Ht.join(e,c.ROOT_PAGE),a)};import Ys from"degit";var hn=async e=>{let t=b("Downloading template...");try{await Ys("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 zt=["npm","yarn","pnpm","bun"],Ks=e=>{if(e!==void 0){if(!zt.includes(e))throw new Error(`Invalid --package-manager "${e}". Valid: ${zt.join(", ")}.`);return e}},yn=e=>{e.command("init").description("Initialize a new Next.js project").argument("[name]","Project name").option("-y, --yes","Skip all prompts and use the recommended production defaults").option("--package-manager <pm>",`Override the package manager (one of: ${zt.join(", ")})`).action(async(t,r)=>{try{let n=Ks(r.packageManager);await Qs(t,{yes:r.yes??!1,packageManager:n})}catch(n){v(`${n instanceof Error?n.message:n}`),process.exit(1)}})},je=async(e,t,r,n)=>{let o=b(e);n.current=o;try{let i=await r();return o.succeed(t),i}finally{n.current===o&&(n.current=null)}},Zs=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("")},Qs=async(e,t)=>{Gr();let r;t.yes?(r=Vr(e,{packageManager:t.packageManager}),l(X.cyan(`\u2728 Bootstrapping ${r.projectName} with the recommended defaults`)),l(""),Zs(r)):(l("Welcome to the Teispace Next.js App Creator!"),l(""),r=await Br(e),t.packageManager&&(r={...r,packageManager:t.packageManager}));let n=Ut.resolve(process.cwd(),r.projectName);m(n)&&(console.error(X.red(`Error: Directory ${r.projectName} already exists.`)),process.exit(1));let o={current:null},i=async()=>{if(m(n)){o.current?.stop(),o.current=null,console.log(X.yellow(`
255
- Cleaning up: Deleting directory ${r.projectName}...`));try{await w(n),console.log(X.green("Cleanup successful."))}catch(a){console.error(X.red(`Failed to clean up directory ${r.projectName}:`),a)}}},s=async()=>{console.log(X.red(`
256
- Process interrupted. Cleaning up...`)),await i(),process.exit(1)};process.on("SIGINT",s),process.on("SIGTERM",s);try{if(await hn(n),await mn(n,r),await ln(n,r),await je("Generating providers and layout...","Providers and layout generated.",async()=>{await fn(n,r),await gn(n,r)},o),await je("Setting up developer tools...","Developer tools configured.",()=>un(n,r),o),await je("Initializing Git...","Git initialized.",()=>Ur(n,r.gitRemote,r.pushToRemote),o),await je("Installing dependencies...","Dependencies installed.",()=>zr(n,r.packageManager),o),await je("Formatting and linting...","Formatted.",()=>q(n,r.packageManager,"lint:fix"),o),r.copyEnv){let a=Ut.join(n,".env.example"),p=Ut.join(n,".env");m(a)&&await(await import("node:fs/promises")).copyFile(a,p)}process.off("SIGINT",s),process.off("SIGTERM",s),l(""),l(X.green(`\u2728 Project ${r.projectName} created successfully!`)),l(""),l("To get started:"),l(X.cyan(` cd ${r.projectName}`)),l(X.cyan(` ${r.packageManager==="npm"?"npm run dev":`${r.packageManager} dev`}`)),l("")}catch(a){o.current?.fail("Failed to create project."),o.current=null,console.error(a),await i(),process.exit(1)}};import or from"node:path";import te from"picocolors";G();import{mkdir as Sn,writeFile as Bt}from"node:fs/promises";import ve from"node:path";P();var Vt=e=>{let{componentName:t,isClient:r,hasI18n:n}=e,o=e.translationNamespace||t,i=[];return(r||n)&&i.push("'use client';"),n&&i.push("import { useTranslations } from 'next-intl';"),i.push(""),i.push(`export function ${t}() {`),n?(i.push(` const t = useTranslations('${o}');`),i.push(""),i.push(" return ("),i.push(" <div>"),i.push(" <h2>{t('title')}</h2>"),i.push(" </div>"),i.push(" );")):(i.push(" return ("),i.push(" <div>"),i.push(` <h2>${t}</h2>`),i.push(" </div>"),i.push(" );")),i.push("}"),i.push(""),i.join(`
257
- `)},wn=e=>`export { ${e.componentName} } from './${e.componentName}';
258
- `;var qt=async e=>{let{name:t,projectPath:r,isClient:n,hasI18n:o,featurePath:i}=e,s=R(t);i?await na(s,r,i,n,o):await oa(s,t,r,n,o)},na=async(e,t,r,n,o)=>{let i=ve.join(t,r,"components");await Sn(i,{recursive:!0}),await Bt(ve.join(i,`${e}.tsx`),Vt({componentName:e,isClient:n,hasI18n:o}))},oa=async(e,t,r,n,o)=>{let i=ve.join(r,"src","components","common",e);await Sn(i,{recursive:!0}),await Bt(ve.join(i,`${e}.tsx`),Vt({componentName:e,isClient:n,hasI18n:o})),await Bt(ve.join(i,"index.ts"),wn({componentName:e}));let s=ve.join(r,"src","components","common","index.ts");await ia(s,`export { ${e} } from './${e}';
259
- `);let a=ve.join(r,"src","components","index.ts");await sa(a)},ia=async(e,t)=>{let r="";m(e)&&(r=await f(e)),r.includes(t.trim())||(r+=t,await g(e,r))},sa=async e=>{let t="";m(e)&&(t=await f(e));let r=`export * from './common';
260
- `;t.includes(r.trim())||(t+=r,await g(e,t))};import{writeFile as aa}from"node:fs/promises";import ca from"node:path";var Cn=e=>{let{camelName:t,pascalName:r,httpClient:n}=e,o=n==="axios"?"import { axiosClient } from '@/lib/utils/http';":"import { fetchClient } from '@/lib/utils/http';",i=n==="axios"?"axiosClient":"fetchClient";return`import { AppApis } from '@/lib/config';
261
- ${o}
398
+ `;await g(er.join(e,c.ROOT_PAGE),d)};import Ja from"degit";var Hn=async e=>{let t=b("Downloading template...");try{await Ja("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!0}).clone(e),t.succeed("Template downloaded successfully.")}catch(r){throw t.fail("Failed to download template."),r}};var rr=["npm","yarn","pnpm","bun"],Va=e=>{if(e!==void 0){if(!rr.includes(e))throw new Error(`Invalid --package-manager "${e}". Valid: ${rr.join(", ")}.`);return e}},Un=e=>{e.command("init").description("Initialize a new Next.js project").argument("[name]","Project name").option("-y, --yes","Skip all prompts and use the recommended production defaults").option("--package-manager <pm>",`Override the package manager (one of: ${rr.join(", ")})`).action(async(t,r)=>{try{let n=Va(r.packageManager);await qa(t,{yes:r.yes??!1,packageManager:n})}catch(n){v(`${n instanceof Error?n.message:n}`),process.exit(1)}})},Ve=async(e,t,r,n)=>{let i=b(e);n.current=i;try{let o=await r();return i.succeed(t),o}finally{n.current===i&&(n.current=null)}},Wa=e=>{let t=[];e.darkMode&&t.push("dark mode"),e.redux&&t.push("redux"),e.i18n&&t.push("i18n"),e.tests&&t.push("tests"),e.reactCompiler&&t.push("react-compiler"),e.preCommitHooks&&t.push("pre-commit hooks"),e.commitizen&&t.push("commitizen"),e.httpClient!=="none"&&t.push(`http (${e.httpClient})`),l(q.dim("Defaults applied (run `next-maker remove <feature>` to undo any of them):")),l(q.dim(` package manager : ${e.packageManager}`)),l(q.dim(` features : ${t.join(", ")}`)),l("")},qa=async(e,t)=>{Qr();let r;t.yes?(r=on(e,{packageManager:t.packageManager}),l(q.cyan(`\u2728 Bootstrapping ${r.projectName} with the recommended defaults`)),l(""),Wa(r)):(l("Welcome to the Teispace Next.js App Creator!"),l(""),r=await sn(e),t.packageManager&&(r={...r,packageManager:t.packageManager}));let n=tr.resolve(process.cwd(),r.projectName);m(n)&&(console.error(q.red(`Error: Directory ${r.projectName} already exists.`)),process.exit(1));let i={current:null},o=async()=>{if(m(n)){i.current?.stop(),i.current=null,console.log(q.yellow(`
399
+ Cleaning up: Deleting directory ${r.projectName}...`));try{await w(n),console.log(q.green("Cleanup successful."))}catch(a){console.error(q.red(`Failed to clean up directory ${r.projectName}:`),a)}}},s=async()=>{console.log(q.red(`
400
+ Process interrupted. Cleaning up...`)),await o(),process.exit(1)};process.on("SIGINT",s),process.on("SIGTERM",s);try{if(await Hn(n),await jn(n,r),await Fn(n,r),await Ve("Generating providers and layout...","Providers and layout generated.",async()=>{await Mn(n,r),await Gn(n,r)},i),await Ve("Setting up developer tools...","Developer tools configured.",()=>Ln(n,r),i),await Ve("Initializing Git...","Git initialized.",()=>tn(n,r.gitRemote,r.pushToRemote),i),await Ve("Installing dependencies...","Dependencies installed.",()=>rn(n,r.packageManager),i),await Ve("Formatting and linting...","Formatted.",()=>z(n,r.packageManager,"lint:fix"),i),r.copyEnv){let a=tr.join(n,".env.example"),p=tr.join(n,".env");m(a)&&await(await import("node:fs/promises")).copyFile(a,p)}process.off("SIGINT",s),process.off("SIGTERM",s),l(""),l(q.green(`\u2728 Project ${r.projectName} created successfully!`)),l(""),l("To get started:"),l(q.cyan(` cd ${r.projectName}`)),l(q.cyan(` ${r.packageManager==="npm"?"npm run dev":`${r.packageManager} dev`}`)),l("")}catch(a){i.current?.fail("Failed to create project."),i.current=null,console.error(a),await o(),process.exit(1)}};import hr from"node:path";import te from"picocolors";H();import{mkdir as Wn,writeFile as ir}from"node:fs/promises";import ve from"node:path";P();var nr=e=>{let{componentName:t,isClient:r,hasI18n:n}=e,i=e.translationNamespace||t,o=[];return(r||n)&&o.push("'use client';"),n&&o.push("import { useTranslations } from 'next-intl';"),o.push(""),o.push(`export function ${t}() {`),n?(o.push(` const t = useTranslations('${i}');`),o.push(""),o.push(" return ("),o.push(" <div>"),o.push(" <h2>{t('title')}</h2>"),o.push(" </div>"),o.push(" );")):(o.push(" return ("),o.push(" <div>"),o.push(` <h2>${t}</h2>`),o.push(" </div>"),o.push(" );")),o.push("}"),o.push(""),o.join(`
401
+ `)},Vn=e=>`export { ${e.componentName} } from './${e.componentName}';
402
+ `;var or=async e=>{let{name:t,projectPath:r,isClient:n,hasI18n:i,featurePath:o}=e,s=R(t);o?await Za(s,r,o,n,i):await Qa(s,t,r,n,i)},Za=async(e,t,r,n,i)=>{let o=ve.join(t,r,"components");await Wn(o,{recursive:!0}),await ir(ve.join(o,`${e}.tsx`),nr({componentName:e,isClient:n,hasI18n:i}))},Qa=async(e,t,r,n,i)=>{let o=ve.join(r,"src","components","common",e);await Wn(o,{recursive:!0}),await ir(ve.join(o,`${e}.tsx`),nr({componentName:e,isClient:n,hasI18n:i})),await ir(ve.join(o,"index.ts"),Vn({componentName:e}));let s=ve.join(r,"src","components","common","index.ts");await ec(s,`export { ${e} } from './${e}';
403
+ `);let a=ve.join(r,"src","components","index.ts");await tc(a)},ec=async(e,t)=>{let r="";m(e)&&(r=await f(e)),r.includes(t.trim())||(r+=t,await g(e,r))},tc=async e=>{let t="";m(e)&&(t=await f(e));let r=`export * from './common';
404
+ `;t.includes(r.trim())||(t+=r,await g(e,t))};import{writeFile as rc}from"node:fs/promises";import nc from"node:path";var qn=e=>{let{camelName:t,pascalName:r,httpClient:n}=e,i=n==="axios"?"import { axiosClient } from '@/lib/utils/http';":"import { fetchClient } from '@/lib/utils/http';",o=n==="axios"?"axiosClient":"fetchClient";return`import { AppApis } from '@/lib/config';
405
+ ${i}
262
406
  import type { ResultAsync } from '@/types';
263
407
 
264
408
  /**
@@ -286,33 +430,33 @@ export interface Update${r}Dto {
286
430
 
287
431
  export const ${t}Service = {
288
432
  getAll: (): ResultAsync<${r}Summary[]> => {
289
- return ${i}.get<${r}Summary[]>(AppApis.${t}.getAll);
433
+ return ${o}.get<${r}Summary[]>(AppApis.${t}.getAll);
290
434
  },
291
435
 
292
436
  getById: (id: string): ResultAsync<${r}Detail> => {
293
- return ${i}.get<${r}Detail>(AppApis.${t}.getById(id));
437
+ return ${o}.get<${r}Detail>(AppApis.${t}.getById(id));
294
438
  },
295
439
 
296
440
  create: (data: Create${r}Dto): ResultAsync<${r}Detail> => {
297
- return ${i}.post<${r}Detail>(AppApis.${t}.create, data);
441
+ return ${o}.post<${r}Detail>(AppApis.${t}.create, data);
298
442
  },
299
443
 
300
444
  update: (id: string, data: Update${r}Dto): ResultAsync<${r}Detail> => {
301
- return ${i}.patch<${r}Detail>(AppApis.${t}.update(id), data);
445
+ return ${o}.patch<${r}Detail>(AppApis.${t}.update(id), data);
302
446
  },
303
447
 
304
448
  delete: (id: string): ResultAsync<void> => {
305
- return ${i}.delete<void>(AppApis.${t}.delete(id));
449
+ return ${o}.delete<void>(AppApis.${t}.delete(id));
306
450
  },
307
451
  };
308
- `},Tn=e=>{let{camelName:t,kebabName:r}=e;return` ${t}: {
452
+ `},Xn=e=>{let{camelName:t,kebabName:r}=e;return` ${t}: {
309
453
  base: '/${r}',
310
454
  getAll: '/${r}',
311
455
  getById: (id: string) => \`/${r}/\${id}\`,
312
456
  create: '/${r}',
313
457
  update: (id: string) => \`/${r}/\${id}\`,
314
458
  delete: (id: string) => \`/${r}/\${id}\`,
315
- },`};var Xt=async e=>{let{name:t,outputPath:r,httpClient:n}=e,o=O(t),i=R(t);await aa(ca.join(r,`${t}.service.ts`),Cn({camelName:o,pascalName:i,httpClient:n}))};import{mkdir as da,writeFile as xt}from"node:fs/promises";import W from"node:path";import{writeFile as pa}from"node:fs/promises";import la from"node:path";var En=e=>{let{camelName:t,httpClient:r}=e;return`import { AppApis } from '@/lib/config';
459
+ },`};var sr=async e=>{let{name:t,outputPath:r,httpClient:n}=e,i=j(t),o=R(t);await rc(nc.join(r,`${t}.service.ts`),qn({camelName:i,pascalName:o,httpClient:n}))};import{mkdir as ac,writeFile as $t}from"node:fs/promises";import Y from"node:path";import{writeFile as ic}from"node:fs/promises";import oc from"node:path";var Yn=e=>{let{camelName:t,httpClient:r}=e;return`import { AppApis } from '@/lib/config';
316
460
  ${r==="axios"?"import { axiosClient } from '@/lib/utils/http';":"import { fetchClient } from '@/lib/utils/http';"}
317
461
  import type { ResultAsync } from '@/types';
318
462
 
@@ -321,23 +465,23 @@ export const ${t}Service = {
321
465
  return ${r==="axios"?"axiosClient":"fetchClient"}.get<string>(AppApis.${t}.getAll);
322
466
  },
323
467
  };
324
- `};var Le=async e=>{let{name:t,outputPath:r,httpClient:n}=e,o=O(t);await pa(la.join(r,`${t}.service.ts`),En({camelName:o,httpClient:n}))};import{mkdir as ma,writeFile as Me}from"node:fs/promises";import Ge from"node:path";var bn=e=>{let{sliceName:t,withPersist:r}=e;return`export * from './${t}.slice';
468
+ `};var Xe=async e=>{let{name:t,outputPath:r,httpClient:n}=e,i=j(t);await ic(oc.join(r,`${t}.service.ts`),Yn({camelName:i,httpClient:n}))};import{mkdir as sc,writeFile as Ye}from"node:fs/promises";import Ke from"node:path";var Kn=e=>{let{sliceName:t,withPersist:r}=e;return`export * from './${t}.slice';
325
469
  export * from './${t}.selectors';
326
470
  export * from './${t}.types';${r?`
327
471
  export * from './persist';`:""}
328
- `},Rn=e=>{let{featureName:t,componentName:r,hookName:n,withStore:o,withService:i}=e;return`export { default as ${r} } from './components/${r}';
472
+ `},Zn=e=>{let{featureName:t,componentName:r,hookName:n,withStore:i,withService:o}=e;return`export { default as ${r} } from './components/${r}';
329
473
  export { ${n} } from './hooks/${n}';
330
- export * from './types/${t}.types';${o?`
331
- export * from './store';`:""}${i?`
474
+ export * from './types/${t}.types';${i?`
475
+ export * from './store';`:""}${o?`
332
476
  export * from './services/${t}.service';`:""}
333
- `};var $n=e=>{let{componentName:t,camelName:r,typesImportPath:n}=e,o=`${r.toUpperCase()}_PERSIST_VERSION`;return`import { createMigrate, type PersistConfig, type PersistedState } from 'redux-persist';
477
+ `};var Qn=e=>{let{componentName:t,camelName:r,typesImportPath:n}=e,i=`${r.toUpperCase()}_PERSIST_VERSION`;return`import { createMigrate, type PersistConfig, type PersistedState } from 'redux-persist';
334
478
  import storage from '@/store/storage';
335
479
  import type { ${t}State } from '${n}';
336
480
 
337
- const ${o} = 1;
481
+ const ${i} = 1;
338
482
 
339
483
  const migrations = {
340
- // Bump ${o} and add a migration here when ${t}State's
484
+ // Bump ${i} and add a migration here when ${t}State's
341
485
  // shape changes. Receives the previously-persisted state, returns the new
342
486
  // shape. Returning \`undefined\` discards stale state.
343
487
  // 2: (state) => ({ ...state, newField: defaultValue }),
@@ -346,15 +490,15 @@ const migrations = {
346
490
  export const ${r}PersistConfig: PersistConfig<${t}State> = {
347
491
  key: '${r}',
348
492
  storage,
349
- version: ${o},
493
+ version: ${i},
350
494
  // whitelist: ['someField'], // Specify which fields to persist
351
495
  migrate: createMigrate(migrations, { debug: false }),
352
496
  };
353
- `};var In=e=>{let{componentName:t,camelName:r,sliceName:n}=e;return`import { RootState } from '@/store/rootReducer';
497
+ `};var ei=e=>{let{componentName:t,camelName:r,sliceName:n}=e;return`import { RootState } from '@/store/rootReducer';
354
498
 
355
499
  export const select${t}State = (state: RootState) => state.${r};
356
500
  export { setLoading, setError, resetState } from './${n}.slice';
357
- `};var Nn=e=>{let{componentName:t,camelName:r,typesImportPath:n}=e;return`import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
501
+ `};var ti=e=>{let{componentName:t,camelName:r,typesImportPath:n}=e;return`import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
358
502
  import type { ${t}State } from '${n}';
359
503
 
360
504
  const initialState: ${t}State = {
@@ -383,13 +527,13 @@ export const ${r}Slice = createSlice({
383
527
  export const { setLoading, setError, resetState } = ${r}Slice.actions;
384
528
 
385
529
  export const ${r}Reducer = ${r}Slice.reducer;
386
- `};var yt=e=>{let{componentName:t,withStore:r}=e;return`export interface ${t}State {
530
+ `};var Rt=e=>{let{componentName:t,withStore:r}=e;return`export interface ${t}State {
387
531
  ${r?`loading: boolean;
388
532
  error: string | null;
389
533
  // Add your state properties here`:`// Add your state properties here
390
534
  // example: value: string;`}
391
535
  }
392
- `};var He=async e=>{let{name:t,outputPath:r,persist:n,typesImportPath:o=`./${t}.types`}=e;await ma(r,{recursive:!0});let i=R(t),s=O(t);await Promise.all([Me(Ge.join(r,`${t}.types.ts`),yt({componentName:i,withStore:!0})),Me(Ge.join(r,`${t}.slice.ts`),Nn({componentName:i,camelName:s,typesImportPath:o})),Me(Ge.join(r,`${t}.selectors.ts`),In({componentName:i,camelName:s,sliceName:t})),...n?[Me(Ge.join(r,"persist.ts"),$n({componentName:i,camelName:s,typesImportPath:o}))]:[],Me(Ge.join(r,"index.ts"),bn({sliceName:t,withPersist:n}))])};var kn=e=>{let{componentName:t,hookName:r}=e;return`'use client';
536
+ `};var Ze=async e=>{let{name:t,outputPath:r,persist:n,typesImportPath:i=`./${t}.types`}=e;await sc(r,{recursive:!0});let o=R(t),s=j(t);await Promise.all([Ye(Ke.join(r,`${t}.types.ts`),Rt({componentName:o,withStore:!0})),Ye(Ke.join(r,`${t}.slice.ts`),ti({componentName:o,camelName:s,typesImportPath:i})),Ye(Ke.join(r,`${t}.selectors.ts`),ei({componentName:o,camelName:s,sliceName:t})),...n?[Ye(Ke.join(r,"persist.ts"),Qn({componentName:o,camelName:s,typesImportPath:i}))]:[],Ye(Ke.join(r,"index.ts"),Kn({sliceName:t,withPersist:n}))])};var ri=e=>{let{componentName:t,hookName:r}=e;return`'use client';
393
537
  import { ${r} } from '../hooks/${r}';
394
538
 
395
539
  export function ${t}() {
@@ -404,7 +548,7 @@ export function ${t}() {
404
548
  }
405
549
 
406
550
  export default ${t};
407
- `};var An=e=>{let{hookName:t,componentName:r,featureName:n}=e;return`'use client';
551
+ `};var ni=e=>{let{hookName:t,componentName:r,featureName:n}=e;return`'use client';
408
552
  import { useAppDispatch, useAppSelector } from '@/store/hooks';
409
553
  import { select${r}State, setLoading, setError } from '../store/${n}.selectors';
410
554
 
@@ -426,7 +570,7 @@ export const ${t} = () => {
426
570
  setError: handleSetError,
427
571
  } as const;
428
572
  };
429
- `},On=e=>{let{hookName:t}=e;return`'use client';
573
+ `},ii=e=>{let{hookName:t}=e;return`'use client';
430
574
  import { useState } from 'react';
431
575
 
432
576
  export const ${t} = () => {
@@ -438,8 +582,8 @@ export const ${t} = () => {
438
582
  // Add your methods here
439
583
  } as const;
440
584
  };
441
- `};var Wt=async e=>{let{name:t,outputPath:r,createStore:n,persistStore:o,createService:i,httpClient:s}=e,a=R(t),p=`use${a}`,u=[W.join(r,"components"),W.join(r,"hooks"),W.join(r,"types"),...n?[W.join(r,"store")]:[],...i?[W.join(r,"services")]:[]];await Promise.all(u.map(d=>da(d,{recursive:!0}))),await Promise.all([xt(W.join(r,"components",`${a}.tsx`),kn({componentName:a,hookName:p})),xt(W.join(r,"hooks",`${p}.ts`),n?An({hookName:p,componentName:a,featureName:t}):On({hookName:p})),xt(W.join(r,"types",`${t}.types.ts`),yt({componentName:a,withStore:n})),xt(W.join(r,"index.ts"),Rn({featureName:t,componentName:a,hookName:p,withStore:n,withService:i}))]),n&&await He({name:t,outputPath:W.join(r,"store"),persist:o,typesImportPath:`../types/${t}.types`}),i&&s&&await Le({name:t,outputPath:W.join(r,"services"),httpClient:s})};import{mkdir as ua,writeFile as fa}from"node:fs/promises";import Yt from"node:path";var Fn=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(`
442
- `)};var Kt=async e=>{let{name:t,projectPath:r,isClient:n,featurePath:o}=e,s=`use${R(t)}`,a;o?a=Yt.join(r,o,"hooks"):a=Yt.join(r,"src","hooks"),await ua(a,{recursive:!0}),await fa(Yt.join(a,`${s}.ts`),Fn({hookName:s,isClient:n}))};import{mkdir as ya}from"node:fs/promises";import Pt from"node:path";P();var ga=e=>`import { setRequestLocale } from 'next-intl/server';
585
+ `};var ar=async e=>{let{name:t,outputPath:r,createStore:n,persistStore:i,createService:o,httpClient:s}=e,a=R(t),p=`use${a}`,u=[Y.join(r,"components"),Y.join(r,"hooks"),Y.join(r,"types"),...n?[Y.join(r,"store")]:[],...o?[Y.join(r,"services")]:[]];await Promise.all(u.map(d=>ac(d,{recursive:!0}))),await Promise.all([$t(Y.join(r,"components",`${a}.tsx`),ri({componentName:a,hookName:p})),$t(Y.join(r,"hooks",`${p}.ts`),n?ni({hookName:p,componentName:a,featureName:t}):ii({hookName:p})),$t(Y.join(r,"types",`${t}.types.ts`),Rt({componentName:a,withStore:n})),$t(Y.join(r,"index.ts"),Zn({featureName:t,componentName:a,hookName:p,withStore:n,withService:o}))]),n&&await Ze({name:t,outputPath:Y.join(r,"store"),persist:i,typesImportPath:`../types/${t}.types`}),o&&s&&await Xe({name:t,outputPath:Y.join(r,"services"),httpClient:s})};import{mkdir as cc,writeFile as pc}from"node:fs/promises";import cr from"node:path";var oi=e=>{let{hookName:t,isClient:r}=e,n=[];return r&&n.push("'use client';"),n.push("import { useState, useCallback } from 'react';"),n.push(""),n.push(`export const ${t} = () => {`),n.push(" const [loading, setLoading] = useState(false);"),n.push(" const [error, setError] = useState<string | null>(null);"),n.push(""),n.push(" const execute = useCallback(async () => {"),n.push(" setLoading(true);"),n.push(" setError(null);"),n.push(" try {"),n.push(" // Add your logic here"),n.push(" } catch (err) {"),n.push(" setError(err instanceof Error ? err.message : 'An error occurred');"),n.push(" } finally {"),n.push(" setLoading(false);"),n.push(" }"),n.push(" }, []);"),n.push(""),n.push(" return {"),n.push(" loading,"),n.push(" error,"),n.push(" execute,"),n.push(" } as const;"),n.push("};"),n.push(""),n.join(`
586
+ `)};var pr=async e=>{let{name:t,projectPath:r,isClient:n,featurePath:i}=e,s=`use${R(t)}`,a;i?a=cr.join(r,i,"hooks"):a=cr.join(r,"src","hooks"),await cc(a,{recursive:!0}),await pc(cr.join(a,`${s}.ts`),oi({hookName:s,isClient:n}))};import{mkdir as dc}from"node:fs/promises";import It from"node:path";P();var lc=e=>`import { setRequestLocale } from 'next-intl/server';
443
587
  import type { SupportedLocale } from '@/types/i18n';
444
588
 
445
589
  type Props = {
@@ -453,21 +597,21 @@ export default async function ${e}({ children, params }: Props) {
453
597
 
454
598
  return <>{children}</>;
455
599
  }
456
- `,ha=e=>`type Props = {
600
+ `,mc=e=>`type Props = {
457
601
  children: React.ReactNode;
458
602
  };
459
603
 
460
604
  export default function ${e}({ children }: Props) {
461
605
  return <>{children}</>;
462
606
  }
463
- `,_n=({componentName:e,hasI18n:t})=>t?ga(e):ha(e);var xa=/^[a-z][a-z0-9-]*$/,Pa=/^[a-z][a-z0-9-]*(\/[a-z][a-z0-9-]*)*$/,va=e=>{if(!xa.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.`)},wa=e=>{if(!Pa.test(e))throw new Error(`Invalid --at path "${e}". Use kebab-case segments separated by "/", e.g. "dashboard/settings".`)},Zt=async e=>{let{segment:t,at:r,projectPath:n,hasI18n:o,withGroup:i}=e;va(t),r&&wa(r);let s=`${R(t)}Layout`,a=i?`(${t})`:t,p=["src","app"];o&&p.push("[locale]"),r&&p.push(...r.split("/")),p.push(a);let u=Pt.join(n,...p),d=Pt.join(u,"layout.tsx");if(m(d))throw new Error(`Layout already exists at ${Pt.relative(n,d)}.`);return await ya(u,{recursive:!0}),await g(d,_n({componentName:s,hasI18n:o})),{layoutFile:d,displayPath:Pt.relative(n,d),componentName:s}};P();import{copyFile as Sa,readFile as Ca,writeFile as Ta}from"node:fs/promises";import Ue from"node:path";var Qt=async e=>{let{code:t,name:r,country:n,flag:o,projectPath:i,copyTranslations:s}=e;await Ea(i,t,s),await ba(i,t),await Ra(i,t,r,n,o)},Ea=async(e,t,r)=>{let n=Ue.join(e,"src","i18n","translations"),o=Ue.join(n,"en.json"),i=Ue.join(n,`${t}.json`);if(r)await Sa(o,i);else{let s=await Ca(o,"utf-8"),a=JSON.parse(s),p=jn(a);await Ta(i,`${JSON.stringify(p,null,2)}
464
- `)}},jn=e=>{let t={};for(let[r,n]of Object.entries(e))typeof n=="object"&&n!==null?t[r]=jn(n):t[r]="";return t},ba=async(e,t)=>{let r=Ue.join(e,"src","types","i18n.ts");if(!m(r))return;let n=await f(r),o=/export type SupportedLocale = (.*);/,i=n.match(o);if(i&&!i[1].includes(`'${t}'`)){let s=`${i[1]} | '${t}'`;n=n.replace(o,`export type SupportedLocale = ${s};`),await g(r,n)}},Ra=async(e,t,r,n,o)=>{let i=Ue.join(e,"src","lib","config","app-locales.ts");if(!m(i))return;let s=await f(i);if(s.includes(`locale: '${t}'`))return;let a=s.lastIndexOf("];");if(a===-1)return;let p=` {
607
+ `,si=({componentName:e,hasI18n:t})=>t?lc(e):mc(e);var uc=/^[a-z][a-z0-9-]*$/,fc=/^[a-z][a-z0-9-]*(\/[a-z][a-z0-9-]*)*$/,gc=e=>{if(!uc.test(e))throw new Error(`Invalid layout segment "${e}". Use kebab-case letters, digits, and hyphens. For route groups pass --group instead of wrapping in parens.`)},hc=e=>{if(!fc.test(e))throw new Error(`Invalid --at path "${e}". Use kebab-case segments separated by "/", e.g. "dashboard/settings".`)},lr=async e=>{let{segment:t,at:r,projectPath:n,hasI18n:i,withGroup:o}=e;gc(t),r&&hc(r);let s=`${R(t)}Layout`,a=o?`(${t})`:t,p=["src","app"];i&&p.push("[locale]"),r&&p.push(...r.split("/")),p.push(a);let u=It.join(n,...p),d=It.join(u,"layout.tsx");if(m(d))throw new Error(`Layout already exists at ${It.relative(n,d)}.`);return await dc(u,{recursive:!0}),await g(d,si({componentName:s,hasI18n:i})),{layoutFile:d,displayPath:It.relative(n,d),componentName:s}};P();import{copyFile as yc,readFile as xc,writeFile as Pc}from"node:fs/promises";import Qe from"node:path";var mr=async e=>{let{code:t,name:r,country:n,flag:i,projectPath:o,copyTranslations:s}=e;await wc(o,t,s),await vc(o,t),await Sc(o,t,r,n,i)},wc=async(e,t,r)=>{let n=Qe.join(e,"src","i18n","translations"),i=Qe.join(n,"en.json"),o=Qe.join(n,`${t}.json`);if(r)await yc(i,o);else{let s=await xc(i,"utf-8"),a=JSON.parse(s),p=ai(a);await Pc(o,`${JSON.stringify(p,null,2)}
608
+ `)}},ai=e=>{let t={};for(let[r,n]of Object.entries(e))typeof n=="object"&&n!==null?t[r]=ai(n):t[r]="";return t},vc=async(e,t)=>{let r=Qe.join(e,"src","types","i18n.ts");if(!m(r))return;let n=await f(r),i=/export type SupportedLocale = (.*);/,o=n.match(i);if(o&&!o[1].includes(`'${t}'`)){let s=`${o[1]} | '${t}'`;n=n.replace(i,`export type SupportedLocale = ${s};`),await g(r,n)}},Sc=async(e,t,r,n,i)=>{let o=Qe.join(e,"src","lib","config","app-locales.ts");if(!m(o))return;let s=await f(o);if(s.includes(`locale: '${t}'`))return;let a=s.lastIndexOf("];");if(a===-1)return;let p=` {
465
609
  name: '${r}',
466
610
  locale: '${t}',
467
- flag: '${o}',
611
+ flag: '${i}',
468
612
  country: '${n}',
469
613
  },
470
- `;s=s.slice(0,a)+p+s.slice(a),await g(i,s)};import{mkdir as $a,writeFile as er}from"node:fs/promises";import ze from"node:path";var Dn=e=>{let{componentName:t,routePath:r,hasI18n:n}=e;return n?`import { generateSEOMetadata } from '@/lib/config/seo';
614
+ `;s=s.slice(0,a)+p+s.slice(a),await g(o,s)};import{mkdir as Cc,writeFile as dr}from"node:fs/promises";import et from"node:path";var ci=e=>{let{componentName:t,routePath:r,hasI18n:n}=e;return n?`import { generateSEOMetadata } from '@/lib/config/seo';
471
615
  import type { Metadata } from 'next';
472
616
  import { getTranslations, setRequestLocale } from 'next-intl/server';
473
617
  import type { SupportedLocale } from '@/types/i18n';
@@ -513,7 +657,7 @@ export default function ${t}Page() {
513
657
  </div>
514
658
  );
515
659
  }
516
- `},Ln=e=>{let{componentName:t,paramName:r,routePath:n,hasI18n:o}=e;return o?`import { generateSEOMetadata } from '@/lib/config/seo';
660
+ `},pi=e=>{let{componentName:t,paramName:r,routePath:n,hasI18n:i}=e;return i?`import { generateSEOMetadata } from '@/lib/config/seo';
517
661
  import type { Metadata } from 'next';
518
662
  import { getTranslations, setRequestLocale } from 'next-intl/server';
519
663
  import type { SupportedLocale } from '@/types/i18n';
@@ -567,14 +711,14 @@ export default async function ${t}Page(props: Props) {
567
711
  </div>
568
712
  );
569
713
  }
570
- `},Mn=e=>`export default function ${e.componentName}Loading() {
714
+ `},li=e=>`export default function ${e.componentName}Loading() {
571
715
  return (
572
716
  <div className="flex h-full items-center justify-center">
573
717
  <p>Loading...</p>
574
718
  </div>
575
719
  );
576
720
  }
577
- `,Gn=e=>`'use client';
721
+ `,mi=e=>`'use client';
578
722
 
579
723
  export default function ${e.componentName}Error({
580
724
  error,
@@ -591,28 +735,28 @@ export default function ${e.componentName}Error({
591
735
  </div>
592
736
  );
593
737
  }
594
- `;var tr=async e=>{let{name:t,projectPath:r,hasI18n:n,dynamic:o,withLoading:i=!1,withError:s=!1}=e,a=R(t),p=`/${t}`,u=n?"src/app/[locale]":"src/app",d;o?d=ze.join(r,u,t,`[${o}]`):d=ze.join(r,u,t),await $a(d,{recursive:!0});let h=o?Ln({componentName:a,routePath:o?`${p}/[${o}]`:p,paramName:o,hasI18n:n}):Dn({componentName:a,routePath:p,hasI18n:n});await er(ze.join(d,"page.tsx"),h),i&&await er(ze.join(d,"loading.tsx"),Mn({componentName:a})),s&&await er(ze.join(d,"error.tsx"),Gn({componentName:a}))};S();import{mkdir as Ia}from"node:fs/promises";import rr from"node:path";P();var Hn=(e,t)=>e.endsWith(t)?e:`${e}${t}`,Un=({baseName:e})=>{let t=Hn(e,"Provider"),r=t.replace(/Provider$/,""),n=`${r}ContextValue`,o=`${r}Context`,i=`use${r}`;return`'use client';
738
+ `;var ur=async e=>{let{name:t,projectPath:r,hasI18n:n,dynamic:i,withLoading:o=!1,withError:s=!1}=e,a=R(t),p=`/${t}`,u=n?"src/app/[locale]":"src/app",d;i?d=et.join(r,u,t,`[${i}]`):d=et.join(r,u,t),await Cc(d,{recursive:!0});let h=i?pi({componentName:a,routePath:i?`${p}/[${i}]`:p,paramName:i,hasI18n:n}):ci({componentName:a,routePath:p,hasI18n:n});await dr(et.join(d,"page.tsx"),h),o&&await dr(et.join(d,"loading.tsx"),li({componentName:a})),s&&await dr(et.join(d,"error.tsx"),mi({componentName:a}))};S();import{mkdir as Ec}from"node:fs/promises";import fr from"node:path";P();var di=(e,t)=>e.endsWith(t)?e:`${e}${t}`,ui=({baseName:e})=>{let t=di(e,"Provider"),r=t.replace(/Provider$/,""),n=`${r}ContextValue`,i=`${r}Context`,o=`use${r}`;return`'use client';
595
739
  import { createContext, useContext, useMemo } from 'react';
596
740
 
597
741
  type ${n} = {
598
742
  // TODO: declare context value fields
599
743
  };
600
744
 
601
- const ${o} = createContext<${n} | null>(null);
745
+ const ${i} = createContext<${n} | null>(null);
602
746
 
603
- export const ${i} = (): ${n} => {
604
- const ctx = useContext(${o});
747
+ export const ${o} = (): ${n} => {
748
+ const ctx = useContext(${i});
605
749
  if (!ctx) {
606
- throw new Error('${i} must be used within ${t}');
750
+ throw new Error('${o} must be used within ${t}');
607
751
  }
608
752
  return ctx;
609
753
  };
610
754
 
611
755
  export const ${t} = ({ children }: { children: React.ReactNode }) => {
612
756
  const value = useMemo<${n}>(() => ({}), []);
613
- return <${o}.Provider value={value}>{children}</${o}.Provider>;
757
+ return <${i}.Provider value={value}>{children}</${i}.Provider>;
614
758
  };
615
- `},zn=e=>Hn(e,"Provider");var Na=/^[A-Za-z][A-Za-z0-9-]*$/,ka=e=>e.includes("-")?R(e):e.charAt(0).toUpperCase()+e.slice(1),nr=async e=>{let{name:t,projectPath:r}=e;if(!Na.test(t))throw new Error(`Invalid provider name "${t}". Use kebab-case or PascalCase letters and digits only.`);let n=ka(t).replace(/Provider$/,""),o=zn(n),i=o,s=rr.join(r,c.PROVIDERS),a=rr.join(s,`${i}.tsx`);if(m(a))throw new Error(`Provider already exists at ${rr.relative(r,a)}.`);return await Ia(s,{recursive:!0}),await g(a,Un({baseName:n})),{componentName:o,fileBaseName:i,providerFile:a}};P();import Je from"node:path";var Jn=e=>{let{componentName:t,sourceImportPath:r,testUtilsImportPath:n,hasRedux:o,hasI18n:i}=e,s=[];i&&s.push("messages: {}"),o&&s.push("preloadedState: {}");let a=s.length?`, {
759
+ `},fi=e=>di(e,"Provider");var Tc=/^[A-Za-z][A-Za-z0-9-]*$/,bc=e=>e.includes("-")?R(e):e.charAt(0).toUpperCase()+e.slice(1),gr=async e=>{let{name:t,projectPath:r}=e;if(!Tc.test(t))throw new Error(`Invalid provider name "${t}". Use kebab-case or PascalCase letters and digits only.`);let n=bc(t).replace(/Provider$/,""),i=fi(n),o=i,s=fr.join(r,c.PROVIDERS),a=fr.join(s,`${o}.tsx`);if(m(a))throw new Error(`Provider already exists at ${fr.relative(r,a)}.`);return await Ec(s,{recursive:!0}),await g(a,ui({baseName:n})),{componentName:i,fileBaseName:o,providerFile:a}};P();import tt from"node:path";var gi=e=>{let{componentName:t,sourceImportPath:r,testUtilsImportPath:n,hasRedux:i,hasI18n:o}=e,s=[];o&&s.push("messages: {}"),i&&s.push("preloadedState: {}");let a=s.length?`, {
616
760
  ${s.join(`,
617
761
  `)},
618
762
  }`:"";return`import { describe, expect, it } from 'vitest';
@@ -626,9 +770,9 @@ describe('${t}', () => {
626
770
  expect(screen).toBeDefined();
627
771
  });
628
772
  });
629
- `},Vn=e=>{let{hookName:t,sourceImportPath:r,withStore:n,testUtilsImportPath:o}=e;return n?`import { renderHook } from '@testing-library/react';
773
+ `},hi=e=>{let{hookName:t,sourceImportPath:r,withStore:n,testUtilsImportPath:i}=e;return n?`import { renderHook } from '@testing-library/react';
630
774
  import { describe, expect, it } from 'vitest';
631
- import { TestProviders } from '${o}';
775
+ import { TestProviders } from '${i}';
632
776
  import { ${t} } from '${r}';
633
777
 
634
778
  describe('${t}', () => {
@@ -647,7 +791,7 @@ describe('${t}', () => {
647
791
  expect(result.current).toBeDefined();
648
792
  });
649
793
  });
650
- `},Bn=e=>{let{camelName:t,sourceImportPath:r}=e,n=`${t}Slice`;return`import { describe, expect, it } from 'vitest';
794
+ `},yi=e=>{let{camelName:t,sourceImportPath:r}=e,n=`${t}Slice`;return`import { describe, expect, it } from 'vitest';
651
795
  import { ${n}, resetState, setError, setLoading } from '${r}';
652
796
 
653
797
  describe('${n}', () => {
@@ -672,65 +816,65 @@ describe('${n}', () => {
672
816
  expect(next).toEqual(initialState);
673
817
  });
674
818
  });
675
- `};var ie=async e=>{let{projectPath:t,sourceFile:r,kind:n,symbolName:o}=e,i=Je.dirname(r),s=Je.basename(r).replace(/\.(tsx?|jsx?)$/i,""),a=n==="component"?".tsx":".ts",p=Je.join(i,`${s}.test${a}`),u=`./${s}`,d=Aa(i,Je.join(t,"test","test-utils")),h;return n==="component"?h=Jn({componentName:o,sourceImportPath:u,testUtilsImportPath:d,hasRedux:!!e.hasRedux,hasI18n:!!e.hasI18n}):n==="hook"?h=Vn({hookName:o,sourceImportPath:u,withStore:!!e.hookUsesStore,testUtilsImportPath:e.hookUsesStore?d:void 0}):h=Bn({camelName:o,sourceImportPath:u}),await g(p,h),p},Aa=(e,t)=>{let r=Je.relative(e,t).replace(/\\/g,"/");return r.startsWith(".")?r:`./${r}`};import Oa from"enquirer";var{prompt:Fa}=Oa,qn=async(e,t={})=>{let r=[];e||r.push({type:"input",name:"componentName",message:"Component name (kebab-case):",validate:o=>o?/^[a-z][a-z0-9-]*$/.test(o)?!0:"Use lowercase letters, numbers, and hyphens only":"Component name is required"}),t.client===void 0&&r.push({type:"confirm",name:"isClient",message:"Add 'use client' directive?",initial:!1});let n=r.length>0?await Fa(r):{};return{componentName:e??n.componentName,isClient:t.client??n.isClient??!1}};var Xn=e=>{e.command("component [name]").description("Generate a shared component").option("--client","Add 'use client' directive").option("--i18n","Add useTranslations hook").option("--feature <path>","Generate in feature directory (e.g., src/features/auth)").option("--test","Also generate a sibling test file").option("--no-test","Skip test file generation").action(async(t,r)=>{try{let n=process.cwd();l(te.cyan(`
819
+ `};var oe=async e=>{let{projectPath:t,sourceFile:r,kind:n,symbolName:i}=e,o=tt.dirname(r),s=tt.basename(r).replace(/\.(tsx?|jsx?)$/i,""),a=n==="component"?".tsx":".ts",p=tt.join(o,`${s}.test${a}`),u=`./${s}`,d=Rc(o,tt.join(t,"test","test-utils")),h;return n==="component"?h=gi({componentName:i,sourceImportPath:u,testUtilsImportPath:d,hasRedux:!!e.hasRedux,hasI18n:!!e.hasI18n}):n==="hook"?h=hi({hookName:i,sourceImportPath:u,withStore:!!e.hookUsesStore,testUtilsImportPath:e.hookUsesStore?d:void 0}):h=yi({camelName:i,sourceImportPath:u}),await g(p,h),p},Rc=(e,t)=>{let r=tt.relative(e,t).replace(/\\/g,"/");return r.startsWith(".")?r:`./${r}`};import $c from"enquirer";var{prompt:Ic}=$c,xi=async(e,t={})=>{let r=[];e||r.push({type:"input",name:"componentName",message:"Component name (kebab-case):",validate:i=>i?/^[a-z][a-z0-9-]*$/.test(i)?!0:"Use lowercase letters, numbers, and hyphens only":"Component name is required"}),t.client===void 0&&r.push({type:"confirm",name:"isClient",message:"Add 'use client' directive?",initial:!1});let n=r.length>0?await Ic(r):{};return{componentName:e??n.componentName,isClient:t.client??n.isClient??!1}};var Pi=e=>{e.command("component [name]").description("Generate a shared component").option("--client","Add 'use client' directive").option("--i18n","Add useTranslations hook").option("--feature <path>","Generate in feature directory (e.g., src/features/auth)").option("--test","Also generate a sibling test file").option("--no-test","Skip test file generation").action(async(t,r)=>{try{let n=process.cwd();l(te.cyan(`
676
820
  \u{1F9E9} Component Generator
677
- `)),y.start("Detecting project setup...");let o=await A(n);y.succeed("Project setup detected");let i=await qn(t,{client:r.client}),s=R(i.componentName),a=i.isClient,p=r.i18n??!1,u=_a(r,o.hasTests);y.start("Generating component..."),await qt({name:i.componentName,projectPath:n,isClient:a||p,hasI18n:p,featurePath:r.feature}),y.succeed("Component generated");let d=null;if(u){let x=r.feature?or.join(n,r.feature,"components",`${s}.tsx`):or.join(n,"src/components/common",s,`${s}.tsx`);y.start("Generating test..."),d=await ie({projectPath:n,sourceFile:x,kind:"component",symbolName:s,hasRedux:o.hasRedux,hasI18n:o.hasI18n}),y.succeed("Test generated")}let h=r.feature?`${r.feature}/components/${s}.tsx`:`src/components/common/${s}/${s}.tsx`;l(te.green(`
821
+ `)),y.start("Detecting project setup...");let i=await F(n);y.succeed("Project setup detected");let o=await xi(t,{client:r.client}),s=R(o.componentName),a=o.isClient,p=r.i18n??!1,u=Nc(r,i.hasTests);y.start("Generating component..."),await or({name:o.componentName,projectPath:n,isClient:a||p,hasI18n:p,featurePath:r.feature}),y.succeed("Component generated");let d=null;if(u){let x=r.feature?hr.join(n,r.feature,"components",`${s}.tsx`):hr.join(n,"src/components/common",s,`${s}.tsx`);y.start("Generating test..."),d=await oe({projectPath:n,sourceFile:x,kind:"component",symbolName:s,hasRedux:i.hasRedux,hasI18n:i.hasI18n}),y.succeed("Test generated")}let h=r.feature?`${r.feature}/components/${s}.tsx`:`src/components/common/${s}/${s}.tsx`;l(te.green(`
678
822
  \u2728 Component '${s}' created successfully!
679
- `)),l(te.dim(` \u{1F4C4} ${h}`)),r.feature||(l(te.dim(` \u{1F4C4} src/components/common/${s}/index.ts`)),l(te.dim(" \u{1F4DD} Updated src/components/common/index.ts")),l(te.dim(" \u{1F4DD} Updated src/components/index.ts"))),d&&l(te.dim(` \u{1F9EA} ${or.relative(n,d)}`)),l(""),l(te.cyan("Usage:")),r.feature?l(te.dim(` import { ${s} } from '${r.feature.replace(/^src\//,"@/")}/components/${s}';`)):l(te.dim(` import { ${s} } from '@/components';`)),l("")}catch(n){y.fail("Component generation failed"),v(`${n}`),process.exit(1)}})},_a=(e,t)=>e.noTest?!1:e.test?!0:t;import L from"picocolors";S();P();import Da from"node:path";S();import Wn from"node:path";import ja from"picocolors";P();var Ve=async e=>{let t=b("Adding @next/bundle-analyzer...");try{let r=Wn.join(e,c.NEXT_CONFIG);if(!m(r))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await f(r);if(n.includes("@next/bundle-analyzer")){t.fail("@next/bundle-analyzer is already configured.");return}n=`import withBundleAnalyzer from '@next/bundle-analyzer';
680
- ${n}`;let o=/export default (.*?);/,i=n.match(o);if(!i)throw new Error("Could not locate `export default` in next.config.ts.");let a=`const bundleAnalyzer = withBundleAnalyzer({
823
+ `)),l(te.dim(` \u{1F4C4} ${h}`)),r.feature||(l(te.dim(` \u{1F4C4} src/components/common/${s}/index.ts`)),l(te.dim(" \u{1F4DD} Updated src/components/common/index.ts")),l(te.dim(" \u{1F4DD} Updated src/components/index.ts"))),d&&l(te.dim(` \u{1F9EA} ${hr.relative(n,d)}`)),l(""),l(te.cyan("Usage:")),r.feature?l(te.dim(` import { ${s} } from '${r.feature.replace(/^src\//,"@/")}/components/${s}';`)):l(te.dim(` import { ${s} } from '@/components';`)),l("")}catch(n){y.fail("Component generation failed"),v(`${n}`),process.exit(1)}})},Nc=(e,t)=>e.noTest?!1:e.test?!0:t;import L from"picocolors";S();P();import Ac from"node:path";S();import wi from"node:path";import kc from"picocolors";P();var rt=async e=>{let t=b("Adding @next/bundle-analyzer...");try{let r=wi.join(e,c.NEXT_CONFIG);if(!m(r))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await f(r);if(n.includes("@next/bundle-analyzer")){t.fail("@next/bundle-analyzer is already configured.");return}n=`import withBundleAnalyzer from '@next/bundle-analyzer';
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({
681
825
  enabled: process.env.ANALYZE === 'true',
682
826
  });
683
827
 
684
- export default bundleAnalyzer(${i[1]});`;n=n.replace(o,a),await g(r,n),await _(Wn.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 mt(e,"@next/bundle-analyzer"),t.succeed(ja.green("@next/bundle-analyzer configured."))}catch(r){throw t.fail("Failed to add @next/bundle-analyzer."),r}};var ir=(e,t)=>{let r=e.split(`
685
- `),n=[],o=new RegExp(`^import\\s+${t}\\s+from\\s+['"][^'"]+['"];?\\s*$`),i=/^(import\s+)\{([^}]+)\}(\s+from\s+['"][^'"]+['"];?\s*)$/;for(let s of r){if(o.test(s))continue;let a=s.match(i);if(a){let p=a[2].split(",").map(d=>d.trim()).filter(Boolean),u=p.filter(d=>d.replace(/^type\s+/,"").split(/\s+as\s+/)[0].trim()!==t);if(u.length===0)continue;if(u.length<p.length){n.push(`${a[1]}{ ${u.join(", ")} }${a[3]}`);continue}}n.push(s)}return n.join(`
686
- `)},$e=e=>t=>{let r=t.split(`
687
- `),n=new RegExp(`^([ \\t]*)<${e}\\b`),o=-1,i="";for(let h=0;h<r.length;h++){let x=r[h].match(n);if(x){o=h,i=x[1];break}}if(o===-1||!/>\s*$/.test(r[o]))return null;let s=i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=new RegExp(`^${s}<\\/${e}>\\s*$`),p=-1;for(let h=o+1;h<r.length;h++)if(a.test(r[h])){p=h;break}if(p===-1)return null;let u=r.slice(o+1,p).map(h=>h.startsWith(" ")?h.slice(2):h),d=[...r.slice(0,o),...u,...r.slice(p+1)].join(`
688
- `);return ir(d,e)};var Yn=e=>{let t=e.split(`
828
+ export default bundleAnalyzer(${o[1]});`;n=n.replace(i,a),await g(r,n),await D(wi.join(e,c.PACKAGE_JSON),p=>(p.scripts=p.scripts??{},p.scripts.analyze||(p.scripts.analyze="ANALYZE=true next build"),p)),t.text="Installing @next/bundle-analyzer...",await vt(e,"@next/bundle-analyzer"),t.succeed(kc.green("@next/bundle-analyzer configured."))}catch(r){throw t.fail("Failed to add @next/bundle-analyzer."),r}};var yr=(e,t)=>{let r=e.split(`
829
+ `),n=[],i=new RegExp(`^import\\s+${t}\\s+from\\s+['"][^'"]+['"];?\\s*$`),o=/^(import\s+)\{([^}]+)\}(\s+from\s+['"][^'"]+['"];?\s*)$/;for(let s of r){if(i.test(s))continue;let a=s.match(o);if(a){let p=a[2].split(",").map(d=>d.trim()).filter(Boolean),u=p.filter(d=>d.replace(/^type\s+/,"").split(/\s+as\s+/)[0].trim()!==t);if(u.length===0)continue;if(u.length<p.length){n.push(`${a[1]}{ ${u.join(", ")} }${a[3]}`);continue}}n.push(s)}return n.join(`
830
+ `)},Ae=e=>t=>{let r=t.split(`
831
+ `),n=new RegExp(`^([ \\t]*)<${e}\\b`),i=-1,o="";for(let h=0;h<r.length;h++){let x=r[h].match(n);if(x){i=h,o=x[1];break}}if(i===-1||!/>\s*$/.test(r[i]))return null;let s=o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=new RegExp(`^${s}<\\/${e}>\\s*$`),p=-1;for(let h=i+1;h<r.length;h++)if(a.test(r[h])){p=h;break}if(p===-1)return null;let u=r.slice(i+1,p).map(h=>h.startsWith(" ")?h.slice(2):h),d=[...r.slice(0,i),...u,...r.slice(p+1)].join(`
832
+ `);return yr(d,e)};var vi=e=>{let t=e.split(`
689
833
  `).filter(n=>!/^import\s+createNextIntlPlugin\s+from\s+['"]next-intl\/plugin['"];?\s*$/.test(n)).join(`
690
- `);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},Kn=e=>{let t=ir(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 Zn={id:"bundle-analyzer",name:"Bundle Analyzer",description:"@next/bundle-analyzer wrapped around the default export",detect:async e=>{let t=Da.join(e,c.NEXT_CONFIG);return m(t)?/@next\/bundle-analyzer/.test(await f(t)):!1},files:[],packages:[{name:"@next/bundle-analyzer",kind:"devDependency"}],scripts:[{name:"analyze",expectedValue:"ANALYZE=true next build"}],injections:[{file:c.NEXT_CONFIG,description:"withBundleAnalyzer import + wrapping",presence:/@next\/bundle-analyzer/,removePattern:Kn}],apply:Ve};S();P();import Ga from"node:path";S();import Qn from"node:path";import La from"picocolors";P();var sr=e=>{let t={...e.scripts??{}},r={...e.devDependencies??{}};return t.commit||(t.commit="cz"),r[T.COMMITIZEN]||(r[T.COMMITIZEN]="*"),r[T.CZ_CONVENTIONAL_CHANGELOG]||(r[T.CZ_CONVENTIONAL_CHANGELOG]="*"),{...e,scripts:t,devDependencies:r}},ar=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 Ma=`${JSON.stringify({path:"cz-conventional-changelog"},null,2)}
691
- `,Be=async e=>{let t=b("Setting up Commitizen...");try{let r=Qn.join(e,c.CZRC);m(r)||await g(r,Ma);let n=Qn.join(e,c.PACKAGE_JSON),o=JSON.parse(await f(n)),i=ar(o);if(await _(n,s=>sr(s)),i.length>0){t.text=`Installing ${i.join(", ")}...`;let s=await j(e);await xe(e,s,i)}t.succeed(La.green("Commitizen configured. Use `commit` to start a guided commit."))}catch(r){throw t.fail("Failed to set up Commitizen."),r}};var eo={id:"commitizen",name:"Commitizen",description:"Guided conventional-commit prompt via `commit` script",detect:async e=>m(Ga.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:Be};S();P();import Ja from"node:path";import Ua from"node:path";import za from"picocolors";P();S();P();import to from"node:path";import Ha from"degit";var ro=async(e,t)=>{t.text="Fetching assets from starter repo...",await Ha("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},no=async(e,t)=>{let r=to.join(e,c.THEME_PROVIDER),n=to.join(t,"src/providers/CustomThemeProvider.tsx");await F(n,r)};S();P();import qe from"node:path";S();P();import oo from"node:path";var vt=async e=>{let t=[oo.join(e,c.ROOT_LAYOUT),oo.join(e,"src/app/[locale]/layout.tsx")];for(let r of t)if(m(r)&&(await f(r)).includes("<body"))return r;for(let r of t)if(m(r))return r;return""};var io=async e=>{let t=qe.join(e,c.THEME_PROVIDER),r=qe.join(e,c.GLOBALS_CSS),n=qe.join(e,"package.json");if(m(t))return{isSetup:!0,reason:"CustomThemeProvider.tsx exists"};if(m(n)){let o=JSON.parse(await f(n)),i="@teispace/next-themes";if(o.dependencies?.[i]||o.devDependencies?.[i])return{isSetup:!0,reason:`${i} is installed`}}return m(r)&&(await f(r)).includes("@custom-variant dark")?{isSetup:!0,reason:"Dark theme CSS found in globals.css"}:{isSetup:!1,reason:""}},so=async e=>{let t=qe.join(e,c.GLOBALS_CSS),r=qe.join(e,c.PROVIDERS_INDEX),n=await vt(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 wt from"node:path";var ao=async e=>{let t=wt.join(e,c.PROVIDERS_INDEX),r=await f(t);r.includes("CustomThemeProvider")||(r+=`export * from './CustomThemeProvider';
692
- `,await g(t,r))},co=async e=>{let t=wt.join(e,"src/providers/RootProvider.tsx");if(!m(t))return;let r=await f(t),n="'use client';",o=r.includes(n);if(o&&(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')/,(i,s,a,p)=>`${s}${a.trim()?`${a.trim()}, CustomThemeProvider `:" CustomThemeProvider "}${p}`):r=`import { CustomThemeProvider } from '@/providers';
693
- ${r}`),o&&(r=`${n}
694
- ${r}`),!r.includes("<CustomThemeProvider"))if(r.includes("{children}"))r=r.replace(/\{children\}/,"<CustomThemeProvider>{children}</CustomThemeProvider>");else{let i=r.match(/return\s*\(\s*([\s\S]*?)\s*\);/);i&&(r=r.replace(i[0],`return (
834
+ `);t=t.replace(/^const\s+withNextIntl\s*=\s*createNextIntlPlugin\([^)]*\);\s*\n?/m,"");let r=/withNextIntl\(\s*((?:[^()]|\([^()]*\))+?)\s*\)/;return r.test(t)?(t=t.replace(r,"$1"),t):null},Si=e=>{let t=yr(e,"withBundleAnalyzer"),r=/^const\s+bundleAnalyzer\s*=\s*withBundleAnalyzer\(\{[\s\S]*?\}\);\s*\n?/m;if(!r.test(t))return null;t=t.replace(r,"");let n=/bundleAnalyzer\(\s*((?:[^()]|\([^()]*\))+?)\s*\)/;return n.test(t)?(t=t.replace(n,"$1"),t):null};var Ci={id:"bundle-analyzer",name:"Bundle Analyzer",description:"@next/bundle-analyzer wrapped around the default export",detect:async e=>{let t=Ac.join(e,c.NEXT_CONFIG);return m(t)?/@next\/bundle-analyzer/.test(await f(t)):!1},files:[],packages:[{name:"@next/bundle-analyzer",kind:"devDependency"}],scripts:[{name:"analyze",expectedValue:"ANALYZE=true next build"}],injections:[{file:c.NEXT_CONFIG,description:"withBundleAnalyzer import + wrapping",presence:/@next\/bundle-analyzer/,removePattern:Si}],apply:rt};S();P();import Fc from"node:path";S();import Ei from"node:path";import _c from"picocolors";P();var xr=e=>{let t={...e.scripts??{}},r={...e.devDependencies??{}};return t.commit||(t.commit="cz"),r[T.COMMITIZEN]||(r[T.COMMITIZEN]="*"),r[T.CZ_CONVENTIONAL_CHANGELOG]||(r[T.CZ_CONVENTIONAL_CHANGELOG]="*"),{...e,scripts:t,devDependencies:r}},Pr=e=>{let t=e.devDependencies??{},r=[];return t[T.COMMITIZEN]||r.push(T.COMMITIZEN),t[T.CZ_CONVENTIONAL_CHANGELOG]||r.push(T.CZ_CONVENTIONAL_CHANGELOG),r};var Oc=`${JSON.stringify({path:"cz-conventional-changelog"},null,2)}
835
+ `,nt=async e=>{let t=b("Setting up Commitizen...");try{let r=Ei.join(e,c.CZRC);m(r)||await g(r,Oc);let n=Ei.join(e,c.PACKAGE_JSON),i=JSON.parse(await f(n)),o=Pr(i);if(await D(n,s=>xr(s)),o.length>0){t.text=`Installing ${o.join(", ")}...`;let s=await k(e);await xe(e,s,o)}t.succeed(_c.green("Commitizen configured. Use `commit` to start a guided commit."))}catch(r){throw t.fail("Failed to set up Commitizen."),r}};var Ti={id:"commitizen",name:"Commitizen",description:"Guided conventional-commit prompt via `commit` script",detect:async e=>m(Fc.join(e,c.CZRC)),files:[{path:c.CZRC,generated:!0}],packages:[{name:"commitizen",kind:"devDependency"},{name:"cz-conventional-changelog",kind:"devDependency"}],scripts:[{name:"commit",expectedValue:"cz"}],injections:[],apply:nt};S();P();import Mc from"node:path";import Dc from"node:path";import Lc from"picocolors";P();S();P();import bi from"node:path";import jc from"degit";var Ri=async(e,t)=>{t.text="Fetching assets from starter repo...",await jc("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},$i=async(e,t)=>{let r=bi.join(e,c.THEME_PROVIDER),n=bi.join(t,"src/providers/CustomThemeProvider.tsx");await N(n,r)};S();P();import it from"node:path";S();P();import Ii from"node:path";var Nt=async e=>{let t=[Ii.join(e,c.ROOT_LAYOUT),Ii.join(e,"src/app/[locale]/layout.tsx")];for(let r of t)if(m(r)&&(await f(r)).includes("<body"))return r;for(let r of t)if(m(r))return r;return""};var Ni=async e=>{let t=it.join(e,c.THEME_PROVIDER),r=it.join(e,c.GLOBALS_CSS),n=it.join(e,"package.json");if(m(t))return{isSetup:!0,reason:"CustomThemeProvider.tsx exists"};if(m(n)){let i=JSON.parse(await f(n)),o="@teispace/next-themes";if(i.dependencies?.[o]||i.devDependencies?.[o])return{isSetup:!0,reason:`${o} is installed`}}return m(r)&&(await f(r)).includes("@custom-variant dark")?{isSetup:!0,reason:"Dark theme CSS found in globals.css"}:{isSetup:!1,reason:""}},ki=async e=>{let t=it.join(e,c.GLOBALS_CSS),r=it.join(e,c.PROVIDERS_INDEX),n=await Nt(e);if(!m(t)||!n||!m(r))throw new Error("Project structure mismatch. Ensure src/styles/globals.css, src/app/layout.tsx (or src/app/[locale]/layout.tsx), and src/providers/index.ts exist.");return n};S();P();import kt from"node:path";var Ai=async e=>{let t=kt.join(e,c.PROVIDERS_INDEX),r=await f(t);r.includes("CustomThemeProvider")||(r+=`export * from './CustomThemeProvider';
836
+ `,await g(t,r))},_i=async e=>{let t=kt.join(e,"src/providers/RootProvider.tsx");if(!m(t))return;let r=await f(t),n="'use client';",i=r.includes(n);if(i&&(r=r.replace(n,"").trim()),r.includes("CustomThemeProvider")||(/import\s*\{[^}]*\}\s*from\s*'@\/providers'/.test(r)?r=r.replace(/(import\s*\{)([^}]*)(\}\s*from\s*'@\/providers')/,(o,s,a,p)=>`${s}${a.trim()?`${a.trim()}, CustomThemeProvider `:" CustomThemeProvider "}${p}`):r=`import { CustomThemeProvider } from '@/providers';
837
+ ${r}`),i&&(r=`${n}
838
+ ${r}`),!r.includes("<CustomThemeProvider"))if(r.includes("{children}"))r=r.replace(/\{children\}/,"<CustomThemeProvider>{children}</CustomThemeProvider>");else{let o=r.match(/return\s*\(\s*([\s\S]*?)\s*\);/);o&&(r=r.replace(o[0],`return (
695
839
  <CustomThemeProvider>
696
- ${i[1]}
840
+ ${o[1]}
697
841
  </CustomThemeProvider>
698
- );`))}await g(t,r)},po=async(e,t)=>{let r=wt.join(e,c.GLOBALS_CSS),n=wt.join(t,"src/styles/globals.css"),o="";if(m(n)){let s=await f(n),a=s.match(/@custom-variant dark \(.*?\);/),p=s.match(/@theme \{[\s\S]*?\}/);a&&(o+=`
842
+ );`))}await g(t,r)},Oi=async(e,t)=>{let r=kt.join(e,c.GLOBALS_CSS),n=kt.join(t,"src/styles/globals.css"),i="";if(m(n)){let s=await f(n),a=s.match(/@custom-variant dark \(.*?\);/),p=s.match(/@theme \{[\s\S]*?\}/);a&&(i+=`
699
843
  ${a[0]}
700
- `),p&&(o+=`
844
+ `),p&&(i+=`
701
845
  ${p[0]}
702
- `)}o||(o=`
846
+ `)}i||(i=`
703
847
  @custom-variant dark (&:where(.dark, .dark *));
704
848
 
705
849
  @theme {
706
850
  --color-dark: #202938;
707
851
  --color-light: #f5f5f5;
708
852
  }
709
- `);let i=await f(r);if(!i.includes("@custom-variant dark")){if(i.includes("@import")){let s=i.lastIndexOf("@import"),a=i.indexOf(`
710
- `,s);i=i.slice(0,a+1)+o+i.slice(a+1)}else i=o+i;await g(r,i)}},lo=async e=>{let t=await f(e);t.includes("dark:bg-dark")||(t=t.replace(/className="([^"]*)"/,'className="$1 bg-light dark:bg-dark"'),await g(e,t))};var Xe=async e=>{let t=b("Setting up Dark Theme..."),r=Ua.join(e,".next-maker-temp");try{let{isSetup:n,reason:o}=await io(e);if(n){t.fail(`Dark Theme is already set up (${o}).`);return}let i=await so(e);await ro(r,t),await no(e,r),await ao(e),await co(e),await po(e,r),await lo(i),t.text="Installing @teispace/next-themes...",await V(e,"@teispace/next-themes"),t.text="Formatting code...";let s=await j(e);await q(e,s,"lint:fix"),t.succeed(za.green("Dark Theme setup successfully!"))}catch(n){throw t.fail("Failed to setup Dark Theme."),n}finally{await w(r)}};var mo={id:"dark-theme",name:"Dark Theme",description:"@teispace/next-themes + CustomThemeProvider",detect:async e=>m(Ja.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:Xe};import Ba from"node:fs/promises";import St from"node:path";import Ct from"enquirer";import cr from"picocolors";P();S();P();import Y from"node:fs/promises";import C from"node:path";import Va from"degit";var uo=async(e,t)=>{t.text="Downloading assets from starter repository...",await Va("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},fo=async(e,t,r,n)=>{let o=C.join(e,c.HTTP_UTILS),i=C.join(t,c.HTTP_UTILS);await Y.cp(C.join(t,c.ERRORS_DIR),C.join(e,c.ERRORS_DIR),{recursive:!0});let s=C.join(e,c.APP_APIS);m(s)||await F(C.join(t,c.APP_APIS),s);let a=C.join(e,c.API_URL_FILE);m(a)||await F(C.join(t,c.API_URL_FILE),a);let p=C.join(e,c.CONSTANTS);if(!m(p))await F(C.join(t,c.CONSTANTS),p);else{let d=await f(p),h=!1;d.includes("API_RESPONSE_DATA_KEY")||(d+=`
853
+ `);let o=await f(r);if(!o.includes("@custom-variant dark")){if(o.includes("@import")){let s=o.lastIndexOf("@import"),a=o.indexOf(`
854
+ `,s);o=o.slice(0,a+1)+i+o.slice(a+1)}else o=i+o;await g(r,o)}},Fi=async e=>{let t=await f(e);t.includes("dark:bg-dark")||(t=t.replace(/className="([^"]*)"/,'className="$1 bg-light dark:bg-dark"'),await g(e,t))};var ot=async e=>{let t=b("Setting up Dark Theme..."),r=Dc.join(e,".next-maker-temp");try{let{isSetup:n,reason:i}=await Ni(e);if(n){t.fail(`Dark Theme is already set up (${i}).`);return}let o=await ki(e);await Ri(r,t),await $i(e,r),await Ai(e),await _i(e),await Oi(e,r),await Fi(o),t.text="Installing @teispace/next-themes...",await G(e,"@teispace/next-themes"),t.text="Formatting code...";let s=await k(e);await z(e,s,"lint:fix"),t.succeed(Lc.green("Dark Theme setup successfully!"))}catch(n){throw t.fail("Failed to setup Dark Theme."),n}finally{await w(r)}};var ji={id:"dark-theme",name:"Dark Theme",description:"@teispace/next-themes + CustomThemeProvider",detect:async e=>m(Mc.join(e,c.THEME_PROVIDER)),files:[{path:c.THEME_PROVIDER,generated:!0}],packages:[{name:"@teispace/next-themes",kind:"dependency"}],scripts:[],injections:[{file:"src/providers/RootProvider.tsx",description:"<CustomThemeProvider> wrap",presence:/CustomThemeProvider/,removePattern:Ae("CustomThemeProvider")}],apply:ot};import Hc from"node:fs/promises";import At from"node:path";import _t from"enquirer";import wr from"picocolors";P();S();P();import X from"node:fs/promises";import C from"node:path";import Gc from"degit";var Di=async(e,t)=>{t.text="Downloading assets from starter repository...",await Gc("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Li=async(e,t,r,n)=>{let i=C.join(e,c.HTTP_UTILS),o=C.join(t,c.HTTP_UTILS);await X.cp(C.join(t,c.ERRORS_DIR),C.join(e,c.ERRORS_DIR),{recursive:!0});let s=C.join(e,c.APP_APIS);m(s)||await N(C.join(t,c.APP_APIS),s);let a=C.join(e,c.API_URL_FILE);m(a)||await N(C.join(t,c.API_URL_FILE),a);let p=C.join(e,c.CONSTANTS);if(!m(p))await N(C.join(t,c.CONSTANTS),p);else{let d=await f(p),h=!1;d.includes("API_RESPONSE_DATA_KEY")||(d+=`
711
855
  export const API_RESPONSE_DATA_KEY = 'data';
712
856
  `,h=!0),d.includes("SAVE_AUTH_TOKENS")||(d+=`
713
857
  export const SAVE_AUTH_TOKENS = false;
714
- `,h=!0),h&&await g(p,d)}let u=C.join(e,c.STORAGE_SERVICE);if(m(u)||await Y.cp(C.join(t,c.STORAGE_SERVICE),u,{recursive:!0}),await Y.cp(C.join(t,c.COMMON_TYPES_DIR),C.join(e,c.COMMON_TYPES_DIR),{recursive:!0}),await Y.cp(C.join(t,c.UTILITY_TYPES_DIR),C.join(e,c.UTILITY_TYPES_DIR),{recursive:!0}),await F(C.join(i,"token-store.ts"),C.join(o,"token-store.ts")),await F(C.join(i,"client-utils.ts"),C.join(o,"client-utils.ts")),await Y.cp(C.join(t,c.HTTP_SHARED),C.join(e,c.HTTP_SHARED),{recursive:!0,force:!0}),n&&n.length>0)for(let d of n){let h=C.join(e,d==="fetch"?c.FETCH_CLIENT:c.AXIOS_CLIENT);await w(h)}for(let d of r)d==="fetch"?await Y.cp(C.join(t,c.FETCH_CLIENT),C.join(e,c.FETCH_CLIENT),{recursive:!0}):await Y.cp(C.join(t,c.AXIOS_CLIENT),C.join(e,c.AXIOS_CLIENT),{recursive:!0});await F(C.join(i,"index.ts"),C.join(o,"index.ts")),await F(C.join(t,c.HTTP_TYPES),C.join(e,c.HTTP_TYPES))},go=async e=>{let{isFileUsed:t,isStringUsed:r}=await Promise.resolve().then(()=>(ut(),Kr));await w(C.join(e,c.HTTP_UTILS));let n=C.join(e,c.STORAGE_SERVICE);m(n)&&(await r(e,"SecureStorageService",[n])||await w(n));let o=C.join(e,c.API_URL_FILE);m(o)&&(await r(e,"getApiBaseUrl",[o])||await Y.unlink(o));let i=C.join(e,c.CONSTANTS);if(m(i)){let u=await f(i),d=!1;await r(e,"API_RESPONSE_DATA_KEY",[i])||(u=u.replace(/export const API_RESPONSE_DATA_KEY = .*;\n?/g,""),d=!0),await r(e,"SAVE_AUTH_TOKENS",[i])||(u=u.replace(/export const SAVE_AUTH_TOKENS = .*;\n?/g,""),d=!0),d&&(u=`${u.replace(/\n\s*\n/g,`
858
+ `,h=!0),h&&await g(p,d)}let u=C.join(e,c.STORAGE_SERVICE);if(m(u)||await X.cp(C.join(t,c.STORAGE_SERVICE),u,{recursive:!0}),await X.cp(C.join(t,c.COMMON_TYPES_DIR),C.join(e,c.COMMON_TYPES_DIR),{recursive:!0}),await X.cp(C.join(t,c.UTILITY_TYPES_DIR),C.join(e,c.UTILITY_TYPES_DIR),{recursive:!0}),await N(C.join(o,"token-store.ts"),C.join(i,"token-store.ts")),await N(C.join(o,"client-utils.ts"),C.join(i,"client-utils.ts")),await X.cp(C.join(t,c.HTTP_SHARED),C.join(e,c.HTTP_SHARED),{recursive:!0,force:!0}),await N(C.join(o,"server.ts"),C.join(i,"server.ts")),await X.cp(C.join(t,c.HTTP_BUNDLE_SENTINEL_DIR),C.join(e,c.HTTP_BUNDLE_SENTINEL_DIR),{recursive:!0,force:!0}),n&&n.length>0)for(let d of n){let h=C.join(e,d==="fetch"?c.FETCH_CLIENT:c.AXIOS_CLIENT);await w(h)}for(let d of r)d==="fetch"?await X.cp(C.join(t,c.FETCH_CLIENT),C.join(e,c.FETCH_CLIENT),{recursive:!0}):await X.cp(C.join(t,c.AXIOS_CLIENT),C.join(e,c.AXIOS_CLIENT),{recursive:!0});await N(C.join(o,"index.ts"),C.join(i,"index.ts")),await N(C.join(t,c.HTTP_TYPES),C.join(e,c.HTTP_TYPES))},Mi=async e=>{let{isFileUsed:t,isStringUsed:r}=await Promise.resolve().then(()=>(Ue(),gn));await w(C.join(e,c.HTTP_UTILS));let n=C.join(e,c.STORAGE_SERVICE);m(n)&&(await r(e,"SecureStorageService",[n])||await w(n));let i=C.join(e,c.API_URL_FILE);m(i)&&(await r(e,"getApiBaseUrl",[i])||await X.unlink(i));let o=C.join(e,c.CONSTANTS);if(m(o)){let u=await f(o),d=!1;await r(e,"API_RESPONSE_DATA_KEY",[o])||(u=u.replace(/export const API_RESPONSE_DATA_KEY = .*;\n?/g,""),d=!0),await r(e,"SAVE_AUTH_TOKENS",[o])||(u=u.replace(/export const SAVE_AUTH_TOKENS = .*;\n?/g,""),d=!0),d&&(u=`${u.replace(/\n\s*\n/g,`
715
859
 
716
860
  `).trim()}
717
- `,await g(i,u))}let s=C.join(e,c.ERRORS_DIR);if(m(s)){let u=await Y.readdir(s),d=!1;for(let h of u){let x=C.parse(h).name;if(await t(e,x,[C.join(s,h)])){d=!0;break}}d||await w(s)}let a=C.join(e,c.COMMON_TYPES_DIR);m(a)&&(await Y.readdir(a)).length===0&&await w(a);let p=C.join(e,c.UTILITY_TYPES_DIR);m(p)&&(await Y.readdir(p)).length===0&&await w(p)};S();P();import We from"node:path";var ho=async e=>{let t=We.join(e,c.FETCH_CLIENT_FILE),r=We.join(e,c.AXIOS_CLIENT_FILE),n=m(t),o=m(r);return n&&o?{status:"both",reason:"Both Fetch and Axios clients are detected"}:n?{status:"fetch",reason:"Fetch client is already setup"}:o?{status:"axios",reason:"Axios client is already setup"}:{status:"none"}},yo=async e=>{let r=[We.join(e,"src/lib"),We.join(e,"src/types"),We.join(e,"src/lib/config")].filter(n=>!m(n));if(r.length>0)throw new Error(`Invalid project structure. Missing directories:
861
+ `,await g(o,u))}let s=C.join(e,c.ERRORS_DIR);if(m(s)){let u=await X.readdir(s),d=!1;for(let h of u){let x=C.parse(h).name;if(await t(e,x,[C.join(s,h)])){d=!0;break}}d||await w(s)}let a=C.join(e,c.COMMON_TYPES_DIR);m(a)&&(await X.readdir(a)).length===0&&await w(a);let p=C.join(e,c.UTILITY_TYPES_DIR);m(p)&&(await X.readdir(p)).length===0&&await w(p)};S();P();import st from"node:path";var Gi=async e=>{let t=st.join(e,c.FETCH_CLIENT_FILE),r=st.join(e,c.AXIOS_CLIENT_FILE),n=m(t),i=m(r);return n&&i?{status:"both",reason:"Both Fetch and Axios clients are detected"}:n?{status:"fetch",reason:"Fetch client is already setup"}:i?{status:"axios",reason:"Axios client is already setup"}:{status:"none"}},Hi=async e=>{let r=[st.join(e,"src/lib"),st.join(e,"src/types"),st.join(e,"src/lib/config")].filter(n=>!m(n));if(r.length>0)throw new Error(`Invalid project structure. Missing directories:
718
862
  ${r.map(n=>`- ${n}`).join(`
719
- `)}`)};ut();var Ye=async e=>{let t=b("Checking HTTP Client setup..."),r=St.join(e,".next-maker-temp-http");try{let{status:n,reason:o}=await ho(e);t.stop();let i=await qa(n,o);if(i.type==="cancel"){console.log(cr.yellow("Setup cancelled."));return}if(t.start("Setting up HTTP client(s)..."),await yo(e),await uo(r,t),i.type==="replace"&&i.fromClient&&(t.text="Migrating client usages...",await Mt(e,i.fromClient,i.clients[0])),i.type!=="remove-both"&&i.type!=="remove-one"){t.text="Copying client files...";let k=i.type==="replace"&&i.fromClient?[i.fromClient]:void 0;await fo(e,r,i.clients,k)}if(i.type==="remove-one"||i.type==="remove-both"){t.text="Removing client files...";let{PROJECT_PATHS:k}=await Promise.resolve().then(()=>(S(),qr));for(let $ of i.clients){let J=St.join(e,$==="fetch"?k.FETCH_CLIENT:k.AXIOS_CLIENT);await w(J)}xo(n,i).length===0&&(t.text="Performing full cleanup...",await go(e),await Gt(e))}let s=xo(n,i);s.length>0&&(t.text="Configuring client...",await _t(e,s),await jt(e),await Dt(e),await Lt(e)),await Re(e,s),t.text="Managing dependencies...";let a=St.join(e,"package.json"),p=JSON.parse(await Ba.readFile(a,"utf-8")),u={...p.dependencies,...p.devDependencies};s.includes("axios")?u.axios||(t.text="Installing Axios...",await V(e,"axios")):u.axios&&(t.text="Uninstalling Axios...",await dt(e,"axios")),s.length>0?u["server-only"]||(t.text="Installing server-only...",await V(e,"server-only")):u["server-only"]&&(t.text="Uninstalling server-only...",await dt(e,"server-only"));let d=St.join(e,"src/services/storage");s.length>0||m(d)?u["react-secure-storage"]||(t.text="Installing react-secure-storage...",await V(e,"react-secure-storage")):u["react-secure-storage"]&&(t.text="Uninstalling react-secure-storage...",await dt(e,"react-secure-storage")),t.text="Formatting code...";let x=await j(e);await q(e,x,"lint:fix"),t.succeed(cr.green(Xa(i)))}catch(n){throw t.fail("Failed to setup HTTP Client."),n}finally{await w(r)}};async function qa(e,t){if(e==="none"){let{choice:n}=await Ct.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 Ct.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 Ct.prompt({type:"select",name:"action",message:`${t}. What would you like to do?`,choices:[{name:"cancel",message:"Keep Axios only (cancel)"},{name:"add",message:"Add Fetch (have both)"},{name:"replace",message:"Replace with Fetch only"},{name:"remove",message:"Remove Axios"}]});if(n==="cancel")return{type:"cancel",clients:[]};if(n==="add")return{type:"add",clients:["fetch"]};if(n==="replace")return{type:"replace",clients:["fetch"],fromClient:"axios"};if(n==="remove")return{type:"remove-one",clients:["axios"]}}console.log(cr.yellow(`\u2716 ${t}`));let{action:r}=await Ct.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 xo(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 Xa(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!"}var Po={id:"http-client",name:"HTTP Client",description:"Axios and/or Fetch client utilities",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(G(),De));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/config/api-url.ts",generated:!0}],packages:[],scripts:[],injections:[],apply:Ye};S();import pr from"node:path";import Za from"picocolors";P();S();P();import Wa from"node:fs/promises";import me from"node:path";import Ya from"degit";var vo=async(e,t)=>{t.text="Fetching assets from starter repo...",await Ya("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},wo=async(e,t)=>{let r=me.join(t,"src/i18n"),n=me.join(e,c.I18N_DIR);await Wa.cp(r,n,{recursive:!0});let o=me.join(t,"src/proxy.ts"),i=me.join(e,c.PROXY);await F(o,i);let s=me.join(t,"src/types/i18n.ts"),a=me.join(e,c.I18N_TYPES);await F(s,a);let p=me.join(t,"src/lib/config/app-locales.ts"),u=me.join(e,c.APP_LOCALES);await F(p,u)};S();P();import Tt from"node:path";var So=async e=>{let t=Tt.join(e,c.I18N_DIR),r=Tt.join(e,"package.json");if(m(t))return{isSetup:!0,reason:"src/i18n directory exists"};if(m(r)){let n=JSON.parse(await f(r));if(n.dependencies?.["next-intl"]||n.devDependencies?.["next-intl"])return{isSetup:!0,reason:"next-intl is installed"}}return{isSetup:!1,reason:""}},Co=async e=>{let t=Tt.join(e,c.ROOT_LAYOUT),r=Tt.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 Ka from"node:fs/promises";import se from"node:path";var To=async e=>{let t=se.join(e,c.NEXT_CONFIG);if(m(t)){let r=await f(t);if(!r.includes("createNextIntlPlugin")){r=`import createNextIntlPlugin from 'next-intl/plugin';
863
+ `)}`)};Ue();var at=async e=>{let t=b("Checking HTTP Client setup..."),r=At.join(e,".next-maker-temp-http");try{let{status:n,reason:i}=await Gi(e);t.stop();let o=await Uc(n,i);if(o.type==="cancel"){console.log(wr.yellow("Setup cancelled."));return}if(t.start("Setting up HTTP client(s)..."),await Hi(e),await Di(r,t),o.type==="replace"&&o.fromClient&&(t.text="Migrating client usages...",await Xt(e,o.fromClient,o.clients[0])),o.type!=="remove-both"&&o.type!=="remove-one"){t.text="Copying client files...";let $=o.type==="replace"&&o.fromClient?[o.fromClient]:void 0;await Li(e,r,o.clients,$)}if(o.type==="remove-one"||o.type==="remove-both"){t.text="Removing client files...";let{PROJECT_PATHS:$}=await Promise.resolve().then(()=>(S(),an));for(let I of o.clients){let V=At.join(e,I==="fetch"?$.FETCH_CLIENT:$.AXIOS_CLIENT);await w(V)}Ui(n,o).length===0&&(t.text="Performing full cleanup...",await Mi(e),await Zt(e))}let s=Ui(n,o);s.length>0?(t.text="Configuring client...",await Jt(e,s),await Vt(e),await Wt(e),await qt(e),await Kt(e),await Ne(e,s),await ke(e,s)):await He(e),await Ie(e,s),t.text="Managing dependencies...";let a=At.join(e,"package.json"),p=JSON.parse(await Hc.readFile(a,"utf-8")),u={...p.dependencies,...p.devDependencies};s.includes("axios")?u.axios||(t.text="Installing Axios...",await G(e,"axios")):u.axios&&(t.text="Uninstalling Axios...",await $e(e,"axios")),s.length>0?u["server-only"]||(t.text="Installing server-only...",await G(e,"server-only")):u["server-only"]&&(t.text="Uninstalling server-only...",await $e(e,"server-only"));let d=At.join(e,"src/services/storage");s.length>0||m(d)?u["react-secure-storage"]||(t.text="Installing react-secure-storage...",await G(e,"react-secure-storage")):u["react-secure-storage"]&&(t.text="Uninstalling react-secure-storage...",await $e(e,"react-secure-storage")),t.text="Formatting code...";let x=await k(e);await z(e,x,"lint:fix"),t.succeed(wr.green(Bc(o)))}catch(n){throw t.fail("Failed to setup HTTP Client."),n}finally{await w(r)}};async function Uc(e,t){if(e==="none"){let{choice:n}=await _t.prompt({type:"select",name:"choice",message:"Which HTTP client(s) do you want to setup?",choices:[{name:"fetch",message:"Fetch (Native)"},{name:"axios",message:"Axios"},{name:"both",message:"Both (Fetch + Axios)"}]});return n==="both"?{type:"install",clients:["fetch","axios"]}:{type:"install",clients:[n]}}if(e==="fetch"){let{action:n}=await _t.prompt({type:"select",name:"action",message:`${t}. What would you like to do?`,choices:[{name:"cancel",message:"Keep Fetch only (cancel)"},{name:"add",message:"Add Axios (have both)"},{name:"replace",message:"Replace with Axios only"},{name:"remove",message:"Remove Fetch"}]});if(n==="cancel")return{type:"cancel",clients:[]};if(n==="add")return{type:"add",clients:["axios"]};if(n==="replace")return{type:"replace",clients:["axios"],fromClient:"fetch"};if(n==="remove")return{type:"remove-one",clients:["fetch"]}}if(e==="axios"){let{action:n}=await _t.prompt({type:"select",name:"action",message:`${t}. What would you like to do?`,choices:[{name:"cancel",message:"Keep Axios only (cancel)"},{name:"add",message:"Add Fetch (have both)"},{name:"replace",message:"Replace with Fetch only"},{name:"remove",message:"Remove Axios"}]});if(n==="cancel")return{type:"cancel",clients:[]};if(n==="add")return{type:"add",clients:["fetch"]};if(n==="replace")return{type:"replace",clients:["fetch"],fromClient:"axios"};if(n==="remove")return{type:"remove-one",clients:["axios"]}}console.log(wr.yellow(`\u2716 ${t}`));let{action:r}=await _t.prompt({type:"select",name:"action",message:"What would you like to do?",choices:[{name:"cancel",message:"Keep both (cancel)"},{name:"remove-fetch",message:"Remove Fetch (keep Axios)"},{name:"remove-axios",message:"Remove Axios (keep Fetch)"},{name:"remove-both",message:"Remove both"}]});return r==="cancel"?{type:"cancel",clients:[]}:r==="remove-fetch"?{type:"remove-one",clients:["fetch"]}:r==="remove-axios"?{type:"remove-one",clients:["axios"]}:r==="remove-both"?{type:"remove-both",clients:["fetch","axios"]}:{type:"cancel",clients:[]}}function Ui(e,t){return t.type==="install"?t.clients:t.type==="add"?[...e==="fetch"?["fetch"]:["axios"],...t.clients]:t.type==="replace"?t.clients:t.type==="remove-one"?e==="both"?t.clients[0]==="fetch"?["axios"]:["fetch"]:[]:[]}function Bc(e){if(e.type==="install")return`HTTP Client (${e.clients.map(r=>r==="fetch"?"Fetch":"Axios").join(" + ")}) setup successfully!`;if(e.type==="add")return`${e.clients[0]==="fetch"?"Fetch":"Axios"} client added successfully! Both clients are now available.`;if(e.type==="replace"){let t=e.fromClient==="fetch"?"Fetch":"Axios",r=e.clients[0]==="fetch"?"Fetch":"Axios";return`Replaced ${t} with ${r} successfully! Imports automatically migrated.`}return e.type==="remove-one"?`${e.clients[0]==="fetch"?"Fetch":"Axios"} client removed successfully!`:e.type==="remove-both"?"Both HTTP clients removed successfully!":"HTTP Client setup completed!"}Ue();var Bi=/<HttpClientBundleSentinel\s*\/>/,zi={id:"http-client",name:"HTTP Client",description:"Axios and/or Fetch client utilities",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(H(),qe));return(await t(e)).httpClient!=="none"},files:[{path:"src/lib/utils/http",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds the http client + any service modules you wired through it \u2014 review before deleting"},{path:"src/lib/utils/http/shared",generated:!0,isDir:!0},{path:"src/lib/utils/http/server.ts",generated:!0},{path:"src/lib/utils/http/__bundle-sentinel__",generated:!0,isDir:!0},{path:"src/lib/config/api-url.ts",generated:!0}],packages:[],scripts:[],injections:[{file:"src/app/[locale]/layout.tsx",description:"<HttpClientBundleSentinel /> mount in locale layout",presence:Bi,removePattern:Ge},{file:"src/app/layout.tsx",description:"<HttpClientBundleSentinel /> mount in root layout",presence:Bi,removePattern:Ge}],apply:at};S();import vr from"node:path";import Wc from"picocolors";P();S();P();import zc from"node:fs/promises";import me from"node:path";import Jc from"degit";var Ji=async(e,t)=>{t.text="Fetching assets from starter repo...",await Jc("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Vi=async(e,t)=>{let r=me.join(t,"src/i18n"),n=me.join(e,c.I18N_DIR);await zc.cp(r,n,{recursive:!0});let i=me.join(t,"src/proxy.ts"),o=me.join(e,c.PROXY);await N(i,o);let s=me.join(t,"src/types/i18n.ts"),a=me.join(e,c.I18N_TYPES);await N(s,a);let p=me.join(t,"src/lib/config/app-locales.ts"),u=me.join(e,c.APP_LOCALES);await N(p,u)};S();P();import Ot from"node:path";var Wi=async e=>{let t=Ot.join(e,c.I18N_DIR),r=Ot.join(e,"package.json");if(m(t))return{isSetup:!0,reason:"src/i18n directory exists"};if(m(r)){let n=JSON.parse(await f(r));if(n.dependencies?.["next-intl"]||n.devDependencies?.["next-intl"])return{isSetup:!0,reason:"next-intl is installed"}}return{isSetup:!1,reason:""}},qi=async e=>{let t=Ot.join(e,c.ROOT_LAYOUT),r=Ot.join(e,"src/app/[locale]/layout.tsx");if(!m(t)&&!m(r))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx exists.")};S();P();import Vc from"node:fs/promises";import se from"node:path";var Xi=async e=>{let t=se.join(e,c.NEXT_CONFIG);if(m(t)){let r=await f(t);if(!r.includes("createNextIntlPlugin")){r=`import createNextIntlPlugin from 'next-intl/plugin';
720
864
  ${r}`;let n=/export default (.*?);/;n.test(r)?r=r.replace(n,`
721
865
  const withNextIntl = createNextIntlPlugin();
722
866
  export default withNextIntl($1);`):(r+=`
723
867
  const withNextIntl = createNextIntlPlugin();
724
868
  `,r+=`export default withNextIntl(nextConfig);
725
- `),await g(t,r)}}},Eo=async e=>{let t=se.join(e,c.TYPES_INDEX);if(m(t)){let r=await f(t);r.includes("./i18n")||(r+=`export * from './i18n';
726
- `,await g(t,r))}},bo=async e=>{let t=se.join(e,c.CONFIG_INDEX);if(m(t)){let r=await f(t);r.includes("./app-locales")||(r+=`export * from './app-locales';
727
- `,await g(t,r))}},Ro=async e=>{let t=se.join(e,"src/providers/RootProvider.tsx");if(m(t)){let r=await f(t),n="'use client';",o=r.includes(n);if(o&&(r=r.replace(n,"").trim()),r.includes("next-intl")||(r=`import { type AbstractIntlMessages, NextIntlClientProvider } from 'next-intl';
869
+ `),await g(t,r)}}},Yi=async e=>{let t=se.join(e,c.TYPES_INDEX);if(m(t)){let r=await f(t);r.includes("./i18n")||(r+=`export * from './i18n';
870
+ `,await g(t,r))}},Ki=async e=>{let t=se.join(e,c.CONFIG_INDEX);if(m(t)){let r=await f(t);r.includes("./app-locales")||(r+=`export * from './app-locales';
871
+ `,await g(t,r))}},Zi=async e=>{let t=se.join(e,"src/providers/RootProvider.tsx");if(m(t)){let r=await f(t),n="'use client';",i=r.includes(n);if(i&&(r=r.replace(n,"").trim()),r.includes("next-intl")||(r=`import { type AbstractIntlMessages, NextIntlClientProvider } from 'next-intl';
728
872
  import type { SupportedLocale } from '@/types/i18n';
729
- `+r),o&&(r=`${n}
730
- ${r}`),!r.includes("locale: SupportedLocale")){let i=` locale: SupportedLocale;
873
+ `+r),i&&(r=`${n}
874
+ ${r}`),!r.includes("locale: SupportedLocale")){let o=` locale: SupportedLocale;
731
875
  messages: AbstractIntlMessages;
732
876
  timeZone: string;`,s=/(type\s+RootProviderProps\s*=\s*\{)([\s\S]*?)(\};?)/,a=/export const RootProvider = \(\{([\s\S]*?)\}: \{([\s\S]*?)\}\) => \{/;if(s.test(r))r=r.replace(s,(p,u,d,h)=>{let x=d.replace(/\s+$/,"");return`${u}${x}
733
- ${i}
877
+ ${o}
734
878
  ${h}`}),r=r.replace(/export const RootProvider = \(\{([\s\S]*?)\}:\s*RootProviderProps\)/,(p,u)=>{let d=u.trim().replace(/,$/,"");return`export const RootProvider = ({ ${d?`${d}, `:""}locale, messages, timeZone }: RootProviderProps)`});else{let p=r.match(a);if(p){let u=p[1].trim().replace(/,$/,""),d=p[2].trim().replace(/;$/,""),h=`
735
879
  ${u?`${u},
736
880
  `:""}locale,
@@ -741,27 +885,27 @@ ${h}`}),r=r.replace(/export const RootProvider = \(\{([\s\S]*?)\}:\s*RootProvide
741
885
  messages: AbstractIntlMessages;
742
886
  timeZone: string;`;r=r.replace(p[0],`export const RootProvider = ({${h}
743
887
  }: {${x}
744
- }) => {`)}}}if(!r.includes("<NextIntlClientProvider")){let i=r.match(/return\s*(?:\(\s*)?([\s\S]*?)(?:\s*\))?;/);if(i){let s=i[1],a=`<NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>
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}>
745
889
  {children}
746
- </NextIntlClientProvider>`;if(s.includes("{children}")){let p=s.replace("{children}",a);r=r.replace(i[0],`return (
890
+ </NextIntlClientProvider>`;if(s.includes("{children}")){let p=s.replace("{children}",a);r=r.replace(o[0],`return (
747
891
  ${p}
748
- );`)}else r=r.replace(i[0],`return (
892
+ );`)}else r=r.replace(o[0],`return (
749
893
  <NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>
750
894
  ${s}
751
895
  </NextIntlClientProvider>
752
- );`)}}await g(t,r)}},$o=async e=>{let t=se.join(e,c.ROOT_LAYOUT),r=se.join(e,c.ROOT_PAGE),n=se.join(e,"src/app/[locale]");if(await Ka.mkdir(n,{recursive:!0}),m(t)){let o=se.join(n,"layout.tsx"),i=await f(t);if(i.includes("next-intl")||(i=`import { routing } from '@/i18n/routing';
896
+ );`)}}await g(t,r)}},Qi=async e=>{let t=se.join(e,c.ROOT_LAYOUT),r=se.join(e,c.ROOT_PAGE),n=se.join(e,"src/app/[locale]");if(await Vc.mkdir(n,{recursive:!0}),m(t)){let i=se.join(n,"layout.tsx"),o=await f(t);if(o.includes("next-intl")||(o=`import { routing } from '@/i18n/routing';
753
897
  import { hasLocale } from 'next-intl';
754
898
  import { notFound } from 'next/navigation';
755
899
  import { getMessages, getTimeZone, setRequestLocale } from 'next-intl/server';
756
900
  import { getLocaleDirection } from '@/lib/config/app-locales';
757
- ${i}`),!i.includes("generateStaticParams")){let p=i.indexOf("};",i.indexOf("export const metadata"));if(p!==-1){let u=p+2;i=i.slice(0,u)+`
901
+ ${o}`),!o.includes("generateStaticParams")){let p=o.indexOf("};",o.indexOf("export const metadata"));if(p!==-1){let u=p+2;o=o.slice(0,u)+`
758
902
 
759
903
  export function generateStaticParams() {
760
904
  return routing.locales.map((locale) => ({ locale }));
761
- }`+i.slice(u)}}i=i.replace(/Readonly<\{\s*children:\s*React\.ReactNode;\s*}>/,`Readonly<{
905
+ }`+o.slice(u)}}o=o.replace(/Readonly<\{\s*children:\s*React\.ReactNode;\s*}>/,`Readonly<{
762
906
  children: React.ReactNode;
763
907
  params: Promise<{ locale: string }>;
764
- }>`);let s=/export default (async )?function RootLayout\(\{\s*children,?\s*\}\s*:/,a=i.match(s);if(a){a[1]||(i=i.replace("export default function","export default async function")),i=i.replace(/export default (async )?function RootLayout\(\{\s*children,?\s*\}\s*:/,"export default async function RootLayout({ children, params }:");let u=/export default async function RootLayout[\s\S]*?\)\s*\{/,d=i.match(u);if(d&&d.index!==void 0){let h=d.index+d[0].length-1;i=i.slice(0,h+1)+`
908
+ }>`);let s=/export default (async )?function RootLayout\(\{\s*children,?\s*\}\s*:/,a=o.match(s);if(a){a[1]||(o=o.replace("export default function","export default async function")),o=o.replace(/export default (async )?function RootLayout\(\{\s*children,?\s*\}\s*:/,"export default async function RootLayout({ children, params }:");let u=/export default async function RootLayout[\s\S]*?\)\s*\{/,d=o.match(u);if(d&&d.index!==void 0){let h=d.index+d[0].length-1;o=o.slice(0,h+1)+`
765
909
  const { locale } = await params;
766
910
 
767
911
  if (!hasLocale(routing.locales, locale)) {
@@ -771,31 +915,31 @@ export function generateStaticParams() {
771
915
  setRequestLocale(locale);
772
916
 
773
917
  const [messages, timeZone] = await Promise.all([getMessages(), getTimeZone()]);
774
- `+i.slice(h+1)}i=i.replace(/<RootProvider>/,"<RootProvider locale={locale} messages={messages} timeZone={timeZone}>"),i=i.replace(/<html lang="en"/,"<html lang={locale} dir={getLocaleDirection(locale)}")}await g(o,i),await E(t)}if(m(r)){let o=se.join(n,"page.tsx"),i=await f(r);i.includes("next-intl")||(i=`import { SupportedLocale } from '@/types/i18n';
918
+ `+o.slice(h+1)}o=o.replace(/<RootProvider>/,"<RootProvider locale={locale} messages={messages} timeZone={timeZone}>"),o=o.replace(/<html lang="en"/,"<html lang={locale} dir={getLocaleDirection(locale)}")}await g(i,o),await E(t)}if(m(r)){let i=se.join(n,"page.tsx"),o=await f(r);o.includes("next-intl")||(o=`import { SupportedLocale } from '@/types/i18n';
775
919
  import { setRequestLocale } from 'next-intl/server';
776
- ${i}`),i=i.replace(/export default function Home\(\)/,`type Props = {
920
+ ${o}`),o=o.replace(/export default function Home\(\)/,`type Props = {
777
921
  params: Promise<{ locale: string }>;
778
922
  };
779
923
 
780
- export default async function Home(props: Props)`);let s=i.indexOf("export default async function Home(props: Props) {");if(s!==-1){let a=`
924
+ export default async function Home(props: Props)`);let s=o.indexOf("export default async function Home(props: Props) {");if(s!==-1){let a=`
781
925
  const locale = (await props.params).locale as SupportedLocale;
782
926
  setRequestLocale(locale);
783
- `,p=i.indexOf("{",s);i=i.slice(0,p+1)+a+i.slice(p+1)}await g(o,i),await E(r)}};var Ke=async e=>{let t=b("Setting up Internationalization (next-intl)..."),r=pr.join(e,".next-maker-temp-i18n");try{let{isSetup:n,reason:o}=await So(e);if(n){t.fail(`i18n is already set up (${o}).`);return}await Co(e),await vo(r,t),t.text="Copying i18n files...",await wo(e,r),t.text="Configuring project structure...",await To(e),await Eo(e),await bo(e),await Ro(e),t.text="Migrating to [locale] structure...",await $o(e),t.text="Installing dependencies...",await V(e,"next-intl");let i=pr.join(e,c.VITEST_CONFIG);if(m(i)){let a=JSON.parse(await f(pr.join(e,c.PACKAGE_JSON))),p={...a.dependencies,...a.devDependencies},u=!!(p["@reduxjs/toolkit"]&&p["react-redux"]);await ce(e,{redux:u,i18n:!0})}t.text="Formatting code...";let s=await j(e);await q(e,s,"lint:fix"),t.succeed(Za.green("Internationalization setup successfully!"))}catch(n){throw t.fail("Failed to setup Internationalization."),n}finally{await w(r)}};var Io={id:"i18n",name:"Internationalization",description:"next-intl with [locale] routing, RootProvider, and proxy.ts",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(G(),De));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:Yn},{file:"src/providers/RootProvider.tsx",description:"<NextIntlClientProvider> wrap",presence:/NextIntlClientProvider/,removePattern:$e("NextIntlClientProvider")}],apply:Ke};S();P();import tc from"node:path";S();import Qa from"node:path";import ec from"picocolors";P();var Ze=async e=>{let t=b("Enabling React Compiler...");try{let r=Qa.join(e,c.NEXT_CONFIG);if(!m(r))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await f(r);if(n.includes("reactCompiler:")){t.fail("React Compiler is already configured in next.config.ts.");return}let o=/(const\s+nextConfig\s*:\s*NextConfig\s*=\s*\{)/;if(!o.test(n))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");n=n.replace(o,`$1
784
- reactCompiler: true,`),await g(r,n),t.text="Installing babel-plugin-react-compiler...",await mt(e,"babel-plugin-react-compiler"),t.succeed(ec.green("React Compiler enabled."))}catch(r){throw t.fail("Failed to enable React Compiler."),r}};var No={id:"react-compiler",name:"React Compiler",description:"reactCompiler: true in next.config.ts + babel-plugin-react-compiler",detect:async e=>{let t=tc.join(e,c.NEXT_CONFIG);return m(t)?/reactCompiler\s*:\s*true/.test(await f(t)):!1},files:[],packages:[{name:"babel-plugin-react-compiler",kind:"devDependency"}],scripts:[],injections:[{file:c.NEXT_CONFIG,description:"`reactCompiler: true` flag",presence:/reactCompiler\s*:\s*true/,removePattern:/\n\s*reactCompiler:\s*true,?/}],apply:Ze};S();import dr from"node:path";import nc from"picocolors";P();S();P();import ko from"node:fs/promises";import we from"node:path";import rc from"degit";var Ao=async(e,t)=>{t.text="Fetching assets from starter repo...",await rc("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Oo=async(e,t)=>{let r=we.join(t,"src/providers/StoreProvider.tsx"),n=we.join(e,c.STORE_PROVIDER);await F(r,n);let o=we.join(t,"src/store"),i=we.join(e,c.STORE);await ko.cp(o,i,{recursive:!0})},Fo=async(e,t)=>{let r=we.join(t,"src/features/counter"),n=we.join(e,c.COUNTER_FEATURE);await ko.cp(r,n,{recursive:!0});let o=we.join(n,"components/Counter.tsx");if(await m(o)){let i=await f(o);i=i.replace(/import \{ useTranslations \} from 'next-intl';\n?/,""),i=i.replace(/const t = useTranslations\('Count'\);\n?/,""),i=i.replace(/\{t\('currentCount', \{ count: value \}\)\}/g,"Current Count: {value}"),i=i.replace(/\{t\('increment'\)\}/g,"Increment"),i=i.replace(/\{t\('decrement'\)\}/g,"Decrement"),i=i.replace(/\{t\('reset'\)\}/g,"Reset"),await g(o,i)}};S();P();import lr from"node:path";var _o=async e=>{let t=lr.join(e,c.STORE),r=lr.join(e,"package.json");if(m(t))return{isSetup:!0,reason:"src/store directory exists"};if(m(r)){let n=JSON.parse(await f(r));if(n.dependencies?.["@reduxjs/toolkit"]||n.devDependencies?.["@reduxjs/toolkit"])return{isSetup:!0,reason:"@reduxjs/toolkit is installed"}}return{isSetup:!1,reason:""}},jo=async e=>{let t=lr.join(e,c.PROVIDERS_INDEX);if(!await vt(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 mr from"node:path";var Do=async e=>{},Lo=async e=>{let t=mr.join(e,"src/providers/RootProvider.tsx");if(!m(t))return;let r=await f(t),n="'use client';",o=r.includes(n);if(o&&(r=r.replace(n,"").trim()),r.includes("from '@/store'")||(r=`import type { AppState } from '@/store';
927
+ `,p=o.indexOf("{",s);o=o.slice(0,p+1)+a+o.slice(p+1)}await g(i,o),await E(r)}};var ct=async e=>{let t=b("Setting up Internationalization (next-intl)..."),r=vr.join(e,".next-maker-temp-i18n");try{let{isSetup:n,reason:i}=await Wi(e);if(n){t.fail(`i18n is already set up (${i}).`);return}await qi(e),await Ji(r,t),t.text="Copying i18n files...",await Vi(e,r),t.text="Configuring project structure...",await Xi(e),await Yi(e),await Ki(e),await Zi(e),t.text="Migrating to [locale] structure...",await Qi(e),t.text="Installing dependencies...",await G(e,"next-intl");let o=vr.join(e,c.VITEST_CONFIG);if(m(o)){let a=JSON.parse(await f(vr.join(e,c.PACKAGE_JSON))),p={...a.dependencies,...a.devDependencies},u=!!(p["@reduxjs/toolkit"]&&p["react-redux"]);await ce(e,{redux:u,i18n:!0})}t.text="Formatting code...";let s=await k(e);await z(e,s,"lint:fix"),t.succeed(Wc.green("Internationalization setup successfully!"))}catch(n){throw t.fail("Failed to setup Internationalization."),n}finally{await w(r)}};var eo={id:"i18n",name:"Internationalization",description:"next-intl with [locale] routing, RootProvider, and proxy.ts",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(H(),qe));return(await t(e)).hasI18n},files:[{path:"src/i18n",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds your translation JSON files \u2014 copy any you want to keep, then delete by hand"},{path:"src/proxy.ts",generated:!0},{path:"src/app/[locale]",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds every page you generated under the locale segment \u2014 move them to src/app/ before deleting"}],packages:[{name:"next-intl",kind:"dependency"}],scripts:[],injections:[{file:"next.config.ts",description:"createNextIntlPlugin wrap in next.config.ts",presence:/next-intl\/plugin/,removePattern:vi},{file:"src/providers/RootProvider.tsx",description:"<NextIntlClientProvider> wrap",presence:/NextIntlClientProvider/,removePattern:Ae("NextIntlClientProvider")}],apply:ct};S();P();import Yc from"node:path";S();import qc from"node:path";import Xc from"picocolors";P();var pt=async e=>{let t=b("Enabling React Compiler...");try{let r=qc.join(e,c.NEXT_CONFIG);if(!m(r))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await f(r);if(n.includes("reactCompiler:")){t.fail("React Compiler is already configured in next.config.ts.");return}let i=/(const\s+nextConfig\s*:\s*NextConfig\s*=\s*\{)/;if(!i.test(n))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");n=n.replace(i,`$1
928
+ reactCompiler: true,`),await g(r,n),t.text="Installing babel-plugin-react-compiler...",await vt(e,"babel-plugin-react-compiler"),t.succeed(Xc.green("React Compiler enabled."))}catch(r){throw t.fail("Failed to enable React Compiler."),r}};var to={id:"react-compiler",name:"React Compiler",description:"reactCompiler: true in next.config.ts + babel-plugin-react-compiler",detect:async e=>{let t=Yc.join(e,c.NEXT_CONFIG);return m(t)?/reactCompiler\s*:\s*true/.test(await f(t)):!1},files:[],packages:[{name:"babel-plugin-react-compiler",kind:"devDependency"}],scripts:[],injections:[{file:c.NEXT_CONFIG,description:"`reactCompiler: true` flag",presence:/reactCompiler\s*:\s*true/,removePattern:/\n\s*reactCompiler:\s*true,?/}],apply:pt};S();import Er from"node:path";import Zc from"picocolors";P();S();P();import ro from"node:fs/promises";import Se from"node:path";import Kc from"degit";var no=async(e,t)=>{t.text="Fetching assets from starter repo...",await Kc("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},io=async(e,t)=>{let r=Se.join(t,"src/providers/StoreProvider.tsx"),n=Se.join(e,c.STORE_PROVIDER);await N(r,n);let i=Se.join(t,"src/store"),o=Se.join(e,c.STORE);await ro.cp(i,o,{recursive:!0})},oo=async(e,t)=>{let r=Se.join(t,"src/features/counter"),n=Se.join(e,c.COUNTER_FEATURE);await ro.cp(r,n,{recursive:!0});let i=Se.join(n,"components/Counter.tsx");if(await m(i)){let o=await f(i);o=o.replace(/import \{ useTranslations \} from 'next-intl';\n?/,""),o=o.replace(/const t = useTranslations\('Count'\);\n?/,""),o=o.replace(/\{t\('currentCount', \{ count: value \}\)\}/g,"Current Count: {value}"),o=o.replace(/\{t\('increment'\)\}/g,"Increment"),o=o.replace(/\{t\('decrement'\)\}/g,"Decrement"),o=o.replace(/\{t\('reset'\)\}/g,"Reset"),await g(i,o)}};S();P();import Sr from"node:path";var so=async e=>{let t=Sr.join(e,c.STORE),r=Sr.join(e,"package.json");if(m(t))return{isSetup:!0,reason:"src/store directory exists"};if(m(r)){let n=JSON.parse(await f(r));if(n.dependencies?.["@reduxjs/toolkit"]||n.devDependencies?.["@reduxjs/toolkit"])return{isSetup:!0,reason:"@reduxjs/toolkit is installed"}}return{isSetup:!1,reason:""}},ao=async e=>{let t=Sr.join(e,c.PROVIDERS_INDEX);if(!await Nt(e)||!m(t))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx (or src/app/[locale]/layout.tsx) and src/providers/index.ts exist.")};S();P();import Cr from"node:path";var co=async e=>{},po=async e=>{let t=Cr.join(e,"src/providers/RootProvider.tsx");if(!m(t))return;let r=await f(t),n="'use client';",i=r.includes(n);if(i&&(r=r.replace(n,"").trim()),r.includes("from '@/store'")||(r=`import type { AppState } from '@/store';
785
929
  ${r}`),r.includes("from './StoreProvider'")||(r=`${r.includes("from '@/store'"),""}import { StoreProvider } from './StoreProvider';
786
- ${r}`),o&&(r=`${n}
930
+ ${r}`),i&&(r=`${n}
787
931
  ${r}`),r.includes("preloadedState")||(r=r.replace(/children:\s*React\.ReactNode;/,`children: React.ReactNode;
788
- preloadedState?: Partial<AppState>;`),r=r.replace(/export const RootProvider = \(\{([\s\S]*?)\}:/,(i,s)=>`export const RootProvider = ({${s}, preloadedState }:`),r=r.replace(/,\s*,/g,",").replace(/\{\s*,/g,"{ ").replace(/,\s*\}/g," }")),!r.includes("<StoreProvider")){let i=r.match(/return\s*\(\s*([\s\S]*?)\s*\);/);if(i){let s=i[1];r=r.replace(i[0],`return (
932
+ preloadedState?: Partial<AppState>;`),r=r.replace(/export const RootProvider = \(\{([\s\S]*?)\}:/,(o,s)=>`export const RootProvider = ({${s}, preloadedState }:`),r=r.replace(/,\s*,/g,",").replace(/\{\s*,/g,"{ ").replace(/,\s*\}/g," }")),!r.includes("<StoreProvider")){let o=r.match(/return\s*\(\s*([\s\S]*?)\s*\);/);if(o){let s=o[1];r=r.replace(o[0],`return (
789
933
  <StoreProvider preloadedState={preloadedState}>
790
934
  ${s}
791
935
  </StoreProvider>
792
- );`)}}await g(t,r)},Mo=async e=>{let t=[mr.join(e,c.ROOT_PAGE),mr.join(e,"src/app/[locale]/page.tsx")],r="";for(let o of t)if(m(o)){r=o;break}if(!r)return;let n=await f(r);if(n.includes("Counter")||(n=`import { Counter } from '@/features/counter';
793
- ${n}`),!n.includes("<Counter />")){let o=n.lastIndexOf("</div>"),i=n.lastIndexOf("</main>"),s=i!==-1?i:o;s!==-1&&(n=n.slice(0,s)+`
936
+ );`)}}await g(t,r)},lo=async e=>{let t=[Cr.join(e,c.ROOT_PAGE),Cr.join(e,"src/app/[locale]/page.tsx")],r="";for(let i of t)if(m(i)){r=i;break}if(!r)return;let n=await f(r);if(n.includes("Counter")||(n=`import { Counter } from '@/features/counter';
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)+`
794
938
  <div className="mt-8">
795
939
  <h2 className="mb-4 text-2xl font-bold">Redux Counter</h2>
796
940
  <Counter />
797
941
  </div>
798
- `+n.slice(s),await g(r,n))}};var Qe=async e=>{let t=b("Setting up Redux Toolkit..."),r=dr.join(e,".next-maker-temp-redux");try{let{isSetup:n,reason:o}=await _o(e);if(n){t.fail(`Redux is already set up (${o}).`);return}await jo(e),await Ao(r,t),t.text="Copying Redux files...",await Oo(e,r),t.text="Creating Counter feature...",await Fo(e,r),t.text="Updating providers and pages...",await Do(e),await Lo(e),await Mo(e),t.text="Installing dependencies...",await V(e,"@reduxjs/toolkit"),await V(e,"react-redux"),await V(e,"redux-persist"),await V(e,"react-secure-storage");let i=dr.join(e,c.VITEST_CONFIG);if(m(i)){let a=JSON.parse(await f(dr.join(e,c.PACKAGE_JSON))),p={...a.dependencies,...a.devDependencies};await ce(e,{redux:!0,i18n:!!p["next-intl"]})}t.text="Formatting code...";let s=await j(e);await q(e,s,"lint:fix"),t.succeed(nc.green("Redux Toolkit setup successfully!"))}catch(n){throw t.fail("Failed to setup Redux Toolkit."),n}finally{await w(r)}};var Go={id:"redux",name:"Redux Toolkit",description:"Redux Toolkit + react-redux + redux-persist + StoreProvider",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(G(),De));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:Qe};S();P();import cc from"node:path";S();import sc from"node:path";import ac from"picocolors";P();var Uo=[{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"}],Ho=/(const\s+nextConfig\s*:\s*NextConfig\s*=\s*\{)/,oc=/^\s+headers\s*:/m,ic=e=>`
942
+ `+n.slice(s),await g(r,n))}};var lt=async e=>{let t=b("Setting up Redux Toolkit..."),r=Er.join(e,".next-maker-temp-redux");try{let{isSetup:n,reason:i}=await so(e);if(n){t.fail(`Redux is already set up (${i}).`);return}await ao(e),await no(r,t),t.text="Copying Redux files...",await io(e,r),t.text="Creating Counter feature...",await oo(e,r),t.text="Updating providers and pages...",await co(e),await po(e),await lo(e),t.text="Installing dependencies...",await G(e,"@reduxjs/toolkit"),await G(e,"react-redux"),await G(e,"redux-persist"),await G(e,"react-secure-storage");let o=Er.join(e,c.VITEST_CONFIG);if(m(o)){let a=JSON.parse(await f(Er.join(e,c.PACKAGE_JSON))),p={...a.dependencies,...a.devDependencies};await ce(e,{redux:!0,i18n:!!p["next-intl"]})}t.text="Formatting code...";let s=await k(e);await z(e,s,"lint:fix"),t.succeed(Zc.green("Redux Toolkit setup successfully!"))}catch(n){throw t.fail("Failed to setup Redux Toolkit."),n}finally{await w(r)}};var mo={id:"redux",name:"Redux Toolkit",description:"Redux Toolkit + react-redux + redux-persist + StoreProvider",detect:async e=>{let{detectProjectSetup:t}=await Promise.resolve().then(()=>(H(),qe));return(await t(e)).hasRedux},files:[{path:"src/store",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds the rootReducer and any slices you registered \u2014 review before deleting"},{path:"src/providers/StoreProvider.tsx",generated:!0}],packages:[{name:"@reduxjs/toolkit",kind:"dependency"},{name:"react-redux",kind:"dependency"},{name:"redux-persist",kind:"dependency"}],scripts:[],injections:[{file:"src/providers/RootProvider.tsx",description:"<StoreProvider> wrap in RootProvider",presence:/<StoreProvider/,removePattern:Ae("StoreProvider")}],apply:lt};S();P();import np from"node:path";S();import tp from"node:path";import rp from"picocolors";P();var fo=[{key:"X-DNS-Prefetch-Control",value:"on"},{key:"Strict-Transport-Security",value:"max-age=63072000; includeSubDomains; preload"},{key:"X-XSS-Protection",value:"1; mode=block"},{key:"X-Frame-Options",value:"SAMEORIGIN"},{key:"X-Content-Type-Options",value:"nosniff"},{key:"Referrer-Policy",value:"origin-when-cross-origin"}],uo=/(const\s+nextConfig\s*:\s*NextConfig\s*=\s*\{)/,Qc=/^\s+headers\s*:/m,ep=e=>`
799
943
  headers: async () => {
800
944
  return [
801
945
  {
@@ -806,7 +950,7 @@ ${e.map(({key:r,value:n})=>` { key: '${r}', value: '${n}' },`).join(`
806
950
  ],
807
951
  },
808
952
  ];
809
- },`,Ie=e=>oc.test(e),ur=(e,t=Uo)=>{if(Ie(e))return e;if(!Ho.test(e))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");return e.replace(Ho,`$1${ic(t)}`)};var et=async e=>{let t=b("Adding security headers to next.config.ts...");try{let r=sc.join(e,c.NEXT_CONFIG);if(!m(r))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await f(r);if(Ie(n)){t.succeed("Security headers already configured.");return}let o=ur(n);await g(r,o),t.succeed(ac.green("Security headers added."))}catch(r){throw t.fail("Failed to add security headers."),r}};var zo={id:"security-headers",name:"Security Headers",description:"Hardened HTTP headers in next.config.ts",detect:async e=>{let t=cc.join(e,c.NEXT_CONFIG);return m(t)?Ie(await f(t)):!1},files:[],packages:[],scripts:[],injections:[{file:c.NEXT_CONFIG,description:"headers() function in next.config.ts",presence:/^\s+headers\s*:/m,removePattern:/\s+headers:\s*async\s*\(\)\s*=>\s*\{[\s\S]*?\n\s{0,2}\},/m}],apply:et};S();P();import uc from"node:path";S();import pc from"node:fs/promises";import de from"node:path";import lc from"degit";import mc from"picocolors";P();var dc=["vitest","jsdom","@vitejs/plugin-react","@testing-library/dom","@testing-library/jest-dom","@testing-library/react","@testing-library/user-event"],tt=async e=>{let t=b("Setting up testing (Vitest + RTL)..."),r=de.join(e,".next-maker-temp-tests");try{let n=de.join(e,c.VITEST_CONFIG);if(m(n)){t.fail("Testing is already set up (vitest.config.ts exists).");return}t.text="Fetching assets from starter repo...",await lc("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(r),await F(de.join(r,c.VITEST_CONFIG),de.join(e,c.VITEST_CONFIG));let i=de.join(e,c.TEST_DIR);await pc.mkdir(i,{recursive:!0}),await F(de.join(r,c.TEST_DIR,"setup.ts"),de.join(i,"setup.ts"));let s=de.join(e,c.PACKAGE_JSON),a=JSON.parse(await f(s)),p={...a.dependencies,...a.devDependencies},u=!!(p["@reduxjs/toolkit"]&&p["react-redux"]),d=!!p["next-intl"];await ce(e,{redux:u,i18n:d}),await _(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 j(e);await xe(e,h,dc),t.text="Formatting code...",await q(e,h,"lint:fix"),t.succeed(mc.green("Testing setup complete."))}catch(n){throw t.fail("Failed to set up testing."),n}finally{await w(r)}};var Jo={id:"tests",name:"Tests",description:"Vitest + React Testing Library + jsdom",detect:async e=>m(uc.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:tt};P();import xc from"node:path";S();import Vo from"node:path";import hc from"picocolors";P();var fc={npm:"npm run",yarn:"yarn",pnpm:"pnpm",bun:"bun run"},gc=e=>{let t=fc[e];return["ci:check","type-check","check:deprecated","test","build"].map(r=>`${t} ${r}`).join(" && ")},fr=(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=gc(t)),!n.tsx&&!e.dependencies?.hasOwnProperty("tsx")&&(n.tsx="*"),{...e,scripts:r,devDependencies:n}};var gr=`import * as fs from 'node:fs';
953
+ },`,_e=e=>Qc.test(e),Tr=(e,t=fo)=>{if(_e(e))return e;if(!uo.test(e))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");return e.replace(uo,`$1${ep(t)}`)};var mt=async e=>{let t=b("Adding security headers to next.config.ts...");try{let r=tp.join(e,c.NEXT_CONFIG);if(!m(r))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await f(r);if(_e(n)){t.succeed("Security headers already configured.");return}let i=Tr(n);await g(r,i),t.succeed(rp.green("Security headers added."))}catch(r){throw t.fail("Failed to add security headers."),r}};var go={id:"security-headers",name:"Security Headers",description:"Hardened HTTP headers in next.config.ts",detect:async e=>{let t=np.join(e,c.NEXT_CONFIG);return m(t)?_e(await f(t)):!1},files:[],packages:[],scripts:[],injections:[{file:c.NEXT_CONFIG,description:"headers() function in next.config.ts",presence:/^\s+headers\s*:/m,removePattern:/\s+headers:\s*async\s*\(\)\s*=>\s*\{[\s\S]*?\n\s{0,2}\},/m}],apply:mt};S();P();import cp from"node:path";S();import ip from"node:fs/promises";import de from"node:path";import op from"degit";import sp from"picocolors";P();var ap=["vitest","jsdom","@vitejs/plugin-react","@testing-library/dom","@testing-library/jest-dom","@testing-library/react","@testing-library/user-event"],dt=async e=>{let t=b("Setting up testing (Vitest + RTL)..."),r=de.join(e,".next-maker-temp-tests");try{let n=de.join(e,c.VITEST_CONFIG);if(m(n)){t.fail("Testing is already set up (vitest.config.ts exists).");return}t.text="Fetching assets from starter repo...",await op("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(r),await N(de.join(r,c.VITEST_CONFIG),de.join(e,c.VITEST_CONFIG));let o=de.join(e,c.TEST_DIR);await ip.mkdir(o,{recursive:!0}),await N(de.join(r,c.TEST_DIR,"setup.ts"),de.join(o,"setup.ts"));let s=de.join(e,c.PACKAGE_JSON),a=JSON.parse(await f(s)),p={...a.dependencies,...a.devDependencies},u=!!(p["@reduxjs/toolkit"]&&p["react-redux"]),d=!!p["next-intl"];await ce(e,{redux:u,i18n:d}),await D(s,x=>(x.scripts=x.scripts??{},x.scripts.test=x.scripts.test??"vitest run",x.scripts["test:watch"]=x.scripts["test:watch"]??"vitest",x.scripts["test:coverage"]=x.scripts["test:coverage"]??"vitest run --coverage",typeof x.scripts.validate=="string"&&!/\byarn\s+test(?![:\w])/.test(x.scripts.validate)&&(x.scripts.validate=x.scripts.validate.replace(/(\byarn\s+check:deprecated\s*)(&&)/,"$1&& yarn test $2")),x)),t.text="Installing testing devDependencies...";let h=await k(e);await xe(e,h,ap),t.text="Formatting code...",await z(e,h,"lint:fix"),t.succeed(sp.green("Testing setup complete."))}catch(n){throw t.fail("Failed to set up testing."),n}finally{await w(r)}};var ho={id:"tests",name:"Tests",description:"Vitest + React Testing Library + jsdom",detect:async e=>m(cp.join(e,c.VITEST_CONFIG)),files:[{path:c.VITEST_CONFIG,generated:!0},{path:"test",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds setup.ts / test-utils.tsx and any helpers you added \u2014 review before deleting"}],packages:[{name:"vitest",kind:"devDependency"},{name:"jsdom",kind:"devDependency"},{name:"@vitejs/plugin-react",kind:"devDependency"},{name:"@testing-library/dom",kind:"devDependency"},{name:"@testing-library/jest-dom",kind:"devDependency"},{name:"@testing-library/react",kind:"devDependency"},{name:"@testing-library/user-event",kind:"devDependency"}],scripts:[{name:"test",expectedValue:"vitest run"},{name:"test:watch",expectedValue:"vitest"}],injections:[],apply:dt};P();import up from"node:path";S();import yo from"node:path";import mp from"picocolors";P();var pp={npm:"npm run",yarn:"yarn",pnpm:"pnpm",bun:"bun run"},lp=e=>{let t=pp[e];return["ci:check","type-check","check:deprecated","test","build"].map(r=>`${t} ${r}`).join(" && ")},br=(e,t)=>{let r={...e.scripts??{}},n={...e.devDependencies??{}};return r["env:sync"]||(r["env:sync"]="tsx scripts/sync-env.ts"),r["check:deprecated"]||(r["check:deprecated"]="tsx scripts/check-deprecated.ts"),r["type-check"]||(r["type-check"]="tsc --noEmit"),r.validate||(r.validate=lp(t)),!n.tsx&&!e.dependencies?.hasOwnProperty("tsx")&&(n.tsx="*"),{...e,scripts:r,devDependencies:n}};var Rr=`import * as fs from 'node:fs';
810
954
  import * as path from 'node:path';
811
955
 
812
956
  const checkOnly = process.argv.includes('--check');
@@ -880,7 +1024,7 @@ if (checkOnly) {
880
1024
 
881
1025
  fs.writeFileSync(examplePath, newExampleContent);
882
1026
  console.log('\u2705 Synchronized .env.example with .env');
883
- `,hr=`/**
1027
+ `,$r=`/**
884
1028
  * Walks every identifier in the project and flags any whose resolved TypeScript
885
1029
  * symbol carries a \`@deprecated\` JSDoc tag. Catches deprecated API usage that
886
1030
  * \`tsc --noEmit\` does not surface (deprecations are "suggestion"-level, not
@@ -944,121 +1088,119 @@ if (hits === 0) {
944
1088
 
945
1089
  console.log(\`\\n\${hits} deprecated symbol use(s) found.\`);
946
1090
  process.exit(1);
947
- `;var yc=[{relative:"scripts/sync-env.ts",content:gr},{relative:"scripts/check-deprecated.ts",content:hr}],rt=async e=>{let t=b("Adding validation scripts...");try{let r=!1;for(let{relative:i,content:s}of yc){let a=Vo.join(e,i);m(a)||(await g(a,s),r=!0)}let n=await j(e),o=!1;await _(Vo.join(e,c.PACKAGE_JSON),i=>{let s=i.devDependencies?.tsx,a=fr(i,n);return o=!s&&!!a.devDependencies?.tsx,a}),o&&(t.text="Installing tsx...",await xe(e,n,["tsx"])),t.succeed(hc.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 Bo=["scripts/sync-env.ts","scripts/check-deprecated.ts"],qo={id:"validate-scripts",name:"Validation Scripts",description:"sync-env, check-deprecated, and the validate chain",detect:async e=>Bo.every(t=>m(xc.join(e,t))),files:Bo.map(e=>({path:e,generated:!0})),packages:[{name:"tsx",kind:"devDependency"}],scripts:[{name:"env:sync",expectedValue:"tsx scripts/sync-env.ts"},{name:"check:deprecated",expectedValue:"tsx scripts/check-deprecated.ts"},{name:"type-check",expectedValue:"tsc --noEmit"},{name:"validate"}],injections:[],apply:rt};S();P();import Ne from"node:path";var Xo=async e=>{let t=Ne.join(e,c.PACKAGE_JSON);return m(t)?JSON.parse(await f(t)):null},Pc=async(e,t)=>{let r=Ne.join(e,c.PACKAGE_JSON);await g(r,`${JSON.stringify(t,null,2)}
948
- `)},Wo=(e,t)=>(t==="dependency"?e.dependencies:e.devDependencies)??{},nt=async(e,t)=>{let r=await e.detect(t),n=[];if(!r)return{manifest:e,installed:!1,drift:[]};for(let i of e.files)i.required!==!1&&(m(Ne.join(t,i.path))||n.push({kind:"missingFile",file:i.path}));let o=await Xo(t);if(o){for(let s of e.packages)Wo(o,s.kind)[s.name]||n.push({kind:"missingPackage",name:s.name,depKind:s.kind});let i=o.scripts??{};for(let s of e.scripts){let a=i[s.name];a?s.expectedValue&&a!==s.expectedValue&&n.push({kind:"mismatchedScript",name:s.name,expected:s.expectedValue,actual:a}):n.push({kind:"missingScript",name:s.name})}}for(let i of e.injections){let s=Ne.join(t,i.file);if(!m(s)){n.push({kind:"missingInjection",file:i.file,description:i.description});continue}let a=await f(s);i.presence.test(a)||n.push({kind:"missingInjection",file:i.file,description:i.description})}return{manifest:e,installed:r,drift:n}},Et=async(e,t,r={})=>{let n=r.dryRun??!1,o={filesRemoved:[],packagesUninstalled:[],scriptsRemoved:[],blocksStripped:[],manualCleanup:[]};for(let a of e.injections){let p=Ne.join(t,a.file);if(!m(p))continue;if(!a.removePattern){o.manualCleanup.push({file:a.file,description:a.description});continue}let u=await f(p);if(!a.presence.test(u))continue;let d;if(typeof a.removePattern=="function"){let h=a.removePattern(u);if(h===null){o.manualCleanup.push({file:a.file,description:a.description});continue}d=h}else d=u.replace(a.removePattern,"");d!==u?(n||await g(p,d),o.blocksStripped.push({file:a.file,description:a.description})):o.manualCleanup.push({file:a.file,description:a.description})}let{rm:i}=await import("node:fs/promises");for(let a of e.files){if(!a.generated)continue;let p=Ne.join(t,a.path);if(m(p)){if(a.containsUserContent){let u=a.removeHint?`${a.path} \u2014 ${a.removeHint}`:`${a.path} (may contain user-authored files; review before deleting)`;o.manualCleanup.push({file:a.path,description:u});continue}n||await i(p,{recursive:!0,force:!0}),o.filesRemoved.push(a.path)}}let s=await Xo(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],o.scriptsRemoved.push(p.name),a=!0);for(let p of e.packages)Wo(s,p.kind)[p.name]&&o.packagesUninstalled.push(p.name);a&&!n&&await Pc(t,s)}if(!n&&o.packagesUninstalled.length>0){let a=await j(t);await Ot(t,a,o.packagesUninstalled)}return o};var Se=[zo,qo,eo,No,Zn,Jo,mo,Po,Go,Io],Yo=e=>Se.find(t=>t.id===e);var vc=e=>{switch(e.kind){case"missingFile":return`missing file: ${e.file}`;case"missingPackage":return`missing ${e.depKind==="dependency"?"dep":"devDep"}: ${e.name}`;case"missingScript":return`missing script: ${e.name}`;case"mismatchedScript":return`script "${e.name}" expected ${L.dim(e.expected)} but got ${L.dim(e.actual)}`;case"missingInjection":return`missing block in ${e.file}: ${e.description}`}},wc=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}},Ko=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?Se.filter(s=>s.id===t.feature):Se;if(t.feature&&n.length===0)throw new Error(`Unknown feature "${t.feature}". Valid: ${Se.map(s=>s.id).join(", ")}.`);let o=[];for(let s of n)o.push(await nt(s,r));t.json&&(l(JSON.stringify(o.map(s=>({id:s.manifest.id,name:s.manifest.name,installed:s.installed,drift:s.drift})),null,2)),process.exit(o.some(s=>s.drift.length>0)?1:0)),l(L.cyan(`
1091
+ `;var dp=[{relative:"scripts/sync-env.ts",content:Rr},{relative:"scripts/check-deprecated.ts",content:$r}],ut=async e=>{let t=b("Adding validation scripts...");try{let r=!1;for(let{relative:o,content:s}of dp){let a=yo.join(e,o);m(a)||(await g(a,s),r=!0)}let n=await k(e),i=!1;await D(yo.join(e,c.PACKAGE_JSON),o=>{let s=o.devDependencies?.tsx,a=br(o,n);return i=!s&&!!a.devDependencies?.tsx,a}),i&&(t.text="Installing tsx...",await xe(e,n,["tsx"])),t.succeed(mp.green(r?"Validation scripts added (env:sync, check:deprecated, validate).":"Validation scripts already present \u2014 refreshed package.json."))}catch(r){throw t.fail("Failed to add validation scripts."),r}};var xo=["scripts/sync-env.ts","scripts/check-deprecated.ts"],Po={id:"validate-scripts",name:"Validation Scripts",description:"sync-env, check-deprecated, and the validate chain",detect:async e=>xo.every(t=>m(up.join(e,t))),files:xo.map(e=>({path:e,generated:!0})),packages:[{name:"tsx",kind:"devDependency"}],scripts:[{name:"env:sync",expectedValue:"tsx scripts/sync-env.ts"},{name:"check:deprecated",expectedValue:"tsx scripts/check-deprecated.ts"},{name:"type-check",expectedValue:"tsc --noEmit"},{name:"validate"}],injections:[],apply:ut};import{access as yp,readFile as xp}from"node:fs/promises";import To from"node:path";S();import Nr from"node:path";import hp from"picocolors";P();S();P();import Ir from"node:fs/promises";import ft from"node:path";import fp from"degit";var wo=async(e,t)=>{t.text="Downloading assets from starter repository...",await fp("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},vo=async(e,t,r)=>{let n=ft.join(e,c.WS_UTILS);await Ir.cp(ft.join(t,c.WS_UTILS),n,{recursive:!0,force:!0});let i=ft.join(e,c.WS_SLICE_FILE);await N(ft.join(t,c.WS_SLICE_FILE),i),r.keepTests||await gp(n)},gp=async e=>{let t=async r=>{let n=await Ir.readdir(r,{withFileTypes:!0});for(let i of n){let o=ft.join(r,i.name);if(i.isDirectory()){if(i.name==="__test-utils__"){await w(o);continue}await t(o)}else i.isFile()&&/\.test\.tsx?$/.test(i.name)&&await Ir.unlink(o)}};await t(e)};S();P();import So from"node:path";var Co=async e=>{let t=So.join(e,c.WS_UTILS);return m(t)?{isSetup:!0,reason:"src/lib/utils/ws/ already exists"}:{isSetup:!1}},Eo=async e=>{let t=[],r=[{rel:"src/lib",label:"src/lib"},{rel:"src/store",label:"src/store (Redux Toolkit not installed?)"},{rel:c.ROOT_REDUCER,label:"src/store/rootReducer.ts (Redux not initialised?)"},{rel:c.STORE_PROVIDER,label:"src/providers/StoreProvider.tsx (Redux not initialised?)"}];for(let{rel:n,label:i}of r)m(So.join(e,n))||t.push(`- ${i}`);if(t.length>0)throw new Error(`WebSocket setup requires Redux Toolkit. Missing:
1092
+ ${t.join(`
1093
+ `)}
1094
+
1095
+ Run \`next-maker setup --redux\` first.`)};var gt=async e=>{let t=b("Setting up WebSocket layer..."),r=Nr.join(e,".next-maker-temp-ws");try{let{isSetup:n,reason:i}=await Co(e);if(n){t.fail(`WebSocket layer is already set up (${i}).`);return}await Eo(e),await wo(r,t),t.text="Copying WebSocket files...";let o=m(Nr.join(e,c.VITEST_CONFIG));await vo(e,r,{keepTests:o}),t.text="Registering wsReducer...",await kn(e),t.text="Mounting WS bridge in StoreProvider...",await An(e),t.text="Ensuring test/setup.ts mocks...",await _n(e),t.text="Installing socket.io-client...";let s=Nr.join(e,c.PACKAGE_JSON),a=JSON.parse(await f(s));({...a.dependencies,...a.devDependencies})["socket.io-client"]||await G(e,"socket.io-client@^4.8.3"),t.text="Formatting code...";let u=await k(e);await z(e,u,"lint:fix"),t.succeed(hp.green("WebSocket layer setup successfully!"))}catch(n){throw t.fail("Failed to setup WebSocket layer."),n}finally{await w(r)}};var Pp=async e=>{try{let t=JSON.parse(await xp(To.join(e,"package.json"),"utf-8"));return{...t.dependencies,...t.devDependencies}["socket.io-client"]?(await yp(To.join(e,"src/lib/utils/ws")),!0):!1}catch{return!1}},bo={id:"ws",name:"WebSocket Client",description:"socket.io-client + lazy WS singleton + Redux slice + hooks",detect:Pp,files:[{path:"src/lib/utils/ws",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds the ws client + any feature event maps you added \u2014 review before deleting"},{path:"src/store/slices/ws.slice.ts",generated:!0}],packages:[{name:"socket.io-client",kind:"dependency"}],scripts:[],injections:[{file:"src/store/rootReducer.ts",description:"wsReducer registration in rootReducer",presence:/ws:\s*wsReducer\b/,removePattern:Et},{file:"src/providers/StoreProvider.tsx",description:"attachWsBridge mount in StoreProvider",presence:/attachWsBridge\(wsClient,\s*store\.dispatch\)/,removePattern:Ct}],apply:gt};S();P();import Oe from"node:path";var Ro=async e=>{let t=Oe.join(e,c.PACKAGE_JSON);return m(t)?JSON.parse(await f(t)):null},wp=async(e,t)=>{let r=Oe.join(e,c.PACKAGE_JSON);await g(r,`${JSON.stringify(t,null,2)}
1096
+ `)},$o=(e,t)=>(t==="dependency"?e.dependencies:e.devDependencies)??{},ht=async(e,t)=>{let r=await e.detect(t),n=[];if(!r)return{manifest:e,installed:!1,drift:[]};for(let o of e.files)o.required!==!1&&(m(Oe.join(t,o.path))||n.push({kind:"missingFile",file:o.path}));let i=await Ro(t);if(i){for(let s of e.packages)$o(i,s.kind)[s.name]||n.push({kind:"missingPackage",name:s.name,depKind:s.kind});let o=i.scripts??{};for(let s of e.scripts){let a=o[s.name];a?s.expectedValue&&a!==s.expectedValue&&n.push({kind:"mismatchedScript",name:s.name,expected:s.expectedValue,actual:a}):n.push({kind:"missingScript",name:s.name})}}for(let o of e.injections){let s=Oe.join(t,o.file);if(!m(s)){n.push({kind:"missingInjection",file:o.file,description:o.description});continue}let a=await f(s);o.presence.test(a)||n.push({kind:"missingInjection",file:o.file,description:o.description})}return{manifest:e,installed:r,drift:n}},Ft=async(e,t,r={})=>{let n=r.dryRun??!1,i={filesRemoved:[],packagesUninstalled:[],scriptsRemoved:[],blocksStripped:[],manualCleanup:[]};for(let a of e.injections){let p=Oe.join(t,a.file);if(!m(p))continue;if(!a.removePattern){i.manualCleanup.push({file:a.file,description:a.description});continue}let u=await f(p);if(!a.presence.test(u))continue;let d;if(typeof a.removePattern=="function"){let h=a.removePattern(u);if(h===null){i.manualCleanup.push({file:a.file,description:a.description});continue}d=h}else d=u.replace(a.removePattern,"");d!==u?(n||await g(p,d),i.blocksStripped.push({file:a.file,description:a.description})):i.manualCleanup.push({file:a.file,description:a.description})}let{rm:o}=await import("node:fs/promises");for(let a of e.files){if(!a.generated)continue;let p=Oe.join(t,a.path);if(m(p)){if(a.containsUserContent){let u=a.removeHint?`${a.path} \u2014 ${a.removeHint}`:`${a.path} (may contain user-authored files; review before deleting)`;i.manualCleanup.push({file:a.path,description:u});continue}n||await o(p,{recursive:!0,force:!0}),i.filesRemoved.push(a.path)}}let s=await Ro(t);if(s){let a=!1;if(s.scripts)for(let p of e.scripts)s.scripts[p.name]&&(n||delete s.scripts[p.name],i.scriptsRemoved.push(p.name),a=!0);for(let p of e.packages)$o(s,p.kind)[p.name]&&i.packagesUninstalled.push(p.name);a&&!n&&await wp(t,s)}if(!n&&i.packagesUninstalled.length>0){let a=await k(t);await Bt(t,a,i.packagesUninstalled)}return i};var Ce=[go,Po,Ti,to,Ci,ho,ji,zi,mo,bo,eo],Io=e=>Ce.find(t=>t.id===e);var vp=e=>{switch(e.kind){case"missingFile":return`missing file: ${e.file}`;case"missingPackage":return`missing ${e.depKind==="dependency"?"dep":"devDep"}: ${e.name}`;case"missingScript":return`missing script: ${e.name}`;case"mismatchedScript":return`script "${e.name}" expected ${L.dim(e.expected)} but got ${L.dim(e.actual)}`;case"missingInjection":return`missing block in ${e.file}: ${e.description}`}},Sp=e=>{let t=e.filter(n=>n.installed),r=t.filter(n=>n.drift.length>0);return{installedCount:t.length,driftedCount:r.length,cleanCount:t.length-r.length,driftedResults:r}},No=e=>{e.command("doctor").description("Diagnose drift between the project and known feature manifests").option("--fix","Re-apply manifests that report drift (idempotent)").option("--feature <id>","Only check this manifest id (e.g. redux, security-headers)").option("--json","Print machine-readable JSON instead of the human report").action(async t=>{try{let r=process.cwd(),n=t.feature?Ce.filter(s=>s.id===t.feature):Ce;if(t.feature&&n.length===0)throw new Error(`Unknown feature "${t.feature}". Valid: ${Ce.map(s=>s.id).join(", ")}.`);let i=[];for(let s of n)i.push(await ht(s,r));t.json&&(l(JSON.stringify(i.map(s=>({id:s.manifest.id,name:s.manifest.name,installed:s.installed,drift:s.drift})),null,2)),process.exit(i.some(s=>s.drift.length>0)?1:0)),l(L.cyan(`
949
1097
  \u{1FA7A} Project Doctor
950
- `));for(let s of o){let{manifest:a,installed:p,drift:u}=s;if(!p){l(` ${L.dim("\u2014")} ${L.dim(a.name)} ${L.dim("(not installed)")}`);continue}if(u.length===0){l(` ${L.green("\u2713")} ${a.name}`);continue}l(` ${L.yellow("!")} ${L.bold(a.name)} ${L.dim(`(${u.length} issue${u.length===1?"":"s"})`)}`);for(let d of u)l(` ${L.yellow("\u2022")} ${vc(d)}`)}let i=wc(o);l(""),l(L.dim(`${i.cleanCount} clean, ${i.driftedCount} drifted, ${o.length-i.installedCount} not installed`)),i.driftedCount===0&&(l(L.green(`
1098
+ `));for(let s of i){let{manifest:a,installed:p,drift:u}=s;if(!p){l(` ${L.dim("\u2014")} ${L.dim(a.name)} ${L.dim("(not installed)")}`);continue}if(u.length===0){l(` ${L.green("\u2713")} ${a.name}`);continue}l(` ${L.yellow("!")} ${L.bold(a.name)} ${L.dim(`(${u.length} issue${u.length===1?"":"s"})`)}`);for(let d of u)l(` ${L.yellow("\u2022")} ${vp(d)}`)}let o=Sp(i);l(""),l(L.dim(`${o.cleanCount} clean, ${o.driftedCount} drifted, ${i.length-o.installedCount} not installed`)),o.driftedCount===0&&(l(L.green(`
951
1099
  \u2713 No drift detected.
952
1100
  `)),process.exit(0)),t.fix||(l(L.dim(`
953
1101
  Run with --fix to re-apply drifted features.
954
1102
  `)),process.exit(1)),l(L.cyan(`
955
1103
  \u{1F527} Applying fixes...
956
- `));for(let s of i.driftedResults){if(!s.manifest.apply){l(L.yellow(` \u26A0\uFE0F ${s.manifest.name} has no apply() \u2014 skipping.`));continue}try{await s.manifest.apply(r)}catch(a){v(`Failed to fix ${s.manifest.name}: ${a}`)}}l(L.green(`
1104
+ `));for(let s of o.driftedResults){if(!s.manifest.apply){l(L.yellow(` \u26A0\uFE0F ${s.manifest.name} has no apply() \u2014 skipping.`));continue}try{await s.manifest.apply(r)}catch(a){v(`Failed to fix ${s.manifest.name}: ${a}`)}}l(L.green(`
957
1105
  \u2713 Doctor finished.
958
- `))}catch(r){v(`${r instanceof Error?r.message:r}`),process.exit(1)}})};import ke from"picocolors";S();P();import yr from"node:path";var Sc=/^[A-Z][A-Z0-9_]*$/,Qo=e=>{if(!Sc.test(e))throw new Error(`Invalid env var name "${e}". Use UPPER_SNAKE_CASE (e.g. SENTRY_DSN, NEXT_PUBLIC_API_URL).`)},ue=(e,t)=>t?e.startsWith("NEXT_PUBLIC_")?e:`NEXT_PUBLIC_${e}`:e,Cc=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,"\\'")}')`}},Tc=e=>{switch(e.type){case"url":return"z.url()";case"number":return"z.coerce.number()";case"boolean":return"z.coerce.boolean()";case"enum":{let t=e.enumValues??[];if(t.length===0)throw new Error(`Enum env var "${e.name}" requires --enum values.`);return`z.enum([${t.map(n=>`'${n.replace(/'/g,"\\'")}'`).join(", ")}])`}default:return"z.string()"}},ei=e=>{let t=ue(e.name,e.public),n=Tc(e),o=e.default!==void 0,i=!e.required&&!o;o&&(n+=Cc(e)),i&&e.type!=="enum"&&(n+=".optional()");let s;if(e.type==="enum"?s=n:s=`z.preprocess(emptyStringToUndefined, ${n})`,e.description){let a=e.description.replace(/'/g,"\\'");s+=`
959
- .describe('${a}')`}return` ${t}: ${s},`},Zo=/(export const envSchema\s*=\s*z\.object\(\{)([\s\S]*?)(\}\);?)/,ti=(e,t)=>{let r=ue(t.name,t.public);if(new RegExp(`\\b${r}\\s*:`).test(e))return e;let o=e.match(Zo);if(!o)throw new Error("Could not locate `export const envSchema = z.object({ \u2026 })` in schema.ts.");let[,i,s,a]=o,p=s.replace(/\s+$/,""),u=p.length===0||/,\s*$/.test(p)?p:`${p},`,d=ei(t),h=`${u}
1106
+ `))}catch(r){v(`${r instanceof Error?r.message:r}`),process.exit(1)}})};import Fe from"picocolors";S();P();import kr from"node:path";var Cp=/^[A-Z][A-Z0-9_]*$/,Ao=e=>{if(!Cp.test(e))throw new Error(`Invalid env var name "${e}". Use UPPER_SNAKE_CASE (e.g. SENTRY_DSN, NEXT_PUBLIC_API_URL).`)},ue=(e,t)=>t?e.startsWith("NEXT_PUBLIC_")?e:`NEXT_PUBLIC_${e}`:e,Ep=e=>{if(e.default===void 0)return"";switch(e.type){case"number":return`.default(${Number(e.default)})`;case"boolean":return`.default(${e.default==="true"})`;default:return`.default('${e.default.replace(/'/g,"\\'")}')`}},Tp=e=>{switch(e.type){case"url":return"z.url()";case"number":return"z.coerce.number()";case"boolean":return"z.coerce.boolean()";case"enum":{let t=e.enumValues??[];if(t.length===0)throw new Error(`Enum env var "${e.name}" requires --enum values.`);return`z.enum([${t.map(n=>`'${n.replace(/'/g,"\\'")}'`).join(", ")}])`}default:return"z.string()"}},_o=e=>{let t=ue(e.name,e.public),n=Tp(e),i=e.default!==void 0,o=!e.required&&!i;i&&(n+=Ep(e)),o&&e.type!=="enum"&&(n+=".optional()");let s;if(e.type==="enum"?s=n:s=`z.preprocess(emptyStringToUndefined, ${n})`,e.description){let a=e.description.replace(/'/g,"\\'");s+=`
1107
+ .describe('${a}')`}return` ${t}: ${s},`},ko=/(export const envSchema\s*=\s*z\.object\(\{)([\s\S]*?)(\}\);?)/,Oo=(e,t)=>{let r=ue(t.name,t.public);if(new RegExp(`\\b${r}\\s*:`).test(e))return e;let i=e.match(ko);if(!i)throw new Error("Could not locate `export const envSchema = z.object({ \u2026 })` in schema.ts.");let[,o,s,a]=i,p=s.replace(/\s+$/,""),u=p.length===0||/,\s*$/.test(p)?p:`${p},`,d=_o(t),h=`${u}
960
1108
  ${d}
961
- `;return e.replace(Zo,`${i}${h}${a}`)},Ec="# -public",bc=e=>{let t=ue(e.name,e.public),r=e.default??"",n=e.public?` ${Ec}`:"";return`${t}=${r}${n}`},ri=(e,t)=>{let r=ue(t.name,t.public);if(new RegExp(`^${r}=`,"m").test(e))return e;let o=e===""||e.endsWith(`
1109
+ `;return e.replace(ko,`${o}${h}${a}`)},bp="# -public",Rp=e=>{let t=ue(e.name,e.public),r=e.default??"",n=e.public?` ${bp}`:"";return`${t}=${r}${n}`},Fo=(e,t)=>{let r=ue(t.name,t.public);if(new RegExp(`^${r}=`,"m").test(e))return e;let i=e===""||e.endsWith(`
962
1110
  `)?"":`
963
- `,i=e===""?"":`
1111
+ `,o=e===""?"":`
964
1112
  `,s=t.description?`# ${t.description}
965
- `:"";return`${e}${o}${i}${s}${bc(t)}
966
- `},ni=(e,t)=>{let r=ue(t.name,t.public);if(new RegExp(`^${r}=`,"m").test(e))return e;let o=e===""||e.endsWith(`
1113
+ `:"";return`${e}${i}${o}${s}${Rp(t)}
1114
+ `},jo=(e,t)=>{let r=ue(t.name,t.public);if(new RegExp(`^${r}=`,"m").test(e))return e;let i=e===""||e.endsWith(`
967
1115
  `)?"":`
968
- `,i=t.default??"";return`${e}${o}${r}=${i}
969
- `},xr=async(e,t)=>{Qo(t.name);let r=yr.join(e,"src/lib/env/schema.ts");if(!m(r))throw new Error("src/lib/env/schema.ts not found \u2014 run `next-maker init` first.");let n=await f(r),o=ti(n,t),i=o!==n;i&&await g(r,o);let s=yr.join(e,c.ENV_EXAMPLE),a=!1;if(m(s)){let d=await f(s),h=ri(d,t);a=h!==d,a&&await g(s,h)}let p=yr.join(e,".env"),u=!1;if(m(p)){let d=await f(p),h=ni(d,t);u=h!==d,u&&await g(p,h)}return{schemaUpdated:i,envExampleUpdated:a,envUpdated:u}};var oi=new Set(["string","url","number","boolean","enum"]),Rc=e=>{let t=(e??"string").toLowerCase();if(!oi.has(t))throw new Error(`Invalid --type "${e}". Valid: ${Array.from(oi).join(", ")}.`);return t},$c=e=>{if(!e)return;let t=e.split(",").map(r=>r.trim()).filter(Boolean);return t.length===0?void 0:t},ii=e=>{e.command("env <NAME>").description("Declare a new environment variable across schema, .env.example, and .env").option("--type <type>","Zod type (string|url|number|boolean|enum)","string").option("--required","Make the variable required (no .optional() / .default())").option("--default <value>","Set a default value (mutually exclusive with --required)").option("--public","Mark as public (auto-prefix NEXT_PUBLIC_ and tag .env.example)").option("--describe <text>","Description (rendered as .describe() and .env.example comment)").option("--enum <list>",'Comma-separated values when --type=enum (e.g. "dev,prod")').action(async(t,r)=>{try{let n=process.cwd();if(l(ke.cyan(`
1116
+ `,o=t.default??"";return`${e}${i}${r}=${o}
1117
+ `},Ar=async(e,t)=>{Ao(t.name);let r=kr.join(e,"src/lib/env/schema.ts");if(!m(r))throw new Error("src/lib/env/schema.ts not found \u2014 run `next-maker init` first.");let n=await f(r),i=Oo(n,t),o=i!==n;o&&await g(r,i);let s=kr.join(e,c.ENV_EXAMPLE),a=!1;if(m(s)){let d=await f(s),h=Fo(d,t);a=h!==d,a&&await g(s,h)}let p=kr.join(e,".env"),u=!1;if(m(p)){let d=await f(p),h=jo(d,t);u=h!==d,u&&await g(p,h)}return{schemaUpdated:o,envExampleUpdated:a,envUpdated:u}};var Do=new Set(["string","url","number","boolean","enum"]),$p=e=>{let t=(e??"string").toLowerCase();if(!Do.has(t))throw new Error(`Invalid --type "${e}". Valid: ${Array.from(Do).join(", ")}.`);return t},Ip=e=>{if(!e)return;let t=e.split(",").map(r=>r.trim()).filter(Boolean);return t.length===0?void 0:t},Lo=e=>{e.command("env <NAME>").description("Declare a new environment variable across schema, .env.example, and .env").option("--type <type>","Zod type (string|url|number|boolean|enum)","string").option("--required","Make the variable required (no .optional() / .default())").option("--default <value>","Set a default value (mutually exclusive with --required)").option("--public","Mark as public (auto-prefix NEXT_PUBLIC_ and tag .env.example)").option("--describe <text>","Description (rendered as .describe() and .env.example comment)").option("--enum <list>",'Comma-separated values when --type=enum (e.g. "dev,prod")').action(async(t,r)=>{try{let n=process.cwd();if(l(Fe.cyan(`
970
1118
  \u{1F510} Env Var Generator
971
- `)),r.required&&r.default!==void 0)throw new Error("--required and --default are mutually exclusive.");let o=Rc(r.type),i=$c(r.enum);if(o==="enum"&&(!i||i.length===0))throw new Error("--type=enum requires at least one value via --enum a,b,c.");let s={name:t,type:o,required:!!r.required,default:r.default,description:r.describe,enumValues:i,public:!!r.public};y.start("Updating schema, .env.example, and .env...");let a=await xr(n,s);y.succeed("Env var written");let p=ue(s.name,s.public);l(ke.green(`
1119
+ `)),r.required&&r.default!==void 0)throw new Error("--required and --default are mutually exclusive.");let i=$p(r.type),o=Ip(r.enum);if(i==="enum"&&(!o||o.length===0))throw new Error("--type=enum requires at least one value via --enum a,b,c.");let s={name:t,type:i,required:!!r.required,default:r.default,description:r.describe,enumValues:o,public:!!r.public};y.start("Updating schema, .env.example, and .env...");let a=await Ar(n,s);y.succeed("Env var written");let p=ue(s.name,s.public);l(Fe.green(`
972
1120
  \u2728 ${p} declared.
973
- `)),l(ke.dim("Touched:")),l(ke.dim(` ${a.schemaUpdated?"\u270F\uFE0F ":"\u23ED "} src/lib/env/schema.ts`)),l(ke.dim(` ${a.envExampleUpdated?"\u270F\uFE0F ":"\u23ED "} .env.example`)),l(ke.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 $t from"node:path";import Te from"picocolors";import Ic from"enquirer";var{prompt:Nc}=Ic,si=async(e={})=>e.source?{source:e.source}:{source:(await Nc({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 kc,readFile as Ac,stat as Oc}from"node:fs/promises";import Ce from"node:path";var ai=async e=>{try{return await kc(e),!0}catch{return!1}},Fc=async e=>{try{return(await Oc(e)).isDirectory()}catch{return!1}},bt=async e=>{let t=[Ce.join(e,"src","app"),Ce.join(e,"app")];for(let r of t)if(await Fc(r))return r;return null},_c=["next-pwa","@ducanh2912/next-pwa","@serwist/next","serwist"],Pr=async e=>{let t={isPwa:!1},r=[Ce.join(e,"public","manifest.json"),Ce.join(e,"public","manifest.webmanifest"),Ce.join(e,"public","site.webmanifest")];for(let o of r)if(await ai(o)){t.publicManifestPath=o,t.isPwa=!0;break}let n=await bt(e);if(n)for(let o of["ts","tsx","js"]){let i=Ce.join(n,`manifest.${o}`);if(await ai(i)){t.appManifestPath=i,t.isPwa=!0;break}}try{let o=JSON.parse(await Ac(Ce.join(e,"package.json"),"utf-8")),i={...o.dependencies,...o.devDependencies};for(let s of _c)if(i[s]){t.framework=s,t.isPwa=!0;break}}catch{}return t};import{mkdir as Gc,readFile as yi,stat as Hc,writeFile as Uc}from"node:fs/promises";import re from"node:path";import zc from"sharp";import Dc from"png-to-ico";import ot from"sharp";var ci=e=>e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;"),vr=(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 jc(t)}},jc=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="${ci(n)}" fill="white"/></svg>`},pi=(e,t)=>`<svg xmlns="http://www.w3.org/2000/svg" width="${e}" height="${e}"><rect width="${e}" height="${e}" fill="${ci(t)}"/></svg>`;var Ae=async e=>{let{size:t,paddingPercent:r,bg:n,fit:o,shape:i,radiusPercent:s,quality:a,forceSquare:p,sourceBuffer:u}=e,d=Math.max(1,Math.round(t*(1-r*2/100))),h=o==="cover"?"cover":"contain",x=await ot(u,{density:384}).resize(d,d,{fit:h,background:{r:0,g:0,b:0,alpha:0}}).png().toBuffer(),k=Math.round((t-d)/2),z=n==="transparent"?{r:0,g:0,b:0,alpha:0}:await wr(n),$=await ot({create:{width:t,height:t,channels:4,background:z}}).composite([{input:x,left:k,top:k}]).png().toBuffer();if(!p&&(i!=="square"||o==="clip")){let he=i==="square"?"rounded":i,qi=Buffer.from(vr(he,t,s));$=await ot($).composite([{input:qi,blend:"dest-in"}]).png({compressionLevel:li(a)}).toBuffer()}else $=await ot($).png({compressionLevel:li(a)}).toBuffer();return $},wr=async e=>{let t=await ot(Buffer.from(pi(1,e))).raw().toBuffer({resolveWithObject:!0}),[r,n,o,i=255]=t.data;return{r,g:n,b:o,alpha:i/255}},li=e=>{let t=Math.round((100-e)/100*9);return Math.max(0,Math.min(9,t))},mi=async e=>{if(e.length===0)throw new Error("No frames provided to encodeIco");return Dc(e)};import{readFile as Lc,writeFile as Hx}from"node:fs/promises";var di=e=>e.map(({src:t,size:r})=>({src:t,sizes:`${r}x${r}`,type:"image/png",purpose:"any maskable"})),ui=async(e,t)=>{let r=await Lc(e,"utf-8"),n=JSON.parse(r),o=Array.isArray(n.icons)?n.icons:[],i=new Map;for(let s of[...o,...t])s&&typeof s.src=="string"&&i.set(s.src,s);return n.icons=[...i.values()],`${JSON.stringify(n,null,2)}
974
- `};var fi=e=>`icons: [
1121
+ `)),l(Fe.dim("Touched:")),l(Fe.dim(` ${a.schemaUpdated?"\u270F\uFE0F ":"\u23ED "} src/lib/env/schema.ts`)),l(Fe.dim(` ${a.envExampleUpdated?"\u270F\uFE0F ":"\u23ED "} .env.example`)),l(Fe.dim(` ${a.envUpdated?"\u270F\uFE0F ":"\u23ED "} .env`)),l("")}catch(n){y.fail("Env var declaration failed"),v(`${n instanceof Error?n.message:n}`),process.exit(1)}})};import Lt from"node:path";import Te from"picocolors";import Np from"enquirer";var{prompt:kp}=Np,Mo=async(e={})=>e.source?{source:e.source}:{source:(await kp({type:"input",name:"source",message:"Path to source image (PNG/JPG/JPEG/SVG/WebP/AVIF):",validate:r=>r?!0:"Source path is required"})).source};import{access as Ap,readFile as _p,stat as Op}from"node:fs/promises";import Ee from"node:path";var Go=async e=>{try{return await Ap(e),!0}catch{return!1}},Fp=async e=>{try{return(await Op(e)).isDirectory()}catch{return!1}},jt=async e=>{let t=[Ee.join(e,"src","app"),Ee.join(e,"app")];for(let r of t)if(await Fp(r))return r;return null},jp=["next-pwa","@ducanh2912/next-pwa","@serwist/next","serwist"],_r=async e=>{let t={isPwa:!1},r=[Ee.join(e,"public","manifest.json"),Ee.join(e,"public","manifest.webmanifest"),Ee.join(e,"public","site.webmanifest")];for(let i of r)if(await Go(i)){t.publicManifestPath=i,t.isPwa=!0;break}let n=await jt(e);if(n)for(let i of["ts","tsx","js"]){let o=Ee.join(n,`manifest.${i}`);if(await Go(o)){t.appManifestPath=o,t.isPwa=!0;break}}try{let i=JSON.parse(await _p(Ee.join(e,"package.json"),"utf-8")),o={...i.dependencies,...i.devDependencies};for(let s of jp)if(o[s]){t.framework=s,t.isPwa=!0;break}}catch{}return t};import{mkdir as Hp,readFile as Yo,stat as Up,writeFile as Bp}from"node:fs/promises";import re from"node:path";import zp from"sharp";import Lp from"png-to-ico";import yt from"sharp";var Ho=e=>e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;"),Or=(e,t,r)=>{switch(e){case"square":return`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}"><rect width="${t}" height="${t}" fill="white"/></svg>`;case"circle":{let n=t/2;return`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}"><circle cx="${n}" cy="${n}" r="${n}" fill="white"/></svg>`}case"rounded":{let n=Math.round(t*r/100);return`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}"><rect width="${t}" height="${t}" rx="${n}" ry="${n}" fill="white"/></svg>`}case"squircle":return Dp(t)}},Dp=e=>{let t=e,r=t*.225,n=[`M 0 ${r}`,`C 0 0 0 0 ${r} 0`,`L ${t-r} 0`,`C ${t} 0 ${t} 0 ${t} ${r}`,`L ${t} ${t-r}`,`C ${t} ${t} ${t} ${t} ${t-r} ${t}`,`L ${r} ${t}`,`C 0 ${t} 0 ${t} 0 ${t-r}`,"Z"].join(" ");return`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}"><path d="${Ho(n)}" fill="white"/></svg>`},Uo=(e,t)=>`<svg xmlns="http://www.w3.org/2000/svg" width="${e}" height="${e}"><rect width="${e}" height="${e}" fill="${Ho(t)}"/></svg>`;var je=async e=>{let{size:t,paddingPercent:r,bg:n,fit:i,shape:o,radiusPercent:s,quality:a,forceSquare:p,sourceBuffer:u}=e,d=Math.max(1,Math.round(t*(1-r*2/100))),h=i==="cover"?"cover":"contain",x=await yt(u,{density:384}).resize(d,d,{fit:h,background:{r:0,g:0,b:0,alpha:0}}).png().toBuffer(),$=Math.round((t-d)/2),J=n==="transparent"?{r:0,g:0,b:0,alpha:0}:await Fr(n),I=await yt({create:{width:t,height:t,channels:4,background:J}}).composite([{input:x,left:$,top:$}]).png().toBuffer();if(!p&&(o!=="square"||i==="clip")){let he=o==="square"?"rounded":o,bs=Buffer.from(Or(he,t,s));I=await yt(I).composite([{input:bs,blend:"dest-in"}]).png({compressionLevel:Bo(a)}).toBuffer()}else I=await yt(I).png({compressionLevel:Bo(a)}).toBuffer();return I},Fr=async e=>{let t=await yt(Buffer.from(Uo(1,e))).raw().toBuffer({resolveWithObject:!0}),[r,n,i,o=255]=t.data;return{r,g:n,b:i,alpha:o/255}},Bo=e=>{let t=Math.round((100-e)/100*9);return Math.max(0,Math.min(9,t))},zo=async e=>{if(e.length===0)throw new Error("No frames provided to encodeIco");return Lp(e)};import{readFile as Mp,writeFile as Fw}from"node:fs/promises";var Jo=e=>e.map(({src:t,size:r})=>({src:t,sizes:`${r}x${r}`,type:"image/png",purpose:"any maskable"})),Vo=async(e,t)=>{let r=await Mp(e,"utf-8"),n=JSON.parse(r),i=Array.isArray(n.icons)?n.icons:[],o=new Map;for(let s of[...i,...t])s&&typeof s.src=="string"&&o.set(s.src,s);return n.icons=[...o.values()],`${JSON.stringify(n,null,2)}
1122
+ `};var Wo=e=>`icons: [
975
1123
  ${e.map(r=>` { src: '${r.src}', sizes: '${r.sizes}', type: '${r.type}'${r.purpose?`, purpose: '${r.purpose}'`:""} }`).join(`,
976
1124
  `)},
977
- ],`,gi=(e,t,r)=>`${JSON.stringify({name:e,short_name:e,start_url:"/",display:"standalone",background_color:"#ffffff",theme_color:t,icons:r},null,2)}
978
- `;import{stat as Mc}from"node:fs/promises";import Sr from"node:path";var hi=[".png",".jpg",".jpeg",".webp",".svg",".avif"],Rt=async e=>{if(!e)throw new Error("Source image path is required (use --path).");let t=Sr.isAbsolute(e)?e:Sr.resolve(process.cwd(),e),r;try{r=await Mc(t)}catch{throw new Error(`Source image not found: ${t}`)}if(!r.isFile())throw new Error(`Source is not a file: ${t}`);let n=Sr.extname(t).toLowerCase();if(!hi.includes(n))throw new Error(`Unsupported source format '${n}'. Use one of: ${hi.join(", ")}`);return{absolutePath:t,ext:n,bytes:r.size,isVector:n===".svg"}};var Cr=(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 Jc=async e=>{try{return await Hc(e),!0}catch{return!1}},Vc=async(e,t,r)=>{let n=[];for(let o of e){if(await Jc(o.outPath)&&!t&&!o.alwaysWrite){n.push({path:o.outPath,bytes:o.bytes.length,skipped:!0});continue}r||(await Gc(re.dirname(o.outPath),{recursive:!0}),await Uc(o.outPath,o.bytes)),n.push({path:o.outPath,bytes:o.bytes.length})}return n},Tr=async(e,t)=>{let r=await Rt(t.source),n=await yi(r.absolutePath),o=t.ogSource?await yi((await Rt(t.ogSource)).absolutePath):n,i=[],s=[];for(let d of t.icoSizes)s.push(await Ae({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 mi(s);if(i.push({outPath:re.join(t.outDir,"favicon.ico"),bytes:a}),t.emitIcon){let d=await Ae({sourceBuffer:n,size:512,shape:t.shape,radiusPercent:t.radius,bg:t.bg,paddingPercent:t.padding,fit:t.fit,quality:t.quality});i.push({outPath:re.join(t.outDir,"icon.png"),bytes:d})}if(t.emitApple){let d=t.bg==="transparent"?"#ffffff":t.bg,h=await Ae({sourceBuffer:n,size:180,shape:t.shape,radiusPercent:t.radius,bg:d,paddingPercent:t.padding,fit:t.fit,quality:t.quality});i.push({outPath:re.join(t.outDir,"apple-icon.png"),bytes:h})}if(t.emitOg){let d=await xi(o,t,!1);i.push({outPath:re.join(t.outDir,"opengraph-image.png"),bytes:d})}if(t.emitTwitter){let d=await xi(o,t,!0);i.push({outPath:re.join(t.outDir,"twitter-image.png"),bytes:d})}let p;if(t.pwa||t.pwaInit){let d=await Pr(e);if(t.pwa&&!d.isPwa)throw new Error("No PWA setup detected. Use --pwa-init to bootstrap a manifest, or set up next-pwa/serwist first.");let h=re.join(e,"public"),x=[192,512],k=[];for(let $ of x){let J=await Ae({sourceBuffer:n,size:$,shape:t.shape,radiusPercent:t.radius,bg:t.bg,paddingPercent:t.padding,fit:t.fit,quality:t.quality}),he=`icon-${$}.png`;i.push({outPath:re.join(h,he),bytes:J}),k.push({src:`/${he}`,size:$})}let z=di(k);if(d.publicManifestPath){let $=await ui(d.publicManifestPath,z);i.push({outPath:d.publicManifestPath,bytes:Buffer.from($,"utf-8"),alwaysWrite:!0})}else if(d.appManifestPath)p=fi(z);else if(t.pwaInit){let $=re.join(h,"manifest.webmanifest"),J=gi(re.basename(e)||"App","#000000",z);i.push({outPath:$,bytes:Buffer.from(J,"utf-8")})}}return{outputs:await Vc(i,t.force,t.dryRun),pwaSnippet:p}},xi=async(e,t,r)=>{let o=r?600:630,i=Math.round(Math.min(1200,o)*(1-t.padding*2/100)),s=await Ae({sourceBuffer:e,size:i,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 wr(a),u=Math.round((1200-i)/2),d=Math.round((o-i)/2);return zc({create:{width:1200,height:o,channels:4,background:p}}).composite([{input:s,left:u,top:d}]).png().toBuffer()};var Pi=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 Bc=["square","rounded","circle","squircle"],qc=["contain","cover","clip"],vi=(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},Er=(e,t,r,n,o)=>{if(e===void 0)return t;let i=Number(e);if(!Number.isFinite(i)||i<n||i>o)throw new Error(`Invalid value for --${r}: '${e}'. Must be a number between ${n}\u2013${o}.`);return i},Si=e=>{e.command("favicon").description("Generate favicon.ico (and optionally icons, OG image, PWA manifest icons)").option("--path <file>","Path to source image (PNG, JPG, JPEG, WebP, SVG, AVIF)").option("--out <dir>","Output dir (default: src/app or app)").option("--force","Overwrite existing files without prompt",!1).option("--dry-run","Show what would be written without writing",!1).option("--icon","Also emit icon.png (512\xD7512)",!1).option("--apple","Also emit apple-icon.png (180\xD7180)",!1).option("--og","Also emit opengraph-image.png (1200\xD7630)",!1).option("--og-source <file>","Use a separate image for the OG/Twitter card").option("--twitter","Also emit twitter-image.png (1200\xD7600)",!1).option("--all","Shorthand for --icon --apple --og",!1).option("--pwa","Detect PWA setup and emit manifest icons (192/512); errors if not detected",!1).option("--pwa-init","Bootstrap public/manifest.webmanifest with icons",!1).option("--shape <shape>","square | rounded | circle | squircle","square").option("--radius <percent>","Corner radius % when shape=rounded (0-50)","20").option("--bg <color>",'Background color (hex, css name, or "transparent")',"transparent").option("--padding <percent>","Padding around source content (0-30)","0").option("--fit <fit>","How source fits target: contain | cover | clip","contain").option("--sizes <list>","Comma-separated ICO sizes (default: 16,32,48)").option("--quality <n>","PNG compression 1-100 (higher = smaller file; PNG is lossless, default: 90)","90").action(async t=>{try{let r=process.cwd();l(Te.cyan(`
1125
+ ],`,qo=(e,t,r)=>`${JSON.stringify({name:e,short_name:e,start_url:"/",display:"standalone",background_color:"#ffffff",theme_color:t,icons:r},null,2)}
1126
+ `;import{stat as Gp}from"node:fs/promises";import jr from"node:path";var Xo=[".png",".jpg",".jpeg",".webp",".svg",".avif"],Dt=async e=>{if(!e)throw new Error("Source image path is required (use --path).");let t=jr.isAbsolute(e)?e:jr.resolve(process.cwd(),e),r;try{r=await Gp(t)}catch{throw new Error(`Source image not found: ${t}`)}if(!r.isFile())throw new Error(`Source is not a file: ${t}`);let n=jr.extname(t).toLowerCase();if(!Xo.includes(n))throw new Error(`Unsupported source format '${n}'. Use one of: ${Xo.join(", ")}`);return{absolutePath:t,ext:n,bytes:r.size,isVector:n===".svg"}};var Dr=(e,t)=>{if(!e)return t;let r=e.split(",").map(n=>Number.parseInt(n.trim(),10)).filter(n=>Number.isFinite(n)&&n>0&&n<=1024);if(r.length===0)throw new Error(`Invalid --sizes value: '${e}'. Provide comma-separated positive integers.`);return r};var Jp=async e=>{try{return await Up(e),!0}catch{return!1}},Vp=async(e,t,r)=>{let n=[];for(let i of e){if(await Jp(i.outPath)&&!t&&!i.alwaysWrite){n.push({path:i.outPath,bytes:i.bytes.length,skipped:!0});continue}r||(await Hp(re.dirname(i.outPath),{recursive:!0}),await Bp(i.outPath,i.bytes)),n.push({path:i.outPath,bytes:i.bytes.length})}return n},Lr=async(e,t)=>{let r=await Dt(t.source),n=await Yo(r.absolutePath),i=t.ogSource?await Yo((await Dt(t.ogSource)).absolutePath):n,o=[],s=[];for(let d of t.icoSizes)s.push(await je({sourceBuffer:n,size:d,shape:"square",radiusPercent:t.radius,bg:t.bg,paddingPercent:t.padding,fit:t.fit,quality:t.quality,forceSquare:!0}));let a=await zo(s);if(o.push({outPath:re.join(t.outDir,"favicon.ico"),bytes:a}),t.emitIcon){let d=await je({sourceBuffer:n,size:512,shape:t.shape,radiusPercent:t.radius,bg:t.bg,paddingPercent:t.padding,fit:t.fit,quality:t.quality});o.push({outPath:re.join(t.outDir,"icon.png"),bytes:d})}if(t.emitApple){let d=t.bg==="transparent"?"#ffffff":t.bg,h=await je({sourceBuffer:n,size:180,shape:t.shape,radiusPercent:t.radius,bg:d,paddingPercent:t.padding,fit:t.fit,quality:t.quality});o.push({outPath:re.join(t.outDir,"apple-icon.png"),bytes:h})}if(t.emitOg){let d=await Ko(i,t,!1);o.push({outPath:re.join(t.outDir,"opengraph-image.png"),bytes:d})}if(t.emitTwitter){let d=await Ko(i,t,!0);o.push({outPath:re.join(t.outDir,"twitter-image.png"),bytes:d})}let p;if(t.pwa||t.pwaInit){let d=await _r(e);if(t.pwa&&!d.isPwa)throw new Error("No PWA setup detected. Use --pwa-init to bootstrap a manifest, or set up next-pwa/serwist first.");let h=re.join(e,"public"),x=[192,512],$=[];for(let I of x){let V=await je({sourceBuffer:n,size:I,shape:t.shape,radiusPercent:t.radius,bg:t.bg,paddingPercent:t.padding,fit:t.fit,quality:t.quality}),he=`icon-${I}.png`;o.push({outPath:re.join(h,he),bytes:V}),$.push({src:`/${he}`,size:I})}let J=Jo($);if(d.publicManifestPath){let I=await Vo(d.publicManifestPath,J);o.push({outPath:d.publicManifestPath,bytes:Buffer.from(I,"utf-8"),alwaysWrite:!0})}else if(d.appManifestPath)p=Wo(J);else if(t.pwaInit){let I=re.join(h,"manifest.webmanifest"),V=qo(re.basename(e)||"App","#000000",J);o.push({outPath:I,bytes:Buffer.from(V,"utf-8")})}}return{outputs:await Vp(o,t.force,t.dryRun),pwaSnippet:p}},Ko=async(e,t,r)=>{let i=r?600:630,o=Math.round(Math.min(1200,i)*(1-t.padding*2/100)),s=await je({sourceBuffer:e,size:o,shape:t.shape,radiusPercent:t.radius,bg:"transparent",paddingPercent:0,fit:t.fit,quality:t.quality}),a=t.bg==="transparent"?"#ffffff":t.bg,p=await Fr(a),u=Math.round((1200-o)/2),d=Math.round((i-o)/2);return zp({create:{width:1200,height:i,channels:4,background:p}}).composite([{input:s,left:u,top:d}]).png().toBuffer()};var Zo=new Set(["aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkgrey","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","green","greenyellow","grey","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightgrey","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen"]);var Wp=["square","rounded","circle","squircle"],qp=["contain","cover","clip"],Qo=(e,t,r,n)=>{if(!e)return r;if(!t.includes(e))throw new Error(`Invalid value for --${n}: '${e}'. Allowed: ${t.join(", ")}`);return e},Mr=(e,t,r,n,i)=>{if(e===void 0)return t;let o=Number(e);if(!Number.isFinite(o)||o<n||o>i)throw new Error(`Invalid value for --${r}: '${e}'. Must be a number between ${n}\u2013${i}.`);return o},ts=e=>{e.command("favicon").description("Generate favicon.ico (and optionally icons, OG image, PWA manifest icons)").option("--path <file>","Path to source image (PNG, JPG, JPEG, WebP, SVG, AVIF)").option("--out <dir>","Output dir (default: src/app or app)").option("--force","Overwrite existing files without prompt",!1).option("--dry-run","Show what would be written without writing",!1).option("--icon","Also emit icon.png (512\xD7512)",!1).option("--apple","Also emit apple-icon.png (180\xD7180)",!1).option("--og","Also emit opengraph-image.png (1200\xD7630)",!1).option("--og-source <file>","Use a separate image for the OG/Twitter card").option("--twitter","Also emit twitter-image.png (1200\xD7600)",!1).option("--all","Shorthand for --icon --apple --og",!1).option("--pwa","Detect PWA setup and emit manifest icons (192/512); errors if not detected",!1).option("--pwa-init","Bootstrap public/manifest.webmanifest with icons",!1).option("--shape <shape>","square | rounded | circle | squircle","square").option("--radius <percent>","Corner radius % when shape=rounded (0-50)","20").option("--bg <color>",'Background color (hex, css name, or "transparent")',"transparent").option("--padding <percent>","Padding around source content (0-30)","0").option("--fit <fit>","How source fits target: contain | cover | clip","contain").option("--sizes <list>","Comma-separated ICO sizes (default: 16,32,48)").option("--quality <n>","PNG compression 1-100 (higher = smaller file; PNG is lossless, default: 90)","90").action(async t=>{try{let r=process.cwd();l(Te.cyan(`
979
1127
  \u{1F3A8} Favicon Generator
980
- `));let n=await si({source:t.path}),o=await Xc(r,t.out),i=vi(t.shape,Bc,"square","shape"),s=vi(t.fit,qc,"contain","fit"),a=Er(t.radius,20,"radius",0,50),p=Er(t.padding,0,"padding",0,30),u=Er(t.quality,90,"quality",1,100),d=Cr(t.sizes,[16,32,48]),h=t.bg??"transparent";Kc(h);let x=t.all===!0,k={source:n.source,outDir:o,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:i,radius:a,bg:h,padding:p,fit:s,icoSizes:d,quality:u};y.start("Generating favicon assets...");let z=await Tr(r,k);y.succeed(k.dryRun?"Favicon plan ready":"Favicon assets generated"),l("");for(let $ of z.outputs){let J=$t.relative(r,$.path);$.skipped?l(Te.yellow(` \u21B7 skipped ${J} (exists; use --force to overwrite)`)):k.dryRun?l(Te.dim(` \u{1F4C4} would write ${J} (${wi($.bytes)})`)):l(Te.green(` \u2713 ${J} `)+Te.dim(`(${wi($.bytes)})`))}z.pwaSnippet&&(l(""),l(Te.cyan("Add this to your typed manifest (src/app/manifest.ts):")),l(Te.dim(z.pwaSnippet))),l("")}catch(r){y.fail("Favicon generation failed");let n=r instanceof Error?r.message:String(r);v(n),process.exit(1)}})},Xc=async(e,t)=>{if(t)return $t.isAbsolute(t)?t:$t.resolve(e,t);let r=await bt(e);return r||(Mr("Could not detect app/ or src/app/ \u2014 falling back to src/app"),$t.join(e,"src","app"))},Wc=/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/,Yc=/^(?:rgb|rgba|hsl|hsla)\(\s*[\d.,%\s/]+\)$/i,Kc=e=>{if(e!=="transparent"&&!Wc.test(e)&&!Yc.test(e)&&!Pi.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().`)},wi=e=>e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(2)} MB`;import Or from"node:path";import M from"picocolors";G();G();import fp from"node:path";import{readFile as Zc,writeFile as Qc}from"node:fs/promises";import ep from"node:path";var it=(e,t)=>{let r=/import\s+.*\s+from\s+['"].*['"];?\n/g,n=e.match(r);if(n&&n.length>0){let o=n[n.length-1],i=e.lastIndexOf(o);return e.slice(0,i+o.length)+t+`
981
- `+e.slice(i+o.length)}return`${t}
982
- ${e}`},br=(e,t,r)=>{let n=/combineReducers\(\{([^}]*)\}\)/s,o=e.match(n);if(!o)throw new Error("Could not find combineReducers in rootReducer.ts");let i=o[1],s=`
983
- ${t}: ${r},`,a=i.trimEnd()+s;return e.replace(n,`combineReducers({${a}
984
- })`)},st=(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),o=e.substring(r);return`${n.trimEnd()}
985
- ${t}
986
- ${o}`};var at=async e=>{let{serviceName:t,projectPath:r}=e,n=O(t),o=ep.join(r,"src","lib","config","app-apis.ts");try{let i=await Zc(o,"utf-8");if(i.includes(`${n}:`))return;if(!i.match(/export const AppApis = \{[\s\S]*?\} as const;/))throw new Error("Could not find AppApis object in app-apis.ts");let s=` ${n}: {
1128
+ `));let n=await Mo({source:t.path}),i=await Xp(r,t.out),o=Qo(t.shape,Wp,"square","shape"),s=Qo(t.fit,qp,"contain","fit"),a=Mr(t.radius,20,"radius",0,50),p=Mr(t.padding,0,"padding",0,30),u=Mr(t.quality,90,"quality",1,100),d=Dr(t.sizes,[16,32,48]),h=t.bg??"transparent";Zp(h);let x=t.all===!0,$={source:n.source,outDir:i,force:!!t.force,dryRun:!!t.dryRun,emitIcon:!!t.icon||x,emitApple:!!t.apple||x,emitOg:!!t.og||x,emitTwitter:!!t.twitter,ogSource:t.ogSource,pwa:!!t.pwa,pwaInit:!!t.pwaInit,shape:o,radius:a,bg:h,padding:p,fit:s,icoSizes:d,quality:u};y.start("Generating favicon assets...");let J=await Lr(r,$);y.succeed($.dryRun?"Favicon plan ready":"Favicon assets generated"),l("");for(let I of J.outputs){let V=Lt.relative(r,I.path);I.skipped?l(Te.yellow(` \u21B7 skipped ${V} (exists; use --force to overwrite)`)):$.dryRun?l(Te.dim(` \u{1F4C4} would write ${V} (${es(I.bytes)})`)):l(Te.green(` \u2713 ${V} `)+Te.dim(`(${es(I.bytes)})`))}J.pwaSnippet&&(l(""),l(Te.cyan("Add this to your typed manifest (src/app/manifest.ts):")),l(Te.dim(J.pwaSnippet))),l("")}catch(r){y.fail("Favicon generation failed");let n=r instanceof Error?r.message:String(r);v(n),process.exit(1)}})},Xp=async(e,t)=>{if(t)return Lt.isAbsolute(t)?t:Lt.resolve(e,t);let r=await jt(e);return r||(Zr("Could not detect app/ or src/app/ \u2014 falling back to src/app"),Lt.join(e,"src","app"))},Yp=/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/,Kp=/^(?:rgb|rgba|hsl|hsla)\(\s*[\d.,%\s/]+\)$/i,Zp=e=>{if(e!=="transparent"&&!Yp.test(e)&&!Kp.test(e)&&!Zo.has(e.toLowerCase()))throw new Error(`Invalid value for --bg: '${e}'. Use 'transparent', a hex code (e.g. #0f172a), a CSS color name, or rgb()/rgba()/hsl()/hsla().`)},es=e=>e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(2)} MB`;import Vr from"node:path";import M from"picocolors";H();H();import dl from"node:path";import{readFile as Qp,writeFile as el}from"node:fs/promises";import tl from"node:path";var xt=async e=>{let{serviceName:t,projectPath:r}=e,n=j(t),i=tl.join(r,"src","lib","config","app-apis.ts");try{let o=await Qp(i,"utf-8");if(o.includes(`${n}:`))return;if(!o.match(/export const AppApis = \{[\s\S]*?\} as const;/))throw new Error("Could not find AppApis object in app-apis.ts");let s=` ${n}: {
987
1129
  base: '/${t}',
988
1130
  getAll: '/${t}',
989
- },`;i=st(i,s),await Qc(o,i)}catch(i){throw new Error(`Failed to register API endpoints: ${i}`,{cause:i})}};import{readFile as tp,writeFile as rp}from"node:fs/promises";import np from"node:path";P();var Rr=async(e,t,r)=>{let n=np.join(e,"src","lib","config","app-paths.ts");if(!m(n))return;let o=await tp(n,"utf-8"),i=O(t);if(o.includes(`${i}:`))return;let s=o.lastIndexOf("} as const;");if(s===-1)return;let a=` ${i}: '${r}',
990
- `;o=o.slice(0,s)+a+o.slice(s),await rp(n,o)};S();P();import It from"node:path";var op=e=>new RegExp(`<\\s*${e}\\b`),Ci=(e,t)=>{if(op(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 o=n.groups?.indent??"",i=`${o} `,s=`${o}<${t}>
991
- ${i}{children}
992
- ${o}</${t}>`;return e.replace(r,s)},Ti=(e,t)=>{let r=`export * from './${t}';`;if(e.includes(r))return e;let n=e.split(`
993
- `),o=[],i=[];for(let h of n)/^export \* from '\.\/.*';\s*$/.test(h)?o.push(h):i.push(h);let s=[...o,r].sort(),a=n.findIndex(h=>/^export \* from '\.\//.test(h));if(a===-1)return`${r}
1131
+ },`;o=ze(o,s),await el(i,o)}catch(o){throw new Error(`Failed to register API endpoints: ${o}`,{cause:o})}};import{readFile as rl,writeFile as nl}from"node:fs/promises";import il from"node:path";P();var Gr=async(e,t,r)=>{let n=il.join(e,"src","lib","config","app-paths.ts");if(!m(n))return;let i=await rl(n,"utf-8"),o=j(t);if(i.includes(`${o}:`))return;let s=i.lastIndexOf("} as const;");if(s===-1)return;let a=` ${o}: '${r}',
1132
+ `;i=i.slice(0,s)+a+i.slice(s),await nl(n,i)};S();P();import Mt from"node:path";var ol=e=>new RegExp(`<\\s*${e}\\b`),rs=(e,t)=>{if(ol(t).test(e))return e;let r=/^(?<indent>[ \t]*)\{children\}\s*$/m,n=e.match(r);if(!n||n.index===void 0)throw new Error("Could not locate `{children}` line in RootProvider \u2014 expected a line containing only `{children}`.");let i=n.groups?.indent??"",o=`${i} `,s=`${i}<${t}>
1133
+ ${o}{children}
1134
+ ${i}</${t}>`;return e.replace(r,s)},ns=(e,t)=>{let r=`export * from './${t}';`;if(e.includes(r))return e;let n=e.split(`
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}
994
1136
  ${e.replace(/^\n+/,"")}`;let p=n.slice(0,a),u=n.findIndex((h,x)=>x>a&&!/^export \* from '\.\//.test(h)),d=u===-1?[]:n.slice(u);return[...p,...s,...d].join(`
995
- `)},ip=c.PROVIDERS,sp=c.ROOT_PROVIDER,ap=c.PROVIDERS_INDEX,Ei=async(e,t={fileExists:m,readFile:f})=>{let r=It.join(e,sp);if(t.fileExists(r))return r;let n=It.join(e,ip);if(!t.fileExists(n))return null;let{readdir:o}=await import("node:fs/promises"),s=(await o(n).catch(()=>[])).filter(p=>p.endsWith(".tsx")),a=null;for(let p of s){let u=It.join(n,p),d=await t.readFile(u);if(!/\{children\}/.test(d))continue;let x=((d.split("{children}")[0]??"").match(/<[A-Z][A-Za-z0-9_]*\b/g)??[]).length;(!a||x>a.depth)&&(a={file:u,depth:x})}return a?.file??null},$r=async e=>{let{projectPath:t,componentName:r,fileBaseName:n}=e,o=await Ei(t);if(o){let a=await f(o),p=a;(!/from '\.\//.test(a)||!a.includes(`{ ${r} }`))&&(p=it(p,`import { ${r} } from './${n}';`)),p=Ci(p,r),p!==a&&await g(o,p)}let i=It.join(t,ap),s=null;if(m(i)){let a=await f(i),p=Ti(a,n);p!==a&&await g(i,p),s=i}return{rootProviderFile:o,barrelFile:s}};import{readFile as cp,writeFile as pp}from"node:fs/promises";import lp from"node:path";var ct=async e=>{let{projectPath:t,name:r,persist:n,importPath:o}=e,i=lp.join(t,"src","store","rootReducer.ts");try{let s=await cp(i,"utf-8"),a=O(r),p=`${a}Reducer`,u=`${a}PersistConfig`,d=o.replace(/^src\//,"@/"),h=n?`import { ${p}, ${u} } from '${d}';`:`import { ${p} } from '${d}';`;s=it(s,h);let x=n?`persistReducer(${u}, ${p})`:p;s=br(s,a,x),await pp(i,s)}catch(s){throw new Error(`Failed to register reducer '${r}' in rootReducer: ${s}`,{cause:s})}};P();import{readFile as mp,writeFile as dp}from"node:fs/promises";import up from"node:path";var Ir=async(e,t)=>{let r=up.join(e,"src","i18n","translations","en.json");if(!m(r))return;let n=await mp(r,"utf-8"),o=JSON.parse(n);o[t]||(o[t]={title:t,description:`${t} page description`},await dp(r,`${JSON.stringify(o,null,2)}
996
- `))};var Nr=()=>[{name:"Project setup detected",spinnerText:"Detecting project setup...",execute:async e=>{e.detection=await A(e.projectPath)}},{name:"Feature files generated",spinnerText:"Generating feature files...",execute:async e=>{await Wt({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 at({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 ct({projectPath:e.projectPath,name:e.featureName,persist:e.persistStore,importPath:fp.join(e.basePath,e.featureName,"store")})}}];var Ee=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 Le({name:e.serviceName,outputPath:e.servicePath,httpClient:e.httpClient})}},{name:"API endpoints registered",spinnerText:"Registering API endpoints...",execute:async e=>{await at({serviceName:e.serviceName,projectPath:e.projectPath})}}];import gp from"node:path";var Ar=()=>[{name:"Slice files generated",spinnerText:"Generating slice files...",execute:async e=>{await He({name:e.sliceName,outputPath:e.slicePath,persist:e.persistSlice})}},{name:"Slice registered in rootReducer",spinnerText:"Registering slice in rootReducer...",execute:async e=>{await ct({projectPath:e.projectPath,name:e.sliceName,persist:e.persistSlice,importPath:gp.join(e.basePath,e.sliceName)})}}];import hp from"enquirer";var{prompt:yp}=hp,bi=async(e,t,r,n,o,i,s)=>{let a=[];e||a.push({type:"input",name:"featureName",message:"What is the feature name?",initial:"my-feature",validate:u=>/^[a-z0-9-]+$/.test(u)?!0:"Feature name must be lowercase and contain only alphanumeric characters and hyphens."}),t&&n===void 0&&o===void 0&&(a.push({type:"confirm",name:"createStore",message:"Generate Redux store for this feature?",initial:!0}),a.push({type:"confirm",name:"persistStore",message:"Enable persistence for this store?",initial:!1,skip(){return!this.state.answers.createStore}})),r&&r!=="none"&&i===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 yp(a):{};return{featureName:e||p.featureName,hasRedux:t||!1,createStore:n===!0?!1:o!==void 0?!0:p.createStore||!1,persistStore:o==="persist"?!0:o==="no-persist"?!1:p.persistStore||!1,httpClient:r||"none",createService:i===!0?!1:s!==void 0?!0:p.createService||!1,selectedHttpClient:s||p.selectedHttpClient||(r==="both"?"fetch":r!=="none"?r:void 0)}};var Ri=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();xp(r),l(M.cyan(`
1137
+ `)},sl=c.PROVIDERS,al=c.ROOT_PROVIDER,cl=c.PROVIDERS_INDEX,is=async(e,t={fileExists:m,readFile:f})=>{let r=Mt.join(e,al);if(t.fileExists(r))return r;let n=Mt.join(e,sl);if(!t.fileExists(n))return null;let{readdir:i}=await import("node:fs/promises"),s=(await i(n).catch(()=>[])).filter(p=>p.endsWith(".tsx")),a=null;for(let p of s){let u=Mt.join(n,p),d=await t.readFile(u);if(!/\{children\}/.test(d))continue;let x=((d.split("{children}")[0]??"").match(/<[A-Z][A-Za-z0-9_]*\b/g)??[]).length;(!a||x>a.depth)&&(a={file:u,depth:x})}return a?.file??null},Hr=async e=>{let{projectPath:t,componentName:r,fileBaseName:n}=e,i=await is(t);if(i){let a=await f(i),p=a;(!/from '\.\//.test(a)||!a.includes(`{ ${r} }`))&&(p=Be(p,`import { ${r} } from './${n}';`)),p=rs(p,r),p!==a&&await g(i,p)}let o=Mt.join(t,cl),s=null;if(m(o)){let a=await f(o),p=ns(a,n);p!==a&&await g(o,p),s=o}return{rootProviderFile:i,barrelFile:s}};P();import{readFile as pl,writeFile as ll}from"node:fs/promises";import ml from"node:path";var Ur=async(e,t)=>{let r=ml.join(e,"src","i18n","translations","en.json");if(!m(r))return;let n=await pl(r,"utf-8"),i=JSON.parse(n);i[t]||(i[t]={title:t,description:`${t} page description`},await ll(r,`${JSON.stringify(i,null,2)}
1138
+ `))};var Br=()=>[{name:"Project setup detected",spinnerText:"Detecting project setup...",execute:async e=>{e.detection=await F(e.projectPath)}},{name:"Feature files generated",spinnerText:"Generating feature files...",execute:async e=>{await ar({name:e.featureName,outputPath:e.featurePath,createStore:e.createStore,persistStore:e.persistStore,createService:e.createService,httpClient:e.httpClient})}},{name:"API endpoints registered",spinnerText:"Registering API endpoints...",shouldSkip:e=>!e.createService,execute:async e=>{await xt({serviceName:e.featureName,projectPath:e.projectPath})}},{name:"Feature registered in rootReducer",spinnerText:"Registering feature in rootReducer...",shouldSkip:e=>!e.createStore||!e.detection.hasRedux,execute:async e=>{await we({projectPath:e.projectPath,name:e.featureName,persist:e.persistStore,importPath:dl.join(e.basePath,e.featureName,"store")})}}];var be=async(e,t)=>{for(let r of e)if(!r.shouldSkip?.(t)){t.spinner.start(r.spinnerText);try{await r.execute(t),t.spinner.succeed(r.name)}catch(n){throw t.spinner.fail(r.name),n}}};var zr=()=>[{name:"Service files generated",spinnerText:"Generating service files...",execute:async e=>{await Xe({name:e.serviceName,outputPath:e.servicePath,httpClient:e.httpClient})}},{name:"API endpoints registered",spinnerText:"Registering API endpoints...",execute:async e=>{await xt({serviceName:e.serviceName,projectPath:e.projectPath})}}];import ul from"node:path";var Jr=()=>[{name:"Slice files generated",spinnerText:"Generating slice files...",execute:async e=>{await Ze({name:e.sliceName,outputPath:e.slicePath,persist:e.persistSlice})}},{name:"Slice registered in rootReducer",spinnerText:"Registering slice in rootReducer...",execute:async e=>{await we({projectPath:e.projectPath,name:e.sliceName,persist:e.persistSlice,importPath:ul.join(e.basePath,e.sliceName)})}}];import fl from"enquirer";var{prompt:gl}=fl,os=async(e,t,r,n,i,o,s)=>{let a=[];e||a.push({type:"input",name:"featureName",message:"What is the feature name?",initial:"my-feature",validate:u=>/^[a-z0-9-]+$/.test(u)?!0:"Feature name must be lowercase and contain only alphanumeric characters and hyphens."}),t&&n===void 0&&i===void 0&&(a.push({type:"confirm",name:"createStore",message:"Generate Redux store for this feature?",initial:!0}),a.push({type:"confirm",name:"persistStore",message:"Enable persistence for this store?",initial:!1,skip(){return!this.state.answers.createStore}})),r&&r!=="none"&&o===void 0&&s===void 0&&(a.push({type:"confirm",name:"createService",message:"Generate API service for this feature?",initial:!0}),r==="both"&&a.push({type:"select",name:"selectedHttpClient",message:"Which HTTP client to use for the service?",choices:["fetch","axios"],initial:0,skip(){return!this.state.answers.createService}}));let p=a.length>0?await gl(a):{};return{featureName:e||p.featureName,hasRedux:t||!1,createStore:n===!0?!1:i!==void 0?!0:p.createStore||!1,persistStore:i==="persist"?!0:i==="no-persist"?!1:p.persistStore||!1,httpClient:r||"none",createService:o===!0?!1:s!==void 0?!0:p.createService||!1,selectedHttpClient:s||p.selectedHttpClient||(r==="both"?"fetch":r!=="none"?r:void 0)}};var ss=e=>{e.command("feature [name]").description("Generate a new feature module").option("--skip-store","Skip Redux store generation").option("--store <type>","Generate Redux store with persistence option (persist|no-persist)").option("--skip-service","Skip API service generation").option("--service <client>","Generate API service with specific HTTP client (axios|fetch)").option("--path <path>","Custom path for feature generation (default: src/features)").action(async(t,r)=>{try{let n=process.cwd();hl(r),l(M.cyan(`
997
1139
  \u{1F3AF} Feature Generator
998
- `));let o=Nr();y.start("Detecting project setup...");let{detectProjectSetup:i}=await Promise.resolve().then(()=>(G(),De)),s=await i(n);y.succeed("Project setup detected"),l(M.dim(` Redux: ${s.hasRedux?"\u2713":"\u2717"}`)),l(M.dim(` HTTP Client: ${s.httpClient}`)),l(M.dim(` i18n: ${s.hasI18n?"\u2713":"\u2717"}
999
- `));let a=await bi(t,s.hasRedux,s.httpClient,r.skipStore,r.store,r.skipService,r.service),p=r.path||Or.join("src","features"),u=Or.join(n,p,a.featureName);await le(n,a.featureName,p)&&(v(`Feature '${a.featureName}' already exists at ${p}!`),process.exit(1)),await Ee(o.slice(1),{projectPath:n,spinner:y,featureName:a.featureName,basePath:p,featurePath:u,createStore:a.createStore,persistStore:a.persistStore,createService:a.createService,httpClient:a.selectedHttpClient,detection:s}),Pp(a,p)}catch(n){y.fail("Feature generation failed"),v(`${n}`),process.exit(1)}})},xp=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))},Pp=(e,t)=>{let r=Or.join(t,e.featureName);l(M.green(`
1140
+ `));let i=Br();y.start("Detecting project setup...");let{detectProjectSetup:o}=await Promise.resolve().then(()=>(H(),qe)),s=await o(n);y.succeed("Project setup detected"),l(M.dim(` Redux: ${s.hasRedux?"\u2713":"\u2717"}`)),l(M.dim(` HTTP Client: ${s.httpClient}`)),l(M.dim(` i18n: ${s.hasI18n?"\u2713":"\u2717"}
1141
+ `));let a=await os(t,s.hasRedux,s.httpClient,r.skipStore,r.store,r.skipService,r.service),p=r.path||Vr.join("src","features"),u=Vr.join(n,p,a.featureName);await le(n,a.featureName,p)&&(v(`Feature '${a.featureName}' already exists at ${p}!`),process.exit(1)),await be(i.slice(1),{projectPath:n,spinner:y,featureName:a.featureName,basePath:p,featurePath:u,createStore:a.createStore,persistStore:a.persistStore,createService:a.createService,httpClient:a.selectedHttpClient,detection:s}),yl(a,p)}catch(n){y.fail("Feature generation failed"),v(`${n}`),process.exit(1)}})},hl=e=>{e.store&&!["persist","no-persist"].includes(e.store)&&(v("Invalid --store option. Use: persist or no-persist"),process.exit(1)),e.service&&!["axios","fetch"].includes(e.service)&&(v("Invalid --service option. Use: axios or fetch"),process.exit(1)),e.skipStore&&e.store&&(v("Cannot use --skip-store and --store together"),process.exit(1)),e.skipService&&e.service&&(v("Cannot use --skip-service and --service together"),process.exit(1))},yl=(e,t)=>{let r=Vr.join(t,e.featureName);l(M.green(`
1000
1142
  \u2728 Feature '${e.featureName}' created successfully!
1001
1143
  `)),l(M.dim("Generated files:")),l(M.dim(` \u{1F4C2} ${r}/`)),l(M.dim(" \u251C\u2500\u2500 components/")),l(M.dim(" \u251C\u2500\u2500 hooks/")),l(M.dim(" \u251C\u2500\u2500 types/")),e.createStore&&l(M.dim(" \u251C\u2500\u2500 store/")),e.createService&&l(M.dim(" \u251C\u2500\u2500 services/")),l(M.dim(` \u2514\u2500\u2500 index.ts
1002
- `)),l(M.cyan("Next steps:"));let n=t.replace(/^src\//,"@/");l(M.dim(` 1. Import and use the feature: import { ${e.featureName} } from '${n}/${e.featureName}'`)),e.createStore&&l(M.dim(` 2. Customize your Redux slice in: ${r}/store/`)),e.createService&&l(M.dim(` 3. Add API methods in: ${r}/services/${e.featureName}.service.ts`)),l("")};import Fr from"node:path";import Oe from"picocolors";G();import vp from"enquirer";var{prompt:wp}=vp,$i=async e=>e?{hookName:e}:await wp({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 Ii=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(Oe.cyan(`
1144
+ `)),l(M.cyan("Next steps:"));let n=t.replace(/^src\//,"@/");l(M.dim(` 1. Import and use the feature: import { ${e.featureName} } from '${n}/${e.featureName}'`)),e.createStore&&l(M.dim(` 2. Customize your Redux slice in: ${r}/store/`)),e.createService&&l(M.dim(` 3. Add API methods in: ${r}/services/${e.featureName}.service.ts`)),l("")};import Wr from"node:path";import De from"picocolors";H();import xl from"enquirer";var{prompt:Pl}=xl,as=async e=>e?{hookName:e}:await Pl({type:"input",name:"hookName",message:'Hook name (kebab-case, without "use" prefix):',validate:r=>r?/^[a-z][a-z0-9-]*$/.test(r)?!0:"Use lowercase letters, numbers, and hyphens only":"Hook name is required"});var cs=e=>{e.command("hook [name]").description("Generate a custom React hook").option("--client","Add 'use client' directive (default: true)",!0).option("--feature <path>","Generate in feature directory (e.g., src/features/auth)").option("--test","Also generate a sibling test file").option("--no-test","Skip test file generation").action(async(t,r)=>{try{let n=process.cwd();l(De.cyan(`
1003
1145
  \u{1FA9D} Hook Generator
1004
- `));let o=await A(n),i=await $i(t),a=`use${R(i.hookName)}`,p=Sp(r,o.hasTests);y.start("Generating hook..."),await Kt({name:i.hookName,projectPath:n,isClient:r.client??!0,featurePath:r.feature}),y.succeed("Hook generated");let u=r.feature?Fr.join(n,r.feature,"hooks",`${a}.ts`):Fr.join(n,"src/hooks",`${a}.ts`),d=null;p&&(y.start("Generating test..."),d=await ie({projectPath:n,sourceFile:u,kind:"hook",symbolName:a,hookUsesStore:o.hasRedux&&!!r.feature}),y.succeed("Test generated"));let h=r.feature?`${r.feature}/hooks/${a}.ts`:`src/hooks/${a}.ts`;l(Oe.green(`
1146
+ `));let i=await F(n),o=await as(t),a=`use${R(o.hookName)}`,p=wl(r,i.hasTests);y.start("Generating hook..."),await pr({name:o.hookName,projectPath:n,isClient:r.client??!0,featurePath:r.feature}),y.succeed("Hook generated");let u=r.feature?Wr.join(n,r.feature,"hooks",`${a}.ts`):Wr.join(n,"src/hooks",`${a}.ts`),d=null;p&&(y.start("Generating test..."),d=await oe({projectPath:n,sourceFile:u,kind:"hook",symbolName:a,hookUsesStore:i.hasRedux&&!!r.feature}),y.succeed("Test generated"));let h=r.feature?`${r.feature}/hooks/${a}.ts`:`src/hooks/${a}.ts`;l(De.green(`
1005
1147
  \u2728 Hook '${a}' created successfully!
1006
- `)),l(Oe.dim(` \u{1F4C4} ${h}`)),d&&l(Oe.dim(` \u{1F9EA} ${Fr.relative(n,d)}`)),l(""),l(Oe.cyan("Usage:"));let x=r.feature?`${r.feature.replace(/^src\//,"@/")}/hooks/${a}`:`@/hooks/${a}`;l(Oe.dim(` import { ${a} } from '${x}';`)),l("")}catch(n){y.fail("Hook generation failed"),v(`${n}`),process.exit(1)}})},Sp=(e,t)=>e.noTest?!1:e.test?!0:t;import Nt from"picocolors";G();var Ni=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(Nt.cyan(`
1148
+ `)),l(De.dim(` \u{1F4C4} ${h}`)),d&&l(De.dim(` \u{1F9EA} ${Wr.relative(n,d)}`)),l(""),l(De.cyan("Usage:"));let x=r.feature?`${r.feature.replace(/^src\//,"@/")}/hooks/${a}`:`@/hooks/${a}`;l(De.dim(` import { ${a} } from '${x}';`)),l("")}catch(n){y.fail("Hook generation failed"),v(`${n}`),process.exit(1)}})},wl=(e,t)=>e.noTest?!1:e.test?!0:t;import Gt from"picocolors";H();var ps=e=>{e.command("layout <segment>").description("Generate a nested layout.tsx (locale-aware when i18n is detected)").option("--group","Treat the segment as a route group (wraps it in parens)").option("--at <path>","Place the layout under this nested path (kebab-case, slash-separated)").option("--no-locale","Skip the locale wrapper even if i18n is detected").action(async(t,r)=>{try{let n=process.cwd();l(Gt.cyan(`
1007
1149
  \u{1F4D0} Layout Generator
1008
- `)),y.start("Detecting project setup...");let o=await A(n);y.succeed("Project setup detected");let i=o.hasI18n&&r.locale!==!1;l(Nt.dim(` i18n: ${i?"\u2713":"\u2717"}
1009
- `)),y.start("Generating layout...");let s=await Zt({segment:t,at:r.at,projectPath:n,hasI18n:i,withGroup:!!r.group});y.succeed("Layout generated"),l(Nt.green(`
1150
+ `)),y.start("Detecting project setup...");let i=await F(n);y.succeed("Project setup detected");let o=i.hasI18n&&r.locale!==!1;l(Gt.dim(` i18n: ${o?"\u2713":"\u2717"}
1151
+ `)),y.start("Generating layout...");let s=await lr({segment:t,at:r.at,projectPath:n,hasI18n:o,withGroup:!!r.group});y.succeed("Layout generated"),l(Gt.green(`
1010
1152
  \u2728 ${s.componentName} created!
1011
- `)),l(Nt.dim(` \u{1F4C4} ${s.displayPath}`)),l("")}catch(n){y.fail("Layout generation failed"),v(`${n instanceof Error?n.message:n}`),process.exit(1)}})};import Ep from"node:path";import ne from"picocolors";P();G();import Cp from"enquirer";var{prompt:Tp}=Cp,ki=async(e,t={})=>{let r=[];e||r.push({type:"input",name:"code",message:"Locale code (e.g., es, fr, de):",validate:o=>o?/^[a-z]{2}(-[A-Z]{2})?$/.test(o)?!0:"Use format: xx or xx-XX (e.g., es, pt-BR)":"Locale code is required"}),r.push({type:"input",name:"name",message:"Language name (e.g., Spanish, French):",validate:o=>o?!0:"Language name is required"},{type:"input",name:"country",message:"Country (e.g., Spain, France):",validate:o=>o?!0:"Country is required"},{type:"input",name:"flag",message:"Flag emoji (e.g., \u{1F1EA}\u{1F1F8}, \u{1F1EB}\u{1F1F7}):",validate:o=>o?!0:"Flag emoji is required"}),t.copyTranslations===void 0&&r.push({type:"confirm",name:"copyTranslations",message:"Copy translations from English? (No = empty values)",initial:!1});let n=await Tp(r);return{code:e??n.code,name:n.name,country:n.country,flag:n.flag,copyTranslations:t.copyTranslations??n.copyTranslations??!1}};var Ai=e=>{e.command("locale [code]").description("Add a new locale/language").option("--copy-translations","Copy translations from English instead of empty values").action(async(t,r)=>{try{let n=process.cwd();l(ne.cyan(`
1153
+ `)),l(Gt.dim(` \u{1F4C4} ${s.displayPath}`)),l("")}catch(n){y.fail("Layout generation failed"),v(`${n instanceof Error?n.message:n}`),process.exit(1)}})};import Cl from"node:path";import ne from"picocolors";P();H();import vl from"enquirer";var{prompt:Sl}=vl,ls=async(e,t={})=>{let r=[];e||r.push({type:"input",name:"code",message:"Locale code (e.g., es, fr, de):",validate:i=>i?/^[a-z]{2}(-[A-Z]{2})?$/.test(i)?!0:"Use format: xx or xx-XX (e.g., es, pt-BR)":"Locale code is required"}),r.push({type:"input",name:"name",message:"Language name (e.g., Spanish, French):",validate:i=>i?!0:"Language name is required"},{type:"input",name:"country",message:"Country (e.g., Spain, France):",validate:i=>i?!0:"Country is required"},{type:"input",name:"flag",message:"Flag emoji (e.g., \u{1F1EA}\u{1F1F8}, \u{1F1EB}\u{1F1F7}):",validate:i=>i?!0:"Flag emoji is required"}),t.copyTranslations===void 0&&r.push({type:"confirm",name:"copyTranslations",message:"Copy translations from English? (No = empty values)",initial:!1});let n=await Sl(r);return{code:e??n.code,name:n.name,country:n.country,flag:n.flag,copyTranslations:t.copyTranslations??n.copyTranslations??!1}};var ms=e=>{e.command("locale [code]").description("Add a new locale/language").option("--copy-translations","Copy translations from English instead of empty values").action(async(t,r)=>{try{let n=process.cwd();l(ne.cyan(`
1012
1154
  \u{1F30D} Locale Generator
1013
- `)),y.start("Detecting project setup...");let o=await A(n);y.succeed("Project setup detected"),o.hasI18n||(y.fail("i18n is not set up in this project"),v("Please set up internationalization first"),l(ne.dim(`
1155
+ `)),y.start("Detecting project setup...");let i=await F(n);y.succeed("Project setup detected"),i.hasI18n||(y.fail("i18n is not set up in this project"),v("Please set up internationalization first"),l(ne.dim(`
1014
1156
  Run: npx @teispace/next-maker setup --i18n
1015
- `)),process.exit(1));let i=await ki(t,{copyTranslations:r.copyTranslations}),s=Ep.join(n,"src","i18n","translations",`${i.code}.json`);m(s)&&(v(`Locale '${i.code}' already exists!`),process.exit(1)),y.start("Adding locale..."),await Qt({...i,projectPath:n}),y.succeed("Locale added"),l(ne.green(`
1016
- \u2728 Locale '${i.code}' (${i.name}) added successfully!
1017
- `)),l(ne.dim("Updated files:")),l(ne.dim(` \u{1F4C4} src/i18n/translations/${i.code}.json`)),l(ne.dim(" \u{1F4DD} src/types/i18n.ts (SupportedLocale type)")),l(ne.dim(" \u{1F4DD} src/lib/config/app-locales.ts")),l(""),l(ne.cyan("Next steps:")),l(ne.dim(` 1. Translate: src/i18n/translations/${i.code}.json`)),l(ne.dim(` 2. Visit: http://localhost:3000/${i.code}`)),l("")}catch(n){y.fail("Locale generation failed"),v(`${n}`),process.exit(1)}})};import Fi from"node:path";import K from"picocolors";G();import bp from"enquirer";var{prompt:Rp}=bp,Oi=async(e,t={})=>{let r=[];e||r.push({type:"input",name:"pageName",message:"Page name (kebab-case):",validate:o=>o?/^[a-z][a-z0-9-]*$/.test(o)?!0:"Use lowercase letters, numbers, and hyphens only":"Page name is required"}),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 Rp(r):{};return{pageName:e??n.pageName,withLoading:t.loading??n.withLoading??!0,withError:t.error??n.withError??!0}};var _i=e=>{e.command("page [name]").description("Generate a new page/route").option("--dynamic <param>","Create dynamic route with parameter (e.g., id)").option("--loading","Generate loading.tsx").option("--error","Generate error.tsx").action(async(t,r)=>{try{let n=process.cwd();l(K.cyan(`
1157
+ `)),process.exit(1));let o=await ls(t,{copyTranslations:r.copyTranslations}),s=Cl.join(n,"src","i18n","translations",`${o.code}.json`);m(s)&&(v(`Locale '${o.code}' already exists!`),process.exit(1)),y.start("Adding locale..."),await mr({...o,projectPath:n}),y.succeed("Locale added"),l(ne.green(`
1158
+ \u2728 Locale '${o.code}' (${o.name}) added successfully!
1159
+ `)),l(ne.dim("Updated files:")),l(ne.dim(` \u{1F4C4} src/i18n/translations/${o.code}.json`)),l(ne.dim(" \u{1F4DD} src/types/i18n.ts (SupportedLocale type)")),l(ne.dim(" \u{1F4DD} src/lib/config/app-locales.ts")),l(""),l(ne.cyan("Next steps:")),l(ne.dim(` 1. Translate: src/i18n/translations/${o.code}.json`)),l(ne.dim(` 2. Visit: http://localhost:3000/${o.code}`)),l("")}catch(n){y.fail("Locale generation failed"),v(`${n}`),process.exit(1)}})};import us from"node:path";import K from"picocolors";H();import El from"enquirer";var{prompt:Tl}=El,ds=async(e,t={})=>{let r=[];e||r.push({type:"input",name:"pageName",message:"Page name (kebab-case):",validate:i=>i?/^[a-z][a-z0-9-]*$/.test(i)?!0:"Use lowercase letters, numbers, and hyphens only":"Page name is required"}),t.loading===void 0&&r.push({type:"confirm",name:"withLoading",message:"Generate loading.tsx?",initial:!0}),t.error===void 0&&r.push({type:"confirm",name:"withError",message:"Generate error.tsx?",initial:!0});let n=r.length>0?await Tl(r):{};return{pageName:e??n.pageName,withLoading:t.loading??n.withLoading??!0,withError:t.error??n.withError??!0}};var fs=e=>{e.command("page [name]").description("Generate a new page/route").option("--dynamic <param>","Create dynamic route with parameter (e.g., id)").option("--loading","Generate loading.tsx").option("--error","Generate error.tsx").action(async(t,r)=>{try{let n=process.cwd();l(K.cyan(`
1018
1160
  \u{1F4C4} Page Generator
1019
- `)),y.start("Detecting project setup...");let o=await A(n);y.succeed("Project setup detected"),l(K.dim(` i18n: ${o.hasI18n?"\u2713":"\u2717"}
1020
- `));let i=await Oi(t,{loading:r.loading,error:r.error}),s=i.pageName,a=R(s),p=o.hasI18n?"src/app/[locale]":"src/app";await le(n,s,p)&&(v(`Page '${s}' already exists at ${p}/${s}!`),process.exit(1)),y.start("Generating page files..."),await tr({name:s,projectPath:n,hasI18n:o.hasI18n,dynamic:r.dynamic,withLoading:r.loading??i.withLoading,withError:r.error??i.withError}),y.succeed("Page files generated"),y.start("Registering route...");let d=r.dynamic?`/${s}/[${r.dynamic}]`:`/${s}`;await Rr(n,s,d),y.succeed("Route registered"),o.hasI18n&&(y.start("Adding translation namespace..."),await Ir(n,a),y.succeed("Translation namespace added"));let h=r.dynamic?Fi.join(p,s,`[${r.dynamic}]`):Fi.join(p,s);l(K.green(`
1161
+ `)),y.start("Detecting project setup...");let i=await F(n);y.succeed("Project setup detected"),l(K.dim(` i18n: ${i.hasI18n?"\u2713":"\u2717"}
1162
+ `));let o=await ds(t,{loading:r.loading,error:r.error}),s=o.pageName,a=R(s),p=i.hasI18n?"src/app/[locale]":"src/app";await le(n,s,p)&&(v(`Page '${s}' already exists at ${p}/${s}!`),process.exit(1)),y.start("Generating page files..."),await ur({name:s,projectPath:n,hasI18n:i.hasI18n,dynamic:r.dynamic,withLoading:r.loading??o.withLoading,withError:r.error??o.withError}),y.succeed("Page files generated"),y.start("Registering route...");let d=r.dynamic?`/${s}/[${r.dynamic}]`:`/${s}`;await Gr(n,s,d),y.succeed("Route registered"),i.hasI18n&&(y.start("Adding translation namespace..."),await Ur(n,a),y.succeed("Translation namespace added"));let h=r.dynamic?us.join(p,s,`[${r.dynamic}]`):us.join(p,s);l(K.green(`
1021
1163
  \u2728 Page '${s}' created successfully!
1022
- `)),l(K.dim("Generated files:")),l(K.dim(` \u{1F4C2} ${h}/`)),l(K.dim(" \u251C\u2500\u2500 page.tsx")),(r.loading??i.withLoading)&&l(K.dim(" \u251C\u2500\u2500 loading.tsx")),(r.error??i.withError)&&l(K.dim(" \u2514\u2500\u2500 error.tsx")),l(""),o.hasI18n&&(l(K.cyan("Next steps:")),l(K.dim(` 1. Add translations in: src/i18n/translations/en.json \u2192 "${a}"`)),l(K.dim(` 2. Visit: http://localhost:3000/${s}`)),l(""))}catch(n){y.fail("Page generation failed"),v(`${n}`),process.exit(1)}})};import _r from"node:path";import fe from"picocolors";var ji=e=>{e.command("provider <name>").description("Generate a context provider in src/providers/ and wire it into RootProvider").action(async t=>{try{let r=process.cwd();l(fe.cyan(`
1164
+ `)),l(K.dim("Generated files:")),l(K.dim(` \u{1F4C2} ${h}/`)),l(K.dim(" \u251C\u2500\u2500 page.tsx")),(r.loading??o.withLoading)&&l(K.dim(" \u251C\u2500\u2500 loading.tsx")),(r.error??o.withError)&&l(K.dim(" \u2514\u2500\u2500 error.tsx")),l(""),i.hasI18n&&(l(K.cyan("Next steps:")),l(K.dim(` 1. Add translations in: src/i18n/translations/en.json \u2192 "${a}"`)),l(K.dim(` 2. Visit: http://localhost:3000/${s}`)),l(""))}catch(n){y.fail("Page generation failed"),v(`${n}`),process.exit(1)}})};import qr from"node:path";import fe from"picocolors";var gs=e=>{e.command("provider <name>").description("Generate a context provider in src/providers/ and wire it into RootProvider").action(async t=>{try{let r=process.cwd();l(fe.cyan(`
1023
1165
  \u{1F50C} Provider Generator
1024
- `)),y.start("Generating provider...");let{componentName:n,fileBaseName:o,providerFile:i}=await nr({name:t,projectPath:r});y.succeed("Provider generated"),y.start("Registering provider in RootProvider and barrel...");let{rootProviderFile:s,barrelFile:a}=await $r({projectPath:r,componentName:n,fileBaseName:o});y.succeed("Provider registered"),l(fe.green(`
1166
+ `)),y.start("Generating provider...");let{componentName:n,fileBaseName:i,providerFile:o}=await gr({name:t,projectPath:r});y.succeed("Provider generated"),y.start("Registering provider in RootProvider and barrel...");let{rootProviderFile:s,barrelFile:a}=await Hr({projectPath:r,componentName:n,fileBaseName:i});y.succeed("Provider registered"),l(fe.green(`
1025
1167
  \u2728 ${n} created!
1026
- `)),l(fe.dim("Generated files:")),l(fe.dim(` \u{1F4C4} ${_r.relative(r,i)}`)),s?l(fe.dim(` \u270F\uFE0F ${_r.relative(r,s)} \u2014 wrapped {children}`)):(l(fe.yellow(`
1027
- \u26A0\uFE0F Could not locate a RootProvider file. Wire the new provider manually:`)),l(fe.dim(` <${n}>{children}</${n}>`))),a&&l(fe.dim(` \u270F\uFE0F ${_r.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 $p from"enquirer";import H from"picocolors";var{prompt:Ip}=$p,Np=e=>{let t=[];for(let r of e.filesRemoved)t.push(` ${H.red("-")} delete: ${r}`);for(let r of e.blocksStripped)t.push(` ${H.red("-")} strip block: ${r.description} ${H.dim(`(${r.file})`)}`);for(let r of e.scriptsRemoved)t.push(` ${H.red("-")} remove script: ${r}`);for(let r of e.packagesUninstalled)t.push(` ${H.red("-")} uninstall: ${r}`);for(let r of e.manualCleanup)t.push(` ${H.yellow("?")} manual cleanup: ${r.description} ${H.dim(`(${r.file})`)}`);return t},kp=e=>e.filesRemoved.length===0&&e.blocksStripped.length===0&&e.scriptsRemoved.length===0&&e.packagesUninstalled.length===0&&e.manualCleanup.length===0,Di=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(),o=Yo(t);if(!o)throw new Error(`Unknown feature "${t}". Valid: ${Se.map(p=>p.id).join(", ")}.`);if(l(H.cyan(`
1028
- \u{1F5D1} Remove ${o.name}
1029
- `)),!(await nt(o,n)).installed){l(H.dim(`${o.name} is not installed \u2014 nothing to remove.`));return}y.start("Computing changes...");let s=await Et(o,n,{dryRun:!0});if(y.succeed("Computed plan"),kp(s)){l(H.yellow(`
1168
+ `)),l(fe.dim("Generated files:")),l(fe.dim(` \u{1F4C4} ${qr.relative(r,o)}`)),s?l(fe.dim(` \u270F\uFE0F ${qr.relative(r,s)} \u2014 wrapped {children}`)):(l(fe.yellow(`
1169
+ \u26A0\uFE0F Could not locate a RootProvider file. Wire the new provider manually:`)),l(fe.dim(` <${n}>{children}</${n}>`))),a&&l(fe.dim(` \u270F\uFE0F ${qr.relative(r,a)} \u2014 added re-export`)),l("")}catch(r){y.fail("Provider generation failed"),v(`${r instanceof Error?r.message:r}`),process.exit(1)}})};import bl from"enquirer";import U from"picocolors";var{prompt:Rl}=bl,$l=e=>{let t=[];for(let r of e.filesRemoved)t.push(` ${U.red("-")} delete: ${r}`);for(let r of e.blocksStripped)t.push(` ${U.red("-")} strip block: ${r.description} ${U.dim(`(${r.file})`)}`);for(let r of e.scriptsRemoved)t.push(` ${U.red("-")} remove script: ${r}`);for(let r of e.packagesUninstalled)t.push(` ${U.red("-")} uninstall: ${r}`);for(let r of e.manualCleanup)t.push(` ${U.yellow("?")} manual cleanup: ${r.description} ${U.dim(`(${r.file})`)}`);return t},Il=e=>e.filesRemoved.length===0&&e.blocksStripped.length===0&&e.scriptsRemoved.length===0&&e.packagesUninstalled.length===0&&e.manualCleanup.length===0,hs=e=>{e.command("remove <feature>").alias("uninstall").description("Reverse a feature install (uses the feature manifest)").option("-y, --yes","Skip confirmation prompt").option("--dry-run","Show what would change without writing").action(async(t,r)=>{try{let n=process.cwd(),i=Io(t);if(!i)throw new Error(`Unknown feature "${t}". Valid: ${Ce.map(p=>p.id).join(", ")}.`);if(l(U.cyan(`
1170
+ \u{1F5D1} Remove ${i.name}
1171
+ `)),!(await ht(i,n)).installed){l(U.dim(`${i.name} is not installed \u2014 nothing to remove.`));return}y.start("Computing changes...");let s=await Ft(i,n,{dryRun:!0});if(y.succeed("Computed plan"),Il(s)){l(U.yellow(`
1030
1172
  \u26A0\uFE0F Manifest had no removable artifacts. Nothing to do.
1031
- `));return}l(H.bold(`
1173
+ `));return}l(U.bold(`
1032
1174
  Planned changes:
1033
- `));for(let p of Np(s))l(p);if(l(""),r.dryRun){l(H.dim(`--dry-run set \u2014 exiting without writing.
1034
- `));return}if(!r.yes){let{confirm:p}=await Ip({type:"confirm",name:"confirm",message:`Apply the changes above to remove ${o.name}?`,initial:!1});if(!p){l(H.yellow(`
1175
+ `));for(let p of $l(s))l(p);if(l(""),r.dryRun){l(U.dim(`--dry-run set \u2014 exiting without writing.
1176
+ `));return}if(!r.yes){let{confirm:p}=await Rl({type:"confirm",name:"confirm",message:`Apply the changes above to remove ${i.name}?`,initial:!1});if(!p){l(U.yellow(`
1035
1177
  Aborted.
1036
- `));return}}y.start(`Removing ${o.name}...`);let a=o.remove?(await o.remove(n),s):await Et(o,n);if(y.succeed(`${o.name} removed`),l(H.green(`
1037
- \u2713 ${o.name} removed.`)),a.manualCleanup.length>0){l(H.yellow(`
1038
- \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 _p}from"node:fs";import{mkdir as jp}from"node:fs/promises";import pt from"node:path";import Z from"picocolors";G();import{readFile as Ap,writeFile as Op}from"node:fs/promises";import Fp from"node:path";var Li=async(e,t)=>{let r=O(t),n=Fp.join(e,"src","lib","config","app-apis.ts");try{let o=await Ap(n,"utf-8");if(o.includes(`${r}:`))return;if(!o.match(/export const AppApis = \{[\s\S]*?\} as const;/))throw new Error("Could not find AppApis object in app-apis.ts");let i=Tn({camelName:r,kebabName:t});o=st(o,i),await Op(n,o)}catch(o){throw new Error(`Failed to register CRUD API endpoints: ${o}`,{cause:o})}};import Mi from"enquirer";var Gi=async(e,t,r,n)=>{let o=e||(await Mi.prompt({type:"input",name:"serviceName",message:"Service name (kebab-case):",validate:s=>s?/^[a-z0-9-]+$/.test(s)?!0:"Service name must be lowercase with hyphens only":"Service name is required"})).serviceName,i;return t!==void 0?i="axios":r!==void 0?i="fetch":n==="axios"?i="axios":n==="fetch"?i="fetch":n==="both"?i=(await Mi.prompt({type:"select",name:"httpClient",message:"Choose HTTP client:",choices:["axios","fetch"]})).httpClient:i="axios",{serviceName:o,httpClient:i}};var Hi=e=>{e.command("service [name]").description("Generate an API service").option("--path <path>","Custom path for service generation (default: create new feature)").option("--axios","Use Axios HTTP client").option("--fetch","Use Fetch HTTP client").option("--crud","Generate full CRUD service (getAll, getById, create, update, delete)").action(async(t,r)=>{try{let n=process.cwd();r.axios&&r.fetch&&(v("Cannot use --axios and --fetch together"),process.exit(1)),l(Z.cyan(`
1178
+ `));return}}y.start(`Removing ${i.name}...`);let a=i.remove?(await i.remove(n),s):await Ft(i,n);if(y.succeed(`${i.name} removed`),l(U.green(`
1179
+ \u2713 ${i.name} removed.`)),a.manualCleanup.length>0){l(U.yellow(`
1180
+ \u26A0\uFE0F Manual cleanup still required:`));for(let p of a.manualCleanup)l(` - ${p.description} (${p.file})`)}l("")}catch(n){y.fail("Remove failed"),v(`${n instanceof Error?n.message:n}`),process.exit(1)}})};import{existsSync as _l}from"node:fs";import{mkdir as Ol}from"node:fs/promises";import Pt from"node:path";import Z from"picocolors";H();import{readFile as Nl,writeFile as kl}from"node:fs/promises";import Al from"node:path";var ys=async(e,t)=>{let r=j(t),n=Al.join(e,"src","lib","config","app-apis.ts");try{let i=await Nl(n,"utf-8");if(i.includes(`${r}:`))return;if(!i.match(/export const AppApis = \{[\s\S]*?\} as const;/))throw new Error("Could not find AppApis object in app-apis.ts");let o=Xn({camelName:r,kebabName:t});i=ze(i,o),await kl(n,i)}catch(i){throw new Error(`Failed to register CRUD API endpoints: ${i}`,{cause:i})}};import xs from"enquirer";var Ps=async(e,t,r,n)=>{let i=e||(await xs.prompt({type:"input",name:"serviceName",message:"Service name (kebab-case):",validate:s=>s?/^[a-z0-9-]+$/.test(s)?!0:"Service name must be lowercase with hyphens only":"Service name is required"})).serviceName,o;return t!==void 0?o="axios":r!==void 0?o="fetch":n==="axios"?o="axios":n==="fetch"?o="fetch":n==="both"?o=(await xs.prompt({type:"select",name:"httpClient",message:"Choose HTTP client:",choices:["axios","fetch"]})).httpClient:o="axios",{serviceName:i,httpClient:o}};var ws=e=>{e.command("service [name]").description("Generate an API service").option("--path <path>","Custom path for service generation (default: create new feature)").option("--axios","Use Axios HTTP client").option("--fetch","Use Fetch HTTP client").option("--crud","Generate full CRUD service (getAll, getById, create, update, delete)").action(async(t,r)=>{try{let n=process.cwd();r.axios&&r.fetch&&(v("Cannot use --axios and --fetch together"),process.exit(1)),l(Z.cyan(`
1039
1181
  \u{1F527} Service Generator
1040
- `)),y.start("Detecting project setup...");let o=await A(n);y.succeed("Project setup detected"),o.httpClient==="none"&&(y.fail("No HTTP client is setup in this project"),v("Please setup either AxiosClient or FetchClient first"),l(Z.dim(`
1182
+ `)),y.start("Detecting project setup...");let i=await F(n);y.succeed("Project setup detected"),i.httpClient==="none"&&(y.fail("No HTTP client is setup in this project"),v("Please setup either AxiosClient or FetchClient first"),l(Z.dim(`
1041
1183
  Check: lib/utils/http/axios-client or lib/utils/http/fetch-client
1042
- `)),process.exit(1));let i=[];(o.httpClient==="axios"||o.httpClient==="both")&&i.push("Axios \u2713"),(o.httpClient==="fetch"||o.httpClient==="both")&&i.push("Fetch \u2713"),l(Z.dim(` HTTP Clients: ${i.join(", ")}
1043
- `));let s=await Gi(t,r.axios,r.fetch,o.httpClient),{basePath:a,servicePath:p}=Dp(n,s.serviceName,r.path);_p(p)||await jp(p,{recursive:!0}),gt(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 Xt({name:s.serviceName,outputPath:p,httpClient:s.httpClient}),y.succeed("CRUD service files generated"),y.start("Registering CRUD API endpoints..."),await Li(n,s.serviceName),y.succeed("CRUD API endpoints registered")):await Ee(kr(),{projectPath:n,spinner:y,serviceName:s.serviceName,servicePath:p,httpClient:s.httpClient}),Lp(s,a,!!r.crud)}catch(n){y.fail("Service generation failed"),v(`${n}`),process.exit(1)}})},Dp=(e,t,r)=>{let n;if(r){let o=r.replace(/^src\//,"");if(o.startsWith("features/")){let i=o.split("/")[1];n=pt.join("src","features",i,"services")}else n=pt.join("src",o)}else n=pt.join("src","features",t,"services");return{basePath:n,servicePath:pt.join(e,n)}},Lp=(e,t,r=!1)=>{let n=pt.join(t,`${e.serviceName}.service.ts`);l(Z.green(`
1184
+ `)),process.exit(1));let o=[];(i.httpClient==="axios"||i.httpClient==="both")&&o.push("Axios \u2713"),(i.httpClient==="fetch"||i.httpClient==="both")&&o.push("Fetch \u2713"),l(Z.dim(` HTTP Clients: ${o.join(", ")}
1185
+ `));let s=await Ps(t,r.axios,r.fetch,i.httpClient),{basePath:a,servicePath:p}=Fl(n,s.serviceName,r.path);_l(p)||await Ol(p,{recursive:!0}),Tt(n,a,`${s.serviceName}.service.ts`)&&(v(`Service '${s.serviceName}' already exists at ${a}!`),process.exit(1)),r.crud?(y.start("Generating CRUD service files..."),await sr({name:s.serviceName,outputPath:p,httpClient:s.httpClient}),y.succeed("CRUD service files generated"),y.start("Registering CRUD API endpoints..."),await ys(n,s.serviceName),y.succeed("CRUD API endpoints registered")):await be(zr(),{projectPath:n,spinner:y,serviceName:s.serviceName,servicePath:p,httpClient:s.httpClient}),jl(s,a,!!r.crud)}catch(n){y.fail("Service generation failed"),v(`${n}`),process.exit(1)}})},Fl=(e,t,r)=>{let n;if(r){let i=r.replace(/^src\//,"");if(i.startsWith("features/")){let o=i.split("/")[1];n=Pt.join("src","features",o,"services")}else n=Pt.join("src",i)}else n=Pt.join("src","features",t,"services");return{basePath:n,servicePath:Pt.join(e,n)}},jl=(e,t,r=!1)=>{let n=Pt.join(t,`${e.serviceName}.service.ts`);l(Z.green(`
1044
1186
  \u2728 ${r?"CRUD ":""}Service '${e.serviceName}' created successfully!
1045
1187
  `)),l(Z.dim("Generated files:")),l(Z.dim(` \u{1F4C4} ${n}
1046
- `)),l(Z.cyan("Next steps:"));let o=t.replace(/^src\//,"@/");l(Z.dim(` 1. Import service: import { ${e.serviceName}Service } from '${o}/${e.serviceName}.service'`)),r?(l(Z.dim(" 2. Available methods: getAll, getById, create, update, delete")),l(Z.dim(" 3. Update DTO types in the service file"))):l(Z.dim(` 2. Use in component: const data = await ${e.serviceName}Service.getAll()`)),l("")};import Mp from"enquirer";import jr from"picocolors";var{prompt:Gp}=Mp,Ui=e=>{e.command("setup").description("Setup features in an existing Next.js project").option("--http-client","Setup HTTP client (axios|fetch)").option("--dark-theme","Setup Dark Theme (Tailwind + @teispace/next-themes)").option("--redux","Setup Redux Toolkit").option("--i18n","Setup next-intl for internationalization").option("--tests","Setup testing (Vitest + React Testing Library)").option("--react-compiler","Enable the React Compiler").option("--bundle-analyzer","Add @next/bundle-analyzer").option("--security-headers","Add hardened HTTP headers to next.config.ts").option("--validate-scripts","Add scripts/sync-env.ts, scripts/check-deprecated.ts, and the validate chain").option("--commitizen","Add Commitizen with the conventional-changelog adapter").action(async t=>{try{if(l(jr.cyan(`
1188
+ `)),l(Z.cyan("Next steps:"));let i=t.replace(/^src\//,"@/");l(Z.dim(` 1. Import service: import { ${e.serviceName}Service } from '${i}/${e.serviceName}.service'`)),r?(l(Z.dim(" 2. Available methods: getAll, getById, create, update, delete")),l(Z.dim(" 3. Update DTO types in the service file"))):l(Z.dim(` 2. Use in component: const data = await ${e.serviceName}Service.getAll()`)),l("")};import Dl from"enquirer";import Xr from"picocolors";var{prompt:Ll}=Dl,vs=e=>{e.command("setup").description("Setup features in an existing Next.js project").option("--http-client","Setup HTTP client (axios|fetch)").option("--dark-theme","Setup Dark Theme (Tailwind + @teispace/next-themes)").option("--redux","Setup Redux Toolkit").option("--ws","Setup WebSocket client (socket.io-client + Redux bridge; requires --redux)").option("--i18n","Setup next-intl for internationalization").option("--tests","Setup testing (Vitest + React Testing Library)").option("--react-compiler","Enable the React Compiler").option("--bundle-analyzer","Add @next/bundle-analyzer").option("--security-headers","Add hardened HTTP headers to next.config.ts").option("--validate-scripts","Add scripts/sync-env.ts, scripts/check-deprecated.ts, and the validate chain").option("--commitizen","Add Commitizen with the conventional-changelog adapter").action(async t=>{try{if(l(Xr.cyan(`
1047
1189
  \u{1F527} Setup Wizard
1048
- `)),t.httpClient||t.darkTheme||t.redux||t.i18n||t.tests||t.reactCompiler||t.bundleAnalyzer||t.securityHeaders||t.validateScripts||t.commitizen){t.httpClient&&await Ye(process.cwd()),t.darkTheme&&await Xe(process.cwd()),t.redux&&await Qe(process.cwd()),t.i18n&&await Ke(process.cwd()),t.tests&&await tt(process.cwd()),t.reactCompiler&&await Ze(process.cwd()),t.bundleAnalyzer&&await Ve(process.cwd()),t.securityHeaders&&await et(process.cwd()),t.validateScripts&&await rt(process.cwd()),t.commitizen&&await Be(process.cwd());return}let o=(await Gp([{type:"select",name:"feature",message:"What would you like to setup?",choices:[{name:"Dark Theme",value:"dark-theme"},{name:"Redux Toolkit",value:"redux"},{name:"HTTP Client (Axios/Fetch)",value:"http-client"},{name:"Internationalization (next-intl)",value:"i18n"},{name:"Testing (Vitest + RTL)",value:"tests"},{name:"React Compiler",value:"react-compiler"},{name:"Bundle Analyzer",value:"bundle-analyzer"},{name:"Security Headers",value:"security-headers"},{name:"Validation Scripts",value:"validate-scripts"},{name:"Commitizen",value:"commitizen"},"Cancel"]}])).feature;if(o==="Cancel"){l(jr.yellow("Setup cancelled."));return}let s={"dark-theme":Xe,redux:Qe,"http-client":Ye,i18n:Ke,tests:tt,"react-compiler":Ze,"bundle-analyzer":Ve,"security-headers":et,"validate-scripts":rt,commitizen:Be}[o];s?await s(process.cwd()):l(jr.yellow(`
1049
- \u26A0\uFE0F ${o} setup is not implemented yet.`))}catch(r){y.fail("Setup failed"),v(`${r}`),process.exit(1)}})};import{existsSync as zp}from"node:fs";import{mkdir as Jp}from"node:fs/promises";import ge from"node:path";import U from"picocolors";G();import Hp from"enquirer";var{prompt:Up}=Hp,zi=async(e,t,r)=>{let n=[];e||n.push({type:"input",name:"sliceName",message:"What is the slice name?",initial:"my-slice",validate:i=>/^[a-z0-9-]+$/.test(i)?!0:"Slice name must be lowercase and contain only alphanumeric characters and hyphens."}),t===void 0&&r===void 0&&n.push({type:"confirm",name:"persistSlice",message:"Enable persistence for this slice?",initial:!1});let o=n.length>0?await Up(n):{};return{sliceName:e||o.sliceName,persistSlice:t===!0?!0:r===!1?!1:o.persistSlice||!1}};var Ji=e=>{e.command("slice [name]").description("Generate a Redux slice").option("--path <path>","Custom path for slice generation (default: create new feature)").option("--persist","Enable persistence for this slice").option("--no-persist","Disable persistence for this slice").option("--test","Also generate a sibling test file").option("--no-test","Skip test file generation").action(async(t,r)=>{try{let n=process.cwd();r.persist&&r.noPersist===!0&&(v("Cannot use --persist and --no-persist together"),process.exit(1)),l(U.cyan(`
1190
+ `)),t.httpClient||t.darkTheme||t.redux||t.ws||t.i18n||t.tests||t.reactCompiler||t.bundleAnalyzer||t.securityHeaders||t.validateScripts||t.commitizen){t.httpClient&&await at(process.cwd()),t.darkTheme&&await ot(process.cwd()),t.redux&&await lt(process.cwd()),t.ws&&await gt(process.cwd()),t.i18n&&await ct(process.cwd()),t.tests&&await dt(process.cwd()),t.reactCompiler&&await pt(process.cwd()),t.bundleAnalyzer&&await rt(process.cwd()),t.securityHeaders&&await mt(process.cwd()),t.validateScripts&&await ut(process.cwd()),t.commitizen&&await nt(process.cwd());return}let i=(await Ll([{type:"select",name:"feature",message:"What would you like to setup?",choices:[{name:"Dark Theme",value:"dark-theme"},{name:"Redux Toolkit",value:"redux"},{name:"WebSocket Client (requires Redux)",value:"ws"},{name:"HTTP Client (Axios/Fetch)",value:"http-client"},{name:"Internationalization (next-intl)",value:"i18n"},{name:"Testing (Vitest + RTL)",value:"tests"},{name:"React Compiler",value:"react-compiler"},{name:"Bundle Analyzer",value:"bundle-analyzer"},{name:"Security Headers",value:"security-headers"},{name:"Validation Scripts",value:"validate-scripts"},{name:"Commitizen",value:"commitizen"},"Cancel"]}])).feature;if(i==="Cancel"){l(Xr.yellow("Setup cancelled."));return}let s={"dark-theme":ot,redux:lt,ws:gt,"http-client":at,i18n:ct,tests:dt,"react-compiler":pt,"bundle-analyzer":rt,"security-headers":mt,"validate-scripts":ut,commitizen:nt}[i];s?await s(process.cwd()):l(Xr.yellow(`
1191
+ \u26A0\uFE0F ${i} setup is not implemented yet.`))}catch(r){y.fail("Setup failed"),v(`${r}`),process.exit(1)}})};import{existsSync as Hl}from"node:fs";import{mkdir as Ul}from"node:fs/promises";import ge from"node:path";import B from"picocolors";H();import Ml from"enquirer";var{prompt:Gl}=Ml,Ss=async(e,t,r)=>{let n=[];e||n.push({type:"input",name:"sliceName",message:"What is the slice name?",initial:"my-slice",validate:o=>/^[a-z0-9-]+$/.test(o)?!0:"Slice name must be lowercase and contain only alphanumeric characters and hyphens."}),t===void 0&&r===void 0&&n.push({type:"confirm",name:"persistSlice",message:"Enable persistence for this slice?",initial:!1});let i=n.length>0?await Gl(n):{};return{sliceName:e||i.sliceName,persistSlice:t===!0?!0:r===!1?!1:i.persistSlice||!1}};var Cs=e=>{e.command("slice [name]").description("Generate a Redux slice").option("--path <path>","Custom path for slice generation (default: create new feature)").option("--persist","Enable persistence for this slice").option("--no-persist","Disable persistence for this slice").option("--test","Also generate a sibling test file").option("--no-test","Skip test file generation").action(async(t,r)=>{try{let n=process.cwd();r.persist&&r.noPersist===!0&&(v("Cannot use --persist and --no-persist together"),process.exit(1)),l(B.cyan(`
1050
1192
  \u{1F527} Slice Generator
1051
- `)),y.start("Detecting project setup...");let o=await A(n);y.succeed("Project setup detected"),o.hasRedux||(y.fail("Redux is not setup in this project"),v("Please install @reduxjs/toolkit and react-redux first"),l(U.dim(`
1193
+ `)),y.start("Detecting project setup...");let i=await F(n);y.succeed("Project setup detected"),i.hasRedux||(y.fail("Redux is not setup in this project"),v("Please install @reduxjs/toolkit and react-redux first"),l(B.dim(`
1052
1194
  Run: npm install @reduxjs/toolkit react-redux
1053
- `)),process.exit(1)),l(U.dim(` Redux: \u2713
1054
- `));let i=await zi(t,r.persist,r.noPersist===!0?!1:void 0),{basePath:s,slicePath:a}=Vp(n,i.sliceName,r.path),p=ge.join(n,s);zp(p)||await Jp(p,{recursive:!0}),await le(n,i.sliceName,s)&&(v(`Slice '${i.sliceName}' already exists at ${s}!`),process.exit(1)),await Ee(Ar(),{projectPath:n,spinner:y,sliceName:i.sliceName,basePath:s,slicePath:a,persistSlice:i.persistSlice});let d=null;if(Bp(r,o.hasTests)){let x=ge.join(a,`${i.sliceName}.slice.ts`);y.start("Generating test..."),d=await ie({projectPath:n,sourceFile:x,kind:"slice",symbolName:O(i.sliceName)}),y.succeed("Test generated")}qp(i,s,d,n)}catch(n){y.fail("Slice generation failed"),v(`${n}`),process.exit(1)}})},Vp=(e,t,r)=>{let n;if(r){let o=r.replace(/^src\//,"");if(o.startsWith("features/")){let i=o.split("/")[1];n=ge.join("src","features",i,"store")}else n=ge.join("src",o)}else n=ge.join("src","features",t,"store");return{basePath:n,slicePath:ge.join(e,n,t)}},Bp=(e,t)=>e.noTest?!1:e.test?!0:t,qp=(e,t,r,n)=>{let o=ge.join(t,e.sliceName);l(U.green(`
1195
+ `)),process.exit(1)),l(B.dim(` Redux: \u2713
1196
+ `));let o=await Ss(t,r.persist,r.noPersist===!0?!1:void 0),{basePath:s,slicePath:a}=Bl(n,o.sliceName,r.path),p=ge.join(n,s);Hl(p)||await Ul(p,{recursive:!0}),await le(n,o.sliceName,s)&&(v(`Slice '${o.sliceName}' already exists at ${s}!`),process.exit(1)),await be(Jr(),{projectPath:n,spinner:y,sliceName:o.sliceName,basePath:s,slicePath:a,persistSlice:o.persistSlice});let d=null;if(zl(r,i.hasTests)){let x=ge.join(a,`${o.sliceName}.slice.ts`);y.start("Generating test..."),d=await oe({projectPath:n,sourceFile:x,kind:"slice",symbolName:j(o.sliceName)}),y.succeed("Test generated")}Jl(o,s,d,n)}catch(n){y.fail("Slice generation failed"),v(`${n}`),process.exit(1)}})},Bl=(e,t,r)=>{let n;if(r){let i=r.replace(/^src\//,"");if(i.startsWith("features/")){let o=i.split("/")[1];n=ge.join("src","features",o,"store")}else n=ge.join("src",i)}else n=ge.join("src","features",t,"store");return{basePath:n,slicePath:ge.join(e,n,t)}},zl=(e,t)=>e.noTest?!1:e.test?!0:t,Jl=(e,t,r,n)=>{let i=ge.join(t,e.sliceName);l(B.green(`
1055
1197
  \u2728 Slice '${e.sliceName}' created successfully!
1056
- `)),l(U.dim("Generated files:")),l(U.dim(` \u{1F4C2} ${o}/`)),l(U.dim(` \u251C\u2500\u2500 ${e.sliceName}.slice.ts`)),l(U.dim(` \u251C\u2500\u2500 ${e.sliceName}.selectors.ts`)),e.persistSlice&&l(U.dim(" \u251C\u2500\u2500 persist.ts")),l(U.dim(` \u251C\u2500\u2500 ${e.sliceName}.types.ts`)),l(U.dim(` \u2514\u2500\u2500 index.ts
1057
- `)),r&&l(U.dim(` \u{1F9EA} ${ge.relative(n,r)}
1058
- `)),l(U.cyan("Next steps:"));let i=t.replace(/^src\//,"@/");l(U.dim(` 1. Import actions: import { setLoading, setError } from '${i}/${e.sliceName}'`)),l(U.dim(" 2. Use in component: dispatch(setLoading(true))")),l("")};import Q from"node:path";import Dr from"picocolors";P();G();var Vi=e=>{e.command("test <file>").description(`Generate a sibling test file for an existing component, hook, or slice.
1059
- 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(),o=Q.isAbsolute(t)?t:Q.join(n,t);l(Dr.cyan(`
1198
+ `)),l(B.dim("Generated files:")),l(B.dim(` \u{1F4C2} ${i}/`)),l(B.dim(` \u251C\u2500\u2500 ${e.sliceName}.slice.ts`)),l(B.dim(` \u251C\u2500\u2500 ${e.sliceName}.selectors.ts`)),e.persistSlice&&l(B.dim(" \u251C\u2500\u2500 persist.ts")),l(B.dim(` \u251C\u2500\u2500 ${e.sliceName}.types.ts`)),l(B.dim(` \u2514\u2500\u2500 index.ts
1199
+ `)),r&&l(B.dim(` \u{1F9EA} ${ge.relative(n,r)}
1200
+ `)),l(B.cyan("Next steps:"));let o=t.replace(/^src\//,"@/");l(B.dim(` 1. Import actions: import { setLoading, setError } from '${o}/${e.sliceName}'`)),l(B.dim(" 2. Use in component: dispatch(setLoading(true))")),l("")};import Q from"node:path";import Yr from"picocolors";P();H();var Es=e=>{e.command("test <file>").description(`Generate a sibling test file for an existing component, hook, or slice.
1201
+ Infers the kind from filename/content; pass --kind to override.`).option("--kind <kind>","Override inferred kind: component | hook | slice").option("--force","Overwrite an existing test file").action(async(t,r)=>{try{let n=process.cwd(),i=Q.isAbsolute(t)?t:Q.join(n,t);l(Yr.cyan(`
1060
1202
  \u{1F9EA} Test Generator
1061
- `)),m(o)||(v(`Source file not found: ${t}`),process.exit(1));let i=await A(n);i.hasTests||(v("Testing is not installed in this project. Run `next-maker setup --tests` first."),process.exit(1));let s=await f(o),a=Xp(r.kind)??Wp(o,s);a||(v(`Could not infer test kind for ${Q.basename(o)}. Pass --kind component|hook|slice.`),process.exit(1));let p=Yp(o,a),u=Kp(o,a);m(u)&&!r.force&&(v(`Test file already exists: ${Q.relative(n,u)}. Use --force to overwrite.`),process.exit(1)),y.start(`Generating ${a} test...`);let d=await ie({projectPath:n,sourceFile:o,kind:a,symbolName:p,hasRedux:i.hasRedux,hasI18n:i.hasI18n,hookUsesStore:a==="hook"&&i.hasRedux&&s.includes("useAppSelector")});y.succeed("Test generated"),l(Dr.green(`
1203
+ `)),m(i)||(v(`Source file not found: ${t}`),process.exit(1));let o=await F(n);o.hasTests||(v("Testing is not installed in this project. Run `next-maker setup --tests` first."),process.exit(1));let s=await f(i),a=Vl(r.kind)??Wl(i,s);a||(v(`Could not infer test kind for ${Q.basename(i)}. Pass --kind component|hook|slice.`),process.exit(1));let p=ql(i,a),u=Xl(i,a);m(u)&&!r.force&&(v(`Test file already exists: ${Q.relative(n,u)}. Use --force to overwrite.`),process.exit(1)),y.start(`Generating ${a} test...`);let d=await oe({projectPath:n,sourceFile:i,kind:a,symbolName:p,hasRedux:o.hasRedux,hasI18n:o.hasI18n,hookUsesStore:a==="hook"&&o.hasRedux&&s.includes("useAppSelector")});y.succeed("Test generated"),l(Yr.green(`
1062
1204
  \u2728 Test '${Q.basename(d)}' created.
1063
- `)),l(Dr.dim(` \u{1F9EA} ${Q.relative(n,d)}`)),l("")}catch(n){y.fail("Test generation failed"),v(`${n}`),process.exit(1)}})},Xp=e=>{if(!e)return null;if(e==="component"||e==="hook"||e==="slice")return e;throw new Error(`Invalid --kind: ${e}. Use component | hook | slice.`)},Wp=(e,t)=>{let r=Q.basename(e);return/\.slice\.ts$/.test(r)?"slice":/^use[A-Z]/.test(r.replace(/\.tsx?$/,""))?"hook":r.endsWith(".tsx")?"component":/createSlice\s*\(/.test(t)?"slice":/^export\s+(const|function)\s+use[A-Z]/m.test(t)?"hook":null},Yp=(e,t)=>{let r=Q.basename(e).replace(/\.(tsx?|jsx?)$/i,"");return t==="slice"?O(r.replace(/\.slice$/,"")):t==="hook"?/^use[A-Z]/.test(r)?r:`use${R(r.replace(/^use-?/,""))}`:R(r)},Kp=(e,t)=>{let r=Q.dirname(e),n=Q.basename(e).replace(/\.(tsx?|jsx?)$/i,""),o=t==="component"?".tsx":".ts";return Q.join(r,`${n}.test${o}`)};var Bi=e=>{yn(e),Ui(e),Ri(e),Ji(e),Hi(e),_i(e),Ni(e),Xn(e),Ai(e),Ii(e),ji(e),ii(e),Si(e),Ko(e),Di(e),Vi(e)};var Qp=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 Qp.apply(process,arguments)};async function el(){Lr({logger:t=>lt(t)});let e=new Zp;e.name("next-maker").description("Teispace Next.js Project Generator").version("1.0.0"),Bi(e),e.parse()}el().catch(e=>{let t=e&&typeof e=="object"&&"message"in e?e.message:String(e);lt(`Unexpected error: ${t}`)});
1205
+ `)),l(Yr.dim(` \u{1F9EA} ${Q.relative(n,d)}`)),l("")}catch(n){y.fail("Test generation failed"),v(`${n}`),process.exit(1)}})},Vl=e=>{if(!e)return null;if(e==="component"||e==="hook"||e==="slice")return e;throw new Error(`Invalid --kind: ${e}. Use component | hook | slice.`)},Wl=(e,t)=>{let r=Q.basename(e);return/\.slice\.ts$/.test(r)?"slice":/^use[A-Z]/.test(r.replace(/\.tsx?$/,""))?"hook":r.endsWith(".tsx")?"component":/createSlice\s*\(/.test(t)?"slice":/^export\s+(const|function)\s+use[A-Z]/m.test(t)?"hook":null},ql=(e,t)=>{let r=Q.basename(e).replace(/\.(tsx?|jsx?)$/i,"");return t==="slice"?j(r.replace(/\.slice$/,"")):t==="hook"?/^use[A-Z]/.test(r)?r:`use${R(r.replace(/^use-?/,""))}`:R(r)},Xl=(e,t)=>{let r=Q.dirname(e),n=Q.basename(e).replace(/\.(tsx?|jsx?)$/i,""),i=t==="component"?".tsx":".ts";return Q.join(r,`${n}.test${i}`)};var Ts=e=>{Un(e),vs(e),ss(e),Cs(e),ws(e),fs(e),ps(e),Pi(e),ms(e),cs(e),gs(e),Lo(e),ts(e),No(e),hs(e),Es(e)};var Kl=process.emitWarning;process.emitWarning=function(e,t,r,n){if(!(typeof e=="string"&&e.includes("--localstorage-file")&&e.includes("was provided without a valid path")))return Kl.apply(process,arguments)};async function Zl(){Kr({logger:t=>wt(t)});let e=new Yl;e.name("next-maker").description("Teispace Next.js Project Generator").version("1.0.0"),Ts(e),e.parse()}Zl().catch(e=>{let t=e&&typeof e=="object"&&"message"in e?e.message:String(e);wt(`Unexpected error: ${t}`)});
1064
1206
  //# sourceMappingURL=index.js.map