@stacksjs/database 0.70.87 → 0.70.90
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/auth-tables.js +220 -0
- package/dist/class-seeder.js +116 -0
- package/dist/column.d.ts +17 -0
- package/dist/column.js +26 -0
- package/dist/custom/audits.js +57 -0
- package/dist/custom/errors.js +48 -0
- package/dist/custom/index.js +3 -0
- package/dist/custom/jobs.js +449 -0
- package/dist/database.js +178 -0
- package/dist/defaults.js +48 -0
- package/dist/driver-config.js +144 -0
- package/dist/drivers/defaults/index.js +2 -0
- package/dist/drivers/defaults/passwords.js +106 -0
- package/dist/drivers/defaults/traits.js +1125 -0
- package/dist/drivers/dynamodb.js +607 -0
- package/dist/drivers/helpers.js +206 -0
- package/dist/drivers/index.js +9 -0
- package/dist/drivers/mysql.js +322 -0
- package/dist/drivers/postgres.js +411 -0
- package/dist/drivers/sqlite.js +397 -0
- package/dist/factory.js +51 -0
- package/dist/fk-audit.js +181 -0
- package/dist/index.js +55 -1263
- package/dist/migration-lock.js +143 -0
- package/dist/migrations.js +528 -0
- package/dist/notification-tables.js +54 -0
- package/dist/query-logger.js +213 -0
- package/dist/query-parser.js +93 -0
- package/dist/rbac-tables.js +84 -0
- package/dist/safe-migrations.js +59 -0
- package/dist/schema.d.ts +4 -0
- package/dist/schema.js +10 -0
- package/dist/seed-scaffold.js +144 -0
- package/dist/seeder.js +363 -0
- package/dist/sql-helpers.js +24 -0
- package/dist/table.d.ts +7 -0
- package/dist/table.js +26 -0
- package/dist/tools/setup.d.ts +1 -0
- package/dist/tools/setup.js +6 -0
- package/dist/transaction-context.js +62 -0
- package/dist/types.js +23 -0
- package/dist/unique-audit.js +174 -0
- package/dist/utils.js +163 -0
- package/dist/uuid-columns.js +68 -0
- package/dist/validators.js +122 -0
- package/package.json +11 -11
package/dist/index.js
CHANGED
|
@@ -1,1263 +1,55 @@
|
|
|
1
|
-
|
|
2
|
-
var h0=Object.defineProperty;var p0=(Z)=>Z;function u0(Z,Y){this[Z]=p0.bind(null,Y)}var c0=(Z,Y)=>{for(var $ in Y)h0(Z,$,{get:Y[$],enumerable:!0,configurable:!0,set:u0.bind(Y,$)})};var AZ=(Z,Y)=>()=>(Z&&(Y=Z(Z=0)),Y);var d=import.meta.require;function m(Z,Y){let $=Y??{};switch(Z){case"sqlite":return{database:$.DB_DATABASE_PATH||dY.sqlitePath,prefix:""};case"mysql":return{database:$.DB_DATABASE||dY.default,host:$.DB_HOST||"127.0.0.1",port:$.DB_PORT||RZ.mysql,username:$.DB_USERNAME||OZ.mysql,password:$.DB_PASSWORD||"",prefix:""};case"postgres":return{database:$.DB_DATABASE||dY.default,host:$.DB_HOST||"127.0.0.1",port:$.DB_PORT||RZ.postgres,username:$.DB_USERNAME||OZ.postgres,password:$.DB_PASSWORD||"",prefix:""};default:return{database:":memory:"}}}var z5="127.0.0.1",RZ,dY,OZ,G5,H5;var MY=AZ(()=>{RZ={mysql:3306,postgres:5432,sqlite:0},dY={default:"stacks",sqlitePath:"database/stacks.sqlite",sqliteTestingPath:"database/stacks_testing.sqlite"},OZ={mysql:"root",postgres:"postgres",sqlite:""},G5={host:"localhost",port:6379},H5={region:"us-east-1"}});var e={};c0(e,{setConfig:()=>wZ,initializeDbConfig:()=>kZ,ensureDatabaseConfigLoaded:()=>lY,db:()=>K,applySqlitePragmas:()=>n0,acquireDbConfigLock:()=>g0,SQLITE_BOOTSTRAP_PRAGMAS:()=>rY});import{AsyncLocalStorage as b0}from"async_hooks";import{createQueryBuilder as C0,setConfig as wZ}from"@stacksjs/query-builder";import{env as AY}from"@stacksjs/env";import{applySqlitePragmas as n0,SQLITE_BOOTSTRAP_PRAGMAS as rY}from"@stacksjs/query-builder";function g0(){let Z=()=>{},Y=new Promise((X)=>{Z=X}),$=gY.then(()=>Z);return gY=gY.then(()=>Y),$}function kZ(Z){if(Z?.app?.env)SZ=Z.app.env;if(Z?.database?.default)xZ=Z.database.default;if(Z?.database)qZ=Z.database;mY(),ZY=null}function DZ(){return SZ}function MZ(){return xZ}function s0(){return qZ}function yZ(){let Z=MZ();if(Z==="sqlite")return"sqlite";if(Z==="mysql")return"mysql";if(Z==="singlestore")return"singlestore";if(Z==="postgres")return"postgres";return"sqlite"}function m0(){let Z=MZ(),Y=s0(),$=DZ();if(Z==="sqlite"){let X=$!=="testing"?"database/stacks.sqlite":"database/stacks_testing.sqlite";return{database:Y.connections?.sqlite?.database??X}}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 X=Y.connections?.postgres?.name??"stacks";return{database:$==="testing"?`${X}_testing`:X,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 mY(){let Z=yZ(),Y=m0();wZ({dialect:Z,database:Y,verbose:DZ()!=="production",timestamps:{createdAt:"created_at",updatedAt:"updated_at",defaultOrderColumn:"created_at"},softDeletes:{enabled:!0,column:"deleted_at",defaultFilter:!0}})}function FZ(){if(!sY)sY=(async()=>{try{let{config:Z,overridesReady:Y}=await import("@stacksjs/config");if(await Y,Z)kZ(Z),ZY=null}catch{}})();return sY}async function lY(){await FZ()}function l0(Z){if(BZ.getStore())return Z();let Y=jZ.then(()=>BZ.run(!0,Z));return jZ=Y.then(()=>{return},()=>{return}),Y}function r0(Z){let Y=Z.transaction.bind(Z);Z.transaction=(...$)=>l0(()=>Y(...$))}function a0(){if(!ZY){if(mY(),ZY=C0(),yZ()==="sqlite")r0(ZY)}return ZY}var d0,p,EY,SZ,xZ,qZ,gY,ZY=null,sY=null,BZ,jZ,K;var D=AZ(()=>{MY();d0=m("sqlite",AY),p=m("mysql",AY),EY=m("postgres",AY),SZ=AY.APP_ENV||"local",xZ=AY.DB_CONNECTION||"sqlite",qZ={connections:{sqlite:{database:d0.database,prefix:""},mysql:{name:p.database,host:p.host,username:p.username,password:p.password,port:p.port,prefix:""},singlestore:{name:p.database,host:p.host,username:p.username,password:p.password,port:p.port,prefix:""},postgres:{name:EY.database,host:EY.host,username:EY.username,password:EY.password,port:EY.port,prefix:""}}},gY=Promise.resolve();mY();BZ=new b0,jZ=Promise.resolve();FZ();K=new Proxy({},{get(Z,Y){let $=a0(),X=$[Y];if(typeof X==="function")return X.bind($);return X}})});D();function TZ(Z,...Y){let $=[],X=[];for(let J=0;J<Z.length;J++)if($.push(Z[J]),J<Y.length)if(Y[J]&&typeof Y[J]==="object"&&"raw"in Y[J])$.push(Y[J].raw);else $.push("?"),X.push(Y[J]);return{sql:$.join(""),parameters:X}}TZ.raw=function(Y){return{raw:Y}};TZ.ref=function(Y){return{raw:Y}};D();import{existsSync as eY,mkdirSync as L1,readdirSync as FY,readFileSync as hZ,unlinkSync as E1,writeFileSync as pZ}from"fs";import{dirname as A1,join as l}from"path";import{log as u}from"@stacksjs/logging";import{err as TY,handleError as PY,ok as $Y}from"@stacksjs/error-handling";import{path as jY}from"@stacksjs/path";import{createQueryBuilder as uZ,executeMigration as R1,generateMigration as tY,resetConnection as yY,resetDatabase as O1,setConfig as cZ}from"@stacksjs/query-builder";import{Buffer as o0}from"buffer";import{createHash as i0}from"crypto";import{closeSync as e0,openSync as t0,statSync as Y1,unlinkSync as PZ,writeFileSync as Z1}from"fs";import $1 from"process";import{userDatabasePath as X1}from"@stacksjs/path";var J1=30000,nY=100,oY=2000,W1=60000,aY="stacks_migrations";async function NZ(Z,Y,$={}){let X=$.timeoutMs??J1;if(Z!=="sqlite"&&Z!=="postgres"&&Z!=="mysql")throw Error(`[migration-lock] unknown dialect: ${String(Z)}`);if(Z==="sqlite")return Q1($.sqliteLockPath,X);if(!Y)throw Error(`[migration-lock] ${Z} requires a database connection to acquire the lock`);if(Z==="postgres")return G1(Y,X);return H1(Y,X)}function z1(){let Z=i0("sha256").update(aY).digest(),Y=Z.readInt32BE(0),$=Z.readInt32BE(4);return{key1:Y,key2:$}}async function G1(Z,Y){let{key1:$,key2:X}=z1(),J=Date.now(),W=nY;while(!0){let z=await Z.unsafe(`SELECT pg_try_advisory_lock(${$}, ${X}) AS acquired`);if(V1(z,"acquired"))return{release:async()=>{try{await Z.unsafe(`SELECT pg_advisory_unlock(${$}, ${X})`)}catch{}}};if(Date.now()-J>=Y)throw Error("[migration-lock] another migration is in progress \u2014 could not acquire postgres advisory lock within timeout");await iY(W),W=Math.min(W*2,oY)}}async function H1(Z,Y){let $=Date.now(),X=nY;while(!0){let J=await Z.unsafe(`SELECT GET_LOCK('${aY}', 0) AS acquired`);if(_1(J,"acquired")===1)return{release:async()=>{try{await Z.unsafe(`SELECT RELEASE_LOCK('${aY}')`)}catch{}}};if(Date.now()-$>=Y)throw Error("[migration-lock] another migration is in progress \u2014 could not acquire MySQL named lock within timeout");await iY(X),X=Math.min(X*2,oY)}}function U1(){return X1(".migration.lock")}async function Q1(Z,Y){let $=Z??U1(),X=Date.now(),J=nY;while(!0){if(I1($)){let W=!1;return{release:async()=>{if(W)return;W=!0;try{PZ($)}catch{}}}}if(K1($),Date.now()-X>=Y)throw Error(`[migration-lock] another migration is in progress \u2014 lock file ${$} held within timeout`);await iY(J),J=Math.min(J*2,oY)}}function I1(Z){try{let Y=t0(Z,"wx");try{let $=JSON.stringify({pid:$1.pid,startedAt:new Date().toISOString()});Z1(Y,o0.from($,"utf8"))}finally{e0(Y)}return!0}catch(Y){if(Y.code==="EEXIST")return!1;throw Y}}function K1(Z){try{let Y=Y1(Z);if(Date.now()-Y.mtimeMs>W1)try{PZ(Z)}catch{}}catch{}}function iY(Z){let Y=Z*(1+Math.random()*0.25);return new Promise(($)=>setTimeout($,Y))}function V1(Z,Y){let $=vZ(Z);if(!$)return!1;let X=$[Y];return X===!0||X===1||X==="1"||X==="t"}function _1(Z,Y){let $=vZ(Z);if(!$)return null;let X=$[Y];if(typeof X==="number")return X;if(typeof X==="string"&&/^-?\d+$/.test(X))return Number.parseInt(X,10);return null}function vZ(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}MY();import{env as NY}from"@stacksjs/env";var R={info:(...Z)=>typeof u?.info==="function"?u.info(...Z):console.log(...Z),success:(Z)=>typeof u?.success==="function"?u.success(Z):console.log(Z),warn:(Z)=>typeof u?.warn==="function"?u.warn(Z):console.warn(Z),error:(...Z)=>typeof u?.error==="function"?u.error(...Z):console.error(...Z),debug:(...Z)=>typeof u?.debug==="function"?u.debug(...Z):console.debug(...Z)},B1=NY.DB_CONNECTION||"sqlite",j1=m("sqlite",NY),RY=m("mysql",NY),OY=m("postgres",NY),BY={default:B1,connections:{sqlite:{database:j1.database,prefix:""},mysql:{name:RY.database,host:RY.host,username:RY.username,password:RY.password,port:RY.port,prefix:""},postgres:{name:OY.database,host:OY.host,username:OY.username,password:OY.password,port:OY.port,prefix:""}}};function bZ(){return BY.default||"sqlite"}function r(){let Z=bZ();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 YZ(){return bZ()==="singlestore"?"singlestore":r()}function wY(){let Z=r(),Y=BY.connections[Z];cZ({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||""}}),yY()}function ZZ(){let Z=jY.userModelsPath();return{modelsDir:Z,skip:!eY(Z)}}function w1(){let Z=l(process.cwd(),"database","migrations"),Y;try{Y=FY(Z).filter((A)=>A.endsWith(".sql"))}catch{return}let $=[],X=(A,V)=>{R.info(`Skipping migration on SQLite (${V}): ${A}`),$.push(A)},J=(A,V,L)=>{R.info(`Dropping no-op migration (${L}): ${A}`);try{E1(V)}catch{}$.push(A)},W=[],z=/^\s*ALTER\s+TABLE\s+.+\s+ADD\s+CONSTRAINT\s+/i,H=/^\s*CREATE\s+TYPE\s+/i,I=/^\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,E=/^\s*CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?["']?(\w+)["']?/i,G=new Map;for(let A of Y){let V=A.match(/^\d+-create-(\w+)-table\.sql$/);if(!V||!V[1])continue;let L=V[1],_=G.get(L);if(!_||A<_)G.set(L,A)}let S=l(process.cwd(),BY.connections.sqlite.database||"stacks.db"),U=null;if(eY(S))try{let{Database:A}=d("bun:sqlite");U=new A(S,{readonly:!0})}catch{}for(let A of Y){R.debug(`[migration] Running: ${A}`);let V=l(Z,A),_=hZ(V,"utf-8").split(";").map((O)=>O.trim()).filter((O)=>O.length>0&&!O.startsWith("--"));if(_.length===0)continue;let x=_[0],B=x?x.match(E):null;if(B&&B[1]){let O=B[1],h=G.get(O);if(h&&h!==A){J(A,V,`duplicate create-table for "${O}" (kept ${h})`);continue}}if(_.every((O)=>z.test(O))){X(A,"SQLite does not support ALTER TABLE ADD CONSTRAINT");continue}if(_.every((O)=>H.test(O))){X(A,"SQLite does not support CREATE TYPE (enum types)");continue}let w=_.map((O)=>O.match(I)?.[1]).filter((O)=>Boolean(O));if(U&&w.length===_.length){let O=U.prepare("SELECT name FROM sqlite_master WHERE type = 'index' AND name = ?");if(w.filter((i)=>!O.get(i)).length>0)R.info(`Re-queueing unique-index migration (index missing from database): ${A}`),W.push(A);continue}if(_.some((O)=>Q.test(O))){let O=!1,h=[];for(let i of _){let _Y=i.match(Q);if(_Y&&_Y[1]&&_Y[2]){let DY=_Y[1],LY=_Y[2];if(!U){R.info(`Skipping DROP COLUMN "${LY}" \u2014 no database exists yet: ${A}`),O=!0;continue}try{let v0=DY.replace(/[^a-zA-Z0-9_]/g,""),EZ=U.prepare(`PRAGMA table_info("${v0}")`).all();if(EZ.length===0){R.info(`Skipping DROP COLUMN "${LY}" \u2014 table "${DY}" does not exist yet: ${A}`),O=!0;continue}if(!EZ.some((f0)=>f0.name===LY)){R.info(`Skipping DROP COLUMN "${LY}" from "${DY}" \u2014 column does not exist: ${A}`),O=!0;continue}}catch{R.info(`Skipping DROP COLUMN "${LY}" \u2014 table "${DY}" not found: ${A}`),O=!0;continue}}h.push(i)}if(O){if(h.length===0)J(A,V,"columns already absent from table");else pZ(V,`${h.join(`;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
`;pZ(G,S),R.debug(`[migration] Wrote ${E} (${Q.length} stmt${Q.length===1?"":"s"})`),z+=1,H+=1}return z}function F1(Z){let Y=new Map,$=(X,J)=>{let W=Y.get(X)??[];W.push(J),Y.set(X,W)};for(let X of Z){let J=X.trim();if(!J)continue;let W=J.match(/^\s*CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?["`]?(\w+)["`]?/i);if(W){$(`create-${W[1]}-table`,J);continue}let z=J.match(/^\s*ALTER\s+TABLE\s+["`]?(\w+)["`]?\s+(?:ADD\s+COLUMN\s+["`]?(\w+)["`]?|DROP\s+COLUMN\s+["`]?(\w+)["`]?|ADD\s+CONSTRAINT)/i);if(z){$(`alter-${z[1]}-${z[2]||z[3]||"constraint"}`,J);continue}let H=J.match(/^\s*CREATE\s+(?:UNIQUE\s+)?INDEX\s+(?:IF\s+NOT\s+EXISTS\s+)?["`]?(\w+)["`]?\s+ON\s+["`]?(\w+)["`]?/i);if(H){$(`create-${H[1]}-index-in-${H[2]}`,J);continue}let I=J.match(/^\s*DROP\s+TABLE\s+(?:IF\s+EXISTS\s+)?["`]?(\w+)["`]?/i);if(I){$(`drop-${I[1]}-table`,J);continue}$("auto-misc",J)}return[...Y.entries()].map(([X,J])=>({label:X,statements:J}))}function T1(Z){let Y=0;try{for(let $ of FY(Z)){let X=$.match(/^(\d+)-/);if(X?.[1])Y=Math.max(Y,Number.parseInt(X[1],10))}}catch{}return Y+1}async function p5(){try{R.info("Generating fresh migrations..."),wY();let Z=r(),{modelsDir:Y,skip:$}=ZZ();if($)return R.info("No app/Models directory found; using committed framework migrations"),$Y("Migrations generated");return await tY(Y,{dialect:YZ(),full:!0,dryRun:!0}),R.success("Migrations generated"),$Y("Migrations generated")}catch(Z){return TY(PY("Fresh migration generation failed",Z))}}D();import{log as j}from"@stacksjs/logging";import{faker as $Z}from"@stacksjs/faker";import{path as xY}from"@stacksjs/path";import{hashMake as P1}from"@stacksjs/security";import{fs as dZ}from"@stacksjs/storage";function XZ(Z){return xY.frameworkPath(`defaults/app/Models/${Z||""}`)}var N1=Object.freeze(["OauthClient","OauthAccessToken","OauthRefreshToken","PersonalAccessToken"]);function v1(Z){return N1.includes(Z)}function JZ(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 SY(Z,Y=!1){let $=[];if(!dZ.existsSync(Z))return $;let X=dZ.readdirSync(Z,{withFileTypes:!0});for(let J of X){let W=xY.join(Z,J.name);if(J.isDirectory()&&Y){let z=await SY(W,!0);$.push(...z);continue}if(!J.name.endsWith(".ts")||J.name.startsWith("index")||J.name.startsWith("_"))continue;try{let z=await import(W),H=z.default||z;if(!H)continue;let I=H.traits?.useSeeder??H.traits?.seedable;if(!I)continue;let Q=10,E=[];if(typeof I==="object"&&"count"in I){let U=I;Q=U.count,E=U.fixtures??[]}let G=H.name||J.name.replace(".ts",""),S=H.table||JZ(G)+"s";$.push({name:G,table:S,count:Math.max(Q,E.length),fixtures:E,attributes:H.attributes||{},model:H,filePath:W})}catch(z){j.error(`Failed to load model ${J.name}:`,z)}}return $}async function gZ(Z,Y=!1,$=!1){let X=XZ(),J=await SY(Z,!1);if(J.length>0&&!$)return J;let W=await SY(X,!0),z=new Map;for(let H of W)z.set(H.name,H);for(let H of J){if(z.has(H.name)&&Y)j.info(` User model "${H.name}" overrides default`);z.set(H.name,H)}return Array.from(z.values())}function f1(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 h1(Z,Y,$=!1){let X={};for(let[J,W]of Object.entries(Z)){let z=JZ(J),H;if(W.factory&&typeof W.factory==="function")try{H=W.factory($Z)}catch(I){let Q=I instanceof Error?I.message:String(I);if($)j.warn(` Factory failed for ${Y}.${J}: ${Q}`);if(W.default!==void 0)H=W.default;else H=p1(J)}else if(W.default!==void 0)H=W.default;else continue;if(f1(J,W)&&typeof H==="string")try{H=await P1(H,{algorithm:"bcrypt"})}catch(I){let Q=I instanceof Error?I.message:String(I);if($)j.warn(` Failed to hash password for ${Y}.${J}: ${Q}`)}X[z]=H}return X}function p1(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 $Z.internet.email();if(Y.includes("name"))return $Z.person.fullName();return null}function u1(Z){let Y={};for(let[$,X]of Object.entries(Z))Y[JZ($)]=X;return Y}async function c1(Z,Y=!1){let $=[];for(let X=0;X<Z.count;X++){let J=await h1(Z.attributes,Z.name,Y&&X===0),W=Z.fixtures[X];$.push(W?{...J,...u1(W)}:J)}return $}function m5(Z,Y){return WZ(Z,Y)}async function WZ(Z,Y){let $=Date.now();try{try{await K.selectFrom(Z.table).limit(0).execute()}catch(z){let H=z?.message||"";if(H.includes("does not exist")||H.includes("no such table")||H.includes("doesn't exist"))return j.info(` Skipping ${Z.name}: table "${Z.table}" does not exist`),{model:Z.name,table:Z.table,count:0,success:!0,duration:Date.now()-$};throw z}if(!Y.fresh){if(await K.selectFrom(Z.table).selectAll().limit(1).executeTakeFirst()){if(Y.verbose)j.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 X=await c1(Z,Y.verbose);if(X.length===0)return{model:Z.name,table:Z.table,count:0,success:!0,duration:Date.now()-$};if(Y.fresh)try{if(await K.deleteFrom(Z.table).execute(),Y.verbose)j.info(` Truncated table: ${Z.table}`)}catch{}let J=100,W=0;for(let z=0;z<X.length;z+=J){let H=X.slice(z,z+J);await K.insertInto(Z.table).values(H).execute(),W+=H.length}if(Y.verbose)j.success(` Seeded ${Z.name}: ${W} records`);return{model:Z.name,table:Z.table,count:W,success:!0,duration:Date.now()-$}}catch(X){let J=X instanceof Error?X.message:String(X);if(Y.verbose)j.error(` Failed to seed ${Z.name}: ${J}`);return{model:Z.name,table:Z.table,count:0,success:!1,error:J,duration:Date.now()-$}}}function b1(Z){let Y={User:0,Team:1,Project:2};return Z.sort(($,X)=>{let J=Y[$.name]??10,W=Y[X.name]??10;return J-W})}async function C1(Z={}){let Y=Date.now();await lY();let $=Z.modelsDir||xY.userModelsPath(),X=Z.verbose??!0;if(X)j.info("Seeding database using model factories..."),j.info(`User models directory: ${$}`),j.info(`Default models directory: ${XZ()}`);let J=await gZ($,X,Z.includeDefaults??!1);if(J.length===0)return j.warn("No seedable models found in defaults or user directories"),{total:0,successful:0,failed:0,results:[],duration:Date.now()-Y};if(j.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: ${J.map((Q)=>Q.name).join(", ")}`),Z.only&&Z.only.length>0)J=J.filter((Q)=>Z.only.includes(Q.name));if(Z.except&&Z.except.length>0)J=J.filter((Q)=>!Z.except.includes(Q.name));if(!Z.fresh&&!Z.allowProtected){let Q=[];if(J=J.filter((E)=>{if(v1(E.name))return Q.push(E),!1;return!0}),Q.length>0)j.info(`Skipped ${Q.length} protected auth model(s) to avoid invalidating live sessions: ${Q.map((E)=>E.name).join(", ")}`),j.info(" Re-run with --fresh (truncates tables first) or --allow-protected to include them.")}if(J=b1(J),X)j.info(`Found ${J.length} seedable model(s)`);let W=[];for(let Q of J){if(X)j.info(`Seeding ${Q.name} (${Q.count} records)...`);try{let E=await WZ(Q,Z);W.push(E)}catch(E){let G=E instanceof Error?E.message:String(E);if(X)j.error(` Unexpected error seeding ${Q.name}: ${G}`);W.push({model:Q.name,table:Q.table,count:0,success:!1,error:G,duration:0})}}let z=W.filter((Q)=>Q.success).length,H=W.filter((Q)=>!Q.success).length,I=W.reduce((Q,E)=>Q+E.count,0);if(X)if(j.info(""),H===0)j.success("Database seeded successfully!"),j.info(` Total records: ${I}`),j.info(` Models seeded: ${z}`);else j.warn(`Seeding completed with ${H} failure(s)`),j.info(` Successful: ${z}`),j.info(` Failed: ${H}`);return{total:W.length,successful:z,failed:H,results:W,duration:Date.now()-Y}}async function l5(Z,Y={}){let $=xY.userModelsPath(),J=(await gZ($,Y.verbose)).find((W)=>W.name===Z);if(!J)throw Error(`Model not found: ${Z}`);if(Y.count)J.count=Y.count;return WZ(J,{fresh:Y.fresh,verbose:Y.verbose??!0})}async function r5(Z={}){return C1({...Z,fresh:!0})}async function a5(){let Z=xY.userModelsPath(),Y=XZ(),$=await SY(Y,!0),X=await SY(Z,!1),J=[],W=new Set;for(let z of X)J.push({name:z.name,table:z.table,count:z.count,source:"user"}),W.add(z.name);for(let z of $)if(!W.has(z.name))J.push({name:z.name,table:z.table,count:z.count,source:"default"});return J}D();import{log as tZ}from"@stacksjs/logging";import{getTableName as d1}from"@stacksjs/orm";import{path as g}from"@stacksjs/path";import{fs as XY,globSync as Y0}from"@stacksjs/storage";import{plural as g1,snakeCase as s1}from"@stacksjs/strings";function sZ(Z){return Z.name==="string"}function mZ(Z){return Z.name==="number"}function lZ(Z){return Z.name==="enum"}function rZ(Z){return Z.name==="boolean"}function aZ(Z){return Z.name==="date"}function nZ(Z){return Z.name==="unix"}function oZ(Z){return Z.name==="float"}function iZ(Z){return Z.name==="datetime"}function eZ(Z){return Z.name==="timestamp"}async function JY(){let Z=await XY.promises.readdir(g.userMigrationsPath());if(Z.length){for(let Y of Z)if(Y.endsWith(".ts")){let $=g.userMigrationsPath(`${Y}`);if(XY.existsSync($))await Bun.$`rm ${$}`}}}async function WY(){let Z=g.frameworkPath("cache/models");if(!XY.existsSync(Z))return;let Y=await XY.promises.readdir(Z);if(Y.length){for(let $ of Y)if($.endsWith(".ts")){let X=g.frameworkPath(`cache/models/${$}`);if(XY.existsSync(X))await Bun.$`rm ${X}`}}}async function c(Z){let $=(await import(g.frameworkPath(`cache/models/${Z}`))).default,X={};if(typeof $.attributes==="object")X=$.attributes;else try{X=JSON.parse($.attributes||"{}")}catch{X={}}return X}async function J6(Z){if(typeof Z==="string")Z=(await import(Z)).default;return Z.table??s1(g1(Z?.name||""))}async function a(Z){return tZ.debug(`hasTableBeenMigrated for table: ${Z}`),(await m1()).some(($)=>$.name.includes(Z))}async function q(Z){return tZ.debug(`hasTableBeenMigrated for table: ${Z}`),Y0([g.userMigrationsPath("*.ts")],{absolute:!0}).some(($)=>$.includes(`create-${Z}`))}async function m1(){try{return await K.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 zZ(Z){if("getRules"in Z){let Y=Z.getRules().find(($)=>$.name==="max");return Y?.params?.length||Y?.params?.max||255}return 255}function l1(Z,Y="mysql"){if(Y==="sqlite")return"'text'";return`'varchar(${zZ(Z)})'`}function W6(Z,Y="mysql"){if(Y==="sqlite")return"'text'";let $=Z.name;if($==="unix")return"'bigint'";return $||"date"}function z6(Z,Y){return Z.min===Y.min&&Z.max===Y.max}async function zY(Z){return(await XY.promises.readdir(g.userMigrationsPath())).some(($)=>{let X=Z.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`(-${X}-)`).test($)})}function GY(Z,Y){let $=Z.filter((J)=>!Y.includes(J)),X=Y.filter((J)=>!Z.includes(J));if($.length===0&&X.length===0)return null;return{added:X,removed:$}}function n(Z){if(!Z)return[];let Y=Object.entries(Z);return Y.sort(([$,X],[J,W])=>{let z=X.order??Number.POSITIVE_INFINITY,H=W.order??Number.POSITIVE_INFINITY;return z-H}),Y}function HY(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 UY(Z,Y){let $=[];for(let X in Z)if(Object.prototype.hasOwnProperty.call(Z,X)&&Object.prototype.hasOwnProperty.call(Y,X)){let J=zZ(Z[X].validation.rule),W=zZ(Y[X].validation.rule);if(J!==void 0&&W!==void 0){if(J!==W)$.push({key:X,max:W,min:W})}}return $}async function vY(){let Z=Y0([g.userModelsPath("*.ts"),g.storagePath("framework/defaults/app/Models/**/*.ts")],{absolute:!0}),Y=[];for(let $ of Z){let X=(await import($)).default,J=d1(X,$),W=t(X,J);if(W)Y.push(W);Y.push(J)}return Y}function t(Z,Y){let $=`${Y}_likes`,X=Z.traits;if(!X?.likeable)return;return typeof X.likeable==="object"?X.likeable.table||$:$}function QY(Z,Y){let $=Z.traits?.likeable;if($&&typeof $==="object"&&!Array.isArray($)&&$.foreignKey)return $.foreignKey;return`${Y.replace(/s$/,"")}_id`}function r1(Z,Y="mysql"){if(Y==="sqlite")return"'integer'";if("getRules"in Z){let $=Z.getRules().find((z)=>z.name==="min"),X=Z.getRules().find((z)=>z.name==="max"),J=$?.params?.min??-2147483648,W=X?.params?.max??2147483647;return J>=-2147483648&&W<=2147483647?"'integer'":"'bigint'"}return"'integer'"}function a1(Z,Y="mysql"){let $=Z.getAllowedValues();if(!$)throw Error("Enum rule found but no allowedValues defined");let X=$.map((J)=>`'${J}'`).join(", ");if(Y==="postgres")return"'varchar(255)'";if(Y==="sqlite")return"'text'";return`sql\`enum(${X})\``}function o(Z,Y="mysql"){if(lZ(Z))return a1(Z,Y);if(sZ(Z))return l1(Z,Y);if(mZ(Z))return r1(Z,Y);if(rZ(Z))return"'boolean'";if(aZ(Z))return"'date'";if(iZ(Z))return Y==="postgres"?"'timestamp'":"'datetime'";if(nZ(Z))return"'bigint'";if(eZ(Z))return"'timestamp'";if(oZ(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 G6(Z){return Z.includes(".required()")}D();import{log as b}from"@stacksjs/logging";import{log as Z0}from"@stacksjs/logging";import{path as X0}from"@stacksjs/path";function $0(Z){return`\x1B[3m${Z}\x1B[23m`}async function fY(){if(await q("password_resets"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
`,Y+=`}
|
|
57
|
-
`;let X=`${new Date().getTime().toString()}-create-password-resets-table.ts`,J=X0.userMigrationsPath(X);await Bun.write(J,Y),Z0.success(`Created migration: ${$0(X)}`)}import{ok as n1}from"@stacksjs/error-handling";import{getModelName as o1,getPivotTables as O0,getTableName as UZ}from"@stacksjs/orm";import{path as s}from"@stacksjs/path";import{fs as i1,globSync as e1}from"@stacksjs/storage";import{snakeCase as IY}from"@stacksjs/strings";D();import{log as M}from"@stacksjs/logging";import{path as F}from"@stacksjs/path";function y(Z){return`\x1B[3m${Z}\x1B[23m`}function R6(){return["tags","taggables","categorizables","comments","commentables","commentable_upvotes","passkeys","password_resets","query_logs","migrations"]}async function J0(){if(await q("users"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
58
|
-
import { sql } from '@stacksjs/database'
|
|
59
|
-
|
|
60
|
-
`;Y+=`export async function up(db: Database<any>) {
|
|
61
|
-
`,Y+=` await db.schema
|
|
62
|
-
`,Y+=` .createTable('passkeys')
|
|
63
|
-
`,Y+=` .addColumn('id', 'text')
|
|
64
|
-
`,Y+=` .addColumn('cred_public_key', 'text')
|
|
65
|
-
`,Y+=` .addColumn('webauthn_user_id', 'varchar(255)')
|
|
66
|
-
`,Y+=` .addColumn('counter', 'integer', col => col.defaultTo(0))
|
|
67
|
-
`,Y+=` .addColumn('device_type', 'varchar(255)')
|
|
68
|
-
`,Y+=` .addColumn('credential_type', 'varchar(255)')
|
|
69
|
-
`,Y+=` .addColumn('backup_eligible', 'boolean', col => col.defaultTo(false))
|
|
70
|
-
`,Y+=` .addColumn('backup_status', 'boolean', col => col.defaultTo(false))
|
|
71
|
-
`,Y+=` .addColumn('transports', 'varchar(255)')
|
|
72
|
-
`,Y+=` .addColumn('last_used_at', 'text')
|
|
73
|
-
`,Y+=` .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
74
|
-
`,Y+=` .execute()
|
|
75
|
-
`,Y+=` }
|
|
76
|
-
`;let X=`${new Date().getTime().toString()}-create-passkeys-table.ts`,J=F.userMigrationsPath(X);await Bun.write(J,Y),M.success(`Created migration: ${y(X)}`)}async function W0(){if(await q("users"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
77
|
-
import { sql } from '@stacksjs/database'
|
|
78
|
-
|
|
79
|
-
`;Y+=`export async function up(db: Database<any>) {
|
|
80
|
-
`,Y+=` await db.schema
|
|
81
|
-
`,Y+=` .createTable('passkeys')
|
|
82
|
-
`,Y+=` .addColumn('id', 'uuid', col => col.primaryKey())
|
|
83
|
-
`,Y+=` .addColumn('cred_public_key', 'text')
|
|
84
|
-
`,Y+=` .addColumn('webauthn_user_id', 'varchar(255)')
|
|
85
|
-
`,Y+=` .addColumn('counter', 'integer', col => col.defaultTo(0))
|
|
86
|
-
`,Y+=` .addColumn('device_type', 'varchar(255)')
|
|
87
|
-
`,Y+=` .addColumn('credential_type', 'varchar(255)')
|
|
88
|
-
`,Y+=` .addColumn('backup_eligible', 'boolean', col => col.defaultTo(false))
|
|
89
|
-
`,Y+=` .addColumn('backup_status', 'boolean', col => col.defaultTo(false))
|
|
90
|
-
`,Y+=` .addColumn('transports', 'varchar(255)')
|
|
91
|
-
`,Y+=` .addColumn('last_used_at', 'timestamp')
|
|
92
|
-
`,Y+=` .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
93
|
-
`,Y+=` .execute()
|
|
94
|
-
|
|
95
|
-
`,Y+=`}
|
|
96
|
-
`;let X=`${new Date().getTime().toString()}-create-passkeys-table.ts`,J=F.userMigrationsPath(X);await Bun.write(J,Y),M.success(`Created migration: ${y(X)}`)}async function z0(){if(await q("tags"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
97
|
-
`;Y+=`import { sql } from '@stacksjs/database'
|
|
98
|
-
|
|
99
|
-
`,Y+=`export async function up(db: Database<any>) {
|
|
100
|
-
`,Y+=` await db.schema
|
|
101
|
-
`,Y+=` .createTable('tags')
|
|
102
|
-
`,Y+=` .addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
|
|
103
|
-
`,Y+=` .addColumn('name', 'varchar(255)', col => col.notNull())
|
|
104
|
-
`,Y+=` .addColumn('slug', 'varchar(255)', col => col.notNull().unique())
|
|
105
|
-
`,Y+=` .addColumn('type', 'varchar(255)')
|
|
106
|
-
`,Y+=` .addColumn('color', 'varchar(255)')
|
|
107
|
-
`,Y+=` .addColumn('description', 'text')
|
|
108
|
-
`,Y+=` .addColumn('is_active', 'boolean', col => col.defaultTo(true))
|
|
109
|
-
`,Y+=` .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
110
|
-
`,Y+=` .addColumn('updated_at', 'timestamp')
|
|
111
|
-
`,Y+=` .execute()
|
|
112
|
-
|
|
113
|
-
`,Y+=` await db.schema
|
|
114
|
-
`,Y+=` .createIndex('idx_tags_slug')
|
|
115
|
-
`,Y+=` .on('tags')
|
|
116
|
-
`,Y+=` .column('slug')
|
|
117
|
-
`,Y+=` .execute()
|
|
118
|
-
|
|
119
|
-
`,Y+=` await db.schema
|
|
120
|
-
`,Y+=` .createIndex('idx_tags_type')
|
|
121
|
-
`,Y+=` .on('tags')
|
|
122
|
-
`,Y+=` .column('type')
|
|
123
|
-
`,Y+=` .execute()
|
|
124
|
-
|
|
125
|
-
`,Y+=` await db.schema
|
|
126
|
-
`,Y+=` .createIndex('idx_tags_name')
|
|
127
|
-
`,Y+=` .on('tags')
|
|
128
|
-
`,Y+=` .column('name')
|
|
129
|
-
`,Y+=` .execute()
|
|
130
|
-
|
|
131
|
-
`,Y+=`}
|
|
132
|
-
`;let X=`${new Date().getTime().toString()}-create-tags-table.ts`,J=F.userMigrationsPath(X);await Bun.write(J,Y),M.success(`Created migration: ${y(X)}`),await new Promise((W)=>setTimeout(W,2)),await GZ()}async function G0(){if(await q("tags"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
133
|
-
`;Y+=`import { sql } from '@stacksjs/database'
|
|
134
|
-
|
|
135
|
-
`,Y+=`export async function up(db: Database<any>) {
|
|
136
|
-
`,Y+=` await db.schema
|
|
137
|
-
`,Y+=` .createTable('tags')
|
|
138
|
-
`,Y+=` .addColumn('id', 'serial', col => col.primaryKey())
|
|
139
|
-
`,Y+=` .addColumn('name', 'varchar(255)', col => col.notNull())
|
|
140
|
-
`,Y+=` .addColumn('slug', 'varchar(255)', col => col.notNull().unique())
|
|
141
|
-
`,Y+=` .addColumn('type', 'varchar(255)')
|
|
142
|
-
`,Y+=` .addColumn('color', 'varchar(255)')
|
|
143
|
-
`,Y+=` .addColumn('description', 'text')
|
|
144
|
-
`,Y+=` .addColumn('is_active', 'boolean', col => col.defaultTo(true))
|
|
145
|
-
`,Y+=` .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
146
|
-
`,Y+=` .addColumn('updated_at', 'timestamp')
|
|
147
|
-
`,Y+=` .execute()
|
|
148
|
-
|
|
149
|
-
`,Y+=` await db.schema
|
|
150
|
-
`,Y+=` .createIndex('idx_tags_slug')
|
|
151
|
-
`,Y+=` .on('tags')
|
|
152
|
-
`,Y+=` .column('slug')
|
|
153
|
-
`,Y+=` .execute()
|
|
154
|
-
|
|
155
|
-
`,Y+=` await db.schema
|
|
156
|
-
`,Y+=` .createIndex('idx_tags_type')
|
|
157
|
-
`,Y+=` .on('tags')
|
|
158
|
-
`,Y+=` .column('type')
|
|
159
|
-
`,Y+=` .execute()
|
|
160
|
-
|
|
161
|
-
`,Y+=` await db.schema
|
|
162
|
-
`,Y+=` .createIndex('idx_tags_name')
|
|
163
|
-
`,Y+=` .on('tags')
|
|
164
|
-
`,Y+=` .column('name')
|
|
165
|
-
`,Y+=` .execute()
|
|
166
|
-
|
|
167
|
-
`,Y+=`}
|
|
168
|
-
`;let X=`${new Date().getTime().toString()}-create-tags-table.ts`,J=F.userMigrationsPath(X);await Bun.write(J,Y),M.success(`Created migration: ${y(X)}`),await new Promise((W)=>setTimeout(W,2)),await HZ()}async function H0(){if(await q("categorizable"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
169
|
-
`;Y+=`import { sql } from '@stacksjs/database'
|
|
170
|
-
|
|
171
|
-
`,Y+=`export async function up(db: Database<any>) {
|
|
172
|
-
`,Y+=` await db.schema
|
|
173
|
-
`,Y+=` .createTable('categorizables')
|
|
174
|
-
`,Y+=` .addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
|
|
175
|
-
`,Y+=` .addColumn('name', 'varchar(255)', col => col.notNull())
|
|
176
|
-
`,Y+=` .addColumn('slug', 'varchar(255)', col => col.notNull().unique())
|
|
177
|
-
`,Y+=` .addColumn('description', 'text')
|
|
178
|
-
`,Y+=` .addColumn('is_active', 'boolean', col => col.defaultTo(true))
|
|
179
|
-
`,Y+=` .addColumn('categorizable_type', 'varchar(255)', col => col.notNull())
|
|
180
|
-
`,Y+=` .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
181
|
-
`,Y+=` .addColumn('updated_at', 'timestamp')
|
|
182
|
-
`,Y+=` .execute()
|
|
183
|
-
|
|
184
|
-
`,Y+=` await db.schema
|
|
185
|
-
`,Y+=` .createIndex('categorizables_id_index')
|
|
186
|
-
`,Y+=` .on('categorizables')
|
|
187
|
-
`,Y+=` .column('id')
|
|
188
|
-
`,Y+=` .execute()
|
|
189
|
-
|
|
190
|
-
`,Y+=` await db.schema
|
|
191
|
-
`,Y+=` .createIndex('categorizables_slug_index')
|
|
192
|
-
`,Y+=` .on('categorizables')
|
|
193
|
-
`,Y+=` .column('slug')
|
|
194
|
-
`,Y+=` .execute()
|
|
195
|
-
|
|
196
|
-
`,Y+=` await db.schema
|
|
197
|
-
`,Y+=` .createIndex('categorizables_polymorphic_index')
|
|
198
|
-
`,Y+=` .on('categorizables')
|
|
199
|
-
`,Y+=` .columns(['categorizable_type'])
|
|
200
|
-
`,Y+=` .execute()
|
|
201
|
-
|
|
202
|
-
`,Y+=` await db.schema
|
|
203
|
-
`,Y+=` .createIndex('categorizables_is_active_index')
|
|
204
|
-
`,Y+=` .on('categorizables')
|
|
205
|
-
`,Y+=` .column('is_active')
|
|
206
|
-
`,Y+=` .execute()
|
|
207
|
-
`,Y+=`}
|
|
208
|
-
`;let X=`${new Date().getTime().toString()}-create-categorizables-table.ts`,J=F.userMigrationsPath(X);await Bun.write(J,Y),M.success(`Created migration: ${y(X)}`)}async function U0(){if(await q("categorizable"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
209
|
-
`;Y+=`import { sql } from '@stacksjs/database'
|
|
210
|
-
|
|
211
|
-
`,Y+=`export async function up(db: Database<any>) {
|
|
212
|
-
`,Y+=` await db.schema
|
|
213
|
-
`,Y+=` .createTable('categorizables')
|
|
214
|
-
`,Y+=` .addColumn('id', 'serial', col => col.primaryKey())
|
|
215
|
-
`,Y+=` .addColumn('name', 'varchar(255)', col => col.notNull())
|
|
216
|
-
`,Y+=` .addColumn('slug', 'varchar(255)', col => col.notNull().unique())
|
|
217
|
-
`,Y+=` .addColumn('description', 'text')
|
|
218
|
-
`,Y+=` .addColumn('order', 'integer', col => col.defaultTo(0))
|
|
219
|
-
`,Y+=` .addColumn('is_active', 'boolean', col => col.defaultTo(true))
|
|
220
|
-
`,Y+=` .addColumn('categorizable_type', 'varchar(255)', col => col.notNull())
|
|
221
|
-
`,Y+=` .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
222
|
-
`,Y+=` .addColumn('updated_at', 'timestamp')
|
|
223
|
-
`,Y+=` .execute()
|
|
224
|
-
|
|
225
|
-
`,Y+=` await db.schema
|
|
226
|
-
`,Y+=` .createIndex('idx_categorizables_slug')
|
|
227
|
-
`,Y+=` .on('categorizables')
|
|
228
|
-
`,Y+=` .column('slug')
|
|
229
|
-
`,Y+=` .execute()
|
|
230
|
-
|
|
231
|
-
`,Y+=` await db.schema
|
|
232
|
-
`,Y+=` .createIndex('idx_categorizables_polymorphic')
|
|
233
|
-
`,Y+=` .on('categorizables')
|
|
234
|
-
`,Y+=` .columns(['categorizable_type'])
|
|
235
|
-
`,Y+=` .execute()
|
|
236
|
-
|
|
237
|
-
`,Y+=` await db.schema
|
|
238
|
-
`,Y+=` .createIndex('idx_categorizables_order')
|
|
239
|
-
`,Y+=` .on('categorizables')
|
|
240
|
-
`,Y+=` .column('order')
|
|
241
|
-
`,Y+=` .execute()
|
|
242
|
-
|
|
243
|
-
`,Y+=` await db.schema
|
|
244
|
-
`,Y+=` .createIndex('idx_categorizables_is_active')
|
|
245
|
-
`,Y+=` .on('categorizables')
|
|
246
|
-
`,Y+=` .column('is_active')
|
|
247
|
-
`,Y+=` .execute()
|
|
248
|
-
`,Y+=`}
|
|
249
|
-
`;let X=`${new Date().getTime().toString()}-create-categorizables-table.ts`,J=F.userMigrationsPath(X);await Bun.write(J,Y),M.success(`Created migration: ${y(X)}`)}async function Q0(Z={}){if(await q("comments"))return;let $=`import type { Database } from '@stacksjs/database'
|
|
250
|
-
`;if($+=`import { sql } from '@stacksjs/database'
|
|
251
|
-
|
|
252
|
-
`,$+=`export async function up(db: Database<any>) {
|
|
253
|
-
`,$+=` await db.schema
|
|
254
|
-
`,$+=` .createTable('comments')
|
|
255
|
-
`,$+=` .addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
|
|
256
|
-
`,$+=` .addColumn('title', 'varchar(255)', col => col.notNull())
|
|
257
|
-
`,$+=` .addColumn('body', 'text', col => col.notNull())
|
|
258
|
-
`,$+=` .addColumn('content', 'text')
|
|
259
|
-
`,$+=` .addColumn('status', 'varchar(50)', col => col.notNull().defaultTo('${Z.requiresApproval?"pending":"approved"}'))
|
|
260
|
-
`,$+=` .addColumn('author_name', 'varchar(100)')
|
|
261
|
-
`,$+=` .addColumn('author_email', 'varchar(255)')
|
|
262
|
-
`,$+=` .addColumn('post_title', 'varchar(255)')
|
|
263
|
-
`,$+=` .addColumn('commentables_id', 'integer', col => col.notNull())
|
|
264
|
-
`,$+=` .addColumn('commentables_type', 'varchar(255)', col => col.notNull())
|
|
265
|
-
`,$+=` .addColumn('ip_address', 'varchar(45)')
|
|
266
|
-
`,$+=` .addColumn('user_agent', 'varchar(500)')
|
|
267
|
-
`,$+=` .addColumn('is_approved', 'integer', col => col.defaultTo(0))
|
|
268
|
-
`,$+=` .addColumn('approved_at', 'integer')
|
|
269
|
-
`,$+=` .addColumn('rejected_at', 'integer')
|
|
270
|
-
`,Z.reportable)$+=` .addColumn('reports_count', 'integer', col => col.defaultTo(0))
|
|
271
|
-
`,$+=` .addColumn('reported_at', 'integer')
|
|
272
|
-
`;if(Z.requiresAuth)$+=` .addColumn('user_id', 'integer', col => col.notNull())
|
|
273
|
-
`;$+=` .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
274
|
-
`,$+=` .addColumn('updated_at', 'timestamp')
|
|
275
|
-
`,$+=` .execute()
|
|
276
|
-
|
|
277
|
-
`,$+=` await db.schema.createIndex('idx_comments_status').on('comments').column('status').execute()
|
|
278
|
-
`,$+=` await db.schema.createIndex('idx_comments_created_at').on('comments').column('created_at').execute()
|
|
279
|
-
`,$+=`}
|
|
280
|
-
`;let J=`${new Date().getTime().toString()}-create-comments-table.ts`,W=F.userMigrationsPath(J);await Bun.write(W,$),M.success(`Created migration: ${y(J)}`)}async function I0(){if(await q("comments"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
281
|
-
`;Y+=`import { sql } from '@stacksjs/database'
|
|
282
|
-
|
|
283
|
-
`,Y+=`export async function up(db: Database<any>) {
|
|
284
|
-
`,Y+=` await db.schema
|
|
285
|
-
`,Y+=` .createTable('comments')
|
|
286
|
-
`,Y+=` .addColumn('id', 'serial', col => col.primaryKey())
|
|
287
|
-
`,Y+=` .addColumn('title', 'varchar(255)', col => col.notNull())
|
|
288
|
-
`,Y+=` .addColumn('body', 'text', col => col.notNull())
|
|
289
|
-
`,Y+=` .addColumn('content', 'text')
|
|
290
|
-
`,Y+=` .addColumn('commentables_id', 'integer', col => col.notNull())
|
|
291
|
-
`,Y+=` .addColumn('commentables_type', 'varchar(255)', col => col.notNull())
|
|
292
|
-
`,Y+=` .addColumn('status', 'varchar(50)', col => col.notNull().defaultTo('pending'))
|
|
293
|
-
`,Y+=` .addColumn('author_name', 'varchar(100)')
|
|
294
|
-
`,Y+=` .addColumn('author_email', 'varchar(255)')
|
|
295
|
-
`,Y+=` .addColumn('post_title', 'varchar(255)')
|
|
296
|
-
`,Y+=` .addColumn('ip_address', 'varchar(45)')
|
|
297
|
-
`,Y+=` .addColumn('user_agent', 'varchar(500)')
|
|
298
|
-
`,Y+=` .addColumn('is_approved', 'integer', col => col.defaultTo(0))
|
|
299
|
-
`,Y+=` .addColumn('approved_at', 'integer')
|
|
300
|
-
`,Y+=` .addColumn('rejected_at', 'integer')
|
|
301
|
-
`,Y+=` .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
302
|
-
`,Y+=` .addColumn('updated_at', 'timestamp')
|
|
303
|
-
`,Y+=` .execute()
|
|
304
|
-
|
|
305
|
-
`,Y+=` await db.schema.createIndex('idx_comments_status').on('comments').column('status').execute()
|
|
306
|
-
`,Y+=` await db.schema.createIndex('idx_comments_created_at').on('comments').column('created_at').execute()
|
|
307
|
-
`,Y+=`}
|
|
308
|
-
`;let X=`${new Date().getTime().toString()}-create-comments-table.ts`,J=F.userMigrationsPath(X);await Bun.write(J,Y),M.success(`Created migration: ${y(X)}`)}async function hY(){await K.unsafe("DROP TABLE IF EXISTS passkeys").execute(),await K.unsafe("DROP TABLE IF EXISTS password_resets").execute(),await K.unsafe("DROP TABLE IF EXISTS query_logs").execute(),await K.unsafe("DROP TABLE IF EXISTS categorizables").execute(),await K.unsafe("DROP TABLE IF EXISTS commentable_upvotes").execute(),await K.unsafe("DROP TABLE IF EXISTS tags").execute(),await K.unsafe("DROP TABLE IF EXISTS taggables").execute(),await K.unsafe("DROP TABLE IF EXISTS categorizable_models").execute(),await K.unsafe("DROP TABLE IF EXISTS commentables").execute(),await K.unsafe("DROP TABLE IF EXISTS comments").execute(),await K.unsafe("DROP TABLE IF EXISTS categories_models").execute(),await K.unsafe("DROP TABLE IF EXISTS activities").execute()}async function O6(){await K.unsafe("DELETE FROM migrations").execute(),await K.unsafe("DELETE FROM migration_locks").execute()}async function K0(){await K.unsafe("DROP TABLE IF EXISTS migrations").execute(),await K.unsafe("DROP TABLE IF EXISTS migration_locks").execute()}async function V0(){if(await q("commentable_upvotes"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
309
|
-
import { sql } from '@stacksjs/database'
|
|
310
|
-
|
|
311
|
-
`;Y+=`export async function up(db: Database<any>) {
|
|
312
|
-
`,Y+=` await db.schema
|
|
313
|
-
`,Y+=` .createTable('commentable_upvotes')
|
|
314
|
-
`,Y+=` .addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
|
|
315
|
-
`,Y+=` .addColumn('upvoteable_id', 'integer', col => col.notNull())
|
|
316
|
-
`,Y+=` .addColumn('upvoteable_type', 'varchar(255)', col => col.notNull())
|
|
317
|
-
`,Y+=` .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
318
|
-
`,Y+=` .execute()
|
|
319
|
-
|
|
320
|
-
`,Y+=` await db.schema.createIndex('idx_commentable_upvotes_upvoteable').on('commentable_upvotes').columns(['upvoteable_id', 'upvoteable_type']).execute()
|
|
321
|
-
`,Y+=`}
|
|
322
|
-
`;let X=`${new Date().getTime().toString()}-create-commentable_upvotes-table.ts`,J=F.userMigrationsPath(X);await Bun.write(J,Y),M.success(`Created migration: ${y(X)}`)}async function _0(){if(await q("commentable_upvotes"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
323
|
-
import { sql } from '@stacksjs/database'
|
|
324
|
-
|
|
325
|
-
`;Y+=`export async function up(db: Database<any>) {
|
|
326
|
-
`,Y+=` await db.schema
|
|
327
|
-
`,Y+=` .createTable('commentable_upvotes')
|
|
328
|
-
`,Y+=` .addColumn('id', 'serial', col => col.primaryKey())
|
|
329
|
-
`,Y+=` .addColumn('upvoteable_id', 'integer', col => col.notNull())
|
|
330
|
-
`,Y+=` .addColumn('upvoteable_type', 'varchar(255)', col => col.notNull())
|
|
331
|
-
`,Y+=` .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
332
|
-
`,Y+=` .execute()
|
|
333
|
-
|
|
334
|
-
`,Y+=` await db.schema.createIndex('idx_commentable_upvotes_upvoteable').on('commentable_upvotes').columns(['upvoteable_id', 'upvoteable_type']).execute()
|
|
335
|
-
`,Y+=`}
|
|
336
|
-
`;let X=`${new Date().getTime().toString()}-create-commentable_upvotes-table.ts`,J=F.userMigrationsPath(X);await Bun.write(J,Y),M.success(`Created migration: ${y(X)}`)}async function B6(){if(await q("commentables"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
337
|
-
`;Y+=`import { sql } from '@stacksjs/database'
|
|
338
|
-
|
|
339
|
-
`,Y+=`export async function up(db: Database<any>) {
|
|
340
|
-
`,Y+=` await db.schema
|
|
341
|
-
`,Y+=` .createTable('commentables')
|
|
342
|
-
`,Y+=` .addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
|
|
343
|
-
`,Y+=` .addColumn('comment_id', 'integer', col => col.notNull())
|
|
344
|
-
`,Y+=` .addColumn('commentable_id', 'integer', col => col.notNull())
|
|
345
|
-
`,Y+=` .addColumn('commentable_type', 'varchar(255)', col => col.notNull())
|
|
346
|
-
`,Y+=` .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
347
|
-
`,Y+=` .addColumn('updated_at', 'timestamp')
|
|
348
|
-
`,Y+=` .execute()
|
|
349
|
-
|
|
350
|
-
`,Y+=` await db.schema
|
|
351
|
-
`,Y+=` .createIndex('idx_commentables_comment')
|
|
352
|
-
`,Y+=` .on('commentables')
|
|
353
|
-
`,Y+=` .column('comment_id')
|
|
354
|
-
`,Y+=` .execute()
|
|
355
|
-
|
|
356
|
-
`,Y+=` await db.schema
|
|
357
|
-
`,Y+=` .createIndex('idx_commentables_polymorphic')
|
|
358
|
-
`,Y+=` .on('commentables')
|
|
359
|
-
`,Y+=` .columns(['commentable_id', 'commentable_type'])
|
|
360
|
-
`,Y+=` .execute()
|
|
361
|
-
|
|
362
|
-
`,Y+=` await db.schema
|
|
363
|
-
`,Y+=` .createIndex('idx_commentables_unique')
|
|
364
|
-
`,Y+=` .on('commentables')
|
|
365
|
-
`,Y+=` .columns(['comment_id', 'commentable_id', 'commentable_type'])
|
|
366
|
-
`,Y+=` .unique()
|
|
367
|
-
`,Y+=` .execute()
|
|
368
|
-
|
|
369
|
-
`,Y+=`}
|
|
370
|
-
`;let X=`${new Date().getTime().toString()}-create-commentables-pivot-table.ts`,J=F.userMigrationsPath(X);await Bun.write(J,Y),M.success(`Created migration: ${y(X)}`)}async function L0(){if(await q("commentables_pivot"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
371
|
-
`;Y+=`import { sql } from '@stacksjs/database'
|
|
372
|
-
|
|
373
|
-
`,Y+=`export async function up(db: Database<any>) {
|
|
374
|
-
`,Y+=` await db.schema
|
|
375
|
-
`,Y+=` .createTable('commentables')
|
|
376
|
-
`,Y+=` .addColumn('id', 'serial', col => col.primaryKey())
|
|
377
|
-
`,Y+=` .addColumn('comment_id', 'integer', col => col.notNull())
|
|
378
|
-
`,Y+=` .addColumn('commentable_id', 'integer', col => col.notNull())
|
|
379
|
-
`,Y+=` .addColumn('commentable_type', 'varchar(255)', col => col.notNull())
|
|
380
|
-
`,Y+=` .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
381
|
-
`,Y+=` .addColumn('updated_at', 'timestamp')
|
|
382
|
-
`,Y+=` .execute()
|
|
383
|
-
|
|
384
|
-
`,Y+=` await db.schema
|
|
385
|
-
`,Y+=` .alterTable('commentables')
|
|
386
|
-
`,Y+=` .addForeignKeyConstraint('commentables_comment_id_foreign', ['comment_id'], 'comments', ['id'], (cb) => cb.onDelete('cascade'))
|
|
387
|
-
`,Y+=` .execute()
|
|
388
|
-
|
|
389
|
-
`,Y+=` await db.schema
|
|
390
|
-
`,Y+=` .createIndex('idx_commentables_comment')
|
|
391
|
-
`,Y+=` .on('commentables')
|
|
392
|
-
`,Y+=` .column('comment_id')
|
|
393
|
-
`,Y+=` .execute()
|
|
394
|
-
|
|
395
|
-
`,Y+=` await db.schema
|
|
396
|
-
`,Y+=` .createIndex('idx_commentables_polymorphic')
|
|
397
|
-
`,Y+=` .on('commentables')
|
|
398
|
-
`,Y+=` .columns(['commentable_id', 'commentable_type'])
|
|
399
|
-
`,Y+=` .execute()
|
|
400
|
-
|
|
401
|
-
`,Y+=` await db.schema
|
|
402
|
-
`,Y+=` .createIndex('idx_commentables_unique')
|
|
403
|
-
`,Y+=` .on('commentables')
|
|
404
|
-
`,Y+=` .columns(['comment_id', 'commentable_id', 'commentable_type'])
|
|
405
|
-
`,Y+=` .unique()
|
|
406
|
-
`,Y+=` .execute()
|
|
407
|
-
|
|
408
|
-
`,Y+=`}
|
|
409
|
-
`;let X=`${new Date().getTime().toString()}-create-commentables-pivot-table.ts`,J=F.userMigrationsPath(X);await Bun.write(J,Y),M.success(`Created migration: ${y(X)}`)}async function GZ(){if(await q("taggables"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
410
|
-
`;Y+=`import { sql } from '@stacksjs/database'
|
|
411
|
-
|
|
412
|
-
`,Y+=`export async function up(db: Database<any>) {
|
|
413
|
-
`,Y+=` await db.schema
|
|
414
|
-
`,Y+=` .createTable('taggables')
|
|
415
|
-
`,Y+=` .addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
|
|
416
|
-
`,Y+=` .addColumn('tag_id', 'integer', col => col.notNull())
|
|
417
|
-
`,Y+=` .addColumn('taggable_id', 'integer', col => col.notNull())
|
|
418
|
-
`,Y+=` .addColumn('taggable_type', 'varchar(255)', col => col.notNull())
|
|
419
|
-
`,Y+=` .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
420
|
-
`,Y+=` .addColumn('updated_at', 'timestamp')
|
|
421
|
-
`,Y+=` .execute()
|
|
422
|
-
|
|
423
|
-
`,Y+=` await db.schema
|
|
424
|
-
`,Y+=` .createIndex('idx_taggables_tag')
|
|
425
|
-
`,Y+=` .on('taggables')
|
|
426
|
-
`,Y+=` .column('tag_id')
|
|
427
|
-
`,Y+=` .execute()
|
|
428
|
-
|
|
429
|
-
`,Y+=` await db.schema
|
|
430
|
-
`,Y+=` .createIndex('idx_taggables_polymorphic')
|
|
431
|
-
`,Y+=` .on('taggables')
|
|
432
|
-
`,Y+=` .columns(['taggable_id', 'taggable_type'])
|
|
433
|
-
`,Y+=` .execute()
|
|
434
|
-
|
|
435
|
-
`,Y+=` await db.schema
|
|
436
|
-
`,Y+=` .createIndex('idx_taggables_unique')
|
|
437
|
-
`,Y+=` .on('taggables')
|
|
438
|
-
`,Y+=` .columns(['tag_id', 'taggable_id', 'taggable_type'])
|
|
439
|
-
`,Y+=` .unique()
|
|
440
|
-
`,Y+=` .execute()
|
|
441
|
-
|
|
442
|
-
`,Y+=`}
|
|
443
|
-
`;let X=`${new Date().getTime().toString()}-create-taggables-table.ts`,J=F.userMigrationsPath(X);await Bun.write(J,Y),M.success(`Created migration: ${y(X)}`)}async function HZ(){if(await q("taggables"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
444
|
-
`;Y+=`import { sql } from '@stacksjs/database'
|
|
445
|
-
|
|
446
|
-
`,Y+=`export async function up(db: Database<any>) {
|
|
447
|
-
`,Y+=` await db.schema
|
|
448
|
-
`,Y+=` .createTable('taggables')
|
|
449
|
-
`,Y+=` .addColumn('id', 'serial', col => col.primaryKey())
|
|
450
|
-
`,Y+=` .addColumn('tag_id', 'integer', col => col.notNull())
|
|
451
|
-
`,Y+=` .addColumn('taggable_id', 'integer', col => col.notNull())
|
|
452
|
-
`,Y+=` .addColumn('taggable_type', 'varchar(255)', col => col.notNull())
|
|
453
|
-
`,Y+=` .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
454
|
-
`,Y+=` .addColumn('updated_at', 'timestamp')
|
|
455
|
-
`,Y+=` .execute()
|
|
456
|
-
|
|
457
|
-
`,Y+=` await db.schema
|
|
458
|
-
`,Y+=` .alterTable('taggables')
|
|
459
|
-
`,Y+=` .addForeignKeyConstraint('taggables_tag_id_foreign', ['tag_id'], 'tags', ['id'], (cb) => cb.onDelete('cascade'))
|
|
460
|
-
`,Y+=` .execute()
|
|
461
|
-
|
|
462
|
-
`,Y+=` await db.schema
|
|
463
|
-
`,Y+=` .createIndex('idx_taggables_tag')
|
|
464
|
-
`,Y+=` .on('taggables')
|
|
465
|
-
`,Y+=` .column('tag_id')
|
|
466
|
-
`,Y+=` .execute()
|
|
467
|
-
|
|
468
|
-
`,Y+=` await db.schema
|
|
469
|
-
`,Y+=` .createIndex('idx_taggables_polymorphic')
|
|
470
|
-
`,Y+=` .on('taggables')
|
|
471
|
-
`,Y+=` .columns(['taggable_id', 'taggable_type'])
|
|
472
|
-
`,Y+=` .execute()
|
|
473
|
-
|
|
474
|
-
`,Y+=` await db.schema
|
|
475
|
-
`,Y+=` .createIndex('idx_taggables_unique')
|
|
476
|
-
`,Y+=` .on('taggables')
|
|
477
|
-
`,Y+=` .columns(['tag_id', 'taggable_id', 'taggable_type'])
|
|
478
|
-
`,Y+=` .unique()
|
|
479
|
-
`,Y+=` .execute()
|
|
480
|
-
|
|
481
|
-
`,Y+=`}
|
|
482
|
-
`;let X=`${new Date().getTime().toString()}-create-taggables-table.ts`,J=F.userMigrationsPath(X);await Bun.write(J,Y),M.success(`Created migration: ${y(X)}`)}async function E0(){if(await q("query_logs"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
483
|
-
`;Y+=`import { sql } from '@stacksjs/database'
|
|
484
|
-
|
|
485
|
-
`,Y+=`export async function up(db: Database<any>) {
|
|
486
|
-
`,Y+=` await db.schema
|
|
487
|
-
`,Y+=` .createTable('query_logs')
|
|
488
|
-
`,Y+=` .addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
|
|
489
|
-
`,Y+=` .addColumn('query', 'text', col => col.notNull())
|
|
490
|
-
`,Y+=` .addColumn('normalized_query', 'text')
|
|
491
|
-
`,Y+=` .addColumn('duration', 'integer')
|
|
492
|
-
`,Y+=` .addColumn('connection', 'varchar(255)')
|
|
493
|
-
`,Y+=` .addColumn('status', 'varchar(50)')
|
|
494
|
-
`,Y+=` .addColumn('executed_at', 'timestamp', col => col.notNull())
|
|
495
|
-
`,Y+=` .addColumn('model', 'varchar(255)')
|
|
496
|
-
`,Y+=` .addColumn('method', 'varchar(255)')
|
|
497
|
-
`,Y+=` .addColumn('rows_affected', 'integer')
|
|
498
|
-
`,Y+=` .addColumn('optimization_suggestions', 'json')
|
|
499
|
-
`,Y+=` .addColumn('affected_tables', 'json')
|
|
500
|
-
`,Y+=` .addColumn('indexes_used', 'json')
|
|
501
|
-
`,Y+=` .addColumn('missing_indexes', 'json')
|
|
502
|
-
`,Y+=` .addColumn('tags', 'json')
|
|
503
|
-
`,Y+=` .addColumn('bindings', 'json')
|
|
504
|
-
`,Y+=` .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
505
|
-
`,Y+=` .addColumn('updated_at', 'timestamp')
|
|
506
|
-
`,Y+=` .execute()
|
|
507
|
-
|
|
508
|
-
`,Y+=` await db.schema
|
|
509
|
-
`,Y+=` .createIndex('idx_query_logs_executed_at')
|
|
510
|
-
`,Y+=` .on('query_logs')
|
|
511
|
-
`,Y+=` .column('executed_at')
|
|
512
|
-
`,Y+=` .execute()
|
|
513
|
-
|
|
514
|
-
`,Y+=` await db.schema
|
|
515
|
-
`,Y+=` .createIndex('idx_query_logs_status')
|
|
516
|
-
`,Y+=` .on('query_logs')
|
|
517
|
-
`,Y+=` .column('status')
|
|
518
|
-
`,Y+=` .execute()
|
|
519
|
-
|
|
520
|
-
`,Y+=` await db.schema
|
|
521
|
-
`,Y+=` .createIndex('idx_query_logs_duration')
|
|
522
|
-
`,Y+=` .on('query_logs')
|
|
523
|
-
`,Y+=` .column('duration')
|
|
524
|
-
`,Y+=` .execute()
|
|
525
|
-
|
|
526
|
-
`,Y+=`}
|
|
527
|
-
`;let X=`${new Date().getTime().toString()}-create-query-logs-table.ts`,J=F.userMigrationsPath(X);await Bun.write(J,Y),M.success(`Created migration: ${y(X)}`)}async function A0(){if(await q("query_logs"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
528
|
-
`;Y+=`import { sql } from '@stacksjs/database'
|
|
529
|
-
|
|
530
|
-
`,Y+=`export async function up(db: Database<any>) {
|
|
531
|
-
`,Y+=` await db.schema
|
|
532
|
-
`,Y+=` .createTable('query_logs')
|
|
533
|
-
`,Y+=` .addColumn('id', 'serial', col => col.primaryKey())
|
|
534
|
-
`,Y+=` .addColumn('query', 'text', col => col.notNull())
|
|
535
|
-
`,Y+=` .addColumn('normalized_query', 'text')
|
|
536
|
-
`,Y+=` .addColumn('duration', 'integer')
|
|
537
|
-
`,Y+=` .addColumn('connection', 'varchar(255)')
|
|
538
|
-
`,Y+=` .addColumn('status', 'varchar(50)')
|
|
539
|
-
`,Y+=` .addColumn('executed_at', 'timestamp', col => col.notNull())
|
|
540
|
-
`,Y+=` .addColumn('model', 'varchar(255)')
|
|
541
|
-
`,Y+=` .addColumn('method', 'varchar(255)')
|
|
542
|
-
`,Y+=` .addColumn('rows_affected', 'integer')
|
|
543
|
-
`,Y+=` .addColumn('optimization_suggestions', 'jsonb')
|
|
544
|
-
`,Y+=` .addColumn('affected_tables', 'jsonb')
|
|
545
|
-
`,Y+=` .addColumn('indexes_used', 'jsonb')
|
|
546
|
-
`,Y+=` .addColumn('missing_indexes', 'jsonb')
|
|
547
|
-
`,Y+=` .addColumn('tags', 'jsonb')
|
|
548
|
-
`,Y+=` .addColumn('bindings', 'jsonb')
|
|
549
|
-
`,Y+=` .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
550
|
-
`,Y+=` .addColumn('updated_at', 'timestamp')
|
|
551
|
-
`,Y+=` .execute()
|
|
552
|
-
|
|
553
|
-
`,Y+=` await db.schema
|
|
554
|
-
`,Y+=` .createIndex('idx_query_logs_executed_at')
|
|
555
|
-
`,Y+=` .on('query_logs')
|
|
556
|
-
`,Y+=` .column('executed_at')
|
|
557
|
-
`,Y+=` .execute()
|
|
558
|
-
|
|
559
|
-
`,Y+=` await db.schema
|
|
560
|
-
`,Y+=` .createIndex('idx_query_logs_status')
|
|
561
|
-
`,Y+=` .on('query_logs')
|
|
562
|
-
`,Y+=` .column('status')
|
|
563
|
-
`,Y+=` .execute()
|
|
564
|
-
|
|
565
|
-
`,Y+=` await db.schema
|
|
566
|
-
`,Y+=` .createIndex('idx_query_logs_duration')
|
|
567
|
-
`,Y+=` .on('query_logs')
|
|
568
|
-
`,Y+=` .column('duration')
|
|
569
|
-
`,Y+=` .execute()
|
|
570
|
-
|
|
571
|
-
`,Y+=`}
|
|
572
|
-
`;let X=`${new Date().getTime().toString()}-create-query-logs-table.ts`,J=F.userMigrationsPath(X);await Bun.write(J,Y),M.success(`Created migration: ${y(X)}`)}function R0(Z){return`\x1B[3m${Z}\x1B[23m`}async function N6(){return await t1(),await WY(),await JY(),n1("All tables dropped successfully!")}async function t1(){let Z=e1([s.userModelsPath("*.ts"),s.storagePath("framework/defaults/app/Models/**/*.ts")],{absolute:!0}),Y=await vY();for(let $ of Y){if(!/^[a-z_][\w]*$/i.test($))throw Error(`[mysql] Refusing to drop table with unsafe name: ${$}`);await K.unsafe(`DROP TABLE IF EXISTS \`${$}\``).execute()}await hY();for(let $ of Z){let X=(await import($)).default,J=await O0(X,$);for(let W of J){if(!/^[a-z_][\w]*$/i.test(W.table))throw Error(`[mysql] Refusing to drop pivot table with unsafe name: ${W.table}`);await K.unsafe(`DROP TABLE IF EXISTS \`${W.table}\``).execute()}}}async function v6(Z){let Y=(await import(Z)).default,$=s.basename(Z),X=UZ(Y,Z),J=JSON.stringify(Y.attributes,null,2),W=s.frameworkPath(`cache/models/${$}`),z=!1;if(i1.existsSync(W)){b.info(`Fields have already been generated for ${X}`);let I=await c($);if(JSON.stringify(I,null,2)===J){b.debug(`Fields have not changed for ${X}`);return}z=!0,b.debug(`Fields have changed for ${X}`)}else b.debug(`Fields have not been generated for ${X}`);await Bun.$`mkdir -p ${s.frameworkPath("cache/models")} && cp ${Z} ${W}`;let H=await a(X);if(b.debug(`Has ${X} been migrated? ${H}`),z)await Z4(Z);else await B0(Z)}async function f6(){await Promise.all([H0(),Q0(),z0(),GZ(),fY(),J0(),E0(),V0()])}async function B0(Z){b.debug("createTableMigration modelPath:",Z);let Y=(await import(Z)).default,$=UZ(Y,Z),X=Y.traits?.useAuth&&typeof Y.traits.useAuth!=="boolean"?Y.traits.useAuth.useTwoFactor:!1;await Y4(Y,Z);let J=Y?.traits?.useTimestamps??Y?.traits?.timestampable??!0,W=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),H=Y?.traits?.useSoftDeletes??Y?.traits?.softDeletable??!1,I=(typeof Y.traits?.useAuth==="object"&&Y.traits.useAuth.usePasskey)??!1,Q=Y.traits?.billable||!1,E=Y.traits?.useUuid||!1;if(Q&&$==="users")await B0(s.frameworkPath("defaults/app/Models/Subscription.ts"));let G=`import type { Database } from '@stacksjs/database'
|
|
573
|
-
`;if(G+=`import { sql } from '@stacksjs/database'
|
|
574
|
-
|
|
575
|
-
`,G+=`export async function up(db: Database<any>) {
|
|
576
|
-
`,G+=` await (db as any).schema
|
|
577
|
-
`,G+=` .createTable('${$}')
|
|
578
|
-
`,G+=` .addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
|
|
579
|
-
`,E)G+=` .addColumn('uuid', 'varchar(255)')
|
|
580
|
-
`;if(W){let V=Y.traits?.useSocials||[];if(V.includes("google"))G+=` .addColumn('google_id', 'varchar(255)')
|
|
581
|
-
`;if(V.includes("github"))G+=` .addColumn('github_id', 'varchar(255)')
|
|
582
|
-
`;if(V.includes("apple"))G+=` .addColumn('apple_id', 'varchar(255)')
|
|
583
|
-
`;if(V.includes("twitter"))G+=` .addColumn('twitter_id', 'varchar(255)')
|
|
584
|
-
`;if(V.includes("facebook"))G+=` .addColumn('facebook_id', 'varchar(255)')
|
|
585
|
-
`}for(let[V,L]of n(Y.attributes)){let _=L,x=IY(V),B=o(_.validation?.rule);G+=` .addColumn('${x}', ${B}`;let f="isRequired"in(_.validation?.rule??{})?(_.validation?.rule).isRequired:!1;if(f||_.unique||_.default!==void 0){if(G+=", col => col",f)G+=".notNull()";if(_.unique)G+=".unique()";if(_.default!==void 0)if(typeof _.default==="string")G+=`.defaultTo('${_.default.replace(/'/g,"\\'")}')`;else if(_.default===null)G+=".defaultTo(null)";else G+=`.defaultTo(${_.default})`;G+=""}G+=`)
|
|
586
|
-
`}if(X!==!1&&X)G+=` .addColumn('two_factor_secret', 'varchar(255)')
|
|
587
|
-
`;if(Q)G+=` .addColumn('stripe_id', 'varchar(255)')
|
|
588
|
-
`;if(I)G+=` .addColumn('public_passkey', 'varchar(255)')
|
|
589
|
-
`;if(J)G+=` .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
590
|
-
`,G+=` .addColumn('updated_at', 'timestamp')
|
|
591
|
-
`;if(H)G+=` .addColumn('deleted_at', 'timestamp')
|
|
592
|
-
`;if(G+=` .execute()
|
|
593
|
-
`,G+=X4($),z){let V=t(Y,$);if(V){let L=QY(Y,$);G+=`
|
|
594
|
-
// Create upvote table
|
|
595
|
-
`,G+=` await (db as any).schema
|
|
596
|
-
`,G+=` .createTable('${V}')
|
|
597
|
-
`,G+=` .addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
|
|
598
|
-
`,G+=` .addColumn('${L}', 'integer', col => col.notNull())
|
|
599
|
-
`,G+=` .addColumn('user_id', 'integer', col => col.notNull())
|
|
600
|
-
`,G+=` .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
601
|
-
`,G+=` .addColumn('updated_at', 'timestamp')
|
|
602
|
-
`,G+=` .execute()
|
|
603
|
-
|
|
604
|
-
`,G+=` // Add indexes for upvote table
|
|
605
|
-
`,G+=` await (db as any).schema.createIndex('${V}_${L}_index').on('${V}').column('${L}').execute()
|
|
606
|
-
`,G+=` await (db as any).schema.createIndex('${V}_user_${L}_unique').on('${V}').columns(['user_id', '${L}']).unique().execute()
|
|
607
|
-
`,G+=` await (db as any).schema.createIndex('${V}_id_index').on('${V}').column('id').execute()
|
|
608
|
-
`}}G+=`}
|
|
609
|
-
`;let U=`${new Date().getTime().toString()}-create-${$}-table.ts`,A=s.userMigrationsPath(U);b.debug(A),await Bun.write(A,G),b.success(`Created migration: ${R0(U)}`)}async function Y4(Z,Y){let $=await O0(Z,Y),X=new Set;if(!$.length)return;for(let J of $){if(X.has(J.table))continue;if(await zY(J.table)){X.add(J.table);continue}let z=`import type { Database } from '@stacksjs/database'
|
|
610
|
-
`;z+=`import { sql } from '@stacksjs/database'
|
|
611
|
-
|
|
612
|
-
`,z+=`export async function up(db: Database<any>) {
|
|
613
|
-
`,z+=` await (db as any).schema
|
|
614
|
-
`,z+=` .createTable('${J.table}')
|
|
615
|
-
`,z+=` .addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
|
|
616
|
-
`,z+=` .addColumn('${J.firstForeignKey}', 'integer')
|
|
617
|
-
`,z+=` .addColumn('${J.secondForeignKey}', 'integer')
|
|
618
|
-
`,z+=` .addColumn('created_at', 'timestamp', col => col.defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
619
|
-
`,z+=` .execute()
|
|
620
|
-
`,z+=` }
|
|
621
|
-
`;let I=`${new Date().getTime().toString()}-create-${J.table}-table.ts`,Q=s.userMigrationsPath(I);await Bun.write(Q,z),X.add(J.table),b.success(`Created pivot migration: ${I}`)}}async function Z4(Z){let Y=(await import(Z)).default,$=o1(Y,Z),X=UZ(Y,Z),J=!1,z=await c($)??{},H=Y.attributes,I=GY(Object.keys(z),Object.keys(H)),Q=I?.added||[],E=I?.removed||[],G=`import type { Database } from '@stacksjs/database'
|
|
622
|
-
`;if(G+=`import { sql } from '@stacksjs/database'
|
|
623
|
-
|
|
624
|
-
`,G+=`export async function up(db: Database<any>) {
|
|
625
|
-
`,Q.length||E.length)J=!0,G+=` await (db as any).schema.alterTable('${X}')
|
|
626
|
-
`;let S=UY(z,H);for(let V of S){J=!0;let L=IY(V.key);G+=` .modifyColumn('${L}', 'varchar(${V.max})')
|
|
627
|
-
`}let U=Object.values(z).map((V)=>V.order),A=Object.values(H).map((V)=>V.order);if(!HY(U,A))J=!0,G+=J4(Y.attributes,X);if(J){G+=` .execute()
|
|
628
|
-
`,G+=`}
|
|
629
|
-
`;let L=`${new Date().getTime().toString()}-alter-${X}-table.ts`,_=s.userMigrationsPath(L);await Bun.write(_,G),b.success(`Created alter migration: ${R0(L)}`)}}function $4(Z,Y){if(Y.unique||Y.where){let X=Y.unique?"UNIQUE ":"",J=Y.columns.map((z)=>IY(z)).join(", "),W=Y.where?` WHERE ${Y.where}`:"";return` await db.unsafe(\`CREATE ${X}INDEX IF NOT EXISTS \\\`${Y.name}\\\` ON \\\`${Z}\\\` (${J})${W}\`).execute()
|
|
630
|
-
`}let $=Y.columns.map((X)=>`'${IY(X)}'`).join(", ");return` await (db as any).schema.createIndex('${Y.name}').on('${Z}').columns([${$}]).execute()
|
|
631
|
-
`}function X4(Z){return` await (db as any).schema.createIndex('${Z}_id_index').on('${Z}').column('id').execute()
|
|
632
|
-
`}function J4(Z,Y){let $=n(Z),X="",J="";for(let[W]of $){let z=IY(W);if(J)X+=`await sql\`
|
|
633
|
-
ALTER TABLE ${Y}
|
|
634
|
-
MODIFY COLUMN ${z} VARCHAR(255) NOT NULL AFTER ${IY(J)};
|
|
635
|
-
\`.execute(db)
|
|
636
|
-
|
|
637
|
-
`;J=z}return X}D();import{log as C}from"@stacksjs/logging";import{ok as W4}from"@stacksjs/error-handling";import{getModelName as z4,getPivotTables as j0,getTableName as pY}from"@stacksjs/orm";import{path as T}from"@stacksjs/path";import{fs as KY,globSync as w0}from"@stacksjs/storage";import{plural as G4,snakeCase as qY}from"@stacksjs/strings";function IZ(Z){return`\x1B[3m${Z}\x1B[23m`}async function H4(){let Z=await _4(),Y=w0([T.userModelsPath("*.ts"),T.storagePath("framework/defaults/app/Models/**/*.ts")],{absolute:!0});await K0();for(let $ of Z)await K.unsafe(`DROP TABLE IF EXISTS "${$}" CASCADE`).execute();await U4();for(let $ of Y){let X=(await import($)).default,J=await j0(X,$);for(let W of J)await K.unsafe(`DROP TABLE IF EXISTS "${W.table}" CASCADE`).execute()}}async function U4(){await K.unsafe('DROP TABLE IF EXISTS "passkeys" CASCADE').execute(),await K.unsafe('DROP TABLE IF EXISTS "password_resets" CASCADE').execute(),await K.unsafe('DROP TABLE IF EXISTS "query_logs" CASCADE').execute(),await K.unsafe('DROP TABLE IF EXISTS "categorizables" CASCADE').execute(),await K.unsafe('DROP TABLE IF EXISTS "commentables" CASCADE').execute(),await K.unsafe('DROP TABLE IF EXISTS "comments" CASCADE').execute(),await K.unsafe('DROP TABLE IF EXISTS "tags" CASCADE').execute(),await K.unsafe('DROP TABLE IF EXISTS "taggables" CASCADE').execute(),await K.unsafe('DROP TABLE IF EXISTS "commentable_upvotes" CASCADE').execute()}async function a6(){await U0(),await I0(),await G0(),await _0(),await W0(),await A0(),await fY(),await L0(),await HZ()}async function n6(){return await H4(),await WY(),await JY(),await K.unsafe('CREATE TABLE IF NOT EXISTS "migrations" (id SERIAL PRIMARY KEY)').execute(),await K.unsafe('CREATE TABLE IF NOT EXISTS "migration_locks" (id SERIAL PRIMARY KEY)').execute(),await K.unsafe('CREATE TABLE IF NOT EXISTS "activities" (id SERIAL PRIMARY KEY)').execute(),W4("All tables dropped successfully!")}async function o6(Z){if((await KY.promises.readdir(T.userMigrationsPath(""))).length===0){C.debug("No migrations found in the database folder, clearing the model snapshot cache...");let E=T.frameworkPath("cache/models");if(KY.existsSync(E)){let G=await KY.promises.readdir(E);if(G.length){for(let S of G)if(S.endsWith(".ts"))await KY.promises.unlink(T.frameworkPath(`cache/models/${S}`))}}}let $=(await import(Z)).default,X=T.basename(Z),J=pY($,Z),W=JSON.stringify($.attributes,null,2),z=T.frameworkPath(`cache/models/${X}`),H=!1;if(KY.existsSync(z)){C.info(`Fields have already been generated for ${J}`);let E=await c(X);if(JSON.stringify(E,null,2)===W){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 ${T.frameworkPath("cache/models")} && cp ${Z} ${z}`;let I=await a(J);if(C.debug(`Has ${J} been migrated? ${I}`),($.traits?.billable||!1)&&J==="users")await QZ(T.frameworkPath("defaults/app/Models/Subscription.ts"));if(H)await I4(Z);else await QZ(Z)}async function QZ(Z){C.debug("createTableMigration modelPath:",Z);let Y=(await import(Z)).default,$=pY(Y,Z),X=Y.traits?.useAuth&&typeof Y.traits.useAuth!=="boolean"?Y.traits.useAuth.useTwoFactor:!1;await Q4(Y,Z);let J=Y.traits?.useTimestamps??Y.traits?.timestampable??!0,W=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),H=Y.traits?.useSoftDeletes??Y.traits?.softDeletable??!1,I=(typeof Y.traits?.useAuth==="object"&&Y.traits.useAuth.usePasskey)??!1,Q=Y.traits?.billable||!1,E=Y.traits?.useUuid||!1;if(Q&&$==="users")await QZ(T.frameworkPath("defaults/app/Models/Subscription.ts"));let G=`import type { Database } from '@stacksjs/database'
|
|
638
|
-
`;if(G+=`import { sql } from '@stacksjs/database'
|
|
639
|
-
|
|
640
|
-
`,G+=`export async function up(db: Database<any>) {
|
|
641
|
-
`,G+=` await (db as any).schema
|
|
642
|
-
`,G+=` .createTable('${$}')
|
|
643
|
-
`,G+=` .addColumn('id', 'serial', (col) => col.primaryKey())
|
|
644
|
-
`,E)G+=` .addColumn('uuid', 'uuid', (col) => col.defaultTo(sql.raw('gen_random_uuid()')))
|
|
645
|
-
`;for(let[V,L]of n(Y.attributes)){let _=L,x=qY(V),B=o(_.validation?.rule,"postgres"),f="isRequired"in(_.validation?.rule??{})?(_.validation?.rule).isRequired:!1;if(G+=` .addColumn('${x}', ${B}`,f||_.unique||_.default!==void 0){if(G+=", col => col",f)G+=".notNull()";if(_.unique)G+=".unique()";if(_.default!==void 0)if(typeof _.default==="string")G+=`.defaultTo('${_.default.replace(/'/g,"\\'")}')`;else if(_.default===null)G+=".defaultTo(null)";else G+=`.defaultTo(${_.default})`;G+=""}G+=`)
|
|
646
|
-
`}if(W){let V=Y.traits?.useSocials||[];if(V.includes("google"))G+=` .addColumn('google_id', 'text')
|
|
647
|
-
`;if(V.includes("github"))G+=` .addColumn('github_id', 'text')
|
|
648
|
-
`;if(V.includes("apple"))G+=` .addColumn('apple_id', 'text')
|
|
649
|
-
`;if(V.includes("twitter"))G+=` .addColumn('twitter_id', 'text')
|
|
650
|
-
`;if(V.includes("facebook"))G+=` .addColumn('facebook_id', 'text')
|
|
651
|
-
`}if(z){let V=Array.isArray(Y.traits?.likeable)?Y.traits.likeable:[];for(let L of V)G+=` .addColumn('${L}_count', 'integer', (col) => col.defaultTo(0))
|
|
652
|
-
`}if(X!==!1&&X)G+=` .addColumn('two_factor_secret', 'text')
|
|
653
|
-
`;if(Q)G+=` .addColumn('stripe_id', 'text')
|
|
654
|
-
`;if(I)G+=` .addColumn('public_passkey', 'text')
|
|
655
|
-
`;if(J)G+=` .addColumn('created_at', 'timestamptz', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
656
|
-
`,G+=` .addColumn('updated_at', 'timestamptz')
|
|
657
|
-
`;if(H)G+=` .addColumn('deleted_at', 'timestamptz')
|
|
658
|
-
`;if(G+=` .execute()
|
|
659
|
-
`,G+=V4($),z){let V=t(Y,$);if(V){let L=QY(Y,$);G+=`
|
|
660
|
-
// Create upvote table
|
|
661
|
-
`,G+=` await (db as any).schema
|
|
662
|
-
`,G+=` .createTable('${V}')
|
|
663
|
-
`,G+=` .addColumn('id', 'serial', (col) => col.primaryKey())
|
|
664
|
-
`,G+=` .addColumn('${L}', 'integer', (col) => col.notNull())
|
|
665
|
-
`,G+=` .addColumn('user_id', 'integer', (col) => col.notNull())
|
|
666
|
-
`,G+=` .addColumn('created_at', 'timestamptz', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
667
|
-
`,G+=` .addColumn('updated_at', 'timestamptz')
|
|
668
|
-
`,G+=` .execute()
|
|
669
|
-
|
|
670
|
-
`,G+=` // Add indexes for upvote table
|
|
671
|
-
`,G+=` await (db as any).schema.createIndex('${V}_${L}_index').on('${V}').column('${L}').execute()
|
|
672
|
-
`,G+=` await (db as any).schema.createIndex('${V}_user_${L}_unique').on('${V}').columns(['user_id', '${L}']).unique().execute()
|
|
673
|
-
`,G+=` await (db as any).schema.createIndex('${V}_id_index').on('${V}').column('id').execute()
|
|
674
|
-
`}}G+=`}
|
|
675
|
-
`;let U=`${new Date().getTime().toString()}-create-${$}-table.ts`,A=T.userMigrationsPath(U);await Bun.write(A,G),C.success(`Created migration: ${IZ(U)}`)}async function Q4(Z,Y){let $=await j0(Z,Y),X=new Set;if(!$.length)return;for(let J of $){if(X.has(J.table))continue;if(await zY(J.table)){X.add(J.table);continue}let z=`import type { Database } from '@stacksjs/database'
|
|
676
|
-
`;z+=`import { sql } from '@stacksjs/database'
|
|
677
|
-
|
|
678
|
-
`,z+=`export async function up(db: Database<any>) {
|
|
679
|
-
`,z+=` await (db as any).schema
|
|
680
|
-
`,z+=` .createTable('${J.table}')
|
|
681
|
-
`,z+=` .addColumn('id', 'serial', (col) => col.primaryKey())
|
|
682
|
-
`,z+=` .addColumn('${J.firstForeignKey}', 'integer', (col) => col.notNull())
|
|
683
|
-
`,z+=` .addColumn('${J.secondForeignKey}', 'integer', (col) => col.notNull())
|
|
684
|
-
`,z+=` .addColumn('created_at', 'timestamptz', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
685
|
-
`,z+=` .execute()
|
|
686
|
-
|
|
687
|
-
`,z+=` await (db as any).schema
|
|
688
|
-
`,z+=` .alterTable('${J.table}')
|
|
689
|
-
`,z+=` .addForeignKeyConstraint('${J.table}_${J.firstForeignKey}_fkey', ['${J.firstForeignKey}'], '${G4(J.firstForeignKey?.replace(/_id$/,"")||"")}', ['id'], (cb) => cb.onDelete('cascade'))
|
|
690
|
-
`,z+=` .execute()
|
|
691
|
-
|
|
692
|
-
`,z+=` await (db as any).schema
|
|
693
|
-
`,z+=` .alterTable('${J.table}')
|
|
694
|
-
`,z+=` .addUniqueConstraint('${J.table}_unique', ['${J.firstForeignKey}', '${J.secondForeignKey}'])
|
|
695
|
-
`,z+=` .execute()
|
|
696
|
-
|
|
697
|
-
`,z+=` await (db as any).schema
|
|
698
|
-
`,z+=` .createIndex('${J.table}_${J.firstForeignKey}_idx')
|
|
699
|
-
`,z+=` .on('${J.table}')
|
|
700
|
-
`,z+=` .column('${J.firstForeignKey}')
|
|
701
|
-
`,z+=` .execute()
|
|
702
|
-
|
|
703
|
-
`,z+=` await (db as any).schema
|
|
704
|
-
`,z+=` .createIndex('${J.table}_${J.secondForeignKey}_idx')
|
|
705
|
-
`,z+=` .on('${J.table}')
|
|
706
|
-
`,z+=` .column('${J.secondForeignKey}')
|
|
707
|
-
`,z+=` .execute()
|
|
708
|
-
`,z+=`}
|
|
709
|
-
`;let I=`${new Date().getTime().toString()}-create-${J.table}-table.ts`,Q=T.userMigrationsPath(I);await Bun.write(Q,z),X.add(J.table),C.success(`Created migration: ${IZ(I)}`)}}async function I4(Z){let Y=(await import(Z)).default,$=z4(Y,Z),X=pY(Y,Z),J=!1,z=await c($)??{},H=Y.attributes,I=GY(Object.keys(z),Object.keys(H)),Q=I?.added||[],E=I?.removed||[],G=`import type { Database } from '@stacksjs/database'
|
|
710
|
-
`;if(G+=`import { sql } from '@stacksjs/database'
|
|
711
|
-
|
|
712
|
-
`,G+=`export async function up(db: Database<any>) {
|
|
713
|
-
`,Q.length||E.length)J=!0,G+=` await (db as any).schema.alterTable('${X}')
|
|
714
|
-
`;for(let V of Q){let L=H[V],_=o(L.validation?.rule,"postgres"),x=qY(V),B="isRequired"in(L.validation?.rule??{})?(L.validation?.rule).isRequired:!1;if(G+=` .addColumn('${x}', '${_}'`,B||L.unique||L.default!==void 0){if(G+=", col => col",B)G+=".notNull()";if(L.unique)G+=".unique()";if(L.default!==void 0)if(typeof L.default==="string")G+=`.defaultTo('${L.default}')`;else if(L.default===null)G+=".defaultTo(null)";else G+=`.defaultTo(${L.default})`;G+=""}G+=`)
|
|
715
|
-
`}for(let V of E)G+=` .dropColumn('${V}')
|
|
716
|
-
`;let S=UY(z,H);for(let V of S){J=!0;let L=qY(V.key);G+=` .alterColumn('${L}', (col) => col.setDataType('text'))
|
|
717
|
-
`}let U=Object.values(z).map((V)=>V.order),A=Object.values(H).map((V)=>V.order);if(!HY(U,A))J=!0;if(J){G+=` .execute()
|
|
718
|
-
`,G+=`}
|
|
719
|
-
`;let L=`${new Date().getTime().toString()}-alter-${X}-table.ts`,_=T.userMigrationsPath(L);await Bun.write(_,G),C.success(`Created alter migration: ${IZ(L)}`)}}function K4(Z,Y){if(Y.unique||Y.where){let X=Y.unique?"UNIQUE ":"",J=Y.columns.map((z)=>qY(z)).join(", "),W=Y.where?` WHERE ${Y.where}`:"";return` await db.unsafe(\`CREATE ${X}INDEX IF NOT EXISTS "${Y.name}" ON "${Z}" (${J})${W}\`).execute()
|
|
720
|
-
`}let $=Y.columns.map((X)=>`'${qY(X)}'`).join(", ");return` await (db as any).schema.createIndex('${Y.name}').on('${Z}').columns([${$}]).execute()
|
|
721
|
-
`}function V4(Z){return` await (db as any).schema.createIndex('${Z}_id_index').on('${Z}').column('id').execute()
|
|
722
|
-
`}async function _4(){let Z=w0([T.userModelsPath("*.ts"),T.storagePath("framework/defaults/app/Models/**/*.ts")],{absolute:!0}),Y=[];for(let $ of Z){let X=(await import($)).default,J=pY(X,$);Y.push(J)}return Y}D();import{log as v}from"@stacksjs/logging";import{app as L4}from"@stacksjs/config";import{ok as E4}from"@stacksjs/error-handling";import{fetchOtherModelRelations as A4,getModelName as x0,getPivotTables as q0,getTableName as uY}from"@stacksjs/orm";import{path as N}from"@stacksjs/path";import{fs as k0,globSync as R4}from"@stacksjs/storage";import{snakeCase as YY}from"@stacksjs/strings";function S0(Z){return`\x1B[3m${Z}\x1B[23m`}async function H7(){return await WY(),await JY(),await O4(),E4("All tables dropped successfully!")}async function U7(){try{for(let Z of rY)await K.unsafe(Z).execute()}catch(Z){v.debug(`[sqlite] Failed to apply pragmas: ${Z.message}`)}}async function O4(){let Z=R4([N.userModelsPath("*.ts"),N.storagePath("framework/defaults/app/Models/**/*.ts")],{absolute:!0}),Y=await vY(),$=/^[a-z_][\w]*$/i;await K.unsafe("PRAGMA foreign_keys = OFF").execute();try{for(let X of Y){if(!$.test(X))throw Error(`[sqlite] Refusing to drop table with unsafe name: ${X}`);await K.unsafe(`DROP TABLE IF EXISTS "${X}"`).execute()}await K.unsafe('DROP TABLE IF EXISTS "migrations"').execute(),await hY();for(let X of Z){let J=(await import(X)).default,W=await q0(J,X);for(let z of W){if(!$.test(z.table))throw Error(`[sqlite] Refusing to drop pivot table with unsafe name: ${z.table}`);await K.unsafe(`DROP TABLE IF EXISTS "${z.table}"`).execute()}}}finally{await K.unsafe("PRAGMA foreign_keys = ON").execute()}}function Q7(){if(L4.env==="testing")return B4();return N.userDatabasePath("stacks.sqlite")}function B4(){return N.userDatabasePath("stacks_testing.sqlite")}async function I7(Z){let Y=(await import(Z)).default,$=N.basename(Z),X=await uY(Y,Z),J=JSON.stringify(Y.attributes,null,2),W=N.frameworkPath(`cache/models/${$}`),z=!1;if(k0.existsSync(W)){v.debug(`Fields have already been generated for ${X}`);let I=await c($);if(JSON.stringify(I,null,2)===J){v.debug(`Fields have not changed for ${X}`);return}z=!0,v.debug(`Fields have changed for ${X}`)}else v.debug(`Fields have not been generated for ${X}`);await Bun.$`mkdir -p ${N.frameworkPath("cache/models")} && cp ${Z} ${W}`;let H=!1;if(v.debug(`Has ${X} been migrated? ${H}`),z)await S4(Z);else await j4(Z)}async function K7(Z){let Y=(await import(Z)).default,$=N.basename(Z),X=await uY(Y,Z),J=JSON.stringify(Y.attributes,null,2),W=N.frameworkPath(`cache/models/${$}`);if(k0.existsSync(W)){v.debug(`Fields have already been generated for ${X}`);let z=await c($);if(JSON.stringify(z,null,2)===J){v.debug(`Fields have not changed for ${X}`);return}}await Bun.$`mkdir -p ${N.frameworkPath("cache/models")} && cp ${Z} ${W}`}async function j4(Z){v.debug("createTableMigration modelPath:",Z);let Y=(await import(Z)).default,$=uY(Y,Z),X=x0(Y,Z),J=Y.traits?.useAuth&&typeof Y.traits.useAuth!=="boolean"?Y.traits.useAuth.useTwoFactor:!1;await w4(Y,Z);let W=await A4(X),z=Y?.traits?.useTimestamps??Y?.traits?.timestampable??!0,H=Y?.traits?.useSocials&&Array.isArray(Y.traits.useSocials)&&Y.traits.useSocials.length>0,I=Array.isArray(Y?.traits?.likeable)?Y.traits.likeable.length>0:Boolean(Y?.traits?.likeable),Q=Y?.traits?.useSoftDeletes??Y?.traits?.softDeletable??!1,E=(typeof Y.traits?.useAuth==="object"&&Y.traits.useAuth.usePasskey)??!1,G=Y.traits?.billable||!1,S=Y.traits?.useUuid||!1,U=`import type { Database } from '@stacksjs/database'
|
|
723
|
-
`;if(U+=`import { sql } from '@stacksjs/database'
|
|
724
|
-
|
|
725
|
-
`,U+=`export async function up(db: Database<any>) {
|
|
726
|
-
`,U+=` await (db as any).schema
|
|
727
|
-
`,U+=` .createTable('${$}')
|
|
728
|
-
`,U+=` .addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
|
|
729
|
-
`,S)U+=` .addColumn('uuid', 'text')
|
|
730
|
-
`;if(H){let _=Y.traits?.useSocials||[];if(_.includes("google"))U+=` .addColumn('google_id', 'text')
|
|
731
|
-
`;if(_.includes("github"))U+=` .addColumn('github_id', 'text')
|
|
732
|
-
`;if(_.includes("apple"))U+=` .addColumn('apple_id', 'text')
|
|
733
|
-
`;if(_.includes("twitter"))U+=` .addColumn('twitter_id', 'text')
|
|
734
|
-
`;if(_.includes("facebook"))U+=` .addColumn('facebook_id', 'text')
|
|
735
|
-
`}for(let[_,x]of n(Y.attributes)){let B=x,f=YY(_),kY=o(B.validation?.rule,"sqlite");U+=` .addColumn('${f}', ${kY}`;let w=B.validation?.rule.isRequired;if(w||B.unique||B.default!==void 0){if(U+=", col => col",w)U+=".notNull()";if(B.unique)U+=".unique()";if(B.default!==void 0)if(typeof B.default==="string")U+=`.defaultTo('${B.default}')`;else if(B.default===null)U+=".defaultTo(null)";else U+=`.defaultTo(${B.default})`;U+=""}U+=`)
|
|
736
|
-
`}if(J!==!1&&J)U+=` .addColumn('two_factor_secret', 'text')
|
|
737
|
-
`;if(G)U+=` .addColumn('stripe_id', 'text')
|
|
738
|
-
`;if(Q)U+=` .addColumn('deleted_at', 'timestamp')
|
|
739
|
-
`;if(E)U+=` .addColumn('public_passkey', 'text')
|
|
740
|
-
`;if(W?.length)for(let _ of W){if(!_.foreignKey)continue;U+=` .addColumn('${_.foreignKey}', 'integer', (col) =>
|
|
741
|
-
col.references('${_.relationTable}.id').onDelete('cascade')
|
|
742
|
-
)
|
|
743
|
-
`}if(z)U+=" .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql`CURRENT_TIMESTAMP`))\n",U+=` .addColumn('updated_at', 'timestamp')
|
|
744
|
-
`;if(U+=` .execute()
|
|
745
|
-
|
|
746
|
-
`,W?.length)for(let _ of W){if(!_.foreignKey)continue;U+=k4($,_.foreignKey)}if(Y.indexes?.length){U+=`
|
|
747
|
-
`;for(let _ of Y.indexes)U+=KZ($,_)}if(U+=q4($),I){let _=t(Y,$);if(_){let x=QY(Y,$);U+=`
|
|
748
|
-
// Create upvote table
|
|
749
|
-
`,U+=` await (db as any).schema
|
|
750
|
-
`,U+=` .createTable('${_}')
|
|
751
|
-
`,U+=` .addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
|
|
752
|
-
`,U+=` .addColumn('${x}', 'integer', col => col.notNull())
|
|
753
|
-
`,U+=` .addColumn('user_id', 'integer', col => col.notNull())
|
|
754
|
-
`,U+=" .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql`CURRENT_TIMESTAMP`))\n",U+=` .addColumn('updated_at', 'timestamp')
|
|
755
|
-
`,U+=` .execute()
|
|
756
|
-
|
|
757
|
-
`,U+=` // Add indexes for upvote table
|
|
758
|
-
`,U+=` await (db as any).schema.createIndex('${_}_${x}_index').on('${_}').column('${x}').execute()
|
|
759
|
-
`,U+=` await (db as any).schema.createIndex('${_}_user_${x}_unique').on('${_}').columns(['user_id', '${x}']).unique().execute()
|
|
760
|
-
`,U+=` await (db as any).schema.createIndex('${_}_id_index').on('${_}').column('id').execute()
|
|
761
|
-
`}}U+=`}
|
|
762
|
-
`;let V=`${new Date().getTime().toString()}-create-${$}-table.ts`,L=N.userMigrationsPath(V);await Bun.write(L,U),v.success(`Created migration: ${S0(V)}`)}async function w4(Z,Y){let $=await q0(Z,Y);if(!$.length)return;for(let X of $){if(await zY(X.table))return;let W=`import type { Database } from '@stacksjs/database'
|
|
763
|
-
`;W+=`import { sql } from '@stacksjs/database'
|
|
764
|
-
|
|
765
|
-
`,W+=`export async function up(db: Database<any>) {
|
|
766
|
-
`,W+=` await (db as any).schema
|
|
767
|
-
`,W+=` .createTable('${X.table}')
|
|
768
|
-
`,W+=` .addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
|
|
769
|
-
`,W+=` .addColumn('${X.firstForeignKey}', 'integer')
|
|
770
|
-
`,W+=` .addColumn('${X.secondForeignKey}', 'integer')
|
|
771
|
-
`,W+=` .addColumn('created_at', 'timestamp', col => col.defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
772
|
-
`,W+=` .execute()
|
|
773
|
-
`,W+=` }
|
|
774
|
-
`;let H=`${new Date().getTime().toString()}-create-${X.table}-table.ts`,I=N.userMigrationsPath(H);await Bun.write(I,W),v.success(`Created pivot migration: ${H}`)}}async function S4(Z){let Y=(await import(Z)).default,$=x0(Y,Z),X=uY(Y,Z),J=!1,z=(await import(N.frameworkPath(`cache/models/${$}.ts`))).default,I=await c($)??{},Q=Y.attributes,E=GY(Object.keys(I),Object.keys(Q)),G=E?.added||[],S=E?.removed||[],U=`import type { Database } from '@stacksjs/database'
|
|
775
|
-
`;if(U+=`import { sql } from '@stacksjs/database'
|
|
776
|
-
|
|
777
|
-
`,U+=`export async function up(db: Database<any>) {
|
|
778
|
-
`,G.length||S.length)J=!0,U+=` await (db as any).schema.alterTable('${X}')
|
|
779
|
-
`;let A=UY(I,Q);for(let w of A){J=!0;let k=YY(w.key);U+=`await sql\`
|
|
780
|
-
ALTER TABLE ${X}
|
|
781
|
-
MODIFY COLUMN ${k} TEXT
|
|
782
|
-
\`.execute(db)
|
|
783
|
-
|
|
784
|
-
`}for(let w of G){let k=Q[w],O=o(k.validation?.rule,"sqlite"),h=YY(w),i=k.validation?.rule.isRequired;if(U+=` .addColumn('${h}', ${O}`,i||k.unique||k.default!==void 0){if(U+=", col => col",i)U+=".notNull()";if(k.unique)U+=".unique()";if(k.default!==void 0)if(typeof k.default==="string")U+=`.defaultTo('${k.default}')`;else if(k.default===null)U+=".defaultTo(null)";else U+=`.defaultTo(${k.default})`;U+=""}U+=`)
|
|
785
|
-
|
|
786
|
-
`}for(let w of S)U+=` .dropColumn('${w}')
|
|
787
|
-
`;if(G.length||S.length)U+=` .execute();
|
|
788
|
-
`;let V=Object.values(I).map((w)=>w.order),L=Object.values(Q).map((w)=>w.order);if(!HY(V,L))J=!0,U+=x4(Y.attributes,X);let _=z.indexes||[],x=Y.indexes||[];for(let w of _)if(!x.find((k)=>k.name===w.name))J=!0,U+=` await (db as any).schema.dropIndex('${w.name}').execute()
|
|
789
|
-
`;for(let w of x)if(!_.find((k)=>k.name===w.name))J=!0,U+=KZ(X,w);U+=`}
|
|
790
|
-
`;let f=`${new Date().getTime().toString()}-update-${X}-table.ts`,kY=N.userMigrationsPath(f);if(J)await Bun.write(kY,U),v.success(`Created migration: ${S0(f)}`)}function x4(Z,Y){let $=n(Z),X="",J="";for(let[W]of $){let z=YY(W);if(J)X+=`await sql\`
|
|
791
|
-
ALTER TABLE ${Y}
|
|
792
|
-
MODIFY COLUMN ${z} TEXT NOT NULL AFTER ${YY(J)};
|
|
793
|
-
\`.execute(db)
|
|
794
|
-
|
|
795
|
-
`;J=z}return X}function KZ(Z,Y){if(Y.unique||Y.where){let X=Y.unique?"UNIQUE ":"",J=Y.columns.map((z)=>YY(z)).join(", "),W=Y.where?` WHERE ${Y.where}`:"";return` await db.unsafe(\`CREATE ${X}INDEX IF NOT EXISTS "${Y.name}" ON "${Z}" (${J})${W}\`).execute()
|
|
796
|
-
`}let $=Y.columns.map((X)=>`\`${YY(X)}\``).join(", ");return` await (db as any).schema.createIndex('${Y.name}').on('${Z}').columns([${$}]).execute()
|
|
797
|
-
`}function q4(Z){return` await (db as any).schema.createIndex('${Z}_id_index').on('${Z}').column('id').execute()
|
|
798
|
-
`}function k4(Z,Y){return` await (db as any).schema.createIndex('${Z}_${Y}_index').on('${Z}').column(\`${Y}\`).execute()
|
|
799
|
-
|
|
800
|
-
`}import{log as D4}from"@stacksjs/logging";import{database as M4}from"@stacksjs/config";import{path as y4}from"@stacksjs/path";async function M7(){if(!["sqlite","mysql"].includes(F4()))return;if(await a("model_audits"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
801
|
-
import { sql } from '@stacksjs/database'
|
|
802
|
-
|
|
803
|
-
`;Y+=`export async function up(db: Database<any>) {
|
|
804
|
-
`,Y+=` await db.schema
|
|
805
|
-
`,Y+=` .createTable('model_audits')
|
|
806
|
-
`,Y+=` .addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
|
|
807
|
-
`,Y+=` .addColumn('auditable_type', 'varchar(255)', col => col.notNull())
|
|
808
|
-
`,Y+=` .addColumn('auditable_id', 'varchar(255)', col => col.notNull())
|
|
809
|
-
`,Y+=` .addColumn('event', 'varchar(32)', col => col.notNull())
|
|
810
|
-
`,Y+=` .addColumn('old_values', 'text')
|
|
811
|
-
`,Y+=` .addColumn('new_values', 'text')
|
|
812
|
-
`,Y+=` .addColumn('user_id', 'integer')
|
|
813
|
-
`,Y+=` .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
814
|
-
`,Y+=` .execute()
|
|
815
|
-
|
|
816
|
-
`,Y+=` await db.schema
|
|
817
|
-
`,Y+=` .createIndex('idx_model_audits_lookup')
|
|
818
|
-
`,Y+=` .on('model_audits')
|
|
819
|
-
`,Y+=` .columns(['auditable_type', 'auditable_id', 'created_at'])
|
|
820
|
-
`,Y+=` .execute()
|
|
821
|
-
`,Y+=`}
|
|
822
|
-
`;let X=`${new Date().getTime().toString()}-create-model-audits-table.ts`,J=y4.userMigrationsPath(X);await Bun.write(J,Y),D4.success("Created model_audits table migration")}function F4(){return M4.default||""}import{log as T4}from"@stacksjs/logging";import{database as P4}from"@stacksjs/config";import{path as N4}from"@stacksjs/path";async function v7(){if(["sqlite","mysql"].includes(v4())){if(await a("errors"))return;let Y=`import type { Database } from '@stacksjs/database'
|
|
823
|
-
import { sql } from '@stacksjs/database'
|
|
824
|
-
|
|
825
|
-
`;Y+=`export async function up(db: Database<any>) {
|
|
826
|
-
`,Y+=` await db.schema
|
|
827
|
-
`,Y+=` .createTable('errors')
|
|
828
|
-
`,Y+=` .addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
|
|
829
|
-
`,Y+=` .addColumn('type', 'varchar(255)', col => col.notNull())
|
|
830
|
-
`,Y+=` .addColumn('message', 'text', col => col.notNull())
|
|
831
|
-
`,Y+=` .addColumn('stack', 'text')
|
|
832
|
-
`,Y+=` .addColumn('status', 'integer', col => col.notNull().defaultTo(0))
|
|
833
|
-
`,Y+=` .addColumn('user_id', 'integer')
|
|
834
|
-
`,Y+=` .addColumn('additional_info', 'text')
|
|
835
|
-
`,Y+=` .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
836
|
-
`,Y+=` .addColumn('updated_at', 'timestamp')
|
|
837
|
-
`,Y+=` .execute()
|
|
838
|
-
`,Y+=`}
|
|
839
|
-
`;let X=`${new Date().getTime().toString()}-create-errors-table.ts`,J=N4.userMigrationsPath(X);await Bun.write(J,Y),T4.success("Created errors table")}}function v4(){return P4.default||""}import{err as f4,ok as h4}from"@stacksjs/error-handling";import{existsSync as VY,readdirSync as p4,writeFileSync as u4,mkdirSync as c4}from"fs";import{join as VZ}from"path";import D0 from"process";import cY from"bun:sqlite";import{env as M0}from"@stacksjs/env";function _Z(){return M0.DB_CONNECTION||"sqlite"}function y0(){return VZ(D0.cwd(),"database","migrations")}function b4(){try{let Z=y0();if(!VY(Z))return!1;return p4(Z).some(($)=>$.includes("create-jobs-table"))}catch{return!1}}async function C4(){let Z=bY();if(VY(Z))try{let $=new cY(Z),X=$.query("SELECT name FROM sqlite_master WHERE type='table' AND name='job_batches'").get();return $.close(),X!==null}catch{}if(_Z()!=="sqlite")try{let{db:$}=await Promise.resolve().then(() => (D(),e));return await $.selectFrom("job_batches").select("id").limit(1).execute(),!0}catch{return!1}return!1}function bY(){let Z=M0.APP_ROOT||D0.cwd();return VZ(Z,"database","stacks.sqlite")}async function d4(){let Z=_Z(),Y=bY();if(VY(Y))try{let $=new cY(Y),X=$.query("SELECT name FROM sqlite_master WHERE type='table' AND name='jobs'").get();return $.close(),X!==null}catch{}if(Z!=="sqlite")try{let{db:$}=await Promise.resolve().then(() => (D(),e));return await $.selectFrom("jobs").select("id").limit(1).execute(),!0}catch{return!1}return!1}async function d7(){try{let Z=_Z();if(["sqlite","mysql","postgres"].includes(Z)){if(!b4()){let J="";if(Z==="sqlite")J=`-- Create jobs table
|
|
840
|
-
CREATE TABLE IF NOT EXISTS jobs (
|
|
841
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
842
|
-
queue TEXT NOT NULL DEFAULT 'default',
|
|
843
|
-
payload TEXT NOT NULL,
|
|
844
|
-
attempts INTEGER NOT NULL DEFAULT 0,
|
|
845
|
-
reserved_at INTEGER,
|
|
846
|
-
available_at INTEGER,
|
|
847
|
-
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
848
|
-
updated_at DATETIME
|
|
849
|
-
);
|
|
850
|
-
|
|
851
|
-
-- Create failed_jobs table
|
|
852
|
-
CREATE TABLE IF NOT EXISTS failed_jobs (
|
|
853
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
854
|
-
uuid TEXT NOT NULL,
|
|
855
|
-
connection TEXT NOT NULL,
|
|
856
|
-
queue TEXT NOT NULL,
|
|
857
|
-
payload TEXT NOT NULL,
|
|
858
|
-
exception TEXT NOT NULL,
|
|
859
|
-
failed_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
860
|
-
);
|
|
861
|
-
|
|
862
|
-
-- Create job_batches table
|
|
863
|
-
-- then_handler / catch_handler / finally_handler columns persist
|
|
864
|
-
-- the terminal handlers across worker restarts
|
|
865
|
-
-- (stacksjs/stacks#1883). Each holds JSON for one
|
|
866
|
-
-- PersistentBatchHandler. Nullable so callers that only use the
|
|
867
|
-
-- in-memory then(fn) API does not need to populate them.
|
|
868
|
-
CREATE TABLE IF NOT EXISTS job_batches (
|
|
869
|
-
id TEXT PRIMARY KEY,
|
|
870
|
-
name TEXT NOT NULL DEFAULT '',
|
|
871
|
-
total_jobs INTEGER NOT NULL DEFAULT 0,
|
|
872
|
-
pending_jobs INTEGER NOT NULL DEFAULT 0,
|
|
873
|
-
failed_jobs INTEGER NOT NULL DEFAULT 0,
|
|
874
|
-
failed_job_ids TEXT NOT NULL DEFAULT '[]',
|
|
875
|
-
options TEXT,
|
|
876
|
-
cancelled_at DATETIME,
|
|
877
|
-
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
878
|
-
finished_at DATETIME,
|
|
879
|
-
then_handler TEXT,
|
|
880
|
-
catch_handler TEXT,
|
|
881
|
-
finally_handler TEXT
|
|
882
|
-
);
|
|
883
|
-
|
|
884
|
-
-- Dead-letter queue (stacksjs/stacks#1885). Jobs that have already
|
|
885
|
-
-- been retried and failed again land here instead of cycling back
|
|
886
|
-
-- through the queue. \`reason\` distinguishes "repeat-failure" from
|
|
887
|
-
-- "poison-detected" / "circuit-broken" for operator triage.
|
|
888
|
-
CREATE TABLE IF NOT EXISTS dead_letter_jobs (
|
|
889
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
890
|
-
uuid TEXT NOT NULL,
|
|
891
|
-
connection TEXT NOT NULL,
|
|
892
|
-
queue TEXT NOT NULL,
|
|
893
|
-
payload TEXT NOT NULL,
|
|
894
|
-
exception TEXT NOT NULL,
|
|
895
|
-
reason TEXT NOT NULL,
|
|
896
|
-
total_failures INTEGER NOT NULL DEFAULT 1,
|
|
897
|
-
first_failed_at DATETIME,
|
|
898
|
-
last_failed_at DATETIME,
|
|
899
|
-
dead_lettered_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
900
|
-
);
|
|
901
|
-
|
|
902
|
-
-- Poison-message quarantine (stacksjs/stacks#1885). Tracks
|
|
903
|
-
-- failure counts per (jobName + payload-hash) over a rolling
|
|
904
|
-
-- window. When the count breaches the configured threshold, new
|
|
905
|
-
-- dispatches of that exact job+payload combination go directly to
|
|
906
|
-
-- the DLQ instead of the queue.
|
|
907
|
-
CREATE TABLE IF NOT EXISTS job_quarantine (
|
|
908
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
909
|
-
job_name TEXT NOT NULL,
|
|
910
|
-
payload_hash TEXT NOT NULL,
|
|
911
|
-
failure_count INTEGER NOT NULL DEFAULT 0,
|
|
912
|
-
window_start DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
913
|
-
quarantined_at DATETIME,
|
|
914
|
-
UNIQUE(job_name, payload_hash)
|
|
915
|
-
);
|
|
916
|
-
|
|
917
|
-
-- Per-queue circuit-breaker state (stacksjs/stacks#1885). Tracks
|
|
918
|
-
-- success/failure counts in a rolling window so the worker can
|
|
919
|
-
-- pause a queue with a sustained high failure rate. Reads + writes
|
|
920
|
-
-- are best-effort; a missing row means "not tripped".
|
|
921
|
-
CREATE TABLE IF NOT EXISTS queue_circuit_state (
|
|
922
|
-
queue_name TEXT PRIMARY KEY,
|
|
923
|
-
success_count INTEGER NOT NULL DEFAULT 0,
|
|
924
|
-
failure_count INTEGER NOT NULL DEFAULT 0,
|
|
925
|
-
window_start DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
926
|
-
paused_at DATETIME,
|
|
927
|
-
resume_at DATETIME
|
|
928
|
-
);
|
|
929
|
-
`;else if(Z==="mysql")J=`-- Create jobs table
|
|
930
|
-
CREATE TABLE IF NOT EXISTS jobs (
|
|
931
|
-
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
932
|
-
queue VARCHAR(255) NOT NULL DEFAULT 'default',
|
|
933
|
-
payload LONGTEXT NOT NULL,
|
|
934
|
-
attempts INT NOT NULL DEFAULT 0,
|
|
935
|
-
reserved_at INT UNSIGNED NULL,
|
|
936
|
-
available_at INT UNSIGNED NULL,
|
|
937
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
938
|
-
updated_at TIMESTAMP NULL
|
|
939
|
-
);
|
|
940
|
-
|
|
941
|
-
-- Create failed_jobs table
|
|
942
|
-
CREATE TABLE IF NOT EXISTS failed_jobs (
|
|
943
|
-
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
944
|
-
uuid VARCHAR(255) NOT NULL,
|
|
945
|
-
connection VARCHAR(255) NOT NULL,
|
|
946
|
-
queue VARCHAR(255) NOT NULL,
|
|
947
|
-
payload LONGTEXT NOT NULL,
|
|
948
|
-
exception LONGTEXT NOT NULL,
|
|
949
|
-
failed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
950
|
-
);
|
|
951
|
-
|
|
952
|
-
-- Create job_batches table
|
|
953
|
-
-- then_handler / catch_handler / finally_handler persist
|
|
954
|
-
-- terminal handlers across worker restarts (stacksjs/stacks#1883).
|
|
955
|
-
CREATE TABLE IF NOT EXISTS job_batches (
|
|
956
|
-
id VARCHAR(255) PRIMARY KEY,
|
|
957
|
-
name VARCHAR(255) NOT NULL DEFAULT '',
|
|
958
|
-
total_jobs INT NOT NULL DEFAULT 0,
|
|
959
|
-
pending_jobs INT NOT NULL DEFAULT 0,
|
|
960
|
-
failed_jobs INT NOT NULL DEFAULT 0,
|
|
961
|
-
failed_job_ids LONGTEXT NOT NULL,
|
|
962
|
-
options LONGTEXT,
|
|
963
|
-
cancelled_at TIMESTAMP NULL,
|
|
964
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
965
|
-
finished_at TIMESTAMP NULL,
|
|
966
|
-
then_handler LONGTEXT,
|
|
967
|
-
catch_handler LONGTEXT,
|
|
968
|
-
finally_handler LONGTEXT
|
|
969
|
-
);
|
|
970
|
-
|
|
971
|
-
-- DLQ + poison-quarantine + circuit-breaker (stacksjs/stacks#1885)
|
|
972
|
-
CREATE TABLE IF NOT EXISTS dead_letter_jobs (
|
|
973
|
-
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
974
|
-
uuid VARCHAR(255) NOT NULL,
|
|
975
|
-
connection VARCHAR(255) NOT NULL,
|
|
976
|
-
queue VARCHAR(255) NOT NULL,
|
|
977
|
-
payload LONGTEXT NOT NULL,
|
|
978
|
-
exception LONGTEXT NOT NULL,
|
|
979
|
-
reason VARCHAR(64) NOT NULL,
|
|
980
|
-
total_failures INT NOT NULL DEFAULT 1,
|
|
981
|
-
first_failed_at TIMESTAMP NULL,
|
|
982
|
-
last_failed_at TIMESTAMP NULL,
|
|
983
|
-
dead_lettered_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
984
|
-
);
|
|
985
|
-
|
|
986
|
-
CREATE TABLE IF NOT EXISTS job_quarantine (
|
|
987
|
-
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
988
|
-
job_name VARCHAR(255) NOT NULL,
|
|
989
|
-
payload_hash VARCHAR(64) NOT NULL,
|
|
990
|
-
failure_count INT NOT NULL DEFAULT 0,
|
|
991
|
-
window_start TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
992
|
-
quarantined_at TIMESTAMP NULL,
|
|
993
|
-
UNIQUE KEY job_quarantine_unique (job_name, payload_hash)
|
|
994
|
-
);
|
|
995
|
-
|
|
996
|
-
CREATE TABLE IF NOT EXISTS queue_circuit_state (
|
|
997
|
-
queue_name VARCHAR(255) PRIMARY KEY,
|
|
998
|
-
success_count INT NOT NULL DEFAULT 0,
|
|
999
|
-
failure_count INT NOT NULL DEFAULT 0,
|
|
1000
|
-
window_start TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1001
|
-
paused_at TIMESTAMP NULL,
|
|
1002
|
-
resume_at TIMESTAMP NULL
|
|
1003
|
-
);
|
|
1004
|
-
`;else if(Z==="postgres")J=`-- Create jobs table
|
|
1005
|
-
CREATE TABLE IF NOT EXISTS jobs (
|
|
1006
|
-
id SERIAL PRIMARY KEY,
|
|
1007
|
-
queue VARCHAR(255) NOT NULL DEFAULT 'default',
|
|
1008
|
-
payload TEXT NOT NULL,
|
|
1009
|
-
attempts INTEGER NOT NULL DEFAULT 0,
|
|
1010
|
-
reserved_at INTEGER,
|
|
1011
|
-
available_at INTEGER,
|
|
1012
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1013
|
-
updated_at TIMESTAMP
|
|
1014
|
-
);
|
|
1015
|
-
|
|
1016
|
-
-- Create failed_jobs table
|
|
1017
|
-
CREATE TABLE IF NOT EXISTS failed_jobs (
|
|
1018
|
-
id SERIAL PRIMARY KEY,
|
|
1019
|
-
uuid VARCHAR(255) NOT NULL,
|
|
1020
|
-
connection VARCHAR(255) NOT NULL,
|
|
1021
|
-
queue VARCHAR(255) NOT NULL,
|
|
1022
|
-
payload TEXT NOT NULL,
|
|
1023
|
-
exception TEXT NOT NULL,
|
|
1024
|
-
failed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
1025
|
-
);
|
|
1026
|
-
|
|
1027
|
-
-- Create job_batches table
|
|
1028
|
-
-- then_handler / catch_handler / finally_handler persist
|
|
1029
|
-
-- terminal handlers across worker restarts (stacksjs/stacks#1883).
|
|
1030
|
-
CREATE TABLE IF NOT EXISTS job_batches (
|
|
1031
|
-
id VARCHAR(255) PRIMARY KEY,
|
|
1032
|
-
name VARCHAR(255) NOT NULL DEFAULT '',
|
|
1033
|
-
total_jobs INTEGER NOT NULL DEFAULT 0,
|
|
1034
|
-
pending_jobs INTEGER NOT NULL DEFAULT 0,
|
|
1035
|
-
failed_jobs INTEGER NOT NULL DEFAULT 0,
|
|
1036
|
-
failed_job_ids TEXT NOT NULL DEFAULT '[]',
|
|
1037
|
-
options TEXT,
|
|
1038
|
-
cancelled_at TIMESTAMP,
|
|
1039
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1040
|
-
finished_at TIMESTAMP,
|
|
1041
|
-
then_handler TEXT,
|
|
1042
|
-
catch_handler TEXT,
|
|
1043
|
-
finally_handler TEXT
|
|
1044
|
-
);
|
|
1045
|
-
|
|
1046
|
-
-- DLQ + poison-quarantine + circuit-breaker (stacksjs/stacks#1885)
|
|
1047
|
-
CREATE TABLE IF NOT EXISTS dead_letter_jobs (
|
|
1048
|
-
id SERIAL PRIMARY KEY,
|
|
1049
|
-
uuid VARCHAR(255) NOT NULL,
|
|
1050
|
-
connection VARCHAR(255) NOT NULL,
|
|
1051
|
-
queue VARCHAR(255) NOT NULL,
|
|
1052
|
-
payload TEXT NOT NULL,
|
|
1053
|
-
exception TEXT NOT NULL,
|
|
1054
|
-
reason VARCHAR(64) NOT NULL,
|
|
1055
|
-
total_failures INTEGER NOT NULL DEFAULT 1,
|
|
1056
|
-
first_failed_at TIMESTAMP,
|
|
1057
|
-
last_failed_at TIMESTAMP,
|
|
1058
|
-
dead_lettered_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
1059
|
-
);
|
|
1060
|
-
|
|
1061
|
-
CREATE TABLE IF NOT EXISTS job_quarantine (
|
|
1062
|
-
id SERIAL PRIMARY KEY,
|
|
1063
|
-
job_name VARCHAR(255) NOT NULL,
|
|
1064
|
-
payload_hash VARCHAR(64) NOT NULL,
|
|
1065
|
-
failure_count INTEGER NOT NULL DEFAULT 0,
|
|
1066
|
-
window_start TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1067
|
-
quarantined_at TIMESTAMP,
|
|
1068
|
-
UNIQUE (job_name, payload_hash)
|
|
1069
|
-
);
|
|
1070
|
-
|
|
1071
|
-
CREATE TABLE IF NOT EXISTS queue_circuit_state (
|
|
1072
|
-
queue_name VARCHAR(255) PRIMARY KEY,
|
|
1073
|
-
success_count INTEGER NOT NULL DEFAULT 0,
|
|
1074
|
-
failure_count INTEGER NOT NULL DEFAULT 0,
|
|
1075
|
-
window_start TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1076
|
-
paused_at TIMESTAMP,
|
|
1077
|
-
resume_at TIMESTAMP
|
|
1078
|
-
);
|
|
1079
|
-
`;let z=`${new Date().getTime().toString()}-create-jobs-table.sql`,H=y0();if(!VY(H))c4(H,{recursive:!0});let I=VZ(H,z);u4(I,J),console.log("\u2713 Created jobs migration file")}else console.log("\u2713 Jobs migration file already exists");if(!await d4()){console.log(" Running migration...");let J=bY();if(Z==="sqlite"||VY(J)){let W=new cY(J);W.run(`CREATE TABLE IF NOT EXISTS jobs (
|
|
1080
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1081
|
-
queue TEXT NOT NULL DEFAULT 'default',
|
|
1082
|
-
payload TEXT NOT NULL,
|
|
1083
|
-
attempts INTEGER NOT NULL DEFAULT 0,
|
|
1084
|
-
reserved_at INTEGER,
|
|
1085
|
-
available_at INTEGER,
|
|
1086
|
-
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
1087
|
-
updated_at DATETIME
|
|
1088
|
-
)`),W.run(`CREATE TABLE IF NOT EXISTS failed_jobs (
|
|
1089
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1090
|
-
uuid TEXT NOT NULL,
|
|
1091
|
-
connection TEXT NOT NULL,
|
|
1092
|
-
queue TEXT NOT NULL,
|
|
1093
|
-
payload TEXT NOT NULL,
|
|
1094
|
-
exception TEXT NOT NULL,
|
|
1095
|
-
failed_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
1096
|
-
)`),W.close()}else if(Z==="mysql"){let{db:W}=await Promise.resolve().then(() => (D(),e));await W.unsafe(`CREATE TABLE IF NOT EXISTS jobs (
|
|
1097
|
-
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
1098
|
-
queue VARCHAR(255) NOT NULL DEFAULT 'default',
|
|
1099
|
-
payload LONGTEXT NOT NULL,
|
|
1100
|
-
attempts INT NOT NULL DEFAULT 0,
|
|
1101
|
-
reserved_at INT UNSIGNED NULL,
|
|
1102
|
-
available_at INT UNSIGNED NULL,
|
|
1103
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1104
|
-
updated_at TIMESTAMP NULL
|
|
1105
|
-
)`).execute(),await W.unsafe(`CREATE TABLE IF NOT EXISTS failed_jobs (
|
|
1106
|
-
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
1107
|
-
uuid VARCHAR(255) NOT NULL,
|
|
1108
|
-
connection VARCHAR(255) NOT NULL,
|
|
1109
|
-
queue VARCHAR(255) NOT NULL,
|
|
1110
|
-
payload LONGTEXT NOT NULL,
|
|
1111
|
-
exception LONGTEXT NOT NULL,
|
|
1112
|
-
failed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
1113
|
-
)`).execute()}else if(Z==="postgres"){let{db:W}=await Promise.resolve().then(() => (D(),e));await W.unsafe(`CREATE TABLE IF NOT EXISTS jobs (
|
|
1114
|
-
id SERIAL PRIMARY KEY,
|
|
1115
|
-
queue VARCHAR(255) NOT NULL DEFAULT 'default',
|
|
1116
|
-
payload TEXT NOT NULL,
|
|
1117
|
-
attempts INTEGER NOT NULL DEFAULT 0,
|
|
1118
|
-
reserved_at INTEGER,
|
|
1119
|
-
available_at INTEGER,
|
|
1120
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1121
|
-
updated_at TIMESTAMP
|
|
1122
|
-
)`).execute(),await W.unsafe(`CREATE TABLE IF NOT EXISTS failed_jobs (
|
|
1123
|
-
id SERIAL PRIMARY KEY,
|
|
1124
|
-
uuid VARCHAR(255) NOT NULL,
|
|
1125
|
-
connection VARCHAR(255) NOT NULL,
|
|
1126
|
-
queue VARCHAR(255) NOT NULL,
|
|
1127
|
-
payload TEXT NOT NULL,
|
|
1128
|
-
exception TEXT NOT NULL,
|
|
1129
|
-
failed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
1130
|
-
)`).execute()}console.log("\u2713 Jobs and failed_jobs tables created")}else console.log("\u2713 Jobs tables already exist");if(!await C4()){console.log(" Creating job_batches table...");let J=bY();if(Z==="sqlite"||VY(J)){let W=new cY(J);W.run(`CREATE TABLE IF NOT EXISTS job_batches (
|
|
1131
|
-
id TEXT PRIMARY KEY,
|
|
1132
|
-
name TEXT NOT NULL DEFAULT '',
|
|
1133
|
-
total_jobs INTEGER NOT NULL DEFAULT 0,
|
|
1134
|
-
pending_jobs INTEGER NOT NULL DEFAULT 0,
|
|
1135
|
-
failed_jobs INTEGER NOT NULL DEFAULT 0,
|
|
1136
|
-
failed_job_ids TEXT NOT NULL DEFAULT '[]',
|
|
1137
|
-
options TEXT,
|
|
1138
|
-
cancelled_at DATETIME,
|
|
1139
|
-
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
1140
|
-
finished_at DATETIME
|
|
1141
|
-
)`),W.close()}else if(Z==="mysql"){let{db:W}=await Promise.resolve().then(() => (D(),e));await W.unsafe(`CREATE TABLE IF NOT EXISTS job_batches (
|
|
1142
|
-
id VARCHAR(255) PRIMARY KEY,
|
|
1143
|
-
name VARCHAR(255) NOT NULL DEFAULT '',
|
|
1144
|
-
total_jobs INT NOT NULL DEFAULT 0,
|
|
1145
|
-
pending_jobs INT NOT NULL DEFAULT 0,
|
|
1146
|
-
failed_jobs INT NOT NULL DEFAULT 0,
|
|
1147
|
-
failed_job_ids LONGTEXT NOT NULL,
|
|
1148
|
-
options LONGTEXT,
|
|
1149
|
-
cancelled_at TIMESTAMP NULL,
|
|
1150
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1151
|
-
finished_at TIMESTAMP NULL
|
|
1152
|
-
)`).execute()}else if(Z==="postgres"){let{db:W}=await Promise.resolve().then(() => (D(),e));await W.unsafe(`CREATE TABLE IF NOT EXISTS job_batches (
|
|
1153
|
-
id VARCHAR(255) PRIMARY KEY,
|
|
1154
|
-
name VARCHAR(255) NOT NULL DEFAULT '',
|
|
1155
|
-
total_jobs INTEGER NOT NULL DEFAULT 0,
|
|
1156
|
-
pending_jobs INTEGER NOT NULL DEFAULT 0,
|
|
1157
|
-
failed_jobs INTEGER NOT NULL DEFAULT 0,
|
|
1158
|
-
failed_job_ids TEXT NOT NULL DEFAULT '[]',
|
|
1159
|
-
options TEXT,
|
|
1160
|
-
cancelled_at TIMESTAMP,
|
|
1161
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1162
|
-
finished_at TIMESTAMP
|
|
1163
|
-
)`).execute()}console.log("\u2713 job_batches table created")}else console.log("\u2713 job_batches table already exists")}return h4("Migration created and executed.")}catch(Z){return f4(Z instanceof Error?Z:Error(String(Z)))}}D();import{randomBytes as g4}from"crypto";import{log as P}from"@stacksjs/logging";import{env as s4}from"@stacksjs/env";function CY(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(J){return Y?`$${J}`:"?"},params(...J){if(Y)return{sql:J.map((H,I)=>`$${I+1}`).join(", "),values:J};return{sql:J.map(()=>"?").join(", "),values:J}}}}function m4(){return s4.DB_CONNECTION||"sqlite"}function l4(Z){return`ALTER TABLE users ADD COLUMN email_verified_at ${Z.nullableTimestamp}`}function r4(Z){return`ALTER TABLE users ADD COLUMN password_changed_at ${Z.nullableTimestamp}`}function a4(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 n4(){return"ALTER TABLE users ADD COLUMN stripe_id VARCHAR(255)"}async function o4(Z,Y={}){let $=[l4(Z),r4(Z),...a4(Z),n4()];for(let X of $)try{await K.unsafe(X).execute()}catch{if(Y.verbose)P.debug(`[auth-tables] Skipped (already applied or users missing): ${X}`)}try{await K.unsafe("CREATE UNIQUE INDEX IF NOT EXISTS idx_users_stripe_id ON users(stripe_id)").execute()}catch{if(Y.verbose)P.debug("[auth-tables] Skipped users.stripe_id unique index (already applied or users missing)")}}async function o7(Z={}){let Y=m4(),$=CY(Y),{isPostgres:X,boolTrue:J,now:W,pkColumn:z,nullableTimestamp:H}=$;if(Z.verbose)P.info(`Creating auth tables for ${Y}...`);try{if(Z.verbose)P.info("Creating oauth_clients table...");if(await K.unsafe(`
|
|
1164
|
-
CREATE TABLE IF NOT EXISTS oauth_clients (
|
|
1165
|
-
${z},
|
|
1166
|
-
name VARCHAR(255) NOT NULL,
|
|
1167
|
-
secret VARCHAR(100),
|
|
1168
|
-
provider VARCHAR(255),
|
|
1169
|
-
redirect VARCHAR(2000) NOT NULL,
|
|
1170
|
-
personal_access_client BOOLEAN NOT NULL DEFAULT ${$.boolFalse},
|
|
1171
|
-
password_client BOOLEAN NOT NULL DEFAULT ${$.boolFalse},
|
|
1172
|
-
revoked BOOLEAN NOT NULL DEFAULT ${$.boolFalse},
|
|
1173
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1174
|
-
updated_at ${H}
|
|
1175
|
-
)
|
|
1176
|
-
`).execute(),Z.verbose)P.info("Creating oauth_access_tokens table...");if(await K.unsafe(`
|
|
1177
|
-
CREATE TABLE IF NOT EXISTS oauth_access_tokens (
|
|
1178
|
-
${z},
|
|
1179
|
-
user_id INTEGER NOT NULL,
|
|
1180
|
-
oauth_client_id INTEGER NOT NULL,
|
|
1181
|
-
token TEXT NOT NULL,
|
|
1182
|
-
name VARCHAR(255),
|
|
1183
|
-
scopes TEXT,
|
|
1184
|
-
revoked BOOLEAN NOT NULL DEFAULT ${$.boolFalse},
|
|
1185
|
-
expires_at ${H},
|
|
1186
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1187
|
-
updated_at ${H}
|
|
1188
|
-
)
|
|
1189
|
-
`).execute(),await F0("idx_oauth_access_tokens_token","oauth_access_tokens","token"),Z.verbose)P.info("Creating oauth_refresh_tokens table...");if(await K.unsafe(`
|
|
1190
|
-
CREATE TABLE IF NOT EXISTS oauth_refresh_tokens (
|
|
1191
|
-
${z},
|
|
1192
|
-
access_token_id INTEGER NOT NULL,
|
|
1193
|
-
token TEXT NOT NULL,
|
|
1194
|
-
revoked BOOLEAN NOT NULL DEFAULT ${$.boolFalse},
|
|
1195
|
-
expires_at ${H},
|
|
1196
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
1197
|
-
)
|
|
1198
|
-
`).execute(),await F0("idx_oauth_refresh_tokens_token","oauth_refresh_tokens","token"),Z.verbose)P.info("Creating password_resets table...");await K.unsafe(`
|
|
1199
|
-
CREATE TABLE IF NOT EXISTS password_resets (
|
|
1200
|
-
${z},
|
|
1201
|
-
email VARCHAR(255) NOT NULL,
|
|
1202
|
-
token VARCHAR(255) NOT NULL,
|
|
1203
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
1204
|
-
)
|
|
1205
|
-
`).execute();try{await K.unsafe(`
|
|
1206
|
-
CREATE INDEX IF NOT EXISTS idx_password_resets_email ON password_resets(email)
|
|
1207
|
-
`).execute()}catch{}if(Z.verbose)P.info("Creating passkeys table...");await K.unsafe(`
|
|
1208
|
-
CREATE TABLE IF NOT EXISTS passkeys (
|
|
1209
|
-
id VARCHAR(255) PRIMARY KEY,
|
|
1210
|
-
cred_public_key TEXT NOT NULL,
|
|
1211
|
-
user_id INTEGER NOT NULL,
|
|
1212
|
-
webauthn_user_id VARCHAR(255) NOT NULL,
|
|
1213
|
-
counter INTEGER NOT NULL DEFAULT 0,
|
|
1214
|
-
credential_type VARCHAR(50),
|
|
1215
|
-
device_type VARCHAR(50),
|
|
1216
|
-
backup_eligible BOOLEAN NOT NULL DEFAULT ${$.boolFalse},
|
|
1217
|
-
backup_status BOOLEAN NOT NULL DEFAULT ${$.boolFalse},
|
|
1218
|
-
transports TEXT,
|
|
1219
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1220
|
-
last_used_at ${H}
|
|
1221
|
-
)
|
|
1222
|
-
`).execute();try{await K.unsafe(`
|
|
1223
|
-
CREATE INDEX IF NOT EXISTS idx_passkeys_user_id ON passkeys(user_id)
|
|
1224
|
-
`).execute()}catch{}if(Z.verbose)P.info("Creating webauthn_challenges table...");await K.unsafe(`
|
|
1225
|
-
CREATE TABLE IF NOT EXISTS webauthn_challenges (
|
|
1226
|
-
${z},
|
|
1227
|
-
user_id INTEGER NOT NULL,
|
|
1228
|
-
challenge TEXT NOT NULL,
|
|
1229
|
-
purpose VARCHAR(20) NOT NULL,
|
|
1230
|
-
expires_at TIMESTAMP NOT NULL,
|
|
1231
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
1232
|
-
)
|
|
1233
|
-
`).execute();try{await K.unsafe(`
|
|
1234
|
-
CREATE UNIQUE INDEX IF NOT EXISTS idx_webauthn_challenges_user_purpose ON webauthn_challenges(user_id, purpose)
|
|
1235
|
-
`).execute()}catch{}if(Z.verbose)P.info("Creating two_factor_challenges table...");await K.unsafe(`
|
|
1236
|
-
CREATE TABLE IF NOT EXISTS two_factor_challenges (
|
|
1237
|
-
id VARCHAR(255) PRIMARY KEY,
|
|
1238
|
-
user_id INTEGER NOT NULL,
|
|
1239
|
-
expires_at TIMESTAMP NOT NULL,
|
|
1240
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
1241
|
-
)
|
|
1242
|
-
`).execute();try{await K.unsafe(`
|
|
1243
|
-
CREATE INDEX IF NOT EXISTS idx_two_factor_challenges_user_id ON two_factor_challenges(user_id)
|
|
1244
|
-
`).execute()}catch{}if(Z.verbose)P.info("Creating two_factor_pending_secrets table...");if(await K.unsafe(`
|
|
1245
|
-
CREATE TABLE IF NOT EXISTS two_factor_pending_secrets (
|
|
1246
|
-
user_id INTEGER PRIMARY KEY,
|
|
1247
|
-
secret VARCHAR(255) NOT NULL,
|
|
1248
|
-
expires_at TIMESTAMP NOT NULL,
|
|
1249
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
1250
|
-
)
|
|
1251
|
-
`).execute(),Z.verbose)P.info("Ensuring users auth columns exist (users may not exist yet on a fresh install \u2014 see ensureUsersAuthColumns)...");if(await o4($,Z),Z.verbose)P.info("Ensuring personal access client exists...");if((await K.unsafe(`
|
|
1252
|
-
SELECT id FROM oauth_clients WHERE personal_access_client = ${J} LIMIT 1
|
|
1253
|
-
`).execute())?.length===0){let Q=g4(40).toString("hex");if(X)await K.unsafe(`
|
|
1254
|
-
INSERT INTO oauth_clients (name, secret, provider, redirect, personal_access_client, password_client, revoked, created_at)
|
|
1255
|
-
VALUES ($1, $2, $3, $4, $5, $6, $7, NOW())
|
|
1256
|
-
`,["Personal Access Client",Q,"local","http://localhost",!0,!1,!1]).execute();else await K.unsafe(`
|
|
1257
|
-
INSERT INTO oauth_clients (name, secret, provider, redirect, personal_access_client, password_client, revoked, created_at)
|
|
1258
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ${W})
|
|
1259
|
-
`,["Personal Access Client",Q,"local","http://localhost",1,0,0]).execute();if(Z.verbose)P.success("Personal access client created")}return P.debug("Auth tables migrated successfully"),{success:!0}}catch(I){let Q=I instanceof Error?I.message:String(I);return P.error("Failed to migrate auth tables:",Q),{success:!1,error:Q}}}async function F0(Z,Y,$){try{await K.unsafe(`
|
|
1260
|
-
CREATE INDEX IF NOT EXISTS ${Z} ON ${Y}(${$}(255))
|
|
1261
|
-
`).execute()}catch{try{await K.unsafe(`
|
|
1262
|
-
CREATE INDEX IF NOT EXISTS ${Z} ON ${Y}(${$})
|
|
1263
|
-
`).execute()}catch{}}}D();import i4 from"process";import{log as T0}from"@stacksjs/logging";import{path as LZ}from"@stacksjs/path";import{getTableName as e4}from"@stacksjs/orm";import{fs as P0}from"@stacksjs/storage";function t4(){return i4.env.DB_CONNECTION||"sqlite"}function Y5(Z){if(Z.isPostgres)return"UUID";if(Z.isMysql)return"VARCHAR(255)";return"TEXT"}function Z5(Z,Y){return`ALTER TABLE ${Z} ADD COLUMN uuid ${Y5(Y)}`}async function N0(Z){let Y=[];if(!P0.existsSync(Z))return Y;let $=P0.readdirSync(Z,{withFileTypes:!0});for(let X of $){let J=LZ.join(Z,X.name);if(X.isDirectory()){Y.push(...await N0(J));continue}if(!X.name.endsWith(".ts"))continue;if(X.name.startsWith("_")||X.name.startsWith("index"))continue;try{let W=(await import(J)).default;if(W?.name||W?.table)Y.push({filePath:J,model:W})}catch{}}return Y}async function $5(){let Z=[LZ.userModelsPath(),LZ.frameworkPath("defaults/app/Models")],Y=new Set;for(let $ of Z)for(let{filePath:X,model:J}of await N0($)){if(!J.traits?.useUuid)continue;Y.add(e4(J,X))}return[...Y]}async function X5(Z,Y={}){let $=await $5();for(let X of $)try{if(await K.unsafe(Z5(X,Z)).execute(),Y.verbose)T0.debug(`[uuid-columns] Added uuid column to ${X}`)}catch{if(Y.verbose)T0.debug(`[uuid-columns] Skipped (already applied or ${X} missing): uuid column`)}}async function z8(Z={}){await X5(CY(t4()),Z)}MY();export{j8 as validateDriverConfig,Z5 as uuidColumnSql,a4 as usersTwoFactorColumnsSql,n4 as usersStripeIdSql,r4 as usersPasswordChangedAtSql,l4 as usersEmailVerifiedAtSql,x9 as unmarshall,O6 as truncateMigrationTables,CY as sqlHelpers,TZ as sql,k8 as setQueryTracker,L9 as setConfig,m5 as seedModelDirect,l5 as seedModel$,C1 as seed,b8 as scaffoldClassSeedersFromModels,C1 as runSeeders,K9 as runInTransactionScope,N5 as runDatabaseMigration,F8 as runClassSeeders,H7 as resetSqliteDatabase,n6 as resetPostgresDatabase,N6 as resetMysqlDatabase,v5 as resetDatabase,C8 as renderSeederFile,v8 as renameColumnSafely,f5 as previewPendingMigrations,w1 as preprocessSqliteMigrations,l1 as prepareTextColumnType,r1 as prepareNumberColumnType,a1 as prepareEnumColumnType,W6 as prepareDateTimeColumnType,GY as pluckChanges,j9 as parseKeyPattern,J6 as modelTableName,n8 as migrateRbacTables,r8 as migrateNotificationTables,o7 as migrateAuthTables,B8 as mergeWithDefaults,S9 as marshall,o as mapFieldTypeToColumnType,D8 as logQuery,a5 as listSeedableModels,v1 as isProtectedModel,I9 as isInTransaction,HY as isArrayEqual,kZ as initializeDbConfig,a as hasTableBeenMigrated,q as hasMigrationBeenCreated,t as getUpvoteTableName,R6 as getTraitTables,z9 as getLiveUniqueIndexes,$9 as getLiveFKs,QY as getLikeableForeignKey,c as getLastMigrationFields,m1 as getExecutedMigrations,W9 as getDeclaredUniques,Z9 as getDeclaredFKs,O8 as getConnectionString,m as getConnectionDefaults,R8 as getConfigFromEnv,I7 as generateSqliteMigration,KZ as generateSqliteIndexCreationSQL,a6 as generatePostgresTraitMigrations,o6 as generatePostgresMigration,K4 as generatePostgresIndexCreationSQL,f6 as generateMysqlTraitMigrations,v6 as generateMysqlMigration,p5 as generateMigrations2,h5 as generateMigrations,B9 as generateKeyPattern,$4 as generateIndexCreationSQL,r5 as freshWithSeed,r5 as freshSeed,$5 as findUuidTables,Y9 as findFkOrphans,UY as findDifferingKeys,B4 as fetchTestSqliteFile,vY as fetchTables,Q7 as fetchSqliteFile,_4 as fetchPostgresTables,u8 as factoryGenerate,p8 as factory,z8 as ensureUuidColumnsForCurrentDriver,X5 as ensureUuidColumns,o4 as ensureUsersAuthColumns,lY as ensureDatabaseConfigLoaded,Q9 as enqueueAfterCommit,R9 as dynamo,O4 as dropSqliteTables,H4 as dropPostgresTables,t1 as dropMysqlTables,K0 as dropMigrationTables,hY as dropCommonTables,A8 as driverDefaults,E8 as detectDriver,JY as deleteMigrationFiles,WY as deleteFrameworkModels,K as db,GZ as createTaggablesTable,z0 as createTaggableTable,_8 as createSqliteDatabase,E0 as createQueryLogsTable,_9 as createQueryBuilder,G0 as createPostgresTagsTable,HZ as createPostgresTaggablesTable,A0 as createPostgresQueryLogsTable,K6 as createPostgresPasswordResetsTable,W0 as createPostgresPasskeyMigration,V8 as createPostgresDatabase,I0 as createPostgresCommentsTable,L0 as createPostgresCommentablesPivotTable,_0 as createPostgresCommentUpvoteMigration,U0 as createPostgresCategorizableTable,fY as createPasswordResetsTable,J0 as createPasskeyMigration,K8 as createMysqlDatabase,M7 as createModelAuditsTable,d7 as createJobsMigration,v7 as createErrorsTable,A9 as createDynamo,I8 as createDatabase,Q0 as createCommentablesTable,B6 as createCommentablesPivotTable,V0 as createCommentUpvoteMigration,H0 as createCategorizableTable,Z4 as createAlterTableMigration,K7 as copyModelFiles,U7 as configureSqlitePragmas,z6 as compareRanges,zY as checkPivotMigration,G6 as checkIsRequired,w9 as buildKey,N8 as backfillInBatches,J9 as auditUniqueIndexes,t8 as auditForeignKeys,n as arrangeColumns,n0 as applySqlitePragmas,P8 as addColumnSafely,g0 as acquireDbConfigLock,U9 as __pendingAfterCommitCount,H9 as __flushAfterCommitNow,y8 as Seeder,rY as SQLITE_BOOTSTRAP_PRAGMAS,G5 as REDIS_DEFAULTS,N1 as PROTECTED_MODELS,O9 as EntityQueryBuilder,Q8 as Database,OZ as DB_USERS,RZ as DB_PORTS,dY as DB_NAMES,z5 as DB_HOST_DEFAULT,H5 as AWS_DEFAULTS};
|
|
1
|
+
export {
|
|
2
|
+
Database,
|
|
3
|
+
createDatabase,
|
|
4
|
+
createMysqlDatabase,
|
|
5
|
+
createPostgresDatabase,
|
|
6
|
+
createSqliteDatabase
|
|
7
|
+
} from "./database";
|
|
8
|
+
export {
|
|
9
|
+
detectDriver,
|
|
10
|
+
driverDefaults,
|
|
11
|
+
getConfigFromEnv,
|
|
12
|
+
getConnectionString,
|
|
13
|
+
mergeWithDefaults,
|
|
14
|
+
validateDriverConfig
|
|
15
|
+
} from "./driver-config";
|
|
16
|
+
export * from "./utils";
|
|
17
|
+
export * from "./types";
|
|
18
|
+
export * from "./migrations";
|
|
19
|
+
export { setQueryTracker, logQuery } from "./query-logger";
|
|
20
|
+
export { Seeder, runClassSeeders } from "./class-seeder";
|
|
21
|
+
export { addColumnSafely, backfillInBatches, renameColumnSafely } from "./safe-migrations";
|
|
22
|
+
export * from "./seeder";
|
|
23
|
+
export { factory, generate as factoryGenerate } from "./factory";
|
|
24
|
+
export { scaffoldClassSeedersFromModels, renderSeederFile } from "./seed-scaffold";
|
|
25
|
+
export * from "./drivers";
|
|
26
|
+
export * from "./custom";
|
|
27
|
+
export * from "./auth-tables";
|
|
28
|
+
export * from "./uuid-columns";
|
|
29
|
+
export { migrateNotificationTables } from "./notification-tables";
|
|
30
|
+
export { migrateRbacTables } from "./rbac-tables";
|
|
31
|
+
export * from "./sql-helpers";
|
|
32
|
+
export * from "./defaults";
|
|
33
|
+
export { auditForeignKeys, findFkOrphans, getDeclaredFKs, getLiveFKs } from "./fk-audit";
|
|
34
|
+
export { auditUniqueIndexes, getDeclaredUniques, getLiveUniqueIndexes } from "./unique-audit";
|
|
35
|
+
export {
|
|
36
|
+
__flushAfterCommitNow,
|
|
37
|
+
__pendingAfterCommitCount,
|
|
38
|
+
enqueueAfterCommit,
|
|
39
|
+
isInTransaction,
|
|
40
|
+
runInTransactionScope
|
|
41
|
+
} from "./transaction-context";
|
|
42
|
+
export {
|
|
43
|
+
createQueryBuilder,
|
|
44
|
+
setConfig
|
|
45
|
+
} from "@stacksjs/query-builder";
|
|
46
|
+
export {
|
|
47
|
+
createDynamo,
|
|
48
|
+
dynamo,
|
|
49
|
+
EntityQueryBuilder,
|
|
50
|
+
generateKeyPattern,
|
|
51
|
+
parseKeyPattern,
|
|
52
|
+
buildKey,
|
|
53
|
+
marshall,
|
|
54
|
+
unmarshall
|
|
55
|
+
} from "./drivers/dynamodb";
|