@beeblock/svelar 0.4.0
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/LICENSE +21 -0
- package/README.md +110 -0
- package/dist/actions/index.d.ts +101 -0
- package/dist/actions/index.js +1 -0
- package/dist/api-keys/index.d.ts +58 -0
- package/dist/api-keys/index.js +1 -0
- package/dist/audit/index.d.ts +52 -0
- package/dist/audit/index.js +1 -0
- package/dist/auth/Auth.d.ts +283 -0
- package/dist/auth/Gate.d.ts +166 -0
- package/dist/auth/index.d.ts +2 -0
- package/dist/auth/index.js +80 -0
- package/dist/broadcasting/client.d.ts +195 -0
- package/dist/broadcasting/client.js +1 -0
- package/dist/broadcasting/index.d.ts +318 -0
- package/dist/broadcasting/index.js +20 -0
- package/dist/cache/index.d.ts +77 -0
- package/dist/cache/index.js +1 -0
- package/dist/cli/Cli.d.ts +23 -0
- package/dist/cli/Command.d.ts +36 -0
- package/dist/cli/bin.d.ts +8 -0
- package/dist/cli/bin.js +5856 -0
- package/dist/cli/commands/KeyGenerateCommand.d.ts +16 -0
- package/dist/cli/commands/MakeActionCommand.d.ts +15 -0
- package/dist/cli/commands/MakeBroadcastingCommand.d.ts +29 -0
- package/dist/cli/commands/MakeChannelCommand.d.ts +18 -0
- package/dist/cli/commands/MakeCommandCommand.d.ts +16 -0
- package/dist/cli/commands/MakeConfigCommand.d.ts +13 -0
- package/dist/cli/commands/MakeControllerCommand.d.ts +28 -0
- package/dist/cli/commands/MakeDashboardCommand.d.ts +34 -0
- package/dist/cli/commands/MakeDockerCommand.d.ts +32 -0
- package/dist/cli/commands/MakeEventCommand.d.ts +11 -0
- package/dist/cli/commands/MakeJobCommand.d.ts +11 -0
- package/dist/cli/commands/MakeListenerCommand.d.ts +16 -0
- package/dist/cli/commands/MakeMiddlewareCommand.d.ts +11 -0
- package/dist/cli/commands/MakeMigrationCommand.d.ts +17 -0
- package/dist/cli/commands/MakeModelCommand.d.ts +25 -0
- package/dist/cli/commands/MakeObserverCommand.d.ts +23 -0
- package/dist/cli/commands/MakePluginCommand.d.ts +11 -0
- package/dist/cli/commands/MakeProviderCommand.d.ts +11 -0
- package/dist/cli/commands/MakeRepositoryCommand.d.ts +22 -0
- package/dist/cli/commands/MakeRequestCommand.d.ts +15 -0
- package/dist/cli/commands/MakeResourceCommand.d.ts +30 -0
- package/dist/cli/commands/MakeRouteCommand.d.ts +42 -0
- package/dist/cli/commands/MakeSchemaCommand.d.ts +20 -0
- package/dist/cli/commands/MakeSeederCommand.d.ts +11 -0
- package/dist/cli/commands/MakeServiceCommand.d.ts +28 -0
- package/dist/cli/commands/MakeTaskCommand.d.ts +12 -0
- package/dist/cli/commands/MigrateCommand.d.ts +26 -0
- package/dist/cli/commands/NewCommand.d.ts +21 -0
- package/dist/cli/commands/NewCommandTemplates.d.ts +123 -0
- package/dist/cli/commands/PluginInstallCommand.d.ts +16 -0
- package/dist/cli/commands/PluginListCommand.d.ts +11 -0
- package/dist/cli/commands/PluginPublishCommand.d.ts +22 -0
- package/dist/cli/commands/QueueFailedCommand.d.ts +9 -0
- package/dist/cli/commands/QueueFlushCommand.d.ts +9 -0
- package/dist/cli/commands/QueueRetryCommand.d.ts +16 -0
- package/dist/cli/commands/QueueWorkCommand.d.ts +25 -0
- package/dist/cli/commands/RoutesListCommand.d.ts +30 -0
- package/dist/cli/commands/ScheduleRunCommand.d.ts +15 -0
- package/dist/cli/commands/SeedCommand.d.ts +14 -0
- package/dist/cli/commands/TinkerCommand.d.ts +10 -0
- package/dist/cli/index.d.ts +36 -0
- package/dist/cli/index.js +1973 -0
- package/dist/cli/ts-resolve-hook.mjs +74 -0
- package/dist/cli/ts-resolver.mjs +8 -0
- package/dist/config/Config.d.ts +65 -0
- package/dist/config/index.d.ts +1 -0
- package/dist/config/index.js +1 -0
- package/dist/container/Application.d.ts +33 -0
- package/dist/container/Container.d.ts +70 -0
- package/dist/container/ServiceProvider.d.ts +21 -0
- package/dist/container/index.d.ts +3 -0
- package/dist/container/index.js +1 -0
- package/dist/dashboard/index.d.ts +123 -0
- package/dist/dashboard/index.js +5 -0
- package/dist/database/Connection.d.ts +80 -0
- package/dist/database/Migration.d.ts +76 -0
- package/dist/database/SchemaBuilder.d.ts +91 -0
- package/dist/database/Seeder.d.ts +9 -0
- package/dist/database/index.d.ts +4 -0
- package/dist/database/index.js +4 -0
- package/dist/email-templates/index.d.ts +51 -0
- package/dist/email-templates/index.js +57 -0
- package/dist/errors/Handler.d.ts +100 -0
- package/dist/errors/index.d.ts +1 -0
- package/dist/errors/index.js +5 -0
- package/dist/events/EventServiceProvider.d.ts +82 -0
- package/dist/events/Listener.d.ts +28 -0
- package/dist/events/index.d.ts +80 -0
- package/dist/events/index.js +1 -0
- package/dist/excel/index.d.ts +154 -0
- package/dist/excel/index.js +1 -0
- package/dist/feature-flags/index.d.ts +158 -0
- package/dist/feature-flags/index.js +59 -0
- package/dist/forms/index.d.ts +81 -0
- package/dist/forms/index.js +1 -0
- package/dist/hashing/Hash.d.ts +51 -0
- package/dist/hashing/index.d.ts +1 -0
- package/dist/hashing/index.js +1 -0
- package/dist/hooks/index.d.ts +135 -0
- package/dist/hooks/index.js +5 -0
- package/dist/http/index.d.ts +201 -0
- package/dist/http/index.js +2 -0
- package/dist/i18n/index.d.ts +81 -0
- package/dist/i18n/index.js +1 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.js +127 -0
- package/dist/logging/LogViewer.d.ts +95 -0
- package/dist/logging/LogViewer.js +1 -0
- package/dist/logging/index.d.ts +83 -0
- package/dist/logging/index.js +3 -0
- package/dist/mail/index.d.ts +149 -0
- package/dist/mail/index.js +1 -0
- package/dist/middleware/Middleware.d.ts +208 -0
- package/dist/middleware/index.d.ts +1 -0
- package/dist/middleware/index.js +1 -0
- package/dist/notifications/index.d.ts +85 -0
- package/dist/notifications/index.js +2 -0
- package/dist/orm/Model.d.ts +123 -0
- package/dist/orm/Observer.d.ts +34 -0
- package/dist/orm/QueryBuilder.d.ts +119 -0
- package/dist/orm/Relationship.d.ts +58 -0
- package/dist/orm/index.d.ts +4 -0
- package/dist/orm/index.js +1 -0
- package/dist/pagination/index.d.ts +8 -0
- package/dist/pagination/index.js +0 -0
- package/dist/pdf/GeneratePdfJob.d.ts +99 -0
- package/dist/pdf/GeneratePdfJob.js +41 -0
- package/dist/pdf/index.d.ts +328 -0
- package/dist/pdf/index.js +41 -0
- package/dist/permissions/index.d.ts +161 -0
- package/dist/permissions/index.js +60 -0
- package/dist/plugins/BootstrapPlugins.d.ts +11 -0
- package/dist/plugins/PluginInstaller.d.ts +30 -0
- package/dist/plugins/PluginInstaller.js +1 -0
- package/dist/plugins/PluginPublisher.d.ts +32 -0
- package/dist/plugins/PluginPublisher.js +1 -0
- package/dist/plugins/PluginRegistry.d.ts +55 -0
- package/dist/plugins/PluginRegistry.js +1 -0
- package/dist/plugins/index.d.ts +206 -0
- package/dist/plugins/index.js +1 -0
- package/dist/queue/JobMonitor.d.ts +109 -0
- package/dist/queue/JobMonitor.js +5 -0
- package/dist/queue/index.d.ts +279 -0
- package/dist/queue/index.js +5 -0
- package/dist/repositories/index.d.ts +147 -0
- package/dist/repositories/index.js +1 -0
- package/dist/routing/Controller.d.ts +115 -0
- package/dist/routing/FormRequest.d.ts +94 -0
- package/dist/routing/Resource.d.ts +213 -0
- package/dist/routing/Response.d.ts +138 -0
- package/dist/routing/index.d.ts +4 -0
- package/dist/routing/index.js +5 -0
- package/dist/scheduler/ScheduleMonitor.d.ts +141 -0
- package/dist/scheduler/ScheduleMonitor.js +1 -0
- package/dist/scheduler/SchedulerLock.d.ts +33 -0
- package/dist/scheduler/index.d.ts +208 -0
- package/dist/scheduler/index.js +34 -0
- package/dist/services/index.d.ts +79 -0
- package/dist/services/index.js +1 -0
- package/dist/session/Session.d.ts +166 -0
- package/dist/session/index.d.ts +1 -0
- package/dist/session/index.js +16 -0
- package/dist/storage/index.d.ts +154 -0
- package/dist/storage/index.js +1 -0
- package/dist/support/Pipeline.d.ts +65 -0
- package/dist/support/date.d.ts +136 -0
- package/dist/support/date.js +1 -0
- package/dist/support/index.d.ts +8 -0
- package/dist/support/index.js +1 -0
- package/dist/support/singleton.d.ts +10 -0
- package/dist/support/uuid.d.ts +40 -0
- package/dist/teams/index.d.ts +91 -0
- package/dist/teams/index.js +78 -0
- package/dist/uploads/index.d.ts +63 -0
- package/dist/uploads/index.js +2 -0
- package/dist/validation/index.d.ts +46 -0
- package/dist/validation/index.js +1 -0
- package/dist/webhooks/index.d.ts +66 -0
- package/dist/webhooks/index.js +1 -0
- package/package.json +338 -0
- package/src/i18n/LanguageSwitcher.svelte +47 -0
- package/src/i18n/index.ts +113 -0
- package/src/ui/Alert.svelte +22 -0
- package/src/ui/Avatar.svelte +18 -0
- package/src/ui/AvatarFallback.svelte +18 -0
- package/src/ui/AvatarImage.svelte +12 -0
- package/src/ui/Badge.svelte +27 -0
- package/src/ui/Button.svelte +51 -0
- package/src/ui/Card.svelte +15 -0
- package/src/ui/CardContent.svelte +15 -0
- package/src/ui/CardDescription.svelte +15 -0
- package/src/ui/CardFooter.svelte +15 -0
- package/src/ui/CardHeader.svelte +15 -0
- package/src/ui/CardTitle.svelte +15 -0
- package/src/ui/Icon.svelte +81 -0
- package/src/ui/Input.svelte +40 -0
- package/src/ui/Label.svelte +20 -0
- package/src/ui/Separator.svelte +10 -0
- package/src/ui/Tabs.svelte +23 -0
- package/src/ui/TabsContent.svelte +27 -0
- package/src/ui/TabsList.svelte +19 -0
- package/src/ui/TabsTrigger.svelte +28 -0
- package/src/ui/Toaster.svelte +279 -0
- package/src/ui/index.ts +31 -0
- package/src/ui/toast.ts +212 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
var ps=Object.defineProperty;var ms=(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 $=(o,e)=>()=>(o&&(e=o(o=0)),e);var F=(o,e)=>{for(var t in e)ps(o,t,{get:e[t],enumerable:!0})};function p(o,e){let t=Symbol.for(o),s=globalThis;return s[t]||(s[t]=e()),s[t]}var T=$(()=>{"use strict"});var y={};F(y,{Connection:()=>d});var Le,d,m=$(()=>{"use strict";T();Le=class{connections=new Map;config=null;defaultName="default";configure(e){this.config=e,this.defaultName=e.default}async connection(e){let t=e??this.defaultName;if(this.connections.has(t))return this.connections.get(t).drizzle;if(!this.config)throw new Error("Database not configured. Call Connection.configure() first, or register DatabaseServiceProvider.");let s=this.config.connections[t];if(!s)throw new Error(`Database connection "${t}" is not defined in configuration.`);let r=await this.createConnection(s);return this.connections.set(t,r),r.drizzle}async rawClient(e){let t=e??this.defaultName;return await this.connection(t),this.connections.get(t).rawClient}async raw(e,t=[],s){let r=await this.connection(s),n=this.getConfig(s);switch(n.driver){case"sqlite":{let i=await this.rawClient(s),a=t.map(u=>typeof u=="boolean"?u?1:0:u instanceof Date?u.toISOString():u),c=i.prepare(e),l=e.trimStart().toUpperCase();return l.startsWith("SELECT")||l.startsWith("PRAGMA")||l.startsWith("WITH")?c.all(...a):c.run(...a)}case"postgres":return(await this.rawClient(s))(e,...t);case"mysql":{let i=await this.rawClient(s),[a]=await i.execute(e,t);return a}default:throw new Error(`Unsupported driver: ${n.driver}`)}}getDriver(e){return this.getConfig(e).driver}getConfig(e){let t=e??this.defaultName;if(!this.config)throw new Error("Database not configured.");let s=this.config.connections[t];if(!s)throw new Error(`Database connection "${t}" is not defined.`);return s}async disconnect(e){if(e){let t=this.connections.get(e);t&&(await this.closeConnection(t),this.connections.delete(e))}else{for(let[t,s]of this.connections)await this.closeConnection(s);this.connections.clear()}}isConnected(e){return this.connections.has(e??this.defaultName)}async transaction(e,t){let s=this.getConfig(t),r=await this.rawClient(t);switch(s.driver){case"sqlite":{r.exec("BEGIN");try{let n=await e();return r.exec("COMMIT"),n}catch(n){throw r.exec("ROLLBACK"),n}}case"postgres":{await r`BEGIN`;try{let n=await e();return await r`COMMIT`,n}catch(n){throw await r`ROLLBACK`,n}}case"mysql":{let n=await r.getConnection();await n.beginTransaction();try{let i=await e();return await n.commit(),n.release(),i}catch(i){throw await n.rollback(),n.release(),i}}default:throw new Error(`Unsupported driver: ${s.driver}`)}}async createConnection(e){switch(e.driver){case"sqlite":return this.createSQLiteConnection(e);case"postgres":return this.createPostgresConnection(e);case"mysql":return this.createMySQLConnection(e);default:throw new Error(`Unsupported database driver: ${e.driver}`)}}async createSQLiteConnection(e){let t=e.filename??e.database??":memory:";try{let s=(await import("better-sqlite3")).default,{drizzle:r}=await import("drizzle-orm/better-sqlite3"),n=new s(t);return n.pragma("journal_mode = WAL"),n.pragma("foreign_keys = ON"),{drizzle:r(n),config:e,rawClient:n}}catch(s){let r;try{r=(await new Function("mod","return import(mod)")("node:sqlite")).DatabaseSync}catch{throw new Error(`No SQLite driver available. Install better-sqlite3 (npm install better-sqlite3) or use Node.js v22+ which includes built-in SQLite support. Original error: ${s instanceof Error?s.message:String(s)}`)}let n=new r(t);n.exec("PRAGMA journal_mode = WAL"),n.exec("PRAGMA foreign_keys = ON");let i={prepare(c){let l=n.prepare(c);return{all(...u){return l.all(...u)},run(...u){return l.run(...u)},get(...u){return l.get(...u)}}},exec(c){n.exec(c)},pragma(c){return n.prepare(`PRAGMA ${c}`).all()},close(){n.close()}},a;try{let{drizzle:c}=await import("drizzle-orm/better-sqlite3");a=c(i)}catch{a=i}return{drizzle:a,config:e,rawClient:i}}}async createPostgresConnection(e){let t=(await import("postgres")).default,{drizzle:s}=await import("drizzle-orm/postgres-js"),r=e.url??`postgres://${e.user}:${e.password}@${e.host??"localhost"}:${e.port??5432}/${e.database}`,n=t(r);return{drizzle:s(n),config:e,rawClient:n}}async createMySQLConnection(e){let t=await import("mysql2/promise"),{drizzle:s}=await import("drizzle-orm/mysql2"),r=t.createPool({host:e.host??"localhost",port:e.port??3306,database:e.database,user:e.user,password:e.password,uri:e.url});return{drizzle:s(r),config:e,rawClient:r}}async closeConnection(e){try{switch(e.config.driver){case"sqlite":e.rawClient.close();break;case"postgres":await e.rawClient.end();break;case"mysql":await e.rawClient.end();break}}catch{}}},d=p("svelar.connection",()=>new Le)});var ne={};F(ne,{Hash:()=>Jt});import{randomBytes as ze,scrypt as Kt,timingSafeEqual as Ts}from"crypto";async function Cs(o,e=16384){let t=ze(16),s=64,r=await new Promise((n,i)=>{Kt(o,t,s,{N:e,r:8,p:1},(a,c)=>{a?i(a):n(c)})});return`$scrypt$N=${e}$${t.toString("base64")}$${r.toString("base64")}`}async function Es(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"),n=Buffer.from(t[4],"base64"),i=n.length,a=await new Promise((c,l)=>{Kt(o,r,i,{N:s,r:8,p:1},(u,h)=>{u?l(u):c(h)})});return Ts(a,n)}var Xe,Jt,_=$(()=>{"use strict";T();Xe=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 Cs(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 Es(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 ze(Math.ceil(e/2)).toString("hex").slice(0,e)}randomToken(e=32){return ze(e).toString("base64url")}},Jt=p("svelar.hash",()=>new Xe)});var Qt={};F(Qt,{EmailTemplates:()=>xs});import{randomUUID as R}from"crypto";var Ge,xs,Wt=$(()=>{"use strict";T();Ge=class{config={driver:"memory"};templates=new Map;constructor(){this.registerDefaults()}configure(e){this.config=e}async register(e){let t={...e,id:R(),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(()=>(m(),y));await s.connection()}catch{this.templates.set(e.name,t)}return t}async render(e,t){let s=await this.get(e);if(!s)throw new Error(`Template "${e}" not found`);let r=this.interpolate(s.subject,t),n=this.interpolate(s.html,t),i=s.text?this.interpolate(s.text,t):void 0;return{subject:r,html:n,text:i}}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:R(),name:"welcome",subject:"Welcome to {{appName}}, {{user.name}}!",html:`
|
|
2
|
+
<h1>Welcome, {{user.name}}!</h1>
|
|
3
|
+
<p>Thank you for joining {{appName}}.</p>
|
|
4
|
+
<p>Your account has been created with the email: <strong>{{user.email}}</strong></p>
|
|
5
|
+
<p><a href="{{confirmUrl}}">Confirm your email address</a></p>
|
|
6
|
+
`,text:`Welcome, {{user.name}}!
|
|
7
|
+
|
|
8
|
+
Confirm your email: {{confirmUrl}}`,variables:["appName","user.name","user.email","confirmUrl"],category:"auth",active:!0,createdAt:Date.now(),updatedAt:Date.now()}),this.templates.set("password-reset",{id:R(),name:"password-reset",subject:"Reset your {{appName}} password",html:`
|
|
9
|
+
<h1>Password Reset</h1>
|
|
10
|
+
<p>Hi {{user.name}},</p>
|
|
11
|
+
<p>Click the link below to reset your password. This link expires in 1 hour.</p>
|
|
12
|
+
<p><a href="{{resetUrl}}">Reset Password</a></p>
|
|
13
|
+
<p>If you didn't request this, you can ignore this email.</p>
|
|
14
|
+
`,text:`Reset your password: {{resetUrl}}
|
|
15
|
+
|
|
16
|
+
This link expires in 1 hour.`,variables:["appName","user.name","resetUrl"],category:"auth",active:!0,createdAt:Date.now(),updatedAt:Date.now()}),this.templates.set("email-verification",{id:R(),name:"email-verification",subject:"Verify your email address",html:`
|
|
17
|
+
<h1>Verify Your Email</h1>
|
|
18
|
+
<p>Hi {{user.name}},</p>
|
|
19
|
+
<p><a href="{{verifyUrl}}">Click here to verify your email address</a></p>
|
|
20
|
+
<p>This link expires in 24 hours.</p>
|
|
21
|
+
`,text:"Verify your email: {{verifyUrl}}",variables:["user.name","verifyUrl"],category:"auth",active:!0,createdAt:Date.now(),updatedAt:Date.now()}),this.templates.set("team-invitation",{id:R(),name:"team-invitation",subject:"{{inviter.name}} invited you to join {{team.name}}",html:`
|
|
22
|
+
<h1>Team Invitation</h1>
|
|
23
|
+
<p>Hi {{user.name}},</p>
|
|
24
|
+
<p><strong>{{inviter.name}}</strong> has invited you to join the team <strong>{{team.name}}</strong>.</p>
|
|
25
|
+
<p><a href="{{acceptUrl}}">Accept Invitation</a></p>
|
|
26
|
+
<p>This invitation expires in 3 days.</p>
|
|
27
|
+
`,text:"Accept: {{acceptUrl}}",variables:["user.name","inviter.name","team.name","acceptUrl"],category:"notification",active:!0,createdAt:Date.now(),updatedAt:Date.now()}),this.templates.set("invoice",{id:R(),name:"invoice",subject:"Invoice #{{invoice.number}} from {{appName}}",html:`
|
|
28
|
+
<h1>Invoice #{{invoice.number}}</h1>
|
|
29
|
+
<p>Hi {{customer.name}},</p>
|
|
30
|
+
<p>Thank you for your purchase!</p>
|
|
31
|
+
<p><strong>Amount:</strong> {{invoice.amount}}</p>
|
|
32
|
+
<p><strong>Date:</strong> {{invoice.date}}</p>
|
|
33
|
+
<p><a href="{{invoiceUrl}}">View Invoice</a></p>
|
|
34
|
+
`,text:`Invoice #{{invoice.number}}
|
|
35
|
+
Amount: {{invoice.amount}}`,variables:["appName","customer.name","invoice.number","invoice.amount","invoice.date","invoiceUrl"],category:"billing",active:!0,createdAt:Date.now(),updatedAt:Date.now()}),this.templates.set("subscription-confirmation",{id:R(),name:"subscription-confirmation",subject:"Subscription Confirmation",html:`
|
|
36
|
+
<h1>Subscription Confirmed</h1>
|
|
37
|
+
<p>Hi {{user.name}},</p>
|
|
38
|
+
<p>Your {{plan.name}} plan is now active.</p>
|
|
39
|
+
<p><strong>Price:</strong> {{plan.price}} / {{plan.interval}}</p>
|
|
40
|
+
<p>Your next billing date is {{nextBillingDate}}.</p>
|
|
41
|
+
`,text:`Your {{plan.name}} plan is active.
|
|
42
|
+
Next billing: {{nextBillingDate}}`,variables:["user.name","plan.name","plan.price","plan.interval","nextBillingDate"],category:"billing",active:!0,createdAt:Date.now(),updatedAt:Date.now()}),this.templates.set("otp-code",{id:R(),name:"otp-code",subject:"Your {{appName}} verification code: {{code}}",html:`
|
|
43
|
+
<h1>Your Verification Code</h1>
|
|
44
|
+
<p>Hi {{user.name}},</p>
|
|
45
|
+
<p>Your one-time verification code is:</p>
|
|
46
|
+
<p style="font-size: 32px; font-weight: bold; letter-spacing: 8px; text-align: center; padding: 16px; background: #f3f4f6; border-radius: 8px; font-family: monospace;">{{code}}</p>
|
|
47
|
+
<p>This code expires in {{expiresMinutes}} minutes.</p>
|
|
48
|
+
<p>If you didn't request this code, you can safely ignore this email.</p>
|
|
49
|
+
`,text:`Your verification code: {{code}}
|
|
50
|
+
|
|
51
|
+
This code expires in {{expiresMinutes}} minutes.`,variables:["appName","user.name","code","expiresMinutes","purpose"],category:"auth",active:!0,createdAt:Date.now(),updatedAt:Date.now()}),this.templates.set("subscription-canceled",{id:R(),name:"subscription-canceled",subject:"Your subscription has been canceled",html:`
|
|
52
|
+
<h1>Subscription Canceled</h1>
|
|
53
|
+
<p>Hi {{user.name}},</p>
|
|
54
|
+
<p>Your {{plan.name}} subscription has been canceled.</p>
|
|
55
|
+
<p>You have access until {{accessUntilDate}}.</p>
|
|
56
|
+
`,text:`Your {{plan.name}} subscription is canceled.
|
|
57
|
+
Access until: {{accessUntilDate}}`,variables:["user.name","plan.name","accessUntilDate"],category:"billing",active:!0,createdAt:Date.now(),updatedAt:Date.now()})}interpolate(e,t){let s=e;return s=s.replace(/\{\{#if\s+(\w+(?:\.\w+)*)\}\}([\s\S]*?)\{\{\/if\}\}/g,(r,n,i)=>this.getNestedValue(t,n)?i:""),s=s.replace(/\{\{#each\s+(\w+(?:\.\w+)*)\}\}([\s\S]*?)\{\{\/each\}\}/g,(r,n,i)=>{let a=this.getNestedValue(t,n);return Array.isArray(a)?a.map((c,l)=>{let u={...t,this:c,$index:l};return this.interpolate(i,u)}).join(""):""}),s=s.replace(/\{\{([\w.$]+)\}\}/g,(r,n)=>{let i=this.getNestedValue(t,n);return i!=null?String(i):""}),s}getNestedValue(e,t){return t.split(".").reduce((s,r)=>s?.[r],e)}},xs=p("svelar.emailTemplates",()=>new Ge)});var nt={};F(nt,{Mailable:()=>we,Mailer:()=>zt});function rt(o){return typeof o=="string"?o:`${o.name} <${o.address}>`}function E(o){return o?Array.isArray(o)?o:[o]:[]}function Vt(o){return Buffer.isBuffer(o)?o.toString("base64"):Buffer.from(o).toString("base64")}var ye,Ye,Ze,et,tt,we,st,zt,be=$(()=>{"use strict";T();ye=class{async send(e){let t=E(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:[]}}},Ye=class{async send(e){return{accepted:E(e.to),rejected:[]}}},Ze=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?rt(e.from):void 0,to:E(e.to).join(", "),cc:E(e.cc).join(", ")||void 0,bcc:E(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}}},et=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(e.to),r=E(e.cc),n=E(e.bcc),i={From:e.from?rt(e.from):void 0,To:s.join(", "),Subject:e.subject,MessageStream:this.config.messageStream||"outbound"};r.length>0&&(i.Cc=r.join(", ")),n.length>0&&(i.Bcc=n.join(", ")),e.replyTo&&(i.ReplyTo=e.replyTo),e.html&&(i.HtmlBody=e.html),e.text&&(i.TextBody=e.text),!i.HtmlBody&&!i.TextBody&&(i.TextBody=""),e.tags&&(i.Tag=Object.values(e.tags)[0]),e.attachments?.length&&(i.Attachments=e.attachments.map(l=>({Name:l.filename,Content:Vt(l.content),ContentType:l.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(i)});if(!a.ok){let l=await a.json().catch(()=>({Message:a.statusText}));throw new Error(`Postmark error ${a.status}: ${l.Message||JSON.stringify(l)}`)}let c=await a.json();return{accepted:s,rejected:[],messageId:c.MessageID}}},tt=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(e.to),r=E(e.cc),n=E(e.bcc),i={from:e.from?rt(e.from):void 0,to:s,subject:e.subject};r.length>0&&(i.cc=r),n.length>0&&(i.bcc=n),e.replyTo&&(i.reply_to=[e.replyTo]),e.html&&(i.html=e.html),e.text&&(i.text=e.text),e.tags&&(i.tags=Object.entries(e.tags).map(([l,u])=>({name:l,value:u}))),e.attachments?.length&&(i.attachments=e.attachments.map(l=>({filename:l.filename,content:Vt(l.content),content_type:l.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(i)});if(!a.ok){let l=await a.json().catch(()=>({message:a.statusText}));throw new Error(`Resend error ${a.status}: ${l.message||JSON.stringify(l)}`)}let c=await a.json();return{accepted:s,rejected:[],messageId:c.id}}},we=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}},st=class{config=null;transports=new Map;configure(e){this.config=e,this.transports.clear()}async send(e,t){let s=this.resolveTransport(t);return!e.from&&this.config?.from&&(e.from=this.config.from),s.send(e)}async sendMailable(e,t){e.build();let s=e.toMessage();return!s.from&&this.config?.from&&(s.from=this.config.from),this.send(s,t)}mailer(e){let t=this.resolveTransport(e);return{send:s=>(!s.from&&this.config?.from&&(s.from=this.config.from),t.send(s))}}resolveTransport(e){let t=e??this.config?.default??"log";if(this.transports.has(t))return this.transports.get(t);if(!this.config){let n=new ye;return this.transports.set(t,n),n}let s=this.config.mailers[t];if(!s)throw new Error(`Mailer "${t}" is not defined.`);let r;switch(s.driver){case"smtp":r=new Ze(s);break;case"postmark":r=new et(s);break;case"resend":r=new tt(s);break;case"log":r=new ye;break;case"null":r=new Ye;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}},zt=p("svelar.mail",()=>new st)});var rs={};F(rs,{FormAuthorizationError:()=>ue,FormRequest:()=>Ee,FormValidationError:()=>le});var Ee,le,ue,wt=$(()=>{"use strict";Ee=class{authorize(e){return!0}messages(){return{}}attributes(){return{}}passedValidation(e){return e}failedValidation(e){throw new le(e)}failedAuthorization(){throw new ue}async parseBody(e){let t=e.request.headers.get("content-type")??"";if(t.includes("application/json"))return e.request.json();if(t.includes("multipart/form-data")||t.includes("application/x-www-form-urlencoded")){let s=await e.request.formData();return Object.fromEntries(s)}return Object.fromEntries(e.url.searchParams)}static async validate(e){let t=new this;await t.authorize(e)||t.failedAuthorization();let r=await t.parseBody(e),n={...Object.fromEntries(e.url.searchParams),...e.params,...r},a=t.rules().safeParse(n);if(!a.success){let c={},l=t.messages(),u=t.attributes();for(let h of a.error.issues){let g=h.path.join("."),b=u[g]??g;c[b]||(c[b]=[]);let f=`${g}.${h.code}`,C=l[f]??l[g];c[b].push(C??h.message)}t.failedValidation(c)}return t.passedValidation(a.data)}},le=class extends Error{constructor(t){super("The given data was invalid.");this.errors=t;this.name="FormValidationError"}statusCode=422;toResponse(){return new Response(JSON.stringify({message:this.message,errors:this.errors}),{status:422,headers:{"Content-Type":"application/json"}})}},ue=class extends Error{statusCode=403;constructor(e="This action is unauthorized."){super(e),this.name="FormAuthorizationError"}toResponse(){return new Response(JSON.stringify({message:this.message}),{status:403,headers:{"Content-Type":"application/json"}})}}});m();var A=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:n}=s.buildWhere(),i=r.replace(/^WHERE /,"");this.whereClauses.push({type:"raw",raw:`(${i})`,values:n,boolean:t})}return this}orWhereNested(e){return this.whereNested(e,"OR")}whereExists(e){let t=new 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:n,bindings:i}=r.toSQL();return this.whereClauses.push({type:"sub",column:e,operator:t,subSQL:n,subBindings:i,boolean:"AND"}),this}orWhereRaw(e,t=[]){return this.whereClauses.push({type:"raw",raw:e,values:t,boolean:"OR"}),this}orWhereIn(e,t){return this.whereClauses.push({type:"in",column:e,values:t,boolean:"OR"}),this}orWhereNull(e){return this.whereClauses.push({type:"null",column:e,boolean:"OR"}),this}orWhereNotNull(e){return this.whereClauses.push({type:"notNull",column:e,boolean:"OR"}),this}withCTE(e,t,s=!1){let r=new o("__placeholder__",void 0,this.connectionName);t(r);let{sql:n,bindings:i}=r.toSQL();return this.cteClauses.push({name:e,sql:n,bindings:i,recursive:s}),this}withRecursiveCTE(e,t){return this.withCTE(e,t,!0)}withRawCTE(e,t,s=[],r=!1){return this.cteClauses.push({name:e,sql:t,bindings:s,recursive:r}),this}union(e){let t=new 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 d.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 d.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 d.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 d.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 d.raw(t,s,this.connectionName))[0]?.aggregate??null}async min(e){let{sql:t,bindings:s}=this.buildAggregate(`MIN(${e})`);return(await d.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 d.raw(this.toSQL().sql,this.toSQL().bindings,this.connectionName)).map(s=>s[e])}async value(e){return this.selectColumns=[e],this.limitValue=1,(await d.raw(this.toSQL().sql,this.toSQL().bindings,this.connectionName))[0]?.[e]??null}async chunk(e,t){let s=1,r=!0;for(;r;){let n=this.clone();n.limitValue=e,n.offsetValue=(s-1)*e;let i=await n.get();if(i.length===0||await t(i,s)===!1||i.length<e)break;s++}}when(e,t){return e&&t(this),this}selectRaw(e){return this.selectColumns[0]==="*"?this.selectColumns=[e]:this.selectColumns.push(e),this}async upsert(e,t,s){let r=d.getDriver(this.connectionName),n=Object.keys(e),i=Object.values(e),a=i.map(()=>"?").join(", "),c=s??n.filter(u=>!t.includes(u)),l;if(r==="postgres"){let u=c.map(h=>`${h} = EXCLUDED.${h}`).join(", ");l=`INSERT INTO ${this.tableName} (${n.join(", ")}) VALUES (${a}) ON CONFLICT (${t.join(", ")}) DO UPDATE SET ${u}`}else if(r==="mysql"){let u=c.map(h=>`${h} = VALUES(${h})`).join(", ");l=`INSERT INTO ${this.tableName} (${n.join(", ")}) VALUES (${a}) ON DUPLICATE KEY UPDATE ${u}`}else{let u=c.map(h=>`${h} = excluded.${h}`).join(", ");l=`INSERT INTO ${this.tableName} (${n.join(", ")}) VALUES (${a}) ON CONFLICT (${t.join(", ")}) DO UPDATE SET ${u}`}return d.raw(l,i,this.connectionName)}async insertMany(e){if(e.length===0)return;let t=Object.keys(e[0]),s=[],r=[];for(let i of e){let a=t.map(c=>i[c]);s.push(...a),r.push(`(${a.map(()=>"?").join(", ")})`)}let n=`INSERT INTO ${this.tableName} (${t.join(", ")}) VALUES ${r.join(", ")}`;return d.raw(n,s,this.connectionName)}async firstOrCreate(e,t={}){for(let[i,a]of Object.entries(e))this.where(i,a);let s=await this.first();if(s)return s;let r={...e,...t},n=await new o(this.tableName,this.modelClass,this.connectionName).insertGetId(r);return new o(this.tableName,this.modelClass,this.connectionName).findOrFail(n)}async updateOrCreate(e,t){let s=new o(this.tableName,this.modelClass,this.connectionName);for(let[a,c]of Object.entries(e))s.where(a,c);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 n={...e,...t},i=await new o(this.tableName,this.modelClass,this.connectionName).insertGetId(n);return new o(this.tableName,this.modelClass,this.connectionName).findOrFail(i)}whereColumn(e,t,s){return s===void 0?this.whereClauses.push({type:"raw",raw:`${e} = ${t}`,values:[],boolean:"AND"}):this.whereClauses.push({type:"raw",raw:`${e} ${t} ${s}`,values:[],boolean:"AND"}),this}havingRaw(e,t=[]){return this.havingClauses.push({type:"raw",raw:e,values:t,boolean:"AND"}),this}orderByRaw(e){return this.orderClauses.push({column:e,direction:"asc"}),this.orderClauses[this.orderClauses.length-1].__raw=!0,this}selectSub(e,t){let s=new o("__placeholder__",void 0,this.connectionName);e(s);let{sql:r,bindings:n}=s.toSQL(),i=`(${r}) as ${t}`;return this.selectColumns[0]==="*"?this.selectColumns=[i]:this.selectColumns.push(i),this._selectBindings||(this._selectBindings=[]),this._selectBindings.push(...n),this}_selectBindings;async truncate(){d.getDriver(this.connectionName)==="sqlite"?(await d.raw(`DELETE FROM ${this.tableName}`,[],this.connectionName),await d.raw("DELETE FROM sqlite_sequence WHERE name = ?",[this.tableName],this.connectionName)):await d.raw(`TRUNCATE TABLE ${this.tableName}`,[],this.connectionName)}async paginate(e=1,t=15){let s=await this.clone().count(),r=Math.ceil(s/t);return this.limitValue=t,this.offsetValue=(e-1)*t,{data:await this.get(),total:s,page:e,perPage:t,lastPage:r,hasMore:e<r}}async insert(e){let t=Object.keys(e),s=Object.values(e),r=s.map(()=>"?").join(", "),n=`INSERT INTO ${this.tableName} (${t.join(", ")}) VALUES (${r})`;return d.raw(n,s,this.connectionName)}async insertGetId(e,t="id"){let s=d.getDriver(this.connectionName),r=Object.keys(e),n=Object.values(e),i=n.map(()=>"?").join(", "),a=`INSERT INTO ${this.tableName} (${r.join(", ")}) VALUES (${i})`;return s==="postgres"?(a+=` RETURNING ${t}`,(await d.raw(a,n,this.connectionName))[0]?.[t]):(await d.raw(a,n,this.connectionName),s==="sqlite"?(await d.raw("SELECT last_insert_rowid() as id",[],this.connectionName))[0]?.id:s==="mysql"?(await d.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(c=>`${c} = ?`).join(", "),{whereSQL:n,whereBindings:i}=this.buildWhere(),a=`UPDATE ${this.tableName} SET ${r}${n}`;return await d.raw(a,[...s,...i],this.connectionName),1}async delete(){let{whereSQL:e,whereBindings:t}=this.buildWhere(),s=`DELETE FROM ${this.tableName}${e}`;return await d.raw(s,t,this.connectionName),1}async increment(e,t=1){let{whereSQL:s,whereBindings:r}=this.buildWhere(),n=`UPDATE ${this.tableName} SET ${e} = ${e} + ?${s}`;await d.raw(n,[t,...r],this.connectionName)}async decrement(e,t=1){return this.increment(e,-t)}toSQL(){let e=[],t=[];if(this.cteClauses.length>0){let a=this.cteClauses.some(l=>l.recursive)?"WITH RECURSIVE":"WITH",c=this.cteClauses.map(l=>(t.push(...l.bindings),`${l.name} AS (${l.sql})`));e.push(`${a} ${c.join(", ")}`)}this._selectBindings?.length&&t.push(...this._selectBindings);let s=this.isDistinct?"DISTINCT ":"";e.push(`SELECT ${s}${this.selectColumns.join(", ")}`),e.push(`FROM ${this.tableName}`);for(let i of this.joinClauses)i.type==="CROSS"?e.push(`CROSS JOIN ${i.table}`):e.push(`${i.type} JOIN ${i.table} ON ${i.first} ${i.operator} ${i.second}`);let{whereSQL:r,whereBindings:n}=this.buildWhere();if(r&&(e.push(r.trim()),t.push(...n)),this.groupByColumns.length>0&&e.push(`GROUP BY ${this.groupByColumns.join(", ")}`),this.havingClauses.length>0){let i=[];for(let a of this.havingClauses)a.type==="raw"?(i.push(a.raw),a.values&&t.push(...a.values)):(i.push(`${a.column} ${a.operator} ?`),t.push(a.value));e.push(`HAVING ${i.join(" AND ")}`)}if(this.orderClauses.length>0){let i=this.orderClauses.map(a=>a.__raw?a.column:`${a.column} ${a.direction.toUpperCase()}`);e.push(`ORDER BY ${i.join(", ")}`)}if(this.limitValue!==null&&e.push(`LIMIT ${this.limitValue}`),this.offsetValue!==null&&e.push(`OFFSET ${this.offsetValue}`),this.unionClauses.length>0)for(let i of this.unionClauses)e.push(i.all?"UNION ALL":"UNION"),e.push(i.sql),t.push(...i.bindings);return{sql:e.join(" "),bindings:t}}clone(){let e=new 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],n=s===0?"WHERE":r.boolean;switch(r.type){case"basic":if((r.operator==="IS"||r.operator==="IS NOT")&&r.value===null){let c=(r.operator==="IS","null");e.push(`${n} ${r.column} ${r.operator} ${c}`)}else e.push(`${n} ${r.column} ${r.operator} ?`),t.push(r.value);break;case"in":let i=r.values.map(()=>"?").join(", ");e.push(`${n} ${r.column} IN (${i})`),t.push(...r.values);break;case"notIn":let a=r.values.map(()=>"?").join(", ");e.push(`${n} ${r.column} NOT IN (${a})`),t.push(...r.values);break;case"null":e.push(`${n} ${r.column} IS NULL`);break;case"notNull":e.push(`${n} ${r.column} IS NOT NULL`);break;case"between":e.push(`${n} ${r.column} BETWEEN ? AND ?`),t.push(r.values[0],r.values[1]);break;case"raw":e.push(`${n} ${r.raw}`),r.values&&t.push(...r.values);break;case"exists":e.push(`${n} EXISTS (${r.subSQL})`),r.subBindings&&t.push(...r.subBindings);break;case"notExists":e.push(`${n} NOT EXISTS (${r.subSQL})`),r.subBindings&&t.push(...r.subBindings);break;case"sub":e.push(`${n} ${r.column} ${r.operator} (${r.subSQL})`),r.subBindings&&t.push(...r.subBindings);break}}return{whereSQL:e.join(" "),whereBindings:t}}buildAggregate(e){let t=this.selectColumns;this.selectColumns=[`${e} as aggregate`];let s=this.toSQL();return this.selectColumns=t,s}hydrateMany(e){return this.modelClass?e.map(t=>this.modelClass.hydrate(t)):e}async loadRelations(e){if(!(!this.modelClass||e.length===0))for(let t of this.eagerLoads){let r=new this.modelClass()[t]?.();r&&typeof r.eagerLoad=="function"&&await r.eagerLoad(e,t)}}};m();var L=class{parentModel;relatedModel;constructor(e,t){this.parentModel=e,this.relatedModel=t}query(){return this.relatedModel.query()}},K=class extends L{constructor(t,s,r,n="id"){super(t,s);this.foreignKey=r;this.localKey=n}async load(t){let s=t.getAttribute(this.localKey);return this.relatedModel.query().where(this.foreignKey,s).first()}async eagerLoad(t,s){let r=t.map(a=>a.getAttribute(this.localKey)),n=await this.relatedModel.query().whereIn(this.foreignKey,r).get(),i=new Map;for(let a of n)i.set(a.getAttribute(this.foreignKey),a);for(let a of t){let c=a.getAttribute(this.localKey);a.setRelation(s,i.get(c)??null)}}async create(t){let s=this.parentModel.getAttribute(this.localKey);return this.relatedModel.create({...t,[this.foreignKey]:s})}},J=class extends L{constructor(t,s,r,n="id"){super(t,s);this.foreignKey=r;this.localKey=n}async load(t){let s=t.getAttribute(this.localKey);return this.relatedModel.query().where(this.foreignKey,s).get()}async eagerLoad(t,s){let r=t.map(a=>a.getAttribute(this.localKey)),n=await this.relatedModel.query().whereIn(this.foreignKey,r).get(),i=new Map;for(let a of n){let c=a.getAttribute(this.foreignKey);i.has(c)||i.set(c,[]),i.get(c).push(a)}for(let a of t){let c=a.getAttribute(this.localKey);a.setRelation(s,i.get(c)??[])}}async create(t){let s=this.parentModel.getAttribute(this.localKey);return this.relatedModel.create({...t,[this.foreignKey]:s})}async createMany(t){let s=[];for(let r of t)s.push(await this.create(r));return s}},Q=class extends L{constructor(t,s,r,n="id"){super(t,s);this.foreignKey=r;this.ownerKey=n}async load(t){let s=t.getAttribute(this.foreignKey);return s==null?null:this.relatedModel.query().where(this.ownerKey,s).first()}async eagerLoad(t,s){let r=t.map(a=>a.getAttribute(this.foreignKey)).filter(a=>a!=null);if(r.length===0){for(let a of t)a.setRelation(s,null);return}let n=await this.relatedModel.query().whereIn(this.ownerKey,r).get(),i=new Map;for(let a of n)i.set(a.getAttribute(this.ownerKey),a);for(let a of t){let c=a.getAttribute(this.foreignKey);a.setRelation(s,i.get(c)??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}},W=class extends L{constructor(t,s,r,n,i,a="id",c="id"){super(t,s);this.pivotTable=r;this.foreignPivotKey=n;this.relatedPivotKey=i;this.parentKey=a;this.relatedKey=c}async load(t){let s=t.getAttribute(this.parentKey),r=this.relatedModel.tableName,i=(await d.raw(`SELECT ${this.relatedPivotKey} FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ?`,[s])).map(a=>a[this.relatedPivotKey]);return i.length===0?[]:this.relatedModel.query().whereIn(this.relatedKey,i).get()}async eagerLoad(t,s){let r=t.map(h=>h.getAttribute(this.parentKey));if(r.length===0){for(let h of t)h.setRelation(s,[]);return}let n=r.map(()=>"?").join(", "),i=await d.raw(`SELECT * FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} IN (${n})`,r),a=[...new Set(i.map(h=>h[this.relatedPivotKey]))],c=a.length>0?await this.relatedModel.query().whereIn(this.relatedKey,a).get():[],l=new Map;for(let h of c)l.set(h.getAttribute(this.relatedKey),h);let u=new Map;for(let h of i){let g=h[this.foreignPivotKey],b=h[this.relatedPivotKey],f=l.get(b);f&&(u.has(g)||u.set(g,[]),u.get(g).push(f))}for(let h of t){let g=h.getAttribute(this.parentKey);h.setRelation(s,u.get(g)??[])}}async attach(t,s){let r=this.parentModel.getAttribute(this.parentKey),n={[this.foreignPivotKey]:r,[this.relatedPivotKey]:t,...s},i=Object.keys(n),a=Object.values(n),c=a.map(()=>"?").join(", ");await d.raw(`INSERT INTO ${this.pivotTable} (${i.join(", ")}) VALUES (${c})`,a)}async detach(t){let s=this.parentModel.getAttribute(this.parentKey);t?await d.raw(`DELETE FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ? AND ${this.relatedPivotKey} = ?`,[s,t]):await d.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 d.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)}};T();var he=class{app;constructor(e){this.app=e}boot(){}};var ge=class{listeners=new Map;wildcardListeners=[];onceListeners=new Map;listen(e,t){let s=typeof e=="string"?e:e.name;return this.listeners.has(s)||this.listeners.set(s,[]),this.listeners.get(s).push(t),()=>{let r=this.listeners.get(s);if(r){let n=r.indexOf(t);n>=0&&r.splice(n,1)}}}once(e,t){let s=typeof e=="string"?e:e.name;return this.onceListeners.has(s)||this.onceListeners.set(s,[]),this.onceListeners.get(s).push(t),()=>{let r=this.onceListeners.get(s);if(r){let n=r.indexOf(t);n>=0&&r.splice(n,1)}}}onAny(e){return this.wildcardListeners.push(e),()=>{let t=this.wildcardListeners.indexOf(e);t>=0&&this.wildcardListeners.splice(t,1)}}async dispatch(e){let t=e.constructor.name,s=this.listeners.get(t)??[];for(let n of s)await n(e);let r=this.onceListeners.get(t)??[];for(let n of r)await n(e);this.onceListeners.delete(t);for(let n of this.wildcardListeners)await n(t,e)}async emit(e,t){let s=this.listeners.get(e)??[];for(let n of s)await n(t);let r=this.onceListeners.get(e)??[];for(let n of r)await n(t);this.onceListeners.delete(e);for(let n of this.wildcardListeners)await n(e,t)}subscribe(e){e.subscribe(this)}forget(e){let t=typeof e=="string"?e:e.name;this.listeners.delete(t),this.onceListeners.delete(t)}flush(){this.listeners.clear(),this.onceListeners.clear(),this.wildcardListeners=[]}hasListeners(e){let t=typeof e=="string"?e:e.name;return(this.listeners.get(t)?.length??0)>0||(this.onceListeners.get(t)?.length??0)>0||this.wildcardListeners.length>0}listenerCount(e){let t=typeof e=="string"?e:e.name;return(this.listeners.get(t)?.length??0)+(this.onceListeners.get(t)?.length??0)}},V=p("svelar.event",()=>new ge);var Ie=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 A(t.table,this,t.connection)}static async find(e){let t=this;return this.query().find(e,t.primaryKey)}static async findOrFail(e){let t=this;return this.query().findOrFail(e,t.primaryKey)}static async all(){return this.query().get()}static async first(){return this.query().first()}static async firstOrFail(){return this.query().firstOrFail()}static where(e,t,s){return this.query().where(e,t,s)}static whereIn(e,t){return this.query().whereIn(e,t)}static whereNull(e){return this.query().whereNull(e)}static whereNotNull(e){return this.query().whereNotNull(e)}static orderBy(e,t){return this.query().orderBy(e,t)}static latest(e){return this.query().latest(e)}static oldest(e){return this.query().oldest(e)}static with(...e){return this.query().with(...e)}static async count(){return this.query().count()}static async create(e){let t=new this,s=this;if(t.fill(e),await t.fireHook("creating"),await t.fireHook("saving"),s.timestamps){let a=new Date().toISOString();t.setAttribute(s.createdAt,a),t.setAttribute(s.updatedAt,a)}let r=t.getInsertableAttributes(),i=await new A(s.table,this,s.connection).insertGetId(r,s.primaryKey);return s.incrementing&&i&&t.setAttribute(s.primaryKey,i),t.syncOriginal(),t.exists=!0,await t.fireHook("created"),await t.fireHook("saved"),t}async save(){let e=this.constructor;if(this.exists){await this.fireHook("updating"),await this.fireHook("saving"),e.timestamps&&this.setAttribute(e.updatedAt,new Date().toISOString());let t=this.getDirty();if(Object.keys(t).length>0){let s=this.getAttribute(e.primaryKey);await new A(e.table,this.constructor,e.connection).where(e.primaryKey,s).update(t)}this.syncOriginal(),await this.fireHook("updated"),await this.fireHook("saved")}else{if(await this.fireHook("creating"),await this.fireHook("saving"),e.timestamps){let n=new Date().toISOString();this.getAttribute(e.createdAt)||this.setAttribute(e.createdAt,n),this.setAttribute(e.updatedAt,n)}let t=this.getInsertableAttributes(),r=await new A(e.table,this.constructor,e.connection).insertGetId(t,e.primaryKey);e.incrementing&&r&&this.setAttribute(e.primaryKey,r),this.syncOriginal(),this.exists=!0,await this.fireHook("created"),await this.fireHook("saved")}}async update(e){this.fill(e),await this.save()}async delete(){let e=this.constructor;await this.fireHook("deleting");let t=this.getAttribute(e.primaryKey);await new A(e.table,this.constructor,e.connection).where(e.primaryKey,t).delete(),this.exists=!1,await this.fireHook("deleted")}async refresh(){let e=this.constructor,t=this.getAttribute(e.primaryKey),s=await this.constructor.find(t);s&&(this.attributes={...s.attributes},this.syncOriginal())}getAttribute(e){let t=this.constructor,s=this.attributes[e],r=t.casts[e];if(r&&s!==void 0&&s!==null)switch(r){case"number":return Number(s);case"boolean":return!!s;case"string":return String(s);case"date":return new Date(s);case"json":return typeof s=="string"?JSON.parse(s):s}return s}setAttribute(e,t){this.constructor.casts[e]==="json"&&typeof t!="string"?this.attributes[e]=JSON.stringify(t):this.attributes[e]=t}fill(e){let t=this.constructor;for(let[s,r]of Object.entries(e))t.fillable.length>0&&!t.fillable.includes(s)||this.setAttribute(s,r)}getAttributes(){return{...this.attributes}}getOriginal(e){return e?this.originalAttributes[e]:{...this.originalAttributes}}getDirty(){let e={};for(let[t,s]of Object.entries(this.attributes))s!==this.originalAttributes[t]&&(e[t]=s);return e}isDirty(...e){let t=this.getDirty();return e.length===0?Object.keys(t).length>0:e.some(s=>s in t)}isClean(...e){return!this.isDirty(...e)}wasChanged(...e){return this.isDirty(...e)}hasOne(e,t,s){return new K(this,e,t,s??this.constructor.primaryKey)}hasMany(e,t,s){return new J(this,e,t,s??this.constructor.primaryKey)}belongsTo(e,t,s){return new Q(this,e,t,s??e.primaryKey)}belongsToMany(e,t,s,r,n,i){return new W(this,e,t,s,r,n??this.constructor.primaryKey,i??e.primaryKey)}setRelation(e,t){this.relations[e]=t}getRelation(e){return this.relations[e]}relationLoaded(e){return e in this.relations}toJSON(){let e=this.constructor,t={};for(let[s,r]of Object.entries(this.attributes))e.hidden.includes(s)||(t[s]=this.getAttribute(s));for(let[s,r]of Object.entries(this.relations))Array.isArray(r)?t[s]=r.map(n=>n instanceof o?n.toJSON():n):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 i of r){let a=i[e];typeof a=="function"&&await a.call(i,this)}let n=t.name.toLowerCase();await V.emit(`${n}.${e}`,this)}async fireEvent(e){let t=this.constructor;if(!t.events.includes(e))throw new Error(`Event "${e}" is not declared in ${t.name}.events. Add it to: static events = ['${e}', ...];`);let s=o.observers.get(t.name)??[];for(let n of s){let i=n[e];typeof i=="function"&&await i.call(n,this)}let r=t.name.toLowerCase();await V.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}};m();m();T();var M=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 je(this.column)}build(){return this.column}},je=class{constructor(e){this.column=e}onDelete(e){return this.column.references.onDelete=e,this}onUpdate(e){return this.column.references.onUpdate=e,this}},z=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 M(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 M(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 M(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 M(t)}toSQL(e,t){let s=[],r=[];for(let n of this.columns)r.push(this.columnToSQL(n,t));this.compositePrimary&&r.push(`PRIMARY KEY (${this.compositePrimary.join(", ")})`);for(let n of this.columns)if(n.references){let i=`FOREIGN KEY (${n.name}) REFERENCES ${n.references.table}(${n.references.column})`;n.references.onDelete&&(i+=` ON DELETE ${n.references.onDelete}`),n.references.onUpdate&&(i+=` ON UPDATE ${n.references.onUpdate}`),r.push(i)}s.push(`CREATE TABLE ${e} (
|
|
58
|
+
${r.join(`,
|
|
59
|
+
`)}
|
|
60
|
+
)`);for(let n of this.indices){let i=n.name??`idx_${e}_${n.columns.join("_")}`,a=n.unique?"UNIQUE ":"";s.push(`CREATE ${a}INDEX ${i} ON ${e} (${n.columns.join(", ")})`)}return s}columnToSQL(e,t){let s=e.name,r=e.type;if(t==="sqlite"?r=this.mapSQLiteType(r,e):t==="postgres"?r=this.mapPostgresType(r,e):t==="mysql"&&(r=this.mapMySQLType(r,e)),s+=` ${r}`,e.primaryKey&&!this.compositePrimary&&(s+=" PRIMARY KEY",e.autoIncrement&&(t==="sqlite"?s+=" AUTOINCREMENT":t==="postgres"||t==="mysql"&&(s+=" AUTO_INCREMENT"))),!e.nullable&&!e.primaryKey&&(s+=" NOT NULL"),e.unique&&!e.primaryKey&&(s+=" UNIQUE"),e.defaultValue!==void 0){let n=typeof e.defaultValue=="string"?`'${e.defaultValue}'`:e.defaultValue===null?"NULL":e.defaultValue;s+=` DEFAULT ${n}`}return s}mapSQLiteType(e,t){return e==="BOOLEAN"?"INTEGER":e==="UUID"||e==="ULID"||e.startsWith("ENUM")||e==="JSON"||e==="JSONB"?"TEXT":e==="BIGINT"&&t.autoIncrement?"INTEGER":e}mapPostgresType(e,t){return t.autoIncrement&&e==="INTEGER"?"SERIAL":t.autoIncrement&&e==="BIGINT"?"BIGSERIAL":e==="DATETIME"?"TIMESTAMP":e==="BLOB"?"BYTEA":e.startsWith("ENUM")?"TEXT":e==="UUID"?"UUID":e==="ULID"?"VARCHAR(26)":e==="JSON"||e==="JSONB"?"JSONB":e}mapMySQLType(e,t){return e==="BOOLEAN"?"TINYINT(1)":e==="UUID"?"CHAR(36)":e==="ULID"?"CHAR(26)":e==="JSONB"?"JSON":e==="TIMESTAMP"?"DATETIME":t.unsigned&&!e.startsWith("DECIMAL")?`${e} UNSIGNED`:e}},D=class{constructor(e){this.connectionName=e}async createTable(e,t){let s=new z;t(s);let r=d.getDriver(this.connectionName),n=s.toSQL(e,r);for(let i of n)await d.raw(i,[],this.connectionName)}async dropTable(e){await d.raw(`DROP TABLE IF EXISTS ${e}`,[],this.connectionName)}async dropTableIfExists(e){await d.raw(`DROP TABLE IF EXISTS ${e}`,[],this.connectionName)}async renameTable(e,t){d.getDriver(this.connectionName)==="mysql"?await d.raw(`RENAME TABLE ${e} TO ${t}`,[],this.connectionName):await d.raw(`ALTER TABLE ${e} RENAME TO ${t}`,[],this.connectionName)}async hasTable(e){let t=d.getDriver(this.connectionName),s;switch(t){case"sqlite":s=await d.raw("SELECT name FROM sqlite_master WHERE type='table' AND name=?",[e],this.connectionName);break;case"postgres":s=await d.raw("SELECT tablename FROM pg_tables WHERE tablename = $1",[e],this.connectionName);break;case"mysql":s=await d.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 z;t(s);let r=d.getDriver(this.connectionName),n=s.columns;for(let i of n){let a=s.columnToSQL(i,r);await d.raw(`ALTER TABLE ${e} ADD COLUMN ${a}`,[],this.connectionName)}}async dropColumn(e,t){await d.raw(`ALTER TABLE ${e} DROP COLUMN ${t}`,[],this.connectionName)}},fs=p("svelar.schema",()=>new D);m();var qe=class{schema=new D},_e=class{migrationsTable="svelar_migrations";connectionName;constructor(e){this.connectionName=e}async ensureMigrationsTable(){let e=new D(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(i=>!t.includes(i.name));if(s.length===0)return[];let r=await this.getNextBatch(),n=[];for(let i of s)await i.migration.up(),await d.raw(`INSERT INTO ${this.migrationsTable} (migration, batch) VALUES (?, ?)`,[i.name,r],this.connectionName),n.push(i.name);return n}async rollback(e){await this.ensureMigrationsTable();let t=await this.getLastBatch();if(t===0)return[];let s=await d.raw(`SELECT migration FROM ${this.migrationsTable} WHERE batch = ? ORDER BY id DESC`,[t],this.connectionName),r=[];for(let n of s){let i=n.migration,a=e.find(c=>c.name===i);a&&(await a.migration.down(),await d.raw(`DELETE FROM ${this.migrationsTable} WHERE migration = ?`,[i],this.connectionName),r.push(i))}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=d.getDriver(this.connectionName),t=[];switch(e){case"sqlite":{t=(await d.raw("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'",[],this.connectionName)).map(r=>r.name),await d.raw("PRAGMA foreign_keys = OFF",[],this.connectionName);for(let r of t)await d.raw(`DROP TABLE IF EXISTS "${r}"`,[],this.connectionName);await d.raw("PRAGMA foreign_keys = ON",[],this.connectionName);break}case"mysql":{t=(await d.raw("SHOW TABLES",[],this.connectionName)).map(r=>Object.values(r)[0]),await d.raw("SET FOREIGN_KEY_CHECKS = 0",[],this.connectionName);for(let r of t)await d.raw(`DROP TABLE IF EXISTS \`${r}\``,[],this.connectionName);await d.raw("SET FOREIGN_KEY_CHECKS = 1",[],this.connectionName);break}case"postgres":{t=(await d.raw("SELECT tablename FROM pg_tables WHERE schemaname = 'public'",[],this.connectionName)).map(r=>r.tablename);for(let r of t)await d.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 d.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 d.raw(`SELECT migration, batch FROM ${this.migrationsTable}`,[],this.connectionName);for(let n of r)s.set(n.migration,n.batch)}catch{}return e.map(r=>({name:r.name,ran:t.includes(r.name),batch:s.get(r.name)??null}))}async getNextBatch(){return await this.getLastBatch()+1}async getLastBatch(){try{return(await d.raw(`SELECT MAX(batch) as max_batch FROM ${this.migrationsTable}`,[],this.connectionName))[0]?.max_batch??0}catch{return 0}}};var Ue=class{async call(e){await new e().run()}};T();var I=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}},ys=p("svelar.container",()=>new I);var Be=class{container;providers=[];booted=!1;constructor(e){this.container=e??new I,this.container.instance("app",this),this.container.instance("container",this.container)}register(e){let t=new e(this.container);return this.providers.push(t),this}async bootstrap(){if(this.booted)return this;for(let e of this.providers)await e.register();for(let e of this.providers)await e.boot();return this.booted=!0,this}isBooted(){return this.booted}async make(e){return this.container.make(e)}getProviders(){return[...this.providers]}};var v=class{},k=class{middleware=[];namedMiddleware=new Map;use(e){return typeof e=="function"&&"prototype"in e&&typeof e.prototype?.handle=="function"?this.middleware.push(new e):this.middleware.push(e),this}register(e,t){return typeof t=="function"&&"prototype"in t&&typeof t.prototype?.handle=="function"?this.namedMiddleware.set(e,new t):this.namedMiddleware.set(e,t),this}get(e){return this.namedMiddleware.get(e)}async execute(e,t,s){let r=[...this.middleware];if(s)for(let i of s){let a=this.namedMiddleware.get(i);a&&r.push(a)}let n=t;for(let i=r.length-1;i>=0;i--){let a=r[i],c=n;typeof a.handle=="function"?n=()=>a.handle(e,c):n=()=>a(e,c)}return n()}count(){return this.middleware.length}},He=class extends v{constructor(t={}){super();this.options=t}async handle(t,s){let r=await s();if(!r)return;let n=Array.isArray(this.options.origin)?this.options.origin.join(", "):this.options.origin??"*";return r.headers.set("Access-Control-Allow-Origin",n),r.headers.set("Access-Control-Allow-Methods",(this.options.methods??["GET","POST","PUT","DELETE","PATCH","OPTIONS"]).join(", ")),r.headers.set("Access-Control-Allow-Headers",(this.options.headers??["Content-Type","Authorization"]).join(", ")),this.options.credentials&&r.headers.set("Access-Control-Allow-Credentials","true"),this.options.maxAge&&r.headers.set("Access-Control-Max-Age",String(this.options.maxAge)),t.event.request.method==="OPTIONS"?new Response(null,{status:204,headers:r.headers}):r}},X=class extends v{requests=new Map;maxRequests;windowMs;constructor(e={}){super(),this.maxRequests=e.maxRequests??60,this.windowMs=e.windowMs??6e4}async handle(e,t){let s=e.event.request.headers.get("x-forwarded-for")??e.event.getClientAddress?.()??"unknown",r=Date.now(),n=this.requests.get(s);if(n&&r<n.resetAt){if(n.count>=this.maxRequests)return new Response(JSON.stringify({error:"Too many requests"}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(Math.ceil((n.resetAt-r)/1e3))}});n.count++}else this.requests.set(s,{count:1,resetAt:r+this.windowMs});return t()}},Fe=class extends v{async handle(e,t){let s=Date.now(),r=e.event.request.method,n=e.event.url.pathname,i=await t(),a=Date.now()-s,c=i instanceof Response?i.status:200;return console.log(`[${new Date().toISOString()}] ${r} ${n} \u2192 ${c} (${a}ms)`),i}},G=class extends v{cookieName;headerName;fieldName;excludePaths;onlyPaths;constructor(e={}){super(),this.cookieName=e.cookieName??"XSRF-TOKEN",this.headerName=e.headerName??"X-CSRF-Token",this.fieldName=e.fieldName??"_csrf",this.excludePaths=e.excludePaths??[],this.onlyPaths=e.onlyPaths??null}async handle(e,t){let{event:s}=e,r=s.request.method.toUpperCase();if(["GET","HEAD","OPTIONS"].includes(r))return this.setTokenAndContinue(e,t);if((s.request.headers.get("authorization")??"").startsWith("Bearer "))return t();let i=s.url.pathname;if(this.onlyPaths&&!this.onlyPaths.some(l=>i.startsWith(l)))return this.setTokenAndContinue(e,t);if(this.excludePaths.some(l=>i.startsWith(l)))return t();let a=this.getCookieToken(s),c=s.request.headers.get(this.headerName)??await this.getBodyToken(s);return!a||!c||!this.timingSafeEqual(a,c)?new Response(JSON.stringify({message:"CSRF token mismatch"}),{status:419,headers:{"Content-Type":"application/json"}}):t()}async setTokenAndContinue(e,t){let s=await t();if(!(s instanceof Response))return s;let n=this.getCookieToken(e.event)||this.generateToken();return s.headers.append("Set-Cookie",`${this.cookieName}=${n}; Path=/; SameSite=Lax`),s}getCookieToken(e){let s=(e.request.headers.get("cookie")??"").match(new RegExp(`${this.cookieName}=([^;]+)`));return s?s[1]:null}async getBodyToken(e){try{let t=e.request.headers.get("content-type")??"";if(t.includes("application/x-www-form-urlencoded")||t.includes("multipart/form-data"))return(await e.request.clone().formData()).get(this.fieldName);if(t.includes("application/json"))return(await e.request.clone().json())[this.fieldName]??null}catch{}return null}generateToken(){let e=new Uint8Array(32);return crypto.getRandomValues(e),Array.from(e,t=>t.toString(16).padStart(2,"0")).join("")}timingSafeEqual(e,t){if(e.length!==t.length)return!1;let s=new TextEncoder,r=s.encode(e),n=s.encode(t),i=0;for(let a=0;a<r.length;a++)i|=r[a]^n[a];return i===0}},Y=class extends v{allowedOrigins;constructor(e={}){super(),this.allowedOrigins=new Set(e.allowedOrigins??[])}async handle(e,t){let{event:s}=e,r=s.request.method.toUpperCase();if(["GET","HEAD","OPTIONS"].includes(r)||(s.request.headers.get("authorization")??"").startsWith("Bearer "))return t();let i=s.request.headers.get("origin");if(!i)return t();let a=s.url.origin;return i===a||this.allowedOrigins.has(i)?t():new Response(JSON.stringify({message:"Cross-origin request blocked"}),{status:403,headers:{"Content-Type":"application/json"}})}},Ke=class extends v{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(x=>C.startsWith(x)))return t()}let r=s.request.headers.get(this.signatureHeader),n=s.request.headers.get(this.timestampHeader);if(!r||!n)return new Response(JSON.stringify({message:"Missing request signature"}),{status:401,headers:{"Content-Type":"application/json"}});let i=parseInt(n,10),a=Math.floor(Date.now()/1e3);if(isNaN(i)||Math.abs(a-i)>this.tolerance)return new Response(JSON.stringify({message:"Request signature expired"}),{status:401,headers:{"Content-Type":"application/json"}});let l=await s.request.clone().text(),{createHmac:u}=await import("crypto"),h=s.request.method.toUpperCase(),g=s.url.pathname+s.url.search,b=`${n}.${h}.${g}.${l}`,f=u("sha256",this.secret).update(b).digest("hex");return r.length!==f.length||!this.timingSafeCompare(r,f)?new Response(JSON.stringify({message:"Invalid request signature"}),{status:401,headers:{"Content-Type":"application/json"}}):t()}timingSafeCompare(e,t){if(e.length!==t.length)return!1;let s=new TextEncoder,r=s.encode(e),n=s.encode(t),i=0;for(let a=0;a<r.length;a++)i|=r[a]^n[a];return i===0}static sign(e,t,s,r,n){let{createHmac:i}=ms("crypto"),a=n??Math.floor(Date.now()/1e3),c=`${a}.${t.toUpperCase()}.${s}.${r}`;return{signature:i("sha256",e).update(c).digest("hex"),timestamp:a}}},Z=class extends v{attempts=new Map;maxAttempts;decayMinutes;constructor(e={}){super(),this.maxAttempts=e.maxAttempts??5,this.decayMinutes=e.decayMinutes??1}async handle(e,t){let r=`${e.event.request.headers.get("x-forwarded-for")??e.event.getClientAddress?.()??"unknown"}:${e.event.url.pathname}`,n=Date.now(),i=this.attempts.get(r);if(i){if(n<i.blockedUntil){let c=Math.ceil((i.blockedUntil-n)/1e3);return new Response(JSON.stringify({message:"Too many attempts. Please try again later.",retry_after:c}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(c)}})}if(i.count>=this.maxAttempts){i.blockedUntil=n+this.decayMinutes*6e4,i.count=0;let c=this.decayMinutes*60;return new Response(JSON.stringify({message:"Too many attempts. Please try again later.",retry_after:c}),{status:429,headers:{"Content-Type":"application/json","Retry-After":String(c)}})}}let a=await t();if(a instanceof Response&&a.status>=400&&a.status<500){let c=this.attempts.get(r)??{count:0,blockedUntil:0};if(c.count++,this.attempts.set(r,c),this.attempts.size>1e4)for(let[l,u]of this.attempts)n>u.blockedUntil+this.decayMinutes*6e4*2&&this.attempts.delete(l)}return a}};import{z as j}from"zod";var Je=class{controllerMiddleware=[];middleware(e,t){let s;typeof e=="function"&&e.prototype instanceof v?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 k;for(let{middleware:a}of s)r.use(a);let n={event:t,params:t.params,locals:t.locals},i=await r.execute(n,async()=>this.callMethod(e,t));if(i instanceof Response)return i}return await this.callMethod(e,t)}catch(s){return this.handleError(s,t)}}}json(e,t=200,s={}){let r=JSON.stringify(e,null,2);return new Response(r,{status:t,headers:{"Content-Type":"application/json",...s}})}text(e,t=200){return new Response(e,{status:t,headers:{"Content-Type":"text/plain"}})}html(e,t=200){return new Response(e,{status:t,headers:{"Content-Type":"text/html"}})}redirect(e,t=302){return new Response(null,{status:t,headers:{Location:e}})}noContent(){return new Response(null,{status:204})}created(e){return e?this.json(e,201):new Response(null,{status:201})}async validate(e,t){let s=t instanceof j.ZodObject?t:j.object(t),r,n=e.request.headers.get("content-type")??"";if(n.includes("application/json"))r=await e.request.json();else if(n.includes("multipart/form-data")||n.includes("application/x-www-form-urlencoded")){let a=await e.request.formData();r=Object.fromEntries(a)}else r=Object.fromEntries(e.url.searchParams);let i=s.safeParse(r);if(!i.success)throw new O(i.error);return i.data}validateQuery(e,t){let s=t instanceof j.ZodObject?t:j.object(t),r=Object.fromEntries(e.url.searchParams),n=s.safeParse(r);if(!n.success)throw new O(n.error);return n.data}validateParams(e,t){let r=(t instanceof j.ZodObject?t:j.object(t)).safeParse(e.params);if(!r.success)throw new O(r.error);return r.data}handleError(e,t){return e instanceof O?this.json({message:"Validation failed",errors:e.errors},422):e instanceof pe?this.json({message:e.message||"Not found"},404):e instanceof me?this.json({message:e.message||"Unauthorized"},401):e instanceof fe?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)}};function ws(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 O=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)}}},pe=class extends Error{constructor(e="Not found"){super(e),this.name="NotFoundError"}},me=class extends Error{constructor(e="Unauthorized"){super(e),this.name="UnauthorizedError"}},fe=class extends Error{constructor(e="Forbidden"){super(e),this.name="ForbiddenError"}};import{randomBytes as bs,createHmac as Ft,timingSafeEqual as vs}from"crypto";import{promises as N}from"fs";import{join as ee}from"path";var se=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=te.get(e);return s instanceof q&&s.markOldSessionId(e),te.delete(e),t}static generateId(){return bs(32).toString("hex")}},te=new Map,q=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}),te.set(e,this)}async destroy(e){this.sessions.delete(e),te.delete(e)}async gc(e){let t=Date.now();for(let[s,r]of this.sessions)t>r.expiresAt&&(this.sessions.delete(s),te.delete(s))}markOldSessionId(e){this.oldSessionIds.add(e),this.sessions.delete(e)}},Qe=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(()=>(m(),y));switch(e.getDriver(this.connectionName)){case"sqlite":await e.raw(`CREATE TABLE IF NOT EXISTS ${this.tableName} (
|
|
61
|
+
id TEXT PRIMARY KEY,
|
|
62
|
+
payload TEXT NOT NULL,
|
|
63
|
+
expires_at TEXT NOT NULL
|
|
64
|
+
)`,[],this.connectionName);break;case"postgres":await e.raw(`CREATE TABLE IF NOT EXISTS ${this.tableName} (
|
|
65
|
+
id VARCHAR(255) PRIMARY KEY,
|
|
66
|
+
payload TEXT NOT NULL,
|
|
67
|
+
expires_at TIMESTAMPTZ NOT NULL
|
|
68
|
+
)`,[],this.connectionName);break;case"mysql":await e.raw(`CREATE TABLE IF NOT EXISTS ${this.tableName} (
|
|
69
|
+
id VARCHAR(255) PRIMARY KEY,
|
|
70
|
+
payload TEXT NOT NULL,
|
|
71
|
+
expires_at DATETIME NOT NULL
|
|
72
|
+
) ENGINE=InnoDB`,[],this.connectionName);break}this.tableEnsured=!0}catch{}}async read(e){await this.ensureTable();let{Connection:t}=await Promise.resolve().then(()=>(m(),y)),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(()=>(m(),y)),n=JSON.stringify(t),i=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 (?, ?, ?)
|
|
73
|
+
ON CONFLICT(id) DO UPDATE SET payload = excluded.payload, expires_at = excluded.expires_at`,[e,n,i],this.connectionName):a==="postgres"?await r.raw(`INSERT INTO ${this.tableName} (id, payload, expires_at) VALUES ($1, $2, $3)
|
|
74
|
+
ON CONFLICT(id) DO UPDATE SET payload = $2, expires_at = $3`,[e,n,i],this.connectionName):await r.raw(`INSERT INTO ${this.tableName} (id, payload, expires_at) VALUES (?, ?, ?)
|
|
75
|
+
ON DUPLICATE KEY UPDATE payload = VALUES(payload), expires_at = VALUES(expires_at)`,[e,n,i],this.connectionName)}async destroy(e){let{Connection:t}=await Promise.resolve().then(()=>(m(),y));await t.raw(`DELETE FROM ${this.tableName} WHERE id = ?`,[e],this.connectionName)}async gc(e){let{Connection:t}=await Promise.resolve().then(()=>(m(),y));await t.raw(`DELETE FROM ${this.tableName} WHERE expires_at < ?`,[new Date().toISOString()],this.connectionName)}},We=class{dir;constructor(e){this.dir=e??ee(process.cwd(),"storage","sessions")}filePath(e){let t=e.replace(/[^a-zA-Z0-9_-]/g,"");return ee(this.dir,`${t}.json`)}async ensureDir(){await N.mkdir(this.dir,{recursive:!0})}async read(e){try{let t=await N.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 N.writeFile(this.filePath(e),JSON.stringify(r),"utf-8")}async destroy(e){try{await N.unlink(this.filePath(e))}catch{}}async gc(e){try{let t=await N.readdir(this.dir),s=new Date;for(let r of t)if(r.endsWith(".json"))try{let n=await N.readFile(ee(this.dir,r),"utf-8"),i=JSON.parse(n);new Date(i.expiresAt)<s&&await N.unlink(ee(this.dir,r))}catch{await N.unlink(ee(this.dir,r)).catch(()=>{})}}catch{}}},Ve=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){}},re=class extends v{config;constructor(e){super(),this.config={cookieName:"svelar_session",lifetime:7200,secret:process.env.APP_KEY??(()=>{throw new Error("APP_KEY is not set. Set it in your .env file before using sessions.")})(),path:"/",domain:"",secure:process.env.NODE_ENV==="production",httpOnly:!0,sameSite:"lax",...e}}async handle(e,t){let s=e.event.request.headers.get("cookie")??"",r=this.getSessionIdFromCookie(s),n=null;if(r){let c=this.verifySignedId(r);c?(n=await this.config.store.read(c),r=c):r=null}r||(r=se.generateId());let i=new se(r,n??{});e.event.locals.session=i,e.locals.session=i;let a=await t();if(i.isDirty()&&await this.config.store.write(i.id,i.toPersist(),this.config.lifetime),a instanceof Response){let c=this.signId(i.id),l=this.buildCookieString(c);a.headers.append("Set-Cookie",l)}return a}getSessionIdFromCookie(e){let t=e.split(";").map(s=>s.trim());for(let s of t){let[r,...n]=s.split("=");if(r===this.config.cookieName)return decodeURIComponent(n.join("="))}return null}signId(e){let t=Ft("sha256",this.config.secret).update(e).digest("base64url");return`${e}.${t}`}verifySignedId(e){let t=e.lastIndexOf(".");if(t===-1)return null;let s=e.slice(0,t),r=e.slice(t+1),n=Ft("sha256",this.config.secret).update(s).digest("base64url");if(r.length!==n.length)return null;let i=Buffer.from(r),a=Buffer.from(n);if(i.length!==a.length)return null;try{if(vs(i,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("; ")}};import{createHmac as U,randomBytes as ie}from"crypto";function Xt(o){return(typeof o=="string"?Buffer.from(o):o).toString("base64url")}function Gt(o){return Buffer.from(o,"base64url").toString("utf-8")}function Yt(o,e,t,s){return U(s==="HS384"?"sha384":s==="HS512"?"sha512":"sha256",t).update(`${o}.${e}`).digest("base64url")}function Zt(o,e,t="HS256"){let s=Xt(JSON.stringify({alg:t,typ:"JWT"})),r=Xt(JSON.stringify(o)),n=Yt(s,r,e,t);return`${s}.${r}.${n}`}function es(o,e){let t=o.split(".");if(t.length!==3)return null;let[s,r,n]=t,i;try{i=JSON.parse(Gt(s))}catch{return null}let a=Yt(s,r,e,i.alg);if(n!==a)return null;try{let c=JSON.parse(Gt(r));return c.exp&&Date.now()/1e3>c.exp?null:c}catch{return null}}var it=class{config;currentUser=null;constructor(e){this.config={identifierColumn:"email",passwordColumn:"password",...e}}async attempt(e,t){let{Hash:s}=await Promise.resolve().then(()=>(_(),ne)),r=e[this.config.identifierColumn],n=e[this.config.passwordColumn];if(!r||!n)return null;let i=await this.config.model.where(this.config.identifierColumn,r).first();if(!i)return null;let a=i.getAttribute(this.config.passwordColumn);return await s.verify(n,a)?(this.currentUser=i,t&&(t.set("auth_user_id",i.getAttribute("id")),t.regenerateId()),i):null}async attemptJwt(e){let{Hash:t}=await Promise.resolve().then(()=>(_(),ne));if(!this.config.jwt)throw new Error("JWT configuration required for JWT guard.");let s=e[this.config.identifierColumn],r=e[this.config.passwordColumn];if(!s||!r)return null;let n=await this.config.model.where(this.config.identifierColumn,s).first();if(!n)return null;let i=n.getAttribute(this.config.passwordColumn);return await t.verify(r,i)?(this.currentUser=n,this.issueTokenPair(n)):null}async issueTokenPair(e){let t=this.config.jwt,s=t.expiresIn??3600,r=Math.floor(Date.now()/1e3),n={sub:e.getAttribute("id"),iat:r,exp:r+s,...t.issuer?{iss:t.issuer}:{}},i=Zt(n,t.secret,t.algorithm),a=new Date((r+s)*1e3),c={user:e,token:i,expiresAt:a};if(t.refreshTokens){let l=t.refreshExpiresIn??604800,u=ie(32).toString("base64url"),h=U("sha256",t.secret).update(u).digest("hex"),g=new Date((r+l)*1e3),{Connection:b}=await Promise.resolve().then(()=>(m(),y)),f=t.refreshTable??"refresh_tokens";await b.raw(`INSERT INTO ${f} (user_id, token, expires_at, created_at) VALUES (?, ?, ?, ?)`,[e.getAttribute("id"),h,g.toISOString(),new Date().toISOString()]),c.refreshToken=u,c.refreshExpiresAt=g}return c}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=U("sha256",t.secret).update(e).digest("hex"),{Connection:r}=await Promise.resolve().then(()=>(m(),y)),n=t.refreshTable??"refresh_tokens",i=await r.raw(`SELECT user_id, expires_at, revoked_at FROM ${n} WHERE token = ?`,[s]);if(i.length===0)return null;let a=i[0];if(a.revoked_at||new Date(a.expires_at)<new Date)return null;await r.raw(`UPDATE ${n} SET revoked_at = ? WHERE token = ?`,[new Date().toISOString(),s]);let c=await this.config.model.find(a.user_id);return c?(this.currentUser=c,this.issueTokenPair(c)):null}async revokeRefreshTokens(e){if(!this.config.jwt?.refreshTokens)return;let{Connection:t}=await Promise.resolve().then(()=>(m(),y)),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=es(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(()=>(_(),ne));e[this.config.passwordColumn]&&(e[this.config.passwordColumn]=await t.make(e[this.config.passwordColumn]));let s=await this.config.model.create(e);return this.currentUser=s,s}async logout(e){this.currentUser=null,e&&(e.forget("auth_user_id"),e.regenerateId())}user(){return this.currentUser}check(){return this.currentUser!==null}id(){return this.currentUser?.getAttribute("id")??null}async generateApiToken(e,t="default"){let s=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 n=U("sha256",r).update(s).digest("hex"),{Connection:i}=await Promise.resolve().then(()=>(m(),y)),a=this.config.token?.table??"personal_access_tokens";return await i.raw(`INSERT INTO ${a} (user_id, name, token, created_at) VALUES (?, ?, ?, ?)`,[e.getAttribute("id"),t,n,new Date().toISOString()]),s}async resolveFromApiToken(e){let{Connection:t}=await Promise.resolve().then(()=>(m(),y)),s=this.config.token?.table??"personal_access_tokens",r=this.config.jwt?.secret??process.env.APP_KEY;if(!r)throw new Error("APP_KEY is not set. Set it in your .env file or pass jwt.secret in auth config.");let n=U("sha256",r).update(e).digest("hex"),i=await t.raw(`SELECT user_id FROM ${s} WHERE token = ?`,[n]);if(i.length===0)return null;let a=await this.config.model.find(i[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(()=>(m(),y)),r=this.config.passwordResets?.table??"password_resets",n=this.config.passwordResets?.expiresIn??3600;await this.ensureTable(r,`
|
|
76
|
+
CREATE TABLE IF NOT EXISTS ${r} (
|
|
77
|
+
email TEXT NOT NULL,
|
|
78
|
+
token TEXT NOT NULL,
|
|
79
|
+
expires_at TEXT NOT NULL,
|
|
80
|
+
created_at TEXT NOT NULL
|
|
81
|
+
)
|
|
82
|
+
`),await s.raw(`DELETE FROM ${r} WHERE email = ?`,[e]);let i=ie(32).toString("base64url"),a=this.hashToken(i),c=new Date(Date.now()+n*1e3).toISOString();await s.raw(`INSERT INTO ${r} (email, token, expires_at, created_at) VALUES (?, ?, ?, ?)`,[e,a,c,new Date().toISOString()]);let l=this.config.appUrl??process.env.APP_URL??"http://localhost:5173",u=this.config.appName??process.env.APP_NAME??"Svelar",h=`${l}/reset-password?token=${i}&email=${encodeURIComponent(e)}`;return await this.sendAuthEmail("password-reset",e,{appName:u,"user.name":t.getAttribute("name")??e,resetUrl:h}),!0}async resetPassword(e,t,s){let{Connection:r}=await Promise.resolve().then(()=>(m(),y)),{Hash:n}=await Promise.resolve().then(()=>(_(),ne)),i=this.config.passwordResets?.table??"password_resets",a=this.hashToken(e),c=await r.raw(`SELECT email, expires_at FROM ${i} WHERE token = ? AND email = ?`,[a,t]);if(c.length===0)return!1;let l=c[0];if(new Date(l.expires_at)<new Date)return await r.raw(`DELETE FROM ${i} WHERE email = ?`,[t]),!1;let u=await this.config.model.where(this.config.identifierColumn,t).first();if(!u)return!1;let h=await n.make(s);return await this.config.model.where("id",u.getAttribute("id")).update({[this.config.passwordColumn]:h}),await r.raw(`DELETE FROM ${i} WHERE email = ?`,[t]),await this.revokeRefreshTokens(u.getAttribute("id")),!0}async sendVerificationEmail(e){let{Connection:t}=await Promise.resolve().then(()=>(m(),y)),s=this.config.emailVerification?.table??"email_verifications",r=this.config.emailVerification?.expiresIn??86400,n=e.getAttribute(this.config.identifierColumn);await this.ensureTable(s,`
|
|
83
|
+
CREATE TABLE IF NOT EXISTS ${s} (
|
|
84
|
+
user_id TEXT NOT NULL,
|
|
85
|
+
token TEXT NOT NULL,
|
|
86
|
+
expires_at TEXT NOT NULL,
|
|
87
|
+
created_at TEXT NOT NULL
|
|
88
|
+
)
|
|
89
|
+
`),await t.raw(`DELETE FROM ${s} WHERE user_id = ?`,[e.getAttribute("id")]);let i=ie(32).toString("base64url"),a=this.hashToken(i),c=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,c,new Date().toISOString()]);let u=`${this.config.appUrl??process.env.APP_URL??"http://localhost:5173"}/verify-email?token=${i}&id=${e.getAttribute("id")}`;await this.sendAuthEmail("email-verification",n,{"user.name":e.getAttribute("name")??n,verifyUrl:u})}async verifyEmail(e,t){let{Connection:s}=await Promise.resolve().then(()=>(m(),y)),r=this.config.emailVerification?.table??"email_verifications",n=this.config.emailVerification?.verifiedColumn??"email_verified_at",i=this.hashToken(e),a=await s.raw(`SELECT user_id, expires_at FROM ${r} WHERE token = ? AND user_id = ?`,[i,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({[n]:new Date().toISOString()}),await s.raw(`DELETE FROM ${r} WHERE user_id = ?`,[t]),!0)}isEmailVerified(e){let t=this.config.emailVerification?.verifiedColumn??"email_verified_at";return!!e.getAttribute(t)}async sendOtp(e,t="login"){let s=await this.config.model.where(this.config.identifierColumn,e).first();if(!s)return!1;let{Connection:r}=await Promise.resolve().then(()=>(m(),y)),n=this.config.otp?.table??"otp_codes",i=this.config.otp?.expiresIn??600,a=this.config.otp?.length??6;await this.ensureTable(n,`
|
|
90
|
+
CREATE TABLE IF NOT EXISTS ${n} (
|
|
91
|
+
email TEXT NOT NULL,
|
|
92
|
+
code TEXT NOT NULL,
|
|
93
|
+
purpose TEXT NOT NULL DEFAULT 'login',
|
|
94
|
+
expires_at TEXT NOT NULL,
|
|
95
|
+
used_at TEXT,
|
|
96
|
+
created_at TEXT NOT NULL
|
|
97
|
+
)
|
|
98
|
+
`),await r.raw(`DELETE FROM ${n} WHERE email = ? AND purpose = ?`,[e,t]);let c=this.generateOtpCode(a),l=this.hashToken(c),u=new Date(Date.now()+i*1e3).toISOString();await r.raw(`INSERT INTO ${n} (email, code, purpose, expires_at, created_at) VALUES (?, ?, ?, ?, ?)`,[e,l,t,u,new Date().toISOString()]);let h=this.config.appName??process.env.APP_NAME??"Svelar",g=Math.ceil(i/60);return await this.sendAuthEmail("otp-code",e,{appName:h,"user.name":s.getAttribute("name")??e,code:c,purpose:t,expiresMinutes:String(g)}),!0}async verifyOtp(e,t,s="login"){let{Connection:r}=await Promise.resolve().then(()=>(m(),y)),n=this.config.otp?.table??"otp_codes",i=this.hashToken(t),a=await r.raw(`SELECT email, expires_at, used_at FROM ${n} WHERE code = ? AND email = ? AND purpose = ? AND used_at IS NULL`,[i,e,s]);if(a.length===0)return null;if(new Date(a[0].expires_at)<new Date)return await r.raw(`DELETE FROM ${n} WHERE email = ? AND purpose = ?`,[e,s]),null;await r.raw(`UPDATE ${n} SET used_at = ? WHERE code = ? AND email = ? AND purpose = ?`,[new Date().toISOString(),i,e,s]);let c=await this.config.model.where(this.config.identifierColumn,e).first();return c&&(this.currentUser=c),c}async attemptOtp(e,t,s,r="login"){let n=await this.verifyOtp(e,t,r);return n?(s&&(s.set("auth_user_id",n.getAttribute("id")),s.regenerateId()),n):null}async cleanupExpiredTokens(){let{Connection:e}=await Promise.resolve().then(()=>(m(),y)),t=new Date().toISOString(),s=0,r=0,n=0,i=this.config.passwordResets?.table??"password_resets",a=this.config.emailVerification?.table??"email_verifications",c=this.config.otp?.table??"otp_codes";try{s=(await e.raw(`DELETE FROM ${i} WHERE expires_at < ?`,[t]))?.changes??0}catch{}try{r=(await e.raw(`DELETE FROM ${a} WHERE expires_at < ?`,[t]))?.changes??0}catch{}try{n=(await e.raw(`DELETE FROM ${c} WHERE expires_at < ? OR used_at IS NOT NULL`,[t]))?.changes??0}catch{}return{passwordResets:s,verifications:r,otpCodes:n}}hashToken(e){let t=this.config.jwt?.secret??process.env.APP_KEY;if(!t)throw new Error("APP_KEY is not set. Set it in your .env file or pass jwt.secret in auth config.");return U("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(()=>(m(),y));await s.raw(t),this.tablesEnsured.add(e)}async sendAuthEmail(e,t,s){try{let{EmailTemplates:r}=await Promise.resolve().then(()=>(Wt(),Qt)),{Mailer:n}=await Promise.resolve().then(()=>(be(),nt)),i=await r.render(e,s);await n.send({to:t,subject:i.subject,html:i.html,text:i.text})}catch(r){console.error(`[Auth] Failed to send ${e} email to ${t}:`,r.message)}}},ae=class extends v{constructor(t){super();this.authManager=t}async handle(t,s){let r=null;if(t.event.locals.session&&(r=await this.authManager.resolveFromSession(t.event.locals.session)),!r){let n=t.event.request.headers.get("authorization");if(n?.startsWith("Bearer ")){let i=n.slice(7);try{r=await this.authManager.resolveFromToken(i)}catch{r=await this.authManager.resolveFromApiToken(i)}}}return t.event.locals.user=r,t.event.locals.auth=this.authManager,s()}},at=class extends v{async handle(e,t){return e.event.locals.user?t():new Response(JSON.stringify({message:"Unauthenticated"}),{status:401,headers:{"Content-Type":"application/json"}})}};T();import{appendFile as Ps,mkdir as Ss}from"fs/promises";import{dirname as As}from"path";var ve={debug:0,info:1,warn:2,error:3,fatal:4},oe=class{minLevel;format;constructor(e){this.minLevel=e.level??"debug",this.format=e.format??"text"}write(e){if(ve[e.level]<ve[this.minLevel])return;if(this.format==="json"){console.log(JSON.stringify(e));return}let t={debug:"\x1B[90m",info:"\x1B[34m",warn:"\x1B[33m",error:"\x1B[31m",fatal:"\x1B[35m"},s="\x1B[0m",r=t[e.level]??"",n=e.level.toUpperCase().padEnd(5),i=Object.keys(e.context).length>0?` ${JSON.stringify(e.context)}`:"",a=e.level==="error"||e.level==="fatal"?"error":"log";console[a](`${r}[${e.timestamp}] ${n}${s} ${e.message}${i}`)}},ot=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(ve[e.level]<ve[this.minLevel])return;this.initialized||(await Ss(As(this.path),{recursive:!0}),this.initialized=!0);let t;if(this.format==="json")t=JSON.stringify(e)+`
|
|
99
|
+
`;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}
|
|
100
|
+
`}await Ps(this.path,t)}},ct=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)}}},lt=class{minLevel="debug";write(){}},ut=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 dt(this.resolveChannel(e))}debug(e,t={}){this.writeToDefault({level:"debug",message:e,context:t,timestamp:P()})}info(e,t={}){this.writeToDefault({level:"info",message:e,context:t,timestamp:P()})}warn(e,t={}){this.writeToDefault({level:"warn",message:e,context:t,timestamp:P()})}error(e,t={}){this.writeToDefault({level:"error",message:e,context:t,timestamp:P()})}fatal(e,t={}){this.writeToDefault({level:"fatal",message:e,context:t,timestamp:P()})}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 oe({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 oe(e);case"file":return new ot(e);case"stack":return new ct(e,t=>this.resolveChannel(t));case"null":return new lt;default:return new oe(e)}}},dt=class{constructor(e){this.channel=e}debug(e,t={}){this.channel.write({level:"debug",message:e,context:t,timestamp:P()})}info(e,t={}){this.channel.write({level:"info",message:e,context:t,timestamp:P()})}warn(e,t={}){this.channel.write({level:"warn",message:e,context:t,timestamp:P()})}error(e,t={}){this.channel.write({level:"error",message:e,context:t,timestamp:P()})}fatal(e,t={}){this.channel.write({level:"fatal",message:e,context:t,timestamp:P()})}};function P(){return new Date().toISOString()}var ht=p("svelar.log",()=>new ut);var S=class extends Error{constructor(t,s,r){super(s);this.statusCode=t;this.details=r;this.name="HttpError"}},Te=class extends S{constructor(e="The requested resource was not found"){super(404,e),this.name="NotFoundError"}},gt=class extends S{constructor(e="Unauthenticated"){super(401,e),this.name="UnauthorizedError"}},pt=class extends S{constructor(e="You do not have permission to perform this action"){super(403,e),this.name="ForbiddenError"}},Ce=class extends S{constructor(t,s="The given data was invalid"){super(422,s,{errors:t});this.errors=t;this.name="ValidationError"}};var mt=class extends Te{constructor(e,t){super(t?`${e} with ID ${t} not found`:`${e} not found`),this.name="ModelNotFoundError"}};function ft(o,e){throw new S(o,e??Ms(o))}function Rs(o,e,t){o&&ft(e,t)}function Ns(o,e,t){o||ft(e,t)}var ce=class{config;constructor(e={}){this.config={debug:process.env.NODE_ENV!=="production",dontReport:[Ce,Te,gt,pt],...e}}async handle(e,t){let s=e instanceof Error?e:new Error(String(e));return await this.reportError(s,t),this.config.render?this.config.render(s,t):this.renderError(s)}handleSvelteKitError(){return({error:e,event:t,status:s,message:r})=>{let n=e instanceof Error?e:new Error(String(e));return this.reportError(n,t),n instanceof S?{message:n.message,status:n.statusCode,...n.details??{},...this.config.debug?{stack:n.stack}:{}}:{message:this.config.debug?n.message:"An unexpected error occurred",status:s,...this.config.debug?{stack:n.stack}:{}}}}middleware(){let e=this;return async(t,s)=>{try{return await s()}catch(r){return e.handle(r,t.event)}}}async reportError(e,t){if(this.config.dontReport){for(let r of this.config.dontReport)if(e instanceof r)return}let s={error:e.name,...t?.url?{url:t.url.toString()}:{},...e.stack?{stack:e.stack}:{}};if(ht.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 S){let s={message:e.message};return e instanceof Ce&&(s.errors=e.errors),e.details&&Object.assign(s,e.details),this.config.debug&&(s.exception=e.name,s.stack=e.stack?.split(`
|
|
101
|
+
`).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(`
|
|
102
|
+
`).map(s=>s.trim())),new Response(JSON.stringify(t),{status:500,headers:{"Content-Type":"application/json"}})}};function Ms(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"}function Ds(o={}){let{auth:e,secret:t=process.env.APP_KEY||(()=>{throw new Error("APP_KEY is not set. Set it in your .env file.")})(),sessionStore:s,sessionLifetime:r=86400,rateLimit:n=100,rateLimitWindow:i=6e4,csrfPaths:a=["/api/"],csrfExcludePaths:c=["/api/webhooks"],authThrottleAttempts:l=5,authThrottleDecay:u=1,debug:h=process.env.NODE_ENV!=="production",middleware:g=[],namedMiddleware:b={},i18n:f,errorConfig:C={}}=o,x=[new Y,new X({maxRequests:n,windowMs:i}),new G({onlyPaths:a,excludePaths:c}),new re({store:s??new q,secret:t,lifetime:r})];e&&x.push(new ae(e)),x.push(...g);let us={"auth-throttle":new Z({maxAttempts:l,decayMinutes:u}),...b},Ut=new ce({debug:h,...C}),Bt=ts({middleware:x,namedMiddleware:us,onError:(ke,Oe)=>Ut.handle(ke,Oe)}),De;if(f){let{paraglideMiddleware:ke,getTextDirection:Oe=()=>"ltr"}=f;De=ss(async({event:$e,resolve:ds})=>ke($e.request,({request:hs,locale:Ht})=>($e.request=hs,ds($e,{transformPageChunk:({html:gs})=>gs.replace("%lang%",Ht).replace("%dir%",Oe(Ht))}))),Bt)}else De=Bt;return{handle:De,handleError:Ut.handleSvelteKitError()}}function ts(o={}){let e=new k;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 n={event:s,params:s.params??{},locals:s.locals??{}};try{o.app&&!o.app.isBooted()&&await o.app.bootstrap();let i=await e.execute(n,async()=>r(s));return i instanceof Response?i:r(s)}catch(i){if(o.onError){let a=await o.onError(i,s);if(a instanceof Response)return a}return console.error("[Svelar] Unhandled error in hooks:",i),new Response(JSON.stringify({message:process.env.NODE_ENV==="production"?"Internal server error":i.message}),{status:500,headers:{"Content-Type":"application/json"}})}}}function ss(...o){return async function({event:t,resolve:s}){let r=s;for(let n=o.length-1;n>=0;n--){let i=o[n],a=r;r=c=>i({event:c,resolve:a})}return r(t)}}T();function ks(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 yt=class{items=new Map;clear(){this.items.clear()}load(e){for(let[t,s]of Object.entries(e))this.set(t,s)}async loadFromDirectory(e){let{resolve:t,basename:s,extname:r}=await import("path"),{existsSync:n,readdirSync:i}=await import("fs"),{pathToFileURL:a}=await import("url"),c=t(e);if(!n(c))return[];let l=i(c).filter(h=>(h.endsWith(".ts")||h.endsWith(".js"))&&!h.startsWith(".")),u=[];for(let h of l){let g=s(h,r(h)),b=t(c,h);try{let C=await import(a(b).href),x=C.default??C.config??C;x&&typeof x=="object"&&!Array.isArray(x)&&(this.set(g,x),u.push(g))}catch{}}return u}get(e,t){let s=e.split("."),r=this.items.get(s[0]);for(let n=1;n<s.length;n++){if(r==null)return t;r=r[s[n]]}return r??t}set(e,t){let s=e.split(".");if(s.length===1){this.items.set(e,t);return}let r=this.items.get(s[0]);(r===void 0||typeof r!="object")&&(r={},this.items.set(s[0],r));let n=r;for(let i=1;i<s.length-1;i++)(n[s[i]]===void 0||typeof n[s[i]]!="object")&&(n[s[i]]={}),n=n[s[i]];n[s[s.length-1]]=t}has(e){return this.get(e)!==void 0}all(){let e={};for(let[t,s]of this.items)e[t]=s;return e}},Os=p("svelar.config",()=>new yt);import{z as w}from"zod";var $s={required:()=>w.string().min(1,"This field is required"),email:()=>w.string().email("Must be a valid email address"),string:(o,e)=>{let t=w.string();return o!==void 0&&(t=t.min(o)),e!==void 0&&(t=t.max(e)),t},number:(o,e)=>{let t=w.number();return o!==void 0&&(t=t.min(o)),e!==void 0&&(t=t.max(e)),t},integer:()=>w.number().int(),boolean:()=>w.boolean(),date:()=>w.coerce.date(),url:()=>w.string().url(),uuid:()=>w.string().uuid(),enum:o=>w.enum(o),array:o=>w.array(o),nullable:o=>o.nullable(),optional:o=>o.optional(),confirmed:(o="password")=>w.object({[o]:w.string(),[`${o}_confirmation`]:w.string()}).refine(e=>e[o]===e[`${o}_confirmation`],{message:"Confirmation does not match",path:[`${o}_confirmation`]}),min:o=>w.number().min(o),max:o=>w.number().max(o),between:(o,e)=>w.number().min(o).max(e),regex:(o,e)=>w.string().regex(o,e),ip:()=>w.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:()=>w.string().refine(o=>{try{return JSON.parse(o),!0}catch{return!1}},{message:"Must be valid JSON"})};function Ls(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 n=r.path.length>0?r.path:["_root"],i=s;for(let c=0;c<n.length-1;c++){let l=n[c];l in i||(i[l]={}),i=i[l]}let a=n[n.length-1];i[a]||(i[a]=[]),i[a].push(r.message)}return{success:!1,errors:s}}_();wt();T();import{readFile as ns,writeFile as Is,unlink as js,mkdir as de,readdir as bt,stat as is,copyFile as qs,rename as _s}from"fs/promises";import{existsSync as Us}from"fs";import{join as Bs,dirname as xe}from"path";var vt=class{constructor(e){this.config=e;if(!e.root)throw new Error('Local disk requires a "root" path.')}resolve(e){return Bs(this.config.root,e)}async get(e){return ns(this.resolve(e))}async getText(e){return ns(this.resolve(e),"utf-8")}async put(e,t){let s=this.resolve(e);await de(xe(s),{recursive:!0}),await Is(s,t)}async append(e,t){let{appendFile:s}=await import("fs/promises"),r=this.resolve(e);await de(xe(r),{recursive:!0}),await s(r,t)}async exists(e){return Us(this.resolve(e))}async delete(e){try{return await js(this.resolve(e)),!0}catch{return!1}}async copy(e,t){let s=this.resolve(t);await de(xe(s),{recursive:!0}),await qs(this.resolve(e),s)}async move(e,t){let s=this.resolve(t);await de(xe(s),{recursive:!0}),await _s(this.resolve(e),s)}async files(e=""){let t=this.resolve(e);try{return(await bt(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 bt(s,{withFileTypes:!0});for(let n of r){let i=e?`${e}/${n.name}`:n.name;n.isFile()?t.push(i):n.isDirectory()&&t.push(...await this.allFiles(i))}}catch{}return t}async directories(e=""){let t=this.resolve(e);try{return(await bt(t,{withFileTypes:!0})).filter(r=>r.isDirectory()).map(r=>e?`${e}/${r.name}`:r.name)}catch{return[]}}async makeDirectory(e){await de(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 is(this.resolve(e))).size}async lastModified(e){return(await is(this.resolve(e))).mtime}url(e){return`${this.config.urlPrefix??""}/${e}`}},Pe=class{config;_client=null;_s3Module=null;constructor(e){if(!e.bucket)throw new Error('S3 disk requires a "bucket" name.');this.config=e}async getS3(){if(this._s3Module)return this._s3Module;try{return this._s3Module=await Function('return import("@aws-sdk/client-s3")')(),this._s3Module}catch{throw new Error("S3 storage driver requires @aws-sdk/client-s3. Install it with: npm install @aws-sdk/client-s3")}}async getClient(){if(this._client)return this._client;let e=await this.getS3();return this._client=new e.S3Client({region:this.config.region??"us-east-1",endpoint:this.config.endpoint,forcePathStyle:this.config.forcePathStyle??!0,credentials:{accessKeyId:this.config.accessKeyId??"",secretAccessKey:this.config.secretAccessKey??""}}),this._client}key(e){let t=this.config.prefix;return t?`${t}/${e}`:e}async get(e){let t=await this.getS3(),n=await(await(await this.getClient()).send(new t.GetObjectCommand({Bucket:this.config.bucket,Key:this.key(e)}))).Body.transformToByteArray();return Buffer.from(n)}async getText(e){return(await this.get(e)).toString("utf-8")}async put(e,t){let s=await this.getS3(),r=await this.getClient(),n=typeof t=="string"?Buffer.from(t,"utf-8"):t;await r.send(new s.PutObjectCommand({Bucket:this.config.bucket,Key:this.key(e),Body:n}))}async append(e,t){let s=null;try{s=await this.get(e)}catch{}let r=typeof t=="string"?Buffer.from(t,"utf-8"):t,n=s?Buffer.concat([s,r]):r;await this.put(e,n)}async exists(e){let t=await this.getS3(),s=await this.getClient();try{return await s.send(new t.HeadObjectCommand({Bucket:this.config.bucket,Key:this.key(e)})),!0}catch{return!1}}async delete(e){let t=await this.getS3(),s=await this.getClient();try{return await s.send(new t.DeleteObjectCommand({Bucket:this.config.bucket,Key:this.key(e)})),!0}catch{return!1}}async copy(e,t){let s=await this.getS3();await(await this.getClient()).send(new s.CopyObjectCommand({Bucket:this.config.bucket,CopySource:`${this.config.bucket}/${this.key(e)}`,Key:this.key(t)}))}async move(e,t){await this.copy(e,t),await this.delete(e)}async files(e=""){let t=await this.getS3(),s=await this.getClient(),r=this.key(e?`${e}/`:"");try{return((await s.send(new t.ListObjectsV2Command({Bucket:this.config.bucket,Prefix:r,Delimiter:"/"}))).Contents??[]).map(i=>i.Key).filter(i=>i!==r).map(i=>{let a=this.config.prefix;return a?i.slice(a.length+1):i})}catch{return[]}}async allFiles(e=""){let t=await this.getS3(),s=await this.getClient(),r=this.key(e?`${e}/`:""),n=[],i;do{let a=await s.send(new t.ListObjectsV2Command({Bucket:this.config.bucket,Prefix:r,ContinuationToken:i}));for(let c of a.Contents??[]){let l=this.config.prefix,u=l?c.Key.slice(l.length+1):c.Key;u&&n.push(u)}i=a.IsTruncated?a.NextContinuationToken:void 0}while(i);return n}async directories(e=""){let t=await this.getS3(),s=await this.getClient(),r=this.key(e?`${e}/`:"");try{return((await s.send(new t.ListObjectsV2Command({Bucket:this.config.bucket,Prefix:r,Delimiter:"/"}))).CommonPrefixes??[]).map(i=>{let a=this.config.prefix;return(a?i.Prefix.slice(a.length+1):i.Prefix).replace(/\/$/,"")}).filter(i=>i.length>0)}catch{return[]}}async makeDirectory(e){}async deleteDirectory(e){let t=await this.allFiles(e);for(let s of t)await this.delete(s)}async size(e){let t=await this.getS3();return(await(await this.getClient()).send(new t.HeadObjectCommand({Bucket:this.config.bucket,Key:this.key(e)}))).ContentLength??0}async lastModified(e){let t=await this.getS3();return(await(await this.getClient()).send(new t.HeadObjectCommand({Bucket:this.config.bucket,Key:this.key(e)}))).LastModified??new Date}url(e){let t=this.config.urlPrefix;if(t)return`${t}/${e}`;let s=this.config.endpoint??`https://s3.${this.config.region??"us-east-1"}.amazonaws.com`;return this.config.forcePathStyle!==!1?`${s}/${this.config.bucket}/${this.key(e)}`:`${s.replace("://",`://${this.config.bucket}.`)}/${this.key(e)}`}async temporaryUrl(e,t=3600){try{let s=await Function('return import("@aws-sdk/s3-request-presigner")')(),r=await this.getS3(),n=await this.getClient(),i=new r.GetObjectCommand({Bucket:this.config.bucket,Key:this.key(e)});return await s.getSignedUrl(n,i,{expiresIn:t})}catch{throw new Error("Pre-signed URLs require @aws-sdk/s3-request-presigner. Install it with: npm install @aws-sdk/s3-request-presigner")}}async ensureBucket(){let e=await this.getS3(),t=await this.getClient();try{await t.send(new e.HeadBucketCommand({Bucket:this.config.bucket}))}catch{await t.send(new e.CreateBucketCommand({Bucket:this.config.bucket}))}}},Tt=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 vt(e);case"s3":return new Pe(e);default:throw new Error(`Unknown storage driver: ${e.driver}`)}}s3Disk(e){let t=this.disk(e);if(!(t instanceof Pe))throw new Error(`Disk "${e??this.config?.default}" is not an S3 disk.`);return t}},Hs=p("svelar.storage",()=>new Tt);T();import{readFile as Fs,writeFile as Ks,unlink as as,mkdir as os}from"fs/promises";import{join as Js,dirname as Qs}from"path";import{createHash as Ws}from"crypto";var Ct=class{store=new Map;async get(e){let t=this.store.get(e);return t?t.expiresAt&&Date.now()>t.expiresAt?(this.store.delete(e),null):t.value:null}async put(e,t,s){this.store.set(e,{value:t,expiresAt:s?Date.now()+s*1e3:null})}async forget(e){return this.store.delete(e)}async flush(){this.store.clear()}async has(e){let t=this.store.get(e);return t?t.expiresAt&&Date.now()>t.expiresAt?(this.store.delete(e),!1):!0:!1}async increment(e,t=1){let r=(await this.get(e)??0)+t,n=this.store.get(e);return await this.put(e,r,n?.expiresAt?Math.ceil((n.expiresAt-Date.now())/1e3):void 0),r}async decrement(e,t=1){return this.increment(e,-t)}},Et=class{basePath;constructor(e){this.basePath=e.path??"storage/cache"}filePath(e){let t=Ws("md5").update(e).digest("hex");return Js(this.basePath,t.slice(0,2),t)}async get(e){let t=this.filePath(e);try{let s=await Fs(t,"utf-8"),r=JSON.parse(s);return r.expiresAt&&Date.now()>r.expiresAt?(await as(t).catch(()=>{}),null):r.value}catch{return null}}async put(e,t,s){let r=this.filePath(e),n={value:t,expiresAt:s?Date.now()+s*1e3:null};await os(Qs(r),{recursive:!0}),await Ks(r,JSON.stringify(n))}async forget(e){try{return await as(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 os(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)}},xt=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}},Pt=class{config={default:"memory",stores:{memory:{driver:"memory"}}};stores=new Map;configure(e){this.config=e,this.stores.clear()}store(e){let t=e??this.config.default;if(this.stores.has(t))return this.stores.get(t);let s=this.config.stores[t];if(!s)throw new Error(`Cache store "${t}" is not defined.`);let r=this.createStore(s);return this.stores.set(t,r),r}async get(e,t){let s=this.store();return await s.has(e)?s.get(e):t??null}async put(e,t,s){return this.store().put(e,t,s??this.config.stores[this.config.default]?.ttl)}async forget(e){return this.store().forget(e)}async flush(){return this.store().flush()}async has(e){return this.store().has(e)}async increment(e,t){return this.store().increment(e,t)}async decrement(e,t){return this.store().decrement(e,t)}async remember(e,t,s){let r=await this.store().get(e);if(r!==null)return r;let n=await s();return await this.store().put(e,n,t),n}async rememberForever(e,t){let s=await this.store().get(e);if(s!==null)return s;let r=await t();return await this.store().put(e,r),r}async pull(e,t){let s=await this.get(e,t);return await this.forget(e),s}createStore(e){switch(e.driver){case"memory":return new Ct;case"file":return new Et(e);case"null":return new xt;case"redis":throw new Error("Redis cache requires ioredis. Install: npm install ioredis");default:throw new Error(`Unknown cache driver: ${e.driver}`)}}},Vs=p("svelar.cache",()=>new Pt);T();var Se=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)}},Ae=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(){}},St=class{queues=new Map;async push(e){let t=e.queue;this.queues.has(t)||this.queues.set(t,[]),this.queues.get(t).push(e)}async pop(e="default"){let t=this.queues.get(e)??[],s=Date.now(),r=t.findIndex(n=>n.availableAt<=s);return r===-1?null:t.splice(r,1)[0]}async size(e="default"){return this.queues.get(e)?.length??0}async clear(e){e?this.queues.delete(e):this.queues.clear()}},B=class{constructor(e,t){this.table=e;this.registry=t}async getConnection(){let{Connection:e}=await Promise.resolve().then(()=>(m(),y));return e}async push(e){await(await this.getConnection()).raw(`INSERT INTO ${this.table} (id, queue, payload, attempts, max_attempts, available_at, created_at)
|
|
103
|
+
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}
|
|
104
|
+
WHERE queue = ? AND available_at <= ? AND reserved_at IS NULL
|
|
105
|
+
ORDER BY created_at ASC LIMIT 1`,[e,s]);if(!r||r.length===0)return null;let n=r[0];await t.raw(`UPDATE ${this.table} SET reserved_at = ?, attempts = attempts + 1 WHERE id = ?`,[s,n.id]);let i=JSON.parse(n.payload),a=this.registry.resolve(i.jobClass,i.payload);return{id:n.id,jobClass:i.jobClass,payload:i.payload,queue:n.queue,attempts:n.attempts+1,maxAttempts:n.max_attempts,availableAt:n.available_at*1e3,createdAt:n.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])}},Re=class{queues=new Map;config;registry;_bullmq=null;constructor(e,t){this.config=e,this.registry=t}async getBullMQ(){if(this._bullmq)return this._bullmq;try{return this._bullmq=await Function('return import("bullmq")')(),this._bullmq}catch{throw new Error("bullmq is required for the Redis queue driver. Install it with: npm install bullmq")}}getRedisConnection(){if(this.config.url){let e=new URL(this.config.url);return{host:e.hostname||"localhost",port:parseInt(e.port)||6379,password:e.password||this.config.password||void 0,db:parseInt(e.pathname?.slice(1)||"0")||this.config.db||0}}return{host:this.config.host??"localhost",port:this.config.port??6379,password:this.config.password,db:this.config.db??0}}async getQueue(e){if(this.queues.has(e))return this.queues.get(e);let t=await this.getBullMQ(),s=this.getRedisConnection(),r=this.config.prefix??"svelar",n=new t.Queue(e,{connection:s,prefix:r,defaultJobOptions:{removeOnComplete:this.config.defaultJobOptions?.removeOnComplete??100,removeOnFail:this.config.defaultJobOptions?.removeOnFail??500}});return this.queues.set(e,n),n}async push(e){let t=await this.getQueue(e.queue),s=Math.max(0,e.availableAt-Date.now());await t.add(e.jobClass,{jobClass:e.jobClass,payload:e.payload},{jobId:e.id,delay:s>0?s:void 0,attempts:e.maxAttempts,backoff:{type:"fixed",delay:(e.job.retryDelay??60)*1e3}})}async pop(e){return null}async size(e="default"){let s=await(await this.getQueue(e)).getJobCounts("waiting","delayed","active");return s.waiting+s.delayed+s.active}async clear(e){if(e)await(await this.getQueue(e)).obliterate({force:!0});else for(let t of this.queues.values())await t.obliterate({force:!0})}async createWorker(e,t,s,r){let n=await this.getBullMQ(),i=this.getRedisConnection(),a=this.config.prefix??"svelar",c=new n.Worker(e,async l=>{let u=l.data,h=t.resolve(u.jobClass,u.payload);h.attempts=l.attemptsMade+1,await h.handle()},{connection:i,prefix:a,concurrency:r?.concurrency??1});return c.on("failed",async(l,u)=>{let h=l?.data;if(h)try{let g=t.resolve(h.jobClass,h.payload);l.attemptsMade>=(l.opts?.attempts??3)&&(g.failed(u),await s.store({id:l.id,jobClass:h.jobClass,payload:h.payload,queue:e,attempts:l.attemptsMade,maxAttempts:l.opts?.attempts??3,availableAt:Date.now(),createdAt:l.timestamp??Date.now(),job:g},u))}catch{console.error("[Queue] Failed to resolve job for failure handler:",u.message)}}),c}},At=class{table="svelar_failed_jobs";async getConnection(){let{Connection:e}=await Promise.resolve().then(()=>(m(),y));return e}async store(e,t){try{await(await this.getConnection()).raw(`INSERT INTO ${this.table} (id, queue, job_class, payload, exception, failed_at)
|
|
106
|
+
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}},Rt=class{jobs=new Map;register(e){this.jobs.set(e.name,e)}registerAll(e){for(let t of e)this.register(t)}resolve(e,t){let s=this.jobs.get(e);if(!s)throw new Error(`Job class "${e}" is not registered. Call Queue.register(${e}) in your app bootstrap. Registered jobs: [${[...this.jobs.keys()].join(", ")}]`);let r=Object.create(s.prototype);r.attempts=0,r.maxAttempts=3,r.retryDelay=60,r.queue="default";try{let n=JSON.parse(t);r.restore(n)}catch{}return r}has(e){return this.jobs.has(e)}},Nt=class{config={default:"sync",connections:{sync:{driver:"sync"}}};drivers=new Map;processing=!1;jobRegistry=new Rt;failedStore=new At;_activeWorker=null;configure(e){this.config=e,this.drivers.clear()}register(e){this.jobRegistry.register(e)}registerAll(e){this.jobRegistry.registerAll(e)}async dispatch(e,t){let s=this.config.default,r=this.config.connections[s],n=this.resolveDriver(s);t?.queue&&(e.queue=t.queue),t?.maxAttempts!==void 0&&(e.maxAttempts=t.maxAttempts);let i={id:crypto.randomUUID(),jobClass:e.constructor.name,payload:e.serialize(),queue:e.queue??r?.queue??"default",attempts:0,maxAttempts:e.maxAttempts,availableAt:Date.now()+(t?.delay??0)*1e3,createdAt:Date.now(),job:e};await n.push(i)}async dispatchSync(e){let t=new Ae,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 Mt(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 Re){let c=await s.createWorker(r,this.jobRegistry,this.failedStore,{concurrency:e?.concurrency??1});return this.processing=!0,this._activeWorker=c,await new Promise(l=>{let u=()=>{this.processing?setTimeout(u,500):c.close().then(l).catch(l)};u()}),0}let n=e?.maxJobs??1/0,i=(e?.sleep??1)*1e3,a=0;for(this.processing=!0;this.processing&&a<n;){let c=await s.pop(r);if(!c){if(n===1/0){await new Promise(l=>setTimeout(l,i));continue}break}c.attempts++,c.job.attempts=c.attempts;try{await c.job.handle(),a++,s instanceof B&&await s.delete(c.id)}catch(l){if(c.attempts<c.maxAttempts){c.job.retrying(c.attempts);let u=c.job.retryDelay??60;s instanceof B?await s.release(c.id,u):(c.availableAt=Date.now()+u*1e3,await s.push(c))}else c.job.failed(l),await this.failedStore.store(c,l),s instanceof B&&await s.delete(c.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 Ae;break;case"memory":s=new St;break;case"database":s=new B(t.table??"svelar_jobs",this.jobRegistry);break;case"redis":s=new Re(t,this.jobRegistry);break;default:throw new Error(`Unknown queue driver: ${t.driver}`)}return this.drivers.set(e,s),s}},Mt=class extends Se{remainingJobs;constructor(e){super(),this.remainingJobs=[...e],this.maxAttempts=1}async handle(){for(let e of this.remainingJobs){let t=null,s=!1;for(let r=1;r<=e.maxAttempts;r++){e.attempts=r;try{await e.handle(),s=!0;break}catch(n){t=n,r<e.maxAttempts&&(e.retrying(r),e.retryDelay>0&&await new Promise(i=>setTimeout(i,e.retryDelay*1e3)))}}if(!s&&t)throw e.failed(t),new Error(`Chain stopped: ${e.constructor.name} failed after ${e.maxAttempts} attempt(s). Remaining jobs: [${this.remainingJobs.slice(this.remainingJobs.indexOf(e)+1).map(r=>r.constructor.name).join(", ")}]`)}}serialize(){return JSON.stringify({jobs:this.remainingJobs.map(e=>({jobClass:e.constructor.name,payload:e.serialize()}))})}},zs=p("svelar.queue",()=>new Nt);be();T();var Dt=class{},kt=class{async send(e,t){if(!t.toMail)return;let s=t.toMail(e),r=e.routeNotificationForMail?.()??e.getAttribute("email");if(!r){console.warn("[Notifications] No email address for notifiable.");return}try{let{Mailer:n}=await Promise.resolve().then(()=>(be(),nt));await n.send({to:r,subject:s.subject,html:s.html,text:s.text,from:s.from})}catch(n){console.error("[Notifications] Failed to send mail notification:",n)}}},Ot=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(()=>(m(),y));await r.raw(`INSERT INTO ${this.table} (id, notifiable_id, type, data, read_at, created_at)
|
|
107
|
+
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)}}},$t=class{channels=new Map;constructor(){this.channels.set("mail",new kt),this.channels.set("database",new Ot)}extend(e,t){this.channels.set(e,t)}async send(e,t){let s=Array.isArray(e)?e:[e];for(let r of s){let n=t.via(r);for(let i of n){let a=this.channels.get(i);if(a)try{await a.send(r,t)}catch(c){console.error(`[Notifications] Channel "${i}" failed:`,c)}else console.warn(`[Notifications] Unknown channel: ${i}`)}}}async sendVia(e,t,s){for(let r of s){let n=this.channels.get(r);n&&await n.send(e,t)}}},Xs=p("svelar.notifier",()=>new $t);T();function Lt(o){return o.startsWith("private-")?"private":o.startsWith("presence-")?"presence":"public"}var It=class{subscribers=[];name;type;constructor(e){this.name=e,this.type=Lt(e)}stream(e,t){let s=this,r=new ReadableStream({start(n){let i={channel:s.name};s.type==="presence"&&(i.members=s.getMembers());let a=`event: connected
|
|
108
|
+
data: ${JSON.stringify(i)}
|
|
109
|
+
id: ${Date.now()}
|
|
110
|
+
|
|
111
|
+
`;n.enqueue(new TextEncoder().encode(a));let c={controller:n,userId:e,userInfo:t};s.subscribers.push(c),s.type==="presence"&&e!==void 0&&s.sendInternal("member:joined",{id:e,...t},c)},cancel(){let n=s.subscribers.findIndex(a=>a.controller===this._controller),i=s.subscribers.length;s.subscribers=s.subscribers.filter(a=>{try{return a.controller.enqueue(new TextEncoder().encode(`:
|
|
112
|
+
|
|
113
|
+
`)),!0}catch{return!1}}),s.type==="presence"&&e!==void 0&&s.subscribers.length<i&&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}
|
|
114
|
+
data: ${JSON.stringify(t)}
|
|
115
|
+
id: ${Date.now()}
|
|
116
|
+
|
|
117
|
+
`,n=new TextEncoder().encode(r);for(let i of this.subscribers)if(!(s!==void 0&&i.userId!==s))try{i.controller.enqueue(n)}catch{}}sendInternal(e,t,s){let r=`event: ${e}
|
|
118
|
+
data: ${JSON.stringify(t)}
|
|
119
|
+
id: ${Date.now()}
|
|
120
|
+
|
|
121
|
+
`,n=new TextEncoder().encode(r);for(let i of this.subscribers)if(i!==s)try{i.controller.enqueue(n)}catch{}}toUser(e){return{send:(t,s)=>this.send(t,s,e)}}subscriberCount(){return this.subscribers.length}getMembers(){return this.type!=="presence"?[]:this.subscribers.filter(e=>e.userId!==void 0).map(e=>({id:e.userId,...e.userInfo??{}}))}hasMember(e){return this.subscribers.some(t=>t.userId===e)}whisper(e,t,s){let r=`event: client-${e}
|
|
122
|
+
data: ${JSON.stringify(t)}
|
|
123
|
+
id: ${Date.now()}
|
|
124
|
+
|
|
125
|
+
`,n=new TextEncoder().encode(r);for(let i of this.subscribers)if(i.userId!==s)try{i.controller.enqueue(n)}catch{}}},Ne=class{config;constructor(e){this.config=e}async send(e,t,s){let r=Array.isArray(e)?e:[e],n=JSON.stringify({name:t,channels:r,data:JSON.stringify(s)}),i=Math.floor(Date.now()/1e3).toString(),a=await this.md5(n),c=["POST",`/apps/${this.config.appId}/events`,[`auth_key=${this.config.key}`,`auth_timestamp=${i}`,"auth_version=1.0",`body_md5=${a}`].join("&")].join(`
|
|
126
|
+
`),l=await this.hmacSha256(this.config.secret,c),u=this.config.useTLS!==!1?"https":"http",h=this.config.host??`api-${this.config.cluster??"mt1"}.pusher.com`,g=this.config.port??(this.config.useTLS!==!1?443:80),b=`${u}://${h}:${g}/apps/${this.config.appId}/events?auth_key=${this.config.key}&auth_timestamp=${i}&auth_version=1.0&body_md5=${a}&auth_signature=${l}`,f=await fetch(b,{method:"POST",headers:{"Content-Type":"application/json"},body:n});if(!f.ok){let C=await f.text();throw new Error(`Pusher API error (${f.status}): ${C}`)}}async authenticate(e,t,s){let r=`${e}:${t}`,n;s&&(n=JSON.stringify(s),r+=`:${n}`);let i=await this.hmacSha256(this.config.secret,r),a=`${this.config.key}:${i}`;return n?{auth:a,channel_data:n}:{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")}},jt=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)}},qt=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 Ne(t))}channel(e,t){if(t){this.channelAuth.set(e,t);return}return this.sseChannels.has(e)||this.sseChannels.set(e,new It(e)),this.sseChannels.get(e)}async authorize(e,t){if(Lt(e)==="public")return!0;for(let[r,n]of this.channelAuth){let i=this.matchPattern(r,e);if(i!==null)return await n(t,i)}return!1}async authenticatePusher(e,t,s){if(!this.pusherDriver)throw new Error("Pusher driver is not configured. Call Broadcast.configure() first.");let r=Lt(e);if(r==="public")return!1;let n=await this.authorize(e,s);if(n===!1)return!1;if(r==="presence"){let i=typeof n=="object"?{user_id:n.id??s.id,user_info:n}:{user_id:s.id,user_info:{id:s.id}};return this.pusherDriver.authenticate(t,e,i)}return this.pusherDriver.authenticate(t,e)}event(e,t){return new jt(this,e,t)}to(e,t){return{send:async(s,r)=>{await this.sendToChannel(e,s,r,t)}}}async sendToChannel(e,t,s,r){let n=this.config.drivers[this.config.default];switch(n?.driver){case"pusher":this.pusherDriver||(this.pusherDriver=new Ne(n)),await this.pusherDriver.send(e,t,s);break;case"log":console.log(`[Broadcast] ${e} \u2192 ${t}:`,JSON.stringify(s));break;default:for(let[,i]of this.sseChannels)i.name===e&&i.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,c=>c==="{"||c==="}"?c:`\\${c}`).replace(/\\\{(\w+)\\\}/g,(c,l)=>(s.push(l),"([^.]+)")).replace(/\{(\w+)\}/g,(c,l)=>(s.push(l),"([^.]+)")),n=new RegExp(`^${r}$`),i=t.match(n);if(!i)return null;let a={};for(let c=0;c<s.length;c++)a[s[c]]=i[c+1];return a}},Gs=p("svelar.broadcast",()=>new qt);var Ys={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."},cs=null;function Me(o,e,t){cs&&cs(o,e,{description:t})}async function Zs(o,e={}){let{csrfCookieName:t="XSRF-TOKEN",csrfHeaderName:s="X-CSRF-Token",showToast:r=!0,errorMessages:n={},...i}=e,a=(i.method||"GET").toUpperCase(),c=new Headers(i.headers);if(["POST","PUT","PATCH","DELETE"].includes(a)){let l=ls(t);l&&c.set(s,l)}i.body&&typeof i.body=="string"&&!c.has("Content-Type")&&c.set("Content-Type","application/json"),c.has("Accept")||c.set("Accept","application/json");try{let l=await fetch(o,{...i,headers:c});return!l.ok&&r&&await er(l,{...Ys,...n}),l}catch(l){throw r&&Me("error","Network Error","Unable to connect. Check your internet connection."),l}}async function er(o,e){let t="";try{if((o.headers.get("content-type")??"").includes("application/json")){let i=await o.clone().json();if(t=i.message??"",o.status===422&&i.errors){let a=Object.entries(i.errors).map(([c,l])=>`${c}: ${l.join(", ")}`).slice(0,3).join(`
|
|
127
|
+
`);Me("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){Me("warning",s,"Please sign in to continue.");return}Me(r,s)}function ls(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 tr(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 _t=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),n={...this._headers},i;s!==void 0&&(n["Content-Type"]||(n["Content-Type"]="application/json"),i=typeof s=="string"?s:JSON.stringify(s)),n.Accept||(n.Accept="application/json");let a=null,c=1+this._retries;for(let l=0;l<c;l++){l>0&&await new Promise(u=>setTimeout(u,this._retryDelay*l));try{let u=new AbortController,h=setTimeout(()=>u.abort(),this._timeout),g=await fetch(r,{method:e,headers:n,body:i,signal:u.signal});if(clearTimeout(h),!g.ok&&g.status<500&&l<c-1,!g.ok&&g.status>=500&&l<c-1){a=new H(`HTTP ${g.status}: ${g.statusText}`,g.status,await g.text());continue}let b=g.headers.get("content-type")??"",f;if(b.includes("application/json")?f=await g.json():f=await g.text(),!g.ok)throw new H(`HTTP ${g.status}: ${typeof f=="string"?f:JSON.stringify(f)}`,g.status,f);return{data:f,status:g.status,headers:g.headers,ok:!0}}catch(u){if(u instanceof H)throw u;if(a=u,u.name==="AbortError"&&(a=new H("Request timed out",0,null)),l>=c-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[n,i]of s)r.searchParams.set(n,i);t=r.toString()}return t}},H=class extends Error{constructor(t,s,r){super(t);this.status=s;this.body=r;this.name="HttpRequestError"}},Un=new _t;function sr(o){let{paraglideMiddleware:e,getTextDirection:t=()=>"ltr",langPlaceholder:s="%lang%",dirPlaceholder:r="%dir%"}=o;return({event:n,resolve:i})=>e(n.request,({request:a,locale:c})=>(n.request=a,i(n,{transformPageChunk:({html:l})=>l.replace(s,c).replace(r,t(c))})))}function rr(o){return e=>o.deLocalizeUrl(e.url).pathname}function nr(o,e,t={}){return async s=>{let{superValidate:r,fail:n,message:i}=await import("sveltekit-superforms"),{zod:a}=await import("sveltekit-superforms/adapters"),c=await r(s,a(o));if(!c.valid)return n(400,{form:c});try{let l=await e(c.data,s);if(t.redirectTo){let{redirect:u}=await import("@sveltejs/kit");throw u(303,t.redirectTo)}return l??{form:c}}catch(l){if(l?.status>=300&&l?.status<400)throw l;return i(c,t.errorMessage||l.message||"An error occurred",{status:l.status||400})}}}async function ir(o,e){let{superValidate:t}=await import("sveltekit-superforms"),{zod:s}=await import("sveltekit-superforms/adapters");return t(e??null,s(o))}async function ar(o,e){let t=await o.request.formData(),s={};for(let[n,i]of t.entries())s[n]=i;let r=e.safeParse(s);if(!r.success){let{FormValidationError:n}=await Promise.resolve().then(()=>(wt(),rs));throw new n(r.error.flatten().fieldErrors)}return r.data}export{Be as Application,it as AuthManager,ae as AuthenticateMiddleware,Q as BelongsTo,W as BelongsToMany,Gs as Broadcast,Vs as Cache,M as ColumnBuilder,d as Connection,I as Container,Je as Controller,He as CorsMiddleware,G as CsrfMiddleware,Qe as DatabaseSessionStore,ce as ErrorHandler,V as Event,ge as EventDispatcher,We as FileSessionStore,fe as ForbiddenError,ue as FormAuthorizationError,Ee as FormRequest,le as FormValidationError,J as HasMany,K as HasOne,Jt as Hash,S as HttpError,Se as Job,ht as Log,Fe as LoggingMiddleware,we as Mailable,zt as Mailer,q as MemorySessionStore,v as Middleware,k as MiddlewareStack,qe as Migration,_e as Migrator,Ie as Model,mt as ModelNotFoundError,pe as NotFoundError,Dt as Notification,Xs as Notifier,Y as OriginMiddleware,A as QueryBuilder,zs as Queue,X as RateLimitMiddleware,Ve as RedisSessionStore,at as RequireAuthMiddleware,D as Schema,Ue as Seeder,he as ServiceProvider,se as Session,re as SessionMiddleware,Ke as SignatureMiddleware,Hs as Storage,z as TableBuilder,Z as ThrottleMiddleware,me as UnauthorizedError,O as ValidationError,ft as abort,Rs as abortIf,Ns as abortUnless,Zs as apiFetch,tr as buildUrl,Os as config,ys as container,nr as createFormAction,sr as createI18nHandle,rr as createReroute,Ds as createSvelarApp,ts as createSvelarHooks,ks as env,ls as getCsrfToken,ir as loadForm,ws as resource,$s as rules,fs as schema,ss as sequence,Zt as signJwt,Ls as validate,ar as validateForm,es as verifyJwt,w as z};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Log Viewer
|
|
3
|
+
*
|
|
4
|
+
* Utility for inspecting and filtering logs from the admin dashboard.
|
|
5
|
+
* Stores recent logs in a ring buffer and provides live tailing support.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { LogViewer } from 'svelar/logging';
|
|
10
|
+
*
|
|
11
|
+
* // Query logs with filtering
|
|
12
|
+
* const errors = LogViewer.getRecentErrors(10);
|
|
13
|
+
*
|
|
14
|
+
* // Get stats
|
|
15
|
+
* const stats = LogViewer.getStats();
|
|
16
|
+
*
|
|
17
|
+
* // Live tailing
|
|
18
|
+
* const unsubscribe = LogViewer.tail((entry) => {
|
|
19
|
+
* console.log(`${entry.level}: ${entry.message}`);
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* // Stop tailing
|
|
23
|
+
* unsubscribe();
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
import type { LogLevel } from './index.js';
|
|
27
|
+
export interface LogEntry {
|
|
28
|
+
timestamp: string;
|
|
29
|
+
level: LogLevel;
|
|
30
|
+
channel: string;
|
|
31
|
+
message: string;
|
|
32
|
+
context: Record<string, any>;
|
|
33
|
+
}
|
|
34
|
+
export interface LogFilter {
|
|
35
|
+
level?: LogLevel;
|
|
36
|
+
channel?: string;
|
|
37
|
+
since?: Date;
|
|
38
|
+
until?: Date;
|
|
39
|
+
search?: string;
|
|
40
|
+
limit?: number;
|
|
41
|
+
offset?: number;
|
|
42
|
+
}
|
|
43
|
+
export interface LogStats {
|
|
44
|
+
totalEntries: number;
|
|
45
|
+
byLevel: Record<string, number>;
|
|
46
|
+
byChannel: Record<string, number>;
|
|
47
|
+
}
|
|
48
|
+
type TailCallback = (entry: LogEntry) => void;
|
|
49
|
+
declare class LogViewerService {
|
|
50
|
+
private ringBuffer;
|
|
51
|
+
private maxSize;
|
|
52
|
+
private currentIndex;
|
|
53
|
+
private tailSubscribers;
|
|
54
|
+
/**
|
|
55
|
+
* Add a log entry to the ring buffer.
|
|
56
|
+
* Called internally by the logging system.
|
|
57
|
+
*/
|
|
58
|
+
addEntry(entry: Omit<LogEntry, 'channel'> & {
|
|
59
|
+
channel?: string;
|
|
60
|
+
}): void;
|
|
61
|
+
/**
|
|
62
|
+
* Query logs with filtering and pagination.
|
|
63
|
+
*/
|
|
64
|
+
query(filter?: LogFilter): LogEntry[];
|
|
65
|
+
/**
|
|
66
|
+
* Get log statistics.
|
|
67
|
+
*/
|
|
68
|
+
getStats(): LogStats;
|
|
69
|
+
/**
|
|
70
|
+
* Get recent errors and critical logs (shortcut).
|
|
71
|
+
*/
|
|
72
|
+
getRecentErrors(limit?: number): LogEntry[];
|
|
73
|
+
/**
|
|
74
|
+
* Clear all stored logs.
|
|
75
|
+
*/
|
|
76
|
+
clear(): void;
|
|
77
|
+
/**
|
|
78
|
+
* Register a callback for live log tailing.
|
|
79
|
+
* Returns an unsubscribe function.
|
|
80
|
+
*/
|
|
81
|
+
tail(callback: TailCallback, filter?: LogFilter): () => void;
|
|
82
|
+
/**
|
|
83
|
+
* Get all entries from the ring buffer in chronological order.
|
|
84
|
+
*/
|
|
85
|
+
private getAllEntries;
|
|
86
|
+
/**
|
|
87
|
+
* Check if a log entry matches the given filter.
|
|
88
|
+
*/
|
|
89
|
+
private matchesFilter;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Global LogViewer singleton
|
|
93
|
+
*/
|
|
94
|
+
export declare const LogViewer: LogViewerService;
|
|
95
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function o(a,t){let e=Symbol.for(a),n=globalThis;return n[e]||(n[e]=t()),n[e]}var l=class{ringBuffer=[];maxSize=1e4;currentIndex=0;tailSubscribers=[];addEntry(t){let e={timestamp:t.timestamp,level:t.level,channel:t.channel??"default",message:t.message,context:t.context};this.ringBuffer.length<this.maxSize?this.ringBuffer.push(e):(this.ringBuffer[this.currentIndex]=e,this.currentIndex=(this.currentIndex+1)%this.maxSize);for(let n of this.tailSubscribers)try{n(e)}catch{}}query(t={}){let e=this.getAllEntries();if(t.level){let i={debug:0,info:1,warn:2,error:3,fatal:4},r=i[t.level];e=e.filter(c=>i[c.level]>=r)}if(t.channel&&(e=e.filter(i=>i.channel===t.channel)),t.since){let i=t.since.getTime();e=e.filter(r=>new Date(r.timestamp).getTime()>=i)}if(t.until){let i=t.until.getTime();e=e.filter(r=>new Date(r.timestamp).getTime()<=i)}if(t.search){let i=t.search.toLowerCase();e=e.filter(r=>r.message.toLowerCase().includes(i)||JSON.stringify(r.context).toLowerCase().includes(i))}let n=t.offset??0,s=t.limit??100;return e.slice(n,n+s)}getStats(){let t=this.getAllEntries(),e={totalEntries:t.length,byLevel:{},byChannel:{}};for(let n of t)e.byLevel[n.level]=(e.byLevel[n.level]??0)+1,e.byChannel[n.channel]=(e.byChannel[n.channel]??0)+1;return e}getRecentErrors(t=10){return this.getAllEntries().filter(n=>n.level==="error"||n.level==="fatal").slice(-t).reverse()}clear(){this.ringBuffer=[],this.currentIndex=0}tail(t,e){let n=e?s=>{this.matchesFilter(s,e)&&t(s)}:t;return this.tailSubscribers.push(n),()=>{let s=this.tailSubscribers.indexOf(n);s>-1&&this.tailSubscribers.splice(s,1)}}getAllEntries(){return this.ringBuffer.length<this.maxSize?[...this.ringBuffer]:[...this.ringBuffer.slice(this.currentIndex),...this.ringBuffer.slice(0,this.currentIndex)]}matchesFilter(t,e){if(e.level){let n={debug:0,info:1,warn:2,error:3,fatal:4},s=n[e.level];if(n[t.level]<s)return!1}if(e.channel&&t.channel!==e.channel)return!1;if(e.since){let n=e.since.getTime();if(new Date(t.timestamp).getTime()<n)return!1}if(e.until){let n=e.until.getTime();if(new Date(t.timestamp).getTime()>n)return!1}if(e.search){let n=e.search.toLowerCase();if(!(t.message.toLowerCase().includes(n)||JSON.stringify(t.context).toLowerCase().includes(n)))return!1}return!0}},h=o("svelar.logViewer",()=>new l);export{h as LogViewer};
|