@kyro-cms/core 0.12.57 → 0.12.60

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.
@@ -1,4 +1,4 @@
1
- 'use strict';var chunkHPYH7GTS_cjs=require('./chunk-HPYH7GTS.cjs'),chunkBUNLC3II_cjs=require('./chunk-BUNLC3II.cjs');chunkBUNLC3II_cjs.h();function g(i){let{brand:e,title:t,previewText:r=t,badgeText:s="Security Notification",badgeType:o="info",bodyHtml:a,ctaText:n,ctaUrl:c,secondaryCtaText:d,secondaryCtaUrl:f}=i,m="#eff6ff",u="#bfdbfe",h="#1d4ed8";o==="success"?(m="#ecfdf5",u="#a7f3d0",h="#047857"):o==="warning"?(m="#fffbeb",u="#fde68a",h="#b45309"):o==="error"&&(m="#fef2f2",u="#fecaca",h="#b91c1c");let y=e?.siteName||"Kyro CMS",B=e?.logoUrl||"https://kyro-cms.com/logo.svg",N=e?.logoDarkUrl||e?.logoUrl||"https://kyro-cms.com/logo-white.svg",b=e?.appUrl||"https://kyro-cms.com";return `<!DOCTYPE html>
1
+ 'use strict';var chunkHPYH7GTS_cjs=require('./chunk-HPYH7GTS.cjs'),chunkBUNLC3II_cjs=require('./chunk-BUNLC3II.cjs');chunkBUNLC3II_cjs.h();function g(i){let{brand:e,title:t,previewText:r=t,bodyHtml:s,ctaText:o,ctaUrl:n,secondaryCtaText:a,secondaryCtaUrl:l}=i,p=e?.siteName||"Kyro CMS",f=e?.logoUrl||"https://kyro-cms.com/logo.svg",m=e?.logoDarkUrl||e?.logoUrl||"https://kyro-cms.com/logo-white.svg",u=e?.appUrl||"https://kyro-cms.com";return `<!DOCTYPE html>
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="UTF-8">
@@ -34,30 +34,25 @@
34
34
  }
35
35
  </style>
36
36
  </head>
37
- <body class="email-body" style="margin: 0; padding: 36px 16px; background-color: #f4f4f5; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; color: #09090b; -webkit-font-smoothing: antialiased;">
37
+ <body class="email-body" style="margin: 0; padding: 24px 12px; background-color: #fafafa; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; color: #09090b; -webkit-font-smoothing: antialiased;">
38
38
  <!-- Preview Text -->
39
39
  <div style="display: none; max-height: 0; overflow: hidden;">${r}</div>
40
40
 
41
- <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-card" style="max-width: 540px; margin: 0 auto; background-color: #ffffff; border: 1px solid #e4e4e7; border-radius: 12px; overflow: hidden; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.03);">
41
+ <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-card" style="max-width: 480px; margin: 0 auto; background-color: #ffffff; border: 1px solid #f4f4f5; border-radius: 16px; overflow: hidden; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.02);">
42
42
  <!-- Header Bar -->
43
43
  <tr>
44
- <td class="email-header" style="padding: 22px 28px; border-bottom: 1px solid #f4f4f5; background-color: #ffffff;">
44
+ <td class="email-header" style="padding: 16px 24px; border-bottom: 1px solid #fafafa; background-color: #ffffff;">
45
45
  <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0">
46
46
  <tr>
47
- <td align="left" valign="middle">
48
- <a href="${b}" target="_blank" style="text-decoration: none; display: inline-flex; align-items: center; gap: 10px;">
47
+ <td align="center" valign="middle">
48
+ <a href="${u}" target="_blank" style="text-decoration: none; display: inline-flex; align-items: center; gap: 8px;">
49
49
  <!-- Light Mode Logo -->
50
- <img src="${B}" alt="${y} Logo" class="logo-light" height="24" style="display: inline-block; border: 0; max-height: 24px; vertical-align: middle;" />
50
+ <img src="${f}" alt="${p} Logo" class="logo-light" height="22" style="display: inline-block; border: 0; max-height: 22px; vertical-align: middle;" />
51
51
  <!-- Dark Mode Logo -->
52
- <img src="${N}" alt="${y} Logo" class="logo-dark" height="24" style="display: none; border: 0; max-height: 24px; vertical-align: middle;" />
53
- <span class="email-brand-text" style="font-size: 16px; font-weight: 700; color: #09090b; letter-spacing: -0.3px; vertical-align: middle;">${y}</span>
52
+ <img src="${m}" alt="${p} Logo" class="logo-dark" height="22" style="display: none; border: 0; max-height: 22px; vertical-align: middle;" />
53
+ <span class="email-brand-text" style="font-size: 15px; font-weight: 600; color: #09090b; letter-spacing: -0.2px; vertical-align: middle;">${p}</span>
54
54
  </a>
55
55
  </td>
56
- <td align="right" valign="middle">
57
- <span class="badge-status" style="display: inline-block; padding: 4px 10px; background-color: ${m}; border: 1px solid ${u}; border-radius: 9999px; font-size: 11px; font-weight: 500; color: ${h};">
58
- ${s}
59
- </span>
60
- </td>
61
56
  </tr>
62
57
  </table>
63
58
  </td>
@@ -65,23 +60,23 @@
65
60
 
66
61
  <!-- Body Section -->
67
62
  <tr>
68
- <td style="padding: 28px;">
69
- <h1 class="email-title" style="margin: 0 0 12px; font-size: 20px; font-weight: 600; color: #09090b; letter-spacing: -0.3px;">
63
+ <td style="padding: 24px;">
64
+ <h1 class="email-title" style="margin: 0 0 8px; font-size: 18px; font-weight: 600; color: #09090b; letter-spacing: -0.2px; text-align: center;">
70
65
  ${t}
71
66
  </h1>
72
67
 
73
- ${a}
68
+ ${s}
74
69
 
