@stacksjs/launchpad
Version:
Like Homebrew, but faster.
6 lines (5 loc) • 8.18 kB
JavaScript
// @bun
import{ab as Y}from"./chunk-b9hx8gsj.js";import{bb as I,cb as O}from"./chunk-8pxdwzvm.js";import{spawn as Z}from"child_process";import W from"fs";import $ from"path";import X from"process";function R(G){if(!W.existsSync(G))return{};try{let z=W.readFileSync(G,"utf-8"),J={};for(let K of z.split(`
`)){let T=K.trim();if(T&&!T.startsWith("#")){let[U,...V]=T.split("=");if(U&&V.length>0){let M=V.join("=");if(M.startsWith('"')&&M.endsWith('"')||M.startsWith("'")&&M.endsWith("'"))M=M.slice(1,-1);J[U]=M}}}return J}catch(z){return console.warn(`Warning: Could not parse .env file at ${G}:`,z),{}}}function q(G=X.cwd()){let z=$.join(G,".env"),J=R(z);return{driver:J.DB_CONNECTION||"sqlite",host:J.DB_HOST||"localhost",port:Number.parseInt(J.DB_PORT||"5432",10),database:J.DB_DATABASE||$.basename(G).replace(/\W/g,"_"),username:J.DB_USERNAME||"root",password:J.DB_PASSWORD||"password"}}function N(){let G=[],z=Y.services;if(!z?.frameworks?.enabled)return G;let J=z.frameworks;if(J.stacks?.enabled)G.push({name:"Stacks.js",detectionFile:"buddy",databaseConfig:{envFile:".env",migrationCommand:["buddy","migrate"],seedCommand:["buddy","db:seed"],configClearCommand:["buddy","config:clear"]}});if(J.laravel?.enabled)G.push({name:"Laravel",detectionFile:"artisan",databaseConfig:{envFile:".env",migrationCommand:["php","artisan","migrate:fresh"],seedCommand:["php","artisan","db:seed"],configClearCommand:["php","artisan","config:clear"]}});return G}function _(){let G=N();for(let z of G)if(W.existsSync(z.detectionFile)){if(z.name==="Laravel"&&W.existsSync(".env")){let J=q();return{...z,databaseConfig:{...z.databaseConfig,actualConfig:J}}}return z}return null}async function L(G){try{console.warn("\uD83D\uDE80 Setting up PHP development environment...");let z=_();if(!z){console.warn("\u26A0\uFE0F No supported PHP framework detected");let V=N();return console.warn(`\uD83D\uDCA1 Supported frameworks: ${V.map((M)=>M.name).join(", ")}`),!1}if(console.log(`\u2705 Detected ${z.name} project`),!await S()){console.warn("\uD83D\uDCE6 Installing PHP...");let{install:V}=await import("./chunk-83b6axd0.js");await V(["php.net"],`${X.env.HOME}/.local`)}let K=await y();if(console.warn(`\uD83D\uDCCA Available PHP database extensions: ${K.available.join(", ")}`),K.missing.length>0)console.warn(`\u26A0\uFE0F Missing PHP extensions: ${K.missing.join(", ")}`);let T=G?.preferredDatabase||"sqlite";if(X.env.LAUNCHPAD_FORCE_SQLITE==="true"||T==="sqlite")return console.warn("\uD83D\uDDC3\uFE0F SQLite selected for database"),await B(z);if(K.available.includes("pdo_pgsql")&&K.available.includes("pgsql"))return console.warn("\uD83D\uDC18 Setting up PostgreSQL development environment..."),await j(z);else if(T==="postgres")return console.warn("\u26A0\uFE0F PostgreSQL preferred but extensions not available"),console.warn("\uD83D\uDCA1 PHP PostgreSQL extensions (pdo_pgsql, pgsql) are core extensions that require PHP to be compiled with PostgreSQL support"),console.warn("\uD83D\uDDC3\uFE0F Falling back to SQLite for development..."),await B(z);else return console.warn("\uD83D\uDDC3\uFE0F Setting up SQLite environment..."),await B(z)}catch(z){return console.error(`\u274C Failed to set up development environment: ${z instanceof Error?z.message:String(z)}`),!1}}async function S(){try{let{findBinaryInPath:G}=await import("./chunk-wkk6vc0r.js");return G("php")!==null}catch{return!1}}async function y(){try{let G=Z("php",["-m"],{stdio:["pipe","pipe","pipe"]}),z="";if(G.stdout.on("data",(M)=>{z+=M.toString()}),!await new Promise((M)=>{G.on("close",(A)=>M(A===0))}))return{available:["pdo","pdo_sqlite","sqlite3"],missing:[]};let K=z.toLowerCase().split(`
`).map((M)=>M.trim()),T=["pdo","pdo_sqlite","pdo_mysql","pdo_pgsql","mysqli","pgsql","sqlite3"],U=T.filter((M)=>K.includes(M)),V=T.filter((M)=>!K.includes(M));return{available:U,missing:V}}catch(G){return console.warn(`\u26A0\uFE0F Could not check PHP extensions: ${G instanceof Error?G.message:String(G)}`),{available:["pdo","pdo_sqlite","sqlite3"],missing:[]}}}async function j(G){try{console.warn("\uD83D\uDD27 Starting PostgreSQL service...");let{startService:z}=await import("./chunk-2q79gpta.js");if(!await z("postgres"))return console.error("\u274C Failed to start PostgreSQL"),!1;let K=G.databaseConfig?.actualConfig,T=E(),U={DB_CONNECTION:K?.driver==="sqlite"?"sqlite":"pgsql",DB_HOST:K?.host||"127.0.0.1",DB_PORT:String(K?.port||5432),DB_DATABASE:K?.database||T,DB_USERNAME:K?.username||Y.services?.database?.username||"root",DB_PASSWORD:K?.password||Y.services?.database?.password||"password"};if(G.databaseConfig?.envFile)await H(G.databaseConfig.envFile,U);if(console.log("\u2705 PostgreSQL environment configured"),G.databaseConfig?.migrationCommand)console.warn(`\uD83D\uDCA1 You can now run: ${G.databaseConfig.migrationCommand.join(" ")}`);return!0}catch(z){return console.error(`\u274C Failed to set up PostgreSQL environment: ${z instanceof Error?z.message:String(z)}`),!1}}async function B(G){try{console.warn("\uD83D\uDD27 Configuring SQLite database...");let z="database",J=$.join(z,"database.sqlite");if(await W.promises.mkdir(z,{recursive:!0}),!W.existsSync(J))await W.promises.writeFile(J,"","utf8"),console.log(`\u2705 Created SQLite database file: ${J}`);if(G.databaseConfig?.envFile)await H(G.databaseConfig.envFile,{DB_CONNECTION:"sqlite",DB_DATABASE:J});if(G.databaseConfig?.configClearCommand)try{await new Promise((K)=>{Z(G.databaseConfig.configClearCommand[0],G.databaseConfig.configClearCommand.slice(1),{stdio:"pipe"}).on("close",()=>K())}),console.log(`\u2705 Cleared ${G.name} configuration cache`)}catch{}if(console.log("\u2705 SQLite environment configured"),G.databaseConfig?.migrationCommand)console.warn(`\uD83D\uDCA1 You can now run: ${G.databaseConfig.migrationCommand.join(" ")}`);return!0}catch(z){return console.error(`\u274C Failed to set up SQLite environment: ${z instanceof Error?z.message:String(z)}`),!1}}function E(){return $.basename(X.cwd()).replace(/-api$|_api$|-app$|_app$/i,"").replace(/\W/g,"_")}async function H(G,z){try{if(!W.existsSync(G)){console.warn(`\u26A0\uFE0F No ${G} file found`);return}let J=await W.promises.readFile(G,"utf8");for(let[K,T]of Object.entries(z))if(J.includes(`${K}=`))J=J.replace(new RegExp(`^${K}=.*`,"gm"),`${K}=${T}`);else J+=`
${K}=${T}`;if(z.DB_CONNECTION==="sqlite")J=J.replace(/^(DB_HOST=.*)/gm,"# $1"),J=J.replace(/^(DB_PORT=.*)/gm,"# $1"),J=J.replace(/^(DB_USERNAME=.*)/gm,"# $1"),J=J.replace(/^(DB_PASSWORD=.*)/gm,"# $1");await W.promises.writeFile(G,J,"utf8"),console.log(`\u2705 Updated ${G} file`)}catch(J){console.warn(`\u26A0\uFE0F Could not update ${G} file: ${J instanceof Error?J.message:String(J)}`)}}async function x(G){try{let z=G||_();if(!z?.databaseConfig?.migrationCommand)return console.warn("\u26A0\uFE0F No migration command configured for current project"),!1;console.warn(`\uD83D\uDDC4\uFE0F Running database migrations for ${z.name}...`);let J=z.databaseConfig.migrationCommand,K=Z(J[0],J.slice(1),{stdio:["pipe","inherit","inherit"]}),T=await new Promise((U)=>{K.on("close",(V)=>U(V||0))});if(T!==0)return console.error(`\u274C Migration failed with exit code: ${T}`),!1;if(z.databaseConfig.seedCommand){console.warn("\uD83C\uDF31 Running database seeding...");let U=z.databaseConfig.seedCommand,V=Z(U[0],U.slice(1),{stdio:["pipe","inherit","inherit"]}),M=await new Promise((A)=>{V.on("close",(Q)=>A(Q||0))});if(M!==0)console.warn(`\u26A0\uFE0F Seeding failed with exit code: ${M}`)}return console.log("\u2705 Database setup completed successfully"),!0}catch(z){return console.error(`\u274C Failed to run database setup: ${z instanceof Error?z.message:String(z)}`),!1}}async function P(G){let z=_();if(!z||z.name!=="Laravel")return console.warn("\u26A0\uFE0F This is not a Laravel project"),!1;if(console.warn("\uD83D\uDE80 Setting up Laravel development environment..."),!await L({preferredDatabase:G?.preferredDatabase,framework:"Laravel"}))return!1;if(G?.runMigrations)return await x(z);return!0}export{L as setupPHPDevelopmentEnvironment,P as setupLaravelEnvironment,x as runDatabaseSetup,R as parseEnvFile,N as getSupportedFrameworks,q as getLaravelDatabaseConfig,_ as detectProjectFramework};