UNPKG

@metricinsights/pp-dev

Version:
3 lines (2 loc) • 33 kB
import*as e from"path";import*as t from"fs";import{performance as o}from"node:perf_hooks";import{watch as n}from"chokidar";import{cac as i}from"cac";import{loadConfigFromFile as s,mergeConfig as r,build as a,resolveConfig as l,optimizeDeps as c,preview as d,loadEnv as p}from"vite";import{g as f,V as h,i as u,s as g,P as m,a as b}from"./index-CmcaJY7U.js";import{c as w,a as v,M as y,i as x,b as T,d as P,e as $,f as S,g as L,u as F}from"./plugin-_rCgP0h-.js";import{parse as j}from"url";import*as E from"dir-compare";import k from"diff-match-patch";import{isBinaryFile as A}from"isbinaryfile";import*as D from"os";import*as C from"crypto";import I from"extract-zip";import N from"svgtofont";import"ejs";import"http-proxy-middleware";import"picocolors";import"axios";import"jsdom";import"https";import"memory-cache";import"process";import"child_process";import"console";import"zlib";import"express";function _(e){return null!=e&&!1!==e}const R=[{key:"r",description:"restart the server",async action(e){await e.restart()}},{key:"u",description:"show server url",action(e){e.config.logger.info(""),e.printUrls()}},{key:"o",description:"open in browser",action(e){e.openBrowser()}},{key:"c",description:"clear console",action(e){e.config.logger.clearScreen("error")}},{key:"q",description:"quit",async action(e){await e.close().finally((()=>process.exit()))}},{key:"C",description:"clear proxy cache",action(e){e.cache&&(e.cache.clear(),e.config.logger.info("Proxy cache cleared"))}}];const M=/(.+)(-[a-f0-9]{6,20})(\.[a-z0-9]+)$/i;class z{oldAssetsPath;newAssetsPath;destinationPath;changelogFilename;changelogTemplate='<!DOCTYPE html>\n <html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>Changelog Diff</title>\n <style>\n tr,\n td {\n padding: 0;\n }\n .diff-file {\n margin-top: 20px;\n border: 1px solid #e1e4e8;\n border-radius: 6px;\n }\n .diff-file-title {\n padding: 10px 20px;\n background-color: #f6f8fa;\n border-bottom: 1px solid #e1e4e8;\n border-radius: 6px 6px 0 0;\n font-weight: bold;\n }\n .diff-file-title .renamed {\n font-weight: normal;\n }\n .diff-file-title .renamed .from {\n color: #cb2431;\n }\n .diff-file-title .renamed .to {\n color: #22863a;\n }\n .diff-file-title .added {\n color: #22863a;\n }\n .diff-file-title .deleted {\n color: #cb2431;\n }\n .diff-file-content {\n }\n .diff-table {\n tab-size: 8;\n width: 100%;\n border-collapse: separate;\n border-spacing: 0;\n }\n .blob-num {\n position: relative;\n color: #1f2328;\n width: 1%;\n min-width: 50px;\n padding: 0 10px;\n font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;\n font-size: 12px;\n line-height: 20px;\n text-align: right;\n white-space: nowrap;\n vertical-align: top;\n cursor: pointer;\n -webkit-user-select: none;\n user-select: none;\n }\n .blob-num.addition {\n background-color: #ccffd8;\n border-color: #1f883e;\n }\n .blob-num.deletion {\n background-color: #ffd7d5;\n border-color: #cf222e;\n }\n .blob-num::before {\n content: attr(data-line-number);\n }\n .blob-code {\n position: relative;\n padding: 0 10px 0 22px;\n vertical-align: top;\n color: #1f2329;\n }\n .blob-code.code-addition {\n background-color: #e6ffec;\n }\n .blob-code.code-deletion {\n background-color: #ffebe9;\n }\n .blob-code.skip,\n .blob-code.message {\n text-align: center;\n }\n .blob-code.skip .blob-code-inner,\n .blob-code.message .blob-code-inner {\n font-weight: bold;\n color: #6a737d;\n padding: 10px 0;\n }\n .blob-code-inner {\n display: table-cell;\n overflow: visible;\n font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;\n font-size: 12px;\n word-wrap: anywhere;\n white-space: pre-wrap;\n }\n .blob-code-inner::before {\n content: attr(data-code-prefix);\n position: absolute;\n top: 1px;\n left: 8px;\n padding-right: 8px;\n }\n </style>\n </head>\n <body>\n <h1>Changelog Diff</h1>\n\n %FILES%\n </body>\n </html>';diffFileTemplateHandler;diffLineTemplateHandler;contextLines=3;logger;constructor(t){const{oldAssetsPath:o,newAssetsPath:n,destinationPath:i,changelogTemplate:s,diffFileTemplateHandler:r,diffLineTemplateHandler:a,changelogFilename:l,contextLines:c}=t;if(this.logger=w(),!o||!n||!i)throw new Error("Previous assets path, current assets path and destination path are required");if(o===n)throw new Error("Previous and current assets paths must be different");if(!this.isExists(o))throw new Error(`Previous assets path ${o} does not exist`);if(!this.isExists(n))throw new Error(`Current assets path ${n} does not exist`);if(this.isZipFile(o)){const t=e.resolve(D.tmpdir(),C.createHash("md5").update(o).digest("hex"));this.oldAssetsPath=this.unzipFile(o,t).then((()=>this.normalizeAssetFolderPath(t))).then((e=>{if(this.isEmptyFolder(e))throw new Error(`Previous assets path ${e} is empty`);return e}))}else{if(!this.isFolder(o))throw new Error(`Invalid previous assets path ${o}. It must be a folder or a zip file`);{const e=this.normalizeAssetFolderPath(o);if(this.isEmptyFolder(e))throw new Error(`Previous assets path ${e} is empty`);this.oldAssetsPath=Promise.resolve(e)}}if(this.isZipFile(n)){const t=e.resolve(D.tmpdir(),C.createHash("md5").update(n).digest("hex"));this.newAssetsPath=this.unzipFile(n,t).then((()=>this.normalizeAssetFolderPath(t))).then((e=>{if(this.isEmptyFolder(e))throw new Error(`Current assets path ${e} is empty`);return e}))}else{if(!this.isFolder(n))throw new Error(`Invalid current assets path ${n}. It must be a folder or a zip file`);{const e=this.normalizeAssetFolderPath(n);if(this.isEmptyFolder(e))throw new Error(`Current assets path ${n} is empty`);this.newAssetsPath=Promise.resolve(e)}}this.destinationPath=i,this.mkdirpSync(this.destinationPath),this.changelogFilename=l||"CHANGELOG.html",s&&(this.templateIsValid(s)?this.changelogTemplate=s:this.logger.warn(v.yellow("Invalid changelog template, using default"))),"function"==typeof r&&(this.diffFileTemplateHandler=r),"function"==typeof a&&(this.diffLineTemplateHandler=a),c&&(this.contextLines=c)}templateIsValid(e){return e.includes("%FILES%")}isExists(e){return t.existsSync(e)}isZipFile(e){return e.endsWith(".zip")}isFolder(e){return t.lstatSync(e).isDirectory()}isEmptyFolder(e){return 0===t.readdirSync(e,{withFileTypes:!0}).length}mkdirpSync(e){t.existsSync(e)||t.mkdirSync(e,{recursive:!0})}async unzipFile(e,o){return t.rmSync(o,{force:!0,recursive:!0}),I(e,{dir:o})}normalizeAssetFolderPath(o){const n=t.readdirSync(o);return 1===n.length&&t.lstatSync(e.join(o,n[0])).isDirectory()?this.normalizeAssetFolderPath(e.join(o,n[0])):o}pathToPosix(e){return e.replace(/\\/g,"/")}diffTableTemplate(e){return`<table class="diff-table">\n <tbody>\n ${e}\n </tbody>\n </table>`}getDiffTableHTML(e){const t=e.filter(((e,t,o)=>0!==e.lineType||(t>=0&&t<this.contextLines||t>o.length-(this.contextLines+1)&&t<=o.length-1||o.slice(t-this.contextLines,t+this.contextLines+1).some((e=>0!==e.lineType))))).map(((e,t,o)=>{if(t>0){const n=o[t-1];if(e.lineNumber-n.lineNumber>1)return[{lineNumber:-1,lineContent:"",lineType:0},e]}return[e]})).flat().map((e=>this.diffLineHTML(e))).join("");return this.diffTableTemplate(t)}diffLineMessageTemplate(e){return`<tr>\n <td class="blob-num"></td>\n <td class="blob-num"></td>\n <td class="blob-code message">\n <span class="blob-code-inner">${e}</span>\n </td>\n </tr>`}diffLineSkipTemplate(){return'<tr>\n <td class="blob-num"></td>\n <td class="blob-num"></td>\n <td class="blob-code skip">\n <span class="blob-code-inner">Skip</span>\n </td>\n </tr>'}diffLineTemplate(e){const{lineNumber:t,lineContent:o,lineType:n}=e,i=1===n?"addition":-1===n?"deletion":"";return`<tr>\n <td\n class="blob-num ${i}${"addition"===i?" empty":""}"\n ${"addition"!==i?` data-line-number="${t}"`:""}\n ></td>\n <td\n class="blob-num ${i}${"deletion"===i?" empty":""}"\n ${"deletion"!==i?` data-line-number="${t}"`:""}\n ></td>\n <td class="blob-code ${1===n?"code-addition":-1===n?"code-deletion":""}">\n <span class="blob-code-inner" data-code-prefix="${1===n?"+":-1===n?"-":" "}">${s=o??"",s.replace(/[\u00A0-\u9999<>&]/g,(e=>"&#"+e.charCodeAt(0)+";"))}</span>\n </td>\n </tr>`;var s}diffLineHTML(e){if(this.diffLineTemplateHandler)return this.diffLineTemplateHandler(e);const{lineNumber:t}=e;return-1===t?this.diffLineSkipTemplate():this.diffLineTemplate(e)}diffFileTemplate(e,t){return this.diffFileTemplateHandler?this.diffFileTemplateHandler(e,t):`<div class="diff-file">\n <div class="diff-file-title">${e}</div>\n <div class="diff-file-content">${t}</div>\n </div>`}async generateAssetFoldersDiff(){this.logger.info(v.blue(`Comparing asset folders ${await this.oldAssetsPath} and ${await this.newAssetsPath}`));const e=await E.compare(await this.oldAssetsPath,await this.newAssetsPath,{compareContent:!0,skipSymlinks:!0,compareSize:!0,compareDate:!1,compareNameHandler:(e,t)=>(M.test(e)&&(e=e.replace(M,"$1$3")),M.test(t)&&(t=t.replace(M,"$1$3")),0===e.localeCompare(t)?0:e.localeCompare(t)>0?1:-1)});return e.diffSet?.filter((e=>"equal"!==e.state||e.name1!==e.name2))||[]}async generateAssetFilesDiff(e,t){const o=new k,n=o.diff_linesToChars_(e,t),i=o.diff_main(n.chars1,n.chars2,!1);o.diff_charsToLines_(i,n.lineArray);let s=0;return i.map((e=>{const[t,o]=e,n=o.endsWith("\n")?o.split("\n").length-1:o.split("\n").length,i=o.split("\n").map(((e,o)=>({lineContent:e,lineNumber:s+o+1,lineType:t}))).slice(0,n);return-1!==t&&(s+=n),i})).flat()}async generateFilesDiff(o){if("equal"===o.state){const t=this.pathToPosix(e.join(".",o.relativePath,o.name1??"")),n=this.pathToPosix(e.join(".",o.relativePath,o.name2??""));return this.diffFileTemplate(`<span class="renamed"\n >Renamed <span class="from">${t}</span> -> <span class="to">${n}</span></span\n >`,this.diffTableTemplate(this.diffLineMessageTemplate("No changes")))}const n=o.path1&&o.name1?e.join(o.path1,o.name1):null,i=o.path2&&o.name2?e.join(o.path2,o.name2):null,s=this.pathToPosix(e.join(".",o.relativePath,(o.name1||o.name2)??""));if("left"===o.state&&n)return this.diffFileTemplate(`<span class="removed">Removed ${s}</span>`,this.diffTableTemplate(this.diffLineMessageTemplate("File removed")));if("right"===o.state&&i)return this.diffFileTemplate(`<span class="added">Added ${s}</span>`,this.diffTableTemplate(this.diffLineMessageTemplate("File added")));if("distinct"===o.state&&n&&i){const r=this.pathToPosix(e.join(".",o.relativePath,o.name1??"")),a=this.pathToPosix(e.join(".",o.relativePath,o.name2??"")),l=o.name1!==o.name2?`<span class="renamed"\n >Renamed <span class="from">${r}</span> -> <span class="to">${a}</span></span\n >`:s;return this.diffFileTemplate(l,await A(n)||await A(i)?this.diffTableTemplate(this.diffLineMessageTemplate("Binary file")):this.getDiffTableHTML(await this.generateAssetFilesDiff(t.readFileSync(n,"utf-8"),t.readFileSync(i,"utf-8"))))}return""}async generateChangelog(){this.logger.info(v.green("Generating changelog"));const o=await this.generateAssetFoldersDiff(),n=(await Promise.all(o.map((e=>this.generateFilesDiff(e))))).join("");this.logger.info(v.green("Writing changelog file"));const i=this.changelogTemplate.split("%FILES%");i.splice(1,0,n);const s=i.join("");t.writeFileSync(e.join(this.destinationPath,this.changelogFilename),s),this.logger.info(v.green(`Changelog file written to ${e.join(this.destinationPath,this.changelogFilename)}`))}}class H{sourceDir;outputDir;fontName;constructor(e){this.sourceDir=e.sourceDir,this.outputDir=e.outputDir,this.fontName=e.fontName}async generate(){await N({src:this.sourceDir,dist:this.outputDir,fontName:this.fontName,css:!0,typescript:!0,startUnicode:59905,svgicons2svgfont:{fontHeight:1024}})}}const G=i("pp-dev");function O(t,o,i){const s=[...m,...b,"package.json","next.config.js","next.config.mjs","next.config.ts","vite.config.js","vite.config.mjs","vite.config.ts",".env",".env.local",".env.development",".env.development.local"].map((o=>e.join(t,o))),r=n(s,{ignored:/(^|[\/\\])\../,persistent:!0,ignoreInitial:!0,followSymlinks:!1});let a=null;return r.on("change",(n=>{i(v.blue(`šŸ”§ Config file changed: ${e.relative(t,n)}`)),a&&clearTimeout(a),a=setTimeout((async()=>{try{i(v.yellow("šŸ”„ Restarting dev server due to config change...")),await o()}catch(e){i(v.red(`āŒ Failed to restart dev server: ${e}`))}}),500)})),r.on("error",(e=>{i(v.red(`āŒ Config watcher error: ${e}`))})),{watcher:r,restartCallback:o,logger:i}}function U(e){e.watcher&&e.watcher.close()}let W=global.__pp_dev_profile_session,q=0;const B=o=>{if(W)return new Promise(((n,i)=>{W.post("Profiler.stop",((s,{profile:r})=>{if(s)i(s);else{const i=e.resolve(`./pp-dev-profile-${q++}.cpuprofile`);t.writeFileSync(i,JSON.stringify(r)),o(v.yellow(`CPU profile written to ${v.white(v.dim(i))}`)),W=void 0,n()}}))}))},V=e=>{for(const[t,o]of Object.entries(e))Array.isArray(o)&&(e[t]=o[o.length-1])};function Z(e){const t={...e};return delete t["--"],delete t.c,delete t.config,delete t.base,delete t.l,delete t.logLevel,delete t.clearScreen,delete t.d,delete t.debug,delete t.f,delete t.filter,delete t.m,delete t.mode,t}G.option("-c, --config <file>","[string] use specified config file").option("--base <path>","[string] public base path (default: /)").option("-l, --logLevel <level>","[string] info | warn | error | silent").option("--clearScreen","[boolean] allow/disable clear screen when logging").option("-d, --debug [feat]","[string | boolean] show debug logs").option("-f, --filter <filter>","[string] filter debug logs").option("-m, --mode <mode>","[string] set env mode"),G.command("[root]","start dev server").alias("serve").alias("dev").option("--host [host]","[string] specify hostname").option("--port <port>","[number] specify port").option("--https","[boolean] use TLS + HTTP/2").option("--open [path]","[boolean | string] open browser on startup").option("--cors","[boolean] enable CORS").option("--strictPort","[boolean] exit if specified port is already in use").option("--force","[boolean] force the optimizer to ignore the cache and re-bundle").action((async(t,n)=>{V(n);let i=null,a=null,l=!1;const c=t?e.resolve(process.cwd(),t):process.cwd(),d=w(n.logLevel),u=async()=>{if(!l){l=!0;try{i&&(d.info(v.yellow("šŸ›‘ Stopping existing dev server...")),await i.close(),i=null);const{clearConfigCache:e}=await import("./index-CmcaJY7U.js").then((e=>e.d));e();const{createServer:g}=await import("vite"),m=await s({mode:n.mode||"development",command:"serve"},n.config,t,n.logLevel);let b=await f();const y=p(n.mode||"development",t??process.cwd(),"");if(y&&Object.keys(y).forEach((e=>{e.startsWith("MI_")&&(process.env[e]=y[e])})),m){const{plugins:e,...t}=m.config;b=r(b,t)}if(i=await g(r(b,{root:t,base:n.base,mode:n.mode,configFile:n.config,logLevel:n.logLevel,clearScreen:n.clearScreen,optimizeDeps:{force:n.force},server:Z(n),customLogger:d},!0)),!i.config.base||"/"===i.config.base)throw new Error('base cannot be equal to "/" or empty string');if(!i.httpServer)throw new Error("HTTP server not available");await i.listen();const x=global.__pp_dev_start_time??!1,T=x?v.dim(`ready in ${v.reset(v.bold(Math.ceil(o.now()-x)))} ms`):"";d.info(`\n ${v.green(`${v.bold("PP-DEV")} v${h}`)} ${T}\n`),i.printUrls(),function(e,t){if(!e.httpServer||!process.stdin.isTTY||process.env.CI)return;e._shortcutsOptions=t;const o=w();t.print&&o.info(v.dim(v.green(" āžœ"))+v.dim(" press ")+v.bold("h")+v.dim(" to show help"));const n=(t.customShortcuts??[]).filter(_).concat(R);let i=!1;const s=async t=>{if(""===t||""===t)return void await e.close().finally((()=>process.exit(1)));if(i)return;"h"===t&&o.info(["",v.bold(" Shortcuts"),...n.map((e=>v.dim(" press ")+v.bold(e.key)+v.dim(` to ${e.description}`)))].join("\n"));const s=n.find((e=>e.key===t));s&&(i=!0,await s.action(e),i=!1)};process.stdin.setRawMode(!0),process.stdin.on("data",s).setEncoding("utf8").resume(),e.httpServer.on("close",(()=>{process.stdin.off("data",s).pause()}))}(i,{print:!0,customShortcuts:[...W?[{key:"p",description:"start/stop the profiler",async action(e){if(W)await B(d.info);else{const e=await import("node:inspector").then((e=>e.default));await new Promise((t=>{W=new e.Session,W.connect(),W.post("Profiler.enable",(()=>{W?.post("Profiler.start",(()=>{d.info("Profiler started"),t()}))}))}))}}}]:[],{key:"l",description:"proxy re-login",action(e){e.ws.send({type:"custom",event:"redirect",data:{url:`/auth/index/logout?proxyRedirect=${encodeURIComponent("/")}`}})}}]}),a||(a=O(c,u,d.info),d.info(v.blue("šŸ”§ Config file watcher started"))),l=!1}catch(e){l=!1,d.error(v.red(`error when starting dev server:\n${e.stack}`),{error:e}),B(d.info),process.exit(1)}}},g=async e=>{d.info(v.yellow(`\nšŸ›‘ Received ${e}, shutting down gracefully...`));try{a&&(U(a),a=null),i&&(await i.close(),i=null),B(d.info),d.info(v.green("āœ… Graceful shutdown completed")),process.exit(0)}catch(e){d.error(v.red(`āŒ Error during graceful shutdown: ${e}`)),process.exit(1)}};process.on("SIGINT",(()=>g("SIGINT"))),process.on("SIGTERM",(()=>g("SIGTERM"))),process.on("uncaughtException",(e=>{d.error(v.red(`āŒ Uncaught Exception: ${e}`)),g("uncaughtException")})),process.on("unhandledRejection",((e,t)=>{d.error(v.red(`āŒ Unhandled Rejection at: ${t}, reason: ${e}`)),g("unhandledRejection")})),await u()})),G.command("next [root]","start Next.js development server with pp-dev integration").alias("next-serve").alias("next-dev").option("--host [host]","[string] specify hostname").option("--port <port>","[number] specify port",{default:3e3}).option("--https","[boolean] use TLS + HTTP/2").option("--open [path]","[boolean | string] open browser on startup").option("--cors","[boolean] enable CORS").option("--strictPort","[boolean] exit if specified port is already in use").option("--force","[boolean] force the optimizer to ignore the cache and re-bundle").action((async(t,o)=>{V(o);let n=null,i=null,s=null,r=!1;t?e.resolve(process.cwd(),t):process.cwd();const a=w(),l=async()=>{if(!r){r=!0;try{i&&(a.info(v.yellow("šŸ›‘ Stopping existing Next.js server...")),await new Promise((e=>{i.close((()=>{i=null,e()}))}))),n&&"function"==typeof n.close&&(await n.close(),n=null);const{clearConfigCache:e}=await import("./index-CmcaJY7U.js").then((e=>e.d));if(e(),!u())throw new Error("Next.js is required but not available. Please install Next.js as a dependency:\nnpm install next@^13\n\nThis package requires Next.js >=13 <16 as a peer dependency.");const{next:c}=await g(),{join:d,basename:f}=await import("path"),{createServer:h}=await import("http"),{default:m}=(await import("next/dist/server/config.js")).default,b=Z(o),w=p(o.mode||"development",t??process.cwd(),"");w&&Object.keys(w).forEach((e=>{e.startsWith("MI_")&&(process.env[e]=w[e])}));const E=t?d(process.cwd(),t):process.cwd();a.info(E);const k=await m("development",E);let A=k?.experimental?.ppDev||k?.ppDev||{};if(0===Object.keys(A).length)try{const{getConfig:e}=await import("./index-CmcaJY7U.js").then((e=>e.d)),t=await e();Object.keys(t).length>0?(A=t,a.info(v.blue("šŸ”§ Loaded pp-dev config from standalone config file"))):a.info(v.yellow("āš ļø No pp-dev config found in Next.js config or standalone file, using defaults"))}catch(e){a.info(v.yellow("āš ļø Failed to load standalone pp-dev config, using defaults")),console.debug("Error loading standalone config:",e)}else a.info(v.blue("šŸ”§ Loaded pp-dev config from Next.js config"));const{backendBaseURL:D=process.env.MI_BACKEND_URL||"http://localhost:8080",portalPageId:C=parseInt(process.env.MI_PORTAL_PAGE_ID||"1"),templateLess:I=!0,v7Features:N=!0,disableSSLValidation:_=!1,enableProxyCache:R=!0,proxyCacheTTL:M=6e5,personalAccessToken:z=process.env.MI_ACCESS_TOKEN,distZip:H=!1,syncBackupsDir:G="./backups",miHudLess:W=!1}=A;let q=A.templateName;if(!q)try{const{getPkg:e}=await import("./index-CmcaJY7U.js").then((e=>e.d));q=e().name}catch(e){q=f(E)}let B=I?"/p":"/pl";if(B+=`/${q}`,n=c({dev:!0,hostname:b.host||"localhost",port:b.port,dir:E,conf:{...k,basePath:B,assetPrefix:B}}),await n.prepare(),B.endsWith("/")||(B+="/"),"/"===B)throw new Error('basePath cannot be equal to "/" or equal to empty string');B.substring(0,B.lastIndexOf("/"));a.info(v.green("āœ… Next.js app prepared successfully")),a.info(v.blue(`šŸ”§ pp-dev plugin configured for template: ${q}`)),a.info(v.blue(`šŸ”§ Base path configured: ${B}`)),D&&(a.info(v.blue(`🌐 Backend URL: ${D}`)),a.info(v.blue(`šŸ†” Portal Page ID: ${C}`)));const V=n.getRequestHandler(),K="number"==typeof b.port?b.port:3e3,Y="string"==typeof b.host?b.host||"0.0.0.0":"localhost",J=new Set;i=h((async(e,t)=>{try{const o=e.url||"/",n=o.split("?")[0];let i=j(o,!0);if(X.length>0){if(n.startsWith("/_next/")||"/favicon.ico"===n||n.startsWith("/__nextjs_")||n.startsWith("/api/")){if(ee.length>0){let l=0;const c=()=>{if(l>=ee.length)return void s();const o=ee[l];l++,o(e,t,c)};return void c()}return void s()}let r=0;const a=()=>{if(r>=X.length)return void s();const o=X[r];r++,o(e,t,a)};return void a()}async function s(){if(n.startsWith(B)){const t=n.substring(B.length);e.url=t||"/",i=j(t,!0)}else if(n===B.replace(/\/$/,""))e.url="/",i=j("/",!0);else if(n.startsWith("/_next/")||"/favicon.ico"===n||n.startsWith("/__nextjs_"));else if("/"===n)return t.writeHead(302,{Location:B}),void t.end();await V(e,t,i)}s()}catch(d){console.error("[DEBUG] Error:",d),t.statusCode=500,t.end("Internal Server Error")}}));let Q=null,X=[],ee=[];if(D){const e=new URL(D).host,t={headers:{host:e,referer:D,origin:D.replace(/^(https?:\/\/)([^/]+)(\/.*)?$/i,"$1$2")},portalPageId:C,appId:C,templateLess:I,disableSSLValidation:_,v7Features:N,personalAccessToken:z??process.env.MI_ACCESS_TOKEN};Q=new y(D,t);const o=x(B,q),n=(e,t,n)=>{o(e,t,n)};if(ee.push(n),X.push(n),R){let e=+M;(!e||Number.isNaN(e)||e<0)&&(e=6e5);const t={middlewares:{use:e=>e},config:{logger:console}},o=T({devServer:t,ttl:e}),n=(e,t,n)=>{o(e,t,n)};X.push(n),a.info(v.blue(`šŸ”§ Proxy cache middleware added with TTL: ${e}ms`))}const i=B.endsWith("/")?B.substring(0,B.length-1):B,s={middlewares:{use:e=>e},config:{logger:console}},r=P({devServer:s,baseURL:D,proxyIgnore:["/@vite","/@metricinsights","/@",i,"/_next","/favicon.ico","/__nextjs_","/api"],disableSSLValidation:_,miAPI:Q}),l=(e,t,o)=>{r(e,t,o)};X.push(l);const c=new RegExp(`^((${B})|/)$`),d=$(c,Q,{base:B,v7Features:N}),p=(e,t,o)=>{d(e,t,o)};X.push(p);const f=S,h=(e,t,o)=>{if(e.url?.startsWith("/@api/")){f(e,t,(()=>{}))}else o()};ee.push(h),X.push(h);const u=L((e=>e.split("?")[0].endsWith("index.html")),((t,o)=>Buffer.from(F(e,o.headers.host??"",Q.buildPage(t,W))))),g=(e,t,o)=>{u(e,t,o)};X.push(g),a.info(v.blue(`šŸ”§ ${X.length} pp-dev middlewares initialized`)),a.info(v.blue(`šŸ”§ ${ee.length} essential middlewares for internal routes`)),a.info(v.blue(`šŸ”§ MiAPI initialized for backend: ${D}`)),a.info(v.blue(`šŸ”§ Portal Page ID: ${C}`))}i.listen(K,Y,(()=>{a.info(v.green(`āœ… pp-dev Next.js server running at http://${Y}:${K}`)),a.info(v.blue(`šŸ“± Next.js app accessible at http://${Y}:${K}${B}`)),a.info(v.blue("šŸ”§ Base path handling active")),s||(s=O(E,l,a.info),a.info(v.blue("šŸ”§ Config file watcher started"))),i.on("connection",(e=>{J.add(e),e.on("close",(()=>J.delete(e)))}));const e=async e=>{a.info(v.yellow(`\nšŸ›‘ Received ${e}, shutting down gracefully...`));const t=setTimeout((()=>{a.info(v.yellow("ā° Shutdown timeout reached, forcing exit")),process.exit(0)}),5e3);try{s&&(U(s),s=null);for(const e of Array.from(J))e.destroy();J.clear(),await new Promise((e=>{i.close((()=>{a.info(v.yellow("šŸ›‘ HTTP server closed")),e()}))})),n&&"function"==typeof n.close&&(await n.close(),a.info(v.yellow("šŸ›‘ Next.js app closed"))),clearTimeout(t),a.info(v.green("āœ… Graceful shutdown completed")),process.exit(0)}catch(e){clearTimeout(t),a.error(v.red(`āŒ Error during graceful shutdown: ${e}`)),process.exit(1)}};let t=process;if("function"!=typeof process.on){const e=globalThis.process||global.process;e&&"function"==typeof e.on&&(t=e,a.info(v.green("āœ… Using global process object for event handlers")))}if("function"==typeof t.on)try{t.on("SIGINT",(()=>e("SIGINT"))),t.on("SIGTERM",(()=>e("SIGTERM"))),t.on("uncaughtException",(t=>{a.error(v.red(`āŒ Uncaught Exception: ${t}`)),e("uncaughtException")})),t.on("unhandledRejection",((t,o)=>{a.error(v.red(`āŒ Unhandled Rejection at: ${o}, reason: ${t}`)),e("unhandledRejection")})),a.info(v.green("āœ… Process event handlers registered successfully"))}catch(e){a.warn(v.yellow(`āš ļø Failed to register process event handlers: ${e}`))}else a.warn(v.yellow("āš ļø process.on is not available, graceful shutdown handlers will not be registered")),a.info(v.blue("šŸ’” This might be due to bundling or environment constraints"))})),r=!1}catch(e){r=!1,a.error(v.red(`āŒ Failed to start Next.js server: ${e}`)),e instanceof Error&&e.message.includes("Next.js is required")&&(a.error(v.red("āŒ Next.js Peer Dependency Error:")),a.error(v.red(e.message)),a.error(v.yellow("\nšŸ’” To fix this issue:")),a.error(v.blue(" 1. Install Next.js in your project:")),a.error(v.white(" npm install next@^15")),a.error(v.blue(" 2. Or use yarn:")),a.error(v.white(" yarn add next@^15")),a.error(v.blue(" 3. Or use pnpm:")),a.error(v.white(" pnpm add next@^15")),a.error(v.yellow("\nšŸ“– For more information, see:")),a.error(v.blue(" https://nextjs.org/docs/getting-started"))),process.exit(1)}}},c=async e=>{a.info(v.yellow(`\nšŸ›‘ Received ${e}, shutting down gracefully...`));try{s&&(U(s),s=null),i&&await new Promise((e=>{i.close((()=>{i=null,e()}))})),n&&"function"==typeof n.close&&(await n.close(),n=null),a.info(v.green("āœ… Graceful shutdown completed")),process.exit(0)}catch(e){a.error(v.red(`āŒ Error during graceful shutdown: ${e}`)),process.exit(1)}};process.on("SIGINT",(()=>c("SIGINT"))),process.on("SIGTERM",(()=>c("SIGTERM"))),process.on("uncaughtException",(e=>{a.error(v.red(`āŒ Uncaught Exception: ${e}`)),c("uncaughtException")})),process.on("unhandledRejection",((e,t)=>{a.error(v.red(`āŒ Unhandled Rejection at: ${t}, reason: ${e}`)),c("unhandledRejection")})),await l()})),G.command("build [root]","build for production").option("--target <target>","[string] transpile target (default: 'modules')").option("--outDir <dir>","[string] output directory (default: dist)").option("--assetsDir <dir>","[string] directory under outDir to place assets in (default: assets)").option("--assetsInlineLimit <number>","[number] static asset base64 inline threshold in bytes (default: 4096)").option("--ssr [entry]","[string] build specified entry for server-side rendering").option("--sourcemap [output]",'[boolean | "inline" | "hidden"] output source maps for build (default: false)').option("--minify [minifier]",'[boolean | "terser" | "esbuild"] enable/disable minification, or specify minifier to use (default: esbuild)').option("--manifest [name]","[boolean | string] emit build manifest json").option("--ssrManifest [name]","[boolean | string] emit ssr manifest json").option("--force","[boolean] force the optimizer to ignore the cache and re-bundle (experimental)").option("--emptyOutDir","[boolean] force empty outDir when it's outside of root").option("-w, --watch","[boolean] rebuilds when modules have changed on disk").option("--changelog [assetsFile]","[boolean | string] generate changelog between assetsFile and current build (default: false)").action((async(o,n)=>{V(n);const i=Z(n);try{const l=await s({mode:n.mode||"production",command:"build"},n.config,o,n.logLevel);let c=await f();if(l){const{plugins:e,...t}=l.config;c=r(c,t)}const d=r(c,{root:o,base:n.base,mode:n.mode,configFile:n.config,logLevel:n.logLevel,clearScreen:n.clearScreen,optimizeDeps:{force:n.force},build:i},!0);if(await a(d),i.changelog){const s=o||process.cwd(),r=d.build?.outDir||"dist";let a="";if("string"==typeof i.changelog)a=e.resolve(s,i.changelog);else{const o=e.resolve(s,d.ppDevConfig?.syncBackupsDir||"backups");if(!t.existsSync(o))return void w(n.logLevel).warn(v.yellow("backups directory not found, skipping changelog generation"));const i=t.readdirSync(o,{withFileTypes:!0});if(!i.length)return void w(n.logLevel).warn(v.yellow("no backups found, skipping changelog generation"));const r=i.filter((e=>e.isFile()&&e.name.endsWith(".zip"))).reduce(((n,i)=>t.statSync(e.resolve(o,n.name)).mtimeMs>t.statSync(e.resolve(o,i.name)).mtimeMs?n:i),i[0]).name;a=e.resolve(o,r)}const l=e.resolve(s,r);let c="dist-zip";d.ppDevConfig&&(!1===d.ppDevConfig.distZip?c=d.build?.outDir||"dist":"object"==typeof d.ppDevConfig.distZip&&"string"==typeof d.ppDevConfig.distZip.outDir&&(c=d.ppDevConfig.distZip.outDir));const p=new z({oldAssetsPath:a,newAssetsPath:l,destinationPath:e.resolve(s,c)});await p.generateChangelog()}}catch(e){w(n.logLevel).error(v.red(`error during build:\n${e.stack}`),{error:e}),process.exit(1)}finally{B((e=>w(n.logLevel).info(e)))}})),G.command("changelog [oldAssetPath] [newAssetPath]","generate changelog between two assets files/folders").option("--oldAssetsPath <oldAssetsPath>","[string] path to the old assets zip file or folder").option("--newAssetsPath <newAssetsPath>","[string] path to the new assets zip file or folder").option("--destination <destination>","[string] destination folder for the changelog (default: .)").option("--filename <filename>","[string] filename for the changelog (default: CHANGELOG.html)").action((async(t,o,n)=>{V(n);const{oldAssetsPath:i=t,newAssetsPath:s=o,destination:r=".",filename:a="CHANGELOG.html",logLevel:l}=n,c=process.cwd();i&&s||(w(l).error(v.red("error during changelog generation: oldAssetPath and newAssetPath are required")),process.exit(1));const d=e.resolve(c,i),p=e.resolve(c,s),f=e.resolve(c,r),h=new z({oldAssetsPath:d,newAssetsPath:p,destinationPath:f,changelogFilename:a});await h.generateChangelog()})),G.command("generate-icon-font [source] [destination]","generate icon font from SVG files").option("--source <source>","[string] path to the source directory with SVG files").option("--destination <destination>","[string] path to the destination directory to save the generated font files").option("--font-name, -n <fontName>","[string] name of the font to generate (default: 'icon-font')").action((async(t,o,n)=>{V(n);const{source:i=t,destination:s=o,fontName:r="icon-font"}=n,a=process.cwd(),l=e.resolve(a,i),c=e.resolve(a,s),d=new H({sourceDir:l,outputDir:c,fontName:r}),p=w(n.logLevel);p.info(`Generating icon font from SVG files in ${v.dim(l)}`),await d.generate(),p.info(`Icon font generated and saved to ${v.dim(c)}`)})),G.command("optimize [root]","pre-bundle dependencies").option("--force","[boolean] force the optimizer to ignore the cache and re-bundle").action((async(e,t)=>{V(t);try{const o=await s({mode:t.mode||"production",command:"build"},t.config,e,t.logLevel);let n=await f();if(o){const{plugins:e,...t}=o.config;n=r(n,t)}const i=await l(r(n,{root:e,base:t.base,configFile:t.config,logLevel:t.logLevel,mode:t.mode}),"serve");await c(i,t.force,!0)}catch(e){w(t.logLevel).error(v.red(`error when optimizing deps:\n${e.stack}`),{error:e}),process.exit(1)}})),G.command("preview [root]","locally preview production build").option("--host [host]","[string] specify hostname").option("--port <port>","[number] specify port").option("--strictPort","[boolean] exit if specified port is already in use").option("--https","[boolean] use TLS + HTTP/2").option("--open [path]","[boolean | string] open browser on startup").option("--outDir <dir>","[string] output directory (default: dist)").action((async(e,t)=>{V(t);try{const o=await s({mode:t.mode||"production",command:"build"},t.config,e,t.logLevel);let n=await f();if(o){const{plugins:e,...t}=o.config;n=r(n,t)}(await d(r(n,{root:e,base:t.base,configFile:t.config,logLevel:t.logLevel,mode:t.mode,build:{outDir:t.outDir},preview:{port:t.port,strictPort:t.strictPort,host:t.host,https:t.https,open:t.open}}))).printUrls()}catch(e){w(t.logLevel).error(v.red(`error when starting preview server:\n${e.stack}`),{error:e}),process.exit(1)}finally{B((e=>w(t.logLevel).info(e)))}})),G.help(),G.version(h),G.parse();export{B as stopProfiler}; //# sourceMappingURL=cli.js.map