@beeblock/svelar 0.4.4 → 0.4.6

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 wn=Object.defineProperty;var ze=(o=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(o,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):o)(function(o){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+o+'" is not supported')});var y=(o,e)=>()=>(o&&(e=o(o=0)),e);var E=(o,e)=>{for(var t in e)wn(o,t,{get:e[t],enumerable:!0})};function w(o,e){let t=Symbol.for(o),s=globalThis;return s[t]||(s[t]=e()),s[t]}var S=y(()=>{"use strict"});var P={};E(P,{Connection:()=>f});var us,f,C=y(()=>{"use strict";S();us=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),a=t.map(d=>typeof d=="boolean"?d?1:0:d instanceof Date?d.toISOString():d),l=n.prepare(e),c=e.trimStart().toUpperCase();return c.startsWith("SELECT")||c.startsWith("PRAGMA")||c.startsWith("WITH")?l.all(...a):l.run(...a)}case"postgres":return(await this.rawClient(s))(e,...t);case"mysql":{let n=await this.rawClient(s),[a]=await n.execute(e,t);return a}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(l){let c=i.prepare(l);return{all(...d){return c.all(...d)},run(...d){return c.run(...d)},get(...d){return c.get(...d)}}},exec(l){i.exec(l)},pragma(l){return i.prepare(`PRAGMA ${l}`).all()},close(){i.close()}},a;try{let{drizzle:l}=await import("drizzle-orm/better-sqlite3");a=l(n)}catch{a=n}return{drizzle:a,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{}}},f=w("svelar.connection",()=>new us)});var _,ys,W,j,ni,bs=y(()=>{"use strict";C();S();_=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 ys(this.column)}build(){return this.column}},ys=class{constructor(e){this.column=e}onDelete(e){return this.column.references.onDelete=e,this}onUpdate(e){return this.column.references.onUpdate=e,this}},W=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 _(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 _(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 _(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 _(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 nn=Object.defineProperty;var ze=(o=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(o,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):o)(function(o){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+o+'" is not supported')});var y=(o,e)=>()=>(o&&(e=o(o=0)),e);var k=(o,e)=>{for(var t in e)nn(o,t,{get:e[t],enumerable:!0})};function C(o,e){let t=Symbol.for(o),s=globalThis;return s[t]||(s[t]=e()),s[t]}var R=y(()=>{"use strict"});var S={};k(S,{Connection:()=>f});var ms,f,x=y(()=>{"use strict";R();ms=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),a=t.map(u=>typeof u=="boolean"?u?1:0:u instanceof Date?u.toISOString():u),l=n.prepare(e),c=e.trimStart().toUpperCase();return c.startsWith("SELECT")||c.startsWith("PRAGMA")||c.startsWith("WITH")?l.all(...a):l.run(...a)}case"postgres":return(await this.rawClient(s))(e,...t);case"mysql":{let n=await this.rawClient(s),[a]=await n.execute(e,t);return a}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(l){let c=i.prepare(l);return{all(...u){return c.all(...u)},run(...u){return c.run(...u)},get(...u){return c.get(...u)}}},exec(l){i.exec(l)},pragma(l){return i.prepare(`PRAGMA ${l}`).all()},close(){i.close()}},a;try{let{drizzle:l}=await import("drizzle-orm/better-sqlite3");a=l(n)}catch{a=n}return{drizzle:a,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{}}},f=C("svelar.connection",()=>new ms)});var I,bs,K,j,Kr,ys=y(()=>{"use strict";x();R();I=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}},K=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 I(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 I(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 I(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 I(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} (
3
3
  ${r.join(`,
4
4
  `)}
5
- )`);for(let i of this.indices){let n=i.name??`idx_${e}_${i.columns.join("_")}`,a=i.unique?"UNIQUE ":"";s.push(`CREATE ${a}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 W;t(s);let r=f.getDriver(this.connectionName),i=s.toSQL(e,r);for(let n of i)await f.raw(n,[],this.connectionName)}async dropTable(e){await f.raw(`DROP TABLE IF EXISTS ${e}`,[],this.connectionName)}async dropTableIfExists(e){await f.raw(`DROP TABLE IF EXISTS ${e}`,[],this.connectionName)}async renameTable(e,t){f.getDriver(this.connectionName)==="mysql"?await f.raw(`RENAME TABLE ${e} TO ${t}`,[],this.connectionName):await f.raw(`ALTER TABLE ${e} RENAME TO ${t}`,[],this.connectionName)}async hasTable(e){let t=f.getDriver(this.connectionName),s;switch(t){case"sqlite":s=await f.raw("SELECT name FROM sqlite_master WHERE type='table' AND name=?",[e],this.connectionName);break;case"postgres":s=await f.raw("SELECT tablename FROM pg_tables WHERE tablename = $1",[e],this.connectionName);break;case"mysql":s=await f.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 W;t(s);let r=f.getDriver(this.connectionName),i=s.columns;for(let n of i){let a=s.columnToSQL(n,r);await f.raw(`ALTER TABLE ${e} ADD COLUMN ${a}`,[],this.connectionName)}}async dropColumn(e,t){await f.raw(`ALTER TABLE ${e} DROP COLUMN ${t}`,[],this.connectionName)}},ni=w("svelar.schema",()=>new j)});var ai={};E(ai,{Migration:()=>we,Migrator:()=>Ce});var we,Ce,vs=y(()=>{"use strict";C();bs();we=class{schema=new j},Ce=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 f.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 f.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,a=e.find(l=>l.name===n);a&&(await a.migration.down(),await f.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=f.getDriver(this.connectionName),t=[];switch(e){case"sqlite":{t=(await f.raw("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'",[],this.connectionName)).map(r=>r.name),await f.raw("PRAGMA foreign_keys = OFF",[],this.connectionName);for(let r of t)await f.raw(`DROP TABLE IF EXISTS "${r}"`,[],this.connectionName);await f.raw("PRAGMA foreign_keys = ON",[],this.connectionName);break}case"mysql":{t=(await f.raw("SHOW TABLES",[],this.connectionName)).map(r=>Object.values(r)[0]),await f.raw("SET FOREIGN_KEY_CHECKS = 0",[],this.connectionName);for(let r of t)await f.raw(`DROP TABLE IF EXISTS \`${r}\``,[],this.connectionName);await f.raw("SET FOREIGN_KEY_CHECKS = 1",[],this.connectionName);break}case"postgres":{t=(await f.raw("SELECT tablename FROM pg_tables WHERE schemaname = 'public'",[],this.connectionName)).map(r=>r.tablename);for(let r of t)await f.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 f.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 f.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 f.raw(`SELECT MAX(batch) as max_batch FROM ${this.migrationsTable}`,[],this.connectionName))[0]?.max_batch??0}catch{return 0}}}});var vt={};E(vt,{SchedulerLock:()=>Pe});import{hostname as qa}from"os";async function xe(){let{Connection:o}=await Promise.resolve().then(()=>(C(),P));return o}async function Ua(){return(await xe()).getDriver()}var ci,F,Pe,Re=y(()=>{"use strict";ci=!1,F=`${qa()}:${process.pid}:${Math.random().toString(36).slice(2,10)}`;Pe=class{static getOwnerId(){return F}static async ensureTable(){if(ci)return;let e=await xe();switch(e.getDriver()){case"sqlite":await e.raw(`CREATE TABLE IF NOT EXISTS scheduler_locks (
5
+ )`);for(let i of this.indices){let n=i.name??`idx_${e}_${i.columns.join("_")}`,a=i.unique?"UNIQUE ":"";s.push(`CREATE ${a}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 K;t(s);let r=f.getDriver(this.connectionName),i=s.toSQL(e,r);for(let n of i)await f.raw(n,[],this.connectionName)}async dropTable(e){await f.raw(`DROP TABLE IF EXISTS ${e}`,[],this.connectionName)}async dropTableIfExists(e){await f.raw(`DROP TABLE IF EXISTS ${e}`,[],this.connectionName)}async renameTable(e,t){f.getDriver(this.connectionName)==="mysql"?await f.raw(`RENAME TABLE ${e} TO ${t}`,[],this.connectionName):await f.raw(`ALTER TABLE ${e} RENAME TO ${t}`,[],this.connectionName)}async hasTable(e){let t=f.getDriver(this.connectionName),s;switch(t){case"sqlite":s=await f.raw("SELECT name FROM sqlite_master WHERE type='table' AND name=?",[e],this.connectionName);break;case"postgres":s=await f.raw("SELECT tablename FROM pg_tables WHERE tablename = $1",[e],this.connectionName);break;case"mysql":s=await f.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 K;t(s);let r=f.getDriver(this.connectionName),i=s.columns;for(let n of i){let a=s.columnToSQL(n,r);await f.raw(`ALTER TABLE ${e} ADD COLUMN ${a}`,[],this.connectionName)}}async dropColumn(e,t){await f.raw(`ALTER TABLE ${e} DROP COLUMN ${t}`,[],this.connectionName)}},Kr=C("svelar.schema",()=>new j)});var Wr={};k(Wr,{Migration:()=>we,Migrator:()=>Ce});var we,Ce,vs=y(()=>{"use strict";x();ys();we=class{schema=new j},Ce=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 f.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 f.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,a=e.find(l=>l.name===n);a&&(await a.migration.down(),await f.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=f.getDriver(this.connectionName),t=[];switch(e){case"sqlite":{t=(await f.raw("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'",[],this.connectionName)).map(r=>r.name),await f.raw("PRAGMA foreign_keys = OFF",[],this.connectionName);for(let r of t)await f.raw(`DROP TABLE IF EXISTS "${r}"`,[],this.connectionName);await f.raw("PRAGMA foreign_keys = ON",[],this.connectionName);break}case"mysql":{t=(await f.raw("SHOW TABLES",[],this.connectionName)).map(r=>Object.values(r)[0]),await f.raw("SET FOREIGN_KEY_CHECKS = 0",[],this.connectionName);for(let r of t)await f.raw(`DROP TABLE IF EXISTS \`${r}\``,[],this.connectionName);await f.raw("SET FOREIGN_KEY_CHECKS = 1",[],this.connectionName);break}case"postgres":{t=(await f.raw("SELECT tablename FROM pg_tables WHERE schemaname = 'public'",[],this.connectionName)).map(r=>r.tablename);for(let r of t)await f.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 f.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 f.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 f.raw(`SELECT MAX(batch) as max_batch FROM ${this.migrationsTable}`,[],this.connectionName))[0]?.max_batch??0}catch{return 0}}}});var wt={};k(wt,{SchedulerLock:()=>Se});import{hostname as Ba}from"os";async function xe(){let{Connection:o}=await Promise.resolve().then(()=>(x(),S));return o}async function Fa(){return(await xe()).getDriver()}var Qr,B,Se,Pe=y(()=>{"use strict";Qr=!1,B=`${Ba()}:${process.pid}:${Math.random().toString(36).slice(2,10)}`;Se=class{static getOwnerId(){return B}static async ensureTable(){if(Qr)return;let e=await xe();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 wn=Object.defineProperty;var ze=(o=>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}ci=!0}static async acquire(e,t=5){await this.ensureTable();let s=await xe(),r=await Ua(),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,F,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,F,n]);break;case"mysql":await s.raw("INSERT IGNORE INTO scheduler_locks (task_key, owner, expires_at) VALUES (?, ?, ?)",[e,F,n]);break}});let a=await s.raw("SELECT owner FROM scheduler_locks WHERE task_key = ?",[e]);return a.length>0&&a[0].owner===F}catch{return!1}}static async release(e){try{await(await xe()).raw("DELETE FROM scheduler_locks WHERE task_key = ? AND owner = ?",[e,F])}catch{}}static async releaseAll(){try{await(await xe()).raw("DELETE FROM scheduler_locks WHERE owner = ?",[F])}catch{}}}});var ui={};E(ui,{ScheduledTask:()=>wt,Scheduler:()=>xs,SchedulerLock:()=>Pe,cronMatches:()=>Cs,parseCron:()=>di,task:()=>Fa});function Se(o,e,t){if(o==="*")return null;let s=new Set;for(let r of o.split(",")){let[i,n]=r.split("/"),a=n?parseInt(n,10):1;if(i==="*")for(let l=e;l<=t;l+=a)s.add(l);else if(i.includes("-")){let[l,c]=i.split("-"),d=parseInt(l,10),p=parseInt(c,10);for(let h=d;h<=p;h+=a)s.add(h)}else s.add(parseInt(i,10))}return[...s].sort((r,i)=>r-i)}function di(o){let e=o.trim().split(/\s+/);if(e.length!==5)throw new Error(`Invalid cron expression: "${o}". Expected 5 fields.`);return{minute:Se(e[0],0,59),hour:Se(e[1],0,23),dayOfMonth:Se(e[2],1,31),month:Se(e[3],1,12),dayOfWeek:Se(e[4],0,6)}}function Cs(o,e){let t=di(o),s=e.getMinutes(),r=e.getHours(),i=e.getDate(),n=e.getMonth()+1,a=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(a))}function Fa(o,e,t){class s extends wt{name=o;schedule(){return t&&t(this),this}async handle(){return e()}}return new s}var wt,xs,mi=y(()=>{"use strict";Re();wt=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(()=>(Re(),vt));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(()=>(Re(),vt));await s.release(this.name)}catch{}}}},xs=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(Cs(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(()=>(Re(),vt));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=>Cs(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(()=>(C(),P));switch(e.getDriver()){case"sqlite":await e.raw(`CREATE TABLE IF NOT EXISTS scheduled_task_runs (
17
+ ) ENGINE=InnoDB`);break}Qr=!0}static async acquire(e,t=5){await this.ensureTable();let s=await xe(),r=await Fa(),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,B,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,B,n]);break;case"mysql":await s.raw("INSERT IGNORE INTO scheduler_locks (task_key, owner, expires_at) VALUES (?, ?, ?)",[e,B,n]);break}});let a=await s.raw("SELECT owner FROM scheduler_locks WHERE task_key = ?",[e]);return a.length>0&&a[0].owner===B}catch{return!1}}static async release(e){try{await(await xe()).raw("DELETE FROM scheduler_locks WHERE task_key = ? AND owner = ?",[e,B])}catch{}}static async releaseAll(){try{await(await xe()).raw("DELETE FROM scheduler_locks WHERE owner = ?",[B])}catch{}}}});var Yr={};k(Yr,{ScheduledTask:()=>Ct,Scheduler:()=>xs,SchedulerLock:()=>Se,cronMatches:()=>Cs,parseCron:()=>Gr,task:()=>Ha});function Re(o,e,t){if(o==="*")return null;let s=new Set;for(let r of o.split(",")){let[i,n]=r.split("/"),a=n?parseInt(n,10):1;if(i==="*")for(let l=e;l<=t;l+=a)s.add(l);else if(i.includes("-")){let[l,c]=i.split("-"),u=parseInt(l,10),m=parseInt(c,10);for(let h=u;h<=m;h+=a)s.add(h)}else s.add(parseInt(i,10))}return[...s].sort((r,i)=>r-i)}function Gr(o){let e=o.trim().split(/\s+/);if(e.length!==5)throw new Error(`Invalid cron expression: "${o}". Expected 5 fields.`);return{minute:Re(e[0],0,59),hour:Re(e[1],0,23),dayOfMonth:Re(e[2],1,31),month:Re(e[3],1,12),dayOfWeek:Re(e[4],0,6)}}function Cs(o,e){let t=Gr(o),s=e.getMinutes(),r=e.getHours(),i=e.getDate(),n=e.getMonth()+1,a=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(a))}function Ha(o,e,t){class s extends Ct{name=o;schedule(){return t&&t(this),this}async handle(){return e()}}return new s}var Ct,xs,Zr=y(()=>{"use strict";Pe();Ct=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(()=>(Pe(),wt));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(()=>(Pe(),wt));await s.release(this.name)}catch{}}}},xs=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(Cs(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(()=>(Pe(),wt));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=>Cs(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(()=>(x(),S));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 wn=Object.defineProperty;var ze=(o=>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(()=>(C(),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 Te={};E(Te,{Job:()=>V,Queue:()=>ks});var V,xt,Ps,J,Pt,Rs,Ss,Ts,Es,ks,Q=y(()=>{"use strict";S();V=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)}},xt=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(){}},Ps=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()}},J=class{constructor(e,t){this.table=e;this.registry=t}async getConnection(){let{Connection:e}=await Promise.resolve().then(()=>(C(),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(()=>(x(),S));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 Te={};k(Te,{Job:()=>J,Queue:()=>$s});var J,St,Ps,W,Pt,Rs,Ts,Es,ks,$s,V=y(()=>{"use strict";R();J=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)}},St=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(){}},Ps=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()}},W=class{constructor(e,t){this.table=e;this.registry=t}async getConnection(){let{Connection:e}=await Promise.resolve().then(()=>(x(),S));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),a=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:a}}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])}},Pt=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(),a=this.config.prefix??"svelar",l=new i.Worker(e,async c=>{let d=c.data,p=t.resolve(d.jobClass,d.payload);p.attempts=c.attemptsMade+1,await p.handle()},{connection:n,prefix:a,concurrency:r?.concurrency??1});return l.on("failed",async(c,d)=>{let p=c?.data;if(p)try{let h=t.resolve(p.jobClass,p.payload);c.attemptsMade>=(c.opts?.attempts??3)&&(h.failed(d),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},d))}catch{console.error("[Queue] Failed to resolve job for failure handler:",d.message)}}),l}},Rs=class{table="svelar_failed_jobs";async getConnection(){let{Connection:e}=await Promise.resolve().then(()=>(C(),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}},Ss=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)}},Ts=class{config={default:"sync",connections:{sync:{driver:"sync"}}};drivers=new Map;processing=!1;jobRegistry=new Ss;failedStore=new Rs;_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 xt,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 Es(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 Pt){let l=await s.createWorker(r,this.jobRegistry,this.failedStore,{concurrency:e?.concurrency??1});return this.processing=!0,this._activeWorker=l,await new Promise(c=>{let d=()=>{this.processing?setTimeout(d,500):l.close().then(c).catch(c)};d()}),0}let i=e?.maxJobs??1/0,n=(e?.sleep??1)*1e3,a=0;for(this.processing=!0;this.processing&&a<i;){let l=await s.pop(r);if(!l){if(i===1/0){await new Promise(c=>setTimeout(c,n));continue}break}l.attempts++,l.job.attempts=l.attempts;try{await l.job.handle(),a++,s instanceof J&&await s.delete(l.id)}catch(c){if(l.attempts<l.maxAttempts){l.job.retrying(l.attempts);let d=l.job.retryDelay??60;s instanceof J?await s.release(l.id,d):(l.availableAt=Date.now()+d*1e3,await s.push(l))}else l.job.failed(c),await this.failedStore.store(l,c),s instanceof J&&await s.delete(l.id)}}return a}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 xt;break;case"memory":s=new Ps;break;case"database":s=new J(t.table??"svelar_jobs",this.jobRegistry);break;case"redis":s=new Pt(t,this.jobRegistry);break;default:throw new Error(`Unknown queue driver: ${t.driver}`)}return this.drivers.set(e,s),s}},Es=class extends V{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()}))})}},ks=w("svelar.queue",()=>new Ts)});var L,$s=y(()=>{"use strict";C();L=class o{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 o(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 o("__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 o("__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 o("__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 o("__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 o("__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 o("__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 f.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 f.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 f.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 f.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 f.raw(t,s,this.connectionName))[0]?.aggregate??null}async min(e){let{sql:t,bindings:s}=this.buildAggregate(`MIN(${e})`);return(await f.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 f.raw(this.toSQL().sql,this.toSQL().bindings,this.connectionName)).map(s=>s[e])}async value(e){return this.selectColumns=[e],this.limitValue=1,(await f.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=f.getDriver(this.connectionName),i=Object.keys(e),n=Object.values(e),a=n.map(()=>"?").join(", "),l=s??i.filter(d=>!t.includes(d)),c;if(r==="postgres"){let d=l.map(p=>`${p} = EXCLUDED.${p}`).join(", ");c=`INSERT INTO ${this.tableName} (${i.join(", ")}) VALUES (${a}) ON CONFLICT (${t.join(", ")}) DO UPDATE SET ${d}`}else if(r==="mysql"){let d=l.map(p=>`${p} = VALUES(${p})`).join(", ");c=`INSERT INTO ${this.tableName} (${i.join(", ")}) VALUES (${a}) ON DUPLICATE KEY UPDATE ${d}`}else{let d=l.map(p=>`${p} = excluded.${p}`).join(", ");c=`INSERT INTO ${this.tableName} (${i.join(", ")}) VALUES (${a}) ON CONFLICT (${t.join(", ")}) DO UPDATE SET ${d}`}return f.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 a=t.map(l=>n[l]);s.push(...a),r.push(`(${a.map(()=>"?").join(", ")})`)}let i=`INSERT INTO ${this.tableName} (${t.join(", ")}) VALUES ${r.join(", ")}`;return f.raw(i,s,this.connectionName)}async firstOrCreate(e,t={}){for(let[n,a]of Object.entries(e))this.where(n,a);let s=await this.first();if(s)return s;let r={...e,...t},i=await new o(this.tableName,this.modelClass,this.connectionName).insertGetId(r);return new o(this.tableName,this.modelClass,this.connectionName).findOrFail(i)}async updateOrCreate(e,t){let s=new o(this.tableName,this.modelClass,this.connectionName);for(let[a,l]of Object.entries(e))s.where(a,l);let r=await s.first();if(r)return await new o(this.tableName,this.modelClass,this.connectionName).where(this.modelClass?.primaryKey??"id",r[this.modelClass?.primaryKey??"id"]).update(t),new o(this.tableName,this.modelClass,this.connectionName).findOrFail(r[this.modelClass?.primaryKey??"id"]);let i={...e,...t},n=await new o(this.tableName,this.modelClass,this.connectionName).insertGetId(i);return new o(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 o("__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(){f.getDriver(this.connectionName)==="sqlite"?(await f.raw(`DELETE FROM ${this.tableName}`,[],this.connectionName),await f.raw("DELETE FROM sqlite_sequence WHERE name = ?",[this.tableName],this.connectionName)):await f.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 f.raw(i,s,this.connectionName)}async insertGetId(e,t="id"){let s=f.getDriver(this.connectionName),r=Object.keys(e),i=Object.values(e),n=i.map(()=>"?").join(", "),a=`INSERT INTO ${this.tableName} (${r.join(", ")}) VALUES (${n})`;return s==="postgres"?(a+=` RETURNING ${t}`,(await f.raw(a,i,this.connectionName))[0]?.[t]):(await f.raw(a,i,this.connectionName),s==="sqlite"?(await f.raw("SELECT last_insert_rowid() as id",[],this.connectionName))[0]?.id:s==="mysql"?(await f.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(l=>`${l} = ?`).join(", "),{whereSQL:i,whereBindings:n}=this.buildWhere(),a=`UPDATE ${this.tableName} SET ${r}${i}`;return await f.raw(a,[...s,...n],this.connectionName),1}async delete(){let{whereSQL:e,whereBindings:t}=this.buildWhere(),s=`DELETE FROM ${this.tableName}${e}`;return await f.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 f.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 a=this.cteClauses.some(c=>c.recursive)?"WITH RECURSIVE":"WITH",l=this.cteClauses.map(c=>(t.push(...c.bindings),`${c.name} AS (${c.sql})`));e.push(`${a} ${l.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 a of this.havingClauses)a.type==="raw"?(n.push(a.raw),a.values&&t.push(...a.values)):(n.push(`${a.column} ${a.operator} ?`),t.push(a.value));e.push(`HAVING ${n.join(" AND ")}`)}if(this.orderClauses.length>0){let n=this.orderClauses.map(a=>a.__raw?a.column:`${a.column} ${a.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 o(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 l=(r.operator==="IS","null");e.push(`${i} ${r.column} ${r.operator} ${l}`)}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 a=r.values.map(()=>"?").join(", ");e.push(`${i} ${r.column} NOT IN (${a})`),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 G,Y,Z,X,ee,As=y(()=>{"use strict";C();G=class{parentModel;relatedModel;constructor(e,t){this.parentModel=e,this.relatedModel=t}query(){return this.relatedModel.query()}},Y=class extends G{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(a=>a.getAttribute(this.localKey)),i=await this.relatedModel.query().whereIn(this.foreignKey,r).get(),n=new Map;for(let a of i)n.set(a.getAttribute(this.foreignKey),a);for(let a of t){let l=a.getAttribute(this.localKey);a.setRelation(s,n.get(l)??null)}}async create(t){let s=this.parentModel.getAttribute(this.localKey);return this.relatedModel.create({...t,[this.foreignKey]:s})}},Z=class extends G{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(a=>a.getAttribute(this.localKey)),i=await this.relatedModel.query().whereIn(this.foreignKey,r).get(),n=new Map;for(let a of i){let l=a.getAttribute(this.foreignKey);n.has(l)||n.set(l,[]),n.get(l).push(a)}for(let a of t){let l=a.getAttribute(this.localKey);a.setRelation(s,n.get(l)??[])}}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}},X=class extends G{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(a=>a.getAttribute(this.foreignKey)).filter(a=>a!=null);if(r.length===0){for(let a of t)a.setRelation(s,null);return}let i=await this.relatedModel.query().whereIn(this.ownerKey,r).get(),n=new Map;for(let a of i)n.set(a.getAttribute(this.ownerKey),a);for(let a of t){let l=a.getAttribute(this.foreignKey);a.setRelation(s,n.get(l)??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}},ee=class extends G{constructor(t,s,r,i,n,a="id",l="id"){super(t,s);this.pivotTable=r;this.foreignPivotKey=i;this.relatedPivotKey=n;this.parentKey=a;this.relatedKey=l}async load(t){let s=t.getAttribute(this.parentKey),r=this.relatedModel.tableName,n=(await f.raw(`SELECT ${this.relatedPivotKey} FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ?`,[s])).map(a=>a[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 f.raw(`SELECT * FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} IN (${i})`,r),a=[...new Set(n.map(p=>p[this.relatedPivotKey]))],l=a.length>0?await this.relatedModel.query().whereIn(this.relatedKey,a).get():[],c=new Map;for(let p of l)c.set(p.getAttribute(this.relatedKey),p);let d=new Map;for(let p of n){let h=p[this.foreignPivotKey],u=p[this.relatedPivotKey],v=c.get(u);v&&(d.has(h)||d.set(h,[]),d.get(h).push(v))}for(let p of t){let h=p.getAttribute(this.parentKey);p.setRelation(s,d.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),a=Object.values(i),l=a.map(()=>"?").join(", ");await f.raw(`INSERT INTO ${this.pivotTable} (${n.join(", ")}) VALUES (${l})`,a)}async detach(t){let s=this.parentModel.getAttribute(this.parentKey);t?await f.raw(`DELETE FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ? AND ${this.relatedPivotKey} = ?`,[s,t]):await f.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 f.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 hi=y(()=>{"use strict"});var Ee,Ds=y(()=>{"use strict";Ee=class{app;constructor(e){this.app=e}boot(){}}});var gi=y(()=>{"use strict";Ds();kt()});var ke,te,kt=y(()=>{"use strict";S();hi();gi();ke=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)}},te=w("svelar.event",()=>new ke)});var $t,fi=y(()=>{"use strict";$s();As();kt();$t=class o{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 L(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 a=new Date().toISOString();t.setAttribute(s.createdAt,a),t.setAttribute(s.updatedAt,a)}let r=t.getInsertableAttributes(),n=await new L(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 L(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 L(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 L(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 Y(this,e,t,s??this.constructor.primaryKey)}hasMany(e,t,s){return new Z(this,e,t,s??this.constructor.primaryKey)}belongsTo(e,t,s){return new X(this,e,t,s??e.primaryKey)}belongsToMany(e,t,s,r,i,n){return new ee(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 o?i.toJSON():i):r instanceof o?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=o.hooks.get(t.name);s?.[e]&&await s[e](this),typeof this[e]=="function"&&await this[e]();let r=o.observers.get(t.name)??[];for(let n of r){let a=n[e];typeof a=="function"&&await a.call(n,this)}let i=t.name.toLowerCase();await te.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=o.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 te.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 At,yi=y(()=>{"use strict";At=class{async call(e){await new e().run()}}});var B,bi,Ls=y(()=>{"use strict";S();B=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}},bi=w("svelar.container",()=>new B)});var Dt,vi=y(()=>{"use strict";Ls();Dt=class{container;providers=[];booted=!1;constructor(e){this.container=e??new B,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 T,O,Lt,se,Mt,re,ie,Nt,ne,ae=y(()=>{"use strict";T=class{},O=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 a=this.namedMiddleware.get(n);a&&r.push(a)}let i=t;for(let n=r.length-1;n>=0;n--){let a=r[n],l=i;typeof a.handle=="function"?i=()=>a.handle(e,l):i=()=>a(e,l)}return i()}count(){return this.middleware.length}},Lt=class extends T{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}},se=class extends T{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()}},Mt=class extends T{async handle(e,t){let s=Date.now(),r=e.event.request.method,i=e.event.url.pathname,n=await t(),a=Date.now()-s,l=n instanceof Response?n.status:200;return console.log(`[${new Date().toISOString()}] ${r} ${i} \u2192 ${l} (${a}ms)`),n}},re=class extends T{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 a=this.getCookieToken(s),l=s.request.headers.get(this.headerName)??await this.getBodyToken(s);return!a||!l||!this.timingSafeEqual(a,l)?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 a=0;a<r.length;a++)n|=r[a]^i[a];return n===0}},ie=class extends T{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 a=s.url.origin;return n===a||this.allowedOrigins.has(n)?t():new Response(JSON.stringify({message:"Cross-origin request blocked"}),{status:403,headers:{"Content-Type":"application/json"}})}},Nt=class extends T{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 x=s.url.pathname;if(!this.onlyPaths.some(k=>x.startsWith(k)))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),a=Math.floor(Date.now()/1e3);if(isNaN(n)||Math.abs(a-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:d}=await import("crypto"),p=s.request.method.toUpperCase(),h=s.url.pathname+s.url.search,u=`${i}.${p}.${h}.${c}`,v=d("sha256",this.secret).update(u).digest("hex");return r.length!==v.length||!this.timingSafeCompare(r,v)?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 a=0;a<r.length;a++)n|=r[a]^i[a];return n===0}static sign(e,t,s,r,i){let{createHmac:n}=ze("crypto"),a=i??Math.floor(Date.now()/1e3),l=`${a}.${t.toUpperCase()}.${s}.${r}`;return{signature:n("sha256",e).update(l).digest("hex"),timestamp:a}}},ne=class extends T{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 l=Math.ceil((n.blockedUntil-i)/1e3);return new Response(JSON.stringify({message:"Too many attempts. Please try again later.",retry_after:l}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(l)}})}if(n.count>=this.maxAttempts){n.blockedUntil=i+this.decayMinutes*6e4,n.count=0;let l=this.decayMinutes*60;return new Response(JSON.stringify({message:"Too many attempts. Please try again later.",retry_after:l}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(l)}})}}let a=await t();if(a instanceof Response&&a.status>=400&&a.status<500){let l=this.attempts.get(r)??{count:0,blockedUntil:0};if(l.count++,this.attempts.set(r,l),this.attempts.size>1e4)for(let[c,d]of this.attempts)i>d.blockedUntil+this.decayMinutes*6e4*2&&this.attempts.delete(c)}return a}}});import{z as oe}from"zod";function wi(o,e=!1){let t=new o;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 It,q,$e,Ae,De,Ci=y(()=>{"use strict";ae();It=class{controllerMiddleware=[];middleware(e,t){let s;typeof e=="function"&&e.prototype instanceof T?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 O;for(let{middleware:a}of s)r.use(a);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 oe.ZodObject?t:oe.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 a=await e.request.formData();r=Object.fromEntries(a)}else r=Object.fromEntries(e.url.searchParams);let n=s.safeParse(r);if(!n.success)throw new q(n.error);return n.data}validateQuery(e,t){let s=t instanceof oe.ZodObject?t:oe.object(t),r=Object.fromEntries(e.url.searchParams),i=s.safeParse(r);if(!i.success)throw new q(i.error);return i.data}validateParams(e,t){let r=(t instanceof oe.ZodObject?t:oe.object(t)).safeParse(e.params);if(!r.success)throw new q(r.error);return r.data}handleError(e,t){return e instanceof q?this.json({message:"Validation failed",errors:e.errors},422):e instanceof $e?this.json({message:e.message||"Not found"},404):e instanceof Ae?this.json({message:e.message||"Unauthorized"},401):e instanceof De?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)}};q=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)}}},$e=class extends Error{constructor(e="Not found"){super(e),this.name="NotFoundError"}},Ae=class extends Error{constructor(e="Unauthorized"){super(e),this.name="UnauthorizedError"}},De=class extends Error{constructor(e="Forbidden"){super(e),this.name="ForbiddenError"}}});import{randomBytes as za,createHmac as xi,timingSafeEqual as Ka}from"crypto";import{promises as U}from"fs";import{join as Le}from"path";var le,Me,H,_t,jt,Ot,ce,Ms=y(()=>{"use strict";ae();le=class o{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=o.generateId();this.id=t,this.dirty=!0;let s=Me.get(e);return s instanceof H&&s.markOldSessionId(e),Me.delete(e),t}static generateId(){return za(32).toString("hex")}},Me=new Map,H=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}),Me.set(e,this)}async destroy(e){this.sessions.delete(e),Me.delete(e)}async gc(e){let t=Date.now();for(let[s,r]of this.sessions)t>r.expiresAt&&(this.sessions.delete(s),Me.delete(s))}markOldSessionId(e){this.oldSessionIds.add(e),this.sessions.delete(e)}},_t=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(()=>(C(),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 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),a=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:a}}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])}},Pt=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(),a=this.config.prefix??"svelar",l=new i.Worker(e,async c=>{let u=c.data,m=t.resolve(u.jobClass,u.payload);m.attempts=c.attemptsMade+1,await m.handle()},{connection:n,prefix:a,concurrency:r?.concurrency??1});return l.on("failed",async(c,u)=>{let m=c?.data;if(m)try{let h=t.resolve(m.jobClass,m.payload);c.attemptsMade>=(c.opts?.attempts??3)&&(h.failed(u),await s.store({id:c.id,jobClass:m.jobClass,payload:m.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)}}),l}},Rs=class{table="svelar_failed_jobs";async getConnection(){let{Connection:e}=await Promise.resolve().then(()=>(x(),S));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}},Ts=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)}},Es=class{config={default:"sync",connections:{sync:{driver:"sync"}}};drivers=new Map;processing=!1;jobRegistry=new Ts;failedStore=new Rs;_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 St,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 ks(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 Pt){let l=await s.createWorker(r,this.jobRegistry,this.failedStore,{concurrency:e?.concurrency??1});return this.processing=!0,this._activeWorker=l,await new Promise(c=>{let u=()=>{this.processing?setTimeout(u,500):l.close().then(c).catch(c)};u()}),0}let i=e?.maxJobs??1/0,n=(e?.sleep??1)*1e3,a=0;for(this.processing=!0;this.processing&&a<i;){let l=await s.pop(r);if(!l){if(i===1/0){await new Promise(c=>setTimeout(c,n));continue}break}l.attempts++,l.job.attempts=l.attempts;try{await l.job.handle(),a++,s instanceof W&&await s.delete(l.id)}catch(c){if(l.attempts<l.maxAttempts){l.job.retrying(l.attempts);let u=l.job.retryDelay??60;s instanceof W?await s.release(l.id,u):(l.availableAt=Date.now()+u*1e3,await s.push(l))}else l.job.failed(c),await this.failedStore.store(l,c),s instanceof W&&await s.delete(l.id)}}return a}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 St;break;case"memory":s=new Ps;break;case"database":s=new W(t.table??"svelar_jobs",this.jobRegistry);break;case"redis":s=new Pt(t,this.jobRegistry);break;default:throw new Error(`Unknown queue driver: ${t.driver}`)}return this.drivers.set(e,s),s}},ks=class extends J{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()}))})}},$s=C("svelar.queue",()=>new Es)});var M,Ds=y(()=>{"use strict";x();M=class o{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 o(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 o("__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 o("__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 o("__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 o("__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 o("__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 o("__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 f.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 f.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 f.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 f.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 f.raw(t,s,this.connectionName))[0]?.aggregate??null}async min(e){let{sql:t,bindings:s}=this.buildAggregate(`MIN(${e})`);return(await f.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 f.raw(this.toSQL().sql,this.toSQL().bindings,this.connectionName)).map(s=>s[e])}async value(e){return this.selectColumns=[e],this.limitValue=1,(await f.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=f.getDriver(this.connectionName),i=Object.keys(e),n=Object.values(e),a=n.map(()=>"?").join(", "),l=s??i.filter(u=>!t.includes(u)),c;if(r==="postgres"){let u=l.map(m=>`${m} = EXCLUDED.${m}`).join(", ");c=`INSERT INTO ${this.tableName} (${i.join(", ")}) VALUES (${a}) ON CONFLICT (${t.join(", ")}) DO UPDATE SET ${u}`}else if(r==="mysql"){let u=l.map(m=>`${m} = VALUES(${m})`).join(", ");c=`INSERT INTO ${this.tableName} (${i.join(", ")}) VALUES (${a}) ON DUPLICATE KEY UPDATE ${u}`}else{let u=l.map(m=>`${m} = excluded.${m}`).join(", ");c=`INSERT INTO ${this.tableName} (${i.join(", ")}) VALUES (${a}) ON CONFLICT (${t.join(", ")}) DO UPDATE SET ${u}`}return f.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 a=t.map(l=>n[l]);s.push(...a),r.push(`(${a.map(()=>"?").join(", ")})`)}let i=`INSERT INTO ${this.tableName} (${t.join(", ")}) VALUES ${r.join(", ")}`;return f.raw(i,s,this.connectionName)}async firstOrCreate(e,t={}){for(let[n,a]of Object.entries(e))this.where(n,a);let s=await this.first();if(s)return s;let r={...e,...t},i=await new o(this.tableName,this.modelClass,this.connectionName).insertGetId(r);return new o(this.tableName,this.modelClass,this.connectionName).findOrFail(i)}async updateOrCreate(e,t){let s=new o(this.tableName,this.modelClass,this.connectionName);for(let[a,l]of Object.entries(e))s.where(a,l);let r=await s.first();if(r)return await new o(this.tableName,this.modelClass,this.connectionName).where(this.modelClass?.primaryKey??"id",r[this.modelClass?.primaryKey??"id"]).update(t),new o(this.tableName,this.modelClass,this.connectionName).findOrFail(r[this.modelClass?.primaryKey??"id"]);let i={...e,...t},n=await new o(this.tableName,this.modelClass,this.connectionName).insertGetId(i);return new o(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 o("__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(){f.getDriver(this.connectionName)==="sqlite"?(await f.raw(`DELETE FROM ${this.tableName}`,[],this.connectionName),await f.raw("DELETE FROM sqlite_sequence WHERE name = ?",[this.tableName],this.connectionName)):await f.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 f.raw(i,s,this.connectionName)}async insertGetId(e,t="id"){let s=f.getDriver(this.connectionName),r=Object.keys(e),i=Object.values(e),n=i.map(()=>"?").join(", "),a=`INSERT INTO ${this.tableName} (${r.join(", ")}) VALUES (${n})`;return s==="postgres"?(a+=` RETURNING ${t}`,(await f.raw(a,i,this.connectionName))[0]?.[t]):(await f.raw(a,i,this.connectionName),s==="sqlite"?(await f.raw("SELECT last_insert_rowid() as id",[],this.connectionName))[0]?.id:s==="mysql"?(await f.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(l=>`${l} = ?`).join(", "),{whereSQL:i,whereBindings:n}=this.buildWhere(),a=`UPDATE ${this.tableName} SET ${r}${i}`;return await f.raw(a,[...s,...n],this.connectionName),1}async delete(){let{whereSQL:e,whereBindings:t}=this.buildWhere(),s=`DELETE FROM ${this.tableName}${e}`;return await f.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 f.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 a=this.cteClauses.some(c=>c.recursive)?"WITH RECURSIVE":"WITH",l=this.cteClauses.map(c=>(t.push(...c.bindings),`${c.name} AS (${c.sql})`));e.push(`${a} ${l.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 a of this.havingClauses)a.type==="raw"?(n.push(a.raw),a.values&&t.push(...a.values)):(n.push(`${a.column} ${a.operator} ?`),t.push(a.value));e.push(`HAVING ${n.join(" AND ")}`)}if(this.orderClauses.length>0){let n=this.orderClauses.map(a=>a.__raw?a.column:`${a.column} ${a.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 o(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 l=(r.operator==="IS","null");e.push(`${i} ${r.column} ${r.operator} ${l}`)}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 a=r.values.map(()=>"?").join(", ");e.push(`${i} ${r.column} NOT IN (${a})`),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 Q,G,Y,Z,X,As=y(()=>{"use strict";x();Q=class{parentModel;relatedModel;constructor(e,t){this.parentModel=e,this.relatedModel=t}query(){return this.relatedModel.query()}},G=class extends Q{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(a=>a.getAttribute(this.localKey)),i=await this.relatedModel.query().whereIn(this.foreignKey,r).get(),n=new Map;for(let a of i)n.set(a.getAttribute(this.foreignKey),a);for(let a of t){let l=a.getAttribute(this.localKey);a.setRelation(s,n.get(l)??null)}}async create(t){let s=this.parentModel.getAttribute(this.localKey);return this.relatedModel.create({...t,[this.foreignKey]:s})}},Y=class extends Q{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(a=>a.getAttribute(this.localKey)),i=await this.relatedModel.query().whereIn(this.foreignKey,r).get(),n=new Map;for(let a of i){let l=a.getAttribute(this.foreignKey);n.has(l)||n.set(l,[]),n.get(l).push(a)}for(let a of t){let l=a.getAttribute(this.localKey);a.setRelation(s,n.get(l)??[])}}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}},Z=class extends Q{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(a=>a.getAttribute(this.foreignKey)).filter(a=>a!=null);if(r.length===0){for(let a of t)a.setRelation(s,null);return}let i=await this.relatedModel.query().whereIn(this.ownerKey,r).get(),n=new Map;for(let a of i)n.set(a.getAttribute(this.ownerKey),a);for(let a of t){let l=a.getAttribute(this.foreignKey);a.setRelation(s,n.get(l)??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}},X=class extends Q{constructor(t,s,r,i,n,a="id",l="id"){super(t,s);this.pivotTable=r;this.foreignPivotKey=i;this.relatedPivotKey=n;this.parentKey=a;this.relatedKey=l}async load(t){let s=t.getAttribute(this.parentKey),r=this.relatedModel.tableName,n=(await f.raw(`SELECT ${this.relatedPivotKey} FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ?`,[s])).map(a=>a[this.relatedPivotKey]);return n.length===0?[]:this.relatedModel.query().whereIn(this.relatedKey,n).get()}async eagerLoad(t,s){let r=t.map(m=>m.getAttribute(this.parentKey));if(r.length===0){for(let m of t)m.setRelation(s,[]);return}let i=r.map(()=>"?").join(", "),n=await f.raw(`SELECT * FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} IN (${i})`,r),a=[...new Set(n.map(m=>m[this.relatedPivotKey]))],l=a.length>0?await this.relatedModel.query().whereIn(this.relatedKey,a).get():[],c=new Map;for(let m of l)c.set(m.getAttribute(this.relatedKey),m);let u=new Map;for(let m of n){let h=m[this.foreignPivotKey],d=m[this.relatedPivotKey],b=c.get(d);b&&(u.has(h)||u.set(h,[]),u.get(h).push(b))}for(let m of t){let h=m.getAttribute(this.parentKey);m.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),a=Object.values(i),l=a.map(()=>"?").join(", ");await f.raw(`INSERT INTO ${this.pivotTable} (${n.join(", ")}) VALUES (${l})`,a)}async detach(t){let s=this.parentModel.getAttribute(this.parentKey);t?await f.raw(`DELETE FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ? AND ${this.relatedPivotKey} = ?`,[s,t]):await f.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 f.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 Xr=y(()=>{"use strict"});var Ee,Ms=y(()=>{"use strict";Ee=class{app;constructor(e){this.app=e}boot(){}}});var ei=y(()=>{"use strict";Ms();$t()});var ke,ee,$t=y(()=>{"use strict";R();Xr();ei();ke=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)}},ee=C("svelar.event",()=>new ke)});var Dt,ti=y(()=>{"use strict";Ds();As();$t();Dt=class o{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 M(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 a=new Date().toISOString();t.setAttribute(s.createdAt,a),t.setAttribute(s.updatedAt,a)}let r=t.getInsertableAttributes(),n=await new M(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 M(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 M(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 M(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 G(this,e,t,s??this.constructor.primaryKey)}hasMany(e,t,s){return new Y(this,e,t,s??this.constructor.primaryKey)}belongsTo(e,t,s){return new Z(this,e,t,s??e.primaryKey)}belongsToMany(e,t,s,r,i,n){return new X(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 o?i.toJSON():i):r instanceof o?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=o.hooks.get(t.name);s?.[e]&&await s[e](this),typeof this[e]=="function"&&await this[e]();let r=o.observers.get(t.name)??[];for(let n of r){let a=n[e];typeof a=="function"&&await a.call(n,this)}let i=t.name.toLowerCase();await ee.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=o.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 ee.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 At,si=y(()=>{"use strict";At=class{async call(e){await new e().run()}}});var F,ri,Ls=y(()=>{"use strict";R();F=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}},ri=C("svelar.container",()=>new F)});var Mt,ii=y(()=>{"use strict";Ls();Mt=class{container;providers=[];booted=!1;constructor(e){this.container=e??new F,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 T,O,Lt,te,_t,se,re,Nt,ie,ne=y(()=>{"use strict";T=class{},O=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 a=this.namedMiddleware.get(n);a&&r.push(a)}let i=t;for(let n=r.length-1;n>=0;n--){let a=r[n],l=i;typeof a.handle=="function"?i=()=>a.handle(e,l):i=()=>a(e,l)}return i()}count(){return this.middleware.length}},Lt=class extends T{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}},te=class extends T{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()}},_t=class extends T{async handle(e,t){let s=Date.now(),r=e.event.request.method,i=e.event.url.pathname,n=await t(),a=Date.now()-s,l=n instanceof Response?n.status:200;return console.log(`[${new Date().toISOString()}] ${r} ${i} \u2192 ${l} (${a}ms)`),n}},se=class extends T{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 a=this.getCookieToken(s),l=s.request.headers.get(this.headerName)??await this.getBodyToken(s);return!a||!l||!this.timingSafeEqual(a,l)?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 a=0;a<r.length;a++)n|=r[a]^i[a];return n===0}},re=class extends T{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 a=s.url.origin;return n===a||this.allowedOrigins.has(n)?t():new Response(JSON.stringify({message:"Cross-origin request blocked"}),{status:403,headers:{"Content-Type":"application/json"}})}},Nt=class extends T{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 w=s.url.pathname;if(!this.onlyPaths.some(E=>w.startsWith(E)))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),a=Math.floor(Date.now()/1e3);if(isNaN(n)||Math.abs(a-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"),m=s.request.method.toUpperCase(),h=s.url.pathname+s.url.search,d=`${i}.${m}.${h}.${c}`,b=u("sha256",this.secret).update(d).digest("hex");return r.length!==b.length||!this.timingSafeCompare(r,b)?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 a=0;a<r.length;a++)n|=r[a]^i[a];return n===0}static sign(e,t,s,r,i){let{createHmac:n}=ze("crypto"),a=i??Math.floor(Date.now()/1e3),l=`${a}.${t.toUpperCase()}.${s}.${r}`;return{signature:n("sha256",e).update(l).digest("hex"),timestamp:a}}},ie=class extends T{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 l=Math.ceil((n.blockedUntil-i)/1e3);return new Response(JSON.stringify({message:"Too many attempts. Please try again later.",retry_after:l}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(l)}})}if(n.count>=this.maxAttempts){n.blockedUntil=i+this.decayMinutes*6e4,n.count=0;let l=this.decayMinutes*60;return new Response(JSON.stringify({message:"Too many attempts. Please try again later.",retry_after:l}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(l)}})}}let a=await t();if(a instanceof Response&&a.status>=400&&a.status<500){let l=this.attempts.get(r)??{count:0,blockedUntil:0};if(l.count++,this.attempts.set(r,l),this.attempts.size>1e4)for(let[c,u]of this.attempts)i>u.blockedUntil+this.decayMinutes*6e4*2&&this.attempts.delete(c)}return a}}});import{z as ae}from"zod";function ni(o,e=!1){let t=new o;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 It,q,$e,De,Ae,ai=y(()=>{"use strict";ne();It=class{controllerMiddleware=[];middleware(e,t){let s;typeof e=="function"&&e.prototype instanceof T?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 O;for(let{middleware:a}of s)r.use(a);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 ae.ZodObject?t:ae.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 a=await e.request.formData();r=Object.fromEntries(a)}else r=Object.fromEntries(e.url.searchParams);let n=s.safeParse(r);if(!n.success)throw new q(n.error);return n.data}validateQuery(e,t){let s=t instanceof ae.ZodObject?t:ae.object(t),r=Object.fromEntries(e.url.searchParams),i=s.safeParse(r);if(!i.success)throw new q(i.error);return i.data}validateParams(e,t){let r=(t instanceof ae.ZodObject?t:ae.object(t)).safeParse(e.params);if(!r.success)throw new q(r.error);return r.data}handleError(e,t){return e instanceof q?this.json({message:"Validation failed",errors:e.errors},422):e instanceof $e?this.json({message:e.message||"Not found"},404):e instanceof De?this.json({message:e.message||"Unauthorized"},401):e instanceof Ae?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)}};q=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)}}},$e=class extends Error{constructor(e="Not found"){super(e),this.name="NotFoundError"}},De=class extends Error{constructor(e="Unauthorized"){super(e),this.name="UnauthorizedError"}},Ae=class extends Error{constructor(e="Forbidden"){super(e),this.name="ForbiddenError"}}});import{randomBytes as Ja,createHmac as oi,timingSafeEqual as Va}from"crypto";import{promises as U}from"fs";import{join as Me}from"path";var oe,Le,H,jt,Ot,qt,le,_s=y(()=>{"use strict";ne();oe=class o{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=o.generateId();this.id=t,this.dirty=!0;let s=Le.get(e);return s instanceof H&&s.markOldSessionId(e),Le.delete(e),t}static generateId(){return Ja(32).toString("hex")}},Le=new Map,H=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}),Le.set(e,this)}async destroy(e){this.sessions.delete(e),Le.delete(e)}async gc(e){let t=Date.now();for(let[s,r]of this.sessions)t>r.expiresAt&&(this.sessions.delete(s),Le.delete(s))}markOldSessionId(e){this.oldSessionIds.add(e),this.sessions.delete(e)}},jt=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(()=>(x(),S));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,17 +51,17 @@ var wn=Object.defineProperty;var ze=(o=>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(()=>(C(),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(()=>(C(),P)),i=JSON.stringify(t),n=new Date(Date.now()+s*1e3).toISOString(),a=r.getDriver(this.connectionName);a==="sqlite"?await r.raw(`INSERT INTO ${this.tableName} (id, payload, expires_at) VALUES (?, ?, ?)
54
+ ) ENGINE=InnoDB`,[],this.connectionName);break}this.tableEnsured=!0}catch{}}async read(e){await this.ensureTable();let{Connection:t}=await Promise.resolve().then(()=>(x(),S)),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(()=>(x(),S)),i=JSON.stringify(t),n=new Date(Date.now()+s*1e3).toISOString(),a=r.getDriver(this.connectionName);a==="sqlite"?await r.raw(`INSERT INTO ${this.tableName} (id, payload, expires_at) VALUES (?, ?, ?)
55
55
  ON CONFLICT(id) DO UPDATE SET payload = excluded.payload, expires_at = excluded.expires_at`,[e,i,n],this.connectionName):a==="postgres"?await r.raw(`INSERT INTO ${this.tableName} (id, payload, expires_at) VALUES ($1, $2, $3)
56
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(()=>(C(),P));await t.raw(`DELETE FROM ${this.tableName} WHERE id = ?`,[e],this.connectionName)}async gc(e){let{Connection:t}=await Promise.resolve().then(()=>(C(),P));await t.raw(`DELETE FROM ${this.tableName} WHERE expires_at < ?`,[new Date().toISOString()],this.connectionName)}},jt=class{dir;constructor(e){this.dir=e??Le(process.cwd(),"storage","sessions")}filePath(e){let t=e.replace(/[^a-zA-Z0-9_-]/g,"");return Le(this.dir,`${t}.json`)}async ensureDir(){await U.mkdir(this.dir,{recursive:!0})}async read(e){try{let t=await U.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 U.writeFile(this.filePath(e),JSON.stringify(r),"utf-8")}async destroy(e){try{await U.unlink(this.filePath(e))}catch{}}async gc(e){try{let t=await U.readdir(this.dir),s=new Date;for(let r of t)if(r.endsWith(".json"))try{let i=await U.readFile(Le(this.dir,r),"utf-8"),n=JSON.parse(i);new Date(n.expiresAt)<s&&await U.unlink(Le(this.dir,r))}catch{await U.unlink(Le(this.dir,r)).catch(()=>{})}}catch{}}},Ot=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){}},ce=class extends T{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 l=this.verifySignedId(r);l?(i=await this.config.store.read(l),r=l):r=null}r||(r=le.generateId());let n=new le(r,i??{});e.event.locals.session=n,e.locals.session=n;let a=await t();if(n.isDirty()&&await this.config.store.write(n.id,n.toPersist(),this.config.lifetime),a instanceof Response){let l=this.signId(n.id),c=this.buildCookieString(l);a.headers.append("Set-Cookie",c)}return a}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=xi("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=xi("sha256",this.config.secret).update(s).digest("base64url");if(r.length!==i.length)return null;let n=Buffer.from(r),a=Buffer.from(i);if(n.length!==a.length)return null;try{if(Ka(n,a))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 Ne={};E(Ne,{Hash:()=>_s});import{randomBytes as Ns,scrypt as Pi,timingSafeEqual as Wa}from"crypto";async function Ja(o,e=16384){let t=Ns(16),s=64,r=await new Promise((i,n)=>{Pi(o,t,s,{N:e,r:8,p:1},(a,l)=>{a?n(a):i(l)})});return`$scrypt$N=${e}$${t.toString("base64")}$${r.toString("base64")}`}async function Va(o,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,a=await new Promise((l,c)=>{Pi(o,r,n,{N:s,r:8,p:1},(d,p)=>{d?c(d):l(p)})});return Wa(a,i)}var Is,_s,de=y(()=>{"use strict";S();Is=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 Ja(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 Va(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 Ns(Math.ceil(e/2)).toString("hex").slice(0,e)}randomToken(e=32){return Ns(e).toString("base64url")}},_s=w("svelar.hash",()=>new Is)});var Ri={};E(Ri,{EmailTemplates:()=>Qa});import{randomUUID as N}from"crypto";var js,Qa,Si=y(()=>{"use strict";S();js=class{config={driver:"memory"};templates=new Map;constructor(){this.registerDefaults()}configure(e){this.config=e}async register(e){let t={...e,id:N(),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(()=>(C(),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:N(),name:"welcome",subject:"Welcome to {{appName}}, {{user.name}}!",html:`
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(()=>(x(),S));await t.raw(`DELETE FROM ${this.tableName} WHERE id = ?`,[e],this.connectionName)}async gc(e){let{Connection:t}=await Promise.resolve().then(()=>(x(),S));await t.raw(`DELETE FROM ${this.tableName} WHERE expires_at < ?`,[new Date().toISOString()],this.connectionName)}},Ot=class{dir;constructor(e){this.dir=e??Me(process.cwd(),"storage","sessions")}filePath(e){let t=e.replace(/[^a-zA-Z0-9_-]/g,"");return Me(this.dir,`${t}.json`)}async ensureDir(){await U.mkdir(this.dir,{recursive:!0})}async read(e){try{let t=await U.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 U.writeFile(this.filePath(e),JSON.stringify(r),"utf-8")}async destroy(e){try{await U.unlink(this.filePath(e))}catch{}}async gc(e){try{let t=await U.readdir(this.dir),s=new Date;for(let r of t)if(r.endsWith(".json"))try{let i=await U.readFile(Me(this.dir,r),"utf-8"),n=JSON.parse(i);new Date(n.expiresAt)<s&&await U.unlink(Me(this.dir,r))}catch{await U.unlink(Me(this.dir,r)).catch(()=>{})}}catch{}}},qt=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){}},le=class extends T{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 l=this.verifySignedId(r);l?(i=await this.config.store.read(l),r=l):r=null}r||(r=oe.generateId());let n=new oe(r,i??{});e.event.locals.session=n,e.locals.session=n;let a=await t();if(n.isDirty()&&await this.config.store.write(n.id,n.toPersist(),this.config.lifetime),a instanceof Response){let l=this.signId(n.id),c=this.buildCookieString(l);a.headers.append("Set-Cookie",c)}return a}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=oi("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=oi("sha256",this.config.secret).update(s).digest("base64url");if(r.length!==i.length)return null;let n=Buffer.from(r),a=Buffer.from(i);if(n.length!==a.length)return null;try{if(Va(n,a))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 _e={};k(_e,{Hash:()=>js});import{randomBytes as Ns,scrypt as li,timingSafeEqual as Qa}from"crypto";async function Ga(o,e=16384){let t=Ns(16),s=64,r=await new Promise((i,n)=>{li(o,t,s,{N:e,r:8,p:1},(a,l)=>{a?n(a):i(l)})});return`$scrypt$N=${e}$${t.toString("base64")}$${r.toString("base64")}`}async function Ya(o,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,a=await new Promise((l,c)=>{li(o,r,n,{N:s,r:8,p:1},(u,m)=>{u?c(u):l(m)})});return Qa(a,i)}var Is,js,ce=y(()=>{"use strict";R();Is=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 Ya(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 Ns(Math.ceil(e/2)).toString("hex").slice(0,e)}randomToken(e=32){return Ns(e).toString("base64url")}},js=C("svelar.hash",()=>new Is)});var ci={};k(ci,{EmailTemplates:()=>Za});import{randomUUID as _}from"crypto";var Os,Za,di=y(()=>{"use strict";R();Os=class{config={driver:"memory"};templates=new Map;constructor(){this.registerDefaults()}configure(e){this.config=e}async register(e){let t={...e,id:_(),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(()=>(x(),S));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:_(),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>
61
61
  <p><a href="{{confirmUrl}}">Confirm your email address</a></p>
62
62
  `,text:`Welcome, {{user.name}}!
63
63
 
64
- Confirm your email: {{confirmUrl}}`,variables:["appName","user.name","user.email","confirmUrl"],category:"auth",active:!0,createdAt:Date.now(),updatedAt:Date.now()}),this.templates.set("password-reset",{id:N(),name:"password-reset",subject:"Reset your {{appName}} password",html:`
64
+ Confirm your email: {{confirmUrl}}`,variables:["appName","user.name","user.email","confirmUrl"],category:"auth",active:!0,createdAt:Date.now(),updatedAt:Date.now()}),this.templates.set("password-reset",{id:_(),name:"password-reset",subject:"Reset your {{appName}} password",html:`
65
65
  <h1>Password Reset</h1>
66
66
  <p>Hi {{user.name}},</p>
67
67
  <p>Click the link below to reset your password. This link expires in 1 hour.</p>
@@ -69,18 +69,18 @@ Confirm your email: {{confirmUrl}}`,variables:["appName","user.name","user.email
69
69
  <p>If you didn't request this, you can ignore this email.</p>
70
70
  `,text:`Reset your password: {{resetUrl}}
71
71
 
72
- This link expires in 1 hour.`,variables:["appName","user.name","resetUrl"],category:"auth",active:!0,createdAt:Date.now(),updatedAt:Date.now()}),this.templates.set("email-verification",{id:N(),name:"email-verification",subject:"Verify your email address",html:`
72
+ This link expires in 1 hour.`,variables:["appName","user.name","resetUrl"],category:"auth",active:!0,createdAt:Date.now(),updatedAt:Date.now()}),this.templates.set("email-verification",{id:_(),name:"email-verification",subject:"Verify your email address",html:`
73
73
  <h1>Verify Your Email</h1>
74
74
  <p>Hi {{user.name}},</p>
75
75
  <p><a href="{{verifyUrl}}">Click here to verify your email address</a></p>
76
76
  <p>This link expires in 24 hours.</p>
77
- `,text:"Verify your email: {{verifyUrl}}",variables:["user.name","verifyUrl"],category:"auth",active:!0,createdAt:Date.now(),updatedAt:Date.now()}),this.templates.set("team-invitation",{id:N(),name:"team-invitation",subject:"{{inviter.name}} invited you to join {{team.name}}",html:`
77
+ `,text:"Verify your email: {{verifyUrl}}",variables:["user.name","verifyUrl"],category:"auth",active:!0,createdAt:Date.now(),updatedAt:Date.now()}),this.templates.set("team-invitation",{id:_(),name:"team-invitation",subject:"{{inviter.name}} invited you to join {{team.name}}",html:`
78
78
  <h1>Team Invitation</h1>
79
79
  <p>Hi {{user.name}},</p>
80
80
  <p><strong>{{inviter.name}}</strong> has invited you to join the team <strong>{{team.name}}</strong>.</p>
81
81
  <p><a href="{{acceptUrl}}">Accept Invitation</a></p>
82
82
  <p>This invitation expires in 3 days.</p>
83
- `,text:"Accept: {{acceptUrl}}",variables:["user.name","inviter.name","team.name","acceptUrl"],category:"notification",active:!0,createdAt:Date.now(),updatedAt:Date.now()}),this.templates.set("invoice",{id:N(),name:"invoice",subject:"Invoice #{{invoice.number}} from {{appName}}",html:`
83
+ `,text:"Accept: {{acceptUrl}}",variables:["user.name","inviter.name","team.name","acceptUrl"],category:"notification",active:!0,createdAt:Date.now(),updatedAt:Date.now()}),this.templates.set("invoice",{id:_(),name:"invoice",subject:"Invoice #{{invoice.number}} from {{appName}}",html:`
84
84
  <h1>Invoice #{{invoice.number}}</h1>
85
85
  <p>Hi {{customer.name}},</p>
86
86
  <p>Thank you for your purchase!</p>
@@ -88,14 +88,14 @@ This link expires in 1 hour.`,variables:["appName","user.name","resetUrl"],categ
88
88
  <p><strong>Date:</strong> {{invoice.date}}</p>
89
89
  <p><a href="{{invoiceUrl}}">View Invoice</a></p>
90
90
  `,text:`Invoice #{{invoice.number}}
91
- Amount: {{invoice.amount}}`,variables:["appName","customer.name","invoice.number","invoice.amount","invoice.date","invoiceUrl"],category:"billing",active:!0,createdAt:Date.now(),updatedAt:Date.now()}),this.templates.set("subscription-confirmation",{id:N(),name:"subscription-confirmation",subject:"Subscription Confirmation",html:`
91
+ Amount: {{invoice.amount}}`,variables:["appName","customer.name","invoice.number","invoice.amount","invoice.date","invoiceUrl"],category:"billing",active:!0,createdAt:Date.now(),updatedAt:Date.now()}),this.templates.set("subscription-confirmation",{id:_(),name:"subscription-confirmation",subject:"Subscription Confirmation",html:`
92
92
  <h1>Subscription Confirmed</h1>
93
93
  <p>Hi {{user.name}},</p>
94
94
  <p>Your {{plan.name}} plan is now active.</p>
95
95
  <p><strong>Price:</strong> {{plan.price}} / {{plan.interval}}</p>
96
96
  <p>Your next billing date is {{nextBillingDate}}.</p>
97
97
  `,text:`Your {{plan.name}} plan is active.
98
- Next billing: {{nextBillingDate}}`,variables:["user.name","plan.name","plan.price","plan.interval","nextBillingDate"],category:"billing",active:!0,createdAt:Date.now(),updatedAt:Date.now()}),this.templates.set("otp-code",{id:N(),name:"otp-code",subject:"Your {{appName}} verification code: {{code}}",html:`
98
+ Next billing: {{nextBillingDate}}`,variables:["user.name","plan.name","plan.price","plan.interval","nextBillingDate"],category:"billing",active:!0,createdAt:Date.now(),updatedAt:Date.now()}),this.templates.set("otp-code",{id:_(),name:"otp-code",subject:"Your {{appName}} verification code: {{code}}",html:`
99
99
  <h1>Your Verification Code</h1>
100
100
  <p>Hi {{user.name}},</p>
101
101
  <p>Your one-time verification code is:</p>
@@ -104,27 +104,27 @@ Next billing: {{nextBillingDate}}`,variables:["user.name","plan.name","plan.pric
104
104
  <p>If you didn't request this code, you can safely ignore this email.</p>
105
105
  `,text:`Your verification code: {{code}}
106
106
 
107
- This code expires in {{expiresMinutes}} minutes.`,variables:["appName","user.name","code","expiresMinutes","purpose"],category:"auth",active:!0,createdAt:Date.now(),updatedAt:Date.now()}),this.templates.set("subscription-canceled",{id:N(),name:"subscription-canceled",subject:"Your subscription has been canceled",html:`
107
+ This code expires in {{expiresMinutes}} minutes.`,variables:["appName","user.name","code","expiresMinutes","purpose"],category:"auth",active:!0,createdAt:Date.now(),updatedAt:Date.now()}),this.templates.set("subscription-canceled",{id:_(),name:"subscription-canceled",subject:"Your subscription has been canceled",html:`
108
108
  <h1>Subscription Canceled</h1>
109
109
  <p>Hi {{user.name}},</p>
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 a=this.getNestedValue(t,i);return Array.isArray(a)?a.map((l,c)=>{let d={...t,this:l,$index:c};return this.interpolate(n,d)}).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)}},Qa=w("svelar.emailTemplates",()=>new js)});var Ks={};E(Ks,{Mailable:()=>Ie,Mailer:()=>zs});function Hs(o){return typeof o=="string"?o:`${o.name} <${o.address}>`}function A(o){return o?Array.isArray(o)?o:[o]:[]}function Ti(o){return Buffer.isBuffer(o)?o.toString("base64"):Buffer.from(o).toString("base64")}var qt,Os,qs,Us,Fs,Ie,Bs,zs,Ut=y(()=>{"use strict";S();qt=class{async send(e){let t=A(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:[]}}},Os=class{async send(e){return{accepted:A(e.to),rejected:[]}}},qs=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?Hs(e.from):void 0,to:A(e.to).join(", "),cc:A(e.cc).join(", ")||void 0,bcc:A(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}}},Us=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=A(e.to),r=A(e.cc),i=A(e.bcc),n={From:e.from?Hs(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:Ti(c.content),ContentType:c.contentType||"application/octet-stream"})));let a=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(!a.ok){let c=await a.json().catch(()=>({Message:a.statusText}));throw new Error(`Postmark error ${a.status}: ${c.Message||JSON.stringify(c)}`)}let l=await a.json();return{accepted:s,rejected:[],messageId:l.MessageID}}},Fs=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=A(e.to),r=A(e.cc),i=A(e.bcc),n={from:e.from?Hs(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,d])=>({name:c,value:d}))),e.attachments?.length&&(n.attachments=e.attachments.map(c=>({filename:c.filename,content:Ti(c.content),content_type:c.contentType||"application/octet-stream"})));let a=await fetch("https://api.resend.com/emails",{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify(n)});if(!a.ok){let c=await a.json().catch(()=>({message:a.statusText}));throw new Error(`Resend error ${a.status}: ${c.message||JSON.stringify(c)}`)}let l=await a.json();return{accepted:s,rejected:[],messageId:l.id}}},Ie=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}},Bs=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 qt;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 qs(s);break;case"postmark":r=new Us(s);break;case"resend":r=new Fs(s);break;case"log":r=new qt;break;case"null":r=new Os;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}},zs=w("svelar.mail",()=>new Bs)});import{createHmac as ue,randomBytes as _e}from"crypto";function Ei(o){return(typeof o=="string"?Buffer.from(o):o).toString("base64url")}function ki(o){return Buffer.from(o,"base64url").toString("utf-8")}function $i(o,e,t,s){return ue(s==="HS384"?"sha384":s==="HS512"?"sha512":"sha256",t).update(`${o}.${e}`).digest("base64url")}function Ws(o,e,t="HS256"){let s=Ei(JSON.stringify({alg:t,typ:"JWT"})),r=Ei(JSON.stringify(o)),i=$i(s,r,e,t);return`${s}.${r}.${i}`}function Js(o,e){let t=o.split(".");if(t.length!==3)return null;let[s,r,i]=t,n;try{n=JSON.parse(ki(s))}catch{return null}let a=$i(s,r,e,n.alg);if(i!==a)return null;try{let l=JSON.parse(ki(r));return l.exp&&Date.now()/1e3>l.exp?null:l}catch{return null}}var Ft,me,Bt,Vs=y(()=>{"use strict";ae();Ft=class{config;currentUser=null;constructor(e){this.config={identifierColumn:"email",passwordColumn:"password",...e}}async attempt(e,t){let{Hash:s}=await Promise.resolve().then(()=>(de(),Ne)),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 a=n.getAttribute(this.config.passwordColumn);return await s.verify(i,a)?(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(()=>(de(),Ne));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=Ws(i,t.secret,t.algorithm),a=new Date((r+s)*1e3),l={user:e,token:n,expiresAt:a};if(t.refreshTokens){let c=t.refreshExpiresIn??604800,d=_e(32).toString("base64url"),p=ue("sha256",t.secret).update(d).digest("hex"),h=new Date((r+c)*1e3),{Connection:u}=await Promise.resolve().then(()=>(C(),P)),v=t.refreshTable??"refresh_tokens";await u.raw(`INSERT INTO ${v} (user_id, token, expires_at, created_at) VALUES (?, ?, ?, ?)`,[e.getAttribute("id"),p,h.toISOString(),new Date().toISOString()]),l.refreshToken=d,l.refreshExpiresAt=h}return l}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=ue("sha256",t.secret).update(e).digest("hex"),{Connection:r}=await Promise.resolve().then(()=>(C(),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 a=n[0];if(a.revoked_at||new Date(a.expires_at)<new Date)return null;await r.raw(`UPDATE ${i} SET revoked_at = ? WHERE token = ?`,[new Date().toISOString(),s]);let l=await this.config.model.find(a.user_id);return l?(this.currentUser=l,this.issueTokenPair(l)):null}async revokeRefreshTokens(e){if(!this.config.jwt?.refreshTokens)return;let{Connection:t}=await Promise.resolve().then(()=>(C(),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=Js(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(()=>(de(),Ne));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=_e(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=ue("sha256",r).update(s).digest("hex"),{Connection:n}=await Promise.resolve().then(()=>(C(),P)),a=this.config.token?.table??"personal_access_tokens";return await n.raw(`INSERT INTO ${a} (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(()=>(C(),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=ue("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 a=await this.config.model.find(n[0].user_id);return a&&(this.currentUser=a),a}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(()=>(C(),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,i,n)=>this.getNestedValue(t,i)?n:""),s=s.replace(/\{\{#each\s+(\w+(?:\.\w+)*)\}\}([\s\S]*?)\{\{\/each\}\}/g,(r,i,n)=>{let a=this.getNestedValue(t,i);return Array.isArray(a)?a.map((l,c)=>{let u={...t,this:l,$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=C("svelar.emailTemplates",()=>new Os)});var Ws={};k(Ws,{Mailable:()=>Ne,Mailer:()=>Ks});function zs(o){return typeof o=="string"?o:`${o.name} <${o.address}>`}function D(o){return o?Array.isArray(o)?o:[o]:[]}function ui(o){return Buffer.isBuffer(o)?o.toString("base64"):Buffer.from(o).toString("base64")}var Ut,qs,Us,Bs,Fs,Ne,Hs,Ks,Bt=y(()=>{"use strict";R();Ut=class{async send(e){let t=D(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:[]}}},qs=class{async send(e){return{accepted:D(e.to),rejected:[]}}},Us=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?zs(e.from):void 0,to:D(e.to).join(", "),cc:D(e.cc).join(", ")||void 0,bcc:D(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}}},Bs=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=D(e.to),r=D(e.cc),i=D(e.bcc),n={From:e.from?zs(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:ui(c.content),ContentType:c.contentType||"application/octet-stream"})));let a=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(!a.ok){let c=await a.json().catch(()=>({Message:a.statusText}));throw new Error(`Postmark error ${a.status}: ${c.Message||JSON.stringify(c)}`)}let l=await a.json();return{accepted:s,rejected:[],messageId:l.MessageID}}},Fs=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=D(e.to),r=D(e.cc),i=D(e.bcc),n={from:e.from?zs(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:ui(c.content),content_type:c.contentType||"application/octet-stream"})));let a=await fetch("https://api.resend.com/emails",{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify(n)});if(!a.ok){let c=await a.json().catch(()=>({message:a.statusText}));throw new Error(`Resend error ${a.status}: ${c.message||JSON.stringify(c)}`)}let l=await a.json();return{accepted:s,rejected:[],messageId:l.id}}},Ne=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}},Hs=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 Ut;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 Us(s);break;case"postmark":r=new Bs(s);break;case"resend":r=new Fs(s);break;case"log":r=new Ut;break;case"null":r=new qs;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}},Ks=C("svelar.mail",()=>new Hs)});import{createHmac as de,randomBytes as Ie}from"crypto";function mi(o){return(typeof o=="string"?Buffer.from(o):o).toString("base64url")}function pi(o){return Buffer.from(o,"base64url").toString("utf-8")}function hi(o,e,t,s){return de(s==="HS384"?"sha384":s==="HS512"?"sha512":"sha256",t).update(`${o}.${e}`).digest("base64url")}function Js(o,e,t="HS256"){let s=mi(JSON.stringify({alg:t,typ:"JWT"})),r=mi(JSON.stringify(o)),i=hi(s,r,e,t);return`${s}.${r}.${i}`}function Vs(o,e){let t=o.split(".");if(t.length!==3)return null;let[s,r,i]=t,n;try{n=JSON.parse(pi(s))}catch{return null}let a=hi(s,r,e,n.alg);if(i!==a)return null;try{let l=JSON.parse(pi(r));return l.exp&&Date.now()/1e3>l.exp?null:l}catch{return null}}var Ft,ue,Ht,Qs=y(()=>{"use strict";ne();Ft=class{config;currentUser=null;constructor(e){this.config={identifierColumn:"email",passwordColumn:"password",...e}}async attempt(e,t){let{Hash:s}=await Promise.resolve().then(()=>(ce(),_e)),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 a=n.getAttribute(this.config.passwordColumn);return await s.verify(i,a)?(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(()=>(ce(),_e));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=Js(i,t.secret,t.algorithm),a=new Date((r+s)*1e3),l={user:e,token:n,expiresAt:a};if(t.refreshTokens){let c=t.refreshExpiresIn??604800,u=Ie(32).toString("base64url"),m=de("sha256",t.secret).update(u).digest("hex"),h=new Date((r+c)*1e3),{Connection:d}=await Promise.resolve().then(()=>(x(),S)),b=t.refreshTable??"refresh_tokens";await d.raw(`INSERT INTO ${b} (user_id, token, expires_at, created_at) VALUES (?, ?, ?, ?)`,[e.getAttribute("id"),m,h.toISOString(),new Date().toISOString()]),l.refreshToken=u,l.refreshExpiresAt=h}return l}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=de("sha256",t.secret).update(e).digest("hex"),{Connection:r}=await Promise.resolve().then(()=>(x(),S)),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 a=n[0];if(a.revoked_at||new Date(a.expires_at)<new Date)return null;await r.raw(`UPDATE ${i} SET revoked_at = ? WHERE token = ?`,[new Date().toISOString(),s]);let l=await this.config.model.find(a.user_id);return l?(this.currentUser=l,this.issueTokenPair(l)):null}async revokeRefreshTokens(e){if(!this.config.jwt?.refreshTokens)return;let{Connection:t}=await Promise.resolve().then(()=>(x(),S)),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=Vs(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(()=>(ce(),_e));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=Ie(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=de("sha256",r).update(s).digest("hex"),{Connection:n}=await Promise.resolve().then(()=>(x(),S)),a=this.config.token?.table??"personal_access_tokens";return await n.raw(`INSERT INTO ${a} (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(()=>(x(),S)),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=de("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 a=await this.config.model.find(n[0].user_id);return a&&(this.currentUser=a),a}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(()=>(x(),S)),r=this.config.passwordResets?.table??"password_resets",i=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=_e(32).toString("base64url"),a=this.hashToken(n),l=new Date(Date.now()+i*1e3).toISOString();await s.raw(`INSERT INTO ${r} (email, token, expires_at, created_at) VALUES (?, ?, ?, ?)`,[e,a,l,new Date().toISOString()]);let c=this.config.appUrl??process.env.APP_URL??"http://localhost:5173",d=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:d,"user.name":t.getAttribute("name")??e,resetUrl:p}),!0}async resetPassword(e,t,s){let{Connection:r}=await Promise.resolve().then(()=>(C(),P)),{Hash:i}=await Promise.resolve().then(()=>(de(),Ne)),n=this.config.passwordResets?.table??"password_resets",a=this.hashToken(e),l=await r.raw(`SELECT email, expires_at FROM ${n} WHERE token = ? AND email = ?`,[a,t]);if(l.length===0)return!1;let c=l[0];if(new Date(c.expires_at)<new Date)return await r.raw(`DELETE FROM ${n} WHERE email = ?`,[t]),!1;let d=await this.config.model.where(this.config.identifierColumn,t).first();if(!d)return!1;let p=await i.make(s);return await this.config.model.where("id",d.getAttribute("id")).update({[this.config.passwordColumn]:p}),await r.raw(`DELETE FROM ${n} WHERE email = ?`,[t]),await this.revokeRefreshTokens(d.getAttribute("id")),!0}async sendVerificationEmail(e){let{Connection:t}=await Promise.resolve().then(()=>(C(),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=Ie(32).toString("base64url"),a=this.hashToken(n),l=new Date(Date.now()+i*1e3).toISOString();await s.raw(`INSERT INTO ${r} (email, token, expires_at, created_at) VALUES (?, ?, ?, ?)`,[e,a,l,new Date().toISOString()]);let c=this.config.appUrl??process.env.APP_URL??"http://localhost:5173",u=this.config.appName??process.env.APP_NAME??"Svelar",m=`${c}/reset-password?token=${n}&email=${encodeURIComponent(e)}`;return await this.sendAuthEmail("password-reset",e,{appName:u,"user.name":t.getAttribute("name")??e,resetUrl:m}),!0}async resetPassword(e,t,s){let{Connection:r}=await Promise.resolve().then(()=>(x(),S)),{Hash:i}=await Promise.resolve().then(()=>(ce(),_e)),n=this.config.passwordResets?.table??"password_resets",a=this.hashToken(e),l=await r.raw(`SELECT email, expires_at FROM ${n} WHERE token = ? AND email = ?`,[a,t]);if(l.length===0)return!1;let c=l[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 m=await i.make(s);return await this.config.model.where("id",u.getAttribute("id")).update({[this.config.passwordColumn]:m}),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(()=>(x(),S)),s=this.config.emailVerification?.table??"email_verifications",r=this.config.emailVerification?.expiresIn??86400,i=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=_e(32).toString("base64url"),a=this.hashToken(n),l=new Date(Date.now()+r*1e3).toISOString();await t.raw(`INSERT INTO ${s} (user_id, token, expires_at, created_at) VALUES (?, ?, ?, ?)`,[e.getAttribute("id"),a,l,new Date().toISOString()]);let d=`${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:d})}async verifyEmail(e,t){let{Connection:s}=await Promise.resolve().then(()=>(C(),P)),r=this.config.emailVerification?.table??"email_verifications",i=this.config.emailVerification?.verifiedColumn??"email_verified_at",n=this.hashToken(e),a=await s.raw(`SELECT user_id, expires_at FROM ${r} WHERE token = ? AND user_id = ?`,[n,t]);return a.length===0?!1:new Date(a[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(()=>(C(),P)),i=this.config.otp?.table??"otp_codes",n=this.config.otp?.expiresIn??600,a=this.config.otp?.length??6;await this.ensureTable(i,`
127
+ `),await t.raw(`DELETE FROM ${s} WHERE user_id = ?`,[e.getAttribute("id")]);let n=Ie(32).toString("base64url"),a=this.hashToken(n),l=new Date(Date.now()+r*1e3).toISOString();await t.raw(`INSERT INTO ${s} (user_id, token, expires_at, created_at) VALUES (?, ?, ?, ?)`,[e.getAttribute("id"),a,l,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(()=>(x(),S)),r=this.config.emailVerification?.table??"email_verifications",i=this.config.emailVerification?.verifiedColumn??"email_verified_at",n=this.hashToken(e),a=await s.raw(`SELECT user_id, expires_at FROM ${r} WHERE token = ? AND user_id = ?`,[n,t]);return a.length===0?!1:new Date(a[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(()=>(x(),S)),i=this.config.otp?.table??"otp_codes",n=this.config.otp?.expiresIn??600,a=this.config.otp?.length??6;await this.ensureTable(i,`
128
128
  CREATE TABLE IF NOT EXISTS ${i} (
129
129
  email TEXT NOT NULL,
130
130
  code TEXT NOT NULL,
@@ -133,12 +133,12 @@ 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 l=this.generateOtpCode(a),c=this.hashToken(l),d=new Date(Date.now()+n*1e3).toISOString();await r.raw(`INSERT INTO ${i} (email, code, purpose, expires_at, created_at) VALUES (?, ?, ?, ?, ?)`,[e,c,t,d,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:l,purpose:t,expiresMinutes:String(h)}),!0}async verifyOtp(e,t,s="login"){let{Connection:r}=await Promise.resolve().then(()=>(C(),P)),i=this.config.otp?.table??"otp_codes",n=this.hashToken(t),a=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(a.length===0)return null;if(new Date(a[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 l=await this.config.model.where(this.config.identifierColumn,e).first();return l&&(this.currentUser=l),l}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(()=>(C(),P)),t=new Date().toISOString(),s=0,r=0,i=0,n=this.config.passwordResets?.table??"password_resets",a=this.config.emailVerification?.table??"email_verifications",l=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 ${a} WHERE expires_at < ?`,[t]))?.changes??0}catch{}try{i=(await e.raw(`DELETE FROM ${l} 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 ue("sha256",t).update(e).digest("hex")}generateOtpCode(e){let t=_e(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(()=>(C(),P));await s.raw(t),this.tablesEnsured.add(e)}async sendAuthEmail(e,t,s){try{let{EmailTemplates:r}=await Promise.resolve().then(()=>(Si(),Ri)),{Mailer:i}=await Promise.resolve().then(()=>(Ut(),Ks)),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)}}},me=class extends T{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()}},Bt=class extends T{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 Ga,mkdir as Ya}from"fs/promises";import{dirname as Za}from"path";function M(){return new Date().toISOString()}var Ht,je,Qs,Gs,Ys,Zs,Xs,zt,er=y(()=>{"use strict";S();Ht={debug:0,info:1,warn:2,error:3,fatal:4},je=class{minLevel;format;constructor(e){this.minLevel=e.level??"debug",this.format=e.format??"text"}write(e){if(Ht[e.level]<Ht[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)}`:"",a=e.level==="error"||e.level==="fatal"?"error":"log";console[a](`${r}[${e.timestamp}] ${i}${s} ${e.message}${n}`)}},Qs=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(Ht[e.level]<Ht[this.minLevel])return;this.initialized||(await Ya(Za(this.path),{recursive:!0}),this.initialized=!0);let t;if(this.format==="json")t=JSON.stringify(e)+`
136
+ `),await r.raw(`DELETE FROM ${i} WHERE email = ? AND purpose = ?`,[e,t]);let l=this.generateOtpCode(a),c=this.hashToken(l),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 m=this.config.appName??process.env.APP_NAME??"Svelar",h=Math.ceil(n/60);return await this.sendAuthEmail("otp-code",e,{appName:m,"user.name":s.getAttribute("name")??e,code:l,purpose:t,expiresMinutes:String(h)}),!0}async verifyOtp(e,t,s="login"){let{Connection:r}=await Promise.resolve().then(()=>(x(),S)),i=this.config.otp?.table??"otp_codes",n=this.hashToken(t),a=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(a.length===0)return null;if(new Date(a[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 l=await this.config.model.where(this.config.identifierColumn,e).first();return l&&(this.currentUser=l),l}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(()=>(x(),S)),t=new Date().toISOString(),s=0,r=0,i=0,n=this.config.passwordResets?.table??"password_resets",a=this.config.emailVerification?.table??"email_verifications",l=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 ${a} WHERE expires_at < ?`,[t]))?.changes??0}catch{}try{i=(await e.raw(`DELETE FROM ${l} 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 de("sha256",t).update(e).digest("hex")}generateOtpCode(e){let t=Ie(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(()=>(x(),S));await s.raw(t),this.tablesEnsured.add(e)}async sendAuthEmail(e,t,s){try{let{EmailTemplates:r}=await Promise.resolve().then(()=>(di(),ci)),{Mailer:i}=await Promise.resolve().then(()=>(Bt(),Ws)),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)}}},ue=class extends T{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()}},Ht=class extends T{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 eo}from"fs/promises";import{dirname as to}from"path";function L(){return new Date().toISOString()}var zt,je,Gs,Ys,Zs,Xs,er,Kt,tr=y(()=>{"use strict";R();zt={debug:0,info:1,warn:2,error:3,fatal:4},je=class{minLevel;format;constructor(e){this.minLevel=e.level??"debug",this.format=e.format??"text"}write(e){if(zt[e.level]<zt[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)}`:"",a=e.level==="error"||e.level==="fatal"?"error":"log";console[a](`${r}[${e.timestamp}] ${i}${s} ${e.message}${n}`)}},Gs=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(zt[e.level]<zt[this.minLevel])return;this.initialized||(await eo(to(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 Ga(this.path,t)}},Gs=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)}}},Ys=class{minLevel="debug";write(){}},Zs=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 Xs(this.resolveChannel(e))}debug(e,t={}){this.writeToDefault({level:"debug",message:e,context:t,timestamp:M()})}info(e,t={}){this.writeToDefault({level:"info",message:e,context:t,timestamp:M()})}warn(e,t={}){this.writeToDefault({level:"warn",message:e,context:t,timestamp:M()})}error(e,t={}){this.writeToDefault({level:"error",message:e,context:t,timestamp:M()})}fatal(e,t={}){this.writeToDefault({level:"fatal",message:e,context:t,timestamp:M()})}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 je({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 je(e);case"file":return new Qs(e);case"stack":return new Gs(e,t=>this.resolveChannel(t));case"null":return new Ys;default:return new je(e)}}},Xs=class{constructor(e){this.channel=e}debug(e,t={}){this.channel.write({level:"debug",message:e,context:t,timestamp:M()})}info(e,t={}){this.channel.write({level:"info",message:e,context:t,timestamp:M()})}warn(e,t={}){this.channel.write({level:"warn",message:e,context:t,timestamp:M()})}error(e,t={}){this.channel.write({level:"error",message:e,context:t,timestamp:M()})}fatal(e,t={}){this.channel.write({level:"fatal",message:e,context:t,timestamp:M()})}};zt=w("svelar.log",()=>new Zs)});function Vt(o,e){throw new D(o,e??Xa(o))}function Ai(o,e,t){o&&Vt(e,t)}function Di(o,e,t){o||Vt(e,t)}function Xa(o){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"}[o]??"An error occurred"}var D,Kt,tr,sr,Wt,Jt,pe,rr=y(()=>{"use strict";er();D=class extends Error{constructor(t,s,r){super(s);this.statusCode=t;this.details=r;this.name="HttpError"}},Kt=class extends D{constructor(e="The requested resource was not found"){super(404,e),this.name="NotFoundError"}},tr=class extends D{constructor(e="Unauthenticated"){super(401,e),this.name="UnauthorizedError"}},sr=class extends D{constructor(e="You do not have permission to perform this action"){super(403,e),this.name="ForbiddenError"}},Wt=class extends D{constructor(t,s="The given data was invalid"){super(422,s,{errors:t});this.errors=t;this.name="ValidationError"}},Jt=class extends Kt{constructor(e,t){super(t?`${e} with ID ${t} not found`:`${e} not found`),this.name="ModelNotFoundError"}};pe=class{config;constructor(e={}){this.config={debug:process.env.NODE_ENV!=="production",dontReport:[Wt,Kt,tr,sr],...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 D?{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(zt.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 D){let s={message:e.message};return e instanceof Wt&&(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)}},Ys=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)}}},Zs=class{minLevel="debug";write(){}},Xs=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:L()})}info(e,t={}){this.writeToDefault({level:"info",message:e,context:t,timestamp:L()})}warn(e,t={}){this.writeToDefault({level:"warn",message:e,context:t,timestamp:L()})}error(e,t={}){this.writeToDefault({level:"error",message:e,context:t,timestamp:L()})}fatal(e,t={}){this.writeToDefault({level:"fatal",message:e,context:t,timestamp:L()})}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 je({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 je(e);case"file":return new Gs(e);case"stack":return new Ys(e,t=>this.resolveChannel(t));case"null":return new Zs;default:return new je(e)}}},er=class{constructor(e){this.channel=e}debug(e,t={}){this.channel.write({level:"debug",message:e,context:t,timestamp:L()})}info(e,t={}){this.channel.write({level:"info",message:e,context:t,timestamp:L()})}warn(e,t={}){this.channel.write({level:"warn",message:e,context:t,timestamp:L()})}error(e,t={}){this.channel.write({level:"error",message:e,context:t,timestamp:L()})}fatal(e,t={}){this.channel.write({level:"fatal",message:e,context:t,timestamp:L()})}};Kt=C("svelar.log",()=>new Xs)});function Qt(o,e){throw new A(o,e??so(o))}function gi(o,e,t){o&&Qt(e,t)}function fi(o,e,t){o||Qt(e,t)}function so(o){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"}[o]??"An error occurred"}var A,Wt,sr,rr,Jt,Vt,me,ir=y(()=>{"use strict";tr();A=class extends Error{constructor(t,s,r){super(s);this.statusCode=t;this.details=r;this.name="HttpError"}},Wt=class extends A{constructor(e="The requested resource was not found"){super(404,e),this.name="NotFoundError"}},sr=class extends A{constructor(e="Unauthenticated"){super(401,e),this.name="UnauthorizedError"}},rr=class extends A{constructor(e="You do not have permission to perform this action"){super(403,e),this.name="ForbiddenError"}},Jt=class extends A{constructor(t,s="The given data was invalid"){super(422,s,{errors:t});this.errors=t;this.name="ValidationError"}},Vt=class extends Wt{constructor(e,t){super(t?`${e} with ID ${t} not found`:`${e} not found`),this.name="ModelNotFoundError"}};me=class{config;constructor(e={}){this.config={debug:process.env.NODE_ENV!=="production",dontReport:[Jt,Wt,sr,rr],...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 A?{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(Kt.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 A){let s={message:e.message};return e instanceof Jt&&(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 Li(o={}){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:a=["/api/"],csrfExcludePaths:l=["/api/webhooks"],authThrottleAttempts:c=5,authThrottleDecay:d=1,debug:p=process.env.NODE_ENV!=="production",middleware:h=[],namedMiddleware:u={},i18n:v,errorConfig:x={}}=o,k=[new ie,new se({maxRequests:i,windowMs:n}),new re({onlyPaths:a,excludePaths:l}),new ce({store:s??new H,secret:t,lifetime:r})];e&&k.push(new me(e)),k.push(...h);let ls={"auth-throttle":new ne({maxAttempts:c,decayMinutes:d}),...u},cs=new pe({debug:p,...x}),Ue=ir({middleware:k,namedMiddleware:ls,onError:(ye,be)=>cs.handle(ye,be)}),z;if(v){let{paraglideMiddleware:ye,getTextDirection:be=()=>"ltr"}=v;z=nr(async({event:$,resolve:Fe})=>ye($.request,({request:ds,locale:Be})=>($.request=ds,Fe($,{transformPageChunk:({html:He})=>He.replace("%lang%",Be).replace("%dir%",be(Be))}))),Ue)}else z=Ue;return{handle:z,handleError:cs.handleSvelteKitError()}}function ir(o={}){let e=new O;if(o.middleware)for(let t of o.middleware)e.use(t);if(o.namedMiddleware)for(let[t,s]of Object.entries(o.namedMiddleware))e.register(t,s);return async function({event:s,resolve:r}){let i={event:s,params:s.params??{},locals:s.locals??{}};try{o.app&&!o.app.isBooted()&&await o.app.bootstrap();let n=await e.execute(i,async()=>r(s));return n instanceof Response?n:r(s)}catch(n){if(o.onError){let a=await o.onError(n,s);if(a instanceof Response)return a}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 nr(...o){return async function({event:t,resolve:s}){let r=s;for(let i=o.length-1;i>=0;i--){let n=o[i],a=r;r=l=>n({event:l,resolve:a})}return r(t)}}var ar=y(()=>{"use strict";ae();Ms();Vs();rr()});function Mi(o,e){let t=process.env[o];return t===void 0?e!==void 0?e:"":t==="true"?!0:t==="false"?!1:t==="null"?null:/^\d+$/.test(t)?Number(t):t}var or,Ni,Ii=y(()=>{"use strict";S();or=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:a}=await import("url"),l=t(e);if(!i(l))return[];let c=n(l).filter(p=>(p.endsWith(".ts")||p.endsWith(".js"))&&!p.startsWith(".")),d=[];for(let p of c){let h=s(p,r(p)),u=t(l,p);try{let x=await import(a(u).href),k=x.default??x.config??x;k&&typeof k=="object"&&!Array.isArray(k)&&(this.set(h,k),d.push(h))}catch{}}return d}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}},Ni=w("svelar.config",()=>new or)});import{z as R}from"zod";function ji(o,e){let t=o.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 l=0;l<i.length-1;l++){let c=i[l];c in n||(n[c]={}),n=n[c]}let a=i[i.length-1];n[a]||(n[a]=[]),n[a].push(r.message)}return{success:!1,errors:s}}var _i,Oi=y(()=>{"use strict";_i={required:()=>R.string().min(1,"This field is required"),email:()=>R.string().email("Must be a valid email address"),string:(o,e)=>{let t=R.string();return o!==void 0&&(t=t.min(o)),e!==void 0&&(t=t.max(e)),t},number:(o,e)=>{let t=R.number();return o!==void 0&&(t=t.min(o)),e!==void 0&&(t=t.max(e)),t},integer:()=>R.number().int(),boolean:()=>R.boolean(),date:()=>R.coerce.date(),url:()=>R.string().url(),uuid:()=>R.string().uuid(),enum:o=>R.enum(o),array:o=>R.array(o),nullable:o=>o.nullable(),optional:o=>o.optional(),confirmed:(o="password")=>R.object({[o]:R.string(),[`${o}_confirmation`]:R.string()}).refine(e=>e[o]===e[`${o}_confirmation`],{message:"Confirmation does not match",path:[`${o}_confirmation`]}),min:o=>R.number().min(o),max:o=>R.number().max(o),between:(o,e)=>R.number().min(o).max(e),regex:(o,e)=>R.string().regex(o,e),ip:()=>R.string().refine(o=>{let e=o.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:()=>R.string().refine(o=>{try{return JSON.parse(o),!0}catch{return!1}},{message:"Must be valid JSON"})}});var qi={};E(qi,{FormAuthorizationError:()=>ge,FormRequest:()=>Oe,FormValidationError:()=>he});var Oe,he,ge,lr=y(()=>{"use strict";Oe=class{authorize(e){return!0}messages(){return{}}attributes(){return{}}passedValidation(e){return e}failedValidation(e){throw new he(e)}failedAuthorization(){throw new ge}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},a=t.rules().safeParse(i);if(!a.success){let l={},c=t.messages(),d=t.attributes();for(let p of a.error.issues){let h=p.path.join("."),u=d[h]??h;l[u]||(l[u]=[]);let v=`${h}.${p.code}`,x=c[v]??c[h];l[u].push(x??p.message)}t.failedValidation(l)}return t.passedValidation(a.data)}},he=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"}})}},ge=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 Ui,writeFile as eo,unlink as to,mkdir as qe,readdir as cr,stat as Fi,copyFile as so,rename as ro}from"fs/promises";import{existsSync as io}from"fs";import{join as no,dirname as Qt}from"path";var dr,Gt,ur,Bi,Hi=y(()=>{"use strict";S();dr=class{constructor(e){this.config=e;if(!e.root)throw new Error('Local disk requires a "root" path.')}resolve(e){return no(this.config.root,e)}async get(e){return Ui(this.resolve(e))}async getText(e){return Ui(this.resolve(e),"utf-8")}async put(e,t){let s=this.resolve(e);await qe(Qt(s),{recursive:!0}),await eo(s,t)}async append(e,t){let{appendFile:s}=await import("fs/promises"),r=this.resolve(e);await qe(Qt(r),{recursive:!0}),await s(r,t)}async exists(e){return io(this.resolve(e))}async delete(e){try{return await to(this.resolve(e)),!0}catch{return!1}}async copy(e,t){let s=this.resolve(t);await qe(Qt(s),{recursive:!0}),await so(this.resolve(e),s)}async move(e,t){let s=this.resolve(t);await qe(Qt(s),{recursive:!0}),await ro(this.resolve(e),s)}async files(e=""){let t=this.resolve(e);try{return(await cr(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 cr(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 cr(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 Fi(this.resolve(e))).size}async lastModified(e){return(await Fi(this.resolve(e))).mtime}url(e){return`${this.config.urlPrefix??""}/${e}`}},Gt=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 a=this.config.prefix;return a?n.slice(a.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 a=await s.send(new t.ListObjectsV2Command({Bucket:this.config.bucket,Prefix:r,ContinuationToken:n}));for(let l of a.Contents??[]){let c=this.config.prefix,d=c?l.Key.slice(c.length+1):l.Key;d&&i.push(d)}n=a.IsTruncated?a.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 a=this.config.prefix;return(a?n.Prefix.slice(a.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}))}}},ur=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 dr(e);case"s3":return new Gt(e);default:throw new Error(`Unknown storage driver: ${e.driver}`)}}s3Disk(e){let t=this.disk(e);if(!(t instanceof Gt))throw new Error(`Disk "${e??this.config?.default}" is not an S3 disk.`);return t}},Bi=w("svelar.storage",()=>new ur)});import{readFile as ao,writeFile as oo,unlink as zi,mkdir as Ki}from"fs/promises";import{join as lo,dirname as co}from"path";import{createHash as uo}from"crypto";var mr,pr,hr,gr,Wi,Ji=y(()=>{"use strict";S();mr=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)}},pr=class{basePath;constructor(e){this.basePath=e.path??"storage/cache"}filePath(e){let t=uo("md5").update(e).digest("hex");return lo(this.basePath,t.slice(0,2),t)}async get(e){let t=this.filePath(e);try{let s=await ao(t,"utf-8"),r=JSON.parse(s);return r.expiresAt&&Date.now()>r.expiresAt?(await zi(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 Ki(co(r),{recursive:!0}),await oo(r,JSON.stringify(i))}async forget(e){try{return await zi(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 Ki(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)}},hr=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}},gr=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 mr;case"file":return new pr(e);case"null":return new hr;case"redis":throw new Error("Redis cache requires ioredis. Install: npm install ioredis");default:throw new Error(`Unknown cache driver: ${e.driver}`)}}},Wi=w("svelar.cache",()=>new gr)});var Yt,fr,yr,br,Vi,Qi=y(()=>{"use strict";S();Yt=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(()=>(Ut(),Ks));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)}}},yr=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(()=>(C(),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)}}},br=class{channels=new Map;constructor(){this.channels.set("mail",new fr),this.channels.set("database",new yr)}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 a=this.channels.get(n);if(a)try{await a.send(r,t)}catch(l){console.error(`[Notifications] Channel "${n}" failed:`,l)}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)}}},Vi=w("svelar.notifier",()=>new br)});function vr(o){return o.startsWith("private-")?"private":o.startsWith("presence-")?"presence":"public"}var wr,Zt,Cr,xr,Gi,Yi=y(()=>{"use strict";S();wr=class{subscribers=[];name;type;constructor(e){this.name=e,this.type=vr(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 a=`event: connected
140
+ `).map(s=>s.trim())),new Response(JSON.stringify(t),{status:500,headers:{"Content-Type":"application/json"}})}}});function bi(o={}){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:a=["/api/"],csrfExcludePaths:l=["/api/webhooks"],authThrottleAttempts:c=5,authThrottleDecay:u=1,debug:m=process.env.NODE_ENV!=="production",middleware:h=[],namedMiddleware:d={},i18n:b,errorConfig:w={}}=o,E=[new re,new te({maxRequests:i,windowMs:n}),new se({onlyPaths:a,excludePaths:l}),new le({store:s??new H,secret:t,lifetime:r})];e&&E.push(new ue(e)),E.push(...h);let cs={"auth-throttle":new ie({maxAttempts:c,decayMinutes:u}),...d},ds=new me({debug:m,...w}),Ue=nr({middleware:E,namedMiddleware:cs,onError:(fe,be)=>ds.handle(fe,be)}),z;if(b){let{paraglideMiddleware:fe,getTextDirection:be=()=>"ltr"}=b;z=ar(async({event:$,resolve:Be})=>fe($.request,({request:us,locale:Fe})=>($.request=us,Be($,{transformPageChunk:({html:He})=>He.replace("%lang%",Fe).replace("%dir%",be(Fe))}))),Ue)}else z=Ue;return{handle:z,handleError:ds.handleSvelteKitError()}}function nr(o={}){let e=new O;if(o.middleware)for(let t of o.middleware)e.use(t);if(o.namedMiddleware)for(let[t,s]of Object.entries(o.namedMiddleware))e.register(t,s);return async function({event:s,resolve:r}){let i={event:s,params:s.params??{},locals:s.locals??{}};try{o.app&&!o.app.isBooted()&&await o.app.bootstrap();let n=await e.execute(i,async()=>r(s));return n instanceof Response?n:r(s)}catch(n){if(o.onError){let a=await o.onError(n,s);if(a instanceof Response)return a}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(...o){return async function({event:t,resolve:s}){let r=s;for(let i=o.length-1;i>=0;i--){let n=o[i],a=r;r=l=>n({event:l,resolve:a})}return r(t)}}var or=y(()=>{"use strict";ne();_s();Qs();ir()});function yi(o,e){let t=process.env[o];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,vi,wi=y(()=>{"use strict";R();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:a}=await import("url"),l=t(e);if(!i(l))return[];let c=n(l).filter(m=>(m.endsWith(".ts")||m.endsWith(".js"))&&!m.startsWith(".")),u=[];for(let m of c){let h=s(m,r(m)),d=t(l,m);try{let w=await import(a(d).href),E=w.default??w.config??w;E&&typeof E=="object"&&!Array.isArray(E)&&(this.set(h,E),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}},vi=C("svelar.config",()=>new lr)});import{z as P}from"zod";function xi(o,e){let t=o.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 l=0;l<i.length-1;l++){let c=i[l];c in n||(n[c]={}),n=n[c]}let a=i[i.length-1];n[a]||(n[a]=[]),n[a].push(r.message)}return{success:!1,errors:s}}var Ci,Si=y(()=>{"use strict";Ci={required:()=>P.string().min(1,"This field is required"),email:()=>P.string().email("Must be a valid email address"),string:(o,e)=>{let t=P.string();return o!==void 0&&(t=t.min(o)),e!==void 0&&(t=t.max(e)),t},number:(o,e)=>{let t=P.number();return o!==void 0&&(t=t.min(o)),e!==void 0&&(t=t.max(e)),t},integer:()=>P.number().int(),boolean:()=>P.boolean(),date:()=>P.coerce.date(),url:()=>P.string().url(),uuid:()=>P.string().uuid(),enum:o=>P.enum(o),array:o=>P.array(o),nullable:o=>o.nullable(),optional:o=>o.optional(),confirmed:(o="password")=>P.object({[o]:P.string(),[`${o}_confirmation`]:P.string()}).refine(e=>e[o]===e[`${o}_confirmation`],{message:"Confirmation does not match",path:[`${o}_confirmation`]}),min:o=>P.number().min(o),max:o=>P.number().max(o),between:(o,e)=>P.number().min(o).max(e),regex:(o,e)=>P.string().regex(o,e),ip:()=>P.string().refine(o=>{let e=o.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:()=>P.string().refine(o=>{try{return JSON.parse(o),!0}catch{return!1}},{message:"Must be valid JSON"})}});var Pi={};k(Pi,{FormAuthorizationError:()=>he,FormRequest:()=>Oe,FormValidationError:()=>pe});var Oe,pe,he,cr=y(()=>{"use strict";Oe=class{authorize(e){return!0}messages(){return{}}attributes(){return{}}passedValidation(e){return e}failedValidation(e){throw new pe(e)}failedAuthorization(){throw new he}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},a=t.rules().safeParse(i);if(!a.success){let l={},c=t.messages(),u=t.attributes();for(let m of a.error.issues){let h=m.path.join("."),d=u[h]??h;l[d]||(l[d]=[]);let b=`${h}.${m.code}`,w=c[b]??c[h];l[d].push(w??m.message)}t.failedValidation(l)}return t.passedValidation(a.data)}},pe=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"}})}},he=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 Ri,writeFile as ro,unlink as io,mkdir as qe,readdir as dr,stat as Ti,copyFile as no,rename as ao}from"fs/promises";import{existsSync as oo}from"fs";import{join as lo,dirname as Gt}from"path";var ur,Yt,mr,Ei,ki=y(()=>{"use strict";R();ur=class{constructor(e){this.config=e;if(!e.root)throw new Error('Local disk requires a "root" path.')}resolve(e){return lo(this.config.root,e)}async get(e){return Ri(this.resolve(e))}async getText(e){return Ri(this.resolve(e),"utf-8")}async put(e,t){let s=this.resolve(e);await qe(Gt(s),{recursive:!0}),await ro(s,t)}async append(e,t){let{appendFile:s}=await import("fs/promises"),r=this.resolve(e);await qe(Gt(r),{recursive:!0}),await s(r,t)}async exists(e){return oo(this.resolve(e))}async delete(e){try{return await io(this.resolve(e)),!0}catch{return!1}}async copy(e,t){let s=this.resolve(t);await qe(Gt(s),{recursive:!0}),await no(this.resolve(e),s)}async move(e,t){let s=this.resolve(t);await qe(Gt(s),{recursive:!0}),await ao(this.resolve(e),s)}async files(e=""){let t=this.resolve(e);try{return(await dr(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 dr(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 dr(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 Ti(this.resolve(e))).size}async lastModified(e){return(await Ti(this.resolve(e))).mtime}url(e){return`${this.config.urlPrefix??""}/${e}`}},Yt=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 a=this.config.prefix;return a?n.slice(a.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 a=await s.send(new t.ListObjectsV2Command({Bucket:this.config.bucket,Prefix:r,ContinuationToken:n}));for(let l of a.Contents??[]){let c=this.config.prefix,u=c?l.Key.slice(c.length+1):l.Key;u&&i.push(u)}n=a.IsTruncated?a.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 a=this.config.prefix;return(a?n.Prefix.slice(a.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}))}}},mr=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 ur(e);case"s3":return new Yt(e);default:throw new Error(`Unknown storage driver: ${e.driver}`)}}s3Disk(e){let t=this.disk(e);if(!(t instanceof Yt))throw new Error(`Disk "${e??this.config?.default}" is not an S3 disk.`);return t}},Ei=C("svelar.storage",()=>new mr)});import{readFile as co,writeFile as uo,unlink as $i,mkdir as Di}from"fs/promises";import{join as mo,dirname as po}from"path";import{createHash as ho}from"crypto";var pr,hr,gr,fr,Ai,Mi=y(()=>{"use strict";R();pr=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)}},hr=class{basePath;constructor(e){this.basePath=e.path??"storage/cache"}filePath(e){let t=ho("md5").update(e).digest("hex");return mo(this.basePath,t.slice(0,2),t)}async get(e){let t=this.filePath(e);try{let s=await co(t,"utf-8"),r=JSON.parse(s);return r.expiresAt&&Date.now()>r.expiresAt?(await $i(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 Di(po(r),{recursive:!0}),await uo(r,JSON.stringify(i))}async forget(e){try{return await $i(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 Di(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)}},gr=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 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 pr;case"file":return new hr(e);case"null":return new gr;case"redis":throw new Error("Redis cache requires ioredis. Install: npm install ioredis");default:throw new Error(`Unknown cache driver: ${e.driver}`)}}},Ai=C("svelar.cache",()=>new fr)});var Zt,br,yr,vr,Li,_i=y(()=>{"use strict";R();Zt=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:i}=await Promise.resolve().then(()=>(Bt(),Ws));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)}}},yr=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(()=>(x(),S));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)}}},vr=class{channels=new Map;constructor(){this.channels.set("mail",new br),this.channels.set("database",new yr)}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 a=this.channels.get(n);if(a)try{await a.send(r,t)}catch(l){console.error(`[Notifications] Channel "${n}" failed:`,l)}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)}}},Li=C("svelar.notifier",()=>new vr)});function wr(o){return o.startsWith("private-")?"private":o.startsWith("presence-")?"presence":"public"}var Cr,Xt,xr,Sr,Ni,Ii=y(()=>{"use strict";R();Cr=class{subscribers=[];name;type;constructor(e){this.name=e,this.type=wr(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 a=`event: connected
142
142
  data: ${JSON.stringify(n)}
143
143
  id: ${Date.now()}
144
144
 
@@ -156,9 +156,9 @@ id: ${Date.now()}
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{}}},Zt=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(),a=await this.md5(i),l=["POST",`/apps/${this.config.appId}/events`,[`auth_key=${this.config.key}`,`auth_timestamp=${n}`,"auth_version=1.0",`body_md5=${a}`].join("&")].join(`
160
- `),c=await this.hmacSha256(this.config.secret,l),d=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),u=`${d}://${p}:${h}/apps/${this.config.appId}/events?auth_key=${this.config.key}&auth_timestamp=${n}&auth_version=1.0&body_md5=${a}&auth_signature=${c}`,v=await fetch(u,{method:"POST",headers:{"Content-Type":"application/json"},body:i});if(!v.ok){let x=await v.text();throw new Error(`Pusher API error (${v.status}): ${x}`)}}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),a=`${this.config.key}:${n}`;return i?{auth:a,channel_data:i}:{auth:a}}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")}},Cr=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)}},xr=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 Zt(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(vr(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=vr(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 Cr(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 Zt(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,l=>l==="{"||l==="}"?l:`\\${l}`).replace(/\\\{(\w+)\\\}/g,(l,c)=>(s.push(c),"([^.]+)")).replace(/\{(\w+)\}/g,(l,c)=>(s.push(c),"([^.]+)")),i=new RegExp(`^${r}$`),n=t.match(i);if(!n)return null;let a={};for(let l=0;l<s.length;l++)a[s[l]]=n[l+1];return a}},Gi=w("svelar.broadcast",()=>new xr)});function Xt(o,e,t){Zi&&Zi(o,e,{description:t})}async function Xi(o,e={}){let{csrfCookieName:t="XSRF-TOKEN",csrfHeaderName:s="X-CSRF-Token",showToast:r=!0,errorMessages:i={},...n}=e,a=(n.method||"GET").toUpperCase(),l=new Headers(n.headers);if(["POST","PUT","PATCH","DELETE"].includes(a)){let c=Rr(t);c&&l.set(s,c)}n.body&&typeof n.body=="string"&&!l.has("Content-Type")&&l.set("Content-Type","application/json"),l.has("Accept")||l.set("Accept","application/json");try{let c=await fetch(o,{...n,headers:l});return!c.ok&&r&&await po(c,{...mo,...i}),c}catch(c){throw r&&Xt("error","Network Error","Unable to connect. Check your internet connection."),c}}async function po(o,e){let t="";try{if((o.headers.get("content-type")??"").includes("application/json")){let n=await o.clone().json();if(t=n.message??"",o.status===422&&n.errors){let a=Object.entries(n.errors).map(([l,c])=>`${l}: ${c.join(", ")}`).slice(0,3).join(`
161
- `);Xt("warning",e[422]??"Validation Error",a);return}}}catch{}let s=t||e[o.status]||`Error ${o.status}`,r=o.status>=500?"error":o.status===429?"warning":"error";if(o.status===401){Xt("warning",s,"Please sign in to continue.");return}Xt(r,s)}function Rr(o="XSRF-TOKEN"){if(typeof document>"u")return null;let e=o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),t=document.cookie.match(new RegExp(`(?:^|;\\s*)${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}function en(o,e){if(!e)return o;let t=new URL(o,"http://localhost");for(let[s,r]of Object.entries(e))r!=null&&t.searchParams.set(s,String(r));return t.pathname+t.search}var mo,Zi,Pr,fe,Cu,tn=y(()=>{"use strict";mo={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."},Zi=null;Pr=class o{_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 o;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 a=null,l=1+this._retries;for(let c=0;c<l;c++){c>0&&await new Promise(d=>setTimeout(d,this._retryDelay*c));try{let d=new AbortController,p=setTimeout(()=>d.abort(),this._timeout),h=await fetch(r,{method:e,headers:i,body:n,signal:d.signal});if(clearTimeout(p),!h.ok&&h.status<500&&c<l-1,!h.ok&&h.status>=500&&c<l-1){a=new fe(`HTTP ${h.status}: ${h.statusText}`,h.status,await h.text());continue}let u=h.headers.get("content-type")??"",v;if(u.includes("application/json")?v=await h.json():v=await h.text(),!h.ok)throw new fe(`HTTP ${h.status}: ${typeof v=="string"?v:JSON.stringify(v)}`,h.status,v);return{data:v,status:h.status,headers:h.headers,ok:!0}}catch(d){if(d instanceof fe)throw d;if(a=d,d.name==="AbortError"&&(a=new fe("Request timed out",0,null)),c>=l-1)break}}throw a??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}},fe=class extends Error{constructor(t,s,r){super(t);this.status=s;this.body=r;this.name="HttpRequestError"}},Cu=new Pr});function sn(o){let{paraglideMiddleware:e,getTextDirection:t=()=>"ltr",langPlaceholder:s="%lang%",dirPlaceholder:r="%dir%"}=o;return({event:i,resolve:n})=>e(i.request,({request:a,locale:l})=>(i.request=a,n(i,{transformPageChunk:({html:c})=>c.replace(s,l).replace(r,t(l))})))}function rn(o){return e=>o.deLocalizeUrl(e.url).pathname}var nn=y(()=>{"use strict"});function an(o,e,t={}){return async s=>{let{superValidate:r,fail:i,message:n}=await import("sveltekit-superforms"),{zod:a}=await import("sveltekit-superforms/adapters"),l=await r(s,a(o));if(!l.valid)return i(400,{form:l});try{let c=await e(l.data,s);if(t.redirectTo){let{redirect:d}=await import("@sveltejs/kit");throw d(303,t.redirectTo)}return c??{form:l}}catch(c){if(c?.status>=300&&c?.status<400)throw c;return n(l,t.errorMessage||c.message||"An error occurred",{status:c.status||400})}}}async function on(o,e){let{superValidate:t}=await import("sveltekit-superforms"),{zod:s}=await import("sveltekit-superforms/adapters");return t(e??null,s(o))}async function ln(o,e){let t=await o.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(()=>(lr(),qi));throw new i(r.error.flatten().fieldErrors)}return r.data}var cn=y(()=>{"use strict"});var dn={};E(dn,{Application:()=>Dt,AuthManager:()=>Ft,AuthenticateMiddleware:()=>me,BelongsTo:()=>X,BelongsToMany:()=>ee,Broadcast:()=>Gi,Cache:()=>Wi,ColumnBuilder:()=>_,Connection:()=>f,Container:()=>B,Controller:()=>It,CorsMiddleware:()=>Lt,CsrfMiddleware:()=>re,DatabaseSessionStore:()=>_t,ErrorHandler:()=>pe,Event:()=>te,EventDispatcher:()=>ke,FileSessionStore:()=>jt,ForbiddenError:()=>De,FormAuthorizationError:()=>ge,FormRequest:()=>Oe,FormValidationError:()=>he,HasMany:()=>Z,HasOne:()=>Y,Hash:()=>_s,HttpError:()=>D,Job:()=>V,Log:()=>zt,LoggingMiddleware:()=>Mt,Mailable:()=>Ie,Mailer:()=>zs,MemorySessionStore:()=>H,Middleware:()=>T,MiddlewareStack:()=>O,Migration:()=>we,Migrator:()=>Ce,Model:()=>$t,ModelNotFoundError:()=>Jt,NotFoundError:()=>$e,Notification:()=>Yt,Notifier:()=>Vi,OriginMiddleware:()=>ie,QueryBuilder:()=>L,Queue:()=>ks,RateLimitMiddleware:()=>se,RedisSessionStore:()=>Ot,RequireAuthMiddleware:()=>Bt,Schema:()=>j,Seeder:()=>At,ServiceProvider:()=>Ee,Session:()=>le,SessionMiddleware:()=>ce,SignatureMiddleware:()=>Nt,Storage:()=>Bi,TableBuilder:()=>W,ThrottleMiddleware:()=>ne,UnauthorizedError:()=>Ae,ValidationError:()=>q,abort:()=>Vt,abortIf:()=>Ai,abortUnless:()=>Di,apiFetch:()=>Xi,buildUrl:()=>en,config:()=>Ni,container:()=>bi,createFormAction:()=>an,createI18nHandle:()=>sn,createReroute:()=>rn,createSvelarApp:()=>Li,createSvelarHooks:()=>ir,env:()=>Mi,getCsrfToken:()=>Rr,loadForm:()=>on,resource:()=>wi,rules:()=>_i,schema:()=>ni,sequence:()=>nr,signJwt:()=>Ws,validate:()=>ji,validateForm:()=>ln,verifyJwt:()=>Js,z:()=>R});var un=y(()=>{"use strict";fi();$s();As();C();bs();vs();yi();Ls();Ds();vi();ae();Ci();ar();Ii();Oi();Vs();de();Ms();rr();kt();lr();Hi();er();Ji();Q();Ut();Qi();Yi();tn();nn();cn();ar()});var Er={};E(Er,{PluginRegistry:()=>rs});var Tr,rs,is=y(()=>{"use strict";S();Tr=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;try{let a=s(n,{withFileTypes:!0});for(let l of a){if(!l.isDirectory())continue;let c=l.name;if(c.startsWith("."))continue;let d=c.startsWith("svelar-");if(!d)continue;let p=e(n,c,"package.json");if(t(p))try{let h=await r(p,"utf-8"),u=JSON.parse(h),v=u.keywords?.includes("svelar-plugin");if(!d&&!v)continue;let x={name:u.name||c,version:u.version||"0.0.0",description:u.description||"",packageName:c,installed:!0,enabled:!1,hasConfig:!!u.svelar?.config,hasMigrations:!!u.svelar?.migrations};i.push(x),this.plugins.set(x.name,x)}catch{}}}catch{}return 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)}},rs=w("svelar.pluginRegistry",()=>new Tr)});var pn={};E(pn,{PluginPublisher:()=>$r});var kr,$r,Ar=y(()=>{"use strict";S();kr=class{async publish(e,t){let{mkdir:s,copyFile:r}=await import("fs/promises"),{join:i,dirname:n}=await import("path"),{existsSync:a}=await import("fs"),l={configs:[],migrations:[],assets:[]},c=e.publishables?.()||{};for(let[d,p]of Object.entries(c))for(let h of p){if(t?.only&&h.type!==t.only)continue;let u=i(process.cwd(),h.dest),v=n(u);if(!(a(u)&&!t?.force))try{await s(v,{recursive:!0}),await r(h.source,u),h.type==="config"?l.configs.push(u):h.type==="migration"?l.migrations.push(u):h.type==="asset"&&l.assets.push(u)}catch(x){console.warn(`Failed to publish ${h.source} to ${u}:`,x)}}return l}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 a=ze("path").join(process.cwd(),n.dest);n.type==="config"?t.configs.push(a):n.type==="migration"?t.migrations.push(a):n.type==="asset"&&t.assets.push(a)}return t}},$r=w("svelar.pluginPublisher",()=>new kr)});var hn={};E(hn,{PluginInstaller:()=>yo});var Dr,yo,gn=y(()=>{"use strict";S();is();Ar();Dr=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:a}=await import("fs");try{await this.runNpmInstall(e);let l=rs,c=await l.discover(),d;for(let h of c)if(h.packageName===e||h.name===e){d=h;break}if(!d)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.`};l.enable(d.name);let p=null;if(t?.publish!==!1)try{let h=await this.loadPluginClass(d.packageName);h&&(p=await $r.publish(new h))}catch(h){console.warn("Failed to publish plugin assets:",h)}return{success:!0,pluginName:d.name,version:d.version,published:p}}catch(l){return{success:!1,pluginName:e,version:"0.0.0",published:null,error:l?.message??String(l)}}}async uninstall(e){try{let t=rs,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}=ze("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}=ze("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);return t.default||Object.values(t)[0]}catch{return null}}},yo=w("svelar.pluginInstaller",()=>new Dr)});import{dirname as yn,join as Lr}from"path";import{fileURLToPath as bn,pathToFileURL as bo}from"url";import{register as vo}from"module";import{readFileSync as vn,existsSync as wo}from"fs";var Ke=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(a){let l=a instanceof Error?a.message:String(a);console.error(`\x1B[31mError:\x1B[0m ${l}`),a?.stack&&console.error(a.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 a=n.slice(2),l=a.indexOf("=");if(l!==-1){let p=a.slice(0,l);r[p]=a.slice(l+1);continue}let c=a;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 a=n.slice(1),l=t.flags.find(c=>c.alias===a);l&&(l.type==="boolean"?r[l.name]=!0:i+1<e.length&&(r[l.name]=e[++i]))}else s.push(n)}return{args:s,flags:r}}showCommandHelp(e){if(console.log(`
159
+ `,i=new TextEncoder().encode(r);for(let n of this.subscribers)if(n.userId!==s)try{n.controller.enqueue(i)}catch{}}},Xt=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(),a=await this.md5(i),l=["POST",`/apps/${this.config.appId}/events`,[`auth_key=${this.config.key}`,`auth_timestamp=${n}`,"auth_version=1.0",`body_md5=${a}`].join("&")].join(`
160
+ `),c=await this.hmacSha256(this.config.secret,l),u=this.config.useTLS!==!1?"https":"http",m=this.config.host??`api-${this.config.cluster??"mt1"}.pusher.com`,h=this.config.port??(this.config.useTLS!==!1?443:80),d=`${u}://${m}:${h}/apps/${this.config.appId}/events?auth_key=${this.config.key}&auth_timestamp=${n}&auth_version=1.0&body_md5=${a}&auth_signature=${c}`,b=await fetch(d,{method:"POST",headers:{"Content-Type":"application/json"},body:i});if(!b.ok){let w=await b.text();throw new Error(`Pusher API error (${b.status}): ${w}`)}}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),a=`${this.config.key}:${n}`;return i?{auth:a,channel_data:i}:{auth:a}}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")}},xr=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)}},Sr=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 Xt(t))}channel(e,t){if(t){this.channelAuth.set(e,t);return}return this.sseChannels.has(e)||this.sseChannels.set(e,new Cr(e)),this.sseChannels.get(e)}async authorize(e,t){if(wr(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=wr(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 xr(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 Xt(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,l=>l==="{"||l==="}"?l:`\\${l}`).replace(/\\\{(\w+)\\\}/g,(l,c)=>(s.push(c),"([^.]+)")).replace(/\{(\w+)\}/g,(l,c)=>(s.push(c),"([^.]+)")),i=new RegExp(`^${r}$`),n=t.match(i);if(!n)return null;let a={};for(let l=0;l<s.length;l++)a[s[l]]=n[l+1];return a}},Ni=C("svelar.broadcast",()=>new Sr)});function es(o,e,t){ji&&ji(o,e,{description:t})}async function Oi(o,e={}){let{csrfCookieName:t="XSRF-TOKEN",csrfHeaderName:s="X-CSRF-Token",showToast:r=!0,errorMessages:i={},...n}=e,a=(n.method||"GET").toUpperCase(),l=new Headers(n.headers);if(["POST","PUT","PATCH","DELETE"].includes(a)){let c=Rr(t);c&&l.set(s,c)}n.body&&typeof n.body=="string"&&!l.has("Content-Type")&&l.set("Content-Type","application/json"),l.has("Accept")||l.set("Accept","application/json");try{let c=await fetch(o,{...n,headers:l});return!c.ok&&r&&await fo(c,{...go,...i}),c}catch(c){throw r&&es("error","Network Error","Unable to connect. Check your internet connection."),c}}async function fo(o,e){let t="";try{if((o.headers.get("content-type")??"").includes("application/json")){let n=await o.clone().json();if(t=n.message??"",o.status===422&&n.errors){let a=Object.entries(n.errors).map(([l,c])=>`${l}: ${c.join(", ")}`).slice(0,3).join(`
161
+ `);es("warning",e[422]??"Validation Error",a);return}}}catch{}let s=t||e[o.status]||`Error ${o.status}`,r=o.status>=500?"error":o.status===429?"warning":"error";if(o.status===401){es("warning",s,"Please sign in to continue.");return}es(r,s)}function Rr(o="XSRF-TOKEN"){if(typeof document>"u")return null;let e=o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),t=document.cookie.match(new RegExp(`(?:^|;\\s*)${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}function qi(o,e){if(!e)return o;let t=new URL(o,"http://localhost");for(let[s,r]of Object.entries(e))r!=null&&t.searchParams.set(s,String(r));return t.pathname+t.search}var go,ji,Pr,ge,Tu,Ui=y(()=>{"use strict";go={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."},ji=null;Pr=class o{_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 o;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 a=null,l=1+this._retries;for(let c=0;c<l;c++){c>0&&await new Promise(u=>setTimeout(u,this._retryDelay*c));try{let u=new AbortController,m=setTimeout(()=>u.abort(),this._timeout),h=await fetch(r,{method:e,headers:i,body:n,signal:u.signal});if(clearTimeout(m),!h.ok&&h.status<500&&c<l-1,!h.ok&&h.status>=500&&c<l-1){a=new ge(`HTTP ${h.status}: ${h.statusText}`,h.status,await h.text());continue}let d=h.headers.get("content-type")??"",b;if(d.includes("application/json")?b=await h.json():b=await h.text(),!h.ok)throw new ge(`HTTP ${h.status}: ${typeof b=="string"?b:JSON.stringify(b)}`,h.status,b);return{data:b,status:h.status,headers:h.headers,ok:!0}}catch(u){if(u instanceof ge)throw u;if(a=u,u.name==="AbortError"&&(a=new ge("Request timed out",0,null)),c>=l-1)break}}throw a??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}},ge=class extends Error{constructor(t,s,r){super(t);this.status=s;this.body=r;this.name="HttpRequestError"}},Tu=new Pr});function Bi(o){let{paraglideMiddleware:e,getTextDirection:t=()=>"ltr",langPlaceholder:s="%lang%",dirPlaceholder:r="%dir%"}=o;return({event:i,resolve:n})=>e(i.request,({request:a,locale:l})=>(i.request=a,n(i,{transformPageChunk:({html:c})=>c.replace(s,l).replace(r,t(l))})))}function Fi(o){return e=>o.deLocalizeUrl(e.url).pathname}var Hi=y(()=>{"use strict"});function zi(o,e,t={}){return async s=>{let{superValidate:r,fail:i,message:n}=await import("sveltekit-superforms"),{zod:a}=await import("sveltekit-superforms/adapters"),l=await r(s,a(o));if(!l.valid)return i(400,{form:l});try{let c=await e(l.data,s);if(t.redirectTo){let{redirect:u}=await import("@sveltejs/kit");throw u(303,t.redirectTo)}return c??{form:l}}catch(c){if(c?.status>=300&&c?.status<400)throw c;return n(l,t.errorMessage||c.message||"An error occurred",{status:c.status||400})}}}async function Ki(o,e){let{superValidate:t}=await import("sveltekit-superforms"),{zod:s}=await import("sveltekit-superforms/adapters");return t(e??null,s(o))}async function Wi(o,e){let t=await o.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(()=>(cr(),Pi));throw new i(r.error.flatten().fieldErrors)}return r.data}var Ji=y(()=>{"use strict"});var Vi={};k(Vi,{Application:()=>Mt,AuthManager:()=>Ft,AuthenticateMiddleware:()=>ue,BelongsTo:()=>Z,BelongsToMany:()=>X,Broadcast:()=>Ni,Cache:()=>Ai,ColumnBuilder:()=>I,Connection:()=>f,Container:()=>F,Controller:()=>It,CorsMiddleware:()=>Lt,CsrfMiddleware:()=>se,DatabaseSessionStore:()=>jt,ErrorHandler:()=>me,Event:()=>ee,EventDispatcher:()=>ke,FileSessionStore:()=>Ot,ForbiddenError:()=>Ae,FormAuthorizationError:()=>he,FormRequest:()=>Oe,FormValidationError:()=>pe,HasMany:()=>Y,HasOne:()=>G,Hash:()=>js,HttpError:()=>A,Job:()=>J,Log:()=>Kt,LoggingMiddleware:()=>_t,Mailable:()=>Ne,Mailer:()=>Ks,MemorySessionStore:()=>H,Middleware:()=>T,MiddlewareStack:()=>O,Migration:()=>we,Migrator:()=>Ce,Model:()=>Dt,ModelNotFoundError:()=>Vt,NotFoundError:()=>$e,Notification:()=>Zt,Notifier:()=>Li,OriginMiddleware:()=>re,QueryBuilder:()=>M,Queue:()=>$s,RateLimitMiddleware:()=>te,RedisSessionStore:()=>qt,RequireAuthMiddleware:()=>Ht,Schema:()=>j,Seeder:()=>At,ServiceProvider:()=>Ee,Session:()=>oe,SessionMiddleware:()=>le,SignatureMiddleware:()=>Nt,Storage:()=>Ei,TableBuilder:()=>K,ThrottleMiddleware:()=>ie,UnauthorizedError:()=>De,ValidationError:()=>q,abort:()=>Qt,abortIf:()=>gi,abortUnless:()=>fi,apiFetch:()=>Oi,buildUrl:()=>qi,config:()=>vi,container:()=>ri,createFormAction:()=>zi,createI18nHandle:()=>Bi,createReroute:()=>Fi,createSvelarApp:()=>bi,createSvelarHooks:()=>nr,env:()=>yi,getCsrfToken:()=>Rr,loadForm:()=>Ki,resource:()=>ni,rules:()=>Ci,schema:()=>Kr,sequence:()=>ar,signJwt:()=>Js,validate:()=>xi,validateForm:()=>Wi,verifyJwt:()=>Vs,z:()=>P});var Qi=y(()=>{"use strict";ti();Ds();As();x();ys();vs();si();Ls();Ms();ii();ne();ai();or();wi();Si();Qs();ce();_s();ir();$t();cr();ki();tr();Mi();V();Bt();_i();Ii();Ui();Hi();Ji();or()});var kr={};k(kr,{PluginRegistry:()=>is});var Er,is,ns=y(()=>{"use strict";R();Er=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;try{let a=s(n,{withFileTypes:!0});for(let l of a){if(!l.isDirectory())continue;let c=l.name;if(c.startsWith("."))continue;let u=c.startsWith("svelar-");if(!u)continue;let m=e(n,c,"package.json");if(t(m))try{let h=await r(m,"utf-8"),d=JSON.parse(h),b=d.keywords?.includes("svelar-plugin");if(!u&&!b)continue;let w={name:d.name||c,version:d.version||"0.0.0",description:d.description||"",packageName:c,installed:!0,enabled:!1,hasConfig:!!d.svelar?.config,hasMigrations:!!d.svelar?.migrations};i.push(w),this.plugins.set(w.name,w)}catch{}}}catch{}return 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)}},is=C("svelar.pluginRegistry",()=>new Er)});var Yi={};k(Yi,{PluginPublisher:()=>Dr});var $r,Dr,Ar=y(()=>{"use strict";R();$r=class{async publish(e,t){let{mkdir:s,copyFile:r}=await import("fs/promises"),{join:i,dirname:n}=await import("path"),{existsSync:a}=await import("fs"),l={configs:[],migrations:[],assets:[]},c=e.publishables?.()||{};for(let[u,m]of Object.entries(c))for(let h of m){if(t?.only&&h.type!==t.only)continue;let d=i(process.cwd(),h.dest),b=n(d);if(!(a(d)&&!t?.force))try{await s(b,{recursive:!0}),await r(h.source,d),h.type==="config"?l.configs.push(d):h.type==="migration"?l.migrations.push(d):h.type==="asset"&&l.assets.push(d)}catch(w){console.warn(`Failed to publish ${h.source} to ${d}:`,w)}}return l}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 a=ze("path").join(process.cwd(),n.dest);n.type==="config"?t.configs.push(a):n.type==="migration"?t.migrations.push(a):n.type==="asset"&&t.assets.push(a)}return t}},Dr=C("svelar.pluginPublisher",()=>new $r)});var Zi={};k(Zi,{PluginInstaller:()=>wo});var Mr,wo,Xi=y(()=>{"use strict";R();ns();Ar();Mr=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:a}=await import("fs");try{await this.runNpmInstall(e);let l=is,c=await l.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.`};l.enable(u.name);let m=null;if(t?.publish!==!1)try{let h=await this.loadPluginClass(u.packageName);h&&(m=await Dr.publish(new h))}catch(h){console.warn("Failed to publish plugin assets:",h)}return{success:!0,pluginName:u.name,version:u.version,published:m}}catch(l){return{success:!1,pluginName:e,version:"0.0.0",published:null,error:l?.message??String(l)}}}async uninstall(e){try{let t=is,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}=ze("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}=ze("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);return t.default||Object.values(t)[0]}catch{return null}}},wo=C("svelar.pluginInstaller",()=>new Mr)});import{dirname as tn,join as Lr}from"path";import{fileURLToPath as sn,pathToFileURL as Co}from"url";import{register as xo}from"module";import{readFileSync as rn,existsSync as So}from"fs";var Ke=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(a){let l=a instanceof Error?a.message:String(a);console.error(`\x1B[31mError:\x1B[0m ${l}`),a?.stack&&console.error(a.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 a=n.slice(2),l=a.indexOf("=");if(l!==-1){let m=a.slice(0,l);r[m]=a.slice(l+1);continue}let c=a;t.flags.find(m=>m.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 a=n.slice(1),l=t.flags.find(c=>c.alias===a);l&&(l.type==="boolean"?r[l.name]=!0:i+1<e.length&&(r[l.name]=e[++i]))}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
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(`
@@ -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()}};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(()=>(C(),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"),d=JSON.parse(c);r.configure(d),this.info("Database configured from svelar.database.json");return}catch(c){this.warn(`Failed to parse svelar.database.json: ${String(c?.message??c)}`)}let a=process.env.DB_DRIVER??"sqlite",l=process.env.DB_PATH??"database.db";r.configure({default:a,connections:{[a]:{driver:a,filename:l,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 ${a} database${a==="sqlite"?`: ${l}`:""}`)}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,a)=>Math.max(n.length,...t.map(l=>(l[a]??"").length))),r=s.map(n=>"\u2500".repeat(n+2)).join("\u253C"),i=n=>n.map((a,l)=>` ${(a??"").padEnd(s[l])} `).join("\u2502");console.log(i(e)),console.log(r);for(let n of t)console.log(i(n))}newLine(){console.log()}};import{writeFileSync as ms,mkdirSync as ps,existsSync as Cn}from"fs";import{join as K}from"path";var We=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.warn(`No --module specified. Using "${i}" as module. Consider: --module ${i}`);let n=K(process.cwd(),"src","lib","modules",i);ps(n,{recursive:!0});let a=K(n,`${s}.ts`);if(Cn(a)){this.warn(`Model ${s} already exists at ${a}`);return}let l=`import { Model } from '@beeblock/svelar/orm';
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 an}from"fs";import{join as ye}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(()=>(x(),S)),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 a=process.env.DB_DRIVER??"sqlite",l=process.env.DB_PATH??"database.db";r.configure({default:a,connections:{[a]:{driver:a,filename:l,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 ${a} database${a==="sqlite"?`: ${l}`:""}`)}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,a)=>Math.max(n.length,...t.map(l=>(l[a]??"").length))),r=s.map(n=>"\u2500".repeat(n+2)).join("\u253C"),i=n=>n.map((a,l)=>` ${(a??"").padEnd(s[l])} `).join("\u2502");console.log(i(e)),console.log(r);for(let n of t)console.log(i(n))}newLine(){console.log()}isDDD(){return an(ye(process.cwd(),"src","lib","modules"))}sharedDir(e){return this.isDDD()?ye(process.cwd(),"src","lib","shared",e):ye(process.cwd(),"src","lib",e)}moduleDir(e,t){return this.isDDD()?ye(process.cwd(),"src","lib","modules",e):ye(process.cwd(),"src","lib",t)}};import{writeFileSync as ps,mkdirSync as hs,existsSync as on}from"fs";import{join as We}from"path";var Je=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");hs(n,{recursive:!0});let a=We(n,`${s}.ts`);if(on(a)){this.warn(`Model ${s} already exists at ${a}`);return}let l=`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
- `;if(ms(a,l),this.success(`Model created: src/lib/modules/${i}/${s}.ts`),t.migration||t.all){let d=`${new Date().toISOString().replace(/[^0-9]/g,"").slice(0,14)}_create_${r}_table`,p=K(process.cwd(),"src","lib","database","migrations");ps(p,{recursive:!0});let h=`import { Migration } from '@beeblock/svelar/database';
192
+ `;ps(a,l);let c=this.isDDD()?`src/lib/modules/${i}`:"src/lib/models";if(this.success(`Model created: ${c}/${s}.ts`),t.migration||t.all){let m=`${new Date().toISOString().replace(/[^0-9]/g,"").slice(0,14)}_create_${r}_table`,h=We(process.cwd(),"src","lib","database","migrations");hs(h,{recursive:!0});let d=`import { Migration } from '@beeblock/svelar/database';
193
193
 
194
194
  export default class Create${s}sTable extends Migration {
195
195
  async up() {
@@ -206,9 +206,9 @@ export default class Create${s}sTable extends Migration {
206
206
  await this.schema.dropTable('${r}');
207
207
  }
208
208
  }
209
- `;ms(K(p,`${d}.ts`),h),this.success(`Migration created: src/lib/database/migrations/${d}.ts`)}if(t.controller||t.resource||t.all){let c=`${s}Controller`,d=K(process.cwd(),"src","lib","modules",i);ps(d,{recursive:!0});let h=t.resource||t.all?this.generateResourceController(s,c):this.generateBasicController(s,c);ms(K(d,`${c}.ts`),h),this.success(`Controller created: src/lib/modules/${i}/${c}.ts`)}}generateResourceController(e,t){return`import { Controller, type RequestEvent } from '@beeblock/svelar/routing';
209
+ `;ps(We(h,`${m}.ts`),d),this.success(`Migration created: src/lib/database/migrations/${m}.ts`)}if(t.controller||t.resource||t.all){let u=`${s}Controller`,m=this.moduleDir(i,"controllers");hs(m,{recursive:!0});let h=t.resource||t.all,d=this.isDDD()?`./${s}.js`:`../models/${s}.js`,b=h?this.generateResourceController(s,u,d):this.generateBasicController(s,u,d);ps(We(m,`${u}.ts`),b);let w=this.isDDD()?`src/lib/modules/${i}`:"src/lib/controllers";this.success(`Controller created: ${w}/${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
- import { ${e} } from './${e}.js';
211
+ import { ${e} } from '${s}';
212
212
 
213
213
  export class ${t} extends Controller {
214
214
  /** GET /api/${this.toSnakeCase(this.pluralize(e))} */
@@ -249,8 +249,8 @@ export class ${t} extends Controller {
249
249
  return this.noContent();
250
250
  }
251
251
  }
252
- `}generateBasicController(e,t){return`import { Controller, type RequestEvent } from '@beeblock/svelar/routing';
253
- import { ${e} } from './${e}.js';
252
+ `}generateBasicController(e,t,s=`./${e}.js`){return`import { Controller, type RequestEvent } from '@beeblock/svelar/routing';
253
+ import { ${e} } from '${s}';
254
254
 
255
255
  export class ${t} extends Controller {
256
256
  async index(event: RequestEvent) {
@@ -258,7 +258,7 @@ 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 xn,mkdirSync as Pn}from"fs";import{join as Nr}from"path";var Je=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=Nr(process.cwd(),"src","lib","database","migrations");Pn(r,{recursive:!0});let n=`${new Date().toISOString().replace(/[^0-9]/g,"").slice(0,14)}_${s}`,a=this.toPascalCase(s),l=t.create??this.detectTableName(s,"create"),c=t.table??this.detectTableName(s,"add"),d;l?d=`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 ln,mkdirSync as cn}from"fs";import{join as Nr}from"path";var Ve=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=Nr(process.cwd(),"src","lib","database","migrations");cn(r,{recursive:!0});let n=`${new Date().toISOString().replace(/[^0-9]/g,"").slice(0,14)}_${s}`,a=this.toPascalCase(s),l=t.create??this.detectTableName(s,"create"),c=t.table??this.detectTableName(s,"add"),u;l?u=`import { Migration } from '@beeblock/svelar/database';
262
262
 
263
263
  export default class ${a} extends Migration {
264
264
  async up() {
@@ -273,7 +273,7 @@ export default class ${a} extends Migration {
273
273
  await this.schema.dropTable('${l}');
274
274
  }
275
275
  }
276
- `:c?d=`import { Migration } from '@beeblock/svelar/database';
276
+ `:c?u=`import { Migration } from '@beeblock/svelar/database';
277
277
 
278
278
  export default class ${a} extends Migration {
279
279
  async up() {
@@ -287,7 +287,7 @@ export default class ${a} extends Migration {
287
287
  await this.schema.dropColumn('${c}', 'new_column');
288
288
  }
289
289
  }
290
- `:d=`import { Migration } from '@beeblock/svelar/database';
290
+ `:u=`import { Migration } from '@beeblock/svelar/database';
291
291
 
292
292
  export default class ${a} extends Migration {
293
293
  async up() {
@@ -298,9 +298,9 @@ export default class ${a} extends Migration {
298
298
  // Reverse the migration
299
299
  }
300
300
  }
301
- `,xn(Nr(r,`${n}.ts`),d),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 Rn,mkdirSync as Sn,existsSync as Tn}from"fs";import{join as Ir}from"path";var Ve=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.warn(`No --module specified. Using "${n}" as module. Consider: --module ${n}`);let a=Ir(process.cwd(),"src","lib","modules",n);Sn(a,{recursive:!0});let l=Ir(a,`${r}.ts`);if(Tn(l)){this.warn(`Controller ${r} already exists.`);return}let c=t.resource?this.generateResourceController(r,t.model):this.generateBasicController(r);Rn(l,c),this.success(`Controller created: src/lib/modules/${n}/${r}.ts`)}generateResourceController(e,t){return`import { Controller, type RequestEvent } from '@beeblock/svelar/routing';
301
+ `,ln(Nr(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 dn,mkdirSync as un,existsSync as mn}from"fs";import{join as pn}from"path";var Qe=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 a=this.moduleDir(n,"controllers");un(a,{recursive:!0});let l=pn(a,`${r}.ts`);if(mn(l)){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);dn(l,u);let m=this.isDDD()?`src/lib/modules/${n}`:"src/lib/controllers";this.success(`Controller created: ${m}/${r}.ts`)}generateResourceController(e,t,s){return`import { Controller, type RequestEvent } from '@beeblock/svelar/routing';
302
302
  import { z } from '@beeblock/svelar/validation';
303
- ${t?`import { ${t} } from './${t}.js';
303
+ ${t&&s?`import { ${t} } from '${s}';
304
304
  `:""}
305
305
  export class ${e} extends Controller {
306
306
  async index(event: RequestEvent) {
@@ -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 En,mkdirSync as kn,existsSync as $n}from"fs";import{join as _r}from"path";var Qe=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=_r(process.cwd(),"src","lib","shared","middleware");kn(r,{recursive:!0});let i=_r(r,`${s}.ts`);if($n(i)){this.warn(`Middleware ${s} already exists.`);return}let n=`import { Middleware, type MiddlewareContext, type NextFunction } from '@beeblock/svelar/middleware';
347
+ `}};import{writeFileSync as hn,mkdirSync as gn,existsSync as fn}from"fs";import{join as bn}from"path";var Ge=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=bn(r,`${s}.ts`);if(fn(i)){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
- `;En(i,n),this.success(`Middleware created: src/lib/shared/middleware/${s}.ts`)}};import{writeFileSync as An,mkdirSync as Dn,existsSync as Ln}from"fs";import{join as jr}from"path";var Ge=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=jr(process.cwd(),"src","lib","shared","providers");Dn(r,{recursive:!0});let i=jr(r,`${s}.ts`);if(Ln(i)){this.warn(`Provider ${s} already exists.`);return}let n=`import { ServiceProvider } from '@beeblock/svelar/container';
360
+ `;hn(i,n);let a=this.isDDD()?`src/lib/shared/middleware/${s}.ts`:`src/lib/middleware/${s}.ts`;this.success(`Middleware created: ${a}`)}};import{writeFileSync as yn,mkdirSync as vn,existsSync as wn}from"fs";import{join as Cn}from"path";var Ye=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");vn(r,{recursive:!0});let i=Cn(r,`${s}.ts`);if(wn(i)){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
- `;An(i,n),this.success(`Provider created: src/lib/shared/providers/${s}.ts`)}};import{writeFileSync as Mn,mkdirSync as Nn,existsSync as In}from"fs";import{join as Or}from"path";var Ye=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=Or(process.cwd(),"src","lib","database","seeders");Nn(r,{recursive:!0});let i=Or(r,`${s}.ts`);if(In(i)){this.warn(`Seeder ${s} already exists.`);return}let n=`import { Seeder } from '@beeblock/svelar/database';
381
+ `;yn(i,n);let a=this.isDDD()?`src/lib/shared/providers/${s}.ts`:`src/lib/providers/${s}.ts`;this.success(`Provider created: ${a}`)}};import{writeFileSync as xn,mkdirSync as Sn,existsSync as Pn}from"fs";import{join as Ir}from"path";var Ze=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=Ir(process.cwd(),"src","lib","database","seeders");Sn(r,{recursive:!0});let i=Ir(r,`${s}.ts`);if(Pn(i)){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,15 +387,15 @@ export class ${s} extends Seeder {
387
387
  // await User.create({ name: 'Admin', email: 'admin@example.com' });
388
388
  }
389
389
  }
390
- `;Mn(i,n),this.success(`Seeder created: src/lib/database/seeders/${s}.ts`)}};import{writeFileSync as _n,mkdirSync as jn,existsSync as On}from"fs";import{join as qr}from"path";var Ze=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.warn(`No --module specified. Using "${n}" as module. Consider: --module ${n}`);let a=qr(process.cwd(),"src","lib","modules",n);jn(a,{recursive:!0});let l=qr(a,`${r}.ts`);if(On(l)){this.warn(`Service ${r} already exists.`);return}let c=t.crud?this.generateCrudService(r,t.model):this.generateBasicService(r);_n(l,c),this.success(`Service created: src/lib/modules/${n}/${r}.ts`)}generateCrudService(e,t){let s=t||"Model";return`import { CrudService, type ServiceResult } from '@beeblock/svelar/services';
391
- import { ${s} } from './${s}.js';
390
+ `;xn(i,n),this.success(`Seeder created: src/lib/database/seeders/${s}.ts`)}};import{writeFileSync as Rn,mkdirSync as Tn,existsSync as En}from"fs";import{join as kn}from"path";var Xe=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 a=this.moduleDir(n,"services");Tn(a,{recursive:!0});let l=kn(a,`${r}.ts`);if(En(l)){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);Rn(l,u);let m=this.isDDD()?`src/lib/modules/${n}`:"src/lib/services";this.success(`Service created: ${m}/${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}';
392
392
 
393
- export class ${e} extends CrudService<${s}> {
394
- protected model = ${s};
393
+ export class ${e} extends CrudService<${r}> {
394
+ protected model = ${r};
395
395
 
396
396
  // Override or add custom methods:
397
- // async findByEmail(email: string): Promise<ServiceResult<${s}>> {
398
- // const record = await ${s}.where('email', email).first();
397
+ // async findByEmail(email: string): Promise<ServiceResult<${r}>> {
398
+ // const record = await ${r}.where('email', email).first();
399
399
  // if (!record) return this.fail('Not found');
400
400
  // return this.ok(record);
401
401
  // }
@@ -412,8 +412,8 @@ export class ${e} extends Service {
412
412
  }
413
413
  }
414
414
  }
415
- `}};import{writeFileSync as qn,mkdirSync as Un,existsSync as Fn}from"fs";import{join as Ur}from"path";var Xe=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.warn(`No --module specified. Using "${n}" as module. Consider: --module ${n}`);let a=Ur(process.cwd(),"src","lib","modules",n);Un(a,{recursive:!0});let l=Ur(a,`${r}.ts`);if(Fn(l)){this.warn(`Repository ${r} already exists.`);return}let c=t.model||this.inferModelName(r),d=`import { Repository } from '@beeblock/svelar/repositories';
416
- import { ${c} } from './${c}.js';
415
+ `}};import{writeFileSync as $n,mkdirSync as Dn,existsSync as An}from"fs";import{join as Mn}from"path";var et=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 a=this.moduleDir(n,"repositories");Dn(a,{recursive:!0});let l=Mn(a,`${r}.ts`);if(An(l)){this.warn(`Repository ${r} already exists.`);return}let c=t.model||this.inferModelName(r),u=this.isDDD()?`./${c}.js`:`../models/${c}.js`,m=`import { Repository } from '@beeblock/svelar/repositories';
416
+ import { ${c} } from '${u}';
417
417
 
418
418
  export class ${r} extends Repository<${c}> {
419
419
  model() {
@@ -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
- `;qn(l,d),this.success(`Repository created: src/lib/modules/${n}/${r}.ts`)}inferModelName(e){return e.replace("Repository","")||"Model"}};import{writeFileSync as Bn,mkdirSync as Hn,existsSync as zn}from"fs";import{join as Fr}from"path";var et=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.warn(`No --module specified. Using "${n}" as module. Consider: --module ${n}`);let a=Fr(process.cwd(),"src","lib","modules",n);Hn(a,{recursive:!0});let l=Fr(a,`${r}.ts`);if(zn(l)){this.warn(`Action ${r} already exists.`);return}let c=`import { Action } from '@beeblock/svelar/actions';
432
+ `;$n(l,m);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 Ln,mkdirSync as _n,existsSync as Nn}from"fs";import{join as In}from"path";var tt=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 a=this.moduleDir(n,"actions");_n(a,{recursive:!0});let l=In(a,`${r}.ts`);if(Nn(l)){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
- `;Bn(l,c),this.success(`Action created: src/lib/modules/${n}/${r}.ts`)}};import{writeFileSync as Kn,mkdirSync as Wn,existsSync as Jn}from"fs";import{join as Br}from"path";var tt=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.warn(`No --module specified. Using "${n}" as module. Consider: --module ${n}`);let a=Br(process.cwd(),"src","lib","modules",n);Wn(a,{recursive:!0});let l=Br(a,`${r}.ts`);if(Jn(l)){this.warn(`Request ${r} already exists.`);return}let c=`import { FormRequest } from '@beeblock/svelar/routing';
448
+ `;Ln(l,c);let u=this.isDDD()?`src/lib/modules/${n}`:"src/lib/actions";this.success(`Action created: ${u}/${r}.ts`)}};import{writeFileSync as jn,mkdirSync as On,existsSync as qn}from"fs";import{join as Un}from"path";var st=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 a=this.moduleDir(n,"dtos");On(a,{recursive:!0});let l=Un(a,`${r}.ts`);if(qn(l)){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
- `;Kn(l,c),this.success(`Request created: src/lib/modules/${n}/${r}.ts`)}};import{writeFileSync as Vn,mkdirSync as Qn,existsSync as Gn}from"fs";import{join as Hr}from"path";var st=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=Hr(process.cwd(),"src","lib","shared","plugins");Qn(r,{recursive:!0});let i=Hr(r,`${s}.ts`);if(Gn(i)){this.warn(`Plugin ${s} already exists.`);return}let n=s.replace(/([A-Z])/g,"-$1").toLowerCase().replace(/^-/,""),a=`import { Plugin } from '@beeblock/svelar/plugins';
477
+ `;jn(l,c);let u=this.isDDD()?`src/lib/modules/${n}`:"src/lib/dtos";this.success(`Request created: ${u}/${r}.ts`)}};import{writeFileSync as Bn,mkdirSync as Fn,existsSync as Hn}from"fs";import{join as zn}from"path";var rt=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");Fn(r,{recursive:!0});let i=zn(r,`${s}.ts`);if(Hn(i)){this.warn(`Plugin ${s} already exists.`);return}let n=s.replace(/([A-Z])/g,"-$1").toLowerCase().replace(/^-/,""),a=`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
- `;Vn(i,a),this.success(`Plugin created: src/lib/shared/plugins/${s}.ts`)}};import{writeFileSync as Yn,mkdirSync as Zn,existsSync as Xn}from"fs";import{join as zr}from"path";var rt=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=zr(process.cwd(),"src","lib","shared","scheduler");Zn(r,{recursive:!0});let i=zr(r,`${s}.ts`);if(Xn(i)){this.warn(`Task ${s} already exists.`);return}let n=`import { ScheduledTask } from '@beeblock/svelar/scheduler';
499
+ `;Bn(i,a);let l=this.isDDD()?`src/lib/shared/plugins/${s}.ts`:`src/lib/plugins/${s}.ts`;this.success(`Plugin created: ${l}`)}};import{writeFileSync as Kn,mkdirSync as Wn,existsSync as Jn}from"fs";import{join as Vn}from"path";var it=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");Wn(r,{recursive:!0});let i=Vn(r,`${s}.ts`);if(Jn(i)){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,15 +529,18 @@ export class ${s} extends ScheduledTask {
529
529
  console.error('${s} failed:', error.message);
530
530
  }
531
531
  }
532
- `;Yn(i,n),this.success(`Scheduled task created: src/lib/shared/scheduler/${s}.ts`)}toKebabCase(e){return e.replace(/([A-Z])/g,"-$1").toLowerCase().replace(/^-/,"")}};import{writeFileSync as ea,mkdirSync as ta,existsSync as sa}from"fs";import{join as Kr}from"path";var it=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=Kr(process.cwd(),"src","lib","shared","jobs");ta(r,{recursive:!0});let i=Kr(r,`${s}.ts`);if(sa(i)){this.warn(`Job ${s} already exists.`);return}let n=`import { Job } from '@beeblock/svelar/queue';
532
+ `;Kn(i,n);let a=this.isDDD()?`src/lib/shared/scheduler/${s}.ts`:`src/lib/scheduler/${s}.ts`;this.success(`Scheduled task created: ${a}`)}toKebabCase(e){return e.replace(/([A-Z])/g,"-$1").toLowerCase().replace(/^-/,"")}};import{writeFileSync as Qn,mkdirSync as Gn,existsSync as Yn}from"fs";import{join as Zn}from"path";var nt=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");Gn(r,{recursive:!0});let i=Zn(r,`${s}.ts`);if(Yn(i)){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
536
536
  retryDelay = 60; // Wait 60 seconds between retries
