@neetru/sdk 3.6.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +49 -0
- package/dist/ai.cjs +254 -391
- package/dist/ai.d.cts +1 -1
- package/dist/ai.d.ts +1 -1
- package/dist/ai.mjs +254 -391
- package/dist/auth.cjs +3547 -4998
- package/dist/auth.d.cts +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/auth.mjs +3544 -4995
- package/dist/build-guard.cjs +101 -119
- package/dist/build-guard.mjs +91 -109
- package/dist/catalog.cjs +152 -224
- package/dist/catalog.d.cts +1 -1
- package/dist/catalog.d.ts +1 -1
- package/dist/catalog.mjs +152 -224
- package/dist/checkout.cjs +237 -320
- package/dist/checkout.d.cts +1 -1
- package/dist/checkout.d.ts +1 -1
- package/dist/checkout.mjs +236 -319
- 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 +2055 -3013
- package/dist/db.d.cts +1 -1
- package/dist/db.d.ts +1 -1
- package/dist/db.mjs +2068 -3026
- package/dist/entitlements.cjs +12 -20
- package/dist/entitlements.d.cts +1 -1
- package/dist/entitlements.d.ts +1 -1
- package/dist/entitlements.mjs +12 -20
- package/dist/errors.cjs +9 -12
- package/dist/errors.d.cts +37 -2
- package/dist/errors.d.ts +37 -2
- package/dist/errors.mjs +8 -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 +3605 -5131
- package/dist/index.d.cts +6 -4
- package/dist/index.d.ts +6 -4
- package/dist/index.mjs +3710 -5236
- package/dist/mobile.cjs +238 -342
- package/dist/mobile.d.cts +1 -1
- package/dist/mobile.d.ts +1 -1
- package/dist/mobile.mjs +238 -342
- package/dist/mocks.cjs +312 -447
- package/dist/mocks.d.cts +1 -1
- package/dist/mocks.d.ts +1 -1
- package/dist/mocks.mjs +306 -441
- package/dist/notifications.cjs +226 -314
- package/dist/notifications.d.cts +1 -1
- package/dist/notifications.d.ts +1 -1
- package/dist/notifications.mjs +225 -313
- package/dist/react.cjs +522 -693
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.mjs +512 -683
- package/dist/support.cjs +329 -325
- package/dist/support.d.cts +25 -3
- package/dist/support.d.ts +25 -3
- package/dist/support.mjs +328 -325
- package/dist/telemetry.cjs +197 -301
- package/dist/telemetry.d.cts +1 -1
- package/dist/telemetry.d.ts +1 -1
- package/dist/telemetry.mjs +197 -301
- package/dist/{types-Du_iioJ7.d.cts → types-Bx4kTLmk.d.cts} +26 -0
- package/dist/{types-BPATkXYu.d.ts → types-Dx0IrOSF.d.ts} +26 -0
- package/dist/usage.cjs +163 -227
- package/dist/usage.d.cts +1 -1
- package/dist/usage.d.ts +1 -1
- package/dist/usage.mjs +163 -227
- package/dist/webhooks.cjs +258 -359
- package/dist/webhooks.d.cts +1 -1
- package/dist/webhooks.d.ts +1 -1
- package/dist/webhooks.mjs +255 -356
- package/package.json +4 -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/support.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/errors.ts
|
|
2
|
-
var
|
|
2
|
+
var o = class t extends Error {
|
|
3
3
|
code;
|
|
4
4
|
status;
|
|
5
5
|
requestId;
|
|
@@ -12,293 +12,321 @@ 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
|
-
constructor(
|
|
16
|
-
super(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
this.
|
|
21
|
-
this.reason = reason;
|
|
22
|
-
Object.setPrototypeOf(this, _NeetruError.prototype);
|
|
15
|
+
constructor(e, r, d, c, u) {
|
|
16
|
+
super(r), this.name = "NeetruError", this.code = e, this.status = d, this.requestId = c, this.reason = u, Object.setPrototypeOf(this, t.prototype);
|
|
17
|
+
}
|
|
18
|
+
}, _ = class t extends o {
|
|
19
|
+
constructor(e, r, d, c) {
|
|
20
|
+
super("auth_required", e, d, c, r), this.name = "NeetruAuthRequiredError", Object.setPrototypeOf(this, t.prototype);
|
|
23
21
|
}
|
|
24
22
|
};
|
|
25
23
|
|
|
26
24
|
// src/idempotency.ts
|
|
27
|
-
function
|
|
28
|
-
|
|
29
|
-
if (
|
|
30
|
-
return
|
|
31
|
-
|
|
32
|
-
throw new NeetruError(
|
|
25
|
+
function U() {
|
|
26
|
+
let t = typeof globalThis < "u" && "crypto" in globalThis ? globalThis.crypto : void 0;
|
|
27
|
+
if (t && typeof t.randomUUID == "function")
|
|
28
|
+
return t.randomUUID();
|
|
29
|
+
throw new o(
|
|
33
30
|
"runtime_unsupported",
|
|
34
31
|
"crypto.randomUUID not available in this runtime. SDK 3.0 requires Node \u226520 or modern browser/Edge."
|
|
35
32
|
);
|
|
36
33
|
}
|
|
37
34
|
|
|
38
35
|
// src/http.ts
|
|
39
|
-
var
|
|
36
|
+
var H = {
|
|
40
37
|
// SDK major 3.x requer Core ≥ 2026.05.1 (suporte a X-Neetru-Version header,
|
|
41
38
|
// runTransaction write-after-read, verifyWebhookRequest, webhooks 3.0+)
|
|
42
39
|
3: "2026.05.1"
|
|
43
40
|
};
|
|
44
|
-
function
|
|
45
|
-
return
|
|
41
|
+
function S(t) {
|
|
42
|
+
return t.split("+")[0] ?? t;
|
|
46
43
|
}
|
|
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;
|
|
44
|
+
function G(t, e) {
|
|
45
|
+
let r = S(t).split(".").map(Number), d = S(e).split(".").map(Number), c = Math.max(r.length, d.length);
|
|
46
|
+
for (let u = 0; u < c; u++) {
|
|
47
|
+
let l = r[u] ?? 0, n = d[u] ?? 0;
|
|
48
|
+
if (l !== n) return l - n;
|
|
55
49
|
}
|
|
56
50
|
return 0;
|
|
57
51
|
}
|
|
58
|
-
function
|
|
52
|
+
function M() {
|
|
59
53
|
try {
|
|
60
|
-
return "3.
|
|
54
|
+
return "3.7.0";
|
|
61
55
|
} catch {
|
|
62
|
-
return
|
|
56
|
+
return;
|
|
63
57
|
}
|
|
64
58
|
}
|
|
65
|
-
function
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
return 3;
|
|
59
|
+
function z() {
|
|
60
|
+
let t = M();
|
|
61
|
+
return t ? parseInt(t.split(".")[0] ?? "3", 10) : 3;
|
|
69
62
|
}
|
|
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
|
-
}
|
|
63
|
+
var N = /* @__PURE__ */ new Set();
|
|
64
|
+
function B(t) {
|
|
65
|
+
if (!t) return;
|
|
66
|
+
let e = z(), r = H[e];
|
|
67
|
+
if (!r) return;
|
|
68
|
+
let d = S(t);
|
|
69
|
+
if (G(d, r) < 0) {
|
|
70
|
+
let c = `${e}:${d}`;
|
|
71
|
+
N.has(c) || (N.add(c), console.warn(
|
|
72
|
+
`[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.`
|
|
73
|
+
));
|
|
85
74
|
}
|
|
86
75
|
}
|
|
87
|
-
var
|
|
88
|
-
var DEFAULT_RETRIES_WRITE = 0;
|
|
89
|
-
var READ_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD"]);
|
|
90
|
-
var RETRYABLE_CODES = /* @__PURE__ */ new Set([
|
|
76
|
+
var X = 2, Y = 0, J = /* @__PURE__ */ new Set(["GET", "HEAD"]), W = /* @__PURE__ */ new Set([
|
|
91
77
|
"rate_limited",
|
|
92
78
|
"server_error",
|
|
93
79
|
"network_error"
|
|
94
80
|
]);
|
|
95
|
-
function
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
return Math.max(50, Math.round(base + jitter));
|
|
81
|
+
function C(t) {
|
|
82
|
+
let e = 200 * Math.pow(4, t), r = e * 0.2 * (Math.random() * 2 - 1);
|
|
83
|
+
return Math.max(50, Math.round(e + r));
|
|
99
84
|
}
|
|
100
|
-
var
|
|
101
|
-
function
|
|
102
|
-
if (!
|
|
103
|
-
|
|
104
|
-
if (Number.isFinite(
|
|
105
|
-
|
|
106
|
-
if (Number.isFinite(
|
|
107
|
-
|
|
108
|
-
if (
|
|
85
|
+
var D = 6e4;
|
|
86
|
+
function Q(t) {
|
|
87
|
+
if (!t) return null;
|
|
88
|
+
let e = Number(t);
|
|
89
|
+
if (Number.isFinite(e) && e >= 0) return Math.min(Math.round(e * 1e3), D);
|
|
90
|
+
let r = Date.parse(t);
|
|
91
|
+
if (Number.isFinite(r)) {
|
|
92
|
+
let d = r - Date.now();
|
|
93
|
+
if (d > 0) return Math.min(d, D);
|
|
109
94
|
}
|
|
110
95
|
return null;
|
|
111
96
|
}
|
|
112
|
-
function
|
|
113
|
-
return new Promise((
|
|
97
|
+
function x(t) {
|
|
98
|
+
return new Promise((e) => setTimeout(e, t));
|
|
114
99
|
}
|
|
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";
|
|
100
|
+
function Z(t) {
|
|
101
|
+
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
102
|
}
|
|
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();
|
|
103
|
+
function ee(t, e, r) {
|
|
104
|
+
let d = t.replace(/\/+$/, ""), c = e.startsWith("/") ? e : `/${e}`, u = new URL(`${d}${c}`);
|
|
105
|
+
if (r)
|
|
106
|
+
for (let [l, n] of Object.entries(r))
|
|
107
|
+
n !== void 0 && u.searchParams.set(l, String(n));
|
|
108
|
+
return u.toString();
|
|
136
109
|
}
|
|
137
|
-
async function
|
|
138
|
-
|
|
139
|
-
if (
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
110
|
+
async function q(t) {
|
|
111
|
+
let e = await t.text();
|
|
112
|
+
if (e)
|
|
113
|
+
try {
|
|
114
|
+
return JSON.parse(e);
|
|
115
|
+
} catch {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
145
118
|
}
|
|
146
|
-
async function
|
|
147
|
-
|
|
148
|
-
const url = buildUrl(config.baseUrl, opts.path, opts.query);
|
|
149
|
-
const defaultRetries = READ_METHODS.has(method) ? DEFAULT_RETRIES_READ : DEFAULT_RETRIES_WRITE;
|
|
150
|
-
const maxRetries = opts.retries ?? defaultRetries;
|
|
151
|
-
const headers = {
|
|
119
|
+
async function b(t, e) {
|
|
120
|
+
let r = e.method ?? "GET", d = ee(t.baseUrl, e.path, e.query), c = J.has(r) ? X : Y, u = e.retries ?? c, l = {
|
|
152
121
|
accept: "application/json",
|
|
153
|
-
...
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
if (opts.requireAuth) {
|
|
160
|
-
if (!config.apiKey) {
|
|
161
|
-
throw new NeetruError(
|
|
122
|
+
...e.headers
|
|
123
|
+
}, n = M();
|
|
124
|
+
if (n && (l["x-neetru-sdk-version"] = n), e.requireAuth) {
|
|
125
|
+
if (!t.apiKey)
|
|
126
|
+
throw new o(
|
|
162
127
|
"missing_api_key",
|
|
163
128
|
"This operation requires an apiKey. Pass it to createNeetruClient({ apiKey }) or set NEETRU_API_KEY env var."
|
|
164
129
|
);
|
|
165
|
-
}
|
|
166
|
-
headers.authorization = `Bearer ${config.apiKey}`;
|
|
167
|
-
}
|
|
168
|
-
if (opts.idempotencyKey) {
|
|
169
|
-
const key = typeof opts.idempotencyKey === "string" ? opts.idempotencyKey : generateIdempotencyKey();
|
|
170
|
-
headers["idempotency-key"] = key;
|
|
130
|
+
l.authorization = `Bearer ${t.apiKey}`;
|
|
171
131
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
132
|
+
if (e.idempotencyKey) {
|
|
133
|
+
let p = typeof e.idempotencyKey == "string" ? e.idempotencyKey : U();
|
|
134
|
+
l["idempotency-key"] = p;
|
|
175
135
|
}
|
|
176
|
-
let
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
136
|
+
let f = e.body !== void 0 && r !== "GET" && r !== "DELETE" ? JSON.stringify(e.body) : void 0;
|
|
137
|
+
f !== void 0 && (l["content-type"] = "application/json");
|
|
138
|
+
let i = null, s = e.deadlineMs != null ? Date.now() + e.deadlineMs : null;
|
|
139
|
+
for (let p = 0; p <= u; p++) {
|
|
140
|
+
if (s != null && Date.now() >= s)
|
|
141
|
+
throw i ?? new o("network_error", "Deadline excedido antes de completar a request");
|
|
142
|
+
let g = { method: r, headers: l };
|
|
143
|
+
f !== void 0 && (g.body = f);
|
|
144
|
+
let F = s != null ? Math.max(1, Math.min(3e4, s - Date.now())) : 3e4;
|
|
145
|
+
g.signal = AbortSignal.timeout(F);
|
|
146
|
+
let m;
|
|
182
147
|
try {
|
|
183
|
-
|
|
184
|
-
} catch (
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
148
|
+
m = await t.fetch(d, g);
|
|
149
|
+
} catch (a) {
|
|
150
|
+
let w = a instanceof DOMException && a.name === "TimeoutError" ? "Network error: timeout after 30s" : `Network error: ${a instanceof Error ? a.message : "fetch failed"}`;
|
|
151
|
+
if (i = new o("network_error", w), p < u) {
|
|
152
|
+
let R = C(p);
|
|
153
|
+
if (s == null || Date.now() + R < s) {
|
|
154
|
+
await x(R);
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
190
157
|
}
|
|
191
|
-
throw
|
|
158
|
+
throw i;
|
|
192
159
|
}
|
|
193
|
-
|
|
194
|
-
if (
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
const parsed = await safeJson(res);
|
|
198
|
-
return parsed;
|
|
160
|
+
let V = m.headers.get("x-request-id") ?? m.headers.get("x-correlation-id") ?? void 0;
|
|
161
|
+
if (m.ok) {
|
|
162
|
+
let a = m.headers.get("x-neetru-version");
|
|
163
|
+
return a && B(a), await q(m);
|
|
199
164
|
}
|
|
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;
|
|
165
|
+
let y = await q(m), k = Z(m.status), h = `HTTP ${m.status}`, v;
|
|
166
|
+
if (y && typeof y == "object") {
|
|
167
|
+
let a = y.error;
|
|
168
|
+
typeof a == "string" ? h = a : a && typeof a == "object" ? (typeof a.code == "string" && (k = a.code), typeof a.message == "string" && (h = a.message), typeof a.reason == "string" && (v = a.reason)) : (typeof y.code == "string" && (k = y.code), typeof y.message == "string" && (h = y.message)), typeof y.reason == "string" && (v = y.reason);
|
|
217
169
|
}
|
|
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;
|
|
170
|
+
if (m.status === 410) {
|
|
171
|
+
let a = m.headers.get("x-neetru-replacement");
|
|
172
|
+
h === `HTTP ${m.status}` && (h = `Endpoint ${e.path} foi removido do Core (HTTP 410 Gone) \u2014 atualize o @neetru/sdk e migre para a API substituta.`), a && !h.includes(a) && (h += ` Substituto: ${a}.`);
|
|
226
173
|
}
|
|
227
|
-
|
|
174
|
+
let I = new o(k, h, m.status, V, v);
|
|
175
|
+
if (i = I, W.has(k) && p < u) {
|
|
176
|
+
let w = Q(m.headers.get("retry-after")) ?? C(p);
|
|
177
|
+
if (s == null || Date.now() + w < s) {
|
|
178
|
+
await x(w);
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
throw I;
|
|
228
183
|
}
|
|
229
|
-
throw
|
|
184
|
+
throw i ?? new o("unknown", "unexpected httpRequest exit");
|
|
230
185
|
}
|
|
231
186
|
|
|
232
187
|
// src/validators.ts
|
|
233
|
-
var
|
|
234
|
-
function
|
|
235
|
-
if (typeof
|
|
236
|
-
throw new
|
|
188
|
+
var O = /^[a-z0-9][a-z0-9_-]{0,62}$/i;
|
|
189
|
+
function A(t, e) {
|
|
190
|
+
if (typeof e != "string" || !O.test(e))
|
|
191
|
+
throw new o(
|
|
237
192
|
"validation_failed",
|
|
238
|
-
`${
|
|
193
|
+
`${t} must match ${O.source} (lowercase alphanumeric, _, -; first char must be alphanumeric; max 63 chars)`
|
|
239
194
|
);
|
|
240
|
-
}
|
|
241
195
|
}
|
|
242
196
|
|
|
243
197
|
// src/support.ts
|
|
244
|
-
var
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
throw new NeetruError("invalid_response", "Ticket missing id");
|
|
253
|
-
}
|
|
254
|
-
const firstAttachment = Array.isArray(r.attachments) && typeof r.attachments[0] === "string" ? r.attachments[0] : void 0;
|
|
198
|
+
var T = ["low", "normal", "high", "urgent"], te = ["open", "pending", "resolved", "closed"], j = 50;
|
|
199
|
+
function P(t) {
|
|
200
|
+
if (!t || typeof t != "object")
|
|
201
|
+
throw new o("invalid_response", "Ticket response is not an object");
|
|
202
|
+
let e = t;
|
|
203
|
+
if (typeof e.id != "string")
|
|
204
|
+
throw new o("invalid_response", "Ticket missing id");
|
|
205
|
+
let r = Array.isArray(e.attachments) && typeof e.attachments[0] == "string" ? e.attachments[0] : void 0, d = typeof e.screenshotUrl == "string" ? e.screenshotUrl : r ?? null;
|
|
255
206
|
return {
|
|
256
|
-
id:
|
|
257
|
-
subject: typeof
|
|
258
|
-
message: typeof
|
|
259
|
-
severity:
|
|
260
|
-
status:
|
|
261
|
-
createdAt: typeof
|
|
262
|
-
updatedAt: typeof
|
|
263
|
-
productSlug: typeof
|
|
264
|
-
pageUrl: typeof
|
|
265
|
-
screenshotUrl:
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
207
|
+
id: e.id,
|
|
208
|
+
subject: typeof e.subject == "string" ? e.subject : "",
|
|
209
|
+
message: typeof e.message == "string" ? e.message : "",
|
|
210
|
+
severity: T.includes(e.severity) ? e.severity : "normal",
|
|
211
|
+
status: te.includes(e.status) ? e.status : "open",
|
|
212
|
+
createdAt: typeof e.createdAt == "string" ? e.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
|
|
213
|
+
updatedAt: typeof e.updatedAt == "string" ? e.updatedAt : void 0,
|
|
214
|
+
productSlug: typeof e.productId == "string" ? e.productId : typeof e.productSlug == "string" ? e.productSlug : void 0,
|
|
215
|
+
pageUrl: typeof e.pageUrl == "string" ? e.pageUrl : null,
|
|
216
|
+
screenshotUrl: d,
|
|
217
|
+
// 3.7.0: a listagem do Core não traz mais `attachments` (screenshotUrl vem
|
|
218
|
+
// null) — `screenshotAttached` diz se o ticket tem print. Fallback: há URL.
|
|
219
|
+
screenshotAttached: typeof e.screenshotAttached == "boolean" ? e.screenshotAttached : d !== null,
|
|
220
|
+
resolvedAt: typeof e.resolvedAt == "string" ? e.resolvedAt : null,
|
|
221
|
+
resolvedNotifiedAt: typeof e.resolvedNotifiedAt == "string" ? e.resolvedNotifiedAt : null,
|
|
222
|
+
satisfactionAttempts: typeof e.satisfactionAttempts == "number" && Number.isFinite(e.satisfactionAttempts) ? e.satisfactionAttempts : 0,
|
|
223
|
+
lastSatisfactionAttemptAt: typeof e.lastSatisfactionAttemptAt == "string" ? e.lastSatisfactionAttemptAt : null,
|
|
224
|
+
satisfiedAt: typeof e.satisfiedAt == "string" ? e.satisfiedAt : null,
|
|
225
|
+
rating: typeof e.rating == "number" && Number.isFinite(e.rating) ? e.rating : null,
|
|
226
|
+
satisfactionComment: typeof e.satisfactionComment == "string" ? e.satisfactionComment : null
|
|
273
227
|
};
|
|
274
228
|
}
|
|
275
|
-
function
|
|
276
|
-
if (!
|
|
277
|
-
throw new
|
|
278
|
-
}
|
|
229
|
+
function E(t) {
|
|
230
|
+
if (!t || typeof t != "string")
|
|
231
|
+
throw new o("validation_failed", "ticketId is required");
|
|
279
232
|
}
|
|
280
|
-
function
|
|
281
|
-
if (typeof
|
|
282
|
-
throw new
|
|
283
|
-
}
|
|
233
|
+
function $(t) {
|
|
234
|
+
if (typeof t == "string" && t.length > 2e3)
|
|
235
|
+
throw new o("validation_failed", "comment max 2000 chars");
|
|
284
236
|
}
|
|
285
|
-
function
|
|
286
|
-
for (
|
|
287
|
-
if (typeof
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
if (config.productId) {
|
|
293
|
-
assertValidSdkId("productId", config.productId);
|
|
294
|
-
return config.productId;
|
|
295
|
-
}
|
|
296
|
-
throw new NeetruError(
|
|
237
|
+
function K(t, ...e) {
|
|
238
|
+
for (let r of e)
|
|
239
|
+
if (typeof r == "string" && r.length > 0)
|
|
240
|
+
return A("productSlug", r), r;
|
|
241
|
+
if (t.productId)
|
|
242
|
+
return A("productId", t.productId), t.productId;
|
|
243
|
+
throw new o(
|
|
297
244
|
"validation_failed",
|
|
298
245
|
"productId required (pass to input.productSlug or set on createNeetruClient)"
|
|
299
246
|
);
|
|
300
247
|
}
|
|
301
|
-
|
|
248
|
+
var ne = "X-Neetru-End-User-Token", re = "Esta opera\xE7\xE3o de suporte exige um usu\xE1rio final logado: o Core s\xF3 mostra/altera os tickets do pr\xF3prio usu\xE1rio (header X-Neetru-End-User-Token com o id_token OIDC). Fa\xE7a login com client.auth.signIn() e tente de novo.", oe = "O Core exige a identidade do usu\xE1rio final para esta opera\xE7\xE3o (403 end_user_token_required) e nenhum id_token foi aceito. Fa\xE7a login com client.auth.signIn() e tente de novo.", ie = "O Core recusou o token do usu\xE1rio final (401 invalid_end_user_token \u2014 sess\xE3o expirada, usu\xE1rio inativo ou token que n\xE3o \xE9 id_token) e a renova\xE7\xE3o autom\xE1tica n\xE3o resolveu. Fa\xE7a login novamente com client.auth.signIn() e tente de novo.", se = "O id_token do usu\xE1rio final foi emitido para o client OIDC de OUTRO produto (403 end_user_token_product_mismatch). Confira se o login (client.auth / clientId OIDC) e a apiKey/productId do createNeetruClient s\xE3o do MESMO produto.";
|
|
249
|
+
function L(t) {
|
|
250
|
+
if (t instanceof o && !(t instanceof _)) {
|
|
251
|
+
if (t.code === "end_user_token_required")
|
|
252
|
+
throw new _(
|
|
253
|
+
oe,
|
|
254
|
+
"end_user_token_required",
|
|
255
|
+
t.status,
|
|
256
|
+
t.requestId
|
|
257
|
+
);
|
|
258
|
+
if (t.code === "invalid_end_user_token")
|
|
259
|
+
throw new _(
|
|
260
|
+
ie,
|
|
261
|
+
"invalid_end_user_token",
|
|
262
|
+
t.status,
|
|
263
|
+
t.requestId
|
|
264
|
+
);
|
|
265
|
+
if (t.code === "end_user_token_product_mismatch")
|
|
266
|
+
throw new o(
|
|
267
|
+
"forbidden",
|
|
268
|
+
se,
|
|
269
|
+
t.status,
|
|
270
|
+
t.requestId,
|
|
271
|
+
"end_user_token_product_mismatch"
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
throw t;
|
|
275
|
+
}
|
|
276
|
+
function ae(t) {
|
|
277
|
+
return t instanceof o && t.code === "invalid_end_user_token";
|
|
278
|
+
}
|
|
279
|
+
function ke(t, e = {}) {
|
|
280
|
+
function r() {
|
|
281
|
+
try {
|
|
282
|
+
let n = e.getEndUserToken?.();
|
|
283
|
+
return typeof n == "string" && n.length > 0 ? n : null;
|
|
284
|
+
} catch {
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
async function d() {
|
|
289
|
+
if (!e.refreshEndUserToken) return false;
|
|
290
|
+
try {
|
|
291
|
+
return await e.refreshEndUserToken() === !0;
|
|
292
|
+
} catch {
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
function c(n) {
|
|
297
|
+
return n ? { [ne]: n } : {};
|
|
298
|
+
}
|
|
299
|
+
async function u(n, f) {
|
|
300
|
+
let i = r();
|
|
301
|
+
if (!i && n && await d() && (i = r()), !i && n)
|
|
302
|
+
throw new _(re, "no_signed_in_user");
|
|
303
|
+
try {
|
|
304
|
+
return await f(c(i));
|
|
305
|
+
} catch (s) {
|
|
306
|
+
if (i && ae(s) && await d()) {
|
|
307
|
+
let p = r();
|
|
308
|
+
if (p)
|
|
309
|
+
try {
|
|
310
|
+
return await f(c(p));
|
|
311
|
+
} catch (g) {
|
|
312
|
+
L(g);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
L(s);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
async function l(n, f = {}) {
|
|
319
|
+
await u(
|
|
320
|
+
true,
|
|
321
|
+
(i) => b(t, {
|
|
322
|
+
method: "POST",
|
|
323
|
+
path: n,
|
|
324
|
+
requireAuth: !0,
|
|
325
|
+
headers: i,
|
|
326
|
+
...f
|
|
327
|
+
})
|
|
328
|
+
);
|
|
329
|
+
}
|
|
302
330
|
return {
|
|
303
331
|
/**
|
|
304
332
|
* Cria um ticket de suporte. Requer Bearer auth. `productSlug` no input
|
|
@@ -306,85 +334,75 @@ function createSupportNamespace(config) {
|
|
|
306
334
|
*
|
|
307
335
|
* Endpoint canonical: `POST /api/sdk/v1/support/tickets`.
|
|
308
336
|
*/
|
|
309
|
-
async createTicket(
|
|
310
|
-
if (!
|
|
311
|
-
throw new
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
if (
|
|
317
|
-
throw new
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
if (input.message.length > 1e4) {
|
|
323
|
-
throw new NeetruError("validation_failed", "message max 10000 chars");
|
|
324
|
-
}
|
|
325
|
-
if (input.severity && !VALID_SEVERITIES.includes(input.severity)) {
|
|
326
|
-
throw new NeetruError(
|
|
337
|
+
async createTicket(n) {
|
|
338
|
+
if (!n || typeof n != "object")
|
|
339
|
+
throw new o("validation_failed", "input is required");
|
|
340
|
+
if (!n.subject || typeof n.subject != "string")
|
|
341
|
+
throw new o("validation_failed", "subject is required");
|
|
342
|
+
if (n.subject.length > 200)
|
|
343
|
+
throw new o("validation_failed", "subject max 200 chars");
|
|
344
|
+
if (!n.message || typeof n.message != "string")
|
|
345
|
+
throw new o("validation_failed", "message is required");
|
|
346
|
+
if (n.message.length > 1e4)
|
|
347
|
+
throw new o("validation_failed", "message max 10000 chars");
|
|
348
|
+
if (n.severity && !T.includes(n.severity))
|
|
349
|
+
throw new o(
|
|
327
350
|
"validation_failed",
|
|
328
|
-
`severity must be one of ${
|
|
351
|
+
`severity must be one of ${T.join(", ")}`
|
|
329
352
|
);
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
message: input.message,
|
|
336
|
-
severity: input.severity ?? "normal"
|
|
353
|
+
let i = {
|
|
354
|
+
productId: K(t, n.productSlug),
|
|
355
|
+
subject: n.subject,
|
|
356
|
+
message: n.message,
|
|
357
|
+
severity: n.severity ?? "normal"
|
|
337
358
|
};
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
method: "POST",
|
|
352
|
-
path: "/api/sdk/v1/support/tickets",
|
|
353
|
-
body,
|
|
354
|
-
requireAuth: true,
|
|
355
|
-
idempotencyKey: true
|
|
356
|
-
});
|
|
357
|
-
const candidate = raw && typeof raw === "object" && "ticket" in raw ? raw.ticket : raw;
|
|
358
|
-
return toTicket(candidate);
|
|
359
|
+
n.metadata && typeof n.metadata == "object" && (i.metadata = n.metadata), typeof n.pageUrl == "string" && (i.pageUrl = n.pageUrl), typeof n.screenshotBase64 == "string" && (i.screenshotBase64 = n.screenshotBase64), typeof n.consoleLogs == "string" && (i.consoleLogs = n.consoleLogs);
|
|
360
|
+
let s = await u(
|
|
361
|
+
false,
|
|
362
|
+
(g) => b(t, {
|
|
363
|
+
method: "POST",
|
|
364
|
+
path: "/api/sdk/v1/support/tickets",
|
|
365
|
+
body: i,
|
|
366
|
+
requireAuth: !0,
|
|
367
|
+
idempotencyKey: !0,
|
|
368
|
+
headers: g
|
|
369
|
+
})
|
|
370
|
+
), p = s && typeof s == "object" && "ticket" in s ? s.ticket : s;
|
|
371
|
+
return P(p);
|
|
359
372
|
},
|
|
360
373
|
/**
|
|
361
374
|
* Lista tickets do customer no produto atual. `productSlug` no contexto.
|
|
362
375
|
*
|
|
363
376
|
* Endpoint canonical: `GET /api/sdk/v1/support/tickets?productId=...`.
|
|
364
377
|
*/
|
|
365
|
-
async listMyTickets(
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
378
|
+
async listMyTickets(n) {
|
|
379
|
+
let f = K(t, n?.productSlug), i = n?.limit;
|
|
380
|
+
if (i !== void 0 && (!Number.isInteger(i) || i < 1 || i > j))
|
|
381
|
+
throw new o(
|
|
382
|
+
"validation_failed",
|
|
383
|
+
`limit must be an integer 1-${j} (Core default 20)`
|
|
384
|
+
);
|
|
385
|
+
let s = await u(
|
|
386
|
+
true,
|
|
387
|
+
(g) => b(t, {
|
|
388
|
+
method: "GET",
|
|
389
|
+
path: "/api/sdk/v1/support/tickets",
|
|
390
|
+
query: { productId: f, limit: i },
|
|
391
|
+
requireAuth: !0,
|
|
392
|
+
headers: g
|
|
393
|
+
})
|
|
394
|
+
);
|
|
395
|
+
return (Array.isArray(s) ? s : s && typeof s == "object" && "tickets" in s ? s.tickets ?? [] : []).map(P);
|
|
375
396
|
},
|
|
376
397
|
/**
|
|
377
398
|
* 3.4: marca a notificação de resolução como vista (`resolvedNotifiedAt`,
|
|
378
399
|
* idempotente no Core). Endpoint canonical:
|
|
379
400
|
* `POST /api/sdk/v1/support/tickets/{id}/resolved-seen`.
|
|
380
401
|
*/
|
|
381
|
-
async markResolvedSeen(
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
path: `/api/sdk/v1/support/tickets/${encodeURIComponent(ticketId)}/resolved-seen`,
|
|
386
|
-
requireAuth: true
|
|
387
|
-
});
|
|
402
|
+
async markResolvedSeen(n) {
|
|
403
|
+
E(n), await l(
|
|
404
|
+
`/api/sdk/v1/support/tickets/${encodeURIComponent(n)}/resolved-seen`
|
|
405
|
+
);
|
|
388
406
|
},
|
|
389
407
|
/**
|
|
390
408
|
* 3.4: registra uma tentativa de exibição do modal de satisfação
|
|
@@ -392,61 +410,46 @@ function createSupportNamespace(config) {
|
|
|
392
410
|
* resposta. Endpoint canonical:
|
|
393
411
|
* `POST /api/sdk/v1/support/tickets/{id}/satisfaction-attempt`.
|
|
394
412
|
*/
|
|
395
|
-
async recordSatisfactionAttempt(
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
method: "POST",
|
|
399
|
-
path: `/api/sdk/v1/support/tickets/${encodeURIComponent(ticketId)}/satisfaction-attempt`,
|
|
400
|
-
requireAuth: true,
|
|
413
|
+
async recordSatisfactionAttempt(n) {
|
|
414
|
+
E(n), await l(
|
|
415
|
+
`/api/sdk/v1/support/tickets/${encodeURIComponent(n)}/satisfaction-attempt`,
|
|
401
416
|
// Incrementa satisfactionAttempts += 1 no Core — sem idempotencyKey,
|
|
402
417
|
// um retry de rede infla o contador (mesmo padrão de createTicket acima).
|
|
403
|
-
idempotencyKey: true
|
|
404
|
-
|
|
418
|
+
{ idempotencyKey: true }
|
|
419
|
+
);
|
|
405
420
|
},
|
|
406
421
|
/**
|
|
407
422
|
* 3.4: envia (ou pula) a avaliação de satisfação (CSAT 1-5). Endpoint
|
|
408
423
|
* canonical: `POST /api/sdk/v1/support/tickets/{id}/satisfaction`.
|
|
409
424
|
*/
|
|
410
|
-
async submitSatisfaction(
|
|
411
|
-
if (!
|
|
412
|
-
throw new
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
425
|
+
async submitSatisfaction(n) {
|
|
426
|
+
if (!n || typeof n != "object")
|
|
427
|
+
throw new o("validation_failed", "input is required");
|
|
428
|
+
if (E(n.ticketId), n.rating !== null && n.rating !== void 0 && (!Number.isInteger(n.rating) || n.rating < 1 || n.rating > 5))
|
|
429
|
+
throw new o("validation_failed", "rating must be an integer 1-5 or null");
|
|
430
|
+
$(n.comment), await l(
|
|
431
|
+
`/api/sdk/v1/support/tickets/${encodeURIComponent(n.ticketId)}/satisfaction`,
|
|
432
|
+
{
|
|
433
|
+
body: {
|
|
434
|
+
rating: n.rating ?? null,
|
|
435
|
+
comment: n.comment ?? null,
|
|
436
|
+
skipped: n.skipped
|
|
437
|
+
}
|
|
418
438
|
}
|
|
419
|
-
|
|
420
|
-
assertValidComment(input.comment);
|
|
421
|
-
await httpRequest(config, {
|
|
422
|
-
method: "POST",
|
|
423
|
-
path: `/api/sdk/v1/support/tickets/${encodeURIComponent(input.ticketId)}/satisfaction`,
|
|
424
|
-
body: {
|
|
425
|
-
rating: input.rating ?? null,
|
|
426
|
-
comment: input.comment ?? null,
|
|
427
|
-
skipped: input.skipped
|
|
428
|
-
},
|
|
429
|
-
requireAuth: true
|
|
430
|
-
});
|
|
439
|
+
);
|
|
431
440
|
},
|
|
432
441
|
/**
|
|
433
442
|
* 3.4: contesta um ticket resolvido — reabre e zera o ciclo de
|
|
434
443
|
* satisfação/notificação. Endpoint canonical:
|
|
435
444
|
* `POST /api/sdk/v1/support/tickets/{id}/contest`.
|
|
436
445
|
*/
|
|
437
|
-
async contestTicket(
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
path: `/api/sdk/v1/support/tickets/${encodeURIComponent(ticketId)}/contest`,
|
|
443
|
-
body: { comment: opts?.comment ?? void 0 },
|
|
444
|
-
requireAuth: true
|
|
445
|
-
});
|
|
446
|
+
async contestTicket(n, f) {
|
|
447
|
+
E(n), $(f?.comment), await l(
|
|
448
|
+
`/api/sdk/v1/support/tickets/${encodeURIComponent(n)}/contest`,
|
|
449
|
+
{ body: { comment: f?.comment ?? void 0 } }
|
|
450
|
+
);
|
|
446
451
|
}
|
|
447
452
|
};
|
|
448
453
|
}
|
|
449
454
|
|
|
450
|
-
export { createSupportNamespace };
|
|
451
|
-
//# sourceMappingURL=support.mjs.map
|
|
452
|
-
//# sourceMappingURL=support.mjs.map
|
|
455
|
+
export { ne as END_USER_TOKEN_HEADER, ke as createSupportNamespace };
|