@neetru/sdk 3.1.9 → 3.1.10
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/ai.cjs +304 -0
- package/dist/ai.cjs.map +1 -0
- package/dist/ai.d.cts +3 -0
- package/dist/ai.d.ts +3 -0
- package/dist/ai.mjs +302 -0
- package/dist/ai.mjs.map +1 -0
- package/dist/auth.cjs +283 -1
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/auth.mjs +283 -1
- package/dist/auth.mjs.map +1 -1
- package/dist/catalog.d.cts +1 -1
- package/dist/catalog.d.ts +1 -1
- package/dist/checkout.d.cts +1 -1
- package/dist/checkout.d.ts +1 -1
- package/dist/db-react.d.cts +1 -1
- package/dist/db-react.d.ts +1 -1
- package/dist/db.d.cts +1 -1
- package/dist/db.d.ts +1 -1
- package/dist/entitlements.d.cts +1 -1
- package/dist/entitlements.d.ts +1 -1
- package/dist/firestore-compat.d.cts +1 -1
- package/dist/firestore-compat.d.ts +1 -1
- package/dist/index.cjs +286 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.mjs +285 -3
- package/dist/index.mjs.map +1 -1
- package/dist/mocks.cjs +52 -0
- package/dist/mocks.cjs.map +1 -1
- package/dist/mocks.d.cts +20 -2
- package/dist/mocks.d.ts +20 -2
- package/dist/mocks.mjs +52 -1
- package/dist/mocks.mjs.map +1 -1
- package/dist/notifications.d.cts +1 -1
- package/dist/notifications.d.ts +1 -1
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/support.d.cts +1 -1
- package/dist/support.d.ts +1 -1
- package/dist/telemetry.d.cts +1 -1
- package/dist/telemetry.d.ts +1 -1
- package/dist/{types-DDiVzgCT.d.cts → types-Cog9S-tC.d.cts} +84 -1
- package/dist/{types-HWDOUmlC.d.ts → types-dagUxKYz.d.ts} +84 -1
- package/dist/usage.d.cts +1 -1
- package/dist/usage.d.ts +1 -1
- package/dist/webhooks.d.cts +1 -1
- package/dist/webhooks.d.ts +1 -1
- package/package.json +6 -1
package/dist/mocks.cjs
CHANGED
|
@@ -642,8 +642,60 @@ var MockDb = class {
|
|
|
642
642
|
this._store.clear();
|
|
643
643
|
}
|
|
644
644
|
};
|
|
645
|
+
var MockAi = class {
|
|
646
|
+
_calls = [];
|
|
647
|
+
_reply(opts) {
|
|
648
|
+
const last = [...opts.messages].reverse().find((m) => m.role === "user") ?? opts.messages[opts.messages.length - 1];
|
|
649
|
+
const content = last?.content ?? "";
|
|
650
|
+
return content ? `mock-reply: ${content}` : "mock-reply";
|
|
651
|
+
}
|
|
652
|
+
async chat(opts) {
|
|
653
|
+
if (!opts || typeof opts.model !== "string" || opts.model.length === 0) {
|
|
654
|
+
throw new NeetruError("validation_failed", "ai: model is required");
|
|
655
|
+
}
|
|
656
|
+
if (!Array.isArray(opts.messages) || opts.messages.length === 0) {
|
|
657
|
+
throw new NeetruError("validation_failed", "ai: messages must be a non-empty array");
|
|
658
|
+
}
|
|
659
|
+
this._calls.push({ model: opts.model, messages: opts.messages, stream: false });
|
|
660
|
+
const text = this._reply(opts);
|
|
661
|
+
const promptTokens = opts.messages.reduce((n, m) => n + (m.content?.length ?? 0), 0);
|
|
662
|
+
const completionTokens = text.length;
|
|
663
|
+
return {
|
|
664
|
+
choices: [{ message: { role: "assistant", content: text }, finish_reason: "stop" }],
|
|
665
|
+
usage: {
|
|
666
|
+
prompt_tokens: promptTokens,
|
|
667
|
+
completion_tokens: completionTokens,
|
|
668
|
+
total_tokens: promptTokens + completionTokens
|
|
669
|
+
},
|
|
670
|
+
model: opts.model,
|
|
671
|
+
provider: "mock",
|
|
672
|
+
usageWarning: false
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
stream(opts) {
|
|
676
|
+
if (!opts || typeof opts.model !== "string" || opts.model.length === 0) {
|
|
677
|
+
throw new NeetruError("validation_failed", "ai: model is required");
|
|
678
|
+
}
|
|
679
|
+
if (!Array.isArray(opts.messages) || opts.messages.length === 0) {
|
|
680
|
+
throw new NeetruError("validation_failed", "ai: messages must be a non-empty array");
|
|
681
|
+
}
|
|
682
|
+
this._calls.push({ model: opts.model, messages: opts.messages, stream: true });
|
|
683
|
+
const text = this._reply(opts);
|
|
684
|
+
const parts = text.match(/\S+\s*/g) ?? [text];
|
|
685
|
+
const meta = Promise.resolve({ provider: "mock", usageWarning: false });
|
|
686
|
+
async function* iterate() {
|
|
687
|
+
for (const p of parts) yield p;
|
|
688
|
+
}
|
|
689
|
+
return { meta, [Symbol.asyncIterator]: iterate };
|
|
690
|
+
}
|
|
691
|
+
/** Test helper — histórico de chamadas. */
|
|
692
|
+
__getCalls() {
|
|
693
|
+
return this._calls;
|
|
694
|
+
}
|
|
695
|
+
};
|
|
645
696
|
|
|
646
697
|
exports.DEV_FIXTURE_USER = DEV_FIXTURE_USER;
|
|
698
|
+
exports.MockAi = MockAi;
|
|
647
699
|
exports.MockAuth = MockAuth;
|
|
648
700
|
exports.MockDb = MockDb;
|
|
649
701
|
exports.MockEntitlements = MockEntitlements;
|
package/dist/mocks.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/db-errors.ts","../src/mocks.ts"],"names":[],"mappings":";;;AA6CO,IAAM,WAAA,GAAN,MAAM,YAAA,SAAoB,KAAA,CAAM;AAAA,EACrB,IAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EAEhB,WAAA,CACE,IAAA,EACA,OAAA,EACA,MAAA,EACA,SAAA,EACA;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,aAAA;AACZ,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AAEjB,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,YAAA,CAAY,SAAS,CAAA;AAAA,EACnD;AACF,CAAA;;;ACtBA,IAAM,eAAA,uBAAsB,GAAA,CAAuB;AAAA,EACjD,gBAAA;AAAA,EACA,aAAA;AAAA,EACA;AACF,CAAC,CAAA;AAgBM,IAAM,aAAA,GAAN,MAAM,cAAA,SAAsB,WAAA,CAAY;AAAA;AAAA,EAEpB,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMT,SAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAA;AAAA,EAEhB,WAAA,CAAY,IAAA,EAAyB,OAAA,EAAiB,IAAA,EAAe;AACnE,IAAA,KAAA,CAAM,MAAM,OAAO,CAAA;AACnB,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AACZ,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,SAAA,GAAY,eAAA,CAAgB,GAAA,CAAI,IAAI,CAAA;AACzC,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AAEZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,cAAA,CAAc,SAAS,CAAA;AAAA,EACrD;AACF,CAAA;;;ACtCO,IAAM,gBAAA,GAA+B,OAAO,MAAA,CAAO;AAAA,EACxD,GAAA,EAAK,sBAAA;AAAA,EACL,KAAA,EAAO,kBAAA;AAAA,EACP,aAAA,EAAe,IAAA;AAAA,EACf,WAAA,EAAa,aAAA;AAAA,EACb,UAAA,EAAY,IAAA;AAAA,EACZ,OAAA,EAAS;AACX,CAAC;AAuBM,IAAM,WAAN,MAAwC;AAAA,EACrC,KAAA;AAAA,EACA,UAAA;AAAA,EACA,oBAAA;AAAA,EAER,WAAA,CAAY,WAAA,GAAiC,IAAA,EAAM,OAAA,EAA2B;AAC5E,IAAA,IAAA,CAAK,KAAA,GAAQ,WAAA;AACb,IAAA,IAAA,CAAK,UAAA,uBAAiB,GAAA,EAAI;AAC1B,IAAA,IAAA,CAAK,oBAAA,GAAuB,SAAS,mBAAA,IAAuB,KAAA;AAM5D,IAAA,IAAI,KAAK,oBAAA,EAAsB;AAC7B,MAAA,MAAM,SAAA,GACH,OAAO,OAAA,KAAY,WAAA,KAClB,QAAQ,GAAA,EAAK,QAAA,KAAa,MAAA,IAC1B,OAAA,CAAQ,GAAA,EAAK,MAAA,KAAW,MAAA,IACxB,OAAA,CAAQ,KAAK,MAAA,IAAU,IAAA,CAAA;AAE3B,MAAA,IAAI,CAAC,SAAA,IAAa,OAAO,OAAA,KAAY,WAAA,EAAa;AAChD,QAAA,OAAA,CAAQ,IAAA;AAAA,UACN;AAAA,SAGF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,QAAA,EAA+C;AAE1D,IAAA,IAAI,CAAC,IAAA,CAAK,KAAA,OAAY,KAAA,GAAQ,EAAE,GAAG,gBAAA,EAAiB;AACpD,IAAA,IAAA,CAAK,OAAA,EAAQ;AACb,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA,EAEA,MAAM,OAAA,GAAyB;AAC7B,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AACb,IAAA,IAAA,CAAK,OAAA,EAAQ;AAAA,EACf;AAAA,EAEA,OAAA,GAA6B;AAC3B,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA,EAEA,mBAAmB,QAAA,EAAyC;AAC1D,IAAA,IAAA,CAAK,UAAA,CAAW,IAAI,QAAQ,CAAA;AAE5B,IAAA,IAAI;AACF,MAAA,QAAA,CAAS,KAAK,KAAK,CAAA;AAAA,IACrB,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,OAAO,MAAM;AACX,MAAA,IAAA,CAAK,UAAA,CAAW,OAAO,QAAQ,CAAA;AAAA,IACjC,CAAA;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,YAAY,KAAA,EAAoC;AACpD,IAAA,IAAI,KAAK,oBAAA,EAAsB;AAC7B,MAAA,OAAO,IAAA,CAAK,qBAAqB,KAAK,CAAA;AAAA,IACxC;AACA,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,MAAM,IAAI,WAAA,CAAY,yBAAA,EAA2B,iCAA8B,CAAA;AAAA,IACjF;AAMA,IAAA,IAAI,CAAC,KAAK,oBAAA,EAAsB;AAC9B,MAAA,MAAM,IAAI,WAAA;AAAA,QACR,cAAA;AAAA,QACA;AAAA,OAIF;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA;AAC7B,MAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,QAAA,MAAM,GAAA,GAAM,KAAA,CAAM,CAAC,CAAA,CAAE,OAAA,CAAQ,MAAM,GAAG,CAAA,CAAE,OAAA,CAAQ,IAAA,EAAM,GAAG,CAAA;AACzD,QAAA,MAAM,MAAM,GAAA,CAAI,MAAA,CAAA,CAAQ,IAAK,GAAA,CAAI,MAAA,GAAS,KAAM,CAAC,CAAA;AACjD,QAAA,MAAM,UAAU,IAAA,CAAK,KAAA;AAAA,UACnB,OAAO,IAAA,KAAS,UAAA,GACZ,IAAA,CAAK,MAAM,GAAG,CAAA,GACd,MAAA,CAAO,IAAA,CAAK,GAAA,GAAM,GAAA,EAAK,QAAQ,CAAA,CAAE,SAAS,OAAO;AAAA,SACvD;AACA,QAAA,IAAI,OAAO,OAAA,CAAQ,GAAA,KAAQ,QAAA,EAAU;AACnC,UAAA,OAAO;AAAA,YACL,KAAK,OAAA,CAAQ,GAAA;AAAA,YACb,OAAO,OAAO,OAAA,CAAQ,KAAA,KAAU,QAAA,GAAW,QAAQ,KAAA,GAAQ,EAAA;AAAA,YAC3D,eAAe,OAAO,OAAA,CAAQ,cAAA,KAAmB,SAAA,GAAY,QAAQ,cAAA,GAAiB,KAAA,CAAA;AAAA,YACtF,aAAa,OAAO,OAAA,CAAQ,IAAA,KAAS,QAAA,GAAW,QAAQ,IAAA,GAAO,KAAA,CAAA;AAAA,YAC/D,UAAU,OAAO,OAAA,CAAQ,OAAA,KAAY,QAAA,GAAW,QAAQ,OAAA,GAAU,KAAA,CAAA;AAAA,YAClE,OAAA,EAAS,QAAQ,QAAA,KAAa,IAAA;AAAA,YAC9B,UAAA,EAAY,QAAQ,WAAA,KAAgB,IAAA;AAAA,YACpC,UAAU,OAAO,OAAA,CAAQ,SAAA,KAAc,QAAA,GAAW,QAAQ,SAAA,GAAY,KAAA,CAAA;AAAA,YACtE,GAAG;AAAA,WACL;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAEA,IAAA,IAAI,IAAA,CAAK,KAAA,EAAO,OAAO,IAAA,CAAK,KAAA;AAC5B,IAAA,MAAM,IAAI,WAAA,CAAY,yBAAA,EAA2B,wDAAkD,CAAA;AAAA,EACrG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,uBAAuB,WAAA,EAA8D;AACzF,IAAA,OAAO,IAAA,CAAK,gBAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAA,GAA4B;AAC1B,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EACd;AAAA,EAEQ,gBAAA,GAAkD,IAAA;AAAA,EAClD,QAAA,GAA0B,IAAA;AAAA;AAAA,EAGlC,qBAAqB,MAAA,EAA6C;AAChE,IAAA,IAAA,CAAK,gBAAA,GAAmB,MAAA;AAAA,EAC1B;AAAA;AAAA,EAGA,aAAa,KAAA,EAA4B;AACvC,IAAA,IAAA,CAAK,QAAA,GAAW,KAAA;AAAA,EAClB;AAAA,EAEQ,oBAAA,GAAwE,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYhF,kBAAkB,EAAA,EAA2D;AAC3E,IAAA,IAAA,CAAK,oBAAA,GAAuB,EAAA;AAAA,EAC9B;AAAA;AAAA,EAGA,UAAU,IAAA,EAA+B;AACvC,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AACb,IAAA,IAAA,CAAK,OAAA,EAAQ;AAAA,EACf;AAAA,EAEQ,OAAA,GAAgB;AACtB,IAAA,KAAA,MAAW,CAAA,IAAK,KAAK,UAAA,EAAY;AAC/B,MAAA,IAAI;AACF,QAAA,CAAA,CAAE,KAAK,KAAK,CAAA;AAAA,MACd,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACF;AAqBO,IAAM,YAAN,MAA0C;AAAA,EACvC,WAAgC,EAAC;AAAA,EACjC,OAAA;AAAA,EACA,SAAA,uBAAqC,GAAA,EAAI;AAAA,EAEjD,WAAA,CAAY,aAAA,GAA4C,EAAC,EAAG;AAC1D,IAAA,IAAA,CAAK,UAAU,IAAI,GAAA,CAAI,MAAA,CAAO,OAAA,CAAQ,aAAa,CAAC,CAAA;AAAA,EACtD;AAAA,EAEA,MAAM,MAAA,CACJ,QAAA,EACA,GAAA,GAAc,GACd,OAAA,EAQC;AACD,IAAA,IAAI,CAAC,QAAA,EAAU,MAAM,IAAI,MAAM,mBAAmB,CAAA;AAClD,IAAA,MAAM,OAAA,GAAU,MAAA,CAAO,QAAA,CAAS,GAAG,CAAA,IAAK,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,GAAI,CAAA;AACpE,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,QAAQ,CAAA,IAAK,CAAA;AACjD,IAAA,MAAM,OAAO,QAAA,GAAW,OAAA;AACxB,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,QAAA,EAAU,IAAI,CAAA;AACjC,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK;AAAA,MACjB,QAAA;AAAA,MACA,GAAA,EAAK,OAAA;AAAA,MACL,WAAW,OAAA,EAAS,SAAA;AAAA,MACpB,UAAU,OAAA,EAAS,QAAA;AAAA,MACnB,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,KACnC,CAAA;AACD,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA;AAC9C,IAAA,MAAM,KAAA,GAAQ,cAAc,KAAA,IAAS,EAAA;AACrC,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,IAAA;AAAA,MACJ,SAAA,EAAW,QAAQ,QAAQ,CAAA,CAAA;AAAA,MAC3B,KAAA,EAAO,IAAA;AAAA,MACP,KAAA;AAAA,MACA,SAAA,EAAW,QAAQ,CAAA,GAAI,EAAA,GAAK,KAAK,GAAA,CAAI,CAAA,EAAG,QAAQ,IAAI,CAAA;AAAA,MACpD,MAAA,EAAQ,KAAA,GAAQ,CAAA,IAAK,IAAA,IAAQ,QAAQ,qBAAA,GAAwB;AAAA,KAC/D;AAAA,EACF;AAAA,EAEA,MAAM,KAAA,CACJ,QAAA,EACA,QAAA,EASC;AACD,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA;AACvC,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,QAAQ,CAAA,IAAK,CAAA;AAC7C,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,MAAA,EAAQ,SAAA,EAAW,OAAO,EAAA,EAAI,SAAA,EAAW,EAAA,EAAI,QAAA,EAAU,IAAA,EAAK;AAAA,IACtF;AACA,IAAA,MAAM,SAAA,GAAY,KAAA,CAAM,KAAA,GAAQ,CAAA,GAAI,EAAA,GAAK,KAAK,GAAA,CAAI,CAAA,EAAG,KAAA,CAAM,KAAA,GAAQ,IAAI,CAAA;AACvE,IAAA,IAAI,cAAc,CAAA,EAAG;AACnB,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,MAAA,EAAQ,gBAAA;AAAA,QACR,OAAO,KAAA,CAAM,KAAA;AAAA,QACb,SAAA,EAAW,CAAA;AAAA,QACX,QAAA,EAAU;AAAA,OACZ;AAAA,IACF;AACA,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,IAAA;AAAA,MACT,MAAA,EAAQ,SAAA;AAAA,MACR,OAAO,KAAA,CAAM,KAAA;AAAA,MACb,SAAA;AAAA,MACA,QAAA,EAAU;AAAA,KACZ;AAAA,EACF;AAAA;AAAA,EAGA,YAAA,GAA6C;AAC3C,IAAA,OAAO,CAAC,GAAG,IAAA,CAAK,QAAQ,CAAA;AAAA,EAC1B;AAAA;AAAA,EAEA,YAAA,GAA6C;AAC3C,IAAA,OAAO,KAAK,YAAA,EAAa;AAAA,EAC3B;AAAA;AAAA,EAEA,UAAA,CAAW,QAAgB,KAAA,EAAyB;AAClD,IAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,MAAA,EAAQ,KAAK,CAAA;AAAA,EAChC;AAAA;AAAA,EAEA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,WAAW,EAAC;AACjB,IAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AACnB,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AAAA,EACvB;AACF;AASO,IAAM,cAAN,MAA8C;AAAA,EAC3C,WAA4B,EAAC;AAAA,EAC7B,UAAA,GAAa,CAAA;AAAA,EAErB,MAAM,aAAa,KAAA,EAAkD;AAInE,IAAA,IAAI,CAAC,KAAA,EAAO,OAAA,QAAe,IAAI,WAAA,CAAY,qBAAqB,kBAAkB,CAAA;AAClF,IAAA,IAAI,CAAC,KAAA,EAAO,OAAA,QAAe,IAAI,WAAA,CAAY,qBAAqB,kBAAkB,CAAA;AAClF,IAAA,IAAI,CAAC,OAAO,WAAA,EAAa;AACvB,MAAA,MAAM,IAAI,WAAA;AAAA,QACR,mBAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF;AACA,IAAA,MAAM,MAAA,GAAwB;AAAA,MAC5B,EAAA,EAAI,CAAA,YAAA,EAAe,EAAE,IAAA,CAAK,UAAU,CAAA,CAAA;AAAA,MACpC,SAAS,KAAA,CAAM,OAAA;AAAA,MACf,SAAS,KAAA,CAAM,OAAA;AAAA,MACf,QAAA,EAAU,MAAM,QAAA,IAAY,QAAA;AAAA,MAC5B,MAAA,EAAQ,MAAA;AAAA,MACR,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,MAClC,aAAa,KAAA,CAAM;AAAA,KACrB;AACA,IAAA,IAAA,CAAK,QAAA,CAAS,KAAK,MAAM,CAAA;AACzB,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,OAAA,EAA8D;AAChF,IAAA,IAAI,SAAS,WAAA,EAAa;AACxB,MAAA,OAAO,IAAA,CAAK,SAAS,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,WAAA,KAAgB,QAAQ,WAAW,CAAA;AAAA,IAC1E;AACA,IAAA,OAAO,CAAC,GAAG,IAAA,CAAK,QAAQ,CAAA;AAAA,EAC1B;AAAA;AAAA,EAGA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,WAAW,EAAC;AACjB,IAAA,IAAA,CAAK,UAAA,GAAa,CAAA;AAAA,EACpB;AACF;AAQO,IAAM,mBAAN,MAAuB;AAAA,EACpB,OAAA,uBAA2B,GAAA,EAAI;AAAA,EAEvC,MAAM,KAAA,CAAM,WAAA,EAAqB,OAAA,EAAmC;AAClE,IAAA,OAAO,CAAC,KAAK,OAAA,CAAQ,GAAA,CAAI,GAAG,WAAW,CAAA,CAAA,EAAI,OAAO,CAAA,CAAE,CAAA;AAAA,EACtD;AAAA,EAEA,MAAM,aAAA,CAAc,WAAA,EAAqB,OAAA,EAA4C;AACnF,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,KAAA,CAAM,aAAa,OAAO,CAAA;AACrD,IAAA,OAAO;AAAA,MACL,OAAA;AAAA,MACA,WAAA;AAAA,MACA,OAAA;AAAA,MACA,MAAA,EAAQ,UAAU,SAAA,GAAY;AAAA,KAChC;AAAA,EACF;AAAA;AAAA,EAGA,MAAA,CAAO,aAAqB,OAAA,EAAuB;AACjD,IAAA,IAAA,CAAK,QAAQ,GAAA,CAAI,CAAA,EAAG,WAAW,CAAA,CAAA,EAAI,OAAO,CAAA,CAAE,CAAA;AAAA,EAC9C;AAAA;AAAA,EAEA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AAAA,EACrB;AACF;AAaO,IAAM,SAAN,MAAiC;AAAA,EAC9B,MAAA,uBAAgE,GAAA,EAAI;AAAA,EACpE,SAAA;AAAA,EAER,WAAA,CAAY,eAAA,GAA2E,EAAC,EAAG;AACzF,IAAA,IAAA,CAAK,YAAY,IAAI,GAAA,CAAI,MAAA,CAAO,OAAA,CAAQ,eAAe,CAAC,CAAA;AAAA,EAC1D;AAAA,EAEA,WAAwC,IAAA,EAAkC;AACxE,IAAA,MAAM,SAAS,IAAA,CAAK,MAAA;AACpB,IAAA,MAAM,YAAY,IAAA,CAAK,SAAA;AACvB,IAAA,IAAI,CAAC,MAAA,CAAO,GAAA,CAAI,IAAI,CAAA,EAAG;AACrB,MAAA,MAAM,IAAA,GAAO,SAAA,CAAU,GAAA,CAAI,IAAI,CAAA;AAC/B,MAAA,MAAA,CAAO,GAAA;AAAA,QACL,IAAA;AAAA,QACA,IAAA,GAAO,IAAI,GAAA,CAAI,MAAA,CAAO,QAAQ,IAAI,CAAC,CAAA,mBAAI,IAAI,GAAA;AAAI,OACjD;AAAA,IACF;AACA,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,GAAA,CAAI,IAAI,CAAA;AAE5B,IAAA,MAAM,aAAA,GAAgB,CACpB,GAAA,EACA,CAAA,KACY;AACZ,MAAA,MAAM,CAAA,GAAI,GAAA,CAAI,CAAA,CAAE,KAAK,CAAA;AACrB,MAAA,QAAQ,EAAE,EAAA;AAAI,QACZ,KAAK,IAAA;AACH,UAAA,OAAO,MAAM,CAAA,CAAE,KAAA;AAAA,QACjB,KAAK,IAAA;AACH,UAAA,OAAO,MAAM,CAAA,CAAE,KAAA;AAAA,QACjB,KAAK,GAAA;AACH,UAAA,OAAO,OAAO,MAAM,QAAA,IAAY,OAAO,EAAE,KAAA,KAAU,QAAA,IAAY,IAAI,CAAA,CAAE,KAAA;AAAA,QACvE,KAAK,IAAA;AACH,UAAA,OAAO,OAAO,MAAM,QAAA,IAAY,OAAO,EAAE,KAAA,KAAU,QAAA,IAAY,KAAK,CAAA,CAAE,KAAA;AAAA,QACxE,KAAK,GAAA;AACH,UAAA,OAAO,OAAO,MAAM,QAAA,IAAY,OAAO,EAAE,KAAA,KAAU,QAAA,IAAY,IAAI,CAAA,CAAE,KAAA;AAAA,QACvE,KAAK,IAAA;AACH,UAAA,OAAO,OAAO,MAAM,QAAA,IAAY,OAAO,EAAE,KAAA,KAAU,QAAA,IAAY,KAAK,CAAA,CAAE,KAAA;AAAA,QACxE,KAAK,IAAA;AACH,UAAA,OAAO,KAAA,CAAM,QAAQ,CAAA,CAAE,KAAK,KAAM,CAAA,CAAE,KAAA,CAAoB,SAAS,CAAC,CAAA;AAAA,QACpE,KAAK,gBAAA;AACH,UAAA,OAAO,MAAM,OAAA,CAAQ,CAAC,KAAM,CAAA,CAAgB,QAAA,CAAS,EAAE,KAAK,CAAA;AAAA,QAC9D,KAAK,QAAA;AACH,UAAA,OAAO,KAAA,CAAM,QAAQ,CAAA,CAAE,KAAK,KAAK,CAAE,CAAA,CAAE,KAAA,CAAoB,QAAA,CAAS,CAAC,CAAA;AAAA,QACrE;AACE,UAAA,OAAO,IAAA;AAAA;AACX,IACF,CAAA;AAEA,IAAA,IAAI,OAAA,GAAU,CAAA;AAGd,IAAA,SAAS,gBAAmB,KAAA,EAAwD;AAClF,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,KAAA,CAAM,GAAA,CAAI,CAAC,GAAG,CAAA,MAAO,EAAE,EAAA,EAAK,CAAA,CAAE,MAAiB,MAAA,CAAO,CAAC,CAAA,EAAG,IAAA,EAAM,GAAO,CAAE,CAAA;AAAA,QAC/E,UAAA,EAAY,IAAA;AAAA,QACZ,SAAA,EAAW,KAAA;AAAA,QACX,KAAA,EAAO,KAAA;AAAA,QACP,gBAAA,EAAkB,KAAA;AAAA,QAClB,SAAS;AAAC,OACZ;AAAA,IACF;AAGA,IAAA,SAAS,cAAA,CAAkB,MAA+B,EAAA,EAA4B;AACpF,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,CAAC,EAAE,EAAA,EAAI,MAAiB,CAAA;AAAA,QAC9B,SAAA,EAAW,KAAA;AAAA,QACX,KAAA,EAAO,KAAA;AAAA,QACP,gBAAA,EAAkB,KAAA;AAAA,QAClB,SAAS;AAAC,OACZ;AAAA,IACF;AAEA,IAAA,MAAM,GAAA,GAA0B;AAAA,MAC9B,MAAM,KAAK,CAAA,EAAuC;AAChD,QAAA,IAAI,KAAA,GAAQ,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA;AACpC,QAAA,IAAI,CAAA,EAAG,KAAA,IAAS,CAAA,CAAE,KAAA,CAAM,SAAS,CAAA,EAAG;AAClC,UAAA,KAAA,GAAQ,KAAA,CAAM,MAAA;AAAA,YAAO,CAAC,GAAA,KACnB,CAAA,CAAE,KAAA,CAA0B,KAAA,CAAM,CAAC,CAAA,KAAM,aAAA,CAAc,GAAA,EAAK,CAAC,CAAC;AAAA,WACjE;AAAA,QACF;AACA,QAAA,IAAI,GAAG,OAAA,EAAS;AACd,UAAA,MAAM,EAAE,KAAA,EAAO,SAAA,EAAU,GAAI,CAAA,CAAE,OAAA;AAC/B,UAAA,KAAA,GAAQ,MAAM,KAAA,EAAM,CAAE,IAAA,CAAK,CAAC,GAAG,CAAA,KAAM;AACnC,YAAA,MAAM,EAAA,GAAK,EAAE,KAAK,CAAA;AAClB,YAAA,MAAM,EAAA,GAAK,EAAE,KAAK,CAAA;AAClB,YAAA,MAAM,MAAM,EAAA,IAAM,EAAA;AAClB,YAAA,MAAM,MAAM,EAAA,IAAM,EAAA;AAClB,YAAA,MAAM,MAAO,GAAA,GAAkB,GAAA,GAAiB,EAAA,GAAM,GAAA,GAAkB,MAAiB,CAAA,GAAI,CAAA;AAC7F,YAAA,OAAO,SAAA,KAAc,MAAA,GAAS,CAAC,GAAA,GAAM,GAAA;AAAA,UACvC,CAAC,CAAA;AAAA,QACH;AACA,QAAA,MAAM,KAAA,GAAQ,GAAG,KAAA,IAAS,EAAA;AAC1B,QAAA,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA;AAC5B,QAAA,OAAO,gBAAmB,KAAK,CAAA;AAAA,MACjC,CAAA;AAAA,MACA,MAAM,IAAI,EAAA,EAA4C;AACpD,QAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA;AACxB,QAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,QAAA,OAAO,cAAA,CAAkB,MAAM,EAAE,CAAA;AAAA,MACnC,CAAA;AAAA,MACA,MAAM,IAAI,IAAA,EAAwD;AAChE,QAAA,MAAM,EAAA,GAAK,CAAA,KAAA,EAAQ,EAAE,OAAO,IAAI,IAAA,CAAK,MAAA,EAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA;AACtE,QAAA,IAAA,CAAK,IAAI,EAAA,EAAI,EAAE,GAAI,IAAA,EAAkC,IAAI,CAAA;AACzD,QAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,EAAA,EAAG;AAAA,MACxB,CAAA;AAAA,MACA,MAAM,GAAA,CAAI,EAAA,EAAY,IAAA,EAA4C;AAChE,QAAA,IAAA,CAAK,IAAI,EAAA,EAAI,EAAE,GAAI,IAAA,EAAkC,IAAI,CAAA;AACzD,QAAA,OAAO,EAAE,IAAI,IAAA,EAAK;AAAA,MACpB,CAAA;AAAA,MACA,MAAM,MAAA,CAAO,EAAA,EAAY,IAAA,EAAqD;AAC5E,QAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA;AACvB,QAAA,IAAI,CAAC,GAAA,EAAK;AACR,UAAA,IAAA,CAAK,IAAI,EAAA,EAAI,EAAE,GAAI,IAAA,EAAkC,IAAI,CAAA;AAAA,QAC3D,CAAA,MAAO;AACL,UAAA,IAAA,CAAK,IAAI,EAAA,EAAI,EAAE,GAAG,GAAA,EAAK,GAAI,MAAkC,CAAA;AAAA,QAC/D;AACA,QAAA,OAAO,EAAE,IAAI,IAAA,EAAK;AAAA,MACpB,CAAA;AAAA,MACA,MAAM,OAAO,EAAA,EAAmC;AAC9C,QAAA,IAAA,CAAK,OAAO,EAAE,CAAA;AACd,QAAA,OAAO,EAAE,IAAI,IAAA,EAAK;AAAA,MACpB,CAAA;AAAA,MACA,MAAM,MAAM,GAAA,EAAyC;AACnD,QAAA,KAAA,MAAW,MAAM,GAAA,EAAK;AAGpB,UAAA,MAAM,OAAA,GAAU,IAAA;AAChB,UAAA,IAAI,EAAA,CAAG,SAAS,KAAA,EAAO;AACrB,YAAA,MAAM,EAAA,GAAK,CAAA,WAAA,EAAc,EAAE,OAAO,CAAA,CAAA;AAClC,YAAA,OAAA,CAAQ,IAAI,EAAA,EAAI,EAAE,GAAI,EAAA,CAAG,IAAA,EAAkC,IAAI,CAAA;AAAA,UACjE,CAAA,MAAA,IAAW,EAAA,CAAG,IAAA,KAAS,KAAA,EAAO;AAC5B,YAAA,OAAA,CAAQ,GAAA,CAAI,EAAA,CAAG,EAAA,EAAI,EAAE,GAAI,GAAG,IAAA,EAAkC,EAAA,EAAI,EAAA,CAAG,EAAA,EAAI,CAAA;AAAA,UAC3E,CAAA,MAAA,IAAW,EAAA,CAAG,IAAA,KAAS,QAAA,EAAU;AAC/B,YAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,GAAA,CAAI,EAAA,CAAG,EAAE,CAAA;AAC7B,YAAA,OAAA,CAAQ,GAAA,CAAI,EAAA,CAAG,EAAA,EAAI,EAAE,GAAI,GAAA,IAAO,EAAC,EAAI,GAAI,EAAA,CAAG,IAAA,EAAkC,EAAA,EAAI,EAAA,CAAG,IAAI,CAAA;AAAA,UAC3F,CAAA,MAAA,IAAW,EAAA,CAAG,IAAA,KAAS,QAAA,EAAU;AAC/B,YAAA,OAAA,CAAQ,MAAA,CAAO,GAAG,EAAE,CAAA;AAAA,UACtB;AAAA,QACF;AACA,QAAA,OAAO,EAAE,IAAI,IAAA,EAAK;AAAA,MACpB,CAAA;AAAA,MACA,KAAA,CAAM,IAAY,EAAA,EAA0C;AAE1D,QAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA;AACxB,QAAA,OAAA,CAAQ,OAAA,GAAU,IAAA,CAAK,MAAM,GAAG,IAAA,GAAQ,IAAA,GAAa,IAAI,CAAC,CAAA;AAE1D,QAAA,OAAO,MAAM;AAAA,QAAC,CAAA;AAAA,MAChB,CAAA;AAAA,MACA,UAAA,CAAW,GAAwB,EAAA,EAAkD;AAEnF,QAAA,OAAA,CAAQ,OAAA,EAAQ,CAAE,IAAA,CAAK,YAAY;AACjC,UAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,CAAK,CAAC,CAAA;AAC7B,UAAA,EAAA,CAAG,IAAI,CAAA;AAAA,QACT,CAAC,CAAA;AACD,QAAA,OAAO,MAAM;AAAA,QAAC,CAAA;AAAA,MAChB,CAAA;AAAA,MACA,IAAI,EAAA,EAAyB;AAC3B,QAAA,OAAO;AAAA,UACL,IAAI,EAAA,GAAa;AAAE,YAAA,OAAO,EAAA;AAAA,UAAI,CAAA;AAAA,UAC9B,IAAI,IAAA,GAAe;AAAE,YAAA,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,EAAE,CAAA,CAAA;AAAA,UAAI,CAAA;AAAA,UAC7C,IAAI,UAAA,GAAqB;AAAE,YAAA,OAAO,IAAA;AAAA,UAAM,CAAA;AAAA,UACxC,MAAM,GAAA,GAAM;AACV,YAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA;AACxB,YAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,YAAA,OAAO,cAAA,CAAkB,MAAM,EAAE,CAAA;AAAA,UACnC,CAAA;AAAA,UACA,MAAM,IAAI,IAAA,EAAqB;AAC7B,YAAA,IAAA,CAAK,IAAI,EAAA,EAAI,EAAE,GAAI,IAAA,EAAkC,IAAI,CAAA;AACzD,YAAA,OAAO,EAAE,IAAI,IAAA,EAAK;AAAA,UACpB,CAAA;AAAA,UACA,MAAM,OAAO,IAAA,EAA8B;AACzC,YAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA;AACvB,YAAA,IAAI,CAAC,GAAA,EAAK;AACR,cAAA,IAAA,CAAK,IAAI,EAAA,EAAI,EAAE,GAAI,IAAA,EAAkC,IAAI,CAAA;AAAA,YAC3D,CAAA,MAAO;AACL,cAAA,IAAA,CAAK,IAAI,EAAA,EAAI,EAAE,GAAG,GAAA,EAAK,GAAI,MAAkC,CAAA;AAAA,YAC/D;AACA,YAAA,OAAO,EAAE,IAAI,IAAA,EAAK;AAAA,UACpB,CAAA;AAAA,UACA,MAAM,MAAA,GAAS;AACb,YAAA,IAAA,CAAK,OAAO,EAAE,CAAA;AACd,YAAA,OAAO,EAAE,IAAI,IAAA,EAAK;AAAA,UACpB,CAAA;AAAA,UACA,WAAW,EAAA,EAAwD;AACjE,YAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA;AACxB,YAAA,OAAA,CAAQ,SAAQ,CAAE,IAAA;AAAA,cAAK,MACrB,EAAA,CAAG,IAAA,GAAO,eAAkB,IAAA,EAAM,EAAE,IAAI,IAAI;AAAA,aAC9C;AACA,YAAA,OAAO,MAAM;AAAA,YAAC,CAAA;AAAA,UAChB;AAAA,SACF;AAAA,MACF;AAAA,KACF;AAEA,IAAA,OAAO,GAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAM,GAAA,CACJ,MAAA,EACA,OAAA,EACmC;AACnC,IAAA,MAAM,IAAA,GAAO,OAAA,EAAS,OAAA,GAClB,KAAA,CAAM,QAAQ,OAAA,CAAQ,OAAO,CAAA,GAAI,OAAA,CAAQ,OAAA,GAAU,CAAC,OAAA,CAAQ,OAAO,IACnE,EAAC;AAML,IAAA,IAAI;AAEF,MAAA,MAAM,YAAY,MAAM;AAAA;AAAA,QAAiC;AAAA,OAAsB;AAC/E,MAAA,MAAM,mBAAmB,MAAM;AAAA;AAAA,QAAiC;AAAA,OAAoB;AAGpF,MAAA,MAAM,MAAA,GAAS,MAAM,SAAA,CAAU,MAAA,CAAO,MAAA,EAAO;AAE7C,MAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,QAAA,MAAM,MAAA,CAAO,MAAM,GAAG,CAAA;AAAA,MACxB;AAEA,MAAA,MAAM,YAAY,gBAAA,CAAiB,OAAA,CAAQ,MAAA,EAAQ,EAAE,QAAQ,CAAA;AAK7D,MAAA,MAAM,SAAA,GAAY,SAAA;AAElB,MAAA,OAAO;AAAA,QACL,GAAA,EAAK,SAAA;AAAA,QACL,MAAM,WAAA,CAAY,EAAA,EAAI,KAAA,EAAO;AAC3B,UAAA,OAAO,MAAM,SAAA,CAAU,WAAA,CAAY,EAAW,CAAA;AAAA,QAChD,CAAA;AAAA,QACA,MAAM,KAAA,GAAQ;AACZ,UAAA,IAAI,CAAC,MAAA,CAAO,MAAA,EAAQ,MAAM,OAAO,KAAA,EAAM;AAAA,QACzC;AAAA,OACF;AAAA,IACF,SAAS,UAAA,EAAY;AAAA,IAErB;AAGA,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI,SAAA;AACJ,IAAA,IAAI;AAEF,MAAA,QAAA,GAAW,MAAM;AAAA;AAAA,QAAiC;AAAA,OAAQ;AAC1D,MAAA,SAAA,GAAY,MAAM;AAAA;AAAA,QAAiC;AAAA,OAA2B;AAAA,IAChF,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,aAAA;AAAA,QACR,gBAAA;AAAA,QACA;AAAA,OAGF;AAAA,IACF;AAEA,IAAA,MAAM,QAAQ,QAAA,CAAS,KAAA,CAAM,EAAE,kBAAA,EAAoB,MAAM,CAAA;AAEzD,IAAA,IAAI,IAAA,CAAK,SAAS,CAAA,EAAG;AACnB,MAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,QAAA,KAAA,CAAM,MAAA,CAAO,KAAK,GAAG,CAAA;AAAA,MACvB;AAAA,IACF;AAEA,IAAA,MAAM,QAAA,GAAW,KAAA,CAAM,QAAA,CAAS,QAAA,EAAS;AACzC,IAAA,MAAM,WAAY,QAAA,CAAyC,IAAA;AAC3D,IAAA,MAAM,IAAA,GAAO,IAAI,QAAA,EAAS;AAQ1B,IAAA,MAAM,SAAA,GAAa,IAAA,CAAiD,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA;AACnF,IAAC,IAAA,CAAiD,KAAA,GAAQ,CAAC,CAAA,EAAA,GAAe,IAAA,KAAoB;AAC5F,MAAA,IAAI,CAAA,KAAM,IAAA,IAAQ,OAAO,CAAA,KAAM,QAAA,EAAU;AACvC,QAAA,MAAM,QAAA,GAAW,CAAA;AACjB,QAAA,MAAM,KAAA,GAAQ,SAAS,OAAO,CAAA;AAC9B,QAAA,IAAI,UAAU,IAAA,IAAQ,OAAO,KAAA,KAAU,QAAA,IAAY,mBAAoB,KAAA,EAAkB;AACvF,UAAA,OAAQ,MAAkC,eAAe,CAAA;AAAA,QAC3D;AAAA,MACF;AACA,MAAA,OAAO,SAAA,CAAU,CAAA,EAAG,GAAG,IAAI,CAAA;AAAA,IAC7B,CAAA;AAEA,IAAA,MAAM,MAAM,SAAA,CAAU,OAAA,CAAQ,IAAA,EAAe,EAAE,QAAQ,CAAA;AAGvD,IAAA,OAAO;AAAA,MACL,GAAA;AAAA,MACA,MAAM,WAAA,CAAY,EAAA,EAAI,KAAA,EAAO;AAC3B,QAAA,OAAO,MAAM,GAAA,CAAI,WAAA,CAAY,EAAW,CAAA;AAAA,MAC1C,CAAA;AAAA,MACA,MAAM,KAAA,GAAQ;AACZ,QAAA,MAAM,CAAA,GAAI,IAAA;AACV,QAAA,IAAI,CAAA,CAAE,GAAA,EAAK,MAAM,CAAA,CAAE,GAAA,EAAI;AAAA,MACzB;AAAA,KACF;AAAA,EACF;AAAA,EAEA,IAAI,SAAA,GAAuB;AACzB,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,MAAA;AAAA,MACR,aAAA,EAAe,CAAA;AAAA,MACf,YAAA,EAAc,IAAA;AAAA,MACd,WAAA,EAAa;AAAA,KACf;AAAA,EACF;AAAA,EAEA,mBAAmB,GAAA,EAA0C;AAC3D,IAAA,OAAO,MAAM;AAAA,IAAC,CAAA;AAAA,EAChB;AAAA,EAEA,MAAM,KAAA,GAAuB;AAAA,EAE7B;AAAA,EAEA,MAAM,UAAA,GAA4B;AAChC,IAAA,IAAA,CAAK,OAAO,KAAA,EAAM;AAAA,EACpB;AAAA,EAEA,MAAM,YAAA,GAA0C;AAC9C,IAAA,OAAO,EAAC;AAAA,EACV;AAAA;AAAA,EAGA,YAAA,CAAa,MAAc,KAAA,EAAsD;AAC/E,IAAA,IAAA,CAAK,MAAA,CAAO,IAAI,IAAA,EAAM,IAAI,IAAI,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAC,CAAC,CAAA;AAAA,EACtD;AAAA;AAAA,EAGA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,OAAO,KAAA,EAAM;AAAA,EACpB;AACF","file":"mocks.cjs","sourcesContent":["/**\n * Erros tipados do SDK.\n *\n * Todo erro lançado pelo SDK estende `NeetruError` — caller pode discriminar\n * por `.code` (string estável) sem parsing de message.\n */\n\n/** Códigos de erro estáveis do SDK. Adicionar aqui requer minor bump. */\nexport type NeetruErrorCode =\n | 'invalid_config'\n | 'missing_api_key'\n | 'unauthorized'\n | 'forbidden'\n | 'not_found'\n | 'rate_limited'\n | 'validation_failed'\n | 'network_error'\n | 'invalid_response'\n | 'server_error'\n | 'token_expired'\n | 'token_invalid_signature'\n | 'token_invalid_audience'\n | 'token_invalid_issuer'\n /** 3.0: runtime não expõe API necessária (ex: WebCrypto ausente). */\n | 'runtime_unsupported'\n /**\n * 3.1.3 (bug_c1c96a00): o `state` retornado pelo IdP no callback OIDC não bate com o gerado em\n * `signIn` (CSRF). Também usado quando não há transação OIDC pendente.\n */\n | 'oidc_state_mismatch'\n /** HTTP 409 — colisão de idempotência ou conflito de recurso. */\n | 'conflict'\n | 'unknown';\n\n/**\n * Erro tipado padrão do SDK. Sempre lançado em vez de Error genérico.\n *\n * @example\n * ```ts\n * try { await client.catalog.list(); }\n * catch (e) {\n * if (e instanceof NeetruError && e.code === 'rate_limited') retry();\n * }\n * ```\n */\nexport class NeetruError extends Error {\n public readonly code: NeetruErrorCode | string;\n public readonly status?: number;\n public readonly requestId?: string;\n\n constructor(\n code: NeetruErrorCode | string,\n message: string,\n status?: number,\n requestId?: string,\n ) {\n super(message);\n this.name = 'NeetruError';\n this.code = code;\n this.status = status;\n this.requestId = requestId;\n // Preserva o prototype chain ao herdar de Error (downlevel quirk de TS).\n Object.setPrototypeOf(this, NeetruError.prototype);\n }\n}\n","/**\r\n * NeetruDbError — classe de erro especializada para o módulo `db`.\r\n *\r\n * Conforma com 02-sdk.md §3.5: `NeetruDbError extends NeetruError`,\r\n * campo `code` fechado em `NeetruDbErrorCode`, campo `retryable` booleano,\r\n * campo `dbId` opaco para correlação.\r\n *\r\n * Herda de `NeetruError` para que um `catch (e) { if (e instanceof NeetruError) }`\r\n * genérico continue pegando erros de DB. Quem quer granularidade usa\r\n * `instanceof NeetruDbError` e o `code` fechado.\r\n */\r\n\r\nimport { NeetruError } from './errors';\r\n\r\n/**\r\n * Códigos de erro específicos do módulo `db`.\r\n *\r\n * - `db_unavailable` — lifecycle: provisionando / falhou / arquivado.\r\n * NÃO significa \"sem rede\" — offline é transparente.\r\n * - `db_not_found` — documento/coleção não encontrado no servidor.\r\n * - `db_conflict` — conflito de escrita detectado.\r\n * - `db_quota_exceeded` — quota de escrita/leitura excedida no banco.\r\n * - `db_permission_denied` — sem permissão para a operação.\r\n * - `db_invalid_query` — query inválida (campo, operador, tipo).\r\n * - `db_timeout` — operação excedeu o timeout.\r\n * - `offline_quota_exceeded`— IndexedDB cheio; a escrita não pode ser enfileirada.\r\n * - `offline_unavailable` — IndexedDB indisponível; SDK degrado para cache RAM.\r\n */\r\nexport type NeetruDbErrorCode =\r\n | 'db_unavailable'\r\n | 'db_not_found'\r\n | 'db_conflict'\r\n | 'db_quota_exceeded'\r\n | 'db_permission_denied'\r\n | 'db_invalid_query'\r\n | 'db_timeout'\r\n | 'offline_quota_exceeded'\r\n | 'offline_unavailable';\r\n\r\n/**\r\n * Códigos que são retryable por natureza.\r\n */\r\nconst RETRYABLE_CODES = new Set<NeetruDbErrorCode>([\r\n 'db_unavailable',\r\n 'db_conflict',\r\n 'db_timeout',\r\n]);\r\n\r\n/**\r\n * Erro tipado do módulo `db` — estende `NeetruError` para compatibilidade.\r\n *\r\n * @example\r\n * ```ts\r\n * try {\r\n * await client.db.collection('orders').add({ ... });\r\n * } catch (e) {\r\n * if (e instanceof NeetruDbError && e.code === 'offline_quota_exceeded') {\r\n * // IndexedDB cheio — notificar usuário\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport class NeetruDbError extends NeetruError {\r\n /** Código de erro fechado — específico de DB. */\r\n public override readonly code: NeetruDbErrorCode;\r\n\r\n /**\r\n * `true` para erros transientes que o produto pode tentar novamente.\r\n * São retryable: `db_unavailable`, `db_conflict`, `db_timeout`.\r\n */\r\n public readonly retryable: boolean;\r\n\r\n /**\r\n * ID opaco do banco lógico — só para correlação com logs do Core.\r\n * Nunca deve ser exibido ao usuário final.\r\n */\r\n public readonly dbId?: string;\r\n\r\n constructor(code: NeetruDbErrorCode, message: string, dbId?: string) {\r\n super(code, message);\r\n this.name = 'NeetruDbError';\r\n this.code = code;\r\n this.retryable = RETRYABLE_CODES.has(code);\r\n this.dbId = dbId;\r\n // Preserva o prototype chain (TypeScript + downlevel).\r\n Object.setPrototypeOf(this, NeetruDbError.prototype);\r\n }\r\n}\r\n","/**\r\n * Mocks determinísticos do SDK — overridáveis em tests do consumer ou\r\n * ativados automaticamente quando `NEETRU_ENV=dev`.\r\n *\r\n * Nada aqui faz I/O. Tudo é puro/sincrono/in-memory. Compat total com\r\n * runtimes browser/Node/Edge — sem `node:` builtins.\r\n *\r\n * Cada mock implementa o mesmo namespace interface das implementações reais\r\n * (`AuthNamespace`, `UsageNamespace`, `SupportNamespace`) — caller pode\r\n * substituir 1:1 sem branching.\r\n *\r\n * @example\r\n * ```ts\r\n * import { createNeetruClient, MockAuth } from '@neetru/sdk';\r\n *\r\n * const client = createNeetruClient({\r\n * mocks: { auth: new MockAuth({ uid: 'fake-user', email: 'x@x.com' }) },\r\n * });\r\n * ```\r\n */\r\n\r\nimport type {\r\n AuthNamespace,\r\n AuthStateListener,\r\n CreateTicketInput,\r\n EntitlementCheck,\r\n NeetruUser,\r\n RedirectCallbackResult,\r\n SignInOptions,\r\n SupportNamespace,\r\n SupportTicket,\r\n UsageNamespace,\r\n UsageQuota,\r\n} from './types';\r\nimport type {\r\n NeetruDb,\r\n NeetruSqlClient,\r\n} from './db/client-db';\r\nimport type { DbCollectionRef, DbWhereFilter, DbListResult, DbGetResult, DbBatchOp, DbDocRef, DbQuery } from './db/collection-ref';\r\nimport type { SyncState, ConflictRecord, Unsubscribe } from './db/offline/types';\r\nimport { NeetruDbError } from './db-errors';\r\nimport { NeetruError } from './errors';\r\n\r\n// ─── User fixture default ──────────────────────────────────────────────────\r\n\r\n/**\r\n * User fixture determinístico — usado quando `NEETRU_ENV=dev` e nenhum mock\r\n * custom é injetado. Email/uid estáveis pra snapshot tests.\r\n */\r\nexport const DEV_FIXTURE_USER: NeetruUser = Object.freeze({\r\n uid: 'dev-fixture-uid-0001',\r\n email: 'dev@neetru.local',\r\n emailVerified: true,\r\n displayName: 'Dev Fixture',\r\n isCustomer: true,\r\n isStaff: false,\r\n}) as NeetruUser;\r\n\r\n// ─── MockAuth ──────────────────────────────────────────────────────────────\r\n\r\n/** Opções do construtor de `MockAuth`. */\r\nexport interface MockAuthOptions {\r\n /**\r\n * Permite que `verifyToken` decodifique tokens JWT sem verificar assinatura.\r\n *\r\n * **SOMENTE para uso em testes.** Com `allowUnsignedDecode: false` (default),\r\n * `verifyToken` lança `unauthorized` em vez de aceitar qualquer JWT não-assinado —\r\n * isso previne que misconfiguração de env (`NEETRU_ENV=dev` em prod) vire bypass\r\n * de autenticação. Testes que precisam do comportamento de decode devem passar\r\n * `{ allowUnsignedDecode: true }` explicitamente.\r\n */\r\n allowUnsignedDecode?: boolean;\r\n}\r\n\r\n/**\r\n * Implementação in-memory do `AuthNamespace`. signIn marca o user como\r\n * logado; signOut limpa. onAuthStateChanged dispara callback síncrono no\r\n * subscribe + a cada mudança.\r\n */\r\nexport class MockAuth implements AuthNamespace {\r\n private _user: NeetruUser | null;\r\n private _listeners: Set<AuthStateListener>;\r\n private _allowUnsignedDecode: boolean;\r\n\r\n constructor(initialUser: NeetruUser | null = null, options?: MockAuthOptions) {\r\n this._user = initialUser;\r\n this._listeners = new Set();\r\n this._allowUnsignedDecode = options?.allowUnsignedDecode ?? false;\r\n\r\n // Emite aviso proeminente em dev quando fora de testes, pra deixar claro\r\n // que verifyToken no mock NÃO valida assinaturas.\r\n // Guard: não spamma em ambientes de teste (process.env.NODE_ENV=test ou\r\n // VITEST=true). Emite só uma vez por instância (basta pra chamar atenção).\r\n if (this._allowUnsignedDecode) {\r\n const isTestEnv =\r\n (typeof process !== 'undefined' && (\r\n process.env?.NODE_ENV === 'test' ||\r\n process.env?.VITEST === 'true' ||\r\n process.env?.VITEST != null\r\n ));\r\n if (!isTestEnv && typeof console !== 'undefined') {\r\n console.warn(\r\n '[neetru-sdk] MockAuth.verifyToken está em modo allowUnsignedDecode=true: ' +\r\n 'tokens NÃO têm assinatura verificada. ' +\r\n 'Este modo é exclusivo para testes — NUNCA use como security boundary em código deployado.',\r\n );\r\n }\r\n }\r\n }\r\n\r\n async signIn(_options?: SignInOptions): Promise<NeetruUser> {\r\n // Mock: apenas marca user como logado (usa fixture se não havia).\r\n if (!this._user) this._user = { ...DEV_FIXTURE_USER };\r\n this._notify();\r\n return this._user;\r\n }\r\n\r\n async signOut(): Promise<void> {\r\n this._user = null;\r\n this._notify();\r\n }\r\n\r\n getUser(): NeetruUser | null {\r\n return this._user;\r\n }\r\n\r\n onAuthStateChanged(listener: AuthStateListener): () => void {\r\n this._listeners.add(listener);\r\n // Dispara imediatamente com estado atual (espelha API Firebase Auth).\r\n try {\r\n listener(this._user);\r\n } catch {\r\n // Callback do consumer não pode quebrar o subscribe.\r\n }\r\n return () => {\r\n this._listeners.delete(listener);\r\n };\r\n }\r\n\r\n /**\r\n * Mock de `verifyToken` — por default lança `unauthorized` pra prevenir uso\r\n * acidental como security boundary em código deployado.\r\n *\r\n * Para decodificar JWTs sem verificar assinatura em testes, crie a instância\r\n * com `new MockAuth(user, { allowUnsignedDecode: true })`. Isso é um opt-in\r\n * explícito — nunca acontece silenciosamente.\r\n *\r\n * Para simular falhas ou resultados customizados, use `__mockVerifyToken(fn)`.\r\n */\r\n async verifyToken(token: string): Promise<NeetruUser> {\r\n if (this._verifyTokenOverride) {\r\n return this._verifyTokenOverride(token);\r\n }\r\n if (!token) {\r\n throw new NeetruError('token_invalid_signature', 'Token inválido: string vazia');\r\n }\r\n // Sem opt-in explícito, recusa-se a decodificar — decodificar JWTs sem\r\n // verificar assinatura é uma vulnerabilidade se este mock vazar pra produção\r\n // (ex: NEETRU_ENV=dev configurado erroneamente, ou globalThis.NEETRU_ENV\r\n // injetado por bundle). O caller deve usar __mockVerifyToken() ou passar\r\n // allowUnsignedDecode: true no construtor.\r\n if (!this._allowUnsignedDecode) {\r\n throw new NeetruError(\r\n 'unauthorized',\r\n 'MockAuth.verifyToken não verifica assinaturas JWT e NÃO deve ser usado como ' +\r\n 'security boundary em código deployado. ' +\r\n 'Em testes, use new MockAuth(user, { allowUnsignedDecode: true }) para habilitar ' +\r\n 'decodificação sem assinatura, ou __mockVerifyToken(fn) para injetar resultado customizado.',\r\n );\r\n }\r\n // allowUnsignedDecode=true: decodifica claims base64 sem verificar assinatura (testes).\r\n try {\r\n const parts = token.split('.');\r\n if (parts.length === 3) {\r\n const b64 = parts[1].replace(/-/g, '+').replace(/_/g, '/');\r\n const pad = '='.repeat((4 - (b64.length % 4)) % 4);\r\n const decoded = JSON.parse(\r\n typeof atob === 'function'\r\n ? atob(b64 + pad)\r\n : Buffer.from(b64 + pad, 'base64').toString('utf-8'),\r\n ) as Record<string, unknown>;\r\n if (typeof decoded.sub === 'string') {\r\n return {\r\n uid: decoded.sub,\r\n email: typeof decoded.email === 'string' ? decoded.email : '',\r\n emailVerified: typeof decoded.email_verified === 'boolean' ? decoded.email_verified : undefined,\r\n displayName: typeof decoded.name === 'string' ? decoded.name : undefined,\r\n photoURL: typeof decoded.picture === 'string' ? decoded.picture : undefined,\r\n isStaff: decoded.is_staff === true,\r\n isCustomer: decoded.is_customer === true,\r\n tenantId: typeof decoded.tenant_id === 'string' ? decoded.tenant_id : undefined,\r\n ...decoded,\r\n };\r\n }\r\n }\r\n } catch {\r\n /* fall through to return current user */\r\n }\r\n // Fallback: retorna o user atual do mock.\r\n if (this._user) return this._user;\r\n throw new NeetruError('token_invalid_signature', 'Nenhum user mock disponível e JWT sem sub válido');\r\n }\r\n\r\n /**\r\n * Mock de `handleRedirectCallback` (Bug 2 / 3.1.3) — não há redirect real no\r\n * mock, então retorna `null` por default. Use `__setPendingCallback(result)`\r\n * em testes pra simular um retorno do IdP.\r\n */\r\n async handleRedirectCallback(_currentUrl?: string): Promise<RedirectCallbackResult | null> {\r\n return this._pendingCallback;\r\n }\r\n\r\n /**\r\n * Mock de `getIdToken` (Bug 2 / 3.1.3). Retorna `null` por default; use\r\n * `__setIdToken(token)` pra injetar um token cru em testes.\r\n */\r\n getIdToken(): string | null {\r\n return this._idToken;\r\n }\r\n\r\n private _pendingCallback: RedirectCallbackResult | null = null;\r\n private _idToken: string | null = null;\r\n\r\n /** Test helper — simula o material devolvido por um callback OIDC. */\r\n __setPendingCallback(result: RedirectCallbackResult | null): void {\r\n this._pendingCallback = result;\r\n }\r\n\r\n /** Test helper — injeta o id_token cru retornado por `getIdToken`. */\r\n __setIdToken(token: string | null): void {\r\n this._idToken = token;\r\n }\r\n\r\n private _verifyTokenOverride: ((token: string) => Promise<NeetruUser>) | null = null;\r\n\r\n /**\r\n * Injeta override pra `verifyToken` em testes — permite simular expiração,\r\n * assinatura inválida etc sem precisar de JWT real.\r\n *\r\n * @example\r\n * ```ts\r\n * const mock = new MockAuth(null);\r\n * mock.__mockVerifyToken(async () => { throw new NeetruError('token_expired', '...'); });\r\n * ```\r\n */\r\n __mockVerifyToken(fn: ((token: string) => Promise<NeetruUser>) | null): void {\r\n this._verifyTokenOverride = fn;\r\n }\r\n\r\n /** Helper de tests — força um user state arbitrário. */\r\n __setUser(user: NeetruUser | null): void {\r\n this._user = user;\r\n this._notify();\r\n }\r\n\r\n private _notify(): void {\r\n for (const l of this._listeners) {\r\n try {\r\n l(this._user);\r\n } catch {\r\n // ignore consumer errors\r\n }\r\n }\r\n }\r\n}\r\n\r\n// ─── MockUsage (3.0 — track/getQuota removidos) ────────────────────────────\r\n\r\ninterface UsageReportRecord {\r\n resource: string;\r\n qty: number;\r\n productId?: string;\r\n tenantId?: string;\r\n timestamp: string;\r\n}\r\n\r\n/**\r\n * In-memory `UsageNamespace` 3.0. `report()` acumula counter local; `check()`\r\n * compara com `__setQuota(resource, {used, limit})` fixture.\r\n *\r\n * Breaking 3.0:\r\n * - `track(event, props)` REMOVIDO.\r\n * - `getQuota(metric)` REMOVIDO.\r\n * - `__getRecords()` agora retorna `UsageReportRecord[]` (resource/qty).\r\n */\r\nexport class MockUsage implements UsageNamespace {\r\n private _reports: UsageReportRecord[] = [];\r\n private _quotas: Map<string, UsageQuota>;\r\n private _counters: Map<string, number> = new Map();\r\n\r\n constructor(initialQuotas: Record<string, UsageQuota> = {}) {\r\n this._quotas = new Map(Object.entries(initialQuotas));\r\n }\r\n\r\n async report(\r\n resource: string,\r\n qty: number = 1,\r\n options?: { productId?: string; tenantId?: string },\r\n ): Promise<{\r\n ok: true;\r\n counterId?: string;\r\n value?: number;\r\n limit?: number;\r\n remaining?: number;\r\n status?: string;\r\n }> {\r\n if (!resource) throw new Error('resource required');\r\n const safeQty = Number.isFinite(qty) && qty > 0 ? Math.floor(qty) : 1;\r\n const existing = this._counters.get(resource) ?? 0;\r\n const next = existing + safeQty;\r\n this._counters.set(resource, next);\r\n this._reports.push({\r\n resource,\r\n qty: safeQty,\r\n productId: options?.productId,\r\n tenantId: options?.tenantId,\r\n timestamp: new Date().toISOString(),\r\n });\r\n const limitFixture = this._quotas.get(resource);\r\n const limit = limitFixture?.limit ?? -1;\r\n return {\r\n ok: true,\r\n counterId: `mock_${resource}`,\r\n value: next,\r\n limit,\r\n remaining: limit < 0 ? -1 : Math.max(0, limit - next),\r\n status: limit > 0 && next >= limit ? 'read_only_overlimit' : 'ok',\r\n };\r\n }\r\n\r\n async check(\r\n resource: string,\r\n _options?: { productId?: string; tenantId?: string },\r\n ): Promise<{\r\n allowed: boolean;\r\n reason?: string;\r\n remaining?: number;\r\n limit?: number;\r\n planId?: string | null;\r\n planFeatures?: string[];\r\n behavior?: 'readonly' | null;\r\n }> {\r\n const quota = this._quotas.get(resource);\r\n const used = this._counters.get(resource) ?? 0;\r\n if (!quota) {\r\n return { allowed: true, reason: 'granted', limit: -1, remaining: -1, behavior: null };\r\n }\r\n const remaining = quota.limit < 0 ? -1 : Math.max(0, quota.limit - used);\r\n if (remaining === 0) {\r\n return {\r\n allowed: false,\r\n reason: 'limit_exceeded',\r\n limit: quota.limit,\r\n remaining: 0,\r\n behavior: 'readonly',\r\n };\r\n }\r\n return {\r\n allowed: true,\r\n reason: 'granted',\r\n limit: quota.limit,\r\n remaining,\r\n behavior: null,\r\n };\r\n }\r\n\r\n /** Test helper — retorna histórico de `report()` calls. */\r\n __getReports(): readonly UsageReportRecord[] {\r\n return [...this._reports];\r\n }\r\n /** @deprecated Removido em 3.0 (usage.track foi removido). Use `__getReports`. */\r\n __getRecords(): readonly UsageReportRecord[] {\r\n return this.__getReports();\r\n }\r\n /** Test helper — substitui quota fixture. */\r\n __setQuota(metric: string, quota: UsageQuota): void {\r\n this._quotas.set(metric, quota);\r\n }\r\n /** Test helper — limpa estado. */\r\n __reset(): void {\r\n this._reports = [];\r\n this._quotas.clear();\r\n this._counters.clear();\r\n }\r\n}\r\n\r\n// ─── MockSupport ───────────────────────────────────────────────────────────\r\n\r\n/**\r\n * In-memory `SupportNamespace`. createTicket gera ID `mock-ticket-{n}`;\r\n * listMyTickets retorna todos criados (FIFO). Sequência por instância\r\n * (evita poluição cross-test do estado de módulo).\r\n */\r\nexport class MockSupport implements SupportNamespace {\r\n private _tickets: SupportTicket[] = [];\r\n private _ticketSeq = 0;\r\n\r\n async createTicket(input: CreateTicketInput): Promise<SupportTicket> {\r\n // L-03 fix (Opus review): MockSupport agora espelha contrato 3.0 do Core.\r\n // Antes aceitava input sem productSlug, mascarando bugs em tests que\r\n // passariam em prod com 400 validation_failed.\r\n if (!input?.subject) throw new NeetruError('validation_failed', 'subject required');\r\n if (!input?.message) throw new NeetruError('validation_failed', 'message required');\r\n if (!input?.productSlug) {\r\n throw new NeetruError(\r\n 'validation_failed',\r\n 'productSlug required (3.0 breaking — pass to input or set on createNeetruClient)',\r\n );\r\n }\r\n const ticket: SupportTicket = {\r\n id: `mock-ticket-${++this._ticketSeq}`,\r\n subject: input.subject,\r\n message: input.message,\r\n severity: input.severity ?? 'normal',\r\n status: 'open',\r\n createdAt: new Date().toISOString(),\r\n productSlug: input.productSlug,\r\n };\r\n this._tickets.push(ticket);\r\n return ticket;\r\n }\r\n\r\n async listMyTickets(options?: { productSlug?: string }): Promise<SupportTicket[]> {\r\n if (options?.productSlug) {\r\n return this._tickets.filter((t) => t.productSlug === options.productSlug);\r\n }\r\n return [...this._tickets];\r\n }\r\n\r\n /** Test helper. */\r\n __reset(): void {\r\n this._tickets = [];\r\n this._ticketSeq = 0;\r\n }\r\n}\r\n\r\n// ─── MockEntitlements ──────────────────────────────────────────────────────\r\n\r\n/**\r\n * In-memory entitlements. Por default `allowed=true` em tudo (dev convém).\r\n * Use `__deny(slug, feature)` em tests pra simular bloqueio.\r\n */\r\nexport class MockEntitlements {\r\n private _denied: Set<string> = new Set();\r\n\r\n async check(productSlug: string, feature: string): Promise<boolean> {\r\n return !this._denied.has(`${productSlug}:${feature}`);\r\n }\r\n\r\n async checkDetailed(productSlug: string, feature: string): Promise<EntitlementCheck> {\r\n const allowed = await this.check(productSlug, feature);\r\n return {\r\n allowed,\r\n productSlug,\r\n feature,\r\n reason: allowed ? 'granted' : 'mock_denied',\r\n };\r\n }\r\n\r\n /** Test helper. */\r\n __deny(productSlug: string, feature: string): void {\r\n this._denied.add(`${productSlug}:${feature}`);\r\n }\r\n /** Test helper. */\r\n __reset(): void {\r\n this._denied.clear();\r\n }\r\n}\r\n\r\n// ─── MockDb (v2.0) ─────────────────────────────────────────────────────────\r\n\r\n/**\r\n * In-memory `NeetruDb`. Cada `collection(name)` aponta para um Map; ops\r\n * são totalmente síncronas (mas API await-friendly).\r\n *\r\n * v2.0: implementa a interface `NeetruDb` completa (collection, sql, syncState,\r\n * flush, clearCache, getConflicts, onSyncStateChanged).\r\n *\r\n * Útil para testar produtos consumidores sem rodar Core REST nem IndexedDB.\r\n */\r\nexport class MockDb implements NeetruDb {\r\n private _store: Map<string, Map<string, Record<string, unknown>>> = new Map();\r\n private _fixtures: Map<string, Record<string, Record<string, unknown>>>;\r\n\r\n constructor(initialFixtures: Record<string, Record<string, Record<string, unknown>>> = {}) {\r\n this._fixtures = new Map(Object.entries(initialFixtures));\r\n }\r\n\r\n collection<T = Record<string, unknown>>(name: string): DbCollectionRef<T> {\r\n const _store = this._store;\r\n const _fixtures = this._fixtures;\r\n if (!_store.has(name)) {\r\n const init = _fixtures.get(name);\r\n _store.set(\r\n name,\r\n init ? new Map(Object.entries(init)) : new Map(),\r\n );\r\n }\r\n const coll = _store.get(name)!;\r\n\r\n const matchesFilter = (\r\n doc: Record<string, unknown>,\r\n f: DbWhereFilter,\r\n ): boolean => {\r\n const v = doc[f.field];\r\n switch (f.op) {\r\n case '==':\r\n return v === f.value;\r\n case '!=':\r\n return v !== f.value;\r\n case '<':\r\n return typeof v === 'number' && typeof f.value === 'number' && v < f.value;\r\n case '<=':\r\n return typeof v === 'number' && typeof f.value === 'number' && v <= f.value;\r\n case '>':\r\n return typeof v === 'number' && typeof f.value === 'number' && v > f.value;\r\n case '>=':\r\n return typeof v === 'number' && typeof f.value === 'number' && v >= f.value;\r\n case 'in':\r\n return Array.isArray(f.value) && (f.value as unknown[]).includes(v);\r\n case 'array-contains':\r\n return Array.isArray(v) && (v as unknown[]).includes(f.value);\r\n case 'not-in':\r\n return Array.isArray(f.value) && !(f.value as unknown[]).includes(v);\r\n default:\r\n return true;\r\n }\r\n };\r\n\r\n let autoSeq = 0;\r\n\r\n // Helper to build a minimal DbListResult from raw items\r\n function buildListResult<U>(items: Array<Record<string, unknown>>): DbListResult<U> {\r\n return {\r\n docs: items.map((d, i) => ({ id: (d.id as string) ?? String(i), data: d as U })),\r\n nextCursor: null,\r\n fromCache: false,\r\n stale: false,\r\n hasPendingWrites: false,\r\n changes: [],\r\n };\r\n }\r\n\r\n // Helper to build a DbGetResult for a single doc\r\n function buildGetResult<U>(data: Record<string, unknown>, id: string): DbGetResult<U> {\r\n return {\r\n docs: [{ id, data: data as U }],\r\n fromCache: false,\r\n stale: false,\r\n hasPendingWrites: false,\r\n changes: [],\r\n };\r\n }\r\n\r\n const ref: DbCollectionRef<T> = {\r\n async list(q?: DbQuery): Promise<DbListResult<T>> {\r\n let items = Array.from(coll.values());\r\n if (q?.where && q.where.length > 0) {\r\n items = items.filter((doc) =>\r\n (q.where as DbWhereFilter[]).every((f) => matchesFilter(doc, f)),\r\n );\r\n }\r\n if (q?.orderBy) {\r\n const { field, direction } = q.orderBy;\r\n items = items.slice().sort((a, b) => {\r\n const av = a[field];\r\n const bv = b[field];\r\n const avs = av ?? '';\r\n const bvs = bv ?? '';\r\n const cmp = (avs as string) < (bvs as string) ? -1 : (avs as string) > (bvs as string) ? 1 : 0;\r\n return direction === 'desc' ? -cmp : cmp;\r\n });\r\n }\r\n const limit = q?.limit ?? 20;\r\n items = items.slice(0, limit);\r\n return buildListResult<T>(items);\r\n },\r\n async get(id: string): Promise<DbGetResult<T> | null> {\r\n const data = coll.get(id);\r\n if (!data) return null;\r\n return buildGetResult<T>(data, id);\r\n },\r\n async add(data: Omit<T, 'id'>): Promise<{ ok: true; id: string }> {\r\n const id = `mock-${++autoSeq}-${Math.random().toString(36).slice(2, 8)}`;\r\n coll.set(id, { ...(data as Record<string, unknown>), id });\r\n return { ok: true, id };\r\n },\r\n async set(id: string, data: Omit<T, 'id'>): Promise<{ ok: true }> {\r\n coll.set(id, { ...(data as Record<string, unknown>), id });\r\n return { ok: true };\r\n },\r\n async update(id: string, data: Partial<Omit<T, 'id'>>): Promise<{ ok: true }> {\r\n const cur = coll.get(id);\r\n if (!cur) {\r\n coll.set(id, { ...(data as Record<string, unknown>), id });\r\n } else {\r\n coll.set(id, { ...cur, ...(data as Record<string, unknown>) });\r\n }\r\n return { ok: true };\r\n },\r\n async remove(id: string): Promise<{ ok: true }> {\r\n coll.delete(id);\r\n return { ok: true };\r\n },\r\n async batch(ops: DbBatchOp[]): Promise<{ ok: true }> {\r\n for (const op of ops) {\r\n // Mock usa a coleção corrente (collName) — o campo collection foi removido\r\n // do discriminated union em 2.1.1; batch opera sempre na coleção do ref.\r\n const collMap = coll;\r\n if (op.kind === 'add') {\r\n const id = `mock-batch-${++autoSeq}`;\r\n collMap.set(id, { ...(op.data as Record<string, unknown>), id });\r\n } else if (op.kind === 'set') {\r\n collMap.set(op.id, { ...(op.data as Record<string, unknown>), id: op.id });\r\n } else if (op.kind === 'update') {\r\n const cur = collMap.get(op.id);\r\n collMap.set(op.id, { ...(cur ?? {}), ...(op.data as Record<string, unknown>), id: op.id });\r\n } else if (op.kind === 'remove') {\r\n collMap.delete(op.id);\r\n }\r\n }\r\n return { ok: true };\r\n },\r\n onDoc(id: string, cb: (doc: T | null) => void): Unsubscribe {\r\n // Entrega snapshot inicial imediato (sync mock)\r\n const data = coll.get(id);\r\n Promise.resolve().then(() => cb(data ? (data as T) : null));\r\n // Mock: não há feed realtime — retorna no-op unsubscribe\r\n return () => {};\r\n },\r\n onSnapshot(q: DbQuery | undefined, cb: (snap: DbListResult<T>) => void): Unsubscribe {\r\n // Entrega snapshot inicial imediato (sync mock)\r\n Promise.resolve().then(async () => {\r\n const snap = await ref.list(q);\r\n cb(snap);\r\n });\r\n return () => {};\r\n },\r\n doc(id: string): DbDocRef<T> {\r\n return {\r\n get id(): string { return id; },\r\n get path(): string { return `${name}/${id}`; },\r\n get collection(): string { return name; },\r\n async get() {\r\n const data = coll.get(id);\r\n if (!data) return null;\r\n return buildGetResult<T>(data, id);\r\n },\r\n async set(data: Omit<T, 'id'>) {\r\n coll.set(id, { ...(data as Record<string, unknown>), id });\r\n return { ok: true };\r\n },\r\n async update(data: Partial<Omit<T, 'id'>>) {\r\n const cur = coll.get(id);\r\n if (!cur) {\r\n coll.set(id, { ...(data as Record<string, unknown>), id });\r\n } else {\r\n coll.set(id, { ...cur, ...(data as Record<string, unknown>) });\r\n }\r\n return { ok: true };\r\n },\r\n async remove() {\r\n coll.delete(id);\r\n return { ok: true };\r\n },\r\n onSnapshot(cb: (snap: DbGetResult<T> | null) => void): Unsubscribe {\r\n const data = coll.get(id);\r\n Promise.resolve().then(() =>\r\n cb(data ? buildGetResult<T>(data, id) : null),\r\n );\r\n return () => {};\r\n },\r\n };\r\n },\r\n };\r\n\r\n return ref;\r\n }\r\n\r\n /**\r\n * Implementa SQL in-memory para testes — preferência: `@electric-sql/pglite`\r\n * + `drizzle-orm/pglite`; fallback: `pg-mem` + `drizzle-orm/node-postgres`\r\n * com strip interceptor.\r\n *\r\n * bug_6bae8674461f4600809e2f9de13c6043 (HIGH 26/05): fix anterior (2.3.3)\r\n * teve efeito INVERSO. Injetar `pool.types.getTypeParser` fez drizzle-orm\r\n * passar `query.types.getTypeParser` pro pg-mem, que tem guard interno\r\n * `if (query.types?.getTypeParser) throw NotSupported`. Ou seja: presença\r\n * de getTypeParser é o gatilho do erro — não ausência.\r\n *\r\n * Solução A (pglite, preferida): `@electric-sql/pglite` é WASM-Postgres\r\n * nativo — sem adapter pg-mem, sem esse conflito de tipos.\r\n * Solução B (fallback pg-mem): strip interceptor no pool.query que deleta\r\n * `types.getTypeParser` do objeto de query ANTES do pg-mem ver. Compat com\r\n * consumers que só têm pg-mem nas devDeps.\r\n *\r\n * Use `options.initSql` pra rodar DDL no setup (CREATE TABLE etc).\r\n */\r\n async sql<TSchema extends Record<string, unknown>>(\r\n schema: TSchema,\r\n options?: { database?: string; initSql?: string | string[] },\r\n ): Promise<NeetruSqlClient<TSchema>> {\r\n const ddls = options?.initSql\r\n ? Array.isArray(options.initSql) ? options.initSql : [options.initSql]\r\n : [];\r\n\r\n // ── Solução A: pglite (preferida) ────────────────────────────────────────\r\n // PGlite é WASM-Postgres nativo — sem adapter pg-mem, sem o conflito de\r\n // tipos (pg-mem rejeita queries com getTypeParser presente; pglite não tem\r\n // esse guard).\r\n try {\r\n // bug_168368ae: webpackIgnore obrigatório — peerDeps optional server-only.\r\n const pglitePkg = await import(/* webpackIgnore: true */ '@electric-sql/pglite');\r\n const drizzlePglitePkg = await import(/* webpackIgnore: true */ 'drizzle-orm/pglite');\r\n\r\n // PGlite.create() retorna instância já pronta (waitReady resolvido).\r\n const pglite = await pglitePkg.PGlite.create();\r\n\r\n for (const ddl of ddls) {\r\n await pglite.query(ddl);\r\n }\r\n\r\n const pgliteOrm = drizzlePglitePkg.drizzle(pglite, { schema });\r\n\r\n // NeetruSqlClient.orm é tipado como NodePgDatabase — pglite e node-postgres\r\n // implementam a mesma superfície Drizzle mas com tipos de resultado internos\r\n // distintos (Results vs QueryResult). Cast via unknown necessário.\r\n const ormAsNode = pgliteOrm as unknown as import('drizzle-orm/node-postgres').NodePgDatabase<TSchema>;\r\n\r\n return {\r\n orm: ormAsNode,\r\n async transaction(fn, _opts) {\r\n return await pgliteOrm.transaction(fn as never) as never;\r\n },\r\n async close() {\r\n if (!pglite.closed) await pglite.close();\r\n },\r\n };\r\n } catch (_pgliteErr) {\r\n // Pglite indisponível (não instalado ou WASM falhou) — cai no pg-mem.\r\n }\r\n\r\n // ── Solução B: pg-mem + strip interceptor (fallback) ─────────────────────\r\n let pgMemMod: typeof import('pg-mem');\r\n let drizzlePg: typeof import('drizzle-orm/node-postgres');\r\n try {\r\n // bug_168368ae: webpackIgnore obrigatório.\r\n pgMemMod = await import(/* webpackIgnore: true */ 'pg-mem');\r\n drizzlePg = await import(/* webpackIgnore: true */ 'drizzle-orm/node-postgres');\r\n } catch {\r\n throw new NeetruDbError(\r\n 'db_unavailable',\r\n '[MockDb] sql() requer @electric-sql/pglite OU pg-mem + drizzle-orm + pg como devDependencies. ' +\r\n 'Preferido: npm install -D @electric-sql/pglite drizzle-orm. ' +\r\n 'Alternativo: npm install -D pg-mem drizzle-orm pg.',\r\n );\r\n }\r\n\r\n const memDb = pgMemMod.newDb({ noAstCoverageCheck: true });\r\n\r\n if (ddls.length > 0) {\r\n for (const ddl of ddls) {\r\n memDb.public.none(ddl);\r\n }\r\n }\r\n\r\n const adapters = memDb.adapters.createPg();\r\n const PoolCtor = (adapters as { Pool: new () => unknown }).Pool;\r\n const pool = new PoolCtor() as Record<string, unknown>;\r\n\r\n // bug_6bae8674 strip interceptor: pg-mem rejeita queries que TÊM\r\n // `query.types.getTypeParser` presente (guard interno NotSupported).\r\n // drizzle-orm/node-postgres/session.js injeta `rawQuery.types = pool.types`\r\n // em toda query. Ao interceptar pool.query e deletar getTypeParser do objeto\r\n // de query antes de passar pro pg-mem, o guard não dispara.\r\n // NÃO adicionar getTypeParser ao pool.types (fix 2.3.3 causou efeito inverso).\r\n const origQuery = (pool as { query: (...a: unknown[]) => unknown }).query.bind(pool);\r\n (pool as { query: (...a: unknown[]) => unknown }).query = (q: unknown, ...rest: unknown[]) => {\r\n if (q !== null && typeof q === 'object') {\r\n const queryObj = q as Record<string, unknown>;\r\n const types = queryObj['types'];\r\n if (types !== null && typeof types === 'object' && 'getTypeParser' in (types as object)) {\r\n delete (types as Record<string, unknown>)['getTypeParser'];\r\n }\r\n }\r\n return origQuery(q, ...rest);\r\n };\r\n\r\n const orm = drizzlePg.drizzle(pool as never, { schema }) as unknown as\r\n import('drizzle-orm/node-postgres').NodePgDatabase<TSchema>;\r\n\r\n return {\r\n orm,\r\n async transaction(fn, _opts) {\r\n return await orm.transaction(fn as never) as never;\r\n },\r\n async close() {\r\n const p = pool as { end?: () => Promise<void> };\r\n if (p.end) await p.end();\r\n },\r\n };\r\n }\r\n\r\n get syncState(): SyncState {\r\n return {\r\n status: 'idle',\r\n pendingWrites: 0,\r\n lastSyncedAt: null,\r\n isLeaderTab: true,\r\n };\r\n }\r\n\r\n onSyncStateChanged(_cb: (s: SyncState) => void): Unsubscribe {\r\n return () => {};\r\n }\r\n\r\n async flush(): Promise<void> {\r\n // no-op in mock\r\n }\r\n\r\n async clearCache(): Promise<void> {\r\n this._store.clear();\r\n }\r\n\r\n async getConflicts(): Promise<ConflictRecord[]> {\r\n return [];\r\n }\r\n\r\n /** Test helper — substitui fixture inteira de uma collection. */\r\n __setFixture(name: string, items: Record<string, Record<string, unknown>>): void {\r\n this._store.set(name, new Map(Object.entries(items)));\r\n }\r\n\r\n /** Test helper — reset total. */\r\n __reset(): void {\r\n this._store.clear();\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/db-errors.ts","../src/mocks.ts"],"names":[],"mappings":"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","file":"mocks.cjs","sourcesContent":["/**\n * Erros tipados do SDK.\n *\n * Todo erro lançado pelo SDK estende `NeetruError` — caller pode discriminar\n * por `.code` (string estável) sem parsing de message.\n */\n\n/** Códigos de erro estáveis do SDK. Adicionar aqui requer minor bump. */\nexport type NeetruErrorCode =\n | 'invalid_config'\n | 'missing_api_key'\n | 'unauthorized'\n | 'forbidden'\n | 'not_found'\n | 'rate_limited'\n | 'validation_failed'\n | 'network_error'\n | 'invalid_response'\n | 'server_error'\n | 'token_expired'\n | 'token_invalid_signature'\n | 'token_invalid_audience'\n | 'token_invalid_issuer'\n /** 3.0: runtime não expõe API necessária (ex: WebCrypto ausente). */\n | 'runtime_unsupported'\n /**\n * 3.1.3 (bug_c1c96a00): o `state` retornado pelo IdP no callback OIDC não bate com o gerado em\n * `signIn` (CSRF). Também usado quando não há transação OIDC pendente.\n */\n | 'oidc_state_mismatch'\n /** HTTP 409 — colisão de idempotência ou conflito de recurso. */\n | 'conflict'\n | 'unknown';\n\n/**\n * Erro tipado padrão do SDK. Sempre lançado em vez de Error genérico.\n *\n * @example\n * ```ts\n * try { await client.catalog.list(); }\n * catch (e) {\n * if (e instanceof NeetruError && e.code === 'rate_limited') retry();\n * }\n * ```\n */\nexport class NeetruError extends Error {\n public readonly code: NeetruErrorCode | string;\n public readonly status?: number;\n public readonly requestId?: string;\n\n constructor(\n code: NeetruErrorCode | string,\n message: string,\n status?: number,\n requestId?: string,\n ) {\n super(message);\n this.name = 'NeetruError';\n this.code = code;\n this.status = status;\n this.requestId = requestId;\n // Preserva o prototype chain ao herdar de Error (downlevel quirk de TS).\n Object.setPrototypeOf(this, NeetruError.prototype);\n }\n}\n","/**\r\n * NeetruDbError — classe de erro especializada para o módulo `db`.\r\n *\r\n * Conforma com 02-sdk.md §3.5: `NeetruDbError extends NeetruError`,\r\n * campo `code` fechado em `NeetruDbErrorCode`, campo `retryable` booleano,\r\n * campo `dbId` opaco para correlação.\r\n *\r\n * Herda de `NeetruError` para que um `catch (e) { if (e instanceof NeetruError) }`\r\n * genérico continue pegando erros de DB. Quem quer granularidade usa\r\n * `instanceof NeetruDbError` e o `code` fechado.\r\n */\r\n\r\nimport { NeetruError } from './errors';\r\n\r\n/**\r\n * Códigos de erro específicos do módulo `db`.\r\n *\r\n * - `db_unavailable` — lifecycle: provisionando / falhou / arquivado.\r\n * NÃO significa \"sem rede\" — offline é transparente.\r\n * - `db_not_found` — documento/coleção não encontrado no servidor.\r\n * - `db_conflict` — conflito de escrita detectado.\r\n * - `db_quota_exceeded` — quota de escrita/leitura excedida no banco.\r\n * - `db_permission_denied` — sem permissão para a operação.\r\n * - `db_invalid_query` — query inválida (campo, operador, tipo).\r\n * - `db_timeout` — operação excedeu o timeout.\r\n * - `offline_quota_exceeded`— IndexedDB cheio; a escrita não pode ser enfileirada.\r\n * - `offline_unavailable` — IndexedDB indisponível; SDK degrado para cache RAM.\r\n */\r\nexport type NeetruDbErrorCode =\r\n | 'db_unavailable'\r\n | 'db_not_found'\r\n | 'db_conflict'\r\n | 'db_quota_exceeded'\r\n | 'db_permission_denied'\r\n | 'db_invalid_query'\r\n | 'db_timeout'\r\n | 'offline_quota_exceeded'\r\n | 'offline_unavailable';\r\n\r\n/**\r\n * Códigos que são retryable por natureza.\r\n */\r\nconst RETRYABLE_CODES = new Set<NeetruDbErrorCode>([\r\n 'db_unavailable',\r\n 'db_conflict',\r\n 'db_timeout',\r\n]);\r\n\r\n/**\r\n * Erro tipado do módulo `db` — estende `NeetruError` para compatibilidade.\r\n *\r\n * @example\r\n * ```ts\r\n * try {\r\n * await client.db.collection('orders').add({ ... });\r\n * } catch (e) {\r\n * if (e instanceof NeetruDbError && e.code === 'offline_quota_exceeded') {\r\n * // IndexedDB cheio — notificar usuário\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport class NeetruDbError extends NeetruError {\r\n /** Código de erro fechado — específico de DB. */\r\n public override readonly code: NeetruDbErrorCode;\r\n\r\n /**\r\n * `true` para erros transientes que o produto pode tentar novamente.\r\n * São retryable: `db_unavailable`, `db_conflict`, `db_timeout`.\r\n */\r\n public readonly retryable: boolean;\r\n\r\n /**\r\n * ID opaco do banco lógico — só para correlação com logs do Core.\r\n * Nunca deve ser exibido ao usuário final.\r\n */\r\n public readonly dbId?: string;\r\n\r\n constructor(code: NeetruDbErrorCode, message: string, dbId?: string) {\r\n super(code, message);\r\n this.name = 'NeetruDbError';\r\n this.code = code;\r\n this.retryable = RETRYABLE_CODES.has(code);\r\n this.dbId = dbId;\r\n // Preserva o prototype chain (TypeScript + downlevel).\r\n Object.setPrototypeOf(this, NeetruDbError.prototype);\r\n }\r\n}\r\n","/**\r\n * Mocks determinísticos do SDK — overridáveis em tests do consumer ou\r\n * ativados automaticamente quando `NEETRU_ENV=dev`.\r\n *\r\n * Nada aqui faz I/O. Tudo é puro/sincrono/in-memory. Compat total com\r\n * runtimes browser/Node/Edge — sem `node:` builtins.\r\n *\r\n * Cada mock implementa o mesmo namespace interface das implementações reais\r\n * (`AuthNamespace`, `UsageNamespace`, `SupportNamespace`) — caller pode\r\n * substituir 1:1 sem branching.\r\n *\r\n * @example\r\n * ```ts\r\n * import { createNeetruClient, MockAuth } from '@neetru/sdk';\r\n *\r\n * const client = createNeetruClient({\r\n * mocks: { auth: new MockAuth({ uid: 'fake-user', email: 'x@x.com' }) },\r\n * });\r\n * ```\r\n */\r\n\r\nimport type {\r\n AuthNamespace,\r\n AuthStateListener,\r\n CreateTicketInput,\r\n EntitlementCheck,\r\n NeetruUser,\r\n RedirectCallbackResult,\r\n SignInOptions,\r\n SupportNamespace,\r\n SupportTicket,\r\n UsageNamespace,\r\n UsageQuota,\r\n} from './types';\r\nimport type {\r\n AiNamespace,\r\n AiChatOptions,\r\n AiChatResult,\r\n AiStreamHandle,\r\n AiStreamMeta,\r\n} from './ai';\r\nimport type {\r\n NeetruDb,\r\n NeetruSqlClient,\r\n} from './db/client-db';\r\nimport type { DbCollectionRef, DbWhereFilter, DbListResult, DbGetResult, DbBatchOp, DbDocRef, DbQuery } from './db/collection-ref';\r\nimport type { SyncState, ConflictRecord, Unsubscribe } from './db/offline/types';\r\nimport { NeetruDbError } from './db-errors';\r\nimport { NeetruError } from './errors';\r\n\r\n// ─── User fixture default ──────────────────────────────────────────────────\r\n\r\n/**\r\n * User fixture determinístico — usado quando `NEETRU_ENV=dev` e nenhum mock\r\n * custom é injetado. Email/uid estáveis pra snapshot tests.\r\n */\r\nexport const DEV_FIXTURE_USER: NeetruUser = Object.freeze({\r\n uid: 'dev-fixture-uid-0001',\r\n email: 'dev@neetru.local',\r\n emailVerified: true,\r\n displayName: 'Dev Fixture',\r\n isCustomer: true,\r\n isStaff: false,\r\n}) as NeetruUser;\r\n\r\n// ─── MockAuth ──────────────────────────────────────────────────────────────\r\n\r\n/** Opções do construtor de `MockAuth`. */\r\nexport interface MockAuthOptions {\r\n /**\r\n * Permite que `verifyToken` decodifique tokens JWT sem verificar assinatura.\r\n *\r\n * **SOMENTE para uso em testes.** Com `allowUnsignedDecode: false` (default),\r\n * `verifyToken` lança `unauthorized` em vez de aceitar qualquer JWT não-assinado —\r\n * isso previne que misconfiguração de env (`NEETRU_ENV=dev` em prod) vire bypass\r\n * de autenticação. Testes que precisam do comportamento de decode devem passar\r\n * `{ allowUnsignedDecode: true }` explicitamente.\r\n */\r\n allowUnsignedDecode?: boolean;\r\n}\r\n\r\n/**\r\n * Implementação in-memory do `AuthNamespace`. signIn marca o user como\r\n * logado; signOut limpa. onAuthStateChanged dispara callback síncrono no\r\n * subscribe + a cada mudança.\r\n */\r\nexport class MockAuth implements AuthNamespace {\r\n private _user: NeetruUser | null;\r\n private _listeners: Set<AuthStateListener>;\r\n private _allowUnsignedDecode: boolean;\r\n\r\n constructor(initialUser: NeetruUser | null = null, options?: MockAuthOptions) {\r\n this._user = initialUser;\r\n this._listeners = new Set();\r\n this._allowUnsignedDecode = options?.allowUnsignedDecode ?? false;\r\n\r\n // Emite aviso proeminente em dev quando fora de testes, pra deixar claro\r\n // que verifyToken no mock NÃO valida assinaturas.\r\n // Guard: não spamma em ambientes de teste (process.env.NODE_ENV=test ou\r\n // VITEST=true). Emite só uma vez por instância (basta pra chamar atenção).\r\n if (this._allowUnsignedDecode) {\r\n const isTestEnv =\r\n (typeof process !== 'undefined' && (\r\n process.env?.NODE_ENV === 'test' ||\r\n process.env?.VITEST === 'true' ||\r\n process.env?.VITEST != null\r\n ));\r\n if (!isTestEnv && typeof console !== 'undefined') {\r\n console.warn(\r\n '[neetru-sdk] MockAuth.verifyToken está em modo allowUnsignedDecode=true: ' +\r\n 'tokens NÃO têm assinatura verificada. ' +\r\n 'Este modo é exclusivo para testes — NUNCA use como security boundary em código deployado.',\r\n );\r\n }\r\n }\r\n }\r\n\r\n async signIn(_options?: SignInOptions): Promise<NeetruUser> {\r\n // Mock: apenas marca user como logado (usa fixture se não havia).\r\n if (!this._user) this._user = { ...DEV_FIXTURE_USER };\r\n this._notify();\r\n return this._user;\r\n }\r\n\r\n async signOut(): Promise<void> {\r\n this._user = null;\r\n this._notify();\r\n }\r\n\r\n getUser(): NeetruUser | null {\r\n return this._user;\r\n }\r\n\r\n onAuthStateChanged(listener: AuthStateListener): () => void {\r\n this._listeners.add(listener);\r\n // Dispara imediatamente com estado atual (espelha API Firebase Auth).\r\n try {\r\n listener(this._user);\r\n } catch {\r\n // Callback do consumer não pode quebrar o subscribe.\r\n }\r\n return () => {\r\n this._listeners.delete(listener);\r\n };\r\n }\r\n\r\n /**\r\n * Mock de `verifyToken` — por default lança `unauthorized` pra prevenir uso\r\n * acidental como security boundary em código deployado.\r\n *\r\n * Para decodificar JWTs sem verificar assinatura em testes, crie a instância\r\n * com `new MockAuth(user, { allowUnsignedDecode: true })`. Isso é um opt-in\r\n * explícito — nunca acontece silenciosamente.\r\n *\r\n * Para simular falhas ou resultados customizados, use `__mockVerifyToken(fn)`.\r\n */\r\n async verifyToken(token: string): Promise<NeetruUser> {\r\n if (this._verifyTokenOverride) {\r\n return this._verifyTokenOverride(token);\r\n }\r\n if (!token) {\r\n throw new NeetruError('token_invalid_signature', 'Token inválido: string vazia');\r\n }\r\n // Sem opt-in explícito, recusa-se a decodificar — decodificar JWTs sem\r\n // verificar assinatura é uma vulnerabilidade se este mock vazar pra produção\r\n // (ex: NEETRU_ENV=dev configurado erroneamente, ou globalThis.NEETRU_ENV\r\n // injetado por bundle). O caller deve usar __mockVerifyToken() ou passar\r\n // allowUnsignedDecode: true no construtor.\r\n if (!this._allowUnsignedDecode) {\r\n throw new NeetruError(\r\n 'unauthorized',\r\n 'MockAuth.verifyToken não verifica assinaturas JWT e NÃO deve ser usado como ' +\r\n 'security boundary em código deployado. ' +\r\n 'Em testes, use new MockAuth(user, { allowUnsignedDecode: true }) para habilitar ' +\r\n 'decodificação sem assinatura, ou __mockVerifyToken(fn) para injetar resultado customizado.',\r\n );\r\n }\r\n // allowUnsignedDecode=true: decodifica claims base64 sem verificar assinatura (testes).\r\n try {\r\n const parts = token.split('.');\r\n if (parts.length === 3) {\r\n const b64 = parts[1].replace(/-/g, '+').replace(/_/g, '/');\r\n const pad = '='.repeat((4 - (b64.length % 4)) % 4);\r\n const decoded = JSON.parse(\r\n typeof atob === 'function'\r\n ? atob(b64 + pad)\r\n : Buffer.from(b64 + pad, 'base64').toString('utf-8'),\r\n ) as Record<string, unknown>;\r\n if (typeof decoded.sub === 'string') {\r\n return {\r\n uid: decoded.sub,\r\n email: typeof decoded.email === 'string' ? decoded.email : '',\r\n emailVerified: typeof decoded.email_verified === 'boolean' ? decoded.email_verified : undefined,\r\n displayName: typeof decoded.name === 'string' ? decoded.name : undefined,\r\n photoURL: typeof decoded.picture === 'string' ? decoded.picture : undefined,\r\n isStaff: decoded.is_staff === true,\r\n isCustomer: decoded.is_customer === true,\r\n tenantId: typeof decoded.tenant_id === 'string' ? decoded.tenant_id : undefined,\r\n ...decoded,\r\n };\r\n }\r\n }\r\n } catch {\r\n /* fall through to return current user */\r\n }\r\n // Fallback: retorna o user atual do mock.\r\n if (this._user) return this._user;\r\n throw new NeetruError('token_invalid_signature', 'Nenhum user mock disponível e JWT sem sub válido');\r\n }\r\n\r\n /**\r\n * Mock de `handleRedirectCallback` (Bug 2 / 3.1.3) — não há redirect real no\r\n * mock, então retorna `null` por default. Use `__setPendingCallback(result)`\r\n * em testes pra simular um retorno do IdP.\r\n */\r\n async handleRedirectCallback(_currentUrl?: string): Promise<RedirectCallbackResult | null> {\r\n return this._pendingCallback;\r\n }\r\n\r\n /**\r\n * Mock de `getIdToken` (Bug 2 / 3.1.3). Retorna `null` por default; use\r\n * `__setIdToken(token)` pra injetar um token cru em testes.\r\n */\r\n getIdToken(): string | null {\r\n return this._idToken;\r\n }\r\n\r\n private _pendingCallback: RedirectCallbackResult | null = null;\r\n private _idToken: string | null = null;\r\n\r\n /** Test helper — simula o material devolvido por um callback OIDC. */\r\n __setPendingCallback(result: RedirectCallbackResult | null): void {\r\n this._pendingCallback = result;\r\n }\r\n\r\n /** Test helper — injeta o id_token cru retornado por `getIdToken`. */\r\n __setIdToken(token: string | null): void {\r\n this._idToken = token;\r\n }\r\n\r\n private _verifyTokenOverride: ((token: string) => Promise<NeetruUser>) | null = null;\r\n\r\n /**\r\n * Injeta override pra `verifyToken` em testes — permite simular expiração,\r\n * assinatura inválida etc sem precisar de JWT real.\r\n *\r\n * @example\r\n * ```ts\r\n * const mock = new MockAuth(null);\r\n * mock.__mockVerifyToken(async () => { throw new NeetruError('token_expired', '...'); });\r\n * ```\r\n */\r\n __mockVerifyToken(fn: ((token: string) => Promise<NeetruUser>) | null): void {\r\n this._verifyTokenOverride = fn;\r\n }\r\n\r\n /** Helper de tests — força um user state arbitrário. */\r\n __setUser(user: NeetruUser | null): void {\r\n this._user = user;\r\n this._notify();\r\n }\r\n\r\n private _notify(): void {\r\n for (const l of this._listeners) {\r\n try {\r\n l(this._user);\r\n } catch {\r\n // ignore consumer errors\r\n }\r\n }\r\n }\r\n}\r\n\r\n// ─── MockUsage (3.0 — track/getQuota removidos) ────────────────────────────\r\n\r\ninterface UsageReportRecord {\r\n resource: string;\r\n qty: number;\r\n productId?: string;\r\n tenantId?: string;\r\n timestamp: string;\r\n}\r\n\r\n/**\r\n * In-memory `UsageNamespace` 3.0. `report()` acumula counter local; `check()`\r\n * compara com `__setQuota(resource, {used, limit})` fixture.\r\n *\r\n * Breaking 3.0:\r\n * - `track(event, props)` REMOVIDO.\r\n * - `getQuota(metric)` REMOVIDO.\r\n * - `__getRecords()` agora retorna `UsageReportRecord[]` (resource/qty).\r\n */\r\nexport class MockUsage implements UsageNamespace {\r\n private _reports: UsageReportRecord[] = [];\r\n private _quotas: Map<string, UsageQuota>;\r\n private _counters: Map<string, number> = new Map();\r\n\r\n constructor(initialQuotas: Record<string, UsageQuota> = {}) {\r\n this._quotas = new Map(Object.entries(initialQuotas));\r\n }\r\n\r\n async report(\r\n resource: string,\r\n qty: number = 1,\r\n options?: { productId?: string; tenantId?: string },\r\n ): Promise<{\r\n ok: true;\r\n counterId?: string;\r\n value?: number;\r\n limit?: number;\r\n remaining?: number;\r\n status?: string;\r\n }> {\r\n if (!resource) throw new Error('resource required');\r\n const safeQty = Number.isFinite(qty) && qty > 0 ? Math.floor(qty) : 1;\r\n const existing = this._counters.get(resource) ?? 0;\r\n const next = existing + safeQty;\r\n this._counters.set(resource, next);\r\n this._reports.push({\r\n resource,\r\n qty: safeQty,\r\n productId: options?.productId,\r\n tenantId: options?.tenantId,\r\n timestamp: new Date().toISOString(),\r\n });\r\n const limitFixture = this._quotas.get(resource);\r\n const limit = limitFixture?.limit ?? -1;\r\n return {\r\n ok: true,\r\n counterId: `mock_${resource}`,\r\n value: next,\r\n limit,\r\n remaining: limit < 0 ? -1 : Math.max(0, limit - next),\r\n status: limit > 0 && next >= limit ? 'read_only_overlimit' : 'ok',\r\n };\r\n }\r\n\r\n async check(\r\n resource: string,\r\n _options?: { productId?: string; tenantId?: string },\r\n ): Promise<{\r\n allowed: boolean;\r\n reason?: string;\r\n remaining?: number;\r\n limit?: number;\r\n planId?: string | null;\r\n planFeatures?: string[];\r\n behavior?: 'readonly' | null;\r\n }> {\r\n const quota = this._quotas.get(resource);\r\n const used = this._counters.get(resource) ?? 0;\r\n if (!quota) {\r\n return { allowed: true, reason: 'granted', limit: -1, remaining: -1, behavior: null };\r\n }\r\n const remaining = quota.limit < 0 ? -1 : Math.max(0, quota.limit - used);\r\n if (remaining === 0) {\r\n return {\r\n allowed: false,\r\n reason: 'limit_exceeded',\r\n limit: quota.limit,\r\n remaining: 0,\r\n behavior: 'readonly',\r\n };\r\n }\r\n return {\r\n allowed: true,\r\n reason: 'granted',\r\n limit: quota.limit,\r\n remaining,\r\n behavior: null,\r\n };\r\n }\r\n\r\n /** Test helper — retorna histórico de `report()` calls. */\r\n __getReports(): readonly UsageReportRecord[] {\r\n return [...this._reports];\r\n }\r\n /** @deprecated Removido em 3.0 (usage.track foi removido). Use `__getReports`. */\r\n __getRecords(): readonly UsageReportRecord[] {\r\n return this.__getReports();\r\n }\r\n /** Test helper — substitui quota fixture. */\r\n __setQuota(metric: string, quota: UsageQuota): void {\r\n this._quotas.set(metric, quota);\r\n }\r\n /** Test helper — limpa estado. */\r\n __reset(): void {\r\n this._reports = [];\r\n this._quotas.clear();\r\n this._counters.clear();\r\n }\r\n}\r\n\r\n// ─── MockSupport ───────────────────────────────────────────────────────────\r\n\r\n/**\r\n * In-memory `SupportNamespace`. createTicket gera ID `mock-ticket-{n}`;\r\n * listMyTickets retorna todos criados (FIFO). Sequência por instância\r\n * (evita poluição cross-test do estado de módulo).\r\n */\r\nexport class MockSupport implements SupportNamespace {\r\n private _tickets: SupportTicket[] = [];\r\n private _ticketSeq = 0;\r\n\r\n async createTicket(input: CreateTicketInput): Promise<SupportTicket> {\r\n // L-03 fix (Opus review): MockSupport agora espelha contrato 3.0 do Core.\r\n // Antes aceitava input sem productSlug, mascarando bugs em tests que\r\n // passariam em prod com 400 validation_failed.\r\n if (!input?.subject) throw new NeetruError('validation_failed', 'subject required');\r\n if (!input?.message) throw new NeetruError('validation_failed', 'message required');\r\n if (!input?.productSlug) {\r\n throw new NeetruError(\r\n 'validation_failed',\r\n 'productSlug required (3.0 breaking — pass to input or set on createNeetruClient)',\r\n );\r\n }\r\n const ticket: SupportTicket = {\r\n id: `mock-ticket-${++this._ticketSeq}`,\r\n subject: input.subject,\r\n message: input.message,\r\n severity: input.severity ?? 'normal',\r\n status: 'open',\r\n createdAt: new Date().toISOString(),\r\n productSlug: input.productSlug,\r\n };\r\n this._tickets.push(ticket);\r\n return ticket;\r\n }\r\n\r\n async listMyTickets(options?: { productSlug?: string }): Promise<SupportTicket[]> {\r\n if (options?.productSlug) {\r\n return this._tickets.filter((t) => t.productSlug === options.productSlug);\r\n }\r\n return [...this._tickets];\r\n }\r\n\r\n /** Test helper. */\r\n __reset(): void {\r\n this._tickets = [];\r\n this._ticketSeq = 0;\r\n }\r\n}\r\n\r\n// ─── MockEntitlements ──────────────────────────────────────────────────────\r\n\r\n/**\r\n * In-memory entitlements. Por default `allowed=true` em tudo (dev convém).\r\n * Use `__deny(slug, feature)` em tests pra simular bloqueio.\r\n */\r\nexport class MockEntitlements {\r\n private _denied: Set<string> = new Set();\r\n\r\n async check(productSlug: string, feature: string): Promise<boolean> {\r\n return !this._denied.has(`${productSlug}:${feature}`);\r\n }\r\n\r\n async checkDetailed(productSlug: string, feature: string): Promise<EntitlementCheck> {\r\n const allowed = await this.check(productSlug, feature);\r\n return {\r\n allowed,\r\n productSlug,\r\n feature,\r\n reason: allowed ? 'granted' : 'mock_denied',\r\n };\r\n }\r\n\r\n /** Test helper. */\r\n __deny(productSlug: string, feature: string): void {\r\n this._denied.add(`${productSlug}:${feature}`);\r\n }\r\n /** Test helper. */\r\n __reset(): void {\r\n this._denied.clear();\r\n }\r\n}\r\n\r\n// ─── MockDb (v2.0) ─────────────────────────────────────────────────────────\r\n\r\n/**\r\n * In-memory `NeetruDb`. Cada `collection(name)` aponta para um Map; ops\r\n * são totalmente síncronas (mas API await-friendly).\r\n *\r\n * v2.0: implementa a interface `NeetruDb` completa (collection, sql, syncState,\r\n * flush, clearCache, getConflicts, onSyncStateChanged).\r\n *\r\n * Útil para testar produtos consumidores sem rodar Core REST nem IndexedDB.\r\n */\r\nexport class MockDb implements NeetruDb {\r\n private _store: Map<string, Map<string, Record<string, unknown>>> = new Map();\r\n private _fixtures: Map<string, Record<string, Record<string, unknown>>>;\r\n\r\n constructor(initialFixtures: Record<string, Record<string, Record<string, unknown>>> = {}) {\r\n this._fixtures = new Map(Object.entries(initialFixtures));\r\n }\r\n\r\n collection<T = Record<string, unknown>>(name: string): DbCollectionRef<T> {\r\n const _store = this._store;\r\n const _fixtures = this._fixtures;\r\n if (!_store.has(name)) {\r\n const init = _fixtures.get(name);\r\n _store.set(\r\n name,\r\n init ? new Map(Object.entries(init)) : new Map(),\r\n );\r\n }\r\n const coll = _store.get(name)!;\r\n\r\n const matchesFilter = (\r\n doc: Record<string, unknown>,\r\n f: DbWhereFilter,\r\n ): boolean => {\r\n const v = doc[f.field];\r\n switch (f.op) {\r\n case '==':\r\n return v === f.value;\r\n case '!=':\r\n return v !== f.value;\r\n case '<':\r\n return typeof v === 'number' && typeof f.value === 'number' && v < f.value;\r\n case '<=':\r\n return typeof v === 'number' && typeof f.value === 'number' && v <= f.value;\r\n case '>':\r\n return typeof v === 'number' && typeof f.value === 'number' && v > f.value;\r\n case '>=':\r\n return typeof v === 'number' && typeof f.value === 'number' && v >= f.value;\r\n case 'in':\r\n return Array.isArray(f.value) && (f.value as unknown[]).includes(v);\r\n case 'array-contains':\r\n return Array.isArray(v) && (v as unknown[]).includes(f.value);\r\n case 'not-in':\r\n return Array.isArray(f.value) && !(f.value as unknown[]).includes(v);\r\n default:\r\n return true;\r\n }\r\n };\r\n\r\n let autoSeq = 0;\r\n\r\n // Helper to build a minimal DbListResult from raw items\r\n function buildListResult<U>(items: Array<Record<string, unknown>>): DbListResult<U> {\r\n return {\r\n docs: items.map((d, i) => ({ id: (d.id as string) ?? String(i), data: d as U })),\r\n nextCursor: null,\r\n fromCache: false,\r\n stale: false,\r\n hasPendingWrites: false,\r\n changes: [],\r\n };\r\n }\r\n\r\n // Helper to build a DbGetResult for a single doc\r\n function buildGetResult<U>(data: Record<string, unknown>, id: string): DbGetResult<U> {\r\n return {\r\n docs: [{ id, data: data as U }],\r\n fromCache: false,\r\n stale: false,\r\n hasPendingWrites: false,\r\n changes: [],\r\n };\r\n }\r\n\r\n const ref: DbCollectionRef<T> = {\r\n async list(q?: DbQuery): Promise<DbListResult<T>> {\r\n let items = Array.from(coll.values());\r\n if (q?.where && q.where.length > 0) {\r\n items = items.filter((doc) =>\r\n (q.where as DbWhereFilter[]).every((f) => matchesFilter(doc, f)),\r\n );\r\n }\r\n if (q?.orderBy) {\r\n const { field, direction } = q.orderBy;\r\n items = items.slice().sort((a, b) => {\r\n const av = a[field];\r\n const bv = b[field];\r\n const avs = av ?? '';\r\n const bvs = bv ?? '';\r\n const cmp = (avs as string) < (bvs as string) ? -1 : (avs as string) > (bvs as string) ? 1 : 0;\r\n return direction === 'desc' ? -cmp : cmp;\r\n });\r\n }\r\n const limit = q?.limit ?? 20;\r\n items = items.slice(0, limit);\r\n return buildListResult<T>(items);\r\n },\r\n async get(id: string): Promise<DbGetResult<T> | null> {\r\n const data = coll.get(id);\r\n if (!data) return null;\r\n return buildGetResult<T>(data, id);\r\n },\r\n async add(data: Omit<T, 'id'>): Promise<{ ok: true; id: string }> {\r\n const id = `mock-${++autoSeq}-${Math.random().toString(36).slice(2, 8)}`;\r\n coll.set(id, { ...(data as Record<string, unknown>), id });\r\n return { ok: true, id };\r\n },\r\n async set(id: string, data: Omit<T, 'id'>): Promise<{ ok: true }> {\r\n coll.set(id, { ...(data as Record<string, unknown>), id });\r\n return { ok: true };\r\n },\r\n async update(id: string, data: Partial<Omit<T, 'id'>>): Promise<{ ok: true }> {\r\n const cur = coll.get(id);\r\n if (!cur) {\r\n coll.set(id, { ...(data as Record<string, unknown>), id });\r\n } else {\r\n coll.set(id, { ...cur, ...(data as Record<string, unknown>) });\r\n }\r\n return { ok: true };\r\n },\r\n async remove(id: string): Promise<{ ok: true }> {\r\n coll.delete(id);\r\n return { ok: true };\r\n },\r\n async batch(ops: DbBatchOp[]): Promise<{ ok: true }> {\r\n for (const op of ops) {\r\n // Mock usa a coleção corrente (collName) — o campo collection foi removido\r\n // do discriminated union em 2.1.1; batch opera sempre na coleção do ref.\r\n const collMap = coll;\r\n if (op.kind === 'add') {\r\n const id = `mock-batch-${++autoSeq}`;\r\n collMap.set(id, { ...(op.data as Record<string, unknown>), id });\r\n } else if (op.kind === 'set') {\r\n collMap.set(op.id, { ...(op.data as Record<string, unknown>), id: op.id });\r\n } else if (op.kind === 'update') {\r\n const cur = collMap.get(op.id);\r\n collMap.set(op.id, { ...(cur ?? {}), ...(op.data as Record<string, unknown>), id: op.id });\r\n } else if (op.kind === 'remove') {\r\n collMap.delete(op.id);\r\n }\r\n }\r\n return { ok: true };\r\n },\r\n onDoc(id: string, cb: (doc: T | null) => void): Unsubscribe {\r\n // Entrega snapshot inicial imediato (sync mock)\r\n const data = coll.get(id);\r\n Promise.resolve().then(() => cb(data ? (data as T) : null));\r\n // Mock: não há feed realtime — retorna no-op unsubscribe\r\n return () => {};\r\n },\r\n onSnapshot(q: DbQuery | undefined, cb: (snap: DbListResult<T>) => void): Unsubscribe {\r\n // Entrega snapshot inicial imediato (sync mock)\r\n Promise.resolve().then(async () => {\r\n const snap = await ref.list(q);\r\n cb(snap);\r\n });\r\n return () => {};\r\n },\r\n doc(id: string): DbDocRef<T> {\r\n return {\r\n get id(): string { return id; },\r\n get path(): string { return `${name}/${id}`; },\r\n get collection(): string { return name; },\r\n async get() {\r\n const data = coll.get(id);\r\n if (!data) return null;\r\n return buildGetResult<T>(data, id);\r\n },\r\n async set(data: Omit<T, 'id'>) {\r\n coll.set(id, { ...(data as Record<string, unknown>), id });\r\n return { ok: true };\r\n },\r\n async update(data: Partial<Omit<T, 'id'>>) {\r\n const cur = coll.get(id);\r\n if (!cur) {\r\n coll.set(id, { ...(data as Record<string, unknown>), id });\r\n } else {\r\n coll.set(id, { ...cur, ...(data as Record<string, unknown>) });\r\n }\r\n return { ok: true };\r\n },\r\n async remove() {\r\n coll.delete(id);\r\n return { ok: true };\r\n },\r\n onSnapshot(cb: (snap: DbGetResult<T> | null) => void): Unsubscribe {\r\n const data = coll.get(id);\r\n Promise.resolve().then(() =>\r\n cb(data ? buildGetResult<T>(data, id) : null),\r\n );\r\n return () => {};\r\n },\r\n };\r\n },\r\n };\r\n\r\n return ref;\r\n }\r\n\r\n /**\r\n * Implementa SQL in-memory para testes — preferência: `@electric-sql/pglite`\r\n * + `drizzle-orm/pglite`; fallback: `pg-mem` + `drizzle-orm/node-postgres`\r\n * com strip interceptor.\r\n *\r\n * bug_6bae8674461f4600809e2f9de13c6043 (HIGH 26/05): fix anterior (2.3.3)\r\n * teve efeito INVERSO. Injetar `pool.types.getTypeParser` fez drizzle-orm\r\n * passar `query.types.getTypeParser` pro pg-mem, que tem guard interno\r\n * `if (query.types?.getTypeParser) throw NotSupported`. Ou seja: presença\r\n * de getTypeParser é o gatilho do erro — não ausência.\r\n *\r\n * Solução A (pglite, preferida): `@electric-sql/pglite` é WASM-Postgres\r\n * nativo — sem adapter pg-mem, sem esse conflito de tipos.\r\n * Solução B (fallback pg-mem): strip interceptor no pool.query que deleta\r\n * `types.getTypeParser` do objeto de query ANTES do pg-mem ver. Compat com\r\n * consumers que só têm pg-mem nas devDeps.\r\n *\r\n * Use `options.initSql` pra rodar DDL no setup (CREATE TABLE etc).\r\n */\r\n async sql<TSchema extends Record<string, unknown>>(\r\n schema: TSchema,\r\n options?: { database?: string; initSql?: string | string[] },\r\n ): Promise<NeetruSqlClient<TSchema>> {\r\n const ddls = options?.initSql\r\n ? Array.isArray(options.initSql) ? options.initSql : [options.initSql]\r\n : [];\r\n\r\n // ── Solução A: pglite (preferida) ────────────────────────────────────────\r\n // PGlite é WASM-Postgres nativo — sem adapter pg-mem, sem o conflito de\r\n // tipos (pg-mem rejeita queries com getTypeParser presente; pglite não tem\r\n // esse guard).\r\n try {\r\n // bug_168368ae: webpackIgnore obrigatório — peerDeps optional server-only.\r\n const pglitePkg = await import(/* webpackIgnore: true */ '@electric-sql/pglite');\r\n const drizzlePglitePkg = await import(/* webpackIgnore: true */ 'drizzle-orm/pglite');\r\n\r\n // PGlite.create() retorna instância já pronta (waitReady resolvido).\r\n const pglite = await pglitePkg.PGlite.create();\r\n\r\n for (const ddl of ddls) {\r\n await pglite.query(ddl);\r\n }\r\n\r\n const pgliteOrm = drizzlePglitePkg.drizzle(pglite, { schema });\r\n\r\n // NeetruSqlClient.orm é tipado como NodePgDatabase — pglite e node-postgres\r\n // implementam a mesma superfície Drizzle mas com tipos de resultado internos\r\n // distintos (Results vs QueryResult). Cast via unknown necessário.\r\n const ormAsNode = pgliteOrm as unknown as import('drizzle-orm/node-postgres').NodePgDatabase<TSchema>;\r\n\r\n return {\r\n orm: ormAsNode,\r\n async transaction(fn, _opts) {\r\n return await pgliteOrm.transaction(fn as never) as never;\r\n },\r\n async close() {\r\n if (!pglite.closed) await pglite.close();\r\n },\r\n };\r\n } catch (_pgliteErr) {\r\n // Pglite indisponível (não instalado ou WASM falhou) — cai no pg-mem.\r\n }\r\n\r\n // ── Solução B: pg-mem + strip interceptor (fallback) ─────────────────────\r\n let pgMemMod: typeof import('pg-mem');\r\n let drizzlePg: typeof import('drizzle-orm/node-postgres');\r\n try {\r\n // bug_168368ae: webpackIgnore obrigatório.\r\n pgMemMod = await import(/* webpackIgnore: true */ 'pg-mem');\r\n drizzlePg = await import(/* webpackIgnore: true */ 'drizzle-orm/node-postgres');\r\n } catch {\r\n throw new NeetruDbError(\r\n 'db_unavailable',\r\n '[MockDb] sql() requer @electric-sql/pglite OU pg-mem + drizzle-orm + pg como devDependencies. ' +\r\n 'Preferido: npm install -D @electric-sql/pglite drizzle-orm. ' +\r\n 'Alternativo: npm install -D pg-mem drizzle-orm pg.',\r\n );\r\n }\r\n\r\n const memDb = pgMemMod.newDb({ noAstCoverageCheck: true });\r\n\r\n if (ddls.length > 0) {\r\n for (const ddl of ddls) {\r\n memDb.public.none(ddl);\r\n }\r\n }\r\n\r\n const adapters = memDb.adapters.createPg();\r\n const PoolCtor = (adapters as { Pool: new () => unknown }).Pool;\r\n const pool = new PoolCtor() as Record<string, unknown>;\r\n\r\n // bug_6bae8674 strip interceptor: pg-mem rejeita queries que TÊM\r\n // `query.types.getTypeParser` presente (guard interno NotSupported).\r\n // drizzle-orm/node-postgres/session.js injeta `rawQuery.types = pool.types`\r\n // em toda query. Ao interceptar pool.query e deletar getTypeParser do objeto\r\n // de query antes de passar pro pg-mem, o guard não dispara.\r\n // NÃO adicionar getTypeParser ao pool.types (fix 2.3.3 causou efeito inverso).\r\n const origQuery = (pool as { query: (...a: unknown[]) => unknown }).query.bind(pool);\r\n (pool as { query: (...a: unknown[]) => unknown }).query = (q: unknown, ...rest: unknown[]) => {\r\n if (q !== null && typeof q === 'object') {\r\n const queryObj = q as Record<string, unknown>;\r\n const types = queryObj['types'];\r\n if (types !== null && typeof types === 'object' && 'getTypeParser' in (types as object)) {\r\n delete (types as Record<string, unknown>)['getTypeParser'];\r\n }\r\n }\r\n return origQuery(q, ...rest);\r\n };\r\n\r\n const orm = drizzlePg.drizzle(pool as never, { schema }) as unknown as\r\n import('drizzle-orm/node-postgres').NodePgDatabase<TSchema>;\r\n\r\n return {\r\n orm,\r\n async transaction(fn, _opts) {\r\n return await orm.transaction(fn as never) as never;\r\n },\r\n async close() {\r\n const p = pool as { end?: () => Promise<void> };\r\n if (p.end) await p.end();\r\n },\r\n };\r\n }\r\n\r\n get syncState(): SyncState {\r\n return {\r\n status: 'idle',\r\n pendingWrites: 0,\r\n lastSyncedAt: null,\r\n isLeaderTab: true,\r\n };\r\n }\r\n\r\n onSyncStateChanged(_cb: (s: SyncState) => void): Unsubscribe {\r\n return () => {};\r\n }\r\n\r\n async flush(): Promise<void> {\r\n // no-op in mock\r\n }\r\n\r\n async clearCache(): Promise<void> {\r\n this._store.clear();\r\n }\r\n\r\n async getConflicts(): Promise<ConflictRecord[]> {\r\n return [];\r\n }\r\n\r\n /** Test helper — substitui fixture inteira de uma collection. */\r\n __setFixture(name: string, items: Record<string, Record<string, unknown>>): void {\r\n this._store.set(name, new Map(Object.entries(items)));\r\n }\r\n\r\n /** Test helper — reset total. */\r\n __reset(): void {\r\n this._store.clear();\r\n }\r\n}\r\n\r\n// ─── MockAi ──────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Mock determinístico do namespace `ai` — ativado em `NEETRU_ENV=dev` ou\r\n * injetado via `mocks.ai`. Sem I/O e sem apiKey: `chat` ecoa o último message\r\n * do usuário; `stream` yielda esse eco fatiado por palavra. `provider='mock'`,\r\n * `usageWarning=false`.\r\n */\r\nexport class MockAi implements AiNamespace {\r\n private _calls: Array<{ model: string; messages: AiChatOptions['messages']; stream: boolean }> = [];\r\n\r\n private _reply(opts: AiChatOptions): string {\r\n const last = [...opts.messages].reverse().find((m) => m.role === 'user') ?? opts.messages[opts.messages.length - 1];\r\n const content = last?.content ?? '';\r\n return content ? `mock-reply: ${content}` : 'mock-reply';\r\n }\r\n\r\n async chat(opts: AiChatOptions): Promise<AiChatResult> {\r\n if (!opts || typeof opts.model !== 'string' || opts.model.length === 0) {\r\n throw new NeetruError('validation_failed', 'ai: model is required');\r\n }\r\n if (!Array.isArray(opts.messages) || opts.messages.length === 0) {\r\n throw new NeetruError('validation_failed', 'ai: messages must be a non-empty array');\r\n }\r\n this._calls.push({ model: opts.model, messages: opts.messages, stream: false });\r\n const text = this._reply(opts);\r\n const promptTokens = opts.messages.reduce((n, m) => n + (m.content?.length ?? 0), 0);\r\n const completionTokens = text.length;\r\n return {\r\n choices: [{ message: { role: 'assistant', content: text }, finish_reason: 'stop' }],\r\n usage: {\r\n prompt_tokens: promptTokens,\r\n completion_tokens: completionTokens,\r\n total_tokens: promptTokens + completionTokens,\r\n },\r\n model: opts.model,\r\n provider: 'mock',\r\n usageWarning: false,\r\n };\r\n }\r\n\r\n stream(opts: AiChatOptions): AiStreamHandle {\r\n if (!opts || typeof opts.model !== 'string' || opts.model.length === 0) {\r\n throw new NeetruError('validation_failed', 'ai: model is required');\r\n }\r\n if (!Array.isArray(opts.messages) || opts.messages.length === 0) {\r\n throw new NeetruError('validation_failed', 'ai: messages must be a non-empty array');\r\n }\r\n this._calls.push({ model: opts.model, messages: opts.messages, stream: true });\r\n const text = this._reply(opts);\r\n // Fatia por palavra preservando os espaços (concatenação reconstrói o texto).\r\n const parts = text.match(/\\S+\\s*/g) ?? [text];\r\n const meta: Promise<AiStreamMeta> = Promise.resolve({ provider: 'mock', usageWarning: false });\r\n async function* iterate(): AsyncGenerator<string, void, unknown> {\r\n for (const p of parts) yield p;\r\n }\r\n return { meta, [Symbol.asyncIterator]: iterate };\r\n }\r\n\r\n /** Test helper — histórico de chamadas. */\r\n __getCalls(): Array<{ model: string; messages: AiChatOptions['messages']; stream: boolean }> {\r\n return this._calls;\r\n }\r\n}\r\n"]}
|
package/dist/mocks.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a0 as NeetruUser, e as AiNamespace, b as AiChatOptions, c as AiChatResult, f as AiStreamHandle, h as AuthNamespace, ae as SignInOptions, i as AuthStateListener, a9 as RedirectCallbackResult, T as NeetruDb, w as DbCollectionRef, $ as NeetruSqlClient, ak as SyncState, ap as Unsubscribe, r as ConflictRecord, J as EntitlementCheck, ag as SupportNamespace, t as CreateTicketInput, aj as SupportTicket, ar as UsageNamespace, as as UsageQuota } from './types-Cog9S-tC.cjs';
|
|
2
2
|
import 'drizzle-orm/node-postgres';
|
|
3
3
|
import './errors.cjs';
|
|
4
4
|
|
|
@@ -227,5 +227,23 @@ declare class MockDb implements NeetruDb {
|
|
|
227
227
|
/** Test helper — reset total. */
|
|
228
228
|
__reset(): void;
|
|
229
229
|
}
|
|
230
|
+
/**
|
|
231
|
+
* Mock determinístico do namespace `ai` — ativado em `NEETRU_ENV=dev` ou
|
|
232
|
+
* injetado via `mocks.ai`. Sem I/O e sem apiKey: `chat` ecoa o último message
|
|
233
|
+
* do usuário; `stream` yielda esse eco fatiado por palavra. `provider='mock'`,
|
|
234
|
+
* `usageWarning=false`.
|
|
235
|
+
*/
|
|
236
|
+
declare class MockAi implements AiNamespace {
|
|
237
|
+
private _calls;
|
|
238
|
+
private _reply;
|
|
239
|
+
chat(opts: AiChatOptions): Promise<AiChatResult>;
|
|
240
|
+
stream(opts: AiChatOptions): AiStreamHandle;
|
|
241
|
+
/** Test helper — histórico de chamadas. */
|
|
242
|
+
__getCalls(): Array<{
|
|
243
|
+
model: string;
|
|
244
|
+
messages: AiChatOptions['messages'];
|
|
245
|
+
stream: boolean;
|
|
246
|
+
}>;
|
|
247
|
+
}
|
|
230
248
|
|
|
231
|
-
export { DEV_FIXTURE_USER, MockAuth, type MockAuthOptions, MockDb, MockEntitlements, MockSupport, MockUsage };
|
|
249
|
+
export { DEV_FIXTURE_USER, MockAi, MockAuth, type MockAuthOptions, MockDb, MockEntitlements, MockSupport, MockUsage };
|
package/dist/mocks.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a0 as NeetruUser, e as AiNamespace, b as AiChatOptions, c as AiChatResult, f as AiStreamHandle, h as AuthNamespace, ae as SignInOptions, i as AuthStateListener, a9 as RedirectCallbackResult, T as NeetruDb, w as DbCollectionRef, $ as NeetruSqlClient, ak as SyncState, ap as Unsubscribe, r as ConflictRecord, J as EntitlementCheck, ag as SupportNamespace, t as CreateTicketInput, aj as SupportTicket, ar as UsageNamespace, as as UsageQuota } from './types-dagUxKYz.js';
|
|
2
2
|
import 'drizzle-orm/node-postgres';
|
|
3
3
|
import './errors.js';
|
|
4
4
|
|
|
@@ -227,5 +227,23 @@ declare class MockDb implements NeetruDb {
|
|
|
227
227
|
/** Test helper — reset total. */
|
|
228
228
|
__reset(): void;
|
|
229
229
|
}
|
|
230
|
+
/**
|
|
231
|
+
* Mock determinístico do namespace `ai` — ativado em `NEETRU_ENV=dev` ou
|
|
232
|
+
* injetado via `mocks.ai`. Sem I/O e sem apiKey: `chat` ecoa o último message
|
|
233
|
+
* do usuário; `stream` yielda esse eco fatiado por palavra. `provider='mock'`,
|
|
234
|
+
* `usageWarning=false`.
|
|
235
|
+
*/
|
|
236
|
+
declare class MockAi implements AiNamespace {
|
|
237
|
+
private _calls;
|
|
238
|
+
private _reply;
|
|
239
|
+
chat(opts: AiChatOptions): Promise<AiChatResult>;
|
|
240
|
+
stream(opts: AiChatOptions): AiStreamHandle;
|
|
241
|
+
/** Test helper — histórico de chamadas. */
|
|
242
|
+
__getCalls(): Array<{
|
|
243
|
+
model: string;
|
|
244
|
+
messages: AiChatOptions['messages'];
|
|
245
|
+
stream: boolean;
|
|
246
|
+
}>;
|
|
247
|
+
}
|
|
230
248
|
|
|
231
|
-
export { DEV_FIXTURE_USER, MockAuth, type MockAuthOptions, MockDb, MockEntitlements, MockSupport, MockUsage };
|
|
249
|
+
export { DEV_FIXTURE_USER, MockAi, MockAuth, type MockAuthOptions, MockDb, MockEntitlements, MockSupport, MockUsage };
|
package/dist/mocks.mjs
CHANGED
|
@@ -640,7 +640,58 @@ var MockDb = class {
|
|
|
640
640
|
this._store.clear();
|
|
641
641
|
}
|
|
642
642
|
};
|
|
643
|
+
var MockAi = class {
|
|
644
|
+
_calls = [];
|
|
645
|
+
_reply(opts) {
|
|
646
|
+
const last = [...opts.messages].reverse().find((m) => m.role === "user") ?? opts.messages[opts.messages.length - 1];
|
|
647
|
+
const content = last?.content ?? "";
|
|
648
|
+
return content ? `mock-reply: ${content}` : "mock-reply";
|
|
649
|
+
}
|
|
650
|
+
async chat(opts) {
|
|
651
|
+
if (!opts || typeof opts.model !== "string" || opts.model.length === 0) {
|
|
652
|
+
throw new NeetruError("validation_failed", "ai: model is required");
|
|
653
|
+
}
|
|
654
|
+
if (!Array.isArray(opts.messages) || opts.messages.length === 0) {
|
|
655
|
+
throw new NeetruError("validation_failed", "ai: messages must be a non-empty array");
|
|
656
|
+
}
|
|
657
|
+
this._calls.push({ model: opts.model, messages: opts.messages, stream: false });
|
|
658
|
+
const text = this._reply(opts);
|
|
659
|
+
const promptTokens = opts.messages.reduce((n, m) => n + (m.content?.length ?? 0), 0);
|
|
660
|
+
const completionTokens = text.length;
|
|
661
|
+
return {
|
|
662
|
+
choices: [{ message: { role: "assistant", content: text }, finish_reason: "stop" }],
|
|
663
|
+
usage: {
|
|
664
|
+
prompt_tokens: promptTokens,
|
|
665
|
+
completion_tokens: completionTokens,
|
|
666
|
+
total_tokens: promptTokens + completionTokens
|
|
667
|
+
},
|
|
668
|
+
model: opts.model,
|
|
669
|
+
provider: "mock",
|
|
670
|
+
usageWarning: false
|
|
671
|
+
};
|
|
672
|
+
}
|
|
673
|
+
stream(opts) {
|
|
674
|
+
if (!opts || typeof opts.model !== "string" || opts.model.length === 0) {
|
|
675
|
+
throw new NeetruError("validation_failed", "ai: model is required");
|
|
676
|
+
}
|
|
677
|
+
if (!Array.isArray(opts.messages) || opts.messages.length === 0) {
|
|
678
|
+
throw new NeetruError("validation_failed", "ai: messages must be a non-empty array");
|
|
679
|
+
}
|
|
680
|
+
this._calls.push({ model: opts.model, messages: opts.messages, stream: true });
|
|
681
|
+
const text = this._reply(opts);
|
|
682
|
+
const parts = text.match(/\S+\s*/g) ?? [text];
|
|
683
|
+
const meta = Promise.resolve({ provider: "mock", usageWarning: false });
|
|
684
|
+
async function* iterate() {
|
|
685
|
+
for (const p of parts) yield p;
|
|
686
|
+
}
|
|
687
|
+
return { meta, [Symbol.asyncIterator]: iterate };
|
|
688
|
+
}
|
|
689
|
+
/** Test helper — histórico de chamadas. */
|
|
690
|
+
__getCalls() {
|
|
691
|
+
return this._calls;
|
|
692
|
+
}
|
|
693
|
+
};
|
|
643
694
|
|
|
644
|
-
export { DEV_FIXTURE_USER, MockAuth, MockDb, MockEntitlements, MockSupport, MockUsage };
|
|
695
|
+
export { DEV_FIXTURE_USER, MockAi, MockAuth, MockDb, MockEntitlements, MockSupport, MockUsage };
|
|
645
696
|
//# sourceMappingURL=mocks.mjs.map
|
|
646
697
|
//# sourceMappingURL=mocks.mjs.map
|