@teispace/next-maker 1.15.1 → 1.16.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 (74) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +420 -281
  3. package/dist/index.js +400 -164
  4. package/dist/index.js.map +4 -4
  5. package/dist/src/commands/app.d.ts.map +1 -1
  6. package/dist/src/commands/doctor.d.ts +3 -0
  7. package/dist/src/commands/doctor.d.ts.map +1 -0
  8. package/dist/src/commands/env.d.ts +3 -0
  9. package/dist/src/commands/env.d.ts.map +1 -0
  10. package/dist/src/commands/index.d.ts.map +1 -1
  11. package/dist/src/commands/layout.d.ts +3 -0
  12. package/dist/src/commands/layout.d.ts.map +1 -0
  13. package/dist/src/commands/provider.d.ts +3 -0
  14. package/dist/src/commands/provider.d.ts.map +1 -0
  15. package/dist/src/commands/remove.d.ts +3 -0
  16. package/dist/src/commands/remove.d.ts.map +1 -0
  17. package/dist/src/commands/setup.d.ts.map +1 -1
  18. package/dist/src/generators/index.d.ts +4 -0
  19. package/dist/src/generators/index.d.ts.map +1 -1
  20. package/dist/src/generators/layout.generator.d.ts +22 -0
  21. package/dist/src/generators/layout.generator.d.ts.map +1 -0
  22. package/dist/src/generators/provider.generator.d.ts +14 -0
  23. package/dist/src/generators/provider.generator.d.ts.map +1 -0
  24. package/dist/src/generators/templates/layout.template.d.ts +13 -0
  25. package/dist/src/generators/templates/layout.template.d.ts.map +1 -0
  26. package/dist/src/generators/templates/provider.template.d.ts +12 -0
  27. package/dist/src/generators/templates/provider.template.d.ts.map +1 -0
  28. package/dist/src/manifests/bundle-analyzer.manifest.d.ts +3 -0
  29. package/dist/src/manifests/bundle-analyzer.manifest.d.ts.map +1 -0
  30. package/dist/src/manifests/commitizen.manifest.d.ts +3 -0
  31. package/dist/src/manifests/commitizen.manifest.d.ts.map +1 -0
  32. package/dist/src/manifests/dark-theme.manifest.d.ts +3 -0
  33. package/dist/src/manifests/dark-theme.manifest.d.ts.map +1 -0
  34. package/dist/src/manifests/http-client.manifest.d.ts +3 -0
  35. package/dist/src/manifests/http-client.manifest.d.ts.map +1 -0
  36. package/dist/src/manifests/i18n.manifest.d.ts +3 -0
  37. package/dist/src/manifests/i18n.manifest.d.ts.map +1 -0
  38. package/dist/src/manifests/index.d.ts +23 -0
  39. package/dist/src/manifests/index.d.ts.map +1 -0
  40. package/dist/src/manifests/react-compiler.manifest.d.ts +3 -0
  41. package/dist/src/manifests/react-compiler.manifest.d.ts.map +1 -0
  42. package/dist/src/manifests/redux.manifest.d.ts +9 -0
  43. package/dist/src/manifests/redux.manifest.d.ts.map +1 -0
  44. package/dist/src/manifests/runner.d.ts +37 -0
  45. package/dist/src/manifests/runner.d.ts.map +1 -0
  46. package/dist/src/manifests/security-headers.manifest.d.ts +3 -0
  47. package/dist/src/manifests/security-headers.manifest.d.ts.map +1 -0
  48. package/dist/src/manifests/tests.manifest.d.ts +3 -0
  49. package/dist/src/manifests/tests.manifest.d.ts.map +1 -0
  50. package/dist/src/manifests/types.d.ts +119 -0
  51. package/dist/src/manifests/types.d.ts.map +1 -0
  52. package/dist/src/manifests/validate-scripts.manifest.d.ts +3 -0
  53. package/dist/src/manifests/validate-scripts.manifest.d.ts.map +1 -0
  54. package/dist/src/modifiers/env-var.modifier.d.ts +60 -0
  55. package/dist/src/modifiers/env-var.modifier.d.ts.map +1 -0
  56. package/dist/src/modifiers/index.d.ts +2 -0
  57. package/dist/src/modifiers/index.d.ts.map +1 -1
  58. package/dist/src/modifiers/root-provider.modifier.d.ts +26 -0
  59. package/dist/src/modifiers/root-provider.modifier.d.ts.map +1 -0
  60. package/dist/src/services/setup/commitizen/index.d.ts +3 -0
  61. package/dist/src/services/setup/commitizen/index.d.ts.map +1 -0
  62. package/dist/src/services/setup/commitizen/package-modifier.d.ts +17 -0
  63. package/dist/src/services/setup/commitizen/package-modifier.d.ts.map +1 -0
  64. package/dist/src/services/setup/security-headers/headers.d.ts +29 -0
  65. package/dist/src/services/setup/security-headers/headers.d.ts.map +1 -0
  66. package/dist/src/services/setup/security-headers/index.d.ts +3 -0
  67. package/dist/src/services/setup/security-headers/index.d.ts.map +1 -0
  68. package/dist/src/services/setup/validate-scripts/index.d.ts +4 -0
  69. package/dist/src/services/setup/validate-scripts/index.d.ts.map +1 -0
  70. package/dist/src/services/setup/validate-scripts/package-modifier.d.ts +19 -0
  71. package/dist/src/services/setup/validate-scripts/package-modifier.d.ts.map +1 -0
  72. package/dist/src/services/setup/validate-scripts/scripts.d.ts +12 -0
  73. package/dist/src/services/setup/validate-scripts/scripts.d.ts.map +1 -0
  74. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