75
- ${n&&c?`
70
+ ${o&&n?`
76
71
  <!-- Action Buttons -->
77
- <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" style="margin-top: 24px;">
72
+ <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" style="margin-top: 20px;">
78
73
  <tr>
79
- <td align="left">
80
- <a href="${c}" target="_blank" class="email-btn-primary" style="display: inline-block; padding: 11px 20px; background-color: #09090b; color: #ffffff; font-size: 13px; font-weight: 500; text-decoration: none; border-radius: 6px;">
81
- ${n} \u2192
74
+ <td align="center">
75
+ <a href="${n}" target="_blank" class="email-btn-primary" style="display: inline-block; padding: 10px 18px; background-color: #09090b; color: #ffffff; font-size: 13px; font-weight: 500; text-decoration: none; border-radius: 8px;">
76
+ ${o} \u2192
82
77
  </a>
83
- ${d&&f?`<a href="${f}" target="_blank" class="email-btn-secondary" style="display: inline-block; padding: 11px 16px; margin-left: 8px; background-color: #ffffff; border: 1px solid #e4e4e7; color: #09090b; font-size: 13px; font-weight: 500; text-decoration: none; border-radius: 6px;">
84
- ${d}
78
+ ${a&&l?`<a href="${l}" target="_blank" class="email-btn-secondary" style="display: inline-block; padding: 10px 16px; margin-left: 8px; background-color: #ffffff; border: 1px solid #e4e4e7; color: #09090b; font-size: 13px; font-weight: 500; text-decoration: none; border-radius: 8px;">
79
+ ${a}
85
80
  </a>`:""}
86
81
  </td>
87
82
  </tr>
@@ -91,20 +86,16 @@
91
86
 
92
87
  <!-- Footer -->
93
88
  <tr>
94
- <td class="email-footer" style="padding: 18px 28px; border-top: 1px solid #f4f4f5; background-color: #fafafa; text-align: center;">
95
- <p class="email-footer-text" style="margin: 0 0 8px; font-size: 12px; color: #71717a;">
96
- Sent securely via <strong>${y} Authentication Engine</strong>.
97
- </p>
98
- <p style="margin: 0; font-size: 12px; color: #71717a;">
99
- <a href="${b}" target="_blank" class="email-footer-link" style="color: #09090b; text-decoration: none; font-weight: 500;">${b.replace(/^https?:\/\//,"")}</a> &nbsp;\u2022&nbsp;
100
- <a href="${b}/docs" target="_blank" class="email-footer-link" style="color: #09090b; text-decoration: none; font-weight: 500;">Docs</a> &nbsp;\u2022&nbsp;
101
- <a href="https://github.com/danielDozie/kyro-cms" target="_blank" class="email-footer-link" style="color: #09090b; text-decoration: none; font-weight: 500;">GitHub</a>
89
+ <td class="email-footer" style="padding: 16px 24px; border-top: 1px solid #fafafa; background-color: #fdfdfd; text-align: center;">
90
+ <p style="margin: 0; font-size: 12px; color: #a1a1aa;">
91
+ <a href="${u}" target="_blank" class="email-footer-link" style="color: #71717a; text-decoration: none; font-weight: 500;">${u.replace(/^https?:\/\//,"")}</a> &nbsp;\u2022&nbsp;
92
+ <a href="${u}/docs" target="_blank" class="email-footer-link" style="color: #71717a; text-decoration: none; font-weight: 500;">Docs</a>
102
93
  </p>
103
94
  </td>
104
95
  </tr>
105
96
  </table>
106
97
  </body>
107
- </html>`}chunkBUNLC3II_cjs.h();function _(i,e="User",t){let r="Confirm your email address \u2014 Kyro CMS",s=`
98
+ </html>`}chunkBUNLC3II_cjs.h();function b(i,e="User",t){let r="Confirm your email address \u2014 Kyro CMS",s=`
108
99
  <p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
109
100
  Hello <strong class="email-strong" style="color: #09090b;">${e}</strong>,
110
101
  </p>
@@ -125,14 +116,14 @@
125
116
  <p class="email-text" style="margin: 0 0 8px; font-size: 12px; color: #71717a;">
126
117
  This verification link will expire in 24 hours. If you did not create an account, you can safely ignore this email.
127
118
  </p>
128
- `,o=g({brand:t,title:"Confirm Your Email Address",previewText:"Please confirm your email address to activate your Kyro CMS account.",badgeText:"Action Required",badgeType:"warning",bodyHtml:s,ctaText:"Confirm Email Address",ctaUrl:i,secondaryCtaText:"Documentation",secondaryCtaUrl:"https://kyro-cms.com/docs"}),a=`Welcome, ${e}!
119
+ `,o=g({brand:t,title:"Confirm Your Email Address",previewText:"Please confirm your email address to activate your Kyro CMS account.",bodyHtml:s,ctaText:"Confirm Email Address",ctaUrl:i,secondaryCtaText:"Documentation",secondaryCtaUrl:"https://kyro-cms.com/docs"}),n=`Welcome, ${e}!
129
120
 
130
121
  Please verify your email address by visiting:
131
122
  ${i}
132
123
 
133
124
  This link expires in 24 hours.
134
125
 
135
- Kyro CMS \u2014 https://kyro-cms.com`;return {subject:r,html:o,text:a}}chunkBUNLC3II_cjs.h();function T(i,e="User",t){let r="Reset your password \u2014 Kyro CMS",s=`
126
+ Kyro CMS \u2014 https://kyro-cms.com`;return {subject:r,html:o,text:n}}chunkBUNLC3II_cjs.h();function x(i,e="User",t){let r="Reset your password \u2014 Kyro CMS",s=`
136
127
  <p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
137
128
  Hello <strong class="email-strong" style="color: #09090b;">${e}</strong>,
138
129
  </p>
@@ -153,14 +144,14 @@ Kyro CMS \u2014 https://kyro-cms.com`;return {subject:r,html:o,text:a}}chunkBUNL
153
144
  <p class="email-text" style="margin: 0 0 8px; font-size: 12px; color: #71717a;">
154
145
  For security reasons, this link will expire in 1 hour. If you did not request a password reset, no further action is required.
155
146
  </p>
156
- `,o=g({brand:t,title:"Reset Your Password",previewText:"Use this secure link to reset your Kyro CMS password.",badgeText:"Security Action",badgeType:"warning",bodyHtml:s,ctaText:"Reset Password",ctaUrl:i}),a=`Hello ${e},
147
+ `,o=g({brand:t,title:"Reset Your Password",previewText:"Use this secure link to reset your Kyro CMS password.",bodyHtml:s,ctaText:"Reset Password",ctaUrl:i}),n=`Hello ${e},
157
148
 
158
149
  Reset your password using the following link:
159
150
  ${i}
160
151
 
161
152
  This link will expire in 1 hour.
162
153
 
163
- Kyro CMS \u2014 https://kyro-cms.com`;return {subject:r,html:o,text:a}}chunkBUNLC3II_cjs.h();function S(i="User",e="https://kyro-cms.com",t){let r="Welcome to Kyro CMS!",s=`
154
+ Kyro CMS \u2014 https://kyro-cms.com`;return {subject:r,html:o,text:n}}chunkBUNLC3II_cjs.h();function w(i="User",e="https://kyro-cms.com",t){let r="Welcome to Kyro CMS!",s=`
164
155
  <p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
165
156
  Welcome <strong class="email-strong" style="color: #09090b;">${i}</strong>,
166
157
  </p>
@@ -181,32 +172,42 @@ Kyro CMS \u2014 https://kyro-cms.com`;return {subject:r,html:o,text:a}}chunkBUNL
181
172
  </td>
182
173
  </tr>
183
174
  </table>
184
- `,o=g({brand:t,title:"Welcome to Kyro CMS",previewText:"Your account is verified and ready. Start building content applications.",badgeText:"Account Ready",badgeType:"success",bodyHtml:s,ctaText:"Open Dashboard",ctaUrl:e,secondaryCtaText:"Documentation",secondaryCtaUrl:"https://kyro-cms.com/docs"}),a=`Welcome to Kyro CMS, ${i}!
175
+ `,o=g({brand:t,title:"Welcome to Kyro CMS",previewText:"Your account is verified and ready. Start building content applications.",bodyHtml:s,ctaText:"Open Dashboard",ctaUrl:e,secondaryCtaText:"Documentation",secondaryCtaUrl:"https://kyro-cms.com/docs"}),n=`Welcome to Kyro CMS, ${i}!
185
176
 
186
177
  Your account is active. Log in at ${e} to start building.
187
178
 
188
- Documentation: https://kyro-cms.com/docs`;return {subject:r,html:o,text:a}}chunkBUNLC3II_cjs.h();function C(i="User",e){let t="Security Alert: Password Changed \u2014 Kyro CMS",r=new Date().toUTCString(),s=`
189
- <p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
179
+ Documentation: https://kyro-cms.com/docs`;return {subject:r,html:o,text:n}}chunkBUNLC3II_cjs.h();function _(i="User",e,t,r){let s="Security Alert: Password Changed \u2014 Kyro CMS",o=new Date().toUTCString(),n=`
180
+ <p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b; text-align: center;">
190
181
  Hello <strong class="email-strong" style="color: #09090b;">${i}</strong>,
191
182
  </p>
192
- <p class="email-text" style="margin: 0 0 20px; font-size: 14px; line-height: 1.6; color: #52525b;">
193
- This email confirms that the password for your Kyro CMS account was successfully updated on <strong>${r}</strong>.
183
+ <p class="email-text" style="margin: 0 0 20px; font-size: 14px; line-height: 1.6; color: #52525b; text-align: center;">
184
+ This email confirms that the password for your Kyro CMS account was successfully updated on <strong>${o}</strong>.
194
185
  </p>
195
186
 
196
187
  <!-- Security Warning Card -->
197
- <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-table" style="background-color: #fef2f2; border: 1px solid #fecaca; border-radius: 8px; margin-bottom: 20px; padding: 14px; border-collapse: separate;">
188
+ <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-table" style="background-color: #fef2f2; border: 1px solid #fecaca; border-radius: 12px; margin-bottom: 20px; padding: 16px; border-collapse: separate;">
198
189
  <tr>
199
- <td style="font-size: 13px; color: #991b1b; line-height: 1.5;">
190
+ <td style="font-size: 13px; color: #991b1b; line-height: 1.5; text-align: center;">
200
191
  \u26A0\uFE0F <strong>Did not request this change?</strong><br />
201
192
  If you did not initiate this change, your account may be compromised. Reset your password immediately and contact an administrator.
202
193
  </td>
203
194
  </tr>
204
195
  </table>
205
- `,o=g({brand:e,title:"Password Updated",previewText:"Your Kyro CMS account password was updated.",badgeText:"Security Alert",badgeType:"warning",bodyHtml:s,ctaText:"Account Security",ctaUrl:"https://kyro-cms.com"}),a=`Security Alert: Your Kyro CMS password was updated at ${r}.
196
+
197
+ ${t||r?`
198
+ <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-table" style="background-color: #fafafa; border: 1px solid #f4f4f5; border-radius: 12px; margin-bottom: 20px; padding: 16px; border-collapse: separate;">
199
+ <tr>
200
+ <td style="font-size: 13px; color: #09090b; line-height: 1.6;" class="email-value">
201
+ <strong>Action IP:</strong> ${t||"Unknown"}<br />
202
+ <strong>Device:</strong> ${r||"Unknown"}
203
+ </td>
204
+ </tr>
205
+ </table>`:""}
206
+ `,a=g({brand:e,title:"Password Updated",previewText:"Your Kyro CMS account password was updated.",bodyHtml:n,ctaText:"Account Security",ctaUrl:"https://kyro-cms.com"}),l=`Security Alert: Your Kyro CMS password was updated at ${o}.
206
207
 
207
208
  If you did not make this change, please reset your password immediately.
208
209
 
209
- Kyro CMS \u2014 https://kyro-cms.com`;return {subject:t,html:o,text:a}}chunkBUNLC3II_cjs.h();function k(i,e,t="User",r){let s="Your one-time login link \u2014 Kyro CMS",o=`
210
+ Kyro CMS \u2014 https://kyro-cms.com`;return {subject:s,html:a,text:l}}chunkBUNLC3II_cjs.h();function C(i,e,t="User",r){let s="Your one-time login link \u2014 Kyro CMS",o=`
210
211
  <p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
211
212
  Hello <strong class="email-strong" style="color: #09090b;">${t}</strong>,
212
213
  </p>
@@ -232,7 +233,7 @@ Kyro CMS \u2014 https://kyro-cms.com`;return {subject:t,html:o,text:a}}chunkBUNL
232
233
  <p class="email-text" style="margin: 0 0 8px; font-size: 12px; color: #71717a;">
233
234
  This single-use link will expire in 10 minutes. Never share authentication links with anyone.
234
235
  </p>
235
- `,a=g({brand:r,title:"Sign in to Kyro CMS",previewText:"Your secure magic login link for Kyro CMS.",badgeText:"Instant Login",badgeType:"info",bodyHtml:o,ctaText:"Sign In Now",ctaUrl:i}),n=`Hello ${t},
236
+ `,n=g({brand:r,title:"Sign in to Kyro CMS",previewText:"Your secure magic login link for Kyro CMS.",bodyHtml:o,ctaText:"Sign In Now",ctaUrl:i}),a=`Hello ${t},
236
237
 
237
238
  Sign in to Kyro CMS using the link below:
238
239
  ${i}${e?`
@@ -241,26 +242,36 @@ Or enter code: ${e}`:""}
241
242
 
242
243
  This link expires in 10 minutes.
243
244
 
244
- Kyro CMS \u2014 https://kyro-cms.com`;return {subject:s,html:a,text:n}}chunkBUNLC3II_cjs.h();function E(i,e,t="User",r){let s="Security Alert: Account Temporarily Locked \u2014 Kyro CMS",o=`
245
- <p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
245
+ Kyro CMS \u2014 https://kyro-cms.com`;return {subject:s,html:n,text:a}}chunkBUNLC3II_cjs.h();function S(i,e,t="User",r,s,o){let n="Security Alert: Account Temporarily Locked \u2014 Kyro CMS",a=`
246
+ <p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b; text-align: center;">
246
247
  Hello <strong class="email-strong" style="color: #09090b;">${t}</strong>,
247
248
  </p>
248
- <p class="email-text" style="margin: 0 0 20px; font-size: 14px; line-height: 1.6; color: #52525b;">
249
+ <p class="email-text" style="margin: 0 0 20px; font-size: 14px; line-height: 1.6; color: #52525b; text-align: center;">
249
250
  Your Kyro CMS account was temporarily locked after <strong>${i} failed login attempts</strong>.
250
251
  </p>
251
252
 
252
253
  <!-- Lockout Notice Card -->
253
- <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-table" style="background-color: #fffbeb; border: 1px solid #fde68a; border-radius: 8px; margin-bottom: 20px; padding: 14px; border-collapse: separate;">
254
+ <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-table" style="background-color: #fffbeb; border: 1px solid #fde68a; border-radius: 12px; margin-bottom: 20px; padding: 16px; border-collapse: separate;">
254
255
  <tr>
255
- <td style="font-size: 13px; color: #b45309; line-height: 1.5;">
256
+ <td style="font-size: 13px; color: #b45309; line-height: 1.5; text-align: center;">
256
257
  \u{1F512} <strong>Lockout duration:</strong> ${e} minutes.<br />
257
258
  You may try logging in again after the cooling-off period expires.
258
259
  </td>
259
260
  </tr>
260
261
  </table>
261
- `,a=g({brand:r,title:"Account Temporarily Locked",previewText:"Your Kyro CMS account was locked due to multiple failed login attempts.",badgeText:"Security Lockout",badgeType:"warning",bodyHtml:o,ctaText:"Unlock Instructions",ctaUrl:"https://kyro-cms.com/docs"}),n=`Security Alert: Account temporarily locked for ${t} after ${i} failed login attempts. Unlocks in ${e} minutes.
262
+
263
+ ${s||o?`
264
+ <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-table" style="background-color: #fafafa; border: 1px solid #f4f4f5; border-radius: 12px; margin-bottom: 20px; padding: 16px; border-collapse: separate;">
265
+ <tr>
266
+ <td style="font-size: 13px; color: #09090b; line-height: 1.6;" class="email-value">
267
+ <strong>Failed Attempts IP:</strong> ${s||"Unknown"}<br />
268
+ <strong>Device:</strong> ${o||"Unknown"}
269
+ </td>
270
+ </tr>
271
+ </table>`:""}
272
+ `,l=g({brand:r,title:"Account Temporarily Locked",previewText:"Your Kyro CMS account was locked due to multiple failed login attempts.",bodyHtml:a,ctaText:"Unlock Instructions",ctaUrl:"https://kyro-cms.com/docs"}),p=`Security Alert: Account temporarily locked for ${t} after ${i} failed login attempts. Unlocks in ${e} minutes.
262
273
 
263
- Kyro CMS \u2014 https://kyro-cms.com`;return {subject:s,html:a,text:n}}chunkBUNLC3II_cjs.h();function v(i,e="Editor",t="An Administrator",r){let s="You're invited to join Kyro CMS",o=`
274
+ Kyro CMS \u2014 https://kyro-cms.com`;return {subject:n,html:l,text:p}}chunkBUNLC3II_cjs.h();function T(i,e="Editor",t="An Administrator",r){let s="You're invited to join Kyro CMS",o=`
264
275
  <p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
265
276
  Hello,
266
277
  </p>
@@ -277,47 +288,48 @@ Kyro CMS \u2014 https://kyro-cms.com`;return {subject:s,html:a,text:n}}chunkBUNL
277
288
  </td>
278
289
  </tr>
279
290
  </table>
280
- `,a=g({brand:r,title:"Workspace Invitation",previewText:`You have been invited to join Kyro CMS as an ${e}.`,badgeText:"Team Invite",badgeType:"info",bodyHtml:o,ctaText:"Accept Invitation",ctaUrl:i,secondaryCtaText:"Documentation",secondaryCtaUrl:"https://kyro-cms.com/docs"}),n=`You're invited to join Kyro CMS as an ${e} by ${t}.
291
+ `,n=g({brand:r,title:"Workspace Invitation",previewText:`You have been invited to join Kyro CMS as an ${e}.`,bodyHtml:o,ctaText:"Accept Invitation",ctaUrl:i,secondaryCtaText:"Documentation",secondaryCtaUrl:"https://kyro-cms.com/docs"}),a=`You're invited to join Kyro CMS as an ${e} by ${t}.
281
292
 
282
293
  Accept your invitation here:
283
294
  ${i}
284
295
 
285
- Kyro CMS \u2014 https://kyro-cms.com`;return {subject:s,html:a,text:n}}chunkBUNLC3II_cjs.h();function A(i,e,t="User",r){let s="Security Alert: New Sign-in to Kyro CMS",o=`
286
- <p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
296
+ Kyro CMS \u2014 https://kyro-cms.com`;return {subject:s,html:n,text:a}}chunkBUNLC3II_cjs.h();function k(i,e,t="User",r,s="Unknown Device"){let o="Security Alert: New Sign-in to Kyro CMS",n=`
297
+ <p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b; text-align: center;">
287
298
  Hello <strong class="email-strong" style="color: #09090b;">${t}</strong>,
288
299
  </p>
289
- <p class="email-text" style="margin: 0 0 20px; font-size: 14px; line-height: 1.6; color: #52525b;">
300
+ <p class="email-text" style="margin: 0 0 20px; font-size: 14px; line-height: 1.6; color: #52525b; text-align: center;">
290
301
  A new sign-in to your Kyro CMS account was detected.
291
302
  </p>
292
303
 
293
304
  <!-- Sign-in Details -->
294
- <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-table" style="background-color: #fafafa; border: 1px solid #e4e4e7; border-radius: 8px; margin-bottom: 20px; padding: 14px; border-collapse: separate;">
305
+ <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-table" style="background-color: #fafafa; border: 1px solid #f4f4f5; border-radius: 12px; margin-bottom: 20px; padding: 16px; border-collapse: separate;">
295
306
  <tr>
296
307
  <td style="font-size: 13px; color: #09090b; line-height: 1.6;" class="email-value">
297
308
  <strong>Time:</strong> ${e}<br />
298
- <strong>Location/IP:</strong> ${i}
309
+ <strong>Location/IP:</strong> ${i}<br />
310
+ <strong>Device:</strong> ${s}
299
311
  </td>
300
312
  </tr>
301
313
  </table>
302
314
 
303
315
  <!-- Security Warning Card -->
304
- <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-table" style="background-color: #fef2f2; border: 1px solid #fecaca; border-radius: 8px; margin-bottom: 20px; padding: 14px; border-collapse: separate;">
316
+ <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" class="email-table" style="background-color: #fef2f2; border: 1px solid #fecaca; border-radius: 12px; margin-bottom: 20px; padding: 16px; border-collapse: separate;">
305
317
  <tr>
306
- <td style="font-size: 13px; color: #991b1b; line-height: 1.5;">
318
+ <td style="font-size: 13px; color: #991b1b; line-height: 1.5; text-align: center;">
307
319
  \u26A0\uFE0F <strong>Don't recognize this activity?</strong><br />
308
320
  If you did not sign in recently, your account may be compromised. Please reset your password immediately and contact an administrator.
309
321
  </td>
310
322
  </tr>
311
323
  </table>
312
- `,a=g({brand:r,title:"New Sign-in Detected",previewText:"A new sign-in was detected on your Kyro CMS account.",badgeText:"Security Alert",badgeType:"warning",bodyHtml:o,ctaText:"Review Account Security",ctaUrl:"https://kyro-cms.com"}),n=`Security Alert: New Sign-in to Kyro CMS
324
+ `,a=g({brand:r,title:"New Sign-in Detected",previewText:"A new sign-in was detected on your Kyro CMS account.",bodyHtml:n,ctaText:"Review Account Security",ctaUrl:"https://kyro-cms.com"}),l=`Security Alert: New Sign-in to Kyro CMS
313
325
 
314
326
  Hello ${t},
315
327
 
316
- A new sign-in to your account was detected at ${e} from ${i}.
328
+ A new sign-in to your account was detected at ${e} from ${i} using ${s}.
317
329
 
318
330
  If you did not sign in recently, please reset your password immediately.
319
331
 
320
- Kyro CMS \u2014 https://kyro-cms.com`;return {subject:s,html:a,text:n}}chunkBUNLC3II_cjs.h();function R(i,e="Customer",t,r,s){let o=`Order Confirmation #${i}`,a=`
332
+ Kyro CMS \u2014 https://kyro-cms.com`;return {subject:o,html:a,text:l}}chunkBUNLC3II_cjs.h();function E(i,e="Customer",t,r,s){let o=`Order Confirmation #${i}`,n=`
321
333
  <p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
322
334
  Hi <strong class="email-strong" style="color: #09090b;">${e}</strong>,
323
335
  </p>
@@ -333,13 +345,13 @@ Kyro CMS \u2014 https://kyro-cms.com`;return {subject:s,html:a,text:n}}chunkBUNL
333
345
  </td>
334
346
  </tr>
335
347
  </table>
336
- `,n=g({brand:s,title:"Order Confirmed",previewText:`Your order #${i} has been confirmed.`,badgeText:"Confirmed",badgeType:"success",bodyHtml:a,ctaText:"View Order",ctaUrl:r||"https://kyro-cms.com"}),c=`Hi ${e},
348
+ `,a=g({brand:s,title:"Order Confirmed",previewText:`Your order #${i} has been confirmed.`,bodyHtml:n,ctaText:"View Order",ctaUrl:r||"https://kyro-cms.com"}),l=`Hi ${e},
337
349
 
338
350
  Thank you for your order #${i}!
339
351
 
340
352
  Order Total: ${t}
341
353
 
342
- View your order here: ${r||"https://kyro-cms.com"}`;return {subject:o,html:n,text:c}}chunkBUNLC3II_cjs.h();function P(i,e="Customer",t,r,s){let o=`Your Order #${i} is on the way!`,a=`
354
+ View your order here: ${r||"https://kyro-cms.com"}`;return {subject:o,html:a,text:l}}chunkBUNLC3II_cjs.h();function v(i,e="Customer",t,r,s){let o=`Your Order #${i} is on the way!`,n=`
343
355
  <p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
344
356
  Great news, <strong class="email-strong" style="color: #09090b;">${e}</strong>!
345
357
  </p>
@@ -354,12 +366,12 @@ View your order here: ${r||"https://kyro-cms.com"}`;return {subject:o,html:n,tex
354
366
  </td>
355
367
  </tr>
356
368
  </table>
357
- `,n=g({brand:s,title:"Order Shipped",previewText:`Your order #${i} has shipped. Track your package now.`,badgeText:"Shipped",badgeType:"info",bodyHtml:a,ctaText:"Track Package",ctaUrl:r}),c=`Hi ${e},
369
+ `,a=g({brand:s,title:"Order Shipped",previewText:`Your order #${i} has shipped. Track your package now.`,bodyHtml:n,ctaText:"Track Package",ctaUrl:r}),l=`Hi ${e},
358
370
 
359
371
  Your order #${i} has been shipped!
360
372
 
361
373
  Tracking Number: ${t}
362
- Track it here: ${r}`;return {subject:o,html:n,text:c}}chunkBUNLC3II_cjs.h();function I(i,e="Customer",t,r){let s=`Your Order #${i} has been delivered`,o=`
374
+ Track it here: ${r}`;return {subject:o,html:a,text:l}}chunkBUNLC3II_cjs.h();function A(i,e="Customer",t,r){let s=`Your Order #${i} has been delivered`,o=`
363
375
  <p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
364
376
  Hi <strong class="email-strong" style="color: #09090b;">${e}</strong>,
365
377
  </p>
@@ -369,11 +381,11 @@ Track it here: ${r}`;return {subject:o,html:n,text:c}}chunkBUNLC3II_cjs.h();func
369
381
  <p class="email-text" style="margin: 0 0 20px; font-size: 14px; line-height: 1.6; color: #52525b;">
