@beeblock/svelar 0.4.3 → 0.4.5
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 +838 -210
- package/dist/cli/commands/MakeEventCommand.d.ts +6 -2
- package/dist/cli/commands/MakeListenerCommand.d.ts +7 -2
- package/dist/cli/commands/NewCommand.d.ts +9 -2
- package/dist/cli/commands/NewCommandTemplates.d.ts +15 -0
- package/dist/cli/index.js +81 -78
- 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/bin.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
2
|
+
var nn=Object.defineProperty;var ze=(o=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(o,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):o)(function(o){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+o+'" is not supported')});var y=(o,e)=>()=>(o&&(e=o(o=0)),e);var k=(o,e)=>{for(var t in e)nn(o,t,{get:e[t],enumerable:!0})};function C(o,e){let t=Symbol.for(o),s=globalThis;return s[t]||(s[t]=e()),s[t]}var R=y(()=>{"use strict"});var P={};k(P,{Connection:()=>f});var ms,f,x=y(()=>{"use strict";R();ms=class{connections=new Map;config=null;defaultName="default";configure(e){this.config=e,this.defaultName=e.default}async connection(e){let t=e??this.defaultName;if(this.connections.has(t))return this.connections.get(t).drizzle;if(!this.config)throw new Error("Database not configured. Call Connection.configure() first, or register DatabaseServiceProvider.");let s=this.config.connections[t];if(!s)throw new Error(`Database connection "${t}" is not defined in configuration.`);let r=await this.createConnection(s);return this.connections.set(t,r),r.drizzle}async rawClient(e){let t=e??this.defaultName;return await this.connection(t),this.connections.get(t).rawClient}async raw(e,t=[],s){let r=await this.connection(s),i=this.getConfig(s);switch(i.driver){case"sqlite":{let n=await this.rawClient(s),a=t.map(u=>typeof u=="boolean"?u?1:0:u instanceof Date?u.toISOString():u),l=n.prepare(e),c=e.trimStart().toUpperCase();return c.startsWith("SELECT")||c.startsWith("PRAGMA")||c.startsWith("WITH")?l.all(...a):l.run(...a)}case"postgres":return(await this.rawClient(s))(e,...t);case"mysql":{let n=await this.rawClient(s),[a]=await n.execute(e,t);return a}default:throw new Error(`Unsupported driver: ${i.driver}`)}}getDriver(e){return this.getConfig(e).driver}getConfig(e){let t=e??this.defaultName;if(!this.config)throw new Error("Database not configured.");let s=this.config.connections[t];if(!s)throw new Error(`Database connection "${t}" is not defined.`);return s}async disconnect(e){if(e){let t=this.connections.get(e);t&&(await this.closeConnection(t),this.connections.delete(e))}else{for(let[t,s]of this.connections)await this.closeConnection(s);this.connections.clear()}}isConnected(e){return this.connections.has(e??this.defaultName)}async transaction(e,t){let s=this.getConfig(t),r=await this.rawClient(t);switch(s.driver){case"sqlite":{r.exec("BEGIN");try{let i=await e();return r.exec("COMMIT"),i}catch(i){throw r.exec("ROLLBACK"),i}}case"postgres":{await r`BEGIN`;try{let i=await e();return await r`COMMIT`,i}catch(i){throw await r`ROLLBACK`,i}}case"mysql":{let i=await r.getConnection();await i.beginTransaction();try{let n=await e();return await i.commit(),i.release(),n}catch(n){throw await i.rollback(),i.release(),n}}default:throw new Error(`Unsupported driver: ${s.driver}`)}}async createConnection(e){switch(e.driver){case"sqlite":return this.createSQLiteConnection(e);case"postgres":return this.createPostgresConnection(e);case"mysql":return this.createMySQLConnection(e);default:throw new Error(`Unsupported database driver: ${e.driver}`)}}async createSQLiteConnection(e){let t=e.filename??e.database??":memory:";try{let s=(await import("better-sqlite3")).default,{drizzle:r}=await import("drizzle-orm/better-sqlite3"),i=new s(t);return i.pragma("journal_mode = WAL"),i.pragma("foreign_keys = ON"),{drizzle:r(i),config:e,rawClient:i}}catch(s){let r;try{r=(await new Function("mod","return import(mod)")("node:sqlite")).DatabaseSync}catch{throw new Error(`No SQLite driver available. Install better-sqlite3 (npm install better-sqlite3) or use Node.js v22+ which includes built-in SQLite support. Original error: ${s instanceof Error?s.message:String(s)}`)}let i=new r(t);i.exec("PRAGMA journal_mode = WAL"),i.exec("PRAGMA foreign_keys = ON");let n={prepare(l){let c=i.prepare(l);return{all(...u){return c.all(...u)},run(...u){return c.run(...u)},get(...u){return c.get(...u)}}},exec(l){i.exec(l)},pragma(l){return i.prepare(`PRAGMA ${l}`).all()},close(){i.close()}},a;try{let{drizzle:l}=await import("drizzle-orm/better-sqlite3");a=l(n)}catch{a=n}return{drizzle:a,config:e,rawClient:n}}}async createPostgresConnection(e){let t=(await import("postgres")).default,{drizzle:s}=await import("drizzle-orm/postgres-js"),r=e.url??`postgres://${e.user}:${e.password}@${e.host??"localhost"}:${e.port??5432}/${e.database}`,i=t(r);return{drizzle:s(i),config:e,rawClient:i}}async createMySQLConnection(e){let t=await import("mysql2/promise"),{drizzle:s}=await import("drizzle-orm/mysql2"),r=t.createPool({host:e.host??"localhost",port:e.port??3306,database:e.database,user:e.user,password:e.password,uri:e.url});return{drizzle:s(r),config:e,rawClient:r}}async closeConnection(e){try{switch(e.config.driver){case"sqlite":e.rawClient.close();break;case"postgres":await e.rawClient.end();break;case"mysql":await e.rawClient.end();break}}catch{}}},f=C("svelar.connection",()=>new ms)});var I,bs,K,j,Kr,ys=y(()=>{"use strict";x();R();I=class{constructor(e){this.column=e}nullable(){return this.column.nullable=!0,this}notNullable(){return this.column.nullable=!1,this}default(e){return this.column.defaultValue=e,this}primary(){return this.column.primaryKey=!0,this}unique(){return this.column.unique=!0,this}unsigned(){return this.column.unsigned=!0,this}references(e,t){return this.column.references={table:t,column:e},new bs(this.column)}build(){return this.column}},bs=class{constructor(e){this.column=e}onDelete(e){return this.column.references.onDelete=e,this}onUpdate(e){return this.column.references.onUpdate=e,this}},K=class{columns=[];indices=[];compositePrimary=null;addColumn(e,t){let s={name:e,type:t,nullable:!1,primaryKey:!1,autoIncrement:!1,unique:!1,unsigned:!1};return this.columns.push(s),new I(s)}increments(e="id"){let t={name:e,type:"INTEGER",nullable:!1,primaryKey:!0,autoIncrement:!0,unique:!1,unsigned:!0};return this.columns.push(t),new I(t)}bigIncrements(e="id"){let t={name:e,type:"BIGINT",nullable:!1,primaryKey:!0,autoIncrement:!0,unique:!1,unsigned:!0};return this.columns.push(t),new I(t)}string(e,t=255){return this.addColumn(e,`VARCHAR(${t})`)}text(e){return this.addColumn(e,"TEXT")}integer(e){return this.addColumn(e,"INTEGER")}bigInteger(e){return this.addColumn(e,"BIGINT")}float(e){return this.addColumn(e,"FLOAT")}decimal(e,t=8,s=2){return this.addColumn(e,`DECIMAL(${t},${s})`)}boolean(e){return this.addColumn(e,"BOOLEAN")}date(e){return this.addColumn(e,"DATE")}datetime(e){return this.addColumn(e,"DATETIME")}timestamp(e){return this.addColumn(e,"TIMESTAMP")}timestamps(){this.timestamp("created_at").nullable(),this.timestamp("updated_at").nullable()}json(e){return this.addColumn(e,"JSON")}blob(e){return this.addColumn(e,"BLOB")}enum(e,t){return this.addColumn(e,`ENUM(${t.map(s=>`'${s}'`).join(",")})`)}uuid(e="id"){return this.addColumn(e,"UUID")}ulid(e="id"){return this.addColumn(e,"ULID")}jsonb(e){return this.addColumn(e,"JSONB")}primary(e){this.compositePrimary=e}index(e,t){let s=Array.isArray(e)?e:[e];this.indices.push({columns:s,unique:!1,name:t})}uniqueIndex(e,t){let s=Array.isArray(e)?e:[e];this.indices.push({columns:s,unique:!0,name:t})}foreign(e){let t=this.columns.find(s=>s.name===e);if(!t)throw new Error(`Column "${e}" must be defined before adding a foreign key.`);return new I(t)}toSQL(e,t){let s=[],r=[];for(let i of this.columns)r.push(this.columnToSQL(i,t));this.compositePrimary&&r.push(`PRIMARY KEY (${this.compositePrimary.join(", ")})`);for(let i of this.columns)if(i.references){let n=`FOREIGN KEY (${i.name}) REFERENCES ${i.references.table}(${i.references.column})`;i.references.onDelete&&(n+=` ON DELETE ${i.references.onDelete}`),i.references.onUpdate&&(n+=` ON UPDATE ${i.references.onUpdate}`),r.push(n)}s.push(`CREATE TABLE ${e} (
|
|
3
3
|
${r.join(`,
|
|
4
4
|
`)}
|
|
5
|
-
)`);for(let i of this.indices){let n=i.name??`idx_${e}_${i.columns.join("_")}`,a=i.unique?"UNIQUE ":"";s.push(`CREATE ${a}INDEX ${n} ON ${e} (${i.columns.join(", ")})`)}return s}columnToSQL(e,t){let s=e.name,r=e.type;if(t==="sqlite"?r=this.mapSQLiteType(r,e):t==="postgres"?r=this.mapPostgresType(r,e):t==="mysql"&&(r=this.mapMySQLType(r,e)),s+=` ${r}`,e.primaryKey&&!this.compositePrimary&&(s+=" PRIMARY KEY",e.autoIncrement&&(t==="sqlite"?s+=" AUTOINCREMENT":t==="postgres"||t==="mysql"&&(s+=" AUTO_INCREMENT"))),!e.nullable&&!e.primaryKey&&(s+=" NOT NULL"),e.unique&&!e.primaryKey&&(s+=" UNIQUE"),e.defaultValue!==void 0){let i=typeof e.defaultValue=="string"?`'${e.defaultValue}'`:e.defaultValue===null?"NULL":e.defaultValue;s+=` DEFAULT ${i}`}return s}mapSQLiteType(e,t){return e==="BOOLEAN"?"INTEGER":e==="UUID"||e==="ULID"||e.startsWith("ENUM")||e==="JSON"||e==="JSONB"?"TEXT":e==="BIGINT"&&t.autoIncrement?"INTEGER":e}mapPostgresType(e,t){return t.autoIncrement&&e==="INTEGER"?"SERIAL":t.autoIncrement&&e==="BIGINT"?"BIGSERIAL":e==="DATETIME"?"TIMESTAMP":e==="BLOB"?"BYTEA":e.startsWith("ENUM")?"TEXT":e==="UUID"?"UUID":e==="ULID"?"VARCHAR(26)":e==="JSON"||e==="JSONB"?"JSONB":e}mapMySQLType(e,t){return e==="BOOLEAN"?"TINYINT(1)":e==="UUID"?"CHAR(36)":e==="ULID"?"CHAR(26)":e==="JSONB"?"JSON":e==="TIMESTAMP"?"DATETIME":t.unsigned&&!e.startsWith("DECIMAL")?`${e} UNSIGNED`:e}},
|
|
5
|
+
)`);for(let i of this.indices){let n=i.name??`idx_${e}_${i.columns.join("_")}`,a=i.unique?"UNIQUE ":"";s.push(`CREATE ${a}INDEX ${n} ON ${e} (${i.columns.join(", ")})`)}return s}columnToSQL(e,t){let s=e.name,r=e.type;if(t==="sqlite"?r=this.mapSQLiteType(r,e):t==="postgres"?r=this.mapPostgresType(r,e):t==="mysql"&&(r=this.mapMySQLType(r,e)),s+=` ${r}`,e.primaryKey&&!this.compositePrimary&&(s+=" PRIMARY KEY",e.autoIncrement&&(t==="sqlite"?s+=" AUTOINCREMENT":t==="postgres"||t==="mysql"&&(s+=" AUTO_INCREMENT"))),!e.nullable&&!e.primaryKey&&(s+=" NOT NULL"),e.unique&&!e.primaryKey&&(s+=" UNIQUE"),e.defaultValue!==void 0){let i=typeof e.defaultValue=="string"?`'${e.defaultValue}'`:e.defaultValue===null?"NULL":e.defaultValue;s+=` DEFAULT ${i}`}return s}mapSQLiteType(e,t){return e==="BOOLEAN"?"INTEGER":e==="UUID"||e==="ULID"||e.startsWith("ENUM")||e==="JSON"||e==="JSONB"?"TEXT":e==="BIGINT"&&t.autoIncrement?"INTEGER":e}mapPostgresType(e,t){return t.autoIncrement&&e==="INTEGER"?"SERIAL":t.autoIncrement&&e==="BIGINT"?"BIGSERIAL":e==="DATETIME"?"TIMESTAMP":e==="BLOB"?"BYTEA":e.startsWith("ENUM")?"TEXT":e==="UUID"?"UUID":e==="ULID"?"VARCHAR(26)":e==="JSON"||e==="JSONB"?"JSONB":e}mapMySQLType(e,t){return e==="BOOLEAN"?"TINYINT(1)":e==="UUID"?"CHAR(36)":e==="ULID"?"CHAR(26)":e==="JSONB"?"JSON":e==="TIMESTAMP"?"DATETIME":t.unsigned&&!e.startsWith("DECIMAL")?`${e} UNSIGNED`:e}},j=class{constructor(e){this.connectionName=e}async createTable(e,t){let s=new K;t(s);let r=f.getDriver(this.connectionName),i=s.toSQL(e,r);for(let n of i)await f.raw(n,[],this.connectionName)}async dropTable(e){await f.raw(`DROP TABLE IF EXISTS ${e}`,[],this.connectionName)}async dropTableIfExists(e){await f.raw(`DROP TABLE IF EXISTS ${e}`,[],this.connectionName)}async renameTable(e,t){f.getDriver(this.connectionName)==="mysql"?await f.raw(`RENAME TABLE ${e} TO ${t}`,[],this.connectionName):await f.raw(`ALTER TABLE ${e} RENAME TO ${t}`,[],this.connectionName)}async hasTable(e){let t=f.getDriver(this.connectionName),s;switch(t){case"sqlite":s=await f.raw("SELECT name FROM sqlite_master WHERE type='table' AND name=?",[e],this.connectionName);break;case"postgres":s=await f.raw("SELECT tablename FROM pg_tables WHERE tablename = $1",[e],this.connectionName);break;case"mysql":s=await f.raw("SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_NAME = ?",[e],this.connectionName);break;default:throw new Error(`Unsupported driver: ${t}`)}return s.length>0}async addColumn(e,t){let s=new K;t(s);let r=f.getDriver(this.connectionName),i=s.columns;for(let n of i){let a=s.columnToSQL(n,r);await f.raw(`ALTER TABLE ${e} ADD COLUMN ${a}`,[],this.connectionName)}}async dropColumn(e,t){await f.raw(`ALTER TABLE ${e} DROP COLUMN ${t}`,[],this.connectionName)}},Kr=C("svelar.schema",()=>new j)});var Wr={};k(Wr,{Migration:()=>we,Migrator:()=>Ce});var we,Ce,vs=y(()=>{"use strict";x();ys();we=class{schema=new j},Ce=class{migrationsTable="svelar_migrations";connectionName;constructor(e){this.connectionName=e}async ensureMigrationsTable(){let e=new j(this.connectionName);await e.hasTable(this.migrationsTable)||await e.createTable(this.migrationsTable,s=>{s.increments("id"),s.string("migration").unique(),s.integer("batch"),s.timestamp("ran_at").default("CURRENT_TIMESTAMP")})}async run(e){await this.ensureMigrationsTable();let t=await this.getRanMigrations(),s=e.filter(n=>!t.includes(n.name));if(s.length===0)return[];let r=await this.getNextBatch(),i=[];for(let n of s)await n.migration.up(),await f.raw(`INSERT INTO ${this.migrationsTable} (migration, batch) VALUES (?, ?)`,[n.name,r],this.connectionName),i.push(n.name);return i}async rollback(e){await this.ensureMigrationsTable();let t=await this.getLastBatch();if(t===0)return[];let s=await f.raw(`SELECT migration FROM ${this.migrationsTable} WHERE batch = ? ORDER BY id DESC`,[t],this.connectionName),r=[];for(let i of s){let n=i.migration,a=e.find(l=>l.name===n);a&&(await a.migration.down(),await f.raw(`DELETE FROM ${this.migrationsTable} WHERE migration = ?`,[n],this.connectionName),r.push(n))}return r}async reset(e){let t=[];for(;;){let s=await this.rollback(e);if(s.length===0)break;t.push(...s)}return t}async refresh(e){let t=await this.reset(e),s=await this.run(e);return{reset:t,migrated:s}}async fresh(e){let t=await this.dropAllTables(),s=await this.run(e);return{dropped:t,migrated:s}}async dropAllTables(){let e=f.getDriver(this.connectionName),t=[];switch(e){case"sqlite":{t=(await f.raw("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'",[],this.connectionName)).map(r=>r.name),await f.raw("PRAGMA foreign_keys = OFF",[],this.connectionName);for(let r of t)await f.raw(`DROP TABLE IF EXISTS "${r}"`,[],this.connectionName);await f.raw("PRAGMA foreign_keys = ON",[],this.connectionName);break}case"mysql":{t=(await f.raw("SHOW TABLES",[],this.connectionName)).map(r=>Object.values(r)[0]),await f.raw("SET FOREIGN_KEY_CHECKS = 0",[],this.connectionName);for(let r of t)await f.raw(`DROP TABLE IF EXISTS \`${r}\``,[],this.connectionName);await f.raw("SET FOREIGN_KEY_CHECKS = 1",[],this.connectionName);break}case"postgres":{t=(await f.raw("SELECT tablename FROM pg_tables WHERE schemaname = 'public'",[],this.connectionName)).map(r=>r.tablename);for(let r of t)await f.raw(`DROP TABLE IF EXISTS "${r}" CASCADE`,[],this.connectionName);break}default:throw new Error(`Unsupported driver for fresh: ${e}`)}return t}async getRanMigrations(){try{return(await f.raw(`SELECT migration FROM ${this.migrationsTable} ORDER BY batch, id`,[],this.connectionName)).map(t=>t.migration)}catch{return[]}}async status(e){let t=await this.getRanMigrations(),s=new Map;try{let r=await f.raw(`SELECT migration, batch FROM ${this.migrationsTable}`,[],this.connectionName);for(let i of r)s.set(i.migration,i.batch)}catch{}return e.map(r=>({name:r.name,ran:t.includes(r.name),batch:s.get(r.name)??null}))}async getNextBatch(){return await this.getLastBatch()+1}async getLastBatch(){try{return(await f.raw(`SELECT MAX(batch) as max_batch FROM ${this.migrationsTable}`,[],this.connectionName))[0]?.max_batch??0}catch{return 0}}}});var wt={};k(wt,{SchedulerLock:()=>Pe});import{hostname as Ba}from"os";async function xe(){let{Connection:o}=await Promise.resolve().then(()=>(x(),P));return o}async function Fa(){return(await xe()).getDriver()}var Qr,B,Pe,Se=y(()=>{"use strict";Qr=!1,B=`${Ba()}:${process.pid}:${Math.random().toString(36).slice(2,10)}`;Pe=class{static getOwnerId(){return B}static async ensureTable(){if(Qr)return;let e=await xe();switch(e.getDriver()){case"sqlite":await e.raw(`CREATE TABLE IF NOT EXISTS scheduler_locks (
|
|
6
6
|
task_key TEXT PRIMARY KEY,
|
|
7
7
|
owner TEXT NOT NULL,
|
|
8
8
|
expires_at TEXT NOT NULL
|
|
@@ -14,7 +14,7 @@ var vn=Object.defineProperty;var Fe=(l=>typeof require<"u"?require:typeof Proxy<
|
|
|
14
14
|
task_key VARCHAR(255) PRIMARY KEY,
|
|
15
15
|
owner VARCHAR(255) NOT NULL,
|
|
16
16
|
expires_at DATETIME NOT NULL
|
|
17
|
-
) ENGINE=InnoDB`);break}
|
|
17
|
+
) ENGINE=InnoDB`);break}Qr=!0}static async acquire(e,t=5){await this.ensureTable();let s=await xe(),r=await Fa(),i=new Date().toISOString(),n=new Date(Date.now()+t*6e4).toISOString();try{await s.transaction(async()=>{switch(await s.raw("DELETE FROM scheduler_locks WHERE task_key = ? AND expires_at < ?",[e,i]),r){case"sqlite":await s.raw("INSERT OR IGNORE INTO scheduler_locks (task_key, owner, expires_at) VALUES (?, ?, ?)",[e,B,n]);break;case"postgres":await s.raw("INSERT INTO scheduler_locks (task_key, owner, expires_at) VALUES ($1, $2, $3) ON CONFLICT (task_key) DO NOTHING",[e,B,n]);break;case"mysql":await s.raw("INSERT IGNORE INTO scheduler_locks (task_key, owner, expires_at) VALUES (?, ?, ?)",[e,B,n]);break}});let a=await s.raw("SELECT owner FROM scheduler_locks WHERE task_key = ?",[e]);return a.length>0&&a[0].owner===B}catch{return!1}}static async release(e){try{await(await xe()).raw("DELETE FROM scheduler_locks WHERE task_key = ? AND owner = ?",[e,B])}catch{}}static async releaseAll(){try{await(await xe()).raw("DELETE FROM scheduler_locks WHERE owner = ?",[B])}catch{}}}});var Yr={};k(Yr,{ScheduledTask:()=>Ct,Scheduler:()=>xs,SchedulerLock:()=>Pe,cronMatches:()=>Cs,parseCron:()=>Gr,task:()=>Ha});function Re(o,e,t){if(o==="*")return null;let s=new Set;for(let r of o.split(",")){let[i,n]=r.split("/"),a=n?parseInt(n,10):1;if(i==="*")for(let l=e;l<=t;l+=a)s.add(l);else if(i.includes("-")){let[l,c]=i.split("-"),u=parseInt(l,10),m=parseInt(c,10);for(let h=u;h<=m;h+=a)s.add(h)}else s.add(parseInt(i,10))}return[...s].sort((r,i)=>r-i)}function Gr(o){let e=o.trim().split(/\s+/);if(e.length!==5)throw new Error(`Invalid cron expression: "${o}". Expected 5 fields.`);return{minute:Re(e[0],0,59),hour:Re(e[1],0,23),dayOfMonth:Re(e[2],1,31),month:Re(e[3],1,12),dayOfWeek:Re(e[4],0,6)}}function Cs(o,e){let t=Gr(o),s=e.getMinutes(),r=e.getHours(),i=e.getDate(),n=e.getMonth()+1,a=e.getDay();return!(t.minute&&!t.minute.includes(s)||t.hour&&!t.hour.includes(r)||t.dayOfMonth&&!t.dayOfMonth.includes(i)||t.month&&!t.month.includes(n)||t.dayOfWeek&&!t.dayOfWeek.includes(a))}function Ha(o,e,t){class s extends Ct{name=o;schedule(){return t&&t(this),this}async handle(){return e()}}return new s}var Ct,xs,Zr=y(()=>{"use strict";Se();Ct=class{name=this.constructor.name;_running=!1;withoutOverlapping=!1;_lockTtlMinutes=5;_expression="* * * * *";schedule(){return this}onSuccess(){}onFailure(e){console.error(`[Scheduler] Task "${this.name}" failed:`,e.message)}everyMinute(){return this._expression="* * * * *",this}everyMinutes(e){return this._expression=`*/${e} * * * *`,this}everyFiveMinutes(){return this.everyMinutes(5)}everyTenMinutes(){return this.everyMinutes(10)}everyFifteenMinutes(){return this.everyMinutes(15)}everyThirtyMinutes(){return this.everyMinutes(30)}hourly(){return this._expression="0 * * * *",this}hourlyAt(e){return this._expression=`${e} * * * *`,this}daily(){return this._expression="0 0 * * *",this}dailyAt(e){let[t,s]=e.split(":").map(Number);return this._expression=`${s??0} ${t} * * *`,this}twiceDaily(e=1,t=13){return this._expression=`0 ${e},${t} * * *`,this}weekly(){return this._expression="0 0 * * 0",this}weeklyOn(e,t="00:00"){let[s,r]=t.split(":").map(Number);return this._expression=`${r??0} ${s} * * ${e}`,this}weekdays(){return this._expression=`${this._expression.split(" ").slice(0,4).join(" ")} 1-5`,this}weekends(){return this._expression=`${this._expression.split(" ").slice(0,4).join(" ")} 0,6`,this}monthly(){return this._expression="0 0 1 * *",this}monthlyOn(e,t="00:00"){let[s,r]=t.split(":").map(Number);return this._expression=`${r??0} ${s} ${e} * *`,this}quarterly(){return this._expression="0 0 1 1,4,7,10 *",this}yearly(){return this._expression="0 0 1 1 *",this}cron(e){return this._expression=e,this}preventOverlap(){return this.withoutOverlapping=!0,this}lockExpiresAfter(e){return this._lockTtlMinutes=e,this}getExpression(){return this.schedule(),this._expression}isRunning(){return this._running}async executeTask(){if(this.withoutOverlapping&&this._running)return{task:this.name,success:!0,duration:0,timestamp:new Date};let e=!1;if(this.withoutOverlapping)try{let{SchedulerLock:s}=await Promise.resolve().then(()=>(Se(),wt));if(e=await s.acquire(this.name,this._lockTtlMinutes),!e)return{task:this.name,success:!0,duration:0,timestamp:new Date}}catch{}this._running=!0;let t=Date.now();try{await this.handle();let s=Date.now()-t;return await this.onSuccess(),{task:this.name,success:!0,duration:s,timestamp:new Date}}catch(s){let r=Date.now()-t;return await this.onFailure(s),{task:this.name,success:!1,duration:r,error:s.message,timestamp:new Date}}finally{if(this._running=!1,e)try{let{SchedulerLock:s}=await Promise.resolve().then(()=>(Se(),wt));await s.release(this.name)}catch{}}}},xs=class{tasks=[];timer=null;history=[];maxHistory=100;_persistToDb=!1;persistToDatabase(){return this._persistToDb=!0,this}register(e){return this.tasks.push(e),this}registerMany(e){for(let t of e)this.register(t);return this}async run(e){let t=e??new Date,s=[];for(let r of this.tasks){let i=r.getExpression();if(Cs(i,t)){let n=await r.executeTask();s.push(n),this.addToHistory(n)}}return s}start(){if(this.timer)return;this.run().catch(s=>console.error("[Scheduler] Error:",s));let t=6e4-Date.now()%6e4;this.timer=setTimeout(()=>{this.run().catch(s=>console.error("[Scheduler] Error:",s)),this.timer=setInterval(()=>{this.run().catch(s=>console.error("[Scheduler] Error:",s))},6e4)},t),console.log(`[Scheduler] Started with ${this.tasks.length} task(s). Next tick in ${Math.round(t/1e3)}s.`)}async stop(){this.timer&&(clearTimeout(this.timer),clearInterval(this.timer),this.timer=null);try{let{SchedulerLock:e}=await Promise.resolve().then(()=>(Se(),wt));await e.releaseAll()}catch{}console.log("[Scheduler] Stopped.")}getTasks(){return[...this.tasks]}getHistory(){return[...this.history]}dueTasks(e){let t=e??new Date;return this.tasks.filter(s=>Cs(s.getExpression(),t))}remove(e){let t=this.tasks.findIndex(s=>s.name===e);return t!==-1?(this.tasks.splice(t,1),!0):!1}clear(){this.tasks=[]}addToHistory(e){this.history.push(e),this.history.length>this.maxHistory&&this.history.shift(),this._persistToDb&&this.persistResult(e).catch(()=>{})}_historyTableEnsured=!1;async ensureHistoryTable(){if(this._historyTableEnsured)return;let{Connection:e}=await Promise.resolve().then(()=>(x(),P));switch(e.getDriver()){case"sqlite":await e.raw(`CREATE TABLE IF NOT EXISTS scheduled_task_runs (
|
|
18
18
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
19
19
|
task TEXT NOT NULL,
|
|
20
20
|
success INTEGER NOT NULL,
|
|
@@ -35,11 +35,11 @@ var vn=Object.defineProperty;var Fe=(l=>typeof require<"u"?require:typeof Proxy<
|
|
|
35
35
|
duration INT NOT NULL,
|
|
36
36
|
error TEXT,
|
|
37
37
|
ran_at DATETIME NOT NULL
|
|
38
|
-
) ENGINE=InnoDB`);break}this._historyTableEnsured=!0}async persistResult(e){try{await this.ensureHistoryTable();let{Connection:t}=await Promise.resolve().then(()=>(x(),P));await t.raw("INSERT INTO scheduled_task_runs (task, success, duration, error, ran_at) VALUES (?, ?, ?, ?, ?)",[e.task,e.success,e.duration,e.error||null,e.timestamp.toISOString()])}catch{}}}});var
|
|
38
|
+
) ENGINE=InnoDB`);break}this._historyTableEnsured=!0}async persistResult(e){try{await this.ensureHistoryTable();let{Connection:t}=await Promise.resolve().then(()=>(x(),P));await t.raw("INSERT INTO scheduled_task_runs (task, success, duration, error, ran_at) VALUES (?, ?, ?, ?, ?)",[e.task,e.success,e.duration,e.error||null,e.timestamp.toISOString()])}catch{}}}});var Te={};k(Te,{Job:()=>J,Queue:()=>$s});var J,Pt,Ss,W,St,Rs,Ts,Es,ks,$s,V=y(()=>{"use strict";R();J=class{attempts=0;maxAttempts=3;retryDelay=60;queue="default";failed(e){console.error(`[Queue] Job ${this.constructor.name} permanently failed:`,e.message)}retrying(e){}serialize(){let e={};for(let[t,s]of Object.entries(this))typeof s!="function"&&(e[t]=s);return JSON.stringify(e)}restore(e){for(let[t,s]of Object.entries(e))t!=="attempts"&&t!=="maxAttempts"&&t!=="retryDelay"&&t!=="queue"&&(this[t]=s)}},Pt=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(){}},Ss=class{queues=new Map;async push(e){let t=e.queue;this.queues.has(t)||this.queues.set(t,[]),this.queues.get(t).push(e)}async pop(e="default"){let t=this.queues.get(e)??[],s=Date.now(),r=t.findIndex(i=>i.availableAt<=s);return r===-1?null:t.splice(r,1)[0]}async size(e="default"){return this.queues.get(e)?.length??0}async clear(e){e?this.queues.delete(e):this.queues.clear()}},W=class{constructor(e,t){this.table=e;this.registry=t}async getConnection(){let{Connection:e}=await Promise.resolve().then(()=>(x(),P));return e}async push(e){await(await this.getConnection()).raw(`INSERT INTO ${this.table} (id, queue, payload, attempts, max_attempts, available_at, created_at)
|
|
39
39
|
VALUES (?, ?, ?, ?, ?, ?, ?)`,[e.id,e.queue,JSON.stringify({jobClass:e.jobClass,payload:e.payload}),e.attempts,e.maxAttempts,Math.floor(e.availableAt/1e3),Math.floor(e.createdAt/1e3)])}async pop(e="default"){let t=await this.getConnection(),s=Math.floor(Date.now()/1e3),r=await t.raw(`SELECT * FROM ${this.table}
|
|
40
40
|
WHERE queue = ? AND available_at <= ? AND reserved_at IS NULL
|
|
41
|
-
ORDER BY created_at ASC LIMIT 1`,[e,s]);if(!r||r.length===0)return null;let i=r[0];await t.raw(`UPDATE ${this.table} SET reserved_at = ?, attempts = attempts + 1 WHERE id = ?`,[s,i.id]);let n=JSON.parse(i.payload),a=this.registry.resolve(n.jobClass,n.payload);return{id:i.id,jobClass:n.jobClass,payload:n.payload,queue:i.queue,attempts:i.attempts+1,maxAttempts:i.max_attempts,availableAt:i.available_at*1e3,createdAt:i.created_at*1e3,job:a}}async size(e="default"){return(await(await this.getConnection()).raw(`SELECT COUNT(*) as count FROM ${this.table} WHERE queue = ? AND reserved_at IS NULL`,[e]))?.[0]?.count??0}async clear(e){let t=await this.getConnection();e?await t.raw(`DELETE FROM ${this.table} WHERE queue = ?`,[e]):await t.raw(`DELETE FROM ${this.table}`,[])}async delete(e){await(await this.getConnection()).raw(`DELETE FROM ${this.table} WHERE id = ?`,[e])}async release(e,t=0){let s=await this.getConnection(),r=Math.floor(Date.now()/1e3)+t;await s.raw(`UPDATE ${this.table} SET reserved_at = NULL, available_at = ? WHERE id = ?`,[r,e])}},
|
|
42
|
-
VALUES (?, ?, ?, ?, ?, ?)`,[crypto.randomUUID(),e.queue,e.jobClass,e.payload,t.stack??t.message,Math.floor(Date.now()/1e3)])}catch{console.error("[Queue] Could not persist failed job (run migration to create svelar_failed_jobs table)")}}async all(){return(await(await this.getConnection()).raw(`SELECT * FROM ${this.table} ORDER BY failed_at DESC`,[])??[]).map(s=>({id:s.id,queue:s.queue,jobClass:s.job_class,payload:s.payload,exception:s.exception,failedAt:s.failed_at}))}async find(e){let s=await(await this.getConnection()).raw(`SELECT * FROM ${this.table} WHERE id = ? LIMIT 1`,[e]);if(!s||s.length===0)return null;let r=s[0];return{id:r.id,queue:r.queue,jobClass:r.job_class,payload:r.payload,exception:r.exception,failedAt:r.failed_at}}async forget(e){return await(await this.getConnection()).raw(`DELETE FROM ${this.table} WHERE id = ?`,[e]),!0}async flush(){let e=await this.getConnection(),s=(await e.raw(`SELECT COUNT(*) as count FROM ${this.table}`,[]))?.[0]?.count??0;return await e.raw(`DELETE FROM ${this.table}`,[]),s}},xs=class{jobs=new Map;register(e){this.jobs.set(e.name,e)}registerAll(e){for(let t of e)this.register(t)}resolve(e,t){let s=this.jobs.get(e);if(!s)throw new Error(`Job class "${e}" is not registered. Call Queue.register(${e}) in your app bootstrap. Registered jobs: [${[...this.jobs.keys()].join(", ")}]`);let r=Object.create(s.prototype);r.attempts=0,r.maxAttempts=3,r.retryDelay=60,r.queue="default";try{let i=JSON.parse(t);r.restore(i)}catch{}return r}has(e){return this.jobs.has(e)}},Cs=class{config={default:"sync",connections:{sync:{driver:"sync"}}};drivers=new Map;processing=!1;jobRegistry=new xs;failedStore=new ws;_activeWorker=null;configure(e){this.config=e,this.drivers.clear()}register(e){this.jobRegistry.register(e)}registerAll(e){this.jobRegistry.registerAll(e)}async dispatch(e,t){let s=this.config.default,r=this.config.connections[s],i=this.resolveDriver(s);t?.queue&&(e.queue=t.queue),t?.maxAttempts!==void 0&&(e.maxAttempts=t.maxAttempts);let n={id:crypto.randomUUID(),jobClass:e.constructor.name,payload:e.serialize(),queue:e.queue??r?.queue??"default",attempts:0,maxAttempts:e.maxAttempts,availableAt:Date.now()+(t?.delay??0)*1e3,createdAt:Date.now(),job:e};await i.push(n)}async dispatchSync(e){let t=new wt,s={id:crypto.randomUUID(),jobClass:e.constructor.name,payload:e.serialize(),queue:e.queue,attempts:0,maxAttempts:e.maxAttempts,availableAt:Date.now(),createdAt:Date.now(),job:e};await t.push(s)}async chain(e,t){if(e.length===0)return;let s=new Ps(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 xt){let o=await s.createWorker(r,this.jobRegistry,this.failedStore,{concurrency:e?.concurrency??1});return this.processing=!0,this._activeWorker=o,await new Promise(c=>{let u=()=>{this.processing?setTimeout(u,500):o.close().then(c).catch(c)};u()}),0}let i=e?.maxJobs??1/0,n=(e?.sleep??1)*1e3,a=0;for(this.processing=!0;this.processing&&a<i;){let o=await s.pop(r);if(!o){if(i===1/0){await new Promise(c=>setTimeout(c,n));continue}break}o.attempts++,o.job.attempts=o.attempts;try{await o.job.handle(),a++,s instanceof J&&await s.delete(o.id)}catch(c){if(o.attempts<o.maxAttempts){o.job.retrying(o.attempts);let u=o.job.retryDelay??60;s instanceof J?await s.release(o.id,u):(o.availableAt=Date.now()+u*1e3,await s.push(o))}else o.job.failed(c),await this.failedStore.store(o,c),s instanceof J&&await s.delete(o.id)}}return a}async stop(){this.processing=!1,this._activeWorker&&(await this._activeWorker.close(),this._activeWorker=null)}async size(e){return this.resolveDriver(this.config.default).size(e)}async clear(e){return this.resolveDriver(this.config.default).clear(e)}async failed(){return this.failedStore.all()}async retry(e){let t=await this.failedStore.find(e);if(!t)return!1;let s=this.jobRegistry.resolve(t.jobClass,t.payload);return s.queue=t.queue,await this.dispatch(s,{queue:t.queue}),await this.failedStore.forget(e),!0}async retryAll(){let e=await this.failedStore.all(),t=0;for(let s of e)try{let r=this.jobRegistry.resolve(s.jobClass,s.payload);r.queue=s.queue,await this.dispatch(r,{queue:s.queue}),await this.failedStore.forget(s.id),t++}catch{}return t}async forgetFailed(e){return this.failedStore.forget(e)}async flushFailed(){return this.failedStore.flush()}resolveDriver(e){if(this.drivers.has(e))return this.drivers.get(e);let t=this.config.connections[e];if(!t)throw new Error(`Queue connection "${e}" is not defined.`);let s;switch(t.driver){case"sync":s=new wt;break;case"memory":s=new bs;break;case"database":s=new J(t.table??"svelar_jobs",this.jobRegistry);break;case"redis":s=new xt(t,this.jobRegistry);break;default:throw new Error(`Unknown queue driver: ${t.driver}`)}return this.drivers.set(e,s),s}},Ps=class extends V{remainingJobs;constructor(e){super(),this.remainingJobs=[...e],this.maxAttempts=1}async handle(){for(let e of this.remainingJobs){let t=null,s=!1;for(let r=1;r<=e.maxAttempts;r++){e.attempts=r;try{await e.handle(),s=!0;break}catch(i){t=i,r<e.maxAttempts&&(e.retrying(r),e.retryDelay>0&&await new Promise(n=>setTimeout(n,e.retryDelay*1e3)))}}if(!s&&t)throw e.failed(t),new Error(`Chain stopped: ${e.constructor.name} failed after ${e.maxAttempts} attempt(s). Remaining jobs: [${this.remainingJobs.slice(this.remainingJobs.indexOf(e)+1).map(r=>r.constructor.name).join(", ")}]`)}}serialize(){return JSON.stringify({jobs:this.remainingJobs.map(e=>({jobClass:e.constructor.name,payload:e.serialize()}))})}},Ss=w("svelar.queue",()=>new Cs)});var D,Rs=y(()=>{"use strict";x();D=class l{tableName;selectColumns=["*"];whereClauses=[];joinClauses=[];orderClauses=[];groupByColumns=[];havingClauses=[];limitValue=null;offsetValue=null;eagerLoads=[];isDistinct=!1;connectionName;cteClauses=[];unionClauses=[];modelClass;constructor(e,t,s){this.tableName=e,this.modelClass=t,this.connectionName=s}select(...e){return this.selectColumns=e.length>0?e:["*"],this}addSelect(...e){return this.selectColumns[0]==="*"?this.selectColumns=e:this.selectColumns.push(...e),this}distinct(){return this.isDistinct=!0,this}from(e){return this.tableName=e,this}where(e,t,s){return s===void 0?this.whereClauses.push({type:"basic",column:e,operator:"=",value:t,boolean:"AND"}):this.whereClauses.push({type:"basic",column:e,operator:t,value:s,boolean:"AND"}),this}orWhere(e,t,s){return s===void 0?this.whereClauses.push({type:"basic",column:e,operator:"=",value:t,boolean:"OR"}):this.whereClauses.push({type:"basic",column:e,operator:t,value:s,boolean:"OR"}),this}whereIn(e,t){return this.whereClauses.push({type:"in",column:e,values:t,boolean:"AND"}),this}whereNotIn(e,t){return this.whereClauses.push({type:"notIn",column:e,values:t,boolean:"AND"}),this}whereNull(e){return this.whereClauses.push({type:"null",column:e,boolean:"AND"}),this}whereNotNull(e){return this.whereClauses.push({type:"notNull",column:e,boolean:"AND"}),this}whereBetween(e,t){return this.whereClauses.push({type:"between",column:e,values:t,boolean:"AND"}),this}whereRaw(e,t=[]){return this.whereClauses.push({type:"raw",raw:e,values:t,boolean:"AND"}),this}whereNested(e,t="AND"){let s=new l(this.tableName,this.modelClass,this.connectionName);if(e(s),s.whereClauses.length>0){let{whereSQL:r,whereBindings:i}=s.buildWhere(),n=r.replace(/^WHERE /,"");this.whereClauses.push({type:"raw",raw:`(${n})`,values:i,boolean:t})}return this}orWhereNested(e){return this.whereNested(e,"OR")}whereExists(e){let t=new l("__placeholder__",void 0,this.connectionName);e(t);let{sql:s,bindings:r}=t.toSQL();return this.whereClauses.push({type:"exists",subSQL:s,subBindings:r,boolean:"AND"}),this}whereNotExists(e){let t=new l("__placeholder__",void 0,this.connectionName);e(t);let{sql:s,bindings:r}=t.toSQL();return this.whereClauses.push({type:"notExists",subSQL:s,subBindings:r,boolean:"AND"}),this}whereSub(e,t,s){let r=new l("__placeholder__",void 0,this.connectionName);s(r);let{sql:i,bindings:n}=r.toSQL();return this.whereClauses.push({type:"sub",column:e,operator:t,subSQL:i,subBindings:n,boolean:"AND"}),this}orWhereRaw(e,t=[]){return this.whereClauses.push({type:"raw",raw:e,values:t,boolean:"OR"}),this}orWhereIn(e,t){return this.whereClauses.push({type:"in",column:e,values:t,boolean:"OR"}),this}orWhereNull(e){return this.whereClauses.push({type:"null",column:e,boolean:"OR"}),this}orWhereNotNull(e){return this.whereClauses.push({type:"notNull",column:e,boolean:"OR"}),this}withCTE(e,t,s=!1){let r=new l("__placeholder__",void 0,this.connectionName);t(r);let{sql:i,bindings:n}=r.toSQL();return this.cteClauses.push({name:e,sql:i,bindings:n,recursive:s}),this}withRecursiveCTE(e,t){return this.withCTE(e,t,!0)}withRawCTE(e,t,s=[],r=!1){return this.cteClauses.push({name:e,sql:t,bindings:s,recursive:r}),this}union(e){let t=new l("__placeholder__",void 0,this.connectionName);e(t);let{sql:s,bindings:r}=t.toSQL();return this.unionClauses.push({sql:s,bindings:r,all:!1}),this}unionAll(e){let t=new l("__placeholder__",void 0,this.connectionName);e(t);let{sql:s,bindings:r}=t.toSQL();return this.unionClauses.push({sql:s,bindings:r,all:!0}),this}join(e,t,s,r){return this.joinClauses.push({type:"INNER",table:e,first:t,operator:s,second:r}),this}leftJoin(e,t,s,r){return this.joinClauses.push({type:"LEFT",table:e,first:t,operator:s,second:r}),this}rightJoin(e,t,s,r){return this.joinClauses.push({type:"RIGHT",table:e,first:t,operator:s,second:r}),this}crossJoin(e){return this.joinClauses.push({type:"CROSS",table:e,first:"",operator:"",second:""}),this}orderBy(e,t="asc"){return this.orderClauses.push({column:e,direction:t}),this}latest(e="created_at"){return this.orderBy(e,"desc")}oldest(e="created_at"){return this.orderBy(e,"asc")}groupBy(...e){return this.groupByColumns.push(...e),this}having(e,t,s){return this.havingClauses.push({type:"basic",column:e,operator:t,value:s,boolean:"AND"}),this}limit(e){return this.limitValue=e,this}offset(e){return this.offsetValue=e,this}take(e){return this.limit(e)}skip(e){return this.offset(e)}with(...e){return this.eagerLoads.push(...e),this}async get(){let{sql:e,bindings:t}=this.toSQL(),s=await 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 i=this.clone();i.limitValue=e,i.offsetValue=(s-1)*e;let n=await i.get();if(n.length===0||await t(n,s)===!1||n.length<e)break;s++}}when(e,t){return e&&t(this),this}selectRaw(e){return this.selectColumns[0]==="*"?this.selectColumns=[e]:this.selectColumns.push(e),this}async upsert(e,t,s){let r=g.getDriver(this.connectionName),i=Object.keys(e),n=Object.values(e),a=n.map(()=>"?").join(", "),o=s??i.filter(u=>!t.includes(u)),c;if(r==="postgres"){let u=o.map(d=>`${d} = EXCLUDED.${d}`).join(", ");c=`INSERT INTO ${this.tableName} (${i.join(", ")}) VALUES (${a}) ON CONFLICT (${t.join(", ")}) DO UPDATE SET ${u}`}else if(r==="mysql"){let u=o.map(d=>`${d} = VALUES(${d})`).join(", ");c=`INSERT INTO ${this.tableName} (${i.join(", ")}) VALUES (${a}) ON DUPLICATE KEY UPDATE ${u}`}else{let u=o.map(d=>`${d} = excluded.${d}`).join(", ");c=`INSERT INTO ${this.tableName} (${i.join(", ")}) VALUES (${a}) ON CONFLICT (${t.join(", ")}) DO UPDATE SET ${u}`}return g.raw(c,n,this.connectionName)}async insertMany(e){if(e.length===0)return;let t=Object.keys(e[0]),s=[],r=[];for(let n of e){let a=t.map(o=>n[o]);s.push(...a),r.push(`(${a.map(()=>"?").join(", ")})`)}let i=`INSERT INTO ${this.tableName} (${t.join(", ")}) VALUES ${r.join(", ")}`;return g.raw(i,s,this.connectionName)}async firstOrCreate(e,t={}){for(let[n,a]of Object.entries(e))this.where(n,a);let s=await this.first();if(s)return s;let r={...e,...t},i=await new l(this.tableName,this.modelClass,this.connectionName).insertGetId(r);return new l(this.tableName,this.modelClass,this.connectionName).findOrFail(i)}async updateOrCreate(e,t){let s=new l(this.tableName,this.modelClass,this.connectionName);for(let[a,o]of Object.entries(e))s.where(a,o);let r=await s.first();if(r)return await new l(this.tableName,this.modelClass,this.connectionName).where(this.modelClass?.primaryKey??"id",r[this.modelClass?.primaryKey??"id"]).update(t),new l(this.tableName,this.modelClass,this.connectionName).findOrFail(r[this.modelClass?.primaryKey??"id"]);let i={...e,...t},n=await new l(this.tableName,this.modelClass,this.connectionName).insertGetId(i);return new l(this.tableName,this.modelClass,this.connectionName).findOrFail(n)}whereColumn(e,t,s){return s===void 0?this.whereClauses.push({type:"raw",raw:`${e} = ${t}`,values:[],boolean:"AND"}):this.whereClauses.push({type:"raw",raw:`${e} ${t} ${s}`,values:[],boolean:"AND"}),this}havingRaw(e,t=[]){return this.havingClauses.push({type:"raw",raw:e,values:t,boolean:"AND"}),this}orderByRaw(e){return this.orderClauses.push({column:e,direction:"asc"}),this.orderClauses[this.orderClauses.length-1].__raw=!0,this}selectSub(e,t){let s=new l("__placeholder__",void 0,this.connectionName);e(s);let{sql:r,bindings:i}=s.toSQL(),n=`(${r}) as ${t}`;return this.selectColumns[0]==="*"?this.selectColumns=[n]:this.selectColumns.push(n),this._selectBindings||(this._selectBindings=[]),this._selectBindings.push(...i),this}_selectBindings;async truncate(){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(", "),i=`INSERT INTO ${this.tableName} (${t.join(", ")}) VALUES (${r})`;return g.raw(i,s,this.connectionName)}async insertGetId(e,t="id"){let s=g.getDriver(this.connectionName),r=Object.keys(e),i=Object.values(e),n=i.map(()=>"?").join(", "),a=`INSERT INTO ${this.tableName} (${r.join(", ")}) VALUES (${n})`;return s==="postgres"?(a+=` RETURNING ${t}`,(await g.raw(a,i,this.connectionName))[0]?.[t]):(await g.raw(a,i,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(o=>`${o} = ?`).join(", "),{whereSQL:i,whereBindings:n}=this.buildWhere(),a=`UPDATE ${this.tableName} SET ${r}${i}`;return await g.raw(a,[...s,...n],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(),i=`UPDATE ${this.tableName} SET ${e} = ${e} + ?${s}`;await g.raw(i,[t,...r],this.connectionName)}async decrement(e,t=1){return this.increment(e,-t)}toSQL(){let e=[],t=[];if(this.cteClauses.length>0){let a=this.cteClauses.some(c=>c.recursive)?"WITH RECURSIVE":"WITH",o=this.cteClauses.map(c=>(t.push(...c.bindings),`${c.name} AS (${c.sql})`));e.push(`${a} ${o.join(", ")}`)}this._selectBindings?.length&&t.push(...this._selectBindings);let s=this.isDistinct?"DISTINCT ":"";e.push(`SELECT ${s}${this.selectColumns.join(", ")}`),e.push(`FROM ${this.tableName}`);for(let n of this.joinClauses)n.type==="CROSS"?e.push(`CROSS JOIN ${n.table}`):e.push(`${n.type} JOIN ${n.table} ON ${n.first} ${n.operator} ${n.second}`);let{whereSQL:r,whereBindings:i}=this.buildWhere();if(r&&(e.push(r.trim()),t.push(...i)),this.groupByColumns.length>0&&e.push(`GROUP BY ${this.groupByColumns.join(", ")}`),this.havingClauses.length>0){let n=[];for(let a of this.havingClauses)a.type==="raw"?(n.push(a.raw),a.values&&t.push(...a.values)):(n.push(`${a.column} ${a.operator} ?`),t.push(a.value));e.push(`HAVING ${n.join(" AND ")}`)}if(this.orderClauses.length>0){let n=this.orderClauses.map(a=>a.__raw?a.column:`${a.column} ${a.direction.toUpperCase()}`);e.push(`ORDER BY ${n.join(", ")}`)}if(this.limitValue!==null&&e.push(`LIMIT ${this.limitValue}`),this.offsetValue!==null&&e.push(`OFFSET ${this.offsetValue}`),this.unionClauses.length>0)for(let n of this.unionClauses)e.push(n.all?"UNION ALL":"UNION"),e.push(n.sql),t.push(...n.bindings);return{sql:e.join(" "),bindings:t}}clone(){let e=new l(this.tableName,this.modelClass,this.connectionName);return e.selectColumns=[...this.selectColumns],e.whereClauses=[...this.whereClauses],e.joinClauses=[...this.joinClauses],e.orderClauses=[...this.orderClauses],e.groupByColumns=[...this.groupByColumns],e.havingClauses=[...this.havingClauses],e.limitValue=this.limitValue,e.offsetValue=this.offsetValue,e.eagerLoads=[...this.eagerLoads],e.isDistinct=this.isDistinct,e.cteClauses=[...this.cteClauses],e.unionClauses=[...this.unionClauses],e}buildWhere(){if(this.whereClauses.length===0)return{whereSQL:"",whereBindings:[]};let e=[],t=[];for(let s=0;s<this.whereClauses.length;s++){let r=this.whereClauses[s],i=s===0?"WHERE":r.boolean;switch(r.type){case"basic":if((r.operator==="IS"||r.operator==="IS NOT")&&r.value===null){let o=(r.operator==="IS","null");e.push(`${i} ${r.column} ${r.operator} ${o}`)}else e.push(`${i} ${r.column} ${r.operator} ?`),t.push(r.value);break;case"in":let n=r.values.map(()=>"?").join(", ");e.push(`${i} ${r.column} IN (${n})`),t.push(...r.values);break;case"notIn":let a=r.values.map(()=>"?").join(", ");e.push(`${i} ${r.column} NOT IN (${a})`),t.push(...r.values);break;case"null":e.push(`${i} ${r.column} IS NULL`);break;case"notNull":e.push(`${i} ${r.column} IS NOT NULL`);break;case"between":e.push(`${i} ${r.column} BETWEEN ? AND ?`),t.push(r.values[0],r.values[1]);break;case"raw":e.push(`${i} ${r.raw}`),r.values&&t.push(...r.values);break;case"exists":e.push(`${i} EXISTS (${r.subSQL})`),r.subBindings&&t.push(...r.subBindings);break;case"notExists":e.push(`${i} NOT EXISTS (${r.subSQL})`),r.subBindings&&t.push(...r.subBindings);break;case"sub":e.push(`${i} ${r.column} ${r.operator} (${r.subSQL})`),r.subBindings&&t.push(...r.subBindings);break}}return{whereSQL:e.join(" "),whereBindings:t}}buildAggregate(e){let t=this.selectColumns;this.selectColumns=[`${e} as aggregate`];let s=this.toSQL();return this.selectColumns=t,s}hydrateMany(e){return this.modelClass?e.map(t=>this.modelClass.hydrate(t)):e}async loadRelations(e){if(!(!this.modelClass||e.length===0))for(let t of this.eagerLoads){let r=new this.modelClass()[t]?.();r&&typeof r.eagerLoad=="function"&&await r.eagerLoad(e,t)}}}});var G,Y,X,Z,ee,Ts=y(()=>{"use strict";x();G=class{parentModel;relatedModel;constructor(e,t){this.parentModel=e,this.relatedModel=t}query(){return this.relatedModel.query()}},Y=class extends G{constructor(t,s,r,i="id"){super(t,s);this.foreignKey=r;this.localKey=i}async load(t){let s=t.getAttribute(this.localKey);return this.relatedModel.query().where(this.foreignKey,s).first()}async eagerLoad(t,s){let r=t.map(a=>a.getAttribute(this.localKey)),i=await this.relatedModel.query().whereIn(this.foreignKey,r).get(),n=new Map;for(let a of i)n.set(a.getAttribute(this.foreignKey),a);for(let a of t){let o=a.getAttribute(this.localKey);a.setRelation(s,n.get(o)??null)}}async create(t){let s=this.parentModel.getAttribute(this.localKey);return this.relatedModel.create({...t,[this.foreignKey]:s})}},X=class extends G{constructor(t,s,r,i="id"){super(t,s);this.foreignKey=r;this.localKey=i}async load(t){let s=t.getAttribute(this.localKey);return this.relatedModel.query().where(this.foreignKey,s).get()}async eagerLoad(t,s){let r=t.map(a=>a.getAttribute(this.localKey)),i=await this.relatedModel.query().whereIn(this.foreignKey,r).get(),n=new Map;for(let a of i){let o=a.getAttribute(this.foreignKey);n.has(o)||n.set(o,[]),n.get(o).push(a)}for(let a of t){let o=a.getAttribute(this.localKey);a.setRelation(s,n.get(o)??[])}}async create(t){let s=this.parentModel.getAttribute(this.localKey);return this.relatedModel.create({...t,[this.foreignKey]:s})}async createMany(t){let s=[];for(let r of t)s.push(await this.create(r));return s}},Z=class extends G{constructor(t,s,r,i="id"){super(t,s);this.foreignKey=r;this.ownerKey=i}async load(t){let s=t.getAttribute(this.foreignKey);return s==null?null:this.relatedModel.query().where(this.ownerKey,s).first()}async eagerLoad(t,s){let r=t.map(a=>a.getAttribute(this.foreignKey)).filter(a=>a!=null);if(r.length===0){for(let a of t)a.setRelation(s,null);return}let i=await this.relatedModel.query().whereIn(this.ownerKey,r).get(),n=new Map;for(let a of i)n.set(a.getAttribute(this.ownerKey),a);for(let a of t){let o=a.getAttribute(this.foreignKey);a.setRelation(s,n.get(o)??null)}}associate(t){return this.parentModel.setAttribute(this.foreignKey,t.getAttribute(this.ownerKey)),this.parentModel}dissociate(){return this.parentModel.setAttribute(this.foreignKey,null),this.parentModel}},ee=class extends G{constructor(t,s,r,i,n,a="id",o="id"){super(t,s);this.pivotTable=r;this.foreignPivotKey=i;this.relatedPivotKey=n;this.parentKey=a;this.relatedKey=o}async load(t){let s=t.getAttribute(this.parentKey),r=this.relatedModel.tableName,n=(await g.raw(`SELECT ${this.relatedPivotKey} FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ?`,[s])).map(a=>a[this.relatedPivotKey]);return n.length===0?[]:this.relatedModel.query().whereIn(this.relatedKey,n).get()}async eagerLoad(t,s){let r=t.map(d=>d.getAttribute(this.parentKey));if(r.length===0){for(let d of t)d.setRelation(s,[]);return}let i=r.map(()=>"?").join(", "),n=await g.raw(`SELECT * FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} IN (${i})`,r),a=[...new Set(n.map(d=>d[this.relatedPivotKey]))],o=a.length>0?await this.relatedModel.query().whereIn(this.relatedKey,a).get():[],c=new Map;for(let d of o)c.set(d.getAttribute(this.relatedKey),d);let u=new Map;for(let d of n){let p=d[this.foreignPivotKey],f=d[this.relatedPivotKey],b=c.get(f);b&&(u.has(p)||u.set(p,[]),u.get(p).push(b))}for(let d of t){let p=d.getAttribute(this.parentKey);d.setRelation(s,u.get(p)??[])}}async attach(t,s){let r=this.parentModel.getAttribute(this.parentKey),i={[this.foreignPivotKey]:r,[this.relatedPivotKey]:t,...s},n=Object.keys(i),a=Object.values(i),o=a.map(()=>"?").join(", ");await g.raw(`INSERT INTO ${this.pivotTable} (${n.join(", ")}) VALUES (${o})`,a)}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 di=y(()=>{"use strict"});var ke,Es=y(()=>{"use strict";ke=class{app;constructor(e){this.app=e}boot(){}}});var ui=y(()=>{"use strict";Es();Tt()});var $e,te,Tt=y(()=>{"use strict";R();di();ui();$e=class{listeners=new Map;wildcardListeners=[];onceListeners=new Map;listen(e,t){let s=typeof e=="string"?e:e.name;return this.listeners.has(s)||this.listeners.set(s,[]),this.listeners.get(s).push(t),()=>{let r=this.listeners.get(s);if(r){let i=r.indexOf(t);i>=0&&r.splice(i,1)}}}once(e,t){let s=typeof e=="string"?e:e.name;return this.onceListeners.has(s)||this.onceListeners.set(s,[]),this.onceListeners.get(s).push(t),()=>{let r=this.onceListeners.get(s);if(r){let i=r.indexOf(t);i>=0&&r.splice(i,1)}}}onAny(e){return this.wildcardListeners.push(e),()=>{let t=this.wildcardListeners.indexOf(e);t>=0&&this.wildcardListeners.splice(t,1)}}async dispatch(e){let t=e.constructor.name,s=this.listeners.get(t)??[];for(let i of s)await i(e);let r=this.onceListeners.get(t)??[];for(let i of r)await i(e);this.onceListeners.delete(t);for(let i of this.wildcardListeners)await i(t,e)}async emit(e,t){let s=this.listeners.get(e)??[];for(let i of s)await i(t);let r=this.onceListeners.get(e)??[];for(let i of r)await i(t);this.onceListeners.delete(e);for(let i of this.wildcardListeners)await i(e,t)}subscribe(e){e.subscribe(this)}forget(e){let t=typeof e=="string"?e:e.name;this.listeners.delete(t),this.onceListeners.delete(t)}flush(){this.listeners.clear(),this.onceListeners.clear(),this.wildcardListeners=[]}hasListeners(e){let t=typeof e=="string"?e:e.name;return(this.listeners.get(t)?.length??0)>0||(this.onceListeners.get(t)?.length??0)>0||this.wildcardListeners.length>0}listenerCount(e){let t=typeof e=="string"?e:e.name;return(this.listeners.get(t)?.length??0)+(this.onceListeners.get(t)?.length??0)}},te=w("svelar.event",()=>new $e)});var Et,mi=y(()=>{"use strict";Rs();Ts();Tt();Et=class l{static table;static primaryKey="id";static incrementing=!0;static timestamps=!0;static createdAt="created_at";static updatedAt="updated_at";static casts={};static fillable=[];static hidden=[];static connection=void 0;static hooks=new Map;static observers=new Map;static events=[];attributes={};originalAttributes={};relations={};exists=!1;constructor(e){return e&&this.fill(e),new Proxy(this,{get(t,s,r){return typeof s=="symbol"||s in t||typeof s!="string"||["table","primaryKey","incrementing","timestamps","casts","fillable","hidden","connection"].includes(s)?Reflect.get(t,s,r):typeof t[s]=="function"?t[s].bind(t):t.getAttribute(s)},set(t,s,r){return typeof s=="symbol"||s in t?Reflect.set(t,s,r):(t.setAttribute(s,r),!0)}})}static query(){let e=new this,t=this;return new D(t.table,this,t.connection)}static async find(e){let t=this;return this.query().find(e,t.primaryKey)}static async findOrFail(e){let t=this;return this.query().findOrFail(e,t.primaryKey)}static async all(){return this.query().get()}static async first(){return this.query().first()}static async firstOrFail(){return this.query().firstOrFail()}static where(e,t,s){return this.query().where(e,t,s)}static whereIn(e,t){return this.query().whereIn(e,t)}static whereNull(e){return this.query().whereNull(e)}static whereNotNull(e){return this.query().whereNotNull(e)}static orderBy(e,t){return this.query().orderBy(e,t)}static latest(e){return this.query().latest(e)}static oldest(e){return this.query().oldest(e)}static with(...e){return this.query().with(...e)}static async count(){return this.query().count()}static async create(e){let t=new this,s=this;if(t.fill(e),await t.fireHook("creating"),await t.fireHook("saving"),s.timestamps){let a=new Date().toISOString();t.setAttribute(s.createdAt,a),t.setAttribute(s.updatedAt,a)}let r=t.getInsertableAttributes(),n=await new D(s.table,this,s.connection).insertGetId(r,s.primaryKey);return s.incrementing&&n&&t.setAttribute(s.primaryKey,n),t.syncOriginal(),t.exists=!0,await t.fireHook("created"),await t.fireHook("saved"),t}async save(){let e=this.constructor;if(this.exists){await this.fireHook("updating"),await this.fireHook("saving"),e.timestamps&&this.setAttribute(e.updatedAt,new Date().toISOString());let t=this.getDirty();if(Object.keys(t).length>0){let s=this.getAttribute(e.primaryKey);await new D(e.table,this.constructor,e.connection).where(e.primaryKey,s).update(t)}this.syncOriginal(),await this.fireHook("updated"),await this.fireHook("saved")}else{if(await this.fireHook("creating"),await this.fireHook("saving"),e.timestamps){let i=new Date().toISOString();this.getAttribute(e.createdAt)||this.setAttribute(e.createdAt,i),this.setAttribute(e.updatedAt,i)}let t=this.getInsertableAttributes(),r=await new D(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 D(e.table,this.constructor,e.connection).where(e.primaryKey,t).delete(),this.exists=!1,await this.fireHook("deleted")}async refresh(){let e=this.constructor,t=this.getAttribute(e.primaryKey),s=await this.constructor.find(t);s&&(this.attributes={...s.attributes},this.syncOriginal())}getAttribute(e){let t=this.constructor,s=this.attributes[e],r=t.casts[e];if(r&&s!==void 0&&s!==null)switch(r){case"number":return Number(s);case"boolean":return!!s;case"string":return String(s);case"date":return new Date(s);case"json":return typeof s=="string"?JSON.parse(s):s}return s}setAttribute(e,t){this.constructor.casts[e]==="json"&&typeof t!="string"?this.attributes[e]=JSON.stringify(t):this.attributes[e]=t}fill(e){let t=this.constructor;for(let[s,r]of Object.entries(e))t.fillable.length>0&&!t.fillable.includes(s)||this.setAttribute(s,r)}getAttributes(){return{...this.attributes}}getOriginal(e){return e?this.originalAttributes[e]:{...this.originalAttributes}}getDirty(){let e={};for(let[t,s]of Object.entries(this.attributes))s!==this.originalAttributes[t]&&(e[t]=s);return e}isDirty(...e){let t=this.getDirty();return e.length===0?Object.keys(t).length>0:e.some(s=>s in t)}isClean(...e){return!this.isDirty(...e)}wasChanged(...e){return this.isDirty(...e)}hasOne(e,t,s){return new Y(this,e,t,s??this.constructor.primaryKey)}hasMany(e,t,s){return new X(this,e,t,s??this.constructor.primaryKey)}belongsTo(e,t,s){return new Z(this,e,t,s??e.primaryKey)}belongsToMany(e,t,s,r,i,n){return new ee(this,e,t,s,r,i??this.constructor.primaryKey,n??e.primaryKey)}setRelation(e,t){this.relations[e]=t}getRelation(e){return this.relations[e]}relationLoaded(e){return e in this.relations}toJSON(){let e=this.constructor,t={};for(let[s,r]of Object.entries(this.attributes))e.hidden.includes(s)||(t[s]=this.getAttribute(s));for(let[s,r]of Object.entries(this.relations))Array.isArray(r)?t[s]=r.map(i=>i instanceof l?i.toJSON():i):r instanceof l?t[s]=r.toJSON():t[s]=r;return t}toObject(){return this.toJSON()}static hydrate(e){let t=new this;return t.attributes={...e},t.syncOriginal(),t.exists=!0,t}static boot(e){this.hooks.set(this.name,e)}static observe(e){let t=this.observers.get(this.name)??[];t.push(e),this.observers.set(this.name,t)}static removeObservers(){this.observers.delete(this.name)}async fireHook(e){let t=this.constructor,s=l.hooks.get(t.name);s?.[e]&&await s[e](this),typeof this[e]=="function"&&await this[e]();let r=l.observers.get(t.name)??[];for(let n of r){let a=n[e];typeof a=="function"&&await a.call(n,this)}let i=t.name.toLowerCase();await te.emit(`${i}.${e}`,this)}async fireEvent(e){let t=this.constructor;if(!t.events.includes(e))throw new Error(`Event "${e}" is not declared in ${t.name}.events. Add it to: static events = ['${e}', ...];`);let s=l.observers.get(t.name)??[];for(let i of s){let n=i[e];typeof n=="function"&&await n.call(i,this)}let r=t.name.toLowerCase();await te.emit(`${r}.${e}`,this)}syncOriginal(){this.originalAttributes={...this.attributes}}getInsertableAttributes(){let e=this.constructor,t={...this.attributes};return e.incrementing&&t[e.primaryKey]===void 0&&delete t[e.primaryKey],t}static get tableName(){return this.table}}});var kt,pi=y(()=>{"use strict";kt=class{async call(e){await new e().run()}}});var F,hi,ks=y(()=>{"use strict";R();F=class{bindings=new Map;aliases=new Map;resolved=new Set;bind(e,t){this.bindings.set(e,{factory:t,singleton:!1,tags:[]})}singleton(e,t){this.bindings.set(e,{factory:t,singleton:!0,tags:[]})}instance(e,t){this.bindings.set(e,{factory:()=>t,singleton:!0,instance:t,tags:[]})}alias(e,t){this.aliases.set(e,t)}async make(e){let t=this.resolveAlias(e),s=this.bindings.get(t);if(!s)throw new Error(`No binding found for "${e}" in the container.`);if(s.singleton&&s.instance!==void 0)return s.instance;let r=await s.factory(this);return s.singleton&&(s.instance=r),this.resolved.add(t),r}makeSync(e){let t=this.resolveAlias(e),s=this.bindings.get(t);if(!s)throw new Error(`No binding found for "${e}" in the container.`);if(s.singleton&&s.instance!==void 0)return s.instance;let r=s.factory(this);if(r instanceof Promise)throw new Error(`Binding "${e}" has an async factory. Use container.make() instead of container.makeSync().`);return s.singleton&&(s.instance=r),this.resolved.add(t),r}has(e){let t=this.resolveAlias(e);return this.bindings.has(t)}isResolved(e){return this.resolved.has(this.resolveAlias(e))}tag(e,t){for(let s of e){let r=this.bindings.get(s);r&&r.tags.push(t)}}async tagged(e){let t=[];for(let[s,r]of this.bindings)r.tags.includes(e)&&t.push(await this.make(s));return t}flush(){for(let e of this.bindings.values())e.singleton&&(e.instance=void 0);this.resolved.clear()}forget(e){this.bindings.delete(e),this.resolved.delete(e)}getBindings(){return[...this.bindings.keys()]}resolveAlias(e){return this.aliases.get(e)??e}},hi=w("svelar.container",()=>new F)});var $t,gi=y(()=>{"use strict";ks();$t=class{container;providers=[];booted=!1;constructor(e){this.container=e??new F,this.container.instance("app",this),this.container.instance("container",this.container)}register(e){let t=new e(this.container);return this.providers.push(t),this}async bootstrap(){if(this.booted)return this;for(let e of this.providers)await e.register();for(let e of this.providers)await e.boot();return this.booted=!0,this}isBooted(){return this.booted}async make(e){return this.container.make(e)}getProviders(){return[...this.providers]}}});var T,L,At,se,Dt,re,ie,Mt,ne,ae=y(()=>{"use strict";T=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 n of s){let a=this.namedMiddleware.get(n);a&&r.push(a)}let i=t;for(let n=r.length-1;n>=0;n--){let a=r[n],o=i;typeof a.handle=="function"?i=()=>a.handle(e,o):i=()=>a(e,o)}return i()}count(){return this.middleware.length}},At=class extends T{constructor(t={}){super();this.options=t}async handle(t,s){let r=await s();if(!r)return;let i=Array.isArray(this.options.origin)?this.options.origin.join(", "):this.options.origin??"*";return r.headers.set("Access-Control-Allow-Origin",i),r.headers.set("Access-Control-Allow-Methods",(this.options.methods??["GET","POST","PUT","DELETE","PATCH","OPTIONS"]).join(", ")),r.headers.set("Access-Control-Allow-Headers",(this.options.headers??["Content-Type","Authorization"]).join(", ")),this.options.credentials&&r.headers.set("Access-Control-Allow-Credentials","true"),this.options.maxAge&&r.headers.set("Access-Control-Max-Age",String(this.options.maxAge)),t.event.request.method==="OPTIONS"?new Response(null,{status:204,headers:r.headers}):r}},se=class extends T{requests=new Map;maxRequests;windowMs;constructor(e={}){super(),this.maxRequests=e.maxRequests??60,this.windowMs=e.windowMs??6e4}async handle(e,t){let s=e.event.request.headers.get("x-forwarded-for")??e.event.getClientAddress?.()??"unknown",r=Date.now(),i=this.requests.get(s);if(i&&r<i.resetAt){if(i.count>=this.maxRequests)return new Response(JSON.stringify({error:"Too many requests"}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(Math.ceil((i.resetAt-r)/1e3))}});i.count++}else this.requests.set(s,{count:1,resetAt:r+this.windowMs});return t()}},Dt=class extends T{async handle(e,t){let s=Date.now(),r=e.event.request.method,i=e.event.url.pathname,n=await t(),a=Date.now()-s,o=n instanceof Response?n.status:200;return console.log(`[${new Date().toISOString()}] ${r} ${i} \u2192 ${o} (${a}ms)`),n}},re=class extends T{cookieName;headerName;fieldName;excludePaths;onlyPaths;constructor(e={}){super(),this.cookieName=e.cookieName??"XSRF-TOKEN",this.headerName=e.headerName??"X-CSRF-Token",this.fieldName=e.fieldName??"_csrf",this.excludePaths=e.excludePaths??[],this.onlyPaths=e.onlyPaths??null}async handle(e,t){let{event:s}=e,r=s.request.method.toUpperCase();if(["GET","HEAD","OPTIONS"].includes(r))return this.setTokenAndContinue(e,t);if((s.request.headers.get("authorization")??"").startsWith("Bearer "))return t();let n=s.url.pathname;if(this.onlyPaths&&!this.onlyPaths.some(c=>n.startsWith(c)))return this.setTokenAndContinue(e,t);if(this.excludePaths.some(c=>n.startsWith(c)))return t();let a=this.getCookieToken(s),o=s.request.headers.get(this.headerName)??await this.getBodyToken(s);return!a||!o||!this.timingSafeEqual(a,o)?new Response(JSON.stringify({message:"CSRF token mismatch"}),{status:419,headers:{"Content-Type":"application/json"}}):t()}async setTokenAndContinue(e,t){let s=await t();if(!(s instanceof Response))return s;let i=this.getCookieToken(e.event)||this.generateToken();return s.headers.append("Set-Cookie",`${this.cookieName}=${i}; Path=/; SameSite=Lax`),s}getCookieToken(e){let s=(e.request.headers.get("cookie")??"").match(new RegExp(`${this.cookieName}=([^;]+)`));return s?s[1]:null}async getBodyToken(e){try{let t=e.request.headers.get("content-type")??"";if(t.includes("application/x-www-form-urlencoded")||t.includes("multipart/form-data"))return(await e.request.clone().formData()).get(this.fieldName);if(t.includes("application/json"))return(await e.request.clone().json())[this.fieldName]??null}catch{}return null}generateToken(){let e=new Uint8Array(32);return crypto.getRandomValues(e),Array.from(e,t=>t.toString(16).padStart(2,"0")).join("")}timingSafeEqual(e,t){if(e.length!==t.length)return!1;let s=new TextEncoder,r=s.encode(e),i=s.encode(t),n=0;for(let a=0;a<r.length;a++)n|=r[a]^i[a];return n===0}},ie=class extends T{allowedOrigins;constructor(e={}){super(),this.allowedOrigins=new Set(e.allowedOrigins??[])}async handle(e,t){let{event:s}=e,r=s.request.method.toUpperCase();if(["GET","HEAD","OPTIONS"].includes(r)||(s.request.headers.get("authorization")??"").startsWith("Bearer "))return t();let n=s.request.headers.get("origin");if(!n)return t();let a=s.url.origin;return n===a||this.allowedOrigins.has(n)?t():new Response(JSON.stringify({message:"Cross-origin request blocked"}),{status:403,headers:{"Content-Type":"application/json"}})}},Mt=class extends T{secret;tolerance;signatureHeader;timestampHeader;onlyPaths;constructor(e){super(),this.secret=e.secret,this.tolerance=e.tolerance??300,this.signatureHeader=e.signatureHeader??"X-Signature",this.timestampHeader=e.timestampHeader??"X-Timestamp",this.onlyPaths=e.onlyPaths??null}async handle(e,t){let{event:s}=e;if(this.onlyPaths){let C=s.url.pathname;if(!this.onlyPaths.some(k=>C.startsWith(k)))return t()}let r=s.request.headers.get(this.signatureHeader),i=s.request.headers.get(this.timestampHeader);if(!r||!i)return new Response(JSON.stringify({message:"Missing request signature"}),{status:401,headers:{"Content-Type":"application/json"}});let n=parseInt(i,10),a=Math.floor(Date.now()/1e3);if(isNaN(n)||Math.abs(a-n)>this.tolerance)return new Response(JSON.stringify({message:"Request signature expired"}),{status:401,headers:{"Content-Type":"application/json"}});let c=await s.request.clone().text(),{createHmac:u}=await import("crypto"),d=s.request.method.toUpperCase(),p=s.url.pathname+s.url.search,f=`${i}.${d}.${p}.${c}`,b=u("sha256",this.secret).update(f).digest("hex");return r.length!==b.length||!this.timingSafeCompare(r,b)?new Response(JSON.stringify({message:"Invalid request signature"}),{status:401,headers:{"Content-Type":"application/json"}}):t()}timingSafeCompare(e,t){if(e.length!==t.length)return!1;let s=new TextEncoder,r=s.encode(e),i=s.encode(t),n=0;for(let a=0;a<r.length;a++)n|=r[a]^i[a];return n===0}static sign(e,t,s,r,i){let{createHmac:n}=Fe("crypto"),a=i??Math.floor(Date.now()/1e3),o=`${a}.${t.toUpperCase()}.${s}.${r}`;return{signature:n("sha256",e).update(o).digest("hex"),timestamp:a}}},ne=class extends T{attempts=new Map;maxAttempts;decayMinutes;constructor(e={}){super(),this.maxAttempts=e.maxAttempts??5,this.decayMinutes=e.decayMinutes??1}async handle(e,t){let r=`${e.event.request.headers.get("x-forwarded-for")??e.event.getClientAddress?.()??"unknown"}:${e.event.url.pathname}`,i=Date.now(),n=this.attempts.get(r);if(n){if(i<n.blockedUntil){let o=Math.ceil((n.blockedUntil-i)/1e3);return new Response(JSON.stringify({message:"Too many attempts. Please try again later.",retry_after:o}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(o)}})}if(n.count>=this.maxAttempts){n.blockedUntil=i+this.decayMinutes*6e4,n.count=0;let o=this.decayMinutes*60;return new Response(JSON.stringify({message:"Too many attempts. Please try again later.",retry_after:o}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(o)}})}}let a=await t();if(a instanceof Response&&a.status>=400&&a.status<500){let o=this.attempts.get(r)??{count:0,blockedUntil:0};if(o.count++,this.attempts.set(r,o),this.attempts.size>1e4)for(let[c,u]of this.attempts)i>u.blockedUntil+this.decayMinutes*6e4*2&&this.attempts.delete(c)}return a}}});import{z as oe}from"zod";function fi(l,e=!1){let t=new l;return e?{GET:t.handle("show"),PUT:t.handle("update"),PATCH:t.handle("update"),DELETE:t.handle("destroy")}:{GET:t.handle("index"),POST:t.handle("store")}}var Nt,q,Ae,De,Me,yi=y(()=>{"use strict";ae();Nt=class{controllerMiddleware=[];middleware(e,t){let s;typeof e=="function"&&e.prototype instanceof T?s=new e:s=e,this.controllerMiddleware.push({middleware:s,only:t?.only,except:t?.except})}handle(e){return async t=>{try{let s=this.controllerMiddleware.filter(r=>!(r.only&&!r.only.includes(e)||r.except&&r.except.includes(e)));if(s.length>0){let r=new L;for(let{middleware:a}of s)r.use(a);let i={event:t,params:t.params,locals:t.locals},n=await r.execute(i,async()=>this.callMethod(e,t));if(n instanceof Response)return n}return await this.callMethod(e,t)}catch(s){return this.handleError(s,t)}}}json(e,t=200,s={}){let r=JSON.stringify(e,null,2);return new Response(r,{status:t,headers:{"Content-Type":"application/json",...s}})}text(e,t=200){return new Response(e,{status:t,headers:{"Content-Type":"text/plain"}})}html(e,t=200){return new Response(e,{status:t,headers:{"Content-Type":"text/html"}})}redirect(e,t=302){return new Response(null,{status:t,headers:{Location:e}})}noContent(){return new Response(null,{status:204})}created(e){return e?this.json(e,201):new Response(null,{status:201})}async validate(e,t){let s=t instanceof oe.ZodObject?t:oe.object(t),r,i=e.request.headers.get("content-type")??"";if(i.includes("application/json"))r=await e.request.json();else if(i.includes("multipart/form-data")||i.includes("application/x-www-form-urlencoded")){let a=await e.request.formData();r=Object.fromEntries(a)}else r=Object.fromEntries(e.url.searchParams);let n=s.safeParse(r);if(!n.success)throw new q(n.error);return n.data}validateQuery(e,t){let s=t instanceof oe.ZodObject?t:oe.object(t),r=Object.fromEntries(e.url.searchParams),i=s.safeParse(r);if(!i.success)throw new q(i.error);return i.data}validateParams(e,t){let r=(t instanceof oe.ZodObject?t:oe.object(t)).safeParse(e.params);if(!r.success)throw new q(r.error);return r.data}handleError(e,t){return e instanceof q?this.json({message:"Validation failed",errors:e.errors},422):e instanceof Ae?this.json({message:e.message||"Not found"},404):e instanceof De?this.json({message:e.message||"Unauthorized"},401):e instanceof Me?this.json({message:e.message||"Forbidden"},403):(console.error("[Svelar] Controller error:",e),this.json({message:process.env.NODE_ENV==="production"?"Internal server error":e.message},500))}async callMethod(e,t){let s=this[e];if(typeof s!="function")throw new Error(`Method "${e}" not found on controller "${this.constructor.name}".`);let r=await s.call(this,t);return r instanceof Response?r:this.json(r)}};q=class extends Error{errors;constructor(e){super("Validation failed"),this.name="ValidationError",this.errors={};for(let t of e.issues){let s=t.path.join(".");this.errors[s]||(this.errors[s]=[]),this.errors[s].push(t.message)}}},Ae=class extends Error{constructor(e="Not found"){super(e),this.name="NotFoundError"}},De=class extends Error{constructor(e="Unauthorized"){super(e),this.name="UnauthorizedError"}},Me=class extends Error{constructor(e="Forbidden"){super(e),this.name="ForbiddenError"}}});import{randomBytes as Fa,createHmac as vi,timingSafeEqual as Ha}from"crypto";import{promises as U}from"fs";import{join as Ne}from"path";var le,_e,H,_t,It,jt,ce,$s=y(()=>{"use strict";ae();le=class l{constructor(e,t){this.id=e;t&&(this.data={...t},this.data._flash&&(this.previousFlashData=this.data._flash,delete this.data._flash))}data={};dirty=!1;flashData={};previousFlashData={};get(e,t){return e in this.flashData?this.flashData[e]:e in this.previousFlashData?this.previousFlashData[e]:e in this.data?this.data[e]:t}set(e,t){this.data[e]=t,this.dirty=!0}has(e){return e in this.data||e in this.flashData||e in this.previousFlashData}forget(e){delete this.data[e],this.dirty=!0}flush(){this.data={},this.dirty=!0}flash(e,t){this.flashData[e]=t,this.dirty=!0}all(){return{...this.data,...this.previousFlashData,...this.flashData}}isDirty(){return this.dirty||Object.keys(this.flashData).length>0}toPersist(){let e={...this.data};return Object.keys(this.flashData).length>0&&(e._flash=this.flashData),e}regenerateId(){let e=this.id,t=l.generateId();this.id=t,this.dirty=!0;let s=_e.get(e);return s instanceof H&&s.markOldSessionId(e),_e.delete(e),t}static generateId(){return Fa(32).toString("hex")}},_e=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}),_e.set(e,this)}async destroy(e){this.sessions.delete(e),_e.delete(e)}async gc(e){let t=Date.now();for(let[s,r]of this.sessions)t>r.expiresAt&&(this.sessions.delete(s),_e.delete(s))}markOldSessionId(e){this.oldSessionIds.add(e),this.sessions.delete(e)}},_t=class{constructor(e="sessions",t){this.tableName=e;this.connectionName=t}tableEnsured=!1;async ensureTable(){if(!this.tableEnsured)try{let{Connection:e}=await Promise.resolve().then(()=>(x(),P));switch(e.getDriver(this.connectionName)){case"sqlite":await e.raw(`CREATE TABLE IF NOT EXISTS ${this.tableName} (
|
|
41
|
+
ORDER BY created_at ASC LIMIT 1`,[e,s]);if(!r||r.length===0)return null;let i=r[0];await t.raw(`UPDATE ${this.table} SET reserved_at = ?, attempts = attempts + 1 WHERE id = ?`,[s,i.id]);let n=JSON.parse(i.payload),a=this.registry.resolve(n.jobClass,n.payload);return{id:i.id,jobClass:n.jobClass,payload:n.payload,queue:i.queue,attempts:i.attempts+1,maxAttempts:i.max_attempts,availableAt:i.available_at*1e3,createdAt:i.created_at*1e3,job:a}}async size(e="default"){return(await(await this.getConnection()).raw(`SELECT COUNT(*) as count FROM ${this.table} WHERE queue = ? AND reserved_at IS NULL`,[e]))?.[0]?.count??0}async clear(e){let t=await this.getConnection();e?await t.raw(`DELETE FROM ${this.table} WHERE queue = ?`,[e]):await t.raw(`DELETE FROM ${this.table}`,[])}async delete(e){await(await this.getConnection()).raw(`DELETE FROM ${this.table} WHERE id = ?`,[e])}async release(e,t=0){let s=await this.getConnection(),r=Math.floor(Date.now()/1e3)+t;await s.raw(`UPDATE ${this.table} SET reserved_at = NULL, available_at = ? WHERE id = ?`,[r,e])}},St=class{queues=new Map;config;registry;_bullmq=null;constructor(e,t){this.config=e,this.registry=t}async getBullMQ(){if(this._bullmq)return this._bullmq;try{return this._bullmq=await Function('return import("bullmq")')(),this._bullmq}catch{throw new Error("bullmq is required for the Redis queue driver. Install it with: npm install bullmq")}}getRedisConnection(){if(this.config.url){let e=new URL(this.config.url);return{host:e.hostname||"localhost",port:parseInt(e.port)||6379,password:e.password||this.config.password||void 0,db:parseInt(e.pathname?.slice(1)||"0")||this.config.db||0}}return{host:this.config.host??"localhost",port:this.config.port??6379,password:this.config.password,db:this.config.db??0}}async getQueue(e){if(this.queues.has(e))return this.queues.get(e);let t=await this.getBullMQ(),s=this.getRedisConnection(),r=this.config.prefix??"svelar",i=new t.Queue(e,{connection:s,prefix:r,defaultJobOptions:{removeOnComplete:this.config.defaultJobOptions?.removeOnComplete??100,removeOnFail:this.config.defaultJobOptions?.removeOnFail??500}});return this.queues.set(e,i),i}async push(e){let t=await this.getQueue(e.queue),s=Math.max(0,e.availableAt-Date.now());await t.add(e.jobClass,{jobClass:e.jobClass,payload:e.payload},{jobId:e.id,delay:s>0?s:void 0,attempts:e.maxAttempts,backoff:{type:"fixed",delay:(e.job.retryDelay??60)*1e3}})}async pop(e){return null}async size(e="default"){let s=await(await this.getQueue(e)).getJobCounts("waiting","delayed","active");return s.waiting+s.delayed+s.active}async clear(e){if(e)await(await this.getQueue(e)).obliterate({force:!0});else for(let t of this.queues.values())await t.obliterate({force:!0})}async createWorker(e,t,s,r){let i=await this.getBullMQ(),n=this.getRedisConnection(),a=this.config.prefix??"svelar",l=new i.Worker(e,async c=>{let u=c.data,m=t.resolve(u.jobClass,u.payload);m.attempts=c.attemptsMade+1,await m.handle()},{connection:n,prefix:a,concurrency:r?.concurrency??1});return l.on("failed",async(c,u)=>{let m=c?.data;if(m)try{let h=t.resolve(m.jobClass,m.payload);c.attemptsMade>=(c.opts?.attempts??3)&&(h.failed(u),await s.store({id:c.id,jobClass:m.jobClass,payload:m.payload,queue:e,attempts:c.attemptsMade,maxAttempts:c.opts?.attempts??3,availableAt:Date.now(),createdAt:c.timestamp??Date.now(),job:h},u))}catch{console.error("[Queue] Failed to resolve job for failure handler:",u.message)}}),l}},Rs=class{table="svelar_failed_jobs";async getConnection(){let{Connection:e}=await Promise.resolve().then(()=>(x(),P));return e}async store(e,t){try{await(await this.getConnection()).raw(`INSERT INTO ${this.table} (id, queue, job_class, payload, exception, failed_at)
|
|
42
|
+
VALUES (?, ?, ?, ?, ?, ?)`,[crypto.randomUUID(),e.queue,e.jobClass,e.payload,t.stack??t.message,Math.floor(Date.now()/1e3)])}catch{console.error("[Queue] Could not persist failed job (run migration to create svelar_failed_jobs table)")}}async all(){return(await(await this.getConnection()).raw(`SELECT * FROM ${this.table} ORDER BY failed_at DESC`,[])??[]).map(s=>({id:s.id,queue:s.queue,jobClass:s.job_class,payload:s.payload,exception:s.exception,failedAt:s.failed_at}))}async find(e){let s=await(await this.getConnection()).raw(`SELECT * FROM ${this.table} WHERE id = ? LIMIT 1`,[e]);if(!s||s.length===0)return null;let r=s[0];return{id:r.id,queue:r.queue,jobClass:r.job_class,payload:r.payload,exception:r.exception,failedAt:r.failed_at}}async forget(e){return await(await this.getConnection()).raw(`DELETE FROM ${this.table} WHERE id = ?`,[e]),!0}async flush(){let e=await this.getConnection(),s=(await e.raw(`SELECT COUNT(*) as count FROM ${this.table}`,[]))?.[0]?.count??0;return await e.raw(`DELETE FROM ${this.table}`,[]),s}},Ts=class{jobs=new Map;register(e){this.jobs.set(e.name,e)}registerAll(e){for(let t of e)this.register(t)}resolve(e,t){let s=this.jobs.get(e);if(!s)throw new Error(`Job class "${e}" is not registered. Call Queue.register(${e}) in your app bootstrap. Registered jobs: [${[...this.jobs.keys()].join(", ")}]`);let r=Object.create(s.prototype);r.attempts=0,r.maxAttempts=3,r.retryDelay=60,r.queue="default";try{let i=JSON.parse(t);r.restore(i)}catch{}return r}has(e){return this.jobs.has(e)}},Es=class{config={default:"sync",connections:{sync:{driver:"sync"}}};drivers=new Map;processing=!1;jobRegistry=new Ts;failedStore=new Rs;_activeWorker=null;configure(e){this.config=e,this.drivers.clear()}register(e){this.jobRegistry.register(e)}registerAll(e){this.jobRegistry.registerAll(e)}async dispatch(e,t){let s=this.config.default,r=this.config.connections[s],i=this.resolveDriver(s);t?.queue&&(e.queue=t.queue),t?.maxAttempts!==void 0&&(e.maxAttempts=t.maxAttempts);let n={id:crypto.randomUUID(),jobClass:e.constructor.name,payload:e.serialize(),queue:e.queue??r?.queue??"default",attempts:0,maxAttempts:e.maxAttempts,availableAt:Date.now()+(t?.delay??0)*1e3,createdAt:Date.now(),job:e};await i.push(n)}async dispatchSync(e){let t=new Pt,s={id:crypto.randomUUID(),jobClass:e.constructor.name,payload:e.serialize(),queue:e.queue,attempts:0,maxAttempts:e.maxAttempts,availableAt:Date.now(),createdAt:Date.now(),job:e};await t.push(s)}async chain(e,t){if(e.length===0)return;let s=new ks(e);t?.queue&&(s.queue=t.queue),t?.maxAttempts!==void 0&&(s.maxAttempts=t.maxAttempts),await this.dispatch(s,t)}async work(e){let t=this.config.default,s=this.resolveDriver(t),r=e?.queue??"default";if(s instanceof St){let l=await s.createWorker(r,this.jobRegistry,this.failedStore,{concurrency:e?.concurrency??1});return this.processing=!0,this._activeWorker=l,await new Promise(c=>{let u=()=>{this.processing?setTimeout(u,500):l.close().then(c).catch(c)};u()}),0}let i=e?.maxJobs??1/0,n=(e?.sleep??1)*1e3,a=0;for(this.processing=!0;this.processing&&a<i;){let l=await s.pop(r);if(!l){if(i===1/0){await new Promise(c=>setTimeout(c,n));continue}break}l.attempts++,l.job.attempts=l.attempts;try{await l.job.handle(),a++,s instanceof W&&await s.delete(l.id)}catch(c){if(l.attempts<l.maxAttempts){l.job.retrying(l.attempts);let u=l.job.retryDelay??60;s instanceof W?await s.release(l.id,u):(l.availableAt=Date.now()+u*1e3,await s.push(l))}else l.job.failed(c),await this.failedStore.store(l,c),s instanceof W&&await s.delete(l.id)}}return a}async stop(){this.processing=!1,this._activeWorker&&(await this._activeWorker.close(),this._activeWorker=null)}async size(e){return this.resolveDriver(this.config.default).size(e)}async clear(e){return this.resolveDriver(this.config.default).clear(e)}async failed(){return this.failedStore.all()}async retry(e){let t=await this.failedStore.find(e);if(!t)return!1;let s=this.jobRegistry.resolve(t.jobClass,t.payload);return s.queue=t.queue,await this.dispatch(s,{queue:t.queue}),await this.failedStore.forget(e),!0}async retryAll(){let e=await this.failedStore.all(),t=0;for(let s of e)try{let r=this.jobRegistry.resolve(s.jobClass,s.payload);r.queue=s.queue,await this.dispatch(r,{queue:s.queue}),await this.failedStore.forget(s.id),t++}catch{}return t}async forgetFailed(e){return this.failedStore.forget(e)}async flushFailed(){return this.failedStore.flush()}resolveDriver(e){if(this.drivers.has(e))return this.drivers.get(e);let t=this.config.connections[e];if(!t)throw new Error(`Queue connection "${e}" is not defined.`);let s;switch(t.driver){case"sync":s=new Pt;break;case"memory":s=new Ss;break;case"database":s=new W(t.table??"svelar_jobs",this.jobRegistry);break;case"redis":s=new St(t,this.jobRegistry);break;default:throw new Error(`Unknown queue driver: ${t.driver}`)}return this.drivers.set(e,s),s}},ks=class extends J{remainingJobs;constructor(e){super(),this.remainingJobs=[...e],this.maxAttempts=1}async handle(){for(let e of this.remainingJobs){let t=null,s=!1;for(let r=1;r<=e.maxAttempts;r++){e.attempts=r;try{await e.handle(),s=!0;break}catch(i){t=i,r<e.maxAttempts&&(e.retrying(r),e.retryDelay>0&&await new Promise(n=>setTimeout(n,e.retryDelay*1e3)))}}if(!s&&t)throw e.failed(t),new Error(`Chain stopped: ${e.constructor.name} failed after ${e.maxAttempts} attempt(s). Remaining jobs: [${this.remainingJobs.slice(this.remainingJobs.indexOf(e)+1).map(r=>r.constructor.name).join(", ")}]`)}}serialize(){return JSON.stringify({jobs:this.remainingJobs.map(e=>({jobClass:e.constructor.name,payload:e.serialize()}))})}},$s=C("svelar.queue",()=>new Es)});var M,Ds=y(()=>{"use strict";x();M=class o{tableName;selectColumns=["*"];whereClauses=[];joinClauses=[];orderClauses=[];groupByColumns=[];havingClauses=[];limitValue=null;offsetValue=null;eagerLoads=[];isDistinct=!1;connectionName;cteClauses=[];unionClauses=[];modelClass;constructor(e,t,s){this.tableName=e,this.modelClass=t,this.connectionName=s}select(...e){return this.selectColumns=e.length>0?e:["*"],this}addSelect(...e){return this.selectColumns[0]==="*"?this.selectColumns=e:this.selectColumns.push(...e),this}distinct(){return this.isDistinct=!0,this}from(e){return this.tableName=e,this}where(e,t,s){return s===void 0?this.whereClauses.push({type:"basic",column:e,operator:"=",value:t,boolean:"AND"}):this.whereClauses.push({type:"basic",column:e,operator:t,value:s,boolean:"AND"}),this}orWhere(e,t,s){return s===void 0?this.whereClauses.push({type:"basic",column:e,operator:"=",value:t,boolean:"OR"}):this.whereClauses.push({type:"basic",column:e,operator:t,value:s,boolean:"OR"}),this}whereIn(e,t){return this.whereClauses.push({type:"in",column:e,values:t,boolean:"AND"}),this}whereNotIn(e,t){return this.whereClauses.push({type:"notIn",column:e,values:t,boolean:"AND"}),this}whereNull(e){return this.whereClauses.push({type:"null",column:e,boolean:"AND"}),this}whereNotNull(e){return this.whereClauses.push({type:"notNull",column:e,boolean:"AND"}),this}whereBetween(e,t){return this.whereClauses.push({type:"between",column:e,values:t,boolean:"AND"}),this}whereRaw(e,t=[]){return this.whereClauses.push({type:"raw",raw:e,values:t,boolean:"AND"}),this}whereNested(e,t="AND"){let s=new o(this.tableName,this.modelClass,this.connectionName);if(e(s),s.whereClauses.length>0){let{whereSQL:r,whereBindings:i}=s.buildWhere(),n=r.replace(/^WHERE /,"");this.whereClauses.push({type:"raw",raw:`(${n})`,values:i,boolean:t})}return this}orWhereNested(e){return this.whereNested(e,"OR")}whereExists(e){let t=new o("__placeholder__",void 0,this.connectionName);e(t);let{sql:s,bindings:r}=t.toSQL();return this.whereClauses.push({type:"exists",subSQL:s,subBindings:r,boolean:"AND"}),this}whereNotExists(e){let t=new o("__placeholder__",void 0,this.connectionName);e(t);let{sql:s,bindings:r}=t.toSQL();return this.whereClauses.push({type:"notExists",subSQL:s,subBindings:r,boolean:"AND"}),this}whereSub(e,t,s){let r=new o("__placeholder__",void 0,this.connectionName);s(r);let{sql:i,bindings:n}=r.toSQL();return this.whereClauses.push({type:"sub",column:e,operator:t,subSQL:i,subBindings:n,boolean:"AND"}),this}orWhereRaw(e,t=[]){return this.whereClauses.push({type:"raw",raw:e,values:t,boolean:"OR"}),this}orWhereIn(e,t){return this.whereClauses.push({type:"in",column:e,values:t,boolean:"OR"}),this}orWhereNull(e){return this.whereClauses.push({type:"null",column:e,boolean:"OR"}),this}orWhereNotNull(e){return this.whereClauses.push({type:"notNull",column:e,boolean:"OR"}),this}withCTE(e,t,s=!1){let r=new o("__placeholder__",void 0,this.connectionName);t(r);let{sql:i,bindings:n}=r.toSQL();return this.cteClauses.push({name:e,sql:i,bindings:n,recursive:s}),this}withRecursiveCTE(e,t){return this.withCTE(e,t,!0)}withRawCTE(e,t,s=[],r=!1){return this.cteClauses.push({name:e,sql:t,bindings:s,recursive:r}),this}union(e){let t=new o("__placeholder__",void 0,this.connectionName);e(t);let{sql:s,bindings:r}=t.toSQL();return this.unionClauses.push({sql:s,bindings:r,all:!1}),this}unionAll(e){let t=new o("__placeholder__",void 0,this.connectionName);e(t);let{sql:s,bindings:r}=t.toSQL();return this.unionClauses.push({sql:s,bindings:r,all:!0}),this}join(e,t,s,r){return this.joinClauses.push({type:"INNER",table:e,first:t,operator:s,second:r}),this}leftJoin(e,t,s,r){return this.joinClauses.push({type:"LEFT",table:e,first:t,operator:s,second:r}),this}rightJoin(e,t,s,r){return this.joinClauses.push({type:"RIGHT",table:e,first:t,operator:s,second:r}),this}crossJoin(e){return this.joinClauses.push({type:"CROSS",table:e,first:"",operator:"",second:""}),this}orderBy(e,t="asc"){return this.orderClauses.push({column:e,direction:t}),this}latest(e="created_at"){return this.orderBy(e,"desc")}oldest(e="created_at"){return this.orderBy(e,"asc")}groupBy(...e){return this.groupByColumns.push(...e),this}having(e,t,s){return this.havingClauses.push({type:"basic",column:e,operator:t,value:s,boolean:"AND"}),this}limit(e){return this.limitValue=e,this}offset(e){return this.offsetValue=e,this}take(e){return this.limit(e)}skip(e){return this.offset(e)}with(...e){return this.eagerLoads.push(...e),this}async get(){let{sql:e,bindings:t}=this.toSQL(),s=await f.raw(e,t,this.connectionName),r=this.hydrateMany(s);return this.eagerLoads.length>0&&this.modelClass&&await this.loadRelations(r),r}async first(){return this.limitValue=1,(await this.get())[0]??null}async firstOrFail(){let e=await this.first();if(!e)throw new Error(`No results found for query on "${this.tableName}".`);return e}async find(e,t="id"){return this.where(t,e).first()}async findOrFail(e,t="id"){return this.where(t,e).firstOrFail()}async count(e="*"){let{sql:t,bindings:s}=this.buildAggregate(`COUNT(${e})`),r=await f.raw(t,s,this.connectionName);return Number(r[0]?.aggregate??0)}async sum(e){let{sql:t,bindings:s}=this.buildAggregate(`SUM(${e})`),r=await f.raw(t,s,this.connectionName);return Number(r[0]?.aggregate??0)}async avg(e){let{sql:t,bindings:s}=this.buildAggregate(`AVG(${e})`),r=await f.raw(t,s,this.connectionName);return Number(r[0]?.aggregate??0)}async max(e){let{sql:t,bindings:s}=this.buildAggregate(`MAX(${e})`);return(await f.raw(t,s,this.connectionName))[0]?.aggregate??null}async min(e){let{sql:t,bindings:s}=this.buildAggregate(`MIN(${e})`);return(await f.raw(t,s,this.connectionName))[0]?.aggregate??null}async exists(){return await this.count()>0}async doesntExist(){return!await this.exists()}async pluck(e){return this.selectColumns=[e],(await f.raw(this.toSQL().sql,this.toSQL().bindings,this.connectionName)).map(s=>s[e])}async value(e){return this.selectColumns=[e],this.limitValue=1,(await f.raw(this.toSQL().sql,this.toSQL().bindings,this.connectionName))[0]?.[e]??null}async chunk(e,t){let s=1,r=!0;for(;r;){let i=this.clone();i.limitValue=e,i.offsetValue=(s-1)*e;let n=await i.get();if(n.length===0||await t(n,s)===!1||n.length<e)break;s++}}when(e,t){return e&&t(this),this}selectRaw(e){return this.selectColumns[0]==="*"?this.selectColumns=[e]:this.selectColumns.push(e),this}async upsert(e,t,s){let r=f.getDriver(this.connectionName),i=Object.keys(e),n=Object.values(e),a=n.map(()=>"?").join(", "),l=s??i.filter(u=>!t.includes(u)),c;if(r==="postgres"){let u=l.map(m=>`${m} = EXCLUDED.${m}`).join(", ");c=`INSERT INTO ${this.tableName} (${i.join(", ")}) VALUES (${a}) ON CONFLICT (${t.join(", ")}) DO UPDATE SET ${u}`}else if(r==="mysql"){let u=l.map(m=>`${m} = VALUES(${m})`).join(", ");c=`INSERT INTO ${this.tableName} (${i.join(", ")}) VALUES (${a}) ON DUPLICATE KEY UPDATE ${u}`}else{let u=l.map(m=>`${m} = excluded.${m}`).join(", ");c=`INSERT INTO ${this.tableName} (${i.join(", ")}) VALUES (${a}) ON CONFLICT (${t.join(", ")}) DO UPDATE SET ${u}`}return f.raw(c,n,this.connectionName)}async insertMany(e){if(e.length===0)return;let t=Object.keys(e[0]),s=[],r=[];for(let n of e){let a=t.map(l=>n[l]);s.push(...a),r.push(`(${a.map(()=>"?").join(", ")})`)}let i=`INSERT INTO ${this.tableName} (${t.join(", ")}) VALUES ${r.join(", ")}`;return f.raw(i,s,this.connectionName)}async firstOrCreate(e,t={}){for(let[n,a]of Object.entries(e))this.where(n,a);let s=await this.first();if(s)return s;let r={...e,...t},i=await new o(this.tableName,this.modelClass,this.connectionName).insertGetId(r);return new o(this.tableName,this.modelClass,this.connectionName).findOrFail(i)}async updateOrCreate(e,t){let s=new o(this.tableName,this.modelClass,this.connectionName);for(let[a,l]of Object.entries(e))s.where(a,l);let r=await s.first();if(r)return await new o(this.tableName,this.modelClass,this.connectionName).where(this.modelClass?.primaryKey??"id",r[this.modelClass?.primaryKey??"id"]).update(t),new o(this.tableName,this.modelClass,this.connectionName).findOrFail(r[this.modelClass?.primaryKey??"id"]);let i={...e,...t},n=await new o(this.tableName,this.modelClass,this.connectionName).insertGetId(i);return new o(this.tableName,this.modelClass,this.connectionName).findOrFail(n)}whereColumn(e,t,s){return s===void 0?this.whereClauses.push({type:"raw",raw:`${e} = ${t}`,values:[],boolean:"AND"}):this.whereClauses.push({type:"raw",raw:`${e} ${t} ${s}`,values:[],boolean:"AND"}),this}havingRaw(e,t=[]){return this.havingClauses.push({type:"raw",raw:e,values:t,boolean:"AND"}),this}orderByRaw(e){return this.orderClauses.push({column:e,direction:"asc"}),this.orderClauses[this.orderClauses.length-1].__raw=!0,this}selectSub(e,t){let s=new o("__placeholder__",void 0,this.connectionName);e(s);let{sql:r,bindings:i}=s.toSQL(),n=`(${r}) as ${t}`;return this.selectColumns[0]==="*"?this.selectColumns=[n]:this.selectColumns.push(n),this._selectBindings||(this._selectBindings=[]),this._selectBindings.push(...i),this}_selectBindings;async truncate(){f.getDriver(this.connectionName)==="sqlite"?(await f.raw(`DELETE FROM ${this.tableName}`,[],this.connectionName),await f.raw("DELETE FROM sqlite_sequence WHERE name = ?",[this.tableName],this.connectionName)):await f.raw(`TRUNCATE TABLE ${this.tableName}`,[],this.connectionName)}async paginate(e=1,t=15){let s=await this.clone().count(),r=Math.ceil(s/t);return this.limitValue=t,this.offsetValue=(e-1)*t,{data:await this.get(),total:s,page:e,perPage:t,lastPage:r,hasMore:e<r}}async insert(e){let t=Object.keys(e),s=Object.values(e),r=s.map(()=>"?").join(", "),i=`INSERT INTO ${this.tableName} (${t.join(", ")}) VALUES (${r})`;return f.raw(i,s,this.connectionName)}async insertGetId(e,t="id"){let s=f.getDriver(this.connectionName),r=Object.keys(e),i=Object.values(e),n=i.map(()=>"?").join(", "),a=`INSERT INTO ${this.tableName} (${r.join(", ")}) VALUES (${n})`;return s==="postgres"?(a+=` RETURNING ${t}`,(await f.raw(a,i,this.connectionName))[0]?.[t]):(await f.raw(a,i,this.connectionName),s==="sqlite"?(await f.raw("SELECT last_insert_rowid() as id",[],this.connectionName))[0]?.id:s==="mysql"?(await f.raw("SELECT LAST_INSERT_ID() as id",[],this.connectionName))[0]?.id:0)}async update(e){let t=Object.keys(e),s=Object.values(e),r=t.map(l=>`${l} = ?`).join(", "),{whereSQL:i,whereBindings:n}=this.buildWhere(),a=`UPDATE ${this.tableName} SET ${r}${i}`;return await f.raw(a,[...s,...n],this.connectionName),1}async delete(){let{whereSQL:e,whereBindings:t}=this.buildWhere(),s=`DELETE FROM ${this.tableName}${e}`;return await f.raw(s,t,this.connectionName),1}async increment(e,t=1){let{whereSQL:s,whereBindings:r}=this.buildWhere(),i=`UPDATE ${this.tableName} SET ${e} = ${e} + ?${s}`;await f.raw(i,[t,...r],this.connectionName)}async decrement(e,t=1){return this.increment(e,-t)}toSQL(){let e=[],t=[];if(this.cteClauses.length>0){let a=this.cteClauses.some(c=>c.recursive)?"WITH RECURSIVE":"WITH",l=this.cteClauses.map(c=>(t.push(...c.bindings),`${c.name} AS (${c.sql})`));e.push(`${a} ${l.join(", ")}`)}this._selectBindings?.length&&t.push(...this._selectBindings);let s=this.isDistinct?"DISTINCT ":"";e.push(`SELECT ${s}${this.selectColumns.join(", ")}`),e.push(`FROM ${this.tableName}`);for(let n of this.joinClauses)n.type==="CROSS"?e.push(`CROSS JOIN ${n.table}`):e.push(`${n.type} JOIN ${n.table} ON ${n.first} ${n.operator} ${n.second}`);let{whereSQL:r,whereBindings:i}=this.buildWhere();if(r&&(e.push(r.trim()),t.push(...i)),this.groupByColumns.length>0&&e.push(`GROUP BY ${this.groupByColumns.join(", ")}`),this.havingClauses.length>0){let n=[];for(let a of this.havingClauses)a.type==="raw"?(n.push(a.raw),a.values&&t.push(...a.values)):(n.push(`${a.column} ${a.operator} ?`),t.push(a.value));e.push(`HAVING ${n.join(" AND ")}`)}if(this.orderClauses.length>0){let n=this.orderClauses.map(a=>a.__raw?a.column:`${a.column} ${a.direction.toUpperCase()}`);e.push(`ORDER BY ${n.join(", ")}`)}if(this.limitValue!==null&&e.push(`LIMIT ${this.limitValue}`),this.offsetValue!==null&&e.push(`OFFSET ${this.offsetValue}`),this.unionClauses.length>0)for(let n of this.unionClauses)e.push(n.all?"UNION ALL":"UNION"),e.push(n.sql),t.push(...n.bindings);return{sql:e.join(" "),bindings:t}}clone(){let e=new o(this.tableName,this.modelClass,this.connectionName);return e.selectColumns=[...this.selectColumns],e.whereClauses=[...this.whereClauses],e.joinClauses=[...this.joinClauses],e.orderClauses=[...this.orderClauses],e.groupByColumns=[...this.groupByColumns],e.havingClauses=[...this.havingClauses],e.limitValue=this.limitValue,e.offsetValue=this.offsetValue,e.eagerLoads=[...this.eagerLoads],e.isDistinct=this.isDistinct,e.cteClauses=[...this.cteClauses],e.unionClauses=[...this.unionClauses],e}buildWhere(){if(this.whereClauses.length===0)return{whereSQL:"",whereBindings:[]};let e=[],t=[];for(let s=0;s<this.whereClauses.length;s++){let r=this.whereClauses[s],i=s===0?"WHERE":r.boolean;switch(r.type){case"basic":if((r.operator==="IS"||r.operator==="IS NOT")&&r.value===null){let l=(r.operator==="IS","null");e.push(`${i} ${r.column} ${r.operator} ${l}`)}else e.push(`${i} ${r.column} ${r.operator} ?`),t.push(r.value);break;case"in":let n=r.values.map(()=>"?").join(", ");e.push(`${i} ${r.column} IN (${n})`),t.push(...r.values);break;case"notIn":let a=r.values.map(()=>"?").join(", ");e.push(`${i} ${r.column} NOT IN (${a})`),t.push(...r.values);break;case"null":e.push(`${i} ${r.column} IS NULL`);break;case"notNull":e.push(`${i} ${r.column} IS NOT NULL`);break;case"between":e.push(`${i} ${r.column} BETWEEN ? AND ?`),t.push(r.values[0],r.values[1]);break;case"raw":e.push(`${i} ${r.raw}`),r.values&&t.push(...r.values);break;case"exists":e.push(`${i} EXISTS (${r.subSQL})`),r.subBindings&&t.push(...r.subBindings);break;case"notExists":e.push(`${i} NOT EXISTS (${r.subSQL})`),r.subBindings&&t.push(...r.subBindings);break;case"sub":e.push(`${i} ${r.column} ${r.operator} (${r.subSQL})`),r.subBindings&&t.push(...r.subBindings);break}}return{whereSQL:e.join(" "),whereBindings:t}}buildAggregate(e){let t=this.selectColumns;this.selectColumns=[`${e} as aggregate`];let s=this.toSQL();return this.selectColumns=t,s}hydrateMany(e){return this.modelClass?e.map(t=>this.modelClass.hydrate(t)):e}async loadRelations(e){if(!(!this.modelClass||e.length===0))for(let t of this.eagerLoads){let r=new this.modelClass()[t]?.();r&&typeof r.eagerLoad=="function"&&await r.eagerLoad(e,t)}}}});var Q,G,Y,Z,X,As=y(()=>{"use strict";x();Q=class{parentModel;relatedModel;constructor(e,t){this.parentModel=e,this.relatedModel=t}query(){return this.relatedModel.query()}},G=class extends Q{constructor(t,s,r,i="id"){super(t,s);this.foreignKey=r;this.localKey=i}async load(t){let s=t.getAttribute(this.localKey);return this.relatedModel.query().where(this.foreignKey,s).first()}async eagerLoad(t,s){let r=t.map(a=>a.getAttribute(this.localKey)),i=await this.relatedModel.query().whereIn(this.foreignKey,r).get(),n=new Map;for(let a of i)n.set(a.getAttribute(this.foreignKey),a);for(let a of t){let l=a.getAttribute(this.localKey);a.setRelation(s,n.get(l)??null)}}async create(t){let s=this.parentModel.getAttribute(this.localKey);return this.relatedModel.create({...t,[this.foreignKey]:s})}},Y=class extends Q{constructor(t,s,r,i="id"){super(t,s);this.foreignKey=r;this.localKey=i}async load(t){let s=t.getAttribute(this.localKey);return this.relatedModel.query().where(this.foreignKey,s).get()}async eagerLoad(t,s){let r=t.map(a=>a.getAttribute(this.localKey)),i=await this.relatedModel.query().whereIn(this.foreignKey,r).get(),n=new Map;for(let a of i){let l=a.getAttribute(this.foreignKey);n.has(l)||n.set(l,[]),n.get(l).push(a)}for(let a of t){let l=a.getAttribute(this.localKey);a.setRelation(s,n.get(l)??[])}}async create(t){let s=this.parentModel.getAttribute(this.localKey);return this.relatedModel.create({...t,[this.foreignKey]:s})}async createMany(t){let s=[];for(let r of t)s.push(await this.create(r));return s}},Z=class extends Q{constructor(t,s,r,i="id"){super(t,s);this.foreignKey=r;this.ownerKey=i}async load(t){let s=t.getAttribute(this.foreignKey);return s==null?null:this.relatedModel.query().where(this.ownerKey,s).first()}async eagerLoad(t,s){let r=t.map(a=>a.getAttribute(this.foreignKey)).filter(a=>a!=null);if(r.length===0){for(let a of t)a.setRelation(s,null);return}let i=await this.relatedModel.query().whereIn(this.ownerKey,r).get(),n=new Map;for(let a of i)n.set(a.getAttribute(this.ownerKey),a);for(let a of t){let l=a.getAttribute(this.foreignKey);a.setRelation(s,n.get(l)??null)}}associate(t){return this.parentModel.setAttribute(this.foreignKey,t.getAttribute(this.ownerKey)),this.parentModel}dissociate(){return this.parentModel.setAttribute(this.foreignKey,null),this.parentModel}},X=class extends Q{constructor(t,s,r,i,n,a="id",l="id"){super(t,s);this.pivotTable=r;this.foreignPivotKey=i;this.relatedPivotKey=n;this.parentKey=a;this.relatedKey=l}async load(t){let s=t.getAttribute(this.parentKey),r=this.relatedModel.tableName,n=(await f.raw(`SELECT ${this.relatedPivotKey} FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ?`,[s])).map(a=>a[this.relatedPivotKey]);return n.length===0?[]:this.relatedModel.query().whereIn(this.relatedKey,n).get()}async eagerLoad(t,s){let r=t.map(m=>m.getAttribute(this.parentKey));if(r.length===0){for(let m of t)m.setRelation(s,[]);return}let i=r.map(()=>"?").join(", "),n=await f.raw(`SELECT * FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} IN (${i})`,r),a=[...new Set(n.map(m=>m[this.relatedPivotKey]))],l=a.length>0?await this.relatedModel.query().whereIn(this.relatedKey,a).get():[],c=new Map;for(let m of l)c.set(m.getAttribute(this.relatedKey),m);let u=new Map;for(let m of n){let h=m[this.foreignPivotKey],d=m[this.relatedPivotKey],b=c.get(d);b&&(u.has(h)||u.set(h,[]),u.get(h).push(b))}for(let m of t){let h=m.getAttribute(this.parentKey);m.setRelation(s,u.get(h)??[])}}async attach(t,s){let r=this.parentModel.getAttribute(this.parentKey),i={[this.foreignPivotKey]:r,[this.relatedPivotKey]:t,...s},n=Object.keys(i),a=Object.values(i),l=a.map(()=>"?").join(", ");await f.raw(`INSERT INTO ${this.pivotTable} (${n.join(", ")}) VALUES (${l})`,a)}async detach(t){let s=this.parentModel.getAttribute(this.parentKey);t?await f.raw(`DELETE FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ? AND ${this.relatedPivotKey} = ?`,[s,t]):await f.raw(`DELETE FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ?`,[s])}async sync(t){await this.detach();for(let s of t)await this.attach(s)}async toggle(t){let s=this.parentModel.getAttribute(this.parentKey);for(let r of t)(await f.raw(`SELECT 1 FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ? AND ${this.relatedPivotKey} = ? LIMIT 1`,[s,r])).length>0?await this.detach(r):await this.attach(r)}}});var Xr=y(()=>{"use strict"});var Ee,Ms=y(()=>{"use strict";Ee=class{app;constructor(e){this.app=e}boot(){}}});var ei=y(()=>{"use strict";Ms();$t()});var ke,ee,$t=y(()=>{"use strict";R();Xr();ei();ke=class{listeners=new Map;wildcardListeners=[];onceListeners=new Map;listen(e,t){let s=typeof e=="string"?e:e.name;return this.listeners.has(s)||this.listeners.set(s,[]),this.listeners.get(s).push(t),()=>{let r=this.listeners.get(s);if(r){let i=r.indexOf(t);i>=0&&r.splice(i,1)}}}once(e,t){let s=typeof e=="string"?e:e.name;return this.onceListeners.has(s)||this.onceListeners.set(s,[]),this.onceListeners.get(s).push(t),()=>{let r=this.onceListeners.get(s);if(r){let i=r.indexOf(t);i>=0&&r.splice(i,1)}}}onAny(e){return this.wildcardListeners.push(e),()=>{let t=this.wildcardListeners.indexOf(e);t>=0&&this.wildcardListeners.splice(t,1)}}async dispatch(e){let t=e.constructor.name,s=this.listeners.get(t)??[];for(let i of s)await i(e);let r=this.onceListeners.get(t)??[];for(let i of r)await i(e);this.onceListeners.delete(t);for(let i of this.wildcardListeners)await i(t,e)}async emit(e,t){let s=this.listeners.get(e)??[];for(let i of s)await i(t);let r=this.onceListeners.get(e)??[];for(let i of r)await i(t);this.onceListeners.delete(e);for(let i of this.wildcardListeners)await i(e,t)}subscribe(e){e.subscribe(this)}forget(e){let t=typeof e=="string"?e:e.name;this.listeners.delete(t),this.onceListeners.delete(t)}flush(){this.listeners.clear(),this.onceListeners.clear(),this.wildcardListeners=[]}hasListeners(e){let t=typeof e=="string"?e:e.name;return(this.listeners.get(t)?.length??0)>0||(this.onceListeners.get(t)?.length??0)>0||this.wildcardListeners.length>0}listenerCount(e){let t=typeof e=="string"?e:e.name;return(this.listeners.get(t)?.length??0)+(this.onceListeners.get(t)?.length??0)}},ee=C("svelar.event",()=>new ke)});var Dt,ti=y(()=>{"use strict";Ds();As();$t();Dt=class o{static table;static primaryKey="id";static incrementing=!0;static timestamps=!0;static createdAt="created_at";static updatedAt="updated_at";static casts={};static fillable=[];static hidden=[];static connection=void 0;static hooks=new Map;static observers=new Map;static events=[];attributes={};originalAttributes={};relations={};exists=!1;constructor(e){return e&&this.fill(e),new Proxy(this,{get(t,s,r){return typeof s=="symbol"||s in t||typeof s!="string"||["table","primaryKey","incrementing","timestamps","casts","fillable","hidden","connection"].includes(s)?Reflect.get(t,s,r):typeof t[s]=="function"?t[s].bind(t):t.getAttribute(s)},set(t,s,r){return typeof s=="symbol"||s in t?Reflect.set(t,s,r):(t.setAttribute(s,r),!0)}})}static query(){let e=new this,t=this;return new M(t.table,this,t.connection)}static async find(e){let t=this;return this.query().find(e,t.primaryKey)}static async findOrFail(e){let t=this;return this.query().findOrFail(e,t.primaryKey)}static async all(){return this.query().get()}static async first(){return this.query().first()}static async firstOrFail(){return this.query().firstOrFail()}static where(e,t,s){return this.query().where(e,t,s)}static whereIn(e,t){return this.query().whereIn(e,t)}static whereNull(e){return this.query().whereNull(e)}static whereNotNull(e){return this.query().whereNotNull(e)}static orderBy(e,t){return this.query().orderBy(e,t)}static latest(e){return this.query().latest(e)}static oldest(e){return this.query().oldest(e)}static with(...e){return this.query().with(...e)}static async count(){return this.query().count()}static async create(e){let t=new this,s=this;if(t.fill(e),await t.fireHook("creating"),await t.fireHook("saving"),s.timestamps){let a=new Date().toISOString();t.setAttribute(s.createdAt,a),t.setAttribute(s.updatedAt,a)}let r=t.getInsertableAttributes(),n=await new M(s.table,this,s.connection).insertGetId(r,s.primaryKey);return s.incrementing&&n&&t.setAttribute(s.primaryKey,n),t.syncOriginal(),t.exists=!0,await t.fireHook("created"),await t.fireHook("saved"),t}async save(){let e=this.constructor;if(this.exists){await this.fireHook("updating"),await this.fireHook("saving"),e.timestamps&&this.setAttribute(e.updatedAt,new Date().toISOString());let t=this.getDirty();if(Object.keys(t).length>0){let s=this.getAttribute(e.primaryKey);await new M(e.table,this.constructor,e.connection).where(e.primaryKey,s).update(t)}this.syncOriginal(),await this.fireHook("updated"),await this.fireHook("saved")}else{if(await this.fireHook("creating"),await this.fireHook("saving"),e.timestamps){let i=new Date().toISOString();this.getAttribute(e.createdAt)||this.setAttribute(e.createdAt,i),this.setAttribute(e.updatedAt,i)}let t=this.getInsertableAttributes(),r=await new M(e.table,this.constructor,e.connection).insertGetId(t,e.primaryKey);e.incrementing&&r&&this.setAttribute(e.primaryKey,r),this.syncOriginal(),this.exists=!0,await this.fireHook("created"),await this.fireHook("saved")}}async update(e){this.fill(e),await this.save()}async delete(){let e=this.constructor;await this.fireHook("deleting");let t=this.getAttribute(e.primaryKey);await new M(e.table,this.constructor,e.connection).where(e.primaryKey,t).delete(),this.exists=!1,await this.fireHook("deleted")}async refresh(){let e=this.constructor,t=this.getAttribute(e.primaryKey),s=await this.constructor.find(t);s&&(this.attributes={...s.attributes},this.syncOriginal())}getAttribute(e){let t=this.constructor,s=this.attributes[e],r=t.casts[e];if(r&&s!==void 0&&s!==null)switch(r){case"number":return Number(s);case"boolean":return!!s;case"string":return String(s);case"date":return new Date(s);case"json":return typeof s=="string"?JSON.parse(s):s}return s}setAttribute(e,t){this.constructor.casts[e]==="json"&&typeof t!="string"?this.attributes[e]=JSON.stringify(t):this.attributes[e]=t}fill(e){let t=this.constructor;for(let[s,r]of Object.entries(e))t.fillable.length>0&&!t.fillable.includes(s)||this.setAttribute(s,r)}getAttributes(){return{...this.attributes}}getOriginal(e){return e?this.originalAttributes[e]:{...this.originalAttributes}}getDirty(){let e={};for(let[t,s]of Object.entries(this.attributes))s!==this.originalAttributes[t]&&(e[t]=s);return e}isDirty(...e){let t=this.getDirty();return e.length===0?Object.keys(t).length>0:e.some(s=>s in t)}isClean(...e){return!this.isDirty(...e)}wasChanged(...e){return this.isDirty(...e)}hasOne(e,t,s){return new G(this,e,t,s??this.constructor.primaryKey)}hasMany(e,t,s){return new Y(this,e,t,s??this.constructor.primaryKey)}belongsTo(e,t,s){return new Z(this,e,t,s??e.primaryKey)}belongsToMany(e,t,s,r,i,n){return new X(this,e,t,s,r,i??this.constructor.primaryKey,n??e.primaryKey)}setRelation(e,t){this.relations[e]=t}getRelation(e){return this.relations[e]}relationLoaded(e){return e in this.relations}toJSON(){let e=this.constructor,t={};for(let[s,r]of Object.entries(this.attributes))e.hidden.includes(s)||(t[s]=this.getAttribute(s));for(let[s,r]of Object.entries(this.relations))Array.isArray(r)?t[s]=r.map(i=>i instanceof o?i.toJSON():i):r instanceof o?t[s]=r.toJSON():t[s]=r;return t}toObject(){return this.toJSON()}static hydrate(e){let t=new this;return t.attributes={...e},t.syncOriginal(),t.exists=!0,t}static boot(e){this.hooks.set(this.name,e)}static observe(e){let t=this.observers.get(this.name)??[];t.push(e),this.observers.set(this.name,t)}static removeObservers(){this.observers.delete(this.name)}async fireHook(e){let t=this.constructor,s=o.hooks.get(t.name);s?.[e]&&await s[e](this),typeof this[e]=="function"&&await this[e]();let r=o.observers.get(t.name)??[];for(let n of r){let a=n[e];typeof a=="function"&&await a.call(n,this)}let i=t.name.toLowerCase();await ee.emit(`${i}.${e}`,this)}async fireEvent(e){let t=this.constructor;if(!t.events.includes(e))throw new Error(`Event "${e}" is not declared in ${t.name}.events. Add it to: static events = ['${e}', ...];`);let s=o.observers.get(t.name)??[];for(let i of s){let n=i[e];typeof n=="function"&&await n.call(i,this)}let r=t.name.toLowerCase();await ee.emit(`${r}.${e}`,this)}syncOriginal(){this.originalAttributes={...this.attributes}}getInsertableAttributes(){let e=this.constructor,t={...this.attributes};return e.incrementing&&t[e.primaryKey]===void 0&&delete t[e.primaryKey],t}static get tableName(){return this.table}}});var At,si=y(()=>{"use strict";At=class{async call(e){await new e().run()}}});var F,ri,Ls=y(()=>{"use strict";R();F=class{bindings=new Map;aliases=new Map;resolved=new Set;bind(e,t){this.bindings.set(e,{factory:t,singleton:!1,tags:[]})}singleton(e,t){this.bindings.set(e,{factory:t,singleton:!0,tags:[]})}instance(e,t){this.bindings.set(e,{factory:()=>t,singleton:!0,instance:t,tags:[]})}alias(e,t){this.aliases.set(e,t)}async make(e){let t=this.resolveAlias(e),s=this.bindings.get(t);if(!s)throw new Error(`No binding found for "${e}" in the container.`);if(s.singleton&&s.instance!==void 0)return s.instance;let r=await s.factory(this);return s.singleton&&(s.instance=r),this.resolved.add(t),r}makeSync(e){let t=this.resolveAlias(e),s=this.bindings.get(t);if(!s)throw new Error(`No binding found for "${e}" in the container.`);if(s.singleton&&s.instance!==void 0)return s.instance;let r=s.factory(this);if(r instanceof Promise)throw new Error(`Binding "${e}" has an async factory. Use container.make() instead of container.makeSync().`);return s.singleton&&(s.instance=r),this.resolved.add(t),r}has(e){let t=this.resolveAlias(e);return this.bindings.has(t)}isResolved(e){return this.resolved.has(this.resolveAlias(e))}tag(e,t){for(let s of e){let r=this.bindings.get(s);r&&r.tags.push(t)}}async tagged(e){let t=[];for(let[s,r]of this.bindings)r.tags.includes(e)&&t.push(await this.make(s));return t}flush(){for(let e of this.bindings.values())e.singleton&&(e.instance=void 0);this.resolved.clear()}forget(e){this.bindings.delete(e),this.resolved.delete(e)}getBindings(){return[...this.bindings.keys()]}resolveAlias(e){return this.aliases.get(e)??e}},ri=C("svelar.container",()=>new F)});var Mt,ii=y(()=>{"use strict";Ls();Mt=class{container;providers=[];booted=!1;constructor(e){this.container=e??new F,this.container.instance("app",this),this.container.instance("container",this.container)}register(e){let t=new e(this.container);return this.providers.push(t),this}async bootstrap(){if(this.booted)return this;for(let e of this.providers)await e.register();for(let e of this.providers)await e.boot();return this.booted=!0,this}isBooted(){return this.booted}async make(e){return this.container.make(e)}getProviders(){return[...this.providers]}}});var T,O,Lt,te,_t,se,re,Nt,ie,ne=y(()=>{"use strict";T=class{},O=class{middleware=[];namedMiddleware=new Map;use(e){return typeof e=="function"&&"prototype"in e&&typeof e.prototype?.handle=="function"?this.middleware.push(new e):this.middleware.push(e),this}register(e,t){return typeof t=="function"&&"prototype"in t&&typeof t.prototype?.handle=="function"?this.namedMiddleware.set(e,new t):this.namedMiddleware.set(e,t),this}get(e){return this.namedMiddleware.get(e)}async execute(e,t,s){let r=[...this.middleware];if(s)for(let n of s){let a=this.namedMiddleware.get(n);a&&r.push(a)}let i=t;for(let n=r.length-1;n>=0;n--){let a=r[n],l=i;typeof a.handle=="function"?i=()=>a.handle(e,l):i=()=>a(e,l)}return i()}count(){return this.middleware.length}},Lt=class extends T{constructor(t={}){super();this.options=t}async handle(t,s){let r=await s();if(!r)return;let i=Array.isArray(this.options.origin)?this.options.origin.join(", "):this.options.origin??"*";return r.headers.set("Access-Control-Allow-Origin",i),r.headers.set("Access-Control-Allow-Methods",(this.options.methods??["GET","POST","PUT","DELETE","PATCH","OPTIONS"]).join(", ")),r.headers.set("Access-Control-Allow-Headers",(this.options.headers??["Content-Type","Authorization"]).join(", ")),this.options.credentials&&r.headers.set("Access-Control-Allow-Credentials","true"),this.options.maxAge&&r.headers.set("Access-Control-Max-Age",String(this.options.maxAge)),t.event.request.method==="OPTIONS"?new Response(null,{status:204,headers:r.headers}):r}},te=class extends T{requests=new Map;maxRequests;windowMs;constructor(e={}){super(),this.maxRequests=e.maxRequests??60,this.windowMs=e.windowMs??6e4}async handle(e,t){let s=e.event.request.headers.get("x-forwarded-for")??e.event.getClientAddress?.()??"unknown",r=Date.now(),i=this.requests.get(s);if(i&&r<i.resetAt){if(i.count>=this.maxRequests)return new Response(JSON.stringify({error:"Too many requests"}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(Math.ceil((i.resetAt-r)/1e3))}});i.count++}else this.requests.set(s,{count:1,resetAt:r+this.windowMs});return t()}},_t=class extends T{async handle(e,t){let s=Date.now(),r=e.event.request.method,i=e.event.url.pathname,n=await t(),a=Date.now()-s,l=n instanceof Response?n.status:200;return console.log(`[${new Date().toISOString()}] ${r} ${i} \u2192 ${l} (${a}ms)`),n}},se=class extends T{cookieName;headerName;fieldName;excludePaths;onlyPaths;constructor(e={}){super(),this.cookieName=e.cookieName??"XSRF-TOKEN",this.headerName=e.headerName??"X-CSRF-Token",this.fieldName=e.fieldName??"_csrf",this.excludePaths=e.excludePaths??[],this.onlyPaths=e.onlyPaths??null}async handle(e,t){let{event:s}=e,r=s.request.method.toUpperCase();if(["GET","HEAD","OPTIONS"].includes(r))return this.setTokenAndContinue(e,t);if((s.request.headers.get("authorization")??"").startsWith("Bearer "))return t();let n=s.url.pathname;if(this.onlyPaths&&!this.onlyPaths.some(c=>n.startsWith(c)))return this.setTokenAndContinue(e,t);if(this.excludePaths.some(c=>n.startsWith(c)))return t();let a=this.getCookieToken(s),l=s.request.headers.get(this.headerName)??await this.getBodyToken(s);return!a||!l||!this.timingSafeEqual(a,l)?new Response(JSON.stringify({message:"CSRF token mismatch"}),{status:419,headers:{"Content-Type":"application/json"}}):t()}async setTokenAndContinue(e,t){let s=await t();if(!(s instanceof Response))return s;let i=this.getCookieToken(e.event)||this.generateToken();return s.headers.append("Set-Cookie",`${this.cookieName}=${i}; Path=/; SameSite=Lax`),s}getCookieToken(e){let s=(e.request.headers.get("cookie")??"").match(new RegExp(`${this.cookieName}=([^;]+)`));return s?s[1]:null}async getBodyToken(e){try{let t=e.request.headers.get("content-type")??"";if(t.includes("application/x-www-form-urlencoded")||t.includes("multipart/form-data"))return(await e.request.clone().formData()).get(this.fieldName);if(t.includes("application/json"))return(await e.request.clone().json())[this.fieldName]??null}catch{}return null}generateToken(){let e=new Uint8Array(32);return crypto.getRandomValues(e),Array.from(e,t=>t.toString(16).padStart(2,"0")).join("")}timingSafeEqual(e,t){if(e.length!==t.length)return!1;let s=new TextEncoder,r=s.encode(e),i=s.encode(t),n=0;for(let a=0;a<r.length;a++)n|=r[a]^i[a];return n===0}},re=class extends T{allowedOrigins;constructor(e={}){super(),this.allowedOrigins=new Set(e.allowedOrigins??[])}async handle(e,t){let{event:s}=e,r=s.request.method.toUpperCase();if(["GET","HEAD","OPTIONS"].includes(r)||(s.request.headers.get("authorization")??"").startsWith("Bearer "))return t();let n=s.request.headers.get("origin");if(!n)return t();let a=s.url.origin;return n===a||this.allowedOrigins.has(n)?t():new Response(JSON.stringify({message:"Cross-origin request blocked"}),{status:403,headers:{"Content-Type":"application/json"}})}},Nt=class extends T{secret;tolerance;signatureHeader;timestampHeader;onlyPaths;constructor(e){super(),this.secret=e.secret,this.tolerance=e.tolerance??300,this.signatureHeader=e.signatureHeader??"X-Signature",this.timestampHeader=e.timestampHeader??"X-Timestamp",this.onlyPaths=e.onlyPaths??null}async handle(e,t){let{event:s}=e;if(this.onlyPaths){let w=s.url.pathname;if(!this.onlyPaths.some(E=>w.startsWith(E)))return t()}let r=s.request.headers.get(this.signatureHeader),i=s.request.headers.get(this.timestampHeader);if(!r||!i)return new Response(JSON.stringify({message:"Missing request signature"}),{status:401,headers:{"Content-Type":"application/json"}});let n=parseInt(i,10),a=Math.floor(Date.now()/1e3);if(isNaN(n)||Math.abs(a-n)>this.tolerance)return new Response(JSON.stringify({message:"Request signature expired"}),{status:401,headers:{"Content-Type":"application/json"}});let c=await s.request.clone().text(),{createHmac:u}=await import("crypto"),m=s.request.method.toUpperCase(),h=s.url.pathname+s.url.search,d=`${i}.${m}.${h}.${c}`,b=u("sha256",this.secret).update(d).digest("hex");return r.length!==b.length||!this.timingSafeCompare(r,b)?new Response(JSON.stringify({message:"Invalid request signature"}),{status:401,headers:{"Content-Type":"application/json"}}):t()}timingSafeCompare(e,t){if(e.length!==t.length)return!1;let s=new TextEncoder,r=s.encode(e),i=s.encode(t),n=0;for(let a=0;a<r.length;a++)n|=r[a]^i[a];return n===0}static sign(e,t,s,r,i){let{createHmac:n}=ze("crypto"),a=i??Math.floor(Date.now()/1e3),l=`${a}.${t.toUpperCase()}.${s}.${r}`;return{signature:n("sha256",e).update(l).digest("hex"),timestamp:a}}},ie=class extends T{attempts=new Map;maxAttempts;decayMinutes;constructor(e={}){super(),this.maxAttempts=e.maxAttempts??5,this.decayMinutes=e.decayMinutes??1}async handle(e,t){let r=`${e.event.request.headers.get("x-forwarded-for")??e.event.getClientAddress?.()??"unknown"}:${e.event.url.pathname}`,i=Date.now(),n=this.attempts.get(r);if(n){if(i<n.blockedUntil){let l=Math.ceil((n.blockedUntil-i)/1e3);return new Response(JSON.stringify({message:"Too many attempts. Please try again later.",retry_after:l}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(l)}})}if(n.count>=this.maxAttempts){n.blockedUntil=i+this.decayMinutes*6e4,n.count=0;let l=this.decayMinutes*60;return new Response(JSON.stringify({message:"Too many attempts. Please try again later.",retry_after:l}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(l)}})}}let a=await t();if(a instanceof Response&&a.status>=400&&a.status<500){let l=this.attempts.get(r)??{count:0,blockedUntil:0};if(l.count++,this.attempts.set(r,l),this.attempts.size>1e4)for(let[c,u]of this.attempts)i>u.blockedUntil+this.decayMinutes*6e4*2&&this.attempts.delete(c)}return a}}});import{z as ae}from"zod";function ni(o,e=!1){let t=new o;return e?{GET:t.handle("show"),PUT:t.handle("update"),PATCH:t.handle("update"),DELETE:t.handle("destroy")}:{GET:t.handle("index"),POST:t.handle("store")}}var It,q,$e,De,Ae,ai=y(()=>{"use strict";ne();It=class{controllerMiddleware=[];middleware(e,t){let s;typeof e=="function"&&e.prototype instanceof T?s=new e:s=e,this.controllerMiddleware.push({middleware:s,only:t?.only,except:t?.except})}handle(e){return async t=>{try{let s=this.controllerMiddleware.filter(r=>!(r.only&&!r.only.includes(e)||r.except&&r.except.includes(e)));if(s.length>0){let r=new O;for(let{middleware:a}of s)r.use(a);let i={event:t,params:t.params,locals:t.locals},n=await r.execute(i,async()=>this.callMethod(e,t));if(n instanceof Response)return n}return await this.callMethod(e,t)}catch(s){return this.handleError(s,t)}}}json(e,t=200,s={}){let r=JSON.stringify(e,null,2);return new Response(r,{status:t,headers:{"Content-Type":"application/json",...s}})}text(e,t=200){return new Response(e,{status:t,headers:{"Content-Type":"text/plain"}})}html(e,t=200){return new Response(e,{status:t,headers:{"Content-Type":"text/html"}})}redirect(e,t=302){return new Response(null,{status:t,headers:{Location:e}})}noContent(){return new Response(null,{status:204})}created(e){return e?this.json(e,201):new Response(null,{status:201})}async validate(e,t){let s=t instanceof ae.ZodObject?t:ae.object(t),r,i=e.request.headers.get("content-type")??"";if(i.includes("application/json"))r=await e.request.json();else if(i.includes("multipart/form-data")||i.includes("application/x-www-form-urlencoded")){let a=await e.request.formData();r=Object.fromEntries(a)}else r=Object.fromEntries(e.url.searchParams);let n=s.safeParse(r);if(!n.success)throw new q(n.error);return n.data}validateQuery(e,t){let s=t instanceof ae.ZodObject?t:ae.object(t),r=Object.fromEntries(e.url.searchParams),i=s.safeParse(r);if(!i.success)throw new q(i.error);return i.data}validateParams(e,t){let r=(t instanceof ae.ZodObject?t:ae.object(t)).safeParse(e.params);if(!r.success)throw new q(r.error);return r.data}handleError(e,t){return e instanceof q?this.json({message:"Validation failed",errors:e.errors},422):e instanceof $e?this.json({message:e.message||"Not found"},404):e instanceof De?this.json({message:e.message||"Unauthorized"},401):e instanceof Ae?this.json({message:e.message||"Forbidden"},403):(console.error("[Svelar] Controller error:",e),this.json({message:process.env.NODE_ENV==="production"?"Internal server error":e.message},500))}async callMethod(e,t){let s=this[e];if(typeof s!="function")throw new Error(`Method "${e}" not found on controller "${this.constructor.name}".`);let r=await s.call(this,t);return r instanceof Response?r:this.json(r)}};q=class extends Error{errors;constructor(e){super("Validation failed"),this.name="ValidationError",this.errors={};for(let t of e.issues){let s=t.path.join(".");this.errors[s]||(this.errors[s]=[]),this.errors[s].push(t.message)}}},$e=class extends Error{constructor(e="Not found"){super(e),this.name="NotFoundError"}},De=class extends Error{constructor(e="Unauthorized"){super(e),this.name="UnauthorizedError"}},Ae=class extends Error{constructor(e="Forbidden"){super(e),this.name="ForbiddenError"}}});import{randomBytes as Ja,createHmac as oi,timingSafeEqual as Va}from"crypto";import{promises as U}from"fs";import{join as Me}from"path";var oe,Le,H,jt,Ot,qt,le,_s=y(()=>{"use strict";ne();oe=class o{constructor(e,t){this.id=e;t&&(this.data={...t},this.data._flash&&(this.previousFlashData=this.data._flash,delete this.data._flash))}data={};dirty=!1;flashData={};previousFlashData={};get(e,t){return e in this.flashData?this.flashData[e]:e in this.previousFlashData?this.previousFlashData[e]:e in this.data?this.data[e]:t}set(e,t){this.data[e]=t,this.dirty=!0}has(e){return e in this.data||e in this.flashData||e in this.previousFlashData}forget(e){delete this.data[e],this.dirty=!0}flush(){this.data={},this.dirty=!0}flash(e,t){this.flashData[e]=t,this.dirty=!0}all(){return{...this.data,...this.previousFlashData,...this.flashData}}isDirty(){return this.dirty||Object.keys(this.flashData).length>0}toPersist(){let e={...this.data};return Object.keys(this.flashData).length>0&&(e._flash=this.flashData),e}regenerateId(){let e=this.id,t=o.generateId();this.id=t,this.dirty=!0;let s=Le.get(e);return s instanceof H&&s.markOldSessionId(e),Le.delete(e),t}static generateId(){return Ja(32).toString("hex")}},Le=new Map,H=class{sessions=new Map;oldSessionIds=new Set;async read(e){if(this.oldSessionIds.has(e))return null;let t=this.sessions.get(e);return t?Date.now()>t.expiresAt?(this.sessions.delete(e),null):t.data:null}async write(e,t,s){this.sessions.set(e,{data:t,expiresAt:Date.now()+s*1e3}),Le.set(e,this)}async destroy(e){this.sessions.delete(e),Le.delete(e)}async gc(e){let t=Date.now();for(let[s,r]of this.sessions)t>r.expiresAt&&(this.sessions.delete(s),Le.delete(s))}markOldSessionId(e){this.oldSessionIds.add(e),this.sessions.delete(e)}},jt=class{constructor(e="sessions",t){this.tableName=e;this.connectionName=t}tableEnsured=!1;async ensureTable(){if(!this.tableEnsured)try{let{Connection:e}=await Promise.resolve().then(()=>(x(),P));switch(e.getDriver(this.connectionName)){case"sqlite":await e.raw(`CREATE TABLE IF NOT EXISTS ${this.tableName} (
|
|
43
43
|
id TEXT PRIMARY KEY,
|
|
44
44
|
payload TEXT NOT NULL,
|
|
45
45
|
expires_at TEXT NOT NULL
|
|
@@ -54,7 +54,7 @@ var vn=Object.defineProperty;var Fe=(l=>typeof require<"u"?require:typeof Proxy<
|
|
|
54
54
|
) ENGINE=InnoDB`,[],this.connectionName);break}this.tableEnsured=!0}catch{}}async read(e){await this.ensureTable();let{Connection:t}=await Promise.resolve().then(()=>(x(),P)),s=await t.raw(`SELECT payload, expires_at FROM ${this.tableName} WHERE id = ?`,[e],this.connectionName);if(s.length===0)return null;let r=s[0];if(new Date(r.expires_at)<new Date)return await this.destroy(e),null;try{return JSON.parse(r.payload)}catch{return null}}async write(e,t,s){await this.ensureTable();let{Connection:r}=await Promise.resolve().then(()=>(x(),P)),i=JSON.stringify(t),n=new Date(Date.now()+s*1e3).toISOString(),a=r.getDriver(this.connectionName);a==="sqlite"?await r.raw(`INSERT INTO ${this.tableName} (id, payload, expires_at) VALUES (?, ?, ?)
|
|
55
55
|
ON CONFLICT(id) DO UPDATE SET payload = excluded.payload, expires_at = excluded.expires_at`,[e,i,n],this.connectionName):a==="postgres"?await r.raw(`INSERT INTO ${this.tableName} (id, payload, expires_at) VALUES ($1, $2, $3)
|
|
56
56
|
ON CONFLICT(id) DO UPDATE SET payload = $2, expires_at = $3`,[e,i,n],this.connectionName):await r.raw(`INSERT INTO ${this.tableName} (id, payload, expires_at) VALUES (?, ?, ?)
|
|
57
|
-
ON DUPLICATE KEY UPDATE payload = VALUES(payload), expires_at = VALUES(expires_at)`,[e,i,n],this.connectionName)}async destroy(e){let{Connection:t}=await Promise.resolve().then(()=>(x(),P));await t.raw(`DELETE FROM ${this.tableName} WHERE id = ?`,[e],this.connectionName)}async gc(e){let{Connection:t}=await Promise.resolve().then(()=>(x(),P));await t.raw(`DELETE FROM ${this.tableName} WHERE expires_at < ?`,[new Date().toISOString()],this.connectionName)}},
|
|
57
|
+
ON DUPLICATE KEY UPDATE payload = VALUES(payload), expires_at = VALUES(expires_at)`,[e,i,n],this.connectionName)}async destroy(e){let{Connection:t}=await Promise.resolve().then(()=>(x(),P));await t.raw(`DELETE FROM ${this.tableName} WHERE id = ?`,[e],this.connectionName)}async gc(e){let{Connection:t}=await Promise.resolve().then(()=>(x(),P));await t.raw(`DELETE FROM ${this.tableName} WHERE expires_at < ?`,[new Date().toISOString()],this.connectionName)}},Ot=class{dir;constructor(e){this.dir=e??Me(process.cwd(),"storage","sessions")}filePath(e){let t=e.replace(/[^a-zA-Z0-9_-]/g,"");return Me(this.dir,`${t}.json`)}async ensureDir(){await U.mkdir(this.dir,{recursive:!0})}async read(e){try{let t=await U.readFile(this.filePath(e),"utf-8"),s=JSON.parse(t);return new Date(s.expiresAt)<new Date?(await this.destroy(e),null):s.data}catch{return null}}async write(e,t,s){await this.ensureDir();let r={data:t,expiresAt:new Date(Date.now()+s*1e3).toISOString()};await U.writeFile(this.filePath(e),JSON.stringify(r),"utf-8")}async destroy(e){try{await U.unlink(this.filePath(e))}catch{}}async gc(e){try{let t=await U.readdir(this.dir),s=new Date;for(let r of t)if(r.endsWith(".json"))try{let i=await U.readFile(Me(this.dir,r),"utf-8"),n=JSON.parse(i);new Date(n.expiresAt)<s&&await U.unlink(Me(this.dir,r))}catch{await U.unlink(Me(this.dir,r)).catch(()=>{})}}catch{}}},qt=class{redis;prefix;constructor(e){this.prefix=e?.prefix??"svelar_session:",e?.client?this.redis=e.client:this._url=e?.url}_url;_connecting;async getClient(){return this.redis?this.redis:(this._connecting||(this._connecting=(async()=>{try{let{default:e}=await import("ioredis");return this.redis=this._url?new e(this._url):new e,this.redis}catch{throw new Error('RedisSessionStore requires "ioredis" package. Install it: npm install ioredis')}})()),this._connecting)}async read(e){let s=await(await this.getClient()).get(this.prefix+e);if(!s)return null;try{return JSON.parse(s)}catch{return null}}async write(e,t,s){await(await this.getClient()).set(this.prefix+e,JSON.stringify(t),"EX",s)}async destroy(e){await(await this.getClient()).del(this.prefix+e)}async gc(e){}},le=class extends T{config;constructor(e){if(super(),this.config={cookieName:"svelar_session",lifetime:7200,secret:"",path:"/",domain:"",secure:process.env.NODE_ENV==="production",httpOnly:!0,sameSite:"lax",...e},!this.config.secret)throw new Error("APP_KEY is not set. Pass `secret` to createSvelarApp() \u2014 e.g. secret: env.APP_KEY (from $env/dynamic/private).")}async handle(e,t){let s=e.event.request.headers.get("cookie")??"",r=this.getSessionIdFromCookie(s),i=null;if(r){let l=this.verifySignedId(r);l?(i=await this.config.store.read(l),r=l):r=null}r||(r=oe.generateId());let n=new oe(r,i??{});e.event.locals.session=n,e.locals.session=n;let a=await t();if(n.isDirty()&&await this.config.store.write(n.id,n.toPersist(),this.config.lifetime),a instanceof Response){let l=this.signId(n.id),c=this.buildCookieString(l);a.headers.append("Set-Cookie",c)}return a}getSessionIdFromCookie(e){let t=e.split(";").map(s=>s.trim());for(let s of t){let[r,...i]=s.split("=");if(r===this.config.cookieName)return decodeURIComponent(i.join("="))}return null}signId(e){let t=oi("sha256",this.config.secret).update(e).digest("base64url");return`${e}.${t}`}verifySignedId(e){let t=e.lastIndexOf(".");if(t===-1)return null;let s=e.slice(0,t),r=e.slice(t+1),i=oi("sha256",this.config.secret).update(s).digest("base64url");if(r.length!==i.length)return null;let n=Buffer.from(r),a=Buffer.from(i);if(n.length!==a.length)return null;try{if(Va(n,a))return s}catch{}return null}buildCookieString(e){let t=[`${this.config.cookieName}=${encodeURIComponent(e)}`];return t.push(`Path=${this.config.path}`),t.push(`Max-Age=${this.config.lifetime}`),this.config.domain&&t.push(`Domain=${this.config.domain}`),this.config.secure&&t.push("Secure"),this.config.httpOnly&&t.push("HttpOnly"),t.push(`SameSite=${this.config.sameSite}`),t.join("; ")}}});var _e={};k(_e,{Hash:()=>js});import{randomBytes as Ns,scrypt as li,timingSafeEqual as Qa}from"crypto";async function Ga(o,e=16384){let t=Ns(16),s=64,r=await new Promise((i,n)=>{li(o,t,s,{N:e,r:8,p:1},(a,l)=>{a?n(a):i(l)})});return`$scrypt$N=${e}$${t.toString("base64")}$${r.toString("base64")}`}async function Ya(o,e){let t=e.split("$");if(t.length!==5||t[1]!=="scrypt")return!1;let s=parseInt(t[2].replace("N=",""),10),r=Buffer.from(t[3],"base64"),i=Buffer.from(t[4],"base64"),n=i.length,a=await new Promise((l,c)=>{li(o,r,n,{N:s,r:8,p:1},(u,m)=>{u?c(u):l(m)})});return Qa(a,i)}var Is,js,ce=y(()=>{"use strict";R();Is=class{config={driver:"scrypt",scryptCost:16384,bcryptRounds:12};configure(e){Object.assign(this.config,e)}async make(e){switch(this.config.driver){case"scrypt":return Ga(e,this.config.scryptCost);case"bcrypt":try{return(await import("bcrypt")).default.hash(e,this.config.bcryptRounds??12)}catch{throw new Error('bcrypt driver requires the "bcrypt" package. Install it: npm install bcrypt')}case"argon2":try{return(await import("argon2")).default.hash(e)}catch{throw new Error('argon2 driver requires the "argon2" package. Install it: npm install argon2')}default:throw new Error(`Unsupported hash driver: ${this.config.driver}`)}}async verify(e,t){if(t.startsWith("$scrypt$"))return Ya(e,t);if(t.startsWith("$2b$")||t.startsWith("$2a$")||t.startsWith("$2y$"))try{return(await import("bcrypt")).default.compare(e,t)}catch{throw new Error("bcrypt package required to verify bcrypt hashes.")}if(t.startsWith("$argon2"))try{return(await import("argon2")).default.verify(t,e)}catch{throw new Error("argon2 package required to verify argon2 hashes.")}return!1}needsRehash(e){if(this.config.driver==="scrypt"&&e.startsWith("$scrypt$")){let t=e.match(/N=(\d+)/);if(t)return parseInt(t[1],10)!==this.config.scryptCost}if(this.config.driver==="bcrypt"&&(e.startsWith("$2b$")||e.startsWith("$2a$"))){let t=e.match(/\$2[aby]\$(\d+)\$/);if(t)return parseInt(t[1],10)!==this.config.bcryptRounds}return this.config.driver==="scrypt"&&!e.startsWith("$scrypt$")||this.config.driver==="bcrypt"&&!e.startsWith("$2")||this.config.driver==="argon2"&&!e.startsWith("$argon2")}randomString(e=32){return Ns(Math.ceil(e/2)).toString("hex").slice(0,e)}randomToken(e=32){return Ns(e).toString("base64url")}},js=C("svelar.hash",()=>new Is)});var ci={};k(ci,{EmailTemplates:()=>Za});import{randomUUID as _}from"crypto";var Os,Za,di=y(()=>{"use strict";R();Os=class{config={driver:"memory"};templates=new Map;constructor(){this.registerDefaults()}configure(e){this.config=e}async register(e){let t={...e,id:_(),createdAt:Date.now(),updatedAt:Date.now()};if(this.config.driver==="memory")this.templates.set(e.name,t);else if(this.config.driver==="database")try{let{Connection:s}=await Promise.resolve().then(()=>(x(),P));await s.connection()}catch{this.templates.set(e.name,t)}return t}async render(e,t){let s=await this.get(e);if(!s)throw new Error(`Template "${e}" not found`);let r=this.interpolate(s.subject,t),i=this.interpolate(s.html,t),n=s.text?this.interpolate(s.text,t):void 0;return{subject:r,html:i,text:n}}async get(e){return this.templates.get(e)||null}async list(e){let t=Array.from(this.templates.values());return e&&(t=t.filter(s=>s.category===e)),t}async update(e,t){let s=this.templates.get(e);return s?(Object.assign(s,t,{updatedAt:Date.now()}),s):null}async delete(e){return this.templates.delete(e)}registerDefaults(){this.templates.set("welcome",{id:_(),name:"welcome",subject:"Welcome to {{appName}}, {{user.name}}!",html:`
|
|
58
58
|
<h1>Welcome, {{user.name}}!</h1>
|
|
59
59
|
<p>Thank you for joining {{appName}}.</p>
|
|
60
60
|
<p>Your account has been created with the email: <strong>{{user.email}}</strong></p>
|
|
@@ -110,21 +110,21 @@ This code expires in {{expiresMinutes}} minutes.`,variables:["appName","user.nam
|
|
|
110
110
|
<p>Your {{plan.name}} subscription has been canceled.</p>
|
|
111
111
|
<p>You have access until {{accessUntilDate}}.</p>
|
|
112
112
|
`,text:`Your {{plan.name}} subscription is canceled.
|
|
113
|
-
Access until: {{accessUntilDate}}`,variables:["user.name","plan.name","accessUntilDate"],category:"billing",active:!0,createdAt:Date.now(),updatedAt:Date.now()})}interpolate(e,t){let s=e;return s=s.replace(/\{\{#if\s+(\w+(?:\.\w+)*)\}\}([\s\S]*?)\{\{\/if\}\}/g,(r,i,n)=>this.getNestedValue(t,i)?n:""),s=s.replace(/\{\{#each\s+(\w+(?:\.\w+)*)\}\}([\s\S]*?)\{\{\/each\}\}/g,(r,i,n)=>{let a=this.getNestedValue(t,i);return Array.isArray(a)?a.map((o,c)=>{let u={...t,this:o,$index:c};return this.interpolate(n,u)}).join(""):""}),s=s.replace(/\{\{([\w.$]+)\}\}/g,(r,i)=>{let n=this.getNestedValue(t,i);return n!=null?String(n):""}),s}getNestedValue(e,t){return t.split(".").reduce((s,r)=>s?.[r],e)}},Ja=w("svelar.emailTemplates",()=>new Ns)});var Bs={};E(Bs,{Mailable:()=>je,Mailer:()=>Us});function qs(l){return typeof l=="string"?l:`${l.name} <${l.address}>`}function $(l){return l?Array.isArray(l)?l:[l]:[]}function Ci(l){return Buffer.isBuffer(l)?l.toString("base64"):Buffer.from(l).toString("base64")}var Ot,_s,Is,js,Os,je,Ls,Us,Lt=y(()=>{"use strict";R();Ot=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:[]}}},_s=class{async send(e){return{accepted:$(e.to),rejected:[]}}},Is=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?qs(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}}},js=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),i=$(e.bcc),n={From:e.from?qs(e.from):void 0,To:s.join(", "),Subject:e.subject,MessageStream:this.config.messageStream||"outbound"};r.length>0&&(n.Cc=r.join(", ")),i.length>0&&(n.Bcc=i.join(", ")),e.replyTo&&(n.ReplyTo=e.replyTo),e.html&&(n.HtmlBody=e.html),e.text&&(n.TextBody=e.text),!n.HtmlBody&&!n.TextBody&&(n.TextBody=""),e.tags&&(n.Tag=Object.values(e.tags)[0]),e.attachments?.length&&(n.Attachments=e.attachments.map(c=>({Name:c.filename,Content:Ci(c.content),ContentType:c.contentType||"application/octet-stream"})));let a=await fetch("https://api.postmarkapp.com/email",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json","X-Postmark-Server-Token":t},body:JSON.stringify(n)});if(!a.ok){let c=await a.json().catch(()=>({Message:a.statusText}));throw new Error(`Postmark error ${a.status}: ${c.Message||JSON.stringify(c)}`)}let o=await a.json();return{accepted:s,rejected:[],messageId:o.MessageID}}},Os=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),i=$(e.bcc),n={from:e.from?qs(e.from):void 0,to:s,subject:e.subject};r.length>0&&(n.cc=r),i.length>0&&(n.bcc=i),e.replyTo&&(n.reply_to=[e.replyTo]),e.html&&(n.html=e.html),e.text&&(n.text=e.text),e.tags&&(n.tags=Object.entries(e.tags).map(([c,u])=>({name:c,value:u}))),e.attachments?.length&&(n.attachments=e.attachments.map(c=>({filename:c.filename,content:Ci(c.content),content_type:c.contentType||"application/octet-stream"})));let a=await fetch("https://api.resend.com/emails",{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify(n)});if(!a.ok){let c=await a.json().catch(()=>({message:a.statusText}));throw new Error(`Resend error ${a.status}: ${c.message||JSON.stringify(c)}`)}let o=await a.json();return{accepted:s,rejected:[],messageId:o.id}}},je=class{message={};to(e){return this.message.to=e,this}cc(e){return this.message.cc=e,this}bcc(e){return this.message.bcc=e,this}from(e){return this.message.from=e,this}replyTo(e){return this.message.replyTo=e,this}subject(e){return this.message.subject=e,this}text(e){return this.message.text=e,this}html(e){return this.message.html=e,this}attach(e,t,s){return this.message.attachments||(this.message.attachments=[]),this.message.attachments.push({filename:e,content:t,contentType:s}),this}tag(e,t){return this.message.tags||(this.message.tags={}),this.message.tags[e]=t,this}toMessage(){return this.message}},Ls=class{config=null;transports=new Map;configure(e){this.config=e,this.transports.clear()}async send(e,t){let s=this.resolveTransport(t);return!e.from&&this.config?.from&&(e.from=this.config.from),s.send(e)}async sendMailable(e,t){e.build();let s=e.toMessage();return!s.from&&this.config?.from&&(s.from=this.config.from),this.send(s,t)}mailer(e){let t=this.resolveTransport(e);return{send:s=>(!s.from&&this.config?.from&&(s.from=this.config.from),t.send(s))}}resolveTransport(e){let t=e??this.config?.default??"log";if(this.transports.has(t))return this.transports.get(t);if(!this.config){let i=new Ot;return this.transports.set(t,i),i}let s=this.config.mailers[t];if(!s)throw new Error(`Mailer "${t}" is not defined.`);let r;switch(s.driver){case"smtp":r=new Is(s);break;case"postmark":r=new js(s);break;case"resend":r=new Os(s);break;case"log":r=new Ot;break;case"null":r=new _s;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}},Us=w("svelar.mail",()=>new Ls)});import{createHmac as ue,randomBytes as Oe}from"crypto";function Pi(l){return(typeof l=="string"?Buffer.from(l):l).toString("base64url")}function Si(l){return Buffer.from(l,"base64url").toString("utf-8")}function Ri(l,e,t,s){return ue(s==="HS384"?"sha384":s==="HS512"?"sha512":"sha256",t).update(`${l}.${e}`).digest("base64url")}function Fs(l,e,t="HS256"){let s=Pi(JSON.stringify({alg:t,typ:"JWT"})),r=Pi(JSON.stringify(l)),i=Ri(s,r,e,t);return`${s}.${r}.${i}`}function Hs(l,e){let t=l.split(".");if(t.length!==3)return null;let[s,r,i]=t,n;try{n=JSON.parse(Si(s))}catch{return null}let a=Ri(s,r,e,n.alg);if(i!==a)return null;try{let o=JSON.parse(Si(r));return o.exp&&Date.now()/1e3>o.exp?null:o}catch{return null}}var qt,me,Ut,zs=y(()=>{"use strict";ae();qt=class{config;currentUser=null;constructor(e){this.config={identifierColumn:"email",passwordColumn:"password",...e}}async attempt(e,t){let{Hash:s}=await Promise.resolve().then(()=>(de(),Ie)),r=e[this.config.identifierColumn],i=e[this.config.passwordColumn];if(!r||!i)return null;let n=await this.config.model.where(this.config.identifierColumn,r).first();if(!n)return null;let a=n.getAttribute(this.config.passwordColumn);return await s.verify(i,a)?(this.currentUser=n,t&&(t.set("auth_user_id",n.getAttribute("id")),t.regenerateId()),n):null}async attemptJwt(e){let{Hash:t}=await Promise.resolve().then(()=>(de(),Ie));if(!this.config.jwt)throw new Error("JWT configuration required for JWT guard.");let s=e[this.config.identifierColumn],r=e[this.config.passwordColumn];if(!s||!r)return null;let i=await this.config.model.where(this.config.identifierColumn,s).first();if(!i)return null;let n=i.getAttribute(this.config.passwordColumn);return await t.verify(r,n)?(this.currentUser=i,this.issueTokenPair(i)):null}async issueTokenPair(e){let t=this.config.jwt,s=t.expiresIn??3600,r=Math.floor(Date.now()/1e3),i={sub:e.getAttribute("id"),iat:r,exp:r+s,...t.issuer?{iss:t.issuer}:{}},n=Fs(i,t.secret,t.algorithm),a=new Date((r+s)*1e3),o={user:e,token:n,expiresAt:a};if(t.refreshTokens){let c=t.refreshExpiresIn??604800,u=Oe(32).toString("base64url"),d=ue("sha256",t.secret).update(u).digest("hex"),p=new Date((r+c)*1e3),{Connection:f}=await Promise.resolve().then(()=>(x(),P)),b=t.refreshTable??"refresh_tokens";await f.raw(`INSERT INTO ${b} (user_id, token, expires_at, created_at) VALUES (?, ?, ?, ?)`,[e.getAttribute("id"),d,p.toISOString(),new Date().toISOString()]),o.refreshToken=u,o.refreshExpiresAt=p}return o}async refreshJwt(e){if(!this.config.jwt)throw new Error("JWT configuration required.");if(!this.config.jwt.refreshTokens)throw new Error("Refresh tokens are not enabled. Set jwt.refreshTokens = true.");let t=this.config.jwt,s=ue("sha256",t.secret).update(e).digest("hex"),{Connection:r}=await Promise.resolve().then(()=>(x(),P)),i=t.refreshTable??"refresh_tokens",n=await r.raw(`SELECT user_id, expires_at, revoked_at FROM ${i} WHERE token = ?`,[s]);if(n.length===0)return null;let a=n[0];if(a.revoked_at||new Date(a.expires_at)<new Date)return null;await r.raw(`UPDATE ${i} SET revoked_at = ? WHERE token = ?`,[new Date().toISOString(),s]);let o=await this.config.model.find(a.user_id);return o?(this.currentUser=o,this.issueTokenPair(o)):null}async revokeRefreshTokens(e){if(!this.config.jwt?.refreshTokens)return;let{Connection:t}=await Promise.resolve().then(()=>(x(),P)),s=this.config.jwt.refreshTable??"refresh_tokens";await t.raw(`UPDATE ${s} SET revoked_at = ? WHERE user_id = ? AND revoked_at IS NULL`,[new Date().toISOString(),e])}async resolveFromToken(e){if(!this.config.jwt)throw new Error("JWT configuration required.");let t=Hs(e,this.config.jwt.secret);if(!t)return null;let s=await this.config.model.find(t.sub);return s&&(this.currentUser=s),s}async resolveFromSession(e){let t=e.get("auth_user_id");if(!t)return null;let s=await this.config.model.find(t);return s&&(this.currentUser=s),s}async register(e){let{Hash:t}=await Promise.resolve().then(()=>(de(),Ie));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=Oe(32).toString("hex"),r=this.config.jwt?.secret??process.env.APP_KEY;if(!r)throw new Error("APP_KEY is not set. Set it in your .env file or pass jwt.secret in auth config.");let i=ue("sha256",r).update(s).digest("hex"),{Connection:n}=await Promise.resolve().then(()=>(x(),P)),a=this.config.token?.table??"personal_access_tokens";return await n.raw(`INSERT INTO ${a} (user_id, name, token, created_at) VALUES (?, ?, ?, ?)`,[e.getAttribute("id"),t,i,new Date().toISOString()]),s}async resolveFromApiToken(e){let{Connection:t}=await Promise.resolve().then(()=>(x(),P)),s=this.config.token?.table??"personal_access_tokens",r=this.config.jwt?.secret??process.env.APP_KEY;if(!r)throw new Error("APP_KEY is not set. Set it in your .env file or pass jwt.secret in auth config.");let i=ue("sha256",r).update(e).digest("hex"),n=await t.raw(`SELECT user_id FROM ${s} WHERE token = ?`,[i]);if(n.length===0)return null;let a=await this.config.model.find(n[0].user_id);return a&&(this.currentUser=a),a}async sendPasswordReset(e){let t=await this.config.model.where(this.config.identifierColumn,e).first();if(!t)return!1;let{Connection:s}=await Promise.resolve().then(()=>(x(),P)),r=this.config.passwordResets?.table??"password_resets",i=this.config.passwordResets?.expiresIn??3600;await this.ensureTable(r,`
|
|
113
|
+
Access until: {{accessUntilDate}}`,variables:["user.name","plan.name","accessUntilDate"],category:"billing",active:!0,createdAt:Date.now(),updatedAt:Date.now()})}interpolate(e,t){let s=e;return s=s.replace(/\{\{#if\s+(\w+(?:\.\w+)*)\}\}([\s\S]*?)\{\{\/if\}\}/g,(r,i,n)=>this.getNestedValue(t,i)?n:""),s=s.replace(/\{\{#each\s+(\w+(?:\.\w+)*)\}\}([\s\S]*?)\{\{\/each\}\}/g,(r,i,n)=>{let a=this.getNestedValue(t,i);return Array.isArray(a)?a.map((l,c)=>{let u={...t,this:l,$index:c};return this.interpolate(n,u)}).join(""):""}),s=s.replace(/\{\{([\w.$]+)\}\}/g,(r,i)=>{let n=this.getNestedValue(t,i);return n!=null?String(n):""}),s}getNestedValue(e,t){return t.split(".").reduce((s,r)=>s?.[r],e)}},Za=C("svelar.emailTemplates",()=>new Os)});var Ws={};k(Ws,{Mailable:()=>Ne,Mailer:()=>Ks});function zs(o){return typeof o=="string"?o:`${o.name} <${o.address}>`}function D(o){return o?Array.isArray(o)?o:[o]:[]}function ui(o){return Buffer.isBuffer(o)?o.toString("base64"):Buffer.from(o).toString("base64")}var Ut,qs,Us,Bs,Fs,Ne,Hs,Ks,Bt=y(()=>{"use strict";R();Ut=class{async send(e){let t=D(e.to);return console.log(`[Mail] To: ${t.join(", ")} | Subject: ${e.subject}`),e.text&&console.log(`[Mail] Body: ${e.text.slice(0,200)}`),{accepted:t,rejected:[]}}},qs=class{async send(e){return{accepted:D(e.to),rejected:[]}}},Us=class{constructor(e){this.config=e}async send(e){try{let r=await(await import("nodemailer")).createTransport({host:this.config.host,port:this.config.port??587,secure:this.config.secure??!1,auth:this.config.auth}).sendMail({from:e.from?zs(e.from):void 0,to:D(e.to).join(", "),cc:D(e.cc).join(", ")||void 0,bcc:D(e.bcc).join(", ")||void 0,replyTo:e.replyTo,subject:e.subject,text:e.text,html:e.html,attachments:e.attachments});return{accepted:r.accepted,rejected:r.rejected,messageId:r.messageId}}catch(t){throw t.code==="MODULE_NOT_FOUND"?new Error("SMTP driver requires nodemailer. Install: npm install nodemailer"):t}}},Bs=class{constructor(e){this.config=e}async send(e){let t=this.config.apiToken;if(!t)throw new Error("Postmark apiToken is required. Set it in your mailer config or POSTMARK_API_TOKEN env var.");let s=D(e.to),r=D(e.cc),i=D(e.bcc),n={From:e.from?zs(e.from):void 0,To:s.join(", "),Subject:e.subject,MessageStream:this.config.messageStream||"outbound"};r.length>0&&(n.Cc=r.join(", ")),i.length>0&&(n.Bcc=i.join(", ")),e.replyTo&&(n.ReplyTo=e.replyTo),e.html&&(n.HtmlBody=e.html),e.text&&(n.TextBody=e.text),!n.HtmlBody&&!n.TextBody&&(n.TextBody=""),e.tags&&(n.Tag=Object.values(e.tags)[0]),e.attachments?.length&&(n.Attachments=e.attachments.map(c=>({Name:c.filename,Content:ui(c.content),ContentType:c.contentType||"application/octet-stream"})));let a=await fetch("https://api.postmarkapp.com/email",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json","X-Postmark-Server-Token":t},body:JSON.stringify(n)});if(!a.ok){let c=await a.json().catch(()=>({Message:a.statusText}));throw new Error(`Postmark error ${a.status}: ${c.Message||JSON.stringify(c)}`)}let l=await a.json();return{accepted:s,rejected:[],messageId:l.MessageID}}},Fs=class{constructor(e){this.config=e}async send(e){let t=this.config.apiKey;if(!t)throw new Error("Resend apiKey is required. Set it in your mailer config or RESEND_API_KEY env var.");let s=D(e.to),r=D(e.cc),i=D(e.bcc),n={from:e.from?zs(e.from):void 0,to:s,subject:e.subject};r.length>0&&(n.cc=r),i.length>0&&(n.bcc=i),e.replyTo&&(n.reply_to=[e.replyTo]),e.html&&(n.html=e.html),e.text&&(n.text=e.text),e.tags&&(n.tags=Object.entries(e.tags).map(([c,u])=>({name:c,value:u}))),e.attachments?.length&&(n.attachments=e.attachments.map(c=>({filename:c.filename,content:ui(c.content),content_type:c.contentType||"application/octet-stream"})));let a=await fetch("https://api.resend.com/emails",{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify(n)});if(!a.ok){let c=await a.json().catch(()=>({message:a.statusText}));throw new Error(`Resend error ${a.status}: ${c.message||JSON.stringify(c)}`)}let l=await a.json();return{accepted:s,rejected:[],messageId:l.id}}},Ne=class{message={};to(e){return this.message.to=e,this}cc(e){return this.message.cc=e,this}bcc(e){return this.message.bcc=e,this}from(e){return this.message.from=e,this}replyTo(e){return this.message.replyTo=e,this}subject(e){return this.message.subject=e,this}text(e){return this.message.text=e,this}html(e){return this.message.html=e,this}attach(e,t,s){return this.message.attachments||(this.message.attachments=[]),this.message.attachments.push({filename:e,content:t,contentType:s}),this}tag(e,t){return this.message.tags||(this.message.tags={}),this.message.tags[e]=t,this}toMessage(){return this.message}},Hs=class{config=null;transports=new Map;configure(e){this.config=e,this.transports.clear()}async send(e,t){let s=this.resolveTransport(t);return!e.from&&this.config?.from&&(e.from=this.config.from),s.send(e)}async sendMailable(e,t){e.build();let s=e.toMessage();return!s.from&&this.config?.from&&(s.from=this.config.from),this.send(s,t)}mailer(e){let t=this.resolveTransport(e);return{send:s=>(!s.from&&this.config?.from&&(s.from=this.config.from),t.send(s))}}resolveTransport(e){let t=e??this.config?.default??"log";if(this.transports.has(t))return this.transports.get(t);if(!this.config){let i=new Ut;return this.transports.set(t,i),i}let s=this.config.mailers[t];if(!s)throw new Error(`Mailer "${t}" is not defined.`);let r;switch(s.driver){case"smtp":r=new Us(s);break;case"postmark":r=new Bs(s);break;case"resend":r=new Fs(s);break;case"log":r=new Ut;break;case"null":r=new qs;break;case"custom":{if(!s.transport)throw new Error(`Custom mail driver "${t}" requires a "transport" instance.`);r=s.transport;break}default:throw new Error(`Unknown mail driver: ${s.driver}`)}return this.transports.set(t,r),r}},Ks=C("svelar.mail",()=>new Hs)});import{createHmac as de,randomBytes as Ie}from"crypto";function mi(o){return(typeof o=="string"?Buffer.from(o):o).toString("base64url")}function pi(o){return Buffer.from(o,"base64url").toString("utf-8")}function hi(o,e,t,s){return de(s==="HS384"?"sha384":s==="HS512"?"sha512":"sha256",t).update(`${o}.${e}`).digest("base64url")}function Js(o,e,t="HS256"){let s=mi(JSON.stringify({alg:t,typ:"JWT"})),r=mi(JSON.stringify(o)),i=hi(s,r,e,t);return`${s}.${r}.${i}`}function Vs(o,e){let t=o.split(".");if(t.length!==3)return null;let[s,r,i]=t,n;try{n=JSON.parse(pi(s))}catch{return null}let a=hi(s,r,e,n.alg);if(i!==a)return null;try{let l=JSON.parse(pi(r));return l.exp&&Date.now()/1e3>l.exp?null:l}catch{return null}}var Ft,ue,Ht,Qs=y(()=>{"use strict";ne();Ft=class{config;currentUser=null;constructor(e){this.config={identifierColumn:"email",passwordColumn:"password",...e}}async attempt(e,t){let{Hash:s}=await Promise.resolve().then(()=>(ce(),_e)),r=e[this.config.identifierColumn],i=e[this.config.passwordColumn];if(!r||!i)return null;let n=await this.config.model.where(this.config.identifierColumn,r).first();if(!n)return null;let a=n.getAttribute(this.config.passwordColumn);return await s.verify(i,a)?(this.currentUser=n,t&&(t.set("auth_user_id",n.getAttribute("id")),t.regenerateId()),n):null}async attemptJwt(e){let{Hash:t}=await Promise.resolve().then(()=>(ce(),_e));if(!this.config.jwt)throw new Error("JWT configuration required for JWT guard.");let s=e[this.config.identifierColumn],r=e[this.config.passwordColumn];if(!s||!r)return null;let i=await this.config.model.where(this.config.identifierColumn,s).first();if(!i)return null;let n=i.getAttribute(this.config.passwordColumn);return await t.verify(r,n)?(this.currentUser=i,this.issueTokenPair(i)):null}async issueTokenPair(e){let t=this.config.jwt,s=t.expiresIn??3600,r=Math.floor(Date.now()/1e3),i={sub:e.getAttribute("id"),iat:r,exp:r+s,...t.issuer?{iss:t.issuer}:{}},n=Js(i,t.secret,t.algorithm),a=new Date((r+s)*1e3),l={user:e,token:n,expiresAt:a};if(t.refreshTokens){let c=t.refreshExpiresIn??604800,u=Ie(32).toString("base64url"),m=de("sha256",t.secret).update(u).digest("hex"),h=new Date((r+c)*1e3),{Connection:d}=await Promise.resolve().then(()=>(x(),P)),b=t.refreshTable??"refresh_tokens";await d.raw(`INSERT INTO ${b} (user_id, token, expires_at, created_at) VALUES (?, ?, ?, ?)`,[e.getAttribute("id"),m,h.toISOString(),new Date().toISOString()]),l.refreshToken=u,l.refreshExpiresAt=h}return l}async refreshJwt(e){if(!this.config.jwt)throw new Error("JWT configuration required.");if(!this.config.jwt.refreshTokens)throw new Error("Refresh tokens are not enabled. Set jwt.refreshTokens = true.");let t=this.config.jwt,s=de("sha256",t.secret).update(e).digest("hex"),{Connection:r}=await Promise.resolve().then(()=>(x(),P)),i=t.refreshTable??"refresh_tokens",n=await r.raw(`SELECT user_id, expires_at, revoked_at FROM ${i} WHERE token = ?`,[s]);if(n.length===0)return null;let a=n[0];if(a.revoked_at||new Date(a.expires_at)<new Date)return null;await r.raw(`UPDATE ${i} SET revoked_at = ? WHERE token = ?`,[new Date().toISOString(),s]);let l=await this.config.model.find(a.user_id);return l?(this.currentUser=l,this.issueTokenPair(l)):null}async revokeRefreshTokens(e){if(!this.config.jwt?.refreshTokens)return;let{Connection:t}=await Promise.resolve().then(()=>(x(),P)),s=this.config.jwt.refreshTable??"refresh_tokens";await t.raw(`UPDATE ${s} SET revoked_at = ? WHERE user_id = ? AND revoked_at IS NULL`,[new Date().toISOString(),e])}async resolveFromToken(e){if(!this.config.jwt)throw new Error("JWT configuration required.");let t=Vs(e,this.config.jwt.secret);if(!t)return null;let s=await this.config.model.find(t.sub);return s&&(this.currentUser=s),s}async resolveFromSession(e){let t=e.get("auth_user_id");if(!t)return null;let s=await this.config.model.find(t);return s&&(this.currentUser=s),s}async register(e){let{Hash:t}=await Promise.resolve().then(()=>(ce(),_e));e[this.config.passwordColumn]&&(e[this.config.passwordColumn]=await t.make(e[this.config.passwordColumn]));let s=await this.config.model.create(e);return this.currentUser=s,s}async logout(e){this.currentUser=null,e&&(e.forget("auth_user_id"),e.regenerateId())}user(){return this.currentUser}check(){return this.currentUser!==null}id(){return this.currentUser?.getAttribute("id")??null}async generateApiToken(e,t="default"){let s=Ie(32).toString("hex"),r=this.config.jwt?.secret??process.env.APP_KEY;if(!r)throw new Error("APP_KEY is not set. Set it in your .env file or pass jwt.secret in auth config.");let i=de("sha256",r).update(s).digest("hex"),{Connection:n}=await Promise.resolve().then(()=>(x(),P)),a=this.config.token?.table??"personal_access_tokens";return await n.raw(`INSERT INTO ${a} (user_id, name, token, created_at) VALUES (?, ?, ?, ?)`,[e.getAttribute("id"),t,i,new Date().toISOString()]),s}async resolveFromApiToken(e){let{Connection:t}=await Promise.resolve().then(()=>(x(),P)),s=this.config.token?.table??"personal_access_tokens",r=this.config.jwt?.secret??process.env.APP_KEY;if(!r)throw new Error("APP_KEY is not set. Set it in your .env file or pass jwt.secret in auth config.");let i=de("sha256",r).update(e).digest("hex"),n=await t.raw(`SELECT user_id FROM ${s} WHERE token = ?`,[i]);if(n.length===0)return null;let a=await this.config.model.find(n[0].user_id);return a&&(this.currentUser=a),a}async sendPasswordReset(e){let t=await this.config.model.where(this.config.identifierColumn,e).first();if(!t)return!1;let{Connection:s}=await Promise.resolve().then(()=>(x(),P)),r=this.config.passwordResets?.table??"password_resets",i=this.config.passwordResets?.expiresIn??3600;await this.ensureTable(r,`
|
|
114
114
|
CREATE TABLE IF NOT EXISTS ${r} (
|
|
115
115
|
email TEXT NOT NULL,
|
|
116
116
|
token TEXT NOT NULL,
|
|
117
117
|
expires_at TEXT NOT NULL,
|
|
118
118
|
created_at TEXT NOT NULL
|
|
119
119
|
)
|
|
120
|
-
`),await s.raw(`DELETE FROM ${r} WHERE email = ?`,[e]);let n=
|
|
120
|
+
`),await s.raw(`DELETE FROM ${r} WHERE email = ?`,[e]);let n=Ie(32).toString("base64url"),a=this.hashToken(n),l=new Date(Date.now()+i*1e3).toISOString();await s.raw(`INSERT INTO ${r} (email, token, expires_at, created_at) VALUES (?, ?, ?, ?)`,[e,a,l,new Date().toISOString()]);let c=this.config.appUrl??process.env.APP_URL??"http://localhost:5173",u=this.config.appName??process.env.APP_NAME??"Svelar",m=`${c}/reset-password?token=${n}&email=${encodeURIComponent(e)}`;return await this.sendAuthEmail("password-reset",e,{appName:u,"user.name":t.getAttribute("name")??e,resetUrl:m}),!0}async resetPassword(e,t,s){let{Connection:r}=await Promise.resolve().then(()=>(x(),P)),{Hash:i}=await Promise.resolve().then(()=>(ce(),_e)),n=this.config.passwordResets?.table??"password_resets",a=this.hashToken(e),l=await r.raw(`SELECT email, expires_at FROM ${n} WHERE token = ? AND email = ?`,[a,t]);if(l.length===0)return!1;let c=l[0];if(new Date(c.expires_at)<new Date)return await r.raw(`DELETE FROM ${n} WHERE email = ?`,[t]),!1;let u=await this.config.model.where(this.config.identifierColumn,t).first();if(!u)return!1;let m=await i.make(s);return await this.config.model.where("id",u.getAttribute("id")).update({[this.config.passwordColumn]:m}),await r.raw(`DELETE FROM ${n} WHERE email = ?`,[t]),await this.revokeRefreshTokens(u.getAttribute("id")),!0}async sendVerificationEmail(e){let{Connection:t}=await Promise.resolve().then(()=>(x(),P)),s=this.config.emailVerification?.table??"email_verifications",r=this.config.emailVerification?.expiresIn??86400,i=e.getAttribute(this.config.identifierColumn);await this.ensureTable(s,`
|
|
121
121
|
CREATE TABLE IF NOT EXISTS ${s} (
|
|
122
122
|
user_id TEXT NOT NULL,
|
|
123
123
|
token TEXT NOT NULL,
|
|
124
124
|
expires_at TEXT NOT NULL,
|
|
125
125
|
created_at TEXT NOT NULL
|
|
126
126
|
)
|
|
127
|
-
`),await t.raw(`DELETE FROM ${s} WHERE user_id = ?`,[e.getAttribute("id")]);let n=
|
|
127
|
+
`),await t.raw(`DELETE FROM ${s} WHERE user_id = ?`,[e.getAttribute("id")]);let n=Ie(32).toString("base64url"),a=this.hashToken(n),l=new Date(Date.now()+r*1e3).toISOString();await t.raw(`INSERT INTO ${s} (user_id, token, expires_at, created_at) VALUES (?, ?, ?, ?)`,[e.getAttribute("id"),a,l,new Date().toISOString()]);let u=`${this.config.appUrl??process.env.APP_URL??"http://localhost:5173"}/verify-email?token=${n}&id=${e.getAttribute("id")}`;await this.sendAuthEmail("email-verification",i,{"user.name":e.getAttribute("name")??i,verifyUrl:u})}async verifyEmail(e,t){let{Connection:s}=await Promise.resolve().then(()=>(x(),P)),r=this.config.emailVerification?.table??"email_verifications",i=this.config.emailVerification?.verifiedColumn??"email_verified_at",n=this.hashToken(e),a=await s.raw(`SELECT user_id, expires_at FROM ${r} WHERE token = ? AND user_id = ?`,[n,t]);return a.length===0?!1:new Date(a[0].expires_at)<new Date?(await s.raw(`DELETE FROM ${r} WHERE user_id = ?`,[t]),!1):(await this.config.model.where("id",t).update({[i]:new Date().toISOString()}),await s.raw(`DELETE FROM ${r} WHERE user_id = ?`,[t]),!0)}isEmailVerified(e){let t=this.config.emailVerification?.verifiedColumn??"email_verified_at";return!!e.getAttribute(t)}async sendOtp(e,t="login"){let s=await this.config.model.where(this.config.identifierColumn,e).first();if(!s)return!1;let{Connection:r}=await Promise.resolve().then(()=>(x(),P)),i=this.config.otp?.table??"otp_codes",n=this.config.otp?.expiresIn??600,a=this.config.otp?.length??6;await this.ensureTable(i,`
|
|
128
128
|
CREATE TABLE IF NOT EXISTS ${i} (
|
|
129
129
|
email TEXT NOT NULL,
|
|
130
130
|
code TEXT NOT NULL,
|
|
@@ -133,16 +133,16 @@ Access until: {{accessUntilDate}}`,variables:["user.name","plan.name","accessUnt
|
|
|
133
133
|
used_at TEXT,
|
|
134
134
|
created_at TEXT NOT NULL
|
|
135
135
|
)
|
|
136
|
-
`),await r.raw(`DELETE FROM ${i} WHERE email = ? AND purpose = ?`,[e,t]);let
|
|
136
|
+
`),await r.raw(`DELETE FROM ${i} WHERE email = ? AND purpose = ?`,[e,t]);let l=this.generateOtpCode(a),c=this.hashToken(l),u=new Date(Date.now()+n*1e3).toISOString();await r.raw(`INSERT INTO ${i} (email, code, purpose, expires_at, created_at) VALUES (?, ?, ?, ?, ?)`,[e,c,t,u,new Date().toISOString()]);let m=this.config.appName??process.env.APP_NAME??"Svelar",h=Math.ceil(n/60);return await this.sendAuthEmail("otp-code",e,{appName:m,"user.name":s.getAttribute("name")??e,code:l,purpose:t,expiresMinutes:String(h)}),!0}async verifyOtp(e,t,s="login"){let{Connection:r}=await Promise.resolve().then(()=>(x(),P)),i=this.config.otp?.table??"otp_codes",n=this.hashToken(t),a=await r.raw(`SELECT email, expires_at, used_at FROM ${i} WHERE code = ? AND email = ? AND purpose = ? AND used_at IS NULL`,[n,e,s]);if(a.length===0)return null;if(new Date(a[0].expires_at)<new Date)return await r.raw(`DELETE FROM ${i} WHERE email = ? AND purpose = ?`,[e,s]),null;await r.raw(`UPDATE ${i} SET used_at = ? WHERE code = ? AND email = ? AND purpose = ?`,[new Date().toISOString(),n,e,s]);let l=await this.config.model.where(this.config.identifierColumn,e).first();return l&&(this.currentUser=l),l}async attemptOtp(e,t,s,r="login"){let i=await this.verifyOtp(e,t,r);return i?(s&&(s.set("auth_user_id",i.getAttribute("id")),s.regenerateId()),i):null}async cleanupExpiredTokens(){let{Connection:e}=await Promise.resolve().then(()=>(x(),P)),t=new Date().toISOString(),s=0,r=0,i=0,n=this.config.passwordResets?.table??"password_resets",a=this.config.emailVerification?.table??"email_verifications",l=this.config.otp?.table??"otp_codes";try{s=(await e.raw(`DELETE FROM ${n} WHERE expires_at < ?`,[t]))?.changes??0}catch{}try{r=(await e.raw(`DELETE FROM ${a} WHERE expires_at < ?`,[t]))?.changes??0}catch{}try{i=(await e.raw(`DELETE FROM ${l} WHERE expires_at < ? OR used_at IS NOT NULL`,[t]))?.changes??0}catch{}return{passwordResets:s,verifications:r,otpCodes:i}}hashToken(e){let t=this.config.jwt?.secret??process.env.APP_KEY;if(!t)throw new Error("APP_KEY is not set. Set it in your .env file or pass jwt.secret in auth config.");return de("sha256",t).update(e).digest("hex")}generateOtpCode(e){let t=Ie(e);return Array.from(t).map(s=>(s%10).toString()).join("")}tablesEnsured=new Set;async ensureTable(e,t){if(this.tablesEnsured.has(e))return;let{Connection:s}=await Promise.resolve().then(()=>(x(),P));await s.raw(t),this.tablesEnsured.add(e)}async sendAuthEmail(e,t,s){try{let{EmailTemplates:r}=await Promise.resolve().then(()=>(di(),ci)),{Mailer:i}=await Promise.resolve().then(()=>(Bt(),Ws)),n=await r.render(e,s);await i.send({to:t,subject:n.subject,html:n.html,text:n.text})}catch(r){console.error(`[Auth] Failed to send ${e} email to ${t}:`,r.message)}}},ue=class extends T{constructor(t){super();this.authManager=t}async handle(t,s){let r=null;if(t.event.locals.session&&(r=await this.authManager.resolveFromSession(t.event.locals.session)),!r){let i=t.event.request.headers.get("authorization");if(i?.startsWith("Bearer ")){let n=i.slice(7);try{r=await this.authManager.resolveFromToken(n)}catch{r=await this.authManager.resolveFromApiToken(n)}}}return t.event.locals.user=r,t.event.locals.auth=this.authManager,s()}},Ht=class extends T{async handle(e,t){return e.event.locals.user?t():new Response(JSON.stringify({message:"Unauthenticated"}),{status:401,headers:{"Content-Type":"application/json"}})}}});import{appendFile as Xa,mkdir as eo}from"fs/promises";import{dirname as to}from"path";function L(){return new Date().toISOString()}var zt,je,Gs,Ys,Zs,Xs,er,Kt,tr=y(()=>{"use strict";R();zt={debug:0,info:1,warn:2,error:3,fatal:4},je=class{minLevel;format;constructor(e){this.minLevel=e.level??"debug",this.format=e.format??"text"}write(e){if(zt[e.level]<zt[this.minLevel])return;if(this.format==="json"){console.log(JSON.stringify(e));return}let t={debug:"\x1B[90m",info:"\x1B[34m",warn:"\x1B[33m",error:"\x1B[31m",fatal:"\x1B[35m"},s="\x1B[0m",r=t[e.level]??"",i=e.level.toUpperCase().padEnd(5),n=Object.keys(e.context).length>0?` ${JSON.stringify(e.context)}`:"",a=e.level==="error"||e.level==="fatal"?"error":"log";console[a](`${r}[${e.timestamp}] ${i}${s} ${e.message}${n}`)}},Gs=class{minLevel;path;format;initialized=!1;constructor(e){this.minLevel=e.level??"info",this.path=e.path??"storage/logs/app.log",this.format=e.format??"text"}async write(e){if(zt[e.level]<zt[this.minLevel])return;this.initialized||(await eo(to(this.path),{recursive:!0}),this.initialized=!0);let t;if(this.format==="json")t=JSON.stringify(e)+`
|
|
137
137
|
`;else{let s=e.level.toUpperCase().padEnd(5),r=Object.keys(e.context).length>0?` ${JSON.stringify(e.context)}`:"";t=`[${e.timestamp}] ${s} ${e.message}${r}
|
|
138
|
-
`}await
|
|
138
|
+
`}await Xa(this.path,t)}},Ys=class{minLevel="debug";channelNames;resolver;constructor(e,t){this.channelNames=e.channels??[],this.resolver=t,this.minLevel=e.level??"debug"}async write(e){for(let t of this.channelNames){let s=this.resolver(t);s&&await s.write(e)}}},Zs=class{minLevel="debug";write(){}},Xs=class{config={default:"console",channels:{console:{driver:"console",level:"debug"}}};channels=new Map;configure(e){this.config=e,this.channels.clear()}channel(e){return new er(this.resolveChannel(e))}debug(e,t={}){this.writeToDefault({level:"debug",message:e,context:t,timestamp:L()})}info(e,t={}){this.writeToDefault({level:"info",message:e,context:t,timestamp:L()})}warn(e,t={}){this.writeToDefault({level:"warn",message:e,context:t,timestamp:L()})}error(e,t={}){this.writeToDefault({level:"error",message:e,context:t,timestamp:L()})}fatal(e,t={}){this.writeToDefault({level:"fatal",message:e,context:t,timestamp:L()})}writeToDefault(e){this.resolveChannel(this.config.default).write(e)}resolveChannel(e){if(this.channels.has(e))return this.channels.get(e);let t=this.config.channels[e];if(!t){let r=new je({driver:"console"});return this.channels.set(e,r),r}let s=this.createChannel(t);return this.channels.set(e,s),s}createChannel(e){switch(e.driver){case"console":return new je(e);case"file":return new Gs(e);case"stack":return new Ys(e,t=>this.resolveChannel(t));case"null":return new Zs;default:return new je(e)}}},er=class{constructor(e){this.channel=e}debug(e,t={}){this.channel.write({level:"debug",message:e,context:t,timestamp:L()})}info(e,t={}){this.channel.write({level:"info",message:e,context:t,timestamp:L()})}warn(e,t={}){this.channel.write({level:"warn",message:e,context:t,timestamp:L()})}error(e,t={}){this.channel.write({level:"error",message:e,context:t,timestamp:L()})}fatal(e,t={}){this.channel.write({level:"fatal",message:e,context:t,timestamp:L()})}};Kt=C("svelar.log",()=>new Xs)});function Qt(o,e){throw new A(o,e??so(o))}function gi(o,e,t){o&&Qt(e,t)}function fi(o,e,t){o||Qt(e,t)}function so(o){return{400:"Bad request",401:"Unauthenticated",403:"Forbidden",404:"Not found",405:"Method not allowed",409:"Conflict",419:"Page expired",422:"Unprocessable entity",429:"Too many requests",500:"Internal server error",502:"Bad gateway",503:"Service unavailable",504:"Gateway timeout"}[o]??"An error occurred"}var A,Wt,sr,rr,Jt,Vt,me,ir=y(()=>{"use strict";tr();A=class extends Error{constructor(t,s,r){super(s);this.statusCode=t;this.details=r;this.name="HttpError"}},Wt=class extends A{constructor(e="The requested resource was not found"){super(404,e),this.name="NotFoundError"}},sr=class extends A{constructor(e="Unauthenticated"){super(401,e),this.name="UnauthorizedError"}},rr=class extends A{constructor(e="You do not have permission to perform this action"){super(403,e),this.name="ForbiddenError"}},Jt=class extends A{constructor(t,s="The given data was invalid"){super(422,s,{errors:t});this.errors=t;this.name="ValidationError"}},Vt=class extends Wt{constructor(e,t){super(t?`${e} with ID ${t} not found`:`${e} not found`),this.name="ModelNotFoundError"}};me=class{config;constructor(e={}){this.config={debug:process.env.NODE_ENV!=="production",dontReport:[Jt,Wt,sr,rr],...e}}async handle(e,t){let s=e instanceof Error?e:new Error(String(e));return await this.reportError(s,t),this.config.render?this.config.render(s,t):this.renderError(s)}handleSvelteKitError(){return({error:e,event:t,status:s,message:r})=>{let i=e instanceof Error?e:new Error(String(e));return this.reportError(i,t),i instanceof A?{message:i.message,status:i.statusCode,...i.details??{},...this.config.debug?{stack:i.stack}:{}}:{message:this.config.debug?i.message:"An unexpected error occurred",status:s,...this.config.debug?{stack:i.stack}:{}}}}middleware(){let e=this;return async(t,s)=>{try{return await s()}catch(r){return e.handle(r,t.event)}}}async reportError(e,t){if(this.config.dontReport){for(let r of this.config.dontReport)if(e instanceof r)return}let s={error:e.name,...t?.url?{url:t.url.toString()}:{},...e.stack?{stack:e.stack}:{}};if(Kt.error(e.message,s),this.config.report)try{await this.config.report(e,t?{url:t.url?.toString()}:void 0)}catch{}}renderError(e){if(e instanceof A){let s={message:e.message};return e instanceof Jt&&(s.errors=e.errors),e.details&&Object.assign(s,e.details),this.config.debug&&(s.exception=e.name,s.stack=e.stack?.split(`
|
|
139
139
|
`).map(r=>r.trim())),new Response(JSON.stringify(s),{status:e.statusCode,headers:{"Content-Type":"application/json"}})}let t={message:this.config.debug?e.message:"Internal server error"};return this.config.debug&&(t.exception=e.name,t.stack=e.stack?.split(`
|
|
140
|
-
`).map(s=>s.trim())),new Response(JSON.stringify(t),{status:500,headers:{"Content-Type":"application/json"}})}}});function ki(l={}){let{auth:e,secret:t=(()=>{throw new Error("APP_KEY is not set. Pass `secret` to createSvelarApp() \u2014 e.g. secret: env.APP_KEY (from $env/dynamic/private).")})(),sessionStore:s,sessionLifetime:r=86400,rateLimit:i=100,rateLimitWindow:n=6e4,csrfPaths:a=["/api/"],csrfExcludePaths:o=["/api/webhooks"],authThrottleAttempts:c=5,authThrottleDecay:u=1,debug:d=process.env.NODE_ENV!=="production",middleware:p=[],namedMiddleware:f={},i18n:b,errorConfig:C={}}=l,k=[new ie,new se({maxRequests:i,windowMs:n}),new re({onlyPaths:a,excludePaths:o}),new ce({store:s??new H,secret:t,lifetime:r})];e&&k.push(new me(e)),k.push(...p);let as={"auth-throttle":new ne({maxAttempts:c,decayMinutes:u}),...f},ye=new pe({debug:d,...C}),Be=er({middleware:k,namedMiddleware:as,onError:(be,N)=>ye.handle(be,N)}),ve;if(b){let{paraglideMiddleware:be,getTextDirection:N=()=>"ltr"}=b;ve=tr(async({event:z,resolve:gn})=>be(z.request,({request:fn,locale:$r})=>(z.request=fn,gn(z,{transformPageChunk:({html:yn})=>yn.replace("%lang%",$r).replace("%dir%",N($r))}))),Be)}else ve=Be;return{handle:ve,handleError:ye.handleSvelteKitError()}}function er(l={}){let e=new L;if(l.middleware)for(let t of l.middleware)e.use(t);if(l.namedMiddleware)for(let[t,s]of Object.entries(l.namedMiddleware))e.register(t,s);return async function({event:s,resolve:r}){let i={event:s,params:s.params??{},locals:s.locals??{}};try{l.app&&!l.app.isBooted()&&await l.app.bootstrap();let n=await e.execute(i,async()=>r(s));return n instanceof Response?n:r(s)}catch(n){if(l.onError){let a=await l.onError(n,s);if(a instanceof Response)return a}return console.error("[Svelar] Unhandled error in hooks:",n),new Response(JSON.stringify({message:process.env.NODE_ENV==="production"?"Internal server error":n.message}),{status:500,headers:{"Content-Type":"application/json"}})}}}function tr(...l){return async function({event:t,resolve:s}){let r=s;for(let i=l.length-1;i>=0;i--){let n=l[i],a=r;r=o=>n({event:o,resolve:a})}return r(t)}}var sr=y(()=>{"use strict";ae();$s();zs();Zs()});function $i(l,e){let t=process.env[l];return t===void 0?e!==void 0?e:"":t==="true"?!0:t==="false"?!1:t==="null"?null:/^\d+$/.test(t)?Number(t):t}var rr,Ai,Di=y(()=>{"use strict";R();rr=class{items=new Map;clear(){this.items.clear()}load(e){for(let[t,s]of Object.entries(e))this.set(t,s)}async loadFromDirectory(e){let{resolve:t,basename:s,extname:r}=await import("path"),{existsSync:i,readdirSync:n}=await import("fs"),{pathToFileURL:a}=await import("url"),o=t(e);if(!i(o))return[];let c=n(o).filter(d=>(d.endsWith(".ts")||d.endsWith(".js"))&&!d.startsWith(".")),u=[];for(let d of c){let p=s(d,r(d)),f=t(o,d);try{let C=await import(a(f).href),k=C.default??C.config??C;k&&typeof k=="object"&&!Array.isArray(k)&&(this.set(p,k),u.push(p))}catch{}}return u}get(e,t){let s=e.split("."),r=this.items.get(s[0]);for(let i=1;i<s.length;i++){if(r==null)return t;r=r[s[i]]}return r??t}set(e,t){let s=e.split(".");if(s.length===1){this.items.set(e,t);return}let r=this.items.get(s[0]);(r===void 0||typeof r!="object")&&(r={},this.items.set(s[0],r));let i=r;for(let n=1;n<s.length-1;n++)(i[s[n]]===void 0||typeof i[s[n]]!="object")&&(i[s[n]]={}),i=i[s[n]];i[s[s.length-1]]=t}has(e){return this.get(e)!==void 0}all(){let e={};for(let[t,s]of this.items)e[t]=s;return e}},Ai=w("svelar.config",()=>new rr)});import{z as S}from"zod";function Ni(l,e){let t=l.safeParse(e);if(t.success)return{success:!0,data:t.data};let s={};for(let r of t.error.issues){let i=r.path.length>0?r.path:["_root"],n=s;for(let o=0;o<i.length-1;o++){let c=i[o];c in n||(n[c]={}),n=n[c]}let a=i[i.length-1];n[a]||(n[a]=[]),n[a].push(r.message)}return{success:!1,errors:s}}var Mi,_i=y(()=>{"use strict";Mi={required:()=>S.string().min(1,"This field is required"),email:()=>S.string().email("Must be a valid email address"),string:(l,e)=>{let t=S.string();return l!==void 0&&(t=t.min(l)),e!==void 0&&(t=t.max(e)),t},number:(l,e)=>{let t=S.number();return l!==void 0&&(t=t.min(l)),e!==void 0&&(t=t.max(e)),t},integer:()=>S.number().int(),boolean:()=>S.boolean(),date:()=>S.coerce.date(),url:()=>S.string().url(),uuid:()=>S.string().uuid(),enum:l=>S.enum(l),array:l=>S.array(l),nullable:l=>l.nullable(),optional:l=>l.optional(),confirmed:(l="password")=>S.object({[l]:S.string(),[`${l}_confirmation`]:S.string()}).refine(e=>e[l]===e[`${l}_confirmation`],{message:"Confirmation does not match",path:[`${l}_confirmation`]}),min:l=>S.number().min(l),max:l=>S.number().max(l),between:(l,e)=>S.number().min(l).max(e),regex:(l,e)=>S.string().regex(l,e),ip:()=>S.string().refine(l=>{let e=l.split(".");return e.length!==4?!1:e.every(t=>{let s=Number(t);return Number.isInteger(s)&&s>=0&&s<=255})},{message:"Must be a valid IP address"}),json:()=>S.string().refine(l=>{try{return JSON.parse(l),!0}catch{return!1}},{message:"Must be valid JSON"})}});var Ii={};E(Ii,{FormAuthorizationError:()=>ge,FormRequest:()=>qe,FormValidationError:()=>he});var qe,he,ge,ir=y(()=>{"use strict";qe=class{authorize(e){return!0}messages(){return{}}attributes(){return{}}passedValidation(e){return e}failedValidation(e){throw new he(e)}failedAuthorization(){throw new ge}async parseBody(e){let t=e.request.headers.get("content-type")??"";if(t.includes("application/json"))return e.request.json();if(t.includes("multipart/form-data")||t.includes("application/x-www-form-urlencoded")){let s=await e.request.formData();return Object.fromEntries(s)}return Object.fromEntries(e.url.searchParams)}static async validate(e){let t=new this;await t.authorize(e)||t.failedAuthorization();let r=await t.parseBody(e),i={...Object.fromEntries(e.url.searchParams),...e.params,...r},a=t.rules().safeParse(i);if(!a.success){let o={},c=t.messages(),u=t.attributes();for(let d of a.error.issues){let p=d.path.join("."),f=u[p]??p;o[f]||(o[f]=[]);let b=`${p}.${d.code}`,C=c[b]??c[p];o[f].push(C??d.message)}t.failedValidation(o)}return t.passedValidation(a.data)}},he=class extends Error{constructor(t){super("The given data was invalid.");this.errors=t;this.name="FormValidationError"}statusCode=422;toResponse(){return new Response(JSON.stringify({message:this.message,errors:this.errors}),{status:422,headers:{"Content-Type":"application/json"}})}},ge=class extends Error{statusCode=403;constructor(e="This action is unauthorized."){super(e),this.name="FormAuthorizationError"}toResponse(){return new Response(JSON.stringify({message:this.message}),{status:403,headers:{"Content-Type":"application/json"}})}}});import{readFile as ji,writeFile as Xa,unlink as Za,mkdir as Ue,readdir as nr,stat as Oi,copyFile as eo,rename as to}from"fs/promises";import{existsSync as so}from"fs";import{join as ro,dirname as Jt}from"path";var ar,Vt,or,Li,qi=y(()=>{"use strict";R();ar=class{constructor(e){this.config=e;if(!e.root)throw new Error('Local disk requires a "root" path.')}resolve(e){return ro(this.config.root,e)}async get(e){return ji(this.resolve(e))}async getText(e){return ji(this.resolve(e),"utf-8")}async put(e,t){let s=this.resolve(e);await Ue(Jt(s),{recursive:!0}),await Xa(s,t)}async append(e,t){let{appendFile:s}=await import("fs/promises"),r=this.resolve(e);await Ue(Jt(r),{recursive:!0}),await s(r,t)}async exists(e){return so(this.resolve(e))}async delete(e){try{return await Za(this.resolve(e)),!0}catch{return!1}}async copy(e,t){let s=this.resolve(t);await Ue(Jt(s),{recursive:!0}),await eo(this.resolve(e),s)}async move(e,t){let s=this.resolve(t);await Ue(Jt(s),{recursive:!0}),await to(this.resolve(e),s)}async files(e=""){let t=this.resolve(e);try{return(await nr(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 nr(s,{withFileTypes:!0});for(let i of r){let n=e?`${e}/${i.name}`:i.name;i.isFile()?t.push(n):i.isDirectory()&&t.push(...await this.allFiles(n))}}catch{}return t}async directories(e=""){let t=this.resolve(e);try{return(await nr(t,{withFileTypes:!0})).filter(r=>r.isDirectory()).map(r=>e?`${e}/${r.name}`:r.name)}catch{return[]}}async makeDirectory(e){await Ue(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 Oi(this.resolve(e))).size}async lastModified(e){return(await Oi(this.resolve(e))).mtime}url(e){return`${this.config.urlPrefix??""}/${e}`}},Vt=class{config;_client=null;_s3Module=null;constructor(e){if(!e.bucket)throw new Error('S3 disk requires a "bucket" name.');this.config=e}async getS3(){if(this._s3Module)return this._s3Module;try{return this._s3Module=await Function('return import("@aws-sdk/client-s3")')(),this._s3Module}catch{throw new Error("S3 storage driver requires @aws-sdk/client-s3. Install it with: npm install @aws-sdk/client-s3")}}async getClient(){if(this._client)return this._client;let e=await this.getS3();return this._client=new e.S3Client({region:this.config.region??"us-east-1",endpoint:this.config.endpoint,forcePathStyle:this.config.forcePathStyle??!0,credentials:{accessKeyId:this.config.accessKeyId??"",secretAccessKey:this.config.secretAccessKey??""}}),this._client}key(e){let t=this.config.prefix;return t?`${t}/${e}`:e}async get(e){let t=await this.getS3(),i=await(await(await this.getClient()).send(new t.GetObjectCommand({Bucket:this.config.bucket,Key:this.key(e)}))).Body.transformToByteArray();return Buffer.from(i)}async getText(e){return(await this.get(e)).toString("utf-8")}async put(e,t){let s=await this.getS3(),r=await this.getClient(),i=typeof t=="string"?Buffer.from(t,"utf-8"):t;await r.send(new s.PutObjectCommand({Bucket:this.config.bucket,Key:this.key(e),Body:i}))}async append(e,t){let s=null;try{s=await this.get(e)}catch{}let r=typeof t=="string"?Buffer.from(t,"utf-8"):t,i=s?Buffer.concat([s,r]):r;await this.put(e,i)}async exists(e){let t=await this.getS3(),s=await this.getClient();try{return await s.send(new t.HeadObjectCommand({Bucket:this.config.bucket,Key:this.key(e)})),!0}catch{return!1}}async delete(e){let t=await this.getS3(),s=await this.getClient();try{return await s.send(new t.DeleteObjectCommand({Bucket:this.config.bucket,Key:this.key(e)})),!0}catch{return!1}}async copy(e,t){let s=await this.getS3();await(await this.getClient()).send(new s.CopyObjectCommand({Bucket:this.config.bucket,CopySource:`${this.config.bucket}/${this.key(e)}`,Key:this.key(t)}))}async move(e,t){await this.copy(e,t),await this.delete(e)}async files(e=""){let t=await this.getS3(),s=await this.getClient(),r=this.key(e?`${e}/`:"");try{return((await s.send(new t.ListObjectsV2Command({Bucket:this.config.bucket,Prefix:r,Delimiter:"/"}))).Contents??[]).map(n=>n.Key).filter(n=>n!==r).map(n=>{let a=this.config.prefix;return a?n.slice(a.length+1):n})}catch{return[]}}async allFiles(e=""){let t=await this.getS3(),s=await this.getClient(),r=this.key(e?`${e}/`:""),i=[],n;do{let a=await s.send(new t.ListObjectsV2Command({Bucket:this.config.bucket,Prefix:r,ContinuationToken:n}));for(let o of a.Contents??[]){let c=this.config.prefix,u=c?o.Key.slice(c.length+1):o.Key;u&&i.push(u)}n=a.IsTruncated?a.NextContinuationToken:void 0}while(n);return i}async directories(e=""){let t=await this.getS3(),s=await this.getClient(),r=this.key(e?`${e}/`:"");try{return((await s.send(new t.ListObjectsV2Command({Bucket:this.config.bucket,Prefix:r,Delimiter:"/"}))).CommonPrefixes??[]).map(n=>{let a=this.config.prefix;return(a?n.Prefix.slice(a.length+1):n.Prefix).replace(/\/$/,"")}).filter(n=>n.length>0)}catch{return[]}}async makeDirectory(e){}async deleteDirectory(e){let t=await this.allFiles(e);for(let s of t)await this.delete(s)}async size(e){let t=await this.getS3();return(await(await this.getClient()).send(new t.HeadObjectCommand({Bucket:this.config.bucket,Key:this.key(e)}))).ContentLength??0}async lastModified(e){let t=await this.getS3();return(await(await this.getClient()).send(new t.HeadObjectCommand({Bucket:this.config.bucket,Key:this.key(e)}))).LastModified??new Date}url(e){let t=this.config.urlPrefix;if(t)return`${t}/${e}`;let s=this.config.endpoint??`https://s3.${this.config.region??"us-east-1"}.amazonaws.com`;return this.config.forcePathStyle!==!1?`${s}/${this.config.bucket}/${this.key(e)}`:`${s.replace("://",`://${this.config.bucket}.`)}/${this.key(e)}`}async temporaryUrl(e,t=3600){try{let s=await Function('return import("@aws-sdk/s3-request-presigner")')(),r=await this.getS3(),i=await this.getClient(),n=new r.GetObjectCommand({Bucket:this.config.bucket,Key:this.key(e)});return await s.getSignedUrl(i,n,{expiresIn:t})}catch{throw new Error("Pre-signed URLs require @aws-sdk/s3-request-presigner. Install it with: npm install @aws-sdk/s3-request-presigner")}}async ensureBucket(){let e=await this.getS3(),t=await this.getClient();try{await t.send(new e.HeadBucketCommand({Bucket:this.config.bucket}))}catch{await t.send(new e.CreateBucketCommand({Bucket:this.config.bucket}))}}},or=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 ar(e);case"s3":return new Vt(e);default:throw new Error(`Unknown storage driver: ${e.driver}`)}}s3Disk(e){let t=this.disk(e);if(!(t instanceof Vt))throw new Error(`Disk "${e??this.config?.default}" is not an S3 disk.`);return t}},Li=w("svelar.storage",()=>new or)});import{readFile as io,writeFile as no,unlink as Ui,mkdir as Bi}from"fs/promises";import{join as ao,dirname as oo}from"path";import{createHash as lo}from"crypto";var lr,cr,dr,ur,Fi,Hi=y(()=>{"use strict";R();lr=class{store=new Map;async get(e){let t=this.store.get(e);return t?t.expiresAt&&Date.now()>t.expiresAt?(this.store.delete(e),null):t.value:null}async put(e,t,s){this.store.set(e,{value:t,expiresAt:s?Date.now()+s*1e3:null})}async forget(e){return this.store.delete(e)}async flush(){this.store.clear()}async has(e){let t=this.store.get(e);return t?t.expiresAt&&Date.now()>t.expiresAt?(this.store.delete(e),!1):!0:!1}async increment(e,t=1){let r=(await this.get(e)??0)+t,i=this.store.get(e);return await this.put(e,r,i?.expiresAt?Math.ceil((i.expiresAt-Date.now())/1e3):void 0),r}async decrement(e,t=1){return this.increment(e,-t)}},cr=class{basePath;constructor(e){this.basePath=e.path??"storage/cache"}filePath(e){let t=lo("md5").update(e).digest("hex");return ao(this.basePath,t.slice(0,2),t)}async get(e){let t=this.filePath(e);try{let s=await io(t,"utf-8"),r=JSON.parse(s);return r.expiresAt&&Date.now()>r.expiresAt?(await Ui(t).catch(()=>{}),null):r.value}catch{return null}}async put(e,t,s){let r=this.filePath(e),i={value:t,expiresAt:s?Date.now()+s*1e3:null};await Bi(oo(r),{recursive:!0}),await no(r,JSON.stringify(i))}async forget(e){try{return await Ui(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 Bi(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)}},dr=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}},ur=class{config={default:"memory",stores:{memory:{driver:"memory"}}};stores=new Map;configure(e){this.config=e,this.stores.clear()}store(e){let t=e??this.config.default;if(this.stores.has(t))return this.stores.get(t);let s=this.config.stores[t];if(!s)throw new Error(`Cache store "${t}" is not defined.`);let r=this.createStore(s);return this.stores.set(t,r),r}async get(e,t){let s=this.store();return await s.has(e)?s.get(e):t??null}async put(e,t,s){return this.store().put(e,t,s??this.config.stores[this.config.default]?.ttl)}async forget(e){return this.store().forget(e)}async flush(){return this.store().flush()}async has(e){return this.store().has(e)}async increment(e,t){return this.store().increment(e,t)}async decrement(e,t){return this.store().decrement(e,t)}async remember(e,t,s){let r=await this.store().get(e);if(r!==null)return r;let i=await s();return await this.store().put(e,i,t),i}async rememberForever(e,t){let s=await this.store().get(e);if(s!==null)return s;let r=await t();return await this.store().put(e,r),r}async pull(e,t){let s=await this.get(e,t);return await this.forget(e),s}createStore(e){switch(e.driver){case"memory":return new lr;case"file":return new cr(e);case"null":return new dr;case"redis":throw new Error("Redis cache requires ioredis. Install: npm install ioredis");default:throw new Error(`Unknown cache driver: ${e.driver}`)}}},Fi=w("svelar.cache",()=>new ur)});var Qt,mr,pr,hr,zi,Ki=y(()=>{"use strict";R();Qt=class{},mr=class{async send(e,t){if(!t.toMail)return;let s=t.toMail(e),r=e.routeNotificationForMail?.()??e.getAttribute("email");if(!r){console.warn("[Notifications] No email address for notifiable.");return}try{let{Mailer:i}=await Promise.resolve().then(()=>(Lt(),Bs));await i.send({to:r,subject:s.subject,html:s.html,text:s.text,from:s.from})}catch(i){console.error("[Notifications] Failed to send mail notification:",i)}}},pr=class{table;constructor(e="notifications"){this.table=e}async send(e,t){if(!t.toDatabase)return;let s=t.toDatabase(e);try{let{Connection:r}=await Promise.resolve().then(()=>(x(),P));await r.raw(`INSERT INTO ${this.table} (id, notifiable_id, type, data, read_at, created_at)
|
|
141
|
-
VALUES (?, ?, ?, ?, NULL, ?)`,[crypto.randomUUID(),e.getAttribute("id"),s.type,JSON.stringify(s.data),new Date().toISOString()])}catch(r){console.error("[Notifications] Failed to store database notification:",r)}}},
|
|
140
|
+
`).map(s=>s.trim())),new Response(JSON.stringify(t),{status:500,headers:{"Content-Type":"application/json"}})}}});function bi(o={}){let{auth:e,secret:t=(()=>{throw new Error("APP_KEY is not set. Pass `secret` to createSvelarApp() \u2014 e.g. secret: env.APP_KEY (from $env/dynamic/private).")})(),sessionStore:s,sessionLifetime:r=86400,rateLimit:i=100,rateLimitWindow:n=6e4,csrfPaths:a=["/api/"],csrfExcludePaths:l=["/api/webhooks"],authThrottleAttempts:c=5,authThrottleDecay:u=1,debug:m=process.env.NODE_ENV!=="production",middleware:h=[],namedMiddleware:d={},i18n:b,errorConfig:w={}}=o,E=[new re,new te({maxRequests:i,windowMs:n}),new se({onlyPaths:a,excludePaths:l}),new le({store:s??new H,secret:t,lifetime:r})];e&&E.push(new ue(e)),E.push(...h);let cs={"auth-throttle":new ie({maxAttempts:c,decayMinutes:u}),...d},ds=new me({debug:m,...w}),Ue=nr({middleware:E,namedMiddleware:cs,onError:(fe,be)=>ds.handle(fe,be)}),z;if(b){let{paraglideMiddleware:fe,getTextDirection:be=()=>"ltr"}=b;z=ar(async({event:$,resolve:Be})=>fe($.request,({request:us,locale:Fe})=>($.request=us,Be($,{transformPageChunk:({html:He})=>He.replace("%lang%",Fe).replace("%dir%",be(Fe))}))),Ue)}else z=Ue;return{handle:z,handleError:ds.handleSvelteKitError()}}function nr(o={}){let e=new O;if(o.middleware)for(let t of o.middleware)e.use(t);if(o.namedMiddleware)for(let[t,s]of Object.entries(o.namedMiddleware))e.register(t,s);return async function({event:s,resolve:r}){let i={event:s,params:s.params??{},locals:s.locals??{}};try{o.app&&!o.app.isBooted()&&await o.app.bootstrap();let n=await e.execute(i,async()=>r(s));return n instanceof Response?n:r(s)}catch(n){if(o.onError){let a=await o.onError(n,s);if(a instanceof Response)return a}return console.error("[Svelar] Unhandled error in hooks:",n),new Response(JSON.stringify({message:process.env.NODE_ENV==="production"?"Internal server error":n.message}),{status:500,headers:{"Content-Type":"application/json"}})}}}function ar(...o){return async function({event:t,resolve:s}){let r=s;for(let i=o.length-1;i>=0;i--){let n=o[i],a=r;r=l=>n({event:l,resolve:a})}return r(t)}}var or=y(()=>{"use strict";ne();_s();Qs();ir()});function yi(o,e){let t=process.env[o];return t===void 0?e!==void 0?e:"":t==="true"?!0:t==="false"?!1:t==="null"?null:/^\d+$/.test(t)?Number(t):t}var lr,vi,wi=y(()=>{"use strict";R();lr=class{items=new Map;clear(){this.items.clear()}load(e){for(let[t,s]of Object.entries(e))this.set(t,s)}async loadFromDirectory(e){let{resolve:t,basename:s,extname:r}=await import("path"),{existsSync:i,readdirSync:n}=await import("fs"),{pathToFileURL:a}=await import("url"),l=t(e);if(!i(l))return[];let c=n(l).filter(m=>(m.endsWith(".ts")||m.endsWith(".js"))&&!m.startsWith(".")),u=[];for(let m of c){let h=s(m,r(m)),d=t(l,m);try{let w=await import(a(d).href),E=w.default??w.config??w;E&&typeof E=="object"&&!Array.isArray(E)&&(this.set(h,E),u.push(h))}catch{}}return u}get(e,t){let s=e.split("."),r=this.items.get(s[0]);for(let i=1;i<s.length;i++){if(r==null)return t;r=r[s[i]]}return r??t}set(e,t){let s=e.split(".");if(s.length===1){this.items.set(e,t);return}let r=this.items.get(s[0]);(r===void 0||typeof r!="object")&&(r={},this.items.set(s[0],r));let i=r;for(let n=1;n<s.length-1;n++)(i[s[n]]===void 0||typeof i[s[n]]!="object")&&(i[s[n]]={}),i=i[s[n]];i[s[s.length-1]]=t}has(e){return this.get(e)!==void 0}all(){let e={};for(let[t,s]of this.items)e[t]=s;return e}},vi=C("svelar.config",()=>new lr)});import{z as S}from"zod";function xi(o,e){let t=o.safeParse(e);if(t.success)return{success:!0,data:t.data};let s={};for(let r of t.error.issues){let i=r.path.length>0?r.path:["_root"],n=s;for(let l=0;l<i.length-1;l++){let c=i[l];c in n||(n[c]={}),n=n[c]}let a=i[i.length-1];n[a]||(n[a]=[]),n[a].push(r.message)}return{success:!1,errors:s}}var Ci,Pi=y(()=>{"use strict";Ci={required:()=>S.string().min(1,"This field is required"),email:()=>S.string().email("Must be a valid email address"),string:(o,e)=>{let t=S.string();return o!==void 0&&(t=t.min(o)),e!==void 0&&(t=t.max(e)),t},number:(o,e)=>{let t=S.number();return o!==void 0&&(t=t.min(o)),e!==void 0&&(t=t.max(e)),t},integer:()=>S.number().int(),boolean:()=>S.boolean(),date:()=>S.coerce.date(),url:()=>S.string().url(),uuid:()=>S.string().uuid(),enum:o=>S.enum(o),array:o=>S.array(o),nullable:o=>o.nullable(),optional:o=>o.optional(),confirmed:(o="password")=>S.object({[o]:S.string(),[`${o}_confirmation`]:S.string()}).refine(e=>e[o]===e[`${o}_confirmation`],{message:"Confirmation does not match",path:[`${o}_confirmation`]}),min:o=>S.number().min(o),max:o=>S.number().max(o),between:(o,e)=>S.number().min(o).max(e),regex:(o,e)=>S.string().regex(o,e),ip:()=>S.string().refine(o=>{let e=o.split(".");return e.length!==4?!1:e.every(t=>{let s=Number(t);return Number.isInteger(s)&&s>=0&&s<=255})},{message:"Must be a valid IP address"}),json:()=>S.string().refine(o=>{try{return JSON.parse(o),!0}catch{return!1}},{message:"Must be valid JSON"})}});var Si={};k(Si,{FormAuthorizationError:()=>he,FormRequest:()=>Oe,FormValidationError:()=>pe});var Oe,pe,he,cr=y(()=>{"use strict";Oe=class{authorize(e){return!0}messages(){return{}}attributes(){return{}}passedValidation(e){return e}failedValidation(e){throw new pe(e)}failedAuthorization(){throw new he}async parseBody(e){let t=e.request.headers.get("content-type")??"";if(t.includes("application/json"))return e.request.json();if(t.includes("multipart/form-data")||t.includes("application/x-www-form-urlencoded")){let s=await e.request.formData();return Object.fromEntries(s)}return Object.fromEntries(e.url.searchParams)}static async validate(e){let t=new this;await t.authorize(e)||t.failedAuthorization();let r=await t.parseBody(e),i={...Object.fromEntries(e.url.searchParams),...e.params,...r},a=t.rules().safeParse(i);if(!a.success){let l={},c=t.messages(),u=t.attributes();for(let m of a.error.issues){let h=m.path.join("."),d=u[h]??h;l[d]||(l[d]=[]);let b=`${h}.${m.code}`,w=c[b]??c[h];l[d].push(w??m.message)}t.failedValidation(l)}return t.passedValidation(a.data)}},pe=class extends Error{constructor(t){super("The given data was invalid.");this.errors=t;this.name="FormValidationError"}statusCode=422;toResponse(){return new Response(JSON.stringify({message:this.message,errors:this.errors}),{status:422,headers:{"Content-Type":"application/json"}})}},he=class extends Error{statusCode=403;constructor(e="This action is unauthorized."){super(e),this.name="FormAuthorizationError"}toResponse(){return new Response(JSON.stringify({message:this.message}),{status:403,headers:{"Content-Type":"application/json"}})}}});import{readFile as Ri,writeFile as ro,unlink as io,mkdir as qe,readdir as dr,stat as Ti,copyFile as no,rename as ao}from"fs/promises";import{existsSync as oo}from"fs";import{join as lo,dirname as Gt}from"path";var ur,Yt,mr,Ei,ki=y(()=>{"use strict";R();ur=class{constructor(e){this.config=e;if(!e.root)throw new Error('Local disk requires a "root" path.')}resolve(e){return lo(this.config.root,e)}async get(e){return Ri(this.resolve(e))}async getText(e){return Ri(this.resolve(e),"utf-8")}async put(e,t){let s=this.resolve(e);await qe(Gt(s),{recursive:!0}),await ro(s,t)}async append(e,t){let{appendFile:s}=await import("fs/promises"),r=this.resolve(e);await qe(Gt(r),{recursive:!0}),await s(r,t)}async exists(e){return oo(this.resolve(e))}async delete(e){try{return await io(this.resolve(e)),!0}catch{return!1}}async copy(e,t){let s=this.resolve(t);await qe(Gt(s),{recursive:!0}),await no(this.resolve(e),s)}async move(e,t){let s=this.resolve(t);await qe(Gt(s),{recursive:!0}),await ao(this.resolve(e),s)}async files(e=""){let t=this.resolve(e);try{return(await dr(t,{withFileTypes:!0})).filter(r=>r.isFile()).map(r=>e?`${e}/${r.name}`:r.name)}catch{return[]}}async allFiles(e=""){let t=[],s=this.resolve(e);try{let r=await dr(s,{withFileTypes:!0});for(let i of r){let n=e?`${e}/${i.name}`:i.name;i.isFile()?t.push(n):i.isDirectory()&&t.push(...await this.allFiles(n))}}catch{}return t}async directories(e=""){let t=this.resolve(e);try{return(await dr(t,{withFileTypes:!0})).filter(r=>r.isDirectory()).map(r=>e?`${e}/${r.name}`:r.name)}catch{return[]}}async makeDirectory(e){await qe(this.resolve(e),{recursive:!0})}async deleteDirectory(e){let{rm:t}=await import("fs/promises");await t(this.resolve(e),{recursive:!0,force:!0})}async size(e){return(await Ti(this.resolve(e))).size}async lastModified(e){return(await Ti(this.resolve(e))).mtime}url(e){return`${this.config.urlPrefix??""}/${e}`}},Yt=class{config;_client=null;_s3Module=null;constructor(e){if(!e.bucket)throw new Error('S3 disk requires a "bucket" name.');this.config=e}async getS3(){if(this._s3Module)return this._s3Module;try{return this._s3Module=await Function('return import("@aws-sdk/client-s3")')(),this._s3Module}catch{throw new Error("S3 storage driver requires @aws-sdk/client-s3. Install it with: npm install @aws-sdk/client-s3")}}async getClient(){if(this._client)return this._client;let e=await this.getS3();return this._client=new e.S3Client({region:this.config.region??"us-east-1",endpoint:this.config.endpoint,forcePathStyle:this.config.forcePathStyle??!0,credentials:{accessKeyId:this.config.accessKeyId??"",secretAccessKey:this.config.secretAccessKey??""}}),this._client}key(e){let t=this.config.prefix;return t?`${t}/${e}`:e}async get(e){let t=await this.getS3(),i=await(await(await this.getClient()).send(new t.GetObjectCommand({Bucket:this.config.bucket,Key:this.key(e)}))).Body.transformToByteArray();return Buffer.from(i)}async getText(e){return(await this.get(e)).toString("utf-8")}async put(e,t){let s=await this.getS3(),r=await this.getClient(),i=typeof t=="string"?Buffer.from(t,"utf-8"):t;await r.send(new s.PutObjectCommand({Bucket:this.config.bucket,Key:this.key(e),Body:i}))}async append(e,t){let s=null;try{s=await this.get(e)}catch{}let r=typeof t=="string"?Buffer.from(t,"utf-8"):t,i=s?Buffer.concat([s,r]):r;await this.put(e,i)}async exists(e){let t=await this.getS3(),s=await this.getClient();try{return await s.send(new t.HeadObjectCommand({Bucket:this.config.bucket,Key:this.key(e)})),!0}catch{return!1}}async delete(e){let t=await this.getS3(),s=await this.getClient();try{return await s.send(new t.DeleteObjectCommand({Bucket:this.config.bucket,Key:this.key(e)})),!0}catch{return!1}}async copy(e,t){let s=await this.getS3();await(await this.getClient()).send(new s.CopyObjectCommand({Bucket:this.config.bucket,CopySource:`${this.config.bucket}/${this.key(e)}`,Key:this.key(t)}))}async move(e,t){await this.copy(e,t),await this.delete(e)}async files(e=""){let t=await this.getS3(),s=await this.getClient(),r=this.key(e?`${e}/`:"");try{return((await s.send(new t.ListObjectsV2Command({Bucket:this.config.bucket,Prefix:r,Delimiter:"/"}))).Contents??[]).map(n=>n.Key).filter(n=>n!==r).map(n=>{let a=this.config.prefix;return a?n.slice(a.length+1):n})}catch{return[]}}async allFiles(e=""){let t=await this.getS3(),s=await this.getClient(),r=this.key(e?`${e}/`:""),i=[],n;do{let a=await s.send(new t.ListObjectsV2Command({Bucket:this.config.bucket,Prefix:r,ContinuationToken:n}));for(let l of a.Contents??[]){let c=this.config.prefix,u=c?l.Key.slice(c.length+1):l.Key;u&&i.push(u)}n=a.IsTruncated?a.NextContinuationToken:void 0}while(n);return i}async directories(e=""){let t=await this.getS3(),s=await this.getClient(),r=this.key(e?`${e}/`:"");try{return((await s.send(new t.ListObjectsV2Command({Bucket:this.config.bucket,Prefix:r,Delimiter:"/"}))).CommonPrefixes??[]).map(n=>{let a=this.config.prefix;return(a?n.Prefix.slice(a.length+1):n.Prefix).replace(/\/$/,"")}).filter(n=>n.length>0)}catch{return[]}}async makeDirectory(e){}async deleteDirectory(e){let t=await this.allFiles(e);for(let s of t)await this.delete(s)}async size(e){let t=await this.getS3();return(await(await this.getClient()).send(new t.HeadObjectCommand({Bucket:this.config.bucket,Key:this.key(e)}))).ContentLength??0}async lastModified(e){let t=await this.getS3();return(await(await this.getClient()).send(new t.HeadObjectCommand({Bucket:this.config.bucket,Key:this.key(e)}))).LastModified??new Date}url(e){let t=this.config.urlPrefix;if(t)return`${t}/${e}`;let s=this.config.endpoint??`https://s3.${this.config.region??"us-east-1"}.amazonaws.com`;return this.config.forcePathStyle!==!1?`${s}/${this.config.bucket}/${this.key(e)}`:`${s.replace("://",`://${this.config.bucket}.`)}/${this.key(e)}`}async temporaryUrl(e,t=3600){try{let s=await Function('return import("@aws-sdk/s3-request-presigner")')(),r=await this.getS3(),i=await this.getClient(),n=new r.GetObjectCommand({Bucket:this.config.bucket,Key:this.key(e)});return await s.getSignedUrl(i,n,{expiresIn:t})}catch{throw new Error("Pre-signed URLs require @aws-sdk/s3-request-presigner. Install it with: npm install @aws-sdk/s3-request-presigner")}}async ensureBucket(){let e=await this.getS3(),t=await this.getClient();try{await t.send(new e.HeadBucketCommand({Bucket:this.config.bucket}))}catch{await t.send(new e.CreateBucketCommand({Bucket:this.config.bucket}))}}},mr=class{config=null;disks=new Map;configure(e){this.config=e}disk(e){let t=e??this.config?.default??"local";if(this.disks.has(t))return this.disks.get(t);if(!this.config)throw new Error("Storage not configured. Call Storage.configure() first.");let s=this.config.disks[t];if(!s)throw new Error(`Storage disk "${t}" is not defined.`);let r=this.createDisk(s);return this.disks.set(t,r),r}async get(e){return this.disk().get(e)}async getText(e){return this.disk().getText(e)}async put(e,t){return this.disk().put(e,t)}async append(e,t){return this.disk().append(e,t)}async exists(e){return this.disk().exists(e)}async delete(e){return this.disk().delete(e)}async copy(e,t){return this.disk().copy(e,t)}async move(e,t){return this.disk().move(e,t)}async files(e){return this.disk().files(e)}async allFiles(e){return this.disk().allFiles(e)}async directories(e){return this.disk().directories(e)}async makeDirectory(e){return this.disk().makeDirectory(e)}async deleteDirectory(e){return this.disk().deleteDirectory(e)}async size(e){return this.disk().size(e)}async lastModified(e){return this.disk().lastModified(e)}url(e){return this.disk().url(e)}createDisk(e){switch(e.driver){case"local":return new ur(e);case"s3":return new Yt(e);default:throw new Error(`Unknown storage driver: ${e.driver}`)}}s3Disk(e){let t=this.disk(e);if(!(t instanceof Yt))throw new Error(`Disk "${e??this.config?.default}" is not an S3 disk.`);return t}},Ei=C("svelar.storage",()=>new mr)});import{readFile as co,writeFile as uo,unlink as $i,mkdir as Di}from"fs/promises";import{join as mo,dirname as po}from"path";import{createHash as ho}from"crypto";var pr,hr,gr,fr,Ai,Mi=y(()=>{"use strict";R();pr=class{store=new Map;async get(e){let t=this.store.get(e);return t?t.expiresAt&&Date.now()>t.expiresAt?(this.store.delete(e),null):t.value:null}async put(e,t,s){this.store.set(e,{value:t,expiresAt:s?Date.now()+s*1e3:null})}async forget(e){return this.store.delete(e)}async flush(){this.store.clear()}async has(e){let t=this.store.get(e);return t?t.expiresAt&&Date.now()>t.expiresAt?(this.store.delete(e),!1):!0:!1}async increment(e,t=1){let r=(await this.get(e)??0)+t,i=this.store.get(e);return await this.put(e,r,i?.expiresAt?Math.ceil((i.expiresAt-Date.now())/1e3):void 0),r}async decrement(e,t=1){return this.increment(e,-t)}},hr=class{basePath;constructor(e){this.basePath=e.path??"storage/cache"}filePath(e){let t=ho("md5").update(e).digest("hex");return mo(this.basePath,t.slice(0,2),t)}async get(e){let t=this.filePath(e);try{let s=await co(t,"utf-8"),r=JSON.parse(s);return r.expiresAt&&Date.now()>r.expiresAt?(await $i(t).catch(()=>{}),null):r.value}catch{return null}}async put(e,t,s){let r=this.filePath(e),i={value:t,expiresAt:s?Date.now()+s*1e3:null};await Di(po(r),{recursive:!0}),await uo(r,JSON.stringify(i))}async forget(e){try{return await $i(this.filePath(e)),!0}catch{return!1}}async flush(){let{rm:e}=await import("fs/promises");await e(this.basePath,{recursive:!0,force:!0}),await Di(this.basePath,{recursive:!0})}async has(e){return await this.get(e)!==null}async increment(e,t=1){let r=(await this.get(e)??0)+t;return await this.put(e,r),r}async decrement(e,t=1){return this.increment(e,-t)}},gr=class{async get(){return null}async put(){}async forget(){return!0}async flush(){}async has(){return!1}async increment(){return 0}async decrement(){return 0}},fr=class{config={default:"memory",stores:{memory:{driver:"memory"}}};stores=new Map;configure(e){this.config=e,this.stores.clear()}store(e){let t=e??this.config.default;if(this.stores.has(t))return this.stores.get(t);let s=this.config.stores[t];if(!s)throw new Error(`Cache store "${t}" is not defined.`);let r=this.createStore(s);return this.stores.set(t,r),r}async get(e,t){let s=this.store();return await s.has(e)?s.get(e):t??null}async put(e,t,s){return this.store().put(e,t,s??this.config.stores[this.config.default]?.ttl)}async forget(e){return this.store().forget(e)}async flush(){return this.store().flush()}async has(e){return this.store().has(e)}async increment(e,t){return this.store().increment(e,t)}async decrement(e,t){return this.store().decrement(e,t)}async remember(e,t,s){let r=await this.store().get(e);if(r!==null)return r;let i=await s();return await this.store().put(e,i,t),i}async rememberForever(e,t){let s=await this.store().get(e);if(s!==null)return s;let r=await t();return await this.store().put(e,r),r}async pull(e,t){let s=await this.get(e,t);return await this.forget(e),s}createStore(e){switch(e.driver){case"memory":return new pr;case"file":return new hr(e);case"null":return new gr;case"redis":throw new Error("Redis cache requires ioredis. Install: npm install ioredis");default:throw new Error(`Unknown cache driver: ${e.driver}`)}}},Ai=C("svelar.cache",()=>new fr)});var Zt,br,yr,vr,Li,_i=y(()=>{"use strict";R();Zt=class{},br=class{async send(e,t){if(!t.toMail)return;let s=t.toMail(e),r=e.routeNotificationForMail?.()??e.getAttribute("email");if(!r){console.warn("[Notifications] No email address for notifiable.");return}try{let{Mailer:i}=await Promise.resolve().then(()=>(Bt(),Ws));await i.send({to:r,subject:s.subject,html:s.html,text:s.text,from:s.from})}catch(i){console.error("[Notifications] Failed to send mail notification:",i)}}},yr=class{table;constructor(e="notifications"){this.table=e}async send(e,t){if(!t.toDatabase)return;let s=t.toDatabase(e);try{let{Connection:r}=await Promise.resolve().then(()=>(x(),P));await r.raw(`INSERT INTO ${this.table} (id, notifiable_id, type, data, read_at, created_at)
|
|
141
|
+
VALUES (?, ?, ?, ?, NULL, ?)`,[crypto.randomUUID(),e.getAttribute("id"),s.type,JSON.stringify(s.data),new Date().toISOString()])}catch(r){console.error("[Notifications] Failed to store database notification:",r)}}},vr=class{channels=new Map;constructor(){this.channels.set("mail",new br),this.channels.set("database",new yr)}extend(e,t){this.channels.set(e,t)}async send(e,t){let s=Array.isArray(e)?e:[e];for(let r of s){let i=t.via(r);for(let n of i){let a=this.channels.get(n);if(a)try{await a.send(r,t)}catch(l){console.error(`[Notifications] Channel "${n}" failed:`,l)}else console.warn(`[Notifications] Unknown channel: ${n}`)}}}async sendVia(e,t,s){for(let r of s){let i=this.channels.get(r);i&&await i.send(e,t)}}},Li=C("svelar.notifier",()=>new vr)});function wr(o){return o.startsWith("private-")?"private":o.startsWith("presence-")?"presence":"public"}var Cr,Xt,xr,Pr,Ni,Ii=y(()=>{"use strict";R();Cr=class{subscribers=[];name;type;constructor(e){this.name=e,this.type=wr(e)}stream(e,t){let s=this,r=new ReadableStream({start(i){let n={channel:s.name};s.type==="presence"&&(n.members=s.getMembers());let a=`event: connected
|
|
142
142
|
data: ${JSON.stringify(n)}
|
|
143
143
|
id: ${Date.now()}
|
|
144
144
|
|
|
145
|
-
`;i.enqueue(new TextEncoder().encode(a));let
|
|
145
|
+
`;i.enqueue(new TextEncoder().encode(a));let l={controller:i,userId:e,userInfo:t};s.subscribers.push(l),s.type==="presence"&&e!==void 0&&s.sendInternal("member:joined",{id:e,...t},l)},cancel(){let i=s.subscribers.findIndex(a=>a.controller===this._controller),n=s.subscribers.length;s.subscribers=s.subscribers.filter(a=>{try{return a.controller.enqueue(new TextEncoder().encode(`:
|
|
146
146
|
|
|
147
147
|
`)),!0}catch{return!1}}),s.type==="presence"&&e!==void 0&&s.subscribers.length<n&&s.sendInternal("member:left",{id:e,...t})}});return new Response(r,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"}})}send(e,t,s){let r=`event: ${e}
|
|
148
148
|
data: ${JSON.stringify(t)}
|
|
@@ -156,9 +156,9 @@ id: ${Date.now()}
|
|
|
156
156
|
data: ${JSON.stringify(t)}
|
|
157
157
|
id: ${Date.now()}
|
|
158
158
|
|
|
159
|
-
`,i=new TextEncoder().encode(r);for(let n of this.subscribers)if(n.userId!==s)try{n.controller.enqueue(i)}catch{}}},
|
|
160
|
-
`),c=await this.hmacSha256(this.config.secret,
|
|
161
|
-
`);Yt("warning",e[422]??"Validation Error",a);return}}}catch{}let s=t||e[l.status]||`Error ${l.status}`,r=l.status>=500?"error":l.status===429?"warning":"error";if(l.status===401){Yt("warning",s,"Please sign in to continue.");return}Yt(r,s)}function wr(l="XSRF-TOKEN"){if(typeof document>"u")return null;let e=l.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),t=document.cookie.match(new RegExp(`(?:^|;\\s*)${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}function Gi(l,e){if(!e)return l;let t=new URL(l,"http://localhost");for(let[s,r]of Object.entries(e))r!=null&&t.searchParams.set(s,String(r));return t.pathname+t.search}var co,Vi,br,fe,fu,Yi=y(()=>{"use strict";co={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."},Vi=null;br=class l{_baseUrl="";_headers={};_timeout=3e4;_retries=0;_retryDelay=1e3;_query={};constructor(e){e?.baseUrl&&(this._baseUrl=e.baseUrl),e?.headers&&(this._headers={...e.headers}),e?.timeout&&(this._timeout=e.timeout),e?.retries&&(this._retries=e.retries),e?.retryDelay&&(this._retryDelay=e.retryDelay)}clone(){let e=new l;return e._baseUrl=this._baseUrl,e._headers={...this._headers},e._timeout=this._timeout,e._retries=this._retries,e._retryDelay=this._retryDelay,e._query={...this._query},e}baseUrl(e){let t=this.clone();return t._baseUrl=e,t}withHeaders(e){let t=this.clone();return t._headers={...t._headers,...e},t}withToken(e,t="Bearer"){return this.withHeaders({Authorization:`${t} ${e}`})}withBasicAuth(e,t){let s=Buffer.from(`${e}:${t}`).toString("base64");return this.withHeaders({Authorization:`Basic ${s}`})}accept(e){return this.withHeaders({Accept:e})}contentType(e){return this.withHeaders({"Content-Type":e})}timeout(e){let t=this.clone();return t._timeout=e,t}retry(e,t=1e3){let s=this.clone();return s._retries=e,s._retryDelay=t,s}query(e){let t=this.clone();for(let[s,r]of Object.entries(e))r!=null&&(t._query[s]=String(r));return t}async get(e){return this.request("GET",e)}async post(e,t){return this.request("POST",e,t)}async put(e,t){return this.request("PUT",e,t)}async patch(e,t){return this.request("PATCH",e,t)}async delete(e,t){return this.request("DELETE",e,t)}async request(e,t,s){let r=this.buildFullUrl(t),i={...this._headers},n;s!==void 0&&(i["Content-Type"]||(i["Content-Type"]="application/json"),n=typeof s=="string"?s:JSON.stringify(s)),i.Accept||(i.Accept="application/json");let a=null,o=1+this._retries;for(let c=0;c<o;c++){c>0&&await new Promise(u=>setTimeout(u,this._retryDelay*c));try{let u=new AbortController,d=setTimeout(()=>u.abort(),this._timeout),p=await fetch(r,{method:e,headers:i,body:n,signal:u.signal});if(clearTimeout(d),!p.ok&&p.status<500&&c<o-1,!p.ok&&p.status>=500&&c<o-1){a=new fe(`HTTP ${p.status}: ${p.statusText}`,p.status,await p.text());continue}let f=p.headers.get("content-type")??"",b;if(f.includes("application/json")?b=await p.json():b=await p.text(),!p.ok)throw new fe(`HTTP ${p.status}: ${typeof b=="string"?b:JSON.stringify(b)}`,p.status,b);return{data:b,status:p.status,headers:p.headers,ok:!0}}catch(u){if(u instanceof fe)throw u;if(a=u,u.name==="AbortError"&&(a=new fe("Request timed out",0,null)),c>=o-1)break}}throw a??new Error("HTTP request failed")}buildFullUrl(e){let t=this._baseUrl?`${this._baseUrl.replace(/\/+$/,"")}/${e.replace(/^\/+/,"")}`:e,s=Object.entries(this._query);if(s.length>0){let r=new URL(t);for(let[i,n]of s)r.searchParams.set(i,n);t=r.toString()}return t}},fe=class extends Error{constructor(t,s,r){super(t);this.status=s;this.body=r;this.name="HttpRequestError"}},fu=new br});function Xi(l){let{paraglideMiddleware:e,getTextDirection:t=()=>"ltr",langPlaceholder:s="%lang%",dirPlaceholder:r="%dir%"}=l;return({event:i,resolve:n})=>e(i.request,({request:a,locale:o})=>(i.request=a,n(i,{transformPageChunk:({html:c})=>c.replace(s,o).replace(r,t(o))})))}function Zi(l){return e=>l.deLocalizeUrl(e.url).pathname}var en=y(()=>{"use strict"});function tn(l,e,t={}){return async s=>{let{superValidate:r,fail:i,message:n}=await import("sveltekit-superforms"),{zod:a}=await import("sveltekit-superforms/adapters"),o=await r(s,a(l));if(!o.valid)return i(400,{form:o});try{let c=await e(o.data,s);if(t.redirectTo){let{redirect:u}=await import("@sveltejs/kit");throw u(303,t.redirectTo)}return c??{form:o}}catch(c){if(c?.status>=300&&c?.status<400)throw c;return n(o,t.errorMessage||c.message||"An error occurred",{status:c.status||400})}}}async function sn(l,e){let{superValidate:t}=await import("sveltekit-superforms"),{zod:s}=await import("sveltekit-superforms/adapters");return t(e??null,s(l))}async function rn(l,e){let t=await l.request.formData(),s={};for(let[i,n]of t.entries())s[i]=n;let r=e.safeParse(s);if(!r.success){let{FormValidationError:i}=await Promise.resolve().then(()=>(ir(),Ii));throw new i(r.error.flatten().fieldErrors)}return r.data}var nn=y(()=>{"use strict"});var an={};E(an,{Application:()=>$t,AuthManager:()=>qt,AuthenticateMiddleware:()=>me,BelongsTo:()=>Z,BelongsToMany:()=>ee,Broadcast:()=>Wi,Cache:()=>Fi,ColumnBuilder:()=>j,Connection:()=>g,Container:()=>F,Controller:()=>Nt,CorsMiddleware:()=>At,CsrfMiddleware:()=>re,DatabaseSessionStore:()=>_t,ErrorHandler:()=>pe,Event:()=>te,EventDispatcher:()=>$e,FileSessionStore:()=>It,ForbiddenError:()=>Me,FormAuthorizationError:()=>ge,FormRequest:()=>qe,FormValidationError:()=>he,HasMany:()=>X,HasOne:()=>Y,Hash:()=>Ms,HttpError:()=>A,Job:()=>V,Log:()=>Ft,LoggingMiddleware:()=>Dt,Mailable:()=>je,Mailer:()=>Us,MemorySessionStore:()=>H,Middleware:()=>T,MiddlewareStack:()=>L,Migration:()=>xe,Migrator:()=>Ce,Model:()=>Et,ModelNotFoundError:()=>Kt,NotFoundError:()=>Ae,Notification:()=>Qt,Notifier:()=>zi,OriginMiddleware:()=>ie,QueryBuilder:()=>D,Queue:()=>Ss,RateLimitMiddleware:()=>se,RedisSessionStore:()=>jt,RequireAuthMiddleware:()=>Ut,Schema:()=>O,Seeder:()=>kt,ServiceProvider:()=>ke,Session:()=>le,SessionMiddleware:()=>ce,SignatureMiddleware:()=>Mt,Storage:()=>Li,TableBuilder:()=>W,ThrottleMiddleware:()=>ne,UnauthorizedError:()=>De,ValidationError:()=>q,abort:()=>Wt,abortIf:()=>Ti,abortUnless:()=>Ei,apiFetch:()=>Qi,buildUrl:()=>Gi,config:()=>Ai,container:()=>hi,createFormAction:()=>tn,createI18nHandle:()=>Xi,createReroute:()=>Zi,createSvelarApp:()=>ki,createSvelarHooks:()=>er,env:()=>$i,getCsrfToken:()=>wr,loadForm:()=>sn,resource:()=>fi,rules:()=>Mi,schema:()=>ti,sequence:()=>tr,signJwt:()=>Fs,validate:()=>Ni,validateForm:()=>rn,verifyJwt:()=>Hs,z:()=>S});var on=y(()=>{"use strict";mi();Rs();Ts();x();hs();gs();pi();ks();Es();gi();ae();yi();sr();Di();_i();zs();de();$s();Zs();Tt();ir();qi();Gs();Hi();Q();Lt();Ki();Ji();Yi();en();nn();sr()});var Cr={};E(Cr,{PluginRegistry:()=>ts});var xr,ts,ss=y(()=>{"use strict";R();xr=class{plugins=new Map;enabledPlugins=new Set;async discover(){let{join:e}=await import("path"),{existsSync:t,readdirSync:s}=await import("fs"),{readFile:r}=await import("fs/promises"),i=[],n=e(process.cwd(),"node_modules");if(!t(n))return i;try{let a=s(n,{withFileTypes:!0});for(let o of a){if(!o.isDirectory())continue;let c=o.name;if(c.startsWith("."))continue;let u=c.startsWith("svelar-");if(!u)continue;let d=e(n,c,"package.json");if(t(d))try{let p=await r(d,"utf-8"),f=JSON.parse(p),b=f.keywords?.includes("svelar-plugin");if(!u&&!b)continue;let C={name:f.name||c,version:f.version||"0.0.0",description:f.description||"",packageName:c,installed:!0,enabled:!1,hasConfig:!!f.svelar?.config,hasMigrations:!!f.svelar?.migrations};i.push(C),this.plugins.set(C.name,C)}catch{}}}catch{}return i}enable(e){let t=this.plugins.get(e);if(!t)throw new Error(`Plugin "${e}" not found in registry.`);this.enabledPlugins.add(e),t.enabled=!0}disable(e){this.enabledPlugins.delete(e);let t=this.plugins.get(e);t&&(t.enabled=!1)}isEnabled(e){return this.enabledPlugins.has(e)}list(){return[...this.plugins.values()]}listEnabled(){return[...this.plugins.values()].filter(e=>this.enabledPlugins.has(e.name))}get(e){return this.plugins.get(e)}register(e){this.plugins.set(e.name,e)}},ts=w("svelar.pluginRegistry",()=>new xr)});var ln={};E(ln,{PluginPublisher:()=>Sr});var Pr,Sr,Rr=y(()=>{"use strict";R();Pr=class{async publish(e,t){let{mkdir:s,copyFile:r}=await import("fs/promises"),{join:i,dirname:n}=await import("path"),{existsSync:a}=await import("fs"),o={configs:[],migrations:[],assets:[]},c=e.publishables?.()||{};for(let[u,d]of Object.entries(c))for(let p of d){if(t?.only&&p.type!==t.only)continue;let f=i(process.cwd(),p.dest),b=n(f);if(!(a(f)&&!t?.force))try{await s(b,{recursive:!0}),await r(p.source,f),p.type==="config"?o.configs.push(f):p.type==="migration"?o.migrations.push(f):p.type==="asset"&&o.assets.push(f)}catch(C){console.warn(`Failed to publish ${p.source} to ${f}:`,C)}}return o}async preview(e){let t={configs:[],migrations:[],assets:[]},s=e.publishables?.()||{};for(let[r,i]of Object.entries(s))for(let n of i){let a=Fe("path").join(process.cwd(),n.dest);n.type==="config"?t.configs.push(a):n.type==="migration"?t.migrations.push(a):n.type==="asset"&&t.assets.push(a)}return t}},Sr=w("svelar.pluginPublisher",()=>new Pr)});var cn={};E(cn,{PluginInstaller:()=>mo});var Tr,mo,dn=y(()=>{"use strict";R();ss();Rr();Tr=class{async install(e,t){let{spawn:s}=await import("child_process"),{promisify:r}=await import("util"),{join:i}=await import("path"),{readFile:n}=await import("fs/promises"),{existsSync:a}=await import("fs");try{await this.runNpmInstall(e);let o=ts,c=await o.discover(),u;for(let p of c)if(p.packageName===e||p.name===e){u=p;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.`};o.enable(u.name);let d=null;if(t?.publish!==!1)try{let p=await this.loadPluginClass(u.packageName);p&&(d=await Sr.publish(new p))}catch(p){console.warn("Failed to publish plugin assets:",p)}return{success:!0,pluginName:u.name,version:u.version,published:d}}catch(o){return{success:!1,pluginName:e,version:"0.0.0",published:null,error:o?.message??String(o)}}}async uninstall(e){try{let t=ts,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}=Fe("child_process"),i=r("npm",["install",e],{cwd:process.cwd(),stdio:"inherit"});i.on("close",n=>{n===0?t():s(new Error(`npm install exited with code ${n}`))}),i.on("error",s)})}async runNpmUninstall(e){return new Promise((t,s)=>{let{spawn:r}=Fe("child_process"),i=r("npm",["uninstall",e],{cwd:process.cwd(),stdio:"inherit"});i.on("close",n=>{n===0?t():s(new Error(`npm uninstall exited with code ${n}`))}),i.on("error",s)})}async loadPluginClass(e){try{let t=await import(e);return t.default||Object.values(t)[0]}catch{return null}}},mo=w("svelar.pluginInstaller",()=>new Tr)});import{dirname as mn,join as Er}from"path";import{fileURLToPath as pn,pathToFileURL as po}from"url";import{register as ho}from"module";import{readFileSync as hn,existsSync as go}from"fs";var He=class{commands=new Map;version;constructor(e="0.1.0"){this.version=e}register(e){let t=new e;return this.commands.set(t.name,t),this}add(e){return this.commands.set(e.name,e),this}async run(e=process.argv.slice(2)){let[t,...s]=e;if(!t||t==="--help"||t==="-h"){this.showHelp();return}if(t==="--version"||t==="-v"){console.log(`Svelar v${this.version}`);return}let r=this.commands.get(t);if(r||(console.error(`\x1B[31mUnknown command:\x1B[0m ${t}`),console.log("Run \x1B[36msvelar --help\x1B[0m for available commands."),process.exit(1)),s.includes("--help")||s.includes("-h")){this.showCommandHelp(r);return}let{args:i,flags:n}=this.parseArgs(s,r);try{await r.handle(i,n)}catch(a){let o=a instanceof Error?a.message:String(a);console.error(`\x1B[31mError:\x1B[0m ${o}`),a?.stack&&console.error(a.stack),process.exit(1)}}parseArgs(e,t){let s=[],r={};for(let i of t.flags)i.default!==void 0&&(r[i.name]=i.default);for(let i=0;i<e.length;i++){let n=e[i];if(n.startsWith("--")){let a=n.slice(2),o=a.indexOf("=");if(o!==-1){let d=a.slice(0,o);r[d]=a.slice(o+1);continue}let c=a;t.flags.find(d=>d.name===c)?.type==="boolean"?r[c]=!0:i+1<e.length&&!e[i+1].startsWith("-")?r[c]=e[++i]:r[c]=!0}else if(n.startsWith("-")&&n.length===2){let a=n.slice(1),o=t.flags.find(c=>c.alias===a);o&&(o.type==="boolean"?r[o.name]=!0:i+1<e.length&&(r[o.name]=e[++i]))}else s.push(n)}return{args:s,flags:r}}showCommandHelp(e){if(console.log(`
|
|
159
|
+
`,i=new TextEncoder().encode(r);for(let n of this.subscribers)if(n.userId!==s)try{n.controller.enqueue(i)}catch{}}},Xt=class{config;constructor(e){this.config=e}async send(e,t,s){let r=Array.isArray(e)?e:[e],i=JSON.stringify({name:t,channels:r,data:JSON.stringify(s)}),n=Math.floor(Date.now()/1e3).toString(),a=await this.md5(i),l=["POST",`/apps/${this.config.appId}/events`,[`auth_key=${this.config.key}`,`auth_timestamp=${n}`,"auth_version=1.0",`body_md5=${a}`].join("&")].join(`
|
|
160
|
+
`),c=await this.hmacSha256(this.config.secret,l),u=this.config.useTLS!==!1?"https":"http",m=this.config.host??`api-${this.config.cluster??"mt1"}.pusher.com`,h=this.config.port??(this.config.useTLS!==!1?443:80),d=`${u}://${m}:${h}/apps/${this.config.appId}/events?auth_key=${this.config.key}&auth_timestamp=${n}&auth_version=1.0&body_md5=${a}&auth_signature=${c}`,b=await fetch(d,{method:"POST",headers:{"Content-Type":"application/json"},body:i});if(!b.ok){let w=await b.text();throw new Error(`Pusher API error (${b.status}): ${w}`)}}async authenticate(e,t,s){let r=`${e}:${t}`,i;s&&(i=JSON.stringify(s),r+=`:${i}`);let n=await this.hmacSha256(this.config.secret,r),a=`${this.config.key}:${n}`;return i?{auth:a,channel_data:i}:{auth:a}}get key(){return this.config.key}clientConfig(){let e={key:this.config.key,cluster:this.config.cluster??"mt1"};return this.config.host&&(e.wsHost=this.config.host,e.wsPort=this.config.port??6001,e.wssPort=this.config.port??6001,e.forceTLS=this.config.useTLS??!1,e.enabledTransports=["ws","wss"],e.disableStats=!0),e}async md5(e){let{createHash:t}=await import("crypto");return t("md5").update(e).digest("hex")}async hmacSha256(e,t){let{createHmac:s}=await import("crypto");return s("sha256",e).update(t).digest("hex")}},xr=class{constructor(e,t,s){this.manager=e;this.eventName=t;this.eventData=s}channels=[];on(...e){return this.channels.push(...e),this}async send(){for(let e of this.channels)await this.manager.sendToChannel(e,this.eventName,this.eventData)}},Pr=class{config={default:"sse",drivers:{sse:{driver:"sse"}}};sseChannels=new Map;channelAuth=new Map;pusherDriver=null;configure(e){this.config=e;let t=Object.values(e.drivers).find(s=>s.driver==="pusher");t&&t.driver==="pusher"&&(this.pusherDriver=new Xt(t))}channel(e,t){if(t){this.channelAuth.set(e,t);return}return this.sseChannels.has(e)||this.sseChannels.set(e,new Cr(e)),this.sseChannels.get(e)}async authorize(e,t){if(wr(e)==="public")return!0;for(let[r,i]of this.channelAuth){let n=this.matchPattern(r,e);if(n!==null)return await i(t,n)}return!1}async authenticatePusher(e,t,s){if(!this.pusherDriver)throw new Error("Pusher driver is not configured. Call Broadcast.configure() first.");let r=wr(e);if(r==="public")return!1;let i=await this.authorize(e,s);if(i===!1)return!1;if(r==="presence"){let n=typeof i=="object"?{user_id:i.id??s.id,user_info:i}:{user_id:s.id,user_info:{id:s.id}};return this.pusherDriver.authenticate(t,e,n)}return this.pusherDriver.authenticate(t,e)}event(e,t){return new xr(this,e,t)}to(e,t){return{send:async(s,r)=>{await this.sendToChannel(e,s,r,t)}}}async sendToChannel(e,t,s,r){let i=this.config.drivers[this.config.default];switch(i?.driver){case"pusher":this.pusherDriver||(this.pusherDriver=new Xt(i)),await this.pusherDriver.send(e,t,s);break;case"log":console.log(`[Broadcast] ${e} \u2192 ${t}:`,JSON.stringify(s));break;default:for(let[,n]of this.sseChannels)n.name===e&&n.send(t,s,r);break}}subscribe(e,t,s){return this.channel(e).stream(t,s)}members(e){let t=this.sseChannels.get(e);return t?t.getMembers():[]}pusher(){if(!this.pusherDriver)throw new Error("Pusher driver is not configured.");return this.pusherDriver}activeChannels(){return[...new Set([...this.sseChannels.values()].map(e=>e.name))]}totalSubscribers(){let e=0;for(let t of this.sseChannels.values())e+=t.subscriberCount();return e}prune(){for(let[e,t]of this.sseChannels)t.subscriberCount()===0&&this.sseChannels.delete(e)}matchPattern(e,t){let s=[],r=e.replace(/[.*+?^${}()|[\]\\]/g,l=>l==="{"||l==="}"?l:`\\${l}`).replace(/\\\{(\w+)\\\}/g,(l,c)=>(s.push(c),"([^.]+)")).replace(/\{(\w+)\}/g,(l,c)=>(s.push(c),"([^.]+)")),i=new RegExp(`^${r}$`),n=t.match(i);if(!n)return null;let a={};for(let l=0;l<s.length;l++)a[s[l]]=n[l+1];return a}},Ni=C("svelar.broadcast",()=>new Pr)});function es(o,e,t){ji&&ji(o,e,{description:t})}async function Oi(o,e={}){let{csrfCookieName:t="XSRF-TOKEN",csrfHeaderName:s="X-CSRF-Token",showToast:r=!0,errorMessages:i={},...n}=e,a=(n.method||"GET").toUpperCase(),l=new Headers(n.headers);if(["POST","PUT","PATCH","DELETE"].includes(a)){let c=Rr(t);c&&l.set(s,c)}n.body&&typeof n.body=="string"&&!l.has("Content-Type")&&l.set("Content-Type","application/json"),l.has("Accept")||l.set("Accept","application/json");try{let c=await fetch(o,{...n,headers:l});return!c.ok&&r&&await fo(c,{...go,...i}),c}catch(c){throw r&&es("error","Network Error","Unable to connect. Check your internet connection."),c}}async function fo(o,e){let t="";try{if((o.headers.get("content-type")??"").includes("application/json")){let n=await o.clone().json();if(t=n.message??"",o.status===422&&n.errors){let a=Object.entries(n.errors).map(([l,c])=>`${l}: ${c.join(", ")}`).slice(0,3).join(`
|
|
161
|
+
`);es("warning",e[422]??"Validation Error",a);return}}}catch{}let s=t||e[o.status]||`Error ${o.status}`,r=o.status>=500?"error":o.status===429?"warning":"error";if(o.status===401){es("warning",s,"Please sign in to continue.");return}es(r,s)}function Rr(o="XSRF-TOKEN"){if(typeof document>"u")return null;let e=o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),t=document.cookie.match(new RegExp(`(?:^|;\\s*)${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}function qi(o,e){if(!e)return o;let t=new URL(o,"http://localhost");for(let[s,r]of Object.entries(e))r!=null&&t.searchParams.set(s,String(r));return t.pathname+t.search}var go,ji,Sr,ge,Tu,Ui=y(()=>{"use strict";go={400:"Invalid request. Please check your input.",401:"Your session has expired. Please sign in again.",403:"You don't have permission to do this.",404:"The requested resource was not found.",405:"This action is not allowed.",409:"A conflict occurred. Please refresh and try again.",419:"Page expired. Please refresh and try again.",422:"The submitted data is invalid.",429:"Too many requests. Please wait a moment.",500:"Something went wrong on our end.",502:"Service temporarily unavailable. Try again shortly.",503:"Service is under maintenance. Try again shortly.",504:"Request timed out. Please try again."},ji=null;Sr=class o{_baseUrl="";_headers={};_timeout=3e4;_retries=0;_retryDelay=1e3;_query={};constructor(e){e?.baseUrl&&(this._baseUrl=e.baseUrl),e?.headers&&(this._headers={...e.headers}),e?.timeout&&(this._timeout=e.timeout),e?.retries&&(this._retries=e.retries),e?.retryDelay&&(this._retryDelay=e.retryDelay)}clone(){let e=new o;return e._baseUrl=this._baseUrl,e._headers={...this._headers},e._timeout=this._timeout,e._retries=this._retries,e._retryDelay=this._retryDelay,e._query={...this._query},e}baseUrl(e){let t=this.clone();return t._baseUrl=e,t}withHeaders(e){let t=this.clone();return t._headers={...t._headers,...e},t}withToken(e,t="Bearer"){return this.withHeaders({Authorization:`${t} ${e}`})}withBasicAuth(e,t){let s=Buffer.from(`${e}:${t}`).toString("base64");return this.withHeaders({Authorization:`Basic ${s}`})}accept(e){return this.withHeaders({Accept:e})}contentType(e){return this.withHeaders({"Content-Type":e})}timeout(e){let t=this.clone();return t._timeout=e,t}retry(e,t=1e3){let s=this.clone();return s._retries=e,s._retryDelay=t,s}query(e){let t=this.clone();for(let[s,r]of Object.entries(e))r!=null&&(t._query[s]=String(r));return t}async get(e){return this.request("GET",e)}async post(e,t){return this.request("POST",e,t)}async put(e,t){return this.request("PUT",e,t)}async patch(e,t){return this.request("PATCH",e,t)}async delete(e,t){return this.request("DELETE",e,t)}async request(e,t,s){let r=this.buildFullUrl(t),i={...this._headers},n;s!==void 0&&(i["Content-Type"]||(i["Content-Type"]="application/json"),n=typeof s=="string"?s:JSON.stringify(s)),i.Accept||(i.Accept="application/json");let a=null,l=1+this._retries;for(let c=0;c<l;c++){c>0&&await new Promise(u=>setTimeout(u,this._retryDelay*c));try{let u=new AbortController,m=setTimeout(()=>u.abort(),this._timeout),h=await fetch(r,{method:e,headers:i,body:n,signal:u.signal});if(clearTimeout(m),!h.ok&&h.status<500&&c<l-1,!h.ok&&h.status>=500&&c<l-1){a=new ge(`HTTP ${h.status}: ${h.statusText}`,h.status,await h.text());continue}let d=h.headers.get("content-type")??"",b;if(d.includes("application/json")?b=await h.json():b=await h.text(),!h.ok)throw new ge(`HTTP ${h.status}: ${typeof b=="string"?b:JSON.stringify(b)}`,h.status,b);return{data:b,status:h.status,headers:h.headers,ok:!0}}catch(u){if(u instanceof ge)throw u;if(a=u,u.name==="AbortError"&&(a=new ge("Request timed out",0,null)),c>=l-1)break}}throw a??new Error("HTTP request failed")}buildFullUrl(e){let t=this._baseUrl?`${this._baseUrl.replace(/\/+$/,"")}/${e.replace(/^\/+/,"")}`:e,s=Object.entries(this._query);if(s.length>0){let r=new URL(t);for(let[i,n]of s)r.searchParams.set(i,n);t=r.toString()}return t}},ge=class extends Error{constructor(t,s,r){super(t);this.status=s;this.body=r;this.name="HttpRequestError"}},Tu=new Sr});function Bi(o){let{paraglideMiddleware:e,getTextDirection:t=()=>"ltr",langPlaceholder:s="%lang%",dirPlaceholder:r="%dir%"}=o;return({event:i,resolve:n})=>e(i.request,({request:a,locale:l})=>(i.request=a,n(i,{transformPageChunk:({html:c})=>c.replace(s,l).replace(r,t(l))})))}function Fi(o){return e=>o.deLocalizeUrl(e.url).pathname}var Hi=y(()=>{"use strict"});function zi(o,e,t={}){return async s=>{let{superValidate:r,fail:i,message:n}=await import("sveltekit-superforms"),{zod:a}=await import("sveltekit-superforms/adapters"),l=await r(s,a(o));if(!l.valid)return i(400,{form:l});try{let c=await e(l.data,s);if(t.redirectTo){let{redirect:u}=await import("@sveltejs/kit");throw u(303,t.redirectTo)}return c??{form:l}}catch(c){if(c?.status>=300&&c?.status<400)throw c;return n(l,t.errorMessage||c.message||"An error occurred",{status:c.status||400})}}}async function Ki(o,e){let{superValidate:t}=await import("sveltekit-superforms"),{zod:s}=await import("sveltekit-superforms/adapters");return t(e??null,s(o))}async function Wi(o,e){let t=await o.request.formData(),s={};for(let[i,n]of t.entries())s[i]=n;let r=e.safeParse(s);if(!r.success){let{FormValidationError:i}=await Promise.resolve().then(()=>(cr(),Si));throw new i(r.error.flatten().fieldErrors)}return r.data}var Ji=y(()=>{"use strict"});var Vi={};k(Vi,{Application:()=>Mt,AuthManager:()=>Ft,AuthenticateMiddleware:()=>ue,BelongsTo:()=>Z,BelongsToMany:()=>X,Broadcast:()=>Ni,Cache:()=>Ai,ColumnBuilder:()=>I,Connection:()=>f,Container:()=>F,Controller:()=>It,CorsMiddleware:()=>Lt,CsrfMiddleware:()=>se,DatabaseSessionStore:()=>jt,ErrorHandler:()=>me,Event:()=>ee,EventDispatcher:()=>ke,FileSessionStore:()=>Ot,ForbiddenError:()=>Ae,FormAuthorizationError:()=>he,FormRequest:()=>Oe,FormValidationError:()=>pe,HasMany:()=>Y,HasOne:()=>G,Hash:()=>js,HttpError:()=>A,Job:()=>J,Log:()=>Kt,LoggingMiddleware:()=>_t,Mailable:()=>Ne,Mailer:()=>Ks,MemorySessionStore:()=>H,Middleware:()=>T,MiddlewareStack:()=>O,Migration:()=>we,Migrator:()=>Ce,Model:()=>Dt,ModelNotFoundError:()=>Vt,NotFoundError:()=>$e,Notification:()=>Zt,Notifier:()=>Li,OriginMiddleware:()=>re,QueryBuilder:()=>M,Queue:()=>$s,RateLimitMiddleware:()=>te,RedisSessionStore:()=>qt,RequireAuthMiddleware:()=>Ht,Schema:()=>j,Seeder:()=>At,ServiceProvider:()=>Ee,Session:()=>oe,SessionMiddleware:()=>le,SignatureMiddleware:()=>Nt,Storage:()=>Ei,TableBuilder:()=>K,ThrottleMiddleware:()=>ie,UnauthorizedError:()=>De,ValidationError:()=>q,abort:()=>Qt,abortIf:()=>gi,abortUnless:()=>fi,apiFetch:()=>Oi,buildUrl:()=>qi,config:()=>vi,container:()=>ri,createFormAction:()=>zi,createI18nHandle:()=>Bi,createReroute:()=>Fi,createSvelarApp:()=>bi,createSvelarHooks:()=>nr,env:()=>yi,getCsrfToken:()=>Rr,loadForm:()=>Ki,resource:()=>ni,rules:()=>Ci,schema:()=>Kr,sequence:()=>ar,signJwt:()=>Js,validate:()=>xi,validateForm:()=>Wi,verifyJwt:()=>Vs,z:()=>S});var Qi=y(()=>{"use strict";ti();Ds();As();x();ys();vs();si();Ls();Ms();ii();ne();ai();or();wi();Pi();Qs();ce();_s();ir();$t();cr();ki();tr();Mi();V();Bt();_i();Ii();Ui();Hi();Ji();or()});var kr={};k(kr,{PluginRegistry:()=>is});var Er,is,ns=y(()=>{"use strict";R();Er=class{plugins=new Map;enabledPlugins=new Set;async discover(){let{join:e}=await import("path"),{existsSync:t,readdirSync:s}=await import("fs"),{readFile:r}=await import("fs/promises"),i=[],n=e(process.cwd(),"node_modules");if(!t(n))return i;try{let a=s(n,{withFileTypes:!0});for(let l of a){if(!l.isDirectory())continue;let c=l.name;if(c.startsWith("."))continue;let u=c.startsWith("svelar-");if(!u)continue;let m=e(n,c,"package.json");if(t(m))try{let h=await r(m,"utf-8"),d=JSON.parse(h),b=d.keywords?.includes("svelar-plugin");if(!u&&!b)continue;let w={name:d.name||c,version:d.version||"0.0.0",description:d.description||"",packageName:c,installed:!0,enabled:!1,hasConfig:!!d.svelar?.config,hasMigrations:!!d.svelar?.migrations};i.push(w),this.plugins.set(w.name,w)}catch{}}}catch{}return i}enable(e){let t=this.plugins.get(e);if(!t)throw new Error(`Plugin "${e}" not found in registry.`);this.enabledPlugins.add(e),t.enabled=!0}disable(e){this.enabledPlugins.delete(e);let t=this.plugins.get(e);t&&(t.enabled=!1)}isEnabled(e){return this.enabledPlugins.has(e)}list(){return[...this.plugins.values()]}listEnabled(){return[...this.plugins.values()].filter(e=>this.enabledPlugins.has(e.name))}get(e){return this.plugins.get(e)}register(e){this.plugins.set(e.name,e)}},is=C("svelar.pluginRegistry",()=>new Er)});var Yi={};k(Yi,{PluginPublisher:()=>Dr});var $r,Dr,Ar=y(()=>{"use strict";R();$r=class{async publish(e,t){let{mkdir:s,copyFile:r}=await import("fs/promises"),{join:i,dirname:n}=await import("path"),{existsSync:a}=await import("fs"),l={configs:[],migrations:[],assets:[]},c=e.publishables?.()||{};for(let[u,m]of Object.entries(c))for(let h of m){if(t?.only&&h.type!==t.only)continue;let d=i(process.cwd(),h.dest),b=n(d);if(!(a(d)&&!t?.force))try{await s(b,{recursive:!0}),await r(h.source,d),h.type==="config"?l.configs.push(d):h.type==="migration"?l.migrations.push(d):h.type==="asset"&&l.assets.push(d)}catch(w){console.warn(`Failed to publish ${h.source} to ${d}:`,w)}}return l}async preview(e){let t={configs:[],migrations:[],assets:[]},s=e.publishables?.()||{};for(let[r,i]of Object.entries(s))for(let n of i){let a=ze("path").join(process.cwd(),n.dest);n.type==="config"?t.configs.push(a):n.type==="migration"?t.migrations.push(a):n.type==="asset"&&t.assets.push(a)}return t}},Dr=C("svelar.pluginPublisher",()=>new $r)});var Zi={};k(Zi,{PluginInstaller:()=>wo});var Mr,wo,Xi=y(()=>{"use strict";R();ns();Ar();Mr=class{async install(e,t){let{spawn:s}=await import("child_process"),{promisify:r}=await import("util"),{join:i}=await import("path"),{readFile:n}=await import("fs/promises"),{existsSync:a}=await import("fs");try{await this.runNpmInstall(e);let l=is,c=await l.discover(),u;for(let h of c)if(h.packageName===e||h.name===e){u=h;break}if(!u)return{success:!1,pluginName:e,version:"0.0.0",published:null,error:`Plugin not found after installation. Make sure ${e} is a valid Svelar plugin.`};l.enable(u.name);let m=null;if(t?.publish!==!1)try{let h=await this.loadPluginClass(u.packageName);h&&(m=await Dr.publish(new h))}catch(h){console.warn("Failed to publish plugin assets:",h)}return{success:!0,pluginName:u.name,version:u.version,published:m}}catch(l){return{success:!1,pluginName:e,version:"0.0.0",published:null,error:l?.message??String(l)}}}async uninstall(e){try{let t=is,s=t.get(e);return s?(t.disable(e),await this.runNpmUninstall(s.packageName),!0):!1}catch(t){return console.error("Failed to uninstall plugin:",t),!1}}async runNpmInstall(e){return new Promise((t,s)=>{let{spawn:r}=ze("child_process"),i=r("npm",["install",e],{cwd:process.cwd(),stdio:"inherit"});i.on("close",n=>{n===0?t():s(new Error(`npm install exited with code ${n}`))}),i.on("error",s)})}async runNpmUninstall(e){return new Promise((t,s)=>{let{spawn:r}=ze("child_process"),i=r("npm",["uninstall",e],{cwd:process.cwd(),stdio:"inherit"});i.on("close",n=>{n===0?t():s(new Error(`npm uninstall exited with code ${n}`))}),i.on("error",s)})}async loadPluginClass(e){try{let t=await import(e);return t.default||Object.values(t)[0]}catch{return null}}},wo=C("svelar.pluginInstaller",()=>new Mr)});import{dirname as tn,join as Lr}from"path";import{fileURLToPath as sn,pathToFileURL as Co}from"url";import{register as xo}from"module";import{readFileSync as rn,existsSync as Po}from"fs";var Ke=class{commands=new Map;version;constructor(e="0.1.0"){this.version=e}register(e){let t=new e;return this.commands.set(t.name,t),this}add(e){return this.commands.set(e.name,e),this}async run(e=process.argv.slice(2)){let[t,...s]=e;if(!t||t==="--help"||t==="-h"){this.showHelp();return}if(t==="--version"||t==="-v"){console.log(`Svelar v${this.version}`);return}let r=this.commands.get(t);if(r||(console.error(`\x1B[31mUnknown command:\x1B[0m ${t}`),console.log("Run \x1B[36msvelar --help\x1B[0m for available commands."),process.exit(1)),s.includes("--help")||s.includes("-h")){this.showCommandHelp(r);return}let{args:i,flags:n}=this.parseArgs(s,r);try{await r.handle(i,n)}catch(a){let l=a instanceof Error?a.message:String(a);console.error(`\x1B[31mError:\x1B[0m ${l}`),a?.stack&&console.error(a.stack),process.exit(1)}}parseArgs(e,t){let s=[],r={};for(let i of t.flags)i.default!==void 0&&(r[i.name]=i.default);for(let i=0;i<e.length;i++){let n=e[i];if(n.startsWith("--")){let a=n.slice(2),l=a.indexOf("=");if(l!==-1){let m=a.slice(0,l);r[m]=a.slice(l+1);continue}let c=a;t.flags.find(m=>m.name===c)?.type==="boolean"?r[c]=!0:i+1<e.length&&!e[i+1].startsWith("-")?r[c]=e[++i]:r[c]=!0}else if(n.startsWith("-")&&n.length===2){let a=n.slice(1),l=t.flags.find(c=>c.alias===a);l&&(l.type==="boolean"?r[l.name]=!0:i+1<e.length&&(r[l.name]=e[++i]))}else s.push(n)}return{args:s,flags:r}}showCommandHelp(e){if(console.log(`
|
|
162
162
|
\x1B[33mDescription:\x1B[0m`),console.log(` ${e.description}
|
|
163
163
|
`),console.log("\x1B[33mUsage:\x1B[0m"),console.log(` svelar ${e.name} [options]
|
|
164
164
|
`),e.flags.length>0){console.log("\x1B[33mOptions:\x1B[0m");for(let t of e.flags){let s=t.alias?`-${t.alias}, `:" ",r=`--${t.name}`,i=24-s.length-r.length;console.log(` ${s}${r}${" ".repeat(Math.max(1,i))}${t.description}`)}console.log()}}showHelp(){console.log(`
|
|
@@ -172,7 +172,7 @@ id: ${Date.now()}
|
|
|
172
172
|
svelar <command> [arguments] [options]
|
|
173
173
|
|
|
174
174
|
\x1B[33mAvailable Commands:\x1B[0m`);let e=new Map;for(let[,t]of this.commands){let s=t.name.includes(":")?t.name.split(":")[0]:"general";e.has(s)||e.set(s,[]),e.get(s).push(t)}for(let[t,s]of e){console.log(`
|
|
175
|
-
\x1B[32m${t}\x1B[0m`);for(let r of s){let i=30-r.name.length;console.log(` \x1B[36m${r.name}\x1B[0m${" ".repeat(Math.max(1,i))}${r.description}`)}}console.log()}};var
|
|
175
|
+
\x1B[32m${t}\x1B[0m`);for(let r of s){let i=30-r.name.length;console.log(` \x1B[36m${r.name}\x1B[0m${" ".repeat(Math.max(1,i))}${r.description}`)}}console.log()}};import{existsSync as an}from"fs";import{join as ye}from"path";var g=class{arguments=[];flags=[];async bootstrap(){let{join:e}=await import("path"),{existsSync:t,readFileSync:s}=await import("fs"),{Connection:r}=await Promise.resolve().then(()=>(x(),P)),i=process.cwd();try{r.getDriver();return}catch{}let n=e(i,"svelar.database.json");if(t(n))try{let c=s(n,"utf-8"),u=JSON.parse(c);r.configure(u),this.info("Database configured from svelar.database.json");return}catch(c){this.warn(`Failed to parse svelar.database.json: ${String(c?.message??c)}`)}let a=process.env.DB_DRIVER??"sqlite",l=process.env.DB_PATH??"database.db";r.configure({default:a,connections:{[a]:{driver:a,filename:l,host:process.env.DB_HOST,port:process.env.DB_PORT?parseInt(process.env.DB_PORT):void 0,database:process.env.DB_NAME,user:process.env.DB_USER,password:process.env.DB_PASSWORD}}}),this.info(`Using ${a} database${a==="sqlite"?`: ${l}`:""}`)}log(e){console.log(e)}info(e){console.log(`\x1B[34mINFO\x1B[0m ${e}`)}success(e){console.log(`\x1B[32m\u2713\x1B[0m ${e}`)}warn(e){console.log(`\x1B[33mWARN\x1B[0m ${e}`)}error(e){console.error(`\x1B[31mERROR\x1B[0m ${e}`)}table(e,t){let s=e.map((n,a)=>Math.max(n.length,...t.map(l=>(l[a]??"").length))),r=s.map(n=>"\u2500".repeat(n+2)).join("\u253C"),i=n=>n.map((a,l)=>` ${(a??"").padEnd(s[l])} `).join("\u2502");console.log(i(e)),console.log(r);for(let n of t)console.log(i(n))}newLine(){console.log()}isDDD(){return an(ye(process.cwd(),"src","lib","modules"))}sharedDir(e){return this.isDDD()?ye(process.cwd(),"src","lib","shared",e):ye(process.cwd(),"src","lib",e)}moduleDir(e,t){return this.isDDD()?ye(process.cwd(),"src","lib","modules",e):ye(process.cwd(),"src","lib",t)}};import{writeFileSync as ps,mkdirSync as hs,existsSync as on}from"fs";import{join as We}from"path";var Je=class extends g{name="make:model";description="Create a new model class";arguments=["name"];flags=[{name:"migration",alias:"m",description:"Also create a migration",type:"boolean"},{name:"controller",alias:"c",description:"Also create a controller",type:"boolean"},{name:"resource",alias:"r",description:"Create a resource controller",type:"boolean"},{name:"all",alias:"a",description:"Create model, migration, and controller",type:"boolean"},{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a model name.");return}let r=this.toSnakeCase(this.pluralize(s)),i=t.module||this.toSnakeCase(this.pluralize(s));!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${i}" as module. Consider: --module ${i}`);let n=this.moduleDir(i,"models");hs(n,{recursive:!0});let a=We(n,`${s}.ts`);if(on(a)){this.warn(`Model ${s} already exists at ${a}`);return}let l=`import { Model } from '@beeblock/svelar/orm';
|
|
176
176
|
|
|
177
177
|
export class ${s} extends Model {
|
|
178
178
|
static table = '${r}';
|
|
@@ -189,7 +189,7 @@ export class ${s} extends Model {
|
|
|
189
189
|
// return this.hasMany(Post, 'user_id');
|
|
190
190
|
// }
|
|
191
191
|
}
|
|
192
|
-
`;
|
|
192
|
+
`;ps(a,l);let c=this.isDDD()?`src/lib/modules/${i}`:"src/lib/models";if(this.success(`Model created: ${c}/${s}.ts`),t.migration||t.all){let m=`${new Date().toISOString().replace(/[^0-9]/g,"").slice(0,14)}_create_${r}_table`,h=We(process.cwd(),"src","lib","database","migrations");hs(h,{recursive:!0});let d=`import { Migration } from '@beeblock/svelar/database';
|
|
193
193
|
|
|
194
194
|
export default class Create${s}sTable extends Migration {
|
|
195
195
|
async up() {
|
|
@@ -206,9 +206,9 @@ export default class Create${s}sTable extends Migration {
|
|
|
206
206
|
await this.schema.dropTable('${r}');
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
|
-
`;
|
|
209
|
+
`;ps(We(h,`${m}.ts`),d),this.success(`Migration created: src/lib/database/migrations/${m}.ts`)}if(t.controller||t.resource||t.all){let u=`${s}Controller`,m=this.moduleDir(i,"controllers");hs(m,{recursive:!0});let h=t.resource||t.all,d=this.isDDD()?`./${s}.js`:`../models/${s}.js`,b=h?this.generateResourceController(s,u,d):this.generateBasicController(s,u,d);ps(We(m,`${u}.ts`),b);let w=this.isDDD()?`src/lib/modules/${i}`:"src/lib/controllers";this.success(`Controller created: ${w}/${u}.ts`)}}generateResourceController(e,t,s=`./${e}.js`){return`import { Controller, type RequestEvent } from '@beeblock/svelar/routing';
|
|
210
210
|
import { z } from '@beeblock/svelar/validation';
|
|
211
|
-
import { ${e} } from '
|
|
211
|
+
import { ${e} } from '${s}';
|
|
212
212
|
|
|
213
213
|
export class ${t} extends Controller {
|
|
214
214
|
/** GET /api/${this.toSnakeCase(this.pluralize(e))} */
|
|
@@ -249,8 +249,8 @@ export class ${t} extends Controller {
|
|
|
249
249
|
return this.noContent();
|
|
250
250
|
}
|
|
251
251
|
}
|
|
252
|
-
`}generateBasicController(e,t){return`import { Controller, type RequestEvent } from '@beeblock/svelar/routing';
|
|
253
|
-
import { ${e} } from '
|
|
252
|
+
`}generateBasicController(e,t,s=`./${e}.js`){return`import { Controller, type RequestEvent } from '@beeblock/svelar/routing';
|
|
253
|
+
import { ${e} } from '${s}';
|
|
254
254
|
|
|
255
255
|
export class ${t} extends Controller {
|
|
256
256
|
async index(event: RequestEvent) {
|
|
@@ -258,11 +258,11 @@ export class ${t} extends Controller {
|
|
|
258
258
|
return this.json(items);
|
|
259
259
|
}
|
|
260
260
|
}
|
|
261
|
-
`}toSnakeCase(e){return e.replace(/([A-Z])/g,"_$1").toLowerCase().replace(/^_/,"")}pluralize(e){return e.endsWith("y")?e.slice(0,-1)+"ies":e.endsWith("s")||e.endsWith("x")||e.endsWith("z")||e.endsWith("ch")||e.endsWith("sh")?e+"es":e+"s"}};import{writeFileSync as
|
|
261
|
+
`}toSnakeCase(e){return e.replace(/([A-Z])/g,"_$1").toLowerCase().replace(/^_/,"")}pluralize(e){return e.endsWith("y")?e.slice(0,-1)+"ies":e.endsWith("s")||e.endsWith("x")||e.endsWith("z")||e.endsWith("ch")||e.endsWith("sh")?e+"es":e+"s"}};import{writeFileSync as ln,mkdirSync as cn}from"fs";import{join as Nr}from"path";var Ve=class extends g{name="make:migration";description="Create a new migration file";arguments=["name"];flags=[{name:"create",description:"Table to create",type:"string"},{name:"table",description:"Table to modify",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a migration name (e.g. create_users_table).");return}let r=Nr(process.cwd(),"src","lib","database","migrations");cn(r,{recursive:!0});let n=`${new Date().toISOString().replace(/[^0-9]/g,"").slice(0,14)}_${s}`,a=this.toPascalCase(s),l=t.create??this.detectTableName(s,"create"),c=t.table??this.detectTableName(s,"add"),u;l?u=`import { Migration } from '@beeblock/svelar/database';
|
|
262
262
|
|
|
263
263
|
export default class ${a} extends Migration {
|
|
264
264
|
async up() {
|
|
265
|
-
await this.schema.createTable('${
|
|
265
|
+
await this.schema.createTable('${l}', (table) => {
|
|
266
266
|
table.increments('id');
|
|
267
267
|
// Add your columns here
|
|
268
268
|
table.timestamps();
|
|
@@ -270,7 +270,7 @@ export default class ${a} extends Migration {
|
|
|
270
270
|
}
|
|
271
271
|
|
|
272
272
|
async down() {
|
|
273
|
-
await this.schema.dropTable('${
|
|
273
|
+
await this.schema.dropTable('${l}');
|
|
274
274
|
}
|
|
275
275
|
}
|
|
276
276
|
`:c?u=`import { Migration } from '@beeblock/svelar/database';
|
|
@@ -298,9 +298,9 @@ export default class ${a} extends Migration {
|
|
|
298
298
|
// Reverse the migration
|
|
299
299
|
}
|
|
300
300
|
}
|
|
301
|
-
`,
|
|
301
|
+
`,ln(Nr(r,`${n}.ts`),u),this.success(`Migration created: src/lib/database/migrations/${n}.ts`)}detectTableName(e,t){let s=e.match(new RegExp(`${t}_(.+?)_table`));return s?s[1]:null}toPascalCase(e){return e.split("_").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join("")}};import{writeFileSync as dn,mkdirSync as un,existsSync as mn}from"fs";import{join as pn}from"path";var Qe=class extends g{name="make:controller";description="Create a new controller class";arguments=["name"];flags=[{name:"resource",alias:"r",description:"Create a resource controller with CRUD methods",type:"boolean"},{name:"model",alias:"m",description:"Model name for resource controller",type:"string"},{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a controller name.");return}let r=s.endsWith("Controller")?s:`${s}Controller`,i=r.replace(/Controller$/,""),n=t.module||i.toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${n}" as module. Consider: --module ${n}`);let a=this.moduleDir(n,"controllers");un(a,{recursive:!0});let l=pn(a,`${r}.ts`);if(mn(l)){this.warn(`Controller ${r} already exists.`);return}let c=t.model?this.isDDD()?`./${t.model}.js`:`../models/${t.model}.js`:void 0,u=t.resource?this.generateResourceController(r,t.model,c):this.generateBasicController(r);dn(l,u);let m=this.isDDD()?`src/lib/modules/${n}`:"src/lib/controllers";this.success(`Controller created: ${m}/${r}.ts`)}generateResourceController(e,t,s){return`import { Controller, type RequestEvent } from '@beeblock/svelar/routing';
|
|
302
302
|
import { z } from '@beeblock/svelar/validation';
|
|
303
|
-
${t?`import { ${t} } from '
|
|
303
|
+
${t&&s?`import { ${t} } from '${s}';
|
|
304
304
|
`:""}
|
|
305
305
|
export class ${e} extends Controller {
|
|
306
306
|
async index(event: RequestEvent) {
|
|
@@ -344,7 +344,7 @@ export class ${e} extends Controller {
|
|
|
344
344
|
return this.json({ message: 'Hello from ${e}' });
|
|
345
345
|
}
|
|
346
346
|
}
|
|
347
|
-
`}};import{writeFileSync as
|
|
347
|
+
`}};import{writeFileSync as hn,mkdirSync as gn,existsSync as fn}from"fs";import{join as bn}from"path";var Ge=class extends g{name="make:middleware";description="Create a new middleware class";arguments=["name"];flags=[];async handle(e){let t=e[0];if(!t){this.error("Please provide a middleware name.");return}let s=t.endsWith("Middleware")?t:`${t}Middleware`,r=this.sharedDir("middleware");gn(r,{recursive:!0});let i=bn(r,`${s}.ts`);if(fn(i)){this.warn(`Middleware ${s} already exists.`);return}let n=`import { Middleware, type MiddlewareContext, type NextFunction } from '@beeblock/svelar/middleware';
|
|
348
348
|
|
|
349
349
|
export class ${s} extends Middleware {
|
|
350
350
|
async handle(ctx: MiddlewareContext, next: NextFunction): Promise<Response | void> {
|
|
@@ -357,7 +357,7 @@ export class ${s} extends Middleware {
|
|
|
357
357
|
return response;
|
|
358
358
|
}
|
|
359
359
|
}
|
|
360
|
-
`;
|
|
360
|
+
`;hn(i,n);let a=this.isDDD()?`src/lib/shared/middleware/${s}.ts`:`src/lib/middleware/${s}.ts`;this.success(`Middleware created: ${a}`)}};import{writeFileSync as yn,mkdirSync as vn,existsSync as wn}from"fs";import{join as Cn}from"path";var Ye=class extends g{name="make:provider";description="Create a new service provider class";arguments=["name"];flags=[];async handle(e){let t=e[0];if(!t){this.error("Please provide a provider name.");return}let s=t.endsWith("ServiceProvider")?t:`${t}ServiceProvider`,r=this.sharedDir("providers");vn(r,{recursive:!0});let i=Cn(r,`${s}.ts`);if(wn(i)){this.warn(`Provider ${s} already exists.`);return}let n=`import { ServiceProvider } from '@beeblock/svelar/container';
|
|
361
361
|
import type { Container } from '@beeblock/svelar/container';
|
|
362
362
|
|
|
363
363
|
export class ${s} extends ServiceProvider {
|
|
@@ -378,7 +378,7 @@ export class ${s} extends ServiceProvider {
|
|
|
378
378
|
// Initialization logic here
|
|
379
379
|
}
|
|
380
380
|
}
|
|
381
|
-
`;
|
|
381
|
+
`;yn(i,n);let a=this.isDDD()?`src/lib/shared/providers/${s}.ts`:`src/lib/providers/${s}.ts`;this.success(`Provider created: ${a}`)}};import{writeFileSync as xn,mkdirSync as Pn,existsSync as Sn}from"fs";import{join as Ir}from"path";var Ze=class extends g{name="make:seeder";description="Create a new database seeder class";arguments=["name"];flags=[];async handle(e){let t=e[0];if(!t){this.error("Please provide a seeder name.");return}let s=t.endsWith("Seeder")?t:`${t}Seeder`,r=Ir(process.cwd(),"src","lib","database","seeders");Pn(r,{recursive:!0});let i=Ir(r,`${s}.ts`);if(Sn(i)){this.warn(`Seeder ${s} already exists.`);return}let n=`import { Seeder } from '@beeblock/svelar/database';
|
|
382
382
|
|
|
383
383
|
export class ${s} extends Seeder {
|
|
384
384
|
async run(): Promise<void> {
|
|
@@ -387,15 +387,15 @@ export class ${s} extends Seeder {
|
|
|
387
387
|
// await User.create({ name: 'Admin', email: 'admin@example.com' });
|
|
388
388
|
}
|
|
389
389
|
}
|
|
390
|
-
`;
|
|
391
|
-
import { ${
|
|
390
|
+
`;xn(i,n),this.success(`Seeder created: src/lib/database/seeders/${s}.ts`)}};import{writeFileSync as Rn,mkdirSync as Tn,existsSync as En}from"fs";import{join as kn}from"path";var Xe=class extends g{name="make:service";description="Create a new service class";arguments=["name"];flags=[{name:"crud",description:"Create a CRUD service with model",type:"boolean"},{name:"model",alias:"m",description:"Model name for CRUD service",type:"string"},{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a service name.");return}let r=s.endsWith("Service")?s:`${s}Service`,i=r.replace(/Service$/,""),n=t.module||i.toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${n}" as module. Consider: --module ${n}`);let a=this.moduleDir(n,"services");Tn(a,{recursive:!0});let l=kn(a,`${r}.ts`);if(En(l)){this.warn(`Service ${r} already exists.`);return}let c=t.model?this.isDDD()?`./${t.model}.js`:`../models/${t.model}.js`:void 0,u=t.crud?this.generateCrudService(r,t.model,c):this.generateBasicService(r);Rn(l,u);let m=this.isDDD()?`src/lib/modules/${n}`:"src/lib/services";this.success(`Service created: ${m}/${r}.ts`)}generateCrudService(e,t,s){let r=t||"Model",i=s||`./${r}.js`;return`import { CrudService, type ServiceResult } from '@beeblock/svelar/services';
|
|
391
|
+
import { ${r} } from '${i}';
|
|
392
392
|
|
|
393
|
-
export class ${e} extends CrudService<${
|
|
394
|
-
protected model = ${
|
|
393
|
+
export class ${e} extends CrudService<${r}> {
|
|
394
|
+
protected model = ${r};
|
|
395
395
|
|
|
396
396
|
// Override or add custom methods:
|
|
397
|
-
// async findByEmail(email: string): Promise<ServiceResult<${
|
|
398
|
-
// const record = await ${
|
|
397
|
+
// async findByEmail(email: string): Promise<ServiceResult<${r}>> {
|
|
398
|
+
// const record = await ${r}.where('email', email).first();
|
|
399
399
|
// if (!record) return this.fail('Not found');
|
|
400
400
|
// return this.ok(record);
|
|
401
401
|
// }
|
|
@@ -412,8 +412,8 @@ export class ${e} extends Service {
|
|
|
412
412
|
}
|
|
413
413
|
}
|
|
414
414
|
}
|
|
415
|
-
`}};import{writeFileSync as
|
|
416
|
-
import { ${c} } from '
|
|
415
|
+
`}};import{writeFileSync as $n,mkdirSync as Dn,existsSync as An}from"fs";import{join as Mn}from"path";var et=class extends g{name="make:repository";description="Create a new repository class";arguments=["name"];flags=[{name:"model",alias:"m",description:"Model name for the repository",type:"string"},{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a repository name.");return}let r=s.endsWith("Repository")?s:`${s}Repository`,i=r.replace(/Repository$/,""),n=t.module||i.toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${n}" as module. Consider: --module ${n}`);let a=this.moduleDir(n,"repositories");Dn(a,{recursive:!0});let l=Mn(a,`${r}.ts`);if(An(l)){this.warn(`Repository ${r} already exists.`);return}let c=t.model||this.inferModelName(r),u=this.isDDD()?`./${c}.js`:`../models/${c}.js`,m=`import { Repository } from '@beeblock/svelar/repositories';
|
|
416
|
+
import { ${c} } from '${u}';
|
|
417
417
|
|
|
418
418
|
export class ${r} extends Repository<${c}> {
|
|
419
419
|
model() {
|
|
@@ -429,7 +429,7 @@ export class ${r} extends Repository<${c}> {
|
|
|
429
429
|
// return ${c}.where('active', true).orderBy('name').get();
|
|
430
430
|
// }
|
|
431
431
|
}
|
|
432
|
-
|
|
432
|
+
`;$n(l,m);let h=this.isDDD()?`src/lib/modules/${n}`:"src/lib/repositories";this.success(`Repository created: ${h}/${r}.ts`)}inferModelName(e){return e.replace("Repository","")||"Model"}};import{writeFileSync as Ln,mkdirSync as _n,existsSync as Nn}from"fs";import{join as In}from"path";var tt=class extends g{name="make:action";description="Create a new action class";arguments=["name"];flags=[{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide an action name.");return}let r=s.endsWith("Action")?s:`${s}Action`,i=r.replace(/Action$/,""),n=t.module||i.toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${n}" as module. Consider: --module ${n}`);let a=this.moduleDir(n,"actions");_n(a,{recursive:!0});let l=In(a,`${r}.ts`);if(Nn(l)){this.warn(`Action ${r} already exists.`);return}let c=`import { Action } from '@beeblock/svelar/actions';
|
|
433
433
|
|
|
434
434
|
interface ${r}Input {
|
|
435
435
|
// Define input type
|
|
@@ -445,7 +445,7 @@ export class ${r} extends Action<${r}Input, ${r}Output> {
|
|
|
445
445
|
throw new Error('Not implemented');
|
|
446
446
|
}
|
|
447
447
|
}
|
|
448
|
-
`;
|
|
448
|
+
`;Ln(l,c);let u=this.isDDD()?`src/lib/modules/${n}`:"src/lib/actions";this.success(`Action created: ${u}/${r}.ts`)}};import{writeFileSync as jn,mkdirSync as On,existsSync as qn}from"fs";import{join as Un}from"path";var st=class extends g{name="make:request";description="Create a new FormRequest validation class";arguments=["name"];flags=[{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a request name.");return}let r=s.endsWith("Request")?s:`${s}Request`,i=r.replace(/Request$/,""),n=t.module||i.toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${n}" as module. Consider: --module ${n}`);let a=this.moduleDir(n,"dtos");On(a,{recursive:!0});let l=Un(a,`${r}.ts`);if(qn(l)){this.warn(`Request ${r} already exists.`);return}let c=`import { FormRequest } from '@beeblock/svelar/routing';
|
|
449
449
|
import { z } from '@beeblock/svelar/validation';
|
|
450
450
|
|
|
451
451
|
export class ${r} extends FormRequest {
|
|
@@ -474,7 +474,7 @@ export class ${r} extends FormRequest {
|
|
|
474
474
|
return data;
|
|
475
475
|
}
|
|
476
476
|
}
|
|
477
|
-
`;
|
|
477
|
+
`;jn(l,c);let u=this.isDDD()?`src/lib/modules/${n}`:"src/lib/dtos";this.success(`Request created: ${u}/${r}.ts`)}};import{writeFileSync as Bn,mkdirSync as Fn,existsSync as Hn}from"fs";import{join as zn}from"path";var rt=class extends g{name="make:plugin";description="Create a new plugin class";arguments=["name"];flags=[];async handle(e){let t=e[0];if(!t){this.error("Please provide a plugin name.");return}let s=t.endsWith("Plugin")?t:`${t}Plugin`,r=this.sharedDir("plugins");Fn(r,{recursive:!0});let i=zn(r,`${s}.ts`);if(Hn(i)){this.warn(`Plugin ${s} already exists.`);return}let n=s.replace(/([A-Z])/g,"-$1").toLowerCase().replace(/^-/,""),a=`import { Plugin } from '@beeblock/svelar/plugins';
|
|
478
478
|
import type { Container } from '@beeblock/svelar/container';
|
|
479
479
|
|
|
480
480
|
export class ${s} extends Plugin {
|
|
@@ -496,7 +496,7 @@ export class ${s} extends Plugin {
|
|
|
496
496
|
// Clean up resources
|
|
497
497
|
}
|
|
498
498
|
}
|
|
499
|
-
`;
|
|
499
|
+
`;Bn(i,a);let l=this.isDDD()?`src/lib/shared/plugins/${s}.ts`:`src/lib/plugins/${s}.ts`;this.success(`Plugin created: ${l}`)}};import{writeFileSync as Kn,mkdirSync as Wn,existsSync as Jn}from"fs";import{join as Vn}from"path";var it=class extends g{name="make:task";description="Create a new scheduled task class";arguments=["name"];flags=[];async handle(e){let t=e[0];if(!t){this.error("Please provide a task name.");return}let s=(t.endsWith("Task"),t),r=this.sharedDir("scheduler");Wn(r,{recursive:!0});let i=Vn(r,`${s}.ts`);if(Jn(i)){this.warn(`Task ${s} already exists.`);return}let n=`import { ScheduledTask } from '@beeblock/svelar/scheduler';
|
|
500
500
|
|
|
501
501
|
export class ${s} extends ScheduledTask {
|
|
502
502
|
name = '${this.toKebabCase(s)}';
|
|
@@ -529,15 +529,18 @@ export class ${s} extends ScheduledTask {
|
|
|
529
529
|
console.error('${s} failed:', error.message);
|
|
530
530
|
}
|
|
531
531
|
}
|
|
532
|
-
`;
|
|
532
|
+
`;Kn(i,n);let a=this.isDDD()?`src/lib/shared/scheduler/${s}.ts`:`src/lib/scheduler/${s}.ts`;this.success(`Scheduled task created: ${a}`)}toKebabCase(e){return e.replace(/([A-Z])/g,"-$1").toLowerCase().replace(/^-/,"")}};import{writeFileSync as Qn,mkdirSync as Gn,existsSync as Yn}from"fs";import{join as Zn}from"path";var nt=class extends g{name="make:job";description="Create a new queue job class";arguments=["name"];flags=[];async handle(e){let t=e[0];if(!t){this.error("Please provide a job name.");return}let s=(t.endsWith("Job"),t),r=this.sharedDir("jobs");Gn(r,{recursive:!0});let i=Zn(r,`${s}.ts`);if(Yn(i)){this.warn(`Job ${s} already exists.`);return}let n=`import { Job } from '@beeblock/svelar/queue';
|
|
533
533
|
|
|
534
534
|
export class ${s} extends Job {
|
|
535
535
|
maxAttempts = 3; // Retry up to 3 times
|
|
536
536
|
retryDelay = 60; // Wait 60 seconds between retries
|
|
537
537
|
queue = 'default'; // Queue name
|
|
538
538
|
|
|
539
|
-
|
|
539
|
+
data: any;
|
|
540
|
+
|
|
541
|
+
constructor(data: any) {
|
|
540
542
|
super();
|
|
543
|
+
this.data = data;
|
|
541
544
|
}
|
|
542
545
|
|
|
543
546
|
async handle(): Promise<void> {
|
|
@@ -553,7 +556,7 @@ export class ${s} extends Job {
|
|
|
553
556
|
console.log('${s} retrying, attempt', attempt);
|
|
554
557
|
}
|
|
555
558
|
}
|
|
556
|
-
`;
|
|
559
|
+
`;Qn(i,n);let a=this.isDDD()?`src/lib/shared/jobs/${s}.ts`:`src/lib/jobs/${s}.ts`;this.success(`Job created: ${a}`)}};import{writeFileSync as Xn,mkdirSync as ea,existsSync as ta}from"fs";import{join as sa}from"path";var at=class extends g{name="make:command";description="Create a new custom CLI command";arguments=["name"];flags=[{name:"command",description:'The terminal command name (e.g. "app:sync")',type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a command class name. Example: npx svelar make:command SyncUsers");return}let r=s.endsWith("Command")?s:`${s}Command`,i=this.sharedDir("commands");ea(i,{recursive:!0});let n=sa(i,`${r}.ts`);if(ta(n)){this.warn(`Command ${r} already exists.`);return}let a=t.command??this.deriveCommandName(r),l=`import { Command } from '@beeblock/svelar/cli';
|
|
557
560
|
|
|
558
561
|
export class ${r} extends Command {
|
|
559
562
|
name = '${a}';
|
|
@@ -576,7 +579,7 @@ export class ${r} extends Command {
|
|
|
576
579
|
this.success('Done!');
|
|
577
580
|
}
|
|
578
581
|
}
|
|
579
|
-
`;
|
|
582
|
+
`;Xn(n,l);let c=this.isDDD()?`src/lib/shared/commands/${r}.ts`:`src/lib/commands/${r}.ts`;this.success(`Command created: ${c}`),this.info(`Command name: ${a}`),this.newLine(),this.info("Your command will be auto-discovered. Run it with:"),this.log(` npx svelar ${a}`)}deriveCommandName(e){return`app:${e.replace(/Command$/,"").replace(/([a-z])([A-Z])/g,"$1-$2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1-$2").toLowerCase()}`}};import{writeFileSync as ra,mkdirSync as ia,existsSync as na}from"fs";import{join as jr}from"path";var ot=class extends g{name="make:config";description="Create a new config file";arguments=["name"];flags=[];templates={app:`import { env } from 'svelar/config';
|
|
580
583
|
|
|
581
584
|
export default {
|
|
582
585
|
name: env('APP_NAME', 'Svelar'),
|
|
@@ -785,7 +788,7 @@ export default {
|
|
|
785
788
|
},
|
|
786
789
|
},
|
|
787
790
|
};
|
|
788
|
-
`};async handle(e){let t=e[0];if(!t){this.error("Please provide a config file name. Example: npx svelar make:config database"),this.newLine(),this.info("Available presets: app, database, auth, mail, cache, queue, storage, broadcasting, logging");return}let s=
|
|
791
|
+
`};async handle(e){let t=e[0];if(!t){this.error("Please provide a config file name. Example: npx svelar make:config database"),this.newLine(),this.info("Available presets: app, database, auth, mail, cache, queue, storage, broadcasting, logging");return}let s=jr(process.cwd(),"config");ia(s,{recursive:!0});let r=t.toLowerCase().replace(/\s+/g,"-"),i=jr(s,`${r}.ts`);if(na(i)){this.warn(`Config file config/${r}.ts already exists.`);return}let n=this.templates[r]??this.blankTemplate(r);ra(i,n),this.success(`Config created: config/${r}.ts`),this.newLine(),this.info("Access it with:"),this.log(` config.get('${r}.key')`)}blankTemplate(e){return`import { env } from 'svelar/config';
|
|
789
792
|
|
|
790
793
|
export default {
|
|
791
794
|
// Add your ${e} configuration here
|
|
@@ -794,7 +797,7 @@ export default {
|
|
|
794
797
|
// env<number>('MY_PORT', 3000)
|
|
795
798
|
// env<boolean>('MY_FLAG', false)
|
|
796
799
|
};
|
|
797
|
-
`}};import{writeFileSync as
|
|
800
|
+
`}};import{writeFileSync as aa,mkdirSync as oa,existsSync as la}from"fs";import{join as ca}from"path";var lt=class extends g{name="make:channel";description="Create a new broadcast channel authorization";arguments=["name"];flags=[{name:"presence",alias:"p",description:"Create a presence channel",type:"boolean"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a channel name. Example: npx svelar make:channel OrderChannel");return}let r=s.endsWith("Channel")?s:`${s}Channel`,i=this.sharedDir("channels");oa(i,{recursive:!0});let n=ca(i,`${r}.ts`);if(la(n)){this.warn(`Channel ${r} already exists.`);return}let a=r.replace(/Channel$/,""),l=a.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),c=a.charAt(0).toLowerCase()+a.slice(1)+"Id",u=t.presence,h=`${u?"presence":"private"}-${l}.{${c}}`,d=u?this.presenceTemplate(r,h,c):this.privateTemplate(r,h,c);aa(n,d);let b=this.isDDD()?"src/lib/shared/channels":"src/lib/channels";this.success(`Channel created: ${b}/${r}.ts`),this.info(`Channel pattern: ${h}`),this.newLine(),this.info("Register it in src/app.ts or a service provider:"),this.log(` import { register${r} } from './${b.replace("src/","")}/${r}.js';`),this.log(` register${r}();`)}privateTemplate(e,t,s){let r=e.replace(/Channel$/,"");return`import { Broadcast } from '@beeblock/svelar/broadcasting';
|
|
798
801
|
|
|
799
802
|
/**
|
|
800
803
|
* ${e}
|
|
@@ -837,7 +840,7 @@ export function register${e}(): void {
|
|
|
837
840
|
};
|
|
838
841
|
});
|
|
839
842
|
}
|
|
840
|
-
`}};import{writeFileSync as da,mkdirSync as ua,existsSync as ma}from"fs";import{join as
|
|
843
|
+
`}};import{writeFileSync as da,mkdirSync as ua,existsSync as ma}from"fs";import{join as ve}from"path";var ct=class extends g{name="make:docker";description="Scaffold Docker deployment files (Dockerfile, docker-compose.yml, PM2 config)";arguments=[];flags=[{name:"db",alias:"d",description:"Database driver: postgres, mysql, sqlite (default: postgres)",type:"string"},{name:"soketi",alias:"s",description:"Include Soketi WebSocket server",type:"boolean"},{name:"redis",alias:"r",description:"Include Redis service",type:"boolean"},{name:"gotenberg",alias:"g",description:"Include Gotenberg PDF service (default: true)",type:"boolean"},{name:"rustfs",description:"Include RustFS S3-compatible object storage (default: true)",type:"boolean"},{name:"meilisearch",alias:"m",description:"Include Meilisearch full-text search engine",type:"boolean"},{name:"force",alias:"f",description:"Overwrite existing files",type:"boolean"}];async handle(e,t){let s=process.cwd(),r=t.db??"postgres",i=t.soketi??!0,n=t.redis??!0,a=t.gotenberg??!0,l=t.rustfs??!0,c=t.meilisearch??!1,u=t.force??!1,m=["postgres","mysql","sqlite"];if(!m.includes(r)){this.error(`Unknown database driver: ${r}. Use one of: ${m.join(", ")}`);return}let h=[{path:ve(s,"Dockerfile"),content:this.dockerfileTemplate(),label:"Dockerfile"},{path:ve(s,"docker-compose.yml"),content:this.composeTemplate(r,i,n,a,l,c),label:"docker-compose.yml"},{path:ve(s,".dockerignore"),content:this.dockerignoreTemplate(),label:".dockerignore"},{path:ve(s,"ecosystem.config.cjs"),content:this.pm2Template(),label:"ecosystem.config.cjs"}],d=0,b=0;for(let w of h){if(ma(w.path)&&!u){this.warn(`${w.label} already exists (use --force to overwrite)`),b++;continue}da(w.path,w.content),this.success(`Created ${w.label}`),d++}if(r!=="sqlite"){let w=ve(s,"docker");ua(w,{recursive:!0})}this.newLine(),d>0?this.info(`${d} file(s) created${b>0?`, ${b} skipped`:""}`):this.info("No files created (all exist already)"),this.newLine(),this.info("Quick start:"),this.log(" # Build and start all services"),this.log(" docker compose up -d --build"),this.newLine(),this.log(" # Run migrations inside the container"),this.log(" docker compose exec app npx svelar migrate"),this.newLine(),this.log(" # View logs"),this.log(" docker compose logs -f app"),this.newLine(),this.log(" # Stop services"),this.log(" docker compose down"),this.newLine(),this.info("Make sure to update .env with production values before deploying.")}dockerfileTemplate(){return`# \u2500\u2500 Svelar Production Dockerfile \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
841
844
|
# Multi-stage build for a lean production image.
|
|
842
845
|
|
|
843
846
|
# Stage 1: Install dependencies & build
|
|
@@ -890,7 +893,7 @@ HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \\
|
|
|
890
893
|
|
|
891
894
|
# Start with PM2
|
|
892
895
|
CMD ["pm2-runtime", "ecosystem.config.cjs"]
|
|
893
|
-
`}composeTemplate(e,t,s,r,i=!0,n=!1){let a=[];a.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"),a.push("# Generated by: npx svelar make:docker"),a.push("#"),a.push("# Usage:"),a.push("# docker compose up -d --build # Start all services"),a.push("# docker compose exec app npx svelar migrate # Run migrations"),a.push("# docker compose logs -f app # View app logs"),a.push("# docker compose down # Stop all services"),a.push(""),a.push("services:"),a.push(" app:"),a.push(" build: ."),a.push(" restart: unless-stopped"),a.push(" ports:"),a.push(' - "${APP_PORT:-3000}:3000"'),a.push(" env_file: .env"),a.push(" environment:"),a.push(" - NODE_ENV=production"),e==="postgres"?(a.push(" - DB_HOST=postgres"),a.push(" - DB_PORT=5432")):e==="mysql"&&(a.push(" - DB_HOST=mysql"),a.push(" - DB_PORT=3306")),s&&(a.push(" - REDIS_HOST=redis"),a.push(" - REDIS_PORT=6379"),a.push(" - REDIS_PASSWORD=${REDIS_PASSWORD:-svelarsecret}"),a.push(" - QUEUE_DRIVER=redis")),t&&(a.push(" - PUSHER_HOST=soketi"),a.push(" - PUSHER_PORT=6001")),r&&a.push(" - GOTENBERG_URL=http://gotenberg:3000"),i&&(a.push(" - S3_ENDPOINT=http://rustfs:9000"),a.push(" - S3_ACCESS_KEY=${RUSTFS_ROOT_USER:-svelar}"),a.push(" - S3_SECRET_KEY=${RUSTFS_ROOT_PASSWORD:-svelarsecret}"),a.push(" - S3_BUCKET=${S3_BUCKET:-svelar}"),a.push(" - S3_REGION=us-east-1"),a.push(" - STORAGE_DISK=s3")),n&&(a.push(" - MEILISEARCH_HOST=http://meilisearch:7700"),a.push(" - MEILISEARCH_KEY=${MEILI_MASTER_KEY:-svelar-meili-master-key}"));let
|
|
896
|
+
`}composeTemplate(e,t,s,r,i=!0,n=!1){let a=[];a.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"),a.push("# Generated by: npx svelar make:docker"),a.push("#"),a.push("# Usage:"),a.push("# docker compose up -d --build # Start all services"),a.push("# docker compose exec app npx svelar migrate # Run migrations"),a.push("# docker compose logs -f app # View app logs"),a.push("# docker compose down # Stop all services"),a.push(""),a.push("services:"),a.push(" app:"),a.push(" build: ."),a.push(" restart: unless-stopped"),a.push(" ports:"),a.push(' - "${APP_PORT:-3000}:3000"'),a.push(" env_file: .env"),a.push(" environment:"),a.push(" - NODE_ENV=production"),e==="postgres"?(a.push(" - DB_HOST=postgres"),a.push(" - DB_PORT=5432")):e==="mysql"&&(a.push(" - DB_HOST=mysql"),a.push(" - DB_PORT=3306")),s&&(a.push(" - REDIS_HOST=redis"),a.push(" - REDIS_PORT=6379"),a.push(" - REDIS_PASSWORD=${REDIS_PASSWORD:-svelarsecret}"),a.push(" - QUEUE_DRIVER=redis")),t&&(a.push(" - PUSHER_HOST=soketi"),a.push(" - PUSHER_PORT=6001")),r&&a.push(" - GOTENBERG_URL=http://gotenberg:3000"),i&&(a.push(" - S3_ENDPOINT=http://rustfs:9000"),a.push(" - S3_ACCESS_KEY=${RUSTFS_ROOT_USER:-svelar}"),a.push(" - S3_SECRET_KEY=${RUSTFS_ROOT_PASSWORD:-svelarsecret}"),a.push(" - S3_BUCKET=${S3_BUCKET:-svelar}"),a.push(" - S3_REGION=us-east-1"),a.push(" - STORAGE_DISK=s3")),n&&(a.push(" - MEILISEARCH_HOST=http://meilisearch:7700"),a.push(" - MEILISEARCH_KEY=${MEILI_MASTER_KEY:-svelar-meili-master-key}"));let l=[];if(e==="postgres"&&l.push("postgres"),e==="mysql"&&l.push("mysql"),s&&l.push("redis"),t&&l.push("soketi"),r&&l.push("gotenberg"),i&&l.push("rustfs"),n&&l.push("meilisearch"),l.length>0){a.push(" depends_on:");for(let c of l)a.push(` ${c}:`),a.push(" condition: service_healthy")}return a.push(" volumes:"),a.push(" - app_storage:/app/storage"),e==="postgres"&&(a.push(""),a.push(" postgres:"),a.push(" image: postgres:16-alpine"),a.push(" restart: unless-stopped"),a.push(" # No ports exposed \u2014 only reachable by app via Docker network"),a.push(" environment:"),a.push(" POSTGRES_DB: ${DB_NAME:-svelar}"),a.push(" POSTGRES_USER: ${DB_USER:-svelar}"),a.push(" POSTGRES_PASSWORD: ${DB_PASSWORD:-secret}"),a.push(" volumes:"),a.push(" - pgdata:/var/lib/postgresql/data"),a.push(" healthcheck:"),a.push(' test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-svelar}"]'),a.push(" interval: 10s"),a.push(" timeout: 5s"),a.push(" retries: 5")),e==="mysql"&&(a.push(""),a.push(" mysql:"),a.push(" image: mysql:8.0"),a.push(" restart: unless-stopped"),a.push(" # No ports exposed \u2014 only reachable by app via Docker network"),a.push(" environment:"),a.push(" MYSQL_DATABASE: ${DB_NAME:-svelar}"),a.push(" MYSQL_USER: ${DB_USER:-svelar}"),a.push(" MYSQL_PASSWORD: ${DB_PASSWORD:-secret}"),a.push(" MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-rootsecret}"),a.push(" volumes:"),a.push(" - mysqldata:/var/lib/mysql"),a.push(" healthcheck:"),a.push(' test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]'),a.push(" interval: 10s"),a.push(" timeout: 5s"),a.push(" retries: 5")),s&&(a.push(""),a.push(" redis:"),a.push(" image: redis:7-alpine"),a.push(" restart: unless-stopped"),a.push(" # No ports exposed \u2014 only reachable by app via Docker network"),a.push(" command: redis-server --requirepass ${REDIS_PASSWORD:-svelarsecret}"),a.push(" volumes:"),a.push(" - redisdata:/data"),a.push(" healthcheck:"),a.push(' test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:-svelarsecret}", "ping"]'),a.push(" interval: 10s"),a.push(" timeout: 5s"),a.push(" retries: 5")),t&&(a.push(""),a.push(" soketi:"),a.push(" image: quay.io/soketi/soketi:1.6-16-debian"),a.push(" restart: unless-stopped"),a.push(" # No ports exposed \u2014 only reachable by app via Docker network"),a.push(" # Expose 6001 to host only if clients connect directly (uncomment below)"),a.push(" # ports:"),a.push(' # - "${SOKETI_PORT:-6001}:6001"'),a.push(" environment:"),a.push(' SOKETI_DEBUG: "${SOKETI_DEBUG:-0}"'),a.push(" SOKETI_DEFAULT_APP_ID: ${PUSHER_APP_ID}"),a.push(" SOKETI_DEFAULT_APP_KEY: ${PUSHER_KEY}"),a.push(" SOKETI_DEFAULT_APP_SECRET: ${PUSHER_SECRET}"),a.push(' SOKETI_DEFAULT_APP_MAX_CONNS: "${SOKETI_MAX_CONNS:-1000}"'),a.push(' SOKETI_DEFAULT_APP_ENABLE_CLIENT_MESSAGES: "true"'),a.push(' SOKETI_DEFAULT_APP_MAX_BACKEND_EVENTS_PER_SEC: "-1"'),a.push(" healthcheck:"),a.push(' test: ["CMD", "wget", "-qO-", "http://localhost:6001"]'),a.push(" interval: 10s"),a.push(" timeout: 5s"),a.push(" retries: 3")),r&&(a.push(""),a.push(" gotenberg:"),a.push(" image: gotenberg/gotenberg:8"),a.push(" restart: unless-stopped"),a.push(" # No ports exposed \u2014 only reachable by app via Docker network"),a.push(" environment:"),a.push(' CHROMIUM_DISABLE_JAVASCRIPT: "false"'),a.push(' CHROMIUM_ALLOW_LIST: "file:///tmp/.*"'),a.push(' API_TIMEOUT: "${GOTENBERG_TIMEOUT:-60s}"'),a.push(' LOG_LEVEL: "${GOTENBERG_LOG_LEVEL:-info}"'),a.push(" healthcheck:"),a.push(' test: ["CMD", "curl", "-f", "http://localhost:3000/health"]'),a.push(" interval: 10s"),a.push(" timeout: 5s"),a.push(" retries: 5")),i&&(a.push(""),a.push(" rustfs:"),a.push(" image: rustfs/rustfs:latest"),a.push(" restart: unless-stopped"),a.push(" ports:"),a.push(' - "${RUSTFS_CONSOLE_PORT:-9001}:9001" # Admin console (protect with firewall)'),a.push(" environment:"),a.push(" RUSTFS_ROOT_USER: ${RUSTFS_ROOT_USER:-svelar}"),a.push(" RUSTFS_ROOT_PASSWORD: ${RUSTFS_ROOT_PASSWORD:-svelarsecret}"),a.push(' command: server /data --console-address ":9001"'),a.push(" volumes:"),a.push(" - rustfs_data:/data"),a.push(" healthcheck:"),a.push(' test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]'),a.push(" interval: 10s"),a.push(" timeout: 5s"),a.push(" retries: 5")),n&&(a.push(""),a.push(" meilisearch:"),a.push(" image: getmeili/meilisearch:v1.13"),a.push(" restart: unless-stopped"),a.push(" # No ports exposed \u2014 only reachable by app via Docker network"),a.push(" # Uncomment below to access the dashboard from the host"),a.push(" # ports:"),a.push(' # - "${MEILI_PORT:-7700}:7700"'),a.push(" environment:"),a.push(" MEILI_MASTER_KEY: ${MEILI_MASTER_KEY:-svelar-meili-master-key}"),a.push(" MEILI_ENV: production"),a.push(" MEILI_DB_PATH: /meili_data"),a.push(' MEILI_NO_ANALYTICS: "true"'),a.push(" volumes:"),a.push(" - meili_data:/meili_data"),a.push(" healthcheck:"),a.push(' test: ["CMD", "wget", "--no-verbose", "--spider", "http://localhost:7700/health"]'),a.push(" interval: 10s"),a.push(" timeout: 5s"),a.push(" retries: 5")),a.push(""),a.push("volumes:"),a.push(" app_storage:"),e==="postgres"&&a.push(" pgdata:"),e==="mysql"&&a.push(" mysqldata:"),s&&a.push(" redisdata:"),i&&a.push(" rustfs_data:"),n&&a.push(" meili_data:"),a.push(""),a.join(`
|
|
894
897
|
`)}dockerignoreTemplate(){return`# Dependencies
|
|
895
898
|
node_modules
|
|
896
899
|
|
|
@@ -1013,7 +1016,7 @@ module.exports = {
|
|
|
1013
1016
|
},
|
|
1014
1017
|
],
|
|
1015
1018
|
};
|
|
1016
|
-
`}};import{writeFileSync as pa,mkdirSync as ha,existsSync as
|
|
1019
|
+
`}};import{writeFileSync as pa,mkdirSync as ha,existsSync as Or}from"fs";import{join as N}from"path";var dt=class extends g{name="make:broadcasting";description="Scaffold broadcasting routes (Pusher auth, SSE stream, client init)";arguments=[];flags=[{name:"sse",description:"Only scaffold SSE routes (no Pusher auth)",type:"boolean"},{name:"pusher",description:"Only scaffold Pusher/Soketi routes",type:"boolean"},{name:"force",alias:"f",description:"Overwrite existing files",type:"boolean"}];async handle(e,t){let s=process.cwd(),r=t.force??!1,i=t.sse??!1,n=t.pusher??!1,a=!i&&!n,l=[];(a||n)&&l.push({path:N(s,"src/routes/api/broadcasting/auth/+server.ts"),content:this.pusherAuthRoute(),label:"src/routes/api/broadcasting/auth/+server.ts",dirs:[N(s,"src/routes/api/broadcasting/auth")]}),(a||i)&&l.push({path:N(s,"src/routes/api/broadcasting/[channel]/+server.ts"),content:this.sseRoute(),label:"src/routes/api/broadcasting/[channel]/+server.ts",dirs:[N(s,"src/routes/api/broadcasting/[channel]")]}),l.push({path:N(s,"src/lib/broadcasting.ts"),content:a||n?this.clientPusher():this.clientSSE(),label:"src/lib/broadcasting.ts",dirs:[N(s,"src/lib")]});let c=N(s,"config/broadcasting.ts");Or(c)||l.push({path:c,content:this.configTemplate(),label:"config/broadcasting.ts",dirs:[N(s,"config")]});let u=0,m=0;for(let h of l){if(Or(h.path)&&!r){this.warn(`${h.label} already exists (use --force to overwrite)`),m++;continue}for(let d of h.dirs)ha(d,{recursive:!0});pa(h.path,h.content),this.success(`Created ${h.label}`),u++}this.newLine(),u>0?this.info(`${u} file(s) created${m>0?`, ${m} skipped`:""}`):this.info("No files created (all exist already)"),this.newLine(),this.info("Next steps:"),a||n?(this.log(" 1. Install pusher-js: npm install pusher-js"),this.log(" 2. Add Pusher env vars to .env:"),this.log(" BROADCAST_DRIVER=pusher"),this.log(" PUSHER_KEY=svelar-key"),this.log(" PUSHER_SECRET=svelar-secret"),this.log(" PUSHER_APP_ID=svelar-app"),this.log(' PUSHER_HOST=localhost # or "soketi" in Docker'),this.log(" PUSHER_PORT=6001"),this.log(" 3. Import broadcasting in your root layout:"),this.log(" import '$lib/broadcasting';")):(this.log(" 1. Import broadcasting in your root layout:"),this.log(" import '$lib/broadcasting';")),this.log(" 4. Register channel authorizations in src/app.ts"),this.log(" 5. Run 'npx svelar make:docker' for Soketi in Docker Compose")}pusherAuthRoute(){return`/**
|
|
1017
1020
|
* Pusher/Soketi Channel Authorization Endpoint
|
|
1018
1021
|
*
|
|
1019
1022
|
* This route authenticates channel subscriptions from pusher-js.
|
|
@@ -1167,16 +1170,16 @@ export default {
|
|
|
1167
1170
|
},
|
|
1168
1171
|
},
|
|
1169
1172
|
};
|
|
1170
|
-
`}};import{writeFileSync as
|
|
1171
|
-
import type { ${t} } from '
|
|
1173
|
+
`}};import{writeFileSync as qr,mkdirSync as ga,existsSync as Ur}from"fs";import{join as Br}from"path";var ut=class extends g{name="make:resource";description="Create a new API resource (response transformer)";arguments=["name"];flags=[{name:"module",description:"Module name (e.g. auth, billing)",type:"string"},{name:"model",alias:"m",description:"Model name to transform",type:"string"},{name:"collection",alias:"c",description:"Also generate a collection resource",type:"boolean"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a resource name.");return}let r=s.endsWith("Resource")?s:`${s}Resource`,i=t.module||this.deriveModuleName(r);!t.module&&this.isDDD()&&this.warn(`No --module specified, using "${i}". Use --module=<name> to target a specific module.`);let n=this.moduleDir(i,"resources");ga(n,{recursive:!0});let a=Br(n,`${r}.ts`);if(Ur(a)){this.warn(`Resource ${r} already exists.`);return}let l=t.model||this.inferModelName(r),c=this.isDDD()?`./${l}.js`:`../models/${l}.js`,u=this.generateResource(r,l,c);qr(a,u);let m=this.isDDD()?`src/lib/modules/${i}`:"src/lib/resources";if(this.success(`Resource created: ${m}/${r}.ts`),t.collection){let h=r.replace("Resource","CollectionResource"),d=Br(n,`${h}.ts`);if(!Ur(d)){let b=this.isDDD()?`./${l}.js`:`../models/${l}.js`,w=this.generateCollectionResource(h,r,l,b);qr(d,w);let E=this.isDDD()?`src/lib/modules/${i}`:"src/lib/resources";this.success(`Collection resource created: ${E}/${h}.ts`)}}}generateResource(e,t,s=`./${t}.js`){let r=`${t}Data`;return`import { Resource } from '@beeblock/svelar/routing';
|
|
1174
|
+
import type { ${t} } from '${s}';
|
|
1172
1175
|
|
|
1173
1176
|
// \u2500\u2500 API Contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1174
1177
|
// Define the shape once \u2014 import this type on the frontend.
|
|
1175
1178
|
//
|
|
1176
|
-
// import type { ${
|
|
1179
|
+
// import type { ${r} } from '$lib/modules/.../${e}';
|
|
1177
1180
|
//
|
|
1178
1181
|
|
|
1179
|
-
export interface ${
|
|
1182
|
+
export interface ${r} {
|
|
1180
1183
|
id: number;
|
|
1181
1184
|
// Add your fields here
|
|
1182
1185
|
// name: string;
|
|
@@ -1186,8 +1189,8 @@ export interface ${s} {
|
|
|
1186
1189
|
|
|
1187
1190
|
// \u2500\u2500 Resource \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1188
1191
|
|
|
1189
|
-
export class ${e} extends Resource<${t}, ${
|
|
1190
|
-
toJSON(): ${
|
|
1192
|
+
export class ${e} extends Resource<${t}, ${r}> {
|
|
1193
|
+
toJSON(): ${r} {
|
|
1191
1194
|
return {
|
|
1192
1195
|
id: this.data.id,
|
|
1193
1196
|
// Map model fields to the API contract
|
|
@@ -1213,9 +1216,9 @@ export class ${e} extends Resource<${t}, ${s}> {
|
|
|
1213
1216
|
// return { comments_count: this.data.comments_count ?? 0 };
|
|
1214
1217
|
// }
|
|
1215
1218
|
}
|
|
1216
|
-
`}generateCollectionResource(e,t,s){return`import { Resource } from '@beeblock/svelar/routing';
|
|
1219
|
+
`}generateCollectionResource(e,t,s,r=`./${s}.js`){return`import { Resource } from '@beeblock/svelar/routing';
|
|
1217
1220
|
import { ${t} } from './${t}.js';
|
|
1218
|
-
import type { ${s} } from '
|
|
1221
|
+
import type { ${s} } from '${r}';
|
|
1219
1222
|
|
|
1220
1223
|
/**
|
|
1221
1224
|
* ${e}
|
|
@@ -1245,7 +1248,7 @@ export class ${e} {
|
|
|
1245
1248
|
.toObject();
|
|
1246
1249
|
}
|
|
1247
1250
|
}
|
|
1248
|
-
`}deriveModuleName(e){return e.replace(/Resource$/,"").replace(/Collection$/,"").toLowerCase()}inferModelName(e){return e.replace(/Resource$/,"")||"Model"}};import{writeFileSync as fa,mkdirSync as
|
|
1251
|
+
`}deriveModuleName(e){return e.replace(/Resource$/,"").replace(/Collection$/,"").toLowerCase()}inferModelName(e){return e.replace(/Resource$/,"")||"Model"}};import{writeFileSync as fa,mkdirSync as ba,existsSync as ya}from"fs";import{join as va}from"path";var mt=class extends g{name="make:schema";description="Create a contract schema (Zod schemas + shared types)";arguments=["name"];flags=[{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a schema name (e.g. User, Post, Invoice).");return}let r=s.charAt(0).toUpperCase()+s.slice(1),i=this.toKebab(s)+".schema",n=t.module||s.toLowerCase(),a=this.moduleDir(n,"schemas");ba(a,{recursive:!0});let l=va(a,`${i}.ts`);if(ya(l)){let h=this.isDDD()?`src/lib/modules/${n}`:"src/lib/schemas";this.warn(`Schema already exists: ${h}/${i}.ts`);return}let c=this.generateSchema(r);fa(l,c);let u=this.isDDD()?`src/lib/modules/${n}`:"src/lib/schemas";this.success(`Schema created: ${u}/${i}.ts`),this.info(""),this.info(" Use this schema across your entire stack:"),this.info(""),this.info(` Resource: extends Resource<${r}, ${r}Data>`),this.info(` FormRequest: uses create${r}Schema / update${r}Schema`);let m=this.isDDD()?`$lib/modules/${n}/${i}`:`$lib/schemas/${i}`;this.info(` Frontend: import type { ${r}Data } from '${m}'`)}generateSchema(e){let t=e.charAt(0).toLowerCase()+e.slice(1),s=this.toKebab(e);return`import { z } from 'zod';
|
|
1249
1252
|
|
|
1250
1253
|
// \u2500\u2500 ${e} Contract Schema \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1251
1254
|
//
|
|
@@ -1280,8 +1283,8 @@ export const update${e}Schema = create${e}Schema.partial();
|
|
|
1280
1283
|
export type ${e}Data = z.infer<typeof ${t}Schema>;
|
|
1281
1284
|
export type Create${e}Input = z.infer<typeof create${e}Schema>;
|
|
1282
1285
|
export type Update${e}Input = z.infer<typeof update${e}Schema>;
|
|
1283
|
-
`}toKebab(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1-$2").toLowerCase()}};import{writeFileSync as
|
|
1284
|
-
import type { ${r} } from '
|
|
1286
|
+
`}toKebab(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1-$2").toLowerCase()}};import{writeFileSync as wa,mkdirSync as Ca,existsSync as xa}from"fs";import{join as Pa}from"path";var pt=class extends g{name="make:observer";description="Create a new model observer class";arguments=["name"];flags=[{name:"model",alias:"m",description:"The model class to observe",type:"string"},{name:"module",description:"Module name (e.g. users, posts)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide an observer name (e.g. UserObserver).");return}let r=t.model||s.replace(/Observer$/,""),i=t.module||this.toSnakeCase(this.pluralize(r)),n=this.moduleDir(i,"observers");Ca(n,{recursive:!0});let a=Pa(n,`${s}.ts`);if(xa(a)){this.warn(`Observer ${s} already exists at ${a}`);return}let l=this.isDDD()?`./${r}.js`:`../models/${r}.js`,c=`import { ModelObserver } from '@beeblock/svelar/orm';
|
|
1287
|
+
import type { ${r} } from '${l}';
|
|
1285
1288
|
|
|
1286
1289
|
export class ${s} extends ModelObserver {
|
|
1287
1290
|
// Fires before a new ${r} is inserted
|
|
@@ -1318,7 +1321,7 @@ export class ${s} extends ModelObserver {
|
|
|
1318
1321
|
// async deleted(${r.toLowerCase()}: ${r}) {
|
|
1319
1322
|
// }
|
|
1320
1323
|
}
|
|
1321
|
-
`;
|
|
1324
|
+
`;wa(a,c);let u=this.isDDD()?`src/lib/modules/${i}`:"src/lib/observers";this.success(`Observer created: ${u}/${s}.ts`),this.info(`Register it in your app: ${r}.observe(new ${s}());`)}toSnakeCase(e){return e.replace(/([A-Z])/g,"_$1").toLowerCase().replace(/^_/,"")}pluralize(e){return e.endsWith("y")?e.slice(0,-1)+"ies":e.endsWith("s")||e.endsWith("x")||e.endsWith("z")||e.endsWith("ch")||e.endsWith("sh")?e+"es":e+"s"}};import{writeFileSync as Sa,mkdirSync as Ra,existsSync as Ta}from"fs";import{join as Ea}from"path";var ht=class extends g{name="make:event";description="Create a new event class";arguments=["name"];flags=[{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide an event name (e.g. UserRegistered).");return}let r=t.module||s.replace(/([A-Z])/g," $1").trim().split(" ")[0].toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${r}" as module. Consider: --module ${r}`);let i=this.moduleDir(r,"events");Ra(i,{recursive:!0});let n=Ea(i,`${s}.ts`);if(Ta(n)){this.warn(`Event ${s} already exists at ${n}`);return}let a=`/**
|
|
1322
1325
|
* ${s} Event
|
|
1323
1326
|
*
|
|
1324
1327
|
* Dispatched when ... (describe when this event fires).
|
|
@@ -1336,30 +1339,30 @@ export class ${s} {
|
|
|
1336
1339
|
// public readonly metadata?: Record<string, any>,
|
|
1337
1340
|
) {}
|
|
1338
1341
|
}
|
|
1339
|
-
`;
|
|
1342
|
+
`;Sa(n,a);let l=this.isDDD()?`src/lib/modules/${r}`:"src/lib/events";this.success(`Event created: ${l}/${s}.ts`)}};import{writeFileSync as ka,mkdirSync as $a,existsSync as Da}from"fs";import{join as Aa}from"path";var gt=class extends g{name="make:listener";description="Create a new event listener class";arguments=["name"];flags=[{name:"event",alias:"e",description:"The event class this listener handles",type:"string"},{name:"module",description:"Module name (e.g. auth, billing)",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a listener name (e.g. SendWelcomeEmail).");return}let r=t.module||s.replace(/([A-Z])/g," $1").trim().split(" ")[0].toLowerCase();!t.module&&this.isDDD()&&this.warn(`No --module specified. Using "${r}" as module. Consider: --module ${r}`);let i=this.moduleDir(r,"listeners");$a(i,{recursive:!0});let n=Aa(i,`${s}.ts`);if(Da(n)){this.warn(`Listener ${s} already exists at ${n}`);return}let a=t.event||"any",l=t.event?this.isDDD()?`./${t.event}.js`:`../events/${t.event}.js`:"",c=t.event?`import type { ${t.event} } from '${l}';
|
|
1340
1343
|
|
|
1341
|
-
`:"",
|
|
1342
|
-
${
|
|
1343
|
-
async handle(event: ${
|
|
1344
|
+
`:"",u=t.event||"any",m=`import { Listener } from '@beeblock/svelar/events';
|
|
1345
|
+
${c}export class ${s} extends Listener<${u}> {
|
|
1346
|
+
async handle(event: ${u}): Promise<void> {
|
|
1344
1347
|
// Handle the event
|
|
1345
1348
|
// e.g. await Mail.to(event.user.email).send(new WelcomeEmail());
|
|
1346
1349
|
}
|
|
1347
1350
|
|
|
1348
1351
|
// Optionally filter which events to handle:
|
|
1349
|
-
// shouldHandle(event: ${
|
|
1352
|
+
// shouldHandle(event: ${u}): boolean {
|
|
1350
1353
|
// return true;
|
|
1351
1354
|
// }
|
|
1352
1355
|
}
|
|
1353
|
-
`;
|
|
1356
|
+
`;ka(n,m);let h=this.isDDD()?`src/lib/modules/${r}`:"src/lib/listeners";this.success(`Listener created: ${h}/${s}.ts`),t.event&&(this.info("Don't forget to register it in your EventServiceProvider:"),this.info(` [${t.event}.name]: [${s}]`))}};import{writeFileSync as Ma,mkdirSync as La,existsSync as _a}from"fs";import{join as Fr}from"path";var ft=class extends g{name="make:route";description="Create route files with controller bindings";arguments=["path"];flags=[{name:"controller",alias:"c",description:"Controller class name",type:"string"},{name:"resource",alias:"r",description:"Generate full CRUD resource routes",type:"boolean"},{name:"api",description:"Prefix path with /api",type:"boolean"},{name:"methods",alias:"m",description:"HTTP methods (comma-separated: GET,POST,PUT,DELETE)",type:"string"},{name:"module",description:"Module name for controller import path",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a route path (e.g. posts, users/[id], admin/settings).");return}let r=s.replace(/^\//,"");t.api&&!r.startsWith("api/")&&(r="api/"+r);let i=t.controller||this.inferControllerName(r),n=t.module||this.inferModuleName(r);t.resource?this.generateResourceRoutes(r,i,n):this.generateRoute(r,i,n,t.methods)}generateResourceRoutes(e,t,s){this.generateRouteFile(e,t,s,[{method:"GET",handler:"index"},{method:"POST",handler:"store"}]);let r=this.inferParamName(e);this.generateRouteFile(`${e}/[${r}]`,t,s,[{method:"GET",handler:"show"},{method:"PUT",handler:"update"},{method:"DELETE",handler:"destroy"}])}generateRoute(e,t,s,r){let n=(r?r.split(",").map(a=>a.trim().toUpperCase()):["GET"]).map(a=>({method:a,handler:this.defaultHandler(a)}));this.generateRouteFile(e,t,s,n)}generateRouteFile(e,t,s,r){let i=Fr(process.cwd(),"src","routes",...e.split("/"));La(i,{recursive:!0});let n=Fr(i,"+server.ts");if(_a(n)){this.warn(`Route already exists: src/routes/${e}/+server.ts (skipped)`);return}let a=this.isDDD()?`$lib/modules/${s}/${t}.js`:`$lib/controllers/${t}.js`,l=r.map(u=>`export const ${u.method} = ctrl.handle('${u.handler}');`).join(`
|
|
1354
1357
|
`),c=`import { ${t} } from '${a}';
|
|
1355
1358
|
|
|
1356
1359
|
const ctrl = new ${t}();
|
|
1357
|
-
${
|
|
1358
|
-
`;
|
|
1359
|
-
`);let n=Math.max(6,...i.map(u=>u.method.length)),a=Math.max(4,...i.map(u=>u.path.length)),o=Math.max(7,...i.map(u=>u.handler.length)),c=` ${"METHOD".padEnd(n)} ${"PATH".padEnd(a)} ${"HANDLER".padEnd(o)} FILE`;this.log(`\x1B[2m${c}\x1B[0m`),this.log(`\x1B[2m ${"\u2500".repeat(n)} ${"\u2500".repeat(a)} ${"\u2500".repeat(o)} ${"\u2500".repeat(20)}\x1B[0m`);for(let u of i){let p=`${this.getMethodColor(u.method)}${u.method.padEnd(n)}\x1B[0m`,f=u.path.padEnd(a),b=`\x1B[2m${u.handler.padEnd(o)}\x1B[0m`,C=`\x1B[2m${u.file}\x1B[0m`;this.log(` ${p} ${f} ${b} ${C}`)}this.log("")}scanRoutes(e,t){let s=[],r=Ma(e);for(let i of r){let n=Zr(e,i);if(Na(n).isDirectory()){s.push(...this.scanRoutes(n,t));continue}i==="+server.ts"||i==="+server.js"?s.push(...this.parseServerFile(n,t)):(i==="+page.server.ts"||i==="+page.server.js")&&s.push(...this.parsePageServerFile(n,t))}return s}parseServerFile(e,t){let s=[],r=ei(e,"utf-8"),i=this.filePathToUrl(e,t),n=us(process.cwd(),e).split(ms).join("/"),a=/export\s+(?:const|function)\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\b/g,o;for(;(o=a.exec(r))!==null;){let c=o[1],u=this.extractHandler(r,c);s.push({method:c,path:i,handler:u,file:n})}return s}parsePageServerFile(e,t){let s=[],r=ei(e,"utf-8"),i=this.filePathToUrl(e,t),n=us(process.cwd(),e).split(ms).join("/");/export\s+(const|async\s+function)\s+load\b/.test(r)&&s.push({method:"GET",path:i,handler:"load()",file:n});let a=r.match(/export\s+const\s+actions\s*=\s*\{([^}]+)\}/);if(a){let o=a[1].split(",").map(c=>c.trim().split(":")[0].split("(")[0].trim()).filter(Boolean);for(let c of o)s.push({method:"POST",path:c==="default"?i:`${i}?/${c}`,handler:`actions.${c}()`,file:n})}return s}filePathToUrl(e,t){let s=us(t,e).split(ms).join("/");return s=s.replace(/\/?\+(?:server|page\.server)\.[tj]s$/,""),s=s.replace(/\[\.\.\.(\w+)\]/g,"*$1").replace(/\[\[(\w+)\]\]/g,":$1?").replace(/\[(\w+)\]/g,":$1"),s=s.replace(/\([^)]+\)\//g,""),"/"+s||"/"}extractHandler(e,t){let s=new RegExp(`export\\s+const\\s+${t}\\s*=\\s*(\\w+)\\.handle\\(['"]([^'"]+)['"]\\)`),r=e.match(s);if(r)return`${r[1]}.${r[2]}()`;let i=new RegExp(`const\\s*\\{[^}]*${t}[^}]*\\}\\s*=\\s*resource\\(\\s*(\\w+)`),n=e.match(i);return n?`${n[1]}.${{GET:"index/show",POST:"store",PUT:"update",PATCH:"update",DELETE:"destroy"}[t]??t.toLowerCase()}()`:new RegExp(`export\\s+(?:const|async\\s+function)\\s+${t}\\s*(?:=\\s*async)?`).test(e)?"inline handler":"handler"}getMethodColor(e){return{GET:"\x1B[32m",POST:"\x1B[33m",PUT:"\x1B[34m",PATCH:"\x1B[34m",DELETE:"\x1B[31m",HEAD:"\x1B[2m",OPTIONS:"\x1B[2m"}[e]||""}};import{readdirSync as _a}from"fs";import{join as ri}from"path";import{pathToFileURL as Ia}from"url";var gt=class extends h{name="migrate";description="Run pending database migrations";flags=[{name:"rollback",description:"Rollback the last batch of migrations",type:"boolean"},{name:"reset",description:"Reset all migrations",type:"boolean"},{name:"refresh",description:"Reset and re-run all migrations",type:"boolean"},{name:"fresh",description:"Drop all tables and re-run all migrations",type:"boolean"},{name:"status",description:"Show migration status",type:"boolean"},{name:"seed",description:"Run seeders after migrating",type:"boolean"},{name:"force",description:"Force destructive operations in production",type:"boolean"}];destructiveFlags=["reset","refresh","fresh"];async handle(e,t){await this.bootstrap();let s=this.destructiveFlags.find(c=>t[c]);s&&this.isProduction()&&!t.force&&(this.error(`The --${s} flag is destructive and cannot be run in production.`),this.error(`Use --force to run this command in production: npx svelar migrate --${s} --force`),process.exit(1));let{Migrator:r}=await Promise.resolve().then(()=>(gs(),si)),i=new r,n=ri(process.cwd(),"src","lib","database","migrations"),a=await this.loadMigrations(n);if(t.status){let c=await i.status(a);this.table(["Migration","Status","Batch"],c.map(u=>[u.name,u.ran?"\x1B[32mRan\x1B[0m":"\x1B[33mPending\x1B[0m",u.batch?.toString()??"-"]));return}if(t.rollback){this.info("Rolling back last batch...");let c=await i.rollback(a);if(c.length===0)this.info("Nothing to rollback.");else for(let u of c)this.success(`Rolled back: ${u}`);return}if(t.reset){this.warnDestructive("reset"),this.info("Resetting all migrations...");let c=await i.reset(a);if(c.length===0)this.info("Nothing to reset.");else for(let u of c)this.success(`Rolled back: ${u}`);return}if(t.refresh){this.warnDestructive("refresh"),this.info("Refreshing migrations...");let c=await i.refresh(a);for(let u of c.reset)this.success(`Rolled back: ${u}`);for(let u of c.migrated)this.success(`Migrated: ${u}`);return}if(t.fresh){this.warnDestructive("fresh"),this.info("Dropping all tables...");let c=await i.fresh(a);if(c.dropped.length>0)for(let u of c.dropped)this.success(`Dropped table: ${u}`);this.newLine(),this.info("Re-running all migrations...");for(let u of c.migrated)this.success(`Migrated: ${u}`);return}this.info("Running migrations...");let o=await i.run(a);if(o.length===0)this.info("Nothing to migrate.");else for(let c of o)this.success(`Migrated: ${c}`)}isProduction(){return(process.env.NODE_ENV||process.env.APP_ENV||"development")==="production"}warnDestructive(e){this.isProduction()&&this.warn(`Running --${e} in PRODUCTION with --force.`)}async loadMigrations(e){let t;try{t=_a(e).filter(r=>r.endsWith(".ts")||r.endsWith(".js")).sort()}catch{return this.warn(`Migrations directory not found: ${e}`),[]}let s=[];for(let r of t){let i=ri(e,r);try{let n=await import(Ia(i).href),a=n.default??Object.values(n).find(o=>typeof o=="function"&&o.prototype&&typeof o.prototype.up=="function");a?s.push({name:r.replace(/\.(ts|js)$/,""),timestamp:r.split("_")[0],path:i,migration:new a}):this.warn(`No migration class found in: ${r}`)}catch(n){let a;try{a=n instanceof Error?n.message:String(n)}catch{a=JSON.stringify(n)??"Unknown error (non-stringifiable object)"}this.error(`Failed to load migration ${r}: ${a}`)}}return s}};import{join as fs}from"path";import{pathToFileURL as ja}from"url";import{existsSync as ii}from"fs";var ft=class extends h{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=fs(process.cwd(),"src","lib","database","seeders"),r=t.class?fs(s,`${t.class}.ts`):fs(s,"DatabaseSeeder.ts"),i=r;ii(i)||(i=i.replace(/\.ts$/,".js")),ii(i)||(this.error(`Seeder not found: ${r}`),process.exit(1)),this.info("Running seeders...");try{let n=await import(ja(i).href),a=n.default??n.DatabaseSeeder??Object.values(n).find(c=>typeof c=="function"&&c.prototype&&typeof c.prototype.run=="function");(!a||typeof a!="function")&&(this.error("No seeder class found in file."),process.exit(1)),await new a().run(),this.success("Database seeded successfully.")}catch(n){let a=n instanceof Error?n.message:String(n);this.error(`Seeding failed: ${a}`),n?.stack&&console.error(n.stack),process.exit(1)}}};import{readdirSync as Ua}from"fs";import{join as ci}from"path";import{pathToFileURL as Ba}from"url";var bt=class extends h{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(()=>(li(),oi)),r=new s;r.persistToDatabase();let i=ci(process.cwd(),"src","lib","scheduler"),n=await this.loadTasks(i);if(n.length===0){this.warn("No scheduled tasks found in src/lib/scheduler/");return}for(let c of n)r.register(c),this.info(`Registered task: ${c.name}`);if(this.newLine(),t.once){this.info("Running due tasks (once)...");let c=await r.run();if(c.length===0)this.info("No tasks were due.");else for(let u of c)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 a=async()=>{let c=await r.run();for(let u of c){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 a();let o=6e4-Date.now()%6e4;this.info(`Next tick aligned to minute boundary in ${Math.round(o/1e3)}s.`),await new Promise(c=>setTimeout(c,o)),await a(),setInterval(a,6e4),await new Promise(()=>{})}async loadTasks(e){let t;try{t=Ua(e).filter(r=>(r.endsWith(".ts")||r.endsWith(".js"))&&!r.startsWith("index")).sort()}catch{return[]}let s=[];for(let r of t){let i=ci(e,r);try{let n=await import(Ba(i).href),a=n.default??Object.values(n).find(o=>typeof o=="function"&&o.prototype&&typeof o.prototype.handle=="function");if(a){let o=new a;o.schedule(),s.push(o)}}catch(n){this.error(`Failed to load task ${r}: ${n.message??n}`)}}return s}};var Ct=class extends h{name="queue:work";description="Process queued jobs";flags=[{name:"queue",description:'Queue name to process (default: "default")',type:"string",default:"default"},{name:"max-jobs",description:"Stop after processing N jobs",type:"string"},{name:"max-time",description:"Stop after N seconds",type:"string"},{name:"sleep",description:"Sleep N milliseconds between polls (default: 1000)",type:"string",default:"1000"},{name:"once",description:"Process a single job and exit",type:"boolean"}];async handle(e,t){await this.bootstrap();let{Queue:s}=await Promise.resolve().then(()=>(Q(),Ee)),r=t.queue??"default",i=t["max-jobs"]?parseInt(t["max-jobs"]):void 0,n=t["max-time"]?parseInt(t["max-time"]):void 0,a=t.sleep?parseInt(t.sleep):1e3;if(this.info(`Processing queue "${r}"...`),i&&this.info(`Will stop after ${i} jobs.`),n&&this.info(`Will stop after ${n} seconds.`),this.newLine(),t.once){let u=await s.work({queue:r,maxJobs:1,sleep:0});u===0?this.info("No jobs to process."):this.success(`Processed ${u} job(s).`);return}this.info(`Worker running on "${r}". Press Ctrl+C to stop.`),this.newLine();let o=Date.now(),c=0;for(;;){if(n&&(Date.now()-o)/1e3>=n){this.info(`Max time (${n}s) reached. Stopping.`);break}if(i&&c>=i){this.info(`Max jobs (${i}) reached. Stopping.`);break}let u=await s.work({queue:r,maxJobs:1,sleep:0});if(u>0){c+=u;let d=new Date().toISOString().replace("T"," ").slice(0,19);this.success(`[${d}] Processed ${u} job(s) (total: ${c})`)}else await new Promise(d=>setTimeout(d,a))}this.newLine(),this.info(`Worker stopped. Total jobs processed: ${c}`)}};var Pt=class extends h{name="queue:failed";description="List all failed jobs";async handle(e,t){await this.bootstrap();let{Queue:s}=await Promise.resolve().then(()=>(Q(),Ee)),r=await s.failed();if(r.length===0){this.info("No failed jobs.");return}this.info(`Found ${r.length} failed job(s):
|
|
1360
|
+
${l}
|
|
1361
|
+
`;Ma(n,c),this.success(`Route created: src/routes/${e}/+server.ts`);for(let u of r)this.info(` ${u.method} /${e} \u2192 ${t}.${u.handler}()`)}inferControllerName(e){let t=e.replace(/^api\//,"").split("/").filter(n=>!n.startsWith("[")),s=t[t.length-1]||t[0]||"Index",r=this.singularize(s);return`${r.charAt(0).toUpperCase()+r.slice(1)}Controller`}inferModuleName(e){return e.replace(/^api\//,"").split("/").filter(s=>!s.startsWith("["))[0]||"app"}inferParamName(e){return"id"}defaultHandler(e){return{GET:"index",POST:"store",PUT:"update",PATCH:"update",DELETE:"destroy"}[e]||e.toLowerCase()}singularize(e){return e.endsWith("ies")?e.slice(0,-3)+"y":e.endsWith("ses")||e.endsWith("xes")||e.endsWith("zes")||e.endsWith("ches")||e.endsWith("shes")?e.slice(0,-2):e.endsWith("s")&&!e.endsWith("ss")?e.slice(0,-1):e}};import{join as Hr,relative as gs,sep as fs}from"path";import{existsSync as Na,readdirSync as Ia,readFileSync as zr,statSync as ja}from"fs";var bt=class extends g{name="routes:list";description="List all registered routes";arguments=[];flags=[{name:"json",description:"Output as JSON",type:"boolean"},{name:"api",description:"Show only API routes",type:"boolean"},{name:"method",alias:"m",description:"Filter by HTTP method (GET, POST, etc.)",type:"string"}];async handle(e,t){let s=Hr(process.cwd(),"src","routes");if(!Na(s)){this.error("No src/routes/ directory found.");return}let i=this.scanRoutes(s,s);if(t.api&&(i=i.filter(u=>u.path.startsWith("/api"))),t.method){let u=t.method.toUpperCase();i=i.filter(m=>m.method===u)}if(i.sort((u,m)=>u.path.localeCompare(m.path)||u.method.localeCompare(m.method)),i.length===0){this.warn("No routes found.");return}if(t.json){this.log(JSON.stringify(i,null,2));return}this.log(""),this.log(` \x1B[1mApplication Routes\x1B[0m (${i.length} routes)
|
|
1362
|
+
`);let n=Math.max(6,...i.map(u=>u.method.length)),a=Math.max(4,...i.map(u=>u.path.length)),l=Math.max(7,...i.map(u=>u.handler.length)),c=` ${"METHOD".padEnd(n)} ${"PATH".padEnd(a)} ${"HANDLER".padEnd(l)} FILE`;this.log(`\x1B[2m${c}\x1B[0m`),this.log(`\x1B[2m ${"\u2500".repeat(n)} ${"\u2500".repeat(a)} ${"\u2500".repeat(l)} ${"\u2500".repeat(20)}\x1B[0m`);for(let u of i){let h=`${this.getMethodColor(u.method)}${u.method.padEnd(n)}\x1B[0m`,d=u.path.padEnd(a),b=`\x1B[2m${u.handler.padEnd(l)}\x1B[0m`,w=`\x1B[2m${u.file}\x1B[0m`;this.log(` ${h} ${d} ${b} ${w}`)}this.log("")}scanRoutes(e,t){let s=[],r=Ia(e);for(let i of r){let n=Hr(e,i);if(ja(n).isDirectory()){s.push(...this.scanRoutes(n,t));continue}i==="+server.ts"||i==="+server.js"?s.push(...this.parseServerFile(n,t)):(i==="+page.server.ts"||i==="+page.server.js")&&s.push(...this.parsePageServerFile(n,t))}return s}parseServerFile(e,t){let s=[],r=zr(e,"utf-8"),i=this.filePathToUrl(e,t),n=gs(process.cwd(),e).split(fs).join("/"),a=/export\s+(?:const|function)\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\b/g,l;for(;(l=a.exec(r))!==null;){let c=l[1],u=this.extractHandler(r,c);s.push({method:c,path:i,handler:u,file:n})}return s}parsePageServerFile(e,t){let s=[],r=zr(e,"utf-8"),i=this.filePathToUrl(e,t),n=gs(process.cwd(),e).split(fs).join("/");/export\s+(const|async\s+function)\s+load\b/.test(r)&&s.push({method:"GET",path:i,handler:"load()",file:n});let a=r.match(/export\s+const\s+actions\s*=\s*\{([^}]+)\}/);if(a){let l=a[1].split(",").map(c=>c.trim().split(":")[0].split("(")[0].trim()).filter(Boolean);for(let c of l)s.push({method:"POST",path:c==="default"?i:`${i}?/${c}`,handler:`actions.${c}()`,file:n})}return s}filePathToUrl(e,t){let s=gs(t,e).split(fs).join("/");return s=s.replace(/\/?\+(?:server|page\.server)\.[tj]s$/,""),s=s.replace(/\[\.\.\.(\w+)\]/g,"*$1").replace(/\[\[(\w+)\]\]/g,":$1?").replace(/\[(\w+)\]/g,":$1"),s=s.replace(/\([^)]+\)\//g,""),"/"+s||"/"}extractHandler(e,t){let s=new RegExp(`export\\s+const\\s+${t}\\s*=\\s*(\\w+)\\.handle\\(['"]([^'"]+)['"]\\)`),r=e.match(s);if(r)return`${r[1]}.${r[2]}()`;let i=new RegExp(`const\\s*\\{[^}]*${t}[^}]*\\}\\s*=\\s*resource\\(\\s*(\\w+)`),n=e.match(i);return n?`${n[1]}.${{GET:"index/show",POST:"store",PUT:"update",PATCH:"update",DELETE:"destroy"}[t]??t.toLowerCase()}()`:new RegExp(`export\\s+(?:const|async\\s+function)\\s+${t}\\s*(?:=\\s*async)?`).test(e)?"inline handler":"handler"}getMethodColor(e){return{GET:"\x1B[32m",POST:"\x1B[33m",PUT:"\x1B[34m",PATCH:"\x1B[34m",DELETE:"\x1B[31m",HEAD:"\x1B[2m",OPTIONS:"\x1B[2m"}[e]||""}};import{readdirSync as Oa}from"fs";import{join as Jr}from"path";import{pathToFileURL as qa}from"url";var yt=class extends g{name="migrate";description="Run pending database migrations";flags=[{name:"rollback",description:"Rollback the last batch of migrations",type:"boolean"},{name:"reset",description:"Reset all migrations",type:"boolean"},{name:"refresh",description:"Reset and re-run all migrations",type:"boolean"},{name:"fresh",description:"Drop all tables and re-run all migrations",type:"boolean"},{name:"status",description:"Show migration status",type:"boolean"},{name:"seed",description:"Run seeders after migrating",type:"boolean"},{name:"force",description:"Force destructive operations in production",type:"boolean"}];destructiveFlags=["reset","refresh","fresh"];async handle(e,t){await this.bootstrap();let s=this.destructiveFlags.find(c=>t[c]);s&&this.isProduction()&&!t.force&&(this.error(`The --${s} flag is destructive and cannot be run in production.`),this.error(`Use --force to run this command in production: npx svelar migrate --${s} --force`),process.exit(1));let{Migrator:r}=await Promise.resolve().then(()=>(vs(),Wr)),i=new r,n=Jr(process.cwd(),"src","lib","database","migrations"),a=await this.loadMigrations(n);if(t.status){let c=await i.status(a);this.table(["Migration","Status","Batch"],c.map(u=>[u.name,u.ran?"\x1B[32mRan\x1B[0m":"\x1B[33mPending\x1B[0m",u.batch?.toString()??"-"]));return}if(t.rollback){this.info("Rolling back last batch...");let c=await i.rollback(a);if(c.length===0)this.info("Nothing to rollback.");else for(let u of c)this.success(`Rolled back: ${u}`);return}if(t.reset){this.warnDestructive("reset"),this.info("Resetting all migrations...");let c=await i.reset(a);if(c.length===0)this.info("Nothing to reset.");else for(let u of c)this.success(`Rolled back: ${u}`);return}if(t.refresh){this.warnDestructive("refresh"),this.info("Refreshing migrations...");let c=await i.refresh(a);for(let u of c.reset)this.success(`Rolled back: ${u}`);for(let u of c.migrated)this.success(`Migrated: ${u}`);return}if(t.fresh){this.warnDestructive("fresh"),this.info("Dropping all tables...");let c=await i.fresh(a);if(c.dropped.length>0)for(let u of c.dropped)this.success(`Dropped table: ${u}`);this.newLine(),this.info("Re-running all migrations...");for(let u of c.migrated)this.success(`Migrated: ${u}`);return}this.info("Running migrations...");let l=await i.run(a);if(l.length===0)this.info("Nothing to migrate.");else for(let c of l)this.success(`Migrated: ${c}`)}isProduction(){return(process.env.NODE_ENV||process.env.APP_ENV||"development")==="production"}warnDestructive(e){this.isProduction()&&this.warn(`Running --${e} in PRODUCTION with --force.`)}async loadMigrations(e){let t;try{t=Oa(e).filter(r=>r.endsWith(".ts")||r.endsWith(".js")).sort()}catch{return this.warn(`Migrations directory not found: ${e}`),[]}let s=[];for(let r of t){let i=Jr(e,r);try{let n=await import(qa(i).href),a=n.default??Object.values(n).find(l=>typeof l=="function"&&l.prototype&&typeof l.prototype.up=="function");a?s.push({name:r.replace(/\.(ts|js)$/,""),timestamp:r.split("_")[0],path:i,migration:new a}):this.warn(`No migration class found in: ${r}`)}catch(n){let a;try{a=n instanceof Error?n.message:String(n)}catch{a=JSON.stringify(n)??"Unknown error (non-stringifiable object)"}this.error(`Failed to load migration ${r}: ${a}`)}}return s}};import{join as ws}from"path";import{pathToFileURL as Ua}from"url";import{existsSync as Vr}from"fs";var vt=class extends g{name="seed:run";description="Run database seeders";flags=[{name:"class",description:"Specific seeder class to run",type:"string"}];async handle(e,t){await this.bootstrap();let s=ws(process.cwd(),"src","lib","database","seeders"),r=t.class?ws(s,`${t.class}.ts`):ws(s,"DatabaseSeeder.ts"),i=r;Vr(i)||(i=i.replace(/\.ts$/,".js")),Vr(i)||(this.error(`Seeder not found: ${r}`),process.exit(1)),this.info("Running seeders...");try{let n=await import(Ua(i).href),a=n.default??n.DatabaseSeeder??Object.values(n).find(c=>typeof c=="function"&&c.prototype&&typeof c.prototype.run=="function");(!a||typeof a!="function")&&(this.error("No seeder class found in file."),process.exit(1)),await new a().run(),this.success("Database seeded successfully.")}catch(n){let a=n instanceof Error?n.message:String(n);this.error(`Seeding failed: ${a}`),n?.stack&&console.error(n.stack),process.exit(1)}}};import{existsSync as za,readdirSync as Ka}from"fs";import{join as Ps}from"path";import{pathToFileURL as Wa}from"url";var xt=class extends g{name="schedule:run";description="Run the task scheduler";flags=[{name:"once",description:"Run due tasks once and exit",type:"boolean"}];async handle(e,t){await this.bootstrap();let{Scheduler:s}=await Promise.resolve().then(()=>(Zr(),Yr)),r=new s;r.persistToDatabase();let i=Ps(process.cwd(),"src","lib","shared","scheduler"),n=Ps(process.cwd(),"src","lib","scheduler"),a=za(i)?i:n,l=await this.loadTasks(a);if(l.length===0){this.warn("No scheduled tasks found in src/lib/shared/scheduler/ or src/lib/scheduler/");return}for(let m of l)r.register(m),this.info(`Registered task: ${m.name}`);if(this.newLine(),t.once){this.info("Running due tasks (once)...");let m=await r.run();if(m.length===0)this.info("No tasks were due.");else for(let h of m)h.success?this.success(`${h.task}: completed in ${h.duration}ms`):this.error(`${h.task}: failed \u2014 ${h.error}`);return}this.info("Scheduler running. Press Ctrl+C to stop."),this.newLine();let c=async()=>{let m=await r.run();for(let h of m){let d=new Date().toISOString().replace("T"," ").slice(0,19);h.success?this.success(`[${d}] ${h.task}: completed in ${h.duration}ms`):this.error(`[${d}] ${h.task}: failed \u2014 ${h.error}`)}};await c();let u=6e4-Date.now()%6e4;this.info(`Next tick aligned to minute boundary in ${Math.round(u/1e3)}s.`),await new Promise(m=>setTimeout(m,u)),await c(),setInterval(c,6e4),await new Promise(()=>{})}async loadTasks(e){let t;try{t=Ka(e).filter(r=>(r.endsWith(".ts")||r.endsWith(".js"))&&!r.startsWith("index")).sort()}catch{return[]}let s=[];for(let r of t){let i=Ps(e,r);try{let n=await import(Wa(i).href),a=n.default??Object.values(n).find(l=>typeof l=="function"&&l.prototype&&typeof l.prototype.handle=="function");if(a){let l=new a;l.schedule(),s.push(l)}}catch(n){this.error(`Failed to load task ${r}: ${n.message??n}`)}}return s}};var Rt=class extends g{name="queue:work";description="Process queued jobs";flags=[{name:"queue",description:'Queue name to process (default: "default")',type:"string",default:"default"},{name:"max-jobs",description:"Stop after processing N jobs",type:"string"},{name:"max-time",description:"Stop after N seconds",type:"string"},{name:"sleep",description:"Sleep N milliseconds between polls (default: 1000)",type:"string",default:"1000"},{name:"once",description:"Process a single job and exit",type:"boolean"}];async handle(e,t){await this.bootstrap();let{Queue:s}=await Promise.resolve().then(()=>(V(),Te)),r=t.queue??"default",i=t["max-jobs"]?parseInt(t["max-jobs"]):void 0,n=t["max-time"]?parseInt(t["max-time"]):void 0,a=t.sleep?parseInt(t.sleep):1e3;if(this.info(`Processing queue "${r}"...`),i&&this.info(`Will stop after ${i} jobs.`),n&&this.info(`Will stop after ${n} seconds.`),this.newLine(),t.once){let u=await s.work({queue:r,maxJobs:1,sleep:0});u===0?this.info("No jobs to process."):this.success(`Processed ${u} job(s).`);return}this.info(`Worker running on "${r}". Press Ctrl+C to stop.`),this.newLine();let l=Date.now(),c=0;for(;;){if(n&&(Date.now()-l)/1e3>=n){this.info(`Max time (${n}s) reached. Stopping.`);break}if(i&&c>=i){this.info(`Max jobs (${i}) reached. Stopping.`);break}let u=await s.work({queue:r,maxJobs:1,sleep:0});if(u>0){c+=u;let m=new Date().toISOString().replace("T"," ").slice(0,19);this.success(`[${m}] Processed ${u} job(s) (total: ${c})`)}else await new Promise(m=>setTimeout(m,a))}this.newLine(),this.info(`Worker stopped. Total jobs processed: ${c}`)}};var Tt=class extends g{name="queue:failed";description="List all failed jobs";async handle(e,t){await this.bootstrap();let{Queue:s}=await Promise.resolve().then(()=>(V(),Te)),r=await s.failed();if(r.length===0){this.info("No failed jobs.");return}this.info(`Found ${r.length} failed job(s):
|
|
1360
1363
|
`);for(let i of r){let n=new Date(i.failedAt*1e3).toISOString().replace("T"," ").slice(0,19);this.log(` ID: ${i.id}`),this.log(` Job: ${i.jobClass}`),this.log(` Queue: ${i.queue}`),this.log(` Date: ${n}`),this.log(` Error: ${i.exception.split(`
|
|
1361
|
-
`)[0]}`),this.log("")}}};var
|
|
1362
|
-
`);let t=(await import("repl")).start({prompt:"\x1B[36msvelar>\x1B[0m ",useGlobal:!0});try{let s=await Promise.resolve().then(()=>(
|
|
1364
|
+
`)[0]}`),this.log("")}}};var Et=class extends g{name="queue:retry";description="Retry a failed job (or all failed jobs)";arguments=["id"];flags=[{name:"all",description:"Retry all failed jobs",type:"boolean",default:!1}];async handle(e,t){await this.bootstrap();let{Queue:s}=await Promise.resolve().then(()=>(V(),Te));if(t.all){let n=await s.retryAll();n===0?this.info("No failed jobs to retry."):this.success(`Retried ${n} job(s).`);return}let r=e[0];r||(this.error("Please provide a failed job ID, or use --all to retry all."),process.exit(1)),await s.retry(r)?this.success(`Job ${r} has been pushed back onto the queue.`):this.error(`Failed job with ID "${r}" not found.`)}};var kt=class extends g{name="queue:flush";description="Delete all failed job records";async handle(e,t){await this.bootstrap();let{Queue:s}=await Promise.resolve().then(()=>(V(),Te)),r=await s.flushFailed();r===0?this.info("No failed jobs to flush."):this.success(`Flushed ${r} failed job record(s).`)}};var ts=class extends g{name="tinker";description="Start an interactive REPL with Svelar preloaded";flags=[];async handle(){await this.bootstrap(),this.info("Starting Svelar Tinker..."),this.log(`Type .exit to quit. All Svelar modules are available.
|
|
1365
|
+
`);let t=(await import("repl")).start({prompt:"\x1B[36msvelar>\x1B[0m ",useGlobal:!0});try{let s=await Promise.resolve().then(()=>(Qi(),Vi));for(let[r,i]of Object.entries(s))t.context[r]=i;t.context.DB=s.Connection,t.context.Schema=s.Schema,this.log("Available: Model, QueryBuilder, Connection, Schema, Hash, Cache, Event, Log, ..."),this.log("")}catch(s){this.warn(`Could not preload all modules: ${s.message}`)}try{let{readdirSync:s}=await import("fs"),{join:r}=await import("path"),{pathToFileURL:i}=await import("url"),{existsSync:n}=await import("fs"),a=r(process.cwd(),"src","lib","models"),l=r(process.cwd(),"src","lib","modules"),c=[],u=a;if(n(a))u=a,c=s(a).filter(m=>(m.endsWith(".ts")||m.endsWith(".js"))&&!m.startsWith("index"));else if(n(l)){u=l;for(let m of s(l,{withFileTypes:!0})){if(!m.isDirectory())continue;let h=r(l,m.name);for(let d of s(h))(d.endsWith(".ts")||d.endsWith(".js"))&&(d.startsWith("index")||d.includes("Controller")||d.includes("Service")||d.includes("Repository")||d.includes("Request")||d.includes("Resource")||d.includes("schema")||d.includes("gates")||c.push(r(m.name,d)))}}for(let m of c)try{let h=await import(i(r(u,m)).href);for(let[d,b]of Object.entries(h))typeof b=="function"&&(t.context[d]=b)}catch{}c.length>0&&this.log(`Loaded models: ${c.map(m=>m.replace(/\.(ts|js)$/,"")).join(", ")}`)}catch{}await new Promise(s=>{t.on("exit",s)})}};var p=class{static packageJson(e,t="0.4.0"){return JSON.stringify({name:e,version:"0.0.1",private:!0,type:"module",scripts:{dev:"vite dev",build:"vite build",preview:"vite preview",migrate:"npx svelar migrate","migrate:rollback":"npx svelar migrate --rollback","migrate:refresh":"npx svelar migrate --refresh",seed:"npx svelar seed:run"},devDependencies:{"@sveltejs/adapter-auto":"^3.0.0","@sveltejs/kit":"^2.55.0","@sveltejs/vite-plugin-svelte":"^5.0.0","@tailwindcss/vite":"^4.2.2","lucide-svelte":"^0.468.0",svelte:"^5.0.0","svelte-check":"^4.0.0",tailwindcss:"^4.2.2",typescript:"^5.7.0",vite:"^6.0.0"},dependencies:{"better-sqlite3":"^11.0.0","drizzle-orm":"^0.38.0","@beeblock/svelar":`^${t}`,exceljs:"^4.4.0",pdfkit:"^0.18.0","sveltekit-superforms":"^2.22.0",zod:"^3.23.0"}},null,2)+`
|
|
1363
1366
|
`}static svelteConfig(){return`import adapter from '@sveltejs/adapter-auto';
|
|
1364
1367
|
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
|
1365
1368
|
|
|
@@ -1435,6 +1438,7 @@ export default defineConfig({
|
|
|
1435
1438
|
'@beeblock/svelar/services': resolve(svelarRoot, 'dist/services/index.js'),
|
|
1436
1439
|
'@beeblock/svelar/session': resolve(svelarRoot, 'dist/session/index.js'),
|
|
1437
1440
|
'@beeblock/svelar/storage': resolve(svelarRoot, 'dist/storage/index.js'),
|
|
1441
|
+
'@beeblock/svelar/stripe': resolve(svelarRoot, 'dist/stripe/index.js'),
|
|
1438
1442
|
'@beeblock/svelar/support': resolve(svelarRoot, 'dist/support/index.js'),
|
|
1439
1443
|
'@beeblock/svelar/teams': resolve(svelarRoot, 'dist/teams/index.js'),
|
|
1440
1444
|
'@beeblock/svelar/uploads': resolve(svelarRoot, 'dist/uploads/index.js'),
|
|
@@ -1465,7 +1469,7 @@ export default defineConfig({
|
|
|
1465
1469
|
<html lang="en">
|
|
1466
1470
|
<head>
|
|
1467
1471
|
<meta charset="utf-8" />
|
|
1468
|
-
<link rel="icon" href="%sveltekit.assets%/favicon.
|
|
1472
|
+
<link rel="icon" href="%sveltekit.assets%/favicon.svg" type="image/svg+xml" />
|
|
1469
1473
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
1470
1474
|
%sveltekit.head%
|
|
1471
1475
|
</head>
|
|
@@ -1473,7 +1477,77 @@ export default defineConfig({
|
|
|
1473
1477
|
<div style="display: contents">%sveltekit.body%</div>
|
|
1474
1478
|
</body>
|
|
1475
1479
|
</html>
|
|
1476
|
-
`}static
|
|
1480
|
+
`}static faviconSvg(){return`<svg width="459" height="540" viewBox="0 0 459 540" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
1481
|
+
<path d="M458.11 4.54057L457.86 5.97056C457.832 6.12139 457.772 6.2639 457.683 6.38823C457.595 6.51256 457.482 6.61574 457.35 6.69057C439.037 17.0172 418.88 24.5506 396.88 29.2906C385.494 31.7506 377.45 33.4239 372.75 34.3106C365.117 27.0639 359.18 21.9206 354.94 18.8806C353.98 18.1939 350.274 16.0072 343.82 12.3206C338.96 9.54057 334.68 8.33056 329.39 6.06056C327.504 5.25389 324.92 4.31723 321.64 3.25056C319.114 2.4239 316.5 1.56388 313.8 0.670546C316.34 0.210546 318.73 -0.0127699 320.97 0.00056342C371.304 0.213897 414.804 0.250549 451.47 0.110549C453.464 0.103882 455.454 0.127223 457.44 0.180556C457.585 0.185536 457.722 0.245097 457.824 0.347182C457.926 0.449268 457.985 0.58629 457.99 0.730574L458.11 4.54057Z" fill="#FDC509"/>
|
|
1482
|
+
<path d="M313.8 0.670478C316.5 1.56381 319.114 2.42383 321.64 3.25049C324.92 4.31716 327.504 5.25383 329.39 6.06049C334.68 8.33049 338.96 9.5405 343.82 12.3205C350.274 16.0072 353.98 18.1938 354.94 18.8805C359.18 21.9205 365.117 27.0638 372.75 34.3105C375.577 38.4505 378.604 42.4238 381.83 46.2305C383.057 47.6772 385.537 51.5605 389.27 57.8805L396.06 70.0305C396.13 70.1583 396.239 70.2603 396.373 70.3215C396.506 70.3827 396.656 70.3999 396.8 70.3705C419.49 66.0905 437.64 59.9005 457.92 53.4905L457.96 75.2105C443.294 83.5838 428.11 90.7371 412.41 96.6705C409.424 94.7438 406.304 92.9505 403.05 91.2905C390.21 84.7305 377.88 77.4205 364.48 71.9505C353.92 67.2305 343.067 63.2405 331.92 59.9805C321.187 56.8338 313.174 54.6038 307.88 53.2905C306.767 53.0172 305.637 52.8372 304.49 52.7505C304.349 52.7391 304.208 52.7713 304.085 52.8427C303.962 52.9141 303.863 53.0214 303.8 53.1505L301.91 57.0805C302.157 55.1338 302.094 53.2505 301.72 51.4305C301.681 51.2523 301.606 51.0824 301.5 50.9305L301.17 50.4305L301.45 0.900489C301.452 0.832197 301.466 0.764839 301.494 0.702246C301.521 0.639654 301.561 0.583042 301.61 0.535681C301.659 0.488321 301.717 0.451129 301.781 0.426215C301.844 0.4013 301.912 0.389153 301.98 0.390479L313.8 0.670478Z" fill="#FD8005"/>
|
|
1483
|
+
<path d="M457.98 36.2305C435.55 45.7705 412.84 52.1705 389.27 57.8805C385.537 51.5605 383.057 47.6772 381.83 46.2305C378.604 42.4239 375.577 38.4505 372.75 34.3105C377.45 33.4238 385.494 31.7505 396.88 29.2905C418.88 24.5505 439.037 17.0172 457.35 6.69052C457.482 6.61569 457.596 6.51252 457.684 6.38818C457.772 6.26385 457.832 6.12134 457.86 5.97052L458.11 4.54053L457.98 36.2305Z" fill="#FCB10A"/>
|
|
1484
|
+
<path d="M457.98 36.2307L457.92 53.4907C437.64 59.9007 419.49 66.0907 396.8 70.3707C396.655 70.4001 396.505 70.3829 396.372 70.3217C396.239 70.2605 396.13 70.1585 396.06 70.0307L389.27 57.8807C412.84 52.1707 435.55 45.7707 457.98 36.2307Z" fill="#FB9708"/>
|
|
1485
|
+
<path d="M245.16 50.0405C244.92 57.0405 244.487 62.6005 243.86 66.7205C239.75 93.7505 224.43 100.88 198.77 98.8304L198.6 93.4504C198.595 93.309 198.535 93.1753 198.434 93.0781C198.333 92.9808 198.199 92.9278 198.06 92.9305L143.01 93.2104L142.48 92.8304L142.57 50.4504C142.57 50.3178 142.623 50.1907 142.716 50.0969C142.81 50.0031 142.937 49.9504 143.07 49.9504L245.16 50.0405Z" fill="#F43702"/>
|
|
1486
|
+
<path d="M285.14 50.2205C285.06 58.0205 285 65.8505 284.96 73.7105C284.87 89.1905 279.31 100.911 269.83 113.151L198.53 113.241L198.71 106.231L198.77 98.8305C224.43 100.881 239.75 93.7505 243.86 66.7205C244.487 62.6005 244.92 57.0405 245.16 50.0405L285.14 50.2205Z" fill="#D50E09"/>
|
|
1487
|
+
<path d="M301.17 50.4305L301.5 50.9305C301.606 51.0824 301.68 51.2522 301.72 51.4305C302.093 53.2505 302.157 55.1338 301.91 57.0804L301.65 113.18L269.83 113.15C279.31 100.91 284.87 89.1904 284.96 73.7104C285 65.8504 285.06 58.0205 285.14 50.2205L301.17 50.4305Z" fill="#B40C08"/>
|
|
1488
|
+
<path d="M364.48 71.9505C361.574 79.2638 358.63 86.5605 355.65 93.8405C352.85 100.651 349.58 107.721 345.81 113.221C339.24 122.761 332.19 130.931 325.76 139.971C325.732 140.01 325.716 140.056 325.713 140.105C325.71 140.153 325.721 140.201 325.744 140.244C325.766 140.286 325.801 140.322 325.843 140.346C325.884 140.37 325.932 140.382 325.98 140.381L345.5 140.481H302.13C301.998 140.481 301.871 140.427 301.777 140.331C301.683 140.236 301.63 140.106 301.63 139.971L301.65 113.181L301.91 57.0805L303.8 53.1505C303.863 53.0214 303.962 52.9141 304.085 52.8427C304.208 52.7713 304.349 52.7392 304.49 52.7505C305.637 52.8372 306.767 53.0172 307.88 53.2905C313.174 54.6039 321.187 56.8339 331.92 59.9805C343.067 63.2405 353.92 67.2305 364.48 71.9505Z" fill="#FD5303"/>
|
|
1489
|
+
<path d="M364.48 71.9504C377.88 77.4204 390.21 84.7305 403.05 91.2905C406.303 92.9505 409.423 94.7438 412.41 96.6704L427.03 106.28C416.937 116.06 408.863 127.244 402.81 139.83C402.787 139.879 402.776 139.932 402.778 139.986C402.781 140.039 402.797 140.091 402.824 140.137C402.852 140.183 402.891 140.221 402.938 140.248C402.984 140.274 403.036 140.289 403.09 140.29L411.43 140.49L345.5 140.48L325.98 140.38C325.932 140.382 325.884 140.37 325.842 140.346C325.8 140.321 325.766 140.286 325.743 140.243C325.72 140.201 325.71 140.153 325.713 140.105C325.716 140.056 325.732 140.01 325.76 139.97C332.19 130.93 339.24 122.76 345.81 113.22C349.58 107.72 352.85 100.65 355.65 93.8405C358.63 86.5605 361.573 79.2638 364.48 71.9504Z" fill="#F43702"/>
|
|
1490
|
+
<path d="M457.96 75.2107L457.89 106.061L439.69 116.351L427.03 106.281L412.41 96.6707C428.11 90.7374 443.293 83.584 457.96 75.2107Z" fill="#FD5303"/>
|
|
1491
|
+
<path d="M101.18 92.8306C109.79 103.171 119.01 112.481 131.45 118.091C137.69 120.904 145.07 122.914 153.59 124.121C168.63 126.247 183.49 125.277 198.17 121.211L197.98 150.451C180.494 157.277 162.604 158.677 144.31 154.651C132.564 152.064 121.264 148.154 110.41 142.921C95.6302 135.787 83.3169 125.654 73.4702 112.521C66.1835 102.794 61.4269 96.2639 59.2002 92.9306L101.18 92.8306Z" fill="#FD8005"/>
|
|
1492
|
+
<path d="M142.48 92.8306L143.01 93.2106C160.71 100.861 179.36 103.951 198.71 106.231L198.53 113.241L198.17 121.211C183.49 125.277 168.63 126.247 153.59 124.121C145.07 122.914 137.69 120.904 131.45 118.091C119.01 112.481 109.79 103.171 101.18 92.8306H142.48Z" fill="#FB9708"/>
|
|
1493
|
+
<path d="M198.77 98.8305L198.71 106.231C179.36 103.951 160.71 100.861 143.01 93.2105L198.06 92.9305C198.199 92.9279 198.333 92.9809 198.434 93.0782C198.535 93.1754 198.595 93.3091 198.6 93.4505L198.77 98.8305Z" fill="#FCB10A"/>
|
|
1494
|
+
<path d="M59.2001 92.9307C61.4268 96.264 66.1834 102.794 73.4701 112.521C83.3168 125.654 95.6301 135.787 110.41 142.921C121.263 148.154 132.563 152.064 144.31 154.651C162.603 158.677 180.493 157.277 197.98 150.451L197.87 163.351C197.869 163.393 197.859 163.434 197.842 163.472C197.825 163.511 197.8 163.545 197.769 163.574C197.739 163.603 197.703 163.625 197.663 163.64C197.624 163.655 197.582 163.662 197.54 163.661C182.733 162.981 168.72 163.031 155.5 163.811C149.45 164.171 143.05 165.731 135.95 167.761C132.61 168.721 129.377 169.571 126.25 170.311L87.4301 171.461C76.4701 163.114 66.0734 154.387 56.2401 145.281C43.0501 133.081 33.0101 120.891 24.3501 106.021C27.6601 103.611 31.0401 100.991 34.4801 99.1907C42.2134 95.164 50.4534 93.0773 59.2001 92.9307Z" fill="#FD5303"/>
|
|
1495
|
+
<path d="M457.89 106.061L457.98 132.371L457.03 134.881C456.985 135 456.908 135.104 456.807 135.183C456.707 135.262 456.587 135.312 456.46 135.327C456.334 135.342 456.205 135.323 456.089 135.271C455.972 135.218 455.873 135.135 455.8 135.031C451.107 128.424 445.737 122.197 439.69 116.351L457.89 106.061Z" fill="#F43702"/>
|
|
1496
|
+
<path d="M427.03 106.281L439.69 116.351C445.737 122.197 451.107 128.424 455.8 135.031C455.873 135.135 455.973 135.218 456.089 135.271C456.205 135.323 456.334 135.342 456.46 135.327C456.587 135.312 456.707 135.262 456.807 135.183C456.908 135.104 456.985 135 457.03 134.881L457.98 132.371L458.01 139.821C458.01 139.958 457.956 140.091 457.861 140.188C457.765 140.286 457.635 140.341 457.5 140.341L411.43 140.491L403.09 140.291C403.037 140.289 402.984 140.274 402.938 140.248C402.891 140.221 402.852 140.183 402.825 140.137C402.797 140.091 402.781 140.039 402.778 139.986C402.776 139.932 402.787 139.879 402.81 139.831C408.863 127.244 416.937 116.061 427.03 106.281Z" fill="#D50E09"/>
|
|
1497
|
+
<path d="M24.3502 106.021C33.0102 120.891 43.0502 133.081 56.2402 145.281C66.0735 154.387 76.4702 163.114 87.4302 171.461C77.8235 171.234 68.3669 170.331 59.0602 168.751C48.6302 166.991 39.2702 163.921 30.5902 159.701C23.3369 156.167 17.2169 150.381 12.2302 142.341C11.7502 141.561 11.2302 141.291 10.7602 140.801C10.6466 140.684 10.5586 140.543 10.5018 140.388C10.445 140.233 10.4206 140.067 10.4302 139.901C10.5369 138.074 10.2169 136.477 9.47021 135.111C10.2502 128.497 12.3136 122.384 15.6602 116.771C16.8736 114.731 19.7702 111.147 24.3502 106.021Z" fill="#F43702"/>
|
|
1498
|
+
<path d="M87.4302 171.461L126.25 170.311L116.23 175.061C116.024 175.014 115.79 175.041 115.53 175.141C111.924 176.514 107.84 178.194 103.28 180.181C101.614 180.901 97.5336 182.587 91.0403 185.241C85.1469 187.647 79.2969 190.444 73.4902 193.631L59.6302 202.291C46.6202 199.851 34.5802 196.481 23.8002 188.841C19.0136 185.454 14.1602 180.351 9.24023 173.531L9.47025 135.111C10.2169 136.477 10.5369 138.074 10.4302 139.901C10.4207 140.067 10.4451 140.234 10.5019 140.388C10.5587 140.543 10.6467 140.684 10.7603 140.801C11.2303 141.291 11.7503 141.561 12.2303 142.341C17.2169 150.381 23.3369 156.167 30.5902 159.701C39.2702 163.921 48.6302 166.991 59.0602 168.751C68.3669 170.331 77.8236 171.234 87.4302 171.461Z" fill="#D50E09"/>
|
|
1499
|
+
<path d="M59.6302 202.291C56.3902 204.857 54.4302 206.551 53.7502 207.371C47.9702 214.404 45.0069 222.55 44.8602 231.81C44.3269 242.817 46.4735 253.171 51.3002 262.871C53.0002 266.281 55.6102 269.08 57.9502 272.25C54.2636 272.244 50.5835 272.271 46.9102 272.331C44.1602 272.381 41.7102 271.36 39.0502 271.82C38.4829 271.919 37.9013 271.903 37.3402 271.771C33.1402 270.801 29.2902 270.131 25.8902 268.621C14.2102 263.447 8.56356 254.271 8.95023 241.091C9.04356 237.831 9.09021 236.157 9.09021 236.07C9.10354 215.304 9.15354 194.457 9.2402 173.531C14.1602 180.351 19.0135 185.454 23.8002 188.841C34.5802 196.481 46.6202 199.851 59.6302 202.291Z" fill="#B40C08"/>
|
|
1500
|
+
<path d="M116.23 175.061L115.53 183.811C115.519 183.956 115.538 184.103 115.586 184.241C115.634 184.379 115.709 184.506 115.808 184.613C115.907 184.72 116.026 184.805 116.159 184.863C116.292 184.921 116.435 184.951 116.58 184.951H165.55C165.746 184.951 165.935 185.029 166.074 185.167C166.212 185.306 166.29 185.494 166.29 185.691L166.16 210.281L165.8 213.171C165.793 213.229 165.773 213.285 165.741 213.334C165.71 213.384 165.667 213.425 165.617 213.456C165.567 213.487 165.511 213.506 165.453 213.512C165.394 213.518 165.335 213.511 165.28 213.491C155.98 210.277 146.384 206.774 136.49 202.981C124.35 198.321 113.16 195.421 101.01 195.021C94.3836 194.801 86.6902 194.947 77.9302 195.461C75.9302 195.041 74.4502 194.431 73.4902 193.631C79.2969 190.444 85.1469 187.647 91.0403 185.241C97.5336 182.587 101.614 180.901 103.28 180.181C107.84 178.194 111.924 176.514 115.53 175.141C115.79 175.041 116.024 175.014 116.23 175.061Z" fill="#FDC509"/>
|
|
1501
|
+
<path d="M166.16 210.281L166.47 230.241C165.83 234.054 165.697 237.537 166.07 240.691L165.34 243.031C164.927 243.151 164.34 242.864 163.58 242.171C163.408 242.011 163.216 241.877 163.01 241.771C155.49 237.941 149.23 233.451 141.81 229.171C133.07 224.137 118.614 215.701 98.4402 203.861C93.5002 200.961 86.6635 198.161 77.9302 195.461C86.6902 194.947 94.3835 194.801 101.01 195.021C113.16 195.421 124.35 198.321 136.49 202.981C146.384 206.774 155.98 210.277 165.28 213.491C165.335 213.511 165.394 213.518 165.453 213.512C165.511 213.506 165.567 213.487 165.617 213.456C165.667 213.425 165.71 213.384 165.741 213.334C165.773 213.285 165.793 213.229 165.8 213.171L166.16 210.281Z" fill="#FCB10A"/>
|
|
1502
|
+
<path d="M73.4903 193.631C74.4503 194.431 75.9303 195.041 77.9303 195.461C86.6637 198.161 93.5003 200.961 98.4403 203.861C118.614 215.701 133.07 224.137 141.81 229.171C149.23 233.451 155.49 237.941 163.01 241.771C163.216 241.877 163.408 242.011 163.58 242.171C164.34 242.864 164.927 243.151 165.34 243.031C165.694 251.404 165.71 259.897 165.39 268.511C165.384 268.564 165.44 269.107 165.56 270.141C165.627 270.794 165.514 271.534 165.22 272.361L142.01 272.251L144.1 272.071C144.137 272.069 144.173 272.055 144.201 272.031C144.229 272.006 144.247 271.973 144.253 271.936C144.259 271.9 144.252 271.862 144.233 271.83C144.214 271.798 144.185 271.773 144.15 271.761C106.3 255.641 78.1004 244.851 44.8604 231.811C45.007 222.551 47.9703 214.404 53.7503 207.371C54.4303 206.551 56.3903 204.857 59.6303 202.291L73.4903 193.631Z" fill="#E15E05"/>
|
|
1503
|
+
<path d="M238.59 230.27C220.64 240.02 200.94 245.97 180.9 249.64L166.07 240.69C165.697 237.537 165.83 234.054 166.47 230.24L238.59 230.27Z" fill="#B9D84B"/>
|
|
1504
|
+
<path d="M302.41 239.291C272.18 249.001 238 255.081 204.72 263.431C202.7 262.477 201.327 261.737 200.6 261.211C197.527 258.951 194.22 257.091 190.68 255.631C188.954 254.917 185.694 252.921 180.9 249.641C200.94 245.971 220.64 240.021 238.59 230.271L301.86 230.231C301.997 230.231 302.127 230.284 302.225 230.379C302.322 230.475 302.378 230.605 302.38 230.741L302.41 239.291Z" fill="#9EC744"/>
|
|
1505
|
+
<path d="M44.8604 231.811C78.1004 244.851 106.3 255.641 144.15 271.761C144.185 271.773 144.214 271.798 144.233 271.83C144.252 271.862 144.259 271.9 144.253 271.936C144.247 271.973 144.229 272.006 144.201 272.031C144.173 272.055 144.137 272.069 144.1 272.071L142.01 272.251H57.9504C55.6104 269.081 53.0003 266.281 51.3003 262.871C46.4737 253.171 44.327 242.817 44.8604 231.811Z" fill="#C14704"/>
|
|
1506
|
+
<path d="M302.41 239.291L302.33 251.051L302.25 253.781C302.247 253.936 302.207 254.089 302.135 254.228C302.062 254.366 301.958 254.487 301.83 254.581C292.05 261.574 282.387 266.63 272.84 269.75C260.967 273.637 249.087 277.521 237.2 281.401L228.57 276.81L204.72 263.431C238 255.081 272.18 249.001 302.41 239.291Z" fill="#6FB33D"/>
|
|
1507
|
+
<path d="M180.9 249.641C185.694 252.921 188.954 254.917 190.68 255.631C194.22 257.091 197.527 258.951 200.6 261.211C201.327 261.737 202.7 262.477 204.72 263.431L228.57 276.811C226.057 277.431 223.957 277.617 222.27 277.371C205.924 274.964 189.507 273.217 173.02 272.131C170.607 271.971 168.18 272.087 165.74 272.481C165.567 272.441 165.394 272.401 165.22 272.361C165.514 271.534 165.627 270.794 165.56 270.141C165.44 269.107 165.384 268.564 165.39 268.511C165.71 259.897 165.694 251.404 165.34 243.031L166.07 240.691L180.9 249.641Z" fill="#3E8832"/>
|
|
1508
|
+
<path d="M302.66 278.091C302.48 278.151 302.344 278.164 302.25 278.13L285.72 278.351C285.587 278.353 285.46 278.408 285.366 278.503C285.273 278.599 285.22 278.727 285.22 278.861L285.1 293.051L284.92 288.971C284.918 288.926 284.903 288.883 284.876 288.847C284.849 288.812 284.812 288.785 284.77 288.771C284.728 288.757 284.682 288.756 284.639 288.769C284.597 288.781 284.558 288.806 284.53 288.841C281.124 292.854 277.267 296.434 272.96 299.581L268.9 297.491L251.87 288.951L237.2 281.401C249.087 277.521 260.967 273.637 272.84 269.75C282.387 266.63 292.05 261.574 301.83 254.581C301.958 254.487 302.062 254.366 302.135 254.228C302.207 254.089 302.247 253.936 302.25 253.781L302.33 251.051L302.66 278.091Z" fill="#51A746"/>
|
|
1509
|
+
<path d="M228.57 276.811L237.2 281.401L251.87 288.951C232.51 295.641 215.41 298.621 195.07 298.041C185.317 297.767 175.547 297.291 165.76 296.611L165.74 272.481C168.18 272.087 170.607 271.971 173.02 272.131C189.507 273.217 205.924 274.964 222.27 277.371C223.957 277.617 226.057 277.431 228.57 276.811Z" fill="#138B74"/>
|
|
1510
|
+
<path d="M302.25 278.131C302.544 291.404 303.787 304.594 305.98 317.701C298.66 314.654 291.737 310.877 285.21 306.371C285.097 306.017 285.044 305.657 285.05 305.291L285.1 293.051L285.22 278.861C285.22 278.727 285.273 278.599 285.366 278.503C285.46 278.408 285.587 278.353 285.72 278.351L302.25 278.131Z" fill="#B9D84B"/>
|
|
1511
|
+
<path d="M302.66 278.091C302.874 278.351 303.144 278.481 303.47 278.481C317.484 278.447 331.454 278.404 345.38 278.351C348.97 297.861 351.16 316.261 348.91 335.831L342.23 333.291L310.19 319.551L305.98 317.701C303.787 304.594 302.544 291.404 302.25 278.131C302.344 278.164 302.48 278.151 302.66 278.091Z" fill="#91D95B"/>
|
|
1512
|
+
<path d="M372.67 278.341C373.284 282.667 373.994 286.927 374.8 291.121C377.407 304.647 379.504 318.251 381.09 331.931C381.72 337.391 382.64 342.631 383.48 348.001L371.93 344.501L348.91 335.831C351.16 316.261 348.97 297.861 345.38 278.351L372.67 278.341Z" fill="#66C96E"/>
|
|
1513
|
+
<path d="M430.47 278.361L427.18 278.791C427.051 278.81 426.935 278.878 426.853 278.98C426.772 279.082 426.731 279.21 426.74 279.341C428.15 299.531 428.81 317.271 426.52 336.871C414.11 343.311 400.12 348.051 386.32 348.451L383.48 348.001C382.64 342.631 381.72 337.391 381.09 331.931C379.504 318.251 377.407 304.647 374.8 291.121C373.994 286.927 373.284 282.667 372.67 278.341L430.47 278.361Z" fill="#47B874"/>
|
|
1514
|
+
<path d="M430.47 278.361C441.23 279.521 449.1 284.811 454.08 294.231C455.233 296.417 456.033 298.797 456.48 301.371C456.947 304.037 457.137 306.544 457.05 308.891C455.017 310.737 453.367 313.231 452.1 316.371C445.513 325.524 436.987 332.357 426.52 336.871C428.81 317.271 428.15 299.531 426.74 279.341C426.731 279.21 426.771 279.082 426.853 278.98C426.934 278.878 427.051 278.81 427.18 278.791L430.47 278.361Z" fill="#24A37C"/>
|
|
1515
|
+
<path d="M285.1 293.051L285.05 305.291L277.95 302.321L272.96 299.581C277.267 296.434 281.124 292.854 284.53 288.841C284.559 288.806 284.597 288.781 284.64 288.769C284.682 288.756 284.728 288.757 284.77 288.771C284.812 288.785 284.85 288.812 284.876 288.848C284.903 288.883 284.919 288.926 284.92 288.971L285.1 293.051Z" fill="#0D6F68"/>
|
|
1516
|
+
<path d="M251.87 288.95L268.9 297.49C253.35 305.63 237.98 311.24 220.33 312.18C202.82 313.12 184.85 311.62 166.59 308.53C166.449 308.507 166.319 308.441 166.215 308.341C166.112 308.241 166.04 308.112 166.01 307.97L165.78 306.87L165.76 296.61C175.547 297.29 185.317 297.767 195.07 298.04C215.41 298.62 232.51 295.64 251.87 288.95Z" fill="#0D6F68"/>
|
|
1517
|
+
<path d="M272.96 299.58L277.95 302.32C268.63 306.787 261.46 309.924 256.44 311.73C227.42 322.17 196.72 323.04 166.65 316.01C166.518 315.98 166.396 315.916 166.295 315.825C166.194 315.734 166.116 315.619 166.07 315.49L165.78 314.62V306.87L166.01 307.97C166.04 308.112 166.112 308.241 166.215 308.341C166.319 308.441 166.449 308.507 166.59 308.53C184.85 311.62 202.82 313.12 220.33 312.18C237.98 311.24 253.35 305.63 268.9 297.49L272.96 299.58Z" fill="#0D6562"/>
|
|
1518
|
+
<path d="M277.95 302.321L285.05 305.291C285.044 305.657 285.097 306.017 285.21 306.371L285.27 307.241C269.14 315.921 252.85 323.121 234.8 326.681C220.014 329.601 203.45 330.587 185.11 329.641C179.944 329.374 173.514 328.444 165.82 326.851L165.78 314.621L166.07 315.491C166.116 315.619 166.194 315.734 166.295 315.825C166.396 315.916 166.518 315.98 166.65 316.011C196.72 323.041 227.42 322.171 256.44 311.731C261.46 309.924 268.63 306.787 277.95 302.321Z" fill="#085A66"/>
|
|
1519
|
+
<path d="M305.98 317.701L310.19 319.551C309.737 324.204 308.924 328.754 307.75 333.201C305.83 340.501 301.32 341.541 294.93 343.601C292.27 343.781 288.65 343.171 286.15 344.211L285.41 343.611L285.31 320.761L285.27 307.241L285.21 306.371C291.737 310.877 298.66 314.654 305.98 317.701Z" fill="#9EC744"/>
|
|
1520
|
+
<path d="M285.27 307.24L285.31 320.76C281.043 325.08 277.617 327.94 275.03 329.34C261.29 336.774 246.91 340.33 231.89 340.01C216.963 339.69 202.047 339.897 187.14 340.63C179.947 340.99 172.83 340.497 165.79 339.15L165.82 326.85C173.513 328.444 179.943 329.374 185.11 329.64C203.45 330.587 220.013 329.6 234.8 326.68C252.85 323.12 269.14 315.92 285.27 307.24Z" fill="#094A57"/>
|
|
1521
|
+
<path d="M457.05 308.891L457.08 315.981C454.687 326.534 451.457 335.394 447.39 342.561C442.57 351.047 435.72 360.154 426.84 369.881C412.08 386.061 393 397.051 370.56 395.381C370.494 395.375 370.428 395.383 370.365 395.404C370.302 395.425 370.244 395.458 370.195 395.502C370.145 395.546 370.105 395.6 370.077 395.66C370.049 395.72 370.033 395.784 370.03 395.851L369.86 401.381L369.74 395.891L369.79 388.331C383.264 382.377 392.687 377.934 398.06 375.001C421.5 362.221 440.09 340.221 452.1 316.371C453.367 313.231 455.017 310.737 457.05 308.891Z" fill="#085A66"/>
|
|
1522
|
+
<path d="M457.08 315.981L457.1 359.001C452.1 370.534 446.394 380.167 439.98 387.901C431.42 398.221 419.82 406.934 405.18 414.041C393.86 419.531 382.06 423.941 370.53 428.991C370.396 429.049 370.28 429.141 370.194 429.259C370.108 429.377 370.055 429.516 370.04 429.661L369.82 431.881L369.86 401.381L370.03 395.851C370.033 395.785 370.049 395.72 370.077 395.66C370.105 395.6 370.145 395.546 370.195 395.502C370.244 395.459 370.302 395.425 370.365 395.404C370.428 395.383 370.494 395.375 370.56 395.381C393 397.051 412.08 386.061 426.84 369.881C435.72 360.154 442.57 351.047 447.39 342.561C451.457 335.394 454.687 326.534 457.08 315.981Z" fill="#094A57"/>
|
|
1523
|
+
<path d="M452.1 316.371C440.09 340.221 421.5 362.221 398.06 375.001C392.687 377.934 383.263 382.377 369.79 388.331L369.93 367.821C375.957 365.554 381.573 362.491 386.78 358.631C388.84 357.101 391.75 353.811 389.66 351.181C388.66 349.927 387.547 349.017 386.32 348.451C400.12 348.051 414.11 343.311 426.52 336.871C436.987 332.357 445.513 325.524 452.1 316.371Z" fill="#0D6F68"/>
|
|
1524
|
+
<path d="M285.31 320.76L285.41 343.611L166.07 343.741C166.007 343.741 165.944 343.728 165.885 343.702C165.827 343.677 165.774 343.64 165.73 343.593C165.686 343.546 165.652 343.491 165.63 343.43C165.608 343.37 165.597 343.305 165.6 343.241L165.79 339.151C172.83 340.497 179.947 340.99 187.14 340.63C202.047 339.897 216.963 339.69 231.89 340.01C246.91 340.33 261.29 336.774 275.03 329.341C277.617 327.941 281.043 325.08 285.31 320.76Z" fill="#083747"/>
|
|
1525
|
+
<path d="M342.23 333.291C340 335.641 335.26 340.99 337 344.75L321.43 344.471L304.91 343.931L294.93 343.601C301.32 341.541 305.83 340.5 307.75 333.201C308.924 328.754 309.737 324.204 310.19 319.551L342.23 333.291Z" fill="#6FB33D"/>
|
|
1526
|
+
<path d="M342.23 333.291L348.91 335.831L371.93 344.5C370.41 346.647 369.684 349.344 369.75 352.591C369.917 350.444 369.777 348.624 369.33 347.13C369.191 346.662 368.907 346.251 368.519 345.954C368.131 345.658 367.659 345.492 367.17 345.481L347.72 345.06L337 344.75C335.26 340.99 340 335.641 342.23 333.291Z" fill="#3E8832"/>
|
|
1527
|
+
<path d="M294.93 343.601L304.91 343.931C302.457 350.071 299.12 357.417 294.9 365.971C289.174 377.584 281.674 387.301 272.4 395.121C277.16 389.174 280.854 383.334 283.48 377.601C285.42 373.361 286.01 368.651 286.05 363.471C286.104 357.051 286.137 350.631 286.15 344.211C288.65 343.171 292.27 343.781 294.93 343.601Z" fill="#B9D84B"/>
|
|
1528
|
+
<path d="M321.43 344.471C313.997 363.151 303.497 379.941 289.93 394.841C287.484 396.181 284.937 397.387 282.29 398.461C279.364 399.654 276.79 400.791 274.57 401.871C269.61 404.291 264.47 406.334 259.15 408.001L272.4 395.121C281.674 387.301 289.174 377.584 294.9 365.971C299.12 357.417 302.457 350.071 304.91 343.931L321.43 344.471Z" fill="#91D95B"/>
|
|
1529
|
+
<path d="M337 344.75L347.72 345.06L334 371.7L324.16 376.85L289.93 394.84C303.497 379.94 313.997 363.15 321.43 344.47L337 344.75Z" fill="#66C96E"/>
|
|
1530
|
+
<path d="M371.93 344.5L383.48 348L386.32 348.451C387.547 349.017 388.66 349.927 389.66 351.181C391.75 353.811 388.84 357.1 386.78 358.63C381.573 362.49 375.957 365.554 369.93 367.82L369.58 364.841L369.35 354.601L369.75 352.591C369.683 349.344 370.41 346.647 371.93 344.5Z" fill="#195239"/>
|
|
1531
|
+
<path d="M369.75 352.591L369.35 354.601L334 371.701L347.72 345.061L367.17 345.481C367.659 345.492 368.131 345.658 368.519 345.954C368.907 346.251 369.191 346.663 369.33 347.131C369.777 348.624 369.917 350.444 369.75 352.591Z" fill="#47B874"/>
|
|
1532
|
+
<path d="M369.35 354.601L369.58 364.841C359.094 374.247 348.404 383.401 337.51 392.301C318.67 407.681 300.67 422.741 287.46 443.421L240.63 443.391C263.26 429.261 279.93 415.741 302.14 397.141C308.934 391.447 316.274 384.684 324.16 376.851L334 371.701L369.35 354.601Z" fill="#209D93"/>
|
|
1533
|
+
<path d="M457.1 359V416.901C457.1 417.226 457.063 417.555 456.99 417.88C455.13 425.927 450.527 431.751 443.18 435.351C435.42 439.151 426.23 441.351 415.61 441.951C415.317 441.97 415.027 442.011 414.74 442.07C412.42 442.604 409.077 442.891 404.71 442.931C393.25 443.031 381.707 443.017 370.08 442.891L369.82 431.88L370.04 429.661C370.055 429.515 370.108 429.377 370.194 429.259C370.28 429.141 370.396 429.049 370.53 428.991C382.06 423.941 393.86 419.531 405.18 414.041C419.82 406.934 431.42 398.221 439.98 387.901C446.394 380.167 452.1 370.534 457.1 359Z" fill="#083747"/>
|
|
1534
|
+
<path d="M369.93 367.821L369.79 388.331L369.74 395.891C362.754 400.677 355.957 405.714 349.35 411.001C337.85 420.207 328.034 431.024 319.9 443.451L298.19 443.461L287.46 443.421C300.67 422.741 318.67 407.681 337.51 392.301C348.404 383.401 359.094 374.247 369.58 364.841L369.93 367.821Z" fill="#188495"/>
|
|
1535
|
+
<path d="M324.16 376.851C316.273 384.684 308.933 391.447 302.14 397.141C279.93 415.741 263.26 429.261 240.63 443.391L187.51 442.911C180.423 443.284 173.767 443.127 167.54 442.441L154.62 441.441C156.88 441.001 159.203 440.824 161.59 440.911C162.566 440.944 163.544 440.85 164.5 440.631C167.073 440.024 172.077 439.091 179.51 437.831C182.517 437.317 187.687 436.261 195.02 434.661C200.367 433.487 205.457 432.094 210.29 430.481C227.47 424.734 243.757 417.241 259.15 408.001C264.47 406.334 269.61 404.291 274.57 401.871C276.79 400.791 279.363 399.654 282.29 398.461C284.937 397.387 287.483 396.181 289.93 394.841L324.16 376.851Z" fill="#2FB991"/>
|
|
1536
|
+
<path d="M20.5104 391.171L25.8704 430.441C25.7838 430.347 25.6271 430.304 25.4004 430.311C18.4538 425.744 11.8504 420.674 5.59043 415.101L0.29044 403.041L0.0904283 391.721C0.0891266 391.655 0.101039 391.59 0.125462 391.529C0.149885 391.467 0.186333 391.412 0.232762 391.364C0.279192 391.317 0.334695 391.279 0.396062 391.253C0.457429 391.226 0.523466 391.212 0.590428 391.211L20.5104 391.171Z" fill="#6FB33D"/>
|
|
1537
|
+
<path d="M74.4302 391.171L76.5403 391.361C76.6938 391.376 76.8398 391.432 76.9617 391.524C77.0836 391.616 77.1766 391.74 77.2303 391.881C80.7103 401.091 83.6202 409.861 84.5302 419.481C84.7902 422.154 84.8236 426.561 84.6302 432.701C84.4502 438.467 84.3136 444.244 84.2202 450.031C71.6202 448.331 59.0802 444.701 47.1302 440.511C43.8102 439.351 40.2169 437.774 36.3503 435.781C32.8836 434.001 29.3902 432.221 25.8702 430.441L20.5103 391.171H74.4302Z" fill="#9EC744"/>
|
|
1538
|
+
<path d="M149.67 442.011L149.33 450.461C140.184 451.747 131.95 452.417 124.63 452.471C121.95 452.491 115.47 452.351 105.19 452.051C98.1569 451.891 91.1669 451.217 84.2202 450.031C84.3135 444.244 84.4502 438.467 84.6302 432.701C84.8235 426.561 84.7902 422.154 84.5302 419.481C83.6202 409.861 80.7102 401.091 77.2302 391.881C77.1765 391.74 77.0835 391.616 76.9616 391.524C76.8397 391.432 76.6938 391.376 76.5402 391.361L74.4302 391.171L149.56 391.181C149.605 391.181 149.649 391.199 149.68 391.23C149.712 391.262 149.73 391.306 149.73 391.351L149.67 442.011Z" fill="#B9D84B"/>
|
|
1539
|
+
<path d="M369.74 395.891L369.86 401.381L369.82 431.881L370.08 442.891L369.69 443.511L323.42 443.521L319.9 443.451C328.034 431.024 337.85 420.207 349.35 411.001C355.957 405.714 362.754 400.677 369.74 395.891Z" fill="#177492"/>
|
|
1540
|
+
<path d="M5.59 415.101C5.55 423.001 8.00666 430.054 12.96 436.26C16.3333 440.48 19.79 443.724 23.33 445.991C27.5433 448.684 33.2733 451.75 40.52 455.19C57.9867 462.264 76.0333 467.511 94.66 470.931C96.5467 471.277 98.3433 471.53 100.05 471.69C103.037 472.144 105.937 472.551 108.75 472.911C114.997 473.711 121.237 474.551 127.47 475.431C131.443 475.991 138.787 476.564 149.5 477.151L149.63 492.621L149.39 495.56C149.375 495.701 149.31 495.831 149.206 495.925C149.103 496.019 148.969 496.071 148.83 496.07C139.777 496.11 131.51 495.864 124.03 495.331C109.397 494.284 94.55 491.387 79.49 486.641C63.8 481.701 32.04 470.251 0 460.361L0.290009 403.041L5.59 415.101Z" fill="#0D6F68"/>
|
|
1541
|
+
<path d="M25.4003 430.311C30.3603 441.151 33.0803 447.691 40.5203 455.191C33.2737 451.751 27.5436 448.684 23.3303 445.991C19.7903 443.724 16.3337 440.481 12.9603 436.261C8.00699 430.054 5.55032 423.001 5.59032 415.101C11.8503 420.674 18.4537 425.744 25.4003 430.311Z" fill="#3E8832"/>
|
|
1542
|
+
<path d="M25.8704 430.44C29.3904 432.22 32.8837 434.001 36.3504 435.781C40.2171 437.774 43.8104 439.35 47.1304 440.51C59.0804 444.7 71.6204 448.331 84.2204 450.031C91.1671 451.217 98.1571 451.891 105.19 452.051C104.737 458.857 103.024 465.404 100.05 471.69C98.3437 471.53 96.5471 471.277 94.6604 470.931C76.0337 467.511 57.9871 462.264 40.5204 455.19C33.0804 447.69 30.3604 441.15 25.4004 430.31C25.6271 430.304 25.7837 430.347 25.8704 430.44Z" fill="#51A746"/>
|
|
1543
|
+
<path d="M154.62 441.441L167.54 442.441C177.66 451.221 188.667 458.281 200.56 463.621C233.093 478.207 265.06 476.837 296.46 459.511C307.28 453.537 316.267 448.207 323.42 443.521L369.69 443.511C369.717 450.857 369.717 458.064 369.69 465.131C369.663 470.631 369.233 474.557 368.4 476.911C364.79 487.061 355.34 493.051 344.99 495.841C341.423 496.801 336.823 497.584 331.19 498.191C327.55 498.584 322.893 498.784 317.22 498.791C246.393 498.924 196.977 498.977 168.97 498.951C161.323 498.944 154.94 499.034 149.82 499.221L149.63 492.621L149.5 477.151L149.33 450.461L149.67 442.011L154.62 441.441Z" fill="#083747"/>
|
|
1544
|
+
<path d="M187.51 442.911C217.33 458.331 248.91 466.001 280.06 448.931C285.333 446.037 288.407 444.351 289.28 443.871C289.55 443.726 289.848 443.647 290.15 443.641L298.19 443.461L319.9 443.451L323.42 443.521C316.267 448.207 307.28 453.537 296.46 459.511C265.06 476.837 233.093 478.207 200.56 463.621C188.667 458.281 177.66 451.221 167.54 442.441C173.767 443.127 180.423 443.284 187.51 442.911Z" fill="#094A57"/>
|
|
1545
|
+
<path d="M240.63 443.391L287.46 443.421L298.19 443.461L290.15 443.641C289.848 443.647 289.55 443.726 289.28 443.871C288.407 444.351 285.334 446.037 280.06 448.931C248.91 466.001 217.33 458.331 187.51 442.911L240.63 443.391Z" fill="#085A66"/>
|
|
1546
|
+
<path d="M149.33 450.461L149.5 477.151C138.787 476.564 131.444 475.991 127.47 475.431C121.237 474.551 114.997 473.711 108.75 472.911C105.937 472.551 103.037 472.144 100.05 471.691C103.024 465.404 104.737 458.857 105.19 452.051C115.47 452.351 121.95 452.491 124.63 452.471C131.95 452.417 140.184 451.747 149.33 450.461Z" fill="#47B874"/>
|
|
1547
|
+
<path d="M149.63 492.621L149.82 499.221L149.69 502.791C124.58 513.291 98.88 509.941 73.68 502.541C61.2333 498.887 48.9233 494.951 36.75 490.731C24.49 486.477 12.2433 482.097 0.0100098 477.591L0 460.361C32.04 470.251 63.8 481.701 79.49 486.641C94.55 491.387 109.397 494.284 124.03 495.331C131.51 495.864 139.777 496.111 148.83 496.071C148.969 496.071 149.103 496.019 149.206 495.925C149.31 495.831 149.375 495.701 149.39 495.561L149.63 492.621Z" fill="#0D6562"/>
|
|
1548
|
+
<path d="M149.69 502.791L149.72 510.591L148.37 522.611C148.356 522.743 148.298 522.867 148.206 522.963C148.114 523.059 147.992 523.121 147.86 523.141C124.52 526.731 101.33 528.021 78.1802 522.711C62.8802 519.204 46.2036 514.057 28.1502 507.271C19.3636 503.964 9.98359 499.657 0.0102539 494.351V477.591C12.2436 482.097 24.4902 486.477 36.7502 490.731C48.9236 494.951 61.2336 498.887 73.6802 502.541C98.8802 509.941 124.58 513.291 149.69 502.791Z" fill="#094A57"/>
|
|
1549
|
+
<path d="M149.72 510.591L149.83 538.721C149.83 538.851 149.78 538.975 149.69 539.067C149.6 539.159 149.478 539.211 149.35 539.211H0.270233C0.230451 539.211 0.192315 539.195 0.164185 539.167C0.136054 539.138 0.120239 539.1 0.120239 539.061L0.0102539 494.351C9.98359 499.657 19.3636 503.964 28.1502 507.271C46.2036 514.057 62.8802 519.204 78.1802 522.711C101.33 528.021 124.52 526.731 147.86 523.141C147.992 523.121 148.114 523.059 148.206 522.963C148.298 522.867 148.356 522.743 148.37 522.611L149.72 510.591Z" fill="#083747"/>
|
|
1550
|
+
</svg>`}static appCss(){return`@import "tailwindcss";
|
|
1477
1551
|
@source "../node_modules/@beeblock/svelar/src/ui";
|
|
1478
1552
|
|
|
1479
1553
|
@theme {
|
|
@@ -1504,9 +1578,9 @@ import { PDF } from '@beeblock/svelar/pdf';
|
|
|
1504
1578
|
import { configureDashboard } from '@beeblock/svelar/dashboard';
|
|
1505
1579
|
import { Broadcast } from '@beeblock/svelar/broadcasting';
|
|
1506
1580
|
import { Notifier } from '@beeblock/svelar/notifications';
|
|
1507
|
-
import { User } from './lib/
|
|
1581
|
+
import { User } from './lib/modules/auth/User.js';
|
|
1508
1582
|
import { EventServiceProvider } from './lib/shared/providers/EventServiceProvider.js';
|
|
1509
|
-
import './lib/auth/gates.js';
|
|
1583
|
+
import './lib/modules/auth/gates.js';
|
|
1510
1584
|
|
|
1511
1585
|
// \u2500\u2500 Database (SQLite) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1512
1586
|
Connection.configure({
|
|
@@ -1587,6 +1661,15 @@ Features.configure({ driver: 'database' });
|
|
|
1587
1661
|
// \u2500\u2500 PDF (PDFKit \u2014 no Docker needed) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1588
1662
|
PDF.configure({ driver: 'pdfkit' });
|
|
1589
1663
|
|
|
1664
|
+
// \u2500\u2500 Stripe (billing \u2014 uncomment and npm install stripe) \u2500\u2500
|
|
1665
|
+
// import { Stripe } from '@beeblock/svelar/stripe';
|
|
1666
|
+
// Stripe.configure({
|
|
1667
|
+
// secretKey: process.env.STRIPE_SECRET_KEY ?? '',
|
|
1668
|
+
// publishableKey: process.env.STRIPE_PUBLISHABLE_KEY ?? '',
|
|
1669
|
+
// webhookSecret: process.env.STRIPE_WEBHOOK_SECRET ?? '',
|
|
1670
|
+
// currency: 'usd',
|
|
1671
|
+
// });
|
|
1672
|
+
|
|
1590
1673
|
// \u2500\u2500 Dashboard \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1591
1674
|
configureDashboard({ enabled: true, prefix: '/admin' });
|
|
1592
1675
|
|
|
@@ -1688,6 +1771,11 @@ DB_PATH=database.db
|
|
|
1688
1771
|
# MEILISEARCH_HOST=http://localhost:7700
|
|
1689
1772
|
# MEILISEARCH_KEY=
|
|
1690
1773
|
|
|
1774
|
+
# Stripe (billing and subscriptions \u2014 npm install stripe)
|
|
1775
|
+
# STRIPE_SECRET_KEY=sk_test_...
|
|
1776
|
+
# STRIPE_PUBLISHABLE_KEY=pk_test_...
|
|
1777
|
+
# STRIPE_WEBHOOK_SECRET=whsec_...
|
|
1778
|
+
|
|
1691
1779
|
# PDF (default driver is pdfkit \u2014 no config needed)
|
|
1692
1780
|
# Switch to Gotenberg for pixel-perfect HTML rendering:
|
|
1693
1781
|
# PDF_DRIVER=gotenberg
|
|
@@ -1752,7 +1840,7 @@ export class User extends HasRoles(Model) {
|
|
|
1752
1840
|
// Enable audit logging for User model (tracks create/update/delete)
|
|
1753
1841
|
auditable(User);
|
|
1754
1842
|
|
|
1755
|
-
import { Post } from '
|
|
1843
|
+
import { Post } from '$lib/modules/posts/Post.js';
|
|
1756
1844
|
`}static postModel(){return`import { Model } from '@beeblock/svelar/orm';
|
|
1757
1845
|
import { auditable } from '@beeblock/svelar/audit';
|
|
1758
1846
|
|
|
@@ -1784,9 +1872,9 @@ export class Post extends Model {
|
|
|
1784
1872
|
// Enable audit logging for Post model (tracks create/update/delete)
|
|
1785
1873
|
auditable(Post);
|
|
1786
1874
|
|
|
1787
|
-
import { User } from '
|
|
1875
|
+
import { User } from '$lib/modules/auth/User.js';
|
|
1788
1876
|
`}static userRepository(){return`import { Repository } from '@beeblock/svelar/repositories';
|
|
1789
|
-
import { User } from '
|
|
1877
|
+
import { User } from './User.js';
|
|
1790
1878
|
|
|
1791
1879
|
export class UserRepository extends Repository<User> {
|
|
1792
1880
|
model() {
|
|
@@ -1802,7 +1890,7 @@ export class UserRepository extends Repository<User> {
|
|
|
1802
1890
|
}
|
|
1803
1891
|
}
|
|
1804
1892
|
`}static postRepository(){return`import { Repository } from '@beeblock/svelar/repositories';
|
|
1805
|
-
import { Post } from '
|
|
1893
|
+
import { Post } from './Post.js';
|
|
1806
1894
|
|
|
1807
1895
|
export class PostRepository extends Repository<Post> {
|
|
1808
1896
|
model() {
|
|
@@ -1830,8 +1918,8 @@ export class PostRepository extends Repository<Post> {
|
|
|
1830
1918
|
`}static authService(){return`import { Service } from '@beeblock/svelar/services';
|
|
1831
1919
|
import { Hash } from '@beeblock/svelar/hashing';
|
|
1832
1920
|
import { Event } from '@beeblock/svelar/events';
|
|
1833
|
-
import { UserRepository } from '
|
|
1834
|
-
import { UserRegistered } from '
|
|
1921
|
+
import { UserRepository } from './UserRepository.js';
|
|
1922
|
+
import { UserRegistered } from './UserRegistered.js';
|
|
1835
1923
|
|
|
1836
1924
|
const userRepo = new UserRepository();
|
|
1837
1925
|
|
|
@@ -1898,8 +1986,8 @@ export class AuthService extends Service {
|
|
|
1898
1986
|
`}static postService(){return`import { CrudService } from '@beeblock/svelar/services';
|
|
1899
1987
|
import { Repository } from '@beeblock/svelar/repositories';
|
|
1900
1988
|
import { Broadcast } from '@beeblock/svelar/broadcasting';
|
|
1901
|
-
import { PostRepository } from '
|
|
1902
|
-
import type { Post } from '
|
|
1989
|
+
import { PostRepository } from './PostRepository.js';
|
|
1990
|
+
import type { Post } from './Post.js';
|
|
1903
1991
|
|
|
1904
1992
|
const postRepo = new PostRepository();
|
|
1905
1993
|
|
|
@@ -1937,11 +2025,15 @@ export class PostService extends CrudService<Post> {
|
|
|
1937
2025
|
}
|
|
1938
2026
|
}
|
|
1939
2027
|
`}static authController(){return`import { Controller } from '@beeblock/svelar/routing';
|
|
1940
|
-
import { RegisterRequest } from '
|
|
1941
|
-
import { LoginRequest } from '
|
|
1942
|
-
import {
|
|
1943
|
-
import {
|
|
1944
|
-
import {
|
|
2028
|
+
import { RegisterRequest } from './RegisterRequest.js';
|
|
2029
|
+
import { LoginRequest } from './LoginRequest.js';
|
|
2030
|
+
import { ForgotPasswordRequest } from './ForgotPasswordRequest.js';
|
|
2031
|
+
import { ResetPasswordRequest } from './ResetPasswordRequest.js';
|
|
2032
|
+
import { OtpSendRequest } from './OtpSendRequest.js';
|
|
2033
|
+
import { OtpVerifyRequest } from './OtpVerifyRequest.js';
|
|
2034
|
+
import { RegisterUserAction } from './RegisterUserAction.js';
|
|
2035
|
+
import { AuthService } from './AuthService.js';
|
|
2036
|
+
import { UserResource } from './UserResource.js';
|
|
1945
2037
|
|
|
1946
2038
|
const registerAction = new RegisterUserAction();
|
|
1947
2039
|
const authService = new AuthService();
|
|
@@ -2005,21 +2097,15 @@ export class AuthController extends Controller {
|
|
|
2005
2097
|
|
|
2006
2098
|
/** POST /api/auth/forgot-password */
|
|
2007
2099
|
async forgotPassword(event: any) {
|
|
2008
|
-
const
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
const result = await authService.forgotPassword(email, event.locals.auth);
|
|
2100
|
+
const data = await ForgotPasswordRequest.validate(event);
|
|
2101
|
+
const result = await authService.forgotPassword(data.email, event.locals.auth);
|
|
2012
2102
|
return this.json(result.data);
|
|
2013
2103
|
}
|
|
2014
2104
|
|
|
2015
2105
|
/** POST /api/auth/reset-password */
|
|
2016
2106
|
async resetPassword(event: any) {
|
|
2017
|
-
const
|
|
2018
|
-
|
|
2019
|
-
return this.json({ message: 'Token, email, and password are required' }, 422);
|
|
2020
|
-
}
|
|
2021
|
-
|
|
2022
|
-
const result = await authService.resetPassword(token, email, password, event.locals.auth);
|
|
2107
|
+
const data = await ResetPasswordRequest.validate(event);
|
|
2108
|
+
const result = await authService.resetPassword(data.token, data.email, data.password, event.locals.auth);
|
|
2023
2109
|
if (!result.success) {
|
|
2024
2110
|
return this.json({ message: result.error }, 400);
|
|
2025
2111
|
}
|
|
@@ -2028,19 +2114,15 @@ export class AuthController extends Controller {
|
|
|
2028
2114
|
|
|
2029
2115
|
/** POST /api/auth/otp/send */
|
|
2030
2116
|
async sendOtp(event: any) {
|
|
2031
|
-
const
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
const result = await authService.sendOtp(email, event.locals.auth);
|
|
2117
|
+
const data = await OtpSendRequest.validate(event);
|
|
2118
|
+
const result = await authService.sendOtp(data.email, event.locals.auth);
|
|
2035
2119
|
return this.json(result.data);
|
|
2036
2120
|
}
|
|
2037
2121
|
|
|
2038
2122
|
/** POST /api/auth/otp/verify */
|
|
2039
2123
|
async verifyOtp(event: any) {
|
|
2040
|
-
const
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
const result = await authService.verifyOtp(email, code, event.locals.auth, event.locals.session);
|
|
2124
|
+
const data = await OtpVerifyRequest.validate(event);
|
|
2125
|
+
const result = await authService.verifyOtp(data.email, data.code, event.locals.auth, event.locals.session);
|
|
2044
2126
|
if (!result.success) {
|
|
2045
2127
|
return this.json({ message: result.error }, 401);
|
|
2046
2128
|
}
|
|
@@ -2066,11 +2148,11 @@ export class AuthController extends Controller {
|
|
|
2066
2148
|
}
|
|
2067
2149
|
}
|
|
2068
2150
|
`}static postController(){return`import { Controller } from '@beeblock/svelar/routing';
|
|
2069
|
-
import { CreatePostRequest } from '
|
|
2070
|
-
import { UpdatePostRequest } from '
|
|
2071
|
-
import { PostService } from '
|
|
2072
|
-
import { CreatePostAction } from '
|
|
2073
|
-
import { PostResource } from '
|
|
2151
|
+
import { CreatePostRequest } from './CreatePostRequest.js';
|
|
2152
|
+
import { UpdatePostRequest } from './UpdatePostRequest.js';
|
|
2153
|
+
import { PostService } from './PostService.js';
|
|
2154
|
+
import { CreatePostAction } from './CreatePostAction.js';
|
|
2155
|
+
import { PostResource } from './PostResource.js';
|
|
2074
2156
|
|
|
2075
2157
|
const postService = new PostService();
|
|
2076
2158
|
const createPostAction = new CreatePostAction();
|
|
@@ -2141,20 +2223,20 @@ export class PostController extends Controller {
|
|
|
2141
2223
|
}
|
|
2142
2224
|
`}static adminController(){return`import { Controller } from '@beeblock/svelar/routing';
|
|
2143
2225
|
import { Gate } from '@beeblock/svelar/auth';
|
|
2144
|
-
import { AdminService } from '
|
|
2145
|
-
import { UserResource } from '
|
|
2146
|
-
import { RoleResource } from '
|
|
2147
|
-
import { PermissionResource } from '
|
|
2148
|
-
import { UpdateUserRoleRequest } from '
|
|
2149
|
-
import { DeleteUserRequest } from '
|
|
2150
|
-
import { CreateRoleRequest } from '
|
|
2151
|
-
import { DeleteRoleRequest } from '
|
|
2152
|
-
import { CreatePermissionRequest } from '
|
|
2153
|
-
import { DeletePermissionRequest } from '
|
|
2154
|
-
import { RolePermissionRequest } from '
|
|
2155
|
-
import { UserRoleRequest } from '
|
|
2156
|
-
import { UserPermissionRequest } from '
|
|
2157
|
-
import { ExportDataRequest } from '
|
|
2226
|
+
import { AdminService } from './AdminService.js';
|
|
2227
|
+
import { UserResource } from '$lib/modules/auth/UserResource.js';
|
|
2228
|
+
import { RoleResource } from './RoleResource.js';
|
|
2229
|
+
import { PermissionResource } from './PermissionResource.js';
|
|
2230
|
+
import { UpdateUserRoleRequest } from './UpdateUserRoleRequest.js';
|
|
2231
|
+
import { DeleteUserRequest } from './DeleteUserRequest.js';
|
|
2232
|
+
import { CreateRoleRequest } from './CreateRoleRequest.js';
|
|
2233
|
+
import { DeleteRoleRequest } from './DeleteRoleRequest.js';
|
|
2234
|
+
import { CreatePermissionRequest } from './CreatePermissionRequest.js';
|
|
2235
|
+
import { DeletePermissionRequest } from './DeletePermissionRequest.js';
|
|
2236
|
+
import { RolePermissionRequest } from './RolePermissionRequest.js';
|
|
2237
|
+
import { UserRoleRequest } from './UserRoleRequest.js';
|
|
2238
|
+
import { UserPermissionRequest } from './UserPermissionRequest.js';
|
|
2239
|
+
import { ExportDataRequest } from './ExportDataRequest.js';
|
|
2158
2240
|
|
|
2159
2241
|
const adminService = new AdminService();
|
|
2160
2242
|
|
|
@@ -2314,7 +2396,7 @@ export class AdminController extends Controller {
|
|
|
2314
2396
|
}
|
|
2315
2397
|
}
|
|
2316
2398
|
`}static registerRequest(){return`import { FormRequest } from '@beeblock/svelar/forms';
|
|
2317
|
-
import { registerSchema } from '
|
|
2399
|
+
import { registerSchema } from './schemas.js';
|
|
2318
2400
|
|
|
2319
2401
|
export class RegisterRequest extends FormRequest {
|
|
2320
2402
|
rules() {
|
|
@@ -2322,15 +2404,47 @@ export class RegisterRequest extends FormRequest {
|
|
|
2322
2404
|
}
|
|
2323
2405
|
}
|
|
2324
2406
|
`}static loginRequest(){return`import { FormRequest } from '@beeblock/svelar/forms';
|
|
2325
|
-
import { loginSchema } from '
|
|
2407
|
+
import { loginSchema } from './schemas.js';
|
|
2326
2408
|
|
|
2327
2409
|
export class LoginRequest extends FormRequest {
|
|
2328
2410
|
rules() {
|
|
2329
2411
|
return loginSchema;
|
|
2330
2412
|
}
|
|
2331
2413
|
}
|
|
2414
|
+
`}static forgotPasswordRequest(){return`import { FormRequest } from '@beeblock/svelar/forms';
|
|
2415
|
+
import { forgotPasswordSchema } from './schemas.js';
|
|
2416
|
+
|
|
2417
|
+
export class ForgotPasswordRequest extends FormRequest {
|
|
2418
|
+
rules() {
|
|
2419
|
+
return forgotPasswordSchema;
|
|
2420
|
+
}
|
|
2421
|
+
}
|
|
2422
|
+
`}static resetPasswordRequest(){return`import { FormRequest } from '@beeblock/svelar/forms';
|
|
2423
|
+
import { resetPasswordSchema } from './schemas.js';
|
|
2424
|
+
|
|
2425
|
+
export class ResetPasswordRequest extends FormRequest {
|
|
2426
|
+
rules() {
|
|
2427
|
+
return resetPasswordSchema;
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2430
|
+
`}static otpSendRequest(){return`import { FormRequest } from '@beeblock/svelar/forms';
|
|
2431
|
+
import { otpRequestSchema } from './schemas.js';
|
|
2432
|
+
|
|
2433
|
+
export class OtpSendRequest extends FormRequest {
|
|
2434
|
+
rules() {
|
|
2435
|
+
return otpRequestSchema;
|
|
2436
|
+
}
|
|
2437
|
+
}
|
|
2438
|
+
`}static otpVerifyRequest(){return`import { FormRequest } from '@beeblock/svelar/forms';
|
|
2439
|
+
import { otpVerifySchema } from './schemas.js';
|
|
2440
|
+
|
|
2441
|
+
export class OtpVerifyRequest extends FormRequest {
|
|
2442
|
+
rules() {
|
|
2443
|
+
return otpVerifySchema;
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2332
2446
|
`}static createPostRequest(){return`import { FormRequest } from '@beeblock/svelar/forms';
|
|
2333
|
-
import { createPostSchema } from '
|
|
2447
|
+
import { createPostSchema } from './schemas.js';
|
|
2334
2448
|
|
|
2335
2449
|
export class CreatePostRequest extends FormRequest {
|
|
2336
2450
|
rules() {
|
|
@@ -2352,7 +2466,7 @@ export class CreatePostRequest extends FormRequest {
|
|
|
2352
2466
|
}
|
|
2353
2467
|
}
|
|
2354
2468
|
`}static updatePostRequest(){return`import { FormRequest } from '@beeblock/svelar/forms';
|
|
2355
|
-
import { updatePostSchema } from '
|
|
2469
|
+
import { updatePostSchema } from './schemas.js';
|
|
2356
2470
|
|
|
2357
2471
|
export class UpdatePostRequest extends FormRequest {
|
|
2358
2472
|
rules() {
|
|
@@ -2364,8 +2478,8 @@ export class UpdatePostRequest extends FormRequest {
|
|
|
2364
2478
|
}
|
|
2365
2479
|
}
|
|
2366
2480
|
`}static registerUserAction(){return`import { Action } from '@beeblock/svelar/actions';
|
|
2367
|
-
import { AuthService } from '
|
|
2368
|
-
import type { User } from '
|
|
2481
|
+
import { AuthService } from './AuthService.js';
|
|
2482
|
+
import type { User } from './User.js';
|
|
2369
2483
|
|
|
2370
2484
|
interface RegisterInput {
|
|
2371
2485
|
name: string;
|
|
@@ -2387,8 +2501,8 @@ export class RegisterUserAction extends Action<RegisterInput, ServiceResult<User
|
|
|
2387
2501
|
}
|
|
2388
2502
|
}
|
|
2389
2503
|
`}static createPostAction(){return`import { Action } from '@beeblock/svelar/actions';
|
|
2390
|
-
import { PostService } from '
|
|
2391
|
-
import type { Post } from '
|
|
2504
|
+
import { PostService } from './PostService.js';
|
|
2505
|
+
import type { Post } from './Post.js';
|
|
2392
2506
|
|
|
2393
2507
|
interface CreatePostInput {
|
|
2394
2508
|
userId: number;
|
|
@@ -2416,31 +2530,33 @@ export class CreatePostAction extends Action<CreatePostInput, Post> {
|
|
|
2416
2530
|
}
|
|
2417
2531
|
}
|
|
2418
2532
|
`}static userResource(){return`import { Resource } from '@beeblock/svelar/routing';
|
|
2533
|
+
import type { UserResponse } from './schemas.js';
|
|
2419
2534
|
|
|
2420
2535
|
export class UserResource extends Resource {
|
|
2421
|
-
toJSON() {
|
|
2536
|
+
toJSON(): UserResponse {
|
|
2422
2537
|
return {
|
|
2423
2538
|
id: this.data.id,
|
|
2424
2539
|
name: this.data.name,
|
|
2425
2540
|
email: this.data.email,
|
|
2426
2541
|
role: this.data.role ?? 'user',
|
|
2427
|
-
created_at: this.data.created_at,
|
|
2542
|
+
created_at: this.data.created_at ?? null,
|
|
2428
2543
|
};
|
|
2429
2544
|
}
|
|
2430
2545
|
}
|
|
2431
2546
|
`}static postResource(){return`import { Resource } from '@beeblock/svelar/routing';
|
|
2547
|
+
import type { PostResponse } from './schemas.js';
|
|
2432
2548
|
|
|
2433
2549
|
export class PostResource extends Resource {
|
|
2434
|
-
toJSON() {
|
|
2550
|
+
toJSON(): PostResponse {
|
|
2435
2551
|
return {
|
|
2436
2552
|
id: this.data.id,
|
|
2437
2553
|
title: this.data.title,
|
|
2438
2554
|
slug: this.data.slug,
|
|
2439
2555
|
body: this.data.body,
|
|
2440
|
-
published: this.data.published,
|
|
2556
|
+
published: !!this.data.published,
|
|
2441
2557
|
user_id: this.data.user_id,
|
|
2442
|
-
created_at: this.data.created_at,
|
|
2443
|
-
updated_at: this.data.updated_at,
|
|
2558
|
+
created_at: this.data.created_at ?? null,
|
|
2559
|
+
updated_at: this.data.updated_at ?? null,
|
|
2444
2560
|
};
|
|
2445
2561
|
}
|
|
2446
2562
|
}
|
|
@@ -2495,8 +2611,40 @@ export const userPermissionSchema = z.object({
|
|
|
2495
2611
|
export const exportDataSchema = z.object({
|
|
2496
2612
|
format: z.enum(['csv', 'json']).default('csv'),
|
|
2497
2613
|
});
|
|
2614
|
+
|
|
2615
|
+
// \u2500\u2500 Inferred Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
2616
|
+
|
|
2617
|
+
export type UpdateUserRoleInput = z.infer<typeof updateUserRoleSchema>;
|
|
2618
|
+
export type DeleteUserInput = z.infer<typeof deleteUserSchema>;
|
|
2619
|
+
export type CreateRoleInput = z.infer<typeof createRoleSchema>;
|
|
2620
|
+
export type DeleteRoleInput = z.infer<typeof deleteRoleSchema>;
|
|
2621
|
+
export type CreatePermissionInput = z.infer<typeof createPermissionSchema>;
|
|
2622
|
+
export type DeletePermissionInput = z.infer<typeof deletePermissionSchema>;
|
|
2623
|
+
export type RolePermissionInput = z.infer<typeof rolePermissionSchema>;
|
|
2624
|
+
export type UserRoleInput = z.infer<typeof userRoleSchema>;
|
|
2625
|
+
export type UserPermissionInput = z.infer<typeof userPermissionSchema>;
|
|
2626
|
+
export type ExportDataInput = z.infer<typeof exportDataSchema>;
|
|
2627
|
+
|
|
2628
|
+
// \u2500\u2500 Response Schemas \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
2629
|
+
|
|
2630
|
+
export const roleResponseSchema = z.object({
|
|
2631
|
+
id: z.number(),
|
|
2632
|
+
name: z.string(),
|
|
2633
|
+
guard: z.string(),
|
|
2634
|
+
description: z.string().nullable(),
|
|
2635
|
+
});
|
|
2636
|
+
|
|
2637
|
+
export const permissionResponseSchema = z.object({
|
|
2638
|
+
id: z.number(),
|
|
2639
|
+
name: z.string(),
|
|
2640
|
+
guard: z.string(),
|
|
2641
|
+
description: z.string().nullable(),
|
|
2642
|
+
});
|
|
2643
|
+
|
|
2644
|
+
export type RoleResponse = z.infer<typeof roleResponseSchema>;
|
|
2645
|
+
export type PermissionResponse = z.infer<typeof permissionResponseSchema>;
|
|
2498
2646
|
`}static updateUserRoleRequest(){return`import { FormRequest } from '@beeblock/svelar/forms';
|
|
2499
|
-
import { updateUserRoleSchema } from '
|
|
2647
|
+
import { updateUserRoleSchema } from './schemas.js';
|
|
2500
2648
|
|
|
2501
2649
|
export class UpdateUserRoleRequest extends FormRequest {
|
|
2502
2650
|
rules() {
|
|
@@ -2508,7 +2656,7 @@ export class UpdateUserRoleRequest extends FormRequest {
|
|
|
2508
2656
|
}
|
|
2509
2657
|
}
|
|
2510
2658
|
`}static deleteUserRequest(){return`import { FormRequest } from '@beeblock/svelar/forms';
|
|
2511
|
-
import { deleteUserSchema } from '
|
|
2659
|
+
import { deleteUserSchema } from './schemas.js';
|
|
2512
2660
|
|
|
2513
2661
|
export class DeleteUserRequest extends FormRequest {
|
|
2514
2662
|
rules() {
|
|
@@ -2520,7 +2668,7 @@ export class DeleteUserRequest extends FormRequest {
|
|
|
2520
2668
|
}
|
|
2521
2669
|
}
|
|
2522
2670
|
`}static createRoleRequest(){return`import { FormRequest } from '@beeblock/svelar/forms';
|
|
2523
|
-
import { createRoleSchema } from '
|
|
2671
|
+
import { createRoleSchema } from './schemas.js';
|
|
2524
2672
|
|
|
2525
2673
|
export class CreateRoleRequest extends FormRequest {
|
|
2526
2674
|
rules() {
|
|
@@ -2532,7 +2680,7 @@ export class CreateRoleRequest extends FormRequest {
|
|
|
2532
2680
|
}
|
|
2533
2681
|
}
|
|
2534
2682
|
`}static deleteRoleRequest(){return`import { FormRequest } from '@beeblock/svelar/forms';
|
|
2535
|
-
import { deleteRoleSchema } from '
|
|
2683
|
+
import { deleteRoleSchema } from './schemas.js';
|
|
2536
2684
|
|
|
2537
2685
|
export class DeleteRoleRequest extends FormRequest {
|
|
2538
2686
|
rules() {
|
|
@@ -2544,7 +2692,7 @@ export class DeleteRoleRequest extends FormRequest {
|
|
|
2544
2692
|
}
|
|
2545
2693
|
}
|
|
2546
2694
|
`}static createPermissionRequest(){return`import { FormRequest } from '@beeblock/svelar/forms';
|
|
2547
|
-
import { createPermissionSchema } from '
|
|
2695
|
+
import { createPermissionSchema } from './schemas.js';
|
|
2548
2696
|
|
|
2549
2697
|
export class CreatePermissionRequest extends FormRequest {
|
|
2550
2698
|
rules() {
|
|
@@ -2556,7 +2704,7 @@ export class CreatePermissionRequest extends FormRequest {
|
|
|
2556
2704
|
}
|
|
2557
2705
|
}
|
|
2558
2706
|
`}static deletePermissionRequest(){return`import { FormRequest } from '@beeblock/svelar/forms';
|
|
2559
|
-
import { deletePermissionSchema } from '
|
|
2707
|
+
import { deletePermissionSchema } from './schemas.js';
|
|
2560
2708
|
|
|
2561
2709
|
export class DeletePermissionRequest extends FormRequest {
|
|
2562
2710
|
rules() {
|
|
@@ -2568,7 +2716,7 @@ export class DeletePermissionRequest extends FormRequest {
|
|
|
2568
2716
|
}
|
|
2569
2717
|
}
|
|
2570
2718
|
`}static rolePermissionRequest(){return`import { FormRequest } from '@beeblock/svelar/forms';
|
|
2571
|
-
import { rolePermissionSchema } from '
|
|
2719
|
+
import { rolePermissionSchema } from './schemas.js';
|
|
2572
2720
|
|
|
2573
2721
|
export class RolePermissionRequest extends FormRequest {
|
|
2574
2722
|
rules() {
|
|
@@ -2580,7 +2728,7 @@ export class RolePermissionRequest extends FormRequest {
|
|
|
2580
2728
|
}
|
|
2581
2729
|
}
|
|
2582
2730
|
`}static userRoleRequest(){return`import { FormRequest } from '@beeblock/svelar/forms';
|
|
2583
|
-
import { userRoleSchema } from '
|
|
2731
|
+
import { userRoleSchema } from './schemas.js';
|
|
2584
2732
|
|
|
2585
2733
|
export class UserRoleRequest extends FormRequest {
|
|
2586
2734
|
rules() {
|
|
@@ -2592,7 +2740,7 @@ export class UserRoleRequest extends FormRequest {
|
|
|
2592
2740
|
}
|
|
2593
2741
|
}
|
|
2594
2742
|
`}static userPermissionRequest(){return`import { FormRequest } from '@beeblock/svelar/forms';
|
|
2595
|
-
import { userPermissionSchema } from '
|
|
2743
|
+
import { userPermissionSchema } from './schemas.js';
|
|
2596
2744
|
|
|
2597
2745
|
export class UserPermissionRequest extends FormRequest {
|
|
2598
2746
|
rules() {
|
|
@@ -2604,7 +2752,7 @@ export class UserPermissionRequest extends FormRequest {
|
|
|
2604
2752
|
}
|
|
2605
2753
|
}
|
|
2606
2754
|
`}static exportDataRequest(){return`import { FormRequest } from '@beeblock/svelar/forms';
|
|
2607
|
-
import { exportDataSchema } from '
|
|
2755
|
+
import { exportDataSchema } from './schemas.js';
|
|
2608
2756
|
|
|
2609
2757
|
export class ExportDataRequest extends FormRequest {
|
|
2610
2758
|
rules() {
|
|
@@ -2616,9 +2764,10 @@ export class ExportDataRequest extends FormRequest {
|
|
|
2616
2764
|
}
|
|
2617
2765
|
}
|
|
2618
2766
|
`}static roleResource(){return`import { Resource } from '@beeblock/svelar/routing';
|
|
2767
|
+
import type { RoleResponse } from './schemas.js';
|
|
2619
2768
|
|
|
2620
2769
|
export class RoleResource extends Resource {
|
|
2621
|
-
toJSON() {
|
|
2770
|
+
toJSON(): RoleResponse {
|
|
2622
2771
|
return {
|
|
2623
2772
|
id: this.data.id,
|
|
2624
2773
|
name: this.data.name,
|
|
@@ -2628,9 +2777,10 @@ export class RoleResource extends Resource {
|
|
|
2628
2777
|
}
|
|
2629
2778
|
}
|
|
2630
2779
|
`}static permissionResource(){return`import { Resource } from '@beeblock/svelar/routing';
|
|
2780
|
+
import type { PermissionResponse } from './schemas.js';
|
|
2631
2781
|
|
|
2632
2782
|
export class PermissionResource extends Resource {
|
|
2633
|
-
toJSON() {
|
|
2783
|
+
toJSON(): PermissionResponse {
|
|
2634
2784
|
return {
|
|
2635
2785
|
id: this.data.id,
|
|
2636
2786
|
name: this.data.name,
|
|
@@ -2642,10 +2792,10 @@ export class PermissionResource extends Resource {
|
|
|
2642
2792
|
`}static adminService(){return`import { Service } from '@beeblock/svelar/services';
|
|
2643
2793
|
import { Permissions } from '@beeblock/svelar/permissions';
|
|
2644
2794
|
import { Queue } from '@beeblock/svelar/queue';
|
|
2645
|
-
import { UserRepository } from '
|
|
2646
|
-
import { Post } from '
|
|
2647
|
-
import { User } from '
|
|
2648
|
-
import { ExportDataJob } from '
|
|
2795
|
+
import { UserRepository } from '$lib/modules/auth/UserRepository.js';
|
|
2796
|
+
import { Post } from '$lib/modules/posts/Post.js';
|
|
2797
|
+
import { User } from '$lib/modules/auth/User.js';
|
|
2798
|
+
import { ExportDataJob } from '$lib/shared/jobs/ExportDataJob.js';
|
|
2649
2799
|
|
|
2650
2800
|
const userRepo = new UserRepository();
|
|
2651
2801
|
|
|
@@ -2775,6 +2925,8 @@ Gate.define('manage-users', (user) => user?.role === 'admin');
|
|
|
2775
2925
|
Gate.defineSuperUser((user) => user?.role === 'admin');
|
|
2776
2926
|
`}static authSchema(){return`import { z } from 'zod';
|
|
2777
2927
|
|
|
2928
|
+
// \u2500\u2500 Input Schemas (DTOs + UI validation) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
2929
|
+
|
|
2778
2930
|
export const loginSchema = z.object({
|
|
2779
2931
|
email: z.string().email('Please enter a valid email address'),
|
|
2780
2932
|
password: z.string().min(1, 'Password is required'),
|
|
@@ -2812,8 +2964,31 @@ export const otpVerifySchema = z.object({
|
|
|
2812
2964
|
email: z.string().email(),
|
|
2813
2965
|
code: z.string().length(6, 'Code must be 6 digits'),
|
|
2814
2966
|
});
|
|
2967
|
+
|
|
2968
|
+
// \u2500\u2500 Inferred Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
2969
|
+
|
|
2970
|
+
export type LoginInput = z.infer<typeof loginSchema>;
|
|
2971
|
+
export type RegisterInput = z.infer<typeof registerSchema>;
|
|
2972
|
+
export type ForgotPasswordInput = z.infer<typeof forgotPasswordSchema>;
|
|
2973
|
+
export type ResetPasswordInput = z.infer<typeof resetPasswordSchema>;
|
|
2974
|
+
export type OtpRequestInput = z.infer<typeof otpRequestSchema>;
|
|
2975
|
+
export type OtpVerifyInput = z.infer<typeof otpVerifySchema>;
|
|
2976
|
+
|
|
2977
|
+
// \u2500\u2500 Response Schemas (Resources + API contracts) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
2978
|
+
|
|
2979
|
+
export const userResponseSchema = z.object({
|
|
2980
|
+
id: z.number(),
|
|
2981
|
+
name: z.string(),
|
|
2982
|
+
email: z.string().email(),
|
|
2983
|
+
role: z.string(),
|
|
2984
|
+
created_at: z.string().nullable(),
|
|
2985
|
+
});
|
|
2986
|
+
|
|
2987
|
+
export type UserResponse = z.infer<typeof userResponseSchema>;
|
|
2815
2988
|
`}static postSchema(){return`import { z } from 'zod';
|
|
2816
2989
|
|
|
2990
|
+
// \u2500\u2500 Input Schemas \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
2991
|
+
|
|
2817
2992
|
export const createPostSchema = z.object({
|
|
2818
2993
|
title: z.string().min(3, 'Title must be at least 3 characters').max(255),
|
|
2819
2994
|
slug: z.string().regex(/^[a-z0-9-]+$/, 'Slug must be lowercase alphanumeric with dashes').optional(),
|
|
@@ -2827,6 +3002,26 @@ export const updatePostSchema = z.object({
|
|
|
2827
3002
|
body: z.string().min(10).optional(),
|
|
2828
3003
|
published: z.boolean().optional(),
|
|
2829
3004
|
});
|
|
3005
|
+
|
|
3006
|
+
// \u2500\u2500 Inferred Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
3007
|
+
|
|
3008
|
+
export type CreatePostInput = z.infer<typeof createPostSchema>;
|
|
3009
|
+
export type UpdatePostInput = z.infer<typeof updatePostSchema>;
|
|
3010
|
+
|
|
3011
|
+
// \u2500\u2500 Response Schema (Resources + API contracts) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
3012
|
+
|
|
3013
|
+
export const postResponseSchema = z.object({
|
|
3014
|
+
id: z.number(),
|
|
3015
|
+
title: z.string(),
|
|
3016
|
+
slug: z.string(),
|
|
3017
|
+
body: z.string(),
|
|
3018
|
+
published: z.boolean(),
|
|
3019
|
+
user_id: z.number(),
|
|
3020
|
+
created_at: z.string().nullable(),
|
|
3021
|
+
updated_at: z.string().nullable(),
|
|
3022
|
+
});
|
|
3023
|
+
|
|
3024
|
+
export type PostResponse = z.infer<typeof postResponseSchema>;
|
|
2830
3025
|
`}static createUsersTable(){return`import { Migration } from '@beeblock/svelar/database';
|
|
2831
3026
|
|
|
2832
3027
|
export default class CreateUsersTable extends Migration {
|
|
@@ -2999,8 +3194,8 @@ export default class CreateFailedJobsTable extends Migration {
|
|
|
2999
3194
|
`}static databaseSeeder(){return`import { Seeder } from '@beeblock/svelar/database';
|
|
3000
3195
|
import { Hash } from '@beeblock/svelar/hashing';
|
|
3001
3196
|
import { Permissions } from '@beeblock/svelar/permissions';
|
|
3002
|
-
import { User } from '
|
|
3003
|
-
import { Post } from '
|
|
3197
|
+
import { User } from '$lib/modules/auth/User.js';
|
|
3198
|
+
import { Post } from '$lib/modules/posts/Post.js';
|
|
3004
3199
|
|
|
3005
3200
|
export class DatabaseSeeder extends Seeder {
|
|
3006
3201
|
async run(): Promise<void> {
|
|
@@ -3091,8 +3286,8 @@ export class DatabaseSeeder extends Seeder {
|
|
|
3091
3286
|
import { fail, redirect } from '@sveltejs/kit';
|
|
3092
3287
|
import { superValidate, message } from 'sveltekit-superforms';
|
|
3093
3288
|
import { zod } from 'sveltekit-superforms/adapters';
|
|
3094
|
-
import { loginSchema } from '$lib/
|
|
3095
|
-
import { AuthService } from '$lib/
|
|
3289
|
+
import { loginSchema } from '$lib/modules/auth/schemas';
|
|
3290
|
+
import { AuthService } from '$lib/modules/auth/AuthService';
|
|
3096
3291
|
import { authConfig } from '../../app.js';
|
|
3097
3292
|
|
|
3098
3293
|
const authService = new AuthService();
|
|
@@ -3221,8 +3416,8 @@ export const actions: Actions = {
|
|
|
3221
3416
|
import { fail, redirect } from '@sveltejs/kit';
|
|
3222
3417
|
import { superValidate, message, setError } from 'sveltekit-superforms';
|
|
3223
3418
|
import { zod } from 'sveltekit-superforms/adapters';
|
|
3224
|
-
import { registerSchema } from '$lib/
|
|
3225
|
-
import { AuthService } from '$lib/
|
|
3419
|
+
import { registerSchema } from '$lib/modules/auth/schemas';
|
|
3420
|
+
import { AuthService } from '$lib/modules/auth/AuthService';
|
|
3226
3421
|
import { auth, authConfig } from '../../app.js';
|
|
3227
3422
|
|
|
3228
3423
|
const authService = new AuthService();
|
|
@@ -3387,7 +3582,7 @@ export const actions: Actions = {
|
|
|
3387
3582
|
import { fail } from '@sveltejs/kit';
|
|
3388
3583
|
import { superValidate, message } from 'sveltekit-superforms';
|
|
3389
3584
|
import { zod } from 'sveltekit-superforms/adapters';
|
|
3390
|
-
import { forgotPasswordSchema } from '$lib/
|
|
3585
|
+
import { forgotPasswordSchema } from '$lib/modules/auth/schemas';
|
|
3391
3586
|
import { auth } from '../../app.js';
|
|
3392
3587
|
|
|
3393
3588
|
export const load: PageServerLoad = async () => {
|
|
@@ -3475,7 +3670,7 @@ export const actions: Actions = {
|
|
|
3475
3670
|
import { fail, redirect } from '@sveltejs/kit';
|
|
3476
3671
|
import { superValidate, message } from 'sveltekit-superforms';
|
|
3477
3672
|
import { zod } from 'sveltekit-superforms/adapters';
|
|
3478
|
-
import { resetPasswordSchema } from '$lib/
|
|
3673
|
+
import { resetPasswordSchema } from '$lib/modules/auth/schemas';
|
|
3479
3674
|
import { auth } from '../../app.js';
|
|
3480
3675
|
|
|
3481
3676
|
export const load: PageServerLoad = async ({ url }) => {
|
|
@@ -3581,7 +3776,7 @@ export const actions: Actions = {
|
|
|
3581
3776
|
import { fail, redirect } from '@sveltejs/kit';
|
|
3582
3777
|
import { superValidate, message } from 'sveltekit-superforms';
|
|
3583
3778
|
import { zod } from 'sveltekit-superforms/adapters';
|
|
3584
|
-
import { otpRequestSchema, otpVerifySchema } from '$lib/
|
|
3779
|
+
import { otpRequestSchema, otpVerifySchema } from '$lib/modules/auth/schemas';
|
|
3585
3780
|
import { auth, authConfig } from '../../app.js';
|
|
3586
3781
|
|
|
3587
3782
|
export const load: PageServerLoad = async ({ locals }) => {
|
|
@@ -3810,6 +4005,7 @@ export const load = guardAuth();
|
|
|
3810
4005
|
import LayoutDashboard from 'lucide-svelte/icons/layout-dashboard';
|
|
3811
4006
|
import KeyRound from 'lucide-svelte/icons/key-round';
|
|
3812
4007
|
import Users from 'lucide-svelte/icons/users';
|
|
4008
|
+
import CreditCard from 'lucide-svelte/icons/credit-card';
|
|
3813
4009
|
import Settings from 'lucide-svelte/icons/settings';
|
|
3814
4010
|
|
|
3815
4011
|
interface Props {
|
|
@@ -3823,6 +4019,7 @@ export const load = guardAuth();
|
|
|
3823
4019
|
{ href: '/dashboard', label: 'Overview', exact: true, icon: LayoutDashboard },
|
|
3824
4020
|
{ href: '/dashboard/api-keys', label: 'API Keys', exact: false, icon: KeyRound },
|
|
3825
4021
|
{ href: '/dashboard/team', label: 'Team', exact: false, icon: Users },
|
|
4022
|
+
{ href: '/dashboard/billing', label: 'Billing', exact: false, icon: CreditCard },
|
|
3826
4023
|
];
|
|
3827
4024
|
|
|
3828
4025
|
function isActive(href: string, exact: boolean, pathname: string): boolean {
|
|
@@ -4506,8 +4703,8 @@ export const load = guardAuth('/dashboard', { role: 'admin' });
|
|
|
4506
4703
|
</div>
|
|
4507
4704
|
</div>
|
|
4508
4705
|
`}static adminPageServer(){return`import type { ServerLoadEvent } from '@sveltejs/kit';
|
|
4509
|
-
import { User } from '$lib/
|
|
4510
|
-
import { Post } from '$lib/
|
|
4706
|
+
import { User } from '$lib/modules/auth/User.js';
|
|
4707
|
+
import { Post } from '$lib/modules/posts/Post.js';
|
|
4511
4708
|
import { JobMonitor } from '@beeblock/svelar/queue/JobMonitor';
|
|
4512
4709
|
import { ScheduleMonitor } from '@beeblock/svelar/scheduler/ScheduleMonitor';
|
|
4513
4710
|
import { LogViewer } from '@beeblock/svelar/logging/LogViewer';
|
|
@@ -5610,7 +5807,7 @@ export const GET: RequestHandler = async () => {
|
|
|
5610
5807
|
});
|
|
5611
5808
|
};
|
|
5612
5809
|
`}static apiAuthRegister(){return`import { ThrottleMiddleware } from '@beeblock/svelar/middleware';
|
|
5613
|
-
import { AuthController } from '$lib/
|
|
5810
|
+
import { AuthController } from '$lib/modules/auth/AuthController.js';
|
|
5614
5811
|
|
|
5615
5812
|
const throttle = new ThrottleMiddleware({ maxAttempts: 5, decayMinutes: 2 });
|
|
5616
5813
|
const ctrl = new AuthController();
|
|
@@ -5621,7 +5818,7 @@ export async function POST(event: any) {
|
|
|
5621
5818
|
return ctrl.handle('register')(event);
|
|
5622
5819
|
}
|
|
5623
5820
|
`}static apiAuthLogin(){return`import { ThrottleMiddleware } from '@beeblock/svelar/middleware';
|
|
5624
|
-
import { AuthController } from '$lib/
|
|
5821
|
+
import { AuthController } from '$lib/modules/auth/AuthController.js';
|
|
5625
5822
|
|
|
5626
5823
|
const throttle = new ThrottleMiddleware({ maxAttempts: 5, decayMinutes: 1 });
|
|
5627
5824
|
const ctrl = new AuthController();
|
|
@@ -5631,16 +5828,16 @@ export async function POST(event: any) {
|
|
|
5631
5828
|
if (blocked) return blocked;
|
|
5632
5829
|
return ctrl.handle('login')(event);
|
|
5633
5830
|
}
|
|
5634
|
-
`}static apiAuthLogout(){return`import { AuthController } from '$lib/
|
|
5831
|
+
`}static apiAuthLogout(){return`import { AuthController } from '$lib/modules/auth/AuthController.js';
|
|
5635
5832
|
|
|
5636
5833
|
const ctrl = new AuthController();
|
|
5637
5834
|
export const POST = ctrl.handle('logout');
|
|
5638
|
-
`}static apiAuthMe(){return`import { AuthController } from '$lib/
|
|
5835
|
+
`}static apiAuthMe(){return`import { AuthController } from '$lib/modules/auth/AuthController.js';
|
|
5639
5836
|
|
|
5640
5837
|
const ctrl = new AuthController();
|
|
5641
5838
|
export const GET = ctrl.handle('me');
|
|
5642
5839
|
`}static apiAuthForgotPassword(){return`import { ThrottleMiddleware } from '@beeblock/svelar/middleware';
|
|
5643
|
-
import { AuthController } from '$lib/
|
|
5840
|
+
import { AuthController } from '$lib/modules/auth/AuthController.js';
|
|
5644
5841
|
|
|
5645
5842
|
const throttle = new ThrottleMiddleware({ maxAttempts: 3, decayMinutes: 5 });
|
|
5646
5843
|
const ctrl = new AuthController();
|
|
@@ -5651,7 +5848,7 @@ export async function POST(event: any) {
|
|
|
5651
5848
|
return ctrl.handle('forgotPassword')(event);
|
|
5652
5849
|
}
|
|
5653
5850
|
`}static apiAuthResetPassword(){return`import { ThrottleMiddleware } from '@beeblock/svelar/middleware';
|
|
5654
|
-
import { AuthController } from '$lib/
|
|
5851
|
+
import { AuthController } from '$lib/modules/auth/AuthController.js';
|
|
5655
5852
|
|
|
5656
5853
|
const throttle = new ThrottleMiddleware({ maxAttempts: 5, decayMinutes: 5 });
|
|
5657
5854
|
const ctrl = new AuthController();
|
|
@@ -5662,7 +5859,7 @@ export async function POST(event: any) {
|
|
|
5662
5859
|
return ctrl.handle('resetPassword')(event);
|
|
5663
5860
|
}
|
|
5664
5861
|
`}static apiAuthOtpSend(){return`import { ThrottleMiddleware } from '@beeblock/svelar/middleware';
|
|
5665
|
-
import { AuthController } from '$lib/
|
|
5862
|
+
import { AuthController } from '$lib/modules/auth/AuthController.js';
|
|
5666
5863
|
|
|
5667
5864
|
const throttle = new ThrottleMiddleware({ maxAttempts: 3, decayMinutes: 2 });
|
|
5668
5865
|
const ctrl = new AuthController();
|
|
@@ -5673,7 +5870,7 @@ export async function POST(event: any) {
|
|
|
5673
5870
|
return ctrl.handle('sendOtp')(event);
|
|
5674
5871
|
}
|
|
5675
5872
|
`}static apiAuthOtpVerify(){return`import { ThrottleMiddleware } from '@beeblock/svelar/middleware';
|
|
5676
|
-
import { AuthController } from '$lib/
|
|
5873
|
+
import { AuthController } from '$lib/modules/auth/AuthController.js';
|
|
5677
5874
|
|
|
5678
5875
|
const throttle = new ThrottleMiddleware({ maxAttempts: 5, decayMinutes: 5 });
|
|
5679
5876
|
const ctrl = new AuthController();
|
|
@@ -5683,22 +5880,22 @@ export async function POST(event: any) {
|
|
|
5683
5880
|
if (blocked) return blocked;
|
|
5684
5881
|
return ctrl.handle('verifyOtp')(event);
|
|
5685
5882
|
}
|
|
5686
|
-
`}static apiAuthVerifyEmail(){return`import { AuthController } from '$lib/
|
|
5883
|
+
`}static apiAuthVerifyEmail(){return`import { AuthController } from '$lib/modules/auth/AuthController.js';
|
|
5687
5884
|
|
|
5688
5885
|
const ctrl = new AuthController();
|
|
5689
5886
|
export const GET = ctrl.handle('verifyEmail');
|
|
5690
|
-
`}static apiPosts(){return`import { PostController } from '$lib/
|
|
5887
|
+
`}static apiPosts(){return`import { PostController } from '$lib/modules/posts/PostController.js';
|
|
5691
5888
|
|
|
5692
5889
|
const ctrl = new PostController();
|
|
5693
5890
|
export const GET = ctrl.handle('index');
|
|
5694
5891
|
export const POST = ctrl.handle('store');
|
|
5695
|
-
`}static apiPostsSingle(){return`import { PostController } from '$lib/
|
|
5892
|
+
`}static apiPostsSingle(){return`import { PostController } from '$lib/modules/posts/PostController.js';
|
|
5696
5893
|
|
|
5697
5894
|
const ctrl = new PostController();
|
|
5698
5895
|
export const GET = ctrl.handle('show');
|
|
5699
5896
|
export const PUT = ctrl.handle('update');
|
|
5700
5897
|
export const DELETE = ctrl.handle('destroy');
|
|
5701
|
-
`}static apiPostsMine(){return`import { PostController } from '$lib/
|
|
5898
|
+
`}static apiPostsMine(){return`import { PostController } from '$lib/modules/posts/PostController.js';
|
|
5702
5899
|
|
|
5703
5900
|
const ctrl = new PostController();
|
|
5704
5901
|
export const GET = ctrl.handle('mine');
|
|
@@ -5759,38 +5956,38 @@ export const POST: RequestHandler = async (event) => {
|
|
|
5759
5956
|
return json({ message: err.message || 'Failed to broadcast' }, { status: 500 });
|
|
5760
5957
|
}
|
|
5761
5958
|
};
|
|
5762
|
-
`}static apiAdminUsers(){return`import { AdminController } from '$lib/
|
|
5959
|
+
`}static apiAdminUsers(){return`import { AdminController } from '$lib/modules/admin/AdminController.js';
|
|
5763
5960
|
|
|
5764
5961
|
const ctrl = new AdminController();
|
|
5765
5962
|
export const GET = ctrl.handle('listUsers');
|
|
5766
5963
|
export const PUT = ctrl.handle('updateUserRole');
|
|
5767
5964
|
export const DELETE = ctrl.handle('deleteUser');
|
|
5768
|
-
`}static apiAdminRoles(){return`import { AdminController } from '$lib/
|
|
5965
|
+
`}static apiAdminRoles(){return`import { AdminController } from '$lib/modules/admin/AdminController.js';
|
|
5769
5966
|
|
|
5770
5967
|
const ctrl = new AdminController();
|
|
5771
5968
|
export const POST = ctrl.handle('createRole');
|
|
5772
5969
|
export const DELETE = ctrl.handle('deleteRole');
|
|
5773
|
-
`}static apiAdminPermissions(){return`import { AdminController } from '$lib/
|
|
5970
|
+
`}static apiAdminPermissions(){return`import { AdminController } from '$lib/modules/admin/AdminController.js';
|
|
5774
5971
|
|
|
5775
5972
|
const ctrl = new AdminController();
|
|
5776
5973
|
export const POST = ctrl.handle('createPermission');
|
|
5777
5974
|
export const DELETE = ctrl.handle('deletePermission');
|
|
5778
|
-
`}static apiAdminRolePermissions(){return`import { AdminController } from '$lib/
|
|
5975
|
+
`}static apiAdminRolePermissions(){return`import { AdminController } from '$lib/modules/admin/AdminController.js';
|
|
5779
5976
|
|
|
5780
5977
|
const ctrl = new AdminController();
|
|
5781
5978
|
export const POST = ctrl.handle('attachRolePermission');
|
|
5782
5979
|
export const DELETE = ctrl.handle('detachRolePermission');
|
|
5783
|
-
`}static apiAdminUserRoles(){return`import { AdminController } from '$lib/
|
|
5980
|
+
`}static apiAdminUserRoles(){return`import { AdminController } from '$lib/modules/admin/AdminController.js';
|
|
5784
5981
|
|
|
5785
5982
|
const ctrl = new AdminController();
|
|
5786
5983
|
export const POST = ctrl.handle('assignUserRole');
|
|
5787
5984
|
export const DELETE = ctrl.handle('removeUserRole');
|
|
5788
|
-
`}static apiAdminUserPermissions(){return`import { AdminController } from '$lib/
|
|
5985
|
+
`}static apiAdminUserPermissions(){return`import { AdminController } from '$lib/modules/admin/AdminController.js';
|
|
5789
5986
|
|
|
5790
5987
|
const ctrl = new AdminController();
|
|
5791
5988
|
export const POST = ctrl.handle('grantUserPermission');
|
|
5792
5989
|
export const DELETE = ctrl.handle('revokeUserPermission');
|
|
5793
|
-
`}static apiAdminExport(){return`import { AdminController } from '$lib/
|
|
5990
|
+
`}static apiAdminExport(){return`import { AdminController } from '$lib/modules/admin/AdminController.js';
|
|
5794
5991
|
|
|
5795
5992
|
const ctrl = new AdminController();
|
|
5796
5993
|
export const POST = ctrl.handle('exportData');
|
|
@@ -5964,8 +6161,15 @@ export class SendWelcomeEmail extends Job {
|
|
|
5964
6161
|
maxAttempts = 3;
|
|
5965
6162
|
retryDelay = 30;
|
|
5966
6163
|
|
|
5967
|
-
|
|
6164
|
+
userId: number;
|
|
6165
|
+
email: string;
|
|
6166
|
+
name: string;
|
|
6167
|
+
|
|
6168
|
+
constructor(userId: number, email: string, name: string) {
|
|
5968
6169
|
super();
|
|
6170
|
+
this.userId = userId;
|
|
6171
|
+
this.email = email;
|
|
6172
|
+
this.name = name;
|
|
5969
6173
|
}
|
|
5970
6174
|
|
|
5971
6175
|
async handle(): Promise<void> {
|
|
@@ -5993,8 +6197,8 @@ export class SendWelcomeEmail extends Job {
|
|
|
5993
6197
|
}
|
|
5994
6198
|
`}static dailyDigestJob(){return`import { Job } from '@beeblock/svelar/queue';
|
|
5995
6199
|
import { Mailer } from '@beeblock/svelar/mail';
|
|
5996
|
-
import { User } from '
|
|
5997
|
-
import { Post } from '
|
|
6200
|
+
import { User } from '$lib/modules/auth/User.js';
|
|
6201
|
+
import { Post } from '$lib/modules/posts/Post.js';
|
|
5998
6202
|
|
|
5999
6203
|
export class DailyDigestJob extends Job {
|
|
6000
6204
|
maxAttempts = 3;
|
|
@@ -6059,8 +6263,8 @@ export class DailyDigestJob extends Job {
|
|
|
6059
6263
|
}
|
|
6060
6264
|
`}static exportDataJob(){return`import { Job } from '@beeblock/svelar/queue';
|
|
6061
6265
|
import { Storage } from '@beeblock/svelar/storage';
|
|
6062
|
-
import { User } from '
|
|
6063
|
-
import { Post } from '
|
|
6266
|
+
import { User } from '$lib/modules/auth/User.js';
|
|
6267
|
+
import { Post } from '$lib/modules/posts/Post.js';
|
|
6064
6268
|
|
|
6065
6269
|
export class ExportDataJob extends Job {
|
|
6066
6270
|
maxAttempts = 2;
|
|
@@ -6168,7 +6372,7 @@ export default class CleanExpiredSessions extends ScheduledTask {
|
|
|
6168
6372
|
}
|
|
6169
6373
|
`}static dailyDigestEmail(){return`import { ScheduledTask } from '@beeblock/svelar/scheduler';
|
|
6170
6374
|
import { Queue } from '@beeblock/svelar/queue';
|
|
6171
|
-
import { DailyDigestJob } from '
|
|
6375
|
+
import { DailyDigestJob } from '$lib/shared/jobs/DailyDigestJob.js';
|
|
6172
6376
|
|
|
6173
6377
|
export default class DailyDigestEmail extends ScheduledTask {
|
|
6174
6378
|
name = 'daily-digest-email';
|
|
@@ -6333,12 +6537,15 @@ export async function load(event: ServerLoadEvent) {
|
|
|
6333
6537
|
</div>
|
|
6334
6538
|
</div>
|
|
6335
6539
|
`}static userRegisteredEvent(){return`export class UserRegistered {
|
|
6336
|
-
|
|
6540
|
+
readonly user: any;
|
|
6541
|
+
constructor(user: any) {
|
|
6542
|
+
this.user = user;
|
|
6543
|
+
}
|
|
6337
6544
|
}
|
|
6338
6545
|
`}static sendWelcomeEmailListener(){return`import { Queue } from '@beeblock/svelar/queue';
|
|
6339
6546
|
import { Notifier } from '@beeblock/svelar/notifications';
|
|
6340
|
-
import { SendWelcomeEmail } from '
|
|
6341
|
-
import { WelcomeNotification } from '
|
|
6547
|
+
import { SendWelcomeEmail } from '$lib/shared/jobs/SendWelcomeEmail.js';
|
|
6548
|
+
import { WelcomeNotification } from './WelcomeNotification.js';
|
|
6342
6549
|
|
|
6343
6550
|
export class SendWelcomeEmailListener {
|
|
6344
6551
|
async handle(event: any): Promise<void> {
|
|
@@ -6354,8 +6561,11 @@ export class SendWelcomeEmailListener {
|
|
|
6354
6561
|
`}static welcomeNotification(){return`import { Notification } from '@beeblock/svelar/notifications';
|
|
6355
6562
|
|
|
6356
6563
|
export class WelcomeNotification extends Notification {
|
|
6357
|
-
|
|
6564
|
+
user: any;
|
|
6565
|
+
|
|
6566
|
+
constructor(user: any) {
|
|
6358
6567
|
super();
|
|
6568
|
+
this.user = user;
|
|
6359
6569
|
}
|
|
6360
6570
|
|
|
6361
6571
|
via() {
|
|
@@ -6373,8 +6583,8 @@ export class WelcomeNotification extends Notification {
|
|
|
6373
6583
|
}
|
|
6374
6584
|
}
|
|
6375
6585
|
`}static eventServiceProvider(){return`import { EventServiceProvider as BaseProvider } from '@beeblock/svelar/events';
|
|
6376
|
-
import { UserRegistered } from '
|
|
6377
|
-
import { SendWelcomeEmailListener } from '
|
|
6586
|
+
import { UserRegistered } from '$lib/modules/auth/UserRegistered.js';
|
|
6587
|
+
import { SendWelcomeEmailListener } from '$lib/modules/auth/SendWelcomeEmailListener.js';
|
|
6378
6588
|
|
|
6379
6589
|
export class EventServiceProvider extends BaseProvider {
|
|
6380
6590
|
protected listen = {
|
|
@@ -6433,12 +6643,430 @@ export class EventServiceProvider extends BaseProvider {
|
|
|
6433
6643
|
</Card>
|
|
6434
6644
|
</div>
|
|
6435
6645
|
</div>
|
|
6436
|
-
`}
|
|
6437
|
-
`);let d=(N,kr)=>{let z=s(u,N);n(s(z,".."),{recursive:!0}),a(z,kr)};this.info("Creating project structure...");let p=["","src","src/lib","src/lib/models","src/lib/repositories","src/lib/services","src/lib/controllers","src/lib/dtos","src/lib/actions","src/lib/auth","src/lib/schemas","src/lib/shared/jobs","src/lib/shared/scheduler","src/lib/events","src/lib/listeners","src/lib/resources","src/lib/notifications","src/lib/shared/middleware","src/lib/shared/components","src/lib/shared/stores","src/lib/shared/plugins","src/lib/shared/channels","src/lib/shared/commands","src/lib/shared/providers","src/lib/database/migrations","src/lib/database/seeders","src/routes","src/routes/api","static","storage/logs","storage/cache","storage/uploads","storage/sessions"];for(let N of p)n(s(u,N),{recursive:!0});this.info("Writing config files...");let{dirname:f}=await import("path"),{fileURLToPath:b}=await import("url"),C=s(f(f(f(b(import.meta.url)))),"package.json"),as=JSON.parse((await import("fs")).readFileSync(C,"utf-8")).version??"0.4.0";d("package.json",m.packageJson(c,as)),d("svelte.config.js",m.svelteConfig()),d("vite.config.ts",m.viteConfig()),d("tsconfig.json",m.tsConfig()),d("src/app.html",m.appHtml()),d("src/app.css",m.appCss()),d("src/app.ts",m.appTs()),d("src/hooks.server.ts",m.hooksServerTs()),d(".env.example",m.envExample());let{randomBytes:ye}=await import("crypto"),Be=ye(32).toString("hex"),ve=ye(16).toString("hex"),be=m.envExample().replace("APP_KEY=change-me-to-a-random-string",`APP_KEY=${Be}`).replace("INTERNAL_SECRET=change-me-to-a-random-string",`INTERNAL_SECRET=${ve}`);d(".env",be),d(".gitignore",m.gitignore()),d("svelar.database.json",m.svelarDatabaseJson());for(let N of["storage/logs","storage/cache","storage/uploads","storage/sessions"])d(`${N}/.gitkeep`,"");if(this.info("Scaffolding domain layer..."),d("src/lib/models/User.ts",m.userModel()),d("src/lib/models/Post.ts",m.postModel()),d("src/lib/repositories/UserRepository.ts",m.userRepository()),d("src/lib/repositories/PostRepository.ts",m.postRepository()),d("src/lib/services/AuthService.ts",m.authService()),d("src/lib/services/PostService.ts",m.postService()),d("src/lib/controllers/AuthController.ts",m.authController()),d("src/lib/controllers/PostController.ts",m.postController()),d("src/lib/controllers/AdminController.ts",m.adminController()),d("src/lib/dtos/RegisterRequest.ts",m.registerRequest()),d("src/lib/dtos/LoginRequest.ts",m.loginRequest()),d("src/lib/dtos/CreatePostRequest.ts",m.createPostRequest()),d("src/lib/dtos/UpdatePostRequest.ts",m.updatePostRequest()),d("src/lib/dtos/UpdateUserRoleRequest.ts",m.updateUserRoleRequest()),d("src/lib/dtos/DeleteUserRequest.ts",m.deleteUserRequest()),d("src/lib/dtos/CreateRoleRequest.ts",m.createRoleRequest()),d("src/lib/dtos/DeleteRoleRequest.ts",m.deleteRoleRequest()),d("src/lib/dtos/CreatePermissionRequest.ts",m.createPermissionRequest()),d("src/lib/dtos/DeletePermissionRequest.ts",m.deletePermissionRequest()),d("src/lib/dtos/RolePermissionRequest.ts",m.rolePermissionRequest()),d("src/lib/dtos/UserRoleRequest.ts",m.userRoleRequest()),d("src/lib/dtos/UserPermissionRequest.ts",m.userPermissionRequest()),d("src/lib/dtos/ExportDataRequest.ts",m.exportDataRequest()),d("src/lib/actions/RegisterUserAction.ts",m.registerUserAction()),d("src/lib/actions/CreatePostAction.ts",m.createPostAction()),d("src/lib/auth/gates.ts",m.gates()),d("src/lib/schemas/auth.ts",m.authSchema()),d("src/lib/schemas/post.ts",m.postSchema()),d("src/lib/schemas/admin.ts",m.adminSchema()),d("src/lib/services/AdminService.ts",m.adminService()),d("src/lib/resources/RoleResource.ts",m.roleResource()),d("src/lib/resources/PermissionResource.ts",m.permissionResource()),d("src/lib/shared/providers/EventServiceProvider.ts",m.eventServiceProvider()),d("src/lib/resources/UserResource.ts",m.userResource()),d("src/lib/resources/PostResource.ts",m.postResource()),d("src/lib/events/UserRegistered.ts",m.userRegisteredEvent()),d("src/lib/listeners/SendWelcomeEmailListener.ts",m.sendWelcomeEmailListener()),d("src/lib/notifications/WelcomeNotification.ts",m.welcomeNotification()),this.info("Creating migrations..."),d("src/lib/database/migrations/00000001_create_users_table.ts",m.createUsersTable()),d("src/lib/database/migrations/00000002_create_posts_table.ts",m.createPostsTable()),d("src/lib/database/migrations/00000003_create_permissions_tables.ts",m.createPermissionsTables()),d("src/lib/database/migrations/00000004_add_role_to_users.ts",m.addRoleToUsers()),d("src/lib/database/migrations/00000005_create_sessions_table.ts",m.createSessionsTable()),d("src/lib/database/migrations/00000006_create_audit_logs_table.ts",m.createAuditLogsTable()),d("src/lib/database/migrations/00000007_create_notifications_table.ts",m.createNotificationsTable()),d("src/lib/database/migrations/00000008_create_failed_jobs_table.ts",m.createFailedJobsTable()),d("src/lib/database/seeders/DatabaseSeeder.ts",m.databaseSeeder()),this.info("Creating auth pages..."),d("src/routes/login/+page.server.ts",m.loginPageServer()),d("src/routes/login/+page.svelte",m.loginPageSvelte()),d("src/routes/register/+page.server.ts",m.registerPageServer()),d("src/routes/register/+page.svelte",m.registerPageSvelte()),d("src/routes/logout/+page.server.ts",m.logoutPageServer()),d("src/routes/forgot-password/+page.server.ts",m.forgotPasswordPageServer()),d("src/routes/forgot-password/+page.svelte",m.forgotPasswordPageSvelte()),d("src/routes/reset-password/+page.server.ts",m.resetPasswordPageServer()),d("src/routes/reset-password/+page.svelte",m.resetPasswordPageSvelte()),d("src/routes/otp-login/+page.server.ts",m.otpLoginPageServer()),d("src/routes/otp-login/+page.svelte",m.otpLoginPageSvelte()),d("src/routes/verify-email/+page.server.ts",m.verifyEmailPageServer()),d("src/routes/verify-email/+page.svelte",m.verifyEmailPageSvelte()),this.info("Creating dashboard..."),d("src/routes/dashboard/+layout.server.ts",m.dashboardLayoutServer()),d("src/routes/dashboard/+layout.svelte",m.dashboardLayoutSvelte()),d("src/routes/dashboard/+page.server.ts",m.dashboardPageServer()),d("src/routes/dashboard/+page.svelte",m.dashboardPageSvelte()),d("src/routes/dashboard/api-keys/+page.server.ts",m.apiKeysPageServer()),d("src/routes/dashboard/api-keys/+page.svelte",m.apiKeysPageSvelte()),d("src/routes/dashboard/team/+page.server.ts",m.teamPageServer()),d("src/routes/dashboard/team/+page.svelte",m.teamPageSvelte()),this.info("Creating admin panel..."),d("src/routes/admin/+layout.server.ts",m.adminLayoutServer()),d("src/routes/admin/+layout.svelte",m.adminLayoutSvelte()),d("src/routes/admin/+page.server.ts",m.adminPageServer()),d("src/routes/admin/+page.svelte",m.adminPageSvelte()),this.info("Creating API routes..."),d("src/routes/api/health/+server.ts",m.apiHealth()),d("src/routes/api/auth/register/+server.ts",m.apiAuthRegister()),d("src/routes/api/auth/login/+server.ts",m.apiAuthLogin()),d("src/routes/api/auth/logout/+server.ts",m.apiAuthLogout()),d("src/routes/api/auth/me/+server.ts",m.apiAuthMe()),d("src/routes/api/auth/forgot-password/+server.ts",m.apiAuthForgotPassword()),d("src/routes/api/auth/reset-password/+server.ts",m.apiAuthResetPassword()),d("src/routes/api/auth/otp/send/+server.ts",m.apiAuthOtpSend()),d("src/routes/api/auth/otp/verify/+server.ts",m.apiAuthOtpVerify()),d("src/routes/api/auth/verify-email/+server.ts",m.apiAuthVerifyEmail()),d("src/routes/api/posts/+server.ts",m.apiPosts()),d("src/routes/api/posts/[id]/+server.ts",m.apiPostsSingle()),d("src/routes/api/posts/mine/+server.ts",m.apiPostsMine()),d("src/routes/api/broadcasting/[channel]/+server.ts",m.apiBroadcasting()),d("src/routes/api/internal/broadcast/+server.ts",m.apiInternalBroadcast()),d("src/routes/api/admin/users/+server.ts",m.apiAdminUsers()),d("src/routes/api/admin/roles/+server.ts",m.apiAdminRoles()),d("src/routes/api/admin/permissions/+server.ts",m.apiAdminPermissions()),d("src/routes/api/admin/role-permissions/+server.ts",m.apiAdminRolePermissions()),d("src/routes/api/admin/user-roles/+server.ts",m.apiAdminUserRoles()),d("src/routes/api/admin/user-permissions/+server.ts",m.apiAdminUserPermissions()),d("src/routes/api/admin/export/+server.ts",m.apiAdminExport()),d("src/routes/api/admin/health/+server.ts",m.apiAdminHealth()),d("src/routes/api/admin/queue/+server.ts",m.apiAdminQueue()),d("src/routes/api/admin/queue/[id]/retry/+server.ts",m.apiAdminQueueRetry()),d("src/routes/api/admin/queue/[id]/+server.ts",m.apiAdminQueueDelete()),d("src/routes/api/admin/scheduler/+server.ts",m.apiAdminScheduler()),d("src/routes/api/admin/scheduler/[name]/run/+server.ts",m.apiAdminSchedulerRun()),d("src/routes/api/admin/scheduler/[name]/toggle/+server.ts",m.apiAdminSchedulerToggle()),d("src/routes/api/admin/logs/+server.ts",m.apiAdminLogs()),d("src/routes/api/admin/stats/+server.ts",m.apiAdminStats()),this.info("Creating background jobs..."),d("src/lib/shared/jobs/SendWelcomeEmail.ts",m.sendWelcomeEmail()),d("src/lib/shared/jobs/DailyDigestJob.ts",m.dailyDigestJob()),d("src/lib/shared/jobs/ExportDataJob.ts",m.exportDataJob()),this.info("Creating scheduled tasks..."),d("src/lib/shared/scheduler/CleanupExpiredTokens.ts",m.cleanupExpiredTokens()),d("src/lib/shared/scheduler/CleanExpiredSessions.ts",m.cleanExpiredSessions()),d("src/lib/shared/scheduler/DailyDigestEmail.ts",m.dailyDigestEmail()),d("src/lib/shared/scheduler/PruneAuditLogs.ts",m.pruneAuditLogs()),d("src/lib/shared/scheduler/QueueHealthCheck.ts",m.queueHealthCheck()),this.info("Creating layouts..."),d("src/routes/+layout.svelte",m.rootLayoutSvelte(c)),d("src/routes/+layout.server.ts",m.rootLayoutServer()),d("src/routes/+error.svelte",m.errorSvelte()),d("src/routes/+page.svelte",m.homePage(c)),this.success("Project structure created"),!t["no-install"]){this.info("Installing dependencies...");try{o("npm install",{cwd:u,stdio:"inherit"}),this.success("Dependencies installed")}catch{this.warn("npm install failed \u2014 run it manually with: cd "+c+" && npm install")}this.info("Running migrations...");try{o("npx svelar migrate",{cwd:u,stdio:"inherit"}),this.success("Migrations complete")}catch{this.warn("Migrations failed \u2014 run manually: cd "+c+" && npx svelar migrate")}this.info("Seeding database...");try{o("npx svelar seed:run",{cwd:u,stdio:"inherit"}),this.success("Database seeded")}catch{this.warn("Seeding failed \u2014 run manually: cd "+c+" && npx svelar seed:run")}}this.log(""),this.log(` \x1B[32m+\x1B[0m Project \x1B[1m${c}\x1B[0m created successfully!
|
|
6646
|
+
`}static addStripeToUsers(){return`import { Migration } from '@beeblock/svelar/database';
|
|
6647
|
+
|
|
6648
|
+
export default class AddStripeToUsers extends Migration {
|
|
6649
|
+
async up() {
|
|
6650
|
+
await this.schema.alterTable('users', (table) => {
|
|
6651
|
+
table.string('stripe_customer_id').nullable();
|
|
6652
|
+
});
|
|
6653
|
+
}
|
|
6654
|
+
|
|
6655
|
+
async down() {
|
|
6656
|
+
await this.schema.alterTable('users', (table) => {
|
|
6657
|
+
table.dropColumn('stripe_customer_id');
|
|
6658
|
+
});
|
|
6659
|
+
}
|
|
6660
|
+
}
|
|
6661
|
+
`}static createSubscriptionPlansTable(){return`import { Migration } from '@beeblock/svelar/database';
|
|
6662
|
+
|
|
6663
|
+
export default class CreateSubscriptionPlansTable extends Migration {
|
|
6664
|
+
async up() {
|
|
6665
|
+
await this.schema.createTable('subscription_plans', (table) => {
|
|
6666
|
+
table.increments('id').primary();
|
|
6667
|
+
table.string('name');
|
|
6668
|
+
table.string('stripe_price_id').unique();
|
|
6669
|
+
table.string('stripe_product_id');
|
|
6670
|
+
table.integer('price');
|
|
6671
|
+
table.string('currency').defaultTo('usd');
|
|
6672
|
+
table.string('interval').defaultTo('month');
|
|
6673
|
+
table.integer('interval_count').defaultTo(1);
|
|
6674
|
+
table.integer('trial_days').defaultTo(0);
|
|
6675
|
+
table.text('features').defaultTo('[]');
|
|
6676
|
+
table.integer('sort_order').defaultTo(0);
|
|
6677
|
+
table.integer('active').defaultTo(1);
|
|
6678
|
+
table.string('created_at');
|
|
6679
|
+
table.string('updated_at');
|
|
6680
|
+
});
|
|
6681
|
+
}
|
|
6682
|
+
|
|
6683
|
+
async down() {
|
|
6684
|
+
await this.schema.dropTable('subscription_plans');
|
|
6685
|
+
}
|
|
6686
|
+
}
|
|
6687
|
+
`}static createSubscriptionsTable(){return`import { Migration } from '@beeblock/svelar/database';
|
|
6688
|
+
|
|
6689
|
+
export default class CreateSubscriptionsTable extends Migration {
|
|
6690
|
+
async up() {
|
|
6691
|
+
await this.schema.createTable('subscriptions', (table) => {
|
|
6692
|
+
table.increments('id').primary();
|
|
6693
|
+
table.integer('user_id');
|
|
6694
|
+
table.string('stripe_subscription_id').unique();
|
|
6695
|
+
table.string('stripe_customer_id');
|
|
6696
|
+
table.integer('plan_id');
|
|
6697
|
+
table.string('status').defaultTo('active');
|
|
6698
|
+
table.string('current_period_start');
|
|
6699
|
+
table.string('current_period_end');
|
|
6700
|
+
table.integer('cancel_at_period_end').defaultTo(0);
|
|
6701
|
+
table.string('trial_ends_at').nullable();
|
|
6702
|
+
table.string('canceled_at').nullable();
|
|
6703
|
+
table.string('created_at');
|
|
6704
|
+
table.string('updated_at');
|
|
6705
|
+
});
|
|
6706
|
+
}
|
|
6707
|
+
|
|
6708
|
+
async down() {
|
|
6709
|
+
await this.schema.dropTable('subscriptions');
|
|
6710
|
+
}
|
|
6711
|
+
}
|
|
6712
|
+
`}static createInvoicesTable(){return`import { Migration } from '@beeblock/svelar/database';
|
|
6713
|
+
|
|
6714
|
+
export default class CreateInvoicesTable extends Migration {
|
|
6715
|
+
async up() {
|
|
6716
|
+
await this.schema.createTable('invoices', (table) => {
|
|
6717
|
+
table.increments('id').primary();
|
|
6718
|
+
table.integer('user_id');
|
|
6719
|
+
table.integer('subscription_id').nullable();
|
|
6720
|
+
table.string('stripe_invoice_id').unique();
|
|
6721
|
+
table.integer('amount_due');
|
|
6722
|
+
table.integer('amount_paid');
|
|
6723
|
+
table.string('currency').defaultTo('usd');
|
|
6724
|
+
table.string('status').defaultTo('open');
|
|
6725
|
+
table.string('paid_at').nullable();
|
|
6726
|
+
table.string('due_date').nullable();
|
|
6727
|
+
table.text('invoice_pdf').nullable();
|
|
6728
|
+
table.string('created_at');
|
|
6729
|
+
table.string('updated_at').nullable();
|
|
6730
|
+
});
|
|
6731
|
+
}
|
|
6732
|
+
|
|
6733
|
+
async down() {
|
|
6734
|
+
await this.schema.dropTable('invoices');
|
|
6735
|
+
}
|
|
6736
|
+
}
|
|
6737
|
+
`}static billingPageServer(){return`import type { Actions, PageServerLoad } from './$types';
|
|
6738
|
+
import { fail, redirect } from '@sveltejs/kit';
|
|
6739
|
+
import { Stripe } from '@beeblock/svelar/stripe';
|
|
6740
|
+
|
|
6741
|
+
export const load: PageServerLoad = async ({ locals }) => {
|
|
6742
|
+
const user = locals.user as any;
|
|
6743
|
+
let subscription: any = null;
|
|
6744
|
+
let invoices: any[] = [];
|
|
6745
|
+
const plans: any[] = [];
|
|
6746
|
+
|
|
6747
|
+
try {
|
|
6748
|
+
const service = Stripe.service();
|
|
6749
|
+
if (user.stripe_customer_id) {
|
|
6750
|
+
const client = await service.getClient();
|
|
6751
|
+
const subs = await client.subscriptions.list({
|
|
6752
|
+
customer: user.stripe_customer_id,
|
|
6753
|
+
limit: 1,
|
|
6754
|
+
expand: ['data.default_payment_method'],
|
|
6755
|
+
});
|
|
6756
|
+
if (subs.data.length > 0) {
|
|
6757
|
+
const sub = subs.data[0] as any;
|
|
6758
|
+
subscription = {
|
|
6759
|
+
id: sub.id,
|
|
6760
|
+
status: sub.status,
|
|
6761
|
+
cancelAtPeriodEnd: sub.cancel_at_period_end,
|
|
6762
|
+
currentPeriodEnd: sub.current_period_end
|
|
6763
|
+
? new Date(typeof sub.current_period_end === 'number' ? sub.current_period_end * 1000 : sub.current_period_end).toISOString()
|
|
6764
|
+
: null,
|
|
6765
|
+
trialEnd: sub.trial_end
|
|
6766
|
+
? new Date(typeof sub.trial_end === 'number' ? sub.trial_end * 1000 : sub.trial_end).toISOString()
|
|
6767
|
+
: null,
|
|
6768
|
+
plan: {
|
|
6769
|
+
nickname: sub.items?.data?.[0]?.price?.nickname ?? 'Plan',
|
|
6770
|
+
amount: sub.items?.data?.[0]?.price?.unit_amount ?? 0,
|
|
6771
|
+
currency: sub.items?.data?.[0]?.price?.currency ?? 'usd',
|
|
6772
|
+
interval: sub.items?.data?.[0]?.price?.recurring?.interval ?? 'month',
|
|
6773
|
+
},
|
|
6774
|
+
};
|
|
6775
|
+
}
|
|
6776
|
+
|
|
6777
|
+
const invResponse = await service.getInvoices(user.stripe_customer_id, 10);
|
|
6778
|
+
invoices = invResponse.map((inv: any) => ({
|
|
6779
|
+
id: inv.id,
|
|
6780
|
+
amountDue: inv.amount_due,
|
|
6781
|
+
amountPaid: inv.amount_paid,
|
|
6782
|
+
currency: inv.currency,
|
|
6783
|
+
status: inv.status,
|
|
6784
|
+
created: new Date(typeof inv.created === 'number' ? inv.created * 1000 : inv.created).toISOString(),
|
|
6785
|
+
invoicePdf: inv.invoice_pdf ?? null,
|
|
6786
|
+
hostedUrl: inv.hosted_invoice_url ?? null,
|
|
6787
|
+
}));
|
|
6788
|
+
}
|
|
6789
|
+
} catch {}
|
|
6790
|
+
|
|
6791
|
+
return { user: { id: user.id, name: user.name, email: user.email, stripeCustomerId: user.stripe_customer_id }, subscription, invoices, plans };
|
|
6792
|
+
};
|
|
6793
|
+
|
|
6794
|
+
export const actions: Actions = {
|
|
6795
|
+
portal: async ({ locals }) => {
|
|
6796
|
+
const user = locals.user as any;
|
|
6797
|
+
if (!user?.stripe_customer_id) return fail(400, { error: 'No billing account' });
|
|
6798
|
+
|
|
6799
|
+
try {
|
|
6800
|
+
const session = await Stripe.service().createPortalSession(
|
|
6801
|
+
user.stripe_customer_id,
|
|
6802
|
+
'/dashboard/billing',
|
|
6803
|
+
);
|
|
6804
|
+
throw redirect(303, session.url);
|
|
6805
|
+
} catch (e: any) {
|
|
6806
|
+
if (e.status === 303) throw e;
|
|
6807
|
+
return fail(500, { error: e.message ?? 'Failed to open portal' });
|
|
6808
|
+
}
|
|
6809
|
+
},
|
|
6810
|
+
|
|
6811
|
+
cancel: async ({ locals }) => {
|
|
6812
|
+
const user = locals.user as any;
|
|
6813
|
+
if (!user?.stripe_customer_id) return fail(400, { error: 'No billing account' });
|
|
6814
|
+
|
|
6815
|
+
try {
|
|
6816
|
+
const client = await Stripe.service().getClient();
|
|
6817
|
+
const subs = await client.subscriptions.list({ customer: user.stripe_customer_id, status: 'active', limit: 1 });
|
|
6818
|
+
if (subs.data.length === 0) return fail(400, { error: 'No active subscription' });
|
|
6819
|
+
await Stripe.service().cancelSubscription(subs.data[0].id, false);
|
|
6820
|
+
return { success: true, canceled: true };
|
|
6821
|
+
} catch (e: any) {
|
|
6822
|
+
return fail(500, { error: e.message ?? 'Failed to cancel' });
|
|
6823
|
+
}
|
|
6824
|
+
},
|
|
6825
|
+
|
|
6826
|
+
resume: async ({ locals }) => {
|
|
6827
|
+
const user = locals.user as any;
|
|
6828
|
+
if (!user?.stripe_customer_id) return fail(400, { error: 'No billing account' });
|
|
6829
|
+
|
|
6830
|
+
try {
|
|
6831
|
+
const client = await Stripe.service().getClient();
|
|
6832
|
+
const subs = await client.subscriptions.list({ customer: user.stripe_customer_id, limit: 1 });
|
|
6833
|
+
if (subs.data.length === 0) return fail(400, { error: 'No subscription found' });
|
|
6834
|
+
await Stripe.service().resumeSubscription(subs.data[0].id);
|
|
6835
|
+
return { success: true, resumed: true };
|
|
6836
|
+
} catch (e: any) {
|
|
6837
|
+
return fail(500, { error: e.message ?? 'Failed to resume' });
|
|
6838
|
+
}
|
|
6839
|
+
},
|
|
6840
|
+
};
|
|
6841
|
+
`}static billingPageSvelte(){return`<script lang="ts">
|
|
6842
|
+
import { enhance } from '\\$app/forms';
|
|
6843
|
+
import { Button, Badge, Card, CardHeader, CardTitle, CardContent, Alert } from '@beeblock/svelar/ui';
|
|
6844
|
+
|
|
6845
|
+
let { data, form: actionData } = \\$props();
|
|
6846
|
+
|
|
6847
|
+
function formatCurrency(amount: number, currency: string): string {
|
|
6848
|
+
return new Intl.NumberFormat('en-US', { style: 'currency', currency: currency.toUpperCase() }).format(amount / 100);
|
|
6849
|
+
}
|
|
6850
|
+
|
|
6851
|
+
function statusColor(status: string): 'default' | 'secondary' | 'destructive' {
|
|
6852
|
+
if (status === 'active' || status === 'trialing' || status === 'paid') return 'default';
|
|
6853
|
+
if (status === 'past_due' || status === 'incomplete') return 'secondary';
|
|
6854
|
+
return 'destructive';
|
|
6855
|
+
}
|
|
6856
|
+
</script>
|
|
6857
|
+
|
|
6858
|
+
<svelte:head>
|
|
6859
|
+
<title>Billing</title>
|
|
6860
|
+
</svelte:head>
|
|
6861
|
+
|
|
6862
|
+
<div class="space-y-8">
|
|
6863
|
+
<div>
|
|
6864
|
+
<h1 class="text-3xl font-bold text-gray-900">Billing</h1>
|
|
6865
|
+
<p class="text-gray-600 mt-1">Manage your subscription and billing</p>
|
|
6866
|
+
</div>
|
|
6867
|
+
|
|
6868
|
+
{#if actionData?.error}
|
|
6869
|
+
<Alert variant="destructive"><span class="text-sm">{actionData.error}</span></Alert>
|
|
6870
|
+
{/if}
|
|
6871
|
+
{#if actionData?.canceled}
|
|
6872
|
+
<Alert variant="default"><span class="text-sm">Subscription will cancel at end of billing period.</span></Alert>
|
|
6873
|
+
{/if}
|
|
6874
|
+
{#if actionData?.resumed}
|
|
6875
|
+
<Alert variant="default"><span class="text-sm">Subscription resumed successfully.</span></Alert>
|
|
6876
|
+
{/if}
|
|
6877
|
+
|
|
6878
|
+
<Card>
|
|
6879
|
+
<CardHeader>
|
|
6880
|
+
<CardTitle>Current Plan</CardTitle>
|
|
6881
|
+
</CardHeader>
|
|
6882
|
+
<CardContent>
|
|
6883
|
+
{#if data.subscription}
|
|
6884
|
+
<div class="flex items-start justify-between">
|
|
6885
|
+
<div>
|
|
6886
|
+
<div class="flex items-center gap-2 mb-2">
|
|
6887
|
+
<h3 class="text-xl font-semibold text-gray-900">{data.subscription.plan.nickname}</h3>
|
|
6888
|
+
<Badge variant={statusColor(data.subscription.status)}>{data.subscription.status}</Badge>
|
|
6889
|
+
</div>
|
|
6890
|
+
<p class="text-2xl font-bold text-brand">
|
|
6891
|
+
{formatCurrency(data.subscription.plan.amount, data.subscription.plan.currency)}/{data.subscription.plan.interval}
|
|
6892
|
+
</p>
|
|
6893
|
+
{#if data.subscription.trialEnd}
|
|
6894
|
+
<p class="text-sm text-gray-500 mt-1">Trial ends {new Date(data.subscription.trialEnd).toLocaleDateString()}</p>
|
|
6895
|
+
{/if}
|
|
6896
|
+
{#if data.subscription.cancelAtPeriodEnd}
|
|
6897
|
+
<p class="text-sm text-orange-600 mt-1">Cancels on {new Date(data.subscription.currentPeriodEnd).toLocaleDateString()}</p>
|
|
6898
|
+
{:else if data.subscription.currentPeriodEnd}
|
|
6899
|
+
<p class="text-sm text-gray-500 mt-1">Renews {new Date(data.subscription.currentPeriodEnd).toLocaleDateString()}</p>
|
|
6900
|
+
{/if}
|
|
6901
|
+
</div>
|
|
6902
|
+
<div class="flex flex-col gap-2">
|
|
6903
|
+
<form method="POST" action="?/portal" use:enhance>
|
|
6904
|
+
<Button type="submit" variant="outline" size="sm">Manage Payment</Button>
|
|
6905
|
+
</form>
|
|
6906
|
+
{#if data.subscription.cancelAtPeriodEnd}
|
|
6907
|
+
<form method="POST" action="?/resume" use:enhance>
|
|
6908
|
+
<Button type="submit" size="sm">Resume</Button>
|
|
6909
|
+
</form>
|
|
6910
|
+
{:else if data.subscription.status === 'active' || data.subscription.status === 'trialing'}
|
|
6911
|
+
<form method="POST" action="?/cancel" use:enhance>
|
|
6912
|
+
<Button type="submit" variant="destructive" size="sm"
|
|
6913
|
+
onclick={(e) => { if (!confirm('Cancel your subscription? You will retain access until the end of the billing period.')) e.preventDefault(); }}>
|
|
6914
|
+
Cancel Plan
|
|
6915
|
+
</Button>
|
|
6916
|
+
</form>
|
|
6917
|
+
{/if}
|
|
6918
|
+
</div>
|
|
6919
|
+
</div>
|
|
6920
|
+
{:else}
|
|
6921
|
+
<div class="text-center py-6">
|
|
6922
|
+
<p class="text-gray-500 mb-4">No active subscription</p>
|
|
6923
|
+
<p class="text-sm text-gray-400">Contact us or visit the pricing page to get started.</p>
|
|
6924
|
+
</div>
|
|
6925
|
+
{/if}
|
|
6926
|
+
</CardContent>
|
|
6927
|
+
</Card>
|
|
6928
|
+
|
|
6929
|
+
<div>
|
|
6930
|
+
<h2 class="text-xl font-bold text-gray-900 mb-4">Invoice History</h2>
|
|
6931
|
+
{#if data.invoices.length === 0}
|
|
6932
|
+
<Card>
|
|
6933
|
+
<CardContent class="pt-8 text-center">
|
|
6934
|
+
<p class="text-gray-500 text-sm">No invoices yet.</p>
|
|
6935
|
+
</CardContent>
|
|
6936
|
+
</Card>
|
|
6937
|
+
{:else}
|
|
6938
|
+
<div class="border rounded-lg overflow-hidden">
|
|
6939
|
+
<table class="w-full text-sm">
|
|
6940
|
+
<thead class="bg-gray-50 text-left">
|
|
6941
|
+
<tr>
|
|
6942
|
+
<th class="px-4 py-3 text-gray-600 font-medium">Date</th>
|
|
6943
|
+
<th class="px-4 py-3 text-gray-600 font-medium">Amount</th>
|
|
6944
|
+
<th class="px-4 py-3 text-gray-600 font-medium">Status</th>
|
|
6945
|
+
<th class="px-4 py-3 text-gray-600 font-medium text-right">Invoice</th>
|
|
6946
|
+
</tr>
|
|
6947
|
+
</thead>
|
|
6948
|
+
<tbody class="divide-y">
|
|
6949
|
+
{#each data.invoices as inv (inv.id)}
|
|
6950
|
+
<tr class="hover:bg-gray-50">
|
|
6951
|
+
<td class="px-4 py-3">{new Date(inv.created).toLocaleDateString()}</td>
|
|
6952
|
+
<td class="px-4 py-3 font-medium">{formatCurrency(inv.amountDue, inv.currency)}</td>
|
|
6953
|
+
<td class="px-4 py-3"><Badge variant={statusColor(inv.status)}>{inv.status}</Badge></td>
|
|
6954
|
+
<td class="px-4 py-3 text-right">
|
|
6955
|
+
{#if inv.invoicePdf}
|
|
6956
|
+
<a href={inv.invoicePdf} target="_blank" rel="noopener" class="text-brand hover:underline text-xs">PDF</a>
|
|
6957
|
+
{/if}
|
|
6958
|
+
{#if inv.hostedUrl}
|
|
6959
|
+
<a href={inv.hostedUrl} target="_blank" rel="noopener" class="text-brand hover:underline text-xs ml-2">View</a>
|
|
6960
|
+
{/if}
|
|
6961
|
+
</td>
|
|
6962
|
+
</tr>
|
|
6963
|
+
{/each}
|
|
6964
|
+
</tbody>
|
|
6965
|
+
</table>
|
|
6966
|
+
</div>
|
|
6967
|
+
{/if}
|
|
6968
|
+
</div>
|
|
6969
|
+
</div>
|
|
6970
|
+
`}static stripeWebhookRoute(){return`import type { RequestHandler } from './$types';
|
|
6971
|
+
import { Stripe } from '@beeblock/svelar/stripe';
|
|
6972
|
+
|
|
6973
|
+
export const POST: RequestHandler = async ({ request }) => {
|
|
6974
|
+
const signature = request.headers.get('stripe-signature');
|
|
6975
|
+
if (!signature) {
|
|
6976
|
+
return new Response(JSON.stringify({ error: 'Missing signature' }), { status: 400 });
|
|
6977
|
+
}
|
|
6978
|
+
|
|
6979
|
+
try {
|
|
6980
|
+
const body = await request.text();
|
|
6981
|
+
const event = await Stripe.service().constructWebhookEvent(body, signature);
|
|
6982
|
+
await Stripe.webhooks().handle(event);
|
|
6983
|
+
return new Response(JSON.stringify({ received: true }), { status: 200 });
|
|
6984
|
+
} catch (err: any) {
|
|
6985
|
+
console.error('Stripe webhook error:', err.message);
|
|
6986
|
+
return new Response(JSON.stringify({ error: 'Webhook failed' }), { status: 400 });
|
|
6987
|
+
}
|
|
6988
|
+
};
|
|
6989
|
+
`}static apiAdminBillingSubscriptions(){return`import type { RequestHandler } from './$types';
|
|
6990
|
+
import { Stripe } from '@beeblock/svelar/stripe';
|
|
6991
|
+
|
|
6992
|
+
export const GET: RequestHandler = async ({ url }) => {
|
|
6993
|
+
try {
|
|
6994
|
+
const limit = Number(url.searchParams.get('limit') ?? '25');
|
|
6995
|
+
const startingAfter = url.searchParams.get('starting_after') ?? undefined;
|
|
6996
|
+
const client = await Stripe.service().getClient();
|
|
6997
|
+
const subs = await client.subscriptions.list({
|
|
6998
|
+
limit,
|
|
6999
|
+
starting_after: startingAfter,
|
|
7000
|
+
expand: ['data.customer'],
|
|
7001
|
+
});
|
|
7002
|
+
|
|
7003
|
+
const data = subs.data.map((sub: any) => ({
|
|
7004
|
+
id: sub.id,
|
|
7005
|
+
status: sub.status,
|
|
7006
|
+
cancelAtPeriodEnd: sub.cancel_at_period_end,
|
|
7007
|
+
customer: {
|
|
7008
|
+
id: typeof sub.customer === 'string' ? sub.customer : sub.customer?.id,
|
|
7009
|
+
email: typeof sub.customer === 'object' ? sub.customer?.email : null,
|
|
7010
|
+
name: typeof sub.customer === 'object' ? sub.customer?.name : null,
|
|
7011
|
+
},
|
|
7012
|
+
plan: {
|
|
7013
|
+
nickname: sub.items?.data?.[0]?.price?.nickname ?? 'Plan',
|
|
7014
|
+
amount: sub.items?.data?.[0]?.price?.unit_amount ?? 0,
|
|
7015
|
+
currency: sub.items?.data?.[0]?.price?.currency ?? 'usd',
|
|
7016
|
+
interval: sub.items?.data?.[0]?.price?.recurring?.interval ?? 'month',
|
|
7017
|
+
},
|
|
7018
|
+
created: sub.created,
|
|
7019
|
+
}));
|
|
7020
|
+
|
|
7021
|
+
return new Response(JSON.stringify({ subscriptions: data, hasMore: subs.has_more }), {
|
|
7022
|
+
headers: { 'Content-Type': 'application/json' },
|
|
7023
|
+
});
|
|
7024
|
+
} catch (err: any) {
|
|
7025
|
+
return new Response(JSON.stringify({ error: err.message }), { status: 500 });
|
|
7026
|
+
}
|
|
7027
|
+
};
|
|
7028
|
+
`}static apiAdminBillingRefund(){return`import type { RequestHandler } from './$types';
|
|
7029
|
+
import { Stripe } from '@beeblock/svelar/stripe';
|
|
7030
|
+
|
|
7031
|
+
export const POST: RequestHandler = async ({ request }) => {
|
|
7032
|
+
try {
|
|
7033
|
+
const { invoiceId } = await request.json();
|
|
7034
|
+
if (!invoiceId) {
|
|
7035
|
+
return new Response(JSON.stringify({ error: 'invoiceId is required' }), { status: 400 });
|
|
7036
|
+
}
|
|
7037
|
+
|
|
7038
|
+
const refund = await Stripe.service().refundInvoice(invoiceId);
|
|
7039
|
+
return new Response(JSON.stringify({ refund: { id: refund.id, amount: refund.amount, status: refund.status } }), {
|
|
7040
|
+
headers: { 'Content-Type': 'application/json' },
|
|
7041
|
+
});
|
|
7042
|
+
} catch (err: any) {
|
|
7043
|
+
return new Response(JSON.stringify({ error: err.message }), { status: 500 });
|
|
7044
|
+
}
|
|
7045
|
+
};
|
|
7046
|
+
`}static apiAdminBillingCancel(){return`import type { RequestHandler } from './$types';
|
|
7047
|
+
import { Stripe } from '@beeblock/svelar/stripe';
|
|
7048
|
+
|
|
7049
|
+
export const POST: RequestHandler = async ({ request }) => {
|
|
7050
|
+
try {
|
|
7051
|
+
const { subscriptionId, immediately } = await request.json();
|
|
7052
|
+
if (!subscriptionId) {
|
|
7053
|
+
return new Response(JSON.stringify({ error: 'subscriptionId is required' }), { status: 400 });
|
|
7054
|
+
}
|
|
7055
|
+
|
|
7056
|
+
const sub = await Stripe.service().cancelSubscription(subscriptionId, immediately ?? false);
|
|
7057
|
+
return new Response(JSON.stringify({ subscription: { id: sub.id, status: sub.status, cancel_at_period_end: sub.cancel_at_period_end } }), {
|
|
7058
|
+
headers: { 'Content-Type': 'application/json' },
|
|
7059
|
+
});
|
|
7060
|
+
} catch (err: any) {
|
|
7061
|
+
return new Response(JSON.stringify({ error: err.message }), { status: 500 });
|
|
7062
|
+
}
|
|
7063
|
+
};
|
|
7064
|
+
`}};var ss=class extends g{name="new";description="Create a new SvelteKit project with Svelar pre-configured";arguments=["name"];flags=[{name:"no-install",alias:"n",description:"Skip npm install",type:"boolean",default:!1},{name:"flat",description:"Use flat folder structure instead of DDD modules",type:"boolean",default:!1}];async handle(e,t){let{join:s,resolve:r}=await import("path"),{existsSync:i,mkdirSync:n,writeFileSync:a}=await import("fs"),{execSync:l}=await import("child_process"),c=e[0];c||(this.error("Please provide a project name: npx svelar new my-app"),process.exit(1));let u=r(process.cwd(),c);i(u)&&(this.error(`Directory "${c}" already exists.`),process.exit(1));let m=t.flat||!1,h=m?"flat":"DDD modular";this.log(""),this.log(` \x1B[1m\x1B[38;5;208m</> Svelar\x1B[0m \u2014 Creating new project (${h})
|
|
7065
|
+
`);let d=($,Be)=>{let us=m?yo($):$,Fe=m?vo(Be,$):Be,He=s(u,us);n(s(He,".."),{recursive:!0}),a(He,Fe)};this.info("Creating project structure...");let b=m?["","src","src/lib","src/lib/models","src/lib/services","src/lib/controllers","src/lib/repositories","src/lib/dtos","src/lib/actions","src/lib/resources","src/lib/events","src/lib/listeners","src/lib/notifications","src/lib/schemas","src/lib/jobs","src/lib/scheduler","src/lib/middleware","src/lib/components","src/lib/stores","src/lib/plugins","src/lib/channels","src/lib/commands","src/lib/providers","src/lib/database/migrations","src/lib/database/seeders","src/routes","src/routes/api","static","storage/logs","storage/cache","storage/uploads","storage/sessions"]:["","src","src/lib","src/lib/modules/auth","src/lib/modules/posts","src/lib/modules/admin","src/lib/shared/jobs","src/lib/shared/scheduler","src/lib/shared/middleware","src/lib/shared/components","src/lib/shared/stores","src/lib/shared/plugins","src/lib/shared/channels","src/lib/shared/commands","src/lib/shared/providers","src/lib/database/migrations","src/lib/database/seeders","src/routes","src/routes/api","static","storage/logs","storage/cache","storage/uploads","storage/sessions"];for(let $ of b)n(s(u,$),{recursive:!0});this.info("Writing config files...");let{dirname:w}=await import("path"),{fileURLToPath:E}=await import("url"),cs=s(w(w(w(E(import.meta.url)))),"package.json"),Ue=JSON.parse((await import("fs")).readFileSync(cs,"utf-8")).version??"0.4.0";d("package.json",p.packageJson(c,Ue)),d("svelte.config.js",p.svelteConfig()),d("vite.config.ts",p.viteConfig()),d("tsconfig.json",p.tsConfig()),d("src/app.html",p.appHtml()),d("static/favicon.svg",p.faviconSvg()),d("src/app.css",p.appCss()),d("src/app.ts",p.appTs()),d("src/hooks.server.ts",p.hooksServerTs()),d(".env.example",p.envExample());let{randomBytes:z}=await import("crypto"),fe=z(32).toString("hex"),be=z(16).toString("hex"),_r=p.envExample().replace("APP_KEY=change-me-to-a-random-string",`APP_KEY=${fe}`).replace("INTERNAL_SECRET=change-me-to-a-random-string",`INTERNAL_SECRET=${be}`);d(".env",_r),d(".gitignore",p.gitignore()),d("svelar.database.json",p.svelarDatabaseJson());for(let $ of["storage/logs","storage/cache","storage/uploads","storage/sessions"])d(`${$}/.gitkeep`,"");if(this.info("Scaffolding domain layer..."),d("src/lib/modules/auth/User.ts",p.userModel()),d("src/lib/modules/auth/UserRepository.ts",p.userRepository()),d("src/lib/modules/auth/AuthService.ts",p.authService()),d("src/lib/modules/auth/AuthController.ts",p.authController()),d("src/lib/modules/auth/RegisterUserAction.ts",p.registerUserAction()),d("src/lib/modules/auth/RegisterRequest.ts",p.registerRequest()),d("src/lib/modules/auth/LoginRequest.ts",p.loginRequest()),d("src/lib/modules/auth/ForgotPasswordRequest.ts",p.forgotPasswordRequest()),d("src/lib/modules/auth/ResetPasswordRequest.ts",p.resetPasswordRequest()),d("src/lib/modules/auth/OtpSendRequest.ts",p.otpSendRequest()),d("src/lib/modules/auth/OtpVerifyRequest.ts",p.otpVerifyRequest()),d("src/lib/modules/auth/UserResource.ts",p.userResource()),d("src/lib/modules/auth/gates.ts",p.gates()),d("src/lib/modules/auth/schemas.ts",p.authSchema()),d("src/lib/modules/auth/UserRegistered.ts",p.userRegisteredEvent()),d("src/lib/modules/auth/SendWelcomeEmailListener.ts",p.sendWelcomeEmailListener()),d("src/lib/modules/auth/WelcomeNotification.ts",p.welcomeNotification()),d("src/lib/modules/posts/Post.ts",p.postModel()),d("src/lib/modules/posts/PostRepository.ts",p.postRepository()),d("src/lib/modules/posts/PostService.ts",p.postService()),d("src/lib/modules/posts/PostController.ts",p.postController()),d("src/lib/modules/posts/CreatePostAction.ts",p.createPostAction()),d("src/lib/modules/posts/CreatePostRequest.ts",p.createPostRequest()),d("src/lib/modules/posts/UpdatePostRequest.ts",p.updatePostRequest()),d("src/lib/modules/posts/PostResource.ts",p.postResource()),d("src/lib/modules/posts/schemas.ts",p.postSchema()),d("src/lib/modules/admin/AdminService.ts",p.adminService()),d("src/lib/modules/admin/AdminController.ts",p.adminController()),d("src/lib/modules/admin/UpdateUserRoleRequest.ts",p.updateUserRoleRequest()),d("src/lib/modules/admin/DeleteUserRequest.ts",p.deleteUserRequest()),d("src/lib/modules/admin/CreateRoleRequest.ts",p.createRoleRequest()),d("src/lib/modules/admin/DeleteRoleRequest.ts",p.deleteRoleRequest()),d("src/lib/modules/admin/CreatePermissionRequest.ts",p.createPermissionRequest()),d("src/lib/modules/admin/DeletePermissionRequest.ts",p.deletePermissionRequest()),d("src/lib/modules/admin/RolePermissionRequest.ts",p.rolePermissionRequest()),d("src/lib/modules/admin/UserRoleRequest.ts",p.userRoleRequest()),d("src/lib/modules/admin/UserPermissionRequest.ts",p.userPermissionRequest()),d("src/lib/modules/admin/ExportDataRequest.ts",p.exportDataRequest()),d("src/lib/modules/admin/RoleResource.ts",p.roleResource()),d("src/lib/modules/admin/PermissionResource.ts",p.permissionResource()),d("src/lib/modules/admin/schemas.ts",p.adminSchema()),d("src/lib/shared/providers/EventServiceProvider.ts",p.eventServiceProvider()),this.info("Creating migrations..."),d("src/lib/database/migrations/00000001_create_users_table.ts",p.createUsersTable()),d("src/lib/database/migrations/00000002_create_posts_table.ts",p.createPostsTable()),d("src/lib/database/migrations/00000003_create_permissions_tables.ts",p.createPermissionsTables()),d("src/lib/database/migrations/00000004_add_role_to_users.ts",p.addRoleToUsers()),d("src/lib/database/migrations/00000005_create_sessions_table.ts",p.createSessionsTable()),d("src/lib/database/migrations/00000006_create_audit_logs_table.ts",p.createAuditLogsTable()),d("src/lib/database/migrations/00000007_create_notifications_table.ts",p.createNotificationsTable()),d("src/lib/database/migrations/00000008_create_failed_jobs_table.ts",p.createFailedJobsTable()),d("src/lib/database/migrations/00000009_add_stripe_to_users.ts",p.addStripeToUsers()),d("src/lib/database/migrations/00000010_create_subscription_plans.ts",p.createSubscriptionPlansTable()),d("src/lib/database/migrations/00000011_create_subscriptions.ts",p.createSubscriptionsTable()),d("src/lib/database/migrations/00000012_create_invoices.ts",p.createInvoicesTable()),d("src/lib/database/seeders/DatabaseSeeder.ts",p.databaseSeeder()),this.info("Creating auth pages..."),d("src/routes/login/+page.server.ts",p.loginPageServer()),d("src/routes/login/+page.svelte",p.loginPageSvelte()),d("src/routes/register/+page.server.ts",p.registerPageServer()),d("src/routes/register/+page.svelte",p.registerPageSvelte()),d("src/routes/logout/+page.server.ts",p.logoutPageServer()),d("src/routes/forgot-password/+page.server.ts",p.forgotPasswordPageServer()),d("src/routes/forgot-password/+page.svelte",p.forgotPasswordPageSvelte()),d("src/routes/reset-password/+page.server.ts",p.resetPasswordPageServer()),d("src/routes/reset-password/+page.svelte",p.resetPasswordPageSvelte()),d("src/routes/otp-login/+page.server.ts",p.otpLoginPageServer()),d("src/routes/otp-login/+page.svelte",p.otpLoginPageSvelte()),d("src/routes/verify-email/+page.server.ts",p.verifyEmailPageServer()),d("src/routes/verify-email/+page.svelte",p.verifyEmailPageSvelte()),this.info("Creating dashboard..."),d("src/routes/dashboard/+layout.server.ts",p.dashboardLayoutServer()),d("src/routes/dashboard/+layout.svelte",p.dashboardLayoutSvelte()),d("src/routes/dashboard/+page.server.ts",p.dashboardPageServer()),d("src/routes/dashboard/+page.svelte",p.dashboardPageSvelte()),d("src/routes/dashboard/api-keys/+page.server.ts",p.apiKeysPageServer()),d("src/routes/dashboard/api-keys/+page.svelte",p.apiKeysPageSvelte()),d("src/routes/dashboard/team/+page.server.ts",p.teamPageServer()),d("src/routes/dashboard/team/+page.svelte",p.teamPageSvelte()),d("src/routes/dashboard/billing/+page.server.ts",p.billingPageServer()),d("src/routes/dashboard/billing/+page.svelte",p.billingPageSvelte()),this.info("Creating admin panel..."),d("src/routes/admin/+layout.server.ts",p.adminLayoutServer()),d("src/routes/admin/+layout.svelte",p.adminLayoutSvelte()),d("src/routes/admin/+page.server.ts",p.adminPageServer()),d("src/routes/admin/+page.svelte",p.adminPageSvelte()),this.info("Creating API routes..."),d("src/routes/api/health/+server.ts",p.apiHealth()),d("src/routes/api/auth/register/+server.ts",p.apiAuthRegister()),d("src/routes/api/auth/login/+server.ts",p.apiAuthLogin()),d("src/routes/api/auth/logout/+server.ts",p.apiAuthLogout()),d("src/routes/api/auth/me/+server.ts",p.apiAuthMe()),d("src/routes/api/auth/forgot-password/+server.ts",p.apiAuthForgotPassword()),d("src/routes/api/auth/reset-password/+server.ts",p.apiAuthResetPassword()),d("src/routes/api/auth/otp/send/+server.ts",p.apiAuthOtpSend()),d("src/routes/api/auth/otp/verify/+server.ts",p.apiAuthOtpVerify()),d("src/routes/api/auth/verify-email/+server.ts",p.apiAuthVerifyEmail()),d("src/routes/api/posts/+server.ts",p.apiPosts()),d("src/routes/api/posts/[id]/+server.ts",p.apiPostsSingle()),d("src/routes/api/posts/mine/+server.ts",p.apiPostsMine()),d("src/routes/api/broadcasting/[channel]/+server.ts",p.apiBroadcasting()),d("src/routes/api/internal/broadcast/+server.ts",p.apiInternalBroadcast()),d("src/routes/api/admin/users/+server.ts",p.apiAdminUsers()),d("src/routes/api/admin/roles/+server.ts",p.apiAdminRoles()),d("src/routes/api/admin/permissions/+server.ts",p.apiAdminPermissions()),d("src/routes/api/admin/role-permissions/+server.ts",p.apiAdminRolePermissions()),d("src/routes/api/admin/user-roles/+server.ts",p.apiAdminUserRoles()),d("src/routes/api/admin/user-permissions/+server.ts",p.apiAdminUserPermissions()),d("src/routes/api/admin/export/+server.ts",p.apiAdminExport()),d("src/routes/api/admin/health/+server.ts",p.apiAdminHealth()),d("src/routes/api/admin/queue/+server.ts",p.apiAdminQueue()),d("src/routes/api/admin/queue/[id]/retry/+server.ts",p.apiAdminQueueRetry()),d("src/routes/api/admin/queue/[id]/+server.ts",p.apiAdminQueueDelete()),d("src/routes/api/admin/scheduler/+server.ts",p.apiAdminScheduler()),d("src/routes/api/admin/scheduler/[name]/run/+server.ts",p.apiAdminSchedulerRun()),d("src/routes/api/admin/scheduler/[name]/toggle/+server.ts",p.apiAdminSchedulerToggle()),d("src/routes/api/admin/logs/+server.ts",p.apiAdminLogs()),d("src/routes/api/admin/stats/+server.ts",p.apiAdminStats()),d("src/routes/api/admin/billing/subscriptions/+server.ts",p.apiAdminBillingSubscriptions()),d("src/routes/api/admin/billing/refund/+server.ts",p.apiAdminBillingRefund()),d("src/routes/api/admin/billing/cancel/+server.ts",p.apiAdminBillingCancel()),d("src/routes/api/webhooks/stripe/+server.ts",p.stripeWebhookRoute()),this.info("Creating background jobs..."),d("src/lib/shared/jobs/SendWelcomeEmail.ts",p.sendWelcomeEmail()),d("src/lib/shared/jobs/DailyDigestJob.ts",p.dailyDigestJob()),d("src/lib/shared/jobs/ExportDataJob.ts",p.exportDataJob()),this.info("Creating scheduled tasks..."),d("src/lib/shared/scheduler/CleanupExpiredTokens.ts",p.cleanupExpiredTokens()),d("src/lib/shared/scheduler/CleanExpiredSessions.ts",p.cleanExpiredSessions()),d("src/lib/shared/scheduler/DailyDigestEmail.ts",p.dailyDigestEmail()),d("src/lib/shared/scheduler/PruneAuditLogs.ts",p.pruneAuditLogs()),d("src/lib/shared/scheduler/QueueHealthCheck.ts",p.queueHealthCheck()),this.info("Creating layouts..."),d("src/routes/+layout.svelte",p.rootLayoutSvelte(c)),d("src/routes/+layout.server.ts",p.rootLayoutServer()),d("src/routes/+error.svelte",p.errorSvelte()),d("src/routes/+page.svelte",p.homePage(c)),this.success(`Project structure created (${h})`),!t["no-install"]){this.info("Installing dependencies...");try{l("npm install",{cwd:u,stdio:"inherit"}),this.success("Dependencies installed")}catch{this.warn("npm install failed \u2014 run it manually with: cd "+c+" && npm install")}this.info("Running migrations...");try{l("npx svelar migrate",{cwd:u,stdio:"inherit"}),this.success("Migrations complete")}catch{this.warn("Migrations failed \u2014 run manually: cd "+c+" && npx svelar migrate")}this.info("Seeding database...");try{l("npx svelar seed:run",{cwd:u,stdio:"inherit"}),this.success("Database seeded")}catch{this.warn("Seeding failed \u2014 run manually: cd "+c+" && npx svelar seed:run")}}this.log(""),this.log(` \x1B[32m+\x1B[0m Project \x1B[1m${c}\x1B[0m created successfully!
|
|
6438
7066
|
`),this.log(` Next steps:
|
|
6439
|
-
`),this.log(` cd ${c}`),t["no-install"]&&(this.log(" npm install"),this.log(" npx svelar migrate"),this.log(" npx svelar seed:run")),this.log(" npm run dev"),this.log(""),this.log(" Default accounts:"),this.log(" Admin: admin@svelar.dev / admin123"),this.log(" Demo: demo@svelar.dev / password"),this.log("")}};var
|
|
6440
|
-
APP_KEY=${
|
|
6441
|
-
`);return}let c=r(process.cwd(),".env");if(!i(c)){let
|
|
6442
|
-
`),this.success("Application key set (created .env).");return}let u=n(c,"utf-8"),
|
|
6443
|
-
${u}`);this.success("Application key set.")}};var
|
|
6444
|
-
`)){let e=
|
|
7067
|
+
`),this.log(` cd ${c}`),t["no-install"]&&(this.log(" npm install"),this.log(" npx svelar migrate"),this.log(" npx svelar seed:run")),this.log(" npm run dev"),this.log(""),this.log(" Default accounts:"),this.log(" Admin: admin@svelar.dev / admin123"),this.log(" Demo: demo@svelar.dev / password"),this.log("")}};function bo(o){return/Service\./.test(o)?"services":/Controller\./.test(o)?"controllers":/Repository\./.test(o)?"repositories":/Request\./.test(o)?"dtos":/Resource\./.test(o)?"resources":/Action\./.test(o)?"actions":/Listener\./.test(o)?"listeners":/Notification\./.test(o)?"notifications":/Registered|Created|Updated|Deleted|Verified|Invited/.test(o)?"events":"models"}function yo(o){let e=o.match(/^src\/lib\/modules\/(\w+)\/(.+)$/);if(e){let[,s,r]=e;return r==="schemas.ts"?`src/lib/schemas/${s}.ts`:r==="gates.ts"?"src/lib/gates.ts":`src/lib/${bo(r)}/${r}`}let t=o.match(/^src\/lib\/shared\/(.+)$/);return t?`src/lib/${t[1]}`:o}function Tr(o,e,t){return e==="schemas"?`$lib/schemas/${o}${t}`:e==="gates"?`$lib/gates${t}`:`$lib/${Gi(e)}/${e}${t}`}function Gi(o){return/Service$/.test(o)?"services":/Controller$/.test(o)?"controllers":/Repository$/.test(o)?"repositories":/Request$/.test(o)?"dtos":/Resource$/.test(o)?"resources":/Action$/.test(o)?"actions":/Listener$/.test(o)?"listeners":/Notification$/.test(o)?"notifications":/Registered|Created|Updated|Deleted|Verified|Invited/.test(o)?"events":"models"}function vo(o,e){let s=e.match(/modules\/(\w+)\//)?.[1]||"";return o=o.replace(/\$lib\/modules\/(\w+)\/(\w+)(\.js)?/g,(r,i,n,a)=>Tr(i,n,a||"")),o=o.replace(/\.\/lib\/modules\/(\w+)\/(\w+)(\.js)?/g,(r,i,n,a)=>n==="schemas"?`./lib/schemas/${i}${a||""}`:n==="gates"?`./lib/gates${a||""}`:`./lib/${Gi(n)}/${n}${a||""}`),o=o.replace(/\$lib\/shared\//g,"$lib/"),o=o.replace(/\.\/lib\/shared\//g,"./lib/"),e.includes("shared/")&&(o=o.replace(/'\.\.\/(\.\.\/\.\.\/)'/g,"'$1'"),o=o.replace(/'\.\.\/\.\.\/\.\.\//g,"'../../")),s&&(o=o.replace(/from '\.\/(\w+)(\.js)?'/g,(r,i,n)=>i.startsWith("$")||i==="app"?r:(n=n||"",`from '${Tr(s,i,n)}'`)),o=o.replace(/import '\.\/(\w+)(\.js)?'/g,(r,i,n)=>i.startsWith("$")||i==="app"?r:(n=n||"",`import '${Tr(s,i,n)}'`))),o}var rs=class extends g{name="key:generate";description="Generate a new APP_KEY and set it in .env";flags=[{name:"show",alias:"s",description:"Only display the key, do not write to .env",type:"boolean",default:!1},{name:"force",alias:"f",description:"Overwrite existing APP_KEY",type:"boolean",default:!1}];async handle(e,t){let{randomBytes:s}=await import("crypto"),{join:r}=await import("path"),{existsSync:i,readFileSync:n,writeFileSync:a}=await import("fs"),l=s(32).toString("hex");if(t.show){this.log(`
|
|
7068
|
+
APP_KEY=${l}
|
|
7069
|
+
`);return}let c=r(process.cwd(),".env");if(!i(c)){let h=r(process.cwd(),".env.example");if(i(h)){let d=n(h,"utf-8");d=d.replace(/^APP_KEY=.*$/m,`APP_KEY=${l}`),a(c,d),this.success("Application key set (created .env from .env.example).")}else a(c,`APP_KEY=${l}
|
|
7070
|
+
`),this.success("Application key set (created .env).");return}let u=n(c,"utf-8"),m=u.match(/^APP_KEY=(.*)$/m);if(m&&m[1]&&m[1]!=="change-me-to-a-random-string"&&!t.force){this.warn("APP_KEY already set. Use --force to overwrite.");return}if(m){let h=u.replace(/^APP_KEY=.*$/m,`APP_KEY=${l}`);a(c,h)}else a(c,`APP_KEY=${l}
|
|
7071
|
+
${u}`);this.success("Application key set.")}};var as=class extends g{name="plugin:list";description="List all discovered and enabled plugins";arguments=[];flags=[];async handle(e,t){try{let{PluginRegistry:s}=await Promise.resolve().then(()=>(ns(),kr)),r=s;await r.discover();let i=r.list();if(i.length===0){this.info("No plugins discovered.");return}let n=["Name","Version","Description","Status","Config","Migrations"],a=i.map(l=>[l.name,l.version,l.description||"-",l.enabled?"\u2713 Enabled":" Disabled",l.hasConfig?"\u2713":"-",l.hasMigrations?"\u2713":"-"]);this.newLine(),this.table(n,a),this.newLine(),this.info(`Total: ${i.length} plugin(s)`)}catch(s){this.error(`Failed to list plugins: ${s?.message??String(s)}`)}}};var os=class extends g{name="plugin:publish";description="Publish a plugin's config and migration files";arguments=["name"];flags=[{name:"force",alias:"f",description:"Overwrite existing files",type:"boolean"},{name:"only",alias:"o",description:"Publish only config|migrations|assets",type:"string"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a plugin name.");return}try{let{PluginRegistry:r}=await Promise.resolve().then(()=>(ns(),kr)),{PluginPublisher:i}=await Promise.resolve().then(()=>(Ar(),Yi)),n=r,a=i;await n.discover();let l=n.get(s);if(!l){this.error(`Plugin "${s}" not found.`);return}let c=await this.loadPluginClass(l.packageName);if(!c){this.error(`Failed to load plugin class for "${s}".`);return}let u=new c,m={force:t.force||!1,only:t.only};this.info(`Publishing plugin: ${s}`);let h=await a.publish(u,m);this.newLine(),h.configs.length>0&&(this.success(`${h.configs.length} config file(s) published:`),h.configs.forEach(d=>this.log(` - ${d}`))),h.migrations.length>0&&(this.success(`${h.migrations.length} migration file(s) published:`),h.migrations.forEach(d=>this.log(` - ${d}`))),h.assets.length>0&&(this.success(`${h.assets.length} asset file(s) published:`),h.assets.forEach(d=>this.log(` - ${d}`))),h.configs.length===0&&h.migrations.length===0&&h.assets.length===0&&this.warn("No publishable files found for this plugin."),this.newLine()}catch(r){this.error(`Failed to publish plugin: ${r?.message??String(r)}`)}}async loadPluginClass(e){try{let t=await import(e);return t.default||Object.values(t)[0]}catch{return null}}};var ls=class extends g{name="plugin:install";description="Install a plugin from npm";arguments=["package"];flags=[{name:"no-publish",alias:"n",description:"Skip auto-publishing plugin assets",type:"boolean"}];async handle(e,t){let s=e[0];if(!s){this.error("Please provide a package name.");return}try{let{PluginInstaller:r}=await Promise.resolve().then(()=>(Xi(),Zi)),i=r;this.info(`Installing plugin package: ${s}`),this.newLine();let n=await i.install(s,{publish:!t["no-publish"]});this.newLine(),n.success?(this.success(`Plugin installed: ${n.pluginName} (v${n.version})`),n.published&&(n.published.configs.length>0&&this.info(`${n.published.configs.length} config file(s) published`),n.published.migrations.length>0&&this.info(`${n.published.migrations.length} migration file(s) published`),n.published.assets.length>0&&this.info(`${n.published.assets.length} asset file(s) published`)),this.newLine(),this.log("You can now use the plugin in your application by registering it in your app bootstrap code.")):this.error(`Failed to install plugin: ${n.error}`),this.newLine()}catch(r){this.error(`Installation error: ${r?.message??String(r)}`)}}};var en=Lr(process.cwd(),".env");if(Po(en))for(let o of rn(en,"utf-8").split(`
|
|
7072
|
+
`)){let e=o.trim();if(!e||e.startsWith("#"))continue;let t=e.indexOf("=");if(t===-1)continue;let s=e.slice(0,t).trim(),r=e.slice(t+1).trim();(r.startsWith('"')&&r.endsWith('"')||r.startsWith("'")&&r.endsWith("'"))&&(r=r.slice(1,-1)),s in process.env||(process.env[s]=r)}var So=tn(sn(import.meta.url));xo(Co(Lr(So,"ts-resolve-hook.mjs")).href,import.meta.url);var Ro=tn(sn(import.meta.url)),To=Lr(Ro,"..","..","package.json"),Eo=JSON.parse(rn(To,"utf-8")),v=new Ke(Eo.version);v.register(ss);v.register(rs);v.register(Je);v.register(Ve);v.register(Qe);v.register(Ge);v.register(Ye);v.register(Ze);v.register(Xe);v.register(et);v.register(tt);v.register(st);v.register(ut);v.register(mt);v.register(rt);v.register(it);v.register(nt);v.register(at);v.register(ot);v.register(lt);v.register(ct);v.register(dt);v.register(pt);v.register(ht);v.register(gt);v.register(ft);v.register(bt);v.register(yt);v.register(vt);v.register(xt);v.register(Rt);v.register(Tt);v.register(Et);v.register(kt);v.register(ts);v.register(as);v.register(os);v.register(ls);async function ko(){let{join:o}=await import("path"),{existsSync:e,readdirSync:t}=await import("fs"),{pathToFileURL:s}=await import("url"),r=o(process.cwd(),"src","lib","shared","commands");if(!e(r))return;let i=t(r).filter(n=>(n.endsWith(".ts")||n.endsWith(".js"))&&!n.startsWith("."));for(let n of i)try{let a=o(r,n),c=await import(s(a).href),u=c.default??Object.values(c).find(m=>typeof m=="function"&&m.prototype&&"handle"in m.prototype);u&&typeof u=="function"&&v.add(new u)}catch{}}ko().then(()=>v.run());
|