@neetru/sdk 3.8.1 → 3.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/README.md +14 -1
  3. package/dist/ai.cjs +1 -1
  4. package/dist/ai.d.cts +1 -1
  5. package/dist/ai.d.ts +1 -1
  6. package/dist/ai.mjs +1 -1
  7. package/dist/auth.cjs +844 -803
  8. package/dist/auth.d.cts +1 -1
  9. package/dist/auth.d.ts +1 -1
  10. package/dist/auth.mjs +841 -800
  11. package/dist/build-guard.cjs +186 -82
  12. package/dist/build-guard.d.cts +53 -1
  13. package/dist/build-guard.d.ts +53 -1
  14. package/dist/build-guard.mjs +175 -74
  15. package/dist/catalog.cjs +1 -1
  16. package/dist/catalog.d.cts +1 -1
  17. package/dist/catalog.d.ts +1 -1
  18. package/dist/catalog.mjs +1 -1
  19. package/dist/checkout.cjs +62 -49
  20. package/dist/checkout.d.cts +1 -1
  21. package/dist/checkout.d.ts +1 -1
  22. package/dist/checkout.mjs +62 -49
  23. package/dist/db-react.d.cts +1 -1
  24. package/dist/db-react.d.ts +1 -1
  25. package/dist/db.cjs +200 -187
  26. package/dist/db.d.cts +1 -1
  27. package/dist/db.d.ts +1 -1
  28. package/dist/db.mjs +193 -180
  29. package/dist/entitlements.d.cts +1 -1
  30. package/dist/entitlements.d.ts +1 -1
  31. package/dist/firestore-compat.d.cts +1 -1
  32. package/dist/firestore-compat.d.ts +1 -1
  33. package/dist/index.cjs +880 -839
  34. package/dist/index.d.cts +2 -2
  35. package/dist/index.d.ts +2 -2
  36. package/dist/index.mjs +847 -806
  37. package/dist/mobile.cjs +328 -276
  38. package/dist/mobile.d.cts +12 -2
  39. package/dist/mobile.d.ts +12 -2
  40. package/dist/mobile.mjs +328 -276
  41. package/dist/mocks.cjs +5 -5
  42. package/dist/mocks.d.cts +2 -2
  43. package/dist/mocks.d.ts +2 -2
  44. package/dist/mocks.mjs +4 -4
  45. package/dist/notifications.cjs +1 -1
  46. package/dist/notifications.d.cts +1 -1
  47. package/dist/notifications.d.ts +1 -1
  48. package/dist/notifications.mjs +1 -1
  49. package/dist/react.cjs +119 -119
  50. package/dist/react.d.cts +8 -2
  51. package/dist/react.d.ts +8 -2
  52. package/dist/react.mjs +119 -119
  53. package/dist/support.cjs +1 -1
  54. package/dist/support.d.cts +1 -1
  55. package/dist/support.d.ts +1 -1
  56. package/dist/support.mjs +1 -1
  57. package/dist/telemetry.cjs +62 -49
  58. package/dist/telemetry.d.cts +1 -1
  59. package/dist/telemetry.d.ts +1 -1
  60. package/dist/telemetry.mjs +62 -49
  61. package/dist/{types-yv3EDKg2.d.cts → types-Bl_4HROd.d.cts} +62 -3
  62. package/dist/{types-BYPk_3HR.d.ts → types-Bqnsqvow.d.ts} +62 -3
  63. package/dist/usage.cjs +1 -1
  64. package/dist/usage.d.cts +1 -1
  65. package/dist/usage.d.ts +1 -1
  66. package/dist/usage.mjs +1 -1
  67. package/dist/webhooks.cjs +1 -1
  68. package/dist/webhooks.d.cts +1 -1
  69. package/dist/webhooks.d.ts +1 -1
  70. package/dist/webhooks.mjs +1 -1
  71. package/package.json +9 -1
