UNPKG

@prisma/dev

Version:

A local Prisma Postgres server for development and testing

6 lines (5 loc) • 31.5 kB
"use strict";var _t=Object.create;var J=Object.defineProperty;var kt=Object.getOwnPropertyDescriptor;var It=Object.getOwnPropertyNames;var Ct=Object.getPrototypeOf,Bt=Object.prototype.hasOwnProperty;var D=(t,e)=>()=>(t&&(e=t(t=0)),e);var ne=(t,e)=>{for(var r in e)J(t,r,{get:e[r],enumerable:!0})},Te=(t,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of It(e))!Bt.call(t,n)&&n!==r&&J(t,n,{get:()=>e[n],enumerable:!(o=kt(e,n))||o.enumerable});return t};var S=(t,e,r)=>(r=t!=null?_t(Ct(t)):{},Te(e||!t||!t.__esModule?J(r,"default",{value:t,enumerable:!0}):r,t)),Ht=t=>Te(J({},"__esModule",{value:!0}),t);var p=D(()=>{"use strict"});function Ae(t){return Buffer.from(JSON.stringify(Object.fromEntries(Object.entries(t).sort(([[e],[r]])=>e.localeCompare(r)))),"utf8").toString("base64url")}function jt(t){let e=Buffer.from(t,"base64url").toString("utf8"),{issues:r,output:o,success:n}=(0,f.safeParse)(Lt,e,{abortEarly:!0});return n?[null,o]:[r]}var f,Oe,Lt,k,se=D(()=>{"use strict";p();f=require("valibot"),Oe=/^(postgres|postgresql):\/\//,Lt=(0,f.pipe)((0,f.string)(),(0,f.parseJson)(),(0,f.object)({databaseUrl:(0,f.pipe)((0,f.string)(),(0,f.url)(),(0,f.regex)(Oe)),name:(0,f.optional)((0,f.pipe)((0,f.string)(),(0,f.minLength)(1))),shadowDatabaseUrl:(0,f.pipe)((0,f.string)(),(0,f.url)(),(0,f.regex)(Oe))}));k=async(t,e)=>{let{authorization:r}=t,{HTTPException:o}=await import("hono/http-exception");if(!r)throw new o(401,{message:"Missing API Key"});let[n,s="",a]=r.split(" ");if(n!=="Bearer"||a)throw new o(401,{message:"Invalid API Key"});let[i,c]=jt(s);if(i)throw new o(401,{message:"Invalid API Key",cause:i.join(", ")});let{databaseUrl:u,name:l,shadowDatabaseUrl:g}=c,{name:b}=e.get("serverState");if(!l)throw new o(401,{message:`Wrong API Key; The Prisma Dev server running at port ${e.get("port")} requires an API Key from a newer version of \`prisma dev\`. Check the "${b}" server's output for the updated \`DATABASE_URL\` value.`});if(l!==b)throw new o(401,{message:`Wrong API Key; The Prisma Dev server running at port ${e.get("port")} is named "${b}", but the API Key is for "${l}"`});let{hostname:T,port:O}=new URL(u),{port:N}=e.get("db"),{hostname:At,port:xt}=new URL(g),$t=e.get("shadowDBPort");if(T!=="localhost"||Number(O)!==N||At!=="localhost"||Number(xt)!==$t)throw new o(401,{message:"Wrong API Key; Check your Prisma schema's `provider.url` value (probably defined in `.env`'s `DATABASE_URL` environment variable) is aligned with `prisma dev`'s output"});return{decodedAPIKey:c}}});function ce(t,{suffix:e="nodejs"}={}){if(typeof t!="string")throw new TypeError(`Expected a string, got ${typeof t}`);return e&&(t+=`-${e}`),Q.default.platform==="darwin"?Mt(t):Q.default.platform==="win32"?Ut(t):Nt(t)}var h,ae,Q,A,ie,I,Mt,Ut,Nt,xe=D(()=>{"use strict";p();h=S(require("path"),1),ae=S(require("os"),1),Q=S(require("process"),1),A=ae.default.homedir(),ie=ae.default.tmpdir(),{env:I}=Q.default,Mt=t=>{let e=h.default.join(A,"Library");return{data:h.default.join(e,"Application Support",t),config:h.default.join(e,"Preferences",t),cache:h.default.join(e,"Caches",t),log:h.default.join(e,"Logs",t),temp:h.default.join(ie,t)}},Ut=t=>{let e=I.APPDATA||h.default.join(A,"AppData","Roaming"),r=I.LOCALAPPDATA||h.default.join(A,"AppData","Local");return{data:h.default.join(r,t,"Data"),config:h.default.join(e,t,"Config"),cache:h.default.join(r,t,"Cache"),log:h.default.join(r,t,"Log"),temp:h.default.join(ie,t)}},Nt=t=>{let e=h.default.basename(A);return{data:h.default.join(I.XDG_DATA_HOME||h.default.join(A,".local","share"),t),config:h.default.join(I.XDG_CONFIG_HOME||h.default.join(A,".config"),t),cache:h.default.join(I.XDG_CACHE_HOME||h.default.join(A,".cache"),t),log:h.default.join(I.XDG_STATE_HOME||h.default.join(A,".local","state"),t),temp:h.default.join(ie,e,t)}}});function Ce(t,e){return`${Ie.cache}/engine/${t}/${e}`}function F(t){return`${Ie.data}/${t}`}async function Be(t){try{return await(0,v.access)(t,v.constants.F_OK),!0}catch(e){if(ue(e))return!1;throw e}}async function He(t,e){let r=await Ft(t);await(0,v.writeFile)(e,r),await(0,v.chmod)(e,"755")}async function Le(t,e){await t.stream().pipeTo(W.WriteStream.toWeb((0,W.createWriteStream)(e,{encoding:"utf-8"})))}function ue(t){return t!=null&&typeof t=="object"&&"code"in t&&t.code==="ENOENT"}async function je(t){try{return await(0,v.readFile)(t,{encoding:"utf-8"})}catch(e){if(ue(e))return null;throw e}}async function Me(t){await(0,v.mkdir)(t,{recursive:!0})}async function Ue(t,e){try{return(await(0,v.readdir)(t,{withFileTypes:!0})).reduce((o,n)=>(n.isDirectory()&&!n.name.startsWith(".")&&(!e||(0,ke.default)(e,n.name))&&o.push(n.name),o),[])}catch(r){if(ue(r))return[];throw r}}var W,v,$e,_e,ke,Ie,Ft,z=D(()=>{"use strict";p();W=require("fs"),v=require("fs/promises"),$e=require("util"),_e=require("zlib");xe();ke=S(require("zeptomatch"),1),Ie=ce("prisma-dev"),Ft=(0,$e.promisify)(_e.unzip)});function Z(t){let e,r,o=new Promise((a,i)=>{e=a,r=i}),n=a=>{n=s=null,r(a),t?.onRejected?.(a),t?.onFulfilled?.()},s=a=>{s=n=null,e(a),t?.onResolved?.(a),t?.onFulfilled?.()};return{isFulfilled:()=>s===n,promise:o,reject:a=>n?.(a),resolve:a=>s?.(a)}}var me=D(()=>{"use strict";p()});function ee(t,e){return console.error(t),t instanceof q?e.json({EngineNotStarted:{reason:{EngineStartupError:{logs:[],msg:t.message}}}},500):t instanceof L?e.text(t.responseBody,t.statusCode):e.body(null,500)}var We,ze,Xe,Ye,Ze,et,Xt,Yt,Qe,j,q,L,fe=D(()=>{"use strict";p();We=require("child_process"),ze=require("events"),Xe=require("fs/promises"),Ye=require("path"),Ze=require("timers/promises");me();et=require("std-env");z();({PRISMA_DEV_FORCE_ENGINE_BINARY_DOWNLOAD:Xt,PRISMA_DEV_FORCE_ENGINE_BINARY_PATH:Yt,PRISMA_DEV_FORCE_NETWORK_DELAY_MS:Qe}=et.process.env),j=class t{static#r=new Map;#e;#t;constructor(e){this.#e=e,this.#t=null}static async get(e){let{debug:r}=e,o=`${e.schemaHash}:${e.clientVersion}`;try{let n=t.#r.get(o);if(n)return n;let s=new t(e);return t.#r.set(o,s),r&&console.debug("[Query Engine] starting...",e),await s.start(),r&&console.debug("[Query Engine] started!"),s}finally{t.stopAll(o)}}static async stopAll(e){let o=(await Promise.allSettled(Array.from(t.#r.entries()).filter(([n])=>n!==e).map(async([n,s])=>{try{await s.stop()}finally{t.#r.delete(n)}}))).filter(n=>n.status==="rejected").map(n=>n.reason);if(o.length>0)throw new AggregateError(o,"Failed to stop engines")}async commitTransaction(e,r){return await this.#i(e,r,"commit")}async request(e,r){let{url:o}=await this.start(),n=this.#o(r),s=await fetch(o,{body:typeof e=="string"?e:JSON.stringify(e),headers:{...n,"Content-Type":"application/json"},method:"POST"});if(!s.ok)throw await L.fromResponse(s);return await s.text()}async rollbackTransaction(e,r){return await this.#i(e,r,"rollback")}async startTransaction(e,r){let{url:o}=await this.start(),n=this.#o(r),s=await fetch(`${o}/transaction/start`,{body:JSON.stringify(e),headers:{...n,"Content-Type":"application/json"},method:"POST"});if(!s.ok)throw await L.fromResponse(s);return await s.json()}async start(){if(this.#t!=null)return await this.#t;let{promise:e,reject:r,resolve:o}=Z();this.#t=e;let n=Yt||await this.#s();this.#e.debug&&console.debug("[Query Engine] spinning up at path...",n);let{proxySignals:s}=await import("foreground-child/proxy-signals"),a=(0,We.spawn)(n,["--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(a),a.stderr.setEncoding("utf8"),a.stdout.setEncoding("utf8");let i=l=>{let g=l.split(` `).find(N=>N.includes("Started query engine http server"));if(!g)return;a.stdout.removeListener("data",i);let{fields:b}=JSON.parse(g);if(b==null)return r(new Error(`Unexpected data during initialization, "fields" are missing: ${l}`));let{ip:T,port:O}=b;if(T==null||O==null)return r(new Error(`This version of query-engine is not compatible with minippg, "ip" and "port" are missing in the startup log entry. Received data: ${l}`));o({childProcess:a,url:`http://${T}:${O}`})},c=l=>{this.#t=null,r(new q(String(l))),a.removeListener("exit",u),a.kill()};a.once("error",c);let u=(l,g)=>{this.#t=null,r(new q(`Query Engine exited with code ${l} and signal ${g}`))};return a.once("exit",u),a.stdout.on("data",i),this.#e.debug&&(a.stderr.on("data",console.error.bind(console,"[Query Engine]")),a.stdout.on("data",console.debug.bind(console,"[Query Engine]"))),await this.#t}async stop(){if(this.#t==null)return;let{childProcess:e}=await this.#t;e.exitCode==null&&e.signalCode==null&&(this.#t=null,e.kill(),await(0,ze.once)(e,"exit"))}async#s(){this.#e.debug&&console.debug("[Query Engine] getting engine commit hash...");let e=await this.#a();this.#e.debug&&console.debug("[Query Engine] got engine commit hash",e);let r=Ce(this.#e.clientVersion,e);this.#e.debug&&console.debug("[Query Engine] cache directory path",r),await(0,Xe.mkdir)(r,{recursive:!0});let{platform:o}=this.#e.platform,n=o==="windows"?".exe":"",s=(0,Ye.join)(r,`query-engine-${o}${n}`);return this.#e.debug&&console.debug("[Query Engine] binary path",s),(Xt==="1"||await Be(s)===!1)&&await this.#n({commitHash:e,extension:n,engineBinaryPath:s}),s}async#a(){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 o=(await e.json()).devDependencies?.["@prisma/engines-version"];if(!o)throw new Error("Couldn't find engines version in package.json");let n=o.split(".").at(-1);if(!n)throw new Error("Couldn't find commit hash in engines version");return n}async#n(e){let{commitHash:r,extension:o,engineBinaryPath:n}=e,{binaryTarget:s}=this.#e.platform,a=`https://binaries.prisma.sh/all_commits/${r}/${s}/query-engine${o}.gz`;this.#e.debug&&console.debug("[Query Engine] downloading engine from url",a);let i=await fetch(a);if(!i.ok)throw new Error(`Couldn't download engine. URL: ${a}, status code: ${i.status}`);Qe&&await(0,Ze.setTimeout)(Number(Qe)),await He(await i.arrayBuffer(),n),this.#e.debug&&console.debug("[Query Engine] downloaded and saved at",n)}#o(e){let r={};for(let[o,n]of Object.entries(e))n!=null&&(r[o]=n);return r}async#i(e,r,o){let{url:n}=await this.#t,s=this.#o(r),a=await fetch(`${n}/transaction/${e}/${o}`,{headers:{...s,"Content-Type":"application/json"},method:"POST"});if(!a.ok)throw await L.fromResponse(a);try{return await a.json()}catch{return{}}}};q=class extends Error{name="EngineStartError"},L=class t extends Error{constructor(r,o,n){super(`${r}: Query Engine response status ${o}, body: ${n}`);this.action=r;this.statusCode=o;this.responseBody=n}name="EngineHttpError";static async fromResponse(r){let o=new URL(r.url),n=await r.text();return new t(o.pathname,r.status,n)}}});async function tt(t){let{output:e,success:r}=(0,w.safeParse)(Zt,await t.req.json(),{abortEarly:!0});return r?e:t.text("Invalid input",400)}var w,Zt,rt=D(()=>{"use strict";p();w=require("valibot"),Zt=(0,w.object)({tags:(0,w.union)([(0,w.pipe)((0,w.array)((0,w.string)()),(0,w.minLength)(1)),(0,w.literal)("all")])})});async function ge(t){let r=new TextEncoder().encode(t),o=await crypto.subtle.digest("SHA-256",r);return Array.from(new Uint8Array(o)).map(a=>a.toString(16).padStart(2,"0")).join("")}function nt(t){let e=t.req.param("schemaHash"),r=te.get(e);return r==null?t.json({EngineNotStarted:{reason:"SchemaMissing"}},404):{schemaHash:e,schemas:r}}async function st(t,e,r){let o=he.Buffer.from(t,"base64").toString("utf8"),n=(0,ot.produceSchema)(o,a=>{a.datasource('"postgresql"',e.toString())});r&&console.log("[Accelerate] schema with override:",n);let s=await ge(n);return{base64Override:he.Buffer.from(n,"utf8").toString("base64"),overrideHash:s}}var he,ot,te,at=D(()=>{"use strict";p();he=require("buffer"),ot=require("@mrleebo/prisma-ast"),te=new Map});function re(t){let{req:e}=t;return{traceparent:e.header("traceparent"),"X-capture-telemetry":e.header("X-capture-telemetry")}}var it=D(()=>{"use strict";p()});async function ct(t){let{issues:e,output:r,success:o}=(0,m.safeParse)(er,await t.req.json(),{abortEarly:!0});return o?r:t.json({EngineNotStarted:{reason:"InvalidRequest",issues:e}},400)}function ut(t,e){let{output:r,success:o}=(0,m.safeParse)(tr,t);return o?r:e.json({EngineMalfunction:{}},500)}var m,er,tr,dt=D(()=>{"use strict";p();m=require("valibot"),er=(0,m.object)({isolation_level:(0,m.optional)((0,m.string)()),max_wait:(0,m.pipe)((0,m.number)(),(0,m.integer)(),(0,m.minValue)(0)),timeout:(0,m.pipe)((0,m.number)(),(0,m.integer)(),(0,m.minValue)(0))});tr=(0,m.looseObject)({id:(0,m.union)([(0,m.string)(),(0,m.number)()])})});var pt={};ne(pt,{accelerateRoute:()=>oe});async function ye(t){let{req:e}=t,r=nt(t);if(r instanceof Response)return r;let{base64Override:o,overrideHash:n}=r.schemas;return await j.get({base64Schema:o,clientVersion:process.env.PRISMA_DEV_FORCE_CLIENT_VERSION||e.param("clientVersion"),debug:t.get("debug"),platform:t.get("platform"),schemaHash:n})}var lt,M,oe,rr,V,or,mt=D(()=>{"use strict";p();lt=require("hono/tiny"),M=require("hono/validator");se();rt();fe();at();it();dt();oe=new lt.Hono;oe.post("/invalidate",(0,M.validator)("header",k),async t=>{let e=await tt(t);return e instanceof Response?e:t.body(null)});rr="/:clientVersion/:schemaHash",V=oe.basePath(rr);oe.route("/",V);or=["/graphql","/itx/:transactionId/graphql"];V.on("POST",[...or],(0,M.validator)("header",k),async t=>{let{req:e}=t;try{let r=await ye(t);if(r instanceof Response)return r;let o=await e.text(),n=e.param("transactionId"),s=await r.request(o,{...re(t),"X-transaction-id":n});return t.text(s)}catch(r){return ee(r,t)}});V.basePath("/itx/:transactionId").on("POST",["/commit","/rollback"],(0,M.validator)("header",k),async t=>{let{req:e}=t;try{let r=await ye(t);if(r instanceof Response)return r;let n=`${e.routePath.split("/").filter(Boolean).at(-1)}Transaction`,s=e.param("transactionId"),a=await r[n](s,re(t));return t.json(a)}catch(r){return ee(r,t)}});V.put("/schema",(0,M.validator)("header",k),async t=>{let{req:e}=t,r=await e.text();if(!r)return t.text("Missing schema",400);let o=e.param("schemaHash"),n=te.get(o);if(n==null){if(o!==await ge(r))return t.text("Schema hash mismatch",400);let s=await st(r,t.get("db").prismaORMConnectionString,t.get("debug"));return te.set(o,{base64Original:r,...s}),t.text(o)}return r!==n.base64Original?t.text("Schema mismatch",400):t.text(o)});V.post("/transaction/start",(0,M.validator)("header",k),async t=>{let{req:e}=t,r=await ct(t);if(r instanceof Response)return r;try{let o=await ye(t);if(o instanceof Response)return o;let n=await o.startTransaction(r,re(t)),s=ut(n,t);if(s instanceof Response)return s;let{id:a}=s,i=e.param("clientVersion"),c=t.get("port"),u=t.get("protocol"),l=e.param("schemaHash");return t.json({...n,"data-proxy":{endpoint:`${u}://localhost:${c}/${i}/${l}/itx/${a}`}})}catch(o){return ee(o,t)}})});var gt={};ne(gt,{utilityRoute:()=>be});var ft,ht,be,Qr,yt=D(()=>{"use strict";p();ft=require("hono/tiny"),ht=require("http-status-codes"),be=new ft.Hono;be.post("/database/dump",async t=>{let e=t.get("db"),r=t.get("serverState");return await e.dump(r.databaseDumpPath),t.json({dumpPath:r.databaseDumpPath},ht.StatusCodes.CREATED)});Qr=be.get("/health",t=>t.json({name:t.get("serverState").name}))});var dr={};ne(dr,{DEFAULT_DATABASE_PORT:()=>C,DEFAULT_SERVER_PORT:()=>B,DEFAULT_SHADOW_DATABASE_PORT:()=>H,PortNotAvailableError:()=>E,ServerAlreadyRunningError:()=>K,unstable_startServer:()=>ur});module.exports=Ht(dr);p();se();p();var Ge=require("pathe/utils");z();p();var $=require("get-port-please"),Y=require("remeda"),C=51214,B=51213,H=51215,X=65535,x=-1/0;async function Fe(t){let{debug:e,name:r,requestedPorts:o,servers:n}=t,{portsUsedByOtherServers:s,portsUsedByThisServerLastTime:a}=Gt(r,n);e&&(console.debug(`ports used by other servers: ${Object.keys(s).join(", ")}`),console.debug(`ports used by "${r}" server last time: ${JSON.stringify(a)}`));let i={databasePort:x,port:x,shadowDatabasePort:x},c=["port","databasePort","shadowDatabasePort"];for(let u of c){let l=await qt({debug:e,portKey:u,portsUsedByOtherServers:s,portsUsedByThisServerLastTime:a,requestedPorts:o})??await Vt({debug:e,pickedPorts:i,portKey:u,portsUsedByOtherServers:s,portsUsedByThisServerLastTime:a});e&&console.debug(`Got port for "${u}": ${l}`),i[u]=l}return e&&console.debug(`Picked ports: ${JSON.stringify(i)}`),i}async function qt(t){let{debug:e,portKey:r,portsUsedByOtherServers:o,portsUsedByThisServerLastTime:n,requestedPorts:s}=t,{[r]:a,...i}=s;if(Ne(a))return await Kt({debug:e,otherRequestedPorts:i,portKey:r,portsUsedByOtherServers:o,requestedPort:a}),a;let c=n?.[r]??x;if(!Ne(c))return e&&console.debug(`No port specified for "${r}". Trying to pick a new port.`),null;let u=c in o;return u||Object.values(i).includes(c)?(e&&console.debug(`Port ${c} that was used last time for this server, ${u?"is also used by another server":"has been requested for another service"}. Trying to pick a new port.`),null):await(0,$.checkPort)(c)===!1?(e&&console.debug(`Port ${c}, that was used last time for this server, is not available. Trying to pick a new port.`),null):(e&&console.debug(`Using port ${c} for "${r}" as it was used last time and is available.`),c)}async function Vt(t){let{debug:e,pickedPorts:r,portKey:o,portsUsedByOtherServers:n,portsUsedByThisServerLastTime:s}=t,a=Math.max(C,B,H)+1,i=[...Object.values(r),...Object.keys(n).map(Number),...Object.values(s||{})],c=Math.min(Math.max(a,...i)+100,X),u=(0,Y.difference)((0,Y.range)(a,c),i),l={port:B,databasePort:C,shadowDatabasePort:H}[o];try{return await(0,$.getPort)({port:l in n||Object.values(r).includes(l)||Object.values(s||{}).includes(l)?void 0:l,ports:u})}catch(g){if(g instanceof Error&&g.name==="GetPortError"&&c+1<=X)return e&&console.debug(`Expanding port lookup to range [${c+1}, ${X}].`),await(0,$.getPort)({portRange:[c+1,X]});throw g}}function Ne(t){return t>=0}function Gt(t,e){let r={},o;for(let n of e){let{databasePort:s,port:a,shadowDatabasePort:i}=n;if(n.name===t){o={databasePort:s,port:a,shadowDatabasePort:i};continue}r[s]=!0,r[a]=!0,r[i]=!0}return{portsUsedByOtherServers:r,portsUsedByThisServerLastTime:o}}async function Kt(t){let{debug:e,otherRequestedPorts:r,portKey:o,portsUsedByOtherServers:n,requestedPort:s}=t;if(s in n)throw e&&console.error(`Port ${s} was requested for "${o}", but is already used by another server.`),new le(s);if(Object.values(r).includes(s))throw e&&console.error(`Port ${s} was requested for "${o}", but also for another key.`),new de(s);if((0,$.isUnsafePort)(s))throw e&&console.error(`Port ${s} was requested for "${o}", but is unsafe.`),new E(s);if(await(0,$.checkPort)(s)===!1)throw e&&console.error(`Port ${s} was requested for "${o}", but is not available.`),new E(s)}var E=class extends Error{constructor(r){super(`Port \`${r}\` is not available.`);this.port=r}name="PortNotAvailableError"},de=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"},le=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"};var y={connectionLimit:1,connectTimeout:0,database:"template1",maxIdleConnectionLifetime:0,password:"postgres",poolTimeout:0,socketTimeout:0,sslMode:"disable",username:"postgres"},Jt=`postgres://${y.username}:${y.password}@localhost`,Ke=new URLSearchParams({sslmode:y.sslMode}),Qt=new URLSearchParams({...Object.fromEntries(Ke.entries()),connection_limit:String(y.connectionLimit),connect_timeout:String(y.connectTimeout),max_idle_connection_lifetime:String(y.maxIdleConnectionLifetime),pool_timeout:String(y.poolTimeout),single_use_connections:"true",socket_timeout:String(y.socketTimeout)});async function pe(t,e){let r=t==="database"?e.databasePort:e.shadowDatabasePort;if(e.dryRun)return qe(t,e,{db:null,port:r,server:null});let{debug:o}=e,s=await(t==="shadow_database"?Wt:Je)(e.pgliteDataDirPath,o);o&&s.onNotification((c,u)=>{console.debug(`[${t}][${c}] ${u}`)});let{PGLiteSocketServer:a}=await import("@electric-sql/pglite-socket"),i=new a({db:s,debug:o,inspect:o,port:r});o&&(i.addEventListener("listening",c=>{let{detail:u}=c;console.debug(`[${t}] server listening on ${JSON.stringify(u)}`)}),i.addEventListener("connection",c=>{let{clientAddress:u,clientPort:l}=c.detail;console.debug(`[${t}] client connected from ${u}:${l}`)}),i.addEventListener("error",c=>{let{detail:u}=c;console.error(`[${t}] server error:`,u)}));try{await i.start()}catch(c){throw c instanceof Error&&"code"in c&&c.code==="EADDRINUSE"?new E(r):c}return qe(t,e,{db:s,port:r,server:i})}function qe(t,e,r){let{debug:o}=e,{db:n,port:s,server:a}=r||{};return o&&console.debug(`[${t}] server started on port ${s}`),{...y,close:async()=>{let i=[];try{await a?.stop(),o&&console.debug(`[${t}] server stopped on port ${s}`)}catch(c){console.error(`[${t}] server stop error`,c),i.push(c)}if(t==="database")try{await n?.syncToFs(),o&&console.debug(`[${t}] synced to filesystem`)}catch(c){console.error(`[${t}] sync error`,c),i.push(c)}try{await n?.close(),o&&console.debug(`[${t}] closed`)}catch(c){console.error(`[${t}] close error`,c),i.push(c)}if(i.length>0)throw new AggregateError(i,`Failed to close ${t} properly`)},connectionString:Ve(s,Ke),dump:async i=>{t==="shadow_database"||!n||await zt({db:n,debug:o,destinationPath:i})},port:s,prismaORMConnectionString:Ve(s,Qt),terminalCommand:`PGPASSWORD=${y.password} PGSSLMODE=${y.sslMode} psql -h localhost -p ${s} -U ${y.username} -d ${y.database}`}}function Ve(t,e){return`${Jt}:${t}/${y.database}?${e.toString()}`}async function Je(t,e){let{PGlite:r}=await import("@electric-sql/pglite");return await r.create({database:y.database,dataDir:t,debug:e?5:void 0,relaxedDurability:!1,username:y.username})}async function Wt(t,e){let{PGlite:r}=await import("@electric-sql/pglite");return await r.create({database:y.database,dataDir:"memory://",debug:e?5:void 0,relaxedDurability:!1,username:y.username})}async function zt(t){let{dataDir:e,db:r,debug:o,destinationPath:n}=t,s=r||await Je(e,o),{pgDump:a}=await import("@electric-sql/pglite-tools/pg_dump"),i=await a({args:["--schema-only","--no-owner"],fileName:n?(0,Ge.filename)(n):void 0,pg:await s.clone()});return n?(o&&console.debug(`[DB] Dumping database to ${n}`),await Le(i,n)):(o&&console.debug("[DB] Dumping database to memory"),await i.text())}p();var Pt=require("http"),wt=require("util"),St=S(require("@prisma/get-platform"),1);me();fe();async function vt(t,e){let{port:r}=e;if(e.dryRun)return bt(r,null);let o=await nr(r,t,e),{promise:n,reject:s,resolve:a}=Z(),{serve:i}=await import("@hono/node-server"),c=i({createServer:Pt.createServer,fetch:o.fetch,overrideGlobalObjects:!1,port:r},a);return c.on("error",u=>{if(typeof u=="object"&&"code"in u&&u.code==="EADDRINUSE")return s(new E(r));console.error("[Accelerate]",u)}),await n,bt(r,c)}function bt(t,e){return{async close(){e&&await Promise.allSettled([(0,wt.promisify)(e.close.bind(e))(),j.stopAll()])},port:t,url:`http://localhost:${t}`}}async function nr(t,e,r){let{debug:o}=r,[{Hono:n},{accelerateRoute:s},{utilityRoute:a}]=await Promise.all([import("hono/tiny"),Promise.resolve().then(()=>(mt(),pt)),Promise.resolve().then(()=>(yt(),gt))]),i=new n,c=await St.default.getPlatformInfo();if(o&&console.debug("[Accelerate] platform info: %s",JSON.stringify(c)),o){let{logger:l}=await import("hono/logger");i.use("*",l((...g)=>console.log("[Accelerate]",...g)))}i.use("*",async(l,g)=>(l.set("db",e),l.set("debug",!!o),l.set("platform",c),l.set("port",t),l.set("protocol","http"),l.set("serverState",r),l.set("shadowDBPort",r.shadowDatabasePort),await g()));let u=new n;return u.route("/",s),u.route("/",a),i.route("/",u),i}p();var Ot=require("fs/promises"),_=require("pathe"),U=require("proper-lockfile"),Ee=require("std-env"),d=require("valibot");z();p();var sr=require("timers/promises"),Dt=require("std-env");function Et(t,e){if(t==null)return!1;try{return Dt.process.kill?.(t,0)??!0}catch(r){return e&&console.error(`Error checking if process with PID ${t} exists:`,r),!1}}var Se=(0,d.pipe)((0,d.string)(),(0,d.url)()),Rt=(0,d.object)({connectionString:Se,prismaORMConnectionString:(0,d.optional)(Se),terminalCommand:(0,d.optional)((0,d.string)())}),Tt=(0,d.object)({url:Se}),Pe=(0,d.pipe)((0,d.number)(),(0,d.integer)(),(0,d.minValue)(1)),ar=(0,d.object)({database:Rt,http:Tt,ppg:Tt,shadowDatabase:Rt}),ir=(0,d.object)({databasePort:Pe,exports:(0,d.optional)(ar),name:(0,d.pipe)((0,d.string)(),(0,d.minLength)(1)),pid:(0,d.optional)((0,d.pipe)((0,d.number)(),(0,d.integer)(),(0,d.minValue)(0))),port:Pe,shadowDatabasePort:Pe,version:(0,d.literal)("1")}),Re=Symbol("initialize"),we="default",R=class{_databasePort;debug;dryRun;name;persistenceMode;pid;_port;_shadowDatabasePort;constructor(e){this._databasePort=e.databasePort??x,this.debug=e.debug??!1,this.dryRun=e.dryRun??!1,this.name=e.name??we,this.persistenceMode=e.persistenceMode,this.pid=e.pid??Ee.process.pid,this._port=e.port??x,this._shadowDatabasePort=e.shadowDatabasePort??x}static async createExclusively(e){let r=e?.dryRun!==!0&&e?.persistenceMode!=="stateless"?new G(e):new ve(e);return await r[Re](),r}static async fromServerDump(e){let{debug:r,name:o=we}=e??{},n=F(o),s=G.getServerDumpPath(n),a=await je(s);if(a==null)return r&&console.debug(`[State] No server dump file found at: ${s}`),null;r&&(console.debug(`[State] server dump file found at "${s}":`),console.debug(a));let{issues:i,output:c,success:u}=(0,d.safeParse)((0,d.pipe)((0,d.string)(),(0,d.parseJson)(),ir),a);if(!u)throw r&&console.debug(`[State] Invalid server dump file at "${s}": ${JSON.stringify(i,null,2)}`),new Error(`Invalid Prisma Dev state for "${o}".`);return new G({databasePort:c.databasePort,debug:r,dryRun:!1,name:o,pid:c.pid,port:c.port,serverDump:c,shadowDatabasePort:c.shadowDatabasePort})}static async scan(e){let{debug:r,globs:o}=e??{},n=(0,_.join)(F(we),"..");r&&console.debug(`[State] scanning for server states in: ${n}`);let s=await Ue(n,o);return r&&console.debug(`[State] found server names: ${JSON.stringify(s)}`),await Promise.all(s.map(a=>cr(a,e)))}get databasePort(){return this._databasePort}get port(){return this._port}get shadowDatabasePort(){return this._shadowDatabasePort}},ve=class extends R{constructor(e){super({...e,databasePort:e?.databasePort??C,persistenceMode:"stateless",port:e?.port??B,shadowDatabasePort:e?.shadowDatabasePort??H})}get databaseDumpPath(){return"<DUMP_PATH>"}get pgliteDataDirPath(){return"memory://"}async[Re](){}async close(){}async writeServerDump(){}},G=class t extends R{#r;#e;#t;#s;#a;#n;#o;constructor(e){super({...e,persistenceMode:"stateful"}),this.#n=!1,this.#e=F(this.name),this.#r=(0,_.join)(this.#e,"db_dump.bak"),this.#t=(0,_.join)(this.#e,".lock"),this.#s=(0,_.join)(this.#e,".pglite"),this.#o=e?.serverDump??null,this.#a=t.getServerDumpPath(this.#e)}static getServerDumpPath(e){return(0,_.join)(e,"server.json")}get databaseDumpPath(){return this.#r}get exports(){return this.#o?.exports}get pgliteDataDirPath(){return this.#s}async[Re](){await Me(this.#e),this.debug&&console.debug(`[State] using data directory: ${this.#e}`);try{await(0,U.lock)(this.#e,{lockfilePath:this.#t}),this.debug&&console.debug(`[State] obtained lock on: ${this.#e}`);let e=await R.scan({debug:this.debug,onlyMetadata:!0}),r=await Fe({debug:this.debug,name:this.name,requestedPorts:{databasePort:this.databasePort,port:this.port,shadowDatabasePort:this.shadowDatabasePort},servers:e});this._databasePort=r.databasePort,this._port=r.port,this._shadowDatabasePort=r.shadowDatabasePort,await this.writeServerDump()}catch(e){throw e instanceof Error&&"code"in e&&e.code==="ELOCKED"?new K(this):e}}async close(){if(!this.#n)try{await(0,U.unlock)(this.#e,{lockfilePath:this.#t}),this.#n=!0,this.debug&&console.debug(`[State] released lock on: ${this.#e}`)}catch(e){throw this.debug&&console.error(`[State] failed to release lock on: ${this.#e}`,e),e}}async writeServerDump(e){this.#o={name:this.name,version:"1",pid:Ee.process.pid,port:this.port,databasePort:this.databasePort,shadowDatabasePort:this.shadowDatabasePort,exports:e},await(0,Ot.writeFile)(this.#a,`${JSON.stringify(this.#o,null,2)} `,{encoding:"utf-8"})}};async function cr(t,e){let{debug:r,onlyMetadata:o}=e||{},n=typeof t=="string"?t:t.name,s=typeof t!="string"?t:void 0,a={databasePort:s?.databasePort??-1,exports:s?.exports,name:n,pid:s?.pid,port:s?.port??-1,shadowDatabasePort:s?.shadowDatabasePort??-1,version:"1"};try{let i=s||await R.fromServerDump({debug:r,name:n});if(!i)return r&&console.debug(`[State] no server state found for name: ${n}`),{...a,status:"no_such_server"};a.databasePort=i.databasePort,a.exports=i.exports,a.pid=i.pid,a.port=i.port,a.shadowDatabasePort=i.shadowDatabasePort;let{exports:c,pid:u}=i;if(o)return{...a,status:"unknown"};if(!Et(u,r))return r&&console.debug(`[State] server state for "${n}" has no running process with PID: ${u}`),{...a,status:"not_running"};let l=F(n);try{if(!await(0,U.check)(l,{lockfilePath:(0,_.join)(l,".lock")}))return r&&console.debug(`[State] server state for "${n}" is not locked, indicating it is not running.`),{...a,status:"starting_up"}}catch(N){r&&console.error(`[State] server state for "${n}" failed to check lock:`,N)}if(!c)return{...a,status:"starting_up"};let{http:g}=c,{hc:b}=await import("hono/client"),T=await b(g.url).health.$get();if(!T.ok)return r&&console.debug(`[State] server state for "${n}" is not live: ${JSON.stringify(T)}`),{...a,status:"not_running"};let O=await T.json();return O.name!==t?(r&&console.debug(`[State] server state for "${n}" has mismatched health response: ${JSON.stringify(O)}`),{...a,status:"unknown"}):(r&&console.debug(`[State] server state for "${t}" is live: ${JSON.stringify(O)}`),{...a,status:"running"})}catch(i){return r&&console.error(`[State] failed to get server status for "${n}":`,i),{...a,status:"error"}}}var De=class extends Error{name="ServerStateAlreadyExistsError";constructor(e){super(`A Prisma Dev server with the name "${e}" is already running.`)}},K=class extends De{#r;name="ServerAlreadyRunningError";constructor(e){super(e.name),this.#r=e}get server(){return R.fromServerDump({debug:this.#r.debug,name:this.#r.name})}};async function ur(t){let e=await R.createExclusively(t),[r,o]=await Promise.all([pe("database",e),pe("shadow_database",e)]),n=await vt(r,e),s=`prisma+postgres://localhost:${n.port}/?${new URLSearchParams({api_key:Ae({databaseUrl:r.prismaORMConnectionString,name:e.name,shadowDatabaseUrl:o.prismaORMConnectionString})}).toString()}`,a={database:{connectionString:r.connectionString,prismaORMConnectionString:r.prismaORMConnectionString,terminalCommand:r.terminalCommand},http:{url:n.url},ppg:{url:s},shadowDatabase:{connectionString:o.prismaORMConnectionString,prismaORMConnectionString:o.prismaORMConnectionString,terminalCommand:o.terminalCommand}};return await e.writeServerDump(a),{...a,close:()=>i(e,[n,r,o]),name:e.name};async function i(c,u){let g=(await Promise.allSettled(u.map(b=>b.close()))).filter(b=>b.status==="rejected").map(b=>new Error(b.reason));try{await c.close()}catch(b){g.push(b)}if(g.length>0)throw new AggregateError(g,"Failed to close some servers")}}0&&(module.exports={DEFAULT_DATABASE_PORT,DEFAULT_SERVER_PORT,DEFAULT_SHADOW_DATABASE_PORT,PortNotAvailableError,ServerAlreadyRunningError,unstable_startServer});