@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.
- package/CHANGELOG.md +75 -0
- package/README.md +66 -1
- package/dist/ai.cjs +221 -177
- package/dist/ai.d.cts +1 -1
- package/dist/ai.d.ts +1 -1
- package/dist/ai.mjs +221 -177
- package/dist/auth.cjs +1051 -868
- package/dist/auth.d.cts +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/auth.mjs +1048 -865
- package/dist/catalog.cjs +164 -97
- package/dist/catalog.d.cts +1 -1
- package/dist/catalog.d.ts +1 -1
- package/dist/catalog.mjs +164 -97
- package/dist/checkout.cjs +182 -115
- package/dist/checkout.d.cts +1 -1
- package/dist/checkout.d.ts +1 -1
- package/dist/checkout.mjs +181 -114
- package/dist/db-react.d.cts +1 -1
- package/dist/db-react.d.ts +1 -1
- package/dist/db.cjs +437 -345
- package/dist/db.d.cts +1 -1
- package/dist/db.d.ts +1 -1
- package/dist/db.mjs +455 -363
- package/dist/entitlements.cjs +17 -10
- package/dist/entitlements.d.cts +1 -1
- package/dist/entitlements.d.ts +1 -1
- package/dist/entitlements.mjs +17 -10
- package/dist/errors.cjs +15 -8
- package/dist/errors.d.cts +24 -3
- package/dist/errors.d.ts +24 -3
- package/dist/errors.mjs +14 -7
- package/dist/firestore-compat.d.cts +1 -1
- package/dist/firestore-compat.d.ts +1 -1
- package/dist/index.cjs +1544 -1190
- package/dist/index.d.cts +177 -3
- package/dist/index.d.ts +177 -3
- package/dist/index.mjs +1676 -1329
- package/dist/mobile.cjs +400 -181
- package/dist/mobile.d.cts +59 -4
- package/dist/mobile.d.ts +59 -4
- package/dist/mobile.mjs +400 -181
- package/dist/mocks.cjs +9 -2
- package/dist/mocks.d.cts +1 -1
- package/dist/mocks.d.ts +1 -1
- package/dist/mocks.mjs +9 -2
- package/dist/notifications.cjs +197 -130
- package/dist/notifications.d.cts +1 -1
- package/dist/notifications.d.ts +1 -1
- package/dist/notifications.mjs +196 -129
- package/dist/react.cjs +303 -282
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.mjs +295 -274
- package/dist/support.cjs +299 -229
- package/dist/support.d.cts +8 -4
- package/dist/support.d.ts +8 -4
- package/dist/support.mjs +298 -228
- package/dist/telemetry.cjs +234 -167
- package/dist/telemetry.d.cts +1 -1
- package/dist/telemetry.d.ts +1 -1
- package/dist/telemetry.mjs +234 -167
- package/dist/{types-Dx0IrOSF.d.ts → types-BYPk_3HR.d.ts} +104 -17
- package/dist/{types-Bx4kTLmk.d.cts → types-yv3EDKg2.d.cts} +104 -17
- package/dist/usage.cjs +183 -116
- package/dist/usage.d.cts +1 -1
- package/dist/usage.d.ts +1 -1
- package/dist/usage.mjs +183 -116
- package/dist/webhooks.cjs +215 -148
- package/dist/webhooks.d.cts +1 -1
- package/dist/webhooks.d.ts +1 -1
- package/dist/webhooks.mjs +212 -145
- 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
|
-
|
|
16
|
-
|
|
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
|
|
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
|
|
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
|
|
41
|
-
let r = A(t).split(".").map(Number), n = A(e).split(".").map(Number),
|
|
42
|
-
for (let
|
|
43
|
-
let
|
|
44
|
-
if (
|
|
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
|
|
107
|
+
function $() {
|
|
49
108
|
try {
|
|
50
|
-
return "3.
|
|
109
|
+
return "3.8.1";
|
|
51
110
|
} catch {
|
|
52
111
|
return;
|
|
53
112
|
}
|
|
54
113
|
}
|
|
55
|
-
function
|
|
56
|
-
let t =
|
|
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
|
|
119
|
+
function J(t) {
|
|
61
120
|
if (!t) return;
|
|
62
|
-
let e =
|
|
121
|
+
let e = Y(), r = G[e];
|
|
63
122
|
if (!r) return;
|
|
64
123
|
let n = A(t);
|
|
65
|
-
if (
|
|
66
|
-
let
|
|
67
|
-
W.has(
|
|
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
|
-
|
|
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
|
|
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
|
|
82
|
-
function
|
|
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),
|
|
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,
|
|
152
|
+
if (n > 0) return Math.min(n, q);
|
|
90
153
|
}
|
|
91
154
|
return null;
|
|
92
155
|
}
|
|
93
|
-
function
|
|
156
|
+
function P(t) {
|
|
94
157
|
return new Promise((e) => setTimeout(e, t));
|
|
95
158
|
}
|
|
96
|
-
function
|
|
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
|
|
100
|
-
let n = t.replace(/\/+$/, ""),
|
|
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 [
|
|
103
|
-
c !== void 0 &&
|
|
104
|
-
return
|
|
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
|
|
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
|
|
116
|
-
let r = e.method ?? "GET", n =
|
|
117
|
-
accept: "application/json",
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if (
|
|
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
|
-
|
|
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 :
|
|
130
|
-
|
|
189
|
+
let l = typeof e.idempotencyKey == "string" ? e.idempotencyKey : N();
|
|
190
|
+
a["idempotency-key"] = l;
|
|
131
191
|
}
|
|
132
|
-
let
|
|
133
|
-
|
|
134
|
-
let
|
|
135
|
-
for (let l = 0; l <=
|
|
136
|
-
if (
|
|
137
|
-
throw
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
-
|
|
145
|
-
} catch (
|
|
146
|
-
let
|
|
147
|
-
if (
|
|
148
|
-
let
|
|
149
|
-
if (
|
|
150
|
-
await
|
|
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
|
|
221
|
+
throw g;
|
|
155
222
|
}
|
|
156
|
-
let
|
|
157
|
-
if (
|
|
158
|
-
let
|
|
159
|
-
return
|
|
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
|
|
162
|
-
if (
|
|
163
|
-
let
|
|
164
|
-
typeof
|
|
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 (
|
|
167
|
-
let
|
|
168
|
-
|
|
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
|
|
171
|
-
if (
|
|
172
|
-
let
|
|
173
|
-
if (
|
|
174
|
-
await
|
|
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
|
|
245
|
+
throw x;
|
|
179
246
|
}
|
|
180
|
-
throw
|
|
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
|
|
185
|
-
function
|
|
186
|
-
if (typeof e != "string" || !
|
|
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 ${
|
|
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
|
|
261
|
+
async function se(t, e, r, n) {
|
|
195
262
|
if (!e || !r) return false;
|
|
196
|
-
let
|
|
197
|
-
if (!/^[0-9a-f]+$/i.test(
|
|
198
|
-
let
|
|
199
|
-
if (!
|
|
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
|
|
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
|
|
207
|
-
|
|
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
|
|
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
|
-
),
|
|
282
|
+
), p = await i.sign(
|
|
216
283
|
"HMAC",
|
|
217
|
-
|
|
284
|
+
g,
|
|
218
285
|
h
|
|
219
|
-
),
|
|
220
|
-
if (!
|
|
221
|
-
let
|
|
222
|
-
for (let
|
|
223
|
-
|
|
224
|
-
return
|
|
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
|
|
227
|
-
let
|
|
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(
|
|
230
|
-
let
|
|
231
|
-
for (let
|
|
232
|
-
if (
|
|
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
|
-
},
|
|
235
|
-
if (!
|
|
301
|
+
}, a = i("x-neetru-timestamp");
|
|
302
|
+
if (!a)
|
|
236
303
|
return { ok: false, reason: "timestamp_missing" };
|
|
237
|
-
let c = Number(
|
|
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) >
|
|
307
|
+
if (Math.abs(Date.now() - c) > o)
|
|
241
308
|
return { ok: false, reason: "timestamp_expired" };
|
|
242
|
-
let h =
|
|
243
|
-
return await
|
|
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
|
|
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),
|
|
250
|
-
if (Number.isNaN(n) || Number.isNaN(
|
|
251
|
-
e[r] = n << 4 |
|
|
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
|
|
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) =>
|
|
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
|
|
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 (
|
|
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
|
|
369
|
+
function R(t, ...e) {
|
|
303
370
|
for (let r of e)
|
|
304
371
|
if (typeof r == "string" && r.length > 0)
|
|
305
|
-
return
|
|
372
|
+
return S("productId", r), r;
|
|
306
373
|
if (t.productId)
|
|
307
|
-
return
|
|
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
|
|
380
|
+
function Ie(t) {
|
|
314
381
|
return {
|
|
315
382
|
async register(e) {
|
|
316
|
-
|
|
317
|
-
let r =
|
|
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
|
|
400
|
+
return H(n);
|
|
334
401
|
},
|
|
335
402
|
async list(e) {
|
|
336
|
-
let r =
|
|
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(
|
|
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 =
|
|
347
|
-
return await
|
|
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 =
|
|
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 (!
|
|
430
|
+
if (!o || typeof o != "object")
|
|
364
431
|
return { ok: false, error: "invalid response" };
|
|
365
|
-
let
|
|
432
|
+
let i = o;
|
|
366
433
|
return {
|
|
367
|
-
ok:
|
|
368
|
-
statusCode: typeof
|
|
369
|
-
durationMs: typeof
|
|
370
|
-
error: typeof
|
|
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
|
|
442
|
+
var j = class {
|
|
376
443
|
endpoints = /* @__PURE__ */ new Map();
|
|
377
444
|
nextId = 1;
|
|
378
445
|
async register(e) {
|
|
379
|
-
|
|
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 {
|
|
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.
|
|
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": [
|