@neetru/sdk 3.6.0 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/README.md +66 -1
  3. package/dist/ai.cjs +298 -391
  4. package/dist/ai.d.cts +1 -1
  5. package/dist/ai.d.ts +1 -1
  6. package/dist/ai.mjs +298 -391
  7. package/dist/auth.cjs +3717 -5005
  8. package/dist/auth.d.cts +1 -1
  9. package/dist/auth.d.ts +1 -1
  10. package/dist/auth.mjs +3714 -5002
  11. package/dist/build-guard.cjs +101 -119
  12. package/dist/build-guard.mjs +91 -109
  13. package/dist/catalog.cjs +220 -225
  14. package/dist/catalog.d.cts +1 -1
  15. package/dist/catalog.d.ts +1 -1
  16. package/dist/catalog.mjs +220 -225
  17. package/dist/checkout.cjs +307 -323
  18. package/dist/checkout.d.cts +1 -1
  19. package/dist/checkout.d.ts +1 -1
  20. package/dist/checkout.mjs +306 -322
  21. package/dist/db-react.cjs +59 -87
  22. package/dist/db-react.d.cts +1 -1
  23. package/dist/db-react.d.ts +1 -1
  24. package/dist/db-react.mjs +56 -84
  25. package/dist/db.cjs +2128 -3014
  26. package/dist/db.d.cts +1 -1
  27. package/dist/db.d.ts +1 -1
  28. package/dist/db.mjs +2141 -3027
  29. package/dist/entitlements.cjs +19 -20
  30. package/dist/entitlements.d.cts +1 -1
  31. package/dist/entitlements.d.ts +1 -1
  32. package/dist/entitlements.mjs +19 -20
  33. package/dist/errors.cjs +16 -12
  34. package/dist/errors.d.cts +59 -3
  35. package/dist/errors.d.ts +59 -3
  36. package/dist/errors.mjs +15 -12
  37. package/dist/firestore-compat.cjs +241 -297
  38. package/dist/firestore-compat.d.cts +1 -1
  39. package/dist/firestore-compat.d.ts +1 -1
  40. package/dist/firestore-compat.mjs +215 -271
  41. package/dist/index.cjs +3942 -5134
  42. package/dist/index.d.cts +181 -5
  43. package/dist/index.d.ts +181 -5
  44. package/dist/index.mjs +4040 -5239
  45. package/dist/mobile.cjs +459 -344
  46. package/dist/mobile.d.cts +59 -4
  47. package/dist/mobile.d.ts +59 -4
  48. package/dist/mobile.mjs +459 -344
  49. package/dist/mocks.cjs +319 -447
  50. package/dist/mocks.d.cts +1 -1
  51. package/dist/mocks.d.ts +1 -1
  52. package/dist/mocks.mjs +313 -441
  53. package/dist/notifications.cjs +296 -317
  54. package/dist/notifications.d.cts +1 -1
  55. package/dist/notifications.d.ts +1 -1
  56. package/dist/notifications.mjs +295 -316
  57. package/dist/react.cjs +557 -707
  58. package/dist/react.d.cts +1 -1
  59. package/dist/react.d.ts +1 -1
  60. package/dist/react.mjs +547 -697
  61. package/dist/support.cjs +402 -328
  62. package/dist/support.d.cts +29 -3
  63. package/dist/support.d.ts +29 -3
  64. package/dist/support.mjs +401 -328
  65. package/dist/telemetry.cjs +267 -304
  66. package/dist/telemetry.d.cts +1 -1
  67. package/dist/telemetry.d.ts +1 -1
  68. package/dist/telemetry.mjs +267 -304
  69. package/dist/{types-Du_iioJ7.d.cts → types-D-9bjlM0.d.cts} +74 -1
  70. package/dist/{types-BPATkXYu.d.ts → types-bVztFQTI.d.ts} +74 -1
  71. package/dist/usage.cjs +233 -230
  72. package/dist/usage.d.cts +1 -1
  73. package/dist/usage.d.ts +1 -1
  74. package/dist/usage.mjs +233 -230
  75. package/dist/webhooks.cjs +328 -362
  76. package/dist/webhooks.d.cts +1 -1
  77. package/dist/webhooks.d.ts +1 -1
  78. package/dist/webhooks.mjs +325 -359
  79. package/package.json +5 -3
  80. package/dist/ai.cjs.map +0 -1
  81. package/dist/ai.mjs.map +0 -1
  82. package/dist/auth.cjs.map +0 -1
  83. package/dist/auth.mjs.map +0 -1
  84. package/dist/build-guard.cjs.map +0 -1
  85. package/dist/build-guard.mjs.map +0 -1
  86. package/dist/catalog.cjs.map +0 -1
  87. package/dist/catalog.mjs.map +0 -1
  88. package/dist/checkout.cjs.map +0 -1
  89. package/dist/checkout.mjs.map +0 -1
  90. package/dist/db-react.cjs.map +0 -1
  91. package/dist/db-react.mjs.map +0 -1
  92. package/dist/db.cjs.map +0 -1
  93. package/dist/db.mjs.map +0 -1
  94. package/dist/entitlements.cjs.map +0 -1
  95. package/dist/entitlements.mjs.map +0 -1
  96. package/dist/errors.cjs.map +0 -1
  97. package/dist/errors.mjs.map +0 -1
  98. package/dist/firestore-compat.cjs.map +0 -1
  99. package/dist/firestore-compat.mjs.map +0 -1
  100. package/dist/index.cjs.map +0 -1
  101. package/dist/index.mjs.map +0 -1
  102. package/dist/mobile.cjs.map +0 -1
  103. package/dist/mobile.mjs.map +0 -1
  104. package/dist/mocks.cjs.map +0 -1
  105. package/dist/mocks.mjs.map +0 -1
  106. package/dist/notifications.cjs.map +0 -1
  107. package/dist/notifications.mjs.map +0 -1
  108. package/dist/react.cjs.map +0 -1
  109. package/dist/react.mjs.map +0 -1
  110. package/dist/support.cjs.map +0 -1
  111. package/dist/support.mjs.map +0 -1
  112. package/dist/telemetry.cjs.map +0 -1
  113. package/dist/telemetry.mjs.map +0 -1
  114. package/dist/usage.cjs.map +0 -1
  115. package/dist/usage.mjs.map +0 -1
  116. package/dist/webhooks.cjs.map +0 -1
  117. package/dist/webhooks.mjs.map +0 -1
package/dist/react.mjs CHANGED
@@ -1,9 +1,9 @@
1
- import * as React2 from 'react';
1
+ import * as l from 'react';
2
2
 
3
3
  // src/react.ts
4
4
 
5
5
  // src/errors.ts
