@kyro-cms/core 0.9.9 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api-handler-graphql.cjs +11 -11
- package/dist/api-handler-graphql.js +7 -7
- package/dist/api-handler-trpc.cjs +9 -9
- package/dist/api-handler-trpc.js +7 -7
- package/dist/api-handler.cjs +10 -10
- package/dist/api-handler.js +7 -7
- package/dist/{bootstrap-4CELFLJO.cjs → bootstrap-FUAPY2OF.cjs} +9 -9
- package/dist/{bootstrap-4CELFLJO.cjs.map → bootstrap-FUAPY2OF.cjs.map} +1 -1
- package/dist/bootstrap-OXNVM7FP.js +7 -0
- package/dist/{bootstrap-3PV3GJ3S.js.map → bootstrap-OXNVM7FP.js.map} +1 -1
- package/dist/{chunk-5RFGYEQ3.js → chunk-354ISGA4.js} +5 -23
- package/dist/chunk-354ISGA4.js.map +1 -0
- package/dist/{chunk-E4JZ73FY.cjs → chunk-3P5AHK2U.cjs} +11 -24
- package/dist/chunk-3P5AHK2U.cjs.map +1 -0
- package/dist/{chunk-BVUDFKKS.js → chunk-526M5MOA.js} +6 -8
- package/dist/chunk-526M5MOA.js.map +1 -0
- package/dist/{chunk-5PMQQFRE.cjs → chunk-5GFQPHGT.cjs} +6 -9
- package/dist/chunk-5GFQPHGT.cjs.map +1 -0
- package/dist/{chunk-OYCICW4B.js → chunk-AN2L2CJZ.js} +4 -17
- package/dist/chunk-AN2L2CJZ.js.map +1 -0
- package/dist/{chunk-RFFSZSCL.cjs → chunk-GYIJ3JJM.cjs} +3 -11
- package/dist/chunk-GYIJ3JJM.cjs.map +1 -0
- package/dist/{chunk-PQ72Z6WC.js → chunk-GZS4LMR7.js} +2 -5
- package/dist/chunk-GZS4LMR7.js.map +1 -0
- package/dist/{chunk-GAAHG2Z4.js → chunk-HY6B7B5A.js} +4 -7
- package/dist/chunk-HY6B7B5A.js.map +1 -0
- package/dist/{chunk-IEIHABVR.cjs → chunk-ISKYUUP4.cjs} +15 -33
- package/dist/chunk-ISKYUUP4.cjs.map +1 -0
- package/dist/{chunk-6UNONDW7.js → chunk-N5QSHUA6.js} +2 -11
- package/dist/chunk-N5QSHUA6.js.map +1 -0
- package/dist/{chunk-OXYSOU6Z.cjs → chunk-NQJJYRLP.cjs} +11 -13
- package/dist/chunk-NQJJYRLP.cjs.map +1 -0
- package/dist/{chunk-Q23GAMLE.cjs → chunk-THBQG64D.cjs} +2 -5
- package/dist/chunk-THBQG64D.cjs.map +1 -0
- package/dist/{chunk-Y7AQK4R4.cjs → chunk-VKREAIBA.cjs} +2 -11
- package/dist/chunk-VKREAIBA.cjs.map +1 -0
- package/dist/{chunk-V7KZQIZ6.js → chunk-XHAAAEXX.js} +2 -10
- package/dist/chunk-XHAAAEXX.js.map +1 -0
- package/dist/cli/index.cjs +1 -41
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +1 -41
- package/dist/cli/index.js.map +1 -1
- package/dist/drizzle/index.cjs +9 -9
- package/dist/drizzle/index.js +1 -1
- package/dist/index.cjs +62 -64
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +8 -10
- package/dist/index.js.map +1 -1
- package/dist/mongodb/index.cjs +3 -3
- package/dist/mongodb/index.js +1 -1
- package/dist/rest/index.cjs +6 -6
- package/dist/rest/index.js +4 -4
- package/package.json +1 -1
- package/dist/bootstrap-3PV3GJ3S.js +0 -7
- package/dist/chunk-5PMQQFRE.cjs.map +0 -1
- package/dist/chunk-5RFGYEQ3.js.map +0 -1
- package/dist/chunk-6UNONDW7.js.map +0 -1
- package/dist/chunk-BVUDFKKS.js.map +0 -1
- package/dist/chunk-E4JZ73FY.cjs.map +0 -1
- package/dist/chunk-GAAHG2Z4.js.map +0 -1
- package/dist/chunk-IEIHABVR.cjs.map +0 -1
- package/dist/chunk-OXYSOU6Z.cjs.map +0 -1
- package/dist/chunk-OYCICW4B.js.map +0 -1
- package/dist/chunk-PQ72Z6WC.js.map +0 -1
- package/dist/chunk-Q23GAMLE.cjs.map +0 -1
- package/dist/chunk-RFFSZSCL.cjs.map +0 -1
- package/dist/chunk-V7KZQIZ6.js.map +0 -1
- package/dist/chunk-Y7AQK4R4.cjs.map +0 -1
|
@@ -717,11 +717,6 @@ var EmailTransport = class _EmailTransport {
|
|
|
717
717
|
const { provider, from, fromName, replyTo: configReplyTo } = this.config;
|
|
718
718
|
const fromFull = `"${fromName || "Kyro CMS"}" <${from}>`;
|
|
719
719
|
const replyTo = options.replyTo || configReplyTo;
|
|
720
|
-
console.log(`[EmailTransport] Sending email via ${provider}...`);
|
|
721
|
-
console.log(
|
|
722
|
-
`[EmailTransport] To: ${Array.isArray(options.to) ? options.to.join(", ") : options.to}`
|
|
723
|
-
);
|
|
724
|
-
console.log(`[EmailTransport] Subject: ${options.subject}`);
|
|
725
720
|
try {
|
|
726
721
|
let result;
|
|
727
722
|
switch (provider) {
|
|
@@ -753,7 +748,6 @@ var EmailTransport = class _EmailTransport {
|
|
|
753
748
|
default:
|
|
754
749
|
throw new Error(`Unsupported email provider: ${provider}`);
|
|
755
750
|
}
|
|
756
|
-
console.log(`[EmailTransport] Success! Provider response received.`);
|
|
757
751
|
return result;
|
|
758
752
|
} catch (error) {
|
|
759
753
|
console.error(`[EmailTransport] FAILED to send email:`, error.message);
|
|
@@ -777,7 +771,6 @@ var EmailTransport = class _EmailTransport {
|
|
|
777
771
|
text: options.text,
|
|
778
772
|
reply_to: replyTo
|
|
779
773
|
};
|
|
780
|
-
console.log(`[EmailTransport] Calling Resend API...`);
|
|
781
774
|
const resp = await fetch("https://api.resend.com/emails", {
|
|
782
775
|
method: "POST",
|
|
783
776
|
headers: {
|
|
@@ -812,7 +805,6 @@ var EmailTransport = class _EmailTransport {
|
|
|
812
805
|
],
|
|
813
806
|
reply_to: replyTo ? { email: replyTo } : void 0
|
|
814
807
|
};
|
|
815
|
-
console.log(`[EmailTransport] Calling SendGrid API...`);
|
|
816
808
|
const resp = await fetch("https://api.sendgrid.com/v3/mail/send", {
|
|
817
809
|
method: "POST",
|
|
818
810
|
headers: {
|
|
@@ -840,7 +832,6 @@ var EmailTransport = class _EmailTransport {
|
|
|
840
832
|
formData.append("html", options.html);
|
|
841
833
|
if (options.text) formData.append("text", options.text);
|
|
842
834
|
if (replyTo) formData.append("h:Reply-To", replyTo);
|
|
843
|
-
console.log(`[EmailTransport] Calling Mailgun API (${region || "us"})...`);
|
|
844
835
|
const resp = await fetch(`https://${base}/v3/${domain}/messages`, {
|
|
845
836
|
method: "POST",
|
|
846
837
|
headers: {
|
|
@@ -1140,5 +1131,5 @@ var PasswordPolicy = class {
|
|
|
1140
1131
|
};
|
|
1141
1132
|
|
|
1142
1133
|
export { ConfigService, EmailTransport, PasswordPolicy };
|
|
1143
|
-
//# sourceMappingURL=chunk-
|
|
1144
|
-
//# sourceMappingURL=chunk-
|
|
1134
|
+
//# sourceMappingURL=chunk-N5QSHUA6.js.map
|
|
1135
|
+
//# sourceMappingURL=chunk-N5QSHUA6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config/ConfigService.ts","../src/auth/nodemailer-transport.ts","../src/auth/security/password-policy.ts"],"names":[],"mappings":";;;AAGA,IAAI,qBAAA,GAAwB,KAAA;AA+FrB,IAAM,aAAA,GAAN,MAAM,cAAA,CAAc;AAAA,EACjB,EAAA;AAAA,EACA,QAAgC,EAAC;AAAA,EACjC,MAAA,GAAS,KAAA;AAAA,EACjB,OAAwB,cAAA,GAAiB;AAAA,IACvC,8BAAA;AAAA,IACA,8BAAA;AAAA,IACA,yBAAA;AAAA,IACA,mCAAA;AAAA,IACA,kCAAA;AAAA,IACA,sBAAA;AAAA,IACA,uBAAA;AAAA,IACA,+BAAA;AAAA,IACA,wBAAA;AAAA,IACA,iBAAA;AAAA,IACA,iBAAA;AAAA,IACA,oBAAA;AAAA,IACA,oBAAA;AAAA,IACA,iBAAA;AAAA,IACA,cAAA;AAAA,IACA,WAAA;AAAA,IACA;AAAA,GACF;AAAA,EAEA,YAAY,EAAA,EAAS;AACnB,IAAA,IAAA,CAAK,EAAA,GAAK,EAAA;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAA,GAAsB;AAC1B,IAAA,IAAI,KAAK,MAAA,EAAQ;AAEjB,IAAA,MAAM,KAAK,mBAAA,EAAoB;AAE/B,IAAA,IAAI;AACF,MAAA,IAAI,OAAO,IAAA,CAAK,EAAA,EAAI,MAAA,KAAW,UAAA,EAAY;AACzC,QAAA,MAAM,cAAc,MAAM,IAAA,CAAK,GAAG,MAAA,EAAO,CAAE,KAAK,QAAc,CAAA;AAC9D,QAAA,IAAA,CAAK,KAAA,GAAQ,WAAA,CAAY,MAAA,CAAO,CAAC,KAAU,GAAA,KAAa;AACtD,UAAA,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA,GAAI,GAAA,CAAI,KAAA;AACnB,UAAA,OAAO,GAAA;AAAA,QACT,CAAA,EAAG,EAAE,CAAA;AAAA,MACP;AAGA,MAAA,MAAM,KAAK,eAAA,EAAgB;AAAA,IAC7B,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AAAA,EAChB;AAAA,EAEA,MAAc,mBAAA,GAAqC;AACjD,IAAA,IAAI,qBAAA,EAAuB;AAE3B,IAAA,IAAI;AACF,MAAA,IAAI,OAAO,IAAA,CAAK,EAAA,EAAI,OAAA,KAAY,UAAA,EAAY;AAC1C,QAAA,MAAM,EAAE,GAAA,EAAI,GAAI,MAAM,OAAO,aAAa,CAAA;AAC1C,QAAA,MAAM,IAAA,CAAK,GAAG,OAAA,CAAQ,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAAA,CAOrB,CAAA;AACD,QAAA,qBAAA,GAAwB,IAAA;AAAA,MAC1B,CAAA,MAAA,IAAW,OAAO,IAAA,CAAK,EAAA,EAAI,SAAS,UAAA,EAAY;AAC9C,QAAA,IAAA,CAAK,GAAG,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAAA,CAOZ,CAAA;AACD,QAAA,qBAAA,GAAwB,IAAA;AAAA,MAC1B;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,eAAA,GAAiC;AAC7C,IAAA,IAAI;AACF,MAAA,IAAI,GAAA,GAAW,IAAA;AACf,MAAA,IAAI,OAAO,IAAA,CAAK,EAAA,EAAI,OAAA,KAAY,UAAA,EAAY;AAC1C,QAAA,MAAM,EAAE,GAAA,EAAI,GAAI,MAAM,OAAO,aAAa,CAAA;AAC1C,QAAA,MAAM,QAAA,GAAW,CAAC,6BAAA,EAA+B,6BAAA,EAA+B,2BAA2B,CAAA;AAC3G,QAAA,KAAA,MAAW,QAAQ,QAAA,EAAU;AAC3B,UAAA,IAAI;AACF,YAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,EAAA,CAAG,OAAA,CAAQ,oBAAoB,GAAA,CAAI,GAAA,CAAI,IAAI,CAAC,CAAA,QAAA,CAAU,CAAA;AAChF,YAAA,GAAA,GAAM,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,GAAI,MAAA,CAAO,CAAC,CAAA,GAAK,MAAA,EAAQ,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,GAAI,IAAA;AAC3E,YAAA,IAAI,GAAA,EAAK;AAAA,UACX,CAAA,CAAA,MAAQ;AAAA,UAAC;AAAA,QACX;AAAA,MACF,CAAA,MAAA,IAAW,OAAO,IAAA,CAAK,EAAA,EAAI,YAAY,UAAA,EAAY;AACjD,QAAA,MAAM,QAAA,GAAW,CAAC,6BAAA,EAA+B,6BAAA,EAA+B,2BAA2B,CAAA;AAC3G,QAAA,KAAA,MAAW,QAAQ,QAAA,EAAU;AAC3B,UAAA,IAAI;AACF,YAAA,GAAA,GAAM,KAAK,EAAA,CAAG,OAAA,CAAQ,iBAAiB,IAAI,CAAA,QAAA,CAAU,EAAE,GAAA,EAAI;AAC3D,YAAA,IAAI,GAAA,EAAK;AAAA,UACX,CAAA,CAAA,MAAQ;AAAA,UAAC;AAAA,QACX;AAAA,MACF;AAEA,MAAA,IAAI,CAAC,GAAA,EAAK;AAEV,MAAA,MAAM,SAAA,GAAY,CAAC,GAAA,KAAa;AAC9B,QAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AACjB,QAAA,IAAI,OAAO,QAAQ,QAAA,EAAU;AAC3B,UAAA,IAAI;AACF,YAAA,OAAO,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,UACvB,CAAA,CAAA,MAAQ;AACN,YAAA,OAAO,IAAA;AAAA,UACT;AAAA,QACF;AACA,QAAA,OAAO,GAAA;AAAA,MACT,CAAA;AAEA,MAAA,MAAM,QAAA,GAAW,IAAI,QAAA,IAAY,OAAA;AACjC,MAAA,IAAA,CAAK,KAAA,CAAM,cAAc,CAAA,GAAI,QAAA,KAAa,QAAQ,IAAA,GAAO,QAAA;AAEzD,MAAA,IAAI,aAAa,OAAA,EAAS;AACxB,QAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA;AACjC,QAAA,IAAA,CAAK,KAAA,CAAM,mBAAmB,CAAA,GAC5B,KAAA,EAAO,SAAA,IAAa,kBAAA;AACtB,QAAA,IAAA,CAAK,KAAA,CAAM,mBAAmB,CAAA,GAAI,KAAA,EAAO,OAAA,IAAW,UAAA;AAAA,MACtD;AAEA,MAAA,IAAI,aAAa,KAAA,EAAO;AACtB,QAAA,MAAM,GAAA,GAAM,SAAA,CAAU,GAAA,CAAI,GAAG,CAAA;AAC7B,QAAA,IAAA,CAAK,KAAA,CAAM,mBAAmB,CAAA,GAAI,GAAA,EAAK,MAAA,IAAU,EAAA;AACjD,QAAA,IAAA,CAAK,KAAA,CAAM,mBAAmB,CAAA,GAAI,GAAA,EAAK,MAAA,IAAU,WAAA;AACjD,QAAA,IAAA,CAAK,KAAA,CAAM,0BAA0B,CAAA,GAAI,GAAA,EAAK,WAAA,IAAe,EAAA;AAC7D,QAAA,IAAA,CAAK,KAAA,CAAM,8BAA8B,CAAA,GAAI,GAAA,EAAK,eAAA,IAAmB,EAAA;AACrE,QAAA,IAAA,CAAK,KAAA,CAAM,qBAAqB,CAAA,GAAI,GAAA,EAAK,QAAA,IAAY,EAAA;AACrD,QAAA,IAAA,CAAK,KAAA,CAAM,oBAAoB,CAAA,GAAI,GAAA,EAAK,MAAA,IAAU,EAAA;AAClD,QAAA,IAAA,CAAK,KAAA,CAAM,mBAAmB,CAAA,GAAI,GAAA,EAAK,MAAA,IAAU,EAAA;AAAA,MACnD;AAEA,MAAA,IAAI,aAAa,IAAA,EAAM;AACrB,QAAA,MAAM,EAAA,GAAK,SAAA,CAAU,GAAA,CAAI,EAAE,CAAA;AAC3B,QAAA,IAAA,CAAK,KAAA,CAAM,uBAAuB,CAAA,GAAI,EAAA,EAAI,SAAA,IAAa,EAAA;AACvD,QAAA,IAAA,CAAK,KAAA,CAAM,0BAA0B,CAAA,GAAI,EAAA,EAAI,WAAA,IAAe,EAAA;AAC5D,QAAA,IAAA,CAAK,KAAA,CAAM,8BAA8B,CAAA,GAAI,EAAA,EAAI,eAAA,IAAmB,EAAA;AACpE,QAAA,IAAA,CAAK,KAAA,CAAM,mBAAmB,CAAA,GAAI,EAAA,EAAI,MAAA,IAAU,EAAA;AAChD,QAAA,IAAA,CAAK,KAAA,CAAM,oBAAoB,CAAA,GAAI,EAAA,EAAI,MAAA,IAAU,EAAA;AACjD,QAAA,IAAA,CAAK,KAAA,CAAM,mBAAmB,CAAA,GAAI,EAAA,EAAI,MAAA,IAAU,EAAA;AAAA,MAClD;AAEA,MAAA,IAAI,aAAa,YAAA,EAAc;AAC7B,QAAA,MAAM,UAAA,GAAa,SAAA,CAAU,GAAA,CAAI,UAAU,CAAA;AAC3C,QAAA,IAAA,CAAK,KAAA,CAAM,+BAA+B,CAAA,GACxC,UAAA,EAAY,SAAA,IAAa,EAAA;AAC3B,QAAA,IAAA,CAAK,KAAA,CAAM,4BAA4B,CAAA,GAAI,UAAA,EAAY,MAAA,IAAU,EAAA;AACjE,QAAA,IAAA,CAAK,KAAA,CAAM,+BAA+B,CAAA,GACxC,UAAA,EAAY,SAAA,IAAa,EAAA;AAC3B,QAAA,IAAA,CAAK,KAAA,CAAM,2BAA2B,CAAA,GAAI,UAAA,EAAY,MAAA,IAAU,EAAA;AAAA,MAClE;AAEA,MAAA,IAAI,aAAa,KAAA,EAAO;AACtB,QAAA,MAAM,GAAA,GAAM,SAAA,CAAU,GAAA,CAAI,GAAG,CAAA;AAC7B,QAAA,IAAA,CAAK,KAAA,CAAM,kBAAkB,CAAA,GAAI,GAAA,EAAK,IAAA,IAAQ,EAAA;AAC9C,QAAA,IAAA,CAAK,MAAM,kBAAkB,CAAA,GAAI,MAAA,CAAO,GAAA,EAAK,QAAQ,IAAI,CAAA;AACzD,QAAA,IAAA,CAAK,KAAA,CAAM,kBAAkB,CAAA,GAAI,GAAA,EAAK,IAAA,IAAQ,EAAA;AAC9C,QAAA,IAAA,CAAK,KAAA,CAAM,sBAAsB,CAAA,GAAI,GAAA,EAAK,QAAA,IAAY,EAAA;AACtD,QAAA,IAAA,CAAK,KAAA,CAAM,oBAAoB,CAAA,GAAI,GAAA,EAAK,SAAS,MAAA,GAAS,OAAA;AAC1D,QAAA,IAAA,CAAK,KAAA,CAAM,sBAAsB,CAAA,GAAI,GAAA,EAAK,OAAA,IAAW,EAAA;AACrD,QAAA,IAAA,CAAK,KAAA,CAAM,oBAAoB,CAAA,GAAI,GAAA,EAAK,MAAA,IAAU,EAAA;AAAA,MACpD;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,IAAA,CAAK,sEAAsE,KAAK,CAAA;AAAA,IAC1F;AAGA,IAAA,IAAI;AACF,MAAA,IAAI,GAAA,GAAW,IAAA;AACf,MAAA,IAAI,OAAO,IAAA,CAAK,EAAA,EAAI,OAAA,KAAY,UAAA,EAAY;AAC1C,QAAA,MAAM,EAAE,GAAA,EAAI,GAAI,MAAM,OAAO,aAAa,CAAA;AAC1C,QAAA,MAAM,QAAA,GAAW,CAAC,2BAAA,EAA6B,2BAAA,EAA6B,yBAAyB,CAAA;AACrG,QAAA,KAAA,MAAW,QAAQ,QAAA,EAAU;AAC3B,UAAA,IAAI;AACF,YAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,EAAA,CAAG,OAAA,CAAQ,oBAAoB,GAAA,CAAI,GAAA,CAAI,IAAI,CAAC,CAAA,QAAA,CAAU,CAAA;AAChF,YAAA,GAAA,GAAM,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,GAAI,MAAA,CAAO,CAAC,CAAA,GAAK,MAAA,EAAQ,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,GAAI,IAAA;AAC3E,YAAA,IAAI,GAAA,EAAK;AAAA,UACX,CAAA,CAAA,MAAQ;AAAA,UAAC;AAAA,QACX;AAAA,MACF,CAAA,MAAA,IAAW,OAAO,IAAA,CAAK,EAAA,EAAI,YAAY,UAAA,EAAY;AACjD,QAAA,MAAM,QAAA,GAAW,CAAC,2BAAA,EAA6B,2BAAA,EAA6B,yBAAyB,CAAA;AACrG,QAAA,KAAA,MAAW,QAAQ,QAAA,EAAU;AAC3B,UAAA,IAAI;AACF,YAAA,GAAA,GAAM,KAAK,EAAA,CAAG,OAAA,CAAQ,iBAAiB,IAAI,CAAA,QAAA,CAAU,EAAE,GAAA,EAAI;AAC3D,YAAA,IAAI,GAAA,EAAK;AAAA,UACX,CAAA,CAAA,MAAQ;AAAA,UAAC;AAAA,QACX;AAAA,MACF;AAEA,MAAA,IAAI,GAAA,EAAK;AACP,QAAA,MAAM,SAAA,GAAY,CAAC,GAAA,KAAa;AAC9B,UAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AACjB,UAAA,IAAI,OAAO,QAAQ,QAAA,EAAU;AAC3B,YAAA,IAAI;AAAE,cAAA,OAAO,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,YAAG,CAAA,CAAA,MAAQ;AAAE,cAAA,OAAO,IAAA;AAAA,YAAM;AAAA,UACvD;AACA,UAAA,OAAO,GAAA;AAAA,QACT,CAAA;AAEA,QAAA,IAAA,CAAK,KAAA,CAAM,gBAAgB,CAAA,GAAI,GAAA,CAAI,QAAA,IAAY,MAAA;AAC/C,QAAA,IAAA,CAAK,KAAA,CAAM,iBAAiB,CAAA,GAAI,GAAA,CAAI,SAAA,IAAa,EAAA;AACjD,QAAA,IAAA,CAAK,KAAA,CAAM,sBAAsB,CAAA,GAAI,GAAA,CAAI,QAAA,IAAY,EAAA;AACrD,QAAA,IAAA,CAAK,KAAA,CAAM,qBAAqB,CAAA,GAAI,GAAA,CAAI,OAAA,IAAW,EAAA;AAEnD,QAAA,IAAI,GAAA,CAAI,aAAa,MAAA,EAAQ;AAC3B,UAAA,MAAM,IAAA,GAAO,SAAA,CAAU,GAAA,CAAI,IAAI,CAAA;AAC/B,UAAA,IAAA,CAAK,KAAA,CAAM,iBAAiB,CAAA,GAAI,IAAA,EAAM,IAAA,IAAQ,EAAA;AAC9C,UAAA,IAAA,CAAK,MAAM,iBAAiB,CAAA,GAAI,MAAA,CAAO,IAAA,EAAM,QAAQ,KAAK,CAAA;AAC1D,UAAA,IAAA,CAAK,KAAA,CAAM,iBAAiB,CAAA,GAAI,IAAA,EAAM,QAAA,IAAY,EAAA;AAClD,UAAA,IAAA,CAAK,KAAA,CAAM,iBAAiB,CAAA,GAAI,IAAA,EAAM,QAAA,IAAY,EAAA;AAClD,UAAA,IAAA,CAAK,KAAA,CAAM,mBAAmB,CAAA,GAAI,IAAA,EAAM,SAAS,MAAA,GAAS,OAAA;AAAA,QAC5D,CAAA,MAAA,IAAW,GAAA,CAAI,QAAA,KAAa,QAAA,EAAU;AACpC,UAAA,MAAM,MAAA,GAAS,SAAA,CAAU,GAAA,CAAI,MAAM,CAAA;AACnC,UAAA,IAAA,CAAK,KAAA,CAAM,iBAAiB,CAAA,GAAI,MAAA,EAAQ,MAAA,IAAU,EAAA;AAAA,QACpD,CAAA,MAAA,IAAW,GAAA,CAAI,QAAA,KAAa,UAAA,EAAY;AACtC,UAAA,MAAM,QAAA,GAAW,SAAA,CAAU,GAAA,CAAI,QAAQ,CAAA;AACvC,UAAA,IAAA,CAAK,KAAA,CAAM,iBAAiB,CAAA,GAAI,QAAA,EAAU,MAAA,IAAU,EAAA;AAAA,QACtD,CAAA,MAAA,IAAW,GAAA,CAAI,QAAA,KAAa,SAAA,EAAW;AACrC,UAAA,MAAM,OAAA,GAAU,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AACrC,UAAA,IAAA,CAAK,KAAA,CAAM,iBAAiB,CAAA,GAAI,OAAA,EAAS,MAAA,IAAU,EAAA;AAAA,QACrD,CAAA,MAAA,IAAW,GAAA,CAAI,QAAA,KAAa,KAAA,EAAO;AACjC,UAAA,MAAM,GAAA,GAAM,SAAA,CAAU,GAAA,CAAI,GAAG,CAAA;AAC7B,UAAA,IAAA,CAAK,KAAA,CAAM,iBAAiB,CAAA,GAAI,GAAA,EAAK,WAAA,IAAe,EAAA;AACpD,UAAA,IAAA,CAAK,KAAA,CAAM,iBAAiB,CAAA,GAAI,GAAA,EAAK,eAAA,IAAmB,EAAA;AAAA,QAC1D;AAAA,MACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,IAAA,CAAK,oEAAoE,KAAK,CAAA;AAAA,IACxF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,GAAA,CAAI,GAAA,EAAa,MAAA,EAAiB,YAAA,EAA2C;AAE3E,IAAA,IAAI,KAAK,KAAA,CAAM,GAAG,GAAG,OAAO,IAAA,CAAK,MAAM,GAAG,CAAA;AAG1C,IAAA,IAAI,MAAA,IAAU,QAAQ,GAAA,CAAI,MAAM,GAAG,OAAO,OAAA,CAAQ,IAAI,MAAM,CAAA;AAG5D,IAAA,OAAO,YAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAA,GAAkC;AAChC,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,cAAA,EAAgB,gBAAgB,OAAO,CAAA;AAAA,MACtD,EAAA,EAAI;AAAA,QACF,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,mBAAA,EAAqB,gBAAgB,CAAA;AAAA,QACtD,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,mBAAA,EAAqB,kBAAkB,WAAW,CAAA;AAAA,QACnE,aAAa,IAAA,CAAK,GAAA;AAAA,UAChB,0BAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,iBAAiB,IAAA,CAAK,GAAA;AAAA,UACpB,8BAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,QAAA,EAAU,IAAA,CAAK,GAAA,CAAI,qBAAA,EAAuB,kBAAkB,CAAA;AAAA,QAC5D,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,oBAAA,EAAsB,iBAAiB,CAAA;AAAA,QACxD,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,mBAAA,EAAqB,gBAAgB;AAAA,OACxD;AAAA,MACA,EAAA,EAAI;AAAA,QACF,SAAA,EAAW,IAAA,CAAK,GAAA,CAAI,uBAAA,EAAyB,eAAe,CAAA;AAAA,QAC5D,WAAA,EAAa,IAAA,CAAK,GAAA,CAAI,0BAAA,EAA4B,kBAAkB,CAAA;AAAA,QACpE,iBAAiB,IAAA,CAAK,GAAA;AAAA,UACpB,8BAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,mBAAA,EAAqB,WAAW,CAAA;AAAA,QACjD,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,oBAAA,EAAsB,YAAY,CAAA;AAAA,QACnD,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,mBAAA,EAAqB,WAAW;AAAA,OACnD;AAAA,MACA,GAAA,EAAK;AAAA,QACH,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,oBAAA,EAAsB,YAAY,CAAA;AAAA,QACnD,SAAA,EAAW,IAAA,CAAK,GAAA,CAAI,wBAAA,EAA0B,gBAAgB,CAAA;AAAA,QAC9D,WAAA,EAAa,IAAA,CAAK,GAAA,CAAI,0BAAA,EAA4B,kBAAkB,CAAA;AAAA,QACpE,UAAA,EAAY,IAAA,CAAK,GAAA,CAAI,yBAAA,EAA2B,iBAAiB,CAAA;AAAA,QACjE,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,qBAAA,EAAuB,aAAa,CAAA;AAAA,QACrD,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,oBAAA,EAAsB,YAAY;AAAA,OACrD;AAAA,MACA,YAAA,EAAc;AAAA,QACZ,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,6BAAA,EAA+B,WAAW,CAAA;AAAA,QAC3D,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,6BAAA,EAA+B,aAAa,MAAM,CAAA;AAAA,QACnE,aAAa,IAAA,CAAK,GAAA;AAAA,UAChB,oCAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,iBAAiB,IAAA,CAAK,GAAA;AAAA,UACpB,wCAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,8BAAA,EAAgC,YAAY,CAAA;AAAA,QAC7D,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,6BAAA,EAA+B,WAAW;AAAA,OAC7D;AAAA,MACA,SAAA,EAAW;AAAA,QACT,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,0BAAA,EAA4B,WAAW,CAAA;AAAA,QACxD,SAAA,EAAW,IAAA,CAAK,GAAA,CAAI,8BAAA,EAAgC,eAAe,CAAA;AAAA,QACnE,kBAAkB,IAAA,CAAK,GAAA;AAAA,UACrB,sCAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,gBAAgB,IAAA,CAAK,GAAA;AAAA,UACnB,mCAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,2BAAA,EAA6B,YAAY,CAAA;AAAA,QAC1D,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,0BAAA,EAA4B,WAAW;AAAA,OAC1D;AAAA,MACA,MAAA,EAAQ;AAAA,QACN,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,uBAAA,EAAyB,eAAe,CAAA;AAAA,QACzD,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,uBAAA,EAAyB,iBAAiB,WAAW,CAAA;AAAA,QACtE,aAAa,IAAA,CAAK,GAAA;AAAA,UAChB,8BAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,iBAAiB,IAAA,CAAK,GAAA;AAAA,UACpB,kCAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,wBAAA,EAA0B,gBAAgB,CAAA;AAAA,QAC3D,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,uBAAA,EAAyB,eAAe;AAAA,OAC3D;AAAA,MACA,KAAA,EAAO;AAAA,QACL,aAAa,IAAA,CAAK,GAAA;AAAA,UAChB,4BAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,uBAAA,EAAyB,eAAe,CAAA;AAAA,QACzD,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,uBAAA,EAAyB,eAAe,CAAA;AAAA,QACzD,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,sBAAA,EAAwB,cAAc;AAAA,OACzD;AAAA,MACA,GAAA,EAAK;AAAA,QACH,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,kBAAA,EAAoB,UAAU,CAAA;AAAA,QAC7C,IAAA,EAAM,SAAS,IAAA,CAAK,GAAA,CAAI,oBAAoB,UAAA,EAAY,IAAI,GAAI,EAAE,CAAA;AAAA,QAClE,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,kBAAA,EAAoB,UAAU,CAAA;AAAA,QAC7C,QAAA,EAAU,IAAA,CAAK,GAAA,CAAI,sBAAA,EAAwB,cAAc,CAAA;AAAA,QACzD,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,oBAAA,EAAsB,YAAY,CAAA,KAAM,MAAA;AAAA,QACzD,OAAA,EAAS,IAAA,CAAK,GAAA,CAAI,sBAAA,EAAwB,cAAc,CAAA;AAAA,QACxD,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,oBAAA,EAAsB,YAAY;AAAA,OACrD;AAAA,MACA,UAAA,EAAY;AAAA,QACV,WAAW,IAAA,CAAK,GAAA;AAAA,UACd,+BAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,4BAAA,EAA8B,oBAAoB,CAAA;AAAA,QACnE,WAAW,IAAA,CAAK,GAAA;AAAA,UACd,+BAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,2BAAA,EAA6B,mBAAmB;AAAA,OACnE;AAAA,MACA,KAAA,EAAO;AAAA,QACL,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,sBAAA,EAAwB,cAAc,CAAA;AAAA,QACvD,OAAA,EAAS,IAAA,CAAK,GAAA,CAAI,wBAAA,EAA0B,gBAAgB;AAAA,OAC9D;AAAA,MACA,KAAA,EAAO;AAAA,QACL,SAAA,EAAW,IAAA,CAAK,GAAA,CAAI,mBAAA,EAAqB,qBAAqB,kBAAkB,CAAA;AAAA,QAChF,OAAA,EAAS,IAAA,CAAK,GAAA,CAAI,mBAAA,EAAqB,qBAAqB,UAAU;AAAA;AACxE,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,cAAA,GAA8B;AAC5B,IAAA,OAAO;AAAA,MACL,QAAA,EAAU,IAAA,CAAK,GAAA,CAAI,gBAAA,EAAkB,kBAAkB,MAAM,CAAA;AAAA,MAC7D,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,iBAAA,EAAmB,WAAW,CAAA;AAAA,MAC7C,IAAA,EAAM,SAAS,IAAA,CAAK,GAAA,CAAI,mBAAmB,WAAA,EAAa,KAAK,GAAI,EAAE,CAAA;AAAA,MACnE,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,mBAAA,EAAqB,aAAa,CAAA,KAAM,MAAA;AAAA,MACzD,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,iBAAA,EAAmB,WAAW,CAAA;AAAA,MAC7C,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,iBAAA,EAAmB,WAAW,CAAA;AAAA,MAC7C,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,iBAAA,EAAmB,aAAa,qBAAqB,CAAA;AAAA,MACpE,QAAA,EAAU,IAAA,CAAK,GAAA,CAAI,sBAAA,EAAwB,kBAAkB,UAAU,CAAA;AAAA,MACvE,OAAA,EAAS,IAAA,CAAK,GAAA,CAAI,qBAAA,EAAuB,eAAe;AAAA,KAC1D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,aAAA,CAAc,KAAa,KAAA,EAA+C;AACxE,IAAA,IAAI,CAAC,OAAO,OAAO,KAAA;AACnB,IAAA,IAAI,cAAA,CAAc,cAAA,CAAe,QAAA,CAAS,GAAG,CAAA,EAAG;AAC9C,MAAA,OAAO,UAAA;AAAA,IACT;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,GAAA,CAAI,GAAA,EAAa,KAAA,EAAe,WAAA,EAAqC;AACzE,IAAA,MAAM,IAAA,CAAK,EAAA,CACR,MAAA,CAAO,QAAc,EACrB,MAAA,CAAO;AAAA,MACN,GAAA;AAAA,MACA,KAAA;AAAA,MACA,WAAA;AAAA,MACA,SAAA,sBAAe,IAAA;AAAK,KACrB,EACA,kBAAA,CAAmB;AAAA,MAClB,MAAA,EAAQ,CAAC,QAAA,CAAe,GAAG,CAAA;AAAA,MAC3B,KAAK,EAAE,KAAA,EAAO,aAAa,SAAA,kBAAW,IAAI,MAAK;AAAE,KAClD,CAAA;AACH,IAAA,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,GAAI,KAAA;AAAA,EACpB;AACF;;;ACvcA,IAAM,gBAAA,GAAmC;AAAA,EACvC,WAAA,EAAa,CAAC,IAAA,EAAM,QAAA,GAAW,MAAA,MAAY;AAAA,IACzC,OAAA,EAAS,2BAAA;AAAA,IACT,IAAA,EAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAAA,EAgBe,QAAQ,CAAA;AAAA;AAAA;AAAA,qBAAA,EAGV,IAAI,CAAA;AAAA;AAAA;AAAA,yDAAA,EAGgC,IAAI,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAAA;AAAA,IAS3D,IAAA,EAAM,WAAW,QAAQ,CAAA;;AAAA,gDAAA,EAAwD,IAAI;;AAAA;;AAAA,kEAAA;AAAA,GACvF,CAAA;AAAA,EAEA,aAAA,EAAe,CAAC,IAAA,EAAM,QAAA,GAAW,MAAA,MAAY;AAAA,IAC3C,OAAA,EAAS,qBAAA;AAAA,IACT,IAAA,EAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAA,EAkBW,QAAQ,CAAA;AAAA;AAAA;AAAA,qBAAA,EAGN,IAAI,CAAA;AAAA;AAAA;AAAA,yDAAA,EAGgC,IAAI,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAAA;AAAA,IAW3D,IAAA,EAAM,CAAA;;AAAA,MAAA,EAAmC,QAAQ,CAAA;;AAAA,wFAAA,EAAgG,IAAI;;AAAA;;AAAA,iEAAA;AAAA,GACvJ,CAAA;AAAA,EAEA,OAAA,EAAS,CAAC,QAAA,GAAW,MAAA,MAAY;AAAA,IAC/B,OAAA,EAAS,qBAAA;AAAA,IACT,IAAA,EAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mCAAA,EAe2B,QAAQ,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAAA;AAAA,IAiBzC,IAAA,EAAM,wBAAwB,QAAQ,CAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA,2CAAA;AAAA,GACxC,CAAA;AAAA,EAEA,aAAA,EAAe,CAAC,QAAA,EAAU,QAAA,EAAU,WAAW,MAAA,MAAY;AAAA,IACzD,OAAA,EAAS,yCAAA;AAAA,IACT,IAAA,EAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAA,EAiBW,QAAQ,CAAA;AAAA;AAAA;AAAA,gCAAA,EAGK,QAAQ,CAAA;AAAA,iCAAA,EACP,IAAA,CAAK,KAAA,CAAM,QAAA,GAAW,GAAK,CAAC,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAAA;AAAA,IAgB3D,IAAA,EAAM,CAAA;;AAAA,MAAA,EAAmC,QAAQ,CAAA;;AAAA,gFAAA,EAAwF,QAAQ,CAAA;;AAAA,kBAAA,EAA2B,IAAA,CAAK,KAAA,CAAM,QAAA,GAAW,GAAK,CAAC,CAAA;;AAAA;;AAAA,iEAAA;AAAA,GAC1M,CAAA;AAAA,EAEA,eAAA,EAAiB,CAAC,QAAA,GAAW,MAAA,MAAY;AAAA,IACvC,OAAA,EAAS,gCAAA;AAAA,IACT,IAAA,EAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAA,EAgBW,QAAQ,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAAA;AAAA,IAUzB,IAAA,EAAM,CAAA;;AAAA,MAAA,EAA6B,QAAQ,CAAA;;AAAA;;AAAA;;AAAA,uEAAA;AAAA,GAC7C,CAAA;AAAA,EAEA,QAAA,EAAU,CAAC,QAAA,EAAU,IAAA,EAAM,WAAW,MAAA,MAAY;AAAA,IAChD,OAAA,EAAS,2BAAA;AAAA,IACT,IAAA,EAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAA,EAiBW,QAAQ,CAAA;AAAA;AAAA;AAAA,0CAAA,EAGe,QAAQ,CAAA;AAAA,sCAAA,EACZ,IAAI,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAAA;AAAA,IAgBxC,IAAA,EAAM,CAAA;;AAAA,MAAA,EAA+B,QAAQ,CAAA;;AAAA;;AAAA,UAAA,EAA8D,QAAQ;AAAA,MAAA,EAAW,IAAI;;AAAA,gFAAA;AAAA,GACpI;AACF,CAAA;AAIO,IAAM,cAAA,GAAN,MAAM,eAAA,CAAe;AAAA,EAClB,WAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,sBAAA,GAAkC,KAAA;AAAA,EAE1C,WAAA,CAAY,QAAqB,SAAA,EAAqC;AACpE,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,SAAA,GAAY,EAAE,GAAG,gBAAA,EAAkB,GAAG,SAAA,EAAU;AAAA,EACvD;AAAA,EAEA,MAAc,iBAAA,GAA2D;AACvE,IAAA,IAAI,KAAK,sBAAA,EAAwB;AAC/B,MAAA,OAAO,IAAA,CAAK,WAAA;AAAA,IACd;AAEA,IAAA,MAAM,EAAE,OAAA,EAAS,UAAA,EAAW,GAAI,MAAM,OAAO,YAAY,CAAA;AAEzD,IAAA,IAAI,KAAK,MAAA,CAAO,QAAA,KAAa,MAAA,IAAU,IAAA,CAAK,OAAO,IAAA,EAAM;AACvD,MAAA,IAAA,CAAK,WAAA,GAAc,WAAW,eAAA,CAAgB;AAAA,QAC5C,IAAA,EAAM,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAA;AAAA,QACvB,IAAA,EAAM,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAA;AAAA,QACvB,MAAA,EAAQ,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,MAAA;AAAA,QACzB,IAAA,EAAM,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK;AAAA,OACxB,CAAA;AAAA,IACH,WAAW,IAAA,CAAK,MAAA,CAAO,aAAa,KAAA,IAAS,IAAA,CAAK,OAAO,GAAA,EAAK;AAC5D,MAAA,IAAA,CAAK,WAAA,GAAc,WAAW,eAAA,CAAgB;AAAA,QAC5C,IAAA,EAAM,CAAA,WAAA,EAAc,IAAA,CAAK,MAAA,CAAO,IAAI,MAAM,CAAA,cAAA,CAAA;AAAA,QAC1C,IAAA,EAAM,GAAA;AAAA,QACN,MAAA,EAAQ,KAAA;AAAA,QACR,IAAA,EAAM;AAAA,UACJ,IAAA,EAAM,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,WAAA;AAAA,UACtB,IAAA,EAAM,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI;AAAA;AACxB,OACD,CAAA;AAAA,IACH;AAEA,IAAA,IAAA,CAAK,sBAAA,GAAyB,IAAA;AAC9B,IAAA,OAAO,IAAA,CAAK,WAAA;AAAA,EACd;AAAA,EAEA,MAAM,KAAK,OAAA,EAAqC;AAC9C,IAAA,MAAM,EAAE,QAAA,EAAU,IAAA,EAAM,UAAU,OAAA,EAAS,aAAA,KAAkB,IAAA,CAAK,MAAA;AAClE,IAAA,MAAM,QAAA,GAAW,CAAA,CAAA,EAAI,QAAA,IAAY,UAAU,MAAM,IAAI,CAAA,CAAA,CAAA;AACrD,IAAA,MAAM,OAAA,GAAU,QAAQ,OAAA,IAAW,aAAA;AAInC,IAAA,IAAI;AACF,MAAA,IAAI,MAAA;AACJ,MAAA,QAAQ,QAAA;AAAU,QAChB,KAAK,MAAA;AAAA,QACL,KAAK,KAAA;AACH,UAAA;AACE,YAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,iBAAA,EAAkB;AACjD,YAAA,IAAI,CAAC,WAAA;AACH,cAAA,MAAM,IAAI,KAAA,CAAM,CAAA,EAAG,QAAQ,CAAA,4BAAA,CAA8B,CAAA;AAC3D,YAAA,MAAA,GAAS,MAAM,YAAY,QAAA,CAAS;AAAA,cAClC,IAAA,EAAM,QAAA;AAAA,cACN,EAAA,EAAI,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ,EAAE,CAAA,GACxB,OAAA,CAAQ,EAAA,CAAG,IAAA,CAAK,IAAI,CAAA,GACpB,OAAA,CAAQ,EAAA;AAAA,cACZ,SAAS,OAAA,CAAQ,OAAA;AAAA,cACjB,MAAM,OAAA,CAAQ,IAAA;AAAA,cACd,MAAM,OAAA,CAAQ,IAAA;AAAA,cACd;AAAA,aACD,CAAA;AAAA,UACH;AACA,UAAA;AAAA,QAEF,KAAK,QAAA;AACH,UAAA,MAAA,GAAS,MAAM,IAAA,CAAK,aAAA,CAAc,QAAA,EAAU,SAAS,OAAO,CAAA;AAC5D,UAAA;AAAA,QAEF,KAAK,UAAA;AACH,UAAA,MAAA,GAAS,MAAM,IAAA,CAAK,eAAA,CAAgB,QAAA,EAAU,SAAS,OAAO,CAAA;AAC9D,UAAA;AAAA,QAEF,KAAK,SAAA;AACH,UAAA,MAAA,GAAS,MAAM,IAAA,CAAK,cAAA,CAAe,QAAA,EAAU,SAAS,OAAO,CAAA;AAC7D,UAAA;AAAA,QAEF;AACE,UAAA,MAAM,IAAI,KAAA,CAAM,CAAA,4BAAA,EAA+B,QAAQ,CAAA,CAAE,CAAA;AAAA;AAG7D,MAAA,OAAO,MAAA;AAAA,IACT,SAAS,KAAA,EAAY;AACnB,MAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,sCAAA,CAAA,EAA0C,KAAA,CAAM,OAAO,CAAA;AACrE,MAAA,IAAI,MAAM,QAAA,EAAU;AAClB,QAAA,OAAA,CAAQ,KAAA;AAAA,UACN,CAAA,uCAAA,CAAA;AAAA,UACA,IAAA,CAAK,SAAA,CAAU,KAAA,CAAM,QAAA,EAAU,MAAM,CAAC;AAAA,SACxC;AAAA,MACF;AACA,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAc,aAAA,CACZ,IAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,MAAA,EAAQ,MAAA;AACnC,IAAA,IAAI,CAAC,MAAA,EAAQ,MAAM,IAAI,MAAM,wBAAwB,CAAA;AAErD,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,IAAA;AAAA,MACA,IAAI,OAAA,CAAQ,EAAA;AAAA,MACZ,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,MAAM,OAAA,CAAQ,IAAA;AAAA,MACd,MAAM,OAAA,CAAQ,IAAA;AAAA,MACd,QAAA,EAAU;AAAA,KACZ;AAGA,IAAA,MAAM,IAAA,GAAO,MAAM,KAAA,CAAM,+BAAA,EAAiC;AAAA,MACxD,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,aAAA,EAAe,UAAU,MAAM,CAAA,CAAA;AAAA,QAC/B,cAAA,EAAgB;AAAA,OAClB;AAAA,MACA,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAI;AAAA,KAC1B,CAAA;AAED,IAAA,IAAI,CAAC,KAAK,EAAA,EAAI;AACZ,MAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,IAAA,EAAK;AAC9B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,cAAA,EAAiB,KAAK,SAAA,CAAU,KAAK,CAAC,CAAA,CAAE,CAAA;AAAA,IAC1D;AACA,IAAA,OAAO,KAAK,IAAA,EAAK;AAAA,EACnB;AAAA,EAEA,MAAc,eAAA,CACZ,IAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,QAAA,EAAU,MAAA;AACrC,IAAA,IAAI,CAAC,MAAA,EAAQ,MAAM,IAAI,MAAM,0BAA0B,CAAA;AAEvD,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,gBAAA,EAAkB;AAAA,QAChB;AAAA,UACE,EAAA,EAAI,MAAM,OAAA,CAAQ,OAAA,CAAQ,EAAE,CAAA,GACxB,OAAA,CAAQ,GAAG,GAAA,CAAI,CAAC,WAAW,EAAE,KAAA,GAAQ,CAAA,GACrC,CAAC,EAAE,KAAA,EAAO,OAAA,CAAQ,IAAI;AAAA;AAC5B,OACF;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,OAAO,IAAA,CAAK,KAAA,CAAM,QAAQ,CAAA,GAAI,CAAC,CAAA,IAAK,IAAA;AAAA,QACpC,IAAA,EAAM,IAAA,CAAK,KAAA,CAAM,QAAQ,IAAI,CAAC;AAAA,OAChC;AAAA,MACA,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,OAAA,EAAS;AAAA,QACP,EAAE,IAAA,EAAM,YAAA,EAAc,KAAA,EAAO,OAAA,CAAQ,QAAQ,EAAA,EAAG;AAAA,QAChD,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,QAAQ,IAAA;AAAK,OAC3C;AAAA,MACA,QAAA,EAAU,OAAA,GAAU,EAAE,KAAA,EAAO,SAAQ,GAAI;AAAA,KAC3C;AAGA,IAAA,MAAM,IAAA,GAAO,MAAM,KAAA,CAAM,uCAAA,EAAyC;AAAA,MAChE,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,aAAA,EAAe,UAAU,MAAM,CAAA,CAAA;AAAA,QAC/B,cAAA,EAAgB;AAAA,OAClB;AAAA,MACA,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAI;AAAA,KAC1B,CAAA;AAED,IAAA,IAAI,CAAC,KAAK,EAAA,EAAI;AACZ,MAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,IAAA,EAAK;AAC9B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB,KAAK,SAAA,CAAU,KAAK,CAAC,CAAA,CAAE,CAAA;AAAA,IAC5D;AACA,IAAA,OAAO,EAAE,SAAS,IAAA,EAAK;AAAA,EACzB;AAAA,EAEA,MAAc,cAAA,CACZ,IAAA,EACA,OAAA,EACA,OAAA,EACA;AACA,IAAA,MAAM,EAAE,QAAQ,MAAA,EAAQ,MAAA,KAAW,IAAA,CAAK,MAAA,CAAO,WAAW,EAAC;AAC3D,IAAA,IAAI,CAAC,MAAA,IAAU,CAAC,QAAQ,MAAM,IAAI,MAAM,wBAAwB,CAAA;AAEhE,IAAA,MAAM,IAAA,GAAO,MAAA,KAAW,IAAA,GAAO,oBAAA,GAAuB,iBAAA;AACtD,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,CAAA,IAAA,EAAO,MAAM,CAAA,CAAE,CAAA;AAEjC,IAAA,MAAM,QAAA,GAAW,IAAI,eAAA,EAAgB;AACrC,IAAA,QAAA,CAAS,MAAA,CAAO,QAAQ,IAAI,CAAA;AAC5B,IAAA,MAAM,EAAA,GAAK,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ,EAAE,CAAA,GAAI,OAAA,CAAQ,EAAA,CAAG,IAAA,CAAK,IAAI,CAAA,GAAI,OAAA,CAAQ,EAAA;AACvE,IAAA,QAAA,CAAS,MAAA,CAAO,MAAM,EAAE,CAAA;AACxB,IAAA,QAAA,CAAS,MAAA,CAAO,SAAA,EAAW,OAAA,CAAQ,OAAO,CAAA;AAC1C,IAAA,QAAA,CAAS,MAAA,CAAO,MAAA,EAAQ,OAAA,CAAQ,IAAI,CAAA;AACpC,IAAA,IAAI,QAAQ,IAAA,EAAM,QAAA,CAAS,MAAA,CAAO,MAAA,EAAQ,QAAQ,IAAI,CAAA;AACtD,IAAA,IAAI,OAAA,EAAS,QAAA,CAAS,MAAA,CAAO,YAAA,EAAc,OAAO,CAAA;AAGlD,IAAA,MAAM,OAAO,MAAM,KAAA,CAAM,WAAW,IAAI,CAAA,IAAA,EAAO,MAAM,CAAA,SAAA,CAAA,EAAa;AAAA,MAChE,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,aAAA,EAAe,SAAS,IAAI,CAAA,CAAA;AAAA,QAC5B,cAAA,EAAgB;AAAA,OAClB;AAAA,MACA,IAAA,EAAM;AAAA,KACP,CAAA;AAED,IAAA,IAAI,CAAC,KAAK,EAAA,EAAI;AACZ,MAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,IAAA,EAAK;AAC9B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,eAAA,EAAkB,KAAK,SAAA,CAAU,KAAK,CAAC,CAAA,CAAE,CAAA;AAAA,IAC3D;AACA,IAAA,OAAO,KAAK,IAAA,EAAK;AAAA,EACnB;AAAA,EAEA,YAAA,GAA+B;AAC7B,IAAA,OAAO,IAAA,CAAK,SAAA;AAAA,EACd;AAAA,EAEA,MAAM,gBAAA,GAAqC;AACzC,IAAA,IAAI,KAAK,MAAA,CAAO,QAAA,KAAa,UAAU,IAAA,CAAK,MAAA,CAAO,aAAa,KAAA,EAAO;AACrE,MAAA,IAAI;AACF,QAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,iBAAA,EAAkB;AACjD,QAAA,IAAI,WAAA,EAAa;AACf,UAAA,MAAM,YAAY,MAAA,EAAO;AACzB,UAAA,OAAO,IAAA;AAAA,QACT;AAAA,MACF,CAAA,CAAA,MAAQ;AACN,QAAA,OAAO,KAAA;AAAA,MACT;AAAA,IACF;AACA,IAAA,OAAO,CAAC,EACN,IAAA,CAAK,MAAA,CAAO,MAAA,EAAQ,MAAA,IACpB,IAAA,CAAK,MAAA,CAAO,QAAA,EAAU,MAAA,IACtB,IAAA,CAAK,MAAA,CAAO,OAAA,EAAS,MAAA,CAAA;AAAA,EAEzB;AAAA,EAEA,aAAa,WAAW,EAAA,EAAyC;AAC/D,IAAA,MAAM,aAAA,GAAgB,IAAI,aAAA,CAAc,EAAE,CAAA;AAC1C,IAAA,MAAM,cAAc,IAAA,EAAK;AACzB,IAAA,MAAM,MAAA,GAAS,cAAc,cAAA,EAAe;AAE5C,IAAA,IAAI,CAAC,OAAO,QAAA,EAAU;AACpB,MAAA,OAAO,KAAK,OAAA,EAAQ;AAAA,IACtB;AAEA,IAAA,MAAM,WAAA,GAA2B;AAAA,MAC/B,QAAA,EAAW,OAAO,QAAA,IAAoB,MAAA;AAAA,MACtC,IAAA,EAAM,OAAO,IAAA,IAAQ,qBAAA;AAAA,MACrB,UAAU,MAAA,CAAO,QAAA;AAAA,MACjB,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,IAAA,EACE,MAAA,CAAO,QAAA,KAAa,MAAA,GAChB;AAAA,QACE,IAAA,EAAM,OAAO,IAAA,IAAQ,EAAA;AAAA,QACrB,IAAA,EAAM,OAAO,IAAA,IAAQ,GAAA;AAAA,QACrB,MAAA,EAAQ,OAAO,MAAA,IAAU,KAAA;AAAA,QACzB,IAAA,EAAM,EAAE,IAAA,EAAM,MAAA,CAAO,QAAQ,EAAA,EAAI,IAAA,EAAM,MAAA,CAAO,IAAA,IAAQ,EAAA;AAAG,OAC3D,GACA,MAAA;AAAA,MACN,MAAA,EACE,OAAO,QAAA,KAAa,QAAA,GAChB,EAAE,MAAA,EAAQ,MAAA,CAAO,IAAA,IAAQ,EAAA,EAAG,GAC5B,MAAA;AAAA,MACN,QAAA,EACE,OAAO,QAAA,KAAa,UAAA,GAChB,EAAE,MAAA,EAAQ,MAAA,CAAO,IAAA,IAAQ,EAAA,EAAG,GAC5B,MAAA;AAAA,MACN,OAAA,EACE,MAAA,CAAO,QAAA,KAAa,SAAA,GAChB;AAAA,QACE,MAAA,EAAQ,OAAO,IAAA,IAAQ,EAAA;AAAA,QACvB,MAAA,EAAQ,OAAO,IAAA,IAAQ,EAAA;AAAA,QACvB,MAAA,EAAS,MAAA,CAAO,MAAA,GAAS,IAAA,GAAO;AAAA,OAClC,GACA,MAAA;AAAA,MACN,GAAA,EACE,MAAA,CAAO,QAAA,KAAa,KAAA,GAChB;AAAA,QACE,WAAA,EAAa,OAAO,IAAA,IAAQ,EAAA;AAAA,QAC5B,eAAA,EAAiB,OAAO,IAAA,IAAQ,EAAA;AAAA,QAChC,MAAA,EAAQ,OAAO,IAAA,IAAQ;AAAA,OACzB,GACA;AAAA,KACR;AAEA,IAAA,OAAO,IAAI,gBAAe,WAAW,CAAA;AAAA,EACvC;AAAA,EAEA,OAAO,OAAA,GAAiC;AACtC,IAAA,MAAM,QAAA,GAAY,OAAA,CAAQ,GAAA,CAAI,cAAA,IAA0B,MAAA;AACxD,IAAA,MAAM,OACJ,OAAA,CAAQ,GAAA,CAAI,SAAA,IACZ,OAAA,CAAQ,IAAI,YAAA,IACZ,qBAAA;AACF,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,GAAA,CAAI,cAAA,IAAkB,UAAA;AAC/C,IAAA,MAAM,OAAA,GAAU,QAAQ,GAAA,CAAI,aAAA;AAE5B,IAAA,IAAI,aAAa,MAAA,EAAQ;AACvB,MAAA,MAAM,IAAA,GAAO,QAAQ,GAAA,CAAI,SAAA;AACzB,MAAA,MAAM,IAAA,GAAO,QAAQ,GAAA,CAAI,SAAA;AACzB,MAAA,MAAM,IAAA,GAAO,QAAQ,GAAA,CAAI,SAAA;AACzB,MAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,IAAA,IAAQ,CAAC,MAAM,OAAO,IAAA;AAEpC,MAAA,OAAO,IAAI,eAAA,CAAe;AAAA,QACxB,QAAA,EAAU,MAAA;AAAA,QACV,IAAA;AAAA,QACA,QAAA;AAAA,QACA,OAAA;AAAA,QACA,IAAA,EAAM;AAAA,UACJ,IAAA;AAAA,UACA,MAAM,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,SAAA,IAAa,OAAO,EAAE,CAAA;AAAA,UACjD,MAAA,EAAQ,OAAA,CAAQ,GAAA,CAAI,WAAA,KAAgB,MAAA;AAAA,UACpC,IAAA,EAAM,EAAE,IAAA,EAAM,IAAA;AAAK;AACrB,OACD,CAAA;AAAA,IACH;AAEA,IAAA,IAAI,aAAa,QAAA,EAAU;AACzB,MAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,cAAA,IAAkB,QAAQ,GAAA,CAAI,SAAA;AACzD,MAAA,IAAI,CAAC,QAAQ,OAAO,IAAA;AACpB,MAAA,OAAO,IAAI,eAAA,CAAe;AAAA,QACxB,QAAA,EAAU,QAAA;AAAA,QACV,IAAA;AAAA,QACA,QAAA;AAAA,QACA,OAAA;AAAA,QACA,MAAA,EAAQ,EAAE,MAAA;AAAO,OAClB,CAAA;AAAA,IACH;AAEA,IAAA,IAAI,aAAa,UAAA,EAAY;AAC3B,MAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,gBAAA,IAAoB,QAAQ,GAAA,CAAI,SAAA;AAC3D,MAAA,IAAI,CAAC,QAAQ,OAAO,IAAA;AACpB,MAAA,OAAO,IAAI,eAAA,CAAe;AAAA,QACxB,QAAA,EAAU,UAAA;AAAA,QACV,IAAA;AAAA,QACA,QAAA;AAAA,QACA,OAAA;AAAA,QACA,QAAA,EAAU,EAAE,MAAA;AAAO,OACpB,CAAA;AAAA,IACH;AAEA,IAAA,IAAI,aAAa,SAAA,EAAW;AAC1B,MAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,eAAA,IAAmB,QAAQ,GAAA,CAAI,SAAA;AAC1D,MAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,cAAA,IAAkB,QAAQ,GAAA,CAAI,SAAA;AACzD,MAAA,IAAI,CAAC,MAAA,IAAU,CAAC,MAAA,EAAQ,OAAO,IAAA;AAC/B,MAAA,OAAO,IAAI,eAAA,CAAe;AAAA,QACxB,QAAA,EAAU,SAAA;AAAA,QACV,IAAA;AAAA,QACA,QAAA;AAAA,QACA,OAAA;AAAA,QACA,OAAA,EAAS;AAAA,UACP,MAAA;AAAA,UACA,MAAA;AAAA,UACA,MAAA,EAAS,QAAQ,GAAA,CAAI,cAAA,KAClB,QAAQ,GAAA,CAAI,WAAA,KAAgB,SAAS,IAAA,GAAO,IAAA;AAAA;AACjD,OACD,CAAA;AAAA,IACH;AAEA,IAAA,IAAI,aAAa,KAAA,EAAO;AACtB,MAAA,MAAM,WAAA,GACJ,OAAA,CAAQ,GAAA,CAAI,iBAAA,IAAqB,QAAQ,GAAA,CAAI,SAAA;AAC/C,MAAA,MAAM,eAAA,GACJ,OAAA,CAAQ,GAAA,CAAI,qBAAA,IAAyB,QAAQ,GAAA,CAAI,SAAA;AACnD,MAAA,MAAM,SACJ,OAAA,CAAQ,GAAA,CAAI,UAAA,IAAc,OAAA,CAAQ,IAAI,SAAA,IAAa,WAAA;AACrD,MAAA,IAAI,CAAC,WAAA,IAAe,CAAC,eAAA,EAAiB,OAAO,IAAA;AAC7C,MAAA,OAAO,IAAI,eAAA,CAAe;AAAA,QACxB,QAAA,EAAU,KAAA;AAAA,QACV,IAAA;AAAA,QACA,QAAA;AAAA,QACA,OAAA;AAAA,QACA,GAAA,EAAK,EAAE,WAAA,EAAa,eAAA,EAAiB,MAAA;AAAO,OAC7C,CAAA;AAAA,IACH;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AACF;;;AC9pBO,IAAM,uBAAA,GAAgD;AAAA,EAC3D,SAAA,EAAW,EAAA;AAAA,EACX,gBAAA,EAAkB,IAAA;AAAA,EAClB,gBAAA,EAAkB,IAAA;AAAA,EAClB,cAAA,EAAgB,IAAA;AAAA,EAChB,mBAAA,EAAqB,IAAA;AAAA,EACrB,YAAA,EAAc,CAAA;AAAA,EACd,SAAA,EAAW;AACb,CAAA;AAEO,IAAM,iBAAN,MAAqB;AAAA,EAClB,MAAA;AAAA,EAER,WAAA,CAAY,MAAA,GAAwC,EAAC,EAAG;AACtD,IAAA,IAAA,CAAK,MAAA,GAAS,EAAE,GAAG,uBAAA,EAAyB,GAAG,MAAA,EAAO;AAAA,EACxD;AAAA,EAEA,SAAS,QAAA,EAAoC;AAC3C,IAAA,MAAM,SAAmB,EAAC;AAE1B,IAAA,IAAI,KAAK,MAAA,CAAO,SAAA,IAAa,SAAS,MAAA,GAAS,IAAA,CAAK,OAAO,SAAA,EAAW;AACpE,MAAA,MAAA,CAAO,IAAA;AAAA,QACL,CAAA,yBAAA,EAA4B,IAAA,CAAK,MAAA,CAAO,SAAS,CAAA,WAAA;AAAA,OACnD;AAAA,IACF;AAEA,IAAA,IAAI,QAAA,CAAS,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,SAAA,EAAW;AAC3C,MAAA,MAAA,CAAO,IAAA;AAAA,QACL,CAAA,0BAAA,EAA6B,IAAA,CAAK,MAAA,CAAO,SAAS,CAAA,WAAA;AAAA,OACpD;AAAA,IACF;AAEA,IAAA,IAAI,KAAK,MAAA,CAAO,gBAAA,IAAoB,CAAC,OAAA,CAAQ,IAAA,CAAK,QAAQ,CAAA,EAAG;AAC3D,MAAA,MAAA,CAAO,KAAK,qDAAqD,CAAA;AAAA,IACnE;AAEA,IAAA,IAAI,KAAK,MAAA,CAAO,gBAAA,IAAoB,CAAC,OAAA,CAAQ,IAAA,CAAK,QAAQ,CAAA,EAAG;AAC3D,MAAA,MAAA,CAAO,KAAK,qDAAqD,CAAA;AAAA,IACnE;AAEA,IAAA,IAAI,KAAK,MAAA,CAAO,cAAA,IAAkB,CAAC,OAAA,CAAQ,IAAA,CAAK,QAAQ,CAAA,EAAG;AACzD,MAAA,MAAA,CAAO,KAAK,2CAA2C,CAAA;AAAA,IACzD;AAEA,IAAA,IACE,KAAK,MAAA,CAAO,mBAAA,IACZ,CAAC,uCAAA,CAAwC,IAAA,CAAK,QAAQ,CAAA,EACtD;AACA,MAAA,MAAA,CAAO,KAAK,sDAAsD,CAAA;AAAA,IACpE;AAEA,IAAA,MAAM,eAAA,GAAkB;AAAA,MACtB,UAAA;AAAA,MACA,QAAA;AAAA,MACA,UAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAA;AAAA,MACA,SAAA;AAAA,MACA,SAAA;AAAA,MACA,UAAA;AAAA,MACA,QAAA;AAAA,MACA,UAAA;AAAA,MACA,UAAA;AAAA,MACA,QAAA;AAAA,MACA,UAAA;AAAA,MACA,QAAA;AAAA,MACA,UAAA;AAAA,MACA,WAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,IAAI,eAAA,CAAgB,QAAA,CAAS,QAAA,CAAS,WAAA,EAAa,CAAA,EAAG;AACpD,MAAA,MAAA,CAAO,IAAA;AAAA,QACL;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAI,cAAc,IAAA,CAAK,QAAQ,KAAK,UAAA,CAAW,IAAA,CAAK,QAAQ,CAAA,EAAG;AAC7D,MAAA,MAAA,CAAO,IAAA;AAAA,QACL;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAI,WAAA,CAAY,IAAA,CAAK,QAAQ,CAAA,EAAG;AAC9B,MAAA,MAAA,CAAO,IAAA;AAAA,QACL;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IACE,+EAAA,CAAgF,IAAA;AAAA,MAC9E;AAAA,KACF,EACA;AACA,MAAA,MAAA,CAAO,KAAK,yDAAyD,CAAA;AAAA,IACvE;AAEA,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,OAAO,MAAA,KAAW,CAAA;AAAA,MACzB;AAAA,KACF;AAAA,EACF;AAAA,EAEA,MAAM,UAAA,CACJ,YAAA,EACA,OAAA,EACA,QAAA,EAC2B;AAC3B,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,IAAA;AAAA,MACP,QAAQ;AAAC,KACX;AAAA,EACF;AAAA,EAEA,MAAM,WAAA,CACJ,QAAA,EACA,OAAA,EACA,QAAA,EACkB;AAClB,IAAA,KAAA,MAAW,QAAQ,OAAA,EAAS;AAC1B,MAAA,IAAI,MAAM,QAAA,CAAS,QAAA,EAAU,IAAI,CAAA,EAAG;AAClC,QAAA,OAAO,IAAA;AAAA,MACT;AAAA,IACF;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEA,gBAAA,CAAiB,SAAiB,EAAA,EAAY;AAC5C,IAAA,MAAM,SAAA,GAAY,4BAAA;AAClB,IAAA,MAAM,SAAA,GAAY,4BAAA;AAClB,IAAA,MAAM,OAAA,GAAU,YAAA;AAChB,IAAA,MAAM,OAAA,GAAU,4BAAA;AAEhB,IAAA,IAAI,QAAA,GAAW,EAAA;AAEf,IAAA,QAAA,IAAY,SAAA,CAAU,KAAK,KAAA,CAAM,IAAA,CAAK,QAAO,GAAI,SAAA,CAAU,MAAM,CAAC,CAAA;AAClE,IAAA,QAAA,IAAY,SAAA,CAAU,KAAK,KAAA,CAAM,IAAA,CAAK,QAAO,GAAI,SAAA,CAAU,MAAM,CAAC,CAAA;AAClE,IAAA,QAAA,IAAY,OAAA,CAAQ,KAAK,KAAA,CAAM,IAAA,CAAK,QAAO,GAAI,OAAA,CAAQ,MAAM,CAAC,CAAA;AAC9D,IAAA,QAAA,IAAY,OAAA,CAAQ,KAAK,KAAA,CAAM,IAAA,CAAK,QAAO,GAAI,OAAA,CAAQ,MAAM,CAAC,CAAA;AAE9D,IAAA,MAAM,QAAA,GAAW,SAAA,GAAY,SAAA,GAAY,OAAA,GAAU,OAAA;AACnD,IAAA,KAAA,IAAS,CAAA,GAAI,QAAA,CAAS,MAAA,EAAQ,CAAA,GAAI,QAAQ,CAAA,EAAA,EAAK;AAC7C,MAAA,QAAA,IAAY,QAAA,CAAS,KAAK,KAAA,CAAM,IAAA,CAAK,QAAO,GAAI,QAAA,CAAS,MAAM,CAAC,CAAA;AAAA,IAClE;AAEA,IAAA,OAAO,QAAA,CACJ,KAAA,CAAM,EAAE,CAAA,CACR,IAAA,CAAK,MAAM,IAAA,CAAK,MAAA,EAAO,GAAI,GAAG,CAAA,CAC9B,IAAA,CAAK,EAAE,CAAA;AAAA,EACZ;AAAA,EAEA,YAAY,QAAA,EAIV;AACA,IAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,IAAA,MAAM,WAAqB,EAAC;AAE5B,IAAA,IAAI,QAAA,CAAS,MAAA,IAAU,CAAA,EAAG,KAAA,IAAS,CAAA;AACnC,IAAA,IAAI,QAAA,CAAS,MAAA,IAAU,EAAA,EAAI,KAAA,IAAS,CAAA;AACpC,IAAA,IAAI,QAAA,CAAS,MAAA,IAAU,EAAA,EAAI,KAAA,IAAS,CAAA;AAEpC,IAAA,IAAI,OAAA,CAAQ,IAAA,CAAK,QAAQ,CAAA,EAAG,KAAA,IAAS,CAAA;AACrC,IAAA,IAAI,OAAA,CAAQ,IAAA,CAAK,QAAQ,CAAA,EAAG,KAAA,IAAS,CAAA;AACrC,IAAA,IAAI,OAAA,CAAQ,IAAA,CAAK,QAAQ,CAAA,EAAG,KAAA,IAAS,CAAA;AACrC,IAAA,IAAI,iCAAA,CAAkC,IAAA,CAAK,QAAQ,CAAA,EAAG,KAAA,IAAS,CAAA;AAE/D,IAAA,IAAI,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG,KAAA,IAAS,CAAA;AAClC,IAAA,IAAI,QAAA,CAAS,MAAA,GAAS,EAAA,EAAI,KAAA,IAAS,CAAA;AAEnC,IAAA,MAAM,WAAA,GAAc,IAAI,GAAA,CAAI,QAAQ,CAAA,CAAE,IAAA;AACtC,IAAA,IAAI,WAAA,GAAc,GAAG,KAAA,IAAS,CAAA;AAC9B,IAAA,IAAI,WAAA,GAAc,IAAI,KAAA,IAAS,CAAA;AAE/B,IAAA,IAAI,KAAA;AACJ,IAAA,IAAI,SAAS,CAAA,EAAG;AACd,MAAA,KAAA,GAAQ,MAAA;AACR,MAAA,QAAA,CAAS,KAAK,qBAAqB,CAAA;AACnC,MAAA,QAAA,CAAS,KAAK,yCAAyC,CAAA;AAAA,IACzD,CAAA,MAAA,IAAW,SAAS,CAAA,EAAG;AACrB,MAAA,KAAA,GAAQ,MAAA;AACR,MAAA,QAAA,CAAS,KAAK,wBAAwB,CAAA;AACtC,MAAA,QAAA,CAAS,KAAK,2BAA2B,CAAA;AAAA,IAC3C,CAAA,MAAA,IAAW,SAAS,CAAA,EAAG;AACrB,MAAA,KAAA,GAAQ,MAAA;AACR,MAAA,QAAA,CAAS,KAAK,8CAA8C,CAAA;AAAA,IAC9D,CAAA,MAAO;AACL,MAAA,KAAA,GAAQ,QAAA;AAAA,IACV;AAEA,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,QAAA,EAAS;AAAA,EAClC;AAAA,EAEA,UAAU,MAAA,EAA6C;AACrD,IAAA,IAAA,CAAK,SAAS,EAAE,GAAG,IAAA,CAAK,MAAA,EAAQ,GAAG,MAAA,EAAO;AAAA,EAC5C;AAAA,EAEA,SAAA,GAAkC;AAChC,IAAA,OAAO,EAAE,GAAG,IAAA,CAAK,MAAA,EAAO;AAAA,EAC1B;AACF","file":"chunk-N5QSHUA6.js","sourcesContent":["import { eq } from \"drizzle-orm\";\nimport { settings as settingsSchema } from \"../database/drizzle/schema/settings.js\";\n\nlet _settingsTableEnsured = false;\n\nexport interface S3CompatibleConfig {\n bucket?: string;\n region?: string;\n accessKeyId?: string;\n secretAccessKey?: string;\n endpoint?: string;\n cdnUrl?: string;\n prefix?: string;\n}\n\nexport interface R2Config {\n accountId?: string;\n accessKeyId?: string;\n secretAccessKey?: string;\n bucket?: string;\n cdnUrl?: string;\n prefix?: string;\n publicDevUrl?: string;\n}\n\nexport interface GCSConfig {\n bucket?: string;\n projectId?: string;\n clientEmail?: string;\n privateKey?: string;\n cdnUrl?: string;\n prefix?: string;\n}\n\nexport interface BackblazeConfig {\n bucket?: string;\n accountId?: string;\n applicationKeyId?: string;\n applicationKey?: string;\n cdnUrl?: string;\n prefix?: string;\n}\n\nexport interface BunnyConfig {\n storageZone?: string;\n apiKey?: string;\n cdnUrl?: string;\n prefix?: string;\n}\n\nexport interface FTPConfig {\n host?: string;\n port?: number;\n user?: string;\n password?: string;\n secure?: boolean;\n baseUrl?: string;\n prefix?: string;\n}\n\nexport interface StorageConfig {\n type: string;\n s3: S3CompatibleConfig;\n r2: R2Config;\n gcs: GCSConfig;\n digitalocean: S3CompatibleConfig;\n backblaze: BackblazeConfig;\n wasabi: S3CompatibleConfig;\n bunny: BunnyConfig;\n ftp: FTPConfig;\n cloudinary: {\n cloudName?: string;\n apiKey?: string;\n apiSecret?: string;\n folder?: string;\n };\n imgix: {\n domain?: string;\n signKey?: string;\n };\n local: {\n uploadDir?: string;\n baseUrl?: string;\n };\n}\n\nexport interface EmailConfig {\n provider?: string;\n host?: string;\n port?: number;\n secure?: boolean;\n user?: string;\n pass?: string;\n from?: string;\n fromName?: string;\n replyTo?: string;\n}\n\nexport class ConfigService {\n private db: any;\n private cache: Record<string, string> = {};\n private loaded = false;\n private static readonly SENSITIVE_KEYS = [\n \"storage.s3.secret_access_key\",\n \"storage.r2.secret_access_key\",\n \"storage.gcs.private_key\",\n \"storage.backblaze.application_key\",\n \"storage.wasabi.secret_access_key\",\n \"storage.ftp.password\",\n \"storage.bunny.api_key\",\n \"storage.cloudinary.api_secret\",\n \"storage.imgix.sign_key\",\n \"email.smtp.pass\",\n \"auth.jwt_secret\",\n \"auth.github_secret\",\n \"auth.google_secret\",\n \"auth.app_secret\",\n \"database.url\",\n \"redis.url\",\n \"auth.admin_password\",\n ];\n\n constructor(db: any) {\n this.db = db;\n }\n\n /**\n * Initialize the service by loading all settings from the database\n */\n async load(): Promise<void> {\n if (this.loaded) return;\n\n await this.ensureSettingsTable();\n\n try {\n if (typeof this.db?.select === \"function\") {\n const allSettings = await this.db.select().from(settingsSchema);\n this.cache = allSettings.reduce((acc: any, row: any) => {\n acc[row.key] = row.value;\n return acc;\n }, {});\n }\n \n // Always try to load from globals to pick up CMS-configured storage settings\n await this.loadFromGlobals();\n } catch (error) {\n console.warn(\n \"ConfigService: Could not load settings from database, using environment fallbacks.\",\n );\n }\n\n this.loaded = true;\n }\n\n private async ensureSettingsTable(): Promise<void> {\n if (_settingsTableEnsured) return;\n\n try {\n if (typeof this.db?.execute === \"function\") {\n const { sql } = await import(\"drizzle-orm\");\n await this.db.execute(sql`\n CREATE TABLE IF NOT EXISTS \"settings\" (\n \"key\" VARCHAR(255) PRIMARY KEY,\n \"value\" TEXT NOT NULL,\n \"description\" TEXT,\n \"updated_at\" TIMESTAMP DEFAULT NOW()\n )\n `);\n _settingsTableEnsured = true;\n } else if (typeof this.db?.exec === \"function\") {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS settings (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n description TEXT,\n updated_at TEXT\n )\n `);\n _settingsTableEnsured = true;\n }\n } catch {\n // Table creation failed — will fall back to env vars\n }\n }\n\n /**\n * Load settings from the _globals_storage-settings table (SQLite fallback)\n * Maps nested global structure to flat key-value cache\n */\n private async loadFromGlobals(): Promise<void> {\n try {\n let row: any = null;\n if (typeof this.db?.execute === \"function\") {\n const { sql } = await import(\"drizzle-orm\");\n const variants = ['\"_globals_storage-settings\"', '\"_globals_storage_settings\"', '\"global_storage_settings\"'];\n for (const name of variants) {\n try {\n const result = await this.db.execute(sql`SELECT * FROM ${sql.raw(name)} LIMIT 1`);\n row = Array.isArray(result) ? result[0] : (result?.rows ? result.rows[0] : null);\n if (row) break;\n } catch {}\n }\n } else if (typeof this.db?.prepare === \"function\") {\n const variants = ['\"_globals_storage-settings\"', '\"_globals_storage_settings\"', '\"global_storage_settings\"'];\n for (const name of variants) {\n try {\n row = this.db.prepare(`SELECT * FROM ${name} LIMIT 1`).get();\n if (row) break;\n } catch {}\n }\n }\n\n if (!row) return;\n\n const parseJSON = (val: any) => {\n if (!val) return null;\n if (typeof val === \"string\") {\n try {\n return JSON.parse(val);\n } catch {\n return null;\n }\n }\n return val;\n };\n\n const provider = row.provider || \"local\";\n this.cache[\"storage.type\"] = provider === \"aws\" ? \"s3\" : provider;\n\n if (provider === \"local\") {\n const local = parseJSON(row.local);\n this.cache[\"storage.local.dir\"] =\n local?.uploadDir || \"./public/uploads\";\n this.cache[\"storage.local.url\"] = local?.baseUrl || \"/uploads\";\n }\n\n if (provider === \"aws\") {\n const aws = parseJSON(row.aws);\n this.cache[\"storage.s3.bucket\"] = aws?.bucket || \"\";\n this.cache[\"storage.s3.region\"] = aws?.region || \"us-east-1\";\n this.cache[\"storage.s3.access_key_id\"] = aws?.accessKeyId || \"\";\n this.cache[\"storage.s3.secret_access_key\"] = aws?.secretAccessKey || \"\";\n this.cache[\"storage.s3.endpoint\"] = aws?.endpoint || \"\";\n this.cache[\"storage.s3.cdn_url\"] = aws?.cdnUrl || \"\";\n this.cache[\"storage.s3.prefix\"] = aws?.prefix || \"\";\n }\n\n if (provider === \"r2\") {\n const r2 = parseJSON(row.r2);\n this.cache[\"storage.r2.account_id\"] = r2?.accountId || \"\";\n this.cache[\"storage.r2.access_key_id\"] = r2?.accessKeyId || \"\";\n this.cache[\"storage.r2.secret_access_key\"] = r2?.secretAccessKey || \"\";\n this.cache[\"storage.r2.bucket\"] = r2?.bucket || \"\";\n this.cache[\"storage.r2.cdn_url\"] = r2?.cdnUrl || \"\";\n this.cache[\"storage.r2.prefix\"] = r2?.prefix || \"\";\n }\n\n if (provider === \"cloudinary\") {\n const cloudinary = parseJSON(row.cloudinary);\n this.cache[\"storage.cloudinary.cloud_name\"] =\n cloudinary?.cloudName || \"\";\n this.cache[\"storage.cloudinary.api_key\"] = cloudinary?.apiKey || \"\";\n this.cache[\"storage.cloudinary.api_secret\"] =\n cloudinary?.apiSecret || \"\";\n this.cache[\"storage.cloudinary.folder\"] = cloudinary?.folder || \"\";\n }\n\n if (provider === \"ftp\") {\n const ftp = parseJSON(row.ftp);\n this.cache[\"storage.ftp.host\"] = ftp?.host || \"\";\n this.cache[\"storage.ftp.port\"] = String(ftp?.port || \"21\");\n this.cache[\"storage.ftp.user\"] = ftp?.user || \"\";\n this.cache[\"storage.ftp.password\"] = ftp?.password || \"\";\n this.cache[\"storage.ftp.secure\"] = ftp?.secure ? \"true\" : \"false\";\n this.cache[\"storage.ftp.base_url\"] = ftp?.baseUrl || \"\";\n this.cache[\"storage.ftp.prefix\"] = ftp?.prefix || \"\";\n }\n } catch (error) {\n console.warn(\"ConfigService: Could not load storage settings from globals table:\", error);\n }\n\n // Also load email-settings\n try {\n let row: any = null;\n if (typeof this.db?.execute === \"function\") {\n const { sql } = await import(\"drizzle-orm\");\n const variants = ['\"_globals_email-settings\"', '\"_globals_email_settings\"', '\"global_email_settings\"'];\n for (const name of variants) {\n try {\n const result = await this.db.execute(sql`SELECT * FROM ${sql.raw(name)} LIMIT 1`);\n row = Array.isArray(result) ? result[0] : (result?.rows ? result.rows[0] : null);\n if (row) break;\n } catch {}\n }\n } else if (typeof this.db?.prepare === \"function\") {\n const variants = ['\"_globals_email-settings\"', '\"_globals_email_settings\"', '\"global_email_settings\"'];\n for (const name of variants) {\n try {\n row = this.db.prepare(`SELECT * FROM ${name} LIMIT 1`).get();\n if (row) break;\n } catch {}\n }\n }\n\n if (row) {\n const parseJSON = (val: any) => {\n if (!val) return null;\n if (typeof val === \"string\") {\n try { return JSON.parse(val); } catch { return null; }\n }\n return val;\n };\n\n this.cache[\"email.provider\"] = row.provider || \"smtp\";\n this.cache[\"email.smtp.from\"] = row.fromEmail || \"\";\n this.cache[\"email.smtp.from_name\"] = row.fromName || \"\";\n this.cache[\"email.smtp.reply_to\"] = row.replyTo || \"\";\n\n if (row.provider === \"smtp\") {\n const smtp = parseJSON(row.smtp);\n this.cache[\"email.smtp.host\"] = smtp?.host || \"\";\n this.cache[\"email.smtp.port\"] = String(smtp?.port || \"587\");\n this.cache[\"email.smtp.user\"] = smtp?.username || \"\";\n this.cache[\"email.smtp.pass\"] = smtp?.password || \"\";\n this.cache[\"email.smtp.secure\"] = smtp?.secure ? \"true\" : \"false\";\n } else if (row.provider === \"resend\") {\n const resend = parseJSON(row.resend);\n this.cache[\"email.smtp.pass\"] = resend?.apiKey || \"\"; // We might use pass as apiKey\n } else if (row.provider === \"sendgrid\") {\n const sendgrid = parseJSON(row.sendgrid);\n this.cache[\"email.smtp.pass\"] = sendgrid?.apiKey || \"\";\n } else if (row.provider === \"mailgun\") {\n const mailgun = parseJSON(row.mailgun);\n this.cache[\"email.smtp.pass\"] = mailgun?.apiKey || \"\";\n } else if (row.provider === \"ses\") {\n const ses = parseJSON(row.ses);\n this.cache[\"email.smtp.user\"] = ses?.accessKeyId || \"\";\n this.cache[\"email.smtp.pass\"] = ses?.secretAccessKey || \"\";\n }\n }\n } catch (error) {\n console.warn(\"ConfigService: Could not load email settings from globals table:\", error);\n }\n }\n\n /**\n * Get a settings value with environment fallback\n */\n get(key: string, envKey?: string, defaultValue?: string): string | undefined {\n // 1. Check database cache\n if (this.cache[key]) return this.cache[key];\n\n // 2. Check environment variable\n if (envKey && process.env[envKey]) return process.env[envKey];\n\n // 3. Return default\n return defaultValue;\n }\n\n /**\n * Get storage configuration\n */\n getStorageConfig(): StorageConfig {\n return {\n type: this.get(\"storage.type\", \"STORAGE_TYPE\", \"local\")!,\n s3: {\n bucket: this.get(\"storage.s3.bucket\", \"STORAGE_BUCKET\"),\n region: this.get(\"storage.s3.region\", \"STORAGE_REGION\", \"us-east-1\"),\n accessKeyId: this.get(\n \"storage.s3.access_key_id\",\n \"STORAGE_ACCESS_KEY_ID\",\n ),\n secretAccessKey: this.get(\n \"storage.s3.secret_access_key\",\n \"STORAGE_SECRET_ACCESS_KEY\",\n ),\n endpoint: this.get(\"storage.s3.endpoint\", \"STORAGE_ENDPOINT\"),\n cdnUrl: this.get(\"storage.s3.cdn_url\", \"STORAGE_CDN_URL\"),\n prefix: this.get(\"storage.s3.prefix\", \"STORAGE_PREFIX\"),\n },\n r2: {\n accountId: this.get(\"storage.r2.account_id\", \"R2_ACCOUNT_ID\"),\n accessKeyId: this.get(\"storage.r2.access_key_id\", \"R2_ACCESS_KEY_ID\"),\n secretAccessKey: this.get(\n \"storage.r2.secret_access_key\",\n \"R2_SECRET_ACCESS_KEY\",\n ),\n bucket: this.get(\"storage.r2.bucket\", \"R2_BUCKET\"),\n cdnUrl: this.get(\"storage.r2.cdn_url\", \"R2_CDN_URL\"),\n prefix: this.get(\"storage.r2.prefix\", \"R2_PREFIX\"),\n },\n gcs: {\n bucket: this.get(\"storage.gcs.bucket\", \"GCS_BUCKET\"),\n projectId: this.get(\"storage.gcs.project_id\", \"GCS_PROJECT_ID\"),\n clientEmail: this.get(\"storage.gcs.client_email\", \"GCS_CLIENT_EMAIL\"),\n privateKey: this.get(\"storage.gcs.private_key\", \"GCS_PRIVATE_KEY\"),\n cdnUrl: this.get(\"storage.gcs.cdn_url\", \"GCS_CDN_URL\"),\n prefix: this.get(\"storage.gcs.prefix\", \"GCS_PREFIX\"),\n },\n digitalocean: {\n bucket: this.get(\"storage.digitalocean.bucket\", \"DO_BUCKET\"),\n region: this.get(\"storage.digitalocean.region\", \"DO_REGION\", \"nyc3\"),\n accessKeyId: this.get(\n \"storage.digitalocean.access_key_id\",\n \"DO_ACCESS_KEY_ID\",\n ),\n secretAccessKey: this.get(\n \"storage.digitalocean.secret_access_key\",\n \"DO_SECRET_ACCESS_KEY\",\n ),\n cdnUrl: this.get(\"storage.digitalocean.cdn_url\", \"DO_CDN_URL\"),\n prefix: this.get(\"storage.digitalocean.prefix\", \"DO_PREFIX\"),\n },\n backblaze: {\n bucket: this.get(\"storage.backblaze.bucket\", \"BB_BUCKET\"),\n accountId: this.get(\"storage.backblaze.account_id\", \"BB_ACCOUNT_ID\"),\n applicationKeyId: this.get(\n \"storage.backblaze.application_key_id\",\n \"BB_APPLICATION_KEY_ID\",\n ),\n applicationKey: this.get(\n \"storage.backblaze.application_key\",\n \"BB_APPLICATION_KEY\",\n ),\n cdnUrl: this.get(\"storage.backblaze.cdn_url\", \"BB_CDN_URL\"),\n prefix: this.get(\"storage.backblaze.prefix\", \"BB_PREFIX\"),\n },\n wasabi: {\n bucket: this.get(\"storage.wasabi.bucket\", \"WASABI_BUCKET\"),\n region: this.get(\"storage.wasabi.region\", \"WASABI_REGION\", \"us-east-1\"),\n accessKeyId: this.get(\n \"storage.wasabi.access_key_id\",\n \"WASABI_ACCESS_KEY_ID\",\n ),\n secretAccessKey: this.get(\n \"storage.wasabi.secret_access_key\",\n \"WASABI_SECRET_ACCESS_KEY\",\n ),\n cdnUrl: this.get(\"storage.wasabi.cdn_url\", \"WASABI_CDN_URL\"),\n prefix: this.get(\"storage.wasabi.prefix\", \"WASABI_PREFIX\"),\n },\n bunny: {\n storageZone: this.get(\n \"storage.bunny.storage_zone\",\n \"BUNNY_STORAGE_ZONE\",\n ),\n apiKey: this.get(\"storage.bunny.api_key\", \"BUNNY_API_KEY\"),\n cdnUrl: this.get(\"storage.bunny.cdn_url\", \"BUNNY_CDN_URL\"),\n prefix: this.get(\"storage.bunny.prefix\", \"BUNNY_PREFIX\"),\n },\n ftp: {\n host: this.get(\"storage.ftp.host\", \"FTP_HOST\"),\n port: parseInt(this.get(\"storage.ftp.port\", \"FTP_PORT\", \"21\")!, 10),\n user: this.get(\"storage.ftp.user\", \"FTP_USER\"),\n password: this.get(\"storage.ftp.password\", \"FTP_PASSWORD\"),\n secure: this.get(\"storage.ftp.secure\", \"FTP_SECURE\") === \"true\",\n baseUrl: this.get(\"storage.ftp.base_url\", \"FTP_BASE_URL\"),\n prefix: this.get(\"storage.ftp.prefix\", \"FTP_PREFIX\"),\n },\n cloudinary: {\n cloudName: this.get(\n \"storage.cloudinary.cloud_name\",\n \"CLOUDINARY_CLOUD_NAME\",\n ),\n apiKey: this.get(\"storage.cloudinary.api_key\", \"CLOUDINARY_API_KEY\"),\n apiSecret: this.get(\n \"storage.cloudinary.api_secret\",\n \"CLOUDINARY_API_SECRET\",\n ),\n folder: this.get(\"storage.cloudinary.folder\", \"CLOUDINARY_FOLDER\"),\n },\n imgix: {\n domain: this.get(\"storage.imgix.domain\", \"IMGIX_DOMAIN\"),\n signKey: this.get(\"storage.imgix.sign_key\", \"IMGIX_SIGN_KEY\"),\n },\n local: {\n uploadDir: this.get(\"storage.local.dir\", \"STORAGE_LOCAL_DIR\", \"./public/uploads\"),\n baseUrl: this.get(\"storage.local.url\", \"STORAGE_LOCAL_URL\", \"/uploads\"),\n },\n };\n }\n\n /**\n * Get email configuration\n */\n getEmailConfig(): EmailConfig {\n return {\n provider: this.get(\"email.provider\", \"EMAIL_PROVIDER\", \"smtp\"),\n host: this.get(\"email.smtp.host\", \"SMTP_HOST\"),\n port: parseInt(this.get(\"email.smtp.port\", \"SMTP_PORT\", \"587\")!, 10),\n secure: this.get(\"email.smtp.secure\", \"SMTP_SECURE\") === \"true\",\n user: this.get(\"email.smtp.user\", \"SMTP_USER\"),\n pass: this.get(\"email.smtp.pass\", \"SMTP_PASS\"),\n from: this.get(\"email.smtp.from\", \"SMTP_FROM\", \"noreply@example.com\"),\n fromName: this.get(\"email.smtp.from_name\", \"SMTP_FROM_NAME\", \"Kyro CMS\"),\n replyTo: this.get(\"email.smtp.reply_to\", \"SMTP_REPLY_TO\"),\n };\n }\n\n /**\n * Mask sensitive values for display\n */\n maskSensitive(key: string, value: string | undefined): string | undefined {\n if (!value) return value;\n if (ConfigService.SENSITIVE_KEYS.includes(key)) {\n return \"********\";\n }\n return value;\n }\n\n /**\n * Update a setting in the database\n */\n async set(key: string, value: string, description?: string): Promise<void> {\n await this.db\n .insert(settingsSchema)\n .values({\n key,\n value,\n description,\n updatedAt: new Date(),\n })\n .onConflictDoUpdate({\n target: [settingsSchema.key],\n set: { value, description, updatedAt: new Date() },\n });\n this.cache[key] = value;\n }\n}\n","import type { Transporter, SentMessageInfo } from \"nodemailer\";\n\nexport interface EmailConfig {\n provider: \"smtp\" | \"resend\" | \"sendgrid\" | \"mailgun\" | \"ses\";\n from: string;\n fromName?: string;\n replyTo?: string;\n smtp?: {\n host: string;\n port: number;\n secure: boolean;\n auth: {\n user: string;\n pass: string;\n };\n };\n resend?: {\n apiKey: string;\n };\n sendgrid?: {\n apiKey: string;\n };\n mailgun?: {\n apiKey: string;\n domain: string;\n region?: \"us\" | \"eu\";\n };\n ses?: {\n accessKeyId: string;\n secretAccessKey: string;\n region: string;\n };\n}\n\nexport interface EmailOptions {\n to: string | string[];\n subject: string;\n html: string;\n text?: string;\n replyTo?: string;\n}\n\nexport interface EmailTemplates {\n verifyEmail: (\n link: string,\n userName?: string,\n ) => { subject: string; html: string; text: string };\n resetPassword: (\n link: string,\n userName?: string,\n ) => { subject: string; html: string; text: string };\n welcome: (userName?: string) => {\n subject: string;\n html: string;\n text: string;\n };\n accountLocked: (\n attempts: number,\n duration: number,\n userName?: string,\n ) => { subject: string; html: string; text: string };\n passwordChanged: (userName?: string) => {\n subject: string;\n html: string;\n text: string;\n };\n newLogin: (\n location: string,\n time: string,\n userName?: string,\n ) => { subject: string; html: string; text: string };\n}\n\nconst defaultTemplates: EmailTemplates = {\n verifyEmail: (link, userName = \"User\") => ({\n subject: \"Verify your email address\",\n html: `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>Verify Email</title>\n <style>\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; }\n .container { max-width: 600px; margin: 0 auto; padding: 20px; }\n .button { display: inline-block; padding: 12px 24px; background: #0b1222; color: white; text-decoration: none; border-radius: 6px; font-weight: 600; }\n .footer { margin-top: 30px; font-size: 12px; color: #666; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Welcome, ${userName}!</h1>\n <p>Please verify your email address by clicking the button below:</p>\n <p style=\"text-align: center; margin: 30px 0;\">\n <a href=\"${link}\" class=\"button\">Verify Email</a>\n </p>\n <p>Or copy and paste this link into your browser:</p>\n <p style=\"word-break: break-all; color: #666;\">${link}</p>\n <p>This link will expire in 24 hours.</p>\n <div class=\"footer\">\n <p>If you didn't create an account, you can safely ignore this email.</p>\n </div>\n </div>\n </body>\n </html>\n `,\n text: `Welcome ${userName}!\\n\\nPlease verify your email by clicking this link: ${link}\\n\\nThis link will expire in 24 hours.\\n\\nIf you didn't create an account, you can safely ignore this email.`,\n }),\n\n resetPassword: (link, userName = \"User\") => ({\n subject: \"Reset your password\",\n html: `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>Reset Password</title>\n <style>\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; }\n .container { max-width: 600px; margin: 0 auto; padding: 20px; }\n .button { display: inline-block; padding: 12px 24px; background: #dc2626; color: white; text-decoration: none; border-radius: 6px; font-weight: 600; }\n .warning { background: #fef3c7; border: 1px solid #f59e0b; padding: 12px; border-radius: 6px; margin: 20px 0; }\n .footer { margin-top: 30px; font-size: 12px; color: #666; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Password Reset Request</h1>\n <p>Hello ${userName},</p>\n <p>We received a request to reset your password. Click the button below to create a new password:</p>\n <p style=\"text-align: center; margin: 30px 0;\">\n <a href=\"${link}\" class=\"button\">Reset Password</a>\n </p>\n <p>Or copy and paste this link into your browser:</p>\n <p style=\"word-break: break-all; color: #666;\">${link}</p>\n <div class=\"warning\">\n <strong>⚠️ Important:</strong> This link will expire in 1 hour. If you didn't request a password reset, please ignore this email or contact support if you have concerns.\n </div>\n <div class=\"footer\">\n <p>For security reasons, please don't share this email with anyone.</p>\n </div>\n </div>\n </body>\n </html>\n `,\n text: `Password Reset Request\\n\\nHello ${userName},\\n\\nWe received a request to reset your password. Click this link to create a new password: ${link}\\n\\nThis link will expire in 1 hour.\\n\\nIf you didn't request a password reset, please ignore this email.`,\n }),\n\n welcome: (userName = \"User\") => ({\n subject: \"Welcome to Kyro CMS\",\n html: `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>Welcome</title>\n <style>\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; }\n .container { max-width: 600px; margin: 0 auto; padding: 20px; }\n .button { display: inline-block; padding: 12px 24px; background: #0b1222; color: white; text-decoration: none; border-radius: 6px; font-weight: 600; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Welcome to Kyro CMS, ${userName}!</h1>\n <p>Your account has been created successfully.</p>\n <p>You can now:</p>\n <ul>\n <li>Manage your content collections</li>\n <li>Upload and organize media</li>\n <li>Configure settings</li>\n <li>And much more...</li>\n </ul>\n <p style=\"text-align: center; margin: 30px 0;\">\n <a href=\"#\" class=\"button\">Get Started</a>\n </p>\n <p>If you have any questions, feel free to reach out to our support team.</p>\n </div>\n </body>\n </html>\n `,\n text: `Welcome to Kyro CMS, ${userName}!\\n\\nYour account has been created successfully.\\n\\nYou can now:\\n- Manage your content collections\\n- Upload and organize media\\n- Configure settings\\n- And much more...\\n\\nGet started by logging into your dashboard.`,\n }),\n\n accountLocked: (attempts, duration, userName = \"User\") => ({\n subject: \"Account Security Alert - Account Locked\",\n html: `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>Account Locked</title>\n <style>\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; }\n .container { max-width: 600px; margin: 0 auto; padding: 20px; }\n .alert { background: #fef2f2; border: 1px solid #ef4444; padding: 16px; border-radius: 8px; margin: 20px 0; }\n .footer { margin-top: 30px; font-size: 12px; color: #666; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Account Security Alert</h1>\n <p>Hello ${userName},</p>\n <div class=\"alert\">\n <p><strong>⚠️ Your account has been temporarily locked due to multiple failed login attempts.</strong></p>\n <p>Failed attempts: ${attempts}</p>\n <p>Lockout duration: ${Math.round(duration / 60000)} minutes</p>\n </div>\n <p>Your account will automatically unlock after the lockout period expires.</p>\n <p>If this wasn't you, we recommend:</p>\n <ul>\n <li>Using a strong, unique password</li>\n <li>Enabling two-factor authentication (coming soon)</li>\n <li>Reviewing your recent account activity</li>\n </ul>\n <div class=\"footer\">\n <p>If you need immediate assistance, please contact support.</p>\n </div>\n </div>\n </body>\n </html>\n `,\n text: `Account Security Alert\\n\\nHello ${userName},\\n\\nYour account has been temporarily locked due to multiple failed login attempts (${attempts}).\\n\\nLockout duration: ${Math.round(duration / 60000)} minutes\\n\\nYour account will automatically unlock after this period.\\n\\nIf this wasn't you, we recommend using a strong, unique password.`,\n }),\n\n passwordChanged: (userName = \"User\") => ({\n subject: \"Your password has been changed\",\n html: `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>Password Changed</title>\n <style>\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; }\n .container { max-width: 600px; margin: 0 auto; padding: 20px; }\n .info { background: #f0fdf4; border: 1px solid #22c55e; padding: 12px; border-radius: 6px; margin: 20px 0; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Password Changed</h1>\n <p>Hello ${userName},</p>\n <div class=\"info\">\n <p>Your password was recently changed.</p>\n </div>\n <p>If you did this, you can safely ignore this email.</p>\n <p><strong>If you didn't change your password</strong>, please contact our support team immediately as your account may have been compromised.</p>\n </div>\n </body>\n </html>\n `,\n text: `Password Changed\\n\\nHello ${userName},\\n\\nYour password was recently changed.\\n\\nIf you did this, you can safely ignore this email.\\n\\nIf you didn't change your password, please contact support immediately.`,\n }),\n\n newLogin: (location, time, userName = \"User\") => ({\n subject: \"New login to your account\",\n html: `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>New Login</title>\n <style>\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; }\n .container { max-width: 600px; margin: 0 auto; padding: 20px; }\n .info-box { background: #f8fafc; border: 1px solid #e2e8f0; padding: 16px; border-radius: 8px; margin: 20px 0; }\n .footer { margin-top: 30px; font-size: 12px; color: #666; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>New Login Detected</h1>\n <p>Hello ${userName},</p>\n <p>We detected a new login to your account:</p>\n <div class=\"info-box\">\n <p><strong>Location:</strong> ${location}</p>\n <p><strong>Time:</strong> ${time}</p>\n </div>\n <p><strong>If this was you</strong>, no action is needed.</p>\n <p><strong>If this wasn't you</strong>, your account may be compromised. Please:</p>\n <ol>\n <li>Change your password immediately</li>\n <li>Review your recent account activity</li>\n <li>Contact support if needed</li>\n </ol>\n <div class=\"footer\">\n <p>This is an automated security notification.</p>\n </div>\n </div>\n </body>\n </html>\n `,\n text: `New Login Detected\\n\\nHello ${userName},\\n\\nWe detected a new login to your account:\\n\\nLocation: ${location}\\nTime: ${time}\\n\\nIf this wasn't you, please change your password immediately and contact support.`,\n }),\n};\n\nimport { ConfigService } from \"../config/ConfigService.js\";\n\nexport class EmailTransport {\n private transporter?: Transporter<SentMessageInfo>;\n private config: EmailConfig;\n private templates: EmailTemplates;\n private transporterInitialized: boolean = false;\n\n constructor(config: EmailConfig, templates?: Partial<EmailTemplates>) {\n this.config = config;\n this.templates = { ...defaultTemplates, ...templates };\n }\n\n private async ensureTransporter(): Promise<Transporter<SentMessageInfo>> {\n if (this.transporterInitialized) {\n return this.transporter!;\n }\n\n const { default: nodemailer } = await import(\"nodemailer\");\n\n if (this.config.provider === \"smtp\" && this.config.smtp) {\n this.transporter = nodemailer.createTransport({\n host: this.config.smtp.host,\n port: this.config.smtp.port,\n secure: this.config.smtp.secure,\n auth: this.config.smtp.auth,\n });\n } else if (this.config.provider === \"ses\" && this.config.ses) {\n this.transporter = nodemailer.createTransport({\n host: `email-smtp.${this.config.ses.region}.amazonaws.com`,\n port: 587,\n secure: false,\n auth: {\n user: this.config.ses.accessKeyId,\n pass: this.config.ses.secretAccessKey,\n },\n });\n }\n\n this.transporterInitialized = true;\n return this.transporter!;\n }\n\n async send(options: EmailOptions): Promise<any> {\n const { provider, from, fromName, replyTo: configReplyTo } = this.config;\n const fromFull = `\"${fromName || \"Kyro CMS\"}\" <${from}>`;\n const replyTo = options.replyTo || configReplyTo;\n\n\n\n try {\n let result;\n switch (provider) {\n case \"smtp\":\n case \"ses\":\n {\n const transporter = await this.ensureTransporter();\n if (!transporter)\n throw new Error(`${provider} transporter not initialized`);\n result = await transporter.sendMail({\n from: fromFull,\n to: Array.isArray(options.to)\n ? options.to.join(\", \")\n : options.to,\n subject: options.subject,\n html: options.html,\n text: options.text,\n replyTo,\n });\n }\n break;\n\n case \"resend\":\n result = await this.sendViaResend(fromFull, options, replyTo);\n break;\n\n case \"sendgrid\":\n result = await this.sendViaSendGrid(fromFull, options, replyTo);\n break;\n\n case \"mailgun\":\n result = await this.sendViaMailgun(fromFull, options, replyTo);\n break;\n\n default:\n throw new Error(`Unsupported email provider: ${provider}`);\n }\n\n return result;\n } catch (error: any) {\n console.error(`[EmailTransport] FAILED to send email:`, error.message);\n if (error.response) {\n console.error(\n `[EmailTransport] Provider Error Detail:`,\n JSON.stringify(error.response, null, 2),\n );\n }\n throw error;\n }\n }\n\n private async sendViaResend(\n from: string,\n options: EmailOptions,\n replyTo?: string,\n ) {\n const apiKey = this.config.resend?.apiKey;\n if (!apiKey) throw new Error(\"Resend API Key missing\");\n\n const body = {\n from,\n to: options.to,\n subject: options.subject,\n html: options.html,\n text: options.text,\n reply_to: replyTo,\n };\n\n\n const resp = await fetch(\"https://api.resend.com/emails\", {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n\n if (!resp.ok) {\n const error = await resp.json();\n throw new Error(`Resend Error: ${JSON.stringify(error)}`);\n }\n return resp.json();\n }\n\n private async sendViaSendGrid(\n from: string,\n options: EmailOptions,\n replyTo?: string,\n ) {\n const apiKey = this.config.sendgrid?.apiKey;\n if (!apiKey) throw new Error(\"SendGrid API Key missing\");\n\n const body = {\n personalizations: [\n {\n to: Array.isArray(options.to)\n ? options.to.map((email) => ({ email }))\n : [{ email: options.to }],\n },\n ],\n from: {\n email: from.match(/<(.+)>/)?.[1] || from,\n name: from.match(/\"(.+)\"/)?.[1],\n },\n subject: options.subject,\n content: [\n { type: \"text/plain\", value: options.text || \"\" },\n { type: \"text/html\", value: options.html },\n ],\n reply_to: replyTo ? { email: replyTo } : undefined,\n };\n\n\n const resp = await fetch(\"https://api.sendgrid.com/v3/mail/send\", {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n\n if (!resp.ok) {\n const error = await resp.json();\n throw new Error(`SendGrid Error: ${JSON.stringify(error)}`);\n }\n return { success: true };\n }\n\n private async sendViaMailgun(\n from: string,\n options: EmailOptions,\n replyTo?: string,\n ) {\n const { apiKey, domain, region } = this.config.mailgun || {};\n if (!apiKey || !domain) throw new Error(\"Mailgun config missing\");\n\n const base = region === \"eu\" ? \"api.eu.mailgun.net\" : \"api.mailgun.net\";\n const auth = btoa(`api:${apiKey}`);\n\n const formData = new URLSearchParams();\n formData.append(\"from\", from);\n const to = Array.isArray(options.to) ? options.to.join(\", \") : options.to;\n formData.append(\"to\", to);\n formData.append(\"subject\", options.subject);\n formData.append(\"html\", options.html);\n if (options.text) formData.append(\"text\", options.text);\n if (replyTo) formData.append(\"h:Reply-To\", replyTo);\n\n\n const resp = await fetch(`https://${base}/v3/${domain}/messages`, {\n method: \"POST\",\n headers: {\n Authorization: `Basic ${auth}`,\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: formData,\n });\n\n if (!resp.ok) {\n const error = await resp.json();\n throw new Error(`Mailgun Error: ${JSON.stringify(error)}`);\n }\n return resp.json();\n }\n\n getTemplates(): EmailTemplates {\n return this.templates;\n }\n\n async verifyConnection(): Promise<boolean> {\n if (this.config.provider === \"smtp\" || this.config.provider === \"ses\") {\n try {\n const transporter = await this.ensureTransporter();\n if (transporter) {\n await transporter.verify();\n return true;\n }\n } catch {\n return false;\n }\n }\n return !!(\n this.config.resend?.apiKey ||\n this.config.sendgrid?.apiKey ||\n this.config.mailgun?.apiKey\n );\n }\n\n static async fromConfig(db: any): Promise<EmailTransport | null> {\n const configService = new ConfigService(db);\n await configService.load();\n const config = configService.getEmailConfig();\n\n if (!config.provider) {\n return this.fromEnv();\n }\n\n const transformed: EmailConfig = {\n provider: (config.provider as any) || \"smtp\",\n from: config.from || \"noreply@example.com\",\n fromName: config.fromName,\n replyTo: config.replyTo,\n smtp:\n config.provider === \"smtp\"\n ? {\n host: config.host || \"\",\n port: config.port || 587,\n secure: config.secure || false,\n auth: { user: config.user || \"\", pass: config.pass || \"\" },\n }\n : undefined,\n resend:\n config.provider === \"resend\"\n ? { apiKey: config.pass || \"\" }\n : undefined,\n sendgrid:\n config.provider === \"sendgrid\"\n ? { apiKey: config.pass || \"\" }\n : undefined,\n mailgun:\n config.provider === \"mailgun\"\n ? {\n apiKey: config.pass || \"\",\n domain: config.host || \"\",\n region: (config.secure ? \"eu\" : \"us\") as any,\n }\n : undefined,\n ses:\n config.provider === \"ses\"\n ? {\n accessKeyId: config.user || \"\",\n secretAccessKey: config.pass || \"\",\n region: config.host || \"us-east-1\",\n }\n : undefined,\n };\n\n return new EmailTransport(transformed);\n }\n\n static fromEnv(): EmailTransport | null {\n const provider = (process.env.EMAIL_PROVIDER as any) || \"smtp\";\n const from =\n process.env.SMTP_FROM ||\n process.env.DEFAULT_FROM ||\n \"noreply@example.com\";\n const fromName = process.env.SMTP_FROM_NAME || \"Kyro CMS\";\n const replyTo = process.env.SMTP_REPLY_TO;\n\n if (provider === \"smtp\") {\n const host = process.env.SMTP_HOST;\n const user = process.env.SMTP_USER;\n const pass = process.env.SMTP_PASS;\n if (!host || !user || !pass) return null;\n\n return new EmailTransport({\n provider: \"smtp\",\n from,\n fromName,\n replyTo,\n smtp: {\n host,\n port: parseInt(process.env.SMTP_PORT || \"587\", 10),\n secure: process.env.SMTP_SECURE === \"true\",\n auth: { user, pass },\n },\n });\n }\n\n if (provider === \"resend\") {\n const apiKey = process.env.RESEND_API_KEY || process.env.SMTP_PASS;\n if (!apiKey) return null;\n return new EmailTransport({\n provider: \"resend\",\n from,\n fromName,\n replyTo,\n resend: { apiKey },\n });\n }\n\n if (provider === \"sendgrid\") {\n const apiKey = process.env.SENDGRID_API_KEY || process.env.SMTP_PASS;\n if (!apiKey) return null;\n return new EmailTransport({\n provider: \"sendgrid\",\n from,\n fromName,\n replyTo,\n sendgrid: { apiKey },\n });\n }\n\n if (provider === \"mailgun\") {\n const apiKey = process.env.MAILGUN_API_KEY || process.env.SMTP_PASS;\n const domain = process.env.MAILGUN_DOMAIN || process.env.SMTP_HOST;\n if (!apiKey || !domain) return null;\n return new EmailTransport({\n provider: \"mailgun\",\n from,\n fromName,\n replyTo,\n mailgun: {\n apiKey,\n domain,\n region: (process.env.MAILGUN_REGION ||\n (process.env.SMTP_SECURE === \"true\" ? \"eu\" : \"us\")) as any,\n },\n });\n }\n\n if (provider === \"ses\") {\n const accessKeyId =\n process.env.AWS_ACCESS_KEY_ID || process.env.SMTP_USER;\n const secretAccessKey =\n process.env.AWS_SECRET_ACCESS_KEY || process.env.SMTP_PASS;\n const region =\n process.env.AWS_REGION || process.env.SMTP_HOST || \"us-east-1\";\n if (!accessKeyId || !secretAccessKey) return null;\n return new EmailTransport({\n provider: \"ses\",\n from,\n fromName,\n replyTo,\n ses: { accessKeyId, secretAccessKey, region },\n });\n }\n\n return null;\n }\n}\n","export interface PasswordPolicyConfig {\n minLength: number;\n requireUppercase: boolean;\n requireLowercase: boolean;\n requireNumbers: boolean;\n requireSpecialChars: boolean;\n preventReuse: number;\n maxLength?: number;\n}\n\nexport interface ValidationResult {\n valid: boolean;\n errors: string[];\n}\n\nexport const DEFAULT_PASSWORD_POLICY: PasswordPolicyConfig = {\n minLength: 12,\n requireUppercase: true,\n requireLowercase: true,\n requireNumbers: true,\n requireSpecialChars: true,\n preventReuse: 5,\n maxLength: 128,\n};\n\nexport class PasswordPolicy {\n private config: PasswordPolicyConfig;\n\n constructor(config: Partial<PasswordPolicyConfig> = {}) {\n this.config = { ...DEFAULT_PASSWORD_POLICY, ...config };\n }\n\n validate(password: string): ValidationResult {\n const errors: string[] = [];\n\n if (this.config.maxLength && password.length > this.config.maxLength) {\n errors.push(\n `Password must not exceed ${this.config.maxLength} characters`,\n );\n }\n\n if (password.length < this.config.minLength) {\n errors.push(\n `Password must be at least ${this.config.minLength} characters`,\n );\n }\n\n if (this.config.requireUppercase && !/[A-Z]/.test(password)) {\n errors.push(\"Password must contain at least one uppercase letter\");\n }\n\n if (this.config.requireLowercase && !/[a-z]/.test(password)) {\n errors.push(\"Password must contain at least one lowercase letter\");\n }\n\n if (this.config.requireNumbers && !/[0-9]/.test(password)) {\n errors.push(\"Password must contain at least one number\");\n }\n\n if (\n this.config.requireSpecialChars &&\n !/[!@#$%^&*()_+\\-=\\[\\]{};':\"\\\\|,.<>\\/?]/.test(password)\n ) {\n errors.push(\"Password must contain at least one special character\");\n }\n\n const commonPasswords = [\n \"password\",\n \"123456\",\n \"12345678\",\n \"qwerty\",\n \"abc123\",\n \"monkey\",\n \"1234567\",\n \"letmein\",\n \"trustno1\",\n \"dragon\",\n \"baseball\",\n \"iloveyou\",\n \"master\",\n \"sunshine\",\n \"ashley\",\n \"football\",\n \"password1\",\n \"shadow\",\n \"123123\",\n \"654321\",\n ];\n\n if (commonPasswords.includes(password.toLowerCase())) {\n errors.push(\n \"This password is too common. Please choose a more secure password\",\n );\n }\n\n if (/^[a-zA-Z]+$/.test(password) || /^[0-9]+$/.test(password)) {\n errors.push(\n \"Password must contain a mix of letters, numbers, and/or special characters\",\n );\n }\n\n if (/(.)\\1{2,}/.test(password)) {\n errors.push(\n \"Password must not contain more than 2 consecutive identical characters\",\n );\n }\n\n if (\n /^(012|123|234|345|456|567|678|789|890|098|987|876|765|654|543|432|321|210)+$/i.test(\n password,\n )\n ) {\n errors.push(\"Password must not contain sequential numbers or letters\");\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n }\n\n async checkReuse(\n passwordHash: string,\n history: string[],\n verifyFn: (password: string, hash: string) => Promise<boolean>,\n ): Promise<ValidationResult> {\n return {\n valid: true,\n errors: [],\n };\n }\n\n async isInHistory(\n password: string,\n history: string[],\n verifyFn: (password: string, hash: string) => Promise<boolean>,\n ): Promise<boolean> {\n for (const hash of history) {\n if (await verifyFn(password, hash)) {\n return true;\n }\n }\n return false;\n }\n\n generatePassword(length: number = 16): string {\n const uppercase = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n const lowercase = \"abcdefghijklmnopqrstuvwxyz\";\n const numbers = \"0123456789\";\n const special = \"!@#$%^&*()_+-=[]{}|;:,.<>?\";\n\n let password = \"\";\n\n password += uppercase[Math.floor(Math.random() * uppercase.length)];\n password += lowercase[Math.floor(Math.random() * lowercase.length)];\n password += numbers[Math.floor(Math.random() * numbers.length)];\n password += special[Math.floor(Math.random() * special.length)];\n\n const allChars = uppercase + lowercase + numbers + special;\n for (let i = password.length; i < length; i++) {\n password += allChars[Math.floor(Math.random() * allChars.length)];\n }\n\n return password\n .split(\"\")\n .sort(() => Math.random() - 0.5)\n .join(\"\");\n }\n\n getStrength(password: string): {\n score: number;\n label: string;\n feedback: string[];\n } {\n let score = 0;\n const feedback: string[] = [];\n\n if (password.length >= 8) score += 1;\n if (password.length >= 12) score += 1;\n if (password.length >= 16) score += 1;\n\n if (/[a-z]/.test(password)) score += 1;\n if (/[A-Z]/.test(password)) score += 1;\n if (/[0-9]/.test(password)) score += 1;\n if (/[!@#$%^&*()_+\\-=\\[\\]{}|;:,.<>?]/.test(password)) score += 1;\n\n if (password.length > 8) score += 1;\n if (password.length > 12) score += 1;\n\n const uniqueChars = new Set(password).size;\n if (uniqueChars > 6) score += 1;\n if (uniqueChars > 10) score += 1;\n\n let label: string;\n if (score <= 3) {\n label = \"Weak\";\n feedback.push(\"Add more characters\");\n feedback.push(\"Include uppercase and lowercase letters\");\n } else if (score <= 5) {\n label = \"Fair\";\n feedback.push(\"Add special characters\");\n feedback.push(\"Consider making it longer\");\n } else if (score <= 7) {\n label = \"Good\";\n feedback.push(\"Consider making it longer for extra security\");\n } else {\n label = \"Strong\";\n }\n\n return { score, label, feedback };\n }\n\n setConfig(config: Partial<PasswordPolicyConfig>): void {\n this.config = { ...this.config, ...config };\n }\n\n getConfig(): PasswordPolicyConfig {\n return { ...this.config };\n }\n}\n"]}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunk3P5AHK2U_cjs = require('./chunk-3P5AHK2U.cjs');
|
|
4
|
+
var chunk5GFQPHGT_cjs = require('./chunk-5GFQPHGT.cjs');
|
|
5
5
|
var chunkIDVRRRAK_cjs = require('./chunk-IDVRRRAK.cjs');
|
|
6
|
-
var
|
|
6
|
+
var chunkGYIJ3JJM_cjs = require('./chunk-GYIJ3JJM.cjs');
|
|
7
7
|
var chunk7OS7TX2Q_cjs = require('./chunk-7OS7TX2Q.cjs');
|
|
8
|
-
var
|
|
8
|
+
var chunkTHBQG64D_cjs = require('./chunk-THBQG64D.cjs');
|
|
9
9
|
var chunkGXFOGU7N_cjs = require('./chunk-GXFOGU7N.cjs');
|
|
10
10
|
var projectConfig = require('kyro:config');
|
|
11
11
|
|
|
@@ -19,30 +19,29 @@ async function doInit() {
|
|
|
19
19
|
if (exports.kyroInstance) return;
|
|
20
20
|
try {
|
|
21
21
|
const config = projectConfig__default.default.default || projectConfig__default.default;
|
|
22
|
-
exports.kyroInstance =
|
|
22
|
+
exports.kyroInstance = chunk3P5AHK2U_cjs.createKyro(config);
|
|
23
23
|
await exports.kyroInstance.init();
|
|
24
24
|
await exports.kyroInstance.loadSettings();
|
|
25
25
|
const db = exports.kyroInstance.db;
|
|
26
26
|
let bootstrapAuthAdapter = void 0;
|
|
27
|
-
if (db instanceof
|
|
27
|
+
if (db instanceof chunkGYIJ3JJM_cjs.DrizzleAdapter) {
|
|
28
28
|
if (db.dialect === "postgres") {
|
|
29
29
|
bootstrapAuthAdapter = new chunk7OS7TX2Q_cjs.PostgresAuthAdapter({ db: db.client });
|
|
30
30
|
} else if (db.dialect === "sqlite") {
|
|
31
31
|
const authDbPath = process.env.KYRO_AUTH_DB_PATH || "./data/auth.db";
|
|
32
32
|
bootstrapAuthAdapter = new chunkIDVRRRAK_cjs.SQLiteAuthAdapter({ path: authDbPath });
|
|
33
33
|
}
|
|
34
|
-
} else if (db instanceof
|
|
34
|
+
} else if (db instanceof chunk3P5AHK2U_cjs.LocalAdapter) {
|
|
35
35
|
const authDbPath = process.env.KYRO_AUTH_DB_PATH || "./data/auth.db";
|
|
36
36
|
bootstrapAuthAdapter = new chunkIDVRRRAK_cjs.SQLiteAuthAdapter({ path: authDbPath });
|
|
37
|
-
} else if (db instanceof
|
|
37
|
+
} else if (db instanceof chunkTHBQG64D_cjs.MongoDBAdapter) {
|
|
38
38
|
bootstrapAuthAdapter = new chunkGXFOGU7N_cjs.MongoDBAuthAdapter({ db: db.db });
|
|
39
39
|
}
|
|
40
40
|
if (bootstrapAuthAdapter?.connect) {
|
|
41
41
|
await bootstrapAuthAdapter.connect();
|
|
42
42
|
}
|
|
43
|
-
const result = await
|
|
43
|
+
const result = await chunk5GFQPHGT_cjs.autoBootstrap(bootstrapAuthAdapter);
|
|
44
44
|
if (result?.success) {
|
|
45
|
-
console.log(`[Kyro] Admin user auto-created from env: ${result.user?.email}`);
|
|
46
45
|
}
|
|
47
46
|
if (typeof exports.kyroInstance.startWebSocket === "function") {
|
|
48
47
|
exports.kyroInstance.startWebSocket().catch((err) => {
|
|
@@ -50,7 +49,6 @@ async function doInit() {
|
|
|
50
49
|
});
|
|
51
50
|
}
|
|
52
51
|
globalThis.__KYRO_INSTANCE__ = exports.kyroInstance;
|
|
53
|
-
console.log("[Kyro API] Backend initialized via Astro Integration");
|
|
54
52
|
} catch (err) {
|
|
55
53
|
exports.kyroInstance = null;
|
|
56
54
|
initPromise = null;
|
|
@@ -108,5 +106,5 @@ var ALL = async (context) => {
|
|
|
108
106
|
|
|
109
107
|
exports.ALL = ALL;
|
|
110
108
|
exports.warmKyroInstance = warmKyroInstance;
|
|
111
|
-
//# sourceMappingURL=chunk-
|
|
112
|
-
//# sourceMappingURL=chunk-
|
|
109
|
+
//# sourceMappingURL=chunk-NQJJYRLP.cjs.map
|
|
110
|
+
//# sourceMappingURL=chunk-NQJJYRLP.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/api-handler.ts"],"names":["kyroInstance","projectConfig","createKyro","DrizzleAdapter","PostgresAuthAdapter","SQLiteAuthAdapter","LocalAdapter","MongoDBAdapter","MongoDBAuthAdapter","autoBootstrap"],"mappings":"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","file":"chunk-NQJJYRLP.cjs","sourcesContent":["import type { APIRoute } from \"astro\";\nimport { createKyro } from \"./createKyro.js\";\nimport { autoBootstrap } from \"./auth/bootstrap.js\";\nimport { DrizzleAdapter } from \"./database/drizzle/adapter.js\";\nimport { PostgresAuthAdapter } from \"./database/drizzle/postgres-auth-adapter.js\";\nimport { LocalAdapter } from \"./database/local/adapter.js\";\nimport { SQLiteAuthAdapter } from \"./auth/sqlite-adapter.js\";\nimport { MongoDBAdapter } from \"./database/mongodb/adapter.js\";\nimport { MongoDBAuthAdapter } from \"./database/mongodb/mongo-auth-adapter.js\";\n// @ts-ignore - handled by vite alias\nimport projectConfig from \"kyro:config\";\n\ndeclare var __KYRO_API_PATH__: string;\n\nexport let kyroInstance: any = null;\nlet initPromise: Promise<void> | null = null;\n\nasync function doInit(): Promise<void> {\n if (kyroInstance) return;\n\n try {\n const config = projectConfig.default || projectConfig;\n kyroInstance = createKyro(config);\n await kyroInstance.init();\n await kyroInstance.loadSettings();\n\n const db = kyroInstance.db;\n let bootstrapAuthAdapter: any = undefined;\n \n if (db instanceof DrizzleAdapter) {\n if (db.dialect === \"postgres\") {\n bootstrapAuthAdapter = new PostgresAuthAdapter({ db: db.client });\n } else if (db.dialect === \"sqlite\") {\n const authDbPath = process.env.KYRO_AUTH_DB_PATH || \"./data/auth.db\";\n bootstrapAuthAdapter = new SQLiteAuthAdapter({ path: authDbPath });\n }\n } else if (db instanceof LocalAdapter) {\n const authDbPath = process.env.KYRO_AUTH_DB_PATH || \"./data/auth.db\";\n bootstrapAuthAdapter = new SQLiteAuthAdapter({ path: authDbPath });\n } else if (db instanceof MongoDBAdapter) {\n bootstrapAuthAdapter = new MongoDBAuthAdapter({ db: db.db });\n }\n\n if (bootstrapAuthAdapter?.connect) {\n await bootstrapAuthAdapter.connect();\n }\n\n const result = await autoBootstrap(bootstrapAuthAdapter);\n if (result?.success) {\n }\n\n // Auto-start WebSocket (checks settings.access.apiAccess.wsEnabled internally)\n if (typeof kyroInstance.startWebSocket === \"function\") {\n kyroInstance.startWebSocket().catch((err: any) => {\n console.error(\"[Kyro] WebSocket auto-start failed:\", err);\n });\n }\n\n // Expose instance globally so admin SSR can read DB directly\n (globalThis as any).__KYRO_INSTANCE__ = kyroInstance;\n\n } catch (err) {\n kyroInstance = null;\n initPromise = null;\n console.error(\"[Kyro API] Init failed, will retry:\", err);\n throw err;\n }\n}\n\nexport async function warmKyroInstance(): Promise<void> {\n if (!initPromise) {\n initPromise = doInit();\n }\n await initPromise;\n}\n\nexport const ALL: APIRoute = async (context) => {\n if (!kyroInstance) {\n if (!initPromise) {\n initPromise = doInit();\n }\n\n try {\n await Promise.race([\n initPromise,\n new Promise<void>((_, reject) =>\n setTimeout(() => reject(new Error(\"Initialization timeout\")), 30000)\n ),\n ]);\n } catch {\n return new Response(JSON.stringify({\n error: \"Service Unavailable\",\n message: \"Kyro CMS is still starting up. Please try again in a moment.\",\n }), {\n status: 503,\n headers: {\n \"Content-Type\": \"application/json\",\n \"Retry-After\": \"5\",\n },\n });\n }\n }\n\n const url = new URL(context.request.url);\n const path = url.pathname;\n const p = __KYRO_API_PATH__;\n\n if (path === `${p}/graphql` && typeof kyroInstance.getGraphQL === \"function\") {\n const yoga = kyroInstance.getGraphQL();\n const res = await yoga.fetch(context.request, context.locals);\n return new Response(res.body, res);\n }\n\n if (path.startsWith(`${p}/trpc/`) && typeof kyroInstance.getTRPC === \"function\") {\n const trpc = kyroInstance.getTRPC();\n const res = await trpc.fetch(context.request, context.locals);\n return new Response(res.body, res);\n }\n\n const app = kyroInstance.getREST();\n return app.fetch(context.request, context.locals);\n};\n"]}
|
|
@@ -32,13 +32,11 @@ var MongoDBAdapter = class extends chunkGUUB5EAG_cjs.AbstractBaseAdapter {
|
|
|
32
32
|
}
|
|
33
33
|
this.db = this.client.db(this.database);
|
|
34
34
|
this.connected = true;
|
|
35
|
-
console.log(`[MongoDBAdapter] Connected to database: ${this.database}`);
|
|
36
35
|
}
|
|
37
36
|
async disconnect() {
|
|
38
37
|
if (this.client) {
|
|
39
38
|
await this.client.close();
|
|
40
39
|
this.connected = false;
|
|
41
|
-
console.log(`[MongoDBAdapter] Disconnected`);
|
|
42
40
|
}
|
|
43
41
|
}
|
|
44
42
|
getMongoCollection(slug) {
|
|
@@ -317,7 +315,6 @@ var MongoDBAdapter = class extends chunkGUUB5EAG_cjs.AbstractBaseAdapter {
|
|
|
317
315
|
}
|
|
318
316
|
}
|
|
319
317
|
}
|
|
320
|
-
console.log(`[MongoDBAdapter] Migration completed`);
|
|
321
318
|
}
|
|
322
319
|
// ========================================================================
|
|
323
320
|
// Helper Methods
|
|
@@ -424,5 +421,5 @@ function createMongoDBAdapter(options) {
|
|
|
424
421
|
|
|
425
422
|
exports.MongoDBAdapter = MongoDBAdapter;
|
|
426
423
|
exports.createMongoDBAdapter = createMongoDBAdapter;
|
|
427
|
-
//# sourceMappingURL=chunk-
|
|
428
|
-
//# sourceMappingURL=chunk-
|
|
424
|
+
//# sourceMappingURL=chunk-THBQG64D.cjs.map
|
|
425
|
+
//# sourceMappingURL=chunk-THBQG64D.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/database/mongodb/adapter.ts"],"names":["AbstractBaseAdapter","applyRLS","DEFAULT_RLS_CONFIG","canAccessDocument","now","randomBytes"],"mappings":"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","file":"chunk-THBQG64D.cjs","sourcesContent":["import { randomBytes } from 'crypto';\nimport { AbstractBaseAdapter } from '../base.js';\nimport type {\n CollectionConfig,\n GlobalConfig,\n FindArgs,\n FindByIDArgs,\n CreateArgs,\n UpdateArgs,\n DeleteArgs,\n FindResult,\n VersionRecord,\n CreateVersionArgs,\n FindVersionsArgs,\n} from '../../registry/types.js';\nimport type { TenantContext } from '../../auth/rls/tenant.js';\nimport { applyRLS, DEFAULT_RLS_CONFIG, canAccessDocument } from '../../auth/rls/tenant.js';\n\nexport class MongoDBAdapter extends AbstractBaseAdapter {\n public client: any;\n public db: any;\n private database: string;\n private connectionString?: string;\n // NOTE: draftsCollectionName removed — autosave now uses versions table with autosave flag\n \n constructor(options: {\n client?: any;\n database?: string;\n connectionString?: string;\n }) {\n super();\n if (options.connectionString) {\n this.connectionString = options.connectionString;\n try {\n const url = new URL(options.connectionString);\n this.database = url.pathname.replace(/^\\//, '') || 'kyro_cms';\n } catch {\n this.database = 'kyro_cms';\n }\n } else {\n this.client = options.client;\n this.database = options.database!;\n }\n }\n\n async connect(): Promise<void> {\n if (this.connectionString && !this.client) {\n const { MongoClient } = await import('mongodb');\n this.client = new MongoClient(this.connectionString);\n await this.client.connect();\n }\n this.db = this.client.db(this.database);\n this.connected = true;\n\n }\n\n async disconnect(): Promise<void> {\n if (this.client) {\n await this.client.close();\n this.connected = false;\n\n }\n }\n\n private getMongoCollection(slug: string): any {\n if (!this.db) {\n throw new Error('MongoDB not connected');\n }\n return this.db.collection(slug);\n }\n\n async find<T>(args: FindArgs): Promise<FindResult<T>> {\n const { collection: slug, where = {}, sort, limit = 10, page = 1, tenantID, select, draft } = args;\n const config = this.getCollectionConfig(slug);\n const col = this.getMongoCollection(slug);\n\n let effectiveWhere = { ...where };\n if (this.tenantContext && config.tenantScoped) {\n const rlsQuery = applyRLS({ where: effectiveWhere }, slug, this.tenantContext, DEFAULT_RLS_CONFIG);\n effectiveWhere = rlsQuery.where || {};\n }\n\n // Build filter\n const filter = this.buildFilter(effectiveWhere, tenantID);\n \n // Default filter for non-draft requests: only show published\n if (!draft) {\n filter.status = 'published';\n }\n\n // Build sort\n const sortOption = this.parseSort(sort);\n const sortObj: Record<string, 1 | -1> = {\n [sortOption.field]: sortOption.direction === 'asc' ? 1 : -1,\n };\n\n // Execute query\n const skip = (page - 1) * limit;\n \n const [docs, totalDocs] = await Promise.all([\n col\n .find(filter)\n .sort(sortObj)\n .skip(skip)\n .limit(limit)\n .project(this.buildProjection(select))\n .toArray(),\n col.countDocuments(filter),\n ]);\n\n // Process results\n let processedDocs = docs.map((doc: any) => this.processResult(doc, config));\n\n if (this.tenantContext && !this.tenantContext.isSuperAdmin) {\n processedDocs = processedDocs.filter((doc: any) => canAccessDocument(doc, slug, this.tenantContext!, DEFAULT_RLS_CONFIG));\n }\n\n // If draft: true, merge the latest version (autosave or manual) into the response\n if (draft) {\n processedDocs = await Promise.all(processedDocs.map(async (doc: any) => {\n const versionCollection = this.getMongoCollection(`${slug}_versions`);\n const version = await versionCollection.findOne(\n { document_id: doc.id },\n { sort: { createdAt: -1 } },\n );\n if (version) {\n const versionData = version.data || {};\n return { ...doc, ...versionData, status: doc.status };\n }\n return doc;\n }));\n }\n\n return {\n docs: processedDocs as T[],\n ...this.calculatePagination(page, limit, totalDocs),\n };\n }\n\n async findByID<T>(args: FindByIDArgs): Promise<T | null> {\n const { collection: slug, id, tenantID, draft } = args;\n const config = this.getCollectionConfig(slug);\n const col = this.getMongoCollection(slug);\n\n if (this.tenantContext && config.tenantScoped) {\n const tempDoc = { _id: id, tenantId: this.tenantContext.tenantId };\n if (!canAccessDocument(tempDoc, slug, this.tenantContext, DEFAULT_RLS_CONFIG)) {\n return null;\n }\n }\n\n const filter: any = { _id: id };\n if (tenantID) {\n filter.tenantId = tenantID;\n }\n \n if (!draft) {\n filter.status = 'published';\n }\n\n const doc = await col.findOne(filter);\n if (!doc) return null;\n\n let processedDoc = this.processResult(doc, config);\n\n // If draft: true, merge the latest version (autosave or manual) into the response\n if (draft) {\n const versionCollection = this.getMongoCollection(`${slug}_versions`);\n const version = await versionCollection.findOne(\n { document_id: processedDoc.id },\n { sort: { createdAt: -1 } },\n );\n if (version) {\n const versionData = version.data || {};\n processedDoc = { ...processedDoc, ...versionData, status: processedDoc.status };\n }\n }\n\n return processedDoc as T;\n }\n\n async create<T>(args: CreateArgs): Promise<T> {\n const { collection: slug, data, tenantID } = args;\n const config = this.getCollectionConfig(slug);\n const col = this.getMongoCollection(slug);\n\n const doc: any = {\n ...this.prepareData(data, config),\n _id: this.generateId(),\n };\n\n if (tenantID) {\n doc.tenantId = tenantID;\n }\n\n await col.insertOne(doc);\n\n return this.processResult(doc, config) as T;\n }\n\n async update<T>(args: UpdateArgs): Promise<T> {\n const { collection: slug, id, data, tenantID } = args;\n const config = this.getCollectionConfig(slug);\n const col = this.getMongoCollection(slug);\n\n const filter: any = { _id: id };\n if (tenantID) {\n filter.tenantId = tenantID;\n }\n\n const updateData = this.prepareData(data, config);\n\n const result = await col.findOneAndUpdate(\n filter,\n { $set: updateData },\n { returnDocument: 'after' }\n );\n\n if (!result) {\n throw new Error(`Document not found: ${slug}/${id}`);\n }\n\n return this.processResult(result, config) as T;\n }\n\n async delete<T>(args: DeleteArgs): Promise<T> {\n const { collection: slug, id, tenantID } = args;\n const config = this.getCollectionConfig(slug);\n const col = this.getMongoCollection(slug);\n\n const filter: any = { _id: id };\n if (tenantID) {\n filter.tenantId = tenantID;\n }\n\n const doc = await col.findOneAndDelete(filter);\n if (!doc) {\n throw new Error(`Document not found: ${slug}/${id}`);\n }\n\n return this.processResult(doc, config) as T;\n }\n\n async count(args: { collection: string; where?: Record<string, any>; tenantID?: string }): Promise<number> {\n const { collection: slug, where = {}, tenantID } = args;\n const col = this.getMongoCollection(slug);\n const filter = this.buildFilter(where, tenantID);\n return col.countDocuments(filter);\n }\n\n async findOne(args: { collection: string; where: Record<string, any>; tenantID?: string; draft?: boolean }): Promise<any> {\n const { collection: slug, where = {}, tenantID, draft } = args;\n const config = this.getCollectionConfig(slug);\n const col = this.getMongoCollection(slug);\n const filter = this.buildFilter(where, tenantID);\n\n if (!draft) {\n filter.status = 'published';\n }\n\n const doc = await col.findOne(filter);\n if (!doc) return null;\n\n let processedDoc = this.processResult(doc, config);\n\n // If draft: true, merge the latest version (autosave or manual) into the response\n if (draft) {\n const versionCollection = this.getMongoCollection(`${slug}_versions`);\n const version = await versionCollection.findOne(\n { document_id: processedDoc.id },\n { sort: { createdAt: -1 } },\n );\n if (version) {\n const versionData = version.data || {};\n processedDoc = { ...processedDoc, ...versionData, status: processedDoc.status };\n }\n }\n\n return processedDoc;\n }\n\n async findVersions(args: FindVersionsArgs): Promise<FindResult<VersionRecord>> {\n const { collection: slug, documentId, sort, limit = 10, page = 1, tenantID } = args;\n \n // Versions stored in a separate collection; exclude ephemeral autosave versions\n const versionCollection = this.getMongoCollection(`${slug}_versions`);\n const filter: any = { document_id: documentId, autosave: { $ne: true } };\n if (tenantID) filter.tenant_id = tenantID;\n\n const skip = (page - 1) * limit;\n const sortOption = this.parseSort(sort);\n const sortObj: Record<string, 1 | -1> = {\n [sortOption.field]: sortOption.direction === 'asc' ? 1 : -1,\n };\n\n const [docs, totalDocs] = await Promise.all([\n versionCollection.find(filter).sort(sortObj).skip(skip).limit(limit).toArray(),\n versionCollection.countDocuments(filter),\n ]);\n\n return {\n docs: docs.map((doc: any) => this.processResult(doc, {} as CollectionConfig) as VersionRecord),\n ...this.calculatePagination(page, limit, totalDocs),\n };\n }\n\n async findVersionByID(args: { collection: string; versionId: string; tenantID?: string }): Promise<VersionRecord | null> {\n const { collection: slug, versionId, tenantID } = args;\n const versionCollection = this.getMongoCollection(`${slug}_versions`);\n const filter: any = { _id: versionId };\n if (tenantID) filter.tenant_id = tenantID;\n \n const doc = await versionCollection.findOne(filter);\n return doc ? this.processResult(doc, {} as CollectionConfig) as VersionRecord : null;\n }\n\n async createVersion<T = Record<string, any>>(args: CreateVersionArgs<T>): Promise<VersionRecord<T>> {\n const { collection: slug, documentId, data, status, createdBy, changeDescription, tenantID, autosave } = args;\n const versionCollection = this.getMongoCollection(`${slug}_versions`);\n\n // Autosave: reuse existing autosave slot instead of creating a new row\n if (autosave) {\n const filter: any = { document_id: documentId, collection_slug: slug, autosave: true };\n if (tenantID) filter.tenant_id = tenantID;\n const existing = await versionCollection.findOne(filter);\n if (existing) {\n const now = new Date().toISOString();\n await versionCollection.updateOne(\n { _id: existing._id },\n { $set: { data, status, updatedAt: now } },\n );\n return this.processResult({ ...existing, data, status, updatedAt: now }, {} as CollectionConfig) as VersionRecord<T>;\n }\n }\n\n const now = new Date().toISOString();\n const versionDoc: any = {\n _id: this.generateId(),\n document_id: documentId,\n collection_slug: slug,\n tenant_id: tenantID,\n data,\n status,\n autosave: autosave === true,\n created_by: createdBy,\n change_description: changeDescription,\n createdAt: now,\n updatedAt: now,\n };\n\n await versionCollection.insertOne(versionDoc);\n \n // Pruning logic — skip for autosave versions\n if (!autosave) {\n const config = this.getCollectionConfig(slug);\n if (config.versions?.maxPerDoc) {\n await this.deleteVersions({\n collection: slug,\n documentId: documentId,\n keepLatest: config.versions.maxPerDoc,\n tenantID: tenantID,\n });\n }\n }\n\n return this.processResult(versionDoc, {} as CollectionConfig) as VersionRecord<T>;\n }\n\n async updateLatestVersion<T = Record<string, any>>(args: CreateVersionArgs<T>): Promise<VersionRecord<T>> {\n return this.createVersion({ ...args, autosave: true });\n }\n\n async deleteVersions(args: { collection: string; documentId: string; keepLatest?: number; tenantID?: string }): Promise<void> {\n const { collection: slug, documentId, keepLatest, tenantID } = args;\n const versionCollection = this.getMongoCollection(`${slug}_versions`);\n \n if (keepLatest) {\n const filter: any = { document_id: documentId, autosave: { $ne: true } };\n if (tenantID) filter.tenant_id = tenantID;\n\n const toKeep = await versionCollection\n .find(filter)\n .sort({ createdAt: -1 })\n .limit(keepLatest)\n .project({ _id: 1 })\n .toArray();\n\n const keepIds = toKeep.map((doc: any) => doc._id);\n if (keepIds.length > 0) {\n await versionCollection.deleteMany({\n document_id: documentId,\n autosave: { $ne: true },\n _id: { $nin: keepIds },\n ...(tenantID ? { tenant_id: tenantID } : {}),\n });\n }\n } else {\n const filter: any = { document_id: documentId };\n if (tenantID) filter.tenant_id = tenantID;\n await versionCollection.deleteMany(filter);\n }\n }\n\n\n\n async migrate?(): Promise<void> {\n // Create indexes for all collections\n for (const config of this.collections.values()) {\n const col = this.getMongoCollection(config.slug);\n\n // Create default indexes\n await col.createIndex({ _id: 1 });\n \n if (config.tenantScoped) {\n await col.createIndex({ tenantId: 1 });\n }\n\n if (config.timestamps) {\n await col.createIndex({ createdAt: -1 });\n }\n\n // Create unique indexes\n for (const field of config.fields) {\n if (field.unique && field.name) {\n await col.createIndex({ [field.name]: 1 }, { unique: true });\n }\n if (field.indexed && field.name) {\n await col.createIndex({ [field.name]: 1 });\n }\n }\n }\n\n\n }\n\n // ========================================================================\n // Helper Methods\n // ========================================================================\n\n private getCollectionConfig(slug: string): CollectionConfig {\n const config = this.collections.get(slug);\n if (!config) {\n throw new Error(`Collection \"${slug}\" not found`);\n }\n return config;\n }\n\n private buildFilter(where: Record<string, any> = {}, tenantID?: string): Record<string, any> {\n const filter: Record<string, any> = {};\n\n // Apply tenant filter\n if (tenantID) {\n filter.tenantId = tenantID;\n }\n\n // Convert operators to MongoDB format\n for (const [key, value] of Object.entries(where)) {\n if (key === 'AND' && Array.isArray(value)) {\n const andConditions = value.map((v: any) => this.buildFilter(v));\n Object.assign(filter, ...andConditions);\n } else if (key === 'OR' && Array.isArray(value)) {\n filter.$or = value.map((v: any) => this.buildFilter(v));\n } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n // Operator-based conditions\n const mongoOperators: Record<string, any> = {};\n \n if (value.equals !== undefined) {\n filter[key === 'id' ? '_id' : key] = value.equals;\n continue;\n }\n if (value.not_equals !== undefined) {\n mongoOperators.$ne = value.not_equals;\n }\n if (value.in !== undefined) {\n mongoOperators.$in = value.in;\n }\n if (value.not_in !== undefined) {\n mongoOperators.$nin = value.not_in;\n }\n if (value.greater_than !== undefined) {\n mongoOperators.$gt = value.greater_than;\n }\n if (value.greater_than_equal !== undefined) {\n mongoOperators.$gte = value.greater_than_equal;\n }\n if (value.less_than !== undefined) {\n mongoOperators.$lt = value.less_than;\n }\n if (value.less_than_equal !== undefined) {\n mongoOperators.$lte = value.less_than_equal;\n }\n if (value.like !== undefined) {\n mongoOperators.$regex = new RegExp(value.like.replace(/%/g, '.*'), 'i');\n }\n if (value.not_like !== undefined) {\n mongoOperators.$not = new RegExp(value.not_like.replace(/%/g, '.*'), 'i');\n }\n if (value.contains !== undefined) {\n mongoOperators.$regex = new RegExp(`.*${value.contains}.*`, 'i');\n }\n if (value.exists !== undefined) {\n mongoOperators.$exists = value.exists;\n }\n\n if (Object.keys(mongoOperators).length > 0) {\n filter[key === 'id' ? '_id' : key] = mongoOperators;\n }\n } else {\n // Direct equality\n filter[key === 'id' ? '_id' : key] = value;\n }\n }\n\n return filter;\n } private buildProjection(select?: string[]): Record<string, 1> | undefined {\n if (!select || select.length === 0) return undefined;\n \n const projection: Record<string, 1> = { _id: 1 };\n for (const field of select) {\n projection[field] = 1;\n }\n return projection;\n }\n\n private processResult(data: any, config: CollectionConfig): any {\n if (!data) return null;\n\n const result = { ...data };\n\n // Convert _id to id\n if (data._id) {\n result.id = data._id;\n delete result._id;\n }\n\n // Remove MongoDB internals\n delete result.__v;\n\n // Convert dates to ISO strings\n if (result.createdAt) {\n result.createdAt = new Date(result.createdAt).toISOString();\n }\n if (result.updatedAt) {\n result.updatedAt = new Date(result.updatedAt).toISOString();\n }\n\n return result;\n }\n\n private generateId(): string {\n const timestamp = Date.now().toString(16).padStart(12, '0');\n const random = randomBytes(6).toString('hex');\n return timestamp + random;\n }\n}\n\n// ============================================================================\n// Factory Function\n// ============================================================================\n\nexport function createMongoDBAdapter(options: {\n client?: any;\n database?: string;\n connectionString?: string;\n}): MongoDBAdapter {\n return new MongoDBAdapter(options);\n}\n"]}
|
|
@@ -719,11 +719,6 @@ var EmailTransport = class _EmailTransport {
|
|
|
719
719
|
const { provider, from, fromName, replyTo: configReplyTo } = this.config;
|
|
720
720
|
const fromFull = `"${fromName || "Kyro CMS"}" <${from}>`;
|
|
721
721
|
const replyTo = options.replyTo || configReplyTo;
|
|
722
|
-
console.log(`[EmailTransport] Sending email via ${provider}...`);
|
|
723
|
-
console.log(
|
|
724
|
-
`[EmailTransport] To: ${Array.isArray(options.to) ? options.to.join(", ") : options.to}`
|
|
725
|
-
);
|
|
726
|
-
console.log(`[EmailTransport] Subject: ${options.subject}`);
|
|
727
722
|
try {
|
|
728
723
|
let result;
|
|
729
724
|
switch (provider) {
|
|
@@ -755,7 +750,6 @@ var EmailTransport = class _EmailTransport {
|
|
|
755
750
|
default:
|
|
756
751
|
throw new Error(`Unsupported email provider: ${provider}`);
|
|
757
752
|
}
|
|
758
|
-
console.log(`[EmailTransport] Success! Provider response received.`);
|
|
759
753
|
return result;
|
|
760
754
|
} catch (error) {
|
|
761
755
|
console.error(`[EmailTransport] FAILED to send email:`, error.message);
|
|
@@ -779,7 +773,6 @@ var EmailTransport = class _EmailTransport {
|
|
|
779
773
|
text: options.text,
|
|
780
774
|
reply_to: replyTo
|
|
781
775
|
};
|
|
782
|
-
console.log(`[EmailTransport] Calling Resend API...`);
|
|
783
776
|
const resp = await fetch("https://api.resend.com/emails", {
|
|
784
777
|
method: "POST",
|
|
785
778
|
headers: {
|
|
@@ -814,7 +807,6 @@ var EmailTransport = class _EmailTransport {
|
|
|
814
807
|
],
|
|
815
808
|
reply_to: replyTo ? { email: replyTo } : void 0
|
|
816
809
|
};
|
|
817
|
-
console.log(`[EmailTransport] Calling SendGrid API...`);
|
|
818
810
|
const resp = await fetch("https://api.sendgrid.com/v3/mail/send", {
|
|
819
811
|
method: "POST",
|
|
820
812
|
headers: {
|
|
@@ -842,7 +834,6 @@ var EmailTransport = class _EmailTransport {
|
|
|
842
834
|
formData.append("html", options.html);
|
|
843
835
|
if (options.text) formData.append("text", options.text);
|
|
844
836
|
if (replyTo) formData.append("h:Reply-To", replyTo);
|
|
845
|
-
console.log(`[EmailTransport] Calling Mailgun API (${region || "us"})...`);
|
|
846
837
|
const resp = await fetch(`https://${base}/v3/${domain}/messages`, {
|
|
847
838
|
method: "POST",
|
|
848
839
|
headers: {
|
|
@@ -1144,5 +1135,5 @@ var PasswordPolicy = class {
|
|
|
1144
1135
|
exports.ConfigService = ConfigService;
|
|
1145
1136
|
exports.EmailTransport = EmailTransport;
|
|
1146
1137
|
exports.PasswordPolicy = PasswordPolicy;
|
|
1147
|
-
//# sourceMappingURL=chunk-
|
|
1148
|
-
//# sourceMappingURL=chunk-
|
|
1138
|
+
//# sourceMappingURL=chunk-VKREAIBA.cjs.map
|
|
1139
|
+
//# sourceMappingURL=chunk-VKREAIBA.cjs.map
|