@beeblock/svelar 0.6.5 → 0.6.7

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/cli/bin.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- var Fn=Object.defineProperty;var tt=(l=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(l,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):l)(function(l){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+l+'" is not supported')});var w=(l,e)=>()=>(l&&(e=l(l=0)),e);var O=(l,e)=>{for(var t in e)Fn(l,t,{get:e[t],enumerable:!0})};function x(l,e){let t=Symbol.for(l),s=globalThis;return s[t]||(s[t]=e()),s[t]}var A=w(()=>{"use strict"});var P={};O(P,{Connection:()=>v});var Ns,v,S=w(()=>{"use strict";A();Ns=class{connections=new Map;config=null;defaultName="default";configure(e){this.config=e,this.defaultName=e.default}async connection(e){let t=e??this.defaultName;if(this.connections.has(t))return this.connections.get(t).drizzle;if(!this.config)throw new Error("Database not configured. Call Connection.configure() first, or register DatabaseServiceProvider.");let s=this.config.connections[t];if(!s)throw new Error(`Database connection "${t}" is not defined in configuration.`);let r=await this.createConnection(s);return this.connections.set(t,r),r.drizzle}async rawClient(e){let t=e??this.defaultName;return await this.connection(t),this.connections.get(t).rawClient}async raw(e,t=[],s){let r=await this.connection(s),i=this.getConfig(s);switch(i.driver){case"sqlite":{let n=await this.rawClient(s),o=t.map(u=>typeof u=="boolean"?u?1:0:u instanceof Date?u.toISOString():u),a=n.prepare(e),c=e.trimStart().toUpperCase();return c.startsWith("SELECT")||c.startsWith("PRAGMA")||c.startsWith("WITH")?a.all(...o):a.run(...o)}case"postgres":return(await this.rawClient(s))(e,...t);case"mysql":{let n=await this.rawClient(s),[o]=await n.execute(e,t);return o}default:throw new Error(`Unsupported driver: ${i.driver}`)}}getDriver(e){return this.getConfig(e).driver}getConfig(e){let t=e??this.defaultName;if(!this.config)throw new Error("Database not configured.");let s=this.config.connections[t];if(!s)throw new Error(`Database connection "${t}" is not defined.`);return s}async disconnect(e){if(e){let t=this.connections.get(e);t&&(await this.closeConnection(t),this.connections.delete(e))}else{for(let[t,s]of this.connections)await this.closeConnection(s);this.connections.clear()}}isConnected(e){return this.connections.has(e??this.defaultName)}async transaction(e,t){let s=this.getConfig(t),r=await this.rawClient(t);switch(s.driver){case"sqlite":{r.exec("BEGIN");try{let i=await e();return r.exec("COMMIT"),i}catch(i){throw r.exec("ROLLBACK"),i}}case"postgres":{await r`BEGIN`;try{let i=await e();return await r`COMMIT`,i}catch(i){throw await r`ROLLBACK`,i}}case"mysql":{let i=await r.getConnection();await i.beginTransaction();try{let n=await e();return await i.commit(),i.release(),n}catch(n){throw await i.rollback(),i.release(),n}}default:throw new Error(`Unsupported driver: ${s.driver}`)}}async createConnection(e){switch(e.driver){case"sqlite":return this.createSQLiteConnection(e);case"postgres":return this.createPostgresConnection(e);case"mysql":return this.createMySQLConnection(e);default:throw new Error(`Unsupported database driver: ${e.driver}`)}}async createSQLiteConnection(e){let t=e.filename??e.database??":memory:";try{let s=(await import("better-sqlite3")).default,{drizzle:r}=await import("drizzle-orm/better-sqlite3"),i=new s(t);return i.pragma("journal_mode = WAL"),i.pragma("foreign_keys = ON"),{drizzle:r(i),config:e,rawClient:i}}catch(s){let r;try{r=(await new Function("mod","return import(mod)")("node:sqlite")).DatabaseSync}catch{throw new Error(`No SQLite driver available. Install better-sqlite3 (npm install better-sqlite3) or use Node.js v22+ which includes built-in SQLite support. Original error: ${s instanceof Error?s.message:String(s)}`)}let i=new r(t);i.exec("PRAGMA journal_mode = WAL"),i.exec("PRAGMA foreign_keys = ON");let n={prepare(a){let c=i.prepare(a);return{all(...u){return c.all(...u)},run(...u){return c.run(...u)},get(...u){return c.get(...u)}}},exec(a){i.exec(a)},pragma(a){return i.prepare(`PRAGMA ${a}`).all()},close(){i.close()}},o;try{let{drizzle:a}=await import("drizzle-orm/better-sqlite3");o=a(n)}catch{o=n}return{drizzle:o,config:e,rawClient:n}}}async createPostgresConnection(e){let t=(await import("postgres")).default,{drizzle:s}=await import("drizzle-orm/postgres-js"),r=e.url??`postgres://${e.user}:${e.password}@${e.host??"localhost"}:${e.port??5432}/${e.database}`,i=t(r);return{drizzle:s(i),config:e,rawClient:i}}async createMySQLConnection(e){let t=await import("mysql2/promise"),{drizzle:s}=await import("drizzle-orm/mysql2"),r=t.createPool({host:e.host??"localhost",port:e.port??3306,database:e.database,user:e.user,password:e.password,uri:e.url});return{drizzle:s(r),config:e,rawClient:r}}async closeConnection(e){try{switch(e.config.driver){case"sqlite":e.rawClient.close();break;case"postgres":await e.rawClient.end();break;case"mysql":await e.rawClient.end();break}}catch{}}},v=x("svelar.connection",()=>new Ns)});var W,Bs,oe,J,Ri,Hs=w(()=>{"use strict";S();A();W=class{constructor(e){this.column=e}nullable(){return this.column.nullable=!0,this}notNullable(){return this.column.nullable=!1,this}default(e){return this.column.defaultValue=e,this}primary(){return this.column.primaryKey=!0,this}unique(){return this.column.unique=!0,this}unsigned(){return this.column.unsigned=!0,this}references(e,t){return this.column.references={table:t,column:e},new Bs(this.column)}build(){return this.column}},Bs=class{constructor(e){this.column=e}onDelete(e){return this.column.references.onDelete=e,this}onUpdate(e){return this.column.references.onUpdate=e,this}},oe=class{columns=[];indices=[];compositePrimary=null;addColumn(e,t){let s={name:e,type:t,nullable:!1,primaryKey:!1,autoIncrement:!1,unique:!1,unsigned:!1};return this.columns.push(s),new W(s)}increments(e="id"){let t={name:e,type:"INTEGER",nullable:!1,primaryKey:!0,autoIncrement:!0,unique:!1,unsigned:!0};return this.columns.push(t),new W(t)}bigIncrements(e="id"){let t={name:e,type:"BIGINT",nullable:!1,primaryKey:!0,autoIncrement:!0,unique:!1,unsigned:!0};return this.columns.push(t),new W(t)}string(e,t=255){return this.addColumn(e,`VARCHAR(${t})`)}text(e){return this.addColumn(e,"TEXT")}integer(e){return this.addColumn(e,"INTEGER")}bigInteger(e){return this.addColumn(e,"BIGINT")}float(e){return this.addColumn(e,"FLOAT")}decimal(e,t=8,s=2){return this.addColumn(e,`DECIMAL(${t},${s})`)}boolean(e){return this.addColumn(e,"BOOLEAN")}date(e){return this.addColumn(e,"DATE")}datetime(e){return this.addColumn(e,"DATETIME")}timestamp(e){return this.addColumn(e,"TIMESTAMP")}timestamps(){this.timestamp("created_at").nullable(),this.timestamp("updated_at").nullable()}json(e){return this.addColumn(e,"JSON")}blob(e){return this.addColumn(e,"BLOB")}enum(e,t){return this.addColumn(e,`ENUM(${t.map(s=>`'${s}'`).join(",")})`)}uuid(e="id"){return this.addColumn(e,"UUID")}ulid(e="id"){return this.addColumn(e,"ULID")}jsonb(e){return this.addColumn(e,"JSONB")}primary(e){this.compositePrimary=e}index(e,t){let s=Array.isArray(e)?e:[e];this.indices.push({columns:s,unique:!1,name:t})}uniqueIndex(e,t){let s=Array.isArray(e)?e:[e];this.indices.push({columns:s,unique:!0,name:t})}foreign(e){let t=this.columns.find(s=>s.name===e);if(!t)throw new Error(`Column "${e}" must be defined before adding a foreign key.`);return new W(t)}toSQL(e,t){let s=[],r=[];for(let i of this.columns)r.push(this.columnToSQL(i,t));this.compositePrimary&&r.push(`PRIMARY KEY (${this.compositePrimary.join(", ")})`);for(let i of this.columns)if(i.references){let n=`FOREIGN KEY (${i.name}) REFERENCES ${i.references.table}(${i.references.column})`;i.references.onDelete&&(n+=` ON DELETE ${i.references.onDelete}`),i.references.onUpdate&&(n+=` ON UPDATE ${i.references.onUpdate}`),r.push(n)}s.push(`CREATE TABLE ${e} (
2
+ var Fo=Object.defineProperty;var tt=(l=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(l,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):l)(function(l){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+l+'" is not supported')});var w=(l,e)=>()=>(l&&(e=l(l=0)),e);var N=(l,e)=>{for(var t in e)Fo(l,t,{get:e[t],enumerable:!0})};function x(l,e){let t=Symbol.for(l),s=globalThis;return s[t]||(s[t]=e()),s[t]}var A=w(()=>{"use strict"});var P={};N(P,{Connection:()=>v});var Ns,v,S=w(()=>{"use strict";A();Ns=class{connections=new Map;config=null;defaultName="default";configure(e){this.config=e,this.defaultName=e.default}async connection(e){let t=e??this.defaultName;if(this.connections.has(t))return this.connections.get(t).drizzle;if(!this.config)throw new Error("Database not configured. Call Connection.configure() first, or register DatabaseServiceProvider.");let s=this.config.connections[t];if(!s)throw new Error(`Database connection "${t}" is not defined in configuration.`);let r=await this.createConnection(s);return this.connections.set(t,r),r.drizzle}async rawClient(e){let t=e??this.defaultName;return await this.connection(t),this.connections.get(t).rawClient}async raw(e,t=[],s){let r=await this.connection(s),o=this.getConfig(s);switch(o.driver){case"sqlite":{let n=await this.rawClient(s),i=t.map(u=>typeof u=="boolean"?u?1:0:u instanceof Date?u.toISOString():u),a=n.prepare(e),c=e.trimStart().toUpperCase();return c.startsWith("SELECT")||c.startsWith("PRAGMA")||c.startsWith("WITH")?a.all(...i):a.run(...i)}case"postgres":return(await this.rawClient(s))(e,...t);case"mysql":{let n=await this.rawClient(s),[i]=await n.execute(e,t);return i}default:throw new Error(`Unsupported driver: ${o.driver}`)}}getDriver(e){return this.getConfig(e).driver}getConfig(e){let t=e??this.defaultName;if(!this.config)throw new Error("Database not configured.");let s=this.config.connections[t];if(!s)throw new Error(`Database connection "${t}" is not defined.`);return s}async disconnect(e){if(e){let t=this.connections.get(e);t&&(await this.closeConnection(t),this.connections.delete(e))}else{for(let[t,s]of this.connections)await this.closeConnection(s);this.connections.clear()}}isConnected(e){return this.connections.has(e??this.defaultName)}async transaction(e,t){let s=this.getConfig(t),r=await this.rawClient(t);switch(s.driver){case"sqlite":{r.exec("BEGIN");try{let o=await e();return r.exec("COMMIT"),o}catch(o){throw r.exec("ROLLBACK"),o}}case"postgres":{await r`BEGIN`;try{let o=await e();return await r`COMMIT`,o}catch(o){throw await r`ROLLBACK`,o}}case"mysql":{let o=await r.getConnection();await o.beginTransaction();try{let n=await e();return await o.commit(),o.release(),n}catch(n){throw await o.rollback(),o.release(),n}}default:throw new Error(`Unsupported driver: ${s.driver}`)}}async createConnection(e){switch(e.driver){case"sqlite":return this.createSQLiteConnection(e);case"postgres":return this.createPostgresConnection(e);case"mysql":return this.createMySQLConnection(e);default:throw new Error(`Unsupported database driver: ${e.driver}`)}}async createSQLiteConnection(e){let t=e.filename??e.database??":memory:";try{let s=(await import("better-sqlite3")).default,{drizzle:r}=await import("drizzle-orm/better-sqlite3"),o=new s(t);return o.pragma("journal_mode = WAL"),o.pragma("foreign_keys = ON"),{drizzle:r(o),config:e,rawClient:o}}catch(s){let r;try{r=(await new Function("mod","return import(mod)")("node:sqlite")).DatabaseSync}catch{throw new Error(`No SQLite driver available. Install better-sqlite3 (npm install better-sqlite3) or use Node.js v22+ which includes built-in SQLite support. Original error: ${s instanceof Error?s.message:String(s)}`)}let o=new r(t);o.exec("PRAGMA journal_mode = WAL"),o.exec("PRAGMA foreign_keys = ON");let n={prepare(a){let c=o.prepare(a);return{all(...u){return c.all(...u)},run(...u){return c.run(...u)},get(...u){return c.get(...u)}}},exec(a){o.exec(a)},pragma(a){return o.prepare(`PRAGMA ${a}`).all()},close(){o.close()}},i;try{let{drizzle:a}=await import("drizzle-orm/better-sqlite3");i=a(n)}catch{i=n}return{drizzle:i,config:e,rawClient:n}}}async createPostgresConnection(e){let t=(await import("postgres")).default,{drizzle:s}=await import("drizzle-orm/postgres-js"),r=e.url??`postgres://${e.user}:${e.password}@${e.host??"localhost"}:${e.port??5432}/${e.database}`,o=t(r);return{drizzle:s(o),config:e,rawClient:o}}async createMySQLConnection(e){let t=await import("mysql2/promise"),{drizzle:s}=await import("drizzle-orm/mysql2"),r=t.createPool({host:e.host??"localhost",port:e.port??3306,database:e.database,user:e.user,password:e.password,uri:e.url});return{drizzle:s(r),config:e,rawClient:r}}async closeConnection(e){try{switch(e.config.driver){case"sqlite":e.rawClient.close();break;case"postgres":await e.rawClient.end();break;case"mysql":await e.rawClient.end();break}}catch{}}},v=x("svelar.connection",()=>new Ns)});var W,Hs,ne,J,Ri,zs=w(()=>{"use strict";S();A();W=class{constructor(e){this.column=e}nullable(){return this.column.nullable=!0,this}notNullable(){return this.column.nullable=!1,this}default(e){return this.column.defaultValue=e,this}primary(){return this.column.primaryKey=!0,this}unique(){return this.column.unique=!0,this}unsigned(){return this.column.unsigned=!0,this}references(e,t){return this.column.references={table:t,column:e},new Hs(this.column)}build(){return this.column}},Hs=class{constructor(e){this.column=e}onDelete(e){return this.column.references.onDelete=e,this}onUpdate(e){return this.column.references.onUpdate=e,this}},ne=class{columns=[];indices=[];compositePrimary=null;addColumn(e,t){let s={name:e,type:t,nullable:!1,primaryKey:!1,autoIncrement:!1,unique:!1,unsigned:!1};return this.columns.push(s),new W(s)}increments(e="id"){let t={name:e,type:"INTEGER",nullable:!1,primaryKey:!0,autoIncrement:!0,unique:!1,unsigned:!0};return this.columns.push(t),new W(t)}bigIncrements(e="id"){let t={name:e,type:"BIGINT",nullable:!1,primaryKey:!0,autoIncrement:!0,unique:!1,unsigned:!0};return this.columns.push(t),new W(t)}string(e,t=255){return this.addColumn(e,`VARCHAR(${t})`)}text(e){return this.addColumn(e,"TEXT")}integer(e){return this.addColumn(e,"INTEGER")}bigInteger(e){return this.addColumn(e,"BIGINT")}float(e){return this.addColumn(e,"FLOAT")}decimal(e,t=8,s=2){return this.addColumn(e,`DECIMAL(${t},${s})`)}boolean(e){return this.addColumn(e,"BOOLEAN")}date(e){return this.addColumn(e,"DATE")}datetime(e){return this.addColumn(e,"DATETIME")}timestamp(e){return this.addColumn(e,"TIMESTAMP")}timestamps(){this.timestamp("created_at").nullable(),this.timestamp("updated_at").nullable()}json(e){return this.addColumn(e,"JSON")}blob(e){return this.addColumn(e,"BLOB")}enum(e,t){return this.addColumn(e,`ENUM(${t.map(s=>`'${s}'`).join(",")})`)}uuid(e="id"){return this.addColumn(e,"UUID")}ulid(e="id"){return this.addColumn(e,"ULID")}jsonb(e){return this.addColumn(e,"JSONB")}primary(e){this.compositePrimary=e}index(e,t){let s=Array.isArray(e)?e:[e];this.indices.push({columns:s,unique:!1,name:t})}uniqueIndex(e,t){let s=Array.isArray(e)?e:[e];this.indices.push({columns:s,unique:!0,name:t})}foreign(e){let t=this.columns.find(s=>s.name===e);if(!t)throw new Error(`Column "${e}" must be defined before adding a foreign key.`);return new W(t)}toSQL(e,t){let s=[],r=[];for(let o of this.columns)r.push(this.columnToSQL(o,t));this.compositePrimary&&r.push(`PRIMARY KEY (${this.compositePrimary.join(", ")})`);for(let o of this.columns)if(o.references){let n=`FOREIGN KEY (${o.name}) REFERENCES ${o.references.table}(${o.references.column})`;o.references.onDelete&&(n+=` ON DELETE ${o.references.onDelete}`),o.references.onUpdate&&(n+=` ON UPDATE ${o.references.onUpdate}`),r.push(n)}s.push(`CREATE TABLE ${e} (
3
3
  ${r.join(`,
4
4
  `)}
5
- )`);for(let i of this.indices){let n=i.name??`idx_${e}_${i.columns.join("_")}`,o=i.unique?"UNIQUE ":"";s.push(`CREATE ${o}INDEX ${n} ON ${e} (${i.columns.join(", ")})`)}return s}columnToSQL(e,t){let s=e.name,r=e.type;if(t==="sqlite"?r=this.mapSQLiteType(r,e):t==="postgres"?r=this.mapPostgresType(r,e):t==="mysql"&&(r=this.mapMySQLType(r,e)),s+=` ${r}`,e.primaryKey&&!this.compositePrimary&&(s+=" PRIMARY KEY",e.autoIncrement&&(t==="sqlite"?s+=" AUTOINCREMENT":t==="postgres"||t==="mysql"&&(s+=" AUTO_INCREMENT"))),!e.nullable&&!e.primaryKey&&(s+=" NOT NULL"),e.unique&&!e.primaryKey&&(s+=" UNIQUE"),e.defaultValue!==void 0){let i=typeof e.defaultValue=="string"?`'${e.defaultValue}'`:e.defaultValue===null?"NULL":e.defaultValue;s+=` DEFAULT ${i}`}return s}mapSQLiteType(e,t){return e==="BOOLEAN"?"INTEGER":e==="UUID"||e==="ULID"||e.startsWith("ENUM")||e==="JSON"||e==="JSONB"?"TEXT":e==="BIGINT"&&t.autoIncrement?"INTEGER":e}mapPostgresType(e,t){return t.autoIncrement&&e==="INTEGER"?"SERIAL":t.autoIncrement&&e==="BIGINT"?"BIGSERIAL":e==="DATETIME"?"TIMESTAMP":e==="BLOB"?"BYTEA":e.startsWith("ENUM")?"TEXT":e==="UUID"?"UUID":e==="ULID"?"VARCHAR(26)":e==="JSON"||e==="JSONB"?"JSONB":e}mapMySQLType(e,t){return e==="BOOLEAN"?"TINYINT(1)":e==="UUID"?"CHAR(36)":e==="ULID"?"CHAR(26)":e==="JSONB"?"JSON":e==="TIMESTAMP"?"DATETIME":t.unsigned&&!e.startsWith("DECIMAL")?`${e} UNSIGNED`:e}},J=class{constructor(e){this.connectionName=e}async createTable(e,t){let s=new oe;t(s);let r=v.getDriver(this.connectionName),i=s.toSQL(e,r);for(let n of i)await v.raw(n,[],this.connectionName)}async dropTable(e){await v.raw(`DROP TABLE IF EXISTS ${e}`,[],this.connectionName)}async dropTableIfExists(e){await v.raw(`DROP TABLE IF EXISTS ${e}`,[],this.connectionName)}async renameTable(e,t){v.getDriver(this.connectionName)==="mysql"?await v.raw(`RENAME TABLE ${e} TO ${t}`,[],this.connectionName):await v.raw(`ALTER TABLE ${e} RENAME TO ${t}`,[],this.connectionName)}async hasTable(e){let t=v.getDriver(this.connectionName),s;switch(t){case"sqlite":s=await v.raw("SELECT name FROM sqlite_master WHERE type='table' AND name=?",[e],this.connectionName);break;case"postgres":s=await v.raw("SELECT tablename FROM pg_tables WHERE tablename = $1",[e],this.connectionName);break;case"mysql":s=await v.raw("SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_NAME = ?",[e],this.connectionName);break;default:throw new Error(`Unsupported driver: ${t}`)}return s.length>0}async addColumn(e,t){let s=new oe;t(s);let r=v.getDriver(this.connectionName),i=s.columns;for(let n of i){let o=s.columnToSQL(n,r);await v.raw(`ALTER TABLE ${e} ADD COLUMN ${o}`,[],this.connectionName)}}async dropColumn(e,t){await v.raw(`ALTER TABLE ${e} DROP COLUMN ${t}`,[],this.connectionName)}},Ri=x("svelar.schema",()=>new J)});var Ei={};O(Ei,{Migration:()=>_e,Migrator:()=>Le});var _e,Le,zs=w(()=>{"use strict";S();Hs();_e=class{schema=new J},Le=class{migrationsTable="svelar_migrations";connectionName;constructor(e){this.connectionName=e}async ensureMigrationsTable(){let e=new J(this.connectionName);await e.hasTable(this.migrationsTable)||await e.createTable(this.migrationsTable,s=>{s.increments("id"),s.string("migration").unique(),s.integer("batch"),s.timestamp("ran_at").default("CURRENT_TIMESTAMP")})}async run(e){await this.ensureMigrationsTable();let t=await this.getRanMigrations(),s=e.filter(n=>!t.includes(n.name));if(s.length===0)return[];let r=await this.getNextBatch(),i=[];for(let n of s)await n.migration.up(),await v.raw(`INSERT INTO ${this.migrationsTable} (migration, batch) VALUES (?, ?)`,[n.name,r],this.connectionName),i.push(n.name);return i}async rollback(e){await this.ensureMigrationsTable();let t=await this.getLastBatch();if(t===0)return[];let s=await v.raw(`SELECT migration FROM ${this.migrationsTable} WHERE batch = ? ORDER BY id DESC`,[t],this.connectionName),r=[];for(let i of s){let n=i.migration,o=e.find(a=>a.name===n);o&&(await o.migration.down(),await v.raw(`DELETE FROM ${this.migrationsTable} WHERE migration = ?`,[n],this.connectionName),r.push(n))}return r}async reset(e){let t=[];for(;;){let s=await this.rollback(e);if(s.length===0)break;t.push(...s)}return t}async refresh(e){let t=await this.reset(e),s=await this.run(e);return{reset:t,migrated:s}}async fresh(e){let t=await this.dropAllTables(),s=await this.run(e);return{dropped:t,migrated:s}}async dropAllTables(){let e=v.getDriver(this.connectionName),t=[];switch(e){case"sqlite":{t=(await v.raw("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'",[],this.connectionName)).map(r=>r.name),await v.raw("PRAGMA foreign_keys = OFF",[],this.connectionName);for(let r of t)await v.raw(`DROP TABLE IF EXISTS "${r}"`,[],this.connectionName);await v.raw("PRAGMA foreign_keys = ON",[],this.connectionName);break}case"mysql":{t=(await v.raw("SHOW TABLES",[],this.connectionName)).map(r=>Object.values(r)[0]),await v.raw("SET FOREIGN_KEY_CHECKS = 0",[],this.connectionName);for(let r of t)await v.raw(`DROP TABLE IF EXISTS \`${r}\``,[],this.connectionName);await v.raw("SET FOREIGN_KEY_CHECKS = 1",[],this.connectionName);break}case"postgres":{t=(await v.raw("SELECT tablename FROM pg_tables WHERE schemaname = 'public'",[],this.connectionName)).map(r=>r.tablename);for(let r of t)await v.raw(`DROP TABLE IF EXISTS "${r}" CASCADE`,[],this.connectionName);break}default:throw new Error(`Unsupported driver for fresh: ${e}`)}return t}async getRanMigrations(){try{return(await v.raw(`SELECT migration FROM ${this.migrationsTable} ORDER BY batch, id`,[],this.connectionName)).map(t=>t.migration)}catch{return[]}}async status(e){let t=await this.getRanMigrations(),s=new Map;try{let r=await v.raw(`SELECT migration, batch FROM ${this.migrationsTable}`,[],this.connectionName);for(let i of r)s.set(i.migration,i.batch)}catch{}return e.map(r=>({name:r.name,ran:t.includes(r.name),batch:s.get(r.name)??null}))}async getNextBatch(){return await this.getLastBatch()+1}async getLastBatch(){try{return(await v.raw(`SELECT MAX(batch) as max_batch FROM ${this.migrationsTable}`,[],this.connectionName))[0]?.max_batch??0}catch{return 0}}}});var Ht={};O(Ht,{SchedulerLock:()=>Oe});import{hostname as Fa}from"os";async function Me(){let{Connection:l}=await Promise.resolve().then(()=>(S(),P));return l}async function Ba(){return(await Me()).getDriver()}var $i,G,Oe,Ne=w(()=>{"use strict";$i=!1,G=`${Fa()}:${process.pid}:${Math.random().toString(36).slice(2,10)}`;Oe=class{static getOwnerId(){return G}static async ensureTable(){if($i)return;let e=await Me();switch(e.getDriver()){case"sqlite":await e.raw(`CREATE TABLE IF NOT EXISTS scheduler_locks (
5
+ )`);for(let o of this.indices){let n=o.name??`idx_${e}_${o.columns.join("_")}`,i=o.unique?"UNIQUE ":"";s.push(`CREATE ${i}INDEX ${n} ON ${e} (${o.columns.join(", ")})`)}return s}columnToSQL(e,t){let s=e.name,r=e.type;if(t==="sqlite"?r=this.mapSQLiteType(r,e):t==="postgres"?r=this.mapPostgresType(r,e):t==="mysql"&&(r=this.mapMySQLType(r,e)),s+=` ${r}`,e.primaryKey&&!this.compositePrimary&&(s+=" PRIMARY KEY",e.autoIncrement&&(t==="sqlite"?s+=" AUTOINCREMENT":t==="postgres"||t==="mysql"&&(s+=" AUTO_INCREMENT"))),!e.nullable&&!e.primaryKey&&(s+=" NOT NULL"),e.unique&&!e.primaryKey&&(s+=" UNIQUE"),e.defaultValue!==void 0){let o=typeof e.defaultValue=="string"?`'${e.defaultValue}'`:e.defaultValue===null?"NULL":e.defaultValue;s+=` DEFAULT ${o}`}return s}mapSQLiteType(e,t){return e==="BOOLEAN"?"INTEGER":e==="UUID"||e==="ULID"||e.startsWith("ENUM")||e==="JSON"||e==="JSONB"?"TEXT":e==="BIGINT"&&t.autoIncrement?"INTEGER":e}mapPostgresType(e,t){return t.autoIncrement&&e==="INTEGER"?"SERIAL":t.autoIncrement&&e==="BIGINT"?"BIGSERIAL":e==="DATETIME"?"TIMESTAMP":e==="BLOB"?"BYTEA":e.startsWith("ENUM")?"TEXT":e==="UUID"?"UUID":e==="ULID"?"VARCHAR(26)":e==="JSON"||e==="JSONB"?"JSONB":e}mapMySQLType(e,t){return e==="BOOLEAN"?"TINYINT(1)":e==="UUID"?"CHAR(36)":e==="ULID"?"CHAR(26)":e==="JSONB"?"JSON":e==="TIMESTAMP"?"DATETIME":t.unsigned&&!e.startsWith("DECIMAL")?`${e} UNSIGNED`:e}},J=class{constructor(e){this.connectionName=e}async createTable(e,t){let s=new ne;t(s);let r=v.getDriver(this.connectionName),o=s.toSQL(e,r);for(let n of o)await v.raw(n,[],this.connectionName)}async dropTable(e){await v.raw(`DROP TABLE IF EXISTS ${e}`,[],this.connectionName)}async dropTableIfExists(e){await v.raw(`DROP TABLE IF EXISTS ${e}`,[],this.connectionName)}async renameTable(e,t){v.getDriver(this.connectionName)==="mysql"?await v.raw(`RENAME TABLE ${e} TO ${t}`,[],this.connectionName):await v.raw(`ALTER TABLE ${e} RENAME TO ${t}`,[],this.connectionName)}async hasTable(e){let t=v.getDriver(this.connectionName),s;switch(t){case"sqlite":s=await v.raw("SELECT name FROM sqlite_master WHERE type='table' AND name=?",[e],this.connectionName);break;case"postgres":s=await v.raw("SELECT tablename FROM pg_tables WHERE tablename = $1",[e],this.connectionName);break;case"mysql":s=await v.raw("SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_NAME = ?",[e],this.connectionName);break;default:throw new Error(`Unsupported driver: ${t}`)}return s.length>0}async addColumn(e,t){let s=new ne;t(s);let r=v.getDriver(this.connectionName),o=s.columns;for(let n of o){let i=s.columnToSQL(n,r);await v.raw(`ALTER TABLE ${e} ADD COLUMN ${i}`,[],this.connectionName)}}async dropColumn(e,t){await v.raw(`ALTER TABLE ${e} DROP COLUMN ${t}`,[],this.connectionName)}},Ri=x("svelar.schema",()=>new J)});var Ei={};N(Ei,{Migration:()=>_e,Migrator:()=>Le});var _e,Le,Ks=w(()=>{"use strict";S();zs();_e=class{schema=new J},Le=class{migrationsTable="svelar_migrations";connectionName;constructor(e){this.connectionName=e}async ensureMigrationsTable(){let e=new J(this.connectionName);await e.hasTable(this.migrationsTable)||await e.createTable(this.migrationsTable,s=>{s.increments("id"),s.string("migration").unique(),s.integer("batch"),s.timestamp("ran_at").default("CURRENT_TIMESTAMP")})}async run(e){await this.ensureMigrationsTable();let t=await this.getRanMigrations(),s=e.filter(n=>!t.includes(n.name));if(s.length===0)return[];let r=await this.getNextBatch(),o=[];for(let n of s)await n.migration.up(),await v.raw(`INSERT INTO ${this.migrationsTable} (migration, batch) VALUES (?, ?)`,[n.name,r],this.connectionName),o.push(n.name);return o}async rollback(e){await this.ensureMigrationsTable();let t=await this.getLastBatch();if(t===0)return[];let s=await v.raw(`SELECT migration FROM ${this.migrationsTable} WHERE batch = ? ORDER BY id DESC`,[t],this.connectionName),r=[];for(let o of s){let n=o.migration,i=e.find(a=>a.name===n);i&&(await i.migration.down(),await v.raw(`DELETE FROM ${this.migrationsTable} WHERE migration = ?`,[n],this.connectionName),r.push(n))}return r}async reset(e){let t=[];for(;;){let s=await this.rollback(e);if(s.length===0)break;t.push(...s)}return t}async refresh(e){let t=await this.reset(e),s=await this.run(e);return{reset:t,migrated:s}}async fresh(e){let t=await this.dropAllTables(),s=await this.run(e);return{dropped:t,migrated:s}}async dropAllTables(){let e=v.getDriver(this.connectionName),t=[];switch(e){case"sqlite":{t=(await v.raw("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'",[],this.connectionName)).map(r=>r.name),await v.raw("PRAGMA foreign_keys = OFF",[],this.connectionName);for(let r of t)await v.raw(`DROP TABLE IF EXISTS "${r}"`,[],this.connectionName);await v.raw("PRAGMA foreign_keys = ON",[],this.connectionName);break}case"mysql":{t=(await v.raw("SHOW TABLES",[],this.connectionName)).map(r=>Object.values(r)[0]),await v.raw("SET FOREIGN_KEY_CHECKS = 0",[],this.connectionName);for(let r of t)await v.raw(`DROP TABLE IF EXISTS \`${r}\``,[],this.connectionName);await v.raw("SET FOREIGN_KEY_CHECKS = 1",[],this.connectionName);break}case"postgres":{t=(await v.raw("SELECT tablename FROM pg_tables WHERE schemaname = 'public'",[],this.connectionName)).map(r=>r.tablename);for(let r of t)await v.raw(`DROP TABLE IF EXISTS "${r}" CASCADE`,[],this.connectionName);break}default:throw new Error(`Unsupported driver for fresh: ${e}`)}return t}async getRanMigrations(){try{return(await v.raw(`SELECT migration FROM ${this.migrationsTable} ORDER BY batch, id`,[],this.connectionName)).map(t=>t.migration)}catch{return[]}}async status(e){let t=await this.getRanMigrations(),s=new Map;try{let r=await v.raw(`SELECT migration, batch FROM ${this.migrationsTable}`,[],this.connectionName);for(let o of r)s.set(o.migration,o.batch)}catch{}return e.map(r=>({name:r.name,ran:t.includes(r.name),batch:s.get(r.name)??null}))}async getNextBatch(){return await this.getLastBatch()+1}async getLastBatch(){try{return(await v.raw(`SELECT MAX(batch) as max_batch FROM ${this.migrationsTable}`,[],this.connectionName))[0]?.max_batch??0}catch{return 0}}}});var zt={};N(zt,{SchedulerLock:()=>Oe});import{hostname as Fa}from"os";async function Me(){let{Connection:l}=await Promise.resolve().then(()=>(S(),P));return l}async function Ba(){return(await Me()).getDriver()}var $i,Q,Oe,Ie=w(()=>{"use strict";$i=!1,Q=`${Fa()}:${process.pid}:${Math.random().toString(36).slice(2,10)}`;Oe=class{static getOwnerId(){return Q}static async ensureTable(){if($i)return;let e=await Me();switch(e.getDriver()){case"sqlite":await e.raw(`CREATE TABLE IF NOT EXISTS scheduler_locks (
6
6
  task_key TEXT PRIMARY KEY,
7
7
  owner TEXT NOT NULL,
8
8
  expires_at TEXT NOT NULL
@@ -14,7 +14,7 @@ var Fn=Object.defineProperty;var tt=(l=>typeof require<"u"?require:typeof Proxy<
14
14
  task_key VARCHAR(255) PRIMARY KEY,
15
15
  owner VARCHAR(255) NOT NULL,
16
16
  expires_at DATETIME NOT NULL
17
- ) ENGINE=InnoDB`);break}$i=!0}static async acquire(e,t=5){await this.ensureTable();let s=await Me(),r=await Ba(),i=new Date().toISOString(),n=new Date(Date.now()+t*6e4).toISOString();try{await s.transaction(async()=>{switch(await s.raw("DELETE FROM scheduler_locks WHERE task_key = ? AND expires_at < ?",[e,i]),r){case"sqlite":await s.raw("INSERT OR IGNORE INTO scheduler_locks (task_key, owner, expires_at) VALUES (?, ?, ?)",[e,G,n]);break;case"postgres":await s.raw("INSERT INTO scheduler_locks (task_key, owner, expires_at) VALUES ($1, $2, $3) ON CONFLICT (task_key) DO NOTHING",[e,G,n]);break;case"mysql":await s.raw("INSERT IGNORE INTO scheduler_locks (task_key, owner, expires_at) VALUES (?, ?, ?)",[e,G,n]);break}});let o=await s.raw("SELECT owner FROM scheduler_locks WHERE task_key = ?",[e]);return o.length>0&&o[0].owner===G}catch{return!1}}static async release(e){try{await(await Me()).raw("DELETE FROM scheduler_locks WHERE task_key = ? AND owner = ?",[e,G])}catch{}}static async releaseAll(){try{await(await Me()).raw("DELETE FROM scheduler_locks WHERE owner = ?",[G])}catch{}}}});var Ai={};O(Ai,{ScheduledTask:()=>zt,Scheduler:()=>Js,SchedulerLock:()=>Oe,cronMatches:()=>Ws,parseCron:()=>Di,task:()=>Ha});function Ie(l,e,t){if(l==="*")return null;let s=new Set;for(let r of l.split(",")){let[i,n]=r.split("/"),o=n?parseInt(n,10):1;if(i==="*")for(let a=e;a<=t;a+=o)s.add(a);else if(i.includes("-")){let[a,c]=i.split("-"),u=parseInt(a,10),p=parseInt(c,10);for(let h=u;h<=p;h+=o)s.add(h)}else s.add(parseInt(i,10))}return[...s].sort((r,i)=>r-i)}function Di(l){let e=l.trim().split(/\s+/);if(e.length!==5)throw new Error(`Invalid cron expression: "${l}". Expected 5 fields.`);return{minute:Ie(e[0],0,59),hour:Ie(e[1],0,23),dayOfMonth:Ie(e[2],1,31),month:Ie(e[3],1,12),dayOfWeek:Ie(e[4],0,6)}}function Ws(l,e){let t=Di(l),s=e.getMinutes(),r=e.getHours(),i=e.getDate(),n=e.getMonth()+1,o=e.getDay();return!(t.minute&&!t.minute.includes(s)||t.hour&&!t.hour.includes(r)||t.dayOfMonth&&!t.dayOfMonth.includes(i)||t.month&&!t.month.includes(n)||t.dayOfWeek&&!t.dayOfWeek.includes(o))}function Ha(l,e,t){class s extends zt{name=l;schedule(){return t&&t(this),this}async handle(){return e()}}return new s}var zt,Js,_i=w(()=>{"use strict";Ne();zt=class{name=this.constructor.name;_running=!1;withoutOverlapping=!1;_lockTtlMinutes=5;_expression="* * * * *";schedule(){return this}onSuccess(){}onFailure(e){console.error(`[Scheduler] Task "${this.name}" failed:`,e.message)}everyMinute(){return this._expression="* * * * *",this}everyMinutes(e){return this._expression=`*/${e} * * * *`,this}everyFiveMinutes(){return this.everyMinutes(5)}everyTenMinutes(){return this.everyMinutes(10)}everyFifteenMinutes(){return this.everyMinutes(15)}everyThirtyMinutes(){return this.everyMinutes(30)}hourly(){return this._expression="0 * * * *",this}hourlyAt(e){return this._expression=`${e} * * * *`,this}daily(){return this._expression="0 0 * * *",this}dailyAt(e){let[t,s]=e.split(":").map(Number);return this._expression=`${s??0} ${t} * * *`,this}twiceDaily(e=1,t=13){return this._expression=`0 ${e},${t} * * *`,this}weekly(){return this._expression="0 0 * * 0",this}weeklyOn(e,t="00:00"){let[s,r]=t.split(":").map(Number);return this._expression=`${r??0} ${s} * * ${e}`,this}weekdays(){return this._expression=`${this._expression.split(" ").slice(0,4).join(" ")} 1-5`,this}weekends(){return this._expression=`${this._expression.split(" ").slice(0,4).join(" ")} 0,6`,this}monthly(){return this._expression="0 0 1 * *",this}monthlyOn(e,t="00:00"){let[s,r]=t.split(":").map(Number);return this._expression=`${r??0} ${s} ${e} * *`,this}quarterly(){return this._expression="0 0 1 1,4,7,10 *",this}yearly(){return this._expression="0 0 1 1 *",this}cron(e){return this._expression=e,this}preventOverlap(){return this.withoutOverlapping=!0,this}lockExpiresAfter(e){return this._lockTtlMinutes=e,this}getExpression(){return this.schedule(),this._expression}isRunning(){return this._running}async executeTask(){if(this.withoutOverlapping&&this._running)return{task:this.name,success:!0,duration:0,timestamp:new Date};let e=!1;if(this.withoutOverlapping)try{let{SchedulerLock:s}=await Promise.resolve().then(()=>(Ne(),Ht));if(e=await s.acquire(this.name,this._lockTtlMinutes),!e)return{task:this.name,success:!0,duration:0,timestamp:new Date}}catch{}this._running=!0;let t=Date.now();try{await this.handle();let s=Date.now()-t;return await this.onSuccess(),{task:this.name,success:!0,duration:s,timestamp:new Date}}catch(s){let r=Date.now()-t;return await this.onFailure(s),{task:this.name,success:!1,duration:r,error:s.message,timestamp:new Date}}finally{if(this._running=!1,e)try{let{SchedulerLock:s}=await Promise.resolve().then(()=>(Ne(),Ht));await s.release(this.name)}catch{}}}},Js=class{tasks=[];timer=null;history=[];maxHistory=100;_persistToDb=!1;persistToDatabase(){return this._persistToDb=!0,this}register(e){return this.tasks.push(e),this}registerMany(e){for(let t of e)this.register(t);return this}async run(e){let t=e??new Date,s=[];for(let r of this.tasks){let i=r.getExpression();if(Ws(i,t)){let n=await r.executeTask();s.push(n),this.addToHistory(n)}}return s}start(){if(this.timer)return;this.run().catch(s=>console.error("[Scheduler] Error:",s));let t=6e4-Date.now()%6e4;this.timer=setTimeout(()=>{this.run().catch(s=>console.error("[Scheduler] Error:",s)),this.timer=setInterval(()=>{this.run().catch(s=>console.error("[Scheduler] Error:",s))},6e4)},t),console.log(`[Scheduler] Started with ${this.tasks.length} task(s). Next tick in ${Math.round(t/1e3)}s.`)}async stop(){this.timer&&(clearTimeout(this.timer),clearInterval(this.timer),this.timer=null);try{let{SchedulerLock:e}=await Promise.resolve().then(()=>(Ne(),Ht));await e.releaseAll()}catch{}console.log("[Scheduler] Stopped.")}getTasks(){return[...this.tasks]}getHistory(){return[...this.history]}dueTasks(e){let t=e??new Date;return this.tasks.filter(s=>Ws(s.getExpression(),t))}remove(e){let t=this.tasks.findIndex(s=>s.name===e);return t!==-1?(this.tasks.splice(t,1),!0):!1}clear(){this.tasks=[]}addToHistory(e){this.history.push(e),this.history.length>this.maxHistory&&this.history.shift(),this._persistToDb&&this.persistResult(e).catch(()=>{})}_historyTableEnsured=!1;async ensureHistoryTable(){if(this._historyTableEnsured)return;let{Connection:e}=await Promise.resolve().then(()=>(S(),P));switch(e.getDriver()){case"sqlite":await e.raw(`CREATE TABLE IF NOT EXISTS scheduled_task_runs (
17
+ ) ENGINE=InnoDB`);break}$i=!0}static async acquire(e,t=5){await this.ensureTable();let s=await Me(),r=await Ba(),o=new Date().toISOString(),n=new Date(Date.now()+t*6e4).toISOString();try{await s.transaction(async()=>{switch(await s.raw("DELETE FROM scheduler_locks WHERE task_key = ? AND expires_at < ?",[e,o]),r){case"sqlite":await s.raw("INSERT OR IGNORE INTO scheduler_locks (task_key, owner, expires_at) VALUES (?, ?, ?)",[e,Q,n]);break;case"postgres":await s.raw("INSERT INTO scheduler_locks (task_key, owner, expires_at) VALUES ($1, $2, $3) ON CONFLICT (task_key) DO NOTHING",[e,Q,n]);break;case"mysql":await s.raw("INSERT IGNORE INTO scheduler_locks (task_key, owner, expires_at) VALUES (?, ?, ?)",[e,Q,n]);break}});let i=await s.raw("SELECT owner FROM scheduler_locks WHERE task_key = ?",[e]);return i.length>0&&i[0].owner===Q}catch{return!1}}static async release(e){try{await(await Me()).raw("DELETE FROM scheduler_locks WHERE task_key = ? AND owner = ?",[e,Q])}catch{}}static async releaseAll(){try{await(await Me()).raw("DELETE FROM scheduler_locks WHERE owner = ?",[Q])}catch{}}}});var Ai={};N(Ai,{ScheduledTask:()=>Kt,Scheduler:()=>Vs,SchedulerLock:()=>Oe,cronMatches:()=>Js,parseCron:()=>Di,task:()=>Ha});function Ne(l,e,t){if(l==="*")return null;let s=new Set;for(let r of l.split(",")){let[o,n]=r.split("/"),i=n?parseInt(n,10):1;if(o==="*")for(let a=e;a<=t;a+=i)s.add(a);else if(o.includes("-")){let[a,c]=o.split("-"),u=parseInt(a,10),p=parseInt(c,10);for(let h=u;h<=p;h+=i)s.add(h)}else s.add(parseInt(o,10))}return[...s].sort((r,o)=>r-o)}function Di(l){let e=l.trim().split(/\s+/);if(e.length!==5)throw new Error(`Invalid cron expression: "${l}". Expected 5 fields.`);return{minute:Ne(e[0],0,59),hour:Ne(e[1],0,23),dayOfMonth:Ne(e[2],1,31),month:Ne(e[3],1,12),dayOfWeek:Ne(e[4],0,6)}}function Js(l,e){let t=Di(l),s=e.getMinutes(),r=e.getHours(),o=e.getDate(),n=e.getMonth()+1,i=e.getDay();return!(t.minute&&!t.minute.includes(s)||t.hour&&!t.hour.includes(r)||t.dayOfMonth&&!t.dayOfMonth.includes(o)||t.month&&!t.month.includes(n)||t.dayOfWeek&&!t.dayOfWeek.includes(i))}function Ha(l,e,t){class s extends Kt{name=l;schedule(){return t&&t(this),this}async handle(){return e()}}return new s}var Kt,Vs,_i=w(()=>{"use strict";Ie();Kt=class{name=this.constructor.name;_running=!1;withoutOverlapping=!1;_lockTtlMinutes=5;_expression="* * * * *";schedule(){return this}onSuccess(){}onFailure(e){console.error(`[Scheduler] Task "${this.name}" failed:`,e.message)}everyMinute(){return this._expression="* * * * *",this}everyMinutes(e){return this._expression=`*/${e} * * * *`,this}everyFiveMinutes(){return this.everyMinutes(5)}everyTenMinutes(){return this.everyMinutes(10)}everyFifteenMinutes(){return this.everyMinutes(15)}everyThirtyMinutes(){return this.everyMinutes(30)}hourly(){return this._expression="0 * * * *",this}hourlyAt(e){return this._expression=`${e} * * * *`,this}daily(){return this._expression="0 0 * * *",this}dailyAt(e){let[t,s]=e.split(":").map(Number);return this._expression=`${s??0} ${t} * * *`,this}twiceDaily(e=1,t=13){return this._expression=`0 ${e},${t} * * *`,this}weekly(){return this._expression="0 0 * * 0",this}weeklyOn(e,t="00:00"){let[s,r]=t.split(":").map(Number);return this._expression=`${r??0} ${s} * * ${e}`,this}weekdays(){return this._expression=`${this._expression.split(" ").slice(0,4).join(" ")} 1-5`,this}weekends(){return this._expression=`${this._expression.split(" ").slice(0,4).join(" ")} 0,6`,this}monthly(){return this._expression="0 0 1 * *",this}monthlyOn(e,t="00:00"){let[s,r]=t.split(":").map(Number);return this._expression=`${r??0} ${s} ${e} * *`,this}quarterly(){return this._expression="0 0 1 1,4,7,10 *",this}yearly(){return this._expression="0 0 1 1 *",this}cron(e){return this._expression=e,this}preventOverlap(){return this.withoutOverlapping=!0,this}lockExpiresAfter(e){return this._lockTtlMinutes=e,this}getExpression(){return this.schedule(),this._expression}isRunning(){return this._running}async executeTask(){if(this.withoutOverlapping&&this._running)return{task:this.name,success:!0,duration:0,timestamp:new Date};let e=!1;if(this.withoutOverlapping)try{let{SchedulerLock:s}=await Promise.resolve().then(()=>(Ie(),zt));if(e=await s.acquire(this.name,this._lockTtlMinutes),!e)return{task:this.name,success:!0,duration:0,timestamp:new Date}}catch{}this._running=!0;let t=Date.now();try{await this.handle();let s=Date.now()-t;return await this.onSuccess(),{task:this.name,success:!0,duration:s,timestamp:new Date}}catch(s){let r=Date.now()-t;return await this.onFailure(s),{task:this.name,success:!1,duration:r,error:s.message,timestamp:new Date}}finally{if(this._running=!1,e)try{let{SchedulerLock:s}=await Promise.resolve().then(()=>(Ie(),zt));await s.release(this.name)}catch{}}}},Vs=class{tasks=[];timer=null;history=[];maxHistory=100;_persistToDb=!1;persistToDatabase(){return this._persistToDb=!0,this}register(e){return this.tasks.push(e),this}registerMany(e){for(let t of e)this.register(t);return this}async run(e){let t=e??new Date,s=[];for(let r of this.tasks){let o=r.getExpression();if(Js(o,t)){let n=await r.executeTask();s.push(n),this.addToHistory(n)}}return s}start(){if(this.timer)return;this.run().catch(s=>console.error("[Scheduler] Error:",s));let t=6e4-Date.now()%6e4;this.timer=setTimeout(()=>{this.run().catch(s=>console.error("[Scheduler] Error:",s)),this.timer=setInterval(()=>{this.run().catch(s=>console.error("[Scheduler] Error:",s))},6e4)},t),console.log(`[Scheduler] Started with ${this.tasks.length} task(s). Next tick in ${Math.round(t/1e3)}s.`)}async stop(){this.timer&&(clearTimeout(this.timer),clearInterval(this.timer),this.timer=null);try{let{SchedulerLock:e}=await Promise.resolve().then(()=>(Ie(),zt));await e.releaseAll()}catch{}console.log("[Scheduler] Stopped.")}getTasks(){return[...this.tasks]}getHistory(){return[...this.history]}dueTasks(e){let t=e??new Date;return this.tasks.filter(s=>Js(s.getExpression(),t))}remove(e){let t=this.tasks.findIndex(s=>s.name===e);return t!==-1?(this.tasks.splice(t,1),!0):!1}clear(){this.tasks=[]}addToHistory(e){this.history.push(e),this.history.length>this.maxHistory&&this.history.shift(),this._persistToDb&&this.persistResult(e).catch(()=>{})}_historyTableEnsured=!1;async ensureHistoryTable(){if(this._historyTableEnsured)return;let{Connection:e}=await Promise.resolve().then(()=>(S(),P));switch(e.getDriver()){case"sqlite":await e.raw(`CREATE TABLE IF NOT EXISTS scheduled_task_runs (
18
18
  id INTEGER PRIMARY KEY AUTOINCREMENT,
19
19
  task TEXT NOT NULL,
20
20
  success INTEGER NOT NULL,
@@ -35,11 +35,11 @@ var Fn=Object.defineProperty;var tt=(l=>typeof require<"u"?require:typeof Proxy<
35
35
  duration INT NOT NULL,
36
36
  error TEXT,
37
37
  ran_at DATETIME NOT NULL
38
- ) ENGINE=InnoDB`);break}this._historyTableEnsured=!0}async persistResult(e){try{await this.ensureHistoryTable();let{Connection:t}=await Promise.resolve().then(()=>(S(),P));await t.raw("INSERT INTO scheduled_task_runs (task, success, duration, error, ran_at) VALUES (?, ?, ?, ?, ?)",[e.task,e.success,e.duration,e.error||null,e.timestamp.toISOString()])}catch{}}}});var je={};O(je,{Job:()=>le,Queue:()=>er});var le,Wt,Ys,ae,Jt,Qs,Gs,Zs,Xs,er,ce=w(()=>{"use strict";A();le=class{attempts=0;maxAttempts=3;retryDelay=60;queue="default";failed(e){console.error(`[Queue] Job ${this.constructor.name} permanently failed:`,e.message)}retrying(e){}serialize(){let e={};for(let[t,s]of Object.entries(this))typeof s!="function"&&(e[t]=s);return JSON.stringify(e)}restore(e){for(let[t,s]of Object.entries(e))t!=="attempts"&&t!=="maxAttempts"&&t!=="retryDelay"&&t!=="queue"&&(this[t]=s)}},Wt=class{async push(e){try{e.job.attempts=1,await e.job.handle()}catch(t){if(e.attempts+1<e.maxAttempts)return e.attempts++,e.job.attempts=e.attempts+1,e.job.retrying(e.job.attempts),this.push(e);e.job.failed(t)}}async pop(){return null}async size(){return 0}async clear(){}},Ys=class{queues=new Map;async push(e){let t=e.queue;this.queues.has(t)||this.queues.set(t,[]),this.queues.get(t).push(e)}async pop(e="default"){let t=this.queues.get(e)??[],s=Date.now(),r=t.findIndex(i=>i.availableAt<=s);return r===-1?null:t.splice(r,1)[0]}async size(e="default"){return this.queues.get(e)?.length??0}async clear(e){e?this.queues.delete(e):this.queues.clear()}},ae=class{constructor(e,t){this.table=e;this.registry=t}async getConnection(){let{Connection:e}=await Promise.resolve().then(()=>(S(),P));return e}async push(e){await(await this.getConnection()).raw(`INSERT INTO ${this.table} (id, queue, payload, attempts, max_attempts, available_at, created_at)
38
+ ) ENGINE=InnoDB`);break}this._historyTableEnsured=!0}async persistResult(e){try{await this.ensureHistoryTable();let{Connection:t}=await Promise.resolve().then(()=>(S(),P));await t.raw("INSERT INTO scheduled_task_runs (task, success, duration, error, ran_at) VALUES (?, ?, ?, ?, ?)",[e.task,e.success,e.duration,e.error||null,e.timestamp.toISOString()])}catch{}}}});var je={};N(je,{Job:()=>le,Queue:()=>tr});var le,Jt,Gs,ae,Vt,Qs,Zs,Xs,er,tr,ce=w(()=>{"use strict";A();le=class{attempts=0;maxAttempts=3;retryDelay=60;queue="default";failed(e){console.error(`[Queue] Job ${this.constructor.name} permanently failed:`,e.message)}retrying(e){}serialize(){let e={};for(let[t,s]of Object.entries(this))typeof s!="function"&&(e[t]=s);return JSON.stringify(e)}restore(e){for(let[t,s]of Object.entries(e))t!=="attempts"&&t!=="maxAttempts"&&t!=="retryDelay"&&t!=="queue"&&(this[t]=s)}},Jt=class{async push(e){try{e.job.attempts=1,await e.job.handle()}catch(t){if(e.attempts+1<e.maxAttempts)return e.attempts++,e.job.attempts=e.attempts+1,e.job.retrying(e.job.attempts),this.push(e);e.job.failed(t)}}async pop(){return null}async size(){return 0}async clear(){}},Gs=class{queues=new Map;async push(e){let t=e.queue;this.queues.has(t)||this.queues.set(t,[]),this.queues.get(t).push(e)}async pop(e="default"){let t=this.queues.get(e)??[],s=Date.now(),r=t.findIndex(o=>o.availableAt<=s);return r===-1?null:t.splice(r,1)[0]}async size(e="default"){return this.queues.get(e)?.length??0}async clear(e){e?this.queues.delete(e):this.queues.clear()}},ae=class{constructor(e,t){this.table=e;this.registry=t}async getConnection(){let{Connection:e}=await Promise.resolve().then(()=>(S(),P));return e}async push(e){await(await this.getConnection()).raw(`INSERT INTO ${this.table} (id, queue, payload, attempts, max_attempts, available_at, created_at)
39
39
  VALUES (?, ?, ?, ?, ?, ?, ?)`,[e.id,e.queue,JSON.stringify({jobClass:e.jobClass,payload:e.payload}),e.attempts,e.maxAttempts,Math.floor(e.availableAt/1e3),Math.floor(e.createdAt/1e3)])}async pop(e="default"){let t=await this.getConnection(),s=Math.floor(Date.now()/1e3),r=await t.raw(`SELECT * FROM ${this.table}
40
40
  WHERE queue = ? AND available_at <= ? AND reserved_at IS NULL
41
- ORDER BY created_at ASC LIMIT 1`,[e,s]);if(!r||r.length===0)return null;let i=r[0];await t.raw(`UPDATE ${this.table} SET reserved_at = ?, attempts = attempts + 1 WHERE id = ?`,[s,i.id]);let n=JSON.parse(i.payload),o=this.registry.resolve(n.jobClass,n.payload);return{id:i.id,jobClass:n.jobClass,payload:n.payload,queue:i.queue,attempts:i.attempts+1,maxAttempts:i.max_attempts,availableAt:i.available_at*1e3,createdAt:i.created_at*1e3,job:o}}async size(e="default"){return(await(await this.getConnection()).raw(`SELECT COUNT(*) as count FROM ${this.table} WHERE queue = ? AND reserved_at IS NULL`,[e]))?.[0]?.count??0}async clear(e){let t=await this.getConnection();e?await t.raw(`DELETE FROM ${this.table} WHERE queue = ?`,[e]):await t.raw(`DELETE FROM ${this.table}`,[])}async delete(e){await(await this.getConnection()).raw(`DELETE FROM ${this.table} WHERE id = ?`,[e])}async release(e,t=0){let s=await this.getConnection(),r=Math.floor(Date.now()/1e3)+t;await s.raw(`UPDATE ${this.table} SET reserved_at = NULL, available_at = ? WHERE id = ?`,[r,e])}},Jt=class{queues=new Map;config;registry;_bullmq=null;constructor(e,t){this.config=e,this.registry=t}async getBullMQ(){if(this._bullmq)return this._bullmq;try{return this._bullmq=await Function('return import("bullmq")')(),this._bullmq}catch{throw new Error("bullmq is required for the Redis queue driver. Install it with: npm install bullmq")}}getRedisConnection(){if(this.config.url){let e=new URL(this.config.url);return{host:e.hostname||"localhost",port:parseInt(e.port)||6379,password:e.password||this.config.password||void 0,db:parseInt(e.pathname?.slice(1)||"0")||this.config.db||0}}return{host:this.config.host??"localhost",port:this.config.port??6379,password:this.config.password,db:this.config.db??0}}async getQueue(e){if(this.queues.has(e))return this.queues.get(e);let t=await this.getBullMQ(),s=this.getRedisConnection(),r=this.config.prefix??"svelar",i=new t.Queue(e,{connection:s,prefix:r,defaultJobOptions:{removeOnComplete:this.config.defaultJobOptions?.removeOnComplete??100,removeOnFail:this.config.defaultJobOptions?.removeOnFail??500}});return this.queues.set(e,i),i}async push(e){let t=await this.getQueue(e.queue),s=Math.max(0,e.availableAt-Date.now());await t.add(e.jobClass,{jobClass:e.jobClass,payload:e.payload},{jobId:e.id,delay:s>0?s:void 0,attempts:e.maxAttempts,backoff:{type:"fixed",delay:(e.job.retryDelay??60)*1e3}})}async pop(e){return null}async size(e="default"){let s=await(await this.getQueue(e)).getJobCounts("waiting","delayed","active");return s.waiting+s.delayed+s.active}async clear(e){if(e)await(await this.getQueue(e)).obliterate({force:!0});else for(let t of this.queues.values())await t.obliterate({force:!0})}async createWorker(e,t,s,r){let i=await this.getBullMQ(),n=this.getRedisConnection(),o=this.config.prefix??"svelar",a=new i.Worker(e,async c=>{let u=c.data,p=t.resolve(u.jobClass,u.payload);p.attempts=c.attemptsMade+1,await p.handle()},{connection:n,prefix:o,concurrency:r?.concurrency??1});return a.on("failed",async(c,u)=>{let p=c?.data;if(p)try{let h=t.resolve(p.jobClass,p.payload);c.attemptsMade>=(c.opts?.attempts??3)&&(h.failed(u),await s.store({id:c.id,jobClass:p.jobClass,payload:p.payload,queue:e,attempts:c.attemptsMade,maxAttempts:c.opts?.attempts??3,availableAt:Date.now(),createdAt:c.timestamp??Date.now(),job:h},u))}catch{console.error("[Queue] Failed to resolve job for failure handler:",u.message)}}),a}},Qs=class{table="svelar_failed_jobs";async getConnection(){let{Connection:e}=await Promise.resolve().then(()=>(S(),P));return e}async store(e,t){try{await(await this.getConnection()).raw(`INSERT INTO ${this.table} (id, queue, job_class, payload, exception, failed_at)
42
- VALUES (?, ?, ?, ?, ?, ?)`,[crypto.randomUUID(),e.queue,e.jobClass,e.payload,t.stack??t.message,Math.floor(Date.now()/1e3)])}catch{console.error("[Queue] Could not persist failed job (run migration to create svelar_failed_jobs table)")}}async all(){return(await(await this.getConnection()).raw(`SELECT * FROM ${this.table} ORDER BY failed_at DESC`,[])??[]).map(s=>({id:s.id,queue:s.queue,jobClass:s.job_class,payload:s.payload,exception:s.exception,failedAt:s.failed_at}))}async find(e){let s=await(await this.getConnection()).raw(`SELECT * FROM ${this.table} WHERE id = ? LIMIT 1`,[e]);if(!s||s.length===0)return null;let r=s[0];return{id:r.id,queue:r.queue,jobClass:r.job_class,payload:r.payload,exception:r.exception,failedAt:r.failed_at}}async forget(e){return await(await this.getConnection()).raw(`DELETE FROM ${this.table} WHERE id = ?`,[e]),!0}async flush(){let e=await this.getConnection(),s=(await e.raw(`SELECT COUNT(*) as count FROM ${this.table}`,[]))?.[0]?.count??0;return await e.raw(`DELETE FROM ${this.table}`,[]),s}},Gs=class{jobs=new Map;register(e){this.jobs.set(e.name,e)}registerAll(e){for(let t of e)this.register(t)}resolve(e,t){let s=this.jobs.get(e);if(!s)throw new Error(`Job class "${e}" is not registered. Call Queue.register(${e}) in your app bootstrap. Registered jobs: [${[...this.jobs.keys()].join(", ")}]`);let r=Object.create(s.prototype);r.attempts=0,r.maxAttempts=3,r.retryDelay=60,r.queue="default";try{let i=JSON.parse(t);r.restore(i)}catch{}return r}has(e){return this.jobs.has(e)}},Zs=class{config={default:"sync",connections:{sync:{driver:"sync"}}};drivers=new Map;processing=!1;jobRegistry=new Gs;failedStore=new Qs;_activeWorker=null;configure(e){this.config=e,this.drivers.clear()}register(e){this.jobRegistry.register(e)}registerAll(e){this.jobRegistry.registerAll(e)}async dispatch(e,t){let s=this.config.default,r=this.config.connections[s],i=this.resolveDriver(s);t?.queue&&(e.queue=t.queue),t?.maxAttempts!==void 0&&(e.maxAttempts=t.maxAttempts);let n={id:crypto.randomUUID(),jobClass:e.constructor.name,payload:e.serialize(),queue:e.queue??r?.queue??"default",attempts:0,maxAttempts:e.maxAttempts,availableAt:Date.now()+(t?.delay??0)*1e3,createdAt:Date.now(),job:e};await i.push(n)}async dispatchSync(e){let t=new Wt,s={id:crypto.randomUUID(),jobClass:e.constructor.name,payload:e.serialize(),queue:e.queue,attempts:0,maxAttempts:e.maxAttempts,availableAt:Date.now(),createdAt:Date.now(),job:e};await t.push(s)}async chain(e,t){if(e.length===0)return;let s=new Xs(e);t?.queue&&(s.queue=t.queue),t?.maxAttempts!==void 0&&(s.maxAttempts=t.maxAttempts),await this.dispatch(s,t)}async work(e){let t=this.config.default,s=this.resolveDriver(t),r=e?.queue??"default";if(s instanceof Jt){let a=await s.createWorker(r,this.jobRegistry,this.failedStore,{concurrency:e?.concurrency??1});return this.processing=!0,this._activeWorker=a,await new Promise(c=>{let u=()=>{this.processing?setTimeout(u,500):a.close().then(c).catch(c)};u()}),0}let i=e?.maxJobs??1/0,n=(e?.sleep??1)*1e3,o=0;for(this.processing=!0;this.processing&&o<i;){let a=await s.pop(r);if(!a){if(i===1/0){await new Promise(c=>setTimeout(c,n));continue}break}a.attempts++,a.job.attempts=a.attempts;try{await a.job.handle(),o++,s instanceof ae&&await s.delete(a.id)}catch(c){if(a.attempts<a.maxAttempts){a.job.retrying(a.attempts);let u=a.job.retryDelay??60;s instanceof ae?await s.release(a.id,u):(a.availableAt=Date.now()+u*1e3,await s.push(a))}else a.job.failed(c),await this.failedStore.store(a,c),s instanceof ae&&await s.delete(a.id)}}return o}async stop(){this.processing=!1,this._activeWorker&&(await this._activeWorker.close(),this._activeWorker=null)}async size(e){return this.resolveDriver(this.config.default).size(e)}async clear(e){return this.resolveDriver(this.config.default).clear(e)}async failed(){return this.failedStore.all()}async retry(e){let t=await this.failedStore.find(e);if(!t)return!1;let s=this.jobRegistry.resolve(t.jobClass,t.payload);return s.queue=t.queue,await this.dispatch(s,{queue:t.queue}),await this.failedStore.forget(e),!0}async retryAll(){let e=await this.failedStore.all(),t=0;for(let s of e)try{let r=this.jobRegistry.resolve(s.jobClass,s.payload);r.queue=s.queue,await this.dispatch(r,{queue:s.queue}),await this.failedStore.forget(s.id),t++}catch{}return t}async forgetFailed(e){return this.failedStore.forget(e)}async flushFailed(){return this.failedStore.flush()}resolveDriver(e){if(this.drivers.has(e))return this.drivers.get(e);let t=this.config.connections[e];if(!t)throw new Error(`Queue connection "${e}" is not defined.`);let s;switch(t.driver){case"sync":s=new Wt;break;case"memory":s=new Ys;break;case"database":s=new ae(t.table??"svelar_jobs",this.jobRegistry);break;case"redis":s=new Jt(t,this.jobRegistry);break;default:throw new Error(`Unknown queue driver: ${t.driver}`)}return this.drivers.set(e,s),s}},Xs=class extends le{remainingJobs;constructor(e){super(),this.remainingJobs=[...e],this.maxAttempts=1}async handle(){for(let e of this.remainingJobs){let t=null,s=!1;for(let r=1;r<=e.maxAttempts;r++){e.attempts=r;try{await e.handle(),s=!0;break}catch(i){t=i,r<e.maxAttempts&&(e.retrying(r),e.retryDelay>0&&await new Promise(n=>setTimeout(n,e.retryDelay*1e3)))}}if(!s&&t)throw e.failed(t),new Error(`Chain stopped: ${e.constructor.name} failed after ${e.maxAttempts} attempt(s). Remaining jobs: [${this.remainingJobs.slice(this.remainingJobs.indexOf(e)+1).map(r=>r.constructor.name).join(", ")}]`)}}serialize(){return JSON.stringify({jobs:this.remainingJobs.map(e=>({jobClass:e.constructor.name,payload:e.serialize()}))})}},er=x("svelar.queue",()=>new Zs)});var F,tr=w(()=>{"use strict";S();F=class l{tableName;selectColumns=["*"];whereClauses=[];joinClauses=[];orderClauses=[];groupByColumns=[];havingClauses=[];limitValue=null;offsetValue=null;eagerLoads=[];isDistinct=!1;connectionName;cteClauses=[];unionClauses=[];modelClass;constructor(e,t,s){this.tableName=e,this.modelClass=t,this.connectionName=s}select(...e){return this.selectColumns=e.length>0?e:["*"],this}addSelect(...e){return this.selectColumns[0]==="*"?this.selectColumns=e:this.selectColumns.push(...e),this}distinct(){return this.isDistinct=!0,this}from(e){return this.tableName=e,this}where(e,t,s){return s===void 0?this.whereClauses.push({type:"basic",column:e,operator:"=",value:t,boolean:"AND"}):this.whereClauses.push({type:"basic",column:e,operator:t,value:s,boolean:"AND"}),this}orWhere(e,t,s){return s===void 0?this.whereClauses.push({type:"basic",column:e,operator:"=",value:t,boolean:"OR"}):this.whereClauses.push({type:"basic",column:e,operator:t,value:s,boolean:"OR"}),this}whereIn(e,t){return this.whereClauses.push({type:"in",column:e,values:t,boolean:"AND"}),this}whereNotIn(e,t){return this.whereClauses.push({type:"notIn",column:e,values:t,boolean:"AND"}),this}whereNull(e){return this.whereClauses.push({type:"null",column:e,boolean:"AND"}),this}whereNotNull(e){return this.whereClauses.push({type:"notNull",column:e,boolean:"AND"}),this}whereBetween(e,t){return this.whereClauses.push({type:"between",column:e,values:t,boolean:"AND"}),this}whereRaw(e,t=[]){return this.whereClauses.push({type:"raw",raw:e,values:t,boolean:"AND"}),this}whereNested(e,t="AND"){let s=new l(this.tableName,this.modelClass,this.connectionName);if(e(s),s.whereClauses.length>0){let{whereSQL:r,whereBindings:i}=s.buildWhere(),n=r.replace(/^WHERE /,"");this.whereClauses.push({type:"raw",raw:`(${n})`,values:i,boolean:t})}return this}orWhereNested(e){return this.whereNested(e,"OR")}whereExists(e){let t=new l("__placeholder__",void 0,this.connectionName);e(t);let{sql:s,bindings:r}=t.toSQL();return this.whereClauses.push({type:"exists",subSQL:s,subBindings:r,boolean:"AND"}),this}whereNotExists(e){let t=new l("__placeholder__",void 0,this.connectionName);e(t);let{sql:s,bindings:r}=t.toSQL();return this.whereClauses.push({type:"notExists",subSQL:s,subBindings:r,boolean:"AND"}),this}whereSub(e,t,s){let r=new l("__placeholder__",void 0,this.connectionName);s(r);let{sql:i,bindings:n}=r.toSQL();return this.whereClauses.push({type:"sub",column:e,operator:t,subSQL:i,subBindings:n,boolean:"AND"}),this}orWhereRaw(e,t=[]){return this.whereClauses.push({type:"raw",raw:e,values:t,boolean:"OR"}),this}orWhereIn(e,t){return this.whereClauses.push({type:"in",column:e,values:t,boolean:"OR"}),this}orWhereNull(e){return this.whereClauses.push({type:"null",column:e,boolean:"OR"}),this}orWhereNotNull(e){return this.whereClauses.push({type:"notNull",column:e,boolean:"OR"}),this}withCTE(e,t,s=!1){let r=new l("__placeholder__",void 0,this.connectionName);t(r);let{sql:i,bindings:n}=r.toSQL();return this.cteClauses.push({name:e,sql:i,bindings:n,recursive:s}),this}withRecursiveCTE(e,t){return this.withCTE(e,t,!0)}withRawCTE(e,t,s=[],r=!1){return this.cteClauses.push({name:e,sql:t,bindings:s,recursive:r}),this}union(e){let t=new l("__placeholder__",void 0,this.connectionName);e(t);let{sql:s,bindings:r}=t.toSQL();return this.unionClauses.push({sql:s,bindings:r,all:!1}),this}unionAll(e){let t=new l("__placeholder__",void 0,this.connectionName);e(t);let{sql:s,bindings:r}=t.toSQL();return this.unionClauses.push({sql:s,bindings:r,all:!0}),this}join(e,t,s,r){return this.joinClauses.push({type:"INNER",table:e,first:t,operator:s,second:r}),this}leftJoin(e,t,s,r){return this.joinClauses.push({type:"LEFT",table:e,first:t,operator:s,second:r}),this}rightJoin(e,t,s,r){return this.joinClauses.push({type:"RIGHT",table:e,first:t,operator:s,second:r}),this}crossJoin(e){return this.joinClauses.push({type:"CROSS",table:e,first:"",operator:"",second:""}),this}orderBy(e,t="asc"){return this.orderClauses.push({column:e,direction:t}),this}latest(e="created_at"){return this.orderBy(e,"desc")}oldest(e="created_at"){return this.orderBy(e,"asc")}groupBy(...e){return this.groupByColumns.push(...e),this}having(e,t,s){return this.havingClauses.push({type:"basic",column:e,operator:t,value:s,boolean:"AND"}),this}limit(e){return this.limitValue=e,this}offset(e){return this.offsetValue=e,this}take(e){return this.limit(e)}skip(e){return this.offset(e)}with(...e){return this.eagerLoads.push(...e),this}async get(){let{sql:e,bindings:t}=this.toSQL(),s=await v.raw(e,t,this.connectionName),r=this.hydrateMany(s);return this.eagerLoads.length>0&&this.modelClass&&await this.loadRelations(r),r}async first(){return this.limitValue=1,(await this.get())[0]??null}async firstOrFail(){let e=await this.first();if(!e)throw new Error(`No results found for query on "${this.tableName}".`);return e}async find(e,t="id"){return this.where(t,e).first()}async findOrFail(e,t="id"){return this.where(t,e).firstOrFail()}async count(e="*"){let{sql:t,bindings:s}=this.buildAggregate(`COUNT(${e})`),r=await v.raw(t,s,this.connectionName);return Number(r[0]?.aggregate??0)}async sum(e){let{sql:t,bindings:s}=this.buildAggregate(`SUM(${e})`),r=await v.raw(t,s,this.connectionName);return Number(r[0]?.aggregate??0)}async avg(e){let{sql:t,bindings:s}=this.buildAggregate(`AVG(${e})`),r=await v.raw(t,s,this.connectionName);return Number(r[0]?.aggregate??0)}async max(e){let{sql:t,bindings:s}=this.buildAggregate(`MAX(${e})`);return(await v.raw(t,s,this.connectionName))[0]?.aggregate??null}async min(e){let{sql:t,bindings:s}=this.buildAggregate(`MIN(${e})`);return(await v.raw(t,s,this.connectionName))[0]?.aggregate??null}async exists(){return await this.count()>0}async doesntExist(){return!await this.exists()}async pluck(e){return this.selectColumns=[e],(await v.raw(this.toSQL().sql,this.toSQL().bindings,this.connectionName)).map(s=>s[e])}async value(e){return this.selectColumns=[e],this.limitValue=1,(await v.raw(this.toSQL().sql,this.toSQL().bindings,this.connectionName))[0]?.[e]??null}async chunk(e,t){let s=1,r=!0;for(;r;){let i=this.clone();i.limitValue=e,i.offsetValue=(s-1)*e;let n=await i.get();if(n.length===0||await t(n,s)===!1||n.length<e)break;s++}}when(e,t){return e&&t(this),this}selectRaw(e){return this.selectColumns[0]==="*"?this.selectColumns=[e]:this.selectColumns.push(e),this}async upsert(e,t,s){let r=v.getDriver(this.connectionName),i=Object.keys(e),n=Object.values(e),o=n.map(()=>"?").join(", "),a=s??i.filter(u=>!t.includes(u)),c;if(r==="postgres"){let u=a.map(p=>`${p} = EXCLUDED.${p}`).join(", ");c=`INSERT INTO ${this.tableName} (${i.join(", ")}) VALUES (${o}) ON CONFLICT (${t.join(", ")}) DO UPDATE SET ${u}`}else if(r==="mysql"){let u=a.map(p=>`${p} = VALUES(${p})`).join(", ");c=`INSERT INTO ${this.tableName} (${i.join(", ")}) VALUES (${o}) ON DUPLICATE KEY UPDATE ${u}`}else{let u=a.map(p=>`${p} = excluded.${p}`).join(", ");c=`INSERT INTO ${this.tableName} (${i.join(", ")}) VALUES (${o}) ON CONFLICT (${t.join(", ")}) DO UPDATE SET ${u}`}return v.raw(c,n,this.connectionName)}async insertMany(e){if(e.length===0)return;let t=Object.keys(e[0]),s=[],r=[];for(let n of e){let o=t.map(a=>n[a]);s.push(...o),r.push(`(${o.map(()=>"?").join(", ")})`)}let i=`INSERT INTO ${this.tableName} (${t.join(", ")}) VALUES ${r.join(", ")}`;return v.raw(i,s,this.connectionName)}async firstOrCreate(e,t={}){for(let[n,o]of Object.entries(e))this.where(n,o);let s=await this.first();if(s)return s;let r={...e,...t},i=await new l(this.tableName,this.modelClass,this.connectionName).insertGetId(r);return new l(this.tableName,this.modelClass,this.connectionName).findOrFail(i)}async updateOrCreate(e,t){let s=new l(this.tableName,this.modelClass,this.connectionName);for(let[o,a]of Object.entries(e))s.where(o,a);let r=await s.first();if(r)return await new l(this.tableName,this.modelClass,this.connectionName).where(this.modelClass?.primaryKey??"id",r[this.modelClass?.primaryKey??"id"]).update(t),new l(this.tableName,this.modelClass,this.connectionName).findOrFail(r[this.modelClass?.primaryKey??"id"]);let i={...e,...t},n=await new l(this.tableName,this.modelClass,this.connectionName).insertGetId(i);return new l(this.tableName,this.modelClass,this.connectionName).findOrFail(n)}whereColumn(e,t,s){return s===void 0?this.whereClauses.push({type:"raw",raw:`${e} = ${t}`,values:[],boolean:"AND"}):this.whereClauses.push({type:"raw",raw:`${e} ${t} ${s}`,values:[],boolean:"AND"}),this}havingRaw(e,t=[]){return this.havingClauses.push({type:"raw",raw:e,values:t,boolean:"AND"}),this}orderByRaw(e){return this.orderClauses.push({column:e,direction:"asc"}),this.orderClauses[this.orderClauses.length-1].__raw=!0,this}selectSub(e,t){let s=new l("__placeholder__",void 0,this.connectionName);e(s);let{sql:r,bindings:i}=s.toSQL(),n=`(${r}) as ${t}`;return this.selectColumns[0]==="*"?this.selectColumns=[n]:this.selectColumns.push(n),this._selectBindings||(this._selectBindings=[]),this._selectBindings.push(...i),this}_selectBindings;async truncate(){v.getDriver(this.connectionName)==="sqlite"?(await v.raw(`DELETE FROM ${this.tableName}`,[],this.connectionName),await v.raw("DELETE FROM sqlite_sequence WHERE name = ?",[this.tableName],this.connectionName)):await v.raw(`TRUNCATE TABLE ${this.tableName}`,[],this.connectionName)}async paginate(e=1,t=15){let s=await this.clone().count(),r=Math.ceil(s/t);return this.limitValue=t,this.offsetValue=(e-1)*t,{data:await this.get(),total:s,page:e,perPage:t,lastPage:r,hasMore:e<r}}async insert(e){let t=Object.keys(e),s=Object.values(e),r=s.map(()=>"?").join(", "),i=`INSERT INTO ${this.tableName} (${t.join(", ")}) VALUES (${r})`;return v.raw(i,s,this.connectionName)}async insertGetId(e,t="id"){let s=v.getDriver(this.connectionName),r=Object.keys(e),i=Object.values(e),n=i.map(()=>"?").join(", "),o=`INSERT INTO ${this.tableName} (${r.join(", ")}) VALUES (${n})`;return s==="postgres"?(o+=` RETURNING ${t}`,(await v.raw(o,i,this.connectionName))[0]?.[t]):(await v.raw(o,i,this.connectionName),s==="sqlite"?(await v.raw("SELECT last_insert_rowid() as id",[],this.connectionName))[0]?.id:s==="mysql"?(await v.raw("SELECT LAST_INSERT_ID() as id",[],this.connectionName))[0]?.id:0)}async update(e){let t=Object.keys(e),s=Object.values(e),r=t.map(a=>`${a} = ?`).join(", "),{whereSQL:i,whereBindings:n}=this.buildWhere(),o=`UPDATE ${this.tableName} SET ${r}${i}`;return await v.raw(o,[...s,...n],this.connectionName),1}async delete(){let{whereSQL:e,whereBindings:t}=this.buildWhere(),s=`DELETE FROM ${this.tableName}${e}`;return await v.raw(s,t,this.connectionName),1}async increment(e,t=1){let{whereSQL:s,whereBindings:r}=this.buildWhere(),i=`UPDATE ${this.tableName} SET ${e} = ${e} + ?${s}`;await v.raw(i,[t,...r],this.connectionName)}async decrement(e,t=1){return this.increment(e,-t)}toSQL(){let e=[],t=[];if(this.cteClauses.length>0){let o=this.cteClauses.some(c=>c.recursive)?"WITH RECURSIVE":"WITH",a=this.cteClauses.map(c=>(t.push(...c.bindings),`${c.name} AS (${c.sql})`));e.push(`${o} ${a.join(", ")}`)}this._selectBindings?.length&&t.push(...this._selectBindings);let s=this.isDistinct?"DISTINCT ":"";e.push(`SELECT ${s}${this.selectColumns.join(", ")}`),e.push(`FROM ${this.tableName}`);for(let n of this.joinClauses)n.type==="CROSS"?e.push(`CROSS JOIN ${n.table}`):e.push(`${n.type} JOIN ${n.table} ON ${n.first} ${n.operator} ${n.second}`);let{whereSQL:r,whereBindings:i}=this.buildWhere();if(r&&(e.push(r.trim()),t.push(...i)),this.groupByColumns.length>0&&e.push(`GROUP BY ${this.groupByColumns.join(", ")}`),this.havingClauses.length>0){let n=[];for(let o of this.havingClauses)o.type==="raw"?(n.push(o.raw),o.values&&t.push(...o.values)):(n.push(`${o.column} ${o.operator} ?`),t.push(o.value));e.push(`HAVING ${n.join(" AND ")}`)}if(this.orderClauses.length>0){let n=this.orderClauses.map(o=>o.__raw?o.column:`${o.column} ${o.direction.toUpperCase()}`);e.push(`ORDER BY ${n.join(", ")}`)}if(this.limitValue!==null&&e.push(`LIMIT ${this.limitValue}`),this.offsetValue!==null&&e.push(`OFFSET ${this.offsetValue}`),this.unionClauses.length>0)for(let n of this.unionClauses)e.push(n.all?"UNION ALL":"UNION"),e.push(n.sql),t.push(...n.bindings);return{sql:e.join(" "),bindings:t}}clone(){let e=new l(this.tableName,this.modelClass,this.connectionName);return e.selectColumns=[...this.selectColumns],e.whereClauses=[...this.whereClauses],e.joinClauses=[...this.joinClauses],e.orderClauses=[...this.orderClauses],e.groupByColumns=[...this.groupByColumns],e.havingClauses=[...this.havingClauses],e.limitValue=this.limitValue,e.offsetValue=this.offsetValue,e.eagerLoads=[...this.eagerLoads],e.isDistinct=this.isDistinct,e.cteClauses=[...this.cteClauses],e.unionClauses=[...this.unionClauses],e}buildWhere(){if(this.whereClauses.length===0)return{whereSQL:"",whereBindings:[]};let e=[],t=[];for(let s=0;s<this.whereClauses.length;s++){let r=this.whereClauses[s],i=s===0?"WHERE":r.boolean;switch(r.type){case"basic":if((r.operator==="IS"||r.operator==="IS NOT")&&r.value===null){let a=(r.operator==="IS","null");e.push(`${i} ${r.column} ${r.operator} ${a}`)}else e.push(`${i} ${r.column} ${r.operator} ?`),t.push(r.value);break;case"in":let n=r.values.map(()=>"?").join(", ");e.push(`${i} ${r.column} IN (${n})`),t.push(...r.values);break;case"notIn":let o=r.values.map(()=>"?").join(", ");e.push(`${i} ${r.column} NOT IN (${o})`),t.push(...r.values);break;case"null":e.push(`${i} ${r.column} IS NULL`);break;case"notNull":e.push(`${i} ${r.column} IS NOT NULL`);break;case"between":e.push(`${i} ${r.column} BETWEEN ? AND ?`),t.push(r.values[0],r.values[1]);break;case"raw":e.push(`${i} ${r.raw}`),r.values&&t.push(...r.values);break;case"exists":e.push(`${i} EXISTS (${r.subSQL})`),r.subBindings&&t.push(...r.subBindings);break;case"notExists":e.push(`${i} NOT EXISTS (${r.subSQL})`),r.subBindings&&t.push(...r.subBindings);break;case"sub":e.push(`${i} ${r.column} ${r.operator} (${r.subSQL})`),r.subBindings&&t.push(...r.subBindings);break}}return{whereSQL:e.join(" "),whereBindings:t}}buildAggregate(e){let t=this.selectColumns;this.selectColumns=[`${e} as aggregate`];let s=this.toSQL();return this.selectColumns=t,s}hydrateMany(e){return this.modelClass?e.map(t=>this.modelClass.hydrate(t)):e}async loadRelations(e){if(!(!this.modelClass||e.length===0))for(let t of this.eagerLoads){let r=new this.modelClass()[t]?.();r&&typeof r.eagerLoad=="function"&&await r.eagerLoad(e,t)}}}});var de,ue,me,pe,he,sr=w(()=>{"use strict";S();de=class{parentModel;relatedModel;constructor(e,t){this.parentModel=e,this.relatedModel=t}query(){return this.relatedModel.query()}},ue=class extends de{constructor(t,s,r,i="id"){super(t,s);this.foreignKey=r;this.localKey=i}async load(t){let s=t.getAttribute(this.localKey);return this.relatedModel.query().where(this.foreignKey,s).first()}async eagerLoad(t,s){let r=t.map(o=>o.getAttribute(this.localKey)),i=await this.relatedModel.query().whereIn(this.foreignKey,r).get(),n=new Map;for(let o of i)n.set(o.getAttribute(this.foreignKey),o);for(let o of t){let a=o.getAttribute(this.localKey);o.setRelation(s,n.get(a)??null)}}async create(t){let s=this.parentModel.getAttribute(this.localKey);return this.relatedModel.create({...t,[this.foreignKey]:s})}},me=class extends de{constructor(t,s,r,i="id"){super(t,s);this.foreignKey=r;this.localKey=i}async load(t){let s=t.getAttribute(this.localKey);return this.relatedModel.query().where(this.foreignKey,s).get()}async eagerLoad(t,s){let r=t.map(o=>o.getAttribute(this.localKey)),i=await this.relatedModel.query().whereIn(this.foreignKey,r).get(),n=new Map;for(let o of i){let a=o.getAttribute(this.foreignKey);n.has(a)||n.set(a,[]),n.get(a).push(o)}for(let o of t){let a=o.getAttribute(this.localKey);o.setRelation(s,n.get(a)??[])}}async create(t){let s=this.parentModel.getAttribute(this.localKey);return this.relatedModel.create({...t,[this.foreignKey]:s})}async createMany(t){let s=[];for(let r of t)s.push(await this.create(r));return s}},pe=class extends de{constructor(t,s,r,i="id"){super(t,s);this.foreignKey=r;this.ownerKey=i}async load(t){let s=t.getAttribute(this.foreignKey);return s==null?null:this.relatedModel.query().where(this.ownerKey,s).first()}async eagerLoad(t,s){let r=t.map(o=>o.getAttribute(this.foreignKey)).filter(o=>o!=null);if(r.length===0){for(let o of t)o.setRelation(s,null);return}let i=await this.relatedModel.query().whereIn(this.ownerKey,r).get(),n=new Map;for(let o of i)n.set(o.getAttribute(this.ownerKey),o);for(let o of t){let a=o.getAttribute(this.foreignKey);o.setRelation(s,n.get(a)??null)}}associate(t){return this.parentModel.setAttribute(this.foreignKey,t.getAttribute(this.ownerKey)),this.parentModel}dissociate(){return this.parentModel.setAttribute(this.foreignKey,null),this.parentModel}},he=class extends de{constructor(t,s,r,i,n,o="id",a="id"){super(t,s);this.pivotTable=r;this.foreignPivotKey=i;this.relatedPivotKey=n;this.parentKey=o;this.relatedKey=a}async load(t){let s=t.getAttribute(this.parentKey),r=this.relatedModel.tableName,n=(await v.raw(`SELECT ${this.relatedPivotKey} FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ?`,[s])).map(o=>o[this.relatedPivotKey]);return n.length===0?[]:this.relatedModel.query().whereIn(this.relatedKey,n).get()}async eagerLoad(t,s){let r=t.map(p=>p.getAttribute(this.parentKey));if(r.length===0){for(let p of t)p.setRelation(s,[]);return}let i=r.map(()=>"?").join(", "),n=await v.raw(`SELECT * FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} IN (${i})`,r),o=[...new Set(n.map(p=>p[this.relatedPivotKey]))],a=o.length>0?await this.relatedModel.query().whereIn(this.relatedKey,o).get():[],c=new Map;for(let p of a)c.set(p.getAttribute(this.relatedKey),p);let u=new Map;for(let p of n){let h=p[this.foreignPivotKey],m=p[this.relatedPivotKey],f=c.get(m);f&&(u.has(h)||u.set(h,[]),u.get(h).push(f))}for(let p of t){let h=p.getAttribute(this.parentKey);p.setRelation(s,u.get(h)??[])}}async attach(t,s){let r=this.parentModel.getAttribute(this.parentKey),i={[this.foreignPivotKey]:r,[this.relatedPivotKey]:t,...s},n=Object.keys(i),o=Object.values(i),a=o.map(()=>"?").join(", ");await v.raw(`INSERT INTO ${this.pivotTable} (${n.join(", ")}) VALUES (${a})`,o)}async detach(t){let s=this.parentModel.getAttribute(this.parentKey);t?await v.raw(`DELETE FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ? AND ${this.relatedPivotKey} = ?`,[s,t]):await v.raw(`DELETE FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ?`,[s])}async sync(t){await this.detach();for(let s of t)await this.attach(s)}async toggle(t){let s=this.parentModel.getAttribute(this.parentKey);for(let r of t)(await v.raw(`SELECT 1 FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ? AND ${this.relatedPivotKey} = ? LIMIT 1`,[s,r])).length>0?await this.detach(r):await this.attach(r)}}});var Li=w(()=>{"use strict"});var Ue,rr=w(()=>{"use strict";Ue=class{app;constructor(e){this.app=e}boot(){}}});var Mi=w(()=>{"use strict";rr();Zt()});var qe,ge,Zt=w(()=>{"use strict";A();Li();Mi();qe=class{listeners=new Map;wildcardListeners=[];onceListeners=new Map;listen(e,t){let s=typeof e=="string"?e:e.name;return this.listeners.has(s)||this.listeners.set(s,[]),this.listeners.get(s).push(t),()=>{let r=this.listeners.get(s);if(r){let i=r.indexOf(t);i>=0&&r.splice(i,1)}}}once(e,t){let s=typeof e=="string"?e:e.name;return this.onceListeners.has(s)||this.onceListeners.set(s,[]),this.onceListeners.get(s).push(t),()=>{let r=this.onceListeners.get(s);if(r){let i=r.indexOf(t);i>=0&&r.splice(i,1)}}}onAny(e){return this.wildcardListeners.push(e),()=>{let t=this.wildcardListeners.indexOf(e);t>=0&&this.wildcardListeners.splice(t,1)}}async dispatch(e){let t=e.constructor.name,s=this.listeners.get(t)??[];for(let i of s)await i(e);let r=this.onceListeners.get(t)??[];for(let i of r)await i(e);this.onceListeners.delete(t);for(let i of this.wildcardListeners)await i(t,e)}async emit(e,t){let s=this.listeners.get(e)??[];for(let i of s)await i(t);let r=this.onceListeners.get(e)??[];for(let i of r)await i(t);this.onceListeners.delete(e);for(let i of this.wildcardListeners)await i(e,t)}subscribe(e){e.subscribe(this)}forget(e){let t=typeof e=="string"?e:e.name;this.listeners.delete(t),this.onceListeners.delete(t)}flush(){this.listeners.clear(),this.onceListeners.clear(),this.wildcardListeners=[]}hasListeners(e){let t=typeof e=="string"?e:e.name;return(this.listeners.get(t)?.length??0)>0||(this.onceListeners.get(t)?.length??0)>0||this.wildcardListeners.length>0}listenerCount(e){let t=typeof e=="string"?e:e.name;return(this.listeners.get(t)?.length??0)+(this.onceListeners.get(t)?.length??0)}},ge=x("svelar.event",()=>new qe)});var Xt,Oi=w(()=>{"use strict";tr();sr();Zt();Xt=class l{static table;static primaryKey="id";static incrementing=!0;static timestamps=!0;static createdAt="created_at";static updatedAt="updated_at";static casts={};static fillable=[];static hidden=[];static connection=void 0;static hooks=new Map;static observers=new Map;static events=[];attributes={};originalAttributes={};relations={};exists=!1;constructor(e){return e&&this.fill(e),new Proxy(this,{get(t,s,r){return typeof s=="symbol"||s in t||typeof s!="string"||["table","primaryKey","incrementing","timestamps","casts","fillable","hidden","connection"].includes(s)?Reflect.get(t,s,r):typeof t[s]=="function"?t[s].bind(t):t.getAttribute(s)},set(t,s,r){return typeof s=="symbol"||s in t?Reflect.set(t,s,r):(t.setAttribute(s,r),!0)}})}static query(){let e=new this,t=this;return new F(t.table,this,t.connection)}static async find(e){let t=this;return this.query().find(e,t.primaryKey)}static async findOrFail(e){let t=this;return this.query().findOrFail(e,t.primaryKey)}static async all(){return this.query().get()}static async first(){return this.query().first()}static async firstOrFail(){return this.query().firstOrFail()}static where(e,t,s){return this.query().where(e,t,s)}static whereIn(e,t){return this.query().whereIn(e,t)}static whereNull(e){return this.query().whereNull(e)}static whereNotNull(e){return this.query().whereNotNull(e)}static orderBy(e,t){return this.query().orderBy(e,t)}static latest(e){return this.query().latest(e)}static oldest(e){return this.query().oldest(e)}static with(...e){return this.query().with(...e)}static async count(){return this.query().count()}static async create(e){let t=new this,s=this;if(t.fill(e),await t.fireHook("creating"),await t.fireHook("saving"),s.timestamps){let o=new Date().toISOString();t.setAttribute(s.createdAt,o),t.setAttribute(s.updatedAt,o)}let r=t.getInsertableAttributes(),n=await new F(s.table,this,s.connection).insertGetId(r,s.primaryKey);return s.incrementing&&n&&t.setAttribute(s.primaryKey,n),t.syncOriginal(),t.exists=!0,await t.fireHook("created"),await t.fireHook("saved"),t}async save(){let e=this.constructor;if(this.exists){await this.fireHook("updating"),await this.fireHook("saving"),e.timestamps&&this.setAttribute(e.updatedAt,new Date().toISOString());let t=this.getDirty();if(Object.keys(t).length>0){let s=this.getAttribute(e.primaryKey);await new F(e.table,this.constructor,e.connection).where(e.primaryKey,s).update(t)}this.syncOriginal(),await this.fireHook("updated"),await this.fireHook("saved")}else{if(await this.fireHook("creating"),await this.fireHook("saving"),e.timestamps){let i=new Date().toISOString();this.getAttribute(e.createdAt)||this.setAttribute(e.createdAt,i),this.setAttribute(e.updatedAt,i)}let t=this.getInsertableAttributes(),r=await new F(e.table,this.constructor,e.connection).insertGetId(t,e.primaryKey);e.incrementing&&r&&this.setAttribute(e.primaryKey,r),this.syncOriginal(),this.exists=!0,await this.fireHook("created"),await this.fireHook("saved")}}async update(e){this.fill(e),await this.save()}async delete(){let e=this.constructor;await this.fireHook("deleting");let t=this.getAttribute(e.primaryKey);await new F(e.table,this.constructor,e.connection).where(e.primaryKey,t).delete(),this.exists=!1,await this.fireHook("deleted")}async refresh(){let e=this.constructor,t=this.getAttribute(e.primaryKey),s=await this.constructor.find(t);s&&(this.attributes={...s.attributes},this.syncOriginal())}getAttribute(e){let t=this.constructor,s=this.attributes[e],r=t.casts[e];if(r&&s!==void 0&&s!==null)switch(r){case"number":return Number(s);case"boolean":return!!s;case"string":return String(s);case"date":return new Date(s);case"json":return typeof s=="string"?JSON.parse(s):s}return s}setAttribute(e,t){this.constructor.casts[e]==="json"&&typeof t!="string"?this.attributes[e]=JSON.stringify(t):this.attributes[e]=t}fill(e){let t=this.constructor;for(let[s,r]of Object.entries(e))t.fillable.length>0&&!t.fillable.includes(s)||this.setAttribute(s,r)}getAttributes(){return{...this.attributes}}getOriginal(e){return e?this.originalAttributes[e]:{...this.originalAttributes}}getDirty(){let e={};for(let[t,s]of Object.entries(this.attributes))s!==this.originalAttributes[t]&&(e[t]=s);return e}isDirty(...e){let t=this.getDirty();return e.length===0?Object.keys(t).length>0:e.some(s=>s in t)}isClean(...e){return!this.isDirty(...e)}wasChanged(...e){return this.isDirty(...e)}hasOne(e,t,s){return new ue(this,e,t,s??this.constructor.primaryKey)}hasMany(e,t,s){return new me(this,e,t,s??this.constructor.primaryKey)}belongsTo(e,t,s){return new pe(this,e,t,s??e.primaryKey)}belongsToMany(e,t,s,r,i,n){return new he(this,e,t,s,r,i??this.constructor.primaryKey,n??e.primaryKey)}setRelation(e,t){this.relations[e]=t}getRelation(e){return this.relations[e]}relationLoaded(e){return e in this.relations}toJSON(){let e=this.constructor,t={};for(let[s,r]of Object.entries(this.attributes))e.hidden.includes(s)||(t[s]=this.getAttribute(s));for(let[s,r]of Object.entries(this.relations))Array.isArray(r)?t[s]=r.map(i=>i instanceof l?i.toJSON():i):r instanceof l?t[s]=r.toJSON():t[s]=r;return t}toObject(){return this.toJSON()}static hydrate(e){let t=new this;return t.attributes={...e},t.syncOriginal(),t.exists=!0,t}static boot(e){this.hooks.set(this.name,e)}static observe(e){let t=this.observers.get(this.name)??[];t.push(e),this.observers.set(this.name,t)}static removeObservers(){this.observers.delete(this.name)}async fireHook(e){let t=this.constructor,s=l.hooks.get(t.name);s?.[e]&&await s[e](this),typeof this[e]=="function"&&await this[e]();let r=l.observers.get(t.name)??[];for(let n of r){let o=n[e];typeof o=="function"&&await o.call(n,this)}let i=t.name.toLowerCase();await ge.emit(`${i}.${e}`,this)}async fireEvent(e){let t=this.constructor;if(!t.events.includes(e))throw new Error(`Event "${e}" is not declared in ${t.name}.events. Add it to: static events = ['${e}', ...];`);let s=l.observers.get(t.name)??[];for(let i of s){let n=i[e];typeof n=="function"&&await n.call(i,this)}let r=t.name.toLowerCase();await ge.emit(`${r}.${e}`,this)}syncOriginal(){this.originalAttributes={...this.attributes}}getInsertableAttributes(){let e=this.constructor,t={...this.attributes};return e.incrementing&&t[e.primaryKey]===void 0&&delete t[e.primaryKey],t}static get tableName(){return this.table}}});var es,Ni=w(()=>{"use strict";es=class{async call(e){await new e().run()}}});var Z,Ii,ir=w(()=>{"use strict";A();Z=class{bindings=new Map;aliases=new Map;resolved=new Set;bind(e,t){this.bindings.set(e,{factory:t,singleton:!1,tags:[]})}singleton(e,t){this.bindings.set(e,{factory:t,singleton:!0,tags:[]})}instance(e,t){this.bindings.set(e,{factory:()=>t,singleton:!0,instance:t,tags:[]})}alias(e,t){this.aliases.set(e,t)}async make(e){let t=this.resolveAlias(e),s=this.bindings.get(t);if(!s)throw new Error(`No binding found for "${e}" in the container.`);if(s.singleton&&s.instance!==void 0)return s.instance;let r=await s.factory(this);return s.singleton&&(s.instance=r),this.resolved.add(t),r}makeSync(e){let t=this.resolveAlias(e),s=this.bindings.get(t);if(!s)throw new Error(`No binding found for "${e}" in the container.`);if(s.singleton&&s.instance!==void 0)return s.instance;let r=s.factory(this);if(r instanceof Promise)throw new Error(`Binding "${e}" has an async factory. Use container.make() instead of container.makeSync().`);return s.singleton&&(s.instance=r),this.resolved.add(t),r}has(e){let t=this.resolveAlias(e);return this.bindings.has(t)}isResolved(e){return this.resolved.has(this.resolveAlias(e))}tag(e,t){for(let s of e){let r=this.bindings.get(s);r&&r.tags.push(t)}}async tagged(e){let t=[];for(let[s,r]of this.bindings)r.tags.includes(e)&&t.push(await this.make(s));return t}flush(){for(let e of this.bindings.values())e.singleton&&(e.instance=void 0);this.resolved.clear()}forget(e){this.bindings.delete(e),this.resolved.delete(e)}getBindings(){return[...this.bindings.keys()]}resolveAlias(e){return this.aliases.get(e)??e}},Ii=x("svelar.container",()=>new Z)});var ts,ji=w(()=>{"use strict";ir();ts=class{container;providers=[];booted=!1;constructor(e){this.container=e??new Z,this.container.instance("app",this),this.container.instance("container",this.container)}register(e){let t=new e(this.container);return this.providers.push(t),this}async bootstrap(){if(this.booted)return this;for(let e of this.providers)await e.register();for(let e of this.providers)await e.boot();return this.booted=!0,this}isBooted(){return this.booted}async make(e){return this.container.make(e)}getProviders(){return[...this.providers]}}});var _,V,ss,fe,rs,ve,be,is,ye,we=w(()=>{"use strict";_=class{},V=class{middleware=[];namedMiddleware=new Map;use(e){return typeof e=="function"&&"prototype"in e&&typeof e.prototype?.handle=="function"?this.middleware.push(new e):this.middleware.push(e),this}register(e,t){return typeof t=="function"&&"prototype"in t&&typeof t.prototype?.handle=="function"?this.namedMiddleware.set(e,new t):this.namedMiddleware.set(e,t),this}get(e){return this.namedMiddleware.get(e)}async execute(e,t,s){let r=[...this.middleware];if(s)for(let n of s){let o=this.namedMiddleware.get(n);o&&r.push(o)}let i=t;for(let n=r.length-1;n>=0;n--){let o=r[n],a=i;typeof o.handle=="function"?i=()=>o.handle(e,a):i=()=>o(e,a)}return i()}count(){return this.middleware.length}},ss=class extends _{constructor(t={}){super();this.options=t}async handle(t,s){let r=await s();if(!r)return;let i=Array.isArray(this.options.origin)?this.options.origin.join(", "):this.options.origin??"*";return r.headers.set("Access-Control-Allow-Origin",i),r.headers.set("Access-Control-Allow-Methods",(this.options.methods??["GET","POST","PUT","DELETE","PATCH","OPTIONS"]).join(", ")),r.headers.set("Access-Control-Allow-Headers",(this.options.headers??["Content-Type","Authorization"]).join(", ")),this.options.credentials&&r.headers.set("Access-Control-Allow-Credentials","true"),this.options.maxAge&&r.headers.set("Access-Control-Max-Age",String(this.options.maxAge)),t.event.request.method==="OPTIONS"?new Response(null,{status:204,headers:r.headers}):r}},fe=class extends _{requests=new Map;maxRequests;windowMs;constructor(e={}){super(),this.maxRequests=e.maxRequests??60,this.windowMs=e.windowMs??6e4}async handle(e,t){let s=e.event.request.headers.get("x-forwarded-for")??e.event.getClientAddress?.()??"unknown",r=Date.now(),i=this.requests.get(s);if(i&&r<i.resetAt){if(i.count>=this.maxRequests)return new Response(JSON.stringify({error:"Too many requests"}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(Math.ceil((i.resetAt-r)/1e3))}});i.count++}else this.requests.set(s,{count:1,resetAt:r+this.windowMs});return t()}},rs=class extends _{async handle(e,t){let s=Date.now(),r=e.event.request.method,i=e.event.url.pathname,n=await t(),o=Date.now()-s,a=n instanceof Response?n.status:200;return console.log(`[${new Date().toISOString()}] ${r} ${i} \u2192 ${a} (${o}ms)`),n}},ve=class extends _{cookieName;headerName;fieldName;excludePaths;onlyPaths;constructor(e={}){super(),this.cookieName=e.cookieName??"XSRF-TOKEN",this.headerName=e.headerName??"X-CSRF-Token",this.fieldName=e.fieldName??"_csrf",this.excludePaths=e.excludePaths??[],this.onlyPaths=e.onlyPaths??null}async handle(e,t){let{event:s}=e,r=s.request.method.toUpperCase();if(["GET","HEAD","OPTIONS"].includes(r))return this.setTokenAndContinue(e,t);if((s.request.headers.get("authorization")??"").startsWith("Bearer "))return t();let n=s.url.pathname;if(this.onlyPaths&&!this.onlyPaths.some(c=>n.startsWith(c)))return this.setTokenAndContinue(e,t);if(this.excludePaths.some(c=>n.startsWith(c)))return t();let o=this.getCookieToken(s),a=s.request.headers.get(this.headerName)??await this.getBodyToken(s);return!o||!a||!this.timingSafeEqual(o,a)?new Response(JSON.stringify({message:"CSRF token mismatch"}),{status:419,headers:{"Content-Type":"application/json"}}):t()}async setTokenAndContinue(e,t){let s=await t();if(!(s instanceof Response))return s;let i=this.getCookieToken(e.event)||this.generateToken();return s.headers.append("Set-Cookie",`${this.cookieName}=${i}; Path=/; SameSite=Lax`),s}getCookieToken(e){let s=(e.request.headers.get("cookie")??"").match(new RegExp(`${this.cookieName}=([^;]+)`));return s?s[1]:null}async getBodyToken(e){try{let t=e.request.headers.get("content-type")??"";if(t.includes("application/x-www-form-urlencoded")||t.includes("multipart/form-data"))return(await e.request.clone().formData()).get(this.fieldName);if(t.includes("application/json"))return(await e.request.clone().json())[this.fieldName]??null}catch{}return null}generateToken(){let e=new Uint8Array(32);return crypto.getRandomValues(e),Array.from(e,t=>t.toString(16).padStart(2,"0")).join("")}timingSafeEqual(e,t){if(e.length!==t.length)return!1;let s=new TextEncoder,r=s.encode(e),i=s.encode(t),n=0;for(let o=0;o<r.length;o++)n|=r[o]^i[o];return n===0}},be=class extends _{allowedOrigins;constructor(e={}){super(),this.allowedOrigins=new Set(e.allowedOrigins??[])}async handle(e,t){let{event:s}=e,r=s.request.method.toUpperCase();if(["GET","HEAD","OPTIONS"].includes(r)||(s.request.headers.get("authorization")??"").startsWith("Bearer "))return t();let n=s.request.headers.get("origin");if(!n)return t();let o=s.url.origin;return n===o||this.allowedOrigins.has(n)?t():new Response(JSON.stringify({message:"Cross-origin request blocked"}),{status:403,headers:{"Content-Type":"application/json"}})}},is=class extends _{secret;tolerance;signatureHeader;timestampHeader;onlyPaths;constructor(e){super(),this.secret=e.secret,this.tolerance=e.tolerance??300,this.signatureHeader=e.signatureHeader??"X-Signature",this.timestampHeader=e.timestampHeader??"X-Timestamp",this.onlyPaths=e.onlyPaths??null}async handle(e,t){let{event:s}=e;if(this.onlyPaths){let y=s.url.pathname;if(!this.onlyPaths.some(C=>y.startsWith(C)))return t()}let r=s.request.headers.get(this.signatureHeader),i=s.request.headers.get(this.timestampHeader);if(!r||!i)return new Response(JSON.stringify({message:"Missing request signature"}),{status:401,headers:{"Content-Type":"application/json"}});let n=parseInt(i,10),o=Math.floor(Date.now()/1e3);if(isNaN(n)||Math.abs(o-n)>this.tolerance)return new Response(JSON.stringify({message:"Request signature expired"}),{status:401,headers:{"Content-Type":"application/json"}});let c=await s.request.clone().text(),{createHmac:u}=await import("crypto"),p=s.request.method.toUpperCase(),h=s.url.pathname+s.url.search,m=`${i}.${p}.${h}.${c}`,f=u("sha256",this.secret).update(m).digest("hex");return r.length!==f.length||!this.timingSafeCompare(r,f)?new Response(JSON.stringify({message:"Invalid request signature"}),{status:401,headers:{"Content-Type":"application/json"}}):t()}timingSafeCompare(e,t){if(e.length!==t.length)return!1;let s=new TextEncoder,r=s.encode(e),i=s.encode(t),n=0;for(let o=0;o<r.length;o++)n|=r[o]^i[o];return n===0}static sign(e,t,s,r,i){let{createHmac:n}=tt("crypto"),o=i??Math.floor(Date.now()/1e3),a=`${o}.${t.toUpperCase()}.${s}.${r}`;return{signature:n("sha256",e).update(a).digest("hex"),timestamp:o}}},ye=class extends _{attempts=new Map;maxAttempts;decayMinutes;constructor(e={}){super(),this.maxAttempts=e.maxAttempts??5,this.decayMinutes=e.decayMinutes??1}async handle(e,t){let r=`${e.event.request.headers.get("x-forwarded-for")??e.event.getClientAddress?.()??"unknown"}:${e.event.url.pathname}`,i=Date.now(),n=this.attempts.get(r);if(n){if(i<n.blockedUntil){let a=Math.ceil((n.blockedUntil-i)/1e3);return new Response(JSON.stringify({message:"Too many attempts. Please try again later.",retry_after:a}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(a)}})}if(n.count>=this.maxAttempts){n.blockedUntil=i+this.decayMinutes*6e4,n.count=0;let a=this.decayMinutes*60;return new Response(JSON.stringify({message:"Too many attempts. Please try again later.",retry_after:a}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(a)}})}}let o=await t();if(o instanceof Response&&o.status>=400&&o.status<500){let a=this.attempts.get(r)??{count:0,blockedUntil:0};if(a.count++,this.attempts.set(r,a),this.attempts.size>1e4)for(let[c,u]of this.attempts)i>u.blockedUntil+this.decayMinutes*6e4*2&&this.attempts.delete(c)}return o}}});import{z as Ce}from"zod";function Ui(l,e=!1){let t=new l;return e?{GET:t.handle("show"),PUT:t.handle("update"),PATCH:t.handle("update"),DELETE:t.handle("destroy")}:{GET:t.handle("index"),POST:t.handle("store")}}var ns,Y,Fe,Be,He,qi=w(()=>{"use strict";we();ns=class{controllerMiddleware=[];middleware(e,t){let s;typeof e=="function"&&e.prototype instanceof _?s=new e:s=e,this.controllerMiddleware.push({middleware:s,only:t?.only,except:t?.except})}handle(e){return async t=>{try{let s=this.controllerMiddleware.filter(r=>!(r.only&&!r.only.includes(e)||r.except&&r.except.includes(e)));if(s.length>0){let r=new V;for(let{middleware:o}of s)r.use(o);let i={event:t,params:t.params,locals:t.locals},n=await r.execute(i,async()=>this.callMethod(e,t));if(n instanceof Response)return n}return await this.callMethod(e,t)}catch(s){return this.handleError(s,t)}}}json(e,t=200,s={}){let r=JSON.stringify(e,null,2);return new Response(r,{status:t,headers:{"Content-Type":"application/json",...s}})}text(e,t=200){return new Response(e,{status:t,headers:{"Content-Type":"text/plain"}})}html(e,t=200){return new Response(e,{status:t,headers:{"Content-Type":"text/html"}})}redirect(e,t=302){return new Response(null,{status:t,headers:{Location:e}})}noContent(){return new Response(null,{status:204})}created(e){return e?this.json(e,201):new Response(null,{status:201})}async validate(e,t){let s=t instanceof Ce.ZodObject?t:Ce.object(t),r,i=e.request.headers.get("content-type")??"";if(i.includes("application/json"))r=await e.request.json();else if(i.includes("multipart/form-data")||i.includes("application/x-www-form-urlencoded")){let o=await e.request.formData();r=Object.fromEntries(o)}else r=Object.fromEntries(e.url.searchParams);let n=s.safeParse(r);if(!n.success)throw new Y(n.error);return n.data}validateQuery(e,t){let s=t instanceof Ce.ZodObject?t:Ce.object(t),r=Object.fromEntries(e.url.searchParams),i=s.safeParse(r);if(!i.success)throw new Y(i.error);return i.data}validateParams(e,t){let r=(t instanceof Ce.ZodObject?t:Ce.object(t)).safeParse(e.params);if(!r.success)throw new Y(r.error);return r.data}handleError(e,t){return e instanceof Y?this.json({message:"Validation failed",errors:e.errors},422):e instanceof Fe?this.json({message:e.message||"Not found"},404):e instanceof Be?this.json({message:e.message||"Unauthorized"},401):e instanceof He?this.json({message:e.message||"Forbidden"},403):(console.error("[Svelar] Controller error:",e),this.json({message:process.env.NODE_ENV==="production"?"Internal server error":e.message},500))}async callMethod(e,t){let s=this[e];if(typeof s!="function")throw new Error(`Method "${e}" not found on controller "${this.constructor.name}".`);let r=await s.call(this,t);return r instanceof Response?r:this.json(r)}};Y=class extends Error{errors;constructor(e){super("Validation failed"),this.name="ValidationError",this.errors={};for(let t of e.issues){let s=t.path.join(".");this.errors[s]||(this.errors[s]=[]),this.errors[s].push(t.message)}}},Fe=class extends Error{constructor(e="Not found"){super(e),this.name="NotFoundError"}},Be=class extends Error{constructor(e="Unauthorized"){super(e),this.name="UnauthorizedError"}},He=class extends Error{constructor(e="Forbidden"){super(e),this.name="ForbiddenError"}}});import{randomBytes as Ja,createHmac as Fi,timingSafeEqual as Va}from"crypto";import{promises as Q}from"fs";import{join as ze}from"path";var xe,Ke,X,os,as,ls,Se,nr=w(()=>{"use strict";we();xe=class l{constructor(e,t){this.id=e;t&&(this.data={...t},this.data._flash&&(this.previousFlashData=this.data._flash,delete this.data._flash))}data={};dirty=!1;flashData={};previousFlashData={};get(e,t){return e in this.flashData?this.flashData[e]:e in this.previousFlashData?this.previousFlashData[e]:e in this.data?this.data[e]:t}set(e,t){this.data[e]=t,this.dirty=!0}has(e){return e in this.data||e in this.flashData||e in this.previousFlashData}forget(e){delete this.data[e],this.dirty=!0}flush(){this.data={},this.dirty=!0}flash(e,t){this.flashData[e]=t,this.dirty=!0}all(){return{...this.data,...this.previousFlashData,...this.flashData}}isDirty(){return this.dirty||Object.keys(this.flashData).length>0}toPersist(){let e={...this.data};return Object.keys(this.flashData).length>0&&(e._flash=this.flashData),e}regenerateId(){let e=this.id,t=l.generateId();this.id=t,this.dirty=!0;let s=Ke.get(e);return s instanceof X&&s.markOldSessionId(e),Ke.delete(e),t}static generateId(){return Ja(32).toString("hex")}},Ke=new Map,X=class{sessions=new Map;oldSessionIds=new Set;async read(e){if(this.oldSessionIds.has(e))return null;let t=this.sessions.get(e);return t?Date.now()>t.expiresAt?(this.sessions.delete(e),null):t.data:null}async write(e,t,s){this.sessions.set(e,{data:t,expiresAt:Date.now()+s*1e3}),Ke.set(e,this)}async destroy(e){this.sessions.delete(e),Ke.delete(e)}async gc(e){let t=Date.now();for(let[s,r]of this.sessions)t>r.expiresAt&&(this.sessions.delete(s),Ke.delete(s))}markOldSessionId(e){this.oldSessionIds.add(e),this.sessions.delete(e)}},os=class{constructor(e="sessions",t){this.tableName=e;this.connectionName=t}tableEnsured=!1;async ensureTable(){if(!this.tableEnsured)try{let{Connection:e}=await Promise.resolve().then(()=>(S(),P));switch(e.getDriver(this.connectionName)){case"sqlite":await e.raw(`CREATE TABLE IF NOT EXISTS ${this.tableName} (
41
+ ORDER BY created_at ASC LIMIT 1`,[e,s]);if(!r||r.length===0)return null;let o=r[0];await t.raw(`UPDATE ${this.table} SET reserved_at = ?, attempts = attempts + 1 WHERE id = ?`,[s,o.id]);let n=JSON.parse(o.payload),i=this.registry.resolve(n.jobClass,n.payload);return{id:o.id,jobClass:n.jobClass,payload:n.payload,queue:o.queue,attempts:o.attempts+1,maxAttempts:o.max_attempts,availableAt:o.available_at*1e3,createdAt:o.created_at*1e3,job:i}}async size(e="default"){return(await(await this.getConnection()).raw(`SELECT COUNT(*) as count FROM ${this.table} WHERE queue = ? AND reserved_at IS NULL`,[e]))?.[0]?.count??0}async clear(e){let t=await this.getConnection();e?await t.raw(`DELETE FROM ${this.table} WHERE queue = ?`,[e]):await t.raw(`DELETE FROM ${this.table}`,[])}async delete(e){await(await this.getConnection()).raw(`DELETE FROM ${this.table} WHERE id = ?`,[e])}async release(e,t=0){let s=await this.getConnection(),r=Math.floor(Date.now()/1e3)+t;await s.raw(`UPDATE ${this.table} SET reserved_at = NULL, available_at = ? WHERE id = ?`,[r,e])}},Vt=class{queues=new Map;config;registry;_bullmq=null;constructor(e,t){this.config=e,this.registry=t}async getBullMQ(){if(this._bullmq)return this._bullmq;try{return this._bullmq=await Function('return import("bullmq")')(),this._bullmq}catch{throw new Error("bullmq is required for the Redis queue driver. Install it with: npm install bullmq")}}getRedisConnection(){if(this.config.url){let e=new URL(this.config.url);return{host:e.hostname||"localhost",port:parseInt(e.port)||6379,password:e.password||this.config.password||void 0,db:parseInt(e.pathname?.slice(1)||"0")||this.config.db||0}}return{host:this.config.host??"localhost",port:this.config.port??6379,password:this.config.password,db:this.config.db??0}}async getQueue(e){if(this.queues.has(e))return this.queues.get(e);let t=await this.getBullMQ(),s=this.getRedisConnection(),r=this.config.prefix??"svelar",o=new t.Queue(e,{connection:s,prefix:r,defaultJobOptions:{removeOnComplete:this.config.defaultJobOptions?.removeOnComplete??100,removeOnFail:this.config.defaultJobOptions?.removeOnFail??500}});return this.queues.set(e,o),o}async push(e){let t=await this.getQueue(e.queue),s=Math.max(0,e.availableAt-Date.now());await t.add(e.jobClass,{jobClass:e.jobClass,payload:e.payload},{jobId:e.id,delay:s>0?s:void 0,attempts:e.maxAttempts,backoff:{type:"fixed",delay:(e.job.retryDelay??60)*1e3}})}async pop(e){return null}async size(e="default"){let s=await(await this.getQueue(e)).getJobCounts("waiting","delayed","active");return s.waiting+s.delayed+s.active}async clear(e){if(e)await(await this.getQueue(e)).obliterate({force:!0});else for(let t of this.queues.values())await t.obliterate({force:!0})}async createWorker(e,t,s,r){let o=await this.getBullMQ(),n=this.getRedisConnection(),i=this.config.prefix??"svelar",a=new o.Worker(e,async c=>{let u=c.data,p=t.resolve(u.jobClass,u.payload);p.attempts=c.attemptsMade+1,await p.handle()},{connection:n,prefix:i,concurrency:r?.concurrency??1});return a.on("failed",async(c,u)=>{let p=c?.data;if(p)try{let h=t.resolve(p.jobClass,p.payload);c.attemptsMade>=(c.opts?.attempts??3)&&(h.failed(u),await s.store({id:c.id,jobClass:p.jobClass,payload:p.payload,queue:e,attempts:c.attemptsMade,maxAttempts:c.opts?.attempts??3,availableAt:Date.now(),createdAt:c.timestamp??Date.now(),job:h},u))}catch{console.error("[Queue] Failed to resolve job for failure handler:",u.message)}}),a}},Qs=class{table="svelar_failed_jobs";async getConnection(){let{Connection:e}=await Promise.resolve().then(()=>(S(),P));return e}async store(e,t){try{await(await this.getConnection()).raw(`INSERT INTO ${this.table} (id, queue, job_class, payload, exception, failed_at)
42
+ VALUES (?, ?, ?, ?, ?, ?)`,[crypto.randomUUID(),e.queue,e.jobClass,e.payload,t.stack??t.message,Math.floor(Date.now()/1e3)])}catch{console.error("[Queue] Could not persist failed job (run migration to create svelar_failed_jobs table)")}}async all(){return(await(await this.getConnection()).raw(`SELECT * FROM ${this.table} ORDER BY failed_at DESC`,[])??[]).map(s=>({id:s.id,queue:s.queue,jobClass:s.job_class,payload:s.payload,exception:s.exception,failedAt:s.failed_at}))}async find(e){let s=await(await this.getConnection()).raw(`SELECT * FROM ${this.table} WHERE id = ? LIMIT 1`,[e]);if(!s||s.length===0)return null;let r=s[0];return{id:r.id,queue:r.queue,jobClass:r.job_class,payload:r.payload,exception:r.exception,failedAt:r.failed_at}}async forget(e){return await(await this.getConnection()).raw(`DELETE FROM ${this.table} WHERE id = ?`,[e]),!0}async flush(){let e=await this.getConnection(),s=(await e.raw(`SELECT COUNT(*) as count FROM ${this.table}`,[]))?.[0]?.count??0;return await e.raw(`DELETE FROM ${this.table}`,[]),s}},Zs=class{jobs=new Map;register(e){this.jobs.set(e.name,e)}registerAll(e){for(let t of e)this.register(t)}resolve(e,t){let s=this.jobs.get(e);if(!s)throw new Error(`Job class "${e}" is not registered. Call Queue.register(${e}) in your app bootstrap. Registered jobs: [${[...this.jobs.keys()].join(", ")}]`);let r=Object.create(s.prototype);r.attempts=0,r.maxAttempts=3,r.retryDelay=60,r.queue="default";try{let o=JSON.parse(t);r.restore(o)}catch{}return r}has(e){return this.jobs.has(e)}},Xs=class{config={default:"sync",connections:{sync:{driver:"sync"}}};drivers=new Map;processing=!1;jobRegistry=new Zs;failedStore=new Qs;_activeWorker=null;configure(e){this.config=e,this.drivers.clear()}register(e){this.jobRegistry.register(e)}registerAll(e){this.jobRegistry.registerAll(e)}async dispatch(e,t){let s=this.config.default,r=this.config.connections[s],o=this.resolveDriver(s);t?.queue&&(e.queue=t.queue),t?.maxAttempts!==void 0&&(e.maxAttempts=t.maxAttempts);let n={id:crypto.randomUUID(),jobClass:e.constructor.name,payload:e.serialize(),queue:e.queue??r?.queue??"default",attempts:0,maxAttempts:e.maxAttempts,availableAt:Date.now()+(t?.delay??0)*1e3,createdAt:Date.now(),job:e};await o.push(n)}async dispatchSync(e){let t=new Jt,s={id:crypto.randomUUID(),jobClass:e.constructor.name,payload:e.serialize(),queue:e.queue,attempts:0,maxAttempts:e.maxAttempts,availableAt:Date.now(),createdAt:Date.now(),job:e};await t.push(s)}async chain(e,t){if(e.length===0)return;let s=new er(e);t?.queue&&(s.queue=t.queue),t?.maxAttempts!==void 0&&(s.maxAttempts=t.maxAttempts),await this.dispatch(s,t)}async work(e){let t=this.config.default,s=this.resolveDriver(t),r=e?.queue??"default";if(s instanceof Vt){let a=await s.createWorker(r,this.jobRegistry,this.failedStore,{concurrency:e?.concurrency??1});return this.processing=!0,this._activeWorker=a,await new Promise(c=>{let u=()=>{this.processing?setTimeout(u,500):a.close().then(c).catch(c)};u()}),0}let o=e?.maxJobs??1/0,n=(e?.sleep??1)*1e3,i=0;for(this.processing=!0;this.processing&&i<o;){let a=await s.pop(r);if(!a){if(o===1/0){await new Promise(c=>setTimeout(c,n));continue}break}a.attempts++,a.job.attempts=a.attempts;try{await a.job.handle(),i++,s instanceof ae&&await s.delete(a.id)}catch(c){if(a.attempts<a.maxAttempts){a.job.retrying(a.attempts);let u=a.job.retryDelay??60;s instanceof ae?await s.release(a.id,u):(a.availableAt=Date.now()+u*1e3,await s.push(a))}else a.job.failed(c),await this.failedStore.store(a,c),s instanceof ae&&await s.delete(a.id)}}return i}async stop(){this.processing=!1,this._activeWorker&&(await this._activeWorker.close(),this._activeWorker=null)}async size(e){return this.resolveDriver(this.config.default).size(e)}async clear(e){return this.resolveDriver(this.config.default).clear(e)}async failed(){return this.failedStore.all()}async retry(e){let t=await this.failedStore.find(e);if(!t)return!1;let s=this.jobRegistry.resolve(t.jobClass,t.payload);return s.queue=t.queue,await this.dispatch(s,{queue:t.queue}),await this.failedStore.forget(e),!0}async retryAll(){let e=await this.failedStore.all(),t=0;for(let s of e)try{let r=this.jobRegistry.resolve(s.jobClass,s.payload);r.queue=s.queue,await this.dispatch(r,{queue:s.queue}),await this.failedStore.forget(s.id),t++}catch{}return t}async forgetFailed(e){return this.failedStore.forget(e)}async flushFailed(){return this.failedStore.flush()}resolveDriver(e){if(this.drivers.has(e))return this.drivers.get(e);let t=this.config.connections[e];if(!t)throw new Error(`Queue connection "${e}" is not defined.`);let s;switch(t.driver){case"sync":s=new Jt;break;case"memory":s=new Gs;break;case"database":s=new ae(t.table??"svelar_jobs",this.jobRegistry);break;case"redis":s=new Vt(t,this.jobRegistry);break;default:throw new Error(`Unknown queue driver: ${t.driver}`)}return this.drivers.set(e,s),s}},er=class extends le{remainingJobs;constructor(e){super(),this.remainingJobs=[...e],this.maxAttempts=1}async handle(){for(let e of this.remainingJobs){let t=null,s=!1;for(let r=1;r<=e.maxAttempts;r++){e.attempts=r;try{await e.handle(),s=!0;break}catch(o){t=o,r<e.maxAttempts&&(e.retrying(r),e.retryDelay>0&&await new Promise(n=>setTimeout(n,e.retryDelay*1e3)))}}if(!s&&t)throw e.failed(t),new Error(`Chain stopped: ${e.constructor.name} failed after ${e.maxAttempts} attempt(s). Remaining jobs: [${this.remainingJobs.slice(this.remainingJobs.indexOf(e)+1).map(r=>r.constructor.name).join(", ")}]`)}}serialize(){return JSON.stringify({jobs:this.remainingJobs.map(e=>({jobClass:e.constructor.name,payload:e.serialize()}))})}},tr=x("svelar.queue",()=>new Xs)});var F,sr=w(()=>{"use strict";S();F=class l{tableName;selectColumns=["*"];whereClauses=[];joinClauses=[];orderClauses=[];groupByColumns=[];havingClauses=[];limitValue=null;offsetValue=null;eagerLoads=[];isDistinct=!1;connectionName;cteClauses=[];unionClauses=[];modelClass;constructor(e,t,s){this.tableName=e,this.modelClass=t,this.connectionName=s}select(...e){return this.selectColumns=e.length>0?e:["*"],this}addSelect(...e){return this.selectColumns[0]==="*"?this.selectColumns=e:this.selectColumns.push(...e),this}distinct(){return this.isDistinct=!0,this}from(e){return this.tableName=e,this}where(e,t,s){return s===void 0?this.whereClauses.push({type:"basic",column:e,operator:"=",value:t,boolean:"AND"}):this.whereClauses.push({type:"basic",column:e,operator:t,value:s,boolean:"AND"}),this}orWhere(e,t,s){return s===void 0?this.whereClauses.push({type:"basic",column:e,operator:"=",value:t,boolean:"OR"}):this.whereClauses.push({type:"basic",column:e,operator:t,value:s,boolean:"OR"}),this}whereIn(e,t){return this.whereClauses.push({type:"in",column:e,values:t,boolean:"AND"}),this}whereNotIn(e,t){return this.whereClauses.push({type:"notIn",column:e,values:t,boolean:"AND"}),this}whereNull(e){return this.whereClauses.push({type:"null",column:e,boolean:"AND"}),this}whereNotNull(e){return this.whereClauses.push({type:"notNull",column:e,boolean:"AND"}),this}whereBetween(e,t){return this.whereClauses.push({type:"between",column:e,values:t,boolean:"AND"}),this}whereRaw(e,t=[]){return this.whereClauses.push({type:"raw",raw:e,values:t,boolean:"AND"}),this}whereNested(e,t="AND"){let s=new l(this.tableName,this.modelClass,this.connectionName);if(e(s),s.whereClauses.length>0){let{whereSQL:r,whereBindings:o}=s.buildWhere(),n=r.replace(/^WHERE /,"");this.whereClauses.push({type:"raw",raw:`(${n})`,values:o,boolean:t})}return this}orWhereNested(e){return this.whereNested(e,"OR")}whereExists(e){let t=new l("__placeholder__",void 0,this.connectionName);e(t);let{sql:s,bindings:r}=t.toSQL();return this.whereClauses.push({type:"exists",subSQL:s,subBindings:r,boolean:"AND"}),this}whereNotExists(e){let t=new l("__placeholder__",void 0,this.connectionName);e(t);let{sql:s,bindings:r}=t.toSQL();return this.whereClauses.push({type:"notExists",subSQL:s,subBindings:r,boolean:"AND"}),this}whereSub(e,t,s){let r=new l("__placeholder__",void 0,this.connectionName);s(r);let{sql:o,bindings:n}=r.toSQL();return this.whereClauses.push({type:"sub",column:e,operator:t,subSQL:o,subBindings:n,boolean:"AND"}),this}orWhereRaw(e,t=[]){return this.whereClauses.push({type:"raw",raw:e,values:t,boolean:"OR"}),this}orWhereIn(e,t){return this.whereClauses.push({type:"in",column:e,values:t,boolean:"OR"}),this}orWhereNull(e){return this.whereClauses.push({type:"null",column:e,boolean:"OR"}),this}orWhereNotNull(e){return this.whereClauses.push({type:"notNull",column:e,boolean:"OR"}),this}withCTE(e,t,s=!1){let r=new l("__placeholder__",void 0,this.connectionName);t(r);let{sql:o,bindings:n}=r.toSQL();return this.cteClauses.push({name:e,sql:o,bindings:n,recursive:s}),this}withRecursiveCTE(e,t){return this.withCTE(e,t,!0)}withRawCTE(e,t,s=[],r=!1){return this.cteClauses.push({name:e,sql:t,bindings:s,recursive:r}),this}union(e){let t=new l("__placeholder__",void 0,this.connectionName);e(t);let{sql:s,bindings:r}=t.toSQL();return this.unionClauses.push({sql:s,bindings:r,all:!1}),this}unionAll(e){let t=new l("__placeholder__",void 0,this.connectionName);e(t);let{sql:s,bindings:r}=t.toSQL();return this.unionClauses.push({sql:s,bindings:r,all:!0}),this}join(e,t,s,r){return this.joinClauses.push({type:"INNER",table:e,first:t,operator:s,second:r}),this}leftJoin(e,t,s,r){return this.joinClauses.push({type:"LEFT",table:e,first:t,operator:s,second:r}),this}rightJoin(e,t,s,r){return this.joinClauses.push({type:"RIGHT",table:e,first:t,operator:s,second:r}),this}crossJoin(e){return this.joinClauses.push({type:"CROSS",table:e,first:"",operator:"",second:""}),this}orderBy(e,t="asc"){return this.orderClauses.push({column:e,direction:t}),this}latest(e="created_at"){return this.orderBy(e,"desc")}oldest(e="created_at"){return this.orderBy(e,"asc")}groupBy(...e){return this.groupByColumns.push(...e),this}having(e,t,s){return this.havingClauses.push({type:"basic",column:e,operator:t,value:s,boolean:"AND"}),this}limit(e){return this.limitValue=e,this}offset(e){return this.offsetValue=e,this}take(e){return this.limit(e)}skip(e){return this.offset(e)}with(...e){return this.eagerLoads.push(...e),this}async get(){let{sql:e,bindings:t}=this.toSQL(),s=await v.raw(e,t,this.connectionName),r=this.hydrateMany(s);return this.eagerLoads.length>0&&this.modelClass&&await this.loadRelations(r),r}async first(){return this.limitValue=1,(await this.get())[0]??null}async firstOrFail(){let e=await this.first();if(!e)throw new Error(`No results found for query on "${this.tableName}".`);return e}async find(e,t="id"){return this.where(t,e).first()}async findOrFail(e,t="id"){return this.where(t,e).firstOrFail()}async count(e="*"){let{sql:t,bindings:s}=this.buildAggregate(`COUNT(${e})`),r=await v.raw(t,s,this.connectionName);return Number(r[0]?.aggregate??0)}async sum(e){let{sql:t,bindings:s}=this.buildAggregate(`SUM(${e})`),r=await v.raw(t,s,this.connectionName);return Number(r[0]?.aggregate??0)}async avg(e){let{sql:t,bindings:s}=this.buildAggregate(`AVG(${e})`),r=await v.raw(t,s,this.connectionName);return Number(r[0]?.aggregate??0)}async max(e){let{sql:t,bindings:s}=this.buildAggregate(`MAX(${e})`);return(await v.raw(t,s,this.connectionName))[0]?.aggregate??null}async min(e){let{sql:t,bindings:s}=this.buildAggregate(`MIN(${e})`);return(await v.raw(t,s,this.connectionName))[0]?.aggregate??null}async exists(){return await this.count()>0}async doesntExist(){return!await this.exists()}async pluck(e){return this.selectColumns=[e],(await v.raw(this.toSQL().sql,this.toSQL().bindings,this.connectionName)).map(s=>s[e])}async value(e){return this.selectColumns=[e],this.limitValue=1,(await v.raw(this.toSQL().sql,this.toSQL().bindings,this.connectionName))[0]?.[e]??null}async chunk(e,t){let s=1,r=!0;for(;r;){let o=this.clone();o.limitValue=e,o.offsetValue=(s-1)*e;let n=await o.get();if(n.length===0||await t(n,s)===!1||n.length<e)break;s++}}when(e,t){return e&&t(this),this}selectRaw(e){return this.selectColumns[0]==="*"?this.selectColumns=[e]:this.selectColumns.push(e),this}async upsert(e,t,s){let r=v.getDriver(this.connectionName),o=Object.keys(e),n=Object.values(e),i=n.map(()=>"?").join(", "),a=s??o.filter(u=>!t.includes(u)),c;if(r==="postgres"){let u=a.map(p=>`${p} = EXCLUDED.${p}`).join(", ");c=`INSERT INTO ${this.tableName} (${o.join(", ")}) VALUES (${i}) ON CONFLICT (${t.join(", ")}) DO UPDATE SET ${u}`}else if(r==="mysql"){let u=a.map(p=>`${p} = VALUES(${p})`).join(", ");c=`INSERT INTO ${this.tableName} (${o.join(", ")}) VALUES (${i}) ON DUPLICATE KEY UPDATE ${u}`}else{let u=a.map(p=>`${p} = excluded.${p}`).join(", ");c=`INSERT INTO ${this.tableName} (${o.join(", ")}) VALUES (${i}) ON CONFLICT (${t.join(", ")}) DO UPDATE SET ${u}`}return v.raw(c,n,this.connectionName)}async insertMany(e){if(e.length===0)return;let t=Object.keys(e[0]),s=[],r=[];for(let n of e){let i=t.map(a=>n[a]);s.push(...i),r.push(`(${i.map(()=>"?").join(", ")})`)}let o=`INSERT INTO ${this.tableName} (${t.join(", ")}) VALUES ${r.join(", ")}`;return v.raw(o,s,this.connectionName)}async firstOrCreate(e,t={}){for(let[n,i]of Object.entries(e))this.where(n,i);let s=await this.first();if(s)return s;let r={...e,...t},o=await new l(this.tableName,this.modelClass,this.connectionName).insertGetId(r);return new l(this.tableName,this.modelClass,this.connectionName).findOrFail(o)}async updateOrCreate(e,t){let s=new l(this.tableName,this.modelClass,this.connectionName);for(let[i,a]of Object.entries(e))s.where(i,a);let r=await s.first();if(r)return await new l(this.tableName,this.modelClass,this.connectionName).where(this.modelClass?.primaryKey??"id",r[this.modelClass?.primaryKey??"id"]).update(t),new l(this.tableName,this.modelClass,this.connectionName).findOrFail(r[this.modelClass?.primaryKey??"id"]);let o={...e,...t},n=await new l(this.tableName,this.modelClass,this.connectionName).insertGetId(o);return new l(this.tableName,this.modelClass,this.connectionName).findOrFail(n)}whereColumn(e,t,s){return s===void 0?this.whereClauses.push({type:"raw",raw:`${e} = ${t}`,values:[],boolean:"AND"}):this.whereClauses.push({type:"raw",raw:`${e} ${t} ${s}`,values:[],boolean:"AND"}),this}havingRaw(e,t=[]){return this.havingClauses.push({type:"raw",raw:e,values:t,boolean:"AND"}),this}orderByRaw(e){return this.orderClauses.push({column:e,direction:"asc"}),this.orderClauses[this.orderClauses.length-1].__raw=!0,this}selectSub(e,t){let s=new l("__placeholder__",void 0,this.connectionName);e(s);let{sql:r,bindings:o}=s.toSQL(),n=`(${r}) as ${t}`;return this.selectColumns[0]==="*"?this.selectColumns=[n]:this.selectColumns.push(n),this._selectBindings||(this._selectBindings=[]),this._selectBindings.push(...o),this}_selectBindings;async truncate(){v.getDriver(this.connectionName)==="sqlite"?(await v.raw(`DELETE FROM ${this.tableName}`,[],this.connectionName),await v.raw("DELETE FROM sqlite_sequence WHERE name = ?",[this.tableName],this.connectionName)):await v.raw(`TRUNCATE TABLE ${this.tableName}`,[],this.connectionName)}async paginate(e=1,t=15){let s=await this.clone().count(),r=Math.ceil(s/t);return this.limitValue=t,this.offsetValue=(e-1)*t,{data:await this.get(),total:s,page:e,perPage:t,lastPage:r,hasMore:e<r}}async insert(e){let t=Object.keys(e),s=Object.values(e),r=s.map(()=>"?").join(", "),o=`INSERT INTO ${this.tableName} (${t.join(", ")}) VALUES (${r})`;return v.raw(o,s,this.connectionName)}async insertGetId(e,t="id"){let s=v.getDriver(this.connectionName),r=Object.keys(e),o=Object.values(e),n=o.map(()=>"?").join(", "),i=`INSERT INTO ${this.tableName} (${r.join(", ")}) VALUES (${n})`;return s==="postgres"?(i+=` RETURNING ${t}`,(await v.raw(i,o,this.connectionName))[0]?.[t]):(await v.raw(i,o,this.connectionName),s==="sqlite"?(await v.raw("SELECT last_insert_rowid() as id",[],this.connectionName))[0]?.id:s==="mysql"?(await v.raw("SELECT LAST_INSERT_ID() as id",[],this.connectionName))[0]?.id:0)}async update(e){let t=Object.keys(e),s=Object.values(e),r=t.map(a=>`${a} = ?`).join(", "),{whereSQL:o,whereBindings:n}=this.buildWhere(),i=`UPDATE ${this.tableName} SET ${r}${o}`;return await v.raw(i,[...s,...n],this.connectionName),1}async delete(){let{whereSQL:e,whereBindings:t}=this.buildWhere(),s=`DELETE FROM ${this.tableName}${e}`;return await v.raw(s,t,this.connectionName),1}async increment(e,t=1){let{whereSQL:s,whereBindings:r}=this.buildWhere(),o=`UPDATE ${this.tableName} SET ${e} = ${e} + ?${s}`;await v.raw(o,[t,...r],this.connectionName)}async decrement(e,t=1){return this.increment(e,-t)}toSQL(){let e=[],t=[];if(this.cteClauses.length>0){let i=this.cteClauses.some(c=>c.recursive)?"WITH RECURSIVE":"WITH",a=this.cteClauses.map(c=>(t.push(...c.bindings),`${c.name} AS (${c.sql})`));e.push(`${i} ${a.join(", ")}`)}this._selectBindings?.length&&t.push(...this._selectBindings);let s=this.isDistinct?"DISTINCT ":"";e.push(`SELECT ${s}${this.selectColumns.join(", ")}`),e.push(`FROM ${this.tableName}`);for(let n of this.joinClauses)n.type==="CROSS"?e.push(`CROSS JOIN ${n.table}`):e.push(`${n.type} JOIN ${n.table} ON ${n.first} ${n.operator} ${n.second}`);let{whereSQL:r,whereBindings:o}=this.buildWhere();if(r&&(e.push(r.trim()),t.push(...o)),this.groupByColumns.length>0&&e.push(`GROUP BY ${this.groupByColumns.join(", ")}`),this.havingClauses.length>0){let n=[];for(let i of this.havingClauses)i.type==="raw"?(n.push(i.raw),i.values&&t.push(...i.values)):(n.push(`${i.column} ${i.operator} ?`),t.push(i.value));e.push(`HAVING ${n.join(" AND ")}`)}if(this.orderClauses.length>0){let n=this.orderClauses.map(i=>i.__raw?i.column:`${i.column} ${i.direction.toUpperCase()}`);e.push(`ORDER BY ${n.join(", ")}`)}if(this.limitValue!==null&&e.push(`LIMIT ${this.limitValue}`),this.offsetValue!==null&&e.push(`OFFSET ${this.offsetValue}`),this.unionClauses.length>0)for(let n of this.unionClauses)e.push(n.all?"UNION ALL":"UNION"),e.push(n.sql),t.push(...n.bindings);return{sql:e.join(" "),bindings:t}}clone(){let e=new l(this.tableName,this.modelClass,this.connectionName);return e.selectColumns=[...this.selectColumns],e.whereClauses=[...this.whereClauses],e.joinClauses=[...this.joinClauses],e.orderClauses=[...this.orderClauses],e.groupByColumns=[...this.groupByColumns],e.havingClauses=[...this.havingClauses],e.limitValue=this.limitValue,e.offsetValue=this.offsetValue,e.eagerLoads=[...this.eagerLoads],e.isDistinct=this.isDistinct,e.cteClauses=[...this.cteClauses],e.unionClauses=[...this.unionClauses],e}buildWhere(){if(this.whereClauses.length===0)return{whereSQL:"",whereBindings:[]};let e=[],t=[];for(let s=0;s<this.whereClauses.length;s++){let r=this.whereClauses[s],o=s===0?"WHERE":r.boolean;switch(r.type){case"basic":if((r.operator==="IS"||r.operator==="IS NOT")&&r.value===null){let a=(r.operator==="IS","null");e.push(`${o} ${r.column} ${r.operator} ${a}`)}else e.push(`${o} ${r.column} ${r.operator} ?`),t.push(r.value);break;case"in":let n=r.values.map(()=>"?").join(", ");e.push(`${o} ${r.column} IN (${n})`),t.push(...r.values);break;case"notIn":let i=r.values.map(()=>"?").join(", ");e.push(`${o} ${r.column} NOT IN (${i})`),t.push(...r.values);break;case"null":e.push(`${o} ${r.column} IS NULL`);break;case"notNull":e.push(`${o} ${r.column} IS NOT NULL`);break;case"between":e.push(`${o} ${r.column} BETWEEN ? AND ?`),t.push(r.values[0],r.values[1]);break;case"raw":e.push(`${o} ${r.raw}`),r.values&&t.push(...r.values);break;case"exists":e.push(`${o} EXISTS (${r.subSQL})`),r.subBindings&&t.push(...r.subBindings);break;case"notExists":e.push(`${o} NOT EXISTS (${r.subSQL})`),r.subBindings&&t.push(...r.subBindings);break;case"sub":e.push(`${o} ${r.column} ${r.operator} (${r.subSQL})`),r.subBindings&&t.push(...r.subBindings);break}}return{whereSQL:e.join(" "),whereBindings:t}}buildAggregate(e){let t=this.selectColumns;this.selectColumns=[`${e} as aggregate`];let s=this.toSQL();return this.selectColumns=t,s}hydrateMany(e){return this.modelClass?e.map(t=>this.modelClass.hydrate(t)):e}async loadRelations(e){if(!(!this.modelClass||e.length===0))for(let t of this.eagerLoads){let r=new this.modelClass()[t]?.();r&&typeof r.eagerLoad=="function"&&await r.eagerLoad(e,t)}}}});var de,ue,me,pe,he,rr=w(()=>{"use strict";S();de=class{parentModel;relatedModel;constructor(e,t){this.parentModel=e,this.relatedModel=t}query(){return this.relatedModel.query()}},ue=class extends de{constructor(t,s,r,o="id"){super(t,s);this.foreignKey=r;this.localKey=o}async load(t){let s=t.getAttribute(this.localKey);return this.relatedModel.query().where(this.foreignKey,s).first()}async eagerLoad(t,s){let r=t.map(i=>i.getAttribute(this.localKey)),o=await this.relatedModel.query().whereIn(this.foreignKey,r).get(),n=new Map;for(let i of o)n.set(i.getAttribute(this.foreignKey),i);for(let i of t){let a=i.getAttribute(this.localKey);i.setRelation(s,n.get(a)??null)}}async create(t){let s=this.parentModel.getAttribute(this.localKey);return this.relatedModel.create({...t,[this.foreignKey]:s})}},me=class extends de{constructor(t,s,r,o="id"){super(t,s);this.foreignKey=r;this.localKey=o}async load(t){let s=t.getAttribute(this.localKey);return this.relatedModel.query().where(this.foreignKey,s).get()}async eagerLoad(t,s){let r=t.map(i=>i.getAttribute(this.localKey)),o=await this.relatedModel.query().whereIn(this.foreignKey,r).get(),n=new Map;for(let i of o){let a=i.getAttribute(this.foreignKey);n.has(a)||n.set(a,[]),n.get(a).push(i)}for(let i of t){let a=i.getAttribute(this.localKey);i.setRelation(s,n.get(a)??[])}}async create(t){let s=this.parentModel.getAttribute(this.localKey);return this.relatedModel.create({...t,[this.foreignKey]:s})}async createMany(t){let s=[];for(let r of t)s.push(await this.create(r));return s}},pe=class extends de{constructor(t,s,r,o="id"){super(t,s);this.foreignKey=r;this.ownerKey=o}async load(t){let s=t.getAttribute(this.foreignKey);return s==null?null:this.relatedModel.query().where(this.ownerKey,s).first()}async eagerLoad(t,s){let r=t.map(i=>i.getAttribute(this.foreignKey)).filter(i=>i!=null);if(r.length===0){for(let i of t)i.setRelation(s,null);return}let o=await this.relatedModel.query().whereIn(this.ownerKey,r).get(),n=new Map;for(let i of o)n.set(i.getAttribute(this.ownerKey),i);for(let i of t){let a=i.getAttribute(this.foreignKey);i.setRelation(s,n.get(a)??null)}}associate(t){return this.parentModel.setAttribute(this.foreignKey,t.getAttribute(this.ownerKey)),this.parentModel}dissociate(){return this.parentModel.setAttribute(this.foreignKey,null),this.parentModel}},he=class extends de{constructor(t,s,r,o,n,i="id",a="id"){super(t,s);this.pivotTable=r;this.foreignPivotKey=o;this.relatedPivotKey=n;this.parentKey=i;this.relatedKey=a}async load(t){let s=t.getAttribute(this.parentKey),r=this.relatedModel.tableName,n=(await v.raw(`SELECT ${this.relatedPivotKey} FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ?`,[s])).map(i=>i[this.relatedPivotKey]);return n.length===0?[]:this.relatedModel.query().whereIn(this.relatedKey,n).get()}async eagerLoad(t,s){let r=t.map(p=>p.getAttribute(this.parentKey));if(r.length===0){for(let p of t)p.setRelation(s,[]);return}let o=r.map(()=>"?").join(", "),n=await v.raw(`SELECT * FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} IN (${o})`,r),i=[...new Set(n.map(p=>p[this.relatedPivotKey]))],a=i.length>0?await this.relatedModel.query().whereIn(this.relatedKey,i).get():[],c=new Map;for(let p of a)c.set(p.getAttribute(this.relatedKey),p);let u=new Map;for(let p of n){let h=p[this.foreignPivotKey],m=p[this.relatedPivotKey],f=c.get(m);f&&(u.has(h)||u.set(h,[]),u.get(h).push(f))}for(let p of t){let h=p.getAttribute(this.parentKey);p.setRelation(s,u.get(h)??[])}}async attach(t,s){let r=this.parentModel.getAttribute(this.parentKey),o={[this.foreignPivotKey]:r,[this.relatedPivotKey]:t,...s},n=Object.keys(o),i=Object.values(o),a=i.map(()=>"?").join(", ");await v.raw(`INSERT INTO ${this.pivotTable} (${n.join(", ")}) VALUES (${a})`,i)}async detach(t){let s=this.parentModel.getAttribute(this.parentKey);t?await v.raw(`DELETE FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ? AND ${this.relatedPivotKey} = ?`,[s,t]):await v.raw(`DELETE FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ?`,[s])}async sync(t){await this.detach();for(let s of t)await this.attach(s)}async toggle(t){let s=this.parentModel.getAttribute(this.parentKey);for(let r of t)(await v.raw(`SELECT 1 FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ? AND ${this.relatedPivotKey} = ? LIMIT 1`,[s,r])).length>0?await this.detach(r):await this.attach(r)}}});var Li=w(()=>{"use strict"});var Ue,ir=w(()=>{"use strict";Ue=class{app;constructor(e){this.app=e}boot(){}}});var Mi=w(()=>{"use strict";ir();Xt()});var qe,ge,Xt=w(()=>{"use strict";A();Li();Mi();qe=class{listeners=new Map;wildcardListeners=[];onceListeners=new Map;listen(e,t){let s=typeof e=="string"?e:e.name;return this.listeners.has(s)||this.listeners.set(s,[]),this.listeners.get(s).push(t),()=>{let r=this.listeners.get(s);if(r){let o=r.indexOf(t);o>=0&&r.splice(o,1)}}}once(e,t){let s=typeof e=="string"?e:e.name;return this.onceListeners.has(s)||this.onceListeners.set(s,[]),this.onceListeners.get(s).push(t),()=>{let r=this.onceListeners.get(s);if(r){let o=r.indexOf(t);o>=0&&r.splice(o,1)}}}onAny(e){return this.wildcardListeners.push(e),()=>{let t=this.wildcardListeners.indexOf(e);t>=0&&this.wildcardListeners.splice(t,1)}}async dispatch(e){let t=e.constructor.name,s=this.listeners.get(t)??[];for(let o of s)await o(e);let r=this.onceListeners.get(t)??[];for(let o of r)await o(e);this.onceListeners.delete(t);for(let o of this.wildcardListeners)await o(t,e)}async emit(e,t){let s=this.listeners.get(e)??[];for(let o of s)await o(t);let r=this.onceListeners.get(e)??[];for(let o of r)await o(t);this.onceListeners.delete(e);for(let o of this.wildcardListeners)await o(e,t)}subscribe(e){e.subscribe(this)}forget(e){let t=typeof e=="string"?e:e.name;this.listeners.delete(t),this.onceListeners.delete(t)}flush(){this.listeners.clear(),this.onceListeners.clear(),this.wildcardListeners=[]}hasListeners(e){let t=typeof e=="string"?e:e.name;return(this.listeners.get(t)?.length??0)>0||(this.onceListeners.get(t)?.length??0)>0||this.wildcardListeners.length>0}listenerCount(e){let t=typeof e=="string"?e:e.name;return(this.listeners.get(t)?.length??0)+(this.onceListeners.get(t)?.length??0)}},ge=x("svelar.event",()=>new qe)});var es,Oi=w(()=>{"use strict";sr();rr();Xt();es=class l{static table;static primaryKey="id";static incrementing=!0;static timestamps=!0;static createdAt="created_at";static updatedAt="updated_at";static casts={};static fillable=[];static hidden=[];static connection=void 0;static hooks=new Map;static observers=new Map;static events=[];attributes={};originalAttributes={};relations={};exists=!1;constructor(e){return e&&this.fill(e),new Proxy(this,{get(t,s,r){return typeof s=="symbol"||s in t||typeof s!="string"||["table","primaryKey","incrementing","timestamps","casts","fillable","hidden","connection"].includes(s)?Reflect.get(t,s,r):typeof t[s]=="function"?t[s].bind(t):t.getAttribute(s)},set(t,s,r){return typeof s=="symbol"||s in t?Reflect.set(t,s,r):(t.setAttribute(s,r),!0)}})}static query(){let e=new this,t=this;return new F(t.table,this,t.connection)}static async find(e){let t=this;return this.query().find(e,t.primaryKey)}static async findOrFail(e){let t=this;return this.query().findOrFail(e,t.primaryKey)}static async all(){return this.query().get()}static async first(){return this.query().first()}static async firstOrFail(){return this.query().firstOrFail()}static where(e,t,s){return this.query().where(e,t,s)}static whereIn(e,t){return this.query().whereIn(e,t)}static whereNull(e){return this.query().whereNull(e)}static whereNotNull(e){return this.query().whereNotNull(e)}static orderBy(e,t){return this.query().orderBy(e,t)}static latest(e){return this.query().latest(e)}static oldest(e){return this.query().oldest(e)}static with(...e){return this.query().with(...e)}static async count(){return this.query().count()}static async create(e){let t=new this,s=this;if(t.fill(e),await t.fireHook("creating"),await t.fireHook("saving"),s.timestamps){let i=new Date().toISOString();t.setAttribute(s.createdAt,i),t.setAttribute(s.updatedAt,i)}let r=t.getInsertableAttributes(),n=await new F(s.table,this,s.connection).insertGetId(r,s.primaryKey);return s.incrementing&&n&&t.setAttribute(s.primaryKey,n),t.syncOriginal(),t.exists=!0,await t.fireHook("created"),await t.fireHook("saved"),t}async save(){let e=this.constructor;if(this.exists){await this.fireHook("updating"),await this.fireHook("saving"),e.timestamps&&this.setAttribute(e.updatedAt,new Date().toISOString());let t=this.getDirty();if(Object.keys(t).length>0){let s=this.getAttribute(e.primaryKey);await new F(e.table,this.constructor,e.connection).where(e.primaryKey,s).update(t)}this.syncOriginal(),await this.fireHook("updated"),await this.fireHook("saved")}else{if(await this.fireHook("creating"),await this.fireHook("saving"),e.timestamps){let o=new Date().toISOString();this.getAttribute(e.createdAt)||this.setAttribute(e.createdAt,o),this.setAttribute(e.updatedAt,o)}let t=this.getInsertableAttributes(),r=await new F(e.table,this.constructor,e.connection).insertGetId(t,e.primaryKey);e.incrementing&&r&&this.setAttribute(e.primaryKey,r),this.syncOriginal(),this.exists=!0,await this.fireHook("created"),await this.fireHook("saved")}}async update(e){this.fill(e),await this.save()}async delete(){let e=this.constructor;await this.fireHook("deleting");let t=this.getAttribute(e.primaryKey);await new F(e.table,this.constructor,e.connection).where(e.primaryKey,t).delete(),this.exists=!1,await this.fireHook("deleted")}async refresh(){let e=this.constructor,t=this.getAttribute(e.primaryKey),s=await this.constructor.find(t);s&&(this.attributes={...s.attributes},this.syncOriginal())}getAttribute(e){let t=this.constructor,s=this.attributes[e],r=t.casts[e];if(r&&s!==void 0&&s!==null)switch(r){case"number":return Number(s);case"boolean":return!!s;case"string":return String(s);case"date":return new Date(s);case"json":return typeof s=="string"?JSON.parse(s):s}return s}setAttribute(e,t){this.constructor.casts[e]==="json"&&typeof t!="string"?this.attributes[e]=JSON.stringify(t):this.attributes[e]=t}fill(e){let t=this.constructor;for(let[s,r]of Object.entries(e))t.fillable.length>0&&!t.fillable.includes(s)||this.setAttribute(s,r)}getAttributes(){return{...this.attributes}}getOriginal(e){return e?this.originalAttributes[e]:{...this.originalAttributes}}getDirty(){let e={};for(let[t,s]of Object.entries(this.attributes))s!==this.originalAttributes[t]&&(e[t]=s);return e}isDirty(...e){let t=this.getDirty();return e.length===0?Object.keys(t).length>0:e.some(s=>s in t)}isClean(...e){return!this.isDirty(...e)}wasChanged(...e){return this.isDirty(...e)}hasOne(e,t,s){return new ue(this,e,t,s??this.constructor.primaryKey)}hasMany(e,t,s){return new me(this,e,t,s??this.constructor.primaryKey)}belongsTo(e,t,s){return new pe(this,e,t,s??e.primaryKey)}belongsToMany(e,t,s,r,o,n){return new he(this,e,t,s,r,o??this.constructor.primaryKey,n??e.primaryKey)}setRelation(e,t){this.relations[e]=t}getRelation(e){return this.relations[e]}relationLoaded(e){return e in this.relations}toJSON(){let e=this.constructor,t={};for(let[s,r]of Object.entries(this.attributes))e.hidden.includes(s)||(t[s]=this.getAttribute(s));for(let[s,r]of Object.entries(this.relations))Array.isArray(r)?t[s]=r.map(o=>o instanceof l?o.toJSON():o):r instanceof l?t[s]=r.toJSON():t[s]=r;return t}toObject(){return this.toJSON()}static hydrate(e){let t=new this;return t.attributes={...e},t.syncOriginal(),t.exists=!0,t}static boot(e){this.hooks.set(this.name,e)}static observe(e){let t=this.observers.get(this.name)??[];t.push(e),this.observers.set(this.name,t)}static removeObservers(){this.observers.delete(this.name)}async fireHook(e){let t=this.constructor,s=l.hooks.get(t.name);s?.[e]&&await s[e](this),typeof this[e]=="function"&&await this[e]();let r=l.observers.get(t.name)??[];for(let n of r){let i=n[e];typeof i=="function"&&await i.call(n,this)}let o=t.name.toLowerCase();await ge.emit(`${o}.${e}`,this)}async fireEvent(e){let t=this.constructor;if(!t.events.includes(e))throw new Error(`Event "${e}" is not declared in ${t.name}.events. Add it to: static events = ['${e}', ...];`);let s=l.observers.get(t.name)??[];for(let o of s){let n=o[e];typeof n=="function"&&await n.call(o,this)}let r=t.name.toLowerCase();await ge.emit(`${r}.${e}`,this)}syncOriginal(){this.originalAttributes={...this.attributes}}getInsertableAttributes(){let e=this.constructor,t={...this.attributes};return e.incrementing&&t[e.primaryKey]===void 0&&delete t[e.primaryKey],t}static get tableName(){return this.table}}});var ts,Ii=w(()=>{"use strict";ts=class{async call(e){await new e().run()}}});var Z,Ni,or=w(()=>{"use strict";A();Z=class{bindings=new Map;aliases=new Map;resolved=new Set;bind(e,t){this.bindings.set(e,{factory:t,singleton:!1,tags:[]})}singleton(e,t){this.bindings.set(e,{factory:t,singleton:!0,tags:[]})}instance(e,t){this.bindings.set(e,{factory:()=>t,singleton:!0,instance:t,tags:[]})}alias(e,t){this.aliases.set(e,t)}async make(e){let t=this.resolveAlias(e),s=this.bindings.get(t);if(!s)throw new Error(`No binding found for "${e}" in the container.`);if(s.singleton&&s.instance!==void 0)return s.instance;let r=await s.factory(this);return s.singleton&&(s.instance=r),this.resolved.add(t),r}makeSync(e){let t=this.resolveAlias(e),s=this.bindings.get(t);if(!s)throw new Error(`No binding found for "${e}" in the container.`);if(s.singleton&&s.instance!==void 0)return s.instance;let r=s.factory(this);if(r instanceof Promise)throw new Error(`Binding "${e}" has an async factory. Use container.make() instead of container.makeSync().`);return s.singleton&&(s.instance=r),this.resolved.add(t),r}has(e){let t=this.resolveAlias(e);return this.bindings.has(t)}isResolved(e){return this.resolved.has(this.resolveAlias(e))}tag(e,t){for(let s of e){let r=this.bindings.get(s);r&&r.tags.push(t)}}async tagged(e){let t=[];for(let[s,r]of this.bindings)r.tags.includes(e)&&t.push(await this.make(s));return t}flush(){for(let e of this.bindings.values())e.singleton&&(e.instance=void 0);this.resolved.clear()}forget(e){this.bindings.delete(e),this.resolved.delete(e)}getBindings(){return[...this.bindings.keys()]}resolveAlias(e){return this.aliases.get(e)??e}},Ni=x("svelar.container",()=>new Z)});var ss,ji=w(()=>{"use strict";or();ss=class{container;providers=[];booted=!1;constructor(e){this.container=e??new Z,this.container.instance("app",this),this.container.instance("container",this.container)}register(e){let t=new e(this.container);return this.providers.push(t),this}async bootstrap(){if(this.booted)return this;for(let e of this.providers)await e.register();for(let e of this.providers)await e.boot();return this.booted=!0,this}isBooted(){return this.booted}async make(e){return this.container.make(e)}getProviders(){return[...this.providers]}}});var _,V,rs,fe,is,ve,be,os,ye,we=w(()=>{"use strict";_=class{},V=class{middleware=[];namedMiddleware=new Map;use(e){return typeof e=="function"&&"prototype"in e&&typeof e.prototype?.handle=="function"?this.middleware.push(new e):this.middleware.push(e),this}register(e,t){return typeof t=="function"&&"prototype"in t&&typeof t.prototype?.handle=="function"?this.namedMiddleware.set(e,new t):this.namedMiddleware.set(e,t),this}get(e){return this.namedMiddleware.get(e)}async execute(e,t,s){let r=[...this.middleware];if(s)for(let n of s){let i=this.namedMiddleware.get(n);i&&r.push(i)}let o=t;for(let n=r.length-1;n>=0;n--){let i=r[n],a=o;typeof i.handle=="function"?o=()=>i.handle(e,a):o=()=>i(e,a)}return o()}count(){return this.middleware.length}},rs=class extends _{constructor(t={}){super();this.options=t}async handle(t,s){let r=await s();if(!r)return;let o=Array.isArray(this.options.origin)?this.options.origin.join(", "):this.options.origin??"*";return r.headers.set("Access-Control-Allow-Origin",o),r.headers.set("Access-Control-Allow-Methods",(this.options.methods??["GET","POST","PUT","DELETE","PATCH","OPTIONS"]).join(", ")),r.headers.set("Access-Control-Allow-Headers",(this.options.headers??["Content-Type","Authorization"]).join(", ")),this.options.credentials&&r.headers.set("Access-Control-Allow-Credentials","true"),this.options.maxAge&&r.headers.set("Access-Control-Max-Age",String(this.options.maxAge)),t.event.request.method==="OPTIONS"?new Response(null,{status:204,headers:r.headers}):r}},fe=class extends _{requests=new Map;maxRequests;windowMs;constructor(e={}){super(),this.maxRequests=e.maxRequests??60,this.windowMs=e.windowMs??6e4}async handle(e,t){let s=e.event.request.headers.get("x-forwarded-for")??e.event.getClientAddress?.()??"unknown",r=Date.now(),o=this.requests.get(s);if(o&&r<o.resetAt){if(o.count>=this.maxRequests)return new Response(JSON.stringify({error:"Too many requests"}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(Math.ceil((o.resetAt-r)/1e3))}});o.count++}else this.requests.set(s,{count:1,resetAt:r+this.windowMs});return t()}},is=class extends _{async handle(e,t){let s=Date.now(),r=e.event.request.method,o=e.event.url.pathname,n=await t(),i=Date.now()-s,a=n instanceof Response?n.status:200;return console.log(`[${new Date().toISOString()}] ${r} ${o} \u2192 ${a} (${i}ms)`),n}},ve=class extends _{cookieName;headerName;fieldName;excludePaths;onlyPaths;constructor(e={}){super(),this.cookieName=e.cookieName??"XSRF-TOKEN",this.headerName=e.headerName??"X-CSRF-Token",this.fieldName=e.fieldName??"_csrf",this.excludePaths=e.excludePaths??[],this.onlyPaths=e.onlyPaths??null}async handle(e,t){let{event:s}=e,r=s.request.method.toUpperCase();if(["GET","HEAD","OPTIONS"].includes(r))return this.setTokenAndContinue(e,t);if((s.request.headers.get("authorization")??"").startsWith("Bearer "))return t();let n=s.url.pathname;if(this.onlyPaths&&!this.onlyPaths.some(c=>n.startsWith(c)))return this.setTokenAndContinue(e,t);if(this.excludePaths.some(c=>n.startsWith(c)))return t();let i=this.getCookieToken(s),a=s.request.headers.get(this.headerName)??await this.getBodyToken(s);return!i||!a||!this.timingSafeEqual(i,a)?new Response(JSON.stringify({message:"CSRF token mismatch"}),{status:419,headers:{"Content-Type":"application/json"}}):t()}async setTokenAndContinue(e,t){let s=await t();if(!(s instanceof Response))return s;let o=this.getCookieToken(e.event)||this.generateToken();return s.headers.append("Set-Cookie",`${this.cookieName}=${o}; Path=/; SameSite=Lax`),s}getCookieToken(e){let s=(e.request.headers.get("cookie")??"").match(new RegExp(`${this.cookieName}=([^;]+)`));return s?s[1]:null}async getBodyToken(e){try{let t=e.request.headers.get("content-type")??"";if(t.includes("application/x-www-form-urlencoded")||t.includes("multipart/form-data"))return(await e.request.clone().formData()).get(this.fieldName);if(t.includes("application/json"))return(await e.request.clone().json())[this.fieldName]??null}catch{}return null}generateToken(){let e=new Uint8Array(32);return crypto.getRandomValues(e),Array.from(e,t=>t.toString(16).padStart(2,"0")).join("")}timingSafeEqual(e,t){if(e.length!==t.length)return!1;let s=new TextEncoder,r=s.encode(e),o=s.encode(t),n=0;for(let i=0;i<r.length;i++)n|=r[i]^o[i];return n===0}},be=class extends _{allowedOrigins;constructor(e={}){super(),this.allowedOrigins=new Set(e.allowedOrigins??[])}async handle(e,t){let{event:s}=e,r=s.request.method.toUpperCase();if(["GET","HEAD","OPTIONS"].includes(r)||(s.request.headers.get("authorization")??"").startsWith("Bearer "))return t();let n=s.request.headers.get("origin");if(!n)return t();let i=s.url.origin;return n===i||this.allowedOrigins.has(n)?t():new Response(JSON.stringify({message:"Cross-origin request blocked"}),{status:403,headers:{"Content-Type":"application/json"}})}},os=class extends _{secret;tolerance;signatureHeader;timestampHeader;onlyPaths;constructor(e){super(),this.secret=e.secret,this.tolerance=e.tolerance??300,this.signatureHeader=e.signatureHeader??"X-Signature",this.timestampHeader=e.timestampHeader??"X-Timestamp",this.onlyPaths=e.onlyPaths??null}async handle(e,t){let{event:s}=e;if(this.onlyPaths){let y=s.url.pathname;if(!this.onlyPaths.some(C=>y.startsWith(C)))return t()}let r=s.request.headers.get(this.signatureHeader),o=s.request.headers.get(this.timestampHeader);if(!r||!o)return new Response(JSON.stringify({message:"Missing request signature"}),{status:401,headers:{"Content-Type":"application/json"}});let n=parseInt(o,10),i=Math.floor(Date.now()/1e3);if(isNaN(n)||Math.abs(i-n)>this.tolerance)return new Response(JSON.stringify({message:"Request signature expired"}),{status:401,headers:{"Content-Type":"application/json"}});let c=await s.request.clone().text(),{createHmac:u}=await import("crypto"),p=s.request.method.toUpperCase(),h=s.url.pathname+s.url.search,m=`${o}.${p}.${h}.${c}`,f=u("sha256",this.secret).update(m).digest("hex");return r.length!==f.length||!this.timingSafeCompare(r,f)?new Response(JSON.stringify({message:"Invalid request signature"}),{status:401,headers:{"Content-Type":"application/json"}}):t()}timingSafeCompare(e,t){if(e.length!==t.length)return!1;let s=new TextEncoder,r=s.encode(e),o=s.encode(t),n=0;for(let i=0;i<r.length;i++)n|=r[i]^o[i];return n===0}static sign(e,t,s,r,o){let{createHmac:n}=tt("crypto"),i=o??Math.floor(Date.now()/1e3),a=`${i}.${t.toUpperCase()}.${s}.${r}`;return{signature:n("sha256",e).update(a).digest("hex"),timestamp:i}}},ye=class extends _{attempts=new Map;maxAttempts;decayMinutes;constructor(e={}){super(),this.maxAttempts=e.maxAttempts??5,this.decayMinutes=e.decayMinutes??1}async handle(e,t){let r=`${e.event.request.headers.get("x-forwarded-for")??e.event.getClientAddress?.()??"unknown"}:${e.event.url.pathname}`,o=Date.now(),n=this.attempts.get(r);if(n){if(o<n.blockedUntil){let a=Math.ceil((n.blockedUntil-o)/1e3);return new Response(JSON.stringify({message:"Too many attempts. Please try again later.",retry_after:a}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(a)}})}if(n.count>=this.maxAttempts){n.blockedUntil=o+this.decayMinutes*6e4,n.count=0;let a=this.decayMinutes*60;return new Response(JSON.stringify({message:"Too many attempts. Please try again later.",retry_after:a}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(a)}})}}let i=await t();if(i instanceof Response&&i.status>=400&&i.status<500){let a=this.attempts.get(r)??{count:0,blockedUntil:0};if(a.count++,this.attempts.set(r,a),this.attempts.size>1e4)for(let[c,u]of this.attempts)o>u.blockedUntil+this.decayMinutes*6e4*2&&this.attempts.delete(c)}return i}}});import{z as Ce}from"zod";function Ui(l,e=!1){let t=new l;return e?{GET:t.handle("show"),PUT:t.handle("update"),PATCH:t.handle("update"),DELETE:t.handle("destroy")}:{GET:t.handle("index"),POST:t.handle("store")}}var ns,Y,Fe,Be,He,qi=w(()=>{"use strict";we();ns=class{controllerMiddleware=[];middleware(e,t){let s;typeof e=="function"&&e.prototype instanceof _?s=new e:s=e,this.controllerMiddleware.push({middleware:s,only:t?.only,except:t?.except})}handle(e){return async t=>{try{let s=this.controllerMiddleware.filter(r=>!(r.only&&!r.only.includes(e)||r.except&&r.except.includes(e)));if(s.length>0){let r=new V;for(let{middleware:i}of s)r.use(i);let o={event:t,params:t.params,locals:t.locals},n=await r.execute(o,async()=>this.callMethod(e,t));if(n instanceof Response)return n}return await this.callMethod(e,t)}catch(s){return this.handleError(s,t)}}}json(e,t=200,s={}){let r=JSON.stringify(e,null,2);return new Response(r,{status:t,headers:{"Content-Type":"application/json",...s}})}text(e,t=200){return new Response(e,{status:t,headers:{"Content-Type":"text/plain"}})}html(e,t=200){return new Response(e,{status:t,headers:{"Content-Type":"text/html"}})}redirect(e,t=302){return new Response(null,{status:t,headers:{Location:e}})}noContent(){return new Response(null,{status:204})}created(e){return e?this.json(e,201):new Response(null,{status:201})}async validate(e,t){let s=t instanceof Ce.ZodObject?t:Ce.object(t),r,o=e.request.headers.get("content-type")??"";if(o.includes("application/json"))r=await e.request.json();else if(o.includes("multipart/form-data")||o.includes("application/x-www-form-urlencoded")){let i=await e.request.formData();r=Object.fromEntries(i)}else r=Object.fromEntries(e.url.searchParams);let n=s.safeParse(r);if(!n.success)throw new Y(n.error);return n.data}validateQuery(e,t){let s=t instanceof Ce.ZodObject?t:Ce.object(t),r=Object.fromEntries(e.url.searchParams),o=s.safeParse(r);if(!o.success)throw new Y(o.error);return o.data}validateParams(e,t){let r=(t instanceof Ce.ZodObject?t:Ce.object(t)).safeParse(e.params);if(!r.success)throw new Y(r.error);return r.data}handleError(e,t){return e instanceof Y?this.json({message:"Validation failed",errors:e.errors},422):e instanceof Fe?this.json({message:e.message||"Not found"},404):e instanceof Be?this.json({message:e.message||"Unauthorized"},401):e instanceof He?this.json({message:e.message||"Forbidden"},403):(console.error("[Svelar] Controller error:",e),this.json({message:process.env.NODE_ENV==="production"?"Internal server error":e.message},500))}async callMethod(e,t){let s=this[e];if(typeof s!="function")throw new Error(`Method "${e}" not found on controller "${this.constructor.name}".`);let r=await s.call(this,t);return r instanceof Response?r:this.json(r)}};Y=class extends Error{errors;constructor(e){super("Validation failed"),this.name="ValidationError",this.errors={};for(let t of e.issues){let s=t.path.join(".");this.errors[s]||(this.errors[s]=[]),this.errors[s].push(t.message)}}},Fe=class extends Error{constructor(e="Not found"){super(e),this.name="NotFoundError"}},Be=class extends Error{constructor(e="Unauthorized"){super(e),this.name="UnauthorizedError"}},He=class extends Error{constructor(e="Forbidden"){super(e),this.name="ForbiddenError"}}});import{randomBytes as Ja,createHmac as Fi,timingSafeEqual as Va}from"crypto";import{promises as G}from"fs";import{join as ze}from"path";var xe,Ke,X,as,ls,cs,Se,nr=w(()=>{"use strict";we();xe=class l{constructor(e,t){this.id=e;t&&(this.data={...t},this.data._flash&&(this.previousFlashData=this.data._flash,delete this.data._flash))}data={};dirty=!1;flashData={};previousFlashData={};get(e,t){return e in this.flashData?this.flashData[e]:e in this.previousFlashData?this.previousFlashData[e]:e in this.data?this.data[e]:t}set(e,t){this.data[e]=t,this.dirty=!0}has(e){return e in this.data||e in this.flashData||e in this.previousFlashData}forget(e){delete this.data[e],this.dirty=!0}flush(){this.data={},this.dirty=!0}flash(e,t){this.flashData[e]=t,this.dirty=!0}all(){return{...this.data,...this.previousFlashData,...this.flashData}}isDirty(){return this.dirty||Object.keys(this.flashData).length>0}toPersist(){let e={...this.data};return Object.keys(this.flashData).length>0&&(e._flash=this.flashData),e}regenerateId(){let e=this.id,t=l.generateId();this.id=t,this.dirty=!0;let s=Ke.get(e);return s instanceof X&&s.markOldSessionId(e),Ke.delete(e),t}static generateId(){return Ja(32).toString("hex")}},Ke=new Map,X=class{sessions=new Map;oldSessionIds=new Set;async read(e){if(this.oldSessionIds.has(e))return null;let t=this.sessions.get(e);return t?Date.now()>t.expiresAt?(this.sessions.delete(e),null):t.data:null}async write(e,t,s){this.sessions.set(e,{data:t,expiresAt:Date.now()+s*1e3}),Ke.set(e,this)}async destroy(e){this.sessions.delete(e),Ke.delete(e)}async gc(e){let t=Date.now();for(let[s,r]of this.sessions)t>r.expiresAt&&(this.sessions.delete(s),Ke.delete(s))}markOldSessionId(e){this.oldSessionIds.add(e),this.sessions.delete(e)}},as=class{constructor(e="sessions",t){this.tableName=e;this.connectionName=t}tableEnsured=!1;async ensureTable(){if(!this.tableEnsured)try{let{Connection:e}=await Promise.resolve().then(()=>(S(),P));switch(e.getDriver(this.connectionName)){case"sqlite":await e.raw(`CREATE TABLE IF NOT EXISTS ${this.tableName} (
43
43
  id TEXT PRIMARY KEY,
44
44
  payload TEXT NOT NULL,
45
45
  expires_at TEXT NOT NULL
@@ -51,10 +51,10 @@ var Fn=Object.defineProperty;var tt=(l=>typeof require<"u"?require:typeof Proxy<
51
51
  id VARCHAR(255) PRIMARY KEY,
52
52
  payload TEXT NOT NULL,
53
53
  expires_at DATETIME NOT NULL
54
- ) ENGINE=InnoDB`,[],this.connectionName);break}this.tableEnsured=!0}catch{}}async read(e){await this.ensureTable();let{Connection:t}=await Promise.resolve().then(()=>(S(),P)),s=await t.raw(`SELECT payload, expires_at FROM ${this.tableName} WHERE id = ?`,[e],this.connectionName);if(s.length===0)return null;let r=s[0];if(new Date(r.expires_at)<new Date)return await this.destroy(e),null;try{return JSON.parse(r.payload)}catch{return null}}async write(e,t,s){await this.ensureTable();let{Connection:r}=await Promise.resolve().then(()=>(S(),P)),i=JSON.stringify(t),n=new Date(Date.now()+s*1e3).toISOString(),o=r.getDriver(this.connectionName);o==="sqlite"?await r.raw(`INSERT INTO ${this.tableName} (id, payload, expires_at) VALUES (?, ?, ?)
55
- ON CONFLICT(id) DO UPDATE SET payload = excluded.payload, expires_at = excluded.expires_at`,[e,i,n],this.connectionName):o==="postgres"?await r.raw(`INSERT INTO ${this.tableName} (id, payload, expires_at) VALUES ($1, $2, $3)
56
- ON CONFLICT(id) DO UPDATE SET payload = $2, expires_at = $3`,[e,i,n],this.connectionName):await r.raw(`INSERT INTO ${this.tableName} (id, payload, expires_at) VALUES (?, ?, ?)
57
- ON DUPLICATE KEY UPDATE payload = VALUES(payload), expires_at = VALUES(expires_at)`,[e,i,n],this.connectionName)}async destroy(e){let{Connection:t}=await Promise.resolve().then(()=>(S(),P));await t.raw(`DELETE FROM ${this.tableName} WHERE id = ?`,[e],this.connectionName)}async gc(e){let{Connection:t}=await Promise.resolve().then(()=>(S(),P));await t.raw(`DELETE FROM ${this.tableName} WHERE expires_at < ?`,[new Date().toISOString()],this.connectionName)}},as=class{dir;constructor(e){this.dir=e??ze(process.cwd(),"storage","sessions")}filePath(e){let t=e.replace(/[^a-zA-Z0-9_-]/g,"");return ze(this.dir,`${t}.json`)}async ensureDir(){await Q.mkdir(this.dir,{recursive:!0})}async read(e){try{let t=await Q.readFile(this.filePath(e),"utf-8"),s=JSON.parse(t);return new Date(s.expiresAt)<new Date?(await this.destroy(e),null):s.data}catch{return null}}async write(e,t,s){await this.ensureDir();let r={data:t,expiresAt:new Date(Date.now()+s*1e3).toISOString()};await Q.writeFile(this.filePath(e),JSON.stringify(r),"utf-8")}async destroy(e){try{await Q.unlink(this.filePath(e))}catch{}}async gc(e){try{let t=await Q.readdir(this.dir),s=new Date;for(let r of t)if(r.endsWith(".json"))try{let i=await Q.readFile(ze(this.dir,r),"utf-8"),n=JSON.parse(i);new Date(n.expiresAt)<s&&await Q.unlink(ze(this.dir,r))}catch{await Q.unlink(ze(this.dir,r)).catch(()=>{})}}catch{}}},ls=class{redis;prefix;constructor(e){this.prefix=e?.prefix??"svelar_session:",e?.client?this.redis=e.client:this._url=e?.url}_url;_connecting;async getClient(){return this.redis?this.redis:(this._connecting||(this._connecting=(async()=>{try{let{default:e}=await import("ioredis");return this.redis=this._url?new e(this._url):new e,this.redis}catch{throw new Error('RedisSessionStore requires "ioredis" package. Install it: npm install ioredis')}})()),this._connecting)}async read(e){let s=await(await this.getClient()).get(this.prefix+e);if(!s)return null;try{return JSON.parse(s)}catch{return null}}async write(e,t,s){await(await this.getClient()).set(this.prefix+e,JSON.stringify(t),"EX",s)}async destroy(e){await(await this.getClient()).del(this.prefix+e)}async gc(e){}},Se=class extends _{config;constructor(e){if(super(),this.config={cookieName:"svelar_session",lifetime:7200,secret:"",path:"/",domain:"",secure:process.env.NODE_ENV==="production",httpOnly:!0,sameSite:"lax",...e},!this.config.secret)throw new Error("APP_KEY is not set. Pass `secret` to createSvelarApp() \u2014 e.g. secret: env.APP_KEY (from $env/dynamic/private).")}async handle(e,t){let s=e.event.request.headers.get("cookie")??"",r=this.getSessionIdFromCookie(s),i=null;if(r){let a=this.verifySignedId(r);a?(i=await this.config.store.read(a),r=a):r=null}r||(r=xe.generateId());let n=new xe(r,i??{});e.event.locals.session=n,e.locals.session=n;let o=await t();if(n.isDirty()&&await this.config.store.write(n.id,n.toPersist(),this.config.lifetime),o instanceof Response){let a=this.signId(n.id),c=this.buildCookieString(a);o.headers.append("Set-Cookie",c)}return o}getSessionIdFromCookie(e){let t=e.split(";").map(s=>s.trim());for(let s of t){let[r,...i]=s.split("=");if(r===this.config.cookieName)return decodeURIComponent(i.join("="))}return null}signId(e){let t=Fi("sha256",this.config.secret).update(e).digest("base64url");return`${e}.${t}`}verifySignedId(e){let t=e.lastIndexOf(".");if(t===-1)return null;let s=e.slice(0,t),r=e.slice(t+1),i=Fi("sha256",this.config.secret).update(s).digest("base64url");if(r.length!==i.length)return null;let n=Buffer.from(r),o=Buffer.from(i);if(n.length!==o.length)return null;try{if(Va(n,o))return s}catch{}return null}buildCookieString(e){let t=[`${this.config.cookieName}=${encodeURIComponent(e)}`];return t.push(`Path=${this.config.path}`),t.push(`Max-Age=${this.config.lifetime}`),this.config.domain&&t.push(`Domain=${this.config.domain}`),this.config.secure&&t.push("Secure"),this.config.httpOnly&&t.push("HttpOnly"),t.push(`SameSite=${this.config.sameSite}`),t.join("; ")}}});var We={};O(We,{Hash:()=>lr});import{randomBytes as or,scrypt as Bi,timingSafeEqual as Ya}from"crypto";async function Qa(l,e=16384){let t=or(16),s=64,r=await new Promise((i,n)=>{Bi(l,t,s,{N:e,r:8,p:1},(o,a)=>{o?n(o):i(a)})});return`$scrypt$N=${e}$${t.toString("base64")}$${r.toString("base64")}`}async function Ga(l,e){let t=e.split("$");if(t.length!==5||t[1]!=="scrypt")return!1;let s=parseInt(t[2].replace("N=",""),10),r=Buffer.from(t[3],"base64"),i=Buffer.from(t[4],"base64"),n=i.length,o=await new Promise((a,c)=>{Bi(l,r,n,{N:s,r:8,p:1},(u,p)=>{u?c(u):a(p)})});return Ya(o,i)}var ar,lr,Pe=w(()=>{"use strict";A();ar=class{config={driver:"scrypt",scryptCost:16384,bcryptRounds:12};configure(e){Object.assign(this.config,e)}async make(e){switch(this.config.driver){case"scrypt":return Qa(e,this.config.scryptCost);case"bcrypt":try{return(await import("bcrypt")).default.hash(e,this.config.bcryptRounds??12)}catch{throw new Error('bcrypt driver requires the "bcrypt" package. Install it: npm install bcrypt')}case"argon2":try{return(await import("argon2")).default.hash(e)}catch{throw new Error('argon2 driver requires the "argon2" package. Install it: npm install argon2')}default:throw new Error(`Unsupported hash driver: ${this.config.driver}`)}}async verify(e,t){if(t.startsWith("$scrypt$"))return Ga(e,t);if(t.startsWith("$2b$")||t.startsWith("$2a$")||t.startsWith("$2y$"))try{return(await import("bcrypt")).default.compare(e,t)}catch{throw new Error("bcrypt package required to verify bcrypt hashes.")}if(t.startsWith("$argon2"))try{return(await import("argon2")).default.verify(t,e)}catch{throw new Error("argon2 package required to verify argon2 hashes.")}return!1}needsRehash(e){if(this.config.driver==="scrypt"&&e.startsWith("$scrypt$")){let t=e.match(/N=(\d+)/);if(t)return parseInt(t[1],10)!==this.config.scryptCost}if(this.config.driver==="bcrypt"&&(e.startsWith("$2b$")||e.startsWith("$2a$"))){let t=e.match(/\$2[aby]\$(\d+)\$/);if(t)return parseInt(t[1],10)!==this.config.bcryptRounds}return this.config.driver==="scrypt"&&!e.startsWith("$scrypt$")||this.config.driver==="bcrypt"&&!e.startsWith("$2")||this.config.driver==="argon2"&&!e.startsWith("$argon2")}randomString(e=32){return or(Math.ceil(e/2)).toString("hex").slice(0,e)}randomToken(e=32){return or(e).toString("base64url")}},lr=x("svelar.hash",()=>new ar)});var Hi={};O(Hi,{EmailTemplates:()=>Za});import{randomUUID as H}from"crypto";var cr,Za,zi=w(()=>{"use strict";A();cr=class{config={driver:"memory"};templates=new Map;constructor(){this.registerDefaults()}configure(e){this.config=e}async register(e){let t={...e,id:H(),createdAt:Date.now(),updatedAt:Date.now()};if(this.config.driver==="memory")this.templates.set(e.name,t);else if(this.config.driver==="database")try{let{Connection:s}=await Promise.resolve().then(()=>(S(),P));await s.connection()}catch{this.templates.set(e.name,t)}return t}async render(e,t){let s=await this.get(e);if(!s)throw new Error(`Template "${e}" not found`);let r=this.interpolate(s.subject,t),i=this.interpolate(s.html,t),n=s.text?this.interpolate(s.text,t):void 0;return{subject:r,html:i,text:n}}async get(e){return this.templates.get(e)||null}async list(e){let t=Array.from(this.templates.values());return e&&(t=t.filter(s=>s.category===e)),t}async update(e,t){let s=this.templates.get(e);return s?(Object.assign(s,t,{updatedAt:Date.now()}),s):null}async delete(e){return this.templates.delete(e)}registerDefaults(){this.templates.set("welcome",{id:H(),name:"welcome",subject:"Welcome to {{appName}}, {{user.name}}!",html:`
54
+ ) ENGINE=InnoDB`,[],this.connectionName);break}this.tableEnsured=!0}catch{}}async read(e){await this.ensureTable();let{Connection:t}=await Promise.resolve().then(()=>(S(),P)),s=await t.raw(`SELECT payload, expires_at FROM ${this.tableName} WHERE id = ?`,[e],this.connectionName);if(s.length===0)return null;let r=s[0];if(new Date(r.expires_at)<new Date)return await this.destroy(e),null;try{return JSON.parse(r.payload)}catch{return null}}async write(e,t,s){await this.ensureTable();let{Connection:r}=await Promise.resolve().then(()=>(S(),P)),o=JSON.stringify(t),n=new Date(Date.now()+s*1e3).toISOString(),i=r.getDriver(this.connectionName);i==="sqlite"?await r.raw(`INSERT INTO ${this.tableName} (id, payload, expires_at) VALUES (?, ?, ?)
55
+ ON CONFLICT(id) DO UPDATE SET payload = excluded.payload, expires_at = excluded.expires_at`,[e,o,n],this.connectionName):i==="postgres"?await r.raw(`INSERT INTO ${this.tableName} (id, payload, expires_at) VALUES ($1, $2, $3)
56
+ ON CONFLICT(id) DO UPDATE SET payload = $2, expires_at = $3`,[e,o,n],this.connectionName):await r.raw(`INSERT INTO ${this.tableName} (id, payload, expires_at) VALUES (?, ?, ?)
57
+ ON DUPLICATE KEY UPDATE payload = VALUES(payload), expires_at = VALUES(expires_at)`,[e,o,n],this.connectionName)}async destroy(e){let{Connection:t}=await Promise.resolve().then(()=>(S(),P));await t.raw(`DELETE FROM ${this.tableName} WHERE id = ?`,[e],this.connectionName)}async gc(e){let{Connection:t}=await Promise.resolve().then(()=>(S(),P));await t.raw(`DELETE FROM ${this.tableName} WHERE expires_at < ?`,[new Date().toISOString()],this.connectionName)}},ls=class{dir;constructor(e){this.dir=e??ze(process.cwd(),"storage","sessions")}filePath(e){let t=e.replace(/[^a-zA-Z0-9_-]/g,"");return ze(this.dir,`${t}.json`)}async ensureDir(){await G.mkdir(this.dir,{recursive:!0})}async read(e){try{let t=await G.readFile(this.filePath(e),"utf-8"),s=JSON.parse(t);return new Date(s.expiresAt)<new Date?(await this.destroy(e),null):s.data}catch{return null}}async write(e,t,s){await this.ensureDir();let r={data:t,expiresAt:new Date(Date.now()+s*1e3).toISOString()};await G.writeFile(this.filePath(e),JSON.stringify(r),"utf-8")}async destroy(e){try{await G.unlink(this.filePath(e))}catch{}}async gc(e){try{let t=await G.readdir(this.dir),s=new Date;for(let r of t)if(r.endsWith(".json"))try{let o=await G.readFile(ze(this.dir,r),"utf-8"),n=JSON.parse(o);new Date(n.expiresAt)<s&&await G.unlink(ze(this.dir,r))}catch{await G.unlink(ze(this.dir,r)).catch(()=>{})}}catch{}}},cs=class{redis;prefix;constructor(e){this.prefix=e?.prefix??"svelar_session:",e?.client?this.redis=e.client:this._url=e?.url}_url;_connecting;async getClient(){return this.redis?this.redis:(this._connecting||(this._connecting=(async()=>{try{let{default:e}=await import("ioredis");return this.redis=this._url?new e(this._url):new e,this.redis}catch{throw new Error('RedisSessionStore requires "ioredis" package. Install it: npm install ioredis')}})()),this._connecting)}async read(e){let s=await(await this.getClient()).get(this.prefix+e);if(!s)return null;try{return JSON.parse(s)}catch{return null}}async write(e,t,s){await(await this.getClient()).set(this.prefix+e,JSON.stringify(t),"EX",s)}async destroy(e){await(await this.getClient()).del(this.prefix+e)}async gc(e){}},Se=class extends _{config;constructor(e){if(super(),this.config={cookieName:"svelar_session",lifetime:7200,secret:"",path:"/",domain:"",secure:process.env.NODE_ENV==="production",httpOnly:!0,sameSite:"lax",...e},!this.config.secret)throw new Error("APP_KEY is not set. Pass `secret` to createSvelarApp() \u2014 e.g. secret: env.APP_KEY (from $env/dynamic/private).")}async handle(e,t){let s=e.event.request.headers.get("cookie")??"",r=this.getSessionIdFromCookie(s),o=null;if(r){let a=this.verifySignedId(r);a?(o=await this.config.store.read(a),r=a):r=null}r||(r=xe.generateId());let n=new xe(r,o??{});e.event.locals.session=n,e.locals.session=n;let i=await t();if(n.isDirty()&&await this.config.store.write(n.id,n.toPersist(),this.config.lifetime),i instanceof Response){let a=this.signId(n.id),c=this.buildCookieString(a);i.headers.append("Set-Cookie",c)}return i}getSessionIdFromCookie(e){let t=e.split(";").map(s=>s.trim());for(let s of t){let[r,...o]=s.split("=");if(r===this.config.cookieName)return decodeURIComponent(o.join("="))}return null}signId(e){let t=Fi("sha256",this.config.secret).update(e).digest("base64url");return`${e}.${t}`}verifySignedId(e){let t=e.lastIndexOf(".");if(t===-1)return null;let s=e.slice(0,t),r=e.slice(t+1),o=Fi("sha256",this.config.secret).update(s).digest("base64url");if(r.length!==o.length)return null;let n=Buffer.from(r),i=Buffer.from(o);if(n.length!==i.length)return null;try{if(Va(n,i))return s}catch{}return null}buildCookieString(e){let t=[`${this.config.cookieName}=${encodeURIComponent(e)}`];return t.push(`Path=${this.config.path}`),t.push(`Max-Age=${this.config.lifetime}`),this.config.domain&&t.push(`Domain=${this.config.domain}`),this.config.secure&&t.push("Secure"),this.config.httpOnly&&t.push("HttpOnly"),t.push(`SameSite=${this.config.sameSite}`),t.join("; ")}}});var We={};N(We,{Hash:()=>cr});import{randomBytes as ar,scrypt as Bi,timingSafeEqual as Ya}from"crypto";async function Ga(l,e=16384){let t=ar(16),s=64,r=await new Promise((o,n)=>{Bi(l,t,s,{N:e,r:8,p:1},(i,a)=>{i?n(i):o(a)})});return`$scrypt$N=${e}$${t.toString("base64")}$${r.toString("base64")}`}async function Qa(l,e){let t=e.split("$");if(t.length!==5||t[1]!=="scrypt")return!1;let s=parseInt(t[2].replace("N=",""),10),r=Buffer.from(t[3],"base64"),o=Buffer.from(t[4],"base64"),n=o.length,i=await new Promise((a,c)=>{Bi(l,r,n,{N:s,r:8,p:1},(u,p)=>{u?c(u):a(p)})});return Ya(i,o)}var lr,cr,Pe=w(()=>{"use strict";A();lr=class{config={driver:"scrypt",scryptCost:16384,bcryptRounds:12};configure(e){Object.assign(this.config,e)}async make(e){switch(this.config.driver){case"scrypt":return Ga(e,this.config.scryptCost);case"bcrypt":try{return(await import("bcrypt")).default.hash(e,this.config.bcryptRounds??12)}catch{throw new Error('bcrypt driver requires the "bcrypt" package. Install it: npm install bcrypt')}case"argon2":try{return(await import("argon2")).default.hash(e)}catch{throw new Error('argon2 driver requires the "argon2" package. Install it: npm install argon2')}default:throw new Error(`Unsupported hash driver: ${this.config.driver}`)}}async verify(e,t){if(t.startsWith("$scrypt$"))return Qa(e,t);if(t.startsWith("$2b$")||t.startsWith("$2a$")||t.startsWith("$2y$"))try{return(await import("bcrypt")).default.compare(e,t)}catch{throw new Error("bcrypt package required to verify bcrypt hashes.")}if(t.startsWith("$argon2"))try{return(await import("argon2")).default.verify(t,e)}catch{throw new Error("argon2 package required to verify argon2 hashes.")}return!1}needsRehash(e){if(this.config.driver==="scrypt"&&e.startsWith("$scrypt$")){let t=e.match(/N=(\d+)/);if(t)return parseInt(t[1],10)!==this.config.scryptCost}if(this.config.driver==="bcrypt"&&(e.startsWith("$2b$")||e.startsWith("$2a$"))){let t=e.match(/\$2[aby]\$(\d+)\$/);if(t)return parseInt(t[1],10)!==this.config.bcryptRounds}return this.config.driver==="scrypt"&&!e.startsWith("$scrypt$")||this.config.driver==="bcrypt"&&!e.startsWith("$2")||this.config.driver==="argon2"&&!e.startsWith("$argon2")}randomString(e=32){return ar(Math.ceil(e/2)).toString("hex").slice(0,e)}randomToken(e=32){return ar(e).toString("base64url")}},cr=x("svelar.hash",()=>new lr)});var Hi={};N(Hi,{EmailTemplates:()=>Za});import{randomUUID as H}from"crypto";var dr,Za,zi=w(()=>{"use strict";A();dr=class{config={driver:"memory"};templates=new Map;constructor(){this.registerDefaults()}configure(e){this.config=e}async register(e){let t={...e,id:H(),createdAt:Date.now(),updatedAt:Date.now()};if(this.config.driver==="memory")this.templates.set(e.name,t);else if(this.config.driver==="database")try{let{Connection:s}=await Promise.resolve().then(()=>(S(),P));await s.connection()}catch{this.templates.set(e.name,t)}return t}async render(e,t){let s=await this.get(e);if(!s)throw new Error(`Template "${e}" not found`);let r=this.interpolate(s.subject,t),o=this.interpolate(s.html,t),n=s.text?this.interpolate(s.text,t):void 0;return{subject:r,html:o,text:n}}async get(e){return this.templates.get(e)||null}async list(e){let t=Array.from(this.templates.values());return e&&(t=t.filter(s=>s.category===e)),t}async update(e,t){let s=this.templates.get(e);return s?(Object.assign(s,t,{updatedAt:Date.now()}),s):null}async delete(e){return this.templates.delete(e)}registerDefaults(){this.templates.set("welcome",{id:H(),name:"welcome",subject:"Welcome to {{appName}}, {{user.name}}!",html:`
58
58
  <h1>Welcome, {{user.name}}!</h1>
59
59
  <p>Thank you for joining {{appName}}.</p>
60
60
  <p>Your account has been created with the email: <strong>{{user.email}}</strong></p>
@@ -110,22 +110,22 @@ This code expires in {{expiresMinutes}} minutes.`,variables:["appName","user.nam
110
110
  <p>Your {{plan.name}} subscription has been canceled.</p>
111
111
  <p>You have access until {{accessUntilDate}}.</p>
112
112
  `,text:`Your {{plan.name}} subscription is canceled.
113
- Access until: {{accessUntilDate}}`,variables:["user.name","plan.name","accessUntilDate"],category:"billing",active:!0,createdAt:Date.now(),updatedAt:Date.now()})}interpolate(e,t){let s=e;return s=s.replace(/\{\{#if\s+(\w+(?:\.\w+)*)\}\}([\s\S]*?)\{\{\/if\}\}/g,(r,i,n)=>this.getNestedValue(t,i)?n:""),s=s.replace(/\{\{#each\s+(\w+(?:\.\w+)*)\}\}([\s\S]*?)\{\{\/each\}\}/g,(r,i,n)=>{let o=this.getNestedValue(t,i);return Array.isArray(o)?o.map((a,c)=>{let u={...t,this:a,$index:c};return this.interpolate(n,u)}).join(""):""}),s=s.replace(/\{\{([\w.$]+)\}\}/g,(r,i)=>{let n=this.getNestedValue(t,i);return n!=null?String(n):""}),s}getNestedValue(e,t){return t.split(".").reduce((s,r)=>s?.[r],e)}},Za=x("svelar.emailTemplates",()=>new cr)});var vr={};O(vr,{Mailable:()=>Je,Mailer:()=>fr});function gr(l){return typeof l=="string"?l:`${l.name} <${l.address}>`}function j(l){return l?Array.isArray(l)?l:[l]:[]}function Ki(l){return Buffer.isBuffer(l)?l.toString("base64"):Buffer.from(l).toString("base64")}var cs,dr,ur,mr,pr,Je,hr,fr,ds=w(()=>{"use strict";A();cs=class{async send(e){let t=j(e.to);return console.log(`[Mail] To: ${t.join(", ")} | Subject: ${e.subject}`),e.text&&console.log(`[Mail] Body: ${e.text.slice(0,200)}`),{accepted:t,rejected:[]}}},dr=class{async send(e){return{accepted:j(e.to),rejected:[]}}},ur=class{constructor(e){this.config=e}async send(e){try{let r=await(await import("nodemailer")).createTransport({host:this.config.host,port:this.config.port??587,secure:this.config.secure??!1,auth:this.config.auth}).sendMail({from:e.from?gr(e.from):void 0,to:j(e.to).join(", "),cc:j(e.cc).join(", ")||void 0,bcc:j(e.bcc).join(", ")||void 0,replyTo:e.replyTo,subject:e.subject,text:e.text,html:e.html,attachments:e.attachments});return{accepted:r.accepted,rejected:r.rejected,messageId:r.messageId}}catch(t){throw t.code==="MODULE_NOT_FOUND"?new Error("SMTP driver requires nodemailer. Install: npm install nodemailer"):t}}},mr=class{constructor(e){this.config=e}async send(e){let t=this.config.apiToken;if(!t)throw new Error("Postmark apiToken is required. Set it in your mailer config or POSTMARK_API_TOKEN env var.");let s=j(e.to),r=j(e.cc),i=j(e.bcc),n={From:e.from?gr(e.from):void 0,To:s.join(", "),Subject:e.subject,MessageStream:this.config.messageStream||"outbound"};r.length>0&&(n.Cc=r.join(", ")),i.length>0&&(n.Bcc=i.join(", ")),e.replyTo&&(n.ReplyTo=e.replyTo),e.html&&(n.HtmlBody=e.html),e.text&&(n.TextBody=e.text),!n.HtmlBody&&!n.TextBody&&(n.TextBody=""),e.tags&&(n.Tag=Object.values(e.tags)[0]),e.attachments?.length&&(n.Attachments=e.attachments.map(c=>({Name:c.filename,Content:Ki(c.content),ContentType:c.contentType||"application/octet-stream"})));let o=await fetch("https://api.postmarkapp.com/email",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json","X-Postmark-Server-Token":t},body:JSON.stringify(n)});if(!o.ok){let c=await o.json().catch(()=>({Message:o.statusText}));throw new Error(`Postmark error ${o.status}: ${c.Message||JSON.stringify(c)}`)}let a=await o.json();return{accepted:s,rejected:[],messageId:a.MessageID}}},pr=class{constructor(e){this.config=e}async send(e){let t=this.config.apiKey;if(!t)throw new Error("Resend apiKey is required. Set it in your mailer config or RESEND_API_KEY env var.");let s=j(e.to),r=j(e.cc),i=j(e.bcc),n={from:e.from?gr(e.from):void 0,to:s,subject:e.subject};r.length>0&&(n.cc=r),i.length>0&&(n.bcc=i),e.replyTo&&(n.reply_to=[e.replyTo]),e.html&&(n.html=e.html),e.text&&(n.text=e.text),e.tags&&(n.tags=Object.entries(e.tags).map(([c,u])=>({name:c,value:u}))),e.attachments?.length&&(n.attachments=e.attachments.map(c=>({filename:c.filename,content:Ki(c.content),content_type:c.contentType||"application/octet-stream"})));let o=await fetch("https://api.resend.com/emails",{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify(n)});if(!o.ok){let c=await o.json().catch(()=>({message:o.statusText}));throw new Error(`Resend error ${o.status}: ${c.message||JSON.stringify(c)}`)}let a=await o.json();return{accepted:s,rejected:[],messageId:a.id}}},Je=class{message={};to(e){return this.message.to=e,this}cc(e){return this.message.cc=e,this}bcc(e){return this.message.bcc=e,this}from(e){return this.message.from=e,this}replyTo(e){return this.message.replyTo=e,this}subject(e){return this.message.subject=e,this}text(e){return this.message.text=e,this}html(e){return this.message.html=e,this}attach(e,t,s){return this.message.attachments||(this.message.attachments=[]),this.message.attachments.push({filename:e,content:t,contentType:s}),this}tag(e,t){return this.message.tags||(this.message.tags={}),this.message.tags[e]=t,this}toMessage(){return this.message}},hr=class{config=null;transports=new Map;configure(e){this.config=e,this.transports.clear()}async send(e,t){let s=this.resolveTransport(t);return!e.from&&this.config?.from&&(e.from=this.config.from),s.send(e)}async sendMailable(e,t){e.build();let s=e.toMessage();return!s.from&&this.config?.from&&(s.from=this.config.from),this.send(s,t)}mailer(e){let t=this.resolveTransport(e);return{send:s=>(!s.from&&this.config?.from&&(s.from=this.config.from),t.send(s))}}resolveTransport(e){let t=e??this.config?.default??"log";if(this.transports.has(t))return this.transports.get(t);if(!this.config){let i=new cs;return this.transports.set(t,i),i}let s=this.config.mailers[t];if(!s)throw new Error(`Mailer "${t}" is not defined.`);let r;switch(s.driver){case"smtp":r=new ur(s);break;case"postmark":r=new mr(s);break;case"resend":r=new pr(s);break;case"log":r=new cs;break;case"null":r=new dr;break;case"custom":{if(!s.transport)throw new Error(`Custom mail driver "${t}" requires a "transport" instance.`);r=s.transport;break}default:throw new Error(`Unknown mail driver: ${s.driver}`)}return this.transports.set(t,r),r}},fr=x("svelar.mail",()=>new hr)});import{createHmac as Re,randomBytes as Ve}from"crypto";function Wi(l){return(typeof l=="string"?Buffer.from(l):l).toString("base64url")}function Ji(l){return Buffer.from(l,"base64url").toString("utf-8")}function Vi(l,e,t,s){return Re(s==="HS384"?"sha384":s==="HS512"?"sha512":"sha256",t).update(`${l}.${e}`).digest("base64url")}function br(l,e,t="HS256"){let s=Wi(JSON.stringify({alg:t,typ:"JWT"})),r=Wi(JSON.stringify(l)),i=Vi(s,r,e,t);return`${s}.${r}.${i}`}function yr(l,e){let t=l.split(".");if(t.length!==3)return null;let[s,r,i]=t,n;try{n=JSON.parse(Ji(s))}catch{return null}let o=Vi(s,r,e,n.alg);if(i!==o)return null;try{let a=JSON.parse(Ji(r));return a.exp&&Date.now()/1e3>a.exp?null:a}catch{return null}}var us,Ee,ms,wr=w(()=>{"use strict";we();us=class{config;currentUser=null;constructor(e){this.config={identifierColumn:"email",passwordColumn:"password",...e}}async attempt(e,t){let{Hash:s}=await Promise.resolve().then(()=>(Pe(),We)),r=e[this.config.identifierColumn],i=e[this.config.passwordColumn];if(!r||!i)return null;let n=await this.config.model.where(this.config.identifierColumn,r).first();if(!n)return null;let o=n.getAttribute(this.config.passwordColumn);return await s.verify(i,o)?(this.currentUser=n,t&&(t.set("auth_user_id",n.getAttribute("id")),t.regenerateId()),n):null}async attemptJwt(e){let{Hash:t}=await Promise.resolve().then(()=>(Pe(),We));if(!this.config.jwt)throw new Error("JWT configuration required for JWT guard.");let s=e[this.config.identifierColumn],r=e[this.config.passwordColumn];if(!s||!r)return null;let i=await this.config.model.where(this.config.identifierColumn,s).first();if(!i)return null;let n=i.getAttribute(this.config.passwordColumn);return await t.verify(r,n)?(this.currentUser=i,this.issueTokenPair(i)):null}async issueTokenPair(e){let t=this.config.jwt,s=t.expiresIn??3600,r=Math.floor(Date.now()/1e3),i={sub:e.getAttribute("id"),iat:r,exp:r+s,...t.issuer?{iss:t.issuer}:{}},n=br(i,t.secret,t.algorithm),o=new Date((r+s)*1e3),a={user:e,token:n,expiresAt:o};if(t.refreshTokens){let c=t.refreshExpiresIn??604800,u=Ve(32).toString("base64url"),p=Re("sha256",t.secret).update(u).digest("hex"),h=new Date((r+c)*1e3),{Connection:m}=await Promise.resolve().then(()=>(S(),P)),f=t.refreshTable??"refresh_tokens";await m.raw(`INSERT INTO ${f} (user_id, token, expires_at, created_at) VALUES (?, ?, ?, ?)`,[e.getAttribute("id"),p,h.toISOString(),new Date().toISOString()]),a.refreshToken=u,a.refreshExpiresAt=h}return a}async refreshJwt(e){if(!this.config.jwt)throw new Error("JWT configuration required.");if(!this.config.jwt.refreshTokens)throw new Error("Refresh tokens are not enabled. Set jwt.refreshTokens = true.");let t=this.config.jwt,s=Re("sha256",t.secret).update(e).digest("hex"),{Connection:r}=await Promise.resolve().then(()=>(S(),P)),i=t.refreshTable??"refresh_tokens",n=await r.raw(`SELECT user_id, expires_at, revoked_at FROM ${i} WHERE token = ?`,[s]);if(n.length===0)return null;let o=n[0];if(o.revoked_at||new Date(o.expires_at)<new Date)return null;await r.raw(`UPDATE ${i} SET revoked_at = ? WHERE token = ?`,[new Date().toISOString(),s]);let a=await this.config.model.find(o.user_id);return a?(this.currentUser=a,this.issueTokenPair(a)):null}async revokeRefreshTokens(e){if(!this.config.jwt?.refreshTokens)return;let{Connection:t}=await Promise.resolve().then(()=>(S(),P)),s=this.config.jwt.refreshTable??"refresh_tokens";await t.raw(`UPDATE ${s} SET revoked_at = ? WHERE user_id = ? AND revoked_at IS NULL`,[new Date().toISOString(),e])}async resolveFromToken(e){if(!this.config.jwt)throw new Error("JWT configuration required.");let t=yr(e,this.config.jwt.secret);if(!t)return null;let s=await this.config.model.find(t.sub);return s&&(this.currentUser=s),s}async resolveFromSession(e){let t=e.get("auth_user_id");if(!t)return null;let s=await this.config.model.find(t);return s&&(this.currentUser=s),s}async register(e){let{Hash:t}=await Promise.resolve().then(()=>(Pe(),We));e[this.config.passwordColumn]&&(e[this.config.passwordColumn]=await t.make(e[this.config.passwordColumn]));let s=await this.config.model.create(e);return this.currentUser=s,s}async logout(e){this.currentUser=null,e&&(e.forget("auth_user_id"),e.regenerateId())}user(){return this.currentUser}check(){return this.currentUser!==null}id(){return this.currentUser?.getAttribute("id")??null}async generateApiToken(e,t="default"){let s=Ve(32).toString("hex"),r=this.config.jwt?.secret??process.env.APP_KEY;if(!r)throw new Error("APP_KEY is not set. Set it in your .env file or pass jwt.secret in auth config.");let i=Re("sha256",r).update(s).digest("hex"),{Connection:n}=await Promise.resolve().then(()=>(S(),P)),o=this.config.token?.table??"personal_access_tokens";return await n.raw(`INSERT INTO ${o} (user_id, name, token, created_at) VALUES (?, ?, ?, ?)`,[e.getAttribute("id"),t,i,new Date().toISOString()]),s}async resolveFromApiToken(e){let{Connection:t}=await Promise.resolve().then(()=>(S(),P)),s=this.config.token?.table??"personal_access_tokens",r=this.config.jwt?.secret??process.env.APP_KEY;if(!r)throw new Error("APP_KEY is not set. Set it in your .env file or pass jwt.secret in auth config.");let i=Re("sha256",r).update(e).digest("hex"),n=await t.raw(`SELECT user_id FROM ${s} WHERE token = ?`,[i]);if(n.length===0)return null;let o=await this.config.model.find(n[0].user_id);return o&&(this.currentUser=o),o}async sendPasswordReset(e){let t=await this.config.model.where(this.config.identifierColumn,e).first();if(!t)return!1;let{Connection:s}=await Promise.resolve().then(()=>(S(),P)),r=this.config.passwordResets?.table??"password_resets",i=this.config.passwordResets?.expiresIn??3600;await this.ensureTable(r,`
113
+ Access until: {{accessUntilDate}}`,variables:["user.name","plan.name","accessUntilDate"],category:"billing",active:!0,createdAt:Date.now(),updatedAt:Date.now()})}interpolate(e,t){let s=e;return s=s.replace(/\{\{#if\s+(\w+(?:\.\w+)*)\}\}([\s\S]*?)\{\{\/if\}\}/g,(r,o,n)=>this.getNestedValue(t,o)?n:""),s=s.replace(/\{\{#each\s+(\w+(?:\.\w+)*)\}\}([\s\S]*?)\{\{\/each\}\}/g,(r,o,n)=>{let i=this.getNestedValue(t,o);return Array.isArray(i)?i.map((a,c)=>{let u={...t,this:a,$index:c};return this.interpolate(n,u)}).join(""):""}),s=s.replace(/\{\{([\w.$]+)\}\}/g,(r,o)=>{let n=this.getNestedValue(t,o);return n!=null?String(n):""}),s}getNestedValue(e,t){return t.split(".").reduce((s,r)=>s?.[r],e)}},Za=x("svelar.emailTemplates",()=>new dr)});var br={};N(br,{Mailable:()=>Je,Mailer:()=>vr});function fr(l){return typeof l=="string"?l:`${l.name} <${l.address}>`}function U(l){return l?Array.isArray(l)?l:[l]:[]}function Ki(l){return Buffer.isBuffer(l)?l.toString("base64"):Buffer.from(l).toString("base64")}var ds,ur,mr,pr,hr,Je,gr,vr,us=w(()=>{"use strict";A();ds=class{async send(e){let t=U(e.to);return console.log(`[Mail] To: ${t.join(", ")} | Subject: ${e.subject}`),e.text&&console.log(`[Mail] Body: ${e.text.slice(0,200)}`),{accepted:t,rejected:[]}}},ur=class{async send(e){return{accepted:U(e.to),rejected:[]}}},mr=class{constructor(e){this.config=e}async send(e){try{let r=await(await import("nodemailer")).createTransport({host:this.config.host,port:this.config.port??587,secure:this.config.secure??!1,auth:this.config.auth}).sendMail({from:e.from?fr(e.from):void 0,to:U(e.to).join(", "),cc:U(e.cc).join(", ")||void 0,bcc:U(e.bcc).join(", ")||void 0,replyTo:e.replyTo,subject:e.subject,text:e.text,html:e.html,attachments:e.attachments});return{accepted:r.accepted,rejected:r.rejected,messageId:r.messageId}}catch(t){throw t.code==="MODULE_NOT_FOUND"?new Error("SMTP driver requires nodemailer. Install: npm install nodemailer"):t}}},pr=class{constructor(e){this.config=e}async send(e){let t=this.config.apiToken;if(!t)throw new Error("Postmark apiToken is required. Set it in your mailer config or POSTMARK_API_TOKEN env var.");let s=U(e.to),r=U(e.cc),o=U(e.bcc),n={From:e.from?fr(e.from):void 0,To:s.join(", "),Subject:e.subject,MessageStream:this.config.messageStream||"outbound"};r.length>0&&(n.Cc=r.join(", ")),o.length>0&&(n.Bcc=o.join(", ")),e.replyTo&&(n.ReplyTo=e.replyTo),e.html&&(n.HtmlBody=e.html),e.text&&(n.TextBody=e.text),!n.HtmlBody&&!n.TextBody&&(n.TextBody=""),e.tags&&(n.Tag=Object.values(e.tags)[0]),e.attachments?.length&&(n.Attachments=e.attachments.map(c=>({Name:c.filename,Content:Ki(c.content),ContentType:c.contentType||"application/octet-stream"})));let i=await fetch("https://api.postmarkapp.com/email",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json","X-Postmark-Server-Token":t},body:JSON.stringify(n)});if(!i.ok){let c=await i.json().catch(()=>({Message:i.statusText}));throw new Error(`Postmark error ${i.status}: ${c.Message||JSON.stringify(c)}`)}let a=await i.json();return{accepted:s,rejected:[],messageId:a.MessageID}}},hr=class{constructor(e){this.config=e}async send(e){let t=this.config.apiKey;if(!t)throw new Error("Resend apiKey is required. Set it in your mailer config or RESEND_API_KEY env var.");let s=U(e.to),r=U(e.cc),o=U(e.bcc),n={from:e.from?fr(e.from):void 0,to:s,subject:e.subject};r.length>0&&(n.cc=r),o.length>0&&(n.bcc=o),e.replyTo&&(n.reply_to=[e.replyTo]),e.html&&(n.html=e.html),e.text&&(n.text=e.text),e.tags&&(n.tags=Object.entries(e.tags).map(([c,u])=>({name:c,value:u}))),e.attachments?.length&&(n.attachments=e.attachments.map(c=>({filename:c.filename,content:Ki(c.content),content_type:c.contentType||"application/octet-stream"})));let i=await fetch("https://api.resend.com/emails",{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify(n)});if(!i.ok){let c=await i.json().catch(()=>({message:i.statusText}));throw new Error(`Resend error ${i.status}: ${c.message||JSON.stringify(c)}`)}let a=await i.json();return{accepted:s,rejected:[],messageId:a.id}}},Je=class{message={};to(e){return this.message.to=e,this}cc(e){return this.message.cc=e,this}bcc(e){return this.message.bcc=e,this}from(e){return this.message.from=e,this}replyTo(e){return this.message.replyTo=e,this}subject(e){return this.message.subject=e,this}text(e){return this.message.text=e,this}html(e){return this.message.html=e,this}attach(e,t,s){return this.message.attachments||(this.message.attachments=[]),this.message.attachments.push({filename:e,content:t,contentType:s}),this}tag(e,t){return this.message.tags||(this.message.tags={}),this.message.tags[e]=t,this}toMessage(){return this.message}},gr=class{config=null;transports=new Map;configure(e){this.config=e,this.transports.clear()}async send(e,t){let s=this.resolveTransport(t);return!e.from&&this.config?.from&&(e.from=this.config.from),s.send(e)}async sendMailable(e,t){e.build();let s=e.toMessage();return!s.from&&this.config?.from&&(s.from=this.config.from),this.send(s,t)}mailer(e){let t=this.resolveTransport(e);return{send:s=>(!s.from&&this.config?.from&&(s.from=this.config.from),t.send(s))}}resolveTransport(e){let t=e??this.config?.default??"log";if(this.transports.has(t))return this.transports.get(t);if(!this.config){let o=new ds;return this.transports.set(t,o),o}let s=this.config.mailers[t];if(!s)throw new Error(`Mailer "${t}" is not defined.`);let r;switch(s.driver){case"smtp":r=new mr(s);break;case"postmark":r=new pr(s);break;case"resend":r=new hr(s);break;case"log":r=new ds;break;case"null":r=new ur;break;case"custom":{if(!s.transport)throw new Error(`Custom mail driver "${t}" requires a "transport" instance.`);r=s.transport;break}default:throw new Error(`Unknown mail driver: ${s.driver}`)}return this.transports.set(t,r),r}},vr=x("svelar.mail",()=>new gr)});import{createHmac as Re,randomBytes as Ve}from"crypto";function Wi(l){return(typeof l=="string"?Buffer.from(l):l).toString("base64url")}function Ji(l){return Buffer.from(l,"base64url").toString("utf-8")}function Vi(l,e,t,s){return Re(s==="HS384"?"sha384":s==="HS512"?"sha512":"sha256",t).update(`${l}.${e}`).digest("base64url")}function yr(l,e,t="HS256"){let s=Wi(JSON.stringify({alg:t,typ:"JWT"})),r=Wi(JSON.stringify(l)),o=Vi(s,r,e,t);return`${s}.${r}.${o}`}function wr(l,e){let t=l.split(".");if(t.length!==3)return null;let[s,r,o]=t,n;try{n=JSON.parse(Ji(s))}catch{return null}let i=Vi(s,r,e,n.alg);if(o!==i)return null;try{let a=JSON.parse(Ji(r));return a.exp&&Date.now()/1e3>a.exp?null:a}catch{return null}}var ms,Ee,ps,Cr=w(()=>{"use strict";we();ms=class{config;currentUser=null;constructor(e){this.config={identifierColumn:"email",passwordColumn:"password",...e}}async attempt(e,t){let{Hash:s}=await Promise.resolve().then(()=>(Pe(),We)),r=e[this.config.identifierColumn],o=e[this.config.passwordColumn];if(!r||!o)return null;let n=await this.config.model.where(this.config.identifierColumn,r).first();if(!n)return null;let i=n.getAttribute(this.config.passwordColumn);return await s.verify(o,i)?(this.currentUser=n,t&&(t.set("auth_user_id",n.getAttribute("id")),t.regenerateId()),n):null}async attemptJwt(e){let{Hash:t}=await Promise.resolve().then(()=>(Pe(),We));if(!this.config.jwt)throw new Error("JWT configuration required for JWT guard.");let s=e[this.config.identifierColumn],r=e[this.config.passwordColumn];if(!s||!r)return null;let o=await this.config.model.where(this.config.identifierColumn,s).first();if(!o)return null;let n=o.getAttribute(this.config.passwordColumn);return await t.verify(r,n)?(this.currentUser=o,this.issueTokenPair(o)):null}async issueTokenPair(e){let t=this.config.jwt,s=t.expiresIn??3600,r=Math.floor(Date.now()/1e3),o={sub:e.getAttribute("id"),iat:r,exp:r+s,...t.issuer?{iss:t.issuer}:{}},n=yr(o,t.secret,t.algorithm),i=new Date((r+s)*1e3),a={user:e,token:n,expiresAt:i};if(t.refreshTokens){let c=t.refreshExpiresIn??604800,u=Ve(32).toString("base64url"),p=Re("sha256",t.secret).update(u).digest("hex"),h=new Date((r+c)*1e3),{Connection:m}=await Promise.resolve().then(()=>(S(),P)),f=t.refreshTable??"refresh_tokens";await m.raw(`INSERT INTO ${f} (user_id, token, expires_at, created_at) VALUES (?, ?, ?, ?)`,[e.getAttribute("id"),p,h.toISOString(),new Date().toISOString()]),a.refreshToken=u,a.refreshExpiresAt=h}return a}async refreshJwt(e){if(!this.config.jwt)throw new Error("JWT configuration required.");if(!this.config.jwt.refreshTokens)throw new Error("Refresh tokens are not enabled. Set jwt.refreshTokens = true.");let t=this.config.jwt,s=Re("sha256",t.secret).update(e).digest("hex"),{Connection:r}=await Promise.resolve().then(()=>(S(),P)),o=t.refreshTable??"refresh_tokens",n=await r.raw(`SELECT user_id, expires_at, revoked_at FROM ${o} WHERE token = ?`,[s]);if(n.length===0)return null;let i=n[0];if(i.revoked_at||new Date(i.expires_at)<new Date)return null;await r.raw(`UPDATE ${o} SET revoked_at = ? WHERE token = ?`,[new Date().toISOString(),s]);let a=await this.config.model.find(i.user_id);return a?(this.currentUser=a,this.issueTokenPair(a)):null}async revokeRefreshTokens(e){if(!this.config.jwt?.refreshTokens)return;let{Connection:t}=await Promise.resolve().then(()=>(S(),P)),s=this.config.jwt.refreshTable??"refresh_tokens";await t.raw(`UPDATE ${s} SET revoked_at = ? WHERE user_id = ? AND revoked_at IS NULL`,[new Date().toISOString(),e])}async resolveFromToken(e){if(!this.config.jwt)throw new Error("JWT configuration required.");let t=wr(e,this.config.jwt.secret);if(!t)return null;let s=await this.config.model.find(t.sub);return s&&(this.currentUser=s),s}async resolveFromSession(e){let t=e.get("auth_user_id");if(!t)return null;let s=await this.config.model.find(t);return s&&(this.currentUser=s),s}async register(e){let{Hash:t}=await Promise.resolve().then(()=>(Pe(),We));e[this.config.passwordColumn]&&(e[this.config.passwordColumn]=await t.make(e[this.config.passwordColumn]));let s=await this.config.model.create(e);return this.currentUser=s,s}async logout(e){this.currentUser=null,e&&(e.forget("auth_user_id"),e.regenerateId())}user(){return this.currentUser}check(){return this.currentUser!==null}id(){return this.currentUser?.getAttribute("id")??null}async generateApiToken(e,t="default"){let s=Ve(32).toString("hex"),r=this.config.jwt?.secret??process.env.APP_KEY;if(!r)throw new Error("APP_KEY is not set. Set it in your .env file or pass jwt.secret in auth config.");let o=Re("sha256",r).update(s).digest("hex"),{Connection:n}=await Promise.resolve().then(()=>(S(),P)),i=this.config.token?.table??"personal_access_tokens";return await n.raw(`INSERT INTO ${i} (user_id, name, token, created_at) VALUES (?, ?, ?, ?)`,[e.getAttribute("id"),t,o,new Date().toISOString()]),s}async resolveFromApiToken(e){let{Connection:t}=await Promise.resolve().then(()=>(S(),P)),s=this.config.token?.table??"personal_access_tokens",r=this.config.jwt?.secret??process.env.APP_KEY;if(!r)throw new Error("APP_KEY is not set. Set it in your .env file or pass jwt.secret in auth config.");let o=Re("sha256",r).update(e).digest("hex"),n=await t.raw(`SELECT user_id FROM ${s} WHERE token = ?`,[o]);if(n.length===0)return null;let i=await this.config.model.find(n[0].user_id);return i&&(this.currentUser=i),i}async sendPasswordReset(e){let t=await this.config.model.where(this.config.identifierColumn,e).first();if(!t)return!1;let{Connection:s}=await Promise.resolve().then(()=>(S(),P)),r=this.config.passwordResets?.table??"password_resets",o=this.config.passwordResets?.expiresIn??3600;await this.ensureTable(r,`
114
114
  CREATE TABLE IF NOT EXISTS ${r} (
115
115
  email TEXT NOT NULL,
116
116
  token TEXT NOT NULL,
117
117
  expires_at TEXT NOT NULL,
118
118
  created_at TEXT NOT NULL
119
119
  )
120
- `),await s.raw(`DELETE FROM ${r} WHERE email = ?`,[e]);let n=Ve(32).toString("base64url"),o=this.hashToken(n),a=new Date(Date.now()+i*1e3).toISOString();await s.raw(`INSERT INTO ${r} (email, token, expires_at, created_at) VALUES (?, ?, ?, ?)`,[e,o,a,new Date().toISOString()]);let c=this.config.appUrl??process.env.APP_URL??"http://localhost:5173",u=this.config.appName??process.env.APP_NAME??"Svelar",p=`${c}/reset-password?token=${n}&email=${encodeURIComponent(e)}`;return await this.sendAuthEmail("password-reset",e,{appName:u,"user.name":t.getAttribute("name")??e,resetUrl:p}),!0}async resetPassword(e,t,s){let{Connection:r}=await Promise.resolve().then(()=>(S(),P)),{Hash:i}=await Promise.resolve().then(()=>(Pe(),We)),n=this.config.passwordResets?.table??"password_resets",o=this.hashToken(e),a=await r.raw(`SELECT email, expires_at FROM ${n} WHERE token = ? AND email = ?`,[o,t]);if(a.length===0)return!1;let c=a[0];if(new Date(c.expires_at)<new Date)return await r.raw(`DELETE FROM ${n} WHERE email = ?`,[t]),!1;let u=await this.config.model.where(this.config.identifierColumn,t).first();if(!u)return!1;let p=await i.make(s);return await this.config.model.where("id",u.getAttribute("id")).update({[this.config.passwordColumn]:p}),await r.raw(`DELETE FROM ${n} WHERE email = ?`,[t]),await this.revokeRefreshTokens(u.getAttribute("id")),!0}async sendVerificationEmail(e){let{Connection:t}=await Promise.resolve().then(()=>(S(),P)),s=this.config.emailVerification?.table??"email_verifications",r=this.config.emailVerification?.expiresIn??86400,i=e.getAttribute(this.config.identifierColumn);await this.ensureTable(s,`
120
+ `),await s.raw(`DELETE FROM ${r} WHERE email = ?`,[e]);let n=Ve(32).toString("base64url"),i=this.hashToken(n),a=new Date(Date.now()+o*1e3).toISOString();await s.raw(`INSERT INTO ${r} (email, token, expires_at, created_at) VALUES (?, ?, ?, ?)`,[e,i,a,new Date().toISOString()]);let c=this.config.appUrl??process.env.APP_URL??"http://localhost:5173",u=this.config.appName??process.env.APP_NAME??"Svelar",p=`${c}/reset-password?token=${n}&email=${encodeURIComponent(e)}`;return await this.sendAuthEmail("password-reset",e,{appName:u,"user.name":t.getAttribute("name")??e,resetUrl:p}),!0}async resetPassword(e,t,s){let{Connection:r}=await Promise.resolve().then(()=>(S(),P)),{Hash:o}=await Promise.resolve().then(()=>(Pe(),We)),n=this.config.passwordResets?.table??"password_resets",i=this.hashToken(e),a=await r.raw(`SELECT email, expires_at FROM ${n} WHERE token = ? AND email = ?`,[i,t]);if(a.length===0)return!1;let c=a[0];if(new Date(c.expires_at)<new Date)return await r.raw(`DELETE FROM ${n} WHERE email = ?`,[t]),!1;let u=await this.config.model.where(this.config.identifierColumn,t).first();if(!u)return!1;let p=await o.make(s);return await this.config.model.where("id",u.getAttribute("id")).update({[this.config.passwordColumn]:p}),await r.raw(`DELETE FROM ${n} WHERE email = ?`,[t]),await this.revokeRefreshTokens(u.getAttribute("id")),!0}async sendVerificationEmail(e){let{Connection:t}=await Promise.resolve().then(()=>(S(),P)),s=this.config.emailVerification?.table??"email_verifications",r=this.config.emailVerification?.expiresIn??86400,o=e.getAttribute(this.config.identifierColumn);await this.ensureTable(s,`
121
121
  CREATE TABLE IF NOT EXISTS ${s} (
122
122
  user_id TEXT NOT NULL,
123
123
  token TEXT NOT NULL,
124
124
  expires_at TEXT NOT NULL,
125
125
  created_at TEXT NOT NULL
126
126
  )
127
- `),await t.raw(`DELETE FROM ${s} WHERE user_id = ?`,[e.getAttribute("id")]);let n=Ve(32).toString("base64url"),o=this.hashToken(n),a=new Date(Date.now()+r*1e3).toISOString();await t.raw(`INSERT INTO ${s} (user_id, token, expires_at, created_at) VALUES (?, ?, ?, ?)`,[e.getAttribute("id"),o,a,new Date().toISOString()]);let u=`${this.config.appUrl??process.env.APP_URL??"http://localhost:5173"}/verify-email?token=${n}&id=${e.getAttribute("id")}`;await this.sendAuthEmail("email-verification",i,{"user.name":e.getAttribute("name")??i,verifyUrl:u})}async verifyEmail(e,t){let{Connection:s}=await Promise.resolve().then(()=>(S(),P)),r=this.config.emailVerification?.table??"email_verifications",i=this.config.emailVerification?.verifiedColumn??"email_verified_at",n=this.hashToken(e),o=await s.raw(`SELECT user_id, expires_at FROM ${r} WHERE token = ? AND user_id = ?`,[n,t]);return o.length===0?!1:new Date(o[0].expires_at)<new Date?(await s.raw(`DELETE FROM ${r} WHERE user_id = ?`,[t]),!1):(await this.config.model.where("id",t).update({[i]:new Date().toISOString()}),await s.raw(`DELETE FROM ${r} WHERE user_id = ?`,[t]),!0)}isEmailVerified(e){let t=this.config.emailVerification?.verifiedColumn??"email_verified_at";return!!e.getAttribute(t)}async sendOtp(e,t="login"){let s=await this.config.model.where(this.config.identifierColumn,e).first();if(!s)return!1;let{Connection:r}=await Promise.resolve().then(()=>(S(),P)),i=this.config.otp?.table??"otp_codes",n=this.config.otp?.expiresIn??600,o=this.config.otp?.length??6;await this.ensureTable(i,`
128
- CREATE TABLE IF NOT EXISTS ${i} (
127
+ `),await t.raw(`DELETE FROM ${s} WHERE user_id = ?`,[e.getAttribute("id")]);let n=Ve(32).toString("base64url"),i=this.hashToken(n),a=new Date(Date.now()+r*1e3).toISOString();await t.raw(`INSERT INTO ${s} (user_id, token, expires_at, created_at) VALUES (?, ?, ?, ?)`,[e.getAttribute("id"),i,a,new Date().toISOString()]);let u=`${this.config.appUrl??process.env.APP_URL??"http://localhost:5173"}/verify-email?token=${n}&id=${e.getAttribute("id")}`;await this.sendAuthEmail("email-verification",o,{"user.name":e.getAttribute("name")??o,verifyUrl:u})}async verifyEmail(e,t){let{Connection:s}=await Promise.resolve().then(()=>(S(),P)),r=this.config.emailVerification?.table??"email_verifications",o=this.config.emailVerification?.verifiedColumn??"email_verified_at",n=this.hashToken(e),i=await s.raw(`SELECT user_id, expires_at FROM ${r} WHERE token = ? AND user_id = ?`,[n,t]);return i.length===0?!1:new Date(i[0].expires_at)<new Date?(await s.raw(`DELETE FROM ${r} WHERE user_id = ?`,[t]),!1):(await this.config.model.where("id",t).update({[o]:new Date().toISOString()}),await s.raw(`DELETE FROM ${r} WHERE user_id = ?`,[t]),!0)}isEmailVerified(e){let t=this.config.emailVerification?.verifiedColumn??"email_verified_at";return!!e.getAttribute(t)}async sendOtp(e,t="login"){let s=await this.config.model.where(this.config.identifierColumn,e).first();if(!s)return!1;let{Connection:r}=await Promise.resolve().then(()=>(S(),P)),o=this.config.otp?.table??"otp_codes",n=this.config.otp?.expiresIn??600,i=this.config.otp?.length??6;await this.ensureTable(o,`
128
+ CREATE TABLE IF NOT EXISTS ${o} (
129
129
  email TEXT NOT NULL,
130
130
  code TEXT NOT NULL,
131
131
  purpose TEXT NOT NULL DEFAULT 'login',
@@ -133,35 +133,35 @@ Access until: {{accessUntilDate}}`,variables:["user.name","plan.name","accessUnt
133
133
  used_at TEXT,
134
134
  created_at TEXT NOT NULL
135
135
  )
136
- `),await r.raw(`DELETE FROM ${i} WHERE email = ? AND purpose = ?`,[e,t]);let a=this.generateOtpCode(o),c=this.hashToken(a),u=new Date(Date.now()+n*1e3).toISOString();await r.raw(`INSERT INTO ${i} (email, code, purpose, expires_at, created_at) VALUES (?, ?, ?, ?, ?)`,[e,c,t,u,new Date().toISOString()]);let p=this.config.appName??process.env.APP_NAME??"Svelar",h=Math.ceil(n/60);return await this.sendAuthEmail("otp-code",e,{appName:p,"user.name":s.getAttribute("name")??e,code:a,purpose:t,expiresMinutes:String(h)}),!0}async verifyOtp(e,t,s="login"){let{Connection:r}=await Promise.resolve().then(()=>(S(),P)),i=this.config.otp?.table??"otp_codes",n=this.hashToken(t),o=await r.raw(`SELECT email, expires_at, used_at FROM ${i} WHERE code = ? AND email = ? AND purpose = ? AND used_at IS NULL`,[n,e,s]);if(o.length===0)return null;if(new Date(o[0].expires_at)<new Date)return await r.raw(`DELETE FROM ${i} WHERE email = ? AND purpose = ?`,[e,s]),null;await r.raw(`UPDATE ${i} SET used_at = ? WHERE code = ? AND email = ? AND purpose = ?`,[new Date().toISOString(),n,e,s]);let a=await this.config.model.where(this.config.identifierColumn,e).first();return a&&(this.currentUser=a),a}async attemptOtp(e,t,s,r="login"){let i=await this.verifyOtp(e,t,r);return i?(s&&(s.set("auth_user_id",i.getAttribute("id")),s.regenerateId()),i):null}async cleanupExpiredTokens(){let{Connection:e}=await Promise.resolve().then(()=>(S(),P)),t=new Date().toISOString(),s=0,r=0,i=0,n=this.config.passwordResets?.table??"password_resets",o=this.config.emailVerification?.table??"email_verifications",a=this.config.otp?.table??"otp_codes";try{s=(await e.raw(`DELETE FROM ${n} WHERE expires_at < ?`,[t]))?.changes??0}catch{}try{r=(await e.raw(`DELETE FROM ${o} WHERE expires_at < ?`,[t]))?.changes??0}catch{}try{i=(await e.raw(`DELETE FROM ${a} WHERE expires_at < ? OR used_at IS NOT NULL`,[t]))?.changes??0}catch{}return{passwordResets:s,verifications:r,otpCodes:i}}hashToken(e){let t=this.config.jwt?.secret??process.env.APP_KEY;if(!t)throw new Error("APP_KEY is not set. Set it in your .env file or pass jwt.secret in auth config.");return Re("sha256",t).update(e).digest("hex")}generateOtpCode(e){let t=Ve(e);return Array.from(t).map(s=>(s%10).toString()).join("")}tablesEnsured=new Set;async ensureTable(e,t){if(this.tablesEnsured.has(e))return;let{Connection:s}=await Promise.resolve().then(()=>(S(),P));await s.raw(t),this.tablesEnsured.add(e)}async sendAuthEmail(e,t,s){try{let{EmailTemplates:r}=await Promise.resolve().then(()=>(zi(),Hi)),{Mailer:i}=await Promise.resolve().then(()=>(ds(),vr)),n=await r.render(e,s);await i.send({to:t,subject:n.subject,html:n.html,text:n.text})}catch(r){console.error(`[Auth] Failed to send ${e} email to ${t}:`,r.message)}}},Ee=class extends _{constructor(t){super();this.authManager=t}async handle(t,s){let r=null;if(t.event.locals.session&&(r=await this.authManager.resolveFromSession(t.event.locals.session)),!r){let i=t.event.request.headers.get("authorization");if(i?.startsWith("Bearer ")){let n=i.slice(7);try{r=await this.authManager.resolveFromToken(n)}catch{r=await this.authManager.resolveFromApiToken(n)}}}return t.event.locals.user=r,t.event.locals.auth=this.authManager,s()}},ms=class extends _{async handle(e,t){return e.event.locals.user?t():new Response(JSON.stringify({message:"Unauthenticated"}),{status:401,headers:{"Content-Type":"application/json"}})}}});import{appendFile as Xa,mkdir as el}from"fs/promises";import{dirname as tl}from"path";function B(){return new Date().toISOString()}var ps,Ye,Cr,xr,Sr,Pr,Rr,hs,Er=w(()=>{"use strict";A();ps={debug:0,info:1,warn:2,error:3,fatal:4},Ye=class{minLevel;format;constructor(e){this.minLevel=e.level??"debug",this.format=e.format??"text"}write(e){if(ps[e.level]<ps[this.minLevel])return;if(this.format==="json"){console.log(JSON.stringify(e));return}let t={debug:"\x1B[90m",info:"\x1B[34m",warn:"\x1B[33m",error:"\x1B[31m",fatal:"\x1B[35m"},s="\x1B[0m",r=t[e.level]??"",i=e.level.toUpperCase().padEnd(5),n=Object.keys(e.context).length>0?` ${JSON.stringify(e.context)}`:"",o=e.level==="error"||e.level==="fatal"?"error":"log";console[o](`${r}[${e.timestamp}] ${i}${s} ${e.message}${n}`)}},Cr=class{minLevel;path;format;initialized=!1;constructor(e){this.minLevel=e.level??"info",this.path=e.path??"storage/logs/app.log",this.format=e.format??"text"}async write(e){if(ps[e.level]<ps[this.minLevel])return;this.initialized||(await el(tl(this.path),{recursive:!0}),this.initialized=!0);let t;if(this.format==="json")t=JSON.stringify(e)+`
136
+ `),await r.raw(`DELETE FROM ${o} WHERE email = ? AND purpose = ?`,[e,t]);let a=this.generateOtpCode(i),c=this.hashToken(a),u=new Date(Date.now()+n*1e3).toISOString();await r.raw(`INSERT INTO ${o} (email, code, purpose, expires_at, created_at) VALUES (?, ?, ?, ?, ?)`,[e,c,t,u,new Date().toISOString()]);let p=this.config.appName??process.env.APP_NAME??"Svelar",h=Math.ceil(n/60);return await this.sendAuthEmail("otp-code",e,{appName:p,"user.name":s.getAttribute("name")??e,code:a,purpose:t,expiresMinutes:String(h)}),!0}async verifyOtp(e,t,s="login"){let{Connection:r}=await Promise.resolve().then(()=>(S(),P)),o=this.config.otp?.table??"otp_codes",n=this.hashToken(t),i=await r.raw(`SELECT email, expires_at, used_at FROM ${o} WHERE code = ? AND email = ? AND purpose = ? AND used_at IS NULL`,[n,e,s]);if(i.length===0)return null;if(new Date(i[0].expires_at)<new Date)return await r.raw(`DELETE FROM ${o} WHERE email = ? AND purpose = ?`,[e,s]),null;await r.raw(`UPDATE ${o} SET used_at = ? WHERE code = ? AND email = ? AND purpose = ?`,[new Date().toISOString(),n,e,s]);let a=await this.config.model.where(this.config.identifierColumn,e).first();return a&&(this.currentUser=a),a}async attemptOtp(e,t,s,r="login"){let o=await this.verifyOtp(e,t,r);return o?(s&&(s.set("auth_user_id",o.getAttribute("id")),s.regenerateId()),o):null}async cleanupExpiredTokens(){let{Connection:e}=await Promise.resolve().then(()=>(S(),P)),t=new Date().toISOString(),s=0,r=0,o=0,n=this.config.passwordResets?.table??"password_resets",i=this.config.emailVerification?.table??"email_verifications",a=this.config.otp?.table??"otp_codes";try{s=(await e.raw(`DELETE FROM ${n} WHERE expires_at < ?`,[t]))?.changes??0}catch{}try{r=(await e.raw(`DELETE FROM ${i} WHERE expires_at < ?`,[t]))?.changes??0}catch{}try{o=(await e.raw(`DELETE FROM ${a} WHERE expires_at < ? OR used_at IS NOT NULL`,[t]))?.changes??0}catch{}return{passwordResets:s,verifications:r,otpCodes:o}}hashToken(e){let t=this.config.jwt?.secret??process.env.APP_KEY;if(!t)throw new Error("APP_KEY is not set. Set it in your .env file or pass jwt.secret in auth config.");return Re("sha256",t).update(e).digest("hex")}generateOtpCode(e){let t=Ve(e);return Array.from(t).map(s=>(s%10).toString()).join("")}tablesEnsured=new Set;async ensureTable(e,t){if(this.tablesEnsured.has(e))return;let{Connection:s}=await Promise.resolve().then(()=>(S(),P));await s.raw(t),this.tablesEnsured.add(e)}async sendAuthEmail(e,t,s){try{let{EmailTemplates:r}=await Promise.resolve().then(()=>(zi(),Hi)),{Mailer:o}=await Promise.resolve().then(()=>(us(),br)),n=await r.render(e,s);await o.send({to:t,subject:n.subject,html:n.html,text:n.text})}catch(r){console.error(`[Auth] Failed to send ${e} email to ${t}:`,r.message)}}},Ee=class extends _{constructor(t){super();this.authManager=t}async handle(t,s){let r=null;if(t.event.locals.session&&(r=await this.authManager.resolveFromSession(t.event.locals.session)),!r){let o=t.event.request.headers.get("authorization");if(o?.startsWith("Bearer ")){let n=o.slice(7);try{r=await this.authManager.resolveFromToken(n)}catch{r=await this.authManager.resolveFromApiToken(n)}}}return t.event.locals.user=r,t.event.locals.auth=this.authManager,s()}},ps=class extends _{async handle(e,t){return e.event.locals.user?t():new Response(JSON.stringify({message:"Unauthenticated"}),{status:401,headers:{"Content-Type":"application/json"}})}}});import{appendFile as Xa,mkdir as el}from"fs/promises";import{dirname as tl}from"path";function B(){return new Date().toISOString()}var hs,Ye,xr,Sr,Pr,Rr,Er,gs,Tr=w(()=>{"use strict";A();hs={debug:0,info:1,warn:2,error:3,fatal:4},Ye=class{minLevel;format;constructor(e){this.minLevel=e.level??"debug",this.format=e.format??"text"}write(e){if(hs[e.level]<hs[this.minLevel])return;if(this.format==="json"){console.log(JSON.stringify(e));return}let t={debug:"\x1B[90m",info:"\x1B[34m",warn:"\x1B[33m",error:"\x1B[31m",fatal:"\x1B[35m"},s="\x1B[0m",r=t[e.level]??"",o=e.level.toUpperCase().padEnd(5),n=Object.keys(e.context).length>0?` ${JSON.stringify(e.context)}`:"",i=e.level==="error"||e.level==="fatal"?"error":"log";console[i](`${r}[${e.timestamp}] ${o}${s} ${e.message}${n}`)}},xr=class{minLevel;path;format;initialized=!1;constructor(e){this.minLevel=e.level??"info",this.path=e.path??"storage/logs/app.log",this.format=e.format??"text"}async write(e){if(hs[e.level]<hs[this.minLevel])return;this.initialized||(await el(tl(this.path),{recursive:!0}),this.initialized=!0);let t;if(this.format==="json")t=JSON.stringify(e)+`
137
137
  `;else{let s=e.level.toUpperCase().padEnd(5),r=Object.keys(e.context).length>0?` ${JSON.stringify(e.context)}`:"";t=`[${e.timestamp}] ${s} ${e.message}${r}
138
- `}await Xa(this.path,t)}},xr=class{minLevel="debug";channelNames;resolver;constructor(e,t){this.channelNames=e.channels??[],this.resolver=t,this.minLevel=e.level??"debug"}async write(e){for(let t of this.channelNames){let s=this.resolver(t);s&&await s.write(e)}}},Sr=class{minLevel="debug";write(){}},Pr=class{config={default:"console",channels:{console:{driver:"console",level:"debug"}}};channels=new Map;configure(e){this.config=e,this.channels.clear()}channel(e){return new Rr(this.resolveChannel(e))}debug(e,t={}){this.writeToDefault({level:"debug",message:e,context:t,timestamp:B()})}info(e,t={}){this.writeToDefault({level:"info",message:e,context:t,timestamp:B()})}warn(e,t={}){this.writeToDefault({level:"warn",message:e,context:t,timestamp:B()})}error(e,t={}){this.writeToDefault({level:"error",message:e,context:t,timestamp:B()})}fatal(e,t={}){this.writeToDefault({level:"fatal",message:e,context:t,timestamp:B()})}writeToDefault(e){this.resolveChannel(this.config.default).write(e)}resolveChannel(e){if(this.channels.has(e))return this.channels.get(e);let t=this.config.channels[e];if(!t){let r=new Ye({driver:"console"});return this.channels.set(e,r),r}let s=this.createChannel(t);return this.channels.set(e,s),s}createChannel(e){switch(e.driver){case"console":return new Ye(e);case"file":return new Cr(e);case"stack":return new xr(e,t=>this.resolveChannel(t));case"null":return new Sr;default:return new Ye(e)}}},Rr=class{constructor(e){this.channel=e}debug(e,t={}){this.channel.write({level:"debug",message:e,context:t,timestamp:B()})}info(e,t={}){this.channel.write({level:"info",message:e,context:t,timestamp:B()})}warn(e,t={}){this.channel.write({level:"warn",message:e,context:t,timestamp:B()})}error(e,t={}){this.channel.write({level:"error",message:e,context:t,timestamp:B()})}fatal(e,t={}){this.channel.write({level:"fatal",message:e,context:t,timestamp:B()})}};hs=x("svelar.log",()=>new Pr)});function bs(l,e){throw new U(l,e??sl(l))}function Yi(l,e,t){l&&bs(e,t)}function Qi(l,e,t){l||bs(e,t)}function sl(l){return{400:"Bad request",401:"Unauthenticated",403:"Forbidden",404:"Not found",405:"Method not allowed",409:"Conflict",419:"Page expired",422:"Unprocessable entity",429:"Too many requests",500:"Internal server error",502:"Bad gateway",503:"Service unavailable",504:"Gateway timeout"}[l]??"An error occurred"}var U,gs,Tr,kr,fs,vs,Te,$r=w(()=>{"use strict";Er();U=class extends Error{constructor(t,s,r){super(s);this.statusCode=t;this.details=r;this.name="HttpError"}},gs=class extends U{constructor(e="The requested resource was not found"){super(404,e),this.name="NotFoundError"}},Tr=class extends U{constructor(e="Unauthenticated"){super(401,e),this.name="UnauthorizedError"}},kr=class extends U{constructor(e="You do not have permission to perform this action"){super(403,e),this.name="ForbiddenError"}},fs=class extends U{constructor(t,s="The given data was invalid"){super(422,s,{errors:t});this.errors=t;this.name="ValidationError"}},vs=class extends gs{constructor(e,t){super(t?`${e} with ID ${t} not found`:`${e} not found`),this.name="ModelNotFoundError"}};Te=class{config;constructor(e={}){this.config={debug:process.env.NODE_ENV!=="production",dontReport:[fs,gs,Tr,kr],...e}}async handle(e,t){let s=e instanceof Error?e:new Error(String(e));return await this.reportError(s,t),this.config.render?this.config.render(s,t):this.renderError(s)}handleSvelteKitError(){return({error:e,event:t,status:s,message:r})=>{let i=e instanceof Error?e:new Error(String(e));return this.reportError(i,t),i instanceof U?{message:i.message,status:i.statusCode,...i.details??{},...this.config.debug?{stack:i.stack}:{}}:{message:this.config.debug?i.message:"An unexpected error occurred",status:s,...this.config.debug?{stack:i.stack}:{}}}}middleware(){let e=this;return async(t,s)=>{try{return await s()}catch(r){return e.handle(r,t.event)}}}async reportError(e,t){if(this.config.dontReport){for(let r of this.config.dontReport)if(e instanceof r)return}let s={error:e.name,...t?.url?{url:t.url.toString()}:{},...e.stack?{stack:e.stack}:{}};if(hs.error(e.message,s),this.config.report)try{await this.config.report(e,t?{url:t.url?.toString()}:void 0)}catch{}}renderError(e){if(e instanceof U){let s={message:e.message};return e instanceof fs&&(s.errors=e.errors),e.details&&Object.assign(s,e.details),this.config.debug&&(s.exception=e.name,s.stack=e.stack?.split(`
138
+ `}await Xa(this.path,t)}},Sr=class{minLevel="debug";channelNames;resolver;constructor(e,t){this.channelNames=e.channels??[],this.resolver=t,this.minLevel=e.level??"debug"}async write(e){for(let t of this.channelNames){let s=this.resolver(t);s&&await s.write(e)}}},Pr=class{minLevel="debug";write(){}},Rr=class{config={default:"console",channels:{console:{driver:"console",level:"debug"}}};channels=new Map;configure(e){this.config=e,this.channels.clear()}channel(e){return new Er(this.resolveChannel(e))}debug(e,t={}){this.writeToDefault({level:"debug",message:e,context:t,timestamp:B()})}info(e,t={}){this.writeToDefault({level:"info",message:e,context:t,timestamp:B()})}warn(e,t={}){this.writeToDefault({level:"warn",message:e,context:t,timestamp:B()})}error(e,t={}){this.writeToDefault({level:"error",message:e,context:t,timestamp:B()})}fatal(e,t={}){this.writeToDefault({level:"fatal",message:e,context:t,timestamp:B()})}writeToDefault(e){this.resolveChannel(this.config.default).write(e)}resolveChannel(e){if(this.channels.has(e))return this.channels.get(e);let t=this.config.channels[e];if(!t){let r=new Ye({driver:"console"});return this.channels.set(e,r),r}let s=this.createChannel(t);return this.channels.set(e,s),s}createChannel(e){switch(e.driver){case"console":return new Ye(e);case"file":return new xr(e);case"stack":return new Sr(e,t=>this.resolveChannel(t));case"null":return new Pr;default:return new Ye(e)}}},Er=class{constructor(e){this.channel=e}debug(e,t={}){this.channel.write({level:"debug",message:e,context:t,timestamp:B()})}info(e,t={}){this.channel.write({level:"info",message:e,context:t,timestamp:B()})}warn(e,t={}){this.channel.write({level:"warn",message:e,context:t,timestamp:B()})}error(e,t={}){this.channel.write({level:"error",message:e,context:t,timestamp:B()})}fatal(e,t={}){this.channel.write({level:"fatal",message:e,context:t,timestamp:B()})}};gs=x("svelar.log",()=>new Rr)});function ys(l,e){throw new q(l,e??sl(l))}function Yi(l,e,t){l&&ys(e,t)}function Gi(l,e,t){l||ys(e,t)}function sl(l){return{400:"Bad request",401:"Unauthenticated",403:"Forbidden",404:"Not found",405:"Method not allowed",409:"Conflict",419:"Page expired",422:"Unprocessable entity",429:"Too many requests",500:"Internal server error",502:"Bad gateway",503:"Service unavailable",504:"Gateway timeout"}[l]??"An error occurred"}var q,fs,kr,$r,vs,bs,Te,Dr=w(()=>{"use strict";Tr();q=class extends Error{constructor(t,s,r){super(s);this.statusCode=t;this.details=r;this.name="HttpError"}},fs=class extends q{constructor(e="The requested resource was not found"){super(404,e),this.name="NotFoundError"}},kr=class extends q{constructor(e="Unauthenticated"){super(401,e),this.name="UnauthorizedError"}},$r=class extends q{constructor(e="You do not have permission to perform this action"){super(403,e),this.name="ForbiddenError"}},vs=class extends q{constructor(t,s="The given data was invalid"){super(422,s,{errors:t});this.errors=t;this.name="ValidationError"}},bs=class extends fs{constructor(e,t){super(t?`${e} with ID ${t} not found`:`${e} not found`),this.name="ModelNotFoundError"}};Te=class{config;constructor(e={}){this.config={debug:process.env.NODE_ENV!=="production",dontReport:[vs,fs,kr,$r],...e}}async handle(e,t){let s=e instanceof Error?e:new Error(String(e));return await this.reportError(s,t),this.config.render?this.config.render(s,t):this.renderError(s)}handleSvelteKitError(){return({error:e,event:t,status:s,message:r})=>{let o=e instanceof Error?e:new Error(String(e));return this.reportError(o,t),o instanceof q?{message:o.message,status:o.statusCode,...o.details??{},...this.config.debug?{stack:o.stack}:{}}:{message:this.config.debug?o.message:"An unexpected error occurred",status:s,...this.config.debug?{stack:o.stack}:{}}}}middleware(){let e=this;return async(t,s)=>{try{return await s()}catch(r){return e.handle(r,t.event)}}}async reportError(e,t){if(this.config.dontReport){for(let r of this.config.dontReport)if(e instanceof r)return}let s={error:e.name,...t?.url?{url:t.url.toString()}:{},...e.stack?{stack:e.stack}:{}};if(gs.error(e.message,s),this.config.report)try{await this.config.report(e,t?{url:t.url?.toString()}:void 0)}catch{}}renderError(e){if(e instanceof q){let s={message:e.message};return e instanceof vs&&(s.errors=e.errors),e.details&&Object.assign(s,e.details),this.config.debug&&(s.exception=e.name,s.stack=e.stack?.split(`
139
139
  `).map(r=>r.trim())),new Response(JSON.stringify(s),{status:e.statusCode,headers:{"Content-Type":"application/json"}})}let t={message:this.config.debug?e.message:"Internal server error"};return this.config.debug&&(t.exception=e.name,t.stack=e.stack?.split(`
140
- `).map(s=>s.trim())),new Response(JSON.stringify(t),{status:500,headers:{"Content-Type":"application/json"}})}}});function Gi(l={}){let{auth:e,secret:t=(()=>{throw new Error("APP_KEY is not set. Pass `secret` to createSvelarApp() \u2014 e.g. secret: env.APP_KEY (from $env/dynamic/private).")})(),sessionStore:s,sessionLifetime:r=86400,rateLimit:i=100,rateLimitWindow:n=6e4,csrfPaths:o=["/api/"],csrfExcludePaths:a=["/api/webhooks"],authThrottleAttempts:c=5,authThrottleDecay:u=1,debug:p=process.env.NODE_ENV!=="production",middleware:h=[],namedMiddleware:m={},i18n:f,errorConfig:y={}}=l,C=[new be,new fe({maxRequests:i,windowMs:n}),new ve({onlyPaths:o,excludePaths:a}),new Se({store:s??new X,secret:t,lifetime:r})];e&&C.push(new Ee(e)),C.push(...h);let M={"auth-throttle":new ye({maxAttempts:c,decayMinutes:u}),...m},T=new Te({debug:p,...y}),D=Dr({middleware:C,namedMiddleware:M,onError:(R,I)=>T.handle(R,I)}),$;if(f){let{paraglideMiddleware:R,getTextDirection:I=()=>"ltr"}=f;$=Ar(async({event:L,resolve:Ze})=>R(L.request,({request:Os,locale:Xe})=>(L.request=Os,Ze(L,{transformPageChunk:({html:et})=>et.replace("%lang%",Xe).replace("%dir%",I(Xe))}))),D)}else $=D;return{handle:$,handleError:T.handleSvelteKitError()}}function Dr(l={}){let e=new V;if(l.middleware)for(let t of l.middleware)e.use(t);if(l.namedMiddleware)for(let[t,s]of Object.entries(l.namedMiddleware))e.register(t,s);return async function({event:s,resolve:r}){let i={event:s,params:s.params??{},locals:s.locals??{}};try{l.app&&!l.app.isBooted()&&await l.app.bootstrap();let n=await e.execute(i,async()=>r(s));return n instanceof Response?n:r(s)}catch(n){if(l.onError){let o=await l.onError(n,s);if(o instanceof Response)return o}return console.error("[Svelar] Unhandled error in hooks:",n),new Response(JSON.stringify({message:process.env.NODE_ENV==="production"?"Internal server error":n.message}),{status:500,headers:{"Content-Type":"application/json"}})}}}function Ar(...l){return async function({event:t,resolve:s}){let r=s;for(let i=l.length-1;i>=0;i--){let n=l[i],o=r;r=a=>n({event:a,resolve:o})}return r(t)}}var _r=w(()=>{"use strict";we();nr();wr();$r()});function Zi(l,e){let t=process.env[l];return t===void 0?e!==void 0?e:"":t==="true"?!0:t==="false"?!1:t==="null"?null:/^\d+$/.test(t)?Number(t):t}var Lr,Xi,en=w(()=>{"use strict";A();Lr=class{items=new Map;clear(){this.items.clear()}load(e){for(let[t,s]of Object.entries(e))this.set(t,s)}async loadFromDirectory(e){let{resolve:t,basename:s,extname:r}=await import("path"),{existsSync:i,readdirSync:n}=await import("fs"),{pathToFileURL:o}=await import("url"),a=t(e);if(!i(a))return[];let c=n(a).filter(p=>(p.endsWith(".ts")||p.endsWith(".js"))&&!p.startsWith(".")),u=[];for(let p of c){let h=s(p,r(p)),m=t(a,p);try{let y=await import(o(m).href),C=y.default??y.config??y;C&&typeof C=="object"&&!Array.isArray(C)&&(this.set(h,C),u.push(h))}catch{}}return u}get(e,t){let s=e.split("."),r=this.items.get(s[0]);for(let i=1;i<s.length;i++){if(r==null)return t;r=r[s[i]]}return r??t}set(e,t){let s=e.split(".");if(s.length===1){this.items.set(e,t);return}let r=this.items.get(s[0]);(r===void 0||typeof r!="object")&&(r={},this.items.set(s[0],r));let i=r;for(let n=1;n<s.length-1;n++)(i[s[n]]===void 0||typeof i[s[n]]!="object")&&(i[s[n]]={}),i=i[s[n]];i[s[s.length-1]]=t}has(e){return this.get(e)!==void 0}all(){let e={};for(let[t,s]of this.items)e[t]=s;return e}},Xi=x("svelar.config",()=>new Lr)});import{z as E}from"zod";function sn(l,e){let t=l.safeParse(e);if(t.success)return{success:!0,data:t.data};let s={};for(let r of t.error.issues){let i=r.path.length>0?r.path:["_root"],n=s;for(let a=0;a<i.length-1;a++){let c=i[a];c in n||(n[c]={}),n=n[c]}let o=i[i.length-1];n[o]||(n[o]=[]),n[o].push(r.message)}return{success:!1,errors:s}}var tn,rn=w(()=>{"use strict";tn={required:()=>E.string().min(1,"This field is required"),email:()=>E.string().email("Must be a valid email address"),string:(l,e)=>{let t=E.string();return l!==void 0&&(t=t.min(l)),e!==void 0&&(t=t.max(e)),t},number:(l,e)=>{let t=E.number();return l!==void 0&&(t=t.min(l)),e!==void 0&&(t=t.max(e)),t},integer:()=>E.number().int(),boolean:()=>E.boolean(),date:()=>E.coerce.date(),url:()=>E.string().url(),uuid:()=>E.string().uuid(),enum:l=>E.enum(l),array:l=>E.array(l),nullable:l=>l.nullable(),optional:l=>l.optional(),confirmed:(l="password")=>E.object({[l]:E.string(),[`${l}_confirmation`]:E.string()}).refine(e=>e[l]===e[`${l}_confirmation`],{message:"Confirmation does not match",path:[`${l}_confirmation`]}),min:l=>E.number().min(l),max:l=>E.number().max(l),between:(l,e)=>E.number().min(l).max(e),regex:(l,e)=>E.string().regex(l,e),ip:()=>E.string().refine(l=>{let e=l.split(".");return e.length!==4?!1:e.every(t=>{let s=Number(t);return Number.isInteger(s)&&s>=0&&s<=255})},{message:"Must be a valid IP address"}),json:()=>E.string().refine(l=>{try{return JSON.parse(l),!0}catch{return!1}},{message:"Must be valid JSON"})}});var nn={};O(nn,{FormAuthorizationError:()=>te,FormRequest:()=>ke,FormValidationError:()=>ee});var ke,ee,te,ys=w(()=>{"use strict";ke=class{authorize(e){return!0}messages(){return{}}attributes(){return{}}passedValidation(e){return e}failedValidation(e){throw new ee(e)}failedAuthorization(){throw new te}async parseBody(e){let t=e.request.headers.get("content-type")??"";if(t.includes("application/json"))return e.request.json();if(t.includes("multipart/form-data")||t.includes("application/x-www-form-urlencoded")){let s=await e.request.formData();return Object.fromEntries(s)}return Object.fromEntries(e.url.searchParams)}static async validate(e){let t=new this;await t.authorize(e)||t.failedAuthorization();let r=await t.parseBody(e),i={...Object.fromEntries(e.url.searchParams),...e.params,...r},o=t.rules().safeParse(i);if(!o.success){let a={},c=t.messages(),u=t.attributes();for(let p of o.error.issues){let h=p.path.join("."),m=u[h]??h;a[m]||(a[m]=[]);let f=`${h}.${p.code}`,y=c[f]??c[h];a[m].push(y??p.message)}t.failedValidation(a)}return t.passedValidation(o.data)}},ee=class extends Error{constructor(t){super("The given data was invalid.");this.errors=t;this.name="FormValidationError"}statusCode=422;toResponse(){return new Response(JSON.stringify({message:this.message,errors:this.errors}),{status:422,headers:{"Content-Type":"application/json"}})}},te=class extends Error{statusCode=403;constructor(e="This action is unauthorized."){super(e),this.name="FormAuthorizationError"}toResponse(){return new Response(JSON.stringify({message:this.message}),{status:403,headers:{"Content-Type":"application/json"}})}}});import{readFile as on,writeFile as rl,unlink as il,mkdir as Qe,readdir as Mr,stat as an,copyFile as nl,rename as ol}from"fs/promises";import{existsSync as al}from"fs";import{join as ll,dirname as ws}from"path";var Or,Cs,Nr,ln,cn=w(()=>{"use strict";A();Or=class{constructor(e){this.config=e;if(!e.root)throw new Error('Local disk requires a "root" path.')}resolve(e){return ll(this.config.root,e)}async get(e){return on(this.resolve(e))}async getText(e){return on(this.resolve(e),"utf-8")}async put(e,t){let s=this.resolve(e);await Qe(ws(s),{recursive:!0}),await rl(s,t)}async append(e,t){let{appendFile:s}=await import("fs/promises"),r=this.resolve(e);await Qe(ws(r),{recursive:!0}),await s(r,t)}async exists(e){return al(this.resolve(e))}async delete(e){try{return await il(this.resolve(e)),!0}catch{return!1}}async copy(e,t){let s=this.resolve(t);await Qe(ws(s),{recursive:!0}),await nl(this.resolve(e),s)}async move(e,t){let s=this.resolve(t);await Qe(ws(s),{recursive:!0}),await ol(this.resolve(e),s)}async files(e=""){let t=this.resolve(e);try{return(await Mr(t,{withFileTypes:!0})).filter(r=>r.isFile()).map(r=>e?`${e}/${r.name}`:r.name)}catch{return[]}}async allFiles(e=""){let t=[],s=this.resolve(e);try{let r=await Mr(s,{withFileTypes:!0});for(let i of r){let n=e?`${e}/${i.name}`:i.name;i.isFile()?t.push(n):i.isDirectory()&&t.push(...await this.allFiles(n))}}catch{}return t}async directories(e=""){let t=this.resolve(e);try{return(await Mr(t,{withFileTypes:!0})).filter(r=>r.isDirectory()).map(r=>e?`${e}/${r.name}`:r.name)}catch{return[]}}async makeDirectory(e){await Qe(this.resolve(e),{recursive:!0})}async deleteDirectory(e){let{rm:t}=await import("fs/promises");await t(this.resolve(e),{recursive:!0,force:!0})}async size(e){return(await an(this.resolve(e))).size}async lastModified(e){return(await an(this.resolve(e))).mtime}url(e){return`${this.config.urlPrefix??""}/${e}`}},Cs=class{config;_client=null;_s3Module=null;constructor(e){if(!e.bucket)throw new Error('S3 disk requires a "bucket" name.');this.config=e}async getS3(){if(this._s3Module)return this._s3Module;try{return this._s3Module=await Function('return import("@aws-sdk/client-s3")')(),this._s3Module}catch{throw new Error("S3 storage driver requires @aws-sdk/client-s3. Install it with: npm install @aws-sdk/client-s3")}}async getClient(){if(this._client)return this._client;let e=await this.getS3();return this._client=new e.S3Client({region:this.config.region??"us-east-1",endpoint:this.config.endpoint,forcePathStyle:this.config.forcePathStyle??!0,credentials:{accessKeyId:this.config.accessKeyId??"",secretAccessKey:this.config.secretAccessKey??""}}),this._client}key(e){let t=this.config.prefix;return t?`${t}/${e}`:e}async get(e){let t=await this.getS3(),i=await(await(await this.getClient()).send(new t.GetObjectCommand({Bucket:this.config.bucket,Key:this.key(e)}))).Body.transformToByteArray();return Buffer.from(i)}async getText(e){return(await this.get(e)).toString("utf-8")}async put(e,t){let s=await this.getS3(),r=await this.getClient(),i=typeof t=="string"?Buffer.from(t,"utf-8"):t;await r.send(new s.PutObjectCommand({Bucket:this.config.bucket,Key:this.key(e),Body:i}))}async append(e,t){let s=null;try{s=await this.get(e)}catch{}let r=typeof t=="string"?Buffer.from(t,"utf-8"):t,i=s?Buffer.concat([s,r]):r;await this.put(e,i)}async exists(e){let t=await this.getS3(),s=await this.getClient();try{return await s.send(new t.HeadObjectCommand({Bucket:this.config.bucket,Key:this.key(e)})),!0}catch{return!1}}async delete(e){let t=await this.getS3(),s=await this.getClient();try{return await s.send(new t.DeleteObjectCommand({Bucket:this.config.bucket,Key:this.key(e)})),!0}catch{return!1}}async copy(e,t){let s=await this.getS3();await(await this.getClient()).send(new s.CopyObjectCommand({Bucket:this.config.bucket,CopySource:`${this.config.bucket}/${this.key(e)}`,Key:this.key(t)}))}async move(e,t){await this.copy(e,t),await this.delete(e)}async files(e=""){let t=await this.getS3(),s=await this.getClient(),r=this.key(e?`${e}/`:"");try{return((await s.send(new t.ListObjectsV2Command({Bucket:this.config.bucket,Prefix:r,Delimiter:"/"}))).Contents??[]).map(n=>n.Key).filter(n=>n!==r).map(n=>{let o=this.config.prefix;return o?n.slice(o.length+1):n})}catch{return[]}}async allFiles(e=""){let t=await this.getS3(),s=await this.getClient(),r=this.key(e?`${e}/`:""),i=[],n;do{let o=await s.send(new t.ListObjectsV2Command({Bucket:this.config.bucket,Prefix:r,ContinuationToken:n}));for(let a of o.Contents??[]){let c=this.config.prefix,u=c?a.Key.slice(c.length+1):a.Key;u&&i.push(u)}n=o.IsTruncated?o.NextContinuationToken:void 0}while(n);return i}async directories(e=""){let t=await this.getS3(),s=await this.getClient(),r=this.key(e?`${e}/`:"");try{return((await s.send(new t.ListObjectsV2Command({Bucket:this.config.bucket,Prefix:r,Delimiter:"/"}))).CommonPrefixes??[]).map(n=>{let o=this.config.prefix;return(o?n.Prefix.slice(o.length+1):n.Prefix).replace(/\/$/,"")}).filter(n=>n.length>0)}catch{return[]}}async makeDirectory(e){}async deleteDirectory(e){let t=await this.allFiles(e);for(let s of t)await this.delete(s)}async size(e){let t=await this.getS3();return(await(await this.getClient()).send(new t.HeadObjectCommand({Bucket:this.config.bucket,Key:this.key(e)}))).ContentLength??0}async lastModified(e){let t=await this.getS3();return(await(await this.getClient()).send(new t.HeadObjectCommand({Bucket:this.config.bucket,Key:this.key(e)}))).LastModified??new Date}url(e){let t=this.config.urlPrefix;if(t)return`${t}/${e}`;let s=this.config.endpoint??`https://s3.${this.config.region??"us-east-1"}.amazonaws.com`;return this.config.forcePathStyle!==!1?`${s}/${this.config.bucket}/${this.key(e)}`:`${s.replace("://",`://${this.config.bucket}.`)}/${this.key(e)}`}async temporaryUrl(e,t=3600){try{let s=await Function('return import("@aws-sdk/s3-request-presigner")')(),r=await this.getS3(),i=await this.getClient(),n=new r.GetObjectCommand({Bucket:this.config.bucket,Key:this.key(e)});return await s.getSignedUrl(i,n,{expiresIn:t})}catch{throw new Error("Pre-signed URLs require @aws-sdk/s3-request-presigner. Install it with: npm install @aws-sdk/s3-request-presigner")}}async ensureBucket(){let e=await this.getS3(),t=await this.getClient();try{await t.send(new e.HeadBucketCommand({Bucket:this.config.bucket}))}catch{await t.send(new e.CreateBucketCommand({Bucket:this.config.bucket}))}}},Nr=class{config=null;disks=new Map;configure(e){this.config=e}disk(e){let t=e??this.config?.default??"local";if(this.disks.has(t))return this.disks.get(t);if(!this.config)throw new Error("Storage not configured. Call Storage.configure() first.");let s=this.config.disks[t];if(!s)throw new Error(`Storage disk "${t}" is not defined.`);let r=this.createDisk(s);return this.disks.set(t,r),r}async get(e){return this.disk().get(e)}async getText(e){return this.disk().getText(e)}async put(e,t){return this.disk().put(e,t)}async append(e,t){return this.disk().append(e,t)}async exists(e){return this.disk().exists(e)}async delete(e){return this.disk().delete(e)}async copy(e,t){return this.disk().copy(e,t)}async move(e,t){return this.disk().move(e,t)}async files(e){return this.disk().files(e)}async allFiles(e){return this.disk().allFiles(e)}async directories(e){return this.disk().directories(e)}async makeDirectory(e){return this.disk().makeDirectory(e)}async deleteDirectory(e){return this.disk().deleteDirectory(e)}async size(e){return this.disk().size(e)}async lastModified(e){return this.disk().lastModified(e)}url(e){return this.disk().url(e)}createDisk(e){switch(e.driver){case"local":return new Or(e);case"s3":return new Cs(e);default:throw new Error(`Unknown storage driver: ${e.driver}`)}}s3Disk(e){let t=this.disk(e);if(!(t instanceof Cs))throw new Error(`Disk "${e??this.config?.default}" is not an S3 disk.`);return t}},ln=x("svelar.storage",()=>new Nr)});import{readFile as cl,writeFile as dl,unlink as dn,mkdir as un}from"fs/promises";import{join as ul,dirname as ml}from"path";import{createHash as pl}from"crypto";var Ir,jr,Ur,qr,mn,pn=w(()=>{"use strict";A();Ir=class{store=new Map;async get(e){let t=this.store.get(e);return t?t.expiresAt&&Date.now()>t.expiresAt?(this.store.delete(e),null):t.value:null}async put(e,t,s){this.store.set(e,{value:t,expiresAt:s?Date.now()+s*1e3:null})}async forget(e){return this.store.delete(e)}async flush(){this.store.clear()}async has(e){let t=this.store.get(e);return t?t.expiresAt&&Date.now()>t.expiresAt?(this.store.delete(e),!1):!0:!1}async increment(e,t=1){let r=(await this.get(e)??0)+t,i=this.store.get(e);return await this.put(e,r,i?.expiresAt?Math.ceil((i.expiresAt-Date.now())/1e3):void 0),r}async decrement(e,t=1){return this.increment(e,-t)}},jr=class{basePath;constructor(e){this.basePath=e.path??"storage/cache"}filePath(e){let t=pl("md5").update(e).digest("hex");return ul(this.basePath,t.slice(0,2),t)}async get(e){let t=this.filePath(e);try{let s=await cl(t,"utf-8"),r=JSON.parse(s);return r.expiresAt&&Date.now()>r.expiresAt?(await dn(t).catch(()=>{}),null):r.value}catch{return null}}async put(e,t,s){let r=this.filePath(e),i={value:t,expiresAt:s?Date.now()+s*1e3:null};await un(ml(r),{recursive:!0}),await dl(r,JSON.stringify(i))}async forget(e){try{return await dn(this.filePath(e)),!0}catch{return!1}}async flush(){let{rm:e}=await import("fs/promises");await e(this.basePath,{recursive:!0,force:!0}),await un(this.basePath,{recursive:!0})}async has(e){return await this.get(e)!==null}async increment(e,t=1){let r=(await this.get(e)??0)+t;return await this.put(e,r),r}async decrement(e,t=1){return this.increment(e,-t)}},Ur=class{async get(){return null}async put(){}async forget(){return!0}async flush(){}async has(){return!1}async increment(){return 0}async decrement(){return 0}},qr=class{config={default:"memory",stores:{memory:{driver:"memory"}}};stores=new Map;configure(e){this.config=e,this.stores.clear()}store(e){let t=e??this.config.default;if(this.stores.has(t))return this.stores.get(t);let s=this.config.stores[t];if(!s)throw new Error(`Cache store "${t}" is not defined.`);let r=this.createStore(s);return this.stores.set(t,r),r}async get(e,t){let s=this.store();return await s.has(e)?s.get(e):t??null}async put(e,t,s){return this.store().put(e,t,s??this.config.stores[this.config.default]?.ttl)}async forget(e){return this.store().forget(e)}async flush(){return this.store().flush()}async has(e){return this.store().has(e)}async increment(e,t){return this.store().increment(e,t)}async decrement(e,t){return this.store().decrement(e,t)}async remember(e,t,s){let r=await this.store().get(e);if(r!==null)return r;let i=await s();return await this.store().put(e,i,t),i}async rememberForever(e,t){let s=await this.store().get(e);if(s!==null)return s;let r=await t();return await this.store().put(e,r),r}async pull(e,t){let s=await this.get(e,t);return await this.forget(e),s}createStore(e){switch(e.driver){case"memory":return new Ir;case"file":return new jr(e);case"null":return new Ur;case"redis":throw new Error("Redis cache requires ioredis. Install: npm install ioredis");default:throw new Error(`Unknown cache driver: ${e.driver}`)}}},mn=x("svelar.cache",()=>new qr)});var xs,Fr,Br,Hr,hn,gn=w(()=>{"use strict";A();xs=class{},Fr=class{async send(e,t){if(!t.toMail)return;let s=t.toMail(e),r=e.routeNotificationForMail?.()??e.getAttribute("email");if(!r){console.warn("[Notifications] No email address for notifiable.");return}try{let{Mailer:i}=await Promise.resolve().then(()=>(ds(),vr));await i.send({to:r,subject:s.subject,html:s.html,text:s.text,from:s.from})}catch(i){console.error("[Notifications] Failed to send mail notification:",i)}}},Br=class{table;constructor(e="notifications"){this.table=e}async send(e,t){if(!t.toDatabase)return;let s=t.toDatabase(e);try{let{Connection:r}=await Promise.resolve().then(()=>(S(),P));await r.raw(`INSERT INTO ${this.table} (id, notifiable_id, type, data, read_at, created_at)
141
- VALUES (?, ?, ?, ?, NULL, ?)`,[crypto.randomUUID(),e.getAttribute("id"),s.type,JSON.stringify(s.data),new Date().toISOString()])}catch(r){console.error("[Notifications] Failed to store database notification:",r)}}},Hr=class{channels=new Map;constructor(){this.channels.set("mail",new Fr),this.channels.set("database",new Br)}extend(e,t){this.channels.set(e,t)}async send(e,t){let s=Array.isArray(e)?e:[e];for(let r of s){let i=t.via(r);for(let n of i){let o=this.channels.get(n);if(o)try{await o.send(r,t)}catch(a){console.error(`[Notifications] Channel "${n}" failed:`,a)}else console.warn(`[Notifications] Unknown channel: ${n}`)}}}async sendVia(e,t,s){for(let r of s){let i=this.channels.get(r);i&&await i.send(e,t)}}},hn=x("svelar.notifier",()=>new Hr)});function zr(l){return l.startsWith("private-")?"private":l.startsWith("presence-")?"presence":"public"}var Kr,Ss,Wr,Jr,fn,vn=w(()=>{"use strict";A();Kr=class{subscribers=[];name;type;constructor(e){this.name=e,this.type=zr(e)}stream(e,t){let s=this,r=new ReadableStream({start(i){let n={channel:s.name};s.type==="presence"&&(n.members=s.getMembers());let o=`event: connected
140
+ `).map(s=>s.trim())),new Response(JSON.stringify(t),{status:500,headers:{"Content-Type":"application/json"}})}}});function Qi(l={}){let{auth:e,secret:t=(()=>{throw new Error("APP_KEY is not set. Pass `secret` to createSvelarApp() \u2014 e.g. secret: env.APP_KEY (from $env/dynamic/private).")})(),sessionStore:s,sessionLifetime:r=86400,rateLimit:o=100,rateLimitWindow:n=6e4,csrfPaths:i=["/api/"],csrfExcludePaths:a=["/api/webhooks"],authThrottleAttempts:c=5,authThrottleDecay:u=1,debug:p=process.env.NODE_ENV!=="production",middleware:h=[],namedMiddleware:m={},i18n:f,errorConfig:y={}}=l,C=[new be,new fe({maxRequests:o,windowMs:n}),new ve({onlyPaths:i,excludePaths:a}),new Se({store:s??new X,secret:t,lifetime:r})];e&&C.push(new Ee(e)),C.push(...h);let $={"auth-throttle":new ye({maxAttempts:c,decayMinutes:u}),...m},T=new Te({debug:p,...y}),D=Ar({middleware:C,namedMiddleware:$,onError:(R,j)=>T.handle(R,j)}),L;if(f){let{paraglideMiddleware:R,getTextDirection:j=()=>"ltr"}=f;L=_r(async({event:M,resolve:Ze})=>R(M.request,({request:Is,locale:Xe})=>(M.request=Is,Ze(M,{transformPageChunk:({html:et})=>et.replace("%lang%",Xe).replace("%dir%",j(Xe))}))),D)}else L=D;return{handle:L,handleError:T.handleSvelteKitError()}}function Ar(l={}){let e=new V;if(l.middleware)for(let t of l.middleware)e.use(t);if(l.namedMiddleware)for(let[t,s]of Object.entries(l.namedMiddleware))e.register(t,s);return async function({event:s,resolve:r}){let o={event:s,params:s.params??{},locals:s.locals??{}};try{l.app&&!l.app.isBooted()&&await l.app.bootstrap();let n=await e.execute(o,async()=>r(s));return n instanceof Response?n:r(s)}catch(n){if(l.onError){let i=await l.onError(n,s);if(i instanceof Response)return i}return console.error("[Svelar] Unhandled error in hooks:",n),new Response(JSON.stringify({message:process.env.NODE_ENV==="production"?"Internal server error":n.message}),{status:500,headers:{"Content-Type":"application/json"}})}}}function _r(...l){return async function({event:t,resolve:s}){let r=s;for(let o=l.length-1;o>=0;o--){let n=l[o],i=r;r=a=>n({event:a,resolve:i})}return r(t)}}var Lr=w(()=>{"use strict";we();nr();Cr();Dr()});function Zi(l,e){let t=process.env[l];return t===void 0?e!==void 0?e:"":t==="true"?!0:t==="false"?!1:t==="null"?null:/^\d+$/.test(t)?Number(t):t}var Mr,Xi,eo=w(()=>{"use strict";A();Mr=class{items=new Map;clear(){this.items.clear()}load(e){for(let[t,s]of Object.entries(e))this.set(t,s)}async loadFromDirectory(e){let{resolve:t,basename:s,extname:r}=await import("path"),{existsSync:o,readdirSync:n}=await import("fs"),{pathToFileURL:i}=await import("url"),a=t(e);if(!o(a))return[];let c=n(a).filter(p=>(p.endsWith(".ts")||p.endsWith(".js"))&&!p.startsWith(".")),u=[];for(let p of c){let h=s(p,r(p)),m=t(a,p);try{let y=await import(i(m).href),C=y.default??y.config??y;C&&typeof C=="object"&&!Array.isArray(C)&&(this.set(h,C),u.push(h))}catch{}}return u}get(e,t){let s=e.split("."),r=this.items.get(s[0]);for(let o=1;o<s.length;o++){if(r==null)return t;r=r[s[o]]}return r??t}set(e,t){let s=e.split(".");if(s.length===1){this.items.set(e,t);return}let r=this.items.get(s[0]);(r===void 0||typeof r!="object")&&(r={},this.items.set(s[0],r));let o=r;for(let n=1;n<s.length-1;n++)(o[s[n]]===void 0||typeof o[s[n]]!="object")&&(o[s[n]]={}),o=o[s[n]];o[s[s.length-1]]=t}has(e){return this.get(e)!==void 0}all(){let e={};for(let[t,s]of this.items)e[t]=s;return e}},Xi=x("svelar.config",()=>new Mr)});import{z as E}from"zod";function so(l,e){let t=l.safeParse(e);if(t.success)return{success:!0,data:t.data};let s={};for(let r of t.error.issues){let o=r.path.length>0?r.path:["_root"],n=s;for(let a=0;a<o.length-1;a++){let c=o[a];c in n||(n[c]={}),n=n[c]}let i=o[o.length-1];n[i]||(n[i]=[]),n[i].push(r.message)}return{success:!1,errors:s}}var to,ro=w(()=>{"use strict";to={required:()=>E.string().min(1,"This field is required"),email:()=>E.string().email("Must be a valid email address"),string:(l,e)=>{let t=E.string();return l!==void 0&&(t=t.min(l)),e!==void 0&&(t=t.max(e)),t},number:(l,e)=>{let t=E.number();return l!==void 0&&(t=t.min(l)),e!==void 0&&(t=t.max(e)),t},integer:()=>E.number().int(),boolean:()=>E.boolean(),date:()=>E.coerce.date(),url:()=>E.string().url(),uuid:()=>E.string().uuid(),enum:l=>E.enum(l),array:l=>E.array(l),nullable:l=>l.nullable(),optional:l=>l.optional(),confirmed:(l="password")=>E.object({[l]:E.string(),[`${l}_confirmation`]:E.string()}).refine(e=>e[l]===e[`${l}_confirmation`],{message:"Confirmation does not match",path:[`${l}_confirmation`]}),min:l=>E.number().min(l),max:l=>E.number().max(l),between:(l,e)=>E.number().min(l).max(e),regex:(l,e)=>E.string().regex(l,e),ip:()=>E.string().refine(l=>{let e=l.split(".");return e.length!==4?!1:e.every(t=>{let s=Number(t);return Number.isInteger(s)&&s>=0&&s<=255})},{message:"Must be a valid IP address"}),json:()=>E.string().refine(l=>{try{return JSON.parse(l),!0}catch{return!1}},{message:"Must be valid JSON"})}});var io={};N(io,{FormAuthorizationError:()=>te,FormRequest:()=>ke,FormValidationError:()=>ee});var ke,ee,te,ws=w(()=>{"use strict";ke=class{authorize(e){return!0}messages(){return{}}attributes(){return{}}passedValidation(e){return e}failedValidation(e){throw new ee(e)}failedAuthorization(){throw new te}async parseBody(e){let t=e.request.headers.get("content-type")??"";if(t.includes("application/json"))return e.request.json();if(t.includes("multipart/form-data")||t.includes("application/x-www-form-urlencoded")){let s=await e.request.formData();return Object.fromEntries(s)}return Object.fromEntries(e.url.searchParams)}static async validate(e){let t=new this;await t.authorize(e)||t.failedAuthorization();let r=await t.parseBody(e),o={...Object.fromEntries(e.url.searchParams),...e.params,...r},i=t.rules().safeParse(o);if(!i.success){let a={},c=t.messages(),u=t.attributes();for(let p of i.error.issues){let h=p.path.join("."),m=u[h]??h;a[m]||(a[m]=[]);let f=`${h}.${p.code}`,y=c[f]??c[h];a[m].push(y??p.message)}t.failedValidation(a)}return t.passedValidation(i.data)}},ee=class extends Error{constructor(t){super("The given data was invalid.");this.errors=t;this.name="FormValidationError"}statusCode=422;toResponse(){return new Response(JSON.stringify({message:this.message,errors:this.errors}),{status:422,headers:{"Content-Type":"application/json"}})}},te=class extends Error{statusCode=403;constructor(e="This action is unauthorized."){super(e),this.name="FormAuthorizationError"}toResponse(){return new Response(JSON.stringify({message:this.message}),{status:403,headers:{"Content-Type":"application/json"}})}}});import{readFile as oo,writeFile as rl,unlink as il,mkdir as Ge,readdir as Or,stat as no,copyFile as ol,rename as nl}from"fs/promises";import{existsSync as al}from"fs";import{join as ll,dirname as Cs}from"path";var Ir,xs,Nr,ao,lo=w(()=>{"use strict";A();Ir=class{constructor(e){this.config=e;if(!e.root)throw new Error('Local disk requires a "root" path.')}resolve(e){return ll(this.config.root,e)}async get(e){return oo(this.resolve(e))}async getText(e){return oo(this.resolve(e),"utf-8")}async put(e,t){let s=this.resolve(e);await Ge(Cs(s),{recursive:!0}),await rl(s,t)}async append(e,t){let{appendFile:s}=await import("fs/promises"),r=this.resolve(e);await Ge(Cs(r),{recursive:!0}),await s(r,t)}async exists(e){return al(this.resolve(e))}async delete(e){try{return await il(this.resolve(e)),!0}catch{return!1}}async copy(e,t){let s=this.resolve(t);await Ge(Cs(s),{recursive:!0}),await ol(this.resolve(e),s)}async move(e,t){let s=this.resolve(t);await Ge(Cs(s),{recursive:!0}),await nl(this.resolve(e),s)}async files(e=""){let t=this.resolve(e);try{return(await Or(t,{withFileTypes:!0})).filter(r=>r.isFile()).map(r=>e?`${e}/${r.name}`:r.name)}catch{return[]}}async allFiles(e=""){let t=[],s=this.resolve(e);try{let r=await Or(s,{withFileTypes:!0});for(let o of r){let n=e?`${e}/${o.name}`:o.name;o.isFile()?t.push(n):o.isDirectory()&&t.push(...await this.allFiles(n))}}catch{}return t}async directories(e=""){let t=this.resolve(e);try{return(await Or(t,{withFileTypes:!0})).filter(r=>r.isDirectory()).map(r=>e?`${e}/${r.name}`:r.name)}catch{return[]}}async makeDirectory(e){await Ge(this.resolve(e),{recursive:!0})}async deleteDirectory(e){let{rm:t}=await import("fs/promises");await t(this.resolve(e),{recursive:!0,force:!0})}async size(e){return(await no(this.resolve(e))).size}async lastModified(e){return(await no(this.resolve(e))).mtime}url(e){return`${this.config.urlPrefix??""}/${e}`}},xs=class{config;_client=null;_s3Module=null;constructor(e){if(!e.bucket)throw new Error('S3 disk requires a "bucket" name.');this.config=e}async getS3(){if(this._s3Module)return this._s3Module;try{return this._s3Module=await Function('return import("@aws-sdk/client-s3")')(),this._s3Module}catch{throw new Error("S3 storage driver requires @aws-sdk/client-s3. Install it with: npm install @aws-sdk/client-s3")}}async getClient(){if(this._client)return this._client;let e=await this.getS3();return this._client=new e.S3Client({region:this.config.region??"us-east-1",endpoint:this.config.endpoint,forcePathStyle:this.config.forcePathStyle??!0,credentials:{accessKeyId:this.config.accessKeyId??"",secretAccessKey:this.config.secretAccessKey??""}}),this._client}key(e){let t=this.config.prefix;return t?`${t}/${e}`:e}async get(e){let t=await this.getS3(),o=await(await(await this.getClient()).send(new t.GetObjectCommand({Bucket:this.config.bucket,Key:this.key(e)}))).Body.transformToByteArray();return Buffer.from(o)}async getText(e){return(await this.get(e)).toString("utf-8")}async put(e,t){let s=await this.getS3(),r=await this.getClient(),o=typeof t=="string"?Buffer.from(t,"utf-8"):t;await r.send(new s.PutObjectCommand({Bucket:this.config.bucket,Key:this.key(e),Body:o}))}async append(e,t){let s=null;try{s=await this.get(e)}catch{}let r=typeof t=="string"?Buffer.from(t,"utf-8"):t,o=s?Buffer.concat([s,r]):r;await this.put(e,o)}async exists(e){let t=await this.getS3(),s=await this.getClient();try{return await s.send(new t.HeadObjectCommand({Bucket:this.config.bucket,Key:this.key(e)})),!0}catch{return!1}}async delete(e){let t=await this.getS3(),s=await this.getClient();try{return await s.send(new t.DeleteObjectCommand({Bucket:this.config.bucket,Key:this.key(e)})),!0}catch{return!1}}async copy(e,t){let s=await this.getS3();await(await this.getClient()).send(new s.CopyObjectCommand({Bucket:this.config.bucket,CopySource:`${this.config.bucket}/${this.key(e)}`,Key:this.key(t)}))}async move(e,t){await this.copy(e,t),await this.delete(e)}async files(e=""){let t=await this.getS3(),s=await this.getClient(),r=this.key(e?`${e}/`:"");try{return((await s.send(new t.ListObjectsV2Command({Bucket:this.config.bucket,Prefix:r,Delimiter:"/"}))).Contents??[]).map(n=>n.Key).filter(n=>n!==r).map(n=>{let i=this.config.prefix;return i?n.slice(i.length+1):n})}catch{return[]}}async allFiles(e=""){let t=await this.getS3(),s=await this.getClient(),r=this.key(e?`${e}/`:""),o=[],n;do{let i=await s.send(new t.ListObjectsV2Command({Bucket:this.config.bucket,Prefix:r,ContinuationToken:n}));for(let a of i.Contents??[]){let c=this.config.prefix,u=c?a.Key.slice(c.length+1):a.Key;u&&o.push(u)}n=i.IsTruncated?i.NextContinuationToken:void 0}while(n);return o}async directories(e=""){let t=await this.getS3(),s=await this.getClient(),r=this.key(e?`${e}/`:"");try{return((await s.send(new t.ListObjectsV2Command({Bucket:this.config.bucket,Prefix:r,Delimiter:"/"}))).CommonPrefixes??[]).map(n=>{let i=this.config.prefix;return(i?n.Prefix.slice(i.length+1):n.Prefix).replace(/\/$/,"")}).filter(n=>n.length>0)}catch{return[]}}async makeDirectory(e){}async deleteDirectory(e){let t=await this.allFiles(e);for(let s of t)await this.delete(s)}async size(e){let t=await this.getS3();return(await(await this.getClient()).send(new t.HeadObjectCommand({Bucket:this.config.bucket,Key:this.key(e)}))).ContentLength??0}async lastModified(e){let t=await this.getS3();return(await(await this.getClient()).send(new t.HeadObjectCommand({Bucket:this.config.bucket,Key:this.key(e)}))).LastModified??new Date}url(e){let t=this.config.urlPrefix;if(t)return`${t}/${e}`;let s=this.config.endpoint??`https://s3.${this.config.region??"us-east-1"}.amazonaws.com`;return this.config.forcePathStyle!==!1?`${s}/${this.config.bucket}/${this.key(e)}`:`${s.replace("://",`://${this.config.bucket}.`)}/${this.key(e)}`}async temporaryUrl(e,t=3600){try{let s=await Function('return import("@aws-sdk/s3-request-presigner")')(),r=await this.getS3(),o=await this.getClient(),n=new r.GetObjectCommand({Bucket:this.config.bucket,Key:this.key(e)});return await s.getSignedUrl(o,n,{expiresIn:t})}catch{throw new Error("Pre-signed URLs require @aws-sdk/s3-request-presigner. Install it with: npm install @aws-sdk/s3-request-presigner")}}async ensureBucket(){let e=await this.getS3(),t=await this.getClient();try{await t.send(new e.HeadBucketCommand({Bucket:this.config.bucket}))}catch{await t.send(new e.CreateBucketCommand({Bucket:this.config.bucket}))}}},Nr=class{config=null;disks=new Map;configure(e){this.config=e}disk(e){let t=e??this.config?.default??"local";if(this.disks.has(t))return this.disks.get(t);if(!this.config)throw new Error("Storage not configured. Call Storage.configure() first.");let s=this.config.disks[t];if(!s)throw new Error(`Storage disk "${t}" is not defined.`);let r=this.createDisk(s);return this.disks.set(t,r),r}async get(e){return this.disk().get(e)}async getText(e){return this.disk().getText(e)}async put(e,t){return this.disk().put(e,t)}async append(e,t){return this.disk().append(e,t)}async exists(e){return this.disk().exists(e)}async delete(e){return this.disk().delete(e)}async copy(e,t){return this.disk().copy(e,t)}async move(e,t){return this.disk().move(e,t)}async files(e){return this.disk().files(e)}async allFiles(e){return this.disk().allFiles(e)}async directories(e){return this.disk().directories(e)}async makeDirectory(e){return this.disk().makeDirectory(e)}async deleteDirectory(e){return this.disk().deleteDirectory(e)}async size(e){return this.disk().size(e)}async lastModified(e){return this.disk().lastModified(e)}url(e){return this.disk().url(e)}createDisk(e){switch(e.driver){case"local":return new Ir(e);case"s3":return new xs(e);default:throw new Error(`Unknown storage driver: ${e.driver}`)}}s3Disk(e){let t=this.disk(e);if(!(t instanceof xs))throw new Error(`Disk "${e??this.config?.default}" is not an S3 disk.`);return t}},ao=x("svelar.storage",()=>new Nr)});import{readFile as cl,writeFile as dl,unlink as co,mkdir as uo}from"fs/promises";import{join as ul,dirname as ml}from"path";import{createHash as pl}from"crypto";var jr,Ur,qr,Fr,mo,po=w(()=>{"use strict";A();jr=class{store=new Map;async get(e){let t=this.store.get(e);return t?t.expiresAt&&Date.now()>t.expiresAt?(this.store.delete(e),null):t.value:null}async put(e,t,s){this.store.set(e,{value:t,expiresAt:s?Date.now()+s*1e3:null})}async forget(e){return this.store.delete(e)}async flush(){this.store.clear()}async has(e){let t=this.store.get(e);return t?t.expiresAt&&Date.now()>t.expiresAt?(this.store.delete(e),!1):!0:!1}async increment(e,t=1){let r=(await this.get(e)??0)+t,o=this.store.get(e);return await this.put(e,r,o?.expiresAt?Math.ceil((o.expiresAt-Date.now())/1e3):void 0),r}async decrement(e,t=1){return this.increment(e,-t)}},Ur=class{basePath;constructor(e){this.basePath=e.path??"storage/cache"}filePath(e){let t=pl("md5").update(e).digest("hex");return ul(this.basePath,t.slice(0,2),t)}async get(e){let t=this.filePath(e);try{let s=await cl(t,"utf-8"),r=JSON.parse(s);return r.expiresAt&&Date.now()>r.expiresAt?(await co(t).catch(()=>{}),null):r.value}catch{return null}}async put(e,t,s){let r=this.filePath(e),o={value:t,expiresAt:s?Date.now()+s*1e3:null};await uo(ml(r),{recursive:!0}),await dl(r,JSON.stringify(o))}async forget(e){try{return await co(this.filePath(e)),!0}catch{return!1}}async flush(){let{rm:e}=await import("fs/promises");await e(this.basePath,{recursive:!0,force:!0}),await uo(this.basePath,{recursive:!0})}async has(e){return await this.get(e)!==null}async increment(e,t=1){let r=(await this.get(e)??0)+t;return await this.put(e,r),r}async decrement(e,t=1){return this.increment(e,-t)}},qr=class{async get(){return null}async put(){}async forget(){return!0}async flush(){}async has(){return!1}async increment(){return 0}async decrement(){return 0}},Fr=class{config={default:"memory",stores:{memory:{driver:"memory"}}};stores=new Map;configure(e){this.config=e,this.stores.clear()}store(e){let t=e??this.config.default;if(this.stores.has(t))return this.stores.get(t);let s=this.config.stores[t];if(!s)throw new Error(`Cache store "${t}" is not defined.`);let r=this.createStore(s);return this.stores.set(t,r),r}async get(e,t){let s=this.store();return await s.has(e)?s.get(e):t??null}async put(e,t,s){return this.store().put(e,t,s??this.config.stores[this.config.default]?.ttl)}async forget(e){return this.store().forget(e)}async flush(){return this.store().flush()}async has(e){return this.store().has(e)}async increment(e,t){return this.store().increment(e,t)}async decrement(e,t){return this.store().decrement(e,t)}async remember(e,t,s){let r=await this.store().get(e);if(r!==null)return r;let o=await s();return await this.store().put(e,o,t),o}async rememberForever(e,t){let s=await this.store().get(e);if(s!==null)return s;let r=await t();return await this.store().put(e,r),r}async pull(e,t){let s=await this.get(e,t);return await this.forget(e),s}createStore(e){switch(e.driver){case"memory":return new jr;case"file":return new Ur(e);case"null":return new qr;case"redis":throw new Error("Redis cache requires ioredis. Install: npm install ioredis");default:throw new Error(`Unknown cache driver: ${e.driver}`)}}},mo=x("svelar.cache",()=>new Fr)});var Ss,Br,Hr,zr,ho,go=w(()=>{"use strict";A();Ss=class{},Br=class{async send(e,t){if(!t.toMail)return;let s=t.toMail(e),r=e.routeNotificationForMail?.()??e.getAttribute("email");if(!r){console.warn("[Notifications] No email address for notifiable.");return}try{let{Mailer:o}=await Promise.resolve().then(()=>(us(),br));await o.send({to:r,subject:s.subject,html:s.html,text:s.text,from:s.from})}catch(o){console.error("[Notifications] Failed to send mail notification:",o)}}},Hr=class{table;constructor(e="notifications"){this.table=e}async send(e,t){if(!t.toDatabase)return;let s=t.toDatabase(e);try{let{Connection:r}=await Promise.resolve().then(()=>(S(),P));await r.raw(`INSERT INTO ${this.table} (id, notifiable_id, type, data, read_at, created_at)
141
+ VALUES (?, ?, ?, ?, NULL, ?)`,[crypto.randomUUID(),e.getAttribute("id"),s.type,JSON.stringify(s.data),new Date().toISOString()])}catch(r){console.error("[Notifications] Failed to store database notification:",r)}}},zr=class{channels=new Map;constructor(){this.channels.set("mail",new Br),this.channels.set("database",new Hr)}extend(e,t){this.channels.set(e,t)}async send(e,t){let s=Array.isArray(e)?e:[e];for(let r of s){let o=t.via(r);for(let n of o){let i=this.channels.get(n);if(i)try{await i.send(r,t)}catch(a){console.error(`[Notifications] Channel "${n}" failed:`,a)}else console.warn(`[Notifications] Unknown channel: ${n}`)}}}async sendVia(e,t,s){for(let r of s){let o=this.channels.get(r);o&&await o.send(e,t)}}},ho=x("svelar.notifier",()=>new zr)});function Kr(l){return l.startsWith("private-")?"private":l.startsWith("presence-")?"presence":"public"}var Wr,Ps,Jr,Vr,fo,vo=w(()=>{"use strict";A();Wr=class{subscribers=[];name;type;constructor(e){this.name=e,this.type=Kr(e)}stream(e,t){let s=this,r=new ReadableStream({start(o){let n={channel:s.name};s.type==="presence"&&(n.members=s.getMembers());let i=`event: connected
142
142
  data: ${JSON.stringify(n)}
143
143
  id: ${Date.now()}
144
144
 
145
- `;i.enqueue(new TextEncoder().encode(o));let a={controller:i,userId:e,userInfo:t};s.subscribers.push(a),s.type==="presence"&&e!==void 0&&s.sendInternal("member:joined",{id:e,...t},a)},cancel(){let i=s.subscribers.findIndex(o=>o.controller===this._controller),n=s.subscribers.length;s.subscribers=s.subscribers.filter(o=>{try{return o.controller.enqueue(new TextEncoder().encode(`:
145
+ `;o.enqueue(new TextEncoder().encode(i));let a={controller:o,userId:e,userInfo:t};s.subscribers.push(a),s.type==="presence"&&e!==void 0&&s.sendInternal("member:joined",{id:e,...t},a)},cancel(){let o=s.subscribers.findIndex(i=>i.controller===this._controller),n=s.subscribers.length;s.subscribers=s.subscribers.filter(i=>{try{return i.controller.enqueue(new TextEncoder().encode(`:
146
146
 
147
147
  `)),!0}catch{return!1}}),s.type==="presence"&&e!==void 0&&s.subscribers.length<n&&s.sendInternal("member:left",{id:e,...t})}});return new Response(r,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"}})}send(e,t,s){let r=`event: ${e}
148
148
  data: ${JSON.stringify(t)}
149
149
  id: ${Date.now()}
150
150
 
151
- `,i=new TextEncoder().encode(r);for(let n of this.subscribers)if(!(s!==void 0&&n.userId!==s))try{n.controller.enqueue(i)}catch{}}sendInternal(e,t,s){let r=`event: ${e}
151
+ `,o=new TextEncoder().encode(r);for(let n of this.subscribers)if(!(s!==void 0&&n.userId!==s))try{n.controller.enqueue(o)}catch{}}sendInternal(e,t,s){let r=`event: ${e}
152
152
  data: ${JSON.stringify(t)}
153
153
  id: ${Date.now()}
154
154
 
155
- `,i=new TextEncoder().encode(r);for(let n of this.subscribers)if(n!==s)try{n.controller.enqueue(i)}catch{}}toUser(e){return{send:(t,s)=>this.send(t,s,e)}}subscriberCount(){return this.subscribers.length}getMembers(){return this.type!=="presence"?[]:this.subscribers.filter(e=>e.userId!==void 0).map(e=>({id:e.userId,...e.userInfo??{}}))}hasMember(e){return this.subscribers.some(t=>t.userId===e)}whisper(e,t,s){let r=`event: client-${e}
155
+ `,o=new TextEncoder().encode(r);for(let n of this.subscribers)if(n!==s)try{n.controller.enqueue(o)}catch{}}toUser(e){return{send:(t,s)=>this.send(t,s,e)}}subscriberCount(){return this.subscribers.length}getMembers(){return this.type!=="presence"?[]:this.subscribers.filter(e=>e.userId!==void 0).map(e=>({id:e.userId,...e.userInfo??{}}))}hasMember(e){return this.subscribers.some(t=>t.userId===e)}whisper(e,t,s){let r=`event: client-${e}
156
156
  data: ${JSON.stringify(t)}
157
157
  id: ${Date.now()}
158
158
 
159
- `,i=new TextEncoder().encode(r);for(let n of this.subscribers)if(n.userId!==s)try{n.controller.enqueue(i)}catch{}}},Ss=class{config;constructor(e){this.config=e}async send(e,t,s){let r=Array.isArray(e)?e:[e],i=JSON.stringify({name:t,channels:r,data:JSON.stringify(s)}),n=Math.floor(Date.now()/1e3).toString(),o=await this.md5(i),a=["POST",`/apps/${this.config.appId}/events`,[`auth_key=${this.config.key}`,`auth_timestamp=${n}`,"auth_version=1.0",`body_md5=${o}`].join("&")].join(`
160
- `),c=await this.hmacSha256(this.config.secret,a),u=this.config.useTLS!==!1?"https":"http",p=this.config.host??`api-${this.config.cluster??"mt1"}.pusher.com`,h=this.config.port??(this.config.useTLS!==!1?443:80),m=`${u}://${p}:${h}/apps/${this.config.appId}/events?auth_key=${this.config.key}&auth_timestamp=${n}&auth_version=1.0&body_md5=${o}&auth_signature=${c}`,f=await fetch(m,{method:"POST",headers:{"Content-Type":"application/json"},body:i});if(!f.ok){let y=await f.text();throw new Error(`Pusher API error (${f.status}): ${y}`)}}async authenticate(e,t,s){let r=`${e}:${t}`,i;s&&(i=JSON.stringify(s),r+=`:${i}`);let n=await this.hmacSha256(this.config.secret,r),o=`${this.config.key}:${n}`;return i?{auth:o,channel_data:i}:{auth:o}}get key(){return this.config.key}clientConfig(){let e={key:this.config.key,cluster:this.config.cluster??"mt1"};return this.config.host&&(e.wsHost=this.config.host,e.wsPort=this.config.port??6001,e.wssPort=this.config.port??6001,e.forceTLS=this.config.useTLS??!1,e.enabledTransports=["ws","wss"],e.disableStats=!0),e}async md5(e){let{createHash:t}=await import("crypto");return t("md5").update(e).digest("hex")}async hmacSha256(e,t){let{createHmac:s}=await import("crypto");return s("sha256",e).update(t).digest("hex")}},Wr=class{constructor(e,t,s){this.manager=e;this.eventName=t;this.eventData=s}channels=[];on(...e){return this.channels.push(...e),this}async send(){for(let e of this.channels)await this.manager.sendToChannel(e,this.eventName,this.eventData)}},Jr=class{config={default:"sse",drivers:{sse:{driver:"sse"}}};sseChannels=new Map;channelAuth=new Map;pusherDriver=null;configure(e){this.config=e;let t=Object.values(e.drivers).find(s=>s.driver==="pusher");t&&t.driver==="pusher"&&(this.pusherDriver=new Ss(t))}channel(e,t){if(t){this.channelAuth.set(e,t);return}return this.sseChannels.has(e)||this.sseChannels.set(e,new Kr(e)),this.sseChannels.get(e)}async authorize(e,t){if(zr(e)==="public")return!0;for(let[r,i]of this.channelAuth){let n=this.matchPattern(r,e);if(n!==null)return await i(t,n)}return!1}async authenticatePusher(e,t,s){if(!this.pusherDriver)throw new Error("Pusher driver is not configured. Call Broadcast.configure() first.");let r=zr(e);if(r==="public")return!1;let i=await this.authorize(e,s);if(i===!1)return!1;if(r==="presence"){let n=typeof i=="object"?{user_id:i.id??s.id,user_info:i}:{user_id:s.id,user_info:{id:s.id}};return this.pusherDriver.authenticate(t,e,n)}return this.pusherDriver.authenticate(t,e)}event(e,t){return new Wr(this,e,t)}to(e,t){return{send:async(s,r)=>{await this.sendToChannel(e,s,r,t)}}}async sendToChannel(e,t,s,r){let i=this.config.drivers[this.config.default];switch(i?.driver){case"pusher":this.pusherDriver||(this.pusherDriver=new Ss(i)),await this.pusherDriver.send(e,t,s);break;case"log":console.log(`[Broadcast] ${e} \u2192 ${t}:`,JSON.stringify(s));break;default:for(let[,n]of this.sseChannels)n.name===e&&n.send(t,s,r);break}}subscribe(e,t,s){return this.channel(e).stream(t,s)}members(e){let t=this.sseChannels.get(e);return t?t.getMembers():[]}pusher(){if(!this.pusherDriver)throw new Error("Pusher driver is not configured.");return this.pusherDriver}activeChannels(){return[...new Set([...this.sseChannels.values()].map(e=>e.name))]}totalSubscribers(){let e=0;for(let t of this.sseChannels.values())e+=t.subscriberCount();return e}prune(){for(let[e,t]of this.sseChannels)t.subscriberCount()===0&&this.sseChannels.delete(e)}matchPattern(e,t){let s=[],r=e.replace(/[.*+?^${}()|[\]\\]/g,a=>a==="{"||a==="}"?a:`\\${a}`).replace(/\\\{(\w+)\\\}/g,(a,c)=>(s.push(c),"([^.]+)")).replace(/\{(\w+)\}/g,(a,c)=>(s.push(c),"([^.]+)")),i=new RegExp(`^${r}$`),n=t.match(i);if(!n)return null;let o={};for(let a=0;a<s.length;a++)o[s[a]]=n[a+1];return o}},fn=x("svelar.broadcast",()=>new Jr)});function Ps(l,e,t){bn&&bn(l,e,{description:t})}async function yn(l,e={}){let{csrfCookieName:t="XSRF-TOKEN",csrfHeaderName:s="X-CSRF-Token",showToast:r=!0,errorMessages:i={},...n}=e,o=(n.method||"GET").toUpperCase(),a=new Headers(n.headers);if(["POST","PUT","PATCH","DELETE"].includes(o)){let c=Yr(t);c&&a.set(s,c)}n.body&&typeof n.body=="string"&&!a.has("Content-Type")&&a.set("Content-Type","application/json"),a.has("Accept")||a.set("Accept","application/json");try{let c=await fetch(l,{...n,headers:a});return!c.ok&&r&&await gl(c,{...hl,...i}),c}catch(c){throw r&&Ps("error","Network Error","Unable to connect. Check your internet connection."),c}}async function gl(l,e){let t="";try{if((l.headers.get("content-type")??"").includes("application/json")){let n=await l.clone().json();if(t=n.message??"",l.status===422&&n.errors){let o=Object.entries(n.errors).map(([a,c])=>`${a}: ${c.join(", ")}`).slice(0,3).join(`
161
- `);Ps("warning",e[422]??"Validation Error",o);return}}}catch{}let s=t||e[l.status]||`Error ${l.status}`,r=l.status>=500?"error":l.status===429?"warning":"error";if(l.status===401){Ps("warning",s,"Please sign in to continue.");return}Ps(r,s)}function Yr(l="XSRF-TOKEN"){if(typeof document>"u")return null;let e=l.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),t=document.cookie.match(new RegExp(`(?:^|;\\s*)${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}function wn(l,e){if(!e)return l;let t=new URL(l,"http://localhost");for(let[s,r]of Object.entries(e))r!=null&&t.searchParams.set(s,String(r));return t.pathname+t.search}var hl,bn,Vr,$e,$p,Cn=w(()=>{"use strict";hl={400:"Invalid request. Please check your input.",401:"Your session has expired. Please sign in again.",403:"You don't have permission to do this.",404:"The requested resource was not found.",405:"This action is not allowed.",409:"A conflict occurred. Please refresh and try again.",419:"Page expired. Please refresh and try again.",422:"The submitted data is invalid.",429:"Too many requests. Please wait a moment.",500:"Something went wrong on our end.",502:"Service temporarily unavailable. Try again shortly.",503:"Service is under maintenance. Try again shortly.",504:"Request timed out. Please try again."},bn=null;Vr=class l{_baseUrl="";_headers={};_timeout=3e4;_retries=0;_retryDelay=1e3;_query={};constructor(e){e?.baseUrl&&(this._baseUrl=e.baseUrl),e?.headers&&(this._headers={...e.headers}),e?.timeout&&(this._timeout=e.timeout),e?.retries&&(this._retries=e.retries),e?.retryDelay&&(this._retryDelay=e.retryDelay)}clone(){let e=new l;return e._baseUrl=this._baseUrl,e._headers={...this._headers},e._timeout=this._timeout,e._retries=this._retries,e._retryDelay=this._retryDelay,e._query={...this._query},e}baseUrl(e){let t=this.clone();return t._baseUrl=e,t}withHeaders(e){let t=this.clone();return t._headers={...t._headers,...e},t}withToken(e,t="Bearer"){return this.withHeaders({Authorization:`${t} ${e}`})}withBasicAuth(e,t){let s=Buffer.from(`${e}:${t}`).toString("base64");return this.withHeaders({Authorization:`Basic ${s}`})}accept(e){return this.withHeaders({Accept:e})}contentType(e){return this.withHeaders({"Content-Type":e})}timeout(e){let t=this.clone();return t._timeout=e,t}retry(e,t=1e3){let s=this.clone();return s._retries=e,s._retryDelay=t,s}query(e){let t=this.clone();for(let[s,r]of Object.entries(e))r!=null&&(t._query[s]=String(r));return t}async get(e){return this.request("GET",e)}async post(e,t){return this.request("POST",e,t)}async put(e,t){return this.request("PUT",e,t)}async patch(e,t){return this.request("PATCH",e,t)}async delete(e,t){return this.request("DELETE",e,t)}async request(e,t,s){let r=this.buildFullUrl(t),i={...this._headers},n;s!==void 0&&(i["Content-Type"]||(i["Content-Type"]="application/json"),n=typeof s=="string"?s:JSON.stringify(s)),i.Accept||(i.Accept="application/json");let o=null,a=1+this._retries;for(let c=0;c<a;c++){c>0&&await new Promise(u=>setTimeout(u,this._retryDelay*c));try{let u=new AbortController,p=setTimeout(()=>u.abort(),this._timeout),h=await fetch(r,{method:e,headers:i,body:n,signal:u.signal});if(clearTimeout(p),!h.ok&&h.status<500&&c<a-1,!h.ok&&h.status>=500&&c<a-1){o=new $e(`HTTP ${h.status}: ${h.statusText}`,h.status,await h.text());continue}let m=h.headers.get("content-type")??"",f;if(m.includes("application/json")?f=await h.json():f=await h.text(),!h.ok)throw new $e(`HTTP ${h.status}: ${typeof f=="string"?f:JSON.stringify(f)}`,h.status,f);return{data:f,status:h.status,headers:h.headers,ok:!0}}catch(u){if(u instanceof $e)throw u;if(o=u,u.name==="AbortError"&&(o=new $e("Request timed out",0,null)),c>=a-1)break}}throw o??new Error("HTTP request failed")}buildFullUrl(e){let t=this._baseUrl?`${this._baseUrl.replace(/\/+$/,"")}/${e.replace(/^\/+/,"")}`:e,s=Object.entries(this._query);if(s.length>0){let r=new URL(t);for(let[i,n]of s)r.searchParams.set(i,n);t=r.toString()}return t}},$e=class extends Error{constructor(t,s,r){super(t);this.status=s;this.body=r;this.name="HttpRequestError"}},$p=new Vr});function xn(l){let{paraglideMiddleware:e,getTextDirection:t=()=>"ltr",langPlaceholder:s="%lang%",dirPlaceholder:r="%dir%"}=l;return({event:i,resolve:n})=>e(i.request,({request:o,locale:a})=>(i.request=o,n(i,{transformPageChunk:({html:c})=>c.replace(s,a).replace(r,t(a))})))}function Sn(l){return e=>l.deLocalizeUrl(e.url).pathname}var Pn=w(()=>{"use strict"});function Rn(l,e,t={}){return async s=>{let{superValidate:r,fail:i,message:n}=await import("sveltekit-superforms"),{zod:o}=await import("sveltekit-superforms/adapters"),a=await r(s,o(l));if(!a.valid)return i(400,{form:a});try{let c=await e(a.data,s);if(t.redirectTo){let{redirect:u}=await import("@sveltejs/kit");throw u(303,t.redirectTo)}return c??{form:a}}catch(c){if(c?.status>=300&&c?.status<400)throw c;return n(a,t.errorMessage||c.message||"An error occurred",{status:c.status||400})}}}async function En(l,e){let{superValidate:t}=await import("sveltekit-superforms"),{zod:s}=await import("sveltekit-superforms/adapters");return t(e??null,s(l))}async function Tn(l,e){let t=await l.request.formData(),s={};for(let[i,n]of t.entries())s[i]=n;let r=e.safeParse(s);if(!r.success){let{FormValidationError:i}=await Promise.resolve().then(()=>(ys(),nn));throw new i(r.error.flatten().fieldErrors)}return r.data}var kn=w(()=>{"use strict";ys()});var $n={};O($n,{Application:()=>ts,AuthManager:()=>us,AuthenticateMiddleware:()=>Ee,BelongsTo:()=>pe,BelongsToMany:()=>he,Broadcast:()=>fn,Cache:()=>mn,ColumnBuilder:()=>W,Connection:()=>v,Container:()=>Z,Controller:()=>ns,CorsMiddleware:()=>ss,CsrfMiddleware:()=>ve,DatabaseSessionStore:()=>os,ErrorHandler:()=>Te,Event:()=>ge,EventDispatcher:()=>qe,FileSessionStore:()=>as,ForbiddenError:()=>He,FormAuthorizationError:()=>te,FormRequest:()=>ke,FormValidationError:()=>ee,HasMany:()=>me,HasOne:()=>ue,Hash:()=>lr,HttpError:()=>U,Job:()=>le,Log:()=>hs,LoggingMiddleware:()=>rs,Mailable:()=>Je,Mailer:()=>fr,MemorySessionStore:()=>X,Middleware:()=>_,MiddlewareStack:()=>V,Migration:()=>_e,Migrator:()=>Le,Model:()=>Xt,ModelNotFoundError:()=>vs,NotFoundError:()=>Fe,Notification:()=>xs,Notifier:()=>hn,OriginMiddleware:()=>be,QueryBuilder:()=>F,Queue:()=>er,RateLimitMiddleware:()=>fe,RedisSessionStore:()=>ls,RequireAuthMiddleware:()=>ms,Schema:()=>J,Seeder:()=>es,ServiceProvider:()=>Ue,Session:()=>xe,SessionMiddleware:()=>Se,SignatureMiddleware:()=>is,Storage:()=>ln,TableBuilder:()=>oe,ThrottleMiddleware:()=>ye,UnauthorizedError:()=>Be,ValidationError:()=>Y,abort:()=>bs,abortIf:()=>Yi,abortUnless:()=>Qi,apiFetch:()=>yn,buildUrl:()=>wn,config:()=>Xi,container:()=>Ii,createFormAction:()=>Rn,createI18nHandle:()=>xn,createReroute:()=>Sn,createSvelarApp:()=>Gi,createSvelarHooks:()=>Dr,env:()=>Zi,getCsrfToken:()=>Yr,loadForm:()=>En,resource:()=>Ui,rules:()=>tn,schema:()=>Ri,sequence:()=>Ar,signJwt:()=>br,validate:()=>sn,validateForm:()=>Tn,verifyJwt:()=>yr,z:()=>E});var Dn=w(()=>{"use strict";Oi();tr();sr();S();Hs();zs();Ni();ir();rr();ji();we();qi();_r();en();rn();wr();Pe();nr();$r();Zt();ys();cn();Er();pn();ce();ds();gn();vn();Cn();Pn();kn();_r()});var Zr={};O(Zr,{PluginRegistry:()=>Ds});var Gr,Ds,As=w(()=>{"use strict";A();Gr=class{plugins=new Map;enabledPlugins=new Set;async discover(){let{join:e}=await import("path"),{existsSync:t,readdirSync:s}=await import("fs"),{readFile:r}=await import("fs/promises"),i=[],n=e(process.cwd(),"node_modules");if(!t(n))return i;let o=async(a,c="")=>{if(t(a))try{let u=s(a,{withFileTypes:!0});for(let p of u){if(!p.isDirectory()||p.name.startsWith("."))continue;if(p.name.startsWith("@")){let y=e(a,p.name);await o(y,p.name+"/");continue}let h=c+p.name,m=p.name.startsWith("svelar-");if(!m)continue;let f=e(a,p.name,"package.json");if(t(f))try{let y=await r(f,"utf-8"),C=JSON.parse(y),M=C.keywords?.includes("svelar-plugin");if(!m&&!M)continue;let T={name:C.name||h,version:C.version||"0.0.0",description:C.description||"",packageName:h,installed:!0,enabled:!1,hasConfig:!!C.svelar?.config,hasMigrations:!!C.svelar?.migrations};i.push(T),this.plugins.set(T.name,T)}catch{}}}catch{}};return await o(n),i}enable(e){let t=this.plugins.get(e);if(!t)throw new Error(`Plugin "${e}" not found in registry.`);this.enabledPlugins.add(e),t.enabled=!0}disable(e){this.enabledPlugins.delete(e);let t=this.plugins.get(e);t&&(t.enabled=!1)}isEnabled(e){return this.enabledPlugins.has(e)}list(){return[...this.plugins.values()]}listEnabled(){return[...this.plugins.values()].filter(e=>this.enabledPlugins.has(e.name))}get(e){return this.plugins.get(e)}register(e){this.plugins.set(e.name,e)}},Ds=x("svelar.pluginRegistry",()=>new Gr)});var Mn={};O(Mn,{PluginPublisher:()=>ei});var Xr,ei,ti=w(()=>{"use strict";A();Xr=class{async publish(e,t){let{mkdir:s,copyFile:r}=await import("fs/promises"),{join:i,dirname:n}=await import("path"),{existsSync:o}=await import("fs"),a={configs:[],migrations:[],assets:[]},c=e.publishables?.()||{};for(let[u,p]of Object.entries(c))for(let h of p){if(t?.only&&h.type!==t.only)continue;let m=i(process.cwd(),h.dest),f=n(m);if(!(o(m)&&!t?.force))try{await s(f,{recursive:!0}),await r(h.source,m),h.type==="config"?a.configs.push(m):h.type==="migration"?a.migrations.push(m):h.type==="asset"&&a.assets.push(m)}catch(y){console.warn(`Failed to publish ${h.source} to ${m}:`,y)}}return a}async preview(e){let t={configs:[],migrations:[],assets:[]},s=e.publishables?.()||{};for(let[r,i]of Object.entries(s))for(let n of i){let o=tt("path").join(process.cwd(),n.dest);n.type==="config"?t.configs.push(o):n.type==="migration"?t.migrations.push(o):n.type==="asset"&&t.assets.push(o)}return t}},ei=x("svelar.pluginPublisher",()=>new Xr)});var On={};O(On,{PluginInstaller:()=>Sl});var si,Sl,Nn=w(()=>{"use strict";A();As();ti();si=class{async install(e,t){let{spawn:s}=await import("child_process"),{promisify:r}=await import("util"),{join:i}=await import("path"),{readFile:n}=await import("fs/promises"),{existsSync:o}=await import("fs");try{await this.runNpmInstall(e);let a=Ds,c=await a.discover(),u;for(let h of c)if(h.packageName===e||h.name===e){u=h;break}if(!u)return{success:!1,pluginName:e,version:"0.0.0",published:null,error:`Plugin not found after installation. Make sure ${e} is a valid Svelar plugin.`};a.enable(u.name);let p=null;if(t?.publish!==!1)try{let h=await this.loadPluginClass(u.packageName);h&&(p=await ei.publish(new h))}catch(h){console.warn("Failed to publish plugin assets:",h)}return{success:!0,pluginName:u.name,version:u.version,published:p}}catch(a){return{success:!1,pluginName:e,version:"0.0.0",published:null,error:a?.message??String(a)}}}async uninstall(e){try{let t=Ds,s=t.get(e);return s?(t.disable(e),await this.runNpmUninstall(s.packageName),!0):!1}catch(t){return console.error("Failed to uninstall plugin:",t),!1}}async runNpmInstall(e){return new Promise((t,s)=>{let{spawn:r}=tt("child_process"),i=r("npm",["install",e],{cwd:process.cwd(),stdio:"inherit"});i.on("close",n=>{n===0?t():s(new Error(`npm install exited with code ${n}`))}),i.on("error",s)})}async runNpmUninstall(e){return new Promise((t,s)=>{let{spawn:r}=tt("child_process"),i=r("npm",["uninstall",e],{cwd:process.cwd(),stdio:"inherit"});i.on("close",n=>{n===0?t():s(new Error(`npm uninstall exited with code ${n}`))}),i.on("error",s)})}async loadPluginClass(e){try{let t=await import(`${e}/plugin`);return t.default||Object.values(t)[0]}catch{try{let t=await import(e);return t.default||Object.values(t)[0]}catch{return null}}}},Sl=x("svelar.pluginInstaller",()=>new si)});import{dirname as jn,join as ri}from"path";import{fileURLToPath as Un,pathToFileURL as Pl}from"url";import{register as Rl}from"module";import{readFileSync as qn,existsSync as El}from"fs";var st=class{commands=new Map;version;constructor(e="0.1.0"){this.version=e}register(e){let t=new e;return this.commands.set(t.name,t),this}add(e){return this.commands.set(e.name,e),this}async run(e=process.argv.slice(2)){let[t,...s]=e;if(!t||t==="--help"||t==="-h"){this.showHelp();return}if(t==="--version"||t==="-v"){console.log(`Svelar v${this.version}`);return}let r=this.commands.get(t);if(r||(console.error(`\x1B[31mUnknown command:\x1B[0m ${t}`),console.log("Run \x1B[36msvelar --help\x1B[0m for available commands."),process.exit(1)),s.includes("--help")||s.includes("-h")){this.showCommandHelp(r);return}let{args:i,flags:n}=this.parseArgs(s,r);try{await r.handle(i,n)}catch(o){let a=o instanceof Error?o.message:String(o);console.error(`\x1B[31mError:\x1B[0m ${a}`),o?.stack&&console.error(o.stack),process.exit(1)}}parseArgs(e,t){let s=[],r={};for(let i of t.flags)i.default!==void 0&&(r[i.name]=i.default);for(let i=0;i<e.length;i++){let n=e[i];if(n.startsWith("--")){let o=n.slice(2),a=o.indexOf("=");if(a!==-1){let p=o.slice(0,a);r[p]=o.slice(a+1);continue}let c=o;t.flags.find(p=>p.name===c)?.type==="boolean"?r[c]=!0:i+1<e.length&&!e[i+1].startsWith("-")?r[c]=e[++i]:r[c]=!0}else if(n.startsWith("-")&&n.length===2){let o=n.slice(1),a=t.flags.find(c=>c.alias===o);a&&(a.type==="boolean"?r[a.name]=!0:i+1<e.length&&(r[a.name]=e[++i]))}else s.push(n)}return{args:s,flags:r}}showCommandHelp(e){if(console.log(`
159
+ `,o=new TextEncoder().encode(r);for(let n of this.subscribers)if(n.userId!==s)try{n.controller.enqueue(o)}catch{}}},Ps=class{config;constructor(e){this.config=e}async send(e,t,s){let r=Array.isArray(e)?e:[e],o=JSON.stringify({name:t,channels:r,data:JSON.stringify(s)}),n=Math.floor(Date.now()/1e3).toString(),i=await this.md5(o),a=["POST",`/apps/${this.config.appId}/events`,[`auth_key=${this.config.key}`,`auth_timestamp=${n}`,"auth_version=1.0",`body_md5=${i}`].join("&")].join(`
160
+ `),c=await this.hmacSha256(this.config.secret,a),u=this.config.useTLS!==!1?"https":"http",p=this.config.host??`api-${this.config.cluster??"mt1"}.pusher.com`,h=this.config.port??(this.config.useTLS!==!1?443:80),m=`${u}://${p}:${h}/apps/${this.config.appId}/events?auth_key=${this.config.key}&auth_timestamp=${n}&auth_version=1.0&body_md5=${i}&auth_signature=${c}`,f=await fetch(m,{method:"POST",headers:{"Content-Type":"application/json"},body:o});if(!f.ok){let y=await f.text();throw new Error(`Pusher API error (${f.status}): ${y}`)}}async authenticate(e,t,s){let r=`${e}:${t}`,o;s&&(o=JSON.stringify(s),r+=`:${o}`);let n=await this.hmacSha256(this.config.secret,r),i=`${this.config.key}:${n}`;return o?{auth:i,channel_data:o}:{auth:i}}get key(){return this.config.key}clientConfig(){let e={key:this.config.key,cluster:this.config.cluster??"mt1"};return this.config.host&&(e.wsHost=this.config.host,e.wsPort=this.config.port??6001,e.wssPort=this.config.port??6001,e.forceTLS=this.config.useTLS??!1,e.enabledTransports=["ws","wss"],e.disableStats=!0),e}async md5(e){let{createHash:t}=await import("crypto");return t("md5").update(e).digest("hex")}async hmacSha256(e,t){let{createHmac:s}=await import("crypto");return s("sha256",e).update(t).digest("hex")}},Jr=class{constructor(e,t,s){this.manager=e;this.eventName=t;this.eventData=s}channels=[];on(...e){return this.channels.push(...e),this}async send(){for(let e of this.channels)await this.manager.sendToChannel(e,this.eventName,this.eventData)}},Vr=class{config={default:"sse",drivers:{sse:{driver:"sse"}}};sseChannels=new Map;channelAuth=new Map;pusherDriver=null;configure(e){this.config=e;let t=Object.values(e.drivers).find(s=>s.driver==="pusher");t&&t.driver==="pusher"&&(this.pusherDriver=new Ps(t))}channel(e,t){if(t){this.channelAuth.set(e,t);return}return this.sseChannels.has(e)||this.sseChannels.set(e,new Wr(e)),this.sseChannels.get(e)}async authorize(e,t){if(Kr(e)==="public")return!0;for(let[r,o]of this.channelAuth){let n=this.matchPattern(r,e);if(n!==null)return await o(t,n)}return!1}async authenticatePusher(e,t,s){if(!this.pusherDriver)throw new Error("Pusher driver is not configured. Call Broadcast.configure() first.");let r=Kr(e);if(r==="public")return!1;let o=await this.authorize(e,s);if(o===!1)return!1;if(r==="presence"){let n=typeof o=="object"?{user_id:o.id??s.id,user_info:o}:{user_id:s.id,user_info:{id:s.id}};return this.pusherDriver.authenticate(t,e,n)}return this.pusherDriver.authenticate(t,e)}event(e,t){return new Jr(this,e,t)}to(e,t){return{send:async(s,r)=>{await this.sendToChannel(e,s,r,t)}}}async sendToChannel(e,t,s,r){let o=this.config.drivers[this.config.default];switch(o?.driver){case"pusher":this.pusherDriver||(this.pusherDriver=new Ps(o)),await this.pusherDriver.send(e,t,s);break;case"log":console.log(`[Broadcast] ${e} \u2192 ${t}:`,JSON.stringify(s));break;default:for(let[,n]of this.sseChannels)n.name===e&&n.send(t,s,r);break}}subscribe(e,t,s){return this.channel(e).stream(t,s)}members(e){let t=this.sseChannels.get(e);return t?t.getMembers():[]}pusher(){if(!this.pusherDriver)throw new Error("Pusher driver is not configured.");return this.pusherDriver}activeChannels(){return[...new Set([...this.sseChannels.values()].map(e=>e.name))]}totalSubscribers(){let e=0;for(let t of this.sseChannels.values())e+=t.subscriberCount();return e}prune(){for(let[e,t]of this.sseChannels)t.subscriberCount()===0&&this.sseChannels.delete(e)}matchPattern(e,t){let s=[],r=e.replace(/[.*+?^${}()|[\]\\]/g,a=>a==="{"||a==="}"?a:`\\${a}`).replace(/\\\{(\w+)\\\}/g,(a,c)=>(s.push(c),"([^.]+)")).replace(/\{(\w+)\}/g,(a,c)=>(s.push(c),"([^.]+)")),o=new RegExp(`^${r}$`),n=t.match(o);if(!n)return null;let i={};for(let a=0;a<s.length;a++)i[s[a]]=n[a+1];return i}},fo=x("svelar.broadcast",()=>new Vr)});function Rs(l,e,t){bo&&bo(l,e,{description:t})}async function yo(l,e={}){let{csrfCookieName:t="XSRF-TOKEN",csrfHeaderName:s="X-CSRF-Token",showToast:r=!0,errorMessages:o={},...n}=e,i=(n.method||"GET").toUpperCase(),a=new Headers(n.headers);if(["POST","PUT","PATCH","DELETE"].includes(i)){let c=Gr(t);c&&a.set(s,c)}n.body&&typeof n.body=="string"&&!a.has("Content-Type")&&a.set("Content-Type","application/json"),a.has("Accept")||a.set("Accept","application/json");try{let c=await fetch(l,{...n,headers:a});return!c.ok&&r&&await gl(c,{...hl,...o}),c}catch(c){throw r&&Rs("error","Network Error","Unable to connect. Check your internet connection."),c}}async function gl(l,e){let t="";try{if((l.headers.get("content-type")??"").includes("application/json")){let n=await l.clone().json();if(t=n.message??"",l.status===422&&n.errors){let i=Object.entries(n.errors).map(([a,c])=>`${a}: ${c.join(", ")}`).slice(0,3).join(`
161
+ `);Rs("warning",e[422]??"Validation Error",i);return}}}catch{}let s=t||e[l.status]||`Error ${l.status}`,r=l.status>=500?"error":l.status===429?"warning":"error";if(l.status===401){Rs("warning",s,"Please sign in to continue.");return}Rs(r,s)}function Gr(l="XSRF-TOKEN"){if(typeof document>"u")return null;let e=l.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),t=document.cookie.match(new RegExp(`(?:^|;\\s*)${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}function wo(l,e){if(!e)return l;let t=new URL(l,"http://localhost");for(let[s,r]of Object.entries(e))r!=null&&t.searchParams.set(s,String(r));return t.pathname+t.search}var hl,bo,Yr,$e,$p,Co=w(()=>{"use strict";hl={400:"Invalid request. Please check your input.",401:"Your session has expired. Please sign in again.",403:"You don't have permission to do this.",404:"The requested resource was not found.",405:"This action is not allowed.",409:"A conflict occurred. Please refresh and try again.",419:"Page expired. Please refresh and try again.",422:"The submitted data is invalid.",429:"Too many requests. Please wait a moment.",500:"Something went wrong on our end.",502:"Service temporarily unavailable. Try again shortly.",503:"Service is under maintenance. Try again shortly.",504:"Request timed out. Please try again."},bo=null;Yr=class l{_baseUrl="";_headers={};_timeout=3e4;_retries=0;_retryDelay=1e3;_query={};constructor(e){e?.baseUrl&&(this._baseUrl=e.baseUrl),e?.headers&&(this._headers={...e.headers}),e?.timeout&&(this._timeout=e.timeout),e?.retries&&(this._retries=e.retries),e?.retryDelay&&(this._retryDelay=e.retryDelay)}clone(){let e=new l;return e._baseUrl=this._baseUrl,e._headers={...this._headers},e._timeout=this._timeout,e._retries=this._retries,e._retryDelay=this._retryDelay,e._query={...this._query},e}baseUrl(e){let t=this.clone();return t._baseUrl=e,t}withHeaders(e){let t=this.clone();return t._headers={...t._headers,...e},t}withToken(e,t="Bearer"){return this.withHeaders({Authorization:`${t} ${e}`})}withBasicAuth(e,t){let s=Buffer.from(`${e}:${t}`).toString("base64");return this.withHeaders({Authorization:`Basic ${s}`})}accept(e){return this.withHeaders({Accept:e})}contentType(e){return this.withHeaders({"Content-Type":e})}timeout(e){let t=this.clone();return t._timeout=e,t}retry(e,t=1e3){let s=this.clone();return s._retries=e,s._retryDelay=t,s}query(e){let t=this.clone();for(let[s,r]of Object.entries(e))r!=null&&(t._query[s]=String(r));return t}async get(e){return this.request("GET",e)}async post(e,t){return this.request("POST",e,t)}async put(e,t){return this.request("PUT",e,t)}async patch(e,t){return this.request("PATCH",e,t)}async delete(e,t){return this.request("DELETE",e,t)}async request(e,t,s){let r=this.buildFullUrl(t),o={...this._headers},n;s!==void 0&&(o["Content-Type"]||(o["Content-Type"]="application/json"),n=typeof s=="string"?s:JSON.stringify(s)),o.Accept||(o.Accept="application/json");let i=null,a=1+this._retries;for(let c=0;c<a;c++){c>0&&await new Promise(u=>setTimeout(u,this._retryDelay*c));try{let u=new AbortController,p=setTimeout(()=>u.abort(),this._timeout),h=await fetch(r,{method:e,headers:o,body:n,signal:u.signal});if(clearTimeout(p),!h.ok&&h.status<500&&c<a-1,!h.ok&&h.status>=500&&c<a-1){i=new $e(`HTTP ${h.status}: ${h.statusText}`,h.status,await h.text());continue}let m=h.headers.get("content-type")??"",f;if(m.includes("application/json")?f=await h.json():f=await h.text(),!h.ok)throw new $e(`HTTP ${h.status}: ${typeof f=="string"?f:JSON.stringify(f)}`,h.status,f);return{data:f,status:h.status,headers:h.headers,ok:!0}}catch(u){if(u instanceof $e)throw u;if(i=u,u.name==="AbortError"&&(i=new $e("Request timed out",0,null)),c>=a-1)break}}throw i??new Error("HTTP request failed")}buildFullUrl(e){let t=this._baseUrl?`${this._baseUrl.replace(/\/+$/,"")}/${e.replace(/^\/+/,"")}`:e,s=Object.entries(this._query);if(s.length>0){let r=new URL(t);for(let[o,n]of s)r.searchParams.set(o,n);t=r.toString()}return t}},$e=class extends Error{constructor(t,s,r){super(t);this.status=s;this.body=r;this.name="HttpRequestError"}},$p=new Yr});function xo(l){let{paraglideMiddleware:e,getTextDirection:t=()=>"ltr",langPlaceholder:s="%lang%",dirPlaceholder:r="%dir%"}=l;return({event:o,resolve:n})=>e(o.request,({request:i,locale:a})=>(o.request=i,n(o,{transformPageChunk:({html:c})=>c.replace(s,a).replace(r,t(a))})))}function So(l){return e=>l.deLocalizeUrl(e.url).pathname}var Po=w(()=>{"use strict"});function Ro(l,e,t={}){return async s=>{let{superValidate:r,fail:o,message:n}=await import("sveltekit-superforms"),{zod:i}=await import("sveltekit-superforms/adapters"),a=await r(s,i(l));if(!a.valid)return o(400,{form:a});try{let c=await e(a.data,s);if(t.redirectTo){let{redirect:u}=await import("@sveltejs/kit");throw u(303,t.redirectTo)}return c??{form:a}}catch(c){if(c?.status>=300&&c?.status<400)throw c;return n(a,t.errorMessage||c.message||"An error occurred",{status:c.status||400})}}}async function Eo(l,e){let{superValidate:t}=await import("sveltekit-superforms"),{zod:s}=await import("sveltekit-superforms/adapters");return t(e??null,s(l))}async function To(l,e){let t=await l.request.formData(),s={};for(let[o,n]of t.entries())s[o]=n;let r=e.safeParse(s);if(!r.success){let{FormValidationError:o}=await Promise.resolve().then(()=>(ws(),io));throw new o(r.error.flatten().fieldErrors)}return r.data}var ko=w(()=>{"use strict";ws()});var $o={};N($o,{Application:()=>ss,AuthManager:()=>ms,AuthenticateMiddleware:()=>Ee,BelongsTo:()=>pe,BelongsToMany:()=>he,Broadcast:()=>fo,Cache:()=>mo,ColumnBuilder:()=>W,Connection:()=>v,Container:()=>Z,Controller:()=>ns,CorsMiddleware:()=>rs,CsrfMiddleware:()=>ve,DatabaseSessionStore:()=>as,ErrorHandler:()=>Te,Event:()=>ge,EventDispatcher:()=>qe,FileSessionStore:()=>ls,ForbiddenError:()=>He,FormAuthorizationError:()=>te,FormRequest:()=>ke,FormValidationError:()=>ee,HasMany:()=>me,HasOne:()=>ue,Hash:()=>cr,HttpError:()=>q,Job:()=>le,Log:()=>gs,LoggingMiddleware:()=>is,Mailable:()=>Je,Mailer:()=>vr,MemorySessionStore:()=>X,Middleware:()=>_,MiddlewareStack:()=>V,Migration:()=>_e,Migrator:()=>Le,Model:()=>es,ModelNotFoundError:()=>bs,NotFoundError:()=>Fe,Notification:()=>Ss,Notifier:()=>ho,OriginMiddleware:()=>be,QueryBuilder:()=>F,Queue:()=>tr,RateLimitMiddleware:()=>fe,RedisSessionStore:()=>cs,RequireAuthMiddleware:()=>ps,Schema:()=>J,Seeder:()=>ts,ServiceProvider:()=>Ue,Session:()=>xe,SessionMiddleware:()=>Se,SignatureMiddleware:()=>os,Storage:()=>ao,TableBuilder:()=>ne,ThrottleMiddleware:()=>ye,UnauthorizedError:()=>Be,ValidationError:()=>Y,abort:()=>ys,abortIf:()=>Yi,abortUnless:()=>Gi,apiFetch:()=>yo,buildUrl:()=>wo,config:()=>Xi,container:()=>Ni,createFormAction:()=>Ro,createI18nHandle:()=>xo,createReroute:()=>So,createSvelarApp:()=>Qi,createSvelarHooks:()=>Ar,env:()=>Zi,getCsrfToken:()=>Gr,loadForm:()=>Eo,resource:()=>Ui,rules:()=>to,schema:()=>Ri,sequence:()=>_r,signJwt:()=>yr,validate:()=>so,validateForm:()=>To,verifyJwt:()=>wr,z:()=>E});var Do=w(()=>{"use strict";Oi();sr();rr();S();zs();Ks();Ii();or();ir();ji();we();qi();Lr();eo();ro();Cr();Pe();nr();Dr();Xt();ws();lo();Tr();po();ce();us();go();vo();Co();Po();ko();Lr()});var Xr={};N(Xr,{PluginRegistry:()=>As});var Zr,As,_s=w(()=>{"use strict";A();Zr=class{plugins=new Map;enabledPlugins=new Set;async discover(){let{join:e}=await import("path"),{existsSync:t,readdirSync:s}=await import("fs"),{readFile:r}=await import("fs/promises"),o=[],n=e(process.cwd(),"node_modules");if(!t(n))return o;let i=async(a,c="")=>{if(t(a))try{let u=s(a,{withFileTypes:!0});for(let p of u){if(!p.isDirectory()||p.name.startsWith("."))continue;if(p.name.startsWith("@")){let y=e(a,p.name);await i(y,p.name+"/");continue}let h=c+p.name,m=p.name.startsWith("svelar-");if(!m)continue;let f=e(a,p.name,"package.json");if(t(f))try{let y=await r(f,"utf-8"),C=JSON.parse(y),$=C.keywords?.includes("svelar-plugin");if(!m&&!$)continue;let T={name:C.name||h,version:C.version||"0.0.0",description:C.description||"",packageName:h,installed:!0,enabled:!1,hasConfig:!!C.svelar?.config,hasMigrations:!!C.svelar?.migrations};o.push(T),this.plugins.set(T.name,T)}catch{}}}catch{}};return await i(n),o}enable(e){let t=this.plugins.get(e);if(!t)throw new Error(`Plugin "${e}" not found in registry.`);this.enabledPlugins.add(e),t.enabled=!0}disable(e){this.enabledPlugins.delete(e);let t=this.plugins.get(e);t&&(t.enabled=!1)}isEnabled(e){return this.enabledPlugins.has(e)}list(){return[...this.plugins.values()]}listEnabled(){return[...this.plugins.values()].filter(e=>this.enabledPlugins.has(e.name))}get(e){return this.plugins.get(e)}register(e){this.plugins.set(e.name,e)}},As=x("svelar.pluginRegistry",()=>new Zr)});var Mo={};N(Mo,{PluginPublisher:()=>ti});var ei,ti,si=w(()=>{"use strict";A();ei=class{async publish(e,t){let{mkdir:s,copyFile:r}=await import("fs/promises"),{join:o,dirname:n}=await import("path"),{existsSync:i}=await import("fs"),a={configs:[],migrations:[],assets:[]},c=e.publishables?.()||{};for(let[u,p]of Object.entries(c))for(let h of p){if(t?.only&&h.type!==t.only)continue;let m=o(process.cwd(),h.dest),f=n(m);if(!(i(m)&&!t?.force))try{await s(f,{recursive:!0}),await r(h.source,m),h.type==="config"?a.configs.push(m):h.type==="migration"?a.migrations.push(m):h.type==="asset"&&a.assets.push(m)}catch(y){console.warn(`Failed to publish ${h.source} to ${m}:`,y)}}return a}async preview(e){let t={configs:[],migrations:[],assets:[]},s=e.publishables?.()||{};for(let[r,o]of Object.entries(s))for(let n of o){let i=tt("path").join(process.cwd(),n.dest);n.type==="config"?t.configs.push(i):n.type==="migration"?t.migrations.push(i):n.type==="asset"&&t.assets.push(i)}return t}},ti=x("svelar.pluginPublisher",()=>new ei)});var Oo={};N(Oo,{PluginInstaller:()=>Sl});var ri,Sl,Io=w(()=>{"use strict";A();_s();si();ri=class{async install(e,t){let{spawn:s}=await import("child_process"),{promisify:r}=await import("util"),{join:o}=await import("path"),{readFile:n}=await import("fs/promises"),{existsSync:i}=await import("fs");try{await this.runNpmInstall(e);let a=As,c=await a.discover(),u;for(let h of c)if(h.packageName===e||h.name===e){u=h;break}if(!u)return{success:!1,pluginName:e,version:"0.0.0",published:null,error:`Plugin not found after installation. Make sure ${e} is a valid Svelar plugin.`};a.enable(u.name);let p=null;if(t?.publish!==!1)try{let h=await this.loadPluginClass(u.packageName);h&&(p=await ti.publish(new h))}catch(h){console.warn("Failed to publish plugin assets:",h)}return{success:!0,pluginName:u.name,version:u.version,published:p}}catch(a){return{success:!1,pluginName:e,version:"0.0.0",published:null,error:a?.message??String(a)}}}async uninstall(e){try{let t=As,s=t.get(e);return s?(t.disable(e),await this.runNpmUninstall(s.packageName),!0):!1}catch(t){return console.error("Failed to uninstall plugin:",t),!1}}async runNpmInstall(e){return new Promise((t,s)=>{let{spawn:r}=tt("child_process"),o=r("npm",["install",e],{cwd:process.cwd(),stdio:"inherit"});o.on("close",n=>{n===0?t():s(new Error(`npm install exited with code ${n}`))}),o.on("error",s)})}async runNpmUninstall(e){return new Promise((t,s)=>{let{spawn:r}=tt("child_process"),o=r("npm",["uninstall",e],{cwd:process.cwd(),stdio:"inherit"});o.on("close",n=>{n===0?t():s(new Error(`npm uninstall exited with code ${n}`))}),o.on("error",s)})}async loadPluginClass(e){try{let t=await import(`${e}/plugin`);return t.default||Object.values(t)[0]}catch{try{let t=await import(e);return t.default||Object.values(t)[0]}catch{return null}}}},Sl=x("svelar.pluginInstaller",()=>new ri)});import{dirname as jo,join as ii}from"path";import{fileURLToPath as Uo,pathToFileURL as Pl}from"url";import{register as Rl}from"module";import{readFileSync as qo,existsSync as El}from"fs";var st=class{commands=new Map;version;constructor(e="0.1.0"){this.version=e}register(e){let t=new e;return this.commands.set(t.name,t),this}add(e){return this.commands.set(e.name,e),this}async run(e=process.argv.slice(2)){let[t,...s]=e;if(!t||t==="--help"||t==="-h"){this.showHelp();return}if(t==="--version"||t==="-v"){console.log(`Svelar v${this.version}`);return}let r=this.commands.get(t);if(r||(console.error(`\x1B[31mUnknown command:\x1B[0m ${t}`),console.log("Run \x1B[36msvelar --help\x1B[0m for available commands."),process.exit(1)),s.includes("--help")||s.includes("-h")){this.showCommandHelp(r);return}let{args:o,flags:n}=this.parseArgs(s,r);try{await r.handle(o,n)}catch(i){let a=i instanceof Error?i.message:String(i);console.error(`\x1B[31mError:\x1B[0m ${a}`),i?.stack&&console.error(i.stack),process.exit(1)}}parseArgs(e,t){let s=[],r={};for(let o of t.flags)o.default!==void 0&&(r[o.name]=o.default);for(let o=0;o<e.length;o++){let n=e[o];if(n.startsWith("--")){let i=n.slice(2),a=i.indexOf("=");if(a!==-1){let p=i.slice(0,a);r[p]=i.slice(a+1);continue}let c=i;t.flags.find(p=>p.name===c)?.type==="boolean"?r[c]=!0:o+1<e.length&&!e[o+1].startsWith("-")?r[c]=e[++o]:r[c]=!0}else if(n.startsWith("-")&&n.length===2){let i=n.slice(1),a=t.flags.find(c=>c.alias===i);a&&(a.type==="boolean"?r[a.name]=!0:o+1<e.length&&(r[a.name]=e[++o]))}else s.push(n)}return{args:s,flags:r}}showCommandHelp(e){if(console.log(`
162
162
  \x1B[33mDescription:\x1B[0m`),console.log(` ${e.description}
163
163
  `),console.log("\x1B[33mUsage:\x1B[0m"),console.log(` svelar ${e.name} [options]
164
- `),e.flags.length>0){console.log("\x1B[33mOptions:\x1B[0m");for(let t of e.flags){let s=t.alias?`-${t.alias}, `:" ",r=`--${t.name}`,i=24-s.length-r.length;console.log(` ${s}${r}${" ".repeat(Math.max(1,i))}${t.description}`)}console.log()}}showHelp(){console.log(`
164
+ `),e.flags.length>0){console.log("\x1B[33mOptions:\x1B[0m");for(let t of e.flags){let s=t.alias?`-${t.alias}, `:" ",r=`--${t.name}`,o=24-s.length-r.length;console.log(` ${s}${r}${" ".repeat(Math.max(1,o))}${t.description}`)}console.log()}}showHelp(){console.log(`
165
165
  \x1B[36m ____ _
166
166
  / ___|_ _____| | __ _ _ __
167
167
  \\___ \\ \\ / / _ \\ |/ _\` | '__|
@@ -172,7 +172,7 @@ id: ${Date.now()}
172
172
  svelar <command> [arguments] [options]
173
173
 
174
174
  \x1B[33mAvailable Commands:\x1B[0m`);let e=new Map;for(let[,t]of this.commands){let s=t.name.includes(":")?t.name.split(":")[0]:"general";e.has(s)||e.set(s,[]),e.get(s).push(t)}for(let[t,s]of e){console.log(`
175
- \x1B[32m${t}\x1B[0m`);for(let r of s){let i=30-r.name.length;console.log(` \x1B[36m${r.name}\x1B[0m${" ".repeat(Math.max(1,i))}${r.description}`)}}console.log()}};import{existsSync as Bn}from"fs";import{join as De}from"path";var g=class{arguments=[];flags=[];async bootstrap(){let{join:e}=await import("path"),{existsSync:t,readFileSync:s}=await import("fs"),{Connection:r}=await Promise.resolve().then(()=>(S(),P)),i=process.cwd();try{r.getDriver();return}catch{}let n=e(i,"svelar.database.json");if(t(n))try{let c=s(n,"utf-8"),u=JSON.parse(c);r.configure(u),this.info("Database configured from svelar.database.json");return}catch(c){this.warn(`Failed to parse svelar.database.json: ${String(c?.message??c)}`)}let o=process.env.DB_DRIVER??"sqlite",a=process.env.DB_PATH??"database.db";r.configure({default:o,connections:{[o]:{driver:o,filename:a,host:process.env.DB_HOST,port:process.env.DB_PORT?parseInt(process.env.DB_PORT):void 0,database:process.env.DB_NAME,user:process.env.DB_USER,password:process.env.DB_PASSWORD}}}),this.info(`Using ${o} database${o==="sqlite"?`: ${a}`:""}`)}log(e){console.log(e)}info(e){console.log(`\x1B[34mINFO\x1B[0m ${e}`)}success(e){console.log(`\x1B[32m\u2713\x1B[0m ${e}`)}warn(e){console.log(`\x1B[33mWARN\x1B[0m ${e}`)}error(e){console.error(`\x1B[31mERROR\x1B[0m ${e}`)}table(e,t){let s=e.map((n,o)=>Math.max(n.length,...t.map(a=>(a[o]??"").length))),r=s.map(n=>"\u2500".repeat(n+2)).join("\u253C"),i=n=>n.map((o,a)=>` ${(o??"").padEnd(s[a])} `).join("\u2502");console.log(i(e)),console.log(r);for(let n of t)console.log(i(n))}newLine(){console.log()}isDDD(){return Bn(De(process.cwd(),"src","lib","modules"))}sharedDir(e){return this.isDDD()?De(process.cwd(),"src","lib","shared",e):De(process.cwd(),"src","lib",e)}moduleDir(e,t){return this.isDDD()?De(process.cwd(),"src","lib","modules",e):De(process.cwd(),"src","lib",t)}};import{writeFileSync as Is,mkdirSync as js,existsSync as Hn}from"fs";import{join as rt}from"path";var it=class extends g{name="make:model";description="Create a new model class";arguments=["name"];flags=[{name:"migration",alias:"m",description:"Also create a migration",type:"boolean"},{name:"controller",alias:"c",description:"Also create a controller",type:"boolean"},{name:"resource",alias:"r",description:"Create a resource controller",type:"boolean"},{name:"all",alias:"a",description:"Create model, migration, and controller",type:"boolean"},{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a model name.");return}let r=this.toSnakeCase(this.pluralize(s)),i=t.module||this.toSnakeCase(this.pluralize(s));!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${i}" as module. Consider: --module ${i}`);let n=this.moduleDir(i,"models");js(n,{recursive:!0});let o=rt(n,`${s}.ts`);if(Hn(o)){this.warn(`Model ${s} already exists at ${o}`);return}let a=`import { Model } from '@beeblock/svelar/orm';
175
+ \x1B[32m${t}\x1B[0m`);for(let r of s){let o=30-r.name.length;console.log(` \x1B[36m${r.name}\x1B[0m${" ".repeat(Math.max(1,o))}${r.description}`)}}console.log()}};import{existsSync as Bo}from"fs";import{join as De}from"path";var g=class{arguments=[];flags=[];async bootstrap(){let{join:e}=await import("path"),{existsSync:t,readFileSync:s}=await import("fs"),{Connection:r}=await Promise.resolve().then(()=>(S(),P)),o=process.cwd();try{r.getDriver();return}catch{}let n=e(o,"svelar.database.json");if(t(n))try{let c=s(n,"utf-8"),u=JSON.parse(c);r.configure(u),this.info("Database configured from svelar.database.json");return}catch(c){this.warn(`Failed to parse svelar.database.json: ${String(c?.message??c)}`)}let i=process.env.DB_DRIVER??"sqlite",a=process.env.DB_PATH??"database.db";r.configure({default:i,connections:{[i]:{driver:i,filename:a,host:process.env.DB_HOST,port:process.env.DB_PORT?parseInt(process.env.DB_PORT):void 0,database:process.env.DB_NAME,user:process.env.DB_USER,password:process.env.DB_PASSWORD}}}),this.info(`Using ${i} database${i==="sqlite"?`: ${a}`:""}`)}log(e){console.log(e)}info(e){console.log(`\x1B[34mINFO\x1B[0m ${e}`)}success(e){console.log(`\x1B[32m\u2713\x1B[0m ${e}`)}warn(e){console.log(`\x1B[33mWARN\x1B[0m ${e}`)}error(e){console.error(`\x1B[31mERROR\x1B[0m ${e}`)}table(e,t){let s=e.map((n,i)=>Math.max(n.length,...t.map(a=>(a[i]??"").length))),r=s.map(n=>"\u2500".repeat(n+2)).join("\u253C"),o=n=>n.map((i,a)=>` ${(i??"").padEnd(s[a])} `).join("\u2502");console.log(o(e)),console.log(r);for(let n of t)console.log(o(n))}newLine(){console.log()}isDDD(){return Bo(De(process.cwd(),"src","lib","modules"))}sharedDir(e){return this.isDDD()?De(process.cwd(),"src","lib","shared",e):De(process.cwd(),"src","lib",e)}moduleDir(e,t){return this.isDDD()?De(process.cwd(),"src","lib","modules",e):De(process.cwd(),"src","lib",t)}};import{writeFileSync as js,mkdirSync as Us,existsSync as Ho}from"fs";import{join as rt}from"path";var it=class extends g{name="make:model";description="Create a new model class";arguments=["name"];flags=[{name:"migration",alias:"m",description:"Also create a migration",type:"boolean"},{name:"controller",alias:"c",description:"Also create a controller",type:"boolean"},{name:"resource",alias:"r",description:"Create a resource controller",type:"boolean"},{name:"all",alias:"a",description:"Create model, migration, and controller",type:"boolean"},{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a model name.");return}let r=this.toSnakeCase(this.pluralize(s)),o=t.module||this.toSnakeCase(this.pluralize(s));!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${o}" as module. Consider: --module ${o}`);let n=this.moduleDir(o,"models");Us(n,{recursive:!0});let i=rt(n,`${s}.ts`);if(Ho(i)){this.warn(`Model ${s} already exists at ${i}`);return}let a=`import { Model } from '@beeblock/svelar/orm';
176
176
 
177
177
  export class ${s} extends Model {
178
178
  static table = '${r}';
@@ -189,7 +189,7 @@ export class ${s} extends Model {
189
189
  // return this.hasMany(Post, 'user_id');
190
190
  // }
191
191
  }
192
- `;Is(o,a);let c=this.isDDD()?`src/lib/modules/${i}`:"src/lib/models";if(this.success(`Model created: ${c}/${s}.ts`),t.migration||t.all){let p=`${new Date().toISOString().replace(/[^0-9]/g,"").slice(0,14)}_create_${r}_table`,h=rt(process.cwd(),"src","lib","database","migrations");js(h,{recursive:!0});let m=`import { Migration } from '@beeblock/svelar/database';
192
+ `;js(i,a);let c=this.isDDD()?`src/lib/modules/${o}`:"src/lib/models";if(this.success(`Model created: ${c}/${s}.ts`),t.migration||t.all){let p=`${new Date().toISOString().replace(/[^0-9]/g,"").slice(0,14)}_create_${r}_table`,h=rt(process.cwd(),"src","lib","database","migrations");Us(h,{recursive:!0});let m=`import { Migration } from '@beeblock/svelar/database';
193
193
 
194
194
  export default class Create${s}sTable extends Migration {
195
195
  async up() {
@@ -206,7 +206,7 @@ export default class Create${s}sTable extends Migration {
206
206
  await this.schema.dropTable('${r}');
207
207
  }
208
208
  }
209
- `;Is(rt(h,`${p}.ts`),m),this.success(`Migration created: src/lib/database/migrations/${p}.ts`)}if(t.controller||t.resource||t.all){let u=`${s}Controller`,p=this.moduleDir(i,"controllers");js(p,{recursive:!0});let h=t.resource||t.all,m=this.isDDD()?`./${s}.js`:`../models/${s}.js`,f=h?this.generateResourceController(s,u,m):this.generateBasicController(s,u,m);Is(rt(p,`${u}.ts`),f);let y=this.isDDD()?`src/lib/modules/${i}`:"src/lib/controllers";this.success(`Controller created: ${y}/${u}.ts`)}}generateResourceController(e,t,s=`./${e}.js`){return`import { Controller, type RequestEvent } from '@beeblock/svelar/routing';
209
+ `;js(rt(h,`${p}.ts`),m),this.success(`Migration created: src/lib/database/migrations/${p}.ts`)}if(t.controller||t.resource||t.all){let u=`${s}Controller`,p=this.moduleDir(o,"controllers");Us(p,{recursive:!0});let h=t.resource||t.all,m=this.isDDD()?`./${s}.js`:`../models/${s}.js`,f=h?this.generateResourceController(s,u,m):this.generateBasicController(s,u,m);js(rt(p,`${u}.ts`),f);let y=this.isDDD()?`src/lib/modules/${o}`:"src/lib/controllers";this.success(`Controller created: ${y}/${u}.ts`)}}generateResourceController(e,t,s=`./${e}.js`){return`import { Controller, type RequestEvent } from '@beeblock/svelar/routing';
210
210
  import { z } from '@beeblock/svelar/validation';
211
211
  import { ${e} } from '${s}';
212
212
 
@@ -258,9 +258,9 @@ export class ${t} extends Controller {
258
258
  return this.json(items);
259
259
  }
260
260
  }
261
- `}toSnakeCase(e){return e.replace(/([A-Z])/g,"_$1").toLowerCase().replace(/^_/,"")}pluralize(e){return e.endsWith("y")?e.slice(0,-1)+"ies":e.endsWith("s")||e.endsWith("x")||e.endsWith("z")||e.endsWith("ch")||e.endsWith("sh")?e+"es":e+"s"}};import{writeFileSync as zn,mkdirSync as Kn}from"fs";import{join as ii}from"path";var nt=class extends g{name="make:migration";description="Create a new migration file";arguments=["name"];flags=[{name:"create",description:"Table to create",type:"string"},{name:"table",description:"Table to modify",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a migration name (e.g. create_users_table).");return}let r=ii(process.cwd(),"src","lib","database","migrations");Kn(r,{recursive:!0});let n=`${new Date().toISOString().replace(/[^0-9]/g,"").slice(0,14)}_${s}`,o=this.toPascalCase(s),a=t.create??this.detectTableName(s,"create"),c=t.table??this.detectTableName(s,"add"),u;a?u=`import { Migration } from '@beeblock/svelar/database';
261
+ `}toSnakeCase(e){return e.replace(/([A-Z])/g,"_$1").toLowerCase().replace(/^_/,"")}pluralize(e){return e.endsWith("y")?e.slice(0,-1)+"ies":e.endsWith("s")||e.endsWith("x")||e.endsWith("z")||e.endsWith("ch")||e.endsWith("sh")?e+"es":e+"s"}};import{writeFileSync as zo,mkdirSync as Ko}from"fs";import{join as oi}from"path";var ot=class extends g{name="make:migration";description="Create a new migration file";arguments=["name"];flags=[{name:"create",description:"Table to create",type:"string"},{name:"table",description:"Table to modify",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a migration name (e.g. create_users_table).");return}let r=oi(process.cwd(),"src","lib","database","migrations");Ko(r,{recursive:!0});let n=`${new Date().toISOString().replace(/[^0-9]/g,"").slice(0,14)}_${s}`,i=this.toPascalCase(s),a=t.create??this.detectTableName(s,"create"),c=t.table??this.detectTableName(s,"add"),u;a?u=`import { Migration } from '@beeblock/svelar/database';
262
262
 
263
- export default class ${o} extends Migration {
263
+ export default class ${i} extends Migration {
264
264
  async up() {
265
265
  await this.schema.createTable('${a}', (table) => {
266
266
  table.increments('id');
@@ -275,7 +275,7 @@ export default class ${o} extends Migration {
275
275
  }
276
276
  `:c?u=`import { Migration } from '@beeblock/svelar/database';
277
277
 
278
- export default class ${o} extends Migration {
278
+ export default class ${i} extends Migration {
279
279
  async up() {
280
280
  await this.schema.addColumn('${c}', (table) => {
281
281
  // Add new columns here
@@ -289,7 +289,7 @@ export default class ${o} extends Migration {
289
289
  }
290
290
  `:u=`import { Migration } from '@beeblock/svelar/database';
291
291
 
292
- export default class ${o} extends Migration {
292
+ export default class ${i} extends Migration {
293
293
  async up() {
294
294
  // Write your migration here
295
295
  }
@@ -298,7 +298,7 @@ export default class ${o} extends Migration {
298
298
  // Reverse the migration
299
299
  }
300
300
  }
301
- `,zn(ii(r,`${n}.ts`),u),this.success(`Migration created: src/lib/database/migrations/${n}.ts`)}detectTableName(e,t){let s=e.match(new RegExp(`${t}_(.+?)_table`));return s?s[1]:null}toPascalCase(e){return e.split("_").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join("")}};import{writeFileSync as Wn,mkdirSync as Jn,existsSync as Vn}from"fs";import{join as Yn}from"path";var ot=class extends g{name="make:controller";description="Create a new controller class";arguments=["name"];flags=[{name:"resource",alias:"r",description:"Create a resource controller with CRUD methods",type:"boolean"},{name:"model",alias:"m",description:"Model name for resource controller",type:"string"},{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a controller name.");return}let r=s.endsWith("Controller")?s:`${s}Controller`,i=r.replace(/Controller$/,""),n=t.module||i.toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${n}" as module. Consider: --module ${n}`);let o=this.moduleDir(n,"controllers");Jn(o,{recursive:!0});let a=Yn(o,`${r}.ts`);if(Vn(a)){this.warn(`Controller ${r} already exists.`);return}let c=t.model?this.isDDD()?`./${t.model}.js`:`../models/${t.model}.js`:void 0,u=t.resource?this.generateResourceController(r,t.model,c):this.generateBasicController(r);Wn(a,u);let p=this.isDDD()?`src/lib/modules/${n}`:"src/lib/controllers";this.success(`Controller created: ${p}/${r}.ts`)}generateResourceController(e,t,s){return`import { Controller, type RequestEvent } from '@beeblock/svelar/routing';
301
+ `,zo(oi(r,`${n}.ts`),u),this.success(`Migration created: src/lib/database/migrations/${n}.ts`)}detectTableName(e,t){let s=e.match(new RegExp(`${t}_(.+?)_table`));return s?s[1]:null}toPascalCase(e){return e.split("_").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join("")}};import{writeFileSync as Wo,mkdirSync as Jo,existsSync as Vo}from"fs";import{join as Yo}from"path";var nt=class extends g{name="make:controller";description="Create a new controller class";arguments=["name"];flags=[{name:"resource",alias:"r",description:"Create a resource controller with CRUD methods",type:"boolean"},{name:"model",alias:"m",description:"Model name for resource controller",type:"string"},{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a controller name.");return}let r=s.endsWith("Controller")?s:`${s}Controller`,o=r.replace(/Controller$/,""),n=t.module||o.toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${n}" as module. Consider: --module ${n}`);let i=this.moduleDir(n,"controllers");Jo(i,{recursive:!0});let a=Yo(i,`${r}.ts`);if(Vo(a)){this.warn(`Controller ${r} already exists.`);return}let c=t.model?this.isDDD()?`./${t.model}.js`:`../models/${t.model}.js`:void 0,u=t.resource?this.generateResourceController(r,t.model,c):this.generateBasicController(r);Wo(a,u);let p=this.isDDD()?`src/lib/modules/${n}`:"src/lib/controllers";this.success(`Controller created: ${p}/${r}.ts`)}generateResourceController(e,t,s){return`import { Controller, type RequestEvent } from '@beeblock/svelar/routing';
302
302
  import { z } from '@beeblock/svelar/validation';
303
303
  ${t&&s?`import { ${t} } from '${s}';
304
304
  `:""}
@@ -344,7 +344,7 @@ export class ${e} extends Controller {
344
344
  return this.json({ message: 'Hello from ${e}' });
345
345
  }
346
346
  }
347
- `}};import{writeFileSync as Qn,mkdirSync as Gn,existsSync as Zn}from"fs";import{join as Xn}from"path";var at=class extends g{name="make:middleware";description="Create a new middleware class";arguments=["name"];flags=[];async handle(e){let t=e[0];if(!t){this.error("Please provide a middleware name.");return}let s=t.endsWith("Middleware")?t:`${t}Middleware`,r=this.sharedDir("middleware");Gn(r,{recursive:!0});let i=Xn(r,`${s}.ts`);if(Zn(i)){this.warn(`Middleware ${s} already exists.`);return}let n=`import { Middleware, type MiddlewareContext, type NextFunction } from '@beeblock/svelar/middleware';
347
+ `}};import{writeFileSync as Go,mkdirSync as Qo,existsSync as Zo}from"fs";import{join as Xo}from"path";var at=class extends g{name="make:middleware";description="Create a new middleware class";arguments=["name"];flags=[];async handle(e){let t=e[0];if(!t){this.error("Please provide a middleware name.");return}let s=t.endsWith("Middleware")?t:`${t}Middleware`,r=this.sharedDir("middleware");Qo(r,{recursive:!0});let o=Xo(r,`${s}.ts`);if(Zo(o)){this.warn(`Middleware ${s} already exists.`);return}let n=`import { Middleware, type MiddlewareContext, type NextFunction } from '@beeblock/svelar/middleware';
348
348
 
349
349
  export class ${s} extends Middleware {
350
350
  async handle(ctx: MiddlewareContext, next: NextFunction): Promise<Response | void> {
@@ -357,7 +357,7 @@ export class ${s} extends Middleware {
357
357
  return response;
358
358
  }
359
359
  }
360
- `;Qn(i,n);let o=this.isDDD()?`src/lib/shared/middleware/${s}.ts`:`src/lib/middleware/${s}.ts`;this.success(`Middleware created: ${o}`)}};import{writeFileSync as eo,mkdirSync as to,existsSync as so}from"fs";import{join as ro}from"path";var lt=class extends g{name="make:provider";description="Create a new service provider class";arguments=["name"];flags=[];async handle(e){let t=e[0];if(!t){this.error("Please provide a provider name.");return}let s=t.endsWith("ServiceProvider")?t:`${t}ServiceProvider`,r=this.sharedDir("providers");to(r,{recursive:!0});let i=ro(r,`${s}.ts`);if(so(i)){this.warn(`Provider ${s} already exists.`);return}let n=`import { ServiceProvider } from '@beeblock/svelar/container';
360
+ `;Go(o,n);let i=this.isDDD()?`src/lib/shared/middleware/${s}.ts`:`src/lib/middleware/${s}.ts`;this.success(`Middleware created: ${i}`)}};import{writeFileSync as en,mkdirSync as tn,existsSync as sn}from"fs";import{join as rn}from"path";var lt=class extends g{name="make:provider";description="Create a new service provider class";arguments=["name"];flags=[];async handle(e){let t=e[0];if(!t){this.error("Please provide a provider name.");return}let s=t.endsWith("ServiceProvider")?t:`${t}ServiceProvider`,r=this.sharedDir("providers");tn(r,{recursive:!0});let o=rn(r,`${s}.ts`);if(sn(o)){this.warn(`Provider ${s} already exists.`);return}let n=`import { ServiceProvider } from '@beeblock/svelar/container';
361
361
  import type { Container } from '@beeblock/svelar/container';
362
362
 
363
363
  export class ${s} extends ServiceProvider {
@@ -378,7 +378,7 @@ export class ${s} extends ServiceProvider {
378
378
  // Initialization logic here
379
379
  }
380
380
  }
381
- `;eo(i,n);let o=this.isDDD()?`src/lib/shared/providers/${s}.ts`:`src/lib/providers/${s}.ts`;this.success(`Provider created: ${o}`)}};import{writeFileSync as io,mkdirSync as no,existsSync as oo}from"fs";import{join as ni}from"path";var ct=class extends g{name="make:seeder";description="Create a new database seeder class";arguments=["name"];flags=[];async handle(e){let t=e[0];if(!t){this.error("Please provide a seeder name.");return}let s=t.endsWith("Seeder")?t:`${t}Seeder`,r=ni(process.cwd(),"src","lib","database","seeders");no(r,{recursive:!0});let i=ni(r,`${s}.ts`);if(oo(i)){this.warn(`Seeder ${s} already exists.`);return}let n=`import { Seeder } from '@beeblock/svelar/database';
381
+ `;en(o,n);let i=this.isDDD()?`src/lib/shared/providers/${s}.ts`:`src/lib/providers/${s}.ts`;this.success(`Provider created: ${i}`)}};import{writeFileSync as on,mkdirSync as nn,existsSync as an}from"fs";import{join as ni}from"path";var ct=class extends g{name="make:seeder";description="Create a new database seeder class";arguments=["name"];flags=[];async handle(e){let t=e[0];if(!t){this.error("Please provide a seeder name.");return}let s=t.endsWith("Seeder")?t:`${t}Seeder`,r=ni(process.cwd(),"src","lib","database","seeders");nn(r,{recursive:!0});let o=ni(r,`${s}.ts`);if(an(o)){this.warn(`Seeder ${s} already exists.`);return}let n=`import { Seeder } from '@beeblock/svelar/database';
382
382
 
383
383
  export class ${s} extends Seeder {
384
384
  async run(): Promise<void> {
@@ -387,8 +387,8 @@ export class ${s} extends Seeder {
387
387
  // await User.create({ name: 'Admin', email: 'admin@example.com' });
388
388
  }
389
389
  }
390
- `;io(i,n),this.success(`Seeder created: src/lib/database/seeders/${s}.ts`)}};import{writeFileSync as ao,mkdirSync as lo,existsSync as co}from"fs";import{join as uo}from"path";var dt=class extends g{name="make:service";description="Create a new service class";arguments=["name"];flags=[{name:"crud",description:"Create a CRUD service with model",type:"boolean"},{name:"model",alias:"m",description:"Model name for CRUD service",type:"string"},{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a service name.");return}let r=s.endsWith("Service")?s:`${s}Service`,i=r.replace(/Service$/,""),n=t.module||i.toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${n}" as module. Consider: --module ${n}`);let o=this.moduleDir(n,"services");lo(o,{recursive:!0});let a=uo(o,`${r}.ts`);if(co(a)){this.warn(`Service ${r} already exists.`);return}let c=t.model?this.isDDD()?`./${t.model}.js`:`../models/${t.model}.js`:void 0,u=t.crud?this.generateCrudService(r,t.model,c):this.generateBasicService(r);ao(a,u);let p=this.isDDD()?`src/lib/modules/${n}`:"src/lib/services";this.success(`Service created: ${p}/${r}.ts`)}generateCrudService(e,t,s){let r=t||"Model",i=s||`./${r}.js`;return`import { CrudService, type ServiceResult } from '@beeblock/svelar/services';
391
- import { ${r} } from '${i}';
390
+ `;on(o,n),this.success(`Seeder created: src/lib/database/seeders/${s}.ts`)}};import{writeFileSync as ln,mkdirSync as cn,existsSync as dn}from"fs";import{join as un}from"path";var dt=class extends g{name="make:service";description="Create a new service class";arguments=["name"];flags=[{name:"crud",description:"Create a CRUD service with model",type:"boolean"},{name:"model",alias:"m",description:"Model name for CRUD service",type:"string"},{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a service name.");return}let r=s.endsWith("Service")?s:`${s}Service`,o=r.replace(/Service$/,""),n=t.module||o.toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${n}" as module. Consider: --module ${n}`);let i=this.moduleDir(n,"services");cn(i,{recursive:!0});let a=un(i,`${r}.ts`);if(dn(a)){this.warn(`Service ${r} already exists.`);return}let c=t.model?this.isDDD()?`./${t.model}.js`:`../models/${t.model}.js`:void 0,u=t.crud?this.generateCrudService(r,t.model,c):this.generateBasicService(r);ln(a,u);let p=this.isDDD()?`src/lib/modules/${n}`:"src/lib/services";this.success(`Service created: ${p}/${r}.ts`)}generateCrudService(e,t,s){let r=t||"Model",o=s||`./${r}.js`;return`import { CrudService, type ServiceResult } from '@beeblock/svelar/services';
391
+ import { ${r} } from '${o}';
392
392
 
393
393
  export class ${e} extends CrudService<${r}> {
394
394
  protected model = ${r};
@@ -412,7 +412,7 @@ export class ${e} extends Service {
412
412
  }
413
413
  }
414
414
  }
415
- `}};import{writeFileSync as mo,mkdirSync as po,existsSync as ho}from"fs";import{join as go}from"path";var ut=class extends g{name="make:repository";description="Create a new repository class";arguments=["name"];flags=[{name:"model",alias:"m",description:"Model name for the repository",type:"string"},{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a repository name.");return}let r=s.endsWith("Repository")?s:`${s}Repository`,i=r.replace(/Repository$/,""),n=t.module||i.toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${n}" as module. Consider: --module ${n}`);let o=this.moduleDir(n,"repositories");po(o,{recursive:!0});let a=go(o,`${r}.ts`);if(ho(a)){this.warn(`Repository ${r} already exists.`);return}let c=t.model||this.inferModelName(r),u=this.isDDD()?`./${c}.js`:`../models/${c}.js`,p=`import { Repository } from '@beeblock/svelar/repositories';
415
+ `}};import{writeFileSync as mn,mkdirSync as pn,existsSync as hn}from"fs";import{join as gn}from"path";var ut=class extends g{name="make:repository";description="Create a new repository class";arguments=["name"];flags=[{name:"model",alias:"m",description:"Model name for the repository",type:"string"},{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a repository name.");return}let r=s.endsWith("Repository")?s:`${s}Repository`,o=r.replace(/Repository$/,""),n=t.module||o.toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${n}" as module. Consider: --module ${n}`);let i=this.moduleDir(n,"repositories");pn(i,{recursive:!0});let a=gn(i,`${r}.ts`);if(hn(a)){this.warn(`Repository ${r} already exists.`);return}let c=t.model||this.inferModelName(r),u=this.isDDD()?`./${c}.js`:`../models/${c}.js`,p=`import { Repository } from '@beeblock/svelar/repositories';
416
416
  import { ${c} } from '${u}';
417
417
 
418
418
  export class ${r} extends Repository<${c}> {
@@ -429,7 +429,7 @@ export class ${r} extends Repository<${c}> {
429
429
  // return ${c}.where('active', true).orderBy('name').get();
430
430
  // }
431
431
  }
432
- `;mo(a,p);let h=this.isDDD()?`src/lib/modules/${n}`:"src/lib/repositories";this.success(`Repository created: ${h}/${r}.ts`)}inferModelName(e){return e.replace("Repository","")||"Model"}};import{writeFileSync as fo,mkdirSync as vo,existsSync as bo}from"fs";import{join as yo}from"path";var mt=class extends g{name="make:action";description="Create a new action class";arguments=["name"];flags=[{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide an action name.");return}let r=s.endsWith("Action")?s:`${s}Action`,i=r.replace(/Action$/,""),n=t.module||i.toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${n}" as module. Consider: --module ${n}`);let o=this.moduleDir(n,"actions");vo(o,{recursive:!0});let a=yo(o,`${r}.ts`);if(bo(a)){this.warn(`Action ${r} already exists.`);return}let c=`import { Action } from '@beeblock/svelar/actions';
432
+ `;mn(a,p);let h=this.isDDD()?`src/lib/modules/${n}`:"src/lib/repositories";this.success(`Repository created: ${h}/${r}.ts`)}inferModelName(e){return e.replace("Repository","")||"Model"}};import{writeFileSync as fn,mkdirSync as vn,existsSync as bn}from"fs";import{join as yn}from"path";var mt=class extends g{name="make:action";description="Create a new action class";arguments=["name"];flags=[{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide an action name.");return}let r=s.endsWith("Action")?s:`${s}Action`,o=r.replace(/Action$/,""),n=t.module||o.toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${n}" as module. Consider: --module ${n}`);let i=this.moduleDir(n,"actions");vn(i,{recursive:!0});let a=yn(i,`${r}.ts`);if(bn(a)){this.warn(`Action ${r} already exists.`);return}let c=`import { Action } from '@beeblock/svelar/actions';
433
433
 
434
434
  interface ${r}Input {
435
435
  // Define input type
@@ -445,7 +445,7 @@ export class ${r} extends Action<${r}Input, ${r}Output> {
445
445
  throw new Error('Not implemented');
446
446
  }
447
447
  }
448
- `;fo(a,c);let u=this.isDDD()?`src/lib/modules/${n}`:"src/lib/actions";this.success(`Action created: ${u}/${r}.ts`)}};import{writeFileSync as wo,mkdirSync as Co,existsSync as xo}from"fs";import{join as So}from"path";var pt=class extends g{name="make:request";description="Create a new FormRequest validation class";arguments=["name"];flags=[{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a request name.");return}let r=s.endsWith("Request")?s:`${s}Request`,i=r.replace(/Request$/,""),n=t.module||i.toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${n}" as module. Consider: --module ${n}`);let o=this.moduleDir(n,"dtos");Co(o,{recursive:!0});let a=So(o,`${r}.ts`);if(xo(a)){this.warn(`Request ${r} already exists.`);return}let c=`import { FormRequest } from '@beeblock/svelar/routing';
448
+ `;fn(a,c);let u=this.isDDD()?`src/lib/modules/${n}`:"src/lib/actions";this.success(`Action created: ${u}/${r}.ts`)}};import{writeFileSync as wn,mkdirSync as Cn,existsSync as xn}from"fs";import{join as Sn}from"path";var pt=class extends g{name="make:request";description="Create a new FormRequest validation class";arguments=["name"];flags=[{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a request name.");return}let r=s.endsWith("Request")?s:`${s}Request`,o=r.replace(/Request$/,""),n=t.module||o.toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${n}" as module. Consider: --module ${n}`);let i=this.moduleDir(n,"dtos");Cn(i,{recursive:!0});let a=Sn(i,`${r}.ts`);if(xn(a)){this.warn(`Request ${r} already exists.`);return}let c=`import { FormRequest } from '@beeblock/svelar/routing';
449
449
  import { z } from '@beeblock/svelar/validation';
450
450
 
451
451
  export class ${r} extends FormRequest {
@@ -474,7 +474,7 @@ export class ${r} extends FormRequest {
474
474
  return data;
475
475
  }
476
476
  }
477
- `;wo(a,c);let u=this.isDDD()?`src/lib/modules/${n}`:"src/lib/dtos";this.success(`Request created: ${u}/${r}.ts`)}};import{writeFileSync as Po,mkdirSync as Ro,existsSync as Eo}from"fs";import{join as To}from"path";var ht=class extends g{name="make:plugin";description="Create a new plugin class";arguments=["name"];flags=[];async handle(e){let t=e[0];if(!t){this.error("Please provide a plugin name.");return}let s=t.endsWith("Plugin")?t:`${t}Plugin`,r=this.sharedDir("plugins");Ro(r,{recursive:!0});let i=To(r,`${s}.ts`);if(Eo(i)){this.warn(`Plugin ${s} already exists.`);return}let n=s.replace(/([A-Z])/g,"-$1").toLowerCase().replace(/^-/,""),o=`import { Plugin } from '@beeblock/svelar/plugins';
477
+ `;wn(a,c);let u=this.isDDD()?`src/lib/modules/${n}`:"src/lib/dtos";this.success(`Request created: ${u}/${r}.ts`)}};import{writeFileSync as Pn,mkdirSync as Rn,existsSync as En}from"fs";import{join as Tn}from"path";var ht=class extends g{name="make:plugin";description="Create a new plugin class";arguments=["name"];flags=[];async handle(e){let t=e[0];if(!t){this.error("Please provide a plugin name.");return}let s=t.endsWith("Plugin")?t:`${t}Plugin`,r=this.sharedDir("plugins");Rn(r,{recursive:!0});let o=Tn(r,`${s}.ts`);if(En(o)){this.warn(`Plugin ${s} already exists.`);return}let n=s.replace(/([A-Z])/g,"-$1").toLowerCase().replace(/^-/,""),i=`import { Plugin } from '@beeblock/svelar/plugins';
478
478
  import type { Container } from '@beeblock/svelar/container';
479
479
 
480
480
  export class ${s} extends Plugin {
@@ -496,7 +496,7 @@ export class ${s} extends Plugin {
496
496
  // Clean up resources
497
497
  }
498
498
  }
499
- `;Po(i,o);let a=this.isDDD()?`src/lib/shared/plugins/${s}.ts`:`src/lib/plugins/${s}.ts`;this.success(`Plugin created: ${a}`)}};import{writeFileSync as ko,mkdirSync as $o,existsSync as Do}from"fs";import{join as Ao}from"path";var gt=class extends g{name="make:task";description="Create a new scheduled task class";arguments=["name"];flags=[];async handle(e){let t=e[0];if(!t){this.error("Please provide a task name.");return}let s=(t.endsWith("Task"),t),r=this.sharedDir("scheduler");$o(r,{recursive:!0});let i=Ao(r,`${s}.ts`);if(Do(i)){this.warn(`Task ${s} already exists.`);return}let n=`import { ScheduledTask } from '@beeblock/svelar/scheduler';
499
+ `;Pn(o,i);let a=this.isDDD()?`src/lib/shared/plugins/${s}.ts`:`src/lib/plugins/${s}.ts`;this.success(`Plugin created: ${a}`)}};import{writeFileSync as kn,mkdirSync as $n,existsSync as Dn}from"fs";import{join as An}from"path";var gt=class extends g{name="make:task";description="Create a new scheduled task class";arguments=["name"];flags=[];async handle(e){let t=e[0];if(!t){this.error("Please provide a task name.");return}let s=(t.endsWith("Task"),t),r=this.sharedDir("scheduler");$n(r,{recursive:!0});let o=An(r,`${s}.ts`);if(Dn(o)){this.warn(`Task ${s} already exists.`);return}let n=`import { ScheduledTask } from '@beeblock/svelar/scheduler';
500
500
 
501
501
  export class ${s} extends ScheduledTask {
502
502
  name = '${this.toKebabCase(s)}';
@@ -529,7 +529,7 @@ export class ${s} extends ScheduledTask {
529
529
  console.error('${s} failed:', error.message);
530
530
  }
531
531
  }
532
- `;ko(i,n);let o=this.isDDD()?`src/lib/shared/scheduler/${s}.ts`:`src/lib/scheduler/${s}.ts`;this.success(`Scheduled task created: ${o}`)}toKebabCase(e){return e.replace(/([A-Z])/g,"-$1").toLowerCase().replace(/^-/,"")}};import{writeFileSync as _o,mkdirSync as Lo,existsSync as Mo}from"fs";import{join as Oo}from"path";var ft=class extends g{name="make:job";description="Create a new queue job class";arguments=["name"];flags=[];async handle(e){let t=e[0];if(!t){this.error("Please provide a job name.");return}let s=(t.endsWith("Job"),t),r=this.sharedDir("jobs");Lo(r,{recursive:!0});let i=Oo(r,`${s}.ts`);if(Mo(i)){this.warn(`Job ${s} already exists.`);return}let n=`import { Job } from '@beeblock/svelar/queue';
532
+ `;kn(o,n);let i=this.isDDD()?`src/lib/shared/scheduler/${s}.ts`:`src/lib/scheduler/${s}.ts`;this.success(`Scheduled task created: ${i}`)}toKebabCase(e){return e.replace(/([A-Z])/g,"-$1").toLowerCase().replace(/^-/,"")}};import{writeFileSync as _n,mkdirSync as Ln,existsSync as Mn}from"fs";import{join as On}from"path";var ft=class extends g{name="make:job";description="Create a new queue job class";arguments=["name"];flags=[];async handle(e){let t=e[0];if(!t){this.error("Please provide a job name.");return}let s=(t.endsWith("Job"),t),r=this.sharedDir("jobs");Ln(r,{recursive:!0});let o=On(r,`${s}.ts`);if(Mn(o)){this.warn(`Job ${s} already exists.`);return}let n=`import { Job } from '@beeblock/svelar/queue';
533
533
 
534
534
  export class ${s} extends Job {
535
535
  maxAttempts = 3; // Retry up to 3 times
@@ -556,10 +556,10 @@ export class ${s} extends Job {
556
556
  console.log('${s} retrying, attempt', attempt);
557
557
  }
558
558
  }
559
- `;_o(i,n);let o=this.isDDD()?`src/lib/shared/jobs/${s}.ts`:`src/lib/jobs/${s}.ts`;this.success(`Job created: ${o}`)}};import{writeFileSync as No,mkdirSync as Io,existsSync as jo}from"fs";import{join as Uo}from"path";var vt=class extends g{name="make:command";description="Create a new custom CLI command";arguments=["name"];flags=[{name:"command",description:'The terminal command name (e.g. "app:sync")',type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a command class name. Example: npx svelar make:command SyncUsers");return}let r=s.endsWith("Command")?s:`${s}Command`,i=this.sharedDir("commands");Io(i,{recursive:!0});let n=Uo(i,`${r}.ts`);if(jo(n)){this.warn(`Command ${r} already exists.`);return}let o=t.command??this.deriveCommandName(r),a=`import { Command } from '@beeblock/svelar/cli';
559
+ `;_n(o,n);let i=this.isDDD()?`src/lib/shared/jobs/${s}.ts`:`src/lib/jobs/${s}.ts`;this.success(`Job created: ${i}`)}};import{writeFileSync as In,mkdirSync as Nn,existsSync as jn}from"fs";import{join as Un}from"path";var vt=class extends g{name="make:command";description="Create a new custom CLI command";arguments=["name"];flags=[{name:"command",description:'The terminal command name (e.g. "app:sync")',type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a command class name. Example: npx svelar make:command SyncUsers");return}let r=s.endsWith("Command")?s:`${s}Command`,o=this.sharedDir("commands");Nn(o,{recursive:!0});let n=Un(o,`${r}.ts`);if(jn(n)){this.warn(`Command ${r} already exists.`);return}let i=t.command??this.deriveCommandName(r),a=`import { Command } from '@beeblock/svelar/cli';
560
560
 
561
561
  export class ${r} extends Command {
562
- name = '${o}';
562
+ name = '${i}';
563
563
  description = 'TODO: Describe your command';
564
564
  arguments = ['name']; // Positional args your command accepts
565
565
  flags = [
@@ -570,7 +570,7 @@ export class ${r} extends Command {
570
570
  async handle(args: string[], flags: Record<string, any>): Promise<void> {
571
571
  const name = args[0];
572
572
 
573
- this.info('Running ${o}...');
573
+ this.info('Running ${i}...');
574
574
 
575
575
  // Your command logic here
576
576
  // Use this.bootstrap() if you need database access
@@ -579,7 +579,7 @@ export class ${r} extends Command {
579
579
  this.success('Done!');
580
580
  }
581
581
  }
582
- `;No(n,a);let c=this.isDDD()?`src/lib/shared/commands/${r}.ts`:`src/lib/commands/${r}.ts`;this.success(`Command created: ${c}`),this.info(`Command name: ${o}`),this.newLine(),this.info("Your command will be auto-discovered. Run it with:"),this.log(` npx svelar ${o}`)}deriveCommandName(e){return`app:${e.replace(/Command$/,"").replace(/([a-z])([A-Z])/g,"$1-$2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1-$2").toLowerCase()}`}};import{writeFileSync as qo,mkdirSync as Fo,existsSync as Bo}from"fs";import{join as oi}from"path";var bt=class extends g{name="make:config";description="Create a new config file";arguments=["name"];flags=[];templates={app:`import { env } from 'svelar/config';
582
+ `;In(n,a);let c=this.isDDD()?`src/lib/shared/commands/${r}.ts`:`src/lib/commands/${r}.ts`;this.success(`Command created: ${c}`),this.info(`Command name: ${i}`),this.newLine(),this.info("Your command will be auto-discovered. Run it with:"),this.log(` npx svelar ${i}`)}deriveCommandName(e){return`app:${e.replace(/Command$/,"").replace(/([a-z])([A-Z])/g,"$1-$2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1-$2").toLowerCase()}`}};import{writeFileSync as qn,mkdirSync as Fn,existsSync as Bn}from"fs";import{join as ai}from"path";var bt=class extends g{name="make:config";description="Create a new config file";arguments=["name"];flags=[];templates={app:`import { env } from 'svelar/config';
583
583
 
584
584
  export default {
585
585
  name: env('APP_NAME', 'Svelar'),
@@ -788,7 +788,7 @@ export default {
788
788
  },
789
789
  },
790
790
  };
791
- `};async handle(e){let t=e[0];if(!t){this.error("Please provide a config file name. Example: npx svelar make:config database"),this.newLine(),this.info("Available presets: app, database, auth, mail, cache, queue, storage, broadcasting, logging");return}let s=oi(process.cwd(),"config");Fo(s,{recursive:!0});let r=t.toLowerCase().replace(/\s+/g,"-"),i=oi(s,`${r}.ts`);if(Bo(i)){this.warn(`Config file config/${r}.ts already exists.`);return}let n=this.templates[r]??this.blankTemplate(r);qo(i,n),this.success(`Config created: config/${r}.ts`),this.newLine(),this.info("Access it with:"),this.log(` config.get('${r}.key')`)}blankTemplate(e){return`import { env } from 'svelar/config';
791
+ `};async handle(e){let t=e[0];if(!t){this.error("Please provide a config file name. Example: npx svelar make:config database"),this.newLine(),this.info("Available presets: app, database, auth, mail, cache, queue, storage, broadcasting, logging");return}let s=ai(process.cwd(),"config");Fn(s,{recursive:!0});let r=t.toLowerCase().replace(/\s+/g,"-"),o=ai(s,`${r}.ts`);if(Bn(o)){this.warn(`Config file config/${r}.ts already exists.`);return}let n=this.templates[r]??this.blankTemplate(r);qn(o,n),this.success(`Config created: config/${r}.ts`),this.newLine(),this.info("Access it with:"),this.log(` config.get('${r}.key')`)}blankTemplate(e){return`import { env } from 'svelar/config';
792
792
 
793
793
  export default {
794
794
  // Add your ${e} configuration here
@@ -797,7 +797,7 @@ export default {
797
797
  // env<number>('MY_PORT', 3000)
798
798
  // env<boolean>('MY_FLAG', false)
799
799
  };
800
- `}};import{writeFileSync as Ho,mkdirSync as zo,existsSync as Ko}from"fs";import{join as Wo}from"path";var yt=class extends g{name="make:channel";description="Create a new broadcast channel authorization";arguments=["name"];flags=[{name:"presence",alias:"p",description:"Create a presence channel",type:"boolean"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a channel name. Example: npx svelar make:channel OrderChannel");return}let r=s.endsWith("Channel")?s:`${s}Channel`,i=this.sharedDir("channels");zo(i,{recursive:!0});let n=Wo(i,`${r}.ts`);if(Ko(n)){this.warn(`Channel ${r} already exists.`);return}let o=r.replace(/Channel$/,""),a=o.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),c=o.charAt(0).toLowerCase()+o.slice(1)+"Id",u=t.presence,h=`${u?"presence":"private"}-${a}.{${c}}`,m=u?this.presenceTemplate(r,h,c):this.privateTemplate(r,h,c);Ho(n,m);let f=this.isDDD()?"src/lib/shared/channels":"src/lib/channels";this.success(`Channel created: ${f}/${r}.ts`),this.info(`Channel pattern: ${h}`),this.newLine(),this.info("Register it in src/app.ts or a service provider:"),this.log(` import { register${r} } from './${f.replace("src/","")}/${r}.js';`),this.log(` register${r}();`)}privateTemplate(e,t,s){let r=e.replace(/Channel$/,"");return`import { Broadcast } from '@beeblock/svelar/broadcasting';
800
+ `}};import{writeFileSync as Hn,mkdirSync as zn,existsSync as Kn}from"fs";import{join as Wn}from"path";var yt=class extends g{name="make:channel";description="Create a new broadcast channel authorization";arguments=["name"];flags=[{name:"presence",alias:"p",description:"Create a presence channel",type:"boolean"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a channel name. Example: npx svelar make:channel OrderChannel");return}let r=s.endsWith("Channel")?s:`${s}Channel`,o=this.sharedDir("channels");zn(o,{recursive:!0});let n=Wn(o,`${r}.ts`);if(Kn(n)){this.warn(`Channel ${r} already exists.`);return}let i=r.replace(/Channel$/,""),a=i.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),c=i.charAt(0).toLowerCase()+i.slice(1)+"Id",u=t.presence,h=`${u?"presence":"private"}-${a}.{${c}}`,m=u?this.presenceTemplate(r,h,c):this.privateTemplate(r,h,c);Hn(n,m);let f=this.isDDD()?"src/lib/shared/channels":"src/lib/channels";this.success(`Channel created: ${f}/${r}.ts`),this.info(`Channel pattern: ${h}`),this.newLine(),this.info("Register it in src/app.ts or a service provider:"),this.log(` import { register${r} } from './${f.replace("src/","")}/${r}.js';`),this.log(` register${r}();`)}privateTemplate(e,t,s){let r=e.replace(/Channel$/,"");return`import { Broadcast } from '@beeblock/svelar/broadcasting';
801
801
 
802
802
  /**
803
803
  * ${e}
@@ -840,7 +840,7 @@ export function register${e}(): void {
840
840
  };
841
841
  });
842
842
  }
843
- `}};import{writeFileSync as Jo,mkdirSync as ai,existsSync as Vo,readFileSync as Yo}from"fs";import{join as q}from"path";var N=class{static dockerfile(){return`# \u2500\u2500 Svelar Production Dockerfile \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
843
+ `}};import{writeFileSync as Jn,mkdirSync as wt,existsSync as Vn,readFileSync as Yn}from"fs";import{join as I}from"path";var O=class{static dockerfile(){return`# \u2500\u2500 Svelar Production Dockerfile \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
844
844
  # Multi-stage build: base \u2192 deps \u2192 builder \u2192 production / development
845
845
  # Generated by: npx svelar make:docker
846
846
 
@@ -924,6 +924,210 @@ services:
924
924
  app:
925
925
  image: \${DOCKER_IMAGE:-${e}}:latest
926
926
  # No build \u2014 uses pre-built image from registry
927
+ `}static postgresInit(){return`-- PostgreSQL init script
928
+ -- Runs once when the data volume is first created.
929
+ -- Add extensions, custom types, or seed data here.
930
+
931
+ -- Common extensions
932
+ CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -- UUID generation (uuid_generate_v4)
933
+ CREATE EXTENSION IF NOT EXISTS "pgcrypto"; -- gen_random_uuid, encryption, hashing
934
+ CREATE EXTENSION IF NOT EXISTS "citext"; -- Case-insensitive text (emails, usernames)
935
+ CREATE EXTENSION IF NOT EXISTS "unaccent"; -- Accent-insensitive search (cafe = cafe)
936
+ CREATE EXTENSION IF NOT EXISTS "pg_trgm"; -- Fast LIKE/ILIKE, fuzzy search, similarity
937
+ CREATE EXTENSION IF NOT EXISTS "pg_stat_statements"; -- Query performance tracking
938
+ `}static postgresConf(){return`# PostgreSQL Configuration
939
+ # Optimized for SvelteKit/Svelar API workload with PgBouncer
940
+ # Generated by: npx svelar make:docker
941
+ #
942
+ # Default tuning: 2GB RAM / 2 vCPUs (typical $12-24/mo droplet)
943
+ # Scale values proportionally for larger instances.
944
+ # Use https://pgtune.leopard.in.ua for precise tuning.
945
+
946
+ # =============================================================================
947
+ # CONNECTIONS
948
+ # =============================================================================
949
+ # With PgBouncer handling pooling, PostgreSQL needs fewer direct connections.
950
+ # PgBouncer's max_db_connections should be less than this.
951
+ max_connections = 100
952
+ superuser_reserved_connections = 3
953
+
954
+ # =============================================================================
955
+ # MEMORY (2GB RAM baseline \u2014 scale proportionally)
956
+ # =============================================================================
957
+ # 25% of RAM for shared buffers
958
+ shared_buffers = 512MB
959
+ # Per-operation sort/hash memory (careful: multiplied by max_connections)
960
+ work_mem = 32MB
961
+ # Memory for VACUUM, CREATE INDEX, ALTER TABLE
962
+ maintenance_work_mem = 256MB
963
+ # WAL writer memory
964
+ wal_buffers = 16MB
965
+ # Estimate of OS + PostgreSQL caches (~75% of RAM)
966
+ effective_cache_size = 1536MB
967
+
968
+ # =============================================================================
969
+ # CHECKPOINT / WAL
970
+ # =============================================================================
971
+ checkpoint_completion_target = 0.9
972
+ max_wal_size = 1GB
973
+ min_wal_size = 256MB
974
+ wal_compression = on
975
+
976
+ # =============================================================================
977
+ # QUERY PLANNER
978
+ # =============================================================================
979
+ # SSD storage \u2014 lower random page cost
980
+ random_page_cost = 1.1
981
+ effective_io_concurrency = 200
982
+ default_statistics_target = 100
983
+
984
+ # =============================================================================
985
+ # PARALLEL QUERY (2 vCPUs baseline)
986
+ # =============================================================================
987
+ max_parallel_workers_per_gather = 1
988
+ max_parallel_workers = 2
989
+ max_parallel_maintenance_workers = 1
990
+ parallel_leader_participation = on
991
+
992
+ # =============================================================================
993
+ # LOGGING
994
+ # =============================================================================
995
+ log_destination = 'stderr'
996
+ logging_collector = on
997
+ log_directory = 'log'
998
+ log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
999
+ log_rotation_age = 1d
1000
+ log_rotation_size = 100MB
1001
+
1002
+ # Log slow queries (>1s)
1003
+ log_min_duration_statement = 1000
1004
+ log_checkpoints = on
1005
+ log_connections = on
1006
+ log_disconnections = on
1007
+ log_lock_waits = on
1008
+ log_temp_files = 0
1009
+
1010
+ log_line_prefix = '%t [%p]: user=%u,db=%d,app=%a,client=%h '
1011
+
1012
+ # =============================================================================
1013
+ # STATISTICS / MONITORING
1014
+ # =============================================================================
1015
+ shared_preload_libraries = 'pg_stat_statements'
1016
+ pg_stat_statements.max = 10000
1017
+ pg_stat_statements.track = all
1018
+ pg_stat_statements.track_utility = on
1019
+ pg_stat_statements.track_planning = on
1020
+
1021
+ track_io_timing = on
1022
+ track_functions = all
1023
+ track_activity_query_size = 2048
1024
+
1025
+ # =============================================================================
1026
+ # AUTOVACUUM
1027
+ # =============================================================================
1028
+ autovacuum = on
1029
+ autovacuum_max_workers = 3
1030
+ autovacuum_naptime = 1min
1031
+ autovacuum_vacuum_threshold = 50
1032
+ autovacuum_vacuum_scale_factor = 0.05
1033
+ autovacuum_analyze_threshold = 50
1034
+ autovacuum_analyze_scale_factor = 0.025
1035
+ autovacuum_vacuum_cost_delay = 2ms
1036
+ autovacuum_vacuum_cost_limit = 1000
1037
+
1038
+ # =============================================================================
1039
+ # LOCALE / ENCODING
1040
+ # =============================================================================
1041
+ lc_messages = 'en_US.utf8'
1042
+ lc_monetary = 'en_US.utf8'
1043
+ lc_numeric = 'en_US.utf8'
1044
+ lc_time = 'en_US.utf8'
1045
+
1046
+ # =============================================================================
1047
+ # SECURITY
1048
+ # =============================================================================
1049
+ password_encryption = scram-sha-256
1050
+ listen_addresses = '*'
1051
+ port = 5432
1052
+ `}static mysqlInit(){return`-- MySQL init script
1053
+ -- Runs once when the data volume is first created.
1054
+ -- Add custom tables, functions, or seed data here.
1055
+
1056
+ -- Ensure UTF-8 support for the default database
1057
+ ALTER DATABASE IF EXISTS \`svelar\`
1058
+ CHARACTER SET = utf8mb4
1059
+ COLLATE = utf8mb4_unicode_ci;
1060
+ `}static pgbouncerIni(){return`; PgBouncer configuration
1061
+ ; Generated by: npx svelar make:docker
1062
+ ; Docs: https://www.pgbouncer.org/config.html
1063
+ ;
1064
+ ; Credentials are read from DATABASE_URL env var in docker-compose.yml.
1065
+ ; The edoburu/pgbouncer image auto-generates the auth file from DATABASE_URL
1066
+ ; at startup \u2014 no static userlist.txt with plain text passwords needed.
1067
+
1068
+ [databases]
1069
+ ; * = use DATABASE_URL from environment (auto-configured by edoburu/pgbouncer image)
1070
+ ; To add more databases, use format: dbname = host=hostname port=port dbname=database
1071
+
1072
+ [pgbouncer]
1073
+ ; Connection settings
1074
+ listen_addr = 0.0.0.0
1075
+ listen_port = 6432
1076
+ unix_socket_dir =
1077
+
1078
+ ; Authentication \u2014 uses auto-generated auth file from DATABASE_URL
1079
+ ; Client \u2192 PgBouncer uses md5 (required: edoburu image writes plain text to userlist)
1080
+ ; PgBouncer \u2192 PostgreSQL uses scram-sha-256 (negotiated automatically by the server)
1081
+ auth_type = md5
1082
+ auth_file = /etc/pgbouncer/userlist.txt
1083
+
1084
+ ; Pool Mode
1085
+ ; transaction = release connection after each transaction (best for web apps)
1086
+ ; session = release after session disconnects
1087
+ ; statement = release after each statement (not recommended with prepared statements)
1088
+ pool_mode = transaction
1089
+
1090
+ ; Pool Size Settings
1091
+ ; default_pool_size: connections per user/database pair
1092
+ default_pool_size = 25
1093
+ min_pool_size = 5
1094
+ reserve_pool_size = 5
1095
+ reserve_pool_timeout = 3
1096
+
1097
+ ; Max connections
1098
+ max_client_conn = 500
1099
+ max_db_connections = 80
1100
+ max_user_connections = 80
1101
+
1102
+ ; Timeouts
1103
+ server_connect_timeout = 15
1104
+ server_idle_timeout = 300
1105
+ server_lifetime = 3600
1106
+ client_idle_timeout = 0
1107
+ client_login_timeout = 60
1108
+ query_timeout = 0
1109
+ query_wait_timeout = 120
1110
+
1111
+ ; Logging
1112
+ log_connections = 1
1113
+ log_disconnections = 1
1114
+ log_pooler_errors = 1
1115
+ stats_period = 60
1116
+ verbose = 0
1117
+
1118
+ ; TCP keepalive
1119
+ tcp_keepalive = 1
1120
+ tcp_keepidle = 30
1121
+ tcp_keepintvl = 10
1122
+ tcp_keepcnt = 3
1123
+
1124
+ ; Server settings
1125
+ server_reset_query = DISCARD ALL
1126
+ server_check_query = SELECT 1
1127
+ server_check_delay = 30
1128
+
1129
+ ; Ignore startup parameters (important for Node.js drivers)
1130
+ ignore_startup_parameters = extra_float_digits,application_name
927
1131
  `}static healthEndpoint(){return`import { json } from '@sveltejs/kit';
928
1132
 
929
1133
  export const GET = () => json({
@@ -970,7 +1174,10 @@ jobs:
970
1174
 
971
1175
  - name: Log in to Docker Hub
972
1176
  if: github.event_name == 'push'
973
- run: echo "\${{ secrets.DOCKER_TOKEN }}" | docker login -u "\${{ secrets.DOCKER_USERNAME }}" --password-stdin
1177
+ uses: docker/login-action@v3
1178
+ with:
1179
+ username: \${{ secrets.DOCKER_USERNAME }}
1180
+ password: \${{ secrets.DOCKER_TOKEN }}
974
1181
 
975
1182
  - name: Define tags
976
1183
  run: |
@@ -989,6 +1196,16 @@ jobs:
989
1196
  docker push $DOCKER_IMAGE:$TIMESTAMP_TAG
990
1197
  docker push $DOCKER_IMAGE:latest
991
1198
 
1199
+ - name: Copy compose files to droplet
1200
+ if: github.event_name == 'push'
1201
+ uses: appleboy/scp-action@v0.1.7
1202
+ with:
1203
+ host: \${{ secrets.DROPLET_HOST }}
1204
+ username: \${{ secrets.DROPLET_USER }}
1205
+ key: \${{ secrets.DROPLET_SSH_KEY }}
1206
+ source: "docker-compose.yml,docker-compose.prod.yml,docker/"
1207
+ target: \${{ secrets.DROPLET_PROJECT }}
1208
+
992
1209
  - name: Deploy to droplet
993
1210
  if: github.event_name == 'push'
994
1211
  uses: appleboy/ssh-action@v1
@@ -1000,6 +1217,7 @@ jobs:
1000
1217
  echo "\${{ secrets.DOCKER_TOKEN }}" | docker login -u "\${{ secrets.DOCKER_USERNAME }}" --password-stdin
1001
1218
  cd \${{ secrets.DROPLET_PROJECT }}/
1002
1219
  echo "\${{ secrets.ENV_PROD }}" > .env
1220
+ echo "DOCKER_IMAGE=\${{ secrets.DOCKER_USERNAME }}/\${{ secrets.DOCKER_IMAGE_NAME }}" >> .env
1003
1221
  docker compose -f docker-compose.yml -f docker-compose.prod.yml pull
1004
1222
  docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
1005
1223
  docker image prune -f
@@ -1084,6 +1302,12 @@ if [[ ! -f "$COMPOSE_PROD" ]]; then
1084
1302
  exit 1
1085
1303
  fi
1086
1304
 
1305
+ # Validate paths don't contain spaces (word-splitting would break SSH commands)
1306
+ if [[ "$SSH_KEY_PATH" == *" "* ]]; then
1307
+ err "SSH_KEY_PATH must not contain spaces: $SSH_KEY_PATH"
1308
+ exit 1
1309
+ fi
1310
+
1087
1311
  SSH_ROOT="ssh -o StrictHostKeyChecking=accept-new -i $SSH_KEY_PATH root@$DROPLET_IP"
1088
1312
  SSH_USER="ssh -o StrictHostKeyChecking=accept-new -i $SSH_KEY_PATH $DEPLOY_USER@$DROPLET_IP"
1089
1313
  PUB_KEY_CONTENT=$(cat "$SSH_PUB_KEY")
@@ -1128,8 +1352,8 @@ $SSH_ROOT bash -s <<REMOTE_SCRIPT
1128
1352
  echo "Password set for $DEPLOY_USER."
1129
1353
  fi
1130
1354
 
1131
- # Allow sudo without password for deploy user
1132
- echo "$DEPLOY_USER ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/$DEPLOY_USER
1355
+ # Allow passwordless sudo for Docker commands only (principle of least privilege)
1356
+ echo "$DEPLOY_USER ALL=(ALL) NOPASSWD:/usr/bin/docker,/usr/bin/docker-compose,/usr/local/bin/docker-compose" > /etc/sudoers.d/$DEPLOY_USER
1133
1357
  chmod 440 /etc/sudoers.d/$DEPLOY_USER
1134
1358
  REMOTE_SCRIPT
1135
1359
 
@@ -1215,6 +1439,13 @@ scp -o StrictHostKeyChecking=accept-new -i "$SSH_KEY_PATH" \\
1215
1439
  scp -o StrictHostKeyChecking=accept-new -i "$SSH_KEY_PATH" \\
1216
1440
  "$COMPOSE_PROD" "$DEPLOY_USER@$DROPLET_IP:$REMOTE_DIR/docker-compose.prod.yml"
1217
1441
 
1442
+ # Copy docker config directory (postgres, pgbouncer configs)
1443
+ if [[ -d "docker" ]]; then
1444
+ scp -o StrictHostKeyChecking=accept-new -i "$SSH_KEY_PATH" -r \\
1445
+ docker "$DEPLOY_USER@$DROPLET_IP:$REMOTE_DIR/"
1446
+ log "Docker config files copied (docker/ directory)."
1447
+ fi
1448
+
1218
1449
  log "Compose files copied (.env is managed by CI/CD via ENV_PROD secret)."
1219
1450
 
1220
1451
  # \u2500\u2500 Step 6: Configure firewall \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
@@ -1295,7 +1526,7 @@ COMPOSE_FILE=docker-compose.prod.yml
1295
1526
 
1296
1527
  # Password for the deploy user (optional, for emergency console access)
1297
1528
  DEPLOY_USER_PASSWORD=
1298
- `}};var re=class extends g{name="make:docker";description="Scaffold Docker deployment files (Dockerfile, docker-compose, PM2, health endpoint)";arguments=[];flags=[{name:"db",alias:"d",description:"Database driver: postgres, mysql, sqlite (default: postgres)",type:"string"},{name:"image",alias:"i",description:"Docker image name (default: package.json name)",type:"string"},{name:"registry",description:"Docker registry prefix (default: Docker Hub)",type:"string"},{name:"port",description:"Production port (default: 3000)",type:"string"},{name:"dev-port",description:"Development port (default: 5173)",type:"string"},{name:"soketi",alias:"s",description:"Include Soketi WebSocket server",type:"boolean"},{name:"redis",alias:"r",description:"Include Redis service",type:"boolean"},{name:"gotenberg",alias:"g",description:"Include Gotenberg PDF service (default: true)",type:"boolean"},{name:"rustfs",description:"Include RustFS S3-compatible object storage (default: true)",type:"boolean"},{name:"meilisearch",alias:"m",description:"Include Meilisearch full-text search engine",type:"boolean"},{name:"force",alias:"f",description:"Overwrite existing files",type:"boolean"}];async handle(e,t){let s=process.cwd(),r=t.db??"postgres",i=t.soketi??!0,n=t.redis??!0,o=t.gotenberg??!0,a=t.rustfs??!0,c=t.meilisearch??!1,u=t.force??!1,p=this.resolveAppName(s),h=t.image??p,m=t.registry,f=m?`${m}/${h}`:h,y=["postgres","mysql","sqlite"];if(!y.includes(r)){this.error(`Unknown database driver: ${r}. Use one of: ${y.join(", ")}`);return}let C=q(s,"src","routes","api","health");ai(C,{recursive:!0});let M=[{path:q(s,"Dockerfile"),content:N.dockerfile(),label:"Dockerfile"},{path:q(s,"docker-compose.yml"),content:this.composeTemplate(r,i,n,o,a,c),label:"docker-compose.yml"},{path:q(s,"docker-compose.dev.yml"),content:N.composeDevOverride(),label:"docker-compose.dev.yml"},{path:q(s,"docker-compose.prod.yml"),content:N.composeProdOverride(f),label:"docker-compose.prod.yml"},{path:q(s,".dockerignore"),content:this.dockerignoreTemplate(),label:".dockerignore"},{path:q(s,"ecosystem.config.cjs"),content:this.pm2Template(),label:"ecosystem.config.cjs"},{path:q(C,"+server.ts"),content:N.healthEndpoint(),label:"src/routes/api/health/+server.ts"}],T=0,D=0;for(let $ of M){if(Vo($.path)&&!u){this.warn(`${$.label} already exists (use --force to overwrite)`),D++;continue}Jo($.path,$.content),this.success(`Created ${$.label}`),T++}if(r!=="sqlite"){let $=q(s,"docker");ai($,{recursive:!0})}this.newLine(),T>0?this.info(`${T} file(s) created${D>0?`, ${D} skipped`:""}`):this.info("No files created (all exist already)"),this.newLine(),this.info("Quick start:"),this.log(" # Development (with hot-reload)"),this.log(" npx svelar dev:up"),this.newLine(),this.log(" # Production (local build)"),this.log(" docker compose up -d --build"),this.newLine(),this.log(" # Run migrations inside the container"),this.log(" docker compose exec app npx svelar migrate"),this.newLine(),this.log(" # View logs"),this.log(" npx svelar dev:logs"),this.newLine(),this.log(" # Stop services"),this.log(" npx svelar dev:down"),this.newLine(),this.info("Make sure to update .env with production values before deploying.")}resolveAppName(e){try{let t=JSON.parse(Yo(q(e,"package.json"),"utf-8"));if(t.name&&typeof t.name=="string")return t.name.replace(/^@[^/]+\//,"")}catch{}return"svelar-app"}composeTemplate(e,t,s,r,i=!0,n=!1){let o=[];o.push("# \u2500\u2500 Svelar Docker Compose \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),o.push("# Generated by: npx svelar make:docker"),o.push("#"),o.push("# Usage:"),o.push("# docker compose up -d --build # Start all services"),o.push("# docker compose exec app npx svelar migrate # Run migrations"),o.push("# docker compose logs -f app # View app logs"),o.push("# docker compose down # Stop all services"),o.push(""),o.push("services:"),o.push(" app:"),o.push(" build: ."),o.push(" restart: unless-stopped"),o.push(" ports:"),o.push(' - "${APP_PORT:-3000}:3000"'),o.push(" env_file: .env"),o.push(" environment:"),o.push(" - NODE_ENV=production"),e==="postgres"?(o.push(" - DB_HOST=postgres"),o.push(" - DB_PORT=5432")):e==="mysql"&&(o.push(" - DB_HOST=mysql"),o.push(" - DB_PORT=3306")),s&&(o.push(" - REDIS_HOST=redis"),o.push(" - REDIS_PORT=6379"),o.push(" - REDIS_PASSWORD=${REDIS_PASSWORD:-svelarsecret}"),o.push(" - QUEUE_DRIVER=redis")),t&&(o.push(" - PUSHER_HOST=soketi"),o.push(" - PUSHER_PORT=6001")),r&&o.push(" - GOTENBERG_URL=http://gotenberg:3000"),i&&(o.push(" - S3_ENDPOINT=http://rustfs:9000"),o.push(" - S3_ACCESS_KEY=${RUSTFS_ROOT_USER:-svelar}"),o.push(" - S3_SECRET_KEY=${RUSTFS_ROOT_PASSWORD:-svelarsecret}"),o.push(" - S3_BUCKET=${S3_BUCKET:-svelar}"),o.push(" - S3_REGION=us-east-1"),o.push(" - STORAGE_DISK=s3")),n&&(o.push(" - MEILISEARCH_HOST=http://meilisearch:7700"),o.push(" - MEILISEARCH_KEY=${MEILI_MASTER_KEY:-svelar-meili-master-key}"));let a=[];if(e==="postgres"&&a.push("postgres"),e==="mysql"&&a.push("mysql"),s&&a.push("redis"),t&&a.push("soketi"),r&&a.push("gotenberg"),i&&a.push("rustfs"),n&&a.push("meilisearch"),a.length>0){o.push(" depends_on:");for(let c of a)o.push(` ${c}:`),o.push(" condition: service_healthy")}return o.push(" volumes:"),o.push(" - app_storage:/app/storage"),e==="postgres"&&(o.push(""),o.push(" postgres:"),o.push(" image: postgres:16-alpine"),o.push(" restart: unless-stopped"),o.push(" # No ports exposed \u2014 only reachable by app via Docker network"),o.push(" environment:"),o.push(" POSTGRES_DB: ${DB_NAME:-svelar}"),o.push(" POSTGRES_USER: ${DB_USER:-svelar}"),o.push(" POSTGRES_PASSWORD: ${DB_PASSWORD:-secret}"),o.push(" volumes:"),o.push(" - pgdata:/var/lib/postgresql/data"),o.push(" healthcheck:"),o.push(' test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-svelar}"]'),o.push(" interval: 10s"),o.push(" timeout: 5s"),o.push(" retries: 5")),e==="mysql"&&(o.push(""),o.push(" mysql:"),o.push(" image: mysql:8.0"),o.push(" restart: unless-stopped"),o.push(" # No ports exposed \u2014 only reachable by app via Docker network"),o.push(" environment:"),o.push(" MYSQL_DATABASE: ${DB_NAME:-svelar}"),o.push(" MYSQL_USER: ${DB_USER:-svelar}"),o.push(" MYSQL_PASSWORD: ${DB_PASSWORD:-secret}"),o.push(" MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-rootsecret}"),o.push(" volumes:"),o.push(" - mysqldata:/var/lib/mysql"),o.push(" healthcheck:"),o.push(' test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]'),o.push(" interval: 10s"),o.push(" timeout: 5s"),o.push(" retries: 5")),s&&(o.push(""),o.push(" redis:"),o.push(" image: redis:7-alpine"),o.push(" restart: unless-stopped"),o.push(" # No ports exposed \u2014 only reachable by app via Docker network"),o.push(" command: redis-server --requirepass ${REDIS_PASSWORD:-svelarsecret}"),o.push(" volumes:"),o.push(" - redisdata:/data"),o.push(" healthcheck:"),o.push(' test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:-svelarsecret}", "ping"]'),o.push(" interval: 10s"),o.push(" timeout: 5s"),o.push(" retries: 5")),t&&(o.push(""),o.push(" soketi:"),o.push(" image: quay.io/soketi/soketi:1.6-16-debian"),o.push(" restart: unless-stopped"),o.push(" # No ports exposed \u2014 only reachable by app via Docker network"),o.push(" # Expose 6001 to host only if clients connect directly (uncomment below)"),o.push(" # ports:"),o.push(' # - "${SOKETI_PORT:-6001}:6001"'),o.push(" environment:"),o.push(' SOKETI_DEBUG: "${SOKETI_DEBUG:-0}"'),o.push(" SOKETI_DEFAULT_APP_ID: ${PUSHER_APP_ID}"),o.push(" SOKETI_DEFAULT_APP_KEY: ${PUSHER_KEY}"),o.push(" SOKETI_DEFAULT_APP_SECRET: ${PUSHER_SECRET}"),o.push(' SOKETI_DEFAULT_APP_MAX_CONNS: "${SOKETI_MAX_CONNS:-1000}"'),o.push(' SOKETI_DEFAULT_APP_ENABLE_CLIENT_MESSAGES: "true"'),o.push(' SOKETI_DEFAULT_APP_MAX_BACKEND_EVENTS_PER_SEC: "-1"'),o.push(" healthcheck:"),o.push(' test: ["CMD", "wget", "-qO-", "http://localhost:6001"]'),o.push(" interval: 10s"),o.push(" timeout: 5s"),o.push(" retries: 3")),r&&(o.push(""),o.push(" gotenberg:"),o.push(" image: gotenberg/gotenberg:8"),o.push(" restart: unless-stopped"),o.push(" # No ports exposed \u2014 only reachable by app via Docker network"),o.push(" environment:"),o.push(' CHROMIUM_DISABLE_JAVASCRIPT: "false"'),o.push(' CHROMIUM_ALLOW_LIST: "file:///tmp/.*"'),o.push(' API_TIMEOUT: "${GOTENBERG_TIMEOUT:-60s}"'),o.push(' LOG_LEVEL: "${GOTENBERG_LOG_LEVEL:-info}"'),o.push(" healthcheck:"),o.push(' test: ["CMD", "curl", "-f", "http://localhost:3000/health"]'),o.push(" interval: 10s"),o.push(" timeout: 5s"),o.push(" retries: 5")),i&&(o.push(""),o.push(" rustfs:"),o.push(" image: rustfs/rustfs:latest"),o.push(" restart: unless-stopped"),o.push(" ports:"),o.push(' - "${RUSTFS_CONSOLE_PORT:-9001}:9001" # Admin console (protect with firewall)'),o.push(" environment:"),o.push(" RUSTFS_ROOT_USER: ${RUSTFS_ROOT_USER:-svelar}"),o.push(" RUSTFS_ROOT_PASSWORD: ${RUSTFS_ROOT_PASSWORD:-svelarsecret}"),o.push(' command: server /data --console-address ":9001"'),o.push(" volumes:"),o.push(" - rustfs_data:/data"),o.push(" healthcheck:"),o.push(' test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]'),o.push(" interval: 10s"),o.push(" timeout: 5s"),o.push(" retries: 5")),n&&(o.push(""),o.push(" meilisearch:"),o.push(" image: getmeili/meilisearch:v1.13"),o.push(" restart: unless-stopped"),o.push(" # No ports exposed \u2014 only reachable by app via Docker network"),o.push(" # Uncomment below to access the dashboard from the host"),o.push(" # ports:"),o.push(' # - "${MEILI_PORT:-7700}:7700"'),o.push(" environment:"),o.push(" MEILI_MASTER_KEY: ${MEILI_MASTER_KEY:-svelar-meili-master-key}"),o.push(" MEILI_ENV: production"),o.push(" MEILI_DB_PATH: /meili_data"),o.push(' MEILI_NO_ANALYTICS: "true"'),o.push(" volumes:"),o.push(" - meili_data:/meili_data"),o.push(" healthcheck:"),o.push(' test: ["CMD", "wget", "--no-verbose", "--spider", "http://localhost:7700/health"]'),o.push(" interval: 10s"),o.push(" timeout: 5s"),o.push(" retries: 5")),o.push(""),o.push("volumes:"),o.push(" app_storage:"),e==="postgres"&&o.push(" pgdata:"),e==="mysql"&&o.push(" mysqldata:"),s&&o.push(" redisdata:"),i&&o.push(" rustfs_data:"),n&&o.push(" meili_data:"),o.push(""),o.join(`
1529
+ `}};var re=class extends g{name="make:docker";description="Scaffold Docker deployment files (Dockerfile, docker-compose, PM2, health endpoint)";arguments=[];flags=[{name:"db",alias:"d",description:"Database driver: postgres, mysql, sqlite (default: postgres)",type:"string"},{name:"image",alias:"i",description:"Docker image name (default: package.json name)",type:"string"},{name:"registry",description:"Docker registry prefix (default: Docker Hub)",type:"string"},{name:"port",description:"Production port (default: 3000)",type:"string"},{name:"dev-port",description:"Development port (default: 5173)",type:"string"},{name:"soketi",alias:"s",description:"Include Soketi WebSocket server",type:"boolean"},{name:"redis",alias:"r",description:"Include Redis service",type:"boolean"},{name:"gotenberg",alias:"g",description:"Include Gotenberg PDF service (default: true)",type:"boolean"},{name:"rustfs",description:"Include RustFS S3-compatible object storage (default: true)",type:"boolean"},{name:"meilisearch",alias:"m",description:"Include Meilisearch full-text search engine",type:"boolean"},{name:"force",alias:"f",description:"Overwrite existing files",type:"boolean"}];async handle(e,t){let s=process.cwd(),r=t.db??"postgres",o=t.soketi??!0,n=t.redis??!0,i=t.gotenberg??!0,a=t.rustfs??!0,c=t.meilisearch??!1,u=t.force??!1,p=this.resolveAppName(s),h=t.image??p,m=t.registry,f=m?`${m}/${h}`:h,y=["postgres","mysql","sqlite"];if(!y.includes(r)){this.error(`Unknown database driver: ${r}. Use one of: ${y.join(", ")}`);return}let C=I(s,"src","routes","api","health");wt(C,{recursive:!0}),r==="postgres"?(wt(I(s,"docker","postgres"),{recursive:!0}),wt(I(s,"docker","pgbouncer"),{recursive:!0})):r==="mysql"&&wt(I(s,"docker","mysql"),{recursive:!0});let $=[{path:I(s,"Dockerfile"),content:O.dockerfile(),label:"Dockerfile"},{path:I(s,"docker-compose.yml"),content:this.composeTemplate(r,o,n,i,a,c),label:"docker-compose.yml"},{path:I(s,"docker-compose.dev.yml"),content:O.composeDevOverride(),label:"docker-compose.dev.yml"},{path:I(s,"docker-compose.prod.yml"),content:O.composeProdOverride(f),label:"docker-compose.prod.yml"},{path:I(s,".dockerignore"),content:this.dockerignoreTemplate(),label:".dockerignore"},{path:I(s,"ecosystem.config.cjs"),content:this.pm2Template(),label:"ecosystem.config.cjs"},{path:I(C,"+server.ts"),content:O.healthEndpoint(),label:"src/routes/api/health/+server.ts"}];r==="postgres"?($.push({path:I(s,"docker","postgres","postgresql.conf"),content:O.postgresConf(),label:"docker/postgres/postgresql.conf"}),$.push({path:I(s,"docker","postgres","init.sql"),content:O.postgresInit(),label:"docker/postgres/init.sql"}),$.push({path:I(s,"docker","pgbouncer","pgbouncer.ini"),content:O.pgbouncerIni(),label:"docker/pgbouncer/pgbouncer.ini"})):r==="mysql"&&$.push({path:I(s,"docker","mysql","init.sql"),content:O.mysqlInit(),label:"docker/mysql/init.sql"});let T=0,D=0;for(let L of $){if(Vn(L.path)&&!u){this.warn(`${L.label} already exists (use --force to overwrite)`),D++;continue}Jn(L.path,L.content),this.success(`Created ${L.label}`),T++}this.newLine(),T>0?this.info(`${T} file(s) created${D>0?`, ${D} skipped`:""}`):this.info("No files created (all exist already)"),this.newLine(),this.info("Quick start:"),this.log(" # Development (with hot-reload)"),this.log(" npx svelar dev:up"),this.newLine(),this.log(" # Production (local build)"),this.log(" docker compose up -d --build"),this.newLine(),this.log(" # Run migrations inside the container"),this.log(" docker compose exec app npx svelar migrate"),this.newLine(),this.log(" # View logs"),this.log(" npx svelar dev:logs"),this.newLine(),this.log(" # Stop services"),this.log(" npx svelar dev:down"),this.newLine(),this.info("Make sure to update .env with production values before deploying.")}resolveAppName(e){try{let t=JSON.parse(Yn(I(e,"package.json"),"utf-8"));if(t.name&&typeof t.name=="string")return t.name.replace(/^@[^/]+\//,"")}catch{}return"svelar-app"}composeTemplate(e,t,s,r,o=!0,n=!1){let i=[];i.push("# \u2500\u2500 Svelar Docker Compose \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),i.push("# Generated by: npx svelar make:docker"),i.push("#"),i.push("# Usage:"),i.push("# docker compose up -d --build # Start all services"),i.push("# docker compose exec app npx svelar migrate # Run migrations"),i.push("# docker compose logs -f app # View app logs"),i.push("# docker compose down # Stop all services"),i.push(""),i.push("services:"),i.push(" app:"),i.push(" build: ."),i.push(" restart: unless-stopped"),i.push(" ports:"),i.push(' - "${APP_PORT:-3000}:3000"'),i.push(" env_file: .env"),i.push(" environment:"),i.push(" - NODE_ENV=production"),e==="postgres"?(i.push(" - DB_HOST=pgbouncer"),i.push(" - DB_PORT=6432")):e==="mysql"&&(i.push(" - DB_HOST=mysql"),i.push(" - DB_PORT=3306")),s&&(i.push(" - REDIS_HOST=redis"),i.push(" - REDIS_PORT=6379"),i.push(" - REDIS_PASSWORD=${REDIS_PASSWORD:-svelarsecret}"),i.push(" - QUEUE_DRIVER=redis")),t&&(i.push(" - PUSHER_HOST=soketi"),i.push(" - PUSHER_PORT=6001")),r&&i.push(" - GOTENBERG_URL=http://gotenberg:3000"),o&&(i.push(" - S3_ENDPOINT=http://rustfs:9000"),i.push(" - S3_ACCESS_KEY=${RUSTFS_ROOT_USER:-svelar}"),i.push(" - S3_SECRET_KEY=${RUSTFS_ROOT_PASSWORD:-svelarsecret}"),i.push(" - S3_BUCKET=${S3_BUCKET:-svelar}"),i.push(" - S3_REGION=us-east-1"),i.push(" - STORAGE_DISK=s3")),n&&(i.push(" - MEILISEARCH_HOST=http://meilisearch:7700"),i.push(" - MEILISEARCH_KEY=${MEILI_MASTER_KEY:-svelar-meili-master-key}"));let a=[];if(e==="postgres"&&a.push("pgbouncer"),e==="mysql"&&a.push("mysql"),s&&a.push("redis"),t&&a.push("soketi"),r&&a.push("gotenberg"),o&&a.push("rustfs"),n&&a.push("meilisearch"),a.length>0){i.push(" depends_on:");for(let c of a)i.push(` ${c}:`),i.push(" condition: service_healthy")}return i.push(" volumes:"),i.push(" - app_storage:/app/storage"),i.push(" healthcheck:"),i.push(' test: ["CMD", "wget", "-qO-", "http://localhost:3000/api/health"]'),i.push(" interval: 30s"),i.push(" timeout: 5s"),i.push(" start_period: 15s"),i.push(" retries: 3"),i.push(" deploy:"),i.push(" resources:"),i.push(" limits:"),i.push(" memory: ${APP_MEMORY_LIMIT:-1G}"),i.push(" pids: 200"),i.push(" logging:"),i.push(" driver: json-file"),i.push(" options:"),i.push(' max-size: "10m"'),i.push(' max-file: "3"'),e==="postgres"&&(i.push(""),i.push(" postgres:"),i.push(" image: postgres:17-alpine"),i.push(" restart: unless-stopped"),i.push(" # No ports exposed \u2014 only reachable via PgBouncer on the Docker network"),i.push(" command: postgres -c config_file=/etc/postgresql/postgresql.conf"),i.push(" environment:"),i.push(" POSTGRES_DB: ${DB_NAME:-svelar}"),i.push(" POSTGRES_USER: ${DB_USER:-svelar}"),i.push(" POSTGRES_PASSWORD: ${DB_PASSWORD:-secret}"),i.push(" volumes:"),i.push(" - pgdata:/var/lib/postgresql/data"),i.push(" - ./docker/postgres/postgresql.conf:/etc/postgresql/postgresql.conf:ro"),i.push(" - ./docker/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql:ro"),i.push(" healthcheck:"),i.push(' test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-svelar} -d ${DB_NAME:-svelar}"]'),i.push(" interval: 30s"),i.push(" timeout: 10s"),i.push(" retries: 5"),i.push(" deploy:"),i.push(" resources:"),i.push(" limits:"),i.push(" memory: ${POSTGRES_MEMORY_LIMIT:-1G}"),i.push(" logging:"),i.push(" driver: json-file"),i.push(" options:"),i.push(' max-size: "10m"'),i.push(' max-file: "3"'),i.push(""),i.push(" pgbouncer:"),i.push(" image: edoburu/pgbouncer:v1.25.1-p0"),i.push(" restart: unless-stopped"),i.push(" # No ports exposed \u2014 only reachable by app via Docker network"),i.push(" # Expose 6432 to host only for direct debugging (uncomment below)"),i.push(" # ports:"),i.push(' # - "6432:6432"'),i.push(" environment:"),i.push(" DATABASE_URL: postgres://${DB_USER:-svelar}:${DB_PASSWORD:-secret}@postgres:5432/${DB_NAME:-svelar}"),i.push(" volumes:"),i.push(" - ./docker/pgbouncer/pgbouncer.ini:/etc/pgbouncer/pgbouncer.ini:ro"),i.push(" depends_on:"),i.push(" postgres:"),i.push(" condition: service_healthy"),i.push(" healthcheck:"),i.push(' test: ["CMD", "pg_isready", "-h", "localhost", "-p", "6432"]'),i.push(" interval: 10s"),i.push(" timeout: 5s"),i.push(" retries: 5"),i.push(" deploy:"),i.push(" resources:"),i.push(" limits:"),i.push(" memory: 128M"),i.push(" logging:"),i.push(" driver: json-file"),i.push(" options:"),i.push(' max-size: "5m"'),i.push(' max-file: "3"')),e==="mysql"&&(i.push(""),i.push(" mysql:"),i.push(" image: mysql:8.0"),i.push(" restart: unless-stopped"),i.push(" # No ports exposed \u2014 only reachable by app via Docker network"),i.push(" environment:"),i.push(" MYSQL_DATABASE: ${DB_NAME:-svelar}"),i.push(" MYSQL_USER: ${DB_USER:-svelar}"),i.push(" MYSQL_PASSWORD: ${DB_PASSWORD:-secret}"),i.push(" MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-rootsecret}"),i.push(" volumes:"),i.push(" - mysqldata:/var/lib/mysql"),i.push(" - ./docker/mysql/init.sql:/docker-entrypoint-initdb.d/init.sql:ro"),i.push(" healthcheck:"),i.push(' test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]'),i.push(" interval: 10s"),i.push(" timeout: 5s"),i.push(" retries: 5"),i.push(" deploy:"),i.push(" resources:"),i.push(" limits:"),i.push(" memory: ${MYSQL_MEMORY_LIMIT:-1G}"),i.push(" logging:"),i.push(" driver: json-file"),i.push(" options:"),i.push(' max-size: "10m"'),i.push(' max-file: "3"')),s&&(i.push(""),i.push(" redis:"),i.push(" image: redis:7-alpine"),i.push(" restart: unless-stopped"),i.push(" # No ports exposed \u2014 only reachable by app via Docker network"),i.push(" command: redis-server --requirepass ${REDIS_PASSWORD:-svelarsecret}"),i.push(" volumes:"),i.push(" - redisdata:/data"),i.push(" healthcheck:"),i.push(' test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:-svelarsecret}", "ping"]'),i.push(" interval: 10s"),i.push(" timeout: 5s"),i.push(" retries: 5"),i.push(" deploy:"),i.push(" resources:"),i.push(" limits:"),i.push(" memory: ${REDIS_MEMORY_LIMIT:-256M}"),i.push(" logging:"),i.push(" driver: json-file"),i.push(" options:"),i.push(' max-size: "5m"'),i.push(' max-file: "3"')),t&&(i.push(""),i.push(" soketi:"),i.push(" image: quay.io/soketi/soketi:1.6-16-debian"),i.push(" restart: unless-stopped"),i.push(" # No ports exposed \u2014 only reachable by app via Docker network"),i.push(" # Expose 6001 to host only if clients connect directly (uncomment below)"),i.push(" # ports:"),i.push(' # - "${SOKETI_PORT:-6001}:6001"'),i.push(" environment:"),i.push(' SOKETI_DEBUG: "${SOKETI_DEBUG:-0}"'),i.push(" SOKETI_DEFAULT_APP_ID: ${PUSHER_APP_ID}"),i.push(" SOKETI_DEFAULT_APP_KEY: ${PUSHER_KEY}"),i.push(" SOKETI_DEFAULT_APP_SECRET: ${PUSHER_SECRET}"),i.push(' SOKETI_DEFAULT_APP_MAX_CONNS: "${SOKETI_MAX_CONNS:-1000}"'),i.push(' SOKETI_DEFAULT_APP_ENABLE_CLIENT_MESSAGES: "true"'),i.push(' SOKETI_DEFAULT_APP_MAX_BACKEND_EVENTS_PER_SEC: "-1"'),i.push(" healthcheck:"),i.push(' test: ["CMD", "wget", "-qO-", "http://localhost:6001"]'),i.push(" interval: 10s"),i.push(" timeout: 5s"),i.push(" retries: 3"),i.push(" deploy:"),i.push(" resources:"),i.push(" limits:"),i.push(" memory: 256M"),i.push(" logging:"),i.push(" driver: json-file"),i.push(" options:"),i.push(' max-size: "5m"'),i.push(' max-file: "3"')),r&&(i.push(""),i.push(" gotenberg:"),i.push(" image: gotenberg/gotenberg:8"),i.push(" restart: unless-stopped"),i.push(" # No ports exposed \u2014 only reachable by app via Docker network"),i.push(" environment:"),i.push(' CHROMIUM_DISABLE_JAVASCRIPT: "false"'),i.push(' CHROMIUM_ALLOW_LIST: "file:///tmp/.*"'),i.push(' API_TIMEOUT: "${GOTENBERG_TIMEOUT:-60s}"'),i.push(' LOG_LEVEL: "${GOTENBERG_LOG_LEVEL:-info}"'),i.push(" healthcheck:"),i.push(' test: ["CMD", "curl", "-f", "http://localhost:3000/health"]'),i.push(" interval: 10s"),i.push(" timeout: 5s"),i.push(" retries: 5"),i.push(" deploy:"),i.push(" resources:"),i.push(" limits:"),i.push(" memory: 512M"),i.push(" logging:"),i.push(" driver: json-file"),i.push(" options:"),i.push(' max-size: "5m"'),i.push(' max-file: "3"')),o&&(i.push(""),i.push(" rustfs:"),i.push(" image: rustfs/rustfs:latest"),i.push(" restart: unless-stopped"),i.push(" ports:"),i.push(' - "${RUSTFS_CONSOLE_PORT:-9001}:9001" # Admin console (protect with firewall)'),i.push(" environment:"),i.push(" RUSTFS_ROOT_USER: ${RUSTFS_ROOT_USER:-svelar}"),i.push(" RUSTFS_ROOT_PASSWORD: ${RUSTFS_ROOT_PASSWORD:-svelarsecret}"),i.push(' command: server /data --console-address ":9001"'),i.push(" volumes:"),i.push(" - rustfs_data:/data"),i.push(" healthcheck:"),i.push(' test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]'),i.push(" interval: 10s"),i.push(" timeout: 5s"),i.push(" retries: 5"),i.push(" deploy:"),i.push(" resources:"),i.push(" limits:"),i.push(" memory: 512M"),i.push(" logging:"),i.push(" driver: json-file"),i.push(" options:"),i.push(' max-size: "5m"'),i.push(' max-file: "3"')),n&&(i.push(""),i.push(" meilisearch:"),i.push(" image: getmeili/meilisearch:v1.13"),i.push(" restart: unless-stopped"),i.push(" # No ports exposed \u2014 only reachable by app via Docker network"),i.push(" # Uncomment below to access the dashboard from the host"),i.push(" # ports:"),i.push(' # - "${MEILI_PORT:-7700}:7700"'),i.push(" environment:"),i.push(" MEILI_MASTER_KEY: ${MEILI_MASTER_KEY:-svelar-meili-master-key}"),i.push(" MEILI_ENV: production"),i.push(" MEILI_DB_PATH: /meili_data"),i.push(' MEILI_NO_ANALYTICS: "true"'),i.push(" volumes:"),i.push(" - meili_data:/meili_data"),i.push(" healthcheck:"),i.push(' test: ["CMD", "wget", "--no-verbose", "--spider", "http://localhost:7700/health"]'),i.push(" interval: 10s"),i.push(" timeout: 5s"),i.push(" retries: 5"),i.push(" deploy:"),i.push(" resources:"),i.push(" limits:"),i.push(" memory: 512M"),i.push(" logging:"),i.push(" driver: json-file"),i.push(" options:"),i.push(' max-size: "5m"'),i.push(' max-file: "3"')),i.push(""),i.push("volumes:"),i.push(" app_storage:"),e==="postgres"&&i.push(" pgdata:"),e==="mysql"&&i.push(" mysqldata:"),s&&i.push(" redisdata:"),o&&i.push(" rustfs_data:"),n&&i.push(" meili_data:"),i.push(""),i.join(`
1299
1530
  `)}dockerignoreTemplate(){return`# Dependencies
1300
1531
  node_modules
1301
1532
 
@@ -1418,12 +1649,12 @@ module.exports = {
1418
1649
  },
1419
1650
  ],
1420
1651
  };
1421
- `}};import{writeFileSync as Qo,mkdirSync as Go,existsSync as Zo}from"fs";import{join as li}from"path";var ie=class extends g{name="make:ci";description="Scaffold GitHub Actions CI/CD workflow for Docker deploy";arguments=[];flags=[{name:"force",alias:"f",description:"Overwrite existing files",type:"boolean"}];async handle(e,t){let s=process.cwd(),r=t.force??!1,i=li(s,".github","workflows");Go(i,{recursive:!0});let n=li(i,"deploy.yml");if(Zo(n)&&!r){this.warn(".github/workflows/deploy.yml already exists (use --force to overwrite)");return}Qo(n,N.githubActionsWorkflow()),this.success("Created .github/workflows/deploy.yml"),this.newLine(),this.info("Required GitHub Secrets:"),this.log(" DOCKER_USERNAME \u2014 Docker Hub username"),this.log(" DOCKER_TOKEN \u2014 Docker Hub access token"),this.log(" DOCKER_IMAGE_NAME \u2014 Docker image name (e.g. myapp)"),this.log(" DROPLET_HOST \u2014 Droplet IP or hostname"),this.log(" DROPLET_USER \u2014 SSH user on the droplet (e.g. deploy)"),this.log(" DROPLET_SSH_KEY \u2014 Private SSH key for the deploy user"),this.log(" DROPLET_PROJECT \u2014 Project directory name on the droplet"),this.log(" ENV_PROD \u2014 Complete production .env file contents")}};import{writeFileSync as Xo,mkdirSync as ea,existsSync as ci,readFileSync as di,chmodSync as ta,appendFileSync as sa}from"fs";import{join as Ae}from"path";var ne=class extends g{name="make:infra";description="Scaffold infrastructure files (droplet setup script, env template)";arguments=[];flags=[{name:"force",alias:"f",description:"Overwrite existing files",type:"boolean"}];async handle(e,t){let s=process.cwd(),r=t.force??!1,i=this.resolveAppName(s),n=Ae(s,"infra");ea(n,{recursive:!0});let o=[{path:Ae(n,"setup-droplet.sh"),content:N.setupDropletScript(i),label:"infra/setup-droplet.sh"},{path:Ae(n,"droplet.env.example"),content:N.dropletEnvExample(i),label:"infra/droplet.env.example"}],a=0,c=0;for(let u of o){if(ci(u.path)&&!r){this.warn(`${u.label} already exists (use --force to overwrite)`),c++;continue}Xo(u.path,u.content),u.path.endsWith(".sh")&&ta(u.path,493),this.success(`Created ${u.label}`),a++}this.addToGitignore(s),this.newLine(),a>0?this.info(`${a} file(s) created${c>0?`, ${c} skipped`:""}`):this.info("No files created (all exist already)"),this.newLine(),this.info("Next steps:"),this.log(" 1. Copy and fill in your config:"),this.log(" cp infra/droplet.env.example infra/droplet.env"),this.newLine(),this.log(" 2. Run the setup:"),this.log(" npx svelar infra:setup"),this.log(" (or: bash infra/setup-droplet.sh)")}addToGitignore(e){let t=Ae(e,".gitignore"),s=["infra/droplet.env"],r="";ci(t)&&(r=di(t,"utf-8"));let i=s.filter(o=>!r.includes(o));if(i.length===0)return;let n=`
1652
+ `}};import{writeFileSync as Gn,mkdirSync as Qn,existsSync as Zn}from"fs";import{join as li}from"path";var ie=class extends g{name="make:ci";description="Scaffold GitHub Actions CI/CD workflow for Docker deploy";arguments=[];flags=[{name:"force",alias:"f",description:"Overwrite existing files",type:"boolean"}];async handle(e,t){let s=process.cwd(),r=t.force??!1,o=li(s,".github","workflows");Qn(o,{recursive:!0});let n=li(o,"deploy.yml");if(Zn(n)&&!r){this.warn(".github/workflows/deploy.yml already exists (use --force to overwrite)");return}Gn(n,O.githubActionsWorkflow()),this.success("Created .github/workflows/deploy.yml"),this.newLine(),this.info("Workflow steps: build image \u2192 push to Docker Hub \u2192 SCP compose files \u2192 SSH deploy"),this.newLine(),this.info("Required GitHub Secrets:"),this.log(" DOCKER_USERNAME \u2014 Docker Hub username"),this.log(" DOCKER_TOKEN \u2014 Docker Hub access token"),this.log(" DOCKER_IMAGE_NAME \u2014 Docker image name (e.g. myapp)"),this.log(" DROPLET_HOST \u2014 Droplet IP or hostname"),this.log(" DROPLET_USER \u2014 SSH user on the droplet (e.g. deploy)"),this.log(" DROPLET_SSH_KEY \u2014 Private SSH key for the deploy user"),this.log(" DROPLET_PROJECT \u2014 Project directory name on the droplet"),this.log(" ENV_PROD \u2014 Complete production .env file contents")}};import{writeFileSync as Xn,mkdirSync as ea,existsSync as ci,readFileSync as di,chmodSync as ta,appendFileSync as sa}from"fs";import{join as Ae}from"path";var oe=class extends g{name="make:infra";description="Scaffold infrastructure files (droplet setup script, env template)";arguments=[];flags=[{name:"force",alias:"f",description:"Overwrite existing files",type:"boolean"}];async handle(e,t){let s=process.cwd(),r=t.force??!1,o=this.resolveAppName(s),n=Ae(s,"infra");ea(n,{recursive:!0});let i=[{path:Ae(n,"setup-droplet.sh"),content:O.setupDropletScript(o),label:"infra/setup-droplet.sh"},{path:Ae(n,"droplet.env.example"),content:O.dropletEnvExample(o),label:"infra/droplet.env.example"}],a=0,c=0;for(let u of i){if(ci(u.path)&&!r){this.warn(`${u.label} already exists (use --force to overwrite)`),c++;continue}Xn(u.path,u.content),u.path.endsWith(".sh")&&ta(u.path,493),this.success(`Created ${u.label}`),a++}this.addToGitignore(s),this.newLine(),a>0?this.info(`${a} file(s) created${c>0?`, ${c} skipped`:""}`):this.info("No files created (all exist already)"),this.newLine(),this.info("Next steps:"),this.log(" 1. Copy and fill in your config:"),this.log(" cp infra/droplet.env.example infra/droplet.env"),this.newLine(),this.log(" 2. Run the setup:"),this.log(" npx svelar infra:setup"),this.log(" (or: bash infra/setup-droplet.sh)")}addToGitignore(e){let t=Ae(e,".gitignore"),s=["infra/droplet.env"],r="";ci(t)&&(r=di(t,"utf-8"));let o=s.filter(i=>!r.includes(i));if(o.length===0)return;let n=`
1422
1653
  # Infrastructure (contains server IPs and SSH key paths)
1423
- `+i.join(`
1654
+ `+o.join(`
1424
1655
  `)+`
1425
- `;sa(t,n),this.success("Updated .gitignore (infra/droplet.env)")}resolveAppName(e){try{let t=JSON.parse(di(Ae(e,"package.json"),"utf-8"));if(t.name&&typeof t.name=="string")return t.name.replace(/^@[^/]+\//,"")}catch{}return"svelar-app"}};import{existsSync as ui,readFileSync as mi}from"fs";import{join as Us}from"path";import{execSync as pi}from"child_process";var wt=class extends g{name="infra:setup";description="Provision a droplet via SSH and copy deployment files";arguments=[];flags=[{name:"config",alias:"c",description:"Path to config file (default: infra/droplet.env)",type:"string"},{name:"ip",description:"Droplet IP or hostname",type:"string"},{name:"key",alias:"k",description:"Path to SSH private key",type:"string"},{name:"user",alias:"u",description:"SSH user for initial setup (default: root)",type:"string"},{name:"deploy-user",description:"Deploy user to create (default: deploy)",type:"string"},{name:"project",alias:"p",description:"Project name / remote directory name",type:"string"}];async handle(e,t){let s=process.cwd(),r=Us(s,"infra","setup-droplet.sh");if(!ui(r)){this.error("infra/setup-droplet.sh not found. Run `npx svelar make:infra` first.");return}let i=t.ip||t.key,n=t.config??Us(s,"infra","droplet.env");if(i){let o=[];if(t.ip||o.push("--ip"),t.key||o.push("--key"),o.length>0){this.error(`Missing required flags: ${o.join(", ")}`),this.newLine(),this.info("Usage with flags:"),this.log(" npx svelar infra:setup --ip=123.45.67.89 --key=~/.ssh/id_ed25519"),this.newLine(),this.info("Or create a config file:"),this.log(" cp infra/droplet.env.example infra/droplet.env"),this.log(" npx svelar infra:setup");return}let a=this.resolveAppName(s),c=[`DROPLET_IP=${t.ip}`,`SSH_KEY_PATH=${t.key}`,`DEPLOY_USER=${t["deploy-user"]??"deploy"}`,`PROJECT_NAME=${t.project??a}`].join(" ");this.info("Running infra/setup-droplet.sh with flags..."),this.newLine();try{pi(`${c} bash "${r}"`,{stdio:"inherit",cwd:s,shell:"bash"})}catch{this.newLine(),this.error("Setup failed. Check the output above for details.")}}else{if(!ui(n)){this.error(`Config file not found: ${n}`),this.newLine(),this.info("Option 1 \u2014 Create a config file:"),this.log(" cp infra/droplet.env.example infra/droplet.env"),this.log(" # Fill in DROPLET_IP, DEPLOY_USER, PROJECT_NAME, SSH_KEY_PATH"),this.log(" npx svelar infra:setup"),this.newLine(),this.info("Option 2 \u2014 Pass values as flags:"),this.log(" npx svelar infra:setup --ip=123.45.67.89 --key=~/.ssh/id_ed25519"),this.newLine(),this.info("Required variables:"),this.log(" DROPLET_IP \u2014 Server IP address"),this.log(" SSH_KEY_PATH \u2014 Path to SSH private key (.pub must exist alongside)"),this.log(" DEPLOY_USER \u2014 Non-root user to create (default: deploy)"),this.log(" PROJECT_NAME \u2014 Remote directory name (default: package.json name)");return}let o=mi(n,"utf-8"),a=this.parseEnvFile(o),c=["DROPLET_IP","SSH_KEY_PATH"],u=[];for(let p of c)a[p]||u.push(p);if(u.length>0){this.error(`Missing required variables in ${n}:`);for(let p of u)this.log(` ${p} is empty or not set`);this.newLine(),this.info("Edit the config file and fill in the required values.");return}this.info("Running infra/setup-droplet.sh..."),this.newLine();try{pi(`bash "${r}" --config "${n}"`,{stdio:"inherit",cwd:s})}catch{this.newLine(),this.error("Setup failed. Check the output above for details.")}}}resolveAppName(e){try{let t=JSON.parse(mi(Us(e,"package.json"),"utf-8"));if(t.name&&typeof t.name=="string")return t.name.replace(/^@[^/]+\//,"")}catch{}return"svelar-app"}parseEnvFile(e){let t={};for(let s of e.split(`
1426
- `)){let r=s.trim();if(!r||r.startsWith("#"))continue;let i=r.indexOf("=");if(i===-1)continue;let n=r.slice(0,i).trim(),o=r.slice(i+1).trim();(o.startsWith('"')&&o.endsWith('"')||o.startsWith("'")&&o.endsWith("'"))&&(o=o.slice(1,-1)),t[n]=o}return t}};var Ct=class extends g{name="make:deploy";description="Scaffold all deployment files (Docker, CI/CD, infrastructure)";arguments=[];flags=[{name:"db",alias:"d",description:"Database driver: postgres, mysql, sqlite (default: postgres)",type:"string"},{name:"image",alias:"i",description:"Docker image name for compose fallback (default: package.json name)",type:"string"},{name:"port",description:"Production port (default: 3000)",type:"string"},{name:"dev-port",description:"Development port (default: 5173)",type:"string"},{name:"force",alias:"f",description:"Overwrite existing files",type:"boolean"}];async handle(e,t){this.info("Scaffolding all deployment files..."),this.newLine(),await new re().handle(e,t),this.newLine(),this.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),this.newLine(),await new ie().handle(e,t),this.newLine(),this.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),this.newLine(),await new ne().handle(e,t),this.newLine(),this.success("All deployment files scaffolded!")}};import{writeFileSync as ra,mkdirSync as ia,existsSync as hi}from"fs";import{join as K}from"path";var xt=class extends g{name="make:broadcasting";description="Scaffold broadcasting routes (Pusher auth, SSE stream, client init)";arguments=[];flags=[{name:"sse",description:"Only scaffold SSE routes (no Pusher auth)",type:"boolean"},{name:"pusher",description:"Only scaffold Pusher/Soketi routes",type:"boolean"},{name:"force",alias:"f",description:"Overwrite existing files",type:"boolean"}];async handle(e,t){let s=process.cwd(),r=t.force??!1,i=t.sse??!1,n=t.pusher??!1,o=!i&&!n,a=[];(o||n)&&a.push({path:K(s,"src/routes/api/broadcasting/auth/+server.ts"),content:this.pusherAuthRoute(),label:"src/routes/api/broadcasting/auth/+server.ts",dirs:[K(s,"src/routes/api/broadcasting/auth")]}),(o||i)&&a.push({path:K(s,"src/routes/api/broadcasting/[channel]/+server.ts"),content:this.sseRoute(),label:"src/routes/api/broadcasting/[channel]/+server.ts",dirs:[K(s,"src/routes/api/broadcasting/[channel]")]}),a.push({path:K(s,"src/lib/broadcasting.ts"),content:o||n?this.clientPusher():this.clientSSE(),label:"src/lib/broadcasting.ts",dirs:[K(s,"src/lib")]});let c=K(s,"config/broadcasting.ts");hi(c)||a.push({path:c,content:this.configTemplate(),label:"config/broadcasting.ts",dirs:[K(s,"config")]});let u=0,p=0;for(let h of a){if(hi(h.path)&&!r){this.warn(`${h.label} already exists (use --force to overwrite)`),p++;continue}for(let m of h.dirs)ia(m,{recursive:!0});ra(h.path,h.content),this.success(`Created ${h.label}`),u++}this.newLine(),u>0?this.info(`${u} file(s) created${p>0?`, ${p} skipped`:""}`):this.info("No files created (all exist already)"),this.newLine(),this.info("Next steps:"),o||n?(this.log(" 1. Install pusher-js: npm install pusher-js"),this.log(" 2. Add Pusher env vars to .env:"),this.log(" BROADCAST_DRIVER=pusher"),this.log(" PUSHER_KEY=svelar-key"),this.log(" PUSHER_SECRET=svelar-secret"),this.log(" PUSHER_APP_ID=svelar-app"),this.log(' PUSHER_HOST=localhost # or "soketi" in Docker'),this.log(" PUSHER_PORT=6001"),this.log(" 3. Import broadcasting in your root layout:"),this.log(" import '$lib/broadcasting';")):(this.log(" 1. Import broadcasting in your root layout:"),this.log(" import '$lib/broadcasting';")),this.log(" 4. Register channel authorizations in src/app.ts"),this.log(" 5. Run 'npx svelar make:docker' for Soketi in Docker Compose")}pusherAuthRoute(){return`/**
1656
+ `;sa(t,n),this.success("Updated .gitignore (infra/droplet.env)")}resolveAppName(e){try{let t=JSON.parse(di(Ae(e,"package.json"),"utf-8"));if(t.name&&typeof t.name=="string")return t.name.replace(/^@[^/]+\//,"")}catch{}return"svelar-app"}};import{existsSync as ui,readFileSync as mi}from"fs";import{join as qs}from"path";import{execSync as pi}from"child_process";var Ct=class extends g{name="infra:setup";description="Provision a droplet via SSH and copy deployment files";arguments=[];flags=[{name:"config",alias:"c",description:"Path to config file (default: infra/droplet.env)",type:"string"},{name:"ip",description:"Droplet IP or hostname",type:"string"},{name:"key",alias:"k",description:"Path to SSH private key",type:"string"},{name:"user",alias:"u",description:"SSH user for initial setup (default: root)",type:"string"},{name:"deploy-user",description:"Deploy user to create (default: deploy)",type:"string"},{name:"project",alias:"p",description:"Project name / remote directory name",type:"string"}];async handle(e,t){let s=process.cwd(),r=qs(s,"infra","setup-droplet.sh");if(!ui(r)){this.error("infra/setup-droplet.sh not found. Run `npx svelar make:infra` first.");return}let o=t.ip||t.key,n=t.config??qs(s,"infra","droplet.env");if(o){let i=[];if(t.ip||i.push("--ip"),t.key||i.push("--key"),i.length>0){this.error(`Missing required flags: ${i.join(", ")}`),this.newLine(),this.info("Usage with flags:"),this.log(" npx svelar infra:setup --ip=123.45.67.89 --key=~/.ssh/id_ed25519"),this.newLine(),this.info("Or create a config file:"),this.log(" cp infra/droplet.env.example infra/droplet.env"),this.log(" npx svelar infra:setup");return}let a=this.resolveAppName(s),c=/^[a-zA-Z0-9@._:~\/ -]+$/,u=process.env.HOME||process.env.USERPROFILE||"",p=m=>m.replace(/^~(?=\/|$)/,u),h={ip:String(t.ip),key:p(String(t.key)),"deploy-user":String(t["deploy-user"]??"deploy"),project:String(t.project??a)};for(let[m,f]of Object.entries(h))if(!c.test(f)){this.error(`Invalid characters in --${m} flag: ${f}`);return}this.info("Running infra/setup-droplet.sh with flags..."),this.newLine();try{pi(`bash "${r}"`,{stdio:"inherit",cwd:s,shell:"bash",env:{...process.env,DROPLET_IP:h.ip,SSH_KEY_PATH:h.key,DEPLOY_USER:h["deploy-user"],PROJECT_NAME:h.project}})}catch{this.newLine(),this.error("Setup failed. Check the output above for details.")}}else{if(!ui(n)){this.error(`Config file not found: ${n}`),this.newLine(),this.info("Option 1 \u2014 Create a config file:"),this.log(" cp infra/droplet.env.example infra/droplet.env"),this.log(" # Fill in DROPLET_IP, DEPLOY_USER, PROJECT_NAME, SSH_KEY_PATH"),this.log(" npx svelar infra:setup"),this.newLine(),this.info("Option 2 \u2014 Pass values as flags:"),this.log(" npx svelar infra:setup --ip=123.45.67.89 --key=~/.ssh/id_ed25519"),this.newLine(),this.info("Required variables:"),this.log(" DROPLET_IP \u2014 Server IP address"),this.log(" SSH_KEY_PATH \u2014 Path to SSH private key (.pub must exist alongside)"),this.log(" DEPLOY_USER \u2014 Non-root user to create (default: deploy)"),this.log(" PROJECT_NAME \u2014 Remote directory name (default: package.json name)");return}let i=mi(n,"utf-8"),a=this.parseEnvFile(i),c=["DROPLET_IP","SSH_KEY_PATH"],u=[];for(let p of c)a[p]||u.push(p);if(u.length>0){this.error(`Missing required variables in ${n}:`);for(let p of u)this.log(` ${p} is empty or not set`);this.newLine(),this.info("Edit the config file and fill in the required values.");return}this.info("Running infra/setup-droplet.sh..."),this.newLine();try{pi(`bash "${r}" --config "${n}"`,{stdio:"inherit",cwd:s})}catch{this.newLine(),this.error("Setup failed. Check the output above for details.")}}}resolveAppName(e){try{let t=JSON.parse(mi(qs(e,"package.json"),"utf-8"));if(t.name&&typeof t.name=="string")return t.name.replace(/^@[^/]+\//,"")}catch{}return"svelar-app"}parseEnvFile(e){let t={};for(let s of e.split(`
1657
+ `)){let r=s.trim();if(!r||r.startsWith("#"))continue;let o=r.indexOf("=");if(o===-1)continue;let n=r.slice(0,o).trim(),i=r.slice(o+1).trim();(i.startsWith('"')&&i.endsWith('"')||i.startsWith("'")&&i.endsWith("'"))&&(i=i.slice(1,-1)),t[n]=i}return t}};var xt=class extends g{name="make:deploy";description="Scaffold all deployment files (Docker, CI/CD, infrastructure)";arguments=[];flags=[{name:"db",alias:"d",description:"Database driver: postgres, mysql, sqlite (default: postgres)",type:"string"},{name:"image",alias:"i",description:"Docker image name for compose fallback (default: package.json name)",type:"string"},{name:"port",description:"Production port (default: 3000)",type:"string"},{name:"dev-port",description:"Development port (default: 5173)",type:"string"},{name:"force",alias:"f",description:"Overwrite existing files",type:"boolean"}];async handle(e,t){this.info("Scaffolding all deployment files..."),this.newLine(),await new re().handle(e,t),this.newLine(),this.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),this.newLine(),await new ie().handle(e,t),this.newLine(),this.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),this.newLine(),await new oe().handle(e,t),this.newLine(),this.success("All deployment files scaffolded!")}};import{writeFileSync as ra,mkdirSync as ia,existsSync as hi}from"fs";import{join as K}from"path";var St=class extends g{name="make:broadcasting";description="Scaffold broadcasting routes (Pusher auth, SSE stream, client init)";arguments=[];flags=[{name:"sse",description:"Only scaffold SSE routes (no Pusher auth)",type:"boolean"},{name:"pusher",description:"Only scaffold Pusher/Soketi routes",type:"boolean"},{name:"force",alias:"f",description:"Overwrite existing files",type:"boolean"}];async handle(e,t){let s=process.cwd(),r=t.force??!1,o=t.sse??!1,n=t.pusher??!1,i=!o&&!n,a=[];(i||n)&&a.push({path:K(s,"src/routes/api/broadcasting/auth/+server.ts"),content:this.pusherAuthRoute(),label:"src/routes/api/broadcasting/auth/+server.ts",dirs:[K(s,"src/routes/api/broadcasting/auth")]}),(i||o)&&a.push({path:K(s,"src/routes/api/broadcasting/[channel]/+server.ts"),content:this.sseRoute(),label:"src/routes/api/broadcasting/[channel]/+server.ts",dirs:[K(s,"src/routes/api/broadcasting/[channel]")]}),a.push({path:K(s,"src/lib/broadcasting.ts"),content:i||n?this.clientPusher():this.clientSSE(),label:"src/lib/broadcasting.ts",dirs:[K(s,"src/lib")]});let c=K(s,"config/broadcasting.ts");hi(c)||a.push({path:c,content:this.configTemplate(),label:"config/broadcasting.ts",dirs:[K(s,"config")]});let u=0,p=0;for(let h of a){if(hi(h.path)&&!r){this.warn(`${h.label} already exists (use --force to overwrite)`),p++;continue}for(let m of h.dirs)ia(m,{recursive:!0});ra(h.path,h.content),this.success(`Created ${h.label}`),u++}this.newLine(),u>0?this.info(`${u} file(s) created${p>0?`, ${p} skipped`:""}`):this.info("No files created (all exist already)"),this.newLine(),this.info("Next steps:"),i||n?(this.log(" 1. Install pusher-js: npm install pusher-js"),this.log(" 2. Add Pusher env vars to .env:"),this.log(" BROADCAST_DRIVER=pusher"),this.log(" PUSHER_KEY=svelar-key"),this.log(" PUSHER_SECRET=svelar-secret"),this.log(" PUSHER_APP_ID=svelar-app"),this.log(' PUSHER_HOST=localhost # or "soketi" in Docker'),this.log(" PUSHER_PORT=6001"),this.log(" 3. Import broadcasting in your root layout:"),this.log(" import '$lib/broadcasting';")):(this.log(" 1. Import broadcasting in your root layout:"),this.log(" import '$lib/broadcasting';")),this.log(" 4. Register channel authorizations in src/app.ts"),this.log(" 5. Run 'npx svelar make:docker' for Soketi in Docker Compose")}pusherAuthRoute(){return`/**
1427
1658
  * Pusher/Soketi Channel Authorization Endpoint
1428
1659
  *
1429
1660
  * This route authenticates channel subscriptions from pusher-js.
@@ -1577,7 +1808,7 @@ export default {
1577
1808
  },
1578
1809
  },
1579
1810
  };
1580
- `}};import{writeFileSync as na,mkdirSync as oa,existsSync as aa}from"fs";import{join as gi}from"path";var St=class extends g{name="make:test";description="Create a new test file";arguments=["name"];flags=[{name:"unit",alias:"u",description:"Create a unit test (default)",type:"boolean",default:!1},{name:"feature",alias:"f",description:"Create a feature test",type:"boolean",default:!1},{name:"e2e",alias:"e",description:"Create an e2e (Playwright) test",type:"boolean",default:!1}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a test name.");return}let r="unit";t.feature&&(r="feature"),t.e2e&&(r="e2e");let i=r==="e2e"?".spec.ts":".test.ts",n=gi(process.cwd(),"tests",r);oa(n,{recursive:!0});let o=s.endsWith(i)?s:`${s}${i}`,a=gi(n,o);if(aa(a)){this.warn(`Test file already exists: tests/${r}/${o}`);return}let c;switch(r){case"unit":c=la(s);break;case"feature":c=ca(s);break;case"e2e":c=da(s);break}na(a,c),this.success(`Test created: tests/${r}/${o}`)}};function la(l){return`import { describe, it, expect } from 'vitest';
1811
+ `}};import{writeFileSync as oa,mkdirSync as na,existsSync as aa}from"fs";import{join as gi}from"path";var Pt=class extends g{name="make:test";description="Create a new test file";arguments=["name"];flags=[{name:"unit",alias:"u",description:"Create a unit test (default)",type:"boolean",default:!1},{name:"feature",alias:"f",description:"Create a feature test",type:"boolean",default:!1},{name:"e2e",alias:"e",description:"Create an e2e (Playwright) test",type:"boolean",default:!1}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a test name.");return}let r="unit";t.feature&&(r="feature"),t.e2e&&(r="e2e");let o=r==="e2e"?".spec.ts":".test.ts",n=gi(process.cwd(),"tests",r);na(n,{recursive:!0});let i=s.endsWith(o)?s:`${s}${o}`,a=gi(n,i);if(aa(a)){this.warn(`Test file already exists: tests/${r}/${i}`);return}let c;switch(r){case"unit":c=la(s);break;case"feature":c=ca(s);break;case"e2e":c=da(s);break}oa(a,c),this.success(`Test created: tests/${r}/${i}`)}};function la(l){return`import { describe, it, expect } from 'vitest';
1581
1812
 
1582
1813
  describe('${l}', () => {
1583
1814
  it('should work', () => {
@@ -1602,25 +1833,25 @@ test.describe('${l}', () => {
1602
1833
  await expect(page).toHaveTitle(/.*/);
1603
1834
  });
1604
1835
  });
1605
- `}import{writeFileSync as ua,mkdirSync as ma,existsSync as pa}from"fs";import{join as fi}from"path";var Pt=class extends g{name="make:factory";description="Create a new model factory for testing";arguments=["name"];flags=[{name:"model",alias:"m",description:"The model class name",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a factory name.");return}let r=s.endsWith("Factory")?s:`${s}Factory`,i=t.model||s.replace(/Factory$/,""),n=fi(process.cwd(),"src","lib","factories");ma(n,{recursive:!0});let o=fi(n,`${r}.ts`);if(pa(o)){this.warn(`Factory ${r} already exists.`);return}let a=this.resolveModelImport(i),c=`import { Factory } from '@beeblock/svelar/testing';
1606
- import { ${i} } from '${a}';
1836
+ `}import{writeFileSync as ua,mkdirSync as ma,existsSync as pa}from"fs";import{join as fi}from"path";var Rt=class extends g{name="make:factory";description="Create a new model factory for testing";arguments=["name"];flags=[{name:"model",alias:"m",description:"The model class name",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a factory name.");return}let r=s.endsWith("Factory")?s:`${s}Factory`,o=t.model||s.replace(/Factory$/,""),n=fi(process.cwd(),"src","lib","factories");ma(n,{recursive:!0});let i=fi(n,`${r}.ts`);if(pa(i)){this.warn(`Factory ${r} already exists.`);return}let a=this.resolveModelImport(o),c=`import { Factory } from '@beeblock/svelar/testing';
1837
+ import { ${o} } from '${a}';
1607
1838
 
1608
- export class ${r} extends Factory<${i}> {
1839
+ export class ${r} extends Factory<${o}> {
1609
1840
  model() {
1610
- return ${i};
1841
+ return ${o};
1611
1842
  }
1612
1843
 
1613
1844
  definition() {
1614
1845
  return {
1615
- name: \`${i} \${this.sequence}\`,
1616
- email: \`${i.toLowerCase()}\${this.sequence}@test.com\`,
1846
+ name: \`${o} \${this.sequence}\`,
1847
+ email: \`${o.toLowerCase()}\${this.sequence}@test.com\`,
1617
1848
  };
1618
1849
  }
1619
1850
  }
1620
1851
 
1621
1852
  // Singleton instance for convenience
1622
1853
  export default new ${r}();
1623
- `;ua(o,c),this.success(`Factory created: src/lib/factories/${r}.ts`)}resolveModelImport(e){if(this.isDDD()){let t=e.toLowerCase();return`$lib/modules/${{User:"auth",Post:"posts"}[e]||t}/${e}`}return`$lib/models/${e}`}};import{existsSync as vi}from"fs";import{execSync as ha}from"child_process";import{join as bi}from"path";var k=class extends g{arguments=[];composeExec(e,t,s={}){let r=process.cwd(),i=bi(r,"docker-compose.yml"),n=bi(r,t?"docker-compose.dev.yml":"docker-compose.prod.yml");if(!vi(i)){this.error("docker-compose.yml not found. Run `npx svelar make:docker` first.");return}if(!vi(n)){let u=t?"docker-compose.dev.yml":"docker-compose.prod.yml";this.error(`${u} not found. Run \`npx svelar make:docker\` first.`);return}let o=s.service,a=["docker","compose","-f","docker-compose.yml","-f",t?"docker-compose.dev.yml":"docker-compose.prod.yml",...e];o&&a.push(o);let c=a.join(" ");this.info(c);try{ha(c,{cwd:r,stdio:"inherit"})}catch{}}};var Rt=class extends k{name="dev:up";description="Start development containers (docker compose up with dev override)";flags=[{name:"service",description:"Target a specific service",type:"string"}];async handle(e,t){this.composeExec(["up","-d","--build"],!0,t)}};var Et=class extends k{name="dev:down";description="Stop development containers";flags=[{name:"service",description:"Target a specific service",type:"string"}];async handle(e,t){this.composeExec(["down"],!0,t)}};var Tt=class extends k{name="dev:logs";description="Follow development container logs";flags=[{name:"service",description:"Target a specific service",type:"string"}];async handle(e,t){this.composeExec(["logs","-f"],!0,t)}};var kt=class extends k{name="dev:restart";description="Restart development containers (down + up)";flags=[{name:"service",description:"Target a specific service",type:"string"}];async handle(e,t){this.composeExec(["down"],!0,t),this.composeExec(["up","-d","--build"],!0,t)}};var $t=class extends k{name="prod:up";description="Start production containers (docker compose up with prod override)";flags=[{name:"service",description:"Target a specific service",type:"string"}];async handle(e,t){this.composeExec(["up","-d"],!1,t)}};var Dt=class extends k{name="prod:down";description="Stop production containers";flags=[{name:"service",description:"Target a specific service",type:"string"}];async handle(e,t){this.composeExec(["down"],!1,t)}};var At=class extends k{name="prod:logs";description="Follow production container logs";flags=[{name:"service",description:"Target a specific service",type:"string"}];async handle(e,t){this.composeExec(["logs","-f"],!1,t)}};var _t=class extends k{name="prod:restart";description="Restart production containers (down + up)";flags=[{name:"service",description:"Target a specific service",type:"string"}];async handle(e,t){this.composeExec(["down"],!1,t),this.composeExec(["up","-d"],!1,t)}};var Lt=class extends k{name="prod:deploy";description="Pull latest images and redeploy production containers";flags=[{name:"service",description:"Target a specific service",type:"string"}];async handle(e,t){this.composeExec(["pull"],!1,t),this.composeExec(["up","-d"],!1,t)}};import{writeFileSync as yi,mkdirSync as ga,existsSync as wi}from"fs";import{join as Ci}from"path";var Mt=class extends g{name="make:resource";description="Create a new API resource (response transformer)";arguments=["name"];flags=[{name:"module",description:"Module name (e.g. auth, billing)",type:"string"},{name:"model",alias:"m",description:"Model name to transform",type:"string"},{name:"collection",alias:"c",description:"Also generate a collection resource",type:"boolean"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a resource name.");return}let r=s.endsWith("Resource")?s:`${s}Resource`,i=t.module||this.deriveModuleName(r);!t.module&&this.isDDD()&&this.warn(`No --module specified, using "${i}". Use --module=<name> to target a specific module.`);let n=this.moduleDir(i,"resources");ga(n,{recursive:!0});let o=Ci(n,`${r}.ts`);if(wi(o)){this.warn(`Resource ${r} already exists.`);return}let a=t.model||this.inferModelName(r),c=this.isDDD()?`./${a}.js`:`../models/${a}.js`,u=this.generateResource(r,a,c);yi(o,u);let p=this.isDDD()?`src/lib/modules/${i}`:"src/lib/resources";if(this.success(`Resource created: ${p}/${r}.ts`),t.collection){let h=r.replace("Resource","CollectionResource"),m=Ci(n,`${h}.ts`);if(!wi(m)){let f=this.isDDD()?`./${a}.js`:`../models/${a}.js`,y=this.generateCollectionResource(h,r,a,f);yi(m,y);let C=this.isDDD()?`src/lib/modules/${i}`:"src/lib/resources";this.success(`Collection resource created: ${C}/${h}.ts`)}}}generateResource(e,t,s=`./${t}.js`){let r=`${t}Data`;return`import { Resource } from '@beeblock/svelar/routing';
1854
+ `;ua(i,c),this.success(`Factory created: src/lib/factories/${r}.ts`)}resolveModelImport(e){if(this.isDDD()){let t=e.toLowerCase();return`$lib/modules/${{User:"auth",Post:"posts"}[e]||t}/${e}`}return`$lib/models/${e}`}};import{existsSync as vi}from"fs";import{execSync as ha}from"child_process";import{join as bi}from"path";var k=class extends g{arguments=[];composeExec(e,t,s={}){let r=process.cwd(),o=bi(r,"docker-compose.yml"),n=bi(r,t?"docker-compose.dev.yml":"docker-compose.prod.yml");if(!vi(o)){this.error("docker-compose.yml not found. Run `npx svelar make:docker` first.");return}if(!vi(n)){let u=t?"docker-compose.dev.yml":"docker-compose.prod.yml";this.error(`${u} not found. Run \`npx svelar make:docker\` first.`);return}let i=s.service;if(i&&!/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(i)){this.error(`Invalid service name: ${i}`);return}let a=["docker","compose","-f","docker-compose.yml","-f",t?"docker-compose.dev.yml":"docker-compose.prod.yml",...e];i&&a.push(i);let c=a.join(" ");this.info(c);try{ha(c,{cwd:r,stdio:"inherit"})}catch{}}};var Et=class extends k{name="dev:up";description="Start development containers (docker compose up with dev override)";flags=[{name:"service",description:"Target a specific service",type:"string"}];async handle(e,t){this.composeExec(["up","-d","--build"],!0,t)}};var Tt=class extends k{name="dev:down";description="Stop development containers";flags=[{name:"service",description:"Target a specific service",type:"string"}];async handle(e,t){this.composeExec(["down"],!0,t)}};var kt=class extends k{name="dev:logs";description="Follow development container logs";flags=[{name:"service",description:"Target a specific service",type:"string"}];async handle(e,t){this.composeExec(["logs","-f"],!0,t)}};var $t=class extends k{name="dev:restart";description="Restart development containers (down + up)";flags=[{name:"service",description:"Target a specific service",type:"string"}];async handle(e,t){this.composeExec(["down"],!0,t),this.composeExec(["up","-d","--build"],!0,t)}};var Dt=class extends k{name="prod:up";description="Start production containers (docker compose up with prod override)";flags=[{name:"service",description:"Target a specific service",type:"string"}];async handle(e,t){this.composeExec(["up","-d"],!1,t)}};var At=class extends k{name="prod:down";description="Stop production containers";flags=[{name:"service",description:"Target a specific service",type:"string"}];async handle(e,t){this.composeExec(["down"],!1,t)}};var _t=class extends k{name="prod:logs";description="Follow production container logs";flags=[{name:"service",description:"Target a specific service",type:"string"}];async handle(e,t){this.composeExec(["logs","-f"],!1,t)}};var Lt=class extends k{name="prod:restart";description="Restart production containers (down + up)";flags=[{name:"service",description:"Target a specific service",type:"string"}];async handle(e,t){this.composeExec(["down"],!1,t),this.composeExec(["up","-d"],!1,t)}};var Mt=class extends k{name="prod:deploy";description="Pull latest images and redeploy production containers";flags=[{name:"service",description:"Target a specific service",type:"string"}];async handle(e,t){this.composeExec(["pull"],!1,t),this.composeExec(["up","-d"],!1,t)}};import{writeFileSync as yi,mkdirSync as ga,existsSync as wi}from"fs";import{join as Ci}from"path";var Ot=class extends g{name="make:resource";description="Create a new API resource (response transformer)";arguments=["name"];flags=[{name:"module",description:"Module name (e.g. auth, billing)",type:"string"},{name:"model",alias:"m",description:"Model name to transform",type:"string"},{name:"collection",alias:"c",description:"Also generate a collection resource",type:"boolean"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a resource name.");return}let r=s.endsWith("Resource")?s:`${s}Resource`,o=t.module||this.deriveModuleName(r);!t.module&&this.isDDD()&&this.warn(`No --module specified, using "${o}". Use --module=<name> to target a specific module.`);let n=this.moduleDir(o,"resources");ga(n,{recursive:!0});let i=Ci(n,`${r}.ts`);if(wi(i)){this.warn(`Resource ${r} already exists.`);return}let a=t.model||this.inferModelName(r),c=this.isDDD()?`./${a}.js`:`../models/${a}.js`,u=this.generateResource(r,a,c);yi(i,u);let p=this.isDDD()?`src/lib/modules/${o}`:"src/lib/resources";if(this.success(`Resource created: ${p}/${r}.ts`),t.collection){let h=r.replace("Resource","CollectionResource"),m=Ci(n,`${h}.ts`);if(!wi(m)){let f=this.isDDD()?`./${a}.js`:`../models/${a}.js`,y=this.generateCollectionResource(h,r,a,f);yi(m,y);let C=this.isDDD()?`src/lib/modules/${o}`:"src/lib/resources";this.success(`Collection resource created: ${C}/${h}.ts`)}}}generateResource(e,t,s=`./${t}.js`){let r=`${t}Data`;return`import { Resource } from '@beeblock/svelar/routing';
1624
1855
  import type { ${t} } from '${s}';
1625
1856
 
1626
1857
  // \u2500\u2500 API Contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
@@ -1698,7 +1929,7 @@ export class ${e} {
1698
1929
  .toObject();
1699
1930
  }
1700
1931
  }
1701
- `}deriveModuleName(e){return e.replace(/Resource$/,"").replace(/Collection$/,"").toLowerCase()}inferModelName(e){return e.replace(/Resource$/,"")||"Model"}};import{writeFileSync as fa,mkdirSync as va,existsSync as ba}from"fs";import{join as ya}from"path";var Ot=class extends g{name="make:schema";description="Create a contract schema (Zod schemas + shared types)";arguments=["name"];flags=[{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a schema name (e.g. User, Post, Invoice).");return}let r=s.charAt(0).toUpperCase()+s.slice(1),i=this.toKebab(s)+".schema",n=t.module||s.toLowerCase(),o=this.moduleDir(n,"schemas");va(o,{recursive:!0});let a=ya(o,`${i}.ts`);if(ba(a)){let h=this.isDDD()?`src/lib/modules/${n}`:"src/lib/schemas";this.warn(`Schema already exists: ${h}/${i}.ts`);return}let c=this.generateSchema(r);fa(a,c);let u=this.isDDD()?`src/lib/modules/${n}`:"src/lib/schemas";this.success(`Schema created: ${u}/${i}.ts`),this.info(""),this.info(" Use this schema across your entire stack:"),this.info(""),this.info(` Resource: extends Resource<${r}, ${r}Data>`),this.info(` FormRequest: uses create${r}Schema / update${r}Schema`);let p=this.isDDD()?`$lib/modules/${n}/${i}`:`$lib/schemas/${i}`;this.info(` Frontend: import type { ${r}Data } from '${p}'`)}generateSchema(e){let t=e.charAt(0).toLowerCase()+e.slice(1),s=this.toKebab(e);return`import { z } from 'zod';
1932
+ `}deriveModuleName(e){return e.replace(/Resource$/,"").replace(/Collection$/,"").toLowerCase()}inferModelName(e){return e.replace(/Resource$/,"")||"Model"}};import{writeFileSync as fa,mkdirSync as va,existsSync as ba}from"fs";import{join as ya}from"path";var It=class extends g{name="make:schema";description="Create a contract schema (Zod schemas + shared types)";arguments=["name"];flags=[{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a schema name (e.g. User, Post, Invoice).");return}let r=s.charAt(0).toUpperCase()+s.slice(1),o=this.toKebab(s)+".schema",n=t.module||s.toLowerCase(),i=this.moduleDir(n,"schemas");va(i,{recursive:!0});let a=ya(i,`${o}.ts`);if(ba(a)){let h=this.isDDD()?`src/lib/modules/${n}`:"src/lib/schemas";this.warn(`Schema already exists: ${h}/${o}.ts`);return}let c=this.generateSchema(r);fa(a,c);let u=this.isDDD()?`src/lib/modules/${n}`:"src/lib/schemas";this.success(`Schema created: ${u}/${o}.ts`),this.info(""),this.info(" Use this schema across your entire stack:"),this.info(""),this.info(` Resource: extends Resource<${r}, ${r}Data>`),this.info(` FormRequest: uses create${r}Schema / update${r}Schema`);let p=this.isDDD()?`$lib/modules/${n}/${o}`:`$lib/schemas/${o}`;this.info(` Frontend: import type { ${r}Data } from '${p}'`)}generateSchema(e){let t=e.charAt(0).toLowerCase()+e.slice(1),s=this.toKebab(e);return`import { z } from 'zod';
1702
1933
 
1703
1934
  // \u2500\u2500 ${e} Contract Schema \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
1704
1935
  //
@@ -1733,7 +1964,7 @@ export const update${e}Schema = create${e}Schema.partial();
1733
1964
  export type ${e}Data = z.infer<typeof ${t}Schema>;
1734
1965
  export type Create${e}Input = z.infer<typeof create${e}Schema>;
1735
1966
  export type Update${e}Input = z.infer<typeof update${e}Schema>;
1736
- `}toKebab(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1-$2").toLowerCase()}};import{writeFileSync as wa,mkdirSync as Ca,existsSync as xa}from"fs";import{join as Sa}from"path";var Nt=class extends g{name="make:observer";description="Create a new model observer class";arguments=["name"];flags=[{name:"model",alias:"m",description:"The model class to observe",type:"string"},{name:"module",description:"Module name (e.g. users, posts)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide an observer name (e.g. UserObserver).");return}let r=t.model||s.replace(/Observer$/,""),i=t.module||this.toSnakeCase(this.pluralize(r)),n=this.moduleDir(i,"observers");Ca(n,{recursive:!0});let o=Sa(n,`${s}.ts`);if(xa(o)){this.warn(`Observer ${s} already exists at ${o}`);return}let a=this.isDDD()?`./${r}.js`:`../models/${r}.js`,c=`import { ModelObserver } from '@beeblock/svelar/orm';
1967
+ `}toKebab(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1-$2").toLowerCase()}};import{writeFileSync as wa,mkdirSync as Ca,existsSync as xa}from"fs";import{join as Sa}from"path";var Nt=class extends g{name="make:observer";description="Create a new model observer class";arguments=["name"];flags=[{name:"model",alias:"m",description:"The model class to observe",type:"string"},{name:"module",description:"Module name (e.g. users, posts)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide an observer name (e.g. UserObserver).");return}let r=t.model||s.replace(/Observer$/,""),o=t.module||this.toSnakeCase(this.pluralize(r)),n=this.moduleDir(o,"observers");Ca(n,{recursive:!0});let i=Sa(n,`${s}.ts`);if(xa(i)){this.warn(`Observer ${s} already exists at ${i}`);return}let a=this.isDDD()?`./${r}.js`:`../models/${r}.js`,c=`import { ModelObserver } from '@beeblock/svelar/orm';
1737
1968
  import type { ${r} } from '${a}';
1738
1969
 
1739
1970
  export class ${s} extends ModelObserver {
@@ -1771,7 +2002,7 @@ export class ${s} extends ModelObserver {
1771
2002
  // async deleted(${r.toLowerCase()}: ${r}) {
1772
2003
  // }
1773
2004
  }
1774
- `;wa(o,c);let u=this.isDDD()?`src/lib/modules/${i}`:"src/lib/observers";this.success(`Observer created: ${u}/${s}.ts`),this.info(`Register it in your app: ${r}.observe(new ${s}());`)}toSnakeCase(e){return e.replace(/([A-Z])/g,"_$1").toLowerCase().replace(/^_/,"")}pluralize(e){return e.endsWith("y")?e.slice(0,-1)+"ies":e.endsWith("s")||e.endsWith("x")||e.endsWith("z")||e.endsWith("ch")||e.endsWith("sh")?e+"es":e+"s"}};import{writeFileSync as Pa,mkdirSync as Ra,existsSync as Ea}from"fs";import{join as Ta}from"path";var It=class extends g{name="make:event";description="Create a new event class";arguments=["name"];flags=[{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide an event name (e.g. UserRegistered).");return}let r=t.module||s.replace(/([A-Z])/g," $1").trim().split(" ")[0].toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${r}" as module. Consider: --module ${r}`);let i=this.moduleDir(r,"events");Ra(i,{recursive:!0});let n=Ta(i,`${s}.ts`);if(Ea(n)){this.warn(`Event ${s} already exists at ${n}`);return}let o=`/**
2005
+ `;wa(i,c);let u=this.isDDD()?`src/lib/modules/${o}`:"src/lib/observers";this.success(`Observer created: ${u}/${s}.ts`),this.info(`Register it in your app: ${r}.observe(new ${s}());`)}toSnakeCase(e){return e.replace(/([A-Z])/g,"_$1").toLowerCase().replace(/^_/,"")}pluralize(e){return e.endsWith("y")?e.slice(0,-1)+"ies":e.endsWith("s")||e.endsWith("x")||e.endsWith("z")||e.endsWith("ch")||e.endsWith("sh")?e+"es":e+"s"}};import{writeFileSync as Pa,mkdirSync as Ra,existsSync as Ea}from"fs";import{join as Ta}from"path";var jt=class extends g{name="make:event";description="Create a new event class";arguments=["name"];flags=[{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide an event name (e.g. UserRegistered).");return}let r=t.module||s.replace(/([A-Z])/g," $1").trim().split(" ")[0].toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${r}" as module. Consider: --module ${r}`);let o=this.moduleDir(r,"events");Ra(o,{recursive:!0});let n=Ta(o,`${s}.ts`);if(Ea(n)){this.warn(`Event ${s} already exists at ${n}`);return}let i=`/**
1775
2006
  * ${s} Event
1776
2007
  *
1777
2008
  * Dispatched when ... (describe when this event fires).
@@ -1789,7 +2020,7 @@ export class ${s} {
1789
2020
  // public readonly metadata?: Record<string, any>,
1790
2021
  ) {}
1791
2022
  }
1792
- `;Pa(n,o);let a=this.isDDD()?`src/lib/modules/${r}`:"src/lib/events";this.success(`Event created: ${a}/${s}.ts`)}};import{writeFileSync as ka,mkdirSync as $a,existsSync as Da}from"fs";import{join as Aa}from"path";var jt=class extends g{name="make:listener";description="Create a new event listener class";arguments=["name"];flags=[{name:"event",alias:"e",description:"The event class this listener handles",type:"string"},{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a listener name (e.g. SendWelcomeEmail).");return}let r=t.module||s.replace(/([A-Z])/g," $1").trim().split(" ")[0].toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${r}" as module. Consider: --module ${r}`);let i=this.moduleDir(r,"listeners");$a(i,{recursive:!0});let n=Aa(i,`${s}.ts`);if(Da(n)){this.warn(`Listener ${s} already exists at ${n}`);return}let o=t.event||"any",a=t.event?this.isDDD()?`./${t.event}.js`:`../events/${t.event}.js`:"",c=t.event?`import type { ${t.event} } from '${a}';
2023
+ `;Pa(n,i);let a=this.isDDD()?`src/lib/modules/${r}`:"src/lib/events";this.success(`Event created: ${a}/${s}.ts`)}};import{writeFileSync as ka,mkdirSync as $a,existsSync as Da}from"fs";import{join as Aa}from"path";var Ut=class extends g{name="make:listener";description="Create a new event listener class";arguments=["name"];flags=[{name:"event",alias:"e",description:"The event class this listener handles",type:"string"},{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a listener name (e.g. SendWelcomeEmail).");return}let r=t.module||s.replace(/([A-Z])/g," $1").trim().split(" ")[0].toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${r}" as module. Consider: --module ${r}`);let o=this.moduleDir(r,"listeners");$a(o,{recursive:!0});let n=Aa(o,`${s}.ts`);if(Da(n)){this.warn(`Listener ${s} already exists at ${n}`);return}let i=t.event||"any",a=t.event?this.isDDD()?`./${t.event}.js`:`../events/${t.event}.js`:"",c=t.event?`import type { ${t.event} } from '${a}';
1793
2024
 
1794
2025
  `:"",u=t.event||"any",p=`import { Listener } from '@beeblock/svelar/events';
1795
2026
  ${c}export class ${s} extends Listener<${u}> {
@@ -1803,16 +2034,16 @@ ${c}export class ${s} extends Listener<${u}> {
1803
2034
  // return true;
1804
2035
  // }
1805
2036
  }
1806
- `;ka(n,p);let h=this.isDDD()?`src/lib/modules/${r}`:"src/lib/listeners";this.success(`Listener created: ${h}/${s}.ts`),t.event&&(this.info("Don't forget to register it in your EventServiceProvider:"),this.info(` [${t.event}.name]: [${s}]`))}};import{writeFileSync as _a,mkdirSync as La,existsSync as Ma}from"fs";import{join as xi}from"path";var Ut=class extends g{name="make:route";description="Create route files with controller bindings";arguments=["path"];flags=[{name:"controller",alias:"c",description:"Controller class name",type:"string"},{name:"resource",alias:"r",description:"Generate full CRUD resource routes",type:"boolean"},{name:"api",description:"Prefix path with /api",type:"boolean"},{name:"methods",alias:"m",description:"HTTP methods (comma-separated: GET,POST,PUT,DELETE)",type:"string"},{name:"module",description:"Module name for controller import path",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a route path (e.g. posts, users/[id], admin/settings).");return}let r=s.replace(/^\//,"");t.api&&!r.startsWith("api/")&&(r="api/"+r);let i=t.controller||this.inferControllerName(r),n=t.module||this.inferModuleName(r);t.resource?this.generateResourceRoutes(r,i,n):this.generateRoute(r,i,n,t.methods)}generateResourceRoutes(e,t,s){this.generateRouteFile(e,t,s,[{method:"GET",handler:"index"},{method:"POST",handler:"store"}]);let r=this.inferParamName(e);this.generateRouteFile(`${e}/[${r}]`,t,s,[{method:"GET",handler:"show"},{method:"PUT",handler:"update"},{method:"DELETE",handler:"destroy"}])}generateRoute(e,t,s,r){let n=(r?r.split(",").map(o=>o.trim().toUpperCase()):["GET"]).map(o=>({method:o,handler:this.defaultHandler(o)}));this.generateRouteFile(e,t,s,n)}generateRouteFile(e,t,s,r){let i=xi(process.cwd(),"src","routes",...e.split("/"));La(i,{recursive:!0});let n=xi(i,"+server.ts");if(Ma(n)){this.warn(`Route already exists: src/routes/${e}/+server.ts (skipped)`);return}let o=this.isDDD()?`$lib/modules/${s}/${t}.js`:`$lib/controllers/${t}.js`,a=r.map(u=>`export const ${u.method} = ctrl.handle('${u.handler}');`).join(`
1807
- `),c=`import { ${t} } from '${o}';
2037
+ `;ka(n,p);let h=this.isDDD()?`src/lib/modules/${r}`:"src/lib/listeners";this.success(`Listener created: ${h}/${s}.ts`),t.event&&(this.info("Don't forget to register it in your EventServiceProvider:"),this.info(` [${t.event}.name]: [${s}]`))}};import{writeFileSync as _a,mkdirSync as La,existsSync as Ma}from"fs";import{join as xi}from"path";var qt=class extends g{name="make:route";description="Create route files with controller bindings";arguments=["path"];flags=[{name:"controller",alias:"c",description:"Controller class name",type:"string"},{name:"resource",alias:"r",description:"Generate full CRUD resource routes",type:"boolean"},{name:"api",description:"Prefix path with /api",type:"boolean"},{name:"methods",alias:"m",description:"HTTP methods (comma-separated: GET,POST,PUT,DELETE)",type:"string"},{name:"module",description:"Module name for controller import path",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a route path (e.g. posts, users/[id], admin/settings).");return}let r=s.replace(/^\//,"");t.api&&!r.startsWith("api/")&&(r="api/"+r);let o=t.controller||this.inferControllerName(r),n=t.module||this.inferModuleName(r);t.resource?this.generateResourceRoutes(r,o,n):this.generateRoute(r,o,n,t.methods)}generateResourceRoutes(e,t,s){this.generateRouteFile(e,t,s,[{method:"GET",handler:"index"},{method:"POST",handler:"store"}]);let r=this.inferParamName(e);this.generateRouteFile(`${e}/[${r}]`,t,s,[{method:"GET",handler:"show"},{method:"PUT",handler:"update"},{method:"DELETE",handler:"destroy"}])}generateRoute(e,t,s,r){let n=(r?r.split(",").map(i=>i.trim().toUpperCase()):["GET"]).map(i=>({method:i,handler:this.defaultHandler(i)}));this.generateRouteFile(e,t,s,n)}generateRouteFile(e,t,s,r){let o=xi(process.cwd(),"src","routes",...e.split("/"));La(o,{recursive:!0});let n=xi(o,"+server.ts");if(Ma(n)){this.warn(`Route already exists: src/routes/${e}/+server.ts (skipped)`);return}let i=this.isDDD()?`$lib/modules/${s}/${t}.js`:`$lib/controllers/${t}.js`,a=r.map(u=>`export const ${u.method} = ctrl.handle('${u.handler}');`).join(`
2038
+ `),c=`import { ${t} } from '${i}';
1808
2039
 
1809
2040
  const ctrl = new ${t}();
1810
2041
  ${a}
1811
- `;_a(n,c),this.success(`Route created: src/routes/${e}/+server.ts`);for(let u of r)this.info(` ${u.method} /${e} \u2192 ${t}.${u.handler}()`)}inferControllerName(e){let t=e.replace(/^api\//,"").split("/").filter(n=>!n.startsWith("[")),s=t[t.length-1]||t[0]||"Index",r=this.singularize(s);return`${r.charAt(0).toUpperCase()+r.slice(1)}Controller`}inferModuleName(e){return e.replace(/^api\//,"").split("/").filter(s=>!s.startsWith("["))[0]||"app"}inferParamName(e){return"id"}defaultHandler(e){return{GET:"index",POST:"store",PUT:"update",PATCH:"update",DELETE:"destroy"}[e]||e.toLowerCase()}singularize(e){return e.endsWith("ies")?e.slice(0,-3)+"y":e.endsWith("ses")||e.endsWith("xes")||e.endsWith("zes")||e.endsWith("ches")||e.endsWith("shes")?e.slice(0,-2):e.endsWith("s")&&!e.endsWith("ss")?e.slice(0,-1):e}};import{join as Si,relative as qs,sep as Fs}from"path";import{existsSync as Oa,readdirSync as Na,readFileSync as Pi,statSync as Ia}from"fs";var qt=class extends g{name="routes:list";description="List all registered routes";arguments=[];flags=[{name:"json",description:"Output as JSON",type:"boolean"},{name:"api",description:"Show only API routes",type:"boolean"},{name:"method",alias:"m",description:"Filter by HTTP method (GET, POST, etc.)",type:"string"}];async handle(e,t){let s=Si(process.cwd(),"src","routes");if(!Oa(s)){this.error("No src/routes/ directory found.");return}let i=this.scanRoutes(s,s);if(t.api&&(i=i.filter(u=>u.path.startsWith("/api"))),t.method){let u=t.method.toUpperCase();i=i.filter(p=>p.method===u)}if(i.sort((u,p)=>u.path.localeCompare(p.path)||u.method.localeCompare(p.method)),i.length===0){this.warn("No routes found.");return}if(t.json){this.log(JSON.stringify(i,null,2));return}this.log(""),this.log(` \x1B[1mApplication Routes\x1B[0m (${i.length} routes)
1812
- `);let n=Math.max(6,...i.map(u=>u.method.length)),o=Math.max(4,...i.map(u=>u.path.length)),a=Math.max(7,...i.map(u=>u.handler.length)),c=` ${"METHOD".padEnd(n)} ${"PATH".padEnd(o)} ${"HANDLER".padEnd(a)} FILE`;this.log(`\x1B[2m${c}\x1B[0m`),this.log(`\x1B[2m ${"\u2500".repeat(n)} ${"\u2500".repeat(o)} ${"\u2500".repeat(a)} ${"\u2500".repeat(20)}\x1B[0m`);for(let u of i){let h=`${this.getMethodColor(u.method)}${u.method.padEnd(n)}\x1B[0m`,m=u.path.padEnd(o),f=`\x1B[2m${u.handler.padEnd(a)}\x1B[0m`,y=`\x1B[2m${u.file}\x1B[0m`;this.log(` ${h} ${m} ${f} ${y}`)}this.log("")}scanRoutes(e,t){let s=[],r=Na(e);for(let i of r){let n=Si(e,i);if(Ia(n).isDirectory()){s.push(...this.scanRoutes(n,t));continue}i==="+server.ts"||i==="+server.js"?s.push(...this.parseServerFile(n,t)):(i==="+page.server.ts"||i==="+page.server.js")&&s.push(...this.parsePageServerFile(n,t))}return s}parseServerFile(e,t){let s=[],r=Pi(e,"utf-8"),i=this.filePathToUrl(e,t),n=qs(process.cwd(),e).split(Fs).join("/"),o=/export\s+(?:const|function)\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\b/g,a;for(;(a=o.exec(r))!==null;){let c=a[1],u=this.extractHandler(r,c);s.push({method:c,path:i,handler:u,file:n})}return s}parsePageServerFile(e,t){let s=[],r=Pi(e,"utf-8"),i=this.filePathToUrl(e,t),n=qs(process.cwd(),e).split(Fs).join("/");/export\s+(const|async\s+function)\s+load\b/.test(r)&&s.push({method:"GET",path:i,handler:"load()",file:n});let o=r.match(/export\s+const\s+actions\s*=\s*\{([^}]+)\}/);if(o){let a=o[1].split(",").map(c=>c.trim().split(":")[0].split("(")[0].trim()).filter(Boolean);for(let c of a)s.push({method:"POST",path:c==="default"?i:`${i}?/${c}`,handler:`actions.${c}()`,file:n})}return s}filePathToUrl(e,t){let s=qs(t,e).split(Fs).join("/");return s=s.replace(/\/?\+(?:server|page\.server)\.[tj]s$/,""),s=s.replace(/\[\.\.\.(\w+)\]/g,"*$1").replace(/\[\[(\w+)\]\]/g,":$1?").replace(/\[(\w+)\]/g,":$1"),s=s.replace(/\([^)]+\)\//g,""),"/"+s||"/"}extractHandler(e,t){let s=new RegExp(`export\\s+const\\s+${t}\\s*=\\s*(\\w+)\\.handle\\(['"]([^'"]+)['"]\\)`),r=e.match(s);if(r)return`${r[1]}.${r[2]}()`;let i=new RegExp(`const\\s*\\{[^}]*${t}[^}]*\\}\\s*=\\s*resource\\(\\s*(\\w+)`),n=e.match(i);return n?`${n[1]}.${{GET:"index/show",POST:"store",PUT:"update",PATCH:"update",DELETE:"destroy"}[t]??t.toLowerCase()}()`:new RegExp(`export\\s+(?:const|async\\s+function)\\s+${t}\\s*(?:=\\s*async)?`).test(e)?"inline handler":"handler"}getMethodColor(e){return{GET:"\x1B[32m",POST:"\x1B[33m",PUT:"\x1B[34m",PATCH:"\x1B[34m",DELETE:"\x1B[31m",HEAD:"\x1B[2m",OPTIONS:"\x1B[2m"}[e]||""}};import{readdirSync as ja}from"fs";import{join as Ti}from"path";import{pathToFileURL as Ua}from"url";var Ft=class extends g{name="migrate";description="Run pending database migrations";flags=[{name:"rollback",description:"Rollback the last batch of migrations",type:"boolean"},{name:"reset",description:"Reset all migrations",type:"boolean"},{name:"refresh",description:"Reset and re-run all migrations",type:"boolean"},{name:"fresh",description:"Drop all tables and re-run all migrations",type:"boolean"},{name:"status",description:"Show migration status",type:"boolean"},{name:"seed",description:"Run seeders after migrating",type:"boolean"},{name:"force",description:"Force destructive operations in production",type:"boolean"}];destructiveFlags=["reset","refresh","fresh"];async handle(e,t){await this.bootstrap();let s=this.destructiveFlags.find(c=>t[c]);s&&this.isProduction()&&!t.force&&(this.error(`The --${s} flag is destructive and cannot be run in production.`),this.error(`Use --force to run this command in production: npx svelar migrate --${s} --force`),process.exit(1));let{Migrator:r}=await Promise.resolve().then(()=>(zs(),Ei)),i=new r,n=Ti(process.cwd(),"src","lib","database","migrations"),o=await this.loadMigrations(n);if(t.status){let c=await i.status(o);this.table(["Migration","Status","Batch"],c.map(u=>[u.name,u.ran?"\x1B[32mRan\x1B[0m":"\x1B[33mPending\x1B[0m",u.batch?.toString()??"-"]));return}if(t.rollback){this.info("Rolling back last batch...");let c=await i.rollback(o);if(c.length===0)this.info("Nothing to rollback.");else for(let u of c)this.success(`Rolled back: ${u}`);return}if(t.reset){this.warnDestructive("reset"),this.info("Resetting all migrations...");let c=await i.reset(o);if(c.length===0)this.info("Nothing to reset.");else for(let u of c)this.success(`Rolled back: ${u}`);return}if(t.refresh){this.warnDestructive("refresh"),this.info("Refreshing migrations...");let c=await i.refresh(o);for(let u of c.reset)this.success(`Rolled back: ${u}`);for(let u of c.migrated)this.success(`Migrated: ${u}`);return}if(t.fresh){this.warnDestructive("fresh"),this.info("Dropping all tables...");let c=await i.fresh(o);if(c.dropped.length>0)for(let u of c.dropped)this.success(`Dropped table: ${u}`);this.newLine(),this.info("Re-running all migrations...");for(let u of c.migrated)this.success(`Migrated: ${u}`);return}this.info("Running migrations...");let a=await i.run(o);if(a.length===0)this.info("Nothing to migrate.");else for(let c of a)this.success(`Migrated: ${c}`)}isProduction(){return(process.env.NODE_ENV||process.env.APP_ENV||"development")==="production"}warnDestructive(e){this.isProduction()&&this.warn(`Running --${e} in PRODUCTION with --force.`)}async loadMigrations(e){let t;try{t=ja(e).filter(r=>r.endsWith(".ts")||r.endsWith(".js")).sort()}catch{return this.warn(`Migrations directory not found: ${e}`),[]}let s=[];for(let r of t){let i=Ti(e,r);try{let n=await import(Ua(i).href),o=n.default??Object.values(n).find(a=>typeof a=="function"&&a.prototype&&typeof a.prototype.up=="function");o?s.push({name:r.replace(/\.(ts|js)$/,""),timestamp:r.split("_")[0],path:i,migration:new o}):this.warn(`No migration class found in: ${r}`)}catch(n){let o;try{o=n instanceof Error?n.message:String(n)}catch{o=JSON.stringify(n)??"Unknown error (non-stringifiable object)"}this.error(`Failed to load migration ${r}: ${o}`)}}return s}};import{join as Ks}from"path";import{pathToFileURL as qa}from"url";import{existsSync as ki}from"fs";var Bt=class extends g{name="seed:run";description="Run database seeders";flags=[{name:"class",description:"Specific seeder class to run",type:"string"}];async handle(e,t){await this.bootstrap();let s=Ks(process.cwd(),"src","lib","database","seeders"),r=t.class?Ks(s,`${t.class}.ts`):Ks(s,"DatabaseSeeder.ts"),i=r;ki(i)||(i=i.replace(/\.ts$/,".js")),ki(i)||(this.error(`Seeder not found: ${r}`),process.exit(1)),this.info("Running seeders...");try{let n=await import(qa(i).href),o=n.default??n.DatabaseSeeder??Object.values(n).find(c=>typeof c=="function"&&c.prototype&&typeof c.prototype.run=="function");(!o||typeof o!="function")&&(this.error("No seeder class found in file."),process.exit(1)),await new o().run(),this.success("Database seeded successfully.")}catch(n){let o=n instanceof Error?n.message:String(n);this.error(`Seeding failed: ${o}`),n?.stack&&console.error(n.stack),process.exit(1)}}};import{existsSync as za,readdirSync as Ka}from"fs";import{join as Vs}from"path";import{pathToFileURL as Wa}from"url";var Kt=class extends g{name="schedule:run";description="Run the task scheduler";flags=[{name:"once",description:"Run due tasks once and exit",type:"boolean"}];async handle(e,t){await this.bootstrap();let{Scheduler:s}=await Promise.resolve().then(()=>(_i(),Ai)),r=new s;r.persistToDatabase();let i=Vs(process.cwd(),"src","lib","shared","scheduler"),n=Vs(process.cwd(),"src","lib","scheduler"),o=za(i)?i:n,a=await this.loadTasks(o);if(a.length===0){this.warn("No scheduled tasks found in src/lib/shared/scheduler/ or src/lib/scheduler/");return}for(let p of a)r.register(p),this.info(`Registered task: ${p.name}`);if(this.newLine(),t.once){this.info("Running due tasks (once)...");let p=await r.run();if(p.length===0)this.info("No tasks were due.");else for(let h of p)h.success?this.success(`${h.task}: completed in ${h.duration}ms`):this.error(`${h.task}: failed \u2014 ${h.error}`);return}this.info("Scheduler running. Press Ctrl+C to stop."),this.newLine();let c=async()=>{let p=await r.run();for(let h of p){let m=new Date().toISOString().replace("T"," ").slice(0,19);h.success?this.success(`[${m}] ${h.task}: completed in ${h.duration}ms`):this.error(`[${m}] ${h.task}: failed \u2014 ${h.error}`)}};await c();let u=6e4-Date.now()%6e4;this.info(`Next tick aligned to minute boundary in ${Math.round(u/1e3)}s.`),await new Promise(p=>setTimeout(p,u)),await c(),setInterval(c,6e4),await new Promise(()=>{})}async loadTasks(e){let t;try{t=Ka(e).filter(r=>(r.endsWith(".ts")||r.endsWith(".js"))&&!r.startsWith("index")).sort()}catch{return[]}let s=[];for(let r of t){let i=Vs(e,r);try{let n=await import(Wa(i).href),o=n.default??Object.values(n).find(a=>typeof a=="function"&&a.prototype&&typeof a.prototype.handle=="function");if(o){let a=new o;a.schedule(),s.push(a)}}catch(n){this.error(`Failed to load task ${r}: ${n.message??n}`)}}return s}};var Vt=class extends g{name="queue:work";description="Process queued jobs";flags=[{name:"queue",description:'Queue name to process (default: "default")',type:"string",default:"default"},{name:"max-jobs",description:"Stop after processing N jobs",type:"string"},{name:"max-time",description:"Stop after N seconds",type:"string"},{name:"sleep",description:"Sleep N milliseconds between polls (default: 1000)",type:"string",default:"1000"},{name:"once",description:"Process a single job and exit",type:"boolean"}];async handle(e,t){await this.bootstrap();let{Queue:s}=await Promise.resolve().then(()=>(ce(),je)),r=t.queue??"default",i=t["max-jobs"]?parseInt(t["max-jobs"]):void 0,n=t["max-time"]?parseInt(t["max-time"]):void 0,o=t.sleep?parseInt(t.sleep):1e3;if(this.info(`Processing queue "${r}"...`),i&&this.info(`Will stop after ${i} jobs.`),n&&this.info(`Will stop after ${n} seconds.`),this.newLine(),t.once){let u=await s.work({queue:r,maxJobs:1,sleep:0});u===0?this.info("No jobs to process."):this.success(`Processed ${u} job(s).`);return}this.info(`Worker running on "${r}". Press Ctrl+C to stop.`),this.newLine();let a=Date.now(),c=0;for(;;){if(n&&(Date.now()-a)/1e3>=n){this.info(`Max time (${n}s) reached. Stopping.`);break}if(i&&c>=i){this.info(`Max jobs (${i}) reached. Stopping.`);break}let u=await s.work({queue:r,maxJobs:1,sleep:0});if(u>0){c+=u;let p=new Date().toISOString().replace("T"," ").slice(0,19);this.success(`[${p}] Processed ${u} job(s) (total: ${c})`)}else await new Promise(p=>setTimeout(p,o))}this.newLine(),this.info(`Worker stopped. Total jobs processed: ${c}`)}};var Yt=class extends g{name="queue:failed";description="List all failed jobs";async handle(e,t){await this.bootstrap();let{Queue:s}=await Promise.resolve().then(()=>(ce(),je)),r=await s.failed();if(r.length===0){this.info("No failed jobs.");return}this.info(`Found ${r.length} failed job(s):
1813
- `);for(let i of r){let n=new Date(i.failedAt*1e3).toISOString().replace("T"," ").slice(0,19);this.log(` ID: ${i.id}`),this.log(` Job: ${i.jobClass}`),this.log(` Queue: ${i.queue}`),this.log(` Date: ${n}`),this.log(` Error: ${i.exception.split(`
1814
- `)[0]}`),this.log("")}}};var Qt=class extends g{name="queue:retry";description="Retry a failed job (or all failed jobs)";arguments=["id"];flags=[{name:"all",description:"Retry all failed jobs",type:"boolean",default:!1}];async handle(e,t){await this.bootstrap();let{Queue:s}=await Promise.resolve().then(()=>(ce(),je));if(t.all){let n=await s.retryAll();n===0?this.info("No failed jobs to retry."):this.success(`Retried ${n} job(s).`);return}let r=e[0];r||(this.error("Please provide a failed job ID, or use --all to retry all."),process.exit(1)),await s.retry(r)?this.success(`Job ${r} has been pushed back onto the queue.`):this.error(`Failed job with ID "${r}" not found.`)}};var Gt=class extends g{name="queue:flush";description="Delete all failed job records";async handle(e,t){await this.bootstrap();let{Queue:s}=await Promise.resolve().then(()=>(ce(),je)),r=await s.flushFailed();r===0?this.info("No failed jobs to flush."):this.success(`Flushed ${r} failed job record(s).`)}};var Rs=class extends g{name="tinker";description="Start an interactive REPL with Svelar preloaded";flags=[];async handle(){await this.bootstrap(),this.info("Starting Svelar Tinker..."),this.log(`Type .exit to quit. All Svelar modules are available.
1815
- `);let t=(await import("repl")).start({prompt:"\x1B[36msvelar>\x1B[0m ",useGlobal:!0});try{let s=await Promise.resolve().then(()=>(Dn(),$n));for(let[r,i]of Object.entries(s))t.context[r]=i;t.context.DB=s.Connection,t.context.Schema=s.Schema,this.log("Available: Model, QueryBuilder, Connection, Schema, Hash, Cache, Event, Log, ..."),this.log("")}catch(s){this.warn(`Could not preload all modules: ${s.message}`)}try{let{readdirSync:s}=await import("fs"),{join:r}=await import("path"),{pathToFileURL:i}=await import("url"),{existsSync:n}=await import("fs"),o=r(process.cwd(),"src","lib","models"),a=r(process.cwd(),"src","lib","modules"),c=[],u=o;if(n(o))u=o,c=s(o).filter(p=>(p.endsWith(".ts")||p.endsWith(".js"))&&!p.startsWith("index"));else if(n(a)){u=a;for(let p of s(a,{withFileTypes:!0})){if(!p.isDirectory())continue;let h=r(a,p.name);for(let m of s(h))(m.endsWith(".ts")||m.endsWith(".js"))&&(m.startsWith("index")||m.includes("Controller")||m.includes("Service")||m.includes("Repository")||m.includes("Request")||m.includes("Resource")||m.includes("schema")||m.includes("gates")||c.push(r(p.name,m)))}}for(let p of c)try{let h=await import(i(r(u,p)).href);for(let[m,f]of Object.entries(h))typeof f=="function"&&(t.context[m]=f)}catch{}c.length>0&&this.log(`Loaded models: ${c.map(p=>p.replace(/\.(ts|js)$/,"")).join(", ")}`)}catch{}await new Promise(s=>{t.on("exit",s)})}};var d=class{static packageJson(e,t="0.4.0"){return JSON.stringify({name:e,version:"0.0.1",private:!0,type:"module",scripts:{dev:"vite dev",build:"vite build",preview:"vite preview",migrate:"npx svelar migrate","migrate:rollback":"npx svelar migrate --rollback","migrate:refresh":"npx svelar migrate --refresh",seed:"npx svelar seed:run",test:"vitest run","test:watch":"vitest","test:e2e":"playwright test","test:coverage":"vitest run --coverage"},devDependencies:{"@sveltejs/adapter-auto":"^3.0.0","@sveltejs/kit":"^2.55.0","@sveltejs/vite-plugin-svelte":"^5.0.0","@tailwindcss/vite":"^4.2.2","lucide-svelte":"^0.468.0",svelte:"^5.0.0","svelte-check":"^4.0.0",tailwindcss:"^4.2.2",typescript:"^5.7.0",vite:"^6.0.0",vitest:"^2.1.0","@playwright/test":"^1.48.0"},dependencies:{"better-sqlite3":"^11.0.0","drizzle-orm":"^0.38.0","@beeblock/svelar":`^${t}`,"bits-ui":"^1.0.0",clsx:"^2.1.0",exceljs:"^4.4.0","mode-watcher":"^0.5.0",pdfkit:"^0.18.0","sveltekit-superforms":"^2.22.0","tailwind-merge":"^3.0.0","tailwind-variants":"^1.0.0","tw-animate-css":"^1.2.0",zod:"^3.23.0"}},null,2)+`
2042
+ `;_a(n,c),this.success(`Route created: src/routes/${e}/+server.ts`);for(let u of r)this.info(` ${u.method} /${e} \u2192 ${t}.${u.handler}()`)}inferControllerName(e){let t=e.replace(/^api\//,"").split("/").filter(n=>!n.startsWith("[")),s=t[t.length-1]||t[0]||"Index",r=this.singularize(s);return`${r.charAt(0).toUpperCase()+r.slice(1)}Controller`}inferModuleName(e){return e.replace(/^api\//,"").split("/").filter(s=>!s.startsWith("["))[0]||"app"}inferParamName(e){return"id"}defaultHandler(e){return{GET:"index",POST:"store",PUT:"update",PATCH:"update",DELETE:"destroy"}[e]||e.toLowerCase()}singularize(e){return e.endsWith("ies")?e.slice(0,-3)+"y":e.endsWith("ses")||e.endsWith("xes")||e.endsWith("zes")||e.endsWith("ches")||e.endsWith("shes")?e.slice(0,-2):e.endsWith("s")&&!e.endsWith("ss")?e.slice(0,-1):e}};import{join as Si,relative as Fs,sep as Bs}from"path";import{existsSync as Oa,readdirSync as Ia,readFileSync as Pi,statSync as Na}from"fs";var Ft=class extends g{name="routes:list";description="List all registered routes";arguments=[];flags=[{name:"json",description:"Output as JSON",type:"boolean"},{name:"api",description:"Show only API routes",type:"boolean"},{name:"method",alias:"m",description:"Filter by HTTP method (GET, POST, etc.)",type:"string"}];async handle(e,t){let s=Si(process.cwd(),"src","routes");if(!Oa(s)){this.error("No src/routes/ directory found.");return}let o=this.scanRoutes(s,s);if(t.api&&(o=o.filter(u=>u.path.startsWith("/api"))),t.method){let u=t.method.toUpperCase();o=o.filter(p=>p.method===u)}if(o.sort((u,p)=>u.path.localeCompare(p.path)||u.method.localeCompare(p.method)),o.length===0){this.warn("No routes found.");return}if(t.json){this.log(JSON.stringify(o,null,2));return}this.log(""),this.log(` \x1B[1mApplication Routes\x1B[0m (${o.length} routes)
2043
+ `);let n=Math.max(6,...o.map(u=>u.method.length)),i=Math.max(4,...o.map(u=>u.path.length)),a=Math.max(7,...o.map(u=>u.handler.length)),c=` ${"METHOD".padEnd(n)} ${"PATH".padEnd(i)} ${"HANDLER".padEnd(a)} FILE`;this.log(`\x1B[2m${c}\x1B[0m`),this.log(`\x1B[2m ${"\u2500".repeat(n)} ${"\u2500".repeat(i)} ${"\u2500".repeat(a)} ${"\u2500".repeat(20)}\x1B[0m`);for(let u of o){let h=`${this.getMethodColor(u.method)}${u.method.padEnd(n)}\x1B[0m`,m=u.path.padEnd(i),f=`\x1B[2m${u.handler.padEnd(a)}\x1B[0m`,y=`\x1B[2m${u.file}\x1B[0m`;this.log(` ${h} ${m} ${f} ${y}`)}this.log("")}scanRoutes(e,t){let s=[],r=Ia(e);for(let o of r){let n=Si(e,o);if(Na(n).isDirectory()){s.push(...this.scanRoutes(n,t));continue}o==="+server.ts"||o==="+server.js"?s.push(...this.parseServerFile(n,t)):(o==="+page.server.ts"||o==="+page.server.js")&&s.push(...this.parsePageServerFile(n,t))}return s}parseServerFile(e,t){let s=[],r=Pi(e,"utf-8"),o=this.filePathToUrl(e,t),n=Fs(process.cwd(),e).split(Bs).join("/"),i=/export\s+(?:const|function)\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\b/g,a;for(;(a=i.exec(r))!==null;){let c=a[1],u=this.extractHandler(r,c);s.push({method:c,path:o,handler:u,file:n})}return s}parsePageServerFile(e,t){let s=[],r=Pi(e,"utf-8"),o=this.filePathToUrl(e,t),n=Fs(process.cwd(),e).split(Bs).join("/");/export\s+(const|async\s+function)\s+load\b/.test(r)&&s.push({method:"GET",path:o,handler:"load()",file:n});let i=r.match(/export\s+const\s+actions\s*=\s*\{([^}]+)\}/);if(i){let a=i[1].split(",").map(c=>c.trim().split(":")[0].split("(")[0].trim()).filter(Boolean);for(let c of a)s.push({method:"POST",path:c==="default"?o:`${o}?/${c}`,handler:`actions.${c}()`,file:n})}return s}filePathToUrl(e,t){let s=Fs(t,e).split(Bs).join("/");return s=s.replace(/\/?\+(?:server|page\.server)\.[tj]s$/,""),s=s.replace(/\[\.\.\.(\w+)\]/g,"*$1").replace(/\[\[(\w+)\]\]/g,":$1?").replace(/\[(\w+)\]/g,":$1"),s=s.replace(/\([^)]+\)\//g,""),"/"+s||"/"}extractHandler(e,t){let s=new RegExp(`export\\s+const\\s+${t}\\s*=\\s*(\\w+)\\.handle\\(['"]([^'"]+)['"]\\)`),r=e.match(s);if(r)return`${r[1]}.${r[2]}()`;let o=new RegExp(`const\\s*\\{[^}]*${t}[^}]*\\}\\s*=\\s*resource\\(\\s*(\\w+)`),n=e.match(o);return n?`${n[1]}.${{GET:"index/show",POST:"store",PUT:"update",PATCH:"update",DELETE:"destroy"}[t]??t.toLowerCase()}()`:new RegExp(`export\\s+(?:const|async\\s+function)\\s+${t}\\s*(?:=\\s*async)?`).test(e)?"inline handler":"handler"}getMethodColor(e){return{GET:"\x1B[32m",POST:"\x1B[33m",PUT:"\x1B[34m",PATCH:"\x1B[34m",DELETE:"\x1B[31m",HEAD:"\x1B[2m",OPTIONS:"\x1B[2m"}[e]||""}};import{readdirSync as ja}from"fs";import{join as Ti}from"path";import{pathToFileURL as Ua}from"url";var Bt=class extends g{name="migrate";description="Run pending database migrations";flags=[{name:"rollback",description:"Rollback the last batch of migrations",type:"boolean"},{name:"reset",description:"Reset all migrations",type:"boolean"},{name:"refresh",description:"Reset and re-run all migrations",type:"boolean"},{name:"fresh",description:"Drop all tables and re-run all migrations",type:"boolean"},{name:"status",description:"Show migration status",type:"boolean"},{name:"seed",description:"Run seeders after migrating",type:"boolean"},{name:"force",description:"Force destructive operations in production",type:"boolean"}];destructiveFlags=["reset","refresh","fresh"];async handle(e,t){await this.bootstrap();let s=this.destructiveFlags.find(c=>t[c]);s&&this.isProduction()&&!t.force&&(this.error(`The --${s} flag is destructive and cannot be run in production.`),this.error(`Use --force to run this command in production: npx svelar migrate --${s} --force`),process.exit(1));let{Migrator:r}=await Promise.resolve().then(()=>(Ks(),Ei)),o=new r,n=Ti(process.cwd(),"src","lib","database","migrations"),i=await this.loadMigrations(n);if(t.status){let c=await o.status(i);this.table(["Migration","Status","Batch"],c.map(u=>[u.name,u.ran?"\x1B[32mRan\x1B[0m":"\x1B[33mPending\x1B[0m",u.batch?.toString()??"-"]));return}if(t.rollback){this.info("Rolling back last batch...");let c=await o.rollback(i);if(c.length===0)this.info("Nothing to rollback.");else for(let u of c)this.success(`Rolled back: ${u}`);return}if(t.reset){this.warnDestructive("reset"),this.info("Resetting all migrations...");let c=await o.reset(i);if(c.length===0)this.info("Nothing to reset.");else for(let u of c)this.success(`Rolled back: ${u}`);return}if(t.refresh){this.warnDestructive("refresh"),this.info("Refreshing migrations...");let c=await o.refresh(i);for(let u of c.reset)this.success(`Rolled back: ${u}`);for(let u of c.migrated)this.success(`Migrated: ${u}`);return}if(t.fresh){this.warnDestructive("fresh"),this.info("Dropping all tables...");let c=await o.fresh(i);if(c.dropped.length>0)for(let u of c.dropped)this.success(`Dropped table: ${u}`);this.newLine(),this.info("Re-running all migrations...");for(let u of c.migrated)this.success(`Migrated: ${u}`);return}this.info("Running migrations...");let a=await o.run(i);if(a.length===0)this.info("Nothing to migrate.");else for(let c of a)this.success(`Migrated: ${c}`)}isProduction(){return(process.env.NODE_ENV||process.env.APP_ENV||"development")==="production"}warnDestructive(e){this.isProduction()&&this.warn(`Running --${e} in PRODUCTION with --force.`)}async loadMigrations(e){let t;try{t=ja(e).filter(r=>r.endsWith(".ts")||r.endsWith(".js")).sort()}catch{return this.warn(`Migrations directory not found: ${e}`),[]}let s=[];for(let r of t){let o=Ti(e,r);try{let n=await import(Ua(o).href),i=n.default??Object.values(n).find(a=>typeof a=="function"&&a.prototype&&typeof a.prototype.up=="function");i?s.push({name:r.replace(/\.(ts|js)$/,""),timestamp:r.split("_")[0],path:o,migration:new i}):this.warn(`No migration class found in: ${r}`)}catch(n){let i;try{i=n instanceof Error?n.message:String(n)}catch{i=JSON.stringify(n)??"Unknown error (non-stringifiable object)"}this.error(`Failed to load migration ${r}: ${i}`)}}return s}};import{join as Ws}from"path";import{pathToFileURL as qa}from"url";import{existsSync as ki}from"fs";var Ht=class extends g{name="seed:run";description="Run database seeders";flags=[{name:"class",description:"Specific seeder class to run",type:"string"}];async handle(e,t){await this.bootstrap();let s=Ws(process.cwd(),"src","lib","database","seeders"),r=t.class?Ws(s,`${t.class}.ts`):Ws(s,"DatabaseSeeder.ts"),o=r;ki(o)||(o=o.replace(/\.ts$/,".js")),ki(o)||(this.error(`Seeder not found: ${r}`),process.exit(1)),this.info("Running seeders...");try{let n=await import(qa(o).href),i=n.default??n.DatabaseSeeder??Object.values(n).find(c=>typeof c=="function"&&c.prototype&&typeof c.prototype.run=="function");(!i||typeof i!="function")&&(this.error("No seeder class found in file."),process.exit(1)),await new i().run(),this.success("Database seeded successfully.")}catch(n){let i=n instanceof Error?n.message:String(n);this.error(`Seeding failed: ${i}`),n?.stack&&console.error(n.stack),process.exit(1)}}};import{existsSync as za,readdirSync as Ka}from"fs";import{join as Ys}from"path";import{pathToFileURL as Wa}from"url";var Wt=class extends g{name="schedule:run";description="Run the task scheduler";flags=[{name:"once",description:"Run due tasks once and exit",type:"boolean"}];async handle(e,t){await this.bootstrap();let{Scheduler:s}=await Promise.resolve().then(()=>(_i(),Ai)),r=new s;r.persistToDatabase();let o=Ys(process.cwd(),"src","lib","shared","scheduler"),n=Ys(process.cwd(),"src","lib","scheduler"),i=za(o)?o:n,a=await this.loadTasks(i);if(a.length===0){this.warn("No scheduled tasks found in src/lib/shared/scheduler/ or src/lib/scheduler/");return}for(let p of a)r.register(p),this.info(`Registered task: ${p.name}`);if(this.newLine(),t.once){this.info("Running due tasks (once)...");let p=await r.run();if(p.length===0)this.info("No tasks were due.");else for(let h of p)h.success?this.success(`${h.task}: completed in ${h.duration}ms`):this.error(`${h.task}: failed \u2014 ${h.error}`);return}this.info("Scheduler running. Press Ctrl+C to stop."),this.newLine();let c=async()=>{let p=await r.run();for(let h of p){let m=new Date().toISOString().replace("T"," ").slice(0,19);h.success?this.success(`[${m}] ${h.task}: completed in ${h.duration}ms`):this.error(`[${m}] ${h.task}: failed \u2014 ${h.error}`)}};await c();let u=6e4-Date.now()%6e4;this.info(`Next tick aligned to minute boundary in ${Math.round(u/1e3)}s.`),await new Promise(p=>setTimeout(p,u)),await c(),setInterval(c,6e4),await new Promise(()=>{})}async loadTasks(e){let t;try{t=Ka(e).filter(r=>(r.endsWith(".ts")||r.endsWith(".js"))&&!r.startsWith("index")).sort()}catch{return[]}let s=[];for(let r of t){let o=Ys(e,r);try{let n=await import(Wa(o).href),i=n.default??Object.values(n).find(a=>typeof a=="function"&&a.prototype&&typeof a.prototype.handle=="function");if(i){let a=new i;a.schedule(),s.push(a)}}catch(n){this.error(`Failed to load task ${r}: ${n.message??n}`)}}return s}};var Yt=class extends g{name="queue:work";description="Process queued jobs";flags=[{name:"queue",description:'Queue name to process (default: "default")',type:"string",default:"default"},{name:"max-jobs",description:"Stop after processing N jobs",type:"string"},{name:"max-time",description:"Stop after N seconds",type:"string"},{name:"sleep",description:"Sleep N milliseconds between polls (default: 1000)",type:"string",default:"1000"},{name:"once",description:"Process a single job and exit",type:"boolean"}];async handle(e,t){await this.bootstrap();let{Queue:s}=await Promise.resolve().then(()=>(ce(),je)),r=t.queue??"default",o=t["max-jobs"]?parseInt(t["max-jobs"]):void 0,n=t["max-time"]?parseInt(t["max-time"]):void 0,i=t.sleep?parseInt(t.sleep):1e3;if(this.info(`Processing queue "${r}"...`),o&&this.info(`Will stop after ${o} jobs.`),n&&this.info(`Will stop after ${n} seconds.`),this.newLine(),t.once){let u=await s.work({queue:r,maxJobs:1,sleep:0});u===0?this.info("No jobs to process."):this.success(`Processed ${u} job(s).`);return}this.info(`Worker running on "${r}". Press Ctrl+C to stop.`),this.newLine();let a=Date.now(),c=0;for(;;){if(n&&(Date.now()-a)/1e3>=n){this.info(`Max time (${n}s) reached. Stopping.`);break}if(o&&c>=o){this.info(`Max jobs (${o}) reached. Stopping.`);break}let u=await s.work({queue:r,maxJobs:1,sleep:0});if(u>0){c+=u;let p=new Date().toISOString().replace("T"," ").slice(0,19);this.success(`[${p}] Processed ${u} job(s) (total: ${c})`)}else await new Promise(p=>setTimeout(p,i))}this.newLine(),this.info(`Worker stopped. Total jobs processed: ${c}`)}};var Gt=class extends g{name="queue:failed";description="List all failed jobs";async handle(e,t){await this.bootstrap();let{Queue:s}=await Promise.resolve().then(()=>(ce(),je)),r=await s.failed();if(r.length===0){this.info("No failed jobs.");return}this.info(`Found ${r.length} failed job(s):
2044
+ `);for(let o of r){let n=new Date(o.failedAt*1e3).toISOString().replace("T"," ").slice(0,19);this.log(` ID: ${o.id}`),this.log(` Job: ${o.jobClass}`),this.log(` Queue: ${o.queue}`),this.log(` Date: ${n}`),this.log(` Error: ${o.exception.split(`
2045
+ `)[0]}`),this.log("")}}};var Qt=class extends g{name="queue:retry";description="Retry a failed job (or all failed jobs)";arguments=["id"];flags=[{name:"all",description:"Retry all failed jobs",type:"boolean",default:!1}];async handle(e,t){await this.bootstrap();let{Queue:s}=await Promise.resolve().then(()=>(ce(),je));if(t.all){let n=await s.retryAll();n===0?this.info("No failed jobs to retry."):this.success(`Retried ${n} job(s).`);return}let r=e[0];r||(this.error("Please provide a failed job ID, or use --all to retry all."),process.exit(1)),await s.retry(r)?this.success(`Job ${r} has been pushed back onto the queue.`):this.error(`Failed job with ID "${r}" not found.`)}};var Zt=class extends g{name="queue:flush";description="Delete all failed job records";async handle(e,t){await this.bootstrap();let{Queue:s}=await Promise.resolve().then(()=>(ce(),je)),r=await s.flushFailed();r===0?this.info("No failed jobs to flush."):this.success(`Flushed ${r} failed job record(s).`)}};var Es=class extends g{name="tinker";description="Start an interactive REPL with Svelar preloaded";flags=[];async handle(){await this.bootstrap(),this.info("Starting Svelar Tinker..."),this.log(`Type .exit to quit. All Svelar modules are available.
2046
+ `);let t=(await import("repl")).start({prompt:"\x1B[36msvelar>\x1B[0m ",useGlobal:!0});try{let s=await Promise.resolve().then(()=>(Do(),$o));for(let[r,o]of Object.entries(s))t.context[r]=o;t.context.DB=s.Connection,t.context.Schema=s.Schema,this.log("Available: Model, QueryBuilder, Connection, Schema, Hash, Cache, Event, Log, ..."),this.log("")}catch(s){this.warn(`Could not preload all modules: ${s.message}`)}try{let{readdirSync:s}=await import("fs"),{join:r}=await import("path"),{pathToFileURL:o}=await import("url"),{existsSync:n}=await import("fs"),i=r(process.cwd(),"src","lib","models"),a=r(process.cwd(),"src","lib","modules"),c=[],u=i;if(n(i))u=i,c=s(i).filter(p=>(p.endsWith(".ts")||p.endsWith(".js"))&&!p.startsWith("index"));else if(n(a)){u=a;for(let p of s(a,{withFileTypes:!0})){if(!p.isDirectory())continue;let h=r(a,p.name);for(let m of s(h))(m.endsWith(".ts")||m.endsWith(".js"))&&(m.startsWith("index")||m.includes("Controller")||m.includes("Service")||m.includes("Repository")||m.includes("Request")||m.includes("Resource")||m.includes("schema")||m.includes("gates")||c.push(r(p.name,m)))}}for(let p of c)try{let h=await import(o(r(u,p)).href);for(let[m,f]of Object.entries(h))typeof f=="function"&&(t.context[m]=f)}catch{}c.length>0&&this.log(`Loaded models: ${c.map(p=>p.replace(/\.(ts|js)$/,"")).join(", ")}`)}catch{}await new Promise(s=>{t.on("exit",s)})}};var d=class{static packageJson(e,t="0.4.0"){return JSON.stringify({name:e,version:"0.0.1",private:!0,type:"module",scripts:{dev:"vite dev",build:"vite build",preview:"vite preview",migrate:"npx svelar migrate","migrate:rollback":"npx svelar migrate --rollback","migrate:refresh":"npx svelar migrate --refresh",seed:"npx svelar seed:run",test:"vitest run","test:watch":"vitest","test:e2e":"playwright test","test:coverage":"vitest run --coverage"},devDependencies:{"@sveltejs/adapter-auto":"^3.0.0","@sveltejs/kit":"^2.55.0","@sveltejs/vite-plugin-svelte":"^5.0.0","@tailwindcss/vite":"^4.2.2","lucide-svelte":"^0.468.0",svelte:"^5.0.0","svelte-check":"^4.0.0",tailwindcss:"^4.2.2",typescript:"^5.7.0",vite:"^6.0.0",vitest:"^2.1.0","@playwright/test":"^1.48.0"},dependencies:{"better-sqlite3":"^11.0.0","drizzle-orm":"^0.38.0","@beeblock/svelar":`^${t}`,"bits-ui":"^1.0.0",clsx:"^2.1.0",exceljs:"^4.4.0","mode-watcher":"^0.5.0",pdfkit:"^0.18.0","sveltekit-superforms":"^2.22.0","tailwind-merge":"^3.0.0","tailwind-variants":"^1.0.0","tw-animate-css":"^1.2.0",zod:"^3.23.0"}},null,2)+`
1816
2047
  `}static svelteConfig(){return`import adapter from '@sveltejs/adapter-auto';
1817
2048
  import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
1818
2049
 
@@ -2288,24 +2519,32 @@ export const { handle, handleError } = createSvelarApp({
2288
2519
  sessionStore: new DatabaseSessionStore(),
2289
2520
  csrfExcludePaths: ['/api/webhooks', '/api/internal/'],
2290
2521
  });
2291
- `}static envExample(){return`# App Security \u2014 generate a random string for production
2522
+ `}static envExample(){return`# \u2500\u2500 App \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
2523
+ # APP_KEY: Encryption key for cookies, sessions, and tokens. Must be unique per environment.
2524
+ # Generate with: npx svelar key:generate
2292
2525
  APP_KEY=change-me-to-a-random-string
2293
-
2294
- # App
2526
+ # APP_NAME: Displayed in emails, page titles, and meta tags.
2295
2527
  APP_NAME=My App
2528
+ # APP_URL: Full public URL of your app. Used for CORS, redirects, and link generation.
2296
2529
  APP_URL=http://localhost:5173
2297
2530
 
2298
- # Internal secret (scheduler <-> web server bridge)
2531
+ # \u2500\u2500 Internal \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
2532
+ # INTERNAL_SECRET: Shared secret for internal HTTP bridge (scheduler -> web server).
2533
+ # Must match between the scheduler process and the web server.
2299
2534
  INTERNAL_SECRET=change-me-to-a-random-string
2300
2535
 
2301
- # Database (SQLite by default, no extra config needed)
2536
+ # \u2500\u2500 Database \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
2537
+ # DB_DRIVER: sqlite | postgresql | mysql2
2538
+ # SQLite is the default \u2014 no extra config needed.
2302
2539
  DB_DRIVER=sqlite
2540
+ # DB_PATH: Path to SQLite file (relative to project root). Only used with sqlite driver.
2303
2541
  DB_PATH=database.db
2304
2542
 
2305
2543
  # PostgreSQL (uncomment to switch)
2544
+ # In Docker: app connects through PgBouncer on port 6432, not directly to postgres.
2306
2545
  # DB_DRIVER=postgresql
2307
- # DB_HOST=localhost
2308
- # DB_PORT=5432
2546
+ # DB_HOST=pgbouncer
2547
+ # DB_PORT=6432
2309
2548
  # DB_NAME=svelar_db
2310
2549
  # DB_USER=postgres
2311
2550
  # DB_PASSWORD=secret
@@ -2317,49 +2556,137 @@ DB_PATH=database.db
2317
2556
  # DB_NAME=svelar_db
2318
2557
  # DB_USER=root
2319
2558
  # DB_PASSWORD=secret
2320
-
2321
- # JWT (if using JWT auth)
2559
+ # DB_ROOT_PASSWORD: Root password for MySQL container (Docker only).
2560
+ # DB_ROOT_PASSWORD=rootsecret
2561
+
2562
+ # \u2500\u2500 PgBouncer (connection pooling \u2014 PostgreSQL only) \u2500\u2500\u2500\u2500\u2500
2563
+ # PgBouncer sits between app and PostgreSQL. Included automatically with postgres.
2564
+ # App connects to pgbouncer:6432, PgBouncer connects to postgres:5432.
2565
+ # Pool settings are in docker/pgbouncer/pgbouncer.ini (not env vars).
2566
+ # PostgreSQL tuning is in docker/postgres/postgresql.conf.
2567
+ # Credentials are read from DATABASE_URL in docker-compose.yml (no static password files).
2568
+
2569
+ # \u2500\u2500 Auth \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
2570
+ # AUTH_OTP_ENABLED: Enable one-time password (magic link) login.
2571
+ AUTH_OTP_ENABLED=true
2572
+ # AUTH_EMAIL_VERIFICATION_REQUIRED: Require email verification before access.
2573
+ AUTH_EMAIL_VERIFICATION_REQUIRED=false
2574
+ # JWT_SECRET: Secret key for signing JWT tokens. Required if using JWT auth.
2322
2575
  # JWT_SECRET=your-jwt-secret-key
2323
2576
 
2324
- # Mail (default: log \u2014 switch to smtp, postmark, or resend for production)
2577
+ # \u2500\u2500 Mail \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
2578
+ # MAIL_DRIVER: log | smtp | postmark | resend
2579
+ # "log" prints to console (dev). Switch to a real driver for production.
2325
2580
  # MAIL_DRIVER=log
2581
+ # MAIL_FROM: Default sender address for all outgoing emails.
2326
2582
  # MAIL_FROM=hello@example.com
2583
+ # SMTP (uncomment for generic SMTP)
2584
+ # SMTP_HOST=smtp.example.com
2585
+ # SMTP_PORT=587
2586
+ # SMTP_USER=your-smtp-user
2587
+ # SMTP_PASSWORD=your-smtp-password
2588
+ # Postmark (uncomment to use)
2327
2589
  # POSTMARK_API_TOKEN=your-postmark-server-token
2590
+ # Resend (uncomment to use)
2328
2591
  # RESEND_API_KEY=re_your-resend-api-key
2329
2592
 
2330
- # Redis (optional \u2014 needed for BullMQ queue and Redis cache/session)
2593
+ # \u2500\u2500 Queue \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
2594
+ # QUEUE_DRIVER: sync | redis
2595
+ # "sync" runs jobs immediately (dev). "redis" uses BullMQ for background processing.
2596
+ # QUEUE_DRIVER=sync
2597
+
2598
+ # \u2500\u2500 Redis \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
2599
+ # Required for: BullMQ queue, Redis cache driver, Redis session driver.
2331
2600
  # REDIS_HOST=localhost
2332
2601
  # REDIS_PORT=6379
2602
+ # REDIS_PASSWORD: Set a password in production. Docker compose uses this for the Redis container too.
2333
2603
  # REDIS_PASSWORD=
2334
2604
 
2335
- # Queue driver (sync = immediate, redis = background via BullMQ)
2336
- # QUEUE_DRIVER=sync
2337
-
2338
- # Meilisearch (optional \u2014 full-text search engine)
2605
+ # \u2500\u2500 Storage \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
2606
+ # STORAGE_DISK: local | s3
2607
+ # "local" stores files on disk. "s3" uses any S3-compatible service (AWS, RustFS, MinIO).
2608
+ # STORAGE_DISK=local
2609
+ # S3_ENDPOINT: URL of the S3-compatible service. Use http://rustfs:9000 for Docker RustFS.
2610
+ # S3_ENDPOINT=http://localhost:9000
2611
+ # S3_ACCESS_KEY=svelar
2612
+ # S3_SECRET_KEY=svelarsecret
2613
+ # S3_BUCKET: Bucket name. Created automatically by most S3 services.
2614
+ # S3_BUCKET=svelar
2615
+ # S3_REGION=us-east-1
2616
+
2617
+ # RustFS (S3 storage container \u2014 Docker only)
2618
+ # RUSTFS_ROOT_USER: Admin username for RustFS/MinIO. Also used as S3_ACCESS_KEY.
2619
+ # RUSTFS_ROOT_USER=svelar
2620
+ # RUSTFS_ROOT_PASSWORD: Admin password for RustFS/MinIO. Also used as S3_SECRET_KEY.
2621
+ # RUSTFS_ROOT_PASSWORD=svelarsecret
2622
+ # RUSTFS_CONSOLE_PORT: Host port for the RustFS admin console (default: 9001). Change per project on shared droplets.
2623
+ # RUSTFS_CONSOLE_PORT=9001
2624
+
2625
+ # \u2500\u2500 Search \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
2626
+ # Meilisearch \u2014 full-text search engine (optional).
2339
2627
  # MEILISEARCH_HOST=http://localhost:7700
2628
+ # MEILISEARCH_KEY: Master key for Meilisearch. Required in production.
2340
2629
  # MEILISEARCH_KEY=
2341
-
2342
- # PDF (default driver is pdfkit \u2014 no config needed)
2343
- # Switch to Gotenberg for pixel-perfect HTML rendering:
2630
+ # MEILI_MASTER_KEY: Same key, used by the Meilisearch Docker container.
2631
+ # MEILI_MASTER_KEY=svelar-meili-master-key
2632
+ # MEILI_PORT: Host port for Meilisearch dashboard (Docker only, default: 7700).
2633
+ # MEILI_PORT=7700
2634
+
2635
+ # \u2500\u2500 PDF \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
2636
+ # PDF_DRIVER: pdfkit | gotenberg
2637
+ # "pdfkit" works out of the box. "gotenberg" renders HTML to PDF (needs Gotenberg service).
2344
2638
  # PDF_DRIVER=gotenberg
2639
+ # GOTENBERG_URL: URL of the Gotenberg service. Use http://gotenberg:3000 for Docker.
2345
2640
  # GOTENBERG_URL=http://localhost:3001
2641
+ # GOTENBERG_TIMEOUT: Max time for PDF generation (default: 60s).
2642
+ # GOTENBERG_TIMEOUT=60s
2643
+ # GOTENBERG_LOG_LEVEL: Gotenberg container log level (default: info).
2644
+ # GOTENBERG_LOG_LEVEL=info
2346
2645
 
2347
- # Auth Features
2348
- AUTH_OTP_ENABLED=true
2349
- AUTH_EMAIL_VERIFICATION_REQUIRED=false
2350
-
2351
- # Stripe (optional \u2014 install @beeblock/svelar-stripe plugin)
2352
- # STRIPE_SECRET_KEY=sk_test_...
2353
- # STRIPE_PUBLISHABLE_KEY=pk_test_...
2354
- # STRIPE_WEBHOOK_SECRET=whsec_...
2355
- # STRIPE_CURRENCY=usd
2356
-
2357
- # Broadcasting (optional \u2014 Pusher/Soketi WebSocket)
2646
+ # \u2500\u2500 Broadcasting \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
2647
+ # Pusher/Soketi WebSocket for real-time events (optional).
2358
2648
  # PUSHER_KEY=app-key
2359
2649
  # PUSHER_SECRET=app-secret
2360
2650
  # PUSHER_APP_ID=app-id
2651
+ # PUSHER_HOST: Use "soketi" for Docker, "localhost" for local dev.
2361
2652
  # PUSHER_HOST=localhost
2362
2653
  # PUSHER_PORT=6001
2654
+ # SOKETI_PORT: Host port for Soketi WebSocket (Docker only, default: 6001).
2655
+ # SOKETI_PORT=6001
2656
+ # SOKETI_DEBUG: Enable Soketi debug logging (0 or 1).
2657
+ # SOKETI_DEBUG=0
2658
+ # SOKETI_MAX_CONNS: Max concurrent WebSocket connections per app (default: 1000).
2659
+ # SOKETI_MAX_CONNS=1000
2660
+
2661
+ # \u2500\u2500 Stripe \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
2662
+ # Install @beeblock/svelar-stripe plugin first.
2663
+ # STRIPE_SECRET_KEY=sk_test_...
2664
+ # STRIPE_PUBLISHABLE_KEY=pk_test_...
2665
+ # STRIPE_WEBHOOK_SECRET: Webhook signing secret from Stripe dashboard.
2666
+ # STRIPE_WEBHOOK_SECRET=whsec_...
2667
+ # STRIPE_CURRENCY: Default currency for charges (default: usd).
2668
+ # STRIPE_CURRENCY=usd
2669
+
2670
+ # \u2500\u2500 Docker / Deployment \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
2671
+ # APP_PORT: Host port for the production container (default: 3000).
2672
+ # Change per project when running multiple apps on the same droplet.
2673
+ # APP_PORT=3000
2674
+ # DEV_PORT: Host port for the development container (default: 5173).
2675
+ # DEV_PORT=5173
2676
+ # DOCKER_IMAGE: Full Docker Hub image path (e.g. username/myapp).
2677
+ # Set automatically by CI/CD \u2014 only needed for manual docker compose commands.
2678
+ # DOCKER_IMAGE=username/myapp
2679
+
2680
+ # \u2500\u2500 Container Memory Limits \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
2681
+ # Prevent any single container from consuming all droplet memory.
2682
+ # APP_MEMORY_LIMIT: App container (PM2 cluster: web + worker + scheduler). Default: 1G.
2683
+ # APP_MEMORY_LIMIT=1G
2684
+ # POSTGRES_MEMORY_LIMIT: PostgreSQL container. Default: 1G. Scale with postgresql.conf shared_buffers.
2685
+ # POSTGRES_MEMORY_LIMIT=1G
2686
+ # MYSQL_MEMORY_LIMIT: MySQL container (if using MySQL). Default: 1G.
2687
+ # MYSQL_MEMORY_LIMIT=1G
2688
+ # REDIS_MEMORY_LIMIT: Redis container. Default: 256M.
2689
+ # REDIS_MEMORY_LIMIT=256M
2363
2690
  `}static gitignore(){return`node_modules
2364
2691
  .svelte-kit
2365
2692
  build
@@ -7338,20 +7665,20 @@ export class UserFactory extends Factory<User> {
7338
7665
 
7339
7666
  // Singleton instance for convenience
7340
7667
  export default new UserFactory();
7341
- `}};var Es=class extends g{name="new";description="Create a new SvelteKit project with Svelar pre-configured";arguments=["name"];flags=[{name:"no-install",alias:"n",description:"Skip npm install",type:"boolean",default:!1},{name:"flat",description:"Use flat folder structure instead of DDD modules",type:"boolean",default:!1}];async handle(e,t){let{join:s,resolve:r}=await import("path"),{existsSync:i,mkdirSync:n,writeFileSync:o}=await import("fs"),{execSync:a}=await import("child_process"),c=e[0];c||(this.error("Please provide a project name: npx svelar new my-app"),process.exit(1));let u=r(process.cwd(),c);i(u)&&(this.error(`Directory "${c}" already exists.`),process.exit(1));let p=t.flat||!1,h=p?"flat":"DDD modular";this.log(""),this.log(` \x1B[1m\x1B[38;5;208m</> Svelar\x1B[0m \u2014 Creating new project (${h})
7342
- `);let m=(L,Ze)=>{let Os=p?vl(L):L,Xe=p?bl(Ze,L):Ze,et=s(u,Os);n(s(et,".."),{recursive:!0}),o(et,Xe)};this.info("Creating project structure...");let f=p?["","src","src/lib","src/lib/models","src/lib/services","src/lib/controllers","src/lib/repositories","src/lib/dtos","src/lib/actions","src/lib/resources","src/lib/events","src/lib/listeners","src/lib/notifications","src/lib/schemas","src/lib/jobs","src/lib/scheduler","src/lib/middleware","src/lib/components","src/lib/components/ui","src/lib/hooks","src/lib/stores","src/lib/plugins","src/lib/channels","src/lib/commands","src/lib/providers","src/lib/database/migrations","src/lib/database/seeders","src/routes","src/routes/api","static","storage/logs","storage/cache","storage/uploads","storage/sessions","tests/unit","tests/feature","tests/e2e","src/lib/factories"]:["","src","src/lib","src/lib/modules/auth","src/lib/modules/posts","src/lib/modules/admin","src/lib/shared/jobs","src/lib/shared/scheduler","src/lib/shared/middleware","src/lib/shared/components","src/lib/components/ui","src/lib/hooks","src/lib/shared/stores","src/lib/shared/plugins","src/lib/shared/channels","src/lib/shared/commands","src/lib/shared/providers","src/lib/database/migrations","src/lib/database/seeders","src/routes","src/routes/api","static","storage/logs","storage/cache","storage/uploads","storage/sessions","tests/unit","tests/feature","tests/e2e","src/lib/factories"];for(let L of f)n(s(u,L),{recursive:!0});this.info("Writing config files...");let{dirname:y}=await import("path"),{fileURLToPath:C}=await import("url"),M=s(y(y(y(C(import.meta.url)))),"package.json"),D=JSON.parse((await import("fs")).readFileSync(M,"utf-8")).version??"0.4.0";m("package.json",d.packageJson(c,D)),m("svelte.config.js",d.svelteConfig()),m("vite.config.ts",d.viteConfig()),m("tsconfig.json",d.tsConfig()),m("src/app.html",d.appHtml()),m("static/favicon.svg",d.faviconSvg()),m("src/app.css",d.appCss()),m("src/app.ts",d.appTs()),m("src/hooks.server.ts",d.hooksServerTs()),m(".env.example",d.envExample());let{randomBytes:$}=await import("crypto"),R=$(32).toString("hex"),I=$(16).toString("hex"),se=d.envExample().replace("APP_KEY=change-me-to-a-random-string",`APP_KEY=${R}`).replace("INTERNAL_SECRET=change-me-to-a-random-string",`INTERNAL_SECRET=${I}`);m(".env",se),m(".gitignore",d.gitignore()),m("svelar.database.json",d.svelarDatabaseJson()),m("components.json",d.componentsJson()),m("src/lib/utils.ts",d.utilsCn());for(let L of["storage/logs","storage/cache","storage/uploads","storage/sessions"])m(`${L}/.gitkeep`,"");if(this.info("Scaffolding domain layer..."),m("src/lib/modules/auth/User.ts",d.userModel()),m("src/lib/modules/auth/UserRepository.ts",d.userRepository()),m("src/lib/modules/auth/AuthService.ts",d.authService()),m("src/lib/modules/auth/AuthController.ts",d.authController()),m("src/lib/modules/auth/RegisterUserAction.ts",d.registerUserAction()),m("src/lib/modules/auth/RegisterRequest.ts",d.registerRequest()),m("src/lib/modules/auth/LoginRequest.ts",d.loginRequest()),m("src/lib/modules/auth/ForgotPasswordRequest.ts",d.forgotPasswordRequest()),m("src/lib/modules/auth/ResetPasswordRequest.ts",d.resetPasswordRequest()),m("src/lib/modules/auth/OtpSendRequest.ts",d.otpSendRequest()),m("src/lib/modules/auth/OtpVerifyRequest.ts",d.otpVerifyRequest()),m("src/lib/modules/auth/UserResource.ts",d.userResource()),m("src/lib/modules/auth/gates.ts",d.gates()),m("src/lib/modules/auth/schemas.ts",d.authSchema()),m("src/lib/modules/auth/UserRegistered.ts",d.userRegisteredEvent()),m("src/lib/modules/auth/SendWelcomeEmailListener.ts",d.sendWelcomeEmailListener()),m("src/lib/modules/auth/WelcomeNotification.ts",d.welcomeNotification()),m("src/lib/modules/posts/Post.ts",d.postModel()),m("src/lib/modules/posts/PostRepository.ts",d.postRepository()),m("src/lib/modules/posts/PostService.ts",d.postService()),m("src/lib/modules/posts/PostController.ts",d.postController()),m("src/lib/modules/posts/CreatePostAction.ts",d.createPostAction()),m("src/lib/modules/posts/CreatePostRequest.ts",d.createPostRequest()),m("src/lib/modules/posts/UpdatePostRequest.ts",d.updatePostRequest()),m("src/lib/modules/posts/PostResource.ts",d.postResource()),m("src/lib/modules/posts/schemas.ts",d.postSchema()),m("src/lib/modules/admin/AdminService.ts",d.adminService()),m("src/lib/modules/admin/AdminController.ts",d.adminController()),m("src/lib/modules/admin/UpdateUserRoleRequest.ts",d.updateUserRoleRequest()),m("src/lib/modules/admin/DeleteUserRequest.ts",d.deleteUserRequest()),m("src/lib/modules/admin/CreateRoleRequest.ts",d.createRoleRequest()),m("src/lib/modules/admin/DeleteRoleRequest.ts",d.deleteRoleRequest()),m("src/lib/modules/admin/CreatePermissionRequest.ts",d.createPermissionRequest()),m("src/lib/modules/admin/DeletePermissionRequest.ts",d.deletePermissionRequest()),m("src/lib/modules/admin/RolePermissionRequest.ts",d.rolePermissionRequest()),m("src/lib/modules/admin/UserRoleRequest.ts",d.userRoleRequest()),m("src/lib/modules/admin/UserPermissionRequest.ts",d.userPermissionRequest()),m("src/lib/modules/admin/ExportDataRequest.ts",d.exportDataRequest()),m("src/lib/modules/admin/RoleResource.ts",d.roleResource()),m("src/lib/modules/admin/PermissionResource.ts",d.permissionResource()),m("src/lib/modules/admin/schemas.ts",d.adminSchema()),m("src/lib/shared/providers/EventServiceProvider.ts",d.eventServiceProvider()),this.info("Creating migrations..."),m("src/lib/database/migrations/00000001_create_users_table.ts",d.createUsersTable()),m("src/lib/database/migrations/00000002_create_posts_table.ts",d.createPostsTable()),m("src/lib/database/migrations/00000003_create_permissions_tables.ts",d.createPermissionsTables()),m("src/lib/database/migrations/00000004_add_role_to_users.ts",d.addRoleToUsers()),m("src/lib/database/migrations/00000005_create_sessions_table.ts",d.createSessionsTable()),m("src/lib/database/migrations/00000006_create_audit_logs_table.ts",d.createAuditLogsTable()),m("src/lib/database/migrations/00000007_create_notifications_table.ts",d.createNotificationsTable()),m("src/lib/database/migrations/00000008_create_failed_jobs_table.ts",d.createFailedJobsTable()),m("src/lib/database/seeders/DatabaseSeeder.ts",d.databaseSeeder()),this.info("Creating auth pages..."),m("src/routes/login/+page.server.ts",d.loginPageServer()),m("src/routes/login/+page.svelte",d.loginPageSvelte()),m("src/routes/register/+page.server.ts",d.registerPageServer()),m("src/routes/register/+page.svelte",d.registerPageSvelte()),m("src/routes/logout/+page.server.ts",d.logoutPageServer()),m("src/routes/forgot-password/+page.server.ts",d.forgotPasswordPageServer()),m("src/routes/forgot-password/+page.svelte",d.forgotPasswordPageSvelte()),m("src/routes/reset-password/+page.server.ts",d.resetPasswordPageServer()),m("src/routes/reset-password/+page.svelte",d.resetPasswordPageSvelte()),m("src/routes/otp-login/+page.server.ts",d.otpLoginPageServer()),m("src/routes/otp-login/+page.svelte",d.otpLoginPageSvelte()),m("src/routes/verify-email/+page.server.ts",d.verifyEmailPageServer()),m("src/routes/verify-email/+page.svelte",d.verifyEmailPageSvelte()),this.info("Creating dashboard..."),m("src/routes/dashboard/+layout.server.ts",d.dashboardLayoutServer()),m("src/routes/dashboard/+layout.svelte",d.dashboardLayoutSvelte()),m("src/routes/dashboard/+page.server.ts",d.dashboardPageServer()),m("src/routes/dashboard/+page.svelte",d.dashboardPageSvelte()),m("src/routes/dashboard/api-keys/+page.server.ts",d.apiKeysPageServer()),m("src/routes/dashboard/api-keys/+page.svelte",d.apiKeysPageSvelte()),m("src/routes/dashboard/team/+page.server.ts",d.teamPageServer()),m("src/routes/dashboard/team/+page.svelte",d.teamPageSvelte()),this.info("Creating admin panel..."),m("src/routes/admin/+layout.server.ts",d.adminLayoutServer()),m("src/routes/admin/+layout.svelte",d.adminLayoutSvelte()),m("src/routes/admin/+page.server.ts",d.adminPageServer()),m("src/routes/admin/+page.svelte",d.adminPageSvelte()),this.info("Creating API routes..."),m("src/routes/api/health/+server.ts",d.apiHealth()),m("src/routes/api/auth/register/+server.ts",d.apiAuthRegister()),m("src/routes/api/auth/login/+server.ts",d.apiAuthLogin()),m("src/routes/api/auth/logout/+server.ts",d.apiAuthLogout()),m("src/routes/api/auth/me/+server.ts",d.apiAuthMe()),m("src/routes/api/auth/forgot-password/+server.ts",d.apiAuthForgotPassword()),m("src/routes/api/auth/reset-password/+server.ts",d.apiAuthResetPassword()),m("src/routes/api/auth/otp/send/+server.ts",d.apiAuthOtpSend()),m("src/routes/api/auth/otp/verify/+server.ts",d.apiAuthOtpVerify()),m("src/routes/api/auth/verify-email/+server.ts",d.apiAuthVerifyEmail()),m("src/routes/api/posts/+server.ts",d.apiPosts()),m("src/routes/api/posts/[id]/+server.ts",d.apiPostsSingle()),m("src/routes/api/posts/mine/+server.ts",d.apiPostsMine()),m("src/routes/api/broadcasting/[channel]/+server.ts",d.apiBroadcasting()),m("src/routes/api/internal/broadcast/+server.ts",d.apiInternalBroadcast()),m("src/routes/api/admin/users/+server.ts",d.apiAdminUsers()),m("src/routes/api/admin/roles/+server.ts",d.apiAdminRoles()),m("src/routes/api/admin/permissions/+server.ts",d.apiAdminPermissions()),m("src/routes/api/admin/role-permissions/+server.ts",d.apiAdminRolePermissions()),m("src/routes/api/admin/user-roles/+server.ts",d.apiAdminUserRoles()),m("src/routes/api/admin/user-permissions/+server.ts",d.apiAdminUserPermissions()),m("src/routes/api/admin/export/+server.ts",d.apiAdminExport()),m("src/routes/api/admin/health/+server.ts",d.apiAdminHealth()),m("src/routes/api/admin/queue/+server.ts",d.apiAdminQueue()),m("src/routes/api/admin/queue/[id]/retry/+server.ts",d.apiAdminQueueRetry()),m("src/routes/api/admin/queue/[id]/+server.ts",d.apiAdminQueueDelete()),m("src/routes/api/admin/scheduler/+server.ts",d.apiAdminScheduler()),m("src/routes/api/admin/scheduler/[name]/run/+server.ts",d.apiAdminSchedulerRun()),m("src/routes/api/admin/scheduler/[name]/toggle/+server.ts",d.apiAdminSchedulerToggle()),m("src/routes/api/admin/logs/+server.ts",d.apiAdminLogs()),m("src/routes/api/admin/stats/+server.ts",d.apiAdminStats()),this.info("Creating background jobs..."),m("src/lib/shared/jobs/SendWelcomeEmail.ts",d.sendWelcomeEmail()),m("src/lib/shared/jobs/DailyDigestJob.ts",d.dailyDigestJob()),m("src/lib/shared/jobs/ExportDataJob.ts",d.exportDataJob()),this.info("Creating scheduled tasks..."),m("src/lib/shared/scheduler/CleanupExpiredTokens.ts",d.cleanupExpiredTokens()),m("src/lib/shared/scheduler/CleanExpiredSessions.ts",d.cleanExpiredSessions()),m("src/lib/shared/scheduler/DailyDigestEmail.ts",d.dailyDigestEmail()),m("src/lib/shared/scheduler/PruneAuditLogs.ts",d.pruneAuditLogs()),m("src/lib/shared/scheduler/QueueHealthCheck.ts",d.queueHealthCheck()),this.info("Creating layouts..."),m("src/routes/+layout.svelte",d.rootLayoutSvelte(c)),m("src/routes/+layout.server.ts",d.rootLayoutServer()),m("src/routes/+error.svelte",d.errorSvelte()),m("src/routes/+page.svelte",d.homePage(c)),this.info("Setting up testing..."),m("vitest.config.ts",d.vitestConfig()),m("playwright.config.ts",d.playwrightConfig()),m("tests/unit/example.test.ts",d.exampleUnitTest()),m("tests/feature/auth.test.ts",d.exampleFeatureTest()),m("src/lib/factories/UserFactory.ts",d.scaffoldUserFactory()),this.success(`Project structure created (${h})`),!t["no-install"]){this.info("Installing dependencies...");try{a("npm install",{cwd:u,stdio:"inherit"}),this.success("Dependencies installed")}catch{this.warn("npm install failed \u2014 run it manually with: cd "+c+" && npm install")}this.info("Installing shadcn-svelte components...");try{a("npx shadcn-svelte@latest add --all --yes --no-changelog",{cwd:u,stdio:"inherit"}),this.success("shadcn-svelte components installed")}catch{this.warn("shadcn-svelte setup failed \u2014 run manually: cd "+c+" && npx shadcn-svelte@latest add --all")}this.info("Running migrations...");try{a("npx svelar migrate",{cwd:u,stdio:"inherit"}),this.success("Migrations complete")}catch{this.warn("Migrations failed \u2014 run manually: cd "+c+" && npx svelar migrate")}this.info("Seeding database...");try{a("npx svelar seed:run",{cwd:u,stdio:"inherit"}),this.success("Database seeded")}catch{this.warn("Seeding failed \u2014 run manually: cd "+c+" && npx svelar seed:run")}}this.log(""),this.log(` \x1B[32m+\x1B[0m Project \x1B[1m${c}\x1B[0m created successfully!
7668
+ `}};var Ts=class extends g{name="new";description="Create a new SvelteKit project with Svelar pre-configured";arguments=["name"];flags=[{name:"no-install",alias:"n",description:"Skip npm install",type:"boolean",default:!1},{name:"flat",description:"Use flat folder structure instead of DDD modules",type:"boolean",default:!1}];async handle(e,t){let{join:s,resolve:r}=await import("path"),{existsSync:o,mkdirSync:n,writeFileSync:i}=await import("fs"),{execSync:a}=await import("child_process"),c=e[0];c||(this.error("Please provide a project name: npx svelar new my-app"),process.exit(1));let u=r(process.cwd(),c);o(u)&&(this.error(`Directory "${c}" already exists.`),process.exit(1));let p=t.flat||!1,h=p?"flat":"DDD modular";this.log(""),this.log(` \x1B[1m\x1B[38;5;208m</> Svelar\x1B[0m \u2014 Creating new project (${h})
7669
+ `);let m=(M,Ze)=>{let Is=p?vl(M):M,Xe=p?bl(Ze,M):Ze,et=s(u,Is);n(s(et,".."),{recursive:!0}),i(et,Xe)};this.info("Creating project structure...");let f=p?["","src","src/lib","src/lib/models","src/lib/services","src/lib/controllers","src/lib/repositories","src/lib/dtos","src/lib/actions","src/lib/resources","src/lib/events","src/lib/listeners","src/lib/notifications","src/lib/schemas","src/lib/jobs","src/lib/scheduler","src/lib/middleware","src/lib/components","src/lib/components/ui","src/lib/hooks","src/lib/stores","src/lib/plugins","src/lib/channels","src/lib/commands","src/lib/providers","src/lib/database/migrations","src/lib/database/seeders","src/routes","src/routes/api","static","storage/logs","storage/cache","storage/uploads","storage/sessions","tests/unit","tests/feature","tests/e2e","src/lib/factories"]:["","src","src/lib","src/lib/modules/auth","src/lib/modules/posts","src/lib/modules/admin","src/lib/shared/jobs","src/lib/shared/scheduler","src/lib/shared/middleware","src/lib/shared/components","src/lib/components/ui","src/lib/hooks","src/lib/shared/stores","src/lib/shared/plugins","src/lib/shared/channels","src/lib/shared/commands","src/lib/shared/providers","src/lib/database/migrations","src/lib/database/seeders","src/routes","src/routes/api","static","storage/logs","storage/cache","storage/uploads","storage/sessions","tests/unit","tests/feature","tests/e2e","src/lib/factories"];for(let M of f)n(s(u,M),{recursive:!0});this.info("Writing config files...");let{dirname:y}=await import("path"),{fileURLToPath:C}=await import("url"),$=s(y(y(y(C(import.meta.url)))),"package.json"),D=JSON.parse((await import("fs")).readFileSync($,"utf-8")).version??"0.4.0";m("package.json",d.packageJson(c,D)),m("svelte.config.js",d.svelteConfig()),m("vite.config.ts",d.viteConfig()),m("tsconfig.json",d.tsConfig()),m("src/app.html",d.appHtml()),m("static/favicon.svg",d.faviconSvg()),m("src/app.css",d.appCss()),m("src/app.ts",d.appTs()),m("src/hooks.server.ts",d.hooksServerTs()),m(".env.example",d.envExample());let{randomBytes:L}=await import("crypto"),R=L(32).toString("hex"),j=L(16).toString("hex"),se=d.envExample().replace("APP_KEY=change-me-to-a-random-string",`APP_KEY=${R}`).replace("INTERNAL_SECRET=change-me-to-a-random-string",`INTERNAL_SECRET=${j}`);m(".env",se),m(".gitignore",d.gitignore()),m("svelar.database.json",d.svelarDatabaseJson()),m("components.json",d.componentsJson()),m("src/lib/utils.ts",d.utilsCn());for(let M of["storage/logs","storage/cache","storage/uploads","storage/sessions"])m(`${M}/.gitkeep`,"");if(this.info("Scaffolding domain layer..."),m("src/lib/modules/auth/User.ts",d.userModel()),m("src/lib/modules/auth/UserRepository.ts",d.userRepository()),m("src/lib/modules/auth/AuthService.ts",d.authService()),m("src/lib/modules/auth/AuthController.ts",d.authController()),m("src/lib/modules/auth/RegisterUserAction.ts",d.registerUserAction()),m("src/lib/modules/auth/RegisterRequest.ts",d.registerRequest()),m("src/lib/modules/auth/LoginRequest.ts",d.loginRequest()),m("src/lib/modules/auth/ForgotPasswordRequest.ts",d.forgotPasswordRequest()),m("src/lib/modules/auth/ResetPasswordRequest.ts",d.resetPasswordRequest()),m("src/lib/modules/auth/OtpSendRequest.ts",d.otpSendRequest()),m("src/lib/modules/auth/OtpVerifyRequest.ts",d.otpVerifyRequest()),m("src/lib/modules/auth/UserResource.ts",d.userResource()),m("src/lib/modules/auth/gates.ts",d.gates()),m("src/lib/modules/auth/schemas.ts",d.authSchema()),m("src/lib/modules/auth/UserRegistered.ts",d.userRegisteredEvent()),m("src/lib/modules/auth/SendWelcomeEmailListener.ts",d.sendWelcomeEmailListener()),m("src/lib/modules/auth/WelcomeNotification.ts",d.welcomeNotification()),m("src/lib/modules/posts/Post.ts",d.postModel()),m("src/lib/modules/posts/PostRepository.ts",d.postRepository()),m("src/lib/modules/posts/PostService.ts",d.postService()),m("src/lib/modules/posts/PostController.ts",d.postController()),m("src/lib/modules/posts/CreatePostAction.ts",d.createPostAction()),m("src/lib/modules/posts/CreatePostRequest.ts",d.createPostRequest()),m("src/lib/modules/posts/UpdatePostRequest.ts",d.updatePostRequest()),m("src/lib/modules/posts/PostResource.ts",d.postResource()),m("src/lib/modules/posts/schemas.ts",d.postSchema()),m("src/lib/modules/admin/AdminService.ts",d.adminService()),m("src/lib/modules/admin/AdminController.ts",d.adminController()),m("src/lib/modules/admin/UpdateUserRoleRequest.ts",d.updateUserRoleRequest()),m("src/lib/modules/admin/DeleteUserRequest.ts",d.deleteUserRequest()),m("src/lib/modules/admin/CreateRoleRequest.ts",d.createRoleRequest()),m("src/lib/modules/admin/DeleteRoleRequest.ts",d.deleteRoleRequest()),m("src/lib/modules/admin/CreatePermissionRequest.ts",d.createPermissionRequest()),m("src/lib/modules/admin/DeletePermissionRequest.ts",d.deletePermissionRequest()),m("src/lib/modules/admin/RolePermissionRequest.ts",d.rolePermissionRequest()),m("src/lib/modules/admin/UserRoleRequest.ts",d.userRoleRequest()),m("src/lib/modules/admin/UserPermissionRequest.ts",d.userPermissionRequest()),m("src/lib/modules/admin/ExportDataRequest.ts",d.exportDataRequest()),m("src/lib/modules/admin/RoleResource.ts",d.roleResource()),m("src/lib/modules/admin/PermissionResource.ts",d.permissionResource()),m("src/lib/modules/admin/schemas.ts",d.adminSchema()),m("src/lib/shared/providers/EventServiceProvider.ts",d.eventServiceProvider()),this.info("Creating migrations..."),m("src/lib/database/migrations/00000001_create_users_table.ts",d.createUsersTable()),m("src/lib/database/migrations/00000002_create_posts_table.ts",d.createPostsTable()),m("src/lib/database/migrations/00000003_create_permissions_tables.ts",d.createPermissionsTables()),m("src/lib/database/migrations/00000004_add_role_to_users.ts",d.addRoleToUsers()),m("src/lib/database/migrations/00000005_create_sessions_table.ts",d.createSessionsTable()),m("src/lib/database/migrations/00000006_create_audit_logs_table.ts",d.createAuditLogsTable()),m("src/lib/database/migrations/00000007_create_notifications_table.ts",d.createNotificationsTable()),m("src/lib/database/migrations/00000008_create_failed_jobs_table.ts",d.createFailedJobsTable()),m("src/lib/database/seeders/DatabaseSeeder.ts",d.databaseSeeder()),this.info("Creating auth pages..."),m("src/routes/login/+page.server.ts",d.loginPageServer()),m("src/routes/login/+page.svelte",d.loginPageSvelte()),m("src/routes/register/+page.server.ts",d.registerPageServer()),m("src/routes/register/+page.svelte",d.registerPageSvelte()),m("src/routes/logout/+page.server.ts",d.logoutPageServer()),m("src/routes/forgot-password/+page.server.ts",d.forgotPasswordPageServer()),m("src/routes/forgot-password/+page.svelte",d.forgotPasswordPageSvelte()),m("src/routes/reset-password/+page.server.ts",d.resetPasswordPageServer()),m("src/routes/reset-password/+page.svelte",d.resetPasswordPageSvelte()),m("src/routes/otp-login/+page.server.ts",d.otpLoginPageServer()),m("src/routes/otp-login/+page.svelte",d.otpLoginPageSvelte()),m("src/routes/verify-email/+page.server.ts",d.verifyEmailPageServer()),m("src/routes/verify-email/+page.svelte",d.verifyEmailPageSvelte()),this.info("Creating dashboard..."),m("src/routes/dashboard/+layout.server.ts",d.dashboardLayoutServer()),m("src/routes/dashboard/+layout.svelte",d.dashboardLayoutSvelte()),m("src/routes/dashboard/+page.server.ts",d.dashboardPageServer()),m("src/routes/dashboard/+page.svelte",d.dashboardPageSvelte()),m("src/routes/dashboard/api-keys/+page.server.ts",d.apiKeysPageServer()),m("src/routes/dashboard/api-keys/+page.svelte",d.apiKeysPageSvelte()),m("src/routes/dashboard/team/+page.server.ts",d.teamPageServer()),m("src/routes/dashboard/team/+page.svelte",d.teamPageSvelte()),this.info("Creating admin panel..."),m("src/routes/admin/+layout.server.ts",d.adminLayoutServer()),m("src/routes/admin/+layout.svelte",d.adminLayoutSvelte()),m("src/routes/admin/+page.server.ts",d.adminPageServer()),m("src/routes/admin/+page.svelte",d.adminPageSvelte()),this.info("Creating API routes..."),m("src/routes/api/health/+server.ts",d.apiHealth()),m("src/routes/api/auth/register/+server.ts",d.apiAuthRegister()),m("src/routes/api/auth/login/+server.ts",d.apiAuthLogin()),m("src/routes/api/auth/logout/+server.ts",d.apiAuthLogout()),m("src/routes/api/auth/me/+server.ts",d.apiAuthMe()),m("src/routes/api/auth/forgot-password/+server.ts",d.apiAuthForgotPassword()),m("src/routes/api/auth/reset-password/+server.ts",d.apiAuthResetPassword()),m("src/routes/api/auth/otp/send/+server.ts",d.apiAuthOtpSend()),m("src/routes/api/auth/otp/verify/+server.ts",d.apiAuthOtpVerify()),m("src/routes/api/auth/verify-email/+server.ts",d.apiAuthVerifyEmail()),m("src/routes/api/posts/+server.ts",d.apiPosts()),m("src/routes/api/posts/[id]/+server.ts",d.apiPostsSingle()),m("src/routes/api/posts/mine/+server.ts",d.apiPostsMine()),m("src/routes/api/broadcasting/[channel]/+server.ts",d.apiBroadcasting()),m("src/routes/api/internal/broadcast/+server.ts",d.apiInternalBroadcast()),m("src/routes/api/admin/users/+server.ts",d.apiAdminUsers()),m("src/routes/api/admin/roles/+server.ts",d.apiAdminRoles()),m("src/routes/api/admin/permissions/+server.ts",d.apiAdminPermissions()),m("src/routes/api/admin/role-permissions/+server.ts",d.apiAdminRolePermissions()),m("src/routes/api/admin/user-roles/+server.ts",d.apiAdminUserRoles()),m("src/routes/api/admin/user-permissions/+server.ts",d.apiAdminUserPermissions()),m("src/routes/api/admin/export/+server.ts",d.apiAdminExport()),m("src/routes/api/admin/health/+server.ts",d.apiAdminHealth()),m("src/routes/api/admin/queue/+server.ts",d.apiAdminQueue()),m("src/routes/api/admin/queue/[id]/retry/+server.ts",d.apiAdminQueueRetry()),m("src/routes/api/admin/queue/[id]/+server.ts",d.apiAdminQueueDelete()),m("src/routes/api/admin/scheduler/+server.ts",d.apiAdminScheduler()),m("src/routes/api/admin/scheduler/[name]/run/+server.ts",d.apiAdminSchedulerRun()),m("src/routes/api/admin/scheduler/[name]/toggle/+server.ts",d.apiAdminSchedulerToggle()),m("src/routes/api/admin/logs/+server.ts",d.apiAdminLogs()),m("src/routes/api/admin/stats/+server.ts",d.apiAdminStats()),this.info("Creating background jobs..."),m("src/lib/shared/jobs/SendWelcomeEmail.ts",d.sendWelcomeEmail()),m("src/lib/shared/jobs/DailyDigestJob.ts",d.dailyDigestJob()),m("src/lib/shared/jobs/ExportDataJob.ts",d.exportDataJob()),this.info("Creating scheduled tasks..."),m("src/lib/shared/scheduler/CleanupExpiredTokens.ts",d.cleanupExpiredTokens()),m("src/lib/shared/scheduler/CleanExpiredSessions.ts",d.cleanExpiredSessions()),m("src/lib/shared/scheduler/DailyDigestEmail.ts",d.dailyDigestEmail()),m("src/lib/shared/scheduler/PruneAuditLogs.ts",d.pruneAuditLogs()),m("src/lib/shared/scheduler/QueueHealthCheck.ts",d.queueHealthCheck()),this.info("Creating layouts..."),m("src/routes/+layout.svelte",d.rootLayoutSvelte(c)),m("src/routes/+layout.server.ts",d.rootLayoutServer()),m("src/routes/+error.svelte",d.errorSvelte()),m("src/routes/+page.svelte",d.homePage(c)),this.info("Setting up testing..."),m("vitest.config.ts",d.vitestConfig()),m("playwright.config.ts",d.playwrightConfig()),m("tests/unit/example.test.ts",d.exampleUnitTest()),m("tests/feature/auth.test.ts",d.exampleFeatureTest()),m("src/lib/factories/UserFactory.ts",d.scaffoldUserFactory()),this.success(`Project structure created (${h})`),!t["no-install"]){this.info("Installing dependencies...");try{a("npm install",{cwd:u,stdio:"inherit"}),this.success("Dependencies installed")}catch{this.warn("npm install failed \u2014 run it manually with: cd "+c+" && npm install")}this.info("Installing shadcn-svelte components...");try{a("npx shadcn-svelte@latest add --all --yes",{cwd:u,stdio:"inherit"}),this.success("shadcn-svelte components installed")}catch{this.warn("shadcn-svelte setup failed \u2014 run manually: cd "+c+" && npx shadcn-svelte@latest add --all")}this.info("Running migrations...");try{a("npx svelar migrate",{cwd:u,stdio:"inherit"}),this.success("Migrations complete")}catch{this.warn("Migrations failed \u2014 run manually: cd "+c+" && npx svelar migrate")}this.info("Seeding database...");try{a("npx svelar seed:run",{cwd:u,stdio:"inherit"}),this.success("Database seeded")}catch{this.warn("Seeding failed \u2014 run manually: cd "+c+" && npx svelar seed:run")}}this.log(""),this.log(` \x1B[32m+\x1B[0m Project \x1B[1m${c}\x1B[0m created successfully!
7343
7670
  `),this.log(` Next steps:
7344
- `),this.log(` cd ${c}`),t["no-install"]&&(this.log(" npm install"),this.log(" npx shadcn-svelte@latest add --all"),this.log(" npx svelar migrate"),this.log(" npx svelar seed:run")),this.log(" npm run dev"),this.log(""),this.log(" Default accounts:"),this.log(" Admin: admin@svelar.dev / admin123"),this.log(" Demo: demo@svelar.dev / password"),this.log("")}};function fl(l){return/Service\./.test(l)?"services":/Controller\./.test(l)?"controllers":/Repository\./.test(l)?"repositories":/Request\./.test(l)?"dtos":/Resource\./.test(l)?"resources":/Action\./.test(l)?"actions":/Listener\./.test(l)?"listeners":/Notification\./.test(l)?"notifications":/Registered|Created|Updated|Deleted|Verified|Invited/.test(l)?"events":"models"}function vl(l){let e=l.match(/^src\/lib\/modules\/(\w+)\/(.+)$/);if(e){let[,s,r]=e;return r==="schemas.ts"?`src/lib/schemas/${s}.ts`:r==="gates.ts"?"src/lib/gates.ts":`src/lib/${fl(r)}/${r}`}let t=l.match(/^src\/lib\/shared\/(.+)$/);return t?`src/lib/${t[1]}`:l}function Qr(l,e,t){return e==="schemas"?`$lib/schemas/${l}${t}`:e==="gates"?`$lib/gates${t}`:`$lib/${An(e)}/${e}${t}`}function An(l){return/Service$/.test(l)?"services":/Controller$/.test(l)?"controllers":/Repository$/.test(l)?"repositories":/Request$/.test(l)?"dtos":/Resource$/.test(l)?"resources":/Action$/.test(l)?"actions":/Listener$/.test(l)?"listeners":/Notification$/.test(l)?"notifications":/Registered|Created|Updated|Deleted|Verified|Invited/.test(l)?"events":"models"}function bl(l,e){let s=e.match(/modules\/(\w+)\//)?.[1]||"";return l=l.replace(/\$lib\/modules\/(\w+)\/(\w+)(\.js)?/g,(r,i,n,o)=>Qr(i,n,o||"")),l=l.replace(/\.\/lib\/modules\/(\w+)\/(\w+)(\.js)?/g,(r,i,n,o)=>n==="schemas"?`./lib/schemas/${i}${o||""}`:n==="gates"?`./lib/gates${o||""}`:`./lib/${An(n)}/${n}${o||""}`),l=l.replace(/\$lib\/shared\//g,"$lib/"),l=l.replace(/\.\/lib\/shared\//g,"./lib/"),e.includes("shared/")&&(l=l.replace(/'\.\.\/(\.\.\/\.\.\/)'/g,"'$1'"),l=l.replace(/'\.\.\/\.\.\/\.\.\//g,"'../../")),s&&(l=l.replace(/from '\.\/(\w+)(\.js)?'/g,(r,i,n)=>i.startsWith("$")||i==="app"?r:(n=n||"",`from '${Qr(s,i,n)}'`)),l=l.replace(/import '\.\/(\w+)(\.js)?'/g,(r,i,n)=>i.startsWith("$")||i==="app"?r:(n=n||"",`import '${Qr(s,i,n)}'`))),l}import{existsSync as Ts,readFileSync as Ge,writeFileSync as _n,mkdirSync as yl}from"fs";import{join as z,dirname as wl}from"path";import{createInterface as Cl}from"readline";function xl(l){let e=Cl({input:process.stdin,output:process.stdout});return new Promise(t=>{e.question(l,s=>{e.close(),t(s.trim().toLowerCase())})})}function Ln(l){return new Promise(e=>{let t=new Set,s=0,r=process.stdin,i=process.stdout,n="\x1B[?25l",o="\x1B[?25h";function a(){c>0&&i.write(`\x1B[${l.length+2}A`),i.write(`\x1B[2K \x1B[36mSpace\x1B[0m toggle \x1B[36mA\x1B[0m toggle all \x1B[36m\u2191\u2193\x1B[0m navigate \x1B[36mEnter\x1B[0m confirm
7345
- `);for(let f=0;f<l.length;f++){let y=f===s,M=t.has(f)?"\x1B[32m\u25C9\x1B[0m":"\x1B[90m\u25CB\x1B[0m",T=y?"\x1B[36m\u276F\x1B[0m":" ",D=y?`\x1B[1m${l[f].label}\x1B[0m`:l[f].label,$=l[f].hint?` \x1B[90m${l[f].hint}\x1B[0m`:"";i.write(`\x1B[2K ${T} ${M} ${D}${$}
7346
- `)}let m=t.size;i.write(`\x1B[2K \x1B[90m${m} file${m!==1?"s":""} selected\x1B[0m
7347
- `),c++}let c=0;i.write(n);let u=r.isRaw;r.setRawMode(!0),r.resume(),a();function p(m){let f=m.toString();if(f==="\r"||f===`
7348
- `){h(),e([...t].sort((y,C)=>y-C));return}if(f===""){h(),e([]);return}if(f==="\x1B"&&m.length===1){h(),e([]);return}if(f===" "){t.has(s)?t.delete(s):t.add(s),a();return}if(f==="a"||f==="A"){if(t.size===l.length)t.clear();else for(let y=0;y<l.length;y++)t.add(y);a();return}if(f==="\x1B[A"||f==="k"){s=s>0?s-1:l.length-1,a();return}if(f==="\x1B[B"||f==="j"){s=s<l.length-1?s+1:0,a();return}}function h(){r.removeListener("data",p),r.setRawMode(u??!1),r.pause(),i.write(o)}r.on("data",p)})}var ks=class extends g{name="update";description="Update scaffold files from the latest svelar templates without overwriting customizations";flags=[{name:"force",alias:"f",description:"Overwrite all framework files without prompting",type:"boolean",default:!1},{name:"dry-run",alias:"d",description:"Show what would be updated without writing",type:"boolean",default:!1},{name:"category",alias:"c",description:"Only update a specific category (config, migration, route, page, domain, job, seeder)",type:"string",default:""},{name:"list",alias:"l",description:"List all updatable files and their status",type:"boolean",default:!1},{name:"include-user-files",alias:"u",description:"Include user-customizable files (app.ts, hooks, layouts, home page, etc.)",type:"boolean",default:!1}];async handle(e,t){let s=process.cwd(),r=t.force??!1,i=t["dry-run"]??!1,n=t.category??"",o=t.list??!1,a=t["include-user-files"]??!1,c=Ts(z(s,"src","lib","modules")),u="app";try{u=JSON.parse(Ge(z(s,"package.json"),"utf-8")).name??"app"}catch{}this.log(""),this.info("Svelar Update \u2014 scanning project files..."),this.log("");let p=this.getFileManifest(c,u),h=n?p.filter(R=>R.category===n):p;if(h.length===0){this.warn(`No files found for category "${n}". Valid categories: config, migration, route, page, domain, job, seeder`);return}let m=h.filter(R=>R.ownership==="framework"),f=h.filter(R=>R.ownership==="user"),y=[],C=[],M=[];for(let R of m){let I=z(s,R.path);if(!Ts(I)){y.push(R);continue}let se=Ge(I,"utf-8"),L;try{L=R.content()}catch{continue}this.normalize(se)===this.normalize(L)?M.push(R):C.push(R)}let T=[],D=[],$=[];if(a)for(let R of f){let I=z(s,R.path);if(!Ts(I)){D.push(R);continue}let se=Ge(I,"utf-8"),L;try{L=R.content()}catch{continue}this.normalize(se)===this.normalize(L)?$.push(R):T.push(R)}if(o){this.printStatus(y,C,M,"Framework Files"),a?(this.log(""),this.printStatus(D,T,$,"User-Customizable Files")):(this.log(""),this.log(` \x1B[90m${f.length} user-customizable files not shown. Use --include-user-files to include.\x1B[0m`));return}if(this.log(` Framework files scanned: ${m.length}`),this.log(` Up to date: \x1B[32m${M.length}\x1B[0m`),this.log(` Changed/outdated: \x1B[33m${C.length}\x1B[0m`),this.log(` Missing (new): \x1B[36m${y.length}\x1B[0m`),!a&&f.length>0&&this.log(` User files (excluded): \x1B[90m${f.length}\x1B[0m \x1B[90m(use --include-user-files to include)\x1B[0m`),this.log(""),C.length===0&&y.length===0&&T.length===0&&D.length===0){this.success("All scaffold files are up to date!");return}y.length>0&&await this.handleNewFiles(y,s,r,i),C.length>0&&await this.handleChangedFiles(C,s,r,i,"Framework"),a&&(D.length>0&&await this.handleNewFiles(D,s,r,i),T.length>0&&(this.log(""),this.warn("The following are user-customizable files. Updating them may overwrite your changes."),await this.handleChangedFiles(T,s,!1,i,"User"))),this.log(""),this.success("Update complete.")}async handleNewFiles(e,t,s,r){this.info(`New files available (${e.length}):`);for(let n of e)this.log(` \x1B[36m+\x1B[0m ${n.path} \x1B[90m(${n.description})\x1B[0m`);if(this.log(""),r)return;if(s){for(let n of e)this.writeFile(z(t,n.path),n.content()),this.success(`Created ${n.path}`);return}this.log(" Select files to create:"),this.log("");let i=await Ln(e.map(n=>({label:n.path,hint:n.description})));if(this.log(""),i.length===0)this.log(" Skipped new files.");else for(let n of i)this.writeFile(z(t,e[n].path),e[n].content()),this.success(`Created ${e[n].path}`);this.log("")}async handleChangedFiles(e,t,s,r,i){this.info(`${i} files with updates (${e.length}):`);for(let a of e)this.log(` \x1B[33m~\x1B[0m ${a.path} \x1B[90m(${a.description})\x1B[0m`);if(this.log(""),r){this.info("Dry run \u2014 no files were modified.");return}if(s){for(let a of e)this.backupAndWrite(z(t,a.path),a.content()),this.success(`Updated ${a.path}`);return}let n=await xl(" View diffs before selecting? [y/N] ");if(n==="y"||n==="yes")for(let a of e)this.log(`
7349
- \x1B[1m${a.path}\x1B[0m \x1B[90m(${a.description})\x1B[0m`),this.showDiff(z(t,a.path),a.content());this.log(" Select files to update (creates .bak backups):"),this.log("");let o=await Ln(e.map(a=>({label:a.path,hint:a.description})));if(this.log(""),o.length===0)this.log(" No files updated.");else for(let a of o)this.backupAndWrite(z(t,e[a].path),e[a].content()),this.success(`Updated ${e[a].path} \x1B[90m(backup: ${e[a].path}.bak)\x1B[0m`)}backupAndWrite(e,t){if(Ts(e)){let s=Ge(e,"utf-8");_n(e+".bak",s)}this.writeFile(e,t)}normalize(e){return e.replace(/\r\n/g,`
7350
- `).trim()}writeFile(e,t){yl(wl(e),{recursive:!0}),_n(e,t)}showDiff(e,t){let s=Ge(e,"utf-8").split(`
7671
+ `),this.log(` cd ${c}`),t["no-install"]&&(this.log(" npm install"),this.log(" npx shadcn-svelte@latest add --all"),this.log(" npx svelar migrate"),this.log(" npx svelar seed:run")),this.log(" npm run dev"),this.log(""),this.log(" Default accounts:"),this.log(" Admin: admin@svelar.dev / admin123"),this.log(" Demo: demo@svelar.dev / password"),this.log("")}};function fl(l){return/Service\./.test(l)?"services":/Controller\./.test(l)?"controllers":/Repository\./.test(l)?"repositories":/Request\./.test(l)?"dtos":/Resource\./.test(l)?"resources":/Action\./.test(l)?"actions":/Listener\./.test(l)?"listeners":/Notification\./.test(l)?"notifications":/Registered|Created|Updated|Deleted|Verified|Invited/.test(l)?"events":"models"}function vl(l){let e=l.match(/^src\/lib\/modules\/(\w+)\/(.+)$/);if(e){let[,s,r]=e;return r==="schemas.ts"?`src/lib/schemas/${s}.ts`:r==="gates.ts"?"src/lib/gates.ts":`src/lib/${fl(r)}/${r}`}let t=l.match(/^src\/lib\/shared\/(.+)$/);return t?`src/lib/${t[1]}`:l}function Qr(l,e,t){return e==="schemas"?`$lib/schemas/${l}${t}`:e==="gates"?`$lib/gates${t}`:`$lib/${Ao(e)}/${e}${t}`}function Ao(l){return/Service$/.test(l)?"services":/Controller$/.test(l)?"controllers":/Repository$/.test(l)?"repositories":/Request$/.test(l)?"dtos":/Resource$/.test(l)?"resources":/Action$/.test(l)?"actions":/Listener$/.test(l)?"listeners":/Notification$/.test(l)?"notifications":/Registered|Created|Updated|Deleted|Verified|Invited/.test(l)?"events":"models"}function bl(l,e){let s=e.match(/modules\/(\w+)\//)?.[1]||"";return l=l.replace(/\$lib\/modules\/(\w+)\/(\w+)(\.js)?/g,(r,o,n,i)=>Qr(o,n,i||"")),l=l.replace(/\.\/lib\/modules\/(\w+)\/(\w+)(\.js)?/g,(r,o,n,i)=>n==="schemas"?`./lib/schemas/${o}${i||""}`:n==="gates"?`./lib/gates${i||""}`:`./lib/${Ao(n)}/${n}${i||""}`),l=l.replace(/\$lib\/shared\//g,"$lib/"),l=l.replace(/\.\/lib\/shared\//g,"./lib/"),e.includes("shared/")&&(l=l.replace(/'\.\.\/(\.\.\/\.\.\/)'/g,"'$1'"),l=l.replace(/'\.\.\/\.\.\/\.\.\//g,"'../../")),s&&(l=l.replace(/from '\.\/(\w+)(\.js)?'/g,(r,o,n)=>o.startsWith("$")||o==="app"?r:(n=n||"",`from '${Qr(s,o,n)}'`)),l=l.replace(/import '\.\/(\w+)(\.js)?'/g,(r,o,n)=>o.startsWith("$")||o==="app"?r:(n=n||"",`import '${Qr(s,o,n)}'`))),l}import{existsSync as ks,readFileSync as Qe,writeFileSync as _o,mkdirSync as yl}from"fs";import{join as z,dirname as wl}from"path";import{createInterface as Cl}from"readline";function xl(l){let e=Cl({input:process.stdin,output:process.stdout});return new Promise(t=>{e.question(l,s=>{e.close(),t(s.trim().toLowerCase())})})}function Lo(l){return new Promise(e=>{let t=new Set,s=0,r=process.stdin,o=process.stdout,n="\x1B[?25l",i="\x1B[?25h";function a(){c>0&&o.write(`\x1B[${l.length+2}A`),o.write(`\x1B[2K \x1B[36mSpace\x1B[0m toggle \x1B[36mA\x1B[0m toggle all \x1B[36m\u2191\u2193\x1B[0m navigate \x1B[36mEnter\x1B[0m confirm
7672
+ `);for(let f=0;f<l.length;f++){let y=f===s,$=t.has(f)?"\x1B[32m\u25C9\x1B[0m":"\x1B[90m\u25CB\x1B[0m",T=y?"\x1B[36m\u276F\x1B[0m":" ",D=y?`\x1B[1m${l[f].label}\x1B[0m`:l[f].label,L=l[f].hint?` \x1B[90m${l[f].hint}\x1B[0m`:"";o.write(`\x1B[2K ${T} ${$} ${D}${L}
7673
+ `)}let m=t.size;o.write(`\x1B[2K \x1B[90m${m} file${m!==1?"s":""} selected\x1B[0m
7674
+ `),c++}let c=0;o.write(n);let u=r.isRaw;r.setRawMode(!0),r.resume(),a();function p(m){let f=m.toString();if(f==="\r"||f===`
7675
+ `){h(),e([...t].sort((y,C)=>y-C));return}if(f===""){h(),e([]);return}if(f==="\x1B"&&m.length===1){h(),e([]);return}if(f===" "){t.has(s)?t.delete(s):t.add(s),a();return}if(f==="a"||f==="A"){if(t.size===l.length)t.clear();else for(let y=0;y<l.length;y++)t.add(y);a();return}if(f==="\x1B[A"||f==="k"){s=s>0?s-1:l.length-1,a();return}if(f==="\x1B[B"||f==="j"){s=s<l.length-1?s+1:0,a();return}}function h(){r.removeListener("data",p),r.setRawMode(u??!1),r.pause(),o.write(i)}r.on("data",p)})}var $s=class extends g{name="update";description="Update scaffold files from the latest svelar templates without overwriting customizations";flags=[{name:"force",alias:"f",description:"Overwrite all framework files without prompting",type:"boolean",default:!1},{name:"dry-run",alias:"d",description:"Show what would be updated without writing",type:"boolean",default:!1},{name:"category",alias:"c",description:"Only update a specific category (config, migration, route, page, domain, job, seeder)",type:"string",default:""},{name:"list",alias:"l",description:"List all updatable files and their status",type:"boolean",default:!1},{name:"include-user-files",alias:"u",description:"Include user-customizable files (app.ts, hooks, layouts, home page, etc.)",type:"boolean",default:!1}];async handle(e,t){let s=process.cwd(),r=t.force??!1,o=t["dry-run"]??!1,n=t.category??"",i=t.list??!1,a=t["include-user-files"]??!1,c=ks(z(s,"src","lib","modules")),u="app";try{u=JSON.parse(Qe(z(s,"package.json"),"utf-8")).name??"app"}catch{}this.log(""),this.info("Svelar Update \u2014 scanning project files..."),this.log("");let p=this.getFileManifest(c,u),h=n?p.filter(R=>R.category===n):p;if(h.length===0){this.warn(`No files found for category "${n}". Valid categories: config, migration, route, page, domain, job, seeder`);return}let m=h.filter(R=>R.ownership==="framework"),f=h.filter(R=>R.ownership==="user"),y=[],C=[],$=[];for(let R of m){let j=z(s,R.path);if(!ks(j)){y.push(R);continue}let se=Qe(j,"utf-8"),M;try{M=R.content()}catch{continue}this.normalize(se)===this.normalize(M)?$.push(R):C.push(R)}let T=[],D=[],L=[];if(a)for(let R of f){let j=z(s,R.path);if(!ks(j)){D.push(R);continue}let se=Qe(j,"utf-8"),M;try{M=R.content()}catch{continue}this.normalize(se)===this.normalize(M)?L.push(R):T.push(R)}if(i){this.printStatus(y,C,$,"Framework Files"),a?(this.log(""),this.printStatus(D,T,L,"User-Customizable Files")):(this.log(""),this.log(` \x1B[90m${f.length} user-customizable files not shown. Use --include-user-files to include.\x1B[0m`));return}if(this.log(` Framework files scanned: ${m.length}`),this.log(` Up to date: \x1B[32m${$.length}\x1B[0m`),this.log(` Changed/outdated: \x1B[33m${C.length}\x1B[0m`),this.log(` Missing (new): \x1B[36m${y.length}\x1B[0m`),!a&&f.length>0&&this.log(` User files (excluded): \x1B[90m${f.length}\x1B[0m \x1B[90m(use --include-user-files to include)\x1B[0m`),this.log(""),C.length===0&&y.length===0&&T.length===0&&D.length===0){this.success("All scaffold files are up to date!");return}y.length>0&&await this.handleNewFiles(y,s,r,o),C.length>0&&await this.handleChangedFiles(C,s,r,o,"Framework"),a&&(D.length>0&&await this.handleNewFiles(D,s,r,o),T.length>0&&(this.log(""),this.warn("The following are user-customizable files. Updating them may overwrite your changes."),await this.handleChangedFiles(T,s,!1,o,"User"))),this.log(""),this.success("Update complete.")}async handleNewFiles(e,t,s,r){this.info(`New files available (${e.length}):`);for(let n of e)this.log(` \x1B[36m+\x1B[0m ${n.path} \x1B[90m(${n.description})\x1B[0m`);if(this.log(""),r)return;if(s){for(let n of e)this.writeFile(z(t,n.path),n.content()),this.success(`Created ${n.path}`);return}this.log(" Select files to create:"),this.log("");let o=await Lo(e.map(n=>({label:n.path,hint:n.description})));if(this.log(""),o.length===0)this.log(" Skipped new files.");else for(let n of o)this.writeFile(z(t,e[n].path),e[n].content()),this.success(`Created ${e[n].path}`);this.log("")}async handleChangedFiles(e,t,s,r,o){this.info(`${o} files with updates (${e.length}):`);for(let a of e)this.log(` \x1B[33m~\x1B[0m ${a.path} \x1B[90m(${a.description})\x1B[0m`);if(this.log(""),r){this.info("Dry run \u2014 no files were modified.");return}if(s){for(let a of e)this.backupAndWrite(z(t,a.path),a.content()),this.success(`Updated ${a.path}`);return}let n=await xl(" View diffs before selecting? [y/N] ");if(n==="y"||n==="yes")for(let a of e)this.log(`
7676
+ \x1B[1m${a.path}\x1B[0m \x1B[90m(${a.description})\x1B[0m`),this.showDiff(z(t,a.path),a.content());this.log(" Select files to update (creates .bak backups):"),this.log("");let i=await Lo(e.map(a=>({label:a.path,hint:a.description})));if(this.log(""),i.length===0)this.log(" No files updated.");else for(let a of i)this.backupAndWrite(z(t,e[a].path),e[a].content()),this.success(`Updated ${e[a].path} \x1B[90m(backup: ${e[a].path}.bak)\x1B[0m`)}backupAndWrite(e,t){if(ks(e)){let s=Qe(e,"utf-8");_o(e+".bak",s)}this.writeFile(e,t)}normalize(e){return e.replace(/\r\n/g,`
7677
+ `).trim()}writeFile(e,t){yl(wl(e),{recursive:!0}),_o(e,t)}showDiff(e,t){let s=Qe(e,"utf-8").split(`
7351
7678
  `),r=t.split(`
7352
- `);this.log(" \x1B[90m--- current\x1B[0m"),this.log(" \x1B[90m+++ updated\x1B[0m");let i=Math.max(s.length,r.length),n=0,o=[];for(let c=0;c<i;c++){let u=s[c]??"",p=r[c]??"";u!==p?(s[c]!==void 0&&o.push(` \x1B[31m- ${u}\x1B[0m`),r[c]!==void 0&&o.push(` \x1B[32m+ ${p}\x1B[0m`),n=0):(n<2&&o.length>0&&o.push(` \x1B[90m ${u}\x1B[0m`),n++)}let a=o.slice(0,50);for(let c of a)this.log(c);o.length>50&&this.log(` \x1B[90m... and ${o.length-50} more lines\x1B[0m`),this.log("")}printStatus(e,t,s,r){this.info(r);let i=[];for(let n of e)i.push(["\x1B[36mNEW\x1B[0m",n.path,n.category,n.description]);for(let n of t)i.push(["\x1B[33mCHANGED\x1B[0m",n.path,n.category,n.description]);for(let n of s)i.push(["\x1B[32mOK\x1B[0m",n.path,n.category,n.description]);this.table(["Status","File","Category","Description"],i)}getFileManifest(e,t){let s=[],r=(y,C,M,T,D="framework")=>{s.push({path:y,content:C,category:M,description:T,ownership:D})};r("src/app.ts",()=>d.appTs(),"config","Application bootstrap","user"),r("src/hooks.server.ts",()=>d.hooksServerTs(),"config","SvelteKit hooks","user"),r("vite.config.ts",()=>d.viteConfig(),"config","Vite configuration","user"),r(".env.example",()=>d.envExample(),"config","Environment template"),r("svelar.database.json",()=>d.svelarDatabaseJson(),"config","Database config"),r("src/app.css",()=>d.appCss(),"config","Global styles"),r("src/app.html",()=>d.appHtml(),"config","HTML shell"),r("src/lib/database/migrations/00000001_create_users_table.ts",()=>d.createUsersTable(),"migration","Users table"),r("src/lib/database/migrations/00000002_create_posts_table.ts",()=>d.createPostsTable(),"migration","Posts table"),r("src/lib/database/migrations/00000003_create_permissions_tables.ts",()=>d.createPermissionsTables(),"migration","Permissions tables"),r("src/lib/database/migrations/00000004_add_role_to_users.ts",()=>d.addRoleToUsers(),"migration","Role column on users"),r("src/lib/database/migrations/00000005_create_sessions_table.ts",()=>d.createSessionsTable(),"migration","Sessions table"),r("src/lib/database/migrations/00000006_create_audit_logs_table.ts",()=>d.createAuditLogsTable(),"migration","Audit logs table"),r("src/lib/database/migrations/00000007_create_notifications_table.ts",()=>d.createNotificationsTable(),"migration","Notifications table"),r("src/lib/database/migrations/00000008_create_failed_jobs_table.ts",()=>d.createFailedJobsTable(),"migration","Failed jobs table");let i=e?"src/lib/modules/auth":"src/lib",n=e?`${i}/User.ts`:`${i}/models/User.ts`,o=e?`${i}/UserRepository.ts`:`${i}/repositories/UserRepository.ts`,a=e?`${i}/AuthService.ts`:`${i}/services/AuthService.ts`,c=e?`${i}/AuthController.ts`:`${i}/controllers/AuthController.ts`,u=e?`${i}/RegisterUserAction.ts`:`${i}/actions/RegisterUserAction.ts`;r(n,()=>d.userModel(),"domain","User model"),r(o,()=>d.userRepository(),"domain","User repository"),r(a,()=>d.authService(),"domain","Auth service"),r(c,()=>d.authController(),"domain","Auth controller"),r(u,()=>d.registerUserAction(),"domain","Register user action");let p=e?i:`${i}/dtos`;r(`${e?i:p}/RegisterRequest.ts`,()=>d.registerRequest(),"domain","Register DTO"),r(`${e?i:p}/LoginRequest.ts`,()=>d.loginRequest(),"domain","Login DTO"),r(`${e?i:p}/ForgotPasswordRequest.ts`,()=>d.forgotPasswordRequest(),"domain","Forgot password DTO"),r(`${e?i:p}/ResetPasswordRequest.ts`,()=>d.resetPasswordRequest(),"domain","Reset password DTO"),r(`${e?i:p}/OtpSendRequest.ts`,()=>d.otpSendRequest(),"domain","OTP send DTO"),r(`${e?i:p}/OtpVerifyRequest.ts`,()=>d.otpVerifyRequest(),"domain","OTP verify DTO"),r(`${e?i:`${i}/resources`}/UserResource.ts`,()=>d.userResource(),"domain","User resource"),r(`${e?i:`${i}/schemas`}/gates.ts`,()=>d.gates(),"domain","Authorization gates"),r(`${e?i+"/schemas":`${i}/schemas`}.ts`,()=>d.authSchema(),"domain","Auth Zod schemas");let h=e?"src/lib/modules/posts":"src/lib";r(`${e?h:`${h}/models`}/Post.ts`,()=>d.postModel(),"domain","Post model","user"),r(`${e?h:`${h}/repositories`}/PostRepository.ts`,()=>d.postRepository(),"domain","Post repository","user"),r(`${e?h:`${h}/services`}/PostService.ts`,()=>d.postService(),"domain","Post service","user"),r(`${e?h:`${h}/controllers`}/PostController.ts`,()=>d.postController(),"domain","Post controller","user"),r(`${e?h:`${h}/actions`}/CreatePostAction.ts`,()=>d.createPostAction(),"domain","Create post action","user"),r("src/lib/database/seeders/DatabaseSeeder.ts",()=>d.databaseSeeder(),"seeder","Database seeder","user"),r("src/routes/login/+page.server.ts",()=>d.loginPageServer(),"page","Login server"),r("src/routes/login/+page.svelte",()=>d.loginPageSvelte(),"page","Login page"),r("src/routes/register/+page.server.ts",()=>d.registerPageServer(),"page","Register server"),r("src/routes/register/+page.svelte",()=>d.registerPageSvelte(),"page","Register page"),r("src/routes/logout/+page.server.ts",()=>d.logoutPageServer(),"page","Logout handler"),r("src/routes/forgot-password/+page.server.ts",()=>d.forgotPasswordPageServer(),"page","Forgot password server"),r("src/routes/forgot-password/+page.svelte",()=>d.forgotPasswordPageSvelte(),"page","Forgot password page"),r("src/routes/reset-password/+page.server.ts",()=>d.resetPasswordPageServer(),"page","Reset password server"),r("src/routes/reset-password/+page.svelte",()=>d.resetPasswordPageSvelte(),"page","Reset password page"),r("src/routes/otp-login/+page.server.ts",()=>d.otpLoginPageServer(),"page","OTP login server"),r("src/routes/otp-login/+page.svelte",()=>d.otpLoginPageSvelte(),"page","OTP login page"),r("src/routes/verify-email/+page.server.ts",()=>d.verifyEmailPageServer(),"page","Verify email server"),r("src/routes/verify-email/+page.svelte",()=>d.verifyEmailPageSvelte(),"page","Verify email page"),r("src/routes/dashboard/+layout.server.ts",()=>d.dashboardLayoutServer(),"page","Dashboard auth guard"),r("src/routes/dashboard/+layout.svelte",()=>d.dashboardLayoutSvelte(),"page","Dashboard layout"),r("src/routes/dashboard/+page.server.ts",()=>d.dashboardPageServer(),"page","Dashboard server"),r("src/routes/dashboard/+page.svelte",()=>d.dashboardPageSvelte(),"page","Dashboard overview"),r("src/routes/dashboard/api-keys/+page.server.ts",()=>d.apiKeysPageServer(),"page","API keys server"),r("src/routes/dashboard/api-keys/+page.svelte",()=>d.apiKeysPageSvelte(),"page","API keys page"),r("src/routes/dashboard/team/+page.server.ts",()=>d.teamPageServer(),"page","Team server"),r("src/routes/dashboard/team/+page.svelte",()=>d.teamPageSvelte(),"page","Team page"),r("src/routes/admin/+layout.server.ts",()=>d.adminLayoutServer(),"page","Admin auth guard"),r("src/routes/admin/+layout.svelte",()=>d.adminLayoutSvelte(),"page","Admin layout"),r("src/routes/admin/+page.server.ts",()=>d.adminPageServer(),"page","Admin server"),r("src/routes/admin/+page.svelte",()=>d.adminPageSvelte(),"page","Admin dashboard"),r("src/routes/api/health/+server.ts",()=>d.apiHealth(),"route","Health check"),r("src/routes/api/auth/register/+server.ts",()=>d.apiAuthRegister(),"route","Auth register API"),r("src/routes/api/auth/login/+server.ts",()=>d.apiAuthLogin(),"route","Auth login API"),r("src/routes/api/auth/logout/+server.ts",()=>d.apiAuthLogout(),"route","Auth logout API"),r("src/routes/api/auth/me/+server.ts",()=>d.apiAuthMe(),"route","Auth me API"),r("src/routes/api/auth/forgot-password/+server.ts",()=>d.apiAuthForgotPassword(),"route","Forgot password API"),r("src/routes/api/auth/reset-password/+server.ts",()=>d.apiAuthResetPassword(),"route","Reset password API"),r("src/routes/api/auth/otp/send/+server.ts",()=>d.apiAuthOtpSend(),"route","OTP send API"),r("src/routes/api/auth/otp/verify/+server.ts",()=>d.apiAuthOtpVerify(),"route","OTP verify API"),r("src/routes/api/auth/verify-email/+server.ts",()=>d.apiAuthVerifyEmail(),"route","Verify email API"),r("src/routes/api/posts/+server.ts",()=>d.apiPosts(),"route","Posts list/create API"),r("src/routes/api/posts/[id]/+server.ts",()=>d.apiPostsSingle(),"route","Post CRUD API"),r("src/routes/api/posts/mine/+server.ts",()=>d.apiPostsMine(),"route","My posts API"),r("src/routes/api/broadcasting/[channel]/+server.ts",()=>d.apiBroadcasting(),"route","SSE broadcasting"),r("src/routes/api/internal/broadcast/+server.ts",()=>d.apiInternalBroadcast(),"route","Internal broadcast bridge"),r("src/routes/api/admin/users/+server.ts",()=>d.apiAdminUsers(),"route","Admin users API"),r("src/routes/api/admin/roles/+server.ts",()=>d.apiAdminRoles(),"route","Admin roles API"),r("src/routes/api/admin/permissions/+server.ts",()=>d.apiAdminPermissions(),"route","Admin permissions API"),r("src/routes/api/admin/role-permissions/+server.ts",()=>d.apiAdminRolePermissions(),"route","Role-permissions API"),r("src/routes/api/admin/user-roles/+server.ts",()=>d.apiAdminUserRoles(),"route","User-roles API"),r("src/routes/api/admin/user-permissions/+server.ts",()=>d.apiAdminUserPermissions(),"route","User-permissions API"),r("src/routes/api/admin/export/+server.ts",()=>d.apiAdminExport(),"route","Admin data export"),r("src/routes/api/admin/health/+server.ts",()=>d.apiAdminHealth(),"route","Admin health API"),r("src/routes/api/admin/queue/+server.ts",()=>d.apiAdminQueue(),"route","Admin queue API"),r("src/routes/api/admin/queue/[id]/retry/+server.ts",()=>d.apiAdminQueueRetry(),"route","Queue retry API"),r("src/routes/api/admin/queue/[id]/+server.ts",()=>d.apiAdminQueueDelete(),"route","Queue job API"),r("src/routes/api/admin/scheduler/+server.ts",()=>d.apiAdminScheduler(),"route","Admin scheduler API"),r("src/routes/api/admin/scheduler/[name]/run/+server.ts",()=>d.apiAdminSchedulerRun(),"route","Run task API"),r("src/routes/api/admin/scheduler/[name]/toggle/+server.ts",()=>d.apiAdminSchedulerToggle(),"route","Toggle task API"),r("src/routes/api/admin/logs/+server.ts",()=>d.apiAdminLogs(),"route","Admin logs API"),r("src/routes/api/admin/stats/+server.ts",()=>d.apiAdminStats(),"route","Admin stats API");let m=e?"src/lib/shared/jobs":"src/lib/jobs";r(`${m}/SendWelcomeEmail.ts`,()=>d.sendWelcomeEmail(),"job","Welcome email job","user"),r(`${m}/DailyDigestJob.ts`,()=>d.dailyDigestJob(),"job","Daily digest job","user"),r(`${m}/ExportDataJob.ts`,()=>d.exportDataJob(),"job","Export data job","user");let f=e?"src/lib/shared/scheduler":"src/lib/scheduler";return r(`${f}/CleanupExpiredTokens.ts`,()=>d.cleanupExpiredTokens(),"job","Cleanup tokens task","user"),r(`${f}/CleanExpiredSessions.ts`,()=>d.cleanExpiredSessions(),"job","Clean sessions task","user"),r(`${f}/DailyDigestEmail.ts`,()=>d.dailyDigestEmail(),"job","Daily digest task","user"),r(`${f}/PruneAuditLogs.ts`,()=>d.pruneAuditLogs(),"job","Prune audit logs task","user"),r(`${f}/QueueHealthCheck.ts`,()=>d.queueHealthCheck(),"job","Queue health check task","user"),r("src/routes/+layout.svelte",()=>d.rootLayoutSvelte(t),"page","Root layout","user"),r("src/routes/+layout.server.ts",()=>d.rootLayoutServer(),"page","Root layout server","user"),r("src/routes/+error.svelte",()=>d.errorSvelte(),"page","Error page","user"),r("src/routes/+page.svelte",()=>d.homePage(t),"page","Home page","user"),s}};var $s=class extends g{name="key:generate";description="Generate a new APP_KEY and set it in .env";flags=[{name:"show",alias:"s",description:"Only display the key, do not write to .env",type:"boolean",default:!1},{name:"force",alias:"f",description:"Overwrite existing APP_KEY",type:"boolean",default:!1}];async handle(e,t){let{randomBytes:s}=await import("crypto"),{join:r}=await import("path"),{existsSync:i,readFileSync:n,writeFileSync:o}=await import("fs"),a=s(32).toString("hex");if(t.show){this.log(`
7679
+ `);this.log(" \x1B[90m--- current\x1B[0m"),this.log(" \x1B[90m+++ updated\x1B[0m");let o=Math.max(s.length,r.length),n=0,i=[];for(let c=0;c<o;c++){let u=s[c]??"",p=r[c]??"";u!==p?(s[c]!==void 0&&i.push(` \x1B[31m- ${u}\x1B[0m`),r[c]!==void 0&&i.push(` \x1B[32m+ ${p}\x1B[0m`),n=0):(n<2&&i.length>0&&i.push(` \x1B[90m ${u}\x1B[0m`),n++)}let a=i.slice(0,50);for(let c of a)this.log(c);i.length>50&&this.log(` \x1B[90m... and ${i.length-50} more lines\x1B[0m`),this.log("")}printStatus(e,t,s,r){this.info(r);let o=[];for(let n of e)o.push(["\x1B[36mNEW\x1B[0m",n.path,n.category,n.description]);for(let n of t)o.push(["\x1B[33mCHANGED\x1B[0m",n.path,n.category,n.description]);for(let n of s)o.push(["\x1B[32mOK\x1B[0m",n.path,n.category,n.description]);this.table(["Status","File","Category","Description"],o)}getFileManifest(e,t){let s=[],r=(y,C,$,T,D="framework")=>{s.push({path:y,content:C,category:$,description:T,ownership:D})};r("src/app.ts",()=>d.appTs(),"config","Application bootstrap","user"),r("src/hooks.server.ts",()=>d.hooksServerTs(),"config","SvelteKit hooks","user"),r("vite.config.ts",()=>d.viteConfig(),"config","Vite configuration","user"),r(".env.example",()=>d.envExample(),"config","Environment template"),r("svelar.database.json",()=>d.svelarDatabaseJson(),"config","Database config"),r("src/app.css",()=>d.appCss(),"config","Global styles"),r("src/app.html",()=>d.appHtml(),"config","HTML shell"),r("src/lib/database/migrations/00000001_create_users_table.ts",()=>d.createUsersTable(),"migration","Users table"),r("src/lib/database/migrations/00000002_create_posts_table.ts",()=>d.createPostsTable(),"migration","Posts table"),r("src/lib/database/migrations/00000003_create_permissions_tables.ts",()=>d.createPermissionsTables(),"migration","Permissions tables"),r("src/lib/database/migrations/00000004_add_role_to_users.ts",()=>d.addRoleToUsers(),"migration","Role column on users"),r("src/lib/database/migrations/00000005_create_sessions_table.ts",()=>d.createSessionsTable(),"migration","Sessions table"),r("src/lib/database/migrations/00000006_create_audit_logs_table.ts",()=>d.createAuditLogsTable(),"migration","Audit logs table"),r("src/lib/database/migrations/00000007_create_notifications_table.ts",()=>d.createNotificationsTable(),"migration","Notifications table"),r("src/lib/database/migrations/00000008_create_failed_jobs_table.ts",()=>d.createFailedJobsTable(),"migration","Failed jobs table");let o=e?"src/lib/modules/auth":"src/lib",n=e?`${o}/User.ts`:`${o}/models/User.ts`,i=e?`${o}/UserRepository.ts`:`${o}/repositories/UserRepository.ts`,a=e?`${o}/AuthService.ts`:`${o}/services/AuthService.ts`,c=e?`${o}/AuthController.ts`:`${o}/controllers/AuthController.ts`,u=e?`${o}/RegisterUserAction.ts`:`${o}/actions/RegisterUserAction.ts`;r(n,()=>d.userModel(),"domain","User model"),r(i,()=>d.userRepository(),"domain","User repository"),r(a,()=>d.authService(),"domain","Auth service"),r(c,()=>d.authController(),"domain","Auth controller"),r(u,()=>d.registerUserAction(),"domain","Register user action");let p=e?o:`${o}/dtos`;r(`${e?o:p}/RegisterRequest.ts`,()=>d.registerRequest(),"domain","Register DTO"),r(`${e?o:p}/LoginRequest.ts`,()=>d.loginRequest(),"domain","Login DTO"),r(`${e?o:p}/ForgotPasswordRequest.ts`,()=>d.forgotPasswordRequest(),"domain","Forgot password DTO"),r(`${e?o:p}/ResetPasswordRequest.ts`,()=>d.resetPasswordRequest(),"domain","Reset password DTO"),r(`${e?o:p}/OtpSendRequest.ts`,()=>d.otpSendRequest(),"domain","OTP send DTO"),r(`${e?o:p}/OtpVerifyRequest.ts`,()=>d.otpVerifyRequest(),"domain","OTP verify DTO"),r(`${e?o:`${o}/resources`}/UserResource.ts`,()=>d.userResource(),"domain","User resource"),r(`${e?o:`${o}/schemas`}/gates.ts`,()=>d.gates(),"domain","Authorization gates"),r(`${e?o+"/schemas":`${o}/schemas`}.ts`,()=>d.authSchema(),"domain","Auth Zod schemas");let h=e?"src/lib/modules/posts":"src/lib";r(`${e?h:`${h}/models`}/Post.ts`,()=>d.postModel(),"domain","Post model","user"),r(`${e?h:`${h}/repositories`}/PostRepository.ts`,()=>d.postRepository(),"domain","Post repository","user"),r(`${e?h:`${h}/services`}/PostService.ts`,()=>d.postService(),"domain","Post service","user"),r(`${e?h:`${h}/controllers`}/PostController.ts`,()=>d.postController(),"domain","Post controller","user"),r(`${e?h:`${h}/actions`}/CreatePostAction.ts`,()=>d.createPostAction(),"domain","Create post action","user"),r("src/lib/database/seeders/DatabaseSeeder.ts",()=>d.databaseSeeder(),"seeder","Database seeder","user"),r("src/routes/login/+page.server.ts",()=>d.loginPageServer(),"page","Login server"),r("src/routes/login/+page.svelte",()=>d.loginPageSvelte(),"page","Login page"),r("src/routes/register/+page.server.ts",()=>d.registerPageServer(),"page","Register server"),r("src/routes/register/+page.svelte",()=>d.registerPageSvelte(),"page","Register page"),r("src/routes/logout/+page.server.ts",()=>d.logoutPageServer(),"page","Logout handler"),r("src/routes/forgot-password/+page.server.ts",()=>d.forgotPasswordPageServer(),"page","Forgot password server"),r("src/routes/forgot-password/+page.svelte",()=>d.forgotPasswordPageSvelte(),"page","Forgot password page"),r("src/routes/reset-password/+page.server.ts",()=>d.resetPasswordPageServer(),"page","Reset password server"),r("src/routes/reset-password/+page.svelte",()=>d.resetPasswordPageSvelte(),"page","Reset password page"),r("src/routes/otp-login/+page.server.ts",()=>d.otpLoginPageServer(),"page","OTP login server"),r("src/routes/otp-login/+page.svelte",()=>d.otpLoginPageSvelte(),"page","OTP login page"),r("src/routes/verify-email/+page.server.ts",()=>d.verifyEmailPageServer(),"page","Verify email server"),r("src/routes/verify-email/+page.svelte",()=>d.verifyEmailPageSvelte(),"page","Verify email page"),r("src/routes/dashboard/+layout.server.ts",()=>d.dashboardLayoutServer(),"page","Dashboard auth guard"),r("src/routes/dashboard/+layout.svelte",()=>d.dashboardLayoutSvelte(),"page","Dashboard layout"),r("src/routes/dashboard/+page.server.ts",()=>d.dashboardPageServer(),"page","Dashboard server"),r("src/routes/dashboard/+page.svelte",()=>d.dashboardPageSvelte(),"page","Dashboard overview"),r("src/routes/dashboard/api-keys/+page.server.ts",()=>d.apiKeysPageServer(),"page","API keys server"),r("src/routes/dashboard/api-keys/+page.svelte",()=>d.apiKeysPageSvelte(),"page","API keys page"),r("src/routes/dashboard/team/+page.server.ts",()=>d.teamPageServer(),"page","Team server"),r("src/routes/dashboard/team/+page.svelte",()=>d.teamPageSvelte(),"page","Team page"),r("src/routes/admin/+layout.server.ts",()=>d.adminLayoutServer(),"page","Admin auth guard"),r("src/routes/admin/+layout.svelte",()=>d.adminLayoutSvelte(),"page","Admin layout"),r("src/routes/admin/+page.server.ts",()=>d.adminPageServer(),"page","Admin server"),r("src/routes/admin/+page.svelte",()=>d.adminPageSvelte(),"page","Admin dashboard"),r("src/routes/api/health/+server.ts",()=>d.apiHealth(),"route","Health check"),r("src/routes/api/auth/register/+server.ts",()=>d.apiAuthRegister(),"route","Auth register API"),r("src/routes/api/auth/login/+server.ts",()=>d.apiAuthLogin(),"route","Auth login API"),r("src/routes/api/auth/logout/+server.ts",()=>d.apiAuthLogout(),"route","Auth logout API"),r("src/routes/api/auth/me/+server.ts",()=>d.apiAuthMe(),"route","Auth me API"),r("src/routes/api/auth/forgot-password/+server.ts",()=>d.apiAuthForgotPassword(),"route","Forgot password API"),r("src/routes/api/auth/reset-password/+server.ts",()=>d.apiAuthResetPassword(),"route","Reset password API"),r("src/routes/api/auth/otp/send/+server.ts",()=>d.apiAuthOtpSend(),"route","OTP send API"),r("src/routes/api/auth/otp/verify/+server.ts",()=>d.apiAuthOtpVerify(),"route","OTP verify API"),r("src/routes/api/auth/verify-email/+server.ts",()=>d.apiAuthVerifyEmail(),"route","Verify email API"),r("src/routes/api/posts/+server.ts",()=>d.apiPosts(),"route","Posts list/create API"),r("src/routes/api/posts/[id]/+server.ts",()=>d.apiPostsSingle(),"route","Post CRUD API"),r("src/routes/api/posts/mine/+server.ts",()=>d.apiPostsMine(),"route","My posts API"),r("src/routes/api/broadcasting/[channel]/+server.ts",()=>d.apiBroadcasting(),"route","SSE broadcasting"),r("src/routes/api/internal/broadcast/+server.ts",()=>d.apiInternalBroadcast(),"route","Internal broadcast bridge"),r("src/routes/api/admin/users/+server.ts",()=>d.apiAdminUsers(),"route","Admin users API"),r("src/routes/api/admin/roles/+server.ts",()=>d.apiAdminRoles(),"route","Admin roles API"),r("src/routes/api/admin/permissions/+server.ts",()=>d.apiAdminPermissions(),"route","Admin permissions API"),r("src/routes/api/admin/role-permissions/+server.ts",()=>d.apiAdminRolePermissions(),"route","Role-permissions API"),r("src/routes/api/admin/user-roles/+server.ts",()=>d.apiAdminUserRoles(),"route","User-roles API"),r("src/routes/api/admin/user-permissions/+server.ts",()=>d.apiAdminUserPermissions(),"route","User-permissions API"),r("src/routes/api/admin/export/+server.ts",()=>d.apiAdminExport(),"route","Admin data export"),r("src/routes/api/admin/health/+server.ts",()=>d.apiAdminHealth(),"route","Admin health API"),r("src/routes/api/admin/queue/+server.ts",()=>d.apiAdminQueue(),"route","Admin queue API"),r("src/routes/api/admin/queue/[id]/retry/+server.ts",()=>d.apiAdminQueueRetry(),"route","Queue retry API"),r("src/routes/api/admin/queue/[id]/+server.ts",()=>d.apiAdminQueueDelete(),"route","Queue job API"),r("src/routes/api/admin/scheduler/+server.ts",()=>d.apiAdminScheduler(),"route","Admin scheduler API"),r("src/routes/api/admin/scheduler/[name]/run/+server.ts",()=>d.apiAdminSchedulerRun(),"route","Run task API"),r("src/routes/api/admin/scheduler/[name]/toggle/+server.ts",()=>d.apiAdminSchedulerToggle(),"route","Toggle task API"),r("src/routes/api/admin/logs/+server.ts",()=>d.apiAdminLogs(),"route","Admin logs API"),r("src/routes/api/admin/stats/+server.ts",()=>d.apiAdminStats(),"route","Admin stats API");let m=e?"src/lib/shared/jobs":"src/lib/jobs";r(`${m}/SendWelcomeEmail.ts`,()=>d.sendWelcomeEmail(),"job","Welcome email job","user"),r(`${m}/DailyDigestJob.ts`,()=>d.dailyDigestJob(),"job","Daily digest job","user"),r(`${m}/ExportDataJob.ts`,()=>d.exportDataJob(),"job","Export data job","user");let f=e?"src/lib/shared/scheduler":"src/lib/scheduler";return r(`${f}/CleanupExpiredTokens.ts`,()=>d.cleanupExpiredTokens(),"job","Cleanup tokens task","user"),r(`${f}/CleanExpiredSessions.ts`,()=>d.cleanExpiredSessions(),"job","Clean sessions task","user"),r(`${f}/DailyDigestEmail.ts`,()=>d.dailyDigestEmail(),"job","Daily digest task","user"),r(`${f}/PruneAuditLogs.ts`,()=>d.pruneAuditLogs(),"job","Prune audit logs task","user"),r(`${f}/QueueHealthCheck.ts`,()=>d.queueHealthCheck(),"job","Queue health check task","user"),r("src/routes/+layout.svelte",()=>d.rootLayoutSvelte(t),"page","Root layout","user"),r("src/routes/+layout.server.ts",()=>d.rootLayoutServer(),"page","Root layout server","user"),r("src/routes/+error.svelte",()=>d.errorSvelte(),"page","Error page","user"),r("src/routes/+page.svelte",()=>d.homePage(t),"page","Home page","user"),s}};var Ds=class extends g{name="key:generate";description="Generate a new APP_KEY and set it in .env";flags=[{name:"show",alias:"s",description:"Only display the key, do not write to .env",type:"boolean",default:!1},{name:"force",alias:"f",description:"Overwrite existing APP_KEY",type:"boolean",default:!1}];async handle(e,t){let{randomBytes:s}=await import("crypto"),{join:r}=await import("path"),{existsSync:o,readFileSync:n,writeFileSync:i}=await import("fs"),a=s(32).toString("hex");if(t.show){this.log(`
7353
7680
  APP_KEY=${a}
7354
- `);return}let c=r(process.cwd(),".env");if(!i(c)){let h=r(process.cwd(),".env.example");if(i(h)){let m=n(h,"utf-8");m=m.replace(/^APP_KEY=.*$/m,`APP_KEY=${a}`),o(c,m),this.success("Application key set (created .env from .env.example).")}else o(c,`APP_KEY=${a}
7355
- `),this.success("Application key set (created .env).");return}let u=n(c,"utf-8"),p=u.match(/^APP_KEY=(.*)$/m);if(p&&p[1]&&p[1]!=="change-me-to-a-random-string"&&!t.force){this.warn("APP_KEY already set. Use --force to overwrite.");return}if(p){let h=u.replace(/^APP_KEY=.*$/m,`APP_KEY=${a}`);o(c,h)}else o(c,`APP_KEY=${a}
7356
- ${u}`);this.success("Application key set.")}};var _s=class extends g{name="plugin:list";description="List all discovered and enabled plugins";arguments=[];flags=[];async handle(e,t){try{let{PluginRegistry:s}=await Promise.resolve().then(()=>(As(),Zr)),r=s;await r.discover();let i=r.list();if(i.length===0){this.info("No plugins discovered.");return}let n=["Name","Version","Description","Status","Config","Migrations"],o=i.map(a=>[a.name,a.version,a.description||"-",a.enabled?"\u2713 Enabled":" Disabled",a.hasConfig?"\u2713":"-",a.hasMigrations?"\u2713":"-"]);this.newLine(),this.table(n,o),this.newLine(),this.info(`Total: ${i.length} plugin(s)`)}catch(s){this.error(`Failed to list plugins: ${s?.message??String(s)}`)}}};var Ls=class extends g{name="plugin:publish";description="Publish a plugin's config and migration files";arguments=["name"];flags=[{name:"force",alias:"f",description:"Overwrite existing files",type:"boolean"},{name:"only",alias:"o",description:"Publish only config|migrations|assets",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a plugin name.");return}try{let{PluginRegistry:r}=await Promise.resolve().then(()=>(As(),Zr)),{PluginPublisher:i}=await Promise.resolve().then(()=>(ti(),Mn)),n=r,o=i;await n.discover();let a=n.get(s);if(!a){this.error(`Plugin "${s}" not found.`);return}let c=await this.loadPluginClass(a.packageName);if(!c){this.error(`Failed to load plugin class for "${s}".`);return}let u=new c,p={force:t.force||!1,only:t.only};this.info(`Publishing plugin: ${s}`);let h=await o.publish(u,p);this.newLine(),h.configs.length>0&&(this.success(`${h.configs.length} config file(s) published:`),h.configs.forEach(m=>this.log(` - ${m}`))),h.migrations.length>0&&(this.success(`${h.migrations.length} migration file(s) published:`),h.migrations.forEach(m=>this.log(` - ${m}`))),h.assets.length>0&&(this.success(`${h.assets.length} asset file(s) published:`),h.assets.forEach(m=>this.log(` - ${m}`))),h.configs.length===0&&h.migrations.length===0&&h.assets.length===0&&this.warn("No publishable files found for this plugin."),this.newLine()}catch(r){this.error(`Failed to publish plugin: ${r?.message??String(r)}`)}}async loadPluginClass(e){try{let t=await import(e);return t.default||Object.values(t)[0]}catch{return null}}};var Ms=class extends g{name="plugin:install";description="Install a plugin from npm";arguments=["package"];flags=[{name:"no-publish",alias:"n",description:"Skip auto-publishing plugin assets",type:"boolean"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a package name.");return}try{let{PluginInstaller:r}=await Promise.resolve().then(()=>(Nn(),On)),i=r;this.info(`Installing plugin package: ${s}`),this.newLine();let n=await i.install(s,{publish:!t["no-publish"]});this.newLine(),n.success?(this.success(`Plugin installed: ${n.pluginName} (v${n.version})`),n.published&&(n.published.configs.length>0&&this.info(`${n.published.configs.length} config file(s) published`),n.published.migrations.length>0&&this.info(`${n.published.migrations.length} migration file(s) published`),n.published.assets.length>0&&this.info(`${n.published.assets.length} asset file(s) published`)),this.newLine(),this.log("You can now use the plugin in your application by registering it in your app bootstrap code.")):this.error(`Failed to install plugin: ${n.error}`),this.newLine()}catch(r){this.error(`Installation error: ${r?.message??String(r)}`)}}};var In=ri(process.cwd(),".env");if(El(In))for(let l of qn(In,"utf-8").split(`
7357
- `)){let e=l.trim();if(!e||e.startsWith("#"))continue;let t=e.indexOf("=");if(t===-1)continue;let s=e.slice(0,t).trim(),r=e.slice(t+1).trim();(r.startsWith('"')&&r.endsWith('"')||r.startsWith("'")&&r.endsWith("'"))&&(r=r.slice(1,-1)),s in process.env||(process.env[s]=r)}var Tl=jn(Un(import.meta.url));Rl(Pl(ri(Tl,"ts-resolve-hook.mjs")).href,import.meta.url);var kl=jn(Un(import.meta.url)),$l=ri(kl,"..","..","package.json"),Dl=JSON.parse(qn($l,"utf-8")),b=new st(Dl.version);b.register(Es);b.register(ks);b.register($s);b.register(it);b.register(nt);b.register(ot);b.register(at);b.register(lt);b.register(ct);b.register(dt);b.register(ut);b.register(mt);b.register(pt);b.register(Mt);b.register(Ot);b.register(ht);b.register(gt);b.register(ft);b.register(vt);b.register(bt);b.register(yt);b.register(re);b.register(ie);b.register(ne);b.register(wt);b.register(Ct);b.register(xt);b.register(St);b.register(Pt);b.register(Nt);b.register(It);b.register(jt);b.register(Ut);b.register(qt);b.register(Ft);b.register(Bt);b.register(Kt);b.register(Vt);b.register(Yt);b.register(Qt);b.register(Gt);b.register(Rs);b.register(_s);b.register(Ls);b.register(Ms);b.register(Rt);b.register(Et);b.register(Tt);b.register(kt);b.register($t);b.register(Dt);b.register(At);b.register(_t);b.register(Lt);async function Al(){let{join:l}=await import("path"),{existsSync:e,readdirSync:t}=await import("fs"),{pathToFileURL:s}=await import("url"),r=l(process.cwd(),"src","lib","shared","commands");if(!e(r))return;let i=t(r).filter(n=>(n.endsWith(".ts")||n.endsWith(".js"))&&!n.startsWith("."));for(let n of i)try{let o=l(r,n),c=await import(s(o).href),u=c.default??Object.values(c).find(p=>typeof p=="function"&&p.prototype&&"handle"in p.prototype);u&&typeof u=="function"&&b.add(new u)}catch{}}Al().then(()=>b.run());
7681
+ `);return}let c=r(process.cwd(),".env");if(!o(c)){let h=r(process.cwd(),".env.example");if(o(h)){let m=n(h,"utf-8");m=m.replace(/^APP_KEY=.*$/m,`APP_KEY=${a}`),i(c,m),this.success("Application key set (created .env from .env.example).")}else i(c,`APP_KEY=${a}
7682
+ `),this.success("Application key set (created .env).");return}let u=n(c,"utf-8"),p=u.match(/^APP_KEY=(.*)$/m);if(p&&p[1]&&p[1]!=="change-me-to-a-random-string"&&!t.force){this.warn("APP_KEY already set. Use --force to overwrite.");return}if(p){let h=u.replace(/^APP_KEY=.*$/m,`APP_KEY=${a}`);i(c,h)}else i(c,`APP_KEY=${a}
7683
+ ${u}`);this.success("Application key set.")}};var Ls=class extends g{name="plugin:list";description="List all discovered and enabled plugins";arguments=[];flags=[];async handle(e,t){try{let{PluginRegistry:s}=await Promise.resolve().then(()=>(_s(),Xr)),r=s;await r.discover();let o=r.list();if(o.length===0){this.info("No plugins discovered.");return}let n=["Name","Version","Description","Status","Config","Migrations"],i=o.map(a=>[a.name,a.version,a.description||"-",a.enabled?"\u2713 Enabled":" Disabled",a.hasConfig?"\u2713":"-",a.hasMigrations?"\u2713":"-"]);this.newLine(),this.table(n,i),this.newLine(),this.info(`Total: ${o.length} plugin(s)`)}catch(s){this.error(`Failed to list plugins: ${s?.message??String(s)}`)}}};var Ms=class extends g{name="plugin:publish";description="Publish a plugin's config and migration files";arguments=["name"];flags=[{name:"force",alias:"f",description:"Overwrite existing files",type:"boolean"},{name:"only",alias:"o",description:"Publish only config|migrations|assets",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a plugin name.");return}try{let{PluginRegistry:r}=await Promise.resolve().then(()=>(_s(),Xr)),{PluginPublisher:o}=await Promise.resolve().then(()=>(si(),Mo)),n=r,i=o;await n.discover();let a=n.get(s);if(!a){this.error(`Plugin "${s}" not found.`);return}let c=await this.loadPluginClass(a.packageName);if(!c){this.error(`Failed to load plugin class for "${s}".`);return}let u=new c,p={force:t.force||!1,only:t.only};this.info(`Publishing plugin: ${s}`);let h=await i.publish(u,p);this.newLine(),h.configs.length>0&&(this.success(`${h.configs.length} config file(s) published:`),h.configs.forEach(m=>this.log(` - ${m}`))),h.migrations.length>0&&(this.success(`${h.migrations.length} migration file(s) published:`),h.migrations.forEach(m=>this.log(` - ${m}`))),h.assets.length>0&&(this.success(`${h.assets.length} asset file(s) published:`),h.assets.forEach(m=>this.log(` - ${m}`))),h.configs.length===0&&h.migrations.length===0&&h.assets.length===0&&this.warn("No publishable files found for this plugin."),this.newLine()}catch(r){this.error(`Failed to publish plugin: ${r?.message??String(r)}`)}}async loadPluginClass(e){try{let t=await import(e);return t.default||Object.values(t)[0]}catch{return null}}};var Os=class extends g{name="plugin:install";description="Install a plugin from npm";arguments=["package"];flags=[{name:"no-publish",alias:"n",description:"Skip auto-publishing plugin assets",type:"boolean"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a package name.");return}try{let{PluginInstaller:r}=await Promise.resolve().then(()=>(Io(),Oo)),o=r;this.info(`Installing plugin package: ${s}`),this.newLine();let n=await o.install(s,{publish:!t["no-publish"]});this.newLine(),n.success?(this.success(`Plugin installed: ${n.pluginName} (v${n.version})`),n.published&&(n.published.configs.length>0&&this.info(`${n.published.configs.length} config file(s) published`),n.published.migrations.length>0&&this.info(`${n.published.migrations.length} migration file(s) published`),n.published.assets.length>0&&this.info(`${n.published.assets.length} asset file(s) published`)),this.newLine(),this.log("You can now use the plugin in your application by registering it in your app bootstrap code.")):this.error(`Failed to install plugin: ${n.error}`),this.newLine()}catch(r){this.error(`Installation error: ${r?.message??String(r)}`)}}};var No=ii(process.cwd(),".env");if(El(No))for(let l of qo(No,"utf-8").split(`
7684
+ `)){let e=l.trim();if(!e||e.startsWith("#"))continue;let t=e.indexOf("=");if(t===-1)continue;let s=e.slice(0,t).trim(),r=e.slice(t+1).trim();(r.startsWith('"')&&r.endsWith('"')||r.startsWith("'")&&r.endsWith("'"))&&(r=r.slice(1,-1)),s in process.env||(process.env[s]=r)}var Tl=jo(Uo(import.meta.url));Rl(Pl(ii(Tl,"ts-resolve-hook.mjs")).href,import.meta.url);var kl=jo(Uo(import.meta.url)),$l=ii(kl,"..","..","package.json"),Dl=JSON.parse(qo($l,"utf-8")),b=new st(Dl.version);b.register(Ts);b.register($s);b.register(Ds);b.register(it);b.register(ot);b.register(nt);b.register(at);b.register(lt);b.register(ct);b.register(dt);b.register(ut);b.register(mt);b.register(pt);b.register(Ot);b.register(It);b.register(ht);b.register(gt);b.register(ft);b.register(vt);b.register(bt);b.register(yt);b.register(re);b.register(ie);b.register(oe);b.register(Ct);b.register(xt);b.register(St);b.register(Pt);b.register(Rt);b.register(Nt);b.register(jt);b.register(Ut);b.register(qt);b.register(Ft);b.register(Bt);b.register(Ht);b.register(Wt);b.register(Yt);b.register(Gt);b.register(Qt);b.register(Zt);b.register(Es);b.register(Ls);b.register(Ms);b.register(Os);b.register(Et);b.register(Tt);b.register(kt);b.register($t);b.register(Dt);b.register(At);b.register(_t);b.register(Lt);b.register(Mt);async function Al(){let{join:l}=await import("path"),{existsSync:e,readdirSync:t}=await import("fs"),{pathToFileURL:s}=await import("url"),r=l(process.cwd(),"src","lib","shared","commands");if(!e(r))return;let o=t(r).filter(n=>(n.endsWith(".ts")||n.endsWith(".js"))&&!n.startsWith("."));for(let n of o)try{let i=l(r,n),c=await import(s(i).href),u=c.default??Object.values(c).find(p=>typeof p=="function"&&p.prototype&&"handle"in p.prototype);u&&typeof u=="function"&&b.add(new u)}catch{}}Al().then(()=>b.run());