@neetru/sdk 3.6.0 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/dist/ai.cjs +254 -391
  3. package/dist/ai.d.cts +1 -1
  4. package/dist/ai.d.ts +1 -1
  5. package/dist/ai.mjs +254 -391
  6. package/dist/auth.cjs +3547 -4998
  7. package/dist/auth.d.cts +1 -1
  8. package/dist/auth.d.ts +1 -1
  9. package/dist/auth.mjs +3544 -4995
  10. package/dist/build-guard.cjs +101 -119
  11. package/dist/build-guard.mjs +91 -109
  12. package/dist/catalog.cjs +152 -224
  13. package/dist/catalog.d.cts +1 -1
  14. package/dist/catalog.d.ts +1 -1
  15. package/dist/catalog.mjs +152 -224
  16. package/dist/checkout.cjs +237 -320
  17. package/dist/checkout.d.cts +1 -1
  18. package/dist/checkout.d.ts +1 -1
  19. package/dist/checkout.mjs +236 -319
  20. package/dist/db-react.cjs +59 -87
  21. package/dist/db-react.d.cts +1 -1
  22. package/dist/db-react.d.ts +1 -1
  23. package/dist/db-react.mjs +56 -84
  24. package/dist/db.cjs +2055 -3013
  25. package/dist/db.d.cts +1 -1
  26. package/dist/db.d.ts +1 -1
  27. package/dist/db.mjs +2068 -3026
  28. package/dist/entitlements.cjs +12 -20
  29. package/dist/entitlements.d.cts +1 -1
  30. package/dist/entitlements.d.ts +1 -1
  31. package/dist/entitlements.mjs +12 -20
  32. package/dist/errors.cjs +9 -12
  33. package/dist/errors.d.cts +37 -2
  34. package/dist/errors.d.ts +37 -2
  35. package/dist/errors.mjs +8 -12
  36. package/dist/firestore-compat.cjs +241 -297
  37. package/dist/firestore-compat.d.cts +1 -1
  38. package/dist/firestore-compat.d.ts +1 -1
  39. package/dist/firestore-compat.mjs +215 -271
  40. package/dist/index.cjs +3605 -5131
  41. package/dist/index.d.cts +6 -4
  42. package/dist/index.d.ts +6 -4
  43. package/dist/index.mjs +3710 -5236
  44. package/dist/mobile.cjs +238 -342
  45. package/dist/mobile.d.cts +1 -1
  46. package/dist/mobile.d.ts +1 -1
  47. package/dist/mobile.mjs +238 -342
  48. package/dist/mocks.cjs +312 -447
  49. package/dist/mocks.d.cts +1 -1
  50. package/dist/mocks.d.ts +1 -1
  51. package/dist/mocks.mjs +306 -441
  52. package/dist/notifications.cjs +226 -314
  53. package/dist/notifications.d.cts +1 -1
  54. package/dist/notifications.d.ts +1 -1
  55. package/dist/notifications.mjs +225 -313
  56. package/dist/react.cjs +522 -693
  57. package/dist/react.d.cts +1 -1
  58. package/dist/react.d.ts +1 -1
  59. package/dist/react.mjs +512 -683
  60. package/dist/support.cjs +329 -325
  61. package/dist/support.d.cts +25 -3
  62. package/dist/support.d.ts +25 -3
  63. package/dist/support.mjs +328 -325
  64. package/dist/telemetry.cjs +197 -301
  65. package/dist/telemetry.d.cts +1 -1
  66. package/dist/telemetry.d.ts +1 -1
  67. package/dist/telemetry.mjs +197 -301
  68. package/dist/{types-Du_iioJ7.d.cts → types-Bx4kTLmk.d.cts} +26 -0
  69. package/dist/{types-BPATkXYu.d.ts → types-Dx0IrOSF.d.ts} +26 -0
  70. package/dist/usage.cjs +163 -227
  71. package/dist/usage.d.cts +1 -1
  72. package/dist/usage.d.ts +1 -1
  73. package/dist/usage.mjs +163 -227
  74. package/dist/webhooks.cjs +258 -359
  75. package/dist/webhooks.d.cts +1 -1
  76. package/dist/webhooks.d.ts +1 -1
  77. package/dist/webhooks.mjs +255 -356
  78. package/package.json +4 -3
  79. package/dist/ai.cjs.map +0 -1
  80. package/dist/ai.mjs.map +0 -1
  81. package/dist/auth.cjs.map +0 -1
  82. package/dist/auth.mjs.map +0 -1
  83. package/dist/build-guard.cjs.map +0 -1
  84. package/dist/build-guard.mjs.map +0 -1
  85. package/dist/catalog.cjs.map +0 -1
  86. package/dist/catalog.mjs.map +0 -1
  87. package/dist/checkout.cjs.map +0 -1
  88. package/dist/checkout.mjs.map +0 -1
  89. package/dist/db-react.cjs.map +0 -1
  90. package/dist/db-react.mjs.map +0 -1
  91. package/dist/db.cjs.map +0 -1
  92. package/dist/db.mjs.map +0 -1
  93. package/dist/entitlements.cjs.map +0 -1
  94. package/dist/entitlements.mjs.map +0 -1
  95. package/dist/errors.cjs.map +0 -1
  96. package/dist/errors.mjs.map +0 -1
  97. package/dist/firestore-compat.cjs.map +0 -1
  98. package/dist/firestore-compat.mjs.map +0 -1
  99. package/dist/index.cjs.map +0 -1
  100. package/dist/index.mjs.map +0 -1
  101. package/dist/mobile.cjs.map +0 -1
  102. package/dist/mobile.mjs.map +0 -1
  103. package/dist/mocks.cjs.map +0 -1
  104. package/dist/mocks.mjs.map +0 -1
  105. package/dist/notifications.cjs.map +0 -1
  106. package/dist/notifications.mjs.map +0 -1
  107. package/dist/react.cjs.map +0 -1
  108. package/dist/react.mjs.map +0 -1
  109. package/dist/support.cjs.map +0 -1
  110. package/dist/support.mjs.map +0 -1
  111. package/dist/telemetry.cjs.map +0 -1
  112. package/dist/telemetry.mjs.map +0 -1
  113. package/dist/usage.cjs.map +0 -1
  114. package/dist/usage.mjs.map +0 -1
  115. package/dist/webhooks.cjs.map +0 -1
  116. package/dist/webhooks.mjs.map +0 -1