537
537
  queue = 'default'; // Queue name
538
538
 
539
- constructor(private data: any) {
539
+ data: any;
540
+
541
+ constructor(data: any) {
540
542
  super();
543
+ this.data = data;
541
544
  }
542
545
 
543
546
  async handle(): Promise<void> {
@@ -553,7 +556,7 @@ export class ${s} extends Job {
553
556
  console.log('${s} retrying, attempt', attempt);
554
557
  }
555
558
  }
556
- `;ea(i,n),this.success(`Job created: src/lib/shared/jobs/${s}.ts`)}};import{writeFileSync as ra,mkdirSync as ia,existsSync as na}from"fs";import{join as Wr}from"path";var nt=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=Wr(process.cwd(),"src","lib","shared","commands");ia(i,{recursive:!0});let n=Wr(i,`${r}.ts`);if(na(n)){this.warn(`Command ${r} already exists.`);return}let a=t.command??this.deriveCommandName(r),l=`import { Command } from '@beeblock/svelar/cli';
559
+ `;Qn(i,n);let a=this.isDDD()?`src/lib/shared/jobs/${s}.ts`:`src/lib/jobs/${s}.ts`;this.success(`Job created: ${a}`)}};import{writeFileSync as Xn,mkdirSync as ea,existsSync as ta}from"fs";import{join as sa}from"path";var at=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");ea(i,{recursive:!0});let n=sa(i,`${r}.ts`);if(ta(n)){this.warn(`Command ${r} already exists.`);return}let a=t.command??this.deriveCommandName(r),l=`import { Command } from '@beeblock/svelar/cli';
557
560
 
558
561
  export class ${r} extends Command {
559
562
  name = '${a}';
@@ -576,7 +579,7 @@ export class ${r} extends Command {
576
579
  this.success('Done!');
577
580
  }
578
581
  }
579
- `;ra(n,l),this.success(`Command created: src/lib/shared/commands/${r}.ts`),this.info(`Command name: ${a}`),this.newLine(),this.info("Your command will be auto-discovered. Run it with:"),this.log(` npx svelar ${a}`)}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 aa,mkdirSync as oa,existsSync as la}from"fs";import{join as Jr}from"path";var at=class extends g{name="make:config";description="Create a new config file";arguments=["name"];flags=[];templates={app:`import { env } from 'svelar/config';
582
+ `;Xn(n,l);let c=this.isDDD()?`src/lib/shared/commands/${r}.ts`:`src/lib/commands/${r}.ts`;this.success(`Command created: ${c}`),this.info(`Command name: ${a}`),this.newLine(),this.info("Your command will be auto-discovered. Run it with:"),this.log(` npx svelar ${a}`)}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 ra,mkdirSync as ia,existsSync as na}from"fs";import{join as jr}from"path";var ot=class extends g{name="make:config";description="Create a new config file";arguments=["name"];flags=[];templates={app:`import { env } from 'svelar/config';
580
583
 
581
584
  export default {
582
585
  name: env('APP_NAME', 'Svelar'),
@@ -785,7 +788,7 @@ export default {
785
788
  },
786
789
  },
787
790
  };
