@neetru/sdk 3.8.0 → 3.9.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 +53 -0
- package/README.md +4 -1
- package/dist/ai.cjs +1 -1
- package/dist/ai.d.cts +1 -1
- package/dist/ai.d.ts +1 -1
- package/dist/ai.mjs +1 -1
- package/dist/auth.cjs +1171 -1110
- package/dist/auth.d.cts +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/auth.mjs +1168 -1107
- package/dist/catalog.cjs +1 -1
- package/dist/catalog.d.cts +1 -1
- package/dist/catalog.d.ts +1 -1
- package/dist/catalog.mjs +1 -1
- package/dist/checkout.cjs +62 -49
- package/dist/checkout.d.cts +1 -1
- package/dist/checkout.d.ts +1 -1
- package/dist/checkout.mjs +62 -49
- package/dist/db-react.d.cts +1 -1
- package/dist/db-react.d.ts +1 -1
- package/dist/db.cjs +303 -270
- package/dist/db.d.cts +1 -1
- package/dist/db.d.ts +1 -1
- package/dist/db.mjs +322 -289
- 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 +1275 -1214
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +1390 -1329
- package/dist/mobile.cjs +328 -276
- package/dist/mobile.d.cts +12 -2
- package/dist/mobile.d.ts +12 -2
- package/dist/mobile.mjs +328 -276
- package/dist/mocks.cjs +5 -5
- package/dist/mocks.d.cts +2 -2
- package/dist/mocks.d.ts +2 -2
- package/dist/mocks.mjs +4 -4
- package/dist/notifications.cjs +1 -1
- package/dist/notifications.d.cts +1 -1
- package/dist/notifications.d.ts +1 -1
- package/dist/notifications.mjs +1 -1
- package/dist/react.cjs +119 -119
- package/dist/react.d.cts +8 -2
- package/dist/react.d.ts +8 -2
- package/dist/react.mjs +119 -119
- package/dist/support.cjs +1 -1
- package/dist/support.d.cts +1 -1
- package/dist/support.d.ts +1 -1
- package/dist/support.mjs +1 -1
- package/dist/telemetry.cjs +62 -49
- package/dist/telemetry.d.cts +1 -1
- package/dist/telemetry.d.ts +1 -1
- package/dist/telemetry.mjs +62 -49
- package/dist/{types-D-9bjlM0.d.cts → types-Bl_4HROd.d.cts} +118 -19
- package/dist/{types-bVztFQTI.d.ts → types-Bqnsqvow.d.ts} +118 -19
- package/dist/usage.cjs +1 -1
- package/dist/usage.d.cts +1 -1
- package/dist/usage.d.ts +1 -1
- package/dist/usage.mjs +1 -1
- package/dist/webhooks.cjs +1 -1
- package/dist/webhooks.d.cts +1 -1
- package/dist/webhooks.d.ts +1 -1
- package/dist/webhooks.mjs +1 -1
- package/package.json +9 -1
package/dist/auth.cjs
CHANGED
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
var jose = require('jose');
|
|
4
4
|
var idb = require('idb');
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var Zn = Object.defineProperty;
|
|
7
7
|
var $ = (n, e) => () => (n && (e = n(n = 0)), e);
|
|
8
|
-
var
|
|
8
|
+
var st = (n, e) => {
|
|
9
9
|
for (var t in e)
|
|
10
|
-
|
|
10
|
+
Zn(n, t, { get: e[t], enumerable: true });
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
// src/errors.ts
|
|
14
|
-
var
|
|
15
|
-
|
|
14
|
+
var c, K, C = $(() => {
|
|
15
|
+
c = class n extends Error {
|
|
16
16
|
code;
|
|
17
17
|
status;
|
|
18
18
|
requestId;
|
|
@@ -35,7 +35,7 @@ var l, V, I = $(() => {
|
|
|
35
35
|
constructor(e, t, r, o, i, s) {
|
|
36
36
|
super(t), this.name = "NeetruError", this.code = e, this.status = r, this.requestId = o, this.reason = i, this.correlationId = s, Object.setPrototypeOf(this, n.prototype);
|
|
37
37
|
}
|
|
38
|
-
},
|
|
38
|
+
}, K = class n extends c {
|
|
39
39
|
constructor(e, t, r, o, i) {
|
|
40
40
|
super("auth_required", e, r, o, t, i), this.name = "NeetruAuthRequiredError", Object.setPrototypeOf(this, n.prototype);
|
|
41
41
|
}
|
|
@@ -43,24 +43,24 @@ var l, V, I = $(() => {
|
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
// src/idempotency.ts
|
|
46
|
-
function
|
|
46
|
+
function yt() {
|
|
47
47
|
let n = typeof globalThis < "u" && "crypto" in globalThis ? globalThis.crypto : void 0;
|
|
48
48
|
if (n && typeof n.randomUUID == "function")
|
|
49
49
|
return n.randomUUID();
|
|
50
|
-
throw new
|
|
50
|
+
throw new c(
|
|
51
51
|
"runtime_unsupported",
|
|
52
52
|
"crypto.randomUUID not available in this runtime. SDK 3.0 requires Node \u226520 or modern browser/Edge."
|
|
53
53
|
);
|
|
54
54
|
}
|
|
55
|
-
var
|
|
56
|
-
|
|
55
|
+
var _t = $(() => {
|
|
56
|
+
C();
|
|
57
57
|
});
|
|
58
58
|
|
|
59
59
|
// src/correlation.ts
|
|
60
|
-
function
|
|
61
|
-
return typeof n == "string" && n.length > 0 && n.length <= 128 &&
|
|
60
|
+
function vt(n) {
|
|
61
|
+
return typeof n == "string" && n.length > 0 && n.length <= 128 && sr.test(n);
|
|
62
62
|
}
|
|
63
|
-
function
|
|
63
|
+
function ar() {
|
|
64
64
|
let n = globalThis.crypto;
|
|
65
65
|
try {
|
|
66
66
|
if (n && typeof n.randomUUID == "function") return n.randomUUID();
|
|
@@ -78,24 +78,24 @@ function tr() {
|
|
|
78
78
|
let r = Array.from(e, (o) => o.toString(16).padStart(2, "0")).join("");
|
|
79
79
|
return `${r.slice(0, 8)}-${r.slice(8, 12)}-${r.slice(12, 16)}-${r.slice(16, 20)}-${r.slice(20)}`;
|
|
80
80
|
}
|
|
81
|
-
function
|
|
81
|
+
function ce(n, e) {
|
|
82
82
|
let t, r = {};
|
|
83
83
|
for (let [i, s] of Object.entries(n)) {
|
|
84
|
-
if (i.toLowerCase() ===
|
|
85
|
-
|
|
84
|
+
if (i.toLowerCase() === bt) {
|
|
85
|
+
vt(s) && (t = s);
|
|
86
86
|
continue;
|
|
87
87
|
}
|
|
88
88
|
r[i] = s;
|
|
89
89
|
}
|
|
90
|
-
let o = t ?? (
|
|
91
|
-
return r[
|
|
90
|
+
let o = t ?? (vt(e) ? e : void 0) ?? ar();
|
|
91
|
+
return r[bt] = o, { headers: r, correlationId: o };
|
|
92
92
|
}
|
|
93
|
-
var
|
|
94
|
-
|
|
93
|
+
var bt, sr, qe = $(() => {
|
|
94
|
+
bt = "x-correlation-id", sr = /^[A-Za-z0-9._:\-]+$/;
|
|
95
95
|
});
|
|
96
96
|
|
|
97
97
|
// src/server-only-key.ts
|
|
98
|
-
function
|
|
98
|
+
function Y() {
|
|
99
99
|
try {
|
|
100
100
|
let n = globalThis.navigator;
|
|
101
101
|
if (n && n.product === "ReactNative") return "react-native";
|
|
@@ -108,108 +108,108 @@ function X() {
|
|
|
108
108
|
}
|
|
109
109
|
return null;
|
|
110
110
|
}
|
|
111
|
-
function
|
|
112
|
-
let t =
|
|
111
|
+
function wt(n, e) {
|
|
112
|
+
let t = cr[n];
|
|
113
113
|
return (`${e ? `[Neetru SDK] Recusado: a credencial nrt_ do produto foi passada ao SDK rodando ${t}.` : `[Neetru SDK] ATEN\xC7\xC3O: a credencial nrt_ do produto est\xE1 sendo usada ${t}.`} Essa chave \xE9 S\xD3 DE SERVIDOR \u2014 quem abrir o DevTools (ou descompactar o app) copia a chave e fala com o Core como se fosse o seu produto. Como corrigir: o site/app chama a API do SEU produto (ex.: https://<produto>.neetru.com/api/v1) com o token do usu\xE1rio (Authorization: Bearer <access_token>); o backend do produto valida com verifyAccessToken() e usa o SDK com a chave (NEETRU_API_KEY, sem prefixo NEXT_PUBLIC_/EXPO_PUBLIC_). ` + (e ? "" : "Nesta vers\xE3o \xE9 s\xF3 um aviso; use strictServerOnlyKey: true para bloquear j\xE1. Na pr\xF3xima vers\xE3o MAJOR do SDK isso passa a falhar sempre.")).trim();
|
|
114
114
|
}
|
|
115
|
-
function
|
|
115
|
+
function St(n) {
|
|
116
116
|
if (!n.hasApiKey) return;
|
|
117
|
-
let e = n.runtime === void 0 ?
|
|
117
|
+
let e = n.runtime === void 0 ? Y() : n.runtime;
|
|
118
118
|
if (e) {
|
|
119
119
|
if (n.strict)
|
|
120
|
-
throw new
|
|
121
|
-
if (!
|
|
122
|
-
|
|
120
|
+
throw new c("server_only_key", wt(e, true), void 0, void 0, e);
|
|
121
|
+
if (!kt) {
|
|
122
|
+
kt = true;
|
|
123
123
|
try {
|
|
124
|
-
typeof console < "u" && typeof console.warn == "function" && console.warn(
|
|
124
|
+
typeof console < "u" && typeof console.warn == "function" && console.warn(wt(e, !1));
|
|
125
125
|
} catch {
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
|
-
var
|
|
131
|
-
|
|
132
|
-
|
|
130
|
+
var cr, kt, Fe = $(() => {
|
|
131
|
+
C();
|
|
132
|
+
cr = {
|
|
133
133
|
browser: "no navegador",
|
|
134
134
|
"react-native": "num app React Native"
|
|
135
135
|
};
|
|
136
|
-
|
|
136
|
+
kt = false;
|
|
137
137
|
});
|
|
138
138
|
|
|
139
139
|
// src/http.ts
|
|
140
|
-
var
|
|
141
|
-
|
|
142
|
-
checkCoreVersionCompat: () =>
|
|
140
|
+
var Z = {};
|
|
141
|
+
st(Z, {
|
|
142
|
+
checkCoreVersionCompat: () => le,
|
|
143
143
|
httpRequest: () => v,
|
|
144
|
-
statusToCode: () =>
|
|
144
|
+
statusToCode: () => de
|
|
145
145
|
});
|
|
146
|
-
function
|
|
146
|
+
function je(n) {
|
|
147
147
|
return n.split("+")[0] ?? n;
|
|
148
148
|
}
|
|
149
|
-
function
|
|
150
|
-
let t =
|
|
149
|
+
function dr(n, e) {
|
|
150
|
+
let t = je(n).split(".").map(Number), r = je(e).split(".").map(Number), o = Math.max(t.length, r.length);
|
|
151
151
|
for (let i = 0; i < o; i++) {
|
|
152
152
|
let s = t[i] ?? 0, a = r[i] ?? 0;
|
|
153
153
|
if (s !== a) return s - a;
|
|
154
154
|
}
|
|
155
155
|
return 0;
|
|
156
156
|
}
|
|
157
|
-
function
|
|
157
|
+
function Et() {
|
|
158
158
|
try {
|
|
159
|
-
return "3.
|
|
159
|
+
return "3.9.0";
|
|
160
160
|
} catch {
|
|
161
161
|
return;
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
|
-
function
|
|
165
|
-
let n =
|
|
164
|
+
function ur() {
|
|
165
|
+
let n = Et();
|
|
166
166
|
return n ? parseInt(n.split(".")[0] ?? "3", 10) : 3;
|
|
167
167
|
}
|
|
168
|
-
function
|
|
168
|
+
function le(n) {
|
|
169
169
|
if (!n) return;
|
|
170
|
-
let e =
|
|
170
|
+
let e = ur(), t = lr[e];
|
|
171
171
|
if (!t) return;
|
|
172
|
-
let r =
|
|
173
|
-
if (
|
|
172
|
+
let r = je(n);
|
|
173
|
+
if (dr(r, t) < 0) {
|
|
174
174
|
let o = `${e}:${r}`;
|
|
175
|
-
|
|
175
|
+
Tt.has(o) || (Tt.add(o), console.warn(
|
|
176
176
|
`[Neetru SDK] Aten\xE7\xE3o: Core vers\xE3o "${n}" \xE9 anterior ao m\xEDnimo recomendado "${t}" para SDK major ${e}. Alguns recursos podem n\xE3o funcionar corretamente. Atualize o Core para a vers\xE3o mais recente.`
|
|
177
177
|
));
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
|
-
function
|
|
180
|
+
function pr() {
|
|
181
181
|
let n = "This operation requires an apiKey. Pass it to createNeetruClient({ apiKey }) or set NEETRU_API_KEY env var.";
|
|
182
|
-
return
|
|
182
|
+
return Y() ? "Esta opera\xE7\xE3o exige a credencial nrt_ do produto, que \xE9 S\xD3 DE SERVIDOR. No navegador/app, chame a API do seu produto (ex.: https://<produto>.neetru.com/api/v1) com o token do usu\xE1rio \u2014 o backend do produto faz esta chamada com o SDK e a chave. (" + n + ")" : n;
|
|
183
183
|
}
|
|
184
|
-
function
|
|
184
|
+
function Rt(n) {
|
|
185
185
|
let e = 200 * Math.pow(4, n), t = e * 0.2 * (Math.random() * 2 - 1);
|
|
186
186
|
return Math.max(50, Math.round(e + t));
|
|
187
187
|
}
|
|
188
|
-
function
|
|
188
|
+
function yr(n) {
|
|
189
189
|
if (!n) return null;
|
|
190
190
|
let e = Number(n);
|
|
191
|
-
if (Number.isFinite(e) && e >= 0) return Math.min(Math.round(e * 1e3),
|
|
191
|
+
if (Number.isFinite(e) && e >= 0) return Math.min(Math.round(e * 1e3), It);
|
|
192
192
|
let t = Date.parse(n);
|
|
193
193
|
if (Number.isFinite(t)) {
|
|
194
194
|
let r = t - Date.now();
|
|
195
|
-
if (r > 0) return Math.min(r,
|
|
195
|
+
if (r > 0) return Math.min(r, It);
|
|
196
196
|
}
|
|
197
197
|
return null;
|
|
198
198
|
}
|
|
199
|
-
function
|
|
199
|
+
function Ct(n) {
|
|
200
200
|
return new Promise((e) => setTimeout(e, n));
|
|
201
201
|
}
|
|
202
|
-
function
|
|
202
|
+
function de(n) {
|
|
203
203
|
return n === 401 ? "unauthorized" : n === 403 ? "forbidden" : n === 404 ? "not_found" : n === 409 ? "conflict" : n === 410 ? "gone" : n === 422 || n === 400 ? "validation_failed" : n === 429 ? "rate_limited" : n >= 500 ? "server_error" : "unknown";
|
|
204
204
|
}
|
|
205
|
-
function
|
|
205
|
+
function _r(n, e, t) {
|
|
206
206
|
let r = n.replace(/\/+$/, ""), o = e.startsWith("/") ? e : `/${e}`, i = new URL(`${r}${o}`);
|
|
207
207
|
if (t)
|
|
208
208
|
for (let [s, a] of Object.entries(t))
|
|
209
209
|
a !== void 0 && i.searchParams.set(s, String(a));
|
|
210
210
|
return i.toString();
|
|
211
211
|
}
|
|
212
|
-
async function
|
|
212
|
+
async function At(n) {
|
|
213
213
|
let e = await n.text();
|
|
214
214
|
if (e)
|
|
215
215
|
try {
|
|
@@ -219,17 +219,17 @@ async function It(n) {
|
|
|
219
219
|
}
|
|
220
220
|
}
|
|
221
221
|
async function v(n, e) {
|
|
222
|
-
let t = e.method ?? "GET", r =
|
|
222
|
+
let t = e.method ?? "GET", r = _r(n.baseUrl, e.path, e.query), o = hr.has(t) ? fr : mr, i = e.retries ?? o, { headers: s, correlationId: a } = ce(
|
|
223
223
|
{ accept: "application/json", ...e.headers },
|
|
224
224
|
e.correlationId
|
|
225
|
-
),
|
|
226
|
-
if (
|
|
225
|
+
), l = Et();
|
|
226
|
+
if (l && (s["x-neetru-sdk-version"] = l), e.requireAuth) {
|
|
227
227
|
if (!n.apiKey)
|
|
228
|
-
throw new
|
|
228
|
+
throw new c("missing_api_key", pr());
|
|
229
229
|
s.authorization = `Bearer ${n.apiKey}`;
|
|
230
230
|
}
|
|
231
231
|
if (e.idempotencyKey) {
|
|
232
|
-
let f = typeof e.idempotencyKey == "string" ? e.idempotencyKey :
|
|
232
|
+
let f = typeof e.idempotencyKey == "string" ? e.idempotencyKey : yt();
|
|
233
233
|
s["idempotency-key"] = f;
|
|
234
234
|
}
|
|
235
235
|
let d = e.body !== void 0 && t !== "GET" && t !== "DELETE" ? JSON.stringify(e.body) : void 0;
|
|
@@ -237,7 +237,7 @@ async function v(n, e) {
|
|
|
237
237
|
let u = null, p = e.deadlineMs != null ? Date.now() + e.deadlineMs : null;
|
|
238
238
|
for (let f = 0; f <= i; f++) {
|
|
239
239
|
if (p != null && Date.now() >= p)
|
|
240
|
-
throw u ?? new
|
|
240
|
+
throw u ?? new c(
|
|
241
241
|
"network_error",
|
|
242
242
|
"Deadline excedido antes de completar a request",
|
|
243
243
|
void 0,
|
|
@@ -245,77 +245,77 @@ async function v(n, e) {
|
|
|
245
245
|
void 0,
|
|
246
246
|
a
|
|
247
247
|
);
|
|
248
|
-
let
|
|
249
|
-
d !== void 0 && (
|
|
250
|
-
let
|
|
251
|
-
|
|
252
|
-
let
|
|
248
|
+
let h = { method: t, headers: s };
|
|
249
|
+
d !== void 0 && (h.body = d);
|
|
250
|
+
let y = p != null ? Math.max(1, Math.min(3e4, p - Date.now())) : 3e4;
|
|
251
|
+
h.signal = AbortSignal.timeout(y);
|
|
252
|
+
let T;
|
|
253
253
|
try {
|
|
254
|
-
|
|
255
|
-
} catch (
|
|
256
|
-
let
|
|
257
|
-
if (u = new
|
|
258
|
-
let D =
|
|
254
|
+
T = await n.fetch(r, h);
|
|
255
|
+
} catch (m) {
|
|
256
|
+
let S = m instanceof DOMException && m.name === "TimeoutError" ? "Network error: timeout after 30s" : `Network error: ${m instanceof Error ? m.message : "fetch failed"}`;
|
|
257
|
+
if (u = new c("network_error", S, void 0, void 0, void 0, a), f < i) {
|
|
258
|
+
let D = Rt(f);
|
|
259
259
|
if (p == null || Date.now() + D < p) {
|
|
260
|
-
await
|
|
260
|
+
await Ct(D);
|
|
261
261
|
continue;
|
|
262
262
|
}
|
|
263
263
|
}
|
|
264
264
|
throw u;
|
|
265
265
|
}
|
|
266
|
-
let x =
|
|
267
|
-
if (
|
|
268
|
-
let
|
|
269
|
-
return
|
|
266
|
+
let x = T.headers.get("x-request-id") ?? T.headers.get("x-correlation-id") ?? void 0;
|
|
267
|
+
if (T.ok) {
|
|
268
|
+
let m = T.headers.get("x-neetru-version");
|
|
269
|
+
return m && le(m), await At(T);
|
|
270
270
|
}
|
|
271
|
-
let
|
|
272
|
-
if (
|
|
273
|
-
let
|
|
274
|
-
typeof
|
|
271
|
+
let R = await At(T), E = de(T.status), j = `HTTP ${T.status}`, g;
|
|
272
|
+
if (R && typeof R == "object") {
|
|
273
|
+
let m = R.error;
|
|
274
|
+
typeof m == "string" ? j = m : m && typeof m == "object" ? (typeof m.code == "string" && (E = m.code), typeof m.message == "string" && (j = m.message), typeof m.reason == "string" && (g = m.reason)) : (typeof R.code == "string" && (E = R.code), typeof R.message == "string" && (j = R.message)), typeof R.reason == "string" && (g = R.reason);
|
|
275
275
|
}
|
|
276
|
-
if (
|
|
277
|
-
let
|
|
278
|
-
|
|
276
|
+
if (T.status === 410) {
|
|
277
|
+
let m = T.headers.get("x-neetru-replacement");
|
|
278
|
+
j === `HTTP ${T.status}` && (j = `Endpoint ${e.path} foi removido do Core (HTTP 410 Gone) \u2014 atualize o @neetru/sdk e migre para a API substituta.`), m && !j.includes(m) && (j += ` Substituto: ${m}.`);
|
|
279
279
|
}
|
|
280
|
-
let
|
|
281
|
-
if (u =
|
|
282
|
-
let
|
|
283
|
-
if (p == null || Date.now() +
|
|
284
|
-
await
|
|
280
|
+
let b = new c(E, j, T.status, x, g, a);
|
|
281
|
+
if (u = b, gr.has(E) && f < i) {
|
|
282
|
+
let S = yr(T.headers.get("retry-after")) ?? Rt(f);
|
|
283
|
+
if (p == null || Date.now() + S < p) {
|
|
284
|
+
await Ct(S);
|
|
285
285
|
continue;
|
|
286
286
|
}
|
|
287
287
|
}
|
|
288
|
-
throw
|
|
288
|
+
throw b;
|
|
289
289
|
}
|
|
290
|
-
throw u ?? new
|
|
290
|
+
throw u ?? new c("unknown", "unexpected httpRequest exit", void 0, void 0, void 0, a);
|
|
291
291
|
}
|
|
292
|
-
var
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
Me();
|
|
292
|
+
var lr, Tt, fr, mr, hr, gr, It, F = $(() => {
|
|
293
|
+
C();
|
|
294
|
+
_t();
|
|
296
295
|
qe();
|
|
297
|
-
|
|
296
|
+
Fe();
|
|
297
|
+
lr = {
|
|
298
298
|
// SDK major 3.x requer Core ≥ 2026.05.1 (suporte a X-Neetru-Version header,
|
|
299
299
|
// runTransaction write-after-read, verifyWebhookRequest, webhooks 3.0+)
|
|
300
300
|
3: "2026.05.1"
|
|
301
301
|
};
|
|
302
|
-
|
|
303
|
-
|
|
302
|
+
Tt = /* @__PURE__ */ new Set();
|
|
303
|
+
fr = 2, mr = 0, hr = /* @__PURE__ */ new Set(["GET", "HEAD"]), gr = /* @__PURE__ */ new Set([
|
|
304
304
|
"rate_limited",
|
|
305
305
|
"server_error",
|
|
306
306
|
"network_error"
|
|
307
307
|
]);
|
|
308
|
-
|
|
308
|
+
It = 6e4;
|
|
309
309
|
});
|
|
310
310
|
|
|
311
311
|
// src/db-errors.ts
|
|
312
|
-
var
|
|
313
|
-
|
|
314
|
-
|
|
312
|
+
var Dr, _, ee = $(() => {
|
|
313
|
+
C();
|
|
314
|
+
Dr = /* @__PURE__ */ new Set([
|
|
315
315
|
"db_unavailable",
|
|
316
316
|
"db_conflict",
|
|
317
317
|
"db_timeout"
|
|
318
|
-
]),
|
|
318
|
+
]), _ = class n extends c {
|
|
319
319
|
/** Código de erro fechado — específico de DB. */
|
|
320
320
|
code;
|
|
321
321
|
/**
|
|
@@ -329,16 +329,16 @@ var Rr, y, Z = $(() => {
|
|
|
329
329
|
*/
|
|
330
330
|
dbId;
|
|
331
331
|
constructor(e, t, r) {
|
|
332
|
-
super(e, t), this.name = "NeetruDbError", this.code = e, this.retryable =
|
|
332
|
+
super(e, t), this.name = "NeetruDbError", this.code = e, this.retryable = Dr.has(e), this.dbId = r, Object.setPrototypeOf(this, n.prototype);
|
|
333
333
|
}
|
|
334
334
|
};
|
|
335
335
|
});
|
|
336
336
|
|
|
337
337
|
// src/db/sql/resilient-pool.ts
|
|
338
|
-
function
|
|
339
|
-
return typeof n == "object" && n !== null && n[
|
|
338
|
+
function we(n) {
|
|
339
|
+
return typeof n == "object" && n !== null && n[Ge] === true;
|
|
340
340
|
}
|
|
341
|
-
function
|
|
341
|
+
function Zr(n) {
|
|
342
342
|
let e = n && typeof n == "object" && "code" in n ? n.code : void 0;
|
|
343
343
|
if (e === "ECONNREFUSED" || e === "ETIMEDOUT" || e === "ENOTFOUND" || e === "EHOSTUNREACH" || e === "EAI_AGAIN")
|
|
344
344
|
return true;
|
|
@@ -350,67 +350,84 @@ function Hr(n) {
|
|
|
350
350
|
let r = (n instanceof Error ? n.message : typeof n == "string" ? n : "").toLowerCase();
|
|
351
351
|
return r.length === 0 ? false : !!(r.includes("certificate expired") || r.includes("certificate has expired") || r.includes("cert_has_expired") || r.includes("alert certificate expired") || r.includes("err_ssl") || r.includes("sslv3 alert") || r.includes("tlsv1 alert") || r.includes("econnrefused") || r.includes("etimedout") || r.includes("enotfound") || r.includes("ehostunreach") || r.includes("getaddrinfo"));
|
|
352
352
|
}
|
|
353
|
-
function
|
|
353
|
+
function Xt(n) {
|
|
354
|
+
let e = n && typeof n == "object" && "code" in n ? n.code : void 0;
|
|
355
|
+
if (typeof e == "string" && eo.has(e.toUpperCase()))
|
|
356
|
+
return true;
|
|
357
|
+
let r = (n instanceof Error ? n.message : typeof n == "string" ? n : "").toLowerCase();
|
|
358
|
+
return r.length === 0 ? false : r.includes("password authentication failed") || r.includes("sasl authentication failed");
|
|
359
|
+
}
|
|
360
|
+
function to(n) {
|
|
361
|
+
return Zr(n) || Xt(n);
|
|
362
|
+
}
|
|
363
|
+
function Je(n) {
|
|
354
364
|
let e = { current: n }, t = null, r = {
|
|
355
|
-
__neetruSwapInner(
|
|
356
|
-
let
|
|
357
|
-
return e.current =
|
|
365
|
+
__neetruSwapInner(u) {
|
|
366
|
+
let p = e.current;
|
|
367
|
+
return e.current = u, p;
|
|
358
368
|
},
|
|
359
369
|
__neetruGetInner() {
|
|
360
370
|
return e.current;
|
|
361
371
|
},
|
|
362
|
-
__neetruSetReLease(
|
|
363
|
-
t =
|
|
372
|
+
__neetruSetReLease(u) {
|
|
373
|
+
t = u;
|
|
364
374
|
}
|
|
365
|
-
}, o = (
|
|
375
|
+
}, o = (u, p, f) => p[u](
|
|
376
|
+
...f
|
|
377
|
+
), i = (u, p) => (...f) => f.length > 0 && typeof f[f.length - 1] == "function" ? o(u, e.current, f) : (async () => {
|
|
366
378
|
try {
|
|
367
|
-
return await o(e.current,
|
|
368
|
-
} catch (
|
|
369
|
-
let
|
|
370
|
-
if (
|
|
371
|
-
throw
|
|
379
|
+
return await o(u, e.current, f);
|
|
380
|
+
} catch (h) {
|
|
381
|
+
let y = t;
|
|
382
|
+
if (y === null || !p(h))
|
|
383
|
+
throw h;
|
|
372
384
|
try {
|
|
373
|
-
await
|
|
385
|
+
await y();
|
|
374
386
|
} catch {
|
|
375
|
-
throw
|
|
387
|
+
throw h;
|
|
376
388
|
}
|
|
377
|
-
return await o(e.current,
|
|
389
|
+
return await o(u, e.current, f);
|
|
378
390
|
}
|
|
379
|
-
})(), s = Object.create(Object.getPrototypeOf(n));
|
|
380
|
-
return new Proxy(
|
|
381
|
-
get(
|
|
382
|
-
if (
|
|
383
|
-
if (
|
|
384
|
-
if (
|
|
385
|
-
if (
|
|
386
|
-
if (
|
|
387
|
-
if (
|
|
391
|
+
})(), s = i("query", to), a = i("connect", Xt), l = Object.create(Object.getPrototypeOf(n));
|
|
392
|
+
return new Proxy(l, {
|
|
393
|
+
get(u, p) {
|
|
394
|
+
if (p === Ge) return true;
|
|
395
|
+
if (p === "__neetruSwapInner") return r.__neetruSwapInner;
|
|
396
|
+
if (p === "__neetruGetInner") return r.__neetruGetInner;
|
|
397
|
+
if (p === "__neetruSetReLease") return r.__neetruSetReLease;
|
|
398
|
+
if (p === "query") return s;
|
|
399
|
+
if (p === "connect") {
|
|
400
|
+
let y = e.current;
|
|
401
|
+
return typeof y.connect == "function" ? a : y.connect;
|
|
402
|
+
}
|
|
403
|
+
if (p === "constructor")
|
|
388
404
|
return e.current.constructor;
|
|
389
|
-
let
|
|
390
|
-
return typeof
|
|
405
|
+
let f = e.current, h = Reflect.get(f, p, f);
|
|
406
|
+
return typeof h == "function" ? h.bind(f) : h;
|
|
391
407
|
}
|
|
392
408
|
});
|
|
393
409
|
}
|
|
394
|
-
var
|
|
395
|
-
|
|
410
|
+
var Ge, eo, Xe = $(() => {
|
|
411
|
+
Ge = /* @__PURE__ */ Symbol.for("neetru.sdk.resilientPool");
|
|
412
|
+
eo = /* @__PURE__ */ new Set(["28P01", "28000"]);
|
|
396
413
|
});
|
|
397
414
|
|
|
398
415
|
// src/db/sql/lease.ts
|
|
399
|
-
function
|
|
416
|
+
function ro(n, e) {
|
|
400
417
|
return n ? n.leaseId !== e.leaseId || n.credentialVersion !== e.credentialVersion || n.host !== e.host || n.port !== e.port || n.dbName !== e.dbName || n.user !== e.user || n.password !== e.password || n.sslca !== e.sslca || n.clientCert !== e.clientCert || n.clientKey !== e.clientKey : true;
|
|
401
418
|
}
|
|
402
|
-
function
|
|
403
|
-
if (n instanceof
|
|
419
|
+
function oo(n) {
|
|
420
|
+
if (n instanceof _) return n;
|
|
404
421
|
let e = n instanceof Error ? n.message : String(n), t = n instanceof Error ? n.code : void 0;
|
|
405
|
-
return typeof t == "string" && (t === "ECONNREFUSED" || t === "ENOTFOUND" || t === "ETIMEDOUT") ? new
|
|
422
|
+
return typeof t == "string" && (t === "ECONNREFUSED" || t === "ENOTFOUND" || t === "ETIMEDOUT") ? new _(
|
|
406
423
|
"db_unavailable",
|
|
407
424
|
`Pool connection failed (${t}): ${e}`
|
|
408
|
-
) : e.includes("statement timeout") || e.includes("lock timeout") ? new
|
|
425
|
+
) : e.includes("statement timeout") || e.includes("lock timeout") ? new _("db_timeout", `Query timeout: ${e}`) : e.includes("40001") || e.includes("40P01") || e.includes("deadlock") ? new _("db_conflict", `Transaction conflict: ${e}`) : e.includes("42501") || e.toLowerCase().includes("permission denied") ? new _("db_permission_denied", `Permission denied: ${e}`) : new _("db_unavailable", `Database error: ${e}`);
|
|
409
426
|
}
|
|
410
|
-
var
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
427
|
+
var no, X, oe, Yt = $(() => {
|
|
428
|
+
ee();
|
|
429
|
+
Xe();
|
|
430
|
+
no = 0.8, X = 3e4, oe = class {
|
|
414
431
|
/**
|
|
415
432
|
* Lease atual. `null` no modo LAZY antes da 1ª query (o 1º lease é adiado —
|
|
416
433
|
* ver `_ensureInitialLease`). Após a 1ª aquisição, sempre não-nulo.
|
|
@@ -450,7 +467,7 @@ var Qr, J, re, Gt = $(() => {
|
|
|
450
467
|
isolationLevel: t.isolationLevel
|
|
451
468
|
}) : await this._orm.transaction(e);
|
|
452
469
|
} catch (r) {
|
|
453
|
-
throw
|
|
470
|
+
throw oo(r);
|
|
454
471
|
}
|
|
455
472
|
}
|
|
456
473
|
async close() {
|
|
@@ -468,13 +485,13 @@ var Qr, J, re, Gt = $(() => {
|
|
|
468
485
|
* usa `MIN_RENEWAL_DELAY_MS` como fallback seguro.
|
|
469
486
|
*/
|
|
470
487
|
_calcRenewalDelayMs() {
|
|
471
|
-
if (!this._lease) return
|
|
488
|
+
if (!this._lease) return X;
|
|
472
489
|
let e = Date.parse(this._lease.expiresAt);
|
|
473
|
-
if (!Number.isFinite(e)) return
|
|
490
|
+
if (!Number.isFinite(e)) return X;
|
|
474
491
|
let t = this._deps.now(), r = e - t;
|
|
475
|
-
if (r <= 0) return
|
|
476
|
-
let o = r * (1 -
|
|
477
|
-
return Math.max(
|
|
492
|
+
if (r <= 0) return X;
|
|
493
|
+
let o = r * (1 - no);
|
|
494
|
+
return Math.max(X, Math.round(o));
|
|
478
495
|
}
|
|
479
496
|
_scheduleRenewal() {
|
|
480
497
|
if (this._closed) return;
|
|
@@ -501,8 +518,8 @@ var Qr, J, re, Gt = $(() => {
|
|
|
501
518
|
} catch (t) {
|
|
502
519
|
this._renewalTimer = setTimeout(() => {
|
|
503
520
|
this._doRenew();
|
|
504
|
-
},
|
|
505
|
-
`[SqlLeaseManager] renova\xE7\xE3o E emiss\xE3o de lease novo falharam; re-tentando em ${
|
|
521
|
+
}, X), console.warn(
|
|
522
|
+
`[SqlLeaseManager] renova\xE7\xE3o E emiss\xE3o de lease novo falharam; re-tentando em ${X}ms (o cert de cliente mTLS do lease expira ~15min ap\xF3s o \xFAltimo swap):`,
|
|
506
523
|
t instanceof Error ? t.message : t
|
|
507
524
|
);
|
|
508
525
|
return;
|
|
@@ -514,10 +531,13 @@ var Qr, J, re, Gt = $(() => {
|
|
|
514
531
|
/**
|
|
515
532
|
* Recuperação REATIVA: chamado pelo wrapper resiliente (`resilient-pool.ts`)
|
|
516
533
|
* quando uma query plana falha num erro de ESTABELECIMENTO de conexão (cert
|
|
517
|
-
* TLS
|
|
518
|
-
* renovação que não disparou)
|
|
519
|
-
* do
|
|
520
|
-
*
|
|
534
|
+
* TLS de cliente mTLS do lease expirado no meio de uma request, ou timer de
|
|
535
|
+
* renovação que não disparou) ou de AUTENTICAÇÃO (senha rotacionada por
|
|
536
|
+
* `rotate-credentials` antes do próximo renew — SQLSTATE 28P01/28000, ou o
|
|
537
|
+
* 08P01+SASL do PgBouncer; também no `connect()` de uma transação). Emite um
|
|
538
|
+
* lease NOVO e faz o swap do pool interno do wrapper com a credencial e o
|
|
539
|
+
* certificado frescos (o pool velho é drenado com `end()`); o wrapper então
|
|
540
|
+
* re-tenta a operação 1x no pool novo.
|
|
521
541
|
*
|
|
522
542
|
* Vai DIRETO ao lease novo (sem `leaseId`) — a conexão falhou porque o
|
|
523
543
|
* certificado do lease atual está ruim, então `renew` (que depende do lease
|
|
@@ -533,7 +553,7 @@ var Qr, J, re, Gt = $(() => {
|
|
|
533
553
|
*/
|
|
534
554
|
async _reactiveReLease() {
|
|
535
555
|
if (this._closed)
|
|
536
|
-
throw new
|
|
556
|
+
throw new _(
|
|
537
557
|
"db_unavailable",
|
|
538
558
|
"SqlLeaseManager foi fechado \u2014 re-lease reativo abortado."
|
|
539
559
|
);
|
|
@@ -570,30 +590,30 @@ var Qr, J, re, Gt = $(() => {
|
|
|
570
590
|
*/
|
|
571
591
|
async _ensureInitialLease() {
|
|
572
592
|
if (this._closed)
|
|
573
|
-
throw new
|
|
593
|
+
throw new _(
|
|
574
594
|
"db_unavailable",
|
|
575
595
|
"SqlLeaseManager foi fechado \u2014 aquisi\xE7\xE3o de lease inicial abortada."
|
|
576
596
|
);
|
|
577
597
|
if (this._lease)
|
|
578
|
-
return
|
|
598
|
+
return we(this._pool) ? this._pool.__neetruGetInner() : this._pool;
|
|
579
599
|
if (this._initInFlight !== null) return this._initInFlight;
|
|
580
600
|
let e = (async () => {
|
|
581
601
|
let t;
|
|
582
602
|
try {
|
|
583
603
|
t = this._deps.database !== void 0 ? await this._deps.fetchLease({ database: this._deps.database }) : await this._deps.fetchLease();
|
|
584
604
|
} catch (o) {
|
|
585
|
-
if (o instanceof
|
|
605
|
+
if (o instanceof _) throw o;
|
|
586
606
|
let i = o instanceof Error ? o.message : String(o);
|
|
587
|
-
throw new
|
|
607
|
+
throw new _("db_unavailable", `Falha ao obter lease inicial: ${i}`);
|
|
588
608
|
}
|
|
589
609
|
let r;
|
|
590
610
|
try {
|
|
591
611
|
r = this._deps.createPool(t);
|
|
592
612
|
} catch (o) {
|
|
593
613
|
let i = o instanceof Error ? o.message : String(o);
|
|
594
|
-
throw new
|
|
614
|
+
throw new _("db_unavailable", `Falha ao abrir pool: ${i}`);
|
|
595
615
|
}
|
|
596
|
-
return
|
|
616
|
+
return we(this._pool) ? this._pool.__neetruSwapInner(r).end().catch(() => {
|
|
597
617
|
}) : this._pool = r, this._lease = t, this._scheduleRenewal(), r;
|
|
598
618
|
})();
|
|
599
619
|
this._initInFlight = e;
|
|
@@ -609,12 +629,12 @@ var Qr, J, re, Gt = $(() => {
|
|
|
609
629
|
* Exposto como método protegido para testes.
|
|
610
630
|
*/
|
|
611
631
|
async _swapPool(e) {
|
|
612
|
-
if (!
|
|
632
|
+
if (!ro(this._lease, e)) {
|
|
613
633
|
this._lease = e;
|
|
614
634
|
return;
|
|
615
635
|
}
|
|
616
636
|
let t = this._deps.createPool(e);
|
|
617
|
-
if (
|
|
637
|
+
if (we(this._pool)) {
|
|
618
638
|
let i = this._pool.__neetruSwapInner(t);
|
|
619
639
|
this._lease = e, i.end().catch(() => {
|
|
620
640
|
});
|
|
@@ -627,7 +647,7 @@ var Qr, J, re, Gt = $(() => {
|
|
|
627
647
|
// ─── Helpers ───────────────────────────────────────────────────────────────
|
|
628
648
|
_assertOpen() {
|
|
629
649
|
if (this._closed)
|
|
630
|
-
throw new
|
|
650
|
+
throw new _(
|
|
631
651
|
"db_unavailable",
|
|
632
652
|
"SqlLeaseManager foi fechado \u2014 chame close() apenas no shutdown."
|
|
633
653
|
);
|
|
@@ -636,29 +656,29 @@ var Qr, J, re, Gt = $(() => {
|
|
|
636
656
|
});
|
|
637
657
|
|
|
638
658
|
// src/db/sql/sql-client.ts
|
|
639
|
-
var
|
|
640
|
-
|
|
641
|
-
DEFAULT_POOL_CONNECT_TIMEOUT_MS: () =>
|
|
642
|
-
DEFAULT_POOL_IDLE_MS: () =>
|
|
643
|
-
DEFAULT_POOL_MAX: () =>
|
|
644
|
-
LEASE_ENDPOINT: () =>
|
|
645
|
-
LEASE_RENEW_ENDPOINT: () =>
|
|
646
|
-
createDrizzleHandle: () =>
|
|
647
|
-
createHttpLeaseFetcher: () =>
|
|
648
|
-
createPgPool: () =>
|
|
649
|
-
createSqlClientFromConfig: () =>
|
|
650
|
-
createSqlClientWithDeps: () =>
|
|
651
|
-
resolvePoolTuning: () =>
|
|
659
|
+
var an = {};
|
|
660
|
+
st(an, {
|
|
661
|
+
DEFAULT_POOL_CONNECT_TIMEOUT_MS: () => on,
|
|
662
|
+
DEFAULT_POOL_IDLE_MS: () => rn,
|
|
663
|
+
DEFAULT_POOL_MAX: () => nn,
|
|
664
|
+
LEASE_ENDPOINT: () => Zt,
|
|
665
|
+
LEASE_RENEW_ENDPOINT: () => en,
|
|
666
|
+
createDrizzleHandle: () => co,
|
|
667
|
+
createHttpLeaseFetcher: () => tn,
|
|
668
|
+
createPgPool: () => ao,
|
|
669
|
+
createSqlClientFromConfig: () => uo,
|
|
670
|
+
createSqlClientWithDeps: () => sn,
|
|
671
|
+
resolvePoolTuning: () => Ze
|
|
652
672
|
});
|
|
653
|
-
function
|
|
673
|
+
function io(n) {
|
|
654
674
|
return n === "workspace" ? "staging" : n === "prod" ? "production" : "dev-local";
|
|
655
675
|
}
|
|
656
|
-
function
|
|
676
|
+
function tn(n) {
|
|
657
677
|
return async (e) => {
|
|
658
|
-
let { httpRequest: t } = await Promise.resolve().then(() => (
|
|
678
|
+
let { httpRequest: t } = await Promise.resolve().then(() => (F(), Z)), r = !!e?.leaseId, o = r ? en : Zt, i;
|
|
659
679
|
r ? i = { leaseId: e.leaseId } : (i = {
|
|
660
680
|
productId: n.productId ?? "",
|
|
661
|
-
environment:
|
|
681
|
+
environment: io(n.env ?? "prod")
|
|
662
682
|
}, e?.database !== void 0 && (i.database = e.database));
|
|
663
683
|
let s;
|
|
664
684
|
try {
|
|
@@ -671,35 +691,35 @@ function Yt(n) {
|
|
|
671
691
|
retries: 2
|
|
672
692
|
});
|
|
673
693
|
} catch (a) {
|
|
674
|
-
let
|
|
694
|
+
let l = r ? "renovar" : "obter", d = a instanceof Error ? a.message : String(a), u = a instanceof c ? a.reason : void 0;
|
|
675
695
|
if (u === "suspended" || u === "archived" || u === "revoked") {
|
|
676
696
|
let p = u === "suspended" ? "ambiente suspenso \u2014 a m\xE1quina que o servia parou; ser\xE1 religado quando o ambiente voltar" : u === "archived" ? "ambiente arquivado \u2014 este banco foi arquivado e n\xE3o aceita mais conex\xF5es" : "lease revogado \u2014 as credenciais deste ambiente foram revogadas pelo Core";
|
|
677
|
-
throw new
|
|
697
|
+
throw new _(
|
|
678
698
|
"db_suspended",
|
|
679
|
-
`Falha ao ${
|
|
699
|
+
`Falha ao ${l} lease SQL: ${p} (reason=${u}).`
|
|
680
700
|
);
|
|
681
701
|
}
|
|
682
|
-
throw new
|
|
702
|
+
throw new _(
|
|
683
703
|
"db_unavailable",
|
|
684
|
-
`Falha ao ${
|
|
704
|
+
`Falha ao ${l} lease SQL: ${d}`
|
|
685
705
|
);
|
|
686
706
|
}
|
|
687
|
-
return
|
|
707
|
+
return so(s);
|
|
688
708
|
};
|
|
689
709
|
}
|
|
690
|
-
function
|
|
710
|
+
function so(n) {
|
|
691
711
|
if (!n || typeof n != "object")
|
|
692
|
-
throw new
|
|
712
|
+
throw new _("db_unavailable", "Resposta de lease inv\xE1lida (n\xE3o \xE9 objeto).");
|
|
693
713
|
let t = n.lease;
|
|
694
714
|
if (!t || typeof t != "object")
|
|
695
|
-
throw new
|
|
715
|
+
throw new _(
|
|
696
716
|
"db_unavailable",
|
|
697
717
|
'Resposta de lease inv\xE1lida: campo "lease" ausente ou n\xE3o \xE9 objeto. O Core retorna { kind, lease: { leaseId, host, ... } }.'
|
|
698
718
|
);
|
|
699
719
|
let r = t;
|
|
700
720
|
function o(i, s) {
|
|
701
721
|
if (typeof r[i] !== s)
|
|
702
|
-
throw new
|
|
722
|
+
throw new _(
|
|
703
723
|
"db_unavailable",
|
|
704
724
|
`Campo obrigat\xF3rio "${i}" ausente ou tipo inv\xE1lido na resposta de lease.`
|
|
705
725
|
);
|
|
@@ -719,22 +739,22 @@ function Yr(n) {
|
|
|
719
739
|
expiresAt: o("expiresAt", "string")
|
|
720
740
|
};
|
|
721
741
|
}
|
|
722
|
-
function
|
|
742
|
+
function Ye(n, e, t, r) {
|
|
723
743
|
let o = typeof process < "u" ? process.env?.[n] : void 0;
|
|
724
744
|
if (o === void 0 || o.trim() === "") return e;
|
|
725
745
|
let i = Number.parseInt(o.trim(), 10);
|
|
726
746
|
return !Number.isFinite(i) || i < t || i > r ? e : i;
|
|
727
747
|
}
|
|
728
|
-
function
|
|
748
|
+
function Ze() {
|
|
729
749
|
return {
|
|
730
750
|
// Teto 100: bem abaixo do `max_client_conn = 500` do PgBouncer, com folga
|
|
731
751
|
// para múltiplas instâncias do app dividirem o mesmo front-door.
|
|
732
|
-
max:
|
|
752
|
+
max: Ye("NEETRU_DB_POOL_MAX", nn, 1, 100),
|
|
733
753
|
// Teto 15min = janela do cert; piso 1s.
|
|
734
|
-
idleTimeoutMillis:
|
|
735
|
-
connectionTimeoutMillis:
|
|
754
|
+
idleTimeoutMillis: Ye("NEETRU_DB_POOL_IDLE_MS", rn, 1e3, 9e5),
|
|
755
|
+
connectionTimeoutMillis: Ye(
|
|
736
756
|
"NEETRU_DB_POOL_CONNECT_TIMEOUT_MS",
|
|
737
|
-
|
|
757
|
+
on,
|
|
738
758
|
1e3,
|
|
739
759
|
12e4
|
|
740
760
|
),
|
|
@@ -742,7 +762,7 @@ function Xe() {
|
|
|
742
762
|
keepAliveInitialDelayMillis: 1e4
|
|
743
763
|
};
|
|
744
764
|
}
|
|
745
|
-
async function
|
|
765
|
+
async function ao(n) {
|
|
746
766
|
let { Pool: e } = await import(
|
|
747
767
|
/* webpackIgnore: true */
|
|
748
768
|
'pg'
|
|
@@ -759,17 +779,17 @@ async function Zr(n) {
|
|
|
759
779
|
user: n.user,
|
|
760
780
|
password: n.password,
|
|
761
781
|
ssl: t,
|
|
762
|
-
...
|
|
782
|
+
...Ze()
|
|
763
783
|
});
|
|
764
784
|
}
|
|
765
|
-
async function
|
|
785
|
+
async function co(n, e) {
|
|
766
786
|
let { drizzle: t } = await import(
|
|
767
787
|
/* webpackIgnore: true */
|
|
768
788
|
'drizzle-orm/node-postgres'
|
|
769
789
|
);
|
|
770
790
|
return t(n, { schema: e });
|
|
771
791
|
}
|
|
772
|
-
function
|
|
792
|
+
function lo(n, e) {
|
|
773
793
|
let t = null, r = null, o = () => t ? Promise.resolve(t) : (r || (r = e().then((s) => (t = s, r = null, s)).catch((s) => {
|
|
774
794
|
throw r = null, s;
|
|
775
795
|
})), r), i = {
|
|
@@ -785,52 +805,52 @@ function to(n, e) {
|
|
|
785
805
|
};
|
|
786
806
|
return n && Object.setPrototypeOf(i, n), i;
|
|
787
807
|
}
|
|
788
|
-
async function
|
|
808
|
+
async function sn(n, e) {
|
|
789
809
|
let t = e?.database !== void 0 ? { ...n, database: e.database } : n;
|
|
790
810
|
if (t.lazy) {
|
|
791
|
-
let
|
|
792
|
-
if (!
|
|
793
|
-
throw new
|
|
794
|
-
return
|
|
795
|
-
}), u =
|
|
811
|
+
let l = null, d = lo(t.poolPrototype ?? null, () => {
|
|
812
|
+
if (!l)
|
|
813
|
+
throw new _("db_unavailable", "SQL client n\xE3o inicializado (manager ausente).");
|
|
814
|
+
return l._ensureInitialLease();
|
|
815
|
+
}), u = Je(d), p;
|
|
796
816
|
try {
|
|
797
817
|
p = t.createDrizzle(u, t.schema);
|
|
798
|
-
} catch (
|
|
799
|
-
let
|
|
800
|
-
throw new
|
|
818
|
+
} catch (h) {
|
|
819
|
+
let y = h instanceof Error ? h.message : String(h);
|
|
820
|
+
throw new _("db_unavailable", `Falha ao criar handle Drizzle: ${y}`);
|
|
801
821
|
}
|
|
802
|
-
let f = new
|
|
803
|
-
return
|
|
822
|
+
let f = new oe(null, u, p, t);
|
|
823
|
+
return l = f, u.__neetruSetReLease(() => f._reactiveReLease()), f;
|
|
804
824
|
}
|
|
805
825
|
let r;
|
|
806
826
|
try {
|
|
807
827
|
e?.database !== void 0 ? r = await t.fetchLease({ database: e.database }) : r = await t.fetchLease();
|
|
808
|
-
} catch (
|
|
809
|
-
if (
|
|
810
|
-
let d =
|
|
811
|
-
throw new
|
|
828
|
+
} catch (l) {
|
|
829
|
+
if (l instanceof _) throw l;
|
|
830
|
+
let d = l instanceof Error ? l.message : String(l);
|
|
831
|
+
throw new _("db_unavailable", `Falha ao obter lease inicial: ${d}`);
|
|
812
832
|
}
|
|
813
833
|
let o;
|
|
814
834
|
try {
|
|
815
835
|
o = t.createPool(r);
|
|
816
|
-
} catch (
|
|
817
|
-
let d =
|
|
818
|
-
throw new
|
|
836
|
+
} catch (l) {
|
|
837
|
+
let d = l instanceof Error ? l.message : String(l);
|
|
838
|
+
throw new _("db_unavailable", `Falha ao abrir pool: ${d}`);
|
|
819
839
|
}
|
|
820
|
-
let i =
|
|
840
|
+
let i = Je(o), s;
|
|
821
841
|
try {
|
|
822
842
|
s = t.createDrizzle(i, t.schema);
|
|
823
|
-
} catch (
|
|
843
|
+
} catch (l) {
|
|
824
844
|
await o.end().catch(() => {
|
|
825
845
|
});
|
|
826
|
-
let d =
|
|
827
|
-
throw new
|
|
846
|
+
let d = l instanceof Error ? l.message : String(l);
|
|
847
|
+
throw new _("db_unavailable", `Falha ao criar handle Drizzle: ${d}`);
|
|
828
848
|
}
|
|
829
|
-
let a = new
|
|
849
|
+
let a = new oe(r, i, s, t);
|
|
830
850
|
return i.__neetruSetReLease(() => a._reactiveReLease()), a;
|
|
831
851
|
}
|
|
832
|
-
async function
|
|
833
|
-
let r =
|
|
852
|
+
async function uo(n, e, t) {
|
|
853
|
+
let r = tn(n), o, i;
|
|
834
854
|
try {
|
|
835
855
|
o = await import(
|
|
836
856
|
/* webpackIgnore: true */
|
|
@@ -840,13 +860,13 @@ async function no(n, e, t) {
|
|
|
840
860
|
'drizzle-orm/node-postgres'
|
|
841
861
|
);
|
|
842
862
|
} catch (d) {
|
|
843
|
-
throw new
|
|
863
|
+
throw new _(
|
|
844
864
|
"db_unavailable",
|
|
845
865
|
`[client.db.sql] requer pg + drizzle-orm como peerDependencies do servidor. Instale: npm install pg drizzle-orm. (${d.message})`
|
|
846
866
|
);
|
|
847
867
|
}
|
|
848
868
|
let s = o.Pool ?? o.default?.Pool;
|
|
849
|
-
return
|
|
869
|
+
return sn(
|
|
850
870
|
{
|
|
851
871
|
fetchLease: r,
|
|
852
872
|
createPool: (d) => {
|
|
@@ -865,7 +885,7 @@ async function no(n, e, t) {
|
|
|
865
885
|
ssl: u,
|
|
866
886
|
// Tuning centralizado (env-tunável) — ver resolvePoolTuning + auditoria
|
|
867
887
|
// docs/_review/AUDITORIA_DB_CONN_PERF_2026-09-06.md no Core.
|
|
868
|
-
...
|
|
888
|
+
...Ze()
|
|
869
889
|
});
|
|
870
890
|
},
|
|
871
891
|
createDrizzle: (d, u) => i.drizzle(d, { schema: u }),
|
|
@@ -881,100 +901,100 @@ async function no(n, e, t) {
|
|
|
881
901
|
t
|
|
882
902
|
);
|
|
883
903
|
}
|
|
884
|
-
var
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
904
|
+
var Zt, en, nn, rn, on, cn = $(() => {
|
|
905
|
+
ee();
|
|
906
|
+
C();
|
|
907
|
+
Yt();
|
|
908
|
+
Xe();
|
|
909
|
+
Zt = "/api/sdk/v1/db/lease", en = "/api/sdk/v1/db/lease/renew";
|
|
910
|
+
nn = 10, rn = 6e4, on = 1e4;
|
|
891
911
|
});
|
|
892
|
-
var
|
|
893
|
-
function
|
|
894
|
-
let t = Date.now(), r =
|
|
912
|
+
var Ue = /* @__PURE__ */ new Map(), Me = 3600 * 1e3;
|
|
913
|
+
function at(n, e = Me) {
|
|
914
|
+
let t = Date.now(), r = Ue.get(n);
|
|
895
915
|
if (r && t - r.createdAt < e)
|
|
896
916
|
return r.jwks;
|
|
897
917
|
let o = jose.createRemoteJWKSet(new URL(n));
|
|
898
|
-
return
|
|
918
|
+
return Ue.set(n, { jwks: o, createdAt: t }), o;
|
|
899
919
|
}
|
|
900
|
-
function
|
|
901
|
-
|
|
920
|
+
function ct() {
|
|
921
|
+
Ue.clear();
|
|
902
922
|
}
|
|
903
923
|
|
|
904
924
|
// src/auth.ts
|
|
905
|
-
|
|
925
|
+
C();
|
|
906
926
|
|
|
907
927
|
// src/api-key.ts
|
|
908
|
-
|
|
909
|
-
var
|
|
910
|
-
function
|
|
928
|
+
C();
|
|
929
|
+
var lt = /^nrt_([A-Za-z0-9]+)_([A-Za-z0-9]+)$/;
|
|
930
|
+
function dt(n) {
|
|
911
931
|
if (typeof n != "string" || n.length === 0)
|
|
912
|
-
throw new
|
|
932
|
+
throw new c(
|
|
913
933
|
"invalid_config",
|
|
914
934
|
"apiKey is required (formato nrt_<keyId>_<secret>)"
|
|
915
935
|
);
|
|
916
|
-
let e =
|
|
936
|
+
let e = lt.exec(n);
|
|
917
937
|
if (!e)
|
|
918
|
-
throw new
|
|
938
|
+
throw new c(
|
|
919
939
|
"invalid_config",
|
|
920
940
|
"apiKey malformado - esperado formato nrt_<keyId>_<secret>"
|
|
921
941
|
);
|
|
922
942
|
return { keyId: e[1], secret: e[2] };
|
|
923
943
|
}
|
|
924
|
-
function
|
|
944
|
+
function ut(n) {
|
|
925
945
|
if (typeof n != "string" || n.length === 0) return null;
|
|
926
|
-
let e =
|
|
946
|
+
let e = lt.exec(n);
|
|
927
947
|
return e ? { keyId: e[1], secret: e[2] } : null;
|
|
928
948
|
}
|
|
929
949
|
|
|
930
950
|
// src/base-url-allowlist.ts
|
|
931
|
-
|
|
932
|
-
var
|
|
933
|
-
function
|
|
934
|
-
return
|
|
951
|
+
C();
|
|
952
|
+
var pt = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]", "::1"]), tr = ".neetru.com", nr = "neetru.com", rr = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?\.(test|localhost)$/;
|
|
953
|
+
function ft(n) {
|
|
954
|
+
return rr.test(n);
|
|
935
955
|
}
|
|
936
|
-
function
|
|
956
|
+
function or(n) {
|
|
937
957
|
return n.toLowerCase().replace(/\.+$/, "");
|
|
938
958
|
}
|
|
939
|
-
function
|
|
959
|
+
function mt(n, e = []) {
|
|
940
960
|
if (typeof n != "string" || n.length === 0)
|
|
941
|
-
throw new
|
|
961
|
+
throw new c("invalid_config", "baseUrl is required");
|
|
942
962
|
let t;
|
|
943
963
|
try {
|
|
944
964
|
t = new URL(n);
|
|
945
965
|
} catch {
|
|
946
|
-
throw new
|
|
966
|
+
throw new c("invalid_config", `baseUrl is not a valid URL: ${n}`);
|
|
947
967
|
}
|
|
948
|
-
let r = t.protocol, o =
|
|
949
|
-
if (
|
|
968
|
+
let r = t.protocol, o = or(t.hostname);
|
|
969
|
+
if (ir())
|
|
950
970
|
return typeof console < "u" && console.warn(
|
|
951
971
|
`[neetru-sdk] NEETRU_ALLOW_INSECURE_BASEURL=1 ativo. baseUrl=${n} aceito sem valida\xE7\xE3o.`
|
|
952
972
|
), n.replace(/\/+$/, "");
|
|
953
973
|
if (r !== "https:" && r !== "http:")
|
|
954
|
-
throw new
|
|
974
|
+
throw new c(
|
|
955
975
|
"invalid_config",
|
|
956
976
|
`baseUrl protocol must be http: or https:, got ${r}`
|
|
957
977
|
);
|
|
958
978
|
if (r === "http:") {
|
|
959
|
-
if (!(
|
|
960
|
-
throw new
|
|
979
|
+
if (!(pt.has(o) || ft(o)))
|
|
980
|
+
throw new c(
|
|
961
981
|
"invalid_config",
|
|
962
982
|
`baseUrl with http: only allowed for localhost/127.0.0.1/*.test/*.localhost. Got: ${o}. Use https: or set NEETRU_ALLOW_INSECURE_BASEURL=1 to bypass.`
|
|
963
983
|
);
|
|
964
984
|
return n.replace(/\/+$/, "");
|
|
965
985
|
}
|
|
966
|
-
let i = o ===
|
|
967
|
-
let d =
|
|
986
|
+
let i = o === nr || o.endsWith(tr), s = e.some((l) => {
|
|
987
|
+
let d = l.toLowerCase();
|
|
968
988
|
return o === d || o.endsWith(`.${d}`);
|
|
969
|
-
}), a =
|
|
989
|
+
}), a = pt.has(o) || ft(o);
|
|
970
990
|
if (!i && !s && !a)
|
|
971
|
-
throw new
|
|
991
|
+
throw new c(
|
|
972
992
|
"invalid_config",
|
|
973
993
|
`baseUrl ${o} is not in the allowlist. Allowed: *.neetru.com, localhost, or configure { allowedHosts: ['...'] }. Bypass: NEETRU_ALLOW_INSECURE_BASEURL=1.`
|
|
974
994
|
);
|
|
975
995
|
return n.replace(/\/+$/, "");
|
|
976
996
|
}
|
|
977
|
-
function
|
|
997
|
+
function ir() {
|
|
978
998
|
try {
|
|
979
999
|
let e = globalThis.process?.env?.NEETRU_ALLOW_INSECURE_BASEURL;
|
|
980
1000
|
if (e === "1" || e === "true") return !0;
|
|
@@ -989,19 +1009,19 @@ function Zn() {
|
|
|
989
1009
|
}
|
|
990
1010
|
|
|
991
1011
|
// src/types.ts
|
|
992
|
-
var
|
|
1012
|
+
var ht = "https://api.neetru.com", gt = "http://localhost:9003";
|
|
993
1013
|
|
|
994
1014
|
// src/catalog.ts
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
function
|
|
1015
|
+
C();
|
|
1016
|
+
F();
|
|
1017
|
+
function Pt(n) {
|
|
998
1018
|
if (!n || typeof n != "object")
|
|
999
|
-
throw new
|
|
1019
|
+
throw new c("invalid_response", "Catalog response item is not an object");
|
|
1000
1020
|
let e = n;
|
|
1001
1021
|
if (typeof e.slug != "string" || !e.slug)
|
|
1002
|
-
throw new
|
|
1022
|
+
throw new c("invalid_response", "Catalog product missing slug");
|
|
1003
1023
|
if (typeof e.name != "string" || !e.name)
|
|
1004
|
-
throw new
|
|
1024
|
+
throw new c("invalid_response", "Catalog product missing name");
|
|
1005
1025
|
let t = {
|
|
1006
1026
|
slug: e.slug,
|
|
1007
1027
|
name: e.name
|
|
@@ -1013,7 +1033,7 @@ function At(n) {
|
|
|
1013
1033
|
return typeof r.amountCents == "number" && (o.amountCents = r.amountCents), Array.isArray(r.features) && r.features.every((i) => typeof i == "string") && (o.features = r.features), o;
|
|
1014
1034
|
})), t;
|
|
1015
1035
|
}
|
|
1016
|
-
function
|
|
1036
|
+
function Dt(n) {
|
|
1017
1037
|
return {
|
|
1018
1038
|
/**
|
|
1019
1039
|
* Lista produtos publicados. Por default só `published=true`; staff
|
|
@@ -1025,12 +1045,12 @@ function Et(n) {
|
|
|
1025
1045
|
path: "/api/sdk/v1/catalog"
|
|
1026
1046
|
});
|
|
1027
1047
|
if (!t || !Array.isArray(t.products))
|
|
1028
|
-
throw new
|
|
1048
|
+
throw new c(
|
|
1029
1049
|
"invalid_response",
|
|
1030
1050
|
"Catalog list response missing products array"
|
|
1031
1051
|
);
|
|
1032
1052
|
return {
|
|
1033
|
-
products: t.products.map(
|
|
1053
|
+
products: t.products.map(Pt),
|
|
1034
1054
|
fetchedAt: typeof t.fetchedAt == "string" ? t.fetchedAt : (/* @__PURE__ */ new Date()).toISOString()
|
|
1035
1055
|
};
|
|
1036
1056
|
},
|
|
@@ -1041,42 +1061,42 @@ function Et(n) {
|
|
|
1041
1061
|
*/
|
|
1042
1062
|
async get(e) {
|
|
1043
1063
|
if (!e || typeof e != "string")
|
|
1044
|
-
throw new
|
|
1064
|
+
throw new c("validation_failed", "slug is required");
|
|
1045
1065
|
let t = await v(n, {
|
|
1046
1066
|
method: "GET",
|
|
1047
1067
|
path: `/api/sdk/v1/catalog/${encodeURIComponent(e)}`
|
|
1048
1068
|
});
|
|
1049
1069
|
if (!t || !t.product)
|
|
1050
|
-
throw new
|
|
1070
|
+
throw new c(
|
|
1051
1071
|
"invalid_response",
|
|
1052
1072
|
"Catalog get response missing product"
|
|
1053
1073
|
);
|
|
1054
|
-
return
|
|
1074
|
+
return Pt(t.product);
|
|
1055
1075
|
}
|
|
1056
1076
|
};
|
|
1057
1077
|
}
|
|
1058
1078
|
|
|
1059
1079
|
// src/entitlements.ts
|
|
1060
|
-
|
|
1061
|
-
var
|
|
1062
|
-
function
|
|
1063
|
-
throw new
|
|
1080
|
+
C();
|
|
1081
|
+
var br = "client.entitlements.check()/checkDetailed() est\xE3o DEPRECADOS \u2014 apontavam para GET /api/v1/sdk/entitlements/check, um endpoint que o Core nunca escreve (sempre retornava not_subscribed). Use client.usage.check(resource, { productId, tenantId }) no lugar \u2014 mesmo resultado (allowed/reason/remaining/limit/behavior), endpoint real.";
|
|
1082
|
+
function Nt() {
|
|
1083
|
+
throw new c("validation_failed", br);
|
|
1064
1084
|
}
|
|
1065
|
-
function
|
|
1085
|
+
function xt(n) {
|
|
1066
1086
|
return {
|
|
1067
1087
|
/**
|
|
1068
1088
|
* @deprecated Endpoint morto no Core — sempre retornava `not_subscribed`.
|
|
1069
1089
|
* Lança `NeetruError`. Use `client.usage.check(resource, {productId, tenantId})`.
|
|
1070
1090
|
*/
|
|
1071
1091
|
async check(e, t, r) {
|
|
1072
|
-
|
|
1092
|
+
Nt();
|
|
1073
1093
|
},
|
|
1074
1094
|
/**
|
|
1075
1095
|
* @deprecated Endpoint morto no Core — sempre retornava `not_subscribed`.
|
|
1076
1096
|
* Lança `NeetruError`. Use `client.usage.check(resource, {productId, tenantId})`.
|
|
1077
1097
|
*/
|
|
1078
1098
|
async checkDetailed(e, t, r) {
|
|
1079
|
-
|
|
1099
|
+
Nt();
|
|
1080
1100
|
},
|
|
1081
1101
|
/** Test helper legado — no-op (não há mais cache). Mantido por compat. */
|
|
1082
1102
|
__resetCache() {
|
|
@@ -1085,16 +1105,31 @@ function Dt(n) {
|
|
|
1085
1105
|
}
|
|
1086
1106
|
|
|
1087
1107
|
// src/telemetry.ts
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1108
|
+
C();
|
|
1109
|
+
F();
|
|
1110
|
+
|
|
1111
|
+
// src/runtime-env.ts
|
|
1112
|
+
function $e() {
|
|
1113
|
+
try {
|
|
1114
|
+
if (typeof process < "u" && process.env)
|
|
1115
|
+
return process.env.NODE_ENV === "production";
|
|
1116
|
+
} catch {
|
|
1117
|
+
}
|
|
1118
|
+
return false;
|
|
1119
|
+
}
|
|
1120
|
+
function W(n) {
|
|
1121
|
+
return n === "dev" && !$e();
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
// src/telemetry.ts
|
|
1125
|
+
var Ot = ["debug", "info", "warn", "error", "fatal"];
|
|
1126
|
+
function vr() {
|
|
1092
1127
|
return typeof globalThis < "u" && typeof globalThis.window < "u";
|
|
1093
1128
|
}
|
|
1094
|
-
function
|
|
1095
|
-
return
|
|
1129
|
+
function Lt() {
|
|
1130
|
+
return vr() ? { path: "/api/sdk/v1/telemetry/event/public", requireAuth: false } : { path: "/api/sdk/v1/telemetry/event", requireAuth: true };
|
|
1096
1131
|
}
|
|
1097
|
-
function
|
|
1132
|
+
function wr(n) {
|
|
1098
1133
|
switch (n) {
|
|
1099
1134
|
case "debug":
|
|
1100
1135
|
return console.debug.bind(console);
|
|
@@ -1110,17 +1145,17 @@ function hr(n) {
|
|
|
1110
1145
|
return console.log.bind(console);
|
|
1111
1146
|
}
|
|
1112
1147
|
}
|
|
1113
|
-
var
|
|
1114
|
-
function
|
|
1148
|
+
var kr = 500, Sr = 50;
|
|
1149
|
+
function Ut(n) {
|
|
1115
1150
|
let e = [], t = null, r = null;
|
|
1116
1151
|
async function o() {
|
|
1117
1152
|
if (e.length === 0) return;
|
|
1118
1153
|
let s = e.splice(0, e.length), a = Promise.allSettled(
|
|
1119
|
-
s.map(async (
|
|
1154
|
+
s.map(async (l) => {
|
|
1120
1155
|
try {
|
|
1121
|
-
let d = { name:
|
|
1122
|
-
u && (d.productSlug = u),
|
|
1123
|
-
let p =
|
|
1156
|
+
let d = { name: l.name }, u = l.productSlug ?? n.productId;
|
|
1157
|
+
u && (d.productSlug = u), l.properties && typeof l.properties == "object" && (d.properties = l.properties), l.timestamp && (d.timestamp = l.timestamp);
|
|
1158
|
+
let p = Lt();
|
|
1124
1159
|
await v(n, {
|
|
1125
1160
|
method: "POST",
|
|
1126
1161
|
path: p.path,
|
|
@@ -1133,7 +1168,7 @@ function Ot(n) {
|
|
|
1133
1168
|
idempotencyKey: !0
|
|
1134
1169
|
});
|
|
1135
1170
|
} catch (d) {
|
|
1136
|
-
typeof console < "u" && console.warn("[neetru-sdk] telemetry.track flush failed for event",
|
|
1171
|
+
typeof console < "u" && console.warn("[neetru-sdk] telemetry.track flush failed for event", l.name, d);
|
|
1137
1172
|
}
|
|
1138
1173
|
})
|
|
1139
1174
|
);
|
|
@@ -1144,7 +1179,7 @@ function Ot(n) {
|
|
|
1144
1179
|
function i() {
|
|
1145
1180
|
t || (t = setTimeout(() => {
|
|
1146
1181
|
o();
|
|
1147
|
-
},
|
|
1182
|
+
}, kr));
|
|
1148
1183
|
}
|
|
1149
1184
|
return {
|
|
1150
1185
|
/**
|
|
@@ -1161,21 +1196,21 @@ function Ot(n) {
|
|
|
1161
1196
|
*/
|
|
1162
1197
|
async event(s) {
|
|
1163
1198
|
if (!s || typeof s != "object")
|
|
1164
|
-
throw new
|
|
1199
|
+
throw new c("validation_failed", "event input is required");
|
|
1165
1200
|
if (typeof s.name != "string" || s.name.length === 0)
|
|
1166
|
-
throw new
|
|
1201
|
+
throw new c("validation_failed", "event.name is required");
|
|
1167
1202
|
if (s.name.length > 128)
|
|
1168
|
-
throw new
|
|
1169
|
-
let a = { name: s.name },
|
|
1170
|
-
|
|
1171
|
-
let d =
|
|
1203
|
+
throw new c("validation_failed", "event.name max 128 chars");
|
|
1204
|
+
let a = { name: s.name }, l = s.productSlug ?? n.productId;
|
|
1205
|
+
l && (a.productSlug = l), s.properties && typeof s.properties == "object" && (a.properties = s.properties), s.timestamp && (a.timestamp = s.timestamp);
|
|
1206
|
+
let d = Lt(), u = await v(n, {
|
|
1172
1207
|
method: "POST",
|
|
1173
1208
|
path: d.path,
|
|
1174
1209
|
body: a,
|
|
1175
1210
|
requireAuth: d.requireAuth
|
|
1176
1211
|
});
|
|
1177
1212
|
if (!u || u.ok !== true || typeof u.eventId != "string")
|
|
1178
|
-
throw new
|
|
1213
|
+
throw new c("invalid_response", "Telemetry response missing eventId");
|
|
1179
1214
|
return { ok: true, eventId: u.eventId };
|
|
1180
1215
|
},
|
|
1181
1216
|
/**
|
|
@@ -1189,7 +1224,7 @@ function Ot(n) {
|
|
|
1189
1224
|
* ```
|
|
1190
1225
|
*/
|
|
1191
1226
|
track(s) {
|
|
1192
|
-
!s || typeof s != "object" || typeof s.name != "string" || s.name.length === 0 || s.name.length > 128 || (e.push(s), e.length >=
|
|
1227
|
+
!s || typeof s != "object" || typeof s.name != "string" || s.name.length === 0 || s.name.length > 128 || (e.push(s), e.length >= Sr ? (t && (clearTimeout(t), t = null), o()) : i());
|
|
1193
1228
|
},
|
|
1194
1229
|
/**
|
|
1195
1230
|
* Força flush imediato da queue de `track()`. Resolva antes de
|
|
@@ -1215,22 +1250,22 @@ function Ot(n) {
|
|
|
1215
1250
|
*/
|
|
1216
1251
|
async log(s) {
|
|
1217
1252
|
if (!s || typeof s != "object")
|
|
1218
|
-
throw new
|
|
1219
|
-
if (!
|
|
1220
|
-
throw new
|
|
1253
|
+
throw new c("validation_failed", "log input is required");
|
|
1254
|
+
if (!Ot.includes(s.level))
|
|
1255
|
+
throw new c("validation_failed", `level must be one of ${Ot.join(", ")}`);
|
|
1221
1256
|
if (typeof s.message != "string" || s.message.length === 0)
|
|
1222
|
-
throw new
|
|
1257
|
+
throw new c("validation_failed", "message is required");
|
|
1223
1258
|
if (s.message.length > 4e3)
|
|
1224
|
-
throw new
|
|
1225
|
-
if (n.env
|
|
1226
|
-
return
|
|
1259
|
+
throw new c("validation_failed", "message max 4000 chars");
|
|
1260
|
+
if (W(n.env))
|
|
1261
|
+
return wr(s.level)(`[neetru-sdk] ${s.level}: ${s.message}`, s.metadata ?? {}), { ok: true, mode: "mock" };
|
|
1227
1262
|
let a = {
|
|
1228
1263
|
level: s.level,
|
|
1229
1264
|
message: s.message
|
|
1230
1265
|
};
|
|
1231
1266
|
s.metadata && (a.metadata = s.metadata);
|
|
1232
|
-
let
|
|
1233
|
-
|
|
1267
|
+
let l = s.productSlug ?? n.productId;
|
|
1268
|
+
l && (a.productSlug = l);
|
|
1234
1269
|
let d = s.correlationId;
|
|
1235
1270
|
if (!d)
|
|
1236
1271
|
try {
|
|
@@ -1248,7 +1283,7 @@ function Ot(n) {
|
|
|
1248
1283
|
headers: u
|
|
1249
1284
|
});
|
|
1250
1285
|
if (!p || p.ok !== true)
|
|
1251
|
-
throw new
|
|
1286
|
+
throw new c("invalid_response", "Telemetry log response missing ok");
|
|
1252
1287
|
return {
|
|
1253
1288
|
ok: true,
|
|
1254
1289
|
logId: typeof p.logId == "string" ? p.logId : void 0,
|
|
@@ -1259,22 +1294,22 @@ function Ot(n) {
|
|
|
1259
1294
|
}
|
|
1260
1295
|
|
|
1261
1296
|
// src/usage.ts
|
|
1262
|
-
|
|
1263
|
-
|
|
1297
|
+
C();
|
|
1298
|
+
F();
|
|
1264
1299
|
|
|
1265
1300
|
// src/validators.ts
|
|
1266
|
-
|
|
1267
|
-
var
|
|
1301
|
+
C();
|
|
1302
|
+
var Mt = /^[a-z0-9][a-z0-9_-]{0,62}$/i;
|
|
1268
1303
|
function N(n, e) {
|
|
1269
|
-
if (typeof e != "string" || !
|
|
1270
|
-
throw new
|
|
1304
|
+
if (typeof e != "string" || !Mt.test(e))
|
|
1305
|
+
throw new c(
|
|
1271
1306
|
"validation_failed",
|
|
1272
|
-
`${n} must match ${
|
|
1307
|
+
`${n} must match ${Mt.source} (lowercase alphanumeric, _, -; first char must be alphanumeric; max 63 chars)`
|
|
1273
1308
|
);
|
|
1274
1309
|
}
|
|
1275
1310
|
|
|
1276
1311
|
// src/usage.ts
|
|
1277
|
-
function
|
|
1312
|
+
function qt(n) {
|
|
1278
1313
|
return {
|
|
1279
1314
|
/**
|
|
1280
1315
|
* Reporta consumo metered de um resource. Hit no endpoint canônico
|
|
@@ -1290,17 +1325,17 @@ function Ut(n) {
|
|
|
1290
1325
|
*/
|
|
1291
1326
|
async report(e, t = 1, r) {
|
|
1292
1327
|
if (!e || typeof e != "string")
|
|
1293
|
-
throw new
|
|
1328
|
+
throw new c("validation_failed", "resource is required");
|
|
1294
1329
|
if (!Number.isFinite(t) || t <= 0 || !Number.isInteger(t))
|
|
1295
|
-
throw new
|
|
1330
|
+
throw new c("validation_failed", "qty must be a positive integer");
|
|
1296
1331
|
let o = r?.productId ?? n.productId, i = r?.tenantId ?? n.tenantId;
|
|
1297
1332
|
if (!o)
|
|
1298
|
-
throw new
|
|
1333
|
+
throw new c(
|
|
1299
1334
|
"validation_failed",
|
|
1300
1335
|
"productId required (pass to options or set on createNeetruClient)"
|
|
1301
1336
|
);
|
|
1302
1337
|
if (!i)
|
|
1303
|
-
throw new
|
|
1338
|
+
throw new c(
|
|
1304
1339
|
"validation_failed",
|
|
1305
1340
|
"tenantId required (pass to options or set on createNeetruClient)"
|
|
1306
1341
|
);
|
|
@@ -1313,7 +1348,7 @@ function Ut(n) {
|
|
|
1313
1348
|
idempotencyKey: true
|
|
1314
1349
|
});
|
|
1315
1350
|
if (!s || s.ok !== true)
|
|
1316
|
-
throw new
|
|
1351
|
+
throw new c("invalid_response", "usage.report response missing ok");
|
|
1317
1352
|
return {
|
|
1318
1353
|
ok: true,
|
|
1319
1354
|
counterId: s.counterId,
|
|
@@ -1331,10 +1366,10 @@ function Ut(n) {
|
|
|
1331
1366
|
*/
|
|
1332
1367
|
async check(e, t) {
|
|
1333
1368
|
if (!e || typeof e != "string")
|
|
1334
|
-
throw new
|
|
1369
|
+
throw new c("validation_failed", "resource is required");
|
|
1335
1370
|
let r = t?.productId ?? n.productId, o = t?.tenantId ?? n.tenantId;
|
|
1336
1371
|
if (!r || !o)
|
|
1337
|
-
throw new
|
|
1372
|
+
throw new c(
|
|
1338
1373
|
"validation_failed",
|
|
1339
1374
|
"productId and tenantId required (pass to options or set on createNeetruClient)"
|
|
1340
1375
|
);
|
|
@@ -1346,7 +1381,7 @@ function Ut(n) {
|
|
|
1346
1381
|
requireAuth: true
|
|
1347
1382
|
});
|
|
1348
1383
|
if (!i || typeof i.allowed != "boolean")
|
|
1349
|
-
throw new
|
|
1384
|
+
throw new c("invalid_response", "usage.check response missing allowed");
|
|
1350
1385
|
let s = i.behavior ?? (i.reason === "limit_exceeded" ? "readonly" : null);
|
|
1351
1386
|
return {
|
|
1352
1387
|
allowed: i.allowed,
|
|
@@ -1362,22 +1397,22 @@ function Ut(n) {
|
|
|
1362
1397
|
}
|
|
1363
1398
|
|
|
1364
1399
|
// src/support.ts
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
var
|
|
1368
|
-
function
|
|
1400
|
+
C();
|
|
1401
|
+
F();
|
|
1402
|
+
var We = ["low", "normal", "high", "urgent"], Tr = ["open", "pending", "resolved", "closed"], Ft = 50;
|
|
1403
|
+
function jt(n) {
|
|
1369
1404
|
if (!n || typeof n != "object")
|
|
1370
|
-
throw new
|
|
1405
|
+
throw new c("invalid_response", "Ticket response is not an object");
|
|
1371
1406
|
let e = n;
|
|
1372
1407
|
if (typeof e.id != "string")
|
|
1373
|
-
throw new
|
|
1408
|
+
throw new c("invalid_response", "Ticket missing id");
|
|
1374
1409
|
let t = Array.isArray(e.attachments) && typeof e.attachments[0] == "string" ? e.attachments[0] : void 0, r = typeof e.screenshotUrl == "string" ? e.screenshotUrl : t ?? null;
|
|
1375
1410
|
return {
|
|
1376
1411
|
id: e.id,
|
|
1377
1412
|
subject: typeof e.subject == "string" ? e.subject : "",
|
|
1378
1413
|
message: typeof e.message == "string" ? e.message : "",
|
|
1379
|
-
severity:
|
|
1380
|
-
status:
|
|
1414
|
+
severity: We.includes(e.severity) ? e.severity : "normal",
|
|
1415
|
+
status: Tr.includes(e.status) ? e.status : "open",
|
|
1381
1416
|
createdAt: typeof e.createdAt == "string" ? e.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
|
|
1382
1417
|
updatedAt: typeof e.updatedAt == "string" ? e.updatedAt : void 0,
|
|
1383
1418
|
productSlug: typeof e.productId == "string" ? e.productId : typeof e.productSlug == "string" ? e.productSlug : void 0,
|
|
@@ -1395,48 +1430,48 @@ function qt(n) {
|
|
|
1395
1430
|
satisfactionComment: typeof e.satisfactionComment == "string" ? e.satisfactionComment : null
|
|
1396
1431
|
};
|
|
1397
1432
|
}
|
|
1398
|
-
function
|
|
1433
|
+
function ue(n) {
|
|
1399
1434
|
if (!n || typeof n != "string")
|
|
1400
|
-
throw new
|
|
1435
|
+
throw new c("validation_failed", "ticketId is required");
|
|
1401
1436
|
}
|
|
1402
|
-
function
|
|
1437
|
+
function $t(n) {
|
|
1403
1438
|
if (typeof n == "string" && n.length > 2e3)
|
|
1404
|
-
throw new
|
|
1439
|
+
throw new c("validation_failed", "comment max 2000 chars");
|
|
1405
1440
|
}
|
|
1406
|
-
function
|
|
1441
|
+
function Wt(n, ...e) {
|
|
1407
1442
|
for (let t of e)
|
|
1408
1443
|
if (typeof t == "string" && t.length > 0)
|
|
1409
1444
|
return N("productSlug", t), t;
|
|
1410
1445
|
if (n.productId)
|
|
1411
1446
|
return N("productId", n.productId), n.productId;
|
|
1412
|
-
throw new
|
|
1447
|
+
throw new c(
|
|
1413
1448
|
"validation_failed",
|
|
1414
1449
|
"productId required (pass to input.productSlug or set on createNeetruClient)"
|
|
1415
1450
|
);
|
|
1416
1451
|
}
|
|
1417
|
-
var
|
|
1418
|
-
function
|
|
1419
|
-
if (n instanceof
|
|
1452
|
+
var Rr = "X-Neetru-End-User-Token", Ir = "Esta opera\xE7\xE3o de suporte exige um usu\xE1rio final logado: o Core s\xF3 mostra/altera os tickets do pr\xF3prio usu\xE1rio (header X-Neetru-End-User-Token com o id_token OIDC). Fa\xE7a login com client.auth.signIn() e tente de novo.", Cr = "O Core exige a identidade do usu\xE1rio final para esta opera\xE7\xE3o (403 end_user_token_required) e nenhum id_token foi aceito. Fa\xE7a login com client.auth.signIn() e tente de novo.", Ar = "O Core recusou o token do usu\xE1rio final (401 invalid_end_user_token \u2014 sess\xE3o expirada, usu\xE1rio inativo ou token que n\xE3o \xE9 id_token) e a renova\xE7\xE3o autom\xE1tica n\xE3o resolveu. Fa\xE7a login novamente com client.auth.signIn() e tente de novo.", Er = "O id_token do usu\xE1rio final foi emitido para o client OIDC de OUTRO produto (403 end_user_token_product_mismatch). Confira se o login (client.auth / clientId OIDC) e a apiKey/productId do createNeetruClient s\xE3o do MESMO produto.";
|
|
1453
|
+
function Bt(n) {
|
|
1454
|
+
if (n instanceof c && !(n instanceof K)) {
|
|
1420
1455
|
if (n.code === "end_user_token_required")
|
|
1421
|
-
throw new
|
|
1422
|
-
|
|
1456
|
+
throw new K(
|
|
1457
|
+
Cr,
|
|
1423
1458
|
"end_user_token_required",
|
|
1424
1459
|
n.status,
|
|
1425
1460
|
n.requestId,
|
|
1426
1461
|
n.correlationId
|
|
1427
1462
|
);
|
|
1428
1463
|
if (n.code === "invalid_end_user_token")
|
|
1429
|
-
throw new
|
|
1430
|
-
|
|
1464
|
+
throw new K(
|
|
1465
|
+
Ar,
|
|
1431
1466
|
"invalid_end_user_token",
|
|
1432
1467
|
n.status,
|
|
1433
1468
|
n.requestId,
|
|
1434
1469
|
n.correlationId
|
|
1435
1470
|
);
|
|
1436
1471
|
if (n.code === "end_user_token_product_mismatch")
|
|
1437
|
-
throw new
|
|
1472
|
+
throw new c(
|
|
1438
1473
|
"forbidden",
|
|
1439
|
-
|
|
1474
|
+
Er,
|
|
1440
1475
|
n.status,
|
|
1441
1476
|
n.requestId,
|
|
1442
1477
|
"end_user_token_product_mismatch",
|
|
@@ -1445,10 +1480,10 @@ function $t(n) {
|
|
|
1445
1480
|
}
|
|
1446
1481
|
throw n;
|
|
1447
1482
|
}
|
|
1448
|
-
function
|
|
1449
|
-
return n instanceof
|
|
1483
|
+
function Pr(n) {
|
|
1484
|
+
return n instanceof c && n.code === "invalid_end_user_token";
|
|
1450
1485
|
}
|
|
1451
|
-
function
|
|
1486
|
+
function Vt(n, e = {}) {
|
|
1452
1487
|
async function t() {
|
|
1453
1488
|
try {
|
|
1454
1489
|
let a = await e.getEndUserToken?.();
|
|
@@ -1466,28 +1501,28 @@ function Wt(n, e = {}) {
|
|
|
1466
1501
|
}
|
|
1467
1502
|
}
|
|
1468
1503
|
function o(a) {
|
|
1469
|
-
return a ? { [
|
|
1504
|
+
return a ? { [Rr]: a } : {};
|
|
1470
1505
|
}
|
|
1471
|
-
async function i(a,
|
|
1506
|
+
async function i(a, l) {
|
|
1472
1507
|
let d = await t();
|
|
1473
1508
|
if (!d && a && await r() && (d = await t()), !d && a)
|
|
1474
|
-
throw new
|
|
1509
|
+
throw new K(Ir, "no_signed_in_user");
|
|
1475
1510
|
try {
|
|
1476
|
-
return await
|
|
1511
|
+
return await l(o(d));
|
|
1477
1512
|
} catch (u) {
|
|
1478
|
-
if (d &&
|
|
1513
|
+
if (d && Pr(u) && await r()) {
|
|
1479
1514
|
let p = await t();
|
|
1480
1515
|
if (p)
|
|
1481
1516
|
try {
|
|
1482
|
-
return await
|
|
1517
|
+
return await l(o(p));
|
|
1483
1518
|
} catch (f) {
|
|
1484
|
-
|
|
1519
|
+
Bt(f);
|
|
1485
1520
|
}
|
|
1486
1521
|
}
|
|
1487
|
-
|
|
1522
|
+
Bt(u);
|
|
1488
1523
|
}
|
|
1489
1524
|
}
|
|
1490
|
-
async function s(a,
|
|
1525
|
+
async function s(a, l = {}) {
|
|
1491
1526
|
await i(
|
|
1492
1527
|
true,
|
|
1493
1528
|
(d) => v(n, {
|
|
@@ -1495,7 +1530,7 @@ function Wt(n, e = {}) {
|
|
|
1495
1530
|
path: a,
|
|
1496
1531
|
requireAuth: !0,
|
|
1497
1532
|
headers: d,
|
|
1498
|
-
...
|
|
1533
|
+
...l
|
|
1499
1534
|
})
|
|
1500
1535
|
);
|
|
1501
1536
|
}
|
|
@@ -1508,22 +1543,22 @@ function Wt(n, e = {}) {
|
|
|
1508
1543
|
*/
|
|
1509
1544
|
async createTicket(a) {
|
|
1510
1545
|
if (!a || typeof a != "object")
|
|
1511
|
-
throw new
|
|
1546
|
+
throw new c("validation_failed", "input is required");
|
|
1512
1547
|
if (!a.subject || typeof a.subject != "string")
|
|
1513
|
-
throw new
|
|
1548
|
+
throw new c("validation_failed", "subject is required");
|
|
1514
1549
|
if (a.subject.length > 200)
|
|
1515
|
-
throw new
|
|
1550
|
+
throw new c("validation_failed", "subject max 200 chars");
|
|
1516
1551
|
if (!a.message || typeof a.message != "string")
|
|
1517
|
-
throw new
|
|
1552
|
+
throw new c("validation_failed", "message is required");
|
|
1518
1553
|
if (a.message.length > 1e4)
|
|
1519
|
-
throw new
|
|
1520
|
-
if (a.severity && !
|
|
1521
|
-
throw new
|
|
1554
|
+
throw new c("validation_failed", "message max 10000 chars");
|
|
1555
|
+
if (a.severity && !We.includes(a.severity))
|
|
1556
|
+
throw new c(
|
|
1522
1557
|
"validation_failed",
|
|
1523
|
-
`severity must be one of ${
|
|
1558
|
+
`severity must be one of ${We.join(", ")}`
|
|
1524
1559
|
);
|
|
1525
1560
|
let d = {
|
|
1526
|
-
productId:
|
|
1561
|
+
productId: Wt(n, a.productSlug),
|
|
1527
1562
|
subject: a.subject,
|
|
1528
1563
|
message: a.message,
|
|
1529
1564
|
severity: a.severity ?? "normal"
|
|
@@ -1540,7 +1575,7 @@ function Wt(n, e = {}) {
|
|
|
1540
1575
|
headers: f
|
|
1541
1576
|
})
|
|
1542
1577
|
), p = u && typeof u == "object" && "ticket" in u ? u.ticket : u;
|
|
1543
|
-
return
|
|
1578
|
+
return jt(p);
|
|
1544
1579
|
},
|
|
1545
1580
|
/**
|
|
1546
1581
|
* Lista tickets do customer no produto atual. `productSlug` no contexto.
|
|
@@ -1548,23 +1583,23 @@ function Wt(n, e = {}) {
|
|
|
1548
1583
|
* Endpoint canonical: `GET /api/sdk/v1/support/tickets?productId=...`.
|
|
1549
1584
|
*/
|
|
1550
1585
|
async listMyTickets(a) {
|
|
1551
|
-
let
|
|
1552
|
-
if (d !== void 0 && (!Number.isInteger(d) || d < 1 || d >
|
|
1553
|
-
throw new
|
|
1586
|
+
let l = Wt(n, a?.productSlug), d = a?.limit;
|
|
1587
|
+
if (d !== void 0 && (!Number.isInteger(d) || d < 1 || d > Ft))
|
|
1588
|
+
throw new c(
|
|
1554
1589
|
"validation_failed",
|
|
1555
|
-
`limit must be an integer 1-${
|
|
1590
|
+
`limit must be an integer 1-${Ft} (Core default 20)`
|
|
1556
1591
|
);
|
|
1557
1592
|
let u = await i(
|
|
1558
1593
|
true,
|
|
1559
1594
|
(f) => v(n, {
|
|
1560
1595
|
method: "GET",
|
|
1561
1596
|
path: "/api/sdk/v1/support/tickets",
|
|
1562
|
-
query: { productId:
|
|
1597
|
+
query: { productId: l, limit: d },
|
|
1563
1598
|
requireAuth: !0,
|
|
1564
1599
|
headers: f
|
|
1565
1600
|
})
|
|
1566
1601
|
);
|
|
1567
|
-
return (Array.isArray(u) ? u : u && typeof u == "object" && "tickets" in u ? u.tickets ?? [] : []).map(
|
|
1602
|
+
return (Array.isArray(u) ? u : u && typeof u == "object" && "tickets" in u ? u.tickets ?? [] : []).map(jt);
|
|
1568
1603
|
},
|
|
1569
1604
|
/**
|
|
1570
1605
|
* 3.4: marca a notificação de resolução como vista (`resolvedNotifiedAt`,
|
|
@@ -1572,7 +1607,7 @@ function Wt(n, e = {}) {
|
|
|
1572
1607
|
* `POST /api/sdk/v1/support/tickets/{id}/resolved-seen`.
|
|
1573
1608
|
*/
|
|
1574
1609
|
async markResolvedSeen(a) {
|
|
1575
|
-
|
|
1610
|
+
ue(a), await s(
|
|
1576
1611
|
`/api/sdk/v1/support/tickets/${encodeURIComponent(a)}/resolved-seen`
|
|
1577
1612
|
);
|
|
1578
1613
|
},
|
|
@@ -1583,7 +1618,7 @@ function Wt(n, e = {}) {
|
|
|
1583
1618
|
* `POST /api/sdk/v1/support/tickets/{id}/satisfaction-attempt`.
|
|
1584
1619
|
*/
|
|
1585
1620
|
async recordSatisfactionAttempt(a) {
|
|
1586
|
-
|
|
1621
|
+
ue(a), await s(
|
|
1587
1622
|
`/api/sdk/v1/support/tickets/${encodeURIComponent(a)}/satisfaction-attempt`,
|
|
1588
1623
|
// Incrementa satisfactionAttempts += 1 no Core — sem idempotencyKey,
|
|
1589
1624
|
// um retry de rede infla o contador (mesmo padrão de createTicket acima).
|
|
@@ -1596,10 +1631,10 @@ function Wt(n, e = {}) {
|
|
|
1596
1631
|
*/
|
|
1597
1632
|
async submitSatisfaction(a) {
|
|
1598
1633
|
if (!a || typeof a != "object")
|
|
1599
|
-
throw new
|
|
1600
|
-
if (
|
|
1601
|
-
throw new
|
|
1602
|
-
|
|
1634
|
+
throw new c("validation_failed", "input is required");
|
|
1635
|
+
if (ue(a.ticketId), a.rating !== null && a.rating !== void 0 && (!Number.isInteger(a.rating) || a.rating < 1 || a.rating > 5))
|
|
1636
|
+
throw new c("validation_failed", "rating must be an integer 1-5 or null");
|
|
1637
|
+
$t(a.comment), await s(
|
|
1603
1638
|
`/api/sdk/v1/support/tickets/${encodeURIComponent(a.ticketId)}/satisfaction`,
|
|
1604
1639
|
{
|
|
1605
1640
|
body: {
|
|
@@ -1615,24 +1650,24 @@ function Wt(n, e = {}) {
|
|
|
1615
1650
|
* satisfação/notificação. Endpoint canonical:
|
|
1616
1651
|
* `POST /api/sdk/v1/support/tickets/{id}/contest`.
|
|
1617
1652
|
*/
|
|
1618
|
-
async contestTicket(a,
|
|
1619
|
-
|
|
1653
|
+
async contestTicket(a, l) {
|
|
1654
|
+
ue(a), $t(l?.comment), await s(
|
|
1620
1655
|
`/api/sdk/v1/support/tickets/${encodeURIComponent(a)}/contest`,
|
|
1621
|
-
{ body: { comment:
|
|
1656
|
+
{ body: { comment: l?.comment ?? void 0 } }
|
|
1622
1657
|
);
|
|
1623
1658
|
}
|
|
1624
1659
|
};
|
|
1625
1660
|
}
|
|
1626
1661
|
|
|
1627
1662
|
// src/db/client-db.ts
|
|
1628
|
-
|
|
1663
|
+
ee();
|
|
1629
1664
|
|
|
1630
1665
|
// src/db/offline/query-engine.ts
|
|
1631
|
-
function
|
|
1666
|
+
function Kt(n) {
|
|
1632
1667
|
return n == null ? 0 : typeof n == "number" ? 1 : typeof n == "string" ? 2 : typeof n == "boolean" ? 3 : 4;
|
|
1633
1668
|
}
|
|
1634
|
-
function
|
|
1635
|
-
let t =
|
|
1669
|
+
function te(n, e) {
|
|
1670
|
+
let t = Kt(n), r = Kt(e);
|
|
1636
1671
|
if (t !== r) return t - r;
|
|
1637
1672
|
if (n == null) return 0;
|
|
1638
1673
|
if (typeof n == "number" && typeof e == "number") return n - e;
|
|
@@ -1641,7 +1676,7 @@ function ee(n, e) {
|
|
|
1641
1676
|
let o = String(n), i = String(e);
|
|
1642
1677
|
return o < i ? -1 : o > i ? 1 : 0;
|
|
1643
1678
|
}
|
|
1644
|
-
function
|
|
1679
|
+
function Be(n, e) {
|
|
1645
1680
|
let t = e.split("."), r = n;
|
|
1646
1681
|
for (let o of t) {
|
|
1647
1682
|
if (r == null || typeof r != "object")
|
|
@@ -1650,8 +1685,8 @@ function $e(n, e) {
|
|
|
1650
1685
|
}
|
|
1651
1686
|
return r;
|
|
1652
1687
|
}
|
|
1653
|
-
function
|
|
1654
|
-
let t =
|
|
1688
|
+
function Nr(n, e) {
|
|
1689
|
+
let t = Be(n, e.field);
|
|
1655
1690
|
if (t === void 0) return false;
|
|
1656
1691
|
let { op: r, value: o } = e;
|
|
1657
1692
|
switch (r) {
|
|
@@ -1660,13 +1695,13 @@ function Ir(n, e) {
|
|
|
1660
1695
|
case "!=":
|
|
1661
1696
|
return t !== o;
|
|
1662
1697
|
case "<":
|
|
1663
|
-
return
|
|
1698
|
+
return te(t, o) < 0;
|
|
1664
1699
|
case "<=":
|
|
1665
|
-
return
|
|
1700
|
+
return te(t, o) <= 0;
|
|
1666
1701
|
case ">":
|
|
1667
|
-
return
|
|
1702
|
+
return te(t, o) > 0;
|
|
1668
1703
|
case ">=":
|
|
1669
|
-
return
|
|
1704
|
+
return te(t, o) >= 0;
|
|
1670
1705
|
case "array-contains":
|
|
1671
1706
|
return Array.isArray(t) && t.includes(o);
|
|
1672
1707
|
case "in":
|
|
@@ -1681,24 +1716,24 @@ function Ir(n, e) {
|
|
|
1681
1716
|
);
|
|
1682
1717
|
}
|
|
1683
1718
|
}
|
|
1684
|
-
function
|
|
1685
|
-
return e.every((t) =>
|
|
1719
|
+
function xr(n, e) {
|
|
1720
|
+
return e.every((t) => Nr(n, t));
|
|
1686
1721
|
}
|
|
1687
|
-
function
|
|
1722
|
+
function Or(n) {
|
|
1688
1723
|
return (e, t) => {
|
|
1689
1724
|
if (n) {
|
|
1690
|
-
let r =
|
|
1725
|
+
let r = Be(e.data, n.field), o = Be(t.data, n.field), i = te(r, o);
|
|
1691
1726
|
if (i !== 0)
|
|
1692
1727
|
return n.direction === "desc" ? -i : i;
|
|
1693
1728
|
}
|
|
1694
1729
|
return e.id < t.id ? -1 : e.id > t.id ? 1 : 0;
|
|
1695
1730
|
};
|
|
1696
1731
|
}
|
|
1697
|
-
function
|
|
1732
|
+
function Lr(n, e) {
|
|
1698
1733
|
let t = n.findIndex((r) => r.id === e.docId);
|
|
1699
1734
|
return t === -1 ? n : e.type === "startAfter" ? n.slice(t + 1) : n.slice(0, t);
|
|
1700
1735
|
}
|
|
1701
|
-
var
|
|
1736
|
+
var H = class n {
|
|
1702
1737
|
/**
|
|
1703
1738
|
* Avalia um `QueryDescriptor` contra um array de `OfflineDoc`.
|
|
1704
1739
|
*
|
|
@@ -1712,11 +1747,11 @@ var z = class n {
|
|
|
1712
1747
|
evaluate(e, t) {
|
|
1713
1748
|
let r = e.filter((u) => !u.meta.deleted), o = t.where ?? [];
|
|
1714
1749
|
o.length > 0 && (r = r.filter(
|
|
1715
|
-
(u) =>
|
|
1750
|
+
(u) => xr(u.data, o)
|
|
1716
1751
|
));
|
|
1717
|
-
let i =
|
|
1752
|
+
let i = Or(t.orderBy), s = [...r].sort(i), a = t.cursor ? Lr(s, t.cursor) : s, l = Math.min(t.limit ?? 20, 500);
|
|
1718
1753
|
return {
|
|
1719
|
-
docs: a.slice(0,
|
|
1754
|
+
docs: a.slice(0, l).map((u) => ({ id: u.id, data: u.data })),
|
|
1720
1755
|
// `incomplete` é sempre true aqui — o QueryEngine não sabe se o cache
|
|
1721
1756
|
// tem todos os docs da coleção. É responsabilidade do chamador (LocalStore)
|
|
1722
1757
|
// injetar o flag de completude baseado nos metadados do query_cache.
|
|
@@ -1734,7 +1769,7 @@ var z = class n {
|
|
|
1734
1769
|
};
|
|
1735
1770
|
|
|
1736
1771
|
// src/db/offline/local-store.ts
|
|
1737
|
-
var
|
|
1772
|
+
var Mr = 1, B = "documents", V = "mutations", ne = "query_cache", pe = "sync_meta", Q = "conflict_log", fe = class {
|
|
1738
1773
|
db = null;
|
|
1739
1774
|
dbName;
|
|
1740
1775
|
constructor(e) {
|
|
@@ -1746,22 +1781,22 @@ var Dr = 1, W = "documents", B = "mutations", te = "query_cache", ue = "sync_met
|
|
|
1746
1781
|
* Idempotente — chamadas subsequentes são no-ops se o banco já está aberto.
|
|
1747
1782
|
*/
|
|
1748
1783
|
async open() {
|
|
1749
|
-
this.db === null && (this.db = await idb.openDB(this.dbName,
|
|
1784
|
+
this.db === null && (this.db = await idb.openDB(this.dbName, Mr, {
|
|
1750
1785
|
upgrade(e) {
|
|
1751
|
-
if (!e.objectStoreNames.contains(
|
|
1752
|
-
let t = e.createObjectStore(
|
|
1786
|
+
if (!e.objectStoreNames.contains(B)) {
|
|
1787
|
+
let t = e.createObjectStore(B, {
|
|
1753
1788
|
keyPath: ["collection", "id"]
|
|
1754
1789
|
});
|
|
1755
1790
|
t.createIndex("by_collection", "collection"), t.createIndex("by_collection_state", ["collection", "meta.state"]), t.createIndex("by_updatedAtServer", "meta.updatedAtServer");
|
|
1756
1791
|
}
|
|
1757
|
-
if (!e.objectStoreNames.contains(
|
|
1758
|
-
let t = e.createObjectStore(
|
|
1792
|
+
if (!e.objectStoreNames.contains(V)) {
|
|
1793
|
+
let t = e.createObjectStore(V, {
|
|
1759
1794
|
keyPath: "mutationId"
|
|
1760
1795
|
});
|
|
1761
1796
|
t.createIndex("by_seq", "seq"), t.createIndex("by_status", "status"), t.createIndex("by_doc", ["collection", "docId"]), t.createIndex("by_batch", "batchId");
|
|
1762
1797
|
}
|
|
1763
|
-
if (e.objectStoreNames.contains(
|
|
1764
|
-
let t = e.createObjectStore(
|
|
1798
|
+
if (e.objectStoreNames.contains(ne) || e.createObjectStore(ne, { keyPath: "queryHash" }), e.objectStoreNames.contains(pe) || e.createObjectStore(pe, { keyPath: "key" }), !e.objectStoreNames.contains(Q)) {
|
|
1799
|
+
let t = e.createObjectStore(Q, {
|
|
1765
1800
|
keyPath: "id",
|
|
1766
1801
|
autoIncrement: true
|
|
1767
1802
|
});
|
|
@@ -1803,14 +1838,14 @@ var Dr = 1, W = "documents", B = "mutations", te = "query_cache", ue = "sync_met
|
|
|
1803
1838
|
* Retorna tombstones (deleted: true) — o chamador decide se deve mostrá-los.
|
|
1804
1839
|
*/
|
|
1805
1840
|
async getDoc(e, t) {
|
|
1806
|
-
return await this.assertOpen().get(
|
|
1841
|
+
return await this.assertOpen().get(B, [e, t]) ?? null;
|
|
1807
1842
|
}
|
|
1808
1843
|
/**
|
|
1809
1844
|
* Insere ou atualiza um documento na store `documents`.
|
|
1810
1845
|
* O documento é identificado pelo keyPath composto `[collection, id]`.
|
|
1811
1846
|
*/
|
|
1812
1847
|
async putDoc(e) {
|
|
1813
|
-
await this.assertOpen().put(
|
|
1848
|
+
await this.assertOpen().put(B, e);
|
|
1814
1849
|
}
|
|
1815
1850
|
/**
|
|
1816
1851
|
* Marca um documento como tombstone (`deleted: true`).
|
|
@@ -1818,8 +1853,8 @@ var Dr = 1, W = "documents", B = "mutations", te = "query_cache", ue = "sync_met
|
|
|
1818
1853
|
* No-op se o documento não existir.
|
|
1819
1854
|
*/
|
|
1820
1855
|
async deleteDoc(e, t) {
|
|
1821
|
-
let r = this.assertOpen(), o = await r.get(
|
|
1822
|
-
o && await r.put(
|
|
1856
|
+
let r = this.assertOpen(), o = await r.get(B, [e, t]);
|
|
1857
|
+
o && await r.put(B, {
|
|
1823
1858
|
...o,
|
|
1824
1859
|
meta: {
|
|
1825
1860
|
...o.meta,
|
|
@@ -1835,8 +1870,8 @@ var Dr = 1, W = "documents", B = "mutations", te = "query_cache", ue = "sync_met
|
|
|
1835
1870
|
* e delega a filtragem/ordenação/paginação ao QueryEngine (que opera em memória).
|
|
1836
1871
|
*/
|
|
1837
1872
|
async listDocs(e, t) {
|
|
1838
|
-
let o = await this.assertOpen().getAllFromIndex(
|
|
1839
|
-
return
|
|
1873
|
+
let o = await this.assertOpen().getAllFromIndex(B, "by_collection", e);
|
|
1874
|
+
return H.evaluate(o, t);
|
|
1840
1875
|
}
|
|
1841
1876
|
// ─── Sync meta (key-value) ──────────────────────────────────────────────────
|
|
1842
1877
|
/**
|
|
@@ -1847,14 +1882,14 @@ var Dr = 1, W = "documents", B = "mutations", te = "query_cache", ue = "sync_met
|
|
|
1847
1882
|
* 'lastFullResyncAt', 'leaderTabId'.
|
|
1848
1883
|
*/
|
|
1849
1884
|
async getMeta(e) {
|
|
1850
|
-
let r = await this.assertOpen().get(
|
|
1885
|
+
let r = await this.assertOpen().get(pe, e);
|
|
1851
1886
|
return r ? r.value : null;
|
|
1852
1887
|
}
|
|
1853
1888
|
/**
|
|
1854
1889
|
* Armazena ou atualiza um valor na store `sync_meta`.
|
|
1855
1890
|
*/
|
|
1856
1891
|
async setMeta(e, t) {
|
|
1857
|
-
await this.assertOpen().put(
|
|
1892
|
+
await this.assertOpen().put(pe, { key: e, value: t });
|
|
1858
1893
|
}
|
|
1859
1894
|
// ─── Conflict log ───────────────────────────────────────────────────────────
|
|
1860
1895
|
/**
|
|
@@ -1862,7 +1897,7 @@ var Dr = 1, W = "documents", B = "mutations", te = "query_cache", ue = "sync_met
|
|
|
1862
1897
|
* O `id` é autoIncrement — não deve ser fornecido pelo chamador.
|
|
1863
1898
|
*/
|
|
1864
1899
|
async appendConflict(e) {
|
|
1865
|
-
let r = await this.assertOpen().add(
|
|
1900
|
+
let r = await this.assertOpen().add(Q, e);
|
|
1866
1901
|
return { ...e, id: r };
|
|
1867
1902
|
}
|
|
1868
1903
|
/**
|
|
@@ -1870,15 +1905,15 @@ var Dr = 1, W = "documents", B = "mutations", te = "query_cache", ue = "sync_met
|
|
|
1870
1905
|
* Filtra por `delivered` se a opção for fornecida.
|
|
1871
1906
|
*/
|
|
1872
1907
|
async listConflicts(e) {
|
|
1873
|
-
let r = await this.assertOpen().getAll(
|
|
1908
|
+
let r = await this.assertOpen().getAll(Q);
|
|
1874
1909
|
return e?.delivered !== void 0 ? r.filter((o) => o.delivered === e.delivered) : r;
|
|
1875
1910
|
}
|
|
1876
1911
|
/**
|
|
1877
1912
|
* Marca um registro do `conflict_log` como entregue ao produto.
|
|
1878
1913
|
*/
|
|
1879
1914
|
async markConflictDelivered(e) {
|
|
1880
|
-
let t = this.assertOpen(), r = await t.get(
|
|
1881
|
-
r && await t.put(
|
|
1915
|
+
let t = this.assertOpen(), r = await t.get(Q, e);
|
|
1916
|
+
r && await t.put(Q, { ...r, delivered: true });
|
|
1882
1917
|
}
|
|
1883
1918
|
// ─── Mutations (acessores usados pelo MutationQueue) ────────────────────────
|
|
1884
1919
|
/**
|
|
@@ -1886,13 +1921,13 @@ var Dr = 1, W = "documents", B = "mutations", te = "query_cache", ue = "sync_met
|
|
|
1886
1921
|
* Key: `mutationId`.
|
|
1887
1922
|
*/
|
|
1888
1923
|
async putMutation(e) {
|
|
1889
|
-
await this.assertOpen().put(
|
|
1924
|
+
await this.assertOpen().put(V, e);
|
|
1890
1925
|
}
|
|
1891
1926
|
/**
|
|
1892
1927
|
* Retorna uma mutação pelo `mutationId`, ou `null` se não existir.
|
|
1893
1928
|
*/
|
|
1894
1929
|
async getMutation(e) {
|
|
1895
|
-
return await this.assertOpen().get(
|
|
1930
|
+
return await this.assertOpen().get(V, e) ?? null;
|
|
1896
1931
|
}
|
|
1897
1932
|
/**
|
|
1898
1933
|
* Lista mutações com filtros opcionais.
|
|
@@ -1900,14 +1935,14 @@ var Dr = 1, W = "documents", B = "mutations", te = "query_cache", ue = "sync_met
|
|
|
1900
1935
|
*/
|
|
1901
1936
|
async listMutations(e) {
|
|
1902
1937
|
let t = this.assertOpen(), r;
|
|
1903
|
-
return e?.status !== void 0 ? r = await t.getAllFromIndex(
|
|
1938
|
+
return e?.status !== void 0 ? r = await t.getAllFromIndex(V, "by_status", e.status) : e?.collection !== void 0 && e.docId !== void 0 ? r = await t.getAllFromIndex(V, "by_doc", [e.collection, e.docId]) : r = await t.getAllFromIndex(V, "by_seq"), r.sort((o, i) => o.seq - i.seq);
|
|
1904
1939
|
}
|
|
1905
1940
|
/**
|
|
1906
1941
|
* Remove uma mutação pelo `mutationId`.
|
|
1907
1942
|
* No-op se não existir.
|
|
1908
1943
|
*/
|
|
1909
1944
|
async deleteMutation(e) {
|
|
1910
|
-
await this.assertOpen().delete(
|
|
1945
|
+
await this.assertOpen().delete(V, e);
|
|
1911
1946
|
}
|
|
1912
1947
|
// ─── Collection discovery ────────────────────────────────────────────────────
|
|
1913
1948
|
/**
|
|
@@ -1920,7 +1955,7 @@ var Dr = 1, W = "documents", B = "mutations", te = "query_cache", ue = "sync_met
|
|
|
1920
1955
|
* coletar os valores únicos de forma eficiente (sem carregar os docs completos).
|
|
1921
1956
|
*/
|
|
1922
1957
|
async listCollections() {
|
|
1923
|
-
let t = await this.assertOpen().getAllFromIndex(
|
|
1958
|
+
let t = await this.assertOpen().getAllFromIndex(B, "by_collection"), r = /* @__PURE__ */ new Set();
|
|
1924
1959
|
for (let o of t)
|
|
1925
1960
|
r.add(o.collection);
|
|
1926
1961
|
return Array.from(r);
|
|
@@ -1930,24 +1965,24 @@ var Dr = 1, W = "documents", B = "mutations", te = "query_cache", ue = "sync_met
|
|
|
1930
1965
|
* Retorna a entrada de `query_cache` para um hash de query, ou `null`.
|
|
1931
1966
|
*/
|
|
1932
1967
|
async getQueryCache(e) {
|
|
1933
|
-
return await this.assertOpen().get(
|
|
1968
|
+
return await this.assertOpen().get(ne, e) ?? null;
|
|
1934
1969
|
}
|
|
1935
1970
|
/**
|
|
1936
1971
|
* Insere ou atualiza uma entrada de `query_cache`.
|
|
1937
1972
|
*/
|
|
1938
1973
|
async putQueryCache(e) {
|
|
1939
|
-
await this.assertOpen().put(
|
|
1974
|
+
await this.assertOpen().put(ne, e);
|
|
1940
1975
|
}
|
|
1941
1976
|
/**
|
|
1942
1977
|
* Remove uma entrada de `query_cache` pelo queryHash.
|
|
1943
1978
|
*/
|
|
1944
1979
|
async deleteQueryCache(e) {
|
|
1945
|
-
await this.assertOpen().delete(
|
|
1980
|
+
await this.assertOpen().delete(ne, e);
|
|
1946
1981
|
}
|
|
1947
1982
|
};
|
|
1948
1983
|
|
|
1949
1984
|
// src/db/offline/memory-store.ts
|
|
1950
|
-
var
|
|
1985
|
+
var me = class {
|
|
1951
1986
|
// store `documents` — key: `${collection}\0${id}`
|
|
1952
1987
|
_docs = /* @__PURE__ */ new Map();
|
|
1953
1988
|
// store `mutations` — key: mutationId
|
|
@@ -1995,7 +2030,7 @@ var fe = class {
|
|
|
1995
2030
|
let r = Array.from(this._docs.values()).filter(
|
|
1996
2031
|
(o) => o.collection === e
|
|
1997
2032
|
);
|
|
1998
|
-
return
|
|
2033
|
+
return H.evaluate(r, t);
|
|
1999
2034
|
}
|
|
2000
2035
|
// ─── Sync meta ──────────────────────────────────────────────────────────────
|
|
2001
2036
|
async getMeta(e) {
|
|
@@ -2052,13 +2087,13 @@ var fe = class {
|
|
|
2052
2087
|
};
|
|
2053
2088
|
|
|
2054
2089
|
// src/db/offline/mutation-queue.ts
|
|
2055
|
-
function
|
|
2090
|
+
function Ve() {
|
|
2056
2091
|
return typeof crypto < "u" && typeof crypto.randomUUID == "function" ? crypto.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (n) => {
|
|
2057
2092
|
let e = Math.random() * 16 | 0;
|
|
2058
2093
|
return (n === "x" ? e : e & 3 | 8).toString(16);
|
|
2059
2094
|
});
|
|
2060
2095
|
}
|
|
2061
|
-
var
|
|
2096
|
+
var he = class {
|
|
2062
2097
|
store;
|
|
2063
2098
|
/**
|
|
2064
2099
|
* Ponteiro de sequência local.
|
|
@@ -2154,18 +2189,18 @@ var me = class {
|
|
|
2154
2189
|
* Atômico: a persistência final é uma única operação putMutation.
|
|
2155
2190
|
*/
|
|
2156
2191
|
async enqueue(e) {
|
|
2157
|
-
let { collection: t, op: r, payload: o, baseVersion: i, batchId: s, upsert: a } = e,
|
|
2192
|
+
let { collection: t, op: r, payload: o, baseVersion: i, batchId: s, upsert: a } = e, l = e.docId ?? (r === "add" ? Ve() : "");
|
|
2158
2193
|
await this.syncSeq();
|
|
2159
|
-
let u = (await this.store.listMutations({ collection: t, docId:
|
|
2194
|
+
let u = (await this.store.listMutations({ collection: t, docId: l })).filter((h) => h.status === "queued").sort((h, y) => y.seq - h.seq)[0];
|
|
2160
2195
|
if (u !== void 0) {
|
|
2161
|
-
let
|
|
2162
|
-
if (
|
|
2163
|
-
if ("removed" in
|
|
2196
|
+
let h = this.tryCoalesce(u, r, o, s, a);
|
|
2197
|
+
if (h !== null) {
|
|
2198
|
+
if ("removed" in h)
|
|
2164
2199
|
return await this.store.deleteMutation(u.mutationId), {
|
|
2165
2200
|
seq: u.seq,
|
|
2166
|
-
mutationId:
|
|
2201
|
+
mutationId: Ve(),
|
|
2167
2202
|
collection: t,
|
|
2168
|
-
docId:
|
|
2203
|
+
docId: l,
|
|
2169
2204
|
op: "remove",
|
|
2170
2205
|
payload: null,
|
|
2171
2206
|
baseVersion: i,
|
|
@@ -2175,15 +2210,15 @@ var me = class {
|
|
|
2175
2210
|
status: "queued",
|
|
2176
2211
|
batchId: s
|
|
2177
2212
|
};
|
|
2178
|
-
let { coalesced:
|
|
2179
|
-
return await this.store.putMutation(
|
|
2213
|
+
let { coalesced: y } = h;
|
|
2214
|
+
return await this.store.putMutation(y), y;
|
|
2180
2215
|
}
|
|
2181
2216
|
}
|
|
2182
2217
|
let f = {
|
|
2183
2218
|
seq: this.nextSeq(),
|
|
2184
|
-
mutationId:
|
|
2219
|
+
mutationId: Ve(),
|
|
2185
2220
|
collection: t,
|
|
2186
|
-
docId:
|
|
2221
|
+
docId: l,
|
|
2187
2222
|
op: r,
|
|
2188
2223
|
payload: o,
|
|
2189
2224
|
baseVersion: i,
|
|
@@ -2294,45 +2329,45 @@ var me = class {
|
|
|
2294
2329
|
};
|
|
2295
2330
|
|
|
2296
2331
|
// src/db/field-value.ts
|
|
2297
|
-
var
|
|
2298
|
-
function
|
|
2299
|
-
return typeof n == "object" && n !== null &&
|
|
2332
|
+
var zt = "__neetru__";
|
|
2333
|
+
function G(n) {
|
|
2334
|
+
return typeof n == "object" && n !== null && zt in n && typeof n[zt] == "string";
|
|
2300
2335
|
}
|
|
2301
|
-
function
|
|
2302
|
-
return
|
|
2336
|
+
function qr(n) {
|
|
2337
|
+
return G(n) && n.__neetru__ === "serverTimestamp";
|
|
2303
2338
|
}
|
|
2304
|
-
function
|
|
2305
|
-
return
|
|
2339
|
+
function Fr(n) {
|
|
2340
|
+
return G(n) && n.__neetru__ === "increment" && typeof n.operand == "number" && Number.isFinite(n.operand);
|
|
2306
2341
|
}
|
|
2307
|
-
function
|
|
2308
|
-
return
|
|
2342
|
+
function jr(n, e) {
|
|
2343
|
+
return qr(n) ? Date.now() : Fr(n) ? (typeof e == "number" && Number.isFinite(e) ? e : 0) + n.operand : n;
|
|
2309
2344
|
}
|
|
2310
|
-
function
|
|
2345
|
+
function z(n, e) {
|
|
2311
2346
|
let t = false, r = {};
|
|
2312
2347
|
for (let [o, i] of Object.entries(n))
|
|
2313
|
-
|
|
2348
|
+
G(i) ? (t = true, r[o] = jr(i, e?.[o])) : r[o] = i;
|
|
2314
2349
|
return t ? r : n;
|
|
2315
2350
|
}
|
|
2316
|
-
function
|
|
2351
|
+
function Ke(n) {
|
|
2317
2352
|
for (let e of Object.values(n))
|
|
2318
|
-
if (
|
|
2353
|
+
if (G(e)) return true;
|
|
2319
2354
|
return false;
|
|
2320
2355
|
}
|
|
2321
2356
|
|
|
2322
2357
|
// src/db/offline/sync-engine.ts
|
|
2323
|
-
var
|
|
2324
|
-
function
|
|
2325
|
-
return n !== null &&
|
|
2358
|
+
var $r = 8, Wr = 1e3, Br = 300 * 1e3, ze = "truncatedCollections";
|
|
2359
|
+
function Vr(n) {
|
|
2360
|
+
return n !== null && Ke(n);
|
|
2326
2361
|
}
|
|
2327
|
-
function
|
|
2362
|
+
function Kr(n) {
|
|
2328
2363
|
if (n === null) return null;
|
|
2329
|
-
if (!
|
|
2364
|
+
if (!Ke(n)) return n;
|
|
2330
2365
|
let e = {};
|
|
2331
2366
|
for (let [t, r] of Object.entries(n))
|
|
2332
|
-
|
|
2367
|
+
G(r) || (e[t] = r);
|
|
2333
2368
|
return e;
|
|
2334
2369
|
}
|
|
2335
|
-
var
|
|
2370
|
+
var ge = class {
|
|
2336
2371
|
_store;
|
|
2337
2372
|
_queue;
|
|
2338
2373
|
_resolver;
|
|
@@ -2476,16 +2511,16 @@ var he = class {
|
|
|
2476
2511
|
try {
|
|
2477
2512
|
t = await this._transport.pushMutations(e);
|
|
2478
2513
|
} catch (s) {
|
|
2479
|
-
let a = s instanceof Error ? s.message : String(s),
|
|
2480
|
-
await this._retryOrDeadLetter(d, a,
|
|
2514
|
+
let a = s instanceof Error ? s.message : String(s), l = [], [d, ...u] = e;
|
|
2515
|
+
await this._retryOrDeadLetter(d, a, l);
|
|
2481
2516
|
for (let p of u)
|
|
2482
2517
|
await this._queue.requeueInflight(p.mutationId);
|
|
2483
|
-
return
|
|
2518
|
+
return l.length > 0 && this._bus.emit(l), this._refreshPendingWrites().catch(() => {
|
|
2484
2519
|
}), false;
|
|
2485
2520
|
}
|
|
2486
2521
|
let r = [];
|
|
2487
2522
|
for (let s of t.results) {
|
|
2488
|
-
let a = e.find((
|
|
2523
|
+
let a = e.find((l) => l.mutationId === s.mutationId);
|
|
2489
2524
|
a && (s.outcome === "confirmed" ? (await this._queue.markApplied(a.mutationId), await this._applySyncedDoc(
|
|
2490
2525
|
a.collection,
|
|
2491
2526
|
a.docId,
|
|
@@ -2503,8 +2538,8 @@ var he = class {
|
|
|
2503
2538
|
"partial_push: muta\xE7\xE3o n\xE3o processada no lote",
|
|
2504
2539
|
r
|
|
2505
2540
|
);
|
|
2506
|
-
for (let
|
|
2507
|
-
await this._queue.requeueInflight(
|
|
2541
|
+
for (let l of a)
|
|
2542
|
+
await this._queue.requeueInflight(l.mutationId);
|
|
2508
2543
|
}
|
|
2509
2544
|
return r.length > 0 && this._bus.emit(r), i.length === 0;
|
|
2510
2545
|
}
|
|
@@ -2526,13 +2561,13 @@ var he = class {
|
|
|
2526
2561
|
}), s.push({ type: "removed", collection: e, doc: { id: t, data: a.data } }));
|
|
2527
2562
|
return;
|
|
2528
2563
|
}
|
|
2529
|
-
let d =
|
|
2564
|
+
let d = Kr(i.payload) ?? a?.data ?? {}, u = {
|
|
2530
2565
|
collection: e,
|
|
2531
2566
|
id: t,
|
|
2532
2567
|
data: i.op === "update" ? { ...a?.data ?? {}, ...d } : (
|
|
2533
2568
|
// add/set: se o payload tinha sentinels, o cache otimista (existing.data)
|
|
2534
2569
|
// é a fonte de verdade até o pull; senão usa o payload literal.
|
|
2535
|
-
|
|
2570
|
+
Vr(i.payload) ? { ...a?.data ?? {}, ...d } : d
|
|
2536
2571
|
),
|
|
2537
2572
|
meta: {
|
|
2538
2573
|
serverVersion: r,
|
|
@@ -2579,7 +2614,7 @@ var he = class {
|
|
|
2579
2614
|
deleted: false,
|
|
2580
2615
|
ownerId: null
|
|
2581
2616
|
}
|
|
2582
|
-
},
|
|
2617
|
+
}, l = this._resolver.resolve(
|
|
2583
2618
|
s,
|
|
2584
2619
|
i,
|
|
2585
2620
|
e
|
|
@@ -2593,7 +2628,7 @@ var he = class {
|
|
|
2593
2628
|
detectedAt: Date.now(),
|
|
2594
2629
|
delivered: false
|
|
2595
2630
|
};
|
|
2596
|
-
await this._store.appendConflict(
|
|
2631
|
+
await this._store.appendConflict(l);
|
|
2597
2632
|
let d = {
|
|
2598
2633
|
collection: e.collection,
|
|
2599
2634
|
id: e.docId,
|
|
@@ -2636,7 +2671,7 @@ var he = class {
|
|
|
2636
2671
|
...i.meta,
|
|
2637
2672
|
serverVersion: t.serverVersion ?? i.meta.serverVersion
|
|
2638
2673
|
}
|
|
2639
|
-
} : null,
|
|
2674
|
+
} : null, l = this._resolver.resolveRejected(
|
|
2640
2675
|
i,
|
|
2641
2676
|
s,
|
|
2642
2677
|
e,
|
|
@@ -2651,7 +2686,7 @@ var he = class {
|
|
|
2651
2686
|
detectedAt: Date.now(),
|
|
2652
2687
|
delivered: false
|
|
2653
2688
|
};
|
|
2654
|
-
await this._store.appendConflict(
|
|
2689
|
+
await this._store.appendConflict(l), t.serverData ? (await this._store.putDoc({
|
|
2655
2690
|
...i,
|
|
2656
2691
|
data: t.serverData,
|
|
2657
2692
|
meta: {
|
|
@@ -2685,7 +2720,7 @@ var he = class {
|
|
|
2685
2720
|
* pending do doc no cache + registra `lastError`/dispara `onError`.
|
|
2686
2721
|
*/
|
|
2687
2722
|
async _retryOrDeadLetter(e, t, r) {
|
|
2688
|
-
if (e.attempts + 1 <
|
|
2723
|
+
if (e.attempts + 1 < $r) {
|
|
2689
2724
|
await this._queue.markRetry(e.mutationId, t);
|
|
2690
2725
|
return;
|
|
2691
2726
|
}
|
|
@@ -2726,7 +2761,7 @@ var he = class {
|
|
|
2726
2761
|
}
|
|
2727
2762
|
/** Backoff exponencial keyed em `attempts`, com teto `BACKOFF_CAP_MS`. */
|
|
2728
2763
|
_backoffDelayMs(e) {
|
|
2729
|
-
return Math.min(
|
|
2764
|
+
return Math.min(Wr * 2 ** (e - 1), Br);
|
|
2730
2765
|
}
|
|
2731
2766
|
// ─── FASE 2 — pull (reconciliar o cache) ─────────────────────────────────────
|
|
2732
2767
|
/**
|
|
@@ -2759,14 +2794,14 @@ var he = class {
|
|
|
2759
2794
|
let r = [];
|
|
2760
2795
|
await this._applyServerDocs(t.docs, r, true);
|
|
2761
2796
|
let o = t.truncatedCollections ?? [], i = new Set(o);
|
|
2762
|
-
await this._store.setMeta(
|
|
2797
|
+
await this._store.setMeta(ze, o);
|
|
2763
2798
|
let s = new Set(
|
|
2764
2799
|
t.docs.map((a) => `${a.collection}::${a.id}`)
|
|
2765
2800
|
);
|
|
2766
2801
|
for (let a of e) {
|
|
2767
2802
|
if (i.has(a)) continue;
|
|
2768
|
-
let
|
|
2769
|
-
for (let { id: d } of
|
|
2803
|
+
let l = await this._store.listDocs(a, {});
|
|
2804
|
+
for (let { id: d } of l.docs) {
|
|
2770
2805
|
let u = `${a}::${d}`;
|
|
2771
2806
|
if (!s.has(u)) {
|
|
2772
2807
|
let p = await this._store.getDoc(a, d);
|
|
@@ -2816,7 +2851,7 @@ var he = class {
|
|
|
2816
2851
|
continue;
|
|
2817
2852
|
}
|
|
2818
2853
|
if (i && i.meta.state === "pending") {
|
|
2819
|
-
let
|
|
2854
|
+
let l = {
|
|
2820
2855
|
collection: o.collection,
|
|
2821
2856
|
id: o.id,
|
|
2822
2857
|
data: o.data,
|
|
@@ -2833,7 +2868,7 @@ var he = class {
|
|
|
2833
2868
|
(p) => p.collection === o.collection && p.docId === o.id
|
|
2834
2869
|
);
|
|
2835
2870
|
if (u) {
|
|
2836
|
-
let p = this._resolver.resolve(i,
|
|
2871
|
+
let p = this._resolver.resolve(i, l, u);
|
|
2837
2872
|
p.conflictRecord && await this._store.appendConflict(p.conflictRecord), await this._store.putDoc({
|
|
2838
2873
|
...i,
|
|
2839
2874
|
meta: { ...i.meta, state: "conflict" }
|
|
@@ -2978,10 +3013,10 @@ var he = class {
|
|
|
2978
3013
|
};
|
|
2979
3014
|
|
|
2980
3015
|
// src/db/offline/conflict-resolver.ts
|
|
2981
|
-
function
|
|
3016
|
+
function Ht(n, e) {
|
|
2982
3017
|
return e === null ? false : n === null ? true : e > n;
|
|
2983
3018
|
}
|
|
2984
|
-
var
|
|
3019
|
+
var ye = class n {
|
|
2985
3020
|
/**
|
|
2986
3021
|
* Resolve um conflito com base na operação da mutação (auto-dispatch).
|
|
2987
3022
|
*
|
|
@@ -3015,7 +3050,7 @@ var ge = class n {
|
|
|
3015
3050
|
resolvedData: t.data,
|
|
3016
3051
|
conflictRecord: null
|
|
3017
3052
|
};
|
|
3018
|
-
if (!
|
|
3053
|
+
if (!Ht(
|
|
3019
3054
|
e.meta.updatedAtServer,
|
|
3020
3055
|
t.meta.updatedAtServer
|
|
3021
3056
|
))
|
|
@@ -3062,7 +3097,7 @@ var ge = class n {
|
|
|
3062
3097
|
let i = t.data;
|
|
3063
3098
|
if (e === null)
|
|
3064
3099
|
return { outcome: "no_conflict", resolvedData: { ...i, ...r.payload ?? {} }, conflictRecord: null };
|
|
3065
|
-
if (!
|
|
3100
|
+
if (!Ht(
|
|
3066
3101
|
e.meta.updatedAtServer,
|
|
3067
3102
|
t.meta.updatedAtServer
|
|
3068
3103
|
))
|
|
@@ -3070,7 +3105,7 @@ var ge = class n {
|
|
|
3070
3105
|
let a = {};
|
|
3071
3106
|
for (let d of o)
|
|
3072
3107
|
a[d] = e.data[d];
|
|
3073
|
-
let
|
|
3108
|
+
let l = {
|
|
3074
3109
|
collection: r.collection,
|
|
3075
3110
|
docId: r.docId,
|
|
3076
3111
|
mutationId: r.mutationId,
|
|
@@ -3083,7 +3118,7 @@ var ge = class n {
|
|
|
3083
3118
|
return {
|
|
3084
3119
|
outcome: "server_wins",
|
|
3085
3120
|
resolvedData: i,
|
|
3086
|
-
conflictRecord:
|
|
3121
|
+
conflictRecord: l
|
|
3087
3122
|
};
|
|
3088
3123
|
}
|
|
3089
3124
|
/**
|
|
@@ -3140,10 +3175,10 @@ var ge = class n {
|
|
|
3140
3175
|
};
|
|
3141
3176
|
|
|
3142
3177
|
// src/db/offline/change-bus.ts
|
|
3143
|
-
function
|
|
3178
|
+
function zr(n) {
|
|
3144
3179
|
return `${n.collection}::${n.doc.id}`;
|
|
3145
3180
|
}
|
|
3146
|
-
var
|
|
3181
|
+
var _e = class {
|
|
3147
3182
|
/** Listeners filtrados por coleção. */
|
|
3148
3183
|
_collectionListeners = /* @__PURE__ */ new Map();
|
|
3149
3184
|
/** Listeners globais (todas as coleções). */
|
|
@@ -3188,15 +3223,15 @@ var ye = class {
|
|
|
3188
3223
|
if (e.length === 0) return;
|
|
3189
3224
|
let t = /* @__PURE__ */ new Map();
|
|
3190
3225
|
for (let i of e)
|
|
3191
|
-
t.set(
|
|
3226
|
+
t.set(zr(i), i);
|
|
3192
3227
|
let r = Array.from(t.values()), o = /* @__PURE__ */ new Map();
|
|
3193
3228
|
for (let i of r)
|
|
3194
3229
|
o.has(i.collection) || o.set(i.collection, []), o.get(i.collection).push(i);
|
|
3195
3230
|
for (let [i, s] of o) {
|
|
3196
3231
|
let a = this._collectionListeners.get(i);
|
|
3197
3232
|
if (a)
|
|
3198
|
-
for (let
|
|
3199
|
-
this._safeCall(
|
|
3233
|
+
for (let l of a)
|
|
3234
|
+
this._safeCall(l, s);
|
|
3200
3235
|
}
|
|
3201
3236
|
for (let i of this._globalListeners)
|
|
3202
3237
|
this._safeCall(i, r);
|
|
@@ -3227,7 +3262,7 @@ var ye = class {
|
|
|
3227
3262
|
};
|
|
3228
3263
|
|
|
3229
3264
|
// src/db/offline/connectivity-monitor.ts
|
|
3230
|
-
var
|
|
3265
|
+
var be = class {
|
|
3231
3266
|
_state;
|
|
3232
3267
|
_listeners = /* @__PURE__ */ new Set();
|
|
3233
3268
|
_nav;
|
|
@@ -3329,7 +3364,7 @@ var _e = class {
|
|
|
3329
3364
|
};
|
|
3330
3365
|
|
|
3331
3366
|
// src/db/offline/tab-coordinator.ts
|
|
3332
|
-
var
|
|
3367
|
+
var re = class {
|
|
3333
3368
|
_lockName;
|
|
3334
3369
|
_channelName;
|
|
3335
3370
|
_lockManager;
|
|
@@ -3506,26 +3541,26 @@ var ne = class {
|
|
|
3506
3541
|
};
|
|
3507
3542
|
|
|
3508
3543
|
// src/db/collection-ref.ts
|
|
3509
|
-
|
|
3510
|
-
function
|
|
3544
|
+
ee();
|
|
3545
|
+
function Hr() {
|
|
3511
3546
|
return typeof indexedDB > "u" || typeof window > "u";
|
|
3512
3547
|
}
|
|
3513
|
-
var
|
|
3514
|
-
function
|
|
3515
|
-
if (!
|
|
3516
|
-
throw new
|
|
3548
|
+
var Qt = /^[a-z0-9][a-z0-9_-]{0,62}$/;
|
|
3549
|
+
function Qr(n) {
|
|
3550
|
+
if (!Qt.test(n))
|
|
3551
|
+
throw new _(
|
|
3517
3552
|
"db_invalid_query",
|
|
3518
|
-
`Nome de cole\xE7\xE3o inv\xE1lido: "${n}". Deve seguir o padr\xE3o ${
|
|
3553
|
+
`Nome de cole\xE7\xE3o inv\xE1lido: "${n}". Deve seguir o padr\xE3o ${Qt}.`
|
|
3519
3554
|
);
|
|
3520
3555
|
}
|
|
3521
|
-
function
|
|
3556
|
+
function J(n, e = "id") {
|
|
3522
3557
|
if (!n || typeof n != "string" || n.trim() === "")
|
|
3523
|
-
throw new
|
|
3558
|
+
throw new _(
|
|
3524
3559
|
"db_invalid_query",
|
|
3525
3560
|
`${e} \xE9 obrigat\xF3rio e deve ser uma string n\xE3o-vazia.`
|
|
3526
3561
|
);
|
|
3527
3562
|
}
|
|
3528
|
-
function
|
|
3563
|
+
function Gr(n) {
|
|
3529
3564
|
let e = {};
|
|
3530
3565
|
if (n?.where && (e.where = n.where.map((t) => ({
|
|
3531
3566
|
field: t.field,
|
|
@@ -3542,12 +3577,12 @@ function Br(n) {
|
|
|
3542
3577
|
}
|
|
3543
3578
|
return e;
|
|
3544
3579
|
}
|
|
3545
|
-
function
|
|
3580
|
+
function Jr(n, e) {
|
|
3546
3581
|
if (n.length < e) return null;
|
|
3547
3582
|
let t = n[n.length - 1];
|
|
3548
3583
|
return t ? btoa(JSON.stringify({ type: "startAfter", docId: t.id })) : null;
|
|
3549
3584
|
}
|
|
3550
|
-
var
|
|
3585
|
+
var He = class {
|
|
3551
3586
|
constructor(e, t, r, o, i, s) {
|
|
3552
3587
|
this._collection = e;
|
|
3553
3588
|
this._store = t;
|
|
@@ -3589,10 +3624,10 @@ var Ke = class {
|
|
|
3589
3624
|
}
|
|
3590
3625
|
/** Constrói um DbListResult para a coleção com query opcional. */
|
|
3591
3626
|
async _buildListResult(e) {
|
|
3592
|
-
let t =
|
|
3627
|
+
let t = Gr(e), r = t.limit ?? 20, o = await this._store.listDocs(this._collection, t), i = await this._hasPendingWrites(), s = this._isOnline(), a = this._engine.getSyncState(), l = Jr(o.docs, r), d = await this._store.getMeta(ze), u = Array.isArray(d) && d.includes(this._collection), p = !s || a.status === "offline" || u, f = i || a.lastSyncedAt === null || p;
|
|
3593
3628
|
return {
|
|
3594
|
-
docs: o.docs.map((
|
|
3595
|
-
nextCursor:
|
|
3629
|
+
docs: o.docs.map((h) => ({ id: h.id, data: h.data })),
|
|
3630
|
+
nextCursor: l,
|
|
3596
3631
|
fromCache: f,
|
|
3597
3632
|
stale: p,
|
|
3598
3633
|
hasPendingWrites: i,
|
|
@@ -3602,13 +3637,13 @@ var Ke = class {
|
|
|
3602
3637
|
}
|
|
3603
3638
|
// ── CRUD ────────────────────────────────────────────────────────────────────
|
|
3604
3639
|
async get(e) {
|
|
3605
|
-
return
|
|
3640
|
+
return J(e), this._buildGetResult(e);
|
|
3606
3641
|
}
|
|
3607
3642
|
async list(e) {
|
|
3608
3643
|
return this._buildListResult(e);
|
|
3609
3644
|
}
|
|
3610
3645
|
async add(e) {
|
|
3611
|
-
let t = e, r =
|
|
3646
|
+
let t = e, r = z(t, void 0), o = await this._queue.enqueue({
|
|
3612
3647
|
collection: this._collection,
|
|
3613
3648
|
op: "add",
|
|
3614
3649
|
payload: t,
|
|
@@ -3635,8 +3670,8 @@ var Ke = class {
|
|
|
3635
3670
|
}]), { ok: true, id: i };
|
|
3636
3671
|
}
|
|
3637
3672
|
async set(e, t) {
|
|
3638
|
-
|
|
3639
|
-
let r = await this._store.getDoc(this._collection, e), o = t, i =
|
|
3673
|
+
J(e);
|
|
3674
|
+
let r = await this._store.getDoc(this._collection, e), o = t, i = z(o, void 0), s = await this._queue.enqueue({
|
|
3640
3675
|
collection: this._collection,
|
|
3641
3676
|
docId: e,
|
|
3642
3677
|
op: "set",
|
|
@@ -3664,8 +3699,8 @@ var Ke = class {
|
|
|
3664
3699
|
}]), { ok: true };
|
|
3665
3700
|
}
|
|
3666
3701
|
async update(e, t, r) {
|
|
3667
|
-
|
|
3668
|
-
let o = await this._store.getDoc(this._collection, e), i = t, s = o?.meta.deleted ? void 0 : o?.data, a =
|
|
3702
|
+
J(e);
|
|
3703
|
+
let o = await this._store.getDoc(this._collection, e), i = t, s = o?.meta.deleted ? void 0 : o?.data, a = z(i, s), l = o?.meta.deleted ? { ...a } : { ...o?.data ?? {}, ...a }, d = await this._queue.enqueue({
|
|
3669
3704
|
collection: this._collection,
|
|
3670
3705
|
docId: e,
|
|
3671
3706
|
op: "update",
|
|
@@ -3678,7 +3713,7 @@ var Ke = class {
|
|
|
3678
3713
|
return await this._store.putDoc({
|
|
3679
3714
|
collection: this._collection,
|
|
3680
3715
|
id: e,
|
|
3681
|
-
data:
|
|
3716
|
+
data: l,
|
|
3682
3717
|
meta: {
|
|
3683
3718
|
serverVersion: o?.meta.serverVersion ?? null,
|
|
3684
3719
|
updatedAtServer: o?.meta.updatedAtServer ?? null,
|
|
@@ -3694,11 +3729,11 @@ var Ke = class {
|
|
|
3694
3729
|
}), this._bus.emit([{
|
|
3695
3730
|
type: "modified",
|
|
3696
3731
|
collection: this._collection,
|
|
3697
|
-
doc: { id: e, data:
|
|
3732
|
+
doc: { id: e, data: l }
|
|
3698
3733
|
}]), { ok: true };
|
|
3699
3734
|
}
|
|
3700
3735
|
async remove(e) {
|
|
3701
|
-
|
|
3736
|
+
J(e);
|
|
3702
3737
|
let t = await this._store.getDoc(this._collection, e);
|
|
3703
3738
|
return !t || t.meta.deleted, await this._queue.enqueue({
|
|
3704
3739
|
collection: this._collection,
|
|
@@ -3718,13 +3753,13 @@ var Ke = class {
|
|
|
3718
3753
|
for (let o of e) {
|
|
3719
3754
|
let i = this._collection;
|
|
3720
3755
|
if (o.kind === "add") {
|
|
3721
|
-
let s = o.data, a =
|
|
3756
|
+
let s = o.data, a = z(s, void 0), l = await this._queue.enqueue({
|
|
3722
3757
|
collection: i,
|
|
3723
3758
|
op: "add",
|
|
3724
3759
|
payload: s,
|
|
3725
3760
|
baseVersion: null,
|
|
3726
3761
|
batchId: t
|
|
3727
|
-
}), d =
|
|
3762
|
+
}), d = l.docId;
|
|
3728
3763
|
await this._store.putDoc({
|
|
3729
3764
|
collection: i,
|
|
3730
3765
|
id: d,
|
|
@@ -3734,18 +3769,18 @@ var Ke = class {
|
|
|
3734
3769
|
updatedAtServer: null,
|
|
3735
3770
|
updatedAtLocal: Date.now(),
|
|
3736
3771
|
state: "pending",
|
|
3737
|
-
pendingMutationIds: [
|
|
3772
|
+
pendingMutationIds: [l.mutationId],
|
|
3738
3773
|
deleted: false,
|
|
3739
3774
|
ownerId: null
|
|
3740
3775
|
}
|
|
3741
3776
|
}), r.push({ type: "added", collection: i, doc: { id: d, data: a } });
|
|
3742
3777
|
} else if (o.kind === "set") {
|
|
3743
|
-
let s = o.id, a = o.data,
|
|
3778
|
+
let s = o.id, a = o.data, l = await this._store.getDoc(i, s), d = z(a, void 0), u = await this._queue.enqueue({
|
|
3744
3779
|
collection: i,
|
|
3745
3780
|
docId: s,
|
|
3746
3781
|
op: "set",
|
|
3747
3782
|
payload: a,
|
|
3748
|
-
baseVersion:
|
|
3783
|
+
baseVersion: l?.meta.serverVersion ?? null,
|
|
3749
3784
|
batchId: t
|
|
3750
3785
|
});
|
|
3751
3786
|
await this._store.putDoc({
|
|
@@ -3753,8 +3788,8 @@ var Ke = class {
|
|
|
3753
3788
|
id: s,
|
|
3754
3789
|
data: d,
|
|
3755
3790
|
meta: {
|
|
3756
|
-
serverVersion:
|
|
3757
|
-
updatedAtServer:
|
|
3791
|
+
serverVersion: l?.meta.serverVersion ?? null,
|
|
3792
|
+
updatedAtServer: l?.meta.updatedAtServer ?? null,
|
|
3758
3793
|
updatedAtLocal: Date.now(),
|
|
3759
3794
|
state: "pending",
|
|
3760
3795
|
pendingMutationIds: [u.mutationId],
|
|
@@ -3762,17 +3797,17 @@ var Ke = class {
|
|
|
3762
3797
|
ownerId: null
|
|
3763
3798
|
}
|
|
3764
3799
|
}), r.push({
|
|
3765
|
-
type:
|
|
3800
|
+
type: l && !l.meta.deleted ? "modified" : "added",
|
|
3766
3801
|
collection: i,
|
|
3767
3802
|
doc: { id: s, data: d }
|
|
3768
3803
|
});
|
|
3769
3804
|
} else if (o.kind === "update") {
|
|
3770
|
-
let s = o.id, a = o.data,
|
|
3805
|
+
let s = o.id, a = o.data, l = await this._store.getDoc(i, s), d = l?.meta.deleted ? void 0 : l?.data, u = z(a, d), p = { ...l?.data ?? {}, ...u }, f = await this._queue.enqueue({
|
|
3771
3806
|
collection: i,
|
|
3772
3807
|
docId: s,
|
|
3773
3808
|
op: "update",
|
|
3774
3809
|
payload: a,
|
|
3775
|
-
baseVersion:
|
|
3810
|
+
baseVersion: l?.meta.serverVersion ?? null,
|
|
3776
3811
|
batchId: t,
|
|
3777
3812
|
// bug_0273e4dd: propaga merge-upsert (writeBatch.set(merge) cria-se-ausente).
|
|
3778
3813
|
upsert: o.upsert
|
|
@@ -3782,16 +3817,16 @@ var Ke = class {
|
|
|
3782
3817
|
id: s,
|
|
3783
3818
|
data: p,
|
|
3784
3819
|
meta: {
|
|
3785
|
-
serverVersion:
|
|
3786
|
-
updatedAtServer:
|
|
3820
|
+
serverVersion: l?.meta.serverVersion ?? null,
|
|
3821
|
+
updatedAtServer: l?.meta.updatedAtServer ?? null,
|
|
3787
3822
|
updatedAtLocal: Date.now(),
|
|
3788
3823
|
state: "pending",
|
|
3789
3824
|
pendingMutationIds: [
|
|
3790
|
-
...
|
|
3825
|
+
...l?.meta.pendingMutationIds ?? [],
|
|
3791
3826
|
f.mutationId
|
|
3792
3827
|
],
|
|
3793
3828
|
deleted: false,
|
|
3794
|
-
ownerId:
|
|
3829
|
+
ownerId: l?.meta.ownerId ?? null
|
|
3795
3830
|
}
|
|
3796
3831
|
}), r.push({ type: "modified", collection: i, doc: { id: s, data: p } });
|
|
3797
3832
|
} else if (o.kind === "remove") {
|
|
@@ -3810,7 +3845,7 @@ var Ke = class {
|
|
|
3810
3845
|
}
|
|
3811
3846
|
// ── Realtime ─────────────────────────────────────────────────────────────────
|
|
3812
3847
|
onDoc(e, t) {
|
|
3813
|
-
return
|
|
3848
|
+
return J(e), this._buildGetResult(e).then((r) => {
|
|
3814
3849
|
t(r ? r.docs[0]?.data ?? null : null);
|
|
3815
3850
|
}).catch(() => t(null)), this._bus.subscribe(this._collection, (r) => {
|
|
3816
3851
|
let o = r.find((i) => i.doc.id === e);
|
|
@@ -3822,11 +3857,11 @@ var Ke = class {
|
|
|
3822
3857
|
});
|
|
3823
3858
|
let r = this._bus.subscribe(this._collection, async (s) => {
|
|
3824
3859
|
try {
|
|
3825
|
-
let a = await this._buildListResult(e),
|
|
3860
|
+
let a = await this._buildListResult(e), l = s.map((d) => ({
|
|
3826
3861
|
type: d.type,
|
|
3827
3862
|
doc: { id: d.doc.id, data: d.doc.data }
|
|
3828
3863
|
}));
|
|
3829
|
-
t({ ...a, changes:
|
|
3864
|
+
t({ ...a, changes: l });
|
|
3830
3865
|
} catch {
|
|
3831
3866
|
}
|
|
3832
3867
|
}), o = this._engine.onSyncStateChange(async () => {
|
|
@@ -3840,15 +3875,15 @@ var Ke = class {
|
|
|
3840
3875
|
this._collection,
|
|
3841
3876
|
async (s, a) => {
|
|
3842
3877
|
if (!a)
|
|
3843
|
-
for (let
|
|
3844
|
-
|
|
3878
|
+
for (let l of s)
|
|
3879
|
+
l.type === "removed" || l.data === null ? (await this._store.deleteDoc(this._collection, l.docId), this._bus.emit([{
|
|
3845
3880
|
type: "removed",
|
|
3846
3881
|
collection: this._collection,
|
|
3847
|
-
doc: { id:
|
|
3882
|
+
doc: { id: l.docId, data: {} }
|
|
3848
3883
|
}])) : (await this._store.putDoc({
|
|
3849
3884
|
collection: this._collection,
|
|
3850
|
-
id:
|
|
3851
|
-
data:
|
|
3885
|
+
id: l.docId,
|
|
3886
|
+
data: l.data,
|
|
3852
3887
|
meta: {
|
|
3853
3888
|
serverVersion: `rt_${Date.now()}`,
|
|
3854
3889
|
updatedAtServer: Date.now(),
|
|
@@ -3859,9 +3894,9 @@ var Ke = class {
|
|
|
3859
3894
|
ownerId: null
|
|
3860
3895
|
}
|
|
3861
3896
|
}), this._bus.emit([{
|
|
3862
|
-
type:
|
|
3897
|
+
type: l.type,
|
|
3863
3898
|
collection: this._collection,
|
|
3864
|
-
doc: { id:
|
|
3899
|
+
doc: { id: l.docId, data: l.data }
|
|
3865
3900
|
}]));
|
|
3866
3901
|
}
|
|
3867
3902
|
)), () => {
|
|
@@ -3869,7 +3904,7 @@ var Ke = class {
|
|
|
3869
3904
|
};
|
|
3870
3905
|
}
|
|
3871
3906
|
doc(e) {
|
|
3872
|
-
|
|
3907
|
+
J(e);
|
|
3873
3908
|
let t = this;
|
|
3874
3909
|
return {
|
|
3875
3910
|
get id() {
|
|
@@ -3896,14 +3931,14 @@ var Ke = class {
|
|
|
3896
3931
|
onSnapshot(r) {
|
|
3897
3932
|
t._buildGetResult(e).then((s) => r(s)).catch(() => r(null));
|
|
3898
3933
|
let o = t._bus.subscribe(t._collection, async (s) => {
|
|
3899
|
-
let a = s.find((
|
|
3934
|
+
let a = s.find((l) => l.doc.id === e);
|
|
3900
3935
|
if (a)
|
|
3901
3936
|
try {
|
|
3902
3937
|
if (a.type === "removed")
|
|
3903
3938
|
r(null);
|
|
3904
3939
|
else {
|
|
3905
|
-
let
|
|
3906
|
-
r(
|
|
3940
|
+
let l = await t._buildGetResult(e);
|
|
3941
|
+
r(l);
|
|
3907
3942
|
}
|
|
3908
3943
|
} catch {
|
|
3909
3944
|
r(null);
|
|
@@ -3922,7 +3957,7 @@ var Ke = class {
|
|
|
3922
3957
|
}
|
|
3923
3958
|
};
|
|
3924
3959
|
}
|
|
3925
|
-
},
|
|
3960
|
+
}, Qe = class {
|
|
3926
3961
|
_store;
|
|
3927
3962
|
_queue;
|
|
3928
3963
|
_bus;
|
|
@@ -3932,7 +3967,7 @@ var Ke = class {
|
|
|
3932
3967
|
this._store = e.store, this._queue = e.queue, this._bus = e.bus, this._engine = e.engine, this._connectivity = e.connectivity;
|
|
3933
3968
|
}
|
|
3934
3969
|
collection(e) {
|
|
3935
|
-
return
|
|
3970
|
+
return Qr(e), new He(
|
|
3936
3971
|
e,
|
|
3937
3972
|
this._store,
|
|
3938
3973
|
this._queue,
|
|
@@ -3961,23 +3996,23 @@ var Ke = class {
|
|
|
3961
3996
|
return this._engine.onError(e);
|
|
3962
3997
|
}
|
|
3963
3998
|
};
|
|
3964
|
-
async function
|
|
3965
|
-
let e =
|
|
3999
|
+
async function Gt(n) {
|
|
4000
|
+
let e = Hr() ? new me() : new fe(n.dbName);
|
|
3966
4001
|
await e.open();
|
|
3967
|
-
let t = new
|
|
4002
|
+
let t = new he(e), r = new ye(), o = new _e(), i = new be({
|
|
3968
4003
|
// Se startOnline=false, injeta um navigator falso
|
|
3969
4004
|
navigator: n.startOnline === false ? { onLine: false } : typeof navigator < "u" ? navigator : void 0
|
|
3970
4005
|
}), s = n.singleTab ? (
|
|
3971
4006
|
// Fake tab coordinator para single-tab mode (sempre líder)
|
|
3972
4007
|
{
|
|
3973
4008
|
isLeader: () => true,
|
|
3974
|
-
onRoleChange: (
|
|
4009
|
+
onRoleChange: (l) => () => {
|
|
3975
4010
|
}
|
|
3976
4011
|
}
|
|
3977
|
-
) : new
|
|
4012
|
+
) : new re({
|
|
3978
4013
|
lockName: `neetru-offline:${n.dbName}`,
|
|
3979
4014
|
channelName: `neetru-offline:${n.dbName}`
|
|
3980
|
-
}), a = new
|
|
4015
|
+
}), a = new ge({
|
|
3981
4016
|
store: e,
|
|
3982
4017
|
queue: t,
|
|
3983
4018
|
resolver: r,
|
|
@@ -3987,7 +4022,7 @@ async function Ht(n) {
|
|
|
3987
4022
|
connectivity: i,
|
|
3988
4023
|
periodicSyncIntervalMs: n.periodicSyncIntervalMs ?? 300 * 1e3
|
|
3989
4024
|
});
|
|
3990
|
-
return i.start(), !n.singleTab && s instanceof
|
|
4025
|
+
return i.start(), !n.singleTab && s instanceof re && s.start(), new Qe({
|
|
3991
4026
|
store: e,
|
|
3992
4027
|
queue: t,
|
|
3993
4028
|
bus: o,
|
|
@@ -3997,11 +4032,11 @@ async function Ht(n) {
|
|
|
3997
4032
|
}
|
|
3998
4033
|
|
|
3999
4034
|
// src/db/realtime/realtime-client.ts
|
|
4000
|
-
var
|
|
4001
|
-
function
|
|
4002
|
-
return typeof globalThis.crypto?.randomUUID == "function" ? globalThis.crypto.randomUUID() : `nrt-sub-${Date.now()}-${++
|
|
4035
|
+
var Xr = 0;
|
|
4036
|
+
function Jt() {
|
|
4037
|
+
return typeof globalThis.crypto?.randomUUID == "function" ? globalThis.crypto.randomUUID() : `nrt-sub-${Date.now()}-${++Xr}-${Math.random().toString(36).slice(2)}`;
|
|
4003
4038
|
}
|
|
4004
|
-
var
|
|
4039
|
+
var ve = class {
|
|
4005
4040
|
// ── configuração ──────────────────────────────────────────────────────────
|
|
4006
4041
|
_gatewayUrl;
|
|
4007
4042
|
_wsFactory;
|
|
@@ -4039,7 +4074,7 @@ var be = class {
|
|
|
4039
4074
|
_pendingFrames = [];
|
|
4040
4075
|
// ── construtor ────────────────────────────────────────────────────────────
|
|
4041
4076
|
constructor(e) {
|
|
4042
|
-
this._gatewayUrl = e.gatewayUrl, this._wsFactory = e.webSocketFactory ??
|
|
4077
|
+
this._gatewayUrl = e.gatewayUrl, this._wsFactory = e.webSocketFactory ?? Yr, this._setTimeout = e.setTimeoutFn ?? globalThis.setTimeout.bind(globalThis), this._clearTimeout = e.clearTimeoutFn ?? globalThis.clearTimeout.bind(globalThis), this._backoffBaseMs = e.backoffBaseMs ?? 1e3, this._backoffMaxMs = e.backoffMaxMs ?? 3e4, this._heartbeatIntervalMs = e.heartbeatIntervalMs ?? 25e3, this._ticketProvider = e.ticketProvider, this._dbId = e.dbId, this._connect();
|
|
4043
4078
|
}
|
|
4044
4079
|
// ── API pública ───────────────────────────────────────────────────────────
|
|
4045
4080
|
/**
|
|
@@ -4053,8 +4088,8 @@ var be = class {
|
|
|
4053
4088
|
*/
|
|
4054
4089
|
subscribe(e, t, r) {
|
|
4055
4090
|
if (this._closed)
|
|
4056
|
-
return
|
|
4057
|
-
let o =
|
|
4091
|
+
return Jt();
|
|
4092
|
+
let o = Jt();
|
|
4058
4093
|
this._subscriptions.set(o, {
|
|
4059
4094
|
subscriptionId: o,
|
|
4060
4095
|
collection: e,
|
|
@@ -4318,7 +4353,7 @@ var be = class {
|
|
|
4318
4353
|
_detachHandlers(e) {
|
|
4319
4354
|
e.onopen = null, e.onmessage = null, e.onclose = null, e.onerror = null;
|
|
4320
4355
|
}
|
|
4321
|
-
},
|
|
4356
|
+
}, Yr = (n) => {
|
|
4322
4357
|
if (typeof WebSocket > "u")
|
|
4323
4358
|
throw new Error(
|
|
4324
4359
|
"[NeetruRealtimeClient] WebSocket n\xE3o dispon\xEDvel neste ambiente. Injete uma implementa\xE7\xE3o via `webSocketFactory` nas op\xE7\xF5es."
|
|
@@ -4327,59 +4362,59 @@ var be = class {
|
|
|
4327
4362
|
};
|
|
4328
4363
|
|
|
4329
4364
|
// src/db/client-db.ts
|
|
4330
|
-
var
|
|
4331
|
-
function
|
|
4332
|
-
return e._transport ? e._transport : n === "firestore" && e.firestoreTransport ? e.firestoreTransport : n === "nosql-vm" && e.realtimeGatewayUrl ?
|
|
4365
|
+
var po = (n) => `/api/sdk/v1/datastore/${encodeURIComponent(n)}`, ke = (n, e) => `/api/sdk/v1/datastore/${encodeURIComponent(n)}/${encodeURIComponent(e)}`, ln = 200;
|
|
4366
|
+
function fo(n, e, t) {
|
|
4367
|
+
return e._transport ? e._transport : n === "firestore" && e.firestoreTransport ? e.firestoreTransport : n === "nosql-vm" && e.realtimeGatewayUrl ? mo(e.realtimeGatewayUrl, t, e) : un(t);
|
|
4333
4368
|
}
|
|
4334
|
-
function
|
|
4369
|
+
function un(n) {
|
|
4335
4370
|
return {
|
|
4336
4371
|
async pushMutations(e) {
|
|
4337
4372
|
if (!n)
|
|
4338
|
-
throw new
|
|
4373
|
+
throw new _(
|
|
4339
4374
|
"db_unavailable",
|
|
4340
4375
|
"[RestSyncTransport] config n\xE3o dispon\xEDvel \u2014 n\xE3o \xE9 poss\xEDvel enviar ao Core. Inicialize o transporte via createNeetruDb."
|
|
4341
4376
|
);
|
|
4342
|
-
let { httpRequest: t } = await Promise.resolve().then(() => (
|
|
4377
|
+
let { httpRequest: t } = await Promise.resolve().then(() => (F(), Z)), r = [], o = n.tenantId ?? n.productId, i = o ? { "x-neetru-tenant": o } : void 0;
|
|
4343
4378
|
for (let s of e)
|
|
4344
4379
|
try {
|
|
4345
4380
|
let a;
|
|
4346
4381
|
s.op === "add" ? a = await t(n, {
|
|
4347
4382
|
method: "PUT",
|
|
4348
|
-
path:
|
|
4383
|
+
path: ke(s.collection, s.docId),
|
|
4349
4384
|
body: { data: s.payload ?? {} },
|
|
4350
4385
|
requireAuth: !0,
|
|
4351
4386
|
retries: 2,
|
|
4352
4387
|
headers: i
|
|
4353
4388
|
}) : s.op === "set" ? a = await t(n, {
|
|
4354
4389
|
method: "PUT",
|
|
4355
|
-
path:
|
|
4390
|
+
path: ke(s.collection, s.docId),
|
|
4356
4391
|
body: { data: s.payload ?? {} },
|
|
4357
4392
|
requireAuth: !0,
|
|
4358
4393
|
retries: 2,
|
|
4359
4394
|
headers: i
|
|
4360
4395
|
}) : s.op === "update" ? a = await t(n, {
|
|
4361
4396
|
method: "PATCH",
|
|
4362
|
-
path:
|
|
4397
|
+
path: ke(s.collection, s.docId),
|
|
4363
4398
|
body: { data: s.payload ?? {}, ...s.upsert ? { upsert: !0 } : {} },
|
|
4364
4399
|
requireAuth: !0,
|
|
4365
4400
|
retries: 2,
|
|
4366
4401
|
headers: i
|
|
4367
4402
|
}) : a = await t(n, {
|
|
4368
4403
|
method: "DELETE",
|
|
4369
|
-
path:
|
|
4404
|
+
path: ke(s.collection, s.docId),
|
|
4370
4405
|
requireAuth: !0,
|
|
4371
4406
|
retries: 2,
|
|
4372
4407
|
headers: i
|
|
4373
4408
|
});
|
|
4374
|
-
let
|
|
4409
|
+
let l = a;
|
|
4375
4410
|
r.push({
|
|
4376
4411
|
mutationId: s.mutationId,
|
|
4377
4412
|
outcome: "confirmed",
|
|
4378
|
-
serverVersion:
|
|
4413
|
+
serverVersion: l?.serverVersion ?? l?.id ?? `rest_${Date.now()}`,
|
|
4379
4414
|
serverTimestamp: Date.now()
|
|
4380
4415
|
});
|
|
4381
4416
|
} catch (a) {
|
|
4382
|
-
let
|
|
4417
|
+
let l = a instanceof Error ? a.message : String(a), d = a?.code, u = a?.status;
|
|
4383
4418
|
if (d === "forbidden" || d === "unauthorized" || d === "not_found" || d === "conflict" || d === "validation_failed" || typeof u == "number" && u >= 400 && u < 500 && u !== 408 && u !== 429) {
|
|
4384
4419
|
let f = d === "forbidden" || d === "unauthorized" ? "rejected_permission" : "rejected_validation";
|
|
4385
4420
|
r.push({
|
|
@@ -4392,7 +4427,7 @@ function cn(n) {
|
|
|
4392
4427
|
continue;
|
|
4393
4428
|
}
|
|
4394
4429
|
if (r.length === 0)
|
|
4395
|
-
throw new
|
|
4430
|
+
throw new _("db_unavailable", `pushMutations falhou: ${l}`);
|
|
4396
4431
|
break;
|
|
4397
4432
|
}
|
|
4398
4433
|
return { results: r };
|
|
@@ -4403,13 +4438,13 @@ function cn(n) {
|
|
|
4403
4438
|
async fullResync(e) {
|
|
4404
4439
|
if (!n)
|
|
4405
4440
|
return { docs: [], newWatermark: Date.now() };
|
|
4406
|
-
let { httpRequest: t } = await Promise.resolve().then(() => (
|
|
4407
|
-
for (let
|
|
4441
|
+
let { httpRequest: t } = await Promise.resolve().then(() => (F(), Z)), r = n.tenantId ?? n.productId, o = r ? { "x-neetru-tenant": r } : void 0, i = Date.now(), s = [], a = [];
|
|
4442
|
+
for (let l of e) {
|
|
4408
4443
|
let d;
|
|
4409
4444
|
try {
|
|
4410
4445
|
d = await t(n, {
|
|
4411
4446
|
method: "GET",
|
|
4412
|
-
path:
|
|
4447
|
+
path: po(l),
|
|
4413
4448
|
requireAuth: !0,
|
|
4414
4449
|
retries: 2,
|
|
4415
4450
|
headers: o,
|
|
@@ -4417,37 +4452,37 @@ function cn(n) {
|
|
|
4417
4452
|
// TRUNCADAS — reportadas em `truncatedCollections` p/ o SyncEngine
|
|
4418
4453
|
// (a) NÃO rodar deleção-por-ausência e (b) sinalizar
|
|
4419
4454
|
// `DbListResult.truncated`. Paginação por cursor é tarefa Core (gated).
|
|
4420
|
-
query: { limit:
|
|
4455
|
+
query: { limit: ln }
|
|
4421
4456
|
});
|
|
4422
4457
|
} catch (f) {
|
|
4423
|
-
let
|
|
4424
|
-
throw new
|
|
4458
|
+
let h = f instanceof Error ? f.message : String(f);
|
|
4459
|
+
throw new _(
|
|
4425
4460
|
"db_unavailable",
|
|
4426
|
-
`[RestSyncTransport] fullResync falhou na cole\xE7\xE3o "${
|
|
4461
|
+
`[RestSyncTransport] fullResync falhou na cole\xE7\xE3o "${l}": ${h}`
|
|
4427
4462
|
);
|
|
4428
4463
|
}
|
|
4429
4464
|
let u = d, p = Array.isArray(u?.items) ? u.items : [];
|
|
4430
|
-
p.length >=
|
|
4465
|
+
p.length >= ln && a.push(l);
|
|
4431
4466
|
for (let f of p) {
|
|
4432
4467
|
if (!f || typeof f != "object") continue;
|
|
4433
|
-
let
|
|
4434
|
-
if (!
|
|
4435
|
-
let { id:
|
|
4436
|
-
if (typeof
|
|
4437
|
-
|
|
4438
|
-
else if (
|
|
4439
|
-
|
|
4440
|
-
else if (typeof
|
|
4441
|
-
let
|
|
4442
|
-
Number.isNaN(
|
|
4468
|
+
let h = f, y = typeof h.id == "string" ? h.id : null;
|
|
4469
|
+
if (!y) continue;
|
|
4470
|
+
let { id: T, ...x } = h, R = i, E = x._updatedAt;
|
|
4471
|
+
if (typeof E == "number")
|
|
4472
|
+
R = E;
|
|
4473
|
+
else if (E !== null && typeof E == "object" && typeof E._seconds == "number")
|
|
4474
|
+
R = E._seconds * 1e3;
|
|
4475
|
+
else if (typeof E == "string") {
|
|
4476
|
+
let g = Date.parse(E);
|
|
4477
|
+
Number.isNaN(g) || (R = g);
|
|
4443
4478
|
}
|
|
4444
|
-
let
|
|
4479
|
+
let j = `rest_${y}_${R}`;
|
|
4445
4480
|
s.push({
|
|
4446
|
-
collection:
|
|
4447
|
-
id:
|
|
4481
|
+
collection: l,
|
|
4482
|
+
id: y,
|
|
4448
4483
|
data: x,
|
|
4449
|
-
serverVersion:
|
|
4450
|
-
serverTimestamp:
|
|
4484
|
+
serverVersion: j,
|
|
4485
|
+
serverTimestamp: R,
|
|
4451
4486
|
deleted: false
|
|
4452
4487
|
});
|
|
4453
4488
|
}
|
|
@@ -4456,10 +4491,10 @@ function cn(n) {
|
|
|
4456
4491
|
}
|
|
4457
4492
|
};
|
|
4458
4493
|
}
|
|
4459
|
-
function
|
|
4460
|
-
let r =
|
|
4494
|
+
function mo(n, e, t) {
|
|
4495
|
+
let r = un(e), o = new ve({
|
|
4461
4496
|
gatewayUrl: n,
|
|
4462
|
-
ticketProvider:
|
|
4497
|
+
ticketProvider: ho(e, t),
|
|
4463
4498
|
dbId: t.dbId,
|
|
4464
4499
|
webSocketFactory: t._wsFactory
|
|
4465
4500
|
});
|
|
@@ -4471,17 +4506,17 @@ function io(n, e, t) {
|
|
|
4471
4506
|
// quando o engine é nosql-vm. Registra a subscription no NeetruRealtimeClient
|
|
4472
4507
|
// e traduz os frames inbound para o contrato de `onChange`.
|
|
4473
4508
|
subscribeCollection(i, s) {
|
|
4474
|
-
let a = o.subscribe(i, {}, (
|
|
4475
|
-
if (
|
|
4509
|
+
let a = o.subscribe(i, {}, (l) => {
|
|
4510
|
+
if (l.op === "resync") {
|
|
4476
4511
|
s([], true);
|
|
4477
4512
|
return;
|
|
4478
4513
|
}
|
|
4479
|
-
if (
|
|
4514
|
+
if (l.op === "stale") {
|
|
4480
4515
|
s([], true);
|
|
4481
4516
|
return;
|
|
4482
4517
|
}
|
|
4483
|
-
if (
|
|
4484
|
-
let d =
|
|
4518
|
+
if (l.op === "delta" && l.changes) {
|
|
4519
|
+
let d = l.changes.map((u) => ({
|
|
4485
4520
|
type: u.type === "insert" ? "added" : u.type === "delete" ? "removed" : "modified",
|
|
4486
4521
|
docId: u.documentId,
|
|
4487
4522
|
data: u.data ?? null
|
|
@@ -4495,9 +4530,9 @@ function io(n, e, t) {
|
|
|
4495
4530
|
}
|
|
4496
4531
|
};
|
|
4497
4532
|
}
|
|
4498
|
-
function
|
|
4533
|
+
function ho(n, e) {
|
|
4499
4534
|
return async () => {
|
|
4500
|
-
let { httpRequest: t } = await Promise.resolve().then(() => (
|
|
4535
|
+
let { httpRequest: t } = await Promise.resolve().then(() => (F(), Z));
|
|
4501
4536
|
return await t(n, {
|
|
4502
4537
|
method: "POST",
|
|
4503
4538
|
path: "/api/sdk/v1/db/realtime/ticket",
|
|
@@ -4510,21 +4545,21 @@ function so(n, e) {
|
|
|
4510
4545
|
});
|
|
4511
4546
|
};
|
|
4512
4547
|
}
|
|
4513
|
-
var
|
|
4514
|
-
function
|
|
4515
|
-
|
|
4548
|
+
var dn = false;
|
|
4549
|
+
function go(n, e) {
|
|
4550
|
+
dn || e.dbId && n.env !== "prod" && (typeof window > "u" || typeof console > "u" || typeof console.warn != "function" || (dn = true, console.warn(
|
|
4516
4551
|
'[neetru/sdk] client.db recebeu `dbId` ("' + e.dbId + '") mas ele N\xC3O roteia nem escopa nada no servidor: as escritas do mundo Documentos (add/set/update/remove/list) SEMPRE caem no datastore gen\xE9rico do Core, escopado s\xF3 por tenant/produto (header x-neetru-tenant). `dbId` apenas nomeia o cache offline LOCAL (IndexedDB). ATEN\xC7\xC3O: usar dbIds distintos no MESMO tenant/produto N\xC3O isola os dados no servidor \u2014 eles se misturam (co-mingling). Veja o JSDoc de NeetruDbOptions.dbId.'
|
|
4517
4552
|
)));
|
|
4518
4553
|
}
|
|
4519
|
-
function
|
|
4520
|
-
|
|
4554
|
+
function pn(n, e = {}) {
|
|
4555
|
+
go(n, e);
|
|
4521
4556
|
let t;
|
|
4522
4557
|
e.transport !== void 0 ? t = e.transport : e.engine !== void 0 ? (console.warn(
|
|
4523
4558
|
'[neetru/sdk] NeetruDbOptions.engine est\xE1 depreciado e ser\xE1 removido em v3.0. Use NeetruDbOptions.transport em vez de engine. Valores v\xE1lidos: "rest" | "firestore" | "nosql-vm". Nota: "engine" no SDK configura o TRANSPORTE (REST/Firestore/WebSocket), n\xE3o o storage engine do admin database (firestore-instance, cloud-sql-postgres, \u2026).'
|
|
4524
4559
|
), t = e.engine) : t = "rest";
|
|
4525
|
-
let r =
|
|
4526
|
-
function
|
|
4527
|
-
return s || (s =
|
|
4560
|
+
let r = fo(t, e, n), o = e.dbId ?? "default", i = e.dbName ?? `neetru-db__${n.productId ?? "sdk"}__${o}__${n.env}`, s = null, a = null;
|
|
4561
|
+
function l() {
|
|
4562
|
+
return s || (s = Gt({
|
|
4528
4563
|
dbName: i,
|
|
4529
4564
|
transport: r,
|
|
4530
4565
|
singleTab: e.singleTab ?? n.env !== "prod"
|
|
@@ -4532,15 +4567,15 @@ function ln(n, e = {}) {
|
|
|
4532
4567
|
}
|
|
4533
4568
|
return {
|
|
4534
4569
|
collection(d) {
|
|
4535
|
-
return a ? a.collection(d) :
|
|
4570
|
+
return a ? a.collection(d) : yo(d, l);
|
|
4536
4571
|
},
|
|
4537
4572
|
async sql(d, u) {
|
|
4538
|
-
if (n.env
|
|
4539
|
-
throw new
|
|
4573
|
+
if (W(n.env))
|
|
4574
|
+
throw new _(
|
|
4540
4575
|
"db_unavailable",
|
|
4541
4576
|
"[SDK] db.sql() n\xE3o dispon\xEDvel em NEETRU_ENV=dev. Use `neetru dev` para subir o container Postgres local."
|
|
4542
4577
|
);
|
|
4543
|
-
return (await Promise.resolve().then(() => (
|
|
4578
|
+
return (await Promise.resolve().then(() => (cn(), an))).createSqlClientFromConfig(n, d, u);
|
|
4544
4579
|
},
|
|
4545
4580
|
get syncState() {
|
|
4546
4581
|
return a?.syncState ?? {
|
|
@@ -4553,25 +4588,25 @@ function ln(n, e = {}) {
|
|
|
4553
4588
|
onSyncStateChanged(d) {
|
|
4554
4589
|
if (a) return a.onSyncStateChanged(d);
|
|
4555
4590
|
let u = null, p = false;
|
|
4556
|
-
return
|
|
4591
|
+
return l().then((f) => {
|
|
4557
4592
|
p || (u = f.onSyncStateChanged(d));
|
|
4558
4593
|
}), () => {
|
|
4559
4594
|
p = true, u?.();
|
|
4560
4595
|
};
|
|
4561
4596
|
},
|
|
4562
4597
|
async flush() {
|
|
4563
|
-
return (await
|
|
4598
|
+
return (await l()).flush();
|
|
4564
4599
|
},
|
|
4565
4600
|
async clearCache() {
|
|
4566
|
-
return (await
|
|
4601
|
+
return (await l()).clearCache();
|
|
4567
4602
|
},
|
|
4568
4603
|
async getConflicts() {
|
|
4569
|
-
return (await
|
|
4604
|
+
return (await l()).getConflicts();
|
|
4570
4605
|
},
|
|
4571
4606
|
onError(d) {
|
|
4572
4607
|
if (a) return a.onError(d);
|
|
4573
4608
|
let u = null, p = false;
|
|
4574
|
-
return
|
|
4609
|
+
return l().then((f) => {
|
|
4575
4610
|
p || (u = f.onError(d));
|
|
4576
4611
|
}), () => {
|
|
4577
4612
|
p = true, u?.();
|
|
@@ -4579,7 +4614,7 @@ function ln(n, e = {}) {
|
|
|
4579
4614
|
}
|
|
4580
4615
|
};
|
|
4581
4616
|
}
|
|
4582
|
-
function
|
|
4617
|
+
function yo(n, e) {
|
|
4583
4618
|
async function t() {
|
|
4584
4619
|
return (await e()).collection(n);
|
|
4585
4620
|
}
|
|
@@ -4658,25 +4693,25 @@ function co(n, e) {
|
|
|
4658
4693
|
}
|
|
4659
4694
|
|
|
4660
4695
|
// src/checkout.ts
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
function
|
|
4696
|
+
C();
|
|
4697
|
+
F();
|
|
4698
|
+
function et(n, e) {
|
|
4664
4699
|
let t = n?.accessToken || n?.idToken;
|
|
4665
4700
|
if (!t || typeof t != "string")
|
|
4666
|
-
throw new
|
|
4701
|
+
throw new c(
|
|
4667
4702
|
"validation_failed",
|
|
4668
4703
|
`checkout.${e} requer o access_token OU o id_token OIDC do usu\xE1rio final (passe \`accessToken\` ou \`idToken\`). A chave de API do SDK (nrt_*) N\xC3O \xE9 aceita pelo endpoint de checkout \u2014 ele autentica a identidade do cliente que est\xE1 assinando (Bearer access_token/id_token OIDC ou cookie de sess\xE3o). No padr\xE3o BFF/cookie, passe o \`idToken\` que seu servidor guardou no cookie httpOnly.`
|
|
4669
4704
|
);
|
|
4670
4705
|
return { requireAuth: false, headers: { authorization: `Bearer ${t}` } };
|
|
4671
4706
|
}
|
|
4672
|
-
function
|
|
4707
|
+
function _o(n) {
|
|
4673
4708
|
if (!n || typeof n != "object")
|
|
4674
|
-
throw new
|
|
4709
|
+
throw new c("invalid_response", "checkout.start response is not an object");
|
|
4675
4710
|
let e = n;
|
|
4676
4711
|
if (typeof e.intentId != "string" || !e.intentId)
|
|
4677
|
-
throw new
|
|
4712
|
+
throw new c("invalid_response", "checkout.start response missing intentId");
|
|
4678
4713
|
if (typeof e.redirectUrl != "string" || !e.redirectUrl)
|
|
4679
|
-
throw new
|
|
4714
|
+
throw new c("invalid_response", "checkout.start response missing redirectUrl");
|
|
4680
4715
|
return {
|
|
4681
4716
|
intentId: e.intentId,
|
|
4682
4717
|
redirectUrl: e.redirectUrl,
|
|
@@ -4685,14 +4720,14 @@ function lo(n) {
|
|
|
4685
4720
|
requiresKyc: e.requiresKyc === true
|
|
4686
4721
|
};
|
|
4687
4722
|
}
|
|
4688
|
-
function
|
|
4723
|
+
function bo(n) {
|
|
4689
4724
|
if (!n || typeof n != "object")
|
|
4690
|
-
throw new
|
|
4725
|
+
throw new c("invalid_response", "checkout.get response is not an object");
|
|
4691
4726
|
let e = n, t = e.intent;
|
|
4692
4727
|
if (!t || typeof t != "object")
|
|
4693
|
-
throw new
|
|
4728
|
+
throw new c("invalid_response", "checkout.get response missing intent");
|
|
4694
4729
|
if (typeof t.intentId != "string")
|
|
4695
|
-
throw new
|
|
4730
|
+
throw new c("invalid_response", "checkout.get response missing intentId");
|
|
4696
4731
|
return {
|
|
4697
4732
|
intentId: t.intentId,
|
|
4698
4733
|
uid: t.uid ?? "",
|
|
@@ -4707,35 +4742,35 @@ function uo(n) {
|
|
|
4707
4742
|
isStale: e.isStale === true
|
|
4708
4743
|
};
|
|
4709
4744
|
}
|
|
4710
|
-
function
|
|
4745
|
+
function vo() {
|
|
4711
4746
|
try {
|
|
4712
4747
|
return typeof globalThis < "u" && typeof globalThis.window < "u" && typeof globalThis.location < "u" && typeof globalThis.location.assign == "function";
|
|
4713
4748
|
} catch {
|
|
4714
4749
|
return false;
|
|
4715
4750
|
}
|
|
4716
4751
|
}
|
|
4717
|
-
function
|
|
4752
|
+
function wo(n) {
|
|
4718
4753
|
try {
|
|
4719
4754
|
globalThis.location.assign(n);
|
|
4720
4755
|
} catch {
|
|
4721
4756
|
}
|
|
4722
4757
|
}
|
|
4723
|
-
function
|
|
4758
|
+
function ko(n) {
|
|
4724
4759
|
return {
|
|
4725
4760
|
async start(e) {
|
|
4726
4761
|
if (!e?.productId)
|
|
4727
|
-
throw new
|
|
4762
|
+
throw new c("validation_failed", "checkout.start: productId is required");
|
|
4728
4763
|
if (!e?.planId)
|
|
4729
|
-
throw new
|
|
4764
|
+
throw new c("validation_failed", "checkout.start: planId is required");
|
|
4730
4765
|
if (!e?.callbackUrl)
|
|
4731
|
-
throw new
|
|
4766
|
+
throw new c("validation_failed", "checkout.start: callbackUrl is required");
|
|
4732
4767
|
let t = {
|
|
4733
4768
|
productId: e.productId,
|
|
4734
4769
|
planId: e.planId,
|
|
4735
4770
|
callbackUrl: e.callbackUrl
|
|
4736
4771
|
};
|
|
4737
4772
|
e.tenantType && (t.targetTenantType = e.tenantType), e.tenantId && (t.targetTenantId = e.tenantId);
|
|
4738
|
-
let { requireAuth: r, headers: o } =
|
|
4773
|
+
let { requireAuth: r, headers: o } = et(
|
|
4739
4774
|
{ accessToken: e.accessToken, idToken: e.idToken },
|
|
4740
4775
|
"start"
|
|
4741
4776
|
), i = await v(n, {
|
|
@@ -4745,13 +4780,13 @@ function mo(n) {
|
|
|
4745
4780
|
requireAuth: r,
|
|
4746
4781
|
headers: o,
|
|
4747
4782
|
idempotencyKey: true
|
|
4748
|
-
}), s =
|
|
4749
|
-
return e.autoRedirect !== false &&
|
|
4783
|
+
}), s = _o(i);
|
|
4784
|
+
return e.autoRedirect !== false && vo() && wo(s.redirectUrl), s;
|
|
4750
4785
|
},
|
|
4751
4786
|
async get(e, t) {
|
|
4752
4787
|
if (!e || typeof e != "string")
|
|
4753
|
-
throw new
|
|
4754
|
-
let { requireAuth: r, headers: o } =
|
|
4788
|
+
throw new c("validation_failed", "checkout.get: intentId is required");
|
|
4789
|
+
let { requireAuth: r, headers: o } = et(
|
|
4755
4790
|
{ accessToken: t?.accessToken, idToken: t?.idToken },
|
|
4756
4791
|
"get"
|
|
4757
4792
|
), i = await v(n, {
|
|
@@ -4760,12 +4795,12 @@ function mo(n) {
|
|
|
4760
4795
|
requireAuth: r,
|
|
4761
4796
|
headers: o
|
|
4762
4797
|
});
|
|
4763
|
-
return
|
|
4798
|
+
return bo(i);
|
|
4764
4799
|
},
|
|
4765
4800
|
async cancel(e, t) {
|
|
4766
4801
|
if (!e || typeof e != "string")
|
|
4767
|
-
throw new
|
|
4768
|
-
let { requireAuth: r, headers: o } =
|
|
4802
|
+
throw new c("validation_failed", "checkout.cancel: intentId is required");
|
|
4803
|
+
let { requireAuth: r, headers: o } = et(
|
|
4769
4804
|
{ accessToken: t?.accessToken, idToken: t?.idToken },
|
|
4770
4805
|
"cancel"
|
|
4771
4806
|
);
|
|
@@ -4781,15 +4816,15 @@ function mo(n) {
|
|
|
4781
4816
|
}
|
|
4782
4817
|
};
|
|
4783
4818
|
}
|
|
4784
|
-
var
|
|
4819
|
+
var tt = class {
|
|
4785
4820
|
intents = /* @__PURE__ */ new Map();
|
|
4786
4821
|
async start(e) {
|
|
4787
4822
|
if (!e?.productId)
|
|
4788
|
-
throw new
|
|
4823
|
+
throw new c("validation_failed", "checkout.start: productId is required");
|
|
4789
4824
|
if (!e?.planId)
|
|
4790
|
-
throw new
|
|
4825
|
+
throw new c("validation_failed", "checkout.start: planId is required");
|
|
4791
4826
|
if (!e?.callbackUrl)
|
|
4792
|
-
throw new
|
|
4827
|
+
throw new c("validation_failed", "checkout.start: callbackUrl is required");
|
|
4793
4828
|
let t = `chk_mock_${Math.random().toString(36).slice(2, 10)}`, r = new Date(Date.now() + 900 * 1e3).toISOString(), o = `https://localhost:9003/portal/checkout/${t}`;
|
|
4794
4829
|
return this.intents.set(t, {
|
|
4795
4830
|
intentId: t,
|
|
@@ -4813,25 +4848,25 @@ var Ze = class {
|
|
|
4813
4848
|
async get(e, t) {
|
|
4814
4849
|
let r = this.intents.get(e);
|
|
4815
4850
|
if (!r)
|
|
4816
|
-
throw new
|
|
4851
|
+
throw new c("not_found", `Mock intent ${e} not found`);
|
|
4817
4852
|
return { ...r };
|
|
4818
4853
|
}
|
|
4819
4854
|
async cancel(e, t) {
|
|
4820
4855
|
let r = this.intents.get(e);
|
|
4821
4856
|
if (!r)
|
|
4822
|
-
throw new
|
|
4857
|
+
throw new c("not_found", `Mock intent ${e} not found`);
|
|
4823
4858
|
let o = r.status === "cancelled";
|
|
4824
4859
|
return this.intents.set(e, { ...r, status: "cancelled" }), { ok: true, alreadyCancelled: o };
|
|
4825
4860
|
}
|
|
4826
4861
|
};
|
|
4827
|
-
function
|
|
4828
|
-
return n.env
|
|
4862
|
+
function fn(n) {
|
|
4863
|
+
return W(n.env) ? new tt() : ko(n);
|
|
4829
4864
|
}
|
|
4830
4865
|
|
|
4831
4866
|
// src/webhooks.ts
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
var
|
|
4867
|
+
C();
|
|
4868
|
+
F();
|
|
4869
|
+
var hn = [
|
|
4835
4870
|
"subscription.activated",
|
|
4836
4871
|
"subscription.cancelled",
|
|
4837
4872
|
"subscription.payment_failed",
|
|
@@ -4841,17 +4876,17 @@ var pn = [
|
|
|
4841
4876
|
"account.reactivated",
|
|
4842
4877
|
"support.ticket_replied"
|
|
4843
4878
|
];
|
|
4844
|
-
function
|
|
4879
|
+
function mn(n) {
|
|
4845
4880
|
if (!n || typeof n != "object")
|
|
4846
|
-
throw new
|
|
4881
|
+
throw new c("invalid_response", "Webhook response is not an object");
|
|
4847
4882
|
let e = n;
|
|
4848
4883
|
if (typeof e.id != "string")
|
|
4849
|
-
throw new
|
|
4884
|
+
throw new c("invalid_response", "Webhook missing id");
|
|
4850
4885
|
return {
|
|
4851
4886
|
id: e.id,
|
|
4852
4887
|
url: typeof e.url == "string" ? e.url : "",
|
|
4853
4888
|
events: Array.isArray(e.events) ? e.events.filter(
|
|
4854
|
-
(t) =>
|
|
4889
|
+
(t) => hn.includes(t)
|
|
4855
4890
|
) : [],
|
|
4856
4891
|
hasSecret: e.hasSecret === true,
|
|
4857
4892
|
status: e.status === "active" || e.status === "degraded" || e.status === "disabled" ? e.status : "active",
|
|
@@ -4860,40 +4895,40 @@ function un(n) {
|
|
|
4860
4895
|
createdAt: typeof e.createdAt == "string" ? e.createdAt : (/* @__PURE__ */ new Date()).toISOString()
|
|
4861
4896
|
};
|
|
4862
4897
|
}
|
|
4863
|
-
function
|
|
4898
|
+
function gn(n) {
|
|
4864
4899
|
if (!n.url || typeof n.url != "string")
|
|
4865
|
-
throw new
|
|
4900
|
+
throw new c("validation_failed", "url \xE9 obrigat\xF3ria");
|
|
4866
4901
|
try {
|
|
4867
4902
|
let e = new URL(n.url);
|
|
4868
4903
|
if (e.protocol !== "https:" && e.protocol !== "http:")
|
|
4869
4904
|
throw new Error("invalid protocol");
|
|
4870
4905
|
} catch {
|
|
4871
|
-
throw new
|
|
4906
|
+
throw new c("validation_failed", `url inv\xE1lida: ${n.url}`);
|
|
4872
4907
|
}
|
|
4873
4908
|
if (!Array.isArray(n.events) || n.events.length === 0)
|
|
4874
|
-
throw new
|
|
4909
|
+
throw new c("validation_failed", "events deve ter pelo menos 1 evento");
|
|
4875
4910
|
for (let e of n.events)
|
|
4876
|
-
if (!
|
|
4877
|
-
throw new
|
|
4911
|
+
if (!hn.includes(e))
|
|
4912
|
+
throw new c("validation_failed", `evento desconhecido: ${e}`);
|
|
4878
4913
|
if (n.secret !== void 0 && n.secret.length < 16)
|
|
4879
|
-
throw new
|
|
4914
|
+
throw new c("validation_failed", "secret deve ter \u226516 chars (recomendado 32+)");
|
|
4880
4915
|
}
|
|
4881
|
-
function
|
|
4916
|
+
function Se(n, ...e) {
|
|
4882
4917
|
for (let t of e)
|
|
4883
4918
|
if (typeof t == "string" && t.length > 0)
|
|
4884
4919
|
return N("productId", t), t;
|
|
4885
4920
|
if (n.productId)
|
|
4886
4921
|
return N("productId", n.productId), n.productId;
|
|
4887
|
-
throw new
|
|
4922
|
+
throw new c(
|
|
4888
4923
|
"validation_failed",
|
|
4889
4924
|
"productId required (pass to options/input or set on createNeetruClient)"
|
|
4890
4925
|
);
|
|
4891
4926
|
}
|
|
4892
|
-
function
|
|
4927
|
+
function yn(n) {
|
|
4893
4928
|
return {
|
|
4894
4929
|
async register(e) {
|
|
4895
|
-
|
|
4896
|
-
let t =
|
|
4930
|
+
gn(e);
|
|
4931
|
+
let t = Se(n, e.productId), r = await v(n, {
|
|
4897
4932
|
method: "POST",
|
|
4898
4933
|
path: "/api/sdk/v1/webhooks",
|
|
4899
4934
|
body: {
|
|
@@ -4909,20 +4944,20 @@ function mn(n) {
|
|
|
4909
4944
|
// dedup TTL 24h (mesmo padrão de usage.report/support.createTicket).
|
|
4910
4945
|
idempotencyKey: true
|
|
4911
4946
|
});
|
|
4912
|
-
return
|
|
4947
|
+
return mn(r);
|
|
4913
4948
|
},
|
|
4914
4949
|
async list(e) {
|
|
4915
|
-
let t =
|
|
4950
|
+
let t = Se(n, e?.productId), r = await v(n, {
|
|
4916
4951
|
method: "GET",
|
|
4917
4952
|
path: "/api/sdk/v1/webhooks",
|
|
4918
4953
|
query: { productId: t },
|
|
4919
4954
|
requireAuth: true
|
|
4920
4955
|
});
|
|
4921
|
-
return (Array.isArray(r?.endpoints) ? r.endpoints : []).map(
|
|
4956
|
+
return (Array.isArray(r?.endpoints) ? r.endpoints : []).map(mn);
|
|
4922
4957
|
},
|
|
4923
4958
|
async unregister(e, t) {
|
|
4924
|
-
if (!e) throw new
|
|
4925
|
-
let r =
|
|
4959
|
+
if (!e) throw new c("validation_failed", "id obrigat\xF3rio");
|
|
4960
|
+
let r = Se(n, t?.productId);
|
|
4926
4961
|
return await v(n, {
|
|
4927
4962
|
method: "DELETE",
|
|
4928
4963
|
path: `/api/sdk/v1/webhooks/${encodeURIComponent(e)}`,
|
|
@@ -4931,8 +4966,8 @@ function mn(n) {
|
|
|
4931
4966
|
}), { ok: true };
|
|
4932
4967
|
},
|
|
4933
4968
|
async test(e, t) {
|
|
4934
|
-
if (!e) throw new
|
|
4935
|
-
let r =
|
|
4969
|
+
if (!e) throw new c("validation_failed", "id obrigat\xF3rio");
|
|
4970
|
+
let r = Se(n, t?.productId), o = await v(n, {
|
|
4936
4971
|
method: "POST",
|
|
4937
4972
|
path: `/api/sdk/v1/webhooks/${encodeURIComponent(e)}/test`,
|
|
4938
4973
|
query: { productId: r },
|
|
@@ -4951,11 +4986,11 @@ function mn(n) {
|
|
|
4951
4986
|
}
|
|
4952
4987
|
};
|
|
4953
4988
|
}
|
|
4954
|
-
var
|
|
4989
|
+
var Te = class {
|
|
4955
4990
|
endpoints = /* @__PURE__ */ new Map();
|
|
4956
4991
|
nextId = 1;
|
|
4957
4992
|
async register(e) {
|
|
4958
|
-
|
|
4993
|
+
gn(e);
|
|
4959
4994
|
let t = `mock_wh_${this.nextId++}`, r = {
|
|
4960
4995
|
id: t,
|
|
4961
4996
|
url: e.url,
|
|
@@ -4971,32 +5006,32 @@ var Se = class {
|
|
|
4971
5006
|
}
|
|
4972
5007
|
async unregister(e, t) {
|
|
4973
5008
|
if (!this.endpoints.has(e))
|
|
4974
|
-
throw new
|
|
5009
|
+
throw new c("not_found", `Webhook ${e} n\xE3o encontrado`);
|
|
4975
5010
|
return this.endpoints.delete(e), { ok: true };
|
|
4976
5011
|
}
|
|
4977
5012
|
async test(e, t) {
|
|
4978
5013
|
if (!this.endpoints.has(e))
|
|
4979
|
-
throw new
|
|
5014
|
+
throw new c("not_found", `Webhook ${e} n\xE3o encontrado`);
|
|
4980
5015
|
return { ok: true, statusCode: 200, durationMs: 42 };
|
|
4981
5016
|
}
|
|
4982
5017
|
};
|
|
4983
5018
|
|
|
4984
5019
|
// src/notifications.ts
|
|
4985
|
-
|
|
4986
|
-
|
|
4987
|
-
var
|
|
5020
|
+
C();
|
|
5021
|
+
F();
|
|
5022
|
+
var nt = [
|
|
4988
5023
|
"info",
|
|
4989
5024
|
"success",
|
|
4990
5025
|
"warning",
|
|
4991
5026
|
"error"
|
|
4992
5027
|
];
|
|
4993
|
-
function
|
|
5028
|
+
function _n(n) {
|
|
4994
5029
|
if (!n || typeof n != "object")
|
|
4995
|
-
throw new
|
|
5030
|
+
throw new c("invalid_response", "Notification response is not an object");
|
|
4996
5031
|
let e = n;
|
|
4997
5032
|
if (typeof e.id != "string")
|
|
4998
|
-
throw new
|
|
4999
|
-
let t =
|
|
5033
|
+
throw new c("invalid_response", "Notification missing id");
|
|
5034
|
+
let t = nt.includes(e.severity) ? e.severity : "info";
|
|
5000
5035
|
return {
|
|
5001
5036
|
id: e.id,
|
|
5002
5037
|
userId: typeof e.userId == "string" ? e.userId : "",
|
|
@@ -5011,37 +5046,37 @@ function hn(n) {
|
|
|
5011
5046
|
dismissedAt: typeof e.dismissedAt == "string" ? e.dismissedAt : void 0
|
|
5012
5047
|
};
|
|
5013
5048
|
}
|
|
5014
|
-
function
|
|
5015
|
-
if (!n.userId) throw new
|
|
5016
|
-
if (!n.kind) throw new
|
|
5017
|
-
if (!n.title) throw new
|
|
5018
|
-
if (n.severity && !
|
|
5019
|
-
throw new
|
|
5049
|
+
function bn(n) {
|
|
5050
|
+
if (!n.userId) throw new c("validation_failed", "userId obrigat\xF3rio");
|
|
5051
|
+
if (!n.kind) throw new c("validation_failed", "kind obrigat\xF3rio");
|
|
5052
|
+
if (!n.title) throw new c("validation_failed", "title obrigat\xF3rio");
|
|
5053
|
+
if (n.severity && !nt.includes(n.severity))
|
|
5054
|
+
throw new c(
|
|
5020
5055
|
"validation_failed",
|
|
5021
|
-
`severity inv\xE1lida: ${n.severity} (use ${
|
|
5056
|
+
`severity inv\xE1lida: ${n.severity} (use ${nt.join("|")})`
|
|
5022
5057
|
);
|
|
5023
5058
|
if (n.title.length > 200)
|
|
5024
|
-
throw new
|
|
5059
|
+
throw new c("validation_failed", "title m\xE1x 200 chars");
|
|
5025
5060
|
if (n.body && n.body.length > 2e3)
|
|
5026
|
-
throw new
|
|
5061
|
+
throw new c("validation_failed", "body m\xE1x 2000 chars");
|
|
5027
5062
|
}
|
|
5028
|
-
function
|
|
5063
|
+
function Re(n, ...e) {
|
|
5029
5064
|
for (let t of e)
|
|
5030
5065
|
if (typeof t == "string" && t.length > 0)
|
|
5031
5066
|
return N("productId", t), t;
|
|
5032
5067
|
if (n.productId)
|
|
5033
5068
|
return N("productId", n.productId), n.productId;
|
|
5034
|
-
throw new
|
|
5069
|
+
throw new c(
|
|
5035
5070
|
"validation_failed",
|
|
5036
5071
|
"productId required (pass to options/input or set on createNeetruClient)"
|
|
5037
5072
|
);
|
|
5038
5073
|
}
|
|
5039
|
-
function
|
|
5074
|
+
function vn(n) {
|
|
5040
5075
|
return {
|
|
5041
5076
|
async send(e) {
|
|
5042
|
-
|
|
5077
|
+
bn(e);
|
|
5043
5078
|
let r = {
|
|
5044
|
-
productId:
|
|
5079
|
+
productId: Re(n, e.productId),
|
|
5045
5080
|
userId: e.userId,
|
|
5046
5081
|
kind: e.kind,
|
|
5047
5082
|
title: e.title,
|
|
@@ -5055,12 +5090,12 @@ function yn(n) {
|
|
|
5055
5090
|
requireAuth: true,
|
|
5056
5091
|
idempotencyKey: true
|
|
5057
5092
|
});
|
|
5058
|
-
return
|
|
5093
|
+
return _n(o);
|
|
5059
5094
|
},
|
|
5060
5095
|
async list(e, t) {
|
|
5061
|
-
if (!e) throw new
|
|
5096
|
+
if (!e) throw new c("validation_failed", "userId obrigat\xF3rio");
|
|
5062
5097
|
let o = {
|
|
5063
|
-
productId:
|
|
5098
|
+
productId: Re(n, t?.productId)
|
|
5064
5099
|
};
|
|
5065
5100
|
t?.includeDismissed && (o.includeDismissed = true), t?.onlyUnread && (o.onlyUnread = true), t?.limit && (o.limit = Math.min(Math.max(1, t.limit), 200));
|
|
5066
5101
|
let i = await v(n, {
|
|
@@ -5069,11 +5104,11 @@ function yn(n) {
|
|
|
5069
5104
|
query: o,
|
|
5070
5105
|
requireAuth: true
|
|
5071
5106
|
});
|
|
5072
|
-
return (Array.isArray(i?.notifications) ? i.notifications : []).map(
|
|
5107
|
+
return (Array.isArray(i?.notifications) ? i.notifications : []).map(_n);
|
|
5073
5108
|
},
|
|
5074
5109
|
async markRead(e, t) {
|
|
5075
|
-
if (!e) throw new
|
|
5076
|
-
let r =
|
|
5110
|
+
if (!e) throw new c("validation_failed", "id obrigat\xF3rio");
|
|
5111
|
+
let r = Re(n, t?.productId);
|
|
5077
5112
|
return await v(n, {
|
|
5078
5113
|
method: "POST",
|
|
5079
5114
|
path: `/api/sdk/v1/notifications/${encodeURIComponent(e)}/read`,
|
|
@@ -5082,8 +5117,8 @@ function yn(n) {
|
|
|
5082
5117
|
}), { ok: true };
|
|
5083
5118
|
},
|
|
5084
5119
|
async dismiss(e, t) {
|
|
5085
|
-
if (!e) throw new
|
|
5086
|
-
let r =
|
|
5120
|
+
if (!e) throw new c("validation_failed", "id obrigat\xF3rio");
|
|
5121
|
+
let r = Re(n, t?.productId);
|
|
5087
5122
|
return await v(n, {
|
|
5088
5123
|
method: "POST",
|
|
5089
5124
|
path: `/api/sdk/v1/notifications/${encodeURIComponent(e)}/dismiss`,
|
|
@@ -5093,11 +5128,11 @@ function yn(n) {
|
|
|
5093
5128
|
}
|
|
5094
5129
|
};
|
|
5095
5130
|
}
|
|
5096
|
-
var
|
|
5131
|
+
var Ie = class {
|
|
5097
5132
|
notifications = /* @__PURE__ */ new Map();
|
|
5098
5133
|
nextId = 1;
|
|
5099
5134
|
async send(e) {
|
|
5100
|
-
if (
|
|
5135
|
+
if (bn(e), e.fingerprint) {
|
|
5101
5136
|
let o = Date.now() - 864e5;
|
|
5102
5137
|
for (let i of this.notifications.values())
|
|
5103
5138
|
if ((i.metadata ?? {}).fingerprint === e.fingerprint && i.userId === e.userId && new Date(i.createdAt).getTime() > o)
|
|
@@ -5117,61 +5152,61 @@ var Re = class {
|
|
|
5117
5152
|
return this.notifications.set(t, r), r;
|
|
5118
5153
|
}
|
|
5119
5154
|
async list(e, t) {
|
|
5120
|
-
if (!e) throw new
|
|
5155
|
+
if (!e) throw new c("validation_failed", "userId obrigat\xF3rio");
|
|
5121
5156
|
let r = Math.min(Math.max(1, t?.limit ?? 50), 200);
|
|
5122
5157
|
return [...this.notifications.values()].filter((o) => o.userId === e).filter((o) => t?.includeDismissed || !o.dismissedAt).filter((o) => !t?.onlyUnread || !o.readAt).sort((o, i) => i.createdAt.localeCompare(o.createdAt)).slice(0, r);
|
|
5123
5158
|
}
|
|
5124
5159
|
async markRead(e, t) {
|
|
5125
5160
|
let r = this.notifications.get(e);
|
|
5126
|
-
if (!r) throw new
|
|
5161
|
+
if (!r) throw new c("not_found", `Notification ${e} n\xE3o encontrada`);
|
|
5127
5162
|
return r.readAt || (r.readAt = (/* @__PURE__ */ new Date()).toISOString(), this.notifications.set(e, r)), { ok: true };
|
|
5128
5163
|
}
|
|
5129
5164
|
async dismiss(e, t) {
|
|
5130
5165
|
let r = this.notifications.get(e);
|
|
5131
|
-
if (!r) throw new
|
|
5166
|
+
if (!r) throw new c("not_found", `Notification ${e} n\xE3o encontrada`);
|
|
5132
5167
|
return r.dismissedAt || (r.dismissedAt = (/* @__PURE__ */ new Date()).toISOString(), this.notifications.set(e, r)), { ok: true };
|
|
5133
5168
|
}
|
|
5134
5169
|
};
|
|
5135
5170
|
|
|
5136
5171
|
// src/ai.ts
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
var
|
|
5172
|
+
C();
|
|
5173
|
+
F();
|
|
5174
|
+
qe();
|
|
5175
|
+
var So = "/api/sdk/v1/ai/chat", wn = 12e4, Ce = 32768, kn = 32, Sn = 4194304, Tn = 2048, To = /^data:image\/(?:png|jpe?g|gif|webp);base64,[A-Za-z0-9+/]+={0,2}$/, Ro = /^https:\/\/[^\s]+$/, Io = /* @__PURE__ */ new Set(["low", "high", "auto"]), Co = /* @__PURE__ */ new Set(["system", "user", "assistant"]), Rn = 100, In = 128, Cn = 32768, An = 0, En = 2, Pn = 200, Dn = 20, Nn = 12 * 1024 * 1024, xn = 5e4, On = 16, Ln = 500, Ao = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]), Eo = /^[a-zA-Z0-9_-]+$/;
|
|
5141
5176
|
function k(n) {
|
|
5142
|
-
throw new
|
|
5177
|
+
throw new c("validation_failed", n);
|
|
5143
5178
|
}
|
|
5144
|
-
function
|
|
5179
|
+
function Po(n) {
|
|
5145
5180
|
if (n.length === 0 || n.length % 4 !== 0) return false;
|
|
5146
5181
|
let e = n.endsWith("==") ? 2 : n.endsWith("=") ? 1 : 0;
|
|
5147
5182
|
return !(e > 0 ? n.slice(0, n.length - e) : n).includes("=");
|
|
5148
5183
|
}
|
|
5149
|
-
function
|
|
5184
|
+
function Do(n) {
|
|
5150
5185
|
let e = n.indexOf(",");
|
|
5151
5186
|
if (e === -1) return 0;
|
|
5152
5187
|
let t = n.slice(e + 1), r = t.endsWith("==") ? 2 : t.endsWith("=") ? 1 : 0;
|
|
5153
5188
|
return Math.max(0, Math.floor(t.length * 3 / 4) - r);
|
|
5154
5189
|
}
|
|
5155
|
-
function
|
|
5190
|
+
function No(n) {
|
|
5156
5191
|
let e = 0, t = 0, r = 0;
|
|
5157
5192
|
for (let o of n) {
|
|
5158
5193
|
let i = o?.content;
|
|
5159
5194
|
if (Array.isArray(i))
|
|
5160
5195
|
for (let s of i) {
|
|
5161
|
-
if (e++, e >
|
|
5162
|
-
return `ai: total content parts exceeds ${
|
|
5196
|
+
if (e++, e > Pn)
|
|
5197
|
+
return `ai: total content parts exceeds ${Pn} per request`;
|
|
5163
5198
|
if (s && typeof s == "object" && s.type === "image_url") {
|
|
5164
|
-
if (t++, t >
|
|
5165
|
-
return `ai: total images exceeds ${
|
|
5199
|
+
if (t++, t > Dn)
|
|
5200
|
+
return `ai: total images exceeds ${Dn} per request`;
|
|
5166
5201
|
let a = s.image_url?.url;
|
|
5167
|
-
if (typeof a == "string" && a.startsWith("data:") && (r +=
|
|
5168
|
-
return `ai: aggregate image bytes exceeds ${
|
|
5202
|
+
if (typeof a == "string" && a.startsWith("data:") && (r += Do(a), r > Nn))
|
|
5203
|
+
return `ai: aggregate image bytes exceeds ${Nn} per request`;
|
|
5169
5204
|
}
|
|
5170
5205
|
}
|
|
5171
5206
|
}
|
|
5172
5207
|
return null;
|
|
5173
5208
|
}
|
|
5174
|
-
function
|
|
5209
|
+
function xo(n) {
|
|
5175
5210
|
if (n === void 0) return null;
|
|
5176
5211
|
if (n === null || typeof n != "object")
|
|
5177
5212
|
return "ai: responseFormat json_schema.schema must be an object";
|
|
@@ -5182,11 +5217,11 @@ function Ro(n) {
|
|
|
5182
5217
|
return "ai: responseFormat json_schema.schema is not serializable";
|
|
5183
5218
|
}
|
|
5184
5219
|
if (e === void 0) return "ai: responseFormat json_schema.schema is invalid";
|
|
5185
|
-
if (e.length >
|
|
5186
|
-
return `ai: responseFormat json_schema.schema exceeds ${
|
|
5220
|
+
if (e.length > xn)
|
|
5221
|
+
return `ai: responseFormat json_schema.schema exceeds ${xn} serialized chars`;
|
|
5187
5222
|
let t = 0, r = (o, i) => {
|
|
5188
|
-
if (i >
|
|
5189
|
-
return `ai: responseFormat json_schema.schema exceeds max depth ${
|
|
5223
|
+
if (i > On)
|
|
5224
|
+
return `ai: responseFormat json_schema.schema exceeds max depth ${On}`;
|
|
5190
5225
|
if (Array.isArray(o)) {
|
|
5191
5226
|
for (let s of o) {
|
|
5192
5227
|
let a = r(s, i + 1);
|
|
@@ -5196,10 +5231,10 @@ function Ro(n) {
|
|
|
5196
5231
|
}
|
|
5197
5232
|
if (o && typeof o == "object")
|
|
5198
5233
|
for (let s of Object.getOwnPropertyNames(o)) {
|
|
5199
|
-
if (
|
|
5234
|
+
if (Ao.has(s))
|
|
5200
5235
|
return `ai: responseFormat json_schema.schema has forbidden key: ${s}`;
|
|
5201
|
-
if (t++, t >
|
|
5202
|
-
return `ai: responseFormat json_schema.schema exceeds ${
|
|
5236
|
+
if (t++, t > Ln)
|
|
5237
|
+
return `ai: responseFormat json_schema.schema exceeds ${Ln} keys`;
|
|
5203
5238
|
let a = r(o[s], i + 1);
|
|
5204
5239
|
if (a) return a;
|
|
5205
5240
|
}
|
|
@@ -5207,44 +5242,44 @@ function Ro(n) {
|
|
|
5207
5242
|
};
|
|
5208
5243
|
return r(n, 0);
|
|
5209
5244
|
}
|
|
5210
|
-
function
|
|
5245
|
+
function Oo(n) {
|
|
5211
5246
|
(typeof n != "string" || n.length === 0) && k("ai: image_url.url must be a non-empty string");
|
|
5212
5247
|
let e = n;
|
|
5213
5248
|
if (e.startsWith("data:")) {
|
|
5214
|
-
e.length >
|
|
5249
|
+
e.length > Sn && k(`ai: image_url.url (data:) exceeds ${Sn} chars`), To.test(e) || k("ai: image_url.url data: must be data:image/<png|jpeg|jpg|gif|webp>;base64,<...>");
|
|
5215
5250
|
let t = e.slice(e.indexOf(",") + 1);
|
|
5216
|
-
|
|
5251
|
+
Po(t) || k("ai: image_url.url data: has invalid base64 (length/padding)");
|
|
5217
5252
|
return;
|
|
5218
5253
|
}
|
|
5219
5254
|
if (e.startsWith("https://")) {
|
|
5220
|
-
e.length >
|
|
5255
|
+
e.length > Tn && k(`ai: image_url.url (https:) exceeds ${Tn} chars`), Ro.test(e) || k("ai: image_url.url https: is invalid");
|
|
5221
5256
|
return;
|
|
5222
5257
|
}
|
|
5223
5258
|
k("ai: image_url.url must be a data:image/...;base64 or https:// URL (other schemes are rejected)");
|
|
5224
5259
|
}
|
|
5225
|
-
function
|
|
5260
|
+
function Lo(n, e) {
|
|
5226
5261
|
if (typeof n == "string") {
|
|
5227
|
-
n.length === 0 && k("ai: message content string must be non-empty"), n.length >
|
|
5262
|
+
n.length === 0 && k("ai: message content string must be non-empty"), n.length > Ce && k(`ai: message content exceeds ${Ce} chars`);
|
|
5228
5263
|
return;
|
|
5229
5264
|
}
|
|
5230
|
-
(!Array.isArray(n) || n.length === 0) && k("ai: message content must be a non-empty string or array of parts"), n.length >
|
|
5265
|
+
(!Array.isArray(n) || n.length === 0) && k("ai: message content must be a non-empty string or array of parts"), n.length > kn && k(`ai: message content has more than ${kn} parts`);
|
|
5231
5266
|
for (let t of n) {
|
|
5232
5267
|
(!t || typeof t != "object") && k("ai: each content part must be an object");
|
|
5233
5268
|
let r = t.type;
|
|
5234
5269
|
if (r === "text") {
|
|
5235
5270
|
let o = t.text;
|
|
5236
|
-
(typeof o != "string" || o.length === 0) && k("ai: text part must have non-empty { text: string }"), o.length >
|
|
5271
|
+
(typeof o != "string" || o.length === 0) && k("ai: text part must have non-empty { text: string }"), o.length > Ce && k(`ai: text part exceeds ${Ce} chars`);
|
|
5237
5272
|
} else if (r === "image_url") {
|
|
5238
5273
|
e !== "user" && k(`ai: image_url is only allowed in role 'user' messages (got '${e}')`);
|
|
5239
5274
|
let o = t.image_url;
|
|
5240
|
-
(!o || typeof o != "object") && k("ai: image_url part must have { image_url: { url } }"),
|
|
5275
|
+
(!o || typeof o != "object") && k("ai: image_url part must have { image_url: { url } }"), Oo(o.url);
|
|
5241
5276
|
let i = o.detail;
|
|
5242
|
-
i !== void 0 && (typeof i != "string" || !
|
|
5277
|
+
i !== void 0 && (typeof i != "string" || !Io.has(i)) && k("ai: image_url.detail must be 'low' | 'high' | 'auto'");
|
|
5243
5278
|
} else
|
|
5244
5279
|
k("ai: content part type must be 'text' or 'image_url'");
|
|
5245
5280
|
}
|
|
5246
5281
|
}
|
|
5247
|
-
function
|
|
5282
|
+
function Uo(n) {
|
|
5248
5283
|
(!n || typeof n != "object") && k("ai: responseFormat must be an object");
|
|
5249
5284
|
let e = n.type;
|
|
5250
5285
|
if (!(e === "text" || e === "json_object")) {
|
|
@@ -5252,8 +5287,8 @@ function Ao(n) {
|
|
|
5252
5287
|
let t = n.json_schema;
|
|
5253
5288
|
(!t || typeof t != "object") && k("ai: responseFormat json_schema requires { json_schema: { name } }");
|
|
5254
5289
|
let r = t, o = r.name;
|
|
5255
|
-
if ((typeof o != "string" || o.length === 0) && k("ai: responseFormat json_schema.name is required"), o.length > 64 && k("ai: responseFormat json_schema.name exceeds 64 chars"),
|
|
5256
|
-
let i =
|
|
5290
|
+
if ((typeof o != "string" || o.length === 0) && k("ai: responseFormat json_schema.name is required"), o.length > 64 && k("ai: responseFormat json_schema.name exceeds 64 chars"), Eo.test(o) || k("ai: responseFormat json_schema.name must match a-zA-Z0-9_-"), r.description !== void 0 && (typeof r.description != "string" && k("ai: responseFormat json_schema.description must be a string"), r.description.length > 1e3 && k("ai: responseFormat json_schema.description exceeds 1000 chars")), r.strict !== void 0 && typeof r.strict != "boolean" && k("ai: responseFormat json_schema.strict must be a boolean"), r.schema !== void 0) {
|
|
5291
|
+
let i = xo(r.schema);
|
|
5257
5292
|
i && k(i);
|
|
5258
5293
|
}
|
|
5259
5294
|
return;
|
|
@@ -5261,35 +5296,35 @@ function Ao(n) {
|
|
|
5261
5296
|
k("ai: responseFormat.type must be 'text' | 'json_object' | 'json_schema'");
|
|
5262
5297
|
}
|
|
5263
5298
|
}
|
|
5264
|
-
function
|
|
5299
|
+
function Un(n, e, t) {
|
|
5265
5300
|
if (!e || typeof e != "object")
|
|
5266
|
-
throw new
|
|
5301
|
+
throw new c("validation_failed", "ai: options object is required");
|
|
5267
5302
|
if (typeof e.model != "string" || e.model.length === 0)
|
|
5268
|
-
throw new
|
|
5269
|
-
if (e.model.length >
|
|
5270
|
-
throw new
|
|
5303
|
+
throw new c("validation_failed", "ai: model is required");
|
|
5304
|
+
if (e.model.length > In)
|
|
5305
|
+
throw new c("validation_failed", `ai: model exceeds ${In} chars`);
|
|
5271
5306
|
if (!Array.isArray(e.messages) || e.messages.length === 0)
|
|
5272
|
-
throw new
|
|
5273
|
-
if (e.messages.length >
|
|
5274
|
-
throw new
|
|
5307
|
+
throw new c("validation_failed", "ai: messages must be a non-empty array");
|
|
5308
|
+
if (e.messages.length > Rn)
|
|
5309
|
+
throw new c("validation_failed", `ai: messages exceeds ${Rn} per request`);
|
|
5275
5310
|
for (let a of e.messages) {
|
|
5276
|
-
if (!a || typeof a != "object" || typeof a.role != "string" || !
|
|
5277
|
-
throw new
|
|
5311
|
+
if (!a || typeof a != "object" || typeof a.role != "string" || !Co.has(a.role))
|
|
5312
|
+
throw new c(
|
|
5278
5313
|
"validation_failed",
|
|
5279
5314
|
"ai: each message role must be 'system' | 'user' | 'assistant'"
|
|
5280
5315
|
);
|
|
5281
|
-
|
|
5316
|
+
Lo(a.content, a.role);
|
|
5282
5317
|
}
|
|
5283
|
-
let r =
|
|
5284
|
-
if (r) throw new
|
|
5318
|
+
let r = No(e.messages);
|
|
5319
|
+
if (r) throw new c("validation_failed", r);
|
|
5285
5320
|
let o = e.productId ?? n.productId, i = e.tenantId ?? n.tenantId;
|
|
5286
5321
|
if (!o)
|
|
5287
|
-
throw new
|
|
5322
|
+
throw new c(
|
|
5288
5323
|
"validation_failed",
|
|
5289
5324
|
"ai: productId required (pass to options or set on createNeetruClient)"
|
|
5290
5325
|
);
|
|
5291
5326
|
if (!i)
|
|
5292
|
-
throw new
|
|
5327
|
+
throw new c(
|
|
5293
5328
|
"validation_failed",
|
|
5294
5329
|
"ai: tenantId required (pass to options or set on createNeetruClient)"
|
|
5295
5330
|
);
|
|
@@ -5302,24 +5337,24 @@ function xn(n, e, t) {
|
|
|
5302
5337
|
stream: t
|
|
5303
5338
|
};
|
|
5304
5339
|
if (e.maxTokens !== void 0) {
|
|
5305
|
-
if (!Number.isInteger(e.maxTokens) || e.maxTokens <= 0 || e.maxTokens >
|
|
5306
|
-
throw new
|
|
5340
|
+
if (!Number.isInteger(e.maxTokens) || e.maxTokens <= 0 || e.maxTokens > Cn)
|
|
5341
|
+
throw new c(
|
|
5307
5342
|
"validation_failed",
|
|
5308
|
-
`ai: maxTokens must be a positive integer <= ${
|
|
5343
|
+
`ai: maxTokens must be a positive integer <= ${Cn}`
|
|
5309
5344
|
);
|
|
5310
5345
|
s.maxTokens = e.maxTokens;
|
|
5311
5346
|
}
|
|
5312
5347
|
if (e.temperature !== void 0) {
|
|
5313
|
-
if (typeof e.temperature != "number" || !Number.isFinite(e.temperature) || e.temperature <
|
|
5314
|
-
throw new
|
|
5348
|
+
if (typeof e.temperature != "number" || !Number.isFinite(e.temperature) || e.temperature < An || e.temperature > En)
|
|
5349
|
+
throw new c(
|
|
5315
5350
|
"validation_failed",
|
|
5316
|
-
`ai: temperature must be a finite number between ${
|
|
5351
|
+
`ai: temperature must be a finite number between ${An} and ${En}`
|
|
5317
5352
|
);
|
|
5318
5353
|
s.temperature = e.temperature;
|
|
5319
5354
|
}
|
|
5320
|
-
return e.responseFormat !== void 0 && (
|
|
5355
|
+
return e.responseFormat !== void 0 && (Uo(e.responseFormat), s.responseFormat = e.responseFormat), s;
|
|
5321
5356
|
}
|
|
5322
|
-
async function
|
|
5357
|
+
async function jn(n) {
|
|
5323
5358
|
try {
|
|
5324
5359
|
let e = await n.text();
|
|
5325
5360
|
return e ? JSON.parse(e) : void 0;
|
|
@@ -5327,48 +5362,48 @@ async function Mn(n) {
|
|
|
5327
5362
|
return;
|
|
5328
5363
|
}
|
|
5329
5364
|
}
|
|
5330
|
-
function
|
|
5365
|
+
function Mo(n, e) {
|
|
5331
5366
|
let t = n.replace(/\/+$/, ""), r = e.startsWith("/") ? e : `/${e}`;
|
|
5332
5367
|
return `${t}${r}`;
|
|
5333
5368
|
}
|
|
5334
|
-
async function
|
|
5369
|
+
async function Mn(n, e, t, r) {
|
|
5335
5370
|
if (!n.apiKey)
|
|
5336
|
-
throw new
|
|
5371
|
+
throw new c(
|
|
5337
5372
|
"missing_api_key",
|
|
5338
5373
|
"ai requires an apiKey. Pass it to createNeetruClient({ apiKey }) or set NEETRU_API_KEY env var."
|
|
5339
5374
|
);
|
|
5340
|
-
let o =
|
|
5375
|
+
let o = Mo(n.baseUrl, So), { headers: i, correlationId: s } = ce({
|
|
5341
5376
|
"content-type": "application/json",
|
|
5342
5377
|
accept: r ? "text/event-stream" : "application/json",
|
|
5343
5378
|
authorization: `Bearer ${n.apiKey}`
|
|
5344
5379
|
}), a = { method: "POST", headers: i, body: JSON.stringify(e) };
|
|
5345
|
-
r ? t && (a.signal = t) : a.signal = t ?? AbortSignal.timeout(
|
|
5346
|
-
let
|
|
5380
|
+
r ? t && (a.signal = t) : a.signal = t ?? AbortSignal.timeout(wn);
|
|
5381
|
+
let l;
|
|
5347
5382
|
try {
|
|
5348
|
-
|
|
5383
|
+
l = await n.fetch(o, a);
|
|
5349
5384
|
} catch (p) {
|
|
5350
|
-
let f = p instanceof DOMException && p.name === "TimeoutError" ? `Network error: timeout after ${
|
|
5351
|
-
throw new
|
|
5385
|
+
let f = p instanceof DOMException && p.name === "TimeoutError" ? `Network error: timeout after ${wn / 1e3}s` : p instanceof DOMException && p.name === "AbortError" ? "Network error: request aborted" : `Network error: ${p instanceof Error ? p.message : "fetch failed"}`;
|
|
5386
|
+
throw new c("network_error", f, void 0, void 0, void 0, s);
|
|
5352
5387
|
}
|
|
5353
|
-
let d =
|
|
5354
|
-
if (!
|
|
5355
|
-
let p = await
|
|
5388
|
+
let d = l.headers.get("x-request-id") ?? l.headers.get("x-correlation-id") ?? void 0;
|
|
5389
|
+
if (!l.ok) {
|
|
5390
|
+
let p = await jn(l), f = de(l.status), h = `HTTP ${l.status}`;
|
|
5356
5391
|
if (p && typeof p == "object" && "error" in p) {
|
|
5357
|
-
let
|
|
5358
|
-
typeof
|
|
5392
|
+
let y = p.error;
|
|
5393
|
+
typeof y == "string" ? h = y : y && typeof y == "object" && (typeof y.code == "string" && (f = y.code), typeof y.message == "string" && (h = y.message));
|
|
5359
5394
|
}
|
|
5360
|
-
throw new
|
|
5395
|
+
throw new c(f, h, l.status, d, void 0, s);
|
|
5361
5396
|
}
|
|
5362
|
-
let u =
|
|
5363
|
-
return u &&
|
|
5397
|
+
let u = l.headers.get("x-neetru-version");
|
|
5398
|
+
return u && le(u), l;
|
|
5364
5399
|
}
|
|
5365
|
-
function
|
|
5400
|
+
function qn(n) {
|
|
5366
5401
|
return {
|
|
5367
5402
|
provider: n.headers.get("x-neetru-provider") ?? "",
|
|
5368
5403
|
usageWarning: n.headers.get("x-neetru-ai-usage-warning") === "1"
|
|
5369
5404
|
};
|
|
5370
5405
|
}
|
|
5371
|
-
function
|
|
5406
|
+
function Fn(n) {
|
|
5372
5407
|
let e = [];
|
|
5373
5408
|
for (let r of n.split(`
|
|
5374
5409
|
`)) {
|
|
@@ -5389,12 +5424,12 @@ function Un(n) {
|
|
|
5389
5424
|
return null;
|
|
5390
5425
|
}
|
|
5391
5426
|
}
|
|
5392
|
-
function
|
|
5427
|
+
function $n(n) {
|
|
5393
5428
|
return {
|
|
5394
5429
|
async chat(e) {
|
|
5395
|
-
let t =
|
|
5430
|
+
let t = Un(n, e, false), r = await Mn(n, t, e.signal, false), { provider: o, usageWarning: i } = qn(r), s = await jn(r);
|
|
5396
5431
|
if (!s || s.ok !== true || !Array.isArray(s.choices))
|
|
5397
|
-
throw new
|
|
5432
|
+
throw new c("invalid_response", "ai.chat response missing ok/choices");
|
|
5398
5433
|
return {
|
|
5399
5434
|
choices: s.choices,
|
|
5400
5435
|
usage: s.usage ?? { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 },
|
|
@@ -5404,38 +5439,38 @@ function qn(n) {
|
|
|
5404
5439
|
};
|
|
5405
5440
|
},
|
|
5406
5441
|
stream(e) {
|
|
5407
|
-
let t =
|
|
5442
|
+
let t = Un(n, e, true), r = Mn(n, t, e.signal, true), o = r.then(qn);
|
|
5408
5443
|
o.catch(() => {
|
|
5409
5444
|
});
|
|
5410
5445
|
async function* i() {
|
|
5411
5446
|
let a = (await r).body;
|
|
5412
5447
|
if (!a)
|
|
5413
|
-
throw new
|
|
5414
|
-
let
|
|
5448
|
+
throw new c("invalid_response", "ai.stream: response has no body");
|
|
5449
|
+
let l = a.getReader(), d = new TextDecoder(), u = "";
|
|
5415
5450
|
try {
|
|
5416
5451
|
for (; ; ) {
|
|
5417
|
-
let { done: f, value:
|
|
5452
|
+
let { done: f, value: h } = await l.read();
|
|
5418
5453
|
if (f) break;
|
|
5419
|
-
u += d.decode(
|
|
5420
|
-
let
|
|
5421
|
-
for (; (
|
|
5454
|
+
u += d.decode(h, { stream: !0 });
|
|
5455
|
+
let y;
|
|
5456
|
+
for (; (y = u.indexOf(`
|
|
5422
5457
|
|
|
5423
5458
|
`)) !== -1; ) {
|
|
5424
|
-
let
|
|
5425
|
-
u = u.slice(
|
|
5426
|
-
let x =
|
|
5459
|
+
let T = u.slice(0, y);
|
|
5460
|
+
u = u.slice(y + 2);
|
|
5461
|
+
let x = Fn(T);
|
|
5427
5462
|
if (x && "done" in x) return;
|
|
5428
5463
|
x && "content" in x && (yield x.content);
|
|
5429
5464
|
}
|
|
5430
5465
|
}
|
|
5431
5466
|
let p = u.trim();
|
|
5432
5467
|
if (p) {
|
|
5433
|
-
let f =
|
|
5468
|
+
let f = Fn(p);
|
|
5434
5469
|
f && "content" in f && (yield f.content);
|
|
5435
5470
|
}
|
|
5436
5471
|
} finally {
|
|
5437
5472
|
try {
|
|
5438
|
-
|
|
5473
|
+
l.releaseLock();
|
|
5439
5474
|
} catch {
|
|
5440
5475
|
}
|
|
5441
5476
|
try {
|
|
@@ -5453,20 +5488,8 @@ function qn(n) {
|
|
|
5453
5488
|
}
|
|
5454
5489
|
|
|
5455
5490
|
// src/mocks.ts
|
|
5456
|
-
|
|
5457
|
-
|
|
5458
|
-
// src/runtime-env.ts
|
|
5459
|
-
function Ce() {
|
|
5460
|
-
try {
|
|
5461
|
-
if (typeof process < "u" && process.env)
|
|
5462
|
-
return process.env.NODE_ENV === "production";
|
|
5463
|
-
} catch {
|
|
5464
|
-
}
|
|
5465
|
-
return false;
|
|
5466
|
-
}
|
|
5467
|
-
|
|
5468
|
-
// src/mocks.ts
|
|
5469
|
-
var tt = Object.freeze({
|
|
5491
|
+
C();
|
|
5492
|
+
var rt = Object.freeze({
|
|
5470
5493
|
uid: "dev-fixture-uid-0001",
|
|
5471
5494
|
email: "dev@neetru.local",
|
|
5472
5495
|
emailVerified: true,
|
|
@@ -5478,8 +5501,8 @@ var tt = Object.freeze({
|
|
|
5478
5501
|
_listeners;
|
|
5479
5502
|
_allowUnsignedDecode;
|
|
5480
5503
|
constructor(e = null, t) {
|
|
5481
|
-
if (this._user = e, this._listeners = /* @__PURE__ */ new Set(), this._allowUnsignedDecode = t?.allowUnsignedDecode ?? false, this._allowUnsignedDecode &&
|
|
5482
|
-
throw new
|
|
5504
|
+
if (this._user = e, this._listeners = /* @__PURE__ */ new Set(), this._allowUnsignedDecode = t?.allowUnsignedDecode ?? false, this._allowUnsignedDecode && $e())
|
|
5505
|
+
throw new c(
|
|
5483
5506
|
"invalid_config",
|
|
5484
5507
|
"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."
|
|
5485
5508
|
);
|
|
@@ -5488,10 +5511,10 @@ var tt = Object.freeze({
|
|
|
5488
5511
|
);
|
|
5489
5512
|
}
|
|
5490
5513
|
async signIn(e) {
|
|
5491
|
-
return this._user || (this._user = { ...
|
|
5514
|
+
return this._user || (this._user = { ...rt }), this._notify(), this._user;
|
|
5492
5515
|
}
|
|
5493
5516
|
async signOut() {
|
|
5494
|
-
this._user = null, this._notify();
|
|
5517
|
+
return this._user = null, this._notify(), { localSessionCleared: true, remoteRevocation: "skipped" };
|
|
5495
5518
|
}
|
|
5496
5519
|
getUser() {
|
|
5497
5520
|
return this._user;
|
|
@@ -5520,9 +5543,9 @@ var tt = Object.freeze({
|
|
|
5520
5543
|
if (this._verifyTokenOverride)
|
|
5521
5544
|
return this._verifyTokenOverride(e);
|
|
5522
5545
|
if (!e)
|
|
5523
|
-
throw new
|
|
5546
|
+
throw new c("token_invalid_signature", "Token inv\xE1lido: string vazia");
|
|
5524
5547
|
if (!this._allowUnsignedDecode)
|
|
5525
|
-
throw new
|
|
5548
|
+
throw new c(
|
|
5526
5549
|
"unauthorized",
|
|
5527
5550
|
"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."
|
|
5528
5551
|
);
|
|
@@ -5548,7 +5571,7 @@ var tt = Object.freeze({
|
|
|
5548
5571
|
} catch {
|
|
5549
5572
|
}
|
|
5550
5573
|
if (this._user) return this._user;
|
|
5551
|
-
throw new
|
|
5574
|
+
throw new c("token_invalid_signature", "Nenhum user mock dispon\xEDvel e JWT sem sub v\xE1lido");
|
|
5552
5575
|
}
|
|
5553
5576
|
/**
|
|
5554
5577
|
* Mock de `handleRedirectCallback` (Bug 2 / 3.1.3) — não há redirect real no
|
|
@@ -5626,14 +5649,14 @@ var tt = Object.freeze({
|
|
|
5626
5649
|
tenantId: r?.tenantId,
|
|
5627
5650
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
5628
5651
|
});
|
|
5629
|
-
let
|
|
5652
|
+
let l = this._quotas.get(e)?.limit ?? -1;
|
|
5630
5653
|
return {
|
|
5631
5654
|
ok: true,
|
|
5632
5655
|
counterId: `mock_${e}`,
|
|
5633
5656
|
value: s,
|
|
5634
|
-
limit:
|
|
5635
|
-
remaining:
|
|
5636
|
-
status:
|
|
5657
|
+
limit: l,
|
|
5658
|
+
remaining: l < 0 ? -1 : Math.max(0, l - s),
|
|
5659
|
+
status: l > 0 && s >= l ? "read_only_overlimit" : "ok"
|
|
5637
5660
|
};
|
|
5638
5661
|
}
|
|
5639
5662
|
async check(e, t) {
|
|
@@ -5675,10 +5698,10 @@ var tt = Object.freeze({
|
|
|
5675
5698
|
_tickets = [];
|
|
5676
5699
|
_ticketSeq = 0;
|
|
5677
5700
|
async createTicket(e) {
|
|
5678
|
-
if (!e?.subject) throw new
|
|
5679
|
-
if (!e?.message) throw new
|
|
5701
|
+
if (!e?.subject) throw new c("validation_failed", "subject required");
|
|
5702
|
+
if (!e?.message) throw new c("validation_failed", "message required");
|
|
5680
5703
|
if (!e?.productSlug)
|
|
5681
|
-
throw new
|
|
5704
|
+
throw new c(
|
|
5682
5705
|
"validation_failed",
|
|
5683
5706
|
"productSlug required (3.0 breaking \u2014 pass to input or set on createNeetruClient)"
|
|
5684
5707
|
);
|
|
@@ -5710,10 +5733,10 @@ var tt = Object.freeze({
|
|
|
5710
5733
|
}
|
|
5711
5734
|
_find(e) {
|
|
5712
5735
|
if (!e || typeof e != "string")
|
|
5713
|
-
throw new
|
|
5736
|
+
throw new c("validation_failed", "ticketId is required");
|
|
5714
5737
|
let t = this._tickets.find((r) => r.id === e);
|
|
5715
5738
|
if (!t)
|
|
5716
|
-
throw new
|
|
5739
|
+
throw new c("not_found", `ticket ${e} not found`);
|
|
5717
5740
|
return t;
|
|
5718
5741
|
}
|
|
5719
5742
|
/** 3.4: espelha `markResolvedSeen` — idempotente (só seta se ainda null). */
|
|
@@ -5729,18 +5752,18 @@ var tt = Object.freeze({
|
|
|
5729
5752
|
/** 3.4: espelha `submitSatisfaction` — terminal, seta `satisfiedAt`. */
|
|
5730
5753
|
async submitSatisfaction(e) {
|
|
5731
5754
|
if (!e || typeof e != "object")
|
|
5732
|
-
throw new
|
|
5755
|
+
throw new c("validation_failed", "input is required");
|
|
5733
5756
|
if (e.rating !== null && e.rating !== void 0 && (!Number.isInteger(e.rating) || e.rating < 1 || e.rating > 5))
|
|
5734
|
-
throw new
|
|
5757
|
+
throw new c("validation_failed", "rating must be an integer 1-5 or null");
|
|
5735
5758
|
if (typeof e.comment == "string" && e.comment.length > 2e3)
|
|
5736
|
-
throw new
|
|
5759
|
+
throw new c("validation_failed", "comment max 2000 chars");
|
|
5737
5760
|
let t = this._find(e.ticketId);
|
|
5738
5761
|
t.satisfiedAt = (/* @__PURE__ */ new Date()).toISOString(), t.rating = e.rating ?? null, t.satisfactionComment = e.comment ?? null;
|
|
5739
5762
|
}
|
|
5740
5763
|
/** 3.4: espelha `contestTicket` — reabre e zera o ciclo de satisfação. */
|
|
5741
5764
|
async contestTicket(e, t) {
|
|
5742
5765
|
if (typeof t?.comment == "string" && t.comment.length > 2e3)
|
|
5743
|
-
throw new
|
|
5766
|
+
throw new c("validation_failed", "comment max 2000 chars");
|
|
5744
5767
|
let r = this._find(e);
|
|
5745
5768
|
r.status = "open", r.resolvedAt = null, r.resolvedNotifiedAt = null, r.satisfactionAttempts = 0, r.lastSatisfactionAttemptAt = null, r.satisfiedAt = null, r.rating = null, r.satisfactionComment = null;
|
|
5746
5769
|
}
|
|
@@ -5783,9 +5806,9 @@ var Ne = class {
|
|
|
5783
5806
|
}
|
|
5784
5807
|
async chat(e) {
|
|
5785
5808
|
if (!e || typeof e.model != "string" || e.model.length === 0)
|
|
5786
|
-
throw new
|
|
5809
|
+
throw new c("validation_failed", "ai: model is required");
|
|
5787
5810
|
if (!Array.isArray(e.messages) || e.messages.length === 0)
|
|
5788
|
-
throw new
|
|
5811
|
+
throw new c("validation_failed", "ai: messages must be a non-empty array");
|
|
5789
5812
|
this._calls.push({ model: e.model, messages: e.messages, stream: false });
|
|
5790
5813
|
let t = this._reply(e), r = e.messages.reduce((i, s) => i + this._contentToText(s.content).length, 0), o = t.length;
|
|
5791
5814
|
return {
|
|
@@ -5802,9 +5825,9 @@ var Ne = class {
|
|
|
5802
5825
|
}
|
|
5803
5826
|
stream(e) {
|
|
5804
5827
|
if (!e || typeof e.model != "string" || e.model.length === 0)
|
|
5805
|
-
throw new
|
|
5828
|
+
throw new c("validation_failed", "ai: model is required");
|
|
5806
5829
|
if (!Array.isArray(e.messages) || e.messages.length === 0)
|
|
5807
|
-
throw new
|
|
5830
|
+
throw new c("validation_failed", "ai: messages must be a non-empty array");
|
|
5808
5831
|
this._calls.push({ model: e.model, messages: e.messages, stream: true });
|
|
5809
5832
|
let t = this._reply(e), r = t.match(/\S+\s*/g) ?? [t], o = Promise.resolve({ provider: "mock", usageWarning: false });
|
|
5810
5833
|
async function* i() {
|
|
@@ -5818,47 +5841,68 @@ var Ne = class {
|
|
|
5818
5841
|
}
|
|
5819
5842
|
};
|
|
5820
5843
|
|
|
5844
|
+
// src/timeout.ts
|
|
5845
|
+
function Wn(n) {
|
|
5846
|
+
let e = globalThis.AbortSignal;
|
|
5847
|
+
if (typeof e?.timeout == "function")
|
|
5848
|
+
return { signal: e.timeout(n), clear: () => {
|
|
5849
|
+
} };
|
|
5850
|
+
if (typeof globalThis.AbortController != "function")
|
|
5851
|
+
return { signal: void 0, clear: () => {
|
|
5852
|
+
} };
|
|
5853
|
+
let t = new AbortController(), r = setTimeout(() => t.abort(), n);
|
|
5854
|
+
return r.unref?.(), { signal: t.signal, clear: () => clearTimeout(r) };
|
|
5855
|
+
}
|
|
5856
|
+
function Bn(n, e, t) {
|
|
5857
|
+
let r, o = new Promise((i) => {
|
|
5858
|
+
r = setTimeout(() => i(t()), e), r.unref?.();
|
|
5859
|
+
});
|
|
5860
|
+
return Promise.race([n, o]).finally(() => {
|
|
5861
|
+
r !== void 0 && clearTimeout(r);
|
|
5862
|
+
});
|
|
5863
|
+
}
|
|
5864
|
+
|
|
5821
5865
|
// src/auth-pkce-shared.ts
|
|
5822
|
-
|
|
5823
|
-
function
|
|
5866
|
+
C();
|
|
5867
|
+
function Vn() {
|
|
5824
5868
|
let n = globalThis.crypto;
|
|
5825
5869
|
if (!n || typeof n.getRandomValues != "function" || !n.subtle)
|
|
5826
|
-
throw new
|
|
5870
|
+
throw new c(
|
|
5827
5871
|
"runtime_unsupported",
|
|
5828
5872
|
"auth.signIn requer WebCrypto (crypto.subtle) \u2014 indispon\xEDvel neste runtime. Use HTTPS (ou http://localhost) num browser moderno, ou instale um polyfill WebCrypto (ex: react-native-quick-crypto) em React Native."
|
|
5829
5873
|
);
|
|
5830
5874
|
return n;
|
|
5831
5875
|
}
|
|
5832
|
-
function
|
|
5876
|
+
function Kn(n) {
|
|
5833
5877
|
let e = "";
|
|
5834
5878
|
for (let r of n) e += String.fromCharCode(r);
|
|
5835
5879
|
return (typeof btoa == "function" ? btoa(e) : Buffer.from(e, "binary").toString("base64")).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
5836
5880
|
}
|
|
5837
5881
|
function xe(n, e) {
|
|
5838
5882
|
let t = new Uint8Array(e);
|
|
5839
|
-
return n.getRandomValues(t),
|
|
5883
|
+
return n.getRandomValues(t), Kn(t);
|
|
5840
5884
|
}
|
|
5841
|
-
async function
|
|
5885
|
+
async function zn(n, e) {
|
|
5842
5886
|
let t = new TextEncoder().encode(e), r = await n.subtle.digest("SHA-256", t);
|
|
5843
|
-
return
|
|
5887
|
+
return Kn(new Uint8Array(r));
|
|
5844
5888
|
}
|
|
5845
|
-
function
|
|
5889
|
+
function ie(n) {
|
|
5846
5890
|
return (typeof globalThis.NEETRU_AUTH_URL == "string" ? globalThis.NEETRU_AUTH_URL : null) ?? n.replace(/^https?:\/\/api\./, "https://auth.");
|
|
5847
5891
|
}
|
|
5848
|
-
function
|
|
5892
|
+
function Hn(n) {
|
|
5849
5893
|
let e = n.oidcClientId;
|
|
5850
|
-
if (!e && n.apiKey && (e =
|
|
5851
|
-
throw new
|
|
5894
|
+
if (!e && n.apiKey && (e = dt(n.apiKey).keyId), !e)
|
|
5895
|
+
throw new c(
|
|
5852
5896
|
"invalid_config",
|
|
5853
5897
|
"auth OIDC requer `oidcClientId` (ou `apiKey`) configurado para montar o client_id."
|
|
5854
5898
|
);
|
|
5855
5899
|
return e;
|
|
5856
5900
|
}
|
|
5857
|
-
function
|
|
5901
|
+
function Qn(n) {
|
|
5858
5902
|
let e = new URL("/api/v1/oauth/authorize", n.idpOrigin);
|
|
5859
5903
|
return e.searchParams.set("response_type", "code"), e.searchParams.set("client_id", n.clientId), e.searchParams.set("redirect_uri", n.redirectUri), e.searchParams.set("scope", n.scope), e.searchParams.set("state", n.state), e.searchParams.set("nonce", n.nonce), e.searchParams.set("code_challenge", n.codeChallenge), e.searchParams.set("code_challenge_method", "S256"), e;
|
|
5860
5904
|
}
|
|
5861
|
-
function
|
|
5905
|
+
function ot(n) {
|
|
5862
5906
|
let e = n.split(".");
|
|
5863
5907
|
if (e.length !== 3) return null;
|
|
5864
5908
|
try {
|
|
@@ -5868,8 +5912,8 @@ function nt(n) {
|
|
|
5868
5912
|
return null;
|
|
5869
5913
|
}
|
|
5870
5914
|
}
|
|
5871
|
-
function
|
|
5872
|
-
let e =
|
|
5915
|
+
function se(n) {
|
|
5916
|
+
let e = ot(n);
|
|
5873
5917
|
return !e || typeof e.sub != "string" || typeof e.exp == "number" && e.exp * 1e3 < Date.now() ? null : {
|
|
5874
5918
|
uid: e.sub,
|
|
5875
5919
|
email: typeof e.email == "string" ? e.email : "",
|
|
@@ -5882,43 +5926,43 @@ function ie(n) {
|
|
|
5882
5926
|
...e
|
|
5883
5927
|
};
|
|
5884
5928
|
}
|
|
5885
|
-
var
|
|
5886
|
-
async function
|
|
5887
|
-
let o = `${e}${
|
|
5929
|
+
var qo = "/api/v1/oauth/revoke";
|
|
5930
|
+
async function Gn(n, e, t, r) {
|
|
5931
|
+
let o = `${e}${qo}`, i = true;
|
|
5888
5932
|
for (let s of r) {
|
|
5889
5933
|
if (!s.token) continue;
|
|
5890
5934
|
let a = new URLSearchParams({
|
|
5891
5935
|
token: s.token,
|
|
5892
5936
|
token_type_hint: s.hint,
|
|
5893
5937
|
client_id: t
|
|
5894
|
-
}).toString(),
|
|
5895
|
-
for (let d = 0; d < 2 && !
|
|
5938
|
+
}).toString(), l = false;
|
|
5939
|
+
for (let d = 0; d < 2 && !l; d++)
|
|
5896
5940
|
try {
|
|
5897
|
-
if (
|
|
5941
|
+
if (l = (await n(o, {
|
|
5898
5942
|
method: "POST",
|
|
5899
5943
|
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
5900
5944
|
body: a
|
|
5901
|
-
})).ok, !
|
|
5945
|
+
})).ok, !l) break;
|
|
5902
5946
|
} catch {
|
|
5903
5947
|
d === 0 && await new Promise((u) => setTimeout(u, 500));
|
|
5904
5948
|
}
|
|
5905
|
-
|
|
5949
|
+
l || (i = false);
|
|
5906
5950
|
}
|
|
5907
5951
|
return i;
|
|
5908
5952
|
}
|
|
5909
5953
|
|
|
5910
5954
|
// src/auth.ts
|
|
5911
|
-
|
|
5955
|
+
Fe();
|
|
5912
5956
|
|
|
5913
5957
|
// src/end-user-token.ts
|
|
5914
|
-
var
|
|
5915
|
-
function
|
|
5916
|
-
|
|
5958
|
+
var Fo = /* @__PURE__ */ new WeakMap();
|
|
5959
|
+
function Jn(n, e) {
|
|
5960
|
+
Fo.set(n, e);
|
|
5917
5961
|
}
|
|
5918
5962
|
|
|
5919
5963
|
// src/unsupported-db.ts
|
|
5920
|
-
|
|
5921
|
-
var
|
|
5964
|
+
C();
|
|
5965
|
+
var jo = "[Neetru SDK] client.db n\xE3o est\xE1 dispon\xEDvel em React Native. O app n\xE3o acessa o banco do produto diretamente: chame a API do SEU produto (ex.: https://<produto>.neetru.com/api/v1) com o access_token do usu\xE1rio (Authorization: Bearer) \u2014 o backend do produto usa client.db no servidor. (At\xE9 a 3.7.x o db ca\xEDa em mem\xF3ria em sil\xEAncio e os dados sumiam ao fechar o app.)", $o = /* @__PURE__ */ new Set([
|
|
5922
5966
|
"then",
|
|
5923
5967
|
"toJSON",
|
|
5924
5968
|
"valueOf",
|
|
@@ -5927,13 +5971,13 @@ var No = "[Neetru SDK] client.db n\xE3o est\xE1 dispon\xEDvel em React Native. O
|
|
|
5927
5971
|
"asymmetricMatch",
|
|
5928
5972
|
"nodeType"
|
|
5929
5973
|
]);
|
|
5930
|
-
function
|
|
5974
|
+
function Xn() {
|
|
5931
5975
|
let n = () => {
|
|
5932
|
-
throw new
|
|
5976
|
+
throw new c("runtime_unsupported", jo, void 0, void 0, "react-native");
|
|
5933
5977
|
}, e = {};
|
|
5934
5978
|
return new Proxy(e, {
|
|
5935
5979
|
get(t, r) {
|
|
5936
|
-
if (!(typeof r == "symbol" ||
|
|
5980
|
+
if (!(typeof r == "symbol" || $o.has(r)))
|
|
5937
5981
|
return r === "toString" ? () => "[NeetruDb indispon\xEDvel em React Native]" : n;
|
|
5938
5982
|
},
|
|
5939
5983
|
set() {
|
|
@@ -5943,7 +5987,7 @@ function zn() {
|
|
|
5943
5987
|
}
|
|
5944
5988
|
|
|
5945
5989
|
// src/auth.ts
|
|
5946
|
-
function
|
|
5990
|
+
function Bo() {
|
|
5947
5991
|
try {
|
|
5948
5992
|
let e = globalThis.process?.env?.NEETRU_API_KEY;
|
|
5949
5993
|
return typeof e == "string" && e.length > 0 ? e : void 0;
|
|
@@ -5951,7 +5995,7 @@ function Lo() {
|
|
|
5951
5995
|
return;
|
|
5952
5996
|
}
|
|
5953
5997
|
}
|
|
5954
|
-
function
|
|
5998
|
+
function Vo(n) {
|
|
5955
5999
|
if (n) return n;
|
|
5956
6000
|
try {
|
|
5957
6001
|
let t = globalThis.process?.env?.NEETRU_ENV;
|
|
@@ -5965,11 +6009,11 @@ function Uo(n) {
|
|
|
5965
6009
|
}
|
|
5966
6010
|
return "prod";
|
|
5967
6011
|
}
|
|
5968
|
-
var
|
|
5969
|
-
function
|
|
5970
|
-
|
|
6012
|
+
var Ko = at;
|
|
6013
|
+
function ga() {
|
|
6014
|
+
ct();
|
|
5971
6015
|
}
|
|
5972
|
-
function
|
|
6016
|
+
function zo(n) {
|
|
5973
6017
|
let e = n.sub ?? "", t = typeof n.email == "string" ? n.email : "";
|
|
5974
6018
|
return {
|
|
5975
6019
|
uid: e,
|
|
@@ -5984,8 +6028,8 @@ function qo(n) {
|
|
|
5984
6028
|
...n
|
|
5985
6029
|
};
|
|
5986
6030
|
}
|
|
5987
|
-
var
|
|
5988
|
-
function
|
|
6031
|
+
var ae = "neetru_oauth_tx";
|
|
6032
|
+
function it(n) {
|
|
5989
6033
|
try {
|
|
5990
6034
|
let e = globalThis.history;
|
|
5991
6035
|
if (!e || typeof e.replaceState != "function") return;
|
|
@@ -5996,7 +6040,7 @@ function rt(n) {
|
|
|
5996
6040
|
} catch {
|
|
5997
6041
|
}
|
|
5998
6042
|
}
|
|
5999
|
-
function
|
|
6043
|
+
function Ho(n) {
|
|
6000
6044
|
let e = "neetru_id_token", t = "neetru_refresh_token", r = /* @__PURE__ */ new Set(), o = null, i = null, s = null;
|
|
6001
6045
|
function a() {
|
|
6002
6046
|
try {
|
|
@@ -6005,7 +6049,7 @@ function Fo(n) {
|
|
|
6005
6049
|
return null;
|
|
6006
6050
|
}
|
|
6007
6051
|
}
|
|
6008
|
-
function
|
|
6052
|
+
function l() {
|
|
6009
6053
|
try {
|
|
6010
6054
|
return typeof globalThis.sessionStorage < "u" ? globalThis.sessionStorage : null;
|
|
6011
6055
|
} catch {
|
|
@@ -6014,21 +6058,21 @@ function Fo(n) {
|
|
|
6014
6058
|
}
|
|
6015
6059
|
function d() {
|
|
6016
6060
|
if (o) {
|
|
6017
|
-
let
|
|
6018
|
-
return typeof
|
|
6061
|
+
let m = o.exp;
|
|
6062
|
+
return typeof m == "number" && m * 1e3 < Date.now() ? (o = null, a()?.removeItem(e), u(), T(), null) : o;
|
|
6019
6063
|
}
|
|
6020
|
-
let
|
|
6021
|
-
if (!
|
|
6022
|
-
let
|
|
6023
|
-
if (!
|
|
6024
|
-
return
|
|
6025
|
-
let w =
|
|
6026
|
-
return w ? (o = w, x(w), o) : (
|
|
6064
|
+
let g = a();
|
|
6065
|
+
if (!g) return null;
|
|
6066
|
+
let b = g.getItem(e);
|
|
6067
|
+
if (!b)
|
|
6068
|
+
return T(), null;
|
|
6069
|
+
let w = se(b);
|
|
6070
|
+
return w ? (o = w, x(w), o) : (g.removeItem(e), T(), null);
|
|
6027
6071
|
}
|
|
6028
6072
|
function u() {
|
|
6029
|
-
for (let
|
|
6073
|
+
for (let g of r)
|
|
6030
6074
|
try {
|
|
6031
|
-
|
|
6075
|
+
g(o);
|
|
6032
6076
|
} catch {
|
|
6033
6077
|
}
|
|
6034
6078
|
}
|
|
@@ -6038,72 +6082,77 @@ function Fo(n) {
|
|
|
6038
6082
|
function f() {
|
|
6039
6083
|
return a()?.getItem(t) ?? null;
|
|
6040
6084
|
}
|
|
6041
|
-
function
|
|
6085
|
+
function h() {
|
|
6042
6086
|
o = null;
|
|
6043
|
-
let
|
|
6044
|
-
|
|
6045
|
-
}
|
|
6046
|
-
function
|
|
6047
|
-
|
|
6048
|
-
|
|
6049
|
-
|
|
6050
|
-
|
|
6087
|
+
let g = a();
|
|
6088
|
+
g?.removeItem(e), g?.removeItem(t), u();
|
|
6089
|
+
}
|
|
6090
|
+
function y() {
|
|
6091
|
+
if (s) return s;
|
|
6092
|
+
let g = false, b = (async () => {
|
|
6093
|
+
let w = f();
|
|
6094
|
+
if (!w) return false;
|
|
6095
|
+
let m;
|
|
6051
6096
|
try {
|
|
6052
|
-
|
|
6097
|
+
m = R();
|
|
6053
6098
|
} catch {
|
|
6054
6099
|
return false;
|
|
6055
6100
|
}
|
|
6056
|
-
let
|
|
6101
|
+
let D = `${ie(n.baseUrl)}/api/v1/oauth/token`, O = new URLSearchParams({
|
|
6057
6102
|
grant_type: "refresh_token",
|
|
6058
|
-
refresh_token:
|
|
6059
|
-
client_id:
|
|
6060
|
-
}),
|
|
6103
|
+
refresh_token: w,
|
|
6104
|
+
client_id: m
|
|
6105
|
+
}), { signal: A, clear: M } = Wn(15e3), I;
|
|
6061
6106
|
try {
|
|
6062
|
-
|
|
6107
|
+
I = await n.fetch(D, {
|
|
6063
6108
|
method: "POST",
|
|
6064
6109
|
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
6065
|
-
body:
|
|
6110
|
+
body: O.toString(),
|
|
6111
|
+
signal: A
|
|
6066
6112
|
});
|
|
6067
6113
|
} catch {
|
|
6068
6114
|
return false;
|
|
6115
|
+
} finally {
|
|
6116
|
+
M();
|
|
6069
6117
|
}
|
|
6070
|
-
let
|
|
6118
|
+
let L = null;
|
|
6071
6119
|
try {
|
|
6072
|
-
|
|
6120
|
+
L = await I.json();
|
|
6073
6121
|
} catch {
|
|
6074
|
-
|
|
6122
|
+
L = null;
|
|
6075
6123
|
}
|
|
6076
|
-
if (!
|
|
6077
|
-
let
|
|
6078
|
-
if (typeof
|
|
6079
|
-
let
|
|
6080
|
-
if (!
|
|
6081
|
-
let
|
|
6082
|
-
|
|
6083
|
-
let
|
|
6084
|
-
return typeof
|
|
6085
|
-
})()
|
|
6124
|
+
if (!I.ok || typeof L?.error == "string") return false;
|
|
6125
|
+
let U = L?.id_token;
|
|
6126
|
+
if (typeof U != "string" || U.length === 0) return false;
|
|
6127
|
+
let q = se(U);
|
|
6128
|
+
if (!q || g) return false;
|
|
6129
|
+
let P = a();
|
|
6130
|
+
P?.setItem(e, U);
|
|
6131
|
+
let Le = L?.refresh_token;
|
|
6132
|
+
return typeof Le == "string" && Le.length > 0 && P?.setItem(t, Le), o = q, x(q), u(), true;
|
|
6133
|
+
})();
|
|
6134
|
+
return s = Bn(b, 15e3, () => (g = true, false)).finally(() => {
|
|
6086
6135
|
s = null;
|
|
6087
|
-
}), s
|
|
6136
|
+
}), s;
|
|
6088
6137
|
}
|
|
6089
|
-
function
|
|
6090
|
-
f() &&
|
|
6091
|
-
|
|
6138
|
+
function T() {
|
|
6139
|
+
f() && y().then((g) => {
|
|
6140
|
+
g || h();
|
|
6092
6141
|
});
|
|
6093
6142
|
}
|
|
6094
|
-
function x(
|
|
6143
|
+
function x(g) {
|
|
6095
6144
|
p();
|
|
6096
|
-
let
|
|
6097
|
-
if (typeof
|
|
6098
|
-
let w =
|
|
6145
|
+
let b = g.exp;
|
|
6146
|
+
if (typeof b != "number") return;
|
|
6147
|
+
let w = b * 1e3 - Date.now();
|
|
6099
6148
|
if (!(w <= 0)) {
|
|
6100
6149
|
if (f()) {
|
|
6101
|
-
let
|
|
6150
|
+
let m = Math.min(w, Math.max(3e4, w * 0.2)), S = Math.max(1, w - m);
|
|
6102
6151
|
i = setTimeout(() => {
|
|
6103
|
-
i = null,
|
|
6104
|
-
D ||
|
|
6152
|
+
i = null, y().then((D) => {
|
|
6153
|
+
D || h();
|
|
6105
6154
|
});
|
|
6106
|
-
},
|
|
6155
|
+
}, S);
|
|
6107
6156
|
return;
|
|
6108
6157
|
}
|
|
6109
6158
|
i = setTimeout(() => {
|
|
@@ -6111,223 +6160,235 @@ function Fo(n) {
|
|
|
6111
6160
|
}, w + 1);
|
|
6112
6161
|
}
|
|
6113
6162
|
}
|
|
6114
|
-
function
|
|
6115
|
-
return
|
|
6163
|
+
function R() {
|
|
6164
|
+
return Hn(n);
|
|
6116
6165
|
}
|
|
6117
|
-
async function
|
|
6118
|
-
let
|
|
6119
|
-
if (!
|
|
6166
|
+
async function E(g) {
|
|
6167
|
+
let b = g ?? (typeof globalThis.location < "u" ? globalThis.location.href : void 0);
|
|
6168
|
+
if (!b) return null;
|
|
6120
6169
|
let w;
|
|
6121
6170
|
try {
|
|
6122
|
-
w = new URL(
|
|
6171
|
+
w = new URL(b);
|
|
6123
6172
|
} catch {
|
|
6124
6173
|
return null;
|
|
6125
6174
|
}
|
|
6126
|
-
let
|
|
6127
|
-
if (
|
|
6128
|
-
let
|
|
6129
|
-
throw
|
|
6175
|
+
let m = w.searchParams, S = m.get("error");
|
|
6176
|
+
if (S) {
|
|
6177
|
+
let L = m.get("error_description") ?? S;
|
|
6178
|
+
throw l()?.removeItem(ae), it(w), new c(S, `OIDC authorize falhou: ${L}`);
|
|
6130
6179
|
}
|
|
6131
|
-
let D =
|
|
6180
|
+
let D = m.get("code");
|
|
6132
6181
|
if (!D) return null;
|
|
6133
|
-
let
|
|
6134
|
-
if (
|
|
6182
|
+
let O = m.get("state"), A = l(), M = A?.getItem(ae) ?? null, I = null;
|
|
6183
|
+
if (M)
|
|
6135
6184
|
try {
|
|
6136
|
-
|
|
6185
|
+
I = JSON.parse(M);
|
|
6137
6186
|
} catch {
|
|
6138
|
-
|
|
6187
|
+
I = null;
|
|
6139
6188
|
}
|
|
6140
|
-
if (!
|
|
6141
|
-
throw new
|
|
6189
|
+
if (!I)
|
|
6190
|
+
throw new c(
|
|
6142
6191
|
"oidc_state_mismatch",
|
|
6143
6192
|
"Callback OIDC sem transa\xE7\xE3o pendente \u2014 `signIn` n\xE3o foi iniciado nesta sess\xE3o (ou j\xE1 consumido)."
|
|
6144
6193
|
);
|
|
6145
|
-
if (!
|
|
6146
|
-
throw
|
|
6194
|
+
if (!O || O !== I.state)
|
|
6195
|
+
throw A?.removeItem(ae), it(w), new c(
|
|
6147
6196
|
"oidc_state_mismatch",
|
|
6148
6197
|
"state do callback OIDC n\xE3o confere com o da transa\xE7\xE3o (poss\xEDvel CSRF)."
|
|
6149
6198
|
);
|
|
6150
|
-
return
|
|
6199
|
+
return A?.removeItem(ae), it(w), {
|
|
6151
6200
|
code: D,
|
|
6152
|
-
codeVerifier:
|
|
6153
|
-
redirectUri:
|
|
6154
|
-
nonce:
|
|
6155
|
-
state:
|
|
6156
|
-
postLoginRedirect:
|
|
6201
|
+
codeVerifier: I.codeVerifier,
|
|
6202
|
+
redirectUri: I.redirectUri,
|
|
6203
|
+
nonce: I.nonce,
|
|
6204
|
+
state: I.state,
|
|
6205
|
+
postLoginRedirect: I.postLoginRedirect
|
|
6157
6206
|
};
|
|
6158
6207
|
}
|
|
6159
|
-
async function
|
|
6160
|
-
let
|
|
6161
|
-
if (!
|
|
6162
|
-
let w =
|
|
6208
|
+
async function j(g) {
|
|
6209
|
+
let b = await E(g);
|
|
6210
|
+
if (!b) return null;
|
|
6211
|
+
let w = R(), S = `${ie(n.baseUrl)}/api/v1/oauth/token`, D = new URLSearchParams({
|
|
6163
6212
|
grant_type: "authorization_code",
|
|
6164
|
-
code:
|
|
6165
|
-
redirect_uri:
|
|
6213
|
+
code: b.code,
|
|
6214
|
+
redirect_uri: b.redirectUri,
|
|
6166
6215
|
client_id: w,
|
|
6167
|
-
code_verifier:
|
|
6168
|
-
}),
|
|
6216
|
+
code_verifier: b.codeVerifier
|
|
6217
|
+
}), O;
|
|
6169
6218
|
try {
|
|
6170
|
-
|
|
6219
|
+
O = await n.fetch(S, {
|
|
6171
6220
|
method: "POST",
|
|
6172
6221
|
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
6173
6222
|
body: D.toString()
|
|
6174
6223
|
});
|
|
6175
|
-
} catch (
|
|
6176
|
-
throw new
|
|
6224
|
+
} catch (P) {
|
|
6225
|
+
throw new c(
|
|
6177
6226
|
"network_error",
|
|
6178
|
-
`POST ${
|
|
6227
|
+
`POST ${S} falhou (network): ${P?.message ?? String(P)}`
|
|
6179
6228
|
);
|
|
6180
6229
|
}
|
|
6181
|
-
let
|
|
6230
|
+
let A = null;
|
|
6182
6231
|
try {
|
|
6183
|
-
|
|
6232
|
+
A = await O.json();
|
|
6184
6233
|
} catch {
|
|
6185
|
-
|
|
6234
|
+
A = null;
|
|
6186
6235
|
}
|
|
6187
|
-
if (!
|
|
6188
|
-
let
|
|
6189
|
-
throw new
|
|
6236
|
+
if (!O.ok || typeof A?.error == "string") {
|
|
6237
|
+
let P = typeof A?.error_description == "string" && A.error_description || typeof A?.error == "string" && A.error || `HTTP ${O.status}`;
|
|
6238
|
+
throw new c(
|
|
6190
6239
|
"token_exchange_failed",
|
|
6191
|
-
`Troca do authorization_code por tokens falhou no /token: ${
|
|
6192
|
-
|
|
6240
|
+
`Troca do authorization_code por tokens falhou no /token: ${P}`,
|
|
6241
|
+
O.status
|
|
6193
6242
|
);
|
|
6194
6243
|
}
|
|
6195
|
-
let
|
|
6196
|
-
if (typeof
|
|
6197
|
-
throw new
|
|
6244
|
+
let M = A?.id_token;
|
|
6245
|
+
if (typeof M != "string" || M.length === 0)
|
|
6246
|
+
throw new c(
|
|
6198
6247
|
"token_exchange_failed",
|
|
6199
6248
|
"Resposta do /token sem `id_token` \u2014 o login n\xE3o pode ser completado.",
|
|
6200
|
-
|
|
6249
|
+
O.status
|
|
6201
6250
|
);
|
|
6202
|
-
let
|
|
6203
|
-
if (!
|
|
6204
|
-
throw new
|
|
6251
|
+
let I = ot(M);
|
|
6252
|
+
if (!I)
|
|
6253
|
+
throw new c(
|
|
6205
6254
|
"token_exchange_failed",
|
|
6206
6255
|
"id_token retornado pelo /token \xE9 malformado (payload indecodific\xE1vel)."
|
|
6207
6256
|
);
|
|
6208
|
-
if (
|
|
6209
|
-
throw new
|
|
6257
|
+
if (I.nonce !== b.nonce)
|
|
6258
|
+
throw new c(
|
|
6210
6259
|
"oidc_nonce_mismatch",
|
|
6211
6260
|
"nonce do id_token n\xE3o confere com o da transa\xE7\xE3o OIDC (poss\xEDvel replay). Token descartado."
|
|
6212
6261
|
);
|
|
6213
|
-
let
|
|
6214
|
-
if (!
|
|
6215
|
-
throw new
|
|
6262
|
+
let L = se(M);
|
|
6263
|
+
if (!L)
|
|
6264
|
+
throw new c(
|
|
6216
6265
|
"token_exchange_failed",
|
|
6217
6266
|
"id_token retornado pelo /token n\xE3o tem `sub` ou j\xE1 est\xE1 expirado."
|
|
6218
6267
|
);
|
|
6219
|
-
let
|
|
6220
|
-
|
|
6221
|
-
let
|
|
6222
|
-
return typeof
|
|
6268
|
+
let U = a();
|
|
6269
|
+
U?.setItem(e, M);
|
|
6270
|
+
let q = A?.refresh_token;
|
|
6271
|
+
return typeof q == "string" && q.length > 0 && U?.setItem(t, q), o = L, x(L), u(), { user: L, postLoginRedirect: b.postLoginRedirect };
|
|
6223
6272
|
}
|
|
6224
6273
|
return {
|
|
6225
|
-
async signIn(
|
|
6274
|
+
async signIn(g) {
|
|
6226
6275
|
if (typeof globalThis.location < "u" && typeof globalThis.location.assign == "function") {
|
|
6227
|
-
let
|
|
6228
|
-
if (!
|
|
6229
|
-
throw new
|
|
6276
|
+
let b = Vn(), w = g?.redirectUri ?? globalThis.location.origin, m = g?.scope ?? "openid profile email", S = R(), D = xe(b, 16), O = xe(b, 16), A = xe(b, 32), M = await zn(b, A), I = l();
|
|
6277
|
+
if (!I)
|
|
6278
|
+
throw new c(
|
|
6230
6279
|
"runtime_unsupported",
|
|
6231
6280
|
"auth.signIn requer sessionStorage para guardar a transa\xE7\xE3o PKCE entre o redirect e o callback."
|
|
6232
6281
|
);
|
|
6233
|
-
let
|
|
6282
|
+
let L = {
|
|
6234
6283
|
state: D,
|
|
6235
|
-
nonce:
|
|
6236
|
-
codeVerifier:
|
|
6284
|
+
nonce: O,
|
|
6285
|
+
codeVerifier: A,
|
|
6237
6286
|
redirectUri: w,
|
|
6238
|
-
postLoginRedirect:
|
|
6287
|
+
postLoginRedirect: g?.postLoginRedirect
|
|
6239
6288
|
};
|
|
6240
|
-
|
|
6241
|
-
let
|
|
6242
|
-
idpOrigin:
|
|
6243
|
-
clientId:
|
|
6289
|
+
I.setItem(ae, JSON.stringify(L));
|
|
6290
|
+
let U = ie(n.baseUrl), q = Qn({
|
|
6291
|
+
idpOrigin: U,
|
|
6292
|
+
clientId: S,
|
|
6244
6293
|
redirectUri: w,
|
|
6245
|
-
scope:
|
|
6294
|
+
scope: m,
|
|
6246
6295
|
state: D,
|
|
6247
|
-
nonce:
|
|
6248
|
-
codeChallenge:
|
|
6296
|
+
nonce: O,
|
|
6297
|
+
codeChallenge: M
|
|
6249
6298
|
});
|
|
6250
|
-
globalThis.location.assign(
|
|
6299
|
+
globalThis.location.assign(q.toString());
|
|
6251
6300
|
return;
|
|
6252
6301
|
}
|
|
6253
|
-
throw new
|
|
6302
|
+
throw new c(
|
|
6254
6303
|
"invalid_config",
|
|
6255
6304
|
"auth.signIn requires a browser context or mocks. Use NEETRU_ENV=dev or pass mocks.auth."
|
|
6256
6305
|
);
|
|
6257
6306
|
},
|
|
6258
|
-
handleRedirectCallback:
|
|
6259
|
-
completeSignIn:
|
|
6307
|
+
handleRedirectCallback: E,
|
|
6308
|
+
completeSignIn: j,
|
|
6260
6309
|
// 3.7.0: exposto pro client.support renovar a sessão 1x num 401
|
|
6261
6310
|
// invalid_end_user_token (mesma função do refresh proativo, com dedup).
|
|
6262
|
-
refreshTokens:
|
|
6311
|
+
refreshTokens: y,
|
|
6263
6312
|
getIdToken() {
|
|
6264
|
-
let
|
|
6265
|
-
return
|
|
6313
|
+
let b = a()?.getItem(e) ?? null;
|
|
6314
|
+
return b && se(b) ? b : null;
|
|
6266
6315
|
},
|
|
6267
6316
|
async signOut() {
|
|
6268
|
-
let
|
|
6269
|
-
if (
|
|
6270
|
-
let
|
|
6317
|
+
let g = a(), b = g?.getItem(t) ?? null, w = true;
|
|
6318
|
+
if (g)
|
|
6319
|
+
for (let S of [e, t])
|
|
6320
|
+
try {
|
|
6321
|
+
g.removeItem(S);
|
|
6322
|
+
} catch {
|
|
6323
|
+
w = false;
|
|
6324
|
+
}
|
|
6325
|
+
p(), o = null;
|
|
6326
|
+
let m = "skipped";
|
|
6327
|
+
if (b) {
|
|
6328
|
+
let S = null;
|
|
6271
6329
|
try {
|
|
6272
|
-
|
|
6330
|
+
S = R();
|
|
6273
6331
|
} catch {
|
|
6274
|
-
|
|
6332
|
+
S = null;
|
|
6275
6333
|
}
|
|
6276
|
-
|
|
6277
|
-
|
|
6278
|
-
|
|
6279
|
-
|
|
6334
|
+
S ? m = await Gn(
|
|
6335
|
+
n.fetch,
|
|
6336
|
+
ie(n.baseUrl),
|
|
6337
|
+
S,
|
|
6338
|
+
[{ token: b, hint: "refresh_token" }]
|
|
6339
|
+
) ? "accepted" : "failed" : m = "not_configured", m !== "accepted" && typeof console < "u" && console.warn(
|
|
6340
|
+
"[neetru-sdk] signOut: a revoga\xE7\xE3o do refresh_token no servidor n\xE3o foi confirmada (" + m + "). A sess\xE3o local foi encerrada, mas o refresh_token pode seguir v\xE1lido at\xE9 expirar. Trate o campo remoteRevocation do SignOutResult no produto."
|
|
6280
6341
|
);
|
|
6281
6342
|
}
|
|
6282
|
-
u();
|
|
6343
|
+
return u(), { localSessionCleared: w, remoteRevocation: m };
|
|
6283
6344
|
},
|
|
6284
6345
|
getUser() {
|
|
6285
6346
|
return d();
|
|
6286
6347
|
},
|
|
6287
|
-
onAuthStateChanged(
|
|
6288
|
-
r.add(
|
|
6348
|
+
onAuthStateChanged(g) {
|
|
6349
|
+
r.add(g);
|
|
6289
6350
|
try {
|
|
6290
|
-
|
|
6351
|
+
g(d());
|
|
6291
6352
|
} catch {
|
|
6292
6353
|
}
|
|
6293
6354
|
return () => {
|
|
6294
|
-
r.delete(
|
|
6355
|
+
r.delete(g);
|
|
6295
6356
|
};
|
|
6296
6357
|
},
|
|
6297
|
-
async verifyToken(
|
|
6298
|
-
if (!
|
|
6299
|
-
throw new
|
|
6300
|
-
let
|
|
6301
|
-
if (!
|
|
6302
|
-
throw new
|
|
6358
|
+
async verifyToken(g, b) {
|
|
6359
|
+
if (!g || typeof g != "string")
|
|
6360
|
+
throw new c("token_invalid_signature", "token must be a non-empty string");
|
|
6361
|
+
let m = (typeof globalThis.NEETRU_AUTH_URL == "string" ? globalThis.NEETRU_AUTH_URL : null) ?? n.baseUrl.replace(/^https?:\/\/api\./, "https://auth."), S = m, D = `${m}/api/v1/oauth/.well-known/jwks`, O = b?.jwksCacheTtlMs ?? Me, A = b?.audience, M = ut(n.apiKey), I = A ?? n.oidcClientId ?? M?.keyId;
|
|
6362
|
+
if (!I)
|
|
6363
|
+
throw new c(
|
|
6303
6364
|
"invalid_config",
|
|
6304
6365
|
"verifyToken requires an audience: provide oidcClientId/apiKey on the client or pass options.audience. Calling jwtVerify without an audience allows tokens issued for other OIDC clients to pass."
|
|
6305
6366
|
);
|
|
6306
|
-
let
|
|
6367
|
+
let L = Ko(D, O);
|
|
6307
6368
|
try {
|
|
6308
|
-
let { payload:
|
|
6309
|
-
issuer:
|
|
6310
|
-
audience:
|
|
6369
|
+
let { payload: U } = await jose.jwtVerify(g, L, {
|
|
6370
|
+
issuer: S,
|
|
6371
|
+
audience: I,
|
|
6311
6372
|
algorithms: ["RS256"]
|
|
6312
6373
|
});
|
|
6313
|
-
return
|
|
6314
|
-
} catch (
|
|
6315
|
-
let
|
|
6316
|
-
throw
|
|
6374
|
+
return zo(U);
|
|
6375
|
+
} catch (U) {
|
|
6376
|
+
let q = U?.code ?? U?.name ?? "", P = U?.message ?? String(U);
|
|
6377
|
+
throw q === "ERR_JWT_EXPIRED" ? new c("token_expired", `Token expired: ${P}`) : q === "ERR_JWS_SIGNATURE_VERIFICATION_FAILED" ? new c("token_invalid_signature", `Token signature invalid: ${P}`) : q === "ERR_JWT_CLAIM_VALIDATION_FAILED" ? P.includes('"aud"') || P.includes("audience") ? new c("token_invalid_audience", `Token audience mismatch: ${P}`) : P.includes('"iss"') || P.includes("issuer") ? new c("token_invalid_issuer", `Token issuer mismatch: ${P}`) : new c("token_invalid_signature", `Token claim validation failed: ${P}`) : new c("token_invalid_signature", `Token verification failed: ${P}`);
|
|
6317
6378
|
}
|
|
6318
6379
|
}
|
|
6319
6380
|
};
|
|
6320
6381
|
}
|
|
6321
|
-
function
|
|
6382
|
+
function Qo(n = {}) {
|
|
6322
6383
|
let e = n.fetch ?? globalThis.fetch;
|
|
6323
6384
|
if (typeof e != "function")
|
|
6324
|
-
throw new
|
|
6385
|
+
throw new c(
|
|
6325
6386
|
"invalid_config",
|
|
6326
6387
|
"fetch is not available in this runtime. Pass `fetch` explicitly to createNeetruClient."
|
|
6327
6388
|
);
|
|
6328
|
-
let t = n.apiKey ??
|
|
6329
|
-
|
|
6330
|
-
let r =
|
|
6389
|
+
let t = n.apiKey ?? Bo();
|
|
6390
|
+
St({ hasApiKey: !!t, strict: n.strictServerOnlyKey === true });
|
|
6391
|
+
let r = Vo(n.env), o = n.baseUrl ?? (r === "dev-local" ? gt : ht), i = mt(o, n.allowedHosts ?? []), s = Object.freeze({
|
|
6331
6392
|
apiKey: t,
|
|
6332
6393
|
oidcClientId: n.oidcClientId,
|
|
6333
6394
|
baseUrl: i,
|
|
@@ -6335,39 +6396,39 @@ function jo(n = {}) {
|
|
|
6335
6396
|
env: r,
|
|
6336
6397
|
productId: n.productId,
|
|
6337
6398
|
tenantId: n.tenantId
|
|
6338
|
-
}), a = r
|
|
6399
|
+
}), a = W(r), l = n.mocks?.auth ?? (a ? new Ae({ ...rt }) : Ho(s)), d = n.mocks?.usage ?? (a ? new Ee() : qt(s)), u = n.endUserAuth ?? l, p = n.mocks?.support ?? (a ? new Pe() : Vt(s, {
|
|
6339
6400
|
getEndUserToken: () => u.getIdToken(),
|
|
6340
6401
|
// `refreshTokens` é opcional (MockAuth/mocks próprios omitem).
|
|
6341
6402
|
refreshEndUserToken: (() => {
|
|
6342
|
-
let
|
|
6343
|
-
return typeof
|
|
6403
|
+
let E = u.refreshTokens;
|
|
6404
|
+
return typeof E == "function" ? () => E.call(u) : void 0;
|
|
6344
6405
|
})()
|
|
6345
|
-
})), f = n.mocks?.entitlements ?? (a ? new De() :
|
|
6406
|
+
})), f = n.mocks?.entitlements ?? (a ? new De() : xt()), h = n.mocks?.db ?? (Y() === "react-native" ? Xn() : pn(s, n.db)), y = n.mocks?.webhooks ?? (a ? new Te() : yn(s)), T = n.mocks?.notifications ?? (a ? new Ie() : vn(s)), x = n.mocks?.ai ?? (a ? new Ne() : $n(s)), R = Object.freeze({
|
|
6346
6407
|
config: s,
|
|
6347
|
-
auth:
|
|
6348
|
-
catalog:
|
|
6408
|
+
auth: l,
|
|
6409
|
+
catalog: Dt(s),
|
|
6349
6410
|
entitlements: f,
|
|
6350
|
-
telemetry:
|
|
6411
|
+
telemetry: Ut(s),
|
|
6351
6412
|
usage: d,
|
|
6352
6413
|
support: p,
|
|
6353
|
-
db:
|
|
6354
|
-
checkout:
|
|
6355
|
-
webhooks:
|
|
6356
|
-
notifications:
|
|
6414
|
+
db: h,
|
|
6415
|
+
checkout: fn(s),
|
|
6416
|
+
webhooks: y,
|
|
6417
|
+
notifications: T,
|
|
6357
6418
|
ai: x
|
|
6358
6419
|
});
|
|
6359
|
-
return n.endUserAuth &&
|
|
6420
|
+
return n.endUserAuth && Jn(R, n.endUserAuth), R;
|
|
6360
6421
|
}
|
|
6361
6422
|
var Oe = /* @__PURE__ */ Symbol.for("@neetru/sdk:serverClient");
|
|
6362
|
-
function
|
|
6423
|
+
function ya(n = {}) {
|
|
6363
6424
|
let e = globalThis;
|
|
6364
|
-
return e[Oe] || (e[Oe] =
|
|
6425
|
+
return e[Oe] || (e[Oe] = Qo(n)), e[Oe];
|
|
6365
6426
|
}
|
|
6366
|
-
function
|
|
6427
|
+
function _a() {
|
|
6367
6428
|
delete globalThis[Oe];
|
|
6368
6429
|
}
|
|
6369
6430
|
|
|
6370
|
-
exports.__resetJwksCacheForTests =
|
|
6371
|
-
exports.__resetServerNeetruClientForTests =
|
|
6372
|
-
exports.createNeetruClient =
|
|
6373
|
-
exports.getServerNeetruClient =
|
|
6431
|
+
exports.__resetJwksCacheForTests = ga;
|
|
6432
|
+
exports.__resetServerNeetruClientForTests = _a;
|
|
6433
|
+
exports.createNeetruClient = Qo;
|
|
6434
|
+
exports.getServerNeetruClient = ya;
|