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