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