6
- var NeetruError = class _NeetruError extends Error {
6
+ var E = class e extends Error {
7
7
  code;
8
8
  status;
9
9
  requestId;
@@ -16,23 +16,37 @@ var NeetruError = class _NeetruError extends Error {
16
16
  * para um `NeetruDbErrorCode` mais específico (recuperável vs não).
17
17
  */
18
18
  reason;
19
- constructor(code, message, status, requestId, reason) {
20
- super(message);
21
- this.name = "NeetruError";
22
- this.code = code;
23
- this.status = status;
24
- this.requestId = requestId;
25
- this.reason = reason;
26
- Object.setPrototypeOf(this, _NeetruError.prototype);
19
+ /**
20
+ * 3.8.0: `x-correlation-id` da requisição que falhou. O SDK gera um UUID por
21
+ * chamada (ou usa o que o chamador passou) e manda no header; o Core grava o
22
+ * mesmo id nos logs/auditoria — cite-o ao abrir um ticket de suporte.
23
+ * `undefined` em erros que acontecem antes de qualquer requisição.
24
+ */
25
+ correlationId;
26
+ constructor(t, i, n, s, c, o) {
27
+ super(i), this.name = "NeetruError", this.code = t, this.status = n, this.requestId = s, this.reason = c, this.correlationId = o, Object.setPrototypeOf(this, e.prototype);
27
28
  }
28
29
  };
29
30
 
30
31
  // src/types.ts
31
- var DEFAULT_BASE_URL = "https://api.neetru.com";
32
+ var O = "https://api.neetru.com";
33
+
34
+ // src/end-user-token.ts
35
+ var ee = /* @__PURE__ */ new WeakMap();
36
+ function te(e) {
37
+ return ee.get(e);
38
+ }
39
+ async function M(e) {
40
+ try {
41
+ let t = te(e), i = e.auth, n = t ? await t.getIdToken() : typeof i?.getIdToken == "function" ? await i.getIdToken() : null;
42
+ return typeof n == "string" && n.length > 0 ? n : null;
43
+ } catch {
44
+ return null;
45
+ }
46
+ }
32
47
 
33
48
  // src/account-bar.ts
34
- var h = React2.createElement;
35
- var DEFAULT_LABELS = {
49
+ var y = l.createElement, ne = {
36
50
  accountButton: "Abrir menu da conta",
37
51
  appsButton: "Seus produtos Neetru",
38
52
  appsTitle: "Trocar de produto",
@@ -42,191 +56,141 @@ var DEFAULT_LABELS = {
42
56
  currentBadge: "Atual",
43
57
  emptyProducts: "Nenhum outro produto dispon\xEDvel."
44
58
  };
45
- async function fetchNeetruAccountBar(client) {
46
- const auth = client.auth;
47
- const idToken = typeof auth?.getIdToken === "function" ? auth.getIdToken() : null;
48
- if (!idToken) return null;
49
- const config = client.config;
50
- const baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
51
- const fetchFn = config.fetch ?? globalThis.fetch;
52
- const url = `${baseUrl}/api/sdk/v1/account/bar`;
59
+ async function W(e) {
60
+ let t = await M(e);
61
+ if (!t) return null;
62
+ let i = e.config, n = (i.baseUrl ?? O).replace(/\/+$/, ""), s = i.fetch ?? globalThis.fetch, c = `${n}/api/sdk/v1/account/bar`;
53
63
  try {
54
- const res = await fetchFn(url, {
55
- headers: { authorization: `Bearer ${idToken}`, accept: "application/json" }
64
+ let o = await s(c, {
65
+ headers: { authorization: `Bearer ${t}`, accept: "application/json" }
56
66
  });
57
- if (!res.ok) return null;
58
- const body = await res.json();
59
- if (!body || typeof body !== "object" || !body.account) return null;
60
- return {
67
+ if (!o.ok) return null;
68
+ let r = await o.json();
69
+ return !r || typeof r != "object" || !r.account ? null : {
61
70
  account: {
62
- displayName: String(body.account.displayName ?? ""),
63
- email: String(body.account.email ?? ""),
64
- photoUrl: body.account.photoUrl ?? null
71
+ displayName: String(r.account.displayName ?? ""),
72
+ email: String(r.account.email ?? ""),
73
+ photoUrl: r.account.photoUrl ?? null
65
74
  },
66
- accountUrl: String(body.accountUrl ?? "https://minhaconta.neetru.com"),
67
- products: Array.isArray(body.products) ? body.products.filter(
68
- (p) => !!p && typeof p.slug === "string" && typeof p.url === "string"
75
+ accountUrl: String(r.accountUrl ?? "https://minhaconta.neetru.com"),
76
+ products: Array.isArray(r.products) ? r.products.filter(
77
+ (b) => !!b && typeof b.slug == "string" && typeof b.url == "string"
69
78
  ) : []
70
79
  };
71
80
  } catch {
72
81
  return null;
73
82
  }
74
83
  }
75
- function initialsFrom(nameOrEmail) {
76
- const s = (nameOrEmail ?? "").trim();
77
- if (!s) return "?";
78
- const local = s.includes("@") ? s.split("@")[0] : s;
79
- const parts = local.split(/[\s._-]+/).filter(Boolean);
80
- if (parts.length === 0) return local.slice(0, 1).toUpperCase();
81
- if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();
82
- return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
84
+ function N(e) {
85
+ let t = (e ?? "").trim();
86
+ if (!t) return "?";
87
+ let i = t.includes("@") ? t.split("@")[0] : t, n = i.split(/[\s._-]+/).filter(Boolean);
88
+ return n.length === 0 ? i.slice(0, 1).toUpperCase() : n.length === 1 ? n[0].slice(0, 2).toUpperCase() : (n[0][0] + n[n.length - 1][0]).toUpperCase();
83
89
  }
84
- var C = {
90
+ var h = {
85
91
  bg: "#ffffff",
86
92
  bgHover: "#f5f5f5",
87
93
  fg: "#0a0a0a",
88
94
  muted: "#666666",
89
95
  border: "#0a0a0a",
90
96
  borderSoft: "#e5e5e5"
91
- };
92
- var SQUARE = 0;
93
- function WaffleIcon({ size = 18, color = C.fg }) {
94
- const dots = [0, 1, 2].flatMap((r) => [0, 1, 2].map((c) => ({ r, c })));
95
- const gap = size / 3;
96
- const dot = Math.max(2, size / 7);
97
- return h(
97
+ }, H = 0;
98
+ function re({ size: e = 18, color: t = h.fg }) {
99
+ let i = [0, 1, 2].flatMap((c) => [0, 1, 2].map((o) => ({ r: c, c: o }))), n = e / 3, s = Math.max(2, e / 7);
100
+ return y(
98
101
  "svg",
99
- { width: size, height: size, viewBox: `0 0 ${size} ${size}`, "aria-hidden": true, style: { display: "block" } },
100
- dots.map(
101
- ({ r, c }) => h("rect", {
102
- key: `${r}-${c}`,
103
- x: c * gap + (gap - dot) / 2,
104
- y: r * gap + (gap - dot) / 2,
105
- width: dot,
106
- height: dot,
107
- fill: color
102
+ { width: e, height: e, viewBox: `0 0 ${e} ${e}`, "aria-hidden": true, style: { display: "block" } },
103
+ i.map(
104
+ ({ r: c, c: o }) => y("rect", {
105
+ key: `${c}-${o}`,
106
+ x: o * n + (n - s) / 2,
107
+ y: c * n + (n - s) / 2,
108
+ width: s,
109
+ height: s,
110
+ fill: t
108
111
  })
109
112
  )
110
113
  );
111
114
  }
112
- function focusables(container) {
113
- if (!container) return [];
114
- return Array.from(
115
- container.querySelectorAll(
115
+ function Q(e) {
116
+ return e ? Array.from(
117
+ e.querySelectorAll(
116
118
  'a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"])'
117
119
  )
118
- ).filter((el) => el.offsetParent !== null || el === document.activeElement);
120
+ ).filter((t) => t.offsetParent !== null || t === document.activeElement) : [];
119
121
  }
120
- function NeetruAccountBar({
121
- client,
122
- currentProductSlug,
123
- settingsUrl,
124
- onSignOut,
125
- fetchBar,
126
- labels,
127
- className
122
+ function oe({
123
+ client: e,
124
+ currentProductSlug: t,
125
+ settingsUrl: i,
126
+ onSignOut: n,
127
+ fetchBar: s,
128
+ labels: c,
129
+ className: o
128
130
  }) {
129
- const L = { ...DEFAULT_LABELS, ...labels };
130
- const seedAccount = React2.useMemo(() => {
131
+ let r = { ...ne, ...c }, b = l.useMemo(() => {
131
132
  try {
132
- const u = client.auth.getUser();
133
- if (!u) return null;
134
- return {
135
- displayName: u.displayName || u.email || "",
136
- email: u.email || "",
137
- photoUrl: u.photoURL ?? null
138
- };
133
+ let a = e.auth.getUser();
134
+ return a ? {
135
+ displayName: a.displayName || a.email || "",
136
+ email: a.email || "",
137
+ photoUrl: a.photoURL ?? null
138
+ } : null;
139
139
  } catch {
140
140
  return null;
141
141
  }
142
- }, [client]);
143
- const [data, setData] = React2.useState(null);
144
- const [open, setOpen] = React2.useState(null);
145
- const [signingOut, setSigningOut] = React2.useState(false);
146
- const containerRef = React2.useRef(null);
147
- const accountBtnRef = React2.useRef(null);
148
- const appsBtnRef = React2.useRef(null);
149
- const popoverRef = React2.useRef(null);
150
- React2.useEffect(() => {
151
- let cancelled = false;
152
- const run = fetchBar ?? fetchNeetruAccountBar;
153
- Promise.resolve(run(client)).then((res) => {
154
- if (!cancelled && res) setData(res);
142
+ }, [e]), [u, f] = l.useState(null), [m, w] = l.useState(null), [T, R] = l.useState(false), p = l.useRef(null), d = l.useRef(null), g = l.useRef(null), C = l.useRef(null);
143
+ l.useEffect(() => {
144
+ let a = false, k = s ?? W;
145
+ return Promise.resolve(k(e)).then((S) => {
146
+ !a && S && f(S);
155
147
  }).catch(() => {
156
- });
157
- return () => {
158
- cancelled = true;
148
+ }), () => {
149
+ a = true;
159
150
  };
160
- }, [client, fetchBar]);
161
- const account = data?.account ?? seedAccount;
162
- const accountUrl = data?.accountUrl ?? "https://minhaconta.neetru.com";
163
- const products = data?.products ?? [];
164
- const closeAndRefocus = React2.useCallback((which) => {
165
- setOpen(null);
166
- const trigger = which === "apps" ? appsBtnRef.current : accountBtnRef.current;
167
- trigger?.focus();
151
+ }, [e, s]);
152
+ let v = u?.account ?? b, G = u?.accountUrl ?? "https://minhaconta.neetru.com", A = u?.products ?? [], L = l.useCallback((a) => {
153
+ w(null), (a === "apps" ? g.current : d.current)?.focus();
168
154
  }, []);
169
- React2.useEffect(() => {
170
- if (!open) return;
171
- const first = focusables(popoverRef.current)[0];
172
- first?.focus();
173
- const onDocMouseDown = (e) => {
174
- if (containerRef.current && !containerRef.current.contains(e.target)) {
175
- setOpen(null);
176
- }
155
+ l.useEffect(() => {
156
+ if (!m) return;
157
+ Q(C.current)[0]?.focus();
158
+ let k = (S) => {
159
+ p.current && !p.current.contains(S.target) && w(null);
177
160
  };
178
- document.addEventListener("mousedown", onDocMouseDown);
179
- return () => document.removeEventListener("mousedown", onDocMouseDown);
180
- }, [open]);
181
- const onPopoverKeyDown = React2.useCallback(
182
- (e) => {
183
- if (e.key === "Escape") {
184
- e.stopPropagation();
185
- closeAndRefocus(open);
161
+ return document.addEventListener("mousedown", k), () => document.removeEventListener("mousedown", k);
162
+ }, [m]);
163
+ let P = l.useCallback(
164
+ (a) => {
165
+ if (a.key === "Escape") {
166
+ a.stopPropagation(), L(m);
186
167
  return;
187
168
  }
188
- const items = focusables(popoverRef.current);
189
- if (items.length === 0) return;
190
- const idx = items.indexOf(document.activeElement);
191
- if (e.key === "Tab") {
192
- if (e.shiftKey && idx <= 0) {
193
- e.preventDefault();
194
- items[items.length - 1].focus();
195
- } else if (!e.shiftKey && idx === items.length - 1) {
196
- e.preventDefault();
197
- items[0].focus();
198
- }
199
- } else if (e.key === "ArrowDown") {
200
- e.preventDefault();
201
- items[(idx + 1) % items.length].focus();
202
- } else if (e.key === "ArrowUp") {
203
- e.preventDefault();
204
- items[(idx - 1 + items.length) % items.length].focus();
205
- }
169
+ let k = Q(C.current);
170
+ if (k.length === 0) return;
171
+ let S = k.indexOf(document.activeElement);
172
+ a.key === "Tab" ? a.shiftKey && S <= 0 ? (a.preventDefault(), k[k.length - 1].focus()) : !a.shiftKey && S === k.length - 1 && (a.preventDefault(), k[0].focus()) : a.key === "ArrowDown" ? (a.preventDefault(), k[(S + 1) % k.length].focus()) : a.key === "ArrowUp" && (a.preventDefault(), k[(S - 1 + k.length) % k.length].focus());
206
173
  },
207
- [open, closeAndRefocus]
208
- );
209
- const handleSignOut = React2.useCallback(async () => {
210
- if (signingOut) return;
211
- setSigningOut(true);
212
- try {
213
- await client.auth.signOut();
214
- } catch {
215
- } finally {
216
- setSigningOut(false);
217
- setOpen(null);
218
- onSignOut?.();
174
+ [m, L]
175
+ ), K = l.useCallback(async () => {
176
+ if (!T) {
177
+ R(true);
178
+ try {
179
+ await e.auth.signOut();
180
+ } catch {
181
+ } finally {
182
+ R(false), w(null), n?.();
183
+ }
219
184
  }
220
- }, [client, signingOut, onSignOut]);
221
- if (!account) return null;
222
- const initials = initialsFrom(account.displayName || account.email);
223
- const avatarInner = account.photoUrl ? h("img", {
224
- src: account.photoUrl,
185
+ }, [e, T, n]);
186
+ if (!v) return null;
187
+ let I = N(v.displayName || v.email), V = v.photoUrl ? y("img", {
188
+ src: v.photoUrl,
225
189
  alt: "",
226
190
  width: 32,
227
191
  height: 32,
228
192
  style: { width: 32, height: 32, objectFit: "cover", display: "block" }
229
- }) : h(
193
+ }) : y(
230
194
  "span",
231
195
  {
232
196
  "aria-hidden": true,
@@ -236,74 +200,69 @@ function NeetruAccountBar({
236
200
  display: "inline-flex",
237
201
  alignItems: "center",
238
202
  justifyContent: "center",
239
- backgroundColor: C.fg,
203
+ backgroundColor: h.fg,
240
204
  color: "#ffffff",
241
205
  fontSize: 13,
242
206
  fontWeight: 700,
243
207
  letterSpacing: "0.02em"
244
208
  }
245
209
  },
246
- initials
247
- );
248
- const iconBtnStyle = (active) => ({
210
+ I
211
+ ), B = (a) => ({
249
212
  display: "inline-flex",
250
213
  alignItems: "center",
251
214
  justifyContent: "center",
252
215
  width: 36,
253
216
  height: 36,
254
217
  padding: 0,
255
- borderRadius: SQUARE,
256
- border: `1px solid ${active ? C.border : C.borderSoft}`,
257
- backgroundColor: active ? C.bgHover : C.bg,
258
- color: C.fg,
218
+ borderRadius: H,
219
+ border: `1px solid ${a ? h.border : h.borderSoft}`,
220
+ backgroundColor: a ? h.bgHover : h.bg,
221
+ color: h.fg,
259
222
  cursor: "pointer",
260
223
  boxSizing: "border-box",
261
224
  fontFamily: "inherit",
262
225
  overflow: "hidden"
263
- });
264
- const appsButton = h(
226
+ }), J = y(
265
227
  "button",
266
228
  {
267
229
  type: "button",
268
- ref: appsBtnRef,
269
- "aria-label": L.appsButton,
230
+ ref: g,
231
+ "aria-label": r.appsButton,
270
232
  "aria-haspopup": "menu",
271
- "aria-expanded": open === "apps",
233
+ "aria-expanded": m === "apps",
272
234
  "data-neetru-appswitcher-button": "true",
273
- onClick: () => setOpen((o) => o === "apps" ? null : "apps"),
274
- style: iconBtnStyle(open === "apps")
235
+ onClick: () => w((a) => a === "apps" ? null : "apps"),
236
+ style: B(m === "apps")
275
237
  },
276
- h(WaffleIcon, {})
277
- );
278
- const accountButton = h(
238
+ y(re, {})
239
+ ), X = y(
279
240
  "button",
280
241
  {
281
242
  type: "button",
282
- ref: accountBtnRef,
283
- "aria-label": `${L.accountButton}${account.displayName ? ` (${account.displayName})` : ""}`,
243
+ ref: d,
244
+ "aria-label": `${r.accountButton}${v.displayName ? ` (${v.displayName})` : ""}`,
284
245
  "aria-haspopup": "menu",
285
- "aria-expanded": open === "account",
246
+ "aria-expanded": m === "account",
286
247
  "data-neetru-account-button": "true",
287
- onClick: () => setOpen((o) => o === "account" ? null : "account"),
288
- style: { ...iconBtnStyle(open === "account"), width: 36, height: 36 }
248
+ onClick: () => w((a) => a === "account" ? null : "account"),
249
+ style: { ...B(m === "account"), width: 36, height: 36 }
289
250
  },
290
- avatarInner
291
- );
292
- const popoverStyle = {
251
+ V
252
+ ), F = {
293
253
  position: "absolute",
294
254
  top: "calc(100% + 6px)",
295
255
  right: 0,
296
256
  minWidth: 260,
297
257
  maxWidth: 320,
298
- backgroundColor: C.bg,
299
- border: `1px solid ${C.border}`,
300
- borderRadius: SQUARE,
258
+ backgroundColor: h.bg,
259
+ border: `1px solid ${h.border}`,
260
+ borderRadius: H,
301
261
  zIndex: 1e3,
302
- color: C.fg,
262
+ color: h.fg,
303
263
  fontFamily: "inherit"
304
264
  // BMW: sem sombra/glassmorphism — borda sólida define o recorte.
305
- };
306
- const menuItemStyle = {
265
+ }, D = {
307
266
  display: "flex",
308
267
  alignItems: "center",
309
268
  gap: 10,
@@ -311,8 +270,8 @@ function NeetruAccountBar({
311
270
  padding: "10px 14px",
312
271
  background: "transparent",
313
272
  border: "none",
314
- borderTop: `1px solid ${C.borderSoft}`,
315
- color: C.fg,
273
+ borderTop: `1px solid ${h.borderSoft}`,
274
+ color: h.fg,
316
275
  fontSize: 14,
317
276
  fontWeight: 400,
318
277
  textAlign: "left",
@@ -320,30 +279,28 @@ function NeetruAccountBar({
320
279
  cursor: "pointer",
321
280
  boxSizing: "border-box",
322
281
  fontFamily: "inherit"
323
- };
324
- const hoverHandlers = {
325
- onMouseEnter: (e) => {
326
- e.currentTarget.style.backgroundColor = C.bgHover;
282
+ }, _ = {
283
+ onMouseEnter: (a) => {
284
+ a.currentTarget.style.backgroundColor = h.bgHover;
327
285
  },
328
- onMouseLeave: (e) => {
329
- e.currentTarget.style.backgroundColor = "transparent";
286
+ onMouseLeave: (a) => {
287
+ a.currentTarget.style.backgroundColor = "transparent";
330
288
  }
331
- };
332
- const accountPopover = open === "account" ? h(
289
+ }, Y = m === "account" ? y(
333
290
  "div",
334
291
  {
335
- ref: popoverRef,
292
+ ref: C,
336
293
  role: "menu",
337
- "aria-label": L.accountButton,
294
+ "aria-label": r.accountButton,
338
295
  "data-neetru-account-menu": "true",
339
- onKeyDown: onPopoverKeyDown,
340
- style: popoverStyle
296
+ onKeyDown: P,
297
+ style: F
341
298
  },
342
299
  // Header identidade
343
- h(
300
+ y(
344
301
  "div",
345
302
  { style: { display: "flex", gap: 12, alignItems: "center", padding: 14 } },
346
- h(
303
+ y(
347
304
  "span",
348
305
  {
349
306
  "aria-hidden": true,
@@ -355,24 +312,24 @@ function NeetruAccountBar({
355
312
  alignItems: "center",
356
313
  justifyContent: "center",
357
314
  overflow: "hidden",
358
- backgroundColor: account.photoUrl ? "transparent" : C.fg,
315
+ backgroundColor: v.photoUrl ? "transparent" : h.fg,
359
316
  color: "#ffffff",
360
317
  fontSize: 15,
361
318
  fontWeight: 700
362
319
  }
363
320
  },
364
- account.photoUrl ? h("img", {
365
- src: account.photoUrl,
321
+ v.photoUrl ? y("img", {
322
+ src: v.photoUrl,
366
323
  alt: "",
367
324
  width: 40,
368
325
  height: 40,
369
326
  style: { width: 40, height: 40, objectFit: "cover", display: "block" }
370
- }) : initials
327
+ }) : I
371
328
  ),
372
- h(
329
+ y(
373
330
  "span",
374
331
  { style: { display: "flex", flexDirection: "column", minWidth: 0 } },
375
- h(
332
+ y(
376
333
  "span",
377
334
  {
378
335
  style: {
@@ -383,68 +340,67 @@ function NeetruAccountBar({
383
340
  textOverflow: "ellipsis"
384
341
  }
385
342
  },
386
- account.displayName || account.email
343
+ v.displayName || v.email
387
344
  ),
388
- account.email ? h(
345
+ v.email ? y(
389
346
  "span",
390
347
  {
391
348
  style: {
392
- color: C.muted,
349
+ color: h.muted,
393
350
  fontSize: 12,
394
351
  whiteSpace: "nowrap",
395
352
  overflow: "hidden",
396
353
  textOverflow: "ellipsis"
397
354
  }
398
355
  },
399
- account.email
356
+ v.email
400
357
  ) : null
401
358
  )
402
359
  ),
403
360
  // Minha conta Neetru
404
- h(
361
+ y(
405
362
  "a",
406
363
  {
407
364
  role: "menuitem",
408
- href: accountUrl,
365
+ href: G,
409
366
  target: "_blank",
410
367
  rel: "noopener noreferrer",
411
- style: menuItemStyle,
412
- ...hoverHandlers
368
+ style: D,
369
+ ..._
413
370
  },
414
- L.myAccount
371
+ r.myAccount
415
372
  ),
416
373
  // Configurações da conta (deste produto)
417
- settingsUrl ? h(
374
+ i ? y(
418
375
  "a",
419
- { role: "menuitem", href: settingsUrl, style: menuItemStyle, ...hoverHandlers },
420
- L.accountSettings
376
+ { role: "menuitem", href: i, style: D, ..._ },
377
+ r.accountSettings
421
378
  ) : null,
422
379
  // Sair
423
- h(
380
+ y(
424
381
  "button",
425
382
  {
426
383
  type: "button",
427
384
  role: "menuitem",
428
- onClick: handleSignOut,
429
- disabled: signingOut,
385
+ onClick: K,
386
+ disabled: T,
430
387
  "data-neetru-signout": "true",
431
- style: { ...menuItemStyle, cursor: signingOut ? "not-allowed" : "pointer" },
432
- ...hoverHandlers
388
+ style: { ...D, cursor: T ? "not-allowed" : "pointer" },
389
+ ..._
433
390
  },
434
- signingOut ? `${L.signOut}\u2026` : L.signOut
391
+ T ? `${r.signOut}\u2026` : r.signOut
435
392
  )
436
- ) : null;
437
- const appsPopover = open === "apps" ? h(
393
+ ) : null, Z = m === "apps" ? y(
438
394
  "div",
439
395
  {
440
- ref: popoverRef,
396
+ ref: C,
441
397
  role: "menu",
442
- "aria-label": L.appsTitle,
398
+ "aria-label": r.appsTitle,
443
399
  "data-neetru-appswitcher-menu": "true",
444
- onKeyDown: onPopoverKeyDown,
445
- style: { ...popoverStyle, minWidth: 280 }
400
+ onKeyDown: P,
401
+ style: { ...F, minWidth: 280 }
446
402
  },
447
- h(
403
+ y(
448
404
  "div",
449
405
  {
450
406
  style: {
@@ -453,16 +409,16 @@ function NeetruAccountBar({
453
409
  fontWeight: 700,
454
410
  letterSpacing: "0.08em",
455
411
  textTransform: "uppercase",
456
- color: C.muted
412
+ color: h.muted
457
413
  }
458
414
  },
459
- L.appsTitle
415
+ r.appsTitle
460
416
  ),
461
- products.length === 0 ? h(
417
+ A.length === 0 ? y(
462
418
  "div",
463
- { style: { padding: "4px 14px 16px", fontSize: 13, color: C.muted } },
464
- L.emptyProducts
465
- ) : h(
419
+ { style: { padding: "4px 14px 16px", fontSize: 13, color: h.muted } },
420
+ r.emptyProducts
421
+ ) : y(
466
422
  "div",
467
423
  {
468
424
  style: {
@@ -470,21 +426,21 @@ function NeetruAccountBar({
470
426
  gridTemplateColumns: "1fr 1fr",
471
427
  gap: 1,
472
428
  padding: 1,
473
- backgroundColor: C.borderSoft
429
+ backgroundColor: h.borderSoft
474
430
  }
475
431
  },
476
- products.map((p) => {
477
- const isCurrent = !!currentProductSlug && p.slug === currentProductSlug;
478
- return h(
432
+ A.map((a) => {
433
+ let k = !!t && a.slug === t;
434
+ return y(
479
435
  "a",
480
436
  {
481
- key: p.slug,
437
+ key: a.slug,
482
438
  role: "menuitem",
483
- href: p.url,
484
- "aria-current": isCurrent ? "true" : void 0,
485
- "data-neetru-product": p.slug,
486
- "data-current": isCurrent ? "true" : void 0,
487
- title: p.name,
439
+ href: a.url,
440
+ "aria-current": k ? "true" : void 0,
441
+ "data-neetru-product": a.slug,
442
+ "data-current": k ? "true" : void 0,
443
+ title: a.name,
488
444
  style: {
489
445
  display: "flex",
490
446
  flexDirection: "column",
@@ -492,26 +448,26 @@ function NeetruAccountBar({
492
448
  gap: 6,
493
449
  padding: "14px 8px",
494
450
  textDecoration: "none",
495
- color: C.fg,
496
- backgroundColor: isCurrent ? C.bgHover : C.bg,
451
+ color: h.fg,
452
+ backgroundColor: k ? h.bgHover : h.bg,
497
453
  cursor: "pointer",
498
454
  boxSizing: "border-box"
499
455
  },
500
- onMouseEnter: (e) => {
501
- e.currentTarget.style.backgroundColor = C.bgHover;
456
+ onMouseEnter: (S) => {
457
+ S.currentTarget.style.backgroundColor = h.bgHover;
502
458
  },
503
- onMouseLeave: (e) => {
504
- e.currentTarget.style.backgroundColor = isCurrent ? C.bgHover : C.bg;
459
+ onMouseLeave: (S) => {
460
+ S.currentTarget.style.backgroundColor = k ? h.bgHover : h.bg;
505
461
  }
506
462
  },
507
463
  // Tile/ícone
508
- p.iconUrl ? h("img", {
509
- src: p.iconUrl,
464
+ a.iconUrl ? y("img", {
465
+ src: a.iconUrl,
510
466
  alt: "",
511
467
  width: 32,
512
468
  height: 32,
513
469
  style: { width: 32, height: 32, objectFit: "cover", display: "block" }
514
- }) : h(
470
+ }) : y(
515
471
  "span",
516
472
  {
517
473
  "aria-hidden": true,
@@ -521,20 +477,20 @@ function NeetruAccountBar({
521
477
  display: "inline-flex",
522
478
  alignItems: "center",
523
479
  justifyContent: "center",
524
- backgroundColor: C.fg,
480
+ backgroundColor: h.fg,
525
481
  color: "#ffffff",
526
482
  fontSize: 13,
527
483
  fontWeight: 700
528
484
  }
529
485
  },
530
- initialsFrom(p.name)
486
+ N(a.name)
531
487
  ),
532
- h(
488
+ y(
533
489
  "span",
534
490
  {
535
491
  style: {
536
492
  fontSize: 12,
537
- fontWeight: isCurrent ? 700 : 400,
493
+ fontWeight: k ? 700 : 400,
538
494
  textAlign: "center",
539
495
  lineHeight: 1.2,
540
496
  maxWidth: "100%",
@@ -544,9 +500,9 @@ function NeetruAccountBar({
544
500
  width: "100%"
545
501
  }
546
502
  },
547
- p.name
503
+ a.name
548
504
  ),
549
- isCurrent ? h(
505
+ k ? y(
550
506
  "span",
551
507
  {
552
508
  style: {
@@ -554,20 +510,20 @@ function NeetruAccountBar({
554
510
  fontWeight: 700,
555
511
  letterSpacing: "0.08em",
556
512
  textTransform: "uppercase",
557
- color: C.muted
513
+ color: h.muted
558
514
  }
559
515
  },
560
- L.currentBadge
516
+ r.currentBadge
561
517
  ) : null
562
518
  );
563
519
  })
564
520
  )
565
521
  ) : null;
566
- return h(
522
+ return y(
567
523
  "div",
568
524
  {
569
- ref: containerRef,
570
- className,
525
+ ref: p,
526
+ className: o,
571
527
  "data-neetru-account-bar": "true",
572
528
  style: {
573
529
  position: "relative",
@@ -579,234 +535,205 @@ function NeetruAccountBar({
579
535
  fontFamily: "inherit"
580
536
  }
581
537
  },
582
- appsButton,
583
- accountButton,
584
- accountPopover,
585
- appsPopover
538
+ J,
539
+ X,
540
+ Y,
541
+ Z
586
542
  );
587
543
  }
588
544
 
589
545
  // src/firestore-compat.ts
590
- function toDbQuery(constraints) {
591
- const whereFilters = [];
592
- let orderByClause;
593
- let limitValue;
594
- for (const c of constraints) {
546
+ function U(e) {
547
+ let t = [], i, n;
548
+ for (let c of e)
595
549
  if (c.__constraint === "where") {
596
- const w = c;
597
- whereFilters.push({ field: w.field, op: normalizeOp(w.op), value: w.value });
550
+ let o = c;
551
+ t.push({ field: o.field, op: o.op, value: o.value });
598
552
  } else if (c.__constraint === "orderBy") {
599
- const o = c;
600
- orderByClause = { field: o.field, direction: o.direction };
601
- } else if (c.__constraint === "limit") {
602
- limitValue = c.value;
603
- }
604
- }
605
- const out = {};
606
- if (whereFilters.length > 0) out.where = whereFilters;
607
- if (orderByClause) out.orderBy = orderByClause;
608
- if (limitValue !== void 0) out.limit = limitValue;
609
- return out;
610
- }
611
- function normalizeOp(op) {
612
- return op;
553
+ let o = c;
554
+ i = { field: o.field, direction: o.direction };
555
+ } else c.__constraint === "limit" && (n = c.value);
556
+ let s = {};
557
+ return t.length > 0 && (s.where = t), i && (s.orderBy = i), n !== void 0 && (s.limit = n), s;
613
558
  }
614
559
 
615
560
  // src/react.ts
616
- async function startCheckoutViaBff(startPath, input) {
617
- const res = await fetch(startPath, {
561
+ async function ie(e, t) {
562
+ let i = await fetch(e, {
618
563
  method: "POST",
619
564
  headers: { "content-type": "application/json", accept: "application/json" },
620
565
  credentials: "include",
621
- body: JSON.stringify(input)
622
- });
623
- let payload = null;
566
+ body: JSON.stringify(t)
567
+ }), n = null;
624
568
  try {
625
- payload = await res.json();
569
+ n = await i.json();
626
570
  } catch {
627
- payload = null;
571
+ n = null;
628
572
  }
629
- if (!res.ok) {
630
- const p = payload;
631
- const errField = p?.error;
632
- const code = (errField && typeof errField === "object" && typeof errField.code === "string" ? errField.code : void 0) ?? "server_error";
633
- const msg = p && (typeof p.error === "object" && p.error?.message || typeof p.error === "string" && p.error || typeof p.message === "string" && p.message) || `Checkout BFF respondeu HTTP ${res.status}`;
634
- throw new NeetruError(
635
- code,
636
- typeof msg === "string" ? msg : `Checkout BFF respondeu HTTP ${res.status}`,
637
- res.status
573
+ if (!i.ok) {
574
+ let o = n, r = o?.error, b = (r && typeof r == "object" && typeof r.code == "string" ? r.code : void 0) ?? "server_error", u = o && (typeof o.error == "object" && o.error?.message || typeof o.error == "string" && o.error || typeof o.message == "string" && o.message) || `Checkout BFF respondeu HTTP ${i.status}`;
575
+ throw new E(
576
+ b,
577
+ typeof u == "string" ? u : `Checkout BFF respondeu HTTP ${i.status}`,
578
+ i.status
638
579
  );
639
580
  }
640
- const intent = payload?.intent ?? payload ?? {};
641
- const redirectUrl = payload?.redirectUrl ?? intent.redirectUrl;
642
- if (!redirectUrl || typeof redirectUrl !== "string") {
643
- throw new NeetruError(
581
+ let s = n?.intent ?? n ?? {}, c = n?.redirectUrl ?? s.redirectUrl;
582
+ if (!c || typeof c != "string")
583
+ throw new E(
644
584
  "invalid_response",
645
585
  "Resposta do route BFF de checkout sem `redirectUrl`."
646
586
  );
647
- }
648
587
  return {
649
- intentId: String(payload?.intentId ?? intent.intentId ?? ""),
650
- redirectUrl,
651
- status: payload?.status ?? intent.status ?? "pending",
652
- expiresAt: typeof payload?.expiresAt === "string" ? payload.expiresAt : typeof intent.expiresAt === "string" ? intent.expiresAt : "",
653
- requiresKyc: payload?.requiresKyc === true || intent.requiresKyc === true
588
+ intentId: String(n?.intentId ?? s.intentId ?? ""),
589
+ redirectUrl: c,
590
+ status: n?.status ?? s.status ?? "pending",
591
+ expiresAt: typeof n?.expiresAt == "string" ? n.expiresAt : typeof s.expiresAt == "string" ? s.expiresAt : "",
592
+ requiresKyc: n?.requiresKyc === true || s.requiresKyc === true
654
593
  };
655
594
  }
656
- function checkoutRedirect(url) {
657
- const loc = globalThis.location;
658
- if (loc && typeof loc.assign === "function") loc.assign(url);
595
+ function se(e) {
596
+ let t = globalThis.location;
597
+ t && typeof t.assign == "function" && t.assign(e);
659
598
  }
660
- function CheckoutLink({
661
- client,
662
- startPath,
663
- productId,
664
- planId,
665
- callbackUrl,
666
- tenantType,
667
- tenantId,
668
- children,
669
- onIntentCreated,
670
- onError,
671
- noAutoRedirect,
672
- ...rest
599
+ function Ee({
600
+ client: e,
601
+ startPath: t,
602
+ productId: i,
603
+ planId: n,
604
+ callbackUrl: s,
605
+ tenantType: c,
606
+ tenantId: o,
607
+ children: r,
608
+ onIntentCreated: b,
609
+ onError: u,
610
+ noAutoRedirect: f,
611
+ ...m
673
612
  }) {
674
- const [submitting, setSubmitting] = React2.useState(false);
675
- const checkout = client?.checkout;
676
- const handleClick = React2.useCallback(
677
- async (event) => {
678
- event.preventDefault();
679
- if (submitting) return;
680
- if (startPath) {
681
- setSubmitting(true);
613
+ let [w, T] = l.useState(false), R = e?.checkout, p = l.useCallback(
614
+ async (d) => {
615
+ if (d.preventDefault(), !w) {
616
+ if (t) {
617
+ T(true);
618
+ try {
619
+ let g = await ie(t, {
620
+ productId: i,
621
+ planId: n,
622
+ callbackUrl: s,
623
+ tenantType: c,
624
+ tenantId: o
625
+ });
626
+ b?.(g), f || se(g.redirectUrl);
627
+ } catch (g) {
628
+ u?.(g instanceof Error ? g : new Error(String(g)));
629
+ } finally {
630
+ T(false);
631
+ }
632
+ return;
633
+ }
634
+ if (!R || typeof R.start != "function") {
635
+ u?.(
636
+ new Error(
637
+ "CheckoutLink: passe `startPath` (padr\xE3o BFF/cookie recomendado) OU um `client` com o namespace `checkout` (SDK 1.1+)."
638
+ )
639
+ );
640
+ return;
641
+ }
642
+ T(true);
682
643
  try {
683
- const result = await startCheckoutViaBff(startPath, {
684
- productId,
685
- planId,
686
- callbackUrl,
687
- tenantType,
688
- tenantId
644
+ let g = await R.start({
645
+ productId: i,
646
+ planId: n,
647
+ callbackUrl: s,
648
+ tenantType: c,
649
+ tenantId: o,
650
+ autoRedirect: !f
689
651
  });
690
- onIntentCreated?.(result);
691
- if (!noAutoRedirect) checkoutRedirect(result.redirectUrl);
692
- } catch (err) {
693
- onError?.(err instanceof Error ? err : new Error(String(err)));
652
+ b?.(g);
653
+ } catch (g) {
654
+ u?.(g instanceof Error ? g : new Error(String(g)));
694
655
  } finally {
695
- setSubmitting(false);
656
+ T(false);
696
657
  }
697
- return;
698
- }
699
- if (!checkout || typeof checkout.start !== "function") {
700
- onError?.(
701
- new Error(
702
- "CheckoutLink: passe `startPath` (padr\xE3o BFF/cookie recomendado) OU um `client` com o namespace `checkout` (SDK 1.1+)."
703
- )
704
- );
705
- return;
706
- }
707
- setSubmitting(true);
708
- try {
709
- const result = await checkout.start({
710
- productId,
711
- planId,
712
- callbackUrl,
713
- tenantType,
714
- tenantId,
715
- autoRedirect: !noAutoRedirect
716
- });
717
- onIntentCreated?.(result);
718
- } catch (err) {
719
- onError?.(err instanceof Error ? err : new Error(String(err)));
720
- } finally {
721
- setSubmitting(false);
722
658
  }
723
659
  },
724
- [submitting, checkout, startPath, productId, planId, callbackUrl, tenantType, tenantId, noAutoRedirect, onIntentCreated, onError]
660
+ [w, R, t, i, n, s, c, o, f, b, u]
725
661
  );
726
- return React2.createElement(
662
+ return l.createElement(
727
663
  "a",
728
664
  {
729
- ...rest,
730
- href: rest.href ?? "#",
731
- onClick: handleClick,
732
- "aria-busy": submitting || void 0,
665
+ ...m,
666
+ href: m.href ?? "#",
667
+ onClick: p,
668
+ "aria-busy": w || void 0,
733
669
  "data-neetru-checkout-link": "true"
734
670
  },
735
- children
671
+ r
736
672
  );
737
673
  }
738
- var NEETRU_FLAME_PATH = "M 281 5.163 C 240.659 26.308, 211.260 52.739, 187.750 89 C 177.297 105.123, 167.942 126.107, 162.988 144.543 C 154.486 176.188, 153.303 204.118, 159.101 236.317 C 161.553 249.934, 164.601 259.065, 171.539 273.568 C 179.323 289.843, 188.311 302.619, 205.856 322.343 C 216.993 334.865, 218.719 337.460, 223.536 348.944 C 233.797 373.403, 237.419 401.984, 232.417 419.032 C 229.111 430.300, 219.859 441.975, 210.427 446.779 C 186.006 459.218, 155.612 448.383, 142.319 422.500 C 128.813 396.204, 123.953 356.753, 129.495 318.395 C 131.172 306.786, 138.276 276.222, 140.080 272.850 C 140.675 271.738, 140.944 270.610, 140.676 270.343 C 139.995 269.662, 121.004 281.262, 112 287.859 C 100.565 296.237, 95.542 300.566, 83.993 312 C 44.470 351.127, 19.275 398.763, 8.623 454.500 C 4.302 477.115, 3.308 513.551, 6.332 538.569 C 9.164 562.011, 17.855 591.852, 27.324 610.648 C 37.693 631.233, 54.130 653.987, 71.900 672.357 C 80.540 681.289, 98.477 696.992, 104.478 700.878 C 106.690 702.310, 108.725 703.766, 109 704.114 C 109.836 705.172, 125.939 715.307, 135.539 720.817 C 152.923 730.795, 169.097 737.316, 200.500 747.009 C 204.454 748.230, 222.087 751.463, 234 753.153 C 246.383 754.909, 283.484 754.921, 296 753.173 C 310.006 751.217, 321.722 749.122, 328.500 747.360 C 384.024 732.928, 433.393 701.075, 469.555 656.351 C 491.448 629.275, 505.223 601.823, 514.391 567 C 519.380 548.047, 520.999 536.377, 521.686 514.410 C 523.126 468.370, 514.560 426.479, 494.812 383 C 471.567 331.818, 436.019 282.480, 379.951 223.582 C 354.302 196.638, 349.024 190.981, 341.670 182.551 C 318.918 156.471, 301.763 128.316, 293.505 103.500 C 286.625 82.826, 285.662 76.446, 285.578 51 C 285.500 27.576, 285.510 27.460, 288.750 15.129 C 290.538 8.326, 292 2.363, 292 1.879 C 292 0.197, 288.454 1.255, 281 5.163";
739
- var NEETRU_FLAME_VIEWBOX = "0 0 527 760";
740
- var NEETRU_FLAME_ASPECT = 527 / 760;
741
- function NeetruFlameIcon({ fill, size = 16 }) {
742
- return React2.createElement(
674
+ var ae = "M 281 5.163 C 240.659 26.308, 211.260 52.739, 187.750 89 C 177.297 105.123, 167.942 126.107, 162.988 144.543 C 154.486 176.188, 153.303 204.118, 159.101 236.317 C 161.553 249.934, 164.601 259.065, 171.539 273.568 C 179.323 289.843, 188.311 302.619, 205.856 322.343 C 216.993 334.865, 218.719 337.460, 223.536 348.944 C 233.797 373.403, 237.419 401.984, 232.417 419.032 C 229.111 430.300, 219.859 441.975, 210.427 446.779 C 186.006 459.218, 155.612 448.383, 142.319 422.500 C 128.813 396.204, 123.953 356.753, 129.495 318.395 C 131.172 306.786, 138.276 276.222, 140.080 272.850 C 140.675 271.738, 140.944 270.610, 140.676 270.343 C 139.995 269.662, 121.004 281.262, 112 287.859 C 100.565 296.237, 95.542 300.566, 83.993 312 C 44.470 351.127, 19.275 398.763, 8.623 454.500 C 4.302 477.115, 3.308 513.551, 6.332 538.569 C 9.164 562.011, 17.855 591.852, 27.324 610.648 C 37.693 631.233, 54.130 653.987, 71.900 672.357 C 80.540 681.289, 98.477 696.992, 104.478 700.878 C 106.690 702.310, 108.725 703.766, 109 704.114 C 109.836 705.172, 125.939 715.307, 135.539 720.817 C 152.923 730.795, 169.097 737.316, 200.500 747.009 C 204.454 748.230, 222.087 751.463, 234 753.153 C 246.383 754.909, 283.484 754.921, 296 753.173 C 310.006 751.217, 321.722 749.122, 328.500 747.360 C 384.024 732.928, 433.393 701.075, 469.555 656.351 C 491.448 629.275, 505.223 601.823, 514.391 567 C 519.380 548.047, 520.999 536.377, 521.686 514.410 C 523.126 468.370, 514.560 426.479, 494.812 383 C 471.567 331.818, 436.019 282.480, 379.951 223.582 C 354.302 196.638, 349.024 190.981, 341.670 182.551 C 318.918 156.471, 301.763 128.316, 293.505 103.500 C 286.625 82.826, 285.662 76.446, 285.578 51 C 285.500 27.576, 285.510 27.460, 288.750 15.129 C 290.538 8.326, 292 2.363, 292 1.879 C 292 0.197, 288.454 1.255, 281 5.163", ce = "0 0 527 760", le = 527 / 760;
675
+ function ue({ fill: e, size: t = 16 }) {
676
+ return l.createElement(
743
677
  "svg",
744
678
  {
745
- viewBox: NEETRU_FLAME_VIEWBOX,
746
- width: Math.round(size * NEETRU_FLAME_ASPECT),
747
- height: size,
679
+ viewBox: ce,
680
+ width: Math.round(t * le),
681
+ height: t,
748
682
  "aria-hidden": true,
749
683
  style: { flexShrink: 0 }
750
684
  },
751
- React2.createElement("path", { d: NEETRU_FLAME_PATH, fill })
685
+ l.createElement("path", { d: ae, fill: e })
752
686
  );
753
687
  }
754
- var NEETRU_LOGIN_BUTTON_THEME = {
688
+ var de = {
755
689
  dark: { bg: "#0a0a0a", bgHover: "#1a1a1a", fg: "#ffffff", border: "#0a0a0a" },
756
690
  light: { bg: "#ffffff", bgHover: "#f5f5f5", fg: "#0a0a0a", border: "#0a0a0a" }
757
- };
758
- var NEETRU_LOGIN_FOCUS_STYLE_ID = "neetru-login-button-focus-style";
759
- var NEETRU_LOGIN_FOCUS_CSS = "button[data-neetru-login-button]:focus-visible{outline:2px solid var(--neetru-login-focus-ring,#ffffff);outline-offset:2px;}";
760
- function ensureLoginFocusStyleInjected() {
761
- if (typeof document === "undefined" || !document.head) return;
762
- if (document.getElementById(NEETRU_LOGIN_FOCUS_STYLE_ID)) return;
763
- const styleEl = document.createElement("style");
764
- styleEl.id = NEETRU_LOGIN_FOCUS_STYLE_ID;
765
- styleEl.textContent = NEETRU_LOGIN_FOCUS_CSS;
766
- document.head.appendChild(styleEl);
691
+ }, j = "neetru-login-button-focus-style", pe = "button[data-neetru-login-button]:focus-visible{outline:2px solid var(--neetru-login-focus-ring,#ffffff);outline-offset:2px;}";
692
+ function ge() {
693
+ if (typeof document > "u" || !document.head || document.getElementById(j)) return;
694
+ let e = document.createElement("style");
695
+ e.id = j, e.textContent = pe, document.head.appendChild(e);
767
696
  }
768
- function NeetruLoginButton({
769
- client,
770
- redirectUri,
771
- scope,
772
- postLoginRedirect,
773
- theme = "dark",
774
- label = "Entrar com Neetru",
775
- onError,
776
- style,
777
- disabled,
778
- ...rest
697
+ function De({
698
+ client: e,
699
+ redirectUri: t,
700
+ scope: i,
701
+ postLoginRedirect: n,
702
+ theme: s = "dark",
703
+ label: c = "Entrar com Neetru",
704
+ onError: o,
705
+ style: r,
706
+ disabled: b,
707
+ ...u
779
708
  }) {
780
- const [isLoading, setIsLoading] = React2.useState(false);
781
- const [isHover, setIsHover] = React2.useState(false);
782
- const colors = NEETRU_LOGIN_BUTTON_THEME[theme];
783
- const isDisabled = Boolean(disabled) || isLoading;
784
- React2.useEffect(() => {
785
- ensureLoginFocusStyleInjected();
709
+ let [f, m] = l.useState(false), [w, T] = l.useState(false), R = de[s], p = !!b || f;
710
+ l.useEffect(() => {
711
+ ge();
786
712
  }, []);
787
- const handleClick = React2.useCallback(async () => {
788
- if (isDisabled) return;
789
- setIsLoading(true);
790
- try {
791
- const options = { redirectUri, scope, postLoginRedirect };
792
- await client.auth.signIn(options);
793
- } catch (err) {
794
- onError?.(err instanceof Error ? err : new Error(String(err)));
795
- } finally {
796
- setIsLoading(false);
713
+ let d = l.useCallback(async () => {
714
+ if (!p) {
715
+ m(true);
716
+ try {
717
+ let g = { redirectUri: t, scope: i, postLoginRedirect: n };
718
+ await e.auth.signIn(g);
719
+ } catch (g) {
720
+ o?.(g instanceof Error ? g : new Error(String(g)));
721
+ } finally {
722
+ m(false);
723
+ }
797
724
  }
798
- }, [client, redirectUri, scope, postLoginRedirect, isDisabled, onError]);
799
- return React2.createElement(
725
+ }, [e, t, i, n, p, o]);
726
+ return l.createElement(
800
727
  "button",
801
728
  {
802
- ...rest,
729
+ ...u,
803
730
  type: "button",
804
- onClick: handleClick,
805
- disabled: isDisabled,
806
- onMouseEnter: () => setIsHover(true),
807
- onMouseLeave: () => setIsHover(false),
808
- "aria-label": rest["aria-label"] ?? label,
809
- "aria-busy": isLoading || void 0,
731
+ onClick: d,
732
+ disabled: p,
733
+ onMouseEnter: () => T(true),
734
+ onMouseLeave: () => T(false),
735
+ "aria-label": u["aria-label"] ?? c,
736
+ "aria-busy": f || void 0,
810
737
  "data-neetru-login-button": "true",
811
738
  style: {
812
739
  display: "inline-flex",
@@ -817,346 +744,269 @@ function NeetruLoginButton({
817
744
  height: "48px",
818
745
  padding: "0 20px",
819
746
  borderRadius: 0,
820
- border: `1px solid ${colors.border}`,
821
- backgroundColor: isHover && !isDisabled ? colors.bgHover : colors.bg,
822
- color: colors.fg,
747
+ border: `1px solid ${R.border}`,
748
+ backgroundColor: w && !p ? R.bgHover : R.bg,
749
+ color: R.fg,
823
750
  fontSize: "14px",
824
751
  fontWeight: 700,
825
752
  textTransform: "uppercase",
826
753
  letterSpacing: "0.08em",
827
754
  fontFamily: "inherit",
828
755
  lineHeight: 1,
829
- cursor: isDisabled ? "not-allowed" : "pointer",
830
- opacity: isDisabled && !isLoading ? 0.6 : 1,
756
+ cursor: p ? "not-allowed" : "pointer",
757
+ opacity: p && !f ? 0.6 : 1,
831
758
  transition: "background-color 150ms ease",
832
759
  boxSizing: "border-box",
833
760
  // Cor do ring de foco de teclado (:focus-visible) — ver
834
761
  // NEETRU_LOGIN_FOCUS_CSS. Usa a cor do texto (contraste AA garantido).
835
- "--neetru-login-focus-ring": colors.fg,
836
- ...style
762
+ "--neetru-login-focus-ring": R.fg,
763
+ ...r
837
764
  }
838
765
  },
839
- React2.createElement(NeetruFlameIcon, { fill: colors.fg }),
840
- React2.createElement("span", null, isLoading ? "Entrando\u2026" : label)
766
+ l.createElement(ue, { fill: R.fg }),
767
+ l.createElement("span", null, f ? "Entrando\u2026" : c)
841
768
  );
842
769
  }
843
- var EntitlementContext = React2.createContext({
770
+ var $ = l.createContext({
844
771
  readonly: false
845
772
  });
846
- function useEntitlementContext() {
847
- return React2.useContext(EntitlementContext);
773
+ function _e() {
774
+ return l.useContext($);
848
775
  }
849
- function EntitlementGate({
850
- client,
851
- feature,
852
- productSlug,
853
- mode = "block",
854
- fallback,
855
- loading,
856
- children
776
+ function Ne({
777
+ client: e,
778
+ feature: t,
779
+ productSlug: i,
780
+ mode: n = "block",
781
+ fallback: s,
782
+ loading: c,
783
+ children: o
857
784
  }) {
858
- const [state, setState] = React2.useState({
785
+ let [r, b] = l.useState({
859
786
  status: "loading"
860
- });
861
- const resolvedSlug = productSlug ?? client.config.productId ?? "";
862
- const resolvedTenantId = client.config.tenantId;
863
- React2.useEffect(() => {
864
- let cancelled = false;
865
- const run = async () => {
787
+ }), u = i ?? e.config.productId ?? "", f = e.config.tenantId;
788
+ if (l.useEffect(() => {
789
+ let R = false;
790
+ return (async () => {
866
791
  try {
867
- let result2;
868
- const usage = client.usage;
869
- if (usage && typeof usage.check === "function" && resolvedTenantId) {
870
- const res = await usage.check(feature, {
871
- productId: resolvedSlug,
872
- tenantId: resolvedTenantId
792
+ let d, g = e.usage;
793
+ if (g && typeof g.check == "function" && f) {
794
+ let C = await g.check(t, {
795
+ productId: u,
796
+ tenantId: f
873
797
  });
874
- result2 = {
875
- allowed: res.allowed === true,
876
- reason: res.reason,
877
- limit: res.limit,
878
- currentUsage: res.currentUsage,
879
- behavior: res.behavior
798
+ d = {
799
+ allowed: C.allowed === !0,
800
+ reason: C.reason,
801
+ limit: C.limit,
802
+ currentUsage: C.currentUsage,
803
+ behavior: C.behavior
880
804
  };
881
- } else {
882
- if (typeof console !== "undefined") {
883
- console.warn(
884
- "[EntitlementGate] tenantId ausente em client.config \u2014 n\xE3o \xE9 poss\xEDvel verificar entitlement (client.entitlements.check() est\xE1 deprecado, ver src/entitlements.ts). Configure tenantId no createNeetruClient() ou passe via props. Bloqueando por padr\xE3o (fail-closed)."
885
- );
886
- }
887
- result2 = { allowed: false, reason: "tenant_id_required" };
888
- }
889
- if (!cancelled) setState({ status: "ready", result: result2 });
890
- } catch (err) {
891
- if (!cancelled) {
892
- setState({ status: "ready", result: { allowed: true, reason: "check_error_fallback" } });
893
- }
894
- if (typeof console !== "undefined") console.warn("[EntitlementGate] check failed \u2014 fail-open", err);
805
+ } else
806
+ typeof console < "u" && console.warn(
807
+ "[EntitlementGate] tenantId ausente em client.config \u2014 n\xE3o \xE9 poss\xEDvel verificar entitlement (client.entitlements.check() est\xE1 deprecado, ver src/entitlements.ts). Configure tenantId no createNeetruClient() ou passe via props. Bloqueando por padr\xE3o (fail-closed)."
808
+ ), d = { allowed: !1, reason: "tenant_id_required" };
809
+ R || b({ status: "ready", result: d });
810
+ } catch (d) {
811
+ R || b({ status: "ready", result: { allowed: true, reason: "check_error_fallback" } }), typeof console < "u" && console.warn("[EntitlementGate] check failed \u2014 fail-open", d);
895
812
  }
813
+ })(), () => {
814
+ R = true;
896
815
  };
897
- run();
898
- return () => {
899
- cancelled = true;
900
- };
901
- }, [client, feature, resolvedSlug, resolvedTenantId]);
902
- if (state.status === "loading") {
903
- return React2.createElement(React2.Fragment, null, loading ?? null);
904
- }
905
- const result = state.result;
906
- const allowed = result?.allowed === true;
907
- const isReadonly = !allowed && (mode === "readonly" || result?.behavior === "readonly");
908
- if (!allowed && mode === "block" && !isReadonly) {
909
- return React2.createElement(React2.Fragment, null, fallback ?? null);
910
- }
911
- return React2.createElement(
912
- EntitlementContext.Provider,
816
+ }, [e, t, u, f]), r.status === "loading")
817
+ return l.createElement(l.Fragment, null, c ?? null);
818
+ let m = r.result, w = m?.allowed === true, T = !w && (n === "readonly" || m?.behavior === "readonly");
819
+ return !w && n === "block" && !T ? l.createElement(l.Fragment, null, s ?? null) : l.createElement(
820
+ $.Provider,
913
821
  {
914
822
  value: {
915
- readonly: isReadonly,
916
- reason: result?.reason,
917
- limit: result?.limit,
918
- currentUsage: result?.currentUsage
823
+ readonly: T,
824
+ reason: m?.reason,
825
+ limit: m?.limit,
826
+ currentUsage: m?.currentUsage
919
827
  }
920
828
  },
921
- children
829
+ o
922
830
  );
923
831
  }
924
- var DEFAULT_INTERVAL_MS = 5e3;
925
- function isDocumentHidden() {
926
- return typeof document !== "undefined" && document.hidden === true;
832
+ var q = 5e3;
833
+ function z() {
834
+ return typeof document < "u" && document.hidden === true;
927
835
  }
928
- function serializeSource(source) {
929
- if (!source) return null;
930
- if (source.__kind === "collection") {
931
- return `collection:${source.id}`;
932
- }
933
- const dbQuery = toDbQuery(source.constraints);
934
- return `query:${source.collection}:${JSON.stringify(dbQuery)}`;
836
+ function fe(e) {
837
+ if (!e) return null;
838
+ if (e.__kind === "collection")
839
+ return `collection:${e.id}`;
840
+ let t = U(e.constraints);
841
+ return `query:${e.collection}:${JSON.stringify(t)}`;
935
842
  }
936
- function rowsFromList(snap) {
937
- return snap.docs.map((d) => {
938
- const data = d.data;
939
- const { id: _omit, ...rest } = data;
940
- return { ...rest, id: d.id };
843
+ function me(e) {
844
+ return e.docs.map((t) => {
845
+ let i = t.data, { id: n, ...s } = i;
846
+ return { ...s, id: t.id };
941
847
  });
942
848
  }
943
- function rowFromGet(snap, id) {
944
- const first = snap?.docs[0];
945
- if (!first) return null;
946
- const data = first.data;
947
- const { id: _omit, ...rest } = data;
948
- return { ...rest, id };
849
+ function ye(e, t) {
850
+ let i = e?.docs[0];
851
+ if (!i) return null;
852
+ let n = i.data, { id: s, ...c } = n;
853
+ return { ...c, id: t };
949
854
  }
950
- function useCollection(source, options) {
951
- const intervalMs = options?.intervalMs ?? DEFAULT_INTERVAL_MS;
952
- const poll = options?.poll ?? false;
953
- const sourceKey = serializeSource(
954
- source
955
- );
956
- const [state, setState] = React2.useState({
855
+ function Ue(e, t) {
856
+ let i = t?.intervalMs ?? q, n = t?.poll ?? false, s = fe(
857
+ e
858
+ ), [c, o] = l.useState({
957
859
  data: null,
958
- isLoading: sourceKey !== null,
860
+ isLoading: s !== null,
959
861
  error: null,
960
862
  isStale: false,
961
863
  lastUpdated: null
962
- });
963
- const mountedRef = React2.useRef(true);
964
- const sourceRef = React2.useRef(source);
965
- sourceRef.current = source;
966
- React2.useEffect(() => {
967
- mountedRef.current = true;
968
- const current = sourceRef.current;
969
- if (!current || sourceKey === null) {
970
- setState({ data: null, isLoading: false, error: null, isStale: false, lastUpdated: null });
971
- return () => {
972
- mountedRef.current = false;
864
+ }), r = l.useRef(true), b = l.useRef(e);
865
+ return b.current = e, l.useEffect(() => {
866
+ r.current = true;
867
+ let u = b.current;
868
+ if (!u || s === null)
869
+ return o({ data: null, isLoading: false, error: null, isStale: false, lastUpdated: null }), () => {
870
+ r.current = false;
973
871
  };
974
- }
975
- setState((prev) => ({ ...prev, isLoading: prev.data === null }));
976
- const collectionName = current.__kind === "query" ? current.collection : current.id;
977
- const dbQuery = current.__kind === "query" ? toDbQuery(current.constraints) : void 0;
978
- const col = current.db.collection(collectionName);
979
- const applySnap = (snap) => {
980
- if (!mountedRef.current) return;
981
- setState({
982
- data: rowsFromList(snap),
872
+ o((d) => ({ ...d, isLoading: d.data === null }));
873
+ let f = u.__kind === "query" ? u.collection : u.id, m = u.__kind === "query" ? U(u.constraints) : void 0, w = u.db.collection(f), T = (d) => {
874
+ r.current && o({
875
+ data: me(d),
983
876
  isLoading: false,
984
877
  error: null,
985
- isStale: snap.stale === true,
878
+ isStale: d.stale === true,
986
879
  lastUpdated: Date.now()
987
880
  });
988
- };
989
- const applyError = (e) => {
990
- if (!mountedRef.current) return;
991
- setState((prev) => ({
992
- ...prev,
881
+ }, R = (d) => {
882
+ r.current && o((g) => ({
883
+ ...g,
993
884
  // Mantém o último data bom — não limpa em erro de refresh.
994
885
  isLoading: false,
995
- error: e instanceof Error ? e : new Error(String(e)),
886
+ error: d instanceof Error ? d : new Error(String(d)),
996
887
  isStale: true
997
888
  }));
998
889
  };
999
- if (poll) {
1000
- let cancelled = false;
1001
- const fetchOnce = async () => {
1002
- if (cancelled || isDocumentHidden()) return;
1003
- try {
1004
- const snap = await col.list(dbQuery);
1005
- if (!cancelled) applySnap(snap);
1006
- } catch (e) {
1007
- if (!cancelled) applyError(e);
1008
- }
890
+ if (n) {
891
+ let d = false, g = async () => {
892
+ if (!(d || z()))
893
+ try {
894
+ let v = await w.list(m);
895
+ d || T(v);
896
+ } catch (v) {
897
+ d || R(v);
898
+ }
1009
899
  };
1010
- void fetchOnce();
1011
- const timer = setInterval(fetchOnce, intervalMs);
900
+ g();
901
+ let C = setInterval(g, i);
1012
902
  return () => {
1013
- cancelled = true;
1014
- clearInterval(timer);
1015
- mountedRef.current = false;
903
+ d = true, clearInterval(C), r.current = false;
1016
904
  };
1017
905
  }
1018
- let unsub;
906
+ let p;
1019
907
  try {
1020
- unsub = col.onSnapshot(dbQuery, applySnap);
1021
- } catch (e) {
1022
- applyError(e);
908
+ p = w.onSnapshot(m, T);
909
+ } catch (d) {
910
+ R(d);
1023
911
  }
1024
912
  return () => {
1025
- mountedRef.current = false;
1026
- unsub?.();
913
+ r.current = false, p?.();
1027
914
  };
1028
- }, [sourceKey, intervalMs, poll]);
1029
- return state;
915
+ }, [s, i, n]), c;
1030
916
  }
1031
- function useDoc(ref, options) {
1032
- const intervalMs = options?.intervalMs ?? DEFAULT_INTERVAL_MS;
1033
- const poll = options?.poll ?? false;
1034
- const refKey = ref && ref.id ? `${ref.collection}/${ref.id}` : null;
1035
- const [state, setState] = React2.useState({
917
+ function Ae(e, t) {
918
+ let i = t?.intervalMs ?? q, n = t?.poll ?? false, s = e && e.id ? `${e.collection}/${e.id}` : null, [c, o] = l.useState({
1036
919
  data: null,
1037
- isLoading: refKey !== null,
920
+ isLoading: s !== null,
1038
921
  error: null,
1039
922
  isStale: false,
1040
923
  lastUpdated: null
1041
- });
1042
- const mountedRef = React2.useRef(true);
1043
- const refRef = React2.useRef(ref);
1044
- refRef.current = ref;
1045
- React2.useEffect(() => {
1046
- mountedRef.current = true;
1047
- const current = refRef.current;
1048
- if (!current || refKey === null) {
1049
- setState({ data: null, isLoading: false, error: null, isStale: false, lastUpdated: null });
1050
- return () => {
1051
- mountedRef.current = false;
924
+ }), r = l.useRef(true), b = l.useRef(e);
925
+ return b.current = e, l.useEffect(() => {
926
+ r.current = true;
927
+ let u = b.current;
928
+ if (!u || s === null)
929
+ return o({ data: null, isLoading: false, error: null, isStale: false, lastUpdated: null }), () => {
930
+ r.current = false;
1052
931
  };
1053
- }
1054
- setState((prev) => ({ ...prev, isLoading: prev.data === null }));
1055
- const docRef = current.db.collection(current.collection).doc(current.id);
1056
- const id = current.id;
1057
- const applySnap = (snap) => {
1058
- if (!mountedRef.current) return;
1059
- setState({
1060
- data: rowFromGet(snap, id),
932
+ o((p) => ({ ...p, isLoading: p.data === null }));
933
+ let f = u.db.collection(u.collection).doc(u.id), m = u.id, w = (p) => {
934
+ r.current && o({
935
+ data: ye(p, m),
1061
936
  isLoading: false,
1062
937
  error: null,
1063
- isStale: snap?.stale === true,
938
+ isStale: p?.stale === true,
1064
939
  lastUpdated: Date.now()
1065
940
  });
1066
- };
1067
- const applyError = (e) => {
1068
- if (!mountedRef.current) return;
1069
- setState((prev) => ({
1070
- ...prev,
941
+ }, T = (p) => {
942
+ r.current && o((d) => ({
943
+ ...d,
1071
944
  isLoading: false,
1072
- error: e instanceof Error ? e : new Error(String(e)),
945
+ error: p instanceof Error ? p : new Error(String(p)),
1073
946
  isStale: true
1074
947
  }));
1075
948
  };
1076
- if (poll) {
1077
- let cancelled = false;
1078
- const fetchOnce = async () => {
1079
- if (cancelled || isDocumentHidden()) return;
1080
- try {
1081
- const snap = await docRef.get();
1082
- if (!cancelled) applySnap(snap);
1083
- } catch (e) {
1084
- if (!cancelled) applyError(e);
1085
- }
949
+ if (n) {
950
+ let p = false, d = async () => {
951
+ if (!(p || z()))
952
+ try {
953
+ let C = await f.get();
954
+ p || w(C);
955
+ } catch (C) {
956
+ p || T(C);
957
+ }
1086
958
  };
1087
- void fetchOnce();
1088
- const timer = setInterval(fetchOnce, intervalMs);
959
+ d();
960
+ let g = setInterval(d, i);
1089
961
  return () => {
1090
- cancelled = true;
1091
- clearInterval(timer);
1092
- mountedRef.current = false;
962
+ p = true, clearInterval(g), r.current = false;
1093
963
  };
1094
964
  }
1095
- let unsub;
965
+ let R;
1096
966
  try {
1097
- unsub = docRef.onSnapshot(applySnap);
1098
- } catch (e) {
1099
- applyError(e);
967
+ R = f.onSnapshot(w);
968
+ } catch (p) {
969
+ T(p);
1100
970
  }
1101
971
  return () => {
1102
- mountedRef.current = false;
1103
- unsub?.();
972
+ r.current = false, R?.();
1104
973
  };
1105
- }, [refKey, intervalMs, poll]);
1106
- return state;
974
+ }, [s, i, n]), c;
1107
975
  }
1108
- function resolveAuth(input) {
1109
- const maybe = input;
1110
- if (maybe.auth && typeof maybe.auth.onAuthStateChanged === "function") {
1111
- return maybe.auth;
1112
- }
1113
- return input;
976
+ function he(e) {
977
+ let t = e;
978
+ return t.auth && typeof t.auth.onAuthStateChanged == "function" ? t.auth : e;
1114
979
  }
1115
- function useUser(input, options) {
1116
- const timeoutMs = options?.timeoutMs ?? 8e3;
1117
- const auth = resolveAuth(input);
1118
- const [state, setState] = React2.useState(() => {
1119
- let seeded = null;
980
+ function Le(e, t) {
981
+ let i = t?.timeoutMs ?? 8e3, n = he(e), [s, c] = l.useState(() => {
982
+ let r = null;
1120
983
  try {
1121
- seeded = auth.getUser();
984
+ r = n.getUser();
1122
985
  } catch {
1123
- seeded = null;
986
+ r = null;
1124
987
  }
1125
- return { user: seeded, isLoading: seeded === null, error: null };
1126
- });
1127
- const mountedRef = React2.useRef(true);
1128
- React2.useEffect(() => {
1129
- mountedRef.current = true;
1130
- let settled = false;
1131
- const timer = setTimeout(() => {
1132
- if (!mountedRef.current || settled) return;
1133
- setState((prev) => prev.isLoading ? { ...prev, isLoading: false } : prev);
1134
- }, timeoutMs);
1135
- let unsub;
988
+ return { user: r, isLoading: r === null, error: null };
989
+ }), o = l.useRef(true);
990
+ return l.useEffect(() => {
991
+ o.current = true;
992
+ let r = false, b = setTimeout(() => {
993
+ !o.current || r || c((f) => f.isLoading ? { ...f, isLoading: false } : f);
994
+ }, i), u;
1136
995
  try {
1137
- unsub = auth.onAuthStateChanged((user) => {
1138
- if (!mountedRef.current) return;
1139
- settled = true;
1140
- setState({ user: user ?? null, isLoading: false, error: null });
996
+ u = n.onAuthStateChanged((f) => {
997
+ o.current && (r = !0, c({ user: f ?? null, isLoading: !1, error: null }));
998
+ });
999
+ } catch (f) {
1000
+ o.current && c({
1001
+ user: null,
1002
+ isLoading: false,
1003
+ error: f instanceof Error ? f : new Error(String(f))
1141
1004
  });
1142
- } catch (e) {
1143
- if (mountedRef.current) {
1144
- setState({
1145
- user: null,
1146
- isLoading: false,
1147
- error: e instanceof Error ? e : new Error(String(e))
1148
- });
1149
- }
1150
1005
  }
1151
1006
  return () => {
1152
- mountedRef.current = false;
1153
- clearTimeout(timer);
1154
- unsub?.();
1007
+ o.current = false, clearTimeout(b), u?.();
1155
1008
  };
1156
- }, [auth, timeoutMs]);
1157
- return state;
1009
+ }, [n, i]), s;
1158
1010
  }
1159
1011
 
1160
- export { CheckoutLink, EntitlementGate, NeetruAccountBar, NeetruLoginButton, fetchNeetruAccountBar, initialsFrom, useCollection, useDoc, useEntitlementContext, useUser };
1161
- //# sourceMappingURL=react.mjs.map
1162
- //# sourceMappingURL=react.mjs.map
1012
+ export { Ee as CheckoutLink, Ne as EntitlementGate, oe as NeetruAccountBar, De as NeetruLoginButton, W as fetchNeetruAccountBar, N as initialsFrom, Ue as useCollection, Ae as useDoc, _e as useEntitlementContext, Le as useUser };