@neetru/sdk 3.7.0 → 3.8.1

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.
Files changed (73) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/README.md +66 -1
  3. package/dist/ai.cjs +221 -177
  4. package/dist/ai.d.cts +1 -1
  5. package/dist/ai.d.ts +1 -1
  6. package/dist/ai.mjs +221 -177
  7. package/dist/auth.cjs +1051 -868
  8. package/dist/auth.d.cts +1 -1
  9. package/dist/auth.d.ts +1 -1
  10. package/dist/auth.mjs +1048 -865
  11. package/dist/catalog.cjs +164 -97
  12. package/dist/catalog.d.cts +1 -1
  13. package/dist/catalog.d.ts +1 -1
  14. package/dist/catalog.mjs +164 -97
  15. package/dist/checkout.cjs +182 -115
  16. package/dist/checkout.d.cts +1 -1
  17. package/dist/checkout.d.ts +1 -1
  18. package/dist/checkout.mjs +181 -114
  19. package/dist/db-react.d.cts +1 -1
  20. package/dist/db-react.d.ts +1 -1
  21. package/dist/db.cjs +437 -345
  22. package/dist/db.d.cts +1 -1
  23. package/dist/db.d.ts +1 -1
  24. package/dist/db.mjs +455 -363
  25. package/dist/entitlements.cjs +17 -10
  26. package/dist/entitlements.d.cts +1 -1
  27. package/dist/entitlements.d.ts +1 -1
  28. package/dist/entitlements.mjs +17 -10
  29. package/dist/errors.cjs +15 -8
  30. package/dist/errors.d.cts +24 -3
  31. package/dist/errors.d.ts +24 -3
  32. package/dist/errors.mjs +14 -7
  33. package/dist/firestore-compat.d.cts +1 -1
  34. package/dist/firestore-compat.d.ts +1 -1
  35. package/dist/index.cjs +1544 -1190
  36. package/dist/index.d.cts +177 -3
  37. package/dist/index.d.ts +177 -3
  38. package/dist/index.mjs +1676 -1329
  39. package/dist/mobile.cjs +400 -181
  40. package/dist/mobile.d.cts +59 -4
  41. package/dist/mobile.d.ts +59 -4
  42. package/dist/mobile.mjs +400 -181
  43. package/dist/mocks.cjs +9 -2
  44. package/dist/mocks.d.cts +1 -1
  45. package/dist/mocks.d.ts +1 -1
  46. package/dist/mocks.mjs +9 -2
  47. package/dist/notifications.cjs +197 -130
  48. package/dist/notifications.d.cts +1 -1
  49. package/dist/notifications.d.ts +1 -1
  50. package/dist/notifications.mjs +196 -129
  51. package/dist/react.cjs +303 -282
  52. package/dist/react.d.cts +1 -1
  53. package/dist/react.d.ts +1 -1
  54. package/dist/react.mjs +295 -274
  55. package/dist/support.cjs +299 -229
  56. package/dist/support.d.cts +8 -4
  57. package/dist/support.d.ts +8 -4
  58. package/dist/support.mjs +298 -228
  59. package/dist/telemetry.cjs +234 -167
  60. package/dist/telemetry.d.cts +1 -1
  61. package/dist/telemetry.d.ts +1 -1
  62. package/dist/telemetry.mjs +234 -167
  63. package/dist/{types-Dx0IrOSF.d.ts → types-BYPk_3HR.d.ts} +104 -17
  64. package/dist/{types-Bx4kTLmk.d.cts → types-yv3EDKg2.d.cts} +104 -17
  65. package/dist/usage.cjs +183 -116
  66. package/dist/usage.d.cts +1 -1
  67. package/dist/usage.d.ts +1 -1
  68. package/dist/usage.mjs +183 -116
  69. package/dist/webhooks.cjs +215 -148
  70. package/dist/webhooks.d.cts +1 -1
  71. package/dist/webhooks.d.ts +1 -1
  72. package/dist/webhooks.mjs +212 -145
  73. package/package.json +2 -1
