@teispace/next-maker 1.12.0 → 1.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +29 -2
- package/dist/index.js +155 -145
- package/dist/index.js.map +3 -3
- package/dist/src/generators/templates/crud-service.template.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var wr=Object.defineProperty;var se=(
|
|
2
|
+
var wr=Object.defineProperty;var se=(t,o)=>()=>(t&&(o=t(t=0)),o);var Me=(t,o)=>{for(var e in o)wr(t,e,{get:o[e],enumerable:!0})};import te from"node:fs/promises";import It from"node:path";import{existsSync as Ue}from"node:fs";var d,u,O,w,h,me,l,P=se(()=>{"use strict";d=async t=>te.readFile(t,"utf-8"),u=async(t,o)=>{await te.mkdir(It.dirname(t),{recursive:!0}),await te.writeFile(t,o,"utf-8")},O=async(t,o)=>{await te.mkdir(It.dirname(o),{recursive:!0}),await te.copyFile(t,o)},w=async t=>{Ue(t)&&await te.unlink(t)},h=async t=>{Ue(t)&&await te.rm(t,{recursive:!0,force:!0})},me=async(t,o)=>{let e=await d(t),r=JSON.parse(e),n=o(r);await u(t,JSON.stringify(n,null,2))},l=t=>Ue(t)});var Ot={};Me(Ot,{PROJECT_PATHS:()=>a});var a,T=se(()=>{"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",SCRIPTS_DIR:"scripts",DOCS_DIR:"docs",CLAUDE_DIR:".claude",VSCODE_DIR:".vscode"}});var _t={};Me(_t,{cleanupHttpTypes:()=>ae,isFileUsed:()=>Gr,isStringUsed:()=>Mr,migrateClientUsages:()=>Ve,removeHttpExports:()=>qe,updateConfigIndex:()=>Be,updateHttpIndex:()=>Ye,updateTypesIndex:()=>We,updateUtilsIndex:()=>ze});import R from"node:path";import{exec as Lr}from"node:child_process";import{promisify as Hr}from"node:util";var Je,Ye,ze,We,Be,ae,Ve,qe,Gr,Mr,Re=se(()=>{"use strict";P();T();Je=Hr(Lr),Ye=async(t,o)=>{let e=R.join(t,a.HTTP_UTILS,"index.ts");if(l(e)){let r=await d(e);r=r.replace(/export .* from '\.\/axios-client';?\n?/g,""),r=r.replace(/export .* from '\.\/fetch-client';?\n?/g,""),o.includes("fetch")&&!r.includes("fetch-client")&&(r+=`export * from './fetch-client';
|
|
3
3
|
`),o.includes("axios")&&!r.includes("axios-client")&&(r+=`export * from './axios-client';
|
|
4
|
-
`),await u(
|
|
5
|
-
`,await u(o,
|
|
6
|
-
`),
|
|
7
|
-
`),await u(o,
|
|
8
|
-
`,await u(o,
|
|
4
|
+
`),await u(e,r)}},ze=async t=>{let o=R.join(t,a.UTILS_INDEX);if(l(o)){let e=await d(o);e.includes("./http")||(e+=`export * from './http';
|
|
5
|
+
`,await u(o,e))}},We=async t=>{let o=R.join(t,a.TYPES_INDEX);if(l(o)){let e=await d(o);e.includes("./common")||(e+=`export * from './common';
|
|
6
|
+
`),e.includes("./utility")||(e+=`export * from './utility';
|
|
7
|
+
`),await u(o,e)}},Be=async t=>{let o=R.join(t,a.CONFIG_INDEX);if(l(o)){let e=await d(o);e.includes("./app-apis")||(e+=`export * from './app-apis';
|
|
8
|
+
`,await u(o,e))}},ae=async(t,o)=>{let e=R.join(t,a.HTTP_TYPES);if(l(e)){let r=await d(e);o.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
9
|
|
|
10
10
|
`).trim()+`
|
|
11
|
-
`,await u(
|
|
12
|
-
`).filter(S=>S);for(let S of x){if(!l(S))continue;let v=await d(S),M=!1,Ge=new RegExp(`(import\\s*\\{[^}]*?)\\b${r}\\b([^}]*?\\}\\s*from\\s*['"][^'"]*?/http['"])`,"g");Ge.test(v)&&(v=v.replace(Ge,`$1${n}$2`),M=!0);let Te=new RegExp(`import\\s+${r}\\s+from\\s+['"]([^'"]*?)/${i}['"]`,"g");Te.test(v)&&(v=v.replace(Te,`import ${n} from '$1/${s}'`),M=!0);let Ee=new RegExp(`\\b${r}\\b(?=\\.)`,"g");Ee.test(v)&&(v=v.replace(Ee,n),M=!0);let Tt=new RegExp(`\\b${r}\\b(?![.\\w])`,"g");Tt.test(v)&&(v=v.replace(Tt,n),M=!0),M&&await u(S,v)}}catch(m){console.warn("Warning: Could not scan for HTTP client usages:",m)}},qe=async
|
|
13
|
-
`).filter(f=>{let[x]=f.split(":"),S=R.resolve(
|
|
14
|
-
`).filter(f=>{let[x]=f.split(":"),S=R.resolve(e,x);return!t.some(v=>!!(S===v||S.startsWith(v+R.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for string ${o}:`,s),!0}}});import{readFile as fi,access as Kt}from"node:fs/promises";import Qe from"node:path";var _,Zt=se(()=>{"use strict";_=async e=>{try{let o=Qe.join(e,"package.json"),t=await fi(o,"utf-8"),r=JSON.parse(t),n={...r.dependencies,...r.devDependencies},i=!!(n["@reduxjs/toolkit"]&&n["react-redux"]),s=!!n["next-intl"],c=!!n.axios,m=!1,f=Qe.join(e,"src","lib","utils","http","axios-client");try{await Kt(f)}catch{c=!1}let x=Qe.join(e,"src","lib","utils","http","fetch-client");try{await Kt(x),m=!0}catch{m=!1}let S;return c&&m?S="both":c?S="axios":m?S="fetch":S="none",{hasRedux:i,httpClient:S,hasI18n:s}}catch(o){throw new Error(`Failed to detect project setup: ${o}`,{cause:o})}}});import{access as gi}from"node:fs/promises";import{existsSync as hi}from"node:fs";import Qt from"node:path";var Q,Ae,eo=se(()=>{"use strict";Q=async(e,o,t)=>{try{return await gi(Qt.join(e,t,o)),!0}catch{return!1}},Ae=(e,o,t)=>hi(Qt.join(e,o,t))});var to={};Me(to,{detectProjectSetup:()=>_,directoryExists:()=>Q,fileExistsAt:()=>Ae});var W=se(()=>{"use strict";Zt();eo()});import{Command as Ln}from"commander";import Ze from"node:path";import Z from"picocolors";import Sr from"ora";function A(e="",o){let t=Sr({text:e,...o});return t.start(),t}import Cr from"enquirer";var{prompt:vr}=Cr,Et=async e=>{let o=await vr([{type:"input",name:"projectName",message:"What is the project name?",initial:e||"my-app",skip:!!e,validate:t=>/^[a-z0-9-_]+$/.test(t)?!0:"Project name must be lowercase and contain only alphanumeric characters, hyphens, and underscores."},{type:"input",name:"description",message:"Project description:",initial:"A Next.js application"},{type:"input",name:"author",message:"Author:",initial:"Teispace"},{type:"input",name:"version",message:"Version:",initial:"0.1.0",validate:t=>/^\d+\.\d+\.\d+$/.test(t)?!0:"Version must be a valid semantic version (x.y.z)."},{type:"input",name:"email",message:"Support email:",initial:"support@example.com",validate:t=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)?!0:"Please enter a valid email address."},{type:"select",name:"packageManager",message:"Which package manager would you like to use?",choices:["npm","yarn","pnpm","bun"],initial:1},{type:"input",name:"gitRemote",message:"GitHub repository URL (optional):",initial:""},{type:"confirm",name:"pushToRemote",message:"Would you like to push the changes to the remote repository?",initial:!0,skip:function(){return!this.state?.answers?.gitRemote}},{type:"input",name:"gitIssues",message:"GitHub issues URL (optional):",initial:"",skip:function(){return!this.state?.answers?.gitRemote},validate:t=>t?/^https:\/\/github\.com\/[\w-]+\/[\w.-]+\/issues$/.test(t)?!0:"Please enter a valid GitHub issues URL (e.g., https://github.com/user/repo/issues)":!0},{type:"input",name:"gitHomepage",message:"GitHub homepage URL (optional):",initial:"",skip:function(){return!this.state?.answers?.gitRemote},validate:t=>t?/^https:\/\/github\.com\/[\w-]+\/[\w.-]+#readme$/.test(t)?!0:"Please enter a valid GitHub homepage URL (e.g., https://github.com/user/repo#readme)":!0},{type:"confirm",name:"keepTemplates",message:"Do you want to keep GitHub issue and pull request templates?",initial:!1},{type:"select",name:"httpClient",message:"Which HTTP client do you want to use?",choices:["axios","fetch","both","none"],initial:1},{type:"confirm",name:"reactSecureStorage",message:"Do you want to include react-secure-storage?",initial:!0,skip:function(){let t=this.state?.answers??this.enquirer?.answers??{};return!!(t.httpClient&&t.httpClient!=="none")}},{type:"confirm",name:"darkMode",message:"Do you want to include Dark Mode (Tailwind + 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(o.company=o.author,o.gitRemote&&!o.gitHomepage){let t=o.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"");o.gitHomepage=`${t}#readme`,o.gitIssues=`${t}/issues`}return o};w();import{exec as Tr}from"node:child_process";import{promisify as Er}from"node:util";var z=Er(Tr),Nt=async(e,o,t)=>{try{if(await z("git init",{cwd:e}),await z("git add .",{cwd:e}),await z('git commit -m "Initial commit from @teispace/next-maker"',{cwd:e}),o&&(await z(`git remote add origin ${o}`,{cwd:e}),t)){await z("git fetch origin",{cwd:e});let r="main";try{await z("git show-branch origin/main",{cwd:e})}catch{try{await z("git show-branch origin/master",{cwd:e}),r="master"}catch{r="main"}}await z(`git merge origin/${r} --allow-unrelated-histories -X ours`,{cwd:e}),await z(`git push origin HEAD:${r}`,{cwd:e})}}catch(r){console.warn("Failed to initialize git repository",r)}};import{exec as Ir}from"node:child_process";import{promisify as Nr}from"node:util";var Ie=Nr(Ir),Rt=async(e,o)=>{let t=`${o} install`;try{await Ie(t,{cwd:e})}catch(r){throw new Error(`Failed to install dependencies with ${o}: ${r}`,{cause:r})}},D=async(e,o,t)=>{let r=o==="npm"?`${o} run ${t}`:`${o} ${t}`;try{await Ie(r,{cwd:e})}catch(n){console.warn(`Warning: Failed to run script '${t}': ${n}`)}},Rr=()=>{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"},U=async e=>{let{existsSync:o}=await import("node:fs"),t=await import("node:path");return o(t.join(e,"pnpm-lock.yaml"))?"pnpm":o(t.join(e,"yarn.lock"))?"yarn":o(t.join(e,"bun.lockb"))?"bun":o(t.join(e,"package-lock.json"))?"npm":Rr()},$r=async(e,o,t)=>{if(t.length===0)return;let n=`${Ar(o)} ${t.join(" ")}`;try{await Ie(n,{cwd:e})}catch(i){throw new Error(`Failed to install packages with ${o}: ${i}`,{cause:i})}},Ar=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"}},F=async(e,o)=>{let t=await U(e);await $r(e,t,[o])},br=async(e,o,t)=>{if(t.length===0)return;let n=`${Or(o)} ${t.join(" ")}`;try{await Ie(n,{cwd:e})}catch(i){throw new Error(`Failed to uninstall packages with ${o}: ${i}`,{cause:i})}},Or=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"}},Xe=async(e,o)=>{let t=await U(e);await br(e,t,[o])};import X from"picocolors";var kr={reset:e=>e,red:X.red,green:X.green,yellow:X.yellow,blue:X.blue,cyan:X.cyan,magenta:X.magenta,white:X.white,gray:X.gray,bright:X.bold,dim:X.dim};function oe(e,o="reset"){let t=kr[o]??(r=>r);console.log(t(e))}function Ne(e){oe(`\u2716 ${e}`,"red")}var C=Ne;function p(e){oe(e)}function $t(){console.log(""),oe("\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"),oe("\u2551 \u2551","cyan"),oe("\u2551 \u{1F680} Create Teispace Next.js App \u{1F680} \u2551","cyan"),oe("\u2551 \u2551","cyan"),oe("\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 At(e){let{logger:o=s=>console.error(s),exitOnCancel:t=process.env.NODE_ENV!=="test"}=e??{},r=()=>{console.log(""),console.log(""),o("Setup cancelled by user"),console.log(""),t&&process.exit(0)},n=s=>{if(s!==null&&typeof s=="object"&&"code"in s&&s.code==="ERR_USE_AFTER_CLOSE"){r();return}if(s instanceof Error){o(`Uncaught exception: ${s.message}`);return}o(`Uncaught exception: ${String(s)}`)},i=s=>{if(s instanceof Error){o(`Unhandled promise rejection: ${s.message}`);return}o(`Unhandled promise rejection: ${String(s)}`)};return process.on("SIGINT",r),process.on("SIGTERM",r),process.on("uncaughtException",n),process.on("unhandledRejection",i),()=>{process.off("SIGINT",r),process.off("SIGTERM",r),process.off("uncaughtException",n),process.off("unhandledRejection",i)}}var _r=e=>e.charAt(0).toUpperCase()+e.slice(1),k=e=>e.replace(/-([a-z])/g,(o,t)=>t.toUpperCase()),N=e=>_r(k(e));import jr from"ora";var g=jr();import Fr from"degit";var bt=async e=>{let o=A("Downloading template...");try{await Fr("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!0}).clone(e),o.succeed("Template downloaded successfully.")}catch(t){throw o.fail("Failed to download template."),t}};w();import Dr from"node:path";T();var b={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 kt=async(e,o)=>{let t=A("Configuring package.json...");try{let r=o.gitRemote,n=o.gitHomepage,i=o.gitIssues;o.gitRemote&&(o.gitRemote.startsWith("git@github.com:")&&(r=o.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"")),n||(n=`${r.replace(/\.git$/,"")}#readme`),i||(i=`${r.replace(/\.git$/,"")}/issues`),r.endsWith(".git")||(r=`${r}.git`)),await me(Dr.join(e,a.PACKAGE_JSON),s=>(s.name=o.projectName,s.version=o.version,s.description=o.description,s.author=o.author,delete s.packageManager,o.gitRemote?(n&&(s.homepage=n),i&&(s.bugs={url:i}),r&&(s.repository={type:"git",url:r})):(delete s.homepage,delete s.bugs,delete s.repository),o.redux||(delete s.dependencies[b.REDUX_TOOLKIT],delete s.dependencies[b.REACT_REDUX],delete s.dependencies[b.REDUX_PERSIST]),o.httpClient!=="none"||o.reactSecureStorage||delete s.dependencies[b.REACT_SECURE_STORAGE],o.i18n||delete s.dependencies[b.NEXT_INTL],o.darkMode||delete s.dependencies[b.NEXT_THEMES],o.httpClient==="none"?delete s.dependencies[b.AXIOS]:o.httpClient==="fetch"&&delete s.dependencies[b.AXIOS],s)),t.succeed("package.json configured.")}catch(r){throw t.fail("Failed to configure package.json."),r}};w();T();Re();import E from"node:path";var jt=async(e,o)=>{let t=E.join(e,a.HTTP_UTILS),r=o.httpClient!=="none"||!!o.reactSecureStorage;o.httpClient==="none"?await Ur(e,t,r):o.httpClient==="axios"?await Xr(e,t):o.httpClient==="fetch"&&await Jr(e,t)},Ur=async(e,o,t)=>{await h(E.join(e,a.AXIOS_CLIENT)),await h(E.join(e,a.FETCH_CLIENT)),t?(await u(E.join(o,"index.ts"),`export * from './token-store';
|
|
15
|
-
`),await
|
|
16
|
-
${
|
|
11
|
+
`,await u(e,r))}},Ve=async(t,o,e)=>{if(o===e)return;let r=o==="fetch"?"fetchClient":"axiosClient",n=e==="fetch"?"fetchClient":"axiosClient",i=o==="fetch"?"fetch-client":"axios-client",s=e==="fetch"?"fetch-client":"axios-client",c=R.join(t,"src");try{let m=`grep -rl "${r}" "${c}" --include="*.ts" --include="*.tsx" || true`,{stdout:f}=await Je(m);if(!f.trim())return;let x=f.trim().split(`
|
|
12
|
+
`).filter(S=>S);for(let S of x){if(!l(S))continue;let v=await d(S),M=!1,Ge=new RegExp(`(import\\s*\\{[^}]*?)\\b${r}\\b([^}]*?\\}\\s*from\\s*['"][^'"]*?/http['"])`,"g");Ge.test(v)&&(v=v.replace(Ge,`$1${n}$2`),M=!0);let Te=new RegExp(`import\\s+${r}\\s+from\\s+['"]([^'"]*?)/${i}['"]`,"g");Te.test(v)&&(v=v.replace(Te,`import ${n} from '$1/${s}'`),M=!0);let Ee=new RegExp(`\\b${r}\\b(?=\\.)`,"g");Ee.test(v)&&(v=v.replace(Ee,n),M=!0);let Tt=new RegExp(`\\b${r}\\b(?![.\\w])`,"g");Tt.test(v)&&(v=v.replace(Tt,n),M=!0),M&&await u(S,v)}}catch(m){console.warn("Warning: Could not scan for HTTP client usages:",m)}},qe=async t=>{let o=R.join(t,a.UTILS_INDEX);if(l(o)){let r=await d(o);r=r.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http['"];?.*$/gm,""),await u(o,r)}let e=R.join(t,a.TYPES_INDEX);if(l(e)){let r=await d(e),n=R.join(t,a.COMMON_TYPES_DIR);if(!l(n))r=r.replace(/^\s*export\s+\*\s+from\s+['"]\.\/common['"];?.*$/gm,"");else{let i=R.join(n,"index.ts");if(l(i)){let s=await d(i);s=s.replace(/^\s*export\s+\*\s+from\s+['"]\.\/http\.types['"];?.*$/gm,""),await u(i,s)}}l(R.join(t,a.UTILITY_TYPES_DIR))||(r=r.replace(/^\s*export\s+\*\s+from\s+['"]\.\/utility['"];?.*$/gm,"")),await u(e,r)}},Gr=async(t,o,e=[])=>{let r=R.join(t,"src"),i=`grep -r "from ['\\"].*${o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}.*['\\"]" "${r}" --include="*.ts" --include="*.tsx" || true`;try{let{stdout:s}=await Je(i);return s.trim()?s.trim().split(`
|
|
13
|
+
`).filter(f=>{let[x]=f.split(":"),S=R.resolve(t,x);return!e.some(v=>!!(S===v||S.startsWith(v+R.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for ${o}:`,s),!0}},Mr=async(t,o,e=[])=>{let r=R.join(t,"src"),i=`grep -r "${o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}" "${r}" --include="*.ts" --include="*.tsx" || true`;try{let{stdout:s}=await Je(i);return s.trim()?s.trim().split(`
|
|
14
|
+
`).filter(f=>{let[x]=f.split(":"),S=R.resolve(t,x);return!e.some(v=>!!(S===v||S.startsWith(v+R.sep)))}).length>0:!1}catch(s){return console.warn(`Warning: Failed to check usage for string ${o}:`,s),!0}}});import{readFile as fi,access as Kt}from"node:fs/promises";import Qe from"node:path";var _,Zt=se(()=>{"use strict";_=async t=>{try{let o=Qe.join(t,"package.json"),e=await fi(o,"utf-8"),r=JSON.parse(e),n={...r.dependencies,...r.devDependencies},i=!!(n["@reduxjs/toolkit"]&&n["react-redux"]),s=!!n["next-intl"],c=!!n.axios,m=!1,f=Qe.join(t,"src","lib","utils","http","axios-client");try{await Kt(f)}catch{c=!1}let x=Qe.join(t,"src","lib","utils","http","fetch-client");try{await Kt(x),m=!0}catch{m=!1}let S;return c&&m?S="both":c?S="axios":m?S="fetch":S="none",{hasRedux:i,httpClient:S,hasI18n:s}}catch(o){throw new Error(`Failed to detect project setup: ${o}`,{cause:o})}}});import{access as gi}from"node:fs/promises";import{existsSync as hi}from"node:fs";import Qt from"node:path";var Q,Ae,eo=se(()=>{"use strict";Q=async(t,o,e)=>{try{return await gi(Qt.join(t,e,o)),!0}catch{return!1}},Ae=(t,o,e)=>hi(Qt.join(t,o,e))});var to={};Me(to,{detectProjectSetup:()=>_,directoryExists:()=>Q,fileExistsAt:()=>Ae});var W=se(()=>{"use strict";Zt();eo()});import{Command as Ln}from"commander";import Ze from"node:path";import Z from"picocolors";import Sr from"ora";function A(t="",o){let e=Sr({text:t,...o});return e.start(),e}import Cr from"enquirer";var{prompt:vr}=Cr,Et=async t=>{let o=await vr([{type:"input",name:"projectName",message:"What is the project name?",initial:t||"my-app",skip:!!t,validate:e=>/^[a-z0-9-_]+$/.test(e)?!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:e=>/^\d+\.\d+\.\d+$/.test(e)?!0:"Version must be a valid semantic version (x.y.z)."},{type:"input",name:"email",message:"Support email:",initial:"support@example.com",validate:e=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)?!0:"Please enter a valid email address."},{type:"select",name:"packageManager",message:"Which package manager would you like to use?",choices:["npm","yarn","pnpm","bun"],initial:1},{type:"input",name:"gitRemote",message:"GitHub repository URL (optional):",initial:""},{type:"confirm",name:"pushToRemote",message:"Would you like to push the changes to the remote repository?",initial:!0,skip:function(){return!this.state?.answers?.gitRemote}},{type:"input",name:"gitIssues",message:"GitHub issues URL (optional):",initial:"",skip:function(){return!this.state?.answers?.gitRemote},validate:e=>e?/^https:\/\/github\.com\/[\w-]+\/[\w.-]+\/issues$/.test(e)?!0:"Please enter a valid GitHub issues URL (e.g., https://github.com/user/repo/issues)":!0},{type:"input",name:"gitHomepage",message:"GitHub homepage URL (optional):",initial:"",skip:function(){return!this.state?.answers?.gitRemote},validate:e=>e?/^https:\/\/github\.com\/[\w-]+\/[\w.-]+#readme$/.test(e)?!0:"Please enter a valid GitHub homepage URL (e.g., https://github.com/user/repo#readme)":!0},{type:"confirm",name:"keepTemplates",message:"Do you want to keep GitHub issue and pull request templates?",initial:!1},{type:"select",name:"httpClient",message:"Which HTTP client do you want to use?",choices:["axios","fetch","both","none"],initial:1},{type:"confirm",name:"reactSecureStorage",message:"Do you want to include react-secure-storage?",initial:!0,skip:function(){let e=this.state?.answers??this.enquirer?.answers??{};return!!(e.httpClient&&e.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:e=>/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(e)?!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:e=>/^[a-z0-9]+(?:[._-][a-z0-9]+)*$/.test(e)?!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:e=>/^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,127}$/.test(e)?!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(o.company=o.author,o.gitRemote&&!o.gitHomepage){let e=o.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"");o.gitHomepage=`${e}#readme`,o.gitIssues=`${e}/issues`}return o};P();import{exec as Tr}from"node:child_process";import{promisify as Er}from"node:util";var z=Er(Tr),Nt=async(t,o,e)=>{try{if(await z("git init",{cwd:t}),await z("git add .",{cwd:t}),await z('git commit -m "Initial commit from @teispace/next-maker"',{cwd:t}),o&&(await z(`git remote add origin ${o}`,{cwd:t}),e)){await z("git fetch origin",{cwd:t});let r="main";try{await z("git show-branch origin/main",{cwd:t})}catch{try{await z("git show-branch origin/master",{cwd:t}),r="master"}catch{r="main"}}await z(`git merge origin/${r} --allow-unrelated-histories -X ours`,{cwd:t}),await z(`git push origin HEAD:${r}`,{cwd:t})}}catch(r){console.warn("Failed to initialize git repository",r)}};import{exec as Ir}from"node:child_process";import{promisify as Nr}from"node:util";var Ie=Nr(Ir),Rt=async(t,o)=>{let e=`${o} install`;try{await Ie(e,{cwd:t})}catch(r){throw new Error(`Failed to install dependencies with ${o}: ${r}`,{cause:r})}},D=async(t,o,e)=>{let r=o==="npm"?`${o} run ${e}`:`${o} ${e}`;try{await Ie(r,{cwd:t})}catch(n){console.warn(`Warning: Failed to run script '${e}': ${n}`)}},Rr=()=>{let t=process.env.npm_config_user_agent;if(t){if(t.startsWith("yarn"))return"yarn";if(t.startsWith("pnpm"))return"pnpm";if(t.startsWith("bun"))return"bun"}return"npm"},U=async t=>{let{existsSync:o}=await import("node:fs"),e=await import("node:path");return o(e.join(t,"pnpm-lock.yaml"))?"pnpm":o(e.join(t,"yarn.lock"))?"yarn":o(e.join(t,"bun.lockb"))?"bun":o(e.join(t,"package-lock.json"))?"npm":Rr()},$r=async(t,o,e)=>{if(e.length===0)return;let n=`${Ar(o)} ${e.join(" ")}`;try{await Ie(n,{cwd:t})}catch(i){throw new Error(`Failed to install packages with ${o}: ${i}`,{cause:i})}},Ar=t=>{switch(t){case"npm":return"npm install";case"yarn":return"yarn add";case"pnpm":return"pnpm add";case"bun":return"bun add";default:return"npm install"}},F=async(t,o)=>{let e=await U(t);await $r(t,e,[o])},br=async(t,o,e)=>{if(e.length===0)return;let n=`${Or(o)} ${e.join(" ")}`;try{await Ie(n,{cwd:t})}catch(i){throw new Error(`Failed to uninstall packages with ${o}: ${i}`,{cause:i})}},Or=t=>{switch(t){case"npm":return"npm uninstall";case"yarn":return"yarn remove";case"pnpm":return"pnpm remove";case"bun":return"bun remove";default:return"npm uninstall"}},Xe=async(t,o)=>{let e=await U(t);await br(t,e,[o])};import X from"picocolors";var kr={reset:t=>t,red:X.red,green:X.green,yellow:X.yellow,blue:X.blue,cyan:X.cyan,magenta:X.magenta,white:X.white,gray:X.gray,bright:X.bold,dim:X.dim};function oe(t,o="reset"){let e=kr[o]??(r=>r);console.log(e(t))}function Ne(t){oe(`\u2716 ${t}`,"red")}var C=Ne;function p(t){oe(t)}function $t(){console.log(""),oe("\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"),oe("\u2551 \u2551","cyan"),oe("\u2551 \u{1F680} Create Teispace Next.js App \u{1F680} \u2551","cyan"),oe("\u2551 \u2551","cyan"),oe("\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 At(t){let{logger:o=s=>console.error(s),exitOnCancel:e=process.env.NODE_ENV!=="test"}=t??{},r=()=>{console.log(""),console.log(""),o("Setup cancelled by user"),console.log(""),e&&process.exit(0)},n=s=>{if(s!==null&&typeof s=="object"&&"code"in s&&s.code==="ERR_USE_AFTER_CLOSE"){r();return}if(s instanceof Error){o(`Uncaught exception: ${s.message}`);return}o(`Uncaught exception: ${String(s)}`)},i=s=>{if(s instanceof Error){o(`Unhandled promise rejection: ${s.message}`);return}o(`Unhandled promise rejection: ${String(s)}`)};return process.on("SIGINT",r),process.on("SIGTERM",r),process.on("uncaughtException",n),process.on("unhandledRejection",i),()=>{process.off("SIGINT",r),process.off("SIGTERM",r),process.off("uncaughtException",n),process.off("unhandledRejection",i)}}var _r=t=>t.charAt(0).toUpperCase()+t.slice(1),k=t=>t.replace(/-([a-z])/g,(o,e)=>e.toUpperCase()),N=t=>_r(k(t));import jr from"ora";var g=jr();import Fr from"degit";var bt=async t=>{let o=A("Downloading template...");try{await Fr("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!0}).clone(t),o.succeed("Template downloaded successfully.")}catch(e){throw o.fail("Failed to download template."),e}};P();import Dr from"node:path";T();var b={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 kt=async(t,o)=>{let e=A("Configuring package.json...");try{let r=o.gitRemote,n=o.gitHomepage,i=o.gitIssues;o.gitRemote&&(o.gitRemote.startsWith("git@github.com:")&&(r=o.gitRemote.replace("git@github.com:","https://github.com/").replace(/\.git$/,"")),n||(n=`${r.replace(/\.git$/,"")}#readme`),i||(i=`${r.replace(/\.git$/,"")}/issues`),r.endsWith(".git")||(r=`${r}.git`)),await me(Dr.join(t,a.PACKAGE_JSON),s=>(s.name=o.projectName,s.version=o.version,s.description=o.description,s.author=o.author,delete s.packageManager,o.gitRemote?(n&&(s.homepage=n),i&&(s.bugs={url:i}),r&&(s.repository={type:"git",url:r})):(delete s.homepage,delete s.bugs,delete s.repository),o.redux||(delete s.dependencies[b.REDUX_TOOLKIT],delete s.dependencies[b.REACT_REDUX],delete s.dependencies[b.REDUX_PERSIST]),o.httpClient!=="none"||o.reactSecureStorage||delete s.dependencies[b.REACT_SECURE_STORAGE],o.i18n||delete s.dependencies[b.NEXT_INTL],o.darkMode||delete s.dependencies[b.NEXT_THEMES],o.httpClient==="none"?delete s.dependencies[b.AXIOS]:o.httpClient==="fetch"&&delete s.dependencies[b.AXIOS],s)),e.succeed("package.json configured.")}catch(r){throw e.fail("Failed to configure package.json."),r}};P();T();Re();import E from"node:path";var jt=async(t,o)=>{let e=E.join(t,a.HTTP_UTILS),r=o.httpClient!=="none"||!!o.reactSecureStorage;o.httpClient==="none"?await Ur(t,e,r):o.httpClient==="axios"?await Xr(t,e):o.httpClient==="fetch"&&await Jr(t,e)},Ur=async(t,o,e)=>{await h(E.join(t,a.AXIOS_CLIENT)),await h(E.join(t,a.FETCH_CLIENT)),e?(await u(E.join(o,"index.ts"),`export * from './token-store';
|
|
15
|
+
`),await w(E.join(t,a.CLIENT_UTILS)),await ae(t,[])):(await h(o),await Yr(t),await w(E.join(t,a.APP_APIS)),await zr(t)),await Wr(t),await h(E.join(t,a.ERRORS_DIR)),e||(await h(E.join(t,a.COMMON_TYPES_DIR)),await h(E.join(t,a.UTILITY_TYPES_DIR)),await Br(t))},Xr=async(t,o)=>{await h(E.join(t,a.FETCH_CLIENT));let e=await d(E.join(o,"index.ts"));e=e.replace(/export .* from '\.\/fetch-client';\n/g,""),await u(E.join(o,"index.ts"),e);let r=E.join(t,a.HTTP_TYPES);if(l(r)){let n=await d(r);n=n.replace(/export interface FetchClientOptions \{[\s\S]*?\}\n\n/,""),n=n.replace(/export interface ExtendedRequestInit extends RequestInit \{[\s\S]*?\}\n\n/,""),await u(r,n)}},Jr=async(t,o)=>{await h(E.join(t,a.AXIOS_CLIENT));let e=await d(E.join(o,"index.ts"));e=e.replace(/export .* from '\.\/axios-client';\n/g,""),await u(E.join(o,"index.ts"),e),await ae(t,["fetch"]);let r=E.join(t,a.HTTP_TYPES);if(l(r)){let n=await d(r);n=n.replace(/export interface AxiosClientOptions \{[\s\S]*?\}\n\n/,""),await u(r,n)}},Yr=async t=>{let o=E.join(t,a.UTILS_INDEX);if(l(o)){let e=await d(o);e=e.replace(/export \* from '\.\/http';\n/,""),await u(o,e)}},zr=async t=>{let o=E.join(t,a.CONFIG_INDEX);if(l(o)){let e=await d(o);e=e.replace(/export \* from '\.\/app-apis';\n/,""),await u(o,e)}},Wr=async t=>{let o=E.join(t,a.CONSTANTS);if(l(o)){let e=await d(o);e=e.replace(/export const API_RESPONSE_DATA_KEY = 'data';\n/,""),e=e.replace(/export const SAVE_AUTH_TOKENS = false;\n/,""),await u(o,e)}},Br=async t=>{let o=E.join(t,a.TYPES_INDEX);if(l(o)){let e=await d(o);e=e.replace(/export \* from '\.\/utility';\n/,""),e=e.replace(/export \* from '\.\/common';\n/,""),await u(o,e)}};P();T();import ce from"node:path";var Ft=async(t,o)=>{o.redux||(await h(ce.join(t,a.STORE)),await h(ce.join(t,a.COUNTER_FEATURE)),await w(ce.join(t,a.STORE_PROVIDER)),await Vr(t),await qr(t))},Vr=async t=>{let o=ce.join(t,a.PROVIDERS_INDEX),e=await d(o);e=e.replace(/export \* from '\.\/StoreProvider';\n/,""),await u(o,e)},qr=async t=>{let o=[ce.join(t,a.ROOT_PAGE),ce.join(t,a.LOCALE_PAGE)];for(let e of o)if(l(e)){let r=await d(e);r=r.replace(/import\s+\{\s*Counter\s*\}\s+from\s+['"]@\/features\/counter['"];\n?/,""),r=r.replace(/<Counter\s*\/>\n?/g,""),await u(e,r)}};P();T();import $e from"node:path";var Dt=async(t,o)=>{o.darkMode||(await w($e.join(t,a.THEME_PROVIDER)),await Kr(t),await Zr(t),o.i18n||await Qr(t))},Kr=async t=>{let o=$e.join(t,a.PROVIDERS_INDEX),e=await d(o);e=e.replace(/export \* from '\.\/CustomThemeProvider';\n/,""),await u(o,e)},Zr=async t=>{let o=$e.join(t,a.GLOBALS_CSS);if(l(o)){let e=await d(o);e=e.replace(/@custom-variant dark \(.*?\);\n\n/,""),e=e.replace(/@theme \{[\s\S]*?\}\n/,""),await u(o,e)}},Qr=async t=>{let o=$e.join(t,a.ROOT_LAYOUT);if(l(o)){let e=await d(o);e=e.replace(/bg-light dark:bg-dark /g,""),await u(o,e)}};P();T();import J from"node:path";var Lt=async(t,o)=>{o.i18n||(await ei(t),await ti(t),await oi(t),await ri(t))},ei=async t=>{await h(J.join(t,a.I18N_DIR)),await h(J.join(t,a.LOCALE_DIR)),await w(J.join(t,a.PROXY)),await w(J.join(t,a.MIDDLEWARE)),await w(J.join(t,a.I18N_TYPES)),await w(J.join(t,a.APP_LOCALES))},ti=async t=>{let o=J.join(t,a.TYPES_INDEX);if(l(o)){let r=await d(o);r=r.replace(/export \* from '\.\/i18n';\n/,""),await u(o,r)}let e=J.join(t,a.CONFIG_INDEX);if(l(e)){let r=await d(e);r=r.replace(/export \* from '\.\/app-locales';\n/,""),await u(e,r)}},oi=async t=>{let o=J.join(t,a.NEXT_CONFIG);if(l(o)){let e=await d(o);e=e.replace(/import createNextIntlPlugin from 'next-intl\/plugin';\n/,""),e=e.replace(/const withNextIntl = createNextIntlPlugin\(\);\n/,""),e=e.replace(/export default withNextIntl\(nextConfig\);/,"export default nextConfig;"),await u(o,e)}},ri=async t=>{let o=J.join(t,a.COUNTER_COMPONENT);if(l(o)){let e=await d(o);e=e.replace(/import\s+\{\s*useTranslations\s*\}\s+from\s+['"]next-intl['"];\n/,""),e=e.replace(/\s*const\s+t\s*=\s*useTranslations\(['"]Count['"]\);\n/,""),e=e.replace(/\{t\('currentCount',\s*\{\s*count:\s*value\s*\}\)\}/g,"{value}"),e=e.replace(/\{t\(['"]increment['"]\)\}/g,"Increment"),e=e.replace(/\{t\(['"]decrement['"]\)\}/g,"Decrement"),e=e.replace(/\{t\(['"]reset['"]\)\}/g,"Reset"),await u(o,e)}};P();T();import K from"node:path";var Ht=async(t,o)=>{o.httpClient!=="none"||o.reactSecureStorage||await h(K.join(t,a.STORAGE_SERVICE))},Gt=async t=>{await w(K.join(t,a.LICENSE))},Mt=async t=>{await w(K.join(t,a.CHANGELOG))},Ut=async t=>{await w(K.join(t,a.NVM_RC)),await w(K.join(t,a.NPM_RC))},Xt=async t=>{await h(K.join(t,a.CLAUDE_DIR)),await h(K.join(t,a.DOCS_DIR)),await h(K.join(t,a.VSCODE_DIR))};var Jt=async(t,o)=>{let e=A("Customizing features...");try{await jt(t,o),await Ht(t,o),await Ft(t,o),await Dt(t,o),await Lt(t,o),await Gt(t),await Mt(t),await Ut(t),await Xt(t),e.succeed("Features customized.")}catch(r){throw e.fail("Failed to customize features."),r}};P();T();import Ke from"node:path";var Yt=async(t,o)=>{let e=[],r=[];o.redux&&(e.push("import { StoreProvider } from '@/providers';"),r.push("StoreProvider")),o.darkMode&&(e.push("import { CustomThemeProvider } from '@/providers';"),r.push("CustomThemeProvider")),o.i18n&&(e.push("import { NextIntlClientProvider, AbstractIntlMessages } from 'next-intl';"),e.push("import { SupportedLocale } from '@/types/i18n';"));let n=`'use client';
|
|
16
|
+
${e.join(`
|
|
17
17
|
`)}
|
|
18
18
|
|
|
19
19
|
export const RootProvider = ({
|
|
@@ -35,7 +35,7 @@ export const RootProvider = ({
|
|
|
35
35
|
</StoreProvider>`),i==="{children}"&&(i="<>{children}</>"),n+=` ${i}
|
|
36
36
|
);
|
|
37
37
|
};
|
|
38
|
-
`,await u(Ke.join(
|
|
38
|
+
`,await u(Ke.join(t,a.ROOT_PROVIDER),n)},zt=async(t,o)=>{if(!o.i18n){let e=`import type { Metadata } from 'next';
|
|
39
39
|
import '@/styles/globals.css';
|
|
40
40
|
import { Livvic } from 'next/font/google';
|
|
41
41
|
import { RootProvider } from '@/providers';
|
|
@@ -67,7 +67,7 @@ export default function RootLayout({
|
|
|
67
67
|
</html>
|
|
68
68
|
);
|
|
69
69
|
}
|
|
70
|
-
`;await u(Ke.join(
|
|
70
|
+
`;await u(Ke.join(t,a.ROOT_LAYOUT),e);let r=o.redux?`import { Counter } from '@/features/counter';
|
|
71
71
|
|
|
72
72
|
`:"",n=o.redux?`
|
|
73
73
|
<Counter />`:"",i=`${r}export default function Home() {
|
|
@@ -78,8 +78,8 @@ export default function RootLayout({
|
|
|
78
78
|
</div>
|
|
79
79
|
);
|
|
80
80
|
}
|
|
81
|
-
`;await u(Ke.join(
|
|
82
|
-
`};n("CONTAINER_NAME",o.containerName||"next-app"),n("IMAGE_NAME",o.imageName||"nextjs-starter"),n("IMAGE_TAG",o.imageTag||"latest"),await u(
|
|
81
|
+
`;await u(Ke.join(t,a.ROOT_PAGE),i)}};P();T();import I from"node:path";import{readdir as Wt}from"node:fs/promises";var Bt=async(t,o)=>{await ii(t,o),await ni(t,o),await si(t,o),await ai(t,o),await ci(t,o),await pi(t,o),await mi(t,o)},ii=async(t,o)=>{o.preCommitHooks||(await h(I.join(t,a.HUSKY_DIR)),await w(I.join(t,a.COMMITLINT_CONFIG)),await w(I.join(t,a.LINTSTAGED_RC)),await me(I.join(t,a.PACKAGE_JSON),e=>(delete e.devDependencies[b.HUSKY],delete e.devDependencies[b.COMMITLINT_CLI],delete e.devDependencies[b.COMMITLINT_CONFIG],delete e.devDependencies[b.LINT_STAGED],delete e.scripts.prepare,delete e.scripts.postinstall,delete e.commitlint,delete e["lint-staged"],e)))},ni=async(t,o)=>{o.commitizen||(await w(I.join(t,a.CZRC)),await me(I.join(t,a.PACKAGE_JSON),e=>(delete e.devDependencies[b.COMMITIZEN],delete e.devDependencies[b.CZ_CONVENTIONAL_CHANGELOG],delete e.config?.commitizen,e.config&&Object.keys(e.config).length===0&&delete e.config,delete e.scripts.commit,e)))},si=async(t,o)=>{o.ci||await h(I.join(t,a.GITHUB_WORKFLOWS))},ai=async(t,o)=>{let e=I.join(t,a.GITHUB_DIR);if(!o.keepTemplates)await h(I.join(e,a.GITHUB_ISSUE_TEMPLATE)),await w(I.join(e,a.GITHUB_PR_TEMPLATE));else{let r=I.join(e,a.GITHUB_ISSUE_TEMPLATE),n=I.join(e,a.GITHUB_PR_TEMPLATE),i=s=>s.replace(/Teispace/g,o.company).replace(/support@teispace\.com/g,o.email).replace(/Next\.js Starter/g,o.projectName).replace(/\[AUTHOR\]/g,o.author).replace(/\[COMPANY\]/g,o.company).replace(/\[EMAIL\]/g,o.email);if(l(n)){let s=await d(n);s=i(s),await u(n,s)}try{if(l(r)){let s=await Wt(r);for(let c of s){let m=I.join(r,c),f=await d(m);f=i(f),await u(m,f)}}}catch{}}},ci=async(t,o)=>{let e=[a.CODE_OF_CONDUCT,a.CONTRIBUTING,a.SECURITY];for(let r of e)o.communityFiles.includes(r)||await w(I.join(t,r))},pi=async(t,o)=>{if(o.docker){let e=I.join(t,a.ENV_EXAMPLE);if(l(e)){let r=await d(e),n=(i,s)=>{let c=new RegExp(`${i}=.*`);c.test(r)?r=r.replace(c,`${i}=${s}`):r+=`${i}=${s}
|
|
82
|
+
`};n("CONTAINER_NAME",o.containerName||"next-app"),n("IMAGE_NAME",o.imageName||"nextjs-starter"),n("IMAGE_TAG",o.imageTag||"latest"),await u(e,r)}}else{await w(I.join(t,a.DOCKERFILE)),await w(I.join(t,a.DOCKER_COMPOSE)),await w(I.join(t,a.DOCKERIGNORE));let e=I.join(t,a.ENV_EXAMPLE);if(l(e)){let r=await d(e);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(e,r)}}},mi=async(t,o)=>{let e=async i=>{let s=await Wt(i,{withFileTypes:!0}),c=[];for(let m of s){let f=I.join(i,m.name);m.isDirectory()&&m.name!=="node_modules"&&m.name!==".git"?c.push(...await e(f)):m.isFile()&&m.name.toLowerCase()==="readme.md"&&c.push(f)}return c},r=await e(t),n=I.join(t,a.README);for(let i of r)i!==n&&await w(i);if(o.readme){let i=`# ${o.projectName}
|
|
83
83
|
|
|
84
84
|
${o.description}
|
|
85
85
|
|
|
@@ -92,13 +92,13 @@ ${o.packageManager==="npm"?"npm run dev":o.packageManager+" dev"}
|
|
|
92
92
|
\`\`\`
|
|
93
93
|
|
|
94
94
|
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
|
95
|
-
`;await u(n,i)}else await
|
|
96
|
-
Cleaning up: Deleting directory ${o.projectName}...`));try{await h(
|
|
97
|
-
Process interrupted. Cleaning up...`)),await n(),process.exit(1)};process.on("SIGINT",i),process.on("SIGTERM",i);try{if(await bt(
|
|
98
|
-
import { ${
|
|
95
|
+
`;await u(n,i)}else await w(n)};var Vt=t=>{t.command("init").description("Initialize a new Next.js project").argument("[name]","Project name").action(async o=>{await li(o)})},li=async t=>{$t(),p("Welcome to the Teispace Next.js App Creator!"),p("");let o=await Et(t),e=Ze.resolve(process.cwd(),o.projectName);l(e)&&(console.error(Z.red(`Error: Directory ${o.projectName} already exists.`)),process.exit(1));let r=A("Initializing project..."),n=async()=>{if(l(e)){r.stop(),console.log(Z.yellow(`
|
|
96
|
+
Cleaning up: Deleting directory ${o.projectName}...`));try{await h(e),console.log(Z.green("Cleanup successful."))}catch(s){console.error(Z.red(`Failed to clean up directory ${o.projectName}:`),s)}}},i=async()=>{console.log(Z.red(`
|
|
97
|
+
Process interrupted. Cleaning up...`)),await n(),process.exit(1)};process.on("SIGINT",i),process.on("SIGTERM",i);try{if(await bt(e),await kt(e,o),await Jt(e,o),r.text="Generating code...",await Yt(e,o),await zt(e,o),r.text="Setting up developer tools...",await Bt(e,o),r.text="Initializing Git...",await Nt(e,o.gitRemote,o.pushToRemote),r.text="Installing dependencies...",await Rt(e,o.packageManager),r.text="Formatting and Linting...",await D(e,o.packageManager,"format"),await D(e,o.packageManager,"lint:fix"),o.copyEnv){r.text="Creating .env file...";let s=Ze.join(e,".env.example"),c=Ze.join(e,".env");l(s)&&await(await import("node:fs/promises")).copyFile(s,c)}process.off("SIGINT",i),process.off("SIGTERM",i),r.succeed(Z.green(`Project ${o.projectName} created successfully!`)),p(""),p("To get started:"),p(Z.cyan(` cd ${o.projectName}`)),p(Z.cyan(` ${o.packageManager==="npm"?"npm run dev":o.packageManager+" dev"}`)),p("")}catch(s){r.fail("Failed to create project."),console.error(s),await n(),process.exit(1)}};import $ from"picocolors";import xt from"node:path";import di from"enquirer";var{prompt:ui}=di,qt=async(t,o,e,r,n,i,s)=>{let c=[];t||c.push({type:"input",name:"featureName",message:"What is the feature name?",initial:"my-feature",validate:f=>/^[a-z0-9-]+$/.test(f)?!0:"Feature name must be lowercase and contain only alphanumeric characters and hyphens."}),o&&r===void 0&&n===void 0&&(c.push({type:"confirm",name:"createStore",message:"Generate Redux store for this feature?",initial:!0}),c.push({type:"confirm",name:"persistStore",message:"Enable persistence for this store?",initial:!1,skip(){return!this.state.answers.createStore}})),e&&e!=="none"&&i===void 0&&s===void 0&&(c.push({type:"confirm",name:"createService",message:"Generate API service for this feature?",initial:!0}),e==="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 m=c.length>0?await ui(c):{};return{featureName:t||m.featureName,hasRedux:o||!1,createStore:r===!0?!1:n!==void 0?!0:m.createStore||!1,persistStore:n==="persist"?!0:n==="no-persist"?!1:m.persistStore||!1,httpClient:e||"none",createService:i===!0?!1:s!==void 0?!0:m.createService||!1,selectedHttpClient:s||m.selectedHttpClient||(e==="both"?"fetch":e!=="none"?e:void 0)}};W();var re=async(t,o)=>{for(let e of t)if(!e.shouldSkip?.(o)){o.spinner.start(e.spinnerText);try{await e.execute(o),o.spinner.succeed(e.name)}catch(r){throw o.spinner.fail(e.name),r}}};import Bi from"node:path";import{writeFile as Oe,mkdir as wi}from"node:fs/promises";import L from"node:path";var oo=t=>{let{componentName:o,hookName:e}=t;return`'use client';
|
|
98
|
+
import { ${e} } from '../hooks/${e}';
|
|
99
99
|
|
|
100
100
|
export function ${o}() {
|
|
101
|
-
const {} = ${
|
|
101
|
+
const {} = ${e}();
|
|
102
102
|
|
|
103
103
|
return (
|
|
104
104
|
<div>
|
|
@@ -109,13 +109,13 @@ export function ${o}() {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
export default ${o};
|
|
112
|
-
`};var ro=
|
|
112
|
+
`};var ro=t=>{let{hookName:o,componentName:e,featureName:r}=t;return`'use client';
|
|
113
113
|
import { useAppDispatch, useAppSelector } from '@/store/hooks';
|
|
114
|
-
import { select${
|
|
114
|
+
import { select${e}State, setLoading, setError } from '../store/${r}.selectors';
|
|
115
115
|
|
|
116
116
|
export const ${o} = () => {
|
|
117
117
|
const dispatch = useAppDispatch();
|
|
118
|
-
const state = useAppSelector(select${
|
|
118
|
+
const state = useAppSelector(select${e}State);
|
|
119
119
|
|
|
120
120
|
const handleSetLoading = (loading: boolean) => {
|
|
121
121
|
dispatch(setLoading(loading));
|
|
@@ -133,7 +133,7 @@ export const ${o} = () => {
|
|
|
133
133
|
setError: handleSetError,
|
|
134
134
|
} as const;
|
|
135
135
|
};
|
|
136
|
-
`},io=
|
|
136
|
+
`},io=t=>{let{hookName:o}=t;return`'use client';
|
|
137
137
|
import { useState } from 'react';
|
|
138
138
|
|
|
139
139
|
export const ${o} = () => {
|
|
@@ -145,22 +145,22 @@ export const ${o} = () => {
|
|
|
145
145
|
// Add your methods here
|
|
146
146
|
} as const;
|
|
147
147
|
};
|
|
148
|
-
`};var be=
|
|
149
|
-
${
|
|
148
|
+
`};var be=t=>{let{componentName:o,withStore:e}=t;return`export interface ${o}State {
|
|
149
|
+
${e?`loading: boolean;
|
|
150
150
|
error: string | null;
|
|
151
151
|
// Add your state properties here`:`// Add your state properties here
|
|
152
152
|
// example: value: string;`}
|
|
153
153
|
}
|
|
154
|
-
`};var no=
|
|
154
|
+
`};var no=t=>{let{sliceName:o,withPersist:e}=t;return`export * from './${o}.slice';
|
|
155
155
|
export * from './${o}.selectors';
|
|
156
|
-
export * from './${o}.types';${
|
|
156
|
+
export * from './${o}.types';${e?`
|
|
157
157
|
export * from './persist';`:""}
|
|
158
|
-
`},so=
|
|
158
|
+
`},so=t=>{let{featureName:o,componentName:e,hookName:r,withStore:n,withService:i}=t;return`export { default as ${e} } from './components/${e}';
|
|
159
159
|
export { ${r} } from './hooks/${r}';
|
|
160
160
|
export * from './types/${o}.types';${n?`
|
|
161
161
|
export * from './store';`:""}${i?`
|
|
162
162
|
export * from './services/${o}.service';`:""}
|
|
163
|
-
`};import{writeFile as le,mkdir as xi}from"node:fs/promises";import de from"node:path";var ao=
|
|
163
|
+
`};import{writeFile as le,mkdir as xi}from"node:fs/promises";import de from"node:path";var ao=t=>{let{componentName:o,camelName:e,typesImportPath:r}=t;return`import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
|
164
164
|
import { ${o}State } from '${r}';
|
|
165
165
|
|
|
166
166
|
const initialState: ${o}State = {
|
|
@@ -169,8 +169,8 @@ const initialState: ${o}State = {
|
|
|
169
169
|
// Add your initial state here
|
|
170
170
|
};
|
|
171
171
|
|
|
172
|
-
export const ${
|
|
173
|
-
name: '${
|
|
172
|
+
export const ${e}Slice = createSlice({
|
|
173
|
+
name: '${e}',
|
|
174
174
|
initialState,
|
|
175
175
|
reducers: {
|
|
176
176
|
setLoading: (state, action: PayloadAction<boolean>) => {
|
|
@@ -186,77 +186,87 @@ export const ${t}Slice = createSlice({
|
|
|
186
186
|
},
|
|
187
187
|
});
|
|
188
188
|
|
|
189
|
-
export const { setLoading, setError, resetState } = ${
|
|
189
|
+
export const { setLoading, setError, resetState } = ${e}Slice.actions;
|
|
190
190
|
|
|
191
|
-
export const ${
|
|
192
|
-
`};var co=
|
|
191
|
+
export const ${e}Reducer = ${e}Slice.reducer;
|
|
192
|
+
`};var co=t=>{let{componentName:o,camelName:e,sliceName:r}=t;return`import { RootState } from '@/store/rootReducer';
|
|
193
193
|
|
|
194
|
-
export const select${o}State = (state: RootState) => state.${
|
|
194
|
+
export const select${o}State = (state: RootState) => state.${e};
|
|
195
195
|
export { setLoading, setError, resetState } from './${r}.slice';
|
|
196
|
-
`};var po=
|
|
196
|
+
`};var po=t=>{let{componentName:o,camelName:e,typesImportPath:r}=t;return`import { PersistConfig } from 'redux-persist';
|
|
197
197
|
import storage from 'redux-persist/lib/storage';
|
|
198
198
|
import { ${o}State } from '${r}';
|
|
199
199
|
|
|
200
|
-
export const ${
|
|
201
|
-
key: '${
|
|
200
|
+
export const ${e}PersistConfig: PersistConfig<${o}State> = {
|
|
201
|
+
key: '${e}',
|
|
202
202
|
storage,
|
|
203
203
|
// whitelist: ['someField'], // Specify which fields to persist
|
|
204
204
|
};
|
|
205
|
-
`};var ue=async
|
|
206
|
-
${
|
|
205
|
+
`};var ue=async t=>{let{name:o,outputPath:e,persist:r,typesImportPath:n=`./${o}.types`}=t;await xi(e,{recursive:!0});let i=N(o),s=k(o);await Promise.all([le(de.join(e,`${o}.types.ts`),be({componentName:i,withStore:!0})),le(de.join(e,`${o}.slice.ts`),ao({componentName:i,camelName:s,typesImportPath:n})),le(de.join(e,`${o}.selectors.ts`),co({componentName:i,camelName:s,sliceName:o})),...r?[le(de.join(e,"persist.ts"),po({componentName:i,camelName:s,typesImportPath:n}))]:[],le(de.join(e,"index.ts"),no({sliceName:o,withPersist:r}))])};import{writeFile as yi}from"node:fs/promises";import Pi from"node:path";var mo=t=>{let{camelName:o,httpClient:e}=t;return`import { AppApis } from '@/lib/config';
|
|
206
|
+
${e==="axios"?"import { axiosClient } from '@/lib/utils/http';":"import { fetchClient } from '@/lib/utils/http';"}
|
|
207
207
|
import { ResultAsync } from '@/types';
|
|
208
208
|
|
|
209
209
|
export const ${o}Service = {
|
|
210
210
|
getAll: (): ResultAsync<string> => {
|
|
211
|
-
return ${
|
|
211
|
+
return ${e==="axios"?"axiosClient":"fetchClient"}.get<string>(AppApis.${o}.getAll);
|
|
212
212
|
},
|
|
213
213
|
};
|
|
214
|
-
`};var fe=async
|
|
214
|
+
`};var fe=async t=>{let{name:o,outputPath:e,httpClient:r}=t,n=k(o);await yi(Pi.join(e,`${o}.service.ts`),mo({camelName:n,httpClient:r}))};var et=async t=>{let{name:o,outputPath:e,createStore:r,persistStore:n,createService:i,httpClient:s}=t,c=N(o),m=`use${c}`,f=[L.join(e,"components"),L.join(e,"hooks"),L.join(e,"types"),...r?[L.join(e,"store")]:[],...i?[L.join(e,"services")]:[]];await Promise.all(f.map(x=>wi(x,{recursive:!0}))),await Promise.all([Oe(L.join(e,"components",`${c}.tsx`),oo({componentName:c,hookName:m})),Oe(L.join(e,"hooks",`${m}.ts`),r?ro({hookName:m,componentName:c,featureName:o}):io({hookName:m})),Oe(L.join(e,"types",`${o}.types.ts`),be({componentName:c,withStore:r})),Oe(L.join(e,"index.ts"),so({featureName:o,componentName:c,hookName:m,withStore:r,withService:i}))]),r&&await ue({name:o,outputPath:L.join(e,"store"),persist:n,typesImportPath:`../types/${o}.types`}),i&&s&&await fe({name:o,outputPath:L.join(e,"services"),httpClient:s})};import{writeFile as Si}from"node:fs/promises";import Ci from"node:path";var lo=t=>{let{camelName:o,pascalName:e,httpClient:r}=t,n=r==="axios"?"import { axiosClient } from '@/lib/utils/http';":"import { fetchClient } from '@/lib/utils/http';",i=r==="axios"?"axiosClient":"fetchClient";return`import { AppApis } from '@/lib/config';
|
|
215
215
|
${n}
|
|
216
216
|
import { ResultAsync } from '@/types';
|
|
217
217
|
|
|
218
|
-
|
|
218
|
+
/**
|
|
219
|
+
* Summary type used in list responses (e.g., cards, tables).
|
|
220
|
+
*/
|
|
221
|
+
export interface ${e}Summary {
|
|
219
222
|
id: string;
|
|
220
|
-
// Add
|
|
223
|
+
// Add list/card fields here (title, thumbnail, status, etc.)
|
|
221
224
|
}
|
|
222
225
|
|
|
223
|
-
|
|
226
|
+
/**
|
|
227
|
+
* Detail type used in single-item responses (e.g., detail page).
|
|
228
|
+
*/
|
|
229
|
+
export interface ${e}Detail extends ${e}Summary {
|
|
230
|
+
// Add detailed fields here (content, metadata, relations, etc.)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export interface Create${e}Dto {
|
|
224
234
|
// Add create fields here
|
|
225
235
|
}
|
|
226
236
|
|
|
227
|
-
export interface Update${
|
|
237
|
+
export interface Update${e}Dto {
|
|
228
238
|
// Add update fields here
|
|
229
239
|
}
|
|
230
240
|
|
|
231
241
|
export const ${o}Service = {
|
|
232
|
-
getAll: (): ResultAsync<${
|
|
233
|
-
return ${i}.get<${
|
|
242
|
+
getAll: (): ResultAsync<${e}Summary[]> => {
|
|
243
|
+
return ${i}.get<${e}Summary[]>(AppApis.${o}.getAll);
|
|
234
244
|
},
|
|
235
245
|
|
|
236
|
-
getById: (id: string): ResultAsync<${
|
|
237
|
-
return ${i}.get<${
|
|
246
|
+
getById: (id: string): ResultAsync<${e}Detail> => {
|
|
247
|
+
return ${i}.get<${e}Detail>(AppApis.${o}.getById(id));
|
|
238
248
|
},
|
|
239
249
|
|
|
240
|
-
create: (data: Create${
|
|
241
|
-
return ${i}.post<${
|
|
250
|
+
create: (data: Create${e}Dto): ResultAsync<${e}Detail> => {
|
|
251
|
+
return ${i}.post<${e}Detail>(AppApis.${o}.create, data);
|
|
242
252
|
},
|
|
243
253
|
|
|
244
|
-
update: (id: string, data: Update${
|
|
245
|
-
return ${i}.patch<${
|
|
254
|
+
update: (id: string, data: Update${e}Dto): ResultAsync<${e}Detail> => {
|
|
255
|
+
return ${i}.patch<${e}Detail>(AppApis.${o}.update(id), data);
|
|
246
256
|
},
|
|
247
257
|
|
|
248
258
|
delete: (id: string): ResultAsync<void> => {
|
|
249
259
|
return ${i}.delete<void>(AppApis.${o}.delete(id));
|
|
250
260
|
},
|
|
251
261
|
};
|
|
252
|
-
`},uo=
|
|
253
|
-
base: \`\${API_PREFIX}/${
|
|
254
|
-
getAll: \`\${API_PREFIX}/${
|
|
255
|
-
getById: (id: string) => \`\${API_PREFIX}/${
|
|
256
|
-
create: \`\${API_PREFIX}/${
|
|
257
|
-
update: (id: string) => \`\${API_PREFIX}/${
|
|
258
|
-
delete: (id: string) => \`\${API_PREFIX}/${
|
|
259
|
-
},`};var tt=async
|
|
262
|
+
`},uo=t=>{let{camelName:o,kebabName:e}=t;return` ${o}: {
|
|
263
|
+
base: \`\${API_PREFIX}/${e}\`,
|
|
264
|
+
getAll: \`\${API_PREFIX}/${e}\`,
|
|
265
|
+
getById: (id: string) => \`\${API_PREFIX}/${e}/\${id}\`,
|
|
266
|
+
create: \`\${API_PREFIX}/${e}\`,
|
|
267
|
+
update: (id: string) => \`\${API_PREFIX}/${e}/\${id}\`,
|
|
268
|
+
delete: (id: string) => \`\${API_PREFIX}/${e}/\${id}\`,
|
|
269
|
+
},`};var tt=async t=>{let{name:o,outputPath:e,httpClient:r}=t,n=k(o),i=N(o);await Si(Ci.join(e,`${o}.service.ts`),lo({camelName:n,pascalName:i,httpClient:r}))};import{writeFile as ot,mkdir as vi}from"node:fs/promises";import ge from"node:path";var fo=t=>{let{componentName:o,routePath:e,hasI18n:r}=t;return r?`import { generateSEOMetadata } from '@/lib/config/seo';
|
|
260
270
|
import { SupportedLocale } from '@/types/i18n';
|
|
261
271
|
import { Metadata } from 'next';
|
|
262
272
|
import { getTranslations, setRequestLocale } from 'next-intl/server';
|
|
@@ -272,7 +282,7 @@ export async function generateMetadata(props: Props): Promise<Metadata> {
|
|
|
272
282
|
return generateSEOMetadata({
|
|
273
283
|
title: t('title'),
|
|
274
284
|
description: t('description'),
|
|
275
|
-
path: '${
|
|
285
|
+
path: '${e}',
|
|
276
286
|
});
|
|
277
287
|
}
|
|
278
288
|
|
|
@@ -302,17 +312,17 @@ export default function ${o}Page() {
|
|
|
302
312
|
</div>
|
|
303
313
|
);
|
|
304
314
|
}
|
|
305
|
-
`},go=
|
|
315
|
+
`},go=t=>{let{componentName:o,paramName:e,routePath:r,hasI18n:n}=t;return n?`import { generateSEOMetadata } from '@/lib/config/seo';
|
|
306
316
|
import { SupportedLocale } from '@/types/i18n';
|
|
307
317
|
import { Metadata } from 'next';
|
|
308
318
|
import { getTranslations, setRequestLocale } from 'next-intl/server';
|
|
309
319
|
|
|
310
320
|
type Props = {
|
|
311
|
-
params: Promise<{ locale: string; ${
|
|
321
|
+
params: Promise<{ locale: string; ${e}: string }>;
|
|
312
322
|
};
|
|
313
323
|
|
|
314
324
|
export async function generateMetadata(props: Props): Promise<Metadata> {
|
|
315
|
-
const { locale, ${
|
|
325
|
+
const { locale, ${e} } = await props.params;
|
|
316
326
|
const t = await getTranslations({ locale: locale as SupportedLocale, namespace: '${o}' });
|
|
317
327
|
|
|
318
328
|
return generateSEOMetadata({
|
|
@@ -323,7 +333,7 @@ export async function generateMetadata(props: Props): Promise<Metadata> {
|
|
|
323
333
|
}
|
|
324
334
|
|
|
325
335
|
export default async function ${o}Page(props: Props) {
|
|
326
|
-
const { locale, ${
|
|
336
|
+
const { locale, ${e} } = await props.params;
|
|
327
337
|
setRequestLocale(locale);
|
|
328
338
|
|
|
329
339
|
const t = await getTranslations('${o}');
|
|
@@ -331,7 +341,7 @@ export default async function ${o}Page(props: Props) {
|
|
|
331
341
|
return (
|
|
332
342
|
<div>
|
|
333
343
|
<h1>{t('title')}</h1>
|
|
334
|
-
<p>${o}: {${
|
|
344
|
+
<p>${o}: {${e}}</p>
|
|
335
345
|
</div>
|
|
336
346
|
);
|
|
337
347
|
}
|
|
@@ -343,29 +353,29 @@ export const metadata: Metadata = {
|
|
|
343
353
|
};
|
|
344
354
|
|
|
345
355
|
type Props = {
|
|
346
|
-
params: Promise<{ ${
|
|
356
|
+
params: Promise<{ ${e}: string }>;
|
|
347
357
|
};
|
|
348
358
|
|
|
349
359
|
export default async function ${o}Page(props: Props) {
|
|
350
|
-
const { ${
|
|
360
|
+
const { ${e} } = await props.params;
|
|
351
361
|
|
|
352
362
|
return (
|
|
353
363
|
<div>
|
|
354
364
|
<h1>${o}</h1>
|
|
355
|
-
<p>${o}: {${
|
|
365
|
+
<p>${o}: {${e}}</p>
|
|
356
366
|
</div>
|
|
357
367
|
);
|
|
358
368
|
}
|
|
359
|
-
`},ho=
|
|
369
|
+
`},ho=t=>`export default function ${t.componentName}Loading() {
|
|
360
370
|
return (
|
|
361
371
|
<div className="flex h-full items-center justify-center">
|
|
362
372
|
<p>Loading...</p>
|
|
363
373
|
</div>
|
|
364
374
|
);
|
|
365
375
|
}
|
|
366
|
-
`,xo=
|
|
376
|
+
`,xo=t=>`'use client';
|
|
367
377
|
|
|
368
|
-
export default function ${
|
|
378
|
+
export default function ${t.componentName}Error({
|
|
369
379
|
error,
|
|
370
380
|
reset,
|
|
371
381
|
}: {
|
|
@@ -380,62 +390,62 @@ export default function ${e.componentName}Error({
|
|
|
380
390
|
</div>
|
|
381
391
|
);
|
|
382
392
|
}
|
|
383
|
-
`;var rt=async
|
|
384
|
-
`)},yo=
|
|
385
|
-
`;
|
|
386
|
-
`);let c=ie.join(
|
|
387
|
-
`;o.includes(
|
|
388
|
-
`)}},wo=
|
|
389
|
-
name: '${
|
|
393
|
+
`;var rt=async t=>{let{name:o,projectPath:e,hasI18n:r,dynamic:n,withLoading:i=!1,withError:s=!1}=t,c=N(o),m=`/${o}`,f=r?"src/app/[locale]":"src/app",x;n?x=ge.join(e,f,o,`[${n}]`):x=ge.join(e,f,o),await vi(x,{recursive:!0});let S=n?go({componentName:c,routePath:n?`${m}/[${n}]`:m,paramName:n,hasI18n:r}):fo({componentName:c,routePath:m,hasI18n:r});await ot(ge.join(x,"page.tsx"),S),i&&await ot(ge.join(x,"loading.tsx"),ho({componentName:c})),s&&await ot(ge.join(x,"error.tsx"),xo({componentName:c}))};import{writeFile as nt,mkdir as Po}from"node:fs/promises";import ie from"node:path";var it=t=>{let{componentName:o,isClient:e,hasI18n:r}=t,n=t.translationNamespace||o,i=[];return(e||r)&&i.push("'use client';"),r&&i.push("import { useTranslations } from 'next-intl';"),i.push(""),i.push(`export function ${o}() {`),r?(i.push(` const t = useTranslations('${n}');`),i.push(""),i.push(" return ("),i.push(" <div>"),i.push(" <h2>{t('title')}</h2>"),i.push(" </div>"),i.push(" );")):(i.push(" return ("),i.push(" <div>"),i.push(` <h2>${o}</h2>`),i.push(" </div>"),i.push(" );")),i.push("}"),i.push(""),i.join(`
|
|
394
|
+
`)},yo=t=>`export { ${t.componentName} } from './${t.componentName}';
|
|
395
|
+
`;P();var st=async t=>{let{name:o,projectPath:e,isClient:r,hasI18n:n,featurePath:i}=t,s=N(o);i?await Ti(s,e,i,r,n):await Ei(s,o,e,r,n)},Ti=async(t,o,e,r,n)=>{let i=ie.join(o,e,"components");await Po(i,{recursive:!0}),await nt(ie.join(i,`${t}.tsx`),it({componentName:t,isClient:r,hasI18n:n}))},Ei=async(t,o,e,r,n)=>{let i=ie.join(e,"src","components","common",t);await Po(i,{recursive:!0}),await nt(ie.join(i,`${t}.tsx`),it({componentName:t,isClient:r,hasI18n:n})),await nt(ie.join(i,"index.ts"),yo({componentName:t}));let s=ie.join(e,"src","components","common","index.ts");await Ii(s,`export { ${t} } from './${t}';
|
|
396
|
+
`);let c=ie.join(e,"src","components","index.ts");await Ni(c)},Ii=async(t,o)=>{let e="";l(t)&&(e=await d(t)),e.includes(o.trim())||(e+=o,await u(t,e))},Ni=async t=>{let o="";l(t)&&(o=await d(t));let e=`export * from './common';
|
|
397
|
+
`;o.includes(e.trim())||(o+=e,await u(t,o))};P();import{readFile as Ri,writeFile as $i,copyFile as Ai}from"node:fs/promises";import he from"node:path";var at=async t=>{let{code:o,name:e,country:r,flag:n,projectPath:i,copyTranslations:s}=t;await bi(i,o,s),await Oi(i,o),await ki(i,o,e,r,n)},bi=async(t,o,e)=>{let r=he.join(t,"src","i18n","translations"),n=he.join(r,"en.json"),i=he.join(r,`${o}.json`);if(e)await Ai(n,i);else{let s=await Ri(n,"utf-8"),c=JSON.parse(s),m=wo(c);await $i(i,JSON.stringify(m,null,2)+`
|
|
398
|
+
`)}},wo=t=>{let o={};for(let[e,r]of Object.entries(t))typeof r=="object"&&r!==null?o[e]=wo(r):o[e]="";return o},Oi=async(t,o)=>{let e=he.join(t,"src","types","i18n.ts");if(!l(e))return;let r=await d(e),n=/export type SupportedLocale = (.*);/,i=r.match(n);if(i&&!i[1].includes(`'${o}'`)){let s=`${i[1]} | '${o}'`;r=r.replace(n,`export type SupportedLocale = ${s};`),await u(e,r)}},ki=async(t,o,e,r,n)=>{let i=he.join(t,"src","lib","config","app-locales.ts");if(!l(i))return;let s=await d(i);if(s.includes(`locale: '${o}'`))return;let c=s.lastIndexOf("];");if(c===-1)return;let m=` {
|
|
399
|
+
name: '${e}',
|
|
390
400
|
locale: '${o}',
|
|
391
401
|
flag: '${n}',
|
|
392
402
|
country: '${r}',
|
|
393
403
|
},
|
|
394
|
-
`;s=s.slice(0,c)+m+s.slice(c),await u(i,s)};import{writeFile as _i,mkdir as ji}from"node:fs/promises";import ct from"node:path";var So=
|
|
395
|
-
`)};var pt=async
|
|
396
|
-
`+
|
|
397
|
-
`+
|
|
398
|
-
${o}: ${
|
|
399
|
-
})`)},xe=(
|
|
404
|
+
`;s=s.slice(0,c)+m+s.slice(c),await u(i,s)};import{writeFile as _i,mkdir as ji}from"node:fs/promises";import ct from"node:path";var So=t=>{let{hookName:o,isClient:e}=t,r=[];return e&&r.push("'use client';"),r.push("import { useState, useCallback } from 'react';"),r.push(""),r.push(`export const ${o} = () => {`),r.push(" const [loading, setLoading] = useState(false);"),r.push(" const [error, setError] = useState<string | null>(null);"),r.push(""),r.push(" const execute = useCallback(async () => {"),r.push(" setLoading(true);"),r.push(" setError(null);"),r.push(" try {"),r.push(" // Add your logic here"),r.push(" } catch (err) {"),r.push(" setError(err instanceof Error ? err.message : 'An error occurred');"),r.push(" } finally {"),r.push(" setLoading(false);"),r.push(" }"),r.push(" }, []);"),r.push(""),r.push(" return {"),r.push(" loading,"),r.push(" error,"),r.push(" execute,"),r.push(" } as const;"),r.push("};"),r.push(""),r.join(`
|
|
405
|
+
`)};var pt=async t=>{let{name:o,projectPath:e,isClient:r,featurePath:n}=t,s=`use${N(o)}`,c;n?c=ct.join(e,n,"hooks"):c=ct.join(e,"src","hooks"),await ji(c,{recursive:!0}),await _i(ct.join(c,`${s}.ts`),So({hookName:s,isClient:r}))};import{readFile as Fi,writeFile as Di}from"node:fs/promises";import Li from"node:path";var mt=(t,o)=>{let e=/import\s+.*\s+from\s+['"].*['"];?\n/g,r=t.match(e);if(r&&r.length>0){let n=r[r.length-1],i=t.lastIndexOf(n);return t.slice(0,i+n.length)+o+`
|
|
406
|
+
`+t.slice(i+n.length)}return o+`
|
|
407
|
+
`+t},lt=(t,o,e)=>{let r=/combineReducers\(\{([^}]*)\}\)/s,n=t.match(r);if(!n)throw new Error("Could not find combineReducers in rootReducer.ts");let i=n[1],s=`
|
|
408
|
+
${o}: ${e},`,c=i.trimEnd()+s;return t.replace(r,`combineReducers({${c}
|
|
409
|
+
})`)},xe=(t,o)=>{let e=t.lastIndexOf("} as const;");if(e===-1)throw new Error("Could not find closing brace of AppApis object");let r=t.substring(0,e),n=t.substring(e);return r.trimEnd()+`
|
|
400
410
|
`+o+`
|
|
401
|
-
`+n};var ye=async
|
|
411
|
+
`+n};var ye=async t=>{let{projectPath:o,name:e,persist:r,importPath:n}=t,i=Li.join(o,"src","store","rootReducer.ts");try{let s=await Fi(i,"utf-8"),c=k(e),m=`${c}Reducer`,f=`${c}PersistConfig`,x=n.replace(/^src\//,"@/"),S=r?`import { ${m}, ${f} } from '${x}';`:`import { ${m} } from '${x}';`;s=mt(s,S);let v=r?`persistReducer(${f}, ${m})`:m;s=lt(s,c,v),await Di(i,s)}catch(s){throw new Error(`Failed to register reducer '${e}' in rootReducer: ${s}`,{cause:s})}};import{readFile as Hi,writeFile as Gi}from"node:fs/promises";import Mi from"node:path";var Pe=async t=>{let{serviceName:o,projectPath:e}=t,r=k(o),n=Mi.join(e,"src","lib","config","app-apis.ts");try{let i=await Hi(n,"utf-8");if(i.includes(`${r}:`))return;if(!i.match(/export const AppApis = \{[\s\S]*?\} as const;/))throw new Error("Could not find AppApis object in app-apis.ts");let s=` ${r}: {
|
|
402
412
|
base: \`\${API_PREFIX}/${o}\`,
|
|
403
413
|
getAll: \`\${API_PREFIX}/${o}\`,
|
|
404
|
-
},`;i=xe(i,s),await Gi(n,i)}catch(i){throw new Error(`Failed to register API endpoints: ${i}`,{cause:i})}};import{readFile as Ui,writeFile as Xi}from"node:fs/promises";import Ji from"node:path";
|
|
405
|
-
`;n=n.slice(0,s)+c+n.slice(s),await Xi(r,n)};
|
|
406
|
-
`))};W();var ft=()=>[{name:"Project setup detected",spinnerText:"Detecting project setup...",execute:async
|
|
414
|
+
},`;i=xe(i,s),await Gi(n,i)}catch(i){throw new Error(`Failed to register API endpoints: ${i}`,{cause:i})}};import{readFile as Ui,writeFile as Xi}from"node:fs/promises";import Ji from"node:path";P();var dt=async(t,o,e)=>{let r=Ji.join(t,"src","lib","config","app-paths.ts");if(!l(r))return;let n=await Ui(r,"utf-8"),i=k(o);if(n.includes(`${i}:`))return;let s=n.lastIndexOf("} as const;");if(s===-1)return;let c=` ${i}: '${e}',
|
|
415
|
+
`;n=n.slice(0,s)+c+n.slice(s),await Xi(r,n)};P();import{readFile as Yi,writeFile as zi}from"node:fs/promises";import Wi from"node:path";var ut=async(t,o)=>{let e=Wi.join(t,"src","i18n","translations","en.json");if(!l(e))return;let r=await Yi(e,"utf-8"),n=JSON.parse(r);n[o]||(n[o]={title:o,description:`${o} page description`},await zi(e,JSON.stringify(n,null,2)+`
|
|
416
|
+
`))};W();var ft=()=>[{name:"Project setup detected",spinnerText:"Detecting project setup...",execute:async t=>{t.detection=await _(t.projectPath)}},{name:"Feature files generated",spinnerText:"Generating feature files...",execute:async t=>{await et({name:t.featureName,outputPath:t.featurePath,createStore:t.createStore,persistStore:t.persistStore,createService:t.createService,httpClient:t.httpClient})}},{name:"API endpoints registered",spinnerText:"Registering API endpoints...",shouldSkip:t=>!t.createService,execute:async t=>{await Pe({serviceName:t.featureName,projectPath:t.projectPath})}},{name:"Feature registered in rootReducer",spinnerText:"Registering feature in rootReducer...",shouldSkip:t=>!t.createStore||!t.detection.hasRedux,execute:async t=>{await ye({projectPath:t.projectPath,name:t.featureName,persist:t.persistStore,importPath:Bi.join(t.basePath,t.featureName,"store")})}}];import Vi from"node:path";var gt=()=>[{name:"Slice files generated",spinnerText:"Generating slice files...",execute:async t=>{await ue({name:t.sliceName,outputPath:t.slicePath,persist:t.persistSlice})}},{name:"Slice registered in rootReducer",spinnerText:"Registering slice in rootReducer...",execute:async t=>{await ye({projectPath:t.projectPath,name:t.sliceName,persist:t.persistSlice,importPath:Vi.join(t.basePath,t.sliceName)})}}];var ht=()=>[{name:"Service files generated",spinnerText:"Generating service files...",execute:async t=>{await fe({name:t.serviceName,outputPath:t.servicePath,httpClient:t.httpClient})}},{name:"API endpoints registered",spinnerText:"Registering API endpoints...",execute:async t=>{await Pe({serviceName:t.serviceName,projectPath:t.projectPath})}}];var Co=t=>{t.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(o,e)=>{try{let r=process.cwd();qi(e),p($.cyan(`
|
|
407
417
|
\u{1F3AF} Feature Generator
|
|
408
418
|
`));let n=ft();g.start("Detecting project setup...");let{detectProjectSetup:i}=await Promise.resolve().then(()=>(W(),to)),s=await i(r);g.succeed("Project setup detected"),p($.dim(` Redux: ${s.hasRedux?"\u2713":"\u2717"}`)),p($.dim(` HTTP Client: ${s.httpClient}`)),p($.dim(` i18n: ${s.hasI18n?"\u2713":"\u2717"}
|
|
409
|
-
`));let c=await qt(o,s.hasRedux,s.httpClient,
|
|
410
|
-
\u2728 Feature '${
|
|
411
|
-
`)),p($.dim("Generated files:")),p($.dim(` \u{1F4C2} ${
|
|
412
|
-
`)),p($.cyan("Next steps:"));let r=o.replace(/^src\//,"@/");p($.dim(` 1. Import and use the feature: import { ${
|
|
419
|
+
`));let c=await qt(o,s.hasRedux,s.httpClient,e.skipStore,e.store,e.skipService,e.service),m=e.path||xt.join("src","features"),f=xt.join(r,m,c.featureName);await Q(r,c.featureName,m)&&(C(`Feature '${c.featureName}' already exists at ${m}!`),process.exit(1)),await re(n.slice(1),{projectPath:r,spinner:g,featureName:c.featureName,basePath:m,featurePath:f,createStore:c.createStore,persistStore:c.persistStore,createService:c.createService,httpClient:c.selectedHttpClient,detection:s}),Ki(c,m)}catch(r){g.fail("Feature generation failed"),C(`${r}`),process.exit(1)}})},qi=t=>{t.store&&!["persist","no-persist"].includes(t.store)&&(C("Invalid --store option. Use: persist or no-persist"),process.exit(1)),t.service&&!["axios","fetch"].includes(t.service)&&(C("Invalid --service option. Use: axios or fetch"),process.exit(1)),t.skipStore&&t.store&&(C("Cannot use --skip-store and --store together"),process.exit(1)),t.skipService&&t.service&&(C("Cannot use --skip-service and --service together"),process.exit(1))},Ki=(t,o)=>{let e=xt.join(o,t.featureName);p($.green(`
|
|
420
|
+
\u2728 Feature '${t.featureName}' created successfully!
|
|
421
|
+
`)),p($.dim("Generated files:")),p($.dim(` \u{1F4C2} ${e}/`)),p($.dim(" \u251C\u2500\u2500 components/")),p($.dim(" \u251C\u2500\u2500 hooks/")),p($.dim(" \u251C\u2500\u2500 types/")),t.createStore&&p($.dim(" \u251C\u2500\u2500 store/")),t.createService&&p($.dim(" \u251C\u2500\u2500 services/")),p($.dim(` \u2514\u2500\u2500 index.ts
|
|
422
|
+
`)),p($.cyan("Next steps:"));let r=o.replace(/^src\//,"@/");p($.dim(` 1. Import and use the feature: import { ${t.featureName} } from '${r}/${t.featureName}'`)),t.createStore&&p($.dim(` 2. Customize your Redux slice in: ${e}/store/`)),t.createService&&p($.dim(` 3. Add API methods in: ${e}/services/${t.featureName}.service.ts`)),p("")};import j from"picocolors";import pe from"node:path";import{existsSync as en}from"node:fs";import{mkdir as tn}from"node:fs/promises";import Zi from"enquirer";var{prompt:Qi}=Zi,vo=async(t,o,e)=>{let r=[];t||r.push({type:"input",name:"sliceName",message:"What is the slice name?",initial:"my-slice",validate:i=>/^[a-z0-9-]+$/.test(i)?!0:"Slice name must be lowercase and contain only alphanumeric characters and hyphens."}),o===void 0&&e===void 0&&r.push({type:"confirm",name:"persistSlice",message:"Enable persistence for this slice?",initial:!1});let n=r.length>0?await Qi(r):{};return{sliceName:t||n.sliceName,persistSlice:o===!0?!0:e===!1?!1:n.persistSlice||!1}};W();var To=t=>{t.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(o,e)=>{try{let r=process.cwd();e.persist&&e.noPersist===!0&&(C("Cannot use --persist and --no-persist together"),process.exit(1)),p(j.cyan(`
|
|
413
423
|
\u{1F527} Slice Generator
|
|
414
424
|
`)),g.start("Detecting project setup...");let n=await _(r);g.succeed("Project setup detected"),n.hasRedux||(g.fail("Redux is not setup in this project"),C("Please install @reduxjs/toolkit and react-redux first"),p(j.dim(`
|
|
415
425
|
Run: npm install @reduxjs/toolkit react-redux
|
|
416
426
|
`)),process.exit(1)),p(j.dim(` Redux: \u2713
|
|
417
|
-
`));let i=await vo(o,
|
|
418
|
-
\u2728 Slice '${
|
|
419
|
-
`)),p(j.dim("Generated files:")),p(j.dim(` \u{1F4C2} ${
|
|
420
|
-
`)),p(j.cyan("Next steps:"));let r=o.replace(/^src\//,"@/");p(j.dim(` 1. Import actions: import { setLoading, setError } from '${r}/${
|
|
427
|
+
`));let i=await vo(o,e.persist,e.noPersist===!0?!1:void 0),{basePath:s,slicePath:c}=on(r,i.sliceName,e.path),m=pe.join(r,s);en(m)||await tn(m,{recursive:!0}),await Q(r,i.sliceName,s)&&(C(`Slice '${i.sliceName}' already exists at ${s}!`),process.exit(1)),await re(gt(),{projectPath:r,spinner:g,sliceName:i.sliceName,basePath:s,slicePath:c,persistSlice:i.persistSlice}),rn(i,s)}catch(r){g.fail("Slice generation failed"),C(`${r}`),process.exit(1)}})},on=(t,o,e)=>{let r;if(e){let n=e.replace(/^src\//,"");if(n.startsWith("features/")){let i=n.split("/")[1];r=pe.join("src","features",i,"store")}else r=pe.join("src",n)}else r=pe.join("src","features",o,"store");return{basePath:r,slicePath:pe.join(t,r,o)}},rn=(t,o)=>{let e=pe.join(o,t.sliceName);p(j.green(`
|
|
428
|
+
\u2728 Slice '${t.sliceName}' created successfully!
|
|
429
|
+
`)),p(j.dim("Generated files:")),p(j.dim(` \u{1F4C2} ${e}/`)),p(j.dim(` \u251C\u2500\u2500 ${t.sliceName}.slice.ts`)),p(j.dim(` \u251C\u2500\u2500 ${t.sliceName}.selectors.ts`)),t.persistSlice&&p(j.dim(" \u251C\u2500\u2500 persist.ts")),p(j.dim(` \u251C\u2500\u2500 ${t.sliceName}.types.ts`)),p(j.dim(` \u2514\u2500\u2500 index.ts
|
|
430
|
+
`)),p(j.cyan("Next steps:"));let r=o.replace(/^src\//,"@/");p(j.dim(` 1. Import actions: import { setLoading, setError } from '${r}/${t.sliceName}'`)),p(j.dim(" 2. Use in component: dispatch(setLoading(true))")),p("")};import H from"picocolors";import we from"node:path";import{existsSync as cn}from"node:fs";import{mkdir as pn}from"node:fs/promises";import Eo from"enquirer";var Io=async(t,o,e,r)=>{let n=t||(await Eo.prompt({type:"input",name:"serviceName",message:"Service name (kebab-case):",validate:s=>s?/^[a-z0-9-]+$/.test(s)?!0:"Service name must be lowercase with hyphens only":"Service name is required"})).serviceName,i;return o!==void 0?i="axios":e!==void 0?i="fetch":r==="axios"?i="axios":r==="fetch"?i="fetch":r==="both"?i=(await Eo.prompt({type:"select",name:"httpClient",message:"Choose HTTP client:",choices:["axios","fetch"]})).httpClient:i="axios",{serviceName:n,httpClient:i}};W();import{readFile as nn,writeFile as sn}from"node:fs/promises";import an from"node:path";var No=async(t,o)=>{let e=k(o),r=an.join(t,"src","lib","config","app-apis.ts");try{let n=await nn(r,"utf-8");if(n.includes(`${e}:`))return;if(!n.match(/export const AppApis = \{[\s\S]*?\} as const;/))throw new Error("Could not find AppApis object in app-apis.ts");let i=uo({camelName:e,kebabName:o});n=xe(n,i),await sn(r,n)}catch(n){throw new Error(`Failed to register CRUD API endpoints: ${n}`,{cause:n})}};var Ro=t=>{t.command("service [name]").description("Generate an API service").option("--path <path>","Custom path for service generation (default: create new feature)").option("--axios","Use Axios HTTP client").option("--fetch","Use Fetch HTTP client").option("--crud","Generate full CRUD service (getAll, getById, create, update, delete)").action(async(o,e)=>{try{let r=process.cwd();e.axios&&e.fetch&&(C("Cannot use --axios and --fetch together"),process.exit(1)),p(H.cyan(`
|
|
421
431
|
\u{1F527} Service Generator
|
|
422
432
|
`)),g.start("Detecting project setup...");let n=await _(r);g.succeed("Project setup detected"),n.httpClient==="none"&&(g.fail("No HTTP client is setup in this project"),C("Please setup either AxiosClient or FetchClient first"),p(H.dim(`
|
|
423
433
|
Check: lib/utils/http/axios-client or lib/utils/http/fetch-client
|
|
424
434
|
`)),process.exit(1));let i=[];(n.httpClient==="axios"||n.httpClient==="both")&&i.push("Axios \u2713"),(n.httpClient==="fetch"||n.httpClient==="both")&&i.push("Fetch \u2713"),p(H.dim(` HTTP Clients: ${i.join(", ")}
|
|
425
|
-
`));let s=await Io(o,
|
|
426
|
-
\u2728 ${
|
|
435
|
+
`));let s=await Io(o,e.axios,e.fetch,n.httpClient),{basePath:c,servicePath:m}=mn(r,s.serviceName,e.path);cn(m)||await pn(m,{recursive:!0}),Ae(r,c,`${s.serviceName}.service.ts`)&&(C(`Service '${s.serviceName}' already exists at ${c}!`),process.exit(1)),e.crud?(g.start("Generating CRUD service files..."),await tt({name:s.serviceName,outputPath:m,httpClient:s.httpClient}),g.succeed("CRUD service files generated"),g.start("Registering CRUD API endpoints..."),await No(r,s.serviceName),g.succeed("CRUD API endpoints registered")):await re(ht(),{projectPath:r,spinner:g,serviceName:s.serviceName,servicePath:m,httpClient:s.httpClient}),ln(s,c,!!e.crud)}catch(r){g.fail("Service generation failed"),C(`${r}`),process.exit(1)}})},mn=(t,o,e)=>{let r;if(e){let n=e.replace(/^src\//,"");if(n.startsWith("features/")){let i=n.split("/")[1];r=we.join("src","features",i,"services")}else r=we.join("src",n)}else r=we.join("src","features",o,"services");return{basePath:r,servicePath:we.join(t,r)}},ln=(t,o,e=!1)=>{let r=we.join(o,`${t.serviceName}.service.ts`);p(H.green(`
|
|
436
|
+
\u2728 ${e?"CRUD ":""}Service '${t.serviceName}' created successfully!
|
|
427
437
|
`)),p(H.dim("Generated files:")),p(H.dim(` \u{1F4C4} ${r}
|
|
428
|
-
`)),p(H.cyan("Next steps:"));let n=o.replace(/^src\//,"@/");p(H.dim(` 1. Import service: import { ${
|
|
429
|
-
`,await u(o,
|
|
430
|
-
`),
|
|
431
|
-
`+
|
|
432
|
-
`+
|
|
433
|
-
<CustomThemeProvider>`),
|
|
434
|
-
</StoreProvider>`);else{let i=
|
|
438
|
+
`)),p(H.cyan("Next steps:"));let n=o.replace(/^src\//,"@/");p(H.dim(` 1. Import service: import { ${t.serviceName}Service } from '${n}/${t.serviceName}.service'`)),e?(p(H.dim(" 2. Available methods: getAll, getById, create, update, delete")),p(H.dim(" 3. Update DTO types in the service file"))):p(H.dim(` 2. Use in component: const data = await ${t.serviceName}Service.getAll()`)),p("")};import He from"picocolors";import Nn from"enquirer";P();import un from"node:path";import fn from"picocolors";P();T();import Se from"node:path";P();T();import $o from"node:path";var ke=async t=>{let o=[$o.join(t,a.ROOT_LAYOUT),$o.join(t,"src/app/[locale]/layout.tsx")];for(let e of o)if(l(e)&&(await d(e)).includes("<body"))return e;for(let e of o)if(l(e))return e;return""};var Ao=async t=>{let o=Se.join(t,a.THEME_PROVIDER),e=Se.join(t,a.GLOBALS_CSS),r=Se.join(t,"package.json");if(l(o))return{isSetup:!0,reason:"CustomThemeProvider.tsx exists"};if(l(r)){let n=JSON.parse(await d(r));if(n.dependencies&&n.dependencies["next-themes"]||n.devDependencies&&n.devDependencies["next-themes"])return{isSetup:!0,reason:"next-themes is installed"}}return l(e)&&(await d(e)).includes("@custom-variant dark")?{isSetup:!0,reason:"Dark theme CSS found in globals.css"}:{isSetup:!1,reason:""}},bo=async t=>{let o=Se.join(t,a.GLOBALS_CSS),e=Se.join(t,a.PROVIDERS_INDEX),r=await ke(t);if(!l(o)||!r||!l(e))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};P();T();import Oo from"node:path";import dn from"degit";var ko=async(t,o)=>{o.text="Fetching assets from starter repo...",await dn("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(t)},_o=async(t,o)=>{let e=Oo.join(t,a.THEME_PROVIDER),r=Oo.join(o,"src/providers/CustomThemeProvider.tsx");await O(r,e)};P();T();import _e from"node:path";var jo=async t=>{let o=_e.join(t,a.PROVIDERS_INDEX),e=await d(o);e.includes("CustomThemeProvider")||(e+=`export * from './CustomThemeProvider';
|
|
439
|
+
`,await u(o,e))},Fo=async t=>{let o=_e.join(t,"src/providers/RootProvider.tsx");if(l(o)){let e=await d(o),r="'use client';",n=e.includes(r);if(n&&(e=e.replace(r,"").trim()),e.includes("CustomThemeProvider")||(e=e.replace(/import \{ StoreProvider \} from '@\/providers';\n/,`import { StoreProvider, CustomThemeProvider } from '@/providers';
|
|
440
|
+
`),e.includes("CustomThemeProvider")||(e.includes("from '@/providers'")?e=e.replace(/\} from '@\/providers'/,", CustomThemeProvider } from '@/providers'"):e=`import { CustomThemeProvider } from '@/providers';
|
|
441
|
+
`+e)),n&&(e=r+`
|
|
442
|
+
`+e),!e.includes("<CustomThemeProvider>")){if(e.includes("<StoreProvider>"))e=e.replace(/<StoreProvider>/,`<StoreProvider>
|
|
443
|
+
<CustomThemeProvider>`),e=e.replace(/<\/StoreProvider>/,`</CustomThemeProvider>
|
|
444
|
+
</StoreProvider>`);else{let i=e.match(/return\s*(?:\(\s*)?([\s\S]*?)(?:\s*\))?;/);if(i){let s=i[1];e=e.replace(i[0],`return (
|
|
435
445
|
<CustomThemeProvider>
|
|
436
446
|
${s}
|
|
437
447
|
</CustomThemeProvider>
|
|
438
|
-
);`)}}await u(o,
|
|
448
|
+
);`)}}await u(o,e)}}},Do=async(t,o)=>{let e=_e.join(t,a.GLOBALS_CSS),r=_e.join(o,"src/styles/globals.css"),n="";if(l(r)){let s=await d(r),c=s.match(/@custom-variant dark \(.*?\);/),m=s.match(/@theme \{[\s\S]*?\}/);c&&(n+=`
|
|
439
449
|
${c[0]}
|
|
440
450
|
`),m&&(n+=`
|
|
441
451
|
${m[0]}
|
|
@@ -446,32 +456,32 @@ ${m[0]}
|
|
|
446
456
|
--color-dark: #202938;
|
|
447
457
|
--color-light: #f5f5f5;
|
|
448
458
|
}
|
|
449
|
-
`);let i=await d(
|
|
450
|
-
`,s);i=i.slice(0,c+1)+n+i.slice(c+1)}else i=n+i;await u(
|
|
451
|
-
`,await u(o,
|
|
452
|
-
`+
|
|
453
|
-
`+
|
|
459
|
+
`);let i=await d(e);if(!i.includes("@custom-variant dark")){if(i.includes("@import")){let s=i.lastIndexOf("@import"),c=i.indexOf(`
|
|
460
|
+
`,s);i=i.slice(0,c+1)+n+i.slice(c+1)}else i=n+i;await u(e,i)}},Lo=async t=>{let o=await d(t);o.includes("dark:bg-dark")||(o=o.replace(/className="([^"]*)"/,'className="$1 bg-light dark:bg-dark"'),await u(t,o))};var yt=async t=>{let o=A("Setting up Dark Theme..."),e=un.join(t,".next-maker-temp");try{let{isSetup:r,reason:n}=await Ao(t);if(r){o.fail(`Dark Theme is already set up (${n}).`);return}let i=await bo(t);await ko(e,o),await _o(t,e),await jo(t),await Fo(t),await Do(t,e),await Lo(i),o.text="Installing next-themes...",await F(t,"next-themes"),o.text="Formatting code...";let s=await U(t);await D(t,s,"format"),o.succeed(fn.green("Dark Theme setup successfully!"))}catch(r){throw o.fail("Failed to setup Dark Theme."),r}finally{await h(e)}};P();import hn from"node:path";import xn from"picocolors";P();T();import Pt from"node:path";var Ho=async t=>{let o=Pt.join(t,a.STORE),e=Pt.join(t,"package.json");if(l(o))return{isSetup:!0,reason:"src/store directory exists"};if(l(e)){let r=JSON.parse(await d(e));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:""}},Go=async t=>{let o=Pt.join(t,a.PROVIDERS_INDEX);if(!await ke(t)||!l(o))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx (or src/app/[locale]/layout.tsx) and src/providers/index.ts exist.")};P();T();import ne from"node:path";import gn from"degit";import Mo from"node:fs/promises";var Uo=async(t,o)=>{o.text="Fetching assets from starter repo...",await gn("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(t)},Xo=async(t,o)=>{let e=ne.join(o,"src/providers/StoreProvider.tsx"),r=ne.join(t,a.STORE_PROVIDER);await O(e,r);let n=ne.join(o,"src/store"),i=ne.join(t,a.STORE);await Mo.cp(n,i,{recursive:!0})},Jo=async(t,o)=>{let e=ne.join(o,"src/features/counter"),r=ne.join(t,a.COUNTER_FEATURE);await Mo.cp(e,r,{recursive:!0});let n=ne.join(r,"components/Counter.tsx");if(await l(n)){let i=await d(n);i=i.replace(/import \{ useTranslations \} from 'next-intl';\n?/,""),i=i.replace(/const t = useTranslations\('Count'\);\n?/,""),i=i.replace(/\{t\('currentCount', \{ count: value \}\)\}/g,"Current Count: {value}"),i=i.replace(/\{t\('increment'\)\}/g,"Increment"),i=i.replace(/\{t\('decrement'\)\}/g,"Decrement"),i=i.replace(/\{t\('reset'\)\}/g,"Reset"),await u(n,i)}};P();T();import je from"node:path";var Yo=async t=>{let o=je.join(t,a.PROVIDERS_INDEX),e=await d(o);e.includes("StoreProvider")||(e+=`export * from './StoreProvider';
|
|
461
|
+
`,await u(o,e))},zo=async t=>{let o=je.join(t,"src/providers/RootProvider.tsx");if(l(o)){let e=await d(o),r="'use client';",n=e.includes(r);if(n&&(e=e.replace(r,"").trim()),e.includes("StoreProvider")||(e=e.replace(/import \{ (.*?) \} from '@\/providers';/,"import { $1, StoreProvider } from '@/providers';"),e.includes("StoreProvider")||(e.includes("from '@/providers'")?e=e.replace(/\} from '@\/providers'/,", StoreProvider } from '@/providers'"):e=`import { StoreProvider } from '@/providers';
|
|
462
|
+
`+e)),n&&(e=r+`
|
|
463
|
+
`+e),!e.includes("<StoreProvider>")){let i=e.match(/return\s*(?:\(\s*)?([\s\S]*?)(?:\s*\))?;/);if(i){let s=i[1];e=e.replace(i[0],`return (
|
|
454
464
|
<StoreProvider>
|
|
455
465
|
${s}
|
|
456
466
|
</StoreProvider>
|
|
457
|
-
);`),await u(o,
|
|
467
|
+
);`),await u(o,e)}}}},Wo=async t=>{let o=[je.join(t,a.ROOT_PAGE),je.join(t,"src/app/[locale]/page.tsx")],e="";for(let r of o)if(l(r)){e=r;break}if(e){let r=await d(e);if(r.includes("Counter")||(r=`import { Counter } from '@/features/counter/components/Counter';
|
|
458
468
|
`+r),!r.includes("<Counter />")){let n=r.lastIndexOf("</div>"),i=r.lastIndexOf("</main>"),s=i!==-1?i:n;s!==-1&&(r=r.slice(0,s)+`
|
|
459
469
|
<div className="mt-8">
|
|
460
470
|
<h2 className="text-2xl font-bold mb-4">Redux Counter</h2>
|
|
461
471
|
<Counter />
|
|
462
472
|
</div>
|
|
463
|
-
`+r.slice(s),await u(
|
|
464
|
-
`+
|
|
473
|
+
`+r.slice(s),await u(e,r))}}};var wt=async t=>{let o=A("Setting up Redux Toolkit..."),e=hn.join(t,".next-maker-temp-redux");try{let{isSetup:r,reason:n}=await Ho(t);if(r){o.fail(`Redux is already set up (${n}).`);return}await Go(t),await Uo(e,o),o.text="Copying Redux files...",await Xo(t,e),o.text="Creating Counter feature...",await Jo(t,e),o.text="Updating providers and pages...",await Yo(t),await zo(t),await Wo(t),o.text="Installing dependencies...",await F(t,"@reduxjs/toolkit"),await F(t,"react-redux"),await F(t,"redux-persist"),await F(t,"react-secure-storage"),o.text="Formatting code...";let i=await U(t);await D(t,i,"format"),o.succeed(xn.green("Redux Toolkit setup successfully!"))}catch(r){throw o.fail("Failed to setup Redux Toolkit."),r}finally{await h(e)}};P();import Sn from"node:path";import Cn from"picocolors";P();T();import Fe from"node:path";var Bo=async t=>{let o=Fe.join(t,a.I18N_DIR),e=Fe.join(t,"package.json");if(l(o))return{isSetup:!0,reason:"src/i18n directory exists"};if(l(e)){let r=JSON.parse(await d(e));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:""}},Vo=async t=>{let o=Fe.join(t,a.ROOT_LAYOUT),e=Fe.join(t,"src/app/[locale]/layout.tsx");if(!l(o)&&!l(e))throw new Error("Project structure mismatch. Ensure src/app/layout.tsx exists.")};P();T();import ee from"node:path";import yn from"degit";import Pn from"node:fs/promises";var qo=async(t,o)=>{o.text="Fetching assets from starter repo...",await yn("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(t)},Ko=async(t,o)=>{let e=ee.join(o,"src/i18n"),r=ee.join(t,a.I18N_DIR);await Pn.cp(e,r,{recursive:!0});let n=ee.join(o,"src/proxy.ts"),i=ee.join(t,a.PROXY);await O(n,i);let s=ee.join(o,"src/types/i18n.ts"),c=ee.join(t,a.I18N_TYPES);await O(s,c);let m=ee.join(o,"src/lib/config/app-locales.ts"),f=ee.join(t,a.APP_LOCALES);await O(m,f)};P();T();import B from"node:path";import wn from"node:fs/promises";var Zo=async t=>{let o=B.join(t,a.NEXT_CONFIG);if(l(o)){let e=await d(o);if(!e.includes("createNextIntlPlugin")){e=`import createNextIntlPlugin from 'next-intl/plugin';
|
|
474
|
+
`+e;let r=/export default (.*?);/;r.test(e)?e=e.replace(r,`
|
|
465
475
|
const withNextIntl = createNextIntlPlugin();
|
|
466
|
-
export default withNextIntl($1);`):(
|
|
476
|
+
export default withNextIntl($1);`):(e+=`
|
|
467
477
|
const withNextIntl = createNextIntlPlugin();
|
|
468
|
-
`,
|
|
469
|
-
`),await u(o,
|
|
470
|
-
`,await u(o,
|
|
471
|
-
`,await u(o,
|
|
478
|
+
`,e+=`export default withNextIntl(nextConfig);
|
|
479
|
+
`),await u(o,e)}}},Qo=async t=>{let o=B.join(t,a.TYPES_INDEX);if(l(o)){let e=await d(o);e.includes("./i18n")||(e+=`export * from './i18n';
|
|
480
|
+
`,await u(o,e))}},er=async t=>{let o=B.join(t,a.CONFIG_INDEX);if(l(o)){let e=await d(o);e.includes("./app-locales")||(e+=`export * from './app-locales';
|
|
481
|
+
`,await u(o,e))}},tr=async t=>{let o=B.join(t,"src/providers/RootProvider.tsx");if(l(o)){let e=await d(o),r="'use client';",n=e.includes(r);if(n&&(e=e.replace(r,"").trim()),e.includes("next-intl")||(e=`import { SupportedLocale } from '@/types/i18n';
|
|
472
482
|
import { NextIntlClientProvider, AbstractIntlMessages } from 'next-intl';
|
|
473
|
-
`+
|
|
474
|
-
`+
|
|
483
|
+
`+e),n&&(e=r+`
|
|
484
|
+
`+e),!e.includes("locale: SupportedLocale")){let i=/export const RootProvider = \(\{([\s\S]*?)\}: \{([\s\S]*?)\}\) => \{/,s=e.match(i);s&&(e=e.replace(s[0],`export const RootProvider = ({
|
|
475
485
|
children,
|
|
476
486
|
locale,
|
|
477
487
|
messages,
|
|
@@ -479,15 +489,15 @@ import { NextIntlClientProvider, AbstractIntlMessages } from 'next-intl';
|
|
|
479
489
|
children: React.ReactNode;
|
|
480
490
|
locale: SupportedLocale;
|
|
481
491
|
messages: AbstractIntlMessages;
|
|
482
|
-
}) => {`))}if(!
|
|
492
|
+
}) => {`))}if(!e.includes("<NextIntlClientProvider")){let i=e.match(/return\s*(?:\(\s*)?([\s\S]*?)(?:\s*\))?;/);if(i){let s=i[1];if(s.includes("{children}")){let c=s.replace("{children}",`<NextIntlClientProvider locale={locale} messages={messages}>
|
|
483
493
|
{children}
|
|
484
|
-
</NextIntlClientProvider>`);
|
|
494
|
+
</NextIntlClientProvider>`);e=e.replace(i[0],`return (
|
|
485
495
|
${c}
|
|
486
|
-
);`)}else
|
|
496
|
+
);`)}else e=e.replace(i[0],`return (
|
|
487
497
|
<NextIntlClientProvider locale={locale} messages={messages}>
|
|
488
498
|
${s}
|
|
489
499
|
</NextIntlClientProvider>
|
|
490
|
-
);`)}}await u(o,
|
|
500
|
+
);`)}}await u(o,e)}},or=async t=>{let o=B.join(t,a.ROOT_LAYOUT),e=B.join(t,a.ROOT_PAGE),r=B.join(t,"src/app/[locale]");if(await wn.mkdir(r,{recursive:!0}),l(o)){let n=B.join(r,"layout.tsx"),i=await d(o);if(i.includes("next-intl")||(i=`import { routing } from '@/i18n/routing';
|
|
491
501
|
import { hasLocale } from 'next-intl';
|
|
492
502
|
import { notFound } from 'next/navigation';
|
|
493
503
|
import { setRequestLocale, getMessages } from 'next-intl/server';
|
|
@@ -508,7 +518,7 @@ export function generateStaticParams() {
|
|
|
508
518
|
setRequestLocale(locale);
|
|
509
519
|
|
|
510
520
|
const messages = await getMessages();
|
|
511
|
-
`+i.slice(S+1)}i=i.replace(/<RootProvider>/,"<RootProvider locale={locale} messages={messages}>"),i=i.replace(/<html lang="en"/,"<html lang={locale}")}await u(n,i),await
|
|
521
|
+
`+i.slice(S+1)}i=i.replace(/<RootProvider>/,"<RootProvider locale={locale} messages={messages}>"),i=i.replace(/<html lang="en"/,"<html lang={locale}")}await u(n,i),await w(o)}if(l(e)){let n=B.join(r,"page.tsx"),i=await d(e);i.includes("next-intl")||(i=`import { SupportedLocale } from '@/types/i18n';
|
|
512
522
|
import { setRequestLocale } from 'next-intl/server';
|
|
513
523
|
`+i),i=i.replace(/export default function Home\(\)/,`type Props = {
|
|
514
524
|
params: Promise<{ locale: string }>;
|
|
@@ -517,36 +527,36 @@ import { setRequestLocale } from 'next-intl/server';
|
|
|
517
527
|
export default async function Home(props: Props)`);let s=i.indexOf("export default async function Home(props: Props) {");if(s!==-1){let c=`
|
|
518
528
|
const locale = (await props.params).locale as SupportedLocale;
|
|
519
529
|
setRequestLocale(locale);
|
|
520
|
-
`,m=i.indexOf("{",s);i=i.slice(0,m+1)+c+i.slice(m+1)}await u(n,i),await
|
|
521
|
-
${
|
|
522
|
-
`)}`)};
|
|
530
|
+
`,m=i.indexOf("{",s);i=i.slice(0,m+1)+c+i.slice(m+1)}await u(n,i),await w(e)}};var St=async t=>{let o=A("Setting up Internationalization (next-intl)..."),e=Sn.join(t,".next-maker-temp-i18n");try{let{isSetup:r,reason:n}=await Bo(t);if(r){o.fail(`i18n is already set up (${n}).`);return}await Vo(t),await qo(e,o),o.text="Copying i18n files...",await Ko(t,e),o.text="Configuring project structure...",await Zo(t),await Qo(t),await er(t),await tr(t),o.text="Migrating to [locale] structure...",await or(t),o.text="Installing dependencies...",await F(t,"next-intl"),o.text="Formatting code...";let i=await U(t);await D(t,i,"format"),o.succeed(Cn.green("Internationalization setup successfully!"))}catch(r){throw o.fail("Failed to setup Internationalization."),r}finally{await h(e)}};P();import De from"node:path";import Tn from"node:fs/promises";import Ct from"picocolors";import Le from"enquirer";P();T();import Ce from"node:path";var rr=async t=>{let o=Ce.join(t,a.FETCH_CLIENT_FILE),e=Ce.join(t,a.AXIOS_CLIENT_FILE),r=l(o),n=l(e);return r&&n?{status:"both",reason:"Both Fetch and Axios clients are detected"}:r?{status:"fetch",reason:"Fetch client is already setup"}:n?{status:"axios",reason:"Axios client is already setup"}:{status:"none"}},ir=async t=>{let e=[Ce.join(t,"src/lib"),Ce.join(t,"src/types"),Ce.join(t,"src/lib/config")].filter(r=>!l(r));if(e.length>0)throw new Error(`Invalid project structure. Missing directories:
|
|
531
|
+
${e.map(r=>`- ${r}`).join(`
|
|
532
|
+
`)}`)};P();T();import y from"node:path";import vn from"degit";import V from"node:fs/promises";var nr=async(t,o)=>{o.text="Downloading assets from starter repository...",await vn("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(t)},sr=async(t,o,e,r)=>{let n=y.join(t,a.HTTP_UTILS),i=y.join(o,a.HTTP_UTILS);await V.cp(y.join(o,a.ERRORS_DIR),y.join(t,a.ERRORS_DIR),{recursive:!0});let s=y.join(t,a.APP_APIS);l(s)||await O(y.join(o,a.APP_APIS),s);let c=y.join(t,a.CONSTANTS);if(!l(c))await O(y.join(o,a.CONSTANTS),c);else{let f=await d(c),x=!1;f.includes("API_RESPONSE_DATA_KEY")||(f+=`
|
|
523
533
|
export const API_RESPONSE_DATA_KEY = 'data';
|
|
524
534
|
`,x=!0),f.includes("SAVE_AUTH_TOKENS")||(f+=`
|
|
525
535
|
export const SAVE_AUTH_TOKENS = false;
|
|
526
|
-
`,x=!0),x&&await u(c,f)}let m=y.join(
|
|
536
|
+
`,x=!0),x&&await u(c,f)}let m=y.join(t,a.STORAGE_SERVICE);if(l(m)||await V.cp(y.join(o,a.STORAGE_SERVICE),m,{recursive:!0}),await V.cp(y.join(o,a.COMMON_TYPES_DIR),y.join(t,a.COMMON_TYPES_DIR),{recursive:!0}),await V.cp(y.join(o,a.UTILITY_TYPES_DIR),y.join(t,a.UTILITY_TYPES_DIR),{recursive:!0}),await O(y.join(i,"token-store.ts"),y.join(n,"token-store.ts")),await O(y.join(i,"client-utils.ts"),y.join(n,"client-utils.ts")),r&&r.length>0)for(let f of r){let x=y.join(t,f==="fetch"?a.FETCH_CLIENT:a.AXIOS_CLIENT);await h(x)}for(let f of e)f==="fetch"?await V.cp(y.join(o,a.FETCH_CLIENT),y.join(t,a.FETCH_CLIENT),{recursive:!0}):await V.cp(y.join(o,a.AXIOS_CLIENT),y.join(t,a.AXIOS_CLIENT),{recursive:!0});await O(y.join(i,"index.ts"),y.join(n,"index.ts")),await O(y.join(o,a.HTTP_TYPES),y.join(t,a.HTTP_TYPES))},ar=async t=>{let{isFileUsed:o,isStringUsed:e}=await Promise.resolve().then(()=>(Re(),_t));await h(y.join(t,a.HTTP_UTILS));let r=y.join(t,a.STORAGE_SERVICE);l(r)&&(await e(t,"SecureStorageService",[r])||await h(r));let n=y.join(t,a.CONSTANTS);if(l(n)){let m=await d(n),f=!1;await e(t,"API_RESPONSE_DATA_KEY",[n])||(m=m.replace(/export const API_RESPONSE_DATA_KEY = .*;\n?/g,""),f=!0),await e(t,"SAVE_AUTH_TOKENS",[n])||(m=m.replace(/export const SAVE_AUTH_TOKENS = .*;\n?/g,""),f=!0),f&&(m=m.replace(/\n\s*\n/g,`
|
|
527
537
|
|
|
528
538
|
`).trim()+`
|
|
529
|
-
`,await u(n,m))}let i=y.join(
|
|
539
|
+
`,await u(n,m))}let i=y.join(t,a.ERRORS_DIR);if(l(i)){let m=await V.readdir(i),f=!1;for(let x of m){let S=y.parse(x).name;if(await o(t,S,[y.join(i,x)])){f=!0;break}}f||await h(i)}let s=y.join(t,a.COMMON_TYPES_DIR);l(s)&&(await V.readdir(s)).length===0&&await h(s);let c=y.join(t,a.UTILITY_TYPES_DIR);l(c)&&(await V.readdir(c)).length===0&&await h(c)};Re();var vt=async t=>{let o=A("Checking HTTP Client setup..."),e=De.join(t,".next-maker-temp-http");try{let{status:r,reason:n}=await rr(t);o.stop();let i=await En(r,n);if(i.type==="cancel"){console.log(Ct.yellow("Setup cancelled."));return}if(o.start("Setting up HTTP client(s)..."),await ir(t),await nr(e,o),i.type==="replace"&&i.fromClient&&(o.text="Migrating client usages...",await Ve(t,i.fromClient,i.clients[0])),i.type!=="remove-both"&&i.type!=="remove-one"){o.text="Copying client files...";let M=i.type==="replace"&&i.fromClient?[i.fromClient]:void 0;await sr(t,e,i.clients,M)}if(i.type==="remove-one"||i.type==="remove-both"){o.text="Removing client files...";let{PROJECT_PATHS:M}=await Promise.resolve().then(()=>(T(),Ot));for(let Te of i.clients){let Ee=De.join(t,Te==="fetch"?M.FETCH_CLIENT:M.AXIOS_CLIENT);await h(Ee)}cr(r,i).length===0&&(o.text="Performing full cleanup...",await ar(t),await qe(t))}let s=cr(r,i);s.length>0&&(o.text="Configuring client...",await Ye(t,s),await ze(t),await We(t),await Be(t)),await ae(t,s),o.text="Managing dependencies...";let c=De.join(t,"package.json"),m=JSON.parse(await Tn.readFile(c,"utf-8")),f={...m.dependencies,...m.devDependencies};s.includes("axios")?f.axios||(o.text="Installing Axios...",await F(t,"axios")):f.axios&&(o.text="Uninstalling Axios...",await Xe(t,"axios"));let x=De.join(t,"src/services/storage");s.length>0||l(x)?f["react-secure-storage"]||(o.text="Installing react-secure-storage...",await F(t,"react-secure-storage")):f["react-secure-storage"]&&(o.text="Uninstalling react-secure-storage...",await Xe(t,"react-secure-storage")),o.text="Formatting code...";let v=await U(t);await D(t,v,"format"),o.succeed(Ct.green(In(i)))}catch(r){throw o.fail("Failed to setup HTTP Client."),r}finally{await h(e)}};async function En(t,o){if(t==="none"){let{choice:r}=await Le.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(t==="fetch"){let{action:r}=await Le.prompt({type:"select",name:"action",message:`${o}. 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(t==="axios"){let{action:r}=await Le.prompt({type:"select",name:"action",message:`${o}. 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(Ct.yellow(`\u2716 ${o}`));let{action:e}=await Le.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 e==="cancel"?{type:"cancel",clients:[]}:e==="remove-fetch"?{type:"remove-one",clients:["fetch"]}:e==="remove-axios"?{type:"remove-one",clients:["axios"]}:e==="remove-both"?{type:"remove-both",clients:["fetch","axios"]}:{type:"cancel",clients:[]}}function cr(t,o){return o.type==="install"?o.clients:o.type==="add"?[...t==="fetch"?["fetch"]:["axios"],...o.clients]:o.type==="replace"?o.clients:o.type==="remove-one"?t==="both"?o.clients[0]==="fetch"?["axios"]:["fetch"]:[]:[]}function In(t){if(t.type==="install")return`HTTP Client (${t.clients.map(e=>e==="fetch"?"Fetch":"Axios").join(" + ")}) setup successfully!`;if(t.type==="add")return`${t.clients[0]==="fetch"?"Fetch":"Axios"} client added successfully! Both clients are now available.`;if(t.type==="replace"){let o=t.fromClient==="fetch"?"Fetch":"Axios",e=t.clients[0]==="fetch"?"Fetch":"Axios";return`Replaced ${o} with ${e} successfully! Imports automatically migrated.`}return t.type==="remove-one"?`${t.clients[0]==="fetch"?"Fetch":"Axios"} client removed successfully!`:t.type==="remove-both"?"Both HTTP clients removed successfully!":"HTTP Client setup completed!"}var{prompt:Rn}=Nn,pr=t=>{t.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 o=>{try{if(p(He.cyan(`
|
|
530
540
|
\u{1F527} Setup Wizard
|
|
531
541
|
`)),o.httpClient||o.darkTheme||o.redux||o.i18n){o.httpClient&&await vt(process.cwd()),o.darkTheme&&await yt(process.cwd()),o.redux&&await wt(process.cwd()),o.i18n&&await St(process.cwd());return}let r=(await Rn([{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"){p(He.yellow("Setup cancelled."));return}r==="dark-theme"?await yt(process.cwd()):r==="redux"?await wt(process.cwd()):r==="http-client"?await vt(process.cwd()):r==="i18n"?await St(process.cwd()):(p(He.yellow(`
|
|
532
|
-
\u26A0\uFE0F ${r} setup is not implemented yet.`)),p(He.dim("This feature will be available in a future update.")))}catch(
|
|
542
|
+
\u26A0\uFE0F ${r} setup is not implemented yet.`)),p(He.dim("This feature will be available in a future update.")))}catch(e){g.fail("Setup failed"),C(`${e}`),process.exit(1)}})};import G from"picocolors";import lr from"node:path";import $n from"enquirer";var{prompt:An}=$n,mr=async t=>{let o=[];t||o.push({type:"input",name:"pageName",message:"Page name (kebab-case):",validate:r=>r?/^[a-z][a-z0-9-]*$/.test(r)?!0:"Use lowercase letters, numbers, and hyphens only":"Page name is required"}),o.push({type:"confirm",name:"withLoading",message:"Generate loading.tsx?",initial:!0},{type:"confirm",name:"withError",message:"Generate error.tsx?",initial:!0});let e=await An(o);return{pageName:t||e.pageName,withLoading:e.withLoading,withError:e.withError}};W();var dr=t=>{t.command("page [name]").description("Generate a new page/route").option("--dynamic <param>","Create dynamic route with parameter (e.g., id)").option("--loading","Generate loading.tsx").option("--error","Generate error.tsx").action(async(o,e)=>{try{let r=process.cwd();p(G.cyan(`
|
|
533
543
|
\u{1F4C4} Page Generator
|
|
534
544
|
`)),g.start("Detecting project setup...");let n=await _(r);g.succeed("Project setup detected"),p(G.dim(` i18n: ${n.hasI18n?"\u2713":"\u2717"}
|
|
535
|
-
`));let i=await mr(o),s=i.pageName,c=N(s),m=n.hasI18n?"src/app/[locale]":"src/app";await Q(r,s,m)&&(C(`Page '${s}' already exists at ${m}/${s}!`),process.exit(1)),g.start("Generating page files..."),await rt({name:s,projectPath:r,hasI18n:n.hasI18n,dynamic:
|
|
545
|
+
`));let i=await mr(o),s=i.pageName,c=N(s),m=n.hasI18n?"src/app/[locale]":"src/app";await Q(r,s,m)&&(C(`Page '${s}' already exists at ${m}/${s}!`),process.exit(1)),g.start("Generating page files..."),await rt({name:s,projectPath:r,hasI18n:n.hasI18n,dynamic:e.dynamic,withLoading:e.loading??i.withLoading,withError:e.error??i.withError}),g.succeed("Page files generated"),g.start("Registering route...");let x=e.dynamic?`/${s}/[${e.dynamic}]`:`/${s}`;await dt(r,s,x),g.succeed("Route registered"),n.hasI18n&&(g.start("Adding translation namespace..."),await ut(r,c),g.succeed("Translation namespace added"));let S=e.dynamic?lr.join(m,s,`[${e.dynamic}]`):lr.join(m,s);p(G.green(`
|
|
536
546
|
\u2728 Page '${s}' created successfully!
|
|
537
|
-
`)),p(G.dim("Generated files:")),p(G.dim(` \u{1F4C2} ${S}/`)),p(G.dim(" \u251C\u2500\u2500 page.tsx")),(
|
|
547
|
+
`)),p(G.dim("Generated files:")),p(G.dim(` \u{1F4C2} ${S}/`)),p(G.dim(" \u251C\u2500\u2500 page.tsx")),(e.loading??i.withLoading)&&p(G.dim(" \u251C\u2500\u2500 loading.tsx")),(e.error??i.withError)&&p(G.dim(" \u2514\u2500\u2500 error.tsx")),p(""),n.hasI18n&&(p(G.cyan("Next steps:")),p(G.dim(` 1. Add translations in: src/i18n/translations/en.json \u2192 "${c}"`)),p(G.dim(` 2. Visit: http://localhost:3000/${s}`)),p(""))}catch(r){g.fail("Page generation failed"),C(`${r}`),process.exit(1)}})};import q from"picocolors";import bn from"enquirer";var{prompt:On}=bn,ur=async t=>{let o=[];t||o.push({type:"input",name:"componentName",message:"Component name (kebab-case):",validate:r=>r?/^[a-z][a-z0-9-]*$/.test(r)?!0:"Use lowercase letters, numbers, and hyphens only":"Component name is required"}),o.push({type:"confirm",name:"isClient",message:"Add 'use client' directive?",initial:!1});let e=await On(o);return{componentName:t||e.componentName,isClient:e.isClient}};W();var fr=t=>{t.command("component [name]").description("Generate a shared component").option("--client","Add 'use client' directive").option("--i18n","Add useTranslations hook").option("--feature <path>","Generate in feature directory (e.g., src/features/auth)").action(async(o,e)=>{try{let r=process.cwd();p(q.cyan(`
|
|
538
548
|
\u{1F9E9} Component Generator
|
|
539
|
-
`)),g.start("Detecting project setup..."),await _(r),g.succeed("Project setup detected");let n=await ur(o),i=N(n.componentName),s=
|
|
549
|
+
`)),g.start("Detecting project setup..."),await _(r),g.succeed("Project setup detected");let n=await ur(o),i=N(n.componentName),s=e.client??n.isClient,c=e.i18n??!1;g.start("Generating component..."),await st({name:n.componentName,projectPath:r,isClient:s||c,hasI18n:c,featurePath:e.feature}),g.succeed("Component generated");let m=e.feature?`${e.feature}/components/${i}.tsx`:`src/components/common/${i}/${i}.tsx`;p(q.green(`
|
|
540
550
|
\u2728 Component '${i}' created successfully!
|
|
541
|
-
`)),p(q.dim(` \u{1F4C4} ${m}`)),
|
|
551
|
+
`)),p(q.dim(` \u{1F4C4} ${m}`)),e.feature||(p(q.dim(` \u{1F4C4} src/components/common/${i}/index.ts`)),p(q.dim(" \u{1F4DD} Updated src/components/common/index.ts")),p(q.dim(" \u{1F4DD} Updated src/components/index.ts"))),p(""),p(q.cyan("Usage:")),e.feature?p(q.dim(` import { ${i} } from '${e.feature.replace(/^src\//,"@/")}/components/${i}';`)):p(q.dim(` import { ${i} } from '@/components';`)),p("")}catch(r){g.fail("Component generation failed"),C(`${r}`),process.exit(1)}})};import Y from"picocolors";import kn from"enquirer";var{prompt:_n}=kn,gr=async t=>{let o=[];t||o.push({type:"input",name:"code",message:"Locale code (e.g., es, fr, de):",validate:r=>r?/^[a-z]{2}(-[A-Z]{2})?$/.test(r)?!0:"Use format: xx or xx-XX (e.g., es, pt-BR)":"Locale code is required"}),o.push({type:"input",name:"name",message:"Language name (e.g., Spanish, French):",validate:r=>r?!0:"Language name is required"},{type:"input",name:"country",message:"Country (e.g., Spain, France):",validate:r=>r?!0:"Country is required"},{type:"input",name:"flag",message:"Flag emoji (e.g., \u{1F1EA}\u{1F1F8}, \u{1F1EB}\u{1F1F7}):",validate:r=>r?!0:"Flag emoji is required"},{type:"confirm",name:"copyTranslations",message:"Copy translations from English? (No = empty values)",initial:!1});let e=await _n(o);return{code:t||e.code,name:e.name,country:e.country,flag:e.flag,copyTranslations:e.copyTranslations}};W();P();import jn from"node:path";var hr=t=>{t.command("locale [code]").description("Add a new locale/language").option("--copy-translations","Copy translations from English instead of empty values").action(async(o,e)=>{try{let r=process.cwd();p(Y.cyan(`
|
|
542
552
|
\u{1F30D} Locale Generator
|
|
543
553
|
`)),g.start("Detecting project setup...");let n=await _(r);g.succeed("Project setup detected"),n.hasI18n||(g.fail("i18n is not set up in this project"),C("Please set up internationalization first"),p(Y.dim(`
|
|
544
554
|
Run: npx @teispace/next-maker setup --i18n
|
|
545
|
-
`)),process.exit(1));let i=await gr(o),s=jn.join(r,"src","i18n","translations",`${i.code}.json`);l(s)&&(C(`Locale '${i.code}' already exists!`),process.exit(1)),g.start("Adding locale..."),await at({...i,projectPath:r,copyTranslations:
|
|
555
|
+
`)),process.exit(1));let i=await gr(o),s=jn.join(r,"src","i18n","translations",`${i.code}.json`);l(s)&&(C(`Locale '${i.code}' already exists!`),process.exit(1)),g.start("Adding locale..."),await at({...i,projectPath:r,copyTranslations:e.copyTranslations??i.copyTranslations}),g.succeed("Locale added"),p(Y.green(`
|
|
546
556
|
\u2728 Locale '${i.code}' (${i.name}) added successfully!
|
|
547
|
-
`)),p(Y.dim("Updated files:")),p(Y.dim(` \u{1F4C4} src/i18n/translations/${i.code}.json`)),p(Y.dim(" \u{1F4DD} src/types/i18n.ts (SupportedLocale type)")),p(Y.dim(" \u{1F4DD} src/lib/config/app-locales.ts")),p(""),p(Y.cyan("Next steps:")),p(Y.dim(` 1. Translate: src/i18n/translations/${i.code}.json`)),p(Y.dim(` 2. Visit: http://localhost:3000/${i.code}`)),p("")}catch(r){g.fail("Locale generation failed"),C(`${r}`),process.exit(1)}})};import ve from"picocolors";import Fn from"enquirer";var{prompt:Dn}=Fn,xr=async
|
|
557
|
+
`)),p(Y.dim("Updated files:")),p(Y.dim(` \u{1F4C4} src/i18n/translations/${i.code}.json`)),p(Y.dim(" \u{1F4DD} src/types/i18n.ts (SupportedLocale type)")),p(Y.dim(" \u{1F4DD} src/lib/config/app-locales.ts")),p(""),p(Y.cyan("Next steps:")),p(Y.dim(` 1. Translate: src/i18n/translations/${i.code}.json`)),p(Y.dim(` 2. Visit: http://localhost:3000/${i.code}`)),p("")}catch(r){g.fail("Locale generation failed"),C(`${r}`),process.exit(1)}})};import ve from"picocolors";import Fn from"enquirer";var{prompt:Dn}=Fn,xr=async t=>t?{hookName:t}:await Dn({type:"input",name:"hookName",message:'Hook name (kebab-case, without "use" prefix):',validate:e=>e?/^[a-z][a-z0-9-]*$/.test(e)?!0:"Use lowercase letters, numbers, and hyphens only":"Hook name is required"});var yr=t=>{t.command("hook [name]").description("Generate a custom React hook").option("--client","Add 'use client' directive (default: true)",!0).option("--feature <path>","Generate in feature directory (e.g., src/features/auth)").action(async(o,e)=>{try{let r=process.cwd();p(ve.cyan(`
|
|
548
558
|
\u{1FA9D} Hook Generator
|
|
549
|
-
`));let n=await xr(o),s=`use${N(n.hookName)}`;g.start("Generating hook..."),await pt({name:n.hookName,projectPath:r,isClient:
|
|
559
|
+
`));let n=await xr(o),s=`use${N(n.hookName)}`;g.start("Generating hook..."),await pt({name:n.hookName,projectPath:r,isClient:e.client??!0,featurePath:e.feature}),g.succeed("Hook generated");let c=e.feature?`${e.feature}/hooks/${s}.ts`:`src/hooks/${s}.ts`;p(ve.green(`
|
|
550
560
|
\u2728 Hook '${s}' created successfully!
|
|
551
|
-
`)),p(ve.dim(` \u{1F4C4} ${c}`)),p(""),p(ve.cyan("Usage:"));let m=
|
|
561
|
+
`)),p(ve.dim(` \u{1F4C4} ${c}`)),p(""),p(ve.cyan("Usage:"));let m=e.feature?`${e.feature.replace(/^src\//,"@/")}/hooks/${s}`:`@/hooks/${s}`;p(ve.dim(` import { ${s} } from '${m}';`)),p("")}catch(r){g.fail("Hook generation failed"),C(`${r}`),process.exit(1)}})};var Pr=t=>{Vt(t),pr(t),Co(t),To(t),Ro(t),dr(t),fr(t),hr(t),yr(t)};var Hn=process.emitWarning;process.emitWarning=function(t,o,e,r){if(!(typeof t=="string"&&t.includes("--localstorage-file")&&t.includes("was provided without a valid path")))return Hn.apply(process,arguments)};async function Gn(){At({logger:o=>Ne(o)});let t=new Ln;t.name("next-maker").description("Teispace Next.js Project Generator").version("1.0.0"),Pr(t),t.parse()}Gn().catch(t=>{let o=t&&typeof t=="object"&&"message"in t?t.message:String(t);Ne(`Unexpected error: ${o}`)});
|
|
552
562
|
//# sourceMappingURL=index.js.map
|