package/dist/mobile.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/errors.ts
2
- var n = class t extends Error {
2
+ var o = class t extends Error {
3
3
  code;
4
4
  status;
5
5
  requestId;
@@ -19,65 +19,65 @@ var n = class t extends Error {
19
19
  * `undefined` em erros que acontecem antes de qualquer requisição.
20
20
  */
21
21
  correlationId;
22
- constructor(e, o, s, i, p, m) {
23
- super(o), this.name = "NeetruError", this.code = e, this.status = s, this.requestId = i, this.reason = p, this.correlationId = m, Object.setPrototypeOf(this, t.prototype);
22
+ constructor(e, n, i, a, f, p) {
23
+ super(n), this.name = "NeetruError", this.code = e, this.status = i, this.requestId = a, this.reason = f, this.correlationId = p, Object.setPrototypeOf(this, t.prototype);
24
24
  }
25
- }, v = class t extends n {
26
- constructor(e, o, s, i, p) {
27
- super("auth_required", e, s, i, o, p), this.name = "NeetruAuthRequiredError", Object.setPrototypeOf(this, t.prototype);
25
+ }, R = class t extends o {
26
+ constructor(e, n, i, a, f) {
27
+ super("auth_required", e, i, a, n, f), this.name = "NeetruAuthRequiredError", Object.setPrototypeOf(this, t.prototype);
28
28
  }
29
29
  };
30
30
 
31
31
  // src/types.ts
32
- var H = "https://api.neetru.com";
32
+ var B = "https://api.neetru.com";
33
33
 
34
34
  // src/base-url-allowlist.ts
35
- var B = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]", "::1"]), le = ".neetru.com", ue = "neetru.com", de = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?\.(test|localhost)$/;
35
+ var F = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]", "::1"]), fe = ".neetru.com", ge = "neetru.com", me = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?\.(test|localhost)$/;
36
36
  function j(t) {
37
- return de.test(t);
37
+ return me.test(t);
38
38
  }
39
- function pe(t) {
39
+ function he(t) {
40
40
  return t.toLowerCase().replace(/\.+$/, "");
41
41
  }
42
- function F(t, e = []) {
42
+ function z(t, e = []) {
43
43
  if (typeof t != "string" || t.length === 0)
44
- throw new n("invalid_config", "baseUrl is required");
45
- let o;
44
+ throw new o("invalid_config", "baseUrl is required");
45
+ let n;
46
46
  try {
47
- o = new URL(t);
47
+ n = new URL(t);
48
48
  } catch {
49
- throw new n("invalid_config", `baseUrl is not a valid URL: ${t}`);
49
+ throw new o("invalid_config", `baseUrl is not a valid URL: ${t}`);
50
50
  }
51
- let s = o.protocol, i = pe(o.hostname);
52
- if (fe())
51
+ let i = n.protocol, a = he(n.hostname);
52
+ if (ye())
53
53
  return typeof console < "u" && console.warn(
54
54
  `[neetru-sdk] NEETRU_ALLOW_INSECURE_BASEURL=1 ativo. baseUrl=${t} aceito sem valida\xE7\xE3o.`
55
55
  ), t.replace(/\/+$/, "");
56
- if (s !== "https:" && s !== "http:")
57
- throw new n(
56
+ if (i !== "https:" && i !== "http:")
57
+ throw new o(
58
58
  "invalid_config",
59
- `baseUrl protocol must be http: or https:, got ${s}`
59
+ `baseUrl protocol must be http: or https:, got ${i}`
60
60
  );
61
- if (s === "http:") {
62
- if (!(B.has(i) || j(i)))
63
- throw new n(
61
+ if (i === "http:") {
62
+ if (!(F.has(a) || j(a)))
63
+ throw new o(
64
64
  "invalid_config",
65
- `baseUrl with http: only allowed for localhost/127.0.0.1/*.test/*.localhost. Got: ${i}. Use https: or set NEETRU_ALLOW_INSECURE_BASEURL=1 to bypass.`
65
+ `baseUrl with http: only allowed for localhost/127.0.0.1/*.test/*.localhost. Got: ${a}. Use https: or set NEETRU_ALLOW_INSECURE_BASEURL=1 to bypass.`
66
66
  );
67
67
  return t.replace(/\/+$/, "");
68
68
  }
69
- let p = i === ue || i.endsWith(le), m = e.some((h) => {
69
+ let f = a === ge || a.endsWith(fe), p = e.some((h) => {
70
70
  let w = h.toLowerCase();
71
- return i === w || i.endsWith(`.${w}`);
72
- }), I = B.has(i) || j(i);
73
- if (!p && !m && !I)
74
- throw new n(
71
+ return a === w || a.endsWith(`.${w}`);
72
+ }), y = F.has(a) || j(a);
73
+ if (!f && !p && !y)
74
+ throw new o(
75
75
  "invalid_config",
76
- `baseUrl ${i} is not in the allowlist. Allowed: *.neetru.com, localhost, or configure { allowedHosts: ['...'] }. Bypass: NEETRU_ALLOW_INSECURE_BASEURL=1.`
76
+ `baseUrl ${a} is not in the allowlist. Allowed: *.neetru.com, localhost, or configure { allowedHosts: ['...'] }. Bypass: NEETRU_ALLOW_INSECURE_BASEURL=1.`
77
77
  );
78
78
  return t.replace(/\/+$/, "");
79
79
  }
80
- function fe() {
80
+ function ye() {
81
81
  try {
82
82
  let e = globalThis.process?.env?.NEETRU_ALLOW_INSECURE_BASEURL;
83
83
  if (e === "1" || e === "true") return !0;
@@ -92,16 +92,16 @@ function fe() {
92
92
  }
93
93
 
94
94
  // src/api-key.ts
95
- var ge = /^nrt_([A-Za-z0-9]+)_([A-Za-z0-9]+)$/;
96
- function z(t) {
95
+ var be = /^nrt_([A-Za-z0-9]+)_([A-Za-z0-9]+)$/;
96
+ function V(t) {
97
97
  if (typeof t != "string" || t.length === 0)
98
- throw new n(
98
+ throw new o(
99
99
  "invalid_config",
100
100
  "apiKey is required (formato nrt_<keyId>_<secret>)"
101
101
  );
102
- let e = ge.exec(t);
102
+ let e = be.exec(t);
103
103
  if (!e)
104
- throw new n(
104
+ throw new o(
105
105
  "invalid_config",
106
106
  "apiKey malformado - esperado formato nrt_<keyId>_<secret>"
107
107
  );
@@ -109,57 +109,57 @@ function z(t) {
109
109
  }
110
110
 
111
111
  // src/auth-pkce-shared.ts
112
- function V() {
112
+ function W() {
113
113
  let t = globalThis.crypto;
114
114
  if (!t || typeof t.getRandomValues != "function" || !t.subtle)
115
- throw new n(
115
+ throw new o(
116
116
  "runtime_unsupported",
117
117
  "auth.signIn requer WebCrypto (crypto.subtle) \u2014 indispon\xEDvel neste runtime. Use HTTPS (ou http://localhost) num browser moderno, ou instale um polyfill WebCrypto (ex: react-native-quick-crypto) em React Native."
118
118
  );
119
119
  return t;
120
120
  }
121
- function W(t) {
121
+ function J(t) {
122
122
  let e = "";
123
- for (let s of t) e += String.fromCharCode(s);
123
+ for (let i of t) e += String.fromCharCode(i);
124
124
  return (typeof btoa == "function" ? btoa(e) : Buffer.from(e, "binary").toString("base64")).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
125
125
  }
126
126
  function x(t, e) {
127
- let o = new Uint8Array(e);
128
- return t.getRandomValues(o), W(o);
127
+ let n = new Uint8Array(e);
128
+ return t.getRandomValues(n), J(n);
129
129
  }
130
- async function J(t, e) {
131
- let o = new TextEncoder().encode(e), s = await t.subtle.digest("SHA-256", o);
132
- return W(new Uint8Array(s));
130
+ async function G(t, e) {
131
+ let n = new TextEncoder().encode(e), i = await t.subtle.digest("SHA-256", n);
132
+ return J(new Uint8Array(i));
133
133
  }
134
- function S(t) {
134
+ function I(t) {
135
135
  return (typeof globalThis.NEETRU_AUTH_URL == "string" ? globalThis.NEETRU_AUTH_URL : null) ?? t.replace(/^https?:\/\/api\./, "https://auth.");
136
136
  }
137
- function L(t) {
137
+ function O(t) {
138
138
  let e = t.oidcClientId;
139
- if (!e && t.apiKey && (e = z(t.apiKey).keyId), !e)
140
- throw new n(
139
+ if (!e && t.apiKey && (e = V(t.apiKey).keyId), !e)
140
+ throw new o(
141
141
  "invalid_config",
142
142
  "auth OIDC requer `oidcClientId` (ou `apiKey`) configurado para montar o client_id."
143
143
  );
144
144
  return e;
145
145
  }
146
- function G(t) {
146
+ function X(t) {
147
147
  let e = new URL("/api/v1/oauth/authorize", t.idpOrigin);
148
148
  return e.searchParams.set("response_type", "code"), e.searchParams.set("client_id", t.clientId), e.searchParams.set("redirect_uri", t.redirectUri), e.searchParams.set("scope", t.scope), e.searchParams.set("state", t.state), e.searchParams.set("nonce", t.nonce), e.searchParams.set("code_challenge", t.codeChallenge), e.searchParams.set("code_challenge_method", "S256"), e;
149
149
  }
150
- var X = "/api/v1/oauth/token";
151
- function O(t) {
150
+ var Y = "/api/v1/oauth/token";
151
+ function L(t) {
152
152
  let e = t.split(".");
153
153
  if (e.length !== 3) return null;
154
154
  try {
155
- let o = e[1].replace(/-/g, "+").replace(/_/g, "/"), s = "=".repeat((4 - o.length % 4) % 4), i = typeof atob == "function" ? atob(o + s) : Buffer.from(o + s, "base64").toString("utf-8");
156
- return JSON.parse(i);
155
+ let n = e[1].replace(/-/g, "+").replace(/_/g, "/"), i = "=".repeat((4 - n.length % 4) % 4), a = typeof atob == "function" ? atob(n + i) : Buffer.from(n + i, "base64").toString("utf-8");
156
+ return JSON.parse(a);
157
157
  } catch {
158
158
  return null;
159
159
  }
160
160
  }
161
- function T(t) {
162
- let e = O(t);
161
+ function A(t) {
162
+ let e = L(t);
163
163
  return !e || typeof e.sub != "string" || typeof e.exp == "number" && e.exp * 1e3 < Date.now() ? null : {
164
164
  uid: e.sub,
165
165
  email: typeof e.email == "string" ? e.email : "",
@@ -172,35 +172,35 @@ function T(t) {
172
172
  ...e
173
173
  };
174
174
  }
175
- var me = "/api/v1/oauth/revoke";
176
- async function Y(t, e, o, s) {
177
- let i = `${e}${me}`, p = true;
178
- for (let m of s) {
179
- if (!m.token) continue;
180
- let I = new URLSearchParams({
181
- token: m.token,
182
- token_type_hint: m.hint,
183
- client_id: o
175
+ var _e = "/api/v1/oauth/revoke";
176
+ async function Q(t, e, n, i) {
177
+ let a = `${e}${_e}`, f = true;
178
+ for (let p of i) {
179
+ if (!p.token) continue;
180
+ let y = new URLSearchParams({
181
+ token: p.token,
182
+ token_type_hint: p.hint,
183
+ client_id: n
184
184
  }).toString(), h = false;
185
185
  for (let w = 0; w < 2 && !h; w++)
186
186
  try {
187
- if (h = (await t(i, {
187
+ if (h = (await t(a, {
188
188
  method: "POST",
189
189
  headers: { "content-type": "application/x-www-form-urlencoded" },
190
- body: I
190
+ body: y
191
191
  })).ok, !h) break;
192
192
  } catch {
193
- w === 0 && await new Promise((_) => setTimeout(_, 500));
193
+ w === 0 && await new Promise((k) => setTimeout(k, 500));
194
194
  }
195
- h || (p = false);
195
+ h || (f = false);
196
196
  }
197
- return p;
197
+ return f;
198
198
  }
199
199
 
200
200
  // src/server-only-key.ts
201
201
  function Z(t) {
202
202
  if (!(t == null || t === ""))
203
- throw new n(
203
+ throw new o(
204
204
  "server_only_key",
205
205
  "[Neetru SDK] Recusado: @neetru/sdk/mobile n\xE3o aceita apiKey. A credencial nrt_ do produto \xE9 S\xD3 DE SERVIDOR \u2014 dentro do app ela \xE9 extra\xEDvel do pacote (.apk/.ipa). Remova a apiKey (e qualquer EXPO_PUBLIC_*_KEY com ela) do app: fa\xE7a login com oidcClientId (client OIDC p\xFAblico do app) e chame a API do seu produto com o access_token do usu\xE1rio; o backend do produto usa o SDK com a chave.",
206
206
  void 0,
@@ -210,419 +210,471 @@ function Z(t) {
210
210
  }
211
211
 
212
212
  // src/correlation.ts
213
- var Q = "x-correlation-id";
214
- var he = /^[A-Za-z0-9._:\-]+$/;
215
- function ee(t) {
216
- return typeof t == "string" && t.length > 0 && t.length <= 128 && he.test(t);
213
+ var ee = "x-correlation-id";
214
+ var we = /^[A-Za-z0-9._:\-]+$/;
215
+ function te(t) {
216
+ return typeof t == "string" && t.length > 0 && t.length <= 128 && we.test(t);
217
217
  }
218
- function ye() {
218
+ function ke() {
219
219
  let t = globalThis.crypto;
220
220
  try {
221
221
  if (t && typeof t.randomUUID == "function") return t.randomUUID();
222
222
  } catch {
223
223
  }
224
- let e = new Uint8Array(16), o = false;
224
+ let e = new Uint8Array(16), n = false;
225
225
  try {
226
- t && typeof t.getRandomValues == "function" && (t.getRandomValues(e), o = !0);
226
+ t && typeof t.getRandomValues == "function" && (t.getRandomValues(e), n = !0);
227
227
  } catch {
228
- o = false;
228
+ n = false;
229
229
  }
230
- if (!o)
231
- for (let i = 0; i < e.length; i++) e[i] = Math.floor(Math.random() * 256);
230
+ if (!n)
231
+ for (let a = 0; a < e.length; a++) e[a] = Math.floor(Math.random() * 256);
232
232
  e[6] = e[6] & 15 | 64, e[8] = e[8] & 63 | 128;
233
- let s = Array.from(e, (i) => i.toString(16).padStart(2, "0")).join("");
234
- return `${s.slice(0, 8)}-${s.slice(8, 12)}-${s.slice(12, 16)}-${s.slice(16, 20)}-${s.slice(20)}`;
233
+ let i = Array.from(e, (a) => a.toString(16).padStart(2, "0")).join("");
234
+ return `${i.slice(0, 8)}-${i.slice(8, 12)}-${i.slice(12, 16)}-${i.slice(16, 20)}-${i.slice(20)}`;
235
235
  }
236
236
  function K(t, e) {
237
- let o, s = {};
238
- for (let [p, m] of Object.entries(t)) {
239
- if (p.toLowerCase() === Q) {
240
- ee(m) && (o = m);
237
+ let n, i = {};
238
+ for (let [f, p] of Object.entries(t)) {
239
+ if (f.toLowerCase() === ee) {
240
+ te(p) && (n = p);
241
241
  continue;
242
242
  }
243
- s[p] = m;
243
+ i[f] = p;
244
244
  }
245
- let i = o ?? (ee(e) ? e : void 0) ?? ye();
246
- return s[Q] = i, { headers: s, correlationId: i };
245
+ let a = n ?? (te(e) ? e : void 0) ?? ke();
246
+ return i[ee] = a, { headers: i, correlationId: a };
247
247
  }
248
248
 
249
249
  // src/http.ts
250
- function te(t) {
250
+ function re(t) {
251
251
  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";
252
252
  }
253
253
 
254
+ // src/timeout.ts
255
+ function ne(t) {
256
+ let e = globalThis.AbortSignal;
257
+ if (typeof e?.timeout == "function")
258
+ return { signal: e.timeout(t), clear: () => {
259
+ } };
260
+ if (typeof globalThis.AbortController != "function")
261
+ return { signal: void 0, clear: () => {
262
+ } };
263
+ let n = new AbortController(), i = setTimeout(() => n.abort(), t);
264
+ return i.unref?.(), { signal: n.signal, clear: () => clearTimeout(i) };
265
+ }
266
+ function oe(t, e, n) {
267
+ let i, a = new Promise((f) => {
268
+ i = setTimeout(() => f(n()), e), i.unref?.();
269
+ });
270
+ return Promise.race([t, a]).finally(() => {
271
+ i !== void 0 && clearTimeout(i);
272
+ });
273
+ }
274
+
254
275
  // src/mobile.ts
255
- var k = "neetru_oauth_tx", U = "neetru_id_token", E = "neetru_refresh_token", C = "neetru_access_token", be = 3e4, we = "/api/v1/oauth/userinfo";
256
- function _e(t) {
276
+ var v = "neetru_oauth_tx", E = "neetru_id_token", U = "neetru_refresh_token", C = "neetru_access_token", ve = 3e4, Re = "/api/v1/oauth/userinfo";
277
+ function Se(t) {
257
278
  if (t === void 0 || t === "") return null;
258
279
  let e;
259
280
  try {
260
281
  e = new URL(t);
261
282
  } catch {
262
- throw new n("invalid_config", `productApiUrl inv\xE1lida: ${t}`);
283
+ throw new o("invalid_config", `productApiUrl inv\xE1lida: ${t}`);
263
284
  }
264
- let o = e.hostname === "localhost" || e.hostname === "127.0.0.1";
265
- if (e.protocol !== "https:" && !(e.protocol === "http:" && o))
266
- throw new n(
285
+ let n = e.hostname === "localhost" || e.hostname === "127.0.0.1";
286
+ if (e.protocol !== "https:" && !(e.protocol === "http:" && n))
287
+ throw new o(
267
288
  "invalid_config",
268
289
  "productApiUrl precisa ser https:// (http s\xF3 para localhost) \u2014 o access_token n\xE3o pode trafegar sem TLS."
269
290
  );
270
291
  return e;
271
292
  }
272
- function ke(t) {
293
+ function Te(t) {
273
294
  if (Z(t.apiKey), !t.storage)
274
- throw new n(
295
+ throw new o(
275
296
  "invalid_config",
276
297
  "createMobileAuthNamespace requer `storage` (MobileAuthStorage) \u2014 ver JSDoc de src/mobile.ts requisito 4."
277
298
  );
278
299
  if (typeof t.openAuthUrl != "function")
279
- throw new n(
300
+ throw new o(
280
301
  "invalid_config",
281
302
  "createMobileAuthNamespace requer `openAuthUrl` (browser externo, NUNCA WebView embutida) \u2014 ver JSDoc de src/mobile.ts requisito 3."
282
303
  );
283
304
  let e = t.fetch ?? globalThis.fetch;
284
305
  if (typeof e != "function")
285
- throw new n(
306
+ throw new o(
286
307
  "invalid_config",
287
308
  "fetch is not available in this runtime. Pass `fetch` explicitly to createMobileAuthNamespace."
288
309
  );
289
310
  if (typeof t.oidcClientId != "string" || t.oidcClientId.length === 0)
290
- throw new n(
311
+ throw new o(
291
312
  "invalid_config",
292
313
  "createMobileAuthNamespace requer `oidcClientId` \u2014 o client OIDC P\xDABLICO do app registrado no Core (a apiKey n\xE3o \xE9 aceita no app; ver requisito 6 no JSDoc de src/mobile.ts)."
293
314
  );
294
- let o = F(t.baseUrl ?? H, t.allowedHosts ?? []);
315
+ let n = z(t.baseUrl ?? B, t.allowedHosts ?? []);
295
316
  return {
296
317
  fetchImpl: e.bind(globalThis),
297
- baseUrl: o,
318
+ baseUrl: n,
298
319
  oidcClientId: t.oidcClientId,
299
- productApiUrl: _e(t.productApiUrl),
320
+ productApiUrl: Se(t.productApiUrl),
300
321
  storage: t.storage,
301
322
  openAuthUrl: t.openAuthUrl
302
323
  };
303
324
  }
304
- function ve(t) {
305
- let o = O(t)?.exp;
306
- return typeof o == "number" ? o * 1e3 : null;
325
+ function Ie(t) {
326
+ let n = L(t)?.exp;
327
+ return typeof n == "number" ? n * 1e3 : null;
307
328
  }
308
- async function re(t, e, o) {
309
- let s;
329
+ async function ie(t, e, n) {
330
+ let { signal: i, clear: a } = ne(15e3), f;
310
331
  try {
311
- s = await t(e, {
332
+ f = await t(e, {
312
333
  method: "POST",
313
334
  headers: { "content-type": "application/x-www-form-urlencoded" },
314
- body: o.toString()
335
+ body: n.toString(),
336
+ signal: i
315
337
  });
316
- } catch (p) {
317
- throw new n(
338
+ } catch (y) {
339
+ throw new o(
318
340
  "network_error",
319
- `POST ${e} falhou (network): ${p?.message ?? String(p)}`
341
+ `POST ${e} falhou (network): ${y?.message ?? String(y)}`
320
342
  );
343
+ } finally {
344
+ a();
321
345
  }
322
- let i = null;
346
+ let p = null;
323
347
  try {
324
- i = await s.json();
348
+ p = await f.json();
325
349
  } catch {
326
- i = null;
350
+ p = null;
327
351
  }
328
- if (!s.ok || typeof i?.error == "string") {
329
- let p = typeof i?.error_description == "string" && i.error_description || typeof i?.error == "string" && i.error || `HTTP ${s.status}`;
330
- throw new n(
352
+ if (!f.ok || typeof p?.error == "string") {
353
+ let y = typeof p?.error_description == "string" && p.error_description || typeof p?.error == "string" && p.error || `HTTP ${f.status}`;
354
+ throw new o(
331
355
  "token_exchange_failed",
332
- `Troca de tokens falhou no /token: ${p}`,
333
- s.status
356
+ `Troca de tokens falhou no /token: ${y}`,
357
+ f.status
334
358
  );
335
359
  }
336
- return i ?? {};
360
+ return p ?? {};
337
361
  }
338
- function je(t) {
339
- let e = ke(t), o = /* @__PURE__ */ new Set();
340
- function s() {
341
- return `${S(e.baseUrl)}${X}`;
362
+ function Ge(t) {
363
+ let e = Te(t), n = /* @__PURE__ */ new Set();
364
+ function i() {
365
+ return `${I(e.baseUrl)}${Y}`;
342
366
  }
343
- async function i() {
344
- let r = await h();
345
- for (let a of o)
367
+ async function a(r) {
368
+ let s = null;
369
+ if (r !== void 0)
370
+ s = r;
371
+ else
346
372
  try {
347
- a(r);
373
+ s = await h();
374
+ } catch {
375
+ s = null;
376
+ }
377
+ for (let l of n)
378
+ try {
379
+ l(s);
348
380
  } catch {
349
381
  }
350
382
  }
351
- async function p(r) {
383
+ async function f(r) {
352
384
  if (!r?.redirectUri)
353
- throw new n(
385
+ throw new o(
354
386
  "invalid_config",
355
387
  "mobile auth.signIn requer `redirectUri` (Universal Link/App Link https://... registrado no Core) \u2014 n\xE3o h\xE1 location.origin impl\xEDcito em React Native."
356
388
  );
357
- let a = V(), c = r.scope ?? "openid profile email", l = L(e), d = x(a, 16), u = x(a, 16), f = x(a, 32), g = await J(a, f), y = {
389
+ let s = W(), l = r.scope ?? "openid profile email", u = O(e), d = x(s, 16), c = x(s, 16), m = x(s, 32), g = await G(s, m), b = {
358
390
  state: d,
359
- nonce: u,
360
- codeVerifier: f,
391
+ nonce: c,
392
+ codeVerifier: m,
361
393
  redirectUri: r.redirectUri,
362
394
  postLoginRedirect: r.postLoginRedirect
363
395
  };
364
- await e.storage.setItem(k, JSON.stringify(y));
365
- let b = S(e.baseUrl), R = G({
366
- idpOrigin: b,
367
- clientId: l,
396
+ await e.storage.setItem(v, JSON.stringify(b));
397
+ let _ = I(e.baseUrl), S = X({
398
+ idpOrigin: _,
399
+ clientId: u,
368
400
  redirectUri: r.redirectUri,
369
- scope: c,
401
+ scope: l,
370
402
  state: d,
371
- nonce: u,
403
+ nonce: c,
372
404
  codeChallenge: g
373
405
  });
374
- await e.openAuthUrl(R.toString());
406
+ await e.openAuthUrl(S.toString());
375
407
  }
376
- async function m(r) {
408
+ async function p(r) {
377
409
  if (!r || typeof r != "string")
378
- throw new n(
410
+ throw new o(
379
411
  "invalid_config",
380
412
  "mobile auth.completeSignIn requer `callbackUrl` (a URL completa do deep link de retorno) \u2014 mobile n\xE3o tem location.href impl\xEDcito."
381
413
  );
382
- let a;
414
+ let s;
383
415
  try {
384
- a = new URL(r);
416
+ s = new URL(r);
385
417
  } catch {
386
- throw new n("invalid_config", `callbackUrl n\xE3o \xE9 uma URL v\xE1lida: ${r}`);
418
+ throw new o("invalid_config", `callbackUrl n\xE3o \xE9 uma URL v\xE1lida: ${r}`);
387
419
  }
388
- let c = a.searchParams, l = c.get("error");
389
- if (l) {
390
- let ce = c.get("error_description") ?? l;
391
- throw await e.storage.removeItem(k), new n(l, `OIDC authorize falhou: ${ce}`);
420
+ let l = s.searchParams, u = l.get("error");
421
+ if (u) {
422
+ let pe = l.get("error_description") ?? u;
423
+ throw await e.storage.removeItem(v), new o(u, `OIDC authorize falhou: ${pe}`);
392
424
  }
393
- let d = c.get("code");
425
+ let d = l.get("code");
394
426
  if (!d)
395
- throw await e.storage.removeItem(k), new n(
427
+ throw await e.storage.removeItem(v), new o(
396
428
  "invalid_config",
397
429
  "callbackUrl n\xE3o cont\xE9m `?code=` nem `?error=` \u2014 n\xE3o \xE9 um callback OIDC v\xE1lido."
398
430
  );
399
- let u = c.get("state"), f = await e.storage.getItem(k), g = null;
400
- if (f)
431
+ let c = l.get("state"), m = await e.storage.getItem(v), g = null;
432
+ if (m)
401
433
  try {
402
- g = JSON.parse(f);
434
+ g = JSON.parse(m);
403
435
  } catch {
404
436
  g = null;
405
437
  }
406
438
  if (!g)
407
- throw new n(
439
+ throw new o(
408
440
  "oidc_state_mismatch",
409
441
  "Callback OIDC sem transa\xE7\xE3o pendente \u2014 `signIn` n\xE3o foi iniciado (ou j\xE1 consumido)."
410
442
  );
411
- if (!u || u !== g.state)
412
- throw await e.storage.removeItem(k), new n(
443
+ if (!c || c !== g.state)
444
+ throw await e.storage.removeItem(v), new o(
413
445
  "oidc_state_mismatch",
414
446
  "state do callback OIDC n\xE3o confere com o da transa\xE7\xE3o (poss\xEDvel CSRF)."
415
447
  );
416
- await e.storage.removeItem(k);
417
- let y = L(e), b = new URLSearchParams({
448
+ await e.storage.removeItem(v);
449
+ let b = O(e), _ = new URLSearchParams({
418
450
  grant_type: "authorization_code",
419
451
  code: d,
420
452
  redirect_uri: g.redirectUri,
421
- client_id: y,
453
+ client_id: b,
422
454
  code_verifier: g.codeVerifier
423
- }), R = await re(e.fetchImpl, s(), b), A = R.id_token;
424
- if (typeof A != "string" || A.length === 0)
425
- throw new n(
455
+ }), S = await ie(e.fetchImpl, i(), _), T = S.id_token;
456
+ if (typeof T != "string" || T.length === 0)
457
+ throw new o(
426
458
  "token_exchange_failed",
427
459
  "Resposta do /token sem `id_token` \u2014 o login n\xE3o pode ser completado."
428
460
  );
429
- let $ = O(A);
430
- if (!$)
431
- throw new n(
461
+ let q = L(T);
462
+ if (!q)
463
+ throw new o(
432
464
  "token_exchange_failed",
433
465
  "id_token retornado pelo /token \xE9 malformado (payload indecodific\xE1vel)."
434
466
  );
435
- if ($.nonce !== g.nonce)
436
- throw new n(
467
+ if (q.nonce !== g.nonce)
468
+ throw new o(
437
469
  "oidc_nonce_mismatch",
438
470
  "nonce do id_token n\xE3o confere com o da transa\xE7\xE3o OIDC (poss\xEDvel replay). Token descartado."
439
471
  );
440
- let q = T(A);
441
- if (!q)
442
- throw new n(
472
+ let H = A(T);
473
+ if (!H)
474
+ throw new o(
443
475
  "token_exchange_failed",
444
476
  "id_token retornado pelo /token n\xE3o tem `sub` ou j\xE1 est\xE1 expirado."
445
477
  );
446
- await e.storage.setItem(U, A);
447
- let M = R.refresh_token;
448
- return typeof M == "string" && M.length > 0 && await e.storage.setItem(E, M), await w(R.access_token), await i(), { user: q, postLoginRedirect: g.postLoginRedirect };
478
+ await e.storage.setItem(E, T);
479
+ let M = S.refresh_token;
480
+ return typeof M == "string" && M.length > 0 && await e.storage.setItem(U, M), await w(S.access_token), await a(), { user: H, postLoginRedirect: g.postLoginRedirect };
449
481
  }
450
- async function I() {
451
- let r = await e.storage.getItem(U);
452
- return r && T(r) ? r : null;
482
+ async function y() {
483
+ let r = await e.storage.getItem(E);
484
+ return r && A(r) ? r : null;
453
485
  }
454
486
  async function h() {
455
- let r = await e.storage.getItem(U);
456
- return r ? T(r) : null;
487
+ let r = await e.storage.getItem(E);
488
+ return r ? A(r) : null;
457
489
  }
458
490
  async function w(r) {
459
491
  typeof r == "string" && r.length > 0 ? await e.storage.setItem(C, r) : await e.storage.removeItem(C);
460
492
  }
461
- let _ = null;
493
+ let k = null;
462
494
  function N() {
463
- return _ || (_ = ne().finally(() => {
464
- _ = null;
465
- }), _);
495
+ if (k) return k;
496
+ let r = { abandoned: false };
497
+ return k = oe(ae(r), 15e3, () => (r.abandoned = true, false)).finally(() => {
498
+ k = null;
499
+ }), k;
466
500
  }
467
- async function ne() {
468
- let r = await e.storage.getItem(E);
469
- if (!r) return false;
470
- let a;
501
+ async function ae(r = { abandoned: false }) {
502
+ let s = await e.storage.getItem(U);
503
+ if (!s) return false;
504
+ let l;
471
505
  try {
472
- a = L(e);
506
+ l = O(e);
473
507
  } catch {
474
508
  return false;
475
509
  }
476
- let c = new URLSearchParams({
510
+ let u = new URLSearchParams({
477
511
  grant_type: "refresh_token",
478
- refresh_token: r,
479
- client_id: a
480
- }), l;
512
+ refresh_token: s,
513
+ client_id: l
514
+ }), d;
481
515
  try {
482
- l = await re(e.fetchImpl, s(), c);
516
+ d = await ie(e.fetchImpl, i(), u);
483
517
  } catch {
484
518
  return false;
485
519
  }
486
- let d = l.id_token;
487
- if (typeof d != "string" || d.length === 0 || !T(d)) return false;
488
- await e.storage.setItem(U, d);
489
- let f = l.refresh_token;
490
- return typeof f == "string" && f.length > 0 && await e.storage.setItem(E, f), await w(l.access_token), await i(), true;
520
+ let c = d.id_token;
521
+ if (typeof c != "string" || c.length === 0 || !A(c) || r.abandoned) return false;
522
+ await e.storage.setItem(E, c);
523
+ let g = d.refresh_token;
524
+ return typeof g == "string" && g.length > 0 && await e.storage.setItem(U, g), await w(d.access_token), await a(), true;
491
525
  }
492
526
  async function P() {
493
527
  let r = await e.storage.getItem(C);
494
528
  if (!r) return null;
495
- let a = ve(r);
496
- return a === null || a - be <= Date.now() ? null : r;
529
+ let s = Ie(r);
530
+ return s === null || s - ve <= Date.now() ? null : r;
497
531
  }
498
532
  async function D() {
499
533
  let r = await P();
500
534
  return r || (await N() ? P() : null);
501
535
  }
502
- async function oe() {
503
- let r = `${S(e.baseUrl)}${we}`, a = async (f) => {
504
- let { headers: g, correlationId: y } = K({
536
+ async function ce() {
537
+ let r = `${I(e.baseUrl)}${Re}`, s = async (m) => {
538
+ let { headers: g, correlationId: b } = K({
505
539
  accept: "application/json",
506
- authorization: `Bearer ${f}`
540
+ authorization: `Bearer ${m}`
507
541
  });
508
542
  try {
509
- return { res: await e.fetchImpl(r, { method: "GET", headers: g }), correlationId: y };
510
- } catch (b) {
511
- throw new n(
543
+ return { res: await e.fetchImpl(r, { method: "GET", headers: g }), correlationId: b };
544
+ } catch (_) {
545
+ throw new o(
512
546
  "network_error",
513
- `GET ${r} falhou (network): ${b?.message ?? String(b)}`,
547
+ `GET ${r} falhou (network): ${_?.message ?? String(_)}`,
514
548
  void 0,
515
549
  void 0,
516
550
  void 0,
517
- y
551
+ b
518
552
  );
519
553
  }
520
- }, c = await D();
521
- if (!c)
522
- throw new v(
554
+ }, l = await D();
555
+ if (!l)
556
+ throw new R(
523
557
  "Sem sess\xE3o: fa\xE7a login (auth.signIn) antes de consultar o userinfo.",
524
558
  "no_signed_in_user"
525
559
  );
526
- let { res: l, correlationId: d } = await a(c);
527
- if (l.status === 401 && await N() && (c = await P(), c && ({ res: l, correlationId: d } = await a(c))), l.status === 401)
528
- throw new v(
560
+ let { res: u, correlationId: d } = await s(l);
561
+ if (u.status === 401 && await N() && (l = await P(), l && ({ res: u, correlationId: d } = await s(l))), u.status === 401)
562
+ throw new R(
529
563
  "O Core recusou a sess\xE3o (token revogado/expirado ou usu\xE1rio inativo). Fa\xE7a login novamente.",
530
564
  "invalid_access_token",
531
565
  401,
532
566
  void 0,
533
567
  d
534
568
  );
535
- let u;
569
+ let c;
536
570
  try {
537
- u = await l.json();
571
+ c = await u.json();
538
572
  } catch {
539
- u = void 0;
573
+ c = void 0;
540
574
  }
541
- if (!l.ok) {
542
- let f = u && typeof u == "object" && typeof u.error_description == "string" ? u.error_description : `HTTP ${l.status}`;
543
- throw new n(te(l.status), `userinfo falhou: ${f}`, l.status, void 0, void 0, d);
575
+ if (!u.ok) {
576
+ let m = c && typeof c == "object" && typeof c.error_description == "string" ? c.error_description : `HTTP ${u.status}`;
577
+ throw new o(re(u.status), `userinfo falhou: ${m}`, u.status, void 0, void 0, d);
544
578
  }
545
- if (!u || typeof u != "object" || typeof u.sub != "string")
546
- throw new n("invalid_response", "userinfo sem `sub`.", l.status, void 0, void 0, d);
547
- return u;
579
+ if (!c || typeof c != "object" || typeof c.sub != "string")
580
+ throw new o("invalid_response", "userinfo sem `sub`.", u.status, void 0, void 0, d);
581
+ return c;
548
582
  }
549
- function ie(r) {
550
- let a = e.productApiUrl;
551
- if (!a)
552
- throw new n(
583
+ function le(r) {
584
+ let s = e.productApiUrl;
585
+ if (!s)
586
+ throw new o(
553
587
  "invalid_config",
554
588
  "auth.authFetch requer `productApiUrl` (URL da API do seu produto) no createMobileAuthNamespace."
555
589
  );
556
- let c;
590
+ let l;
557
591
  if (/^[a-z][a-z0-9+.-]*:/i.test(r))
558
592
  try {
559
- c = new URL(r);
593
+ l = new URL(r);
560
594
  } catch {
561
- throw new n("invalid_config", `URL inv\xE1lida: ${r}`);
595
+ throw new o("invalid_config", `URL inv\xE1lida: ${r}`);
562
596
  }
563
597
  else {
564
- let l = a.pathname.replace(/\/+$/, ""), d = r.startsWith("/") ? r : `/${r}`;
565
- c = new URL(`${a.origin}${l}${d}`);
598
+ let u = s.pathname.replace(/\/+$/, ""), d = r.startsWith("/") ? r : `/${r}`;
599
+ l = new URL(`${s.origin}${u}${d}`);
566
600
  }
567
- if (c.origin !== a.origin)
568
- throw new n(
601
+ if (l.origin !== s.origin)
602
+ throw new o(
569
603
  "invalid_config",
570
- `auth.authFetch s\xF3 envia o access_token para a API do produto (${a.origin}); recusado: ${c.origin}.`
604
+ `auth.authFetch s\xF3 envia o access_token para a API do produto (${s.origin}); recusado: ${l.origin}.`
571
605
  );
572
- return c.toString();
606
+ return l.toString();
573
607
  }
574
- async function se(r, a = {}) {
575
- let c = ie(r), l = {};
576
- new Headers(a.headers ?? {}).forEach((y, b) => {
577
- l[b] = y;
608
+ async function ue(r, s = {}) {
609
+ let l = le(r), u = {};
610
+ new Headers(s.headers ?? {}).forEach((b, _) => {
611
+ u[_] = b;
578
612
  });
579
- let d = (y) => {
580
- let { headers: b } = K({ ...l, authorization: `Bearer ${y}` });
581
- return e.fetchImpl(c, { ...a, headers: b });
582
- }, u = await D();
583
- if (!u)
584
- throw new v(
613
+ let d = (b) => {
614
+ let { headers: _ } = K({ ...u, authorization: `Bearer ${b}` });
615
+ return e.fetchImpl(l, { ...s, headers: _ });
616
+ }, c = await D();
617
+ if (!c)
618
+ throw new R(
585
619
  "Sem sess\xE3o: fa\xE7a login (auth.signIn) antes de chamar a API do produto.",
586
620
  "no_signed_in_user"
587
621
  );
588
- let f = await d(u), g = a.body === void 0 || a.body === null || typeof a.body == "string";
589
- return f.status === 401 && g && await N() && (u = await P(), u && (f = await d(u))), f;
622
+ let m = await d(c), g = s.body === void 0 || s.body === null || typeof s.body == "string";
623
+ return m.status === 401 && g && await N() && (c = await P(), c && (m = await d(c))), m;
624
+ }
625
+ async function $(r) {
626
+ try {
627
+ return await e.storage.getItem(r);
628
+ } catch {
629
+ return null;
630
+ }
590
631
  }
591
- async function ae() {
592
- let r = await e.storage.getItem(E), a = await e.storage.getItem(C);
593
- await e.storage.removeItem(U), await e.storage.removeItem(E), await e.storage.removeItem(C), await e.storage.removeItem(k);
594
- let c = [];
595
- r && c.push({ token: r, hint: "refresh_token" }), a && c.push({ token: a, hint: "access_token" }), c.length > 0 && !await Y(
596
- e.fetchImpl,
597
- S(e.baseUrl),
598
- e.oidcClientId,
599
- c
600
- ) && typeof console < "u" && console.warn(
601
- "[neetru-sdk] mobile signOut: a revoga\xE7\xE3o no servidor n\xE3o foi confirmada. A sess\xE3o local foi encerrada, mas o refresh_token pode seguir v\xE1lido at\xE9 expirar."
602
- ), await i();
632
+ async function de() {
633
+ let r = await $(U), s = await $(C), l = true;
634
+ for (let c of [E, U, C, v])
635
+ try {
636
+ await e.storage.removeItem(c);
637
+ } catch {
638
+ l = false;
639
+ }
640
+ let u = [];
641
+ r && u.push({ token: r, hint: "refresh_token" }), s && u.push({ token: s, hint: "access_token" });
642
+ let d = "skipped";
643
+ if (u.length > 0) {
644
+ let c = await Q(
645
+ e.fetchImpl,
646
+ I(e.baseUrl),
647
+ e.oidcClientId,
648
+ u
649
+ );
650
+ d = c ? "accepted" : "failed", !c && typeof console < "u" && console.warn(
651
+ "[neetru-sdk] mobile signOut: a revoga\xE7\xE3o no servidor n\xE3o foi confirmada. A sess\xE3o local foi encerrada, mas o refresh_token pode seguir v\xE1lido at\xE9 expirar. Trate o campo remoteRevocation do SignOutResult no produto."
652
+ );
653
+ }
654
+ return await a(null), { localSessionCleared: l, remoteRevocation: d };
603
655
  }
604
656
  return {
605
- signIn: p,
606
- completeSignIn: m,
607
- getIdToken: I,
657
+ signIn: f,
658
+ completeSignIn: p,
659
+ getIdToken: y,
608
660
  getAccessToken: D,
609
- getUserInfo: oe,
610
- authFetch: se,
661
+ getUserInfo: ce,
662
+ authFetch: ue,
611
663
  getUser: h,
612
664
  onAuthStateChanged(r) {
613
- return o.add(r), h().then((a) => {
614
- if (o.has(r))
665
+ return n.add(r), h().then((s) => {
666
+ if (n.has(r))
615
667
  try {
616
- r(a);
668
+ r(s);
617
669
  } catch {
618
670
  }
619
671
  }), () => {
620
- o.delete(r);
672
+ n.delete(r);
621
673
  };
622
674
  },
623
675
  refreshTokens: N,
624
- signOut: ae
676
+ signOut: de
625
677
  };
626
678
  }
627
679
 
628
- export { je as createMobileAuthNamespace };
680
+ export { Ge as createMobileAuthNamespace };