driftsql 1.0.32 → 2.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,16 +1,84 @@
1
- // @bun
2
- import consola6 from"consola";function hasTransactionSupport(driver){return"transaction"in driver&&typeof driver.transaction==="function"}function hasPreparedStatementSupport(driver){return"prepare"in driver&&typeof driver.prepare==="function"}class DatabaseError extends Error{driverType;originalError;constructor(message,driverType,originalError){super(message);this.driverType=driverType;this.originalError=originalError;this.name="DatabaseError"}}class QueryError extends DatabaseError{constructor(driverType,sql,originalError){super(`Query failed: ${sql}`,driverType,originalError);this.name="QueryError"}}class ConnectionError extends DatabaseError{constructor(driverType,originalError){super(`Failed to connect to ${driverType}`,driverType,originalError);this.name="ConnectionError"}}import postgres from"postgres";import ky from"ky";class PostgresDriver{client;constructor(config){try{if(config.experimental?.http){this.client=new PostgresHTTPDriver(config.experimental.http)}else{this.client=postgres(config.connectionString||"")}}catch(error){throw new ConnectionError("postgres",error)}}async query(sql,params){try{if(this.client instanceof PostgresHTTPDriver){return await this.client.query(sql,params)}const result=await this.client.unsafe(sql,params||[]);return{rows:result,rowCount:Array.isArray(result)?result.length:0,command:undefined}}catch(error){throw new QueryError("postgres",sql,error)}}async transaction(callback){if(this.client instanceof PostgresHTTPDriver){throw new Error("Transactions not supported with HTTP driver")}const result=await this.client.begin(async(sql)=>{const transactionDriver=new PostgresDriver({connectionString:""});transactionDriver.client=sql;return await callback(transactionDriver)});return result}async findFirst(table,where){const whereEntries=Object.entries(where||{});let sql=`SELECT * FROM ${table}`;let params=[];if(whereEntries.length>0){const whereClause=whereEntries.map((_,index)=>`${whereEntries[index]?.[0]} = $${index+1}`).join(" AND ");sql+=` WHERE ${whereClause}`;params=whereEntries.map(([,value])=>value)}sql+=" LIMIT 1";const result=await this.query(sql,params);return result.rows.length>0?result:null}async findMany(table,options){if(this.client instanceof PostgresHTTPDriver){return await this.client.findMany(table,options)}const{where,limit,offset}=options||{};const whereEntries=Object.entries(where||{});let sql=`SELECT * FROM ${table}`;let params=[];if(whereEntries.length>0){const whereClause=whereEntries.map((_,index)=>`${whereEntries[index]?.[0]} = $${index+1}`).join(" AND ");sql+=` WHERE ${whereClause}`;params=whereEntries.map(([,value])=>value)}if(typeof limit==="number"&&limit>0){sql+=` LIMIT $${params.length+1}`;params.push(limit)}if(typeof offset==="number"&&offset>0){sql+=` OFFSET $${params.length+1}`;params.push(offset)}return this.query(sql,params)}async insert(table,data){const tableName=String(table);const keys=Object.keys(data);const values=Object.values(data);if(keys.length===0){throw new Error("No data provided for insert")}const placeholders=keys.map((_,index)=>`$${index+1}`).join(", ");const sql=`INSERT INTO ${tableName} (${keys.join(", ")}) VALUES (${placeholders}) RETURNING *`;const result=await this.query(sql,values);if(!result.rows[0]){throw new Error("Insert failed: No data returned")}return result}async update(table,data,where){const tableName=String(table);const setEntries=Object.entries(data);const whereEntries=Object.entries(where);if(setEntries.length===0){throw new Error("No data provided for update")}if(whereEntries.length===0){throw new Error("No conditions provided for update")}const setClause=setEntries.map((_,index)=>`${setEntries[index]?.[0]} = $${index+1}`).join(", ");const whereClause=whereEntries.map((_,index)=>`${whereEntries[index]?.[0]} = $${setEntries.length+index+1}`).join(" AND ");const sql=`UPDATE ${tableName} SET ${setClause} WHERE ${whereClause} RETURNING *`;const params=[...setEntries.map(([,value])=>value),...whereEntries.map(([,value])=>value)];const result=await this.query(sql,params);return result.rows.length>0?result:result}async delete(table,where){const tableName=String(table);const whereEntries=Object.entries(where);if(whereEntries.length===0){throw new Error("No conditions provided for delete")}const whereClause=whereEntries.map((_,index)=>`${whereEntries[index]?.[0]} = $${index+1}`).join(" AND ");const sql=`DELETE FROM ${tableName} WHERE ${whereClause}`;const params=whereEntries.map(([,value])=>value);const result=await this.query(sql,params);return result.rowCount}async close(){try{if(this.client instanceof PostgresHTTPDriver){return await this.client.close()}await this.client.end()}catch(error){console.error("Error closing Postgres client:",error)}}}class PostgresHTTPDriver{httpClient;constructor(config){this.httpClient=ky.create({prefixUrl:config.url,headers:{Authorization:`Bearer ${config.apiKey||""}`}})}async query(sql,params){try{const response=await this.httpClient.post("query",{json:{query:sql,args:params}}).json();return{rows:response.rows,rowCount:response.rowCount,command:undefined}}catch(error){throw new QueryError("postgres-http",sql,error)}}async findFirst(table,where){const whereEntries=Object.entries(where||{});let sql=`SELECT * FROM ${table}`;let params=[];if(whereEntries.length>0){const whereClause=whereEntries.map((_,index)=>`${whereEntries[index]?.[0]} = $${index+1}`).join(" AND ");sql+=` WHERE ${whereClause}`;params=whereEntries.map(([,value])=>value)}sql+=" LIMIT 1";const result=await this.query(sql,params);return result.rows.length>0?result:null}async findMany(table,options){const{where,limit,offset}=options||{};const whereEntries=Object.entries(where||{});let sql=`SELECT * FROM ${table}`;let params=[];if(whereEntries.length>0){const whereClause=whereEntries.map((_,index)=>`${whereEntries[index]?.[0]} = $${index+1}`).join(" AND ");sql+=` WHERE ${whereClause}`;params=whereEntries.map(([,value])=>value)}if(typeof limit==="number"&&limit>0){sql+=` LIMIT $${params.length+1}`;params.push(limit)}if(typeof offset==="number"&&offset>0){sql+=` OFFSET $${params.length+1}`;params.push(offset)}return this.query(sql,params)}async insert(table,data){const tableName=String(table);const keys=Object.keys(data);const values=Object.values(data);if(keys.length===0){throw new Error("No data provided for insert")}const placeholders=keys.map((_,index)=>`$${index+1}`).join(", ");const sql=`INSERT INTO ${tableName} (${keys.join(", ")}) VALUES (${placeholders}) RETURNING *`;const result=await this.query(sql,values);if(!result.rows[0]){throw new Error("Insert failed: No data returned")}return result}async update(table,data,where){const tableName=String(table);const setEntries=Object.entries(data);const whereEntries=Object.entries(where);if(setEntries.length===0){throw new Error("No data provided for update")}if(whereEntries.length===0){throw new Error("No conditions provided for update")}const setClause=setEntries.map((_,index)=>`${setEntries[index]?.[0]} = $${index+1}`).join(", ");const whereClause=whereEntries.map((_,index)=>`${whereEntries[index]?.[0]} = $${setEntries.length+index+1}`).join(" AND ");const sql=`UPDATE ${tableName} SET ${setClause} WHERE ${whereClause} RETURNING *`;const params=[...setEntries.map(([,value])=>value),...whereEntries.map(([,value])=>value)];const result=await this.query(sql,params);return result.rows.length>0?result:result}async delete(table,where){const tableName=String(table);const whereEntries=Object.entries(where);if(whereEntries.length===0){throw new Error("No conditions provided for delete")}const whereClause=whereEntries.map((_,index)=>`${whereEntries[index]?.[0]} = $${index+1}`).join(" AND ");const sql=`DELETE FROM ${tableName} WHERE ${whereClause}`;const params=whereEntries.map(([,value])=>value);const result=await this.query(sql,params);return result.rowCount}async close(){return Promise.resolve()}}import{createClient}from"@libsql/client";import{createClient as tursoServerLessClient}from"@tursodatabase/serverless/compat";class LibSQLDriver{client;constructor(config){try{this.client=config.useTursoServerlessDriver?tursoServerLessClient({url:config.url,...config.authToken?{authToken:config.authToken}:{}}):createClient({url:config.url,...config.authToken?{authToken:config.authToken}:{}})}catch(error){throw new ConnectionError("libsql",error)}}async query(sql,params){try{const result=await this.client.execute(sql,params);return this.convertLibsqlResult(result)}catch(error){throw new QueryError("libsql",sql,error)}}async transaction(callback){const transactionDriver=new LibSQLDriver({url:"",authToken:""});transactionDriver.client=this.client;return await callback(transactionDriver)}async findFirst(table,where){const whereEntries=Object.entries(where||{});let sql=`SELECT * FROM ${table}`;let params=[];if(whereEntries.length>0){const whereClause=whereEntries.map((_,index)=>`${whereEntries[index]?.[0]} = ?`).join(" AND ");sql+=` WHERE ${whereClause}`;params=whereEntries.map(([,value])=>value)}sql+=" LIMIT 1";const result=await this.query(sql,params);return result.rows.length>0?result:null}async findMany(table,options){const{where,limit,offset}=options||{};const whereEntries=Object.entries(where||{});let sql=`SELECT * FROM ${table}`;let params=[];if(whereEntries.length>0){const whereClause=whereEntries.map((_,index)=>`${whereEntries[index]?.[0]} = ?`).join(" AND ");sql+=` WHERE ${whereClause}`;params=whereEntries.map(([,value])=>value)}if(typeof limit==="number"&&limit>0){sql+=` LIMIT ?`;params.push(limit)}if(typeof offset==="number"&&offset>0){sql+=` OFFSET ?`;params.push(offset)}return this.query(sql,params)}async insert(table,data){const tableName=String(table);const keys=Object.keys(data);const values=Object.values(data);if(keys.length===0){throw new Error("No data provided for insert")}const placeholders=keys.map(()=>"?").join(", ");const sql=`INSERT INTO ${tableName} (${keys.join(", ")}) VALUES (${placeholders})`;try{const result=await this.client.execute(sql,values);if(result.lastInsertRowid){try{const selectSql=`SELECT * FROM ${tableName} WHERE rowid = ?`;const insertedRow=await this.query(selectSql,[result.lastInsertRowid]);return{rows:insertedRow.rows,rowCount:result.rowsAffected||0,command:undefined,fields:insertedRow.fields}}catch{return{rows:[],rowCount:result.rowsAffected||0,command:undefined,fields:[]}}}return{rows:[],rowCount:result.rowsAffected||0,command:undefined,fields:[]}}catch(error){throw new QueryError("libsql",sql,error)}}async update(table,data,where){const tableName=String(table);const setEntries=Object.entries(data);const whereEntries=Object.entries(where);if(setEntries.length===0){throw new Error("No data provided for update")}if(whereEntries.length===0){throw new Error("No conditions provided for update")}const setClause=setEntries.map(([key])=>`${key} = ?`).join(", ");const whereClause=whereEntries.map(([key])=>`${key} = ?`).join(" AND ");const sql=`UPDATE ${tableName} SET ${setClause} WHERE ${whereClause}`;const params=[...setEntries.map(([,value])=>value),...whereEntries.map(([,value])=>value)];try{const result=await this.client.execute(sql,params);const selectSql=`SELECT * FROM ${tableName} WHERE ${whereClause}`;const selectParams=whereEntries.map(([,value])=>value);const updatedRows=await this.query(selectSql,selectParams);return{rows:updatedRows.rows,rowCount:result.rowsAffected||0,command:undefined,fields:updatedRows.fields}}catch(error){throw new QueryError("libsql",sql,error)}}async delete(table,where){const tableName=String(table);const whereEntries=Object.entries(where);if(whereEntries.length===0){throw new Error("No conditions provided for delete")}const whereClause=whereEntries.map(([key])=>`${key} = ?`).join(" AND ");const sql=`DELETE FROM ${tableName} WHERE ${whereClause}`;const params=whereEntries.map(([,value])=>value);try{const result=await this.client.execute(sql,params);return result.rowsAffected||0}catch(error){throw new QueryError("libsql",sql,error)}}async close(){try{this.client.close()}catch(error){console.error("Error closing LibSQL client:",error)}}convertLibsqlResult(result){const rows=result.rows.map((row)=>{const obj={};result.columns.forEach((col,index)=>{obj[col]=row[index]});return obj});return{rows,rowCount:result.rowsAffected||rows.length,command:undefined,fields:result.columns.map((col)=>({name:col,dataTypeID:0}))}}}import consola from"consola";import*as mysql from"mysql2/promise";class MySQLDriver{client;constructor(config){try{this.client=mysql.createConnection(config.connectionString)}catch(error){throw new ConnectionError("mysql",error)}}async query(sql,params){try{const[rows,fields]=await(await this.client).execute(sql,params||[]);const rowCount=Array.isArray(rows)?rows.length:0;const normalizedFields=fields.map((field)=>({name:field.name,dataTypeID:field.columnType}));return{rows,rowCount,command:undefined,fields:normalizedFields}}catch(error){throw new QueryError("mysql",sql,error)}}async transaction(callback){const connection=await this.client;try{await connection.beginTransaction();const transactionDriver=new MySQLDriver({connectionString:""});transactionDriver.client=Promise.resolve(connection);const result=await callback(transactionDriver);await connection.commit();return result}catch(error){await connection.rollback();throw error}}async findFirst(table,where){const whereEntries=Object.entries(where||{});let sql=`SELECT * FROM ${table}`;let params=[];if(whereEntries.length>0){const whereClause=whereEntries.map(([key])=>`${key} = ?`).join(" AND ");sql+=` WHERE ${whereClause}`;params=whereEntries.map(([,value])=>value)}sql+=" LIMIT 1";const result=await this.query(sql,params);return result.rows.length>0?result:null}async findMany(table,options){const{where,limit,offset}=options||{};const whereEntries=Object.entries(where||{});let sql=`SELECT * FROM ${table}`;let params=[];if(whereEntries.length>0){const whereClause=whereEntries.map(([key])=>`${key} = ?`).join(" AND ");sql+=` WHERE ${whereClause}`;params=whereEntries.map(([,value])=>value)}if(typeof limit==="number"&&limit>0){sql+=` LIMIT ?`;params.push(limit)}if(typeof offset==="number"&&offset>0){sql+=` OFFSET ?`;params.push(offset)}return this.query(sql,params)}async insert(table,data){const tableName=String(table);const keys=Object.keys(data);const values=Object.values(data);if(keys.length===0){throw new Error("No data provided for insert")}const placeholders=keys.map(()=>"?").join(", ");const sql=`INSERT INTO ${tableName} (${keys.join(", ")}) VALUES (${placeholders})`;try{const connection=await this.client;const[result]=await connection.execute(sql,values);const insertResult=result;if(insertResult.insertId){try{const selectSql=`SELECT * FROM ${tableName} WHERE id = ?`;const insertedRow=await this.query(selectSql,[insertResult.insertId]);return{rows:insertedRow.rows,rowCount:insertResult.affectedRows||0,command:undefined,fields:insertedRow.fields}}catch{return{rows:[],rowCount:insertResult.affectedRows||0,command:undefined,fields:[]}}}return{rows:[],rowCount:insertResult.affectedRows||0,command:undefined,fields:[]}}catch(error){throw new QueryError("mysql",sql,error)}}async update(table,data,where){const tableName=String(table);const setEntries=Object.entries(data);const whereEntries=Object.entries(where);if(setEntries.length===0){throw new Error("No data provided for update")}if(whereEntries.length===0){throw new Error("No conditions provided for update")}const setClause=setEntries.map(([key])=>`${key} = ?`).join(", ");const whereClause=whereEntries.map(([key])=>`${key} = ?`).join(" AND ");const sql=`UPDATE ${tableName} SET ${setClause} WHERE ${whereClause}`;const params=[...setEntries.map(([,value])=>value),...whereEntries.map(([,value])=>value)];try{const connection=await this.client;const[result]=await connection.execute(sql,params);const selectSql=`SELECT * FROM ${tableName} WHERE ${whereClause}`;const selectParams=whereEntries.map(([,value])=>value);const updatedRows=await this.query(selectSql,selectParams);const updateResult=result;return{rows:updatedRows.rows,rowCount:updateResult.affectedRows||0,command:undefined,fields:updatedRows.fields}}catch(error){throw new QueryError("mysql",sql,error)}}async delete(table,where){const tableName=String(table);const whereEntries=Object.entries(where);if(whereEntries.length===0){throw new Error("No conditions provided for delete")}const whereClause=whereEntries.map(([key])=>`${key} = ?`).join(" AND ");const sql=`DELETE FROM ${tableName} WHERE ${whereClause}`;const params=whereEntries.map(([,value])=>value);try{const connection=await this.client;const[result]=await connection.execute(sql,params);const deleteResult=result;return deleteResult.affectedRows||0}catch(error){throw new QueryError("mysql",sql,error)}}async close(){try{await(await this.client).end()}catch(error){consola.error("Error closing MySQL client:",error)}}}import{neon}from"@neondatabase/serverless";class NeonDriver{client;constructor(options){this.client=neon(options.connectionString)}async query(sql,params){try{const resp=await this.client.query(sql,params);return{rows:resp,rowCount:resp.length||0}}catch(error){throw new QueryError("neon",`Failed to query database: ${error}`)}}async findFirst(table,where){const whereEntries=Object.entries(where||{});let sql=`SELECT * FROM ${table}`;let params=[];if(whereEntries.length>0){const whereClause=whereEntries.map((_,index)=>`${whereEntries[index]?.[0]} = $${index+1}`).join(" AND ");sql+=` WHERE ${whereClause}`;params=whereEntries.map(([,value])=>value)}sql+=" LIMIT 1";const result=await this.query(sql,params);return result.rows.length>0?result:null}async findMany(table,options){const{where,limit,offset}=options||{};const whereEntries=Object.entries(where||{});let sql=`SELECT * FROM ${table}`;let params=[];if(whereEntries.length>0){const whereClause=whereEntries.map((_,index)=>`${whereEntries[index]?.[0]} = $${index+1}`).join(" AND ");sql+=` WHERE ${whereClause}`;params=whereEntries.map(([,value])=>value)}if(typeof limit==="number"&&limit>0){sql+=` LIMIT $${params.length+1}`;params.push(limit)}if(typeof offset==="number"&&offset>0){sql+=` OFFSET $${params.length+1}`;params.push(offset)}return this.query(sql,params)}async insert(table,data){const tableName=String(table);const keys=Object.keys(data);const values=Object.values(data);if(keys.length===0){throw new Error("No data provided for insert")}const placeholders=keys.map((_,index)=>`$${index+1}`).join(", ");const sql=`INSERT INTO ${tableName} (${keys.join(", ")}) VALUES (${placeholders}) RETURNING *`;const result=await this.query(sql,values);if(!result.rows[0]){throw new Error("Insert failed: No data returned")}return result}async update(table,data,where){const tableName=String(table);const setEntries=Object.entries(data);const whereEntries=Object.entries(where);if(setEntries.length===0){throw new Error("No data provided for update")}if(whereEntries.length===0){throw new Error("No conditions provided for update")}const setClause=setEntries.map((_,index)=>`${setEntries[index]?.[0]} = $${index+1}`).join(", ");const whereClause=whereEntries.map((_,index)=>`${whereEntries[index]?.[0]} = $${setEntries.length+index+1}`).join(" AND ");const sql=`UPDATE ${tableName} SET ${setClause} WHERE ${whereClause} RETURNING *`;const params=[...setEntries.map(([,value])=>value),...whereEntries.map(([,value])=>value)];const result=await this.query(sql,params);return result.rows.length>0?result:result}async delete(table,where){const tableName=String(table);const whereEntries=Object.entries(where);if(whereEntries.length===0){throw new Error("No conditions provided for delete")}const whereClause=whereEntries.map((_,index)=>`${whereEntries[index]?.[0]} = $${index+1}`).join(" AND ");const sql=`DELETE FROM ${tableName} WHERE ${whereClause}`;const params=whereEntries.map(([,value])=>value);const result=await this.query(sql,params);return result.rowCount}close(){return Promise.resolve()}}import{Database}from"@sqlitecloud/drivers";class SqliteCloudDriver{options;client;constructor(options){this.options=options;this.client=new Database(this.options.connectionString)}async query(sql,params){try{const result=await this.client.sql(sql,params);const rows=Array.isArray(result)?result.map((row)=>{const data={};for(const key in row){if(typeof row[key]!=="function"){data[key]=row[key]}}return data}):[];return{rows,rowCount:rows.length,command:undefined}}catch(error){throw new QueryError("sqlitecloud",sql,error)}}async prepare(sql){return this.client.prepare(sql)}async findFirst(table,where){const whereEntries=Object.entries(where||{});let sql=`SELECT * FROM ${table}`;let params=[];if(whereEntries.length>0){const whereClause=whereEntries.map((_,index)=>`${whereEntries[index]?.[0]} = ?`).join(" AND ");sql+=` WHERE ${whereClause}`;params=whereEntries.map(([,value])=>value)}sql+=" LIMIT 1";const result=await this.query(sql,params);return result.rows.length>0?result:null}async findMany(table,options){const{where,limit,offset}=options||{};const whereEntries=Object.entries(where||{});let sql=`SELECT * FROM ${table}`;let params=[];if(whereEntries.length>0){const whereClause=whereEntries.map((_,index)=>`${whereEntries[index]?.[0]} = ?`).join(" AND ");sql+=` WHERE ${whereClause}`;params=whereEntries.map(([,value])=>value)}if(typeof limit==="number"&&limit>0){sql+=` LIMIT ?`;params.push(limit)}if(typeof offset==="number"&&offset>0){sql+=` OFFSET ?`;params.push(offset)}return this.query(sql,params)}async insert(table,data){const tableName=String(table);const keys=Object.keys(data);const values=Object.values(data);if(keys.length===0){throw new Error("No data provided for insert")}const placeholders=keys.map(()=>"?").join(", ");const sql=`INSERT INTO ${tableName} (${keys.join(", ")}) VALUES (${placeholders})`;try{const result=await this.query(sql,values);if(result.rows.length===0){const returningSql=`INSERT INTO ${tableName} (${keys.join(", ")}) VALUES (${placeholders}) RETURNING *`;return await this.query(returningSql,values)}return result}catch(error){throw new QueryError("sqlitecloud",sql,error)}}async update(table,data,where){const tableName=String(table);const setEntries=Object.entries(data);const whereEntries=Object.entries(where);if(setEntries.length===0){throw new Error("No data provided for update")}if(whereEntries.length===0){throw new Error("No conditions provided for update")}const setClause=setEntries.map(([key])=>`${key} = ?`).join(", ");const whereClause=whereEntries.map(([key])=>`${key} = ?`).join(" AND ");const sql=`UPDATE ${tableName} SET ${setClause} WHERE ${whereClause} RETURNING *`;const params=[...setEntries.map(([,value])=>value),...whereEntries.map(([,value])=>value)];try{const result=await this.query(sql,params);return result}catch(error){throw new QueryError("sqlitecloud",sql,error)}}async delete(table,where){const tableName=String(table);const whereEntries=Object.entries(where);if(whereEntries.length===0){throw new Error("No conditions provided for delete")}const whereClause=whereEntries.map(([key])=>`${key} = ?`).join(" AND ");const sql=`DELETE FROM ${tableName} WHERE ${whereClause}`;const params=whereEntries.map(([,value])=>value);try{const result=await this.query(sql,params);return result.rowCount}catch(error){throw new QueryError("sqlitecloud",sql,error)}}async close(){this.client.close()}}import consola2 from"consola";import chalk from"chalk";import fs from"fs/promises";var withTimeout=(promise,timeoutMs=30000)=>{return Promise.race([promise,new Promise((_,reject)=>setTimeout(()=>reject(new Error(`Query timeout after ${timeoutMs}ms`)),timeoutMs))])};var retryQuery=async(queryFn,maxRetries=3,baseDelay=1000)=>{for(let attempt=1;attempt<=maxRetries;attempt++){try{return await queryFn()}catch(error){if(attempt===maxRetries){throw error}const delay=baseDelay*Math.pow(2,attempt-1);consola2.warn(`Query attempt ${attempt} failed, retrying in ${delay}ms...`,error);await new Promise((resolve)=>setTimeout(resolve,delay))}}throw new Error("Max retries exceeded")};var mapDatabaseTypeToTypeScript=(dataType,isNullable=false,driverType="postgres")=>{const nullable=isNullable?" | null":"";const lowerType=dataType.toLowerCase();switch(lowerType){case"uuid":{return`string${nullable}`}case"character varying":case"varchar":case"text":case"char":case"character":case"longtext":case"mediumtext":case"tinytext":{return`string${nullable}`}case"integer":case"int":case"int4":case"smallint":case"int2":case"bigint":case"int8":case"serial":case"bigserial":case"numeric":case"decimal":case"real":case"float4":case"double precision":case"float8":case"tinyint":case"mediumint":case"float":case"double":{return`number${nullable}`}case"boolean":case"bool":case"bit":{return`boolean${nullable}`}case"timestamp":case"timestamp with time zone":case"timestamp without time zone":case"timestamptz":case"date":case"time":case"time with time zone":case"time without time zone":case"timetz":case"interval":case"datetime":case"year":{return`Date${nullable}`}case"json":case"jsonb":{return`any${nullable}`}case"array":{return`any[]${nullable}`}case"bytea":case"binary":case"varbinary":case"blob":case"longblob":case"mediumblob":case"tinyblob":{return`Buffer${nullable}`}case"enum":case"set":{return`string${nullable}`}default:{consola2.warn(`Unknown ${driverType} type: ${dataType}, defaulting to 'any'`);return`any${nullable}`}}};var getDriverType=(driver)=>{if(driver instanceof PostgresDriver)return"postgres";if(driver instanceof LibSQLDriver)return"libsql";if(driver instanceof MySQLDriver)return"mysql";if(driver instanceof NeonDriver)return"neon";if(driver instanceof SqliteCloudDriver)return"sqlitecloud";return`${driver.constructor.name||"unknown driver"}`};var inspectDB=async(options)=>{consola2.warn("inspectDB is experimental and may make mistakes when inspecting your database. However it will not destroy your database.");const{driver,outputFile="db-types.ts"}=options;const driverType=getDriverType(driver);consola2.start(`Inspecting database using ${driverType} driver`);const client=new SQLClient({driver});let generatedTypes="";try{let tablesQuery;let tableSchemaFilter;if(driverType==="mysql"){const dbResult=await withTimeout(retryQuery(()=>client.query("SELECT DATABASE() as `database`",[])),1e4);const currentDatabase=dbResult.rows[0]?.database;if(!currentDatabase){throw new Error("Could not determine current MySQL database name")}consola2.success(`Using MySQL database: ${currentDatabase}`);tablesQuery=`SELECT TABLE_NAME as table_name
1
+ import{a as e,i as t,n,o as r,r as i,t as a}from"./postgres-9C7eE0wB.js";import{n as o,t as s}from"./type-generator-Ba8bgnMm.js";import{Command as c}from"commander";import l from"consola";import u from"node:fs/promises";import d from"node:path";import f from"chalk";import p from"postgres";var m=class{client;constructor(e){this.client=e}async ensureMigrationsTable(){await this.client.query(`
2
+ CREATE TABLE IF NOT EXISTS _migrations (
3
+ version VARCHAR(255) PRIMARY KEY,
4
+ name VARCHAR(255) NOT NULL,
5
+ applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
6
+ );
7
+ `)}async getAppliedMigrations(){return await this.ensureMigrationsTable(),(await this.client.query(`SELECT version FROM _migrations ORDER BY version`)).rows.map(e=>e.version)}async up(e){if((await this.getAppliedMigrations()).includes(e.version)){l.info(`Migration ${e.version} (${e.name}) already applied`);return}l.start(`Running migration ${e.version} (${e.name})`);for(let t of e.up)await this.client.query(t);await this.client.query(`INSERT INTO _migrations (version, name) VALUES ($1, $2)`,[e.version,e.name]),l.success(`Migration ${e.version} (${e.name}) applied successfully`)}async down(e){if(!(await this.getAppliedMigrations()).includes(e.version)){l.info(`Migration ${e.version} (${e.name}) not applied`);return}l.start(`Rolling back migration ${e.version} (${e.name})`);for(let t of e.down)await this.client.query(t);await this.client.query(`DELETE FROM _migrations WHERE version = $1`,[e.version]),l.success(`Migration ${e.version} (${e.name}) rolled back successfully`)}async upAll(e){let t=await this.getAppliedMigrations(),n=e.filter(e=>!t.includes(e.version));if(n.length===0){l.info(`No pending migrations`);return}l.info(`Found ${n.length} pending migrations`);for(let e of n)await this.up(e)}async downAll(e){let t=await this.getAppliedMigrations(),n=e.filter(e=>t.includes(e.version)).reverse();if(n.length===0){l.info(`No migrations to rollback`);return}l.info(`Rolling back ${n.length} migrations`);for(let e of n)await this.down(e)}async reset(e){await this.downAll(e),await this.upAll(e)}},h=class{snapshotPath;constructor(e=`./.driftsql/snapshot.json`){this.snapshotPath=e}async save(e){let t={version:`1`,timestamp:Date.now(),tables:e},n=d.dirname(this.snapshotPath);await u.mkdir(n,{recursive:!0}),await u.writeFile(this.snapshotPath,JSON.stringify(t,null,2),`utf8`)}async load(){try{let e=await u.readFile(this.snapshotPath,`utf8`);return JSON.parse(e)}catch{return null}}async exists(){try{return await u.access(this.snapshotPath),!0}catch{return!1}}},g=e({MySQLGenerator:()=>_}),_,v=t((()=>{_=class{generateCreateTable(e){let t=[];t.push(`CREATE TABLE \`${e.name}\` (`);let n=[];for(let t of e.columns)n.push(` `+this.generateColumnDefinition(t));if(e.primaryKey&&e.primaryKey.length>0){let t=e.primaryKey.map(e=>`\`${e}\``).join(`, `);n.push(` PRIMARY KEY (${t})`)}if(e.checks&&e.checks.length>0)for(let t of e.checks)n.push(` CONSTRAINT \`${t.name}\` CHECK (${t.expression})`);t.push(n.join(`,
8
+ `)),t.push(`) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;`);let r=[t.join(`
9
+ `)];if(e.indexes&&e.indexes.length>0)for(let t of e.indexes)r.push(this.generateIndex(e.name,t));return r.join(`
10
+
11
+ `)}generateDropTable(e){return`DROP TABLE IF EXISTS \`${e}\`;`}generateColumnDefinition(e){let t=[`\`${e.name}\``];if(t.push(this.getColumnType(e)),e.notNull&&!e.primaryKey&&e.type!==`serial`&&e.type!==`bigserial`&&t.push(`NOT NULL`),e.unique&&t.push(`UNIQUE`),(e.type===`serial`||e.type===`bigserial`)&&t.push(`AUTO_INCREMENT`),e.default!==void 0&&t.push(`DEFAULT ${this.formatDefault(e.default)}`),e.references){let n=e.references;t.push(`REFERENCES \`${n.table}\`(\`${n.column}\`)`),n.onDelete&&t.push(`ON DELETE ${n.onDelete}`),n.onUpdate&&t.push(`ON UPDATE ${n.onUpdate}`)}return e.check&&t.push(`CHECK (${e.check})`),t.join(` `)}getColumnType(e){let t=e.type;if(t===`serial`)return`INT`;if(t===`bigserial`)return`BIGINT`;if(t===`timestamptz`)return`TIMESTAMP`;if(t===`jsonb`)return`JSON`;if(t===`bytea`)return`BLOB`;if(t===`double precision`)return`DOUBLE`;let n=t.toUpperCase();return e.length?n+=`(${e.length})`:e.precision&&(e.scale===void 0?n+=`(${e.precision})`:n+=`(${e.precision}, ${e.scale})`),n}formatDefault(e){return typeof e==`string`?e.toUpperCase()===`NOW()`||e.toUpperCase()===`CURRENT_TIMESTAMP`?`CURRENT_TIMESTAMP`:`'${e}'`:typeof e==`boolean`?e?`1`:`0`:String(e)}generateIndex(e,t){let n=t.unique?`UNIQUE `:``,r=t.type&&t.type!==`btree`?` USING ${t.type.toUpperCase()}`:``,i=t.columns.map(e=>`\`${e}\``).join(`, `);return`CREATE ${n}INDEX \`${t.name}\` ON \`${e}\`${r} (${i});`}}})),y=e({SQLiteGenerator:()=>b}),b,x=t((()=>{b=class{generateCreateTable(e){let t=[];t.push(`CREATE TABLE "${e.name}" (`);let n=[];for(let t of e.columns)n.push(` `+this.generateColumnDefinition(t));if(e.primaryKey&&e.primaryKey.length>0){let t=e.primaryKey.map(e=>`"${e}"`).join(`, `);n.push(` PRIMARY KEY (${t})`)}if(e.checks&&e.checks.length>0)for(let t of e.checks)n.push(` CONSTRAINT "${t.name}" CHECK (${t.expression})`);t.push(n.join(`,
12
+ `)),t.push(`);`);let r=[t.join(`
13
+ `)];if(e.indexes&&e.indexes.length>0)for(let t of e.indexes)r.push(this.generateIndex(e.name,t));return r.join(`
14
+
15
+ `)}generateDropTable(e){return`DROP TABLE IF EXISTS "${e}";`}generateColumnDefinition(e){let t=[`"${e.name}"`];if(t.push(this.getColumnType(e)),e.primaryKey&&(t.push(`PRIMARY KEY`),(e.type===`serial`||e.type===`bigserial`)&&t.push(`AUTOINCREMENT`)),e.notNull&&!e.primaryKey&&t.push(`NOT NULL`),e.unique&&t.push(`UNIQUE`),e.default!==void 0&&t.push(`DEFAULT ${this.formatDefault(e.default)}`),e.references){let n=e.references;t.push(`REFERENCES "${n.table}"("${n.column}")`),n.onDelete&&t.push(`ON DELETE ${n.onDelete}`),n.onUpdate&&t.push(`ON UPDATE ${n.onUpdate}`)}return e.check&&t.push(`CHECK (${e.check})`),t.join(` `)}getColumnType(e){let t=e.type;return t===`serial`||t===`bigserial`||t===`bigint`||t===`smallint`?`INTEGER`:t===`varchar`||t===`char`||t===`timestamptz`||t===`timestamp`||t===`date`||t===`time`||t===`uuid`||t===`json`||t===`jsonb`?`TEXT`:t===`bytea`?`BLOB`:t===`decimal`||t===`numeric`||t===`real`||t===`double precision`?`REAL`:t===`boolean`?`INTEGER`:t.toUpperCase()}formatDefault(e){return typeof e==`string`?e.toUpperCase()===`NOW()`||e.toUpperCase()===`CURRENT_TIMESTAMP`?`CURRENT_TIMESTAMP`:`'${e}'`:typeof e==`boolean`?e?`1`:`0`:String(e)}generateIndex(e,t){let n=t.unique?`UNIQUE `:``,r=t.columns.map(e=>`"${e}"`).join(`, `);return`CREATE ${n}INDEX "${t.name}" ON "${e}" (${r});`}}}));n(),v(),x();var S=class{upStatements=[];downStatements=[];dialect;constructor(e=`postgres`){this.dialect=e}createTable(e){let t=e.getDefinition(),n=this.getGenerator();return this.upStatements.push(n.generateCreateTable(t)),this.downStatements.unshift(n.generateDropTable(t.name)),this}dropTable(e){let t=this.getGenerator();return this.upStatements.push(t.generateDropTable(e)),this}addColumn(e,t){return this.upStatements.push(`ALTER TABLE "${e}" ADD COLUMN ${t};`),this}dropColumn(e,t){return this.upStatements.push(`ALTER TABLE "${e}" DROP COLUMN "${t}";`),this}renameTable(e,t){return this.dialect===`postgres`?this.upStatements.push(`ALTER TABLE "${e}" RENAME TO "${t}";`):this.dialect===`mysql`?this.upStatements.push(`RENAME TABLE \`${e}\` TO \`${t}\`;`):this.upStatements.push(`ALTER TABLE "${e}" RENAME TO "${t}";`),this}raw(e,t){return this.upStatements.push(e),t&&this.downStatements.unshift(t),this}build(e,t){return{version:e,name:t,up:this.upStatements,down:this.downStatements}}getGenerator(){switch(this.dialect){case`postgres`:return new a;case`mysql`:return new _;case`sqlite`:return new b;default:return new a}}};function ee(e=`postgres`){return new S(e)}var C=class{dialect;constructor(e=`postgres`){this.dialect=e}detectChanges(e,t){let n=[],r=new Map(e.map(e=>[e.name,e])),i=new Map(t.map(e=>[e.name,e]));for(let[e,t]of i){let i=r.get(e);i?(n.push(...this.detectColumnChanges(i,t)),n.push(...this.detectIndexChanges(i,t))):n.push({type:`create_table`,table:e,details:t})}for(let[e]of r)i.has(e)||n.push({type:`drop_table`,table:e});return n}detectColumnChanges(e,t){let n=[],r=new Map(e.columns.map(e=>[e.name,e])),i=new Map(t.columns.map(e=>[e.name,e]));for(let[e,a]of i){let i=r.get(e);i?this.hasColumnChanged(i,a)&&n.push({type:`modify_column`,table:t.name,details:{old:i,new:a}}):n.push({type:`add_column`,table:t.name,details:a})}for(let[e]of r)i.has(e)||n.push({type:`drop_column`,table:t.name,details:{name:e}});return n}detectIndexChanges(e,t){let n=[],r=new Map((e.indexes||[]).map(e=>[e.name,e])),i=new Map((t.indexes||[]).map(e=>[e.name,e]));for(let[e,a]of i)r.has(e)||n.push({type:`create_index`,table:t.name,details:a});for(let[e]of r)i.has(e)||n.push({type:`drop_index`,table:t.name,details:{name:e}});return n}hasColumnChanged(e,t){return e.type!==t.type||e.length!==t.length||e.precision!==t.precision||e.scale!==t.scale||e.notNull!==t.notNull||e.unique!==t.unique||e.default!==t.default||JSON.stringify(e.references)!==JSON.stringify(t.references)}generateMigration(e,t,n){let r=new S(this.dialect);for(let t of e)switch(t.type){case`create_table`:{let e=t.details,n=this.getGenerator(),i=n.generateCreateTable(e);r.raw(i,n.generateDropTable(e.name));break}case`drop_table`:{let e=this.getGenerator();r.raw(e.generateDropTable(t.table));break}case`add_column`:{let e=t.details,n=this.generateColumnSQL(e);r.raw(`ALTER TABLE "${t.table}" ADD COLUMN ${n};`,`ALTER TABLE "${t.table}" DROP COLUMN "${e.name}";`);break}case`drop_column`:{let e=t.details.name;r.raw(`ALTER TABLE "${t.table}" DROP COLUMN "${e}";`);break}case`create_index`:{let e=t.details,n=this.generateIndexSQL(t.table,e);r.raw(n,`DROP INDEX "${e.name}";`);break}case`drop_index`:{let e=t.details.name;r.raw(`DROP INDEX "${e}";`);break}}return r}generateColumnSQL(e){let t=[`"${e.name}"`];return t.push(e.type.toUpperCase()),e.length&&(t[1]+=`(${e.length})`),e.notNull&&t.push(`NOT NULL`),e.unique&&t.push(`UNIQUE`),e.default!==void 0&&t.push(`DEFAULT ${this.formatDefault(e.default)}`),t.join(` `)}generateIndexSQL(e,t){let n=t.unique?`UNIQUE `:``,r=t.columns.map(e=>`"${e}"`).join(`, `);return`CREATE ${n}INDEX "${t.name}" ON "${e}" (${r});`}formatDefault(e){return typeof e==`string`?e.toUpperCase()===`NOW()`||e.toUpperCase()===`CURRENT_TIMESTAMP`?e.toUpperCase():`'${e}'`:typeof e==`boolean`?e?`TRUE`:`FALSE`:String(e)}getGenerator(){let{PostgresGenerator:e}=(n(),r(i)),{MySQLGenerator:t}=(v(),r(g)),{SQLiteGenerator:a}=(x(),r(y));switch(this.dialect){case`postgres`:return new e;case`mysql`:return new t;case`sqlite`:return new a;default:return new e}}};function w(e,t,n=`postgres`){return new C(n).detectChanges(e,t)}function T(e,t,n,r=`postgres`){return new C(r).generateMigration(e,t,n)}const E=new c;E.name(`driftsql`).description(`DriftSQL CLI - Database migrations and schema management`).version(`0.0.1`),E.command(`migrate:up`).description(`Run all pending migrations`).option(`-d, --dir <directory>`,`Migrations directory`,`./migrations`).option(`-c, --config <path>`,`Config file path`,`./driftsql.config.ts`).action(async e=>{try{let{client:t,migrations:n}=await O(e.dir,e.config);await new m(t).upAll(n),await t.close(),l.success(`All migrations applied successfully`)}catch(e){l.error(`Migration failed:`,e),process.exit(1)}}),E.command(`migrate:down`).description(`Rollback the last migration`).option(`-d, --dir <directory>`,`Migrations directory`,`./migrations`).option(`-c, --config <path>`,`Config file path`,`./driftsql.config.ts`).action(async e=>{try{let{client:t,migrations:n}=await O(e.dir,e.config),r=new m(t),i=await r.getAppliedMigrations(),a=n.find(e=>e.version===i[i.length-1]);a?await r.down(a):l.info(`No migrations to rollback`),await t.close()}catch(e){l.error(`Rollback failed:`,e),process.exit(1)}}),E.command(`migrate:reset`).description(`Reset all migrations (down then up)`).option(`-d, --dir <directory>`,`Migrations directory`,`./migrations`).option(`-c, --config <path>`,`Config file path`,`./driftsql.config.ts`).action(async e=>{try{let{client:t,migrations:n}=await O(e.dir,e.config);await new m(t).reset(n),await t.close(),l.success(`All migrations reset successfully`)}catch(e){l.error(`Reset failed:`,e),process.exit(1)}}),E.command(`migrate:status`).description(`Show migration status`).option(`-d, --dir <directory>`,`Migrations directory`,`./migrations`).option(`-c, --config <path>`,`Config file path`,`./driftsql.config.ts`).action(async e=>{try{let{client:t,migrations:n}=await O(e.dir,e.config),r=await new m(t).getAppliedMigrations();l.info(`Migration Status:
16
+ `);for(let e of n){let t=r.includes(e.version)?`✓ Applied`:`✗ Pending`;l.log(`${t} - ${e.version} (${e.name})`)}await t.close()}catch(e){l.error(`Failed to get status:`,e),process.exit(1)}}),E.command(`migrate:create <name>`).description(`Create a new migration file`).option(`-d, --dir <directory>`,`Migrations directory`,`./migrations`).action(async(e,t)=>{try{let n=new Date().toISOString().replace(/[-:T.]/g,``).slice(0,14),r=`${n}_${e}.ts`,i=d.join(t.dir,r);await u.mkdir(t.dir,{recursive:!0});let a=`import { createMigration } from 'driftsql'
17
+
18
+ export const migration = createMigration('postgres')
19
+ .raw('-- Add your migration SQL here')
20
+ .build('${n}', '${e}')
21
+ `;await u.writeFile(i,a,`utf8`),l.success(`Created migration: ${r}`)}catch(e){l.error(`Failed to create migration:`,e),process.exit(1)}}),E.command(`migrate:generate [name]`).description(`Automatically generate migration from schema changes`).option(`-s, --schema <path>`,`Schema file path`,`./schema.ts`).option(`-d, --dir <directory>`,`Migrations directory`,`./migrations`).action(async(e,t)=>{try{let n=new h,r=d.resolve(process.cwd(),t.schema);l.start(`Loading schema...`);let i=await import(r),a=i.default||i.schema;(!a||!Array.isArray(a))&&(l.error(`Schema file must export default or named "schema" as an array of table definitions`),l.info(`Example: export default [usersTable.getDefinition(), postsTable.getDefinition()]`),process.exit(1));let o=a,s=await n.load();if(!s){l.info(`No previous schema snapshot found, creating initial migration...`);let r=new Date().toISOString().replace(/[-:T.]/g,``).slice(0,14),i=e||`initial`,a=`${r}_${i}.ts`,s=d.join(t.dir,a);await u.mkdir(t.dir,{recursive:!0});let{PostgresGenerator:c}=await import(`./postgres-DWtAqXNK.js`),f=new c,p=o.map(e=>f.generateCreateTable(e)).map(e=>` .raw(\`${e.replace(/`/g,"\\`")}\`)`).join(`
22
+ `),m=`import { createMigration } from 'driftsql'
23
+
24
+ // Initial migration - automatically generated
25
+ // Generated at: ${new Date().toISOString()}
26
+
27
+ export const migration = createMigration('postgres')
28
+ ${p}
29
+ .build('${r}', '${i}')
30
+ `;await u.writeFile(s,m,`utf8`),await n.save(o);let{generateTypesFromSchema:h}=await import(`./type-generator-DbcqBk-4.js`);await h(o,d.join(process.cwd(),`db-types.ts`)),l.success(`\nCreated initial migration: ${a}`),l.success(`Generated TypeScript types: db-types.ts`),l.info(`Snapshot saved. Run "driftsql migrate:up" to apply changes.`);return}l.info(`Detecting changes...`);let c=w(s.tables,o,`postgres`);if(c.length===0){l.success(`No schema changes detected!`);return}l.info(`Found ${c.length} change(s):`),c.forEach((e,t)=>{l.log(` ${t+1}. ${e.type} - ${e.table}`)});let f=new Date().toISOString().replace(/[-:T.]/g,``).slice(0,14),p=e||`auto_migration`,m=`${f}_${p}.ts`,g=d.join(t.dir,m);await u.mkdir(t.dir,{recursive:!0});let _=T(c,f,p).build(f,p).up.map(e=>` .raw(\`${e.replace(/`/g,"\\`")}\``).join(`
31
+ `),v=`import { createMigration } from 'driftsql'
32
+
33
+ // This migration was automatically generated
34
+ // Generated at: ${new Date().toISOString()}
35
+ // Changes: ${c.length}
36
+
37
+ export const migration = createMigration('postgres')
38
+ ${_}
39
+ .build('${f}', '${p}')
40
+ `;await u.writeFile(g,v,`utf8`),await n.save(o);let{generateTypesFromSchema:y}=await import(`./type-generator-DbcqBk-4.js`);await y(o,d.join(process.cwd(),`db-types.ts`)),l.success(`\nGenerated migration: ${m}`),l.success(`Updated TypeScript types: db-types.ts`),l.info(`Snapshot updated. Run "driftsql migrate:up" to apply changes.`)}catch(e){l.error(`Failed to generate migration:`,e),process.exit(1)}}),E.command(`db:inspect`).description(`Inspect database and generate TypeScript types`).option(`-c, --config <path>`,`Config file path`,`./driftsql.config.ts`).option(`-o, --output <path>`,`Output file path`,`./db-types.ts`).action(async e=>{try{let t=await D(e.config);await t.inspectDB({driver:t.getDriver(),outputFile:e.output}),await t.close()}catch(e){l.error(`Inspection failed:`,e),process.exit(1)}}),E.command(`generate:types`).description(`Generate TypeScript types from schema file`).option(`-s, --schema <path>`,`Schema file path`,`./schema.ts`).option(`-o, --output <path>`,`Output file path`,`./db-types.ts`).action(async e=>{try{let t=d.resolve(process.cwd(),e.schema),n=d.resolve(process.cwd(),e.output);l.start(`Loading schema...`);let r=await import(t),i=r.default||r.schema;(!i||!Array.isArray(i))&&(l.error(`Schema file must export default or named "schema" as an array of table definitions`),process.exit(1));let{generateTypesFromSchema:a}=await import(`./type-generator-DbcqBk-4.js`);await a(i,n),l.success(`TypeScript types generated: ${e.output}`)}catch(e){l.error(`Type generation failed:`,e),process.exit(1)}}),E.command(`init`).description(`Initialize DriftSQL with a basic notes schema`).option(`-d, --dir <directory>`,`Migrations directory`,`./migrations`).action(async e=>{try{await u.mkdir(e.dir,{recursive:!0});let t=`.driftsql/
41
+ .env
42
+ `,n=d.join(process.cwd(),`driftsql.config.ts`),r=d.join(process.cwd(),`schema.ts`),i=d.join(process.cwd(),`.env.example`),a=d.join(process.cwd(),`.gitignore`),o=[{path:n,content:`import { SQLClient, PostgresDriver } from 'driftsql'
43
+
44
+ export default new SQLClient({
45
+ driver: new PostgresDriver({
46
+ connectionString: process.env.DATABASE_URL!,
47
+ }),
48
+ })
49
+ `,name:`driftsql.config.ts`},{path:r,content:`import { createTable, serial, varchar, text, timestamp, boolean } from 'driftsql'
50
+
51
+ const notesTable = createTable('notes', (table) => {
52
+ table
53
+ .column(serial('id').primaryKey())
54
+ .column(varchar('title', 255).notNull())
55
+ .column(text('content'))
56
+ .column(boolean('is_archived').default(false).notNull())
57
+ .column(timestamp('created_at').default('CURRENT_TIMESTAMP').notNull())
58
+ .column(timestamp('updated_at').default('CURRENT_TIMESTAMP').notNull())
59
+ .index('idx_notes_archived', ['is_archived'])
60
+ .index('idx_notes_created_at', ['created_at'])
61
+ })
62
+
63
+ // Export array of table definitions
64
+ export default [notesTable.getDefinition()]
65
+ `,name:`schema.ts`},{path:i,content:`DATABASE_URL=postgresql://user:password@localhost:5432/mydb
66
+ `,name:`.env.example`}];for(let e of o)try{await u.access(e.path),l.warn(`${e.name} already exists, skipping...`)}catch{await u.writeFile(e.path,e.content,`utf8`),l.success(`Created ${e.name}`)}try{(await u.readFile(a,`utf8`)).includes(`.driftsql/`)||(await u.appendFile(a,`
67
+ `+t),l.success(`Updated .gitignore`))}catch{await u.writeFile(a,t,`utf8`),l.success(`Created .gitignore`)}l.success(`
68
+ ✨ DriftSQL initialized successfully!
69
+ `),l.info(`Next steps:`),l.info(`1. Copy .env.example to .env and update DATABASE_URL`),l.info(`2. Run: driftsql migrate:generate initial (generates migration + types)`),l.info(`3. Run: driftsql migrate:up`),l.info(`4. Import Database type from db-types.ts for type safety`),l.info(`5. Edit schema.ts and run migrate:generate to auto-detect changes!
70
+ `)}catch(e){l.error(`Initialization failed:`,e),process.exit(1)}});async function D(e){try{let t=await import(d.resolve(process.cwd(),e));return t.default||t.client}catch(t){throw l.error(`Failed to load config from ${e}`),t}}async function O(e,t){let n=await D(t),r=[];try{let t=d.resolve(process.cwd(),e),i=(await u.readdir(t)).filter(e=>e.endsWith(`.ts`)||e.endsWith(`.js`)).sort();for(let e of i){let n=await import(d.join(t,e)),i=n.migration||n.default;i&&r.push(i)}return{client:n,migrations:r}}catch(t){throw l.error(`Failed to load migrations from ${e}`),t}}E.parse();function k(e){return`transaction`in e&&typeof e.transaction==`function`}function A(e){return`prepare`in e&&typeof e.prepare==`function`}var j=class extends Error{constructor(e,t,n){super(e),this.driverType=t,this.originalError=n,this.name=`DatabaseError`}},M=class extends j{constructor(e,t,n){super(`Query failed: ${t}`,e,n),this.name=`QueryError`}};const N=(e,t=3e4)=>Promise.race([e,new Promise((e,n)=>setTimeout(()=>n(Error(`Query timeout after ${t}ms`)),t))]),P=async(e,t=3,n=1e3)=>{for(let r=1;r<=t;r++)try{return await e()}catch(e){if(r===t)throw e;let i=n*2**(r-1);l.warn(`Query attempt ${r} failed, retrying in ${i}ms...`,e),await new Promise(e=>setTimeout(e,i))}throw Error(`Max retries exceeded`)},F=(e,t=!1,n=`postgres`)=>{let r=t?` | null`:``;switch(e.toLowerCase()){case`uuid`:return`string${r}`;case`character varying`:case`varchar`:case`text`:case`char`:case`character`:case`longtext`:case`mediumtext`:case`tinytext`:return`string${r}`;case`integer`:case`int`:case`int4`:case`smallint`:case`int2`:case`bigint`:case`int8`:case`serial`:case`bigserial`:case`numeric`:case`decimal`:case`real`:case`float4`:case`double precision`:case`float8`:case`tinyint`:case`mediumint`:case`float`:case`double`:return`number${r}`;case`boolean`:case`bool`:case`bit`:return`boolean${r}`;case`timestamp`:case`timestamp with time zone`:case`timestamp without time zone`:case`timestamptz`:case`date`:case`time`:case`time with time zone`:case`time without time zone`:case`timetz`:case`interval`:case`datetime`:case`year`:return`Date${r}`;case`json`:case`jsonb`:return`any${r}`;case`array`:return`any[]${r}`;case`bytea`:case`binary`:case`varbinary`:case`blob`:case`longblob`:case`mediumblob`:case`tinyblob`:return`Buffer${r}`;case`enum`:case`set`:return`string${r}`;default:return l.warn(`Unknown ${n} type: ${e}, defaulting to 'any'`),`any${r}`}},te=e=>`${e.constructor.name||`unknown driver`}`;var ne=async e=>{l.warn(`inspectDB is experimental and may make mistakes when inspecting your database. However it will not destroy your database.`);let{driver:t,outputFile:n=`db-types.ts`}=e,r=te(t);l.start(`Inspecting database using ${r} driver`);let i=new $({driver:t}),a=``;try{let e,t;if(r===`mysql`){let n=(await N(P(()=>i.query("SELECT DATABASE() as `database`",[])),1e4)).rows[0]?.database;if(!n)throw Error(`Could not determine current MySQL database name`);l.success(`Using MySQL database: ${n}`),e=`SELECT TABLE_NAME as table_name
3
71
  FROM information_schema.tables
4
72
  WHERE TABLE_SCHEMA = ?
5
73
  AND TABLE_TYPE = 'BASE TABLE'
6
- ORDER BY TABLE_NAME`;tableSchemaFilter=currentDatabase}else if(driverType==="postgres"||driverType==="neon"){tablesQuery=`SELECT table_name
74
+ ORDER BY TABLE_NAME`,t=n}else if(r===`postgres`||r===`neon`)e=`SELECT table_name
7
75
  FROM information_schema.tables
8
76
  WHERE table_schema = $1
9
77
  AND table_type = 'BASE TABLE'
10
- ORDER BY table_name`;tableSchemaFilter="public"}else if(driverType==="libsql"||driverType==="sqlite"||driverType==="sqlitecloud"){tablesQuery=`SELECT name as table_name
78
+ ORDER BY table_name`,t=`public`;else if(r===`libsql`||r===`sqlite`||r===`sqlitecloud`)e=`SELECT name as table_name
11
79
  FROM sqlite_master
12
80
  WHERE type = 'table'
13
- ORDER BY name`;tableSchemaFilter=undefined}else{throw new Error(`Unsupported driver type: ${driverType}`)}const tables=await withTimeout(retryQuery(()=>client.query(tablesQuery,tableSchemaFilter?[tableSchemaFilter]:[])),30000);consola2.info("Tables in the database:",tables.rows.map((t)=>t.table_name).join(", "));let processedTables=0;const totalTables=tables.rows.length;for(const table of tables.rows){const tableName=table.table_name;if(tableName.startsWith("sqlite_sequence")||tableName.startsWith("_prisma_migrations")){continue}processedTables++;consola2.info(`[${processedTables}/${totalTables}] Inspecting table: ${tableName}`);try{let columnsQuery;let queryParams;if(driverType==="mysql"){columnsQuery=`
81
+ ORDER BY name`,t=void 0;else throw Error(`Unsupported driver type: ${r}`);let o=await N(P(()=>i.query(e,t?[t]:[])),3e4);l.info(`Tables in the database:`,o.rows.map(e=>e.table_name).join(`, `));let s=0,c=o.rows.length;for(let e of o.rows){let n=e.table_name;if(!(n.startsWith(`sqlite_sequence`)||n.startsWith(`_prisma_migrations`))){s++,l.info(`[${s}/${c}] Inspecting table: ${n}`);try{let e,o;r===`mysql`?(e=`
14
82
  SELECT
15
83
  COLUMN_NAME as column_name,
16
84
  DATA_TYPE as data_type,
@@ -20,7 +88,7 @@ import consola6 from"consola";function hasTransactionSupport(driver){return"tran
20
88
  WHERE TABLE_NAME = ?
21
89
  AND TABLE_SCHEMA = ?
22
90
  ORDER BY ORDINAL_POSITION
23
- `;queryParams=[tableName,tableSchemaFilter]}else if(driverType==="postgres"||driverType==="neon"){columnsQuery=`
91
+ `,o=[n,t]):r===`postgres`||r===`neon`?(e=`
24
92
  SELECT
25
93
  column_name,
26
94
  data_type,
@@ -30,7 +98,7 @@ import consola6 from"consola";function hasTransactionSupport(driver){return"tran
30
98
  WHERE table_name = $1
31
99
  AND table_schema = $2
32
100
  ORDER BY ordinal_position
33
- `;queryParams=[tableName,tableSchemaFilter]}else{columnsQuery=`
101
+ `,o=[n,t]):(e=`
34
102
  SELECT
35
103
  name as column_name,
36
104
  type as data_type,
@@ -38,17 +106,9 @@ import consola6 from"consola";function hasTransactionSupport(driver){return"tran
38
106
  dflt_value as column_default
39
107
  FROM pragma_table_info(?)
40
108
  ORDER BY cid
41
- `;queryParams=[tableName]}const columns=await withTimeout(retryQuery(()=>client.query(columnsQuery,queryParams)),15000);if(columns.rows.length===0){consola2.info(`No columns found for table: ${tableName}`);continue}consola2.info(`Columns in '${tableName}'`);columns.rows.forEach((c)=>{const typeDisplay=c.data_type+(c.is_nullable==="YES"?" (nullable)":"");consola2.info(` > ${chalk.bold.yellow(typeDisplay)} > ${c.column_name}`)});const uniqueColumns=new Map;columns.rows.forEach((col)=>{if(!uniqueColumns.has(col.column_name)){uniqueColumns.set(col.column_name,col)}});generatedTypes+=`export interface ${tableName.charAt(0).toUpperCase()+tableName.slice(1)} {
42
- `;for(const col of uniqueColumns.values()){const tsType=mapDatabaseTypeToTypeScript(col.data_type,col.is_nullable==="YES",driverType);generatedTypes+=` ${col.column_name}: ${tsType};
43
- `}generatedTypes+=`}
44
-
45
- `}catch(error){consola2.error(`Failed to process table ${tableName}:`,error);consola2.info(`Skipping table ${tableName} and continuing...`);continue}}generatedTypes+=`export interface Database {
46
- `;for(const table of tables.rows){if(table.table_name.startsWith("sqlite_sequence")||table.table_name.startsWith("_prisma_migrations")){continue}const interfaceName=table.table_name.charAt(0).toUpperCase()+table.table_name.slice(1);generatedTypes+=` ${table.table_name}: ${interfaceName};
47
- `}generatedTypes+=`}
48
-
49
- `;await fs.writeFile(outputFile,generatedTypes,"utf8");consola2.success(`TypeScript types written to ${outputFile}`);consola2.success(`Successfully processed ${processedTables} tables`)}catch(error){consola2.error("Fatal error during database inspection:",error);throw error}finally{await client.close().catch((error)=>consola2.error("Error closing client:",error))}};import Surreal from"surrealdb";import consola3 from"consola";class SurrealDriver{client;constructor(config){consola3.warn("SurrealDriver is very experimental and not all functions from the sdk are supported. It is only used for testing purposes.");this.client=new Surreal;this.client.connect(config.url,{namespace:config.namespace,database:config.database,auth:config.auth})}async query(sql,params){try{if(params)throw new QueryError("surreal",sql,new Error("SurrealDB does need params"));const dbResult=await this.client.query(sql);return{rows:dbResult,rowCount:dbResult.length}}catch(error){throw new QueryError("surreal",sql,error)}}async close(){await this.client.close()}}var{SQL}=globalThis.Bun;import consola4 from"consola";class BunDriver{client;adapter;constructor(config){if(!Bun){throw new Error("BunDriver is only supported in Bun runtime")}consola4.warn("BunDriver only supports helper functions for PostgreSQL for now. But you can still use the query method.");this.adapter=config.adapter;this.client=new SQL({url:config.connectionString,adapter:config.adapter==="postgres"?"postgres":config.adapter==="mysql"?"mysql":config.adapter==="mariadb"?"mariadb":"sqlite"})}async query(sql,params){try{const response=await this.client.unsafe(sql,params);return{rows:response,rowCount:response.length}}catch(error){throw new QueryError("bun",sql,error)}}async findFirst(table,where){if(this.adapter!=="postgres"){throw new Error("Helper functions are only supported for PostgreSQL adapter")}const whereEntries=Object.entries(where||{});let sql=`SELECT * FROM ${table}`;let params=[];if(whereEntries.length>0){const whereClause=whereEntries.map((_,index)=>`${whereEntries[index]?.[0]} = $${index+1}`).join(" AND ");sql+=` WHERE ${whereClause}`;params=whereEntries.map(([,value])=>value)}sql+=" LIMIT 1";const result=await this.query(sql,params);return result.rows.length>0?result:null}async findMany(table,options){if(this.adapter!=="postgres"){throw new Error("Helper functions are only supported for PostgreSQL adapter")}const{where,limit,offset}=options||{};const whereEntries=Object.entries(where||{});let sql=`SELECT * FROM ${table}`;let params=[];if(whereEntries.length>0){const whereClause=whereEntries.map((_,index)=>`${whereEntries[index]?.[0]} = $${index+1}`).join(" AND ");sql+=` WHERE ${whereClause}`;params=whereEntries.map(([,value])=>value)}if(typeof limit==="number"&&limit>0){sql+=` LIMIT $${params.length+1}`;params.push(limit)}if(typeof offset==="number"&&offset>0){sql+=` OFFSET $${params.length+1}`;params.push(offset)}return this.query(sql,params)}async insert(table,data){if(this.adapter!=="postgres"){throw new Error("Helper functions are only supported for PostgreSQL adapter")}const tableName=String(table);const keys=Object.keys(data);const values=Object.values(data);if(keys.length===0){throw new Error("No data provided for insert")}const placeholders=keys.map((_,index)=>`$${index+1}`).join(", ");const sql=`INSERT INTO ${tableName} (${keys.join(", ")}) VALUES (${placeholders}) RETURNING *`;const result=await this.query(sql,values);if(!result.rows[0]){throw new Error("Insert failed: No data returned")}return result}async update(table,data,where){if(this.adapter!=="postgres"){throw new Error("Helper functions are only supported for PostgreSQL adapter")}const tableName=String(table);const setEntries=Object.entries(data);const whereEntries=Object.entries(where);if(setEntries.length===0){throw new Error("No data provided for update")}if(whereEntries.length===0){throw new Error("No conditions provided for update")}const setClause=setEntries.map((_,index)=>`${setEntries[index]?.[0]} = $${index+1}`).join(", ");const whereClause=whereEntries.map((_,index)=>`${whereEntries[index]?.[0]} = $${setEntries.length+index+1}`).join(" AND ");const sql=`UPDATE ${tableName} SET ${setClause} WHERE ${whereClause} RETURNING *`;const params=[...setEntries.map(([,value])=>value),...whereEntries.map(([,value])=>value)];const result=await this.query(sql,params);return result.rows.length>0?result:result}async delete(table,where){if(this.adapter!=="postgres"){throw new Error("Helper functions are only supported for PostgreSQL adapter")}const tableName=String(table);const whereEntries=Object.entries(where);if(whereEntries.length===0){throw new Error("No conditions provided for delete")}const whereClause=whereEntries.map((_,index)=>`${whereEntries[index]?.[0]} = $${index+1}`).join(" AND ");const sql=`DELETE FROM ${tableName} WHERE ${whereClause}`;const params=whereEntries.map(([,value])=>value);const result=await this.query(sql,params);return result.rowCount}async close(){await this.client.close()}}import consola5 from"consola";var{connect}=globalThis.Bun;function parseRows(result){const rows=[];const lines=result.split(`
50
- `).filter((l)=>l.trim());for(const line of lines){const cleaned=line.replace(/^{|}$/g,"");const pairs=cleaned.split(", ");const row={};for(const pair of pairs){const[key,value]=pair.split(": ");if(key&&value){const cleanKey=key.replace(/"/g,"");const cleanValue=value.replace(/"/g,"");if(cleanValue==="Null"){row[cleanKey]=null}else if(cleanValue.startsWith("Int(")){row[cleanKey]=parseInt(cleanValue.slice(4,-1))}else if(cleanValue.startsWith("Text(")){row[cleanKey]=cleanValue.slice(5,-1)}else{row[cleanKey]=cleanValue}}}if(Object.keys(row).length>0){rows.push(row)}}return rows}class PoubelleClient{socket=null;config;connected=false;buffer="";constructor(connectionString){this.config=this.parseConnectionString(connectionString)}parseConnectionString(connStr){const urlPattern=/^poubelle:\/\/([^:]+):([^@]+)@([^:]+):(\d+)$/;const match=connStr.match(urlPattern);if(!match){throw new Error("Invalid connection string format. Expected: poubelle://username:password@host:port")}const[,username,password,host,port]=match;return{username,password,host,port:parseInt(port,10)}}async connect(){this.socket=await connect({hostname:this.config.host,port:this.config.port,socket:{data:(socket,data)=>{const text=Buffer.from(data).toString();this.buffer+=text},error:(socket,error)=>{console.error("Socket error:",error)}}});await this.waitForPrompt("Username: ");await this.send(`${this.config.username}
51
- `);await this.waitForPrompt("Password: ");await this.send(`${this.config.password}
52
- `);await this.waitForPrompt("Connected to Poubelle DB");this.connected=true}async query(sql){if(!this.connected||!this.socket){throw new Error("Not connected")}await this.waitForPrompt("poubelle> ");this.buffer="";await this.send(`${sql}
53
- `);await new Promise((resolve)=>setTimeout(resolve,100));const result=this.buffer.split("poubelle> ")[0].trim();return parseRows(result)}async createTable(name,columns){const cols=Object.entries(columns).map(([name2,type])=>`${name2} ${type}`).join(", ");await this.query(`CREATE TABLE ${name} (${cols})`)}async insert(table,data){const columns=Object.keys(data).join(", ");const values=Object.values(data).map((v)=>{if(v===null)return"NULL";if(typeof v==="string")return`'${v}'`;return v}).join(", ");await this.query(`INSERT INTO ${table} (${columns}) VALUES (${values})`)}async select(table,columns=["*"]){const cols=columns.join(", ");return await this.query(`SELECT ${cols} FROM ${table}`)}async close(){if(this.socket){await this.send(`exit
54
- `);this.socket.end();this.socket=null;this.connected=false}}async send(data){if(!this.socket)throw new Error("Socket not connected");this.socket.write(data)}async waitForPrompt(prompt,timeout=5000){const start=Date.now();while(!this.buffer.includes(prompt)){if(Date.now()-start>timeout){throw new Error(`Timeout waiting for prompt: ${prompt}`)}await new Promise((resolve)=>setTimeout(resolve,10))}}}var client_default=PoubelleClient;class PoubelleDriver{client;constructor(config){if(!Bun){throw new Error("PoubelleDriver is only supported in Bun runtime")}consola5.warn("PoubelleDriver is experimental, please use with caution");this.client=new client_default(config.connectionString)}async query(sql,params){try{if(params)throw new Error("PoubelleDriver does not support params");const result=await this.client.query(sql);return{rows:result,rowCount:0}}catch(error){throw new QueryError("poubelle",sql,error)}}async close(){await this.client.close()}}class SQLClient{primaryDriver;fallbackDrivers;constructor(options){this.primaryDriver=options.driver;this.fallbackDrivers=options.fallbackDrivers||[]}async query(sql,params){const drivers=[this.primaryDriver,...this.fallbackDrivers];let lastError;for(const driver of drivers){try{return await driver.query(sql,params)}catch(error){lastError=error;consola6.warn(`Query failed with ${driver.constructor.name}:`,error);continue}}throw lastError||new DatabaseError("All drivers failed to execute query","unknown")}async transaction(callback){if(!hasTransactionSupport(this.primaryDriver)){throw new DatabaseError("Primary driver does not support transactions",this.primaryDriver.constructor.name)}return await this.primaryDriver.transaction(async(transactionDriver)=>{const transactionClient=new SQLClient({driver:transactionDriver,fallbackDrivers:[]});return await callback(transactionClient)})}async prepare(sql){if(!hasPreparedStatementSupport(this.primaryDriver)){throw new DatabaseError("Primary driver does not support prepared statements",this.primaryDriver.constructor.name)}return await this.primaryDriver.prepare(sql)}async findFirst(table,where){if(!this.primaryDriver.findFirst)throw new DatabaseError("Primary driver does not support findFirst",this.primaryDriver.constructor.name);try{const response=await this.primaryDriver.findFirst(table,where);return response.rows[0]||null}catch(error){throw new QueryError("findFirst",`Error finding first in ${String(table)}`,error)}}async findMany(table,options){if(!this.primaryDriver.findMany)throw new DatabaseError("Primary driver does not support findMany",this.primaryDriver.constructor.name);try{const response=await this.primaryDriver.findMany(table,options);return response.rows}catch(error){throw new QueryError("findMany",`Error finding many in ${String(table)}`,error)}}async insert(table,data){if(!this.primaryDriver.insert)throw new DatabaseError("Primary driver does not support insert",this.primaryDriver.constructor.name);try{const response=await this.primaryDriver.insert(table,data);return response.rows[0]}catch(error){throw new QueryError("insert",`Error inserting into ${String(table)}`,error)}}async update(table,data,where){if(!this.primaryDriver.update)throw new DatabaseError("Primary driver does not support update",this.primaryDriver.constructor.name);try{const response=await this.primaryDriver.update(table,data,where);return response.rows[0]||null}catch(error){throw new QueryError("update",`Error updating ${String(table)}`,error)}}async delete(table,where){if(!this.primaryDriver.delete)throw new DatabaseError("Primary driver does not support delete",this.primaryDriver.constructor.name);try{const affectedRows=await this.primaryDriver.delete(table,where);return affectedRows}catch(error){throw new QueryError("delete",`Error deleting from ${String(table)}`,error)}}getDriver(){return this.primaryDriver}supportsTransactions(){return hasTransactionSupport(this.primaryDriver)}supportsPreparedStatements(){return hasPreparedStatementSupport(this.primaryDriver)}async close(){const drivers=[this.primaryDriver,...this.fallbackDrivers];await Promise.all(drivers.map((driver)=>driver.close().catch((err)=>consola6.warn(`Error closing ${driver.constructor.name}:`,err))))}}var DriftSQLClient=SQLClient;export{inspectDB,SurrealDriver,SqliteCloudDriver,SQLClient,PoubelleDriver,PostgresDriver,NeonDriver,MySQLDriver,LibSQLDriver,DriftSQLClient,BunDriver};
109
+ `,o=[n]);let s=await N(P(()=>i.query(e,o)),15e3);if(s.rows.length===0){l.info(`No columns found for table: ${n}`);continue}l.info(`Columns in '${n}'`),s.rows.forEach(e=>{let t=e.data_type+(e.is_nullable===`YES`?` (nullable)`:``);l.info(` > ${f.bold.yellow(t)} > ${e.column_name}`)});let c=new Map;s.rows.forEach(e=>{c.has(e.column_name)||c.set(e.column_name,e)}),a+=`export interface ${n.charAt(0).toUpperCase()+n.slice(1)} {\n`;for(let e of c.values()){let t=F(e.data_type,e.is_nullable===`YES`,r);a+=` ${e.column_name}: ${t};\n`}a+=`}
110
+
111
+ `}catch(e){l.error(`Failed to process table ${n}:`,e),l.info(`Skipping table ${n} and continuing...`);continue}}}a+=`export interface Database {
112
+ `;for(let e of o.rows){if(e.table_name.startsWith(`sqlite_sequence`)||e.table_name.startsWith(`_prisma_migrations`))continue;let t=e.table_name.charAt(0).toUpperCase()+e.table_name.slice(1);a+=` ${e.table_name}: ${t};\n`}a+=`}
113
+
114
+ `,await u.writeFile(n,a,`utf8`),l.success(`TypeScript types written to ${n}`),l.success(`Successfully processed ${s} tables`)}catch(e){throw l.error(`Fatal error during database inspection:`,e),e}finally{await i.close().catch(e=>l.error(`Error closing client:`,e))}};function I(e){return{async findFirst(t,n){let r=[],i=[],a=1;if(n)for(let[e,t]of Object.entries(n))r.push(`"${e}" = $${a}`),i.push(t),a++;let o=`SELECT * FROM "${t}" ${r.length>0?`WHERE ${r.join(` AND `)}`:``} LIMIT 1`;return await e.query(o,i)},async findMany(t,n){let r=[],i=[],a=1;if(n?.where)for(let[e,t]of Object.entries(n.where))r.push(`"${e}" = $${a}`),i.push(t),a++;let o=r.length>0?`WHERE ${r.join(` AND `)}`:``,s=n?.limit?`LIMIT $${a++}`:``,c=n?.offset?`OFFSET $${a++}`:``;n?.limit&&i.push(n.limit),n?.offset&&i.push(n.offset);let l=`SELECT * FROM "${t}" ${o} ${s} ${c}`.trim();return await e.query(l,i)},async insert(t,n){let r=Object.keys(n),i=Object.values(n),a=`INSERT INTO "${t}" (${r.map(e=>`"${e}"`).join(`, `)}) VALUES (${r.map((e,t)=>`$${t+1}`).join(`, `)}) RETURNING *`;return await e.query(a,i)},async update(t,n,r){let i=Object.entries(n),a=Object.entries(r),o=[],s=1,c=i.map(([e,t])=>(o.push(t),`"${e}" = $${s++}`)),l=a.map(([e,t])=>(o.push(t),`"${e}" = $${s++}`)),u=`UPDATE "${t}" SET ${c.join(`, `)} WHERE ${l.join(` AND `)} RETURNING *`;return await e.query(u,o)},async delete(t,n){let r=[],i=[],a=1;for(let[e,t]of Object.entries(n))r.push(`"${e}" = $${a}`),i.push(t),a++;let o=`DELETE FROM "${t}" WHERE ${r.join(` AND `)}`;return(await e.query(o,i)).rowCount}}}var L=class{client;findFirst;findMany;insert;update;delete;constructor(e){this.client=p(e.connectionString,{max:e.max??10,idle_timeout:e.idle_timeout??30,connect_timeout:e.connect_timeout??10,prepare:!1,transform:{undefined:null}});let t=I(this);this.findFirst=t.findFirst,this.findMany=t.findMany,this.insert=t.insert,this.update=t.update,this.delete=t.delete}async query(e,t){try{let n=await this.client.unsafe(e,t||[]),r=Array.isArray(n)?[...n]:[];return{rows:r,rowCount:r.length,command:n.command}}catch(t){throw new M(`postgres`,e,t)}}async close(){await this.client.end()}};function R(e){return{async findFirst(t,n){let r=[],i=[];if(n)for(let[e,t]of Object.entries(n))r.push(`\`${e}\` = ?`),i.push(t);let a=`SELECT * FROM \`${t}\` ${r.length>0?`WHERE ${r.join(` AND `)}`:``} LIMIT 1`;return await e.query(a,i)},async findMany(t,n){let r=[],i=[];if(n?.where)for(let[e,t]of Object.entries(n.where))r.push(`\`${e}\` = ?`),i.push(t);let a=r.length>0?`WHERE ${r.join(` AND `)}`:``,o=n?.limit?`LIMIT ?`:``,s=n?.offset?`OFFSET ?`:``;n?.limit&&i.push(n.limit),n?.offset&&i.push(n.offset);let c=`SELECT * FROM \`${t}\` ${a} ${o} ${s}`.trim();return await e.query(c,i)},async insert(t,n){let r=Object.keys(n),i=Object.values(n),a=`INSERT INTO \`${t}\` (${r.map(e=>`\`${e}\``).join(`, `)}) VALUES (${r.map(()=>`?`).join(`, `)})`;await e.query(a,i);let o=`SELECT * FROM \`${t}\` WHERE id = LAST_INSERT_ID()`;return await e.query(o)},async update(t,n,r){let i=Object.entries(n),a=Object.entries(r),o=[],s=i.map(([e,t])=>(o.push(t),`\`${e}\` = ?`)),c=a.map(([e,t])=>(o.push(t),`\`${e}\` = ?`)),l=`UPDATE \`${t}\` SET ${s.join(`, `)} WHERE ${c.join(` AND `)}`;await e.query(l,o);let u=Object.values(r),d=`SELECT * FROM \`${t}\` WHERE ${Object.keys(r).map(e=>`\`${e}\` = ?`).join(` AND `)}`;return await e.query(d,u)},async delete(t,n){let r=[],i=[];for(let[e,t]of Object.entries(n))r.push(`\`${e}\` = ?`),i.push(t);let a=`DELETE FROM \`${t}\` WHERE ${r.join(` AND `)}`;return(await e.query(a,i)).rowCount}}}function z(e){return{async findFirst(t,n){let r=[],i=[];if(n)for(let[e,t]of Object.entries(n))r.push(`"${e}" = ?`),i.push(t);let a=`SELECT * FROM "${t}" ${r.length>0?`WHERE ${r.join(` AND `)}`:``} LIMIT 1`;return await e.query(a,i)},async findMany(t,n){let r=[],i=[];if(n?.where)for(let[e,t]of Object.entries(n.where))r.push(`"${e}" = ?`),i.push(t);let a=r.length>0?`WHERE ${r.join(` AND `)}`:``,o=n?.limit?`LIMIT ?`:``,s=n?.offset?`OFFSET ?`:``;n?.limit&&i.push(n.limit),n?.offset&&i.push(n.offset);let c=`SELECT * FROM "${t}" ${a} ${o} ${s}`.trim();return await e.query(c,i)},async insert(t,n){let r=Object.keys(n),i=Object.values(n),a=`INSERT INTO "${t}" (${r.map(e=>`"${e}"`).join(`, `)}) VALUES (${r.map(()=>`?`).join(`, `)}) RETURNING *`;return await e.query(a,i)},async update(t,n,r){let i=Object.entries(n),a=Object.entries(r),o=[],s=i.map(([e,t])=>(o.push(t),`"${e}" = ?`)),c=a.map(([e,t])=>(o.push(t),`"${e}" = ?`)),l=`UPDATE "${t}" SET ${s.join(`, `)} WHERE ${c.join(` AND `)} RETURNING *`;return await e.query(l,o)},async delete(t,n){let r=[],i=[];for(let[e,t]of Object.entries(n))r.push(`"${e}" = ?`),i.push(t);let a=`DELETE FROM "${t}" WHERE ${r.join(` AND `)}`;return(await e.query(a,i)).rowCount}}}var B=class{definition;constructor(e,t){this.definition={name:e,type:t}}length(e){return this.definition.length=e,this}precision(e,t){return this.definition.precision=e,t!==void 0&&(this.definition.scale=t),this}primaryKey(){return this.definition.primaryKey=!0,this.definition.notNull=!0,this}notNull(){return this.definition.notNull=!0,this}unique(){return this.definition.unique=!0,this}default(e){return this.definition.default=e,this}references(e,t=`id`){return this.definition.references={table:e,column:t},this}onDelete(e){return this.definition.references&&(this.definition.references.onDelete=e),this}onUpdate(e){return this.definition.references&&(this.definition.references.onUpdate=e),this}check(e){return this.definition.check=e,this}getDefinition(){return this.definition}};function V(e){return new B(e,`serial`)}function H(e){return new B(e,`bigserial`)}function U(e){return new B(e,`integer`)}function W(e){return new B(e,`bigint`)}function G(e){return new B(e,`smallint`)}function K(e){return new B(e,`text`)}function q(e,t){let n=new B(e,`varchar`);return t&&n.length(t),n}function J(e,t){let n=new B(e,`char`);return t&&n.length(t),n}function Y(e){return new B(e,`boolean`)}function X(e){return new B(e,`timestamp`)}function re(e){return new B(e,`timestamptz`)}function ie(e){return new B(e,`date`)}function ae(e){return new B(e,`time`)}function oe(e){return new B(e,`json`)}function Z(e){return new B(e,`jsonb`)}function se(e){return new B(e,`uuid`)}function ce(e,t,n){let r=new B(e,`decimal`);return t&&r.precision(t,n),r}function le(e,t,n){let r=new B(e,`numeric`);return t&&r.precision(t,n),r}function ue(e){return new B(e,`real`)}function de(e){return new B(e,`double precision`)}function fe(e){return new B(e,`bytea`)}var Q=class{definition;constructor(e){this.definition={name:e,columns:[],indexes:[],checks:[]}}column(e){return this.definition.columns.push(e.getDefinition()),this}primaryKey(...e){return this.definition.primaryKey=e,this}index(e,t,n){let r={name:e,columns:t,unique:n?.unique,type:n?.type};return this.definition.indexes?.push(r),this}unique(e,...t){return this.index(e,t,{unique:!0})}check(e,t){return this.definition.checks?.push({name:e,expression:t}),this}getDefinition(){return this.definition}};function pe(e,t){let n=new Q(e);return t(n),n}n(),v(),x();var $=class e{primaryDriver;fallbackDrivers;queryCache;cacheTTL;maxCacheSize=100;constructor(e){this.primaryDriver=e.driver,this.fallbackDrivers=e.fallbackDrivers||[],this.queryCache=new Map,this.cacheTTL=e.cacheTTL??5e3}isCacheValid(e){return Date.now()-e.timestamp<this.cacheTTL}getCacheKey(e,t){return JSON.stringify({sql:e,params:t})}maintainCacheSize(){if(this.queryCache.size>this.maxCacheSize){let e=this.queryCache.keys().next().value;e!==void 0&&this.queryCache.delete(e)}}cacheResult(e,t){this.queryCache.set(e,{result:t,timestamp:Date.now()}),this.maintainCacheSize()}async tryFallbackDrivers(e,t){l.warn(`Query failed with ${this.primaryDriver.constructor.name}, trying fallbacks`);let n;for(let r of this.fallbackDrivers)try{return await r.query(e,t)}catch(e){n=e}throw n||new j(`All drivers failed to execute query`,`unknown`)}async query(e,t){let n=this.getCacheKey(e,t),r=this.queryCache.get(n);if(r&&this.isCacheValid(r))return r.result;try{let r=await this.primaryDriver.query(e,t);return this.cacheResult(n,r),r}catch(n){if(this.fallbackDrivers.length===0)throw n;return await this.tryFallbackDrivers(e,t)}}async transaction(t){if(!k(this.primaryDriver))throw new j(`Primary driver does not support transactions`,this.primaryDriver.constructor.name);return await this.primaryDriver.transaction(async n=>await t(new e({driver:n,fallbackDrivers:[]})))}async prepare(e){if(!A(this.primaryDriver))throw new j(`Primary driver does not support prepared statements`,this.primaryDriver.constructor.name);return await this.primaryDriver.prepare(e)}async findFirst(e,t){if(!this.primaryDriver.findFirst)throw new j(`Primary driver does not support findFirst`,this.primaryDriver.constructor.name);return(await this.primaryDriver.findFirst(e,t))?.rows[0]||null}async findMany(e,t){if(!this.primaryDriver.findMany)throw new j(`Primary driver does not support findMany`,this.primaryDriver.constructor.name);return(await this.primaryDriver.findMany(e,t)).rows}async insert(e,t){if(!this.primaryDriver.insert)throw new j(`Primary driver does not support insert`,this.primaryDriver.constructor.name);return(await this.primaryDriver.insert(e,t)).rows[0]}async update(e,t,n){if(!this.primaryDriver.update)throw new j(`Primary driver does not support update`,this.primaryDriver.constructor.name);return(await this.primaryDriver.update(e,t,n)).rows[0]||null}async delete(e,t){if(!this.primaryDriver.delete)throw new j(`Primary driver does not support delete`,this.primaryDriver.constructor.name);return await this.primaryDriver.delete(e,t)}getDriver(){return this.primaryDriver}async inspectDB(e){return await ne({driver:this.getDriver(),...e})}supportsTransactions(){return k(this.primaryDriver)}supportsPreparedStatements(){return A(this.primaryDriver)}clearCache(){this.queryCache.clear()}getCacheStats(){return{size:this.queryCache.size,ttl:this.cacheTTL}}async close(){this.queryCache.clear();let e=[this.primaryDriver,...this.fallbackDrivers].map(e=>e.close().catch(t=>l.warn(`Error closing ${e.constructor.name}:`,t)));await Promise.all(e)}};const me=$;export{B as Column,me as DriftSQLClient,S as MigrationBuilder,m as MigrationRunner,_ as MySQLGenerator,L as PostgresDriver,a as PostgresGenerator,$ as SQLClient,b as SQLiteGenerator,C as SchemaDiffer,h as SnapshotManager,Q as Table,s as TypeGenerator,W as bigint,H as bigserial,Y as boolean,fe as bytea,J as char,ee as createMigration,R as createMySQLHelpers,I as createPostgresHelpers,z as createSQLiteHelpers,pe as createTable,ie as date,ce as decimal,w as detectChanges,de as doublePrecision,T as generateMigrationFromChanges,o as generateTypesFromSchema,U as integer,oe as json,Z as jsonb,le as numeric,ue as real,V as serial,G as smallint,K as text,ae as time,X as timestamp,re as timestamptz,se as uuid,q as varchar};
@@ -0,0 +1,5 @@
1
+ var e=Object.defineProperty,t=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,r=Object.prototype.hasOwnProperty,i=(e,t)=>()=>(e&&(t=e(e=0)),t),a=t=>{let n={};for(var r in t)e(n,r,{get:t[r],enumerable:!0});return n},o=(i,a,o,s)=>{if(a&&typeof a==`object`||typeof a==`function`)for(var c=n(a),l=0,u=c.length,d;l<u;l++)d=c[l],!r.call(i,d)&&d!==o&&e(i,d,{get:(e=>a[e]).bind(null,d),enumerable:!(s=t(a,d))||s.enumerable});return i},s=t=>o(e({},`__esModule`,{value:!0}),t),c=a({PostgresGenerator:()=>l}),l,u=i((()=>{l=class{generateCreateTable(e){let t=[];t.push(`CREATE TABLE "${e.name}" (`);let n=[];for(let t of e.columns)n.push(` `+this.generateColumnDefinition(t));if(e.primaryKey&&e.primaryKey.length>0){let t=e.primaryKey.map(e=>`"${e}"`).join(`, `);n.push(` PRIMARY KEY (${t})`)}if(e.checks&&e.checks.length>0)for(let t of e.checks)n.push(` CONSTRAINT "${t.name}" CHECK (${t.expression})`);t.push(n.join(`,
2
+ `)),t.push(`);`);let r=[t.join(`
3
+ `)];if(e.indexes&&e.indexes.length>0)for(let t of e.indexes)r.push(this.generateIndex(e.name,t));return r.join(`
4
+
5
+ `)}generateDropTable(e){return`DROP TABLE IF EXISTS "${e}" CASCADE;`}generateColumnDefinition(e){let t=[`"${e.name}"`];if(t.push(this.getColumnType(e)),e.primaryKey&&!e.type.includes(`serial`)&&t.push(`PRIMARY KEY`),e.notNull&&!e.primaryKey&&!e.type.includes(`serial`)&&t.push(`NOT NULL`),e.unique&&t.push(`UNIQUE`),e.default!==void 0&&t.push(`DEFAULT ${this.formatDefault(e.default)}`),e.references){let n=e.references;t.push(`REFERENCES "${n.table}"("${n.column}")`),n.onDelete&&t.push(`ON DELETE ${n.onDelete}`),n.onUpdate&&t.push(`ON UPDATE ${n.onUpdate}`)}return e.check&&t.push(`CHECK (${e.check})`),t.join(` `)}getColumnType(e){let t=e.type.toUpperCase();return e.length?t+=`(${e.length})`:e.precision&&(e.scale===void 0?t+=`(${e.precision})`:t+=`(${e.precision}, ${e.scale})`),t}formatDefault(e){return typeof e==`string`?e.toUpperCase()===`NOW()`||e.toUpperCase()===`CURRENT_TIMESTAMP`?e.toUpperCase():`'${e}'`:typeof e==`boolean`?e?`TRUE`:`FALSE`:String(e)}generateIndex(e,t){let n=t.unique?`UNIQUE `:``,r=t.type?` USING ${t.type.toUpperCase()}`:``,i=t.columns.map(e=>`"${e}"`).join(`, `);return`CREATE ${n}INDEX "${t.name}" ON "${e}"${r} (${i});`}}}));export{a,i,u as n,s as o,c as r,l as t};
@@ -0,0 +1 @@
1
+ import{n as e,t}from"./postgres-9C7eE0wB.js";e();export{t as PostgresGenerator};
@@ -0,0 +1,7 @@
1
+ import e from"node:fs/promises";var t=class{generateTypes(e){let t=`// This file was automatically generated - DO NOT EDIT
2
+
3
+ `;for(let n of e)t+=this.generateTableInterface(n),t+=`
4
+
5
+ `;return t+=this.generateDatabaseInterface(e),t}generateTableInterface(e){let t=[`export interface ${this.pascalCase(e.name)} {`];for(let n of e.columns){let e=this.columnToTypeScript(n),r=!n.notNull&&!n.primaryKey?`?`:``;t.push(` ${n.name}${r}: ${e}`)}return t.push(`}`),t.join(`
6
+ `)}generateDatabaseInterface(e){let t=[`export interface Database {`];for(let n of e){let e=this.pascalCase(n.name);t.push(` ${n.name}: ${e}`)}return t.push(`}`),t.join(`
7
+ `)}columnToTypeScript(e){let t=!e.notNull&&!e.primaryKey,n;switch(e.type.toLowerCase()){case`serial`:case`bigserial`:case`integer`:case`int`:case`bigint`:case`smallint`:case`numeric`:case`decimal`:case`real`:case`double precision`:n=`number`;break;case`text`:case`varchar`:case`char`:case`uuid`:n=`string`;break;case`boolean`:n=`boolean`;break;case`timestamp`:case`timestamptz`:case`date`:case`time`:n=`Date | string`;break;case`json`:case`jsonb`:n=`any`;break;case`bytea`:n=`Buffer`;break;default:n=`any`}return t?`${n} | null`:n}pascalCase(e){return e.split(`_`).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(``)}async writeToFile(t,n){let r=this.generateTypes(t);await e.writeFile(n,r,`utf8`)}};async function n(e,n){await new t().writeToFile(e,n)}export{n,t};
@@ -0,0 +1 @@
1
+ import{n as e,t}from"./type-generator-Ba8bgnMm.js";export{t as TypeGenerator,e as generateTypesFromSchema};
package/package.json CHANGED
@@ -1,35 +1,48 @@
1
1
  {
2
2
  "name": "driftsql",
3
- "version": "1.0.32",
4
- "main": "dist/index.js",
5
- "description": "A lightweight SQL client for TypeScript",
6
- "scripts": {
7
- "build": "bun build.ts"
3
+ "version": "2.0.0-beta.2",
4
+ "description": "A modern, type-safe SQL client with built-in schema builder and migration system for TypeScript.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "homepage": "https://github.com/lassejlv/driftsql",
8
+ "bugs": {
9
+ "url": "https://github.com/lassejlv/driftsql/issues"
8
10
  },
9
- "author": "Lasse Vestergaard",
10
11
  "repository": {
11
12
  "type": "git",
12
- "url": "lassejlv/driftsql"
13
+ "url": "git+https://github.com/lassejlv/driftsql.git"
14
+ },
15
+ "author": "Lasse Vestergaard",
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "main": "./dist/index.js",
20
+ "module": "./dist/index.js",
21
+ "types": "./dist/index.d.ts",
22
+ "bin": {
23
+ "driftsql": "./dist/index.js"
24
+ },
25
+ "exports": {
26
+ ".": "./dist/index.js",
27
+ "./package.json": "./package.json"
28
+ },
29
+ "scripts": {
30
+ "build": "tsdown",
31
+ "dev": "tsdown --watch --minify=false",
32
+ "test": "vitest",
33
+ "typecheck": "tsc --noEmit"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^24.9.1",
37
+ "bumpp": "^10.3.1",
38
+ "tsdown": "^0.15.9",
39
+ "typescript": "^5.9.3",
40
+ "vitest": "^4.0.1"
13
41
  },
14
- "license": "MIT",
15
42
  "dependencies": {
16
- "@libsql/client": "^0.15.15",
17
- "@neondatabase/serverless": "^1.0.2",
18
- "@sqlitecloud/drivers": "^1.0.507",
19
- "@tursodatabase/serverless": "^0.1.3",
20
43
  "chalk": "^5.6.2",
44
+ "commander": "^14.0.2",
21
45
  "consola": "^3.4.2",
22
- "driftsql": "^1.0.29",
23
- "ky": "^1.11.0",
24
- "mysql2": "^3.15.1",
25
- "ora": "^9.0.0",
26
- "postgres": "^3.4.7",
27
- "surrealdb": "^1.3.2",
28
- "zod": "^4.1.11"
29
- },
30
- "devDependencies": {
31
- "@types/bun": "^1.2.23",
32
- "prettier": "^3.6.2",
33
- "typescript": "^5.9.3"
46
+ "postgres": "^3.4.7"
34
47
  }
35
48
  }
package/.prettierrc DELETED
@@ -1,5 +0,0 @@
1
- {
2
- "printWidth": 200,
3
- "semi": false,
4
- "singleQuote": true
5
- }
@@ -1,22 +0,0 @@
1
- import { type DatabaseDriver, type QueryResult } from '../types';
2
- interface BunConfig {
3
- connectionString: string;
4
- adapter: 'postgres' | 'mysql' | 'mariadb' | 'sqlite';
5
- }
6
- export declare class BunDriver implements DatabaseDriver {
7
- private client;
8
- private adapter;
9
- constructor(config: BunConfig);
10
- query<T = any>(sql: string, params?: any[]): Promise<QueryResult<T>>;
11
- findFirst<T = any>(table: string, where?: Record<string, any>): Promise<QueryResult<T> | null>;
12
- findMany<T = any>(table: string, options?: {
13
- where?: Record<string, any>;
14
- limit?: number;
15
- offset?: number;
16
- }): Promise<QueryResult<T>>;
17
- insert<T = any>(table: string, data: Record<string, any>): Promise<QueryResult<T>>;
18
- update<T = any>(table: string, data: Record<string, any>, where: Record<string, any>): Promise<QueryResult<T>>;
19
- delete<T = any>(table: string, where: Record<string, any>): Promise<number>;
20
- close(): Promise<void>;
21
- }
22
- export {};
@@ -1,23 +0,0 @@
1
- import type { DatabaseDriver, QueryResult, TransactionCapable } from '../types';
2
- export interface LibSQLConfig {
3
- url: string;
4
- authToken?: string;
5
- useTursoServerlessDriver?: boolean;
6
- }
7
- export declare class LibSQLDriver implements DatabaseDriver, TransactionCapable {
8
- private client;
9
- constructor(config: LibSQLConfig);
10
- query<T = any>(sql: string, params?: any[]): Promise<QueryResult<T>>;
11
- transaction<T>(callback: (driver: DatabaseDriver) => Promise<T>): Promise<T>;
12
- findFirst<T = any>(table: string, where?: Record<string, any>): Promise<QueryResult<T> | null>;
13
- findMany<T = any>(table: string, options?: {
14
- where?: Record<string, any>;
15
- limit?: number;
16
- offset?: number;
17
- }): Promise<QueryResult<T>>;
18
- insert<T = any>(table: string, data: Record<string, any>): Promise<QueryResult<T>>;
19
- update<T = any>(table: string, data: Record<string, any>, where: Record<string, any>): Promise<QueryResult<T>>;
20
- delete(table: string, where: Record<string, any>): Promise<number>;
21
- close(): Promise<void>;
22
- private convertLibsqlResult;
23
- }
@@ -1,20 +0,0 @@
1
- import type { DatabaseDriver, QueryResult, TransactionCapable } from '../types';
2
- export interface MySQLConfig {
3
- connectionString: string;
4
- }
5
- export declare class MySQLDriver implements DatabaseDriver, TransactionCapable {
6
- private client;
7
- constructor(config: MySQLConfig);
8
- query<T = any>(sql: string, params?: any[]): Promise<QueryResult<T>>;
9
- transaction<T>(callback: (driver: DatabaseDriver) => Promise<T>): Promise<T>;
10
- findFirst<T = any>(table: string, where?: Record<string, any>): Promise<QueryResult<T> | null>;
11
- findMany<T = any>(table: string, options?: {
12
- where?: Record<string, any>;
13
- limit?: number;
14
- offset?: number;
15
- }): Promise<QueryResult<T>>;
16
- insert<T = any>(table: string, data: Record<string, any>): Promise<QueryResult<T>>;
17
- update<T = any>(table: string, data: Record<string, any>, where: Record<string, any>): Promise<QueryResult<T>>;
18
- delete(table: string, where: Record<string, any>): Promise<number>;
19
- close(): Promise<void>;
20
- }
@@ -1,19 +0,0 @@
1
- import { type DatabaseDriver, type QueryResult } from '../types';
2
- export interface NeonDriverOptions {
3
- connectionString: string;
4
- }
5
- export declare class NeonDriver implements DatabaseDriver {
6
- private client;
7
- constructor(options: NeonDriverOptions);
8
- query<T = any>(sql: string, params?: any[]): Promise<QueryResult<T>>;
9
- findFirst<T = any>(table: string, where?: Record<string, any>): Promise<QueryResult<T> | null>;
10
- findMany<T = any>(table: string, options?: {
11
- where?: Record<string, any>;
12
- limit?: number;
13
- offset?: number;
14
- }): Promise<QueryResult<T>>;
15
- insert<T = any>(table: string, data: Record<string, any>): Promise<QueryResult<T>>;
16
- update<T = any>(table: string, data: Record<string, any>, where: Record<string, any>): Promise<QueryResult<T>>;
17
- delete<T = any>(table: string, where: Record<string, any>): Promise<number>;
18
- close(): Promise<void>;
19
- }
@@ -1,26 +0,0 @@
1
- import type { DatabaseDriver, QueryResult, TransactionCapable } from '../types';
2
- export interface PostgresConfig {
3
- connectionString?: string;
4
- experimental?: {
5
- http?: {
6
- url: string;
7
- apiKey?: string;
8
- };
9
- };
10
- }
11
- export declare class PostgresDriver implements DatabaseDriver, TransactionCapable {
12
- private client;
13
- constructor(config: PostgresConfig);
14
- query<T = any>(sql: string, params?: any[]): Promise<QueryResult<T>>;
15
- transaction<T>(callback: (driver: DatabaseDriver) => Promise<T>): Promise<T>;
16
- findFirst<T = any>(table: string, where?: Record<string, any>): Promise<QueryResult<T> | null>;
17
- findMany<T = any>(table: string, options?: {
18
- where?: Record<string, any>;
19
- limit?: number;
20
- offset?: number;
21
- }): Promise<QueryResult<T>>;
22
- insert<T = any>(table: string, data: Record<string, any>): Promise<QueryResult<T>>;
23
- update<T = any>(table: string, data: Record<string, any>, where: Record<string, any>): Promise<QueryResult<T>>;
24
- delete<T = any>(table: string, where: Record<string, any>): Promise<number>;
25
- close(): Promise<void>;
26
- }
@@ -1,20 +0,0 @@
1
- export interface Row {
2
- [key: string]: number | string | null;
3
- }
4
- export declare class PoubelleClient {
5
- private socket;
6
- private config;
7
- private connected;
8
- private buffer;
9
- constructor(connectionString: string);
10
- private parseConnectionString;
11
- connect(): Promise<void>;
12
- query(sql: string): Promise<Row[]>;
13
- createTable(name: string, columns: Record<string, 'INT' | 'TEXT'>): Promise<void>;
14
- insert(table: string, data: Record<string, number | string | null>): Promise<void>;
15
- select(table: string, columns?: string[]): Promise<Row[]>;
16
- close(): Promise<void>;
17
- private send;
18
- private waitForPrompt;
19
- }
20
- export default PoubelleClient;
@@ -1,11 +0,0 @@
1
- import { type DatabaseDriver, type QueryResult } from '../../types';
2
- interface PoubelleConfig {
3
- connectionString: string;
4
- }
5
- export declare class PoubelleDriver implements DatabaseDriver {
6
- private client;
7
- constructor(config: PoubelleConfig);
8
- query<T = any>(sql: string, params?: any[]): Promise<QueryResult<T>>;
9
- close(): Promise<void>;
10
- }
11
- export {};
@@ -1,21 +0,0 @@
1
- import { type DatabaseDriver, type QueryResult } from '../types';
2
- export interface SqliteCloudDriverOptions {
3
- connectionString: string;
4
- }
5
- export declare class SqliteCloudDriver implements DatabaseDriver {
6
- private readonly options;
7
- private client;
8
- constructor(options: SqliteCloudDriverOptions);
9
- query<T = any>(sql: string, params?: any[]): Promise<QueryResult<T>>;
10
- prepare(sql: string): Promise<import("@sqlitecloud/drivers/lib/drivers/statement").Statement<any>>;
11
- findFirst<T = any>(table: string, where?: Record<string, any>): Promise<QueryResult<T> | null>;
12
- findMany<T = any>(table: string, options?: {
13
- where?: Record<string, any>;
14
- limit?: number;
15
- offset?: number;
16
- }): Promise<QueryResult<T>>;
17
- insert<T = any>(table: string, data: Record<string, any>): Promise<QueryResult<T>>;
18
- update<T = any>(table: string, data: Record<string, any>, where: Record<string, any>): Promise<QueryResult<T>>;
19
- delete(table: string, where: Record<string, any>): Promise<number>;
20
- close(): Promise<void>;
21
- }
@@ -1,17 +0,0 @@
1
- import type { DatabaseDriver, QueryResult } from '../types';
2
- interface SurrealConfig {
3
- url: string;
4
- namespace: string;
5
- database: string;
6
- auth: {
7
- username: string;
8
- password: string;
9
- };
10
- }
11
- export declare class SurrealDriver implements DatabaseDriver {
12
- private client;
13
- constructor(config: SurrealConfig);
14
- query<T = any>(sql: string, params?: any[]): Promise<QueryResult<T>>;
15
- close(): Promise<void>;
16
- }
17
- export {};
package/dist/inspect.d.ts DELETED
@@ -1,7 +0,0 @@
1
- import type { DatabaseDriver } from './types';
2
- interface InspectOptions {
3
- driver: DatabaseDriver;
4
- outputFile?: string;
5
- }
6
- export declare const inspectDB: (options: InspectOptions) => Promise<void>;
7
- export default inspectDB;
package/dist/pull.d.ts DELETED
@@ -1,7 +0,0 @@
1
- import type { DatabaseDriver } from './types';
2
- interface InspectOptions {
3
- driver: DatabaseDriver;
4
- outputFile?: string;
5
- }
6
- export declare const inspectDB: (options: InspectOptions) => Promise<void>;
7
- export default inspectDB;