@stacksjs/database 0.70.73 → 0.70.74
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/database.d.ts +7 -6
- package/dist/driver-config.d.ts +42 -42
- package/dist/drivers/index.d.ts +3 -0
- package/dist/factory.d.ts +1 -1
- package/dist/index.js +136 -132
- package/dist/types.d.ts +3 -0
- package/dist/utils.d.ts +17 -6
- package/package.json +12 -12
package/dist/index.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var v6=Object.defineProperty;var f6=(Z)=>Z;function b6(Z,Y){this[Z]=f6.bind(null,Y)}var p6=(Z,Y)=>{for(var $ in Y)v6(Z,$,{get:Y[$],enumerable:!0,configurable:!0,set:b6.bind(Y,$)})};var sZ=(Z,Y)=>()=>(Z&&(Y=Z(Z=0)),Y);var p=import.meta.require;function o(Z,Y){let $=Y??{};switch(Z){case"sqlite":return{database:$.DB_DATABASE_PATH||GZ.sqlitePath,prefix:""};case"mysql":return{database:$.DB_DATABASE||GZ.default,host:$.DB_HOST||"127.0.0.1",port:$.DB_PORT||rZ.mysql,username:$.DB_USERNAME||nZ.mysql,password:$.DB_PASSWORD||"",prefix:""};case"postgres":return{database:$.DB_DATABASE||GZ.default,host:$.DB_HOST||"127.0.0.1",port:$.DB_PORT||rZ.postgres,username:$.DB_USERNAME||nZ.postgres,password:$.DB_PASSWORD||"",prefix:""};default:return{database:":memory:"}}}var k0="127.0.0.1",rZ,GZ,nZ,N0,y0;var rY=sZ(()=>{rZ={mysql:3306,postgres:5432,sqlite:0},GZ={default:"stacks",sqlitePath:"database/stacks.sqlite",sqliteTestingPath:"database/stacks_testing.sqlite"},nZ={mysql:"root",postgres:"postgres",sqlite:""},N0={host:"localhost",port:6379},y0={region:"us-east-1"}});var u={};p6(u,{setConfig:()=>oZ,initializeDbConfig:()=>Z4,ensureDatabaseConfigLoaded:()=>_Z,db:()=>V,applySqlitePragmas:()=>W7,acquireDbConfigLock:()=>e6,SQLITE_BOOTSTRAP_PRAGMAS:()=>OZ});import{AsyncLocalStorage as a6}from"async_hooks";import{createQueryBuilder as o6,setConfig as oZ}from"@stacksjs/query-builder";import{env as xY}from"@stacksjs/env";import{applySqlitePragmas as W7,SQLITE_BOOTSTRAP_PRAGMAS as OZ}from"@stacksjs/query-builder";function e6(){let Z=()=>{},Y=new Promise((J)=>{Z=J}),$=zZ.then(()=>Z);return zZ=zZ.then(()=>Y),$}function Z4(Z){if(Z?.app?.env)tZ=Z.app.env;if(Z?.database?.default)eZ=Z.database.default;if(Z?.database)Y4=Z.database;QZ(),QY=null}function $4(){return tZ}function J4(){return eZ}function Y7(){return Y4}function X4(){let Z=J4();if(Z==="sqlite")return"sqlite";if(Z==="mysql")return"mysql";if(Z==="singlestore")return"singlestore";if(Z==="postgres")return"postgres";return"sqlite"}function Z7(){let Z=J4(),Y=Y7(),$=$4();if(Z==="sqlite"){let J=$!=="testing"?"database/stacks.sqlite":"database/stacks_testing.sqlite";return{database:Y.connections?.sqlite?.database??J}}if(Z==="mysql")return{database:Y.connections?.mysql?.name||"stacks",host:Y.connections?.mysql?.host??"127.0.0.1",username:Y.connections?.mysql?.username??"root",password:Y.connections?.mysql?.password??"",port:Y.connections?.mysql?.port??3306};if(Z==="singlestore")return{database:Y.connections?.singlestore?.name||"stacks",host:Y.connections?.singlestore?.host??"127.0.0.1",username:Y.connections?.singlestore?.username??"root",password:Y.connections?.singlestore?.password??"",port:Y.connections?.singlestore?.port??3306};if(Z==="postgres"){let J=Y.connections?.postgres?.name??"stacks";return{database:$==="testing"?`${J}_testing`:J,host:Y.connections?.postgres?.host??"127.0.0.1",username:Y.connections?.postgres?.username??"",password:Y.connections?.postgres?.password??"",port:Y.connections?.postgres?.port??5432}}return{database:":memory:"}}function QZ(){let Z=X4(),Y=Z7();oZ({dialect:Z,database:Y,verbose:$4()!=="production",timestamps:{createdAt:"created_at",updatedAt:"updated_at",defaultOrderColumn:"created_at"},softDeletes:{enabled:!0,column:"deleted_at",defaultFilter:!0}})}function W4(){if(!UZ)UZ=(async()=>{try{let{config:Z,overridesReady:Y}=await import("@stacksjs/config");if(await Y,Z)Z4(Z),QY=null}catch{}})();return UZ}async function _Z(){await W4()}function $7(Z){if(iZ.getStore())return Z();let Y=aZ.then(()=>iZ.run(!0,Z));return aZ=Y.then(()=>{return},()=>{return}),Y}function J7(Z){let Y=Z.transaction.bind(Z);Z.transaction=(...$)=>$7(()=>Y(...$))}function X7(){if(!QY){if(QZ(),QY=o6(),X4()==="sqlite")J7(QY)}return QY}var t6,DY,qY,tZ,eZ,Y4,zZ,QY=null,UZ=null,iZ,aZ,V;var F=sZ(()=>{rY();t6=o("sqlite",xY),DY=o("mysql",xY),qY=o("postgres",xY),tZ=xY.APP_ENV||"local",eZ=xY.DB_CONNECTION||"sqlite",Y4={connections:{sqlite:{database:t6.database,prefix:""},mysql:{name:DY.database,host:DY.host,username:DY.username,password:DY.password,port:DY.port,prefix:""},postgres:{name:qY.database,host:qY.host,username:qY.username,password:qY.password,port:qY.port,prefix:""}}},zZ=Promise.resolve();QZ();iZ=new a6,aZ=Promise.resolve();W4();V=new Proxy({},{get(Z,Y){let $=X7(),J=$[Y];if(typeof J==="function")return J.bind($);return J}})});import{createQueryBuilder as C6,setConfig as c6}from"@stacksjs/query-builder";import{env as C}from"@stacksjs/env";class a{_queryBuilder=null;_options;_initialized=!1;constructor(Z){this._options={verbose:!1,timestamps:{createdAt:"created_at",updatedAt:"updated_at",defaultOrderColumn:"created_at"},softDeletes:{enabled:!1,column:"deleted_at",defaultFilter:!0},...Z}}get driver(){return this._options.driver}get connection(){return this._options.connection}get isInitialized(){return this._initialized}get query(){if(!this._queryBuilder)this.initialize();return this._queryBuilder}initialize(){if(this._initialized)return;c6({dialect:this._options.driver,database:this._options.connection,verbose:this._options.verbose,timestamps:this._options.timestamps,softDeletes:this._options.softDeletes,hooks:this._options.hooks}),this._queryBuilder=C6(),this._initialized=!0}switchDriver(Z,Y){this.close(),this._options.driver=Z,this._options.connection=Y,this._initialized=!1,this.initialize()}async close(){if(this._queryBuilder&&typeof this._queryBuilder.close==="function")await this._queryBuilder.close();this._queryBuilder=null,this._initialized=!1}static fromConfig(Z,Y){let $=Z.default,J;switch($){case"sqlite":{J={database:Y==="testing"?Z.connections.sqlite?.database?.replace(".sqlite","_testing.sqlite")||"database/stacks_testing.sqlite":Z.connections.sqlite?.database||"database/stacks.sqlite"};break}case"mysql":{let X=Z.connections.mysql;J={database:X?.name||"stacks",host:X?.host||"127.0.0.1",port:X?.port||3306,username:X?.username||"root",password:X?.password||""};break}case"singlestore":{let X=Z.connections.singlestore;J={database:X?.name||"stacks",host:X?.host||"127.0.0.1",port:X?.port||3306,username:X?.username||"root",password:X?.password||""};break}case"postgres":{let X=Z.connections.postgres,W=X?.name||"stacks";J={database:Y==="testing"?`${W}_testing`:W,host:X?.host||"127.0.0.1",port:X?.port||5432,username:X?.username||"",password:X?.password||""};break}case"dynamodb":throw Error("[database] DB_CONNECTION=dynamodb is not a SQL driver. Use the entity-style `dynamo.entity(...)` API for DynamoDB access, or set DB_CONNECTION to sqlite/mysql/postgres for SQL workloads.");default:throw Error(`[database] Unknown DB_CONNECTION "${String($)}". Allowed values: sqlite, mysql, postgres.`)}return new a({driver:$,connection:J,verbose:Y!=="production"})}static fromEnv(){let Z=C.DB_CONNECTION||"sqlite",Y;switch(Z){case"sqlite":Y={database:C.DB_DATABASE||"database/stacks.sqlite"};break;case"mysql":case"singlestore":Y={database:C.DB_DATABASE||"stacks",host:C.DB_HOST||"127.0.0.1",port:C.DB_PORT||3306,username:C.DB_USERNAME||"root",password:C.DB_PASSWORD||""};break;case"postgres":Y={database:C.DB_DATABASE||"stacks",host:C.DB_HOST||"127.0.0.1",port:C.DB_PORT||5432,username:C.DB_USERNAME||"",password:C.DB_PASSWORD||""};break;default:Y={database:":memory:"}}return new a({driver:Z,connection:Y,verbose:C.APP_ENV!=="prod"})}}function u6(Z){return new a(Z)}function g6(Z,Y){return new a({driver:"sqlite",connection:{database:Z},...Y})}function d6(Z,Y){return new a({driver:"postgres",connection:Z,...Y})}function m6(Z,Y){return new a({driver:"mysql",connection:Z,...Y})}import{env as S}from"@stacksjs/env";var lZ={sqlite:{database:"database/stacks.sqlite",prefix:""},mysql:{name:"stacks",host:"127.0.0.1",port:3306,username:"root",password:"",prefix:"",charset:"utf8mb4",collation:"utf8mb4_unicode_ci"},singlestore:{name:"stacks",host:"127.0.0.1",port:3306,username:"root",password:"",prefix:"",charset:"utf8mb4",ssl:!1},postgres:{name:"stacks",host:"127.0.0.1",port:5432,username:"postgres",password:"",prefix:"",schema:"public"},browser:{}};function s6(Z,Y){switch(Z){case"sqlite":{let $=Y;if($.database===":memory:")return":memory:";return`sqlite://${$.database}`}case"mysql":{let $=Y,{name:J,host:X="127.0.0.1",port:W=3306,username:H="root",password:G=""}=$;return`mysql://${H}:${G}@${X}:${W}/${J}`}case"singlestore":{let $=Y,{name:J,host:X="127.0.0.1",port:W=3306,username:H="root",password:G=""}=$;return`mysql://${H}:${G}@${X}:${W}/${J}`}case"postgres":{let $=Y,{name:J,host:X="127.0.0.1",port:W=5432,username:H="postgres",password:G=""}=$;return`postgres://${H}:${G}@${X}:${W}/${J}`}default:throw Error(`Unsupported driver: ${Z}`)}}function l6(Z,Y){let $=[];switch(Z){case"sqlite":{if(!Y.database)$.push("SQLite requires a database path");break}case"mysql":{if(!Y.name)$.push("MySQL requires a database name");break}case"singlestore":{if(!Y.name)$.push("SingleStore requires a database name");break}case"postgres":{if(!Y.name)$.push("PostgreSQL requires a database name");break}default:$.push(`Unsupported driver: ${Z}`)}return{valid:$.length===0,errors:$}}function r6(Z,Y){return{...lZ[Z],...Y}}function n6(Z){switch(Z){case"sqlite":return{database:S.DB_DATABASE||"database/stacks.sqlite",prefix:S.DB_PREFIX||""};case"mysql":return{name:S.DB_DATABASE||"stacks",host:S.DB_HOST||"127.0.0.1",port:S.DB_PORT??3306,username:S.DB_USERNAME||"root",password:S.DB_PASSWORD||"",prefix:S.DB_PREFIX||""};case"singlestore":return{name:S.DB_DATABASE||"stacks",host:S.DB_HOST||"127.0.0.1",port:S.DB_PORT??3306,username:S.DB_USERNAME||"root",password:S.DB_PASSWORD||"",prefix:S.DB_PREFIX||"",ssl:S.DB_SSL==="true"||S.DB_SSL==="1"};case"postgres":return{name:S.DB_DATABASE||"stacks",host:S.DB_HOST||"127.0.0.1",port:S.DB_PORT??5432,username:S.DB_USERNAME||"postgres",password:S.DB_PASSWORD||"",prefix:S.DB_PREFIX||"",schema:S.DB_SCHEMA||"public"};default:throw Error(`Unsupported driver: ${Z}`)}}function i6(){if(S.DB_CONNECTION)return S.DB_CONNECTION;if(S.DATABASE_URL?.startsWith("postgres"))return"postgres";if(S.DATABASE_URL?.startsWith("mysql"))return"mysql";return"sqlite"}F();function TY(Z,...Y){let $=[],J=[];for(let X=0;X<Z.length;X++)if($.push(Z[X]),X<Y.length)if(Y[X]&&typeof Y[X]==="object"&&"raw"in Y[X])$.push(Y[X].raw);else $.push("?"),J.push(Y[X]);return{sql:$.join(""),parameters:J}}TY.raw=function(Y){return{raw:Y}};TY.ref=function(Y){return{raw:Y}};F();import{existsSync as EZ,mkdirSync as F7,readdirSync as iY,readFileSync as Q4,unlinkSync as D7,writeFileSync as _4}from"fs";import{dirname as q7,join as t}from"path";import{log as d}from"@stacksjs/logging";import{err as aY,handleError as oY,ok as _Y}from"@stacksjs/error-handling";import{path as yY}from"@stacksjs/path";import{createQueryBuilder as O4,executeMigration as x7,generateMigration as IZ,resetConnection as nY,resetDatabase as T7,setConfig as V4}from"@stacksjs/query-builder";import{Buffer as H7}from"buffer";import{createHash as G7}from"crypto";import{closeSync as z7,openSync as U7,statSync as Q7,unlinkSync as H4,writeFileSync as _7}from"fs";import O7 from"process";import{userDatabasePath as V7}from"@stacksjs/path";var A7=30000,AZ=100,BZ=2000,B7=60000,VZ="stacks_migrations";async function G4(Z,Y,$={}){let J=$.timeoutMs??A7;if(Z!=="sqlite"&&Z!=="postgres"&&Z!=="mysql")throw Error(`[migration-lock] unknown dialect: ${String(Z)}`);if(Z==="sqlite")return j7($.sqliteLockPath,J);if(!Y)throw Error(`[migration-lock] ${Z} requires a database connection to acquire the lock`);if(Z==="postgres")return E7(Y,J);return I7(Y,J)}function L7(){let Z=G7("sha256").update(VZ).digest(),Y=Z.readInt32BE(0),$=Z.readInt32BE(4);return{key1:Y,key2:$}}async function E7(Z,Y){let{key1:$,key2:J}=L7(),X=Date.now(),W=AZ;while(!0){let H=await Z.unsafe(`SELECT pg_try_advisory_lock(${$}, ${J}) AS acquired`);if(S7(H,"acquired"))return{release:async()=>{try{await Z.unsafe(`SELECT pg_advisory_unlock(${$}, ${J})`)}catch{}}};if(Date.now()-X>=Y)throw Error("[migration-lock] another migration is in progress \u2014 could not acquire postgres advisory lock within timeout");await LZ(W),W=Math.min(W*2,BZ)}}async function I7(Z,Y){let $=Date.now(),J=AZ;while(!0){let X=await Z.unsafe(`SELECT GET_LOCK('${VZ}', 0) AS acquired`);if(M7(X,"acquired")===1)return{release:async()=>{try{await Z.unsafe(`SELECT RELEASE_LOCK('${VZ}')`)}catch{}}};if(Date.now()-$>=Y)throw Error("[migration-lock] another migration is in progress \u2014 could not acquire MySQL named lock within timeout");await LZ(J),J=Math.min(J*2,BZ)}}function K7(){return V7(".migration.lock")}async function j7(Z,Y){let $=Z??K7(),J=Date.now(),X=AZ;while(!0){if(R7($)){let W=!1;return{release:async()=>{if(W)return;W=!0;try{H4($)}catch{}}}}if(w7($),Date.now()-J>=Y)throw Error(`[migration-lock] another migration is in progress \u2014 lock file ${$} held within timeout`);await LZ(X),X=Math.min(X*2,BZ)}}function R7(Z){try{let Y=U7(Z,"wx");try{let $=JSON.stringify({pid:O7.pid,startedAt:new Date().toISOString()});_7(Y,H7.from($,"utf8"))}finally{z7(Y)}return!0}catch(Y){if(Y.code==="EEXIST")return!1;throw Y}}function w7(Z){try{let Y=Q7(Z);if(Date.now()-Y.mtimeMs>B7)try{H4(Z)}catch{}}catch{}}function LZ(Z){let Y=Z*(1+Math.random()*0.25);return new Promise(($)=>setTimeout($,Y))}function S7(Z,Y){let $=z4(Z);if(!$)return!1;let J=$[Y];return J===!0||J===1||J==="1"||J==="t"}function M7(Z,Y){let $=z4(Z);if(!$)return null;let J=$[Y];if(typeof J==="number")return J;if(typeof J==="string"&&/^-?\d+$/.test(J))return Number.parseInt(J,10);return null}function z4(Z){if(!Z)return null;if(Array.isArray(Z))return Z[0];if(typeof Z==="object"&&"rows"in Z&&Array.isArray(Z.rows))return Z.rows[0];return null}rY();import{env as tY}from"@stacksjs/env";var K={info:(...Z)=>typeof d?.info==="function"?d.info(...Z):console.log(...Z),success:(Z)=>typeof d?.success==="function"?d.success(Z):console.log(Z),warn:(Z)=>typeof d?.warn==="function"?d.warn(Z):console.warn(Z),error:(...Z)=>typeof d?.error==="function"?d.error(...Z):console.error(...Z),debug:(...Z)=>typeof d?.debug==="function"?d.debug(...Z):console.debug(...Z)},P7=tY.DB_CONNECTION||"sqlite",k7=o("sqlite",tY),PY=o("mysql",tY),kY=o("postgres",tY),NY={default:P7,connections:{sqlite:{database:k7.database,prefix:""},mysql:{name:PY.database,host:PY.host,username:PY.username,password:PY.password,port:PY.port,prefix:""},postgres:{name:kY.database,host:kY.host,username:kY.username,password:kY.password,port:kY.port,prefix:""}}};function A4(){return NY.default||"sqlite"}function e(){let Z=A4();if(Z==="sqlite"||Z==="mysql"||Z==="postgres")return Z;if(Z==="singlestore")return"mysql";if(Z==="dynamodb")throw Error("[database] DB_CONNECTION=dynamodb is not compatible with the SQL migration runner. "+"DynamoDB has no schema-migration concept \u2014 use the entity-style `dynamo.entity(...)` "+"API from @stacksjs/database directly. To run SQL migrations, set DB_CONNECTION to one of: sqlite, mysql, postgres.");throw Error(`[database] Unknown DB_CONNECTION "${Z}". Allowed values: sqlite, mysql, postgres, dynamodb.`)}function KZ(){return A4()==="singlestore"?"singlestore":e()}function hY(){let Z=e(),Y=NY.connections[Z];V4({dialect:Z,verbose:!1,database:{database:Y?.name||Y?.database||"stacks",host:Y?.host||"localhost",port:Y?.port||(Z==="postgres"?5432:Z==="mysql"?3306:0),username:Y?.username||"",password:Y?.password||""}}),nY()}function jZ(){let Z=yY.userModelsPath();return{modelsDir:Z,skip:!EZ(Z)}}function N7(){let Z=t(process.cwd(),"database","migrations"),Y;try{Y=iY(Z).filter((L)=>L.endsWith(".sql"))}catch{return}let $=[],J=(L,A)=>{K.info(`Skipping migration on SQLite (${A}): ${L}`),$.push(L)},X=(L,A,E)=>{K.info(`Dropping no-op migration (${E}): ${L}`);try{D7(A)}catch{}$.push(L)},W=[],H=/^\s*ALTER\s+TABLE\s+.+\s+ADD\s+CONSTRAINT\s+/i,G=/^\s*CREATE\s+TYPE\s+/i,z=/^\s*CREATE\s+UNIQUE\s+INDEX\s+(?:IF\s+NOT\s+EXISTS\s+)?["'`]?(\w+)["'`]?/i,Q=/^\s*ALTER\s+TABLE\s+["']?(\w+)["']?\s+DROP\s+COLUMN\s+["']?(\w+)["']?\s*$/i,_=/^\s*CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?["']?(\w+)["']?/i,U=new Map;for(let L of Y){let A=L.match(/^\d+-create-(\w+)-table\.sql$/);if(!A||!A[1])continue;let E=A[1],B=U.get(E);if(!B||L<B)U.set(E,L)}let I=t(process.cwd(),NY.connections.sqlite.database||"stacks.db"),O=null;if(EZ(I))try{let{Database:L}=p("bun:sqlite");O=new L(I,{readonly:!0})}catch{}for(let L of Y){K.debug(`[migration] Running: ${L}`);let A=t(Z,L),B=Q4(A,"utf-8").split(";").map((w)=>w.trim()).filter((w)=>w.length>0&&!w.startsWith("--"));if(B.length===0)continue;let j=B[0],R=j?j.match(_):null;if(R&&R[1]){let w=R[1],g=U.get(w);if(g&&g!==L){X(L,A,`duplicate create-table for "${w}" (kept ${g})`);continue}}if(B.every((w)=>H.test(w))){J(L,"SQLite does not support ALTER TABLE ADD CONSTRAINT");continue}if(B.every((w)=>G.test(w))){J(L,"SQLite does not support CREATE TYPE (enum types)");continue}let D=B.map((w)=>w.match(z)?.[1]).filter((w)=>Boolean(w));if(O&&D.length===B.length){let w=O.prepare("SELECT name FROM sqlite_master WHERE type = 'index' AND name = ?");if(D.filter((GY)=>!w.get(GY)).length>0)K.info(`Re-queueing unique-index migration (index missing from database): ${L}`),W.push(L);continue}if(B.some((w)=>Q.test(w))){let w=!1,g=[];for(let GY of B){let MY=GY.match(Q);if(MY&&MY[1]&&MY[2]){let lY=MY[1],FY=MY[2];if(!O){K.info(`Skipping DROP COLUMN "${FY}" \u2014 no database exists yet: ${L}`),w=!0;continue}try{let y6=lY.replace(/[^a-zA-Z0-9_]/g,""),mZ=O.prepare(`PRAGMA table_info("${y6}")`).all();if(mZ.length===0){K.info(`Skipping DROP COLUMN "${FY}" \u2014 table "${lY}" does not exist yet: ${L}`),w=!0;continue}if(!mZ.some((h6)=>h6.name===FY)){K.info(`Skipping DROP COLUMN "${FY}" from "${lY}" \u2014 column does not exist: ${L}`),w=!0;continue}}catch{K.info(`Skipping DROP COLUMN "${FY}" \u2014 table "${lY}" not found: ${L}`),w=!0;continue}}g.push(GY)}if(w){if(g.length===0)X(L,A,"columns already absent from table");else _4(A,`${g.join(`;
|
|
2
|
+
var f6=Object.defineProperty;var b6=(Z)=>Z;function p6(Z,Y){this[Z]=b6.bind(null,Y)}var C6=(Z,Y)=>{for(var $ in Y)f6(Z,$,{get:Y[$],enumerable:!0,configurable:!0,set:p6.bind(Y,$)})};var rZ=(Z,Y)=>()=>(Z&&(Y=Z(Z=0)),Y);var b=import.meta.require;function t(Z,Y){let $=Y??{};switch(Z){case"sqlite":return{database:$.DB_DATABASE_PATH||UZ.sqlitePath,prefix:""};case"mysql":return{database:$.DB_DATABASE||UZ.default,host:$.DB_HOST||"127.0.0.1",port:$.DB_PORT||iZ.mysql,username:$.DB_USERNAME||aZ.mysql,password:$.DB_PASSWORD||"",prefix:""};case"postgres":return{database:$.DB_DATABASE||UZ.default,host:$.DB_HOST||"127.0.0.1",port:$.DB_PORT||iZ.postgres,username:$.DB_USERNAME||aZ.postgres,password:$.DB_PASSWORD||"",prefix:""};default:return{database:":memory:"}}}var h0="127.0.0.1",iZ,UZ,aZ,v0,f0;var iY=rZ(()=>{iZ={mysql:3306,postgres:5432,sqlite:0},UZ={default:"stacks",sqlitePath:"database/stacks.sqlite",sqliteTestingPath:"database/stacks_testing.sqlite"},aZ={mysql:"root",postgres:"postgres",sqlite:""},v0={host:"localhost",port:6379},f0={region:"us-east-1"}});var u={};C6(u,{setConfig:()=>eZ,initializeDbConfig:()=>J4,ensureDatabaseConfigLoaded:()=>AZ,db:()=>A,applySqlitePragmas:()=>H7,acquireDbConfigLock:()=>Y7,SQLITE_BOOTSTRAP_PRAGMAS:()=>BZ});import{AsyncLocalStorage as o6}from"async_hooks";import{createQueryBuilder as t6,setConfig as eZ}from"@stacksjs/query-builder";import{env as TY}from"@stacksjs/env";import{applySqlitePragmas as H7,SQLITE_BOOTSTRAP_PRAGMAS as BZ}from"@stacksjs/query-builder";function Y7(){let Z=()=>{},Y=new Promise((J)=>{Z=J}),$=QZ.then(()=>Z);return QZ=QZ.then(()=>Y),$}function J4(Z){if(Z?.app?.env)Y4=Z.app.env;if(Z?.database?.default)Z4=Z.database.default;if(Z?.database)$4=Z.database;OZ(),_Y=null}function X4(){return Y4}function W4(){return Z4}function Z7(){return $4}function H4(){let Z=W4();if(Z==="sqlite")return"sqlite";if(Z==="mysql")return"mysql";if(Z==="singlestore")return"singlestore";if(Z==="postgres")return"postgres";return"sqlite"}function $7(){let Z=W4(),Y=Z7(),$=X4();if(Z==="sqlite"){let J=$!=="testing"?"database/stacks.sqlite":"database/stacks_testing.sqlite";return{database:Y.connections?.sqlite?.database??J}}if(Z==="mysql")return{database:Y.connections?.mysql?.name||"stacks",host:Y.connections?.mysql?.host??"127.0.0.1",username:Y.connections?.mysql?.username??"root",password:Y.connections?.mysql?.password??"",port:Y.connections?.mysql?.port??3306};if(Z==="singlestore")return{database:Y.connections?.singlestore?.name||"stacks",host:Y.connections?.singlestore?.host??"127.0.0.1",username:Y.connections?.singlestore?.username??"root",password:Y.connections?.singlestore?.password??"",port:Y.connections?.singlestore?.port??3306};if(Z==="postgres"){let J=Y.connections?.postgres?.name??"stacks";return{database:$==="testing"?`${J}_testing`:J,host:Y.connections?.postgres?.host??"127.0.0.1",username:Y.connections?.postgres?.username??"",password:Y.connections?.postgres?.password??"",port:Y.connections?.postgres?.port??5432}}return{database:":memory:"}}function OZ(){let Z=H4(),Y=$7();eZ({dialect:Z,database:Y,verbose:X4()!=="production",timestamps:{createdAt:"created_at",updatedAt:"updated_at",defaultOrderColumn:"created_at"},softDeletes:{enabled:!0,column:"deleted_at",defaultFilter:!0}})}function G4(){if(!_Z)_Z=(async()=>{try{let{config:Z,overridesReady:Y}=await import("@stacksjs/config");if(await Y,Z)J4(Z),_Y=null}catch{}})();return _Z}async function AZ(){await G4()}function J7(Z){if(oZ.getStore())return Z();let Y=tZ.then(()=>oZ.run(!0,Z));return tZ=Y.then(()=>{return},()=>{return}),Y}function X7(Z){let Y=Z.transaction.bind(Z);Z.transaction=(...$)=>J7(()=>Y(...$))}function W7(){if(!_Y){if(OZ(),_Y=t6(),H4()==="sqlite")X7(_Y)}return _Y}var e6,d,qY,Y4,Z4,$4,QZ,_Y=null,_Z=null,oZ,tZ,A;var F=rZ(()=>{iY();e6=t("sqlite",TY),d=t("mysql",TY),qY=t("postgres",TY),Y4=TY.APP_ENV||"local",Z4=TY.DB_CONNECTION||"sqlite",$4={connections:{sqlite:{database:e6.database,prefix:""},mysql:{name:d.database,host:d.host,username:d.username,password:d.password,port:d.port,prefix:""},singlestore:{name:d.database,host:d.host,username:d.username,password:d.password,port:d.port,prefix:""},postgres:{name:qY.database,host:qY.host,username:qY.username,password:qY.password,port:qY.port,prefix:""}}},QZ=Promise.resolve();OZ();oZ=new o6,tZ=Promise.resolve();G4();A=new Proxy({},{get(Z,Y){let $=W7(),J=$[Y];if(typeof J==="function")return J.bind($);return J}})});import{createQueryBuilder as c6,setConfig as u6}from"@stacksjs/query-builder";import{env as p}from"@stacksjs/env";class o{_queryBuilder=null;_options;_initialized=!1;constructor(Z){this._options={verbose:!1,timestamps:{createdAt:"created_at",updatedAt:"updated_at",defaultOrderColumn:"created_at"},softDeletes:{enabled:!1,column:"deleted_at",defaultFilter:!0},...Z}}get driver(){return this._options.driver}get connection(){return this._options.connection}get isInitialized(){return this._initialized}get query(){if(!this._queryBuilder)this.initialize();return this._queryBuilder}initialize(){if(this._initialized)return;u6({dialect:this._options.driver,database:this._options.connection,verbose:this._options.verbose,timestamps:this._options.timestamps,softDeletes:this._options.softDeletes,hooks:this._options.hooks}),this._queryBuilder=c6(),this._initialized=!0}switchDriver(Z,Y){this.close(),this._options.driver=Z,this._options.connection=Y,this._initialized=!1,this.initialize()}async close(){if(this._queryBuilder&&typeof this._queryBuilder.close==="function")await this._queryBuilder.close();this._queryBuilder=null,this._initialized=!1}static fromConfig(Z,Y){let $=Z.default,J;switch($){case"sqlite":{J={database:Y==="testing"?Z.connections.sqlite?.database?.replace(".sqlite","_testing.sqlite")||"database/stacks_testing.sqlite":Z.connections.sqlite?.database||"database/stacks.sqlite"};break}case"mysql":{let X=Z.connections.mysql;J={database:X?.name||"stacks",host:X?.host||"127.0.0.1",port:X?.port||3306,username:X?.username||"root",password:X?.password||""};break}case"singlestore":{let X=Z.connections.singlestore;J={database:X?.name||"stacks",host:X?.host||"127.0.0.1",port:X?.port||3306,username:X?.username||"root",password:X?.password||""};break}case"postgres":{let X=Z.connections.postgres,W=X?.name||"stacks";J={database:Y==="testing"?`${W}_testing`:W,host:X?.host||"127.0.0.1",port:X?.port||5432,username:X?.username||"",password:X?.password||""};break}case"dynamodb":throw Error("[database] DB_CONNECTION=dynamodb is not a SQL driver. Use the entity-style `dynamo.entity(...)` API for DynamoDB access, or set DB_CONNECTION to sqlite/mysql/postgres for SQL workloads.");default:throw Error(`[database] Unknown DB_CONNECTION "${String($)}". Allowed values: sqlite, mysql, postgres.`)}return new o({driver:$,connection:J,verbose:Y!=="production"})}static fromEnv(){let Z=p.DB_CONNECTION||"sqlite",Y;switch(Z){case"sqlite":Y={database:p.DB_DATABASE||"database/stacks.sqlite"};break;case"mysql":case"singlestore":Y={database:p.DB_DATABASE||"stacks",host:p.DB_HOST||"127.0.0.1",port:p.DB_PORT||3306,username:p.DB_USERNAME||"root",password:p.DB_PASSWORD||""};break;case"postgres":Y={database:p.DB_DATABASE||"stacks",host:p.DB_HOST||"127.0.0.1",port:p.DB_PORT||5432,username:p.DB_USERNAME||"",password:p.DB_PASSWORD||""};break;default:Y={database:":memory:"}}return new o({driver:Z,connection:Y,verbose:p.APP_ENV!=="prod"})}}function g6(Z){return new o(Z)}function d6(Z,Y){return new o({driver:"sqlite",connection:{database:Z},...Y})}function m6(Z,Y){return new o({driver:"postgres",connection:Z,...Y})}function s6(Z,Y){return new o({driver:"mysql",connection:Z,...Y})}import{env as S}from"@stacksjs/env";var nZ={sqlite:{database:"database/stacks.sqlite",prefix:""},mysql:{name:"stacks",host:"127.0.0.1",port:3306,username:"root",password:"",prefix:"",charset:"utf8mb4",collation:"utf8mb4_unicode_ci"},singlestore:{name:"stacks",host:"127.0.0.1",port:3306,username:"root",password:"",prefix:"",charset:"utf8mb4",ssl:!1},postgres:{name:"stacks",host:"127.0.0.1",port:5432,username:"postgres",password:"",prefix:"",schema:"public"},browser:{}};function l6(Z,Y){switch(Z){case"sqlite":{let $=Y;if($.database===":memory:")return":memory:";return`sqlite://${$.database}`}case"mysql":{let $=Y,{name:J,host:X="127.0.0.1",port:W=3306,username:H="root",password:G=""}=$;return`mysql://${H}:${G}@${X}:${W}/${J}`}case"singlestore":{let $=Y,{name:J,host:X="127.0.0.1",port:W=3306,username:H="root",password:G=""}=$;return`mysql://${H}:${G}@${X}:${W}/${J}`}case"postgres":{let $=Y,{name:J,host:X="127.0.0.1",port:W=5432,username:H="postgres",password:G=""}=$;return`postgres://${H}:${G}@${X}:${W}/${J}`}default:throw Error(`Unsupported driver: ${Z}`)}}function r6(Z,Y){let $=[];switch(Z){case"sqlite":{if(!Y.database)$.push("SQLite requires a database path");break}case"mysql":{if(!Y.name)$.push("MySQL requires a database name");break}case"singlestore":{if(!Y.name)$.push("SingleStore requires a database name");break}case"postgres":{if(!Y.name)$.push("PostgreSQL requires a database name");break}default:$.push(`Unsupported driver: ${Z}`)}return{valid:$.length===0,errors:$}}function n6(Z,Y){return{...nZ[Z],...Y}}function i6(Z){switch(Z){case"sqlite":return{database:S.DB_DATABASE||"database/stacks.sqlite",prefix:S.DB_PREFIX||""};case"mysql":return{name:S.DB_DATABASE||"stacks",host:S.DB_HOST||"127.0.0.1",port:S.DB_PORT??3306,username:S.DB_USERNAME||"root",password:S.DB_PASSWORD||"",prefix:S.DB_PREFIX||""};case"singlestore":return{name:S.DB_DATABASE||"stacks",host:S.DB_HOST||"127.0.0.1",port:S.DB_PORT??3306,username:S.DB_USERNAME||"root",password:S.DB_PASSWORD||"",prefix:S.DB_PREFIX||"",ssl:S.DB_SSL==="true"||S.DB_SSL==="1"};case"postgres":return{name:S.DB_DATABASE||"stacks",host:S.DB_HOST||"127.0.0.1",port:S.DB_PORT??5432,username:S.DB_USERNAME||"postgres",password:S.DB_PASSWORD||"",prefix:S.DB_PREFIX||"",schema:S.DB_SCHEMA||"public"};default:throw Error(`Unsupported driver: ${Z}`)}}function a6(){if(S.DB_CONNECTION)return S.DB_CONNECTION;if(S.DATABASE_URL?.startsWith("postgres"))return"postgres";if(S.DATABASE_URL?.startsWith("mysql"))return"mysql";return"sqlite"}F();function PY(Z,...Y){let $=[],J=[];for(let X=0;X<Z.length;X++)if($.push(Z[X]),X<Y.length)if(Y[X]&&typeof Y[X]==="object"&&"raw"in Y[X])$.push(Y[X].raw);else $.push("?"),J.push(Y[X]);return{sql:$.join(""),parameters:J}}PY.raw=function(Y){return{raw:Y}};PY.ref=function(Y){return{raw:Y}};F();import{existsSync as KZ,mkdirSync as D7,readdirSync as oY,readFileSync as O4,unlinkSync as x7,writeFileSync as A4}from"fs";import{dirname as q7,join as e}from"path";import{log as m}from"@stacksjs/logging";import{err as tY,handleError as eY,ok as OY}from"@stacksjs/error-handling";import{path as hY}from"@stacksjs/path";import{createQueryBuilder as B4,executeMigration as T7,generateMigration as jZ,resetConnection as aY,resetDatabase as P7,setConfig as V4}from"@stacksjs/query-builder";import{Buffer as G7}from"buffer";import{createHash as z7}from"crypto";import{closeSync as U7,openSync as Q7,statSync as _7,unlinkSync as z4,writeFileSync as O7}from"fs";import A7 from"process";import{userDatabasePath as B7}from"@stacksjs/path";var V7=30000,LZ=100,EZ=2000,L7=60000,VZ="stacks_migrations";async function U4(Z,Y,$={}){let J=$.timeoutMs??V7;if(Z!=="sqlite"&&Z!=="postgres"&&Z!=="mysql")throw Error(`[migration-lock] unknown dialect: ${String(Z)}`);if(Z==="sqlite")return R7($.sqliteLockPath,J);if(!Y)throw Error(`[migration-lock] ${Z} requires a database connection to acquire the lock`);if(Z==="postgres")return I7(Y,J);return K7(Y,J)}function E7(){let Z=z7("sha256").update(VZ).digest(),Y=Z.readInt32BE(0),$=Z.readInt32BE(4);return{key1:Y,key2:$}}async function I7(Z,Y){let{key1:$,key2:J}=E7(),X=Date.now(),W=LZ;while(!0){let H=await Z.unsafe(`SELECT pg_try_advisory_lock(${$}, ${J}) AS acquired`);if(M7(H,"acquired"))return{release:async()=>{try{await Z.unsafe(`SELECT pg_advisory_unlock(${$}, ${J})`)}catch{}}};if(Date.now()-X>=Y)throw Error("[migration-lock] another migration is in progress \u2014 could not acquire postgres advisory lock within timeout");await IZ(W),W=Math.min(W*2,EZ)}}async function K7(Z,Y){let $=Date.now(),J=LZ;while(!0){let X=await Z.unsafe(`SELECT GET_LOCK('${VZ}', 0) AS acquired`);if(F7(X,"acquired")===1)return{release:async()=>{try{await Z.unsafe(`SELECT RELEASE_LOCK('${VZ}')`)}catch{}}};if(Date.now()-$>=Y)throw Error("[migration-lock] another migration is in progress \u2014 could not acquire MySQL named lock within timeout");await IZ(J),J=Math.min(J*2,EZ)}}function j7(){return B7(".migration.lock")}async function R7(Z,Y){let $=Z??j7(),J=Date.now(),X=LZ;while(!0){if(w7($)){let W=!1;return{release:async()=>{if(W)return;W=!0;try{z4($)}catch{}}}}if(S7($),Date.now()-J>=Y)throw Error(`[migration-lock] another migration is in progress \u2014 lock file ${$} held within timeout`);await IZ(X),X=Math.min(X*2,EZ)}}function w7(Z){try{let Y=Q7(Z,"wx");try{let $=JSON.stringify({pid:A7.pid,startedAt:new Date().toISOString()});O7(Y,G7.from($,"utf8"))}finally{U7(Y)}return!0}catch(Y){if(Y.code==="EEXIST")return!1;throw Y}}function S7(Z){try{let Y=_7(Z);if(Date.now()-Y.mtimeMs>L7)try{z4(Z)}catch{}}catch{}}function IZ(Z){let Y=Z*(1+Math.random()*0.25);return new Promise(($)=>setTimeout($,Y))}function M7(Z,Y){let $=Q4(Z);if(!$)return!1;let J=$[Y];return J===!0||J===1||J==="1"||J==="t"}function F7(Z,Y){let $=Q4(Z);if(!$)return null;let J=$[Y];if(typeof J==="number")return J;if(typeof J==="string"&&/^-?\d+$/.test(J))return Number.parseInt(J,10);return null}function Q4(Z){if(!Z)return null;if(Array.isArray(Z))return Z[0];if(typeof Z==="object"&&"rows"in Z&&Array.isArray(Z.rows))return Z.rows[0];return null}iY();import{env as YZ}from"@stacksjs/env";var K={info:(...Z)=>typeof m?.info==="function"?m.info(...Z):console.log(...Z),success:(Z)=>typeof m?.success==="function"?m.success(Z):console.log(Z),warn:(Z)=>typeof m?.warn==="function"?m.warn(Z):console.warn(Z),error:(...Z)=>typeof m?.error==="function"?m.error(...Z):console.error(...Z),debug:(...Z)=>typeof m?.debug==="function"?m.debug(...Z):console.debug(...Z)},k7=YZ.DB_CONNECTION||"sqlite",N7=t("sqlite",YZ),kY=t("mysql",YZ),NY=t("postgres",YZ),yY={default:k7,connections:{sqlite:{database:N7.database,prefix:""},mysql:{name:kY.database,host:kY.host,username:kY.username,password:kY.password,port:kY.port,prefix:""},postgres:{name:NY.database,host:NY.host,username:NY.username,password:NY.password,port:NY.port,prefix:""}}};function L4(){return yY.default||"sqlite"}function YY(){let Z=L4();if(Z==="sqlite"||Z==="mysql"||Z==="postgres")return Z;if(Z==="singlestore")return"mysql";if(Z==="dynamodb")throw Error("[database] DB_CONNECTION=dynamodb is not compatible with the SQL migration runner. "+"DynamoDB has no schema-migration concept \u2014 use the entity-style `dynamo.entity(...)` "+"API from @stacksjs/database directly. To run SQL migrations, set DB_CONNECTION to one of: sqlite, mysql, postgres.");throw Error(`[database] Unknown DB_CONNECTION "${Z}". Allowed values: sqlite, mysql, postgres, dynamodb.`)}function RZ(){return L4()==="singlestore"?"singlestore":YY()}function vY(){let Z=YY(),Y=yY.connections[Z];V4({dialect:Z,verbose:!1,database:{database:Y?.name||Y?.database||"stacks",host:Y?.host||"localhost",port:Y?.port||(Z==="postgres"?5432:Z==="mysql"?3306:0),username:Y?.username||"",password:Y?.password||""}}),aY()}function wZ(){let Z=hY.userModelsPath();return{modelsDir:Z,skip:!KZ(Z)}}function y7(){let Z=e(process.cwd(),"database","migrations"),Y;try{Y=oY(Z).filter((L)=>L.endsWith(".sql"))}catch{return}let $=[],J=(L,B)=>{K.info(`Skipping migration on SQLite (${B}): ${L}`),$.push(L)},X=(L,B,E)=>{K.info(`Dropping no-op migration (${E}): ${L}`);try{x7(B)}catch{}$.push(L)},W=[],H=/^\s*ALTER\s+TABLE\s+.+\s+ADD\s+CONSTRAINT\s+/i,G=/^\s*CREATE\s+TYPE\s+/i,z=/^\s*CREATE\s+UNIQUE\s+INDEX\s+(?:IF\s+NOT\s+EXISTS\s+)?["'`]?(\w+)["'`]?/i,Q=/^\s*ALTER\s+TABLE\s+["']?(\w+)["']?\s+DROP\s+COLUMN\s+["']?(\w+)["']?\s*$/i,_=/^\s*CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?["']?(\w+)["']?/i,U=new Map;for(let L of Y){let B=L.match(/^\d+-create-(\w+)-table\.sql$/);if(!B||!B[1])continue;let E=B[1],V=U.get(E);if(!V||L<V)U.set(E,L)}let I=e(process.cwd(),yY.connections.sqlite.database||"stacks.db"),O=null;if(KZ(I))try{let{Database:L}=b("bun:sqlite");O=new L(I,{readonly:!0})}catch{}for(let L of Y){K.debug(`[migration] Running: ${L}`);let B=e(Z,L),V=O4(B,"utf-8").split(";").map((w)=>w.trim()).filter((w)=>w.length>0&&!w.startsWith("--"));if(V.length===0)continue;let j=V[0],R=j?j.match(_):null;if(R&&R[1]){let w=R[1],g=U.get(w);if(g&&g!==L){X(L,B,`duplicate create-table for "${w}" (kept ${g})`);continue}}if(V.every((w)=>H.test(w))){J(L,"SQLite does not support ALTER TABLE ADD CONSTRAINT");continue}if(V.every((w)=>G.test(w))){J(L,"SQLite does not support CREATE TYPE (enum types)");continue}let D=V.map((w)=>w.match(z)?.[1]).filter((w)=>Boolean(w));if(O&&D.length===V.length){let w=O.prepare("SELECT name FROM sqlite_master WHERE type = 'index' AND name = ?");if(D.filter((zY)=>!w.get(zY)).length>0)K.info(`Re-queueing unique-index migration (index missing from database): ${L}`),W.push(L);continue}if(V.some((w)=>Q.test(w))){let w=!1,g=[];for(let zY of V){let DY=zY.match(Q);if(DY&&DY[1]&&DY[2]){let nY=DY[1],xY=DY[2];if(!O){K.info(`Skipping DROP COLUMN "${xY}" \u2014 no database exists yet: ${L}`),w=!0;continue}try{let h6=nY.replace(/[^a-zA-Z0-9_]/g,""),lZ=O.prepare(`PRAGMA table_info("${h6}")`).all();if(lZ.length===0){K.info(`Skipping DROP COLUMN "${xY}" \u2014 table "${nY}" does not exist yet: ${L}`),w=!0;continue}if(!lZ.some((v6)=>v6.name===xY)){K.info(`Skipping DROP COLUMN "${xY}" from "${nY}" \u2014 column does not exist: ${L}`),w=!0;continue}}catch{K.info(`Skipping DROP COLUMN "${xY}" \u2014 table "${nY}" not found: ${L}`),w=!0;continue}}g.push(zY)}if(w){if(g.length===0)X(L,B,"columns already absent from table");else A4(B,`${g.join(`;
|
|
3
3
|
`)};
|
|
4
|
-
`);continue}}}if(O)try{O.close()}catch{}if($.length>0||W.length>0)try{let L=
|
|
4
|
+
`);continue}}}if(O)try{O.close()}catch{}if($.length>0||W.length>0)try{let L=e(process.cwd(),yY.connections.sqlite.database||"stacks.db");D7(q7(L),{recursive:!0});let{Database:B}=b("bun:sqlite"),E=new B(L);try{E.exec(`CREATE TABLE IF NOT EXISTS migrations (
|
|
5
5
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
6
6
|
migration TEXT NOT NULL UNIQUE,
|
|
7
7
|
executed_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
8
|
-
)`);let
|
|
9
|
-
${
|
|
8
|
+
)`);let V=E.prepare("INSERT OR IGNORE INTO migrations (migration) VALUES (?)");for(let R of $)V.run(R);let j=E.prepare("DELETE FROM migrations WHERE migration = ?");for(let R of W)j.run(R)}finally{E.close()}}catch(L){K.debug(`[migration] Could not record dropped migrations as executed: ${L}`)}}async function h7(){let Z=YY();if(Z==="sqlite")return;let Y=yY.connections[Z],$=(Y?.name||"stacks").replace(/['"]/g,""),J=Y?.host||"localhost",X=Y?.port||(Z==="postgres"?5432:3306),W=Y?.username||(Z==="postgres"?process.env.USER||"postgres":"root"),H=Y?.password||"",G=Z==="postgres"?"postgres":"mysql";try{V4({dialect:Z,database:{database:G,host:J,port:X,username:W,password:H}}),aY();let z=B4();if(Z==="postgres")try{await z.unsafe(`CREATE DATABASE "${$}"`),K.info(`Created database "${$}"`)}catch(Q){if(Q?.message?.includes("already exists")||Q?.errno==="42P04")K.info(`Database "${$}" already exists`);else throw Q}else if(Z==="mysql")try{await z.unsafe(`CREATE DATABASE IF NOT EXISTS \`${$}\``),K.info(`Ensured database "${$}" exists`)}catch(Q){if(Q?.message?.includes("database exists"))K.info(`Database "${$}" already exists`);else throw Q}aY()}catch(z){K.warn(`Could not auto-create database "${$}": ${z?.message||z}`),K.info("If the database already exists, this warning can be ignored."),aY()}}async function v7(){let Z=[];try{let{FEATURE_NAMES:Y,migrationFeature:$}=await import("@stacksjs/buddy"),{feature:J}=await import("@stacksjs/config"),X=await import("fs/promises"),W=hY.projectPath("database/migrations");if(!KZ(W))return Z;let H=new Set(Y.filter((z)=>!J(z)));if(H.size===0)return Z;let G=oY(W).filter((z)=>z.endsWith(".sql"));for(let z of G){let Q=$(z);if(!Q||!H.has(Q))continue;let _=e(W,z),U=`${_}.disabled`;await X.rename(_,U),Z.push({original:_,hidden:U,feature:Q})}if(Z.length>0){let z=Object.entries(Z.reduce((Q,_)=>{return Q[_.feature]=(Q[_.feature]??0)+1,Q},{})).map(([Q,_])=>`${Q}: ${_}`).join(", ");K.info(`[migration] Skipping ${Z.length} migration(s) for disabled features (${z}). Run \`./buddy <feature>:install\` to enable.`)}}catch{}return Z}async function f7(Z){let Y=await import("fs/promises");for(let{original:$,hidden:J}of Z)try{await Y.rename(J,$)}catch{}}async function _4(){try{let Z=await A.selectFrom("migrations").select(($)=>$.fn.count("id").as("n")).executeTakeFirst();if(!Z)return 0;let Y=Number(Z.n??Z.N??0);return Number.isFinite(Y)?Y:0}catch{return 0}}async function b7(Z){try{let Y=await import("fs/promises"),$=hY.projectPath(".stacks");await Y.mkdir($,{recursive:!0});let J=`${$}/last-migrate-result.json`,X=JSON.stringify({appliedCount:Z,completedAt:new Date().toISOString()});await Y.writeFile(J,X,"utf8")}catch{}}async function G5(){let Z=Date.now(),Y=await v7(),$=null;try{K.debug("Migrating database..."),await h7(),vY();let J=YY(),X=J==="sqlite"?null:B4();if($=await U4(J,X),J==="sqlite")y7();let W=hY.userModelsPath(),H=await _4();K.debug(`[migration] Running migrations from: ${W}`),await T7(W);let G=await _4(),z=Math.max(0,G-H);return await b7(z),K.debug(`Database migration completed in ${Date.now()-Z}ms (applied ${z}).`),OY(z===0?"Nothing to migrate.":`Applied ${z} migration${z===1?"":"s"}.`)}catch(J){let X=J instanceof Error?J.message:String(J);return K.error(`[migration] Failed after ${Date.now()-Z}ms: ${X}`),K.info("[migration] Run `./buddy migrate:fresh` to drop and recreate the schema if state is partial."),tY(eY("Migration failed",J))}finally{if($)try{await $.release()}catch{}await f7(Y)}}var p7=["oauth_refresh_tokens","oauth_access_tokens","oauth_clients","passkeys","failed_jobs","jobs","notifications","password_reset_tokens"];async function z5(){try{vY();let Z=hY.userModelsPath(),Y=YY();return await C7(Y),await P7(Z,{dialect:Y}),OY("All tables dropped successfully!")}catch(Z){return tY(eY("Database reset failed",Z))}}async function C7(Z){if(Z==="mysql")try{await A.unsafe("SET FOREIGN_KEY_CHECKS = 0").execute()}catch(Y){K.warn(`Could not disable foreign key checks: ${Y instanceof Error?Y.message:String(Y)}`)}if(Z==="sqlite")try{await A.unsafe("PRAGMA foreign_keys = OFF").execute()}catch(Y){K.warn(`Could not disable foreign key checks: ${Y instanceof Error?Y.message:String(Y)}`)}for(let Y of p7)try{let $;if(Z==="postgres")$=`DROP TABLE IF EXISTS "${Y}" CASCADE`;else if(Z==="mysql")$=`DROP TABLE IF EXISTS \`${Y}\``;else $=`DROP TABLE IF EXISTS "${Y}"`;K.info(`Dropping framework table: ${Y}`),await A.unsafe($).execute(),K.info(`Dropped framework table: ${Y}`)}catch($){K.warn(`Could not drop table ${Y}: ${$ instanceof Error?$.message:String($)}`)}if(Z==="mysql")try{await A.unsafe("SET FOREIGN_KEY_CHECKS = 1").execute()}catch(Y){K.warn(`Could not re-enable foreign key checks: ${Y instanceof Error?Y.message:String(Y)}`)}if(Z==="sqlite")try{await A.unsafe("PRAGMA foreign_keys = ON").execute()}catch(Y){K.warn(`Could not re-enable foreign key checks: ${Y instanceof Error?Y.message:String(Y)}`)}}function E4(Z){let Y=Z.applyRenames??(process.env.STACKS_MIGRATE_NO_RENAME==="1"?!1:void 0),$=Z.fromDb??(process.env.STACKS_MIGRATE_FROM_DB==="1"?!0:void 0);return{applyRenames:Y,fromDb:$}}async function U5(Z={}){try{vY();let Y=YY(),{modelsDir:$,skip:J}=wZ();if(J)return[];let{applyRenames:X,fromDb:W}=E4(Z);return(await jZ($,{dialect:RZ(),dryRun:!0,applyRenames:X,fromDb:W})).operations??[]}catch(Y){return K.debug(`[migration] preview failed: ${Y instanceof Error?Y.message:String(Y)}`),[]}}async function Q5(Z={}){try{K.debug("Generating migrations..."),vY();let Y=YY(),{modelsDir:$,skip:J}=wZ();if(J)return K.debug("No app/Models directory found; using committed framework migrations"),OY("Migrations generated");let{applyRenames:X,fromDb:W}=E4(Z);K.debug(`[migration] Generating migrations for dialect: ${Y}, models: ${$}`);let H=await jZ($,{dialect:RZ(),dryRun:!0,applyRenames:X,fromDb:W});if(H.hasChanges){let G=c7(H.sqlStatements??[]);if(G>0)K.success(`Generated ${G} migration file${G===1?"":"s"}`);else K.debug("Migration generation produced no new files (already up to date)")}else K.debug("No changes detected");return OY("Migrations generated")}catch(Y){return tY(eY("Migration generation failed",Y))}}function c7(Z){if(!Z?.length)return 0;let Y=e(process.cwd(),"database","migrations");try{b("fs").mkdirSync(Y,{recursive:!0})}catch{}let $="";try{for(let z of oY(Y).filter((Q)=>Q.endsWith(".sql")))$+=`
|
|
9
|
+
${O4(e(Y,z),"utf8")}`}catch{}let J=(z)=>z.replace(/\s+/g," ").trim(),X=J($),W=u7(Z),H=0,G=g7(Y);for(let z of W){let Q=z.statements.filter((O)=>!X.includes(J(O)));if(Q.length===0)continue;let _=`${String(G).padStart(10,"0")}-${z.label}.sql`,U=e(Y,_),I=`${Q.map((O)=>O.trim().replace(/;\s*$/,"")).join(`;
|
|
10
10
|
`)};
|
|
11
|
-
`;
|
|
12
|
-
`).slice(1).find((X)=>!X.includes("query-logger.ts")),J={};if($){let X=$.match(/at (.+?) \(/),W=$.match(/\((.+?):(\d+):(\d+)\)/);if(X&&X[1]){let H=X[1].split(".");J={model:H.length>1?H[0]:void 0,method:H.length>1?H[1]:H[0]}}if(W&&W[1]&&W[2])J={...J,file:W[1],line:Number.parseInt(W[2],10)}}return{trace:
|
|
13
|
-
UPDATE ${T(Y)} SET ${T($)} = ${
|
|
11
|
+
`;A4(U,I),K.debug(`[migration] Wrote ${_} (${Q.length} stmt${Q.length===1?"":"s"})`),H+=1,G+=1}return H}function u7(Z){let Y=new Map,$=(J,X)=>{let W=Y.get(J)??[];W.push(X),Y.set(J,W)};for(let J of Z){let X=J.trim();if(!X)continue;let W=X.match(/^\s*CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?["`]?(\w+)["`]?/i);if(W){$(`create-${W[1]}-table`,X);continue}let H=X.match(/^\s*ALTER\s+TABLE\s+["`]?(\w+)["`]?\s+(?:ADD\s+COLUMN\s+["`]?(\w+)["`]?|DROP\s+COLUMN\s+["`]?(\w+)["`]?|ADD\s+CONSTRAINT)/i);if(H){$(`alter-${H[1]}-${H[2]||H[3]||"constraint"}`,X);continue}let G=X.match(/^\s*CREATE\s+(?:UNIQUE\s+)?INDEX\s+(?:IF\s+NOT\s+EXISTS\s+)?["`]?(\w+)["`]?\s+ON\s+["`]?(\w+)["`]?/i);if(G){$(`create-${G[1]}-index-in-${G[2]}`,X);continue}let z=X.match(/^\s*DROP\s+TABLE\s+(?:IF\s+EXISTS\s+)?["`]?(\w+)["`]?/i);if(z){$(`drop-${z[1]}-table`,X);continue}$("auto-misc",X)}return[...Y.entries()].map(([J,X])=>({label:J,statements:X}))}function g7(Z){let Y=0;try{for(let $ of oY(Z)){let J=$.match(/^(\d+)-/);if(J?.[1])Y=Math.max(Y,Number.parseInt(J[1],10))}}catch{}return Y+1}async function _5(){try{K.info("Generating fresh migrations..."),vY();let Z=YY(),{modelsDir:Y,skip:$}=wZ();if($)return K.info("No app/Models directory found; using committed framework migrations"),OY("Migrations generated");return await jZ(Y,{dialect:RZ(),full:!0,dryRun:!0}),K.success("Migrations generated"),OY("Migrations generated")}catch(Z){return tY(eY("Fresh migration generation failed",Z))}}import{memoryUsage as s7}from"process";import{config as ZY}from"@stacksjs/config";import{log as pY}from"@stacksjs/logging";function SZ(Z){let Y={normalized:"",type:"OTHER",tables:[]};if(!Z)return Y;try{let $=Z.trim().toUpperCase();if($.startsWith("SELECT"))Y.type="SELECT";else if($.startsWith("INSERT"))Y.type="INSERT";else if($.startsWith("UPDATE"))Y.type="UPDATE";else if($.startsWith("DELETE"))Y.type="DELETE";return Y.tables=d7(Z,Y.type),Y.normalized=m7(Z),Y}catch{return{normalized:Z,type:"OTHER",tables:[]}}}function fY(Z,Y="i"){return new RegExp(`${Z}\\s+(?:"([^"]+)"|\`([^\`]+)\`|\\[([^\\]]+)\\]|([\\w.]+))`,Y)}function bY(Z){if(!Z)return null;let Y=Z[1]??Z[2]??Z[3]??Z[4];if(!Y)return null;return Y.split(".").pop()??null}function d7(Z,Y){let $=[];try{switch(Y){case"SELECT":{let J=Z.match(fY("from")),X=bY(J);if(X)$.push(X);let W=fY("join","gi");for(let H of Z.matchAll(W)){let G=bY(H);if(G)$.push(G)}break}case"INSERT":{let J=Z.match(fY("into")),X=bY(J);if(X)$.push(X);break}case"UPDATE":{let J=Z.match(fY("update")),X=bY(J);if(X)$.push(X);break}case"DELETE":{let J=Z.match(fY("from")),X=bY(J);if(X)$.push(X);break}}}catch{}return[...new Set($)].filter(Boolean)}function m7(Z){try{let Y=Z;return Y=Y.replace(/(?<![a-zA-Z_])\b\d+\b(?![a-zA-Z_])/g,"?"),Y=Y.replace(/'([^']|'')*'/g,"?"),Y=Y.replace(/"([^"]|"")*"/g,"?"),Y=Y.replace(/\btrue\b/gi,"?"),Y=Y.replace(/\bfalse\b/gi,"?"),Y=Y.replace(/\bnull\b/gi,"?"),Y=Y.replace(/\s+/g," ").trim(),Y}catch{return Z}}F();var I4=()=>{};function l7(Z){I4=Z}var MZ=!1;async function r7(Z){if(MZ)return;try{let{query:Y,durationMs:$,error:J,bindings:X}=n7(Z);try{I4(Y,$,ZY.database?.default||"unknown")}catch{}if(!ZY.database?.queryLogging?.enabled)return;let W=i7($,J),H=await a7(Y,$,W,J,X);if(ZY.database?.queryLogging?.analysis?.enabled&&(W==="slow"||ZY.database.queryLogging.analysis.analyzeAll))await Y8(H);MZ=!0;try{await X8(H)}finally{MZ=!1}if(W!=="completed")pY[W==="failed"?"error":"warn"](`Query ${W}:`,{query:H.query,duration:H.duration,connection:H.connection,...J&&{error:J}})}catch(Y){pY.error("Failed to log query:",Y)}}function n7(Z){let Y=Z.query?.sql||"",$=Z.queryDurationMillis||0,J=Z.error,X;if(Z.query?.parameters)try{X=JSON.stringify(Z.query.parameters)}catch{X="[]"}return{query:Y,durationMs:$,error:J,bindings:X}}function i7(Z,Y){let $=ZY.database?.queryLogging?.slowThreshold||100;if(Y)return"failed";if(Z>$)return"slow";return"completed"}async function a7(Z,Y,$,J,X){let W=ZY.database.default||"unknown",H=SZ(Z).normalized||Z,{trace:G,caller:z}=e7();return{query:Z,normalized_query:H,duration:Y,connection:W,status:$,error:J?String(J):void 0,executed_at:new Date().toISOString(),bindings:X,trace:G,...z,memory_usage:s7().heapUsed/1024/1024}}var o7=[/\b(?:sk|pk|rk|api|secret|token|bearer|password|pwd|key)[_-]?[A-Za-z0-9]{12,}/gi,/\bsk_(?:live|test)_[A-Za-z0-9]{20,}/g,/\bAKIA[0-9A-Z]{16}/g,/\b[A-Za-z0-9_-]{40,}\b(?=\s|$|['"])/g];function t7(Z){let Y=Z;for(let $ of o7)Y=Y.replace($,"<redacted>");return Y}function e7(){try{let Z=Error("Stack trace capture").stack||"",$=Z.split(`
|
|
12
|
+
`).slice(1).find((X)=>!X.includes("query-logger.ts")),J={};if($){let X=$.match(/at (.+?) \(/),W=$.match(/\((.+?):(\d+):(\d+)\)/);if(X&&X[1]){let H=X[1].split(".");J={model:H.length>1?H[0]:void 0,method:H.length>1?H[1]:H[0]}}if(W&&W[1]&&W[2])J={...J,file:W[1],line:Number.parseInt(W[2],10)}}return{trace:t7(Z),caller:J}}catch{return{trace:"",caller:{}}}}async function Y8(Z){try{let{tables:Y,type:$}=SZ(Z.query);if(Z.affected_tables=JSON.stringify(Y||[]),$==="SELECT"&&ZY.database?.queryLogging?.analysis?.explainPlan){let X=await $8(Z.query);if(X){if(Z.explain_plan=X.plan,Z.indexes_used=JSON.stringify(X.indexesUsed||[]),Z.missing_indexes=JSON.stringify(X.missingIndexes||[]),ZY.database?.queryLogging?.analysis?.suggestions)Z.optimization_suggestions=JSON.stringify(J8(X,Z))}}let J=[$];if(Y&&Y.length>0)J.push(...Y.map((X)=>`table:${X}`));Z.tags=JSON.stringify(J)}catch(Y){pY.debug("Error during query analysis:",Y)}}var Z8=new Set(["sqlite","mysql","postgres"]);async function $8(Z){try{let Y=(await import("@stacksjs/config")).config?.database?.default,$=typeof Y==="string"?Y:"sqlite";if(!Z8.has($))return null;let J;if($==="mysql")J=`EXPLAIN FORMAT=JSON ${Z}`;else if($==="postgres")J=`EXPLAIN (FORMAT JSON) ${Z}`;else J=`EXPLAIN QUERY PLAN ${Z}`;let X=await A.unsafe?.(J);if(!X)return null;let W=Array.isArray(X)?X:X.rows??[],H=JSON.stringify(W),G=[],z=[];if($==="sqlite")for(let Q of W){let _=Q?.detail||"",U=_.match(/USING (?:COVERING )?INDEX (\w+)/i);if(U&&U[1])G.push(U[1]);else{let I=_.match(/^SCAN\s+(\w+)/i);if(I&&I[1])z.push(I[1])}}else if($==="mysql"){let Q=H;for(let _ of Q.matchAll(/"key"\s*:\s*"([^"]+)"/g))if(_[1])G.push(_[1]);for(let _ of Q.matchAll(/"table_name"\s*:\s*"([^"]+)"[^}]*"access_type"\s*:\s*"ALL"/g))if(_[1])z.push(_[1])}else if($==="postgres"){let Q=H;for(let _ of Q.matchAll(/"Index Name"\s*:\s*"([^"]+)"/g))if(_[1])G.push(_[1]);for(let _ of Q.matchAll(/"Node Type"\s*:\s*"Seq Scan"[^}]*"Relation Name"\s*:\s*"([^"]+)"/g))if(_[1])z.push(_[1])}return{plan:H.length>4000?`${H.slice(0,4000)}\u2026`:H,indexesUsed:Array.from(new Set(G)),missingIndexes:Array.from(new Set(z))}}catch(Y){return pY.debug("[query-logger] EXPLAIN failed (non-fatal):",Y),null}}function J8(Z,Y){let $=[];if(Z.missingIndexes&&Z.missingIndexes.length>0)$.push(`Consider adding index on ${Z.missingIndexes.join(", ")}`);if(Y.status==="slow"){if($.push("Consider optimizing this query to reduce execution time"),Y.query.toLowerCase().includes("select *"))$.push("Specify only needed columns instead of using SELECT *");if(!Y.query.toLowerCase().includes("limit"))$.push("Consider adding LIMIT clause to reduce result set size")}return $}async function X8(Z){try{await A.insertInto("query_logs").values(Z).execute()}catch(Y){pY.error("Failed to store query log:",Y)}}import{log as $Y}from"@stacksjs/logging";import{path as W8}from"@stacksjs/path";import{fs as K4}from"@stacksjs/storage";class j4{dependencies;async call(Z){await new Z().run()}}function H8(Z){let Y=new Set(Z.map((G)=>G.name)),$=new Map;for(let G of Z){let z=new Set;for(let Q of G.dependencies??[]){if(Q===G.name)continue;if(!Y.has(Q)){$Y.warn(`[seeder] ${G.name} depends on '${Q}' but no seeder by that name was discovered \u2014 ignoring`);continue}z.add(Q)}$.set(G.name,z)}let J=new Map,X=new Map;for(let G of Z)J.set(G.name,$.get(G.name).size),X.set(G.name,new Set);for(let G of Z)for(let z of $.get(G.name))X.get(z).add(G.name);let W=Z.filter((G)=>J.get(G.name)===0).map((G)=>G.name).sort(),H=[];while(W.length>0){let G=W.shift();H.push(G);let z=[];for(let Q of X.get(G)){let _=(J.get(Q)??0)-1;if(J.set(Q,_),_===0)z.push(Q)}if(z.length>0)W.push(...z),W.sort()}if(H.length!==Z.length){let G=Z.map((z)=>z.name).filter((z)=>!H.includes(z));throw Error(`[seeder] Cycle in seeder \`dependencies\` among: ${G.join(", ")}`)}return H}async function G8(Z={}){try{let{injectGlobalAutoImports:Q}=await import("@stacksjs/server");await Q()}catch{}let Y=Z.dir??W8.projectPath("database/seeders"),$=[],J=[];if(!K4.existsSync(Y))return $Y.info(`[seeder] No class seeders directory at ${Y}`),{ran:$,skipped:J};let X=K4.readdirSync(Y).filter((Q)=>Q.endsWith(".ts")&&!Q.startsWith("_")).sort(),W=[];for(let Q of X){let _=Q.replace(/\.ts$/,"");try{let U=await import(`${Y}/${Q}`),I=U.default??U[_];if(!I){$Y.warn(`[seeder] ${Q} has no default export`),J.push(_);continue}let O=new I;if(typeof O.run!=="function"){$Y.warn(`[seeder] ${_} does not implement run()`),J.push(_);continue}W.push({className:_,inst:O})}catch(U){$Y.error(`[seeder] ${_} failed to load:`,U),J.push(_)}}let H=W.some((Q)=>(Q.inst.dependencies?.length??0)>0),G;if(H)try{G=H8(W.map((Q)=>({name:Q.className,dependencies:Q.inst.dependencies})))}catch(Q){return $Y.error(Q instanceof Error?Q.message:String(Q)),{ran:$,skipped:[...J,...W.map((_)=>_.className)]}}else G=W.map((Q)=>Q.className);let z=new Map(W.map((Q)=>[Q.className,Q.inst]));for(let Q of G){if(Z.class&&Q!==Z.class){J.push(Q);continue}let _=z.get(Q);try{$Y.info(`[seeder] Running ${Q}\u2026`),await _.run(),$.push(Q)}catch(U){$Y.error(`[seeder] ${Q} failed:`,U),J.push(Q)}}return{ran:$,skipped:J}}async function z8(Z,Y,$,J){let{type:X,defaultValue:W,notNull:H=!1,batchSize:G=1000}=J,z=Z,Q=W===void 0?"":` DEFAULT ${S4(W)}`;if(await AY(z,`ALTER TABLE ${T(Y)} ADD COLUMN ${T($)} ${X}${Q}`),W!==void 0)await w4(Z,Y,$,W,G);if(H)await AY(z,`ALTER TABLE ${T(Y)} ALTER COLUMN ${T($)} SET NOT NULL`)}async function AY(Z,Y){if(typeof Z.unsafe==="function")return await Z.unsafe(Y)??{};return await PY`${PY.raw(Y)}`.execute(Z),{}}async function w4(Z,Y,$,J,X=1000){let W=Z,H=0,G=0;do{let z=`
|
|
13
|
+
UPDATE ${T(Y)} SET ${T($)} = ${S4(J)}
|
|
14
14
|
WHERE ${T($)} IS NULL
|
|
15
|
-
AND ${
|
|
16
|
-
SELECT ${
|
|
15
|
+
AND ${R4(W)} IN (
|
|
16
|
+
SELECT ${R4(W)} FROM ${T(Y)}
|
|
17
17
|
WHERE ${T($)} IS NULL
|
|
18
18
|
LIMIT ${X}
|
|
19
19
|
)
|
|
20
|
-
`,Q=await
|
|
20
|
+
`,Q=await AY(W,z);H=Q.numAffectedRows!=null?Number(Q.numAffectedRows):0,G+=H}while(H>0)}async function U8(Z,Y,$,J,X){let W=Z;if(X.atomic){await AY(W,`ALTER TABLE ${T(Y)} RENAME COLUMN ${T($)} TO ${T(J)}`);return}await AY(W,`ALTER TABLE ${T(Y)} ADD COLUMN ${T(J)} ${X.type}`),await AY(W,`UPDATE ${T(Y)} SET ${T(J)} = ${T($)}`)}function T(Z){if(!/^[a-z_][a-z0-9_]*$/i.test(Z))throw Error(`Refusing to quote unsafe identifier: ${JSON.stringify(Z)}`);return`"${Z}"`}function S4(Z){if(Z===null)return"NULL";if(typeof Z==="number")return String(Z);if(typeof Z==="boolean")return Z?"TRUE":"FALSE";return`'${String(Z).replace(/'/g,"''")}'`}function R4(Z){return"id"}F();import{log as M}from"@stacksjs/logging";import{faker as FZ}from"@stacksjs/faker";import{path as cY}from"@stacksjs/path";import{hashMake as Q8}from"@stacksjs/security";import{fs as M4}from"@stacksjs/storage";function DZ(Z){return cY.frameworkPath(`defaults/app/Models/${Z||""}`)}var _8=Object.freeze(["OauthClient","OauthAccessToken","OauthRefreshToken","PersonalAccessToken"]);function O8(Z){return _8.includes(Z)}function xZ(Z){return Z.replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/(\d)([A-Za-z])/g,"$1_$2").toLowerCase()}async function CY(Z,Y=!1){let $=[];if(!M4.existsSync(Z))return $;let J=M4.readdirSync(Z,{withFileTypes:!0});for(let X of J){let W=cY.join(Z,X.name);if(X.isDirectory()&&Y){let H=await CY(W,!0);$.push(...H);continue}if(!X.name.endsWith(".ts")||X.name.startsWith("index")||X.name.startsWith("_"))continue;try{let H=await import(W),G=H.default||H;if(!G)continue;let z=G.traits?.useSeeder??G.traits?.seedable;if(!z)continue;let Q=10,_=[];if(typeof z==="object"&&"count"in z){let O=z;Q=O.count,_=O.fixtures??[]}let U=G.name||X.name.replace(".ts",""),I=G.table||xZ(U)+"s";$.push({name:U,table:I,count:Math.max(Q,_.length),fixtures:_,attributes:G.attributes||{},model:G,filePath:W})}catch(H){M.error(`Failed to load model ${X.name}:`,H)}}return $}async function F4(Z,Y=!1,$=!1){let J=DZ(),X=await CY(Z,!1);if(X.length>0&&!$)return X;let W=await CY(J,!0),H=new Map;for(let G of W)H.set(G.name,G);for(let G of X){if(H.has(G.name)&&Y)M.info(` User model "${G.name}" overrides default`);H.set(G.name,G)}return Array.from(H.values())}function A8(Z,Y){let $=Z.toLowerCase();if($==="password"||$.endsWith("_password")||$.endsWith("password"))return!0;if(Y.hidden===!0&&$.includes("pass"))return!0;return!1}async function B8(Z,Y,$=!1){let J={};for(let[X,W]of Object.entries(Z)){let H=xZ(X),G;if(W.factory&&typeof W.factory==="function")try{G=W.factory(FZ)}catch(z){let Q=z instanceof Error?z.message:String(z);if($)M.warn(` Factory failed for ${Y}.${X}: ${Q}`);if(W.default!==void 0)G=W.default;else G=V8(X)}else if(W.default!==void 0)G=W.default;else continue;if(A8(X,W)&&typeof G==="string")try{G=await Q8(G,{algorithm:"bcrypt"})}catch(z){let Q=z instanceof Error?z.message:String(z);if($)M.warn(` Failed to hash password for ${Y}.${X}: ${Q}`)}J[H]=G}return J}function V8(Z){let Y=Z.toLowerCase();if(Y.startsWith("is")||Y.startsWith("has")||Y.endsWith("able"))return!1;if(Y.includes("count")||Y.includes("amount")||Y.includes("quantity"))return 0;if(Y.includes("url")||Y.includes("link"))return"https://example.com";if(Y.includes("email"))return FZ.internet.email();if(Y.includes("name"))return FZ.person.fullName();return null}function L8(Z){let Y={};for(let[$,J]of Object.entries(Z))Y[xZ($)]=J;return Y}async function E8(Z,Y=!1){let $=[];for(let J=0;J<Z.count;J++){let X=await B8(Z.attributes,Z.name,Y&&J===0),W=Z.fixtures[J];$.push(W?{...X,...L8(W)}:X)}return $}function D4(Z,Y){return qZ(Z,Y)}async function qZ(Z,Y){let $=Date.now();try{try{await A.selectFrom(Z.table).limit(0).execute()}catch(H){let G=H?.message||"";if(G.includes("does not exist")||G.includes("no such table")||G.includes("doesn't exist"))return M.info(` Skipping ${Z.name}: table "${Z.table}" does not exist`),{model:Z.name,table:Z.table,count:0,success:!0,duration:Date.now()-$};throw H}if(!Y.fresh){if(await A.selectFrom(Z.table).selectAll().limit(1).executeTakeFirst()){if(Y.verbose)M.info(` ${Z.name}: table already has rows \u2014 skipping (use --fresh to replace)`);return{model:Z.name,table:Z.table,count:0,success:!0,duration:Date.now()-$}}}let J=await E8(Z,Y.verbose);if(J.length===0)return{model:Z.name,table:Z.table,count:0,success:!0,duration:Date.now()-$};if(Y.fresh)try{if(await A.deleteFrom(Z.table).execute(),Y.verbose)M.info(` Truncated table: ${Z.table}`)}catch{}let X=100,W=0;for(let H=0;H<J.length;H+=X){let G=J.slice(H,H+X);await A.insertInto(Z.table).values(G).execute(),W+=G.length}if(Y.verbose)M.success(` Seeded ${Z.name}: ${W} records`);return{model:Z.name,table:Z.table,count:W,success:!0,duration:Date.now()-$}}catch(J){let X=J instanceof Error?J.message:String(J);if(Y.verbose)M.error(` Failed to seed ${Z.name}: ${X}`);return{model:Z.name,table:Z.table,count:0,success:!1,error:X,duration:Date.now()-$}}}function I8(Z){let Y={User:0,Team:1,Project:2};return Z.sort(($,J)=>{let X=Y[$.name]??10,W=Y[J.name]??10;return X-W})}async function K8(Z={}){let Y=Date.now();await AZ();let $=Z.modelsDir||cY.userModelsPath(),J=Z.verbose??!0;if(J)M.info("Seeding database using model factories..."),M.info(`User models directory: ${$}`),M.info(`Default models directory: ${DZ()}`);let X=await F4($,J,Z.includeDefaults??!1);if(X.length===0)return M.warn("No seedable models found in defaults or user directories"),{total:0,successful:0,failed:0,results:[],duration:Date.now()-Y};if(M.warn(`[seed] The \`useSeeder\` trait + auto-walker is deprecated (stacksjs/stacks#1919, #1929). Run \`./buddy seed:scaffold\` to generate a class seeder per \`useSeeder\` model AND strip the trait from the model in one pass. The walker + trait are scheduled for removal in the next major. Affected: ${X.map((Q)=>Q.name).join(", ")}`),Z.only&&Z.only.length>0)X=X.filter((Q)=>Z.only.includes(Q.name));if(Z.except&&Z.except.length>0)X=X.filter((Q)=>!Z.except.includes(Q.name));if(!Z.fresh&&!Z.allowProtected){let Q=[];if(X=X.filter((_)=>{if(O8(_.name))return Q.push(_),!1;return!0}),Q.length>0)M.info(`Skipped ${Q.length} protected auth model(s) to avoid invalidating live sessions: ${Q.map((_)=>_.name).join(", ")}`),M.info(" Re-run with --fresh (truncates tables first) or --allow-protected to include them.")}if(X=I8(X),J)M.info(`Found ${X.length} seedable model(s)`);let W=[];for(let Q of X){if(J)M.info(`Seeding ${Q.name} (${Q.count} records)...`);try{let _=await qZ(Q,Z);W.push(_)}catch(_){let U=_ instanceof Error?_.message:String(_);if(J)M.error(` Unexpected error seeding ${Q.name}: ${U}`);W.push({model:Q.name,table:Q.table,count:0,success:!1,error:U,duration:0})}}let H=W.filter((Q)=>Q.success).length,G=W.filter((Q)=>!Q.success).length,z=W.reduce((Q,_)=>Q+_.count,0);if(J)if(M.info(""),G===0)M.success("Database seeded successfully!"),M.info(` Total records: ${z}`),M.info(` Models seeded: ${H}`);else M.warn(`Seeding completed with ${G} failure(s)`),M.info(` Successful: ${H}`),M.info(` Failed: ${G}`);return{total:W.length,successful:H,failed:G,results:W,duration:Date.now()-Y}}async function N5(Z,Y={}){let $=cY.userModelsPath(),X=(await F4($,Y.verbose)).find((W)=>W.name===Z);if(!X)throw Error(`Model not found: ${Z}`);if(Y.count)X.count=Y.count;return qZ(X,{fresh:Y.fresh,verbose:Y.verbose??!0})}async function y5(Z={}){return K8({...Z,fresh:!0})}async function h5(){let Z=cY.userModelsPath(),Y=DZ(),$=await CY(Y,!0),J=await CY(Z,!1),X=[],W=new Set;for(let H of J)X.push({name:H.name,table:H.table,count:H.count,source:"user"}),W.add(H.name);for(let H of $)if(!W.has(H.name))X.push({name:H.name,table:H.table,count:H.count,source:"default"});return X}import{log as j8}from"@stacksjs/logging";function R8(Z){if(Z&&typeof Z==="object"){let Y=Z;if(Y._definition&&typeof Y._definition==="object"&&"name"in Y._definition)return Y._definition;if("name"in Y&&(("attributes"in Y)||("table"in Y)||("traits"in Y)))return Y}throw Error("factory.generate: expected a Stacks model (the default export of app/Models/*.ts, or a defineModel() return value). Got something without a `.name` field.")}function q4(Z){return Z.replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/(\d)([A-Za-z])/g,"$1_$2").toLowerCase()}function x4(Z){let Y={};for(let[$,J]of Object.entries(Z))Y[q4($)]=J;return Y}function w8(Z,Y={}){let $=R8(Z),J=$.name,X=$.attributes??{},W=$.traits?.useSeeder,H=W&&typeof W==="object"?W:void 0,G=Y.count??H?.count??10,z=Y.with?x4(Y.with):void 0,Q=Y.rows??H?.fixtures??[],_=Math.max(G,Q.length),U=[];for(let O=0;O<_;O++){let L=Q[O];if(!z&&!L)continue;U[O]={...z??{},...L?x4(L):{}}}let I=$.table??`${q4(J)}s`;return{name:J,table:I,count:_,fixtures:U,attributes:X,model:$}}async function T4(Z,Y={}){let $=w8(Z,Y);try{return await D4({...$,filePath:""},{fresh:Y.fresh,verbose:Y.verbose??!1})}catch(J){let X=J instanceof Error?J.message:String(J);throw j8.error(`[factory] generate(${$.name}) failed: ${X}`),J}}var S8={generate:T4};import{log as TZ}from"@stacksjs/logging";import{path as uY}from"@stacksjs/path";import{fs as n}from"@stacksjs/storage";function M8(Z){let Y=Z,$=!1,J=!1;for(let X of["useSeeder","seedable"]){let H=new RegExp(`\\b${X}\\s*:`).exec(Y);if(!H)continue;let G=H.index,z=G+H[0].length;while(z<Y.length&&/\s/.test(Y[z]))z++;if(Y[z]==="{"){let I=0,O=null;for(;z<Y.length;z++){let L=Y[z];if(O){if(L==="\\"){z++;continue}if(L===O)O=null;continue}if(L==='"'||L==="'"||L==="`"){O=L;continue}if(L==="{")I++;else if(L==="}"){if(I--,I===0){z++;break}}}}else if(Y.startsWith("true",z)||Y.startsWith("false",z))z+=Y.startsWith("true",z)?4:5;else{J=!0;continue}let _=z;while(_<Y.length&&(Y[_]===" "||Y[_]==="\t"))_++;if(Y[_]===",")_++;while(_<Y.length&&(Y[_]===" "||Y[_]==="\t"))_++;if(Y[_]==="/"&&Y[_+1]==="/")while(_<Y.length&&Y[_]!==`
|
|
21
21
|
`)_++;let U=G;while(U>0&&(Y[U-1]===" "||Y[U-1]==="\t"))U--;if(U>0&&Y[U-1]===`
|
|
22
22
|
`&&Y[_]===`
|
|
23
|
-
`)_++;Y=Y.slice(0,U)+Y.slice(_),$=!0}return{source:Y,changed:$,skipped:J&&!$}}var
|
|
23
|
+
`)_++;Y=Y.slice(0,U)+Y.slice(_),$=!0}return{source:Y,changed:$,skipped:J&&!$}}var P4=(Z,Y,$)=>`import { factory, Seeder } from '@stacksjs/database'
|
|
24
24
|
import ${Z} from '${Y}'
|
|
25
25
|
|
|
26
26
|
export default class ${Z}Seeder extends Seeder {
|
|
@@ -28,7 +28,7 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
28
28
|
await factory.generate(${Z}, { count: ${$} })
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
`;function
|
|
31
|
+
`;function F8(Z,Y){let J=uY.relative(Z,Y).replace(/\\/g,"/").replace(/\.ts$/,"");return J.startsWith(".")?J:`./${J}`}async function D8(Z={}){let Y=Z.modelsDir??uY.userModelsPath(),$=Z.seedersDir??uY.projectPath("database/seeders"),J={generated:[],skipped:[],errors:[],strippedTrait:[],traitStripSkipped:[]};if(!n.existsSync(Y))return TZ.warn(`[seed:scaffold] No models directory at ${Y}`),J;if(!Z.dryRun&&!n.existsSync($))n.mkdirSync($,{recursive:!0});let X=n.readdirSync(Y,{withFileTypes:!0});for(let W of X){if(!W.isFile()||!W.name.endsWith(".ts"))continue;if(W.name.startsWith("_")||W.name.startsWith("index"))continue;let H=uY.join(Y,W.name),G;try{let O=await import(H);G=O.default||O}catch(O){J.errors.push({model:W.name,error:O.message});continue}if(!G||!G.name){J.errors.push({model:W.name,error:"missing default export with `name` field"});continue}let z=G.traits?.useSeeder??G.traits?.seedable;if(!z){J.skipped.push({model:G.name,file:"",reason:"no-useseeder"});continue}let Q=typeof z==="object"&&"count"in z?z.count:10,_=`${G.name}Seeder.ts`,U=uY.join($,_);if(n.existsSync(U)&&!Z.force)J.skipped.push({model:G.name,file:U,reason:"already-exists"});else{let O=F8($,H),L=P4(G.name,O,Q);if(Z.dryRun)TZ.info(`[seed:scaffold] would write ${U}`);else n.writeFileSync(U,L,"utf-8");J.generated.push({model:G.name,file:U})}try{let O=n.readFileSync(H,"utf-8"),{source:L,changed:B,skipped:E}=M8(O);if(B){if(Z.dryRun)TZ.info(`[seed:scaffold] would strip useSeeder trait from ${H}`);else n.writeFileSync(H,L,"utf-8");J.strippedTrait.push({model:G.name,file:H})}else if(E)J.traitStripSkipped.push({model:G.name,file:H})}catch(O){J.errors.push({model:G.name,error:`trait strip failed: ${O.message}`})}}return J}function x8(Z,Y,$){return P4(Z,Y,$)}F();import{log as c4}from"@stacksjs/logging";import{getTableName as q8}from"@stacksjs/orm";import{path as i}from"@stacksjs/path";import{fs as BY,globSync as u4}from"@stacksjs/storage";import{plural as T8,snakeCase as P8}from"@stacksjs/strings";function k4(Z){return Z.name==="string"}function N4(Z){return Z.name==="number"}function y4(Z){return Z.name==="enum"}function h4(Z){return Z.name==="boolean"}function v4(Z){return Z.name==="date"}function f4(Z){return Z.name==="unix"}function b4(Z){return Z.name==="float"}function p4(Z){return Z.name==="datetime"}function C4(Z){return Z.name==="timestamp"}async function VY(){let Z=await BY.promises.readdir(i.userMigrationsPath());if(Z.length){for(let Y of Z)if(Y.endsWith(".ts")){let $=i.userMigrationsPath(`${Y}`);if(BY.existsSync($))await Bun.$`rm ${$}`}}}async function LY(){let Z=i.frameworkPath("cache/models");if(!BY.existsSync(Z))return;let Y=await BY.promises.readdir(Z);if(Y.length){for(let $ of Y)if($.endsWith(".ts")){let J=i.frameworkPath(`cache/models/${$}`);if(BY.existsSync(J))await Bun.$`rm ${J}`}}}async function s(Z){let $=(await import(i.frameworkPath(`cache/models/${Z}`))).default,J={};if(typeof $.attributes==="object")J=$.attributes;else try{J=JSON.parse($.attributes||"{}")}catch{J={}}return J}async function o5(Z){if(typeof Z==="string")Z=(await import(Z)).default;return Z.table??P8(T8(Z?.name||""))}async function JY(Z){return c4.debug(`hasTableBeenMigrated for table: ${Z}`),(await k8()).some(($)=>$.name.includes(Z))}async function x(Z){return c4.debug(`hasTableBeenMigrated for table: ${Z}`),u4([i.userMigrationsPath("*.ts")],{absolute:!0}).some(($)=>$.includes(`create-${Z}`))}async function k8(){try{return await A.selectFrom("migrations").select("name").execute()}catch(Z){if(Z?.message.includes("no such table: migrations"))return console.warn("Migrations table does not exist, returning empty list."),[];return[]}}function PZ(Z){if("getRules"in Z){let Y=Z.getRules().find(($)=>$.name==="max");return Y?.params?.length||Y?.params?.max||255}return 255}function N8(Z,Y="mysql"){if(Y==="sqlite")return"'text'";return`'varchar(${PZ(Z)})'`}function t5(Z,Y="mysql"){if(Y==="sqlite")return"'text'";let $=Z.name;if($==="unix")return"'bigint'";return $||"date"}function e5(Z,Y){return Z.min===Y.min&&Z.max===Y.max}async function EY(Z){return(await BY.promises.readdir(i.userMigrationsPath())).some(($)=>{let J=Z.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`(-${J}-)`).test($)})}function IY(Z,Y){let $=Z.filter((X)=>!Y.includes(X)),J=Y.filter((X)=>!Z.includes(X));if($.length===0&&J.length===0)return null;return{added:J,removed:$}}function XY(Z){if(!Z)return[];let Y=Object.entries(Z);return Y.sort(([$,J],[X,W])=>{let H=J.order??Number.POSITIVE_INFINITY,G=W.order??Number.POSITIVE_INFINITY;return H-G}),Y}function KY(Z,Y){if(!Z||!Y)return!1;if(Z.length!==Y.length)return!1;for(let $=0;$<Z.length;$++)if(Z[$]!==Y[$])return!1;return!0}function jY(Z,Y){let $=[];for(let J in Z)if(Object.prototype.hasOwnProperty.call(Z,J)&&Object.prototype.hasOwnProperty.call(Y,J)){let X=PZ(Z[J].validation.rule),W=PZ(Y[J].validation.rule);if(X!==void 0&&W!==void 0){if(X!==W)$.push({key:J,max:W,min:W})}}return $}async function ZZ(){let Z=u4([i.userModelsPath("*.ts"),i.storagePath("framework/defaults/app/Models/**/*.ts")],{absolute:!0}),Y=[];for(let $ of Z){let J=(await import($)).default,X=q8(J,$),W=UY(J,X);if(W)Y.push(W);Y.push(X)}return Y}function UY(Z,Y){let $=`${Y}_likes`,J=Z.traits;if(!J?.likeable)return;return typeof J.likeable==="object"?J.likeable.table||$:$}function RY(Z,Y){let $=Z.traits?.likeable;if($&&typeof $==="object"&&!Array.isArray($)&&$.foreignKey)return $.foreignKey;return`${Y.replace(/s$/,"")}_id`}function y8(Z,Y="mysql"){if(Y==="sqlite")return"'integer'";if("getRules"in Z){let $=Z.getRules().find((H)=>H.name==="min"),J=Z.getRules().find((H)=>H.name==="max"),X=$?.params?.min??-2147483648,W=J?.params?.max??2147483647;return X>=-2147483648&&W<=2147483647?"'integer'":"'bigint'"}return"'integer'"}function h8(Z,Y="mysql"){let $=Z.getAllowedValues();if(!$)throw Error("Enum rule found but no allowedValues defined");let J=$.map((X)=>`'${X}'`).join(", ");if(Y==="postgres")return"'varchar(255)'";if(Y==="sqlite")return"'text'";return`sql\`enum(${J})\``}function WY(Z,Y="mysql"){if(y4(Z))return h8(Z,Y);if(k4(Z))return N8(Z,Y);if(N4(Z))return y8(Z,Y);if(h4(Z))return"'boolean'";if(v4(Z))return"'date'";if(p4(Z))return Y==="postgres"?"'timestamp'":"'datetime'";if(f4(Z))return"'bigint'";if(C4(Z))return"'timestamp'";if(b4(Z))return"'float4'";if(["array","object"].includes(Z.name))return Y==="sqlite"?"'text'":"'json'";if(Y==="sqlite")return"'text'";return Y==="mysql"?"'varchar(255)'":"'text'"}function Y1(Z){return Z.includes(".required()")}F();import{log as l}from"@stacksjs/logging";import{log as g4}from"@stacksjs/logging";import{path as m4}from"@stacksjs/path";function d4(Z){return`\x1B[3m${Z}\x1B[23m`}async function $Z(){if(await x("password_resets"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
32
32
|
`;Y+=`import { sql } from '@stacksjs/database'
|
|
33
33
|
|
|
34
34
|
`,Y+=`export async function up(db: Database<any>) {
|
|
@@ -51,7 +51,7 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
51
51
|
`,Y+=` .column('token')
|
|
52
52
|
`,Y+=` .execute()
|
|
53
53
|
`,Y+=`}
|
|
54
|
-
`;let J=`${new Date().getTime().toString()}-create-password-resets-table.ts`,X=
|
|
54
|
+
`;let J=`${new Date().getTime().toString()}-create-password-resets-table.ts`,X=m4.userMigrationsPath(J);await Bun.write(X,Y),g4.success(`Created migration: ${d4(J)}`)}async function W1(){if(await x("password_resets"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
55
55
|
`;Y+=`import { sql } from '@stacksjs/database'
|
|
56
56
|
|
|
57
57
|
`,Y+=`export async function up(db: Database<any>) {
|
|
@@ -74,7 +74,7 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
74
74
|
`,Y+=` .column('token')
|
|
75
75
|
`,Y+=` .execute()
|
|
76
76
|
`,Y+=`}
|
|
77
|
-
`;let J=`${new Date().getTime().toString()}-create-password-resets-table.ts`,X=
|
|
77
|
+
`;let J=`${new Date().getTime().toString()}-create-password-resets-table.ts`,X=m4.userMigrationsPath(J);await Bun.write(X,Y),g4.success(`Created migration: ${d4(J)}`)}import{ok as v8}from"@stacksjs/error-handling";import{getModelName as f8,getPivotTables as H6,getTableName as yZ}from"@stacksjs/orm";import{path as a}from"@stacksjs/path";import{fs as b8,globSync as p8}from"@stacksjs/storage";import{snakeCase as wY}from"@stacksjs/strings";F();import{log as P}from"@stacksjs/logging";import{path as N}from"@stacksjs/path";function k(Z){return`\x1B[3m${Z}\x1B[23m`}function _1(){return["tags","taggables","categorizables","comments","commentables","commentable_upvotes","passkeys","password_resets","query_logs","migrations"]}async function s4(){if(await x("users"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
78
78
|
import { sql } from '@stacksjs/database'
|
|
79
79
|
|
|
80
80
|
`;Y+=`export async function up(db: Database<any>) {
|
|
@@ -93,7 +93,7 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
93
93
|
`,Y+=` .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
94
94
|
`,Y+=` .execute()
|
|
95
95
|
`,Y+=` }
|
|
96
|
-
`;let J=`${new Date().getTime().toString()}-create-passkeys-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function
|
|
96
|
+
`;let J=`${new Date().getTime().toString()}-create-passkeys-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function l4(){if(await x("users"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
97
97
|
import { sql } from '@stacksjs/database'
|
|
98
98
|
|
|
99
99
|
`;Y+=`export async function up(db: Database<any>) {
|
|
@@ -113,7 +113,7 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
113
113
|
`,Y+=` .execute()
|
|
114
114
|
|
|
115
115
|
`,Y+=`}
|
|
116
|
-
`;let J=`${new Date().getTime().toString()}-create-passkeys-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function
|
|
116
|
+
`;let J=`${new Date().getTime().toString()}-create-passkeys-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function r4(){if(await x("tags"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
117
117
|
`;Y+=`import { sql } from '@stacksjs/database'
|
|
118
118
|
|
|
119
119
|
`,Y+=`export async function up(db: Database<any>) {
|
|
@@ -149,7 +149,7 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
149
149
|
`,Y+=` .execute()
|
|
150
150
|
|
|
151
151
|
`,Y+=`}
|
|
152
|
-
`;let J=`${new Date().getTime().toString()}-create-tags-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`),await new Promise((W)=>setTimeout(W,2)),await
|
|
152
|
+
`;let J=`${new Date().getTime().toString()}-create-tags-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`),await new Promise((W)=>setTimeout(W,2)),await kZ()}async function n4(){if(await x("tags"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
153
153
|
`;Y+=`import { sql } from '@stacksjs/database'
|
|
154
154
|
|
|
155
155
|
`,Y+=`export async function up(db: Database<any>) {
|
|
@@ -185,7 +185,7 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
185
185
|
`,Y+=` .execute()
|
|
186
186
|
|
|
187
187
|
`,Y+=`}
|
|
188
|
-
`;let J=`${new Date().getTime().toString()}-create-tags-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`),await new Promise((W)=>setTimeout(W,2)),await
|
|
188
|
+
`;let J=`${new Date().getTime().toString()}-create-tags-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`),await new Promise((W)=>setTimeout(W,2)),await NZ()}async function i4(){if(await x("categorizable"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
189
189
|
`;Y+=`import { sql } from '@stacksjs/database'
|
|
190
190
|
|
|
191
191
|
`,Y+=`export async function up(db: Database<any>) {
|
|
@@ -225,7 +225,7 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
225
225
|
`,Y+=` .column('is_active')
|
|
226
226
|
`,Y+=` .execute()
|
|
227
227
|
`,Y+=`}
|
|
228
|
-
`;let J=`${new Date().getTime().toString()}-create-categorizables-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function
|
|
228
|
+
`;let J=`${new Date().getTime().toString()}-create-categorizables-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function a4(){if(await x("categorizable"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
229
229
|
`;Y+=`import { sql } from '@stacksjs/database'
|
|
230
230
|
|
|
231
231
|
`,Y+=`export async function up(db: Database<any>) {
|
|
@@ -266,7 +266,7 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
266
266
|
`,Y+=` .column('is_active')
|
|
267
267
|
`,Y+=` .execute()
|
|
268
268
|
`,Y+=`}
|
|
269
|
-
`;let J=`${new Date().getTime().toString()}-create-categorizables-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function
|
|
269
|
+
`;let J=`${new Date().getTime().toString()}-create-categorizables-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function o4(Z={}){if(await x("comments"))return;let $=`import type { Database } from '@stacksjs/database'
|
|
270
270
|
`;if($+=`import { sql } from '@stacksjs/database'
|
|
271
271
|
|
|
272
272
|
`,$+=`export async function up(db: Database<any>) {
|
|
@@ -297,7 +297,7 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
297
297
|
`,$+=` await db.schema.createIndex('idx_comments_status').on('comments').column('status').execute()
|
|
298
298
|
`,$+=` await db.schema.createIndex('idx_comments_created_at').on('comments').column('created_at').execute()
|
|
299
299
|
`,$+=`}
|
|
300
|
-
`;let X=`${new Date().getTime().toString()}-create-comments-table.ts`,W=N.userMigrationsPath(X);await Bun.write(W,$),P.success(`Created migration: ${k(X)}`)}async function
|
|
300
|
+
`;let X=`${new Date().getTime().toString()}-create-comments-table.ts`,W=N.userMigrationsPath(X);await Bun.write(W,$),P.success(`Created migration: ${k(X)}`)}async function t4(){if(await x("comments"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
301
301
|
`;Y+=`import { sql } from '@stacksjs/database'
|
|
302
302
|
|
|
303
303
|
`,Y+=`export async function up(db: Database<any>) {
|
|
@@ -325,7 +325,7 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
325
325
|
`,Y+=` await db.schema.createIndex('idx_comments_status').on('comments').column('status').execute()
|
|
326
326
|
`,Y+=` await db.schema.createIndex('idx_comments_created_at').on('comments').column('created_at').execute()
|
|
327
327
|
`,Y+=`}
|
|
328
|
-
`;let J=`${new Date().getTime().toString()}-create-comments-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function
|
|
328
|
+
`;let J=`${new Date().getTime().toString()}-create-comments-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function JZ(){await A.unsafe("DROP TABLE IF EXISTS passkeys").execute(),await A.unsafe("DROP TABLE IF EXISTS password_resets").execute(),await A.unsafe("DROP TABLE IF EXISTS query_logs").execute(),await A.unsafe("DROP TABLE IF EXISTS categorizables").execute(),await A.unsafe("DROP TABLE IF EXISTS commentable_upvotes").execute(),await A.unsafe("DROP TABLE IF EXISTS tags").execute(),await A.unsafe("DROP TABLE IF EXISTS taggables").execute(),await A.unsafe("DROP TABLE IF EXISTS categorizable_models").execute(),await A.unsafe("DROP TABLE IF EXISTS commentables").execute(),await A.unsafe("DROP TABLE IF EXISTS comments").execute(),await A.unsafe("DROP TABLE IF EXISTS categories_models").execute(),await A.unsafe("DROP TABLE IF EXISTS activities").execute()}async function O1(){await A.unsafe("DELETE FROM migrations").execute(),await A.unsafe("DELETE FROM migration_locks").execute()}async function e4(){await A.unsafe("DROP TABLE IF EXISTS migrations").execute(),await A.unsafe("DROP TABLE IF EXISTS migration_locks").execute()}async function Y6(){if(await x("commentable_upvotes"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
329
329
|
import { sql } from '@stacksjs/database'
|
|
330
330
|
|
|
331
331
|
`;Y+=`export async function up(db: Database<any>) {
|
|
@@ -339,7 +339,7 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
339
339
|
|
|
340
340
|
`,Y+=` await db.schema.createIndex('idx_commentable_upvotes_upvoteable').on('commentable_upvotes').columns(['upvoteable_id', 'upvoteable_type']).execute()
|
|
341
341
|
`,Y+=`}
|
|
342
|
-
`;let J=`${new Date().getTime().toString()}-create-commentable_upvotes-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function
|
|
342
|
+
`;let J=`${new Date().getTime().toString()}-create-commentable_upvotes-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function Z6(){if(await x("commentable_upvotes"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
343
343
|
import { sql } from '@stacksjs/database'
|
|
344
344
|
|
|
345
345
|
`;Y+=`export async function up(db: Database<any>) {
|
|
@@ -353,7 +353,7 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
353
353
|
|
|
354
354
|
`,Y+=` await db.schema.createIndex('idx_commentable_upvotes_upvoteable').on('commentable_upvotes').columns(['upvoteable_id', 'upvoteable_type']).execute()
|
|
355
355
|
`,Y+=`}
|
|
356
|
-
`;let J=`${new Date().getTime().toString()}-create-commentable_upvotes-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function
|
|
356
|
+
`;let J=`${new Date().getTime().toString()}-create-commentable_upvotes-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function A1(){if(await x("commentables"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
357
357
|
`;Y+=`import { sql } from '@stacksjs/database'
|
|
358
358
|
|
|
359
359
|
`,Y+=`export async function up(db: Database<any>) {
|
|
@@ -387,7 +387,7 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
387
387
|
`,Y+=` .execute()
|
|
388
388
|
|
|
389
389
|
`,Y+=`}
|
|
390
|
-
`;let J=`${new Date().getTime().toString()}-create-commentables-pivot-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function
|
|
390
|
+
`;let J=`${new Date().getTime().toString()}-create-commentables-pivot-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function $6(){if(await x("commentables_pivot"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
391
391
|
`;Y+=`import { sql } from '@stacksjs/database'
|
|
392
392
|
|
|
393
393
|
`,Y+=`export async function up(db: Database<any>) {
|
|
@@ -426,7 +426,7 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
426
426
|
`,Y+=` .execute()
|
|
427
427
|
|
|
428
428
|
`,Y+=`}
|
|
429
|
-
`;let J=`${new Date().getTime().toString()}-create-commentables-pivot-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function
|
|
429
|
+
`;let J=`${new Date().getTime().toString()}-create-commentables-pivot-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function kZ(){if(await x("taggables"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
430
430
|
`;Y+=`import { sql } from '@stacksjs/database'
|
|
431
431
|
|
|
432
432
|
`,Y+=`export async function up(db: Database<any>) {
|
|
@@ -460,7 +460,7 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
460
460
|
`,Y+=` .execute()
|
|
461
461
|
|
|
462
462
|
`,Y+=`}
|
|
463
|
-
`;let J=`${new Date().getTime().toString()}-create-taggables-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function
|
|
463
|
+
`;let J=`${new Date().getTime().toString()}-create-taggables-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function NZ(){if(await x("taggables"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
464
464
|
`;Y+=`import { sql } from '@stacksjs/database'
|
|
465
465
|
|
|
466
466
|
`,Y+=`export async function up(db: Database<any>) {
|
|
@@ -499,7 +499,7 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
499
499
|
`,Y+=` .execute()
|
|
500
500
|
|
|
501
501
|
`,Y+=`}
|
|
502
|
-
`;let J=`${new Date().getTime().toString()}-create-taggables-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function
|
|
502
|
+
`;let J=`${new Date().getTime().toString()}-create-taggables-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function J6(){if(await x("query_logs"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
503
503
|
`;Y+=`import { sql } from '@stacksjs/database'
|
|
504
504
|
|
|
505
505
|
`,Y+=`export async function up(db: Database<any>) {
|
|
@@ -544,7 +544,7 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
544
544
|
`,Y+=` .execute()
|
|
545
545
|
|
|
546
546
|
`,Y+=`}
|
|
547
|
-
`;let J=`${new Date().getTime().toString()}-create-query-logs-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function
|
|
547
|
+
`;let J=`${new Date().getTime().toString()}-create-query-logs-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}async function X6(){if(await x("query_logs"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
548
548
|
`;Y+=`import { sql } from '@stacksjs/database'
|
|
549
549
|
|
|
550
550
|
`,Y+=`export async function up(db: Database<any>) {
|
|
@@ -589,7 +589,7 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
589
589
|
`,Y+=` .execute()
|
|
590
590
|
|
|
591
591
|
`,Y+=`}
|
|
592
|
-
`;let J=`${new Date().getTime().toString()}-create-query-logs-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}function
|
|
592
|
+
`;let J=`${new Date().getTime().toString()}-create-query-logs-table.ts`,X=N.userMigrationsPath(J);await Bun.write(X,Y),P.success(`Created migration: ${k(J)}`)}function W6(Z){return`\x1B[3m${Z}\x1B[23m`}async function D1(){return await C8(),await LY(),await VY(),v8("All tables dropped successfully!")}async function C8(){let Z=p8([a.userModelsPath("*.ts"),a.storagePath("framework/defaults/app/Models/**/*.ts")],{absolute:!0}),Y=await ZZ();for(let $ of Y){if(!/^[a-z_][\w]*$/i.test($))throw Error(`[mysql] Refusing to drop table with unsafe name: ${$}`);await A.unsafe(`DROP TABLE IF EXISTS \`${$}\``).execute()}await JZ();for(let $ of Z){let J=(await import($)).default,X=await H6(J,$);for(let W of X){if(!/^[a-z_][\w]*$/i.test(W.table))throw Error(`[mysql] Refusing to drop pivot table with unsafe name: ${W.table}`);await A.unsafe(`DROP TABLE IF EXISTS \`${W.table}\``).execute()}}}async function x1(Z){let Y=(await import(Z)).default,$=a.basename(Z),J=yZ(Y,Z),X=JSON.stringify(Y.attributes,null,2),W=a.frameworkPath(`cache/models/${$}`),H=!1;if(b8.existsSync(W)){l.info(`Fields have already been generated for ${J}`);let z=await s($);if(JSON.stringify(z,null,2)===X){l.debug(`Fields have not changed for ${J}`);return}H=!0,l.debug(`Fields have changed for ${J}`)}else l.debug(`Fields have not been generated for ${J}`);await Bun.$`mkdir -p ${a.frameworkPath("cache/models")} && cp ${Z} ${W}`;let G=await JY(J);if(l.debug(`Has ${J} been migrated? ${G}`),H)await u8(Z);else await G6(Z)}async function q1(){await Promise.all([i4(),o4(),r4(),kZ(),$Z(),s4(),J6(),Y6()])}async function G6(Z){l.debug("createTableMigration modelPath:",Z);let Y=(await import(Z)).default,$=yZ(Y,Z),J=Y.traits?.useAuth&&typeof Y.traits.useAuth!=="boolean"?Y.traits.useAuth.useTwoFactor:!1;await c8(Y,Z);let X=Y?.traits?.useTimestamps??Y?.traits?.timestampable??!0,W=Y?.traits?.useSocials&&Array.isArray(Y.traits.useSocials)&&Y.traits.useSocials.length>0,H=Array.isArray(Y?.traits?.likeable)?Y.traits.likeable.length>0:Boolean(Y?.traits?.likeable),G=Y?.traits?.useSoftDeletes??Y?.traits?.softDeletable??!1,z=(typeof Y.traits?.useAuth==="object"&&Y.traits.useAuth.usePasskey)??!1,Q=Y.traits?.billable||!1,_=Y.traits?.useUuid||!1;if(Q&&$==="users")await G6(a.frameworkPath("defaults/app/Models/Subscription.ts"));let U=`import type { Database } from '@stacksjs/database'
|
|
593
593
|
`;if(U+=`import { sql } from '@stacksjs/database'
|
|
594
594
|
|
|
595
595
|
`,U+=`export async function up(db: Database<any>) {
|
|
@@ -597,12 +597,12 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
597
597
|
`,U+=` .createTable('${$}')
|
|
598
598
|
`,U+=` .addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
|
|
599
599
|
`,_)U+=` .addColumn('uuid', 'varchar(255)')
|
|
600
|
-
`;if(W){let
|
|
601
|
-
`;if(
|
|
602
|
-
`;if(
|
|
603
|
-
`;if(
|
|
604
|
-
`;if(
|
|
605
|
-
`}for(let[
|
|
600
|
+
`;if(W){let B=Y.traits?.useSocials||[];if(B.includes("google"))U+=` .addColumn('google_id', 'varchar(255)')
|
|
601
|
+
`;if(B.includes("github"))U+=` .addColumn('github_id', 'varchar(255)')
|
|
602
|
+
`;if(B.includes("apple"))U+=` .addColumn('apple_id', 'varchar(255)')
|
|
603
|
+
`;if(B.includes("twitter"))U+=` .addColumn('twitter_id', 'varchar(255)')
|
|
604
|
+
`;if(B.includes("facebook"))U+=` .addColumn('facebook_id', 'varchar(255)')
|
|
605
|
+
`}for(let[B,E]of XY(Y.attributes)){let V=E,j=wY(B),R=WY(V.validation?.rule);U+=` .addColumn('${j}', ${R}`;let v="isRequired"in(V.validation?.rule??{})?(V.validation?.rule).isRequired:!1;if(v||V.unique||V.default!==void 0){if(U+=", col => col",v)U+=".notNull()";if(V.unique)U+=".unique()";if(V.default!==void 0)if(typeof V.default==="string")U+=`.defaultTo('${V.default.replace(/'/g,"\\'")}')`;else if(V.default===null)U+=".defaultTo(null)";else U+=`.defaultTo(${V.default})`;U+=""}U+=`)
|
|
606
606
|
`}if(J!==!1&&J)U+=` .addColumn('two_factor_secret', 'varchar(255)')
|
|
607
607
|
`;if(Q)U+=` .addColumn('stripe_id', 'varchar(255)')
|
|
608
608
|
`;if(z)U+=` .addColumn('public_passkey', 'varchar(255)')
|
|
@@ -610,10 +610,10 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
610
610
|
`,U+=` .addColumn('updated_at', 'timestamp')
|
|
611
611
|
`;if(G)U+=` .addColumn('deleted_at', 'timestamp')
|
|
612
612
|
`;if(U+=` .execute()
|
|
613
|
-
`,U+=
|
|
613
|
+
`,U+=d8($),H){let B=UY(Y,$);if(B){let E=RY(Y,$);U+=`
|
|
614
614
|
// Create upvote table
|
|
615
615
|
`,U+=` await (db as any).schema
|
|
616
|
-
`,U+=` .createTable('${
|
|
616
|
+
`,U+=` .createTable('${B}')
|
|
617
617
|
`,U+=` .addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
|
|
618
618
|
`,U+=` .addColumn('${E}', 'integer', col => col.notNull())
|
|
619
619
|
`,U+=` .addColumn('user_id', 'integer', col => col.notNull())
|
|
@@ -622,11 +622,11 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
622
622
|
`,U+=` .execute()
|
|
623
623
|
|
|
624
624
|
`,U+=` // Add indexes for upvote table
|
|
625
|
-
`,U+=` await (db as any).schema.createIndex('${
|
|
626
|
-
`,U+=` await (db as any).schema.createIndex('${
|
|
627
|
-
`,U+=` await (db as any).schema.createIndex('${
|
|
625
|
+
`,U+=` await (db as any).schema.createIndex('${B}_${E}_index').on('${B}').column('${E}').execute()
|
|
626
|
+
`,U+=` await (db as any).schema.createIndex('${B}_user_${E}_unique').on('${B}').columns(['user_id', '${E}']).unique().execute()
|
|
627
|
+
`,U+=` await (db as any).schema.createIndex('${B}_id_index').on('${B}').column('id').execute()
|
|
628
628
|
`}}U+=`}
|
|
629
|
-
`;let O=`${new Date().getTime().toString()}-create-${$}-table.ts`,L=
|
|
629
|
+
`;let O=`${new Date().getTime().toString()}-create-${$}-table.ts`,L=a.userMigrationsPath(O);l.debug(L),await Bun.write(L,U),l.success(`Created migration: ${W6(O)}`)}async function c8(Z,Y){let $=await H6(Z,Y),J=new Set;if(!$.length)return;for(let X of $){if(J.has(X.table))continue;if(await EY(X.table)){J.add(X.table);continue}let H=`import type { Database } from '@stacksjs/database'
|
|
630
630
|
`;H+=`import { sql } from '@stacksjs/database'
|
|
631
631
|
|
|
632
632
|
`,H+=`export async function up(db: Database<any>) {
|
|
@@ -638,21 +638,23 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
638
638
|
`,H+=` .addColumn('created_at', 'timestamp', col => col.defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
639
639
|
`,H+=` .execute()
|
|
640
640
|
`,H+=` }
|
|
641
|
-
`;let z=`${new Date().getTime().toString()}-create-${X.table}-table.ts`,Q=
|
|
641
|
+
`;let z=`${new Date().getTime().toString()}-create-${X.table}-table.ts`,Q=a.userMigrationsPath(z);await Bun.write(Q,H),J.add(X.table),l.success(`Created pivot migration: ${z}`)}}async function u8(Z){let Y=(await import(Z)).default,$=f8(Y,Z),J=yZ(Y,Z),X=!1,H=await s($)??{},G=Y.attributes,z=IY(Object.keys(H),Object.keys(G)),Q=z?.added||[],_=z?.removed||[],U=`import type { Database } from '@stacksjs/database'
|
|
642
642
|
`;if(U+=`import { sql } from '@stacksjs/database'
|
|
643
643
|
|
|
644
644
|
`,U+=`export async function up(db: Database<any>) {
|
|
645
645
|
`,Q.length||_.length)X=!0,U+=` await (db as any).schema.alterTable('${J}')
|
|
646
|
-
`;let I=
|
|
647
|
-
`}let O=Object.values(H).map((
|
|
646
|
+
`;let I=jY(H,G);for(let B of I){X=!0;let E=wY(B.key);U+=` .modifyColumn('${E}', 'varchar(${B.max})')
|
|
647
|
+
`}let O=Object.values(H).map((B)=>B.order),L=Object.values(G).map((B)=>B.order);if(!KY(O,L))X=!0,U+=m8(Y.attributes,J);if(X){U+=` .execute()
|
|
648
648
|
`,U+=`}
|
|
649
|
-
`;let E=`${new Date().getTime().toString()}-alter-${J}-table.ts`,
|
|
650
|
-
`}
|
|
649
|
+
`;let E=`${new Date().getTime().toString()}-alter-${J}-table.ts`,V=a.userMigrationsPath(E);await Bun.write(V,U),l.success(`Created alter migration: ${W6(E)}`)}}function g8(Z,Y){if(Y.unique||Y.where){let J=Y.unique?"UNIQUE ":"",X=Y.columns.map((H)=>wY(H)).join(", "),W=Y.where?` WHERE ${Y.where}`:"";return` await db.unsafe(\`CREATE ${J}INDEX IF NOT EXISTS \\\`${Y.name}\\\` ON \\\`${Z}\\\` (${X})${W}\`).execute()
|
|
650
|
+
`}let $=Y.columns.map((J)=>`'${wY(J)}'`).join(", ");return` await (db as any).schema.createIndex('${Y.name}').on('${Z}').columns([${$}]).execute()
|
|
651
|
+
`}function d8(Z){return` await (db as any).schema.createIndex('${Z}_id_index').on('${Z}').column('id').execute()
|
|
652
|
+
`}function m8(Z,Y){let $=XY(Z),J="",X="";for(let[W]of $){let H=wY(W);if(X)J+=`await sql\`
|
|
651
653
|
ALTER TABLE ${Y}
|
|
652
|
-
MODIFY COLUMN ${H} VARCHAR(255) NOT NULL AFTER ${
|
|
654
|
+
MODIFY COLUMN ${H} VARCHAR(255) NOT NULL AFTER ${wY(X)};
|
|
653
655
|
\`.execute(db)
|
|
654
656
|
|
|
655
|
-
`;X=H}return J}F();import{log as
|
|
657
|
+
`;X=H}return J}F();import{log as r}from"@stacksjs/logging";import{ok as s8}from"@stacksjs/error-handling";import{getModelName as l8,getPivotTables as z6,getTableName as XZ}from"@stacksjs/orm";import{path as y}from"@stacksjs/path";import{fs as SY,globSync as U6}from"@stacksjs/storage";import{plural as r8,snakeCase as gY}from"@stacksjs/strings";function vZ(Z){return`\x1B[3m${Z}\x1B[23m`}async function n8(){let Z=await Y$(),Y=U6([y.userModelsPath("*.ts"),y.storagePath("framework/defaults/app/Models/**/*.ts")],{absolute:!0});await e4();for(let $ of Z)await A.unsafe(`DROP TABLE IF EXISTS "${$}" CASCADE`).execute();await i8();for(let $ of Y){let J=(await import($)).default,X=await z6(J,$);for(let W of X)await A.unsafe(`DROP TABLE IF EXISTS "${W.table}" CASCADE`).execute()}}async function i8(){await A.unsafe('DROP TABLE IF EXISTS "passkeys" CASCADE').execute(),await A.unsafe('DROP TABLE IF EXISTS "password_resets" CASCADE').execute(),await A.unsafe('DROP TABLE IF EXISTS "query_logs" CASCADE').execute(),await A.unsafe('DROP TABLE IF EXISTS "categorizables" CASCADE').execute(),await A.unsafe('DROP TABLE IF EXISTS "commentables" CASCADE').execute(),await A.unsafe('DROP TABLE IF EXISTS "comments" CASCADE').execute(),await A.unsafe('DROP TABLE IF EXISTS "tags" CASCADE').execute(),await A.unsafe('DROP TABLE IF EXISTS "taggables" CASCADE').execute(),await A.unsafe('DROP TABLE IF EXISTS "commentable_upvotes" CASCADE').execute()}async function u1(){await a4(),await t4(),await n4(),await Z6(),await l4(),await X6(),await $Z(),await $6(),await NZ()}async function g1(){return await n8(),await LY(),await VY(),await A.unsafe('CREATE TABLE IF NOT EXISTS "migrations" (id SERIAL PRIMARY KEY)').execute(),await A.unsafe('CREATE TABLE IF NOT EXISTS "migration_locks" (id SERIAL PRIMARY KEY)').execute(),await A.unsafe('CREATE TABLE IF NOT EXISTS "activities" (id SERIAL PRIMARY KEY)').execute(),s8("All tables dropped successfully!")}async function d1(Z){if((await SY.promises.readdir(y.userMigrationsPath(""))).length===0){r.debug("No migrations found in the database folder, clearing the model snapshot cache...");let _=y.frameworkPath("cache/models");if(SY.existsSync(_)){let U=await SY.promises.readdir(_);if(U.length){for(let I of U)if(I.endsWith(".ts"))await SY.promises.unlink(y.frameworkPath(`cache/models/${I}`))}}}let $=(await import(Z)).default,J=y.basename(Z),X=XZ($,Z),W=JSON.stringify($.attributes,null,2),H=y.frameworkPath(`cache/models/${J}`),G=!1;if(SY.existsSync(H)){r.info(`Fields have already been generated for ${X}`);let _=await s(J);if(JSON.stringify(_,null,2)===W){r.debug(`Fields have not changed for ${X}`);return}G=!0,r.debug(`Fields have changed for ${X}`)}else r.debug(`Fields have not been generated for ${X}`);await Bun.$`mkdir -p ${y.frameworkPath("cache/models")} && cp ${Z} ${H}`;let z=await JY(X);if(r.debug(`Has ${X} been migrated? ${z}`),($.traits?.billable||!1)&&X==="users")await hZ(y.frameworkPath("defaults/app/Models/Subscription.ts"));if(G)await o8(Z);else await hZ(Z)}async function hZ(Z){r.debug("createTableMigration modelPath:",Z);let Y=(await import(Z)).default,$=XZ(Y,Z),J=Y.traits?.useAuth&&typeof Y.traits.useAuth!=="boolean"?Y.traits.useAuth.useTwoFactor:!1;await a8(Y,Z);let X=Y.traits?.useTimestamps??Y.traits?.timestampable??!0,W=Y?.traits?.useSocials&&Array.isArray(Y.traits.useSocials)&&Y.traits.useSocials.length>0,H=Array.isArray(Y?.traits?.likeable)?Y.traits.likeable.length>0:Boolean(Y?.traits?.likeable),G=Y.traits?.useSoftDeletes??Y.traits?.softDeletable??!1,z=(typeof Y.traits?.useAuth==="object"&&Y.traits.useAuth.usePasskey)??!1,Q=Y.traits?.billable||!1,_=Y.traits?.useUuid||!1;if(Q&&$==="users")await hZ(y.frameworkPath("defaults/app/Models/Subscription.ts"));let U=`import type { Database } from '@stacksjs/database'
|
|
656
658
|
`;if(U+=`import { sql } from '@stacksjs/database'
|
|
657
659
|
|
|
658
660
|
`,U+=`export async function up(db: Database<any>) {
|
|
@@ -660,13 +662,13 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
660
662
|
`,U+=` .createTable('${$}')
|
|
661
663
|
`,U+=` .addColumn('id', 'serial', (col) => col.primaryKey())
|
|
662
664
|
`,_)U+=` .addColumn('uuid', 'uuid', (col) => col.defaultTo(sql.raw('gen_random_uuid()')))
|
|
663
|
-
`;for(let[
|
|
664
|
-
`}if(W){let
|
|
665
|
-
`;if(
|
|
666
|
-
`;if(
|
|
667
|
-
`;if(
|
|
668
|
-
`;if(
|
|
669
|
-
`}if(H){let
|
|
665
|
+
`;for(let[B,E]of XY(Y.attributes)){let V=E,j=gY(B),R=WY(V.validation?.rule,"postgres"),v="isRequired"in(V.validation?.rule??{})?(V.validation?.rule).isRequired:!1;if(U+=` .addColumn('${j}', ${R}`,v||V.unique||V.default!==void 0){if(U+=", col => col",v)U+=".notNull()";if(V.unique)U+=".unique()";if(V.default!==void 0)if(typeof V.default==="string")U+=`.defaultTo('${V.default.replace(/'/g,"\\'")}')`;else if(V.default===null)U+=".defaultTo(null)";else U+=`.defaultTo(${V.default})`;U+=""}U+=`)
|
|
666
|
+
`}if(W){let B=Y.traits?.useSocials||[];if(B.includes("google"))U+=` .addColumn('google_id', 'text')
|
|
667
|
+
`;if(B.includes("github"))U+=` .addColumn('github_id', 'text')
|
|
668
|
+
`;if(B.includes("apple"))U+=` .addColumn('apple_id', 'text')
|
|
669
|
+
`;if(B.includes("twitter"))U+=` .addColumn('twitter_id', 'text')
|
|
670
|
+
`;if(B.includes("facebook"))U+=` .addColumn('facebook_id', 'text')
|
|
671
|
+
`}if(H){let B=Array.isArray(Y.traits?.likeable)?Y.traits.likeable:[];for(let E of B)U+=` .addColumn('${E}_count', 'integer', (col) => col.defaultTo(0))
|
|
670
672
|
`}if(J!==!1&&J)U+=` .addColumn('two_factor_secret', 'text')
|
|
671
673
|
`;if(Q)U+=` .addColumn('stripe_id', 'text')
|
|
672
674
|
`;if(z)U+=` .addColumn('public_passkey', 'text')
|
|
@@ -674,10 +676,10 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
674
676
|
`,U+=` .addColumn('updated_at', 'timestamptz')
|
|
675
677
|
`;if(G)U+=` .addColumn('deleted_at', 'timestamptz')
|
|
676
678
|
`;if(U+=` .execute()
|
|
677
|
-
`,U+=
|
|
679
|
+
`,U+=e8($),H){let B=UY(Y,$);if(B){let E=RY(Y,$);U+=`
|
|
678
680
|
// Create upvote table
|
|
679
681
|
`,U+=` await (db as any).schema
|
|
680
|
-
`,U+=` .createTable('${
|
|
682
|
+
`,U+=` .createTable('${B}')
|
|
681
683
|
`,U+=` .addColumn('id', 'serial', (col) => col.primaryKey())
|
|
682
684
|
`,U+=` .addColumn('${E}', 'integer', (col) => col.notNull())
|
|
683
685
|
`,U+=` .addColumn('user_id', 'integer', (col) => col.notNull())
|
|
@@ -686,11 +688,11 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
686
688
|
`,U+=` .execute()
|
|
687
689
|
|
|
688
690
|
`,U+=` // Add indexes for upvote table
|
|
689
|
-
`,U+=` await (db as any).schema.createIndex('${
|
|
690
|
-
`,U+=` await (db as any).schema.createIndex('${
|
|
691
|
-
`,U+=` await (db as any).schema.createIndex('${
|
|
691
|
+
`,U+=` await (db as any).schema.createIndex('${B}_${E}_index').on('${B}').column('${E}').execute()
|
|
692
|
+
`,U+=` await (db as any).schema.createIndex('${B}_user_${E}_unique').on('${B}').columns(['user_id', '${E}']).unique().execute()
|
|
693
|
+
`,U+=` await (db as any).schema.createIndex('${B}_id_index').on('${B}').column('id').execute()
|
|
692
694
|
`}}U+=`}
|
|
693
|
-
`;let O=`${new Date().getTime().toString()}-create-${$}-table.ts`,L=y.userMigrationsPath(O);await Bun.write(L,U),
|
|
695
|
+
`;let O=`${new Date().getTime().toString()}-create-${$}-table.ts`,L=y.userMigrationsPath(O);await Bun.write(L,U),r.success(`Created migration: ${vZ(O)}`)}async function a8(Z,Y){let $=await z6(Z,Y),J=new Set;if(!$.length)return;for(let X of $){if(J.has(X.table))continue;if(await EY(X.table)){J.add(X.table);continue}let H=`import type { Database } from '@stacksjs/database'
|
|
694
696
|
`;H+=`import { sql } from '@stacksjs/database'
|
|
695
697
|
|
|
696
698
|
`,H+=`export async function up(db: Database<any>) {
|
|
@@ -704,7 +706,7 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
704
706
|
|
|
705
707
|
`,H+=` await (db as any).schema
|
|
706
708
|
`,H+=` .alterTable('${X.table}')
|
|
707
|
-
`,H+=` .addForeignKeyConstraint('${X.table}_${X.firstForeignKey}_fkey', ['${X.firstForeignKey}'], '${
|
|
709
|
+
`,H+=` .addForeignKeyConstraint('${X.table}_${X.firstForeignKey}_fkey', ['${X.firstForeignKey}'], '${r8(X.firstForeignKey?.replace(/_id$/,"")||"")}', ['id'], (cb) => cb.onDelete('cascade'))
|
|
708
710
|
`,H+=` .execute()
|
|
709
711
|
|
|
710
712
|
`,H+=` await (db as any).schema
|
|
@@ -724,18 +726,20 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
724
726
|
`,H+=` .column('${X.secondForeignKey}')
|
|
725
727
|
`,H+=` .execute()
|
|
726
728
|
`,H+=`}
|
|
727
|
-
`;let z=`${new Date().getTime().toString()}-create-${X.table}-table.ts`,Q=y.userMigrationsPath(z);await Bun.write(Q,H),J.add(X.table),
|
|
729
|
+
`;let z=`${new Date().getTime().toString()}-create-${X.table}-table.ts`,Q=y.userMigrationsPath(z);await Bun.write(Q,H),J.add(X.table),r.success(`Created migration: ${vZ(z)}`)}}async function o8(Z){let Y=(await import(Z)).default,$=l8(Y,Z),J=XZ(Y,Z),X=!1,H=await s($)??{},G=Y.attributes,z=IY(Object.keys(H),Object.keys(G)),Q=z?.added||[],_=z?.removed||[],U=`import type { Database } from '@stacksjs/database'
|
|
728
730
|
`;if(U+=`import { sql } from '@stacksjs/database'
|
|
729
731
|
|
|
730
732
|
`,U+=`export async function up(db: Database<any>) {
|
|
731
733
|
`,Q.length||_.length)X=!0,U+=` await (db as any).schema.alterTable('${J}')
|
|
732
|
-
`;for(let
|
|
733
|
-
`}for(let
|
|
734
|
-
`;let I=
|
|
735
|
-
`}let O=Object.values(H).map((
|
|
734
|
+
`;for(let B of Q){let E=G[B],V=WY(E.validation?.rule,"postgres"),j=gY(B),R="isRequired"in(E.validation?.rule??{})?(E.validation?.rule).isRequired:!1;if(U+=` .addColumn('${j}', '${V}'`,R||E.unique||E.default!==void 0){if(U+=", col => col",R)U+=".notNull()";if(E.unique)U+=".unique()";if(E.default!==void 0)if(typeof E.default==="string")U+=`.defaultTo('${E.default}')`;else if(E.default===null)U+=".defaultTo(null)";else U+=`.defaultTo(${E.default})`;U+=""}U+=`)
|
|
735
|
+
`}for(let B of _)U+=` .dropColumn('${B}')
|
|
736
|
+
`;let I=jY(H,G);for(let B of I){X=!0;let E=gY(B.key);U+=` .alterColumn('${E}', (col) => col.setDataType('text'))
|
|
737
|
+
`}let O=Object.values(H).map((B)=>B.order),L=Object.values(G).map((B)=>B.order);if(!KY(O,L))X=!0;if(X){U+=` .execute()
|
|
736
738
|
`,U+=`}
|
|
737
|
-
`;let E=`${new Date().getTime().toString()}-alter-${J}-table.ts`,
|
|
738
|
-
`}
|
|
739
|
+
`;let E=`${new Date().getTime().toString()}-alter-${J}-table.ts`,V=y.userMigrationsPath(E);await Bun.write(V,U),r.success(`Created alter migration: ${vZ(E)}`)}}function t8(Z,Y){if(Y.unique||Y.where){let J=Y.unique?"UNIQUE ":"",X=Y.columns.map((H)=>gY(H)).join(", "),W=Y.where?` WHERE ${Y.where}`:"";return` await db.unsafe(\`CREATE ${J}INDEX IF NOT EXISTS "${Y.name}" ON "${Z}" (${X})${W}\`).execute()
|
|
740
|
+
`}let $=Y.columns.map((J)=>`'${gY(J)}'`).join(", ");return` await (db as any).schema.createIndex('${Y.name}').on('${Z}').columns([${$}]).execute()
|
|
741
|
+
`}function e8(Z){return` await (db as any).schema.createIndex('${Z}_id_index').on('${Z}').column('id').execute()
|
|
742
|
+
`}async function Y$(){let Z=U6([y.userModelsPath("*.ts"),y.storagePath("framework/defaults/app/Models/**/*.ts")],{absolute:!0}),Y=[];for(let $ of Z){let J=(await import($)).default,X=XZ(J,$);Y.push(X)}return Y}F();import{log as c}from"@stacksjs/logging";import{app as Z$}from"@stacksjs/config";import{ok as $$}from"@stacksjs/error-handling";import{fetchOtherModelRelations as J$,getModelName as _6,getPivotTables as O6,getTableName as WZ}from"@stacksjs/orm";import{path as f}from"@stacksjs/path";import{fs as A6,globSync as X$}from"@stacksjs/storage";import{snakeCase as QY}from"@stacksjs/strings";function Q6(Z){return`\x1B[3m${Z}\x1B[23m`}async function Z9(){return await LY(),await VY(),await W$(),$$("All tables dropped successfully!")}async function $9(){try{for(let Z of BZ)await A.unsafe(Z).execute()}catch(Z){c.debug(`[sqlite] Failed to apply pragmas: ${Z.message}`)}}async function W$(){let Z=X$([f.userModelsPath("*.ts"),f.storagePath("framework/defaults/app/Models/**/*.ts")],{absolute:!0}),Y=await ZZ(),$=/^[a-z_][\w]*$/i;await A.unsafe("PRAGMA foreign_keys = OFF").execute();try{for(let J of Y){if(!$.test(J))throw Error(`[sqlite] Refusing to drop table with unsafe name: ${J}`);await A.unsafe(`DROP TABLE IF EXISTS "${J}"`).execute()}await A.unsafe('DROP TABLE IF EXISTS "migrations"').execute(),await JZ();for(let J of Z){let X=(await import(J)).default,W=await O6(X,J);for(let H of W){if(!$.test(H.table))throw Error(`[sqlite] Refusing to drop pivot table with unsafe name: ${H.table}`);await A.unsafe(`DROP TABLE IF EXISTS "${H.table}"`).execute()}}}finally{await A.unsafe("PRAGMA foreign_keys = ON").execute()}}function J9(){if(Z$.env==="testing")return H$();return f.userDatabasePath("stacks.sqlite")}function H$(){return f.userDatabasePath("stacks_testing.sqlite")}async function X9(Z){let Y=(await import(Z)).default,$=f.basename(Z),J=await WZ(Y,Z),X=JSON.stringify(Y.attributes,null,2),W=f.frameworkPath(`cache/models/${$}`),H=!1;if(A6.existsSync(W)){c.debug(`Fields have already been generated for ${J}`);let z=await s($);if(JSON.stringify(z,null,2)===X){c.debug(`Fields have not changed for ${J}`);return}H=!0,c.debug(`Fields have changed for ${J}`)}else c.debug(`Fields have not been generated for ${J}`);await Bun.$`mkdir -p ${f.frameworkPath("cache/models")} && cp ${Z} ${W}`;let G=!1;if(c.debug(`Has ${J} been migrated? ${G}`),H)await U$(Z);else await G$(Z)}async function W9(Z){let Y=(await import(Z)).default,$=f.basename(Z),J=await WZ(Y,Z),X=JSON.stringify(Y.attributes,null,2),W=f.frameworkPath(`cache/models/${$}`);if(A6.existsSync(W)){c.debug(`Fields have already been generated for ${J}`);let H=await s($);if(JSON.stringify(H,null,2)===X){c.debug(`Fields have not changed for ${J}`);return}}await Bun.$`mkdir -p ${f.frameworkPath("cache/models")} && cp ${Z} ${W}`}async function G$(Z){c.debug("createTableMigration modelPath:",Z);let Y=(await import(Z)).default,$=WZ(Y,Z),J=_6(Y,Z),X=Y.traits?.useAuth&&typeof Y.traits.useAuth!=="boolean"?Y.traits.useAuth.useTwoFactor:!1;await z$(Y,Z);let W=await J$(J),H=Y?.traits?.useTimestamps??Y?.traits?.timestampable??!0,G=Y?.traits?.useSocials&&Array.isArray(Y.traits.useSocials)&&Y.traits.useSocials.length>0,z=Array.isArray(Y?.traits?.likeable)?Y.traits.likeable.length>0:Boolean(Y?.traits?.likeable),Q=Y?.traits?.useSoftDeletes??Y?.traits?.softDeletable??!1,_=(typeof Y.traits?.useAuth==="object"&&Y.traits.useAuth.usePasskey)??!1,U=Y.traits?.billable||!1,I=Y.traits?.useUuid||!1,O=`import type { Database } from '@stacksjs/database'
|
|
739
743
|
`;if(O+=`import { sql } from '@stacksjs/database'
|
|
740
744
|
|
|
741
745
|
`,O+=`export async function up(db: Database<any>) {
|
|
@@ -743,27 +747,27 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
743
747
|
`,O+=` .createTable('${$}')
|
|
744
748
|
`,O+=` .addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
|
|
745
749
|
`,I)O+=` .addColumn('uuid', 'text')
|
|
746
|
-
`;if(G){let
|
|
747
|
-
`;if(
|
|
748
|
-
`;if(
|
|
749
|
-
`;if(
|
|
750
|
-
`;if(
|
|
751
|
-
`}for(let[
|
|
750
|
+
`;if(G){let V=Y.traits?.useSocials||[];if(V.includes("google"))O+=` .addColumn('google_id', 'text')
|
|
751
|
+
`;if(V.includes("github"))O+=` .addColumn('github_id', 'text')
|
|
752
|
+
`;if(V.includes("apple"))O+=` .addColumn('apple_id', 'text')
|
|
753
|
+
`;if(V.includes("twitter"))O+=` .addColumn('twitter_id', 'text')
|
|
754
|
+
`;if(V.includes("facebook"))O+=` .addColumn('facebook_id', 'text')
|
|
755
|
+
`}for(let[V,j]of XY(Y.attributes)){let R=j,v=QY(V),rY=WY(R.validation?.rule,"sqlite");O+=` .addColumn('${v}', ${rY}`;let D=R.validation?.rule.isRequired;if(D||R.unique||R.default!==void 0){if(O+=", col => col",D)O+=".notNull()";if(R.unique)O+=".unique()";if(R.default!==void 0)if(typeof R.default==="string")O+=`.defaultTo('${R.default}')`;else if(R.default===null)O+=".defaultTo(null)";else O+=`.defaultTo(${R.default})`;O+=""}O+=`)
|
|
752
756
|
`}if(X!==!1&&X)O+=` .addColumn('two_factor_secret', 'text')
|
|
753
757
|
`;if(U)O+=` .addColumn('stripe_id', 'text')
|
|
754
758
|
`;if(Q)O+=` .addColumn('deleted_at', 'timestamp')
|
|
755
759
|
`;if(_)O+=` .addColumn('public_passkey', 'text')
|
|
756
|
-
`;if(W?.length)for(let
|
|
757
|
-
col.references('${
|
|
760
|
+
`;if(W?.length)for(let V of W){if(!V.foreignKey)continue;O+=` .addColumn('${V.foreignKey}', 'integer', (col) =>
|
|
761
|
+
col.references('${V.relationTable}.id').onDelete('cascade')
|
|
758
762
|
)
|
|
759
763
|
`}if(H)O+=" .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql`CURRENT_TIMESTAMP`))\n",O+=` .addColumn('updated_at', 'timestamp')
|
|
760
764
|
`;if(O+=` .execute()
|
|
761
765
|
|
|
762
|
-
`,W?.length)for(let
|
|
763
|
-
`;for(let
|
|
766
|
+
`,W?.length)for(let V of W){if(!V.foreignKey)continue;O+=O$($,V.foreignKey)}if(Y.indexes?.length){O+=`
|
|
767
|
+
`;for(let V of Y.indexes)O+=fZ($,V)}if(O+=_$($),z){let V=UY(Y,$);if(V){let j=RY(Y,$);O+=`
|
|
764
768
|
// Create upvote table
|
|
765
769
|
`,O+=` await (db as any).schema
|
|
766
|
-
`,O+=` .createTable('${
|
|
770
|
+
`,O+=` .createTable('${V}')
|
|
767
771
|
`,O+=` .addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
|
|
768
772
|
`,O+=` .addColumn('${j}', 'integer', col => col.notNull())
|
|
769
773
|
`,O+=` .addColumn('user_id', 'integer', col => col.notNull())
|
|
@@ -771,11 +775,11 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
771
775
|
`,O+=` .execute()
|
|
772
776
|
|
|
773
777
|
`,O+=` // Add indexes for upvote table
|
|
774
|
-
`,O+=` await (db as any).schema.createIndex('${
|
|
775
|
-
`,O+=` await (db as any).schema.createIndex('${
|
|
776
|
-
`,O+=` await (db as any).schema.createIndex('${
|
|
778
|
+
`,O+=` await (db as any).schema.createIndex('${V}_${j}_index').on('${V}').column('${j}').execute()
|
|
779
|
+
`,O+=` await (db as any).schema.createIndex('${V}_user_${j}_unique').on('${V}').columns(['user_id', '${j}']).unique().execute()
|
|
780
|
+
`,O+=` await (db as any).schema.createIndex('${V}_id_index').on('${V}').column('id').execute()
|
|
777
781
|
`}}O+=`}
|
|
778
|
-
`;let
|
|
782
|
+
`;let B=`${new Date().getTime().toString()}-create-${$}-table.ts`,E=f.userMigrationsPath(B);await Bun.write(E,O),c.success(`Created migration: ${Q6(B)}`)}async function z$(Z,Y){let $=await O6(Z,Y);if(!$.length)return;for(let J of $){if(await EY(J.table))return;let W=`import type { Database } from '@stacksjs/database'
|
|
779
783
|
`;W+=`import { sql } from '@stacksjs/database'
|
|
780
784
|
|
|
781
785
|
`,W+=`export async function up(db: Database<any>) {
|
|
@@ -787,33 +791,33 @@ export default class ${Z}Seeder extends Seeder {
|
|
|
787
791
|
`,W+=` .addColumn('created_at', 'timestamp', col => col.defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
788
792
|
`,W+=` .execute()
|
|
789
793
|
`,W+=` }
|
|
790
|
-
`;let G=`${new Date().getTime().toString()}-create-${J.table}-table.ts`,z=
|
|
794
|
+
`;let G=`${new Date().getTime().toString()}-create-${J.table}-table.ts`,z=f.userMigrationsPath(G);await Bun.write(z,W),c.success(`Created pivot migration: ${G}`)}}async function U$(Z){let Y=(await import(Z)).default,$=_6(Y,Z),J=WZ(Y,Z),X=!1,H=(await import(f.frameworkPath(`cache/models/${$}.ts`))).default,z=await s($)??{},Q=Y.attributes,_=IY(Object.keys(z),Object.keys(Q)),U=_?.added||[],I=_?.removed||[],O=`import type { Database } from '@stacksjs/database'
|
|
791
795
|
`;if(O+=`import { sql } from '@stacksjs/database'
|
|
792
796
|
|
|
793
797
|
`,O+=`export async function up(db: Database<any>) {
|
|
794
798
|
`,U.length||I.length)X=!0,O+=` await (db as any).schema.alterTable('${J}')
|
|
795
|
-
`;let L=
|
|
799
|
+
`;let L=jY(z,Q);for(let D of L){X=!0;let q=QY(D.key);O+=`await sql\`
|
|
796
800
|
ALTER TABLE ${J}
|
|
797
|
-
MODIFY COLUMN ${
|
|
801
|
+
MODIFY COLUMN ${q} TEXT
|
|
798
802
|
\`.execute(db)
|
|
799
803
|
|
|
800
|
-
`}for(let D of U){let
|
|
804
|
+
`}for(let D of U){let q=Q[D],w=WY(q.validation?.rule,"sqlite"),g=QY(D),zY=q.validation?.rule.isRequired;if(O+=` .addColumn('${g}', ${w}`,zY||q.unique||q.default!==void 0){if(O+=", col => col",zY)O+=".notNull()";if(q.unique)O+=".unique()";if(q.default!==void 0)if(typeof q.default==="string")O+=`.defaultTo('${q.default}')`;else if(q.default===null)O+=".defaultTo(null)";else O+=`.defaultTo(${q.default})`;O+=""}O+=`)
|
|
801
805
|
|
|
802
806
|
`}for(let D of I)O+=` .dropColumn('${D}')
|
|
803
807
|
`;if(U.length||I.length)O+=` .execute();
|
|
804
|
-
`;let
|
|
805
|
-
`;for(let D of j)if(!
|
|
806
|
-
`;let
|
|
808
|
+
`;let B=Object.values(z).map((D)=>D.order),E=Object.values(Q).map((D)=>D.order);if(!KY(B,E))X=!0,O+=Q$(Y.attributes,J);let V=H.indexes||[],j=Y.indexes||[];for(let D of V)if(!j.find((q)=>q.name===D.name))X=!0,O+=` await (db as any).schema.dropIndex('${D.name}').execute()
|
|
809
|
+
`;for(let D of j)if(!V.find((q)=>q.name===D.name))X=!0,O+=fZ(J,D);O+=`}
|
|
810
|
+
`;let v=`${new Date().getTime().toString()}-update-${J}-table.ts`,rY=f.userMigrationsPath(v);if(X)await Bun.write(rY,O),c.success(`Created migration: ${Q6(v)}`)}function Q$(Z,Y){let $=XY(Z),J="",X="";for(let[W]of $){let H=QY(W);if(X)J+=`await sql\`
|
|
807
811
|
ALTER TABLE ${Y}
|
|
808
|
-
MODIFY COLUMN ${H} TEXT NOT NULL AFTER ${
|
|
812
|
+
MODIFY COLUMN ${H} TEXT NOT NULL AFTER ${QY(X)};
|
|
809
813
|
\`.execute(db)
|
|
810
814
|
|
|
811
|
-
`;X=H}return J}function
|
|
812
|
-
`}let $=Y.columns.map((J)=>`\`${
|
|
813
|
-
`}function
|
|
814
|
-
`}function
|
|
815
|
+
`;X=H}return J}function fZ(Z,Y){if(Y.unique||Y.where){let J=Y.unique?"UNIQUE ":"",X=Y.columns.map((H)=>QY(H)).join(", "),W=Y.where?` WHERE ${Y.where}`:"";return` await db.unsafe(\`CREATE ${J}INDEX IF NOT EXISTS "${Y.name}" ON "${Z}" (${X})${W}\`).execute()
|
|
816
|
+
`}let $=Y.columns.map((J)=>`\`${QY(J)}\``).join(", ");return` await (db as any).schema.createIndex('${Y.name}').on('${Z}').columns([${$}]).execute()
|
|
817
|
+
`}function _$(Z){return` await (db as any).schema.createIndex('${Z}_id_index').on('${Z}').column('id').execute()
|
|
818
|
+
`}function O$(Z,Y){return` await (db as any).schema.createIndex('${Z}_${Y}_index').on('${Z}').column(\`${Y}\`).execute()
|
|
815
819
|
|
|
816
|
-
`}function vZ(Z){if(Z===null||Z===void 0)return{NULL:!0};if(typeof Z==="string")return{S:Z};if(typeof Z==="number")return{N:String(Z)};if(typeof Z==="boolean")return{BOOL:Z};if(Array.isArray(Z))return{L:Z.map((Y)=>vZ(Y))};if(typeof Z==="object"){let Y={};for(let[$,J]of Object.entries(Z))Y[$]=vZ(J);return{M:Y}}return{S:String(Z)}}function fZ(Z){if("NULL"in Z&&Z.NULL)return null;if("S"in Z&&Z.S!==void 0)return Z.S;if("N"in Z&&Z.N!==void 0)return Number(Z.N);if("BOOL"in Z&&Z.BOOL!==void 0)return Z.BOOL;if("L"in Z&&Z.L!==void 0)return Z.L.map((Y)=>fZ(Y));if("M"in Z&&Z.M!==void 0){let Y={};for(let[$,J]of Object.entries(Z.M))Y[$]=fZ(J);return Y}if("SS"in Z&&Z.SS!==void 0)return Z.SS;if("NS"in Z&&Z.NS!==void 0)return Z.NS.map((Y)=>Number(Y));if("B"in Z&&Z.B!==void 0)return Z.B;if("BS"in Z&&Z.BS!==void 0)return Z.BS;return null}function h(Z){let Y={};for(let[$,J]of Object.entries(Z))Y[$]=vZ(J);return Y}function uY(Z){let Y={};for(let[$,J]of Object.entries(Z))Y[$]=fZ(J);return Y}class bZ{client;tableName;pkAttribute;skAttribute;entityTypeAttr;delimiter;_entityType;_pkValue;_skCondition;_indexName;_projectionAttrs=[];_filterConditions=[];_limitValue;_scanForward=!0;_consistentRead=!1;_startKey;constructor(Z,Y,$){this.client=Z,this.tableName=Y,this.pkAttribute=$.pkAttribute,this.skAttribute=$.skAttribute,this.entityTypeAttr=$.entityTypeAttribute,this.delimiter=$.keyDelimiter}entity(Z){return this._entityType=Z,this}pk(Z){return this._pkValue=Z,this}get sk(){let Z=this;return{equals(Y){return Z._skCondition={type:"eq",value:Y},Z},beginsWith(Y){return Z._skCondition={type:"begins_with",value:Y},Z},between(Y,$){return Z._skCondition={type:"between",value:Y,value2:$},Z},lt(Y){return Z._skCondition={type:"lt",value:Y},Z},lte(Y){return Z._skCondition={type:"lte",value:Y},Z},gt(Y){return Z._skCondition={type:"gt",value:Y},Z},gte(Y){return Z._skCondition={type:"gte",value:Y},Z}}}index(Z){return this._indexName=Z,this}project(...Z){return this._projectionAttrs.push(...Z),this}filter(Z,Y,$){return this._filterConditions.push({attribute:Z,operator:Y,value:$}),this}where(Z,Y){return this.filter(Z,"=",Y)}whereIn(Z,Y){return this._filterConditions.push({attribute:Z,operator:"IN",values:Y}),this}limit(Z){return this._limitValue=Z,this}asc(){return this._scanForward=!0,this}desc(){return this._scanForward=!1,this}consistent(){return this._consistentRead=!0,this}startFrom(Z){return this._startKey=Z,this}toRequest(){let Z={TableName:this.tableName};if(this._indexName)Z.IndexName=this._indexName;let Y=[],$={},J={},X=0;if(this._pkValue){let W=`#pk${X}`,H=`:pk${X}`;$[W]=this.pkAttribute,J[H]={S:this._pkValue},Y.push(`${W} = ${H}`),X++}if(this._skCondition){let W=`#sk${X}`;switch($[W]=this.skAttribute,this._skCondition.type){case"eq":{let H=`:sk${X}`;J[H]={S:this._skCondition.value},Y.push(`${W} = ${H}`);break}case"begins_with":{let H=`:sk${X}`;J[H]={S:this._skCondition.value},Y.push(`begins_with(${W}, ${H})`);break}case"between":{let H=`:sk${X}a`,G=`:sk${X}b`;J[H]={S:this._skCondition.value},J[G]={S:this._skCondition.value2},Y.push(`${W} BETWEEN ${H} AND ${G}`);break}case"lt":{let H=`:sk${X}`;J[H]={S:this._skCondition.value},Y.push(`${W} < ${H}`);break}case"lte":{let H=`:sk${X}`;J[H]={S:this._skCondition.value},Y.push(`${W} <= ${H}`);break}case"gt":{let H=`:sk${X}`;J[H]={S:this._skCondition.value},Y.push(`${W} > ${H}`);break}case"gte":{let H=`:sk${X}`;J[H]={S:this._skCondition.value},Y.push(`${W} >= ${H}`);break}}X++}if(Y.length>0)Z.KeyConditionExpression=Y.join(" AND ");if(this._filterConditions.length>0){let W=[];for(let H of this._filterConditions){let G=`#flt${X}`;if($[G]=H.attribute,H.operator==="IN"&&H.values){let z=H.values.map((Q,_)=>`:flt${X}_${_}`);H.values.forEach((Q,_)=>{J[`:flt${X}_${_}`]=h({v:Q}).v}),W.push(`${G} IN (${z.join(", ")})`)}else{let z=`:flt${X}`;J[z]=h({v:H.value}).v,W.push(`${G} ${H.operator} ${z}`)}X++}Z.FilterExpression=W.join(" AND ")}if(this._projectionAttrs.length>0){let W=[];for(let H of this._projectionAttrs){let G=`#proj${X}`;$[G]=H,W.push(G),X++}Z.ProjectionExpression=W.join(", ")}if(Object.keys($).length>0)Z.ExpressionAttributeNames=$;if(Object.keys(J).length>0)Z.ExpressionAttributeValues=J;if(this._limitValue!==void 0)Z.Limit=this._limitValue;if(Z.ScanIndexForward=this._scanForward,this._consistentRead)Z.ConsistentRead=!0;if(this._startKey)Z.ExclusiveStartKey=h(this._startKey);return Z}async get(){if(!this.client)throw Error("DynamoDB client not configured. Call dynamo.connection() first.");let Z=this.toRequest();return((this._pkValue!==void 0?await this.client.query(Z):await this.client.scan(Z)).Items??[]).map((J)=>uY(J))}async first(){return this._limitValue=1,(await this.get())[0]}async getAll(){let Z=[],Y;do{if(Y)this._startKey=Y;let $=this.toRequest(),X=this._pkValue!==void 0?await this.client.query($):await this.client.scan($),W=(X.Items??[]).map((H)=>uY(H));Z.push(...W),Y=X.LastEvaluatedKey?uY(X.LastEvaluatedKey):void 0}while(Y);return Z}async count(){if(!this.client)throw Error("DynamoDB client not configured. Call dynamo.connection() first.");let Z=this.toRequest();return Z.Select="COUNT",(this._pkValue!==void 0?await this.client.query(Z):await this.client.scan(Z)).Count??0}}class pZ{client;tableName="";pkAttribute="pk";skAttribute="sk";entityTypeAttr="_et";delimiter="#";entityMappings=new Map;_configured=!1;connection(Z){return this.tableName=Z.table,this.pkAttribute=Z.pkAttribute??"pk",this.skAttribute=Z.skAttribute??"sk",this.entityTypeAttr=Z.entityTypeAttribute??"_et",this.delimiter=Z.keyDelimiter??"#",this._configured=!0,this}isConfigured(){return this._configured}setClient(Z){return this.client=Z,this}getClient(){return this.client}registerEntity(Z){return this.entityMappings.set(Z.entityType,Z),this}registerModel(Z){let Y=Z.name??"Unknown",$=Y.toUpperCase(),J={entityType:Y,pkPattern:`${$}#{id}`,skPattern:`${$}#{id}`};return this.entityMappings.set(Y,J),this}getEntityMapping(Z){return this.entityMappings.get(Z)}entity(Z){if(!this._configured)throw Error("DynamoDB not configured. Call dynamo.connection() first.");return new bZ(this.client,this.tableName,{pkAttribute:this.pkAttribute,skAttribute:this.skAttribute,entityTypeAttribute:this.entityTypeAttr,keyDelimiter:this.delimiter}).entity(Z)}async batchWrite(Z){if(!this.client)throw Error("DynamoDB client not configured. Call setClient() first.");if(!this._configured)throw Error("DynamoDB not configured. Call dynamo.connection() first.");let Y=[];for(let $ of Z)if($.put){let J={...$.put.item,[this.entityTypeAttr]:$.put.entity};Y.push({PutRequest:{Item:h(J)}})}else if($.delete)Y.push({DeleteRequest:{Key:h({[this.pkAttribute]:$.delete.pk,[this.skAttribute]:$.delete.sk})}});if(Y.length>0)await this.client.batchWriteItem({RequestItems:{[this.tableName]:Y}})}async transactWrite(Z){if(!this.client)throw Error("DynamoDB client not configured. Call setClient() first.");if(!this._configured)throw Error("DynamoDB not configured. Call dynamo.connection() first.");let Y=[];for(let $ of Z)if($.put){let J={...$.put.item,[this.entityTypeAttr]:$.put.entity},X={TableName:this.tableName,Item:h(J)};if($.put.condition)X.ConditionExpression=$.put.condition;Y.push({Put:X})}else if($.update){let J={[this.pkAttribute]:$.update.pk};if($.update.sk)J[this.skAttribute]=$.update.sk;let X=[],W={},H={},G=0;if($.update.set){let z=[];for(let[Q,_]of Object.entries($.update.set)){let U=`#set${G}`,I=`:set${G}`;W[U]=Q,H[I]=h({v:_}).v,z.push(`${U} = ${I}`),G++}if(z.length>0)X.push(`SET ${z.join(", ")}`)}if($.update.add){let z=[];for(let[Q,_]of Object.entries($.update.add)){let U=`#add${G}`,I=`:add${G}`;W[U]=Q,H[I]={N:String(_)},z.push(`${U} ${I}`),G++}if(z.length>0)X.push(`ADD ${z.join(", ")}`)}if($.update.remove&&$.update.remove.length>0){let z=[];for(let Q of $.update.remove){let _=`#rem${G}`;W[_]=Q,z.push(_),G++}X.push(`REMOVE ${z.join(", ")}`)}Y.push({Update:{TableName:this.tableName,Key:h(J),UpdateExpression:X.join(" "),ExpressionAttributeNames:W,ExpressionAttributeValues:H}})}else if($.delete){let J={TableName:this.tableName,Key:h({[this.pkAttribute]:$.delete.pk,[this.skAttribute]:$.delete.sk})};if($.delete.condition)J.ConditionExpression=$.delete.condition;Y.push({Delete:J})}else if($.conditionCheck)Y.push({ConditionCheck:{TableName:this.tableName,Key:h({[this.pkAttribute]:$.conditionCheck.pk,[this.skAttribute]:$.conditionCheck.sk}),ConditionExpression:$.conditionCheck.condition}});if(Y.length>0)await this.client.transactWriteItems({TransactItems:Y})}async put(Z,Y){if(!this.client)throw Error("DynamoDB client not configured. Call setClient() first.");let $={...Y,[this.entityTypeAttr]:Z};await this.client.putItem({TableName:this.tableName,Item:h($)})}async get(Z,Y){if(!this.client)throw Error("DynamoDB client not configured. Call setClient() first.");let $={[this.pkAttribute]:Z};if(Y)$[this.skAttribute]=Y;let J=await this.client.getItem({TableName:this.tableName,Key:h($)});if(!J.Item)return;return uY(J.Item)}async delete(Z,Y){if(!this.client)throw Error("DynamoDB client not configured. Call setClient() first.");let $={[this.pkAttribute]:Z};if(Y)$[this.skAttribute]=Y;await this.client.deleteItem({TableName:this.tableName,Key:h($)})}async update(Z,Y,$){if(!this.client)throw Error("DynamoDB client not configured. Call setClient() first.");let J={[this.pkAttribute]:Z};if(Y)J[this.skAttribute]=Y;let X=[],W={},H={},G=0,z=[];for(let[Q,_]of Object.entries($)){let U=`#upd${G}`,I=`:upd${G}`;W[U]=Q,H[I]=h({v:_}).v,z.push(`${U} = ${I}`),G++}if(z.length>0)X.push(`SET ${z.join(", ")}`);await this.client.updateItem({TableName:this.tableName,Key:h(J),UpdateExpression:X.join(" "),ExpressionAttributeNames:W,ExpressionAttributeValues:H})}getTableName(){return this.tableName}getConfig(){return{tableName:this.tableName,pkAttribute:this.pkAttribute,skAttribute:this.skAttribute,entityTypeAttribute:this.entityTypeAttr,keyDelimiter:this.delimiter}}}function Q$(Z,Y="id"){return`${Z.toUpperCase()}#{${Y}}`}function _$(Z,Y){let $={},J=Z.split("#"),X=Y.split("#");for(let W=0;W<J.length;W++){let H=J[W],G=X[W];if(H?.startsWith("{")&&H.endsWith("}")){let z=H.slice(1,-1);$[z]=G??""}}return $}function O$(Z,Y){let $=Z;for(let[J,X]of Object.entries(Y))$=$.replace(`{${J}}`,X);return $}var V$=new pZ;function A$(){return new pZ}import{log as B$}from"@stacksjs/logging";import{database as L$}from"@stacksjs/config";import{path as E$}from"@stacksjs/path";async function K9(){if(!["sqlite","mysql"].includes(I$()))return;if(await $Y("model_audits"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
820
|
+
`}function bZ(Z){if(Z===null||Z===void 0)return{NULL:!0};if(typeof Z==="string")return{S:Z};if(typeof Z==="number")return{N:String(Z)};if(typeof Z==="boolean")return{BOOL:Z};if(Array.isArray(Z))return{L:Z.map((Y)=>bZ(Y))};if(typeof Z==="object"){let Y={};for(let[$,J]of Object.entries(Z))Y[$]=bZ(J);return{M:Y}}return{S:String(Z)}}function pZ(Z){if("NULL"in Z&&Z.NULL)return null;if("S"in Z&&Z.S!==void 0)return Z.S;if("N"in Z&&Z.N!==void 0)return Number(Z.N);if("BOOL"in Z&&Z.BOOL!==void 0)return Z.BOOL;if("L"in Z&&Z.L!==void 0)return Z.L.map((Y)=>pZ(Y));if("M"in Z&&Z.M!==void 0){let Y={};for(let[$,J]of Object.entries(Z.M))Y[$]=pZ(J);return Y}if("SS"in Z&&Z.SS!==void 0)return Z.SS;if("NS"in Z&&Z.NS!==void 0)return Z.NS.map((Y)=>Number(Y));if("B"in Z&&Z.B!==void 0)return Z.B;if("BS"in Z&&Z.BS!==void 0)return Z.BS;return null}function C(Z){let Y={};for(let[$,J]of Object.entries(Z))Y[$]=bZ(J);return Y}function HZ(Z){let Y=C({value:Z}).value;if(!Y)throw Error("Failed to marshal DynamoDB attribute value");return Y}function dY(Z){let Y={};for(let[$,J]of Object.entries(Z))Y[$]=pZ(J);return Y}class CZ{client;tableName;pkAttribute;skAttribute;entityTypeAttr;delimiter;_entityType;_pkValue;_skCondition;_indexName;_projectionAttrs=[];_filterConditions=[];_limitValue;_scanForward=!0;_consistentRead=!1;_startKey;constructor(Z,Y,$){this.client=Z,this.tableName=Y,this.pkAttribute=$.pkAttribute,this.skAttribute=$.skAttribute,this.entityTypeAttr=$.entityTypeAttribute,this.delimiter=$.keyDelimiter}entity(Z){return this._entityType=Z,this}pk(Z){return this._pkValue=Z,this}get sk(){let Z=this;return{equals(Y){return Z._skCondition={type:"eq",value:Y},Z},beginsWith(Y){return Z._skCondition={type:"begins_with",value:Y},Z},between(Y,$){return Z._skCondition={type:"between",value:Y,value2:$},Z},lt(Y){return Z._skCondition={type:"lt",value:Y},Z},lte(Y){return Z._skCondition={type:"lte",value:Y},Z},gt(Y){return Z._skCondition={type:"gt",value:Y},Z},gte(Y){return Z._skCondition={type:"gte",value:Y},Z}}}index(Z){return this._indexName=Z,this}project(...Z){return this._projectionAttrs.push(...Z),this}filter(Z,Y,$){return this._filterConditions.push({attribute:Z,operator:Y,value:$}),this}where(Z,Y){return this.filter(Z,"=",Y)}whereIn(Z,Y){return this._filterConditions.push({attribute:Z,operator:"IN",values:Y}),this}limit(Z){return this._limitValue=Z,this}asc(){return this._scanForward=!0,this}desc(){return this._scanForward=!1,this}consistent(){return this._consistentRead=!0,this}startFrom(Z){return this._startKey=Z,this}toRequest(){let Z={TableName:this.tableName};if(this._indexName)Z.IndexName=this._indexName;let Y=[],$={},J={},X=0;if(this._pkValue){let W=`#pk${X}`,H=`:pk${X}`;$[W]=this.pkAttribute,J[H]={S:this._pkValue},Y.push(`${W} = ${H}`),X++}if(this._skCondition){let W=`#sk${X}`;switch($[W]=this.skAttribute,this._skCondition.type){case"eq":{let H=`:sk${X}`;J[H]={S:this._skCondition.value},Y.push(`${W} = ${H}`);break}case"begins_with":{let H=`:sk${X}`;J[H]={S:this._skCondition.value},Y.push(`begins_with(${W}, ${H})`);break}case"between":{if(this._skCondition.value2===void 0)throw Error("DynamoDB between condition requires a second value");let H=`:sk${X}a`,G=`:sk${X}b`;J[H]={S:this._skCondition.value},J[G]={S:this._skCondition.value2},Y.push(`${W} BETWEEN ${H} AND ${G}`);break}case"lt":{let H=`:sk${X}`;J[H]={S:this._skCondition.value},Y.push(`${W} < ${H}`);break}case"lte":{let H=`:sk${X}`;J[H]={S:this._skCondition.value},Y.push(`${W} <= ${H}`);break}case"gt":{let H=`:sk${X}`;J[H]={S:this._skCondition.value},Y.push(`${W} > ${H}`);break}case"gte":{let H=`:sk${X}`;J[H]={S:this._skCondition.value},Y.push(`${W} >= ${H}`);break}}X++}if(Y.length>0)Z.KeyConditionExpression=Y.join(" AND ");if(this._filterConditions.length>0){let W=[];for(let H of this._filterConditions){let G=`#flt${X}`;if($[G]=H.attribute,H.operator==="IN"&&H.values){let z=H.values.map((Q,_)=>`:flt${X}_${_}`);H.values.forEach((Q,_)=>{J[`:flt${X}_${_}`]=HZ(Q)}),W.push(`${G} IN (${z.join(", ")})`)}else{let z=`:flt${X}`;J[z]=HZ(H.value),W.push(`${G} ${H.operator} ${z}`)}X++}Z.FilterExpression=W.join(" AND ")}if(this._projectionAttrs.length>0){let W=[];for(let H of this._projectionAttrs){let G=`#proj${X}`;$[G]=H,W.push(G),X++}Z.ProjectionExpression=W.join(", ")}if(Object.keys($).length>0)Z.ExpressionAttributeNames=$;if(Object.keys(J).length>0)Z.ExpressionAttributeValues=J;if(this._limitValue!==void 0)Z.Limit=this._limitValue;if(Z.ScanIndexForward=this._scanForward,this._consistentRead)Z.ConsistentRead=!0;if(this._startKey)Z.ExclusiveStartKey=C(this._startKey);return Z}async get(){if(!this.client)throw Error("DynamoDB client not configured. Call dynamo.connection() first.");let Z=this.toRequest();return((this._pkValue!==void 0?await this.client.query(Z):await this.client.scan(Z)).Items??[]).map((J)=>dY(J))}async first(){return this._limitValue=1,(await this.get())[0]}async getAll(){let Z=[],Y;do{if(Y)this._startKey=Y;let $=this.toRequest(),J=this.client;if(!J)throw Error("DynamoDB client is not configured");let W=this._pkValue!==void 0?await J.query($):await J.scan($),H=(W.Items??[]).map((G)=>dY(G));Z.push(...H),Y=W.LastEvaluatedKey?dY(W.LastEvaluatedKey):void 0}while(Y);return Z}async count(){if(!this.client)throw Error("DynamoDB client not configured. Call dynamo.connection() first.");let Z=this.toRequest();return Z.Select="COUNT",(this._pkValue!==void 0?await this.client.query(Z):await this.client.scan(Z)).Count??0}}class cZ{client;tableName="";pkAttribute="pk";skAttribute="sk";entityTypeAttr="_et";delimiter="#";entityMappings=new Map;_configured=!1;connection(Z){return this.tableName=Z.table,this.pkAttribute=Z.pkAttribute??"pk",this.skAttribute=Z.skAttribute??"sk",this.entityTypeAttr=Z.entityTypeAttribute??"_et",this.delimiter=Z.keyDelimiter??"#",this._configured=!0,this}isConfigured(){return this._configured}setClient(Z){return this.client=Z,this}getClient(){return this.client}registerEntity(Z){return this.entityMappings.set(Z.entityType,Z),this}registerModel(Z){let Y=Z.name??"Unknown",$=Y.toUpperCase(),J={entityType:Y,pkPattern:`${$}#{id}`,skPattern:`${$}#{id}`};return this.entityMappings.set(Y,J),this}getEntityMapping(Z){return this.entityMappings.get(Z)}entity(Z){if(!this._configured)throw Error("DynamoDB not configured. Call dynamo.connection() first.");return new CZ(this.client,this.tableName,{pkAttribute:this.pkAttribute,skAttribute:this.skAttribute,entityTypeAttribute:this.entityTypeAttr,keyDelimiter:this.delimiter}).entity(Z)}async batchWrite(Z){if(!this.client)throw Error("DynamoDB client not configured. Call setClient() first.");if(!this._configured)throw Error("DynamoDB not configured. Call dynamo.connection() first.");let Y=[];for(let $ of Z)if($.put){let J={...$.put.item,[this.entityTypeAttr]:$.put.entity};Y.push({PutRequest:{Item:C(J)}})}else if($.delete)Y.push({DeleteRequest:{Key:C({[this.pkAttribute]:$.delete.pk,[this.skAttribute]:$.delete.sk})}});if(Y.length>0)await this.client.batchWriteItem({RequestItems:{[this.tableName]:Y}})}async transactWrite(Z){if(!this.client)throw Error("DynamoDB client not configured. Call setClient() first.");if(!this._configured)throw Error("DynamoDB not configured. Call dynamo.connection() first.");let Y=[];for(let $ of Z)if($.put){let J={...$.put.item,[this.entityTypeAttr]:$.put.entity},X={TableName:this.tableName,Item:C(J)};if($.put.condition)X.ConditionExpression=$.put.condition;Y.push({Put:X})}else if($.update){let J={[this.pkAttribute]:$.update.pk};if($.update.sk)J[this.skAttribute]=$.update.sk;let X=[],W={},H={},G=0;if($.update.set){let z=[];for(let[Q,_]of Object.entries($.update.set)){let U=`#set${G}`,I=`:set${G}`;W[U]=Q,H[I]=HZ(_),z.push(`${U} = ${I}`),G++}if(z.length>0)X.push(`SET ${z.join(", ")}`)}if($.update.add){let z=[];for(let[Q,_]of Object.entries($.update.add)){let U=`#add${G}`,I=`:add${G}`;W[U]=Q,H[I]={N:String(_)},z.push(`${U} ${I}`),G++}if(z.length>0)X.push(`ADD ${z.join(", ")}`)}if($.update.remove&&$.update.remove.length>0){let z=[];for(let Q of $.update.remove){let _=`#rem${G}`;W[_]=Q,z.push(_),G++}X.push(`REMOVE ${z.join(", ")}`)}Y.push({Update:{TableName:this.tableName,Key:C(J),UpdateExpression:X.join(" "),ExpressionAttributeNames:W,ExpressionAttributeValues:H}})}else if($.delete){let J={TableName:this.tableName,Key:C({[this.pkAttribute]:$.delete.pk,[this.skAttribute]:$.delete.sk})};if($.delete.condition)J.ConditionExpression=$.delete.condition;Y.push({Delete:J})}else if($.conditionCheck)Y.push({ConditionCheck:{TableName:this.tableName,Key:C({[this.pkAttribute]:$.conditionCheck.pk,[this.skAttribute]:$.conditionCheck.sk}),ConditionExpression:$.conditionCheck.condition}});if(Y.length>0)await this.client.transactWriteItems({TransactItems:Y})}async put(Z,Y){if(!this.client)throw Error("DynamoDB client not configured. Call setClient() first.");let $={...Y,[this.entityTypeAttr]:Z};await this.client.putItem({TableName:this.tableName,Item:C($)})}async get(Z,Y){if(!this.client)throw Error("DynamoDB client not configured. Call setClient() first.");let $={[this.pkAttribute]:Z};if(Y)$[this.skAttribute]=Y;let J=await this.client.getItem({TableName:this.tableName,Key:C($)});if(!J.Item)return;return dY(J.Item)}async delete(Z,Y){if(!this.client)throw Error("DynamoDB client not configured. Call setClient() first.");let $={[this.pkAttribute]:Z};if(Y)$[this.skAttribute]=Y;await this.client.deleteItem({TableName:this.tableName,Key:C($)})}async update(Z,Y,$){if(!this.client)throw Error("DynamoDB client not configured. Call setClient() first.");let J={[this.pkAttribute]:Z};if(Y)J[this.skAttribute]=Y;let X=[],W={},H={},G=0,z=[];for(let[Q,_]of Object.entries($)){let U=`#upd${G}`,I=`:upd${G}`;W[U]=Q,H[I]=HZ(_),z.push(`${U} = ${I}`),G++}if(z.length>0)X.push(`SET ${z.join(", ")}`);await this.client.updateItem({TableName:this.tableName,Key:C(J),UpdateExpression:X.join(" "),ExpressionAttributeNames:W,ExpressionAttributeValues:H})}getTableName(){return this.tableName}getConfig(){return{tableName:this.tableName,pkAttribute:this.pkAttribute,skAttribute:this.skAttribute,entityTypeAttribute:this.entityTypeAttr,keyDelimiter:this.delimiter}}}function A$(Z,Y="id"){return`${Z.toUpperCase()}#{${Y}}`}function B$(Z,Y){let $={},J=Z.split("#"),X=Y.split("#");for(let W=0;W<J.length;W++){let H=J[W],G=X[W];if(H?.startsWith("{")&&H.endsWith("}")){let z=H.slice(1,-1);$[z]=G??""}}return $}function V$(Z,Y){let $=Z;for(let[J,X]of Object.entries(Y))$=$.replace(`{${J}}`,X);return $}var L$=new cZ;function E$(){return new cZ}import{log as I$}from"@stacksjs/logging";import{database as K$}from"@stacksjs/config";import{path as j$}from"@stacksjs/path";async function F9(){if(!["sqlite","mysql"].includes(R$()))return;if(await JY("model_audits"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
817
821
|
import { sql } from '@stacksjs/database'
|
|
818
822
|
|
|
819
823
|
`;Y+=`export async function up(db: Database<any>) {
|
|
@@ -835,7 +839,7 @@ import { sql } from '@stacksjs/database'
|
|
|
835
839
|
`,Y+=` .columns(['auditable_type', 'auditable_id', 'created_at'])
|
|
836
840
|
`,Y+=` .execute()
|
|
837
841
|
`,Y+=`}
|
|
838
|
-
`;let J=`${new Date().getTime().toString()}-create-model-audits-table.ts`,X=
|
|
842
|
+
`;let J=`${new Date().getTime().toString()}-create-model-audits-table.ts`,X=j$.userMigrationsPath(J);await Bun.write(X,Y),I$.success("Created model_audits table migration")}function R$(){return K$.default||""}import{log as w$}from"@stacksjs/logging";import{database as S$}from"@stacksjs/config";import{path as M$}from"@stacksjs/path";async function k9(){if(["sqlite","mysql"].includes(F$())){if(await JY("errors"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
839
843
|
import { sql } from '@stacksjs/database'
|
|
840
844
|
|
|
841
845
|
`;Y+=`export async function up(db: Database<any>) {
|
|
@@ -852,7 +856,7 @@ import { sql } from '@stacksjs/database'
|
|
|
852
856
|
`,Y+=` .addColumn('updated_at', 'timestamp')
|
|
853
857
|
`,Y+=` .execute()
|
|
854
858
|
`,Y+=`}
|
|
855
|
-
`;let J=`${new Date().getTime().toString()}-create-errors-table.ts`,X=
|
|
859
|
+
`;let J=`${new Date().getTime().toString()}-create-errors-table.ts`,X=M$.userMigrationsPath(J);await Bun.write(X,Y),w$.success("Created errors table")}}function F$(){return S$.default||""}import{err as D$,ok as x$}from"@stacksjs/error-handling";import{existsSync as MY,readdirSync as q$,writeFileSync as T$,mkdirSync as P$}from"fs";import{join as uZ}from"path";import B6 from"process";import GZ from"bun:sqlite";import{env as V6}from"@stacksjs/env";function gZ(){return V6.DB_CONNECTION||"sqlite"}function L6(){return uZ(B6.cwd(),"database","migrations")}function k$(){try{let Z=L6();if(!MY(Z))return!1;return q$(Z).some(($)=>$.includes("create-jobs-table"))}catch{return!1}}async function N$(){let Z=zZ();if(MY(Z))try{let $=new GZ(Z),J=$.query("SELECT name FROM sqlite_master WHERE type='table' AND name='job_batches'").get();return $.close(),J!==null}catch{}if(gZ()!=="sqlite")try{let{db:$}=await Promise.resolve().then(() => (F(),u));return await $.selectFrom("job_batches").select("id").limit(1).execute(),!0}catch{return!1}return!1}function zZ(){let Z=V6.APP_ROOT||B6.cwd();return uZ(Z,"database","stacks.sqlite")}async function y$(){let Z=gZ(),Y=zZ();if(MY(Y))try{let $=new GZ(Y),J=$.query("SELECT name FROM sqlite_master WHERE type='table' AND name='jobs'").get();return $.close(),J!==null}catch{}if(Z!=="sqlite")try{let{db:$}=await Promise.resolve().then(() => (F(),u));return await $.selectFrom("jobs").select("id").limit(1).execute(),!0}catch{return!1}return!1}async function C9(){try{let Z=gZ();if(["sqlite","mysql","postgres"].includes(Z)){if(!k$()){let X="";if(Z==="sqlite")X=`-- Create jobs table
|
|
856
860
|
CREATE TABLE IF NOT EXISTS jobs (
|
|
857
861
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
858
862
|
queue TEXT NOT NULL DEFAULT 'default',
|
|
@@ -880,7 +884,7 @@ CREATE TABLE IF NOT EXISTS failed_jobs (
|
|
|
880
884
|
-- the terminal handlers across worker restarts
|
|
881
885
|
-- (stacksjs/stacks#1883). Each holds JSON for one
|
|
882
886
|
-- PersistentBatchHandler. Nullable so callers that only use the
|
|
883
|
-
-- in-memory
|
|
887
|
+
-- in-memory then(fn) API does not need to populate them.
|
|
884
888
|
CREATE TABLE IF NOT EXISTS job_batches (
|
|
885
889
|
id TEXT PRIMARY KEY,
|
|
886
890
|
name TEXT NOT NULL DEFAULT '',
|
|
@@ -1092,7 +1096,7 @@ CREATE TABLE IF NOT EXISTS queue_circuit_state (
|
|
|
1092
1096
|
paused_at TIMESTAMP,
|
|
1093
1097
|
resume_at TIMESTAMP
|
|
1094
1098
|
);
|
|
1095
|
-
`;let H=`${new Date().getTime().toString()}-create-jobs-table.sql`,G=
|
|
1099
|
+
`;let H=`${new Date().getTime().toString()}-create-jobs-table.sql`,G=L6();if(!MY(G))P$(G,{recursive:!0});let z=uZ(G,H);T$(z,X),console.log("\u2713 Created jobs migration file")}else console.log("\u2713 Jobs migration file already exists");if(!await y$()){console.log(" Running migration...");let X=zZ();if(Z==="sqlite"||MY(X)){let W=new GZ(X);W.run(`CREATE TABLE IF NOT EXISTS jobs (
|
|
1096
1100
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1097
1101
|
queue TEXT NOT NULL DEFAULT 'default',
|
|
1098
1102
|
payload TEXT NOT NULL,
|
|
@@ -1143,7 +1147,7 @@ CREATE TABLE IF NOT EXISTS queue_circuit_state (
|
|
|
1143
1147
|
payload TEXT NOT NULL,
|
|
1144
1148
|
exception TEXT NOT NULL,
|
|
1145
1149
|
failed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
1146
|
-
)`).execute()}console.log("\u2713 Jobs and failed_jobs tables created")}else console.log("\u2713 Jobs tables already exist");if(!await
|
|
1150
|
+
)`).execute()}console.log("\u2713 Jobs and failed_jobs tables created")}else console.log("\u2713 Jobs tables already exist");if(!await N$()){console.log(" Creating job_batches table...");let X=zZ();if(Z==="sqlite"||MY(X)){let W=new GZ(X);W.run(`CREATE TABLE IF NOT EXISTS job_batches (
|
|
1147
1151
|
id TEXT PRIMARY KEY,
|
|
1148
1152
|
name TEXT NOT NULL DEFAULT '',
|
|
1149
1153
|
total_jobs INTEGER NOT NULL DEFAULT 0,
|
|
@@ -1176,7 +1180,7 @@ CREATE TABLE IF NOT EXISTS queue_circuit_state (
|
|
|
1176
1180
|
cancelled_at TIMESTAMP,
|
|
1177
1181
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1178
1182
|
finished_at TIMESTAMP
|
|
1179
|
-
)`).execute()}console.log("\u2713 job_batches table created")}else console.log("\u2713 job_batches table already exists")}return
|
|
1183
|
+
)`).execute()}console.log("\u2713 job_batches table created")}else console.log("\u2713 job_batches table already exists")}return x$("Migration created and executed.")}catch(Z){return D$(Z instanceof Error?Z:Error(String(Z)))}}F();import{randomBytes as h$}from"crypto";import{log as h}from"@stacksjs/logging";import{env as v$}from"@stacksjs/env";function HY(Z){let Y=Z==="postgres",$=Z==="mysql"||Z==="singlestore";return{driver:Z,isPostgres:Y,isMysql:$,isSqlite:!Y&&!$,now:Y||$?"NOW()":"datetime('now')",boolTrue:Y?"true":"1",boolFalse:Y?"false":"0",autoIncrement:Y?"SERIAL":"INTEGER",primaryKey:Y?"PRIMARY KEY":$?"PRIMARY KEY AUTO_INCREMENT":"PRIMARY KEY AUTOINCREMENT",pkColumn:Y?"id SERIAL PRIMARY KEY":$?"id INTEGER PRIMARY KEY AUTO_INCREMENT":"id INTEGER PRIMARY KEY AUTOINCREMENT",nullableTimestamp:$?"TIMESTAMP NULL":"TIMESTAMP",param(X){return Y?`$${X}`:"?"},params(...X){if(Y)return{sql:X.map((G,z)=>`$${z+1}`).join(", "),values:X};return{sql:X.map(()=>"?").join(", "),values:X}}}}function f$(){return v$.DB_CONNECTION||"sqlite"}function b$(Z){return`ALTER TABLE users ADD COLUMN email_verified_at ${Z.nullableTimestamp}`}function p$(Z){return`ALTER TABLE users ADD COLUMN password_changed_at ${Z.nullableTimestamp}`}function C$(Z){return["ALTER TABLE users ADD COLUMN two_factor_secret VARCHAR(255)",`ALTER TABLE users ADD COLUMN two_factor_enabled BOOLEAN NOT NULL DEFAULT ${Z.boolFalse}`]}function c$(){return"ALTER TABLE users ADD COLUMN stripe_id VARCHAR(255)"}async function u$(Z,Y={}){let $=[b$(Z),p$(Z),...C$(Z),c$()];for(let J of $)try{await A.unsafe(J).execute()}catch{if(Y.verbose)h.debug(`[auth-tables] Skipped (already applied or users missing): ${J}`)}try{await A.unsafe("CREATE UNIQUE INDEX IF NOT EXISTS idx_users_stripe_id ON users(stripe_id)").execute()}catch{if(Y.verbose)h.debug("[auth-tables] Skipped users.stripe_id unique index (already applied or users missing)")}}async function o9(Z={}){let Y=f$(),$=HY(Y),{isPostgres:J,boolTrue:X,now:W,pkColumn:H,nullableTimestamp:G}=$;if(Z.verbose)h.info(`Creating auth tables for ${Y}...`);try{if(Z.verbose)h.info("Creating oauth_clients table...");if(await A.unsafe(`
|
|
1180
1184
|
CREATE TABLE IF NOT EXISTS oauth_clients (
|
|
1181
1185
|
${H},
|
|
1182
1186
|
name VARCHAR(255) NOT NULL,
|
|
@@ -1189,7 +1193,7 @@ CREATE TABLE IF NOT EXISTS queue_circuit_state (
|
|
|
1189
1193
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1190
1194
|
updated_at ${G}
|
|
1191
1195
|
)
|
|
1192
|
-
`).execute(),Z.verbose)
|
|
1196
|
+
`).execute(),Z.verbose)h.info("Creating oauth_access_tokens table...");if(await A.unsafe(`
|
|
1193
1197
|
CREATE TABLE IF NOT EXISTS oauth_access_tokens (
|
|
1194
1198
|
${H},
|
|
1195
1199
|
user_id INTEGER NOT NULL,
|
|
@@ -1202,7 +1206,7 @@ CREATE TABLE IF NOT EXISTS queue_circuit_state (
|
|
|
1202
1206
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1203
1207
|
updated_at ${G}
|
|
1204
1208
|
)
|
|
1205
|
-
`).execute(),await
|
|
1209
|
+
`).execute(),await E6("idx_oauth_access_tokens_token","oauth_access_tokens","token"),Z.verbose)h.info("Creating oauth_refresh_tokens table...");if(await A.unsafe(`
|
|
1206
1210
|
CREATE TABLE IF NOT EXISTS oauth_refresh_tokens (
|
|
1207
1211
|
${H},
|
|
1208
1212
|
access_token_id INTEGER NOT NULL,
|
|
@@ -1211,16 +1215,16 @@ CREATE TABLE IF NOT EXISTS queue_circuit_state (
|
|
|
1211
1215
|
expires_at ${G},
|
|
1212
1216
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
1213
1217
|
)
|
|
1214
|
-
`).execute(),await
|
|
1218
|
+
`).execute(),await E6("idx_oauth_refresh_tokens_token","oauth_refresh_tokens","token"),Z.verbose)h.info("Creating password_resets table...");await A.unsafe(`
|
|
1215
1219
|
CREATE TABLE IF NOT EXISTS password_resets (
|
|
1216
1220
|
${H},
|
|
1217
1221
|
email VARCHAR(255) NOT NULL,
|
|
1218
1222
|
token VARCHAR(255) NOT NULL,
|
|
1219
1223
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
1220
1224
|
)
|
|
1221
|
-
`).execute();try{await
|
|
1225
|
+
`).execute();try{await A.unsafe(`
|
|
1222
1226
|
CREATE INDEX IF NOT EXISTS idx_password_resets_email ON password_resets(email)
|
|
1223
|
-
`).execute()}catch{}if(Z.verbose)
|
|
1227
|
+
`).execute()}catch{}if(Z.verbose)h.info("Creating passkeys table...");await A.unsafe(`
|
|
1224
1228
|
CREATE TABLE IF NOT EXISTS passkeys (
|
|
1225
1229
|
id VARCHAR(255) PRIMARY KEY,
|
|
1226
1230
|
cred_public_key TEXT NOT NULL,
|
|
@@ -1235,9 +1239,9 @@ CREATE TABLE IF NOT EXISTS queue_circuit_state (
|
|
|
1235
1239
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1236
1240
|
last_used_at ${G}
|
|
1237
1241
|
)
|
|
1238
|
-
`).execute();try{await
|
|
1242
|
+
`).execute();try{await A.unsafe(`
|
|
1239
1243
|
CREATE INDEX IF NOT EXISTS idx_passkeys_user_id ON passkeys(user_id)
|
|
1240
|
-
`).execute()}catch{}if(Z.verbose)
|
|
1244
|
+
`).execute()}catch{}if(Z.verbose)h.info("Creating webauthn_challenges table...");await A.unsafe(`
|
|
1241
1245
|
CREATE TABLE IF NOT EXISTS webauthn_challenges (
|
|
1242
1246
|
${H},
|
|
1243
1247
|
user_id INTEGER NOT NULL,
|
|
@@ -1246,37 +1250,37 @@ CREATE TABLE IF NOT EXISTS queue_circuit_state (
|
|
|
1246
1250
|
expires_at TIMESTAMP NOT NULL,
|
|
1247
1251
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
1248
1252
|
)
|
|
1249
|
-
`).execute();try{await
|
|
1253
|
+
`).execute();try{await A.unsafe(`
|
|
1250
1254
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_webauthn_challenges_user_purpose ON webauthn_challenges(user_id, purpose)
|
|
1251
|
-
`).execute()}catch{}if(Z.verbose)
|
|
1255
|
+
`).execute()}catch{}if(Z.verbose)h.info("Creating two_factor_challenges table...");await A.unsafe(`
|
|
1252
1256
|
CREATE TABLE IF NOT EXISTS two_factor_challenges (
|
|
1253
1257
|
id VARCHAR(255) PRIMARY KEY,
|
|
1254
1258
|
user_id INTEGER NOT NULL,
|
|
1255
1259
|
expires_at TIMESTAMP NOT NULL,
|
|
1256
1260
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
1257
1261
|
)
|
|
1258
|
-
`).execute();try{await
|
|
1262
|
+
`).execute();try{await A.unsafe(`
|
|
1259
1263
|
CREATE INDEX IF NOT EXISTS idx_two_factor_challenges_user_id ON two_factor_challenges(user_id)
|
|
1260
|
-
`).execute()}catch{}if(Z.verbose)
|
|
1264
|
+
`).execute()}catch{}if(Z.verbose)h.info("Creating two_factor_pending_secrets table...");if(await A.unsafe(`
|
|
1261
1265
|
CREATE TABLE IF NOT EXISTS two_factor_pending_secrets (
|
|
1262
1266
|
user_id INTEGER PRIMARY KEY,
|
|
1263
1267
|
secret VARCHAR(255) NOT NULL,
|
|
1264
1268
|
expires_at TIMESTAMP NOT NULL,
|
|
1265
1269
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
1266
1270
|
)
|
|
1267
|
-
`).execute(),Z.verbose)
|
|
1271
|
+
`).execute(),Z.verbose)h.info("Ensuring users auth columns exist (users may not exist yet on a fresh install \u2014 see ensureUsersAuthColumns)...");if(await u$($,Z),Z.verbose)h.info("Ensuring personal access client exists...");if((await A.unsafe(`
|
|
1268
1272
|
SELECT id FROM oauth_clients WHERE personal_access_client = ${X} LIMIT 1
|
|
1269
|
-
`).execute())?.length===0){let Q=
|
|
1273
|
+
`).execute())?.length===0){let Q=h$(40).toString("hex");if(J)await A.unsafe(`
|
|
1270
1274
|
INSERT INTO oauth_clients (name, secret, provider, redirect, personal_access_client, password_client, revoked, created_at)
|
|
1271
1275
|
VALUES ($1, $2, $3, $4, $5, $6, $7, NOW())
|
|
1272
|
-
`,["Personal Access Client",Q,"local","http://localhost",!0,!1,!1]).execute();else await
|
|
1276
|
+
`,["Personal Access Client",Q,"local","http://localhost",!0,!1,!1]).execute();else await A.unsafe(`
|
|
1273
1277
|
INSERT INTO oauth_clients (name, secret, provider, redirect, personal_access_client, password_client, revoked, created_at)
|
|
1274
1278
|
VALUES (?, ?, ?, ?, ?, ?, ?, ${W})
|
|
1275
|
-
`,["Personal Access Client",Q,"local","http://localhost",1,0,0]).execute();if(Z.verbose)
|
|
1279
|
+
`,["Personal Access Client",Q,"local","http://localhost",1,0,0]).execute();if(Z.verbose)h.success("Personal access client created")}return h.debug("Auth tables migrated successfully"),{success:!0}}catch(z){let Q=z instanceof Error?z.message:String(z);return h.error("Failed to migrate auth tables:",Q),{success:!1,error:Q}}}async function E6(Z,Y,$){try{await A.unsafe(`
|
|
1276
1280
|
CREATE INDEX IF NOT EXISTS ${Z} ON ${Y}(${$}(255))
|
|
1277
|
-
`).execute()}catch{try{await
|
|
1281
|
+
`).execute()}catch{try{await A.unsafe(`
|
|
1278
1282
|
CREATE INDEX IF NOT EXISTS ${Z} ON ${Y}(${$})
|
|
1279
|
-
`).execute()}catch{}}}F();import
|
|
1283
|
+
`).execute()}catch{}}}F();import g$ from"process";import{log as I6}from"@stacksjs/logging";import{path as dZ}from"@stacksjs/path";import{getTableName as d$}from"@stacksjs/orm";import{fs as K6}from"@stacksjs/storage";function m$(){return g$.env.DB_CONNECTION||"sqlite"}function s$(Z){if(Z.isPostgres)return"UUID";if(Z.isMysql)return"VARCHAR(255)";return"TEXT"}function l$(Z,Y){return`ALTER TABLE ${Z} ADD COLUMN uuid ${s$(Y)}`}async function j6(Z){let Y=[];if(!K6.existsSync(Z))return Y;let $=K6.readdirSync(Z,{withFileTypes:!0});for(let J of $){let X=dZ.join(Z,J.name);if(J.isDirectory()){Y.push(...await j6(X));continue}if(!J.name.endsWith(".ts"))continue;if(J.name.startsWith("_")||J.name.startsWith("index"))continue;try{let W=(await import(X)).default;if(W?.name||W?.table)Y.push({filePath:X,model:W})}catch{}}return Y}async function r$(){let Z=[dZ.userModelsPath(),dZ.frameworkPath("defaults/app/Models")],Y=new Set;for(let $ of Z)for(let{filePath:J,model:X}of await j6($)){if(!X.traits?.useUuid)continue;Y.add(d$(X,J))}return[...Y]}async function n$(Z,Y={}){let $=await r$();for(let J of $)try{if(await A.unsafe(l$(J,Z)).execute(),Y.verbose)I6.debug(`[uuid-columns] Added uuid column to ${J}`)}catch{if(Y.verbose)I6.debug(`[uuid-columns] Skipped (already applied or ${J} missing): uuid column`)}}async function GJ(Z={}){await n$(HY(m$()),Z)}F();import{log as mY}from"@stacksjs/logging";import{env as i$}from"@stacksjs/env";function a$(){return i$.DB_CONNECTION||"sqlite"}function o$(Z){let{pkColumn:Y,nullableTimestamp:$}=Z;return`CREATE TABLE IF NOT EXISTS notifications (
|
|
1280
1284
|
${Y},
|
|
1281
1285
|
user_id INTEGER NOT NULL,
|
|
1282
1286
|
type VARCHAR(255) NOT NULL,
|
|
@@ -1284,7 +1288,7 @@ CREATE TABLE IF NOT EXISTS queue_circuit_state (
|
|
|
1284
1288
|
read_at ${$},
|
|
1285
1289
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1286
1290
|
updated_at ${$}
|
|
1287
|
-
)`}function
|
|
1291
|
+
)`}function t$(Z){let{pkColumn:Y,boolTrue:$,nullableTimestamp:J}=Z;return`CREATE TABLE IF NOT EXISTS notification_preferences (
|
|
1288
1292
|
${Y},
|
|
1289
1293
|
user_id INTEGER NOT NULL,
|
|
1290
1294
|
channel VARCHAR(50) NOT NULL,
|
|
@@ -1293,7 +1297,7 @@ CREATE TABLE IF NOT EXISTS queue_circuit_state (
|
|
|
1293
1297
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1294
1298
|
updated_at ${J},
|
|
1295
1299
|
UNIQUE (user_id, channel, category)
|
|
1296
|
-
)`}async function
|
|
1300
|
+
)`}async function e$(Z={}){let Y=a$(),$=HY(Y);if(Z.verbose)mY.info(`Creating notification tables for ${Y}...`);try{if(Z.verbose)mY.info("Creating notifications table...");if(await A.unsafe(o$($)).execute(),await A.unsafe("CREATE INDEX IF NOT EXISTS idx_notifications_user ON notifications (user_id)").execute(),Z.verbose)mY.info("Creating notification_preferences table...");if(await A.unsafe(t$($)).execute(),await A.unsafe("CREATE INDEX IF NOT EXISTS idx_notification_preferences_user ON notification_preferences (user_id)").execute(),Z.verbose)mY.success("Notification tables created");return{success:!0}}catch(J){let X=J instanceof Error?J.message:String(J);return mY.error(`Failed to create notification tables: ${X}`),{success:!1,error:X}}}F();import{log as GY}from"@stacksjs/logging";import{env as Y0}from"@stacksjs/env";function Z0(){return Y0.DB_CONNECTION||"sqlite"}function $0(Z){let{pkColumn:Y,nullableTimestamp:$}=Z;return`CREATE TABLE IF NOT EXISTS roles (
|
|
1297
1301
|
${Y},
|
|
1298
1302
|
name VARCHAR(255) NOT NULL,
|
|
1299
1303
|
guard_name VARCHAR(255) NOT NULL DEFAULT 'web',
|
|
@@ -1301,7 +1305,7 @@ CREATE TABLE IF NOT EXISTS queue_circuit_state (
|
|
|
1301
1305
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1302
1306
|
updated_at ${$},
|
|
1303
1307
|
UNIQUE (name, guard_name)
|
|
1304
|
-
)`}function
|
|
1308
|
+
)`}function J0(Z){let{pkColumn:Y,nullableTimestamp:$}=Z;return`CREATE TABLE IF NOT EXISTS permissions (
|
|
1305
1309
|
${Y},
|
|
1306
1310
|
name VARCHAR(255) NOT NULL,
|
|
1307
1311
|
guard_name VARCHAR(255) NOT NULL DEFAULT 'web',
|
|
@@ -1309,27 +1313,27 @@ CREATE TABLE IF NOT EXISTS queue_circuit_state (
|
|
|
1309
1313
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1310
1314
|
updated_at ${$},
|
|
1311
1315
|
UNIQUE (name, guard_name)
|
|
1312
|
-
)`}function
|
|
1316
|
+
)`}function X0(){return`CREATE TABLE IF NOT EXISTS user_roles (
|
|
1313
1317
|
user_id INTEGER NOT NULL,
|
|
1314
1318
|
role_id INTEGER NOT NULL,
|
|
1315
1319
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1316
1320
|
PRIMARY KEY (user_id, role_id)
|
|
1317
|
-
)`}function
|
|
1321
|
+
)`}function W0(){return`CREATE TABLE IF NOT EXISTS user_permissions (
|
|
1318
1322
|
user_id INTEGER NOT NULL,
|
|
1319
1323
|
permission_id INTEGER NOT NULL,
|
|
1320
1324
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1321
1325
|
PRIMARY KEY (user_id, permission_id)
|
|
1322
|
-
)`}function
|
|
1326
|
+
)`}function H0(){return`CREATE TABLE IF NOT EXISTS role_permissions (
|
|
1323
1327
|
role_id INTEGER NOT NULL,
|
|
1324
1328
|
permission_id INTEGER NOT NULL,
|
|
1325
1329
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1326
1330
|
PRIMARY KEY (role_id, permission_id)
|
|
1327
|
-
)`}async function
|
|
1331
|
+
)`}async function G0(Z={}){let Y=Z0(),$=HY(Y);if(Z.verbose)GY.info(`Creating RBAC tables for ${Y}...`);try{if(Z.verbose)GY.info("Creating roles table...");if(await A.unsafe($0($)).execute(),Z.verbose)GY.info("Creating permissions table...");if(await A.unsafe(J0($)).execute(),Z.verbose)GY.info("Creating user_roles pivot...");if(await A.unsafe(X0()).execute(),Z.verbose)GY.info("Creating user_permissions pivot...");if(await A.unsafe(W0()).execute(),Z.verbose)GY.info("Creating role_permissions pivot...");if(await A.unsafe(H0()).execute(),Z.verbose)GY.success("RBAC tables created");return{success:!0}}catch(J){let X=J instanceof Error?J.message:String(J);return GY.error(`Failed to create RBAC tables: ${X}`),{success:!1,error:X}}}iY();import{existsSync as z0}from"fs";import{dirname as R6}from"path";import{plural as mZ,singular as w6,snakeCase as sY}from"@stacksjs/strings";import{path as S6}from"@stacksjs/path";import{globSync as U0}from"@stacksjs/storage";function lY(Z){let Y=Z.search(/[*?[]/),$=Y===-1?R6(Z):R6(Z.slice(0,Y));if(!z0($))return[];try{return U0(Z,{absolute:!0})}catch{return[]}}async function M6(){let Z=[...lY(S6.userModelsPath("*.ts")),...lY(S6.storagePath("framework/defaults/app/Models/**/*.ts"))],Y=[];for(let $ of Z){let J;try{J=(await import($)).default}catch{continue}if(!J||typeof J!=="object")continue;let X=J.table||mZ(sY(J.name||"")),W=J.belongsTo;if(Array.isArray(W))for(let H of W){let G=typeof H==="string"?H:H?.model??"";if(!G)continue;let z=`${sY(w6(G))}_id`,Q=mZ(sY(G));Y.push({fromTable:X,fromColumn:z,toTable:Q,toColumn:"id",model:J.name||""})}else if(W&&typeof W==="object")for(let H of Object.keys(W)){let G=`${sY(w6(H))}_id`,z=mZ(sY(H));Y.push({fromTable:X,fromColumn:G,toTable:z,toColumn:"id",model:J.name||""})}}return Y}async function F6(){let{db:Z}=await Promise.resolve().then(() => (F(),u)),Y=await D6();if(Y==="sqlite")return O0(Z);if(Y==="mysql")return A0(Z);if(Y==="postgres")return B0(Z);return[]}async function Q0(){let Z=await M6(),Y=await F6(),$=new Set(Y.map((X)=>`${X.fromTable.toLowerCase()}.${X.fromColumn.toLowerCase()}\u2192${X.toTable.toLowerCase()}.${X.toColumn.toLowerCase()}`)),J=Z.filter((X)=>{let W=`${X.fromTable.toLowerCase()}.${X.fromColumn.toLowerCase()}\u2192${X.toTable.toLowerCase()}.${X.toColumn.toLowerCase()}`;return!$.has(W)});return{declared:Z,live:Y,missing:J}}async function _0(Z){if((Z??await D6())!=="sqlite")return{supported:!1,total:0,orphans:[]};let{db:$}=await Promise.resolve().then(() => (F(),u)),J=await $.unsafe("PRAGMA foreign_key_check").execute(),X=Array.isArray(J)?J:[],W=new Map;async function H(_){if(W.has(_))return W.get(_);if(!/^[a-z_]\w*$/i.test(_))return W.set(_,[]),[];let U=await $.unsafe(`PRAGMA foreign_key_list("${_}")`).execute(),I=Array.isArray(U)?U:[];return W.set(_,I),I}let G=new Map;for(let _ of X){let U=_,I=String(U.table??""),O=String(U.parent??"");if(!I||!O)continue;let L=Number(U.fkid??0),B="",E=await H(I);for(let R of E){let v=R;if(Number(v.id)===L&&v.from){B=String(v.from);break}}let V=`${I}\x00${O}\x00${L}`,j=G.get(V);if(!j)j={table:I,column:B,parent:O,count:0,sampleRowids:[]},G.set(V,j);if(j.count++,j.sampleRowids.length<5&&typeof U.rowid==="number")j.sampleRowids.push(U.rowid)}let z=[...G.values()];return{supported:!0,total:z.reduce((_,U)=>_+U.count,0),orphans:z}}async function D6(){let Y=((await import("@stacksjs/env")).env?.DB_CONNECTION??"sqlite").toLowerCase();if(Y==="sqlite"||Y==="mysql"||Y==="postgres")return Y;return"other"}async function O0(Z){let Y=await Z.unsafe("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'"),$=Array.isArray(Y)?Y:[],J=[];for(let X of $){let W=X.name;if(!W)continue;if(!/^[a-z_][\w]*$/i.test(W))continue;let H=await Z.unsafe(`PRAGMA foreign_key_list("${W}")`);for(let G of Array.isArray(H)?H:[]){let z=G;if((z.seq??0)!==0)continue;if(!z.from||!z.to||!z.table)continue;J.push({fromTable:W,fromColumn:z.from,toTable:z.table,toColumn:z.to})}}return J}async function A0(Z){let Y=await Z.unsafe(`
|
|
1328
1332
|
SELECT TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
|
|
1329
1333
|
FROM information_schema.KEY_COLUMN_USAGE
|
|
1330
1334
|
WHERE TABLE_SCHEMA = DATABASE()
|
|
1331
1335
|
AND REFERENCED_TABLE_NAME IS NOT NULL
|
|
1332
|
-
`);return(Array.isArray(Y)?Y:[]).map(($)=>({fromTable:String($.TABLE_NAME??$.table_name??""),fromColumn:String($.COLUMN_NAME??$.column_name??""),toTable:String($.REFERENCED_TABLE_NAME??$.referenced_table_name??""),toColumn:String($.REFERENCED_COLUMN_NAME??$.referenced_column_name??"")})).filter(($)=>$.fromTable&&$.fromColumn&&$.toTable&&$.toColumn)}async function
|
|
1336
|
+
`);return(Array.isArray(Y)?Y:[]).map(($)=>({fromTable:String($.TABLE_NAME??$.table_name??""),fromColumn:String($.COLUMN_NAME??$.column_name??""),toTable:String($.REFERENCED_TABLE_NAME??$.referenced_table_name??""),toColumn:String($.REFERENCED_COLUMN_NAME??$.referenced_column_name??"")})).filter(($)=>$.fromTable&&$.fromColumn&&$.toTable&&$.toColumn)}async function B0(Z){let Y=await Z.unsafe(`
|
|
1333
1337
|
SELECT
|
|
1334
1338
|
kcu.table_name AS from_table,
|
|
1335
1339
|
kcu.column_name AS from_column,
|
|
@@ -1343,13 +1347,13 @@ CREATE TABLE IF NOT EXISTS queue_circuit_state (
|
|
|
1343
1347
|
ON ccu.constraint_name = rc.constraint_name
|
|
1344
1348
|
AND ccu.constraint_schema = rc.constraint_schema
|
|
1345
1349
|
WHERE rc.constraint_schema = 'public'
|
|
1346
|
-
`);return(Array.isArray(Y)?Y:[]).map(($)=>({fromTable:String($.from_table??""),fromColumn:String($.from_column??""),toTable:String($.to_table??""),toColumn:String($.to_column??"")})).filter(($)=>$.fromTable&&$.fromColumn&&$.toTable&&$.toColumn)}import{path as
|
|
1350
|
+
`);return(Array.isArray(Y)?Y:[]).map(($)=>({fromTable:String($.from_table??""),fromColumn:String($.from_column??""),toTable:String($.to_table??""),toColumn:String($.to_column??"")})).filter(($)=>$.fromTable&&$.fromColumn&&$.toTable&&$.toColumn)}import{path as x6}from"@stacksjs/path";import{plural as V0,snakeCase as sZ}from"@stacksjs/strings";async function T6(){let Z=[...lY(x6.userModelsPath("*.ts")),...lY(x6.storagePath("framework/defaults/app/Models/**/*.ts"))],Y=[];for(let $ of Z){let J;try{J=(await import($)).default}catch{continue}if(!J||typeof J!=="object")continue;let X=J.table||V0(sZ(J.name||"")),W=J.name||"",H=J.attributes;if(H&&typeof H==="object"){for(let[z,Q]of Object.entries(H))if(Q&&typeof Q==="object"&&Q.unique===!0)Y.push({table:X,columns:[sZ(z)],model:W,source:"attribute"})}let G=J.indexes;if(Array.isArray(G)){for(let z of G)if(z&&z.unique===!0&&Array.isArray(z.columns)&&z.columns.length>0)Y.push({table:X,columns:z.columns.map((Q)=>sZ(Q)),model:W,source:"index",indexName:z.name})}}return Y}async function P6(Z){let{db:Y}=await Promise.resolve().then(() => (F(),u)),$=Z??await k6();if($==="sqlite")return I0(Y);if($==="mysql")return K0(Y);if($==="postgres")return j0(Y);return[]}async function L0(Z){let Y=Z??await k6();if(Y!=="sqlite"&&Y!=="mysql"&&Y!=="postgres")return{supported:!1,declared:[],live:[],missing:[],skippedTables:[]};let $=await T6(),J=await P6(Y),X=await E0(Y),W=new Map;for(let z of J){let Q=z.table.toLowerCase(),_=q6(z.columns);if(!W.has(Q))W.set(Q,new Set);W.get(Q).add(_)}let H=[],G=new Set;for(let z of $){let Q=z.table.toLowerCase();if(!X.has(Q)){G.add(z.table);continue}let _=q6(z.columns);if(!(W.get(Q)?.has(_)??!1))H.push(z)}return{supported:!0,declared:$,live:J,missing:H,skippedTables:[...G]}}async function E0(Z){let{db:Y}=await Promise.resolve().then(() => (F(),u)),$=[];if(Z==="sqlite"){let J=await Y.unsafe("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'").execute();$=(Array.isArray(J)?J:[]).map((X)=>X.name)}else if(Z==="mysql"){let J=await Y.unsafe("SELECT TABLE_NAME AS name FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE()").execute();$=(Array.isArray(J)?J:[]).map((X)=>X.name??X.TABLE_NAME)}else if(Z==="postgres"){let J=await Y.unsafe("SELECT tablename AS name FROM pg_tables WHERE schemaname = 'public'").execute();$=(Array.isArray(J)?J:[]).map((X)=>X.name??X.tablename)}return new Set($.filter((J)=>typeof J==="string"&&J.length>0).map((J)=>J.toLowerCase()))}function q6(Z){return[...Z].map((Y)=>Y.toLowerCase()).sort().join(",")}async function k6(){let Y=((await import("@stacksjs/env")).env?.DB_CONNECTION??"sqlite").toLowerCase();if(Y==="sqlite"||Y==="mysql"||Y==="postgres")return Y;return"other"}async function I0(Z){let Y=await Z.unsafe("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'").execute(),$=Array.isArray(Y)?Y:[],J=[];for(let X of $){let W=X.name;if(!W)continue;if(!/^[a-z_]\w*$/i.test(W))continue;let H=await Z.unsafe(`PRAGMA index_list("${W}")`).execute();for(let G of Array.isArray(H)?H:[]){let z=G;if(Number(z.unique)!==1||!z.name)continue;if(!/^[a-z_]\w*$/i.test(z.name))continue;let Q=await Z.unsafe(`PRAGMA index_info("${z.name}")`).execute(),_=(Array.isArray(Q)?Q:[]).map((U)=>String(U.name??"")).filter((U)=>U.length>0);if(_.length>0)J.push({table:W,name:z.name,columns:_})}}return J}async function K0(Z){let Y=await Z.unsafe(`
|
|
1347
1351
|
SELECT TABLE_NAME, INDEX_NAME, COLUMN_NAME, SEQ_IN_INDEX
|
|
1348
1352
|
FROM information_schema.STATISTICS
|
|
1349
1353
|
WHERE TABLE_SCHEMA = DATABASE()
|
|
1350
1354
|
AND NON_UNIQUE = 0
|
|
1351
1355
|
ORDER BY TABLE_NAME, INDEX_NAME, SEQ_IN_INDEX
|
|
1352
|
-
`).execute();return
|
|
1356
|
+
`).execute();return N6(Array.isArray(Y)?Y:[],($)=>({table:String($.TABLE_NAME??$.table_name??""),name:String($.INDEX_NAME??$.index_name??""),column:String($.COLUMN_NAME??$.column_name??"")}))}async function j0(Z){let Y=await Z.unsafe(`
|
|
1353
1357
|
SELECT
|
|
1354
1358
|
t.relname AS table_name,
|
|
1355
1359
|
ix.relname AS index_name,
|
|
@@ -1364,4 +1368,4 @@ CREATE TABLE IF NOT EXISTS queue_circuit_state (
|
|
|
1364
1368
|
WHERE i.indisunique = true
|
|
1365
1369
|
AND n.nspname = 'public'
|
|
1366
1370
|
ORDER BY table_name, index_name, seq_in_index
|
|
1367
|
-
`).execute();return
|
|
1371
|
+
`).execute();return N6(Array.isArray(Y)?Y:[],($)=>({table:String($.table_name??""),name:String($.index_name??""),column:String($.column_name??"")}))}function N6(Z,Y){let $=new Map;for(let J of Z){let{table:X,name:W,column:H}=Y(J);if(!X||!W||!H)continue;let G=`${X} ${W}`,z=$.get(G);if(z)z.columns.push(H);else $.set(G,{table:X,name:W,columns:[H]})}return[...$.values()]}import{AsyncLocalStorage as R0}from"async_hooks";var FY=new R0;function w0(){return FY.getStore()!==void 0}function S0(Z){let Y=FY.getStore();if(!Y)return!1;return Y.pending.push(Z),!0}async function M0(Z,Y={}){let $=FY.getStore();if($){$.depth+=1;try{return await Z()}finally{$.depth-=1}}let J={pending:[],depth:1,onError:Y.onError},X;try{X=await FY.run(J,Z)}catch(W){throw J.pending.length=0,W}return await y6(J),X}async function y6(Z){for(let Y=0;Y<Z.pending.length;Y++)try{await Z.pending[Y]()}catch($){if(Z.onError)try{Z.onError($,Y)}catch{}else console.error("[transaction-context] after-commit callback threw:",$)}Z.pending.length=0}async function F0(){let Z=FY.getStore();if(!Z)return 0;let Y=Z.pending.length;return await y6(Z),Y}function D0(){return FY.getStore()?.pending.length??0}import{createQueryBuilder as ZX,setConfig as $X}from"@stacksjs/query-builder";export{r6 as validateDriverConfig,l$ as uuidColumnSql,C$ as usersTwoFactorColumnsSql,c$ as usersStripeIdSql,p$ as usersPasswordChangedAtSql,b$ as usersEmailVerifiedAtSql,dY as unmarshall,O1 as truncateMigrationTables,HY as sqlHelpers,PY as sql,l7 as setQueryTracker,$X as setConfig,D4 as seedModelDirect,N5 as seedModel$,K8 as seed,D8 as scaffoldClassSeedersFromModels,K8 as runSeeders,M0 as runInTransactionScope,G5 as runDatabaseMigration,G8 as runClassSeeders,Z9 as resetSqliteDatabase,g1 as resetPostgresDatabase,D1 as resetMysqlDatabase,z5 as resetDatabase,x8 as renderSeederFile,U8 as renameColumnSafely,U5 as previewPendingMigrations,y7 as preprocessSqliteMigrations,N8 as prepareTextColumnType,y8 as prepareNumberColumnType,h8 as prepareEnumColumnType,t5 as prepareDateTimeColumnType,IY as pluckChanges,B$ as parseKeyPattern,o5 as modelTableName,G0 as migrateRbacTables,e$ as migrateNotificationTables,o9 as migrateAuthTables,n6 as mergeWithDefaults,C as marshall,WY as mapFieldTypeToColumnType,r7 as logQuery,h5 as listSeedableModels,O8 as isProtectedModel,w0 as isInTransaction,KY as isArrayEqual,J4 as initializeDbConfig,JY as hasTableBeenMigrated,x as hasMigrationBeenCreated,UY as getUpvoteTableName,_1 as getTraitTables,P6 as getLiveUniqueIndexes,F6 as getLiveFKs,RY as getLikeableForeignKey,s as getLastMigrationFields,k8 as getExecutedMigrations,T6 as getDeclaredUniques,M6 as getDeclaredFKs,l6 as getConnectionString,t as getConnectionDefaults,i6 as getConfigFromEnv,X9 as generateSqliteMigration,fZ as generateSqliteIndexCreationSQL,u1 as generatePostgresTraitMigrations,d1 as generatePostgresMigration,t8 as generatePostgresIndexCreationSQL,q1 as generateMysqlTraitMigrations,x1 as generateMysqlMigration,_5 as generateMigrations2,Q5 as generateMigrations,A$ as generateKeyPattern,g8 as generateIndexCreationSQL,y5 as freshWithSeed,y5 as freshSeed,r$ as findUuidTables,_0 as findFkOrphans,jY as findDifferingKeys,H$ as fetchTestSqliteFile,ZZ as fetchTables,J9 as fetchSqliteFile,Y$ as fetchPostgresTables,T4 as factoryGenerate,S8 as factory,GJ as ensureUuidColumnsForCurrentDriver,n$ as ensureUuidColumns,u$ as ensureUsersAuthColumns,AZ as ensureDatabaseConfigLoaded,S0 as enqueueAfterCommit,L$ as dynamo,W$ as dropSqliteTables,n8 as dropPostgresTables,C8 as dropMysqlTables,e4 as dropMigrationTables,JZ as dropCommonTables,nZ as driverDefaults,a6 as detectDriver,VY as deleteMigrationFiles,LY as deleteFrameworkModels,A as db,kZ as createTaggablesTable,r4 as createTaggableTable,d6 as createSqliteDatabase,J6 as createQueryLogsTable,ZX as createQueryBuilder,n4 as createPostgresTagsTable,NZ as createPostgresTaggablesTable,X6 as createPostgresQueryLogsTable,W1 as createPostgresPasswordResetsTable,l4 as createPostgresPasskeyMigration,m6 as createPostgresDatabase,t4 as createPostgresCommentsTable,$6 as createPostgresCommentablesPivotTable,Z6 as createPostgresCommentUpvoteMigration,a4 as createPostgresCategorizableTable,$Z as createPasswordResetsTable,s4 as createPasskeyMigration,s6 as createMysqlDatabase,F9 as createModelAuditsTable,C9 as createJobsMigration,k9 as createErrorsTable,E$ as createDynamo,g6 as createDatabase,o4 as createCommentablesTable,A1 as createCommentablesPivotTable,Y6 as createCommentUpvoteMigration,i4 as createCategorizableTable,u8 as createAlterTableMigration,W9 as copyModelFiles,$9 as configureSqlitePragmas,e5 as compareRanges,EY as checkPivotMigration,Y1 as checkIsRequired,V$ as buildKey,w4 as backfillInBatches,L0 as auditUniqueIndexes,Q0 as auditForeignKeys,XY as arrangeColumns,H7 as applySqlitePragmas,z8 as addColumnSafely,Y7 as acquireDbConfigLock,D0 as __pendingAfterCommitCount,F0 as __flushAfterCommitNow,j4 as Seeder,BZ as SQLITE_BOOTSTRAP_PRAGMAS,v0 as REDIS_DEFAULTS,_8 as PROTECTED_MODELS,CZ as EntityQueryBuilder,o as Database,aZ as DB_USERS,iZ as DB_PORTS,UZ as DB_NAMES,h0 as DB_HOST_DEFAULT,f0 as AWS_DEFAULTS};
|