import{checkPort as w,getPort as m,isUnsafePort as O}from"get-port-please";import{difference as T,range as $}from"remeda";var v=51214,h=51213,S=51215,p=65535,k=0,P=-1/0;async function E(o){let{debug:t,name:r,requestedPorts:n,servers:u}=o,{portsUsedByOtherServers:e,portsUsedByThisServerLastTime:a}=B(r,u);t&&(console.debug(`ports used by other servers: ${Object.keys(e).join(", ")}`),console.debug(`ports used by "${r}" server last time: ${JSON.stringify(a)}`));let i={databasePort:P,port:P,shadowDatabasePort:P},s=["port","databasePort","shadowDatabasePort"];for(let c of s){let d=await x({debug:t,portKey:c,portsUsedByOtherServers:e,portsUsedByThisServerLastTime:a,requestedPorts:n})??await U({debug:t,pickedPorts:i,portKey:c,portsUsedByOtherServers:e,portsUsedByThisServerLastTime:a});t&&console.debug(`Got port for "${c}": ${d}`),i[c]=d}return t&&console.debug(`Picked ports: ${JSON.stringify(i)}`),i}async function x(o){let{debug:t,portKey:r,portsUsedByOtherServers:n,portsUsedByThisServerLastTime:u,requestedPorts:e}=o,{[r]:a,...i}=e;if(g(a))return await R({debug:t,otherRequestedPorts:i,portKey:r,portsUsedByOtherServers:n,requestedPort:a}),a;let s=u?.[r]??P;if(!g(s))return t&&console.debug(`No port specified for "${r}". Trying to pick a new port.`),null;let c=s in n;return c||Object.values(i).includes(s)?(t&&console.debug(`Port ${s} that was used last time for this server, ${c?"is also used by another server":"has been requested for another service"}. Trying to pick a new port.`),null):await w(s)===!1?(t&&console.debug(`Port ${s}, that was used last time for this server, is not available. Trying to pick a new port.`),null):(t&&console.debug(`Using port ${s} for "${r}" as it was used last time and is available.`),s)}async function U(o){let{debug:t,pickedPorts:r,portKey:n,portsUsedByOtherServers:u,portsUsedByThisServerLastTime:e}=o,a=Math.max(v,h,S)+1,i=[...Object.values(r),...Object.keys(u).map(Number),...Object.values(e||{})],s=Math.min(Math.max(a,...i)+100,p),c=T($(a,s),i),d={port:h,databasePort:v,shadowDatabasePort:S}[n];try{return await m({port:d in u||Object.values(r).includes(d)||Object.values(e||{}).includes(d)?void 0:d,ports:c})}catch(b){if(b instanceof Error&&b.name==="GetPortError"&&s+1<=p)return t&&console.debug(`Expanding port lookup to range [${s+1}, ${p}].`),await m({portRange:[s+1,p]});throw b}}function g(o){return Number.isFinite(o)&&o>=0}function B(o,t){let r={},n;for(let u of t){let{databasePort:e,port:a,shadowDatabasePort:i}=u;if(u.name===o){n={databasePort:e,port:a,shadowDatabasePort:i};continue}r[e]=!0,r[a]=!0,r[i]=!0}return{portsUsedByOtherServers:r,portsUsedByThisServerLastTime:n}}async function R(o){let{debug:t,otherRequestedPorts:r,portKey:n,portsUsedByOtherServers:u,requestedPort:e}=o;if(e!==k){if(e in u)throw t&&console.error(`Port ${e} was requested for "${n}", but is already used by another server.`),new y(e);if(Object.values(r).includes(e))throw t&&console.error(`Port ${e} was requested for "${n}", but also for another key.`),new l(e);if(O(e))throw t&&console.error(`Port ${e} was requested for "${n}", but is unsafe.`),new f(e);if(await w(e)===!1)throw t&&console.error(`Port ${e} was requested for "${n}", but is not available.`),new f(e)}}var f=class extends Error{constructor(r){super(`Port \`${r}\` is not available.`);this.port=r}name="PortNotAvailableError"},l=class extends Error{constructor(r){super(`Port number \`${r}\` was requested twice. Please choose a different port for each service.`);this.port=r}name="PortRequestedTwiceError"},y=class extends Error{constructor(r){super(`Port number \`${r}\` belongs to another Prisma Dev server. Please choose a different port.`);this.port=r}name="PortBelongsToAnotherServerError"};export{v as a,h as b,S as c,k as d,P as e,E as f,f as g};
