@teispace/next-maker 1.5.1 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,6 +1,16 @@
1
1
  #!/usr/bin/env node
2
- var Kt=Object.defineProperty;var qt=(e,i)=>()=>(e&&(i=e(e=0)),i);var Zt=(e,i)=>{for(var t in i)Kt(e,t,{get:i[t],enumerable:!0})};var Me={};Zt(Me,{PROJECT_PATHS:()=>a});var a,I=qt(()=>{"use strict";a={NEXT_CONFIG:"next.config.ts",TAILWIND_CONFIG:"tailwind.config.ts",POSTCSS_CONFIG:"postcss.config.mjs",ESLINT_CONFIG:"eslint.config.mjs",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",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"}});import{Command as No}from"commander";import ve from"node:path";import Y from"picocolors";import Qt from"ora";function O(e="",i){let t=Qt({text:e,...i});return t.start(),t}import ei from"enquirer";var{prompt:ti}=ei,be=async e=>{let i=await ti([{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):",validate:t=>{if(!t)return!0;let r=/^https:\/\/github\.com\/[\w-]+\/[\w.-]+$/,s=/^git@github\.com:[\w-]+\/[\w.-]+\.git$/;return!r.test(t)&&!s.test(t)?"Please enter a valid GitHub repository URL (e.g., https://github.com/user/repo)":!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 + 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:"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(i.company=i.author,i.gitRemote&&!i.gitHomepage){let t=i.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"");i.gitHomepage=`${t}#readme`,i.gitIssues=`${t}/issues`}return i};import V from"node:fs/promises";import _e from"node:path";import{existsSync as ye}from"node:fs";var d=async e=>V.readFile(e,"utf-8"),u=async(e,i)=>{await V.mkdir(_e.dirname(e),{recursive:!0}),await V.writeFile(e,i,"utf-8")},$=async(e,i)=>{await V.mkdir(_e.dirname(i),{recursive:!0}),await V.copyFile(e,i)},v=async e=>{ye(e)&&await V.unlink(e)},h=async e=>{ye(e)&&await V.rm(e,{recursive:!0,force:!0})},te=async(e,i)=>{let t=await d(e),r=JSON.parse(t),s=i(r);await u(e,JSON.stringify(s,null,2))},l=e=>ye(e);import{exec as ii}from"node:child_process";import{promisify as oi}from"node:util";var le=oi(ii),je=async(e,i)=>{try{await le("git init",{cwd:e}),await le("git add .",{cwd:e}),await le('git commit -m "Initial commit from @teispace/next-maker"',{cwd:e}),i&&await le(`git remote add origin ${i}`,{cwd:e})}catch(t){console.warn("Failed to initialize git repository",t)}};import{exec as ri}from"node:child_process";import{promisify as ni}from"node:util";var Pe=ni(ri),Fe=async(e,i)=>{let t=`${i} install`;try{await Pe(t,{cwd:e})}catch(r){throw new Error(`Failed to install dependencies with ${i}: ${r}`)}},L=async(e,i,t)=>{let r=i==="npm"?`${i} run ${t}`:`${i} ${t}`;try{await Pe(r,{cwd:e})}catch(s){console.warn(`Warning: Failed to run script '${t}': ${s}`)}},si=()=>{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"},G=async e=>{let{existsSync:i}=await import("node:fs"),t=await import("node:path");return i(t.join(e,"pnpm-lock.yaml"))?"pnpm":i(t.join(e,"yarn.lock"))?"yarn":i(t.join(e,"bun.lockb"))?"bun":i(t.join(e,"package-lock.json"))?"npm":si()},ai=async(e,i,t)=>{if(t.length===0)return;let s=`${ci(i)} ${t.join(" ")}`;try{await Pe(s,{cwd:e})}catch(o){throw new Error(`Failed to install packages with ${i}: ${o}`)}},ci=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"}},D=async(e,i)=>{let t=await G(e);await ai(e,t,[i])};import M from"picocolors";var li={reset:e=>e,red:M.red,green:M.green,yellow:M.yellow,blue:M.blue,cyan:M.cyan,magenta:M.magenta,white:M.white,gray:M.gray,bright:M.bold,dim:M.dim};function B(e,i="reset"){let t=li[i]??(r=>r);console.log(t(e))}function pe(e){B(`\u2716 ${e}`,"red")}var E=pe;function m(e){B(e)}function ke(){console.log(""),B("\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"),B("\u2551 \u2551","cyan"),B("\u2551 \u{1F680} Create Teispace Next.js App \u{1F680} \u2551","cyan"),B("\u2551 \u2551","cyan"),B("\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("")}function De(e){let{logger:i=n=>console.error(n),exitOnCancel:t=process.env.NODE_ENV!=="test"}=e??{},r=()=>{console.log(""),console.log(""),i("Setup cancelled by user"),console.log(""),t&&process.exit(0)},s=n=>{if(n!==null&&typeof n=="object"&&"code"in n&&n.code==="ERR_USE_AFTER_CLOSE"){r();return}if(n instanceof Error){i(`Uncaught exception: ${n.message}`);return}i(`Uncaught exception: ${String(n)}`)},o=n=>{if(n instanceof Error){i(`Unhandled promise rejection: ${n.message}`);return}i(`Unhandled promise rejection: ${String(n)}`)};return process.on("SIGINT",r),process.on("SIGTERM",r),process.on("uncaughtException",s),process.on("unhandledRejection",o),()=>{process.off("SIGINT",r),process.off("SIGTERM",r),process.off("uncaughtException",s),process.off("unhandledRejection",o)}}var pi=e=>e.charAt(0).toUpperCase()+e.slice(1),j=e=>e.replace(/-([a-z])/g,(i,t)=>t.toUpperCase()),J=e=>pi(j(e));import mi from"ora";var y=mi();import di from"degit";var Le=async e=>{let i=O("Downloading template...");try{await di("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!0}).clone(e),i.succeed("Template downloaded successfully.")}catch(t){throw i.fail("Failed to download template."),t}};import ui from"node:path";I();var A={REDUX_TOOLKIT:"@reduxjs/toolkit",REACT_REDUX:"react-redux",REDUX_PERSIST:"redux-persist",REACT_SECURE_STORAGE:"react-secure-storage",NEXT_INTL:"next-intl",NEXT_THEMES:"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"};var Ge=async(e,i)=>{let t=O("Configuring package.json...");try{let r=i.gitRemote,s=i.gitHomepage,o=i.gitIssues;i.gitRemote&&(i.gitRemote.startsWith("git@github.com:")&&(r=i.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"")),s||(s=`${r.replace(/\.git$/,"")}#readme`),o||(o=`${r.replace(/\.git$/,"")}/issues`),r.endsWith(".git")||(r=`${r}.git`)),await te(ui.join(e,a.PACKAGE_JSON),n=>(n.name=i.projectName,n.version=i.version,n.description=i.description,n.author=i.author,delete n.packageManager,i.gitRemote?(s&&(n.homepage=s),o&&(n.bugs={url:o}),r&&(n.repository={type:"git",url:r})):(delete n.homepage,delete n.bugs,delete n.repository),i.redux||(delete n.dependencies[A.REDUX_TOOLKIT],delete n.dependencies[A.REACT_REDUX],delete n.dependencies[A.REDUX_PERSIST]),i.httpClient!=="none"||i.reactSecureStorage||delete n.dependencies[A.REACT_SECURE_STORAGE],i.i18n||delete n.dependencies[A.NEXT_INTL],i.darkMode||delete n.dependencies[A.NEXT_THEMES],i.httpClient==="none"?delete n.dependencies[A.AXIOS]:i.httpClient==="fetch"&&delete n.dependencies[A.AXIOS],n)),t.succeed("package.json configured.")}catch(r){throw t.fail("Failed to configure package.json."),r}};import f from"node:path";I();var He=async(e,i)=>{let t=O("Customizing features...");try{await fi(e,i),await gi(e,i),await xi(e,i),await hi(e,i),await yi(e,i),await Pi(e),await Si(e),await vi(e),t.succeed("Features customized.")}catch(r){throw t.fail("Failed to customize features."),r}},fi=async(e,i)=>{let t=f.join(e,a.HTTP_UTILS),r=i.httpClient!=="none"||i.reactSecureStorage;if(i.httpClient==="none"){if(await h(f.join(e,a.AXIOS_CLIENT)),await h(f.join(e,a.FETCH_CLIENT)),r)await u(f.join(t,"index.ts"),`export * from './token-store';
3
- `),await v(f.join(e,a.CLIENT_UTILS));else{await h(t);let o=f.join(e,a.UTILS_INDEX);if(l(o)){let c=await d(o);c=c.replace(/export \* from '\.\/http';\n/,""),await u(o,c)}await v(f.join(e,a.APP_APIS));let n=f.join(e,a.CONFIG_INDEX);if(l(n)){let c=await d(n);c=c.replace(/export \* from '\.\/app-apis';\n/,""),await u(n,c)}}let s=f.join(e,a.CONSTANTS);if(l(s)){let o=await d(s);o=o.replace(/export const API_RESPONSE_DATA_KEY = 'data';\n/,""),o=o.replace(/export const SAVE_AUTH_TOKENS = false;\n/,""),await u(s,o)}if(await h(f.join(e,a.ERRORS_DIR)),!r){await h(f.join(e,a.COMMON_TYPES_DIR)),await h(f.join(e,a.UTILITY_TYPES_DIR));let o=f.join(e,a.TYPES_INDEX);if(l(o)){let n=await d(o);n=n.replace(/export \* from '\.\/utility';\n/,""),n=n.replace(/export \* from '\.\/common';\n/,""),await u(o,n)}}}else if(i.httpClient==="axios"){await h(f.join(e,a.FETCH_CLIENT));let s=await d(f.join(t,"index.ts"));s=s.replace(/export .* from '\.\/fetch-client';\n/g,""),await u(f.join(t,"index.ts"),s);let o=f.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)}}else if(i.httpClient==="fetch"){await h(f.join(e,a.AXIOS_CLIENT));let s=await d(f.join(t,"index.ts"));s=s.replace(/export .* from '\.\/axios-client';\n/g,""),await u(f.join(t,"index.ts"),s);let o=f.join(e,a.HTTP_TYPES);if(l(o)){let n=await d(o);n=n.replace(/declare module 'axios' \{[\s\S]*?\}\n\n/,""),n=n.replace(/export interface AxiosClientOptions \{[\s\S]*?\}\n\n/,""),await u(o,n)}}},gi=async(e,i)=>{i.httpClient!=="none"||i.reactSecureStorage||await h(f.join(e,a.STORAGE_SERVICE))},xi=async(e,i)=>{if(!i.redux){await h(f.join(e,a.STORE)),await h(f.join(e,a.COUNTER_FEATURE)),await v(f.join(e,a.STORE_PROVIDER));let t=f.join(e,a.PROVIDERS_INDEX),r=await d(t);r=r.replace(/export \* from '\.\/StoreProvider';\n/,""),await u(t,r);let s=[f.join(e,a.ROOT_PAGE),f.join(e,a.LOCALE_PAGE)];for(let o of s)if(l(o)){let n=await d(o);n=n.replace(/import\s+\{\s*Counter\s*\}\s+from\s+['"]@\/features\/counter['"];\n?/,""),n=n.replace(/<Counter\s*\/>\n?/g,""),await u(o,n)}}},hi=async(e,i)=>{if(!i.darkMode){await v(f.join(e,a.THEME_PROVIDER));let t=f.join(e,a.PROVIDERS_INDEX),r=await d(t);r=r.replace(/export \* from '\.\/CustomThemeProvider';\n/,""),await u(t,r);let s=f.join(e,a.GLOBALS_CSS);if(l(s)){let o=await d(s);o=o.replace(/@custom-variant dark \(.*?\);\n\n/,""),o=o.replace(/@theme \{[\s\S]*?\}\n/,""),await u(s,o)}if(!i.i18n){let o=f.join(e,a.ROOT_LAYOUT);if(l(o)){let n=await d(o);n=n.replace(/bg-light dark:bg-dark /g,""),await u(o,n)}}}},yi=async(e,i)=>{if(!i.i18n){await h(f.join(e,a.I18N_DIR)),await h(f.join(e,a.LOCALE_DIR)),await v(f.join(e,a.PROXY)),await v(f.join(e,a.MIDDLEWARE)),await v(f.join(e,a.I18N_TYPES)),await v(f.join(e,a.APP_LOCALES));let t=f.join(e,a.TYPES_INDEX);if(l(t)){let n=await d(t);n=n.replace(/export \* from '\.\/i18n';\n/,""),await u(t,n)}let r=f.join(e,a.CONFIG_INDEX);if(l(r)){let n=await d(r);n=n.replace(/export \* from '\.\/app-locales';\n/,""),await u(r,n)}let s=f.join(e,a.NEXT_CONFIG);if(l(s)){let n=await d(s);n=n.replace(/import createNextIntlPlugin from 'next-intl\/plugin';\n/,""),n=n.replace(/const withNextIntl = createNextIntlPlugin\(\);\n/,""),n=n.replace(/export default withNextIntl\(nextConfig\);/,"export default nextConfig;"),await u(s,n)}let o=f.join(e,a.COUNTER_COMPONENT);if(l(o)){let n=await d(o);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,"{value}"),n=n.replace(/\{t\(['"]increment['"]\)\}/g,"Increment"),n=n.replace(/\{t\(['"]decrement['"]\)\}/g,"Decrement"),n=n.replace(/\{t\(['"]reset['"]\)\}/g,"Reset"),await u(o,n)}}},Pi=async e=>{await v(f.join(e,a.LICENSE))},Si=async e=>{await v(f.join(e,a.CHANGELOG))},vi=async e=>{await v(f.join(e,a.NVM_RC)),await v(f.join(e,a.NPM_RC))};import Se from"node:path";I();var Ue=async(e,i)=>{let t=[],r=[];i.redux&&(t.push("import { StoreProvider } from '@/providers';"),r.push("StoreProvider")),i.darkMode&&(t.push("import { CustomThemeProvider } from '@/providers';"),r.push("CustomThemeProvider")),i.i18n&&(t.push("import { NextIntlClientProvider, AbstractIntlMessages } from 'next-intl';"),t.push("import { SupportedLocale } from '@/types/i18n';"));let s=`'use client';
2
+ var ii=Object.defineProperty;var oi=(e,i)=>()=>(e&&(i=e(e=0)),i);var ri=(e,i)=>{for(var t in i)ii(e,t,{get:i[t],enumerable:!0})};var Ge={};ri(Ge,{PROJECT_PATHS:()=>a});var a,I=oi(()=>{"use strict";a={NEXT_CONFIG:"next.config.ts",TAILWIND_CONFIG:"tailwind.config.ts",POSTCSS_CONFIG:"postcss.config.mjs",ESLINT_CONFIG:"eslint.config.mjs",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",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"}});import{Command as jo}from"commander";import Te from"node:path";import W from"picocolors";import ni from"ora";function O(e="",i){let t=ni({text:e,...i});return t.start(),t}import si from"enquirer";var{prompt:ai}=si,je=async e=>{let i=await ai([{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):",validate:t=>{if(!t)return!0;let r=/^https:\/\/github\.com\/[\w-]+\/[\w.-]+$/,s=/^git@github\.com:[\w-]+\/[\w.-]+\.git$/;return!r.test(t)&&!s.test(t)?"Please enter a valid GitHub repository URL (e.g., https://github.com/user/repo)":!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 + 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:"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(i.company=i.author,i.gitRemote&&!i.gitHomepage){let t=i.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"");i.gitHomepage=`${t}#readme`,i.gitIssues=`${t}/issues`}return i};import K from"node:fs/promises";import Fe from"node:path";import{existsSync as ve}from"node:fs";var m=async e=>K.readFile(e,"utf-8"),u=async(e,i)=>{await K.mkdir(Fe.dirname(e),{recursive:!0}),await K.writeFile(e,i,"utf-8")},$=async(e,i)=>{await K.mkdir(Fe.dirname(i),{recursive:!0}),await K.copyFile(e,i)},w=async e=>{ve(e)&&await K.unlink(e)},x=async e=>{ve(e)&&await K.rm(e,{recursive:!0,force:!0})},ie=async(e,i)=>{let t=await m(e),r=JSON.parse(t),s=i(r);await u(e,JSON.stringify(s,null,2))},l=e=>ve(e);import{exec as ci}from"node:child_process";import{promisify as li}from"node:util";var pe=li(ci),ke=async(e,i)=>{try{await pe("git init",{cwd:e}),await pe("git add .",{cwd:e}),await pe('git commit -m "Initial commit from @teispace/next-maker"',{cwd:e}),i&&await pe(`git remote add origin ${i}`,{cwd:e})}catch(t){console.warn("Failed to initialize git repository",t)}};import{exec as pi}from"node:child_process";import{promisify as mi}from"node:util";var me=mi(pi),De=async(e,i)=>{let t=`${i} install`;try{await me(t,{cwd:e})}catch(r){throw new Error(`Failed to install dependencies with ${i}: ${r}`)}},L=async(e,i,t)=>{let r=i==="npm"?`${i} run ${t}`:`${i} ${t}`;try{await me(r,{cwd:e})}catch(s){console.warn(`Warning: Failed to run script '${t}': ${s}`)}},di=()=>{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"},H=async e=>{let{existsSync:i}=await import("node:fs"),t=await import("node:path");return i(t.join(e,"pnpm-lock.yaml"))?"pnpm":i(t.join(e,"yarn.lock"))?"yarn":i(t.join(e,"bun.lockb"))?"bun":i(t.join(e,"package-lock.json"))?"npm":di()},ui=async(e,i,t)=>{if(t.length===0)return;let s=`${fi(i)} ${t.join(" ")}`;try{await me(s,{cwd:e})}catch(o){throw new Error(`Failed to install packages with ${i}: ${o}`)}},fi=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"}},D=async(e,i)=>{let t=await H(e);await ui(e,t,[i])},gi=async(e,i,t)=>{if(t.length===0)return;let s=`${xi(i)} ${t.join(" ")}`;try{await me(s,{cwd:e})}catch(o){throw new Error(`Failed to uninstall packages with ${i}: ${o}`)}},xi=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"}},Ce=async(e,i)=>{let t=await H(e);await gi(e,t,[i])};import G from"picocolors";var hi={reset:e=>e,red:G.red,green:G.green,yellow:G.yellow,blue:G.blue,cyan:G.cyan,magenta:G.magenta,white:G.white,gray:G.gray,bright:G.bold,dim:G.dim};function q(e,i="reset"){let t=hi[i]??(r=>r);console.log(t(e))}function de(e){q(`\u2716 ${e}`,"red")}var E=de;function d(e){q(e)}function Le(){console.log(""),q("\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"),q("\u2551 \u2551","cyan"),q("\u2551 \u{1F680} Create Teispace Next.js App \u{1F680} \u2551","cyan"),q("\u2551 \u2551","cyan"),q("\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("")}function Me(e){let{logger:i=n=>console.error(n),exitOnCancel:t=process.env.NODE_ENV!=="test"}=e??{},r=()=>{console.log(""),console.log(""),i("Setup cancelled by user"),console.log(""),t&&process.exit(0)},s=n=>{if(n!==null&&typeof n=="object"&&"code"in n&&n.code==="ERR_USE_AFTER_CLOSE"){r();return}if(n instanceof Error){i(`Uncaught exception: ${n.message}`);return}i(`Uncaught exception: ${String(n)}`)},o=n=>{if(n instanceof Error){i(`Unhandled promise rejection: ${n.message}`);return}i(`Unhandled promise rejection: ${String(n)}`)};return process.on("SIGINT",r),process.on("SIGTERM",r),process.on("uncaughtException",s),process.on("unhandledRejection",o),()=>{process.off("SIGINT",r),process.off("SIGTERM",r),process.off("uncaughtException",s),process.off("unhandledRejection",o)}}var yi=e=>e.charAt(0).toUpperCase()+e.slice(1),j=e=>e.replace(/-([a-z])/g,(i,t)=>t.toUpperCase()),z=e=>yi(j(e));import Si from"ora";var P=Si();import Pi from"degit";var He=async e=>{let i=O("Downloading template...");try{await Pi("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!0}).clone(e),i.succeed("Template downloaded successfully.")}catch(t){throw i.fail("Failed to download template."),t}};import vi from"node:path";I();var A={REDUX_TOOLKIT:"@reduxjs/toolkit",REACT_REDUX:"react-redux",REDUX_PERSIST:"redux-persist",REACT_SECURE_STORAGE:"react-secure-storage",NEXT_INTL:"next-intl",NEXT_THEMES:"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"};var Ue=async(e,i)=>{let t=O("Configuring package.json...");try{let r=i.gitRemote,s=i.gitHomepage,o=i.gitIssues;i.gitRemote&&(i.gitRemote.startsWith("git@github.com:")&&(r=i.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"")),s||(s=`${r.replace(/\.git$/,"")}#readme`),o||(o=`${r.replace(/\.git$/,"")}/issues`),r.endsWith(".git")||(r=`${r}.git`)),await ie(vi.join(e,a.PACKAGE_JSON),n=>(n.name=i.projectName,n.version=i.version,n.description=i.description,n.author=i.author,delete n.packageManager,i.gitRemote?(s&&(n.homepage=s),o&&(n.bugs={url:o}),r&&(n.repository={type:"git",url:r})):(delete n.homepage,delete n.bugs,delete n.repository),i.redux||(delete n.dependencies[A.REDUX_TOOLKIT],delete n.dependencies[A.REACT_REDUX],delete n.dependencies[A.REDUX_PERSIST]),i.httpClient!=="none"||i.reactSecureStorage||delete n.dependencies[A.REACT_SECURE_STORAGE],i.i18n||delete n.dependencies[A.NEXT_INTL],i.darkMode||delete n.dependencies[A.NEXT_THEMES],i.httpClient==="none"?delete n.dependencies[A.AXIOS]:i.httpClient==="fetch"&&delete n.dependencies[A.AXIOS],n)),t.succeed("package.json configured.")}catch(r){throw t.fail("Failed to configure package.json."),r}};import f from"node:path";I();import M from"node:path";I();import{exec as Ci}from"node:child_process";import{promisify as wi}from"node:util";var Ti=wi(Ci),Xe=async(e,i)=>{let t=M.join(e,a.HTTP_UTILS,"index.ts");if(l(t)){let r=await m(t);r=r.replace(/export .* from '\.\/axios-client';?\n?/g,""),r=r.replace(/export .* from '\.\/fetch-client';?\n?/g,""),i.includes("fetch")&&!r.includes("fetch-client")&&(r+=`export * from './fetch-client';
3
+ `),i.includes("axios")&&!r.includes("axios-client")&&(r+=`export * from './axios-client';
4
+ `),await u(t,r)}},Ye=async e=>{let i=M.join(e,a.UTILS_INDEX);if(l(i)){let t=await m(i);t.includes("./http")||(t+=`export * from './http';
5
+ `,await u(i,t))}},Je=async e=>{let i=M.join(e,a.TYPES_INDEX);if(l(i)){let t=await m(i);t.includes("./common")||(t+=`export * from './common';
6
+ `),t.includes("./utility")||(t+=`export * from './utility';
7
+ `),await u(i,t)}},ze=async e=>{let i=M.join(e,a.CONFIG_INDEX);if(l(i)){let t=await m(i);t.includes("./app-apis")||(t+=`export * from './app-apis';
8
+ `,await u(i,t))}},oe=async(e,i)=>{let t=M.join(e,a.HTTP_TYPES);if(l(t)){let r=await m(t);i.includes("axios")||(r=r.replace(/declare module 'axios'\s*\{\s*export interface AxiosRequestConfig\s*\{[\s\S]*?\}\s*\}/g,""),r=r.replace(/\n\s*\n/g,`
9
+
10
+ `).trim()+`
11
+ `,await u(t,r))}},We=async(e,i,t)=>{if(i===t)return;let r=i==="fetch"?"fetchClient":"axiosClient",s=t==="fetch"?"fetchClient":"axiosClient",o=i==="fetch"?"fetch-client":"axios-client",n=t==="fetch"?"fetch-client":"axios-client",c=M.join(e,"src");try{let p=`grep -rl "${r}" "${c}" --include="*.ts" --include="*.tsx" || true`,{stdout:g}=await Ti(p);if(!g.trim())return;let v=g.trim().split(`
12
+ `).filter(C=>C);for(let C of v){if(!l(C))continue;let h=await m(C),S=!1,F=new RegExp(`(import\\s*\\{[^}]*?)\\b${r}\\b([^}]*?\\}\\s*from\\s*['"][^'"]*?/http['"])`,"g");F.test(h)&&(h=h.replace(F,`$1${s}$2`),S=!0);let R=new RegExp(`import\\s+${r}\\s+from\\s+['"]([^'"]*?)/${o}['"]`,"g");R.test(h)&&(h=h.replace(R,`import ${s} from '$1/${n}'`),S=!0);let k=new RegExp(`\\b${r}\\b(?=\\.)`,"g");k.test(h)&&(h=h.replace(k,s),S=!0);let ee=new RegExp(`\\b${r}\\b(?![.\\w])`,"g");ee.test(h)&&(h=h.replace(ee,s),S=!0),S&&await u(C,h)}}catch(p){console.warn("Warning: Could not scan for HTTP client usages:",p)}},Ve=async e=>{let i=M.join(e,a.UTILS_INDEX);if(l(i)){let s=await m(i);s=s.replace(/export \* from '\.\/http';\n?/g,""),await u(i,s)}let t=M.join(e,a.TYPES_INDEX);if(l(t)){let s=await m(t);l(M.join(e,a.COMMON_TYPES_DIR))||(s=s.replace(/export \* from '\.\/common';\n?/g,"")),l(M.join(e,a.UTILITY_TYPES_DIR))||(s=s.replace(/export \* from '\.\/utility';\n?/g,"")),await u(t,s)}let r=M.join(e,a.CONFIG_INDEX);if(l(r)){let s=await m(r);s=s.replace(/export \* from '\.\/app-apis';\n?/g,""),await u(r,s)}};var Be=async(e,i)=>{let t=O("Customizing features...");try{await Ei(e,i),await Ii(e,i),await Ri(e,i),await Ni(e,i),await Oi(e,i),await Ai(e),await $i(e),await bi(e),t.succeed("Features customized.")}catch(r){throw t.fail("Failed to customize features."),r}},Ei=async(e,i)=>{let t=f.join(e,a.HTTP_UTILS),r=i.httpClient!=="none"||i.reactSecureStorage;if(i.httpClient==="none"){if(await x(f.join(e,a.AXIOS_CLIENT)),await x(f.join(e,a.FETCH_CLIENT)),r)await u(f.join(t,"index.ts"),`export * from './token-store';
13
+ `),await w(f.join(e,a.CLIENT_UTILS)),await oe(e,[]);else{await x(t);let o=f.join(e,a.UTILS_INDEX);if(l(o)){let c=await m(o);c=c.replace(/export \* from '\.\/http';\n/,""),await u(o,c)}await w(f.join(e,a.APP_APIS));let n=f.join(e,a.CONFIG_INDEX);if(l(n)){let c=await m(n);c=c.replace(/export \* from '\.\/app-apis';\n/,""),await u(n,c)}}let s=f.join(e,a.CONSTANTS);if(l(s)){let o=await m(s);o=o.replace(/export const API_RESPONSE_DATA_KEY = 'data';\n/,""),o=o.replace(/export const SAVE_AUTH_TOKENS = false;\n/,""),await u(s,o)}if(await x(f.join(e,a.ERRORS_DIR)),!r){await x(f.join(e,a.COMMON_TYPES_DIR)),await x(f.join(e,a.UTILITY_TYPES_DIR));let o=f.join(e,a.TYPES_INDEX);if(l(o)){let n=await m(o);n=n.replace(/export \* from '\.\/utility';\n/,""),n=n.replace(/export \* from '\.\/common';\n/,""),await u(o,n)}}}else if(i.httpClient==="axios"){await x(f.join(e,a.FETCH_CLIENT));let s=await m(f.join(t,"index.ts"));s=s.replace(/export .* from '\.\/fetch-client';\n/g,""),await u(f.join(t,"index.ts"),s);let o=f.join(e,a.HTTP_TYPES);if(l(o)){let n=await m(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)}}else if(i.httpClient==="fetch"){await x(f.join(e,a.AXIOS_CLIENT));let s=await m(f.join(t,"index.ts"));s=s.replace(/export .* from '\.\/axios-client';\n/g,""),await u(f.join(t,"index.ts"),s),await oe(e,["fetch"]);let o=f.join(e,a.HTTP_TYPES);if(l(o)){let n=await m(o);n=n.replace(/export interface AxiosClientOptions \{[\s\S]*?\}\n\n/,""),await u(o,n)}}},Ii=async(e,i)=>{i.httpClient!=="none"||i.reactSecureStorage||await x(f.join(e,a.STORAGE_SERVICE))},Ri=async(e,i)=>{if(!i.redux){await x(f.join(e,a.STORE)),await x(f.join(e,a.COUNTER_FEATURE)),await w(f.join(e,a.STORE_PROVIDER));let t=f.join(e,a.PROVIDERS_INDEX),r=await m(t);r=r.replace(/export \* from '\.\/StoreProvider';\n/,""),await u(t,r);let s=[f.join(e,a.ROOT_PAGE),f.join(e,a.LOCALE_PAGE)];for(let o of s)if(l(o)){let n=await m(o);n=n.replace(/import\s+\{\s*Counter\s*\}\s+from\s+['"]@\/features\/counter['"];\n?/,""),n=n.replace(/<Counter\s*\/>\n?/g,""),await u(o,n)}}},Ni=async(e,i)=>{if(!i.darkMode){await w(f.join(e,a.THEME_PROVIDER));let t=f.join(e,a.PROVIDERS_INDEX),r=await m(t);r=r.replace(/export \* from '\.\/CustomThemeProvider';\n/,""),await u(t,r);let s=f.join(e,a.GLOBALS_CSS);if(l(s)){let o=await m(s);o=o.replace(/@custom-variant dark \(.*?\);\n\n/,""),o=o.replace(/@theme \{[\s\S]*?\}\n/,""),await u(s,o)}if(!i.i18n){let o=f.join(e,a.ROOT_LAYOUT);if(l(o)){let n=await m(o);n=n.replace(/bg-light dark:bg-dark /g,""),await u(o,n)}}}},Oi=async(e,i)=>{if(!i.i18n){await x(f.join(e,a.I18N_DIR)),await x(f.join(e,a.LOCALE_DIR)),await w(f.join(e,a.PROXY)),await w(f.join(e,a.MIDDLEWARE)),await w(f.join(e,a.I18N_TYPES)),await w(f.join(e,a.APP_LOCALES));let t=f.join(e,a.TYPES_INDEX);if(l(t)){let n=await m(t);n=n.replace(/export \* from '\.\/i18n';\n/,""),await u(t,n)}let r=f.join(e,a.CONFIG_INDEX);if(l(r)){let n=await m(r);n=n.replace(/export \* from '\.\/app-locales';\n/,""),await u(r,n)}let s=f.join(e,a.NEXT_CONFIG);if(l(s)){let n=await m(s);n=n.replace(/import createNextIntlPlugin from 'next-intl\/plugin';\n/,""),n=n.replace(/const withNextIntl = createNextIntlPlugin\(\);\n/,""),n=n.replace(/export default withNextIntl\(nextConfig\);/,"export default nextConfig;"),await u(s,n)}let o=f.join(e,a.COUNTER_COMPONENT);if(l(o)){let n=await m(o);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,"{value}"),n=n.replace(/\{t\(['"]increment['"]\)\}/g,"Increment"),n=n.replace(/\{t\(['"]decrement['"]\)\}/g,"Decrement"),n=n.replace(/\{t\(['"]reset['"]\)\}/g,"Reset"),await u(o,n)}}},Ai=async e=>{await w(f.join(e,a.LICENSE))},$i=async e=>{await w(f.join(e,a.CHANGELOG))},bi=async e=>{await w(f.join(e,a.NVM_RC)),await w(f.join(e,a.NPM_RC))};import we from"node:path";I();var Ke=async(e,i)=>{let t=[],r=[];i.redux&&(t.push("import { StoreProvider } from '@/providers';"),r.push("StoreProvider")),i.darkMode&&(t.push("import { CustomThemeProvider } from '@/providers';"),r.push("CustomThemeProvider")),i.i18n&&(t.push("import { NextIntlClientProvider, AbstractIntlMessages } from 'next-intl';"),t.push("import { SupportedLocale } from '@/types/i18n';"));let s=`'use client';
4
14
  ${t.join(`
5
15
  `)}
6
16
 
@@ -23,7 +33,7 @@ export const RootProvider = ({
23
33
  </StoreProvider>`),o==="{children}"&&(o="<>{children}</>"),s+=` ${o}
24
34
  );
25
35
  };
26
- `,await u(Se.join(e,a.ROOT_PROVIDER),s)},Xe=async(e,i)=>{if(!i.i18n){let t=`import type { Metadata } from 'next';
36
+ `,await u(we.join(e,a.ROOT_PROVIDER),s)},qe=async(e,i)=>{if(!i.i18n){let t=`import type { Metadata } from 'next';
27
37
  import '@/styles/globals.css';
28
38
  import { Livvic } from 'next/font/google';
29
39
  import { RootProvider } from '@/providers';
@@ -55,7 +65,7 @@ export default function RootLayout({
55
65
  </html>
56
66
  );
57
67
  }
58
- `;await u(Se.join(e,a.ROOT_LAYOUT),t);let r=i.redux?`import { Counter } from '@/features/counter';
68
+ `;await u(we.join(e,a.ROOT_LAYOUT),t);let r=i.redux?`import { Counter } from '@/features/counter';
59
69
 
60
70
  `:"",s=i.redux?`
61
71
  <Counter />`:"",o=`${r}export default function Home() {
@@ -66,8 +76,8 @@ export default function RootLayout({
66
76
  </div>
67
77
  );
68
78
  }
69
- `;await u(Se.join(e,a.ROOT_PAGE),o)}};import T from"node:path";import{readdir as Je}from"node:fs/promises";I();var Ye=async(e,i)=>{await Ci(e,i),await wi(e,i),await Ti(e,i),await Ei(e,i),await Ii(e,i),await Ri(e,i),await Ni(e,i)},Ci=async(e,i)=>{i.preCommitHooks||(await h(T.join(e,a.HUSKY_DIR)),await v(T.join(e,a.COMMITLINT_CONFIG)),await v(T.join(e,a.LINTSTAGED_RC)),await te(T.join(e,a.PACKAGE_JSON),t=>(delete t.devDependencies[A.HUSKY],delete t.devDependencies[A.COMMITLINT_CLI],delete t.devDependencies[A.COMMITLINT_CONFIG],delete t.devDependencies[A.LINT_STAGED],delete t.scripts.prepare,delete t.scripts.postinstall,delete t.commitlint,delete t["lint-staged"],t)))},wi=async(e,i)=>{i.commitizen||(await v(T.join(e,a.CZRC)),await te(T.join(e,a.PACKAGE_JSON),t=>(delete t.devDependencies[A.COMMITIZEN],delete t.devDependencies[A.CZ_CONVENTIONAL_CHANGELOG],delete t.config?.commitizen,t.config&&Object.keys(t.config).length===0&&delete t.config,delete t.scripts.commit,t)))},Ti=async(e,i)=>{i.ci||await h(T.join(e,a.GITHUB_WORKFLOWS))},Ei=async(e,i)=>{let t=T.join(e,a.GITHUB_DIR);if(!i.keepTemplates)await h(T.join(t,a.GITHUB_ISSUE_TEMPLATE)),await v(T.join(t,a.GITHUB_PR_TEMPLATE));else{let r=T.join(t,a.GITHUB_ISSUE_TEMPLATE),s=T.join(t,a.GITHUB_PR_TEMPLATE),o=n=>n.replace(/Teispace/g,i.company).replace(/support@teispace\.com/g,i.email).replace(/Next\.js Starter/g,i.projectName).replace(/\[AUTHOR\]/g,i.author).replace(/\[COMPANY\]/g,i.company).replace(/\[EMAIL\]/g,i.email);if(l(s)){let n=await d(s);n=o(n),await u(s,n)}try{if(l(r)){let n=await Je(r);for(let c of n){let p=T.join(r,c),g=await d(p);g=o(g),await u(p,g)}}}catch{}}},Ii=async(e,i)=>{let t=[a.CODE_OF_CONDUCT,a.CONTRIBUTING,a.SECURITY];for(let r of t)i.communityFiles.includes(r)||await v(T.join(e,r))},Ri=async(e,i)=>{if(i.docker){let t=T.join(e,a.ENV_EXAMPLE);if(l(t)){let r=await d(t),s=(o,n)=>{let c=new RegExp(`${o}=.*`);c.test(r)?r=r.replace(c,`${o}=${n}`):r+=`${o}=${n}
70
- `};s("CONTAINER_NAME",i.containerName||"next-app"),s("IMAGE_NAME",i.imageName||"nextjs-starter"),s("IMAGE_TAG",i.imageTag||"latest"),await u(t,r)}}else{await v(T.join(e,a.DOCKERFILE)),await v(T.join(e,a.DOCKER_COMPOSE)),await v(T.join(e,a.DOCKERIGNORE));let t=T.join(e,a.ENV_EXAMPLE);if(l(t)){let r=await d(t);r=r.replace(/# Docker Compose Configuration\n/,""),r=r.replace(/CONTAINER_NAME=.*\n/,""),r=r.replace(/IMAGE_NAME=.*\n/,""),r=r.replace(/IMAGE_TAG=.*\n/,""),await u(t,r)}}},Ni=async(e,i)=>{let t=async o=>{let n=await Je(o,{withFileTypes:!0}),c=[];for(let p of n){let g=T.join(o,p.name);p.isDirectory()&&p.name!=="node_modules"&&p.name!==".git"?c.push(...await t(g)):p.isFile()&&p.name.toLowerCase()==="readme.md"&&c.push(g)}return c},r=await t(e),s=T.join(e,a.README);for(let o of r)o!==s&&await v(o);if(i.readme){let o=`# ${i.projectName}
79
+ `;await u(we.join(e,a.ROOT_PAGE),o)}};import T from"node:path";import{readdir as Ze}from"node:fs/promises";I();var Qe=async(e,i)=>{await _i(e,i),await ji(e,i),await Fi(e,i),await ki(e,i),await Di(e,i),await Li(e,i),await Mi(e,i)},_i=async(e,i)=>{i.preCommitHooks||(await x(T.join(e,a.HUSKY_DIR)),await w(T.join(e,a.COMMITLINT_CONFIG)),await w(T.join(e,a.LINTSTAGED_RC)),await ie(T.join(e,a.PACKAGE_JSON),t=>(delete t.devDependencies[A.HUSKY],delete t.devDependencies[A.COMMITLINT_CLI],delete t.devDependencies[A.COMMITLINT_CONFIG],delete t.devDependencies[A.LINT_STAGED],delete t.scripts.prepare,delete t.scripts.postinstall,delete t.commitlint,delete t["lint-staged"],t)))},ji=async(e,i)=>{i.commitizen||(await w(T.join(e,a.CZRC)),await ie(T.join(e,a.PACKAGE_JSON),t=>(delete t.devDependencies[A.COMMITIZEN],delete t.devDependencies[A.CZ_CONVENTIONAL_CHANGELOG],delete t.config?.commitizen,t.config&&Object.keys(t.config).length===0&&delete t.config,delete t.scripts.commit,t)))},Fi=async(e,i)=>{i.ci||await x(T.join(e,a.GITHUB_WORKFLOWS))},ki=async(e,i)=>{let t=T.join(e,a.GITHUB_DIR);if(!i.keepTemplates)await x(T.join(t,a.GITHUB_ISSUE_TEMPLATE)),await w(T.join(t,a.GITHUB_PR_TEMPLATE));else{let r=T.join(t,a.GITHUB_ISSUE_TEMPLATE),s=T.join(t,a.GITHUB_PR_TEMPLATE),o=n=>n.replace(/Teispace/g,i.company).replace(/support@teispace\.com/g,i.email).replace(/Next\.js Starter/g,i.projectName).replace(/\[AUTHOR\]/g,i.author).replace(/\[COMPANY\]/g,i.company).replace(/\[EMAIL\]/g,i.email);if(l(s)){let n=await m(s);n=o(n),await u(s,n)}try{if(l(r)){let n=await Ze(r);for(let c of n){let p=T.join(r,c),g=await m(p);g=o(g),await u(p,g)}}}catch{}}},Di=async(e,i)=>{let t=[a.CODE_OF_CONDUCT,a.CONTRIBUTING,a.SECURITY];for(let r of t)i.communityFiles.includes(r)||await w(T.join(e,r))},Li=async(e,i)=>{if(i.docker){let t=T.join(e,a.ENV_EXAMPLE);if(l(t)){let r=await m(t),s=(o,n)=>{let c=new RegExp(`${o}=.*`);c.test(r)?r=r.replace(c,`${o}=${n}`):r+=`${o}=${n}
80
+ `};s("CONTAINER_NAME",i.containerName||"next-app"),s("IMAGE_NAME",i.imageName||"nextjs-starter"),s("IMAGE_TAG",i.imageTag||"latest"),await u(t,r)}}else{await w(T.join(e,a.DOCKERFILE)),await w(T.join(e,a.DOCKER_COMPOSE)),await w(T.join(e,a.DOCKERIGNORE));let t=T.join(e,a.ENV_EXAMPLE);if(l(t)){let r=await m(t);r=r.replace(/# Docker Compose Configuration\n/,""),r=r.replace(/CONTAINER_NAME=.*\n/,""),r=r.replace(/IMAGE_NAME=.*\n/,""),r=r.replace(/IMAGE_TAG=.*\n/,""),await u(t,r)}}},Mi=async(e,i)=>{let t=async o=>{let n=await Ze(o,{withFileTypes:!0}),c=[];for(let p of n){let g=T.join(o,p.name);p.isDirectory()&&p.name!=="node_modules"&&p.name!==".git"?c.push(...await t(g)):p.isFile()&&p.name.toLowerCase()==="readme.md"&&c.push(g)}return c},r=await t(e),s=T.join(e,a.README);for(let o of r)o!==s&&await w(o);if(i.readme){let o=`# ${i.projectName}
71
81
 
72
82
  ${i.description}
73
83
 
@@ -80,9 +90,9 @@ ${i.packageManager==="npm"?"npm run dev":i.packageManager+" dev"}
80
90
  \`\`\`
81
91
 
82
92
  Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
83
- `;await u(s,o)}else await v(s)};var ze=e=>{e.command("init").description("Initialize a new Next.js project").argument("[name]","Project name").action(async i=>{await Oi(i)})},Oi=async e=>{ke(),m("Welcome to the Teispace Next.js App Creator!"),m("");let i=await be(e),t=ve.resolve(process.cwd(),i.projectName);l(t)&&(console.error(Y.red(`Error: Directory ${i.projectName} already exists.`)),process.exit(1));let r=O("Initializing project..."),s=async()=>{if(l(t)){r.stop(),console.log(Y.yellow(`
84
- Cleaning up: Deleting directory ${i.projectName}...`));try{await h(t),console.log(Y.green("Cleanup successful."))}catch(n){console.error(Y.red(`Failed to clean up directory ${i.projectName}:`),n)}}},o=async()=>{console.log(Y.red(`
85
- Process interrupted. Cleaning up...`)),await s(),process.exit(1)};process.on("SIGINT",o),process.on("SIGTERM",o);try{if(await Le(t),await Ge(t,i),await He(t,i),r.text="Generating code...",await Ue(t,i),await Xe(t,i),r.text="Setting up developer tools...",await Ye(t,i),r.text="Initializing Git...",await je(t,i.gitRemote),r.text="Installing dependencies...",await Fe(t,i.packageManager),r.text="Formatting and Linting...",await L(t,i.packageManager,"format"),await L(t,i.packageManager,"lint:fix"),i.copyEnv){r.text="Creating .env file...";let n=ve.join(t,".env.example"),c=ve.join(t,".env");l(n)&&await(await import("node:fs/promises")).copyFile(n,c)}process.off("SIGINT",o),process.off("SIGTERM",o),r.succeed(Y.green(`Project ${i.projectName} created successfully!`)),m(""),m("To get started:"),m(Y.cyan(` cd ${i.projectName}`)),m(Y.cyan(` ${i.packageManager==="npm"?"npm run dev":i.packageManager+" dev"}`)),m("")}catch(n){r.fail("Failed to create project."),console.error(n),await s(),process.exit(1)}};import N from"picocolors";import Te from"node:path";import Ai from"enquirer";var{prompt:$i}=Ai,We=async(e,i,t,r,s,o,n)=>{let c=[];e||c.push({type:"input",name:"featureName",message:"What is the feature name?",initial:"my-feature",validate:g=>/^[a-z0-9-]+$/.test(g)?!0:"Feature name must be lowercase and contain only alphanumeric characters and hyphens."}),i&&r===void 0&&s===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"&&o===void 0&&n===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 $i(c):{};return{featureName:e||p.featureName,hasRedux:i||!1,createStore:r===!0?!1:s!==void 0?!0:p.createStore||!1,persistStore:s==="persist"?!0:s==="no-persist"?!1:p.persistStore||!1,httpClient:t||"none",createService:o===!0?!1:n!==void 0?!0:p.createService||!1,selectedHttpClient:n||p.selectedHttpClient||(t==="both"?"fetch":t!=="none"?t:void 0)}};import{readFile as bi,access as Ce}from"node:fs/promises";import ie from"node:path";var Q=async e=>{let i=!1,t=!1,r=!1,s=!1;try{let o=ie.join(e,"package.json"),n=await bi(o,"utf-8"),c=JSON.parse(n),p={...c.dependencies,...c.devDependencies};i=!!(p["@reduxjs/toolkit"]&&p["react-redux"]),t=!!p.axios,s=!!p["next-intl"];let g=ie.join(e,"src","lib","utils","http","axios-client");try{await Ce(g),t=t&&!0}catch{t=!1}let S=ie.join(e,"src","lib","utils","http","fetch-client");try{await Ce(S),r=!0}catch{r=!1}let P;return t&&r?P="both":t?P="axios":r?P="fetch":P="none",{hasRedux:i,httpClient:P,hasI18n:s}}catch(o){throw new Error(`Failed to detect project setup: ${o}`)}},Ve=async(e,i,t=ie.join("src","features"))=>{let r=ie.join(e,t,i);try{return await Ce(r),!0}catch{return!1}};import{writeFile as H,mkdir as oe}from"node:fs/promises";import b from"node:path";var Be=async e=>{let{featurePath:i}=e;await oe(b.join(i,"components"),{recursive:!0}),await oe(b.join(i,"hooks"),{recursive:!0}),await oe(b.join(i,"types"),{recursive:!0}),e.createStore&&await oe(b.join(i,"store"),{recursive:!0}),e.createService&&await oe(b.join(i,"services"),{recursive:!0}),await _i(e),await ji(e),await Fi(e),await Li(e),e.createStore&&await ki(e),e.createService&&e.httpClient&&await Di(e)};var _i=async e=>{let{featureName:i,featurePath:t}=e,r=J(i),s=`use${r}`,o=`'use client';
93
+ `;await u(s,o)}else await w(s)};var et=e=>{e.command("init").description("Initialize a new Next.js project").argument("[name]","Project name").action(async i=>{await Hi(i)})},Hi=async e=>{Le(),d("Welcome to the Teispace Next.js App Creator!"),d("");let i=await je(e),t=Te.resolve(process.cwd(),i.projectName);l(t)&&(console.error(W.red(`Error: Directory ${i.projectName} already exists.`)),process.exit(1));let r=O("Initializing project..."),s=async()=>{if(l(t)){r.stop(),console.log(W.yellow(`
94
+ Cleaning up: Deleting directory ${i.projectName}...`));try{await x(t),console.log(W.green("Cleanup successful."))}catch(n){console.error(W.red(`Failed to clean up directory ${i.projectName}:`),n)}}},o=async()=>{console.log(W.red(`
95
+ Process interrupted. Cleaning up...`)),await s(),process.exit(1)};process.on("SIGINT",o),process.on("SIGTERM",o);try{if(await He(t),await Ue(t,i),await Be(t,i),r.text="Generating code...",await Ke(t,i),await qe(t,i),r.text="Setting up developer tools...",await Qe(t,i),r.text="Initializing Git...",await ke(t,i.gitRemote),r.text="Installing dependencies...",await De(t,i.packageManager),r.text="Formatting and Linting...",await L(t,i.packageManager,"format"),await L(t,i.packageManager,"lint:fix"),i.copyEnv){r.text="Creating .env file...";let n=Te.join(t,".env.example"),c=Te.join(t,".env");l(n)&&await(await import("node:fs/promises")).copyFile(n,c)}process.off("SIGINT",o),process.off("SIGTERM",o),r.succeed(W.green(`Project ${i.projectName} created successfully!`)),d(""),d("To get started:"),d(W.cyan(` cd ${i.projectName}`)),d(W.cyan(` ${i.packageManager==="npm"?"npm run dev":i.packageManager+" dev"}`)),d("")}catch(n){r.fail("Failed to create project."),console.error(n),await s(),process.exit(1)}};import N from"picocolors";import Re from"node:path";import Gi from"enquirer";var{prompt:Ui}=Gi,tt=async(e,i,t,r,s,o,n)=>{let c=[];e||c.push({type:"input",name:"featureName",message:"What is the feature name?",initial:"my-feature",validate:g=>/^[a-z0-9-]+$/.test(g)?!0:"Feature name must be lowercase and contain only alphanumeric characters and hyphens."}),i&&r===void 0&&s===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"&&o===void 0&&n===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 Ui(c):{};return{featureName:e||p.featureName,hasRedux:i||!1,createStore:r===!0?!1:s!==void 0?!0:p.createStore||!1,persistStore:s==="persist"?!0:s==="no-persist"?!1:p.persistStore||!1,httpClient:t||"none",createService:o===!0?!1:n!==void 0?!0:p.createService||!1,selectedHttpClient:n||p.selectedHttpClient||(t==="both"?"fetch":t!=="none"?t:void 0)}};import{readFile as Xi,access as Ee}from"node:fs/promises";import re from"node:path";var te=async e=>{let i=!1,t=!1,r=!1,s=!1;try{let o=re.join(e,"package.json"),n=await Xi(o,"utf-8"),c=JSON.parse(n),p={...c.dependencies,...c.devDependencies};i=!!(p["@reduxjs/toolkit"]&&p["react-redux"]),t=!!p.axios,s=!!p["next-intl"];let g=re.join(e,"src","lib","utils","http","axios-client");try{await Ee(g),t=t&&!0}catch{t=!1}let v=re.join(e,"src","lib","utils","http","fetch-client");try{await Ee(v),r=!0}catch{r=!1}let C;return t&&r?C="both":t?C="axios":r?C="fetch":C="none",{hasRedux:i,httpClient:C,hasI18n:s}}catch(o){throw new Error(`Failed to detect project setup: ${o}`)}},it=async(e,i,t=re.join("src","features"))=>{let r=re.join(e,t,i);try{return await Ee(r),!0}catch{return!1}};import{writeFile as U,mkdir as ne}from"node:fs/promises";import b from"node:path";var ot=async e=>{let{featurePath:i}=e;await ne(b.join(i,"components"),{recursive:!0}),await ne(b.join(i,"hooks"),{recursive:!0}),await ne(b.join(i,"types"),{recursive:!0}),e.createStore&&await ne(b.join(i,"store"),{recursive:!0}),e.createService&&await ne(b.join(i,"services"),{recursive:!0}),await Yi(e),await Ji(e),await zi(e),await Bi(e),e.createStore&&await Wi(e),e.createService&&e.httpClient&&await Vi(e)};var Yi=async e=>{let{featureName:i,featurePath:t}=e,r=z(i),s=`use${r}`,o=`'use client';
86
96
  import { ${s} } from '../hooks/${s}';
87
97
 
88
98
  export function ${r}() {
@@ -97,7 +107,7 @@ export function ${r}() {
97
107
  }
98
108
 
99
109
  export default ${r};
100
- `;await H(b.join(t,"components",`${r}.tsx`),o)},ji=async e=>{let{featureName:i,featurePath:t,createStore:r}=e,s=J(i),o=`use${s}`,n;r?n=`'use client';
110
+ `;await U(b.join(t,"components",`${r}.tsx`),o)},Ji=async e=>{let{featureName:i,featurePath:t,createStore:r}=e,s=z(i),o=`use${s}`,n;r?n=`'use client';
101
111
  import { useAppDispatch, useAppSelector } from '@/store/hooks';
102
112
  import { select${s}State, setLoading, setError } from '../store/${i}.selectors';
103
113
 
@@ -133,12 +143,12 @@ export const ${o} = () => {
133
143
  // Add your methods here
134
144
  } as const;
135
145
  };
136
- `,await H(b.join(t,"hooks",`${o}.ts`),n)},Fi=async e=>{let{featureName:i,featurePath:t,createStore:r}=e,n=`export interface ${`${J(i)}State`} {
146
+ `,await U(b.join(t,"hooks",`${o}.ts`),n)},zi=async e=>{let{featureName:i,featurePath:t,createStore:r}=e,n=`export interface ${`${z(i)}State`} {
137
147
  // Add your state properties here
138
148
  ${r?`loading: boolean;
139
149
  error: string | null;`:"// example: value: string;"}
140
150
  }
141
- `;await H(b.join(t,"types",`${i}.types.ts`),n)},ki=async e=>{let{featureName:i,featurePath:t,persistStore:r}=e,s=J(i),o=j(i),n=`import { createSlice, PayloadAction } from '@reduxjs/toolkit';
151
+ `;await U(b.join(t,"types",`${i}.types.ts`),n)},Wi=async e=>{let{featureName:i,featurePath:t,persistStore:r}=e,s=z(i),o=j(i),n=`import { createSlice, PayloadAction } from '@reduxjs/toolkit';
142
152
  import { ${s}State } from '../types/${i}.types';
143
153
 
144
154
  const initialState: ${s}State = {
@@ -167,11 +177,11 @@ export const ${o}Slice = createSlice({
167
177
  export const { setLoading, setError, resetState } = ${o}Slice.actions;
168
178
 
169
179
  export const ${o}Reducer = ${o}Slice.reducer;
170
- `;await H(b.join(t,"store",`${i}.slice.ts`),n);let c=`import { RootState } from '@/store/rootReducer';
180
+ `;await U(b.join(t,"store",`${i}.slice.ts`),n);let c=`import { RootState } from '@/store/rootReducer';
171
181
 
172
182
  export const select${s}State = (state: RootState) => state.${o};
173
183
  export { setLoading, setError, resetState } from './${i}.slice';
174
- `;if(await H(b.join(t,"store",`${i}.selectors.ts`),c),r){let g=`import { PersistConfig } from 'redux-persist';
184
+ `;if(await U(b.join(t,"store",`${i}.selectors.ts`),c),r){let g=`import { PersistConfig } from 'redux-persist';
175
185
  import storage from 'redux-persist/lib/storage';
176
186
  import { ${s}State } from '../types/${i}.types';
177
187
 
@@ -180,10 +190,10 @@ export const ${o}PersistConfig: PersistConfig<${s}State> = {
180
190
  storage,
181
191
  // whitelist: ['someField'], // Specify which fields to persist
182
192
  };
183
- `;await H(b.join(t,"store","persist.ts"),g)}let p=`export * from './${i}.slice';
193
+ `;await U(b.join(t,"store","persist.ts"),g)}let p=`export * from './${i}.slice';
184
194
  export * from './${i}.selectors';${r?`
185
195
  export * from './persist';`:""}
186
- `;await H(b.join(t,"store","index.ts"),p)},Di=async e=>{let{featureName:i,featurePath:t,httpClient:r}=e,s=j(i),o;r==="axios"?o=`import { AppApis } from '@/lib/config';
196
+ `;await U(b.join(t,"store","index.ts"),p)},Vi=async e=>{let{featureName:i,featurePath:t,httpClient:r}=e,s=j(i),o;r==="axios"?o=`import { AppApis } from '@/lib/config';
187
197
  import { axiosClient } from '@/lib/utils/http';
188
198
  import { ResultAsync } from '@/types';
189
199
 
@@ -201,40 +211,40 @@ export const ${s}Service = {
201
211
  return fetchClient.get<string>(AppApis.${s}.getAll);
202
212
  },
203
213
  };
204
- `,await H(b.join(t,"services",`${i}.service.ts`),o)},Li=async e=>{let{featureName:i,featurePath:t,createStore:r,createService:s}=e,o=J(i),n=`export { default as ${o} } from './components/${o}';
214
+ `,await U(b.join(t,"services",`${i}.service.ts`),o)},Bi=async e=>{let{featureName:i,featurePath:t,createStore:r,createService:s}=e,o=z(i),n=`export { default as ${o} } from './components/${o}';
205
215
  export { use${o} } from './hooks/use${o}';
206
216
  export * from './types/${i}.types';${r?`
207
217
  export * from './store';`:""}${s?`
208
218
  export * from './services/${i}.service';`:""}
209
- `;await H(b.join(t,"index.ts"),n)};import{readFile as Ke,writeFile as qe}from"node:fs/promises";import we from"node:path";var Ze=async(e,i,t,r=we.join("src","features"))=>{let s=we.join(e,"src","store","rootReducer.ts");try{let o=await Ke(s,"utf-8"),n=j(i),c=`${n}Reducer`,p=t?`${n}PersistConfig`:"",g=r.replace(/^src\//,"@/"),S=t?`import { ${c}, ${p} } from '${g}/${i}/store';`:`import { ${c} } from '${g}/${i}/store';`,P=/import\s+.*\s+from\s+['"].*['"];?\n/g,x=o.match(P);if(x&&x.length>0){let R=x[x.length-1],k=o.lastIndexOf(R);o=o.slice(0,k+R.length)+S+`
210
- `+o.slice(k+R.length)}else o=S+`
211
- `+o;let w=/combineReducers\(\{([^}]*)\}\)/s,F=o.match(w);if(F){let R=F[1],k=t?`
219
+ `;await U(b.join(t,"index.ts"),n)};import{readFile as rt,writeFile as nt}from"node:fs/promises";import Ie from"node:path";var st=async(e,i,t,r=Ie.join("src","features"))=>{let s=Ie.join(e,"src","store","rootReducer.ts");try{let o=await rt(s,"utf-8"),n=j(i),c=`${n}Reducer`,p=t?`${n}PersistConfig`:"",g=r.replace(/^src\//,"@/"),v=t?`import { ${c}, ${p} } from '${g}/${i}/store';`:`import { ${c} } from '${g}/${i}/store';`,C=/import\s+.*\s+from\s+['"].*['"];?\n/g,h=o.match(C);if(h&&h.length>0){let R=h[h.length-1],k=o.lastIndexOf(R);o=o.slice(0,k+R.length)+v+`
220
+ `+o.slice(k+R.length)}else o=v+`
221
+ `+o;let S=/combineReducers\(\{([^}]*)\}\)/s,F=o.match(S);if(F){let R=F[1],k=t?`
212
222
  ${n}: persistReducer(${p}, ${c}),`:`
213
- ${n}: ${c},`,Z=R.trimEnd()+k;o=o.replace(w,`combineReducers({${Z}
214
- })`)}else throw new Error("Could not find combineReducers in rootReducer.ts");await qe(s,o)}catch(o){throw new Error(`Failed to register feature in rootReducer: ${o}`)}},Qe=async(e,i,t,r)=>{let s=we.join(e,"src","store","rootReducer.ts");try{let o=await Ke(s,"utf-8"),n=j(i),c=`${n}Reducer`,p=t?`${n}PersistConfig`:"",g=r.replace(/^src\//,"@/"),S=t?`import { ${c}, ${p} } from '${g}/${i}';`:`import { ${c} } from '${g}/${i}';`,P=/import\s+.*\s+from\s+['"].*['"];?\n/g,x=o.match(P);if(x&&x.length>0){let R=x[x.length-1],k=o.lastIndexOf(R);o=o.slice(0,k+R.length)+S+`
215
- `+o.slice(k+R.length)}else o=S+`
216
- `+o;let w=/combineReducers\(\{([^}]*)\}\)/s,F=o.match(w);if(F){let R=F[1],k=t?`
223
+ ${n}: ${c},`,ee=R.trimEnd()+k;o=o.replace(S,`combineReducers({${ee}
224
+ })`)}else throw new Error("Could not find combineReducers in rootReducer.ts");await nt(s,o)}catch(o){throw new Error(`Failed to register feature in rootReducer: ${o}`)}},at=async(e,i,t,r)=>{let s=Ie.join(e,"src","store","rootReducer.ts");try{let o=await rt(s,"utf-8"),n=j(i),c=`${n}Reducer`,p=t?`${n}PersistConfig`:"",g=r.replace(/^src\//,"@/"),v=t?`import { ${c}, ${p} } from '${g}/${i}';`:`import { ${c} } from '${g}/${i}';`,C=/import\s+.*\s+from\s+['"].*['"];?\n/g,h=o.match(C);if(h&&h.length>0){let R=h[h.length-1],k=o.lastIndexOf(R);o=o.slice(0,k+R.length)+v+`
225
+ `+o.slice(k+R.length)}else o=v+`
226
+ `+o;let S=/combineReducers\(\{([^}]*)\}\)/s,F=o.match(S);if(F){let R=F[1],k=t?`
217
227
  ${n}: persistReducer(${p}, ${c}),`:`
218
- ${n}: ${c},`,Z=R.trimEnd()+k;o=o.replace(w,`combineReducers({${Z}
219
- })`)}else throw new Error("Could not find combineReducers in rootReducer.ts");await qe(s,o)}catch(o){throw new Error(`Failed to register slice in rootReducer: ${o}`)}};import{readFile as Mi,writeFile as Gi}from"node:fs/promises";import Hi from"node:path";var me=async e=>{let{serviceName:i,projectPath:t}=e,r=j(i),s=Hi.join(t,"src","lib","config","app-apis.ts");try{let o=await Mi(s,"utf-8");if(o.includes(`${r}:`))return;if(!o.match(/export const AppApis = \{[\s\S]*?\} as const;/))throw new Error("Could not find AppApis object in app-apis.ts");let c=` ${r}: {
228
+ ${n}: ${c},`,ee=R.trimEnd()+k;o=o.replace(S,`combineReducers({${ee}
229
+ })`)}else throw new Error("Could not find combineReducers in rootReducer.ts");await nt(s,o)}catch(o){throw new Error(`Failed to register slice in rootReducer: ${o}`)}};import{readFile as Ki,writeFile as qi}from"node:fs/promises";import Zi from"node:path";var ue=async e=>{let{serviceName:i,projectPath:t}=e,r=j(i),s=Zi.join(t,"src","lib","config","app-apis.ts");try{let o=await Ki(s,"utf-8");if(o.includes(`${r}:`))return;if(!o.match(/export const AppApis = \{[\s\S]*?\} as const;/))throw new Error("Could not find AppApis object in app-apis.ts");let c=` ${r}: {
220
230
  base: \`\${API_PREFIX}/${i}\`,
221
231
  getAll: \`\${API_PREFIX}/${i}\`,
222
- },`,p=/(\s*)\} as const;/;if(!o.match(p))throw new Error("Could not find closing brace of AppApis object");let S=o.lastIndexOf("} as const;"),P=o.substring(0,S),x=o.substring(S),w=P.trim().endsWith(","),F=P.match(/:\s*\{[^}]*\},\s*$/),R;F||w?R=`${P}
232
+ },`,p=/(\s*)\} as const;/;if(!o.match(p))throw new Error("Could not find closing brace of AppApis object");let v=o.lastIndexOf("} as const;"),C=o.substring(0,v),h=o.substring(v),S=C.trim().endsWith(","),F=C.match(/:\s*\{[^}]*\},\s*$/),R;F||S?R=`${C}
223
233
  ${c}
224
- ${x}`:R=P.trimEnd()+`
234
+ ${h}`:R=C.trimEnd()+`
225
235
  `+c+`
226
- `+x,await Gi(s,R)}catch(o){throw new Error(`Failed to register API endpoints: ${o}`)}};var et=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(i,t)=>{try{let r=process.cwd();t.store&&!["persist","no-persist"].includes(t.store)&&(E("Invalid --store option. Use: persist or no-persist"),process.exit(1)),t.service&&!["axios","fetch"].includes(t.service)&&(E("Invalid --service option. Use: axios or fetch"),process.exit(1)),t.skipStore&&t.store&&(E("Cannot use --skip-store and --store together"),process.exit(1)),t.skipService&&t.service&&(E("Cannot use --skip-service and --service together"),process.exit(1)),m(N.cyan(`
236
+ `+h,await qi(s,R)}catch(o){throw new Error(`Failed to register API endpoints: ${o}`)}};var ct=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(i,t)=>{try{let r=process.cwd();t.store&&!["persist","no-persist"].includes(t.store)&&(E("Invalid --store option. Use: persist or no-persist"),process.exit(1)),t.service&&!["axios","fetch"].includes(t.service)&&(E("Invalid --service option. Use: axios or fetch"),process.exit(1)),t.skipStore&&t.store&&(E("Cannot use --skip-store and --store together"),process.exit(1)),t.skipService&&t.service&&(E("Cannot use --skip-service and --service together"),process.exit(1)),d(N.cyan(`
227
237
  \u{1F3AF} Feature Generator
228
- `)),y.start("Detecting project setup...");let s=await Q(r);y.succeed("Project setup detected"),m(N.dim(` Redux: ${s.hasRedux?"\u2713":"\u2717"}`)),m(N.dim(` HTTP Client: ${s.httpClient}`)),m(N.dim(` i18n: ${s.hasI18n?"\u2713":"\u2717"}
229
- `));let o=await We(i,s.hasRedux,s.httpClient,t.skipStore,t.store,t.skipService,t.service),n=t.path||Te.join("src","features"),c=Te.join(r,n,o.featureName);await Ve(r,o.featureName,n)&&(E(`Feature '${o.featureName}' already exists at ${n}!`),process.exit(1)),y.start("Generating feature files..."),await Be({featureName:o.featureName,featurePath:c,createStore:o.createStore,persistStore:o.persistStore,createService:o.createService,httpClient:o.selectedHttpClient}),y.succeed("Feature files generated"),o.createService&&(y.start("Registering API endpoints..."),await me({serviceName:o.featureName,projectPath:r}),y.succeed("API endpoints registered")),o.createStore&&s.hasRedux&&(y.start("Registering feature in rootReducer..."),await Ze(r,o.featureName,o.persistStore,n),y.succeed("Feature registered in rootReducer"));let g=Te.join(n,o.featureName);m(N.green(`
238
+ `)),P.start("Detecting project setup...");let s=await te(r);P.succeed("Project setup detected"),d(N.dim(` Redux: ${s.hasRedux?"\u2713":"\u2717"}`)),d(N.dim(` HTTP Client: ${s.httpClient}`)),d(N.dim(` i18n: ${s.hasI18n?"\u2713":"\u2717"}
239
+ `));let o=await tt(i,s.hasRedux,s.httpClient,t.skipStore,t.store,t.skipService,t.service),n=t.path||Re.join("src","features"),c=Re.join(r,n,o.featureName);await it(r,o.featureName,n)&&(E(`Feature '${o.featureName}' already exists at ${n}!`),process.exit(1)),P.start("Generating feature files..."),await ot({featureName:o.featureName,featurePath:c,createStore:o.createStore,persistStore:o.persistStore,createService:o.createService,httpClient:o.selectedHttpClient}),P.succeed("Feature files generated"),o.createService&&(P.start("Registering API endpoints..."),await ue({serviceName:o.featureName,projectPath:r}),P.succeed("API endpoints registered")),o.createStore&&s.hasRedux&&(P.start("Registering feature in rootReducer..."),await st(r,o.featureName,o.persistStore,n),P.succeed("Feature registered in rootReducer"));let g=Re.join(n,o.featureName);d(N.green(`
230
240
  \u2728 Feature '${o.featureName}' created successfully!
231
- `)),m(N.dim("Generated files:")),m(N.dim(` \u{1F4C2} ${g}/`)),m(N.dim(" \u251C\u2500\u2500 components/")),m(N.dim(" \u251C\u2500\u2500 hooks/")),m(N.dim(" \u251C\u2500\u2500 types/")),o.createStore&&m(N.dim(" \u251C\u2500\u2500 store/")),o.createService&&m(N.dim(" \u251C\u2500\u2500 services/")),m(N.dim(` \u2514\u2500\u2500 index.ts
232
- `)),m(N.cyan("Next steps:"));let S=n.replace(/^src\//,"@/");m(N.dim(` 1. Import and use the feature: import { ${o.featureName} } from '${S}/${o.featureName}'`)),o.createStore&&m(N.dim(` 2. Customize your Redux slice in: ${g}/store/`)),o.createService&&m(N.dim(` 3. Add API methods in: ${g}/services/${o.featureName}.service.ts`)),m("")}catch(r){y.fail("Feature generation failed"),E(`${r}`),process.exit(1)}})};import _ from"picocolors";import z from"node:path";import{existsSync as qi}from"node:fs";import{mkdir as Zi}from"node:fs/promises";import Ui from"enquirer";var{prompt:Xi}=Ui,tt=async(e,i,t)=>{let r=[];e||r.push({type:"input",name:"sliceName",message:"What is the slice name?",initial:"my-slice",validate:o=>/^[a-z0-9-]+$/.test(o)?!0:"Slice name must be lowercase and contain only alphanumeric characters and hyphens."}),i===void 0&&t===void 0&&r.push({type:"confirm",name:"persistSlice",message:"Enable persistence for this slice?",initial:!1});let s=r.length>0?await Xi(r):{};return{sliceName:e||s.sliceName,persistSlice:i===!0?!0:t===!1?!1:s.persistSlice||!1}};import{writeFile as re,mkdir as Ji}from"node:fs/promises";import ne from"node:path";var it=async e=>{let{sliceName:i,slicePath:t,persistSlice:r}=e;await Ji(t,{recursive:!0});let s=J(i),o=j(i);await Yi(i,t,s),await zi(i,t,s,o),await Wi(i,t,s,o),r&&await Vi(i,t,s,o),await Bi(i,t,r)},Yi=async(e,i,t)=>{let r=`export interface ${t}State {
241
+ `)),d(N.dim("Generated files:")),d(N.dim(` \u{1F4C2} ${g}/`)),d(N.dim(" \u251C\u2500\u2500 components/")),d(N.dim(" \u251C\u2500\u2500 hooks/")),d(N.dim(" \u251C\u2500\u2500 types/")),o.createStore&&d(N.dim(" \u251C\u2500\u2500 store/")),o.createService&&d(N.dim(" \u251C\u2500\u2500 services/")),d(N.dim(` \u2514\u2500\u2500 index.ts
242
+ `)),d(N.cyan("Next steps:"));let v=n.replace(/^src\//,"@/");d(N.dim(` 1. Import and use the feature: import { ${o.featureName} } from '${v}/${o.featureName}'`)),o.createStore&&d(N.dim(` 2. Customize your Redux slice in: ${g}/store/`)),o.createService&&d(N.dim(` 3. Add API methods in: ${g}/services/${o.featureName}.service.ts`)),d("")}catch(r){P.fail("Feature generation failed"),E(`${r}`),process.exit(1)}})};import _ from"picocolors";import V from"node:path";import{existsSync as co}from"node:fs";import{mkdir as lo}from"node:fs/promises";import Qi from"enquirer";var{prompt:eo}=Qi,lt=async(e,i,t)=>{let r=[];e||r.push({type:"input",name:"sliceName",message:"What is the slice name?",initial:"my-slice",validate:o=>/^[a-z0-9-]+$/.test(o)?!0:"Slice name must be lowercase and contain only alphanumeric characters and hyphens."}),i===void 0&&t===void 0&&r.push({type:"confirm",name:"persistSlice",message:"Enable persistence for this slice?",initial:!1});let s=r.length>0?await eo(r):{};return{sliceName:e||s.sliceName,persistSlice:i===!0?!0:t===!1?!1:s.persistSlice||!1}};import{writeFile as se,mkdir as to}from"node:fs/promises";import ae from"node:path";var pt=async e=>{let{sliceName:i,slicePath:t,persistSlice:r}=e;await to(t,{recursive:!0});let s=z(i),o=j(i);await io(i,t,s),await oo(i,t,s,o),await ro(i,t,s,o),r&&await no(i,t,s,o),await so(i,t,r)},io=async(e,i,t)=>{let r=`export interface ${t}State {
233
243
  loading: boolean;
234
244
  error: string | null;
235
245
  // Add your state properties here
236
246
  }
237
- `;await re(ne.join(i,`${e}.types.ts`),r)},zi=async(e,i,t,r)=>{let s=`import { createSlice, PayloadAction } from '@reduxjs/toolkit';
247
+ `;await se(ae.join(i,`${e}.types.ts`),r)},oo=async(e,i,t,r)=>{let s=`import { createSlice, PayloadAction } from '@reduxjs/toolkit';
238
248
  import { ${t}State } from './${e}.types';
239
249
 
240
250
  const initialState: ${t}State = {
@@ -263,11 +273,11 @@ export const ${r}Slice = createSlice({
263
273
  export const { setLoading, setError, resetState } = ${r}Slice.actions;
264
274
 
265
275
  export const ${r}Reducer = ${r}Slice.reducer;
266
- `;await re(ne.join(i,`${e}.slice.ts`),s)},Wi=async(e,i,t,r)=>{let s=`import { RootState } from '@/store/rootReducer';
276
+ `;await se(ae.join(i,`${e}.slice.ts`),s)},ro=async(e,i,t,r)=>{let s=`import { RootState } from '@/store/rootReducer';
267
277
 
268
278
  export const select${t}State = (state: RootState) => state.${r};
269
279
  export { setLoading, setError, resetState } from './${e}.slice';
270
- `;await re(ne.join(i,`${e}.selectors.ts`),s)},Vi=async(e,i,t,r)=>{let s=`import { PersistConfig } from 'redux-persist';
280
+ `;await se(ae.join(i,`${e}.selectors.ts`),s)},no=async(e,i,t,r)=>{let s=`import { PersistConfig } from 'redux-persist';
271
281
  import storage from 'redux-persist/lib/storage';
272
282
  import { ${t}State } from './${e}.types';
273
283
 
@@ -276,19 +286,19 @@ export const ${r}PersistConfig: PersistConfig<${t}State> = {
276
286
  storage,
277
287
  // whitelist: ['someField'], // Specify which fields to persist
278
288
  };
279
- `;await re(ne.join(i,"persist.ts"),s)},Bi=async(e,i,t)=>{let r=`export * from './${e}.slice';
289
+ `;await se(ae.join(i,"persist.ts"),s)},so=async(e,i,t)=>{let r=`export * from './${e}.slice';
280
290
  export * from './${e}.selectors';
281
291
  export * from './${e}.types';${t?`
282
292
  export * from './persist';`:""}
283
- `;await re(ne.join(i,"index.ts"),r)};import{access as Ki}from"node:fs/promises";import ot from"node:path";var rt=async(e,i,t=ot.join("src","store","slices"))=>{let r=ot.join(e,t,i);try{return await Ki(r),!0}catch{return!1}};var nt=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").action(async(i,t)=>{try{let r=process.cwd();t.persist&&t.noPersist===!0&&(E("Cannot use --persist and --no-persist together"),process.exit(1)),m(_.cyan(`
293
+ `;await se(ae.join(i,"index.ts"),r)};import{access as ao}from"node:fs/promises";import mt from"node:path";var dt=async(e,i,t=mt.join("src","store","slices"))=>{let r=mt.join(e,t,i);try{return await ao(r),!0}catch{return!1}};var ut=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").action(async(i,t)=>{try{let r=process.cwd();t.persist&&t.noPersist===!0&&(E("Cannot use --persist and --no-persist together"),process.exit(1)),d(_.cyan(`
284
294
  \u{1F527} Slice Generator
285
- `)),y.start("Detecting project setup...");let s=await Q(r);y.succeed("Project setup detected"),s.hasRedux||(y.fail("Redux is not setup in this project"),E("Please install @reduxjs/toolkit and react-redux first"),m(_.dim(`
295
+ `)),P.start("Detecting project setup...");let s=await te(r);P.succeed("Project setup detected"),s.hasRedux||(P.fail("Redux is not setup in this project"),E("Please install @reduxjs/toolkit and react-redux first"),d(_.dim(`
286
296
  Run: npm install @reduxjs/toolkit react-redux
287
- `)),process.exit(1)),m(_.dim(` Redux: \u2713
288
- `));let o=await tt(i,t.persist,t.noPersist===!0?!1:void 0),n,c,p;if(t.path){let w=t.path.replace(/^src\//,"");w.startsWith("features/")?(c=w.split("/")[1],n=z.join("src","features",c,"store"),p=z.join(r,n,o.sliceName)):(n=z.join("src",w),c=w.split("/")[0],p=z.join(r,n,o.sliceName))}else c=o.sliceName,n=z.join("src","features",c,"store"),p=z.join(r,n,o.sliceName);let g=z.join(r,n);qi(g)||await Zi(g,{recursive:!0}),await rt(r,o.sliceName,n)&&(E(`Slice '${o.sliceName}' already exists at ${n}!`),process.exit(1)),y.start("Generating slice files..."),await it({sliceName:o.sliceName,slicePath:p,persistSlice:o.persistSlice}),y.succeed("Slice files generated"),y.start("Registering slice in rootReducer..."),await Qe(r,o.sliceName,o.persistSlice,n),y.succeed("Slice registered in rootReducer");let P=z.join(n,o.sliceName);m(_.green(`
297
+ `)),process.exit(1)),d(_.dim(` Redux: \u2713
298
+ `));let o=await lt(i,t.persist,t.noPersist===!0?!1:void 0),n,c,p;if(t.path){let S=t.path.replace(/^src\//,"");S.startsWith("features/")?(c=S.split("/")[1],n=V.join("src","features",c,"store"),p=V.join(r,n,o.sliceName)):(n=V.join("src",S),c=S.split("/")[0],p=V.join(r,n,o.sliceName))}else c=o.sliceName,n=V.join("src","features",c,"store"),p=V.join(r,n,o.sliceName);let g=V.join(r,n);co(g)||await lo(g,{recursive:!0}),await dt(r,o.sliceName,n)&&(E(`Slice '${o.sliceName}' already exists at ${n}!`),process.exit(1)),P.start("Generating slice files..."),await pt({sliceName:o.sliceName,slicePath:p,persistSlice:o.persistSlice}),P.succeed("Slice files generated"),P.start("Registering slice in rootReducer..."),await at(r,o.sliceName,o.persistSlice,n),P.succeed("Slice registered in rootReducer");let C=V.join(n,o.sliceName);d(_.green(`
289
299
  \u2728 Slice '${o.sliceName}' created successfully!
290
- `)),m(_.dim("Generated files:")),m(_.dim(` \u{1F4C2} ${P}/`)),m(_.dim(` \u251C\u2500\u2500 ${o.sliceName}.slice.ts`)),m(_.dim(` \u251C\u2500\u2500 ${o.sliceName}.selectors.ts`)),o.persistSlice&&m(_.dim(" \u251C\u2500\u2500 persist.ts")),m(_.dim(` \u251C\u2500\u2500 ${o.sliceName}.types.ts`)),m(_.dim(` \u2514\u2500\u2500 index.ts
291
- `)),m(_.cyan("Next steps:"));let x=n.replace(/^src\//,"@/");m(_.dim(` 1. Import actions: import { setLoading, setError } from '${x}/${o.sliceName}'`)),m(_.dim(" 2. Use in component: dispatch(setLoading(true))")),m("")}catch(r){y.fail("Slice generation failed"),E(`${r}`),process.exit(1)}})};import U from"picocolors";import K from"node:path";import{existsSync as ro}from"node:fs";import{mkdir as no}from"node:fs/promises";import st from"enquirer";var at=async(e,i,t,r)=>{let s=e||(await st.prompt({type:"input",name:"serviceName",message:"Service name (kebab-case):",validate:n=>n?/^[a-z0-9-]+$/.test(n)?!0:"Service name must be lowercase with hyphens only":"Service name is required"})).serviceName,o;return i!==void 0?o="axios":t!==void 0?o="fetch":r==="axios"?o="axios":r==="fetch"?o="fetch":r==="both"?o=(await st.prompt({type:"select",name:"httpClient",message:"Choose HTTP client:",choices:["axios","fetch"]})).httpClient:o="axios",{serviceName:s,httpClient:o}};import{writeFile as Qi}from"node:fs/promises";import eo from"node:path";var ct=async e=>{await to(e)},to=async e=>{let{serviceName:i,servicePath:t,httpClient:r}=e,s=j(i),o;r==="axios"?o=`import { AppApis } from '@/lib/config';
300
+ `)),d(_.dim("Generated files:")),d(_.dim(` \u{1F4C2} ${C}/`)),d(_.dim(` \u251C\u2500\u2500 ${o.sliceName}.slice.ts`)),d(_.dim(` \u251C\u2500\u2500 ${o.sliceName}.selectors.ts`)),o.persistSlice&&d(_.dim(" \u251C\u2500\u2500 persist.ts")),d(_.dim(` \u251C\u2500\u2500 ${o.sliceName}.types.ts`)),d(_.dim(` \u2514\u2500\u2500 index.ts
301
+ `)),d(_.cyan("Next steps:"));let h=n.replace(/^src\//,"@/");d(_.dim(` 1. Import actions: import { setLoading, setError } from '${h}/${o.sliceName}'`)),d(_.dim(" 2. Use in component: dispatch(setLoading(true))")),d("")}catch(r){P.fail("Slice generation failed"),E(`${r}`),process.exit(1)}})};import X from"picocolors";import Z from"node:path";import{existsSync as xo}from"node:fs";import{mkdir as ho}from"node:fs/promises";import ft from"enquirer";var gt=async(e,i,t,r)=>{let s=e||(await ft.prompt({type:"input",name:"serviceName",message:"Service name (kebab-case):",validate:n=>n?/^[a-z0-9-]+$/.test(n)?!0:"Service name must be lowercase with hyphens only":"Service name is required"})).serviceName,o;return i!==void 0?o="axios":t!==void 0?o="fetch":r==="axios"?o="axios":r==="fetch"?o="fetch":r==="both"?o=(await ft.prompt({type:"select",name:"httpClient",message:"Choose HTTP client:",choices:["axios","fetch"]})).httpClient:o="axios",{serviceName:s,httpClient:o}};import{writeFile as po}from"node:fs/promises";import mo from"node:path";var xt=async e=>{await uo(e)},uo=async e=>{let{serviceName:i,servicePath:t,httpClient:r}=e,s=j(i),o;r==="axios"?o=`import { AppApis } from '@/lib/config';
292
302
  import { axiosClient } from '@/lib/utils/http';
293
303
  import { ResultAsync } from '@/types';
294
304
 
@@ -306,16 +316,16 @@ export const ${s}Service = {
306
316
  return fetchClient.get<string>(AppApis.${s}.getAll);
307
317
  },
308
318
  };
309
- `;let n=`${i}.service.ts`;await Qi(eo.join(t,n),o)};import{existsSync as io}from"node:fs";import oo from"node:path";var lt=async(e,i,t)=>{let r=oo.join(e,t,`${i}.service.ts`);return io(r)};var pt=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").action(async(i,t)=>{try{let r=process.cwd();t.axios&&t.fetch&&(E("Cannot use --axios and --fetch together"),process.exit(1)),m(U.cyan(`
319
+ `;let n=`${i}.service.ts`;await po(mo.join(t,n),o)};import{existsSync as fo}from"node:fs";import go from"node:path";var ht=async(e,i,t)=>{let r=go.join(e,t,`${i}.service.ts`);return fo(r)};var yt=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").action(async(i,t)=>{try{let r=process.cwd();t.axios&&t.fetch&&(E("Cannot use --axios and --fetch together"),process.exit(1)),d(X.cyan(`
310
320
  \u{1F527} Service Generator
311
- `)),y.start("Detecting project setup...");let s=await Q(r);y.succeed("Project setup detected"),s.httpClient==="none"&&(y.fail("No HTTP client is setup in this project"),E("Please setup either AxiosClient or FetchClient first"),m(U.dim(`
321
+ `)),P.start("Detecting project setup...");let s=await te(r);P.succeed("Project setup detected"),s.httpClient==="none"&&(P.fail("No HTTP client is setup in this project"),E("Please setup either AxiosClient or FetchClient first"),d(X.dim(`
312
322
  Check: lib/utils/http/axios-client or lib/utils/http/fetch-client
313
- `)),process.exit(1));let o=[];(s.httpClient==="axios"||s.httpClient==="both")&&o.push("Axios \u2713"),(s.httpClient==="fetch"||s.httpClient==="both")&&o.push("Fetch \u2713"),m(U.dim(` HTTP Clients: ${o.join(", ")}
314
- `));let n=await at(i,t.axios,t.fetch,s.httpClient),c,p,g;if(t.path){let w=t.path.replace(/^src\//,"");w.startsWith("features/")?(p=w.split("/")[1],c=K.join("src","features",p,"services"),g=K.join(r,c)):(c=K.join("src",w),p=w.split("/")[0],g=K.join(r,c))}else p=n.serviceName,c=K.join("src","features",p,"services"),g=K.join(r,c);ro(g)||await no(g,{recursive:!0}),await lt(r,n.serviceName,c)&&(E(`Service '${n.serviceName}' already exists at ${c}!`),process.exit(1)),y.start("Generating service files..."),await ct({serviceName:n.serviceName,servicePath:g,httpClient:n.httpClient}),y.succeed("Service files generated"),y.start("Registering API endpoints..."),await me({serviceName:n.serviceName,projectPath:r}),y.succeed("API endpoints registered");let P=K.join(c,`${n.serviceName}.service.ts`);m(U.green(`
323
+ `)),process.exit(1));let o=[];(s.httpClient==="axios"||s.httpClient==="both")&&o.push("Axios \u2713"),(s.httpClient==="fetch"||s.httpClient==="both")&&o.push("Fetch \u2713"),d(X.dim(` HTTP Clients: ${o.join(", ")}
324
+ `));let n=await gt(i,t.axios,t.fetch,s.httpClient),c,p,g;if(t.path){let S=t.path.replace(/^src\//,"");S.startsWith("features/")?(p=S.split("/")[1],c=Z.join("src","features",p,"services"),g=Z.join(r,c)):(c=Z.join("src",S),p=S.split("/")[0],g=Z.join(r,c))}else p=n.serviceName,c=Z.join("src","features",p,"services"),g=Z.join(r,c);xo(g)||await ho(g,{recursive:!0}),await ht(r,n.serviceName,c)&&(E(`Service '${n.serviceName}' already exists at ${c}!`),process.exit(1)),P.start("Generating service files..."),await xt({serviceName:n.serviceName,servicePath:g,httpClient:n.httpClient}),P.succeed("Service files generated"),P.start("Registering API endpoints..."),await ue({serviceName:n.serviceName,projectPath:r}),P.succeed("API endpoints registered");let C=Z.join(c,`${n.serviceName}.service.ts`);d(X.green(`
315
325
  \u2728 Service '${n.serviceName}' created successfully!
316
- `)),m(U.dim("Generated files:")),m(U.dim(` \u{1F4C4} ${P}
317
- `)),m(U.cyan("Next steps:"));let x=c.replace(/^src\//,"@/");m(U.dim(` 1. Import service: import { ${n.serviceName}Service } from '${x}/${n.serviceName}.service'`)),m(U.dim(` 2. Use in component: const data = await ${n.serviceName}Service.getAll()`)),m("")}catch(r){y.fail("Service generation failed"),E(`${r}`),process.exit(1)}})};import he from"picocolors";import Io from"enquirer";import ao from"node:path";import co from"picocolors";import se from"node:path";I();import mt from"node:path";I();var de=async e=>{let i=[mt.join(e,a.ROOT_LAYOUT),mt.join(e,"src/app/[locale]/layout.tsx")];for(let t of i)if(l(t)&&(await d(t)).includes("<body"))return t;for(let t of i)if(l(t))return t;return""};var dt=async e=>{let i=se.join(e,a.THEME_PROVIDER),t=se.join(e,a.GLOBALS_CSS),r=se.join(e,"package.json");if(l(i))return{isSetup:!0,reason:"CustomThemeProvider.tsx exists"};if(l(r)){let s=JSON.parse(await d(r));if(s.dependencies&&s.dependencies["next-themes"]||s.devDependencies&&s.devDependencies["next-themes"])return{isSetup:!0,reason:"next-themes 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:""}},ut=async e=>{let i=se.join(e,a.GLOBALS_CSS),t=se.join(e,a.PROVIDERS_INDEX),r=await de(e);if(!l(i)||!r||!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 r};import ft from"node:path";import so from"degit";I();var gt=async(e,i)=>{i.text="Fetching assets from starter repo...",await so("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},xt=async(e,i)=>{let t=ft.join(e,a.THEME_PROVIDER),r=ft.join(i,"src/providers/CustomThemeProvider.tsx");await $(r,t)};import ue from"node:path";I();var ht=async e=>{let i=ue.join(e,a.PROVIDERS_INDEX),t=await d(i);t.includes("CustomThemeProvider")||(t+=`export * from './CustomThemeProvider';
318
- `,await u(i,t))},yt=async e=>{let i=ue.join(e,"src/providers/RootProvider.tsx");if(l(i)){let t=await d(i),r="'use client';",s=t.includes(r);if(s&&(t=t.replace(r,"").trim()),t.includes("CustomThemeProvider")||(t=t.replace(/import \{ StoreProvider \} from '@\/providers';\n/,`import { StoreProvider, CustomThemeProvider } from '@/providers';
326
+ `)),d(X.dim("Generated files:")),d(X.dim(` \u{1F4C4} ${C}
327
+ `)),d(X.cyan("Next steps:"));let h=c.replace(/^src\//,"@/");d(X.dim(` 1. Import service: import { ${n.serviceName}Service } from '${h}/${n.serviceName}.service'`)),d(X.dim(` 2. Use in component: const data = await ${n.serviceName}Service.getAll()`)),d("")}catch(r){P.fail("Service generation failed"),E(`${r}`),process.exit(1)}})};import Pe from"picocolors";import bo from"enquirer";import So from"node:path";import Po from"picocolors";import ce from"node:path";I();import St from"node:path";I();var fe=async e=>{let i=[St.join(e,a.ROOT_LAYOUT),St.join(e,"src/app/[locale]/layout.tsx")];for(let t of i)if(l(t)&&(await m(t)).includes("<body"))return t;for(let t of i)if(l(t))return t;return""};var Pt=async e=>{let i=ce.join(e,a.THEME_PROVIDER),t=ce.join(e,a.GLOBALS_CSS),r=ce.join(e,"package.json");if(l(i))return{isSetup:!0,reason:"CustomThemeProvider.tsx exists"};if(l(r)){let s=JSON.parse(await m(r));if(s.dependencies&&s.dependencies["next-themes"]||s.devDependencies&&s.devDependencies["next-themes"])return{isSetup:!0,reason:"next-themes is installed"}}return l(t)&&(await m(t)).includes("@custom-variant dark")?{isSetup:!0,reason:"Dark theme CSS found in globals.css"}:{isSetup:!1,reason:""}},vt=async e=>{let i=ce.join(e,a.GLOBALS_CSS),t=ce.join(e,a.PROVIDERS_INDEX),r=await fe(e);if(!l(i)||!r||!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 r};import Ct from"node:path";import yo from"degit";I();var wt=async(e,i)=>{i.text="Fetching assets from starter repo...",await yo("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Tt=async(e,i)=>{let t=Ct.join(e,a.THEME_PROVIDER),r=Ct.join(i,"src/providers/CustomThemeProvider.tsx");await $(r,t)};import ge from"node:path";I();var Et=async e=>{let i=ge.join(e,a.PROVIDERS_INDEX),t=await m(i);t.includes("CustomThemeProvider")||(t+=`export * from './CustomThemeProvider';
328
+ `,await u(i,t))},It=async e=>{let i=ge.join(e,"src/providers/RootProvider.tsx");if(l(i)){let t=await m(i),r="'use client';",s=t.includes(r);if(s&&(t=t.replace(r,"").trim()),t.includes("CustomThemeProvider")||(t=t.replace(/import \{ StoreProvider \} from '@\/providers';\n/,`import { StoreProvider, CustomThemeProvider } from '@/providers';
319
329
  `),t.includes("CustomThemeProvider")||(t.includes("from '@/providers'")?t=t.replace(/\} from '@\/providers'/,", CustomThemeProvider } from '@/providers'"):t=`import { CustomThemeProvider } from '@/providers';
320
330
  `+t)),s&&(t=r+`
321
331
  `+t),!t.includes("<CustomThemeProvider>")){if(t.includes("<StoreProvider>"))t=t.replace(/<StoreProvider>/,`<StoreProvider>
@@ -324,7 +334,7 @@ Check: lib/utils/http/axios-client or lib/utils/http/fetch-client
324
334
  <CustomThemeProvider>
325
335
  ${n}
326
336
  </CustomThemeProvider>
327
- );`)}}await u(i,t)}}},Pt=async(e,i)=>{let t=ue.join(e,a.GLOBALS_CSS),r=ue.join(i,"src/styles/globals.css"),s="";if(l(r)){let n=await d(r),c=n.match(/@custom-variant dark \(.*?\);/),p=n.match(/@theme \{[\s\S]*?\}/);c&&(s+=`
337
+ );`)}}await u(i,t)}}},Rt=async(e,i)=>{let t=ge.join(e,a.GLOBALS_CSS),r=ge.join(i,"src/styles/globals.css"),s="";if(l(r)){let n=await m(r),c=n.match(/@custom-variant dark \(.*?\);/),p=n.match(/@theme \{[\s\S]*?\}/);c&&(s+=`
328
338
  ${c[0]}
329
339
  `),p&&(s+=`
330
340
  ${p[0]}
@@ -335,29 +345,29 @@ ${p[0]}
335
345
  --color-dark: #202938;
336
346
  --color-light: #f5f5f5;
337
347
  }
338
- `);let o=await d(t);if(!o.includes("@custom-variant dark")){if(o.includes("@import")){let n=o.lastIndexOf("@import"),c=o.indexOf(`
339
- `,n);o=o.slice(0,c+1)+s+o.slice(c+1)}else o=s+o;await u(t,o)}},St=async e=>{let i=await d(e);i.includes("dark:bg-dark")||(i=i.replace(/className="([^"]*)"/,'className="$1 bg-light dark:bg-dark"'),await u(e,i))};var Ee=async e=>{let i=O("Setting up Dark Theme..."),t=ao.join(e,".next-maker-temp");try{let{isSetup:r,reason:s}=await dt(e);if(r){i.fail(`Dark Theme is already set up (${s}).`);return}let o=await ut(e);await gt(t,i),await xt(e,t),await ht(e),await yt(e),await Pt(e,t),await St(o),i.text="Installing next-themes...",await D(e,"next-themes"),i.text="Formatting code...";let n=await G(e);await L(e,n,"format"),i.succeed(co.green("Dark Theme setup successfully!"))}catch(r){throw i.fail("Failed to setup Dark Theme."),r}finally{await h(t)}};import po from"node:path";import mo from"picocolors";import Ie from"node:path";I();var vt=async e=>{let i=Ie.join(e,a.STORE),t=Ie.join(e,"package.json");if(l(i))return{isSetup:!0,reason:"src/store directory exists"};if(l(t)){let r=JSON.parse(await d(t));if(r.dependencies&&r.dependencies["@reduxjs/toolkit"]||r.devDependencies&&r.devDependencies["@reduxjs/toolkit"])return{isSetup:!0,reason:"@reduxjs/toolkit is installed"}}return{isSetup:!1,reason:""}},Ct=async e=>{let i=Ie.join(e,a.PROVIDERS_INDEX);if(!await de(e)||!l(i))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx (or src/app/[locale]/layout.tsx) and src/providers/index.ts exist.")};import q from"node:path";import lo from"degit";I();import wt from"node:fs/promises";var Tt=async(e,i)=>{i.text="Fetching assets from starter repo...",await lo("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Et=async(e,i)=>{let t=q.join(i,"src/providers/StoreProvider.tsx"),r=q.join(e,a.STORE_PROVIDER);await $(t,r);let s=q.join(i,"src/store"),o=q.join(e,a.STORE);await wt.cp(s,o,{recursive:!0})},It=async(e,i)=>{let t=q.join(i,"src/features/counter"),r=q.join(e,a.COUNTER_FEATURE);await wt.cp(t,r,{recursive:!0});let s=q.join(r,"components/Counter.tsx");if(await l(s)){let o=await d(s);o=o.replace(/import \{ useTranslations \} from 'next-intl';\n?/,""),o=o.replace(/const t = useTranslations\('Count'\);\n?/,""),o=o.replace(/\{t\('currentCount', \{ count: value \}\)\}/g,"Current Count: {value}"),o=o.replace(/\{t\('increment'\)\}/g,"Increment"),o=o.replace(/\{t\('decrement'\)\}/g,"Decrement"),o=o.replace(/\{t\('reset'\)\}/g,"Reset"),await u(s,o)}};import fe from"node:path";I();var Rt=async e=>{let i=fe.join(e,a.PROVIDERS_INDEX),t=await d(i);t.includes("StoreProvider")||(t+=`export * from './StoreProvider';
340
- `,await u(i,t))},Nt=async e=>{let i=fe.join(e,"src/providers/RootProvider.tsx");if(l(i)){let t=await d(i),r="'use client';",s=t.includes(r);if(s&&(t=t.replace(r,"").trim()),t.includes("StoreProvider")||(t=t.replace(/import \{ (.*?) \} from '@\/providers';/,"import { $1, StoreProvider } from '@/providers';"),t.includes("StoreProvider")||(t.includes("from '@/providers'")?t=t.replace(/\} from '@\/providers'/,", StoreProvider } from '@/providers'"):t=`import { StoreProvider } from '@/providers';
348
+ `);let o=await m(t);if(!o.includes("@custom-variant dark")){if(o.includes("@import")){let n=o.lastIndexOf("@import"),c=o.indexOf(`
349
+ `,n);o=o.slice(0,c+1)+s+o.slice(c+1)}else o=s+o;await u(t,o)}},Nt=async e=>{let i=await m(e);i.includes("dark:bg-dark")||(i=i.replace(/className="([^"]*)"/,'className="$1 bg-light dark:bg-dark"'),await u(e,i))};var Ne=async e=>{let i=O("Setting up Dark Theme..."),t=So.join(e,".next-maker-temp");try{let{isSetup:r,reason:s}=await Pt(e);if(r){i.fail(`Dark Theme is already set up (${s}).`);return}let o=await vt(e);await wt(t,i),await Tt(e,t),await Et(e),await It(e),await Rt(e,t),await Nt(o),i.text="Installing next-themes...",await D(e,"next-themes"),i.text="Formatting code...";let n=await H(e);await L(e,n,"format"),i.succeed(Po.green("Dark Theme setup successfully!"))}catch(r){throw i.fail("Failed to setup Dark Theme."),r}finally{await x(t)}};import Co from"node:path";import wo from"picocolors";import Oe from"node:path";I();var Ot=async e=>{let i=Oe.join(e,a.STORE),t=Oe.join(e,"package.json");if(l(i))return{isSetup:!0,reason:"src/store directory exists"};if(l(t)){let r=JSON.parse(await m(t));if(r.dependencies&&r.dependencies["@reduxjs/toolkit"]||r.devDependencies&&r.devDependencies["@reduxjs/toolkit"])return{isSetup:!0,reason:"@reduxjs/toolkit is installed"}}return{isSetup:!1,reason:""}},At=async e=>{let i=Oe.join(e,a.PROVIDERS_INDEX);if(!await fe(e)||!l(i))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx (or src/app/[locale]/layout.tsx) and src/providers/index.ts exist.")};import Q from"node:path";import vo from"degit";I();import $t from"node:fs/promises";var bt=async(e,i)=>{i.text="Fetching assets from starter repo...",await vo("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},_t=async(e,i)=>{let t=Q.join(i,"src/providers/StoreProvider.tsx"),r=Q.join(e,a.STORE_PROVIDER);await $(t,r);let s=Q.join(i,"src/store"),o=Q.join(e,a.STORE);await $t.cp(s,o,{recursive:!0})},jt=async(e,i)=>{let t=Q.join(i,"src/features/counter"),r=Q.join(e,a.COUNTER_FEATURE);await $t.cp(t,r,{recursive:!0});let s=Q.join(r,"components/Counter.tsx");if(await l(s)){let o=await m(s);o=o.replace(/import \{ useTranslations \} from 'next-intl';\n?/,""),o=o.replace(/const t = useTranslations\('Count'\);\n?/,""),o=o.replace(/\{t\('currentCount', \{ count: value \}\)\}/g,"Current Count: {value}"),o=o.replace(/\{t\('increment'\)\}/g,"Increment"),o=o.replace(/\{t\('decrement'\)\}/g,"Decrement"),o=o.replace(/\{t\('reset'\)\}/g,"Reset"),await u(s,o)}};import xe from"node:path";I();var Ft=async e=>{let i=xe.join(e,a.PROVIDERS_INDEX),t=await m(i);t.includes("StoreProvider")||(t+=`export * from './StoreProvider';
350
+ `,await u(i,t))},kt=async e=>{let i=xe.join(e,"src/providers/RootProvider.tsx");if(l(i)){let t=await m(i),r="'use client';",s=t.includes(r);if(s&&(t=t.replace(r,"").trim()),t.includes("StoreProvider")||(t=t.replace(/import \{ (.*?) \} from '@\/providers';/,"import { $1, StoreProvider } from '@/providers';"),t.includes("StoreProvider")||(t.includes("from '@/providers'")?t=t.replace(/\} from '@\/providers'/,", StoreProvider } from '@/providers'"):t=`import { StoreProvider } from '@/providers';
341
351
  `+t)),s&&(t=r+`
342
352
  `+t),!t.includes("<StoreProvider>")){let o=t.match(/return\s*(?:\(\s*)?([\s\S]*?)(?:\s*\))?;/);if(o){let n=o[1];t=t.replace(o[0],`return (
343
353
  <StoreProvider>
344
354
  ${n}
345
355
  </StoreProvider>
346
- );`),await u(i,t)}}}},Ot=async e=>{let i=[fe.join(e,a.ROOT_PAGE),fe.join(e,"src/app/[locale]/page.tsx")],t="";for(let r of i)if(l(r)){t=r;break}if(t){let r=await d(t);if(r.includes("Counter")||(r=`import { Counter } from '@/features/counter/components/Counter';
356
+ );`),await u(i,t)}}}},Dt=async e=>{let i=[xe.join(e,a.ROOT_PAGE),xe.join(e,"src/app/[locale]/page.tsx")],t="";for(let r of i)if(l(r)){t=r;break}if(t){let r=await m(t);if(r.includes("Counter")||(r=`import { Counter } from '@/features/counter/components/Counter';
347
357
  `+r),!r.includes("<Counter />")){let s=r.lastIndexOf("</div>"),o=r.lastIndexOf("</main>"),n=o!==-1?o:s;n!==-1&&(r=r.slice(0,n)+`
348
358
  <div className="mt-8">
349
359
  <h2 className="text-2xl font-bold mb-4">Redux Counter</h2>
350
360
  <Counter />
351
361
  </div>
352
- `+r.slice(n),await u(t,r))}}};var Re=async e=>{let i=O("Setting up Redux Toolkit..."),t=po.join(e,".next-maker-temp-redux");try{let{isSetup:r,reason:s}=await vt(e);if(r){i.fail(`Redux is already set up (${s}).`);return}await Ct(e),await Tt(t,i),i.text="Copying Redux files...",await Et(e,t),i.text="Creating Counter feature...",await It(e,t),i.text="Updating providers and pages...",await Rt(e),await Nt(e),await Ot(e),i.text="Installing dependencies...",await D(e,"@reduxjs/toolkit"),await D(e,"react-redux"),await D(e,"redux-persist"),await D(e,"react-secure-storage"),i.text="Formatting code...";let o=await G(e);await L(e,o,"format"),i.succeed(mo.green("Redux Toolkit setup successfully!"))}catch(r){throw i.fail("Failed to setup Redux Toolkit."),r}finally{await h(t)}};import xo from"node:path";import ho from"picocolors";import ge from"node:path";I();var At=async e=>{let i=ge.join(e,a.I18N_DIR),t=ge.join(e,"package.json");if(l(i))return{isSetup:!0,reason:"src/i18n directory exists"};if(l(t)){let r=JSON.parse(await d(t));if(r.dependencies&&r.dependencies["next-intl"]||r.devDependencies&&r.devDependencies["next-intl"])return{isSetup:!0,reason:"next-intl is installed"}}return{isSetup:!1,reason:""}},$t=async e=>{let i=ge.join(e,a.ROOT_LAYOUT),t=ge.join(e,"src/app/[locale]/layout.tsx");if(!l(i)&&!l(t))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx exists.")};import W from"node:path";import uo from"degit";I();import fo from"node:fs/promises";var bt=async(e,i)=>{i.text="Fetching assets from starter repo...",await uo("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},_t=async(e,i)=>{let t=W.join(i,"src/i18n"),r=W.join(e,a.I18N_DIR);await fo.cp(t,r,{recursive:!0});let s=W.join(i,"src/proxy.ts"),o=W.join(e,a.PROXY);await $(s,o);let n=W.join(i,"src/types/i18n.ts"),c=W.join(e,a.I18N_TYPES);await $(n,c);let p=W.join(i,"src/lib/config/app-locales.ts"),g=W.join(e,a.APP_LOCALES);await $(p,g)};import X from"node:path";I();import go from"node:fs/promises";var jt=async e=>{let i=X.join(e,a.NEXT_CONFIG);if(l(i)){let t=await d(i);if(!t.includes("createNextIntlPlugin")){t=`import createNextIntlPlugin from 'next-intl/plugin';
362
+ `+r.slice(n),await u(t,r))}}};var Ae=async e=>{let i=O("Setting up Redux Toolkit..."),t=Co.join(e,".next-maker-temp-redux");try{let{isSetup:r,reason:s}=await Ot(e);if(r){i.fail(`Redux is already set up (${s}).`);return}await At(e),await bt(t,i),i.text="Copying Redux files...",await _t(e,t),i.text="Creating Counter feature...",await jt(e,t),i.text="Updating providers and pages...",await Ft(e),await kt(e),await Dt(e),i.text="Installing dependencies...",await D(e,"@reduxjs/toolkit"),await D(e,"react-redux"),await D(e,"redux-persist"),await D(e,"react-secure-storage"),i.text="Formatting code...";let o=await H(e);await L(e,o,"format"),i.succeed(wo.green("Redux Toolkit setup successfully!"))}catch(r){throw i.fail("Failed to setup Redux Toolkit."),r}finally{await x(t)}};import Ro from"node:path";import No from"picocolors";import he from"node:path";I();var Lt=async e=>{let i=he.join(e,a.I18N_DIR),t=he.join(e,"package.json");if(l(i))return{isSetup:!0,reason:"src/i18n directory exists"};if(l(t)){let r=JSON.parse(await m(t));if(r.dependencies&&r.dependencies["next-intl"]||r.devDependencies&&r.devDependencies["next-intl"])return{isSetup:!0,reason:"next-intl is installed"}}return{isSetup:!1,reason:""}},Mt=async e=>{let i=he.join(e,a.ROOT_LAYOUT),t=he.join(e,"src/app/[locale]/layout.tsx");if(!l(i)&&!l(t))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx exists.")};import B from"node:path";import To from"degit";I();import Eo from"node:fs/promises";var Ht=async(e,i)=>{i.text="Fetching assets from starter repo...",await To("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Gt=async(e,i)=>{let t=B.join(i,"src/i18n"),r=B.join(e,a.I18N_DIR);await Eo.cp(t,r,{recursive:!0});let s=B.join(i,"src/proxy.ts"),o=B.join(e,a.PROXY);await $(s,o);let n=B.join(i,"src/types/i18n.ts"),c=B.join(e,a.I18N_TYPES);await $(n,c);let p=B.join(i,"src/lib/config/app-locales.ts"),g=B.join(e,a.APP_LOCALES);await $(p,g)};import Y from"node:path";I();import Io from"node:fs/promises";var Ut=async e=>{let i=Y.join(e,a.NEXT_CONFIG);if(l(i)){let t=await m(i);if(!t.includes("createNextIntlPlugin")){t=`import createNextIntlPlugin from 'next-intl/plugin';
353
363
  `+t;let r=/export default (.*?);/;r.test(t)?t=t.replace(r,`
354
364
  const withNextIntl = createNextIntlPlugin();
355
365
  export default withNextIntl($1);`):(t+=`
356
366
  const withNextIntl = createNextIntlPlugin();
357
367
  `,t+=`export default withNextIntl(nextConfig);
358
- `),await u(i,t)}}},Ft=async e=>{let i=X.join(e,a.TYPES_INDEX);if(l(i)){let t=await d(i);t.includes("./i18n")||(t+=`export * from './i18n';
359
- `,await u(i,t))}},kt=async e=>{let i=X.join(e,a.CONFIG_INDEX);if(l(i)){let t=await d(i);t.includes("./app-locales")||(t+=`export * from './app-locales';
360
- `,await u(i,t))}},Dt=async e=>{let i=X.join(e,"src/providers/RootProvider.tsx");if(l(i)){let t=await d(i),r="'use client';",s=t.includes(r);if(s&&(t=t.replace(r,"").trim()),t.includes("next-intl")||(t=`import { SupportedLocale } from '@/types/i18n';
368
+ `),await u(i,t)}}},Xt=async e=>{let i=Y.join(e,a.TYPES_INDEX);if(l(i)){let t=await m(i);t.includes("./i18n")||(t+=`export * from './i18n';
369
+ `,await u(i,t))}},Yt=async e=>{let i=Y.join(e,a.CONFIG_INDEX);if(l(i)){let t=await m(i);t.includes("./app-locales")||(t+=`export * from './app-locales';
370
+ `,await u(i,t))}},Jt=async e=>{let i=Y.join(e,"src/providers/RootProvider.tsx");if(l(i)){let t=await m(i),r="'use client';",s=t.includes(r);if(s&&(t=t.replace(r,"").trim()),t.includes("next-intl")||(t=`import { SupportedLocale } from '@/types/i18n';
361
371
  import { NextIntlClientProvider, AbstractIntlMessages } from 'next-intl';
362
372
  `+t),s&&(t=r+`
363
373
  `+t),!t.includes("locale: SupportedLocale")){let o=/export const RootProvider = \(\{([\s\S]*?)\}: \{([\s\S]*?)\}\) => \{/,n=t.match(o);n&&(t=t.replace(n[0],`export const RootProvider = ({
@@ -376,7 +386,7 @@ import { NextIntlClientProvider, AbstractIntlMessages } from 'next-intl';
376
386
  <NextIntlClientProvider locale={locale} messages={messages}>
377
387
  ${n}
378
388
  </NextIntlClientProvider>
379
- );`)}}await u(i,t)}},Lt=async e=>{let i=X.join(e,a.ROOT_LAYOUT),t=X.join(e,a.ROOT_PAGE),r=X.join(e,"src/app/[locale]");if(await go.mkdir(r,{recursive:!0}),l(i)){let s=X.join(r,"layout.tsx"),o=await d(i);if(o.includes("next-intl")||(o=`import { routing } from '@/i18n/routing';
389
+ );`)}}await u(i,t)}},zt=async e=>{let i=Y.join(e,a.ROOT_LAYOUT),t=Y.join(e,a.ROOT_PAGE),r=Y.join(e,"src/app/[locale]");if(await Io.mkdir(r,{recursive:!0}),l(i)){let s=Y.join(r,"layout.tsx"),o=await m(i);if(o.includes("next-intl")||(o=`import { routing } from '@/i18n/routing';
380
390
  import { hasLocale } from 'next-intl';
381
391
  import { notFound } from 'next/navigation';
382
392
  import { setRequestLocale, getMessages } from 'next-intl/server';
@@ -387,7 +397,7 @@ export function generateStaticParams() {
387
397
  }`+o.slice(g)}}o=o.replace(/Readonly<\{\s*children:\s*React\.ReactNode;\s*}>/,`Readonly<{
388
398
  children: React.ReactNode;
389
399
  params: Promise<{ locale: string }>;
390
- }>`);let n=/export default (async )?function RootLayout\(\{\s*children,?\s*\}\s*:/,c=o.match(n);if(c){c[1]||(o=o.replace("export default function","export default async function")),o=o.replace(/export default (async )?function RootLayout\(\{\s*children,?\s*\}\s*:/,"export default async function RootLayout({ children, params }:");let g=/export default async function RootLayout[\s\S]*?\)\s*\{/,S=o.match(g);if(S&&S.index!==void 0){let P=S.index+S[0].length-1;o=o.slice(0,P+1)+`
400
+ }>`);let n=/export default (async )?function RootLayout\(\{\s*children,?\s*\}\s*:/,c=o.match(n);if(c){c[1]||(o=o.replace("export default function","export default async function")),o=o.replace(/export default (async )?function RootLayout\(\{\s*children,?\s*\}\s*:/,"export default async function RootLayout({ children, params }:");let g=/export default async function RootLayout[\s\S]*?\)\s*\{/,v=o.match(g);if(v&&v.index!==void 0){let C=v.index+v[0].length-1;o=o.slice(0,C+1)+`
391
401
  const { locale } = await params;
392
402
 
393
403
  if (!hasLocale(routing.locales, locale)) {
@@ -397,7 +407,7 @@ export function generateStaticParams() {
397
407
  setRequestLocale(locale);
398
408
 
399
409
  const messages = await getMessages();
400
- `+o.slice(P+1)}o=o.replace(/<RootProvider>/,"<RootProvider locale={locale} messages={messages}>"),o=o.replace(/<html lang="en"/,"<html lang={locale}")}await u(s,o),await v(i)}if(l(t)){let s=X.join(r,"page.tsx"),o=await d(t);o.includes("next-intl")||(o=`import { SupportedLocale } from '@/types/i18n';
410
+ `+o.slice(C+1)}o=o.replace(/<RootProvider>/,"<RootProvider locale={locale} messages={messages}>"),o=o.replace(/<html lang="en"/,"<html lang={locale}")}await u(s,o),await w(i)}if(l(t)){let s=Y.join(r,"page.tsx"),o=await m(t);o.includes("next-intl")||(o=`import { SupportedLocale } from '@/types/i18n';
401
411
  import { setRequestLocale } from 'next-intl/server';
402
412
  `+o),o=o.replace(/export default function Home\(\)/,`type Props = {
403
413
  params: Promise<{ locale: string }>;
@@ -406,17 +416,10 @@ import { setRequestLocale } from 'next-intl/server';
406
416
  export default async function Home(props: Props)`);let n=o.indexOf("export default async function Home(props: Props) {");if(n!==-1){let c=`
407
417
  const locale = (await props.params).locale as SupportedLocale;
408
418
  setRequestLocale(locale);
409
- `,p=o.indexOf("{",n);o=o.slice(0,p+1)+c+o.slice(p+1)}await u(s,o),await v(t)}};var Ne=async e=>{let i=O("Setting up Internationalization (next-intl)..."),t=xo.join(e,".next-maker-temp-i18n");try{let{isSetup:r,reason:s}=await At(e);if(r){i.fail(`i18n is already set up (${s}).`);return}await $t(e),await bt(t,i),i.text="Copying i18n files...",await _t(e,t),i.text="Configuring project structure...",await jt(e),await Ft(e),await kt(e),await Dt(e),i.text="Migrating to [locale] structure...",await Lt(e),i.text="Installing dependencies...",await D(e,"next-intl"),i.text="Formatting code...";let o=await G(e);await L(e,o,"format"),i.succeed(ho.green("Internationalization setup successfully!"))}catch(r){throw i.fail("Failed to setup Internationalization."),r}finally{await h(t)}};import Oe from"node:path";import Co from"node:fs/promises";import Ae from"picocolors";import xe from"enquirer";import ae from"node:path";I();var Mt=async e=>{let i=ae.join(e,a.FETCH_CLIENT_FILE),t=ae.join(e,a.AXIOS_CLIENT_FILE),r=l(i),s=l(t);return r&&s?{status:"both",reason:"Both Fetch and Axios clients are detected"}:r?{status:"fetch",reason:"Fetch client is already setup"}:s?{status:"axios",reason:"Axios client is already setup"}:{status:"none"}},Gt=async e=>{let t=[ae.join(e,"src/lib"),ae.join(e,"src/types"),ae.join(e,"src/lib/config")].filter(r=>!l(r));if(t.length>0)throw new Error(`Invalid project structure. Missing directories:
419
+ `,p=o.indexOf("{",n);o=o.slice(0,p+1)+c+o.slice(p+1)}await u(s,o),await w(t)}};var $e=async e=>{let i=O("Setting up Internationalization (next-intl)..."),t=Ro.join(e,".next-maker-temp-i18n");try{let{isSetup:r,reason:s}=await Lt(e);if(r){i.fail(`i18n is already set up (${s}).`);return}await Mt(e),await Ht(t,i),i.text="Copying i18n files...",await Gt(e,t),i.text="Configuring project structure...",await Ut(e),await Xt(e),await Yt(e),await Jt(e),i.text="Migrating to [locale] structure...",await zt(e),i.text="Installing dependencies...",await D(e,"next-intl"),i.text="Formatting code...";let o=await H(e);await L(e,o,"format"),i.succeed(No.green("Internationalization setup successfully!"))}catch(r){throw i.fail("Failed to setup Internationalization."),r}finally{await x(t)}};import ye from"node:path";import Zt from"node:fs/promises";import be from"picocolors";import Se from"enquirer";import le from"node:path";I();var Wt=async e=>{let i=le.join(e,a.FETCH_CLIENT_FILE),t=le.join(e,a.AXIOS_CLIENT_FILE),r=l(i),s=l(t);return r&&s?{status:"both",reason:"Both Fetch and Axios clients are detected"}:r?{status:"fetch",reason:"Fetch client is already setup"}:s?{status:"axios",reason:"Axios client is already setup"}:{status:"none"}},Vt=async e=>{let t=[le.join(e,"src/lib"),le.join(e,"src/types"),le.join(e,"src/lib/config")].filter(r=>!l(r));if(t.length>0)throw new Error(`Invalid project structure. Missing directories:
410
420
  ${t.map(r=>`- ${r}`).join(`
411
- `)}`)};import C from"node:path";import yo from"degit";I();import ee from"node:fs/promises";var Ht=async(e,i)=>{i.text="Downloading assets from starter repository...",await yo("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Ut=async(e,i,t,r)=>{let s=C.join(e,a.HTTP_UTILS),o=C.join(i,a.HTTP_UTILS);await ee.cp(C.join(i,a.ERRORS_DIR),C.join(e,a.ERRORS_DIR),{recursive:!0}),await $(C.join(i,a.APP_APIS),C.join(e,a.APP_APIS)),await $(C.join(i,a.CONSTANTS),C.join(e,a.CONSTANTS));let n=C.join(e,a.STORAGE_SERVICE);if(l(n)||await ee.cp(C.join(i,a.STORAGE_SERVICE),n,{recursive:!0}),await ee.cp(C.join(i,a.COMMON_TYPES_DIR),C.join(e,a.COMMON_TYPES_DIR),{recursive:!0}),await ee.cp(C.join(i,a.UTILITY_TYPES_DIR),C.join(e,a.UTILITY_TYPES_DIR),{recursive:!0}),await $(C.join(o,"token-store.ts"),C.join(s,"token-store.ts")),await $(C.join(o,"client-utils.ts"),C.join(s,"client-utils.ts")),r&&r.length>0)for(let c of r){let p=C.join(e,c==="fetch"?a.FETCH_CLIENT:a.AXIOS_CLIENT);await h(p)}for(let c of t)c==="fetch"?await ee.cp(C.join(i,a.FETCH_CLIENT),C.join(e,a.FETCH_CLIENT),{recursive:!0}):await ee.cp(C.join(i,a.AXIOS_CLIENT),C.join(e,a.AXIOS_CLIENT),{recursive:!0});await $(C.join(o,"index.ts"),C.join(s,"index.ts")),await $(C.join(i,a.HTTP_TYPES),C.join(e,a.HTTP_TYPES))};import ce from"node:path";I();import{exec as Po}from"node:child_process";import{promisify as So}from"node:util";var vo=So(Po),Xt=async(e,i)=>{let t=ce.join(e,a.HTTP_UTILS,"index.ts");if(l(t)){let r=await d(t);r=r.replace(/export .* from '\.\/axios-client';?\n?/g,""),r=r.replace(/export .* from '\.\/fetch-client';?\n?/g,""),i.includes("fetch")&&!r.includes("fetch-client")&&(r+=`export * from './fetch-client';
412
- `),i.includes("axios")&&!r.includes("axios-client")&&(r+=`export * from './axios-client';
413
- `),await u(t,r)}},Jt=async e=>{let i=ce.join(e,a.UTILS_INDEX);if(l(i)){let t=await d(i);t.includes("./http")||(t+=`export * from './http';
414
- `,await u(i,t))}},Yt=async e=>{let i=ce.join(e,a.TYPES_INDEX);if(l(i)){let t=await d(i);t.includes("./common")||(t+=`export * from './common';
415
- `),t.includes("./utility")||(t+=`export * from './utility';
416
- `),await u(i,t)}},zt=async e=>{let i=ce.join(e,a.CONFIG_INDEX);if(l(i)){let t=await d(i);t.includes("./app-apis")||(t+=`export * from './app-apis';
417
- `,await u(i,t))}},Wt=async(e,i,t)=>{if(i===t)return;let r=i==="fetch"?"fetchClient":"axiosClient",s=t==="fetch"?"fetchClient":"axiosClient",o=i==="fetch"?"fetch-client":"axios-client",n=t==="fetch"?"fetch-client":"axios-client",c=ce.join(e,"src");try{let p=`grep -rl "${r}" "${c}" --include="*.ts" --include="*.tsx" || true`,{stdout:g}=await vo(p);if(!g.trim())return;let S=g.trim().split(`
418
- `).filter(P=>P);for(let P of S){if(!l(P))continue;let x=await d(P),w=!1,F=new RegExp(`(import\\s*\\{[^}]*?)\\b${r}\\b([^}]*?\\}\\s*from\\s*['"][^'"]*?/http['"])`,"g");F.test(x)&&(x=x.replace(F,`$1${s}$2`),w=!0);let R=new RegExp(`import\\s+${r}\\s+from\\s+['"]([^'"]*?)/${o}['"]`,"g");R.test(x)&&(x=x.replace(R,`import ${s} from '$1/${n}'`),w=!0);let k=new RegExp(`\\b${r}\\b(?=\\.)`,"g");k.test(x)&&(x=x.replace(k,s),w=!0);let Z=new RegExp(`\\b${r}\\b(?![.\\w])`,"g");Z.test(x)&&(x=x.replace(Z,s),w=!0),w&&await u(P,x)}}catch(p){console.warn("Warning: Could not scan for HTTP client usages:",p)}};var $e=async e=>{let i=O("Checking HTTP Client setup..."),t=Oe.join(e,".next-maker-temp-http");try{let{status:r,reason:s}=await Mt(e);i.stop();let o=await wo(r,s);if(o.type==="cancel"){console.log(Ae.yellow("Setup cancelled."));return}if(i.start("Setting up HTTP client(s)..."),await Gt(e),await Ht(t,i),o.type==="replace"&&o.fromClient&&(i.text="Migrating client usages...",await Wt(e,o.fromClient,o.clients[0])),o.type!=="remove-both"&&o.type!=="remove-one"){i.text="Copying client files...";let S=o.type==="replace"&&o.fromClient?[o.fromClient]:void 0;await Ut(e,t,o.clients,S)}if(o.type==="remove-one"||o.type==="remove-both"){i.text="Removing client files...";let{PROJECT_PATHS:S}=await Promise.resolve().then(()=>(I(),Me));for(let P of o.clients){let x=Oe.join(e,P==="fetch"?S.FETCH_CLIENT:S.AXIOS_CLIENT);await h(x)}}if(o.type!=="remove-both"){i.text="Configuring client...";let S=To(r,o);await Xt(e,S),await Jt(e),await Yt(e),await zt(e)}o.clients.includes("axios")&&(o.type==="install"||o.type==="add")&&(i.text="Installing Axios...",await D(e,"axios"));let n=Oe.join(e,"package.json"),c=JSON.parse(await Co.readFile(n,"utf-8"));!(c.dependencies?.["react-secure-storage"]||c.devDependencies?.["react-secure-storage"])&&o.type!=="remove-both"&&(i.text="Installing react-secure-storage (for token storage)...",await D(e,"react-secure-storage")),i.text="Formatting code...";let g=await G(e);await L(e,g,"format"),i.succeed(Ae.green(Eo(o)))}catch(r){throw i.fail("Failed to setup HTTP Client."),r}finally{await h(t)}};async function wo(e,i){if(e==="none"){let{choice:r}=await xe.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 r==="both"?{type:"install",clients:["fetch","axios"]}:{type:"install",clients:[r]}}if(e==="fetch"){let{action:r}=await xe.prompt({type:"select",name:"action",message:`${i}. 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(r==="cancel")return{type:"cancel",clients:[]};if(r==="add")return{type:"add",clients:["axios"]};if(r==="replace")return{type:"replace",clients:["axios"],fromClient:"fetch"};if(r==="remove")return{type:"remove-one",clients:["fetch"]}}if(e==="axios"){let{action:r}=await xe.prompt({type:"select",name:"action",message:`${i}. 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(r==="cancel")return{type:"cancel",clients:[]};if(r==="add")return{type:"add",clients:["fetch"]};if(r==="replace")return{type:"replace",clients:["fetch"],fromClient:"axios"};if(r==="remove")return{type:"remove-one",clients:["axios"]}}console.log(Ae.yellow(`\u2716 ${i}`));let{action:t}=await xe.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 To(e,i){return i.type==="install"?i.clients:i.type==="add"?[...e==="fetch"?["fetch"]:["axios"],...i.clients]:i.type==="replace"?i.clients:i.type==="remove-one"?e==="both"?i.clients[0]==="fetch"?["axios"]:["fetch"]:[]:[]}function Eo(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 i=e.fromClient==="fetch"?"Fetch":"Axios",t=e.clients[0]==="fetch"?"Fetch":"Axios";return`Replaced ${i} 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{prompt:Ro}=Io,Vt=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 + next-themes)").option("--redux","Setup Redux Toolkit").option("--i18n","Setup next-intl for internationalization").action(async i=>{try{if(m(he.cyan(`
421
+ `)}`)};import y from"node:path";import Oo from"degit";I();import J from"node:fs/promises";var Bt=async(e,i)=>{i.text="Downloading assets from starter repository...",await Oo("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(e)},Kt=async(e,i,t,r)=>{let s=y.join(e,a.HTTP_UTILS),o=y.join(i,a.HTTP_UTILS);await J.cp(y.join(i,a.ERRORS_DIR),y.join(e,a.ERRORS_DIR),{recursive:!0}),await $(y.join(i,a.APP_APIS),y.join(e,a.APP_APIS)),await $(y.join(i,a.CONSTANTS),y.join(e,a.CONSTANTS));let n=y.join(e,a.STORAGE_SERVICE);if(l(n)||await J.cp(y.join(i,a.STORAGE_SERVICE),n,{recursive:!0}),await J.cp(y.join(i,a.COMMON_TYPES_DIR),y.join(e,a.COMMON_TYPES_DIR),{recursive:!0}),await J.cp(y.join(i,a.UTILITY_TYPES_DIR),y.join(e,a.UTILITY_TYPES_DIR),{recursive:!0}),await $(y.join(o,"token-store.ts"),y.join(s,"token-store.ts")),await $(y.join(o,"client-utils.ts"),y.join(s,"client-utils.ts")),r&&r.length>0)for(let c of r){let p=y.join(e,c==="fetch"?a.FETCH_CLIENT:a.AXIOS_CLIENT);await x(p)}for(let c of t)c==="fetch"?await J.cp(y.join(i,a.FETCH_CLIENT),y.join(e,a.FETCH_CLIENT),{recursive:!0}):await J.cp(y.join(i,a.AXIOS_CLIENT),y.join(e,a.AXIOS_CLIENT),{recursive:!0});await $(y.join(o,"index.ts"),y.join(s,"index.ts")),await $(y.join(i,a.HTTP_TYPES),y.join(e,a.HTTP_TYPES))},qt=async e=>{await x(y.join(e,a.HTTP_UTILS)),await x(y.join(e,a.STORAGE_SERVICE)),await x(y.join(e,a.ERRORS_DIR));let i=[a.HTTP_TYPES,a.APP_APIS,a.CONSTANTS];for(let s of i){let o=y.join(e,s);l(o)&&await J.unlink(o)}let t=y.join(e,a.COMMON_TYPES_DIR);l(t)&&(await J.readdir(t)).length===0&&await x(t);let r=y.join(e,a.UTILITY_TYPES_DIR);l(r)&&(await J.readdir(r)).length===0&&await x(r)};var _e=async e=>{let i=O("Checking HTTP Client setup..."),t=ye.join(e,".next-maker-temp-http");try{let{status:r,reason:s}=await Wt(e);i.stop();let o=await Ao(r,s);if(o.type==="cancel"){console.log(be.yellow("Setup cancelled."));return}if(i.start("Setting up HTTP client(s)..."),await Vt(e),await Bt(t,i),o.type==="replace"&&o.fromClient&&(i.text="Migrating client usages...",await We(e,o.fromClient,o.clients[0])),o.type!=="remove-both"&&o.type!=="remove-one"){i.text="Copying client files...";let v=o.type==="replace"&&o.fromClient?[o.fromClient]:void 0;await Kt(e,t,o.clients,v)}if(o.type==="remove-one"||o.type==="remove-both"){i.text="Removing client files...";let{PROJECT_PATHS:v}=await Promise.resolve().then(()=>(I(),Ge));for(let h of o.clients){let S=ye.join(e,h==="fetch"?v.FETCH_CLIENT:v.AXIOS_CLIENT);await x(S)}if(Qt(r,o).length===0){i.text="Performing full cleanup...",await qt(e),await Ve(e),i.text="Uninstalling dependencies...";let h=ye.join(e,"package.json"),S=JSON.parse(await Zt.readFile(h,"utf-8"));(S.dependencies?.axios||S.devDependencies?.axios)&&await Ce(e,"axios"),(S.dependencies?.["react-secure-storage"]||S.devDependencies?.["react-secure-storage"])&&await Ce(e,"react-secure-storage")}}if(o.type!=="remove-both"){i.text="Configuring client...";let v=Qt(r,o);await Xe(e,v),await Ye(e),await Je(e),await ze(e),await oe(e,v)}o.clients.includes("axios")&&(o.type==="install"||o.type==="add")&&(i.text="Installing Axios...",await D(e,"axios"));let n=ye.join(e,"package.json"),c=JSON.parse(await Zt.readFile(n,"utf-8"));!(c.dependencies?.["react-secure-storage"]||c.devDependencies?.["react-secure-storage"])&&o.type!=="remove-both"&&(i.text="Installing react-secure-storage (for token storage)...",await D(e,"react-secure-storage")),i.text="Formatting code...";let g=await H(e);await L(e,g,"format"),i.succeed(be.green($o(o)))}catch(r){throw i.fail("Failed to setup HTTP Client."),r}finally{await x(t)}};async function Ao(e,i){if(e==="none"){let{choice:r}=await Se.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 r==="both"?{type:"install",clients:["fetch","axios"]}:{type:"install",clients:[r]}}if(e==="fetch"){let{action:r}=await Se.prompt({type:"select",name:"action",message:`${i}. 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(r==="cancel")return{type:"cancel",clients:[]};if(r==="add")return{type:"add",clients:["axios"]};if(r==="replace")return{type:"replace",clients:["axios"],fromClient:"fetch"};if(r==="remove")return{type:"remove-one",clients:["fetch"]}}if(e==="axios"){let{action:r}=await Se.prompt({type:"select",name:"action",message:`${i}. 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(r==="cancel")return{type:"cancel",clients:[]};if(r==="add")return{type:"add",clients:["fetch"]};if(r==="replace")return{type:"replace",clients:["fetch"],fromClient:"axios"};if(r==="remove")return{type:"remove-one",clients:["axios"]}}console.log(be.yellow(`\u2716 ${i}`));let{action:t}=await Se.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 Qt(e,i){return i.type==="install"?i.clients:i.type==="add"?[...e==="fetch"?["fetch"]:["axios"],...i.clients]:i.type==="replace"?i.clients:i.type==="remove-one"?e==="both"?i.clients[0]==="fetch"?["axios"]:["fetch"]:[]:[]}function $o(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 i=e.fromClient==="fetch"?"Fetch":"Axios",t=e.clients[0]==="fetch"?"Fetch":"Axios";return`Replaced ${i} 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{prompt:_o}=bo,ei=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 + next-themes)").option("--redux","Setup Redux Toolkit").option("--i18n","Setup next-intl for internationalization").action(async i=>{try{if(d(Pe.cyan(`
419
422
  \u{1F527} Setup Wizard
420
- `)),i.httpClient||i.darkTheme||i.redux||i.i18n){i.httpClient&&await $e(process.cwd()),i.darkTheme&&await Ee(process.cwd()),i.redux&&await Re(process.cwd()),i.i18n&&await Ne(process.cwd());return}let r=(await Ro([{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"},"Cancel"]}])).feature;if(r==="Cancel"){m(he.yellow("Setup cancelled."));return}r==="dark-theme"?await Ee(process.cwd()):r==="redux"?await Re(process.cwd()):r==="http-client"?await $e(process.cwd()):r==="i18n"?await Ne(process.cwd()):(m(he.yellow(`
421
- \u26A0\uFE0F ${r} setup is not implemented yet.`)),m(he.dim("This feature will be available in a future update.")))}catch(t){y.fail("Setup failed"),E(`${t}`),process.exit(1)}})};var Bt=e=>{ze(e),Vt(e),et(e),nt(e),pt(e)};var Oo=process.emitWarning;process.emitWarning=function(e,i,t,r){if(!(typeof e=="string"&&e.includes("--localstorage-file")&&e.includes("was provided without a valid path")))return Oo.apply(process,arguments)};async function Ao(){De({logger:i=>pe(i)});let e=new No;e.name("next-maker").description("Teispace Next.js Project Generator").version("1.0.0"),Bt(e),e.parse()}Ao().catch(e=>{let i=e&&typeof e=="object"&&"message"in e?e.message:String(e);pe(`Unexpected error: ${i}`)});
423
+ `)),i.httpClient||i.darkTheme||i.redux||i.i18n){i.httpClient&&await _e(process.cwd()),i.darkTheme&&await Ne(process.cwd()),i.redux&&await Ae(process.cwd()),i.i18n&&await $e(process.cwd());return}let r=(await _o([{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"},"Cancel"]}])).feature;if(r==="Cancel"){d(Pe.yellow("Setup cancelled."));return}r==="dark-theme"?await Ne(process.cwd()):r==="redux"?await Ae(process.cwd()):r==="http-client"?await _e(process.cwd()):r==="i18n"?await $e(process.cwd()):(d(Pe.yellow(`
424
+ \u26A0\uFE0F ${r} setup is not implemented yet.`)),d(Pe.dim("This feature will be available in a future update.")))}catch(t){P.fail("Setup failed"),E(`${t}`),process.exit(1)}})};var ti=e=>{et(e),ei(e),ct(e),ut(e),yt(e)};var Fo=process.emitWarning;process.emitWarning=function(e,i,t,r){if(!(typeof e=="string"&&e.includes("--localstorage-file")&&e.includes("was provided without a valid path")))return Fo.apply(process,arguments)};async function ko(){Me({logger:i=>de(i)});let e=new jo;e.name("next-maker").description("Teispace Next.js Project Generator").version("1.0.0"),ti(e),e.parse()}ko().catch(e=>{let i=e&&typeof e=="object"&&"message"in e?e.message:String(e);de(`Unexpected error: ${i}`)});
422
425
  //# sourceMappingURL=index.js.map