@neetru/sdk 3.4.1 → 3.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var React = require('react');
3
+ var React2 = require('react');
4
4
 
5
5
  function _interopNamespace(e) {
6
6
  if (e && e.__esModule) return e;
@@ -20,10 +20,569 @@ function _interopNamespace(e) {
20
20
  return Object.freeze(n);
21
21
  }
22
22
 
23
- var React__namespace = /*#__PURE__*/_interopNamespace(React);
23
+ var React2__namespace = /*#__PURE__*/_interopNamespace(React2);
24
24
 
25
25
  // src/react.ts
26
26
 
27
+ // src/types.ts
28
+ var DEFAULT_BASE_URL = "https://api.neetru.com";
29
+
30
+ // src/account-bar.ts
31
+ var h = React2__namespace.createElement;
32
+ var DEFAULT_LABELS = {
33
+ accountButton: "Abrir menu da conta",
34
+ appsButton: "Seus produtos Neetru",
35
+ appsTitle: "Trocar de produto",
36
+ myAccount: "Minha conta Neetru",
37
+ accountSettings: "Configura\xE7\xF5es da conta",
38
+ signOut: "Sair",
39
+ currentBadge: "Atual",
40
+ emptyProducts: "Nenhum outro produto dispon\xEDvel."
41
+ };
42
+ async function fetchNeetruAccountBar(client) {
43
+ const auth = client.auth;
44
+ const idToken = typeof auth?.getIdToken === "function" ? auth.getIdToken() : null;
45
+ if (!idToken) return null;
46
+ const config = client.config;
47
+ const baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
48
+ const fetchFn = config.fetch ?? globalThis.fetch;
49
+ const url = `${baseUrl}/api/sdk/v1/account/bar`;
50
+ try {
51
+ const res = await fetchFn(url, {
52
+ headers: { authorization: `Bearer ${idToken}`, accept: "application/json" }
53
+ });
54
+ if (!res.ok) return null;
55
+ const body = await res.json();
56
+ if (!body || typeof body !== "object" || !body.account) return null;
57
+ return {
58
+ account: {
59
+ displayName: String(body.account.displayName ?? ""),
60
+ email: String(body.account.email ?? ""),
61
+ photoUrl: body.account.photoUrl ?? null
62
+ },
63
+ accountUrl: String(body.accountUrl ?? "https://minhaconta.neetru.com"),
64
+ products: Array.isArray(body.products) ? body.products.filter(
65
+ (p) => !!p && typeof p.slug === "string" && typeof p.url === "string"
66
+ ) : []
67
+ };
68
+ } catch {
69
+ return null;
70
+ }
71
+ }
72
+ function initialsFrom(nameOrEmail) {
73
+ const s = (nameOrEmail ?? "").trim();
74
+ if (!s) return "?";
75
+ const local = s.includes("@") ? s.split("@")[0] : s;
76
+ const parts = local.split(/[\s._-]+/).filter(Boolean);
77
+ if (parts.length === 0) return local.slice(0, 1).toUpperCase();
78
+ if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();
79
+ return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
80
+ }
81
+ var C = {
82
+ bg: "#ffffff",
83
+ bgHover: "#f5f5f5",
84
+ fg: "#0a0a0a",
85
+ muted: "#666666",
86
+ border: "#0a0a0a",
87
+ borderSoft: "#e5e5e5"
88
+ };
89
+ var SQUARE = 0;
90
+ function WaffleIcon({ size = 18, color = C.fg }) {
91
+ const dots = [0, 1, 2].flatMap((r) => [0, 1, 2].map((c) => ({ r, c })));
92
+ const gap = size / 3;
93
+ const dot = Math.max(2, size / 7);
94
+ return h(
95
+ "svg",
96
+ { width: size, height: size, viewBox: `0 0 ${size} ${size}`, "aria-hidden": true, style: { display: "block" } },
97
+ dots.map(
98
+ ({ r, c }) => h("rect", {
99
+ key: `${r}-${c}`,
100
+ x: c * gap + (gap - dot) / 2,
101
+ y: r * gap + (gap - dot) / 2,
102
+ width: dot,
103
+ height: dot,
104
+ fill: color
105
+ })
106
+ )
107
+ );
108
+ }
109
+ function focusables(container) {
110
+ if (!container) return [];
111
+ return Array.from(
112
+ container.querySelectorAll(
113
+ 'a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"])'
114
+ )
115
+ ).filter((el) => el.offsetParent !== null || el === document.activeElement);
116
+ }
117
+ function NeetruAccountBar({
118
+ client,
119
+ currentProductSlug,
120
+ settingsUrl,
121
+ onSignOut,
122
+ fetchBar,
123
+ labels,
124
+ className
125
+ }) {
126
+ const L = { ...DEFAULT_LABELS, ...labels };
127
+ const seedAccount = React2__namespace.useMemo(() => {
128
+ try {
129
+ const u = client.auth.getUser();
130
+ if (!u) return null;
131
+ return {
132
+ displayName: u.displayName || u.email || "",
133
+ email: u.email || "",
134
+ photoUrl: u.photoURL ?? null
135
+ };
136
+ } catch {
137
+ return null;
138
+ }
139
+ }, [client]);
140
+ const [data, setData] = React2__namespace.useState(null);
141
+ const [open, setOpen] = React2__namespace.useState(null);
142
+ const [signingOut, setSigningOut] = React2__namespace.useState(false);
143
+ const containerRef = React2__namespace.useRef(null);
144
+ const accountBtnRef = React2__namespace.useRef(null);
145
+ const appsBtnRef = React2__namespace.useRef(null);
146
+ const popoverRef = React2__namespace.useRef(null);
147
+ React2__namespace.useEffect(() => {
148
+ let cancelled = false;
149
+ const run = fetchBar ?? fetchNeetruAccountBar;
150
+ Promise.resolve(run(client)).then((res) => {
151
+ if (!cancelled && res) setData(res);
152
+ }).catch(() => {
153
+ });
154
+ return () => {
155
+ cancelled = true;
156
+ };
157
+ }, [client, fetchBar]);
158
+ const account = data?.account ?? seedAccount;
159
+ const accountUrl = data?.accountUrl ?? "https://minhaconta.neetru.com";
160
+ const products = data?.products ?? [];
161
+ const closeAndRefocus = React2__namespace.useCallback((which) => {
162
+ setOpen(null);
163
+ const trigger = which === "apps" ? appsBtnRef.current : accountBtnRef.current;
164
+ trigger?.focus();
165
+ }, []);
166
+ React2__namespace.useEffect(() => {
167
+ if (!open) return;
168
+ const first = focusables(popoverRef.current)[0];
169
+ first?.focus();
170
+ const onDocMouseDown = (e) => {
171
+ if (containerRef.current && !containerRef.current.contains(e.target)) {
172
+ setOpen(null);
173
+ }
174
+ };
175
+ document.addEventListener("mousedown", onDocMouseDown);
176
+ return () => document.removeEventListener("mousedown", onDocMouseDown);
177
+ }, [open]);
178
+ const onPopoverKeyDown = React2__namespace.useCallback(
179
+ (e) => {
180
+ if (e.key === "Escape") {
181
+ e.stopPropagation();
182
+ closeAndRefocus(open);
183
+ return;
184
+ }
185
+ const items = focusables(popoverRef.current);
186
+ if (items.length === 0) return;
187
+ const idx = items.indexOf(document.activeElement);
188
+ if (e.key === "Tab") {
189
+ if (e.shiftKey && idx <= 0) {
190
+ e.preventDefault();
191
+ items[items.length - 1].focus();
192
+ } else if (!e.shiftKey && idx === items.length - 1) {
193
+ e.preventDefault();
194
+ items[0].focus();
195
+ }
196
+ } else if (e.key === "ArrowDown") {
197
+ e.preventDefault();
198
+ items[(idx + 1) % items.length].focus();
199
+ } else if (e.key === "ArrowUp") {
200
+ e.preventDefault();
201
+ items[(idx - 1 + items.length) % items.length].focus();
202
+ }
203
+ },
204
+ [open, closeAndRefocus]
205
+ );
206
+ const handleSignOut = React2__namespace.useCallback(async () => {
207
+ if (signingOut) return;
208
+ setSigningOut(true);
209
+ try {
210
+ await client.auth.signOut();
211
+ } catch {
212
+ } finally {
213
+ setSigningOut(false);
214
+ setOpen(null);
215
+ onSignOut?.();
216
+ }
217
+ }, [client, signingOut, onSignOut]);
218
+ if (!account) return null;
219
+ const initials = initialsFrom(account.displayName || account.email);
220
+ const avatarInner = account.photoUrl ? h("img", {
221
+ src: account.photoUrl,
222
+ alt: "",
223
+ width: 32,
224
+ height: 32,
225
+ style: { width: 32, height: 32, objectFit: "cover", display: "block" }
226
+ }) : h(
227
+ "span",
228
+ {
229
+ "aria-hidden": true,
230
+ style: {
231
+ width: 32,
232
+ height: 32,
233
+ display: "inline-flex",
234
+ alignItems: "center",
235
+ justifyContent: "center",
236
+ backgroundColor: C.fg,
237
+ color: "#ffffff",
238
+ fontSize: 13,
239
+ fontWeight: 700,
240
+ letterSpacing: "0.02em"
241
+ }
242
+ },
243
+ initials
244
+ );
245
+ const iconBtnStyle = (active) => ({
246
+ display: "inline-flex",
247
+ alignItems: "center",
248
+ justifyContent: "center",
249
+ width: 36,
250
+ height: 36,
251
+ padding: 0,
252
+ borderRadius: SQUARE,
253
+ border: `1px solid ${active ? C.border : C.borderSoft}`,
254
+ backgroundColor: active ? C.bgHover : C.bg,
255
+ color: C.fg,
256
+ cursor: "pointer",
257
+ boxSizing: "border-box",
258
+ fontFamily: "inherit",
259
+ overflow: "hidden"
260
+ });
261
+ const appsButton = h(
262
+ "button",
263
+ {
264
+ type: "button",
265
+ ref: appsBtnRef,
266
+ "aria-label": L.appsButton,
267
+ "aria-haspopup": "menu",
268
+ "aria-expanded": open === "apps",
269
+ "data-neetru-appswitcher-button": "true",
270
+ onClick: () => setOpen((o) => o === "apps" ? null : "apps"),
271
+ style: iconBtnStyle(open === "apps")
272
+ },
273
+ h(WaffleIcon, {})
274
+ );
275
+ const accountButton = h(
276
+ "button",
277
+ {
278
+ type: "button",
279
+ ref: accountBtnRef,
280
+ "aria-label": `${L.accountButton}${account.displayName ? ` (${account.displayName})` : ""}`,
281
+ "aria-haspopup": "menu",
282
+ "aria-expanded": open === "account",
283
+ "data-neetru-account-button": "true",
284
+ onClick: () => setOpen((o) => o === "account" ? null : "account"),
285
+ style: { ...iconBtnStyle(open === "account"), width: 36, height: 36 }
286
+ },
287
+ avatarInner
288
+ );
289
+ const popoverStyle = {
290
+ position: "absolute",
291
+ top: "calc(100% + 6px)",
292
+ right: 0,
293
+ minWidth: 260,
294
+ maxWidth: 320,
295
+ backgroundColor: C.bg,
296
+ border: `1px solid ${C.border}`,
297
+ borderRadius: SQUARE,
298
+ zIndex: 1e3,
299
+ color: C.fg,
300
+ fontFamily: "inherit"
301
+ // BMW: sem sombra/glassmorphism — borda sólida define o recorte.
302
+ };
303
+ const menuItemStyle = {
304
+ display: "flex",
305
+ alignItems: "center",
306
+ gap: 10,
307
+ width: "100%",
308
+ padding: "10px 14px",
309
+ background: "transparent",
310
+ border: "none",
311
+ borderTop: `1px solid ${C.borderSoft}`,
312
+ color: C.fg,
313
+ fontSize: 14,
314
+ fontWeight: 400,
315
+ textAlign: "left",
316
+ textDecoration: "none",
317
+ cursor: "pointer",
318
+ boxSizing: "border-box",
319
+ fontFamily: "inherit"
320
+ };
321
+ const hoverHandlers = {
322
+ onMouseEnter: (e) => {
323
+ e.currentTarget.style.backgroundColor = C.bgHover;
324
+ },
325
+ onMouseLeave: (e) => {
326
+ e.currentTarget.style.backgroundColor = "transparent";
327
+ }
328
+ };
329
+ const accountPopover = open === "account" ? h(
330
+ "div",
331
+ {
332
+ ref: popoverRef,
333
+ role: "menu",
334
+ "aria-label": L.accountButton,
335
+ "data-neetru-account-menu": "true",
336
+ onKeyDown: onPopoverKeyDown,
337
+ style: popoverStyle
338
+ },
339
+ // Header identidade
340
+ h(
341
+ "div",
342
+ { style: { display: "flex", gap: 12, alignItems: "center", padding: 14 } },
343
+ h(
344
+ "span",
345
+ {
346
+ "aria-hidden": true,
347
+ style: {
348
+ width: 40,
349
+ height: 40,
350
+ flexShrink: 0,
351
+ display: "inline-flex",
352
+ alignItems: "center",
353
+ justifyContent: "center",
354
+ overflow: "hidden",
355
+ backgroundColor: account.photoUrl ? "transparent" : C.fg,
356
+ color: "#ffffff",
357
+ fontSize: 15,
358
+ fontWeight: 700
359
+ }
360
+ },
361
+ account.photoUrl ? h("img", {
362
+ src: account.photoUrl,
363
+ alt: "",
364
+ width: 40,
365
+ height: 40,
366
+ style: { width: 40, height: 40, objectFit: "cover", display: "block" }
367
+ }) : initials
368
+ ),
369
+ h(
370
+ "span",
371
+ { style: { display: "flex", flexDirection: "column", minWidth: 0 } },
372
+ h(
373
+ "span",
374
+ {
375
+ style: {
376
+ fontWeight: 700,
377
+ fontSize: 14,
378
+ whiteSpace: "nowrap",
379
+ overflow: "hidden",
380
+ textOverflow: "ellipsis"
381
+ }
382
+ },
383
+ account.displayName || account.email
384
+ ),
385
+ account.email ? h(
386
+ "span",
387
+ {
388
+ style: {
389
+ color: C.muted,
390
+ fontSize: 12,
391
+ whiteSpace: "nowrap",
392
+ overflow: "hidden",
393
+ textOverflow: "ellipsis"
394
+ }
395
+ },
396
+ account.email
397
+ ) : null
398
+ )
399
+ ),
400
+ // Minha conta Neetru
401
+ h(
402
+ "a",
403
+ {
404
+ role: "menuitem",
405
+ href: accountUrl,
406
+ target: "_blank",
407
+ rel: "noopener noreferrer",
408
+ style: menuItemStyle,
409
+ ...hoverHandlers
410
+ },
411
+ L.myAccount
412
+ ),
413
+ // Configurações da conta (deste produto)
414
+ settingsUrl ? h(
415
+ "a",
416
+ { role: "menuitem", href: settingsUrl, style: menuItemStyle, ...hoverHandlers },
417
+ L.accountSettings
418
+ ) : null,
419
+ // Sair
420
+ h(
421
+ "button",
422
+ {
423
+ type: "button",
424
+ role: "menuitem",
425
+ onClick: handleSignOut,
426
+ disabled: signingOut,
427
+ "data-neetru-signout": "true",
428
+ style: { ...menuItemStyle, cursor: signingOut ? "not-allowed" : "pointer" },
429
+ ...hoverHandlers
430
+ },
431
+ signingOut ? `${L.signOut}\u2026` : L.signOut
432
+ )
433
+ ) : null;
434
+ const appsPopover = open === "apps" ? h(
435
+ "div",
436
+ {
437
+ ref: popoverRef,
438
+ role: "menu",
439
+ "aria-label": L.appsTitle,
440
+ "data-neetru-appswitcher-menu": "true",
441
+ onKeyDown: onPopoverKeyDown,
442
+ style: { ...popoverStyle, minWidth: 280 }
443
+ },
444
+ h(
445
+ "div",
446
+ {
447
+ style: {
448
+ padding: "12px 14px 8px",
449
+ fontSize: 11,
450
+ fontWeight: 700,
451
+ letterSpacing: "0.08em",
452
+ textTransform: "uppercase",
453
+ color: C.muted
454
+ }
455
+ },
456
+ L.appsTitle
457
+ ),
458
+ products.length === 0 ? h(
459
+ "div",
460
+ { style: { padding: "4px 14px 16px", fontSize: 13, color: C.muted } },
461
+ L.emptyProducts
462
+ ) : h(
463
+ "div",
464
+ {
465
+ style: {
466
+ display: "grid",
467
+ gridTemplateColumns: "1fr 1fr",
468
+ gap: 1,
469
+ padding: 1,
470
+ backgroundColor: C.borderSoft
471
+ }
472
+ },
473
+ products.map((p) => {
474
+ const isCurrent = !!currentProductSlug && p.slug === currentProductSlug;
475
+ return h(
476
+ "a",
477
+ {
478
+ key: p.slug,
479
+ role: "menuitem",
480
+ href: p.url,
481
+ "aria-current": isCurrent ? "true" : void 0,
482
+ "data-neetru-product": p.slug,
483
+ "data-current": isCurrent ? "true" : void 0,
484
+ title: p.name,
485
+ style: {
486
+ display: "flex",
487
+ flexDirection: "column",
488
+ alignItems: "center",
489
+ gap: 6,
490
+ padding: "14px 8px",
491
+ textDecoration: "none",
492
+ color: C.fg,
493
+ backgroundColor: isCurrent ? C.bgHover : C.bg,
494
+ cursor: "pointer",
495
+ boxSizing: "border-box"
496
+ },
497
+ onMouseEnter: (e) => {
498
+ e.currentTarget.style.backgroundColor = C.bgHover;
499
+ },
500
+ onMouseLeave: (e) => {
501
+ e.currentTarget.style.backgroundColor = isCurrent ? C.bgHover : C.bg;
502
+ }
503
+ },
504
+ // Tile/ícone
505
+ p.iconUrl ? h("img", {
506
+ src: p.iconUrl,
507
+ alt: "",
508
+ width: 32,
509
+ height: 32,
510
+ style: { width: 32, height: 32, objectFit: "cover", display: "block" }
511
+ }) : h(
512
+ "span",
513
+ {
514
+ "aria-hidden": true,
515
+ style: {
516
+ width: 32,
517
+ height: 32,
518
+ display: "inline-flex",
519
+ alignItems: "center",
520
+ justifyContent: "center",
521
+ backgroundColor: C.fg,
522
+ color: "#ffffff",
523
+ fontSize: 13,
524
+ fontWeight: 700
525
+ }
526
+ },
527
+ initialsFrom(p.name)
528
+ ),
529
+ h(
530
+ "span",
531
+ {
532
+ style: {
533
+ fontSize: 12,
534
+ fontWeight: isCurrent ? 700 : 400,
535
+ textAlign: "center",
536
+ lineHeight: 1.2,
537
+ maxWidth: "100%",
538
+ overflow: "hidden",
539
+ textOverflow: "ellipsis",
540
+ whiteSpace: "nowrap",
541
+ width: "100%"
542
+ }
543
+ },
544
+ p.name
545
+ ),
546
+ isCurrent ? h(
547
+ "span",
548
+ {
549
+ style: {
550
+ fontSize: 9,
551
+ fontWeight: 700,
552
+ letterSpacing: "0.08em",
553
+ textTransform: "uppercase",
554
+ color: C.muted
555
+ }
556
+ },
557
+ L.currentBadge
558
+ ) : null
559
+ );
560
+ })
561
+ )
562
+ ) : null;
563
+ return h(
564
+ "div",
565
+ {
566
+ ref: containerRef,
567
+ className,
568
+ "data-neetru-account-bar": "true",
569
+ style: {
570
+ position: "relative",
571
+ display: "inline-flex",
572
+ alignItems: "center",
573
+ gap: 8,
574
+ // Superfície de cliente = sempre claro (dark é staff-only).
575
+ colorScheme: "light",
576
+ fontFamily: "inherit"
577
+ }
578
+ },
579
+ appsButton,
580
+ accountButton,
581
+ accountPopover,
582
+ appsPopover
583
+ );
584
+ }
585
+
27
586
  // src/firestore-compat.ts
28
587
  function toDbQuery(constraints) {
29
588
  const whereFilters = [];
@@ -64,9 +623,9 @@ function CheckoutLink({
64
623
  noAutoRedirect,
65
624
  ...rest
66
625
  }) {
67
- const [submitting, setSubmitting] = React__namespace.useState(false);
626
+ const [submitting, setSubmitting] = React2__namespace.useState(false);
68
627
  const checkout = client.checkout;
69
- const handleClick = React__namespace.useCallback(
628
+ const handleClick = React2__namespace.useCallback(
70
629
  async (event) => {
71
630
  event.preventDefault();
72
631
  if (submitting) return;
@@ -93,7 +652,7 @@ function CheckoutLink({
93
652
  },
94
653
  [submitting, checkout, productId, planId, callbackUrl, tenantType, tenantId, noAutoRedirect, onIntentCreated, onError]
95
654
  );
96
- return React__namespace.createElement(
655
+ return React2__namespace.createElement(
97
656
  "a",
98
657
  {
99
658
  ...rest,
@@ -109,7 +668,7 @@ var NEETRU_FLAME_PATH = "M 281 5.163 C 240.659 26.308, 211.260 52.739, 187.750 8
109
668
  var NEETRU_FLAME_VIEWBOX = "0 0 527 760";
110
669
  var NEETRU_FLAME_ASPECT = 527 / 760;
111
670
  function NeetruFlameIcon({ fill, size = 16 }) {
112
- return React__namespace.createElement(
671
+ return React2__namespace.createElement(
113
672
  "svg",
114
673
  {
115
674
  viewBox: NEETRU_FLAME_VIEWBOX,
@@ -118,7 +677,7 @@ function NeetruFlameIcon({ fill, size = 16 }) {
118
677
  "aria-hidden": true,
119
678
  style: { flexShrink: 0 }
120
679
  },
121
- React__namespace.createElement("path", { d: NEETRU_FLAME_PATH, fill })
680
+ React2__namespace.createElement("path", { d: NEETRU_FLAME_PATH, fill })
122
681
  );
123
682
  }
124
683
  var NEETRU_LOGIN_BUTTON_THEME = {
@@ -137,11 +696,11 @@ function NeetruLoginButton({
137
696
  disabled,
138
697
  ...rest
139
698
  }) {
140
- const [isLoading, setIsLoading] = React__namespace.useState(false);
141
- const [isHover, setIsHover] = React__namespace.useState(false);
699
+ const [isLoading, setIsLoading] = React2__namespace.useState(false);
700
+ const [isHover, setIsHover] = React2__namespace.useState(false);
142
701
  const colors = NEETRU_LOGIN_BUTTON_THEME[theme];
143
702
  const isDisabled = Boolean(disabled) || isLoading;
144
- const handleClick = React__namespace.useCallback(async () => {
703
+ const handleClick = React2__namespace.useCallback(async () => {
145
704
  if (isDisabled) return;
146
705
  setIsLoading(true);
147
706
  try {
@@ -153,7 +712,7 @@ function NeetruLoginButton({
153
712
  setIsLoading(false);
154
713
  }
155
714
  }, [client, redirectUri, scope, postLoginRedirect, isDisabled, onError]);
156
- return React__namespace.createElement(
715
+ return React2__namespace.createElement(
157
716
  "button",
158
717
  {
159
718
  ...rest,
@@ -190,15 +749,15 @@ function NeetruLoginButton({
190
749
  ...style
191
750
  }
192
751
  },
193
- React__namespace.createElement(NeetruFlameIcon, { fill: colors.fg }),
194
- React__namespace.createElement("span", null, isLoading ? "Entrando\u2026" : label)
752
+ React2__namespace.createElement(NeetruFlameIcon, { fill: colors.fg }),
753
+ React2__namespace.createElement("span", null, isLoading ? "Entrando\u2026" : label)
195
754
  );
196
755
  }
197
- var EntitlementContext = React__namespace.createContext({
756
+ var EntitlementContext = React2__namespace.createContext({
198
757
  readonly: false
199
758
  });
200
759
  function useEntitlementContext() {
201
- return React__namespace.useContext(EntitlementContext);
760
+ return React2__namespace.useContext(EntitlementContext);
202
761
  }
203
762
  function EntitlementGate({
204
763
  client,
@@ -209,12 +768,12 @@ function EntitlementGate({
209
768
  loading,
210
769
  children
211
770
  }) {
212
- const [state, setState] = React__namespace.useState({
771
+ const [state, setState] = React2__namespace.useState({
213
772
  status: "loading"
214
773
  });
215
774
  const resolvedSlug = productSlug ?? client.config.productId ?? "";
216
775
  const resolvedTenantId = client.config.tenantId;
217
- React__namespace.useEffect(() => {
776
+ React2__namespace.useEffect(() => {
218
777
  let cancelled = false;
219
778
  const run = async () => {
220
779
  try {
@@ -250,15 +809,15 @@ function EntitlementGate({
250
809
  };
251
810
  }, [client, feature, resolvedSlug, resolvedTenantId]);
252
811
  if (state.status === "loading") {
253
- return React__namespace.createElement(React__namespace.Fragment, null, loading ?? null);
812
+ return React2__namespace.createElement(React2__namespace.Fragment, null, loading ?? null);
254
813
  }
255
814
  const result = state.result;
256
815
  const allowed = result?.allowed === true;
257
816
  const isReadonly = !allowed && (mode === "readonly" || result?.behavior === "readonly");
258
817
  if (!allowed && mode === "block" && !isReadonly) {
259
- return React__namespace.createElement(React__namespace.Fragment, null, fallback ?? null);
818
+ return React2__namespace.createElement(React2__namespace.Fragment, null, fallback ?? null);
260
819
  }
261
- return React__namespace.createElement(
820
+ return React2__namespace.createElement(
262
821
  EntitlementContext.Provider,
263
822
  {
264
823
  value: {
@@ -303,17 +862,17 @@ function useCollection(source, options) {
303
862
  const sourceKey = serializeSource(
304
863
  source
305
864
  );
306
- const [state, setState] = React__namespace.useState({
865
+ const [state, setState] = React2__namespace.useState({
307
866
  data: null,
308
867
  isLoading: sourceKey !== null,
309
868
  error: null,
310
869
  isStale: false,
311
870
  lastUpdated: null
312
871
  });
313
- const mountedRef = React__namespace.useRef(true);
314
- const sourceRef = React__namespace.useRef(source);
872
+ const mountedRef = React2__namespace.useRef(true);
873
+ const sourceRef = React2__namespace.useRef(source);
315
874
  sourceRef.current = source;
316
- React__namespace.useEffect(() => {
875
+ React2__namespace.useEffect(() => {
317
876
  mountedRef.current = true;
318
877
  const current = sourceRef.current;
319
878
  if (!current || sourceKey === null) {
@@ -382,17 +941,17 @@ function useDoc(ref, options) {
382
941
  const intervalMs = options?.intervalMs ?? DEFAULT_INTERVAL_MS;
383
942
  const poll = options?.poll ?? false;
384
943
  const refKey = ref && ref.id ? `${ref.collection}/${ref.id}` : null;
385
- const [state, setState] = React__namespace.useState({
944
+ const [state, setState] = React2__namespace.useState({
386
945
  data: null,
387
946
  isLoading: refKey !== null,
388
947
  error: null,
389
948
  isStale: false,
390
949
  lastUpdated: null
391
950
  });
392
- const mountedRef = React__namespace.useRef(true);
393
- const refRef = React__namespace.useRef(ref);
951
+ const mountedRef = React2__namespace.useRef(true);
952
+ const refRef = React2__namespace.useRef(ref);
394
953
  refRef.current = ref;
395
- React__namespace.useEffect(() => {
954
+ React2__namespace.useEffect(() => {
396
955
  mountedRef.current = true;
397
956
  const current = refRef.current;
398
957
  if (!current || refKey === null) {
@@ -465,7 +1024,7 @@ function resolveAuth(input) {
465
1024
  function useUser(input, options) {
466
1025
  const timeoutMs = options?.timeoutMs ?? 8e3;
467
1026
  const auth = resolveAuth(input);
468
- const [state, setState] = React__namespace.useState(() => {
1027
+ const [state, setState] = React2__namespace.useState(() => {
469
1028
  let seeded = null;
470
1029
  try {
471
1030
  seeded = auth.getUser();
@@ -474,8 +1033,8 @@ function useUser(input, options) {
474
1033
  }
475
1034
  return { user: seeded, isLoading: seeded === null, error: null };
476
1035
  });
477
- const mountedRef = React__namespace.useRef(true);
478
- React__namespace.useEffect(() => {
1036
+ const mountedRef = React2__namespace.useRef(true);
1037
+ React2__namespace.useEffect(() => {
479
1038
  mountedRef.current = true;
480
1039
  let settled = false;
481
1040
  const timer = setTimeout(() => {
@@ -509,7 +1068,10 @@ function useUser(input, options) {
509
1068
 
510
1069
  exports.CheckoutLink = CheckoutLink;
511
1070
  exports.EntitlementGate = EntitlementGate;
1071
+ exports.NeetruAccountBar = NeetruAccountBar;
512
1072
  exports.NeetruLoginButton = NeetruLoginButton;
1073
+ exports.fetchNeetruAccountBar = fetchNeetruAccountBar;
1074
+ exports.initialsFrom = initialsFrom;
513
1075
  exports.useCollection = useCollection;
514
1076
  exports.useDoc = useDoc;
515
1077
  exports.useEntitlementContext = useEntitlementContext;