@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
package/dist/mobile.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/errors.ts
2
- var NeetruError = class _NeetruError extends Error {
2
+ var r = class t extends Error {
3
3
  code;
4
4
  status;
5
5
  requestId;
@@ -12,502 +12,398 @@ 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(code, message, status, requestId, reason) {
16
- super(message);
17
- this.name = "NeetruError";
18
- this.code = code;
19
- this.status = status;
20
- this.requestId = requestId;
21
- this.reason = reason;
22
- Object.setPrototypeOf(this, _NeetruError.prototype);
15
+ constructor(e, i, s, o, l) {
16
+ super(i), this.name = "NeetruError", this.code = e, this.status = s, this.requestId = o, this.reason = l, Object.setPrototypeOf(this, t.prototype);
23
17
  }
24
18
  };
25
19
 
26
20
  // src/types.ts
27
- var DEFAULT_BASE_URL = "https://api.neetru.com";
21
+ var L = "https://api.neetru.com";
28
22
 
29
23
  // src/base-url-allowlist.ts
30
- var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]", "::1"]);
31
- var NEETRU_SUFFIX = ".neetru.com";
32
- var NEETRU_APEX = "neetru.com";
33
- var SAFE_DEV_HOST_RE = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?\.(test|localhost)$/;
34
- function isSafeDevHost(hostname) {
35
- return SAFE_DEV_HOST_RE.test(hostname);
24
+ var O = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]", "::1"]), F = ".neetru.com", J = "neetru.com", Y = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?\.(test|localhost)$/;
25
+ function D(t) {
26
+ return Y.test(t);
36
27
  }
37
- function normalizeHostname(hostname) {
38
- return hostname.toLowerCase().replace(/\.+$/, "");
28
+ function X(t) {
29
+ return t.toLowerCase().replace(/\.+$/, "");
39
30
  }
40
- function validateBaseUrl(baseUrl, allowedHosts = []) {
41
- if (typeof baseUrl !== "string" || baseUrl.length === 0) {
42
- throw new NeetruError("invalid_config", "baseUrl is required");
43
- }
44
- let parsed;
31
+ function M(t, e = []) {
32
+ if (typeof t != "string" || t.length === 0)
33
+ throw new r("invalid_config", "baseUrl is required");
34
+ let i;
45
35
  try {
46
- parsed = new URL(baseUrl);
36
+ i = new URL(t);
47
37
  } catch {
48
- throw new NeetruError("invalid_config", `baseUrl is not a valid URL: ${baseUrl}`);
38
+ throw new r("invalid_config", `baseUrl is not a valid URL: ${t}`);
49
39
  }
50
- const protocol = parsed.protocol;
51
- const hostname = normalizeHostname(parsed.hostname);
52
- if (isInsecureBypassActive()) {
53
- if (typeof console !== "undefined") {
54
- console.warn(
55
- `[neetru-sdk] NEETRU_ALLOW_INSECURE_BASEURL=1 ativo. baseUrl=${baseUrl} aceito sem valida\xE7\xE3o.`
56
- );
57
- }
58
- return baseUrl.replace(/\/+$/, "");
59
- }
60
- if (protocol !== "https:" && protocol !== "http:") {
61
- throw new NeetruError(
40
+ let s = i.protocol, o = X(i.hostname);
41
+ if (Z())
42
+ return typeof console < "u" && console.warn(
43
+ `[neetru-sdk] NEETRU_ALLOW_INSECURE_BASEURL=1 ativo. baseUrl=${t} aceito sem valida\xE7\xE3o.`
44
+ ), t.replace(/\/+$/, "");
45
+ if (s !== "https:" && s !== "http:")
46
+ throw new r(
62
47
  "invalid_config",
63
- `baseUrl protocol must be http: or https:, got ${protocol}`
48
+ `baseUrl protocol must be http: or https:, got ${s}`
64
49
  );
65
- }
66
- if (protocol === "http:") {
67
- const isLoopback = LOOPBACK_HOSTS.has(hostname) || isSafeDevHost(hostname);
68
- if (!isLoopback) {
69
- throw new NeetruError(
50
+ if (s === "http:") {
51
+ if (!(O.has(o) || D(o)))
52
+ throw new r(
70
53
  "invalid_config",
71
- `baseUrl with http: only allowed for localhost/127.0.0.1/*.test/*.localhost. Got: ${hostname}. Use https: or set NEETRU_ALLOW_INSECURE_BASEURL=1 to bypass.`
54
+ `baseUrl with http: only allowed for localhost/127.0.0.1/*.test/*.localhost. Got: ${o}. Use https: or set NEETRU_ALLOW_INSECURE_BASEURL=1 to bypass.`
72
55
  );
73
- }
74
- return baseUrl.replace(/\/+$/, "");
56
+ return t.replace(/\/+$/, "");
75
57
  }
76
- const isNeetruDomain = hostname === NEETRU_APEX || hostname.endsWith(NEETRU_SUFFIX);
77
- const isAllowedHost = allowedHosts.some((allowed) => {
78
- const norm = allowed.toLowerCase();
79
- return hostname === norm || hostname.endsWith(`.${norm}`);
80
- });
81
- const isLoopbackHttps = LOOPBACK_HOSTS.has(hostname) || isSafeDevHost(hostname);
82
- if (!isNeetruDomain && !isAllowedHost && !isLoopbackHttps) {
83
- throw new NeetruError(
58
+ let l = o === J || o.endsWith(F), A = e.some((m) => {
59
+ let k = m.toLowerCase();
60
+ return o === k || o.endsWith(`.${k}`);
61
+ }), R = O.has(o) || D(o);
62
+ if (!l && !A && !R)
63
+ throw new r(
84
64
  "invalid_config",
85
- `baseUrl ${hostname} is not in the allowlist. Allowed: *.neetru.com, localhost, or configure { allowedHosts: ['...'] }. Bypass: NEETRU_ALLOW_INSECURE_BASEURL=1.`
65
+ `baseUrl ${o} is not in the allowlist. Allowed: *.neetru.com, localhost, or configure { allowedHosts: ['...'] }. Bypass: NEETRU_ALLOW_INSECURE_BASEURL=1.`
86
66
  );
87
- }
88
- return baseUrl.replace(/\/+$/, "");
67
+ return t.replace(/\/+$/, "");
89
68
  }
90
- function isInsecureBypassActive() {
69
+ function Z() {
91
70
  try {
92
- const proc = globalThis.process;
93
- const envVal = proc?.env?.NEETRU_ALLOW_INSECURE_BASEURL;
94
- if (envVal === "1" || envVal === "true") return true;
71
+ let e = globalThis.process?.env?.NEETRU_ALLOW_INSECURE_BASEURL;
72
+ if (e === "1" || e === "true") return !0;
95
73
  } catch {
96
74
  }
97
75
  try {
98
- const g = globalThis.NEETRU_ALLOW_INSECURE_BASEURL;
99
- if (g === "1" || g === "true" || g === true) return true;
76
+ let t = globalThis.NEETRU_ALLOW_INSECURE_BASEURL;
77
+ if (t === "1" || t === "true" || t === !0) return !0;
100
78
  } catch {
101
79
  }
102
80
  return false;
103
81
  }
104
82
 
105
83
  // src/api-key.ts
106
- var API_KEY_RE = /^nrt_([A-Za-z0-9]+)_([A-Za-z0-9]+)$/;
107
- function parseApiKey(apiKey) {
108
- if (typeof apiKey !== "string" || apiKey.length === 0) {
109
- throw new NeetruError(
84
+ var G = /^nrt_([A-Za-z0-9]+)_([A-Za-z0-9]+)$/;
85
+ function K(t) {
86
+ if (typeof t != "string" || t.length === 0)
87
+ throw new r(
110
88
  "invalid_config",
111
89
  "apiKey is required (formato nrt_<keyId>_<secret>)"
112
90
  );
113
- }
114
- const match = API_KEY_RE.exec(apiKey);
115
- if (!match) {
116
- throw new NeetruError(
91
+ let e = G.exec(t);
92
+ if (!e)
93
+ throw new r(
117
94
  "invalid_config",
118
95
  "apiKey malformado - esperado formato nrt_<keyId>_<secret>"
119
96
  );
120
- }
121
- return { keyId: match[1], secret: match[2] };
97
+ return { keyId: e[1], secret: e[2] };
122
98
  }
123
99
 
124
100
  // src/auth-pkce-shared.ts
125
- function getWebCrypto() {
126
- const c = globalThis.crypto;
127
- if (!c || typeof c.getRandomValues !== "function" || !c.subtle) {
128
- throw new NeetruError(
101
+ function H() {
102
+ let t = globalThis.crypto;
103
+ if (!t || typeof t.getRandomValues != "function" || !t.subtle)
104
+ throw new r(
129
105
  "runtime_unsupported",
130
106
  "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."
131
107
  );
132
- }
133
- return c;
108
+ return t;
134
109
  }
135
- function base64UrlFromBytes(bytes) {
136
- let str = "";
137
- for (const b of bytes) str += String.fromCharCode(b);
138
- const b64 = typeof btoa === "function" ? btoa(str) : Buffer.from(str, "binary").toString("base64");
139
- return b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
110
+ function $(t) {
111
+ let e = "";
112
+ for (let s of t) e += String.fromCharCode(s);
113
+ return (typeof btoa == "function" ? btoa(e) : Buffer.from(e, "binary").toString("base64")).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
140
114
  }
141
- function randomUrlSafe(crypto, byteLen) {
142
- const bytes = new Uint8Array(byteLen);
143
- crypto.getRandomValues(bytes);
144
- return base64UrlFromBytes(bytes);
115
+ function v(t, e) {
116
+ let i = new Uint8Array(e);
117
+ return t.getRandomValues(i), $(i);
145
118
  }
146
- async function pkceChallengeS256(crypto, verifier) {
147
- const data = new TextEncoder().encode(verifier);
148
- const digest = await crypto.subtle.digest("SHA-256", data);
149
- return base64UrlFromBytes(new Uint8Array(digest));
119
+ async function B(t, e) {
120
+ let i = new TextEncoder().encode(e), s = await t.subtle.digest("SHA-256", i);
121
+ return $(new Uint8Array(s));
150
122
  }
151
- function resolveIdpOrigin(baseUrl) {
152
- const overrideAuthUrl = typeof globalThis.NEETRU_AUTH_URL === "string" ? globalThis.NEETRU_AUTH_URL : null;
153
- return overrideAuthUrl ?? baseUrl.replace(/^https?:\/\/api\./, "https://auth.");
123
+ function U(t) {
124
+ return (typeof globalThis.NEETRU_AUTH_URL == "string" ? globalThis.NEETRU_AUTH_URL : null) ?? t.replace(/^https?:\/\/api\./, "https://auth.");
154
125
  }
155
- function resolveOidcClientId(config) {
156
- let clientId = config.oidcClientId;
157
- if (!clientId && config.apiKey) {
158
- clientId = parseApiKey(config.apiKey).keyId;
159
- }
160
- if (!clientId) {
161
- throw new NeetruError(
126
+ function I(t) {
127
+ let e = t.oidcClientId;
128
+ if (!e && t.apiKey && (e = K(t.apiKey).keyId), !e)
129
+ throw new r(
162
130
  "invalid_config",
163
131
  "auth OIDC requer `oidcClientId` (ou `apiKey`) configurado para montar o client_id."
164
132
  );
165
- }
166
- return clientId;
133
+ return e;
167
134
  }
168
- function buildAuthorizeUrl(params) {
169
- const url = new URL("/api/v1/oauth/authorize", params.idpOrigin);
170
- url.searchParams.set("response_type", "code");
171
- url.searchParams.set("client_id", params.clientId);
172
- url.searchParams.set("redirect_uri", params.redirectUri);
173
- url.searchParams.set("scope", params.scope);
174
- url.searchParams.set("state", params.state);
175
- url.searchParams.set("nonce", params.nonce);
176
- url.searchParams.set("code_challenge", params.codeChallenge);
177
- url.searchParams.set("code_challenge_method", "S256");
178
- return url;
135
+ function q(t) {
136
+ let e = new URL("/api/v1/oauth/authorize", t.idpOrigin);
137
+ 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;
179
138
  }
180
- var OAUTH_TOKEN_PATH = "/api/v1/oauth/token";
181
- function decodeJwtPayload(token) {
182
- const parts = token.split(".");
183
- if (parts.length !== 3) return null;
139
+ var W = "/api/v1/oauth/token";
140
+ function N(t) {
141
+ let e = t.split(".");
142
+ if (e.length !== 3) return null;
184
143
  try {
185
- const b64 = parts[1].replace(/-/g, "+").replace(/_/g, "/");
186
- const pad = "=".repeat((4 - b64.length % 4) % 4);
187
- const decoded = typeof atob === "function" ? atob(b64 + pad) : Buffer.from(b64 + pad, "base64").toString("utf-8");
188
- return JSON.parse(decoded);
144
+ let i = e[1].replace(/-/g, "+").replace(/_/g, "/"), s = "=".repeat((4 - i.length % 4) % 4), o = typeof atob == "function" ? atob(i + s) : Buffer.from(i + s, "base64").toString("utf-8");
145
+ return JSON.parse(o);
189
146
  } catch {
190
147
  return null;
191
148
  }
192
149
  }
193
- function jwtToNeetruUser(token) {
194
- const payload = decodeJwtPayload(token);
195
- if (!payload || typeof payload.sub !== "string") return null;
196
- if (typeof payload.exp === "number" && payload.exp * 1e3 < Date.now()) {
197
- return null;
198
- }
199
- return {
200
- uid: payload.sub,
201
- email: typeof payload.email === "string" ? payload.email : "",
202
- emailVerified: typeof payload.email_verified === "boolean" ? payload.email_verified : void 0,
203
- displayName: typeof payload.name === "string" ? payload.name : void 0,
204
- photoURL: typeof payload.picture === "string" ? payload.picture : void 0,
205
- isStaff: payload.is_staff === true,
206
- isCustomer: payload.is_customer === true,
207
- tenantId: typeof payload.tenant_id === "string" ? payload.tenant_id : void 0,
208
- ...payload
150
+ function _(t) {
151
+ let e = N(t);
152
+ return !e || typeof e.sub != "string" || typeof e.exp == "number" && e.exp * 1e3 < Date.now() ? null : {
153
+ uid: e.sub,
154
+ email: typeof e.email == "string" ? e.email : "",
155
+ emailVerified: typeof e.email_verified == "boolean" ? e.email_verified : void 0,
156
+ displayName: typeof e.name == "string" ? e.name : void 0,
157
+ photoURL: typeof e.picture == "string" ? e.picture : void 0,
158
+ isStaff: e.is_staff === true,
159
+ isCustomer: e.is_customer === true,
160
+ tenantId: typeof e.tenant_id == "string" ? e.tenant_id : void 0,
161
+ ...e
209
162
  };
210
163
  }
211
164
 
212
165
  // src/mobile.ts
213
- var OIDC_TX_KEY = "neetru_oauth_tx";
214
- var ID_TOKEN_KEY = "neetru_id_token";
215
- var REFRESH_TOKEN_KEY = "neetru_refresh_token";
216
- function resolveMobileConfig(config) {
217
- if (!config.storage) {
218
- throw new NeetruError(
166
+ var h = "neetru_oauth_tx", y = "neetru_id_token", S = "neetru_refresh_token";
167
+ function Q(t) {
168
+ if (!t.storage)
169
+ throw new r(
219
170
  "invalid_config",
220
171
  "createMobileAuthNamespace requer `storage` (MobileAuthStorage) \u2014 ver JSDoc de src/mobile.ts requisito 4."
221
172
  );
222
- }
223
- if (typeof config.openAuthUrl !== "function") {
224
- throw new NeetruError(
173
+ if (typeof t.openAuthUrl != "function")
174
+ throw new r(
225
175
  "invalid_config",
226
176
  "createMobileAuthNamespace requer `openAuthUrl` (browser externo, NUNCA WebView embutida) \u2014 ver JSDoc de src/mobile.ts requisito 3."
227
177
  );
228
- }
229
- const fetchImpl = config.fetch ?? globalThis.fetch;
230
- if (typeof fetchImpl !== "function") {
231
- throw new NeetruError(
178
+ let e = t.fetch ?? globalThis.fetch;
179
+ if (typeof e != "function")
180
+ throw new r(
232
181
  "invalid_config",
233
182
  "fetch is not available in this runtime. Pass `fetch` explicitly to createMobileAuthNamespace."
234
183
  );
235
- }
236
- const baseUrl = validateBaseUrl(config.baseUrl ?? DEFAULT_BASE_URL, config.allowedHosts ?? []);
184
+ let i = M(t.baseUrl ?? L, t.allowedHosts ?? []);
237
185
  return {
238
- fetchImpl: fetchImpl.bind(globalThis),
239
- baseUrl,
240
- oidcClientId: config.oidcClientId,
241
- apiKey: config.apiKey,
242
- storage: config.storage,
243
- openAuthUrl: config.openAuthUrl
186
+ fetchImpl: e.bind(globalThis),
187
+ baseUrl: i,
188
+ oidcClientId: t.oidcClientId,
189
+ apiKey: t.apiKey,
190
+ storage: t.storage,
191
+ openAuthUrl: t.openAuthUrl
244
192
  };
245
193
  }
246
- async function postToken(fetchImpl, tokenUrl, form) {
247
- let res;
194
+ async function z(t, e, i) {
195
+ let s;
248
196
  try {
249
- res = await fetchImpl(tokenUrl, {
197
+ s = await t(e, {
250
198
  method: "POST",
251
199
  headers: { "content-type": "application/x-www-form-urlencoded" },
252
- body: form.toString()
200
+ body: i.toString()
253
201
  });
254
- } catch (err) {
255
- throw new NeetruError(
202
+ } catch (l) {
203
+ throw new r(
256
204
  "network_error",
257
- `POST ${tokenUrl} falhou (network): ${err?.message ?? String(err)}`
205
+ `POST ${e} falhou (network): ${l?.message ?? String(l)}`
258
206
  );
259
207
  }
260
- let payload = null;
208
+ let o = null;
261
209
  try {
262
- payload = await res.json();
210
+ o = await s.json();
263
211
  } catch {
264
- payload = null;
212
+ o = null;
265
213
  }
266
- if (!res.ok || typeof payload?.error === "string") {
267
- const desc = typeof payload?.error_description === "string" && payload.error_description || typeof payload?.error === "string" && payload.error || `HTTP ${res.status}`;
268
- throw new NeetruError(
214
+ if (!s.ok || typeof o?.error == "string") {
215
+ let l = typeof o?.error_description == "string" && o.error_description || typeof o?.error == "string" && o.error || `HTTP ${s.status}`;
216
+ throw new r(
269
217
  "token_exchange_failed",
270
- `Troca de tokens falhou no /token: ${desc}`,
271
- res.status
218
+ `Troca de tokens falhou no /token: ${l}`,
219
+ s.status
272
220
  );
273
221
  }
274
- return payload ?? {};
222
+ return o ?? {};
275
223
  }
276
- function createMobileAuthNamespace(config) {
277
- const resolved = resolveMobileConfig(config);
278
- const listeners = /* @__PURE__ */ new Set();
279
- function tokenUrl() {
280
- return `${resolveIdpOrigin(resolved.baseUrl)}${OAUTH_TOKEN_PATH}`;
224
+ function ge(t) {
225
+ let e = Q(t), i = /* @__PURE__ */ new Set();
226
+ function s() {
227
+ return `${U(e.baseUrl)}${W}`;
281
228
  }
282
- async function notify() {
283
- const user = await getUser();
284
- for (const l of listeners) {
229
+ async function o() {
230
+ let n = await m();
231
+ for (let a of i)
285
232
  try {
286
- l(user);
233
+ a(n);
287
234
  } catch {
288
235
  }
289
- }
290
236
  }
291
- async function signIn(options) {
292
- if (!options?.redirectUri) {
293
- throw new NeetruError(
237
+ async function l(n) {
238
+ if (!n?.redirectUri)
239
+ throw new r(
294
240
  "invalid_config",
295
241
  "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."
296
242
  );
297
- }
298
- const crypto = getWebCrypto();
299
- const scope = options.scope ?? "openid profile email";
300
- const clientId = resolveOidcClientId(resolved);
301
- const state = randomUrlSafe(crypto, 16);
302
- const nonce = randomUrlSafe(crypto, 16);
303
- const codeVerifier = randomUrlSafe(crypto, 32);
304
- const codeChallenge = await pkceChallengeS256(crypto, codeVerifier);
305
- const tx = {
306
- state,
307
- nonce,
308
- codeVerifier,
309
- redirectUri: options.redirectUri,
310
- postLoginRedirect: options.postLoginRedirect
243
+ let a = H(), u = n.scope ?? "openid profile email", c = I(e), d = v(a, 16), f = v(a, 16), g = v(a, 32), p = await B(a, g), T = {
244
+ state: d,
245
+ nonce: f,
246
+ codeVerifier: g,
247
+ redirectUri: n.redirectUri,
248
+ postLoginRedirect: n.postLoginRedirect
311
249
  };
312
- await resolved.storage.setItem(OIDC_TX_KEY, JSON.stringify(tx));
313
- const idpOrigin = resolveIdpOrigin(resolved.baseUrl);
314
- const url = buildAuthorizeUrl({
315
- idpOrigin,
316
- clientId,
317
- redirectUri: options.redirectUri,
318
- scope,
319
- state,
320
- nonce,
321
- codeChallenge
250
+ await e.storage.setItem(h, JSON.stringify(T));
251
+ let C = U(e.baseUrl), w = q({
252
+ idpOrigin: C,
253
+ clientId: c,
254
+ redirectUri: n.redirectUri,
255
+ scope: u,
256
+ state: d,
257
+ nonce: f,
258
+ codeChallenge: p
322
259
  });
323
- await resolved.openAuthUrl(url.toString());
260
+ await e.openAuthUrl(w.toString());
324
261
  }
325
- async function completeSignIn(callbackUrl) {
326
- if (!callbackUrl || typeof callbackUrl !== "string") {
327
- throw new NeetruError(
262
+ async function A(n) {
263
+ if (!n || typeof n != "string")
264
+ throw new r(
328
265
  "invalid_config",
329
266
  "mobile auth.completeSignIn requer `callbackUrl` (a URL completa do deep link de retorno) \u2014 mobile n\xE3o tem location.href impl\xEDcito."
330
267
  );
331
- }
332
- let parsed;
268
+ let a;
333
269
  try {
334
- parsed = new URL(callbackUrl);
270
+ a = new URL(n);
335
271
  } catch {
336
- throw new NeetruError("invalid_config", `callbackUrl n\xE3o \xE9 uma URL v\xE1lida: ${callbackUrl}`);
272
+ throw new r("invalid_config", `callbackUrl n\xE3o \xE9 uma URL v\xE1lida: ${n}`);
337
273
  }
338
- const params = parsed.searchParams;
339
- const idpError = params.get("error");
340
- if (idpError) {
341
- const desc = params.get("error_description") ?? idpError;
342
- await resolved.storage.removeItem(OIDC_TX_KEY);
343
- throw new NeetruError(idpError, `OIDC authorize falhou: ${desc}`);
274
+ let u = a.searchParams, c = u.get("error");
275
+ if (c) {
276
+ let j = u.get("error_description") ?? c;
277
+ throw await e.storage.removeItem(h), new r(c, `OIDC authorize falhou: ${j}`);
344
278
  }
345
- const code = params.get("code");
346
- if (!code) {
347
- await resolved.storage.removeItem(OIDC_TX_KEY);
348
- throw new NeetruError(
279
+ let d = u.get("code");
280
+ if (!d)
281
+ throw await e.storage.removeItem(h), new r(
349
282
  "invalid_config",
350
283
  "callbackUrl n\xE3o cont\xE9m `?code=` nem `?error=` \u2014 n\xE3o \xE9 um callback OIDC v\xE1lido."
351
284
  );
352
- }
353
- const returnedState = params.get("state");
354
- const txRaw = await resolved.storage.getItem(OIDC_TX_KEY);
355
- let tx = null;
356
- if (txRaw) {
285
+ let f = u.get("state"), g = await e.storage.getItem(h), p = null;
286
+ if (g)
357
287
  try {
358
- tx = JSON.parse(txRaw);
288
+ p = JSON.parse(g);
359
289
  } catch {
360
- tx = null;
290
+ p = null;
361
291
  }
362
- }
363
- if (!tx) {
364
- throw new NeetruError(
292
+ if (!p)
293
+ throw new r(
365
294
  "oidc_state_mismatch",
366
295
  "Callback OIDC sem transa\xE7\xE3o pendente \u2014 `signIn` n\xE3o foi iniciado (ou j\xE1 consumido)."
367
296
  );
368
- }
369
- if (!returnedState || returnedState !== tx.state) {
370
- await resolved.storage.removeItem(OIDC_TX_KEY);
371
- throw new NeetruError(
297
+ if (!f || f !== p.state)
298
+ throw await e.storage.removeItem(h), new r(
372
299
  "oidc_state_mismatch",
373
300
  "state do callback OIDC n\xE3o confere com o da transa\xE7\xE3o (poss\xEDvel CSRF)."
374
301
  );
375
- }
376
- await resolved.storage.removeItem(OIDC_TX_KEY);
377
- const clientId = resolveOidcClientId(resolved);
378
- const form = new URLSearchParams({
302
+ await e.storage.removeItem(h);
303
+ let T = I(e), C = new URLSearchParams({
379
304
  grant_type: "authorization_code",
380
- code,
381
- redirect_uri: tx.redirectUri,
382
- client_id: clientId,
383
- code_verifier: tx.codeVerifier
384
- });
385
- const payload = await postToken(resolved.fetchImpl, tokenUrl(), form);
386
- const idToken = payload.id_token;
387
- if (typeof idToken !== "string" || idToken.length === 0) {
388
- throw new NeetruError(
305
+ code: d,
306
+ redirect_uri: p.redirectUri,
307
+ client_id: T,
308
+ code_verifier: p.codeVerifier
309
+ }), w = await z(e.fetchImpl, s(), C), b = w.id_token;
310
+ if (typeof b != "string" || b.length === 0)
311
+ throw new r(
389
312
  "token_exchange_failed",
390
313
  "Resposta do /token sem `id_token` \u2014 o login n\xE3o pode ser completado."
391
314
  );
392
- }
393
- const claims = decodeJwtPayload(idToken);
394
- if (!claims) {
395
- throw new NeetruError(
315
+ let x = N(b);
316
+ if (!x)
317
+ throw new r(
396
318
  "token_exchange_failed",
397
319
  "id_token retornado pelo /token \xE9 malformado (payload indecodific\xE1vel)."
398
320
  );
399
- }
400
- if (claims.nonce !== tx.nonce) {
401
- throw new NeetruError(
321
+ if (x.nonce !== p.nonce)
322
+ throw new r(
402
323
  "oidc_nonce_mismatch",
403
324
  "nonce do id_token n\xE3o confere com o da transa\xE7\xE3o OIDC (poss\xEDvel replay). Token descartado."
404
325
  );
405
- }
406
- const user = jwtToNeetruUser(idToken);
407
- if (!user) {
408
- throw new NeetruError(
326
+ let E = _(b);
327
+ if (!E)
328
+ throw new r(
409
329
  "token_exchange_failed",
410
330
  "id_token retornado pelo /token n\xE3o tem `sub` ou j\xE1 est\xE1 expirado."
411
331
  );
412
- }
413
- await resolved.storage.setItem(ID_TOKEN_KEY, idToken);
414
- const refreshToken = payload.refresh_token;
415
- if (typeof refreshToken === "string" && refreshToken.length > 0) {
416
- await resolved.storage.setItem(REFRESH_TOKEN_KEY, refreshToken);
417
- }
418
- await notify();
419
- return { user, postLoginRedirect: tx.postLoginRedirect };
332
+ await e.storage.setItem(y, b);
333
+ let P = w.refresh_token;
334
+ return typeof P == "string" && P.length > 0 && await e.storage.setItem(S, P), await o(), { user: E, postLoginRedirect: p.postLoginRedirect };
420
335
  }
421
- async function getIdToken() {
422
- const token = await resolved.storage.getItem(ID_TOKEN_KEY);
423
- if (!token) return null;
424
- return jwtToNeetruUser(token) ? token : null;
336
+ async function R() {
337
+ let n = await e.storage.getItem(y);
338
+ return n && _(n) ? n : null;
425
339
  }
426
- async function getUser() {
427
- const token = await resolved.storage.getItem(ID_TOKEN_KEY);
428
- if (!token) return null;
429
- return jwtToNeetruUser(token);
340
+ async function m() {
341
+ let n = await e.storage.getItem(y);
342
+ return n ? _(n) : null;
430
343
  }
431
- async function refreshTokens() {
432
- const refreshToken = await resolved.storage.getItem(REFRESH_TOKEN_KEY);
433
- if (!refreshToken) return false;
434
- let clientId;
344
+ async function k() {
345
+ let n = await e.storage.getItem(S);
346
+ if (!n) return false;
347
+ let a;
435
348
  try {
436
- clientId = resolveOidcClientId(resolved);
349
+ a = I(e);
437
350
  } catch {
438
351
  return false;
439
352
  }
440
- const form = new URLSearchParams({
353
+ let u = new URLSearchParams({
441
354
  grant_type: "refresh_token",
442
- refresh_token: refreshToken,
443
- client_id: clientId
444
- });
445
- let payload;
355
+ refresh_token: n,
356
+ client_id: a
357
+ }), c;
446
358
  try {
447
- payload = await postToken(resolved.fetchImpl, tokenUrl(), form);
359
+ c = await z(e.fetchImpl, s(), u);
448
360
  } catch {
449
361
  return false;
450
362
  }
451
- const idToken = payload.id_token;
452
- if (typeof idToken !== "string" || idToken.length === 0) return false;
453
- const user = jwtToNeetruUser(idToken);
454
- if (!user) return false;
455
- await resolved.storage.setItem(ID_TOKEN_KEY, idToken);
456
- const rotated = payload.refresh_token;
457
- if (typeof rotated === "string" && rotated.length > 0) {
458
- await resolved.storage.setItem(REFRESH_TOKEN_KEY, rotated);
459
- }
460
- await notify();
461
- return true;
363
+ let d = c.id_token;
364
+ if (typeof d != "string" || d.length === 0 || !_(d)) return false;
365
+ await e.storage.setItem(y, d);
366
+ let g = c.refresh_token;
367
+ return typeof g == "string" && g.length > 0 && await e.storage.setItem(S, g), await o(), true;
462
368
  }
463
- async function signOut() {
464
- const storedToken = await resolved.storage.getItem(ID_TOKEN_KEY);
465
- await resolved.storage.removeItem(ID_TOKEN_KEY);
466
- await resolved.storage.removeItem(REFRESH_TOKEN_KEY);
467
- if (storedToken) {
468
- const idpOrigin = resolveIdpOrigin(resolved.baseUrl);
469
- const revokeUrl = `${idpOrigin}/api/v1/oauth/revoke`;
369
+ async function V() {
370
+ let n = await e.storage.getItem(y);
371
+ if (await e.storage.removeItem(y), await e.storage.removeItem(S), n) {
372
+ let u = `${U(e.baseUrl)}/api/v1/oauth/revoke`;
470
373
  try {
471
- await resolved.fetchImpl(revokeUrl, {
374
+ await e.fetchImpl(u, {
472
375
  method: "POST",
473
376
  headers: { "content-type": "application/json" },
474
- body: JSON.stringify({ token: storedToken })
377
+ body: JSON.stringify({ token: n })
475
378
  });
476
- } catch (err) {
477
- if (typeof console !== "undefined") {
478
- console.warn(
479
- "[neetru-sdk] mobile signOut: server-side revoke falhou. Refresh token pode estar stale.",
480
- err
481
- );
482
- }
379
+ } catch (c) {
380
+ typeof console < "u" && console.warn(
381
+ "[neetru-sdk] mobile signOut: server-side revoke falhou. Refresh token pode estar stale.",
382
+ c
383
+ );
483
384
  }
484
385
  }
485
- await notify();
386
+ await o();
486
387
  }
487
388
  return {
488
- signIn,
489
- completeSignIn,
490
- getIdToken,
491
- getUser,
492
- onAuthStateChanged(listener) {
493
- listeners.add(listener);
494
- void getUser().then((user) => {
495
- if (listeners.has(listener)) {
389
+ signIn: l,
390
+ completeSignIn: A,
391
+ getIdToken: R,
392
+ getUser: m,
393
+ onAuthStateChanged(n) {
394
+ return i.add(n), m().then((a) => {
395
+ if (i.has(n))
496
396
  try {
497
- listener(user);
397
+ n(a);
498
398
  } catch {
499
399
  }
500
- }
501
- });
502
- return () => {
503
- listeners.delete(listener);
400
+ }), () => {
401
+ i.delete(n);
504
402
  };
505
403
  },
506
- refreshTokens,
507
- signOut
404
+ refreshTokens: k,
405
+ signOut: V
508
406
  };
509
407
  }
510
408
 
511
- export { createMobileAuthNamespace };
512
- //# sourceMappingURL=mobile.mjs.map
513
- //# sourceMappingURL=mobile.mjs.map
409
+ export { ge as createMobileAuthNamespace };