@neetru/sdk 3.6.0 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/dist/ai.cjs +254 -391
  3. package/dist/ai.d.cts +1 -1
  4. package/dist/ai.d.ts +1 -1
  5. package/dist/ai.mjs +254 -391
  6. package/dist/auth.cjs +3547 -4998
  7. package/dist/auth.d.cts +1 -1
  8. package/dist/auth.d.ts +1 -1
  9. package/dist/auth.mjs +3544 -4995
  10. package/dist/build-guard.cjs +101 -119
  11. package/dist/build-guard.mjs +91 -109
  12. package/dist/catalog.cjs +152 -224
  13. package/dist/catalog.d.cts +1 -1
  14. package/dist/catalog.d.ts +1 -1
  15. package/dist/catalog.mjs +152 -224
  16. package/dist/checkout.cjs +237 -320
  17. package/dist/checkout.d.cts +1 -1
  18. package/dist/checkout.d.ts +1 -1
  19. package/dist/checkout.mjs +236 -319
  20. package/dist/db-react.cjs +59 -87
  21. package/dist/db-react.d.cts +1 -1
  22. package/dist/db-react.d.ts +1 -1
  23. package/dist/db-react.mjs +56 -84
  24. package/dist/db.cjs +2055 -3013
  25. package/dist/db.d.cts +1 -1
  26. package/dist/db.d.ts +1 -1
  27. package/dist/db.mjs +2068 -3026
  28. package/dist/entitlements.cjs +12 -20
  29. package/dist/entitlements.d.cts +1 -1
  30. package/dist/entitlements.d.ts +1 -1
  31. package/dist/entitlements.mjs +12 -20
  32. package/dist/errors.cjs +9 -12
  33. package/dist/errors.d.cts +37 -2
  34. package/dist/errors.d.ts +37 -2
  35. package/dist/errors.mjs +8 -12
  36. package/dist/firestore-compat.cjs +241 -297
  37. package/dist/firestore-compat.d.cts +1 -1
  38. package/dist/firestore-compat.d.ts +1 -1
  39. package/dist/firestore-compat.mjs +215 -271
  40. package/dist/index.cjs +3605 -5131
  41. package/dist/index.d.cts +6 -4
  42. package/dist/index.d.ts +6 -4
  43. package/dist/index.mjs +3710 -5236
  44. package/dist/mobile.cjs +238 -342
  45. package/dist/mobile.d.cts +1 -1
  46. package/dist/mobile.d.ts +1 -1
  47. package/dist/mobile.mjs +238 -342
  48. package/dist/mocks.cjs +312 -447
  49. package/dist/mocks.d.cts +1 -1
  50. package/dist/mocks.d.ts +1 -1
  51. package/dist/mocks.mjs +306 -441
  52. package/dist/notifications.cjs +226 -314
  53. package/dist/notifications.d.cts +1 -1
  54. package/dist/notifications.d.ts +1 -1
  55. package/dist/notifications.mjs +225 -313
  56. package/dist/react.cjs +522 -693
  57. package/dist/react.d.cts +1 -1
  58. package/dist/react.d.ts +1 -1
  59. package/dist/react.mjs +512 -683
  60. package/dist/support.cjs +329 -325
  61. package/dist/support.d.cts +25 -3
  62. package/dist/support.d.ts +25 -3
  63. package/dist/support.mjs +328 -325
  64. package/dist/telemetry.cjs +197 -301
  65. package/dist/telemetry.d.cts +1 -1
  66. package/dist/telemetry.d.ts +1 -1
  67. package/dist/telemetry.mjs +197 -301
  68. package/dist/{types-Du_iioJ7.d.cts → types-Bx4kTLmk.d.cts} +26 -0
  69. package/dist/{types-BPATkXYu.d.ts → types-Dx0IrOSF.d.ts} +26 -0
  70. package/dist/usage.cjs +163 -227
  71. package/dist/usage.d.cts +1 -1
  72. package/dist/usage.d.ts +1 -1
  73. package/dist/usage.mjs +163 -227
  74. package/dist/webhooks.cjs +258 -359
  75. package/dist/webhooks.d.cts +1 -1
  76. package/dist/webhooks.d.ts +1 -1
  77. package/dist/webhooks.mjs +255 -356
  78. package/package.json +4 -3
  79. package/dist/ai.cjs.map +0 -1
  80. package/dist/ai.mjs.map +0 -1
  81. package/dist/auth.cjs.map +0 -1
  82. package/dist/auth.mjs.map +0 -1
  83. package/dist/build-guard.cjs.map +0 -1
  84. package/dist/build-guard.mjs.map +0 -1
  85. package/dist/catalog.cjs.map +0 -1
  86. package/dist/catalog.mjs.map +0 -1
  87. package/dist/checkout.cjs.map +0 -1
  88. package/dist/checkout.mjs.map +0 -1
  89. package/dist/db-react.cjs.map +0 -1
  90. package/dist/db-react.mjs.map +0 -1
  91. package/dist/db.cjs.map +0 -1
  92. package/dist/db.mjs.map +0 -1
  93. package/dist/entitlements.cjs.map +0 -1
  94. package/dist/entitlements.mjs.map +0 -1
  95. package/dist/errors.cjs.map +0 -1
  96. package/dist/errors.mjs.map +0 -1
  97. package/dist/firestore-compat.cjs.map +0 -1
  98. package/dist/firestore-compat.mjs.map +0 -1
  99. package/dist/index.cjs.map +0 -1
  100. package/dist/index.mjs.map +0 -1
  101. package/dist/mobile.cjs.map +0 -1
  102. package/dist/mobile.mjs.map +0 -1
  103. package/dist/mocks.cjs.map +0 -1
  104. package/dist/mocks.mjs.map +0 -1
  105. package/dist/notifications.cjs.map +0 -1
  106. package/dist/notifications.mjs.map +0 -1
  107. package/dist/react.cjs.map +0 -1
  108. package/dist/react.mjs.map +0 -1
  109. package/dist/support.cjs.map +0 -1
  110. package/dist/support.mjs.map +0 -1
  111. package/dist/telemetry.cjs.map +0 -1
  112. package/dist/telemetry.mjs.map +0 -1
  113. package/dist/usage.cjs.map +0 -1
  114. package/dist/usage.mjs.map +0 -1
  115. package/dist/webhooks.cjs.map +0 -1
  116. package/dist/webhooks.mjs.map +0 -1