package/dist/webhooks.mjs CHANGED
@@ -12,13 +12,20 @@ var s = class t extends Error {
12
12
  * para um `NeetruDbErrorCode` mais específico (recuperável vs não).
13
13
  */
14
14
  reason;
15
- constructor(e, r, n, i, o) {
16
- super(r), this.name = "NeetruError", this.code = e, this.status = n, this.requestId = i, this.reason = o, Object.setPrototypeOf(this, t.prototype);
15
+ /**
16
+ * 3.8.0: `x-correlation-id` da requisição que falhou. O SDK gera um UUID por
17
+ * chamada (ou usa o que o chamador passou) e manda no header; o Core grava o
18
+ * mesmo id nos logs/auditoria — cite-o ao abrir um ticket de suporte.
19
+ * `undefined` em erros que acontecem antes de qualquer requisição.
20
+ */
21
+ correlationId;
22
+ constructor(e, r, n, o, i, a) {
23
+ super(r), this.name = "NeetruError", this.code = e, this.status = n, this.requestId = o, this.reason = i, this.correlationId = a, Object.setPrototypeOf(this, t.prototype);
17
24
  }
18
25
  };
19
26
 
20
27
  // src/idempotency.ts
21
- function S() {
28
+ function N() {
22
29
  let t = typeof globalThis < "u" && "crypto" in globalThis ? globalThis.crypto : void 0;
23
30
  if (t && typeof t.randomUUID == "function")
24
31
  return t.randomUUID();
@@ -28,8 +35,60 @@ function S() {
28
35
  );
29
36
  }
30
37
 
38
+ // src/correlation.ts
39
+ var D = "x-correlation-id";
40
+ var F = /^[A-Za-z0-9._:\-]+$/;
41
+ function C(t) {
42
+ return typeof t == "string" && t.length > 0 && t.length <= 128 && F.test(t);
43
+ }
44
+ function z() {
45
+ let t = globalThis.crypto;
46
+ try {
47
+ if (t && typeof t.randomUUID == "function") return t.randomUUID();
48
+ } catch {
49
+ }
50
+ let e = new Uint8Array(16), r = false;
51
+ try {
52
+ t && typeof t.getRandomValues == "function" && (t.getRandomValues(e), r = !0);
53
+ } catch {
54
+ r = false;
55
+ }
56
+ if (!r)
57
+ for (let o = 0; o < e.length; o++) e[o] = Math.floor(Math.random() * 256);
58
+ e[6] = e[6] & 15 | 64, e[8] = e[8] & 63 | 128;
59
+ let n = Array.from(e, (o) => o.toString(16).padStart(2, "0")).join("");
60
+ return `${n.slice(0, 8)}-${n.slice(8, 12)}-${n.slice(12, 16)}-${n.slice(16, 20)}-${n.slice(20)}`;
61
+ }
62
+ function O(t, e) {
63
+ let r, n = {};
64
+ for (let [i, a] of Object.entries(t)) {
65
+ if (i.toLowerCase() === D) {
66
+ C(a) && (r = a);
67
+ continue;
68
+ }
69
+ n[i] = a;
70
+ }
71
+ let o = r ?? (C(e) ? e : void 0) ?? z();
72
+ return n[D] = o, { headers: n, correlationId: o };
73
+ }
74
+
75
+ // src/server-only-key.ts
76
+ function M() {
77
+ try {
78
+ let t = globalThis.navigator;
79
+ if (t && t.product === "ReactNative") return "react-native";
80
+ } catch {
81
+ }
82
+ try {
83
+ let t = globalThis;
84
+ if (typeof t.window < "u" && typeof t.document < "u") return "browser";
85
+ } catch {
86
+ }
87
+ return null;
88
+ }
89
+
31
90
  // src/http.ts
32
- var H = {
91
+ var G = {
33
92
  // SDK major 3.x requer Core ≥ 2026.05.1 (suporte a X-Neetru-Version header,
34
93
  // runTransaction write-after-read, verifyWebhookRequest, webhooks 3.0+)
35
94
  3: "2026.05.1"
@@ -37,73 +96,77 @@ var H = {
37
96
  function A(t) {
38
97
  return t.split("+")[0] ?? t;
39
98
  }
40
- function j(t, e) {
41
- let r = A(t).split(".").map(Number), n = A(e).split(".").map(Number), i = Math.max(r.length, n.length);
42
- for (let o = 0; o < i; o++) {
43
- let d = r[o] ?? 0, c = n[o] ?? 0;
44
- if (d !== c) return d - c;
99
+ function X(t, e) {
100
+ let r = A(t).split(".").map(Number), n = A(e).split(".").map(Number), o = Math.max(r.length, n.length);
101
+ for (let i = 0; i < o; i++) {
102
+ let a = r[i] ?? 0, c = n[i] ?? 0;
103
+ if (a !== c) return a - c;
45
104
  }
46
105
  return 0;
47
106
  }
48
- function q() {
107
+ function $() {
49
108
  try {
50
- return "3.7.0";
109
+ return "3.8.1";
51
110
  } catch {
52
111
  return;
53
112
  }
54
113
  }
55
- function V() {
56
- let t = q();
114
+ function Y() {
115
+ let t = $();
57
116
  return t ? parseInt(t.split(".")[0] ?? "3", 10) : 3;
58
117
  }
59
118
  var W = /* @__PURE__ */ new Set();
60
- function B(t) {
119
+ function J(t) {
61
120
  if (!t) return;
62
- let e = V(), r = H[e];
121
+ let e = Y(), r = G[e];
63
122
  if (!r) return;
64
123
  let n = A(t);
65
- if (j(n, r) < 0) {
66
- let i = `${e}:${n}`;
67
- W.has(i) || (W.add(i), console.warn(
124
+ if (X(n, r) < 0) {
125
+ let o = `${e}:${n}`;
126
+ W.has(o) || (W.add(o), console.warn(
68
127
  `[Neetru SDK] Aten\xE7\xE3o: Core vers\xE3o "${t}" \xE9 anterior ao m\xEDnimo recomendado "${r}" para SDK major ${e}. Alguns recursos podem n\xE3o funcionar corretamente. Atualize o Core para a vers\xE3o mais recente.`
69
128
  ));
70
129
  }
71
130
  }
72
- var L = 2, F = 0, z = /* @__PURE__ */ new Set(["GET", "HEAD"]), G = /* @__PURE__ */ new Set([
131
+ function Z() {
132
+ let t = "This operation requires an apiKey. Pass it to createNeetruClient({ apiKey }) or set NEETRU_API_KEY env var.";
133
+ return M() ? "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. (" + t + ")" : t;
134
+ }
135
+ var Q = 2, ee = 0, te = /* @__PURE__ */ new Set(["GET", "HEAD"]), re = /* @__PURE__ */ new Set([
73
136
  "rate_limited",
74
137
  "server_error",
75
138
  "network_error"
76
139
  ]);
77
- function N(t) {
140
+ function U(t) {
78
141
  let e = 200 * Math.pow(4, t), r = e * 0.2 * (Math.random() * 2 - 1);
79
142
  return Math.max(50, Math.round(e + r));
80
143
  }
81
- var C = 6e4;
82
- function J(t) {
144
+ var q = 6e4;
145
+ function ne(t) {
83
146
  if (!t) return null;
84
147
  let e = Number(t);
85
- if (Number.isFinite(e) && e >= 0) return Math.min(Math.round(e * 1e3), C);
148
+ if (Number.isFinite(e) && e >= 0) return Math.min(Math.round(e * 1e3), q);
86
149
  let r = Date.parse(t);
87
150
  if (Number.isFinite(r)) {
88
151
  let n = r - Date.now();
89
- if (n > 0) return Math.min(n, C);
152
+ if (n > 0) return Math.min(n, q);
90
153
  }
91
154
  return null;
92
155
  }
93
- function D(t) {
156
+ function P(t) {
94
157
  return new Promise((e) => setTimeout(e, t));
95
158
  }
96
- function Y(t) {
159
+ function oe(t) {
97
160
  return t === 401 ? "unauthorized" : t === 403 ? "forbidden" : t === 404 ? "not_found" : t === 409 ? "conflict" : t === 410 ? "gone" : t === 422 || t === 400 ? "validation_failed" : t === 429 ? "rate_limited" : t >= 500 ? "server_error" : "unknown";
98
161
  }
99
- function X(t, e, r) {
100
- let n = t.replace(/\/+$/, ""), i = e.startsWith("/") ? e : `/${e}`, o = new URL(`${n}${i}`);
162
+ function ie(t, e, r) {
163
+ let n = t.replace(/\/+$/, ""), o = e.startsWith("/") ? e : `/${e}`, i = new URL(`${n}${o}`);
101
164
  if (r)
102
- for (let [d, c] of Object.entries(r))
103
- c !== void 0 && o.searchParams.set(d, String(c));
104
- return o.toString();
165
+ for (let [a, c] of Object.entries(r))
166
+ c !== void 0 && i.searchParams.set(a, String(c));
167
+ return i.toString();
105
168
  }
106
- async function M(t) {
169
+ async function K(t) {
107
170
  let e = await t.text();
108
171
  if (e)
109
172
  try {
@@ -112,147 +175,151 @@ async function M(t) {
112
175
  return;
113
176
  }
114
177
  }
115
- async function _(t, e) {
116
- let r = e.method ?? "GET", n = X(t.baseUrl, e.path, e.query), i = z.has(r) ? L : F, o = e.retries ?? i, d = {
117
- accept: "application/json",
118
- ...e.headers
119
- }, c = q();
120
- if (c && (d["x-neetru-sdk-version"] = c), e.requireAuth) {
178
+ async function k(t, e) {
179
+ let r = e.method ?? "GET", n = ie(t.baseUrl, e.path, e.query), o = te.has(r) ? Q : ee, i = e.retries ?? o, { headers: a, correlationId: c } = O(
180
+ { accept: "application/json", ...e.headers },
181
+ e.correlationId
182
+ ), b = $();
183
+ if (b && (a["x-neetru-sdk-version"] = b), e.requireAuth) {
121
184
  if (!t.apiKey)
122
- throw new s(
123
- "missing_api_key",
124
- "This operation requires an apiKey. Pass it to createNeetruClient({ apiKey }) or set NEETRU_API_KEY env var."
125
- );
126
- d.authorization = `Bearer ${t.apiKey}`;
185
+ throw new s("missing_api_key", Z());
186
+ a.authorization = `Bearer ${t.apiKey}`;
127
187
  }
128
188
  if (e.idempotencyKey) {
129
- let l = typeof e.idempotencyKey == "string" ? e.idempotencyKey : S();
130
- d["idempotency-key"] = l;
189
+ let l = typeof e.idempotencyKey == "string" ? e.idempotencyKey : N();
190
+ a["idempotency-key"] = l;
131
191
  }
132
- let y = e.body !== void 0 && r !== "GET" && r !== "DELETE" ? JSON.stringify(e.body) : void 0;
133
- y !== void 0 && (d["content-type"] = "application/json");
134
- let h = null, f = e.deadlineMs != null ? Date.now() + e.deadlineMs : null;
135
- for (let l = 0; l <= o; l++) {
136
- if (f != null && Date.now() >= f)
137
- throw h ?? new s("network_error", "Deadline excedido antes de completar a request");
138
- let m = { method: r, headers: d };
139
- y !== void 0 && (m.body = y);
140
- let k = f != null ? Math.max(1, Math.min(3e4, f - Date.now())) : 3e4;
141
- m.signal = AbortSignal.timeout(k);
142
- let u;
192
+ let h = e.body !== void 0 && r !== "GET" && r !== "DELETE" ? JSON.stringify(e.body) : void 0;
193
+ h !== void 0 && (a["content-type"] = "application/json");
194
+ let g = null, p = e.deadlineMs != null ? Date.now() + e.deadlineMs : null;
195
+ for (let l = 0; l <= i; l++) {
196
+ if (p != null && Date.now() >= p)
197
+ throw g ?? new s(
198
+ "network_error",
199
+ "Deadline excedido antes de completar a request",
200
+ void 0,
201
+ void 0,
202
+ void 0,
203
+ c
204
+ );
205
+ let f = { method: r, headers: a };
206
+ h !== void 0 && (f.body = h);
207
+ let v = p != null ? Math.max(1, Math.min(3e4, p - Date.now())) : 3e4;
208
+ f.signal = AbortSignal.timeout(v);
209
+ let d;
143
210
  try {
144
- u = await t.fetch(n, m);
145
- } catch (a) {
146
- let w = a instanceof DOMException && a.name === "TimeoutError" ? "Network error: timeout after 30s" : `Network error: ${a instanceof Error ? a.message : "fetch failed"}`;
147
- if (h = new s("network_error", w), l < o) {
148
- let x = N(l);
149
- if (f == null || Date.now() + x < f) {
150
- await D(x);
211
+ d = await t.fetch(n, f);
212
+ } catch (u) {
213
+ let _ = u instanceof DOMException && u.name === "TimeoutError" ? "Network error: timeout after 30s" : `Network error: ${u instanceof Error ? u.message : "fetch failed"}`;
214
+ if (g = new s("network_error", _, void 0, void 0, void 0, c), l < i) {
215
+ let T = U(l);
216
+ if (p == null || Date.now() + T < p) {
217
+ await P(T);
151
218
  continue;
152
219
  }
153
220
  }
154
- throw h;
221
+ throw g;
155
222
  }
156
- let g = u.headers.get("x-request-id") ?? u.headers.get("x-correlation-id") ?? void 0;
157
- if (u.ok) {
158
- let a = u.headers.get("x-neetru-version");
159
- return a && B(a), await M(u);
223
+ let w = d.headers.get("x-request-id") ?? d.headers.get("x-correlation-id") ?? void 0;
224
+ if (d.ok) {
225
+ let u = d.headers.get("x-neetru-version");
226
+ return u && J(u), await K(d);
160
227
  }
161
- let p = await M(u), v = Y(u.status), b = `HTTP ${u.status}`, R;
162
- if (p && typeof p == "object") {
163
- let a = p.error;
164
- typeof a == "string" ? b = a : a && typeof a == "object" ? (typeof a.code == "string" && (v = a.code), typeof a.message == "string" && (b = a.message), typeof a.reason == "string" && (R = a.reason)) : (typeof p.code == "string" && (v = p.code), typeof p.message == "string" && (b = p.message)), typeof p.reason == "string" && (R = p.reason);
228
+ let m = await K(d), E = oe(d.status), y = `HTTP ${d.status}`, I;
229
+ if (m && typeof m == "object") {
230
+ let u = m.error;
231
+ typeof u == "string" ? y = u : u && typeof u == "object" ? (typeof u.code == "string" && (E = u.code), typeof u.message == "string" && (y = u.message), typeof u.reason == "string" && (I = u.reason)) : (typeof m.code == "string" && (E = m.code), typeof m.message == "string" && (y = m.message)), typeof m.reason == "string" && (I = m.reason);
165
232
  }
166
- if (u.status === 410) {
167
- let a = u.headers.get("x-neetru-replacement");
168
- b === `HTTP ${u.status}` && (b = `Endpoint ${e.path} foi removido do Core (HTTP 410 Gone) \u2014 atualize o @neetru/sdk e migre para a API substituta.`), a && !b.includes(a) && (b += ` Substituto: ${a}.`);
233
+ if (d.status === 410) {
234
+ let u = d.headers.get("x-neetru-replacement");
235
+ y === `HTTP ${d.status}` && (y = `Endpoint ${e.path} foi removido do Core (HTTP 410 Gone) \u2014 atualize o @neetru/sdk e migre para a API substituta.`), u && !y.includes(u) && (y += ` Substituto: ${u}.`);
169
236
  }
170
- let T = new s(v, b, u.status, g, R);
171
- if (h = T, G.has(v) && l < o) {
172
- let w = J(u.headers.get("retry-after")) ?? N(l);
173
- if (f == null || Date.now() + w < f) {
174
- await D(w);
237
+ let x = new s(E, y, d.status, w, I, c);
238
+ if (g = x, re.has(E) && l < i) {
239
+ let _ = ne(d.headers.get("retry-after")) ?? U(l);
240
+ if (p == null || Date.now() + _ < p) {
241
+ await P(_);
175
242
  continue;
176
243
  }
177
244
  }
178
- throw T;
245
+ throw x;
179
246
  }
180
- throw h ?? new s("unknown", "unexpected httpRequest exit");
247
+ throw g ?? new s("unknown", "unexpected httpRequest exit", void 0, void 0, void 0, c);
181
248
  }
182
249
 
183
250
  // src/validators.ts
184
- var O = /^[a-z0-9][a-z0-9_-]{0,62}$/i;
185
- function I(t, e) {
186
- if (typeof e != "string" || !O.test(e))
251
+ var L = /^[a-z0-9][a-z0-9_-]{0,62}$/i;
252
+ function S(t, e) {
253
+ if (typeof e != "string" || !L.test(e))
187
254
  throw new s(
188
255
  "validation_failed",
189
- `${t} must match ${O.source} (lowercase alphanumeric, _, -; first char must be alphanumeric; max 63 chars)`
256
+ `${t} must match ${L.source} (lowercase alphanumeric, _, -; first char must be alphanumeric; max 63 chars)`
190
257
  );
191
258
  }
192
259
 
193
260
  // src/webhooks.ts
194
- async function Q(t, e, r, n) {
261
+ async function se(t, e, r, n) {
195
262
  if (!e || !r) return false;
196
- let i = e.startsWith("sha256=") ? e.slice(7) : e;
197
- if (!/^[0-9a-f]+$/i.test(i)) return false;
198
- let o = typeof globalThis < "u" && "crypto" in globalThis ? globalThis.crypto?.subtle : void 0;
199
- if (!o)
263
+ let o = e.startsWith("sha256=") ? e.slice(7) : e;
264
+ if (!/^[0-9a-f]+$/i.test(o)) return false;
265
+ let i = typeof globalThis < "u" && "crypto" in globalThis ? globalThis.crypto?.subtle : void 0;
266
+ if (!i)
200
267
  throw new s(
201
268
  "runtime_unsupported",
202
269
  "verifyWebhookSignature requires globalThis.crypto.subtle (Node \u226520, modern browser, or Edge runtime)."
203
270
  );
204
- let d = new TextEncoder(), c = d.encode(r), y = typeof t == "string" ? d.encode(t) : t, h = y;
271
+ let a = new TextEncoder(), c = a.encode(r), b = typeof t == "string" ? a.encode(t) : t, h = b;
205
272
  if (n !== void 0) {
206
- let g = d.encode(`${n}.`), p = new Uint8Array(g.length + y.length);
207
- p.set(g, 0), p.set(y, g.length), h = p;
273
+ let d = a.encode(`${n}.`), w = new Uint8Array(d.length + b.length);
274
+ w.set(d, 0), w.set(b, d.length), h = w;
208
275
  }
209
- let f = await o.importKey(
276
+ let g = await i.importKey(
210
277
  "raw",
211
278
  c,
212
279
  { name: "HMAC", hash: "SHA-256" },
213
280
  false,
214
281
  ["sign"]
215
- ), l = await o.sign(
282
+ ), p = await i.sign(
216
283
  "HMAC",
217
- f,
284
+ g,
218
285
  h
219
- ), m = new Uint8Array(l), k = Z(i.toLowerCase());
220
- if (!k || k.length !== m.length) return false;
221
- let u = 0;
222
- for (let g = 0; g < m.length; g++)
223
- u |= m[g] ^ k[g];
224
- return u === 0;
286
+ ), l = new Uint8Array(p), f = ae(o.toLowerCase());
287
+ if (!f || f.length !== l.length) return false;
288
+ let v = 0;
289
+ for (let d = 0; d < l.length; d++)
290
+ v |= l[d] ^ f[d];
291
+ return v === 0;
225
292
  }
226
- async function pe(t, e, r, n = {}) {
227
- let i = n.toleranceMs ?? 3e5, o = (l) => {
293
+ async function Re(t, e, r, n = {}) {
294
+ let o = n.toleranceMs ?? 3e5, i = (p) => {
228
295
  if (typeof e.get == "function")
229
- return e.get(l);
230
- let m = e, k = l.toLowerCase();
231
- for (let u of Object.keys(m))
232
- if (u.toLowerCase() === k) return m[u] ?? null;
296
+ return e.get(p);
297
+ let l = e, f = p.toLowerCase();
298
+ for (let v of Object.keys(l))
299
+ if (v.toLowerCase() === f) return l[v] ?? null;
233
300
  return null;
234
- }, d = o("x-neetru-timestamp");
235
- if (!d)
301
+ }, a = i("x-neetru-timestamp");
302
+ if (!a)
236
303
  return { ok: false, reason: "timestamp_missing" };
237
- let c = Number(d);
304
+ let c = Number(a);
238
305
  if (!Number.isFinite(c))
239
306
  return { ok: false, reason: "timestamp_missing" };
240
- if (Math.abs(Date.now() - c) > i)
307
+ if (Math.abs(Date.now() - c) > o)
241
308
  return { ok: false, reason: "timestamp_expired" };
242
- let h = o("x-neetru-signature");
243
- return await Q(t, h, r, d) ? { ok: true } : { ok: false, reason: "invalid_signature" };
309
+ let h = i("x-neetru-signature");
310
+ return await se(t, h, r, a) ? { ok: true } : { ok: false, reason: "invalid_signature" };
244
311
  }
245
- function Z(t) {
312
+ function ae(t) {
246
313
  if (t.length % 2 !== 0) return null;
247
314
  let e = new Uint8Array(t.length / 2);
248
315
  for (let r = 0; r < e.length; r++) {
249
- let n = parseInt(t[r * 2], 16), i = parseInt(t[r * 2 + 1], 16);
250
- if (Number.isNaN(n) || Number.isNaN(i)) return null;
251
- e[r] = n << 4 | i;
316
+ let n = parseInt(t[r * 2], 16), o = parseInt(t[r * 2 + 1], 16);
317
+ if (Number.isNaN(n) || Number.isNaN(o)) return null;
318
+ e[r] = n << 4 | o;
252
319
  }
253
320
  return e;
254
321
  }
255
- var $ = [
322
+ var V = [
256
323
  "subscription.activated",
257
324
  "subscription.cancelled",
258
325
  "subscription.payment_failed",
@@ -262,7 +329,7 @@ var $ = [
262
329
  "account.reactivated",
263
330
  "support.ticket_replied"
264
331
  ];
265
- function U(t) {
332
+ function H(t) {
266
333
  if (!t || typeof t != "object")
267
334
  throw new s("invalid_response", "Webhook response is not an object");
268
335
  let e = t;
@@ -272,7 +339,7 @@ function U(t) {
272
339
  id: e.id,
273
340
  url: typeof e.url == "string" ? e.url : "",
274
341
  events: Array.isArray(e.events) ? e.events.filter(
275
- (r) => $.includes(r)
342
+ (r) => V.includes(r)
276
343
  ) : [],
277
344
  hasSecret: e.hasSecret === true,
278
345
  status: e.status === "active" || e.status === "degraded" || e.status === "disabled" ? e.status : "active",
@@ -281,7 +348,7 @@ function U(t) {
281
348
  createdAt: typeof e.createdAt == "string" ? e.createdAt : (/* @__PURE__ */ new Date()).toISOString()
282
349
  };
283
350
  }
284
- function K(t) {
351
+ function B(t) {
285
352
  if (!t.url || typeof t.url != "string")
286
353
  throw new s("validation_failed", "url \xE9 obrigat\xF3ria");
287
354
  try {
@@ -294,27 +361,27 @@ function K(t) {
294
361
  if (!Array.isArray(t.events) || t.events.length === 0)
295
362
  throw new s("validation_failed", "events deve ter pelo menos 1 evento");
296
363
  for (let e of t.events)
297
- if (!$.includes(e))
364
+ if (!V.includes(e))
298
365
  throw new s("validation_failed", `evento desconhecido: ${e}`);
299
366
  if (t.secret !== void 0 && t.secret.length < 16)
300
367
  throw new s("validation_failed", "secret deve ter \u226516 chars (recomendado 32+)");
301
368
  }
302
- function E(t, ...e) {
369
+ function R(t, ...e) {
303
370
  for (let r of e)
304
371
  if (typeof r == "string" && r.length > 0)
305
- return I("productId", r), r;
372
+ return S("productId", r), r;
306
373
  if (t.productId)
307
- return I("productId", t.productId), t.productId;
374
+ return S("productId", t.productId), t.productId;
308
375
  throw new s(
309
376
  "validation_failed",
310
377
  "productId required (pass to options/input or set on createNeetruClient)"
311
378
  );
312
379
  }
313
- function fe(t) {
380
+ function Ie(t) {
314
381
  return {
315
382
  async register(e) {
316
- K(e);
317
- let r = E(t, e.productId), n = await _(t, {
383
+ B(e);
384
+ let r = R(t, e.productId), n = await k(t, {
318
385
  method: "POST",
319
386
  path: "/api/sdk/v1/webhooks",
320
387
  body: {
@@ -330,21 +397,21 @@ function fe(t) {
330
397
  // dedup TTL 24h (mesmo padrão de usage.report/support.createTicket).
331
398
  idempotencyKey: true
332
399
  });
333
- return U(n);
400
+ return H(n);
334
401
  },
335
402
  async list(e) {
336
- let r = E(t, e?.productId), n = await _(t, {
403
+ let r = R(t, e?.productId), n = await k(t, {
337
404
  method: "GET",
338
405
  path: "/api/sdk/v1/webhooks",
339
406
  query: { productId: r },
340
407
  requireAuth: true
341
408
  });
342
- return (Array.isArray(n?.endpoints) ? n.endpoints : []).map(U);
409
+ return (Array.isArray(n?.endpoints) ? n.endpoints : []).map(H);
343
410
  },
344
411
  async unregister(e, r) {
345
412
  if (!e) throw new s("validation_failed", "id obrigat\xF3rio");
346
- let n = E(t, r?.productId);
347
- return await _(t, {
413
+ let n = R(t, r?.productId);
414
+ return await k(t, {
348
415
  method: "DELETE",
349
416
  path: `/api/sdk/v1/webhooks/${encodeURIComponent(e)}`,
350
417
  query: { productId: n },
@@ -353,30 +420,30 @@ function fe(t) {
353
420
  },
354
421
  async test(e, r) {
355
422
  if (!e) throw new s("validation_failed", "id obrigat\xF3rio");
356
- let n = E(t, r?.productId), i = await _(t, {
423
+ let n = R(t, r?.productId), o = await k(t, {
357
424
  method: "POST",
358
425
  path: `/api/sdk/v1/webhooks/${encodeURIComponent(e)}/test`,
359
426
  query: { productId: n },
360
427
  requireAuth: true,
361
428
  idempotencyKey: true
362
429
  });
363
- if (!i || typeof i != "object")
430
+ if (!o || typeof o != "object")
364
431
  return { ok: false, error: "invalid response" };
365
- let o = i;
432
+ let i = o;
366
433
  return {
367
- ok: o.ok === true,
368
- statusCode: typeof o.statusCode == "number" ? o.statusCode : void 0,
369
- durationMs: typeof o.durationMs == "number" ? o.durationMs : void 0,
370
- error: typeof o.error == "string" ? o.error : void 0
434
+ ok: i.ok === true,
435
+ statusCode: typeof i.statusCode == "number" ? i.statusCode : void 0,
436
+ durationMs: typeof i.durationMs == "number" ? i.durationMs : void 0,
437
+ error: typeof i.error == "string" ? i.error : void 0
371
438
  };
372
439
  }
373
440
  };
374
441
  }
375
- var P = class {
442
+ var j = class {
376
443
  endpoints = /* @__PURE__ */ new Map();
377
444
  nextId = 1;
378
445
  async register(e) {
379
- K(e);
446
+ B(e);
380
447
  let r = `mock_wh_${this.nextId++}`, n = {
381
448
  id: r,
382
449
  url: e.url,
@@ -402,4 +469,4 @@ var P = class {
402
469
  }
403
470
  };
404
471
 
405
- export { P as MockWebhooks, fe as createWebhooksNamespace, pe as verifyWebhookRequest, Q as verifyWebhookSignature };
472
+ export { j as MockWebhooks, Ie as createWebhooksNamespace, Re as verifyWebhookRequest, se as verifyWebhookSignature };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neetru/sdk",
3
- "version": "3.7.0",
3
+ "version": "3.8.1",
4
4
  "description": "Neetru SDK 3.0 — biblioteca runtime universal (browser/Node/Edge) para consumir o ecossistema Neetru. Paths canonical /api/sdk/v1/*, productId obrigatório, Idempotency-Key em mutations, WebCrypto signatures, baseUrl allowlist fail-closed.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -135,6 +135,7 @@
135
135
  "test:coverage": "vitest run --coverage",
136
136
  "lint": "tsc --noEmit",
137
137
  "docs:gen": "typedoc --options scripts/typedoc.config.json",
138
+ "prepare": "node -e \"try{if(require('fs').existsSync('.git'))require('child_process').execFileSync('git',['config','core.hooksPath','.githooks'],{stdio:'ignore'})}catch{}\"",
138
139
  "prepublishOnly": "npm run build"
139
140
  },
140
141
  "files": [