@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/README.md +1 -0
- package/dist/cli/Command.d.ts +14 -0
- package/dist/cli/bin.js +731 -91
- package/dist/cli/commands/NewCommandTemplates.d.ts +10 -0
- package/dist/cli/index.js +97 -94
- package/dist/cli/ts-resolve-hook.mjs +22 -1
- package/dist/stripe/Invoice.d.ts +44 -0
- package/dist/stripe/StripeService.d.ts +52 -0
- package/dist/stripe/StripeWebhookHandler.d.ts +14 -0
- package/dist/stripe/Subscription.d.ts +40 -0
- package/dist/stripe/SubscriptionManager.d.ts +39 -0
- package/dist/stripe/SubscriptionPlan.d.ts +41 -0
- package/dist/stripe/SyncStripeCustomerJob.d.ts +11 -0
- package/dist/stripe/index.d.ts +22 -0
- package/dist/stripe/index.js +1 -0
- package/package.json +17 -4
package/dist/cli/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
var
|
|
1
|
+
var Jn=Object.defineProperty;var Me=(c=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(c,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):c)(function(c){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+c+'" is not supported')});var y=(c,e)=>()=>(c&&(e=c(c=0)),e);var C=(c,e)=>{for(var t in e)Jn(c,t,{get:e[t],enumerable:!0})};function b(c,e){let t=Symbol.for(c),s=globalThis;return s[t]||(s[t]=e()),s[t]}var E=y(()=>{"use strict"});var T={};C(T,{Connection:()=>g});var bt,g,w=y(()=>{"use strict";E();bt=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),n=this.getConfig(s);switch(n.driver){case"sqlite":{let o=await this.rawClient(s),i=t.map(u=>typeof u=="boolean"?u?1:0:u instanceof Date?u.toISOString():u),a=o.prepare(e),l=e.trimStart().toUpperCase();return l.startsWith("SELECT")||l.startsWith("PRAGMA")||l.startsWith("WITH")?a.all(...i):a.run(...i)}case"postgres":return(await this.rawClient(s))(e,...t);case"mysql":{let o=await this.rawClient(s),[i]=await o.execute(e,t);return i}default:throw new Error(`Unsupported driver: ${n.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 n=await e();return r.exec("COMMIT"),n}catch(n){throw r.exec("ROLLBACK"),n}}case"postgres":{await r`BEGIN`;try{let n=await e();return await r`COMMIT`,n}catch(n){throw await r`ROLLBACK`,n}}case"mysql":{let n=await r.getConnection();await n.beginTransaction();try{let o=await e();return await n.commit(),n.release(),o}catch(o){throw await n.rollback(),n.release(),o}}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"),n=new s(t);return n.pragma("journal_mode = WAL"),n.pragma("foreign_keys = ON"),{drizzle:r(n),config:e,rawClient:n}}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 n=new r(t);n.exec("PRAGMA journal_mode = WAL"),n.exec("PRAGMA foreign_keys = ON");let o={prepare(a){let l=n.prepare(a);return{all(...u){return l.all(...u)},run(...u){return l.run(...u)},get(...u){return l.get(...u)}}},exec(a){n.exec(a)},pragma(a){return n.prepare(`PRAGMA ${a}`).all()},close(){n.close()}},i;try{let{drizzle:a}=await import("drizzle-orm/better-sqlite3");i=a(o)}catch{i=o}return{drizzle:i,config:e,rawClient:o}}}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}`,n=t(r);return{drizzle:s(n),config:e,rawClient:n}}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{}}},g=b("svelar.connection",()=>new bt)});var O,Qt,F,_,Nr,Gt=y(()=>{"use strict";w();E();O=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 Qt(this.column)}build(){return this.column}},Qt=class{constructor(e){this.column=e}onDelete(e){return this.column.references.onDelete=e,this}onUpdate(e){return this.column.references.onUpdate=e,this}},F=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 O(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 O(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 O(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 O(t)}toSQL(e,t){let s=[],r=[];for(let n of this.columns)r.push(this.columnToSQL(n,t));this.compositePrimary&&r.push(`PRIMARY KEY (${this.compositePrimary.join(", ")})`);for(let n of this.columns)if(n.references){let o=`FOREIGN KEY (${n.name}) REFERENCES ${n.references.table}(${n.references.column})`;n.references.onDelete&&(o+=` ON DELETE ${n.references.onDelete}`),n.references.onUpdate&&(o+=` ON UPDATE ${n.references.onUpdate}`),r.push(o)}s.push(`CREATE TABLE ${e} (
|
|
2
2
|
${r.join(`,
|
|
3
3
|
`)}
|
|
4
|
-
)`);for(let n of this.indices){let
|
|
4
|
+
)`);for(let n of this.indices){let o=n.name??`idx_${e}_${n.columns.join("_")}`,i=n.unique?"UNIQUE ":"";s.push(`CREATE ${i}INDEX ${o} ON ${e} (${n.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 n=typeof e.defaultValue=="string"?`'${e.defaultValue}'`:e.defaultValue===null?"NULL":e.defaultValue;s+=` DEFAULT ${n}`}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}},_=class{constructor(e){this.connectionName=e}async createTable(e,t){let s=new F;t(s);let r=g.getDriver(this.connectionName),n=s.toSQL(e,r);for(let o of n)await g.raw(o,[],this.connectionName)}async dropTable(e){await g.raw(`DROP TABLE IF EXISTS ${e}`,[],this.connectionName)}async dropTableIfExists(e){await g.raw(`DROP TABLE IF EXISTS ${e}`,[],this.connectionName)}async renameTable(e,t){g.getDriver(this.connectionName)==="mysql"?await g.raw(`RENAME TABLE ${e} TO ${t}`,[],this.connectionName):await g.raw(`ALTER TABLE ${e} RENAME TO ${t}`,[],this.connectionName)}async hasTable(e){let t=g.getDriver(this.connectionName),s;switch(t){case"sqlite":s=await g.raw("SELECT name FROM sqlite_master WHERE type='table' AND name=?",[e],this.connectionName);break;case"postgres":s=await g.raw("SELECT tablename FROM pg_tables WHERE tablename = $1",[e],this.connectionName);break;case"mysql":s=await g.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 F;t(s);let r=g.getDriver(this.connectionName),n=s.columns;for(let o of n){let i=s.columnToSQL(o,r);await g.raw(`ALTER TABLE ${e} ADD COLUMN ${i}`,[],this.connectionName)}}async dropColumn(e,t){await g.raw(`ALTER TABLE ${e} DROP COLUMN ${t}`,[],this.connectionName)}},Nr=b("svelar.schema",()=>new _)});var Mr={};C(Mr,{Migration:()=>me,Migrator:()=>ge});var me,ge,Yt=y(()=>{"use strict";w();Gt();me=class{schema=new _},ge=class{migrationsTable="svelar_migrations";connectionName;constructor(e){this.connectionName=e}async ensureMigrationsTable(){let e=new _(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(o=>!t.includes(o.name));if(s.length===0)return[];let r=await this.getNextBatch(),n=[];for(let o of s)await o.migration.up(),await g.raw(`INSERT INTO ${this.migrationsTable} (migration, batch) VALUES (?, ?)`,[o.name,r],this.connectionName),n.push(o.name);return n}async rollback(e){await this.ensureMigrationsTable();let t=await this.getLastBatch();if(t===0)return[];let s=await g.raw(`SELECT migration FROM ${this.migrationsTable} WHERE batch = ? ORDER BY id DESC`,[t],this.connectionName),r=[];for(let n of s){let o=n.migration,i=e.find(a=>a.name===o);i&&(await i.migration.down(),await g.raw(`DELETE FROM ${this.migrationsTable} WHERE migration = ?`,[o],this.connectionName),r.push(o))}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=g.getDriver(this.connectionName),t=[];switch(e){case"sqlite":{t=(await g.raw("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'",[],this.connectionName)).map(r=>r.name),await g.raw("PRAGMA foreign_keys = OFF",[],this.connectionName);for(let r of t)await g.raw(`DROP TABLE IF EXISTS "${r}"`,[],this.connectionName);await g.raw("PRAGMA foreign_keys = ON",[],this.connectionName);break}case"mysql":{t=(await g.raw("SHOW TABLES",[],this.connectionName)).map(r=>Object.values(r)[0]),await g.raw("SET FOREIGN_KEY_CHECKS = 0",[],this.connectionName);for(let r of t)await g.raw(`DROP TABLE IF EXISTS \`${r}\``,[],this.connectionName);await g.raw("SET FOREIGN_KEY_CHECKS = 1",[],this.connectionName);break}case"postgres":{t=(await g.raw("SELECT tablename FROM pg_tables WHERE schemaname = 'public'",[],this.connectionName)).map(r=>r.tablename);for(let r of t)await g.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 g.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 g.raw(`SELECT migration, batch FROM ${this.migrationsTable}`,[],this.connectionName);for(let n of r)s.set(n.migration,n.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 g.raw(`SELECT MAX(batch) as max_batch FROM ${this.migrationsTable}`,[],this.connectionName))[0]?.max_batch??0}catch{return 0}}}});var _e={};C(_e,{SchedulerLock:()=>ye});import{hostname as No}from"os";async function fe(){let{Connection:c}=await Promise.resolve().then(()=>(w(),T));return c}async function Mo(){return(await fe()).getDriver()}var Lr,q,ye,be=y(()=>{"use strict";Lr=!1,q=`${No()}:${process.pid}:${Math.random().toString(36).slice(2,10)}`;ye=class{static getOwnerId(){return q}static async ensureTable(){if(Lr)return;let e=await fe();switch(e.getDriver()){case"sqlite":await e.raw(`CREATE TABLE IF NOT EXISTS scheduler_locks (
|
|
5
5
|
task_key TEXT PRIMARY KEY,
|
|
6
6
|
owner TEXT NOT NULL,
|
|
7
7
|
expires_at TEXT NOT NULL
|
|
@@ -13,7 +13,7 @@ var ai=Object.defineProperty;var De=(c=>typeof require<"u"?require:typeof Proxy<
|
|
|
13
13
|
task_key VARCHAR(255) PRIMARY KEY,
|
|
14
14
|
owner VARCHAR(255) NOT NULL,
|
|
15
15
|
expires_at DATETIME NOT NULL
|
|
16
|
-
) ENGINE=InnoDB`);break}
|
|
16
|
+
) ENGINE=InnoDB`);break}Lr=!0}static async acquire(e,t=5){await this.ensureTable();let s=await fe(),r=await Mo(),n=new Date().toISOString(),o=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,n]),r){case"sqlite":await s.raw("INSERT OR IGNORE INTO scheduler_locks (task_key, owner, expires_at) VALUES (?, ?, ?)",[e,q,o]);break;case"postgres":await s.raw("INSERT INTO scheduler_locks (task_key, owner, expires_at) VALUES ($1, $2, $3) ON CONFLICT (task_key) DO NOTHING",[e,q,o]);break;case"mysql":await s.raw("INSERT IGNORE INTO scheduler_locks (task_key, owner, expires_at) VALUES (?, ?, ?)",[e,q,o]);break}});let i=await s.raw("SELECT owner FROM scheduler_locks WHERE task_key = ?",[e]);return i.length>0&&i[0].owner===q}catch{return!1}}static async release(e){try{await(await fe()).raw("DELETE FROM scheduler_locks WHERE task_key = ? AND owner = ?",[e,q])}catch{}}static async releaseAll(){try{await(await fe()).raw("DELETE FROM scheduler_locks WHERE owner = ?",[q])}catch{}}}});var jr={};C(jr,{ScheduledTask:()=>Le,Scheduler:()=>ss,SchedulerLock:()=>ye,cronMatches:()=>ts,parseCron:()=>Ir,task:()=>Oo});function we(c,e,t){if(c==="*")return null;let s=new Set;for(let r of c.split(",")){let[n,o]=r.split("/"),i=o?parseInt(o,10):1;if(n==="*")for(let a=e;a<=t;a+=i)s.add(a);else if(n.includes("-")){let[a,l]=n.split("-"),u=parseInt(a,10),d=parseInt(l,10);for(let h=u;h<=d;h+=i)s.add(h)}else s.add(parseInt(n,10))}return[...s].sort((r,n)=>r-n)}function Ir(c){let e=c.trim().split(/\s+/);if(e.length!==5)throw new Error(`Invalid cron expression: "${c}". Expected 5 fields.`);return{minute:we(e[0],0,59),hour:we(e[1],0,23),dayOfMonth:we(e[2],1,31),month:we(e[3],1,12),dayOfWeek:we(e[4],0,6)}}function ts(c,e){let t=Ir(c),s=e.getMinutes(),r=e.getHours(),n=e.getDate(),o=e.getMonth()+1,i=e.getDay();return!(t.minute&&!t.minute.includes(s)||t.hour&&!t.hour.includes(r)||t.dayOfMonth&&!t.dayOfMonth.includes(n)||t.month&&!t.month.includes(o)||t.dayOfWeek&&!t.dayOfWeek.includes(i))}function Oo(c,e,t){class s extends Le{name=c;schedule(){return t&&t(this),this}async handle(){return e()}}return new s}var Le,ss,qr=y(()=>{"use strict";be();Le=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(()=>(be(),_e));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(()=>(be(),_e));await s.release(this.name)}catch{}}}},ss=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 n=r.getExpression();if(ts(n,t)){let o=await r.executeTask();s.push(o),this.addToHistory(o)}}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(()=>(be(),_e));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=>ts(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(()=>(w(),T));switch(e.getDriver()){case"sqlite":await e.raw(`CREATE TABLE IF NOT EXISTS scheduled_task_runs (
|
|
17
17
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
18
18
|
task TEXT NOT NULL,
|
|
19
19
|
success INTEGER NOT NULL,
|
|
@@ -34,11 +34,11 @@ var ai=Object.defineProperty;var De=(c=>typeof require<"u"?require:typeof Proxy<
|
|
|
34
34
|
duration INT NOT NULL,
|
|
35
35
|
error TEXT,
|
|
36
36
|
ran_at DATETIME NOT NULL
|
|
37
|
-
) ENGINE=InnoDB`);break}this._historyTableEnsured=!0}async persistResult(e){try{await this.ensureHistoryTable();let{Connection:t}=await Promise.resolve().then(()=>(w(),T));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
|
|
37
|
+
) ENGINE=InnoDB`);break}this._historyTableEnsured=!0}async persistResult(e){try{await this.ensureHistoryTable();let{Connection:t}=await Promise.resolve().then(()=>(w(),T));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 Ur={};C(Ur,{Job:()=>W,Queue:()=>us});var W,Ie,is,B,je,os,as,cs,ls,us,ds=y(()=>{"use strict";E();W=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)}},Ie=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(){}},is=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(n=>n.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()}},B=class{constructor(e,t){this.table=e;this.registry=t}async getConnection(){let{Connection:e}=await Promise.resolve().then(()=>(w(),T));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
38
|
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}
|
|
39
39
|
WHERE queue = ? AND available_at <= ? AND reserved_at IS NULL
|
|
40
|
-
ORDER BY created_at ASC LIMIT 1`,[e,s]);if(!r||r.length===0)return null;let n=r[0];await t.raw(`UPDATE ${this.table} SET reserved_at = ?, attempts = attempts + 1 WHERE id = ?`,[s,n.id]);let
|
|
41
|
-
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}},os=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 n=JSON.parse(t);r.restore(n)}catch{}return r}has(e){return this.jobs.has(e)}},as=class{config={default:"sync",connections:{sync:{driver:"sync"}}};drivers=new Map;processing=!1;jobRegistry=new os;failedStore=new is;_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],n=this.resolveDriver(s);t?.queue&&(e.queue=t.queue),t?.maxAttempts!==void 0&&(e.maxAttempts=t.maxAttempts);let i={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 n.push(i)}async dispatchSync(e){let t=new Le,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 cs(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 Ie){let a=await s.createWorker(r,this.jobRegistry,this.failedStore,{concurrency:e?.concurrency??1});return this.processing=!0,this._activeWorker=a,await new Promise(l=>{let u=()=>{this.processing?setTimeout(u,500):a.close().then(l).catch(l)};u()}),0}let n=e?.maxJobs??1/0,i=(e?.sleep??1)*1e3,o=0;for(this.processing=!0;this.processing&&o<n;){let a=await s.pop(r);if(!a){if(n===1/0){await new Promise(l=>setTimeout(l,i));continue}break}a.attempts++,a.job.attempts=a.attempts;try{await a.job.handle(),o++,s instanceof W&&await s.delete(a.id)}catch(l){if(a.attempts<a.maxAttempts){a.job.retrying(a.attempts);let u=a.job.retryDelay??60;s instanceof W?await s.release(a.id,u):(a.availableAt=Date.now()+u*1e3,await s.push(a))}else a.job.failed(l),await this.failedStore.store(a,l),s instanceof W&&await s.delete(a.id)}}return o}async stop(){this.processing=!1,this._activeWorker&&(await this._activeWorker.close(),this._activeWorker=null)}async size(e){return this.resolveDriver(this.config.default).size(e)}async clear(e){return this.resolveDriver(this.config.default).clear(e)}async failed(){return this.failedStore.all()}async retry(e){let t=await this.failedStore.find(e);if(!t)return!1;let s=this.jobRegistry.resolve(t.jobClass,t.payload);return s.queue=t.queue,await this.dispatch(s,{queue:t.queue}),await this.failedStore.forget(e),!0}async retryAll(){let e=await this.failedStore.all(),t=0;for(let s of e)try{let r=this.jobRegistry.resolve(s.jobClass,s.payload);r.queue=s.queue,await this.dispatch(r,{queue:s.queue}),await this.failedStore.forget(s.id),t++}catch{}return t}async forgetFailed(e){return this.failedStore.forget(e)}async flushFailed(){return this.failedStore.flush()}resolveDriver(e){if(this.drivers.has(e))return this.drivers.get(e);let t=this.config.connections[e];if(!t)throw new Error(`Queue connection "${e}" is not defined.`);let s;switch(t.driver){case"sync":s=new Le;break;case"memory":s=new ns;break;case"database":s=new W(t.table??"svelar_jobs",this.jobRegistry);break;case"redis":s=new Ie(t,this.jobRegistry);break;default:throw new Error(`Unknown queue driver: ${t.driver}`)}return this.drivers.set(e,s),s}},cs=class extends K{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(n){t=n,r<e.maxAttempts&&(e.retrying(r),e.retryDelay>0&&await new Promise(i=>setTimeout(i,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()}))})}},ls=b("svelar.queue",()=>new as)});var A,hs=f(()=>{"use strict";w();A=class c{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 c(this.tableName,this.modelClass,this.connectionName);if(e(s),s.whereClauses.length>0){let{whereSQL:r,whereBindings:n}=s.buildWhere(),i=r.replace(/^WHERE /,"");this.whereClauses.push({type:"raw",raw:`(${i})`,values:n,boolean:t})}return this}orWhereNested(e){return this.whereNested(e,"OR")}whereExists(e){let t=new c("__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 c("__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 c("__placeholder__",void 0,this.connectionName);s(r);let{sql:n,bindings:i}=r.toSQL();return this.whereClauses.push({type:"sub",column:e,operator:t,subSQL:n,subBindings:i,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 c("__placeholder__",void 0,this.connectionName);t(r);let{sql:n,bindings:i}=r.toSQL();return this.cteClauses.push({name:e,sql:n,bindings:i,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 c("__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 c("__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 m.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 m.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 m.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 m.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 m.raw(t,s,this.connectionName))[0]?.aggregate??null}async min(e){let{sql:t,bindings:s}=this.buildAggregate(`MIN(${e})`);return(await m.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 m.raw(this.toSQL().sql,this.toSQL().bindings,this.connectionName)).map(s=>s[e])}async value(e){return this.selectColumns=[e],this.limitValue=1,(await m.raw(this.toSQL().sql,this.toSQL().bindings,this.connectionName))[0]?.[e]??null}async chunk(e,t){let s=1,r=!0;for(;r;){let n=this.clone();n.limitValue=e,n.offsetValue=(s-1)*e;let i=await n.get();if(i.length===0||await t(i,s)===!1||i.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=m.getDriver(this.connectionName),n=Object.keys(e),i=Object.values(e),o=i.map(()=>"?").join(", "),a=s??n.filter(u=>!t.includes(u)),l;if(r==="postgres"){let u=a.map(d=>`${d} = EXCLUDED.${d}`).join(", ");l=`INSERT INTO ${this.tableName} (${n.join(", ")}) VALUES (${o}) ON CONFLICT (${t.join(", ")}) DO UPDATE SET ${u}`}else if(r==="mysql"){let u=a.map(d=>`${d} = VALUES(${d})`).join(", ");l=`INSERT INTO ${this.tableName} (${n.join(", ")}) VALUES (${o}) ON DUPLICATE KEY UPDATE ${u}`}else{let u=a.map(d=>`${d} = excluded.${d}`).join(", ");l=`INSERT INTO ${this.tableName} (${n.join(", ")}) VALUES (${o}) ON CONFLICT (${t.join(", ")}) DO UPDATE SET ${u}`}return m.raw(l,i,this.connectionName)}async insertMany(e){if(e.length===0)return;let t=Object.keys(e[0]),s=[],r=[];for(let i of e){let o=t.map(a=>i[a]);s.push(...o),r.push(`(${o.map(()=>"?").join(", ")})`)}let n=`INSERT INTO ${this.tableName} (${t.join(", ")}) VALUES ${r.join(", ")}`;return m.raw(n,s,this.connectionName)}async firstOrCreate(e,t={}){for(let[i,o]of Object.entries(e))this.where(i,o);let s=await this.first();if(s)return s;let r={...e,...t},n=await new c(this.tableName,this.modelClass,this.connectionName).insertGetId(r);return new c(this.tableName,this.modelClass,this.connectionName).findOrFail(n)}async updateOrCreate(e,t){let s=new c(this.tableName,this.modelClass,this.connectionName);for(let[o,a]of Object.entries(e))s.where(o,a);let r=await s.first();if(r)return await new c(this.tableName,this.modelClass,this.connectionName).where(this.modelClass?.primaryKey??"id",r[this.modelClass?.primaryKey??"id"]).update(t),new c(this.tableName,this.modelClass,this.connectionName).findOrFail(r[this.modelClass?.primaryKey??"id"]);let n={...e,...t},i=await new c(this.tableName,this.modelClass,this.connectionName).insertGetId(n);return new c(this.tableName,this.modelClass,this.connectionName).findOrFail(i)}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 c("__placeholder__",void 0,this.connectionName);e(s);let{sql:r,bindings:n}=s.toSQL(),i=`(${r}) as ${t}`;return this.selectColumns[0]==="*"?this.selectColumns=[i]:this.selectColumns.push(i),this._selectBindings||(this._selectBindings=[]),this._selectBindings.push(...n),this}_selectBindings;async truncate(){m.getDriver(this.connectionName)==="sqlite"?(await m.raw(`DELETE FROM ${this.tableName}`,[],this.connectionName),await m.raw("DELETE FROM sqlite_sequence WHERE name = ?",[this.tableName],this.connectionName)):await m.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(", "),n=`INSERT INTO ${this.tableName} (${t.join(", ")}) VALUES (${r})`;return m.raw(n,s,this.connectionName)}async insertGetId(e,t="id"){let s=m.getDriver(this.connectionName),r=Object.keys(e),n=Object.values(e),i=n.map(()=>"?").join(", "),o=`INSERT INTO ${this.tableName} (${r.join(", ")}) VALUES (${i})`;return s==="postgres"?(o+=` RETURNING ${t}`,(await m.raw(o,n,this.connectionName))[0]?.[t]):(await m.raw(o,n,this.connectionName),s==="sqlite"?(await m.raw("SELECT last_insert_rowid() as id",[],this.connectionName))[0]?.id:s==="mysql"?(await m.raw("SELECT LAST_INSERT_ID() as id",[],this.connectionName))[0]?.id:0)}async update(e){let t=Object.keys(e),s=Object.values(e),r=t.map(a=>`${a} = ?`).join(", "),{whereSQL:n,whereBindings:i}=this.buildWhere(),o=`UPDATE ${this.tableName} SET ${r}${n}`;return await m.raw(o,[...s,...i],this.connectionName),1}async delete(){let{whereSQL:e,whereBindings:t}=this.buildWhere(),s=`DELETE FROM ${this.tableName}${e}`;return await m.raw(s,t,this.connectionName),1}async increment(e,t=1){let{whereSQL:s,whereBindings:r}=this.buildWhere(),n=`UPDATE ${this.tableName} SET ${e} = ${e} + ?${s}`;await m.raw(n,[t,...r],this.connectionName)}async decrement(e,t=1){return this.increment(e,-t)}toSQL(){let e=[],t=[];if(this.cteClauses.length>0){let o=this.cteClauses.some(l=>l.recursive)?"WITH RECURSIVE":"WITH",a=this.cteClauses.map(l=>(t.push(...l.bindings),`${l.name} AS (${l.sql})`));e.push(`${o} ${a.join(", ")}`)}this._selectBindings?.length&&t.push(...this._selectBindings);let s=this.isDistinct?"DISTINCT ":"";e.push(`SELECT ${s}${this.selectColumns.join(", ")}`),e.push(`FROM ${this.tableName}`);for(let i of this.joinClauses)i.type==="CROSS"?e.push(`CROSS JOIN ${i.table}`):e.push(`${i.type} JOIN ${i.table} ON ${i.first} ${i.operator} ${i.second}`);let{whereSQL:r,whereBindings:n}=this.buildWhere();if(r&&(e.push(r.trim()),t.push(...n)),this.groupByColumns.length>0&&e.push(`GROUP BY ${this.groupByColumns.join(", ")}`),this.havingClauses.length>0){let i=[];for(let o of this.havingClauses)o.type==="raw"?(i.push(o.raw),o.values&&t.push(...o.values)):(i.push(`${o.column} ${o.operator} ?`),t.push(o.value));e.push(`HAVING ${i.join(" AND ")}`)}if(this.orderClauses.length>0){let i=this.orderClauses.map(o=>o.__raw?o.column:`${o.column} ${o.direction.toUpperCase()}`);e.push(`ORDER BY ${i.join(", ")}`)}if(this.limitValue!==null&&e.push(`LIMIT ${this.limitValue}`),this.offsetValue!==null&&e.push(`OFFSET ${this.offsetValue}`),this.unionClauses.length>0)for(let i of this.unionClauses)e.push(i.all?"UNION ALL":"UNION"),e.push(i.sql),t.push(...i.bindings);return{sql:e.join(" "),bindings:t}}clone(){let e=new c(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],n=s===0?"WHERE":r.boolean;switch(r.type){case"basic":if((r.operator==="IS"||r.operator==="IS NOT")&&r.value===null){let a=(r.operator==="IS","null");e.push(`${n} ${r.column} ${r.operator} ${a}`)}else e.push(`${n} ${r.column} ${r.operator} ?`),t.push(r.value);break;case"in":let i=r.values.map(()=>"?").join(", ");e.push(`${n} ${r.column} IN (${i})`),t.push(...r.values);break;case"notIn":let o=r.values.map(()=>"?").join(", ");e.push(`${n} ${r.column} NOT IN (${o})`),t.push(...r.values);break;case"null":e.push(`${n} ${r.column} IS NULL`);break;case"notNull":e.push(`${n} ${r.column} IS NOT NULL`);break;case"between":e.push(`${n} ${r.column} BETWEEN ? AND ?`),t.push(r.values[0],r.values[1]);break;case"raw":e.push(`${n} ${r.raw}`),r.values&&t.push(...r.values);break;case"exists":e.push(`${n} EXISTS (${r.subSQL})`),r.subBindings&&t.push(...r.subBindings);break;case"notExists":e.push(`${n} NOT EXISTS (${r.subSQL})`),r.subBindings&&t.push(...r.subBindings);break;case"sub":e.push(`${n} ${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 J,z,V,Q,G,ps=f(()=>{"use strict";w();J=class{parentModel;relatedModel;constructor(e,t){this.parentModel=e,this.relatedModel=t}query(){return this.relatedModel.query()}},z=class extends J{constructor(t,s,r,n="id"){super(t,s);this.foreignKey=r;this.localKey=n}async load(t){let s=t.getAttribute(this.localKey);return this.relatedModel.query().where(this.foreignKey,s).first()}async eagerLoad(t,s){let r=t.map(o=>o.getAttribute(this.localKey)),n=await this.relatedModel.query().whereIn(this.foreignKey,r).get(),i=new Map;for(let o of n)i.set(o.getAttribute(this.foreignKey),o);for(let o of t){let a=o.getAttribute(this.localKey);o.setRelation(s,i.get(a)??null)}}async create(t){let s=this.parentModel.getAttribute(this.localKey);return this.relatedModel.create({...t,[this.foreignKey]:s})}},V=class extends J{constructor(t,s,r,n="id"){super(t,s);this.foreignKey=r;this.localKey=n}async load(t){let s=t.getAttribute(this.localKey);return this.relatedModel.query().where(this.foreignKey,s).get()}async eagerLoad(t,s){let r=t.map(o=>o.getAttribute(this.localKey)),n=await this.relatedModel.query().whereIn(this.foreignKey,r).get(),i=new Map;for(let o of n){let a=o.getAttribute(this.foreignKey);i.has(a)||i.set(a,[]),i.get(a).push(o)}for(let o of t){let a=o.getAttribute(this.localKey);o.setRelation(s,i.get(a)??[])}}async create(t){let s=this.parentModel.getAttribute(this.localKey);return this.relatedModel.create({...t,[this.foreignKey]:s})}async createMany(t){let s=[];for(let r of t)s.push(await this.create(r));return s}},Q=class extends J{constructor(t,s,r,n="id"){super(t,s);this.foreignKey=r;this.ownerKey=n}async load(t){let s=t.getAttribute(this.foreignKey);return s==null?null:this.relatedModel.query().where(this.ownerKey,s).first()}async eagerLoad(t,s){let r=t.map(o=>o.getAttribute(this.foreignKey)).filter(o=>o!=null);if(r.length===0){for(let o of t)o.setRelation(s,null);return}let n=await this.relatedModel.query().whereIn(this.ownerKey,r).get(),i=new Map;for(let o of n)i.set(o.getAttribute(this.ownerKey),o);for(let o of t){let a=o.getAttribute(this.foreignKey);o.setRelation(s,i.get(a)??null)}}associate(t){return this.parentModel.setAttribute(this.foreignKey,t.getAttribute(this.ownerKey)),this.parentModel}dissociate(){return this.parentModel.setAttribute(this.foreignKey,null),this.parentModel}},G=class extends J{constructor(t,s,r,n,i,o="id",a="id"){super(t,s);this.pivotTable=r;this.foreignPivotKey=n;this.relatedPivotKey=i;this.parentKey=o;this.relatedKey=a}async load(t){let s=t.getAttribute(this.parentKey),r=this.relatedModel.tableName,i=(await m.raw(`SELECT ${this.relatedPivotKey} FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ?`,[s])).map(o=>o[this.relatedPivotKey]);return i.length===0?[]:this.relatedModel.query().whereIn(this.relatedKey,i).get()}async eagerLoad(t,s){let r=t.map(d=>d.getAttribute(this.parentKey));if(r.length===0){for(let d of t)d.setRelation(s,[]);return}let n=r.map(()=>"?").join(", "),i=await m.raw(`SELECT * FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} IN (${n})`,r),o=[...new Set(i.map(d=>d[this.relatedPivotKey]))],a=o.length>0?await this.relatedModel.query().whereIn(this.relatedKey,o).get():[],l=new Map;for(let d of a)l.set(d.getAttribute(this.relatedKey),d);let u=new Map;for(let d of i){let h=d[this.foreignPivotKey],g=d[this.relatedPivotKey],y=l.get(g);y&&(u.has(h)||u.set(h,[]),u.get(h).push(y))}for(let d of t){let h=d.getAttribute(this.parentKey);d.setRelation(s,u.get(h)??[])}}async attach(t,s){let r=this.parentModel.getAttribute(this.parentKey),n={[this.foreignPivotKey]:r,[this.relatedPivotKey]:t,...s},i=Object.keys(n),o=Object.values(n),a=o.map(()=>"?").join(", ");await m.raw(`INSERT INTO ${this.pivotTable} (${i.join(", ")}) VALUES (${a})`,o)}async detach(t){let s=this.parentModel.getAttribute(this.parentKey);t?await m.raw(`DELETE FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ? AND ${this.relatedPivotKey} = ?`,[s,t]):await m.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 m.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 sn=f(()=>{"use strict"});var ve,ms=f(()=>{"use strict";ve=class{app;constructor(e){this.app=e}boot(){}}});var rn=f(()=>{"use strict";ms();je()});var Te,Y,je=f(()=>{"use strict";E();sn();rn();Te=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 n=r.indexOf(t);n>=0&&r.splice(n,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 n=r.indexOf(t);n>=0&&r.splice(n,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 n of s)await n(e);let r=this.onceListeners.get(t)??[];for(let n of r)await n(e);this.onceListeners.delete(t);for(let n of this.wildcardListeners)await n(t,e)}async emit(e,t){let s=this.listeners.get(e)??[];for(let n of s)await n(t);let r=this.onceListeners.get(e)??[];for(let n of r)await n(t);this.onceListeners.delete(e);for(let n of this.wildcardListeners)await n(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)}},Y=b("svelar.event",()=>new Te)});var qe,nn=f(()=>{"use strict";hs();ps();je();qe=class c{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 A(t.table,this,t.connection)}static async find(e){let t=this;return this.query().find(e,t.primaryKey)}static async findOrFail(e){let t=this;return this.query().findOrFail(e,t.primaryKey)}static async all(){return this.query().get()}static async first(){return this.query().first()}static async firstOrFail(){return this.query().firstOrFail()}static where(e,t,s){return this.query().where(e,t,s)}static whereIn(e,t){return this.query().whereIn(e,t)}static whereNull(e){return this.query().whereNull(e)}static whereNotNull(e){return this.query().whereNotNull(e)}static orderBy(e,t){return this.query().orderBy(e,t)}static latest(e){return this.query().latest(e)}static oldest(e){return this.query().oldest(e)}static with(...e){return this.query().with(...e)}static async count(){return this.query().count()}static async create(e){let t=new this,s=this;if(t.fill(e),await t.fireHook("creating"),await t.fireHook("saving"),s.timestamps){let o=new Date().toISOString();t.setAttribute(s.createdAt,o),t.setAttribute(s.updatedAt,o)}let r=t.getInsertableAttributes(),i=await new A(s.table,this,s.connection).insertGetId(r,s.primaryKey);return s.incrementing&&i&&t.setAttribute(s.primaryKey,i),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 A(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 n=new Date().toISOString();this.getAttribute(e.createdAt)||this.setAttribute(e.createdAt,n),this.setAttribute(e.updatedAt,n)}let t=this.getInsertableAttributes(),r=await new A(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 A(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 z(this,e,t,s??this.constructor.primaryKey)}hasMany(e,t,s){return new V(this,e,t,s??this.constructor.primaryKey)}belongsTo(e,t,s){return new Q(this,e,t,s??e.primaryKey)}belongsToMany(e,t,s,r,n,i){return new G(this,e,t,s,r,n??this.constructor.primaryKey,i??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(n=>n instanceof c?n.toJSON():n):r instanceof c?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=c.hooks.get(t.name);s?.[e]&&await s[e](this),typeof this[e]=="function"&&await this[e]();let r=c.observers.get(t.name)??[];for(let i of r){let o=i[e];typeof o=="function"&&await o.call(i,this)}let n=t.name.toLowerCase();await Y.emit(`${n}.${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=c.observers.get(t.name)??[];for(let n of s){let i=n[e];typeof i=="function"&&await i.call(n,this)}let r=t.name.toLowerCase();await Y.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 Ue,on=f(()=>{"use strict";Ue=class{async call(e){await new e().run()}}});var U,an,gs=f(()=>{"use strict";E();U=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}},an=b("svelar.container",()=>new U)});var He,cn=f(()=>{"use strict";gs();He=class{container;providers=[];booted=!1;constructor(e){this.container=e??new U,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 S,L,Fe,X,Be,Z,ee,We,te,se=f(()=>{"use strict";S=class{},L=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 i of s){let o=this.namedMiddleware.get(i);o&&r.push(o)}let n=t;for(let i=r.length-1;i>=0;i--){let o=r[i],a=n;typeof o.handle=="function"?n=()=>o.handle(e,a):n=()=>o(e,a)}return n()}count(){return this.middleware.length}},Fe=class extends S{constructor(t={}){super();this.options=t}async handle(t,s){let r=await s();if(!r)return;let n=Array.isArray(this.options.origin)?this.options.origin.join(", "):this.options.origin??"*";return r.headers.set("Access-Control-Allow-Origin",n),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}},X=class extends S{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(),n=this.requests.get(s);if(n&&r<n.resetAt){if(n.count>=this.maxRequests)return new Response(JSON.stringify({error:"Too many requests"}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(Math.ceil((n.resetAt-r)/1e3))}});n.count++}else this.requests.set(s,{count:1,resetAt:r+this.windowMs});return t()}},Be=class extends S{async handle(e,t){let s=Date.now(),r=e.event.request.method,n=e.event.url.pathname,i=await t(),o=Date.now()-s,a=i instanceof Response?i.status:200;return console.log(`[${new Date().toISOString()}] ${r} ${n} \u2192 ${a} (${o}ms)`),i}},Z=class extends S{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 i=s.url.pathname;if(this.onlyPaths&&!this.onlyPaths.some(l=>i.startsWith(l)))return this.setTokenAndContinue(e,t);if(this.excludePaths.some(l=>i.startsWith(l)))return t();let o=this.getCookieToken(s),a=s.request.headers.get(this.headerName)??await this.getBodyToken(s);return!o||!a||!this.timingSafeEqual(o,a)?new Response(JSON.stringify({message:"CSRF token mismatch"}),{status:419,headers:{"Content-Type":"application/json"}}):t()}async setTokenAndContinue(e,t){let s=await t();if(!(s instanceof Response))return s;let n=this.getCookieToken(e.event)||this.generateToken();return s.headers.append("Set-Cookie",`${this.cookieName}=${n}; 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),n=s.encode(t),i=0;for(let o=0;o<r.length;o++)i|=r[o]^n[o];return i===0}},ee=class extends S{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 i=s.request.headers.get("origin");if(!i)return t();let o=s.url.origin;return i===o||this.allowedOrigins.has(i)?t():new Response(JSON.stringify({message:"Cross-origin request blocked"}),{status:403,headers:{"Content-Type":"application/json"}})}},We=class extends S{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 v=s.url.pathname;if(!this.onlyPaths.some(k=>v.startsWith(k)))return t()}let r=s.request.headers.get(this.signatureHeader),n=s.request.headers.get(this.timestampHeader);if(!r||!n)return new Response(JSON.stringify({message:"Missing request signature"}),{status:401,headers:{"Content-Type":"application/json"}});let i=parseInt(n,10),o=Math.floor(Date.now()/1e3);if(isNaN(i)||Math.abs(o-i)>this.tolerance)return new Response(JSON.stringify({message:"Request signature expired"}),{status:401,headers:{"Content-Type":"application/json"}});let l=await s.request.clone().text(),{createHmac:u}=await import("crypto"),d=s.request.method.toUpperCase(),h=s.url.pathname+s.url.search,g=`${n}.${d}.${h}.${l}`,y=u("sha256",this.secret).update(g).digest("hex");return r.length!==y.length||!this.timingSafeCompare(r,y)?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),n=s.encode(t),i=0;for(let o=0;o<r.length;o++)i|=r[o]^n[o];return i===0}static sign(e,t,s,r,n){let{createHmac:i}=De("crypto"),o=n??Math.floor(Date.now()/1e3),a=`${o}.${t.toUpperCase()}.${s}.${r}`;return{signature:i("sha256",e).update(a).digest("hex"),timestamp:o}}},te=class extends S{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}`,n=Date.now(),i=this.attempts.get(r);if(i){if(n<i.blockedUntil){let a=Math.ceil((i.blockedUntil-n)/1e3);return new Response(JSON.stringify({message:"Too many attempts. Please try again later.",retry_after:a}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(a)}})}if(i.count>=this.maxAttempts){i.blockedUntil=n+this.decayMinutes*6e4,i.count=0;let a=this.decayMinutes*60;return new Response(JSON.stringify({message:"Too many attempts. Please try again later.",retry_after:a}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(a)}})}}let o=await t();if(o instanceof Response&&o.status>=400&&o.status<500){let a=this.attempts.get(r)??{count:0,blockedUntil:0};if(a.count++,this.attempts.set(r,a),this.attempts.size>1e4)for(let[l,u]of this.attempts)n>u.blockedUntil+this.decayMinutes*6e4*2&&this.attempts.delete(l)}return o}}});import{z as re}from"zod";function ln(c,e=!1){let t=new c;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 Ke,I,xe,Ee,Se,un=f(()=>{"use strict";se();Ke=class{controllerMiddleware=[];middleware(e,t){let s;typeof e=="function"&&e.prototype instanceof S?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 L;for(let{middleware:o}of s)r.use(o);let n={event:t,params:t.params,locals:t.locals},i=await r.execute(n,async()=>this.callMethod(e,t));if(i instanceof Response)return i}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 re.ZodObject?t:re.object(t),r,n=e.request.headers.get("content-type")??"";if(n.includes("application/json"))r=await e.request.json();else if(n.includes("multipart/form-data")||n.includes("application/x-www-form-urlencoded")){let o=await e.request.formData();r=Object.fromEntries(o)}else r=Object.fromEntries(e.url.searchParams);let i=s.safeParse(r);if(!i.success)throw new I(i.error);return i.data}validateQuery(e,t){let s=t instanceof re.ZodObject?t:re.object(t),r=Object.fromEntries(e.url.searchParams),n=s.safeParse(r);if(!n.success)throw new I(n.error);return n.data}validateParams(e,t){let r=(t instanceof re.ZodObject?t:re.object(t)).safeParse(e.params);if(!r.success)throw new I(r.error);return r.data}handleError(e,t){return e instanceof I?this.json({message:"Validation failed",errors:e.errors},422):e instanceof xe?this.json({message:e.message||"Not found"},404):e instanceof Ee?this.json({message:e.message||"Unauthorized"},401):e instanceof Se?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)}};I=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)}}},xe=class extends Error{constructor(e="Not found"){super(e),this.name="NotFoundError"}},Ee=class extends Error{constructor(e="Unauthorized"){super(e),this.name="UnauthorizedError"}},Se=class extends Error{constructor(e="Forbidden"){super(e),this.name="ForbiddenError"}}});import{randomBytes as _o,createHmac as dn,timingSafeEqual as Lo}from"crypto";import{promises as j}from"fs";import{join as Ce}from"path";var ne,Pe,H,Je,ze,Ve,ie,fs=f(()=>{"use strict";se();ne=class c{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=c.generateId();this.id=t,this.dirty=!0;let s=Pe.get(e);return s instanceof H&&s.markOldSessionId(e),Pe.delete(e),t}static generateId(){return _o(32).toString("hex")}},Pe=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}),Pe.set(e,this)}async destroy(e){this.sessions.delete(e),Pe.delete(e)}async gc(e){let t=Date.now();for(let[s,r]of this.sessions)t>r.expiresAt&&(this.sessions.delete(s),Pe.delete(s))}markOldSessionId(e){this.oldSessionIds.add(e),this.sessions.delete(e)}},Je=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(()=>(w(),T));switch(e.getDriver(this.connectionName)){case"sqlite":await e.raw(`CREATE TABLE IF NOT EXISTS ${this.tableName} (
|
|
40
|
+
ORDER BY created_at ASC LIMIT 1`,[e,s]);if(!r||r.length===0)return null;let n=r[0];await t.raw(`UPDATE ${this.table} SET reserved_at = ?, attempts = attempts + 1 WHERE id = ?`,[s,n.id]);let o=JSON.parse(n.payload),i=this.registry.resolve(o.jobClass,o.payload);return{id:n.id,jobClass:o.jobClass,payload:o.payload,queue:n.queue,attempts:n.attempts+1,maxAttempts:n.max_attempts,availableAt:n.available_at*1e3,createdAt:n.created_at*1e3,job:i}}async size(e="default"){return(await(await this.getConnection()).raw(`SELECT COUNT(*) as count FROM ${this.table} WHERE queue = ? AND reserved_at IS NULL`,[e]))?.[0]?.count??0}async clear(e){let t=await this.getConnection();e?await t.raw(`DELETE FROM ${this.table} WHERE queue = ?`,[e]):await t.raw(`DELETE FROM ${this.table}`,[])}async delete(e){await(await this.getConnection()).raw(`DELETE FROM ${this.table} WHERE id = ?`,[e])}async release(e,t=0){let s=await this.getConnection(),r=Math.floor(Date.now()/1e3)+t;await s.raw(`UPDATE ${this.table} SET reserved_at = NULL, available_at = ? WHERE id = ?`,[r,e])}},je=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",n=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,n),n}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 n=await this.getBullMQ(),o=this.getRedisConnection(),i=this.config.prefix??"svelar",a=new n.Worker(e,async l=>{let u=l.data,d=t.resolve(u.jobClass,u.payload);d.attempts=l.attemptsMade+1,await d.handle()},{connection:o,prefix:i,concurrency:r?.concurrency??1});return a.on("failed",async(l,u)=>{let d=l?.data;if(d)try{let h=t.resolve(d.jobClass,d.payload);l.attemptsMade>=(l.opts?.attempts??3)&&(h.failed(u),await s.store({id:l.id,jobClass:d.jobClass,payload:d.payload,queue:e,attempts:l.attemptsMade,maxAttempts:l.opts?.attempts??3,availableAt:Date.now(),createdAt:l.timestamp??Date.now(),job:h},u))}catch{console.error("[Queue] Failed to resolve job for failure handler:",u.message)}}),a}},os=class{table="svelar_failed_jobs";async getConnection(){let{Connection:e}=await Promise.resolve().then(()=>(w(),T));return e}async store(e,t){try{await(await this.getConnection()).raw(`INSERT INTO ${this.table} (id, queue, job_class, payload, exception, failed_at)
|
|
41
|
+
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}},as=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 n=JSON.parse(t);r.restore(n)}catch{}return r}has(e){return this.jobs.has(e)}},cs=class{config={default:"sync",connections:{sync:{driver:"sync"}}};drivers=new Map;processing=!1;jobRegistry=new as;failedStore=new os;_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],n=this.resolveDriver(s);t?.queue&&(e.queue=t.queue),t?.maxAttempts!==void 0&&(e.maxAttempts=t.maxAttempts);let o={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 n.push(o)}async dispatchSync(e){let t=new Ie,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 ls(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 je){let a=await s.createWorker(r,this.jobRegistry,this.failedStore,{concurrency:e?.concurrency??1});return this.processing=!0,this._activeWorker=a,await new Promise(l=>{let u=()=>{this.processing?setTimeout(u,500):a.close().then(l).catch(l)};u()}),0}let n=e?.maxJobs??1/0,o=(e?.sleep??1)*1e3,i=0;for(this.processing=!0;this.processing&&i<n;){let a=await s.pop(r);if(!a){if(n===1/0){await new Promise(l=>setTimeout(l,o));continue}break}a.attempts++,a.job.attempts=a.attempts;try{await a.job.handle(),i++,s instanceof B&&await s.delete(a.id)}catch(l){if(a.attempts<a.maxAttempts){a.job.retrying(a.attempts);let u=a.job.retryDelay??60;s instanceof B?await s.release(a.id,u):(a.availableAt=Date.now()+u*1e3,await s.push(a))}else a.job.failed(l),await this.failedStore.store(a,l),s instanceof B&&await s.delete(a.id)}}return i}async stop(){this.processing=!1,this._activeWorker&&(await this._activeWorker.close(),this._activeWorker=null)}async size(e){return this.resolveDriver(this.config.default).size(e)}async clear(e){return this.resolveDriver(this.config.default).clear(e)}async failed(){return this.failedStore.all()}async retry(e){let t=await this.failedStore.find(e);if(!t)return!1;let s=this.jobRegistry.resolve(t.jobClass,t.payload);return s.queue=t.queue,await this.dispatch(s,{queue:t.queue}),await this.failedStore.forget(e),!0}async retryAll(){let e=await this.failedStore.all(),t=0;for(let s of e)try{let r=this.jobRegistry.resolve(s.jobClass,s.payload);r.queue=s.queue,await this.dispatch(r,{queue:s.queue}),await this.failedStore.forget(s.id),t++}catch{}return t}async forgetFailed(e){return this.failedStore.forget(e)}async flushFailed(){return this.failedStore.flush()}resolveDriver(e){if(this.drivers.has(e))return this.drivers.get(e);let t=this.config.connections[e];if(!t)throw new Error(`Queue connection "${e}" is not defined.`);let s;switch(t.driver){case"sync":s=new Ie;break;case"memory":s=new is;break;case"database":s=new B(t.table??"svelar_jobs",this.jobRegistry);break;case"redis":s=new je(t,this.jobRegistry);break;default:throw new Error(`Unknown queue driver: ${t.driver}`)}return this.drivers.set(e,s),s}},ls=class extends W{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(n){t=n,r<e.maxAttempts&&(e.retrying(r),e.retryDelay>0&&await new Promise(o=>setTimeout(o,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()}))})}},us=b("svelar.queue",()=>new cs)});var k,ps=y(()=>{"use strict";w();k=class c{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 c(this.tableName,this.modelClass,this.connectionName);if(e(s),s.whereClauses.length>0){let{whereSQL:r,whereBindings:n}=s.buildWhere(),o=r.replace(/^WHERE /,"");this.whereClauses.push({type:"raw",raw:`(${o})`,values:n,boolean:t})}return this}orWhereNested(e){return this.whereNested(e,"OR")}whereExists(e){let t=new c("__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 c("__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 c("__placeholder__",void 0,this.connectionName);s(r);let{sql:n,bindings:o}=r.toSQL();return this.whereClauses.push({type:"sub",column:e,operator:t,subSQL:n,subBindings:o,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 c("__placeholder__",void 0,this.connectionName);t(r);let{sql:n,bindings:o}=r.toSQL();return this.cteClauses.push({name:e,sql:n,bindings:o,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 c("__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 c("__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 g.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 g.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 g.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 g.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 g.raw(t,s,this.connectionName))[0]?.aggregate??null}async min(e){let{sql:t,bindings:s}=this.buildAggregate(`MIN(${e})`);return(await g.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 g.raw(this.toSQL().sql,this.toSQL().bindings,this.connectionName)).map(s=>s[e])}async value(e){return this.selectColumns=[e],this.limitValue=1,(await g.raw(this.toSQL().sql,this.toSQL().bindings,this.connectionName))[0]?.[e]??null}async chunk(e,t){let s=1,r=!0;for(;r;){let n=this.clone();n.limitValue=e,n.offsetValue=(s-1)*e;let o=await n.get();if(o.length===0||await t(o,s)===!1||o.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=g.getDriver(this.connectionName),n=Object.keys(e),o=Object.values(e),i=o.map(()=>"?").join(", "),a=s??n.filter(u=>!t.includes(u)),l;if(r==="postgres"){let u=a.map(d=>`${d} = EXCLUDED.${d}`).join(", ");l=`INSERT INTO ${this.tableName} (${n.join(", ")}) VALUES (${i}) ON CONFLICT (${t.join(", ")}) DO UPDATE SET ${u}`}else if(r==="mysql"){let u=a.map(d=>`${d} = VALUES(${d})`).join(", ");l=`INSERT INTO ${this.tableName} (${n.join(", ")}) VALUES (${i}) ON DUPLICATE KEY UPDATE ${u}`}else{let u=a.map(d=>`${d} = excluded.${d}`).join(", ");l=`INSERT INTO ${this.tableName} (${n.join(", ")}) VALUES (${i}) ON CONFLICT (${t.join(", ")}) DO UPDATE SET ${u}`}return g.raw(l,o,this.connectionName)}async insertMany(e){if(e.length===0)return;let t=Object.keys(e[0]),s=[],r=[];for(let o of e){let i=t.map(a=>o[a]);s.push(...i),r.push(`(${i.map(()=>"?").join(", ")})`)}let n=`INSERT INTO ${this.tableName} (${t.join(", ")}) VALUES ${r.join(", ")}`;return g.raw(n,s,this.connectionName)}async firstOrCreate(e,t={}){for(let[o,i]of Object.entries(e))this.where(o,i);let s=await this.first();if(s)return s;let r={...e,...t},n=await new c(this.tableName,this.modelClass,this.connectionName).insertGetId(r);return new c(this.tableName,this.modelClass,this.connectionName).findOrFail(n)}async updateOrCreate(e,t){let s=new c(this.tableName,this.modelClass,this.connectionName);for(let[i,a]of Object.entries(e))s.where(i,a);let r=await s.first();if(r)return await new c(this.tableName,this.modelClass,this.connectionName).where(this.modelClass?.primaryKey??"id",r[this.modelClass?.primaryKey??"id"]).update(t),new c(this.tableName,this.modelClass,this.connectionName).findOrFail(r[this.modelClass?.primaryKey??"id"]);let n={...e,...t},o=await new c(this.tableName,this.modelClass,this.connectionName).insertGetId(n);return new c(this.tableName,this.modelClass,this.connectionName).findOrFail(o)}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 c("__placeholder__",void 0,this.connectionName);e(s);let{sql:r,bindings:n}=s.toSQL(),o=`(${r}) as ${t}`;return this.selectColumns[0]==="*"?this.selectColumns=[o]:this.selectColumns.push(o),this._selectBindings||(this._selectBindings=[]),this._selectBindings.push(...n),this}_selectBindings;async truncate(){g.getDriver(this.connectionName)==="sqlite"?(await g.raw(`DELETE FROM ${this.tableName}`,[],this.connectionName),await g.raw("DELETE FROM sqlite_sequence WHERE name = ?",[this.tableName],this.connectionName)):await g.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(", "),n=`INSERT INTO ${this.tableName} (${t.join(", ")}) VALUES (${r})`;return g.raw(n,s,this.connectionName)}async insertGetId(e,t="id"){let s=g.getDriver(this.connectionName),r=Object.keys(e),n=Object.values(e),o=n.map(()=>"?").join(", "),i=`INSERT INTO ${this.tableName} (${r.join(", ")}) VALUES (${o})`;return s==="postgres"?(i+=` RETURNING ${t}`,(await g.raw(i,n,this.connectionName))[0]?.[t]):(await g.raw(i,n,this.connectionName),s==="sqlite"?(await g.raw("SELECT last_insert_rowid() as id",[],this.connectionName))[0]?.id:s==="mysql"?(await g.raw("SELECT LAST_INSERT_ID() as id",[],this.connectionName))[0]?.id:0)}async update(e){let t=Object.keys(e),s=Object.values(e),r=t.map(a=>`${a} = ?`).join(", "),{whereSQL:n,whereBindings:o}=this.buildWhere(),i=`UPDATE ${this.tableName} SET ${r}${n}`;return await g.raw(i,[...s,...o],this.connectionName),1}async delete(){let{whereSQL:e,whereBindings:t}=this.buildWhere(),s=`DELETE FROM ${this.tableName}${e}`;return await g.raw(s,t,this.connectionName),1}async increment(e,t=1){let{whereSQL:s,whereBindings:r}=this.buildWhere(),n=`UPDATE ${this.tableName} SET ${e} = ${e} + ?${s}`;await g.raw(n,[t,...r],this.connectionName)}async decrement(e,t=1){return this.increment(e,-t)}toSQL(){let e=[],t=[];if(this.cteClauses.length>0){let i=this.cteClauses.some(l=>l.recursive)?"WITH RECURSIVE":"WITH",a=this.cteClauses.map(l=>(t.push(...l.bindings),`${l.name} AS (${l.sql})`));e.push(`${i} ${a.join(", ")}`)}this._selectBindings?.length&&t.push(...this._selectBindings);let s=this.isDistinct?"DISTINCT ":"";e.push(`SELECT ${s}${this.selectColumns.join(", ")}`),e.push(`FROM ${this.tableName}`);for(let o of this.joinClauses)o.type==="CROSS"?e.push(`CROSS JOIN ${o.table}`):e.push(`${o.type} JOIN ${o.table} ON ${o.first} ${o.operator} ${o.second}`);let{whereSQL:r,whereBindings:n}=this.buildWhere();if(r&&(e.push(r.trim()),t.push(...n)),this.groupByColumns.length>0&&e.push(`GROUP BY ${this.groupByColumns.join(", ")}`),this.havingClauses.length>0){let o=[];for(let i of this.havingClauses)i.type==="raw"?(o.push(i.raw),i.values&&t.push(...i.values)):(o.push(`${i.column} ${i.operator} ?`),t.push(i.value));e.push(`HAVING ${o.join(" AND ")}`)}if(this.orderClauses.length>0){let o=this.orderClauses.map(i=>i.__raw?i.column:`${i.column} ${i.direction.toUpperCase()}`);e.push(`ORDER BY ${o.join(", ")}`)}if(this.limitValue!==null&&e.push(`LIMIT ${this.limitValue}`),this.offsetValue!==null&&e.push(`OFFSET ${this.offsetValue}`),this.unionClauses.length>0)for(let o of this.unionClauses)e.push(o.all?"UNION ALL":"UNION"),e.push(o.sql),t.push(...o.bindings);return{sql:e.join(" "),bindings:t}}clone(){let e=new c(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],n=s===0?"WHERE":r.boolean;switch(r.type){case"basic":if((r.operator==="IS"||r.operator==="IS NOT")&&r.value===null){let a=(r.operator==="IS","null");e.push(`${n} ${r.column} ${r.operator} ${a}`)}else e.push(`${n} ${r.column} ${r.operator} ?`),t.push(r.value);break;case"in":let o=r.values.map(()=>"?").join(", ");e.push(`${n} ${r.column} IN (${o})`),t.push(...r.values);break;case"notIn":let i=r.values.map(()=>"?").join(", ");e.push(`${n} ${r.column} NOT IN (${i})`),t.push(...r.values);break;case"null":e.push(`${n} ${r.column} IS NULL`);break;case"notNull":e.push(`${n} ${r.column} IS NOT NULL`);break;case"between":e.push(`${n} ${r.column} BETWEEN ? AND ?`),t.push(r.values[0],r.values[1]);break;case"raw":e.push(`${n} ${r.raw}`),r.values&&t.push(...r.values);break;case"exists":e.push(`${n} EXISTS (${r.subSQL})`),r.subBindings&&t.push(...r.subBindings);break;case"notExists":e.push(`${n} NOT EXISTS (${r.subSQL})`),r.subBindings&&t.push(...r.subBindings);break;case"sub":e.push(`${n} ${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 K,J,z,V,Q,ms=y(()=>{"use strict";w();K=class{parentModel;relatedModel;constructor(e,t){this.parentModel=e,this.relatedModel=t}query(){return this.relatedModel.query()}},J=class extends K{constructor(t,s,r,n="id"){super(t,s);this.foreignKey=r;this.localKey=n}async load(t){let s=t.getAttribute(this.localKey);return this.relatedModel.query().where(this.foreignKey,s).first()}async eagerLoad(t,s){let r=t.map(i=>i.getAttribute(this.localKey)),n=await this.relatedModel.query().whereIn(this.foreignKey,r).get(),o=new Map;for(let i of n)o.set(i.getAttribute(this.foreignKey),i);for(let i of t){let a=i.getAttribute(this.localKey);i.setRelation(s,o.get(a)??null)}}async create(t){let s=this.parentModel.getAttribute(this.localKey);return this.relatedModel.create({...t,[this.foreignKey]:s})}},z=class extends K{constructor(t,s,r,n="id"){super(t,s);this.foreignKey=r;this.localKey=n}async load(t){let s=t.getAttribute(this.localKey);return this.relatedModel.query().where(this.foreignKey,s).get()}async eagerLoad(t,s){let r=t.map(i=>i.getAttribute(this.localKey)),n=await this.relatedModel.query().whereIn(this.foreignKey,r).get(),o=new Map;for(let i of n){let a=i.getAttribute(this.foreignKey);o.has(a)||o.set(a,[]),o.get(a).push(i)}for(let i of t){let a=i.getAttribute(this.localKey);i.setRelation(s,o.get(a)??[])}}async create(t){let s=this.parentModel.getAttribute(this.localKey);return this.relatedModel.create({...t,[this.foreignKey]:s})}async createMany(t){let s=[];for(let r of t)s.push(await this.create(r));return s}},V=class extends K{constructor(t,s,r,n="id"){super(t,s);this.foreignKey=r;this.ownerKey=n}async load(t){let s=t.getAttribute(this.foreignKey);return s==null?null:this.relatedModel.query().where(this.ownerKey,s).first()}async eagerLoad(t,s){let r=t.map(i=>i.getAttribute(this.foreignKey)).filter(i=>i!=null);if(r.length===0){for(let i of t)i.setRelation(s,null);return}let n=await this.relatedModel.query().whereIn(this.ownerKey,r).get(),o=new Map;for(let i of n)o.set(i.getAttribute(this.ownerKey),i);for(let i of t){let a=i.getAttribute(this.foreignKey);i.setRelation(s,o.get(a)??null)}}associate(t){return this.parentModel.setAttribute(this.foreignKey,t.getAttribute(this.ownerKey)),this.parentModel}dissociate(){return this.parentModel.setAttribute(this.foreignKey,null),this.parentModel}},Q=class extends K{constructor(t,s,r,n,o,i="id",a="id"){super(t,s);this.pivotTable=r;this.foreignPivotKey=n;this.relatedPivotKey=o;this.parentKey=i;this.relatedKey=a}async load(t){let s=t.getAttribute(this.parentKey),r=this.relatedModel.tableName,o=(await g.raw(`SELECT ${this.relatedPivotKey} FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ?`,[s])).map(i=>i[this.relatedPivotKey]);return o.length===0?[]:this.relatedModel.query().whereIn(this.relatedKey,o).get()}async eagerLoad(t,s){let r=t.map(d=>d.getAttribute(this.parentKey));if(r.length===0){for(let d of t)d.setRelation(s,[]);return}let n=r.map(()=>"?").join(", "),o=await g.raw(`SELECT * FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} IN (${n})`,r),i=[...new Set(o.map(d=>d[this.relatedPivotKey]))],a=i.length>0?await this.relatedModel.query().whereIn(this.relatedKey,i).get():[],l=new Map;for(let d of a)l.set(d.getAttribute(this.relatedKey),d);let u=new Map;for(let d of o){let h=d[this.foreignPivotKey],p=d[this.relatedPivotKey],f=l.get(p);f&&(u.has(h)||u.set(h,[]),u.get(h).push(f))}for(let d of t){let h=d.getAttribute(this.parentKey);d.setRelation(s,u.get(h)??[])}}async attach(t,s){let r=this.parentModel.getAttribute(this.parentKey),n={[this.foreignPivotKey]:r,[this.relatedPivotKey]:t,...s},o=Object.keys(n),i=Object.values(n),a=i.map(()=>"?").join(", ");await g.raw(`INSERT INTO ${this.pivotTable} (${o.join(", ")}) VALUES (${a})`,i)}async detach(t){let s=this.parentModel.getAttribute(this.parentKey);t?await g.raw(`DELETE FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ? AND ${this.relatedPivotKey} = ?`,[s,t]):await g.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 g.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 Hr=y(()=>{"use strict"});var ve,gs=y(()=>{"use strict";ve=class{app;constructor(e){this.app=e}boot(){}}});var Fr=y(()=>{"use strict";gs();qe()});var Te,G,qe=y(()=>{"use strict";E();Hr();Fr();Te=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 n=r.indexOf(t);n>=0&&r.splice(n,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 n=r.indexOf(t);n>=0&&r.splice(n,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 n of s)await n(e);let r=this.onceListeners.get(t)??[];for(let n of r)await n(e);this.onceListeners.delete(t);for(let n of this.wildcardListeners)await n(t,e)}async emit(e,t){let s=this.listeners.get(e)??[];for(let n of s)await n(t);let r=this.onceListeners.get(e)??[];for(let n of r)await n(t);this.onceListeners.delete(e);for(let n of this.wildcardListeners)await n(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)}},G=b("svelar.event",()=>new Te)});var Ue,Br=y(()=>{"use strict";ps();ms();qe();Ue=class c{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 k(t.table,this,t.connection)}static async find(e){let t=this;return this.query().find(e,t.primaryKey)}static async findOrFail(e){let t=this;return this.query().findOrFail(e,t.primaryKey)}static async all(){return this.query().get()}static async first(){return this.query().first()}static async firstOrFail(){return this.query().firstOrFail()}static where(e,t,s){return this.query().where(e,t,s)}static whereIn(e,t){return this.query().whereIn(e,t)}static whereNull(e){return this.query().whereNull(e)}static whereNotNull(e){return this.query().whereNotNull(e)}static orderBy(e,t){return this.query().orderBy(e,t)}static latest(e){return this.query().latest(e)}static oldest(e){return this.query().oldest(e)}static with(...e){return this.query().with(...e)}static async count(){return this.query().count()}static async create(e){let t=new this,s=this;if(t.fill(e),await t.fireHook("creating"),await t.fireHook("saving"),s.timestamps){let i=new Date().toISOString();t.setAttribute(s.createdAt,i),t.setAttribute(s.updatedAt,i)}let r=t.getInsertableAttributes(),o=await new k(s.table,this,s.connection).insertGetId(r,s.primaryKey);return s.incrementing&&o&&t.setAttribute(s.primaryKey,o),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 k(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 n=new Date().toISOString();this.getAttribute(e.createdAt)||this.setAttribute(e.createdAt,n),this.setAttribute(e.updatedAt,n)}let t=this.getInsertableAttributes(),r=await new k(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 k(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 J(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 V(this,e,t,s??e.primaryKey)}belongsToMany(e,t,s,r,n,o){return new Q(this,e,t,s,r,n??this.constructor.primaryKey,o??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(n=>n instanceof c?n.toJSON():n):r instanceof c?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=c.hooks.get(t.name);s?.[e]&&await s[e](this),typeof this[e]=="function"&&await this[e]();let r=c.observers.get(t.name)??[];for(let o of r){let i=o[e];typeof i=="function"&&await i.call(o,this)}let n=t.name.toLowerCase();await G.emit(`${n}.${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=c.observers.get(t.name)??[];for(let n of s){let o=n[e];typeof o=="function"&&await o.call(n,this)}let r=t.name.toLowerCase();await G.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 He,Wr=y(()=>{"use strict";He=class{async call(e){await new e().run()}}});var U,Kr,fs=y(()=>{"use strict";E();U=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}},Kr=b("svelar.container",()=>new U)});var Fe,Jr=y(()=>{"use strict";fs();Fe=class{container;providers=[];booted=!1;constructor(e){this.container=e??new U,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 S,L,Be,Y,We,X,Z,Ke,ee,te=y(()=>{"use strict";S=class{},L=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 o of s){let i=this.namedMiddleware.get(o);i&&r.push(i)}let n=t;for(let o=r.length-1;o>=0;o--){let i=r[o],a=n;typeof i.handle=="function"?n=()=>i.handle(e,a):n=()=>i(e,a)}return n()}count(){return this.middleware.length}},Be=class extends S{constructor(t={}){super();this.options=t}async handle(t,s){let r=await s();if(!r)return;let n=Array.isArray(this.options.origin)?this.options.origin.join(", "):this.options.origin??"*";return r.headers.set("Access-Control-Allow-Origin",n),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}},Y=class extends S{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(),n=this.requests.get(s);if(n&&r<n.resetAt){if(n.count>=this.maxRequests)return new Response(JSON.stringify({error:"Too many requests"}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(Math.ceil((n.resetAt-r)/1e3))}});n.count++}else this.requests.set(s,{count:1,resetAt:r+this.windowMs});return t()}},We=class extends S{async handle(e,t){let s=Date.now(),r=e.event.request.method,n=e.event.url.pathname,o=await t(),i=Date.now()-s,a=o instanceof Response?o.status:200;return console.log(`[${new Date().toISOString()}] ${r} ${n} \u2192 ${a} (${i}ms)`),o}},X=class extends S{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 o=s.url.pathname;if(this.onlyPaths&&!this.onlyPaths.some(l=>o.startsWith(l)))return this.setTokenAndContinue(e,t);if(this.excludePaths.some(l=>o.startsWith(l)))return t();let i=this.getCookieToken(s),a=s.request.headers.get(this.headerName)??await this.getBodyToken(s);return!i||!a||!this.timingSafeEqual(i,a)?new Response(JSON.stringify({message:"CSRF token mismatch"}),{status:419,headers:{"Content-Type":"application/json"}}):t()}async setTokenAndContinue(e,t){let s=await t();if(!(s instanceof Response))return s;let n=this.getCookieToken(e.event)||this.generateToken();return s.headers.append("Set-Cookie",`${this.cookieName}=${n}; 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),n=s.encode(t),o=0;for(let i=0;i<r.length;i++)o|=r[i]^n[i];return o===0}},Z=class extends S{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 o=s.request.headers.get("origin");if(!o)return t();let i=s.url.origin;return o===i||this.allowedOrigins.has(o)?t():new Response(JSON.stringify({message:"Cross-origin request blocked"}),{status:403,headers:{"Content-Type":"application/json"}})}},Ke=class extends S{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 v=s.url.pathname;if(!this.onlyPaths.some(P=>v.startsWith(P)))return t()}let r=s.request.headers.get(this.signatureHeader),n=s.request.headers.get(this.timestampHeader);if(!r||!n)return new Response(JSON.stringify({message:"Missing request signature"}),{status:401,headers:{"Content-Type":"application/json"}});let o=parseInt(n,10),i=Math.floor(Date.now()/1e3);if(isNaN(o)||Math.abs(i-o)>this.tolerance)return new Response(JSON.stringify({message:"Request signature expired"}),{status:401,headers:{"Content-Type":"application/json"}});let l=await s.request.clone().text(),{createHmac:u}=await import("crypto"),d=s.request.method.toUpperCase(),h=s.url.pathname+s.url.search,p=`${n}.${d}.${h}.${l}`,f=u("sha256",this.secret).update(p).digest("hex");return r.length!==f.length||!this.timingSafeCompare(r,f)?new Response(JSON.stringify({message:"Invalid request signature"}),{status:401,headers:{"Content-Type":"application/json"}}):t()}timingSafeCompare(e,t){if(e.length!==t.length)return!1;let s=new TextEncoder,r=s.encode(e),n=s.encode(t),o=0;for(let i=0;i<r.length;i++)o|=r[i]^n[i];return o===0}static sign(e,t,s,r,n){let{createHmac:o}=Me("crypto"),i=n??Math.floor(Date.now()/1e3),a=`${i}.${t.toUpperCase()}.${s}.${r}`;return{signature:o("sha256",e).update(a).digest("hex"),timestamp:i}}},ee=class extends S{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}`,n=Date.now(),o=this.attempts.get(r);if(o){if(n<o.blockedUntil){let a=Math.ceil((o.blockedUntil-n)/1e3);return new Response(JSON.stringify({message:"Too many attempts. Please try again later.",retry_after:a}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(a)}})}if(o.count>=this.maxAttempts){o.blockedUntil=n+this.decayMinutes*6e4,o.count=0;let a=this.decayMinutes*60;return new Response(JSON.stringify({message:"Too many attempts. Please try again later.",retry_after:a}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(a)}})}}let i=await t();if(i instanceof Response&&i.status>=400&&i.status<500){let a=this.attempts.get(r)??{count:0,blockedUntil:0};if(a.count++,this.attempts.set(r,a),this.attempts.size>1e4)for(let[l,u]of this.attempts)n>u.blockedUntil+this.decayMinutes*6e4*2&&this.attempts.delete(l)}return i}}});import{z as se}from"zod";function zr(c,e=!1){let t=new c;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 Je,I,xe,Ee,Se,Vr=y(()=>{"use strict";te();Je=class{controllerMiddleware=[];middleware(e,t){let s;typeof e=="function"&&e.prototype instanceof S?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 L;for(let{middleware:i}of s)r.use(i);let n={event:t,params:t.params,locals:t.locals},o=await r.execute(n,async()=>this.callMethod(e,t));if(o instanceof Response)return o}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 se.ZodObject?t:se.object(t),r,n=e.request.headers.get("content-type")??"";if(n.includes("application/json"))r=await e.request.json();else if(n.includes("multipart/form-data")||n.includes("application/x-www-form-urlencoded")){let i=await e.request.formData();r=Object.fromEntries(i)}else r=Object.fromEntries(e.url.searchParams);let o=s.safeParse(r);if(!o.success)throw new I(o.error);return o.data}validateQuery(e,t){let s=t instanceof se.ZodObject?t:se.object(t),r=Object.fromEntries(e.url.searchParams),n=s.safeParse(r);if(!n.success)throw new I(n.error);return n.data}validateParams(e,t){let r=(t instanceof se.ZodObject?t:se.object(t)).safeParse(e.params);if(!r.success)throw new I(r.error);return r.data}handleError(e,t){return e instanceof I?this.json({message:"Validation failed",errors:e.errors},422):e instanceof xe?this.json({message:e.message||"Not found"},404):e instanceof Ee?this.json({message:e.message||"Unauthorized"},401):e instanceof Se?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)}};I=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)}}},xe=class extends Error{constructor(e="Not found"){super(e),this.name="NotFoundError"}},Ee=class extends Error{constructor(e="Unauthorized"){super(e),this.name="UnauthorizedError"}},Se=class extends Error{constructor(e="Forbidden"){super(e),this.name="ForbiddenError"}}});import{randomBytes as jo,createHmac as Qr,timingSafeEqual as qo}from"crypto";import{promises as j}from"fs";import{join as Ce}from"path";var re,Pe,H,ze,Ve,Qe,ne,ys=y(()=>{"use strict";te();re=class c{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=c.generateId();this.id=t,this.dirty=!0;let s=Pe.get(e);return s instanceof H&&s.markOldSessionId(e),Pe.delete(e),t}static generateId(){return jo(32).toString("hex")}},Pe=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}),Pe.set(e,this)}async destroy(e){this.sessions.delete(e),Pe.delete(e)}async gc(e){let t=Date.now();for(let[s,r]of this.sessions)t>r.expiresAt&&(this.sessions.delete(s),Pe.delete(s))}markOldSessionId(e){this.oldSessionIds.add(e),this.sessions.delete(e)}},ze=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(()=>(w(),T));switch(e.getDriver(this.connectionName)){case"sqlite":await e.raw(`CREATE TABLE IF NOT EXISTS ${this.tableName} (
|
|
42
42
|
id TEXT PRIMARY KEY,
|
|
43
43
|
payload TEXT NOT NULL,
|
|
44
44
|
expires_at TEXT NOT NULL
|
|
@@ -50,17 +50,17 @@ var ai=Object.defineProperty;var De=(c=>typeof require<"u"?require:typeof Proxy<
|
|
|
50
50
|
id VARCHAR(255) PRIMARY KEY,
|
|
51
51
|
payload TEXT NOT NULL,
|
|
52
52
|
expires_at DATETIME NOT NULL
|
|
53
|
-
) ENGINE=InnoDB`,[],this.connectionName);break}this.tableEnsured=!0}catch{}}async read(e){await this.ensureTable();let{Connection:t}=await Promise.resolve().then(()=>(w(),T)),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(()=>(w(),T)),n=JSON.stringify(t),
|
|
54
|
-
ON CONFLICT(id) DO UPDATE SET payload = excluded.payload, expires_at = excluded.expires_at`,[e,n,
|
|
55
|
-
ON CONFLICT(id) DO UPDATE SET payload = $2, expires_at = $3`,[e,n,
|
|
56
|
-
ON DUPLICATE KEY UPDATE payload = VALUES(payload), expires_at = VALUES(expires_at)`,[e,n,
|
|
53
|
+
) ENGINE=InnoDB`,[],this.connectionName);break}this.tableEnsured=!0}catch{}}async read(e){await this.ensureTable();let{Connection:t}=await Promise.resolve().then(()=>(w(),T)),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(()=>(w(),T)),n=JSON.stringify(t),o=new Date(Date.now()+s*1e3).toISOString(),i=r.getDriver(this.connectionName);i==="sqlite"?await r.raw(`INSERT INTO ${this.tableName} (id, payload, expires_at) VALUES (?, ?, ?)
|
|
54
|
+
ON CONFLICT(id) DO UPDATE SET payload = excluded.payload, expires_at = excluded.expires_at`,[e,n,o],this.connectionName):i==="postgres"?await r.raw(`INSERT INTO ${this.tableName} (id, payload, expires_at) VALUES ($1, $2, $3)
|
|
55
|
+
ON CONFLICT(id) DO UPDATE SET payload = $2, expires_at = $3`,[e,n,o],this.connectionName):await r.raw(`INSERT INTO ${this.tableName} (id, payload, expires_at) VALUES (?, ?, ?)
|
|
56
|
+
ON DUPLICATE KEY UPDATE payload = VALUES(payload), expires_at = VALUES(expires_at)`,[e,n,o],this.connectionName)}async destroy(e){let{Connection:t}=await Promise.resolve().then(()=>(w(),T));await t.raw(`DELETE FROM ${this.tableName} WHERE id = ?`,[e],this.connectionName)}async gc(e){let{Connection:t}=await Promise.resolve().then(()=>(w(),T));await t.raw(`DELETE FROM ${this.tableName} WHERE expires_at < ?`,[new Date().toISOString()],this.connectionName)}},Ve=class{dir;constructor(e){this.dir=e??Ce(process.cwd(),"storage","sessions")}filePath(e){let t=e.replace(/[^a-zA-Z0-9_-]/g,"");return Ce(this.dir,`${t}.json`)}async ensureDir(){await j.mkdir(this.dir,{recursive:!0})}async read(e){try{let t=await j.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 j.writeFile(this.filePath(e),JSON.stringify(r),"utf-8")}async destroy(e){try{await j.unlink(this.filePath(e))}catch{}}async gc(e){try{let t=await j.readdir(this.dir),s=new Date;for(let r of t)if(r.endsWith(".json"))try{let n=await j.readFile(Ce(this.dir,r),"utf-8"),o=JSON.parse(n);new Date(o.expiresAt)<s&&await j.unlink(Ce(this.dir,r))}catch{await j.unlink(Ce(this.dir,r)).catch(()=>{})}}catch{}}},Qe=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){}},ne=class extends S{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),n=null;if(r){let a=this.verifySignedId(r);a?(n=await this.config.store.read(a),r=a):r=null}r||(r=re.generateId());let o=new re(r,n??{});e.event.locals.session=o,e.locals.session=o;let i=await t();if(o.isDirty()&&await this.config.store.write(o.id,o.toPersist(),this.config.lifetime),i instanceof Response){let a=this.signId(o.id),l=this.buildCookieString(a);i.headers.append("Set-Cookie",l)}return i}getSessionIdFromCookie(e){let t=e.split(";").map(s=>s.trim());for(let s of t){let[r,...n]=s.split("=");if(r===this.config.cookieName)return decodeURIComponent(n.join("="))}return null}signId(e){let t=Qr("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),n=Qr("sha256",this.config.secret).update(s).digest("base64url");if(r.length!==n.length)return null;let o=Buffer.from(r),i=Buffer.from(n);if(o.length!==i.length)return null;try{if(qo(o,i))return s}catch{}return null}buildCookieString(e){let t=[`${this.config.cookieName}=${encodeURIComponent(e)}`];return t.push(`Path=${this.config.path}`),t.push(`Max-Age=${this.config.lifetime}`),this.config.domain&&t.push(`Domain=${this.config.domain}`),this.config.secure&&t.push("Secure"),this.config.httpOnly&&t.push("HttpOnly"),t.push(`SameSite=${this.config.sameSite}`),t.join("; ")}}});var Re={};C(Re,{Hash:()=>vs});import{randomBytes as bs,scrypt as Gr,timingSafeEqual as Uo}from"crypto";async function Ho(c,e=16384){let t=bs(16),s=64,r=await new Promise((n,o)=>{Gr(c,t,s,{N:e,r:8,p:1},(i,a)=>{i?o(i):n(a)})});return`$scrypt$N=${e}$${t.toString("base64")}$${r.toString("base64")}`}async function Fo(c,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"),n=Buffer.from(t[4],"base64"),o=n.length,i=await new Promise((a,l)=>{Gr(c,r,o,{N:s,r:8,p:1},(u,d)=>{u?l(u):a(d)})});return Uo(i,n)}var ws,vs,ie=y(()=>{"use strict";E();ws=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 Ho(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 Fo(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 bs(Math.ceil(e/2)).toString("hex").slice(0,e)}randomToken(e=32){return bs(e).toString("base64url")}},vs=b("svelar.hash",()=>new ws)});var Yr={};C(Yr,{EmailTemplates:()=>Bo});import{randomUUID as N}from"crypto";var Ts,Bo,Xr=y(()=>{"use strict";E();Ts=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(()=>(w(),T));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),n=this.interpolate(s.html,t),o=s.text?this.interpolate(s.text,t):void 0;return{subject:r,html:n,text:o}}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
57
|
<h1>Welcome, {{user.name}}!</h1>
|
|
58
58
|
<p>Thank you for joining {{appName}}.</p>
|
|
59
59
|
<p>Your account has been created with the email: <strong>{{user.email}}</strong></p>
|
|
60
60
|
<p><a href="{{confirmUrl}}">Confirm your email address</a></p>
|
|
61
61
|
`,text:`Welcome, {{user.name}}!
|
|
62
62
|
|
|
63
|
-
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:
|
|
63
|
+
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
64
|
<h1>Password Reset</h1>
|
|
65
65
|
<p>Hi {{user.name}},</p>
|
|
66
66
|
<p>Click the link below to reset your password. This link expires in 1 hour.</p>
|
|
@@ -68,18 +68,18 @@ Confirm your email: {{confirmUrl}}`,variables:["appName","user.name","user.email
|
|
|
68
68
|
<p>If you didn't request this, you can ignore this email.</p>
|
|
69
69
|
`,text:`Reset your password: {{resetUrl}}
|
|
70
70
|
|
|
71
|
-
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:
|
|
71
|
+
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
72
|
<h1>Verify Your Email</h1>
|
|
73
73
|
<p>Hi {{user.name}},</p>
|
|
74
74
|
<p><a href="{{verifyUrl}}">Click here to verify your email address</a></p>
|
|
75
75
|
<p>This link expires in 24 hours.</p>
|
|
76
|
-
`,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:
|
|
76
|
+
`,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
77
|
<h1>Team Invitation</h1>
|
|
78
78
|
<p>Hi {{user.name}},</p>
|
|
79
79
|
<p><strong>{{inviter.name}}</strong> has invited you to join the team <strong>{{team.name}}</strong>.</p>
|
|
80
80
|
<p><a href="{{acceptUrl}}">Accept Invitation</a></p>
|
|
81
81
|
<p>This invitation expires in 3 days.</p>
|
|
82
|
-
`,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:
|
|
82
|
+
`,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
83
|
<h1>Invoice #{{invoice.number}}</h1>
|
|
84
84
|
<p>Hi {{customer.name}},</p>
|
|
85
85
|
<p>Thank you for your purchase!</p>
|
|
@@ -87,14 +87,14 @@ This link expires in 1 hour.`,variables:["appName","user.name","resetUrl"],categ
|
|
|
87
87
|
<p><strong>Date:</strong> {{invoice.date}}</p>
|
|
88
88
|
<p><a href="{{invoiceUrl}}">View Invoice</a></p>
|
|
89
89
|
`,text:`Invoice #{{invoice.number}}
|
|
90
|
-
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:
|
|
90
|
+
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
91
|
<h1>Subscription Confirmed</h1>
|
|
92
92
|
<p>Hi {{user.name}},</p>
|
|
93
93
|
<p>Your {{plan.name}} plan is now active.</p>
|
|
94
94
|
<p><strong>Price:</strong> {{plan.price}} / {{plan.interval}}</p>
|
|
95
95
|
<p>Your next billing date is {{nextBillingDate}}.</p>
|
|
96
96
|
`,text:`Your {{plan.name}} plan is active.
|
|
97
|
-
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:
|
|
97
|
+
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
98
|
<h1>Your Verification Code</h1>
|
|
99
99
|
<p>Hi {{user.name}},</p>
|
|
100
100
|
<p>Your one-time verification code is:</p>
|
|
@@ -103,27 +103,27 @@ Next billing: {{nextBillingDate}}`,variables:["user.name","plan.name","plan.pric
|
|
|
103
103
|
<p>If you didn't request this code, you can safely ignore this email.</p>
|
|
104
104
|
`,text:`Your verification code: {{code}}
|
|
105
105
|
|
|
106
|
-
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:
|
|
106
|
+
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
107
|
<h1>Subscription Canceled</h1>
|
|
108
108
|
<p>Hi {{user.name}},</p>
|
|
109
109
|
<p>Your {{plan.name}} subscription has been canceled.</p>
|
|
110
110
|
<p>You have access until {{accessUntilDate}}.</p>
|
|
111
111
|
`,text:`Your {{plan.name}} subscription is canceled.
|
|
112
|
-
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,n,i)=>this.getNestedValue(t,n)?i:""),s=s.replace(/\{\{#each\s+(\w+(?:\.\w+)*)\}\}([\s\S]*?)\{\{\/each\}\}/g,(r,n,i)=>{let o=this.getNestedValue(t,n);return Array.isArray(o)?o.map((a,l)=>{let u={...t,this:a,$index:l};return this.interpolate(i,u)}).join(""):""}),s=s.replace(/\{\{([\w.$]+)\}\}/g,(r,n)=>{let i=this.getNestedValue(t,n);return i!=null?String(i):""}),s}getNestedValue(e,t){return t.split(".").reduce((s,r)=>s?.[r],e)}},Uo=b("svelar.emailTemplates",()=>new vs)});var $s={};C($s,{Mailable:()=>$e,Mailer:()=>Rs});function Ps(c){return typeof c=="string"?c:`${c.name} <${c.address}>`}function R(c){return c?Array.isArray(c)?c:[c]:[]}function gn(c){return Buffer.isBuffer(c)?c.toString("base64"):Buffer.from(c).toString("base64")}var Qe,Ts,xs,Es,Ss,$e,Cs,Rs,Ge=f(()=>{"use strict";E();Qe=class{async send(e){let t=R(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:[]}}},Ts=class{async send(e){return{accepted:R(e.to),rejected:[]}}},xs=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?Ps(e.from):void 0,to:R(e.to).join(", "),cc:R(e.cc).join(", ")||void 0,bcc:R(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}}},Es=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=R(e.to),r=R(e.cc),n=R(e.bcc),i={From:e.from?Ps(e.from):void 0,To:s.join(", "),Subject:e.subject,MessageStream:this.config.messageStream||"outbound"};r.length>0&&(i.Cc=r.join(", ")),n.length>0&&(i.Bcc=n.join(", ")),e.replyTo&&(i.ReplyTo=e.replyTo),e.html&&(i.HtmlBody=e.html),e.text&&(i.TextBody=e.text),!i.HtmlBody&&!i.TextBody&&(i.TextBody=""),e.tags&&(i.Tag=Object.values(e.tags)[0]),e.attachments?.length&&(i.Attachments=e.attachments.map(l=>({Name:l.filename,Content:gn(l.content),ContentType:l.contentType||"application/octet-stream"})));let o=await fetch("https://api.postmarkapp.com/email",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json","X-Postmark-Server-Token":t},body:JSON.stringify(i)});if(!o.ok){let l=await o.json().catch(()=>({Message:o.statusText}));throw new Error(`Postmark error ${o.status}: ${l.Message||JSON.stringify(l)}`)}let a=await o.json();return{accepted:s,rejected:[],messageId:a.MessageID}}},Ss=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=R(e.to),r=R(e.cc),n=R(e.bcc),i={from:e.from?Ps(e.from):void 0,to:s,subject:e.subject};r.length>0&&(i.cc=r),n.length>0&&(i.bcc=n),e.replyTo&&(i.reply_to=[e.replyTo]),e.html&&(i.html=e.html),e.text&&(i.text=e.text),e.tags&&(i.tags=Object.entries(e.tags).map(([l,u])=>({name:l,value:u}))),e.attachments?.length&&(i.attachments=e.attachments.map(l=>({filename:l.filename,content:gn(l.content),content_type:l.contentType||"application/octet-stream"})));let o=await fetch("https://api.resend.com/emails",{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify(i)});if(!o.ok){let l=await o.json().catch(()=>({message:o.statusText}));throw new Error(`Resend error ${o.status}: ${l.message||JSON.stringify(l)}`)}let a=await o.json();return{accepted:s,rejected:[],messageId:a.id}}},$e=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}},Cs=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 n=new Qe;return this.transports.set(t,n),n}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 xs(s);break;case"postmark":r=new Es(s);break;case"resend":r=new Ss(s);break;case"log":r=new Qe;break;case"null":r=new Ts;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}},Rs=b("svelar.mail",()=>new Cs)});import{createHmac as ae,randomBytes as ke}from"crypto";function fn(c){return(typeof c=="string"?Buffer.from(c):c).toString("base64url")}function yn(c){return Buffer.from(c,"base64url").toString("utf-8")}function bn(c,e,t,s){return ae(s==="HS384"?"sha384":s==="HS512"?"sha512":"sha256",t).update(`${c}.${e}`).digest("base64url")}function ks(c,e,t="HS256"){let s=fn(JSON.stringify({alg:t,typ:"JWT"})),r=fn(JSON.stringify(c)),n=bn(s,r,e,t);return`${s}.${r}.${n}`}function As(c,e){let t=c.split(".");if(t.length!==3)return null;let[s,r,n]=t,i;try{i=JSON.parse(yn(s))}catch{return null}let o=bn(s,r,e,i.alg);if(n!==o)return null;try{let a=JSON.parse(yn(r));return a.exp&&Date.now()/1e3>a.exp?null:a}catch{return null}}var Ye,ce,Xe,Ns=f(()=>{"use strict";se();Ye=class{config;currentUser=null;constructor(e){this.config={identifierColumn:"email",passwordColumn:"password",...e}}async attempt(e,t){let{Hash:s}=await Promise.resolve().then(()=>(oe(),Re)),r=e[this.config.identifierColumn],n=e[this.config.passwordColumn];if(!r||!n)return null;let i=await this.config.model.where(this.config.identifierColumn,r).first();if(!i)return null;let o=i.getAttribute(this.config.passwordColumn);return await s.verify(n,o)?(this.currentUser=i,t&&(t.set("auth_user_id",i.getAttribute("id")),t.regenerateId()),i):null}async attemptJwt(e){let{Hash:t}=await Promise.resolve().then(()=>(oe(),Re));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 n=await this.config.model.where(this.config.identifierColumn,s).first();if(!n)return null;let i=n.getAttribute(this.config.passwordColumn);return await t.verify(r,i)?(this.currentUser=n,this.issueTokenPair(n)):null}async issueTokenPair(e){let t=this.config.jwt,s=t.expiresIn??3600,r=Math.floor(Date.now()/1e3),n={sub:e.getAttribute("id"),iat:r,exp:r+s,...t.issuer?{iss:t.issuer}:{}},i=ks(n,t.secret,t.algorithm),o=new Date((r+s)*1e3),a={user:e,token:i,expiresAt:o};if(t.refreshTokens){let l=t.refreshExpiresIn??604800,u=ke(32).toString("base64url"),d=ae("sha256",t.secret).update(u).digest("hex"),h=new Date((r+l)*1e3),{Connection:g}=await Promise.resolve().then(()=>(w(),T)),y=t.refreshTable??"refresh_tokens";await g.raw(`INSERT INTO ${y} (user_id, token, expires_at, created_at) VALUES (?, ?, ?, ?)`,[e.getAttribute("id"),d,h.toISOString(),new Date().toISOString()]),a.refreshToken=u,a.refreshExpiresAt=h}return a}async refreshJwt(e){if(!this.config.jwt)throw new Error("JWT configuration required.");if(!this.config.jwt.refreshTokens)throw new Error("Refresh tokens are not enabled. Set jwt.refreshTokens = true.");let t=this.config.jwt,s=ae("sha256",t.secret).update(e).digest("hex"),{Connection:r}=await Promise.resolve().then(()=>(w(),T)),n=t.refreshTable??"refresh_tokens",i=await r.raw(`SELECT user_id, expires_at, revoked_at FROM ${n} WHERE token = ?`,[s]);if(i.length===0)return null;let o=i[0];if(o.revoked_at||new Date(o.expires_at)<new Date)return null;await r.raw(`UPDATE ${n} SET revoked_at = ? WHERE token = ?`,[new Date().toISOString(),s]);let a=await this.config.model.find(o.user_id);return a?(this.currentUser=a,this.issueTokenPair(a)):null}async revokeRefreshTokens(e){if(!this.config.jwt?.refreshTokens)return;let{Connection:t}=await Promise.resolve().then(()=>(w(),T)),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=As(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(()=>(oe(),Re));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=ke(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 n=ae("sha256",r).update(s).digest("hex"),{Connection:i}=await Promise.resolve().then(()=>(w(),T)),o=this.config.token?.table??"personal_access_tokens";return await i.raw(`INSERT INTO ${o} (user_id, name, token, created_at) VALUES (?, ?, ?, ?)`,[e.getAttribute("id"),t,n,new Date().toISOString()]),s}async resolveFromApiToken(e){let{Connection:t}=await Promise.resolve().then(()=>(w(),T)),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 n=ae("sha256",r).update(e).digest("hex"),i=await t.raw(`SELECT user_id FROM ${s} WHERE token = ?`,[n]);if(i.length===0)return null;let o=await this.config.model.find(i[0].user_id);return o&&(this.currentUser=o),o}async sendPasswordReset(e){let t=await this.config.model.where(this.config.identifierColumn,e).first();if(!t)return!1;let{Connection:s}=await Promise.resolve().then(()=>(w(),T)),r=this.config.passwordResets?.table??"password_resets",n=this.config.passwordResets?.expiresIn??3600;await this.ensureTable(r,`
|
|
112
|
+
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,n,o)=>this.getNestedValue(t,n)?o:""),s=s.replace(/\{\{#each\s+(\w+(?:\.\w+)*)\}\}([\s\S]*?)\{\{\/each\}\}/g,(r,n,o)=>{let i=this.getNestedValue(t,n);return Array.isArray(i)?i.map((a,l)=>{let u={...t,this:a,$index:l};return this.interpolate(o,u)}).join(""):""}),s=s.replace(/\{\{([\w.$]+)\}\}/g,(r,n)=>{let o=this.getNestedValue(t,n);return o!=null?String(o):""}),s}getNestedValue(e,t){return t.split(".").reduce((s,r)=>s?.[r],e)}},Bo=b("svelar.emailTemplates",()=>new Ts)});var Ds={};C(Ds,{Mailable:()=>$e,Mailer:()=>$s});function Rs(c){return typeof c=="string"?c:`${c.name} <${c.address}>`}function $(c){return c?Array.isArray(c)?c:[c]:[]}function Zr(c){return Buffer.isBuffer(c)?c.toString("base64"):Buffer.from(c).toString("base64")}var Ge,xs,Es,Ss,Cs,$e,Ps,$s,Ye=y(()=>{"use strict";E();Ge=class{async send(e){let t=$(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:[]}}},xs=class{async send(e){return{accepted:$(e.to),rejected:[]}}},Es=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?Rs(e.from):void 0,to:$(e.to).join(", "),cc:$(e.cc).join(", ")||void 0,bcc:$(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}}},Ss=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=$(e.to),r=$(e.cc),n=$(e.bcc),o={From:e.from?Rs(e.from):void 0,To:s.join(", "),Subject:e.subject,MessageStream:this.config.messageStream||"outbound"};r.length>0&&(o.Cc=r.join(", ")),n.length>0&&(o.Bcc=n.join(", ")),e.replyTo&&(o.ReplyTo=e.replyTo),e.html&&(o.HtmlBody=e.html),e.text&&(o.TextBody=e.text),!o.HtmlBody&&!o.TextBody&&(o.TextBody=""),e.tags&&(o.Tag=Object.values(e.tags)[0]),e.attachments?.length&&(o.Attachments=e.attachments.map(l=>({Name:l.filename,Content:Zr(l.content),ContentType:l.contentType||"application/octet-stream"})));let i=await fetch("https://api.postmarkapp.com/email",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json","X-Postmark-Server-Token":t},body:JSON.stringify(o)});if(!i.ok){let l=await i.json().catch(()=>({Message:i.statusText}));throw new Error(`Postmark error ${i.status}: ${l.Message||JSON.stringify(l)}`)}let a=await i.json();return{accepted:s,rejected:[],messageId:a.MessageID}}},Cs=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=$(e.to),r=$(e.cc),n=$(e.bcc),o={from:e.from?Rs(e.from):void 0,to:s,subject:e.subject};r.length>0&&(o.cc=r),n.length>0&&(o.bcc=n),e.replyTo&&(o.reply_to=[e.replyTo]),e.html&&(o.html=e.html),e.text&&(o.text=e.text),e.tags&&(o.tags=Object.entries(e.tags).map(([l,u])=>({name:l,value:u}))),e.attachments?.length&&(o.attachments=e.attachments.map(l=>({filename:l.filename,content:Zr(l.content),content_type:l.contentType||"application/octet-stream"})));let i=await fetch("https://api.resend.com/emails",{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify(o)});if(!i.ok){let l=await i.json().catch(()=>({message:i.statusText}));throw new Error(`Resend error ${i.status}: ${l.message||JSON.stringify(l)}`)}let a=await i.json();return{accepted:s,rejected:[],messageId:a.id}}},$e=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}},Ps=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 n=new Ge;return this.transports.set(t,n),n}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 Es(s);break;case"postmark":r=new Ss(s);break;case"resend":r=new Cs(s);break;case"log":r=new Ge;break;case"null":r=new xs;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}},$s=b("svelar.mail",()=>new Ps)});import{createHmac as oe,randomBytes as De}from"crypto";function en(c){return(typeof c=="string"?Buffer.from(c):c).toString("base64url")}function tn(c){return Buffer.from(c,"base64url").toString("utf-8")}function sn(c,e,t,s){return oe(s==="HS384"?"sha384":s==="HS512"?"sha512":"sha256",t).update(`${c}.${e}`).digest("base64url")}function ks(c,e,t="HS256"){let s=en(JSON.stringify({alg:t,typ:"JWT"})),r=en(JSON.stringify(c)),n=sn(s,r,e,t);return`${s}.${r}.${n}`}function As(c,e){let t=c.split(".");if(t.length!==3)return null;let[s,r,n]=t,o;try{o=JSON.parse(tn(s))}catch{return null}let i=sn(s,r,e,o.alg);if(n!==i)return null;try{let a=JSON.parse(tn(r));return a.exp&&Date.now()/1e3>a.exp?null:a}catch{return null}}var Xe,ae,Ze,Ns=y(()=>{"use strict";te();Xe=class{config;currentUser=null;constructor(e){this.config={identifierColumn:"email",passwordColumn:"password",...e}}async attempt(e,t){let{Hash:s}=await Promise.resolve().then(()=>(ie(),Re)),r=e[this.config.identifierColumn],n=e[this.config.passwordColumn];if(!r||!n)return null;let o=await this.config.model.where(this.config.identifierColumn,r).first();if(!o)return null;let i=o.getAttribute(this.config.passwordColumn);return await s.verify(n,i)?(this.currentUser=o,t&&(t.set("auth_user_id",o.getAttribute("id")),t.regenerateId()),o):null}async attemptJwt(e){let{Hash:t}=await Promise.resolve().then(()=>(ie(),Re));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 n=await this.config.model.where(this.config.identifierColumn,s).first();if(!n)return null;let o=n.getAttribute(this.config.passwordColumn);return await t.verify(r,o)?(this.currentUser=n,this.issueTokenPair(n)):null}async issueTokenPair(e){let t=this.config.jwt,s=t.expiresIn??3600,r=Math.floor(Date.now()/1e3),n={sub:e.getAttribute("id"),iat:r,exp:r+s,...t.issuer?{iss:t.issuer}:{}},o=ks(n,t.secret,t.algorithm),i=new Date((r+s)*1e3),a={user:e,token:o,expiresAt:i};if(t.refreshTokens){let l=t.refreshExpiresIn??604800,u=De(32).toString("base64url"),d=oe("sha256",t.secret).update(u).digest("hex"),h=new Date((r+l)*1e3),{Connection:p}=await Promise.resolve().then(()=>(w(),T)),f=t.refreshTable??"refresh_tokens";await p.raw(`INSERT INTO ${f} (user_id, token, expires_at, created_at) VALUES (?, ?, ?, ?)`,[e.getAttribute("id"),d,h.toISOString(),new Date().toISOString()]),a.refreshToken=u,a.refreshExpiresAt=h}return a}async refreshJwt(e){if(!this.config.jwt)throw new Error("JWT configuration required.");if(!this.config.jwt.refreshTokens)throw new Error("Refresh tokens are not enabled. Set jwt.refreshTokens = true.");let t=this.config.jwt,s=oe("sha256",t.secret).update(e).digest("hex"),{Connection:r}=await Promise.resolve().then(()=>(w(),T)),n=t.refreshTable??"refresh_tokens",o=await r.raw(`SELECT user_id, expires_at, revoked_at FROM ${n} WHERE token = ?`,[s]);if(o.length===0)return null;let i=o[0];if(i.revoked_at||new Date(i.expires_at)<new Date)return null;await r.raw(`UPDATE ${n} SET revoked_at = ? WHERE token = ?`,[new Date().toISOString(),s]);let a=await this.config.model.find(i.user_id);return a?(this.currentUser=a,this.issueTokenPair(a)):null}async revokeRefreshTokens(e){if(!this.config.jwt?.refreshTokens)return;let{Connection:t}=await Promise.resolve().then(()=>(w(),T)),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=As(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(()=>(ie(),Re));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=De(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 n=oe("sha256",r).update(s).digest("hex"),{Connection:o}=await Promise.resolve().then(()=>(w(),T)),i=this.config.token?.table??"personal_access_tokens";return await o.raw(`INSERT INTO ${i} (user_id, name, token, created_at) VALUES (?, ?, ?, ?)`,[e.getAttribute("id"),t,n,new Date().toISOString()]),s}async resolveFromApiToken(e){let{Connection:t}=await Promise.resolve().then(()=>(w(),T)),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 n=oe("sha256",r).update(e).digest("hex"),o=await t.raw(`SELECT user_id FROM ${s} WHERE token = ?`,[n]);if(o.length===0)return null;let i=await this.config.model.find(o[0].user_id);return i&&(this.currentUser=i),i}async sendPasswordReset(e){let t=await this.config.model.where(this.config.identifierColumn,e).first();if(!t)return!1;let{Connection:s}=await Promise.resolve().then(()=>(w(),T)),r=this.config.passwordResets?.table??"password_resets",n=this.config.passwordResets?.expiresIn??3600;await this.ensureTable(r,`
|
|
113
113
|
CREATE TABLE IF NOT EXISTS ${r} (
|
|
114
114
|
email TEXT NOT NULL,
|
|
115
115
|
token TEXT NOT NULL,
|
|
116
116
|
expires_at TEXT NOT NULL,
|
|
117
117
|
created_at TEXT NOT NULL
|
|
118
118
|
)
|
|
119
|
-
`),await s.raw(`DELETE FROM ${r} WHERE email = ?`,[e]);let
|
|
119
|
+
`),await s.raw(`DELETE FROM ${r} WHERE email = ?`,[e]);let o=De(32).toString("base64url"),i=this.hashToken(o),a=new Date(Date.now()+n*1e3).toISOString();await s.raw(`INSERT INTO ${r} (email, token, expires_at, created_at) VALUES (?, ?, ?, ?)`,[e,i,a,new Date().toISOString()]);let l=this.config.appUrl??process.env.APP_URL??"http://localhost:5173",u=this.config.appName??process.env.APP_NAME??"Svelar",d=`${l}/reset-password?token=${o}&email=${encodeURIComponent(e)}`;return await this.sendAuthEmail("password-reset",e,{appName:u,"user.name":t.getAttribute("name")??e,resetUrl:d}),!0}async resetPassword(e,t,s){let{Connection:r}=await Promise.resolve().then(()=>(w(),T)),{Hash:n}=await Promise.resolve().then(()=>(ie(),Re)),o=this.config.passwordResets?.table??"password_resets",i=this.hashToken(e),a=await r.raw(`SELECT email, expires_at FROM ${o} WHERE token = ? AND email = ?`,[i,t]);if(a.length===0)return!1;let l=a[0];if(new Date(l.expires_at)<new Date)return await r.raw(`DELETE FROM ${o} WHERE email = ?`,[t]),!1;let u=await this.config.model.where(this.config.identifierColumn,t).first();if(!u)return!1;let d=await n.make(s);return await this.config.model.where("id",u.getAttribute("id")).update({[this.config.passwordColumn]:d}),await r.raw(`DELETE FROM ${o} WHERE email = ?`,[t]),await this.revokeRefreshTokens(u.getAttribute("id")),!0}async sendVerificationEmail(e){let{Connection:t}=await Promise.resolve().then(()=>(w(),T)),s=this.config.emailVerification?.table??"email_verifications",r=this.config.emailVerification?.expiresIn??86400,n=e.getAttribute(this.config.identifierColumn);await this.ensureTable(s,`
|
|
120
120
|
CREATE TABLE IF NOT EXISTS ${s} (
|
|
121
121
|
user_id TEXT NOT NULL,
|
|
122
122
|
token TEXT NOT NULL,
|
|
123
123
|
expires_at TEXT NOT NULL,
|
|
124
124
|
created_at TEXT NOT NULL
|
|
125
125
|
)
|
|
126
|
-
`),await t.raw(`DELETE FROM ${s} WHERE user_id = ?`,[e.getAttribute("id")]);let
|
|
126
|
+
`),await t.raw(`DELETE FROM ${s} WHERE user_id = ?`,[e.getAttribute("id")]);let o=De(32).toString("base64url"),i=this.hashToken(o),a=new Date(Date.now()+r*1e3).toISOString();await t.raw(`INSERT INTO ${s} (user_id, token, expires_at, created_at) VALUES (?, ?, ?, ?)`,[e.getAttribute("id"),i,a,new Date().toISOString()]);let u=`${this.config.appUrl??process.env.APP_URL??"http://localhost:5173"}/verify-email?token=${o}&id=${e.getAttribute("id")}`;await this.sendAuthEmail("email-verification",n,{"user.name":e.getAttribute("name")??n,verifyUrl:u})}async verifyEmail(e,t){let{Connection:s}=await Promise.resolve().then(()=>(w(),T)),r=this.config.emailVerification?.table??"email_verifications",n=this.config.emailVerification?.verifiedColumn??"email_verified_at",o=this.hashToken(e),i=await s.raw(`SELECT user_id, expires_at FROM ${r} WHERE token = ? AND user_id = ?`,[o,t]);return i.length===0?!1:new Date(i[0].expires_at)<new Date?(await s.raw(`DELETE FROM ${r} WHERE user_id = ?`,[t]),!1):(await this.config.model.where("id",t).update({[n]: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(()=>(w(),T)),n=this.config.otp?.table??"otp_codes",o=this.config.otp?.expiresIn??600,i=this.config.otp?.length??6;await this.ensureTable(n,`
|
|
127
127
|
CREATE TABLE IF NOT EXISTS ${n} (
|
|
128
128
|
email TEXT NOT NULL,
|
|
129
129
|
code TEXT NOT NULL,
|
|
@@ -132,32 +132,32 @@ Access until: {{accessUntilDate}}`,variables:["user.name","plan.name","accessUnt
|
|
|
132
132
|
used_at TEXT,
|
|
133
133
|
created_at TEXT NOT NULL
|
|
134
134
|
)
|
|
135
|
-
`),await r.raw(`DELETE FROM ${n} WHERE email = ? AND purpose = ?`,[e,t]);let a=this.generateOtpCode(
|
|
135
|
+
`),await r.raw(`DELETE FROM ${n} WHERE email = ? AND purpose = ?`,[e,t]);let a=this.generateOtpCode(i),l=this.hashToken(a),u=new Date(Date.now()+o*1e3).toISOString();await r.raw(`INSERT INTO ${n} (email, code, purpose, expires_at, created_at) VALUES (?, ?, ?, ?, ?)`,[e,l,t,u,new Date().toISOString()]);let d=this.config.appName??process.env.APP_NAME??"Svelar",h=Math.ceil(o/60);return await this.sendAuthEmail("otp-code",e,{appName:d,"user.name":s.getAttribute("name")??e,code:a,purpose:t,expiresMinutes:String(h)}),!0}async verifyOtp(e,t,s="login"){let{Connection:r}=await Promise.resolve().then(()=>(w(),T)),n=this.config.otp?.table??"otp_codes",o=this.hashToken(t),i=await r.raw(`SELECT email, expires_at, used_at FROM ${n} WHERE code = ? AND email = ? AND purpose = ? AND used_at IS NULL`,[o,e,s]);if(i.length===0)return null;if(new Date(i[0].expires_at)<new Date)return await r.raw(`DELETE FROM ${n} WHERE email = ? AND purpose = ?`,[e,s]),null;await r.raw(`UPDATE ${n} SET used_at = ? WHERE code = ? AND email = ? AND purpose = ?`,[new Date().toISOString(),o,e,s]);let a=await this.config.model.where(this.config.identifierColumn,e).first();return a&&(this.currentUser=a),a}async attemptOtp(e,t,s,r="login"){let n=await this.verifyOtp(e,t,r);return n?(s&&(s.set("auth_user_id",n.getAttribute("id")),s.regenerateId()),n):null}async cleanupExpiredTokens(){let{Connection:e}=await Promise.resolve().then(()=>(w(),T)),t=new Date().toISOString(),s=0,r=0,n=0,o=this.config.passwordResets?.table??"password_resets",i=this.config.emailVerification?.table??"email_verifications",a=this.config.otp?.table??"otp_codes";try{s=(await e.raw(`DELETE FROM ${o} WHERE expires_at < ?`,[t]))?.changes??0}catch{}try{r=(await e.raw(`DELETE FROM ${i} WHERE expires_at < ?`,[t]))?.changes??0}catch{}try{n=(await e.raw(`DELETE FROM ${a} WHERE expires_at < ? OR used_at IS NOT NULL`,[t]))?.changes??0}catch{}return{passwordResets:s,verifications:r,otpCodes:n}}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 oe("sha256",t).update(e).digest("hex")}generateOtpCode(e){let t=De(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(()=>(w(),T));await s.raw(t),this.tablesEnsured.add(e)}async sendAuthEmail(e,t,s){try{let{EmailTemplates:r}=await Promise.resolve().then(()=>(Xr(),Yr)),{Mailer:n}=await Promise.resolve().then(()=>(Ye(),Ds)),o=await r.render(e,s);await n.send({to:t,subject:o.subject,html:o.html,text:o.text})}catch(r){console.error(`[Auth] Failed to send ${e} email to ${t}:`,r.message)}}},ae=class extends S{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 n=t.event.request.headers.get("authorization");if(n?.startsWith("Bearer ")){let o=n.slice(7);try{r=await this.authManager.resolveFromToken(o)}catch{r=await this.authManager.resolveFromApiToken(o)}}}return t.event.locals.user=r,t.event.locals.auth=this.authManager,s()}},Ze=class extends S{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 Wo,mkdir as Ko}from"fs/promises";import{dirname as Jo}from"path";function A(){return new Date().toISOString()}var et,ke,Ms,Os,_s,Ls,Is,tt,js=y(()=>{"use strict";E();et={debug:0,info:1,warn:2,error:3,fatal:4},ke=class{minLevel;format;constructor(e){this.minLevel=e.level??"debug",this.format=e.format??"text"}write(e){if(et[e.level]<et[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]??"",n=e.level.toUpperCase().padEnd(5),o=Object.keys(e.context).length>0?` ${JSON.stringify(e.context)}`:"",i=e.level==="error"||e.level==="fatal"?"error":"log";console[i](`${r}[${e.timestamp}] ${n}${s} ${e.message}${o}`)}},Ms=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(et[e.level]<et[this.minLevel])return;this.initialized||(await Ko(Jo(this.path),{recursive:!0}),this.initialized=!0);let t;if(this.format==="json")t=JSON.stringify(e)+`
|
|
136
136
|
`;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}
|
|
137
|
-
`}await
|
|
137
|
+
`}await Wo(this.path,t)}},Os=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)}}},_s=class{minLevel="debug";write(){}},Ls=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 Is(this.resolveChannel(e))}debug(e,t={}){this.writeToDefault({level:"debug",message:e,context:t,timestamp:A()})}info(e,t={}){this.writeToDefault({level:"info",message:e,context:t,timestamp:A()})}warn(e,t={}){this.writeToDefault({level:"warn",message:e,context:t,timestamp:A()})}error(e,t={}){this.writeToDefault({level:"error",message:e,context:t,timestamp:A()})}fatal(e,t={}){this.writeToDefault({level:"fatal",message:e,context:t,timestamp:A()})}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 ke({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 ke(e);case"file":return new Ms(e);case"stack":return new Os(e,t=>this.resolveChannel(t));case"null":return new _s;default:return new ke(e)}}},Is=class{constructor(e){this.channel=e}debug(e,t={}){this.channel.write({level:"debug",message:e,context:t,timestamp:A()})}info(e,t={}){this.channel.write({level:"info",message:e,context:t,timestamp:A()})}warn(e,t={}){this.channel.write({level:"warn",message:e,context:t,timestamp:A()})}error(e,t={}){this.channel.write({level:"error",message:e,context:t,timestamp:A()})}fatal(e,t={}){this.channel.write({level:"fatal",message:e,context:t,timestamp:A()})}};tt=b("svelar.log",()=>new Ls)});function it(c,e){throw new D(c,e??zo(c))}function rn(c,e,t){c&&it(e,t)}function nn(c,e,t){c||it(e,t)}function zo(c){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"}[c]??"An error occurred"}var D,st,qs,Us,rt,nt,ce,Hs=y(()=>{"use strict";js();D=class extends Error{constructor(t,s,r){super(s);this.statusCode=t;this.details=r;this.name="HttpError"}},st=class extends D{constructor(e="The requested resource was not found"){super(404,e),this.name="NotFoundError"}},qs=class extends D{constructor(e="Unauthenticated"){super(401,e),this.name="UnauthorizedError"}},Us=class extends D{constructor(e="You do not have permission to perform this action"){super(403,e),this.name="ForbiddenError"}},rt=class extends D{constructor(t,s="The given data was invalid"){super(422,s,{errors:t});this.errors=t;this.name="ValidationError"}},nt=class extends st{constructor(e,t){super(t?`${e} with ID ${t} not found`:`${e} not found`),this.name="ModelNotFoundError"}};ce=class{config;constructor(e={}){this.config={debug:process.env.NODE_ENV!=="production",dontReport:[rt,st,qs,Us],...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 n=e instanceof Error?e:new Error(String(e));return this.reportError(n,t),n instanceof D?{message:n.message,status:n.statusCode,...n.details??{},...this.config.debug?{stack:n.stack}:{}}:{message:this.config.debug?n.message:"An unexpected error occurred",status:s,...this.config.debug?{stack:n.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(tt.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 rt&&(s.errors=e.errors),e.details&&Object.assign(s,e.details),this.config.debug&&(s.exception=e.name,s.stack=e.stack?.split(`
|
|
138
138
|
`).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(`
|
|
139
|
-
`).map(s=>s.trim())),new Response(JSON.stringify(t),{status:500,headers:{"Content-Type":"application/json"}})}}});function Tn(c={}){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:n=100,rateLimitWindow:i=6e4,csrfPaths:o=["/api/"],csrfExcludePaths:a=["/api/webhooks"],authThrottleAttempts:l=5,authThrottleDecay:u=1,debug:d=process.env.NODE_ENV!=="production",middleware:h=[],namedMiddleware:g={},i18n:y,errorConfig:v={}}=c,k=[new ee,new X({maxRequests:n,windowMs:i}),new Z({onlyPaths:o,excludePaths:a}),new ie({store:s??new H,secret:t,lifetime:r})];e&&k.push(new ce(e)),k.push(...h);let ri={"auth-throttle":new te({maxAttempts:l,decayMinutes:u}),...g},br=new le({debug:d,...v}),wr=Hs({middleware:k,namedMiddleware:ri,onError:(pt,mt)=>br.handle(pt,mt)}),ht;if(y){let{paraglideMiddleware:pt,getTextDirection:mt=()=>"ltr"}=y;ht=Fs(async({event:gt,resolve:ni})=>pt(gt.request,({request:ii,locale:vr})=>(gt.request=ii,ni(gt,{transformPageChunk:({html:oi})=>oi.replace("%lang%",vr).replace("%dir%",mt(vr))}))),wr)}else ht=wr;return{handle:ht,handleError:br.handleSvelteKitError()}}function Hs(c={}){let e=new L;if(c.middleware)for(let t of c.middleware)e.use(t);if(c.namedMiddleware)for(let[t,s]of Object.entries(c.namedMiddleware))e.register(t,s);return async function({event:s,resolve:r}){let n={event:s,params:s.params??{},locals:s.locals??{}};try{c.app&&!c.app.isBooted()&&await c.app.bootstrap();let i=await e.execute(n,async()=>r(s));return i instanceof Response?i:r(s)}catch(i){if(c.onError){let o=await c.onError(i,s);if(o instanceof Response)return o}return console.error("[Svelar] Unhandled error in hooks:",i),new Response(JSON.stringify({message:process.env.NODE_ENV==="production"?"Internal server error":i.message}),{status:500,headers:{"Content-Type":"application/json"}})}}}function Fs(...c){return async function({event:t,resolve:s}){let r=s;for(let n=c.length-1;n>=0;n--){let i=c[n],o=r;r=a=>i({event:a,resolve:o})}return r(t)}}var Bs=f(()=>{"use strict";se();fs();Ns();Us()});function xn(c,e){let t=process.env[c];return t===void 0?e!==void 0?e:"":t==="true"?!0:t==="false"?!1:t==="null"?null:/^\d+$/.test(t)?Number(t):t}var Ws,En,Sn=f(()=>{"use strict";E();Ws=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:n,readdirSync:i}=await import("fs"),{pathToFileURL:o}=await import("url"),a=t(e);if(!n(a))return[];let l=i(a).filter(d=>(d.endsWith(".ts")||d.endsWith(".js"))&&!d.startsWith(".")),u=[];for(let d of l){let h=s(d,r(d)),g=t(a,d);try{let v=await import(o(g).href),k=v.default??v.config??v;k&&typeof k=="object"&&!Array.isArray(k)&&(this.set(h,k),u.push(h))}catch{}}return u}get(e,t){let s=e.split("."),r=this.items.get(s[0]);for(let n=1;n<s.length;n++){if(r==null)return t;r=r[s[n]]}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 n=r;for(let i=1;i<s.length-1;i++)(n[s[i]]===void 0||typeof n[s[i]]!="object")&&(n[s[i]]={}),n=n[s[i]];n[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}},En=b("svelar.config",()=>new Ws)});import{z as x}from"zod";function Pn(c,e){let t=c.safeParse(e);if(t.success)return{success:!0,data:t.data};let s={};for(let r of t.error.issues){let n=r.path.length>0?r.path:["_root"],i=s;for(let a=0;a<n.length-1;a++){let l=n[a];l in i||(i[l]={}),i=i[l]}let o=n[n.length-1];i[o]||(i[o]=[]),i[o].push(r.message)}return{success:!1,errors:s}}var Cn,Rn=f(()=>{"use strict";Cn={required:()=>x.string().min(1,"This field is required"),email:()=>x.string().email("Must be a valid email address"),string:(c,e)=>{let t=x.string();return c!==void 0&&(t=t.min(c)),e!==void 0&&(t=t.max(e)),t},number:(c,e)=>{let t=x.number();return c!==void 0&&(t=t.min(c)),e!==void 0&&(t=t.max(e)),t},integer:()=>x.number().int(),boolean:()=>x.boolean(),date:()=>x.coerce.date(),url:()=>x.string().url(),uuid:()=>x.string().uuid(),enum:c=>x.enum(c),array:c=>x.array(c),nullable:c=>c.nullable(),optional:c=>c.optional(),confirmed:(c="password")=>x.object({[c]:x.string(),[`${c}_confirmation`]:x.string()}).refine(e=>e[c]===e[`${c}_confirmation`],{message:"Confirmation does not match",path:[`${c}_confirmation`]}),min:c=>x.number().min(c),max:c=>x.number().max(c),between:(c,e)=>x.number().min(c).max(e),regex:(c,e)=>x.string().regex(c,e),ip:()=>x.string().refine(c=>{let e=c.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:()=>x.string().refine(c=>{try{return JSON.parse(c),!0}catch{return!1}},{message:"Must be valid JSON"})}});var $n={};C($n,{FormAuthorizationError:()=>de,FormRequest:()=>Ne,FormValidationError:()=>ue});var Ne,ue,de,Ks=f(()=>{"use strict";Ne=class{authorize(e){return!0}messages(){return{}}attributes(){return{}}passedValidation(e){return e}failedValidation(e){throw new ue(e)}failedAuthorization(){throw new de}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),n={...Object.fromEntries(e.url.searchParams),...e.params,...r},o=t.rules().safeParse(n);if(!o.success){let a={},l=t.messages(),u=t.attributes();for(let d of o.error.issues){let h=d.path.join("."),g=u[h]??h;a[g]||(a[g]=[]);let y=`${h}.${d.code}`,v=l[y]??l[h];a[g].push(v??d.message)}t.failedValidation(a)}return t.passedValidation(o.data)}},ue=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"}})}},de=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 kn,writeFile as Ko,unlink as Jo,mkdir as Me,readdir as Js,stat as An,copyFile as zo,rename as Vo}from"fs/promises";import{existsSync as Qo}from"fs";import{join as Go,dirname as it}from"path";var zs,ot,Vs,Nn,Mn=f(()=>{"use strict";E();zs=class{constructor(e){this.config=e;if(!e.root)throw new Error('Local disk requires a "root" path.')}resolve(e){return Go(this.config.root,e)}async get(e){return kn(this.resolve(e))}async getText(e){return kn(this.resolve(e),"utf-8")}async put(e,t){let s=this.resolve(e);await Me(it(s),{recursive:!0}),await Ko(s,t)}async append(e,t){let{appendFile:s}=await import("fs/promises"),r=this.resolve(e);await Me(it(r),{recursive:!0}),await s(r,t)}async exists(e){return Qo(this.resolve(e))}async delete(e){try{return await Jo(this.resolve(e)),!0}catch{return!1}}async copy(e,t){let s=this.resolve(t);await Me(it(s),{recursive:!0}),await zo(this.resolve(e),s)}async move(e,t){let s=this.resolve(t);await Me(it(s),{recursive:!0}),await Vo(this.resolve(e),s)}async files(e=""){let t=this.resolve(e);try{return(await Js(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 Js(s,{withFileTypes:!0});for(let n of r){let i=e?`${e}/${n.name}`:n.name;n.isFile()?t.push(i):n.isDirectory()&&t.push(...await this.allFiles(i))}}catch{}return t}async directories(e=""){let t=this.resolve(e);try{return(await Js(t,{withFileTypes:!0})).filter(r=>r.isDirectory()).map(r=>e?`${e}/${r.name}`:r.name)}catch{return[]}}async makeDirectory(e){await Me(this.resolve(e),{recursive:!0})}async deleteDirectory(e){let{rm:t}=await import("fs/promises");await t(this.resolve(e),{recursive:!0,force:!0})}async size(e){return(await An(this.resolve(e))).size}async lastModified(e){return(await An(this.resolve(e))).mtime}url(e){return`${this.config.urlPrefix??""}/${e}`}},ot=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(),n=await(await(await this.getClient()).send(new t.GetObjectCommand({Bucket:this.config.bucket,Key:this.key(e)}))).Body.transformToByteArray();return Buffer.from(n)}async getText(e){return(await this.get(e)).toString("utf-8")}async put(e,t){let s=await this.getS3(),r=await this.getClient(),n=typeof t=="string"?Buffer.from(t,"utf-8"):t;await r.send(new s.PutObjectCommand({Bucket:this.config.bucket,Key:this.key(e),Body:n}))}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,n=s?Buffer.concat([s,r]):r;await this.put(e,n)}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(i=>i.Key).filter(i=>i!==r).map(i=>{let o=this.config.prefix;return o?i.slice(o.length+1):i})}catch{return[]}}async allFiles(e=""){let t=await this.getS3(),s=await this.getClient(),r=this.key(e?`${e}/`:""),n=[],i;do{let o=await s.send(new t.ListObjectsV2Command({Bucket:this.config.bucket,Prefix:r,ContinuationToken:i}));for(let a of o.Contents??[]){let l=this.config.prefix,u=l?a.Key.slice(l.length+1):a.Key;u&&n.push(u)}i=o.IsTruncated?o.NextContinuationToken:void 0}while(i);return n}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(i=>{let o=this.config.prefix;return(o?i.Prefix.slice(o.length+1):i.Prefix).replace(/\/$/,"")}).filter(i=>i.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(),n=await this.getClient(),i=new r.GetObjectCommand({Bucket:this.config.bucket,Key:this.key(e)});return await s.getSignedUrl(n,i,{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}))}}},Vs=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 zs(e);case"s3":return new ot(e);default:throw new Error(`Unknown storage driver: ${e.driver}`)}}s3Disk(e){let t=this.disk(e);if(!(t instanceof ot))throw new Error(`Disk "${e??this.config?.default}" is not an S3 disk.`);return t}},Nn=b("svelar.storage",()=>new Vs)});import{readFile as Yo,writeFile as Xo,unlink as Dn,mkdir as On}from"fs/promises";import{join as Zo,dirname as ea}from"path";import{createHash as ta}from"crypto";var Qs,Gs,Ys,Xs,_n,Ln=f(()=>{"use strict";E();Qs=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,n=this.store.get(e);return await this.put(e,r,n?.expiresAt?Math.ceil((n.expiresAt-Date.now())/1e3):void 0),r}async decrement(e,t=1){return this.increment(e,-t)}},Gs=class{basePath;constructor(e){this.basePath=e.path??"storage/cache"}filePath(e){let t=ta("md5").update(e).digest("hex");return Zo(this.basePath,t.slice(0,2),t)}async get(e){let t=this.filePath(e);try{let s=await Yo(t,"utf-8"),r=JSON.parse(s);return r.expiresAt&&Date.now()>r.expiresAt?(await Dn(t).catch(()=>{}),null):r.value}catch{return null}}async put(e,t,s){let r=this.filePath(e),n={value:t,expiresAt:s?Date.now()+s*1e3:null};await On(ea(r),{recursive:!0}),await Xo(r,JSON.stringify(n))}async forget(e){try{return await Dn(this.filePath(e)),!0}catch{return!1}}async flush(){let{rm:e}=await import("fs/promises");await e(this.basePath,{recursive:!0,force:!0}),await On(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)}},Ys=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}},Xs=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 n=await s();return await this.store().put(e,n,t),n}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 Qs;case"file":return new Gs(e);case"null":return new Ys;case"redis":throw new Error("Redis cache requires ioredis. Install: npm install ioredis");default:throw new Error(`Unknown cache driver: ${e.driver}`)}}},_n=b("svelar.cache",()=>new Xs)});var at,Zs,er,tr,In,jn=f(()=>{"use strict";E();at=class{},Zs=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:n}=await Promise.resolve().then(()=>(Ge(),$s));await n.send({to:r,subject:s.subject,html:s.html,text:s.text,from:s.from})}catch(n){console.error("[Notifications] Failed to send mail notification:",n)}}},er=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(()=>(w(),T));await r.raw(`INSERT INTO ${this.table} (id, notifiable_id, type, data, read_at, created_at)
|
|
140
|
-
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)}}},
|
|
141
|
-
data: ${JSON.stringify(
|
|
139
|
+
`).map(s=>s.trim())),new Response(JSON.stringify(t),{status:500,headers:{"Content-Type":"application/json"}})}}});function on(c={}){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:n=100,rateLimitWindow:o=6e4,csrfPaths:i=["/api/"],csrfExcludePaths:a=["/api/webhooks"],authThrottleAttempts:l=5,authThrottleDecay:u=1,debug:d=process.env.NODE_ENV!=="production",middleware:h=[],namedMiddleware:p={},i18n:f,errorConfig:v={}}=c,P=[new Z,new Y({maxRequests:n,windowMs:o}),new X({onlyPaths:i,excludePaths:a}),new ne({store:s??new H,secret:t,lifetime:r})];e&&P.push(new ae(e)),P.push(...h);let Fn={"auth-throttle":new ee({maxAttempts:l,decayMinutes:u}),...p},wr=new ce({debug:d,...v}),vr=Fs({middleware:P,namedMiddleware:Fn,onError:(mt,gt)=>wr.handle(mt,gt)}),pt;if(f){let{paraglideMiddleware:mt,getTextDirection:gt=()=>"ltr"}=f;pt=Bs(async({event:ft,resolve:Bn})=>mt(ft.request,({request:Wn,locale:Tr})=>(ft.request=Wn,Bn(ft,{transformPageChunk:({html:Kn})=>Kn.replace("%lang%",Tr).replace("%dir%",gt(Tr))}))),vr)}else pt=vr;return{handle:pt,handleError:wr.handleSvelteKitError()}}function Fs(c={}){let e=new L;if(c.middleware)for(let t of c.middleware)e.use(t);if(c.namedMiddleware)for(let[t,s]of Object.entries(c.namedMiddleware))e.register(t,s);return async function({event:s,resolve:r}){let n={event:s,params:s.params??{},locals:s.locals??{}};try{c.app&&!c.app.isBooted()&&await c.app.bootstrap();let o=await e.execute(n,async()=>r(s));return o instanceof Response?o:r(s)}catch(o){if(c.onError){let i=await c.onError(o,s);if(i instanceof Response)return i}return console.error("[Svelar] Unhandled error in hooks:",o),new Response(JSON.stringify({message:process.env.NODE_ENV==="production"?"Internal server error":o.message}),{status:500,headers:{"Content-Type":"application/json"}})}}}function Bs(...c){return async function({event:t,resolve:s}){let r=s;for(let n=c.length-1;n>=0;n--){let o=c[n],i=r;r=a=>o({event:a,resolve:i})}return r(t)}}var Ws=y(()=>{"use strict";te();ys();Ns();Hs()});function an(c,e){let t=process.env[c];return t===void 0?e!==void 0?e:"":t==="true"?!0:t==="false"?!1:t==="null"?null:/^\d+$/.test(t)?Number(t):t}var Ks,cn,ln=y(()=>{"use strict";E();Ks=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:n,readdirSync:o}=await import("fs"),{pathToFileURL:i}=await import("url"),a=t(e);if(!n(a))return[];let l=o(a).filter(d=>(d.endsWith(".ts")||d.endsWith(".js"))&&!d.startsWith(".")),u=[];for(let d of l){let h=s(d,r(d)),p=t(a,d);try{let v=await import(i(p).href),P=v.default??v.config??v;P&&typeof P=="object"&&!Array.isArray(P)&&(this.set(h,P),u.push(h))}catch{}}return u}get(e,t){let s=e.split("."),r=this.items.get(s[0]);for(let n=1;n<s.length;n++){if(r==null)return t;r=r[s[n]]}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 n=r;for(let o=1;o<s.length-1;o++)(n[s[o]]===void 0||typeof n[s[o]]!="object")&&(n[s[o]]={}),n=n[s[o]];n[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}},cn=b("svelar.config",()=>new Ks)});import{z as x}from"zod";function dn(c,e){let t=c.safeParse(e);if(t.success)return{success:!0,data:t.data};let s={};for(let r of t.error.issues){let n=r.path.length>0?r.path:["_root"],o=s;for(let a=0;a<n.length-1;a++){let l=n[a];l in o||(o[l]={}),o=o[l]}let i=n[n.length-1];o[i]||(o[i]=[]),o[i].push(r.message)}return{success:!1,errors:s}}var un,hn=y(()=>{"use strict";un={required:()=>x.string().min(1,"This field is required"),email:()=>x.string().email("Must be a valid email address"),string:(c,e)=>{let t=x.string();return c!==void 0&&(t=t.min(c)),e!==void 0&&(t=t.max(e)),t},number:(c,e)=>{let t=x.number();return c!==void 0&&(t=t.min(c)),e!==void 0&&(t=t.max(e)),t},integer:()=>x.number().int(),boolean:()=>x.boolean(),date:()=>x.coerce.date(),url:()=>x.string().url(),uuid:()=>x.string().uuid(),enum:c=>x.enum(c),array:c=>x.array(c),nullable:c=>c.nullable(),optional:c=>c.optional(),confirmed:(c="password")=>x.object({[c]:x.string(),[`${c}_confirmation`]:x.string()}).refine(e=>e[c]===e[`${c}_confirmation`],{message:"Confirmation does not match",path:[`${c}_confirmation`]}),min:c=>x.number().min(c),max:c=>x.number().max(c),between:(c,e)=>x.number().min(c).max(e),regex:(c,e)=>x.string().regex(c,e),ip:()=>x.string().refine(c=>{let e=c.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:()=>x.string().refine(c=>{try{return JSON.parse(c),!0}catch{return!1}},{message:"Must be valid JSON"})}});var pn={};C(pn,{FormAuthorizationError:()=>ue,FormRequest:()=>Ae,FormValidationError:()=>le});var Ae,le,ue,Js=y(()=>{"use strict";Ae=class{authorize(e){return!0}messages(){return{}}attributes(){return{}}passedValidation(e){return e}failedValidation(e){throw new le(e)}failedAuthorization(){throw new ue}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),n={...Object.fromEntries(e.url.searchParams),...e.params,...r},i=t.rules().safeParse(n);if(!i.success){let a={},l=t.messages(),u=t.attributes();for(let d of i.error.issues){let h=d.path.join("."),p=u[h]??h;a[p]||(a[p]=[]);let f=`${h}.${d.code}`,v=l[f]??l[h];a[p].push(v??d.message)}t.failedValidation(a)}return t.passedValidation(i.data)}},le=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"}})}},ue=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 mn,writeFile as Vo,unlink as Qo,mkdir as Ne,readdir as zs,stat as gn,copyFile as Go,rename as Yo}from"fs/promises";import{existsSync as Xo}from"fs";import{join as Zo,dirname as ot}from"path";var Vs,at,Qs,fn,yn=y(()=>{"use strict";E();Vs=class{constructor(e){this.config=e;if(!e.root)throw new Error('Local disk requires a "root" path.')}resolve(e){return Zo(this.config.root,e)}async get(e){return mn(this.resolve(e))}async getText(e){return mn(this.resolve(e),"utf-8")}async put(e,t){let s=this.resolve(e);await Ne(ot(s),{recursive:!0}),await Vo(s,t)}async append(e,t){let{appendFile:s}=await import("fs/promises"),r=this.resolve(e);await Ne(ot(r),{recursive:!0}),await s(r,t)}async exists(e){return Xo(this.resolve(e))}async delete(e){try{return await Qo(this.resolve(e)),!0}catch{return!1}}async copy(e,t){let s=this.resolve(t);await Ne(ot(s),{recursive:!0}),await Go(this.resolve(e),s)}async move(e,t){let s=this.resolve(t);await Ne(ot(s),{recursive:!0}),await Yo(this.resolve(e),s)}async files(e=""){let t=this.resolve(e);try{return(await zs(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 zs(s,{withFileTypes:!0});for(let n of r){let o=e?`${e}/${n.name}`:n.name;n.isFile()?t.push(o):n.isDirectory()&&t.push(...await this.allFiles(o))}}catch{}return t}async directories(e=""){let t=this.resolve(e);try{return(await zs(t,{withFileTypes:!0})).filter(r=>r.isDirectory()).map(r=>e?`${e}/${r.name}`:r.name)}catch{return[]}}async makeDirectory(e){await Ne(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 gn(this.resolve(e))).size}async lastModified(e){return(await gn(this.resolve(e))).mtime}url(e){return`${this.config.urlPrefix??""}/${e}`}},at=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(),n=await(await(await this.getClient()).send(new t.GetObjectCommand({Bucket:this.config.bucket,Key:this.key(e)}))).Body.transformToByteArray();return Buffer.from(n)}async getText(e){return(await this.get(e)).toString("utf-8")}async put(e,t){let s=await this.getS3(),r=await this.getClient(),n=typeof t=="string"?Buffer.from(t,"utf-8"):t;await r.send(new s.PutObjectCommand({Bucket:this.config.bucket,Key:this.key(e),Body:n}))}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,n=s?Buffer.concat([s,r]):r;await this.put(e,n)}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(o=>o.Key).filter(o=>o!==r).map(o=>{let i=this.config.prefix;return i?o.slice(i.length+1):o})}catch{return[]}}async allFiles(e=""){let t=await this.getS3(),s=await this.getClient(),r=this.key(e?`${e}/`:""),n=[],o;do{let i=await s.send(new t.ListObjectsV2Command({Bucket:this.config.bucket,Prefix:r,ContinuationToken:o}));for(let a of i.Contents??[]){let l=this.config.prefix,u=l?a.Key.slice(l.length+1):a.Key;u&&n.push(u)}o=i.IsTruncated?i.NextContinuationToken:void 0}while(o);return n}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(o=>{let i=this.config.prefix;return(i?o.Prefix.slice(i.length+1):o.Prefix).replace(/\/$/,"")}).filter(o=>o.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(),n=await this.getClient(),o=new r.GetObjectCommand({Bucket:this.config.bucket,Key:this.key(e)});return await s.getSignedUrl(n,o,{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}))}}},Qs=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 Vs(e);case"s3":return new at(e);default:throw new Error(`Unknown storage driver: ${e.driver}`)}}s3Disk(e){let t=this.disk(e);if(!(t instanceof at))throw new Error(`Disk "${e??this.config?.default}" is not an S3 disk.`);return t}},fn=b("svelar.storage",()=>new Qs)});import{readFile as ea,writeFile as ta,unlink as bn,mkdir as wn}from"fs/promises";import{join as sa,dirname as ra}from"path";import{createHash as na}from"crypto";var Gs,Ys,Xs,Zs,vn,Tn=y(()=>{"use strict";E();Gs=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,n=this.store.get(e);return await this.put(e,r,n?.expiresAt?Math.ceil((n.expiresAt-Date.now())/1e3):void 0),r}async decrement(e,t=1){return this.increment(e,-t)}},Ys=class{basePath;constructor(e){this.basePath=e.path??"storage/cache"}filePath(e){let t=na("md5").update(e).digest("hex");return sa(this.basePath,t.slice(0,2),t)}async get(e){let t=this.filePath(e);try{let s=await ea(t,"utf-8"),r=JSON.parse(s);return r.expiresAt&&Date.now()>r.expiresAt?(await bn(t).catch(()=>{}),null):r.value}catch{return null}}async put(e,t,s){let r=this.filePath(e),n={value:t,expiresAt:s?Date.now()+s*1e3:null};await wn(ra(r),{recursive:!0}),await ta(r,JSON.stringify(n))}async forget(e){try{return await bn(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 wn(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)}},Xs=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}},Zs=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 n=await s();return await this.store().put(e,n,t),n}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 Gs;case"file":return new Ys(e);case"null":return new Xs;case"redis":throw new Error("Redis cache requires ioredis. Install: npm install ioredis");default:throw new Error(`Unknown cache driver: ${e.driver}`)}}},vn=b("svelar.cache",()=>new Zs)});var ct,er,tr,sr,xn,En=y(()=>{"use strict";E();ct=class{},er=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:n}=await Promise.resolve().then(()=>(Ye(),Ds));await n.send({to:r,subject:s.subject,html:s.html,text:s.text,from:s.from})}catch(n){console.error("[Notifications] Failed to send mail notification:",n)}}},tr=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(()=>(w(),T));await r.raw(`INSERT INTO ${this.table} (id, notifiable_id, type, data, read_at, created_at)
|
|
140
|
+
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)}}},sr=class{channels=new Map;constructor(){this.channels.set("mail",new er),this.channels.set("database",new tr)}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 n=t.via(r);for(let o of n){let i=this.channels.get(o);if(i)try{await i.send(r,t)}catch(a){console.error(`[Notifications] Channel "${o}" failed:`,a)}else console.warn(`[Notifications] Unknown channel: ${o}`)}}}async sendVia(e,t,s){for(let r of s){let n=this.channels.get(r);n&&await n.send(e,t)}}},xn=b("svelar.notifier",()=>new sr)});function rr(c){return c.startsWith("private-")?"private":c.startsWith("presence-")?"presence":"public"}var nr,lt,ir,or,Sn,Cn=y(()=>{"use strict";E();nr=class{subscribers=[];name;type;constructor(e){this.name=e,this.type=rr(e)}stream(e,t){let s=this,r=new ReadableStream({start(n){let o={channel:s.name};s.type==="presence"&&(o.members=s.getMembers());let i=`event: connected
|
|
141
|
+
data: ${JSON.stringify(o)}
|
|
142
142
|
id: ${Date.now()}
|
|
143
143
|
|
|
144
|
-
`;n.enqueue(new TextEncoder().encode(
|
|
144
|
+
`;n.enqueue(new TextEncoder().encode(i));let a={controller:n,userId:e,userInfo:t};s.subscribers.push(a),s.type==="presence"&&e!==void 0&&s.sendInternal("member:joined",{id:e,...t},a)},cancel(){let n=s.subscribers.findIndex(i=>i.controller===this._controller),o=s.subscribers.length;s.subscribers=s.subscribers.filter(i=>{try{return i.controller.enqueue(new TextEncoder().encode(`:
|
|
145
145
|
|
|
146
|
-
`)),!0}catch{return!1}}),s.type==="presence"&&e!==void 0&&s.subscribers.length<
|
|
146
|
+
`)),!0}catch{return!1}}),s.type==="presence"&&e!==void 0&&s.subscribers.length<o&&s.sendInternal("member:left",{id:e,...t})}});return new Response(r,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"}})}send(e,t,s){let r=`event: ${e}
|
|
147
147
|
data: ${JSON.stringify(t)}
|
|
148
148
|
id: ${Date.now()}
|
|
149
149
|
|
|
150
|
-
`,n=new TextEncoder().encode(r);for(let
|
|
150
|
+
`,n=new TextEncoder().encode(r);for(let o of this.subscribers)if(!(s!==void 0&&o.userId!==s))try{o.controller.enqueue(n)}catch{}}sendInternal(e,t,s){let r=`event: ${e}
|
|
151
151
|
data: ${JSON.stringify(t)}
|
|
152
152
|
id: ${Date.now()}
|
|
153
153
|
|
|
154
|
-
`,n=new TextEncoder().encode(r);for(let
|
|
154
|
+
`,n=new TextEncoder().encode(r);for(let o of this.subscribers)if(o!==s)try{o.controller.enqueue(n)}catch{}}toUser(e){return{send:(t,s)=>this.send(t,s,e)}}subscriberCount(){return this.subscribers.length}getMembers(){return this.type!=="presence"?[]:this.subscribers.filter(e=>e.userId!==void 0).map(e=>({id:e.userId,...e.userInfo??{}}))}hasMember(e){return this.subscribers.some(t=>t.userId===e)}whisper(e,t,s){let r=`event: client-${e}
|
|
155
155
|
data: ${JSON.stringify(t)}
|
|
156
156
|
id: ${Date.now()}
|
|
157
157
|
|
|
158
|
-
`,n=new TextEncoder().encode(r);for(let
|
|
159
|
-
`),l=await this.hmacSha256(this.config.secret,a),u=this.config.useTLS!==!1?"https":"http",d=this.config.host??`api-${this.config.cluster??"mt1"}.pusher.com`,h=this.config.port??(this.config.useTLS!==!1?443:80),
|
|
160
|
-
`);lt("warning",e[422]??"Validation Error",o);return}}}catch{}let s=t||e[c.status]||`Error ${c.status}`,r=c.status>=500?"error":c.status===429?"warning":"error";if(c.status===401){lt("warning",s,"Please sign in to continue.");return}lt(r,s)}function ar(c="XSRF-TOKEN"){if(typeof document>"u")return null;let e=c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),t=document.cookie.match(new RegExp(`(?:^|;\\s*)${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}function Bn(c,e){if(!e)return c;let t=new URL(c,"http://localhost");for(let[s,r]of Object.entries(e))r!=null&&t.searchParams.set(s,String(r));return t.pathname+t.search}var sa,Hn,or,he,Zu,Wn=f(()=>{"use strict";sa={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."},Hn=null;or=class c{_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 c;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),n={...this._headers},i;s!==void 0&&(n["Content-Type"]||(n["Content-Type"]="application/json"),i=typeof s=="string"?s:JSON.stringify(s)),n.Accept||(n.Accept="application/json");let o=null,a=1+this._retries;for(let l=0;l<a;l++){l>0&&await new Promise(u=>setTimeout(u,this._retryDelay*l));try{let u=new AbortController,d=setTimeout(()=>u.abort(),this._timeout),h=await fetch(r,{method:e,headers:n,body:i,signal:u.signal});if(clearTimeout(d),!h.ok&&h.status<500&&l<a-1,!h.ok&&h.status>=500&&l<a-1){o=new he(`HTTP ${h.status}: ${h.statusText}`,h.status,await h.text());continue}let g=h.headers.get("content-type")??"",y;if(g.includes("application/json")?y=await h.json():y=await h.text(),!h.ok)throw new he(`HTTP ${h.status}: ${typeof y=="string"?y:JSON.stringify(y)}`,h.status,y);return{data:y,status:h.status,headers:h.headers,ok:!0}}catch(u){if(u instanceof he)throw u;if(o=u,u.name==="AbortError"&&(o=new he("Request timed out",0,null)),l>=a-1)break}}throw o??new Error("HTTP request failed")}buildFullUrl(e){let t=this._baseUrl?`${this._baseUrl.replace(/\/+$/,"")}/${e.replace(/^\/+/,"")}`:e,s=Object.entries(this._query);if(s.length>0){let r=new URL(t);for(let[n,i]of s)r.searchParams.set(n,i);t=r.toString()}return t}},he=class extends Error{constructor(t,s,r){super(t);this.status=s;this.body=r;this.name="HttpRequestError"}},Zu=new or});function Kn(c){let{paraglideMiddleware:e,getTextDirection:t=()=>"ltr",langPlaceholder:s="%lang%",dirPlaceholder:r="%dir%"}=c;return({event:n,resolve:i})=>e(n.request,({request:o,locale:a})=>(n.request=o,i(n,{transformPageChunk:({html:l})=>l.replace(s,a).replace(r,t(a))})))}function Jn(c){return e=>c.deLocalizeUrl(e.url).pathname}var zn=f(()=>{"use strict"});function Vn(c,e,t={}){return async s=>{let{superValidate:r,fail:n,message:i}=await import("sveltekit-superforms"),{zod:o}=await import("sveltekit-superforms/adapters"),a=await r(s,o(c));if(!a.valid)return n(400,{form:a});try{let l=await e(a.data,s);if(t.redirectTo){let{redirect:u}=await import("@sveltejs/kit");throw u(303,t.redirectTo)}return l??{form:a}}catch(l){if(l?.status>=300&&l?.status<400)throw l;return i(a,t.errorMessage||l.message||"An error occurred",{status:l.status||400})}}}async function Qn(c,e){let{superValidate:t}=await import("sveltekit-superforms"),{zod:s}=await import("sveltekit-superforms/adapters");return t(e??null,s(c))}async function Gn(c,e){let t=await c.request.formData(),s={};for(let[n,i]of t.entries())s[n]=i;let r=e.safeParse(s);if(!r.success){let{FormValidationError:n}=await Promise.resolve().then(()=>(Ks(),$n));throw new n(r.error.flatten().fieldErrors)}return r.data}var Yn=f(()=>{"use strict"});var Xn={};C(Xn,{Application:()=>He,AuthManager:()=>Ye,AuthenticateMiddleware:()=>ce,BelongsTo:()=>Q,BelongsToMany:()=>G,Broadcast:()=>qn,Cache:()=>_n,ColumnBuilder:()=>O,Connection:()=>m,Container:()=>U,Controller:()=>Ke,CorsMiddleware:()=>Fe,CsrfMiddleware:()=>Z,DatabaseSessionStore:()=>Je,ErrorHandler:()=>le,Event:()=>Y,EventDispatcher:()=>Te,FileSessionStore:()=>ze,ForbiddenError:()=>Se,FormAuthorizationError:()=>de,FormRequest:()=>Ne,FormValidationError:()=>ue,HasMany:()=>V,HasOne:()=>z,Hash:()=>ws,HttpError:()=>$,Job:()=>K,Log:()=>et,LoggingMiddleware:()=>Be,Mailable:()=>$e,Mailer:()=>Rs,MemorySessionStore:()=>H,Middleware:()=>S,MiddlewareStack:()=>L,Migration:()=>me,Migrator:()=>ge,Model:()=>qe,ModelNotFoundError:()=>rt,NotFoundError:()=>xe,Notification:()=>at,Notifier:()=>In,OriginMiddleware:()=>ee,QueryBuilder:()=>A,Queue:()=>ls,RateLimitMiddleware:()=>X,RedisSessionStore:()=>Ve,RequireAuthMiddleware:()=>Xe,Schema:()=>_,Seeder:()=>Ue,ServiceProvider:()=>ve,Session:()=>ne,SessionMiddleware:()=>ie,SignatureMiddleware:()=>We,Storage:()=>Nn,TableBuilder:()=>B,ThrottleMiddleware:()=>te,UnauthorizedError:()=>Ee,ValidationError:()=>I,abort:()=>nt,abortIf:()=>wn,abortUnless:()=>vn,apiFetch:()=>Fn,buildUrl:()=>Bn,config:()=>En,container:()=>an,createFormAction:()=>Vn,createI18nHandle:()=>Kn,createReroute:()=>Jn,createSvelarApp:()=>Tn,createSvelarHooks:()=>Hs,env:()=>xn,getCsrfToken:()=>ar,loadForm:()=>Qn,resource:()=>ln,rules:()=>Cn,schema:()=>Jr,sequence:()=>Fs,signJwt:()=>ks,validate:()=>Pn,validateForm:()=>Gn,verifyJwt:()=>As,z:()=>x});var Zn=f(()=>{"use strict";nn();hs();ps();w();Gt();Yt();on();gs();ms();cn();se();un();Bs();Sn();Rn();Ns();oe();fs();Us();je();Ks();Mn();Is();Ln();us();Ge();jn();Un();Wn();zn();Yn();Bs()});var ur={};C(ur,{PluginRegistry:()=>ut});var lr,ut,dt=f(()=>{"use strict";E();lr=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"),n=[],i=e(process.cwd(),"node_modules");if(!t(i))return n;try{let o=s(i,{withFileTypes:!0});for(let a of o){if(!a.isDirectory())continue;let l=a.name;if(l.startsWith("."))continue;let u=l.startsWith("svelar-");if(!u)continue;let d=e(i,l,"package.json");if(t(d))try{let h=await r(d,"utf-8"),g=JSON.parse(h),y=g.keywords?.includes("svelar-plugin");if(!u&&!y)continue;let v={name:g.name||l,version:g.version||"0.0.0",description:g.description||"",packageName:l,installed:!0,enabled:!1,hasConfig:!!g.svelar?.config,hasMigrations:!!g.svelar?.migrations};n.push(v),this.plugins.set(v.name,v)}catch{}}}catch{}return n}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)}},ut=b("svelar.pluginRegistry",()=>new lr)});var ei={};C(ei,{PluginPublisher:()=>pr});var hr,pr,mr=f(()=>{"use strict";E();hr=class{async publish(e,t){let{mkdir:s,copyFile:r}=await import("fs/promises"),{join:n,dirname:i}=await import("path"),{existsSync:o}=await import("fs"),a={configs:[],migrations:[],assets:[]},l=e.publishables?.()||{};for(let[u,d]of Object.entries(l))for(let h of d){if(t?.only&&h.type!==t.only)continue;let g=n(process.cwd(),h.dest),y=i(g);if(!(o(g)&&!t?.force))try{await s(y,{recursive:!0}),await r(h.source,g),h.type==="config"?a.configs.push(g):h.type==="migration"?a.migrations.push(g):h.type==="asset"&&a.assets.push(g)}catch(v){console.warn(`Failed to publish ${h.source} to ${g}:`,v)}}return a}async preview(e){let t={configs:[],migrations:[],assets:[]},s=e.publishables?.()||{};for(let[r,n]of Object.entries(s))for(let i of n){let o=De("path").join(process.cwd(),i.dest);i.type==="config"?t.configs.push(o):i.type==="migration"?t.migrations.push(o):i.type==="asset"&&t.assets.push(o)}return t}},pr=b("svelar.pluginPublisher",()=>new hr)});var ti={};C(ti,{PluginInstaller:()=>na});var fr,na,si=f(()=>{"use strict";E();dt();mr();fr=class{async install(e,t){let{spawn:s}=await import("child_process"),{promisify:r}=await import("util"),{join:n}=await import("path"),{readFile:i}=await import("fs/promises"),{existsSync:o}=await import("fs");try{await this.runNpmInstall(e);let a=ut,l=await a.discover(),u;for(let h of l)if(h.packageName===e||h.name===e){u=h;break}if(!u)return{success:!1,pluginName:e,version:"0.0.0",published:null,error:`Plugin not found after installation. Make sure ${e} is a valid Svelar plugin.`};a.enable(u.name);let d=null;if(t?.publish!==!1)try{let h=await this.loadPluginClass(u.packageName);h&&(d=await pr.publish(new h))}catch(h){console.warn("Failed to publish plugin assets:",h)}return{success:!0,pluginName:u.name,version:u.version,published:d}}catch(a){return{success:!1,pluginName:e,version:"0.0.0",published:null,error:a?.message??String(a)}}}async uninstall(e){try{let t=ut,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}=De("child_process"),n=r("npm",["install",e],{cwd:process.cwd(),stdio:"inherit"});n.on("close",i=>{i===0?t():s(new Error(`npm install exited with code ${i}`))}),n.on("error",s)})}async runNpmUninstall(e){return new Promise((t,s)=>{let{spawn:r}=De("child_process"),n=r("npm",["uninstall",e],{cwd:process.cwd(),stdio:"inherit"});n.on("close",i=>{i===0?t():s(new Error(`npm uninstall exited with code ${i}`))}),n.on("error",s)})}async loadPluginClass(e){try{let t=await import(e);return t.default||Object.values(t)[0]}catch{return null}}},na=b("svelar.pluginInstaller",()=>new fr)});var ft=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:n,flags:i}=this.parseArgs(s,r);try{await r.handle(n,i)}catch(o){let a=o instanceof Error?o.message:String(o);console.error(`\x1B[31mError:\x1B[0m ${a}`),o?.stack&&console.error(o.stack),process.exit(1)}}parseArgs(e,t){let s=[],r={};for(let n of t.flags)n.default!==void 0&&(r[n.name]=n.default);for(let n=0;n<e.length;n++){let i=e[n];if(i.startsWith("--")){let o=i.slice(2),a=o.indexOf("=");if(a!==-1){let d=o.slice(0,a);r[d]=o.slice(a+1);continue}let l=o;t.flags.find(d=>d.name===l)?.type==="boolean"?r[l]=!0:n+1<e.length&&!e[n+1].startsWith("-")?r[l]=e[++n]:r[l]=!0}else if(i.startsWith("-")&&i.length===2){let o=i.slice(1),a=t.flags.find(l=>l.alias===o);a&&(a.type==="boolean"?r[a.name]=!0:n+1<e.length&&(r[a.name]=e[++n]))}else s.push(i)}return{args:s,flags:r}}showCommandHelp(e){if(console.log(`
|
|
158
|
+
`,n=new TextEncoder().encode(r);for(let o of this.subscribers)if(o.userId!==s)try{o.controller.enqueue(n)}catch{}}},lt=class{config;constructor(e){this.config=e}async send(e,t,s){let r=Array.isArray(e)?e:[e],n=JSON.stringify({name:t,channels:r,data:JSON.stringify(s)}),o=Math.floor(Date.now()/1e3).toString(),i=await this.md5(n),a=["POST",`/apps/${this.config.appId}/events`,[`auth_key=${this.config.key}`,`auth_timestamp=${o}`,"auth_version=1.0",`body_md5=${i}`].join("&")].join(`
|
|
159
|
+
`),l=await this.hmacSha256(this.config.secret,a),u=this.config.useTLS!==!1?"https":"http",d=this.config.host??`api-${this.config.cluster??"mt1"}.pusher.com`,h=this.config.port??(this.config.useTLS!==!1?443:80),p=`${u}://${d}:${h}/apps/${this.config.appId}/events?auth_key=${this.config.key}&auth_timestamp=${o}&auth_version=1.0&body_md5=${i}&auth_signature=${l}`,f=await fetch(p,{method:"POST",headers:{"Content-Type":"application/json"},body:n});if(!f.ok){let v=await f.text();throw new Error(`Pusher API error (${f.status}): ${v}`)}}async authenticate(e,t,s){let r=`${e}:${t}`,n;s&&(n=JSON.stringify(s),r+=`:${n}`);let o=await this.hmacSha256(this.config.secret,r),i=`${this.config.key}:${o}`;return n?{auth:i,channel_data:n}:{auth:i}}get key(){return this.config.key}clientConfig(){let e={key:this.config.key,cluster:this.config.cluster??"mt1"};return this.config.host&&(e.wsHost=this.config.host,e.wsPort=this.config.port??6001,e.wssPort=this.config.port??6001,e.forceTLS=this.config.useTLS??!1,e.enabledTransports=["ws","wss"],e.disableStats=!0),e}async md5(e){let{createHash:t}=await import("crypto");return t("md5").update(e).digest("hex")}async hmacSha256(e,t){let{createHmac:s}=await import("crypto");return s("sha256",e).update(t).digest("hex")}},ir=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)}},or=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 lt(t))}channel(e,t){if(t){this.channelAuth.set(e,t);return}return this.sseChannels.has(e)||this.sseChannels.set(e,new nr(e)),this.sseChannels.get(e)}async authorize(e,t){if(rr(e)==="public")return!0;for(let[r,n]of this.channelAuth){let o=this.matchPattern(r,e);if(o!==null)return await n(t,o)}return!1}async authenticatePusher(e,t,s){if(!this.pusherDriver)throw new Error("Pusher driver is not configured. Call Broadcast.configure() first.");let r=rr(e);if(r==="public")return!1;let n=await this.authorize(e,s);if(n===!1)return!1;if(r==="presence"){let o=typeof n=="object"?{user_id:n.id??s.id,user_info:n}:{user_id:s.id,user_info:{id:s.id}};return this.pusherDriver.authenticate(t,e,o)}return this.pusherDriver.authenticate(t,e)}event(e,t){return new ir(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 n=this.config.drivers[this.config.default];switch(n?.driver){case"pusher":this.pusherDriver||(this.pusherDriver=new lt(n)),await this.pusherDriver.send(e,t,s);break;case"log":console.log(`[Broadcast] ${e} \u2192 ${t}:`,JSON.stringify(s));break;default:for(let[,o]of this.sseChannels)o.name===e&&o.send(t,s,r);break}}subscribe(e,t,s){return this.channel(e).stream(t,s)}members(e){let t=this.sseChannels.get(e);return t?t.getMembers():[]}pusher(){if(!this.pusherDriver)throw new Error("Pusher driver is not configured.");return this.pusherDriver}activeChannels(){return[...new Set([...this.sseChannels.values()].map(e=>e.name))]}totalSubscribers(){let e=0;for(let t of this.sseChannels.values())e+=t.subscriberCount();return e}prune(){for(let[e,t]of this.sseChannels)t.subscriberCount()===0&&this.sseChannels.delete(e)}matchPattern(e,t){let s=[],r=e.replace(/[.*+?^${}()|[\]\\]/g,a=>a==="{"||a==="}"?a:`\\${a}`).replace(/\\\{(\w+)\\\}/g,(a,l)=>(s.push(l),"([^.]+)")).replace(/\{(\w+)\}/g,(a,l)=>(s.push(l),"([^.]+)")),n=new RegExp(`^${r}$`),o=t.match(n);if(!o)return null;let i={};for(let a=0;a<s.length;a++)i[s[a]]=o[a+1];return i}},Sn=b("svelar.broadcast",()=>new or)});function ut(c,e,t){Pn&&Pn(c,e,{description:t})}async function Rn(c,e={}){let{csrfCookieName:t="XSRF-TOKEN",csrfHeaderName:s="X-CSRF-Token",showToast:r=!0,errorMessages:n={},...o}=e,i=(o.method||"GET").toUpperCase(),a=new Headers(o.headers);if(["POST","PUT","PATCH","DELETE"].includes(i)){let l=cr(t);l&&a.set(s,l)}o.body&&typeof o.body=="string"&&!a.has("Content-Type")&&a.set("Content-Type","application/json"),a.has("Accept")||a.set("Accept","application/json");try{let l=await fetch(c,{...o,headers:a});return!l.ok&&r&&await oa(l,{...ia,...n}),l}catch(l){throw r&&ut("error","Network Error","Unable to connect. Check your internet connection."),l}}async function oa(c,e){let t="";try{if((c.headers.get("content-type")??"").includes("application/json")){let o=await c.clone().json();if(t=o.message??"",c.status===422&&o.errors){let i=Object.entries(o.errors).map(([a,l])=>`${a}: ${l.join(", ")}`).slice(0,3).join(`
|
|
160
|
+
`);ut("warning",e[422]??"Validation Error",i);return}}}catch{}let s=t||e[c.status]||`Error ${c.status}`,r=c.status>=500?"error":c.status===429?"warning":"error";if(c.status===401){ut("warning",s,"Please sign in to continue.");return}ut(r,s)}function cr(c="XSRF-TOKEN"){if(typeof document>"u")return null;let e=c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),t=document.cookie.match(new RegExp(`(?:^|;\\s*)${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}function $n(c,e){if(!e)return c;let t=new URL(c,"http://localhost");for(let[s,r]of Object.entries(e))r!=null&&t.searchParams.set(s,String(r));return t.pathname+t.search}var ia,Pn,ar,de,nd,Dn=y(()=>{"use strict";ia={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."},Pn=null;ar=class c{_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 c;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),n={...this._headers},o;s!==void 0&&(n["Content-Type"]||(n["Content-Type"]="application/json"),o=typeof s=="string"?s:JSON.stringify(s)),n.Accept||(n.Accept="application/json");let i=null,a=1+this._retries;for(let l=0;l<a;l++){l>0&&await new Promise(u=>setTimeout(u,this._retryDelay*l));try{let u=new AbortController,d=setTimeout(()=>u.abort(),this._timeout),h=await fetch(r,{method:e,headers:n,body:o,signal:u.signal});if(clearTimeout(d),!h.ok&&h.status<500&&l<a-1,!h.ok&&h.status>=500&&l<a-1){i=new de(`HTTP ${h.status}: ${h.statusText}`,h.status,await h.text());continue}let p=h.headers.get("content-type")??"",f;if(p.includes("application/json")?f=await h.json():f=await h.text(),!h.ok)throw new de(`HTTP ${h.status}: ${typeof f=="string"?f:JSON.stringify(f)}`,h.status,f);return{data:f,status:h.status,headers:h.headers,ok:!0}}catch(u){if(u instanceof de)throw u;if(i=u,u.name==="AbortError"&&(i=new de("Request timed out",0,null)),l>=a-1)break}}throw i??new Error("HTTP request failed")}buildFullUrl(e){let t=this._baseUrl?`${this._baseUrl.replace(/\/+$/,"")}/${e.replace(/^\/+/,"")}`:e,s=Object.entries(this._query);if(s.length>0){let r=new URL(t);for(let[n,o]of s)r.searchParams.set(n,o);t=r.toString()}return t}},de=class extends Error{constructor(t,s,r){super(t);this.status=s;this.body=r;this.name="HttpRequestError"}},nd=new ar});function kn(c){let{paraglideMiddleware:e,getTextDirection:t=()=>"ltr",langPlaceholder:s="%lang%",dirPlaceholder:r="%dir%"}=c;return({event:n,resolve:o})=>e(n.request,({request:i,locale:a})=>(n.request=i,o(n,{transformPageChunk:({html:l})=>l.replace(s,a).replace(r,t(a))})))}function An(c){return e=>c.deLocalizeUrl(e.url).pathname}var Nn=y(()=>{"use strict"});function Mn(c,e,t={}){return async s=>{let{superValidate:r,fail:n,message:o}=await import("sveltekit-superforms"),{zod:i}=await import("sveltekit-superforms/adapters"),a=await r(s,i(c));if(!a.valid)return n(400,{form:a});try{let l=await e(a.data,s);if(t.redirectTo){let{redirect:u}=await import("@sveltejs/kit");throw u(303,t.redirectTo)}return l??{form:a}}catch(l){if(l?.status>=300&&l?.status<400)throw l;return o(a,t.errorMessage||l.message||"An error occurred",{status:l.status||400})}}}async function On(c,e){let{superValidate:t}=await import("sveltekit-superforms"),{zod:s}=await import("sveltekit-superforms/adapters");return t(e??null,s(c))}async function _n(c,e){let t=await c.request.formData(),s={};for(let[n,o]of t.entries())s[n]=o;let r=e.safeParse(s);if(!r.success){let{FormValidationError:n}=await Promise.resolve().then(()=>(Js(),pn));throw new n(r.error.flatten().fieldErrors)}return r.data}var Ln=y(()=>{"use strict"});var In={};C(In,{Application:()=>Fe,AuthManager:()=>Xe,AuthenticateMiddleware:()=>ae,BelongsTo:()=>V,BelongsToMany:()=>Q,Broadcast:()=>Sn,Cache:()=>vn,ColumnBuilder:()=>O,Connection:()=>g,Container:()=>U,Controller:()=>Je,CorsMiddleware:()=>Be,CsrfMiddleware:()=>X,DatabaseSessionStore:()=>ze,ErrorHandler:()=>ce,Event:()=>G,EventDispatcher:()=>Te,FileSessionStore:()=>Ve,ForbiddenError:()=>Se,FormAuthorizationError:()=>ue,FormRequest:()=>Ae,FormValidationError:()=>le,HasMany:()=>z,HasOne:()=>J,Hash:()=>vs,HttpError:()=>D,Job:()=>W,Log:()=>tt,LoggingMiddleware:()=>We,Mailable:()=>$e,Mailer:()=>$s,MemorySessionStore:()=>H,Middleware:()=>S,MiddlewareStack:()=>L,Migration:()=>me,Migrator:()=>ge,Model:()=>Ue,ModelNotFoundError:()=>nt,NotFoundError:()=>xe,Notification:()=>ct,Notifier:()=>xn,OriginMiddleware:()=>Z,QueryBuilder:()=>k,Queue:()=>us,RateLimitMiddleware:()=>Y,RedisSessionStore:()=>Qe,RequireAuthMiddleware:()=>Ze,Schema:()=>_,Seeder:()=>He,ServiceProvider:()=>ve,Session:()=>re,SessionMiddleware:()=>ne,SignatureMiddleware:()=>Ke,Storage:()=>fn,TableBuilder:()=>F,ThrottleMiddleware:()=>ee,UnauthorizedError:()=>Ee,ValidationError:()=>I,abort:()=>it,abortIf:()=>rn,abortUnless:()=>nn,apiFetch:()=>Rn,buildUrl:()=>$n,config:()=>cn,container:()=>Kr,createFormAction:()=>Mn,createI18nHandle:()=>kn,createReroute:()=>An,createSvelarApp:()=>on,createSvelarHooks:()=>Fs,env:()=>an,getCsrfToken:()=>cr,loadForm:()=>On,resource:()=>zr,rules:()=>un,schema:()=>Nr,sequence:()=>Bs,signJwt:()=>ks,validate:()=>dn,validateForm:()=>_n,verifyJwt:()=>As,z:()=>x});var jn=y(()=>{"use strict";Br();ps();ms();w();Gt();Yt();Wr();fs();gs();Jr();te();Vr();Ws();ln();hn();Ns();ie();ys();Hs();qe();Js();yn();js();Tn();ds();Ye();En();Cn();Dn();Nn();Ln();Ws()});var dr={};C(dr,{PluginRegistry:()=>dt});var ur,dt,ht=y(()=>{"use strict";E();ur=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"),n=[],o=e(process.cwd(),"node_modules");if(!t(o))return n;try{let i=s(o,{withFileTypes:!0});for(let a of i){if(!a.isDirectory())continue;let l=a.name;if(l.startsWith("."))continue;let u=l.startsWith("svelar-");if(!u)continue;let d=e(o,l,"package.json");if(t(d))try{let h=await r(d,"utf-8"),p=JSON.parse(h),f=p.keywords?.includes("svelar-plugin");if(!u&&!f)continue;let v={name:p.name||l,version:p.version||"0.0.0",description:p.description||"",packageName:l,installed:!0,enabled:!1,hasConfig:!!p.svelar?.config,hasMigrations:!!p.svelar?.migrations};n.push(v),this.plugins.set(v.name,v)}catch{}}}catch{}return n}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)}},dt=b("svelar.pluginRegistry",()=>new ur)});var qn={};C(qn,{PluginPublisher:()=>mr});var pr,mr,gr=y(()=>{"use strict";E();pr=class{async publish(e,t){let{mkdir:s,copyFile:r}=await import("fs/promises"),{join:n,dirname:o}=await import("path"),{existsSync:i}=await import("fs"),a={configs:[],migrations:[],assets:[]},l=e.publishables?.()||{};for(let[u,d]of Object.entries(l))for(let h of d){if(t?.only&&h.type!==t.only)continue;let p=n(process.cwd(),h.dest),f=o(p);if(!(i(p)&&!t?.force))try{await s(f,{recursive:!0}),await r(h.source,p),h.type==="config"?a.configs.push(p):h.type==="migration"?a.migrations.push(p):h.type==="asset"&&a.assets.push(p)}catch(v){console.warn(`Failed to publish ${h.source} to ${p}:`,v)}}return a}async preview(e){let t={configs:[],migrations:[],assets:[]},s=e.publishables?.()||{};for(let[r,n]of Object.entries(s))for(let o of n){let i=Me("path").join(process.cwd(),o.dest);o.type==="config"?t.configs.push(i):o.type==="migration"?t.migrations.push(i):o.type==="asset"&&t.assets.push(i)}return t}},mr=b("svelar.pluginPublisher",()=>new pr)});var Un={};C(Un,{PluginInstaller:()=>aa});var yr,aa,Hn=y(()=>{"use strict";E();ht();gr();yr=class{async install(e,t){let{spawn:s}=await import("child_process"),{promisify:r}=await import("util"),{join:n}=await import("path"),{readFile:o}=await import("fs/promises"),{existsSync:i}=await import("fs");try{await this.runNpmInstall(e);let a=dt,l=await a.discover(),u;for(let h of l)if(h.packageName===e||h.name===e){u=h;break}if(!u)return{success:!1,pluginName:e,version:"0.0.0",published:null,error:`Plugin not found after installation. Make sure ${e} is a valid Svelar plugin.`};a.enable(u.name);let d=null;if(t?.publish!==!1)try{let h=await this.loadPluginClass(u.packageName);h&&(d=await mr.publish(new h))}catch(h){console.warn("Failed to publish plugin assets:",h)}return{success:!0,pluginName:u.name,version:u.version,published:d}}catch(a){return{success:!1,pluginName:e,version:"0.0.0",published:null,error:a?.message??String(a)}}}async uninstall(e){try{let t=dt,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}=Me("child_process"),n=r("npm",["install",e],{cwd:process.cwd(),stdio:"inherit"});n.on("close",o=>{o===0?t():s(new Error(`npm install exited with code ${o}`))}),n.on("error",s)})}async runNpmUninstall(e){return new Promise((t,s)=>{let{spawn:r}=Me("child_process"),n=r("npm",["uninstall",e],{cwd:process.cwd(),stdio:"inherit"});n.on("close",o=>{o===0?t():s(new Error(`npm uninstall exited with code ${o}`))}),n.on("error",s)})}async loadPluginClass(e){try{let t=await import(e);return t.default||Object.values(t)[0]}catch{return null}}},aa=b("svelar.pluginInstaller",()=>new yr)});var yt=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:n,flags:o}=this.parseArgs(s,r);try{await r.handle(n,o)}catch(i){let a=i instanceof Error?i.message:String(i);console.error(`\x1B[31mError:\x1B[0m ${a}`),i?.stack&&console.error(i.stack),process.exit(1)}}parseArgs(e,t){let s=[],r={};for(let n of t.flags)n.default!==void 0&&(r[n.name]=n.default);for(let n=0;n<e.length;n++){let o=e[n];if(o.startsWith("--")){let i=o.slice(2),a=i.indexOf("=");if(a!==-1){let d=i.slice(0,a);r[d]=i.slice(a+1);continue}let l=i;t.flags.find(d=>d.name===l)?.type==="boolean"?r[l]=!0:n+1<e.length&&!e[n+1].startsWith("-")?r[l]=e[++n]:r[l]=!0}else if(o.startsWith("-")&&o.length===2){let i=o.slice(1),a=t.flags.find(l=>l.alias===i);a&&(a.type==="boolean"?r[a.name]=!0:n+1<e.length&&(r[a.name]=e[++n]))}else s.push(o)}return{args:s,flags:r}}showCommandHelp(e){if(console.log(`
|
|
161
161
|
\x1B[33mDescription:\x1B[0m`),console.log(` ${e.description}
|
|
162
162
|
`),console.log("\x1B[33mUsage:\x1B[0m"),console.log(` svelar ${e.name} [options]
|
|
163
163
|
`),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}`,n=24-s.length-r.length;console.log(` ${s}${r}${" ".repeat(Math.max(1,n))}${t.description}`)}console.log()}}showHelp(){console.log(`
|
|
@@ -171,7 +171,7 @@ id: ${Date.now()}
|
|
|
171
171
|
svelar <command> [arguments] [options]
|
|
172
172
|
|
|
173
173
|
\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(`
|
|
174
|
-
\x1B[32m${t}\x1B[0m`);for(let r of s){let n=30-r.name.length;console.log(` \x1B[36m${r.name}\x1B[0m${" ".repeat(Math.max(1,n))}${r.description}`)}}console.log()}};var
|
|
174
|
+
\x1B[32m${t}\x1B[0m`);for(let r of s){let n=30-r.name.length;console.log(` \x1B[36m${r.name}\x1B[0m${" ".repeat(Math.max(1,n))}${r.description}`)}}console.log()}};import{existsSync as zn}from"fs";import{join as he}from"path";var m=class{arguments=[];flags=[];async bootstrap(){let{join:e}=await import("path"),{existsSync:t,readFileSync:s}=await import("fs"),{Connection:r}=await Promise.resolve().then(()=>(w(),T)),n=process.cwd();try{r.getDriver();return}catch{}let o=e(n,"svelar.database.json");if(t(o))try{let l=s(o,"utf-8"),u=JSON.parse(l);r.configure(u),this.info("Database configured from svelar.database.json");return}catch(l){this.warn(`Failed to parse svelar.database.json: ${String(l?.message??l)}`)}let i=process.env.DB_DRIVER??"sqlite",a=process.env.DB_PATH??"database.db";r.configure({default:i,connections:{[i]:{driver:i,filename:a,host:process.env.DB_HOST,port:process.env.DB_PORT?parseInt(process.env.DB_PORT):void 0,database:process.env.DB_NAME,user:process.env.DB_USER,password:process.env.DB_PASSWORD}}}),this.info(`Using ${i} database${i==="sqlite"?`: ${a}`:""}`)}log(e){console.log(e)}info(e){console.log(`\x1B[34mINFO\x1B[0m ${e}`)}success(e){console.log(`\x1B[32m\u2713\x1B[0m ${e}`)}warn(e){console.log(`\x1B[33mWARN\x1B[0m ${e}`)}error(e){console.error(`\x1B[31mERROR\x1B[0m ${e}`)}table(e,t){let s=e.map((o,i)=>Math.max(o.length,...t.map(a=>(a[i]??"").length))),r=s.map(o=>"\u2500".repeat(o+2)).join("\u253C"),n=o=>o.map((i,a)=>` ${(i??"").padEnd(s[a])} `).join("\u2502");console.log(n(e)),console.log(r);for(let o of t)console.log(n(o))}newLine(){console.log()}isDDD(){return zn(he(process.cwd(),"src","lib","modules"))}sharedDir(e){return this.isDDD()?he(process.cwd(),"src","lib","shared",e):he(process.cwd(),"src","lib",e)}moduleDir(e,t){return this.isDDD()?he(process.cwd(),"src","lib","modules",e):he(process.cwd(),"src","lib",t)}};import{writeFileSync as wt,mkdirSync as vt,existsSync as Vn}from"fs";import{join as Oe}from"path";var Tt=class extends m{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)),n=t.module||this.toSnakeCase(this.pluralize(s));!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${n}" as module. Consider: --module ${n}`);let o=this.moduleDir(n,"models");vt(o,{recursive:!0});let i=Oe(o,`${s}.ts`);if(Vn(i)){this.warn(`Model ${s} already exists at ${i}`);return}let a=`import { Model } from '@beeblock/svelar/orm';
|
|
175
175
|
|
|
176
176
|
export class ${s} extends Model {
|
|
177
177
|
static table = '${r}';
|
|
@@ -188,7 +188,7 @@ export class ${s} extends Model {
|
|
|
188
188
|
// return this.hasMany(Post, 'user_id');
|
|
189
189
|
// }
|
|
190
190
|
}
|
|
191
|
-
`;
|
|
191
|
+
`;wt(i,a);let l=this.isDDD()?`src/lib/modules/${n}`:"src/lib/models";if(this.success(`Model created: ${l}/${s}.ts`),t.migration||t.all){let d=`${new Date().toISOString().replace(/[^0-9]/g,"").slice(0,14)}_create_${r}_table`,h=Oe(process.cwd(),"src","lib","database","migrations");vt(h,{recursive:!0});let p=`import { Migration } from '@beeblock/svelar/database';
|
|
192
192
|
|
|
193
193
|
export default class Create${s}sTable extends Migration {
|
|
194
194
|
async up() {
|
|
@@ -205,9 +205,9 @@ export default class Create${s}sTable extends Migration {
|
|
|
205
205
|
await this.schema.dropTable('${r}');
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
|
-
`;
|
|
208
|
+
`;wt(Oe(h,`${d}.ts`),p),this.success(`Migration created: src/lib/database/migrations/${d}.ts`)}if(t.controller||t.resource||t.all){let u=`${s}Controller`,d=this.moduleDir(n,"controllers");vt(d,{recursive:!0});let h=t.resource||t.all,p=this.isDDD()?`./${s}.js`:`../models/${s}.js`,f=h?this.generateResourceController(s,u,p):this.generateBasicController(s,u,p);wt(Oe(d,`${u}.ts`),f);let v=this.isDDD()?`src/lib/modules/${n}`:"src/lib/controllers";this.success(`Controller created: ${v}/${u}.ts`)}}generateResourceController(e,t,s=`./${e}.js`){return`import { Controller, type RequestEvent } from '@beeblock/svelar/routing';
|
|
209
209
|
import { z } from '@beeblock/svelar/validation';
|
|
210
|
-
import { ${e} } from '
|
|
210
|
+
import { ${e} } from '${s}';
|
|
211
211
|
|
|
212
212
|
export class ${t} extends Controller {
|
|
213
213
|
/** GET /api/${this.toSnakeCase(this.pluralize(e))} */
|
|
@@ -248,8 +248,8 @@ export class ${t} extends Controller {
|
|
|
248
248
|
return this.noContent();
|
|
249
249
|
}
|
|
250
250
|
}
|
|
251
|
-
`}generateBasicController(e,t){return`import { Controller, type RequestEvent } from '@beeblock/svelar/routing';
|
|
252
|
-
import { ${e} } from '
|
|
251
|
+
`}generateBasicController(e,t,s=`./${e}.js`){return`import { Controller, type RequestEvent } from '@beeblock/svelar/routing';
|
|
252
|
+
import { ${e} } from '${s}';
|
|
253
253
|
|
|
254
254
|
export class ${t} extends Controller {
|
|
255
255
|
async index(event: RequestEvent) {
|
|
@@ -257,9 +257,9 @@ export class ${t} extends Controller {
|
|
|
257
257
|
return this.json(items);
|
|
258
258
|
}
|
|
259
259
|
}
|
|
260
|
-
`}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
|
|
260
|
+
`}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 Qn,mkdirSync as Gn}from"fs";import{join as xr}from"path";var xt=class extends m{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=xr(process.cwd(),"src","lib","database","migrations");Gn(r,{recursive:!0});let o=`${new Date().toISOString().replace(/[^0-9]/g,"").slice(0,14)}_${s}`,i=this.toPascalCase(s),a=t.create??this.detectTableName(s,"create"),l=t.table??this.detectTableName(s,"add"),u;a?u=`import { Migration } from '@beeblock/svelar/database';
|
|
261
261
|
|
|
262
|
-
export default class ${
|
|
262
|
+
export default class ${i} extends Migration {
|
|
263
263
|
async up() {
|
|
264
264
|
await this.schema.createTable('${a}', (table) => {
|
|
265
265
|
table.increments('id');
|
|
@@ -274,7 +274,7 @@ export default class ${o} extends Migration {
|
|
|
274
274
|
}
|
|
275
275
|
`:l?u=`import { Migration } from '@beeblock/svelar/database';
|
|
276
276
|
|
|
277
|
-
export default class ${
|
|
277
|
+
export default class ${i} extends Migration {
|
|
278
278
|
async up() {
|
|
279
279
|
await this.schema.addColumn('${l}', (table) => {
|
|
280
280
|
// Add new columns here
|
|
@@ -288,7 +288,7 @@ export default class ${o} extends Migration {
|
|
|
288
288
|
}
|
|
289
289
|
`:u=`import { Migration } from '@beeblock/svelar/database';
|
|
290
290
|
|
|
291
|
-
export default class ${
|
|
291
|
+
export default class ${i} extends Migration {
|
|
292
292
|
async up() {
|
|
293
293
|
// Write your migration here
|
|
294
294
|
}
|
|
@@ -297,9 +297,9 @@ export default class ${o} extends Migration {
|
|
|
297
297
|
// Reverse the migration
|
|
298
298
|
}
|
|
299
299
|
}
|
|
300
|
-
`,
|
|
300
|
+
`,Qn(xr(r,`${o}.ts`),u),this.success(`Migration created: src/lib/database/migrations/${o}.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 Yn,mkdirSync as Xn,existsSync as Zn}from"fs";import{join as ei}from"path";var Et=class extends m{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`,n=r.replace(/Controller$/,""),o=t.module||n.toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${o}" as module. Consider: --module ${o}`);let i=this.moduleDir(o,"controllers");Xn(i,{recursive:!0});let a=ei(i,`${r}.ts`);if(Zn(a)){this.warn(`Controller ${r} already exists.`);return}let l=t.model?this.isDDD()?`./${t.model}.js`:`../models/${t.model}.js`:void 0,u=t.resource?this.generateResourceController(r,t.model,l):this.generateBasicController(r);Yn(a,u);let d=this.isDDD()?`src/lib/modules/${o}`:"src/lib/controllers";this.success(`Controller created: ${d}/${r}.ts`)}generateResourceController(e,t,s){return`import { Controller, type RequestEvent } from '@beeblock/svelar/routing';
|
|
301
301
|
import { z } from '@beeblock/svelar/validation';
|
|
302
|
-
${t?`import { ${t} } from '
|
|
302
|
+
${t&&s?`import { ${t} } from '${s}';
|
|
303
303
|
`:""}
|
|
304
304
|
export class ${e} extends Controller {
|
|
305
305
|
async index(event: RequestEvent) {
|
|
@@ -343,7 +343,7 @@ export class ${e} extends Controller {
|
|
|
343
343
|
return this.json({ message: 'Hello from ${e}' });
|
|
344
344
|
}
|
|
345
345
|
}
|
|
346
|
-
`}};import{writeFileSync as
|
|
346
|
+
`}};import{writeFileSync as ti,mkdirSync as si,existsSync as ri}from"fs";import{join as ni}from"path";var St=class extends m{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");si(r,{recursive:!0});let n=ni(r,`${s}.ts`);if(ri(n)){this.warn(`Middleware ${s} already exists.`);return}let o=`import { Middleware, type MiddlewareContext, type NextFunction } from '@beeblock/svelar/middleware';
|
|
347
347
|
|
|
348
348
|
export class ${s} extends Middleware {
|
|
349
349
|
async handle(ctx: MiddlewareContext, next: NextFunction): Promise<Response | void> {
|
|
@@ -356,7 +356,7 @@ export class ${s} extends Middleware {
|
|
|
356
356
|
return response;
|
|
357
357
|
}
|
|
358
358
|
}
|
|
359
|
-
`;
|
|
359
|
+
`;ti(n,o);let i=this.isDDD()?`src/lib/shared/middleware/${s}.ts`:`src/lib/middleware/${s}.ts`;this.success(`Middleware created: ${i}`)}};import{writeFileSync as ii,mkdirSync as oi,existsSync as ai}from"fs";import{join as ci}from"path";var Ct=class extends m{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");oi(r,{recursive:!0});let n=ci(r,`${s}.ts`);if(ai(n)){this.warn(`Provider ${s} already exists.`);return}let o=`import { ServiceProvider } from '@beeblock/svelar/container';
|
|
360
360
|
import type { Container } from '@beeblock/svelar/container';
|
|
361
361
|
|
|
362
362
|
export class ${s} extends ServiceProvider {
|
|
@@ -377,7 +377,7 @@ export class ${s} extends ServiceProvider {
|
|
|
377
377
|
// Initialization logic here
|
|
378
378
|
}
|
|
379
379
|
}
|
|
380
|
-
`;
|
|
380
|
+
`;ii(n,o);let i=this.isDDD()?`src/lib/shared/providers/${s}.ts`:`src/lib/providers/${s}.ts`;this.success(`Provider created: ${i}`)}};import{writeFileSync as li,mkdirSync as ui,existsSync as di}from"fs";import{join as Er}from"path";var Pt=class extends m{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=Er(process.cwd(),"src","lib","database","seeders");ui(r,{recursive:!0});let n=Er(r,`${s}.ts`);if(di(n)){this.warn(`Seeder ${s} already exists.`);return}let o=`import { Seeder } from '@beeblock/svelar/database';
|
|
381
381
|
|
|
382
382
|
export class ${s} extends Seeder {
|
|
383
383
|
async run(): Promise<void> {
|
|
@@ -386,15 +386,15 @@ export class ${s} extends Seeder {
|
|
|
386
386
|
// await User.create({ name: 'Admin', email: 'admin@example.com' });
|
|
387
387
|
}
|
|
388
388
|
}
|
|
389
|
-
`;
|
|
390
|
-
import { ${
|
|
389
|
+
`;li(n,o),this.success(`Seeder created: src/lib/database/seeders/${s}.ts`)}};import{writeFileSync as hi,mkdirSync as pi,existsSync as mi}from"fs";import{join as gi}from"path";var Rt=class extends m{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`,n=r.replace(/Service$/,""),o=t.module||n.toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${o}" as module. Consider: --module ${o}`);let i=this.moduleDir(o,"services");pi(i,{recursive:!0});let a=gi(i,`${r}.ts`);if(mi(a)){this.warn(`Service ${r} already exists.`);return}let l=t.model?this.isDDD()?`./${t.model}.js`:`../models/${t.model}.js`:void 0,u=t.crud?this.generateCrudService(r,t.model,l):this.generateBasicService(r);hi(a,u);let d=this.isDDD()?`src/lib/modules/${o}`:"src/lib/services";this.success(`Service created: ${d}/${r}.ts`)}generateCrudService(e,t,s){let r=t||"Model",n=s||`./${r}.js`;return`import { CrudService, type ServiceResult } from '@beeblock/svelar/services';
|
|
390
|
+
import { ${r} } from '${n}';
|
|
391
391
|
|
|
392
|
-
export class ${e} extends CrudService<${
|
|
393
|
-
protected model = ${
|
|
392
|
+
export class ${e} extends CrudService<${r}> {
|
|
393
|
+
protected model = ${r};
|
|
394
394
|
|
|
395
395
|
// Override or add custom methods:
|
|
396
|
-
// async findByEmail(email: string): Promise<ServiceResult<${
|
|
397
|
-
// const record = await ${
|
|
396
|
+
// async findByEmail(email: string): Promise<ServiceResult<${r}>> {
|
|
397
|
+
// const record = await ${r}.where('email', email).first();
|
|
398
398
|
// if (!record) return this.fail('Not found');
|
|
399
399
|
// return this.ok(record);
|
|
400
400
|
// }
|
|
@@ -411,8 +411,8 @@ export class ${e} extends Service {
|
|
|
411
411
|
}
|
|
412
412
|
}
|
|
413
413
|
}
|
|
414
|
-
`}};import{writeFileSync as
|
|
415
|
-
import { ${l} } from '
|
|
414
|
+
`}};import{writeFileSync as fi,mkdirSync as yi,existsSync as bi}from"fs";import{join as wi}from"path";var $t=class extends m{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`,n=r.replace(/Repository$/,""),o=t.module||n.toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${o}" as module. Consider: --module ${o}`);let i=this.moduleDir(o,"repositories");yi(i,{recursive:!0});let a=wi(i,`${r}.ts`);if(bi(a)){this.warn(`Repository ${r} already exists.`);return}let l=t.model||this.inferModelName(r),u=this.isDDD()?`./${l}.js`:`../models/${l}.js`,d=`import { Repository } from '@beeblock/svelar/repositories';
|
|
415
|
+
import { ${l} } from '${u}';
|
|
416
416
|
|
|
417
417
|
export class ${r} extends Repository<${l}> {
|
|
418
418
|
model() {
|
|
@@ -428,7 +428,7 @@ export class ${r} extends Repository<${l}> {
|
|
|
428
428
|
// return ${l}.where('active', true).orderBy('name').get();
|
|
429
429
|
// }
|
|
430
430
|
}
|
|
431
|
-
`;
|
|
431
|
+
`;fi(a,d);let h=this.isDDD()?`src/lib/modules/${o}`:"src/lib/repositories";this.success(`Repository created: ${h}/${r}.ts`)}inferModelName(e){return e.replace("Repository","")||"Model"}};import{writeFileSync as vi,mkdirSync as Ti,existsSync as xi}from"fs";import{join as Ei}from"path";var Dt=class extends m{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`,n=r.replace(/Action$/,""),o=t.module||n.toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${o}" as module. Consider: --module ${o}`);let i=this.moduleDir(o,"actions");Ti(i,{recursive:!0});let a=Ei(i,`${r}.ts`);if(xi(a)){this.warn(`Action ${r} already exists.`);return}let l=`import { Action } from '@beeblock/svelar/actions';
|
|
432
432
|
|
|
433
433
|
interface ${r}Input {
|
|
434
434
|
// Define input type
|
|
@@ -444,7 +444,7 @@ export class ${r} extends Action<${r}Input, ${r}Output> {
|
|
|
444
444
|
throw new Error('Not implemented');
|
|
445
445
|
}
|
|
446
446
|
}
|
|
447
|
-
`;
|
|
447
|
+
`;vi(a,l);let u=this.isDDD()?`src/lib/modules/${o}`:"src/lib/actions";this.success(`Action created: ${u}/${r}.ts`)}};import{writeFileSync as Si,mkdirSync as Ci,existsSync as Pi}from"fs";import{join as Ri}from"path";var kt=class extends m{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`,n=r.replace(/Request$/,""),o=t.module||n.toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${o}" as module. Consider: --module ${o}`);let i=this.moduleDir(o,"dtos");Ci(i,{recursive:!0});let a=Ri(i,`${r}.ts`);if(Pi(a)){this.warn(`Request ${r} already exists.`);return}let l=`import { FormRequest } from '@beeblock/svelar/routing';
|
|
448
448
|
import { z } from '@beeblock/svelar/validation';
|
|
449
449
|
|
|
450
450
|
export class ${r} extends FormRequest {
|
|
@@ -473,11 +473,11 @@ export class ${r} extends FormRequest {
|
|
|
473
473
|
return data;
|
|
474
474
|
}
|
|
475
475
|
}
|
|
476
|
-
`;
|
|
476
|
+
`;Si(a,l);let u=this.isDDD()?`src/lib/modules/${o}`:"src/lib/dtos";this.success(`Request created: ${u}/${r}.ts`)}};import{writeFileSync as $i,mkdirSync as Di,existsSync as ki}from"fs";import{join as Ai}from"path";var At=class extends m{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");Di(r,{recursive:!0});let n=Ai(r,`${s}.ts`);if(ki(n)){this.warn(`Plugin ${s} already exists.`);return}let o=s.replace(/([A-Z])/g,"-$1").toLowerCase().replace(/^-/,""),i=`import { Plugin } from '@beeblock/svelar/plugins';
|
|
477
477
|
import type { Container } from '@beeblock/svelar/container';
|
|
478
478
|
|
|
479
479
|
export class ${s} extends Plugin {
|
|
480
|
-
readonly name = '${
|
|
480
|
+
readonly name = '${o}';
|
|
481
481
|
readonly version = '1.0.0';
|
|
482
482
|
description = '${s} for Svelar';
|
|
483
483
|
|
|
@@ -495,7 +495,7 @@ export class ${s} extends Plugin {
|
|
|
495
495
|
// Clean up resources
|
|
496
496
|
}
|
|
497
497
|
}
|
|
498
|
-
|
|
498
|
+
`;$i(n,i);let a=this.isDDD()?`src/lib/shared/plugins/${s}.ts`:`src/lib/plugins/${s}.ts`;this.success(`Plugin created: ${a}`)}};import{writeFileSync as Ni,mkdirSync as Mi,existsSync as Oi}from"fs";import{join as _i}from"path";var Nt=class extends m{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");Mi(r,{recursive:!0});let n=_i(r,`${s}.ts`);if(Oi(n)){this.warn(`Task ${s} already exists.`);return}let o=`import { ScheduledTask } from '@beeblock/svelar/scheduler';
|
|
499
499
|
|
|
500
500
|
export class ${s} extends ScheduledTask {
|
|
501
501
|
name = '${this.toKebabCase(s)}';
|
|
@@ -528,15 +528,18 @@ export class ${s} extends ScheduledTask {
|
|
|
528
528
|
console.error('${s} failed:', error.message);
|
|
529
529
|
}
|
|
530
530
|
}
|
|
531
|
-
`;
|
|
531
|
+
`;Ni(n,o);let i=this.isDDD()?`src/lib/shared/scheduler/${s}.ts`:`src/lib/scheduler/${s}.ts`;this.success(`Scheduled task created: ${i}`)}toKebabCase(e){return e.replace(/([A-Z])/g,"-$1").toLowerCase().replace(/^-/,"")}};import{writeFileSync as Li,mkdirSync as Ii,existsSync as ji}from"fs";import{join as qi}from"path";var Mt=class extends m{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");Ii(r,{recursive:!0});let n=qi(r,`${s}.ts`);if(ji(n)){this.warn(`Job ${s} already exists.`);return}let o=`import { Job } from '@beeblock/svelar/queue';
|
|
532
532
|
|
|
533
533
|
export class ${s} extends Job {
|
|
534
534
|
maxAttempts = 3; // Retry up to 3 times
|
|
535
535
|
retryDelay = 60; // Wait 60 seconds between retries
|
|
536
536
|
queue = 'default'; // Queue name
|
|
537
537
|
|
|
538
|
-
|
|
538
|
+
data: any;
|
|
539
|
+
|
|
540
|
+
constructor(data: any) {
|
|
539
541
|
super();
|
|
542
|
+
this.data = data;
|
|
540
543
|
}
|
|
541
544
|
|
|
542
545
|
async handle(): Promise<void> {
|
|
@@ -552,10 +555,10 @@ export class ${s} extends Job {
|
|
|
552
555
|
console.log('${s} retrying, attempt', attempt);
|
|
553
556
|
}
|
|
554
557
|
}
|
|
555
|
-
`;
|
|
558
|
+
`;Li(n,o);let i=this.isDDD()?`src/lib/shared/jobs/${s}.ts`:`src/lib/jobs/${s}.ts`;this.success(`Job created: ${i}`)}};import{writeFileSync as Ui,mkdirSync as Hi,existsSync as Fi}from"fs";import{join as Bi}from"path";var Ot=class extends m{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`,n=this.sharedDir("commands");Hi(n,{recursive:!0});let o=Bi(n,`${r}.ts`);if(Fi(o)){this.warn(`Command ${r} already exists.`);return}let i=t.command??this.deriveCommandName(r),a=`import { Command } from '@beeblock/svelar/cli';
|
|
556
559
|
|
|
557
560
|
export class ${r} extends Command {
|
|
558
|
-
name = '${
|
|
561
|
+
name = '${i}';
|
|
559
562
|
description = 'TODO: Describe your command';
|
|
560
563
|
arguments = ['name']; // Positional args your command accepts
|
|
561
564
|
flags = [
|
|
@@ -566,7 +569,7 @@ export class ${r} extends Command {
|
|
|
566
569
|
async handle(args: string[], flags: Record<string, any>): Promise<void> {
|
|
567
570
|
const name = args[0];
|
|
568
571
|
|
|
569
|
-
this.info('Running ${
|
|
572
|
+
this.info('Running ${i}...');
|
|
570
573
|
|
|
571
574
|
// Your command logic here
|
|
572
575
|
// Use this.bootstrap() if you need database access
|
|
@@ -575,7 +578,7 @@ export class ${r} extends Command {
|
|
|
575
578
|
this.success('Done!');
|
|
576
579
|
}
|
|
577
580
|
}
|
|
578
|
-
`;
|
|
581
|
+
`;Ui(o,a);let l=this.isDDD()?`src/lib/shared/commands/${r}.ts`:`src/lib/commands/${r}.ts`;this.success(`Command created: ${l}`),this.info(`Command name: ${i}`),this.newLine(),this.info("Your command will be auto-discovered. Run it with:"),this.log(` npx svelar ${i}`)}deriveCommandName(e){return`app:${e.replace(/Command$/,"").replace(/([a-z])([A-Z])/g,"$1-$2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1-$2").toLowerCase()}`}};import{writeFileSync as Wi,mkdirSync as Ki,existsSync as Ji}from"fs";import{join as Sr}from"path";var _t=class extends m{name="make:config";description="Create a new config file";arguments=["name"];flags=[];templates={app:`import { env } from 'svelar/config';
|
|
579
582
|
|
|
580
583
|
export default {
|
|
581
584
|
name: env('APP_NAME', 'Svelar'),
|
|
@@ -784,7 +787,7 @@ export default {
|
|
|
784
787
|
},
|
|
785
788
|
},
|
|
786
789
|
};
|
|
787
|
-
`};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=
|
|
790
|
+
`};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=Sr(process.cwd(),"config");Ki(s,{recursive:!0});let r=t.toLowerCase().replace(/\s+/g,"-"),n=Sr(s,`${r}.ts`);if(Ji(n)){this.warn(`Config file config/${r}.ts already exists.`);return}let o=this.templates[r]??this.blankTemplate(r);Wi(n,o),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';
|
|
788
791
|
|
|
789
792
|
export default {
|
|
790
793
|
// Add your ${e} configuration here
|
|
@@ -793,7 +796,7 @@ export default {
|
|
|
793
796
|
// env<number>('MY_PORT', 3000)
|
|
794
797
|
// env<boolean>('MY_FLAG', false)
|
|
795
798
|
};
|
|
796
|
-
`}};import{writeFileSync as
|
|
799
|
+
`}};import{writeFileSync as zi,mkdirSync as Vi,existsSync as Qi}from"fs";import{join as Gi}from"path";var Lt=class extends m{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`,n=this.sharedDir("channels");Vi(n,{recursive:!0});let o=Gi(n,`${r}.ts`);if(Qi(o)){this.warn(`Channel ${r} already exists.`);return}let i=r.replace(/Channel$/,""),a=i.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),l=i.charAt(0).toLowerCase()+i.slice(1)+"Id",u=t.presence,h=`${u?"presence":"private"}-${a}.{${l}}`,p=u?this.presenceTemplate(r,h,l):this.privateTemplate(r,h,l);zi(o,p);let f=this.isDDD()?"src/lib/shared/channels":"src/lib/channels";this.success(`Channel created: ${f}/${r}.ts`),this.info(`Channel pattern: ${h}`),this.newLine(),this.info("Register it in src/app.ts or a service provider:"),this.log(` import { register${r} } from './${f.replace("src/","")}/${r}.js';`),this.log(` register${r}();`)}privateTemplate(e,t,s){let r=e.replace(/Channel$/,"");return`import { Broadcast } from '@beeblock/svelar/broadcasting';
|
|
797
800
|
|
|
798
801
|
/**
|
|
799
802
|
* ${e}
|
|
@@ -836,7 +839,7 @@ export function register${e}(): void {
|
|
|
836
839
|
};
|
|
837
840
|
});
|
|
838
841
|
}
|
|
839
|
-
`}};import{writeFileSync as
|
|
842
|
+
`}};import{writeFileSync as Yi,mkdirSync as Xi,existsSync as Zi}from"fs";import{join as pe}from"path";var It=class extends m{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",n=t.soketi??!0,o=t.redis??!0,i=t.gotenberg??!0,a=t.rustfs??!0,l=t.meilisearch??!1,u=t.force??!1,d=["postgres","mysql","sqlite"];if(!d.includes(r)){this.error(`Unknown database driver: ${r}. Use one of: ${d.join(", ")}`);return}let h=[{path:pe(s,"Dockerfile"),content:this.dockerfileTemplate(),label:"Dockerfile"},{path:pe(s,"docker-compose.yml"),content:this.composeTemplate(r,n,o,i,a,l),label:"docker-compose.yml"},{path:pe(s,".dockerignore"),content:this.dockerignoreTemplate(),label:".dockerignore"},{path:pe(s,"ecosystem.config.cjs"),content:this.pm2Template(),label:"ecosystem.config.cjs"}],p=0,f=0;for(let v of h){if(Zi(v.path)&&!u){this.warn(`${v.label} already exists (use --force to overwrite)`),f++;continue}Yi(v.path,v.content),this.success(`Created ${v.label}`),p++}if(r!=="sqlite"){let v=pe(s,"docker");Xi(v,{recursive:!0})}this.newLine(),p>0?this.info(`${p} file(s) created${f>0?`, ${f} 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
|
|
840
843
|
# Multi-stage build for a lean production image.
|
|
841
844
|
|
|
842
845
|
# Stage 1: Install dependencies & build
|
|
@@ -889,7 +892,7 @@ HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \\
|
|
|
889
892
|
|
|
890
893
|
# Start with PM2
|
|
891
894
|
CMD ["pm2-runtime", "ecosystem.config.cjs"]
|
|
892
|
-
`}composeTemplate(e,t,s,r,n=!0,
|
|
895
|
+
`}composeTemplate(e,t,s,r,n=!0,o=!1){let i=[];i.push("# \u2500\u2500 Svelar Docker Compose \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),i.push("# Generated by: npx svelar make:docker"),i.push("#"),i.push("# Usage:"),i.push("# docker compose up -d --build # Start all services"),i.push("# docker compose exec app npx svelar migrate # Run migrations"),i.push("# docker compose logs -f app # View app logs"),i.push("# docker compose down # Stop all services"),i.push(""),i.push("services:"),i.push(" app:"),i.push(" build: ."),i.push(" restart: unless-stopped"),i.push(" ports:"),i.push(' - "${APP_PORT:-3000}:3000"'),i.push(" env_file: .env"),i.push(" environment:"),i.push(" - NODE_ENV=production"),e==="postgres"?(i.push(" - DB_HOST=postgres"),i.push(" - DB_PORT=5432")):e==="mysql"&&(i.push(" - DB_HOST=mysql"),i.push(" - DB_PORT=3306")),s&&(i.push(" - REDIS_HOST=redis"),i.push(" - REDIS_PORT=6379"),i.push(" - REDIS_PASSWORD=${REDIS_PASSWORD:-svelarsecret}"),i.push(" - QUEUE_DRIVER=redis")),t&&(i.push(" - PUSHER_HOST=soketi"),i.push(" - PUSHER_PORT=6001")),r&&i.push(" - GOTENBERG_URL=http://gotenberg:3000"),n&&(i.push(" - S3_ENDPOINT=http://rustfs:9000"),i.push(" - S3_ACCESS_KEY=${RUSTFS_ROOT_USER:-svelar}"),i.push(" - S3_SECRET_KEY=${RUSTFS_ROOT_PASSWORD:-svelarsecret}"),i.push(" - S3_BUCKET=${S3_BUCKET:-svelar}"),i.push(" - S3_REGION=us-east-1"),i.push(" - STORAGE_DISK=s3")),o&&(i.push(" - MEILISEARCH_HOST=http://meilisearch:7700"),i.push(" - MEILISEARCH_KEY=${MEILI_MASTER_KEY:-svelar-meili-master-key}"));let a=[];if(e==="postgres"&&a.push("postgres"),e==="mysql"&&a.push("mysql"),s&&a.push("redis"),t&&a.push("soketi"),r&&a.push("gotenberg"),n&&a.push("rustfs"),o&&a.push("meilisearch"),a.length>0){i.push(" depends_on:");for(let l of a)i.push(` ${l}:`),i.push(" condition: service_healthy")}return i.push(" volumes:"),i.push(" - app_storage:/app/storage"),e==="postgres"&&(i.push(""),i.push(" postgres:"),i.push(" image: postgres:16-alpine"),i.push(" restart: unless-stopped"),i.push(" # No ports exposed \u2014 only reachable by app via Docker network"),i.push(" environment:"),i.push(" POSTGRES_DB: ${DB_NAME:-svelar}"),i.push(" POSTGRES_USER: ${DB_USER:-svelar}"),i.push(" POSTGRES_PASSWORD: ${DB_PASSWORD:-secret}"),i.push(" volumes:"),i.push(" - pgdata:/var/lib/postgresql/data"),i.push(" healthcheck:"),i.push(' test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-svelar}"]'),i.push(" interval: 10s"),i.push(" timeout: 5s"),i.push(" retries: 5")),e==="mysql"&&(i.push(""),i.push(" mysql:"),i.push(" image: mysql:8.0"),i.push(" restart: unless-stopped"),i.push(" # No ports exposed \u2014 only reachable by app via Docker network"),i.push(" environment:"),i.push(" MYSQL_DATABASE: ${DB_NAME:-svelar}"),i.push(" MYSQL_USER: ${DB_USER:-svelar}"),i.push(" MYSQL_PASSWORD: ${DB_PASSWORD:-secret}"),i.push(" MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-rootsecret}"),i.push(" volumes:"),i.push(" - mysqldata:/var/lib/mysql"),i.push(" healthcheck:"),i.push(' test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]'),i.push(" interval: 10s"),i.push(" timeout: 5s"),i.push(" retries: 5")),s&&(i.push(""),i.push(" redis:"),i.push(" image: redis:7-alpine"),i.push(" restart: unless-stopped"),i.push(" # No ports exposed \u2014 only reachable by app via Docker network"),i.push(" command: redis-server --requirepass ${REDIS_PASSWORD:-svelarsecret}"),i.push(" volumes:"),i.push(" - redisdata:/data"),i.push(" healthcheck:"),i.push(' test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:-svelarsecret}", "ping"]'),i.push(" interval: 10s"),i.push(" timeout: 5s"),i.push(" retries: 5")),t&&(i.push(""),i.push(" soketi:"),i.push(" image: quay.io/soketi/soketi:1.6-16-debian"),i.push(" restart: unless-stopped"),i.push(" # No ports exposed \u2014 only reachable by app via Docker network"),i.push(" # Expose 6001 to host only if clients connect directly (uncomment below)"),i.push(" # ports:"),i.push(' # - "${SOKETI_PORT:-6001}:6001"'),i.push(" environment:"),i.push(' SOKETI_DEBUG: "${SOKETI_DEBUG:-0}"'),i.push(" SOKETI_DEFAULT_APP_ID: ${PUSHER_APP_ID}"),i.push(" SOKETI_DEFAULT_APP_KEY: ${PUSHER_KEY}"),i.push(" SOKETI_DEFAULT_APP_SECRET: ${PUSHER_SECRET}"),i.push(' SOKETI_DEFAULT_APP_MAX_CONNS: "${SOKETI_MAX_CONNS:-1000}"'),i.push(' SOKETI_DEFAULT_APP_ENABLE_CLIENT_MESSAGES: "true"'),i.push(' SOKETI_DEFAULT_APP_MAX_BACKEND_EVENTS_PER_SEC: "-1"'),i.push(" healthcheck:"),i.push(' test: ["CMD", "wget", "-qO-", "http://localhost:6001"]'),i.push(" interval: 10s"),i.push(" timeout: 5s"),i.push(" retries: 3")),r&&(i.push(""),i.push(" gotenberg:"),i.push(" image: gotenberg/gotenberg:8"),i.push(" restart: unless-stopped"),i.push(" # No ports exposed \u2014 only reachable by app via Docker network"),i.push(" environment:"),i.push(' CHROMIUM_DISABLE_JAVASCRIPT: "false"'),i.push(' CHROMIUM_ALLOW_LIST: "file:///tmp/.*"'),i.push(' API_TIMEOUT: "${GOTENBERG_TIMEOUT:-60s}"'),i.push(' LOG_LEVEL: "${GOTENBERG_LOG_LEVEL:-info}"'),i.push(" healthcheck:"),i.push(' test: ["CMD", "curl", "-f", "http://localhost:3000/health"]'),i.push(" interval: 10s"),i.push(" timeout: 5s"),i.push(" retries: 5")),n&&(i.push(""),i.push(" rustfs:"),i.push(" image: rustfs/rustfs:latest"),i.push(" restart: unless-stopped"),i.push(" ports:"),i.push(' - "${RUSTFS_CONSOLE_PORT:-9001}:9001" # Admin console (protect with firewall)'),i.push(" environment:"),i.push(" RUSTFS_ROOT_USER: ${RUSTFS_ROOT_USER:-svelar}"),i.push(" RUSTFS_ROOT_PASSWORD: ${RUSTFS_ROOT_PASSWORD:-svelarsecret}"),i.push(' command: server /data --console-address ":9001"'),i.push(" volumes:"),i.push(" - rustfs_data:/data"),i.push(" healthcheck:"),i.push(' test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]'),i.push(" interval: 10s"),i.push(" timeout: 5s"),i.push(" retries: 5")),o&&(i.push(""),i.push(" meilisearch:"),i.push(" image: getmeili/meilisearch:v1.13"),i.push(" restart: unless-stopped"),i.push(" # No ports exposed \u2014 only reachable by app via Docker network"),i.push(" # Uncomment below to access the dashboard from the host"),i.push(" # ports:"),i.push(' # - "${MEILI_PORT:-7700}:7700"'),i.push(" environment:"),i.push(" MEILI_MASTER_KEY: ${MEILI_MASTER_KEY:-svelar-meili-master-key}"),i.push(" MEILI_ENV: production"),i.push(" MEILI_DB_PATH: /meili_data"),i.push(' MEILI_NO_ANALYTICS: "true"'),i.push(" volumes:"),i.push(" - meili_data:/meili_data"),i.push(" healthcheck:"),i.push(' test: ["CMD", "wget", "--no-verbose", "--spider", "http://localhost:7700/health"]'),i.push(" interval: 10s"),i.push(" timeout: 5s"),i.push(" retries: 5")),i.push(""),i.push("volumes:"),i.push(" app_storage:"),e==="postgres"&&i.push(" pgdata:"),e==="mysql"&&i.push(" mysqldata:"),s&&i.push(" redisdata:"),n&&i.push(" rustfs_data:"),o&&i.push(" meili_data:"),i.push(""),i.join(`
|
|
893
896
|
`)}dockerignoreTemplate(){return`# Dependencies
|
|
894
897
|
node_modules
|
|
895
898
|
|
|
@@ -1012,7 +1015,7 @@ module.exports = {
|
|
|
1012
1015
|
},
|
|
1013
1016
|
],
|
|
1014
1017
|
};
|
|
1015
|
-
`}};import{writeFileSync as
|
|
1018
|
+
`}};import{writeFileSync as eo,mkdirSync as to,existsSync as Cr}from"fs";import{join as M}from"path";var jt=class extends m{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,n=t.sse??!1,o=t.pusher??!1,i=!n&&!o,a=[];(i||o)&&a.push({path:M(s,"src/routes/api/broadcasting/auth/+server.ts"),content:this.pusherAuthRoute(),label:"src/routes/api/broadcasting/auth/+server.ts",dirs:[M(s,"src/routes/api/broadcasting/auth")]}),(i||n)&&a.push({path:M(s,"src/routes/api/broadcasting/[channel]/+server.ts"),content:this.sseRoute(),label:"src/routes/api/broadcasting/[channel]/+server.ts",dirs:[M(s,"src/routes/api/broadcasting/[channel]")]}),a.push({path:M(s,"src/lib/broadcasting.ts"),content:i||o?this.clientPusher():this.clientSSE(),label:"src/lib/broadcasting.ts",dirs:[M(s,"src/lib")]});let l=M(s,"config/broadcasting.ts");Cr(l)||a.push({path:l,content:this.configTemplate(),label:"config/broadcasting.ts",dirs:[M(s,"config")]});let u=0,d=0;for(let h of a){if(Cr(h.path)&&!r){this.warn(`${h.label} already exists (use --force to overwrite)`),d++;continue}for(let p of h.dirs)to(p,{recursive:!0});eo(h.path,h.content),this.success(`Created ${h.label}`),u++}this.newLine(),u>0?this.info(`${u} file(s) created${d>0?`, ${d} skipped`:""}`):this.info("No files created (all exist already)"),this.newLine(),this.info("Next steps:"),i||o?(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`/**
|
|
1016
1019
|
* Pusher/Soketi Channel Authorization Endpoint
|
|
1017
1020
|
*
|
|
1018
1021
|
* This route authenticates channel subscriptions from pusher-js.
|
|
@@ -1166,7 +1169,7 @@ export default {
|
|
|
1166
1169
|
},
|
|
1167
1170
|
},
|
|
1168
1171
|
};
|
|
1169
|
-
`}};import{writeFileSync as
|
|
1172
|
+
`}};import{writeFileSync as so,mkdirSync as ro,existsSync as no}from"fs";import{join as R}from"path";var qt=class extends m{name="make:dashboard";description="Scaffold admin dashboard routes (health, queue, scheduler, logs)";arguments=[];flags=[{name:"force",alias:"f",description:"Overwrite existing files",type:"boolean"}];async handle(e,t){let s=process.cwd(),r=t.force??!1,n=[{path:R(s,"src/routes/api/admin/health/+server.ts"),content:this.healthServerTemplate(),label:"api/admin/health/+server.ts"},{path:R(s,"src/routes/api/admin/queue/+server.ts"),content:this.queueServerTemplate(),label:"api/admin/queue/+server.ts"},{path:R(s,"src/routes/api/admin/queue/[id]/retry/+server.ts"),content:this.queueRetryServerTemplate(),label:"api/admin/queue/[id]/retry/+server.ts"},{path:R(s,"src/routes/api/admin/queue/[id]/+server.ts"),content:this.queueDeleteServerTemplate(),label:"api/admin/queue/[id]/+server.ts"},{path:R(s,"src/routes/api/admin/scheduler/+server.ts"),content:this.schedulerServerTemplate(),label:"api/admin/scheduler/+server.ts"},{path:R(s,"src/routes/api/admin/scheduler/[name]/run/+server.ts"),content:this.schedulerRunServerTemplate(),label:"api/admin/scheduler/[name]/run/+server.ts"},{path:R(s,"src/routes/api/admin/scheduler/[name]/toggle/+server.ts"),content:this.schedulerToggleServerTemplate(),label:"api/admin/scheduler/[name]/toggle/+server.ts"},{path:R(s,"src/routes/api/admin/logs/+server.ts"),content:this.logsServerTemplate(),label:"api/admin/logs/+server.ts"},{path:R(s,"src/routes/api/admin/logs/tail/+server.ts"),content:this.logsTailServerTemplate(),label:"api/admin/logs/tail/+server.ts"},{path:R(s,"src/routes/api/admin/stats/+server.ts"),content:this.statsServerTemplate(),label:"api/admin/stats/+server.ts"},{path:R(s,"src/routes/admin/dashboard/+page.server.ts"),content:this.dashboardPageServerTemplate(),label:"admin/dashboard/+page.server.ts"},{path:R(s,"src/routes/admin/dashboard/+page.svelte"),content:this.dashboardPageSvelteTemplate(),label:"admin/dashboard/+page.svelte"}],o=0,i=0;for(let a of n){let l=a.path.substring(0,a.path.lastIndexOf("/"));if(ro(l,{recursive:!0}),no(a.path)&&!r){this.warn(`${a.label} already exists (use --force to overwrite)`),i++;continue}so(a.path,a.content),this.success(`Created ${a.label}`),o++}this.newLine(),o>0?this.info(`${o} file(s) created${i>0?`, ${i} skipped`:""}`):this.info("No files created (all exist already)"),this.newLine(),this.info("Setup instructions:"),this.log(" 1. Import dashboard modules in your app:"),this.log(' import { ScheduleMonitor } from "svelar/scheduler/ScheduleMonitor";'),this.log(' import { JobMonitor } from "svelar/queue/JobMonitor";'),this.log(' import { LogViewer } from "svelar/logging/LogViewer";'),this.newLine(),this.log(" 2. Configure auth middleware on admin routes:"),this.log(' - Replace "// TODO: Add admin middleware check" with your auth logic'),this.log(' - Example: if (!event.locals.user?.isAdmin) return error(403, "Forbidden");'),this.newLine(),this.log(" 3. Access the dashboard:"),this.log(" - Navigate to: /admin/dashboard"),this.newLine(),this.log(" 4. API endpoints available at:"),this.log(" - GET /api/admin/health"),this.log(" - GET /api/admin/queue"),this.log(" - GET /api/admin/scheduler"),this.log(" - GET /api/admin/logs"),this.log(" - GET /api/admin/stats"),this.newLine()}healthServerTemplate(){return`import { json } from '@sveltejs/kit';
|
|
1170
1173
|
import type { RequestHandler } from '@sveltejs/kit';
|
|
1171
1174
|
|
|
1172
1175
|
/**
|
|
@@ -1783,16 +1786,16 @@ export const load: PageServerLoad = async ({ fetch }) => {
|
|
|
1783
1786
|
margin-top: 0;
|
|
1784
1787
|
}
|
|
1785
1788
|
</style>
|
|
1786
|
-
`}};import{writeFileSync as
|
|
1787
|
-
import type { ${t} } from '
|
|
1789
|
+
`}};import{writeFileSync as Pr,mkdirSync as io,existsSync as Rr}from"fs";import{join as $r}from"path";var Ut=class extends m{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`,n=t.module||this.deriveModuleName(r);!t.module&&this.isDDD()&&this.warn(`No --module specified, using "${n}". Use --module=<name> to target a specific module.`);let o=this.moduleDir(n,"resources");io(o,{recursive:!0});let i=$r(o,`${r}.ts`);if(Rr(i)){this.warn(`Resource ${r} already exists.`);return}let a=t.model||this.inferModelName(r),l=this.isDDD()?`./${a}.js`:`../models/${a}.js`,u=this.generateResource(r,a,l);Pr(i,u);let d=this.isDDD()?`src/lib/modules/${n}`:"src/lib/resources";if(this.success(`Resource created: ${d}/${r}.ts`),t.collection){let h=r.replace("Resource","CollectionResource"),p=$r(o,`${h}.ts`);if(!Rr(p)){let f=this.isDDD()?`./${a}.js`:`../models/${a}.js`,v=this.generateCollectionResource(h,r,a,f);Pr(p,v);let P=this.isDDD()?`src/lib/modules/${n}`:"src/lib/resources";this.success(`Collection resource created: ${P}/${h}.ts`)}}}generateResource(e,t,s=`./${t}.js`){let r=`${t}Data`;return`import { Resource } from '@beeblock/svelar/routing';
|
|
1790
|
+
import type { ${t} } from '${s}';
|
|
1788
1791
|
|
|
1789
1792
|
// \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
|
|
1790
1793
|
// Define the shape once \u2014 import this type on the frontend.
|
|
1791
1794
|
//
|
|
1792
|
-
// import type { ${
|
|
1795
|
+
// import type { ${r} } from '$lib/modules/.../${e}';
|
|
1793
1796
|
//
|
|
1794
1797
|
|
|
1795
|
-
export interface ${
|
|
1798
|
+
export interface ${r} {
|
|
1796
1799
|
id: number;
|
|
1797
1800
|
// Add your fields here
|
|
1798
1801
|
// name: string;
|
|
@@ -1802,8 +1805,8 @@ export interface ${s} {
|
|
|
1802
1805
|
|
|
1803
1806
|
// \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
|
|
1804
1807
|
|
|
1805
|
-
export class ${e} extends Resource<${t}, ${
|
|
1806
|
-
toJSON(): ${
|
|
1808
|
+
export class ${e} extends Resource<${t}, ${r}> {
|
|
1809
|
+
toJSON(): ${r} {
|
|
1807
1810
|
return {
|
|
1808
1811
|
id: this.data.id,
|
|
1809
1812
|
// Map model fields to the API contract
|
|
@@ -1829,9 +1832,9 @@ export class ${e} extends Resource<${t}, ${s}> {
|
|
|
1829
1832
|
// return { comments_count: this.data.comments_count ?? 0 };
|
|
1830
1833
|
// }
|
|
1831
1834
|
}
|
|
1832
|
-
`}generateCollectionResource(e,t,s){return`import { Resource } from '@beeblock/svelar/routing';
|
|
1835
|
+
`}generateCollectionResource(e,t,s,r=`./${s}.js`){return`import { Resource } from '@beeblock/svelar/routing';
|
|
1833
1836
|
import { ${t} } from './${t}.js';
|
|
1834
|
-
import type { ${s} } from '
|
|
1837
|
+
import type { ${s} } from '${r}';
|
|
1835
1838
|
|
|
1836
1839
|
/**
|
|
1837
1840
|
* ${e}
|
|
@@ -1861,7 +1864,7 @@ export class ${e} {
|
|
|
1861
1864
|
.toObject();
|
|
1862
1865
|
}
|
|
1863
1866
|
}
|
|
1864
|
-
`}deriveModuleName(e){return e.replace(/Resource$/,"").replace(/Collection$/,"").toLowerCase()}inferModelName(e){return e.replace(/Resource$/,"")||"Model"}};import{writeFileSync as
|
|
1867
|
+
`}deriveModuleName(e){return e.replace(/Resource$/,"").replace(/Collection$/,"").toLowerCase()}inferModelName(e){return e.replace(/Resource$/,"")||"Model"}};import{writeFileSync as oo,mkdirSync as ao,existsSync as co}from"fs";import{join as lo}from"path";var Ht=class extends m{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),n=this.toKebab(s)+".schema",o=t.module||s.toLowerCase(),i=this.moduleDir(o,"schemas");ao(i,{recursive:!0});let a=lo(i,`${n}.ts`);if(co(a)){let h=this.isDDD()?`src/lib/modules/${o}`:"src/lib/schemas";this.warn(`Schema already exists: ${h}/${n}.ts`);return}let l=this.generateSchema(r);oo(a,l);let u=this.isDDD()?`src/lib/modules/${o}`:"src/lib/schemas";this.success(`Schema created: ${u}/${n}.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 d=this.isDDD()?`$lib/modules/${o}/${n}`:`$lib/schemas/${n}`;this.info(` Frontend: import type { ${r}Data } from '${d}'`)}generateSchema(e){let t=e.charAt(0).toLowerCase()+e.slice(1),s=this.toKebab(e);return`import { z } from 'zod';
|
|
1865
1868
|
|
|
1866
1869
|
// \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
|
|
1867
1870
|
//
|
|
@@ -1896,8 +1899,8 @@ export const update${e}Schema = create${e}Schema.partial();
|
|
|
1896
1899
|
export type ${e}Data = z.infer<typeof ${t}Schema>;
|
|
1897
1900
|
export type Create${e}Input = z.infer<typeof create${e}Schema>;
|
|
1898
1901
|
export type Update${e}Input = z.infer<typeof update${e}Schema>;
|
|
1899
|
-
`}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
|
|
1900
|
-
import type { ${r} } from '
|
|
1902
|
+
`}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 uo,mkdirSync as ho,existsSync as po}from"fs";import{join as mo}from"path";var Ft=class extends m{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$/,""),n=t.module||this.toSnakeCase(this.pluralize(r)),o=this.moduleDir(n,"observers");ho(o,{recursive:!0});let i=mo(o,`${s}.ts`);if(po(i)){this.warn(`Observer ${s} already exists at ${i}`);return}let a=this.isDDD()?`./${r}.js`:`../models/${r}.js`,l=`import { ModelObserver } from '@beeblock/svelar/orm';
|
|
1903
|
+
import type { ${r} } from '${a}';
|
|
1901
1904
|
|
|
1902
1905
|
export class ${s} extends ModelObserver {
|
|
1903
1906
|
// Fires before a new ${r} is inserted
|
|
@@ -1934,7 +1937,7 @@ export class ${s} extends ModelObserver {
|
|
|
1934
1937
|
// async deleted(${r.toLowerCase()}: ${r}) {
|
|
1935
1938
|
// }
|
|
1936
1939
|
}
|
|
1937
|
-
`;
|
|
1940
|
+
`;uo(i,l);let u=this.isDDD()?`src/lib/modules/${n}`:"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 go,mkdirSync as fo,existsSync as yo}from"fs";import{join as bo}from"path";var Bt=class extends m{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 n=this.moduleDir(r,"events");fo(n,{recursive:!0});let o=bo(n,`${s}.ts`);if(yo(o)){this.warn(`Event ${s} already exists at ${o}`);return}let i=`/**
|
|
1938
1941
|
* ${s} Event
|
|
1939
1942
|
*
|
|
1940
1943
|
* Dispatched when ... (describe when this event fires).
|
|
@@ -1952,25 +1955,25 @@ export class ${s} {
|
|
|
1952
1955
|
// public readonly metadata?: Record<string, any>,
|
|
1953
1956
|
) {}
|
|
1954
1957
|
}
|
|
1955
|
-
`;go(i
|
|
1958
|
+
`;go(o,i);let a=this.isDDD()?`src/lib/modules/${r}`:"src/lib/events";this.success(`Event created: ${a}/${s}.ts`)}};import{writeFileSync as wo,mkdirSync as vo,existsSync as To}from"fs";import{join as xo}from"path";var Wt=class extends m{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 n=this.moduleDir(r,"listeners");vo(n,{recursive:!0});let o=xo(n,`${s}.ts`);if(To(o)){this.warn(`Listener ${s} already exists at ${o}`);return}let i=t.event||"any",a=t.event?this.isDDD()?`./${t.event}.js`:`../events/${t.event}.js`:"",l=t.event?`import type { ${t.event} } from '${a}';
|
|
1956
1959
|
|
|
1957
|
-
`:"",
|
|
1958
|
-
${
|
|
1959
|
-
async handle(event: ${
|
|
1960
|
+
`:"",u=t.event||"any",d=`import { Listener } from '@beeblock/svelar/events';
|
|
1961
|
+
${l}export class ${s} extends Listener<${u}> {
|
|
1962
|
+
async handle(event: ${u}): Promise<void> {
|
|
1960
1963
|
// Handle the event
|
|
1961
1964
|
// e.g. await Mail.to(event.user.email).send(new WelcomeEmail());
|
|
1962
1965
|
}
|
|
1963
1966
|
|
|
1964
1967
|
// Optionally filter which events to handle:
|
|
1965
|
-
// shouldHandle(event: ${
|
|
1968
|
+
// shouldHandle(event: ${u}): boolean {
|
|
1966
1969
|
// return true;
|
|
1967
1970
|
// }
|
|
1968
1971
|
}
|
|
1969
|
-
`;
|
|
1970
|
-
`),l=`import { ${t} } from '${
|
|
1972
|
+
`;wo(o,d);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 Eo,mkdirSync as So,existsSync as Co}from"fs";import{join as Dr}from"path";var Kt=class extends m{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 n=t.controller||this.inferControllerName(r),o=t.module||this.inferModuleName(r);t.resource?this.generateResourceRoutes(r,n,o):this.generateRoute(r,n,o,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 o=(r?r.split(",").map(i=>i.trim().toUpperCase()):["GET"]).map(i=>({method:i,handler:this.defaultHandler(i)}));this.generateRouteFile(e,t,s,o)}generateRouteFile(e,t,s,r){let n=Dr(process.cwd(),"src","routes",...e.split("/"));So(n,{recursive:!0});let o=Dr(n,"+server.ts");if(Co(o)){this.warn(`Route already exists: src/routes/${e}/+server.ts (skipped)`);return}let i=this.isDDD()?`$lib/modules/${s}/${t}.js`:`$lib/controllers/${t}.js`,a=r.map(u=>`export const ${u.method} = ctrl.handle('${u.handler}');`).join(`
|
|
1973
|
+
`),l=`import { ${t} } from '${i}';
|
|
1971
1974
|
|
|
1972
1975
|
const ctrl = new ${t}();
|
|
1973
1976
|
${a}
|
|
1974
|
-
`;
|
|
1975
|
-
`);let i=Math.max(6,...n.map(u=>u.method.length)),o=Math.max(4,...n.map(u=>u.path.length)),a=Math.max(7,...n.map(u=>u.handler.length)),l=` ${"METHOD".padEnd(i)} ${"PATH".padEnd(o)} ${"HANDLER".padEnd(a)} FILE`;this.log(`\x1B[2m${l}\x1B[0m`),this.log(`\x1B[2m ${"\u2500".repeat(i)} ${"\u2500".repeat(o)} ${"\u2500".repeat(a)} ${"\u2500".repeat(20)}\x1B[0m`);for(let u of n){let h=`${this.getMethodColor(u.method)}${u.method.padEnd(i)}\x1B[0m`,g=u.path.padEnd(o),y=`\x1B[2m${u.handler.padEnd(a)}\x1B[0m`,v=`\x1B[2m${u.file}\x1B[0m`;this.log(` ${h} ${g} ${y} ${v}`)}this.log("")}scanRoutes(e,t){let s=[],r=Co(e);for(let n of r){let i=Wr(e,n);if(Po(i).isDirectory()){s.push(...this.scanRoutes(i,t));continue}n==="+server.ts"||n==="+server.js"?s.push(...this.parseServerFile(i,t)):(n==="+page.server.ts"||n==="+page.server.js")&&s.push(...this.parsePageServerFile(i,t))}return s}parseServerFile(e,t){let s=[],r=Kr(e,"utf-8"),n=this.filePathToUrl(e,t),i=Jt(process.cwd(),e).split(zt).join("/"),o=/export\s+(?:const|function)\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\b/g,a;for(;(a=o.exec(r))!==null;){let l=a[1],u=this.extractHandler(r,l);s.push({method:l,path:n,handler:u,file:i})}return s}parsePageServerFile(e,t){let s=[],r=Kr(e,"utf-8"),n=this.filePathToUrl(e,t),i=Jt(process.cwd(),e).split(zt).join("/");/export\s+(const|async\s+function)\s+load\b/.test(r)&&s.push({method:"GET",path:n,handler:"load()",file:i});let o=r.match(/export\s+const\s+actions\s*=\s*\{([^}]+)\}/);if(o){let a=o[1].split(",").map(l=>l.trim().split(":")[0].split("(")[0].trim()).filter(Boolean);for(let l of a)s.push({method:"POST",path:l==="default"?n:`${n}?/${l}`,handler:`actions.${l}()`,file:i})}return s}filePathToUrl(e,t){let s=Jt(t,e).split(zt).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 n=new RegExp(`const\\s*\\{[^}]*${t}[^}]*\\}\\s*=\\s*resource\\(\\s*(\\w+)`),i=e.match(n);return i?`${i[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 Ro}from"fs";import{join as Vr}from"path";import{pathToFileURL as $o}from"url";var Xt=class extends p{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(l=>t[l]);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(()=>(Yt(),zr)),n=new r,i=Vr(process.cwd(),"src","lib","database","migrations"),o=await this.loadMigrations(i);if(t.status){let l=await n.status(o);this.table(["Migration","Status","Batch"],l.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 l=await n.rollback(o);if(l.length===0)this.info("Nothing to rollback.");else for(let u of l)this.success(`Rolled back: ${u}`);return}if(t.reset){this.warnDestructive("reset"),this.info("Resetting all migrations...");let l=await n.reset(o);if(l.length===0)this.info("Nothing to reset.");else for(let u of l)this.success(`Rolled back: ${u}`);return}if(t.refresh){this.warnDestructive("refresh"),this.info("Refreshing migrations...");let l=await n.refresh(o);for(let u of l.reset)this.success(`Rolled back: ${u}`);for(let u of l.migrated)this.success(`Migrated: ${u}`);return}if(t.fresh){this.warnDestructive("fresh"),this.info("Dropping all tables...");let l=await n.fresh(o);if(l.dropped.length>0)for(let u of l.dropped)this.success(`Dropped table: ${u}`);this.newLine(),this.info("Re-running all migrations...");for(let u of l.migrated)this.success(`Migrated: ${u}`);return}this.info("Running migrations...");let a=await n.run(o);if(a.length===0)this.info("Nothing to migrate.");else for(let l of a)this.success(`Migrated: ${l}`)}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=Ro(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 n=Vr(e,r);try{let i=await import($o(n).href),o=i.default??Object.values(i).find(a=>typeof a=="function"&&a.prototype&&typeof a.prototype.up=="function");o?s.push({name:r.replace(/\.(ts|js)$/,""),timestamp:r.split("_")[0],path:n,migration:new o}):this.warn(`No migration class found in: ${r}`)}catch(i){let o;try{o=i instanceof Error?i.message:String(i)}catch{o=JSON.stringify(i)??"Unknown error (non-stringifiable object)"}this.error(`Failed to load migration ${r}: ${o}`)}}return s}};import{join as Zt}from"path";import{pathToFileURL as ko}from"url";import{existsSync as Qr}from"fs";var es=class extends p{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=Zt(process.cwd(),"src","lib","database","seeders"),r=t.class?Zt(s,`${t.class}.ts`):Zt(s,"DatabaseSeeder.ts"),n=r;Qr(n)||(n=n.replace(/\.ts$/,".js")),Qr(n)||(this.error(`Seeder not found: ${r}`),process.exit(1)),this.info("Running seeders...");try{let i=await import(ko(n).href),o=i.default??i.DatabaseSeeder??Object.values(i).find(l=>typeof l=="function"&&l.prototype&&typeof l.prototype.run=="function");(!o||typeof o!="function")&&(this.error("No seeder class found in file."),process.exit(1)),await new o().run(),this.success("Database seeded successfully.")}catch(i){let o=i instanceof Error?i.message:String(i);this.error(`Seeding failed: ${o}`),i?.stack&&console.error(i.stack),process.exit(1)}}};import{readdirSync as Do}from"fs";import{join as en}from"path";import{pathToFileURL as Oo}from"url";var rs=class extends p{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(),Xr)),r=new s;r.persistToDatabase();let n=en(process.cwd(),"src","lib","scheduler"),i=await this.loadTasks(n);if(i.length===0){this.warn("No scheduled tasks found in src/lib/scheduler/");return}for(let l of i)r.register(l),this.info(`Registered task: ${l.name}`);if(this.newLine(),t.once){this.info("Running due tasks (once)...");let l=await r.run();if(l.length===0)this.info("No tasks were due.");else for(let u of l)u.success?this.success(`${u.task}: completed in ${u.duration}ms`):this.error(`${u.task}: failed \u2014 ${u.error}`);return}this.info("Scheduler running. Press Ctrl+C to stop."),this.newLine();let o=async()=>{let l=await r.run();for(let u of l){let d=new Date().toISOString().replace("T"," ").slice(0,19);u.success?this.success(`[${d}] ${u.task}: completed in ${u.duration}ms`):this.error(`[${d}] ${u.task}: failed \u2014 ${u.error}`)}};await o();let a=6e4-Date.now()%6e4;this.info(`Next tick aligned to minute boundary in ${Math.round(a/1e3)}s.`),await new Promise(l=>setTimeout(l,a)),await o(),setInterval(o,6e4),await new Promise(()=>{})}async loadTasks(e){let t;try{t=Do(e).filter(r=>(r.endsWith(".ts")||r.endsWith(".js"))&&!r.startsWith("index")).sort()}catch{return[]}let s=[];for(let r of t){let n=en(e,r);try{let i=await import(Oo(n).href),o=i.default??Object.values(i).find(a=>typeof a=="function"&&a.prototype&&typeof a.prototype.handle=="function");if(o){let a=new o;a.schedule(),s.push(a)}}catch(i){this.error(`Failed to load task ${r}: ${i.message??i}`)}}return s}};var ds=class extends p{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(()=>(us(),tn)),r=t.queue??"default",n=t["max-jobs"]?parseInt(t["max-jobs"]):void 0,i=t["max-time"]?parseInt(t["max-time"]):void 0,o=t.sleep?parseInt(t.sleep):1e3;if(this.info(`Processing queue "${r}"...`),n&&this.info(`Will stop after ${n} jobs.`),i&&this.info(`Will stop after ${i} seconds.`),this.newLine(),t.once){let u=await s.work({queue:r,maxJobs:1,sleep:0});u===0?this.info("No jobs to process."):this.success(`Processed ${u} job(s).`);return}this.info(`Worker running on "${r}". Press Ctrl+C to stop.`),this.newLine();let a=Date.now(),l=0;for(;;){if(i&&(Date.now()-a)/1e3>=i){this.info(`Max time (${i}s) reached. Stopping.`);break}if(n&&l>=n){this.info(`Max jobs (${n}) reached. Stopping.`);break}let u=await s.work({queue:r,maxJobs:1,sleep:0});if(u>0){l+=u;let d=new Date().toISOString().replace("T"," ").slice(0,19);this.success(`[${d}] Processed ${u} job(s) (total: ${l})`)}else await new Promise(d=>setTimeout(d,o))}this.newLine(),this.info(`Worker stopped. Total jobs processed: ${l}`)}};var cr=class extends p{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.
|
|
1976
|
-
`);let t=(await import("repl")).start({prompt:"\x1B[36msvelar>\x1B[0m ",useGlobal:!0});try{let s=await Promise.resolve().then(()=>(
|
|
1977
|
+
`;Eo(o,l),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(o=>!o.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 kr,relative as Jt,sep as zt}from"path";import{existsSync as Po,readdirSync as Ro,readFileSync as Ar,statSync as $o}from"fs";var Vt=class extends m{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=kr(process.cwd(),"src","routes");if(!Po(s)){this.error("No src/routes/ directory found.");return}let n=this.scanRoutes(s,s);if(t.api&&(n=n.filter(u=>u.path.startsWith("/api"))),t.method){let u=t.method.toUpperCase();n=n.filter(d=>d.method===u)}if(n.sort((u,d)=>u.path.localeCompare(d.path)||u.method.localeCompare(d.method)),n.length===0){this.warn("No routes found.");return}if(t.json){this.log(JSON.stringify(n,null,2));return}this.log(""),this.log(` \x1B[1mApplication Routes\x1B[0m (${n.length} routes)
|
|
1978
|
+
`);let o=Math.max(6,...n.map(u=>u.method.length)),i=Math.max(4,...n.map(u=>u.path.length)),a=Math.max(7,...n.map(u=>u.handler.length)),l=` ${"METHOD".padEnd(o)} ${"PATH".padEnd(i)} ${"HANDLER".padEnd(a)} FILE`;this.log(`\x1B[2m${l}\x1B[0m`),this.log(`\x1B[2m ${"\u2500".repeat(o)} ${"\u2500".repeat(i)} ${"\u2500".repeat(a)} ${"\u2500".repeat(20)}\x1B[0m`);for(let u of n){let h=`${this.getMethodColor(u.method)}${u.method.padEnd(o)}\x1B[0m`,p=u.path.padEnd(i),f=`\x1B[2m${u.handler.padEnd(a)}\x1B[0m`,v=`\x1B[2m${u.file}\x1B[0m`;this.log(` ${h} ${p} ${f} ${v}`)}this.log("")}scanRoutes(e,t){let s=[],r=Ro(e);for(let n of r){let o=kr(e,n);if($o(o).isDirectory()){s.push(...this.scanRoutes(o,t));continue}n==="+server.ts"||n==="+server.js"?s.push(...this.parseServerFile(o,t)):(n==="+page.server.ts"||n==="+page.server.js")&&s.push(...this.parsePageServerFile(o,t))}return s}parseServerFile(e,t){let s=[],r=Ar(e,"utf-8"),n=this.filePathToUrl(e,t),o=Jt(process.cwd(),e).split(zt).join("/"),i=/export\s+(?:const|function)\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\b/g,a;for(;(a=i.exec(r))!==null;){let l=a[1],u=this.extractHandler(r,l);s.push({method:l,path:n,handler:u,file:o})}return s}parsePageServerFile(e,t){let s=[],r=Ar(e,"utf-8"),n=this.filePathToUrl(e,t),o=Jt(process.cwd(),e).split(zt).join("/");/export\s+(const|async\s+function)\s+load\b/.test(r)&&s.push({method:"GET",path:n,handler:"load()",file:o});let i=r.match(/export\s+const\s+actions\s*=\s*\{([^}]+)\}/);if(i){let a=i[1].split(",").map(l=>l.trim().split(":")[0].split("(")[0].trim()).filter(Boolean);for(let l of a)s.push({method:"POST",path:l==="default"?n:`${n}?/${l}`,handler:`actions.${l}()`,file:o})}return s}filePathToUrl(e,t){let s=Jt(t,e).split(zt).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 n=new RegExp(`const\\s*\\{[^}]*${t}[^}]*\\}\\s*=\\s*resource\\(\\s*(\\w+)`),o=e.match(n);return o?`${o[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 Do}from"fs";import{join as Or}from"path";import{pathToFileURL as ko}from"url";var Xt=class extends m{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(l=>t[l]);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(()=>(Yt(),Mr)),n=new r,o=Or(process.cwd(),"src","lib","database","migrations"),i=await this.loadMigrations(o);if(t.status){let l=await n.status(i);this.table(["Migration","Status","Batch"],l.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 l=await n.rollback(i);if(l.length===0)this.info("Nothing to rollback.");else for(let u of l)this.success(`Rolled back: ${u}`);return}if(t.reset){this.warnDestructive("reset"),this.info("Resetting all migrations...");let l=await n.reset(i);if(l.length===0)this.info("Nothing to reset.");else for(let u of l)this.success(`Rolled back: ${u}`);return}if(t.refresh){this.warnDestructive("refresh"),this.info("Refreshing migrations...");let l=await n.refresh(i);for(let u of l.reset)this.success(`Rolled back: ${u}`);for(let u of l.migrated)this.success(`Migrated: ${u}`);return}if(t.fresh){this.warnDestructive("fresh"),this.info("Dropping all tables...");let l=await n.fresh(i);if(l.dropped.length>0)for(let u of l.dropped)this.success(`Dropped table: ${u}`);this.newLine(),this.info("Re-running all migrations...");for(let u of l.migrated)this.success(`Migrated: ${u}`);return}this.info("Running migrations...");let a=await n.run(i);if(a.length===0)this.info("Nothing to migrate.");else for(let l of a)this.success(`Migrated: ${l}`)}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=Do(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 n=Or(e,r);try{let o=await import(ko(n).href),i=o.default??Object.values(o).find(a=>typeof a=="function"&&a.prototype&&typeof a.prototype.up=="function");i?s.push({name:r.replace(/\.(ts|js)$/,""),timestamp:r.split("_")[0],path:n,migration:new i}):this.warn(`No migration class found in: ${r}`)}catch(o){let i;try{i=o instanceof Error?o.message:String(o)}catch{i=JSON.stringify(o)??"Unknown error (non-stringifiable object)"}this.error(`Failed to load migration ${r}: ${i}`)}}return s}};import{join as Zt}from"path";import{pathToFileURL as Ao}from"url";import{existsSync as _r}from"fs";var es=class extends m{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=Zt(process.cwd(),"src","lib","database","seeders"),r=t.class?Zt(s,`${t.class}.ts`):Zt(s,"DatabaseSeeder.ts"),n=r;_r(n)||(n=n.replace(/\.ts$/,".js")),_r(n)||(this.error(`Seeder not found: ${r}`),process.exit(1)),this.info("Running seeders...");try{let o=await import(Ao(n).href),i=o.default??o.DatabaseSeeder??Object.values(o).find(l=>typeof l=="function"&&l.prototype&&typeof l.prototype.run=="function");(!i||typeof i!="function")&&(this.error("No seeder class found in file."),process.exit(1)),await new i().run(),this.success("Database seeded successfully.")}catch(o){let i=o instanceof Error?o.message:String(o);this.error(`Seeding failed: ${i}`),o?.stack&&console.error(o.stack),process.exit(1)}}};import{existsSync as _o,readdirSync as Lo}from"fs";import{join as rs}from"path";import{pathToFileURL as Io}from"url";var ns=class extends m{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(()=>(qr(),jr)),r=new s;r.persistToDatabase();let n=rs(process.cwd(),"src","lib","shared","scheduler"),o=rs(process.cwd(),"src","lib","scheduler"),i=_o(n)?n:o,a=await this.loadTasks(i);if(a.length===0){this.warn("No scheduled tasks found in src/lib/shared/scheduler/ or src/lib/scheduler/");return}for(let d of a)r.register(d),this.info(`Registered task: ${d.name}`);if(this.newLine(),t.once){this.info("Running due tasks (once)...");let d=await r.run();if(d.length===0)this.info("No tasks were due.");else for(let h of d)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 l=async()=>{let d=await r.run();for(let h of d){let p=new Date().toISOString().replace("T"," ").slice(0,19);h.success?this.success(`[${p}] ${h.task}: completed in ${h.duration}ms`):this.error(`[${p}] ${h.task}: failed \u2014 ${h.error}`)}};await l();let u=6e4-Date.now()%6e4;this.info(`Next tick aligned to minute boundary in ${Math.round(u/1e3)}s.`),await new Promise(d=>setTimeout(d,u)),await l(),setInterval(l,6e4),await new Promise(()=>{})}async loadTasks(e){let t;try{t=Lo(e).filter(r=>(r.endsWith(".ts")||r.endsWith(".js"))&&!r.startsWith("index")).sort()}catch{return[]}let s=[];for(let r of t){let n=rs(e,r);try{let o=await import(Io(n).href),i=o.default??Object.values(o).find(a=>typeof a=="function"&&a.prototype&&typeof a.prototype.handle=="function");if(i){let a=new i;a.schedule(),s.push(a)}}catch(o){this.error(`Failed to load task ${r}: ${o.message??o}`)}}return s}};var hs=class extends m{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(()=>(ds(),Ur)),r=t.queue??"default",n=t["max-jobs"]?parseInt(t["max-jobs"]):void 0,o=t["max-time"]?parseInt(t["max-time"]):void 0,i=t.sleep?parseInt(t.sleep):1e3;if(this.info(`Processing queue "${r}"...`),n&&this.info(`Will stop after ${n} jobs.`),o&&this.info(`Will stop after ${o} seconds.`),this.newLine(),t.once){let u=await s.work({queue:r,maxJobs:1,sleep:0});u===0?this.info("No jobs to process."):this.success(`Processed ${u} job(s).`);return}this.info(`Worker running on "${r}". Press Ctrl+C to stop.`),this.newLine();let a=Date.now(),l=0;for(;;){if(o&&(Date.now()-a)/1e3>=o){this.info(`Max time (${o}s) reached. Stopping.`);break}if(n&&l>=n){this.info(`Max jobs (${n}) reached. Stopping.`);break}let u=await s.work({queue:r,maxJobs:1,sleep:0});if(u>0){l+=u;let d=new Date().toISOString().replace("T"," ").slice(0,19);this.success(`[${d}] Processed ${u} job(s) (total: ${l})`)}else await new Promise(d=>setTimeout(d,i))}this.newLine(),this.info(`Worker stopped. Total jobs processed: ${l}`)}};var lr=class extends m{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.
|
|
1979
|
+
`);let t=(await import("repl")).start({prompt:"\x1B[36msvelar>\x1B[0m ",useGlobal:!0});try{let s=await Promise.resolve().then(()=>(jn(),In));for(let[r,n]of Object.entries(s))t.context[r]=n;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:n}=await import("url"),{existsSync:o}=await import("fs"),i=r(process.cwd(),"src","lib","models"),a=r(process.cwd(),"src","lib","modules"),l=[],u=i;if(o(i))u=i,l=s(i).filter(d=>(d.endsWith(".ts")||d.endsWith(".js"))&&!d.startsWith("index"));else if(o(a)){u=a;for(let d of s(a,{withFileTypes:!0})){if(!d.isDirectory())continue;let h=r(a,d.name);for(let p of s(h))(p.endsWith(".ts")||p.endsWith(".js"))&&(p.startsWith("index")||p.includes("Controller")||p.includes("Service")||p.includes("Repository")||p.includes("Request")||p.includes("Resource")||p.includes("schema")||p.includes("gates")||l.push(r(d.name,p)))}}for(let d of l)try{let h=await import(n(r(u,d)).href);for(let[p,f]of Object.entries(h))typeof f=="function"&&(t.context[p]=f)}catch{}l.length>0&&this.log(`Loaded models: ${l.map(d=>d.replace(/\.(ts|js)$/,"")).join(", ")}`)}catch{}await new Promise(s=>{t.on("exit",s)})}};var hr=class extends m{name="plugin:list";description="List all discovered and enabled plugins";arguments=[];flags=[];async handle(e,t){try{let{PluginRegistry:s}=await Promise.resolve().then(()=>(ht(),dr)),r=s;await r.discover();let n=r.list();if(n.length===0){this.info("No plugins discovered.");return}let o=["Name","Version","Description","Status","Config","Migrations"],i=n.map(a=>[a.name,a.version,a.description||"-",a.enabled?"\u2713 Enabled":" Disabled",a.hasConfig?"\u2713":"-",a.hasMigrations?"\u2713":"-"]);this.newLine(),this.table(o,i),this.newLine(),this.info(`Total: ${n.length} plugin(s)`)}catch(s){this.error(`Failed to list plugins: ${s?.message??String(s)}`)}}};var fr=class extends m{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(()=>(ht(),dr)),{PluginPublisher:n}=await Promise.resolve().then(()=>(gr(),qn)),o=r,i=n;await o.discover();let a=o.get(s);if(!a){this.error(`Plugin "${s}" not found.`);return}let l=await this.loadPluginClass(a.packageName);if(!l){this.error(`Failed to load plugin class for "${s}".`);return}let u=new l,d={force:t.force||!1,only:t.only};this.info(`Publishing plugin: ${s}`);let h=await i.publish(u,d);this.newLine(),h.configs.length>0&&(this.success(`${h.configs.length} config file(s) published:`),h.configs.forEach(p=>this.log(` - ${p}`))),h.migrations.length>0&&(this.success(`${h.migrations.length} migration file(s) published:`),h.migrations.forEach(p=>this.log(` - ${p}`))),h.assets.length>0&&(this.success(`${h.assets.length} asset file(s) published:`),h.assets.forEach(p=>this.log(` - ${p}`))),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 br=class extends m{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(()=>(Hn(),Un)),n=r;this.info(`Installing plugin package: ${s}`),this.newLine();let o=await n.install(s,{publish:!t["no-publish"]});this.newLine(),o.success?(this.success(`Plugin installed: ${o.pluginName} (v${o.version})`),o.published&&(o.published.configs.length>0&&this.info(`${o.published.configs.length} config file(s) published`),o.published.migrations.length>0&&this.info(`${o.published.migrations.length} migration file(s) published`),o.published.assets.length>0&&this.info(`${o.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: ${o.error}`),this.newLine()}catch(r){this.error(`Installation error: ${r?.message??String(r)}`)}}};export{yt as Cli,m as Command,Dt as MakeActionCommand,jt as MakeBroadcastingCommand,Lt as MakeChannelCommand,Ot as MakeCommandCommand,_t as MakeConfigCommand,Et as MakeControllerCommand,qt as MakeDashboardCommand,It as MakeDockerCommand,Bt as MakeEventCommand,Mt as MakeJobCommand,Wt as MakeListenerCommand,St as MakeMiddlewareCommand,xt as MakeMigrationCommand,Tt as MakeModelCommand,Ft as MakeObserverCommand,At as MakePluginCommand,Ct as MakeProviderCommand,$t as MakeRepositoryCommand,kt as MakeRequestCommand,Ut as MakeResourceCommand,Kt as MakeRouteCommand,Ht as MakeSchemaCommand,Pt as MakeSeederCommand,Rt as MakeServiceCommand,Nt as MakeTaskCommand,Xt as MigrateCommand,br as PluginInstallCommand,hr as PluginListCommand,fr as PluginPublishCommand,hs as QueueWorkCommand,Vt as RoutesListCommand,ns as ScheduleRunCommand,es as SeedCommand,lr as TinkerCommand};
|