788
- `};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=Jr(process.cwd(),"config");oa(s,{recursive:!0});let r=t.toLowerCase().replace(/\s+/g,"-"),i=Jr(s,`${r}.ts`);if(la(i)){this.warn(`Config file config/${r}.ts already exists.`);return}let n=this.templates[r]??this.blankTemplate(r);aa(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=jr(process.cwd(),"config");ia(s,{recursive:!0});let r=t.toLowerCase().replace(/\s+/g,"-"),i=jr(s,`${r}.ts`);if(na(i)){this.warn(`Config file config/${r}.ts already exists.`);return}let n=this.templates[r]??this.blankTemplate(r);ra(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';
789
792
 
790
793
  export default {
791
794
  // Add your ${e} configuration here
@@ -794,7 +797,7 @@ export default {
794
797
  // env<number>('MY_PORT', 3000)
795
798
  // env<boolean>('MY_FLAG', false)
796
799
  };
797
- `}};import{writeFileSync as ca,mkdirSync as da,existsSync as ua}from"fs";import{join as Vr}from"path";var ot=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=Vr(process.cwd(),"src","lib","shared","channels");da(i,{recursive:!0});let n=Vr(i,`${r}.ts`);if(ua(n)){this.warn(`Channel ${r} already exists.`);return}let a=r.replace(/Channel$/,""),l=a.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),c=a.charAt(0).toLowerCase()+a.slice(1)+"Id",d=t.presence,h=`${d?"presence":"private"}-${l}.{${c}}`,u=d?this.presenceTemplate(r,h,c):this.privateTemplate(r,h,c);ca(n,u),this.success(`Channel created: src/lib/shared/channels/${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 './lib/shared/channels/${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 aa,mkdirSync as oa,existsSync as la}from"fs";import{join as ca}from"path";var lt=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");oa(i,{recursive:!0});let n=ca(i,`${r}.ts`);if(la(n)){this.warn(`Channel ${r} already exists.`);return}let a=r.replace(/Channel$/,""),l=a.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),c=a.charAt(0).toLowerCase()+a.slice(1)+"Id",u=t.presence,h=`${u?"presence":"private"}-${l}.{${c}}`,d=u?this.presenceTemplate(r,h,c):this.privateTemplate(r,h,c);aa(n,d);let b=this.isDDD()?"src/lib/shared/channels":"src/lib/channels";this.success(`Channel created: ${b}/${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 './${b.replace("src/","")}/${r}.js';`),this.log(` register${r}();`)}privateTemplate(e,t,s){let r=e.replace(/Channel$/,"");return`import { Broadcast } from '@beeblock/svelar/broadcasting';
798
801
 
799
802
  /**
800
803
  * ${e}
@@ -837,7 +840,7 @@ export function register${e}(): void {
837
840
  };
838
841
  });
839
842
  }
840
- `}};import{writeFileSync as ma,mkdirSync as pa,existsSync as ha}from"fs";import{join as ve}from"path";var lt=class extends g{name="make:docker";description="Scaffold Docker deployment files (Dockerfile, docker-compose.yml, PM2 config)";arguments=[];flags=[{name:"db",alias:"d",description:"Database driver: postgres, mysql, sqlite (default: postgres)",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,a=t.gotenberg??!0,l=t.rustfs??!0,c=t.meilisearch??!1,d=t.force??!1,p=["postgres","mysql","sqlite"];if(!p.includes(r)){this.error(`Unknown database driver: ${r}. Use one of: ${p.join(", ")}`);return}let h=[{path:ve(s,"Dockerfile"),content:this.dockerfileTemplate(),label:"Dockerfile"},{path:ve(s,"docker-compose.yml"),content:this.composeTemplate(r,i,n,a,l,c),label:"docker-compose.yml"},{path:ve(s,".dockerignore"),content:this.dockerignoreTemplate(),label:".dockerignore"},{path:ve(s,"ecosystem.config.cjs"),content:this.pm2Template(),label:"ecosystem.config.cjs"}],u=0,v=0;for(let x of h){if(ha(x.path)&&!d){this.warn(`${x.label} already exists (use --force to overwrite)`),v++;continue}ma(x.path,x.content),this.success(`Created ${x.label}`),u++}if(r!=="sqlite"){let x=ve(s,"docker");pa(x,{recursive:!0})}this.newLine(),u>0?this.info(`${u} file(s) created${v>0?`, ${v} skipped`:""}`):this.info("No files created (all exist already)"),this.newLine(),this.info("Quick start:"),this.log(" # Build and start all services"),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(" docker compose logs -f app"),this.newLine(),this.log(" # Stop services"),this.log(" docker compose down"),this.newLine(),this.info("Make sure to update .env with production values before deploying.")}dockerfileTemplate(){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 da,mkdirSync as ua,existsSync as ma}from"fs";import{join as ve}from"path";var ct=class extends g{name="make:docker";description="Scaffold Docker deployment files (Dockerfile, docker-compose.yml, PM2 config)";arguments=[];flags=[{name:"db",alias:"d",description:"Database driver: postgres, mysql, sqlite (default: postgres)",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,a=t.gotenberg??!0,l=t.rustfs??!0,c=t.meilisearch??!1,u=t.force??!1,m=["postgres","mysql","sqlite"];if(!m.includes(r)){this.error(`Unknown database driver: ${r}. Use one of: ${m.join(", ")}`);return}let h=[{path:ve(s,"Dockerfile"),content:this.dockerfileTemplate(),label:"Dockerfile"},{path:ve(s,"docker-compose.yml"),content:this.composeTemplate(r,i,n,a,l,c),label:"docker-compose.yml"},{path:ve(s,".dockerignore"),content:this.dockerignoreTemplate(),label:".dockerignore"},{path:ve(s,"ecosystem.config.cjs"),content:this.pm2Template(),label:"ecosystem.config.cjs"}],d=0,b=0;for(let w of h){if(ma(w.path)&&!u){this.warn(`${w.label} already exists (use --force to overwrite)`),b++;continue}da(w.path,w.content),this.success(`Created ${w.label}`),d++}if(r!=="sqlite"){let w=ve(s,"docker");ua(w,{recursive:!0})}this.newLine(),d>0?this.info(`${d} file(s) created${b>0?`, ${b} skipped`:""}`):this.info("No files created (all exist already)"),this.newLine(),this.info("Quick start:"),this.log(" # Build and start all services"),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(" docker compose logs -f app"),this.newLine(),this.log(" # Stop services"),this.log(" docker compose down"),this.newLine(),this.info("Make sure to update .env with production values before deploying.")}dockerfileTemplate(){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
841
844
  # Multi-stage build for a lean production image.
842
845
 
843
846
  # Stage 1: Install dependencies & build
@@ -1013,7 +1016,7 @@ module.exports = {
1013
1016
  },
1014
1017
  ],
1015
1018
  };
1016
- `}};import{writeFileSync as ga,mkdirSync as fa,existsSync as Qr}from"fs";import{join as I}from"path";var ct=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,a=!i&&!n,l=[];(a||n)&&l.push({path:I(s,"src/routes/api/broadcasting/auth/+server.ts"),content:this.pusherAuthRoute(),label:"src/routes/api/broadcasting/auth/+server.ts",dirs:[I(s,"src/routes/api/broadcasting/auth")]}),(a||i)&&l.push({path:I(s,"src/routes/api/broadcasting/[channel]/+server.ts"),content:this.sseRoute(),label:"src/routes/api/broadcasting/[channel]/+server.ts",dirs:[I(s,"src/routes/api/broadcasting/[channel]")]}),l.push({path:I(s,"src/lib/broadcasting.ts"),content:a||n?this.clientPusher():this.clientSSE(),label:"src/lib/broadcasting.ts",dirs:[I(s,"src/lib")]});let c=I(s,"config/broadcasting.ts");Qr(c)||l.push({path:c,content:this.configTemplate(),label:"config/broadcasting.ts",dirs:[I(s,"config")]});let d=0,p=0;for(let h of l){if(Qr(h.path)&&!r){this.warn(`${h.label} already exists (use --force to overwrite)`),p++;continue}for(let u of h.dirs)fa(u,{recursive:!0});ga(h.path,h.content),this.success(`Created ${h.label}`),d++}this.newLine(),d>0?this.info(`${d} file(s) created${p>0?`, ${p} skipped`:""}`):this.info("No files created (all exist already)"),this.newLine(),this.info("Next steps:"),a||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`/**
1019
+ `}};import{writeFileSync as pa,mkdirSync as ha,existsSync as Or}from"fs";import{join as N}from"path";var dt=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,a=!i&&!n,l=[];(a||n)&&l.push({path:N(s,"src/routes/api/broadcasting/auth/+server.ts"),content:this.pusherAuthRoute(),label:"src/routes/api/broadcasting/auth/+server.ts",dirs:[N(s,"src/routes/api/broadcasting/auth")]}),(a||i)&&l.push({path:N(s,"src/routes/api/broadcasting/[channel]/+server.ts"),content:this.sseRoute(),label:"src/routes/api/broadcasting/[channel]/+server.ts",dirs:[N(s,"src/routes/api/broadcasting/[channel]")]}),l.push({path:N(s,"src/lib/broadcasting.ts"),content:a||n?this.clientPusher():this.clientSSE(),label:"src/lib/broadcasting.ts",dirs:[N(s,"src/lib")]});let c=N(s,"config/broadcasting.ts");Or(c)||l.push({path:c,content:this.configTemplate(),label:"config/broadcasting.ts",dirs:[N(s,"config")]});let u=0,m=0;for(let h of l){if(Or(h.path)&&!r){this.warn(`${h.label} already exists (use --force to overwrite)`),m++;continue}for(let d of h.dirs)ha(d,{recursive:!0});pa(h.path,h.content),this.success(`Created ${h.label}`),u++}this.newLine(),u>0?this.info(`${u} file(s) created${m>0?`, ${m} skipped`:""}`):this.info("No files created (all exist already)"),this.newLine(),this.info("Next steps:"),a||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`/**
1017
1020
  * Pusher/Soketi Channel Authorization Endpoint
1018
1021
  *
1019
1022
  * This route authenticates channel subscriptions from pusher-js.
@@ -1167,16 +1170,16 @@ export default {
1167
1170
  },
1168
1171
  },
1169
1172
  };
1170
- `}};import{writeFileSync as Gr,mkdirSync as ya,existsSync as Yr}from"fs";import{join as hs}from"path";var dt=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.warn(`No --module specified, using "${i}". Use --module=<name> to target a specific module.`);let n=hs(process.cwd(),"src","lib","modules",i);ya(n,{recursive:!0});let a=hs(n,`${r}.ts`);if(Yr(a)){this.warn(`Resource ${r} already exists.`);return}let l=t.model||this.inferModelName(r),c=this.generateResource(r,l);if(Gr(a,c),this.success(`Resource created: src/lib/modules/${i}/${r}.ts`),t.collection){let d=r.replace("Resource","CollectionResource"),p=hs(n,`${d}.ts`);if(!Yr(p)){let h=this.generateCollectionResource(d,r,l);Gr(p,h),this.success(`Collection resource created: src/lib/modules/${i}/${d}.ts`)}}}generateResource(e,t){let s=`${t}Data`;return`import { Resource } from '@beeblock/svelar/routing';
1171
- import type { ${t} } from './${t}.js';
1173
+ `}};import{writeFileSync as qr,mkdirSync as ga,existsSync as Ur}from"fs";import{join as Br}from"path";var ut=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 a=Br(n,`${r}.ts`);if(Ur(a)){this.warn(`Resource ${r} already exists.`);return}let l=t.model||this.inferModelName(r),c=this.isDDD()?`./${l}.js`:`../models/${l}.js`,u=this.generateResource(r,l,c);qr(a,u);let m=this.isDDD()?`src/lib/modules/${i}`:"src/lib/resources";if(this.success(`Resource created: ${m}/${r}.ts`),t.collection){let h=r.replace("Resource","CollectionResource"),d=Br(n,`${h}.ts`);if(!Ur(d)){let b=this.isDDD()?`./${l}.js`:`../models/${l}.js`,w=this.generateCollectionResource(h,r,l,b);qr(d,w);let E=this.isDDD()?`src/lib/modules/${i}`:"src/lib/resources";this.success(`Collection resource created: ${E}/${h}.ts`)}}}generateResource(e,t,s=`./${t}.js`){let r=`${t}Data`;return`import { Resource } from '@beeblock/svelar/routing';
1174
+ import type { ${t} } from '${s}';
1172
1175
 
1173
1176
  // \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
1174
1177
  // Define the shape once \u2014 import this type on the frontend.
1175
1178
  //
1176
- // import type { ${s} } from '$lib/modules/.../${e}';
1179
+ // import type { ${r} } from '$lib/modules/.../${e}';
1177
1180
  //
1178
1181
 
1179
- export interface ${s} {
1182
+ export interface ${r} {
1180
1183
  id: number;
1181
1184
  // Add your fields here
1182
1185
  // name: string;
@@ -1186,8 +1189,8 @@ export interface ${s} {
1186
1189
 
1187
1190
  // \u2500\u2500 Resource \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
1188
1191
 
1189
- export class ${e} extends Resource<${t}, ${s}> {
1190
- toJSON(): ${s} {
1192
+ export class ${e} extends Resource<${t}, ${r}> {
1193
+ toJSON(): ${r} {
1191
1194
  return {
1192
1195
  id: this.data.id,
1193
1196
  // Map model fields to the API contract
@@ -1213,9 +1216,9 @@ export class ${e} extends Resource<${t}, ${s}> {
1213
1216
  // return { comments_count: this.data.comments_count ?? 0 };
1214
1217
  // }
1215
1218
  }
1216
- `}generateCollectionResource(e,t,s){return`import { Resource } from '@beeblock/svelar/routing';
1219
+ `}generateCollectionResource(e,t,s,r=`./${s}.js`){return`import { Resource } from '@beeblock/svelar/routing';
1217
1220
  import { ${t} } from './${t}.js';
1218
- import type { ${s} } from './${s}.js';
1221
+ import type { ${s} } from '${r}';
1219
1222
 
1220
1223
  /**
1221
1224
  * ${e}
@@ -1245,7 +1248,7 @@ export class ${e} {
1245
1248
  .toObject();
1246
1249
  }
1247
1250
  }
1248
- `}deriveModuleName(e){return e.replace(/Resource$/,"").replace(/Collection$/,"").toLowerCase()}inferModelName(e){return e.replace(/Resource$/,"")||"Model"}};import{writeFileSync as ba,mkdirSync as va,existsSync as wa}from"fs";import{join as Zr}from"path";var ut=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(),a=Zr(process.cwd(),"src","lib","modules",n);va(a,{recursive:!0});let l=Zr(a,`${i}.ts`);if(wa(l)){this.warn(`Schema already exists: src/lib/modules/${n}/${i}.ts`);return}let c=this.generateSchema(r);ba(l,c),this.success(`Schema created: src/lib/modules/${n}/${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`),this.info(` Frontend: import type { ${r}Data } from '$lib/modules/${n}/${i}'`)}generateSchema(e){let t=e.charAt(0).toLowerCase()+e.slice(1),s=this.toKebab(e);return`import { z } from 'zod';
1251
+ `}deriveModuleName(e){return e.replace(/Resource$/,"").replace(/Collection$/,"").toLowerCase()}inferModelName(e){return e.replace(/Resource$/,"")||"Model"}};import{writeFileSync as fa,mkdirSync as ba,existsSync as ya}from"fs";import{join as va}from"path";var mt=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(),a=this.moduleDir(n,"schemas");ba(a,{recursive:!0});let l=va(a,`${i}.ts`);if(ya(l)){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(l,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 m=this.isDDD()?`$lib/modules/${n}/${i}`:`$lib/schemas/${i}`;this.info(` Frontend: import type { ${r}Data } from '${m}'`)}generateSchema(e){let t=e.charAt(0).toLowerCase()+e.slice(1),s=this.toKebab(e);return`import { z } from 'zod';
1249
1252
 
1250
1253
  // \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
1251
1254
  //
@@ -1280,8 +1283,8 @@ export const update${e}Schema = create${e}Schema.partial();
1280
1283
  export type ${e}Data = z.infer<typeof ${t}Schema>;
1281
1284
  export type Create${e}Input = z.infer<typeof create${e}Schema>;
1282
1285
  export type Update${e}Input = z.infer<typeof update${e}Schema>;
1283
- `}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 Ca,mkdirSync as xa,existsSync as Pa}from"fs";import{join as Xr}from"path";var mt=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=Xr(process.cwd(),"src","lib","modules",i);xa(n,{recursive:!0});let a=Xr(n,`${s}.ts`);if(Pa(a)){this.warn(`Observer ${s} already exists at ${a}`);return}let l=`import { ModelObserver } from '@beeblock/svelar/orm';
1284
- import type { ${r} } from './${r}.js';
1286
+ `}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 pt=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 a=Sa(n,`${s}.ts`);if(xa(a)){this.warn(`Observer ${s} already exists at ${a}`);return}let l=this.isDDD()?`./${r}.js`:`../models/${r}.js`,c=`import { ModelObserver } from '@beeblock/svelar/orm';
1287
+ import type { ${r} } from '${l}';
1285
1288
 
1286
1289
  export class ${s} extends ModelObserver {
1287
1290
  // Fires before a new ${r} is inserted
@@ -1318,7 +1321,7 @@ export class ${s} extends ModelObserver {
1318
1321
  // async deleted(${r.toLowerCase()}: ${r}) {
1319
1322
  // }
1320
1323
  }
1321
- `;Ca(a,l),this.success(`Observer created: src/lib/modules/${i}/${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 Ra,mkdirSync as Sa,existsSync as Ta}from"fs";import{join as ei}from"path";var pt=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.warn(`No --module specified. Using "${r}" as module. Consider: --module ${r}`);let i=ei(process.cwd(),"src","lib","modules",r);Sa(i,{recursive:!0});let n=ei(i,`${s}.ts`);if(Ta(n)){this.warn(`Event ${s} already exists at ${n}`);return}let a=`/**
1324
+ `;wa(a,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 Ta}from"fs";import{join as Ea}from"path";var ht=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=Ea(i,`${s}.ts`);if(Ta(n)){this.warn(`Event ${s} already exists at ${n}`);return}let a=`/**
1322
1325
  * ${s} Event
1323
1326
  *
1324
1327
  * Dispatched when ... (describe when this event fires).
@@ -1336,30 +1339,30 @@ export class ${s} {
1336
1339
  // public readonly metadata?: Record<string, any>,
1337
1340
  ) {}
1338
1341
  }
1339
- `;Ra(n,a),this.success(`Event created: src/lib/modules/${r}/${s}.ts`)}};import{writeFileSync as Ea,mkdirSync as ka,existsSync as $a}from"fs";import{join as ti}from"path";var ht=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.warn(`No --module specified. Using "${r}" as module. Consider: --module ${r}`);let i=ti(process.cwd(),"src","lib","modules",r);ka(i,{recursive:!0});let n=ti(i,`${s}.ts`);if($a(n)){this.warn(`Listener ${s} already exists at ${n}`);return}let a=t.event||"any",l=t.event?`import type { ${t.event} } from './${t.event}.js';
1342
+ `;Pa(n,a);let l=this.isDDD()?`src/lib/modules/${r}`:"src/lib/events";this.success(`Event created: ${l}/${s}.ts`)}};import{writeFileSync as ka,mkdirSync as $a,existsSync as Da}from"fs";import{join as Aa}from"path";var gt=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 a=t.event||"any",l=t.event?this.isDDD()?`./${t.event}.js`:`../events/${t.event}.js`:"",c=t.event?`import type { ${t.event} } from '${l}';
1340
1343
 
1341
- `:"",c=t.event||"any",d=`import { Listener } from '@beeblock/svelar/events';
1342
- ${l}export class ${s} extends Listener<${c}> {
1343
- async handle(event: ${c}): Promise<void> {
1344
+ `:"",u=t.event||"any",m=`import { Listener } from '@beeblock/svelar/events';
1345
+ ${c}export class ${s} extends Listener<${u}> {
1346
+ async handle(event: ${u}): Promise<void> {
1344
1347
  // Handle the event
1345
1348
  // e.g. await Mail.to(event.user.email).send(new WelcomeEmail());
1346
1349
  }
1347
1350
 
1348
1351
  // Optionally filter which events to handle:
1349
- // shouldHandle(event: ${c}): boolean {
1352
+ // shouldHandle(event: ${u}): boolean {
1350
1353
  // return true;
1351
1354
  // }
1352
1355
  }
1353
- `;Ea(n,d),this.success(`Listener created: src/lib/modules/${r}/${s}.ts`),t.event&&(this.info("Don't forget to register it in your EventServiceProvider:"),this.info(` [${t.event}.name]: [${s}]`))}};import{writeFileSync as Aa,mkdirSync as Da,existsSync as La}from"fs";import{join as si}from"path";var gt=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(a=>a.trim().toUpperCase()):["GET"]).map(a=>({method:a,handler:this.defaultHandler(a)}));this.generateRouteFile(e,t,s,n)}generateRouteFile(e,t,s,r){let i=si(process.cwd(),"src","routes",...e.split("/"));Da(i,{recursive:!0});let n=si(i,"+server.ts");if(La(n)){this.warn(`Route already exists: src/routes/${e}/+server.ts (skipped)`);return}let a=`$lib/modules/${s}/${t}.js`,l=r.map(d=>`export const ${d.method} = ctrl.handle('${d.handler}');`).join(`
1356
+ `;ka(n,m);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 Ma,mkdirSync as La,existsSync as _a}from"fs";import{join as Fr}from"path";var ft=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(a=>a.trim().toUpperCase()):["GET"]).map(a=>({method:a,handler:this.defaultHandler(a)}));this.generateRouteFile(e,t,s,n)}generateRouteFile(e,t,s,r){let i=Fr(process.cwd(),"src","routes",...e.split("/"));La(i,{recursive:!0});let n=Fr(i,"+server.ts");if(_a(n)){this.warn(`Route already exists: src/routes/${e}/+server.ts (skipped)`);return}let a=this.isDDD()?`$lib/modules/${s}/${t}.js`:`$lib/controllers/${t}.js`,l=r.map(u=>`export const ${u.method} = ctrl.handle('${u.handler}');`).join(`
1354
1357
  `),c=`import { ${t} } from '${a}';
1355
1358
 
1356
1359
  const ctrl = new ${t}();
1357
1360
  ${l}
1358
- `;Aa(n,c),this.success(`Route created: src/routes/${e}/+server.ts`);for(let d of r)this.info(` ${d.method} /${e} \u2192 ${t}.${d.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 ri,relative as gs,sep as fs}from"path";import{existsSync as Ma,readdirSync as Na,readFileSync as ii,statSync as Ia}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=ri(process.cwd(),"src","routes");if(!Ma(s)){this.error("No src/routes/ directory found.");return}let i=this.scanRoutes(s,s);if(t.api&&(i=i.filter(d=>d.path.startsWith("/api"))),t.method){let d=t.method.toUpperCase();i=i.filter(p=>p.method===d)}if(i.sort((d,p)=>d.path.localeCompare(p.path)||d.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)
1359
- `);let n=Math.max(6,...i.map(d=>d.method.length)),a=Math.max(4,...i.map(d=>d.path.length)),l=Math.max(7,...i.map(d=>d.handler.length)),c=` ${"METHOD".padEnd(n)} ${"PATH".padEnd(a)} ${"HANDLER".padEnd(l)} FILE`;this.log(`\x1B[2m${c}\x1B[0m`),this.log(`\x1B[2m ${"\u2500".repeat(n)} ${"\u2500".repeat(a)} ${"\u2500".repeat(l)} ${"\u2500".repeat(20)}\x1B[0m`);for(let d of i){let h=`${this.getMethodColor(d.method)}${d.method.padEnd(n)}\x1B[0m`,u=d.path.padEnd(a),v=`\x1B[2m${d.handler.padEnd(l)}\x1B[0m`,x=`\x1B[2m${d.file}\x1B[0m`;this.log(` ${h} ${u} ${v} ${x}`)}this.log("")}scanRoutes(e,t){let s=[],r=Na(e);for(let i of r){let n=ri(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=ii(e,"utf-8"),i=this.filePathToUrl(e,t),n=gs(process.cwd(),e).split(fs).join("/"),a=/export\s+(?:const|function)\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\b/g,l;for(;(l=a.exec(r))!==null;){let c=l[1],d=this.extractHandler(r,c);s.push({method:c,path:i,handler:d,file:n})}return s}parsePageServerFile(e,t){let s=[],r=ii(e,"utf-8"),i=this.filePathToUrl(e,t),n=gs(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 a=r.match(/export\s+const\s+actions\s*=\s*\{([^}]+)\}/);if(a){let l=a[1].split(",").map(c=>c.trim().split(":")[0].split("(")[0].trim()).filter(Boolean);for(let c of l)s.push({method:"POST",path:c==="default"?i:`${i}?/${c}`,handler:`actions.${c}()`,file:n})}return s}filePathToUrl(e,t){let s=gs(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 _a}from"fs";import{join as oi}from"path";import{pathToFileURL as ja}from"url";var yt=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(()=>(vs(),ai)),i=new r,n=oi(process.cwd(),"src","lib","database","migrations"),a=await this.loadMigrations(n);if(t.status){let c=await i.status(a);this.table(["Migration","Status","Batch"],c.map(d=>[d.name,d.ran?"\x1B[32mRan\x1B[0m":"\x1B[33mPending\x1B[0m",d.batch?.toString()??"-"]));return}if(t.rollback){this.info("Rolling back last batch...");let c=await i.rollback(a);if(c.length===0)this.info("Nothing to rollback.");else for(let d of c)this.success(`Rolled back: ${d}`);return}if(t.reset){this.warnDestructive("reset"),this.info("Resetting all migrations...");let c=await i.reset(a);if(c.length===0)this.info("Nothing to reset.");else for(let d of c)this.success(`Rolled back: ${d}`);return}if(t.refresh){this.warnDestructive("refresh"),this.info("Refreshing migrations...");let c=await i.refresh(a);for(let d of c.reset)this.success(`Rolled back: ${d}`);for(let d of c.migrated)this.success(`Migrated: ${d}`);return}if(t.fresh){this.warnDestructive("fresh"),this.info("Dropping all tables...");let c=await i.fresh(a);if(c.dropped.length>0)for(let d of c.dropped)this.success(`Dropped table: ${d}`);this.newLine(),this.info("Re-running all migrations...");for(let d of c.migrated)this.success(`Migrated: ${d}`);return}this.info("Running migrations...");let l=await i.run(a);if(l.length===0)this.info("Nothing to migrate.");else for(let c of l)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=_a(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=oi(e,r);try{let n=await import(ja(i).href),a=n.default??Object.values(n).find(l=>typeof l=="function"&&l.prototype&&typeof l.prototype.up=="function");a?s.push({name:r.replace(/\.(ts|js)$/,""),timestamp:r.split("_")[0],path:i,migration:new a}):this.warn(`No migration class found in: ${r}`)}catch(n){let a;try{a=n instanceof Error?n.message:String(n)}catch{a=JSON.stringify(n)??"Unknown error (non-stringifiable object)"}this.error(`Failed to load migration ${r}: ${a}`)}}return s}};import{join as ws}from"path";import{pathToFileURL as Oa}from"url";import{existsSync as li}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=ws(process.cwd(),"src","lib","database","seeders"),r=t.class?ws(s,`${t.class}.ts`):ws(s,"DatabaseSeeder.ts"),i=r;li(i)||(i=i.replace(/\.ts$/,".js")),li(i)||(this.error(`Seeder not found: ${r}`),process.exit(1)),this.info("Running seeders...");try{let n=await import(Oa(i).href),a=n.default??n.DatabaseSeeder??Object.values(n).find(c=>typeof c=="function"&&c.prototype&&typeof c.prototype.run=="function");(!a||typeof a!="function")&&(this.error("No seeder class found in file."),process.exit(1)),await new a().run(),this.success("Database seeded successfully.")}catch(n){let a=n instanceof Error?n.message:String(n);this.error(`Seeding failed: ${a}`),n?.stack&&console.error(n.stack),process.exit(1)}}};import{readdirSync as Ba}from"fs";import{join as pi}from"path";import{pathToFileURL as Ha}from"url";var Ct=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(()=>(mi(),ui)),r=new s;r.persistToDatabase();let i=pi(process.cwd(),"src","lib","scheduler"),n=await this.loadTasks(i);if(n.length===0){this.warn("No scheduled tasks found in src/lib/scheduler/");return}for(let c of n)r.register(c),this.info(`Registered task: ${c.name}`);if(this.newLine(),t.once){this.info("Running due tasks (once)...");let c=await r.run();if(c.length===0)this.info("No tasks were due.");else for(let d of c)d.success?this.success(`${d.task}: completed in ${d.duration}ms`):this.error(`${d.task}: failed \u2014 ${d.error}`);return}this.info("Scheduler running. Press Ctrl+C to stop."),this.newLine();let a=async()=>{let c=await r.run();for(let d of c){let p=new Date().toISOString().replace("T"," ").slice(0,19);d.success?this.success(`[${p}] ${d.task}: completed in ${d.duration}ms`):this.error(`[${p}] ${d.task}: failed \u2014 ${d.error}`)}};await a();let l=6e4-Date.now()%6e4;this.info(`Next tick aligned to minute boundary in ${Math.round(l/1e3)}s.`),await new Promise(c=>setTimeout(c,l)),await a(),setInterval(a,6e4),await new Promise(()=>{})}async loadTasks(e){let t;try{t=Ba(e).filter(r=>(r.endsWith(".ts")||r.endsWith(".js"))&&!r.startsWith("index")).sort()}catch{return[]}let s=[];for(let r of t){let i=pi(e,r);try{let n=await import(Ha(i).href),a=n.default??Object.values(n).find(l=>typeof l=="function"&&l.prototype&&typeof l.prototype.handle=="function");if(a){let l=new a;l.schedule(),s.push(l)}}catch(n){this.error(`Failed to load task ${r}: ${n.message??n}`)}}return s}};var Rt=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(()=>(Q(),Te)),r=t.queue??"default",i=t["max-jobs"]?parseInt(t["max-jobs"]):void 0,n=t["max-time"]?parseInt(t["max-time"]):void 0,a=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 d=await s.work({queue:r,maxJobs:1,sleep:0});d===0?this.info("No jobs to process."):this.success(`Processed ${d} job(s).`);return}this.info(`Worker running on "${r}". Press Ctrl+C to stop.`),this.newLine();let l=Date.now(),c=0;for(;;){if(n&&(Date.now()-l)/1e3>=n){this.info(`Max time (${n}s) reached. Stopping.`);break}if(i&&c>=i){this.info(`Max jobs (${i}) reached. Stopping.`);break}let d=await s.work({queue:r,maxJobs:1,sleep:0});if(d>0){c+=d;let p=new Date().toISOString().replace("T"," ").slice(0,19);this.success(`[${p}] Processed ${d} job(s) (total: ${c})`)}else await new Promise(p=>setTimeout(p,a))}this.newLine(),this.info(`Worker stopped. Total jobs processed: ${c}`)}};var St=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(()=>(Q(),Te)),r=await s.failed();if(r.length===0){this.info("No failed jobs.");return}this.info(`Found ${r.length} failed job(s):
1361
+ `;Ma(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 Hr,relative as gs,sep as fs}from"path";import{existsSync as Na,readdirSync as Ia,readFileSync as zr,statSync as ja}from"fs";var bt=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=Hr(process.cwd(),"src","routes");if(!Na(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(m=>m.method===u)}if(i.sort((u,m)=>u.path.localeCompare(m.path)||u.method.localeCompare(m.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)
1362
+ `);let n=Math.max(6,...i.map(u=>u.method.length)),a=Math.max(4,...i.map(u=>u.path.length)),l=Math.max(7,...i.map(u=>u.handler.length)),c=` ${"METHOD".padEnd(n)} ${"PATH".padEnd(a)} ${"HANDLER".padEnd(l)} FILE`;this.log(`\x1B[2m${c}\x1B[0m`),this.log(`\x1B[2m ${"\u2500".repeat(n)} ${"\u2500".repeat(a)} ${"\u2500".repeat(l)} ${"\u2500".repeat(20)}\x1B[0m`);for(let u of i){let h=`${this.getMethodColor(u.method)}${u.method.padEnd(n)}\x1B[0m`,d=u.path.padEnd(a),b=`\x1B[2m${u.handler.padEnd(l)}\x1B[0m`,w=`\x1B[2m${u.file}\x1B[0m`;this.log(` ${h} ${d} ${b} ${w}`)}this.log("")}scanRoutes(e,t){let s=[],r=Ia(e);for(let i of r){let n=Hr(e,i);if(ja(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=zr(e,"utf-8"),i=this.filePathToUrl(e,t),n=gs(process.cwd(),e).split(fs).join("/"),a=/export\s+(?:const|function)\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\b/g,l;for(;(l=a.exec(r))!==null;){let c=l[1],u=this.extractHandler(r,c);s.push({method:c,path:i,handler:u,file:n})}return s}parsePageServerFile(e,t){let s=[],r=zr(e,"utf-8"),i=this.filePathToUrl(e,t),n=gs(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 a=r.match(/export\s+const\s+actions\s*=\s*\{([^}]+)\}/);if(a){let l=a[1].split(",").map(c=>c.trim().split(":")[0].split("(")[0].trim()).filter(Boolean);for(let c of l)s.push({method:"POST",path:c==="default"?i:`${i}?/${c}`,handler:`actions.${c}()`,file:n})}return s}filePathToUrl(e,t){let s=gs(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 Oa}from"fs";import{join as Jr}from"path";import{pathToFileURL as qa}from"url";var yt=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(()=>(vs(),Wr)),i=new r,n=Jr(process.cwd(),"src","lib","database","migrations"),a=await this.loadMigrations(n);if(t.status){let c=await i.status(a);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(a);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(a);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(a);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(a);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 l=await i.run(a);if(l.length===0)this.info("Nothing to migrate.");else for(let c of l)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=Oa(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=Jr(e,r);try{let n=await import(qa(i).href),a=n.default??Object.values(n).find(l=>typeof l=="function"&&l.prototype&&typeof l.prototype.up=="function");a?s.push({name:r.replace(/\.(ts|js)$/,""),timestamp:r.split("_")[0],path:i,migration:new a}):this.warn(`No migration class found in: ${r}`)}catch(n){let a;try{a=n instanceof Error?n.message:String(n)}catch{a=JSON.stringify(n)??"Unknown error (non-stringifiable object)"}this.error(`Failed to load migration ${r}: ${a}`)}}return s}};import{join as ws}from"path";import{pathToFileURL as Ua}from"url";import{existsSync as Vr}from"fs";var vt=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"),i=r;Vr(i)||(i=i.replace(/\.ts$/,".js")),Vr(i)||(this.error(`Seeder not found: ${r}`),process.exit(1)),this.info("Running seeders...");try{let n=await import(Ua(i).href),a=n.default??n.DatabaseSeeder??Object.values(n).find(c=>typeof c=="function"&&c.prototype&&typeof c.prototype.run=="function");(!a||typeof a!="function")&&(this.error("No seeder class found in file."),process.exit(1)),await new a().run(),this.success("Database seeded successfully.")}catch(n){let a=n instanceof Error?n.message:String(n);this.error(`Seeding failed: ${a}`),n?.stack&&console.error(n.stack),process.exit(1)}}};import{existsSync as za,readdirSync as Ka}from"fs";import{join as Ss}from"path";import{pathToFileURL as Wa}from"url";var xt=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(()=>(Zr(),Yr)),r=new s;r.persistToDatabase();let i=Ss(process.cwd(),"src","lib","shared","scheduler"),n=Ss(process.cwd(),"src","lib","scheduler"),a=za(i)?i:n,l=await this.loadTasks(a);if(l.length===0){this.warn("No scheduled tasks found in src/lib/shared/scheduler/ or src/lib/scheduler/");return}for(let m of l)r.register(m),this.info(`Registered task: ${m.name}`);if(this.newLine(),t.once){this.info("Running due tasks (once)...");let m=await r.run();if(m.length===0)this.info("No tasks were due.");else for(let h of m)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 m=await r.run();for(let h of m){let d=new Date().toISOString().replace("T"," ").slice(0,19);h.success?this.success(`[${d}] ${h.task}: completed in ${h.duration}ms`):this.error(`[${d}] ${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(m=>setTimeout(m,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=Ss(e,r);try{let n=await import(Wa(i).href),a=n.default??Object.values(n).find(l=>typeof l=="function"&&l.prototype&&typeof l.prototype.handle=="function");if(a){let l=new a;l.schedule(),s.push(l)}}catch(n){this.error(`Failed to load task ${r}: ${n.message??n}`)}}return s}};var Rt=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(()=>(V(),Te)),r=t.queue??"default",i=t["max-jobs"]?parseInt(t["max-jobs"]):void 0,n=t["max-time"]?parseInt(t["max-time"]):void 0,a=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 l=Date.now(),c=0;for(;;){if(n&&(Date.now()-l)/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 m=new Date().toISOString().replace("T"," ").slice(0,19);this.success(`[${m}] Processed ${u} job(s) (total: ${c})`)}else await new Promise(m=>setTimeout(m,a))}this.newLine(),this.info(`Worker stopped. Total jobs processed: ${c}`)}};var Tt=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(()=>(V(),Te)),r=await s.failed();if(r.length===0){this.info("No failed jobs.");return}this.info(`Found ${r.length} failed job(s):
1360
1363
  `);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(`
1361
- `)[0]}`),this.log("")}}};var Tt=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(()=>(Q(),Te));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 Et=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(()=>(Q(),Te)),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.
1362
- `);let t=(await import("repl")).start({prompt:"\x1B[36msvelar>\x1B[0m ",useGlobal:!0});try{let s=await Promise.resolve().then(()=>(un(),dn));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"),n=r(process.cwd(),"src","lib","models"),a=s(n).filter(l=>l.endsWith(".ts")||l.endsWith(".js"));for(let l of a)try{let c=await import(i(r(n,l)).href);for(let[d,p]of Object.entries(c))typeof p=="function"&&(t.context[d]=p)}catch{}a.length>0&&this.log(`Loaded models: ${a.map(l=>l.replace(/\.(ts|js)$/,"")).join(", ")}`)}catch{}await new Promise(s=>{t.on("exit",s)})}};var m=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"},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"},dependencies:{"better-sqlite3":"^11.0.0","drizzle-orm":"^0.38.0","@beeblock/svelar":`^${t}`,exceljs:"^4.4.0",pdfkit:"^0.18.0","sveltekit-superforms":"^2.22.0",zod:"^3.23.0"}},null,2)+`
1364
+ `)[0]}`),this.log("")}}};var Et=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(()=>(V(),Te));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 kt=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(()=>(V(),Te)),r=await s.flushFailed();r===0?this.info("No failed jobs to flush."):this.success(`Flushed ${r} failed job record(s).`)}};var ts=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.
1365
+ `);let t=(await import("repl")).start({prompt:"\x1B[36msvelar>\x1B[0m ",useGlobal:!0});try{let s=await Promise.resolve().then(()=>(Qi(),Vi));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"),a=r(process.cwd(),"src","lib","models"),l=r(process.cwd(),"src","lib","modules"),c=[],u=a;if(n(a))u=a,c=s(a).filter(m=>(m.endsWith(".ts")||m.endsWith(".js"))&&!m.startsWith("index"));else if(n(l)){u=l;for(let m of s(l,{withFileTypes:!0})){if(!m.isDirectory())continue;let h=r(l,m.name);for(let d of s(h))(d.endsWith(".ts")||d.endsWith(".js"))&&(d.startsWith("index")||d.includes("Controller")||d.includes("Service")||d.includes("Repository")||d.includes("Request")||d.includes("Resource")||d.includes("schema")||d.includes("gates")||c.push(r(m.name,d)))}}for(let m of c)try{let h=await import(i(r(u,m)).href);for(let[d,b]of Object.entries(h))typeof b=="function"&&(t.context[d]=b)}catch{}c.length>0&&this.log(`Loaded models: ${c.map(m=>m.replace(/\.(ts|js)$/,"")).join(", ")}`)}catch{}await new Promise(s=>{t.on("exit",s)})}};var p=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"},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"},dependencies:{"better-sqlite3":"^11.0.0","drizzle-orm":"^0.38.0","@beeblock/svelar":`^${t}`,exceljs:"^4.4.0",pdfkit:"^0.18.0","sveltekit-superforms":"^2.22.0",zod:"^3.23.0"}},null,2)+`
1363
1366
  `}static svelteConfig(){return`import adapter from '@sveltejs/adapter-auto';
1364
1367
  import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
1365
1368
 
@@ -1435,6 +1438,7 @@ export default defineConfig({
1435
1438
  '@beeblock/svelar/services': resolve(svelarRoot, 'dist/services/index.js'),
1436
1439
  '@beeblock/svelar/session': resolve(svelarRoot, 'dist/session/index.js'),
1437
1440
  '@beeblock/svelar/storage': resolve(svelarRoot, 'dist/storage/index.js'),
1441
+ '@beeblock/svelar/stripe': resolve(svelarRoot, 'dist/stripe/index.js'),
1438
1442
  '@beeblock/svelar/support': resolve(svelarRoot, 'dist/support/index.js'),
1439
1443
  '@beeblock/svelar/teams': resolve(svelarRoot, 'dist/teams/index.js'),
1440
1444
  '@beeblock/svelar/uploads': resolve(svelarRoot, 'dist/uploads/index.js'),
@@ -1657,6 +1661,15 @@ Features.configure({ driver: 'database' });
1657
1661
  // \u2500\u2500 PDF (PDFKit \u2014 no Docker needed) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
1658
1662
  PDF.configure({ driver: 'pdfkit' });
1659
1663
 
1664
+ // \u2500\u2500 Stripe (billing \u2014 uncomment and npm install stripe) \u2500\u2500
1665
+ // import { Stripe } from '@beeblock/svelar/stripe';
1666
+ // Stripe.configure({
1667
+ // secretKey: process.env.STRIPE_SECRET_KEY ?? '',
1668
+ // publishableKey: process.env.STRIPE_PUBLISHABLE_KEY ?? '',
1669
+ // webhookSecret: process.env.STRIPE_WEBHOOK_SECRET ?? '',
1670
+ // currency: 'usd',
1671
+ // });
1672
+
1660
1673
  // \u2500\u2500 Dashboard \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
1661
1674
  configureDashboard({ enabled: true, prefix: '/admin' });
1662
1675
 
@@ -1758,6 +1771,11 @@ DB_PATH=database.db
1758
1771
  # MEILISEARCH_HOST=http://localhost:7700
1759
1772
  # MEILISEARCH_KEY=
1760
1773
 
1774
+ # Stripe (billing and subscriptions \u2014 npm install stripe)
1775
+ # STRIPE_SECRET_KEY=sk_test_...
1776
+ # STRIPE_PUBLISHABLE_KEY=pk_test_...
1777
+ # STRIPE_WEBHOOK_SECRET=whsec_...
1778
+
1761
1779
  # PDF (default driver is pdfkit \u2014 no config needed)
1762
1780
  # Switch to Gotenberg for pixel-perfect HTML rendering:
1763
1781
  # PDF_DRIVER=gotenberg
@@ -3987,6 +4005,7 @@ export const load = guardAuth();
3987
4005
  import LayoutDashboard from 'lucide-svelte/icons/layout-dashboard';
3988
4006
  import KeyRound from 'lucide-svelte/icons/key-round';
3989
4007
  import Users from 'lucide-svelte/icons/users';
4008
+ import CreditCard from 'lucide-svelte/icons/credit-card';
3990
4009
  import Settings from 'lucide-svelte/icons/settings';
3991
4010
 
3992
4011
  interface Props {
@@ -4000,6 +4019,7 @@ export const load = guardAuth();
4000
4019
  { href: '/dashboard', label: 'Overview', exact: true, icon: LayoutDashboard },
4001
4020
  { href: '/dashboard/api-keys', label: 'API Keys', exact: false, icon: KeyRound },
4002
4021
  { href: '/dashboard/team', label: 'Team', exact: false, icon: Users },
4022
+ { href: '/dashboard/billing', label: 'Billing', exact: false, icon: CreditCard },
4003
4023
  ];
4004
4024
 
4005
4025
  function isActive(href: string, exact: boolean, pathname: string): boolean {
@@ -4623,6 +4643,7 @@ export const load = guardAuth('/dashboard', { role: 'admin' });
4623
4643
  import ListTodo from 'lucide-svelte/icons/list-todo';
4624
4644
  import Clock from 'lucide-svelte/icons/clock';
4625
4645
  import FileText from 'lucide-svelte/icons/file-text';
4646
+ import CreditCard from 'lucide-svelte/icons/credit-card';
4626
4647
  import ArrowLeft from 'lucide-svelte/icons/arrow-left';
4627
4648
 
4628
4649
  interface Props {
@@ -4637,6 +4658,7 @@ export const load = guardAuth('/dashboard', { role: 'admin' });
4637
4658
  { tab: 'users', label: 'Users', icon: Users },
4638
4659
  { tab: 'roles', label: 'Roles', icon: ShieldCheck },
4639
4660
  { tab: 'permissions', label: 'Permissions', icon: Lock },
4661
+ { tab: 'billing', label: 'Billing', icon: CreditCard },
4640
4662
  { tab: 'queue', label: 'Queue', icon: ListTodo },
4641
4663
  { tab: 'scheduler', label: 'Scheduler', icon: Clock },
4642
4664
  { tab: 'logs', label: 'Logs', icon: FileText },
@@ -4689,6 +4711,7 @@ import { JobMonitor } from '@beeblock/svelar/queue/JobMonitor';
4689
4711
  import { ScheduleMonitor } from '@beeblock/svelar/scheduler/ScheduleMonitor';
4690
4712
  import { LogViewer } from '@beeblock/svelar/logging/LogViewer';
4691
4713
  import { Permissions } from '@beeblock/svelar/permissions';
4714
+ import { Stripe } from '@beeblock/svelar/stripe';
4692
4715
 
4693
4716
  export async function load(event: ServerLoadEvent) {
4694
4717
  const user = event.locals.user;
@@ -4758,6 +4781,33 @@ export async function load(event: ServerLoadEvent) {
4758
4781
  }
4759
4782
  } catch { /* permissions tables may not exist yet */ }
4760
4783
 
4784
+ // Billing / Stripe subscriptions
4785
+ let billingSubscriptions: any[] = [];
4786
+ try {
4787
+ const client = await Stripe.service().getClient();
4788
+ const subs = await client.subscriptions.list({
4789
+ limit: 25,
4790
+ expand: ['data.customer'],
4791
+ });
4792
+ billingSubscriptions = subs.data.map((sub: any) => ({
4793
+ id: sub.id,
4794
+ status: sub.status,
4795
+ cancelAtPeriodEnd: sub.cancel_at_period_end,
4796
+ customer: {
4797
+ id: typeof sub.customer === 'string' ? sub.customer : sub.customer?.id,
4798
+ email: typeof sub.customer === 'object' ? sub.customer?.email : null,
4799
+ name: typeof sub.customer === 'object' ? sub.customer?.name : null,
4800
+ },
4801
+ plan: {
4802
+ nickname: sub.items?.data?.[0]?.price?.nickname ?? 'Plan',
4803
+ amount: sub.items?.data?.[0]?.price?.unit_amount ?? 0,
4804
+ currency: sub.items?.data?.[0]?.price?.currency ?? 'usd',
4805
+ interval: sub.items?.data?.[0]?.price?.recurring?.interval ?? 'month',
4806
+ },
4807
+ created: sub.created,
4808
+ }));
4809
+ } catch { /* stripe not configured or no subscriptions */ }
4810
+
4761
4811
  return {
4762
4812
  user: {
4763
4813
  id: user.id,
@@ -4823,6 +4873,7 @@ export async function load(event: ServerLoadEvent) {
4823
4873
  perms.map((p: any) => ({ id: p.id, name: p.name })),
4824
4874
  ]),
4825
4875
  ),
4876
+ billingSubscriptions,
4826
4877
  };
