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