@beeblock/svelar 0.5.1 → 0.6.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.
@@ -12,6 +12,8 @@ export declare class NewCommandTemplates {
12
12
  static appHtml(): string;
13
13
  static faviconSvg(): string;
14
14
  static appCss(): string;
15
+ static componentsJson(): string;
16
+ static utilsCn(): string;
15
17
  static appTs(): string;
16
18
  static hooksServerTs(): string;
17
19
  static envExample(): string;
@@ -136,16 +138,6 @@ export declare class NewCommandTemplates {
136
138
  static welcomeNotification(): string;
137
139
  static eventServiceProvider(): string;
138
140
  static homePage(name: string): string;
139
- static addStripeToUsers(): string;
140
- static createSubscriptionPlansTable(): string;
141
- static createSubscriptionsTable(): string;
142
- static createInvoicesTable(): string;
143
- static billingPageServer(): string;
144
- static billingPageSvelte(): string;
145
- static stripeWebhookRoute(): string;
146
- static apiAdminBillingSubscriptions(): string;
147
- static apiAdminBillingRefund(): string;
148
- static apiAdminBillingCancel(): string;
149
141
  static vitestConfig(): string;
150
142
  static playwrightConfig(): string;
151
143
  static exampleUnitTest(): string;
@@ -16,6 +16,9 @@ export declare class UpdateCommand extends Command {
16
16
  default: string;
17
17
  })[];
18
18
  handle(_args: string[], flags: Record<string, any>): Promise<void>;
19
+ private handleNewFiles;
20
+ private handleChangedFiles;
21
+ private backupAndWrite;
19
22
  private normalize;
20
23
  private writeFile;
21
24
  private showDiff;
package/dist/cli/index.js CHANGED
@@ -157,7 +157,7 @@ id: ${Date.now()}
157
157
 
158
158
  `,n=new TextEncoder().encode(r);for(let o of this.subscribers)if(o.userId!==s)try{o.controller.enqueue(n)}catch{}}},dt=class{config;constructor(e){this.config=e}async send(e,t,s){let r=Array.isArray(e)?e:[e],n=JSON.stringify({name:t,channels:r,data:JSON.stringify(s)}),o=Math.floor(Date.now()/1e3).toString(),i=await this.md5(n),a=["POST",`/apps/${this.config.appId}/events`,[`auth_key=${this.config.key}`,`auth_timestamp=${o}`,"auth_version=1.0",`body_md5=${i}`].join("&")].join(`
159
159
  `),l=await this.hmacSha256(this.config.secret,a),u=this.config.useTLS!==!1?"https":"http",d=this.config.host??`api-${this.config.cluster??"mt1"}.pusher.com`,h=this.config.port??(this.config.useTLS!==!1?443:80),m=`${u}://${d}:${h}/apps/${this.config.appId}/events?auth_key=${this.config.key}&auth_timestamp=${o}&auth_version=1.0&body_md5=${i}&auth_signature=${l}`,f=await fetch(m,{method:"POST",headers:{"Content-Type":"application/json"},body:n});if(!f.ok){let v=await f.text();throw new Error(`Pusher API error (${f.status}): ${v}`)}}async authenticate(e,t,s){let r=`${e}:${t}`,n;s&&(n=JSON.stringify(s),r+=`:${n}`);let o=await this.hmacSha256(this.config.secret,r),i=`${this.config.key}:${o}`;return n?{auth:i,channel_data:n}:{auth:i}}get key(){return this.config.key}clientConfig(){let e={key:this.config.key,cluster:this.config.cluster??"mt1"};return this.config.host&&(e.wsHost=this.config.host,e.wsPort=this.config.port??6001,e.wssPort=this.config.port??6001,e.forceTLS=this.config.useTLS??!1,e.enabledTransports=["ws","wss"],e.disableStats=!0),e}async md5(e){let{createHash:t}=await import("crypto");return t("md5").update(e).digest("hex")}async hmacSha256(e,t){let{createHmac:s}=await import("crypto");return s("sha256",e).update(t).digest("hex")}},ar=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)}},cr=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 dt(t))}channel(e,t){if(t){this.channelAuth.set(e,t);return}return this.sseChannels.has(e)||this.sseChannels.set(e,new or(e)),this.sseChannels.get(e)}async authorize(e,t){if(ir(e)==="public")return!0;for(let[r,n]of this.channelAuth){let o=this.matchPattern(r,e);if(o!==null)return await n(t,o)}return!1}async authenticatePusher(e,t,s){if(!this.pusherDriver)throw new Error("Pusher driver is not configured. Call Broadcast.configure() first.");let r=ir(e);if(r==="public")return!1;let n=await this.authorize(e,s);if(n===!1)return!1;if(r==="presence"){let o=typeof n=="object"?{user_id:n.id??s.id,user_info:n}:{user_id:s.id,user_info:{id:s.id}};return this.pusherDriver.authenticate(t,e,o)}return this.pusherDriver.authenticate(t,e)}event(e,t){return new ar(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 dt(n)),await this.pusherDriver.send(e,t,s);break;case"log":console.log(`[Broadcast] ${e} \u2192 ${t}:`,JSON.stringify(s));break;default:for(let[,o]of this.sseChannels)o.name===e&&o.send(t,s,r);break}}subscribe(e,t,s){return this.channel(e).stream(t,s)}members(e){let t=this.sseChannels.get(e);return t?t.getMembers():[]}pusher(){if(!this.pusherDriver)throw new Error("Pusher driver is not configured.");return this.pusherDriver}activeChannels(){return[...new Set([...this.sseChannels.values()].map(e=>e.name))]}totalSubscribers(){let e=0;for(let t of this.sseChannels.values())e+=t.subscriberCount();return e}prune(){for(let[e,t]of this.sseChannels)t.subscriberCount()===0&&this.sseChannels.delete(e)}matchPattern(e,t){let s=[],r=e.replace(/[.*+?^${}()|[\]\\]/g,a=>a==="{"||a==="}"?a:`\\${a}`).replace(/\\\{(\w+)\\\}/g,(a,l)=>(s.push(l),"([^.]+)")).replace(/\{(\w+)\}/g,(a,l)=>(s.push(l),"([^.]+)")),n=new RegExp(`^${r}$`),o=t.match(n);if(!o)return null;let i={};for(let a=0;a<s.length;a++)i[s[a]]=o[a+1];return i}},Cn=b("svelar.broadcast",()=>new cr)});function ht(c,e,t){Rn&&Rn(c,e,{description:t})}async function $n(c,e={}){let{csrfCookieName:t="XSRF-TOKEN",csrfHeaderName:s="X-CSRF-Token",showToast:r=!0,errorMessages:n={},...o}=e,i=(o.method||"GET").toUpperCase(),a=new Headers(o.headers);if(["POST","PUT","PATCH","DELETE"].includes(i)){let l=ur(t);l&&a.set(s,l)}o.body&&typeof o.body=="string"&&!a.has("Content-Type")&&a.set("Content-Type","application/json"),a.has("Accept")||a.set("Accept","application/json");try{let l=await fetch(c,{...o,headers:a});return!l.ok&&r&&await oa(l,{...ia,...n}),l}catch(l){throw r&&ht("error","Network Error","Unable to connect. Check your internet connection."),l}}async function oa(c,e){let t="";try{if((c.headers.get("content-type")??"").includes("application/json")){let o=await c.clone().json();if(t=o.message??"",c.status===422&&o.errors){let i=Object.entries(o.errors).map(([a,l])=>`${a}: ${l.join(", ")}`).slice(0,3).join(`
160
- `);ht("warning",e[422]??"Validation Error",i);return}}}catch{}let s=t||e[c.status]||`Error ${c.status}`,r=c.status>=500?"error":c.status===429?"warning":"error";if(c.status===401){ht("warning",s,"Please sign in to continue.");return}ht(r,s)}function ur(c="XSRF-TOKEN"){if(typeof document>"u")return null;let e=c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),t=document.cookie.match(new RegExp(`(?:^|;\\s*)${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}function Dn(c,e){if(!e)return c;let t=new URL(c,"http://localhost");for(let[s,r]of Object.entries(e))r!=null&&t.searchParams.set(s,String(r));return t.pathname+t.search}var ia,Rn,lr,pe,nd,kn=y(()=>{"use strict";ia={400:"Invalid request. Please check your input.",401:"Your session has expired. Please sign in again.",403:"You don't have permission to do this.",404:"The requested resource was not found.",405:"This action is not allowed.",409:"A conflict occurred. Please refresh and try again.",419:"Page expired. Please refresh and try again.",422:"The submitted data is invalid.",429:"Too many requests. Please wait a moment.",500:"Something went wrong on our end.",502:"Service temporarily unavailable. Try again shortly.",503:"Service is under maintenance. Try again shortly.",504:"Request timed out. Please try again."},Rn=null;lr=class c{_baseUrl="";_headers={};_timeout=3e4;_retries=0;_retryDelay=1e3;_query={};constructor(e){e?.baseUrl&&(this._baseUrl=e.baseUrl),e?.headers&&(this._headers={...e.headers}),e?.timeout&&(this._timeout=e.timeout),e?.retries&&(this._retries=e.retries),e?.retryDelay&&(this._retryDelay=e.retryDelay)}clone(){let e=new c;return e._baseUrl=this._baseUrl,e._headers={...this._headers},e._timeout=this._timeout,e._retries=this._retries,e._retryDelay=this._retryDelay,e._query={...this._query},e}baseUrl(e){let t=this.clone();return t._baseUrl=e,t}withHeaders(e){let t=this.clone();return t._headers={...t._headers,...e},t}withToken(e,t="Bearer"){return this.withHeaders({Authorization:`${t} ${e}`})}withBasicAuth(e,t){let s=Buffer.from(`${e}:${t}`).toString("base64");return this.withHeaders({Authorization:`Basic ${s}`})}accept(e){return this.withHeaders({Accept:e})}contentType(e){return this.withHeaders({"Content-Type":e})}timeout(e){let t=this.clone();return t._timeout=e,t}retry(e,t=1e3){let s=this.clone();return s._retries=e,s._retryDelay=t,s}query(e){let t=this.clone();for(let[s,r]of Object.entries(e))r!=null&&(t._query[s]=String(r));return t}async get(e){return this.request("GET",e)}async post(e,t){return this.request("POST",e,t)}async put(e,t){return this.request("PUT",e,t)}async patch(e,t){return this.request("PATCH",e,t)}async delete(e,t){return this.request("DELETE",e,t)}async request(e,t,s){let r=this.buildFullUrl(t),n={...this._headers},o;s!==void 0&&(n["Content-Type"]||(n["Content-Type"]="application/json"),o=typeof s=="string"?s:JSON.stringify(s)),n.Accept||(n.Accept="application/json");let i=null,a=1+this._retries;for(let l=0;l<a;l++){l>0&&await new Promise(u=>setTimeout(u,this._retryDelay*l));try{let u=new AbortController,d=setTimeout(()=>u.abort(),this._timeout),h=await fetch(r,{method:e,headers:n,body:o,signal:u.signal});if(clearTimeout(d),!h.ok&&h.status<500&&l<a-1,!h.ok&&h.status>=500&&l<a-1){i=new pe(`HTTP ${h.status}: ${h.statusText}`,h.status,await h.text());continue}let m=h.headers.get("content-type")??"",f;if(m.includes("application/json")?f=await h.json():f=await h.text(),!h.ok)throw new pe(`HTTP ${h.status}: ${typeof f=="string"?f:JSON.stringify(f)}`,h.status,f);return{data:f,status:h.status,headers:h.headers,ok:!0}}catch(u){if(u instanceof pe)throw u;if(i=u,u.name==="AbortError"&&(i=new pe("Request timed out",0,null)),l>=a-1)break}}throw i??new Error("HTTP request failed")}buildFullUrl(e){let t=this._baseUrl?`${this._baseUrl.replace(/\/+$/,"")}/${e.replace(/^\/+/,"")}`:e,s=Object.entries(this._query);if(s.length>0){let r=new URL(t);for(let[n,o]of s)r.searchParams.set(n,o);t=r.toString()}return t}},pe=class extends Error{constructor(t,s,r){super(t);this.status=s;this.body=r;this.name="HttpRequestError"}},nd=new lr});function An(c){let{paraglideMiddleware:e,getTextDirection:t=()=>"ltr",langPlaceholder:s="%lang%",dirPlaceholder:r="%dir%"}=c;return({event:n,resolve:o})=>e(n.request,({request:i,locale:a})=>(n.request=i,o(n,{transformPageChunk:({html:l})=>l.replace(s,a).replace(r,t(a))})))}function Nn(c){return e=>c.deLocalizeUrl(e.url).pathname}var Mn=y(()=>{"use strict"});function On(c,e,t={}){return async s=>{let{superValidate:r,fail:n,message:o}=await import("sveltekit-superforms"),{zod:i}=await import("sveltekit-superforms/adapters"),a=await r(s,i(c));if(!a.valid)return n(400,{form:a});try{let l=await e(a.data,s);if(t.redirectTo){let{redirect:u}=await import("@sveltejs/kit");throw u(303,t.redirectTo)}return l??{form:a}}catch(l){if(l?.status>=300&&l?.status<400)throw l;return o(a,t.errorMessage||l.message||"An error occurred",{status:l.status||400})}}}async function _n(c,e){let{superValidate:t}=await import("sveltekit-superforms"),{zod:s}=await import("sveltekit-superforms/adapters");return t(e??null,s(c))}async function Ln(c,e){let t=await c.request.formData(),s={};for(let[n,o]of t.entries())s[n]=o;let r=e.safeParse(s);if(!r.success){let{FormValidationError:n}=await Promise.resolve().then(()=>(at(),mn));throw new n(r.error.flatten().fieldErrors)}return r.data}var In=y(()=>{"use strict";at()});var jn={};P(jn,{Application:()=>Be,AuthManager:()=>Ze,AuthenticateMiddleware:()=>ue,BelongsTo:()=>Y,BelongsToMany:()=>X,Broadcast:()=>Cn,Cache:()=>Tn,ColumnBuilder:()=>O,Connection:()=>g,Container:()=>U,Controller:()=>ze,CorsMiddleware:()=>We,CsrfMiddleware:()=>te,DatabaseSessionStore:()=>Ve,ErrorHandler:()=>de,Event:()=>Z,EventDispatcher:()=>Ee,FileSessionStore:()=>Qe,ForbiddenError:()=>Pe,FormAuthorizationError:()=>B,FormRequest:()=>he,FormValidationError:()=>F,HasMany:()=>G,HasOne:()=>Q,Hash:()=>Es,HttpError:()=>D,Job:()=>z,Log:()=>st,LoggingMiddleware:()=>Ke,Mailable:()=>ke,Mailer:()=>As,MemorySessionStore:()=>H,Middleware:()=>C,MiddlewareStack:()=>L,Migration:()=>fe,Migrator:()=>ye,Model:()=>He,ModelNotFoundError:()=>it,NotFoundError:()=>Se,Notification:()=>ut,Notifier:()=>En,OriginMiddleware:()=>se,QueryBuilder:()=>k,Queue:()=>ps,RateLimitMiddleware:()=>ee,RedisSessionStore:()=>Ge,RequireAuthMiddleware:()=>et,Schema:()=>_,Seeder:()=>Fe,ServiceProvider:()=>xe,Session:()=>oe,SessionMiddleware:()=>ae,SignatureMiddleware:()=>Je,Storage:()=>yn,TableBuilder:()=>K,ThrottleMiddleware:()=>re,UnauthorizedError:()=>Ce,ValidationError:()=>I,abort:()=>ot,abortIf:()=>nn,abortUnless:()=>on,apiFetch:()=>$n,buildUrl:()=>Dn,config:()=>ln,container:()=>Jr,createFormAction:()=>On,createI18nHandle:()=>An,createReroute:()=>Nn,createSvelarApp:()=>an,createSvelarHooks:()=>Ks,env:()=>cn,getCsrfToken:()=>ur,loadForm:()=>_n,resource:()=>Vr,rules:()=>dn,schema:()=>Mr,sequence:()=>Js,signJwt:()=>Ms,validate:()=>hn,validateForm:()=>Ln,verifyJwt:()=>Os,z:()=>x});var qn=y(()=>{"use strict";Wr();fs();ys();w();Zt();es();Kr();ws();bs();zr();ne();Qr();zs();un();pn();_s();ce();vs();Ws();Ue();at();bn();Hs();xn();ms();Xe();Sn();Pn();kn();Mn();In();zs()});var pr={};P(pr,{PluginRegistry:()=>pt});var hr,pt,mt=y(()=>{"use strict";S();hr=class{plugins=new Map;enabledPlugins=new Set;async discover(){let{join:e}=await import("path"),{existsSync:t,readdirSync:s}=await import("fs"),{readFile:r}=await import("fs/promises"),n=[],o=e(process.cwd(),"node_modules");if(!t(o))return n;let i=async(a,l="")=>{if(t(a))try{let u=s(a,{withFileTypes:!0});for(let d of u){if(!d.isDirectory()||d.name.startsWith("."))continue;if(d.name.startsWith("@")){let v=e(a,d.name);await i(v,d.name+"/");continue}let h=l+d.name,m=d.name.startsWith("svelar-");if(!m)continue;let f=e(a,d.name,"package.json");if(t(f))try{let v=await r(f,"utf-8"),E=JSON.parse(v),gt=E.keywords?.includes("svelar-plugin");if(!m&&!gt)continue;let W={name:E.name||h,version:E.version||"0.0.0",description:E.description||"",packageName:h,installed:!0,enabled:!1,hasConfig:!!E.svelar?.config,hasMigrations:!!E.svelar?.migrations};n.push(W),this.plugins.set(W.name,W)}catch{}}}catch{}};return await i(o),n}enable(e){let t=this.plugins.get(e);if(!t)throw new Error(`Plugin "${e}" not found in registry.`);this.enabledPlugins.add(e),t.enabled=!0}disable(e){this.enabledPlugins.delete(e);let t=this.plugins.get(e);t&&(t.enabled=!1)}isEnabled(e){return this.enabledPlugins.has(e)}list(){return[...this.plugins.values()]}listEnabled(){return[...this.plugins.values()].filter(e=>this.enabledPlugins.has(e.name))}get(e){return this.plugins.get(e)}register(e){this.plugins.set(e.name,e)}},pt=b("svelar.pluginRegistry",()=>new hr)});var Un={};P(Un,{PluginPublisher:()=>fr});var gr,fr,yr=y(()=>{"use strict";S();gr=class{async publish(e,t){let{mkdir:s,copyFile:r}=await import("fs/promises"),{join:n,dirname:o}=await import("path"),{existsSync:i}=await import("fs"),a={configs:[],migrations:[],assets:[]},l=e.publishables?.()||{};for(let[u,d]of Object.entries(l))for(let h of d){if(t?.only&&h.type!==t.only)continue;let m=n(process.cwd(),h.dest),f=o(m);if(!(i(m)&&!t?.force))try{await s(f,{recursive:!0}),await r(h.source,m),h.type==="config"?a.configs.push(m):h.type==="migration"?a.migrations.push(m):h.type==="asset"&&a.assets.push(m)}catch(v){console.warn(`Failed to publish ${h.source} to ${m}:`,v)}}return a}async preview(e){let t={configs:[],migrations:[],assets:[]},s=e.publishables?.()||{};for(let[r,n]of Object.entries(s))for(let o of n){let i=Oe("path").join(process.cwd(),o.dest);o.type==="config"?t.configs.push(i):o.type==="migration"?t.migrations.push(i):o.type==="asset"&&t.assets.push(i)}return t}},fr=b("svelar.pluginPublisher",()=>new gr)});var Hn={};P(Hn,{PluginInstaller:()=>aa});var wr,aa,Fn=y(()=>{"use strict";S();mt();yr();wr=class{async install(e,t){let{spawn:s}=await import("child_process"),{promisify:r}=await import("util"),{join:n}=await import("path"),{readFile:o}=await import("fs/promises"),{existsSync:i}=await import("fs");try{await this.runNpmInstall(e);let a=pt,l=await a.discover(),u;for(let h of l)if(h.packageName===e||h.name===e){u=h;break}if(!u)return{success:!1,pluginName:e,version:"0.0.0",published:null,error:`Plugin not found after installation. Make sure ${e} is a valid Svelar plugin.`};a.enable(u.name);let d=null;if(t?.publish!==!1)try{let h=await this.loadPluginClass(u.packageName);h&&(d=await fr.publish(new h))}catch(h){console.warn("Failed to publish plugin assets:",h)}return{success:!0,pluginName:u.name,version:u.version,published:d}}catch(a){return{success:!1,pluginName:e,version:"0.0.0",published:null,error:a?.message??String(a)}}}async uninstall(e){try{let t=pt,s=t.get(e);return s?(t.disable(e),await this.runNpmUninstall(s.packageName),!0):!1}catch(t){return console.error("Failed to uninstall plugin:",t),!1}}async runNpmInstall(e){return new Promise((t,s)=>{let{spawn:r}=Oe("child_process"),n=r("npm",["install",e],{cwd:process.cwd(),stdio:"inherit"});n.on("close",o=>{o===0?t():s(new Error(`npm install exited with code ${o}`))}),n.on("error",s)})}async runNpmUninstall(e){return new Promise((t,s)=>{let{spawn:r}=Oe("child_process"),n=r("npm",["uninstall",e],{cwd:process.cwd(),stdio:"inherit"});n.on("close",o=>{o===0?t():s(new Error(`npm uninstall exited with code ${o}`))}),n.on("error",s)})}async loadPluginClass(e){try{let t=await import(e);return t.default||Object.values(t)[0]}catch{return null}}},aa=b("svelar.pluginInstaller",()=>new wr)});var vt=class{commands=new Map;version;constructor(e="0.1.0"){this.version=e}register(e){let t=new e;return this.commands.set(t.name,t),this}add(e){return this.commands.set(e.name,e),this}async run(e=process.argv.slice(2)){let[t,...s]=e;if(!t||t==="--help"||t==="-h"){this.showHelp();return}if(t==="--version"||t==="-v"){console.log(`Svelar v${this.version}`);return}let r=this.commands.get(t);if(r||(console.error(`\x1B[31mUnknown command:\x1B[0m ${t}`),console.log("Run \x1B[36msvelar --help\x1B[0m for available commands."),process.exit(1)),s.includes("--help")||s.includes("-h")){this.showCommandHelp(r);return}let{args:n,flags:o}=this.parseArgs(s,r);try{await r.handle(n,o)}catch(i){let a=i instanceof Error?i.message:String(i);console.error(`\x1B[31mError:\x1B[0m ${a}`),i?.stack&&console.error(i.stack),process.exit(1)}}parseArgs(e,t){let s=[],r={};for(let n of t.flags)n.default!==void 0&&(r[n.name]=n.default);for(let n=0;n<e.length;n++){let o=e[n];if(o.startsWith("--")){let i=o.slice(2),a=i.indexOf("=");if(a!==-1){let d=i.slice(0,a);r[d]=i.slice(a+1);continue}let l=i;t.flags.find(d=>d.name===l)?.type==="boolean"?r[l]=!0:n+1<e.length&&!e[n+1].startsWith("-")?r[l]=e[++n]:r[l]=!0}else if(o.startsWith("-")&&o.length===2){let i=o.slice(1),a=t.flags.find(l=>l.alias===i);a&&(a.type==="boolean"?r[a.name]=!0:n+1<e.length&&(r[a.name]=e[++n]))}else s.push(o)}return{args:s,flags:r}}showCommandHelp(e){if(console.log(`
160
+ `);ht("warning",e[422]??"Validation Error",i);return}}}catch{}let s=t||e[c.status]||`Error ${c.status}`,r=c.status>=500?"error":c.status===429?"warning":"error";if(c.status===401){ht("warning",s,"Please sign in to continue.");return}ht(r,s)}function ur(c="XSRF-TOKEN"){if(typeof document>"u")return null;let e=c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),t=document.cookie.match(new RegExp(`(?:^|;\\s*)${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}function Dn(c,e){if(!e)return c;let t=new URL(c,"http://localhost");for(let[s,r]of Object.entries(e))r!=null&&t.searchParams.set(s,String(r));return t.pathname+t.search}var ia,Rn,lr,pe,nd,kn=y(()=>{"use strict";ia={400:"Invalid request. Please check your input.",401:"Your session has expired. Please sign in again.",403:"You don't have permission to do this.",404:"The requested resource was not found.",405:"This action is not allowed.",409:"A conflict occurred. Please refresh and try again.",419:"Page expired. Please refresh and try again.",422:"The submitted data is invalid.",429:"Too many requests. Please wait a moment.",500:"Something went wrong on our end.",502:"Service temporarily unavailable. Try again shortly.",503:"Service is under maintenance. Try again shortly.",504:"Request timed out. Please try again."},Rn=null;lr=class c{_baseUrl="";_headers={};_timeout=3e4;_retries=0;_retryDelay=1e3;_query={};constructor(e){e?.baseUrl&&(this._baseUrl=e.baseUrl),e?.headers&&(this._headers={...e.headers}),e?.timeout&&(this._timeout=e.timeout),e?.retries&&(this._retries=e.retries),e?.retryDelay&&(this._retryDelay=e.retryDelay)}clone(){let e=new c;return e._baseUrl=this._baseUrl,e._headers={...this._headers},e._timeout=this._timeout,e._retries=this._retries,e._retryDelay=this._retryDelay,e._query={...this._query},e}baseUrl(e){let t=this.clone();return t._baseUrl=e,t}withHeaders(e){let t=this.clone();return t._headers={...t._headers,...e},t}withToken(e,t="Bearer"){return this.withHeaders({Authorization:`${t} ${e}`})}withBasicAuth(e,t){let s=Buffer.from(`${e}:${t}`).toString("base64");return this.withHeaders({Authorization:`Basic ${s}`})}accept(e){return this.withHeaders({Accept:e})}contentType(e){return this.withHeaders({"Content-Type":e})}timeout(e){let t=this.clone();return t._timeout=e,t}retry(e,t=1e3){let s=this.clone();return s._retries=e,s._retryDelay=t,s}query(e){let t=this.clone();for(let[s,r]of Object.entries(e))r!=null&&(t._query[s]=String(r));return t}async get(e){return this.request("GET",e)}async post(e,t){return this.request("POST",e,t)}async put(e,t){return this.request("PUT",e,t)}async patch(e,t){return this.request("PATCH",e,t)}async delete(e,t){return this.request("DELETE",e,t)}async request(e,t,s){let r=this.buildFullUrl(t),n={...this._headers},o;s!==void 0&&(n["Content-Type"]||(n["Content-Type"]="application/json"),o=typeof s=="string"?s:JSON.stringify(s)),n.Accept||(n.Accept="application/json");let i=null,a=1+this._retries;for(let l=0;l<a;l++){l>0&&await new Promise(u=>setTimeout(u,this._retryDelay*l));try{let u=new AbortController,d=setTimeout(()=>u.abort(),this._timeout),h=await fetch(r,{method:e,headers:n,body:o,signal:u.signal});if(clearTimeout(d),!h.ok&&h.status<500&&l<a-1,!h.ok&&h.status>=500&&l<a-1){i=new pe(`HTTP ${h.status}: ${h.statusText}`,h.status,await h.text());continue}let m=h.headers.get("content-type")??"",f;if(m.includes("application/json")?f=await h.json():f=await h.text(),!h.ok)throw new pe(`HTTP ${h.status}: ${typeof f=="string"?f:JSON.stringify(f)}`,h.status,f);return{data:f,status:h.status,headers:h.headers,ok:!0}}catch(u){if(u instanceof pe)throw u;if(i=u,u.name==="AbortError"&&(i=new pe("Request timed out",0,null)),l>=a-1)break}}throw i??new Error("HTTP request failed")}buildFullUrl(e){let t=this._baseUrl?`${this._baseUrl.replace(/\/+$/,"")}/${e.replace(/^\/+/,"")}`:e,s=Object.entries(this._query);if(s.length>0){let r=new URL(t);for(let[n,o]of s)r.searchParams.set(n,o);t=r.toString()}return t}},pe=class extends Error{constructor(t,s,r){super(t);this.status=s;this.body=r;this.name="HttpRequestError"}},nd=new lr});function An(c){let{paraglideMiddleware:e,getTextDirection:t=()=>"ltr",langPlaceholder:s="%lang%",dirPlaceholder:r="%dir%"}=c;return({event:n,resolve:o})=>e(n.request,({request:i,locale:a})=>(n.request=i,o(n,{transformPageChunk:({html:l})=>l.replace(s,a).replace(r,t(a))})))}function Nn(c){return e=>c.deLocalizeUrl(e.url).pathname}var Mn=y(()=>{"use strict"});function On(c,e,t={}){return async s=>{let{superValidate:r,fail:n,message:o}=await import("sveltekit-superforms"),{zod:i}=await import("sveltekit-superforms/adapters"),a=await r(s,i(c));if(!a.valid)return n(400,{form:a});try{let l=await e(a.data,s);if(t.redirectTo){let{redirect:u}=await import("@sveltejs/kit");throw u(303,t.redirectTo)}return l??{form:a}}catch(l){if(l?.status>=300&&l?.status<400)throw l;return o(a,t.errorMessage||l.message||"An error occurred",{status:l.status||400})}}}async function _n(c,e){let{superValidate:t}=await import("sveltekit-superforms"),{zod:s}=await import("sveltekit-superforms/adapters");return t(e??null,s(c))}async function Ln(c,e){let t=await c.request.formData(),s={};for(let[n,o]of t.entries())s[n]=o;let r=e.safeParse(s);if(!r.success){let{FormValidationError:n}=await Promise.resolve().then(()=>(at(),mn));throw new n(r.error.flatten().fieldErrors)}return r.data}var In=y(()=>{"use strict";at()});var jn={};P(jn,{Application:()=>Be,AuthManager:()=>Ze,AuthenticateMiddleware:()=>ue,BelongsTo:()=>Y,BelongsToMany:()=>X,Broadcast:()=>Cn,Cache:()=>Tn,ColumnBuilder:()=>O,Connection:()=>g,Container:()=>U,Controller:()=>ze,CorsMiddleware:()=>We,CsrfMiddleware:()=>te,DatabaseSessionStore:()=>Ve,ErrorHandler:()=>de,Event:()=>Z,EventDispatcher:()=>Ee,FileSessionStore:()=>Qe,ForbiddenError:()=>Pe,FormAuthorizationError:()=>B,FormRequest:()=>he,FormValidationError:()=>F,HasMany:()=>G,HasOne:()=>Q,Hash:()=>Es,HttpError:()=>D,Job:()=>z,Log:()=>st,LoggingMiddleware:()=>Ke,Mailable:()=>ke,Mailer:()=>As,MemorySessionStore:()=>H,Middleware:()=>C,MiddlewareStack:()=>L,Migration:()=>fe,Migrator:()=>ye,Model:()=>He,ModelNotFoundError:()=>it,NotFoundError:()=>Se,Notification:()=>ut,Notifier:()=>En,OriginMiddleware:()=>se,QueryBuilder:()=>k,Queue:()=>ps,RateLimitMiddleware:()=>ee,RedisSessionStore:()=>Ge,RequireAuthMiddleware:()=>et,Schema:()=>_,Seeder:()=>Fe,ServiceProvider:()=>xe,Session:()=>oe,SessionMiddleware:()=>ae,SignatureMiddleware:()=>Je,Storage:()=>yn,TableBuilder:()=>K,ThrottleMiddleware:()=>re,UnauthorizedError:()=>Ce,ValidationError:()=>I,abort:()=>ot,abortIf:()=>nn,abortUnless:()=>on,apiFetch:()=>$n,buildUrl:()=>Dn,config:()=>ln,container:()=>Jr,createFormAction:()=>On,createI18nHandle:()=>An,createReroute:()=>Nn,createSvelarApp:()=>an,createSvelarHooks:()=>Ks,env:()=>cn,getCsrfToken:()=>ur,loadForm:()=>_n,resource:()=>Vr,rules:()=>dn,schema:()=>Mr,sequence:()=>Js,signJwt:()=>Ms,validate:()=>hn,validateForm:()=>Ln,verifyJwt:()=>Os,z:()=>x});var qn=y(()=>{"use strict";Wr();fs();ys();w();Zt();es();Kr();ws();bs();zr();ne();Qr();zs();un();pn();_s();ce();vs();Ws();Ue();at();bn();Hs();xn();ms();Xe();Sn();Pn();kn();Mn();In();zs()});var pr={};P(pr,{PluginRegistry:()=>pt});var hr,pt,mt=y(()=>{"use strict";S();hr=class{plugins=new Map;enabledPlugins=new Set;async discover(){let{join:e}=await import("path"),{existsSync:t,readdirSync:s}=await import("fs"),{readFile:r}=await import("fs/promises"),n=[],o=e(process.cwd(),"node_modules");if(!t(o))return n;let i=async(a,l="")=>{if(t(a))try{let u=s(a,{withFileTypes:!0});for(let d of u){if(!d.isDirectory()||d.name.startsWith("."))continue;if(d.name.startsWith("@")){let v=e(a,d.name);await i(v,d.name+"/");continue}let h=l+d.name,m=d.name.startsWith("svelar-");if(!m)continue;let f=e(a,d.name,"package.json");if(t(f))try{let v=await r(f,"utf-8"),E=JSON.parse(v),gt=E.keywords?.includes("svelar-plugin");if(!m&&!gt)continue;let W={name:E.name||h,version:E.version||"0.0.0",description:E.description||"",packageName:h,installed:!0,enabled:!1,hasConfig:!!E.svelar?.config,hasMigrations:!!E.svelar?.migrations};n.push(W),this.plugins.set(W.name,W)}catch{}}}catch{}};return await i(o),n}enable(e){let t=this.plugins.get(e);if(!t)throw new Error(`Plugin "${e}" not found in registry.`);this.enabledPlugins.add(e),t.enabled=!0}disable(e){this.enabledPlugins.delete(e);let t=this.plugins.get(e);t&&(t.enabled=!1)}isEnabled(e){return this.enabledPlugins.has(e)}list(){return[...this.plugins.values()]}listEnabled(){return[...this.plugins.values()].filter(e=>this.enabledPlugins.has(e.name))}get(e){return this.plugins.get(e)}register(e){this.plugins.set(e.name,e)}},pt=b("svelar.pluginRegistry",()=>new hr)});var Un={};P(Un,{PluginPublisher:()=>fr});var gr,fr,yr=y(()=>{"use strict";S();gr=class{async publish(e,t){let{mkdir:s,copyFile:r}=await import("fs/promises"),{join:n,dirname:o}=await import("path"),{existsSync:i}=await import("fs"),a={configs:[],migrations:[],assets:[]},l=e.publishables?.()||{};for(let[u,d]of Object.entries(l))for(let h of d){if(t?.only&&h.type!==t.only)continue;let m=n(process.cwd(),h.dest),f=o(m);if(!(i(m)&&!t?.force))try{await s(f,{recursive:!0}),await r(h.source,m),h.type==="config"?a.configs.push(m):h.type==="migration"?a.migrations.push(m):h.type==="asset"&&a.assets.push(m)}catch(v){console.warn(`Failed to publish ${h.source} to ${m}:`,v)}}return a}async preview(e){let t={configs:[],migrations:[],assets:[]},s=e.publishables?.()||{};for(let[r,n]of Object.entries(s))for(let o of n){let i=Oe("path").join(process.cwd(),o.dest);o.type==="config"?t.configs.push(i):o.type==="migration"?t.migrations.push(i):o.type==="asset"&&t.assets.push(i)}return t}},fr=b("svelar.pluginPublisher",()=>new gr)});var Hn={};P(Hn,{PluginInstaller:()=>aa});var wr,aa,Fn=y(()=>{"use strict";S();mt();yr();wr=class{async install(e,t){let{spawn:s}=await import("child_process"),{promisify:r}=await import("util"),{join:n}=await import("path"),{readFile:o}=await import("fs/promises"),{existsSync:i}=await import("fs");try{await this.runNpmInstall(e);let a=pt,l=await a.discover(),u;for(let h of l)if(h.packageName===e||h.name===e){u=h;break}if(!u)return{success:!1,pluginName:e,version:"0.0.0",published:null,error:`Plugin not found after installation. Make sure ${e} is a valid Svelar plugin.`};a.enable(u.name);let d=null;if(t?.publish!==!1)try{let h=await this.loadPluginClass(u.packageName);h&&(d=await fr.publish(new h))}catch(h){console.warn("Failed to publish plugin assets:",h)}return{success:!0,pluginName:u.name,version:u.version,published:d}}catch(a){return{success:!1,pluginName:e,version:"0.0.0",published:null,error:a?.message??String(a)}}}async uninstall(e){try{let t=pt,s=t.get(e);return s?(t.disable(e),await this.runNpmUninstall(s.packageName),!0):!1}catch(t){return console.error("Failed to uninstall plugin:",t),!1}}async runNpmInstall(e){return new Promise((t,s)=>{let{spawn:r}=Oe("child_process"),n=r("npm",["install",e],{cwd:process.cwd(),stdio:"inherit"});n.on("close",o=>{o===0?t():s(new Error(`npm install exited with code ${o}`))}),n.on("error",s)})}async runNpmUninstall(e){return new Promise((t,s)=>{let{spawn:r}=Oe("child_process"),n=r("npm",["uninstall",e],{cwd:process.cwd(),stdio:"inherit"});n.on("close",o=>{o===0?t():s(new Error(`npm uninstall exited with code ${o}`))}),n.on("error",s)})}async loadPluginClass(e){try{let t=await import(`${e}/plugin`);return t.default||Object.values(t)[0]}catch{try{let t=await import(e);return t.default||Object.values(t)[0]}catch{return null}}}},aa=b("svelar.pluginInstaller",()=>new wr)});var vt=class{commands=new Map;version;constructor(e="0.1.0"){this.version=e}register(e){let t=new e;return this.commands.set(t.name,t),this}add(e){return this.commands.set(e.name,e),this}async run(e=process.argv.slice(2)){let[t,...s]=e;if(!t||t==="--help"||t==="-h"){this.showHelp();return}if(t==="--version"||t==="-v"){console.log(`Svelar v${this.version}`);return}let r=this.commands.get(t);if(r||(console.error(`\x1B[31mUnknown command:\x1B[0m ${t}`),console.log("Run \x1B[36msvelar --help\x1B[0m for available commands."),process.exit(1)),s.includes("--help")||s.includes("-h")){this.showCommandHelp(r);return}let{args:n,flags:o}=this.parseArgs(s,r);try{await r.handle(n,o)}catch(i){let a=i instanceof Error?i.message:String(i);console.error(`\x1B[31mError:\x1B[0m ${a}`),i?.stack&&console.error(i.stack),process.exit(1)}}parseArgs(e,t){let s=[],r={};for(let n of t.flags)n.default!==void 0&&(r[n.name]=n.default);for(let n=0;n<e.length;n++){let o=e[n];if(o.startsWith("--")){let i=o.slice(2),a=i.indexOf("=");if(a!==-1){let d=i.slice(0,a);r[d]=i.slice(a+1);continue}let l=i;t.flags.find(d=>d.name===l)?.type==="boolean"?r[l]=!0:n+1<e.length&&!e[n+1].startsWith("-")?r[l]=e[++n]:r[l]=!0}else if(o.startsWith("-")&&o.length===2){let i=o.slice(1),a=t.flags.find(l=>l.alias===i);a&&(a.type==="boolean"?r[a.name]=!0:n+1<e.length&&(r[a.name]=e[++n]))}else s.push(o)}return{args:s,flags:r}}showCommandHelp(e){if(console.log(`
161
161
  \x1B[33mDescription:\x1B[0m`),console.log(` ${e.description}
162
162
  `),console.log("\x1B[33mUsage:\x1B[0m"),console.log(` svelar ${e.name} [options]
163
163
  `),e.flags.length>0){console.log("\x1B[33mOptions:\x1B[0m");for(let t of e.flags){let s=t.alias?`-${t.alias}, `:" ",r=`--${t.name}`,n=24-s.length-r.length;console.log(` ${s}${r}${" ".repeat(Math.max(1,n))}${t.description}`)}console.log()}}showHelp(){console.log(`
@@ -1 +1 @@
1
- var w=(u=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(u,{get:(s,e)=>(typeof require<"u"?require:s)[e]}):u)(function(u){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+u+'" is not supported')});function m(u,s){let e=Symbol.for(u),n=globalThis;return n[e]||(n[e]=s()),n[e]}var P=class{plugins=new Map;enabledPlugins=new Set;async discover(){let{join:s}=await import("path"),{existsSync:e,readdirSync:n}=await import("fs"),{readFile:c}=await import("fs/promises"),o=[],t=s(process.cwd(),"node_modules");if(!e(t))return o;let g=async(r,d="")=>{if(e(r))try{let p=n(r,{withFileTypes:!0});for(let a of p){if(!a.isDirectory()||a.name.startsWith("."))continue;if(a.name.startsWith("@")){let h=s(r,a.name);await g(h,a.name+"/");continue}let i=d+a.name,l=a.name.startsWith("svelar-");if(!l)continue;let b=s(r,a.name,"package.json");if(e(b))try{let h=await c(b,"utf-8"),f=JSON.parse(h),k=f.keywords?.includes("svelar-plugin");if(!l&&!k)continue;let y={name:f.name||i,version:f.version||"0.0.0",description:f.description||"",packageName:i,installed:!0,enabled:!1,hasConfig:!!f.svelar?.config,hasMigrations:!!f.svelar?.migrations};o.push(y),this.plugins.set(y.name,y)}catch{}}}catch{}};return await g(t),o}enable(s){let e=this.plugins.get(s);if(!e)throw new Error(`Plugin "${s}" not found in registry.`);this.enabledPlugins.add(s),e.enabled=!0}disable(s){this.enabledPlugins.delete(s);let e=this.plugins.get(s);e&&(e.enabled=!1)}isEnabled(s){return this.enabledPlugins.has(s)}list(){return[...this.plugins.values()]}listEnabled(){return[...this.plugins.values()].filter(s=>this.enabledPlugins.has(s.name))}get(s){return this.plugins.get(s)}register(s){this.plugins.set(s.name,s)}},v=m("svelar.pluginRegistry",()=>new P);var M=class{async publish(s,e){let{mkdir:n,copyFile:c}=await import("fs/promises"),{join:o,dirname:t}=await import("path"),{existsSync:g}=await import("fs"),r={configs:[],migrations:[],assets:[]},d=s.publishables?.()||{};for(let[p,a]of Object.entries(d))for(let i of a){if(e?.only&&i.type!==e.only)continue;let l=o(process.cwd(),i.dest),b=t(l);if(!(g(l)&&!e?.force))try{await n(b,{recursive:!0}),await c(i.source,l),i.type==="config"?r.configs.push(l):i.type==="migration"?r.migrations.push(l):i.type==="asset"&&r.assets.push(l)}catch(h){console.warn(`Failed to publish ${i.source} to ${l}:`,h)}}return r}async preview(s){let e={configs:[],migrations:[],assets:[]},n=s.publishables?.()||{};for(let[c,o]of Object.entries(n))for(let t of o){let g=w("path").join(process.cwd(),t.dest);t.type==="config"?e.configs.push(g):t.type==="migration"?e.migrations.push(g):t.type==="asset"&&e.assets.push(g)}return e}},R=m("svelar.pluginPublisher",()=>new M);var x=class{async install(s,e){let{spawn:n}=await import("child_process"),{promisify:c}=await import("util"),{join:o}=await import("path"),{readFile:t}=await import("fs/promises"),{existsSync:g}=await import("fs");try{await this.runNpmInstall(s);let r=v,d=await r.discover(),p;for(let i of d)if(i.packageName===s||i.name===s){p=i;break}if(!p)return{success:!1,pluginName:s,version:"0.0.0",published:null,error:`Plugin not found after installation. Make sure ${s} is a valid Svelar plugin.`};r.enable(p.name);let a=null;if(e?.publish!==!1)try{let i=await this.loadPluginClass(p.packageName);i&&(a=await R.publish(new i))}catch(i){console.warn("Failed to publish plugin assets:",i)}return{success:!0,pluginName:p.name,version:p.version,published:a}}catch(r){return{success:!1,pluginName:s,version:"0.0.0",published:null,error:r?.message??String(r)}}}async uninstall(s){try{let e=v,n=e.get(s);return n?(e.disable(s),await this.runNpmUninstall(n.packageName),!0):!1}catch(e){return console.error("Failed to uninstall plugin:",e),!1}}async runNpmInstall(s){return new Promise((e,n)=>{let{spawn:c}=w("child_process"),o=c("npm",["install",s],{cwd:process.cwd(),stdio:"inherit"});o.on("close",t=>{t===0?e():n(new Error(`npm install exited with code ${t}`))}),o.on("error",n)})}async runNpmUninstall(s){return new Promise((e,n)=>{let{spawn:c}=w("child_process"),o=c("npm",["uninstall",s],{cwd:process.cwd(),stdio:"inherit"});o.on("close",t=>{t===0?e():n(new Error(`npm uninstall exited with code ${t}`))}),o.on("error",n)})}async loadPluginClass(s){try{let e=await import(s);return e.default||Object.values(e)[0]}catch{return null}}},D=m("svelar.pluginInstaller",()=>new x);export{D as PluginInstaller};
1
+ var w=(u=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(u,{get:(s,e)=>(typeof require<"u"?require:s)[e]}):u)(function(u){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+u+'" is not supported')});function d(u,s){let e=Symbol.for(u),n=globalThis;return n[e]||(n[e]=s()),n[e]}var P=class{plugins=new Map;enabledPlugins=new Set;async discover(){let{join:s}=await import("path"),{existsSync:e,readdirSync:n}=await import("fs"),{readFile:c}=await import("fs/promises"),o=[],i=s(process.cwd(),"node_modules");if(!e(i))return o;let g=async(r,m="")=>{if(e(r))try{let p=n(r,{withFileTypes:!0});for(let a of p){if(!a.isDirectory()||a.name.startsWith("."))continue;if(a.name.startsWith("@")){let h=s(r,a.name);await g(h,a.name+"/");continue}let t=m+a.name,l=a.name.startsWith("svelar-");if(!l)continue;let b=s(r,a.name,"package.json");if(e(b))try{let h=await c(b,"utf-8"),f=JSON.parse(h),k=f.keywords?.includes("svelar-plugin");if(!l&&!k)continue;let y={name:f.name||t,version:f.version||"0.0.0",description:f.description||"",packageName:t,installed:!0,enabled:!1,hasConfig:!!f.svelar?.config,hasMigrations:!!f.svelar?.migrations};o.push(y),this.plugins.set(y.name,y)}catch{}}}catch{}};return await g(i),o}enable(s){let e=this.plugins.get(s);if(!e)throw new Error(`Plugin "${s}" not found in registry.`);this.enabledPlugins.add(s),e.enabled=!0}disable(s){this.enabledPlugins.delete(s);let e=this.plugins.get(s);e&&(e.enabled=!1)}isEnabled(s){return this.enabledPlugins.has(s)}list(){return[...this.plugins.values()]}listEnabled(){return[...this.plugins.values()].filter(s=>this.enabledPlugins.has(s.name))}get(s){return this.plugins.get(s)}register(s){this.plugins.set(s.name,s)}},v=d("svelar.pluginRegistry",()=>new P);var M=class{async publish(s,e){let{mkdir:n,copyFile:c}=await import("fs/promises"),{join:o,dirname:i}=await import("path"),{existsSync:g}=await import("fs"),r={configs:[],migrations:[],assets:[]},m=s.publishables?.()||{};for(let[p,a]of Object.entries(m))for(let t of a){if(e?.only&&t.type!==e.only)continue;let l=o(process.cwd(),t.dest),b=i(l);if(!(g(l)&&!e?.force))try{await n(b,{recursive:!0}),await c(t.source,l),t.type==="config"?r.configs.push(l):t.type==="migration"?r.migrations.push(l):t.type==="asset"&&r.assets.push(l)}catch(h){console.warn(`Failed to publish ${t.source} to ${l}:`,h)}}return r}async preview(s){let e={configs:[],migrations:[],assets:[]},n=s.publishables?.()||{};for(let[c,o]of Object.entries(n))for(let i of o){let g=w("path").join(process.cwd(),i.dest);i.type==="config"?e.configs.push(g):i.type==="migration"?e.migrations.push(g):i.type==="asset"&&e.assets.push(g)}return e}},R=d("svelar.pluginPublisher",()=>new M);var x=class{async install(s,e){let{spawn:n}=await import("child_process"),{promisify:c}=await import("util"),{join:o}=await import("path"),{readFile:i}=await import("fs/promises"),{existsSync:g}=await import("fs");try{await this.runNpmInstall(s);let r=v,m=await r.discover(),p;for(let t of m)if(t.packageName===s||t.name===s){p=t;break}if(!p)return{success:!1,pluginName:s,version:"0.0.0",published:null,error:`Plugin not found after installation. Make sure ${s} is a valid Svelar plugin.`};r.enable(p.name);let a=null;if(e?.publish!==!1)try{let t=await this.loadPluginClass(p.packageName);t&&(a=await R.publish(new t))}catch(t){console.warn("Failed to publish plugin assets:",t)}return{success:!0,pluginName:p.name,version:p.version,published:a}}catch(r){return{success:!1,pluginName:s,version:"0.0.0",published:null,error:r?.message??String(r)}}}async uninstall(s){try{let e=v,n=e.get(s);return n?(e.disable(s),await this.runNpmUninstall(n.packageName),!0):!1}catch(e){return console.error("Failed to uninstall plugin:",e),!1}}async runNpmInstall(s){return new Promise((e,n)=>{let{spawn:c}=w("child_process"),o=c("npm",["install",s],{cwd:process.cwd(),stdio:"inherit"});o.on("close",i=>{i===0?e():n(new Error(`npm install exited with code ${i}`))}),o.on("error",n)})}async runNpmUninstall(s){return new Promise((e,n)=>{let{spawn:c}=w("child_process"),o=c("npm",["uninstall",s],{cwd:process.cwd(),stdio:"inherit"});o.on("close",i=>{i===0?e():n(new Error(`npm uninstall exited with code ${i}`))}),o.on("error",n)})}async loadPluginClass(s){try{let e=await import(`${s}/plugin`);return e.default||Object.values(e)[0]}catch{try{let e=await import(s);return e.default||Object.values(e)[0]}catch{return null}}}},C=d("svelar.pluginInstaller",()=>new x);export{C as PluginInstaller};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beeblock/svelar",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "Laravel-inspired framework on top of SvelteKit 2",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -242,10 +242,6 @@
242
242
  "types": "./dist/excel/index.d.ts",
243
243
  "import": "./dist/excel/index.js"
244
244
  },
245
- "./stripe": {
246
- "types": "./dist/stripe/index.d.ts",
247
- "import": "./dist/stripe/index.js"
248
- },
249
245
  "./testing": {
250
246
  "types": "./dist/testing/index.d.ts",
251
247
  "import": "./dist/testing/index.js"
@@ -273,7 +269,7 @@
273
269
  "@vitest/coverage-v8": "^2.1.9",
274
270
  "better-sqlite3": "^11.0.0",
275
271
  "exceljs": "^4.4.0",
276
- "stripe": "^21.0.1",
272
+
277
273
  "sveltekit-superforms": "^2.30.1",
278
274
  "tsup": "^8.3.0",
279
275
  "typescript": "^5.7.0",
@@ -292,7 +288,7 @@
292
288
  "pdfkit": ">=0.18.0",
293
289
  "postgres": "*",
294
290
  "pusher-js": ">=8.0.0",
295
- "stripe": ">=14.0.0",
291
+
296
292
  "sveltekit-superforms": ">=2.0.0",
297
293
  "vitest": ">=1.0.0"
298
294
  },
@@ -333,9 +329,7 @@
333
329
  "meilisearch": {
334
330
  "optional": true
335
331
  },
336
- "stripe": {
337
- "optional": true
338
- },
332
+
339
333
  "vitest": {
340
334
  "optional": true
341
335
  }
@@ -353,9 +347,7 @@
353
347
  "cache",
354
348
  "queue",
355
349
  "mail",
356
- "stripe",
357
- "billing",
358
- "subscriptions"
350
+ "billing"
359
351
  ],
360
352
  "license": "MIT",
361
353
  "author": "Raoni <alephtus@gmail.com>",
@@ -1,44 +0,0 @@
1
- export type InvoiceStatus = 'draft' | 'open' | 'paid' | 'void' | 'uncollectible';
2
- export interface InvoiceAttributes {
3
- id: number;
4
- userId: number;
5
- subscriptionId: number | null;
6
- stripeInvoiceId: string;
7
- amountDue: number;
8
- amountPaid: number;
9
- currency: string;
10
- status: InvoiceStatus;
11
- paidAt: Date | null;
12
- dueDate: Date | null;
13
- invoicePdf: string | null;
14
- createdAt: Date;
15
- updatedAt?: Date;
16
- }
17
- export declare class Invoice implements InvoiceAttributes {
18
- id: number;
19
- userId: number;
20
- subscriptionId: number | null;
21
- stripeInvoiceId: string;
22
- amountDue: number;
23
- amountPaid: number;
24
- currency: string;
25
- status: InvoiceStatus;
26
- paidAt: Date | null;
27
- dueDate: Date | null;
28
- invoicePdf: string | null;
29
- createdAt: Date;
30
- updatedAt?: Date;
31
- constructor(attributes: InvoiceAttributes);
32
- isPaid(): boolean;
33
- isOpen(): boolean;
34
- isDraft(): boolean;
35
- isVoid(): boolean;
36
- isUncollectible(): boolean;
37
- isOverdue(): boolean;
38
- outstandingAmount(): number;
39
- formattedAmountDue(): string;
40
- formattedAmountPaid(): string;
41
- formattedOutstanding(): string;
42
- daysUntilDue(): number | null;
43
- private formatCurrency;
44
- }
@@ -1,52 +0,0 @@
1
- import type Stripe from 'stripe';
2
- export interface StripeConfig {
3
- secretKey: string;
4
- publishableKey: string;
5
- webhookSecret: string;
6
- currency?: string;
7
- trialDays?: number;
8
- portalReturnUrl?: string;
9
- checkoutSuccessUrl?: string;
10
- checkoutCancelUrl?: string;
11
- }
12
- export declare class StripeService {
13
- private stripe;
14
- private config;
15
- configure(config: StripeConfig): void;
16
- getConfig(): StripeConfig;
17
- getClient(): Promise<Stripe>;
18
- createCustomer(user: {
19
- id: number | string;
20
- name?: string;
21
- email?: string;
22
- }): Promise<Stripe.Customer>;
23
- updateCustomer(customerId: string, data: Stripe.CustomerUpdateParams): Promise<Stripe.Customer>;
24
- deleteCustomer(customerId: string): Promise<void>;
25
- getCustomer(customerId: string): Promise<Stripe.Customer>;
26
- createSubscription(customerId: string, priceId: string, opts?: {
27
- trialDays?: number;
28
- metadata?: Record<string, string>;
29
- collectionMethod?: 'send_invoice' | 'charge_automatically';
30
- daysUntilDue?: number;
31
- }): Promise<Stripe.Subscription>;
32
- getSubscription(subscriptionId: string): Promise<Stripe.Subscription>;
33
- cancelSubscription(subscriptionId: string, immediately?: boolean): Promise<Stripe.Subscription>;
34
- resumeSubscription(subscriptionId: string): Promise<Stripe.Subscription>;
35
- updateSubscription(subscriptionId: string, newPriceId: string, opts?: {
36
- proration?: 'create_prorations' | 'none';
37
- metadata?: Record<string, string>;
38
- }): Promise<Stripe.Subscription>;
39
- getInvoices(customerId: string, limit?: number): Promise<Stripe.Invoice[]>;
40
- getInvoice(invoiceId: string): Promise<Stripe.Invoice>;
41
- createCheckoutSession(customerId: string, priceId: string, successUrl: string, cancelUrl: string, opts?: {
42
- trialDays?: number;
43
- metadata?: Record<string, string>;
44
- }): Promise<Stripe.Checkout.Session>;
45
- createPortalSession(customerId: string, returnUrl: string): Promise<Stripe.BillingPortal.Session>;
46
- constructWebhookEvent(body: string | Buffer, signature: string): Promise<Stripe.Event>;
47
- listPrices(productId?: string, limit?: number): Promise<Stripe.Price[]>;
48
- listProducts(limit?: number): Promise<Stripe.Product[]>;
49
- refundInvoice(invoiceId: string): Promise<Stripe.Refund>;
50
- getRefund(refundId: string): Promise<Stripe.Refund>;
51
- listRefunds(chargeId: string): Promise<Stripe.Refund[]>;
52
- }
@@ -1,14 +0,0 @@
1
- import type Stripe from 'stripe';
2
- export type WebhookEventType = 'customer.subscription.created' | 'customer.subscription.updated' | 'customer.subscription.deleted' | 'invoice.payment_succeeded' | 'invoice.payment_failed' | 'customer.created' | 'customer.updated' | 'customer.deleted' | 'checkout.session.completed' | 'invoice.created' | 'invoice.finalized' | 'charge.refunded' | string;
3
- export type WebhookHandler = (event: Stripe.Event) => Promise<void>;
4
- export declare class StripeWebhookHandler {
5
- private handlers;
6
- on(eventType: WebhookEventType, handler: WebhookHandler): this;
7
- once(eventType: WebhookEventType, handler: WebhookHandler): this;
8
- off(eventType: WebhookEventType, handler: WebhookHandler): void;
9
- removeAllListeners(eventType?: WebhookEventType): void;
10
- handle(event: Stripe.Event): Promise<void>;
11
- getHandlers(eventType: WebhookEventType): WebhookHandler[];
12
- getEventTypes(): WebhookEventType[];
13
- hasHandlers(eventType: WebhookEventType): boolean;
14
- }
@@ -1,40 +0,0 @@
1
- export type SubscriptionStatus = 'active' | 'past_due' | 'canceled' | 'trialing' | 'incomplete' | 'paused';
2
- export interface SubscriptionAttributes {
3
- id: number;
4
- userId: number;
5
- stripeSubscriptionId: string;
6
- stripeCustomerId: string;
7
- planId: number;
8
- status: SubscriptionStatus;
9
- currentPeriodStart: Date;
10
- currentPeriodEnd: Date;
11
- cancelAtPeriodEnd: boolean;
12
- trialEndsAt: Date | null;
13
- canceledAt: Date | null;
14
- createdAt: Date;
15
- updatedAt: Date;
16
- }
17
- export declare class Subscription implements SubscriptionAttributes {
18
- id: number;
19
- userId: number;
20
- stripeSubscriptionId: string;
21
- stripeCustomerId: string;
22
- planId: number;
23
- status: SubscriptionStatus;
24
- currentPeriodStart: Date;
25
- currentPeriodEnd: Date;
26
- cancelAtPeriodEnd: boolean;
27
- trialEndsAt: Date | null;
28
- canceledAt: Date | null;
29
- createdAt: Date;
30
- updatedAt: Date;
31
- constructor(attributes: SubscriptionAttributes);
32
- isActive(): boolean;
33
- isPastDue(): boolean;
34
- isCanceled(): boolean;
35
- isOnTrial(): boolean;
36
- isOnGracePeriod(): boolean;
37
- isIncomplete(): boolean;
38
- isPaused(): boolean;
39
- daysUntilEnd(): number;
40
- }
@@ -1,39 +0,0 @@
1
- import type { StripeService } from './StripeService.js';
2
- import type { Subscription } from './Subscription.js';
3
- import type { SubscriptionPlan } from './SubscriptionPlan.js';
4
- export interface SubscriptionManagerDependencies {
5
- stripeService: StripeService;
6
- subscriptionRepository?: {
7
- findByUserId(userId: number): Promise<Subscription | null>;
8
- findByStripeSubscriptionId(id: string): Promise<Subscription | null>;
9
- create(data: any): Promise<Subscription>;
10
- update(id: number, data: any): Promise<Subscription>;
11
- delete(id: number): Promise<void>;
12
- };
13
- planRepository?: {
14
- findById(id: number): Promise<SubscriptionPlan | null>;
15
- findByStripePriceId(id: string): Promise<SubscriptionPlan | null>;
16
- all(): Promise<SubscriptionPlan[]>;
17
- };
18
- userRepository?: {
19
- findById(id: number): Promise<any>;
20
- update(id: number, data: any): Promise<any>;
21
- };
22
- }
23
- export declare class SubscriptionManager {
24
- private stripeService;
25
- private deps;
26
- constructor(deps: SubscriptionManagerDependencies);
27
- subscribe(userId: number, planId: number, opts?: {
28
- trialDays?: number;
29
- metadata?: Record<string, string>;
30
- }): Promise<Subscription>;
31
- upgrade(userId: number, newPlanId: number): Promise<Subscription>;
32
- downgrade(userId: number, newPlanId: number): Promise<Subscription>;
33
- cancel(userId: number, immediately?: boolean): Promise<void>;
34
- resume(userId: number): Promise<Subscription>;
35
- isSubscribed(userId: number, planId?: number): Promise<boolean>;
36
- onTrial(userId: number): Promise<boolean>;
37
- hasFeature(userId: number, feature: string): Promise<boolean>;
38
- syncFromStripe(userId: number): Promise<Subscription>;
39
- }
@@ -1,41 +0,0 @@
1
- export type PlanInterval = 'month' | 'year';
2
- export interface SubscriptionPlanAttributes {
3
- id: number;
4
- name: string;
5
- stripePriceId: string;
6
- stripeProductId: string;
7
- price: number;
8
- currency: string;
9
- interval: PlanInterval;
10
- intervalCount: number;
11
- trialDays: number;
12
- features: string[];
13
- sortOrder: number;
14
- active: boolean;
15
- createdAt: Date;
16
- updatedAt: Date;
17
- }
18
- export declare class SubscriptionPlan implements SubscriptionPlanAttributes {
19
- id: number;
20
- name: string;
21
- stripePriceId: string;
22
- stripeProductId: string;
23
- price: number;
24
- currency: string;
25
- interval: PlanInterval;
26
- intervalCount: number;
27
- trialDays: number;
28
- features: string[];
29
- sortOrder: number;
30
- active: boolean;
31
- createdAt: Date;
32
- updatedAt: Date;
33
- constructor(attributes: SubscriptionPlanAttributes);
34
- isActive(): boolean;
35
- monthlyPrice(): number;
36
- yearlyPrice(): number;
37
- hasFeature(feature: string): boolean;
38
- formattedPrice(): string;
39
- intervalLabel(): string;
40
- trialLabel(): string;
41
- }
@@ -1,11 +0,0 @@
1
- import { StripeService } from './StripeService.js';
2
- export declare class SyncStripeCustomerJob {
3
- userId: number;
4
- email: string;
5
- userName: string;
6
- readonly name = "sync-stripe-customer";
7
- constructor(userId: number, email: string, userName: string);
8
- handle(stripeService: StripeService): Promise<void>;
9
- serialize(): string;
10
- static restore(data: any): SyncStripeCustomerJob;
11
- }
@@ -1,22 +0,0 @@
1
- import { StripeService, type StripeConfig } from './StripeService.js';
2
- import { StripeWebhookHandler } from './StripeWebhookHandler.js';
3
- import { SubscriptionManager, type SubscriptionManagerDependencies } from './SubscriptionManager.js';
4
- declare class StripeManager {
5
- private stripeService;
6
- private webhookHandler;
7
- private subscriptionManager;
8
- configure(config: StripeConfig): void;
9
- service(): StripeService;
10
- webhooks(): StripeWebhookHandler;
11
- subscriptions(deps?: SubscriptionManagerDependencies): SubscriptionManager;
12
- initSubscriptions(deps: Omit<SubscriptionManagerDependencies, 'stripeService'>): SubscriptionManager;
13
- }
14
- export declare const Stripe: StripeManager;
15
- export { StripeManager };
16
- export { StripeService, type StripeConfig } from './StripeService.js';
17
- export { StripeWebhookHandler, type WebhookEventType, type WebhookHandler } from './StripeWebhookHandler.js';
18
- export { SubscriptionManager, type SubscriptionManagerDependencies } from './SubscriptionManager.js';
19
- export { Subscription, type SubscriptionAttributes, type SubscriptionStatus } from './Subscription.js';
20
- export { SubscriptionPlan, type SubscriptionPlanAttributes, type PlanInterval } from './SubscriptionPlan.js';
21
- export { Invoice, type InvoiceAttributes, type InvoiceStatus } from './Invoice.js';
22
- export { SyncStripeCustomerJob } from './SyncStripeCustomerJob.js';
@@ -1 +0,0 @@
1
- import{randomBytes as D}from"crypto";function h(n,t){let e=Symbol.for(n),i=globalThis;return i[e]||(i[e]=t()),i[e]}var p=class{stripe=null;config=null;configure(t){this.config=t,this.stripe=null}getConfig(){if(!this.config)throw new Error("StripeService not configured. Call Stripe.configure() in app.ts first.");return this.config}async getClient(){if(!this.stripe){if(!this.config)throw new Error("StripeService not configured. Call Stripe.configure() in app.ts first.");let{default:t}=await import("stripe");this.stripe=new t(this.config.secretKey,{apiVersion:"2024-04-10"})}return this.stripe}async createCustomer(t){return(await this.getClient()).customers.create({email:t.email,name:t.name||void 0,metadata:{userId:String(t.id)}})}async updateCustomer(t,e){return(await this.getClient()).customers.update(t,e)}async deleteCustomer(t){await(await this.getClient()).customers.del(t)}async getCustomer(t){return await(await this.getClient()).customers.retrieve(t)}async createSubscription(t,e,i){let r=await this.getClient(),s={customer:t,items:[{price:e}],metadata:i?.metadata,collection_method:i?.collectionMethod||"charge_automatically"};return i?.trialDays&&(s.trial_period_days=i.trialDays),i?.daysUntilDue&&(s.days_until_due=i.daysUntilDue),r.subscriptions.create(s)}async getSubscription(t){return(await this.getClient()).subscriptions.retrieve(t)}async cancelSubscription(t,e=!1){let i=await this.getClient();return e?i.subscriptions.cancel(t):i.subscriptions.update(t,{cancel_at_period_end:!0})}async resumeSubscription(t){return(await this.getClient()).subscriptions.update(t,{cancel_at_period_end:!1})}async updateSubscription(t,e,i){let r=await this.getClient(),s=await r.subscriptions.retrieve(t);if(!s.items.data[0])throw new Error("Subscription has no items");return r.subscriptions.update(t,{items:[{id:s.items.data[0].id,price:e}],proration_behavior:i?.proration||"create_prorations",metadata:i?.metadata})}async getInvoices(t,e=10){return(await(await this.getClient()).invoices.list({customer:t,limit:e})).data}async getInvoice(t){return(await this.getClient()).invoices.retrieve(t)}async createCheckoutSession(t,e,i,r,s){let o=await this.getClient(),a={customer:t,payment_method_types:["card"],line_items:[{price:e,quantity:1}],mode:"subscription",success_url:i,cancel_url:r,metadata:s?.metadata};return s?.trialDays&&(a.subscription_data={trial_period_days:s.trialDays}),o.checkout.sessions.create(a)}async createPortalSession(t,e){return(await this.getClient()).billingPortal.sessions.create({customer:t,return_url:e})}async constructWebhookEvent(t,e){if(!this.config)throw new Error("StripeService not configured");return(await this.getClient()).webhooks.constructEvent(t,e,this.config.webhookSecret)}async listPrices(t,e=100){let i=await this.getClient(),r={limit:e,expand:["data.product"]};return t&&(r.product=t),(await i.prices.list(r)).data}async listProducts(t=100){return(await(await this.getClient()).products.list({limit:t})).data}async refundInvoice(t){let e=await this.getClient(),i=await e.invoices.retrieve(t),r=i.charge??i.payment_intent;if(!r)throw new Error("Invoice has no associated charge or payment intent");return e.refunds.create({charge:String(r)})}async getRefund(t){return(await this.getClient()).refunds.retrieve(t)}async listRefunds(t){return(await(await this.getClient()).refunds.list({charge:t})).data}};var d=class{handlers=new Map;on(t,e){return this.handlers.has(t)||this.handlers.set(t,[]),this.handlers.get(t).push(e),this}once(t,e){let i=async r=>{await e(r),this.off(t,i)};return this.on(t,i)}off(t,e){let i=this.handlers.get(t);if(i){let r=i.indexOf(e);r>-1&&i.splice(r,1)}}removeAllListeners(t){t?this.handlers.delete(t):this.handlers.clear()}async handle(t){let e=this.handlers.get(t.type)||[];for(let i of e)try{await i(t)}catch(r){throw console.error(`Error handling webhook event ${t.type}:`,r),r}}getHandlers(t){return this.handlers.get(t)||[]}getEventTypes(){return Array.from(this.handlers.keys())}hasHandlers(t){let e=this.handlers.get(t);return!!e&&e.length>0}};function m(n){let t=n.current_period_start;return typeof t=="number"?new Date(t*1e3):new Date(t)}function b(n){let t=n.current_period_end;return typeof t=="number"?new Date(t*1e3):new Date(t)}function w(n){let t=n.trial_end;return t?typeof t=="number"?new Date(t*1e3):new Date(t):null}function P(n){let t=n.canceled_at;return t?typeof t=="number"?new Date(t*1e3):new Date(t):null}var u=class{stripeService;deps;constructor(t){this.stripeService=t.stripeService,this.deps=t}async subscribe(t,e,i){let r=await this.deps.userRepository?.findById(t);if(!r)throw new Error(`User ${t} not found`);let s=await this.deps.planRepository?.findById(e);if(!s)throw new Error(`Plan ${e} not found`);let o=r.stripe_customer_id;o||(o=(await this.stripeService.createCustomer({id:t,name:r.name,email:r.email})).id,await this.deps.userRepository?.update(t,{stripe_customer_id:o}));let a=await this.stripeService.createSubscription(o,s.stripePriceId,{trialDays:i?.trialDays||s.trialDays,metadata:{userId:String(t),planId:String(e),...i?.metadata}}),c=await this.deps.subscriptionRepository?.create({user_id:t,stripe_subscription_id:a.id,stripe_customer_id:o,plan_id:e,status:a.status,current_period_start:m(a),current_period_end:b(a),trial_ends_at:w(a),cancel_at_period_end:a.cancel_at_period_end,canceled_at:P(a)});if(!c)throw new Error("Failed to create subscription record");return c}async upgrade(t,e){let i=await this.deps.subscriptionRepository?.findByUserId(t);if(!i)throw new Error(`User ${t} has no active subscription`);let r=await this.deps.planRepository?.findById(e);if(!r)throw new Error(`Plan ${e} not found`);let s=await this.stripeService.updateSubscription(i.stripeSubscriptionId,r.stripePriceId,{proration:"create_prorations"}),o=await this.deps.subscriptionRepository?.update(i.id,{plan_id:e,status:s.status,current_period_start:m(s),current_period_end:b(s)});if(!o)throw new Error("Failed to update subscription record");return o}async downgrade(t,e){let i=await this.deps.subscriptionRepository?.findByUserId(t);if(!i)throw new Error(`User ${t} has no active subscription`);let r=await this.deps.planRepository?.findById(e);if(!r)throw new Error(`Plan ${e} not found`);let s=await this.stripeService.updateSubscription(i.stripeSubscriptionId,r.stripePriceId,{proration:"none"}),o=await this.deps.subscriptionRepository?.update(i.id,{plan_id:e,status:s.status});if(!o)throw new Error("Failed to update subscription record");return o}async cancel(t,e=!1){let i=await this.deps.subscriptionRepository?.findByUserId(t);if(!i)throw new Error(`User ${t} has no active subscription`);await this.stripeService.cancelSubscription(i.stripeSubscriptionId,e),e?await this.deps.subscriptionRepository?.update(i.id,{status:"canceled",canceled_at:new Date}):await this.deps.subscriptionRepository?.update(i.id,{cancel_at_period_end:!0})}async resume(t){let e=await this.deps.subscriptionRepository?.findByUserId(t);if(!e)throw new Error(`User ${t} has no subscription`);let i=await this.stripeService.resumeSubscription(e.stripeSubscriptionId),r=await this.deps.subscriptionRepository?.update(e.id,{cancel_at_period_end:!1,canceled_at:null,status:i.status});if(!r)throw new Error("Failed to update subscription record");return r}async isSubscribed(t,e){let i=await this.deps.subscriptionRepository?.findByUserId(t);return!(!i||!i.isActive()||e&&i.planId!==e)}async onTrial(t){let e=await this.deps.subscriptionRepository?.findByUserId(t);return e?e.isOnTrial():!1}async hasFeature(t,e){let i=await this.deps.subscriptionRepository?.findByUserId(t);if(!i)return!1;let r=await this.deps.planRepository?.findById(i.planId);return r?r.hasFeature(e):!1}async syncFromStripe(t){let e=await this.deps.userRepository?.findById(t);if(!e||!e.stripe_customer_id)throw new Error(`User ${t} not found or has no Stripe customer`);let r=await(await this.stripeService.getClient()).subscriptions.list({customer:e.stripe_customer_id,status:"active",limit:1});if(r.data.length===0)throw new Error(`User ${t} has no active Stripe subscription`);let s=r.data[0],o=s.items.data[0]?.price?.id,a=await this.deps.planRepository?.findByStripePriceId(o);if(!a)throw new Error(`No plan found for Stripe price ${o}`);let c=await this.deps.subscriptionRepository?.findByStripeSubscriptionId(s.id),l={user_id:t,stripe_subscription_id:s.id,stripe_customer_id:e.stripe_customer_id,plan_id:a.id,status:s.status,current_period_start:m(s),current_period_end:b(s),trial_ends_at:w(s),cancel_at_period_end:s.cancel_at_period_end,canceled_at:P(s)};if(c?c=await this.deps.subscriptionRepository?.update(c.id,l):c=await this.deps.subscriptionRepository?.create(l),!c)throw new Error("Failed to sync subscription");return c}};var y=class{id;userId;stripeSubscriptionId;stripeCustomerId;planId;status;currentPeriodStart;currentPeriodEnd;cancelAtPeriodEnd;trialEndsAt;canceledAt;createdAt;updatedAt;constructor(t){this.id=t.id,this.userId=t.userId,this.stripeSubscriptionId=t.stripeSubscriptionId,this.stripeCustomerId=t.stripeCustomerId,this.planId=t.planId,this.status=t.status,this.currentPeriodStart=t.currentPeriodStart,this.currentPeriodEnd=t.currentPeriodEnd,this.cancelAtPeriodEnd=t.cancelAtPeriodEnd,this.trialEndsAt=t.trialEndsAt,this.canceledAt=t.canceledAt,this.createdAt=t.createdAt,this.updatedAt=t.updatedAt}isActive(){return this.status==="active"}isPastDue(){return this.status==="past_due"}isCanceled(){return this.status==="canceled"}isOnTrial(){return this.status==="trialing"||this.trialEndsAt!==null&&new Date<this.trialEndsAt}isOnGracePeriod(){return this.cancelAtPeriodEnd&&this.status!=="canceled"}isIncomplete(){return this.status==="incomplete"}isPaused(){return this.status==="paused"}daysUntilEnd(){let t=this.currentPeriodEnd.getTime()-Date.now();return Math.ceil(t/(1e3*60*60*24))}};var f=class{id;name;stripePriceId;stripeProductId;price;currency;interval;intervalCount;trialDays;features;sortOrder;active;createdAt;updatedAt;constructor(t){this.id=t.id,this.name=t.name,this.stripePriceId=t.stripePriceId,this.stripeProductId=t.stripeProductId,this.price=t.price,this.currency=t.currency,this.interval=t.interval,this.intervalCount=t.intervalCount,this.trialDays=t.trialDays,this.features=t.features,this.sortOrder=t.sortOrder,this.active=t.active,this.createdAt=t.createdAt,this.updatedAt=t.updatedAt}isActive(){return this.active}monthlyPrice(){let t=this.price/100;return this.interval==="month"?t:t/12}yearlyPrice(){let t=this.price/100;return this.interval==="year"?t:t*12}hasFeature(t){return this.features.includes(t)}formattedPrice(){let t=(this.price/100).toFixed(2),e=this.intervalCount>1?`${this.intervalCount} ${this.interval}s`:this.interval;return`${this.currency.toUpperCase()} ${t}/${e}`}intervalLabel(){return this.intervalCount>1?`Every ${this.intervalCount} ${this.interval}s`:`Every ${this.interval}`}trialLabel(){return this.trialDays===0?"No trial":`${this.trialDays} day${this.trialDays!==1?"s":""} free trial`}};var g=class{id;userId;subscriptionId;stripeInvoiceId;amountDue;amountPaid;currency;status;paidAt;dueDate;invoicePdf;createdAt;updatedAt;constructor(t){this.id=t.id,this.userId=t.userId,this.subscriptionId=t.subscriptionId,this.stripeInvoiceId=t.stripeInvoiceId,this.amountDue=t.amountDue,this.amountPaid=t.amountPaid,this.currency=t.currency,this.status=t.status,this.paidAt=t.paidAt,this.dueDate=t.dueDate,this.invoicePdf=t.invoicePdf,this.createdAt=t.createdAt,this.updatedAt=t.updatedAt}isPaid(){return this.status==="paid"}isOpen(){return this.status==="open"}isDraft(){return this.status==="draft"}isVoid(){return this.status==="void"}isUncollectible(){return this.status==="uncollectible"}isOverdue(){return!this.dueDate||this.status==="paid"||this.status==="void"?!1:new Date>this.dueDate}outstandingAmount(){return this.amountDue-this.amountPaid}formattedAmountDue(){return this.formatCurrency(this.amountDue)}formattedAmountPaid(){return this.formatCurrency(this.amountPaid)}formattedOutstanding(){return this.formatCurrency(this.outstandingAmount())}daysUntilDue(){return this.dueDate?Math.ceil((this.dueDate.getTime()-Date.now())/(1e3*60*60*24)):null}formatCurrency(t){return`${{usd:"$",eur:"\u20AC",gbp:"\xA3",jpy:"\xA5",cad:"C$",aud:"A$",chf:"CHF"}[this.currency.toLowerCase()]||this.currency.toUpperCase()}${(t/100).toFixed(2)}`}};var S=class n{constructor(t,e,i){this.userId=t;this.email=e;this.userName=i}name="sync-stripe-customer";async handle(t){let e=await t.createCustomer({id:this.userId,name:this.userName,email:this.email});console.log(`Synced user ${this.userId} to Stripe customer ${e.id}`)}serialize(){return JSON.stringify({userId:this.userId,email:this.email,name:this.userName})}static restore(t){return new n(t.userId,t.email,t.name)}};var v=class{stripeService=new p;webhookHandler=new d;subscriptionManager=null;configure(t){this.stripeService.configure(t)}service(){return this.stripeService}webhooks(){return this.webhookHandler}subscriptions(t){if(!this.subscriptionManager){if(!t)throw new Error("SubscriptionManager not initialized. Call Stripe.subscriptions({ stripeService, ... }) with dependencies first.");this.subscriptionManager=new u(t)}return this.subscriptionManager}initSubscriptions(t){return this.subscriptionManager=new u({stripeService:this.stripeService,...t}),this.subscriptionManager}},q=h("svelar.stripe",()=>new v);export{g as Invoice,q as Stripe,v as StripeManager,p as StripeService,d as StripeWebhookHandler,y as Subscription,u as SubscriptionManager,f as SubscriptionPlan,S as SyncStripeCustomerJob};