4827
4878
  }
4828
4879
  `}static adminPageSvelte(){return`<script lang="ts">
@@ -4856,6 +4907,12 @@ export async function load(event: ServerLoadEvent) {
4856
4907
  let showRoleForm = $state(false);
4857
4908
  let showPermForm = $state(false);
4858
4909
 
4910
+ // Billing state
4911
+ let billingSubscriptions = $state<any[]>(data.billingSubscriptions ?? []);
4912
+ let billingLoading = $state(false);
4913
+ let billingMessage = $state('');
4914
+ let billingMessageType = $state<'success' | 'error'>('success');
4915
+
4859
4916
  let logFilter = $state<'all' | 'info' | 'warn' | 'error'>('all');
4860
4917
 
4861
4918
  const activeTab = $derived($page.url.searchParams.get('tab') ?? 'overview');
@@ -5233,6 +5290,75 @@ export async function load(event: ServerLoadEvent) {
5233
5290
  function getLogBadgeVariant(level: string): 'default' | 'secondary' | 'destructive' {
5234
5291
  return level === 'error' || level === 'fatal' ? 'destructive' : level === 'warn' ? 'secondary' : 'default';
5235
5292
  }
5293
+
5294
+ function billingFlash(msg: string, type: 'success' | 'error' = 'success') {
5295
+ billingMessage = msg;
5296
+ billingMessageType = type;
5297
+ }
5298
+
5299
+ function formatCurrency(amount: number, currency: string): string {
5300
+ return new Intl.NumberFormat('en-US', { style: 'currency', currency: currency.toUpperCase() }).format(amount / 100);
5301
+ }
5302
+
5303
+ function billingStatusVariant(status: string): 'default' | 'secondary' | 'destructive' {
5304
+ if (status === 'active' || status === 'trialing') return 'default';
5305
+ if (status === 'past_due' || status === 'incomplete') return 'secondary';
5306
+ return 'destructive';
5307
+ }
5308
+
5309
+ async function refreshBilling() {
5310
+ billingLoading = true;
5311
+ try {
5312
+ const res = await fetch('/api/admin/billing/subscriptions?limit=50');
5313
+ if (res.ok) {
5314
+ const data = await res.json();
5315
+ billingSubscriptions = data.subscriptions;
5316
+ }
5317
+ } catch { /* ignore */ }
5318
+ billingLoading = false;
5319
+ }
5320
+
5321
+ async function cancelSubscription(subscriptionId: string, customerEmail: string, immediately: boolean) {
5322
+ const mode = immediately ? 'immediately' : 'at end of billing period';
5323
+ if (!confirm(\`Cancel subscription for \${customerEmail} \${mode}?\`)) return;
5324
+ try {
5325
+ const res = await fetch('/api/admin/billing/cancel', {
5326
+ method: 'POST',
5327
+ headers: { 'Content-Type': 'application/json' },
5328
+ body: JSON.stringify({ subscriptionId, immediately }),
5329
+ });
5330
+ if (res.ok) {
5331
+ billingFlash(\`Subscription \${immediately ? 'canceled' : 'set to cancel at period end'}\`);
5332
+ await refreshBilling();
5333
+ } else {
5334
+ const err = await res.json();
5335
+ billingFlash(err.error || 'Failed to cancel', 'error');
5336
+ }
5337
+ } catch {
5338
+ billingFlash('Network error', 'error');
5339
+ }
5340
+ }
5341
+
5342
+ async function refundSubscription(subscriptionId: string, customerEmail: string) {
5343
+ const invoiceId = prompt(\`Enter the Stripe Invoice ID to refund for \${customerEmail}:\`);
5344
+ if (!invoiceId) return;
5345
+ try {
5346
+ const res = await fetch('/api/admin/billing/refund', {
5347
+ method: 'POST',
5348
+ headers: { 'Content-Type': 'application/json' },
5349
+ body: JSON.stringify({ invoiceId }),
5350
+ });
5351
+ if (res.ok) {
5352
+ const data = await res.json();
5353
+ billingFlash(\`Refund issued: \${data.refund.id} (\${data.refund.status})\`);
5354
+ } else {
5355
+ const err = await res.json();
5356
+ billingFlash(err.error || 'Refund failed', 'error');
5357
+ }
5358
+ } catch {
5359
+ billingFlash('Network error', 'error');
5360
+ }
5361
+ }
5236
5362
  </script>
5237
5363
 
5238
5364
  <svelte:head>
@@ -5615,6 +5741,89 @@ export async function load(event: ServerLoadEvent) {
5615
5741
  </div>
5616
5742
  {/if}
5617
5743
 
5744
+ <!-- Billing -->
5745
+ {#if activeTab === 'billing'}
5746
+ <Card>
5747
+ <CardHeader>
5748
+ <div class="flex items-center justify-between">
5749
+ <div>
5750
+ <CardTitle>Subscriptions</CardTitle>
5751
+ <CardDescription>Manage user subscriptions, issue refunds, and cancel plans</CardDescription>
5752
+ </div>
5753
+ <Button variant="outline" size="sm" onclick={refreshBilling} disabled={billingLoading}>
5754
+ {billingLoading ? 'Loading...' : 'Refresh'}
5755
+ </Button>
5756
+ </div>
5757
+ </CardHeader>
5758
+ <CardContent>
5759
+ {#if billingMessage}
5760
+ <Alert variant={billingMessageType === 'error' ? 'destructive' : 'default'} class="mb-4">
5761
+ <span class="text-sm">{billingMessage}</span>
5762
+ </Alert>
5763
+ {/if}
5764
+
5765
+ {#if billingSubscriptions.length === 0}
5766
+ <p class="text-sm text-gray-500 py-8 text-center">
5767
+ No subscriptions found. Subscriptions will appear here when users subscribe via Stripe.
5768
+ </p>
5769
+ {:else}
5770
+ <div class="border rounded-lg overflow-hidden">
5771
+ <table class="w-full text-sm">
5772
+ <thead class="bg-gray-50 text-left">
5773
+ <tr>
5774
+ <th class="px-4 py-3 text-gray-600 font-medium">Customer</th>
5775
+ <th class="px-4 py-3 text-gray-600 font-medium">Plan</th>
5776
+ <th class="px-4 py-3 text-gray-600 font-medium">Price</th>
5777
+ <th class="px-4 py-3 text-gray-600 font-medium">Status</th>
5778
+ <th class="px-4 py-3 text-gray-600 font-medium">Created</th>
5779
+ <th class="px-4 py-3 text-gray-600 font-medium text-right">Actions</th>
5780
+ </tr>
5781
+ </thead>
5782
+ <tbody class="divide-y">
5783
+ {#each billingSubscriptions as sub (sub.id)}
5784
+ <tr class="hover:bg-gray-50">
5785
+ <td class="px-4 py-3">
5786
+ <div>
5787
+ <p class="font-medium text-gray-900">{sub.customer.name ?? 'Unknown'}</p>
5788
+ <p class="text-xs text-gray-500">{sub.customer.email ?? sub.customer.id}</p>
5789
+ </div>
5790
+ </td>
5791
+ <td class="px-4 py-3 text-gray-700">{sub.plan.nickname}</td>
5792
+ <td class="px-4 py-3 text-gray-700">{formatCurrency(sub.plan.amount, sub.plan.currency)}/{sub.plan.interval}</td>
5793
+ <td class="px-4 py-3">
5794
+ <Badge variant={billingStatusVariant(sub.status)}>{sub.status}</Badge>
5795
+ {#if sub.cancelAtPeriodEnd}
5796
+ <Badge variant="secondary" class="ml-1">canceling</Badge>
5797
+ {/if}
5798
+ </td>
5799
+ <td class="px-4 py-3 text-gray-500">{formatDate(new Date(sub.created * 1000).toISOString())}</td>
5800
+ <td class="px-4 py-3 text-right">
5801
+ <div class="flex gap-1 justify-end">
5802
+ <Button size="sm" variant="outline" onclick={() => refundSubscription(sub.id, sub.customer.email ?? sub.customer.id)}>
5803
+ Refund
5804
+ </Button>
5805
+ {#if sub.status === 'active' || sub.status === 'trialing'}
5806
+ {#if !sub.cancelAtPeriodEnd}
5807
+ <Button size="sm" variant="outline" onclick={() => cancelSubscription(sub.id, sub.customer.email ?? sub.customer.id, false)}>
5808
+ Cancel
5809
+ </Button>
5810
+ {/if}
5811
+ <Button size="sm" variant="destructive" onclick={() => cancelSubscription(sub.id, sub.customer.email ?? sub.customer.id, true)}>
5812
+ Cancel Now
5813
+ </Button>
5814
+ {/if}
5815
+ </div>
5816
+ </td>
5817
+ </tr>
5818
+ {/each}
5819
+ </tbody>
5820
+ </table>
5821
+ </div>
5822
+ {/if}
5823
+ </CardContent>
5824
+ </Card>
5825
+ {/if}
5826
+
5618
5827
  <!-- Queue -->
5619
5828
  {#if activeTab === 'queue'}
5620
5829
  <div class="space-y-6">
@@ -6141,8 +6350,15 @@ export class SendWelcomeEmail extends Job {
6141
6350
  maxAttempts = 3;
6142
6351
  retryDelay = 30;
6143
6352
 
6144
- constructor(private userId: number, private email: string, private name: string) {
6353
+ userId: number;
6354
+ email: string;
6355
+ name: string;
6356
+
6357
+ constructor(userId: number, email: string, name: string) {
6145
6358
  super();
6359
+ this.userId = userId;
6360
+ this.email = email;
6361
+ this.name = name;
6146
6362
  }
6147
6363
 
6148
6364
  async handle(): Promise<void> {
@@ -6510,7 +6726,10 @@ export async function load(event: ServerLoadEvent) {
6510
6726
  </div>
6511
6727
  </div>
6512
6728
  `}static userRegisteredEvent(){return`export class UserRegistered {
6513
- constructor(public readonly user: any) {}
6729
+ readonly user: any;
6730
+ constructor(user: any) {
6731
+ this.user = user;
6732
+ }
6514
6733
  }
6515
6734
  `}static sendWelcomeEmailListener(){return`import { Queue } from '@beeblock/svelar/queue';
6516
6735
  import { Notifier } from '@beeblock/svelar/notifications';
@@ -6531,8 +6750,11 @@ export class SendWelcomeEmailListener {
6531
6750
  `}static welcomeNotification(){return`import { Notification } from '@beeblock/svelar/notifications';
6532
6751
 
6533
6752
  export class WelcomeNotification extends Notification {
6534
- constructor(private user: any) {
6753
+ user: any;
6754
+
6755
+ constructor(user: any) {
6535
6756
  super();
6757
+ this.user = user;
6536
6758
  }
6537
6759
 
6538
6760
  via() {
@@ -6610,12 +6832,430 @@ export class EventServiceProvider extends BaseProvider {
6610
6832
  </Card>
6611
6833
  </div>
6612
6834
  </div>
6613
- `}};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:i,mkdirSync:n,writeFileSync:a}=await import("fs"),{execSync:l}=await import("child_process"),c=e[0];c||(this.error("Please provide a project name: npx svelar new my-app"),process.exit(1));let d=r(process.cwd(),c);i(d)&&(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})
6614
- `);let u=($,Fe)=>{let ds=p?go($):$,Be=p?fo(Fe,$):Fe,He=s(d,ds);n(s(He,".."),{recursive:!0}),a(He,Be)};this.info("Creating project structure...");let v=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/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"]:["","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/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"];for(let $ of v)n(s(d,$),{recursive:!0});this.info("Writing config files...");let{dirname:x}=await import("path"),{fileURLToPath:k}=await import("url"),ls=s(x(x(x(k(import.meta.url)))),"package.json"),Ue=JSON.parse((await import("fs")).readFileSync(ls,"utf-8")).version??"0.4.0";u("package.json",m.packageJson(c,Ue)),u("svelte.config.js",m.svelteConfig()),u("vite.config.ts",m.viteConfig()),u("tsconfig.json",m.tsConfig()),u("src/app.html",m.appHtml()),u("static/favicon.svg",m.faviconSvg()),u("src/app.css",m.appCss()),u("src/app.ts",m.appTs()),u("src/hooks.server.ts",m.hooksServerTs()),u(".env.example",m.envExample());let{randomBytes:z}=await import("crypto"),ye=z(32).toString("hex"),be=z(16).toString("hex"),Mr=m.envExample().replace("APP_KEY=change-me-to-a-random-string",`APP_KEY=${ye}`).replace("INTERNAL_SECRET=change-me-to-a-random-string",`INTERNAL_SECRET=${be}`);u(".env",Mr),u(".gitignore",m.gitignore()),u("svelar.database.json",m.svelarDatabaseJson());for(let $ of["storage/logs","storage/cache","storage/uploads","storage/sessions"])u(`${$}/.gitkeep`,"");if(this.info("Scaffolding domain layer..."),u("src/lib/modules/auth/User.ts",m.userModel()),u("src/lib/modules/auth/UserRepository.ts",m.userRepository()),u("src/lib/modules/auth/AuthService.ts",m.authService()),u("src/lib/modules/auth/AuthController.ts",m.authController()),u("src/lib/modules/auth/RegisterUserAction.ts",m.registerUserAction()),u("src/lib/modules/auth/RegisterRequest.ts",m.registerRequest()),u("src/lib/modules/auth/LoginRequest.ts",m.loginRequest()),u("src/lib/modules/auth/ForgotPasswordRequest.ts",m.forgotPasswordRequest()),u("src/lib/modules/auth/ResetPasswordRequest.ts",m.resetPasswordRequest()),u("src/lib/modules/auth/OtpSendRequest.ts",m.otpSendRequest()),u("src/lib/modules/auth/OtpVerifyRequest.ts",m.otpVerifyRequest()),u("src/lib/modules/auth/UserResource.ts",m.userResource()),u("src/lib/modules/auth/gates.ts",m.gates()),u("src/lib/modules/auth/schemas.ts",m.authSchema()),u("src/lib/modules/auth/UserRegistered.ts",m.userRegisteredEvent()),u("src/lib/modules/auth/SendWelcomeEmailListener.ts",m.sendWelcomeEmailListener()),u("src/lib/modules/auth/WelcomeNotification.ts",m.welcomeNotification()),u("src/lib/modules/posts/Post.ts",m.postModel()),u("src/lib/modules/posts/PostRepository.ts",m.postRepository()),u("src/lib/modules/posts/PostService.ts",m.postService()),u("src/lib/modules/posts/PostController.ts",m.postController()),u("src/lib/modules/posts/CreatePostAction.ts",m.createPostAction()),u("src/lib/modules/posts/CreatePostRequest.ts",m.createPostRequest()),u("src/lib/modules/posts/UpdatePostRequest.ts",m.updatePostRequest()),u("src/lib/modules/posts/PostResource.ts",m.postResource()),u("src/lib/modules/posts/schemas.ts",m.postSchema()),u("src/lib/modules/admin/AdminService.ts",m.adminService()),u("src/lib/modules/admin/AdminController.ts",m.adminController()),u("src/lib/modules/admin/UpdateUserRoleRequest.ts",m.updateUserRoleRequest()),u("src/lib/modules/admin/DeleteUserRequest.ts",m.deleteUserRequest()),u("src/lib/modules/admin/CreateRoleRequest.ts",m.createRoleRequest()),u("src/lib/modules/admin/DeleteRoleRequest.ts",m.deleteRoleRequest()),u("src/lib/modules/admin/CreatePermissionRequest.ts",m.createPermissionRequest()),u("src/lib/modules/admin/DeletePermissionRequest.ts",m.deletePermissionRequest()),u("src/lib/modules/admin/RolePermissionRequest.ts",m.rolePermissionRequest()),u("src/lib/modules/admin/UserRoleRequest.ts",m.userRoleRequest()),u("src/lib/modules/admin/UserPermissionRequest.ts",m.userPermissionRequest()),u("src/lib/modules/admin/ExportDataRequest.ts",m.exportDataRequest()),u("src/lib/modules/admin/RoleResource.ts",m.roleResource()),u("src/lib/modules/admin/PermissionResource.ts",m.permissionResource()),u("src/lib/modules/admin/schemas.ts",m.adminSchema()),u("src/lib/shared/providers/EventServiceProvider.ts",m.eventServiceProvider()),this.info("Creating migrations..."),u("src/lib/database/migrations/00000001_create_users_table.ts",m.createUsersTable()),u("src/lib/database/migrations/00000002_create_posts_table.ts",m.createPostsTable()),u("src/lib/database/migrations/00000003_create_permissions_tables.ts",m.createPermissionsTables()),u("src/lib/database/migrations/00000004_add_role_to_users.ts",m.addRoleToUsers()),u("src/lib/database/migrations/00000005_create_sessions_table.ts",m.createSessionsTable()),u("src/lib/database/migrations/00000006_create_audit_logs_table.ts",m.createAuditLogsTable()),u("src/lib/database/migrations/00000007_create_notifications_table.ts",m.createNotificationsTable()),u("src/lib/database/migrations/00000008_create_failed_jobs_table.ts",m.createFailedJobsTable()),u("src/lib/database/seeders/DatabaseSeeder.ts",m.databaseSeeder()),this.info("Creating auth pages..."),u("src/routes/login/+page.server.ts",m.loginPageServer()),u("src/routes/login/+page.svelte",m.loginPageSvelte()),u("src/routes/register/+page.server.ts",m.registerPageServer()),u("src/routes/register/+page.svelte",m.registerPageSvelte()),u("src/routes/logout/+page.server.ts",m.logoutPageServer()),u("src/routes/forgot-password/+page.server.ts",m.forgotPasswordPageServer()),u("src/routes/forgot-password/+page.svelte",m.forgotPasswordPageSvelte()),u("src/routes/reset-password/+page.server.ts",m.resetPasswordPageServer()),u("src/routes/reset-password/+page.svelte",m.resetPasswordPageSvelte()),u("src/routes/otp-login/+page.server.ts",m.otpLoginPageServer()),u("src/routes/otp-login/+page.svelte",m.otpLoginPageSvelte()),u("src/routes/verify-email/+page.server.ts",m.verifyEmailPageServer()),u("src/routes/verify-email/+page.svelte",m.verifyEmailPageSvelte()),this.info("Creating dashboard..."),u("src/routes/dashboard/+layout.server.ts",m.dashboardLayoutServer()),u("src/routes/dashboard/+layout.svelte",m.dashboardLayoutSvelte()),u("src/routes/dashboard/+page.server.ts",m.dashboardPageServer()),u("src/routes/dashboard/+page.svelte",m.dashboardPageSvelte()),u("src/routes/dashboard/api-keys/+page.server.ts",m.apiKeysPageServer()),u("src/routes/dashboard/api-keys/+page.svelte",m.apiKeysPageSvelte()),u("src/routes/dashboard/team/+page.server.ts",m.teamPageServer()),u("src/routes/dashboard/team/+page.svelte",m.teamPageSvelte()),this.info("Creating admin panel..."),u("src/routes/admin/+layout.server.ts",m.adminLayoutServer()),u("src/routes/admin/+layout.svelte",m.adminLayoutSvelte()),u("src/routes/admin/+page.server.ts",m.adminPageServer()),u("src/routes/admin/+page.svelte",m.adminPageSvelte()),this.info("Creating API routes..."),u("src/routes/api/health/+server.ts",m.apiHealth()),u("src/routes/api/auth/register/+server.ts",m.apiAuthRegister()),u("src/routes/api/auth/login/+server.ts",m.apiAuthLogin()),u("src/routes/api/auth/logout/+server.ts",m.apiAuthLogout()),u("src/routes/api/auth/me/+server.ts",m.apiAuthMe()),u("src/routes/api/auth/forgot-password/+server.ts",m.apiAuthForgotPassword()),u("src/routes/api/auth/reset-password/+server.ts",m.apiAuthResetPassword()),u("src/routes/api/auth/otp/send/+server.ts",m.apiAuthOtpSend()),u("src/routes/api/auth/otp/verify/+server.ts",m.apiAuthOtpVerify()),u("src/routes/api/auth/verify-email/+server.ts",m.apiAuthVerifyEmail()),u("src/routes/api/posts/+server.ts",m.apiPosts()),u("src/routes/api/posts/[id]/+server.ts",m.apiPostsSingle()),u("src/routes/api/posts/mine/+server.ts",m.apiPostsMine()),u("src/routes/api/broadcasting/[channel]/+server.ts",m.apiBroadcasting()),u("src/routes/api/internal/broadcast/+server.ts",m.apiInternalBroadcast()),u("src/routes/api/admin/users/+server.ts",m.apiAdminUsers()),u("src/routes/api/admin/roles/+server.ts",m.apiAdminRoles()),u("src/routes/api/admin/permissions/+server.ts",m.apiAdminPermissions()),u("src/routes/api/admin/role-permissions/+server.ts",m.apiAdminRolePermissions()),u("src/routes/api/admin/user-roles/+server.ts",m.apiAdminUserRoles()),u("src/routes/api/admin/user-permissions/+server.ts",m.apiAdminUserPermissions()),u("src/routes/api/admin/export/+server.ts",m.apiAdminExport()),u("src/routes/api/admin/health/+server.ts",m.apiAdminHealth()),u("src/routes/api/admin/queue/+server.ts",m.apiAdminQueue()),u("src/routes/api/admin/queue/[id]/retry/+server.ts",m.apiAdminQueueRetry()),u("src/routes/api/admin/queue/[id]/+server.ts",m.apiAdminQueueDelete()),u("src/routes/api/admin/scheduler/+server.ts",m.apiAdminScheduler()),u("src/routes/api/admin/scheduler/[name]/run/+server.ts",m.apiAdminSchedulerRun()),u("src/routes/api/admin/scheduler/[name]/toggle/+server.ts",m.apiAdminSchedulerToggle()),u("src/routes/api/admin/logs/+server.ts",m.apiAdminLogs()),u("src/routes/api/admin/stats/+server.ts",m.apiAdminStats()),this.info("Creating background jobs..."),u("src/lib/shared/jobs/SendWelcomeEmail.ts",m.sendWelcomeEmail()),u("src/lib/shared/jobs/DailyDigestJob.ts",m.dailyDigestJob()),u("src/lib/shared/jobs/ExportDataJob.ts",m.exportDataJob()),this.info("Creating scheduled tasks..."),u("src/lib/shared/scheduler/CleanupExpiredTokens.ts",m.cleanupExpiredTokens()),u("src/lib/shared/scheduler/CleanExpiredSessions.ts",m.cleanExpiredSessions()),u("src/lib/shared/scheduler/DailyDigestEmail.ts",m.dailyDigestEmail()),u("src/lib/shared/scheduler/PruneAuditLogs.ts",m.pruneAuditLogs()),u("src/lib/shared/scheduler/QueueHealthCheck.ts",m.queueHealthCheck()),this.info("Creating layouts..."),u("src/routes/+layout.svelte",m.rootLayoutSvelte(c)),u("src/routes/+layout.server.ts",m.rootLayoutServer()),u("src/routes/+error.svelte",m.errorSvelte()),u("src/routes/+page.svelte",m.homePage(c)),this.success(`Project structure created (${h})`),!t["no-install"]){this.info("Installing dependencies...");try{l("npm install",{cwd:d,stdio:"inherit"}),this.success("Dependencies installed")}catch{this.warn("npm install failed \u2014 run it manually with: cd "+c+" && npm install")}this.info("Running migrations...");try{l("npx svelar migrate",{cwd:d,stdio:"inherit"}),this.success("Migrations complete")}catch{this.warn("Migrations failed \u2014 run manually: cd "+c+" && npx svelar migrate")}this.info("Seeding database...");try{l("npx svelar seed:run",{cwd:d,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!
6835
+ `}static addStripeToUsers(){return`import { Migration } from '@beeblock/svelar/database';
6836
+
6837
+ export default class AddStripeToUsers extends Migration {
6838
+ async up() {
6839
+ await this.schema.alterTable('users', (table) => {
6840
+ table.string('stripe_customer_id').nullable();
6841
+ });
6842
+ }
6843
+
6844
+ async down() {
6845
+ await this.schema.alterTable('users', (table) => {
6846
+ table.dropColumn('stripe_customer_id');
6847
+ });
6848
+ }
6849
+ }
6850
+ `}static createSubscriptionPlansTable(){return`import { Migration } from '@beeblock/svelar/database';
6851
+
6852
+ export default class CreateSubscriptionPlansTable extends Migration {
6853
+ async up() {
6854
+ await this.schema.createTable('subscription_plans', (table) => {
6855
+ table.increments('id').primary();
6856
+ table.string('name');
6857
+ table.string('stripe_price_id').unique();
6858
+ table.string('stripe_product_id');
6859
+ table.integer('price');
6860
+ table.string('currency').defaultTo('usd');
6861
+ table.string('interval').defaultTo('month');
6862
+ table.integer('interval_count').defaultTo(1);
6863
+ table.integer('trial_days').defaultTo(0);
6864
+ table.text('features').defaultTo('[]');
6865
+ table.integer('sort_order').defaultTo(0);
6866
+ table.integer('active').defaultTo(1);
6867
+ table.string('created_at');
6868
+ table.string('updated_at');
6869
+ });
6870
+ }
6871
+
6872
+ async down() {
6873
+ await this.schema.dropTable('subscription_plans');
6874
+ }
6875
+ }
6876
+ `}static createSubscriptionsTable(){return`import { Migration } from '@beeblock/svelar/database';
6877
+
6878
+ export default class CreateSubscriptionsTable extends Migration {
6879
+ async up() {
6880
+ await this.schema.createTable('subscriptions', (table) => {
6881
+ table.increments('id').primary();
6882
+ table.integer('user_id');
6883
+ table.string('stripe_subscription_id').unique();
6884
+ table.string('stripe_customer_id');
6885
+ table.integer('plan_id');
6886
+ table.string('status').defaultTo('active');
6887
+ table.string('current_period_start');
6888
+ table.string('current_period_end');
6889
+ table.integer('cancel_at_period_end').defaultTo(0);
6890
+ table.string('trial_ends_at').nullable();
6891
+ table.string('canceled_at').nullable();
6892
+ table.string('created_at');
6893
+ table.string('updated_at');
6894
+ });
6895
+ }
6896
+
6897
+ async down() {
6898
+ await this.schema.dropTable('subscriptions');
6899
+ }
6900
+ }
6901
+ `}static createInvoicesTable(){return`import { Migration } from '@beeblock/svelar/database';
6902
+
6903
+ export default class CreateInvoicesTable extends Migration {
6904
+ async up() {
6905
+ await this.schema.createTable('invoices', (table) => {
6906
+ table.increments('id').primary();
6907
+ table.integer('user_id');
6908
+ table.integer('subscription_id').nullable();
6909
+ table.string('stripe_invoice_id').unique();
6910
+ table.integer('amount_due');
6911
+ table.integer('amount_paid');
6912
+ table.string('currency').defaultTo('usd');
6913
+ table.string('status').defaultTo('open');
6914
+ table.string('paid_at').nullable();
6915
+ table.string('due_date').nullable();
6916
+ table.text('invoice_pdf').nullable();
6917
+ table.string('created_at');
6918
+ table.string('updated_at').nullable();
6919
+ });
6920
+ }
6921
+
6922
+ async down() {
6923
+ await this.schema.dropTable('invoices');
6924
+ }
6925
+ }
6926
+ `}static billingPageServer(){return`import type { Actions, PageServerLoad } from './$types';
6927
+ import { fail, redirect } from '@sveltejs/kit';
6928
+ import { Stripe } from '@beeblock/svelar/stripe';
6929
+
6930
+ export const load: PageServerLoad = async ({ locals }) => {
6931
+ const user = locals.user as any;
6932
+ let subscription: any = null;
6933
+ let invoices: any[] = [];
6934
+ const plans: any[] = [];
6935
+
6936
+ try {
6937
+ const service = Stripe.service();
6938
+ if (user.stripe_customer_id) {
6939
+ const client = await service.getClient();
6940
+ const subs = await client.subscriptions.list({
6941
+ customer: user.stripe_customer_id,
6942
+ limit: 1,
6943
+ expand: ['data.default_payment_method'],
6944
+ });
6945
+ if (subs.data.length > 0) {
6946
+ const sub = subs.data[0] as any;
6947
+ subscription = {
6948
+ id: sub.id,
6949
+ status: sub.status,
6950
+ cancelAtPeriodEnd: sub.cancel_at_period_end,
6951
+ currentPeriodEnd: sub.current_period_end
6952
+ ? new Date(typeof sub.current_period_end === 'number' ? sub.current_period_end * 1000 : sub.current_period_end).toISOString()
6953
+ : null,
6954
+ trialEnd: sub.trial_end
6955
+ ? new Date(typeof sub.trial_end === 'number' ? sub.trial_end * 1000 : sub.trial_end).toISOString()
6956
+ : null,
6957
+ plan: {
6958
+ nickname: sub.items?.data?.[0]?.price?.nickname ?? 'Plan',
6959
+ amount: sub.items?.data?.[0]?.price?.unit_amount ?? 0,
6960
+ currency: sub.items?.data?.[0]?.price?.currency ?? 'usd',
6961
+ interval: sub.items?.data?.[0]?.price?.recurring?.interval ?? 'month',
6962
+ },
6963
+ };
6964
+ }
6965
+
6966
+ const invResponse = await service.getInvoices(user.stripe_customer_id, 10);
6967
+ invoices = invResponse.map((inv: any) => ({
6968
+ id: inv.id,
6969
+ amountDue: inv.amount_due,
6970
+ amountPaid: inv.amount_paid,
6971
+ currency: inv.currency,
6972
+ status: inv.status,
6973
+ created: new Date(typeof inv.created === 'number' ? inv.created * 1000 : inv.created).toISOString(),
6974
+ invoicePdf: inv.invoice_pdf ?? null,
6975
+ hostedUrl: inv.hosted_invoice_url ?? null,
6976
+ }));
6977
+ }
6978
+ } catch {}
6979
+
6980
+ return { user: { id: user.id, name: user.name, email: user.email, stripeCustomerId: user.stripe_customer_id }, subscription, invoices, plans };
6981
+ };
6982
+
6983
+ export const actions: Actions = {
6984
+ portal: async ({ locals }) => {
6985
+ const user = locals.user as any;
6986
+ if (!user?.stripe_customer_id) return fail(400, { error: 'No billing account' });
6987
+
6988
+ try {
6989
+ const session = await Stripe.service().createPortalSession(
6990
+ user.stripe_customer_id,
6991
+ '/dashboard/billing',
6992
+ );
6993
+ throw redirect(303, session.url);
6994
+ } catch (e: any) {
6995
+ if (e.status === 303) throw e;
6996
+ return fail(500, { error: e.message ?? 'Failed to open portal' });
6997
+ }
6998
+ },
6999
+
7000
+ cancel: async ({ locals }) => {
7001
+ const user = locals.user as any;
7002
+ if (!user?.stripe_customer_id) return fail(400, { error: 'No billing account' });
7003
+
7004
+ try {
7005
+ const client = await Stripe.service().getClient();
7006
+ const subs = await client.subscriptions.list({ customer: user.stripe_customer_id, status: 'active', limit: 1 });
7007
+ if (subs.data.length === 0) return fail(400, { error: 'No active subscription' });
7008
+ await Stripe.service().cancelSubscription(subs.data[0].id, false);
7009
+ return { success: true, canceled: true };
7010
+ } catch (e: any) {
7011
+ return fail(500, { error: e.message ?? 'Failed to cancel' });
7012
+ }
7013
+ },
7014
+
7015
+ resume: async ({ locals }) => {
7016
+ const user = locals.user as any;
7017
+ if (!user?.stripe_customer_id) return fail(400, { error: 'No billing account' });
7018
+
7019
+ try {
7020
+ const client = await Stripe.service().getClient();
7021
+ const subs = await client.subscriptions.list({ customer: user.stripe_customer_id, limit: 1 });
7022
+ if (subs.data.length === 0) return fail(400, { error: 'No subscription found' });
7023
+ await Stripe.service().resumeSubscription(subs.data[0].id);
7024
+ return { success: true, resumed: true };
7025
+ } catch (e: any) {
7026
+ return fail(500, { error: e.message ?? 'Failed to resume' });
7027
+ }
7028
+ },
7029
+ };
7030
+ `}static billingPageSvelte(){return`<script lang="ts">
7031
+ import { enhance } from '$app/forms';
7032
+ import { Button, Badge, Card, CardHeader, CardTitle, CardContent, Alert } from '@beeblock/svelar/ui';
7033
+
7034
+ let { data, form: actionData } = $props();
7035
+
7036
+ function formatCurrency(amount: number, currency: string): string {
7037
+ return new Intl.NumberFormat('en-US', { style: 'currency', currency: currency.toUpperCase() }).format(amount / 100);
7038
+ }
7039
+
7040
+ function statusColor(status: string): 'default' | 'secondary' | 'destructive' {
7041
+ if (status === 'active' || status === 'trialing' || status === 'paid') return 'default';
7042
+ if (status === 'past_due' || status === 'incomplete') return 'secondary';
7043
+ return 'destructive';
7044
+ }
7045
+ </script>
7046
+
7047
+ <svelte:head>
7048
+ <title>Billing</title>
7049
+ </svelte:head>
7050
+
7051
+ <div class="space-y-8">
7052
+ <div>
7053
+ <h1 class="text-3xl font-bold text-gray-900">Billing</h1>
7054
+ <p class="text-gray-600 mt-1">Manage your subscription and billing</p>
7055
+ </div>
7056
+
7057
+ {#if actionData?.error}
7058
+ <Alert variant="destructive"><span class="text-sm">{actionData.error}</span></Alert>
7059
+ {/if}
7060
+ {#if actionData?.canceled}
7061
+ <Alert variant="default"><span class="text-sm">Subscription will cancel at end of billing period.</span></Alert>
7062
+ {/if}
7063
+ {#if actionData?.resumed}
7064
+ <Alert variant="default"><span class="text-sm">Subscription resumed successfully.</span></Alert>
7065
+ {/if}
7066
+
7067
+ <Card>
7068
+ <CardHeader>
7069
+ <CardTitle>Current Plan</CardTitle>
7070
+ </CardHeader>
7071
+ <CardContent>
7072
+ {#if data.subscription}
7073
+ <div class="flex items-start justify-between">
7074
+ <div>
7075
+ <div class="flex items-center gap-2 mb-2">
7076
+ <h3 class="text-xl font-semibold text-gray-900">{data.subscription.plan.nickname}</h3>
7077
+ <Badge variant={statusColor(data.subscription.status)}>{data.subscription.status}</Badge>
7078
+ </div>
7079
+ <p class="text-2xl font-bold text-brand">
7080
+ {formatCurrency(data.subscription.plan.amount, data.subscription.plan.currency)}/{data.subscription.plan.interval}
7081
+ </p>
7082
+ {#if data.subscription.trialEnd}
7083
+ <p class="text-sm text-gray-500 mt-1">Trial ends {new Date(data.subscription.trialEnd).toLocaleDateString()}</p>
7084
+ {/if}
7085
+ {#if data.subscription.cancelAtPeriodEnd}
7086
+ <p class="text-sm text-orange-600 mt-1">Cancels on {new Date(data.subscription.currentPeriodEnd).toLocaleDateString()}</p>
7087
+ {:else if data.subscription.currentPeriodEnd}
7088
+ <p class="text-sm text-gray-500 mt-1">Renews {new Date(data.subscription.currentPeriodEnd).toLocaleDateString()}</p>
7089
+ {/if}
7090
+ </div>
7091
+ <div class="flex flex-col gap-2">
7092
+ <form method="POST" action="?/portal" use:enhance>
7093
+ <Button type="submit" variant="outline" size="sm">Manage Payment</Button>
7094
+ </form>
7095
+ {#if data.subscription.cancelAtPeriodEnd}
7096
+ <form method="POST" action="?/resume" use:enhance>
7097
+ <Button type="submit" size="sm">Resume</Button>
7098
+ </form>
7099
+ {:else if data.subscription.status === 'active' || data.subscription.status === 'trialing'}
7100
+ <form method="POST" action="?/cancel" use:enhance>
7101
+ <Button type="submit" variant="destructive" size="sm"
7102
+ onclick={(e) => { if (!confirm('Cancel your subscription? You will retain access until the end of the billing period.')) e.preventDefault(); }}>
7103
+ Cancel Plan
7104
+ </Button>
7105
+ </form>
7106
+ {/if}
7107
+ </div>
7108
+ </div>
7109
+ {:else}
7110
+ <div class="text-center py-6">
7111
+ <p class="text-gray-500 mb-4">No active subscription</p>
7112
+ <p class="text-sm text-gray-400">Contact us or visit the pricing page to get started.</p>
7113
+ </div>
7114
+ {/if}
7115
+ </CardContent>
7116
+ </Card>
7117
+
7118
+ <div>
7119
+ <h2 class="text-xl font-bold text-gray-900 mb-4">Invoice History</h2>
7120
+ {#if data.invoices.length === 0}
7121
+ <Card>
7122
+ <CardContent class="pt-8 text-center">
7123
+ <p class="text-gray-500 text-sm">No invoices yet.</p>
7124
+ </CardContent>
7125
+ </Card>
7126
+ {:else}
7127
+ <div class="border rounded-lg overflow-hidden">
7128
+ <table class="w-full text-sm">
7129
+ <thead class="bg-gray-50 text-left">
7130
+ <tr>
7131
+ <th class="px-4 py-3 text-gray-600 font-medium">Date</th>
7132
+ <th class="px-4 py-3 text-gray-600 font-medium">Amount</th>
7133
+ <th class="px-4 py-3 text-gray-600 font-medium">Status</th>
7134
+ <th class="px-4 py-3 text-gray-600 font-medium text-right">Invoice</th>
7135
+ </tr>
7136
+ </thead>
7137
+ <tbody class="divide-y">
7138
+ {#each data.invoices as inv (inv.id)}
7139
+ <tr class="hover:bg-gray-50">
7140
+ <td class="px-4 py-3">{new Date(inv.created).toLocaleDateString()}</td>
7141
+ <td class="px-4 py-3 font-medium">{formatCurrency(inv.amountDue, inv.currency)}</td>
7142
+ <td class="px-4 py-3"><Badge variant={statusColor(inv.status)}>{inv.status}</Badge></td>
7143
+ <td class="px-4 py-3 text-right">
7144
+ {#if inv.invoicePdf}
7145
+ <a href={inv.invoicePdf} target="_blank" rel="noopener" class="text-brand hover:underline text-xs">PDF</a>
7146
+ {/if}
7147
+ {#if inv.hostedUrl}
7148
+ <a href={inv.hostedUrl} target="_blank" rel="noopener" class="text-brand hover:underline text-xs ml-2">View</a>
7149
+ {/if}
7150
+ </td>
7151
+ </tr>
7152
+ {/each}
7153
+ </tbody>
7154
+ </table>
7155
+ </div>
7156
+ {/if}
7157
+ </div>
7158
+ </div>
7159
+ `}static stripeWebhookRoute(){return`import type { RequestHandler } from './$types';
7160
+ import { Stripe } from '@beeblock/svelar/stripe';
7161
+
7162
+ export const POST: RequestHandler = async ({ request }) => {
7163
+ const signature = request.headers.get('stripe-signature');
7164
+ if (!signature) {
7165
+ return new Response(JSON.stringify({ error: 'Missing signature' }), { status: 400 });
7166
+ }
7167
+
7168
+ try {
7169
+ const body = await request.text();
7170
+ const event = await Stripe.service().constructWebhookEvent(body, signature);
7171
+ await Stripe.webhooks().handle(event);
7172
+ return new Response(JSON.stringify({ received: true }), { status: 200 });
7173
+ } catch (err: any) {
7174
+ console.error('Stripe webhook error:', err.message);
7175
+ return new Response(JSON.stringify({ error: 'Webhook failed' }), { status: 400 });
7176
+ }
7177
+ };
7178
+ `}static apiAdminBillingSubscriptions(){return`import type { RequestHandler } from './$types';
7179
+ import { Stripe } from '@beeblock/svelar/stripe';
7180
+
7181
+ export const GET: RequestHandler = async ({ url }) => {
7182
+ try {
7183
+ const limit = Number(url.searchParams.get('limit') ?? '25');
7184
+ const startingAfter = url.searchParams.get('starting_after') ?? undefined;
7185
+ const client = await Stripe.service().getClient();
7186
+ const subs = await client.subscriptions.list({
7187
+ limit,
7188
+ starting_after: startingAfter,
7189
+ expand: ['data.customer'],
7190
+ });
7191
+
7192
+ const data = subs.data.map((sub: any) => ({
7193
+ id: sub.id,
7194
+ status: sub.status,
7195
+ cancelAtPeriodEnd: sub.cancel_at_period_end,
7196
+ customer: {
7197
+ id: typeof sub.customer === 'string' ? sub.customer : sub.customer?.id,
7198
+ email: typeof sub.customer === 'object' ? sub.customer?.email : null,
7199
+ name: typeof sub.customer === 'object' ? sub.customer?.name : null,
7200
+ },
7201
+ plan: {
7202
+ nickname: sub.items?.data?.[0]?.price?.nickname ?? 'Plan',
7203
+ amount: sub.items?.data?.[0]?.price?.unit_amount ?? 0,
7204
+ currency: sub.items?.data?.[0]?.price?.currency ?? 'usd',
7205
+ interval: sub.items?.data?.[0]?.price?.recurring?.interval ?? 'month',
7206
+ },
7207
+ created: sub.created,
7208
+ }));
7209
+
7210
+ return new Response(JSON.stringify({ subscriptions: data, hasMore: subs.has_more }), {
7211
+ headers: { 'Content-Type': 'application/json' },
7212
+ });
7213
+ } catch (err: any) {
7214
+ return new Response(JSON.stringify({ error: err.message }), { status: 500 });
7215
+ }
7216
+ };
7217
+ `}static apiAdminBillingRefund(){return`import type { RequestHandler } from './$types';
7218
+ import { Stripe } from '@beeblock/svelar/stripe';
7219
+
7220
+ export const POST: RequestHandler = async ({ request }) => {
7221
+ try {
7222
+ const { invoiceId } = await request.json();
7223
+ if (!invoiceId) {
7224
+ return new Response(JSON.stringify({ error: 'invoiceId is required' }), { status: 400 });
7225
+ }
7226
+
7227
+ const refund = await Stripe.service().refundInvoice(invoiceId);
7228
+ return new Response(JSON.stringify({ refund: { id: refund.id, amount: refund.amount, status: refund.status } }), {
7229
+ headers: { 'Content-Type': 'application/json' },
7230
+ });
7231
+ } catch (err: any) {
7232
+ return new Response(JSON.stringify({ error: err.message }), { status: 500 });
7233
+ }
7234
+ };
7235
+ `}static apiAdminBillingCancel(){return`import type { RequestHandler } from './$types';
7236
+ import { Stripe } from '@beeblock/svelar/stripe';
7237
+
7238
+ export const POST: RequestHandler = async ({ request }) => {
7239
+ try {
7240
+ const { subscriptionId, immediately } = await request.json();
7241
+ if (!subscriptionId) {
7242
+ return new Response(JSON.stringify({ error: 'subscriptionId is required' }), { status: 400 });
7243
+ }
7244
+
7245
+ const sub = await Stripe.service().cancelSubscription(subscriptionId, immediately ?? false);
7246
+ return new Response(JSON.stringify({ subscription: { id: sub.id, status: sub.status, cancel_at_period_end: sub.cancel_at_period_end } }), {
7247
+ headers: { 'Content-Type': 'application/json' },
7248
+ });
7249
+ } catch (err: any) {
7250
+ return new Response(JSON.stringify({ error: err.message }), { status: 500 });
7251
+ }
7252
+ };
7253
+ `}};var ss=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:a}=await import("fs"),{execSync:l}=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 m=t.flat||!1,h=m?"flat":"DDD modular";this.log(""),this.log(` \x1B[1m\x1B[38;5;208m</> Svelar\x1B[0m \u2014 Creating new project (${h})
7254
+ `);let d=($,Be)=>{let us=m?yo($):$,Fe=m?vo(Be,$):Be,He=s(u,us);n(s(He,".."),{recursive:!0}),a(He,Fe)};this.info("Creating project structure...");let b=m?["","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/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"]:["","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/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"];for(let $ of b)n(s(u,$),{recursive:!0});this.info("Writing config files...");let{dirname:w}=await import("path"),{fileURLToPath:E}=await import("url"),cs=s(w(w(w(E(import.meta.url)))),"package.json"),Ue=JSON.parse((await import("fs")).readFileSync(cs,"utf-8")).version??"0.4.0";d("package.json",p.packageJson(c,Ue)),d("svelte.config.js",p.svelteConfig()),d("vite.config.ts",p.viteConfig()),d("tsconfig.json",p.tsConfig()),d("src/app.html",p.appHtml()),d("static/favicon.svg",p.faviconSvg()),d("src/app.css",p.appCss()),d("src/app.ts",p.appTs()),d("src/hooks.server.ts",p.hooksServerTs()),d(".env.example",p.envExample());let{randomBytes:z}=await import("crypto"),fe=z(32).toString("hex"),be=z(16).toString("hex"),_r=p.envExample().replace("APP_KEY=change-me-to-a-random-string",`APP_KEY=${fe}`).replace("INTERNAL_SECRET=change-me-to-a-random-string",`INTERNAL_SECRET=${be}`);d(".env",_r),d(".gitignore",p.gitignore()),d("svelar.database.json",p.svelarDatabaseJson());for(let $ of["storage/logs","storage/cache","storage/uploads","storage/sessions"])d(`${$}/.gitkeep`,"");if(this.info("Scaffolding domain layer..."),d("src/lib/modules/auth/User.ts",p.userModel()),d("src/lib/modules/auth/UserRepository.ts",p.userRepository()),d("src/lib/modules/auth/AuthService.ts",p.authService()),d("src/lib/modules/auth/AuthController.ts",p.authController()),d("src/lib/modules/auth/RegisterUserAction.ts",p.registerUserAction()),d("src/lib/modules/auth/RegisterRequest.ts",p.registerRequest()),d("src/lib/modules/auth/LoginRequest.ts",p.loginRequest()),d("src/lib/modules/auth/ForgotPasswordRequest.ts",p.forgotPasswordRequest()),d("src/lib/modules/auth/ResetPasswordRequest.ts",p.resetPasswordRequest()),d("src/lib/modules/auth/OtpSendRequest.ts",p.otpSendRequest()),d("src/lib/modules/auth/OtpVerifyRequest.ts",p.otpVerifyRequest()),d("src/lib/modules/auth/UserResource.ts",p.userResource()),d("src/lib/modules/auth/gates.ts",p.gates()),d("src/lib/modules/auth/schemas.ts",p.authSchema()),d("src/lib/modules/auth/UserRegistered.ts",p.userRegisteredEvent()),d("src/lib/modules/auth/SendWelcomeEmailListener.ts",p.sendWelcomeEmailListener()),d("src/lib/modules/auth/WelcomeNotification.ts",p.welcomeNotification()),d("src/lib/modules/posts/Post.ts",p.postModel()),d("src/lib/modules/posts/PostRepository.ts",p.postRepository()),d("src/lib/modules/posts/PostService.ts",p.postService()),d("src/lib/modules/posts/PostController.ts",p.postController()),d("src/lib/modules/posts/CreatePostAction.ts",p.createPostAction()),d("src/lib/modules/posts/CreatePostRequest.ts",p.createPostRequest()),d("src/lib/modules/posts/UpdatePostRequest.ts",p.updatePostRequest()),d("src/lib/modules/posts/PostResource.ts",p.postResource()),d("src/lib/modules/posts/schemas.ts",p.postSchema()),d("src/lib/modules/admin/AdminService.ts",p.adminService()),d("src/lib/modules/admin/AdminController.ts",p.adminController()),d("src/lib/modules/admin/UpdateUserRoleRequest.ts",p.updateUserRoleRequest()),d("src/lib/modules/admin/DeleteUserRequest.ts",p.deleteUserRequest()),d("src/lib/modules/admin/CreateRoleRequest.ts",p.createRoleRequest()),d("src/lib/modules/admin/DeleteRoleRequest.ts",p.deleteRoleRequest()),d("src/lib/modules/admin/CreatePermissionRequest.ts",p.createPermissionRequest()),d("src/lib/modules/admin/DeletePermissionRequest.ts",p.deletePermissionRequest()),d("src/lib/modules/admin/RolePermissionRequest.ts",p.rolePermissionRequest()),d("src/lib/modules/admin/UserRoleRequest.ts",p.userRoleRequest()),d("src/lib/modules/admin/UserPermissionRequest.ts",p.userPermissionRequest()),d("src/lib/modules/admin/ExportDataRequest.ts",p.exportDataRequest()),d("src/lib/modules/admin/RoleResource.ts",p.roleResource()),d("src/lib/modules/admin/PermissionResource.ts",p.permissionResource()),d("src/lib/modules/admin/schemas.ts",p.adminSchema()),d("src/lib/shared/providers/EventServiceProvider.ts",p.eventServiceProvider()),this.info("Creating migrations..."),d("src/lib/database/migrations/00000001_create_users_table.ts",p.createUsersTable()),d("src/lib/database/migrations/00000002_create_posts_table.ts",p.createPostsTable()),d("src/lib/database/migrations/00000003_create_permissions_tables.ts",p.createPermissionsTables()),d("src/lib/database/migrations/00000004_add_role_to_users.ts",p.addRoleToUsers()),d("src/lib/database/migrations/00000005_create_sessions_table.ts",p.createSessionsTable()),d("src/lib/database/migrations/00000006_create_audit_logs_table.ts",p.createAuditLogsTable()),d("src/lib/database/migrations/00000007_create_notifications_table.ts",p.createNotificationsTable()),d("src/lib/database/migrations/00000008_create_failed_jobs_table.ts",p.createFailedJobsTable()),d("src/lib/database/migrations/00000009_add_stripe_to_users.ts",p.addStripeToUsers()),d("src/lib/database/migrations/00000010_create_subscription_plans.ts",p.createSubscriptionPlansTable()),d("src/lib/database/migrations/00000011_create_subscriptions.ts",p.createSubscriptionsTable()),d("src/lib/database/migrations/00000012_create_invoices.ts",p.createInvoicesTable()),d("src/lib/database/seeders/DatabaseSeeder.ts",p.databaseSeeder()),this.info("Creating auth pages..."),d("src/routes/login/+page.server.ts",p.loginPageServer()),d("src/routes/login/+page.svelte",p.loginPageSvelte()),d("src/routes/register/+page.server.ts",p.registerPageServer()),d("src/routes/register/+page.svelte",p.registerPageSvelte()),d("src/routes/logout/+page.server.ts",p.logoutPageServer()),d("src/routes/forgot-password/+page.server.ts",p.forgotPasswordPageServer()),d("src/routes/forgot-password/+page.svelte",p.forgotPasswordPageSvelte()),d("src/routes/reset-password/+page.server.ts",p.resetPasswordPageServer()),d("src/routes/reset-password/+page.svelte",p.resetPasswordPageSvelte()),d("src/routes/otp-login/+page.server.ts",p.otpLoginPageServer()),d("src/routes/otp-login/+page.svelte",p.otpLoginPageSvelte()),d("src/routes/verify-email/+page.server.ts",p.verifyEmailPageServer()),d("src/routes/verify-email/+page.svelte",p.verifyEmailPageSvelte()),this.info("Creating dashboard..."),d("src/routes/dashboard/+layout.server.ts",p.dashboardLayoutServer()),d("src/routes/dashboard/+layout.svelte",p.dashboardLayoutSvelte()),d("src/routes/dashboard/+page.server.ts",p.dashboardPageServer()),d("src/routes/dashboard/+page.svelte",p.dashboardPageSvelte()),d("src/routes/dashboard/api-keys/+page.server.ts",p.apiKeysPageServer()),d("src/routes/dashboard/api-keys/+page.svelte",p.apiKeysPageSvelte()),d("src/routes/dashboard/team/+page.server.ts",p.teamPageServer()),d("src/routes/dashboard/team/+page.svelte",p.teamPageSvelte()),d("src/routes/dashboard/billing/+page.server.ts",p.billingPageServer()),d("src/routes/dashboard/billing/+page.svelte",p.billingPageSvelte()),this.info("Creating admin panel..."),d("src/routes/admin/+layout.server.ts",p.adminLayoutServer()),d("src/routes/admin/+layout.svelte",p.adminLayoutSvelte()),d("src/routes/admin/+page.server.ts",p.adminPageServer()),d("src/routes/admin/+page.svelte",p.adminPageSvelte()),this.info("Creating API routes..."),d("src/routes/api/health/+server.ts",p.apiHealth()),d("src/routes/api/auth/register/+server.ts",p.apiAuthRegister()),d("src/routes/api/auth/login/+server.ts",p.apiAuthLogin()),d("src/routes/api/auth/logout/+server.ts",p.apiAuthLogout()),d("src/routes/api/auth/me/+server.ts",p.apiAuthMe()),d("src/routes/api/auth/forgot-password/+server.ts",p.apiAuthForgotPassword()),d("src/routes/api/auth/reset-password/+server.ts",p.apiAuthResetPassword()),d("src/routes/api/auth/otp/send/+server.ts",p.apiAuthOtpSend()),d("src/routes/api/auth/otp/verify/+server.ts",p.apiAuthOtpVerify()),d("src/routes/api/auth/verify-email/+server.ts",p.apiAuthVerifyEmail()),d("src/routes/api/posts/+server.ts",p.apiPosts()),d("src/routes/api/posts/[id]/+server.ts",p.apiPostsSingle()),d("src/routes/api/posts/mine/+server.ts",p.apiPostsMine()),d("src/routes/api/broadcasting/[channel]/+server.ts",p.apiBroadcasting()),d("src/routes/api/internal/broadcast/+server.ts",p.apiInternalBroadcast()),d("src/routes/api/admin/users/+server.ts",p.apiAdminUsers()),d("src/routes/api/admin/roles/+server.ts",p.apiAdminRoles()),d("src/routes/api/admin/permissions/+server.ts",p.apiAdminPermissions()),d("src/routes/api/admin/role-permissions/+server.ts",p.apiAdminRolePermissions()),d("src/routes/api/admin/user-roles/+server.ts",p.apiAdminUserRoles()),d("src/routes/api/admin/user-permissions/+server.ts",p.apiAdminUserPermissions()),d("src/routes/api/admin/export/+server.ts",p.apiAdminExport()),d("src/routes/api/admin/health/+server.ts",p.apiAdminHealth()),d("src/routes/api/admin/queue/+server.ts",p.apiAdminQueue()),d("src/routes/api/admin/queue/[id]/retry/+server.ts",p.apiAdminQueueRetry()),d("src/routes/api/admin/queue/[id]/+server.ts",p.apiAdminQueueDelete()),d("src/routes/api/admin/scheduler/+server.ts",p.apiAdminScheduler()),d("src/routes/api/admin/scheduler/[name]/run/+server.ts",p.apiAdminSchedulerRun()),d("src/routes/api/admin/scheduler/[name]/toggle/+server.ts",p.apiAdminSchedulerToggle()),d("src/routes/api/admin/logs/+server.ts",p.apiAdminLogs()),d("src/routes/api/admin/stats/+server.ts",p.apiAdminStats()),d("src/routes/api/admin/billing/subscriptions/+server.ts",p.apiAdminBillingSubscriptions()),d("src/routes/api/admin/billing/refund/+server.ts",p.apiAdminBillingRefund()),d("src/routes/api/admin/billing/cancel/+server.ts",p.apiAdminBillingCancel()),d("src/routes/api/webhooks/stripe/+server.ts",p.stripeWebhookRoute()),this.info("Creating background jobs..."),d("src/lib/shared/jobs/SendWelcomeEmail.ts",p.sendWelcomeEmail()),d("src/lib/shared/jobs/DailyDigestJob.ts",p.dailyDigestJob()),d("src/lib/shared/jobs/ExportDataJob.ts",p.exportDataJob()),this.info("Creating scheduled tasks..."),d("src/lib/shared/scheduler/CleanupExpiredTokens.ts",p.cleanupExpiredTokens()),d("src/lib/shared/scheduler/CleanExpiredSessions.ts",p.cleanExpiredSessions()),d("src/lib/shared/scheduler/DailyDigestEmail.ts",p.dailyDigestEmail()),d("src/lib/shared/scheduler/PruneAuditLogs.ts",p.pruneAuditLogs()),d("src/lib/shared/scheduler/QueueHealthCheck.ts",p.queueHealthCheck()),this.info("Creating layouts..."),d("src/routes/+layout.svelte",p.rootLayoutSvelte(c)),d("src/routes/+layout.server.ts",p.rootLayoutServer()),d("src/routes/+error.svelte",p.errorSvelte()),d("src/routes/+page.svelte",p.homePage(c)),this.success(`Project structure created (${h})`),!t["no-install"]){this.info("Installing dependencies...");try{l("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("Running migrations...");try{l("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{l("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!
6615
7255
  `),this.log(` Next steps:
6616
- `),this.log(` cd ${c}`),t["no-install"]&&(this.log(" npm install"),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 ho(o){return/Service\./.test(o)?"services":/Controller\./.test(o)?"controllers":/Repository\./.test(o)?"repositories":/Request\./.test(o)?"dtos":/Resource\./.test(o)?"resources":/Action\./.test(o)?"actions":/Listener\./.test(o)?"listeners":/Notification\./.test(o)?"notifications":/Registered|Created|Updated|Deleted|Verified|Invited/.test(o)?"events":"models"}function go(o){let e=o.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/${ho(r)}/${r}`}let t=o.match(/^src\/lib\/shared\/(.+)$/);return t?`src/lib/${t[1]}`:o}function Sr(o,e,t){return e==="schemas"?`$lib/schemas/${o}${t}`:e==="gates"?`$lib/gates${t}`:`$lib/${mn(e)}/${e}${t}`}function mn(o){return/Service$/.test(o)?"services":/Controller$/.test(o)?"controllers":/Repository$/.test(o)?"repositories":/Request$/.test(o)?"dtos":/Resource$/.test(o)?"resources":/Action$/.test(o)?"actions":/Listener$/.test(o)?"listeners":/Notification$/.test(o)?"notifications":/Registered|Created|Updated|Deleted|Verified|Invited/.test(o)?"events":"models"}function fo(o,e){let s=e.match(/modules\/(\w+)\//)?.[1]||"";return o=o.replace(/\$lib\/modules\/(\w+)\/(\w+)(\.js)?/g,(r,i,n,a)=>Sr(i,n,a||"")),o=o.replace(/\.\/lib\/modules\/(\w+)\/(\w+)(\.js)?/g,(r,i,n,a)=>n==="schemas"?`./lib/schemas/${i}${a||""}`:n==="gates"?`./lib/gates${a||""}`:`./lib/${mn(n)}/${n}${a||""}`),o=o.replace(/\$lib\/shared\//g,"$lib/"),o=o.replace(/\.\/lib\/shared\//g,"./lib/"),s&&(o=o.replace(/from '\.\/(\w+)(\.js)?'/g,(r,i,n)=>i.startsWith("$")||i==="app"?r:(n=n||"",`from '${Sr(s,i,n)}'`)),o=o.replace(/import '\.\/(\w+)(\.js)?'/g,(r,i,n)=>i.startsWith("$")||i==="app"?r:(n=n||"",`import '${Sr(s,i,n)}'`))),o}var ss=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:a}=await import("fs"),l=s(32).toString("hex");if(t.show){this.log(`
7256
+ `),this.log(` cd ${c}`),t["no-install"]&&(this.log(" npm install"),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 bo(o){return/Service\./.test(o)?"services":/Controller\./.test(o)?"controllers":/Repository\./.test(o)?"repositories":/Request\./.test(o)?"dtos":/Resource\./.test(o)?"resources":/Action\./.test(o)?"actions":/Listener\./.test(o)?"listeners":/Notification\./.test(o)?"notifications":/Registered|Created|Updated|Deleted|Verified|Invited/.test(o)?"events":"models"}function yo(o){let e=o.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/${bo(r)}/${r}`}let t=o.match(/^src\/lib\/shared\/(.+)$/);return t?`src/lib/${t[1]}`:o}function Tr(o,e,t){return e==="schemas"?`$lib/schemas/${o}${t}`:e==="gates"?`$lib/gates${t}`:`$lib/${Gi(e)}/${e}${t}`}function Gi(o){return/Service$/.test(o)?"services":/Controller$/.test(o)?"controllers":/Repository$/.test(o)?"repositories":/Request$/.test(o)?"dtos":/Resource$/.test(o)?"resources":/Action$/.test(o)?"actions":/Listener$/.test(o)?"listeners":/Notification$/.test(o)?"notifications":/Registered|Created|Updated|Deleted|Verified|Invited/.test(o)?"events":"models"}function vo(o,e){let s=e.match(/modules\/(\w+)\//)?.[1]||"";return o=o.replace(/\$lib\/modules\/(\w+)\/(\w+)(\.js)?/g,(r,i,n,a)=>Tr(i,n,a||"")),o=o.replace(/\.\/lib\/modules\/(\w+)\/(\w+)(\.js)?/g,(r,i,n,a)=>n==="schemas"?`./lib/schemas/${i}${a||""}`:n==="gates"?`./lib/gates${a||""}`:`./lib/${Gi(n)}/${n}${a||""}`),o=o.replace(/\$lib\/shared\//g,"$lib/"),o=o.replace(/\.\/lib\/shared\//g,"./lib/"),e.includes("shared/")&&(o=o.replace(/'\.\.\/(\.\.\/\.\.\/)'/g,"'$1'"),o=o.replace(/'\.\.\/\.\.\/\.\.\//g,"'../../")),s&&(o=o.replace(/from '\.\/(\w+)(\.js)?'/g,(r,i,n)=>i.startsWith("$")||i==="app"?r:(n=n||"",`from '${Tr(s,i,n)}'`)),o=o.replace(/import '\.\/(\w+)(\.js)?'/g,(r,i,n)=>i.startsWith("$")||i==="app"?r:(n=n||"",`import '${Tr(s,i,n)}'`))),o}var rs=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:a}=await import("fs"),l=s(32).toString("hex");if(t.show){this.log(`
6617
7257
  APP_KEY=${l}
6618
- `);return}let c=r(process.cwd(),".env");if(!i(c)){let h=r(process.cwd(),".env.example");if(i(h)){let u=n(h,"utf-8");u=u.replace(/^APP_KEY=.*$/m,`APP_KEY=${l}`),a(c,u),this.success("Application key set (created .env from .env.example).")}else a(c,`APP_KEY=${l}
6619
- `),this.success("Application key set (created .env).");return}let d=n(c,"utf-8"),p=d.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=d.replace(/^APP_KEY=.*$/m,`APP_KEY=${l}`);a(c,h)}else a(c,`APP_KEY=${l}
6620
- ${d}`);this.success("Application key set.")}};var ns=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(()=>(is(),Er)),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"],a=i.map(l=>[l.name,l.version,l.description||"-",l.enabled?"\u2713 Enabled":" Disabled",l.hasConfig?"\u2713":"-",l.hasMigrations?"\u2713":"-"]);this.newLine(),this.table(n,a),this.newLine(),this.info(`Total: ${i.length} plugin(s)`)}catch(s){this.error(`Failed to list plugins: ${s?.message??String(s)}`)}}};var as=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(()=>(is(),Er)),{PluginPublisher:i}=await Promise.resolve().then(()=>(Ar(),pn)),n=r,a=i;await n.discover();let l=n.get(s);if(!l){this.error(`Plugin "${s}" not found.`);return}let c=await this.loadPluginClass(l.packageName);if(!c){this.error(`Failed to load plugin class for "${s}".`);return}let d=new c,p={force:t.force||!1,only:t.only};this.info(`Publishing plugin: ${s}`);let h=await a.publish(d,p);this.newLine(),h.configs.length>0&&(this.success(`${h.configs.length} config file(s) published:`),h.configs.forEach(u=>this.log(` - ${u}`))),h.migrations.length>0&&(this.success(`${h.migrations.length} migration file(s) published:`),h.migrations.forEach(u=>this.log(` - ${u}`))),h.assets.length>0&&(this.success(`${h.assets.length} asset file(s) published:`),h.assets.forEach(u=>this.log(` - ${u}`))),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(()=>(gn(),hn)),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 fn=Lr(process.cwd(),".env");if(wo(fn))for(let o of vn(fn,"utf-8").split(`
6621
- `)){let e=o.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 Co=yn(bn(import.meta.url));vo(bo(Lr(Co,"ts-resolve-hook.mjs")).href,import.meta.url);var xo=yn(bn(import.meta.url)),Po=Lr(xo,"..","..","package.json"),Ro=JSON.parse(vn(Po,"utf-8")),b=new Ke(Ro.version);b.register(ts);b.register(ss);b.register(We);b.register(Je);b.register(Ve);b.register(Qe);b.register(Ge);b.register(Ye);b.register(Ze);b.register(Xe);b.register(et);b.register(tt);b.register(dt);b.register(ut);b.register(st);b.register(rt);b.register(it);b.register(nt);b.register(at);b.register(ot);b.register(lt);b.register(ct);b.register(mt);b.register(pt);b.register(ht);b.register(gt);b.register(ft);b.register(yt);b.register(bt);b.register(Ct);b.register(Rt);b.register(St);b.register(Tt);b.register(Et);b.register(es);b.register(ns);b.register(as);b.register(os);async function So(){let{join:o}=await import("path"),{existsSync:e,readdirSync:t}=await import("fs"),{pathToFileURL:s}=await import("url"),r=o(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 a=o(r,n),c=await import(s(a).href),d=c.default??Object.values(c).find(p=>typeof p=="function"&&p.prototype&&"handle"in p.prototype);d&&typeof d=="function"&&b.add(new d)}catch{}}So().then(()=>b.run());
7258
+ `);return}let c=r(process.cwd(),".env");if(!i(c)){let h=r(process.cwd(),".env.example");if(i(h)){let d=n(h,"utf-8");d=d.replace(/^APP_KEY=.*$/m,`APP_KEY=${l}`),a(c,d),this.success("Application key set (created .env from .env.example).")}else a(c,`APP_KEY=${l}
7259
+ `),this.success("Application key set (created .env).");return}let u=n(c,"utf-8"),m=u.match(/^APP_KEY=(.*)$/m);if(m&&m[1]&&m[1]!=="change-me-to-a-random-string"&&!t.force){this.warn("APP_KEY already set. Use --force to overwrite.");return}if(m){let h=u.replace(/^APP_KEY=.*$/m,`APP_KEY=${l}`);a(c,h)}else a(c,`APP_KEY=${l}
7260
+ ${u}`);this.success("Application key set.")}};var as=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(()=>(ns(),kr)),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"],a=i.map(l=>[l.name,l.version,l.description||"-",l.enabled?"\u2713 Enabled":" Disabled",l.hasConfig?"\u2713":"-",l.hasMigrations?"\u2713":"-"]);this.newLine(),this.table(n,a),this.newLine(),this.info(`Total: ${i.length} plugin(s)`)}catch(s){this.error(`Failed to list plugins: ${s?.message??String(s)}`)}}};var os=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(()=>(ns(),kr)),{PluginPublisher:i}=await Promise.resolve().then(()=>(Ar(),Yi)),n=r,a=i;await n.discover();let l=n.get(s);if(!l){this.error(`Plugin "${s}" not found.`);return}let c=await this.loadPluginClass(l.packageName);if(!c){this.error(`Failed to load plugin class for "${s}".`);return}let u=new c,m={force:t.force||!1,only:t.only};this.info(`Publishing plugin: ${s}`);let h=await a.publish(u,m);this.newLine(),h.configs.length>0&&(this.success(`${h.configs.length} config file(s) published:`),h.configs.forEach(d=>this.log(` - ${d}`))),h.migrations.length>0&&(this.success(`${h.migrations.length} migration file(s) published:`),h.migrations.forEach(d=>this.log(` - ${d}`))),h.assets.length>0&&(this.success(`${h.assets.length} asset file(s) published:`),h.assets.forEach(d=>this.log(` - ${d}`))),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 ls=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(()=>(Xi(),Zi)),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 en=Lr(process.cwd(),".env");if(So(en))for(let o of rn(en,"utf-8").split(`
7261
+ `)){let e=o.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 Po=tn(sn(import.meta.url));xo(Co(Lr(Po,"ts-resolve-hook.mjs")).href,import.meta.url);var Ro=tn(sn(import.meta.url)),To=Lr(Ro,"..","..","package.json"),Eo=JSON.parse(rn(To,"utf-8")),v=new Ke(Eo.version);v.register(ss);v.register(rs);v.register(Je);v.register(Ve);v.register(Qe);v.register(Ge);v.register(Ye);v.register(Ze);v.register(Xe);v.register(et);v.register(tt);v.register(st);v.register(ut);v.register(mt);v.register(rt);v.register(it);v.register(nt);v.register(at);v.register(ot);v.register(lt);v.register(ct);v.register(dt);v.register(pt);v.register(ht);v.register(gt);v.register(ft);v.register(bt);v.register(yt);v.register(vt);v.register(xt);v.register(Rt);v.register(Tt);v.register(Et);v.register(kt);v.register(ts);v.register(as);v.register(os);v.register(ls);async function ko(){let{join:o}=await import("path"),{existsSync:e,readdirSync:t}=await import("fs"),{pathToFileURL:s}=await import("url"),r=o(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 a=o(r,n),c=await import(s(a).href),u=c.default??Object.values(c).find(m=>typeof m=="function"&&m.prototype&&"handle"in m.prototype);u&&typeof u=="function"&&v.add(new u)}catch{}}ko().then(()=>v.run());