UNPKG

@prisma/dev

Version:

A local Prisma Postgres server for development and testing

4 lines (3 loc) 7.26 kB
import{a as V,b as N,c as L,d as f,e as F}from"./chunk-LMPFMHCB.js";import{b as d,f as O,g as I,h as A,i as T}from"./chunk-EPFUMVT3.js";import{writeFile as X}from"fs/promises";import{join as l}from"pathe";import{check as ee,lock as te,unlock as re}from"proper-lockfile";import{process as B}from"std-env";import{integer as C,literal as se,minLength as ae,minValue as H,number as K,object as P,optional as g,parseJson as oe,pipe as h,safeParse as ne,string as v,url as ie}from"valibot";import{setTimeout as Q}from"timers/promises";import{process as b}from"std-env";function y(t,e){if(t==null)return!1;try{return b.kill?.(t,0)??!0}catch(r){return e&&console.error(`Error checking if process with PID ${t} exists:`,r),!1}}async function J(t,e){if(!b.kill)return!1;try{b.kill(t,"SIGTERM")}catch(n){return e&&console.error(`Error killing process with PID ${t}:`,n),!1}let r=0;do{if(!y(t,e))return!0;await Q(100)}while(++r<50);try{return b.kill(t,"SIGKILL")}catch(n){return e&&console.error(`Error forcefully killing process with PID ${t}:`,n),!1}}var _=h(v(),ie()),U=P({connectionString:_,prismaORMConnectionString:g(_),terminalCommand:g(v())}),j=P({url:_}),w=h(K(),C(),H(1)),ue=P({database:U,http:j,ppg:j,shadowDatabase:U}),ce=P({databasePort:w,exports:g(ue),name:h(v(),ae(1)),pid:g(h(K(),C(),H(0))),port:w,shadowDatabasePort:w,version:se("1")}),R=Symbol("initialize"),x="default",c=class{_databasePort;debug;dryRun;name;persistenceMode;pid;_port;_shadowDatabasePort;constructor(e){this._databasePort=e.databasePort??f,this.debug=e.debug??!1,this.dryRun=e.dryRun??!1,this.name=e.name??x,this.persistenceMode=e.persistenceMode,this.pid=e.pid??B.pid,this._port=e.port??f,this._shadowDatabasePort=e.shadowDatabasePort??f}static async createExclusively(e){let r=e?.dryRun!==!0&&e?.persistenceMode!=="stateless"?new p(e):new k(e);return await r[R](),r}static async fromServerDump(e){let{debug:r,name:n=x}=e??{},a=d(n),o=p.getServerDumpPath(a),s=await O(o);if(s==null)return r&&console.debug(`[State] No server dump file found at: ${o}`),null;r&&(console.debug(`[State] server dump file found at "${o}":`),console.debug(s));let{issues:i,output:u,success:m}=ne(h(v(),oe(),ce),s);if(!m)throw r&&console.debug(`[State] Invalid server dump file at "${o}": ${JSON.stringify(i,null,2)}`),new Error(`Invalid Prisma Dev state for "${n}".`);return new p({databasePort:u.databasePort,debug:r,dryRun:!1,name:n,pid:u.pid,port:u.port,serverDump:u,shadowDatabasePort:u.shadowDatabasePort})}static async scan(e){let{debug:r,globs:n}=e??{},a=l(d(x),"..");r&&console.debug(`[State] scanning for server states in: ${a}`);let o=await A(a,n);return r&&console.debug(`[State] found server names: ${JSON.stringify(o)}`),await Promise.all(o.map(s=>q(s,e)))}get databasePort(){return this._databasePort}get port(){return this._port}get shadowDatabasePort(){return this._shadowDatabasePort}},k=class extends c{constructor(e){super({...e,databasePort:e?.databasePort??V,persistenceMode:"stateless",port:e?.port??N,shadowDatabasePort:e?.shadowDatabasePort??L})}get databaseDumpPath(){return"<DUMP_PATH>"}get pgliteDataDirPath(){return"memory://"}async[R](){}async close(){}async writeServerDump(){}},p=class t extends c{#t;#e;#s;#o;#n;#a;#r;constructor(e){super({...e,persistenceMode:"stateful"}),this.#a=!1,this.#e=d(this.name),this.#t=l(this.#e,"db_dump.bak"),this.#s=l(this.#e,".lock"),this.#o=l(this.#e,".pglite"),this.#r=e?.serverDump??null,this.#n=t.getServerDumpPath(this.#e)}static getServerDumpPath(e){return l(e,"server.json")}get databaseDumpPath(){return this.#t}get exports(){return this.#r?.exports}get pgliteDataDirPath(){return this.#o}async[R](){await I(this.#e),this.debug&&console.debug(`[State] using data directory: ${this.#e}`);try{await te(this.#e,{lockfilePath:this.#s}),this.debug&&console.debug(`[State] obtained lock on: ${this.#e}`);let e=await c.scan({debug:this.debug,onlyMetadata:!0}),r=await F({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 E(this):e}}async close(){if(!this.#a)try{await re(this.#e,{lockfilePath:this.#s}),this.#a=!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.#r={name:this.name,version:"1",pid:B.pid,port:this.port,databasePort:this.databasePort,shadowDatabasePort:this.shadowDatabasePort,exports:e},await X(this.#n,`${JSON.stringify(this.#r,null,2)} `,{encoding:"utf-8"})}};async function xe(t,e){await le(t,e);let r=d(typeof t=="string"?t:t.name);await T(r)}async function q(t,e){let{debug:r,onlyMetadata:n}=e||{},a=typeof t=="string"?t:t.name,o=typeof t!="string"?t:void 0,s={databasePort:o?.databasePort??-1,exports:o?.exports,name:a,pid:o?.pid,port:o?.port??-1,shadowDatabasePort:o?.shadowDatabasePort??-1,version:"1"};try{let i=o||await c.fromServerDump({debug:r,name:a});if(!i)return r&&console.debug(`[State] no server state found for name: ${a}`),{...s,status:"no_such_server"};s.databasePort=i.databasePort,s.exports=i.exports,s.pid=i.pid,s.port=i.port,s.shadowDatabasePort=i.shadowDatabasePort;let{exports:u,pid:m}=i;if(n)return{...s,status:"unknown"};if(!y(m,r))return r&&console.debug(`[State] server state for "${a}" has no running process with PID: ${m}`),{...s,status:"not_running"};let M=d(a);try{if(!await ee(M,{lockfilePath:l(M,".lock")}))return r&&console.debug(`[State] server state for "${a}" is not locked, indicating it is not running.`),{...s,status:"starting_up"}}catch(Z){r&&console.error(`[State] server state for "${a}" failed to check lock:`,Z)}if(!u)return{...s,status:"starting_up"};let{http:G}=u,{hc:Y}=await import("hono/client"),S=await Y(G.url).health.$get();if(!S.ok)return r&&console.debug(`[State] server state for "${a}" is not live: ${JSON.stringify(S)}`),{...s,status:"not_running"};let D=await S.json();return D.name!==t?(r&&console.debug(`[State] server state for "${a}" has mismatched health response: ${JSON.stringify(D)}`),{...s,status:"unknown"}):(r&&console.debug(`[State] server state for "${t}" is live: ${JSON.stringify(D)}`),{...s,status:"running"})}catch(i){return r&&console.error(`[State] failed to get server status for "${a}":`,i),{...s,status:"error"}}}function de(t){let{status:e}=t;return e==="running"||e==="starting_up"}async function le(t,e){let{pid:r,...n}=typeof t=="string"?await q(t,{debug:e}):t;if(!de(n))return!1;let a=await c.fromServerDump({debug:e,name:n.name});if(r==null){e&&console.debug(`[State] No PID found for server "${n.name}" to kill.`);try{await a?.close()}catch{}return!1}let o=await J(r,e);try{await a?.close()}catch{}return o}var $=class extends Error{name="ServerStateAlreadyExistsError";constructor(e){super(`A Prisma Dev server with the name "${e}" is already running.`)}},E=class extends ${#t;name="ServerAlreadyRunningError";constructor(e){super(e.name),this.#t=e}get server(){return c.fromServerDump({debug:this.#t.debug,name:this.#t.name})}};export{c as a,xe as b,q as c,de as d,le as e,$ as f,E as g};