package/dist/webhooks.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  // src/errors.ts
4
- var NeetruError = class _NeetruError extends Error {
4
+ var s = class t extends Error {
5
5
  code;
6
6
  status;
7
7
  requestId;
@@ -14,322 +14,247 @@ var NeetruError = class _NeetruError extends Error {
14
14
  * para um `NeetruDbErrorCode` mais específico (recuperável vs não).
15
15
  */
16
16
  reason;
17
- constructor(code, message, status, requestId, reason) {
18
- super(message);
19
- this.name = "NeetruError";
20
- this.code = code;
21
- this.status = status;
22
- this.requestId = requestId;
23
- this.reason = reason;
24
- Object.setPrototypeOf(this, _NeetruError.prototype);
17
+ constructor(e, r, n, i, o) {
18
+ super(r), this.name = "NeetruError", this.code = e, this.status = n, this.requestId = i, this.reason = o, Object.setPrototypeOf(this, t.prototype);
25
19
  }
26
20
  };
27
21
 
28
22
  // src/idempotency.ts
29
- function generateIdempotencyKey() {
30
- const cryptoObj = typeof globalThis !== "undefined" && "crypto" in globalThis ? globalThis.crypto : void 0;
31
- if (cryptoObj && typeof cryptoObj.randomUUID === "function") {
32
- return cryptoObj.randomUUID();
33
- }
34
- throw new NeetruError(
23
+ function S() {
24
+ let t = typeof globalThis < "u" && "crypto" in globalThis ? globalThis.crypto : void 0;
25
+ if (t && typeof t.randomUUID == "function")
26
+ return t.randomUUID();
27
+ throw new s(
35
28
  "runtime_unsupported",
36
29
  "crypto.randomUUID not available in this runtime. SDK 3.0 requires Node \u226520 or modern browser/Edge."
37
30
  );
38
31
  }
39
32
 
40
33
  // src/http.ts
41
- var COMPAT_MATRIX = {
34
+ var H = {
42
35
  // SDK major 3.x requer Core ≥ 2026.05.1 (suporte a X-Neetru-Version header,
43
36
  // runTransaction write-after-read, verifyWebhookRequest, webhooks 3.0+)
44
37
  3: "2026.05.1"
45
38
  };
46
- function stripRevision(v) {
47
- return v.split("+")[0] ?? v;
39
+ function A(t) {
40
+ return t.split("+")[0] ?? t;
48
41
  }
49
- function compareCalVer(a, b) {
50
- const partsA = stripRevision(a).split(".").map(Number);
51
- const partsB = stripRevision(b).split(".").map(Number);
52
- const len = Math.max(partsA.length, partsB.length);
53
- for (let i = 0; i < len; i++) {
54
- const pa = partsA[i] ?? 0;
55
- const pb = partsB[i] ?? 0;
56
- if (pa !== pb) return pa - pb;
42
+ function j(t, e) {
43
+ let r = A(t).split(".").map(Number), n = A(e).split(".").map(Number), i = Math.max(r.length, n.length);
44
+ for (let o = 0; o < i; o++) {
45
+ let d = r[o] ?? 0, c = n[o] ?? 0;
46
+ if (d !== c) return d - c;
57
47
  }
58
48
  return 0;
59
49
  }
60
- function readInjectedSdkVersion() {
50
+ function q() {
61
51
  try {
62
- return "3.6.0";
52
+ return "3.7.0";
63
53
  } catch {
64
- return void 0;
54
+ return;
65
55
  }
66
56
  }
67
- function getSdkMajor() {
68
- const ver = readInjectedSdkVersion();
69
- if (ver) return parseInt(ver.split(".")[0] ?? "3", 10);
70
- return 3;
57
+ function V() {
58
+ let t = q();
59
+ return t ? parseInt(t.split(".")[0] ?? "3", 10) : 3;
71
60
  }
72
- var _warnedCoreTooOld = /* @__PURE__ */ new Set();
73
- function checkCoreVersionCompat(coreVersion) {
74
- if (!coreVersion) return;
75
- const sdkMajor = getSdkMajor();
76
- const minCore = COMPAT_MATRIX[sdkMajor];
77
- if (!minCore) return;
78
- const stripped = stripRevision(coreVersion);
79
- if (compareCalVer(stripped, minCore) < 0) {
80
- const key = `${sdkMajor}:${stripped}`;
81
- if (!_warnedCoreTooOld.has(key)) {
82
- _warnedCoreTooOld.add(key);
83
- console.warn(
84
- `[Neetru SDK] Aten\xE7\xE3o: Core vers\xE3o "${coreVersion}" \xE9 anterior ao m\xEDnimo recomendado "${minCore}" para SDK major ${sdkMajor}. Alguns recursos podem n\xE3o funcionar corretamente. Atualize o Core para a vers\xE3o mais recente.`
85
- );
86
- }
61
+ var W = /* @__PURE__ */ new Set();
62
+ function B(t) {
63
+ if (!t) return;
64
+ let e = V(), r = H[e];
65
+ if (!r) return;
66
+ let n = A(t);
67
+ if (j(n, r) < 0) {
68
+ let i = `${e}:${n}`;
69
+ W.has(i) || (W.add(i), console.warn(
70
+ `[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.`
71
+ ));
87
72
  }
88
73
  }
89
- var DEFAULT_RETRIES_READ = 2;
90
- var DEFAULT_RETRIES_WRITE = 0;
91
- var READ_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD"]);
92
- var RETRYABLE_CODES = /* @__PURE__ */ new Set([
74
+ var L = 2, F = 0, z = /* @__PURE__ */ new Set(["GET", "HEAD"]), G = /* @__PURE__ */ new Set([
93
75
  "rate_limited",
94
76
  "server_error",
95
77
  "network_error"
96
78
  ]);
97
- function backoffMs(attempt) {
98
- const base = 200 * Math.pow(4, attempt);
99
- const jitter = base * 0.2 * (Math.random() * 2 - 1);
100
- return Math.max(50, Math.round(base + jitter));
79
+ function N(t) {
80
+ let e = 200 * Math.pow(4, t), r = e * 0.2 * (Math.random() * 2 - 1);
81
+ return Math.max(50, Math.round(e + r));
101
82
  }
102
- var MAX_RETRY_AFTER_MS = 6e4;
103
- function parseRetryAfter(value) {
104
- if (!value) return null;
105
- const secs = Number(value);
106
- if (Number.isFinite(secs) && secs >= 0) return Math.min(Math.round(secs * 1e3), MAX_RETRY_AFTER_MS);
107
- const dateMs = Date.parse(value);
108
- if (Number.isFinite(dateMs)) {
109
- const delta = dateMs - Date.now();
110
- if (delta > 0) return Math.min(delta, MAX_RETRY_AFTER_MS);
83
+ var C = 6e4;
84
+ function J(t) {
85
+ if (!t) return null;
86
+ let e = Number(t);
87
+ if (Number.isFinite(e) && e >= 0) return Math.min(Math.round(e * 1e3), C);
88
+ let r = Date.parse(t);
89
+ if (Number.isFinite(r)) {
90
+ let n = r - Date.now();
91
+ if (n > 0) return Math.min(n, C);
111
92
  }
112
93
  return null;
113
94
  }
114
- function sleep(ms) {
115
- return new Promise((resolve) => setTimeout(resolve, ms));
95
+ function D(t) {
96
+ return new Promise((e) => setTimeout(e, t));
116
97
  }
117
- function statusToCode(status) {
118
- if (status === 401) return "unauthorized";
119
- if (status === 403) return "forbidden";
120
- if (status === 404) return "not_found";
121
- if (status === 409) return "conflict";
122
- if (status === 422 || status === 400) return "validation_failed";
123
- if (status === 429) return "rate_limited";
124
- if (status >= 500) return "server_error";
125
- return "unknown";
98
+ function Y(t) {
99
+ 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";
126
100
  }
127
- function buildUrl(baseUrl, path, query) {
128
- const base = baseUrl.replace(/\/+$/, "");
129
- const p = path.startsWith("/") ? path : `/${path}`;
130
- const url = new URL(`${base}${p}`);
131
- if (query) {
132
- for (const [k, v] of Object.entries(query)) {
133
- if (v === void 0) continue;
134
- url.searchParams.set(k, String(v));
135
- }
136
- }
137
- return url.toString();
101
+ function X(t, e, r) {
102
+ let n = t.replace(/\/+$/, ""), i = e.startsWith("/") ? e : `/${e}`, o = new URL(`${n}${i}`);
103
+ if (r)
104
+ for (let [d, c] of Object.entries(r))
105
+ c !== void 0 && o.searchParams.set(d, String(c));
106
+ return o.toString();
138
107
  }
139
- async function safeJson(res) {
140
- const text = await res.text();
141
- if (!text) return void 0;
142
- try {
143
- return JSON.parse(text);
144
- } catch {
145
- return void 0;
146
- }
108
+ async function M(t) {
109
+ let e = await t.text();
110
+ if (e)
111
+ try {
112
+ return JSON.parse(e);
113
+ } catch {
114
+ return;
115
+ }
147
116
  }
148
- async function httpRequest(config, opts) {
149
- const method = opts.method ?? "GET";
150
- const url = buildUrl(config.baseUrl, opts.path, opts.query);
151
- const defaultRetries = READ_METHODS.has(method) ? DEFAULT_RETRIES_READ : DEFAULT_RETRIES_WRITE;
152
- const maxRetries = opts.retries ?? defaultRetries;
153
- const headers = {
117
+ async function _(t, e) {
118
+ let r = e.method ?? "GET", n = X(t.baseUrl, e.path, e.query), i = z.has(r) ? L : F, o = e.retries ?? i, d = {
154
119
  accept: "application/json",
155
- ...opts.headers
156
- };
157
- const sdkVersion = readInjectedSdkVersion();
158
- if (sdkVersion) {
159
- headers["x-neetru-sdk-version"] = sdkVersion;
160
- }
161
- if (opts.requireAuth) {
162
- if (!config.apiKey) {
163
- throw new NeetruError(
120
+ ...e.headers
121
+ }, c = q();
122
+ if (c && (d["x-neetru-sdk-version"] = c), e.requireAuth) {
123
+ if (!t.apiKey)
124
+ throw new s(
164
125
  "missing_api_key",
165
126
  "This operation requires an apiKey. Pass it to createNeetruClient({ apiKey }) or set NEETRU_API_KEY env var."
166
127
  );
167
- }
168
- headers.authorization = `Bearer ${config.apiKey}`;
169
- }
170
- if (opts.idempotencyKey) {
171
- const key = typeof opts.idempotencyKey === "string" ? opts.idempotencyKey : generateIdempotencyKey();
172
- headers["idempotency-key"] = key;
173
- }
174
- const bodyString = opts.body !== void 0 && method !== "GET" && method !== "DELETE" ? JSON.stringify(opts.body) : void 0;
175
- if (bodyString !== void 0) {
176
- headers["content-type"] = "application/json";
177
- }
178
- let lastError = null;
179
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
180
- const init = { method, headers };
181
- if (bodyString !== void 0) init.body = bodyString;
182
- init.signal = AbortSignal.timeout(3e4);
183
- let res;
128
+ d.authorization = `Bearer ${t.apiKey}`;
129
+ }
130
+ if (e.idempotencyKey) {
131
+ let l = typeof e.idempotencyKey == "string" ? e.idempotencyKey : S();
132
+ d["idempotency-key"] = l;
133
+ }
134
+ let y = e.body !== void 0 && r !== "GET" && r !== "DELETE" ? JSON.stringify(e.body) : void 0;
135
+ y !== void 0 && (d["content-type"] = "application/json");
136
+ let h = null, f = e.deadlineMs != null ? Date.now() + e.deadlineMs : null;
137
+ for (let l = 0; l <= o; l++) {
138
+ if (f != null && Date.now() >= f)
139
+ throw h ?? new s("network_error", "Deadline excedido antes de completar a request");
140
+ let m = { method: r, headers: d };
141
+ y !== void 0 && (m.body = y);
142
+ let k = f != null ? Math.max(1, Math.min(3e4, f - Date.now())) : 3e4;
143
+ m.signal = AbortSignal.timeout(k);
144
+ let u;
184
145
  try {
185
- res = await config.fetch(url, init);
186
- } catch (err2) {
187
- const message2 = err2 instanceof DOMException && err2.name === "TimeoutError" ? "Network error: timeout after 30s" : `Network error: ${err2 instanceof Error ? err2.message : "fetch failed"}`;
188
- lastError = new NeetruError("network_error", message2);
189
- if (attempt < maxRetries) {
190
- await sleep(backoffMs(attempt));
191
- continue;
146
+ u = await t.fetch(n, m);
147
+ } catch (a) {
148
+ let w = a instanceof DOMException && a.name === "TimeoutError" ? "Network error: timeout after 30s" : `Network error: ${a instanceof Error ? a.message : "fetch failed"}`;
149
+ if (h = new s("network_error", w), l < o) {
150
+ let x = N(l);
151
+ if (f == null || Date.now() + x < f) {
152
+ await D(x);
153
+ continue;
154
+ }
192
155
  }
193
- throw lastError;
156
+ throw h;
194
157
  }
195
- const requestId = res.headers.get("x-request-id") ?? res.headers.get("x-correlation-id") ?? void 0;
196
- if (res.ok) {
197
- const coreVersion = res.headers.get("x-neetru-version");
198
- if (coreVersion) checkCoreVersionCompat(coreVersion);
199
- const parsed = await safeJson(res);
200
- return parsed;
158
+ let g = u.headers.get("x-request-id") ?? u.headers.get("x-correlation-id") ?? void 0;
159
+ if (u.ok) {
160
+ let a = u.headers.get("x-neetru-version");
161
+ return a && B(a), await M(u);
201
162
  }
202
- const body = await safeJson(res);
203
- let code = statusToCode(res.status);
204
- let message = `HTTP ${res.status}`;
205
- let reason;
206
- if (body && typeof body === "object") {
207
- const errField = body.error;
208
- if (typeof errField === "string") {
209
- message = errField;
210
- } else if (errField && typeof errField === "object") {
211
- if (typeof errField.code === "string") code = errField.code;
212
- if (typeof errField.message === "string") message = errField.message;
213
- if (typeof errField.reason === "string") reason = errField.reason;
214
- } else {
215
- if (typeof body.code === "string") code = body.code;
216
- if (typeof body.message === "string") message = body.message;
217
- }
218
- if (typeof body.reason === "string") reason = body.reason;
163
+ let p = await M(u), v = Y(u.status), b = `HTTP ${u.status}`, R;
164
+ if (p && typeof p == "object") {
165
+ let a = p.error;
166
+ 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);
167
+ }
168
+ if (u.status === 410) {
169
+ let a = u.headers.get("x-neetru-replacement");
170
+ 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}.`);
219
171
  }
220
- const err = new NeetruError(code, message, res.status, requestId, reason);
221
- lastError = err;
222
- const isRetryable = RETRYABLE_CODES.has(code);
223
- if (isRetryable && attempt < maxRetries) {
224
- const retryAfter = parseRetryAfter(res.headers.get("retry-after"));
225
- const delay = retryAfter ?? backoffMs(attempt);
226
- await sleep(delay);
227
- continue;
172
+ let T = new s(v, b, u.status, g, R);
173
+ if (h = T, G.has(v) && l < o) {
174
+ let w = J(u.headers.get("retry-after")) ?? N(l);
175
+ if (f == null || Date.now() + w < f) {
176
+ await D(w);
177
+ continue;
178
+ }
228
179
  }
229
- throw err;
180
+ throw T;
230
181
  }
231
- throw lastError ?? new NeetruError("unknown", "unexpected httpRequest exit");
182
+ throw h ?? new s("unknown", "unexpected httpRequest exit");
232
183
  }
233
184
 
234
185
  // src/validators.ts
235
- var SDK_ID_RE = /^[a-z0-9][a-z0-9_-]{0,62}$/i;
236
- function assertValidSdkId(field, value) {
237
- if (typeof value !== "string" || !SDK_ID_RE.test(value)) {
238
- throw new NeetruError(
186
+ var O = /^[a-z0-9][a-z0-9_-]{0,62}$/i;
187
+ function I(t, e) {
188
+ if (typeof e != "string" || !O.test(e))
189
+ throw new s(
239
190
  "validation_failed",
240
- `${field} must match ${SDK_ID_RE.source} (lowercase alphanumeric, _, -; first char must be alphanumeric; max 63 chars)`
191
+ `${t} must match ${O.source} (lowercase alphanumeric, _, -; first char must be alphanumeric; max 63 chars)`
241
192
  );
242
- }
243
193
  }
244
194
 
245
195
  // src/webhooks.ts
246
- async function verifyWebhookSignature(payload, signature, secret, timestamp) {
247
- if (!signature || !secret) return false;
248
- const sigHex = signature.startsWith("sha256=") ? signature.slice(7) : signature;
249
- if (!/^[0-9a-f]+$/i.test(sigHex)) return false;
250
- const subtle = typeof globalThis !== "undefined" && "crypto" in globalThis ? globalThis.crypto?.subtle : void 0;
251
- if (!subtle) {
252
- throw new NeetruError(
196
+ async function Q(t, e, r, n) {
197
+ if (!e || !r) return false;
198
+ let i = e.startsWith("sha256=") ? e.slice(7) : e;
199
+ if (!/^[0-9a-f]+$/i.test(i)) return false;
200
+ let o = typeof globalThis < "u" && "crypto" in globalThis ? globalThis.crypto?.subtle : void 0;
201
+ if (!o)
202
+ throw new s(
253
203
  "runtime_unsupported",
254
204
  "verifyWebhookSignature requires globalThis.crypto.subtle (Node \u226520, modern browser, or Edge runtime)."
255
205
  );
206
+ let d = new TextEncoder(), c = d.encode(r), y = typeof t == "string" ? d.encode(t) : t, h = y;
207
+ if (n !== void 0) {
208
+ let g = d.encode(`${n}.`), p = new Uint8Array(g.length + y.length);
209
+ p.set(g, 0), p.set(y, g.length), h = p;
256
210
  }
257
- const encoder = new TextEncoder();
258
- const keyBytes = encoder.encode(secret);
259
- const rawBytes = typeof payload === "string" ? encoder.encode(payload) : payload;
260
- let payloadBytes = rawBytes;
261
- if (timestamp !== void 0) {
262
- const prefix = encoder.encode(`${timestamp}.`);
263
- const merged = new Uint8Array(prefix.length + rawBytes.length);
264
- merged.set(prefix, 0);
265
- merged.set(rawBytes, prefix.length);
266
- payloadBytes = merged;
267
- }
268
- const key = await subtle.importKey(
211
+ let f = await o.importKey(
269
212
  "raw",
270
- keyBytes,
213
+ c,
271
214
  { name: "HMAC", hash: "SHA-256" },
272
215
  false,
273
216
  ["sign"]
274
- );
275
- const macBuffer = await subtle.sign(
217
+ ), l = await o.sign(
276
218
  "HMAC",
277
- key,
278
- payloadBytes
279
- );
280
- const macBytes = new Uint8Array(macBuffer);
281
- const sigBytes = hexToBytes(sigHex.toLowerCase());
282
- if (!sigBytes || sigBytes.length !== macBytes.length) return false;
283
- let diff = 0;
284
- for (let i = 0; i < macBytes.length; i++) {
285
- diff |= macBytes[i] ^ sigBytes[i];
286
- }
287
- return diff === 0;
219
+ f,
220
+ h
221
+ ), m = new Uint8Array(l), k = Z(i.toLowerCase());
222
+ if (!k || k.length !== m.length) return false;
223
+ let u = 0;
224
+ for (let g = 0; g < m.length; g++)
225
+ u |= m[g] ^ k[g];
226
+ return u === 0;
288
227
  }
289
- async function verifyWebhookRequest(payload, headers, secret, options = {}) {
290
- const toleranceMs = options.toleranceMs ?? 3e5;
291
- const getHeader = (name) => {
292
- if (typeof headers.get === "function") {
293
- return headers.get(name);
294
- }
295
- const rec = headers;
296
- const lower = name.toLowerCase();
297
- for (const key of Object.keys(rec)) {
298
- if (key.toLowerCase() === lower) return rec[key] ?? null;
299
- }
228
+ async function pe(t, e, r, n = {}) {
229
+ let i = n.toleranceMs ?? 3e5, o = (l) => {
230
+ if (typeof e.get == "function")
231
+ return e.get(l);
232
+ let m = e, k = l.toLowerCase();
233
+ for (let u of Object.keys(m))
234
+ if (u.toLowerCase() === k) return m[u] ?? null;
300
235
  return null;
301
- };
302
- const tsHeader = getHeader("x-neetru-timestamp");
303
- if (!tsHeader) {
236
+ }, d = o("x-neetru-timestamp");
237
+ if (!d)
304
238
  return { ok: false, reason: "timestamp_missing" };
305
- }
306
- const tsMs = Number(tsHeader);
307
- if (!Number.isFinite(tsMs)) {
239
+ let c = Number(d);
240
+ if (!Number.isFinite(c))
308
241
  return { ok: false, reason: "timestamp_missing" };
309
- }
310
- const skewMs = Math.abs(Date.now() - tsMs);
311
- if (skewMs > toleranceMs) {
242
+ if (Math.abs(Date.now() - c) > i)
312
243
  return { ok: false, reason: "timestamp_expired" };
313
- }
314
- const sig = getHeader("x-neetru-signature");
315
- const valid = await verifyWebhookSignature(payload, sig, secret, tsHeader);
316
- if (!valid) {
317
- return { ok: false, reason: "invalid_signature" };
318
- }
319
- return { ok: true };
244
+ let h = o("x-neetru-signature");
245
+ return await Q(t, h, r, d) ? { ok: true } : { ok: false, reason: "invalid_signature" };
320
246
  }
321
- function hexToBytes(hex) {
322
- if (hex.length % 2 !== 0) return null;
323
- const bytes = new Uint8Array(hex.length / 2);
324
- for (let i = 0; i < bytes.length; i++) {
325
- const high = parseInt(hex[i * 2], 16);
326
- const low = parseInt(hex[i * 2 + 1], 16);
327
- if (Number.isNaN(high) || Number.isNaN(low)) return null;
328
- bytes[i] = high << 4 | low;
329
- }
330
- return bytes;
247
+ function Z(t) {
248
+ if (t.length % 2 !== 0) return null;
249
+ let e = new Uint8Array(t.length / 2);
250
+ for (let r = 0; r < e.length; r++) {
251
+ let n = parseInt(t[r * 2], 16), i = parseInt(t[r * 2 + 1], 16);
252
+ if (Number.isNaN(n) || Number.isNaN(i)) return null;
253
+ e[r] = n << 4 | i;
254
+ }
255
+ return e;
331
256
  }
332
- var VALID_EVENTS = [
257
+ var $ = [
333
258
  "subscription.activated",
334
259
  "subscription.cancelled",
335
260
  "subscription.payment_failed",
@@ -339,80 +264,66 @@ var VALID_EVENTS = [
339
264
  "account.reactivated",
340
265
  "support.ticket_replied"
341
266
  ];
342
- function toEndpoint(raw) {
343
- if (!raw || typeof raw !== "object") {
344
- throw new NeetruError("invalid_response", "Webhook response is not an object");
345
- }
346
- const r = raw;
347
- if (typeof r.id !== "string") {
348
- throw new NeetruError("invalid_response", "Webhook missing id");
349
- }
267
+ function U(t) {
268
+ if (!t || typeof t != "object")
269
+ throw new s("invalid_response", "Webhook response is not an object");
270
+ let e = t;
271
+ if (typeof e.id != "string")
272
+ throw new s("invalid_response", "Webhook missing id");
350
273
  return {
351
- id: r.id,
352
- url: typeof r.url === "string" ? r.url : "",
353
- events: Array.isArray(r.events) ? r.events.filter(
354
- (e) => VALID_EVENTS.includes(e)
274
+ id: e.id,
275
+ url: typeof e.url == "string" ? e.url : "",
276
+ events: Array.isArray(e.events) ? e.events.filter(
277
+ (r) => $.includes(r)
355
278
  ) : [],
356
- hasSecret: r.hasSecret === true,
357
- status: r.status === "active" || r.status === "degraded" || r.status === "disabled" ? r.status : "active",
358
- lastDeliveryAt: typeof r.lastDeliveryAt === "string" ? r.lastDeliveryAt : void 0,
359
- consecutiveFailures: typeof r.consecutiveFailures === "number" ? r.consecutiveFailures : void 0,
360
- createdAt: typeof r.createdAt === "string" ? r.createdAt : (/* @__PURE__ */ new Date()).toISOString()
279
+ hasSecret: e.hasSecret === true,
280
+ status: e.status === "active" || e.status === "degraded" || e.status === "disabled" ? e.status : "active",
281
+ lastDeliveryAt: typeof e.lastDeliveryAt == "string" ? e.lastDeliveryAt : void 0,
282
+ consecutiveFailures: typeof e.consecutiveFailures == "number" ? e.consecutiveFailures : void 0,
283
+ createdAt: typeof e.createdAt == "string" ? e.createdAt : (/* @__PURE__ */ new Date()).toISOString()
361
284
  };
362
285
  }
363
- function validateInput(input) {
364
- if (!input.url || typeof input.url !== "string") {
365
- throw new NeetruError("validation_failed", "url \xE9 obrigat\xF3ria");
366
- }
286
+ function K(t) {
287
+ if (!t.url || typeof t.url != "string")
288
+ throw new s("validation_failed", "url \xE9 obrigat\xF3ria");
367
289
  try {
368
- const parsed = new URL(input.url);
369
- if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
290
+ let e = new URL(t.url);
291
+ if (e.protocol !== "https:" && e.protocol !== "http:")
370
292
  throw new Error("invalid protocol");
371
- }
372
293
  } catch {
373
- throw new NeetruError("validation_failed", `url inv\xE1lida: ${input.url}`);
374
- }
375
- if (!Array.isArray(input.events) || input.events.length === 0) {
376
- throw new NeetruError("validation_failed", "events deve ter pelo menos 1 evento");
377
- }
378
- for (const ev of input.events) {
379
- if (!VALID_EVENTS.includes(ev)) {
380
- throw new NeetruError("validation_failed", `evento desconhecido: ${ev}`);
381
- }
382
- }
383
- if (input.secret !== void 0 && input.secret.length < 16) {
384
- throw new NeetruError("validation_failed", "secret deve ter \u226516 chars (recomendado 32+)");
385
- }
294
+ throw new s("validation_failed", `url inv\xE1lida: ${t.url}`);
295
+ }
296
+ if (!Array.isArray(t.events) || t.events.length === 0)
297
+ throw new s("validation_failed", "events deve ter pelo menos 1 evento");
298
+ for (let e of t.events)
299
+ if (!$.includes(e))
300
+ throw new s("validation_failed", `evento desconhecido: ${e}`);
301
+ if (t.secret !== void 0 && t.secret.length < 16)
302
+ throw new s("validation_failed", "secret deve ter \u226516 chars (recomendado 32+)");
386
303
  }
387
- function resolveProductId(config, ...candidates) {
388
- for (const c of candidates) {
389
- if (typeof c === "string" && c.length > 0) {
390
- assertValidSdkId("productId", c);
391
- return c;
392
- }
393
- }
394
- if (config.productId) {
395
- assertValidSdkId("productId", config.productId);
396
- return config.productId;
397
- }
398
- throw new NeetruError(
304
+ function E(t, ...e) {
305
+ for (let r of e)
306
+ if (typeof r == "string" && r.length > 0)
307
+ return I("productId", r), r;
308
+ if (t.productId)
309
+ return I("productId", t.productId), t.productId;
310
+ throw new s(
399
311
  "validation_failed",
400
312
  "productId required (pass to options/input or set on createNeetruClient)"
401
313
  );
402
314
  }
403
- function createWebhooksNamespace(config) {
315
+ function fe(t) {
404
316
  return {
405
- async register(input) {
406
- validateInput(input);
407
- const productId = resolveProductId(config, input.productId);
408
- const raw = await httpRequest(config, {
317
+ async register(e) {
318
+ K(e);
319
+ let r = E(t, e.productId), n = await _(t, {
409
320
  method: "POST",
410
321
  path: "/api/sdk/v1/webhooks",
411
322
  body: {
412
- productId,
413
- url: input.url,
414
- events: input.events,
415
- ...input.secret ? { secret: input.secret } : {}
323
+ productId: r,
324
+ url: e.url,
325
+ events: e.events,
326
+ ...e.secret ? { secret: e.secret } : {}
416
327
  },
417
328
  requireAuth: true,
418
329
  // Sem isso, um retry de rede (app-level; SDK default é 0 retries em
@@ -421,91 +332,79 @@ function createWebhooksNamespace(config) {
421
332
  // dedup TTL 24h (mesmo padrão de usage.report/support.createTicket).
422
333
  idempotencyKey: true
423
334
  });
424
- return toEndpoint(raw);
335
+ return U(n);
425
336
  },
426
- async list(options) {
427
- const productId = resolveProductId(config, options?.productId);
428
- const raw = await httpRequest(config, {
337
+ async list(e) {
338
+ let r = E(t, e?.productId), n = await _(t, {
429
339
  method: "GET",
430
340
  path: "/api/sdk/v1/webhooks",
431
- query: { productId },
341
+ query: { productId: r },
432
342
  requireAuth: true
433
343
  });
434
- const list = Array.isArray(raw?.endpoints) ? raw.endpoints : [];
435
- return list.map(toEndpoint);
344
+ return (Array.isArray(n?.endpoints) ? n.endpoints : []).map(U);
436
345
  },
437
- async unregister(id, options) {
438
- if (!id) throw new NeetruError("validation_failed", "id obrigat\xF3rio");
439
- const productId = resolveProductId(config, options?.productId);
440
- await httpRequest(config, {
346
+ async unregister(e, r) {
347
+ if (!e) throw new s("validation_failed", "id obrigat\xF3rio");
348
+ let n = E(t, r?.productId);
349
+ return await _(t, {
441
350
  method: "DELETE",
442
- path: `/api/sdk/v1/webhooks/${encodeURIComponent(id)}`,
443
- query: { productId },
351
+ path: `/api/sdk/v1/webhooks/${encodeURIComponent(e)}`,
352
+ query: { productId: n },
444
353
  requireAuth: true
445
- });
446
- return { ok: true };
354
+ }), { ok: true };
447
355
  },
448
- async test(id, options) {
449
- if (!id) throw new NeetruError("validation_failed", "id obrigat\xF3rio");
450
- const productId = resolveProductId(config, options?.productId);
451
- const raw = await httpRequest(config, {
356
+ async test(e, r) {
357
+ if (!e) throw new s("validation_failed", "id obrigat\xF3rio");
358
+ let n = E(t, r?.productId), i = await _(t, {
452
359
  method: "POST",
453
- path: `/api/sdk/v1/webhooks/${encodeURIComponent(id)}/test`,
454
- query: { productId },
360
+ path: `/api/sdk/v1/webhooks/${encodeURIComponent(e)}/test`,
361
+ query: { productId: n },
455
362
  requireAuth: true,
456
363
  idempotencyKey: true
457
364
  });
458
- if (!raw || typeof raw !== "object") {
365
+ if (!i || typeof i != "object")
459
366
  return { ok: false, error: "invalid response" };
460
- }
461
- const r = raw;
367
+ let o = i;
462
368
  return {
463
- ok: r.ok === true,
464
- statusCode: typeof r.statusCode === "number" ? r.statusCode : void 0,
465
- durationMs: typeof r.durationMs === "number" ? r.durationMs : void 0,
466
- error: typeof r.error === "string" ? r.error : void 0
369
+ ok: o.ok === true,
370
+ statusCode: typeof o.statusCode == "number" ? o.statusCode : void 0,
371
+ durationMs: typeof o.durationMs == "number" ? o.durationMs : void 0,
372
+ error: typeof o.error == "string" ? o.error : void 0
467
373
  };
468
374
  }
469
375
  };
470
376
  }
471
- var MockWebhooks = class {
377
+ var P = class {
472
378
  endpoints = /* @__PURE__ */ new Map();
473
379
  nextId = 1;
474
- async register(input) {
475
- validateInput(input);
476
- const id = `mock_wh_${this.nextId++}`;
477
- const endpoint = {
478
- id,
479
- url: input.url,
480
- events: input.events,
481
- hasSecret: !!input.secret,
380
+ async register(e) {
381
+ K(e);
382
+ let r = `mock_wh_${this.nextId++}`, n = {
383
+ id: r,
384
+ url: e.url,
385
+ events: e.events,
386
+ hasSecret: !!e.secret,
482
387
  status: "active",
483
388
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
484
389
  };
485
- this.endpoints.set(id, endpoint);
486
- return endpoint;
390
+ return this.endpoints.set(r, n), n;
487
391
  }
488
- async list(_options) {
392
+ async list(e) {
489
393
  return [...this.endpoints.values()];
490
394
  }
491
- async unregister(id, _options) {
492
- if (!this.endpoints.has(id)) {
493
- throw new NeetruError("not_found", `Webhook ${id} n\xE3o encontrado`);
494
- }
495
- this.endpoints.delete(id);
496
- return { ok: true };
395
+ async unregister(e, r) {
396
+ if (!this.endpoints.has(e))
397
+ throw new s("not_found", `Webhook ${e} n\xE3o encontrado`);
398
+ return this.endpoints.delete(e), { ok: true };
497
399
  }
498
- async test(id, _options) {
499
- if (!this.endpoints.has(id)) {
500
- throw new NeetruError("not_found", `Webhook ${id} n\xE3o encontrado`);
501
- }
400
+ async test(e, r) {
401
+ if (!this.endpoints.has(e))
402
+ throw new s("not_found", `Webhook ${e} n\xE3o encontrado`);
502
403
  return { ok: true, statusCode: 200, durationMs: 42 };
503
404
  }
504
405
  };
505
406
 
506
- exports.MockWebhooks = MockWebhooks;
507
- exports.createWebhooksNamespace = createWebhooksNamespace;
508
- exports.verifyWebhookRequest = verifyWebhookRequest;
509
- exports.verifyWebhookSignature = verifyWebhookSignature;
510
- //# sourceMappingURL=webhooks.cjs.map
511
- //# sourceMappingURL=webhooks.cjs.map
407
+ exports.MockWebhooks = P;
408
+ exports.createWebhooksNamespace = fe;
409
+ exports.verifyWebhookRequest = pe;
410
+ exports.verifyWebhookSignature = Q;