@neetru/sdk 3.6.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +49 -0
- package/dist/ai.cjs +254 -391
- package/dist/ai.d.cts +1 -1
- package/dist/ai.d.ts +1 -1
- package/dist/ai.mjs +254 -391
- package/dist/auth.cjs +3547 -4998
- package/dist/auth.d.cts +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/auth.mjs +3544 -4995
- package/dist/build-guard.cjs +101 -119
- package/dist/build-guard.mjs +91 -109
- package/dist/catalog.cjs +152 -224
- package/dist/catalog.d.cts +1 -1
- package/dist/catalog.d.ts +1 -1
- package/dist/catalog.mjs +152 -224
- package/dist/checkout.cjs +237 -320
- package/dist/checkout.d.cts +1 -1
- package/dist/checkout.d.ts +1 -1
- package/dist/checkout.mjs +236 -319
- package/dist/db-react.cjs +59 -87
- package/dist/db-react.d.cts +1 -1
- package/dist/db-react.d.ts +1 -1
- package/dist/db-react.mjs +56 -84
- package/dist/db.cjs +2055 -3013
- package/dist/db.d.cts +1 -1
- package/dist/db.d.ts +1 -1
- package/dist/db.mjs +2068 -3026
- package/dist/entitlements.cjs +12 -20
- package/dist/entitlements.d.cts +1 -1
- package/dist/entitlements.d.ts +1 -1
- package/dist/entitlements.mjs +12 -20
- package/dist/errors.cjs +9 -12
- package/dist/errors.d.cts +37 -2
- package/dist/errors.d.ts +37 -2
- package/dist/errors.mjs +8 -12
- package/dist/firestore-compat.cjs +241 -297
- package/dist/firestore-compat.d.cts +1 -1
- package/dist/firestore-compat.d.ts +1 -1
- package/dist/firestore-compat.mjs +215 -271
- package/dist/index.cjs +3605 -5131
- package/dist/index.d.cts +6 -4
- package/dist/index.d.ts +6 -4
- package/dist/index.mjs +3710 -5236
- package/dist/mobile.cjs +238 -342
- package/dist/mobile.d.cts +1 -1
- package/dist/mobile.d.ts +1 -1
- package/dist/mobile.mjs +238 -342
- package/dist/mocks.cjs +312 -447
- package/dist/mocks.d.cts +1 -1
- package/dist/mocks.d.ts +1 -1
- package/dist/mocks.mjs +306 -441
- package/dist/notifications.cjs +226 -314
- package/dist/notifications.d.cts +1 -1
- package/dist/notifications.d.ts +1 -1
- package/dist/notifications.mjs +225 -313
- package/dist/react.cjs +522 -693
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.mjs +512 -683
- package/dist/support.cjs +329 -325
- package/dist/support.d.cts +25 -3
- package/dist/support.d.ts +25 -3
- package/dist/support.mjs +328 -325
- package/dist/telemetry.cjs +197 -301
- package/dist/telemetry.d.cts +1 -1
- package/dist/telemetry.d.ts +1 -1
- package/dist/telemetry.mjs +197 -301
- package/dist/{types-Du_iioJ7.d.cts → types-Bx4kTLmk.d.cts} +26 -0
- package/dist/{types-BPATkXYu.d.ts → types-Dx0IrOSF.d.ts} +26 -0
- package/dist/usage.cjs +163 -227
- package/dist/usage.d.cts +1 -1
- package/dist/usage.d.ts +1 -1
- package/dist/usage.mjs +163 -227
- package/dist/webhooks.cjs +258 -359
- package/dist/webhooks.d.cts +1 -1
- package/dist/webhooks.d.ts +1 -1
- package/dist/webhooks.mjs +255 -356
- package/package.json +4 -3
- package/dist/ai.cjs.map +0 -1
- package/dist/ai.mjs.map +0 -1
- package/dist/auth.cjs.map +0 -1
- package/dist/auth.mjs.map +0 -1
- package/dist/build-guard.cjs.map +0 -1
- package/dist/build-guard.mjs.map +0 -1
- package/dist/catalog.cjs.map +0 -1
- package/dist/catalog.mjs.map +0 -1
- package/dist/checkout.cjs.map +0 -1
- package/dist/checkout.mjs.map +0 -1
- package/dist/db-react.cjs.map +0 -1
- package/dist/db-react.mjs.map +0 -1
- package/dist/db.cjs.map +0 -1
- package/dist/db.mjs.map +0 -1
- package/dist/entitlements.cjs.map +0 -1
- package/dist/entitlements.mjs.map +0 -1
- package/dist/errors.cjs.map +0 -1
- package/dist/errors.mjs.map +0 -1
- package/dist/firestore-compat.cjs.map +0 -1
- package/dist/firestore-compat.mjs.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/mobile.cjs.map +0 -1
- package/dist/mobile.mjs.map +0 -1
- package/dist/mocks.cjs.map +0 -1
- package/dist/mocks.mjs.map +0 -1
- package/dist/notifications.cjs.map +0 -1
- package/dist/notifications.mjs.map +0 -1
- package/dist/react.cjs.map +0 -1
- package/dist/react.mjs.map +0 -1
- package/dist/support.cjs.map +0 -1
- package/dist/support.mjs.map +0 -1
- package/dist/telemetry.cjs.map +0 -1
- package/dist/telemetry.mjs.map +0 -1
- package/dist/usage.cjs.map +0 -1
- package/dist/usage.mjs.map +0 -1
- package/dist/webhooks.cjs.map +0 -1
- package/dist/webhooks.mjs.map +0 -1
package/dist/mocks.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/errors.ts
|
|
2
|
-
var
|
|
2
|
+
var l = class m extends Error {
|
|
3
3
|
code;
|
|
4
4
|
status;
|
|
5
5
|
requestId;
|
|
@@ -12,24 +12,17 @@ var NeetruError = class _NeetruError extends Error {
|
|
|
12
12
|
* para um `NeetruDbErrorCode` mais específico (recuperável vs não).
|
|
13
13
|
*/
|
|
14
14
|
reason;
|
|
15
|
-
constructor(
|
|
16
|
-
super(
|
|
17
|
-
this.name = "NeetruError";
|
|
18
|
-
this.code = code;
|
|
19
|
-
this.status = status;
|
|
20
|
-
this.requestId = requestId;
|
|
21
|
-
this.reason = reason;
|
|
22
|
-
Object.setPrototypeOf(this, _NeetruError.prototype);
|
|
15
|
+
constructor(e, r, i, o, a) {
|
|
16
|
+
super(r), this.name = "NeetruError", this.code = e, this.status = i, this.requestId = o, this.reason = a, Object.setPrototypeOf(this, m.prototype);
|
|
23
17
|
}
|
|
24
18
|
};
|
|
25
19
|
|
|
26
20
|
// src/db-errors.ts
|
|
27
|
-
var
|
|
21
|
+
var U = /* @__PURE__ */ new Set([
|
|
28
22
|
"db_unavailable",
|
|
29
23
|
"db_conflict",
|
|
30
24
|
"db_timeout"
|
|
31
|
-
])
|
|
32
|
-
var NeetruDbError = class _NeetruDbError extends NeetruError {
|
|
25
|
+
]), _ = class m extends l {
|
|
33
26
|
/** Código de erro fechado — específico de DB. */
|
|
34
27
|
code;
|
|
35
28
|
/**
|
|
@@ -42,79 +35,60 @@ var NeetruDbError = class _NeetruDbError extends NeetruError {
|
|
|
42
35
|
* Nunca deve ser exibido ao usuário final.
|
|
43
36
|
*/
|
|
44
37
|
dbId;
|
|
45
|
-
constructor(
|
|
46
|
-
super(code,
|
|
47
|
-
this.name = "NeetruDbError";
|
|
48
|
-
this.code = code;
|
|
49
|
-
this.retryable = RETRYABLE_CODES.has(code);
|
|
50
|
-
this.dbId = dbId;
|
|
51
|
-
Object.setPrototypeOf(this, _NeetruDbError.prototype);
|
|
38
|
+
constructor(e, r, i) {
|
|
39
|
+
super(e, r), this.name = "NeetruDbError", this.code = e, this.retryable = U.has(e), this.dbId = i, Object.setPrototypeOf(this, m.prototype);
|
|
52
40
|
}
|
|
53
41
|
};
|
|
54
42
|
|
|
55
43
|
// src/runtime-env.ts
|
|
56
|
-
function
|
|
44
|
+
function R() {
|
|
57
45
|
try {
|
|
58
|
-
if (typeof process
|
|
46
|
+
if (typeof process < "u" && process.env)
|
|
59
47
|
return process.env.NODE_ENV === "production";
|
|
60
|
-
}
|
|
61
48
|
} catch {
|
|
62
49
|
}
|
|
63
50
|
return false;
|
|
64
51
|
}
|
|
65
52
|
|
|
66
53
|
// src/mocks.ts
|
|
67
|
-
var
|
|
54
|
+
var x = Object.freeze({
|
|
68
55
|
uid: "dev-fixture-uid-0001",
|
|
69
56
|
email: "dev@neetru.local",
|
|
70
57
|
emailVerified: true,
|
|
71
58
|
displayName: "Dev Fixture",
|
|
72
59
|
isCustomer: true,
|
|
73
60
|
isStaff: false
|
|
74
|
-
})
|
|
75
|
-
var MockAuth = class {
|
|
61
|
+
}), A = class {
|
|
76
62
|
_user;
|
|
77
63
|
_listeners;
|
|
78
64
|
_allowUnsignedDecode;
|
|
79
|
-
constructor(
|
|
80
|
-
this._user =
|
|
81
|
-
|
|
82
|
-
this._allowUnsignedDecode = options?.allowUnsignedDecode ?? false;
|
|
83
|
-
if (this._allowUnsignedDecode && isProductionRuntime()) {
|
|
84
|
-
throw new NeetruError(
|
|
65
|
+
constructor(e = null, r) {
|
|
66
|
+
if (this._user = e, this._listeners = /* @__PURE__ */ new Set(), this._allowUnsignedDecode = r?.allowUnsignedDecode ?? false, this._allowUnsignedDecode && R())
|
|
67
|
+
throw new l(
|
|
85
68
|
"invalid_config",
|
|
86
69
|
"MockAuth com allowUnsignedDecode=true \xE9 PROIBIDO em produ\xE7\xE3o (NODE_ENV=production): decodificar JWT sem verificar assinatura \xE9 bypass de autentica\xE7\xE3o. Este modo existe exclusivamente para testes."
|
|
87
70
|
);
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (!isTestEnv && typeof console !== "undefined") {
|
|
92
|
-
console.warn(
|
|
93
|
-
"[neetru-sdk] MockAuth.verifyToken est\xE1 em modo allowUnsignedDecode=true: tokens N\xC3O t\xEAm assinatura verificada. Este modo \xE9 exclusivo para testes \u2014 NUNCA use como security boundary em c\xF3digo deployado."
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
71
|
+
this._allowUnsignedDecode && !(typeof process < "u" && (process.env?.NODE_ENV === "test" || process.env?.VITEST === "true" || process.env?.VITEST != null)) && typeof console < "u" && console.warn(
|
|
72
|
+
"[neetru-sdk] MockAuth.verifyToken est\xE1 em modo allowUnsignedDecode=true: tokens N\xC3O t\xEAm assinatura verificada. Este modo \xE9 exclusivo para testes \u2014 NUNCA use como security boundary em c\xF3digo deployado."
|
|
73
|
+
);
|
|
97
74
|
}
|
|
98
|
-
async signIn(
|
|
99
|
-
|
|
100
|
-
this._notify();
|
|
101
|
-
return this._user;
|
|
75
|
+
async signIn(e) {
|
|
76
|
+
return this._user || (this._user = { ...x }), this._notify(), this._user;
|
|
102
77
|
}
|
|
103
78
|
async signOut() {
|
|
104
|
-
this._user = null;
|
|
105
|
-
this._notify();
|
|
79
|
+
this._user = null, this._notify();
|
|
106
80
|
}
|
|
107
81
|
getUser() {
|
|
108
82
|
return this._user;
|
|
109
83
|
}
|
|
110
|
-
onAuthStateChanged(
|
|
111
|
-
this._listeners.add(
|
|
84
|
+
onAuthStateChanged(e) {
|
|
85
|
+
this._listeners.add(e);
|
|
112
86
|
try {
|
|
113
|
-
|
|
87
|
+
e(this._user);
|
|
114
88
|
} catch {
|
|
115
89
|
}
|
|
116
90
|
return () => {
|
|
117
|
-
this._listeners.delete(
|
|
91
|
+
this._listeners.delete(e);
|
|
118
92
|
};
|
|
119
93
|
}
|
|
120
94
|
/**
|
|
@@ -127,52 +101,46 @@ var MockAuth = class {
|
|
|
127
101
|
*
|
|
128
102
|
* Para simular falhas ou resultados customizados, use `__mockVerifyToken(fn)`.
|
|
129
103
|
*/
|
|
130
|
-
async verifyToken(
|
|
131
|
-
if (this._verifyTokenOverride)
|
|
132
|
-
return this._verifyTokenOverride(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
if (!this._allowUnsignedDecode) {
|
|
138
|
-
throw new NeetruError(
|
|
104
|
+
async verifyToken(e) {
|
|
105
|
+
if (this._verifyTokenOverride)
|
|
106
|
+
return this._verifyTokenOverride(e);
|
|
107
|
+
if (!e)
|
|
108
|
+
throw new l("token_invalid_signature", "Token inv\xE1lido: string vazia");
|
|
109
|
+
if (!this._allowUnsignedDecode)
|
|
110
|
+
throw new l(
|
|
139
111
|
"unauthorized",
|
|
140
112
|
"MockAuth.verifyToken n\xE3o verifica assinaturas JWT e N\xC3O deve ser usado como security boundary em c\xF3digo deployado. Em testes, use new MockAuth(user, { allowUnsignedDecode: true }) para habilitar decodifica\xE7\xE3o sem assinatura, ou __mockVerifyToken(fn) para injetar resultado customizado."
|
|
141
113
|
);
|
|
142
|
-
}
|
|
143
114
|
try {
|
|
144
|
-
|
|
145
|
-
if (
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const decoded = JSON.parse(
|
|
149
|
-
typeof atob === "function" ? atob(b64 + pad) : Buffer.from(b64 + pad, "base64").toString("utf-8")
|
|
115
|
+
let r = e.split(".");
|
|
116
|
+
if (r.length === 3) {
|
|
117
|
+
let i = r[1].replace(/-/g, "+").replace(/_/g, "/"), o = "=".repeat((4 - i.length % 4) % 4), a = JSON.parse(
|
|
118
|
+
typeof atob == "function" ? atob(i + o) : Buffer.from(i + o, "base64").toString("utf-8")
|
|
150
119
|
);
|
|
151
|
-
if (typeof
|
|
120
|
+
if (typeof a.sub == "string")
|
|
152
121
|
return {
|
|
153
|
-
uid:
|
|
154
|
-
email: typeof
|
|
155
|
-
emailVerified: typeof
|
|
156
|
-
displayName: typeof
|
|
157
|
-
photoURL: typeof
|
|
158
|
-
isStaff:
|
|
159
|
-
isCustomer:
|
|
160
|
-
tenantId: typeof
|
|
161
|
-
...
|
|
122
|
+
uid: a.sub,
|
|
123
|
+
email: typeof a.email == "string" ? a.email : "",
|
|
124
|
+
emailVerified: typeof a.email_verified == "boolean" ? a.email_verified : void 0,
|
|
125
|
+
displayName: typeof a.name == "string" ? a.name : void 0,
|
|
126
|
+
photoURL: typeof a.picture == "string" ? a.picture : void 0,
|
|
127
|
+
isStaff: a.is_staff === !0,
|
|
128
|
+
isCustomer: a.is_customer === !0,
|
|
129
|
+
tenantId: typeof a.tenant_id == "string" ? a.tenant_id : void 0,
|
|
130
|
+
...a
|
|
162
131
|
};
|
|
163
|
-
}
|
|
164
132
|
}
|
|
165
133
|
} catch {
|
|
166
134
|
}
|
|
167
135
|
if (this._user) return this._user;
|
|
168
|
-
throw new
|
|
136
|
+
throw new l("token_invalid_signature", "Nenhum user mock dispon\xEDvel e JWT sem sub v\xE1lido");
|
|
169
137
|
}
|
|
170
138
|
/**
|
|
171
139
|
* Mock de `handleRedirectCallback` (Bug 2 / 3.1.3) — não há redirect real no
|
|
172
140
|
* mock, então retorna `null` por default. Use `__setPendingCallback(result)`
|
|
173
141
|
* em testes pra simular um retorno do IdP.
|
|
174
142
|
*/
|
|
175
|
-
async handleRedirectCallback(
|
|
143
|
+
async handleRedirectCallback(e) {
|
|
176
144
|
return this._pendingCallback;
|
|
177
145
|
}
|
|
178
146
|
/**
|
|
@@ -181,7 +149,7 @@ var MockAuth = class {
|
|
|
181
149
|
* contrato "no-op seguro em todo page load" da implementação real). O login
|
|
182
150
|
* mock acontece direto via `signIn()`.
|
|
183
151
|
*/
|
|
184
|
-
async completeSignIn(
|
|
152
|
+
async completeSignIn(e) {
|
|
185
153
|
return null;
|
|
186
154
|
}
|
|
187
155
|
/**
|
|
@@ -194,12 +162,12 @@ var MockAuth = class {
|
|
|
194
162
|
_pendingCallback = null;
|
|
195
163
|
_idToken = null;
|
|
196
164
|
/** Test helper — simula o material devolvido por um callback OIDC. */
|
|
197
|
-
__setPendingCallback(
|
|
198
|
-
this._pendingCallback =
|
|
165
|
+
__setPendingCallback(e) {
|
|
166
|
+
this._pendingCallback = e;
|
|
199
167
|
}
|
|
200
168
|
/** Test helper — injeta o id_token cru retornado por `getIdToken`. */
|
|
201
|
-
__setIdToken(
|
|
202
|
-
this._idToken =
|
|
169
|
+
__setIdToken(e) {
|
|
170
|
+
this._idToken = e;
|
|
203
171
|
}
|
|
204
172
|
_verifyTokenOverride = null;
|
|
205
173
|
/**
|
|
@@ -212,75 +180,63 @@ var MockAuth = class {
|
|
|
212
180
|
* mock.__mockVerifyToken(async () => { throw new NeetruError('token_expired', '...'); });
|
|
213
181
|
* ```
|
|
214
182
|
*/
|
|
215
|
-
__mockVerifyToken(
|
|
216
|
-
this._verifyTokenOverride =
|
|
183
|
+
__mockVerifyToken(e) {
|
|
184
|
+
this._verifyTokenOverride = e;
|
|
217
185
|
}
|
|
218
186
|
/** Helper de tests — força um user state arbitrário. */
|
|
219
|
-
__setUser(
|
|
220
|
-
this._user =
|
|
221
|
-
this._notify();
|
|
187
|
+
__setUser(e) {
|
|
188
|
+
this._user = e, this._notify();
|
|
222
189
|
}
|
|
223
190
|
_notify() {
|
|
224
|
-
for (
|
|
191
|
+
for (let e of this._listeners)
|
|
225
192
|
try {
|
|
226
|
-
|
|
193
|
+
e(this._user);
|
|
227
194
|
} catch {
|
|
228
195
|
}
|
|
229
|
-
}
|
|
230
196
|
}
|
|
231
|
-
}
|
|
232
|
-
var MockUsage = class {
|
|
197
|
+
}, T = class {
|
|
233
198
|
_reports = [];
|
|
234
199
|
_quotas;
|
|
235
200
|
_counters = /* @__PURE__ */ new Map();
|
|
236
|
-
constructor(
|
|
237
|
-
this._quotas = new Map(Object.entries(
|
|
238
|
-
}
|
|
239
|
-
async report(
|
|
240
|
-
if (!
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
qty: safeQty,
|
|
248
|
-
productId: options?.productId,
|
|
249
|
-
tenantId: options?.tenantId,
|
|
201
|
+
constructor(e = {}) {
|
|
202
|
+
this._quotas = new Map(Object.entries(e));
|
|
203
|
+
}
|
|
204
|
+
async report(e, r = 1, i) {
|
|
205
|
+
if (!e) throw new Error("resource required");
|
|
206
|
+
let o = Number.isFinite(r) && r > 0 ? Math.floor(r) : 1, c = (this._counters.get(e) ?? 0) + o;
|
|
207
|
+
this._counters.set(e, c), this._reports.push({
|
|
208
|
+
resource: e,
|
|
209
|
+
qty: o,
|
|
210
|
+
productId: i?.productId,
|
|
211
|
+
tenantId: i?.tenantId,
|
|
250
212
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
251
213
|
});
|
|
252
|
-
|
|
253
|
-
const limit = limitFixture?.limit ?? -1;
|
|
214
|
+
let d = this._quotas.get(e)?.limit ?? -1;
|
|
254
215
|
return {
|
|
255
216
|
ok: true,
|
|
256
|
-
counterId: `mock_${
|
|
257
|
-
value:
|
|
258
|
-
limit,
|
|
259
|
-
remaining:
|
|
260
|
-
status:
|
|
217
|
+
counterId: `mock_${e}`,
|
|
218
|
+
value: c,
|
|
219
|
+
limit: d,
|
|
220
|
+
remaining: d < 0 ? -1 : Math.max(0, d - c),
|
|
221
|
+
status: d > 0 && c >= d ? "read_only_overlimit" : "ok"
|
|
261
222
|
};
|
|
262
223
|
}
|
|
263
|
-
async check(
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
if (!quota) {
|
|
224
|
+
async check(e, r) {
|
|
225
|
+
let i = this._quotas.get(e), o = this._counters.get(e) ?? 0;
|
|
226
|
+
if (!i)
|
|
267
227
|
return { allowed: true, reason: "granted", limit: -1, remaining: -1, behavior: null };
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
behavior: "readonly"
|
|
277
|
-
};
|
|
278
|
-
}
|
|
279
|
-
return {
|
|
228
|
+
let a = i.limit < 0 ? -1 : Math.max(0, i.limit - o);
|
|
229
|
+
return a === 0 ? {
|
|
230
|
+
allowed: false,
|
|
231
|
+
reason: "limit_exceeded",
|
|
232
|
+
limit: i.limit,
|
|
233
|
+
remaining: 0,
|
|
234
|
+
behavior: "readonly"
|
|
235
|
+
} : {
|
|
280
236
|
allowed: true,
|
|
281
237
|
reason: "granted",
|
|
282
|
-
limit:
|
|
283
|
-
remaining,
|
|
238
|
+
limit: i.limit,
|
|
239
|
+
remaining: a,
|
|
284
240
|
behavior: null
|
|
285
241
|
};
|
|
286
242
|
}
|
|
@@ -293,40 +249,37 @@ var MockUsage = class {
|
|
|
293
249
|
return this.__getReports();
|
|
294
250
|
}
|
|
295
251
|
/** Test helper — substitui quota fixture. */
|
|
296
|
-
__setQuota(
|
|
297
|
-
this._quotas.set(
|
|
252
|
+
__setQuota(e, r) {
|
|
253
|
+
this._quotas.set(e, r);
|
|
298
254
|
}
|
|
299
255
|
/** Test helper — limpa estado. */
|
|
300
256
|
__reset() {
|
|
301
|
-
this._reports = [];
|
|
302
|
-
this._quotas.clear();
|
|
303
|
-
this._counters.clear();
|
|
257
|
+
this._reports = [], this._quotas.clear(), this._counters.clear();
|
|
304
258
|
}
|
|
305
|
-
}
|
|
306
|
-
var MockSupport = class {
|
|
259
|
+
}, P = class {
|
|
307
260
|
_tickets = [];
|
|
308
261
|
_ticketSeq = 0;
|
|
309
|
-
async createTicket(
|
|
310
|
-
if (!
|
|
311
|
-
if (!
|
|
312
|
-
if (!
|
|
313
|
-
throw new
|
|
262
|
+
async createTicket(e) {
|
|
263
|
+
if (!e?.subject) throw new l("validation_failed", "subject required");
|
|
264
|
+
if (!e?.message) throw new l("validation_failed", "message required");
|
|
265
|
+
if (!e?.productSlug)
|
|
266
|
+
throw new l(
|
|
314
267
|
"validation_failed",
|
|
315
268
|
"productSlug required (3.0 breaking \u2014 pass to input or set on createNeetruClient)"
|
|
316
269
|
);
|
|
317
|
-
|
|
318
|
-
const ticket = {
|
|
270
|
+
let r = {
|
|
319
271
|
id: `mock-ticket-${++this._ticketSeq}`,
|
|
320
|
-
subject:
|
|
321
|
-
message:
|
|
322
|
-
severity:
|
|
272
|
+
subject: e.subject,
|
|
273
|
+
message: e.message,
|
|
274
|
+
severity: e.severity ?? "normal",
|
|
323
275
|
status: "open",
|
|
324
276
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
325
|
-
productSlug:
|
|
277
|
+
productSlug: e.productSlug,
|
|
326
278
|
// 3.4 (product-feedback): espelha o contrato — campos novos nullable,
|
|
327
279
|
// populados a partir do input quando fornecidos.
|
|
328
|
-
pageUrl: typeof
|
|
329
|
-
screenshotUrl: typeof
|
|
280
|
+
pageUrl: typeof e.pageUrl == "string" ? e.pageUrl : null,
|
|
281
|
+
screenshotUrl: typeof e.screenshotBase64 == "string" ? e.screenshotBase64 : null,
|
|
282
|
+
screenshotAttached: typeof e.screenshotBase64 == "string",
|
|
330
283
|
resolvedAt: null,
|
|
331
284
|
resolvedNotifiedAt: null,
|
|
332
285
|
satisfactionAttempts: 0,
|
|
@@ -335,146 +288,116 @@ var MockSupport = class {
|
|
|
335
288
|
rating: null,
|
|
336
289
|
satisfactionComment: null
|
|
337
290
|
};
|
|
338
|
-
this._tickets.push(
|
|
339
|
-
return ticket;
|
|
291
|
+
return this._tickets.push(r), r;
|
|
340
292
|
}
|
|
341
|
-
async listMyTickets(
|
|
342
|
-
|
|
343
|
-
return this._tickets.filter((t) => t.productSlug === options.productSlug);
|
|
344
|
-
}
|
|
345
|
-
return [...this._tickets];
|
|
293
|
+
async listMyTickets(e) {
|
|
294
|
+
return e?.productSlug ? this._tickets.filter((r) => r.productSlug === e.productSlug) : [...this._tickets];
|
|
346
295
|
}
|
|
347
|
-
_find(
|
|
348
|
-
if (!
|
|
349
|
-
throw new
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
}
|
|
355
|
-
return ticket;
|
|
296
|
+
_find(e) {
|
|
297
|
+
if (!e || typeof e != "string")
|
|
298
|
+
throw new l("validation_failed", "ticketId is required");
|
|
299
|
+
let r = this._tickets.find((i) => i.id === e);
|
|
300
|
+
if (!r)
|
|
301
|
+
throw new l("not_found", `ticket ${e} not found`);
|
|
302
|
+
return r;
|
|
356
303
|
}
|
|
357
304
|
/** 3.4: espelha `markResolvedSeen` — idempotente (só seta se ainda null). */
|
|
358
|
-
async markResolvedSeen(
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
ticket.resolvedNotifiedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
362
|
-
}
|
|
305
|
+
async markResolvedSeen(e) {
|
|
306
|
+
let r = this._find(e);
|
|
307
|
+
r.resolvedNotifiedAt === null && (r.resolvedNotifiedAt = (/* @__PURE__ */ new Date()).toISOString());
|
|
363
308
|
}
|
|
364
309
|
/** 3.4: espelha `recordSatisfactionAttempt` — incrementa contador. */
|
|
365
|
-
async recordSatisfactionAttempt(
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
ticket.lastSatisfactionAttemptAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
310
|
+
async recordSatisfactionAttempt(e) {
|
|
311
|
+
let r = this._find(e);
|
|
312
|
+
r.satisfactionAttempts += 1, r.lastSatisfactionAttemptAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
369
313
|
}
|
|
370
314
|
/** 3.4: espelha `submitSatisfaction` — terminal, seta `satisfiedAt`. */
|
|
371
|
-
async submitSatisfaction(
|
|
372
|
-
if (!
|
|
373
|
-
throw new
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
if (typeof input.comment === "string" && input.comment.length > 2e3) {
|
|
381
|
-
throw new NeetruError("validation_failed", "comment max 2000 chars");
|
|
382
|
-
}
|
|
383
|
-
const ticket = this._find(input.ticketId);
|
|
384
|
-
ticket.satisfiedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
385
|
-
ticket.rating = input.rating ?? null;
|
|
386
|
-
ticket.satisfactionComment = input.comment ?? null;
|
|
315
|
+
async submitSatisfaction(e) {
|
|
316
|
+
if (!e || typeof e != "object")
|
|
317
|
+
throw new l("validation_failed", "input is required");
|
|
318
|
+
if (e.rating !== null && e.rating !== void 0 && (!Number.isInteger(e.rating) || e.rating < 1 || e.rating > 5))
|
|
319
|
+
throw new l("validation_failed", "rating must be an integer 1-5 or null");
|
|
320
|
+
if (typeof e.comment == "string" && e.comment.length > 2e3)
|
|
321
|
+
throw new l("validation_failed", "comment max 2000 chars");
|
|
322
|
+
let r = this._find(e.ticketId);
|
|
323
|
+
r.satisfiedAt = (/* @__PURE__ */ new Date()).toISOString(), r.rating = e.rating ?? null, r.satisfactionComment = e.comment ?? null;
|
|
387
324
|
}
|
|
388
325
|
/** 3.4: espelha `contestTicket` — reabre e zera o ciclo de satisfação. */
|
|
389
|
-
async contestTicket(
|
|
390
|
-
if (typeof
|
|
391
|
-
throw new
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
ticket.status = "open";
|
|
395
|
-
ticket.resolvedAt = null;
|
|
396
|
-
ticket.resolvedNotifiedAt = null;
|
|
397
|
-
ticket.satisfactionAttempts = 0;
|
|
398
|
-
ticket.lastSatisfactionAttemptAt = null;
|
|
399
|
-
ticket.satisfiedAt = null;
|
|
400
|
-
ticket.rating = null;
|
|
401
|
-
ticket.satisfactionComment = null;
|
|
326
|
+
async contestTicket(e, r) {
|
|
327
|
+
if (typeof r?.comment == "string" && r.comment.length > 2e3)
|
|
328
|
+
throw new l("validation_failed", "comment max 2000 chars");
|
|
329
|
+
let i = this._find(e);
|
|
330
|
+
i.status = "open", i.resolvedAt = null, i.resolvedNotifiedAt = null, i.satisfactionAttempts = 0, i.lastSatisfactionAttemptAt = null, i.satisfiedAt = null, i.rating = null, i.satisfactionComment = null;
|
|
402
331
|
}
|
|
403
332
|
/** Test helper. */
|
|
404
333
|
__reset() {
|
|
405
|
-
this._tickets = [];
|
|
406
|
-
this._ticketSeq = 0;
|
|
334
|
+
this._tickets = [], this._ticketSeq = 0;
|
|
407
335
|
}
|
|
408
|
-
}
|
|
409
|
-
var MockEntitlements = class {
|
|
336
|
+
}, D = class {
|
|
410
337
|
_denied = /* @__PURE__ */ new Set();
|
|
411
|
-
async check(
|
|
412
|
-
return !this._denied.has(`${
|
|
338
|
+
async check(e, r) {
|
|
339
|
+
return !this._denied.has(`${e}:${r}`);
|
|
413
340
|
}
|
|
414
|
-
async checkDetailed(
|
|
415
|
-
|
|
341
|
+
async checkDetailed(e, r) {
|
|
342
|
+
let i = await this.check(e, r);
|
|
416
343
|
return {
|
|
417
|
-
allowed,
|
|
418
|
-
productSlug,
|
|
419
|
-
feature,
|
|
420
|
-
reason:
|
|
344
|
+
allowed: i,
|
|
345
|
+
productSlug: e,
|
|
346
|
+
feature: r,
|
|
347
|
+
reason: i ? "granted" : "mock_denied"
|
|
421
348
|
};
|
|
422
349
|
}
|
|
423
350
|
/** Test helper. */
|
|
424
|
-
__deny(
|
|
425
|
-
this._denied.add(`${
|
|
351
|
+
__deny(e, r) {
|
|
352
|
+
this._denied.add(`${e}:${r}`);
|
|
426
353
|
}
|
|
427
354
|
/** Test helper. */
|
|
428
355
|
__reset() {
|
|
429
356
|
this._denied.clear();
|
|
430
357
|
}
|
|
431
|
-
}
|
|
432
|
-
var MockDb = class {
|
|
358
|
+
}, C = class {
|
|
433
359
|
_store = /* @__PURE__ */ new Map();
|
|
434
360
|
_fixtures;
|
|
435
|
-
constructor(
|
|
436
|
-
this._fixtures = new Map(Object.entries(
|
|
437
|
-
}
|
|
438
|
-
collection(
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
init ? new Map(Object.entries(init)) : /* @__PURE__ */ new Map()
|
|
361
|
+
constructor(e = {}) {
|
|
362
|
+
this._fixtures = new Map(Object.entries(e));
|
|
363
|
+
}
|
|
364
|
+
collection(e) {
|
|
365
|
+
let r = this._store, i = this._fixtures;
|
|
366
|
+
if (!r.has(e)) {
|
|
367
|
+
let s = i.get(e);
|
|
368
|
+
r.set(
|
|
369
|
+
e,
|
|
370
|
+
s ? new Map(Object.entries(s)) : /* @__PURE__ */ new Map()
|
|
446
371
|
);
|
|
447
372
|
}
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
switch (f.op) {
|
|
373
|
+
let o = r.get(e), a = (s, t) => {
|
|
374
|
+
let n = s[t.field];
|
|
375
|
+
switch (t.op) {
|
|
452
376
|
case "==":
|
|
453
|
-
return
|
|
377
|
+
return n === t.value;
|
|
454
378
|
case "!=":
|
|
455
|
-
return
|
|
379
|
+
return n !== t.value;
|
|
456
380
|
case "<":
|
|
457
|
-
return typeof
|
|
381
|
+
return typeof n == "number" && typeof t.value == "number" && n < t.value;
|
|
458
382
|
case "<=":
|
|
459
|
-
return typeof
|
|
383
|
+
return typeof n == "number" && typeof t.value == "number" && n <= t.value;
|
|
460
384
|
case ">":
|
|
461
|
-
return typeof
|
|
385
|
+
return typeof n == "number" && typeof t.value == "number" && n > t.value;
|
|
462
386
|
case ">=":
|
|
463
|
-
return typeof
|
|
387
|
+
return typeof n == "number" && typeof t.value == "number" && n >= t.value;
|
|
464
388
|
case "in":
|
|
465
|
-
return Array.isArray(
|
|
389
|
+
return Array.isArray(t.value) && t.value.includes(n);
|
|
466
390
|
case "array-contains":
|
|
467
|
-
return Array.isArray(
|
|
391
|
+
return Array.isArray(n) && n.includes(t.value);
|
|
468
392
|
case "not-in":
|
|
469
|
-
return Array.isArray(
|
|
393
|
+
return Array.isArray(t.value) && !t.value.includes(n);
|
|
470
394
|
default:
|
|
471
395
|
return true;
|
|
472
396
|
}
|
|
473
|
-
};
|
|
474
|
-
|
|
475
|
-
function buildListResult(items) {
|
|
397
|
+
}, c = 0;
|
|
398
|
+
function y(s) {
|
|
476
399
|
return {
|
|
477
|
-
docs:
|
|
400
|
+
docs: s.map((t, n) => ({ id: t.id ?? String(n), data: t })),
|
|
478
401
|
nextCursor: null,
|
|
479
402
|
fromCache: false,
|
|
480
403
|
stale: false,
|
|
@@ -482,141 +405,111 @@ var MockDb = class {
|
|
|
482
405
|
changes: []
|
|
483
406
|
};
|
|
484
407
|
}
|
|
485
|
-
function
|
|
408
|
+
function d(s, t) {
|
|
486
409
|
return {
|
|
487
|
-
docs: [{ id, data }],
|
|
410
|
+
docs: [{ id: t, data: s }],
|
|
488
411
|
fromCache: false,
|
|
489
412
|
stale: false,
|
|
490
413
|
hasPendingWrites: false,
|
|
491
414
|
changes: []
|
|
492
415
|
};
|
|
493
416
|
}
|
|
494
|
-
|
|
495
|
-
async list(
|
|
496
|
-
let
|
|
497
|
-
if (
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
items = items.slice().sort((a, b) => {
|
|
505
|
-
const av = a[field];
|
|
506
|
-
const bv = b[field];
|
|
507
|
-
const avs = av ?? "";
|
|
508
|
-
const bvs = bv ?? "";
|
|
509
|
-
const cmp = avs < bvs ? -1 : avs > bvs ? 1 : 0;
|
|
510
|
-
return direction === "desc" ? -cmp : cmp;
|
|
417
|
+
let f = {
|
|
418
|
+
async list(s) {
|
|
419
|
+
let t = Array.from(o.values());
|
|
420
|
+
if (s?.where && s.where.length > 0 && (t = t.filter(
|
|
421
|
+
(u) => s.where.every((g) => a(u, g))
|
|
422
|
+
)), s?.orderBy) {
|
|
423
|
+
let { field: u, direction: g } = s.orderBy;
|
|
424
|
+
t = t.slice().sort((p, b) => {
|
|
425
|
+
let h = p[u], v = b[u], k = h ?? "", w = v ?? "", S = k < w ? -1 : k > w ? 1 : 0;
|
|
426
|
+
return g === "desc" ? -S : S;
|
|
511
427
|
});
|
|
512
428
|
}
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
return buildListResult(items);
|
|
429
|
+
let n = s?.limit ?? 20;
|
|
430
|
+
return t = t.slice(0, n), y(t);
|
|
516
431
|
},
|
|
517
|
-
async get(
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
return buildGetResult(data, id);
|
|
432
|
+
async get(s) {
|
|
433
|
+
let t = o.get(s);
|
|
434
|
+
return t ? d(t, s) : null;
|
|
521
435
|
},
|
|
522
|
-
async add(
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
return { ok: true, id };
|
|
436
|
+
async add(s) {
|
|
437
|
+
let t = `mock-${++c}-${Math.random().toString(36).slice(2, 8)}`;
|
|
438
|
+
return o.set(t, { ...s, id: t }), { ok: true, id: t };
|
|
526
439
|
},
|
|
527
|
-
async set(
|
|
528
|
-
|
|
529
|
-
return { ok: true };
|
|
440
|
+
async set(s, t) {
|
|
441
|
+
return o.set(s, { ...t, id: s }), { ok: true };
|
|
530
442
|
},
|
|
531
|
-
async update(
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
coll.set(id, { ...data, id });
|
|
535
|
-
} else {
|
|
536
|
-
coll.set(id, { ...cur, ...data });
|
|
537
|
-
}
|
|
538
|
-
return { ok: true };
|
|
443
|
+
async update(s, t) {
|
|
444
|
+
let n = o.get(s);
|
|
445
|
+
return n ? o.set(s, { ...n, ...t }) : o.set(s, { ...t, id: s }), { ok: true };
|
|
539
446
|
},
|
|
540
|
-
async remove(
|
|
541
|
-
|
|
542
|
-
return { ok: true };
|
|
447
|
+
async remove(s) {
|
|
448
|
+
return o.delete(s), { ok: true };
|
|
543
449
|
},
|
|
544
|
-
async batch(
|
|
545
|
-
for (
|
|
546
|
-
|
|
547
|
-
if (
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
} else if (
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
} else
|
|
556
|
-
collMap.delete(op.id);
|
|
557
|
-
}
|
|
450
|
+
async batch(s) {
|
|
451
|
+
for (let t of s) {
|
|
452
|
+
let n = o;
|
|
453
|
+
if (t.kind === "add") {
|
|
454
|
+
let u = `mock-batch-${++c}`;
|
|
455
|
+
n.set(u, { ...t.data, id: u });
|
|
456
|
+
} else if (t.kind === "set")
|
|
457
|
+
n.set(t.id, { ...t.data, id: t.id });
|
|
458
|
+
else if (t.kind === "update") {
|
|
459
|
+
let u = n.get(t.id);
|
|
460
|
+
n.set(t.id, { ...u ?? {}, ...t.data, id: t.id });
|
|
461
|
+
} else t.kind === "remove" && n.delete(t.id);
|
|
558
462
|
}
|
|
559
463
|
return { ok: true };
|
|
560
464
|
},
|
|
561
|
-
onDoc(
|
|
562
|
-
|
|
563
|
-
Promise.resolve().then(() =>
|
|
564
|
-
return () => {
|
|
465
|
+
onDoc(s, t) {
|
|
466
|
+
let n = o.get(s);
|
|
467
|
+
return Promise.resolve().then(() => t(n || null)), () => {
|
|
565
468
|
};
|
|
566
469
|
},
|
|
567
|
-
onSnapshot(
|
|
568
|
-
Promise.resolve().then(async () => {
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
})
|
|
572
|
-
return () => {
|
|
470
|
+
onSnapshot(s, t) {
|
|
471
|
+
return Promise.resolve().then(async () => {
|
|
472
|
+
let n = await f.list(s);
|
|
473
|
+
t(n);
|
|
474
|
+
}), () => {
|
|
573
475
|
};
|
|
574
476
|
},
|
|
575
|
-
doc(
|
|
477
|
+
doc(s) {
|
|
576
478
|
return {
|
|
577
479
|
get id() {
|
|
578
|
-
return
|
|
480
|
+
return s;
|
|
579
481
|
},
|
|
580
482
|
get path() {
|
|
581
|
-
return `${
|
|
483
|
+
return `${e}/${s}`;
|
|
582
484
|
},
|
|
583
485
|
get collection() {
|
|
584
|
-
return
|
|
486
|
+
return e;
|
|
585
487
|
},
|
|
586
488
|
async get() {
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
return buildGetResult(data, id);
|
|
489
|
+
let t = o.get(s);
|
|
490
|
+
return t ? d(t, s) : null;
|
|
590
491
|
},
|
|
591
|
-
async set(
|
|
592
|
-
|
|
593
|
-
return { ok: true };
|
|
492
|
+
async set(t) {
|
|
493
|
+
return o.set(s, { ...t, id: s }), { ok: true };
|
|
594
494
|
},
|
|
595
|
-
async update(
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
coll.set(id, { ...data, id });
|
|
599
|
-
} else {
|
|
600
|
-
coll.set(id, { ...cur, ...data });
|
|
601
|
-
}
|
|
602
|
-
return { ok: true };
|
|
495
|
+
async update(t) {
|
|
496
|
+
let n = o.get(s);
|
|
497
|
+
return n ? o.set(s, { ...n, ...t }) : o.set(s, { ...t, id: s }), { ok: true };
|
|
603
498
|
},
|
|
604
499
|
async remove() {
|
|
605
|
-
|
|
606
|
-
return { ok: true };
|
|
500
|
+
return o.delete(s), { ok: true };
|
|
607
501
|
},
|
|
608
|
-
onSnapshot(
|
|
609
|
-
|
|
610
|
-
Promise.resolve().then(
|
|
611
|
-
() =>
|
|
612
|
-
)
|
|
613
|
-
return () => {
|
|
502
|
+
onSnapshot(t) {
|
|
503
|
+
let n = o.get(s);
|
|
504
|
+
return Promise.resolve().then(
|
|
505
|
+
() => t(n ? d(n, s) : null)
|
|
506
|
+
), () => {
|
|
614
507
|
};
|
|
615
508
|
}
|
|
616
509
|
};
|
|
617
510
|
}
|
|
618
511
|
};
|
|
619
|
-
return
|
|
512
|
+
return f;
|
|
620
513
|
}
|
|
621
514
|
/**
|
|
622
515
|
* Implementa SQL in-memory para testes — preferência: `@electric-sql/pglite`
|
|
@@ -637,80 +530,66 @@ var MockDb = class {
|
|
|
637
530
|
*
|
|
638
531
|
* Use `options.initSql` pra rodar DDL no setup (CREATE TABLE etc).
|
|
639
532
|
*/
|
|
640
|
-
async sql(
|
|
641
|
-
|
|
533
|
+
async sql(e, r) {
|
|
534
|
+
let i = r?.initSql ? Array.isArray(r.initSql) ? r.initSql : [r.initSql] : [];
|
|
642
535
|
try {
|
|
643
|
-
|
|
536
|
+
let n = await import(
|
|
644
537
|
/* webpackIgnore: true */
|
|
645
538
|
'@electric-sql/pglite'
|
|
646
|
-
)
|
|
647
|
-
const drizzlePglitePkg = await import(
|
|
539
|
+
), u = await import(
|
|
648
540
|
/* webpackIgnore: true */
|
|
649
541
|
'drizzle-orm/pglite'
|
|
650
|
-
);
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
}
|
|
655
|
-
const pgliteOrm = drizzlePglitePkg.drizzle(pglite, { schema });
|
|
656
|
-
const ormAsNode = pgliteOrm;
|
|
542
|
+
), g = await n.PGlite.create();
|
|
543
|
+
for (let h of i)
|
|
544
|
+
await g.query(h);
|
|
545
|
+
let p = u.drizzle(g, { schema: e });
|
|
657
546
|
return {
|
|
658
|
-
orm:
|
|
659
|
-
async transaction(
|
|
660
|
-
return await
|
|
547
|
+
orm: p,
|
|
548
|
+
async transaction(h, v) {
|
|
549
|
+
return await p.transaction(h);
|
|
661
550
|
},
|
|
662
551
|
async close() {
|
|
663
|
-
|
|
552
|
+
g.closed || await g.close();
|
|
664
553
|
}
|
|
665
554
|
};
|
|
666
|
-
} catch
|
|
555
|
+
} catch {
|
|
667
556
|
}
|
|
668
|
-
let
|
|
669
|
-
let drizzlePg;
|
|
557
|
+
let o, a;
|
|
670
558
|
try {
|
|
671
|
-
|
|
559
|
+
o = await import(
|
|
672
560
|
/* webpackIgnore: true */
|
|
673
561
|
'pg-mem'
|
|
674
|
-
)
|
|
675
|
-
drizzlePg = await import(
|
|
562
|
+
), a = await import(
|
|
676
563
|
/* webpackIgnore: true */
|
|
677
564
|
'drizzle-orm/node-postgres'
|
|
678
565
|
);
|
|
679
566
|
} catch {
|
|
680
|
-
throw new
|
|
567
|
+
throw new _(
|
|
681
568
|
"db_unavailable",
|
|
682
569
|
"[MockDb] sql() requer @electric-sql/pglite OU pg-mem + drizzle-orm + pg como devDependencies. Preferido: npm install -D @electric-sql/pglite drizzle-orm. Alternativo: npm install -D pg-mem drizzle-orm pg."
|
|
683
570
|
);
|
|
684
571
|
}
|
|
685
|
-
|
|
686
|
-
if (
|
|
687
|
-
for (
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
const origQuery = pool.query.bind(pool);
|
|
695
|
-
pool.query = (q, ...rest) => {
|
|
696
|
-
if (q !== null && typeof q === "object") {
|
|
697
|
-
const queryObj = q;
|
|
698
|
-
const types = queryObj["types"];
|
|
699
|
-
if (types !== null && typeof types === "object" && "getTypeParser" in types) {
|
|
700
|
-
delete types["getTypeParser"];
|
|
701
|
-
}
|
|
572
|
+
let c = o.newDb({ noAstCoverageCheck: true });
|
|
573
|
+
if (i.length > 0)
|
|
574
|
+
for (let n of i)
|
|
575
|
+
c.public.none(n);
|
|
576
|
+
let d = c.adapters.createPg().Pool, f = new d(), s = f.query.bind(f);
|
|
577
|
+
f.query = (n, ...u) => {
|
|
578
|
+
if (n !== null && typeof n == "object") {
|
|
579
|
+
let p = n.types;
|
|
580
|
+
p !== null && typeof p == "object" && "getTypeParser" in p && delete p.getTypeParser;
|
|
702
581
|
}
|
|
703
|
-
return
|
|
582
|
+
return s(n, ...u);
|
|
704
583
|
};
|
|
705
|
-
|
|
584
|
+
let t = a.drizzle(f, { schema: e });
|
|
706
585
|
return {
|
|
707
|
-
orm,
|
|
708
|
-
async transaction(
|
|
709
|
-
return await
|
|
586
|
+
orm: t,
|
|
587
|
+
async transaction(n, u) {
|
|
588
|
+
return await t.transaction(n);
|
|
710
589
|
},
|
|
711
590
|
async close() {
|
|
712
|
-
|
|
713
|
-
|
|
591
|
+
let n = f;
|
|
592
|
+
n.end && await n.end();
|
|
714
593
|
}
|
|
715
594
|
};
|
|
716
595
|
}
|
|
@@ -722,7 +601,7 @@ var MockDb = class {
|
|
|
722
601
|
isLeaderTab: true
|
|
723
602
|
};
|
|
724
603
|
}
|
|
725
|
-
onSyncStateChanged(
|
|
604
|
+
onSyncStateChanged(e) {
|
|
726
605
|
return () => {
|
|
727
606
|
};
|
|
728
607
|
}
|
|
@@ -735,65 +614,53 @@ var MockDb = class {
|
|
|
735
614
|
return [];
|
|
736
615
|
}
|
|
737
616
|
/** Test helper — substitui fixture inteira de uma collection. */
|
|
738
|
-
__setFixture(
|
|
739
|
-
this._store.set(
|
|
617
|
+
__setFixture(e, r) {
|
|
618
|
+
this._store.set(e, new Map(Object.entries(r)));
|
|
740
619
|
}
|
|
741
620
|
/** Test helper — reset total. */
|
|
742
621
|
__reset() {
|
|
743
622
|
this._store.clear();
|
|
744
623
|
}
|
|
745
|
-
}
|
|
746
|
-
var MockAi = class {
|
|
624
|
+
}, N = class {
|
|
747
625
|
_calls = [];
|
|
748
626
|
/** Extrai texto de um content string OU array multimodal (imagens ignoradas). */
|
|
749
|
-
_contentToText(
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
if (!Array.isArray(opts.messages) || opts.messages.length === 0) {
|
|
764
|
-
throw new NeetruError("validation_failed", "ai: messages must be a non-empty array");
|
|
765
|
-
}
|
|
766
|
-
this._calls.push({ model: opts.model, messages: opts.messages, stream: false });
|
|
767
|
-
const text = this._reply(opts);
|
|
768
|
-
const promptTokens = opts.messages.reduce((n, m) => n + this._contentToText(m.content).length, 0);
|
|
769
|
-
const completionTokens = text.length;
|
|
627
|
+
_contentToText(e) {
|
|
628
|
+
return typeof e == "string" ? e : Array.isArray(e) ? e.filter((r) => !!r && r.type === "text").map((r) => r.text).join(" ") : "";
|
|
629
|
+
}
|
|
630
|
+
_reply(e) {
|
|
631
|
+
let r = [...e.messages].reverse().find((o) => o.role === "user") ?? e.messages[e.messages.length - 1], i = this._contentToText(r?.content);
|
|
632
|
+
return i ? `mock-reply: ${i}` : "mock-reply";
|
|
633
|
+
}
|
|
634
|
+
async chat(e) {
|
|
635
|
+
if (!e || typeof e.model != "string" || e.model.length === 0)
|
|
636
|
+
throw new l("validation_failed", "ai: model is required");
|
|
637
|
+
if (!Array.isArray(e.messages) || e.messages.length === 0)
|
|
638
|
+
throw new l("validation_failed", "ai: messages must be a non-empty array");
|
|
639
|
+
this._calls.push({ model: e.model, messages: e.messages, stream: false });
|
|
640
|
+
let r = this._reply(e), i = e.messages.reduce((a, c) => a + this._contentToText(c.content).length, 0), o = r.length;
|
|
770
641
|
return {
|
|
771
|
-
choices: [{ message: { role: "assistant", content:
|
|
642
|
+
choices: [{ message: { role: "assistant", content: r }, finish_reason: "stop" }],
|
|
772
643
|
usage: {
|
|
773
|
-
prompt_tokens:
|
|
774
|
-
completion_tokens:
|
|
775
|
-
total_tokens:
|
|
644
|
+
prompt_tokens: i,
|
|
645
|
+
completion_tokens: o,
|
|
646
|
+
total_tokens: i + o
|
|
776
647
|
},
|
|
777
|
-
model:
|
|
648
|
+
model: e.model,
|
|
778
649
|
provider: "mock",
|
|
779
650
|
usageWarning: false
|
|
780
651
|
};
|
|
781
652
|
}
|
|
782
|
-
stream(
|
|
783
|
-
if (!
|
|
784
|
-
throw new
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
const parts = text.match(/\S+\s*/g) ?? [text];
|
|
792
|
-
const meta = Promise.resolve({ provider: "mock", usageWarning: false });
|
|
793
|
-
async function* iterate() {
|
|
794
|
-
for (const p of parts) yield p;
|
|
653
|
+
stream(e) {
|
|
654
|
+
if (!e || typeof e.model != "string" || e.model.length === 0)
|
|
655
|
+
throw new l("validation_failed", "ai: model is required");
|
|
656
|
+
if (!Array.isArray(e.messages) || e.messages.length === 0)
|
|
657
|
+
throw new l("validation_failed", "ai: messages must be a non-empty array");
|
|
658
|
+
this._calls.push({ model: e.model, messages: e.messages, stream: true });
|
|
659
|
+
let r = this._reply(e), i = r.match(/\S+\s*/g) ?? [r], o = Promise.resolve({ provider: "mock", usageWarning: false });
|
|
660
|
+
async function* a() {
|
|
661
|
+
for (let c of i) yield c;
|
|
795
662
|
}
|
|
796
|
-
return { meta, [Symbol.asyncIterator]:
|
|
663
|
+
return { meta: o, [Symbol.asyncIterator]: a };
|
|
797
664
|
}
|
|
798
665
|
/** Test helper — histórico de chamadas. */
|
|
799
666
|
__getCalls() {
|
|
@@ -801,6 +668,4 @@ var MockAi = class {
|
|
|
801
668
|
}
|
|
802
669
|
};
|
|
803
670
|
|
|
804
|
-
export { DEV_FIXTURE_USER, MockAi, MockAuth, MockDb, MockEntitlements, MockSupport, MockUsage };
|
|
805
|
-
//# sourceMappingURL=mocks.mjs.map
|
|
806
|
-
//# sourceMappingURL=mocks.mjs.map
|
|
671
|
+
export { x as DEV_FIXTURE_USER, N as MockAi, A as MockAuth, C as MockDb, D as MockEntitlements, P as MockSupport, T as MockUsage };
|