@@ -2362,6 +2362,13 @@ interface AuthNamespace {
2362
2362
  * decodificados use `getUser()`; para validar assinatura use `verifyToken()`.
2363
2363
  */
2364
2364
  getIdToken(): string | null;
2365
+ /**
2366
+ * 3.7.0 — renova a sessão do usuário final via `refresh_token` (rotation).
2367
+ * Resolve `true` se gravou um id_token novo; `false` em qualquer falha (sem
2368
+ * refresh token, revogado, rede). Opcional: mocks/implementações próprias
2369
+ * podem omitir. Usado pelo `client.support` antes de desistir num 401.
2370
+ */
2371
+ refreshTokens?(): Promise<boolean>;
2365
2372
  /** Limpa session local + revoga refresh token no servidor. */
2366
2373
  signOut(): Promise<void>;
2367
2374
  /** Retorna o user atual (do id_token cached) ou `null` se não logado. */
@@ -2557,7 +2564,17 @@ interface SupportTicket {
2557
2564
  * 3.4: URL do primeiro anexo (screenshot) do ticket, quando enviado via
2558
2565
  * `createTicket({ screenshotBase64 })`. `null` se nenhum anexo.
2559
2566
  */
2567
+ /**
2568
+ * Print do ticket. **3.7.0**: na LISTAGEM (`listMyTickets`) vem sempre `null`
2569
+ * — o Core não devolve mais `attachments`/`consoleLogs` na lista (pesados e
2570
+ * sensíveis). Use `screenshotAttached` pra saber se há print.
2571
+ */
2560
2572
  screenshotUrl: string | null;
2573
+ /**
2574
+ * 3.7.0 — se o ticket tem print anexado. Na LISTAGEM o Core não devolve mais
2575
+ * o anexo (`screenshotUrl` vem `null`); use este campo pra saber se há print.
2576
+ */
2577
+ screenshotAttached?: boolean;
2561
2578
  /**
2562
2579
  * 3.4: ISO — setado pelo Core na transição do ticket pra `resolved`.
2563
2580
  * `null` enquanto não resolvido.
@@ -2623,9 +2640,18 @@ interface SupportNamespace {
2623
2640
  /**
2624
2641
  * Lista meus tickets abertos. **3.0**: GET `/api/sdk/v1/support/tickets?productId=...`
2625
2642
  * (canonical). `options.productSlug` override do `config.productId` default.
2643
+ *
2644
+ * **3.7.0**: o Core só lista os tickets do usuário final logado — o SDK manda
2645
+ * o id_token dele (`auth.getIdToken()`) em `X-Neetru-End-User-Token`. Sem
2646
+ * usuário logado lança `NeetruAuthRequiredError` (sem request). O mesmo vale
2647
+ * pra `markResolvedSeen`/`recordSatisfactionAttempt`/`submitSatisfaction`/
2648
+ * `contestTicket`. `createTicket` manda o header quando há usuário (o ticket
2649
+ * fica amarrado a ele) e segue sem ele quando não há.
2626
2650
  */
2627
2651
  listMyTickets(options?: {
2628
2652
  productSlug?: string;
2653
+ /** 3.7.0: quantos tickets (inteiro 1-50). Omitido → default do Core: 20. Máximo 50. */
2654
+ limit?: number;
2629
2655
  }): Promise<SupportTicket[]>;
2630
2656
  /**
2631
2657
  * 3.4: marca que o usuário viu a notificação de resolução do ticket
@@ -2362,6 +2362,13 @@ interface AuthNamespace {
2362
2362
  * decodificados use `getUser()`; para validar assinatura use `verifyToken()`.
2363
2363
  */
2364
2364
  getIdToken(): string | null;
2365
+ /**
2366
+ * 3.7.0 — renova a sessão do usuário final via `refresh_token` (rotation).
2367
+ * Resolve `true` se gravou um id_token novo; `false` em qualquer falha (sem
2368
+ * refresh token, revogado, rede). Opcional: mocks/implementações próprias
2369
+ * podem omitir. Usado pelo `client.support` antes de desistir num 401.
2370
+ */
2371
+ refreshTokens?(): Promise<boolean>;
2365
2372
  /** Limpa session local + revoga refresh token no servidor. */
2366
2373
  signOut(): Promise<void>;
2367
2374
  /** Retorna o user atual (do id_token cached) ou `null` se não logado. */
@@ -2557,7 +2564,17 @@ interface SupportTicket {
2557
2564
  * 3.4: URL do primeiro anexo (screenshot) do ticket, quando enviado via
2558
2565
  * `createTicket({ screenshotBase64 })`. `null` se nenhum anexo.
2559
2566
  */
2567
+ /**
2568
+ * Print do ticket. **3.7.0**: na LISTAGEM (`listMyTickets`) vem sempre `null`
2569
+ * — o Core não devolve mais `attachments`/`consoleLogs` na lista (pesados e
2570
+ * sensíveis). Use `screenshotAttached` pra saber se há print.
2571
+ */
2560
2572
  screenshotUrl: string | null;
2573
+ /**
2574
+ * 3.7.0 — se o ticket tem print anexado. Na LISTAGEM o Core não devolve mais
2575
+ * o anexo (`screenshotUrl` vem `null`); use este campo pra saber se há print.
2576
+ */
2577
+ screenshotAttached?: boolean;
2561
2578
  /**
2562
2579
  * 3.4: ISO — setado pelo Core na transição do ticket pra `resolved`.
2563
2580
  * `null` enquanto não resolvido.
@@ -2623,9 +2640,18 @@ interface SupportNamespace {
2623
2640
  /**
2624
2641
  * Lista meus tickets abertos. **3.0**: GET `/api/sdk/v1/support/tickets?productId=...`
2625
2642
  * (canonical). `options.productSlug` override do `config.productId` default.
2643
+ *
2644
+ * **3.7.0**: o Core só lista os tickets do usuário final logado — o SDK manda
2645
+ * o id_token dele (`auth.getIdToken()`) em `X-Neetru-End-User-Token`. Sem
2646
+ * usuário logado lança `NeetruAuthRequiredError` (sem request). O mesmo vale
2647
+ * pra `markResolvedSeen`/`recordSatisfactionAttempt`/`submitSatisfaction`/
2648
+ * `contestTicket`. `createTicket` manda o header quando há usuário (o ticket
2649
+ * fica amarrado a ele) e segue sem ele quando não há.
2626
2650
  */
2627
2651
  listMyTickets(options?: {
2628
2652
  productSlug?: string;
2653
+ /** 3.7.0: quantos tickets (inteiro 1-50). Omitido → default do Core: 20. Máximo 50. */
2654
+ limit?: number;
2629
2655
  }): Promise<SupportTicket[]>;
2630
2656
  /**
2631
2657
  * 3.4: marca que o usuário viu a notificação de resolução do ticket
package/dist/usage.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  // src/errors.ts
4
- var NeetruError = class _NeetruError extends Error {
4
+ var s = class e extends Error {
5
5
  code;
6
6
  status;
7
7
  requestId;
@@ -14,236 +14,186 @@ var NeetruError = class _NeetruError extends Error {
14
14
  * para um `NeetruDbErrorCode` mais específico (recuperável vs não).
15
15
  */
16
16
  reason;
17
- constructor(code, message, status, requestId, reason) {
18
- super(message);
19
- this.name = "NeetruError";
20
- this.code = code;
21
- this.status = status;
22
- this.requestId = requestId;
23
- this.reason = reason;
24
- Object.setPrototypeOf(this, _NeetruError.prototype);
17
+ constructor(t, r, i, d, n) {
18
+ super(r), this.name = "NeetruError", this.code = t, this.status = i, this.requestId = d, this.reason = n, Object.setPrototypeOf(this, e.prototype);
25
19
  }
26
20
  };
27
21
 
28
22
  // src/idempotency.ts
29
- function generateIdempotencyKey() {
30
- const cryptoObj = typeof globalThis !== "undefined" && "crypto" in globalThis ? globalThis.crypto : void 0;
31
- if (cryptoObj && typeof cryptoObj.randomUUID === "function") {
32
- return cryptoObj.randomUUID();
33
- }
34
- throw new NeetruError(
23
+ function k() {
24
+ let e = typeof globalThis < "u" && "crypto" in globalThis ? globalThis.crypto : void 0;
25
+ if (e && typeof e.randomUUID == "function")
26
+ return e.randomUUID();
27
+ throw new s(
35
28
  "runtime_unsupported",
36
29
  "crypto.randomUUID not available in this runtime. SDK 3.0 requires Node \u226520 or modern browser/Edge."
37
30
  );
38
31
  }
39
32
 
40
33
  // src/http.ts
41
- var COMPAT_MATRIX = {
34
+ var O = {
42
35
  // SDK major 3.x requer Core ≥ 2026.05.1 (suporte a X-Neetru-Version header,
43
36
  // runTransaction write-after-read, verifyWebhookRequest, webhooks 3.0+)
44
37
  3: "2026.05.1"
45
38
  };
46
- function stripRevision(v) {
47
- return v.split("+")[0] ?? v;
39
+ function E(e) {
40
+ return e.split("+")[0] ?? e;
48
41
  }
49
- function compareCalVer(a, b) {
50
- const partsA = stripRevision(a).split(".").map(Number);
51
- const partsB = stripRevision(b).split(".").map(Number);
52
- const len = Math.max(partsA.length, partsB.length);
53
- for (let i = 0; i < len; i++) {
54
- const pa = partsA[i] ?? 0;
55
- const pb = partsB[i] ?? 0;
56
- if (pa !== pb) return pa - pb;
42
+ function $(e, t) {
43
+ let r = E(e).split(".").map(Number), i = E(t).split(".").map(Number), d = Math.max(r.length, i.length);
44
+ for (let n = 0; n < d; n++) {
45
+ let a = r[n] ?? 0, l = i[n] ?? 0;
46
+ if (a !== l) return a - l;
57
47
  }
58
48
  return 0;
59
49
  }
60
- function readInjectedSdkVersion() {
50
+ function C() {
61
51
  try {
62
- return "3.6.0";
52
+ return "3.7.0";
63
53
  } catch {
64
- return void 0;
54
+ return;
65
55
  }
66
56
  }
67
- function getSdkMajor() {
68
- const ver = readInjectedSdkVersion();
69
- if (ver) return parseInt(ver.split(".")[0] ?? "3", 10);
70
- return 3;
57
+ function P() {
58
+ let e = C();
59
+ return e ? parseInt(e.split(".")[0] ?? "3", 10) : 3;
71
60
  }
72
- var _warnedCoreTooOld = /* @__PURE__ */ new Set();
73
- function checkCoreVersionCompat(coreVersion) {
74
- if (!coreVersion) return;
75
- const sdkMajor = getSdkMajor();
76
- const minCore = COMPAT_MATRIX[sdkMajor];
77
- if (!minCore) return;
78
- const stripped = stripRevision(coreVersion);
79
- if (compareCalVer(stripped, minCore) < 0) {
80
- const key = `${sdkMajor}:${stripped}`;
81
- if (!_warnedCoreTooOld.has(key)) {
82
- _warnedCoreTooOld.add(key);
83
- console.warn(
84
- `[Neetru SDK] Aten\xE7\xE3o: Core vers\xE3o "${coreVersion}" \xE9 anterior ao m\xEDnimo recomendado "${minCore}" para SDK major ${sdkMajor}. Alguns recursos podem n\xE3o funcionar corretamente. Atualize o Core para a vers\xE3o mais recente.`
85
- );
86
- }
61
+ var N = /* @__PURE__ */ new Set();
62
+ function K(e) {
63
+ if (!e) return;
64
+ let t = P(), r = O[t];
65
+ if (!r) return;
66
+ let i = E(e);
67
+ if ($(i, r) < 0) {
68
+ let d = `${t}:${i}`;
69
+ N.has(d) || (N.add(d), console.warn(
70
+ `[Neetru SDK] Aten\xE7\xE3o: Core vers\xE3o "${e}" \xE9 anterior ao m\xEDnimo recomendado "${r}" para SDK major ${t}. Alguns recursos podem n\xE3o funcionar corretamente. Atualize o Core para a vers\xE3o mais recente.`
71
+ ));
87
72
  }
88
73
  }
89
- var DEFAULT_RETRIES_READ = 2;
90
- var DEFAULT_RETRIES_WRITE = 0;
91
- var READ_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD"]);
92
- var RETRYABLE_CODES = /* @__PURE__ */ new Set([
74
+ var j = 2, F = 0, H = /* @__PURE__ */ new Set(["GET", "HEAD"]), z = /* @__PURE__ */ new Set([
93
75
  "rate_limited",
94
76
  "server_error",
95
77
  "network_error"
96
78
  ]);
97
- function backoffMs(attempt) {
98
- const base = 200 * Math.pow(4, attempt);
99
- const jitter = base * 0.2 * (Math.random() * 2 - 1);
100
- return Math.max(50, Math.round(base + jitter));
79
+ function x(e) {
80
+ let t = 200 * Math.pow(4, e), r = t * 0.2 * (Math.random() * 2 - 1);
81
+ return Math.max(50, Math.round(t + r));
101
82
  }
102
- var MAX_RETRY_AFTER_MS = 6e4;
103
- function parseRetryAfter(value) {
104
- if (!value) return null;
105
- const secs = Number(value);
106
- if (Number.isFinite(secs) && secs >= 0) return Math.min(Math.round(secs * 1e3), MAX_RETRY_AFTER_MS);
107
- const dateMs = Date.parse(value);
108
- if (Number.isFinite(dateMs)) {
109
- const delta = dateMs - Date.now();
110
- if (delta > 0) return Math.min(delta, MAX_RETRY_AFTER_MS);
83
+ var D = 6e4;
84
+ function V(e) {
85
+ if (!e) return null;
86
+ let t = Number(e);
87
+ if (Number.isFinite(t) && t >= 0) return Math.min(Math.round(t * 1e3), D);
88
+ let r = Date.parse(e);
89
+ if (Number.isFinite(r)) {
90
+ let i = r - Date.now();
91
+ if (i > 0) return Math.min(i, D);
111
92
  }
112
93
  return null;
113
94
  }
114
- function sleep(ms) {
115
- return new Promise((resolve) => setTimeout(resolve, ms));
95
+ function q(e) {
96
+ return new Promise((t) => setTimeout(t, e));
116
97
  }
117
- function statusToCode(status) {
118
- if (status === 401) return "unauthorized";
119
- if (status === 403) return "forbidden";
120
- if (status === 404) return "not_found";
121
- if (status === 409) return "conflict";
122
- if (status === 422 || status === 400) return "validation_failed";
123
- if (status === 429) return "rate_limited";
124
- if (status >= 500) return "server_error";
125
- return "unknown";
98
+ function G(e) {
99
+ return e === 401 ? "unauthorized" : e === 403 ? "forbidden" : e === 404 ? "not_found" : e === 409 ? "conflict" : e === 410 ? "gone" : e === 422 || e === 400 ? "validation_failed" : e === 429 ? "rate_limited" : e >= 500 ? "server_error" : "unknown";
126
100
  }
127
- function buildUrl(baseUrl, path, query) {
128
- const base = baseUrl.replace(/\/+$/, "");
129
- const p = path.startsWith("/") ? path : `/${path}`;
130
- const url = new URL(`${base}${p}`);
131
- if (query) {
132
- for (const [k, v] of Object.entries(query)) {
133
- if (v === void 0) continue;
134
- url.searchParams.set(k, String(v));
135
- }
136
- }
137
- return url.toString();
101
+ function L(e, t, r) {
102
+ let i = e.replace(/\/+$/, ""), d = t.startsWith("/") ? t : `/${t}`, n = new URL(`${i}${d}`);
103
+ if (r)
104
+ for (let [a, l] of Object.entries(r))
105
+ l !== void 0 && n.searchParams.set(a, String(l));
106
+ return n.toString();
138
107
  }
139
- async function safeJson(res) {
140
- const text = await res.text();
141
- if (!text) return void 0;
142
- try {
143
- return JSON.parse(text);
144
- } catch {
145
- return void 0;
146
- }
108
+ async function A(e) {
109
+ let t = await e.text();
110
+ if (t)
111
+ try {
112
+ return JSON.parse(t);
113
+ } catch {
114
+ return;
115
+ }
147
116
  }
148
- async function httpRequest(config, opts) {
149
- const method = opts.method ?? "GET";
150
- const url = buildUrl(config.baseUrl, opts.path, opts.query);
151
- const defaultRetries = READ_METHODS.has(method) ? DEFAULT_RETRIES_READ : DEFAULT_RETRIES_WRITE;
152
- const maxRetries = opts.retries ?? defaultRetries;
153
- const headers = {
117
+ async function v(e, t) {
118
+ let r = t.method ?? "GET", i = L(e.baseUrl, t.path, t.query), d = H.has(r) ? j : F, n = t.retries ?? d, a = {
154
119
  accept: "application/json",
155
- ...opts.headers
156
- };
157
- const sdkVersion = readInjectedSdkVersion();
158
- if (sdkVersion) {
159
- headers["x-neetru-sdk-version"] = sdkVersion;
160
- }
161
- if (opts.requireAuth) {
162
- if (!config.apiKey) {
163
- throw new NeetruError(
120
+ ...t.headers
121
+ }, l = C();
122
+ if (l && (a["x-neetru-sdk-version"] = l), t.requireAuth) {
123
+ if (!e.apiKey)
124
+ throw new s(
164
125
  "missing_api_key",
165
126
  "This operation requires an apiKey. Pass it to createNeetruClient({ apiKey }) or set NEETRU_API_KEY env var."
166
127
  );
167
- }
168
- headers.authorization = `Bearer ${config.apiKey}`;
169
- }
170
- if (opts.idempotencyKey) {
171
- const key = typeof opts.idempotencyKey === "string" ? opts.idempotencyKey : generateIdempotencyKey();
172
- headers["idempotency-key"] = key;
128
+ a.authorization = `Bearer ${e.apiKey}`;
173
129
  }
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";
130
+ if (t.idempotencyKey) {
131
+ let f = typeof t.idempotencyKey == "string" ? t.idempotencyKey : k();
132
+ a["idempotency-key"] = f;
177
133
  }
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;
134
+ let _ = t.body !== void 0 && r !== "GET" && r !== "DELETE" ? JSON.stringify(t.body) : void 0;
135
+ _ !== void 0 && (a["content-type"] = "application/json");
136
+ let g = null, p = t.deadlineMs != null ? Date.now() + t.deadlineMs : null;
137
+ for (let f = 0; f <= n; f++) {
138
+ if (p != null && Date.now() >= p)
139
+ throw g ?? new s("network_error", "Deadline excedido antes de completar a request");
140
+ let w = { method: r, headers: a };
141
+ _ !== void 0 && (w.body = _);
142
+ let M = p != null ? Math.max(1, Math.min(3e4, p - Date.now())) : 3e4;
143
+ w.signal = AbortSignal.timeout(M);
144
+ let u;
184
145
  try {
185
- res = await config.fetch(url, init);
186
- } catch (err2) {
187
- const message2 = err2 instanceof DOMException && err2.name === "TimeoutError" ? "Network error: timeout after 30s" : `Network error: ${err2 instanceof Error ? err2.message : "fetch failed"}`;
188
- lastError = new NeetruError("network_error", message2);
189
- if (attempt < maxRetries) {
190
- await sleep(backoffMs(attempt));
191
- continue;
146
+ u = await e.fetch(i, w);
147
+ } catch (o) {
148
+ let h = o instanceof DOMException && o.name === "TimeoutError" ? "Network error: timeout after 30s" : `Network error: ${o instanceof Error ? o.message : "fetch failed"}`;
149
+ if (g = new s("network_error", h), f < n) {
150
+ let T = x(f);
151
+ if (p == null || Date.now() + T < p) {
152
+ await q(T);
153
+ continue;
154
+ }
192
155
  }
193
- throw lastError;
156
+ throw g;
194
157
  }
195
- const requestId = res.headers.get("x-request-id") ?? res.headers.get("x-correlation-id") ?? void 0;
196
- if (res.ok) {
197
- const coreVersion = res.headers.get("x-neetru-version");
198
- if (coreVersion) checkCoreVersionCompat(coreVersion);
199
- const parsed = await safeJson(res);
200
- return parsed;
158
+ let U = u.headers.get("x-request-id") ?? u.headers.get("x-correlation-id") ?? void 0;
159
+ if (u.ok) {
160
+ let o = u.headers.get("x-neetru-version");
161
+ return o && K(o), await A(u);
201
162
  }
202
- const body = await safeJson(res);
203
- let code = statusToCode(res.status);
204
- let message = `HTTP ${res.status}`;
205
- let reason;
206
- if (body && typeof body === "object") {
207
- const errField = body.error;
208
- if (typeof errField === "string") {
209
- message = errField;
210
- } else if (errField && typeof errField === "object") {
211
- if (typeof errField.code === "string") code = errField.code;
212
- if (typeof errField.message === "string") message = errField.message;
213
- if (typeof errField.reason === "string") reason = errField.reason;
214
- } else {
215
- if (typeof body.code === "string") code = body.code;
216
- if (typeof body.message === "string") message = body.message;
217
- }
218
- if (typeof body.reason === "string") reason = body.reason;
163
+ let c = await A(u), b = G(u.status), m = `HTTP ${u.status}`, I;
164
+ if (c && typeof c == "object") {
165
+ let o = c.error;
166
+ typeof o == "string" ? m = o : o && typeof o == "object" ? (typeof o.code == "string" && (b = o.code), typeof o.message == "string" && (m = o.message), typeof o.reason == "string" && (I = o.reason)) : (typeof c.code == "string" && (b = c.code), typeof c.message == "string" && (m = c.message)), typeof c.reason == "string" && (I = c.reason);
219
167
  }
220
- const err = new NeetruError(code, message, res.status, requestId, reason);
221
- lastError = err;
222
- const isRetryable = RETRYABLE_CODES.has(code);
223
- if (isRetryable && attempt < maxRetries) {
224
- const retryAfter = parseRetryAfter(res.headers.get("retry-after"));
225
- const delay = retryAfter ?? backoffMs(attempt);
226
- await sleep(delay);
227
- continue;
168
+ if (u.status === 410) {
169
+ let o = u.headers.get("x-neetru-replacement");
170
+ m === `HTTP ${u.status}` && (m = `Endpoint ${t.path} foi removido do Core (HTTP 410 Gone) \u2014 atualize o @neetru/sdk e migre para a API substituta.`), o && !m.includes(o) && (m += ` Substituto: ${o}.`);
228
171
  }
229
- throw err;
172
+ let R = new s(b, m, u.status, U, I);
173
+ if (g = R, z.has(b) && f < n) {
174
+ let h = V(u.headers.get("retry-after")) ?? x(f);
175
+ if (p == null || Date.now() + h < p) {
176
+ await q(h);
177
+ continue;
178
+ }
179
+ }
180
+ throw R;
230
181
  }
231
- throw lastError ?? new NeetruError("unknown", "unexpected httpRequest exit");
182
+ throw g ?? new s("unknown", "unexpected httpRequest exit");
232
183
  }
233
184
 
234
185
  // src/validators.ts
235
- var SDK_ID_RE = /^[a-z0-9][a-z0-9_-]{0,62}$/i;
236
- function assertValidSdkId(field, value) {
237
- if (typeof value !== "string" || !SDK_ID_RE.test(value)) {
238
- throw new NeetruError(
186
+ var S = /^[a-z0-9][a-z0-9_-]{0,62}$/i;
187
+ function y(e, t) {
188
+ if (typeof t != "string" || !S.test(t))
189
+ throw new s(
239
190
  "validation_failed",
240
- `${field} must match ${SDK_ID_RE.source} (lowercase alphanumeric, _, -; first char must be alphanumeric; max 63 chars)`
191
+ `${e} must match ${S.source} (lowercase alphanumeric, _, -; first char must be alphanumeric; max 63 chars)`
241
192
  );
242
- }
243
193
  }
244
194
 
245
195
  // src/usage.ts
246
- function createUsageNamespace(config) {
196
+ function ie(e) {
247
197
  return {
248
198
  /**
249
199
  * Reporta consumo metered de um resource. Hit no endpoint canônico
@@ -257,46 +207,39 @@ function createUsageNamespace(config) {
257
207
  * await client.usage.report('api_call', 5, { productId: 'gestovendas', tenantId: 't-acme' });
258
208
  * ```
259
209
  */
260
- async report(resource, qty = 1, options) {
261
- if (!resource || typeof resource !== "string") {
262
- throw new NeetruError("validation_failed", "resource is required");
263
- }
264
- if (!Number.isFinite(qty) || qty <= 0 || !Number.isInteger(qty)) {
265
- throw new NeetruError("validation_failed", "qty must be a positive integer");
266
- }
267
- const productId = options?.productId ?? config.productId;
268
- const tenantId = options?.tenantId ?? config.tenantId;
269
- if (!productId) {
270
- throw new NeetruError(
210
+ async report(t, r = 1, i) {
211
+ if (!t || typeof t != "string")
212
+ throw new s("validation_failed", "resource is required");
213
+ if (!Number.isFinite(r) || r <= 0 || !Number.isInteger(r))
214
+ throw new s("validation_failed", "qty must be a positive integer");
215
+ let d = i?.productId ?? e.productId, n = i?.tenantId ?? e.tenantId;
216
+ if (!d)
217
+ throw new s(
271
218
  "validation_failed",
272
219
  "productId required (pass to options or set on createNeetruClient)"
273
220
  );
274
- }
275
- if (!tenantId) {
276
- throw new NeetruError(
221
+ if (!n)
222
+ throw new s(
277
223
  "validation_failed",
278
224
  "tenantId required (pass to options or set on createNeetruClient)"
279
225
  );
280
- }
281
- assertValidSdkId("productId", productId);
282
- assertValidSdkId("tenantId", tenantId);
283
- const raw = await httpRequest(config, {
226
+ y("productId", d), y("tenantId", n);
227
+ let a = await v(e, {
284
228
  method: "POST",
285
229
  path: "/api/sdk/v1/usage/record",
286
- body: { productId, tenantId, resource, qty: Math.floor(qty) },
230
+ body: { productId: d, tenantId: n, resource: t, qty: Math.floor(r) },
287
231
  requireAuth: true,
288
232
  idempotencyKey: true
289
233
  });
290
- if (!raw || raw.ok !== true) {
291
- throw new NeetruError("invalid_response", "usage.report response missing ok");
292
- }
234
+ if (!a || a.ok !== true)
235
+ throw new s("invalid_response", "usage.report response missing ok");
293
236
  return {
294
237
  ok: true,
295
- counterId: raw.counterId,
296
- value: raw.value,
297
- limit: raw.limit,
298
- remaining: raw.remaining,
299
- status: raw.status
238
+ counterId: a.counterId,
239
+ value: a.value,
240
+ limit: a.limit,
241
+ remaining: a.remaining,
242
+ status: a.status
300
243
  };
301
244
  },
302
245
  /**
@@ -305,43 +248,36 @@ function createUsageNamespace(config) {
305
248
  * 'subscription_inactive' | 'feature_not_in_plan' | 'limit_exceeded'),
306
249
  * `remaining`, `limit`, `planId`, `planFeatures`.
307
250
  */
308
- async check(resource, options) {
309
- if (!resource || typeof resource !== "string") {
310
- throw new NeetruError("validation_failed", "resource is required");
311
- }
312
- const productId = options?.productId ?? config.productId;
313
- const tenantId = options?.tenantId ?? config.tenantId;
314
- if (!productId || !tenantId) {
315
- throw new NeetruError(
251
+ async check(t, r) {
252
+ if (!t || typeof t != "string")
253
+ throw new s("validation_failed", "resource is required");
254
+ let i = r?.productId ?? e.productId, d = r?.tenantId ?? e.tenantId;
255
+ if (!i || !d)
256
+ throw new s(
316
257
  "validation_failed",
317
258
  "productId and tenantId required (pass to options or set on createNeetruClient)"
318
259
  );
319
- }
320
- assertValidSdkId("productId", productId);
321
- assertValidSdkId("tenantId", tenantId);
322
- const raw = await httpRequest(config, {
260
+ y("productId", i), y("tenantId", d);
261
+ let n = await v(e, {
323
262
  method: "GET",
324
263
  path: "/api/sdk/v1/entitlements",
325
- query: { productId, tenantId, feature: resource },
264
+ query: { productId: i, tenantId: d, feature: t },
326
265
  requireAuth: true
327
266
  });
328
- if (!raw || typeof raw.allowed !== "boolean") {
329
- throw new NeetruError("invalid_response", "usage.check response missing allowed");
330
- }
331
- const behavior = raw.behavior ?? (raw.reason === "limit_exceeded" ? "readonly" : null);
267
+ if (!n || typeof n.allowed != "boolean")
268
+ throw new s("invalid_response", "usage.check response missing allowed");
269
+ let a = n.behavior ?? (n.reason === "limit_exceeded" ? "readonly" : null);
332
270
  return {
333
- allowed: raw.allowed,
334
- reason: raw.reason,
335
- remaining: raw.remaining,
336
- limit: raw.limit,
337
- planId: raw.planId,
338
- planFeatures: raw.planFeatures,
339
- behavior
271
+ allowed: n.allowed,
272
+ reason: n.reason,
273
+ remaining: n.remaining,
274
+ limit: n.limit,
275
+ planId: n.planId,
276
+ planFeatures: n.planFeatures,
277
+ behavior: a
340
278
  };
341
279
  }
342
280
  };
343
281
  }
344
282
 
345
- exports.createUsageNamespace = createUsageNamespace;
346
- //# sourceMappingURL=usage.cjs.map
347
- //# sourceMappingURL=usage.cjs.map
283
+ exports.createUsageNamespace = ie;
package/dist/usage.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { ag as ResolvedConfig, ax as UsageNamespace } from './types-Du_iioJ7.cjs';
1
+ import { ag as ResolvedConfig, ax as UsageNamespace } from './types-Bx4kTLmk.cjs';
2
2
  import 'drizzle-orm/node-postgres';
3
3
  import './errors.cjs';
4
4
 
package/dist/usage.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ag as ResolvedConfig, ax as UsageNamespace } from './types-BPATkXYu.js';
1
+ import { ag as ResolvedConfig, ax as UsageNamespace } from './types-Dx0IrOSF.js';
2
2
  import 'drizzle-orm/node-postgres';
3
3
  import './errors.js';
4
4