370
382
  We'd love to hear your thoughts. If you have a minute, please leave a review for your items.
371
383
  </p>
372
- `,a=g({brand:r,title:"Order Delivered",previewText:`Your order #${i} has arrived!`,badgeText:"Delivered",badgeType:"success",bodyHtml:o,ctaText:"Leave a Review",ctaUrl:t}),n=`Hi ${e},
384
+ `,n=g({brand:r,title:"Order Delivered",previewText:`Your order #${i} has arrived!`,bodyHtml:o,ctaText:"Leave a Review",ctaUrl:t}),a=`Hi ${e},
373
385
 
374
386
  Your order #${i} has been delivered!
375
387
 
376
- Leave a review here: ${t}`;return {subject:s,html:a,text:n}}chunkBUNLC3II_cjs.h();function O(i,e="Customer",t,r){let s=`Refund Processed for Order #${i}`,o=`
388
+ Leave a review here: ${t}`;return {subject:s,html:n,text:a}}chunkBUNLC3II_cjs.h();function P(i,e="Customer",t,r){let s=`Refund Processed for Order #${i}`,o=`
377
389
  <p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
378
390
  Hi <strong class="email-strong" style="color: #09090b;">${e}</strong>,
379
391
  </p>
@@ -388,32 +400,32 @@ Leave a review here: ${t}`;return {subject:s,html:a,text:n}}chunkBUNLC3II_cjs.h(
388
400
  </td>
389
401
  </tr>
390
402
  </table>
391
- `,a=g({brand:r,title:"Refund Processed",previewText:`We have processed a refund of ${t} for order #${i}.`,badgeText:"Refunded",badgeType:"info",bodyHtml:o,ctaText:"View Store",ctaUrl:"https://kyro-cms.com"}),n=`Hi ${e},
403
+ `,n=g({brand:r,title:"Refund Processed",previewText:`We have processed a refund of ${t} for order #${i}.`,bodyHtml:o,ctaText:"View Store",ctaUrl:"https://kyro-cms.com"}),a=`Hi ${e},
392
404
 
393
405
  We have processed a refund of ${t} for order #${i}.
394
406
 
395
- View store: https://kyro-cms.com`;return {subject:s,html:a,text:n}}chunkBUNLC3II_cjs.h();function K(i="Customer",e,t){let r="You left something behind...",s=`
407
+ View store: https://kyro-cms.com`;return {subject:s,html:n,text:a}}chunkBUNLC3II_cjs.h();function R(i="Customer",e,t){let r="You left something behind...",s=`
396
408
  <p class="email-text" style="margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: #52525b;">
397
409
  Hi <strong class="email-strong" style="color: #09090b;">${i}</strong>,
398
410
  </p>
399
411
  <p class="email-text" style="margin: 0 0 20px; font-size: 14px; line-height: 1.6; color: #52525b;">
400
412
  We noticed you left some great items in your shopping cart. They are still waiting for you, but they might sell out soon!
401
413
  </p>
402
- `,o=g({brand:t,title:"Complete Your Purchase",previewText:"Your shopping cart is waiting for you. Complete your purchase now.",badgeText:"Cart Reminder",badgeType:"warning",bodyHtml:s,ctaText:"Return to Checkout",ctaUrl:e}),a=`Hi ${i},
414
+ `,o=g({brand:t,title:"Complete Your Purchase",previewText:"Your shopping cart is waiting for you. Complete your purchase now.",bodyHtml:s,ctaText:"Return to Checkout",ctaUrl:e}),n=`Hi ${i},
403
415
 
404
- You left some items in your cart! Complete your purchase here: ${e}`;return {subject:r,html:o,text:a}}chunkBUNLC3II_cjs.h();function L(i){return {verifyEmail:(e,t)=>_(e,t,i),resetPassword:(e,t)=>T(e,t,i),welcome:(e,t)=>S(e,t,i),passwordChanged:e=>C(e,i),magicLink:(e,t,r)=>k(e,t,r,i),accountLocked:(e,t,r)=>E(e,t,r,i),newLogin:(e,t,r)=>A(e,t,r,i),userInvite:(e,t,r)=>v(e,t,r,i),orderConfirmation:(e,t,r,s)=>R(e,t,r||"0.00",s,i),orderShipped:(e,t,r,s)=>P(e,t,r||"",s||"",i),orderDelivered:(e,t,r)=>I(e,t,r||"",i),orderRefunded:(e,t,r)=>O(e,t,r||"0.00",i),abandonedCart:(e,t)=>K(e,t||"",i)}}chunkBUNLC3II_cjs.h();var $=false,w=class i{db;cache={};loaded=false;static SENSITIVE_KEYS=["storage.s3.secret_access_key","storage.r2.secret_access_key","storage.gcs.private_key","storage.backblaze.application_key","storage.wasabi.secret_access_key","storage.ftp.password","storage.bunny.api_key","storage.cloudinary.api_secret","storage.imgix.sign_key","email.smtp.pass","auth.jwt_secret","auth.github_secret","auth.google_secret","auth.app_secret","database.url","redis.url","auth.admin_password"];constructor(e){this.db=e;}async load(){if(!this.loaded){await this.ensureSettingsTable();try{if(typeof this.db?.select=="function"){let e=await this.db.select().from(chunkHPYH7GTS_cjs.a);this.cache=e.reduce((t,r)=>(t[r.key]=r.value,t),{});}await this.loadFromGlobals();}catch{console.warn("ConfigService: Could not load settings from database, using environment fallbacks.");}this.loaded=true;}}async ensureSettingsTable(){if(!$)try{if(typeof this.db?.execute=="function"){let{sql:e}=await import('./drizzle-orm-47ELDEM6.cjs');await this.db.execute(e`
416
+ You left some items in your cart! Complete your purchase here: ${e}`;return {subject:r,html:o,text:n}}chunkBUNLC3II_cjs.h();function I(i){return {verifyEmail:(e,t)=>b(e,t,i),resetPassword:(e,t)=>x(e,t,i),welcome:(e,t)=>w(e,t,i),passwordChanged:e=>_(e,i),magicLink:(e,t,r)=>C(e,t,r,i),accountLocked:(e,t,r)=>S(e,t,r,i),newLogin:(e,t,r)=>k(e,t,r,i),userInvite:(e,t,r)=>T(e,t,r,i),orderConfirmation:(e,t,r,s)=>E(e,t,r||"0.00",s,i),orderShipped:(e,t,r,s)=>v(e,t,r||"",s||"",i),orderDelivered:(e,t,r)=>A(e,t,r||"",i),orderRefunded:(e,t,r)=>P(e,t,r||"0.00",i),abandonedCart:(e,t)=>R(e,t||"",i)}}chunkBUNLC3II_cjs.h();var O=false,y=class i{db;cache={};loaded=false;static SENSITIVE_KEYS=["storage.s3.secret_access_key","storage.r2.secret_access_key","storage.gcs.private_key","storage.backblaze.application_key","storage.wasabi.secret_access_key","storage.ftp.password","storage.bunny.api_key","storage.cloudinary.api_secret","storage.imgix.sign_key","email.smtp.pass","auth.jwt_secret","auth.github_secret","auth.google_secret","auth.app_secret","database.url","redis.url","auth.admin_password"];constructor(e){this.db=e;}async load(){if(!this.loaded){await this.ensureSettingsTable();try{if(typeof this.db?.select=="function"){let e=await this.db.select().from(chunkHPYH7GTS_cjs.a);this.cache=e.reduce((t,r)=>(t[r.key]=r.value,t),{});}await this.loadFromGlobals();}catch{console.warn("ConfigService: Could not load settings from database, using environment fallbacks.");}this.loaded=true;}}async ensureSettingsTable(){if(!O)try{if(typeof this.db?.execute=="function"){let{sql:e}=await import('./drizzle-orm-47ELDEM6.cjs');await this.db.execute(e`
405
417
  CREATE TABLE IF NOT EXISTS "settings" (
406
418
  "key" VARCHAR(255) PRIMARY KEY,
407
419
  "value" TEXT NOT NULL,
408
420
  "description" TEXT,
409
421
  "updated_at" TIMESTAMP DEFAULT NOW()
410
422
  )
411
- `),$=!0;}else typeof this.db?.exec=="function"&&(this.db.exec(`
423
+ `),O=!0;}else typeof this.db?.exec=="function"&&(this.db.exec(`
412
424
  CREATE TABLE IF NOT EXISTS settings (
413
425
  key TEXT PRIMARY KEY,
414
426
  value TEXT NOT NULL,
415
427
  description TEXT,
416
428
  updated_at TEXT
417
429
  )
418
- `),$=!0);}catch{}}async loadFromGlobals(){try{let e=null;if(typeof this.db?.findOne=="function")try{let s=await this.db.findOne({collection:"_globals_storage-settings",where:{},draft:!0});s&&(e=s);}catch{}if(!e&&typeof this.db?.execute=="function"){let{sql:s}=await import('./drizzle-orm-47ELDEM6.cjs'),o=['"_globals_storage-settings"','"_globals_storage_settings"','"global_storage_settings"'];for(let a of o)try{let n=await this.db.execute(s`SELECT * FROM ${s.raw(a)} LIMIT 1`);if(e=Array.isArray(n)?n[0]:n?.rows?n.rows[0]:null,e)break}catch{}}else if(!e&&typeof this.db?.prepare=="function"){let s=['"_globals_storage-settings"','"_globals_storage_settings"','"global_storage_settings"'];for(let o of s)try{if(e=this.db.prepare(`SELECT * FROM ${o} LIMIT 1`).get(),e)break}catch{}}if(!e)return;let t=s=>{if(!s)return null;if(typeof s=="string")try{return JSON.parse(s)}catch{return null}return s},r=e.provider||"local";if(this.cache["storage.type"]=r,r==="local"){let s=t(e.local);this.cache["storage.local.dir"]=s?.uploadDir||"./public/uploads",this.cache["storage.local.url"]=s?.baseUrl||"/uploads";}if(r==="aws"){let s=t(e.aws);this.cache["storage.s3.bucket"]=s?.bucket||"",this.cache["storage.s3.region"]=s?.region||"us-east-1",this.cache["storage.s3.access_key_id"]=s?.accessKeyId||"",this.cache["storage.s3.secret_access_key"]=s?.secretAccessKey||"",this.cache["storage.s3.endpoint"]=s?.endpoint||"",this.cache["storage.s3.cdn_url"]=s?.cdnUrl||"",this.cache["storage.s3.prefix"]=s?.prefix||"";}if(r==="r2"){let s=t(e.r2);this.cache["storage.r2.account_id"]=s?.accountId||"",this.cache["storage.r2.access_key_id"]=s?.accessKeyId||"",this.cache["storage.r2.secret_access_key"]=s?.secretAccessKey||"",this.cache["storage.r2.bucket"]=s?.bucket||"",this.cache["storage.r2.cdn_url"]=s?.cdnUrl||"",this.cache["storage.r2.prefix"]=s?.prefix||"";}if(r==="cloudinary"){let s=t(e.cloudinary);this.cache["storage.cloudinary.cloud_name"]=s?.cloudName||"",this.cache["storage.cloudinary.api_key"]=s?.apiKey||"",this.cache["storage.cloudinary.api_secret"]=s?.apiSecret||"",this.cache["storage.cloudinary.folder"]=s?.folder||"";}if(r==="ftp"){let s=t(e.ftp);this.cache["storage.ftp.host"]=s?.host||"",this.cache["storage.ftp.port"]=String(s?.port||"21"),this.cache["storage.ftp.user"]=s?.user||"",this.cache["storage.ftp.password"]=s?.password||"",this.cache["storage.ftp.secure"]=s?.secure?"true":"false",this.cache["storage.ftp.base_url"]=s?.baseUrl||"",this.cache["storage.ftp.prefix"]=s?.prefix||"";}}catch(e){console.warn("ConfigService: Could not load storage settings from globals table:",e);}try{let e=null;if(typeof this.db?.findOne=="function")try{let t=await this.db.findOne({collection:"_globals_email-settings",where:{},draft:!0});t&&(e=t);}catch{}if(!e&&typeof this.db?.execute=="function"){let{sql:t}=await import('./drizzle-orm-47ELDEM6.cjs'),r=['"_globals_email-settings"','"_globals_email_settings"','"global_email_settings"'];for(let s of r)try{let o=await this.db.execute(t`SELECT * FROM ${t.raw(s)} LIMIT 1`);if(e=Array.isArray(o)?o[0]:o?.rows?o.rows[0]:null,e)break}catch{}}else if(!e&&typeof this.db?.prepare=="function"){let t=['"_globals_email-settings"','"_globals_email_settings"','"global_email_settings"'];for(let r of t)try{if(e=this.db.prepare(`SELECT * FROM ${r} LIMIT 1`).get(),e)break}catch{}}if(e){let t=r=>{if(!r)return null;if(typeof r=="string")try{return JSON.parse(r)}catch{return null}return r};if(this.cache["email.provider"]=e.provider||"smtp",this.cache["email.smtp.from"]=e.fromEmail||"",this.cache["email.smtp.from_name"]=e.fromName||"",this.cache["email.smtp.reply_to"]=e.replyTo||"",e.provider==="smtp"){let r=t(e.smtp);this.cache["email.smtp.host"]=r?.host||"",this.cache["email.smtp.port"]=String(r?.port||"587"),this.cache["email.smtp.user"]=r?.username||"",this.cache["email.smtp.pass"]=r?.password||"",this.cache["email.smtp.secure"]=r?.secure?"true":"false";}else if(e.provider==="resend"){let r=t(e.resend);this.cache["email.smtp.pass"]=r?.apiKey||"";}else if(e.provider==="sendgrid"){let r=t(e.sendgrid);this.cache["email.smtp.pass"]=r?.apiKey||"";}else if(e.provider==="mailgun"){let r=t(e.mailgun);this.cache["email.smtp.pass"]=r?.apiKey||"";}else if(e.provider==="ses"){let r=t(e.ses);this.cache["email.smtp.user"]=r?.accessKeyId||"",this.cache["email.smtp.pass"]=r?.secretAccessKey||"";}}}catch(e){console.warn("ConfigService: Could not load email settings from globals table:",e);}}get(e,t,r){return this.cache[e]?this.cache[e]:t&&process.env[t]?process.env[t]:r}getStorageConfig(){let e="local";return typeof globalThis.STORAGE_BUCKET<"u"&&(e="cloudflare_r2"),{type:this.get("storage.type","STORAGE_TYPE",e),s3:{bucket:this.get("storage.s3.bucket","STORAGE_BUCKET"),region:this.get("storage.s3.region","STORAGE_REGION","us-east-1"),accessKeyId:this.get("storage.s3.access_key_id","STORAGE_ACCESS_KEY_ID"),secretAccessKey:this.get("storage.s3.secret_access_key","STORAGE_SECRET_ACCESS_KEY"),endpoint:this.get("storage.s3.endpoint","STORAGE_ENDPOINT"),cdnUrl:this.get("storage.s3.cdn_url","STORAGE_CDN_URL"),prefix:this.get("storage.s3.prefix","STORAGE_PREFIX")},r2:{accountId:this.get("storage.r2.account_id","R2_ACCOUNT_ID"),accessKeyId:this.get("storage.r2.access_key_id","R2_ACCESS_KEY_ID"),secretAccessKey:this.get("storage.r2.secret_access_key","R2_SECRET_ACCESS_KEY"),bucket:this.get("storage.r2.bucket","R2_BUCKET"),cdnUrl:this.get("storage.r2.cdn_url","R2_CDN_URL"),prefix:this.get("storage.r2.prefix","R2_PREFIX")},gcs:{bucket:this.get("storage.gcs.bucket","GCS_BUCKET"),projectId:this.get("storage.gcs.project_id","GCS_PROJECT_ID"),clientEmail:this.get("storage.gcs.client_email","GCS_CLIENT_EMAIL"),privateKey:this.get("storage.gcs.private_key","GCS_PRIVATE_KEY"),cdnUrl:this.get("storage.gcs.cdn_url","GCS_CDN_URL"),prefix:this.get("storage.gcs.prefix","GCS_PREFIX")},digitalocean:{bucket:this.get("storage.digitalocean.bucket","DO_BUCKET"),region:this.get("storage.digitalocean.region","DO_REGION","nyc3"),accessKeyId:this.get("storage.digitalocean.access_key_id","DO_ACCESS_KEY_ID"),secretAccessKey:this.get("storage.digitalocean.secret_access_key","DO_SECRET_ACCESS_KEY"),cdnUrl:this.get("storage.digitalocean.cdn_url","DO_CDN_URL"),prefix:this.get("storage.digitalocean.prefix","DO_PREFIX")},backblaze:{bucket:this.get("storage.backblaze.bucket","BB_BUCKET"),accountId:this.get("storage.backblaze.account_id","BB_ACCOUNT_ID"),applicationKeyId:this.get("storage.backblaze.application_key_id","BB_APPLICATION_KEY_ID"),applicationKey:this.get("storage.backblaze.application_key","BB_APPLICATION_KEY"),cdnUrl:this.get("storage.backblaze.cdn_url","BB_CDN_URL"),prefix:this.get("storage.backblaze.prefix","BB_PREFIX")},wasabi:{bucket:this.get("storage.wasabi.bucket","WASABI_BUCKET"),region:this.get("storage.wasabi.region","WASABI_REGION","us-east-1"),accessKeyId:this.get("storage.wasabi.access_key_id","WASABI_ACCESS_KEY_ID"),secretAccessKey:this.get("storage.wasabi.secret_access_key","WASABI_SECRET_ACCESS_KEY"),cdnUrl:this.get("storage.wasabi.cdn_url","WASABI_CDN_URL"),prefix:this.get("storage.wasabi.prefix","WASABI_PREFIX")},bunny:{storageZone:this.get("storage.bunny.storage_zone","BUNNY_STORAGE_ZONE"),apiKey:this.get("storage.bunny.api_key","BUNNY_API_KEY"),cdnUrl:this.get("storage.bunny.cdn_url","BUNNY_CDN_URL"),prefix:this.get("storage.bunny.prefix","BUNNY_PREFIX")},ftp:{host:this.get("storage.ftp.host","FTP_HOST"),port:parseInt(this.get("storage.ftp.port","FTP_PORT","21"),10),user:this.get("storage.ftp.user","FTP_USER"),password:this.get("storage.ftp.password","FTP_PASSWORD"),secure:this.get("storage.ftp.secure","FTP_SECURE")==="true",baseUrl:this.get("storage.ftp.base_url","FTP_BASE_URL"),prefix:this.get("storage.ftp.prefix","FTP_PREFIX")},cloudinary:{cloudName:this.get("storage.cloudinary.cloud_name","CLOUDINARY_CLOUD_NAME"),apiKey:this.get("storage.cloudinary.api_key","CLOUDINARY_API_KEY"),apiSecret:this.get("storage.cloudinary.api_secret","CLOUDINARY_API_SECRET"),folder:this.get("storage.cloudinary.folder","CLOUDINARY_FOLDER")},imgix:{domain:this.get("storage.imgix.domain","IMGIX_DOMAIN"),signKey:this.get("storage.imgix.sign_key","IMGIX_SIGN_KEY")},local:{uploadDir:this.get("storage.local.dir","STORAGE_LOCAL_DIR","./public/uploads"),baseUrl:this.get("storage.local.url","STORAGE_LOCAL_URL","/uploads")}}}getEmailConfig(){return {provider:this.get("email.provider","EMAIL_PROVIDER","smtp"),host:this.get("email.smtp.host","SMTP_HOST"),port:parseInt(this.get("email.smtp.port","SMTP_PORT","587"),10),secure:this.get("email.smtp.secure","SMTP_SECURE")==="true",user:this.get("email.smtp.user","SMTP_USER"),pass:this.get("email.smtp.pass","SMTP_PASS"),from:this.get("email.smtp.from","SMTP_FROM","noreply@example.com"),fromName:this.get("email.smtp.from_name","SMTP_FROM_NAME","Kyro CMS"),replyTo:this.get("email.smtp.reply_to","SMTP_REPLY_TO")}}maskSensitive(e,t){return t&&(i.SENSITIVE_KEYS.includes(e)?"********":t)}async set(e,t,r){await this.db.insert(chunkHPYH7GTS_cjs.a).values({key:e,value:t,description:r,updatedAt:new Date}).onConflictDoUpdate({target:[chunkHPYH7GTS_cjs.a.key],set:{value:t,description:r,updatedAt:new Date}}),this.cache[e]=t;}};chunkBUNLC3II_cjs.h();var M=class i{transporter;config;templates;transporterInitialized=false;constructor(e,t){this.config=e,this.templates={...L(e.brand),...t};}async ensureTransporter(){if(this.transporterInitialized)return this.transporter;let{default:e}=await import('./nodemailer-IDML4L6W.cjs');return this.config.provider==="smtp"&&this.config.smtp?this.transporter=e.createTransport({host:this.config.smtp.host,port:this.config.smtp.port,secure:this.config.smtp.secure,auth:this.config.smtp.auth}):this.config.provider==="ses"&&this.config.ses&&(this.transporter=e.createTransport({host:`email-smtp.${this.config.ses.region}.amazonaws.com`,port:587,secure:false,auth:{user:this.config.ses.accessKeyId,pass:this.config.ses.secretAccessKey}})),this.transporterInitialized=true,this.transporter}async send(e){let{provider:t,from:r,fromName:s,replyTo:o}=this.config,a=`"${s||"Kyro CMS"}" <${r}>`,n=e.replyTo||o;try{let c;switch(t){case "smtp":case "ses":{let d=await this.ensureTransporter();if(!d)throw new Error(`${t} transporter not initialized`);c=await d.sendMail({from:a,to:Array.isArray(e.to)?e.to.join(", "):e.to,subject:e.subject,html:e.html,text:e.text,replyTo:n});}break;case "resend":c=await this.sendViaResend(a,e,n);break;case "sendgrid":c=await this.sendViaSendGrid(a,e,n);break;case "mailgun":c=await this.sendViaMailgun(a,e,n);break;default:throw new Error(`Unsupported email provider: ${t}`)}return c}catch(c){throw console.error("[EmailTransport] FAILED to send email:",c.message),c.response&&console.error("[EmailTransport] Provider Error Detail:",JSON.stringify(c.response,null,2)),c}}async sendViaResend(e,t,r){let s=this.config.resend?.apiKey;if(!s)throw new Error("Resend API Key missing");let o={from:e,to:t.to,subject:t.subject,html:t.html,text:t.text,reply_to:r},a=await fetch("https://api.resend.com/emails",{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json"},body:JSON.stringify(o)});if(!a.ok){let n=await a.json();throw new Error(`Resend Error: ${JSON.stringify(n)}`)}return a.json()}async sendViaSendGrid(e,t,r){let s=this.config.sendgrid?.apiKey;if(!s)throw new Error("SendGrid API Key missing");let o={personalizations:[{to:Array.isArray(t.to)?t.to.map(n=>({email:n})):[{email:t.to}]}],from:{email:e.match(/<(.+)>/)?.[1]||e,name:e.match(/"(.+)"/)?.[1]},subject:t.subject,content:[{type:"text/plain",value:t.text||""},{type:"text/html",value:t.html}],reply_to:r?{email:r}:void 0},a=await fetch("https://api.sendgrid.com/v3/mail/send",{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json"},body:JSON.stringify(o)});if(!a.ok){let n=await a.json();throw new Error(`SendGrid Error: ${JSON.stringify(n)}`)}return {success:true}}async sendViaMailgun(e,t,r){let{apiKey:s,domain:o,region:a}=this.config.mailgun||{};if(!s||!o)throw new Error("Mailgun config missing");let n=a==="eu"?"api.eu.mailgun.net":"api.mailgun.net",c=btoa(`api:${s}`),d=new URLSearchParams;d.append("from",e);let f=Array.isArray(t.to)?t.to.join(", "):t.to;d.append("to",f),d.append("subject",t.subject),d.append("html",t.html),t.text&&d.append("text",t.text),r&&d.append("h:Reply-To",r);let m=await fetch(`https://${n}/v3/${o}/messages`,{method:"POST",headers:{Authorization:`Basic ${c}`,"Content-Type":"application/x-www-form-urlencoded"},body:d});if(!m.ok){let u=await m.json();throw new Error(`Mailgun Error: ${JSON.stringify(u)}`)}return m.json()}getTemplates(){return this.templates}async verifyConnection(){if(this.config.provider==="smtp"||this.config.provider==="ses")try{let e=await this.ensureTransporter();if(e)return await e.verify(),!0}catch{return false}return !!(this.config.resend?.apiKey||this.config.sendgrid?.apiKey||this.config.mailgun?.apiKey)}static async fetchBrandConfig(e){let t="Kyro CMS",r="https://kyro-cms.com/logo.svg",s="https://kyro-cms.com/logo-white.svg";try{let o=null,a=null;if(typeof e?.findOne=="function")o=await e.findOne({collection:"_globals_store-settings",where:{},draft:!0}),a=await e.findOne({collection:"_globals_brand-settings",where:{},draft:!0});else if(typeof e?.execute=="function"){let{sql:n}=await import('./drizzle-orm-47ELDEM6.cjs');try{let c=await e.execute(n`SELECT * FROM "_globals_store-settings" LIMIT 1`);o=Array.isArray(c)?c[0]:c?.rows?c.rows[0]:null;}catch{}try{let c=await e.execute(n`SELECT * FROM "_globals_brand-settings" LIMIT 1`);a=Array.isArray(c)?c[0]:c?.rows?c.rows[0]:null;}catch{}}else if(typeof e?.prepare=="function"){try{o=e.prepare('SELECT * FROM "_globals_store-settings" LIMIT 1').get();}catch{}try{a=e.prepare('SELECT * FROM "_globals_brand-settings" LIMIT 1').get();}catch{}}if(o?.storeName&&(t=o.storeName),a?.identity){let n=typeof a.identity=="string"?JSON.parse(a.identity):a.identity,c=async d=>{if(typeof e?.findOne=="function")return (await e.findOne({collection:"media",where:{id:{equals:d}}}))?.url;if(typeof e?.execute=="function"){let{sql:f}=await import('./drizzle-orm-47ELDEM6.cjs');try{let m=await e.execute(f`SELECT url FROM "media" WHERE id = ${d}`);return (Array.isArray(m)?m[0]:m?.rows?m.rows[0]:null)?.url}catch{}}else if(typeof e?.prepare=="function")try{return e.prepare('SELECT url FROM "media" WHERE id = ?').get(d)?.url}catch{}};if(n.primaryLogo){let d=await c(n.primaryLogo);d&&(r=d);}if(n.darkLogo){let d=await c(n.darkLogo);d&&(s=d);}}}catch{}return {siteName:t,logoUrl:r,logoDarkUrl:s,appUrl:process.env.PUBLIC_URL||"https://kyro-cms.com"}}static async fromConfig(e){let t=new w(e);await t.load();let r=t.getEmailConfig();if(!r.provider)return this.fromEnv();let o={brand:await this.fetchBrandConfig(e),provider:r.provider||"smtp",from:r.from||"noreply@example.com",fromName:r.fromName,replyTo:r.replyTo,smtp:r.provider==="smtp"?{host:r.host||"",port:r.port||587,secure:r.secure||false,auth:{user:r.user||"",pass:r.pass||""}}:void 0,resend:r.provider==="resend"?{apiKey:r.pass||""}:void 0,sendgrid:r.provider==="sendgrid"?{apiKey:r.pass||""}:void 0,mailgun:r.provider==="mailgun"?{apiKey:r.pass||"",domain:r.host||"",region:r.secure?"eu":"us"}:void 0,ses:r.provider==="ses"?{accessKeyId:r.user||"",secretAccessKey:r.pass||"",region:r.host||"us-east-1"}:void 0};return new i(o)}static fromEnv(){let e=process.env.EMAIL_PROVIDER||"smtp",t=process.env.SMTP_FROM||process.env.DEFAULT_FROM||"noreply@example.com",r=process.env.SMTP_FROM_NAME||"Kyro CMS",s=process.env.SMTP_REPLY_TO;if(e==="smtp"){let o=process.env.SMTP_HOST,a=process.env.SMTP_USER,n=process.env.SMTP_PASS;return !o||!a||!n?null:new i({provider:"smtp",from:t,fromName:r,replyTo:s,smtp:{host:o,port:parseInt(process.env.SMTP_PORT||"587",10),secure:process.env.SMTP_SECURE==="true",auth:{user:a,pass:n}}})}if(e==="resend"){let o=process.env.RESEND_API_KEY||process.env.SMTP_PASS;return o?new i({provider:"resend",from:t,fromName:r,replyTo:s,resend:{apiKey:o}}):null}if(e==="sendgrid"){let o=process.env.SENDGRID_API_KEY||process.env.SMTP_PASS;return o?new i({provider:"sendgrid",from:t,fromName:r,replyTo:s,sendgrid:{apiKey:o}}):null}if(e==="mailgun"){let o=process.env.MAILGUN_API_KEY||process.env.SMTP_PASS,a=process.env.MAILGUN_DOMAIN||process.env.SMTP_HOST;return !o||!a?null:new i({provider:"mailgun",from:t,fromName:r,replyTo:s,mailgun:{apiKey:o,domain:a,region:process.env.MAILGUN_REGION||(process.env.SMTP_SECURE==="true"?"eu":"us")}})}if(e==="ses"){let o=process.env.AWS_ACCESS_KEY_ID||process.env.SMTP_USER,a=process.env.AWS_SECRET_ACCESS_KEY||process.env.SMTP_PASS,n=process.env.AWS_REGION||process.env.SMTP_HOST||"us-east-1";return !o||!a?null:new i({provider:"ses",from:t,fromName:r,replyTo:s,ses:{accessKeyId:o,secretAccessKey:a,region:n}})}return null}};chunkBUNLC3II_cjs.h();var D={minLength:12,requireUppercase:true,requireLowercase:true,requireNumbers:true,requireSpecialChars:true,preventReuse:5,maxLength:128},U=class{config;constructor(e={}){this.config={...D,...e};}validate(e){let t=[];return this.config.maxLength&&e.length>this.config.maxLength&&t.push(`Password must not exceed ${this.config.maxLength} characters`),e.length<this.config.minLength&&t.push(`Password must be at least ${this.config.minLength} characters`),this.config.requireUppercase&&!/[A-Z]/.test(e)&&t.push("Password must contain at least one uppercase letter"),this.config.requireLowercase&&!/[a-z]/.test(e)&&t.push("Password must contain at least one lowercase letter"),this.config.requireNumbers&&!/[0-9]/.test(e)&&t.push("Password must contain at least one number"),this.config.requireSpecialChars&&!/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(e)&&t.push("Password must contain at least one special character"),["password","123456","12345678","qwerty","abc123","monkey","1234567","letmein","trustno1","dragon","baseball","iloveyou","master","sunshine","ashley","football","password1","shadow","123123","654321"].includes(e.toLowerCase())&&t.push("This password is too common. Please choose a more secure password"),(/^[a-zA-Z]+$/.test(e)||/^[0-9]+$/.test(e))&&t.push("Password must contain a mix of letters, numbers, and/or special characters"),/(.)\1{2,}/.test(e)&&t.push("Password must not contain more than 2 consecutive identical characters"),/^(012|123|234|345|456|567|678|789|890|098|987|876|765|654|543|432|321|210)+$/i.test(e)&&t.push("Password must not contain sequential numbers or letters"),{valid:t.length===0,errors:t}}async checkReuse(e,t,r){return {valid:true,errors:[]}}async isInHistory(e,t,r){for(let s of t)if(await r(e,s))return true;return false}generatePassword(e=16){let t="ABCDEFGHIJKLMNOPQRSTUVWXYZ",r="abcdefghijklmnopqrstuvwxyz",s="0123456789",o="!@#$%^&*()_+-=[]{}|;:,.<>?",a="";a+=t[Math.floor(Math.random()*t.length)],a+=r[Math.floor(Math.random()*r.length)],a+=s[Math.floor(Math.random()*s.length)],a+=o[Math.floor(Math.random()*o.length)];let n=t+r+s+o;for(let c=a.length;c<e;c++)a+=n[Math.floor(Math.random()*n.length)];return a.split("").sort(()=>Math.random()-.5).join("")}getStrength(e){let t=0,r=[];e.length>=8&&(t+=1),e.length>=12&&(t+=1),e.length>=16&&(t+=1),/[a-z]/.test(e)&&(t+=1),/[A-Z]/.test(e)&&(t+=1),/[0-9]/.test(e)&&(t+=1),/[!@#$%^&*()_+\-=\[\]{}|;:,.<>?]/.test(e)&&(t+=1),e.length>8&&(t+=1),e.length>12&&(t+=1);let s=new Set(e).size;s>6&&(t+=1),s>10&&(t+=1);let o;return t<=3?(o="Weak",r.push("Add more characters"),r.push("Include uppercase and lowercase letters")):t<=5?(o="Fair",r.push("Add special characters"),r.push("Consider making it longer")):t<=7?(o="Good",r.push("Consider making it longer for extra security")):o="Strong",{score:t,label:o,feedback:r}}setConfig(e){this.config={...this.config,...e};}getConfig(){return {...this.config}}};
419
- exports.a=g;exports.b=_;exports.c=T;exports.d=S;exports.e=C;exports.f=k;exports.g=E;exports.h=v;exports.i=A;exports.j=R;exports.k=P;exports.l=I;exports.m=O;exports.n=K;exports.o=L;exports.p=w;exports.q=M;exports.r=U;
430
+ `),O=!0);}catch{}}async loadFromGlobals(){try{let e=null;if(typeof this.db?.findOne=="function")try{let s=await this.db.findOne({collection:"_globals_storage-settings",where:{},draft:!0});s&&(e=s);}catch{}if(!e&&typeof this.db?.execute=="function"){let{sql:s}=await import('./drizzle-orm-47ELDEM6.cjs'),o=['"_globals_storage-settings"','"_globals_storage_settings"','"global_storage_settings"'];for(let n of o)try{let a=await this.db.execute(s`SELECT * FROM ${s.raw(n)} LIMIT 1`);if(e=Array.isArray(a)?a[0]:a?.rows?a.rows[0]:null,e)break}catch{}}else if(!e&&typeof this.db?.prepare=="function"){let s=['"_globals_storage-settings"','"_globals_storage_settings"','"global_storage_settings"'];for(let o of s)try{if(e=this.db.prepare(`SELECT * FROM ${o} LIMIT 1`).get(),e)break}catch{}}if(!e)return;let t=s=>{if(!s)return null;if(typeof s=="string")try{return JSON.parse(s)}catch{return null}return s},r=e.provider||"local";if(this.cache["storage.type"]=r,r==="local"){let s=t(e.local);this.cache["storage.local.dir"]=s?.uploadDir||"./public/uploads",this.cache["storage.local.url"]=s?.baseUrl||"/uploads";}if(r==="aws"){let s=t(e.aws);this.cache["storage.s3.bucket"]=s?.bucket||"",this.cache["storage.s3.region"]=s?.region||"us-east-1",this.cache["storage.s3.access_key_id"]=s?.accessKeyId||"",this.cache["storage.s3.secret_access_key"]=s?.secretAccessKey||"",this.cache["storage.s3.endpoint"]=s?.endpoint||"",this.cache["storage.s3.cdn_url"]=s?.cdnUrl||"",this.cache["storage.s3.prefix"]=s?.prefix||"";}if(r==="r2"){let s=t(e.r2);this.cache["storage.r2.account_id"]=s?.accountId||"",this.cache["storage.r2.access_key_id"]=s?.accessKeyId||"",this.cache["storage.r2.secret_access_key"]=s?.secretAccessKey||"",this.cache["storage.r2.bucket"]=s?.bucket||"",this.cache["storage.r2.cdn_url"]=s?.cdnUrl||"",this.cache["storage.r2.prefix"]=s?.prefix||"";}if(r==="cloudinary"){let s=t(e.cloudinary);this.cache["storage.cloudinary.cloud_name"]=s?.cloudName||"",this.cache["storage.cloudinary.api_key"]=s?.apiKey||"",this.cache["storage.cloudinary.api_secret"]=s?.apiSecret||"",this.cache["storage.cloudinary.folder"]=s?.folder||"";}if(r==="ftp"){let s=t(e.ftp);this.cache["storage.ftp.host"]=s?.host||"",this.cache["storage.ftp.port"]=String(s?.port||"21"),this.cache["storage.ftp.user"]=s?.user||"",this.cache["storage.ftp.password"]=s?.password||"",this.cache["storage.ftp.secure"]=s?.secure?"true":"false",this.cache["storage.ftp.base_url"]=s?.baseUrl||"",this.cache["storage.ftp.prefix"]=s?.prefix||"";}}catch(e){console.warn("ConfigService: Could not load storage settings from globals table:",e);}try{let e=null;if(typeof this.db?.findOne=="function")try{let t=await this.db.findOne({collection:"_globals_email-settings",where:{},draft:!0});t&&(e=t);}catch{}if(!e&&typeof this.db?.execute=="function"){let{sql:t}=await import('./drizzle-orm-47ELDEM6.cjs'),r=['"_globals_email-settings"','"_globals_email_settings"','"global_email_settings"'];for(let s of r)try{let o=await this.db.execute(t`SELECT * FROM ${t.raw(s)} LIMIT 1`);if(e=Array.isArray(o)?o[0]:o?.rows?o.rows[0]:null,e)break}catch{}}else if(!e&&typeof this.db?.prepare=="function"){let t=['"_globals_email-settings"','"_globals_email_settings"','"global_email_settings"'];for(let r of t)try{if(e=this.db.prepare(`SELECT * FROM ${r} LIMIT 1`).get(),e)break}catch{}}if(e){let t=r=>{if(!r)return null;if(typeof r=="string")try{return JSON.parse(r)}catch{return null}return r};if(this.cache["email.provider"]=e.provider||"smtp",this.cache["email.smtp.from"]=e.fromEmail||"",this.cache["email.smtp.from_name"]=e.fromName||"",this.cache["email.smtp.reply_to"]=e.replyTo||"",e.provider==="smtp"){let r=t(e.smtp);this.cache["email.smtp.host"]=r?.host||"",this.cache["email.smtp.port"]=String(r?.port||"587"),this.cache["email.smtp.user"]=r?.username||"",this.cache["email.smtp.pass"]=r?.password||"",this.cache["email.smtp.secure"]=r?.secure?"true":"false";}else if(e.provider==="resend"){let r=t(e.resend);this.cache["email.smtp.pass"]=r?.apiKey||"";}else if(e.provider==="sendgrid"){let r=t(e.sendgrid);this.cache["email.smtp.pass"]=r?.apiKey||"";}else if(e.provider==="mailgun"){let r=t(e.mailgun);this.cache["email.smtp.pass"]=r?.apiKey||"";}else if(e.provider==="ses"){let r=t(e.ses);this.cache["email.smtp.user"]=r?.accessKeyId||"",this.cache["email.smtp.pass"]=r?.secretAccessKey||"";}}}catch(e){console.warn("ConfigService: Could not load email settings from globals table:",e);}}get(e,t,r){return this.cache[e]?this.cache[e]:t&&process.env[t]?process.env[t]:r}getStorageConfig(){let e="local";return typeof globalThis.STORAGE_BUCKET<"u"&&(e="cloudflare_r2"),{type:this.get("storage.type","STORAGE_TYPE",e),s3:{bucket:this.get("storage.s3.bucket","STORAGE_BUCKET"),region:this.get("storage.s3.region","STORAGE_REGION","us-east-1"),accessKeyId:this.get("storage.s3.access_key_id","STORAGE_ACCESS_KEY_ID"),secretAccessKey:this.get("storage.s3.secret_access_key","STORAGE_SECRET_ACCESS_KEY"),endpoint:this.get("storage.s3.endpoint","STORAGE_ENDPOINT"),cdnUrl:this.get("storage.s3.cdn_url","STORAGE_CDN_URL"),prefix:this.get("storage.s3.prefix","STORAGE_PREFIX")},r2:{accountId:this.get("storage.r2.account_id","R2_ACCOUNT_ID"),accessKeyId:this.get("storage.r2.access_key_id","R2_ACCESS_KEY_ID"),secretAccessKey:this.get("storage.r2.secret_access_key","R2_SECRET_ACCESS_KEY"),bucket:this.get("storage.r2.bucket","R2_BUCKET"),cdnUrl:this.get("storage.r2.cdn_url","R2_CDN_URL"),prefix:this.get("storage.r2.prefix","R2_PREFIX")},gcs:{bucket:this.get("storage.gcs.bucket","GCS_BUCKET"),projectId:this.get("storage.gcs.project_id","GCS_PROJECT_ID"),clientEmail:this.get("storage.gcs.client_email","GCS_CLIENT_EMAIL"),privateKey:this.get("storage.gcs.private_key","GCS_PRIVATE_KEY"),cdnUrl:this.get("storage.gcs.cdn_url","GCS_CDN_URL"),prefix:this.get("storage.gcs.prefix","GCS_PREFIX")},digitalocean:{bucket:this.get("storage.digitalocean.bucket","DO_BUCKET"),region:this.get("storage.digitalocean.region","DO_REGION","nyc3"),accessKeyId:this.get("storage.digitalocean.access_key_id","DO_ACCESS_KEY_ID"),secretAccessKey:this.get("storage.digitalocean.secret_access_key","DO_SECRET_ACCESS_KEY"),cdnUrl:this.get("storage.digitalocean.cdn_url","DO_CDN_URL"),prefix:this.get("storage.digitalocean.prefix","DO_PREFIX")},backblaze:{bucket:this.get("storage.backblaze.bucket","BB_BUCKET"),accountId:this.get("storage.backblaze.account_id","BB_ACCOUNT_ID"),applicationKeyId:this.get("storage.backblaze.application_key_id","BB_APPLICATION_KEY_ID"),applicationKey:this.get("storage.backblaze.application_key","BB_APPLICATION_KEY"),cdnUrl:this.get("storage.backblaze.cdn_url","BB_CDN_URL"),prefix:this.get("storage.backblaze.prefix","BB_PREFIX")},wasabi:{bucket:this.get("storage.wasabi.bucket","WASABI_BUCKET"),region:this.get("storage.wasabi.region","WASABI_REGION","us-east-1"),accessKeyId:this.get("storage.wasabi.access_key_id","WASABI_ACCESS_KEY_ID"),secretAccessKey:this.get("storage.wasabi.secret_access_key","WASABI_SECRET_ACCESS_KEY"),cdnUrl:this.get("storage.wasabi.cdn_url","WASABI_CDN_URL"),prefix:this.get("storage.wasabi.prefix","WASABI_PREFIX")},bunny:{storageZone:this.get("storage.bunny.storage_zone","BUNNY_STORAGE_ZONE"),apiKey:this.get("storage.bunny.api_key","BUNNY_API_KEY"),cdnUrl:this.get("storage.bunny.cdn_url","BUNNY_CDN_URL"),prefix:this.get("storage.bunny.prefix","BUNNY_PREFIX")},ftp:{host:this.get("storage.ftp.host","FTP_HOST"),port:parseInt(this.get("storage.ftp.port","FTP_PORT","21"),10),user:this.get("storage.ftp.user","FTP_USER"),password:this.get("storage.ftp.password","FTP_PASSWORD"),secure:this.get("storage.ftp.secure","FTP_SECURE")==="true",baseUrl:this.get("storage.ftp.base_url","FTP_BASE_URL"),prefix:this.get("storage.ftp.prefix","FTP_PREFIX")},cloudinary:{cloudName:this.get("storage.cloudinary.cloud_name","CLOUDINARY_CLOUD_NAME"),apiKey:this.get("storage.cloudinary.api_key","CLOUDINARY_API_KEY"),apiSecret:this.get("storage.cloudinary.api_secret","CLOUDINARY_API_SECRET"),folder:this.get("storage.cloudinary.folder","CLOUDINARY_FOLDER")},imgix:{domain:this.get("storage.imgix.domain","IMGIX_DOMAIN"),signKey:this.get("storage.imgix.sign_key","IMGIX_SIGN_KEY")},local:{uploadDir:this.get("storage.local.dir","STORAGE_LOCAL_DIR","./public/uploads"),baseUrl:this.get("storage.local.url","STORAGE_LOCAL_URL","/uploads")}}}getEmailConfig(){return {provider:this.get("email.provider","EMAIL_PROVIDER","smtp"),host:this.get("email.smtp.host","SMTP_HOST"),port:parseInt(this.get("email.smtp.port","SMTP_PORT","587"),10),secure:this.get("email.smtp.secure","SMTP_SECURE")==="true",user:this.get("email.smtp.user","SMTP_USER"),pass:this.get("email.smtp.pass","SMTP_PASS"),from:this.get("email.smtp.from","SMTP_FROM","noreply@example.com"),fromName:this.get("email.smtp.from_name","SMTP_FROM_NAME","Kyro CMS"),replyTo:this.get("email.smtp.reply_to","SMTP_REPLY_TO")}}maskSensitive(e,t){return t&&(i.SENSITIVE_KEYS.includes(e)?"********":t)}async set(e,t,r){await this.db.insert(chunkHPYH7GTS_cjs.a).values({key:e,value:t,description:r,updatedAt:new Date}).onConflictDoUpdate({target:[chunkHPYH7GTS_cjs.a.key],set:{value:t,description:r,updatedAt:new Date}}),this.cache[e]=t;}};chunkBUNLC3II_cjs.h();var $=class i{transporter;config;templates;transporterInitialized=false;constructor(e,t){this.config=e,this.templates={...I(e.brand),...t};}async ensureTransporter(){if(this.transporterInitialized)return this.transporter;let{default:e}=await import('./nodemailer-IDML4L6W.cjs');return this.config.provider==="smtp"&&this.config.smtp?this.transporter=e.createTransport({host:this.config.smtp.host,port:this.config.smtp.port,secure:this.config.smtp.secure,auth:this.config.smtp.auth}):this.config.provider==="ses"&&this.config.ses&&(this.transporter=e.createTransport({host:`email-smtp.${this.config.ses.region}.amazonaws.com`,port:587,secure:false,auth:{user:this.config.ses.accessKeyId,pass:this.config.ses.secretAccessKey}})),this.transporterInitialized=true,this.transporter}async send(e){let{provider:t,from:r,fromName:s,replyTo:o}=this.config,n=`"${s||"Kyro CMS"}" <${r}>`,a=e.replyTo||o;try{let l;switch(t){case "smtp":case "ses":{let p=await this.ensureTransporter();if(!p)throw new Error(`${t} transporter not initialized`);l=await p.sendMail({from:n,to:Array.isArray(e.to)?e.to.join(", "):e.to,subject:e.subject,html:e.html,text:e.text,replyTo:a});}break;case "resend":l=await this.sendViaResend(n,e,a);break;case "sendgrid":l=await this.sendViaSendGrid(n,e,a);break;case "mailgun":l=await this.sendViaMailgun(n,e,a);break;default:throw new Error(`Unsupported email provider: ${t}`)}return l}catch(l){throw console.error("[EmailTransport] FAILED to send email:",l.message),l.response&&console.error("[EmailTransport] Provider Error Detail:",JSON.stringify(l.response,null,2)),l}}async sendViaResend(e,t,r){let s=this.config.resend?.apiKey;if(!s)throw new Error("Resend API Key missing");let o={from:e,to:t.to,subject:t.subject,html:t.html,text:t.text,reply_to:r},n=await fetch("https://api.resend.com/emails",{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json"},body:JSON.stringify(o)});if(!n.ok){let a=await n.json();throw new Error(`Resend Error: ${JSON.stringify(a)}`)}return n.json()}async sendViaSendGrid(e,t,r){let s=this.config.sendgrid?.apiKey;if(!s)throw new Error("SendGrid API Key missing");let o={personalizations:[{to:Array.isArray(t.to)?t.to.map(a=>({email:a})):[{email:t.to}]}],from:{email:e.match(/<(.+)>/)?.[1]||e,name:e.match(/"(.+)"/)?.[1]},subject:t.subject,content:[{type:"text/plain",value:t.text||""},{type:"text/html",value:t.html}],reply_to:r?{email:r}:void 0},n=await fetch("https://api.sendgrid.com/v3/mail/send",{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json"},body:JSON.stringify(o)});if(!n.ok){let a=await n.json();throw new Error(`SendGrid Error: ${JSON.stringify(a)}`)}return {success:true}}async sendViaMailgun(e,t,r){let{apiKey:s,domain:o,region:n}=this.config.mailgun||{};if(!s||!o)throw new Error("Mailgun config missing");let a=n==="eu"?"api.eu.mailgun.net":"api.mailgun.net",l=btoa(`api:${s}`),p=new URLSearchParams;p.append("from",e);let f=Array.isArray(t.to)?t.to.join(", "):t.to;p.append("to",f),p.append("subject",t.subject),p.append("html",t.html),t.text&&p.append("text",t.text),r&&p.append("h:Reply-To",r);let m=await fetch(`https://${a}/v3/${o}/messages`,{method:"POST",headers:{Authorization:`Basic ${l}`,"Content-Type":"application/x-www-form-urlencoded"},body:p});if(!m.ok){let u=await m.json();throw new Error(`Mailgun Error: ${JSON.stringify(u)}`)}return m.json()}getTemplates(){return this.templates}async verifyConnection(){if(this.config.provider==="smtp"||this.config.provider==="ses")try{let e=await this.ensureTransporter();if(e)return await e.verify(),!0}catch{return false}return !!(this.config.resend?.apiKey||this.config.sendgrid?.apiKey||this.config.mailgun?.apiKey)}static async fetchBrandConfig(e){let t="Kyro CMS",r="https://kyro-cms.com/logo.svg",s="https://kyro-cms.com/logo-white.svg";try{let o=null,n=null;if(typeof e?.findOne=="function")o=await e.findOne({collection:"_globals_store-settings",where:{},draft:!0}),n=await e.findOne({collection:"_globals_brand-settings",where:{},draft:!0});else if(typeof e?.execute=="function"){let{sql:a}=await import('./drizzle-orm-47ELDEM6.cjs');try{let l=await e.execute(a`SELECT * FROM "_globals_store-settings" LIMIT 1`);o=Array.isArray(l)?l[0]:l?.rows?l.rows[0]:null;}catch{}try{let l=await e.execute(a`SELECT * FROM "_globals_brand-settings" LIMIT 1`);n=Array.isArray(l)?l[0]:l?.rows?l.rows[0]:null;}catch{}}else if(typeof e?.prepare=="function"){try{o=e.prepare('SELECT * FROM "_globals_store-settings" LIMIT 1').get();}catch{}try{n=e.prepare('SELECT * FROM "_globals_brand-settings" LIMIT 1').get();}catch{}}if(o?.storeName&&(t=o.storeName),n?.identity){let a=typeof n.identity=="string"?JSON.parse(n.identity):n.identity,l=async p=>{if(typeof e?.findOne=="function")return (await e.findOne({collection:"media",where:{id:{equals:p}}}))?.url;if(typeof e?.execute=="function"){let{sql:f}=await import('./drizzle-orm-47ELDEM6.cjs');try{let m=await e.execute(f`SELECT url FROM "media" WHERE id = ${p}`);return (Array.isArray(m)?m[0]:m?.rows?m.rows[0]:null)?.url}catch{}}else if(typeof e?.prepare=="function")try{return e.prepare('SELECT url FROM "media" WHERE id = ?').get(p)?.url}catch{}};if(a.primaryLogo){let p=await l(a.primaryLogo);p&&(r=p);}if(a.darkLogo){let p=await l(a.darkLogo);p&&(s=p);}}}catch{}return {siteName:t,logoUrl:r,logoDarkUrl:s,appUrl:process.env.PUBLIC_URL||"https://kyro-cms.com"}}static async fromConfig(e){let t=new y(e);await t.load();let r=t.getEmailConfig();if(!r.provider)return this.fromEnv();let o={brand:await this.fetchBrandConfig(e),provider:r.provider||"smtp",from:r.from||"noreply@example.com",fromName:r.fromName,replyTo:r.replyTo,smtp:r.provider==="smtp"?{host:r.host||"",port:r.port||587,secure:r.secure||false,auth:{user:r.user||"",pass:r.pass||""}}:void 0,resend:r.provider==="resend"?{apiKey:r.pass||""}:void 0,sendgrid:r.provider==="sendgrid"?{apiKey:r.pass||""}:void 0,mailgun:r.provider==="mailgun"?{apiKey:r.pass||"",domain:r.host||"",region:r.secure?"eu":"us"}:void 0,ses:r.provider==="ses"?{accessKeyId:r.user||"",secretAccessKey:r.pass||"",region:r.host||"us-east-1"}:void 0};return new i(o)}static fromEnv(){let e=process.env.EMAIL_PROVIDER||"smtp",t=process.env.SMTP_FROM||process.env.DEFAULT_FROM||"noreply@example.com",r=process.env.SMTP_FROM_NAME||"Kyro CMS",s=process.env.SMTP_REPLY_TO;if(e==="smtp"){let o=process.env.SMTP_HOST,n=process.env.SMTP_USER,a=process.env.SMTP_PASS;return !o||!n||!a?null:new i({provider:"smtp",from:t,fromName:r,replyTo:s,smtp:{host:o,port:parseInt(process.env.SMTP_PORT||"587",10),secure:process.env.SMTP_SECURE==="true",auth:{user:n,pass:a}}})}if(e==="resend"){let o=process.env.RESEND_API_KEY||process.env.SMTP_PASS;return o?new i({provider:"resend",from:t,fromName:r,replyTo:s,resend:{apiKey:o}}):null}if(e==="sendgrid"){let o=process.env.SENDGRID_API_KEY||process.env.SMTP_PASS;return o?new i({provider:"sendgrid",from:t,fromName:r,replyTo:s,sendgrid:{apiKey:o}}):null}if(e==="mailgun"){let o=process.env.MAILGUN_API_KEY||process.env.SMTP_PASS,n=process.env.MAILGUN_DOMAIN||process.env.SMTP_HOST;return !o||!n?null:new i({provider:"mailgun",from:t,fromName:r,replyTo:s,mailgun:{apiKey:o,domain:n,region:process.env.MAILGUN_REGION||(process.env.SMTP_SECURE==="true"?"eu":"us")}})}if(e==="ses"){let o=process.env.AWS_ACCESS_KEY_ID||process.env.SMTP_USER,n=process.env.AWS_SECRET_ACCESS_KEY||process.env.SMTP_PASS,a=process.env.AWS_REGION||process.env.SMTP_HOST||"us-east-1";return !o||!n?null:new i({provider:"ses",from:t,fromName:r,replyTo:s,ses:{accessKeyId:o,secretAccessKey:n,region:a}})}return null}};chunkBUNLC3II_cjs.h();var M={minLength:12,requireUppercase:true,requireLowercase:true,requireNumbers:true,requireSpecialChars:true,preventReuse:5,maxLength:128},K=class{config;constructor(e={}){this.config={...M,...e};}validate(e){let t=[];return this.config.maxLength&&e.length>this.config.maxLength&&t.push(`Password must not exceed ${this.config.maxLength} characters`),e.length<this.config.minLength&&t.push(`Password must be at least ${this.config.minLength} characters`),this.config.requireUppercase&&!/[A-Z]/.test(e)&&t.push("Password must contain at least one uppercase letter"),this.config.requireLowercase&&!/[a-z]/.test(e)&&t.push("Password must contain at least one lowercase letter"),this.config.requireNumbers&&!/[0-9]/.test(e)&&t.push("Password must contain at least one number"),this.config.requireSpecialChars&&!/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(e)&&t.push("Password must contain at least one special character"),["password","123456","12345678","qwerty","abc123","monkey","1234567","letmein","trustno1","dragon","baseball","iloveyou","master","sunshine","ashley","football","password1","shadow","123123","654321"].includes(e.toLowerCase())&&t.push("This password is too common. Please choose a more secure password"),(/^[a-zA-Z]+$/.test(e)||/^[0-9]+$/.test(e))&&t.push("Password must contain a mix of letters, numbers, and/or special characters"),/(.)\1{2,}/.test(e)&&t.push("Password must not contain more than 2 consecutive identical characters"),/^(012|123|234|345|456|567|678|789|890|098|987|876|765|654|543|432|321|210)+$/i.test(e)&&t.push("Password must not contain sequential numbers or letters"),{valid:t.length===0,errors:t}}async checkReuse(e,t,r){return {valid:true,errors:[]}}async isInHistory(e,t,r){for(let s of t)if(await r(e,s))return true;return false}generatePassword(e=16){let t="ABCDEFGHIJKLMNOPQRSTUVWXYZ",r="abcdefghijklmnopqrstuvwxyz",s="0123456789",o="!@#$%^&*()_+-=[]{}|;:,.<>?",n="";n+=t[Math.floor(Math.random()*t.length)],n+=r[Math.floor(Math.random()*r.length)],n+=s[Math.floor(Math.random()*s.length)],n+=o[Math.floor(Math.random()*o.length)];let a=t+r+s+o;for(let l=n.length;l<e;l++)n+=a[Math.floor(Math.random()*a.length)];return n.split("").sort(()=>Math.random()-.5).join("")}getStrength(e){let t=0,r=[];e.length>=8&&(t+=1),e.length>=12&&(t+=1),e.length>=16&&(t+=1),/[a-z]/.test(e)&&(t+=1),/[A-Z]/.test(e)&&(t+=1),/[0-9]/.test(e)&&(t+=1),/[!@#$%^&*()_+\-=\[\]{}|;:,.<>?]/.test(e)&&(t+=1),e.length>8&&(t+=1),e.length>12&&(t+=1);let s=new Set(e).size;s>6&&(t+=1),s>10&&(t+=1);let o;return t<=3?(o="Weak",r.push("Add more characters"),r.push("Include uppercase and lowercase letters")):t<=5?(o="Fair",r.push("Add special characters"),r.push("Consider making it longer")):t<=7?(o="Good",r.push("Consider making it longer for extra security")):o="Strong",{score:t,label:o,feedback:r}}setConfig(e){this.config={...this.config,...e};}getConfig(){return {...this.config}}};
431
+ exports.a=g;exports.b=b;exports.c=x;exports.d=w;exports.e=_;exports.f=C;exports.g=S;exports.h=T;exports.i=k;exports.j=E;exports.k=v;exports.l=A;exports.m=P;exports.n=R;exports.o=I;exports.p=y;exports.q=$;exports.r=K;
@@ -390,4 +390,4 @@ bucket_name = "${u}"
390
390
  `);}catch(x){let _=x?.stdout?.toString?.()||"",L=x?.stderr?.toString?.()||"";ee.fail("Deployment failed"),_&&process.stdout.write(_),L&&process.stdout.write(L),console.log(`
391
391
  ${C.red.bold("\u2716 Deployment Failed!")}`),console.log(` ${C.dim("See the Wrangler error above.")}
392
392
  `),f&&process.stdout.write(JSON.stringify({ok:false,error:"Deployment failed"})+`
393
- `),process.exit(1);}}),i}var ng=url.fileURLToPath(chunkBUNLC3II_cjs.g),og=Gt.dirname(ng),Gl="0.1.0";try{Gl=JSON.parse(et.readFileSync(Gt.join(og,"../../package.json"),"utf-8")).version;}catch{}var jt=new ie;jt.name("kyro").description("Kyro CMS - Astro-native headless CMS").version(Gl);jt.command("dev").description("Start Kyro CMS development server").option("-p, --port <port>","Port to run on","4321").option("-h, --host <host>","Host to bind to","localhost").action(async i=>{let{exec:t}=await import('child_process'),e=t(`astro dev --port ${i.port} --host ${i.host}`,{env:{...process.env,NODE_NO_WARNINGS:"1"}});e.stdout?.on("data",s=>process.stdout.write(s)),e.stderr?.on("data",s=>process.stderr.write(s)),process.on("SIGINT",()=>{e.kill("SIGINT"),process.exit(0);}),process.on("SIGTERM",()=>{e.kill("SIGTERM"),process.exit(0);});});jt.addCommand(Bo());jt.addCommand(Vl());var ts=jt.command("db").description("Database management commands");ts.command("generate").description("Generate migrations from schema").action(async()=>{let{exec:i}=await import('child_process');i("npx drizzle-kit generate",(t,e,s)=>{t&&(console.error("\u274C Generation failed:",t.message),process.exit(1));});});ts.command("migrate").description("Run database migrations").action(async()=>{let{exec:i}=await import('child_process');i("npx drizzle-kit migrate",(t,e,s)=>{t&&(console.error("\u274C Migration failed:",t.message),process.exit(1));});});ts.command("push").description("Push schema to database (development)").action(async()=>{let{exec:i}=await import('child_process');i("npx drizzle-kit push",(t,e,s)=>{t&&(console.error("\u274C Push failed:",t.message),process.exit(1));});});ts.command("seed").description("Seed database with initial data").action(async()=>{let{exec:i}=await import('child_process');i("npx tsx src/database/drizzle/seed.ts",(t,e,s)=>{t&&(console.error("\u274C Seeding failed:",t.message),process.exit(1));});});ts.command("studio").description("Open Drizzle Studio").action(async()=>{let{exec:i}=await import('child_process');i("npx drizzle-kit studio",(t,e,s)=>{t&&(console.error("\u274C Studio failed:",t.message),process.exit(1));});});var ug=jt.command("auth").description("Authentication management commands");ug.command("bootstrap").description("Create initial admin user").option("-e, --email <email>","Admin email",process.env.KYRO_ADMIN_EMAIL).option("-p, --password <password>","Admin password",process.env.KYRO_ADMIN_PASSWORD).option("-r, --role <role>","Admin role",process.env.KYRO_ADMIN_ROLE||"admin").action(async i=>{(!i.email||!i.password)&&(console.error("\u274C Email and password are required. Set KYRO_ADMIN_EMAIL and KYRO_ADMIN_PASSWORD env vars or use -e and -p options."),process.exit(1));try{let{bootstrapAdmin:t}=await import('../bootstrap-FTVBJ47D.cjs'),e=process.env.DATABASE_URL||"",s=e.toLowerCase().startsWith("postgres://")||e.toLowerCase().startsWith("postgresql://"),r=e.toLowerCase().startsWith("mongodb://")||e.toLowerCase().startsWith("mongodb+srv://"),n=!e||e.includes(".db")||e.includes("sqlite")||e.includes("file:"),o;if(s){let{PostgresAuthAdapter:a}=await import('../postgres-auth-adapter-ZO6HK5AK.cjs'),{drizzle:h}=await import('../postgres-js-3Y54EXVQ.cjs'),{default:d}=await import('../src-6LAUXXDM.cjs'),c=d(e,{max:1,onnotice:()=>{}}),f=h(c);o=new a({db:f});}else if(r){let{MongoDBAuthAdapter:a}=await import('../mongo-auth-adapter-EUHAYWJ6.cjs'),h=await import('../lib-5QYYN6ML.cjs'),d=h.MongoClient??h.default?.MongoClient,c=new d(e);await c.connect();let f=c.db();o=new a({db:f});}else {let{SQLiteAuthAdapter:a}=await import('../sqlite-adapter-ZTABLT2X.cjs'),h=process.env.KYRO_AUTH_DB_PATH||"./data/auth.db";o=new a({path:h});}o.connect&&await o.connect();let u=await t({authAdapter:o,adminEmail:i.email,adminPassword:i.password,adminRole:i.role});o.disconnect&&await o.disconnect(),u.success||(console.error("\u274C Failed to create admin:",u.error),process.exit(1));}catch(t){console.error("\u274C Bootstrap failed:",t),process.exit(1);}});jt.command("health").description("Check system health").action(async()=>{let i=process.env.DATABASE_URL||"",t=i.toLowerCase().startsWith("postgres://")||i.toLowerCase().startsWith("postgresql://"),e=i.toLowerCase().startsWith("mongodb://")||i.toLowerCase().startsWith("mongodb+srv://"),s=!i||i.includes(".db")||i.includes("sqlite")||i.includes("file:");if(t)try{let{default:r}=await import('../src-6LAUXXDM.cjs'),n=r(i,{max:1,onnotice:()=>{}});await n.unsafe("SELECT 1"),await n.end();}catch{}else if(e)try{let r=await import('../lib-5QYYN6ML.cjs'),n=r.MongoClient??r.default?.MongoClient,o=new n(i);await o.connect(),await o.db().admin().ping(),await o.close();}catch{}else if(s)try{let r=process.env.KYRO_AUTH_DB_PATH||"./data/auth.db",{existsSync:n}=await import('fs');n(r);}catch{}});jt.parse();process.argv.slice(2).length||jt.outputHelp();
393
+ `),process.exit(1);}}),i}var ng=url.fileURLToPath(chunkBUNLC3II_cjs.g),og=Gt.dirname(ng),Gl="0.1.0";try{Gl=JSON.parse(et.readFileSync(Gt.join(og,"../../package.json"),"utf-8")).version;}catch{}var jt=new ie;jt.name("kyro").description("Kyro CMS - Astro-native headless CMS").version(Gl);jt.command("dev").description("Start Kyro CMS development server").option("-p, --port <port>","Port to run on","4321").option("-h, --host <host>","Host to bind to","localhost").action(async i=>{let{exec:t}=await import('child_process'),e=t(`astro dev --port ${i.port} --host ${i.host}`,{env:{...process.env,NODE_NO_WARNINGS:"1"}});e.stdout?.on("data",s=>process.stdout.write(s)),e.stderr?.on("data",s=>process.stderr.write(s)),process.on("SIGINT",()=>{e.kill("SIGINT"),process.exit(0);}),process.on("SIGTERM",()=>{e.kill("SIGTERM"),process.exit(0);});});jt.addCommand(Bo());jt.addCommand(Vl());var ts=jt.command("db").description("Database management commands");ts.command("generate").description("Generate migrations from schema").action(async()=>{let{exec:i}=await import('child_process');i("npx drizzle-kit generate",(t,e,s)=>{t&&(console.error("\u274C Generation failed:",t.message),process.exit(1));});});ts.command("migrate").description("Run database migrations").action(async()=>{let{exec:i}=await import('child_process');i("npx drizzle-kit migrate",(t,e,s)=>{t&&(console.error("\u274C Migration failed:",t.message),process.exit(1));});});ts.command("push").description("Push schema to database (development)").action(async()=>{let{exec:i}=await import('child_process');i("npx drizzle-kit push",(t,e,s)=>{t&&(console.error("\u274C Push failed:",t.message),process.exit(1));});});ts.command("seed").description("Seed database with initial data").action(async()=>{let{exec:i}=await import('child_process');i("npx tsx src/database/drizzle/seed.ts",(t,e,s)=>{t&&(console.error("\u274C Seeding failed:",t.message),process.exit(1));});});ts.command("studio").description("Open Drizzle Studio").action(async()=>{let{exec:i}=await import('child_process');i("npx drizzle-kit studio",(t,e,s)=>{t&&(console.error("\u274C Studio failed:",t.message),process.exit(1));});});var ug=jt.command("auth").description("Authentication management commands");ug.command("bootstrap").description("Create initial admin user").option("-e, --email <email>","Admin email",process.env.KYRO_ADMIN_EMAIL).option("-p, --password <password>","Admin password",process.env.KYRO_ADMIN_PASSWORD).option("-r, --role <role>","Admin role",process.env.KYRO_ADMIN_ROLE||"admin").action(async i=>{(!i.email||!i.password)&&(console.error("\u274C Email and password are required. Set KYRO_ADMIN_EMAIL and KYRO_ADMIN_PASSWORD env vars or use -e and -p options."),process.exit(1));try{let{bootstrapAdmin:t}=await import('../bootstrap-JF6Q4L6P.cjs'),e=process.env.DATABASE_URL||"",s=e.toLowerCase().startsWith("postgres://")||e.toLowerCase().startsWith("postgresql://"),r=e.toLowerCase().startsWith("mongodb://")||e.toLowerCase().startsWith("mongodb+srv://"),n=!e||e.includes(".db")||e.includes("sqlite")||e.includes("file:"),o;if(s){let{PostgresAuthAdapter:a}=await import('../postgres-auth-adapter-ZO6HK5AK.cjs'),{drizzle:h}=await import('../postgres-js-3Y54EXVQ.cjs'),{default:d}=await import('../src-6LAUXXDM.cjs'),c=d(e,{max:1,onnotice:()=>{}}),f=h(c);o=new a({db:f});}else if(r){let{MongoDBAuthAdapter:a}=await import('../mongo-auth-adapter-EUHAYWJ6.cjs'),h=await import('../lib-5QYYN6ML.cjs'),d=h.MongoClient??h.default?.MongoClient,c=new d(e);await c.connect();let f=c.db();o=new a({db:f});}else {let{SQLiteAuthAdapter:a}=await import('../sqlite-adapter-ZTABLT2X.cjs'),h=process.env.KYRO_AUTH_DB_PATH||"./data/auth.db";o=new a({path:h});}o.connect&&await o.connect();let u=await t({authAdapter:o,adminEmail:i.email,adminPassword:i.password,adminRole:i.role});o.disconnect&&await o.disconnect(),u.success||(console.error("\u274C Failed to create admin:",u.error),process.exit(1));}catch(t){console.error("\u274C Bootstrap failed:",t),process.exit(1);}});jt.command("health").description("Check system health").action(async()=>{let i=process.env.DATABASE_URL||"",t=i.toLowerCase().startsWith("postgres://")||i.toLowerCase().startsWith("postgresql://"),e=i.toLowerCase().startsWith("mongodb://")||i.toLowerCase().startsWith("mongodb+srv://"),s=!i||i.includes(".db")||i.includes("sqlite")||i.includes("file:");if(t)try{let{default:r}=await import('../src-6LAUXXDM.cjs'),n=r(i,{max:1,onnotice:()=>{}});await n.unsafe("SELECT 1"),await n.end();}catch{}else if(e)try{let r=await import('../lib-5QYYN6ML.cjs'),n=r.MongoClient??r.default?.MongoClient,o=new n(i);await o.connect(),await o.db().admin().ping(),await o.close();}catch{}else if(s)try{let r=process.env.KYRO_AUTH_DB_PATH||"./data/auth.db",{existsSync:n}=await import('fs');n(r);}catch{}});jt.parse();process.argv.slice(2).length||jt.outputHelp();
package/dist/cli/index.js CHANGED
@@ -391,4 +391,4 @@ bucket_name = "${u}"
391
391
  `);}catch(v){let S=v?.stdout?.toString?.()||"",W=v?.stderr?.toString?.()||"";se.fail("Deployment failed"),S&&process.stdout.write(S),W&&process.stdout.write(W),console.log(`
392
392
  ${E.red.bold("\u2716 Deployment Failed!")}`),console.log(` ${E.dim("See the Wrangler error above.")}
393
393
  `),f&&process.stdout.write(JSON.stringify({ok:false,error:"Deployment failed"})+`
394
- `),process.exit(1);}}),i}var og=fileURLToPath(import.meta.url),ug=dirname(og),zl="0.1.0";try{zl=JSON.parse(readFileSync(join(ug,"../../package.json"),"utf-8")).version;}catch{}var Nt=new re;Nt.name("kyro").description("Kyro CMS - Astro-native headless CMS").version(zl);Nt.command("dev").description("Start Kyro CMS development server").option("-p, --port <port>","Port to run on","4321").option("-h, --host <host>","Host to bind to","localhost").action(async i=>{let{exec:t}=await import('child_process'),e=t(`astro dev --port ${i.port} --host ${i.host}`,{env:{...process.env,NODE_NO_WARNINGS:"1"}});e.stdout?.on("data",s=>process.stdout.write(s)),e.stderr?.on("data",s=>process.stderr.write(s)),process.on("SIGINT",()=>{e.kill("SIGINT"),process.exit(0);}),process.on("SIGTERM",()=>{e.kill("SIGTERM"),process.exit(0);});});Nt.addCommand(Mo());Nt.addCommand(Gl());var es=Nt.command("db").description("Database management commands");es.command("generate").description("Generate migrations from schema").action(async()=>{let{exec:i}=await import('child_process');i("npx drizzle-kit generate",(t,e,s)=>{t&&(console.error("\u274C Generation failed:",t.message),process.exit(1));});});es.command("migrate").description("Run database migrations").action(async()=>{let{exec:i}=await import('child_process');i("npx drizzle-kit migrate",(t,e,s)=>{t&&(console.error("\u274C Migration failed:",t.message),process.exit(1));});});es.command("push").description("Push schema to database (development)").action(async()=>{let{exec:i}=await import('child_process');i("npx drizzle-kit push",(t,e,s)=>{t&&(console.error("\u274C Push failed:",t.message),process.exit(1));});});es.command("seed").description("Seed database with initial data").action(async()=>{let{exec:i}=await import('child_process');i("npx tsx src/database/drizzle/seed.ts",(t,e,s)=>{t&&(console.error("\u274C Seeding failed:",t.message),process.exit(1));});});es.command("studio").description("Open Drizzle Studio").action(async()=>{let{exec:i}=await import('child_process');i("npx drizzle-kit studio",(t,e,s)=>{t&&(console.error("\u274C Studio failed:",t.message),process.exit(1));});});var ag=Nt.command("auth").description("Authentication management commands");ag.command("bootstrap").description("Create initial admin user").option("-e, --email <email>","Admin email",process.env.KYRO_ADMIN_EMAIL).option("-p, --password <password>","Admin password",process.env.KYRO_ADMIN_PASSWORD).option("-r, --role <role>","Admin role",process.env.KYRO_ADMIN_ROLE||"admin").action(async i=>{(!i.email||!i.password)&&(console.error("\u274C Email and password are required. Set KYRO_ADMIN_EMAIL and KYRO_ADMIN_PASSWORD env vars or use -e and -p options."),process.exit(1));try{let{bootstrapAdmin:t}=await import('../bootstrap-IGHJFNYG.js'),e=process.env.DATABASE_URL||"",s=e.toLowerCase().startsWith("postgres://")||e.toLowerCase().startsWith("postgresql://"),r=e.toLowerCase().startsWith("mongodb://")||e.toLowerCase().startsWith("mongodb+srv://"),n=!e||e.includes(".db")||e.includes("sqlite")||e.includes("file:"),o;if(s){let{PostgresAuthAdapter:a}=await import('../postgres-auth-adapter-SK3N3OSS.js'),{drizzle:h}=await import('../postgres-js-4CI7FMYS.js'),{default:d}=await import('../src-QBADSZV4.js'),c=d(e,{max:1,onnotice:()=>{}}),f=h(c);o=new a({db:f});}else if(r){let{MongoDBAuthAdapter:a}=await import('../mongo-auth-adapter-FW7ATYQ6.js'),h=await import('../lib-XXYYUPMW.js'),d=h.MongoClient??h.default?.MongoClient,c=new d(e);await c.connect();let f=c.db();o=new a({db:f});}else {let{SQLiteAuthAdapter:a}=await import('../sqlite-adapter-4TPNROJK.js'),h=process.env.KYRO_AUTH_DB_PATH||"./data/auth.db";o=new a({path:h});}o.connect&&await o.connect();let u=await t({authAdapter:o,adminEmail:i.email,adminPassword:i.password,adminRole:i.role});o.disconnect&&await o.disconnect(),u.success||(console.error("\u274C Failed to create admin:",u.error),process.exit(1));}catch(t){console.error("\u274C Bootstrap failed:",t),process.exit(1);}});Nt.command("health").description("Check system health").action(async()=>{let i=process.env.DATABASE_URL||"",t=i.toLowerCase().startsWith("postgres://")||i.toLowerCase().startsWith("postgresql://"),e=i.toLowerCase().startsWith("mongodb://")||i.toLowerCase().startsWith("mongodb+srv://"),s=!i||i.includes(".db")||i.includes("sqlite")||i.includes("file:");if(t)try{let{default:r}=await import('../src-QBADSZV4.js'),n=r(i,{max:1,onnotice:()=>{}});await n.unsafe("SELECT 1"),await n.end();}catch{}else if(e)try{let r=await import('../lib-XXYYUPMW.js'),n=r.MongoClient??r.default?.MongoClient,o=new n(i);await o.connect(),await o.db().admin().ping(),await o.close();}catch{}else if(s)try{let r=process.env.KYRO_AUTH_DB_PATH||"./data/auth.db",{existsSync:n}=await import('fs');n(r);}catch{}});Nt.parse();process.argv.slice(2).length||Nt.outputHelp();
394
+ `),process.exit(1);}}),i}var og=fileURLToPath(import.meta.url),ug=dirname(og),zl="0.1.0";try{zl=JSON.parse(readFileSync(join(ug,"../../package.json"),"utf-8")).version;}catch{}var Nt=new re;Nt.name("kyro").description("Kyro CMS - Astro-native headless CMS").version(zl);Nt.command("dev").description("Start Kyro CMS development server").option("-p, --port <port>","Port to run on","4321").option("-h, --host <host>","Host to bind to","localhost").action(async i=>{let{exec:t}=await import('child_process'),e=t(`astro dev --port ${i.port} --host ${i.host}`,{env:{...process.env,NODE_NO_WARNINGS:"1"}});e.stdout?.on("data",s=>process.stdout.write(s)),e.stderr?.on("data",s=>process.stderr.write(s)),process.on("SIGINT",()=>{e.kill("SIGINT"),process.exit(0);}),process.on("SIGTERM",()=>{e.kill("SIGTERM"),process.exit(0);});});Nt.addCommand(Mo());Nt.addCommand(Gl());var es=Nt.command("db").description("Database management commands");es.command("generate").description("Generate migrations from schema").action(async()=>{let{exec:i}=await import('child_process');i("npx drizzle-kit generate",(t,e,s)=>{t&&(console.error("\u274C Generation failed:",t.message),process.exit(1));});});es.command("migrate").description("Run database migrations").action(async()=>{let{exec:i}=await import('child_process');i("npx drizzle-kit migrate",(t,e,s)=>{t&&(console.error("\u274C Migration failed:",t.message),process.exit(1));});});es.command("push").description("Push schema to database (development)").action(async()=>{let{exec:i}=await import('child_process');i("npx drizzle-kit push",(t,e,s)=>{t&&(console.error("\u274C Push failed:",t.message),process.exit(1));});});es.command("seed").description("Seed database with initial data").action(async()=>{let{exec:i}=await import('child_process');i("npx tsx src/database/drizzle/seed.ts",(t,e,s)=>{t&&(console.error("\u274C Seeding failed:",t.message),process.exit(1));});});es.command("studio").description("Open Drizzle Studio").action(async()=>{let{exec:i}=await import('child_process');i("npx drizzle-kit studio",(t,e,s)=>{t&&(console.error("\u274C Studio failed:",t.message),process.exit(1));});});var ag=Nt.command("auth").description("Authentication management commands");ag.command("bootstrap").description("Create initial admin user").option("-e, --email <email>","Admin email",process.env.KYRO_ADMIN_EMAIL).option("-p, --password <password>","Admin password",process.env.KYRO_ADMIN_PASSWORD).option("-r, --role <role>","Admin role",process.env.KYRO_ADMIN_ROLE||"admin").action(async i=>{(!i.email||!i.password)&&(console.error("\u274C Email and password are required. Set KYRO_ADMIN_EMAIL and KYRO_ADMIN_PASSWORD env vars or use -e and -p options."),process.exit(1));try{let{bootstrapAdmin:t}=await import('../bootstrap-VUWX45QN.js'),e=process.env.DATABASE_URL||"",s=e.toLowerCase().startsWith("postgres://")||e.toLowerCase().startsWith("postgresql://"),r=e.toLowerCase().startsWith("mongodb://")||e.toLowerCase().startsWith("mongodb+srv://"),n=!e||e.includes(".db")||e.includes("sqlite")||e.includes("file:"),o;if(s){let{PostgresAuthAdapter:a}=await import('../postgres-auth-adapter-SK3N3OSS.js'),{drizzle:h}=await import('../postgres-js-4CI7FMYS.js'),{default:d}=await import('../src-QBADSZV4.js'),c=d(e,{max:1,onnotice:()=>{}}),f=h(c);o=new a({db:f});}else if(r){let{MongoDBAuthAdapter:a}=await import('../mongo-auth-adapter-FW7ATYQ6.js'),h=await import('../lib-XXYYUPMW.js'),d=h.MongoClient??h.default?.MongoClient,c=new d(e);await c.connect();let f=c.db();o=new a({db:f});}else {let{SQLiteAuthAdapter:a}=await import('../sqlite-adapter-4TPNROJK.js'),h=process.env.KYRO_AUTH_DB_PATH||"./data/auth.db";o=new a({path:h});}o.connect&&await o.connect();let u=await t({authAdapter:o,adminEmail:i.email,adminPassword:i.password,adminRole:i.role});o.disconnect&&await o.disconnect(),u.success||(console.error("\u274C Failed to create admin:",u.error),process.exit(1));}catch(t){console.error("\u274C Bootstrap failed:",t),process.exit(1);}});Nt.command("health").description("Check system health").action(async()=>{let i=process.env.DATABASE_URL||"",t=i.toLowerCase().startsWith("postgres://")||i.toLowerCase().startsWith("postgresql://"),e=i.toLowerCase().startsWith("mongodb://")||i.toLowerCase().startsWith("mongodb+srv://"),s=!i||i.includes(".db")||i.includes("sqlite")||i.includes("file:");if(t)try{let{default:r}=await import('../src-QBADSZV4.js'),n=r(i,{max:1,onnotice:()=>{}});await n.unsafe("SELECT 1"),await n.end();}catch{}else if(e)try{let r=await import('../lib-XXYYUPMW.js'),n=r.MongoClient??r.default?.MongoClient,o=new n(i);await o.connect(),await o.db().admin().ping(),await o.close();}catch{}else if(s)try{let r=process.env.KYRO_AUTH_DB_PATH||"./data/auth.db",{existsSync:n}=await import('fs');n(r);}catch{}});Nt.parse();process.argv.slice(2).length||Nt.outputHelp();