@promakeai/cli 0.4.3 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -494,7 +494,7 @@ constants.json (full)`)),console.log(C.dim(JSON.stringify(B.constantsConfig,null
494
494
  `)),D6("promake create <name>","Create new project"),D6("promake add <modules...>","Add modules"),D6("promake add <page> --module-name <name>","Add page with custom name"),D6("promake remove <modules...>","Remove modules"),D6("promake sync","Sync from promake.json"),D6("promake theme --list","List theme options"),D6("promake theme --preset <name>","Apply color preset"),D6("promake list","List available modules"),D6("promake doctor","Check project health"),D6("promake doctor --runtime","Include runtime checks"),D6("promake discover --json","Project info for AI"),D6("promake seo","Sync SEO meta tags"),D6("promake usage","Show this guide"),D6("promake <command> --help","Command-specific help"),console.log()}var fr=new $5("info").description("Show detailed information about a module").argument("<module>","Module name").option("--json","Output as JSON").action(async(D,X)=>{let Z=E2(`Fetching ${D}...`).start();try{let J=await T4(D);if(Z.stop(),!J)console.error(C.red(`Module not found: ${D}`)),process.exit(1);if(X.json){console.log(JSON.stringify(J,null,2));return}if(console.log(""),console.log(C.bold.cyan(J.name)),console.log(C.dim("─".repeat(J.name.length+4))),J.title)console.log(`${C.gray("Title:")} ${J.title}`);if(console.log(`${C.gray("Type:")} ${J.type.replace("registry:","")}`),J.description)console.log(`${C.gray("Description:")} ${J.description}`);if(J.registryDependencies?.length)console.log(""),console.log(C.gray("Dependencies:")),J.registryDependencies.forEach((Y)=>{let $=!Y.includes("-")||["button","card","input","badge","dialog","sheet","dropdown-menu","accordion","tabs","select","checkbox","slider","separator","avatar","tooltip","popover","navigation-menu","scroll-area"].includes(Y)?C.dim("(shadcn)"):"";console.log(` ${C.yellow("•")} ${Y} ${$}`)});if(J.dependencies?.length)console.log(""),console.log(C.gray("NPM Packages:")),J.dependencies.forEach((Y)=>{console.log(` ${C.blue("•")} ${Y}`)});if(J.files?.length)console.log(""),console.log(C.gray("Files:")),J.files.forEach((Y)=>{console.log(` ${C.dim("•")} ${Y.path}`)});if(J.exports){if(console.log(""),console.log(C.gray("Exports:")),J.exports.types?.length)console.log(` ${C.magenta("Types:")} ${J.exports.types.join(", ")}`);if(J.exports.variables?.length)console.log(` ${C.green("Components:")} ${J.exports.variables.join(", ")}`)}if(J.route)console.log(""),console.log(C.gray("Route:")),console.log(` ${C.cyan("Path:")} ${J.route.path}`),console.log(` ${C.cyan("Component:")} ${J.route.componentName}`);if(J.usage)console.log(""),console.log(C.gray("Usage:")),console.log(C.dim("─".repeat(40))),console.log(J.usage);console.log("")}catch(J){if(Z.fail("Failed to fetch module info"),J instanceof Error)console.error(C.red(J.message));process.exit(1)}});import s91 from"path";var vK=k1(r8(),1);import{execSync as wx0}from"child_process";import xq from"path";async function rE(D,X=!1){let Z=Date.now(),J=[],Y=xq.join(D,"tsconfig.json");if(!await vK.default.pathExists(Y))return{name:"TypeScript",status:"skip",severity:"info",duration:Date.now()-Z,items:[],summary:"No tsconfig.json found"};let Q=xq.join(D,"package.json"),$=!1;if(await vK.default.pathExists(Q))$=!!(await vK.default.readJson(Q)).scripts?.check;let K=X$(D),G=K==="npm"?"npm run":`${K} run`;try{let F=$?`${G} check 2>&1`:"npx tsc --noEmit 2>&1";if(!X)console.log(C.dim(` $ ${$?`${G} check`:"tsc --noEmit"}`));let W=wx0(F,{cwd:D,encoding:"utf-8",stdio:"pipe"});if(!X&&W.trim())console.log(C.dim(W));return{name:"TypeScript",status:"pass",severity:"error",duration:Date.now()-Z,items:[],summary:"No type errors"}}catch(F){let W=F.stdout||F.stderr||F.message||"";if(W.includes("This is not the tsc command")||W.includes("typescript"))return{name:"TypeScript",status:"skip",severity:"info",duration:Date.now()-Z,items:[],summary:"TypeScript not installed"};if(!X&&W.trim())console.log(C.dim(W));return J.push(...Sx0(W,D)),{name:"TypeScript",status:"fail",severity:"error",duration:Date.now()-Z,items:J,summary:`${J.length} type error(s)`}}}function Sx0(D,X){let Z=[],J=/^(.+)\((\d+),(\d+)\):\s*(error|warning)\s*(TS\d+):\s*(.+)$/gm,Y=/^(.+):(\d+):(\d+)\s*-\s*(error|warning)\s*(TS\d+):\s*(.+)$/gm;for(let $ of[J,Y]){let K;while((K=$.exec(D))!==null){let G=K[1].trim();Z.push({file:xq.isAbsolute(G)?xq.relative(X,G):G,line:parseInt(K[2]),column:parseInt(K[3]),code:K[5],message:K[6]})}}let Q=new Set;return Z.filter(($)=>{let K=`${$.file}:${$.line}:${$.column}:${$.message}`;if(Q.has(K))return!1;return Q.add(K),!0})}var oD=k1(r8(),1);import{execSync as _x0}from"child_process";import bK from"path";var kx0=["eslint.config.js","eslint.config.mjs","eslint.config.cjs",".eslintrc.js",".eslintrc.cjs",".eslintrc.json",".eslintrc.yml",".eslintrc.yaml",".eslintrc"];async function hx0(D){for(let Z of kx0)if(await oD.default.pathExists(bK.join(D,Z)))return!0;let X=bK.join(D,"package.json");if(await oD.default.pathExists(X))try{if((await oD.default.readJson(X)).eslintConfig)return!0}catch{}return!1}async function sE(D,X=!1,Z=!1){let J=Date.now();if(!await hx0(D))return{name:"ESLint",status:"skip",severity:"warning",duration:Date.now()-J,items:[],summary:"No ESLint config found"};let Y=bK.join(D,"package.json"),Q=!1;if(await oD.default.pathExists(Y))Q=!!(await oD.default.readJson(Y)).scripts?.lint;let $=X$(D),K=$==="npm"?"npm run":`${$} run`,G=X?" -- --fix":"";try{let F=Q?`${K} lint${G} 2>&1`:`npx eslint .${X?" --fix":""} 2>&1`;if(!Z)console.log(C.dim(` $ ${Q?`${K} lint${G}`:`eslint .${X?" --fix":""}`}`));let W=_x0(F,{cwd:D,encoding:"utf-8",stdio:"pipe",maxBuffer:10485760});if(!Z&&W.trim())console.log(C.dim(W));return{name:"ESLint",status:"pass",severity:"warning",duration:Date.now()-J,items:[],summary:"No linting issues"}}catch(F){let W=F.stdout||F.stderr||F.message||"";if(W.includes("eslint: not found")||W.includes("'eslint' is not recognized"))return{name:"ESLint",status:"skip",severity:"info",duration:Date.now()-J,items:[],summary:"ESLint not installed"};if(!Z&&W.trim())console.log(C.dim(W));let V=xx0(W,D);if(V.length===0&&W.includes("error"))return{name:"ESLint",status:"fail",severity:"warning",duration:Date.now()-J,items:[{message:"ESLint encountered an error"}],summary:"ESLint error"};return{name:"ESLint",status:V.length>0?"fail":"pass",severity:"warning",duration:Date.now()-J,items:V,summary:V.length>0?`${V.length} linting issue(s)`:"No linting issues"}}}function xx0(D,X){let Z=[],J=/^([^\s].*\.(ts|tsx|js|jsx))$/gm,Y=/^\s+(\d+):(\d+)\s+(error|warning)\s+(.+?)\s{2,}(\S+)?$/gm,Q=null,$=D.split(`
495
495
  `);for(let K of $){let G=K.match(/^([^\s].*\.(ts|tsx|js|jsx))$/);if(G){Q=G[1];continue}let F=K.match(/^\s+(\d+):(\d+)\s+(error|warning)\s+(.+?)\s{2,}(\S+)?$/);if(F&&Q)Z.push({file:bK.isAbsolute(Q)?bK.relative(X,Q):Q,line:parseInt(F[1]),column:parseInt(F[2]),code:F[5]||void 0,message:F[4].trim()})}return Z}var yq=k1(r8(),1);import{execSync as yx0}from"child_process";import fK from"path";async function aE(D){let X=Date.now(),Z=["vite.config.ts","vite.config.js","vite.config.mjs"],J=!1;for(let Y of Z)if(await yq.default.pathExists(fK.join(D,Y))){J=!0;break}if(!J)return{name:"Build",status:"skip",severity:"error",duration:Date.now()-X,items:[],summary:"No vite.config found"};try{yx0("npx vite build 2>&1",{cwd:D,encoding:"utf-8",stdio:"pipe",env:{...process.env,NODE_ENV:"production"}});let Y=fK.join(D,"dist");if(await yq.default.pathExists(Y))await yq.default.remove(Y);return{name:"Build",status:"pass",severity:"error",duration:Date.now()-X,items:[],summary:"Build succeeded"}}catch(Y){let Q=Y.stdout||Y.stderr||Y.message||"",$=vx0(Q,D);return{name:"Build",status:"fail",severity:"error",duration:Date.now()-X,items:$.length>0?$:[{message:"Build failed"}],summary:"Build failed"}}}function vx0(D,X){let Z=[],J=D.split(`
496
496
  `),Y=[/^(.+):(\d+):(\d+):\s*(.+)$/,/\[vite\]:\s*Error:\s*(.+)/,/Error:\s*(.+?)\s+at\s+(.+):(\d+):(\d+)/,/Could not resolve ["']([^"']+)["']\s+from\s+["']([^"']+)["']/,/RollupError:\s*(.+)/];for(let $=0;$<J.length;$++){let K=J[$].trim();if(!K)continue;if(K.includes("building for production")||K.includes("transforming")||K.includes("rendering chunks")||K.includes("computing gzip")||K.startsWith("✓")||K.startsWith("vite v"))continue;for(let G of Y){let F=K.match(G);if(F){if(G.source.includes("Could not resolve"))Z.push({file:fK.relative(X,F[2]),message:`Cannot find module '${F[1]}'`,suggestion:"Check if the module is installed or the path is correct"});else if(F.length===5)Z.push({file:fK.isAbsolute(F[1]||F[2])?fK.relative(X,F[1]||F[2]):F[1]||F[2],line:parseInt(F[2]||F[3]),column:parseInt(F[3]||F[4]),message:F[4]||F[1]});else Z.push({message:F[1]||K});break}}if(Z.length===0&&(K.toLowerCase().includes("error")||K.toLowerCase().includes("failed")))Z.push({message:K})}let Q=new Set;return Z.filter(($)=>{let K=`${$.file}:${$.line}:${$.message}`;if(Q.has(K))return!1;return Q.add(K),!0})}var lS=k1(r8(),1);import DF from"path";var v91=[process.env["PROGRAMFILES(X86)"]&&DF.join(process.env["PROGRAMFILES(X86)"],"Google","Chrome","Application","chrome.exe"),process.env.PROGRAMFILES&&DF.join(process.env.PROGRAMFILES,"Google","Chrome","Application","chrome.exe"),process.env.LOCALAPPDATA&&DF.join(process.env.LOCALAPPDATA,"Google","Chrome","Application","chrome.exe"),process.env["PROGRAMFILES(X86)"]&&DF.join(process.env["PROGRAMFILES(X86)"],"Microsoft","Edge","Application","msedge.exe"),process.env.PROGRAMFILES&&DF.join(process.env.PROGRAMFILES,"Microsoft","Edge","Application","msedge.exe")].filter(Boolean),b91=["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome","/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge","/Applications/Chromium.app/Contents/MacOS/Chromium"],f91=["/usr/bin/google-chrome","/usr/bin/google-chrome-stable","/usr/bin/chromium-browser","/usr/bin/chromium","/snap/bin/chromium"];async function v$0(){let D=await g91();if(!D)return null;try{return{type:"chrome",browser:await(await Promise.resolve().then(() => (y$0(),x$0))).default.launch({executablePath:D,headless:!0,args:["--no-sandbox","--disable-setuid-sandbox","--disable-gpu"]})}}catch{return null}}async function g91(){if(process.env.CHROME_PATH){if(await lS.default.pathExists(process.env.CHROME_PATH))return process.env.CHROME_PATH}let D;switch(process.platform){case"win32":D=v91;break;case"darwin":D=b91;break;default:D=f91}for(let X of D)if(await lS.default.pathExists(X))return X;return null}async function b$0(D){try{await D.browser.close()}catch{}}async function pS(D,X,Z="/"){let J=Date.now();if(!await u91(D))return{name:"Runtime",status:"skip",severity:"error",duration:Date.now()-J,items:[{message:`No server running on port ${D}`,suggestion:"Start dev server first: npm run dev (or use --port to specify different port)"}],summary:`Skipped (no server on port ${D})`};let Q=null;try{Q=await v$0()}catch{}if(!Q)return{name:"Runtime",status:"skip",severity:"info",duration:Date.now()-J,items:[{message:"No browser available (Chrome/Chromium/Edge not found)",suggestion:"Set CHROME_PATH environment variable or install Chrome/Edge"}],summary:"Skipped (no browser)"};let $=[],{browser:K,type:G}=Q;try{let W=await K.newPage();W.on("console",(H)=>{let q=H.type();if(q==="error"||q==="warning"){let U=H.location();$.push({type:q==="warning"?"warning":"console",message:H.text(),fileName:U?.url,lineNumber:U?.lineNumber,columnNumber:U?.columnNumber})}}),W.on("pageerror",(H)=>{$.push({type:"error",message:H.message,stack:H.stack})});let V=Z.startsWith("/")?Z:`/${Z}`;await W.goto(`http://localhost:${D}${V}`,{waitUntil:"networkidle0",timeout:X}),await m91(3000);let z=await W.evaluate(()=>{return window.__earlyErrors||[]});$.push(...z)}catch(W){let V=W.message||"Unknown error";if(V.includes("timeout")||V.includes("Timeout"))$.push({type:"error",message:"Page load timeout - app may have crashed or is unresponsive"});else if(V.includes("net::ERR"))$.push({type:"error",message:`Network error: ${V}`});else $.push({type:"error",message:`Runtime check error: ${V}`})}finally{await b$0(Q)}let F=c91($);return{name:`Runtime (${G})`,status:F.length>0?"fail":"pass",severity:"error",duration:Date.now()-J,items:F,summary:F.length>0?`${F.length} runtime error(s)`:"No runtime errors"}}async function u91(D){try{let X=await fetch(`http://localhost:${D}`,{method:"HEAD",signal:AbortSignal.timeout(3000)});return X.ok||X.status<500}catch{return!1}}function m91(D){return new Promise((X)=>setTimeout(X,D))}function c91(D){return D.map((X)=>{let Z=[];for(let[J,Y]of Object.entries(X))if(Y!==void 0&&Y!==null)Z.push(`${J}: ${Y}`);return{message:Z.join(`
497
- `)}})}function iS(D,X){console.log(""),console.log(C.bold("Health Check")+C.dim(` (${r91(D.duration)})`)),console.log(C.dim("─".repeat(40)));for(let Z of D.checks)d91(Z,X);console.log(C.dim("─".repeat(40))),o91(D)}function d91(D,X){let Z=i91(D.status),J=n91(D.status,D.severity),Y=C.dim(`${D.duration}ms`);console.log(`${Z} ${J(D.name)} ${Y} ${C.dim("·")} ${C.dim(D.summary||"")}`);let Q=D.name.startsWith("Runtime"),$=X||Q?D.items:D.items.slice(0,3),K=D.items.length-$.length;for(let G of $)l91(G,D.severity);if(K>0)console.log(C.dim(` ... +${K} more (--verbose)`))}function l91(D,X){let Z=X==="error"?C.red:C.yellow,J=p91(D),Y=J?C.cyan(J)+" ":"";console.log(` ${Z("›")} ${Y}${D.message}`)}function p91(D){if(!D.file)return"";let X=D.file;if(D.line!==void 0){if(X+=`:${D.line}`,D.column!==void 0)X+=`:${D.column}`}return X}function i91(D){switch(D){case"pass":return C.green("✓");case"fail":return C.red("✗");case"skip":return C.dim("○");default:return C.dim("?")}}function n91(D,X){if(D==="fail")return X==="error"?C.red:C.yellow;if(D==="pass")return C.green;return C.dim}function o91(D){let{summary:X}=D,Z=[];if(X.passed>0)Z.push(C.green(`${X.passed} passed`));if(X.failed>0)Z.push(C.red(`${X.failed} failed`));if(X.skipped>0)Z.push(C.dim(`${X.skipped} skipped`));if(console.log(Z.join(C.dim(" · "))),X.errors>0)console.log(C.red(`${X.errors} error(s) need attention`));else if(X.warnings>0)console.log(C.yellow(`${X.warnings} warning(s) to review`));else console.log(C.green("All good!"))}function r91(D){if(D<1000)return`${D}ms`;return`${(D/1000).toFixed(1)}s`}var f$0=new $5("doctor").description("Analyze project for issues (TypeScript, ESLint, build, runtime)").option("--cwd <path>","Working directory").option("--port <number>","Vite dev server port","5174").option("--fix","Auto-fix ESLint issues where possible").option("--runtime","Run runtime error detection (requires running dev server)").option("--runtime-timeout <ms>","Runtime check timeout in ms","10000").option("--route <path>","Route path for runtime check","/").option("--json","Output as JSON (for CI/CD)").option("-v, --verbose","Show all details including all errors").option("-q, --quiet","Hide command output logs (only show summary)").option("--no-typecheck","Skip TypeScript type checking").option("--no-lint","Skip ESLint checking").option("--no-build","Skip Vite build checking").action(async(D)=>{let X=D.cwd||process.cwd(),Z=parseInt(D.port||"5173"),J=parseInt(D.runtimeTimeout||"10000"),Y=D.route||"/",Q=Date.now(),$=D.quiet||D.json||!1;if(!await T2(X)&&!D.json)console.log(C.yellow("Warning: No promake.json found. Running checks anyway..."));let G=D.json?null:E2("Running health checks...").start(),F=[];if(D.typecheck!==!1)F.push(()=>rE(X,$));if(D.lint!==!1)F.push(()=>sE(X,D.fix,$));if(D.build!==!1)F.push(()=>aE(X));if(D.runtime)F.push(()=>pS(Z,J,Y));let W=[];try{if(W=await a91(F,1),G)G.stop()}catch(z){if(G)G.fail("Health check failed");if(!D.json)console.error(C.red(z.message));process.exit(1)}let V={project:s91.basename(X),timestamp:new Date().toISOString(),duration:Date.now()-Q,checks:W,summary:{passed:W.filter((z)=>z.status==="pass").length,failed:W.filter((z)=>z.status==="fail").length,skipped:W.filter((z)=>z.status==="skip").length,errors:W.filter((z)=>z.status==="fail"&&z.severity==="error").reduce((z,H)=>z+H.items.length,0),warnings:W.filter((z)=>z.status==="fail"&&z.severity==="warning").reduce((z,H)=>z+H.items.length,0)}};if(D.json)console.log(JSON.stringify(V,null,2));else iS(V,D.verbose||!1);if(V.summary.errors>0)process.exit(1)});async function a91(D,X){let Z=[],J=0;async function Y(){let $=J++;if($>=D.length)return;Z[$]=await D[$](),await Y()}let Q=Array(Math.min(X,D.length)).fill(null).map(()=>Y());return await Promise.all(Q),Z}var g$0={name:"@promakeai/cli",version:"0.4.3",type:"module",bin:{promake:"dist/index.js"},files:["dist/index.js","dist/registry","template"],scripts:{dev:"bun run src/index.ts","dev:app":"cd dev && bun run dev","dev:populate":"bun run scripts/populate-dev.ts","dev:fresh":"bun run dev:populate && bun run dev:app","playground:create":"rm -rf playground && bun run dev -- create playground --template empty --pm bun","playground:reset":"bun run playground:create","playground:add":"cd playground && bun run ../src/index.ts add","playground:ecommerce":"rm -rf playground && bun run dev -- create playground --template ecommerce --pm bun",build:"bun run build:cli && bun run build:registry","build:cli":"bun build src/index.ts --outdir dist --target node --minify","build:registry":"bun run scripts/build-registry.ts",typecheck:"tsc --noEmit",prepublishOnly:"bun run build",test:"bun test","test:watch":"bun test --watch","test:coverage":"bun test --coverage",release:"bun run build && npm publish --access public"},dependencies:{"adm-zip":"^0.5.16",archiver:"^7.0.1",chalk:"^5.3.0",commander:"^12.1.0",culori:"^4.0.2",dotenv:"^17.2.3","fs-extra":"^11.3.3",glob:"^11.0.0",ora:"^8.1.1",prompts:"^2.4.2","puppeteer-core":"^24.36.0"},devDependencies:{"@types/archiver":"^7.0.0","@types/bun":"^1.1.14","@types/culori":"^4.0.1","@types/fs-extra":"^11.0.4","@types/node":"^22.10.2","@types/prompts":"^2.4.9",typescript:"^5.7.2"}};var P8=new $5;P8.name("promake").description(`Modular React template CLI - Build React apps with pre-built components
497
+ `)}})}function iS(D,X){console.log(""),console.log(C.bold("Health Check")+C.dim(` (${r91(D.duration)})`)),console.log(C.dim("─".repeat(40)));for(let Z of D.checks)d91(Z,X);console.log(C.dim("─".repeat(40))),o91(D)}function d91(D,X){let Z=i91(D.status),J=n91(D.status,D.severity),Y=C.dim(`${D.duration}ms`);console.log(`${Z} ${J(D.name)} ${Y} ${C.dim("·")} ${C.dim(D.summary||"")}`);let Q=D.name.startsWith("Runtime"),$=X||Q?D.items:D.items.slice(0,3),K=D.items.length-$.length;for(let G of $)l91(G,D.severity);if(K>0)console.log(C.dim(` ... +${K} more (--verbose)`))}function l91(D,X){let Z=X==="error"?C.red:C.yellow,J=p91(D),Y=J?C.cyan(J)+" ":"";console.log(` ${Z("›")} ${Y}${D.message}`)}function p91(D){if(!D.file)return"";let X=D.file;if(D.line!==void 0){if(X+=`:${D.line}`,D.column!==void 0)X+=`:${D.column}`}return X}function i91(D){switch(D){case"pass":return C.green("✓");case"fail":return C.red("✗");case"skip":return C.dim("○");default:return C.dim("?")}}function n91(D,X){if(D==="fail")return X==="error"?C.red:C.yellow;if(D==="pass")return C.green;return C.dim}function o91(D){let{summary:X}=D,Z=[];if(X.passed>0)Z.push(C.green(`${X.passed} passed`));if(X.failed>0)Z.push(C.red(`${X.failed} failed`));if(X.skipped>0)Z.push(C.dim(`${X.skipped} skipped`));if(console.log(Z.join(C.dim(" · "))),X.errors>0)console.log(C.red(`${X.errors} error(s) need attention`));else if(X.warnings>0)console.log(C.yellow(`${X.warnings} warning(s) to review`));else console.log(C.green("All good!"))}function r91(D){if(D<1000)return`${D}ms`;return`${(D/1000).toFixed(1)}s`}var f$0=new $5("doctor").description("Analyze project for issues (TypeScript, ESLint, build, runtime)").option("--cwd <path>","Working directory").option("--port <number>","Vite dev server port","5174").option("--fix","Auto-fix ESLint issues where possible").option("--runtime","Run runtime error detection (requires running dev server)").option("--runtime-timeout <ms>","Runtime check timeout in ms","10000").option("--route <path>","Route path for runtime check","/").option("--json","Output as JSON (for CI/CD)").option("-v, --verbose","Show all details including all errors").option("-q, --quiet","Hide command output logs (only show summary)").option("--no-typecheck","Skip TypeScript type checking").option("--no-lint","Skip ESLint checking").option("--no-build","Skip Vite build checking").action(async(D)=>{let X=D.cwd||process.cwd(),Z=parseInt(D.port||"5173"),J=parseInt(D.runtimeTimeout||"10000"),Y=D.route||"/",Q=Date.now(),$=D.quiet||D.json||!1;if(!await T2(X)&&!D.json)console.log(C.yellow("Warning: No promake.json found. Running checks anyway..."));let G=D.json?null:E2("Running health checks...").start(),F=[];if(D.typecheck!==!1)F.push(()=>rE(X,$));if(D.lint!==!1)F.push(()=>sE(X,D.fix,$));if(D.build!==!1)F.push(()=>aE(X));if(D.runtime)F.push(()=>pS(Z,J,Y));let W=[];try{if(W=await a91(F,1),G)G.stop()}catch(z){if(G)G.fail("Health check failed");if(!D.json)console.error(C.red(z.message));process.exit(1)}let V={project:s91.basename(X),timestamp:new Date().toISOString(),duration:Date.now()-Q,checks:W,summary:{passed:W.filter((z)=>z.status==="pass").length,failed:W.filter((z)=>z.status==="fail").length,skipped:W.filter((z)=>z.status==="skip").length,errors:W.filter((z)=>z.status==="fail"&&z.severity==="error").reduce((z,H)=>z+H.items.length,0),warnings:W.filter((z)=>z.status==="fail"&&z.severity==="warning").reduce((z,H)=>z+H.items.length,0)}};if(D.json)console.log(JSON.stringify(V,null,2));else iS(V,D.verbose||!1);if(V.summary.errors>0)process.exit(1)});async function a91(D,X){let Z=[],J=0;async function Y(){let $=J++;if($>=D.length)return;Z[$]=await D[$](),await Y()}let Q=Array(Math.min(X,D.length)).fill(null).map(()=>Y());return await Promise.all(Q),Z}var g$0={name:"@promakeai/cli",version:"0.4.4",type:"module",bin:{promake:"dist/index.js"},files:["dist/index.js","dist/registry","template"],scripts:{dev:"bun run src/index.ts","dev:app":"cd dev && bun run dev","dev:populate":"bun run scripts/populate-dev.ts","dev:fresh":"bun run dev:populate && bun run dev:app","playground:create":"rm -rf playground && bun run dev -- create playground --template empty --pm bun","playground:reset":"bun run playground:create","playground:add":"cd playground && bun run ../src/index.ts add","playground:ecommerce":"rm -rf playground && bun run dev -- create playground --template ecommerce --pm bun",build:"bun run build:cli && bun run build:registry","build:cli":"bun build src/index.ts --outdir dist --target node --minify","build:registry":"bun run scripts/build-registry.ts",typecheck:"tsc --noEmit",prepublishOnly:"bun run build",test:"bun test","test:watch":"bun test --watch","test:coverage":"bun test --coverage",release:"bun run build && npm publish --access public"},dependencies:{"adm-zip":"^0.5.16",archiver:"^7.0.1",chalk:"^5.3.0",commander:"^12.1.0",culori:"^4.0.2",dotenv:"^17.2.3","fs-extra":"^11.3.3",glob:"^11.0.0",ora:"^8.1.1",prompts:"^2.4.2","puppeteer-core":"^24.36.0"},devDependencies:{"@types/archiver":"^7.0.0","@types/bun":"^1.1.14","@types/culori":"^4.0.1","@types/fs-extra":"^11.0.4","@types/node":"^22.10.2","@types/prompts":"^2.4.9",typescript:"^5.7.2"}};var P8=new $5;P8.name("promake").description(`Modular React template CLI - Build React apps with pre-built components
498
498
 
499
499
  Quick Start:
500
500
  $ promake create my-app
@@ -20,7 +20,7 @@
20
20
  "path": "payment-success-block/payment-success-block.tsx",
21
21
  "type": "registry:block",
22
22
  "target": "$modules$/payment-success-block/payment-success-block.tsx",
23
- "content": "import { Link } from \"react-router\";\nimport {\n CheckCircle,\n XCircle,\n Loader2,\n ShoppingBag,\n Package,\n} from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport { useTranslation } from \"react-i18next\";\nimport { formatPrice } from \"@/modules/ecommerce-core\";\n\ntype PaymentStatus = \"loading\" | \"success\" | \"failed\";\n\ninterface OrderDetails {\n id?: string;\n totalAmount?: number;\n currency?: string;\n paymentMethod?: string;\n paymentStatus?: string;\n status?: string;\n}\n\ninterface PaymentSuccessBlockProps {\n status: PaymentStatus;\n orderDetails?: OrderDetails | null;\n errorMessage?: string;\n onRetry?: () => void;\n}\n\nexport function PaymentSuccessBlock({\n status,\n orderDetails,\n errorMessage,\n onRetry,\n}: PaymentSuccessBlockProps) {\n const { t } = useTranslation(\"payment-success-block\");\n\n // Loading State\n if (status === \"loading\") {\n return (\n <div className=\"w-full max-w-[var(--container-max-width)] mx-auto px-4 py-16\">\n <div className=\"max-w-md mx-auto text-center\">\n <Card>\n <CardContent className=\"pt-8 pb-8\">\n <Loader2 className=\"w-16 h-16 text-primary mx-auto mb-4 animate-spin\" />\n <h1 className=\"text-2xl font-bold mb-2\">\n {t(\"verifyingPayment\", \"Verifying Payment\")}\n </h1>\n <p className=\"text-muted-foreground\">\n {t(\n \"pleaseWait\",\n \"Please wait while we verify your payment...\"\n )}\n </p>\n </CardContent>\n </Card>\n </div>\n </div>\n );\n }\n\n // Failed State\n if (status === \"failed\") {\n return (\n <div className=\"w-full max-w-[var(--container-max-width)] mx-auto px-4 py-16\">\n <div className=\"max-w-md mx-auto text-center\">\n <Card>\n <CardContent className=\"pt-8 pb-8\">\n <XCircle className=\"w-16 h-16 text-destructive mx-auto mb-4\" />\n <h1 className=\"text-2xl font-bold mb-2\">\n {t(\"paymentFailed\", \"Payment Failed\")}\n </h1>\n\n {/* Error Message */}\n {errorMessage && (\n <div className=\"bg-destructive/10 border border-destructive/30 rounded-lg p-4 mb-4\">\n <p className=\"text-sm text-destructive\">{errorMessage}</p>\n </div>\n )}\n\n <p className=\"text-muted-foreground mb-6\">\n {t(\n \"paymentFailedDescription\",\n \"We couldn't verify your payment. Please try again or contact support.\"\n )}\n </p>\n\n <div className=\"flex flex-col gap-3\">\n {onRetry && (\n <Button onClick={onRetry}>\n {t(\"tryAgain\", \"Try Again\")}\n </Button>\n )}\n <Button variant=\"outline\" asChild>\n <Link to=\"/contact\">\n {t(\"contactSupport\", \"Contact Support\")}\n </Link>\n </Button>\n </div>\n </CardContent>\n </Card>\n </div>\n </div>\n );\n }\n\n // Success State\n return (\n <div className=\"w-full max-w-[var(--container-max-width)] mx-auto px-4 py-16\">\n <div className=\"max-w-lg mx-auto text-center\">\n <Card>\n <CardContent className=\"pt-8 pb-8\">\n <CheckCircle className=\"w-20 h-20 text-green-600 dark:text-green-400 mx-auto mb-6\" />\n <h1 className=\"text-3xl font-bold mb-2\">\n {t(\"thankYou\", \"Thank You!\")}\n </h1>\n <p className=\"text-xl text-muted-foreground mb-6\">\n {t(\"orderConfirmed\", \"Your order has been confirmed.\")}\n </p>\n\n {orderDetails && (\n <div className=\"bg-muted/50 rounded-lg p-4 mb-6 text-left\">\n <h3 className=\"font-semibold mb-2\">\n {t(\"orderDetails\", \"Order Details\")}\n </h3>\n <div className=\"text-sm space-y-1\">\n {orderDetails.id && (\n <p>\n <span className=\"text-muted-foreground\">\n {t(\"orderId\", \"Order ID\")}:\n </span>{\" \"}\n <span className=\"font-medium\">{orderDetails.id}</span>\n </p>\n )}\n {orderDetails.totalAmount !== undefined && orderDetails.currency && (\n <p>\n <span className=\"text-muted-foreground\">\n {t(\"total\", \"Total\")}:\n </span>{\" \"}\n <span className=\"font-medium\">\n {formatPrice(orderDetails.totalAmount, orderDetails.currency)}\n </span>\n </p>\n )}\n {orderDetails.paymentMethod && (\n <p>\n <span className=\"text-muted-foreground\">\n {t(\"paymentMethod\", \"Payment Method\")}:\n </span>{\" \"}\n <span className=\"font-medium capitalize\">\n {orderDetails.paymentMethod}\n </span>\n </p>\n )}\n {orderDetails.paymentStatus && (\n <p>\n <span className=\"text-muted-foreground\">\n {t(\"paymentStatus\", \"Payment Status\")}:\n </span>{\" \"}\n <span className=\"font-medium capitalize text-green-600 dark:text-green-400\">\n {orderDetails.paymentStatus}\n </span>\n </p>\n )}\n {orderDetails.status && (\n <p>\n <span className=\"text-muted-foreground\">\n {t(\"orderStatus\", \"Order Status\")}:\n </span>{\" \"}\n <span className=\"font-medium capitalize\">\n {orderDetails.status}\n </span>\n </p>\n )}\n </div>\n </div>\n )}\n\n <p className=\"text-sm text-muted-foreground mb-6\">\n {t(\n \"confirmationEmailSent\",\n \"A confirmation email has been sent to your email address.\"\n )}\n </p>\n\n <div className=\"flex flex-col gap-3\">\n <Button asChild size=\"lg\">\n <Link to=\"/orders\">\n <Package className=\"w-4 h-4 mr-2\" />\n {t(\"viewMyOrders\", \"View My Orders\")}\n </Link>\n </Button>\n <Button variant=\"outline\" asChild>\n <Link to=\"/products\">\n <ShoppingBag className=\"w-4 h-4 mr-2\" />\n {t(\"continueShopping\", \"Continue Shopping\")}\n </Link>\n </Button>\n </div>\n </CardContent>\n </Card>\n </div>\n </div>\n );\n}\n"
23
+ "content": "import { Link } from \"react-router\";\nimport {\n CheckCircle,\n XCircle,\n Loader2,\n ShoppingBag,\n Package,\n} from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport { useTranslation } from \"react-i18next\";\nimport { formatPrice } from \"@/modules/ecommerce-core\";\n\ntype PaymentStatus = \"loading\" | \"success\" | \"failed\";\n\ninterface OrderDetails {\n id?: string;\n totalAmount?: number;\n currency?: string;\n paymentMethod?: string;\n paymentStatus?: string;\n status?: string;\n}\n\ninterface PaymentSuccessBlockProps {\n status: PaymentStatus;\n orderDetails?: OrderDetails | null;\n errorMessage?: string;\n onRetry?: () => void;\n}\n\nexport function PaymentSuccessBlock({\n status,\n orderDetails,\n errorMessage,\n onRetry,\n}: PaymentSuccessBlockProps) {\n const { t } = useTranslation(\"payment-success-block\");\n\n // Loading State\n if (status === \"loading\") {\n return (\n <div className=\"w-full max-w-[var(--container-max-width)] mx-auto px-4 py-16\">\n <div className=\"max-w-md mx-auto text-center\">\n <Card>\n <CardContent className=\"pt-8 pb-8\">\n <Loader2 className=\"w-16 h-16 text-primary mx-auto mb-4 animate-spin\" />\n <h1 className=\"text-2xl font-bold mb-2\">\n {t(\"verifyingPayment\", \"Verifying Payment\")}\n </h1>\n <p className=\"text-muted-foreground\">\n {t(\n \"pleaseWait\",\n \"Please wait while we verify your payment...\"\n )}\n </p>\n </CardContent>\n </Card>\n </div>\n </div>\n );\n }\n\n // Failed State\n if (status === \"failed\") {\n return (\n <div className=\"w-full max-w-[var(--container-max-width)] mx-auto px-4 py-16\">\n <div className=\"max-w-md mx-auto text-center\">\n <Card>\n <CardContent className=\"pt-8 pb-8\">\n <XCircle className=\"w-16 h-16 text-destructive mx-auto mb-4\" />\n <h1 className=\"text-2xl font-bold mb-2\">\n {t(\"paymentFailed\", \"Payment Failed\")}\n </h1>\n\n {/* Error Message */}\n {errorMessage && (\n <div className=\"bg-destructive/10 border border-destructive/30 rounded-lg p-4 mb-4\">\n <p className=\"text-sm text-destructive\">{errorMessage}</p>\n </div>\n )}\n\n <p className=\"text-muted-foreground mb-6\">\n {t(\n \"paymentFailedDescription\",\n \"We couldn't verify your payment. Please try again or contact support.\"\n )}\n </p>\n\n <div className=\"flex flex-col gap-3\">\n {onRetry && (\n <Button onClick={onRetry}>\n {t(\"tryAgain\", \"Try Again\")}\n </Button>\n )}\n <Button variant=\"outline\" asChild>\n <Link to=\"/contact\">\n {t(\"contactSupport\", \"Contact Support\")}\n </Link>\n </Button>\n </div>\n </CardContent>\n </Card>\n </div>\n </div>\n );\n }\n\n // Success State\n return (\n <div className=\"w-full max-w-[var(--container-max-width)] mx-auto px-4 py-16\">\n <div className=\"max-w-lg mx-auto text-center\">\n <Card>\n <CardContent className=\"pt-8 pb-8\">\n <CheckCircle className=\"w-20 h-20 text-green-600 dark:text-green-400 mx-auto mb-6\" />\n <h1 className=\"text-3xl font-bold mb-2\">\n {t(\"thankYou\", \"Thank You!\")}\n </h1>\n <p className=\"text-xl text-muted-foreground mb-6\">\n {t(\"orderConfirmed\", \"Your order has been confirmed.\")}\n </p>\n\n {orderDetails && (\n <div className=\"bg-muted/50 rounded-lg p-4 mb-6 text-left\">\n <h3 className=\"font-semibold mb-2\">\n {t(\"orderDetails\", \"Order Details\")}\n </h3>\n <div className=\"text-sm space-y-1\">\n {orderDetails.id && (\n <p>\n <span className=\"text-muted-foreground\">\n {t(\"orderId\", \"Order ID\")}:\n </span>{\" \"}\n <span className=\"font-medium\">{orderDetails.id}</span>\n </p>\n )}\n {orderDetails.totalAmount !== undefined && orderDetails.currency && (\n <p>\n <span className=\"text-muted-foreground\">\n {t(\"total\", \"Total\")}:\n </span>{\" \"}\n <span className=\"font-medium\">\n {formatPrice(orderDetails.totalAmount, orderDetails.currency)}\n </span>\n </p>\n )}\n {orderDetails.paymentMethod && (\n <p>\n <span className=\"text-muted-foreground\">\n {t(\"paymentMethod\", \"Payment Method\")}:\n </span>{\" \"}\n <span className=\"font-medium capitalize\">\n {orderDetails.paymentMethod}\n </span>\n </p>\n )}\n {orderDetails.paymentStatus && (\n <p>\n <span className=\"text-muted-foreground\">\n {t(\"paymentStatus\", \"Payment Status\")}:\n </span>{\" \"}\n <span className=\"font-medium capitalize text-green-600 dark:text-green-400\">\n {orderDetails.paymentStatus}\n </span>\n </p>\n )}\n {orderDetails.status && (\n <p>\n <span className=\"text-muted-foreground\">\n {t(\"orderStatus\", \"Order Status\")}:\n </span>{\" \"}\n <span className=\"font-medium capitalize\">\n {orderDetails.status}\n </span>\n </p>\n )}\n </div>\n </div>\n )}\n\n <p className=\"text-sm text-muted-foreground mb-6\">\n {t(\n \"confirmationEmailSent\",\n \"A confirmation email has been sent to your email address.\"\n )}\n </p>\n\n <div className=\"flex flex-col gap-3\">\n <Button asChild size=\"lg\">\n <Link to=\"/my-orders\">\n <Package className=\"w-4 h-4 mr-2\" />\n {t(\"viewMyOrders\", \"View My Orders\")}\n </Link>\n </Button>\n <Button variant=\"outline\" asChild>\n <Link to=\"/products\">\n <ShoppingBag className=\"w-4 h-4 mr-2\" />\n {t(\"continueShopping\", \"Continue Shopping\")}\n </Link>\n </Button>\n </div>\n </CardContent>\n </Card>\n </div>\n </div>\n );\n}\n"
24
24
  },
25
25
  {
26
26
  "path": "payment-success-block/lang/en.json",
package/package.json CHANGED
@@ -1,54 +1,54 @@
1
- {
2
- "name": "@promakeai/cli",
3
- "version": "0.4.3",
4
- "type": "module",
5
- "bin": {
6
- "promake": "dist/index.js"
7
- },
8
- "files": [
9
- "dist/index.js",
10
- "dist/registry",
11
- "template"
12
- ],
13
- "scripts": {
14
- "dev": "bun run src/index.ts",
15
- "dev:app": "cd dev && bun run dev",
16
- "dev:populate": "bun run scripts/populate-dev.ts",
17
- "dev:fresh": "bun run dev:populate && bun run dev:app",
18
- "playground:create": "rm -rf playground && bun run dev -- create playground --template empty --pm bun",
19
- "playground:reset": "bun run playground:create",
20
- "playground:add": "cd playground && bun run ../src/index.ts add",
21
- "playground:ecommerce": "rm -rf playground && bun run dev -- create playground --template ecommerce --pm bun",
22
- "build": "bun run build:cli && bun run build:registry",
23
- "build:cli": "bun build src/index.ts --outdir dist --target node --minify",
24
- "build:registry": "bun run scripts/build-registry.ts",
25
- "typecheck": "tsc --noEmit",
26
- "prepublishOnly": "bun run build",
27
- "test": "bun test",
28
- "test:watch": "bun test --watch",
29
- "test:coverage": "bun test --coverage",
30
- "release": "bun run build && npm publish --access public"
31
- },
32
- "dependencies": {
33
- "adm-zip": "^0.5.16",
34
- "archiver": "^7.0.1",
35
- "chalk": "^5.3.0",
36
- "commander": "^12.1.0",
37
- "culori": "^4.0.2",
38
- "dotenv": "^17.2.3",
39
- "fs-extra": "^11.3.3",
40
- "glob": "^11.0.0",
41
- "ora": "^8.1.1",
42
- "prompts": "^2.4.2",
43
- "puppeteer-core": "^24.36.0"
44
- },
45
- "devDependencies": {
46
- "@types/archiver": "^7.0.0",
47
- "@types/bun": "^1.1.14",
48
- "@types/culori": "^4.0.1",
49
- "@types/fs-extra": "^11.0.4",
50
- "@types/node": "^22.10.2",
51
- "@types/prompts": "^2.4.9",
52
- "typescript": "^5.7.2"
53
- }
54
- }
1
+ {
2
+ "name": "@promakeai/cli",
3
+ "version": "0.4.4",
4
+ "type": "module",
5
+ "bin": {
6
+ "promake": "dist/index.js"
7
+ },
8
+ "files": [
9
+ "dist/index.js",
10
+ "dist/registry",
11
+ "template"
12
+ ],
13
+ "scripts": {
14
+ "dev": "bun run src/index.ts",
15
+ "dev:app": "cd dev && bun run dev",
16
+ "dev:populate": "bun run scripts/populate-dev.ts",
17
+ "dev:fresh": "bun run dev:populate && bun run dev:app",
18
+ "playground:create": "rm -rf playground && bun run dev -- create playground --template empty --pm bun",
19
+ "playground:reset": "bun run playground:create",
20
+ "playground:add": "cd playground && bun run ../src/index.ts add",
21
+ "playground:ecommerce": "rm -rf playground && bun run dev -- create playground --template ecommerce --pm bun",
22
+ "build": "bun run build:cli && bun run build:registry",
23
+ "build:cli": "bun build src/index.ts --outdir dist --target node --minify",
24
+ "build:registry": "bun run scripts/build-registry.ts",
25
+ "typecheck": "tsc --noEmit",
26
+ "prepublishOnly": "bun run build",
27
+ "test": "bun test",
28
+ "test:watch": "bun test --watch",
29
+ "test:coverage": "bun test --coverage",
30
+ "release": "bun run build && npm publish --access public"
31
+ },
32
+ "dependencies": {
33
+ "adm-zip": "^0.5.16",
34
+ "archiver": "^7.0.1",
35
+ "chalk": "^5.3.0",
36
+ "commander": "^12.1.0",
37
+ "culori": "^4.0.2",
38
+ "dotenv": "^17.2.3",
39
+ "fs-extra": "^11.3.3",
40
+ "glob": "^11.0.0",
41
+ "ora": "^8.1.1",
42
+ "prompts": "^2.4.2",
43
+ "puppeteer-core": "^24.36.0"
44
+ },
45
+ "devDependencies": {
46
+ "@types/archiver": "^7.0.0",
47
+ "@types/bun": "^1.1.14",
48
+ "@types/culori": "^4.0.1",
49
+ "@types/fs-extra": "^11.0.4",
50
+ "@types/node": "^22.10.2",
51
+ "@types/prompts": "^2.4.9",
52
+ "typescript": "^5.7.2"
53
+ }
54
+ }
@@ -5,7 +5,9 @@
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "vite",
8
- "build": "tsc -b && vite build",
8
+ "prebuild": "tsc -b || cd .",
9
+ "build": "vite build",
10
+ "typecheck": "tsc -b",
9
11
  "lint": "eslint .",
10
12
  "preview": "vite preview",
11
13
  "check": "tsc --noEmit",
@@ -1,132 +1,65 @@
1
- import path from "path";
2
- import tailwindcss from "@tailwindcss/vite";
3
- import react from "@vitejs/plugin-react";
4
- import { defineConfig, type Plugin } from "vite";
5
- import { inspectorDebugger } from "@promakeai/inspector/plugin";
6
-
7
- // Plugin: Restart dev server when new lang files are added
8
- function langWatchPlugin(): Plugin {
9
- return {
10
- name: "lang-watch",
11
- configureServer(server) {
12
- server.watcher.on("add", (file) => {
13
- const normalizedPath = file.replace(/\\/g, "/");
14
- const isModuleLang = normalizedPath.includes("/modules/") && normalizedPath.includes("/lang/");
15
- const isGlobalLang = normalizedPath.includes("/src/lang/");
16
-
17
- if ((isModuleLang || isGlobalLang) && file.endsWith(".json")) {
18
- console.log("\n🌐 New translation file detected!");
19
- console.log("🔄 Restarting server to load translations...\n");
20
- server.restart();
21
- }
22
- });
23
- },
24
- };
25
- }
26
-
27
- // https://vite.dev/config/
28
- export default defineConfig(({ mode }) => ({
29
- plugins: [
30
- inspectorDebugger({ enabled: mode === "development" }),
31
- react(),
32
- tailwindcss(),
33
- mode === "development" && langWatchPlugin(),
34
- ].filter(Boolean),
35
- base: "/",
36
- resolve: {
37
- alias: {
38
- "@": path.resolve(__dirname, "./src"),
39
- },
40
- preserveSymlinks: true,
41
- },
42
- optimizeDeps: {
43
- include: [
44
- // Radix UI - CJS/ESM compatibility issues
45
- "@radix-ui/react-dropdown-menu",
46
- "@radix-ui/react-dialog",
47
- "@radix-ui/react-select",
48
- "@radix-ui/react-popover",
49
- "@radix-ui/react-tooltip",
50
- "@radix-ui/react-tabs",
51
- "@radix-ui/react-checkbox",
52
- "@radix-ui/react-accordion",
53
- "@radix-ui/react-alert-dialog",
54
- "@radix-ui/react-avatar",
55
- "@radix-ui/react-collapsible",
56
- "@radix-ui/react-context-menu",
57
- "@radix-ui/react-hover-card",
58
- "@radix-ui/react-label",
59
- "@radix-ui/react-menubar",
60
- "@radix-ui/react-navigation-menu",
61
- "@radix-ui/react-progress",
62
- "@radix-ui/react-radio-group",
63
- "@radix-ui/react-scroll-area",
64
- "@radix-ui/react-separator",
65
- "@radix-ui/react-slider",
66
- "@radix-ui/react-switch",
67
- "@radix-ui/react-toggle",
68
- "@radix-ui/react-toggle-group",
69
-
70
- // State management - ESM issues
71
- "@tanstack/react-query",
72
- "zustand",
73
-
74
- // Form libraries - external deps
75
- "react-hook-form",
76
- "@hookform/resolvers",
77
- "zod",
78
-
79
- // UI libraries - CJS/ESM mixed
80
- "cmdk",
81
- "vaul",
82
- "sonner",
83
-
84
- // Date libraries - CJS format
85
- "date-fns",
86
- "react-day-picker",
87
-
88
- // Charts - many sub-dependencies
89
- "recharts",
90
-
91
- // Carousel - external deps
92
- "embla-carousel-react",
93
-
94
- // HTTP client - CJS format
95
- "axios",
96
-
97
- // i18n - external deps
98
- "i18next",
99
- "react-i18next",
100
- "i18next-browser-languagedetector",
101
-
102
- // Animation - ESM issues
103
- "motion",
104
-
105
- // Database - WASM loader
106
- "sql.js",
107
- ],
108
- },
109
- server: {
110
- host: '0.0.0.0',
111
- allowedHosts: true,
112
- hmr: false,
113
- port: 5174,
114
- watch: {
115
- usePolling: true,
116
- interval: 500,
117
- },
118
- headers: {
119
- "Cache-Control": "no-cache, no-store, must-revalidate",
120
- },
121
- },
122
- preview: {
123
- port: 4173,
124
- },
125
- build: {
126
- rollupOptions: {
127
- output: {
128
- manualChunks: undefined,
129
- },
130
- },
131
- },
132
- }));
1
+ import path from "path";
2
+ import tailwindcss from "@tailwindcss/vite";
3
+ import react from "@vitejs/plugin-react";
4
+ import { defineConfig, type Plugin } from "vite";
5
+ import { inspectorDebugger } from "@promakeai/inspector/plugin";
6
+
7
+ // Plugin: Restart dev server when new lang files are added
8
+ function langWatchPlugin(): Plugin {
9
+ return {
10
+ name: "lang-watch",
11
+ configureServer(server) {
12
+ server.watcher.on("add", (file) => {
13
+ const normalizedPath = file.replace(/\\/g, "/");
14
+ const isModuleLang = normalizedPath.includes("/modules/") && normalizedPath.includes("/lang/");
15
+ const isGlobalLang = normalizedPath.includes("/src/lang/");
16
+
17
+ if ((isModuleLang || isGlobalLang) && file.endsWith(".json")) {
18
+ console.log("\n🌐 New translation file detected!");
19
+ console.log("🔄 Restarting server to load translations...\n");
20
+ server.restart();
21
+ }
22
+ });
23
+ },
24
+ };
25
+ }
26
+
27
+ // https://vite.dev/config/
28
+ export default defineConfig(({ mode }) => ({
29
+ cacheDir: '/tmp/.vite-cache',
30
+ plugins: [
31
+ inspectorDebugger({ enabled: mode === "development" }),
32
+ react(),
33
+ tailwindcss(),
34
+ mode === "development" && langWatchPlugin(),
35
+ ].filter(Boolean),
36
+ resolve: {
37
+ alias: {
38
+ "@": path.resolve(__dirname, "./src"),
39
+ },
40
+ preserveSymlinks: true,
41
+ },
42
+ server: {
43
+ host: '0.0.0.0',
44
+ allowedHosts: true,
45
+ hmr: false,
46
+ port: 5174,
47
+ watch: {
48
+ usePolling: true,
49
+ interval: 500,
50
+ },
51
+ headers: {
52
+ "Cache-Control": "no-cache, no-store, must-revalidate",
53
+ },
54
+ },
55
+ preview: {
56
+ port: 4173,
57
+ },
58
+ build: {
59
+ rollupOptions: {
60
+ output: {
61
+ manualChunks: undefined,
62
+ },
63
+ },
64
+ },
65
+ }));