import{a as E}from"./chunk-HQMJSXYT.js";import{b as f,d as w,e as y}from"./chunk-DWY47FQV.js";import{spawn as k}from"child_process";import{once as v}from"events";import{mkdir as T}from"fs/promises";import{join as $}from"path";import{setTimeout as x}from"timers/promises";import{process as C}from"std-env";var{PRISMA_DEV_FORCE_ENGINE_BINARY_DOWNLOAD:O,PRISMA_DEV_FORCE_ENGINE_BINARY_PATH:H,PRISMA_DEV_FORCE_NETWORK_DELAY_MS:b}=C.env,P=class o{static#t=new Map;#e;#n;constructor(e){this.#e=e,this.#n=null}static async get(e){let{debug:n}=e,i=`${e.schemaHash}:${e.clientVersion}`;try{let t=o.#t.get(i);if(t)return t;let s=new o(e);return o.#t.set(i,s),n&&console.debug("[Query Engine] starting...",e),await s.start(),n&&console.debug("[Query Engine] started!"),s}finally{o.stopAll(i)}}static async stopAll(e){let i=(await Promise.allSettled(Array.from(o.#t.entries()).filter(([t])=>t!==e).map(async([t,s])=>{try{await s.stop()}finally{o.#t.delete(t)}}))).filter(t=>t.status==="rejected").map(t=>t.reason);if(i.length>0)throw new AggregateError(i,"Failed to stop engines")}async commitTransaction(e,n){return await this.#s(e,n,"commit")}async request(e,n){let{url:i}=await this.start(),t=this.#i(n),s=await fetch(i,{body:typeof e=="string"?e:JSON.stringify(e),headers:{...t,"Content-Type":"application/json"},method:"POST"});if(!s.ok)throw await l.fromResponse(s);return await s.text()}async rollbackTransaction(e,n){return await this.#s(e,n,"rollback")}async startTransaction(e,n){let{url:i}=await this.start(),t=this.#i(n),s=await fetch(`${i}/transaction/start`,{body:JSON.stringify(e),headers:{...t,"Content-Type":"application/json"},method:"POST"});if(!s.ok)throw await l.fromResponse(s);return await s.json()}async start(){if(this.#n!=null)return await this.#n;let{promise:e,reject:n,resolve:i}=E();this.#n=e;let t=H||await this.#r();this.#e.debug&&console.debug("[Query Engine] spinning up at path...",t);let{proxySignals:s}=await import("foreground-child/proxy-signals"),r=k(t,["--enable-raw-queries","--enable-telemetry-in-response","--port","0"],{env:{LOG_QUERIES:"y",PRISMA_DML:this.#e.base64Schema,QE_LOG_LEVEL:"TRACE",RUST_BACKTRACE:"1",RUST_LOG:"info"},stdio:["ignore","pipe","pipe"],windowsHide:!0});s(r),r.stderr.setEncoding("utf8"),r.stdout.setEncoding("utf8");let c=a=>{let d=a.split(`
`).find(S=>S.includes("Started query engine http server"));if(!d)return;r.stdout.removeListener("data",c);let{fields:p}=JSON.parse(d);if(p==null)return n(new Error(`Unexpected data during initialization, "fields" are missing: ${a}`));let{ip:m,port:h}=p;if(m==null||h==null)return n(new Error(`This version of query-engine is not compatible with minippg, "ip" and "port" are missing in the startup log entry.
Received data: ${a}`));i({childProcess:r,url:`http://${m}:${h}`})},R=a=>{this.#n=null,n(new g(String(a))),r.removeListener("exit",u),r.kill()};r.once("error",R);let u=(a,d)=>{this.#n=null,n(new g(`Query Engine exited with code ${a} and signal ${d}`))};return r.once("exit",u),r.stdout.on("data",c),this.#e.debug&&(r.stderr.on("data",console.error.bind(console,"[Query Engine]")),r.stdout.on("data",console.debug.bind(console,"[Query Engine]"))),await this.#n}async stop(){if(this.#n==null)return;let{childProcess:e}=await this.#n;e.exitCode==null&&e.signalCode==null&&(this.#n=null,e.kill(),await v(e,"exit"))}async#r(){this.#e.debug&&console.debug("[Query Engine] getting engine commit hash...");let e=await this.#o();this.#e.debug&&console.debug("[Query Engine] got engine commit hash",e);let n=f(this.#e.clientVersion,e);this.#e.debug&&console.debug("[Query Engine] cache directory path",n),await T(n,{recursive:!0});let{binaryTarget:i}=this.#e.platform,t=i==="windows"?".exe":"",s=$(n,`query-engine-${i}${t}`);return this.#e.debug&&console.debug("[Query Engine] binary path",s),(O==="1"||await w(s)===!1)&&await this.#a({commitHash:e,extension:t,engineBinaryPath:s}),s}async#o(){let e=await fetch(`https://registry.npmjs.org/@prisma/client/${this.#e.clientVersion}`);if(!e.ok)throw new Error(`Couldn't fetch package.json from npm registry, status code: ${e.status}`);let i=(await e.json()).devDependencies?.["@prisma/engines-version"];if(!i)throw new Error("Couldn't find engines version in package.json");let t=i.split(".").at(-1);if(!t)throw new Error("Couldn't find commit hash in engines version");return t}async#a(e){let{commitHash:n,extension:i,engineBinaryPath:t}=e,{binaryTarget:s}=this.#e.platform,r=`https://binaries.prisma.sh/all_commits/${n}/${s}/query-engine${i}.gz`;this.#e.debug&&console.debug("[Query Engine] downloading engine from url",r);let c=await fetch(r);if(!c.ok)throw new Error(`Couldn't download engine. URL: ${r}, status code: ${c.status}`);b&&await x(Number(b)),await y(await c.arrayBuffer(),t),this.#e.debug&&console.debug("[Query Engine] downloaded and saved at",t)}#i(e){let n={};for(let[i,t]of Object.entries(e))t!=null&&(n[i]=t);return n}async#s(e,n,i){let{url:t}=await this.#n,s=this.#i(n),r=await fetch(`${t}/transaction/${e}/${i}`,{headers:{...s,"Content-Type":"application/json"},method:"POST"});if(!r.ok)throw await l.fromResponse(r);try{return await r.json()}catch{return{}}}};function M(o,e){return console.error(o),o instanceof g?e.json({EngineNotStarted:{reason:{EngineStartupError:{logs:[],msg:o.message}}}},500):o instanceof l?e.text(o.responseBody,o.statusCode):e.body(null,500)}var g=class extends Error{name="EngineStartError"},l=class o extends Error{constructor(n,i,t){super(`${n}: Query Engine response status ${i}, body: ${t}`);this.action=n;this.statusCode=i;this.responseBody=t}name="EngineHttpError";static async fromResponse(n){let i=new URL(n.url),t=await n.text();return new o(i.pathname,n.status,t)}};export{P as Engine,M as handleEngineError};