- var Yo=Object.defineProperty;var ue=(e,r)=>()=>(e&&(r=e(e=0)),r);var Ye=(e,r)=>{for(var t in r)Yo(e,t,{get:r[t],enumerable:!0})};import{existsSync as Ve}from"node:fs";import ce from"node:fs/promises";import zt from"node:path";var d,u,A,S,P,j,l,T=ue(()=>{"use strict";d=async e=>ce.readFile(e,"utf-8"),u=async(e,r)=>{await ce.mkdir(zt.dirname(e),{recursive:!0}),await ce.writeFile(e,r,"utf-8")},A=async(e,r)=>{await ce.mkdir(zt.dirname(r),{recursive:!0}),await ce.copyFile(e,r)},S=async e=>{Ve(e)&&await ce.unlink(e)},P=async e=>{Ve(e)&&await ce.rm(e,{recursive:!0,force:!0})},j=async(e,r)=>{let t=await d(e),o=JSON.parse(t),n=r(o);await u(e,JSON.stringify(n,null,2))},l=e=>Ve(e)});var Kt={};Ye(Kt,{PROJECT_PATHS:()=>a});var a,C=ue(()=>{"use strict";a={NEXT_CONFIG:"next.config.ts",POSTCSS_CONFIG:"postcss.config.mjs",BIOME_CONFIG:"biome.json",VITEST_CONFIG:"vitest.config.ts",TEST_DIR:"test",TS_CONFIG:"tsconfig.json",PACKAGE_JSON:"package.json",ENV_EXAMPLE:".env.example",GITIGNORE:".gitignore",README:"README.md",LICENSE:"LICENSE",CHANGELOG:"CHANGELOG.md",NVM_RC:".nvmrc",NPM_RC:".npmrc",AGENTS_MD:"AGENTS.md",CLAUDE_MD:"CLAUDE.md",SRC:"src",APP:"src/app",COMPONENTS:"src/components",LIB:"src/lib",PROVIDERS:"src/providers",STYLES:"src/styles",TYPES:"src/types",UTILS:"src/lib/utils",HOOKS:"src/hooks",SERVICES:"src/services",STORE:"src/store",I18N:"src/i18n",GLOBALS_CSS:"src/styles/globals.css",ROOT_LAYOUT:"src/app/layout.tsx",ROOT_PAGE:"src/app/page.tsx",ROOT_PROVIDER:"src/providers/RootProvider.tsx",PROVIDERS_INDEX:"src/providers/index.ts",COMPONENTS_INDEX:"src/components/index.ts",TYPES_INDEX:"src/types/index.ts",UTILS_INDEX:"src/lib/utils/index.ts",CONFIG_INDEX:"src/lib/config/index.ts",CONSTANTS:"src/lib/config/constants.ts",APP_LOCALES:"src/lib/config/app-locales.ts",MIDDLEWARE:"src/middleware.ts",PROXY:"src/proxy.ts",I18N_TYPES:"src/types/i18n.ts",HTTP_UTILS:"src/lib/utils/http",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",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 Qt={};Ye(Qt,{cleanupHttpTypes:()=>fe,isFileUsed:()=>Si,isStringUsed:()=>wi,migrateClientUsages:()=>rt,removeHttpExports:()=>ot,updateConfigIndex:()=>tt,updateHttpIndex:()=>Ze,updateTypesIndex:()=>et,updateUtilsIndex:()=>Qe});import{exec as Pi}from"node:child_process";import _ from"node:path";import{promisify as Ti}from"node:util";var qe,Ze,Qe,et,tt,fe,rt,ot,Si,wi,je=ue(()=>{"use strict";C();T();qe=Ti(Pi),Ze=async(e,r)=>{let t=_.join(e,a.HTTP_UTILS,"index.ts");if(l(t)){let o=await d(t);o=o.replace(/export .* from '\.\/axios-client';?\n?/g,""),o=o.replace(/export .* from '\.\/fetch-client';?\n?/g,""),r.includes("fetch")&&!o.includes("fetch-client")&&(o+=`export * from './fetch-client';
2
+ var ci=Object.defineProperty;var Pe=(e,r)=>()=>(e&&(r=e(e=0)),r);var vt=(e,r)=>{for(var t in r)ci(e,t,{get:r[t],enumerable:!0})};import{existsSync as St}from"node:fs";import de from"node:fs/promises";import wr from"node:path";var d,f,_,T,S,k,m,P=Pe(()=>{"use strict";d=async e=>de.readFile(e,"utf-8"),f=async(e,r)=>{await de.mkdir(wr.dirname(e),{recursive:!0}),await de.writeFile(e,r,"utf-8")},_=async(e,r)=>{await de.mkdir(wr.dirname(r),{recursive:!0}),await de.copyFile(e,r)},T=async e=>{St(e)&&await de.unlink(e)},S=async e=>{St(e)&&await de.rm(e,{recursive:!0,force:!0})},k=async(e,r)=>{let t=await d(e),o=JSON.parse(t),i=r(o);await f(e,JSON.stringify(i,null,2))},m=e=>St(e)});var br={};vt(br,{PROJECT_PATHS:()=>c});var c,w=Pe(()=>{"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",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",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 Ar={};vt(Ar,{cleanupHttpTypes:()=>ve,isFileUsed:()=>Fi,isStringUsed:()=>ji,migrateClientUsages:()=>Nt,removeHttpExports:()=>It,updateConfigIndex:()=>$t,updateHttpIndex:()=>Et,updateTypesIndex:()=>bt,updateUtilsIndex:()=>Rt});import{exec as Oi}from"node:child_process";import F from"node:path";import{promisify as _i}from"node:util";var Tt,Et,Rt,bt,$t,ve,Nt,It,Fi,ji,nt=Pe(()=>{"use strict";w();P();Tt=_i(Oi),Et=async(e,r)=>{let t=F.join(e,c.HTTP_UTILS,"index.ts");if(m(t)){let o=await d(t);o=o.replace(/export .* from '\.\/axios-client';?\n?/g,""),o=o.replace(/export .* from '\.\/fetch-client';?\n?/g,""),r.includes("fetch")&&!o.includes("fetch-client")&&(o+=`export * from './fetch-client';
3
3
  `),r.includes("axios")&&!o.includes("axios-client")&&(o+=`export * from './axios-client';
4
- `),await u(t,o)}},Qe=async e=>{let r=_.join(e,a.UTILS_INDEX);if(l(r)){let t=await d(r);t.includes("./http")||(t+=`export * from './http';
5
- `,await u(r,t))}},et=async e=>{let r=_.join(e,a.TYPES_INDEX);if(l(r)){let t=await d(r);t.includes("./common")||(t+=`export * from './common';
4
+ `),await f(t,o)}},Rt=async e=>{let r=F.join(e,c.UTILS_INDEX);if(m(r)){let t=await d(r);t.includes("./http")||(t+=`export * from './http';
5
+ `,await f(r,t))}},bt=async e=>{let r=F.join(e,c.TYPES_INDEX);if(m(r)){let t=await d(r);t.includes("./common")||(t+=`export * from './common';
6
6
  `),t.includes("./utility")||(t+=`export * from './utility';
7
- `),await u(r,t)}},tt=async e=>{let r=_.join(e,a.CONFIG_INDEX);if(l(r)){let t=await d(r);t.includes("./app-apis")||(t+=`export * from './app-apis';
8
- `,await u(r,t))}},fe=async(e,r)=>{let t=_.join(e,a.HTTP_TYPES);if(l(t)){let o=await d(t);r.includes("axios")||(o=o.replace(/declare module 'axios'\s*\{\s*export interface AxiosRequestConfig\s*\{[\s\S]*?\}\s*\}/g,""),o=`${o.replace(/\n\s*\n/g,`
7
+ `),await f(r,t)}},$t=async e=>{let r=F.join(e,c.CONFIG_INDEX);if(m(r)){let t=await d(r);t.includes("./app-apis")||(t+=`export * from './app-apis';
8
+ `,await f(r,t))}},ve=async(e,r)=>{let t=F.join(e,c.HTTP_TYPES);if(m(t)){let o=await d(t);r.includes("axios")||(o=o.replace(/declare module 'axios'\s*\{\s*export interface AxiosRequestConfig\s*\{[\s\S]*?\}\s*\}/g,""),o=`${o.replace(/\n\s*\n/g,`
9
9
 
10
10
  `).trim()}
11
- `,await u(t,o))}},rt=async(e,r,t)=>{if(r===t)return;let o=r==="fetch"?"fetchClient":"axiosClient",n=t==="fetch"?"fetchClient":"axiosClient",i=r==="fetch"?"fetch-client":"axios-client",s=t==="fetch"?"fetch-client":"axios-client",c=_.join(e,"src");try{let p=`grep -rl "${o}" "${c}" --include="*.ts" --include="*.tsx" || true`,{stdout:f}=await qe(p);if(!f.trim())return;let g=f.trim().split(`
12
- `).filter(y=>y);for(let y of g){if(!l(y))continue;let x=await d(y),X=!1,Xe=new RegExp(`(import\\s*\\{[^}]*?)\\b${o}\\b([^}]*?\\}\\s*from\\s*['"][^'"]*?/http['"])`,"g");Xe.test(x)&&(x=x.replace(Xe,`$1${n}$2`),X=!0);let Ae=new RegExp(`import\\s+${o}\\s+from\\s+['"]([^'"]*?)/${i}['"]`,"g");Ae.test(x)&&(x=x.replace(Ae,`import ${n} from '$1/${s}'`),X=!0);let Oe=new RegExp(`\\b${o}\\b(?=\\.)`,"g");Oe.test(x)&&(x=x.replace(Oe,n),X=!0);let Ut=new RegExp(`\\b${o}\\b(?![.\\w])`,"g");Ut.test(x)&&(x=x.replace(Ut,n),X=!0),X&&await u(y,x)}}catch(p){console.warn("Warning: Could not scan for HTTP client usages:",p)}},ot=async e=>{let r=_.join(e,a.UTILS_INDEX);if(l(r)){let o=await d(r);o=o.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http['"];?.*$/gm,""),await u(r,o)}let t=_.join(e,a.TYPES_INDEX);if(l(t)){let o=await d(t),n=_.join(e,a.COMMON_TYPES_DIR);if(!l(n))o=o.replace(/^\s*export\s+\*\s+from\s+['"]\.\/common['"];?.*$/gm,"");else{let i=_.join(n,"index.ts");if(l(i)){let s=await d(i);s=s.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http\.types['"];?.*$/gm,""),await u(i,s)}}l(_.join(e,a.UTILITY_TYPES_DIR))||(o=o.replace(/^\s*export\s+\*\s+from\s+['"]\.\/utility['"];?.*$/gm,"")),await u(t,o)}},Si=async(e,r,t=[])=>{let o=_.join(e,"src"),i=`grep -r "from ['\\"].*${r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}.*['\\"]" "${o}" --include="*.ts" --include="*.tsx" || true`;try{let{stdout:s}=await qe(i);return s.trim()?s.trim().split(`
13
- `).filter(f=>{let[g]=f.split(":"),y=_.resolve(e,g);return!t.some(x=>!!(y===x||y.startsWith(x+_.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for ${r}:`,s),!0}},wi=async(e,r,t=[])=>{let o=_.join(e,"src"),i=`grep -r "${r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}" "${o}" --include="*.ts" --include="*.tsx" || true`;try{let{stdout:s}=await qe(i);return s.trim()?s.trim().split(`
14
- `).filter(f=>{let[g]=f.split(":"),y=_.resolve(e,g);return!t.some(x=>!!(y===x||y.startsWith(x+_.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for string ${r}:`,s),!0}}});import{existsSync as Vi}from"node:fs";import{access as Ki}from"node:fs/promises";import Pr from"node:path";var oe,De,Tr=ue(()=>{"use strict";oe=async(e,r,t)=>{try{return await Ki(Pr.join(e,t,r)),!0}catch{return!1}},De=(e,r,t)=>Vi(Pr.join(e,r,t))});import{access as st,readFile as Wi}from"node:fs/promises";import Le from"node:path";var O,Sr=ue(()=>{"use strict";O=async e=>{try{let r=Le.join(e,"package.json"),t=await Wi(r,"utf-8"),o=JSON.parse(t),n={...o.dependencies,...o.devDependencies},i=!!(n["@reduxjs/toolkit"]&&n["react-redux"]),s=!!n["next-intl"],c=!!n.axios,p=!1,f=Le.join(e,"src","lib","utils","http","axios-client");try{await st(f)}catch{c=!1}let g=Le.join(e,"src","lib","utils","http","fetch-client");try{await st(g),p=!0}catch{p=!1}let y;c&&p?y="both":c?y="axios":p?y="fetch":y="none";let x=!!n.vitest;if(!x)try{await st(Le.join(e,"vitest.config.ts")),x=!0}catch{}return{hasRedux:i,httpClient:y,hasI18n:s,hasTests:x}}catch(r){throw new Error(`Failed to detect project setup: ${r}`,{cause:r})}}});var wr={};Ye(wr,{detectProjectSetup:()=>O,directoryExists:()=>oe,fileExistsAt:()=>De});var U=ue(()=>{"use strict";Tr();Sr()});import{Command as _s}from"commander";import nt from"node:path";import re from"picocolors";function Mt(e){let{logger:r=s=>console.error(s),exitOnCancel:t=process.env.NODE_ENV!=="test"}=e??{},o=()=>{console.log(""),console.log(""),r("Setup cancelled by user"),console.log(""),t&&process.exit(0)},n=s=>{if(s!==null&&typeof s=="object"&&"code"in s&&s.code==="ERR_USE_AFTER_CLOSE"){o();return}if(s instanceof Error){r(`Uncaught exception: ${s.message}`);return}r(`Uncaught exception: ${String(s)}`)},i=s=>{if(s instanceof Error){r(`Unhandled promise rejection: ${s.message}`);return}r(`Unhandled promise rejection: ${String(s)}`)};return process.on("SIGINT",o),process.on("SIGTERM",o),process.on("uncaughtException",n),process.on("unhandledRejection",i),()=>{process.off("SIGINT",o),process.off("SIGTERM",o),process.off("uncaughtException",n),process.off("unhandledRejection",i)}}import Y from"picocolors";var Vo={reset:e=>e,red:Y.red,green:Y.green,yellow:Y.yellow,blue:Y.blue,cyan:Y.cyan,magenta:Y.magenta,white:Y.white,gray:Y.gray,bright:Y.bold,dim:Y.dim};function ae(e,r="reset"){let t=Vo[r]??(o=>o);console.log(t(e))}function _e(e){ae(`\u2716 ${e}`,"red")}var w=_e;function m(e){ae(e)}function Jt(){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 Ko from"ora";function I(e="",r){let t=Ko({text:e,...r});return t.start(),t}var Wo=e=>e.charAt(0).toUpperCase()+e.slice(1),$=e=>e.replace(/-([a-z])/g,(r,t)=>t.toUpperCase()),R=e=>Wo($(e));import qo from"ora";var h=qo();T();import{exec as Zo}from"node:child_process";import{promisify as Qo}from"node:util";var W=Qo(Zo),Bt=async(e,r,t)=>{try{if(await W("git init",{cwd:e}),await W("git add .",{cwd:e}),await W('git commit -m "Initial commit from @teispace/next-maker"',{cwd:e}),r&&(await W(`git remote add origin ${r}`,{cwd:e}),t)){await W("git fetch origin",{cwd:e});let o="main";try{await W("git show-branch origin/main",{cwd:e})}catch{try{await W("git show-branch origin/master",{cwd:e}),o="master"}catch{o="main"}}await W(`git merge origin/${o} --allow-unrelated-histories -X ours`,{cwd:e}),await W(`git push origin HEAD:${o}`,{cwd:e})}}catch(o){console.warn("Failed to initialize git repository",o)}};import{exec as ei}from"node:child_process";import{promisify as ti}from"node:util";var he=ti(ei),Xt=async(e,r)=>{let t=`${r} install`;try{await he(t,{cwd:e})}catch(o){throw new Error(`Failed to install dependencies with ${r}: ${o}`,{cause:o})}},G=async(e,r,t)=>{let o=r==="npm"?`${r} run ${t}`:`${r} ${t}`;try{await he(o,{cwd:e})}catch(n){console.warn(`Warning: Failed to run script '${t}': ${n}`)}},ri=()=>{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"},D=async e=>{let{existsSync:r}=await import("node:fs"),t=await import("node:path");return r(t.join(e,"pnpm-lock.yaml"))?"pnpm":r(t.join(e,"yarn.lock"))?"yarn":r(t.join(e,"bun.lockb"))?"bun":r(t.join(e,"package-lock.json"))?"npm":ri()},oi=async(e,r,t)=>{if(t.length===0)return;let n=`${Yt(r)} ${t.join(" ")}`;try{await he(n,{cwd:e})}catch(i){throw new Error(`Failed to install packages with ${r}: ${i}`,{cause:i})}},Yt=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"}},H=async(e,r)=>{let t=await D(e);await oi(e,t,[r])},ii=e=>{switch(e){case"npm":return"--save-dev";case"yarn":case"pnpm":case"bun":return"-D";default:return"--save-dev"}},Ke=async(e,r,t)=>{if(t.length===0)return;let o=Yt(r),n=ii(r),i=`${o} ${n} ${t.join(" ")}`;try{await he(i,{cwd:e})}catch(s){throw new Error(`Failed to install dev packages with ${r}: ${s}`,{cause:s})}},ke=async(e,r)=>{let t=await D(e);await Ke(e,t,[r])},ni=async(e,r,t)=>{if(t.length===0)return;let n=`${si(r)} ${t.join(" ")}`;try{await he(n,{cwd:e})}catch(i){throw new Error(`Failed to uninstall packages with ${r}: ${i}`,{cause:i})}},si=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"}},We=async(e,r)=>{let t=await D(e);await ni(e,t,[r])};import ai from"enquirer";var{prompt:ci}=ai,Vt=async e=>{let r=await ci([{type:"input",name:"projectName",message:"What is the project name?",initial:e||"my-app",skip:!!e,validate:t=>/^[a-z0-9-_]+$/.test(t)?!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:t=>/^\d+\.\d+\.\d+$/.test(t)?!0:"Version must be a valid semantic version (x.y.z)."},{type:"input",name:"email",message:"Support email:",initial:"support@example.com",validate:t=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)?!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:t=>t?/^https:\/\/github\.com\/[\w-]+\/[\w.-]+\/issues$/.test(t)?!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:t=>t?/^https:\/\/github\.com\/[\w-]+\/[\w.-]+#readme$/.test(t)?!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 t=this.state?.answers??this.enquirer?.answers??{};return!!(t.httpClient&&t.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:t=>/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(t)?!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:t=>/^[a-z0-9]+(?:[._-][a-z0-9]+)*$/.test(t)?!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:t=>/^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,127}$/.test(t)?!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(r.company=r.author,r.gitRemote&&!r.gitHomepage){let t=r.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"");r.gitHomepage=`${t}#readme`,r.gitIssues=`${t}/issues`}return r};T();import pi from"node:path";var ee=async(e,r)=>{let t=li(r);await u(pi.join(e,"test/test-utils.tsx"),t)},li=({redux:e,i18n:r})=>e&&r?mi:e?di:r?ui:fi,mi=`import { type RenderOptions, render } from '@testing-library/react';
11
+ `,await f(t,o))}},Nt=async(e,r,t)=>{if(r===t)return;let o=r==="fetch"?"fetchClient":"axiosClient",i=t==="fetch"?"fetchClient":"axiosClient",n=r==="fetch"?"fetch-client":"axios-client",s=t==="fetch"?"fetch-client":"axios-client",a=F.join(e,"src");try{let p=`grep -rl "${o}" "${a}" --include="*.ts" --include="*.tsx" || true`,{stdout:u}=await Tt(p);if(!u.trim())return;let g=u.trim().split(`
12
+ `).filter(y=>y);for(let y of g){if(!m(y))continue;let x=await d(y),Y=!1,Pt=new RegExp(`(import\\s*\\{[^}]*?)\\b${o}\\b([^}]*?\\}\\s*from\\s*['"][^'"]*?/http['"])`,"g");Pt.test(x)&&(x=x.replace(Pt,`$1${i}$2`),Y=!0);let et=new RegExp(`import\\s+${o}\\s+from\\s+['"]([^'"]*?)/${n}['"]`,"g");et.test(x)&&(x=x.replace(et,`import ${i} from '$1/${s}'`),Y=!0);let tt=new RegExp(`\\b${o}\\b(?=\\.)`,"g");tt.test(x)&&(x=x.replace(tt,i),Y=!0);let Pr=new RegExp(`\\b${o}\\b(?![.\\w])`,"g");Pr.test(x)&&(x=x.replace(Pr,i),Y=!0),Y&&await f(y,x)}}catch(p){console.warn("Warning: Could not scan for HTTP client usages:",p)}},It=async e=>{let r=F.join(e,c.UTILS_INDEX);if(m(r)){let o=await d(r);o=o.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http['"];?.*$/gm,""),await f(r,o)}let t=F.join(e,c.TYPES_INDEX);if(m(t)){let o=await d(t),i=F.join(e,c.COMMON_TYPES_DIR);if(!m(i))o=o.replace(/^\s*export\s+\*\s+from\s+['"]\.\/common['"];?.*$/gm,"");else{let n=F.join(i,"index.ts");if(m(n)){let s=await d(n);s=s.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http\.types['"];?.*$/gm,""),await f(n,s)}}m(F.join(e,c.UTILITY_TYPES_DIR))||(o=o.replace(/^\s*export\s+\*\s+from\s+['"]\.\/utility['"];?.*$/gm,"")),await f(t,o)}},Fi=async(e,r,t=[])=>{let o=F.join(e,"src"),n=`grep -r "from ['\\"].*${r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}.*['\\"]" "${o}" --include="*.ts" --include="*.tsx" || true`;try{let{stdout:s}=await Tt(n);return s.trim()?s.trim().split(`
13
+ `).filter(u=>{let[g]=u.split(":"),y=F.resolve(e,g);return!t.some(x=>!!(y===x||y.startsWith(x+F.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for ${r}:`,s),!0}},ji=async(e,r,t=[])=>{let o=F.join(e,"src"),n=`grep -r "${r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}" "${o}" --include="*.ts" --include="*.tsx" || true`;try{let{stdout:s}=await Tt(n);return s.trim()?s.trim().split(`
14
+ `).filter(u=>{let[g]=u.split(":"),y=F.resolve(e,g);return!t.some(x=>!!(y===x||y.startsWith(x+F.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for string ${r}:`,s),!0}}});import{existsSync as cs}from"node:fs";import{access as ps}from"node:fs/promises";import Wr from"node:path";var ie,st,Zr=Pe(()=>{"use strict";ie=async(e,r,t)=>{try{return await ps(Wr.join(e,t,r)),!0}catch{return!1}},st=(e,r,t)=>cs(Wr.join(e,r,t))});import{access as Ot,readFile as ls}from"node:fs/promises";import at from"node:path";var I,Qr=Pe(()=>{"use strict";I=async e=>{try{let r=at.join(e,"package.json"),t=await ls(r,"utf-8"),o=JSON.parse(t),i={...o.dependencies,...o.devDependencies},n=!!(i["@reduxjs/toolkit"]&&i["react-redux"]),s=!!i["next-intl"],a=!!i.axios,p=!1,u=at.join(e,"src","lib","utils","http","axios-client");try{await Ot(u)}catch{a=!1}let g=at.join(e,"src","lib","utils","http","fetch-client");try{await Ot(g),p=!0}catch{p=!1}let y;a&&p?y="both":a?y="axios":p?y="fetch":y="none";let x=!!i.vitest;if(!x)try{await Ot(at.join(e,"vitest.config.ts")),x=!0}catch{}return{hasRedux:n,httpClient:y,hasI18n:s,hasTests:x}}catch(r){throw new Error(`Failed to detect project setup: ${r}`,{cause:r})}}});var $e={};vt($e,{detectProjectSetup:()=>I,directoryExists:()=>ie,fileExistsAt:()=>st});var L=Pe(()=>{"use strict";Zr();Qr()});import{Command as Dc}from"commander";import kt from"node:path";import ne from"picocolors";function vr(e){let{logger:r=s=>console.error(s),exitOnCancel:t=process.env.NODE_ENV!=="test"}=e??{},o=()=>{console.log(""),console.log(""),r("Setup cancelled by user"),console.log(""),t&&process.exit(0)},i=s=>{if(s!==null&&typeof s=="object"&&"code"in s&&s.code==="ERR_USE_AFTER_CLOSE"){o();return}if(s instanceof Error){r(`Uncaught exception: ${s.message}`);return}r(`Uncaught exception: ${String(s)}`)},n=s=>{if(s instanceof Error){r(`Unhandled promise rejection: ${s.message}`);return}r(`Unhandled promise rejection: ${String(s)}`)};return process.on("SIGINT",o),process.on("SIGTERM",o),process.on("uncaughtException",i),process.on("unhandledRejection",n),()=>{process.off("SIGINT",o),process.off("SIGTERM",o),process.off("uncaughtException",i),process.off("unhandledRejection",n)}}import K from"picocolors";var pi={reset:e=>e,red:K.red,green:K.green,yellow:K.yellow,blue:K.blue,cyan:K.cyan,magenta:K.magenta,white:K.white,gray:K.gray,bright:K.bold,dim:K.dim};function me(e,r="reset"){let t=pi[r]??(o=>o);console.log(t(e))}function rt(e){me(`\u2716 ${e}`,"red")}var v=rt;function l(e){me(e)}function Sr(){console.log(""),me("\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"),me("\u2551 \u2551","cyan"),me("\u2551 \u{1F680} Create Teispace Next.js App \u{1F680} \u2551","cyan"),me("\u2551 \u2551","cyan"),me("\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 li from"ora";function R(e="",r){let t=li({text:e,...r});return t.start(),t}var mi=e=>e.charAt(0).toUpperCase()+e.slice(1),A=e=>e.replace(/-([a-z])/g,(r,t)=>t.toUpperCase()),b=e=>mi(A(e));import di from"ora";var h=di();P();import{exec as ui}from"node:child_process";import{promisify as fi}from"node:util";var Z=fi(ui),Cr=async(e,r,t)=>{try{if(await Z("git init",{cwd:e}),await Z("git add .",{cwd:e}),await Z('git commit -m "Initial commit from @teispace/next-maker"',{cwd:e}),r&&(await Z(`git remote add origin ${r}`,{cwd:e}),t)){await Z("git fetch origin",{cwd:e});let o="main";try{await Z("git show-branch origin/main",{cwd:e})}catch{try{await Z("git show-branch origin/master",{cwd:e}),o="master"}catch{o="main"}}await Z(`git merge origin/${o} --allow-unrelated-histories -X ours`,{cwd:e}),await Z(`git push origin HEAD:${o}`,{cwd:e})}}catch(o){console.warn("Failed to initialize git repository",o)}};import{exec as gi}from"node:child_process";import{promisify as hi}from"node:util";var Ee=hi(gi),Tr=async(e,r)=>{let t=`${r} install`;try{await Ee(t,{cwd:e})}catch(o){throw new Error(`Failed to install dependencies with ${r}: ${o}`,{cause:o})}},U=async(e,r,t)=>{let o=r==="npm"?`${r} run ${t}`:`${r} ${t}`;try{await Ee(o,{cwd:e})}catch(i){console.warn(`Warning: Failed to run script '${t}': ${i}`)}},yi=()=>{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"},O=async e=>{let{existsSync:r}=await import("node:fs"),t=await import("node:path");return r(t.join(e,"pnpm-lock.yaml"))?"pnpm":r(t.join(e,"yarn.lock"))?"yarn":r(t.join(e,"bun.lockb"))?"bun":r(t.join(e,"package-lock.json"))?"npm":yi()},xi=async(e,r,t)=>{if(t.length===0)return;let i=`${Er(r)} ${t.join(" ")}`;try{await Ee(i,{cwd:e})}catch(n){throw new Error(`Failed to install packages with ${r}: ${n}`,{cause:n})}},Er=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"}},z=async(e,r)=>{let t=await O(e);await xi(e,t,[r])},Pi=e=>{switch(e){case"npm":return"--save-dev";case"yarn":case"pnpm":case"bun":return"-D";default:return"--save-dev"}},ue=async(e,r,t)=>{if(t.length===0)return;let o=Er(r),i=Pi(r),n=`${o} ${i} ${t.join(" ")}`;try{await Ee(n,{cwd:e})}catch(s){throw new Error(`Failed to install dev packages with ${r}: ${s}`,{cause:s})}},ot=async(e,r)=>{let t=await O(e);await ue(e,t,[r])},wt=async(e,r,t)=>{if(t.length===0)return;let i=`${vi(r)} ${t.join(" ")}`;try{await Ee(i,{cwd:e})}catch(n){throw new Error(`Failed to uninstall packages with ${r}: ${n}`,{cause:n})}},vi=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"}},Ct=async(e,r)=>{let t=await O(e);await wt(e,t,[r])};import Si from"enquirer";var{prompt:wi}=Si,Rr=async e=>{let r=await wi([{type:"input",name:"projectName",message:"What is the project name?",initial:e||"my-app",skip:!!e,validate:t=>/^[a-z0-9-_]+$/.test(t)?!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:t=>/^\d+\.\d+\.\d+$/.test(t)?!0:"Version must be a valid semantic version (x.y.z)."},{type:"input",name:"email",message:"Support email:",initial:"support@example.com",validate:t=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)?!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:t=>t?/^https:\/\/github\.com\/[\w-]+\/[\w.-]+\/issues$/.test(t)?!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:t=>t?/^https:\/\/github\.com\/[\w-]+\/[\w.-]+#readme$/.test(t)?!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 t=this.state?.answers??this.enquirer?.answers??{};return!!(t.httpClient&&t.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:t=>/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(t)?!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:t=>/^[a-z0-9]+(?:[._-][a-z0-9]+)*$/.test(t)?!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:t=>/^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,127}$/.test(t)?!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(r.company=r.author,r.gitRemote&&!r.gitHomepage){let t=r.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"");r.gitHomepage=`${t}#readme`,r.gitIssues=`${t}/issues`}return r};P();import Ci from"node:path";var re=async(e,r)=>{let t=Ti(r);await f(Ci.join(e,"test/test-utils.tsx"),t)},Ti=({redux:e,i18n:r})=>e&&r?Ei:e?Ri:r?bi:$i,Ei=`import { type RenderOptions, render } from '@testing-library/react';
15
15
  import { NextIntlClientProvider } from 'next-intl';
16
16
  import type { ReactElement, ReactNode } from 'react';
17
17
  import { Provider } from 'react-redux';
@@ -72,7 +72,7 @@ export function renderWithProviders(
72
72
 
73
73
  export * from '@testing-library/react';
74
74
  export { default as userEvent } from '@testing-library/user-event';
75
- `,di=`import { type RenderOptions, render } from '@testing-library/react';
75
+ `,Ri=`import { type RenderOptions, render } from '@testing-library/react';
76
76
  import type { ReactElement, ReactNode } from 'react';
77
77
  import { Provider } from 'react-redux';
78
78
  import { type AppState, type AppStore, makeStore } from '@/store';
@@ -111,7 +111,7 @@ export function renderWithProviders(
111
111
 
112
112
  export * from '@testing-library/react';
113
113
  export { default as userEvent } from '@testing-library/user-event';
114
- `,ui=`import { type RenderOptions, render } from '@testing-library/react';
114
+ `,bi=`import { type RenderOptions, render } from '@testing-library/react';
115
115
  import { NextIntlClientProvider } from 'next-intl';
116
116
  import type { ReactElement, ReactNode } from 'react';
117
117
  import type { SupportedLocale } from '@/types/i18n';
@@ -151,7 +151,7 @@ export function renderWithProviders(
151
151
 
152
152
  export * from '@testing-library/react';
153
153
  export { default as userEvent } from '@testing-library/user-event';
154
- `,fi=`import { type RenderOptions, render } from '@testing-library/react';
154
+ `,$i=`import { type RenderOptions, render } from '@testing-library/react';
155
155
  import type { ReactElement, ReactNode } from 'react';
156
156
 
157
157
  type TestProvidersProps = {
@@ -173,9 +173,9 @@ export function renderWithProviders(ui: ReactElement, options: ExtendedRenderOpt
173
173
 
174
174
  export * from '@testing-library/react';
175
175
  export { default as userEvent } from '@testing-library/user-event';
176
- `;import Wt from"node:path";var E={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"};C();T();var qt=async(e,r)=>{if(r.bundleAnalyzer)return;let t=Wt.join(e,a.NEXT_CONFIG);if(l(t)){let o=await d(t);o=o.replace(/import\s+withBundleAnalyzer\s+from\s+'@next\/bundle-analyzer';\n/,""),o=o.replace(/const\s+bundleAnalyzer\s*=\s*withBundleAnalyzer\(\{[\s\S]*?\}\);\n+/,""),o=o.replace(/bundleAnalyzer\(([^)]*)\)/,"$1"),await u(t,o)}await j(Wt.join(e,a.PACKAGE_JSON),o=>(o.devDependencies&&delete o.devDependencies[E.NEXT_BUNDLE_ANALYZER],o.scripts&&delete o.scripts.analyze,o))};C();T();import xe from"node:path";var Zt=async(e,r)=>{r.darkMode||(await S(xe.join(e,a.THEME_PROVIDER)),await gi(e),await hi(e),await yi(e))},gi=async e=>{let r=xe.join(e,a.PROVIDERS_INDEX),t=await d(r);t=t.replace(/export \* from '\.\/CustomThemeProvider';\n/,""),await u(r,t)},hi=async e=>{let r=xe.join(e,a.GLOBALS_CSS);if(l(r)){let t=await d(r);t=t.replace(/@custom-variant dark \(.*?\);\n\n/,""),t=t.replace(/@theme \{[\s\S]*?\}\n/,""),await u(r,t)}},xi=e=>e.replace(/\bbg-light\b\s?/g,"").replace(/\bdark:bg-dark\b\s?/g,"").replace(/\s{2,}/g," ").replace(/suppressHydrationWarning=\{true\}/g,""),yi=async e=>{let r=[xe.join(e,a.ROOT_LAYOUT),xe.join(e,"src/app/[locale]/layout.tsx")];for(let t of r)if(l(t)){let o=await d(t),n=xi(o);n!==o&&await u(t,n)}};C();T();je();import N from"node:path";var er=async(e,r)=>{let t=N.join(e,a.HTTP_UTILS),o=r.httpClient!=="none"||!!r.reactSecureStorage;r.httpClient==="none"?await vi(e,t,o):r.httpClient==="axios"?await Ci(e,t):r.httpClient==="fetch"&&await Ei(e,t)},vi=async(e,r,t)=>{await P(N.join(e,a.AXIOS_CLIENT)),await P(N.join(e,a.FETCH_CLIENT)),t?(await u(N.join(r,"index.ts"),`export * from './token-store';
177
- `),await S(N.join(e,a.CLIENT_UTILS)),await fe(e,[])):(await P(r),await Ii(e),await S(N.join(e,a.APP_APIS)),await Ri(e)),await Ni(e),await P(N.join(e,a.ERRORS_DIR)),t||(await P(N.join(e,a.COMMON_TYPES_DIR)),await P(N.join(e,a.UTILITY_TYPES_DIR)),await bi(e))},Ci=async(e,r)=>{await P(N.join(e,a.FETCH_CLIENT));let t=await d(N.join(r,"index.ts"));t=t.replace(/export .* from '\.\/fetch-client';\n/g,""),await u(N.join(r,"index.ts"),t);let o=N.join(e,a.HTTP_TYPES);if(l(o)){let n=await d(o);n=n.replace(/export interface FetchClientOptions \{[\s\S]*?\}\n\n/,""),n=n.replace(/export interface ExtendedRequestInit extends RequestInit \{[\s\S]*?\}\n\n/,""),await u(o,n)}},Ei=async(e,r)=>{await P(N.join(e,a.AXIOS_CLIENT));let t=await d(N.join(r,"index.ts"));t=t.replace(/export .* from '\.\/axios-client';\n/g,""),await u(N.join(r,"index.ts"),t),await fe(e,["fetch"]);let o=N.join(e,a.HTTP_TYPES);if(l(o)){let n=await d(o);n=n.replace(/export interface AxiosClientOptions \{[\s\S]*?\}\n\n/,""),await u(o,n)}},Ii=async e=>{let r=N.join(e,a.UTILS_INDEX);if(l(r)){let t=await d(r);t=t.replace(/export \* from '\.\/http';\n/,""),await u(r,t)}},Ri=async e=>{let r=N.join(e,a.CONFIG_INDEX);if(l(r)){let t=await d(r);t=t.replace(/export \* from '\.\/app-apis';\n/,""),await u(r,t)}},Ni=async e=>{let r=N.join(e,a.CONSTANTS);if(l(r)){let t=await d(r);t=t.replace(/export const API_RESPONSE_DATA_KEY = 'data';\n/,""),t=t.replace(/export const SAVE_AUTH_TOKENS = false;\n/,""),await u(r,t)}},bi=async e=>{let r=N.join(e,a.TYPES_INDEX);if(l(r)){let t=await d(r);t=t.replace(/export \* from '\.\/utility';\n/,""),t=t.replace(/export \* from '\.\/common';\n/,""),await u(r,t)}};C();T();import L from"node:path";var tr=async(e,r)=>{r.i18n||(await Ai(e),await Oi(e),await _i(e),await ki(e),await $i(e))},$i=async e=>{let r=L.join(e,a.ENV_EXAMPLE);if(!l(r))return;let t=await d(r);t=t.replace(/#[^\n]*IANA time zone[\s\S]*?DEFAULT_TIMEZONE=[^\n]*\n?/,""),t=t.replace(/#[^\n]*Fallback locale[\s\S]*?DEFAULT_LOCALE=[^\n]*\n?/,""),t=t.replace(/^DEFAULT_TIMEZONE=.*\n?/m,""),t=t.replace(/^DEFAULT_LOCALE=.*\n?/m,""),await u(r,t)},Ai=async e=>{await P(L.join(e,a.I18N_DIR)),await P(L.join(e,a.LOCALE_DIR)),await S(L.join(e,a.PROXY)),await S(L.join(e,a.MIDDLEWARE)),await S(L.join(e,a.I18N_TYPES)),await S(L.join(e,a.APP_LOCALES))},Oi=async e=>{let r=L.join(e,a.TYPES_INDEX);if(l(r)){let o=await d(r);o=o.replace(/export \* from '\.\/i18n';\n/,""),await u(r,o)}let t=L.join(e,a.CONFIG_INDEX);if(l(t)){let o=await d(t);o=o.replace(/export \* from '\.\/app-locales';\n/,""),await u(t,o)}},_i=async e=>{let r=L.join(e,a.NEXT_CONFIG);if(l(r)){let t=await d(r);t=t.replace(/import createNextIntlPlugin from 'next-intl\/plugin';\n/,""),t=t.replace(/const withNextIntl = createNextIntlPlugin\(\);\n+/,""),t=t.replace(/withNextIntl\(([^)]+)\)/,"$1"),await u(r,t)}},ki=async e=>{let r=L.join(e,a.COUNTER_COMPONENT);if(l(r)){let n=await d(r);n=n.replace(/import\s+\{\s*useTranslations\s*\}\s+from\s+['"]next-intl['"];\n/,""),n=n.replace(/\s*const\s+t\s*=\s*useTranslations\(['"]Count['"]\);\n/,""),n=n.replace(/\{t\('currentCount',\s*\{\s*count:\s*value\s*\}\)\}/g,"Current Count: {value}"),n=n.replace(/\{t\(['"]increment['"]\)\}/g,"Increment"),n=n.replace(/\{t\(['"]decrement['"]\)\}/g,"Decrement"),n=n.replace(/\{t\(['"]reset['"]\)\}/g,"Reset"),await u(r,n)}let t=L.join(e,"src/features/counter/components/Counter.test.tsx"),o=L.join(e,"test/test-utils.tsx");await S(t),await S(o)};C();T();import te from"node:path";var rr=async(e,r)=>{r.httpClient!=="none"||r.reactSecureStorage||await P(te.join(e,a.STORAGE_SERVICE))},or=async e=>{await S(te.join(e,a.LICENSE))},ir=async e=>{await S(te.join(e,a.CHANGELOG))},nr=async e=>{await S(te.join(e,a.NVM_RC)),await S(te.join(e,a.NPM_RC))},sr=async e=>{await P(te.join(e,a.CLAUDE_DIR)),await P(te.join(e,a.DOCS_DIR)),await P(te.join(e,a.VSCODE_DIR))};import ar from"node:path";C();T();var cr=async(e,r)=>{if(r.reactCompiler)return;let t=ar.join(e,a.NEXT_CONFIG);if(l(t)){let o=await d(t);o=o.replace(/^\s*reactCompiler:\s*true,?\n/m,""),await u(t,o)}await j(ar.join(e,a.PACKAGE_JSON),o=>(o.devDependencies&&delete o.devDependencies[E.REACT_COMPILER_BABEL],o))};C();T();import pe from"node:path";var pr=async(e,r)=>{r.redux||(await P(pe.join(e,a.STORE)),await P(pe.join(e,a.COUNTER_FEATURE)),await S(pe.join(e,a.STORE_PROVIDER)),await S(pe.join(e,"test/test-utils.tsx")),await ji(e),await Fi(e))},ji=async e=>{let r=pe.join(e,a.PROVIDERS_INDEX),t=await d(r);t=t.replace(/export \* from '\.\/StoreProvider';\n/,""),await u(r,t)},Fi=async e=>{let r=[pe.join(e,a.ROOT_PAGE),pe.join(e,a.LOCALE_PAGE)];for(let t of r)if(l(t)){let o=await d(t);o=o.replace(/import\s+\{\s*Counter\s*\}\s+from\s+['"]@\/features\/counter['"];\n?/,""),o=o.replace(/<Counter\s*\/>\n?/g,""),await u(t,o)}};import Fe from"node:path";C();T();var Di=[E.VITEST,E.JSDOM,E.VITE_PLUGIN_REACT,E.TESTING_LIBRARY_DOM,E.TESTING_LIBRARY_JEST_DOM,E.TESTING_LIBRARY_REACT,E.TESTING_LIBRARY_USER_EVENT],lr=async(e,r)=>{r.tests||(await S(Fe.join(e,a.VITEST_CONFIG)),await P(Fe.join(e,a.TEST_DIR)),await S(Fe.join(e,"src/features/counter/components/Counter.test.tsx")),await j(Fe.join(e,a.PACKAGE_JSON),t=>{if(t.devDependencies)for(let o of Di)delete t.devDependencies[o];return t.scripts&&(delete t.scripts.test,delete t.scripts["test:watch"],delete t.scripts["test:coverage"],typeof t.scripts.validate=="string"&&(t.scripts.validate=t.scripts.validate.replace(/\s*&&\s*yarn\s+test(?![:\w])/,"").replace(/\byarn\s+test(?![:\w])\s*&&\s*/,""))),t}))};var mr=async(e,r)=>{let t=I("Customizing features...");try{await er(e,r),await rr(e,r),await pr(e,r),await Zt(e,r),await qt(e,r),await tr(e,r),await cr(e,r),await lr(e,r),await or(e),await ir(e),await nr(e),await sr(e),r.tests&&await ee(e,{redux:r.redux,i18n:r.i18n}),t.succeed("Features customized.")}catch(o){throw t.fail("Failed to customize features."),o}};import Li from"node:path";C();T();var dr=async(e,r)=>{let t=I("Configuring package.json...");try{let o=r.gitRemote,n=r.gitHomepage,i=r.gitIssues;r.gitRemote&&(r.gitRemote.startsWith("git@github.com:")&&(o=r.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"")),n||(n=`${o.replace(/\.git$/,"")}#readme`),i||(i=`${o.replace(/\.git$/,"")}/issues`),o.endsWith(".git")||(o=`${o}.git`)),await j(Li.join(e,a.PACKAGE_JSON),s=>(s.name=r.projectName,s.version=r.version,s.description=r.description,s.author=r.author,delete s.packageManager,r.gitRemote?(n&&(s.homepage=n),i&&(s.bugs={url:i}),o&&(s.repository={type:"git",url:o})):(delete s.homepage,delete s.bugs,delete s.repository),r.redux||(delete s.dependencies[E.REDUX_TOOLKIT],delete s.dependencies[E.REACT_REDUX],delete s.dependencies[E.REDUX],delete s.dependencies[E.REDUX_PERSIST]),r.httpClient!=="none"||r.reactSecureStorage||delete s.dependencies[E.REACT_SECURE_STORAGE],r.i18n||delete s.dependencies[E.NEXT_INTL],r.darkMode||delete s.dependencies[E.NEXT_THEMES],r.httpClient==="none"?delete s.dependencies[E.AXIOS]:r.httpClient==="fetch"&&delete s.dependencies[E.AXIOS],s)),t.succeed("package.json configured.")}catch(o){throw t.fail("Failed to configure package.json."),o}};import{readdir as ur}from"node:fs/promises";import b from"node:path";C();T();var fr=async(e,r)=>{await Gi(e,r),await Hi(e,r),await Ui(e,r),await Mi(e,r),await Ji(e,r),await zi(e,r),await Bi(e,r)},Gi=async(e,r)=>{r.preCommitHooks||(await P(b.join(e,a.HUSKY_DIR)),await S(b.join(e,a.COMMITLINT_CONFIG)),await S(b.join(e,a.LINTSTAGED_RC)),await j(b.join(e,a.PACKAGE_JSON),t=>(delete t.devDependencies[E.HUSKY],delete t.devDependencies[E.COMMITLINT_CLI],delete t.devDependencies[E.COMMITLINT_CONFIG],delete t.devDependencies[E.LINT_STAGED],delete t.scripts.prepare,delete t.scripts.postinstall,delete t.commitlint,delete t["lint-staged"],t)))},Hi=async(e,r)=>{r.commitizen||(await S(b.join(e,a.CZRC)),await j(b.join(e,a.PACKAGE_JSON),t=>(delete t.devDependencies[E.COMMITIZEN],delete t.devDependencies[E.CZ_CONVENTIONAL_CHANGELOG],delete t.config?.commitizen,t.config&&Object.keys(t.config).length===0&&delete t.config,delete t.scripts.commit,t)))},Ui=async(e,r)=>{r.ci||await P(b.join(e,a.GITHUB_WORKFLOWS))},Mi=async(e,r)=>{let t=b.join(e,a.GITHUB_DIR);if(!r.keepTemplates)await P(b.join(t,a.GITHUB_ISSUE_TEMPLATE)),await S(b.join(t,a.GITHUB_PR_TEMPLATE));else{let o=b.join(t,a.GITHUB_ISSUE_TEMPLATE),n=b.join(t,a.GITHUB_PR_TEMPLATE),i=s=>s.replace(/Teispace/g,r.company).replace(/support@teispace\.com/g,r.email).replace(/Next\.js Starter/g,r.projectName).replace(/\[AUTHOR\]/g,r.author).replace(/\[COMPANY\]/g,r.company).replace(/\[EMAIL\]/g,r.email);if(l(n)){let s=await d(n);s=i(s),await u(n,s)}try{if(l(o)){let s=await ur(o);for(let c of s){let p=b.join(o,c),f=await d(p);f=i(f),await u(p,f)}}}catch{}}},Ji=async(e,r)=>{let t=[a.CODE_OF_CONDUCT,a.CONTRIBUTING,a.SECURITY];for(let o of t)r.communityFiles.includes(o)||await S(b.join(e,o))},zi=async(e,r)=>{if(r.docker){let t=b.join(e,a.ENV_EXAMPLE);if(l(t)){let o=await d(t),n=(i,s)=>{let c=new RegExp(`${i}=.*`);c.test(o)?o=o.replace(c,`${i}=${s}`):o+=`${i}=${s}
178
- `};n("CONTAINER_NAME",r.containerName||"next-app"),n("IMAGE_NAME",r.imageName||"nextjs-starter"),n("IMAGE_TAG",r.imageTag||"latest"),await u(t,o)}}else{await S(b.join(e,a.DOCKERFILE)),await S(b.join(e,a.DOCKER_COMPOSE)),await S(b.join(e,a.DOCKERIGNORE));let t=b.join(e,a.ENV_EXAMPLE);if(l(t)){let o=await d(t);o=o.replace(/# Docker Compose Configuration\n/,""),o=o.replace(/CONTAINER_NAME=.*\n/,""),o=o.replace(/IMAGE_NAME=.*\n/,""),o=o.replace(/IMAGE_TAG=.*\n/,""),await u(t,o)}}},Bi=async(e,r)=>{let t=async i=>{let s=await ur(i,{withFileTypes:!0}),c=[];for(let p of s){let f=b.join(i,p.name);p.isDirectory()&&p.name!=="node_modules"&&p.name!==".git"?c.push(...await t(f)):p.isFile()&&p.name.toLowerCase()==="readme.md"&&c.push(f)}return c},o=await t(e),n=b.join(e,a.README);for(let i of o)i!==n&&await S(i);if(r.readme){let i=`# ${r.projectName}
176
+ `;import $r from"node:path";var C={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"};w();P();var Nr=async(e,r)=>{if(r.bundleAnalyzer)return;let t=$r.join(e,c.NEXT_CONFIG);if(m(t)){let o=await d(t);o=o.replace(/import\s+withBundleAnalyzer\s+from\s+'@next\/bundle-analyzer';\n/,""),o=o.replace(/const\s+bundleAnalyzer\s*=\s*withBundleAnalyzer\(\{[\s\S]*?\}\);\n+/,""),o=o.replace(/bundleAnalyzer\(([^)]*)\)/,"$1"),await f(t,o)}await k($r.join(e,c.PACKAGE_JSON),o=>(o.devDependencies&&delete o.devDependencies[C.NEXT_BUNDLE_ANALYZER],o.scripts&&delete o.scripts.analyze,o))};w();P();import Re from"node:path";var Ir=async(e,r)=>{r.darkMode||(await T(Re.join(e,c.THEME_PROVIDER)),await Ni(e),await Ii(e),await ki(e))},Ni=async e=>{let r=Re.join(e,c.PROVIDERS_INDEX),t=await d(r);t=t.replace(/export \* from '\.\/CustomThemeProvider';\n/,""),await f(r,t)},Ii=async e=>{let r=Re.join(e,c.GLOBALS_CSS);if(m(r)){let t=await d(r);t=t.replace(/@custom-variant dark \(.*?\);\n\n/,""),t=t.replace(/@theme \{[\s\S]*?\}\n/,""),await f(r,t)}},Ai=e=>e.replace(/\bbg-light\b\s?/g,"").replace(/\bdark:bg-dark\b\s?/g,"").replace(/\s{2,}/g," ").replace(/suppressHydrationWarning=\{true\}/g,""),ki=async e=>{let r=[Re.join(e,c.ROOT_LAYOUT),Re.join(e,"src/app/[locale]/layout.tsx")];for(let t of r)if(m(t)){let o=await d(t),i=Ai(o);i!==o&&await f(t,i)}};w();P();nt();import $ from"node:path";var kr=async(e,r)=>{let t=$.join(e,c.HTTP_UTILS),o=r.httpClient!=="none"||!!r.reactSecureStorage;r.httpClient==="none"?await Di(e,t,o):r.httpClient==="axios"?await Li(e,t):r.httpClient==="fetch"&&await Mi(e,t)},Di=async(e,r,t)=>{await S($.join(e,c.AXIOS_CLIENT)),await S($.join(e,c.FETCH_CLIENT)),t?(await f($.join(r,"index.ts"),`export * from './token-store';
177
+ `),await T($.join(e,c.CLIENT_UTILS)),await ve(e,[])):(await S(r),await Gi(e),await T($.join(e,c.APP_APIS)),await Hi(e)),await Ui(e),await S($.join(e,c.ERRORS_DIR)),t||(await S($.join(e,c.COMMON_TYPES_DIR)),await S($.join(e,c.UTILITY_TYPES_DIR)),await zi(e))},Li=async(e,r)=>{await S($.join(e,c.FETCH_CLIENT));let t=await d($.join(r,"index.ts"));t=t.replace(/export .* from '\.\/fetch-client';\n/g,""),await f($.join(r,"index.ts"),t);let o=$.join(e,c.HTTP_TYPES);if(m(o)){let i=await d(o);i=i.replace(/export interface FetchClientOptions \{[\s\S]*?\}\n\n/,""),i=i.replace(/export interface ExtendedRequestInit extends RequestInit \{[\s\S]*?\}\n\n/,""),await f(o,i)}},Mi=async(e,r)=>{await S($.join(e,c.AXIOS_CLIENT));let t=await d($.join(r,"index.ts"));t=t.replace(/export .* from '\.\/axios-client';\n/g,""),await f($.join(r,"index.ts"),t),await ve(e,["fetch"]);let o=$.join(e,c.HTTP_TYPES);if(m(o)){let i=await d(o);i=i.replace(/export interface AxiosClientOptions \{[\s\S]*?\}\n\n/,""),await f(o,i)}},Gi=async e=>{let r=$.join(e,c.UTILS_INDEX);if(m(r)){let t=await d(r);t=t.replace(/export \* from '\.\/http';\n/,""),await f(r,t)}},Hi=async e=>{let r=$.join(e,c.CONFIG_INDEX);if(m(r)){let t=await d(r);t=t.replace(/export \* from '\.\/app-apis';\n/,""),await f(r,t)}},Ui=async e=>{let r=$.join(e,c.CONSTANTS);if(m(r)){let t=await d(r);t=t.replace(/export const API_RESPONSE_DATA_KEY = 'data';\n/,""),t=t.replace(/export const SAVE_AUTH_TOKENS = false;\n/,""),await f(r,t)}},zi=async e=>{let r=$.join(e,c.TYPES_INDEX);if(m(r)){let t=await d(r);t=t.replace(/export \* from '\.\/utility';\n/,""),t=t.replace(/export \* from '\.\/common';\n/,""),await f(r,t)}};w();P();import H from"node:path";var Or=async(e,r)=>{r.i18n||(await Ji(e),await Bi(e),await Xi(e),await Yi(e),await Vi(e))},Vi=async e=>{let r=H.join(e,c.ENV_EXAMPLE);if(!m(r))return;let t=await d(r);t=t.replace(/#[^\n]*IANA time zone[\s\S]*?DEFAULT_TIMEZONE=[^\n]*\n?/,""),t=t.replace(/#[^\n]*Fallback locale[\s\S]*?DEFAULT_LOCALE=[^\n]*\n?/,""),t=t.replace(/^DEFAULT_TIMEZONE=.*\n?/m,""),t=t.replace(/^DEFAULT_LOCALE=.*\n?/m,""),await f(r,t)},Ji=async e=>{await S(H.join(e,c.I18N_DIR)),await S(H.join(e,c.LOCALE_DIR)),await T(H.join(e,c.PROXY)),await T(H.join(e,c.MIDDLEWARE)),await T(H.join(e,c.I18N_TYPES)),await T(H.join(e,c.APP_LOCALES))},Bi=async e=>{let r=H.join(e,c.TYPES_INDEX);if(m(r)){let o=await d(r);o=o.replace(/export \* from '\.\/i18n';\n/,""),await f(r,o)}let t=H.join(e,c.CONFIG_INDEX);if(m(t)){let o=await d(t);o=o.replace(/export \* from '\.\/app-locales';\n/,""),await f(t,o)}},Xi=async e=>{let r=H.join(e,c.NEXT_CONFIG);if(m(r)){let t=await d(r);t=t.replace(/import createNextIntlPlugin from 'next-intl\/plugin';\n/,""),t=t.replace(/const withNextIntl = createNextIntlPlugin\(\);\n+/,""),t=t.replace(/withNextIntl\(([^)]+)\)/,"$1"),await f(r,t)}},Yi=async e=>{let r=H.join(e,c.COUNTER_COMPONENT);if(m(r)){let i=await d(r);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 f(r,i)}let t=H.join(e,"src/features/counter/components/Counter.test.tsx"),o=H.join(e,"test/test-utils.tsx");await T(t),await T(o)};w();P();import oe from"node:path";var _r=async(e,r)=>{r.httpClient!=="none"||r.reactSecureStorage||await S(oe.join(e,c.STORAGE_SERVICE))},Fr=async e=>{await T(oe.join(e,c.LICENSE))},jr=async e=>{await T(oe.join(e,c.CHANGELOG))},Dr=async e=>{await T(oe.join(e,c.NVM_RC)),await T(oe.join(e,c.NPM_RC))},Lr=async e=>{await S(oe.join(e,c.CLAUDE_DIR)),await S(oe.join(e,c.DOCS_DIR)),await S(oe.join(e,c.VSCODE_DIR))};import Mr from"node:path";w();P();var Gr=async(e,r)=>{if(r.reactCompiler)return;let t=Mr.join(e,c.NEXT_CONFIG);if(m(t)){let o=await d(t);o=o.replace(/^\s*reactCompiler:\s*true,?\n/m,""),await f(t,o)}await k(Mr.join(e,c.PACKAGE_JSON),o=>(o.devDependencies&&delete o.devDependencies[C.REACT_COMPILER_BABEL],o))};w();P();import fe from"node:path";var Hr=async(e,r)=>{r.redux||(await S(fe.join(e,c.STORE)),await S(fe.join(e,c.COUNTER_FEATURE)),await T(fe.join(e,c.STORE_PROVIDER)),await T(fe.join(e,"test/test-utils.tsx")),await Ki(e),await qi(e))},Ki=async e=>{let r=fe.join(e,c.PROVIDERS_INDEX),t=await d(r);t=t.replace(/export \* from '\.\/StoreProvider';\n/,""),await f(r,t)},qi=async e=>{let r=[fe.join(e,c.ROOT_PAGE),fe.join(e,c.LOCALE_PAGE)];for(let t of r)if(m(t)){let o=await d(t);o=o.replace(/import\s+\{\s*Counter\s*\}\s+from\s+['"]@\/features\/counter['"];\n?/,""),o=o.replace(/<Counter\s*\/>\n?/g,""),await f(t,o)}};import it from"node:path";w();P();var Wi=[C.VITEST,C.JSDOM,C.VITE_PLUGIN_REACT,C.TESTING_LIBRARY_DOM,C.TESTING_LIBRARY_JEST_DOM,C.TESTING_LIBRARY_REACT,C.TESTING_LIBRARY_USER_EVENT],Ur=async(e,r)=>{r.tests||(await T(it.join(e,c.VITEST_CONFIG)),await S(it.join(e,c.TEST_DIR)),await T(it.join(e,"src/features/counter/components/Counter.test.tsx")),await k(it.join(e,c.PACKAGE_JSON),t=>{if(t.devDependencies)for(let o of Wi)delete t.devDependencies[o];return t.scripts&&(delete t.scripts.test,delete t.scripts["test:watch"],delete t.scripts["test:coverage"],typeof t.scripts.validate=="string"&&(t.scripts.validate=t.scripts.validate.replace(/\s*&&\s*yarn\s+test(?![:\w])/,"").replace(/\byarn\s+test(?![:\w])\s*&&\s*/,""))),t}))};var zr=async(e,r)=>{let t=R("Customizing features...");try{await kr(e,r),await _r(e,r),await Hr(e,r),await Ir(e,r),await Nr(e,r),await Or(e,r),await Gr(e,r),await Ur(e,r),await Fr(e),await jr(e),await Dr(e),await Lr(e),r.tests&&await re(e,{redux:r.redux,i18n:r.i18n}),t.succeed("Features customized.")}catch(o){throw t.fail("Failed to customize features."),o}};import Zi from"node:path";w();P();var Vr=async(e,r)=>{let t=R("Configuring package.json...");try{let o=r.gitRemote,i=r.gitHomepage,n=r.gitIssues;r.gitRemote&&(r.gitRemote.startsWith("git@github.com:")&&(o=r.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"")),i||(i=`${o.replace(/\.git$/,"")}#readme`),n||(n=`${o.replace(/\.git$/,"")}/issues`),o.endsWith(".git")||(o=`${o}.git`)),await k(Zi.join(e,c.PACKAGE_JSON),s=>(s.name=r.projectName,s.version=r.version,s.description=r.description,s.author=r.author,delete s.packageManager,r.gitRemote?(i&&(s.homepage=i),n&&(s.bugs={url:n}),o&&(s.repository={type:"git",url:o})):(delete s.homepage,delete s.bugs,delete s.repository),r.redux||(delete s.dependencies[C.REDUX_TOOLKIT],delete s.dependencies[C.REACT_REDUX],delete s.dependencies[C.REDUX],delete s.dependencies[C.REDUX_PERSIST]),r.httpClient!=="none"||r.reactSecureStorage||delete s.dependencies[C.REACT_SECURE_STORAGE],r.i18n||delete s.dependencies[C.NEXT_INTL],r.darkMode||delete s.dependencies[C.NEXT_THEMES],r.httpClient==="none"?delete s.dependencies[C.AXIOS]:r.httpClient==="fetch"&&delete s.dependencies[C.AXIOS],s)),t.succeed("package.json configured.")}catch(o){throw t.fail("Failed to configure package.json."),o}};import{readdir as Jr}from"node:fs/promises";import N from"node:path";w();P();var Br=async(e,r)=>{await Qi(e,r),await es(e,r),await ts(e,r),await rs(e,r),await os(e,r),await ns(e,r),await is(e,r)},Qi=async(e,r)=>{r.preCommitHooks||(await S(N.join(e,c.HUSKY_DIR)),await T(N.join(e,c.COMMITLINT_CONFIG)),await T(N.join(e,c.LINTSTAGED_RC)),await k(N.join(e,c.PACKAGE_JSON),t=>(delete t.devDependencies[C.HUSKY],delete t.devDependencies[C.COMMITLINT_CLI],delete t.devDependencies[C.COMMITLINT_CONFIG],delete t.devDependencies[C.LINT_STAGED],delete t.scripts.prepare,delete t.scripts.postinstall,delete t.commitlint,delete t["lint-staged"],t)))},es=async(e,r)=>{r.commitizen||(await T(N.join(e,c.CZRC)),await k(N.join(e,c.PACKAGE_JSON),t=>(delete t.devDependencies[C.COMMITIZEN],delete t.devDependencies[C.CZ_CONVENTIONAL_CHANGELOG],delete t.config?.commitizen,t.config&&Object.keys(t.config).length===0&&delete t.config,delete t.scripts.commit,t)))},ts=async(e,r)=>{r.ci||await S(N.join(e,c.GITHUB_WORKFLOWS))},rs=async(e,r)=>{let t=N.join(e,c.GITHUB_DIR);if(!r.keepTemplates)await S(N.join(t,c.GITHUB_ISSUE_TEMPLATE)),await T(N.join(t,c.GITHUB_PR_TEMPLATE));else{let o=N.join(t,c.GITHUB_ISSUE_TEMPLATE),i=N.join(t,c.GITHUB_PR_TEMPLATE),n=s=>s.replace(/Teispace/g,r.company).replace(/support@teispace\.com/g,r.email).replace(/Next\.js Starter/g,r.projectName).replace(/\[AUTHOR\]/g,r.author).replace(/\[COMPANY\]/g,r.company).replace(/\[EMAIL\]/g,r.email);if(m(i)){let s=await d(i);s=n(s),await f(i,s)}try{if(m(o)){let s=await Jr(o);for(let a of s){let p=N.join(o,a),u=await d(p);u=n(u),await f(p,u)}}}catch{}}},os=async(e,r)=>{let t=[c.CODE_OF_CONDUCT,c.CONTRIBUTING,c.SECURITY];for(let o of t)r.communityFiles.includes(o)||await T(N.join(e,o))},ns=async(e,r)=>{if(r.docker){let t=N.join(e,c.ENV_EXAMPLE);if(m(t)){let o=await d(t),i=(n,s)=>{let a=new RegExp(`${n}=.*`);a.test(o)?o=o.replace(a,`${n}=${s}`):o+=`${n}=${s}
178
+ `};i("CONTAINER_NAME",r.containerName||"next-app"),i("IMAGE_NAME",r.imageName||"nextjs-starter"),i("IMAGE_TAG",r.imageTag||"latest"),await f(t,o)}}else{await T(N.join(e,c.DOCKERFILE)),await T(N.join(e,c.DOCKER_COMPOSE)),await T(N.join(e,c.DOCKERIGNORE));let t=N.join(e,c.ENV_EXAMPLE);if(m(t)){let o=await d(t);o=o.replace(/# Docker Compose Configuration\n/,""),o=o.replace(/CONTAINER_NAME=.*\n/,""),o=o.replace(/IMAGE_NAME=.*\n/,""),o=o.replace(/IMAGE_TAG=.*\n/,""),await f(t,o)}}},is=async(e,r)=>{let t=async n=>{let s=await Jr(n,{withFileTypes:!0}),a=[];for(let p of s){let u=N.join(n,p.name);p.isDirectory()&&p.name!=="node_modules"&&p.name!==".git"?a.push(...await t(u)):p.isFile()&&p.name.toLowerCase()==="readme.md"&&a.push(u)}return a},o=await t(e),i=N.join(e,c.README);for(let n of o)n!==i&&await T(n);if(r.readme){let n=`# ${r.projectName}
179
179
 
180
180
  ${r.description}
181
181
 
@@ -188,27 +188,27 @@ ${r.packageManager==="npm"?"npm run dev":`${r.packageManager} dev`}
188
188
  \`\`\`
189
189
 
190
190
  Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
191
- `;await u(n,i)}else await S(n)};C();T();import it from"node:path";var gr=async(e,r)=>{let t=[];r.i18n&&t.push("import { type AbstractIntlMessages, NextIntlClientProvider } from 'next-intl';"),r.darkMode&&t.push("import { CustomThemeProvider } from '@/providers';"),r.redux&&t.push("import type { AppState } from '@/store';"),r.i18n&&t.push("import type { SupportedLocale } from '@/types/i18n';"),r.redux&&t.push("import { StoreProvider } from './StoreProvider';");let o=["children: React.ReactNode;"],n=["children"];r.i18n&&(o.push("locale: SupportedLocale;"),o.push("messages: AbstractIntlMessages;"),o.push("timeZone: string;"),n.push("locale","messages","timeZone")),r.redux&&(o.push("preloadedState?: Partial<AppState>;"),n.push("preloadedState"));let i="{children}";r.i18n&&(i=`<NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>
192
- ${i}
193
- </NextIntlClientProvider>`),r.darkMode&&(i=`<CustomThemeProvider>
194
- ${i}
195
- </CustomThemeProvider>`),r.redux&&(i=`<StoreProvider preloadedState={preloadedState}>
196
- ${i}
197
- </StoreProvider>`),i==="{children}"&&(i="<>{children}</>");let s=`type RootProviderProps = {
191
+ `;await f(i,n)}else await T(i)};w();P();import At from"node:path";var Xr=async(e,r)=>{let t=[];r.i18n&&t.push("import { type AbstractIntlMessages, NextIntlClientProvider } from 'next-intl';"),r.darkMode&&t.push("import { CustomThemeProvider } from '@/providers';"),r.redux&&t.push("import type { AppState } from '@/store';"),r.i18n&&t.push("import type { SupportedLocale } from '@/types/i18n';"),r.redux&&t.push("import { StoreProvider } from './StoreProvider';");let o=["children: React.ReactNode;"],i=["children"];r.i18n&&(o.push("locale: SupportedLocale;"),o.push("messages: AbstractIntlMessages;"),o.push("timeZone: string;"),i.push("locale","messages","timeZone")),r.redux&&(o.push("preloadedState?: Partial<AppState>;"),i.push("preloadedState"));let n="{children}";r.i18n&&(n=`<NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>
192
+ ${n}
193
+ </NextIntlClientProvider>`),r.darkMode&&(n=`<CustomThemeProvider>
194
+ ${n}
195
+ </CustomThemeProvider>`),r.redux&&(n=`<StoreProvider preloadedState={preloadedState}>
196
+ ${n}
197
+ </StoreProvider>`),n==="{children}"&&(n="<>{children}</>");let s=`type RootProviderProps = {
198
198
  ${o.join(`
199
199
  `)}
200
- };`,c=`'use client';
200
+ };`,a=`'use client';
201
201
  ${t.join(`
202
202
  `)}
203
203
 
204
204
  ${s}
205
205
 
206
- export const RootProvider = ({ ${n.join(", ")} }: RootProviderProps) => {
206
+ export const RootProvider = ({ ${i.join(", ")} }: RootProviderProps) => {
207
207
  return (
208
- ${i}
208
+ ${n}
209
209
  );
210
210
  };
211
- `;await u(it.join(e,a.ROOT_PROVIDER),c)},hr=async(e,r)=>{if(r.i18n)return;let t=`\`\${livvic.variable} ${r.darkMode?"bg-light antialiased dark:bg-dark":"antialiased"}\``,o=(r.redux,""),n=`import type { Metadata } from 'next';
211
+ `;await f(At.join(e,c.ROOT_PROVIDER),a)},Yr=async(e,r)=>{if(r.i18n)return;let t=`\`\${livvic.variable} ${r.darkMode?"bg-light antialiased dark:bg-dark":"antialiased"}\``,o=(r.redux,""),i=`import type { Metadata } from 'next';
212
212
  import '@/styles/globals.css';
213
213
  import { Livvic } from 'next/font/google';
214
214
  import { RootProvider } from '@/providers';
@@ -240,10 +240,10 @@ export default function RootLayout({
240
240
  </html>
241
241
  );
242
242
  }
243
- `;await u(it.join(e,a.ROOT_LAYOUT),n);let i=r.redux?`import { Counter } from '@/features/counter';
243
+ `;await f(At.join(e,c.ROOT_LAYOUT),i);let n=r.redux?`import { Counter } from '@/features/counter';
244
244
 
245
245
  `:"",s=r.redux?`
246
- <Counter />`:"",c=`${i}export default function Home() {
246
+ <Counter />`:"",a=`${n}export default function Home() {
247
247
  return (
248
248
  <div className="flex min-h-screen flex-col items-center justify-center p-24">
249
249
  <h1 className="text-4xl font-bold">Welcome to ${r.projectName}</h1>
@@ -251,14 +251,14 @@ export default function RootLayout({
251
251
  </div>
252
252
  );
253
253
  }
254
- `;await u(it.join(e,a.ROOT_PAGE),c)};import Xi from"degit";var xr=async e=>{let r=I("Downloading template...");try{await Xi("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!0}).clone(e),r.succeed("Template downloaded successfully.")}catch(t){throw r.fail("Failed to download template."),t}};var yr=e=>{e.command("init").description("Initialize a new Next.js project").argument("[name]","Project name").action(async r=>{await Yi(r)})},Yi=async e=>{Jt(),m("Welcome to the Teispace Next.js App Creator!"),m("");let r=await Vt(e),t=nt.resolve(process.cwd(),r.projectName);l(t)&&(console.error(re.red(`Error: Directory ${r.projectName} already exists.`)),process.exit(1));let o=I("Initializing project..."),n=async()=>{if(l(t)){o.stop(),console.log(re.yellow(`
255
- Cleaning up: Deleting directory ${r.projectName}...`));try{await P(t),console.log(re.green("Cleanup successful."))}catch(s){console.error(re.red(`Failed to clean up directory ${r.projectName}:`),s)}}},i=async()=>{console.log(re.red(`
256
- Process interrupted. Cleaning up...`)),await n(),process.exit(1)};process.on("SIGINT",i),process.on("SIGTERM",i);try{if(await xr(t),await dr(t,r),await mr(t,r),o.text="Generating code...",await gr(t,r),await hr(t,r),o.text="Setting up developer tools...",await fr(t,r),o.text="Initializing Git...",await Bt(t,r.gitRemote,r.pushToRemote),o.text="Installing dependencies...",await Xt(t,r.packageManager),o.text="Formatting and Linting...",await G(t,r.packageManager,"lint:fix"),r.copyEnv){o.text="Creating .env file...";let s=nt.join(t,".env.example"),c=nt.join(t,".env");l(s)&&await(await import("node:fs/promises")).copyFile(s,c)}process.off("SIGINT",i),process.off("SIGTERM",i),o.succeed(re.green(`Project ${r.projectName} created successfully!`)),m(""),m("To get started:"),m(re.cyan(` cd ${r.projectName}`)),m(re.cyan(` ${r.packageManager==="npm"?"npm run dev":`${r.packageManager} dev`}`)),m("")}catch(s){o.fail("Failed to create project."),console.error(s),await n(),process.exit(1)}};import xt from"node:path";import V from"picocolors";U();import{mkdir as Cr,writeFile as ct}from"node:fs/promises";import le from"node:path";T();var at=e=>{let{componentName:r,isClient:t,hasI18n:o}=e,n=e.translationNamespace||r,i=[];return(t||o)&&i.push("'use client';"),o&&i.push("import { useTranslations } from 'next-intl';"),i.push(""),i.push(`export function ${r}() {`),o?(i.push(` const t = useTranslations('${n}');`),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>${r}</h2>`),i.push(" </div>"),i.push(" );")),i.push("}"),i.push(""),i.join(`
257
- `)},vr=e=>`export { ${e.componentName} } from './${e.componentName}';
258
- `;var pt=async e=>{let{name:r,projectPath:t,isClient:o,hasI18n:n,featurePath:i}=e,s=R(r);i?await qi(s,t,i,o,n):await Zi(s,r,t,o,n)},qi=async(e,r,t,o,n)=>{let i=le.join(r,t,"components");await Cr(i,{recursive:!0}),await ct(le.join(i,`${e}.tsx`),at({componentName:e,isClient:o,hasI18n:n}))},Zi=async(e,r,t,o,n)=>{let i=le.join(t,"src","components","common",e);await Cr(i,{recursive:!0}),await ct(le.join(i,`${e}.tsx`),at({componentName:e,isClient:o,hasI18n:n})),await ct(le.join(i,"index.ts"),vr({componentName:e}));let s=le.join(t,"src","components","common","index.ts");await Qi(s,`export { ${e} } from './${e}';
259
- `);let c=le.join(t,"src","components","index.ts");await en(c)},Qi=async(e,r)=>{let t="";l(e)&&(t=await d(e)),t.includes(r.trim())||(t+=r,await u(e,t))},en=async e=>{let r="";l(e)&&(r=await d(e));let t=`export * from './common';
260
- `;r.includes(t.trim())||(r+=t,await u(e,r))};import{writeFile as tn}from"node:fs/promises";import rn from"node:path";var Er=e=>{let{camelName:r,pascalName:t,httpClient:o}=e,n=o==="axios"?"import { axiosClient } from '@/lib/utils/http';":"import { fetchClient } from '@/lib/utils/http';",i=o==="axios"?"axiosClient":"fetchClient";return`import { AppApis } from '@/lib/config';
261
- ${n}
254
+ `;await f(At.join(e,c.ROOT_PAGE),a)};import ss from"degit";var Kr=async e=>{let r=R("Downloading template...");try{await ss("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!0}).clone(e),r.succeed("Template downloaded successfully.")}catch(t){throw r.fail("Failed to download template."),t}};var qr=e=>{e.command("init").description("Initialize a new Next.js project").argument("[name]","Project name").action(async r=>{await as(r)})},be=async(e,r,t,o)=>{let i=R(e);o.current=i;try{let n=await t();return i.succeed(r),n}finally{o.current===i&&(o.current=null)}},as=async e=>{Sr(),l("Welcome to the Teispace Next.js App Creator!"),l("");let r=await Rr(e),t=kt.resolve(process.cwd(),r.projectName);m(t)&&(console.error(ne.red(`Error: Directory ${r.projectName} already exists.`)),process.exit(1));let o={current:null},i=async()=>{if(m(t)){o.current?.stop(),o.current=null,console.log(ne.yellow(`
255
+ Cleaning up: Deleting directory ${r.projectName}...`));try{await S(t),console.log(ne.green("Cleanup successful."))}catch(s){console.error(ne.red(`Failed to clean up directory ${r.projectName}:`),s)}}},n=async()=>{console.log(ne.red(`
256
+ Process interrupted. Cleaning up...`)),await i(),process.exit(1)};process.on("SIGINT",n),process.on("SIGTERM",n);try{if(await Kr(t),await Vr(t,r),await zr(t,r),await be("Generating providers and layout...","Providers and layout generated.",async()=>{await Xr(t,r),await Yr(t,r)},o),await be("Setting up developer tools...","Developer tools configured.",()=>Br(t,r),o),await be("Initializing Git...","Git initialized.",()=>Cr(t,r.gitRemote,r.pushToRemote),o),await be("Installing dependencies...","Dependencies installed.",()=>Tr(t,r.packageManager),o),await be("Formatting and linting...","Formatted.",()=>U(t,r.packageManager,"lint:fix"),o),r.copyEnv){let s=kt.join(t,".env.example"),a=kt.join(t,".env");m(s)&&await(await import("node:fs/promises")).copyFile(s,a)}process.off("SIGINT",n),process.off("SIGTERM",n),l(""),l(ne.green(`\u2728 Project ${r.projectName} created successfully!`)),l(""),l("To get started:"),l(ne.cyan(` cd ${r.projectName}`)),l(ne.cyan(` ${r.packageManager==="npm"?"npm run dev":`${r.packageManager} dev`}`)),l("")}catch(s){o.current?.fail("Failed to create project."),o.current=null,console.error(s),await i(),process.exit(1)}};import Xt from"node:path";import q from"picocolors";L();import{mkdir as to,writeFile as Ft}from"node:fs/promises";import ge from"node:path";P();var _t=e=>{let{componentName:r,isClient:t,hasI18n:o}=e,i=e.translationNamespace||r,n=[];return(t||o)&&n.push("'use client';"),o&&n.push("import { useTranslations } from 'next-intl';"),n.push(""),n.push(`export function ${r}() {`),o?(n.push(` const t = useTranslations('${i}');`),n.push(""),n.push(" return ("),n.push(" <div>"),n.push(" <h2>{t('title')}</h2>"),n.push(" </div>"),n.push(" );")):(n.push(" return ("),n.push(" <div>"),n.push(` <h2>${r}</h2>`),n.push(" </div>"),n.push(" );")),n.push("}"),n.push(""),n.join(`
257
+ `)},eo=e=>`export { ${e.componentName} } from './${e.componentName}';
258
+ `;var jt=async e=>{let{name:r,projectPath:t,isClient:o,hasI18n:i,featurePath:n}=e,s=b(r);n?await ms(s,t,n,o,i):await ds(s,r,t,o,i)},ms=async(e,r,t,o,i)=>{let n=ge.join(r,t,"components");await to(n,{recursive:!0}),await Ft(ge.join(n,`${e}.tsx`),_t({componentName:e,isClient:o,hasI18n:i}))},ds=async(e,r,t,o,i)=>{let n=ge.join(t,"src","components","common",e);await to(n,{recursive:!0}),await Ft(ge.join(n,`${e}.tsx`),_t({componentName:e,isClient:o,hasI18n:i})),await Ft(ge.join(n,"index.ts"),eo({componentName:e}));let s=ge.join(t,"src","components","common","index.ts");await us(s,`export { ${e} } from './${e}';
259
+ `);let a=ge.join(t,"src","components","index.ts");await fs(a)},us=async(e,r)=>{let t="";m(e)&&(t=await d(e)),t.includes(r.trim())||(t+=r,await f(e,t))},fs=async e=>{let r="";m(e)&&(r=await d(e));let t=`export * from './common';
260
+ `;r.includes(t.trim())||(r+=t,await f(e,r))};import{writeFile as gs}from"node:fs/promises";import hs from"node:path";var ro=e=>{let{camelName:r,pascalName:t,httpClient:o}=e,i=o==="axios"?"import { axiosClient } from '@/lib/utils/http';":"import { fetchClient } from '@/lib/utils/http';",n=o==="axios"?"axiosClient":"fetchClient";return`import { AppApis } from '@/lib/config';
261
+ ${i}
262
262
  import type { ResultAsync } from '@/types';
263
263
 
264
264
  /**
@@ -286,33 +286,33 @@ export interface Update${t}Dto {
286
286
 
287
287
  export const ${r}Service = {
288
288
  getAll: (): ResultAsync<${t}Summary[]> => {
289
- return ${i}.get<${t}Summary[]>(AppApis.${r}.getAll);
289
+ return ${n}.get<${t}Summary[]>(AppApis.${r}.getAll);
290
290
  },
291
291
 
292
292
  getById: (id: string): ResultAsync<${t}Detail> => {
293
- return ${i}.get<${t}Detail>(AppApis.${r}.getById(id));
293
+ return ${n}.get<${t}Detail>(AppApis.${r}.getById(id));
294
294
  },
295
295
 
296
296
  create: (data: Create${t}Dto): ResultAsync<${t}Detail> => {
297
- return ${i}.post<${t}Detail>(AppApis.${r}.create, data);
297
+ return ${n}.post<${t}Detail>(AppApis.${r}.create, data);
298
298
  },
299
299
 
300
300
  update: (id: string, data: Update${t}Dto): ResultAsync<${t}Detail> => {
301
- return ${i}.patch<${t}Detail>(AppApis.${r}.update(id), data);
301
+ return ${n}.patch<${t}Detail>(AppApis.${r}.update(id), data);
302
302
  },
303
303
 
304
304
  delete: (id: string): ResultAsync<void> => {
305
- return ${i}.delete<void>(AppApis.${r}.delete(id));
305
+ return ${n}.delete<void>(AppApis.${r}.delete(id));
306
306
  },
307
307
  };
308
- `},Ir=e=>{let{camelName:r,kebabName:t}=e;return` ${r}: {
308
+ `},oo=e=>{let{camelName:r,kebabName:t}=e;return` ${r}: {
309
309
  base: \`\${API_PREFIX}/${t}\`,
310
310
  getAll: \`\${API_PREFIX}/${t}\`,
311
311
  getById: (id: string) => \`\${API_PREFIX}/${t}/\${id}\`,
312
312
  create: \`\${API_PREFIX}/${t}\`,
313
313
  update: (id: string) => \`\${API_PREFIX}/${t}/\${id}\`,
314
314
  delete: (id: string) => \`\${API_PREFIX}/${t}/\${id}\`,
315
- },`};var lt=async e=>{let{name:r,outputPath:t,httpClient:o}=e,n=$(r),i=R(r);await tn(rn.join(t,`${r}.service.ts`),Er({camelName:n,pascalName:i,httpClient:o}))};import{mkdir as an,writeFile as He}from"node:fs/promises";import M from"node:path";import{writeFile as on}from"node:fs/promises";import nn from"node:path";var Rr=e=>{let{camelName:r,httpClient:t}=e;return`import { AppApis } from '@/lib/config';
315
+ },`};var Dt=async e=>{let{name:r,outputPath:t,httpClient:o}=e,i=A(r),n=b(r);await gs(hs.join(t,`${r}.service.ts`),ro({camelName:i,pascalName:n,httpClient:o}))};import{mkdir as vs,writeFile as pt}from"node:fs/promises";import V from"node:path";import{writeFile as ys}from"node:fs/promises";import xs from"node:path";var no=e=>{let{camelName:r,httpClient:t}=e;return`import { AppApis } from '@/lib/config';
316
316
  ${t==="axios"?"import { axiosClient } from '@/lib/utils/http';":"import { fetchClient } from '@/lib/utils/http';"}
317
317
  import type { ResultAsync } from '@/types';
318
318
 
@@ -321,16 +321,16 @@ export const ${r}Service = {
321
321
  return ${t==="axios"?"axiosClient":"fetchClient"}.get<string>(AppApis.${r}.getAll);
322
322
  },
323
323
  };
324
- `};var ye=async e=>{let{name:r,outputPath:t,httpClient:o}=e,n=$(r);await on(nn.join(t,`${r}.service.ts`),Rr({camelName:n,httpClient:o}))};import{mkdir as sn,writeFile as Pe}from"node:fs/promises";import Te from"node:path";var Nr=e=>{let{sliceName:r,withPersist:t}=e;return`export * from './${r}.slice';
324
+ `};var Ne=async e=>{let{name:r,outputPath:t,httpClient:o}=e,i=A(r);await ys(xs.join(t,`${r}.service.ts`),no({camelName:i,httpClient:o}))};import{mkdir as Ps,writeFile as Ie}from"node:fs/promises";import Ae from"node:path";var io=e=>{let{sliceName:r,withPersist:t}=e;return`export * from './${r}.slice';
325
325
  export * from './${r}.selectors';
326
326
  export * from './${r}.types';${t?`
327
327
  export * from './persist';`:""}
328
- `},br=e=>{let{featureName:r,componentName:t,hookName:o,withStore:n,withService:i}=e;return`export { default as ${t} } from './components/${t}';
328
+ `},so=e=>{let{featureName:r,componentName:t,hookName:o,withStore:i,withService:n}=e;return`export { default as ${t} } from './components/${t}';
329
329
  export { ${o} } from './hooks/${o}';
330
- export * from './types/${r}.types';${n?`
331
- export * from './store';`:""}${i?`
330
+ export * from './types/${r}.types';${i?`
331
+ export * from './store';`:""}${n?`
332
332
  export * from './services/${r}.service';`:""}
333
- `};var $r=e=>{let{componentName:r,camelName:t,typesImportPath:o}=e;return`import type { PersistConfig } from 'redux-persist';
333
+ `};var ao=e=>{let{componentName:r,camelName:t,typesImportPath:o}=e;return`import type { PersistConfig } from 'redux-persist';
334
334
  import storage from 'redux-persist/lib/storage';
335
335
  import type { ${r}State } from '${o}';
336
336
 
@@ -339,11 +339,11 @@ export const ${t}PersistConfig: PersistConfig<${r}State> = {
339
339
  storage,
340
340
  // whitelist: ['someField'], // Specify which fields to persist
341
341
  };
342
- `};var Ar=e=>{let{componentName:r,camelName:t,sliceName:o}=e;return`import { RootState } from '@/store/rootReducer';
342
+ `};var co=e=>{let{componentName:r,camelName:t,sliceName:o}=e;return`import { RootState } from '@/store/rootReducer';
343
343
 
344
344
  export const select${r}State = (state: RootState) => state.${t};
345
345
  export { setLoading, setError, resetState } from './${o}.slice';
346
- `};var Or=e=>{let{componentName:r,camelName:t,typesImportPath:o}=e;return`import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
346
+ `};var po=e=>{let{componentName:r,camelName:t,typesImportPath:o}=e;return`import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
347
347
  import type { ${r}State } from '${o}';
348
348
 
349
349
  const initialState: ${r}State = {
@@ -372,13 +372,13 @@ export const ${t}Slice = createSlice({
372
372
  export const { setLoading, setError, resetState } = ${t}Slice.actions;
373
373
 
374
374
  export const ${t}Reducer = ${t}Slice.reducer;
375
- `};var Ge=e=>{let{componentName:r,withStore:t}=e;return`export interface ${r}State {
375
+ `};var ct=e=>{let{componentName:r,withStore:t}=e;return`export interface ${r}State {
376
376
  ${t?`loading: boolean;
377
377
  error: string | null;
378
378
  // Add your state properties here`:`// Add your state properties here
379
379
  // example: value: string;`}
380
380
  }
381
- `};var Se=async e=>{let{name:r,outputPath:t,persist:o,typesImportPath:n=`./${r}.types`}=e;await sn(t,{recursive:!0});let i=R(r),s=$(r);await Promise.all([Pe(Te.join(t,`${r}.types.ts`),Ge({componentName:i,withStore:!0})),Pe(Te.join(t,`${r}.slice.ts`),Or({componentName:i,camelName:s,typesImportPath:n})),Pe(Te.join(t,`${r}.selectors.ts`),Ar({componentName:i,camelName:s,sliceName:r})),...o?[Pe(Te.join(t,"persist.ts"),$r({componentName:i,camelName:s,typesImportPath:n}))]:[],Pe(Te.join(t,"index.ts"),Nr({sliceName:r,withPersist:o}))])};var _r=e=>{let{componentName:r,hookName:t}=e;return`'use client';
381
+ `};var ke=async e=>{let{name:r,outputPath:t,persist:o,typesImportPath:i=`./${r}.types`}=e;await Ps(t,{recursive:!0});let n=b(r),s=A(r);await Promise.all([Ie(Ae.join(t,`${r}.types.ts`),ct({componentName:n,withStore:!0})),Ie(Ae.join(t,`${r}.slice.ts`),po({componentName:n,camelName:s,typesImportPath:i})),Ie(Ae.join(t,`${r}.selectors.ts`),co({componentName:n,camelName:s,sliceName:r})),...o?[Ie(Ae.join(t,"persist.ts"),ao({componentName:n,camelName:s,typesImportPath:i}))]:[],Ie(Ae.join(t,"index.ts"),io({sliceName:r,withPersist:o}))])};var lo=e=>{let{componentName:r,hookName:t}=e;return`'use client';
382
382
  import { ${t} } from '../hooks/${t}';
383
383
 
384
384
  export function ${r}() {
@@ -393,7 +393,7 @@ export function ${r}() {
393
393
  }
394
394
 
395
395
  export default ${r};
396
- `};var kr=e=>{let{hookName:r,componentName:t,featureName:o}=e;return`'use client';
396
+ `};var mo=e=>{let{hookName:r,componentName:t,featureName:o}=e;return`'use client';
397
397
  import { useAppDispatch, useAppSelector } from '@/store/hooks';
398
398
  import { select${t}State, setLoading, setError } from '../store/${o}.selectors';
399
399
 
@@ -417,7 +417,7 @@ export const ${r} = () => {
417
417
  setError: handleSetError,
418
418
  } as const;
419
419
  };
420
- `},jr=e=>{let{hookName:r}=e;return`'use client';
420
+ `},uo=e=>{let{hookName:r}=e;return`'use client';
421
421
  import { useState } from 'react';
422
422
 
423
423
  export const ${r} = () => {
@@ -429,15 +429,36 @@ export const ${r} = () => {
429
429
  // Add your methods here
430
430
  } as const;
431
431
  };
432
- `};var mt=async e=>{let{name:r,outputPath:t,createStore:o,persistStore:n,createService:i,httpClient:s}=e,c=R(r),p=`use${c}`,f=[M.join(t,"components"),M.join(t,"hooks"),M.join(t,"types"),...o?[M.join(t,"store")]:[],...i?[M.join(t,"services")]:[]];await Promise.all(f.map(g=>an(g,{recursive:!0}))),await Promise.all([He(M.join(t,"components",`${c}.tsx`),_r({componentName:c,hookName:p})),He(M.join(t,"hooks",`${p}.ts`),o?kr({hookName:p,componentName:c,featureName:r}):jr({hookName:p})),He(M.join(t,"types",`${r}.types.ts`),Ge({componentName:c,withStore:o})),He(M.join(t,"index.ts"),br({featureName:r,componentName:c,hookName:p,withStore:o,withService:i}))]),o&&await Se({name:r,outputPath:M.join(t,"store"),persist:n,typesImportPath:`../types/${r}.types`}),i&&s&&await ye({name:r,outputPath:M.join(t,"services"),httpClient:s})};import{mkdir as cn,writeFile as pn}from"node:fs/promises";import dt from"node:path";var Fr=e=>{let{hookName:r,isClient:t}=e,o=[];return t&&o.push("'use client';"),o.push("import { useState, useCallback } from 'react';"),o.push(""),o.push(`export const ${r} = () => {`),o.push(" const [loading, setLoading] = useState(false);"),o.push(" const [error, setError] = useState<string | null>(null);"),o.push(""),o.push(" const execute = useCallback(async () => {"),o.push(" setLoading(true);"),o.push(" setError(null);"),o.push(" try {"),o.push(" // Add your logic here"),o.push(" } catch (err) {"),o.push(" setError(err instanceof Error ? err.message : 'An error occurred');"),o.push(" } finally {"),o.push(" setLoading(false);"),o.push(" }"),o.push(" }, []);"),o.push(""),o.push(" return {"),o.push(" loading,"),o.push(" error,"),o.push(" execute,"),o.push(" } as const;"),o.push("};"),o.push(""),o.join(`
433
- `)};var ut=async e=>{let{name:r,projectPath:t,isClient:o,featurePath:n}=e,s=`use${R(r)}`,c;n?c=dt.join(t,n,"hooks"):c=dt.join(t,"src","hooks"),await cn(c,{recursive:!0}),await pn(dt.join(c,`${s}.ts`),Fr({hookName:s,isClient:o}))};T();import{copyFile as ln,readFile as mn,writeFile as dn}from"node:fs/promises";import we from"node:path";var ft=async e=>{let{code:r,name:t,country:o,flag:n,projectPath:i,copyTranslations:s}=e;await un(i,r,s),await fn(i,r),await gn(i,r,t,o,n)},un=async(e,r,t)=>{let o=we.join(e,"src","i18n","translations"),n=we.join(o,"en.json"),i=we.join(o,`${r}.json`);if(t)await ln(n,i);else{let s=await mn(n,"utf-8"),c=JSON.parse(s),p=Dr(c);await dn(i,`${JSON.stringify(p,null,2)}
434
- `)}},Dr=e=>{let r={};for(let[t,o]of Object.entries(e))typeof o=="object"&&o!==null?r[t]=Dr(o):r[t]="";return r},fn=async(e,r)=>{let t=we.join(e,"src","types","i18n.ts");if(!l(t))return;let o=await d(t),n=/export type SupportedLocale = (.*);/,i=o.match(n);if(i&&!i[1].includes(`'${r}'`)){let s=`${i[1]} | '${r}'`;o=o.replace(n,`export type SupportedLocale = ${s};`),await u(t,o)}},gn=async(e,r,t,o,n)=>{let i=we.join(e,"src","lib","config","app-locales.ts");if(!l(i))return;let s=await d(i);if(s.includes(`locale: '${r}'`))return;let c=s.lastIndexOf("];");if(c===-1)return;let p=` {
432
+ `};var Lt=async e=>{let{name:r,outputPath:t,createStore:o,persistStore:i,createService:n,httpClient:s}=e,a=b(r),p=`use${a}`,u=[V.join(t,"components"),V.join(t,"hooks"),V.join(t,"types"),...o?[V.join(t,"store")]:[],...n?[V.join(t,"services")]:[]];await Promise.all(u.map(g=>vs(g,{recursive:!0}))),await Promise.all([pt(V.join(t,"components",`${a}.tsx`),lo({componentName:a,hookName:p})),pt(V.join(t,"hooks",`${p}.ts`),o?mo({hookName:p,componentName:a,featureName:r}):uo({hookName:p})),pt(V.join(t,"types",`${r}.types.ts`),ct({componentName:a,withStore:o})),pt(V.join(t,"index.ts"),so({featureName:r,componentName:a,hookName:p,withStore:o,withService:n}))]),o&&await ke({name:r,outputPath:V.join(t,"store"),persist:i,typesImportPath:`../types/${r}.types`}),n&&s&&await Ne({name:r,outputPath:V.join(t,"services"),httpClient:s})};import{mkdir as Ss,writeFile as ws}from"node:fs/promises";import Mt from"node:path";var fo=e=>{let{hookName:r,isClient:t}=e,o=[];return t&&o.push("'use client';"),o.push("import { useState, useCallback } from 'react';"),o.push(""),o.push(`export const ${r} = () => {`),o.push(" const [loading, setLoading] = useState(false);"),o.push(" const [error, setError] = useState<string | null>(null);"),o.push(""),o.push(" const execute = useCallback(async () => {"),o.push(" setLoading(true);"),o.push(" setError(null);"),o.push(" try {"),o.push(" // Add your logic here"),o.push(" } catch (err) {"),o.push(" setError(err instanceof Error ? err.message : 'An error occurred');"),o.push(" } finally {"),o.push(" setLoading(false);"),o.push(" }"),o.push(" }, []);"),o.push(""),o.push(" return {"),o.push(" loading,"),o.push(" error,"),o.push(" execute,"),o.push(" } as const;"),o.push("};"),o.push(""),o.join(`
433
+ `)};var Gt=async e=>{let{name:r,projectPath:t,isClient:o,featurePath:i}=e,s=`use${b(r)}`,a;i?a=Mt.join(t,i,"hooks"):a=Mt.join(t,"src","hooks"),await Ss(a,{recursive:!0}),await ws(Mt.join(a,`${s}.ts`),fo({hookName:s,isClient:o}))};import{mkdir as Es}from"node:fs/promises";import lt from"node:path";P();var Cs=e=>`import { setRequestLocale } from 'next-intl/server';
434
+ import type { SupportedLocale } from '@/types/i18n';
435
+
436
+ type Props = {
437
+ children: React.ReactNode;
438
+ params: Promise<{ locale: string }>;
439
+ };
440
+
441
+ export default async function ${e}({ children, params }: Props) {
442
+ const { locale } = await params;
443
+ setRequestLocale(locale as SupportedLocale);
444
+
445
+ return <>{children}</>;
446
+ }
447
+ `,Ts=e=>`type Props = {
448
+ children: React.ReactNode;
449
+ };
450
+
451
+ export default function ${e}({ children }: Props) {
452
+ return <>{children}</>;
453
+ }
454
+ `,go=({componentName:e,hasI18n:r})=>r?Cs(e):Ts(e);var Rs=/^[a-z][a-z0-9-]*$/,bs=/^[a-z][a-z0-9-]*(\/[a-z][a-z0-9-]*)*$/,$s=e=>{if(!Rs.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.`)},Ns=e=>{if(!bs.test(e))throw new Error(`Invalid --at path "${e}". Use kebab-case segments separated by "/", e.g. "dashboard/settings".`)},Ht=async e=>{let{segment:r,at:t,projectPath:o,hasI18n:i,withGroup:n}=e;$s(r),t&&Ns(t);let s=`${b(r)}Layout`,a=n?`(${r})`:r,p=["src","app"];i&&p.push("[locale]"),t&&p.push(...t.split("/")),p.push(a);let u=lt.join(o,...p),g=lt.join(u,"layout.tsx");if(m(g))throw new Error(`Layout already exists at ${lt.relative(o,g)}.`);return await Es(u,{recursive:!0}),await f(g,go({componentName:s,hasI18n:i})),{layoutFile:g,displayPath:lt.relative(o,g),componentName:s}};P();import{copyFile as Is,readFile as As,writeFile as ks}from"node:fs/promises";import Oe from"node:path";var Ut=async e=>{let{code:r,name:t,country:o,flag:i,projectPath:n,copyTranslations:s}=e;await Os(n,r,s),await _s(n,r),await Fs(n,r,t,o,i)},Os=async(e,r,t)=>{let o=Oe.join(e,"src","i18n","translations"),i=Oe.join(o,"en.json"),n=Oe.join(o,`${r}.json`);if(t)await Is(i,n);else{let s=await As(i,"utf-8"),a=JSON.parse(s),p=ho(a);await ks(n,`${JSON.stringify(p,null,2)}
455
+ `)}},ho=e=>{let r={};for(let[t,o]of Object.entries(e))typeof o=="object"&&o!==null?r[t]=ho(o):r[t]="";return r},_s=async(e,r)=>{let t=Oe.join(e,"src","types","i18n.ts");if(!m(t))return;let o=await d(t),i=/export type SupportedLocale = (.*);/,n=o.match(i);if(n&&!n[1].includes(`'${r}'`)){let s=`${n[1]} | '${r}'`;o=o.replace(i,`export type SupportedLocale = ${s};`),await f(t,o)}},Fs=async(e,r,t,o,i)=>{let n=Oe.join(e,"src","lib","config","app-locales.ts");if(!m(n))return;let s=await d(n);if(s.includes(`locale: '${r}'`))return;let a=s.lastIndexOf("];");if(a===-1)return;let p=` {
435
456
  name: '${t}',
436
457
  locale: '${r}',
437
- flag: '${n}',
458
+ flag: '${i}',
438
459
  country: '${o}',
439
460
  },
440
- `;s=s.slice(0,c)+p+s.slice(c),await u(i,s)};import{mkdir as hn,writeFile as gt}from"node:fs/promises";import ve from"node:path";var Lr=e=>{let{componentName:r,routePath:t,hasI18n:o}=e;return o?`import { generateSEOMetadata } from '@/lib/config/seo';
461
+ `;s=s.slice(0,a)+p+s.slice(a),await f(n,s)};import{mkdir as js,writeFile as zt}from"node:fs/promises";import _e from"node:path";var yo=e=>{let{componentName:r,routePath:t,hasI18n:o}=e;return o?`import { generateSEOMetadata } from '@/lib/config/seo';
441
462
  import type { Metadata } from 'next';
442
463
  import { getTranslations, setRequestLocale } from 'next-intl/server';
443
464
  import type { SupportedLocale } from '@/types/i18n';
@@ -483,7 +504,7 @@ export default function ${r}Page() {
483
504
  </div>
484
505
  );
485
506
  }
486
- `},Gr=e=>{let{componentName:r,paramName:t,routePath:o,hasI18n:n}=e;return n?`import { generateSEOMetadata } from '@/lib/config/seo';
507
+ `},xo=e=>{let{componentName:r,paramName:t,routePath:o,hasI18n:i}=e;return i?`import { generateSEOMetadata } from '@/lib/config/seo';
487
508
  import type { Metadata } from 'next';
488
509
  import { getTranslations, setRequestLocale } from 'next-intl/server';
489
510
  import type { SupportedLocale } from '@/types/i18n';
@@ -537,14 +558,14 @@ export default async function ${r}Page(props: Props) {
537
558
  </div>
538
559
  );
539
560
  }
540
- `},Hr=e=>`export default function ${e.componentName}Loading() {
561
+ `},Po=e=>`export default function ${e.componentName}Loading() {
541
562
  return (
542
563
  <div className="flex h-full items-center justify-center">
543
564
  <p>Loading...</p>
544
565
  </div>
545
566
  );
546
567
  }
547
- `,Ur=e=>`'use client';
568
+ `,vo=e=>`'use client';
548
569
 
549
570
  export default function ${e.componentName}Error({
550
571
  error,
@@ -561,7 +582,28 @@ export default function ${e.componentName}Error({
561
582
  </div>
562
583
  );
563
584
  }
564
- `;var ht=async e=>{let{name:r,projectPath:t,hasI18n:o,dynamic:n,withLoading:i=!1,withError:s=!1}=e,c=R(r),p=`/${r}`,f=o?"src/app/[locale]":"src/app",g;n?g=ve.join(t,f,r,`[${n}]`):g=ve.join(t,f,r),await hn(g,{recursive:!0});let y=n?Gr({componentName:c,routePath:n?`${p}/[${n}]`:p,paramName:n,hasI18n:o}):Lr({componentName:c,routePath:p,hasI18n:o});await gt(ve.join(g,"page.tsx"),y),i&&await gt(ve.join(g,"loading.tsx"),Hr({componentName:c})),s&&await gt(ve.join(g,"error.tsx"),Ur({componentName:c}))};T();import Ce from"node:path";var Mr=e=>{let{componentName:r,sourceImportPath:t,testUtilsImportPath:o,hasRedux:n,hasI18n:i}=e,s=[];i&&s.push("messages: {}"),n&&s.push("preloadedState: {}");let c=s.length?`, {
585
+ `;var Vt=async e=>{let{name:r,projectPath:t,hasI18n:o,dynamic:i,withLoading:n=!1,withError:s=!1}=e,a=b(r),p=`/${r}`,u=o?"src/app/[locale]":"src/app",g;i?g=_e.join(t,u,r,`[${i}]`):g=_e.join(t,u,r),await js(g,{recursive:!0});let y=i?xo({componentName:a,routePath:i?`${p}/[${i}]`:p,paramName:i,hasI18n:o}):yo({componentName:a,routePath:p,hasI18n:o});await zt(_e.join(g,"page.tsx"),y),n&&await zt(_e.join(g,"loading.tsx"),Po({componentName:a})),s&&await zt(_e.join(g,"error.tsx"),vo({componentName:a}))};w();import{mkdir as Ds}from"node:fs/promises";import Jt from"node:path";P();var So=(e,r)=>e.endsWith(r)?e:`${e}${r}`,wo=({baseName:e})=>{let r=So(e,"Provider"),t=r.replace(/Provider$/,""),o=`${t}ContextValue`,i=`${t}Context`,n=`use${t}`;return`'use client';
586
+ import { createContext, useContext, useMemo } from 'react';
587
+
588
+ type ${o} = {
589
+ // TODO: declare context value fields
590
+ };
591
+
592
+ const ${i} = createContext<${o} | null>(null);
593
+
594
+ export const ${n} = (): ${o} => {
595
+ const ctx = useContext(${i});
596
+ if (!ctx) {
597
+ throw new Error('${n} must be used within ${r}');
598
+ }
599
+ return ctx;
600
+ };
601
+
602
+ export const ${r} = ({ children }: { children: React.ReactNode }) => {
603
+ const value = useMemo<${o}>(() => ({}), []);
604
+ return <${i}.Provider value={value}>{children}</${i}.Provider>;
605
+ };
606
+ `},Co=e=>So(e,"Provider");var Ls=/^[A-Za-z][A-Za-z0-9-]*$/,Ms=e=>e.includes("-")?b(e):e.charAt(0).toUpperCase()+e.slice(1),Bt=async e=>{let{name:r,projectPath:t}=e;if(!Ls.test(r))throw new Error(`Invalid provider name "${r}". Use kebab-case or PascalCase letters and digits only.`);let o=Ms(r).replace(/Provider$/,""),i=Co(o),n=i,s=Jt.join(t,c.PROVIDERS),a=Jt.join(s,`${n}.tsx`);if(m(a))throw new Error(`Provider already exists at ${Jt.relative(t,a)}.`);return await Ds(s,{recursive:!0}),await f(a,wo({baseName:o})),{componentName:i,fileBaseName:n,providerFile:a}};P();import Fe from"node:path";var To=e=>{let{componentName:r,sourceImportPath:t,testUtilsImportPath:o,hasRedux:i,hasI18n:n}=e,s=[];n&&s.push("messages: {}"),i&&s.push("preloadedState: {}");let a=s.length?`, {
565
607
  ${s.join(`,
566
608
  `)},
567
609
  }`:"";return`import { describe, expect, it } from 'vitest';
@@ -570,14 +612,14 @@ import { ${r} } from '${t}';
570
612
 
571
613
  describe('${r}', () => {
572
614
  it('renders without crashing', () => {
573
- renderWithProviders(<${r} />${c});
615
+ renderWithProviders(<${r} />${a});
574
616
  // TODO: assert something meaningful about the rendered output.
575
617
  expect(screen).toBeDefined();
576
618
  });
577
619
  });
578
- `},Jr=e=>{let{hookName:r,sourceImportPath:t,withStore:o,testUtilsImportPath:n}=e;return o?`import { renderHook } from '@testing-library/react';
620
+ `},Eo=e=>{let{hookName:r,sourceImportPath:t,withStore:o,testUtilsImportPath:i}=e;return o?`import { renderHook } from '@testing-library/react';
579
621
  import { describe, expect, it } from 'vitest';
580
- import { TestProviders } from '${n}';
622
+ import { TestProviders } from '${i}';
581
623
  import { ${r} } from '${t}';
582
624
 
583
625
  describe('${r}', () => {
@@ -596,7 +638,7 @@ describe('${r}', () => {
596
638
  expect(result.current).toBeDefined();
597
639
  });
598
640
  });
599
- `},zr=e=>{let{camelName:r,sourceImportPath:t}=e,o=`${r}Slice`;return`import { describe, expect, it } from 'vitest';
641
+ `},Ro=e=>{let{camelName:r,sourceImportPath:t}=e,o=`${r}Slice`;return`import { describe, expect, it } from 'vitest';
600
642
  import { ${o}, resetState, setError, setLoading } from '${t}';
601
643
 
602
644
  describe('${o}', () => {
@@ -621,100 +663,61 @@ describe('${o}', () => {
621
663
  expect(next).toEqual(initialState);
622
664
  });
623
665
  });
624
- `};var q=async e=>{let{projectPath:r,sourceFile:t,kind:o,symbolName:n}=e,i=Ce.dirname(t),s=Ce.basename(t).replace(/\.(tsx?|jsx?)$/i,""),c=o==="component"?".tsx":".ts",p=Ce.join(i,`${s}.test${c}`),f=`./${s}`,g=xn(i,Ce.join(r,"test","test-utils")),y;return o==="component"?y=Mr({componentName:n,sourceImportPath:f,testUtilsImportPath:g,hasRedux:!!e.hasRedux,hasI18n:!!e.hasI18n}):o==="hook"?y=Jr({hookName:n,sourceImportPath:f,withStore:!!e.hookUsesStore,testUtilsImportPath:e.hookUsesStore?g:void 0}):y=zr({camelName:n,sourceImportPath:f}),await u(p,y),p},xn=(e,r)=>{let t=Ce.relative(e,r).replace(/\\/g,"/");return t.startsWith(".")?t:`./${t}`};import yn from"enquirer";var{prompt:Pn}=yn,Br=async e=>{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"}),r.push({type:"confirm",name:"isClient",message:"Add 'use client' directive?",initial:!1});let t=await Pn(r);return{componentName:e||t.componentName,isClient:t.isClient}};var Xr=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(r,t)=>{try{let o=process.cwd();m(V.cyan(`
666
+ `};var Q=async e=>{let{projectPath:r,sourceFile:t,kind:o,symbolName:i}=e,n=Fe.dirname(t),s=Fe.basename(t).replace(/\.(tsx?|jsx?)$/i,""),a=o==="component"?".tsx":".ts",p=Fe.join(n,`${s}.test${a}`),u=`./${s}`,g=Gs(n,Fe.join(r,"test","test-utils")),y;return o==="component"?y=To({componentName:i,sourceImportPath:u,testUtilsImportPath:g,hasRedux:!!e.hasRedux,hasI18n:!!e.hasI18n}):o==="hook"?y=Eo({hookName:i,sourceImportPath:u,withStore:!!e.hookUsesStore,testUtilsImportPath:e.hookUsesStore?g:void 0}):y=Ro({camelName:i,sourceImportPath:u}),await f(p,y),p},Gs=(e,r)=>{let t=Fe.relative(e,r).replace(/\\/g,"/");return t.startsWith(".")?t:`./${t}`};import Hs from"enquirer";var{prompt:Us}=Hs,bo=async e=>{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"}),r.push({type:"confirm",name:"isClient",message:"Add 'use client' directive?",initial:!1});let t=await Us(r);return{componentName:e||t.componentName,isClient:t.isClient}};var $o=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(r,t)=>{try{let o=process.cwd();l(q.cyan(`
625
667
  \u{1F9E9} Component Generator
626
- `)),h.start("Detecting project setup...");let n=await O(o);h.succeed("Project setup detected");let i=await Br(r),s=R(i.componentName),c=t.client??i.isClient,p=t.i18n??!1,f=Tn(t,n.hasTests);h.start("Generating component..."),await pt({name:i.componentName,projectPath:o,isClient:c||p,hasI18n:p,featurePath:t.feature}),h.succeed("Component generated");let g=null;if(f){let x=t.feature?xt.join(o,t.feature,"components",`${s}.tsx`):xt.join(o,"src/components/common",s,`${s}.tsx`);h.start("Generating test..."),g=await q({projectPath:o,sourceFile:x,kind:"component",symbolName:s,hasRedux:n.hasRedux,hasI18n:n.hasI18n}),h.succeed("Test generated")}let y=t.feature?`${t.feature}/components/${s}.tsx`:`src/components/common/${s}/${s}.tsx`;m(V.green(`
668
+ `)),h.start("Detecting project setup...");let i=await I(o);h.succeed("Project setup detected");let n=await bo(r),s=b(n.componentName),a=t.client??n.isClient,p=t.i18n??!1,u=zs(t,i.hasTests);h.start("Generating component..."),await jt({name:n.componentName,projectPath:o,isClient:a||p,hasI18n:p,featurePath:t.feature}),h.succeed("Component generated");let g=null;if(u){let x=t.feature?Xt.join(o,t.feature,"components",`${s}.tsx`):Xt.join(o,"src/components/common",s,`${s}.tsx`);h.start("Generating test..."),g=await Q({projectPath:o,sourceFile:x,kind:"component",symbolName:s,hasRedux:i.hasRedux,hasI18n:i.hasI18n}),h.succeed("Test generated")}let y=t.feature?`${t.feature}/components/${s}.tsx`:`src/components/common/${s}/${s}.tsx`;l(q.green(`
627
669
  \u2728 Component '${s}' created successfully!
628
- `)),m(V.dim(` \u{1F4C4} ${y}`)),t.feature||(m(V.dim(` \u{1F4C4} src/components/common/${s}/index.ts`)),m(V.dim(" \u{1F4DD} Updated src/components/common/index.ts")),m(V.dim(" \u{1F4DD} Updated src/components/index.ts"))),g&&m(V.dim(` \u{1F9EA} ${xt.relative(o,g)}`)),m(""),m(V.cyan("Usage:")),t.feature?m(V.dim(` import { ${s} } from '${t.feature.replace(/^src\//,"@/")}/components/${s}';`)):m(V.dim(` import { ${s} } from '@/components';`)),m("")}catch(o){h.fail("Component generation failed"),w(`${o}`),process.exit(1)}})},Tn=(e,r)=>e.noTest?!1:e.test?!0:r;import Et from"node:path";import k from"picocolors";U();U();import _n from"node:path";import{readFile as Sn,writeFile as wn}from"node:fs/promises";import vn from"node:path";var yt=(e,r)=>{let t=/import\s+.*\s+from\s+['"].*['"];?\n/g,o=e.match(t);if(o&&o.length>0){let n=o[o.length-1],i=e.lastIndexOf(n);return e.slice(0,i+n.length)+r+`
629
- `+e.slice(i+n.length)}return`${r}
630
- ${e}`},Pt=(e,r,t)=>{let o=/combineReducers\(\{([^}]*)\}\)/s,n=e.match(o);if(!n)throw new Error("Could not find combineReducers in rootReducer.ts");let i=n[1],s=`
631
- ${r}: ${t},`,c=i.trimEnd()+s;return e.replace(o,`combineReducers({${c}
632
- })`)},Ee=(e,r)=>{let t=e.lastIndexOf("} as const;");if(t===-1)throw new Error("Could not find closing brace of AppApis object");let o=e.substring(0,t),n=e.substring(t);return`${o.trimEnd()}
633
- ${r}
634
- ${n}`};var Ie=async e=>{let{serviceName:r,projectPath:t}=e,o=$(r),n=vn.join(t,"src","lib","config","app-apis.ts");try{let i=await Sn(n,"utf-8");if(i.includes(`${o}:`))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=` ${o}: {
635
- base: \`\${API_PREFIX}/${r}\`,
636
- getAll: \`\${API_PREFIX}/${r}\`,
637
- },`;i=Ee(i,s),await wn(n,i)}catch(i){throw new Error(`Failed to register API endpoints: ${i}`,{cause:i})}};import{readFile as Cn,writeFile as En}from"node:fs/promises";import In from"node:path";T();var Tt=async(e,r,t)=>{let o=In.join(e,"src","lib","config","app-paths.ts");if(!l(o))return;let n=await Cn(o,"utf-8"),i=$(r);if(n.includes(`${i}:`))return;let s=n.lastIndexOf("} as const;");if(s===-1)return;let c=` ${i}: '${t}',
638
- `;n=n.slice(0,s)+c+n.slice(s),await En(o,n)};import{readFile as Rn,writeFile as Nn}from"node:fs/promises";import bn from"node:path";var Re=async e=>{let{projectPath:r,name:t,persist:o,importPath:n}=e,i=bn.join(r,"src","store","rootReducer.ts");try{let s=await Rn(i,"utf-8"),c=$(t),p=`${c}Reducer`,f=`${c}PersistConfig`,g=n.replace(/^src\//,"@/"),y=o?`import { ${p}, ${f} } from '${g}';`:`import { ${p} } from '${g}';`;s=yt(s,y);let x=o?`persistReducer(${f}, ${p})`:p;s=Pt(s,c,x),await Nn(i,s)}catch(s){throw new Error(`Failed to register reducer '${t}' in rootReducer: ${s}`,{cause:s})}};T();import{readFile as $n,writeFile as An}from"node:fs/promises";import On from"node:path";var St=async(e,r)=>{let t=On.join(e,"src","i18n","translations","en.json");if(!l(t))return;let o=await $n(t,"utf-8"),n=JSON.parse(o);n[r]||(n[r]={title:r,description:`${r} page description`},await An(t,`${JSON.stringify(n,null,2)}
639
- `))};var wt=()=>[{name:"Project setup detected",spinnerText:"Detecting project setup...",execute:async e=>{e.detection=await O(e.projectPath)}},{name:"Feature files generated",spinnerText:"Generating feature files...",execute:async e=>{await mt({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 Ie({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 Re({projectPath:e.projectPath,name:e.featureName,persist:e.persistStore,importPath:_n.join(e.basePath,e.featureName,"store")})}}];var me=async(e,r)=>{for(let t of e)if(!t.shouldSkip?.(r)){r.spinner.start(t.spinnerText);try{await t.execute(r),r.spinner.succeed(t.name)}catch(o){throw r.spinner.fail(t.name),o}}};var vt=()=>[{name:"Service files generated",spinnerText:"Generating service files...",execute:async e=>{await ye({name:e.serviceName,outputPath:e.servicePath,httpClient:e.httpClient})}},{name:"API endpoints registered",spinnerText:"Registering API endpoints...",execute:async e=>{await Ie({serviceName:e.serviceName,projectPath:e.projectPath})}}];import kn from"node:path";var Ct=()=>[{name:"Slice files generated",spinnerText:"Generating slice files...",execute:async e=>{await Se({name:e.sliceName,outputPath:e.slicePath,persist:e.persistSlice})}},{name:"Slice registered in rootReducer",spinnerText:"Registering slice in rootReducer...",execute:async e=>{await Re({projectPath:e.projectPath,name:e.sliceName,persist:e.persistSlice,importPath:kn.join(e.basePath,e.sliceName)})}}];import jn from"enquirer";var{prompt:Fn}=jn,Yr=async(e,r,t,o,n,i,s)=>{let c=[];e||c.push({type:"input",name:"featureName",message:"What is the feature name?",initial:"my-feature",validate:f=>/^[a-z0-9-]+$/.test(f)?!0:"Feature name must be lowercase and contain only alphanumeric characters and hyphens."}),r&&o===void 0&&n===void 0&&(c.push({type:"confirm",name:"createStore",message:"Generate Redux store for this feature?",initial:!0}),c.push({type:"confirm",name:"persistStore",message:"Enable persistence for this store?",initial:!1,skip(){return!this.state.answers.createStore}})),t&&t!=="none"&&i===void 0&&s===void 0&&(c.push({type:"confirm",name:"createService",message:"Generate API service for this feature?",initial:!0}),t==="both"&&c.push({type:"select",name:"selectedHttpClient",message:"Which HTTP client to use for the service?",choices:["fetch","axios"],initial:0,skip(){return!this.state.answers.createService}}));let p=c.length>0?await Fn(c):{};return{featureName:e||p.featureName,hasRedux:r||!1,createStore:o===!0?!1:n!==void 0?!0:p.createStore||!1,persistStore:n==="persist"?!0:n==="no-persist"?!1:p.persistStore||!1,httpClient:t||"none",createService:i===!0?!1:s!==void 0?!0:p.createService||!1,selectedHttpClient:s||p.selectedHttpClient||(t==="both"?"fetch":t!=="none"?t:void 0)}};var Vr=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(r,t)=>{try{let o=process.cwd();Dn(t),m(k.cyan(`
640
- \u{1F3AF} Feature Generator
641
- `));let n=wt();h.start("Detecting project setup...");let{detectProjectSetup:i}=await Promise.resolve().then(()=>(U(),wr)),s=await i(o);h.succeed("Project setup detected"),m(k.dim(` Redux: ${s.hasRedux?"\u2713":"\u2717"}`)),m(k.dim(` HTTP Client: ${s.httpClient}`)),m(k.dim(` i18n: ${s.hasI18n?"\u2713":"\u2717"}
642
- `));let c=await Yr(r,s.hasRedux,s.httpClient,t.skipStore,t.store,t.skipService,t.service),p=t.path||Et.join("src","features"),f=Et.join(o,p,c.featureName);await oe(o,c.featureName,p)&&(w(`Feature '${c.featureName}' already exists at ${p}!`),process.exit(1)),await me(n.slice(1),{projectPath:o,spinner:h,featureName:c.featureName,basePath:p,featurePath:f,createStore:c.createStore,persistStore:c.persistStore,createService:c.createService,httpClient:c.selectedHttpClient,detection:s}),Ln(c,p)}catch(o){h.fail("Feature generation failed"),w(`${o}`),process.exit(1)}})},Dn=e=>{e.store&&!["persist","no-persist"].includes(e.store)&&(w("Invalid --store option. Use: persist or no-persist"),process.exit(1)),e.service&&!["axios","fetch"].includes(e.service)&&(w("Invalid --service option. Use: axios or fetch"),process.exit(1)),e.skipStore&&e.store&&(w("Cannot use --skip-store and --store together"),process.exit(1)),e.skipService&&e.service&&(w("Cannot use --skip-service and --service together"),process.exit(1))},Ln=(e,r)=>{let t=Et.join(r,e.featureName);m(k.green(`
643
- \u2728 Feature '${e.featureName}' created successfully!
644
- `)),m(k.dim("Generated files:")),m(k.dim(` \u{1F4C2} ${t}/`)),m(k.dim(" \u251C\u2500\u2500 components/")),m(k.dim(" \u251C\u2500\u2500 hooks/")),m(k.dim(" \u251C\u2500\u2500 types/")),e.createStore&&m(k.dim(" \u251C\u2500\u2500 store/")),e.createService&&m(k.dim(" \u251C\u2500\u2500 services/")),m(k.dim(` \u2514\u2500\u2500 index.ts
645
- `)),m(k.cyan("Next steps:"));let o=r.replace(/^src\//,"@/");m(k.dim(` 1. Import and use the feature: import { ${e.featureName} } from '${o}/${e.featureName}'`)),e.createStore&&m(k.dim(` 2. Customize your Redux slice in: ${t}/store/`)),e.createService&&m(k.dim(` 3. Add API methods in: ${t}/services/${e.featureName}.service.ts`)),m("")};import It from"node:path";import ge from"picocolors";U();import Gn from"enquirer";var{prompt:Hn}=Gn,Kr=async e=>e?{hookName:e}:await Hn({type:"input",name:"hookName",message:'Hook name (kebab-case, without "use" prefix):',validate:t=>t?/^[a-z][a-z0-9-]*$/.test(t)?!0:"Use lowercase letters, numbers, and hyphens only":"Hook name is required"});var Wr=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(r,t)=>{try{let o=process.cwd();m(ge.cyan(`
646
- \u{1FA9D} Hook Generator
647
- `));let n=await O(o),i=await Kr(r),c=`use${R(i.hookName)}`,p=Un(t,n.hasTests);h.start("Generating hook..."),await ut({name:i.hookName,projectPath:o,isClient:t.client??!0,featurePath:t.feature}),h.succeed("Hook generated");let f=t.feature?It.join(o,t.feature,"hooks",`${c}.ts`):It.join(o,"src/hooks",`${c}.ts`),g=null;p&&(h.start("Generating test..."),g=await q({projectPath:o,sourceFile:f,kind:"hook",symbolName:c,hookUsesStore:n.hasRedux&&!!t.feature}),h.succeed("Test generated"));let y=t.feature?`${t.feature}/hooks/${c}.ts`:`src/hooks/${c}.ts`;m(ge.green(`
648
- \u2728 Hook '${c}' created successfully!
649
- `)),m(ge.dim(` \u{1F4C4} ${y}`)),g&&m(ge.dim(` \u{1F9EA} ${It.relative(o,g)}`)),m(""),m(ge.cyan("Usage:"));let x=t.feature?`${t.feature.replace(/^src\//,"@/")}/hooks/${c}`:`@/hooks/${c}`;m(ge.dim(` import { ${c} } from '${x}';`)),m("")}catch(o){h.fail("Hook generation failed"),w(`${o}`),process.exit(1)}})},Un=(e,r)=>e.noTest?!1:e.test?!0:r;import zn from"node:path";import K from"picocolors";T();U();import Mn from"enquirer";var{prompt:Jn}=Mn,qr=async e=>{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"},{type:"confirm",name:"copyTranslations",message:"Copy translations from English? (No = empty values)",initial:!1});let t=await Jn(r);return{code:e||t.code,name:t.name,country:t.country,flag:t.flag,copyTranslations:t.copyTranslations}};var Zr=e=>{e.command("locale [code]").description("Add a new locale/language").option("--copy-translations","Copy translations from English instead of empty values").action(async(r,t)=>{try{let o=process.cwd();m(K.cyan(`
650
- \u{1F30D} Locale Generator
651
- `)),h.start("Detecting project setup...");let n=await O(o);h.succeed("Project setup detected"),n.hasI18n||(h.fail("i18n is not set up in this project"),w("Please set up internationalization first"),m(K.dim(`
652
- Run: npx @teispace/next-maker setup --i18n
653
- `)),process.exit(1));let i=await qr(r),s=zn.join(o,"src","i18n","translations",`${i.code}.json`);l(s)&&(w(`Locale '${i.code}' already exists!`),process.exit(1)),h.start("Adding locale..."),await ft({...i,projectPath:o,copyTranslations:t.copyTranslations??i.copyTranslations}),h.succeed("Locale added"),m(K.green(`
654
- \u2728 Locale '${i.code}' (${i.name}) added successfully!
655
- `)),m(K.dim("Updated files:")),m(K.dim(` \u{1F4C4} src/i18n/translations/${i.code}.json`)),m(K.dim(" \u{1F4DD} src/types/i18n.ts (SupportedLocale type)")),m(K.dim(" \u{1F4DD} src/lib/config/app-locales.ts")),m(""),m(K.cyan("Next steps:")),m(K.dim(` 1. Translate: src/i18n/translations/${i.code}.json`)),m(K.dim(` 2. Visit: http://localhost:3000/${i.code}`)),m("")}catch(o){h.fail("Locale generation failed"),w(`${o}`),process.exit(1)}})};import eo from"node:path";import J from"picocolors";U();import Bn from"enquirer";var{prompt:Xn}=Bn,Qr=async e=>{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"}),r.push({type:"confirm",name:"withLoading",message:"Generate loading.tsx?",initial:!0},{type:"confirm",name:"withError",message:"Generate error.tsx?",initial:!0});let t=await Xn(r);return{pageName:e||t.pageName,withLoading:t.withLoading,withError:t.withError}};var to=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(r,t)=>{try{let o=process.cwd();m(J.cyan(`
656
- \u{1F4C4} Page Generator
657
- `)),h.start("Detecting project setup...");let n=await O(o);h.succeed("Project setup detected"),m(J.dim(` i18n: ${n.hasI18n?"\u2713":"\u2717"}
658
- `));let i=await Qr(r),s=i.pageName,c=R(s),p=n.hasI18n?"src/app/[locale]":"src/app";await oe(o,s,p)&&(w(`Page '${s}' already exists at ${p}/${s}!`),process.exit(1)),h.start("Generating page files..."),await ht({name:s,projectPath:o,hasI18n:n.hasI18n,dynamic:t.dynamic,withLoading:t.loading??i.withLoading,withError:t.error??i.withError}),h.succeed("Page files generated"),h.start("Registering route...");let g=t.dynamic?`/${s}/[${t.dynamic}]`:`/${s}`;await Tt(o,s,g),h.succeed("Route registered"),n.hasI18n&&(h.start("Adding translation namespace..."),await St(o,c),h.succeed("Translation namespace added"));let y=t.dynamic?eo.join(p,s,`[${t.dynamic}]`):eo.join(p,s);m(J.green(`
659
- \u2728 Page '${s}' created successfully!
660
- `)),m(J.dim("Generated files:")),m(J.dim(` \u{1F4C2} ${y}/`)),m(J.dim(" \u251C\u2500\u2500 page.tsx")),(t.loading??i.withLoading)&&m(J.dim(" \u251C\u2500\u2500 loading.tsx")),(t.error??i.withError)&&m(J.dim(" \u2514\u2500\u2500 error.tsx")),m(""),n.hasI18n&&(m(J.cyan("Next steps:")),m(J.dim(` 1. Add translations in: src/i18n/translations/en.json \u2192 "${c}"`)),m(J.dim(` 2. Visit: http://localhost:3000/${s}`)),m(""))}catch(o){h.fail("Page generation failed"),w(`${o}`),process.exit(1)}})};import{existsSync as Wn}from"node:fs";import{mkdir as qn}from"node:fs/promises";import Ne from"node:path";import z from"picocolors";U();import{readFile as Yn,writeFile as Vn}from"node:fs/promises";import Kn from"node:path";var ro=async(e,r)=>{let t=$(r),o=Kn.join(e,"src","lib","config","app-apis.ts");try{let n=await Yn(o,"utf-8");if(n.includes(`${t}:`))return;if(!n.match(/export const AppApis = \{[\s\S]*?\} as const;/))throw new Error("Could not find AppApis object in app-apis.ts");let i=Ir({camelName:t,kebabName:r});n=Ee(n,i),await Vn(o,n)}catch(n){throw new Error(`Failed to register CRUD API endpoints: ${n}`,{cause:n})}};import oo from"enquirer";var io=async(e,r,t,o)=>{let n=e||(await oo.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 r!==void 0?i="axios":t!==void 0?i="fetch":o==="axios"?i="axios":o==="fetch"?i="fetch":o==="both"?i=(await oo.prompt({type:"select",name:"httpClient",message:"Choose HTTP client:",choices:["axios","fetch"]})).httpClient:i="axios",{serviceName:n,httpClient:i}};var no=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(r,t)=>{try{let o=process.cwd();t.axios&&t.fetch&&(w("Cannot use --axios and --fetch together"),process.exit(1)),m(z.cyan(`
661
- \u{1F527} Service Generator
662
- `)),h.start("Detecting project setup...");let n=await O(o);h.succeed("Project setup detected"),n.httpClient==="none"&&(h.fail("No HTTP client is setup in this project"),w("Please setup either AxiosClient or FetchClient first"),m(z.dim(`
663
- Check: lib/utils/http/axios-client or lib/utils/http/fetch-client
664
- `)),process.exit(1));let i=[];(n.httpClient==="axios"||n.httpClient==="both")&&i.push("Axios \u2713"),(n.httpClient==="fetch"||n.httpClient==="both")&&i.push("Fetch \u2713"),m(z.dim(` HTTP Clients: ${i.join(", ")}
665
- `));let s=await io(r,t.axios,t.fetch,n.httpClient),{basePath:c,servicePath:p}=Zn(o,s.serviceName,t.path);Wn(p)||await qn(p,{recursive:!0}),De(o,c,`${s.serviceName}.service.ts`)&&(w(`Service '${s.serviceName}' already exists at ${c}!`),process.exit(1)),t.crud?(h.start("Generating CRUD service files..."),await lt({name:s.serviceName,outputPath:p,httpClient:s.httpClient}),h.succeed("CRUD service files generated"),h.start("Registering CRUD API endpoints..."),await ro(o,s.serviceName),h.succeed("CRUD API endpoints registered")):await me(vt(),{projectPath:o,spinner:h,serviceName:s.serviceName,servicePath:p,httpClient:s.httpClient}),Qn(s,c,!!t.crud)}catch(o){h.fail("Service generation failed"),w(`${o}`),process.exit(1)}})},Zn=(e,r,t)=>{let o;if(t){let n=t.replace(/^src\//,"");if(n.startsWith("features/")){let i=n.split("/")[1];o=Ne.join("src","features",i,"services")}else o=Ne.join("src",n)}else o=Ne.join("src","features",r,"services");return{basePath:o,servicePath:Ne.join(e,o)}},Qn=(e,r,t=!1)=>{let o=Ne.join(r,`${e.serviceName}.service.ts`);m(z.green(`
666
- \u2728 ${t?"CRUD ":""}Service '${e.serviceName}' created successfully!
667
- `)),m(z.dim("Generated files:")),m(z.dim(` \u{1F4C4} ${o}
668
- `)),m(z.cyan("Next steps:"));let n=r.replace(/^src\//,"@/");m(z.dim(` 1. Import service: import { ${e.serviceName}Service } from '${n}/${e.serviceName}.service'`)),t?(m(z.dim(" 2. Available methods: getAll, getById, create, update, delete")),m(z.dim(" 3. Update DTO types in the service file"))):m(z.dim(` 2. Use in component: const data = await ${e.serviceName}Service.getAll()`)),m("")};import Ts from"enquirer";import Gt from"picocolors";C();import so from"node:path";import es from"picocolors";T();var Rt=async e=>{let r=I("Adding @next/bundle-analyzer...");try{let t=so.join(e,a.NEXT_CONFIG);if(!l(t))throw new Error(`${a.NEXT_CONFIG} not found.`);let o=await d(t);if(o.includes("@next/bundle-analyzer")){r.fail("@next/bundle-analyzer is already configured.");return}o=`import withBundleAnalyzer from '@next/bundle-analyzer';
669
- ${o}`;let n=/export default (.*?);/,i=o.match(n);if(!i)throw new Error("Could not locate `export default` in next.config.ts.");let c=`const bundleAnalyzer = withBundleAnalyzer({
670
+ `)),l(q.dim(` \u{1F4C4} ${y}`)),t.feature||(l(q.dim(` \u{1F4C4} src/components/common/${s}/index.ts`)),l(q.dim(" \u{1F4DD} Updated src/components/common/index.ts")),l(q.dim(" \u{1F4DD} Updated src/components/index.ts"))),g&&l(q.dim(` \u{1F9EA} ${Xt.relative(o,g)}`)),l(""),l(q.cyan("Usage:")),t.feature?l(q.dim(` import { ${s} } from '${t.feature.replace(/^src\//,"@/")}/components/${s}';`)):l(q.dim(` import { ${s} } from '@/components';`)),l("")}catch(o){h.fail("Component generation failed"),v(`${o}`),process.exit(1)}})},zs=(e,r)=>e.noTest?!1:e.test?!0:r;import j from"picocolors";w();P();import Js from"node:path";w();import No from"node:path";import Vs from"picocolors";P();var je=async e=>{let r=R("Adding @next/bundle-analyzer...");try{let t=No.join(e,c.NEXT_CONFIG);if(!m(t))throw new Error(`${c.NEXT_CONFIG} not found.`);let o=await d(t);if(o.includes("@next/bundle-analyzer")){r.fail("@next/bundle-analyzer is already configured.");return}o=`import withBundleAnalyzer from '@next/bundle-analyzer';
671
+ ${o}`;let i=/export default (.*?);/,n=o.match(i);if(!n)throw new Error("Could not locate `export default` in next.config.ts.");let a=`const bundleAnalyzer = withBundleAnalyzer({
670
672
  enabled: process.env.ANALYZE === 'true',
671
673
  });
672
674
 
673
- export default bundleAnalyzer(${i[1]});`;o=o.replace(n,c),await u(t,o),await j(so.join(e,a.PACKAGE_JSON),p=>(p.scripts=p.scripts??{},p.scripts.analyze||(p.scripts.analyze="ANALYZE=true next build"),p)),r.text="Installing @next/bundle-analyzer...",await ke(e,"@next/bundle-analyzer"),r.succeed(es.green("@next/bundle-analyzer configured."))}catch(t){throw r.fail("Failed to add @next/bundle-analyzer."),t}};import rs from"node:path";import os from"picocolors";T();C();T();import ao from"node:path";import ts from"degit";var co=async(e,r)=>{r.text="Fetching assets from starter repo...",await ts("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},po=async(e,r)=>{let t=ao.join(e,a.THEME_PROVIDER),o=ao.join(r,"src/providers/CustomThemeProvider.tsx");await A(o,t)};C();T();import be from"node:path";C();T();import lo from"node:path";var Ue=async e=>{let r=[lo.join(e,a.ROOT_LAYOUT),lo.join(e,"src/app/[locale]/layout.tsx")];for(let t of r)if(l(t)&&(await d(t)).includes("<body"))return t;for(let t of r)if(l(t))return t;return""};var mo=async e=>{let r=be.join(e,a.THEME_PROVIDER),t=be.join(e,a.GLOBALS_CSS),o=be.join(e,"package.json");if(l(r))return{isSetup:!0,reason:"CustomThemeProvider.tsx exists"};if(l(o)){let n=JSON.parse(await d(o)),i="@teispace/next-themes";if(n.dependencies?.[i]||n.devDependencies?.[i])return{isSetup:!0,reason:`${i} is installed`}}return l(t)&&(await d(t)).includes("@custom-variant dark")?{isSetup:!0,reason:"Dark theme CSS found in globals.css"}:{isSetup:!1,reason:""}},uo=async e=>{let r=be.join(e,a.GLOBALS_CSS),t=be.join(e,a.PROVIDERS_INDEX),o=await Ue(e);if(!l(r)||!o||!l(t))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 o};C();T();import Me from"node:path";var fo=async e=>{let r=Me.join(e,a.PROVIDERS_INDEX),t=await d(r);t.includes("CustomThemeProvider")||(t+=`export * from './CustomThemeProvider';
674
- `,await u(r,t))},go=async e=>{let r=Me.join(e,"src/providers/RootProvider.tsx");if(!l(r))return;let t=await d(r),o="'use client';",n=t.includes(o);if(n&&(t=t.replace(o,"").trim()),t.includes("CustomThemeProvider")||(/import\s*\{[^}]*\}\s*from\s*'@\/providers'/.test(t)?t=t.replace(/(import\s*\{)([^}]*)(\}\s*from\s*'@\/providers')/,(i,s,c,p)=>`${s}${c.trim()?`${c.trim()}, CustomThemeProvider `:" CustomThemeProvider "}${p}`):t=`import { CustomThemeProvider } from '@/providers';
675
- ${t}`),n&&(t=`${o}
676
- ${t}`),!t.includes("<CustomThemeProvider"))if(t.includes("{children}"))t=t.replace(/\{children\}/,"<CustomThemeProvider>{children}</CustomThemeProvider>");else{let i=t.match(/return\s*\(\s*([\s\S]*?)\s*\);/);i&&(t=t.replace(i[0],`return (
675
+ export default bundleAnalyzer(${n[1]});`;o=o.replace(i,a),await f(t,o),await k(No.join(e,c.PACKAGE_JSON),p=>(p.scripts=p.scripts??{},p.scripts.analyze||(p.scripts.analyze="ANALYZE=true next build"),p)),r.text="Installing @next/bundle-analyzer...",await ot(e,"@next/bundle-analyzer"),r.succeed(Vs.green("@next/bundle-analyzer configured."))}catch(t){throw r.fail("Failed to add @next/bundle-analyzer."),t}};var Io={id:"bundle-analyzer",name:"Bundle Analyzer",description:"@next/bundle-analyzer wrapped around the default export",detect:async e=>{let r=Js.join(e,c.NEXT_CONFIG);return m(r)?/@next\/bundle-analyzer/.test(await d(r)):!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/}],apply:je};w();P();import Ys from"node:path";w();import Ao from"node:path";import Bs from"picocolors";P();var Yt=e=>{let r={...e.scripts??{}},t={...e.devDependencies??{}};return r.commit||(r.commit="cz"),t[C.COMMITIZEN]||(t[C.COMMITIZEN]="*"),t[C.CZ_CONVENTIONAL_CHANGELOG]||(t[C.CZ_CONVENTIONAL_CHANGELOG]="*"),{...e,scripts:r,devDependencies:t}},Kt=e=>{let r=e.devDependencies??{},t=[];return r[C.COMMITIZEN]||t.push(C.COMMITIZEN),r[C.CZ_CONVENTIONAL_CHANGELOG]||t.push(C.CZ_CONVENTIONAL_CHANGELOG),t};var Xs=`${JSON.stringify({path:"cz-conventional-changelog"},null,2)}
676
+ `,De=async e=>{let r=R("Setting up Commitizen...");try{let t=Ao.join(e,c.CZRC);m(t)||await f(t,Xs);let o=Ao.join(e,c.PACKAGE_JSON),i=JSON.parse(await d(o)),n=Kt(i);if(await k(o,s=>Yt(s)),n.length>0){r.text=`Installing ${n.join(", ")}...`;let s=await O(e);await ue(e,s,n)}r.succeed(Bs.green("Commitizen configured. Use `commit` to start a guided commit."))}catch(t){throw r.fail("Failed to set up Commitizen."),t}};var ko={id:"commitizen",name:"Commitizen",description:"Guided conventional-commit prompt via `commit` script",detect:async e=>m(Ys.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:De};w();P();import Zs from"node:path";import qs from"node:path";import Ws from"picocolors";P();w();P();import Oo from"node:path";import Ks from"degit";var _o=async(e,r)=>{r.text="Fetching assets from starter repo...",await Ks("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Fo=async(e,r)=>{let t=Oo.join(e,c.THEME_PROVIDER),o=Oo.join(r,"src/providers/CustomThemeProvider.tsx");await _(o,t)};w();P();import Le from"node:path";w();P();import jo from"node:path";var mt=async e=>{let r=[jo.join(e,c.ROOT_LAYOUT),jo.join(e,"src/app/[locale]/layout.tsx")];for(let t of r)if(m(t)&&(await d(t)).includes("<body"))return t;for(let t of r)if(m(t))return t;return""};var Do=async e=>{let r=Le.join(e,c.THEME_PROVIDER),t=Le.join(e,c.GLOBALS_CSS),o=Le.join(e,"package.json");if(m(r))return{isSetup:!0,reason:"CustomThemeProvider.tsx exists"};if(m(o)){let i=JSON.parse(await d(o)),n="@teispace/next-themes";if(i.dependencies?.[n]||i.devDependencies?.[n])return{isSetup:!0,reason:`${n} is installed`}}return m(t)&&(await d(t)).includes("@custom-variant dark")?{isSetup:!0,reason:"Dark theme CSS found in globals.css"}:{isSetup:!1,reason:""}},Lo=async e=>{let r=Le.join(e,c.GLOBALS_CSS),t=Le.join(e,c.PROVIDERS_INDEX),o=await mt(e);if(!m(r)||!o||!m(t))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 o};w();P();import dt from"node:path";var Mo=async e=>{let r=dt.join(e,c.PROVIDERS_INDEX),t=await d(r);t.includes("CustomThemeProvider")||(t+=`export * from './CustomThemeProvider';
677
+ `,await f(r,t))},Go=async e=>{let r=dt.join(e,"src/providers/RootProvider.tsx");if(!m(r))return;let t=await d(r),o="'use client';",i=t.includes(o);if(i&&(t=t.replace(o,"").trim()),t.includes("CustomThemeProvider")||(/import\s*\{[^}]*\}\s*from\s*'@\/providers'/.test(t)?t=t.replace(/(import\s*\{)([^}]*)(\}\s*from\s*'@\/providers')/,(n,s,a,p)=>`${s}${a.trim()?`${a.trim()}, CustomThemeProvider `:" CustomThemeProvider "}${p}`):t=`import { CustomThemeProvider } from '@/providers';
678
+ ${t}`),i&&(t=`${o}
679
+ ${t}`),!t.includes("<CustomThemeProvider"))if(t.includes("{children}"))t=t.replace(/\{children\}/,"<CustomThemeProvider>{children}</CustomThemeProvider>");else{let n=t.match(/return\s*\(\s*([\s\S]*?)\s*\);/);n&&(t=t.replace(n[0],`return (
677
680
  <CustomThemeProvider>
678
- ${i[1]}
681
+ ${n[1]}
679
682
  </CustomThemeProvider>
680
- );`))}await u(r,t)},ho=async(e,r)=>{let t=Me.join(e,a.GLOBALS_CSS),o=Me.join(r,"src/styles/globals.css"),n="";if(l(o)){let s=await d(o),c=s.match(/@custom-variant dark \(.*?\);/),p=s.match(/@theme \{[\s\S]*?\}/);c&&(n+=`
681
- ${c[0]}
682
- `),p&&(n+=`
683
+ );`))}await f(r,t)},Ho=async(e,r)=>{let t=dt.join(e,c.GLOBALS_CSS),o=dt.join(r,"src/styles/globals.css"),i="";if(m(o)){let s=await d(o),a=s.match(/@custom-variant dark \(.*?\);/),p=s.match(/@theme \{[\s\S]*?\}/);a&&(i+=`
684
+ ${a[0]}
685
+ `),p&&(i+=`
683
686
  ${p[0]}
684
- `)}n||(n=`
687
+ `)}i||(i=`
685
688
  @custom-variant dark (&:where(.dark, .dark *));
686
689
 
687
690
  @theme {
688
691
  --color-dark: #202938;
689
692
  --color-light: #f5f5f5;
690
693
  }
691
- `);let i=await d(t);if(!i.includes("@custom-variant dark")){if(i.includes("@import")){let s=i.lastIndexOf("@import"),c=i.indexOf(`
692
- `,s);i=i.slice(0,c+1)+n+i.slice(c+1)}else i=n+i;await u(t,i)}},xo=async e=>{let r=await d(e);r.includes("dark:bg-dark")||(r=r.replace(/className="([^"]*)"/,'className="$1 bg-light dark:bg-dark"'),await u(e,r))};var Nt=async e=>{let r=I("Setting up Dark Theme..."),t=rs.join(e,".next-maker-temp");try{let{isSetup:o,reason:n}=await mo(e);if(o){r.fail(`Dark Theme is already set up (${n}).`);return}let i=await uo(e);await co(t,r),await po(e,t),await fo(e),await go(e),await ho(e,t),await xo(i),r.text="Installing @teispace/next-themes...",await H(e,"@teispace/next-themes"),r.text="Formatting code...";let s=await D(e);await G(e,s,"lint:fix"),r.succeed(os.green("Dark Theme setup successfully!"))}catch(o){throw r.fail("Failed to setup Dark Theme."),o}finally{await P(t)}};import ns from"node:fs/promises";import Je from"node:path";import ze from"enquirer";import bt from"picocolors";T();C();T();import Z from"node:fs/promises";import v from"node:path";import is from"degit";var yo=async(e,r)=>{r.text="Downloading assets from starter repository...",await is("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Po=async(e,r,t,o)=>{let n=v.join(e,a.HTTP_UTILS),i=v.join(r,a.HTTP_UTILS);await Z.cp(v.join(r,a.ERRORS_DIR),v.join(e,a.ERRORS_DIR),{recursive:!0});let s=v.join(e,a.APP_APIS);l(s)||await A(v.join(r,a.APP_APIS),s);let c=v.join(e,a.CONSTANTS);if(!l(c))await A(v.join(r,a.CONSTANTS),c);else{let f=await d(c),g=!1;f.includes("API_RESPONSE_DATA_KEY")||(f+=`
694
+ `);let n=await d(t);if(!n.includes("@custom-variant dark")){if(n.includes("@import")){let s=n.lastIndexOf("@import"),a=n.indexOf(`
695
+ `,s);n=n.slice(0,a+1)+i+n.slice(a+1)}else n=i+n;await f(t,n)}},Uo=async e=>{let r=await d(e);r.includes("dark:bg-dark")||(r=r.replace(/className="([^"]*)"/,'className="$1 bg-light dark:bg-dark"'),await f(e,r))};var Me=async e=>{let r=R("Setting up Dark Theme..."),t=qs.join(e,".next-maker-temp");try{let{isSetup:o,reason:i}=await Do(e);if(o){r.fail(`Dark Theme is already set up (${i}).`);return}let n=await Lo(e);await _o(t,r),await Fo(e,t),await Mo(e),await Go(e),await Ho(e,t),await Uo(n),r.text="Installing @teispace/next-themes...",await z(e,"@teispace/next-themes"),r.text="Formatting code...";let s=await O(e);await U(e,s,"lint:fix"),r.succeed(Ws.green("Dark Theme setup successfully!"))}catch(o){throw r.fail("Failed to setup Dark Theme."),o}finally{await S(t)}};var zo={id:"dark-theme",name:"Dark Theme",description:"@teispace/next-themes + CustomThemeProvider",detect:async e=>m(Zs.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/}],apply:Me};import ea from"node:fs/promises";import ut from"node:path";import ft from"enquirer";import qt from"picocolors";P();w();P();import ee from"node:fs/promises";import E from"node:path";import Qs from"degit";var Vo=async(e,r)=>{r.text="Downloading assets from starter repository...",await Qs("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Jo=async(e,r,t,o)=>{let i=E.join(e,c.HTTP_UTILS),n=E.join(r,c.HTTP_UTILS);await ee.cp(E.join(r,c.ERRORS_DIR),E.join(e,c.ERRORS_DIR),{recursive:!0});let s=E.join(e,c.APP_APIS);m(s)||await _(E.join(r,c.APP_APIS),s);let a=E.join(e,c.CONSTANTS);if(!m(a))await _(E.join(r,c.CONSTANTS),a);else{let u=await d(a),g=!1;u.includes("API_RESPONSE_DATA_KEY")||(u+=`
693
696
  export const API_RESPONSE_DATA_KEY = 'data';
694
- `,g=!0),f.includes("SAVE_AUTH_TOKENS")||(f+=`
697
+ `,g=!0),u.includes("SAVE_AUTH_TOKENS")||(u+=`
695
698
  export const SAVE_AUTH_TOKENS = false;
696
- `,g=!0),g&&await u(c,f)}let p=v.join(e,a.STORAGE_SERVICE);if(l(p)||await Z.cp(v.join(r,a.STORAGE_SERVICE),p,{recursive:!0}),await Z.cp(v.join(r,a.COMMON_TYPES_DIR),v.join(e,a.COMMON_TYPES_DIR),{recursive:!0}),await Z.cp(v.join(r,a.UTILITY_TYPES_DIR),v.join(e,a.UTILITY_TYPES_DIR),{recursive:!0}),await A(v.join(i,"token-store.ts"),v.join(n,"token-store.ts")),await A(v.join(i,"client-utils.ts"),v.join(n,"client-utils.ts")),o&&o.length>0)for(let f of o){let g=v.join(e,f==="fetch"?a.FETCH_CLIENT:a.AXIOS_CLIENT);await P(g)}for(let f of t)f==="fetch"?await Z.cp(v.join(r,a.FETCH_CLIENT),v.join(e,a.FETCH_CLIENT),{recursive:!0}):await Z.cp(v.join(r,a.AXIOS_CLIENT),v.join(e,a.AXIOS_CLIENT),{recursive:!0});await A(v.join(i,"index.ts"),v.join(n,"index.ts")),await A(v.join(r,a.HTTP_TYPES),v.join(e,a.HTTP_TYPES))},To=async e=>{let{isFileUsed:r,isStringUsed:t}=await Promise.resolve().then(()=>(je(),Qt));await P(v.join(e,a.HTTP_UTILS));let o=v.join(e,a.STORAGE_SERVICE);l(o)&&(await t(e,"SecureStorageService",[o])||await P(o));let n=v.join(e,a.CONSTANTS);if(l(n)){let p=await d(n),f=!1;await t(e,"API_RESPONSE_DATA_KEY",[n])||(p=p.replace(/export const API_RESPONSE_DATA_KEY = .*;\n?/g,""),f=!0),await t(e,"SAVE_AUTH_TOKENS",[n])||(p=p.replace(/export const SAVE_AUTH_TOKENS = .*;\n?/g,""),f=!0),f&&(p=`${p.replace(/\n\s*\n/g,`
699
+ `,g=!0),g&&await f(a,u)}let p=E.join(e,c.STORAGE_SERVICE);if(m(p)||await ee.cp(E.join(r,c.STORAGE_SERVICE),p,{recursive:!0}),await ee.cp(E.join(r,c.COMMON_TYPES_DIR),E.join(e,c.COMMON_TYPES_DIR),{recursive:!0}),await ee.cp(E.join(r,c.UTILITY_TYPES_DIR),E.join(e,c.UTILITY_TYPES_DIR),{recursive:!0}),await _(E.join(n,"token-store.ts"),E.join(i,"token-store.ts")),await _(E.join(n,"client-utils.ts"),E.join(i,"client-utils.ts")),o&&o.length>0)for(let u of o){let g=E.join(e,u==="fetch"?c.FETCH_CLIENT:c.AXIOS_CLIENT);await S(g)}for(let u of t)u==="fetch"?await ee.cp(E.join(r,c.FETCH_CLIENT),E.join(e,c.FETCH_CLIENT),{recursive:!0}):await ee.cp(E.join(r,c.AXIOS_CLIENT),E.join(e,c.AXIOS_CLIENT),{recursive:!0});await _(E.join(n,"index.ts"),E.join(i,"index.ts")),await _(E.join(r,c.HTTP_TYPES),E.join(e,c.HTTP_TYPES))},Bo=async e=>{let{isFileUsed:r,isStringUsed:t}=await Promise.resolve().then(()=>(nt(),Ar));await S(E.join(e,c.HTTP_UTILS));let o=E.join(e,c.STORAGE_SERVICE);m(o)&&(await t(e,"SecureStorageService",[o])||await S(o));let i=E.join(e,c.CONSTANTS);if(m(i)){let p=await d(i),u=!1;await t(e,"API_RESPONSE_DATA_KEY",[i])||(p=p.replace(/export const API_RESPONSE_DATA_KEY = .*;\n?/g,""),u=!0),await t(e,"SAVE_AUTH_TOKENS",[i])||(p=p.replace(/export const SAVE_AUTH_TOKENS = .*;\n?/g,""),u=!0),u&&(p=`${p.replace(/\n\s*\n/g,`
697
700
 
698
701
  `).trim()}
699
- `,await u(n,p))}let i=v.join(e,a.ERRORS_DIR);if(l(i)){let p=await Z.readdir(i),f=!1;for(let g of p){let y=v.parse(g).name;if(await r(e,y,[v.join(i,g)])){f=!0;break}}f||await P(i)}let s=v.join(e,a.COMMON_TYPES_DIR);l(s)&&(await Z.readdir(s)).length===0&&await P(s);let c=v.join(e,a.UTILITY_TYPES_DIR);l(c)&&(await Z.readdir(c)).length===0&&await P(c)};C();T();import $e from"node:path";var So=async e=>{let r=$e.join(e,a.FETCH_CLIENT_FILE),t=$e.join(e,a.AXIOS_CLIENT_FILE),o=l(r),n=l(t);return o&&n?{status:"both",reason:"Both Fetch and Axios clients are detected"}:o?{status:"fetch",reason:"Fetch client is already setup"}:n?{status:"axios",reason:"Axios client is already setup"}:{status:"none"}},wo=async e=>{let t=[$e.join(e,"src/lib"),$e.join(e,"src/types"),$e.join(e,"src/lib/config")].filter(o=>!l(o));if(t.length>0)throw new Error(`Invalid project structure. Missing directories:
702
+ `,await f(i,p))}let n=E.join(e,c.ERRORS_DIR);if(m(n)){let p=await ee.readdir(n),u=!1;for(let g of p){let y=E.parse(g).name;if(await r(e,y,[E.join(n,g)])){u=!0;break}}u||await S(n)}let s=E.join(e,c.COMMON_TYPES_DIR);m(s)&&(await ee.readdir(s)).length===0&&await S(s);let a=E.join(e,c.UTILITY_TYPES_DIR);m(a)&&(await ee.readdir(a)).length===0&&await S(a)};w();P();import Ge from"node:path";var Xo=async e=>{let r=Ge.join(e,c.FETCH_CLIENT_FILE),t=Ge.join(e,c.AXIOS_CLIENT_FILE),o=m(r),i=m(t);return o&&i?{status:"both",reason:"Both Fetch and Axios clients are detected"}:o?{status:"fetch",reason:"Fetch client is already setup"}:i?{status:"axios",reason:"Axios client is already setup"}:{status:"none"}},Yo=async e=>{let t=[Ge.join(e,"src/lib"),Ge.join(e,"src/types"),Ge.join(e,"src/lib/config")].filter(o=>!m(o));if(t.length>0)throw new Error(`Invalid project structure. Missing directories:
700
703
  ${t.map(o=>`- ${o}`).join(`
701
- `)}`)};je();var $t=async e=>{let r=I("Checking HTTP Client setup..."),t=Je.join(e,".next-maker-temp-http");try{let{status:o,reason:n}=await So(e);r.stop();let i=await ss(o,n);if(i.type==="cancel"){console.log(bt.yellow("Setup cancelled."));return}if(r.start("Setting up HTTP client(s)..."),await wo(e),await yo(t,r),i.type==="replace"&&i.fromClient&&(r.text="Migrating client usages...",await rt(e,i.fromClient,i.clients[0])),i.type!=="remove-both"&&i.type!=="remove-one"){r.text="Copying client files...";let X=i.type==="replace"&&i.fromClient?[i.fromClient]:void 0;await Po(e,t,i.clients,X)}if(i.type==="remove-one"||i.type==="remove-both"){r.text="Removing client files...";let{PROJECT_PATHS:X}=await Promise.resolve().then(()=>(C(),Kt));for(let Ae of i.clients){let Oe=Je.join(e,Ae==="fetch"?X.FETCH_CLIENT:X.AXIOS_CLIENT);await P(Oe)}vo(o,i).length===0&&(r.text="Performing full cleanup...",await To(e),await ot(e))}let s=vo(o,i);s.length>0&&(r.text="Configuring client...",await Ze(e,s),await Qe(e),await et(e),await tt(e)),await fe(e,s),r.text="Managing dependencies...";let c=Je.join(e,"package.json"),p=JSON.parse(await ns.readFile(c,"utf-8")),f={...p.dependencies,...p.devDependencies};s.includes("axios")?f.axios||(r.text="Installing Axios...",await H(e,"axios")):f.axios&&(r.text="Uninstalling Axios...",await We(e,"axios"));let g=Je.join(e,"src/services/storage");s.length>0||l(g)?f["react-secure-storage"]||(r.text="Installing react-secure-storage...",await H(e,"react-secure-storage")):f["react-secure-storage"]&&(r.text="Uninstalling react-secure-storage...",await We(e,"react-secure-storage")),r.text="Formatting code...";let x=await D(e);await G(e,x,"lint:fix"),r.succeed(bt.green(as(i)))}catch(o){throw r.fail("Failed to setup HTTP Client."),o}finally{await P(t)}};async function ss(e,r){if(e==="none"){let{choice:o}=await ze.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 o==="both"?{type:"install",clients:["fetch","axios"]}:{type:"install",clients:[o]}}if(e==="fetch"){let{action:o}=await ze.prompt({type:"select",name:"action",message:`${r}. 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(o==="cancel")return{type:"cancel",clients:[]};if(o==="add")return{type:"add",clients:["axios"]};if(o==="replace")return{type:"replace",clients:["axios"],fromClient:"fetch"};if(o==="remove")return{type:"remove-one",clients:["fetch"]}}if(e==="axios"){let{action:o}=await ze.prompt({type:"select",name:"action",message:`${r}. 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(o==="cancel")return{type:"cancel",clients:[]};if(o==="add")return{type:"add",clients:["fetch"]};if(o==="replace")return{type:"replace",clients:["fetch"],fromClient:"axios"};if(o==="remove")return{type:"remove-one",clients:["axios"]}}console.log(bt.yellow(`\u2716 ${r}`));let{action:t}=await ze.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 t==="cancel"?{type:"cancel",clients:[]}:t==="remove-fetch"?{type:"remove-one",clients:["fetch"]}:t==="remove-axios"?{type:"remove-one",clients:["axios"]}:t==="remove-both"?{type:"remove-both",clients:["fetch","axios"]}:{type:"cancel",clients:[]}}function vo(e,r){return r.type==="install"?r.clients:r.type==="add"?[...e==="fetch"?["fetch"]:["axios"],...r.clients]:r.type==="replace"?r.clients:r.type==="remove-one"?e==="both"?r.clients[0]==="fetch"?["axios"]:["fetch"]:[]:[]}function as(e){if(e.type==="install")return`HTTP Client (${e.clients.map(t=>t==="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 r=e.fromClient==="fetch"?"Fetch":"Axios",t=e.clients[0]==="fetch"?"Fetch":"Axios";return`Replaced ${r} with ${t} 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!"}C();import At from"node:path";import ms from"picocolors";T();C();T();import cs from"node:fs/promises";import ie from"node:path";import ps from"degit";var Co=async(e,r)=>{r.text="Fetching assets from starter repo...",await ps("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Eo=async(e,r)=>{let t=ie.join(r,"src/i18n"),o=ie.join(e,a.I18N_DIR);await cs.cp(t,o,{recursive:!0});let n=ie.join(r,"src/proxy.ts"),i=ie.join(e,a.PROXY);await A(n,i);let s=ie.join(r,"src/types/i18n.ts"),c=ie.join(e,a.I18N_TYPES);await A(s,c);let p=ie.join(r,"src/lib/config/app-locales.ts"),f=ie.join(e,a.APP_LOCALES);await A(p,f)};C();T();import Be from"node:path";var Io=async e=>{let r=Be.join(e,a.I18N_DIR),t=Be.join(e,"package.json");if(l(r))return{isSetup:!0,reason:"src/i18n directory exists"};if(l(t)){let o=JSON.parse(await d(t));if(o.dependencies?.["next-intl"]||o.devDependencies?.["next-intl"])return{isSetup:!0,reason:"next-intl is installed"}}return{isSetup:!1,reason:""}},Ro=async e=>{let r=Be.join(e,a.ROOT_LAYOUT),t=Be.join(e,"src/app/[locale]/layout.tsx");if(!l(r)&&!l(t))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx exists.")};C();T();import ls from"node:fs/promises";import Q from"node:path";var No=async e=>{let r=Q.join(e,a.NEXT_CONFIG);if(l(r)){let t=await d(r);if(!t.includes("createNextIntlPlugin")){t=`import createNextIntlPlugin from 'next-intl/plugin';
704
+ `)}`)};nt();var He=async e=>{let r=R("Checking HTTP Client setup..."),t=ut.join(e,".next-maker-temp-http");try{let{status:o,reason:i}=await Xo(e);r.stop();let n=await ta(o,i);if(n.type==="cancel"){console.log(qt.yellow("Setup cancelled."));return}if(r.start("Setting up HTTP client(s)..."),await Yo(e),await Vo(t,r),n.type==="replace"&&n.fromClient&&(r.text="Migrating client usages...",await Nt(e,n.fromClient,n.clients[0])),n.type!=="remove-both"&&n.type!=="remove-one"){r.text="Copying client files...";let Y=n.type==="replace"&&n.fromClient?[n.fromClient]:void 0;await Jo(e,t,n.clients,Y)}if(n.type==="remove-one"||n.type==="remove-both"){r.text="Removing client files...";let{PROJECT_PATHS:Y}=await Promise.resolve().then(()=>(w(),br));for(let et of n.clients){let tt=ut.join(e,et==="fetch"?Y.FETCH_CLIENT:Y.AXIOS_CLIENT);await S(tt)}Ko(o,n).length===0&&(r.text="Performing full cleanup...",await Bo(e),await It(e))}let s=Ko(o,n);s.length>0&&(r.text="Configuring client...",await Et(e,s),await Rt(e),await bt(e),await $t(e)),await ve(e,s),r.text="Managing dependencies...";let a=ut.join(e,"package.json"),p=JSON.parse(await ea.readFile(a,"utf-8")),u={...p.dependencies,...p.devDependencies};s.includes("axios")?u.axios||(r.text="Installing Axios...",await z(e,"axios")):u.axios&&(r.text="Uninstalling Axios...",await Ct(e,"axios"));let g=ut.join(e,"src/services/storage");s.length>0||m(g)?u["react-secure-storage"]||(r.text="Installing react-secure-storage...",await z(e,"react-secure-storage")):u["react-secure-storage"]&&(r.text="Uninstalling react-secure-storage...",await Ct(e,"react-secure-storage")),r.text="Formatting code...";let x=await O(e);await U(e,x,"lint:fix"),r.succeed(qt.green(ra(n)))}catch(o){throw r.fail("Failed to setup HTTP Client."),o}finally{await S(t)}};async function ta(e,r){if(e==="none"){let{choice:o}=await ft.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 o==="both"?{type:"install",clients:["fetch","axios"]}:{type:"install",clients:[o]}}if(e==="fetch"){let{action:o}=await ft.prompt({type:"select",name:"action",message:`${r}. 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(o==="cancel")return{type:"cancel",clients:[]};if(o==="add")return{type:"add",clients:["axios"]};if(o==="replace")return{type:"replace",clients:["axios"],fromClient:"fetch"};if(o==="remove")return{type:"remove-one",clients:["fetch"]}}if(e==="axios"){let{action:o}=await ft.prompt({type:"select",name:"action",message:`${r}. 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(o==="cancel")return{type:"cancel",clients:[]};if(o==="add")return{type:"add",clients:["fetch"]};if(o==="replace")return{type:"replace",clients:["fetch"],fromClient:"axios"};if(o==="remove")return{type:"remove-one",clients:["axios"]}}console.log(qt.yellow(`\u2716 ${r}`));let{action:t}=await ft.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 t==="cancel"?{type:"cancel",clients:[]}:t==="remove-fetch"?{type:"remove-one",clients:["fetch"]}:t==="remove-axios"?{type:"remove-one",clients:["axios"]}:t==="remove-both"?{type:"remove-both",clients:["fetch","axios"]}:{type:"cancel",clients:[]}}function Ko(e,r){return r.type==="install"?r.clients:r.type==="add"?[...e==="fetch"?["fetch"]:["axios"],...r.clients]:r.type==="replace"?r.clients:r.type==="remove-one"?e==="both"?r.clients[0]==="fetch"?["axios"]:["fetch"]:[]:[]}function ra(e){if(e.type==="install")return`HTTP Client (${e.clients.map(t=>t==="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 r=e.fromClient==="fetch"?"Fetch":"Axios",t=e.clients[0]==="fetch"?"Fetch":"Axios";return`Replaced ${r} with ${t} 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 qo={id:"http-client",name:"HTTP Client",description:"Axios and/or Fetch client utilities",detect:async e=>{let{detectProjectSetup:r}=await Promise.resolve().then(()=>(L(),$e));return(await r(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"}],packages:[],scripts:[],injections:[],apply:He};w();import Wt from"node:path";import sa from"picocolors";P();w();P();import oa from"node:fs/promises";import se from"node:path";import na from"degit";var Wo=async(e,r)=>{r.text="Fetching assets from starter repo...",await na("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Zo=async(e,r)=>{let t=se.join(r,"src/i18n"),o=se.join(e,c.I18N_DIR);await oa.cp(t,o,{recursive:!0});let i=se.join(r,"src/proxy.ts"),n=se.join(e,c.PROXY);await _(i,n);let s=se.join(r,"src/types/i18n.ts"),a=se.join(e,c.I18N_TYPES);await _(s,a);let p=se.join(r,"src/lib/config/app-locales.ts"),u=se.join(e,c.APP_LOCALES);await _(p,u)};w();P();import gt from"node:path";var Qo=async e=>{let r=gt.join(e,c.I18N_DIR),t=gt.join(e,"package.json");if(m(r))return{isSetup:!0,reason:"src/i18n directory exists"};if(m(t)){let o=JSON.parse(await d(t));if(o.dependencies?.["next-intl"]||o.devDependencies?.["next-intl"])return{isSetup:!0,reason:"next-intl is installed"}}return{isSetup:!1,reason:""}},en=async e=>{let r=gt.join(e,c.ROOT_LAYOUT),t=gt.join(e,"src/app/[locale]/layout.tsx");if(!m(r)&&!m(t))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx exists.")};w();P();import ia from"node:fs/promises";import te from"node:path";var tn=async e=>{let r=te.join(e,c.NEXT_CONFIG);if(m(r)){let t=await d(r);if(!t.includes("createNextIntlPlugin")){t=`import createNextIntlPlugin from 'next-intl/plugin';
702
705
  ${t}`;let o=/export default (.*?);/;o.test(t)?t=t.replace(o,`
703
706
  const withNextIntl = createNextIntlPlugin();
704
707
  export default withNextIntl($1);`):(t+=`
705
708
  const withNextIntl = createNextIntlPlugin();
706
709
  `,t+=`export default withNextIntl(nextConfig);
707
- `),await u(r,t)}}},bo=async e=>{let r=Q.join(e,a.TYPES_INDEX);if(l(r)){let t=await d(r);t.includes("./i18n")||(t+=`export * from './i18n';
708
- `,await u(r,t))}},$o=async e=>{let r=Q.join(e,a.CONFIG_INDEX);if(l(r)){let t=await d(r);t.includes("./app-locales")||(t+=`export * from './app-locales';
709
- `,await u(r,t))}},Ao=async e=>{let r=Q.join(e,"src/providers/RootProvider.tsx");if(l(r)){let t=await d(r),o="'use client';",n=t.includes(o);if(n&&(t=t.replace(o,"").trim()),t.includes("next-intl")||(t=`import { type AbstractIntlMessages, NextIntlClientProvider } from 'next-intl';
710
+ `),await f(r,t)}}},rn=async e=>{let r=te.join(e,c.TYPES_INDEX);if(m(r)){let t=await d(r);t.includes("./i18n")||(t+=`export * from './i18n';
711
+ `,await f(r,t))}},on=async e=>{let r=te.join(e,c.CONFIG_INDEX);if(m(r)){let t=await d(r);t.includes("./app-locales")||(t+=`export * from './app-locales';
712
+ `,await f(r,t))}},nn=async e=>{let r=te.join(e,"src/providers/RootProvider.tsx");if(m(r)){let t=await d(r),o="'use client';",i=t.includes(o);if(i&&(t=t.replace(o,"").trim()),t.includes("next-intl")||(t=`import { type AbstractIntlMessages, NextIntlClientProvider } from 'next-intl';
710
713
  import type { SupportedLocale } from '@/types/i18n';
711
- `+t),n&&(t=`${o}
712
- ${t}`),!t.includes("locale: SupportedLocale")){let i=` locale: SupportedLocale;
714
+ `+t),i&&(t=`${o}
715
+ ${t}`),!t.includes("locale: SupportedLocale")){let n=` locale: SupportedLocale;
713
716
  messages: AbstractIntlMessages;
714
- timeZone: string;`,s=/(type\s+RootProviderProps\s*=\s*\{)([\s\S]*?)(\};?)/,c=/export const RootProvider = \(\{([\s\S]*?)\}: \{([\s\S]*?)\}\) => \{/;if(s.test(t))t=t.replace(s,(p,f,g,y)=>{let x=g.replace(/\s+$/,"");return`${f}${x}
715
- ${i}
716
- ${y}`}),t=t.replace(/export const RootProvider = \(\{([\s\S]*?)\}:\s*RootProviderProps\)/,(p,f)=>{let g=f.trim().replace(/,$/,"");return`export const RootProvider = ({ ${g?`${g}, `:""}locale, messages, timeZone }: RootProviderProps)`});else{let p=t.match(c);if(p){let f=p[1].trim().replace(/,$/,""),g=p[2].trim().replace(/;$/,""),y=`
717
- ${f?`${f},
717
+ timeZone: string;`,s=/(type\s+RootProviderProps\s*=\s*\{)([\s\S]*?)(\};?)/,a=/export const RootProvider = \(\{([\s\S]*?)\}: \{([\s\S]*?)\}\) => \{/;if(s.test(t))t=t.replace(s,(p,u,g,y)=>{let x=g.replace(/\s+$/,"");return`${u}${x}
718
+ ${n}
719
+ ${y}`}),t=t.replace(/export const RootProvider = \(\{([\s\S]*?)\}:\s*RootProviderProps\)/,(p,u)=>{let g=u.trim().replace(/,$/,"");return`export const RootProvider = ({ ${g?`${g}, `:""}locale, messages, timeZone }: RootProviderProps)`});else{let p=t.match(a);if(p){let u=p[1].trim().replace(/,$/,""),g=p[2].trim().replace(/;$/,""),y=`
720
+ ${u?`${u},
718
721
  `:""}locale,
719
722
  messages,
720
723
  timeZone,`,x=`
@@ -723,26 +726,26 @@ ${y}`}),t=t.replace(/export const RootProvider = \(\{([\s\S]*?)\}:\s*RootProvide
723
726
  messages: AbstractIntlMessages;
724
727
  timeZone: string;`;t=t.replace(p[0],`export const RootProvider = ({${y}
725
728
  }: {${x}
726
- }) => {`)}}}if(!t.includes("<NextIntlClientProvider")){let i=t.match(/return\s*(?:\(\s*)?([\s\S]*?)(?:\s*\))?;/);if(i){let s=i[1],c=`<NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>
729
+ }) => {`)}}}if(!t.includes("<NextIntlClientProvider")){let n=t.match(/return\s*(?:\(\s*)?([\s\S]*?)(?:\s*\))?;/);if(n){let s=n[1],a=`<NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>
727
730
  {children}
728
- </NextIntlClientProvider>`;if(s.includes("{children}")){let p=s.replace("{children}",c);t=t.replace(i[0],`return (
731
+ </NextIntlClientProvider>`;if(s.includes("{children}")){let p=s.replace("{children}",a);t=t.replace(n[0],`return (
729
732
  ${p}
730
- );`)}else t=t.replace(i[0],`return (
733
+ );`)}else t=t.replace(n[0],`return (
731
734
  <NextIntlClientProvider locale={locale} messages={messages} timeZone={timeZone}>
732
735
  ${s}
733
736
  </NextIntlClientProvider>
734
- );`)}}await u(r,t)}},Oo=async e=>{let r=Q.join(e,a.ROOT_LAYOUT),t=Q.join(e,a.ROOT_PAGE),o=Q.join(e,"src/app/[locale]");if(await ls.mkdir(o,{recursive:!0}),l(r)){let n=Q.join(o,"layout.tsx"),i=await d(r);if(i.includes("next-intl")||(i=`import { routing } from '@/i18n/routing';
737
+ );`)}}await f(r,t)}},sn=async e=>{let r=te.join(e,c.ROOT_LAYOUT),t=te.join(e,c.ROOT_PAGE),o=te.join(e,"src/app/[locale]");if(await ia.mkdir(o,{recursive:!0}),m(r)){let i=te.join(o,"layout.tsx"),n=await d(r);if(n.includes("next-intl")||(n=`import { routing } from '@/i18n/routing';
735
738
  import { hasLocale } from 'next-intl';
736
739
  import { notFound } from 'next/navigation';
737
740
  import { getMessages, getTimeZone, setRequestLocale } from 'next-intl/server';
738
- ${i}`),!i.includes("generateStaticParams")){let p=i.indexOf("};",i.indexOf("export const metadata"));if(p!==-1){let f=p+2;i=i.slice(0,f)+`
741
+ ${n}`),!n.includes("generateStaticParams")){let p=n.indexOf("};",n.indexOf("export const metadata"));if(p!==-1){let u=p+2;n=n.slice(0,u)+`
739
742
 
740
743
  export function generateStaticParams() {
741
744
  return routing.locales.map((locale) => ({ locale }));
742
- }`+i.slice(f)}}i=i.replace(/Readonly<\{\s*children:\s*React\.ReactNode;\s*}>/,`Readonly<{
745
+ }`+n.slice(u)}}n=n.replace(/Readonly<\{\s*children:\s*React\.ReactNode;\s*}>/,`Readonly<{
743
746
  children: React.ReactNode;
744
747
  params: Promise<{ locale: string }>;
745
- }>`);let s=/export default (async )?function RootLayout\(\{\s*children,?\s*\}\s*:/,c=i.match(s);if(c){c[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 f=/export default async function RootLayout[\s\S]*?\)\s*\{/,g=i.match(f);if(g&&g.index!==void 0){let y=g.index+g[0].length-1;i=i.slice(0,y+1)+`
748
+ }>`);let s=/export default (async )?function RootLayout\(\{\s*children,?\s*\}\s*:/,a=n.match(s);if(a){a[1]||(n=n.replace("export default function","export default async function")),n=n.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*\{/,g=n.match(u);if(g&&g.index!==void 0){let y=g.index+g[0].length-1;n=n.slice(0,y+1)+`
746
749
  const { locale } = await params;
747
750
 
748
751
  if (!hasLocale(routing.locales, locale)) {
@@ -752,46 +755,279 @@ export function generateStaticParams() {
752
755
  setRequestLocale(locale);
753
756
 
754
757
  const [messages, timeZone] = await Promise.all([getMessages(), getTimeZone()]);
755
- `+i.slice(y+1)}i=i.replace(/<RootProvider>/,"<RootProvider locale={locale} messages={messages} timeZone={timeZone}>"),i=i.replace(/<html lang="en"/,"<html lang={locale}")}await u(n,i),await S(r)}if(l(t)){let n=Q.join(o,"page.tsx"),i=await d(t);i.includes("next-intl")||(i=`import { SupportedLocale } from '@/types/i18n';
758
+ `+n.slice(y+1)}n=n.replace(/<RootProvider>/,"<RootProvider locale={locale} messages={messages} timeZone={timeZone}>"),n=n.replace(/<html lang="en"/,"<html lang={locale}")}await f(i,n),await T(r)}if(m(t)){let i=te.join(o,"page.tsx"),n=await d(t);n.includes("next-intl")||(n=`import { SupportedLocale } from '@/types/i18n';
756
759
  import { setRequestLocale } from 'next-intl/server';
757
- ${i}`),i=i.replace(/export default function Home\(\)/,`type Props = {
760
+ ${n}`),n=n.replace(/export default function Home\(\)/,`type Props = {
758
761
  params: Promise<{ locale: string }>;
759
762
  };
760
763
 
761
- export default async function Home(props: Props)`);let s=i.indexOf("export default async function Home(props: Props) {");if(s!==-1){let c=`
764
+ export default async function Home(props: Props)`);let s=n.indexOf("export default async function Home(props: Props) {");if(s!==-1){let a=`
762
765
  const locale = (await props.params).locale as SupportedLocale;
763
766
  setRequestLocale(locale);
764
- `,p=i.indexOf("{",s);i=i.slice(0,p+1)+c+i.slice(p+1)}await u(n,i),await S(t)}};var Ot=async e=>{let r=I("Setting up Internationalization (next-intl)..."),t=At.join(e,".next-maker-temp-i18n");try{let{isSetup:o,reason:n}=await Io(e);if(o){r.fail(`i18n is already set up (${n}).`);return}await Ro(e),await Co(t,r),r.text="Copying i18n files...",await Eo(e,t),r.text="Configuring project structure...",await No(e),await bo(e),await $o(e),await Ao(e),r.text="Migrating to [locale] structure...",await Oo(e),r.text="Installing dependencies...",await H(e,"next-intl");let i=At.join(e,a.VITEST_CONFIG);if(l(i)){let c=JSON.parse(await d(At.join(e,a.PACKAGE_JSON))),p={...c.dependencies,...c.devDependencies},f=!!(p["@reduxjs/toolkit"]&&p["react-redux"]);await ee(e,{redux:f,i18n:!0})}r.text="Formatting code...";let s=await D(e);await G(e,s,"lint:fix"),r.succeed(ms.green("Internationalization setup successfully!"))}catch(o){throw r.fail("Failed to setup Internationalization."),o}finally{await P(t)}};C();import ds from"node:path";import us from"picocolors";T();var _t=async e=>{let r=I("Enabling React Compiler...");try{let t=ds.join(e,a.NEXT_CONFIG);if(!l(t))throw new Error(`${a.NEXT_CONFIG} not found.`);let o=await d(t);if(o.includes("reactCompiler:")){r.fail("React Compiler is already configured in next.config.ts.");return}let n=/(const\s+nextConfig\s*:\s*NextConfig\s*=\s*\{)/;if(!n.test(o))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");o=o.replace(n,`$1
765
- reactCompiler: true,`),await u(t,o),r.text="Installing babel-plugin-react-compiler...",await ke(e,"babel-plugin-react-compiler"),r.succeed(us.green("React Compiler enabled."))}catch(t){throw r.fail("Failed to enable React Compiler."),t}};C();import Ft from"node:path";import gs from"picocolors";T();C();T();import _o from"node:fs/promises";import de from"node:path";import fs from"degit";var ko=async(e,r)=>{r.text="Fetching assets from starter repo...",await fs("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},jo=async(e,r)=>{let t=de.join(r,"src/providers/StoreProvider.tsx"),o=de.join(e,a.STORE_PROVIDER);await A(t,o);let n=de.join(r,"src/store"),i=de.join(e,a.STORE);await _o.cp(n,i,{recursive:!0})},Fo=async(e,r)=>{let t=de.join(r,"src/features/counter"),o=de.join(e,a.COUNTER_FEATURE);await _o.cp(t,o,{recursive:!0});let n=de.join(o,"components/Counter.tsx");if(await l(n)){let i=await d(n);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 u(n,i)}};C();T();import kt from"node:path";var Do=async e=>{let r=kt.join(e,a.STORE),t=kt.join(e,"package.json");if(l(r))return{isSetup:!0,reason:"src/store directory exists"};if(l(t)){let o=JSON.parse(await d(t));if(o.dependencies?.["@reduxjs/toolkit"]||o.devDependencies?.["@reduxjs/toolkit"])return{isSetup:!0,reason:"@reduxjs/toolkit is installed"}}return{isSetup:!1,reason:""}},Lo=async e=>{let r=kt.join(e,a.PROVIDERS_INDEX);if(!await Ue(e)||!l(r))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx (or src/app/[locale]/layout.tsx) and src/providers/index.ts exist.")};C();T();import jt from"node:path";var Go=async e=>{},Ho=async e=>{let r=jt.join(e,"src/providers/RootProvider.tsx");if(!l(r))return;let t=await d(r),o="'use client';",n=t.includes(o);if(n&&(t=t.replace(o,"").trim()),t.includes("from '@/store'")||(t=`import type { AppState } from '@/store';
767
+ `,p=n.indexOf("{",s);n=n.slice(0,p+1)+a+n.slice(p+1)}await f(i,n),await T(t)}};var Ue=async e=>{let r=R("Setting up Internationalization (next-intl)..."),t=Wt.join(e,".next-maker-temp-i18n");try{let{isSetup:o,reason:i}=await Qo(e);if(o){r.fail(`i18n is already set up (${i}).`);return}await en(e),await Wo(t,r),r.text="Copying i18n files...",await Zo(e,t),r.text="Configuring project structure...",await tn(e),await rn(e),await on(e),await nn(e),r.text="Migrating to [locale] structure...",await sn(e),r.text="Installing dependencies...",await z(e,"next-intl");let n=Wt.join(e,c.VITEST_CONFIG);if(m(n)){let a=JSON.parse(await d(Wt.join(e,c.PACKAGE_JSON))),p={...a.dependencies,...a.devDependencies},u=!!(p["@reduxjs/toolkit"]&&p["react-redux"]);await re(e,{redux:u,i18n:!0})}r.text="Formatting code...";let s=await O(e);await U(e,s,"lint:fix"),r.succeed(sa.green("Internationalization setup successfully!"))}catch(o){throw r.fail("Failed to setup Internationalization."),o}finally{await S(t)}};var an={id:"i18n",name:"Internationalization",description:"next-intl with [locale] routing, RootProvider, and proxy.ts",detect:async e=>{let{detectProjectSetup:r}=await Promise.resolve().then(()=>(L(),$e));return(await r(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/},{file:"src/providers/RootProvider.tsx",description:"<NextIntlClientProvider> wrap",presence:/NextIntlClientProvider/}],apply:Ue};w();P();import pa from"node:path";w();import aa from"node:path";import ca from"picocolors";P();var ze=async e=>{let r=R("Enabling React Compiler...");try{let t=aa.join(e,c.NEXT_CONFIG);if(!m(t))throw new Error(`${c.NEXT_CONFIG} not found.`);let o=await d(t);if(o.includes("reactCompiler:")){r.fail("React Compiler is already configured in next.config.ts.");return}let i=/(const\s+nextConfig\s*:\s*NextConfig\s*=\s*\{)/;if(!i.test(o))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");o=o.replace(i,`$1
768
+ reactCompiler: true,`),await f(t,o),r.text="Installing babel-plugin-react-compiler...",await ot(e,"babel-plugin-react-compiler"),r.succeed(ca.green("React Compiler enabled."))}catch(t){throw r.fail("Failed to enable React Compiler."),t}};var cn={id:"react-compiler",name:"React Compiler",description:"reactCompiler: true in next.config.ts + babel-plugin-react-compiler",detect:async e=>{let r=pa.join(e,c.NEXT_CONFIG);return m(r)?/reactCompiler\s*:\s*true/.test(await d(r)):!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};w();import er from"node:path";import ma from"picocolors";P();w();P();import pn from"node:fs/promises";import he from"node:path";import la from"degit";var ln=async(e,r)=>{r.text="Fetching assets from starter repo...",await la("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},mn=async(e,r)=>{let t=he.join(r,"src/providers/StoreProvider.tsx"),o=he.join(e,c.STORE_PROVIDER);await _(t,o);let i=he.join(r,"src/store"),n=he.join(e,c.STORE);await pn.cp(i,n,{recursive:!0})},dn=async(e,r)=>{let t=he.join(r,"src/features/counter"),o=he.join(e,c.COUNTER_FEATURE);await pn.cp(t,o,{recursive:!0});let i=he.join(o,"components/Counter.tsx");if(await m(i)){let n=await d(i);n=n.replace(/import \{ useTranslations \} from 'next-intl';\n?/,""),n=n.replace(/const t = useTranslations\('Count'\);\n?/,""),n=n.replace(/\{t\('currentCount', \{ count: value \}\)\}/g,"Current Count: {value}"),n=n.replace(/\{t\('increment'\)\}/g,"Increment"),n=n.replace(/\{t\('decrement'\)\}/g,"Decrement"),n=n.replace(/\{t\('reset'\)\}/g,"Reset"),await f(i,n)}};w();P();import Zt from"node:path";var un=async e=>{let r=Zt.join(e,c.STORE),t=Zt.join(e,"package.json");if(m(r))return{isSetup:!0,reason:"src/store directory exists"};if(m(t)){let o=JSON.parse(await d(t));if(o.dependencies?.["@reduxjs/toolkit"]||o.devDependencies?.["@reduxjs/toolkit"])return{isSetup:!0,reason:"@reduxjs/toolkit is installed"}}return{isSetup:!1,reason:""}},fn=async e=>{let r=Zt.join(e,c.PROVIDERS_INDEX);if(!await mt(e)||!m(r))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx (or src/app/[locale]/layout.tsx) and src/providers/index.ts exist.")};w();P();import Qt from"node:path";var gn=async e=>{},hn=async e=>{let r=Qt.join(e,"src/providers/RootProvider.tsx");if(!m(r))return;let t=await d(r),o="'use client';",i=t.includes(o);if(i&&(t=t.replace(o,"").trim()),t.includes("from '@/store'")||(t=`import type { AppState } from '@/store';
766
769
  ${t}`),t.includes("from './StoreProvider'")||(t=`${t.includes("from '@/store'"),""}import { StoreProvider } from './StoreProvider';
767
- ${t}`),n&&(t=`${o}
770
+ ${t}`),i&&(t=`${o}
768
771
  ${t}`),t.includes("preloadedState")||(t=t.replace(/children:\s*React\.ReactNode;/,`children: React.ReactNode;
769
- preloadedState?: Partial<AppState>;`),t=t.replace(/export const RootProvider = \(\{([\s\S]*?)\}:/,(i,s)=>`export const RootProvider = ({${s}, preloadedState }:`),t=t.replace(/,\s*,/g,",").replace(/\{\s*,/g,"{ ").replace(/,\s*\}/g," }")),!t.includes("<StoreProvider")){let i=t.match(/return\s*\(\s*([\s\S]*?)\s*\);/);if(i){let s=i[1];t=t.replace(i[0],`return (
772
+ preloadedState?: Partial<AppState>;`),t=t.replace(/export const RootProvider = \(\{([\s\S]*?)\}:/,(n,s)=>`export const RootProvider = ({${s}, preloadedState }:`),t=t.replace(/,\s*,/g,",").replace(/\{\s*,/g,"{ ").replace(/,\s*\}/g," }")),!t.includes("<StoreProvider")){let n=t.match(/return\s*\(\s*([\s\S]*?)\s*\);/);if(n){let s=n[1];t=t.replace(n[0],`return (
770
773
  <StoreProvider preloadedState={preloadedState}>
771
774
  ${s}
772
775
  </StoreProvider>
773
- );`)}}await u(r,t)},Uo=async e=>{let r=[jt.join(e,a.ROOT_PAGE),jt.join(e,"src/app/[locale]/page.tsx")],t="";for(let n of r)if(l(n)){t=n;break}if(!t)return;let o=await d(t);if(o.includes("Counter")||(o=`import { Counter } from '@/features/counter';
774
- ${o}`),!o.includes("<Counter />")){let n=o.lastIndexOf("</div>"),i=o.lastIndexOf("</main>"),s=i!==-1?i:n;s!==-1&&(o=o.slice(0,s)+`
776
+ );`)}}await f(r,t)},yn=async e=>{let r=[Qt.join(e,c.ROOT_PAGE),Qt.join(e,"src/app/[locale]/page.tsx")],t="";for(let i of r)if(m(i)){t=i;break}if(!t)return;let o=await d(t);if(o.includes("Counter")||(o=`import { Counter } from '@/features/counter';
777
+ ${o}`),!o.includes("<Counter />")){let i=o.lastIndexOf("</div>"),n=o.lastIndexOf("</main>"),s=n!==-1?n:i;s!==-1&&(o=o.slice(0,s)+`
775
778
  <div className="mt-8">
776
779
  <h2 className="mb-4 text-2xl font-bold">Redux Counter</h2>
777
780
  <Counter />
778
781
  </div>
779
- `+o.slice(s),await u(t,o))}};var Dt=async e=>{let r=I("Setting up Redux Toolkit..."),t=Ft.join(e,".next-maker-temp-redux");try{let{isSetup:o,reason:n}=await Do(e);if(o){r.fail(`Redux is already set up (${n}).`);return}await Lo(e),await ko(t,r),r.text="Copying Redux files...",await jo(e,t),r.text="Creating Counter feature...",await Fo(e,t),r.text="Updating providers and pages...",await Go(e),await Ho(e),await Uo(e),r.text="Installing dependencies...",await H(e,"@reduxjs/toolkit"),await H(e,"react-redux"),await H(e,"redux-persist"),await H(e,"react-secure-storage");let i=Ft.join(e,a.VITEST_CONFIG);if(l(i)){let c=JSON.parse(await d(Ft.join(e,a.PACKAGE_JSON))),p={...c.dependencies,...c.devDependencies};await ee(e,{redux:!0,i18n:!!p["next-intl"]})}r.text="Formatting code...";let s=await D(e);await G(e,s,"lint:fix"),r.succeed(gs.green("Redux Toolkit setup successfully!"))}catch(o){throw r.fail("Failed to setup Redux Toolkit."),o}finally{await P(t)}};C();import hs from"node:fs/promises";import ne from"node:path";import xs from"degit";import ys from"picocolors";T();var Ps=["vitest","jsdom","@vitejs/plugin-react","@testing-library/dom","@testing-library/jest-dom","@testing-library/react","@testing-library/user-event"],Lt=async e=>{let r=I("Setting up testing (Vitest + RTL)..."),t=ne.join(e,".next-maker-temp-tests");try{let o=ne.join(e,a.VITEST_CONFIG);if(l(o)){r.fail("Testing is already set up (vitest.config.ts exists).");return}r.text="Fetching assets from starter repo...",await xs("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(t),await A(ne.join(t,a.VITEST_CONFIG),ne.join(e,a.VITEST_CONFIG));let i=ne.join(e,a.TEST_DIR);await hs.mkdir(i,{recursive:!0}),await A(ne.join(t,a.TEST_DIR,"setup.ts"),ne.join(i,"setup.ts"));let s=ne.join(e,a.PACKAGE_JSON),c=JSON.parse(await d(s)),p={...c.dependencies,...c.devDependencies},f=!!(p["@reduxjs/toolkit"]&&p["react-redux"]),g=!!p["next-intl"];await ee(e,{redux:f,i18n:g}),await j(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)),r.text="Installing testing devDependencies...";let y=await D(e);await Ke(e,y,Ps),r.text="Formatting code...",await G(e,y,"lint:fix"),r.succeed(ys.green("Testing setup complete."))}catch(o){throw r.fail("Failed to set up testing."),o}finally{await P(t)}};var{prompt:Ss}=Ts,Mo=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").action(async r=>{try{if(m(Gt.cyan(`
782
+ `+o.slice(s),await f(t,o))}};var Ve=async e=>{let r=R("Setting up Redux Toolkit..."),t=er.join(e,".next-maker-temp-redux");try{let{isSetup:o,reason:i}=await un(e);if(o){r.fail(`Redux is already set up (${i}).`);return}await fn(e),await ln(t,r),r.text="Copying Redux files...",await mn(e,t),r.text="Creating Counter feature...",await dn(e,t),r.text="Updating providers and pages...",await gn(e),await hn(e),await yn(e),r.text="Installing dependencies...",await z(e,"@reduxjs/toolkit"),await z(e,"react-redux"),await z(e,"redux-persist"),await z(e,"react-secure-storage");let n=er.join(e,c.VITEST_CONFIG);if(m(n)){let a=JSON.parse(await d(er.join(e,c.PACKAGE_JSON))),p={...a.dependencies,...a.devDependencies};await re(e,{redux:!0,i18n:!!p["next-intl"]})}r.text="Formatting code...";let s=await O(e);await U(e,s,"lint:fix"),r.succeed(ma.green("Redux Toolkit setup successfully!"))}catch(o){throw r.fail("Failed to setup Redux Toolkit."),o}finally{await S(t)}};var xn={id:"redux",name:"Redux Toolkit",description:"Redux Toolkit + react-redux + redux-persist + StoreProvider",detect:async e=>{let{detectProjectSetup:r}=await Promise.resolve().then(()=>(L(),$e));return(await r(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/}],apply:Ve};w();P();import ha from"node:path";w();import fa from"node:path";import ga from"picocolors";P();var vn=[{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"}],Pn=/(const\s+nextConfig\s*:\s*NextConfig\s*=\s*\{)/,da=/^\s+headers\s*:/m,ua=e=>`
783
+ headers: async () => {
784
+ return [
785
+ {
786
+ source: '/:path*',
787
+ headers: [
788
+ ${e.map(({key:t,value:o})=>` { key: '${t}', value: '${o}' },`).join(`
789
+ `)}
790
+ ],
791
+ },
792
+ ];
793
+ },`,Se=e=>da.test(e),tr=(e,r=vn)=>{if(Se(e))return e;if(!Pn.test(e))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");return e.replace(Pn,`$1${ua(r)}`)};var Je=async e=>{let r=R("Adding security headers to next.config.ts...");try{let t=fa.join(e,c.NEXT_CONFIG);if(!m(t))throw new Error(`${c.NEXT_CONFIG} not found.`);let o=await d(t);if(Se(o)){r.succeed("Security headers already configured.");return}let i=tr(o);await f(t,i),r.succeed(ga.green("Security headers added."))}catch(t){throw r.fail("Failed to add security headers."),t}};var Sn={id:"security-headers",name:"Security Headers",description:"Hardened HTTP headers in next.config.ts",detect:async e=>{let r=ha.join(e,c.NEXT_CONFIG);return m(r)?Se(await d(r)):!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:Je};w();P();import Sa from"node:path";w();import ya from"node:fs/promises";import ae from"node:path";import xa from"degit";import Pa from"picocolors";P();var va=["vitest","jsdom","@vitejs/plugin-react","@testing-library/dom","@testing-library/jest-dom","@testing-library/react","@testing-library/user-event"],Be=async e=>{let r=R("Setting up testing (Vitest + RTL)..."),t=ae.join(e,".next-maker-temp-tests");try{let o=ae.join(e,c.VITEST_CONFIG);if(m(o)){r.fail("Testing is already set up (vitest.config.ts exists).");return}r.text="Fetching assets from starter repo...",await xa("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(t),await _(ae.join(t,c.VITEST_CONFIG),ae.join(e,c.VITEST_CONFIG));let n=ae.join(e,c.TEST_DIR);await ya.mkdir(n,{recursive:!0}),await _(ae.join(t,c.TEST_DIR,"setup.ts"),ae.join(n,"setup.ts"));let s=ae.join(e,c.PACKAGE_JSON),a=JSON.parse(await d(s)),p={...a.dependencies,...a.devDependencies},u=!!(p["@reduxjs/toolkit"]&&p["react-redux"]),g=!!p["next-intl"];await re(e,{redux:u,i18n:g}),await k(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)),r.text="Installing testing devDependencies...";let y=await O(e);await ue(e,y,va),r.text="Formatting code...",await U(e,y,"lint:fix"),r.succeed(Pa.green("Testing setup complete."))}catch(o){throw r.fail("Failed to set up testing."),o}finally{await S(t)}};var wn={id:"tests",name:"Tests",description:"Vitest + React Testing Library + jsdom",detect:async e=>m(Sa.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:Be};P();import Ra from"node:path";w();import Cn from"node:path";import Ta from"picocolors";P();var wa={npm:"npm run",yarn:"yarn",pnpm:"pnpm",bun:"bun run"},Ca=e=>{let r=wa[e];return["ci:check","type-check","check:deprecated","test","build"].map(t=>`${r} ${t}`).join(" && ")},rr=(e,r)=>{let t={...e.scripts??{}},o={...e.devDependencies??{}};return t["env:sync"]||(t["env:sync"]="tsx scripts/sync-env.ts"),t["check:deprecated"]||(t["check:deprecated"]="tsx scripts/check-deprecated.ts"),t["type-check"]||(t["type-check"]="tsc --noEmit"),t.validate||(t.validate=Ca(r)),!o.tsx&&!e.dependencies?.hasOwnProperty("tsx")&&(o.tsx="*"),{...e,scripts:t,devDependencies:o}};var or=`import * as fs from 'node:fs';
794
+ import * as path from 'node:path';
795
+
796
+ const envPath = path.join(process.cwd(), '.env');
797
+ const examplePath = path.join(process.cwd(), '.env.example');
798
+
799
+ if (!fs.existsSync(envPath)) {
800
+ console.log('\u26A0\uFE0F No .env file found. Skipping sync.');
801
+ process.exit(0);
802
+ }
803
+
804
+ const envContent = fs.readFileSync(envPath, 'utf-8');
805
+ const lines = envContent.split('\\n');
806
+
807
+ let isPublicBlock = false;
808
+
809
+ const exampleLines = lines.map((line) => {
810
+ const trimmed = line.trim();
811
+
812
+ // Preserve empty lines and reset public block state
813
+ if (!trimmed) {
814
+ isPublicBlock = false;
815
+ return line;
816
+ }
817
+
818
+ // Preserve comments
819
+ if (trimmed.startsWith('#')) {
820
+ if (line.toLowerCase().includes('-public')) {
821
+ isPublicBlock = true;
822
+ }
823
+ return line;
824
+ }
825
+
826
+ // Parse KEY=VALUE
827
+ const match = line.match(/^([^=]+)=(.*)$/);
828
+
829
+ if (match) {
830
+ const key = match[1];
831
+
832
+ // Public marker: explicit "# -public" comment, or "KEY=VAL # -public"
833
+ if (isPublicBlock || line.toLowerCase().includes('-public')) {
834
+ isPublicBlock = false;
835
+ return line;
836
+ }
837
+
838
+ isPublicBlock = false;
839
+ return \`\${key}=\`;
840
+ }
841
+
842
+ isPublicBlock = false;
843
+ return line;
844
+ });
845
+
846
+ const newExampleContent = exampleLines.join('\\n');
847
+
848
+ let currentExampleContent = '';
849
+ if (fs.existsSync(examplePath)) {
850
+ currentExampleContent = fs.readFileSync(examplePath, 'utf-8');
851
+ }
852
+
853
+ if (currentExampleContent !== newExampleContent) {
854
+ fs.writeFileSync(examplePath, newExampleContent);
855
+ console.log('\u2705 Synchronized .env.example with .env');
856
+ } else {
857
+ console.log('\u2728 .env.example is already up to date');
858
+ }
859
+ `,nr=`/**
860
+ * Walks every identifier in the project and flags any whose resolved TypeScript
861
+ * symbol carries a \`@deprecated\` JSDoc tag. Catches deprecated API usage that
862
+ * \`tsc --noEmit\` does not surface (deprecations are "suggestion"-level, not
863
+ * errors) and that Biome does not yet detect.
864
+ *
865
+ * Exits 1 if any deprecated usage is found (so it can gate CI).
866
+ */
867
+ import path from 'node:path';
868
+ import ts from 'typescript';
869
+
870
+ const cwd = process.cwd();
871
+ const configPath = ts.findConfigFile(cwd, ts.sys.fileExists, 'tsconfig.json');
872
+
873
+ if (!configPath) {
874
+ console.error('tsconfig.json not found');
875
+ process.exit(1);
876
+ }
877
+
878
+ const raw = ts.readConfigFile(configPath, ts.sys.readFile).config;
879
+ const parsed = ts.parseJsonConfigFileContent(raw, ts.sys, path.dirname(configPath));
880
+
881
+ const program = ts.createProgram({
882
+ rootNames: parsed.fileNames,
883
+ options: parsed.options,
884
+ });
885
+
886
+ const checker = program.getTypeChecker();
887
+
888
+ function isDeprecated(sym: ts.Symbol | undefined): boolean {
889
+ if (!sym) return false;
890
+ return sym.getJsDocTags(checker).some((tag) => tag.name === 'deprecated');
891
+ }
892
+
893
+ let hits = 0;
894
+
895
+ for (const sourceFile of program.getSourceFiles()) {
896
+ if (sourceFile.fileName.includes('node_modules')) continue;
897
+ if (!sourceFile.fileName.startsWith(cwd)) continue;
898
+
899
+ const visit = (node: ts.Node): void => {
900
+ if (ts.isIdentifier(node)) {
901
+ const sym = checker.getSymbolAtLocation(node);
902
+ if (isDeprecated(sym)) {
903
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
904
+ console.log(
905
+ \`\${path.relative(cwd, sourceFile.fileName)}:\${line + 1}:\${character + 1} \${node.text} (@deprecated)\`,
906
+ );
907
+ hits++;
908
+ }
909
+ }
910
+ ts.forEachChild(node, visit);
911
+ };
912
+
913
+ visit(sourceFile);
914
+ }
915
+
916
+ if (hits === 0) {
917
+ console.log('\u2713 No deprecated API usage found.');
918
+ process.exit(0);
919
+ }
920
+
921
+ console.log(\`\\n\${hits} deprecated symbol use(s) found.\`);
922
+ process.exit(1);
923
+ `;var Ea=[{relative:"scripts/sync-env.ts",content:or},{relative:"scripts/check-deprecated.ts",content:nr}],Xe=async e=>{let r=R("Adding validation scripts...");try{let t=!1;for(let{relative:n,content:s}of Ea){let a=Cn.join(e,n);m(a)||(await f(a,s),t=!0)}let o=await O(e),i=!1;await k(Cn.join(e,c.PACKAGE_JSON),n=>{let s=n.devDependencies?.tsx,a=rr(n,o);return i=!s&&!!a.devDependencies?.tsx,a}),i&&(r.text="Installing tsx...",await ue(e,o,["tsx"])),r.succeed(Ta.green(t?"Validation scripts added (env:sync, check:deprecated, validate).":"Validation scripts already present \u2014 refreshed package.json."))}catch(t){throw r.fail("Failed to add validation scripts."),t}};var Tn=["scripts/sync-env.ts","scripts/check-deprecated.ts"],En={id:"validate-scripts",name:"Validation Scripts",description:"sync-env, check-deprecated, and the validate chain",detect:async e=>Tn.every(r=>m(Ra.join(e,r))),files:Tn.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:Xe};w();P();import we from"node:path";var Rn=async e=>{let r=we.join(e,c.PACKAGE_JSON);return m(r)?JSON.parse(await d(r)):null},ba=async(e,r)=>{let t=we.join(e,c.PACKAGE_JSON);await f(t,`${JSON.stringify(r,null,2)}
924
+ `)},bn=(e,r)=>(r==="dependency"?e.dependencies:e.devDependencies)??{},Ye=async(e,r)=>{let t=await e.detect(r),o=[];if(!t)return{manifest:e,installed:!1,drift:[]};for(let n of e.files)n.required!==!1&&(m(we.join(r,n.path))||o.push({kind:"missingFile",file:n.path}));let i=await Rn(r);if(i){for(let s of e.packages)bn(i,s.kind)[s.name]||o.push({kind:"missingPackage",name:s.name,depKind:s.kind});let n=i.scripts??{};for(let s of e.scripts){let a=n[s.name];a?s.expectedValue&&a!==s.expectedValue&&o.push({kind:"mismatchedScript",name:s.name,expected:s.expectedValue,actual:a}):o.push({kind:"missingScript",name:s.name})}}for(let n of e.injections){let s=we.join(r,n.file);if(!m(s)){o.push({kind:"missingInjection",file:n.file,description:n.description});continue}let a=await d(s);n.presence.test(a)||o.push({kind:"missingInjection",file:n.file,description:n.description})}return{manifest:e,installed:t,drift:o}},ht=async(e,r,t={})=>{let o=t.dryRun??!1,i={filesRemoved:[],packagesUninstalled:[],scriptsRemoved:[],blocksStripped:[],manualCleanup:[]};for(let a of e.injections){let p=we.join(r,a.file);if(!m(p))continue;if(!a.removePattern){i.manualCleanup.push({file:a.file,description:a.description});continue}let u=await d(p);if(!a.presence.test(u))continue;let g=u.replace(a.removePattern,"");g!==u?(o||await f(p,g),i.blocksStripped.push({file:a.file,description:a.description})):i.manualCleanup.push({file:a.file,description:a.description})}let{rm:n}=await import("node:fs/promises");for(let a of e.files){if(!a.generated)continue;let p=we.join(r,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}o||await n(p,{recursive:!0,force:!0}),i.filesRemoved.push(a.path)}}let s=await Rn(r);if(s){let a=!1;if(s.scripts)for(let p of e.scripts)s.scripts[p.name]&&(o||delete s.scripts[p.name],i.scriptsRemoved.push(p.name),a=!0);for(let p of e.packages)bn(s,p.kind)[p.name]&&i.packagesUninstalled.push(p.name);a&&!o&&await ba(r,s)}if(!o&&i.packagesUninstalled.length>0){let a=await O(r);await wt(r,a,i.packagesUninstalled)}return i};var ye=[Sn,En,ko,cn,Io,wn,zo,qo,xn,an],$n=e=>ye.find(r=>r.id===e);var $a=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 ${j.dim(e.expected)} but got ${j.dim(e.actual)}`;case"missingInjection":return`missing block in ${e.file}: ${e.description}`}},Na=e=>{let r=e.filter(o=>o.installed),t=r.filter(o=>o.drift.length>0);return{installedCount:r.length,driftedCount:t.length,cleanCount:r.length-t.length,driftedResults:t}},Nn=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 r=>{try{let t=process.cwd(),o=r.feature?ye.filter(s=>s.id===r.feature):ye;if(r.feature&&o.length===0)throw new Error(`Unknown feature "${r.feature}". Valid: ${ye.map(s=>s.id).join(", ")}.`);let i=[];for(let s of o)i.push(await Ye(s,t));r.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(j.cyan(`
925
+ \u{1FA7A} Project Doctor
926
+ `));for(let s of i){let{manifest:a,installed:p,drift:u}=s;if(!p){l(` ${j.dim("\u2014")} ${j.dim(a.name)} ${j.dim("(not installed)")}`);continue}if(u.length===0){l(` ${j.green("\u2713")} ${a.name}`);continue}l(` ${j.yellow("!")} ${j.bold(a.name)} ${j.dim(`(${u.length} issue${u.length===1?"":"s"})`)}`);for(let g of u)l(` ${j.yellow("\u2022")} ${$a(g)}`)}let n=Na(i);l(""),l(j.dim(`${n.cleanCount} clean, ${n.driftedCount} drifted, ${i.length-n.installedCount} not installed`)),n.driftedCount===0&&(l(j.green(`
927
+ \u2713 No drift detected.
928
+ `)),process.exit(0)),r.fix||(l(j.dim(`
929
+ Run with --fix to re-apply drifted features.
930
+ `)),process.exit(1)),l(j.cyan(`
931
+ \u{1F527} Applying fixes...
932
+ `));for(let s of n.driftedResults){if(!s.manifest.apply){l(j.yellow(` \u26A0\uFE0F ${s.manifest.name} has no apply() \u2014 skipping.`));continue}try{await s.manifest.apply(t)}catch(a){v(`Failed to fix ${s.manifest.name}: ${a}`)}}l(j.green(`
933
+ \u2713 Doctor finished.
934
+ `))}catch(t){v(`${t instanceof Error?t.message:t}`),process.exit(1)}})};import Ce from"picocolors";w();P();import ir from"node:path";var Ia=/^[A-Z][A-Z0-9_]*$/,An=e=>{if(!Ia.test(e))throw new Error(`Invalid env var name "${e}". Use UPPER_SNAKE_CASE (e.g. SENTRY_DSN, NEXT_PUBLIC_API_URL).`)},ce=(e,r)=>r?e.startsWith("NEXT_PUBLIC_")?e:`NEXT_PUBLIC_${e}`:e,Aa=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,"\\'")}')`}},ka=e=>{switch(e.type){case"url":return"z.url()";case"number":return"z.coerce.number()";case"boolean":return"z.coerce.boolean()";case"enum":{let r=e.enumValues??[];if(r.length===0)throw new Error(`Enum env var "${e.name}" requires --enum values.`);return`z.enum([${r.map(o=>`'${o.replace(/'/g,"\\'")}'`).join(", ")}])`}default:return"z.string()"}},kn=e=>{let r=ce(e.name,e.public),o=ka(e),i=e.default!==void 0,n=!e.required&&!i;i&&(o+=Aa(e)),n&&e.type!=="enum"&&(o+=".optional()");let s;if(e.type==="enum"?s=o:s=`z.preprocess(emptyStringToUndefined, ${o})`,e.description){let a=e.description.replace(/'/g,"\\'");s+=`
935
+ .describe('${a}')`}return` ${r}: ${s},`},In=/(export const envSchema\s*=\s*z\.object\(\{)([\s\S]*?)(\}\);?)/,On=(e,r)=>{let t=ce(r.name,r.public);if(new RegExp(`\\b${t}\\s*:`).test(e))return e;let i=e.match(In);if(!i)throw new Error("Could not locate `export const envSchema = z.object({ \u2026 })` in schema.ts.");let[,n,s,a]=i,p=s.replace(/\s+$/,""),u=p.length===0||/,\s*$/.test(p)?p:`${p},`,g=kn(r),y=`${u}
936
+ ${g}
937
+ `;return e.replace(In,`${n}${y}${a}`)},Oa="# -public",_a=e=>{let r=ce(e.name,e.public),t=e.default??"",o=e.public?` ${Oa}`:"";return`${r}=${t}${o}`},_n=(e,r)=>{let t=ce(r.name,r.public);if(new RegExp(`^${t}=`,"m").test(e))return e;let i=e===""||e.endsWith(`
938
+ `)?"":`
939
+ `,n=e===""?"":`
940
+ `,s=r.description?`# ${r.description}
941
+ `:"";return`${e}${i}${n}${s}${_a(r)}
942
+ `},Fn=(e,r)=>{let t=ce(r.name,r.public);if(new RegExp(`^${t}=`,"m").test(e))return e;let i=e===""||e.endsWith(`
943
+ `)?"":`
944
+ `,n=r.default??"";return`${e}${i}${t}=${n}
945
+ `},sr=async(e,r)=>{An(r.name);let t=ir.join(e,"src/lib/env/schema.ts");if(!m(t))throw new Error("src/lib/env/schema.ts not found \u2014 run `next-maker init` first.");let o=await d(t),i=On(o,r),n=i!==o;n&&await f(t,i);let s=ir.join(e,c.ENV_EXAMPLE),a=!1;if(m(s)){let g=await d(s),y=_n(g,r);a=y!==g,a&&await f(s,y)}let p=ir.join(e,".env"),u=!1;if(m(p)){let g=await d(p),y=Fn(g,r);u=y!==g,u&&await f(p,y)}return{schemaUpdated:n,envExampleUpdated:a,envUpdated:u}};var jn=new Set(["string","url","number","boolean","enum"]),Fa=e=>{let r=(e??"string").toLowerCase();if(!jn.has(r))throw new Error(`Invalid --type "${e}". Valid: ${Array.from(jn).join(", ")}.`);return r},ja=e=>{if(!e)return;let r=e.split(",").map(t=>t.trim()).filter(Boolean);return r.length===0?void 0:r},Dn=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(r,t)=>{try{let o=process.cwd();if(l(Ce.cyan(`
946
+ \u{1F510} Env Var Generator
947
+ `)),t.required&&t.default!==void 0)throw new Error("--required and --default are mutually exclusive.");let i=Fa(t.type),n=ja(t.enum);if(i==="enum"&&(!n||n.length===0))throw new Error("--type=enum requires at least one value via --enum a,b,c.");let s={name:r,type:i,required:!!t.required,default:t.default,description:t.describe,enumValues:n,public:!!t.public};h.start("Updating schema, .env.example, and .env...");let a=await sr(o,s);h.succeed("Env var written");let p=ce(s.name,s.public);l(Ce.green(`
948
+ \u2728 ${p} declared.
949
+ `)),l(Ce.dim("Touched:")),l(Ce.dim(` ${a.schemaUpdated?"\u270F\uFE0F ":"\u23ED "} src/lib/env/schema.ts`)),l(Ce.dim(` ${a.envExampleUpdated?"\u270F\uFE0F ":"\u23ED "} .env.example`)),l(Ce.dim(` ${a.envUpdated?"\u270F\uFE0F ":"\u23ED "} .env`)),l("")}catch(o){h.fail("Env var declaration failed"),v(`${o instanceof Error?o.message:o}`),process.exit(1)}})};import fr from"node:path";import D from"picocolors";L();L();import Qa from"node:path";import{readFile as Da,writeFile as La}from"node:fs/promises";import Ma from"node:path";var Ke=(e,r)=>{let t=/import\s+.*\s+from\s+['"].*['"];?\n/g,o=e.match(t);if(o&&o.length>0){let i=o[o.length-1],n=e.lastIndexOf(i);return e.slice(0,n+i.length)+r+`
950
+ `+e.slice(n+i.length)}return`${r}
951
+ ${e}`},ar=(e,r,t)=>{let o=/combineReducers\(\{([^}]*)\}\)/s,i=e.match(o);if(!i)throw new Error("Could not find combineReducers in rootReducer.ts");let n=i[1],s=`
952
+ ${r}: ${t},`,a=n.trimEnd()+s;return e.replace(o,`combineReducers({${a}
953
+ })`)},qe=(e,r)=>{let t=e.lastIndexOf("} as const;");if(t===-1)throw new Error("Could not find closing brace of AppApis object");let o=e.substring(0,t),i=e.substring(t);return`${o.trimEnd()}
954
+ ${r}
955
+ ${i}`};var We=async e=>{let{serviceName:r,projectPath:t}=e,o=A(r),i=Ma.join(t,"src","lib","config","app-apis.ts");try{let n=await Da(i,"utf-8");if(n.includes(`${o}:`))return;if(!n.match(/export const AppApis = \{[\s\S]*?\} as const;/))throw new Error("Could not find AppApis object in app-apis.ts");let s=` ${o}: {
956
+ base: \`\${API_PREFIX}/${r}\`,
957
+ getAll: \`\${API_PREFIX}/${r}\`,
958
+ },`;n=qe(n,s),await La(i,n)}catch(n){throw new Error(`Failed to register API endpoints: ${n}`,{cause:n})}};import{readFile as Ga,writeFile as Ha}from"node:fs/promises";import Ua from"node:path";P();var cr=async(e,r,t)=>{let o=Ua.join(e,"src","lib","config","app-paths.ts");if(!m(o))return;let i=await Ga(o,"utf-8"),n=A(r);if(i.includes(`${n}:`))return;let s=i.lastIndexOf("} as const;");if(s===-1)return;let a=` ${n}: '${t}',
959
+ `;i=i.slice(0,s)+a+i.slice(s),await Ha(o,i)};w();P();import yt from"node:path";var za=e=>new RegExp(`<\\s*${e}\\b`),Ln=(e,r)=>{if(za(r).test(e))return e;let t=/^(?<indent>[ \t]*)\{children\}\s*$/m,o=e.match(t);if(!o||o.index===void 0)throw new Error("Could not locate `{children}` line in RootProvider \u2014 expected a line containing only `{children}`.");let i=o.groups?.indent??"",n=`${i} `,s=`${i}<${r}>
960
+ ${n}{children}
961
+ ${i}</${r}>`;return e.replace(t,s)},Mn=(e,r)=>{let t=`export * from './${r}';`;if(e.includes(t))return e;let o=e.split(`
962
+ `),i=[],n=[];for(let y of o)/^export \* from '\.\/.*';\s*$/.test(y)?i.push(y):n.push(y);let s=[...i,t].sort(),a=o.findIndex(y=>/^export \* from '\.\//.test(y));if(a===-1)return`${t}
963
+ ${e.replace(/^\n+/,"")}`;let p=o.slice(0,a),u=o.findIndex((y,x)=>x>a&&!/^export \* from '\.\//.test(y)),g=u===-1?[]:o.slice(u);return[...p,...s,...g].join(`
964
+ `)},Va=c.PROVIDERS,Ja=c.ROOT_PROVIDER,Ba=c.PROVIDERS_INDEX,Gn=async(e,r={fileExists:m,readFile:d})=>{let t=yt.join(e,Ja);if(r.fileExists(t))return t;let o=yt.join(e,Va);if(!r.fileExists(o))return null;let{readdir:i}=await import("node:fs/promises"),s=(await i(o).catch(()=>[])).filter(p=>p.endsWith(".tsx")),a=null;for(let p of s){let u=yt.join(o,p),g=await r.readFile(u);if(!/\{children\}/.test(g))continue;let x=((g.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},pr=async e=>{let{projectPath:r,componentName:t,fileBaseName:o}=e,i=await Gn(r);if(i){let a=await d(i),p=a;(!/from '\.\//.test(a)||!a.includes(`{ ${t} }`))&&(p=Ke(p,`import { ${t} } from './${o}';`)),p=Ln(p,t),p!==a&&await f(i,p)}let n=yt.join(r,Ba),s=null;if(m(n)){let a=await d(n),p=Mn(a,o);p!==a&&await f(n,p),s=n}return{rootProviderFile:i,barrelFile:s}};import{readFile as Xa,writeFile as Ya}from"node:fs/promises";import Ka from"node:path";var Ze=async e=>{let{projectPath:r,name:t,persist:o,importPath:i}=e,n=Ka.join(r,"src","store","rootReducer.ts");try{let s=await Xa(n,"utf-8"),a=A(t),p=`${a}Reducer`,u=`${a}PersistConfig`,g=i.replace(/^src\//,"@/"),y=o?`import { ${p}, ${u} } from '${g}';`:`import { ${p} } from '${g}';`;s=Ke(s,y);let x=o?`persistReducer(${u}, ${p})`:p;s=ar(s,a,x),await Ya(n,s)}catch(s){throw new Error(`Failed to register reducer '${t}' in rootReducer: ${s}`,{cause:s})}};P();import{readFile as qa,writeFile as Wa}from"node:fs/promises";import Za from"node:path";var lr=async(e,r)=>{let t=Za.join(e,"src","i18n","translations","en.json");if(!m(t))return;let o=await qa(t,"utf-8"),i=JSON.parse(o);i[r]||(i[r]={title:r,description:`${r} page description`},await Wa(t,`${JSON.stringify(i,null,2)}
965
+ `))};var mr=()=>[{name:"Project setup detected",spinnerText:"Detecting project setup...",execute:async e=>{e.detection=await I(e.projectPath)}},{name:"Feature files generated",spinnerText:"Generating feature files...",execute:async e=>{await Lt({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 We({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 Ze({projectPath:e.projectPath,name:e.featureName,persist:e.persistStore,importPath:Qa.join(e.basePath,e.featureName,"store")})}}];var xe=async(e,r)=>{for(let t of e)if(!t.shouldSkip?.(r)){r.spinner.start(t.spinnerText);try{await t.execute(r),r.spinner.succeed(t.name)}catch(o){throw r.spinner.fail(t.name),o}}};var dr=()=>[{name:"Service files generated",spinnerText:"Generating service files...",execute:async e=>{await Ne({name:e.serviceName,outputPath:e.servicePath,httpClient:e.httpClient})}},{name:"API endpoints registered",spinnerText:"Registering API endpoints...",execute:async e=>{await We({serviceName:e.serviceName,projectPath:e.projectPath})}}];import ec from"node:path";var ur=()=>[{name:"Slice files generated",spinnerText:"Generating slice files...",execute:async e=>{await ke({name:e.sliceName,outputPath:e.slicePath,persist:e.persistSlice})}},{name:"Slice registered in rootReducer",spinnerText:"Registering slice in rootReducer...",execute:async e=>{await Ze({projectPath:e.projectPath,name:e.sliceName,persist:e.persistSlice,importPath:ec.join(e.basePath,e.sliceName)})}}];import tc from"enquirer";var{prompt:rc}=tc,Hn=async(e,r,t,o,i,n,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."}),r&&o===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}})),t&&t!=="none"&&n===void 0&&s===void 0&&(a.push({type:"confirm",name:"createService",message:"Generate API service for this feature?",initial:!0}),t==="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 rc(a):{};return{featureName:e||p.featureName,hasRedux:r||!1,createStore:o===!0?!1:i!==void 0?!0:p.createStore||!1,persistStore:i==="persist"?!0:i==="no-persist"?!1:p.persistStore||!1,httpClient:t||"none",createService:n===!0?!1:s!==void 0?!0:p.createService||!1,selectedHttpClient:s||p.selectedHttpClient||(t==="both"?"fetch":t!=="none"?t:void 0)}};var Un=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(r,t)=>{try{let o=process.cwd();oc(t),l(D.cyan(`
966
+ \u{1F3AF} Feature Generator
967
+ `));let i=mr();h.start("Detecting project setup...");let{detectProjectSetup:n}=await Promise.resolve().then(()=>(L(),$e)),s=await n(o);h.succeed("Project setup detected"),l(D.dim(` Redux: ${s.hasRedux?"\u2713":"\u2717"}`)),l(D.dim(` HTTP Client: ${s.httpClient}`)),l(D.dim(` i18n: ${s.hasI18n?"\u2713":"\u2717"}
968
+ `));let a=await Hn(r,s.hasRedux,s.httpClient,t.skipStore,t.store,t.skipService,t.service),p=t.path||fr.join("src","features"),u=fr.join(o,p,a.featureName);await ie(o,a.featureName,p)&&(v(`Feature '${a.featureName}' already exists at ${p}!`),process.exit(1)),await xe(i.slice(1),{projectPath:o,spinner:h,featureName:a.featureName,basePath:p,featurePath:u,createStore:a.createStore,persistStore:a.persistStore,createService:a.createService,httpClient:a.selectedHttpClient,detection:s}),nc(a,p)}catch(o){h.fail("Feature generation failed"),v(`${o}`),process.exit(1)}})},oc=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))},nc=(e,r)=>{let t=fr.join(r,e.featureName);l(D.green(`
969
+ \u2728 Feature '${e.featureName}' created successfully!
970
+ `)),l(D.dim("Generated files:")),l(D.dim(` \u{1F4C2} ${t}/`)),l(D.dim(" \u251C\u2500\u2500 components/")),l(D.dim(" \u251C\u2500\u2500 hooks/")),l(D.dim(" \u251C\u2500\u2500 types/")),e.createStore&&l(D.dim(" \u251C\u2500\u2500 store/")),e.createService&&l(D.dim(" \u251C\u2500\u2500 services/")),l(D.dim(` \u2514\u2500\u2500 index.ts
971
+ `)),l(D.cyan("Next steps:"));let o=r.replace(/^src\//,"@/");l(D.dim(` 1. Import and use the feature: import { ${e.featureName} } from '${o}/${e.featureName}'`)),e.createStore&&l(D.dim(` 2. Customize your Redux slice in: ${t}/store/`)),e.createService&&l(D.dim(` 3. Add API methods in: ${t}/services/${e.featureName}.service.ts`)),l("")};import gr from"node:path";import Te from"picocolors";L();import ic from"enquirer";var{prompt:sc}=ic,zn=async e=>e?{hookName:e}:await sc({type:"input",name:"hookName",message:'Hook name (kebab-case, without "use" prefix):',validate:t=>t?/^[a-z][a-z0-9-]*$/.test(t)?!0:"Use lowercase letters, numbers, and hyphens only":"Hook name is required"});var Vn=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(r,t)=>{try{let o=process.cwd();l(Te.cyan(`
972
+ \u{1FA9D} Hook Generator
973
+ `));let i=await I(o),n=await zn(r),a=`use${b(n.hookName)}`,p=ac(t,i.hasTests);h.start("Generating hook..."),await Gt({name:n.hookName,projectPath:o,isClient:t.client??!0,featurePath:t.feature}),h.succeed("Hook generated");let u=t.feature?gr.join(o,t.feature,"hooks",`${a}.ts`):gr.join(o,"src/hooks",`${a}.ts`),g=null;p&&(h.start("Generating test..."),g=await Q({projectPath:o,sourceFile:u,kind:"hook",symbolName:a,hookUsesStore:i.hasRedux&&!!t.feature}),h.succeed("Test generated"));let y=t.feature?`${t.feature}/hooks/${a}.ts`:`src/hooks/${a}.ts`;l(Te.green(`
974
+ \u2728 Hook '${a}' created successfully!
975
+ `)),l(Te.dim(` \u{1F4C4} ${y}`)),g&&l(Te.dim(` \u{1F9EA} ${gr.relative(o,g)}`)),l(""),l(Te.cyan("Usage:"));let x=t.feature?`${t.feature.replace(/^src\//,"@/")}/hooks/${a}`:`@/hooks/${a}`;l(Te.dim(` import { ${a} } from '${x}';`)),l("")}catch(o){h.fail("Hook generation failed"),v(`${o}`),process.exit(1)}})},ac=(e,r)=>e.noTest?!1:e.test?!0:r;import xt from"picocolors";L();var Jn=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(r,t)=>{try{let o=process.cwd();l(xt.cyan(`
976
+ \u{1F4D0} Layout Generator
977
+ `)),h.start("Detecting project setup...");let i=await I(o);h.succeed("Project setup detected");let n=i.hasI18n&&t.locale!==!1;l(xt.dim(` i18n: ${n?"\u2713":"\u2717"}
978
+ `)),h.start("Generating layout...");let s=await Ht({segment:r,at:t.at,projectPath:o,hasI18n:n,withGroup:!!t.group});h.succeed("Layout generated"),l(xt.green(`
979
+ \u2728 ${s.componentName} created!
980
+ `)),l(xt.dim(` \u{1F4C4} ${s.displayPath}`)),l("")}catch(o){h.fail("Layout generation failed"),v(`${o instanceof Error?o.message:o}`),process.exit(1)}})};import lc from"node:path";import W from"picocolors";P();L();import cc from"enquirer";var{prompt:pc}=cc,Bn=async e=>{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"},{type:"confirm",name:"copyTranslations",message:"Copy translations from English? (No = empty values)",initial:!1});let t=await pc(r);return{code:e||t.code,name:t.name,country:t.country,flag:t.flag,copyTranslations:t.copyTranslations}};var Xn=e=>{e.command("locale [code]").description("Add a new locale/language").option("--copy-translations","Copy translations from English instead of empty values").action(async(r,t)=>{try{let o=process.cwd();l(W.cyan(`
981
+ \u{1F30D} Locale Generator
982
+ `)),h.start("Detecting project setup...");let i=await I(o);h.succeed("Project setup detected"),i.hasI18n||(h.fail("i18n is not set up in this project"),v("Please set up internationalization first"),l(W.dim(`
983
+ Run: npx @teispace/next-maker setup --i18n
984
+ `)),process.exit(1));let n=await Bn(r),s=lc.join(o,"src","i18n","translations",`${n.code}.json`);m(s)&&(v(`Locale '${n.code}' already exists!`),process.exit(1)),h.start("Adding locale..."),await Ut({...n,projectPath:o,copyTranslations:t.copyTranslations??n.copyTranslations}),h.succeed("Locale added"),l(W.green(`
985
+ \u2728 Locale '${n.code}' (${n.name}) added successfully!
986
+ `)),l(W.dim("Updated files:")),l(W.dim(` \u{1F4C4} src/i18n/translations/${n.code}.json`)),l(W.dim(" \u{1F4DD} src/types/i18n.ts (SupportedLocale type)")),l(W.dim(" \u{1F4DD} src/lib/config/app-locales.ts")),l(""),l(W.cyan("Next steps:")),l(W.dim(` 1. Translate: src/i18n/translations/${n.code}.json`)),l(W.dim(` 2. Visit: http://localhost:3000/${n.code}`)),l("")}catch(o){h.fail("Locale generation failed"),v(`${o}`),process.exit(1)}})};import Kn from"node:path";import J from"picocolors";L();import mc from"enquirer";var{prompt:dc}=mc,Yn=async e=>{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"}),r.push({type:"confirm",name:"withLoading",message:"Generate loading.tsx?",initial:!0},{type:"confirm",name:"withError",message:"Generate error.tsx?",initial:!0});let t=await dc(r);return{pageName:e||t.pageName,withLoading:t.withLoading,withError:t.withError}};var qn=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(r,t)=>{try{let o=process.cwd();l(J.cyan(`
987
+ \u{1F4C4} Page Generator
988
+ `)),h.start("Detecting project setup...");let i=await I(o);h.succeed("Project setup detected"),l(J.dim(` i18n: ${i.hasI18n?"\u2713":"\u2717"}
989
+ `));let n=await Yn(r),s=n.pageName,a=b(s),p=i.hasI18n?"src/app/[locale]":"src/app";await ie(o,s,p)&&(v(`Page '${s}' already exists at ${p}/${s}!`),process.exit(1)),h.start("Generating page files..."),await Vt({name:s,projectPath:o,hasI18n:i.hasI18n,dynamic:t.dynamic,withLoading:t.loading??n.withLoading,withError:t.error??n.withError}),h.succeed("Page files generated"),h.start("Registering route...");let g=t.dynamic?`/${s}/[${t.dynamic}]`:`/${s}`;await cr(o,s,g),h.succeed("Route registered"),i.hasI18n&&(h.start("Adding translation namespace..."),await lr(o,a),h.succeed("Translation namespace added"));let y=t.dynamic?Kn.join(p,s,`[${t.dynamic}]`):Kn.join(p,s);l(J.green(`
990
+ \u2728 Page '${s}' created successfully!
991
+ `)),l(J.dim("Generated files:")),l(J.dim(` \u{1F4C2} ${y}/`)),l(J.dim(" \u251C\u2500\u2500 page.tsx")),(t.loading??n.withLoading)&&l(J.dim(" \u251C\u2500\u2500 loading.tsx")),(t.error??n.withError)&&l(J.dim(" \u2514\u2500\u2500 error.tsx")),l(""),i.hasI18n&&(l(J.cyan("Next steps:")),l(J.dim(` 1. Add translations in: src/i18n/translations/en.json \u2192 "${a}"`)),l(J.dim(` 2. Visit: http://localhost:3000/${s}`)),l(""))}catch(o){h.fail("Page generation failed"),v(`${o}`),process.exit(1)}})};import hr from"node:path";import pe from"picocolors";var Wn=e=>{e.command("provider <name>").description("Generate a context provider in src/providers/ and wire it into RootProvider").action(async r=>{try{let t=process.cwd();l(pe.cyan(`
992
+ \u{1F50C} Provider Generator
993
+ `)),h.start("Generating provider...");let{componentName:o,fileBaseName:i,providerFile:n}=await Bt({name:r,projectPath:t});h.succeed("Provider generated"),h.start("Registering provider in RootProvider and barrel...");let{rootProviderFile:s,barrelFile:a}=await pr({projectPath:t,componentName:o,fileBaseName:i});h.succeed("Provider registered"),l(pe.green(`
994
+ \u2728 ${o} created!
995
+ `)),l(pe.dim("Generated files:")),l(pe.dim(` \u{1F4C4} ${hr.relative(t,n)}`)),s?l(pe.dim(` \u270F\uFE0F ${hr.relative(t,s)} \u2014 wrapped {children}`)):(l(pe.yellow(`
996
+ \u26A0\uFE0F Could not locate a RootProvider file. Wire the new provider manually:`)),l(pe.dim(` <${o}>{children}</${o}>`))),a&&l(pe.dim(` \u270F\uFE0F ${hr.relative(t,a)} \u2014 added re-export`)),l("")}catch(t){h.fail("Provider generation failed"),v(`${t instanceof Error?t.message:t}`),process.exit(1)}})};import uc from"enquirer";import M from"picocolors";var{prompt:fc}=uc,gc=e=>{let r=[];for(let t of e.filesRemoved)r.push(` ${M.red("-")} delete: ${t}`);for(let t of e.blocksStripped)r.push(` ${M.red("-")} strip block: ${t.description} ${M.dim(`(${t.file})`)}`);for(let t of e.scriptsRemoved)r.push(` ${M.red("-")} remove script: ${t}`);for(let t of e.packagesUninstalled)r.push(` ${M.red("-")} uninstall: ${t}`);for(let t of e.manualCleanup)r.push(` ${M.yellow("?")} manual cleanup: ${t.description} ${M.dim(`(${t.file})`)}`);return r},hc=e=>e.filesRemoved.length===0&&e.blocksStripped.length===0&&e.scriptsRemoved.length===0&&e.packagesUninstalled.length===0&&e.manualCleanup.length===0,Zn=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(r,t)=>{try{let o=process.cwd(),i=$n(r);if(!i)throw new Error(`Unknown feature "${r}". Valid: ${ye.map(p=>p.id).join(", ")}.`);if(l(M.cyan(`
997
+ \u{1F5D1} Remove ${i.name}
998
+ `)),!(await Ye(i,o)).installed){l(M.dim(`${i.name} is not installed \u2014 nothing to remove.`));return}h.start("Computing changes...");let s=await ht(i,o,{dryRun:!0});if(h.succeed("Computed plan"),hc(s)){l(M.yellow(`
999
+ \u26A0\uFE0F Manifest had no removable artifacts. Nothing to do.
1000
+ `));return}l(M.bold(`
1001
+ Planned changes:
1002
+ `));for(let p of gc(s))l(p);if(l(""),t.dryRun){l(M.dim(`--dry-run set \u2014 exiting without writing.
1003
+ `));return}if(!t.yes){let{confirm:p}=await fc({type:"confirm",name:"confirm",message:`Apply the changes above to remove ${i.name}?`,initial:!1});if(!p){l(M.yellow(`
1004
+ Aborted.
1005
+ `));return}}h.start(`Removing ${i.name}...`);let a=i.remove?(await i.remove(o),s):await ht(i,o);if(h.succeed(`${i.name} removed`),l(M.green(`
1006
+ \u2713 ${i.name} removed.`)),a.manualCleanup.length>0){l(M.yellow(`
1007
+ \u26A0\uFE0F Manual cleanup still required:`));for(let p of a.manualCleanup)l(` - ${p.description} (${p.file})`)}l("")}catch(o){h.fail("Remove failed"),v(`${o instanceof Error?o.message:o}`),process.exit(1)}})};import{existsSync as vc}from"node:fs";import{mkdir as Sc}from"node:fs/promises";import Qe from"node:path";import B from"picocolors";L();import{readFile as yc,writeFile as xc}from"node:fs/promises";import Pc from"node:path";var Qn=async(e,r)=>{let t=A(r),o=Pc.join(e,"src","lib","config","app-apis.ts");try{let i=await yc(o,"utf-8");if(i.includes(`${t}:`))return;if(!i.match(/export const AppApis = \{[\s\S]*?\} as const;/))throw new Error("Could not find AppApis object in app-apis.ts");let n=oo({camelName:t,kebabName:r});i=qe(i,n),await xc(o,i)}catch(i){throw new Error(`Failed to register CRUD API endpoints: ${i}`,{cause:i})}};import ei from"enquirer";var ti=async(e,r,t,o)=>{let i=e||(await ei.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,n;return r!==void 0?n="axios":t!==void 0?n="fetch":o==="axios"?n="axios":o==="fetch"?n="fetch":o==="both"?n=(await ei.prompt({type:"select",name:"httpClient",message:"Choose HTTP client:",choices:["axios","fetch"]})).httpClient:n="axios",{serviceName:i,httpClient:n}};var ri=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(r,t)=>{try{let o=process.cwd();t.axios&&t.fetch&&(v("Cannot use --axios and --fetch together"),process.exit(1)),l(B.cyan(`
1008
+ \u{1F527} Service Generator
1009
+ `)),h.start("Detecting project setup...");let i=await I(o);h.succeed("Project setup detected"),i.httpClient==="none"&&(h.fail("No HTTP client is setup in this project"),v("Please setup either AxiosClient or FetchClient first"),l(B.dim(`
1010
+ Check: lib/utils/http/axios-client or lib/utils/http/fetch-client
1011
+ `)),process.exit(1));let n=[];(i.httpClient==="axios"||i.httpClient==="both")&&n.push("Axios \u2713"),(i.httpClient==="fetch"||i.httpClient==="both")&&n.push("Fetch \u2713"),l(B.dim(` HTTP Clients: ${n.join(", ")}
1012
+ `));let s=await ti(r,t.axios,t.fetch,i.httpClient),{basePath:a,servicePath:p}=wc(o,s.serviceName,t.path);vc(p)||await Sc(p,{recursive:!0}),st(o,a,`${s.serviceName}.service.ts`)&&(v(`Service '${s.serviceName}' already exists at ${a}!`),process.exit(1)),t.crud?(h.start("Generating CRUD service files..."),await Dt({name:s.serviceName,outputPath:p,httpClient:s.httpClient}),h.succeed("CRUD service files generated"),h.start("Registering CRUD API endpoints..."),await Qn(o,s.serviceName),h.succeed("CRUD API endpoints registered")):await xe(dr(),{projectPath:o,spinner:h,serviceName:s.serviceName,servicePath:p,httpClient:s.httpClient}),Cc(s,a,!!t.crud)}catch(o){h.fail("Service generation failed"),v(`${o}`),process.exit(1)}})},wc=(e,r,t)=>{let o;if(t){let i=t.replace(/^src\//,"");if(i.startsWith("features/")){let n=i.split("/")[1];o=Qe.join("src","features",n,"services")}else o=Qe.join("src",i)}else o=Qe.join("src","features",r,"services");return{basePath:o,servicePath:Qe.join(e,o)}},Cc=(e,r,t=!1)=>{let o=Qe.join(r,`${e.serviceName}.service.ts`);l(B.green(`
1013
+ \u2728 ${t?"CRUD ":""}Service '${e.serviceName}' created successfully!
1014
+ `)),l(B.dim("Generated files:")),l(B.dim(` \u{1F4C4} ${o}
1015
+ `)),l(B.cyan("Next steps:"));let i=r.replace(/^src\//,"@/");l(B.dim(` 1. Import service: import { ${e.serviceName}Service } from '${i}/${e.serviceName}.service'`)),t?(l(B.dim(" 2. Available methods: getAll, getById, create, update, delete")),l(B.dim(" 3. Update DTO types in the service file"))):l(B.dim(` 2. Use in component: const data = await ${e.serviceName}Service.getAll()`)),l("")};import Tc from"enquirer";import yr from"picocolors";var{prompt:Ec}=Tc,oi=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 r=>{try{if(l(yr.cyan(`
780
1016
  \u{1F527} Setup Wizard
781
- `)),r.httpClient||r.darkTheme||r.redux||r.i18n||r.tests||r.reactCompiler||r.bundleAnalyzer){r.httpClient&&await $t(process.cwd()),r.darkTheme&&await Nt(process.cwd()),r.redux&&await Dt(process.cwd()),r.i18n&&await Ot(process.cwd()),r.tests&&await Lt(process.cwd()),r.reactCompiler&&await _t(process.cwd()),r.bundleAnalyzer&&await Rt(process.cwd());return}let n=(await Ss([{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"},"Cancel"]}])).feature;if(n==="Cancel"){m(Gt.yellow("Setup cancelled."));return}let s={"dark-theme":Nt,redux:Dt,"http-client":$t,i18n:Ot,tests:Lt,"react-compiler":_t,"bundle-analyzer":Rt}[n];s?await s(process.cwd()):m(Gt.yellow(`
782
- \u26A0\uFE0F ${n} setup is not implemented yet.`))}catch(t){h.fail("Setup failed"),w(`${t}`),process.exit(1)}})};import{existsSync as Cs}from"node:fs";import{mkdir as Es}from"node:fs/promises";import se from"node:path";import F from"picocolors";U();import ws from"enquirer";var{prompt:vs}=ws,Jo=async(e,r,t)=>{let o=[];e||o.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."}),r===void 0&&t===void 0&&o.push({type:"confirm",name:"persistSlice",message:"Enable persistence for this slice?",initial:!1});let n=o.length>0?await vs(o):{};return{sliceName:e||n.sliceName,persistSlice:r===!0?!0:t===!1?!1:n.persistSlice||!1}};var zo=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(r,t)=>{try{let o=process.cwd();t.persist&&t.noPersist===!0&&(w("Cannot use --persist and --no-persist together"),process.exit(1)),m(F.cyan(`
1017
+ `)),r.httpClient||r.darkTheme||r.redux||r.i18n||r.tests||r.reactCompiler||r.bundleAnalyzer||r.securityHeaders||r.validateScripts||r.commitizen){r.httpClient&&await He(process.cwd()),r.darkTheme&&await Me(process.cwd()),r.redux&&await Ve(process.cwd()),r.i18n&&await Ue(process.cwd()),r.tests&&await Be(process.cwd()),r.reactCompiler&&await ze(process.cwd()),r.bundleAnalyzer&&await je(process.cwd()),r.securityHeaders&&await Je(process.cwd()),r.validateScripts&&await Xe(process.cwd()),r.commitizen&&await De(process.cwd());return}let i=(await Ec([{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(i==="Cancel"){l(yr.yellow("Setup cancelled."));return}let s={"dark-theme":Me,redux:Ve,"http-client":He,i18n:Ue,tests:Be,"react-compiler":ze,"bundle-analyzer":je,"security-headers":Je,"validate-scripts":Xe,commitizen:De}[i];s?await s(process.cwd()):l(yr.yellow(`
1018
+ \u26A0\uFE0F ${i} setup is not implemented yet.`))}catch(t){h.fail("Setup failed"),v(`${t}`),process.exit(1)}})};import{existsSync as $c}from"node:fs";import{mkdir as Nc}from"node:fs/promises";import le from"node:path";import G from"picocolors";L();import Rc from"enquirer";var{prompt:bc}=Rc,ni=async(e,r,t)=>{let o=[];e||o.push({type:"input",name:"sliceName",message:"What is the slice name?",initial:"my-slice",validate:n=>/^[a-z0-9-]+$/.test(n)?!0:"Slice name must be lowercase and contain only alphanumeric characters and hyphens."}),r===void 0&&t===void 0&&o.push({type:"confirm",name:"persistSlice",message:"Enable persistence for this slice?",initial:!1});let i=o.length>0?await bc(o):{};return{sliceName:e||i.sliceName,persistSlice:r===!0?!0:t===!1?!1:i.persistSlice||!1}};var ii=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(r,t)=>{try{let o=process.cwd();t.persist&&t.noPersist===!0&&(v("Cannot use --persist and --no-persist together"),process.exit(1)),l(G.cyan(`
783
1019
  \u{1F527} Slice Generator
784
- `)),h.start("Detecting project setup...");let n=await O(o);h.succeed("Project setup detected"),n.hasRedux||(h.fail("Redux is not setup in this project"),w("Please install @reduxjs/toolkit and react-redux first"),m(F.dim(`
1020
+ `)),h.start("Detecting project setup...");let i=await I(o);h.succeed("Project setup detected"),i.hasRedux||(h.fail("Redux is not setup in this project"),v("Please install @reduxjs/toolkit and react-redux first"),l(G.dim(`
785
1021
  Run: npm install @reduxjs/toolkit react-redux
786
- `)),process.exit(1)),m(F.dim(` Redux: \u2713
787
- `));let i=await Jo(r,t.persist,t.noPersist===!0?!1:void 0),{basePath:s,slicePath:c}=Is(o,i.sliceName,t.path),p=se.join(o,s);Cs(p)||await Es(p,{recursive:!0}),await oe(o,i.sliceName,s)&&(w(`Slice '${i.sliceName}' already exists at ${s}!`),process.exit(1)),await me(Ct(),{projectPath:o,spinner:h,sliceName:i.sliceName,basePath:s,slicePath:c,persistSlice:i.persistSlice});let g=null;if(Rs(t,n.hasTests)){let x=se.join(c,`${i.sliceName}.slice.ts`);h.start("Generating test..."),g=await q({projectPath:o,sourceFile:x,kind:"slice",symbolName:$(i.sliceName)}),h.succeed("Test generated")}Ns(i,s,g,o)}catch(o){h.fail("Slice generation failed"),w(`${o}`),process.exit(1)}})},Is=(e,r,t)=>{let o;if(t){let n=t.replace(/^src\//,"");if(n.startsWith("features/")){let i=n.split("/")[1];o=se.join("src","features",i,"store")}else o=se.join("src",n)}else o=se.join("src","features",r,"store");return{basePath:o,slicePath:se.join(e,o,r)}},Rs=(e,r)=>e.noTest?!1:e.test?!0:r,Ns=(e,r,t,o)=>{let n=se.join(r,e.sliceName);m(F.green(`
1022
+ `)),process.exit(1)),l(G.dim(` Redux: \u2713
1023
+ `));let n=await ni(r,t.persist,t.noPersist===!0?!1:void 0),{basePath:s,slicePath:a}=Ic(o,n.sliceName,t.path),p=le.join(o,s);$c(p)||await Nc(p,{recursive:!0}),await ie(o,n.sliceName,s)&&(v(`Slice '${n.sliceName}' already exists at ${s}!`),process.exit(1)),await xe(ur(),{projectPath:o,spinner:h,sliceName:n.sliceName,basePath:s,slicePath:a,persistSlice:n.persistSlice});let g=null;if(Ac(t,i.hasTests)){let x=le.join(a,`${n.sliceName}.slice.ts`);h.start("Generating test..."),g=await Q({projectPath:o,sourceFile:x,kind:"slice",symbolName:A(n.sliceName)}),h.succeed("Test generated")}kc(n,s,g,o)}catch(o){h.fail("Slice generation failed"),v(`${o}`),process.exit(1)}})},Ic=(e,r,t)=>{let o;if(t){let i=t.replace(/^src\//,"");if(i.startsWith("features/")){let n=i.split("/")[1];o=le.join("src","features",n,"store")}else o=le.join("src",i)}else o=le.join("src","features",r,"store");return{basePath:o,slicePath:le.join(e,o,r)}},Ac=(e,r)=>e.noTest?!1:e.test?!0:r,kc=(e,r,t,o)=>{let i=le.join(r,e.sliceName);l(G.green(`
788
1024
  \u2728 Slice '${e.sliceName}' created successfully!
789
- `)),m(F.dim("Generated files:")),m(F.dim(` \u{1F4C2} ${n}/`)),m(F.dim(` \u251C\u2500\u2500 ${e.sliceName}.slice.ts`)),m(F.dim(` \u251C\u2500\u2500 ${e.sliceName}.selectors.ts`)),e.persistSlice&&m(F.dim(" \u251C\u2500\u2500 persist.ts")),m(F.dim(` \u251C\u2500\u2500 ${e.sliceName}.types.ts`)),m(F.dim(` \u2514\u2500\u2500 index.ts
790
- `)),t&&m(F.dim(` \u{1F9EA} ${se.relative(o,t)}
791
- `)),m(F.cyan("Next steps:"));let i=r.replace(/^src\//,"@/");m(F.dim(` 1. Import actions: import { setLoading, setError } from '${i}/${e.sliceName}'`)),m(F.dim(" 2. Use in component: dispatch(setLoading(true))")),m("")};import B from"node:path";import Ht from"picocolors";T();U();var Bo=e=>{e.command("test <file>").description(`Generate a sibling test file for an existing component, hook, or slice.
792
- 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(r,t)=>{try{let o=process.cwd(),n=B.isAbsolute(r)?r:B.join(o,r);m(Ht.cyan(`
1025
+ `)),l(G.dim("Generated files:")),l(G.dim(` \u{1F4C2} ${i}/`)),l(G.dim(` \u251C\u2500\u2500 ${e.sliceName}.slice.ts`)),l(G.dim(` \u251C\u2500\u2500 ${e.sliceName}.selectors.ts`)),e.persistSlice&&l(G.dim(" \u251C\u2500\u2500 persist.ts")),l(G.dim(` \u251C\u2500\u2500 ${e.sliceName}.types.ts`)),l(G.dim(` \u2514\u2500\u2500 index.ts
1026
+ `)),t&&l(G.dim(` \u{1F9EA} ${le.relative(o,t)}
1027
+ `)),l(G.cyan("Next steps:"));let n=r.replace(/^src\//,"@/");l(G.dim(` 1. Import actions: import { setLoading, setError } from '${n}/${e.sliceName}'`)),l(G.dim(" 2. Use in component: dispatch(setLoading(true))")),l("")};import X from"node:path";import xr from"picocolors";P();L();var si=e=>{e.command("test <file>").description(`Generate a sibling test file for an existing component, hook, or slice.
1028
+ 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(r,t)=>{try{let o=process.cwd(),i=X.isAbsolute(r)?r:X.join(o,r);l(xr.cyan(`
793
1029
  \u{1F9EA} Test Generator
794
- `)),l(n)||(w(`Source file not found: ${r}`),process.exit(1));let i=await O(o);i.hasTests||(w("Testing is not installed in this project. Run `next-maker setup --tests` first."),process.exit(1));let s=await d(n),c=bs(t.kind)??$s(n,s);c||(w(`Could not infer test kind for ${B.basename(n)}. Pass --kind component|hook|slice.`),process.exit(1));let p=As(n,c),f=Os(n,c);l(f)&&!t.force&&(w(`Test file already exists: ${B.relative(o,f)}. Use --force to overwrite.`),process.exit(1)),h.start(`Generating ${c} test...`);let g=await q({projectPath:o,sourceFile:n,kind:c,symbolName:p,hasRedux:i.hasRedux,hasI18n:i.hasI18n,hookUsesStore:c==="hook"&&i.hasRedux&&s.includes("useAppSelector")});h.succeed("Test generated"),m(Ht.green(`
795
- \u2728 Test '${B.basename(g)}' created.
796
- `)),m(Ht.dim(` \u{1F9EA} ${B.relative(o,g)}`)),m("")}catch(o){h.fail("Test generation failed"),w(`${o}`),process.exit(1)}})},bs=e=>{if(!e)return null;if(e==="component"||e==="hook"||e==="slice")return e;throw new Error(`Invalid --kind: ${e}. Use component | hook | slice.`)},$s=(e,r)=>{let t=B.basename(e);return/\.slice\.ts$/.test(t)?"slice":/^use[A-Z]/.test(t.replace(/\.tsx?$/,""))?"hook":t.endsWith(".tsx")?"component":/createSlice\s*\(/.test(r)?"slice":/^export\s+(const|function)\s+use[A-Z]/m.test(r)?"hook":null},As=(e,r)=>{let t=B.basename(e).replace(/\.(tsx?|jsx?)$/i,"");return r==="slice"?$(t.replace(/\.slice$/,"")):r==="hook"?/^use[A-Z]/.test(t)?t:`use${R(t.replace(/^use-?/,""))}`:R(t)},Os=(e,r)=>{let t=B.dirname(e),o=B.basename(e).replace(/\.(tsx?|jsx?)$/i,""),n=r==="component"?".tsx":".ts";return B.join(t,`${o}.test${n}`)};var Xo=e=>{yr(e),Mo(e),Vr(e),zo(e),no(e),to(e),Xr(e),Zr(e),Wr(e),Bo(e)};var ks=process.emitWarning;process.emitWarning=function(e,r,t,o){if(!(typeof e=="string"&&e.includes("--localstorage-file")&&e.includes("was provided without a valid path")))return ks.apply(process,arguments)};async function js(){Mt({logger:r=>_e(r)});let e=new _s;e.name("next-maker").description("Teispace Next.js Project Generator").version("1.0.0"),Xo(e),e.parse()}js().catch(e=>{let r=e&&typeof e=="object"&&"message"in e?e.message:String(e);_e(`Unexpected error: ${r}`)});
1030
+ `)),m(i)||(v(`Source file not found: ${r}`),process.exit(1));let n=await I(o);n.hasTests||(v("Testing is not installed in this project. Run `next-maker setup --tests` first."),process.exit(1));let s=await d(i),a=Oc(t.kind)??_c(i,s);a||(v(`Could not infer test kind for ${X.basename(i)}. Pass --kind component|hook|slice.`),process.exit(1));let p=Fc(i,a),u=jc(i,a);m(u)&&!t.force&&(v(`Test file already exists: ${X.relative(o,u)}. Use --force to overwrite.`),process.exit(1)),h.start(`Generating ${a} test...`);let g=await Q({projectPath:o,sourceFile:i,kind:a,symbolName:p,hasRedux:n.hasRedux,hasI18n:n.hasI18n,hookUsesStore:a==="hook"&&n.hasRedux&&s.includes("useAppSelector")});h.succeed("Test generated"),l(xr.green(`
1031
+ \u2728 Test '${X.basename(g)}' created.
1032
+ `)),l(xr.dim(` \u{1F9EA} ${X.relative(o,g)}`)),l("")}catch(o){h.fail("Test generation failed"),v(`${o}`),process.exit(1)}})},Oc=e=>{if(!e)return null;if(e==="component"||e==="hook"||e==="slice")return e;throw new Error(`Invalid --kind: ${e}. Use component | hook | slice.`)},_c=(e,r)=>{let t=X.basename(e);return/\.slice\.ts$/.test(t)?"slice":/^use[A-Z]/.test(t.replace(/\.tsx?$/,""))?"hook":t.endsWith(".tsx")?"component":/createSlice\s*\(/.test(r)?"slice":/^export\s+(const|function)\s+use[A-Z]/m.test(r)?"hook":null},Fc=(e,r)=>{let t=X.basename(e).replace(/\.(tsx?|jsx?)$/i,"");return r==="slice"?A(t.replace(/\.slice$/,"")):r==="hook"?/^use[A-Z]/.test(t)?t:`use${b(t.replace(/^use-?/,""))}`:b(t)},jc=(e,r)=>{let t=X.dirname(e),o=X.basename(e).replace(/\.(tsx?|jsx?)$/i,""),i=r==="component"?".tsx":".ts";return X.join(t,`${o}.test${i}`)};var ai=e=>{qr(e),oi(e),Un(e),ii(e),ri(e),qn(e),Jn(e),$o(e),Xn(e),Vn(e),Wn(e),Dn(e),Nn(e),Zn(e),si(e)};var Lc=process.emitWarning;process.emitWarning=function(e,r,t,o){if(!(typeof e=="string"&&e.includes("--localstorage-file")&&e.includes("was provided without a valid path")))return Lc.apply(process,arguments)};async function Mc(){vr({logger:r=>rt(r)});let e=new Dc;e.name("next-maker").description("Teispace Next.js Project Generator").version("1.0.0"),ai(e),e.parse()}Mc().catch(e=>{let r=e&&typeof e=="object"&&"message"in e?e.message:String(e);rt(`Unexpected error: ${r}`)});
797
1033
  //# sourceMappingURL=index.js.map