@lunora/studio 1.0.0-alpha.38 → 1.0.0-alpha.39

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 (121) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.js +10 -10
  3. package/dist/mount.js +1 -1
  4. package/dist/packem_chunks/ApiTab.js +3 -3
  5. package/dist/packem_chunks/AuditPanel.js +3 -3
  6. package/dist/packem_chunks/ExportImportPanel.js +2 -2
  7. package/dist/packem_chunks/FileBrowser.js +2 -2
  8. package/dist/packem_chunks/FunctionRunner.js +1 -1
  9. package/dist/packem_chunks/FunctionStatsPanel.js +3 -3
  10. package/dist/packem_chunks/HealthPanel.js +2 -2
  11. package/dist/packem_chunks/InsightsPanel.js +3 -3
  12. package/dist/packem_chunks/LogsPanel.js +2 -2
  13. package/dist/packem_chunks/MailPanel.js +3 -3
  14. package/dist/packem_chunks/MetricsPanel.js +2 -2
  15. package/dist/packem_chunks/MigrationsPanel.js +3 -3
  16. package/dist/packem_chunks/PitrPanel.js +1 -1
  17. package/dist/packem_chunks/SchemaViewer.js +1 -1
  18. package/dist/packem_chunks/SecurityAdvisorPanel.js +2 -2
  19. package/dist/packem_chunks/SettingsPanel.js +2 -2
  20. package/dist/packem_chunks/SqlEditorPanel.js +149 -139
  21. package/dist/packem_chunks/TableEditor.js +3 -3
  22. package/dist/packem_chunks/analytics-panel.js +1 -1
  23. package/dist/packem_chunks/auth-config-panel.js +1 -1
  24. package/dist/packem_chunks/auth-sessions-panel.js +2 -2
  25. package/dist/packem_chunks/containers-panel.js +1 -1
  26. package/dist/packem_chunks/dashboards-panel.js +2 -2
  27. package/dist/packem_chunks/fanout-panel.js +2 -2
  28. package/dist/packem_chunks/flags-panel.js +2 -2
  29. package/dist/packem_chunks/kv-browser.js +2 -2
  30. package/dist/packem_chunks/log-drains-panel.js +1 -1
  31. package/dist/packem_chunks/organizations-panel.js +3 -3
  32. package/dist/packem_chunks/payments-panel.js +3 -3
  33. package/dist/packem_chunks/permissions-panel.js +3 -3
  34. package/dist/packem_chunks/queues-panel.js +242 -219
  35. package/dist/packem_chunks/rls-panel.js +2 -2
  36. package/dist/packem_chunks/schedule-panel.js +3 -3
  37. package/dist/packem_chunks/storage-rules-panel.js +2 -2
  38. package/dist/packem_chunks/subscriptions-panel.js +2 -2
  39. package/dist/packem_chunks/users-panel.js +3 -3
  40. package/dist/packem_chunks/vector-browser.js +1 -1
  41. package/dist/packem_chunks/workflows-panel.js +2 -2
  42. package/dist/packem_shared/{ApiDocsPanel-D4CJf2ad.js → ApiDocsPanel-CBma-lnp.js} +1 -1
  43. package/dist/packem_shared/{ApiReferencePanel-Co_wpRF2.js → ApiReferencePanel-CQM3pPN7.js} +1 -1
  44. package/dist/packem_shared/{CommandPalette-BUPpbpMc.js → CommandPalette-X2tkbyHk.js} +1 -1
  45. package/dist/packem_shared/{DataBrowser-BeVNxSVm.js → DataBrowser-D2ywrdId.js} +5 -5
  46. package/dist/packem_shared/{GlobalDataBrowser-ErfvIs1S.js → GlobalDataBrowser-BkTPLzAY.js} +3 -3
  47. package/dist/packem_shared/{HomePanel-D9MQk8I7.js → HomePanel-D1Q9LZgK.js} +3 -3
  48. package/dist/packem_shared/{OpenRpcReferencePanel-DLWzrIx9.js → OpenRpcReferencePanel-Dno-hfDb.js} +1 -1
  49. package/dist/packem_shared/{ScheduledJobs-ClaNpZsg.js → ScheduledJobs-Ctw4jYtU.js} +2 -2
  50. package/dist/packem_shared/{Studio-C48P1K5W.js → Studio-lJhzDAze.js} +4 -4
  51. package/dist/packem_shared/{StudioApp-Cqh-SYm2.js → StudioApp-DiMkupvZ.js} +3 -12
  52. package/dist/packem_shared/{advisor-view-D3-U4kRR.js → advisor-view-BX8OhG0w.js} +1 -1
  53. package/dist/packem_shared/{browser-storage-tLOxkIHd.js → browser-storage-BTrX4y3B.js} +32 -2
  54. package/dist/packem_shared/{data-grid-Jz8FqQ2C.js → data-grid-CdXztApG.js} +1 -1
  55. package/dist/packem_shared/{error-alert-BBT6D22d.js → error-alert-CXjqyGw9.js} +1 -1
  56. package/dist/packem_shared/{grid-features-CUr8Z1_O.js → grid-features-BF-KBDFz.js} +128 -65
  57. package/dist/packem_shared/{home-panel-CoGxi-oj.js → home-panel-TFcRf9Ui.js} +272 -22
  58. package/dist/packem_shared/{internal-DTsYVn-g.js → internal-CYcbqMjX.js} +15 -3
  59. package/dist/packem_shared/{reference-view-CSKyUyPl.js → reference-view-DUiJcILV.js} +1 -1
  60. package/dist/packem_shared/{studio-CPHA_-3I.js → studio-Dh9UlaF_.js} +3 -3
  61. package/dist/packem_shared/{table-list-sidebar-B5psdSV1.js → table-list-sidebar-UVIXQJdU.js} +1 -1
  62. package/dist/packem_shared/{use-admin-query-BHPKmPuj.js → use-admin-query-CfHYWx5n.js} +1 -1
  63. package/dist/packem_shared/{use-async-submit-BWMDwRa4.js → use-async-submit-DJQiPc-_.js} +2 -2
  64. package/dist/standalone/{chunk-ZL4E2WVF.js → chunk-23C4TCRO.js} +1 -1
  65. package/dist/standalone/{chunk-NV6RHG5L.js → chunk-5ZAA2PVR.js} +1 -1
  66. package/dist/standalone/{chunk-Q3PTSVVU.js → chunk-676HEBIR.js} +1 -1
  67. package/dist/standalone/{chunk-Y2ZPNDL7.js → chunk-6VO23MMW.js} +1 -1
  68. package/dist/standalone/{chunk-2GFAOIC3.js → chunk-7RE5UW27.js} +1 -1
  69. package/dist/standalone/{chunk-4FL3EDN5.js → chunk-AAVIFQ4Y.js} +1 -1
  70. package/dist/standalone/{chunk-SE2TQAHJ.js → chunk-AJFQ3LNM.js} +1 -1
  71. package/dist/standalone/chunk-AJULNB46.js +4 -0
  72. package/dist/standalone/{chunk-6GFEVKJP.js → chunk-BGXOXASQ.js} +1 -1
  73. package/dist/standalone/{chunk-3DBG4RIV.js → chunk-BKW7FFEO.js} +1 -1
  74. package/dist/standalone/{chunk-OES45DFG.js → chunk-BXOYVWJR.js} +1 -1
  75. package/dist/standalone/{chunk-OIC7EJWI.js → chunk-C7WTJLC3.js} +1 -1
  76. package/dist/standalone/{chunk-AJIUI7DD.js → chunk-CACB34RQ.js} +1 -1
  77. package/dist/standalone/{chunk-TI7SE33D.js → chunk-CICVBMEN.js} +1 -1
  78. package/dist/standalone/{chunk-VFJPO4UO.js → chunk-CWEAJUHW.js} +1 -1
  79. package/dist/standalone/{chunk-FA3CCTXK.js → chunk-DECHEGIC.js} +1 -1
  80. package/dist/standalone/{chunk-PVZI3CXP.js → chunk-E75ANNWX.js} +7 -7
  81. package/dist/standalone/{chunk-MZ756AFF.js → chunk-ERJNDIXC.js} +1 -1
  82. package/dist/standalone/{chunk-I3VXCZZL.js → chunk-FKACHRWO.js} +1 -1
  83. package/dist/standalone/{chunk-X7RPB4K4.js → chunk-FSGCANAU.js} +1 -1
  84. package/dist/standalone/{chunk-34OQUHSV.js → chunk-H6RKXQZU.js} +1 -1
  85. package/dist/standalone/chunk-HZTGDL4L.js +1 -0
  86. package/dist/standalone/{chunk-FCSPAJW4.js → chunk-I7ZZRM7I.js} +1 -1
  87. package/dist/standalone/{chunk-OLE2AYTD.js → chunk-J46WXQYL.js} +1 -1
  88. package/dist/standalone/{chunk-2F4VYKM6.js → chunk-JVODY4EP.js} +1 -1
  89. package/dist/standalone/{chunk-IU6GTBPD.js → chunk-LYB5L53X.js} +1 -1
  90. package/dist/standalone/chunk-MJWVMKQ4.js +6 -0
  91. package/dist/standalone/chunk-MT2J3H7O.js +3 -0
  92. package/dist/standalone/{chunk-P5JW7HKP.js → chunk-N746FOQP.js} +1 -1
  93. package/dist/standalone/{chunk-P3ZMBPCY.js → chunk-NC6MBMSI.js} +1 -1
  94. package/dist/standalone/chunk-NN27EDQB.js +1 -0
  95. package/dist/standalone/{chunk-AJKR6PY7.js → chunk-NY6GDADQ.js} +1 -1
  96. package/dist/standalone/{chunk-R5OQZYSW.js → chunk-OY3HD7BJ.js} +1 -1
  97. package/dist/standalone/{chunk-4JOKDSPU.js → chunk-P5HJXCZS.js} +1 -1
  98. package/dist/standalone/{chunk-GM4NPF3W.js → chunk-PTS5TW3J.js} +1 -1
  99. package/dist/standalone/{chunk-IQ466Q6W.js → chunk-QDBOPDJ7.js} +1 -1
  100. package/dist/standalone/{chunk-KQTCLPLO.js → chunk-QHFTGJPS.js} +1 -1
  101. package/dist/standalone/{chunk-N7G5I47W.js → chunk-SSI4G2MY.js} +1 -1
  102. package/dist/standalone/{chunk-QKQABJBE.js → chunk-TH45YG6Q.js} +1 -1
  103. package/dist/standalone/{chunk-WXPWVBIY.js → chunk-UGUEC6BC.js} +1 -1
  104. package/dist/standalone/{chunk-K3GNLVYK.js → chunk-UKDJ4H7I.js} +1 -1
  105. package/dist/standalone/{chunk-O3I57FXK.js → chunk-V6IWFYAQ.js} +1 -1
  106. package/dist/standalone/{chunk-7FF76BYY.js → chunk-V7SRH36W.js} +1 -1
  107. package/dist/standalone/{chunk-XFSUINL3.js → chunk-WPNXY7IS.js} +1 -1
  108. package/dist/standalone/{chunk-PZ7HD5T2.js → chunk-X33MSJPP.js} +1 -1
  109. package/dist/standalone/{chunk-LEHGGJP2.js → chunk-XRNXOIVZ.js} +1 -1
  110. package/dist/standalone/{chunk-TDL7NEWA.js → chunk-YBGC4PPD.js} +1 -1
  111. package/dist/standalone/{chunk-HLZ4YLRK.js → chunk-YNZ7ARWW.js} +1 -1
  112. package/dist/standalone/{chunk-XGUOXHX4.js → chunk-YTO65GHS.js} +1 -1
  113. package/dist/standalone/{chunk-JTTVXBLU.js → chunk-ZE6FT5Z3.js} +1 -1
  114. package/dist/standalone/studio.js +31 -31
  115. package/dist/styles.css +1 -1
  116. package/package.json +2 -2
  117. package/dist/standalone/chunk-2SAZ5BZ5.js +0 -4
  118. package/dist/standalone/chunk-2SE7II7A.js +0 -1
  119. package/dist/standalone/chunk-3UFZCRWL.js +0 -1
  120. package/dist/standalone/chunk-IJPFHUJK.js +0 -2
  121. package/dist/standalone/chunk-ZYRGPDZB.js +0 -1
@@ -4,14 +4,15 @@ import { useState, useEffect, Suspense, lazy } from 'react';
4
4
  import { B as Badge } from './badge-B2PKA1-5.js';
5
5
  import { a as CardContent, C as Card } from './card-DURq3ElK.js';
6
6
  import { E as EmptyState } from './empty-state-DY_oe0k6.js';
7
- import { u as useAdminQuery } from './use-admin-query-BHPKmPuj.js';
7
+ import { u as useAdminQuery } from './use-admin-query-CfHYWx5n.js';
8
8
  import { useT } from './DEFAULT_LOCALE-CiX4W7Kr.js';
9
9
  import { ADMIN_FUNCTIONS } from './ADMIN_FUNCTIONS-BHHJi3Gb.js';
10
- import { f as fireAndForget, c as callOptions, a as adminRef, j as formatBytes } from './internal-DTsYVn-g.js';
10
+ import { f as fireAndForget, c as callOptions, a as adminRef, r as resolveOrigin, g as copyToClipboard, j as formatBytes } from './internal-CYcbqMjX.js';
11
11
  import { c as cn } from './utils-B05Dmz_H.js';
12
12
  import { deriveInsights } from './DEFAULT_INSIGHT_THRESHOLDS-DjF0h-gA.js';
13
13
  import { useLunora } from '@lunora/react';
14
14
  import { jsxDEV } from 'react/jsx-dev-runtime';
15
+ import { B as Button } from './button-BhsN2uZH.js';
15
16
 
16
17
  const STUDIO_FEATURES = adminRef(ADMIN_FUNCTIONS.studioFeatures);
17
18
  const DEFAULT_STUDIO_FEATURES = {
@@ -372,6 +373,248 @@ function _temp4(group) {
372
373
  }, group.tab, false);
373
374
  }
374
375
 
376
+ const MCP_TOOLS = [{
377
+ name: "lunora_list_functions",
378
+ summary: "list every query, mutation, and action with its path"
379
+ }, {
380
+ name: "lunora_list_tables",
381
+ summary: "list the schema's tables"
382
+ }, {
383
+ name: "lunora_get_function_schema",
384
+ summary: "read a function's argument JSON Schema before calling it"
385
+ }, {
386
+ name: "lunora_run_query",
387
+ summary: "run a read-only query"
388
+ }, {
389
+ name: "lunora_run_mutation",
390
+ summary: "run a mutation — writes; only when LUNORA_MCP_ALLOW_WRITES is set"
391
+ }, {
392
+ name: "lunora_run_action",
393
+ summary: "run an action — writes/effects; only when LUNORA_MCP_ALLOW_WRITES is set"
394
+ }];
395
+ const buildMcpConfig = (origin) => JSON.stringify({
396
+ mcpServers: {
397
+ lunora: {
398
+ args: ["-y", "@lunora/mcp"],
399
+ command: "npx",
400
+ env: {
401
+ LUNORA_ADMIN_TOKEN: "<your-admin-token>",
402
+ LUNORA_URL: origin
403
+ }
404
+ }
405
+ }
406
+ }, null, 2);
407
+ const buildAgentPrompt = (origin) => {
408
+ const tools = MCP_TOOLS.map((tool) => `- ${tool.name} — ${tool.summary}`).join("\n");
409
+ return [`You have a Lunora MCP server connected to the deployment at ${origin}.`, "It exposes this backend's functions and schema so you can inspect and operate it:", tools, "", `Start by calling lunora_list_functions and lunora_list_tables to learn what exists, then lunora_get_function_schema before any run call. The full HTTP API is also documented at ${origin}/_lunora/admin/openapi (that endpoint needs the same admin token the MCP server is configured with).`].join("\n");
410
+ };
411
+ const COPIED_RESET_MS = 1500;
412
+ const ConnectAgentCard = () => {
413
+ const $ = c(35);
414
+ const t = useT();
415
+ let t0;
416
+ if ($[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
417
+ t0 = resolveOrigin();
418
+ $[0] = t0;
419
+ } else {
420
+ t0 = $[0];
421
+ }
422
+ const origin = t0;
423
+ const [copied, setCopied] = useState(null);
424
+ let t1;
425
+ let t2;
426
+ if ($[1] !== copied) {
427
+ t1 = () => {
428
+ if (copied === null) {
429
+ return;
430
+ }
431
+ const timer = globalThis.setTimeout(() => {
432
+ setCopied(null);
433
+ }, COPIED_RESET_MS);
434
+ return () => {
435
+ globalThis.clearTimeout(timer);
436
+ };
437
+ };
438
+ t2 = [copied];
439
+ $[1] = copied;
440
+ $[2] = t1;
441
+ $[3] = t2;
442
+ } else {
443
+ t1 = $[2];
444
+ t2 = $[3];
445
+ }
446
+ useEffect(t1, t2);
447
+ let t3;
448
+ if ($[4] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
449
+ t3 = (target, text) => {
450
+ if (!copyToClipboard(text)) {
451
+ return;
452
+ }
453
+ setCopied(target);
454
+ };
455
+ $[4] = t3;
456
+ } else {
457
+ t3 = $[4];
458
+ }
459
+ const copy = t3;
460
+ let t4;
461
+ if ($[5] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
462
+ t4 = () => {
463
+ copy("config", buildMcpConfig(origin));
464
+ };
465
+ $[5] = t4;
466
+ } else {
467
+ t4 = $[5];
468
+ }
469
+ const onCopyConfig = t4;
470
+ let t5;
471
+ if ($[6] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
472
+ t5 = () => {
473
+ copy("prompt", buildAgentPrompt(origin));
474
+ };
475
+ $[6] = t5;
476
+ } else {
477
+ t5 = $[6];
478
+ }
479
+ const onCopyPrompt = t5;
480
+ let t6;
481
+ if ($[7] !== t) {
482
+ t6 = t("Connect an AI agent");
483
+ $[7] = t;
484
+ $[8] = t6;
485
+ } else {
486
+ t6 = $[8];
487
+ }
488
+ let t7;
489
+ if ($[9] !== t6) {
490
+ t7 = /* @__PURE__ */ jsxDEV("span", {
491
+ className: "text-sm font-medium text-foreground",
492
+ children: t6
493
+ }, void 0, false);
494
+ $[9] = t6;
495
+ $[10] = t7;
496
+ } else {
497
+ t7 = $[10];
498
+ }
499
+ let t8;
500
+ if ($[11] !== t) {
501
+ t8 = t("Drive this deployment from an AI agent over the Model Context Protocol — it can list functions and tables, read schemas, and run read-only queries. Writes stay off unless you opt in.");
502
+ $[11] = t;
503
+ $[12] = t8;
504
+ } else {
505
+ t8 = $[12];
506
+ }
507
+ let t9;
508
+ if ($[13] !== t8) {
509
+ t9 = /* @__PURE__ */ jsxDEV("span", {
510
+ className: "text-xs text-muted-foreground",
511
+ children: t8
512
+ }, void 0, false);
513
+ $[13] = t8;
514
+ $[14] = t9;
515
+ } else {
516
+ t9 = $[14];
517
+ }
518
+ let t10;
519
+ if ($[15] !== t7 || $[16] !== t9) {
520
+ t10 = /* @__PURE__ */ jsxDEV("div", {
521
+ className: "flex flex-col gap-1.5 p-4",
522
+ children: [t7, t9]
523
+ }, void 0, true);
524
+ $[15] = t7;
525
+ $[16] = t9;
526
+ $[17] = t10;
527
+ } else {
528
+ t10 = $[17];
529
+ }
530
+ let t11;
531
+ if ($[18] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
532
+ t11 = /* @__PURE__ */ jsxDEV("code", {
533
+ className: "font-mono text-xs text-muted-foreground",
534
+ "data-testid": "home-connect-agent-command",
535
+ children: "npx -y @lunora/mcp"
536
+ }, void 0, false);
537
+ $[18] = t11;
538
+ } else {
539
+ t11 = $[18];
540
+ }
541
+ let t12;
542
+ if ($[19] !== copied || $[20] !== t) {
543
+ t12 = copied === "config" ? t("Copied") : t("Copy MCP config");
544
+ $[19] = copied;
545
+ $[20] = t;
546
+ $[21] = t12;
547
+ } else {
548
+ t12 = $[21];
549
+ }
550
+ let t13;
551
+ if ($[22] !== t12) {
552
+ t13 = /* @__PURE__ */ jsxDEV(Button, {
553
+ "data-testid": "home-connect-agent-copy-config",
554
+ onClick: onCopyConfig,
555
+ size: "xs",
556
+ variant: "outline",
557
+ children: t12
558
+ }, void 0, false);
559
+ $[22] = t12;
560
+ $[23] = t13;
561
+ } else {
562
+ t13 = $[23];
563
+ }
564
+ let t14;
565
+ if ($[24] !== copied || $[25] !== t) {
566
+ t14 = copied === "prompt" ? t("Copied") : t("Copy agent prompt");
567
+ $[24] = copied;
568
+ $[25] = t;
569
+ $[26] = t14;
570
+ } else {
571
+ t14 = $[26];
572
+ }
573
+ let t15;
574
+ if ($[27] !== t14) {
575
+ t15 = /* @__PURE__ */ jsxDEV(Button, {
576
+ "data-testid": "home-connect-agent-copy-prompt",
577
+ onClick: onCopyPrompt,
578
+ size: "xs",
579
+ variant: "outline",
580
+ children: t14
581
+ }, void 0, false);
582
+ $[27] = t14;
583
+ $[28] = t15;
584
+ } else {
585
+ t15 = $[28];
586
+ }
587
+ let t16;
588
+ if ($[29] !== t13 || $[30] !== t15) {
589
+ t16 = /* @__PURE__ */ jsxDEV("div", {
590
+ className: "flex flex-col gap-3 border-t border-border bg-muted/50 px-4 py-3",
591
+ children: [t11, /* @__PURE__ */ jsxDEV("div", {
592
+ className: "flex flex-wrap gap-2",
593
+ children: [t13, t15]
594
+ }, void 0, true)]
595
+ }, void 0, true);
596
+ $[29] = t13;
597
+ $[30] = t15;
598
+ $[31] = t16;
599
+ } else {
600
+ t16 = $[31];
601
+ }
602
+ let t17;
603
+ if ($[32] !== t10 || $[33] !== t16) {
604
+ t17 = /* @__PURE__ */ jsxDEV(Card, {
605
+ className: "gap-0 py-0",
606
+ "data-testid": "home-connect-agent",
607
+ children: [t10, t16]
608
+ }, void 0, true);
609
+ $[32] = t10;
610
+ $[33] = t16;
611
+ $[34] = t17;
612
+ } else {
613
+ t17 = $[34];
614
+ }
615
+ return t17;
616
+ };
617
+
375
618
  const Sparkline = /* @__PURE__ */ lazy(() => import('../packem_chunks/sparkline.js').then((m) => {
376
619
  return {
377
620
  default: m.Sparkline
@@ -980,7 +1223,7 @@ const averageLatencyMs = (functions) => {
980
1223
  return functions.reduce((sum, function_) => sum + function_.totalDurationMs, 0) / calls;
981
1224
  };
982
1225
  const HomePanel = (t0) => {
983
- const $ = c(150);
1226
+ const $ = c(151);
984
1227
  const {
985
1228
  initialShardKey
986
1229
  } = t0;
@@ -1580,36 +1823,43 @@ const HomePanel = (t0) => {
1580
1823
  t45 = $[139];
1581
1824
  }
1582
1825
  let t46;
1583
- if ($[140] !== t38 || $[141] !== t45) {
1584
- t46 = /* @__PURE__ */ jsxDEV("section", {
1826
+ if ($[140] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
1827
+ t46 = /* @__PURE__ */ jsxDEV(ConnectAgentCard, {}, void 0, false);
1828
+ $[140] = t46;
1829
+ } else {
1830
+ t46 = $[140];
1831
+ }
1832
+ let t47;
1833
+ if ($[141] !== t38 || $[142] !== t45) {
1834
+ t47 = /* @__PURE__ */ jsxDEV("section", {
1585
1835
  className: "flex flex-col gap-3",
1586
1836
  "data-testid": "home-get-connected",
1587
- children: [t38, t45]
1837
+ children: [t38, t45, t46]
1588
1838
  }, void 0, true);
1589
- $[140] = t38;
1590
- $[141] = t45;
1591
- $[142] = t46;
1839
+ $[141] = t38;
1840
+ $[142] = t45;
1841
+ $[143] = t47;
1592
1842
  } else {
1593
- t46 = $[142];
1843
+ t47 = $[143];
1594
1844
  }
1595
- let t47;
1596
- if ($[143] !== t18 || $[144] !== t19 || $[145] !== t26 || $[146] !== t32 || $[147] !== t36 || $[148] !== t46) {
1597
- t47 = /* @__PURE__ */ jsxDEV("div", {
1845
+ let t48;
1846
+ if ($[144] !== t18 || $[145] !== t19 || $[146] !== t26 || $[147] !== t32 || $[148] !== t36 || $[149] !== t47) {
1847
+ t48 = /* @__PURE__ */ jsxDEV("div", {
1598
1848
  className: t18,
1599
1849
  "data-testid": t19,
1600
- children: [t26, t27, t32, t36, t46]
1850
+ children: [t26, t27, t32, t36, t47]
1601
1851
  }, void 0, true);
1602
- $[143] = t18;
1603
- $[144] = t19;
1604
- $[145] = t26;
1605
- $[146] = t32;
1606
- $[147] = t36;
1607
- $[148] = t46;
1852
+ $[144] = t18;
1853
+ $[145] = t19;
1854
+ $[146] = t26;
1855
+ $[147] = t32;
1856
+ $[148] = t36;
1608
1857
  $[149] = t47;
1858
+ $[150] = t48;
1609
1859
  } else {
1610
- t47 = $[149];
1860
+ t48 = $[150];
1611
1861
  }
1612
- return t47;
1862
+ return t48;
1613
1863
  };
1614
1864
  function _temp(a, b) {
1615
1865
  return b.calls - a.calls;
@@ -64,11 +64,23 @@ const fireAndForget = (promise, onError) => {
64
64
  promise.catch((error) => {
65
65
  });
66
66
  };
67
+ const resolveOrigin = (explicit) => {
68
+ if (explicit !== void 0 && explicit !== "") {
69
+ return explicit;
70
+ }
71
+ const loc = globalThis.location;
72
+ if (loc?.origin !== void 0 && loc.origin !== "") {
73
+ return loc.origin;
74
+ }
75
+ return "http://localhost:5173";
76
+ };
67
77
  const copyToClipboard = (text) => {
68
78
  const clipboard = "navigator" in globalThis ? globalThis.navigator.clipboard : void 0;
69
- if (clipboard !== void 0) {
70
- fireAndForget(clipboard.writeText(text));
79
+ if (clipboard === void 0) {
80
+ return false;
71
81
  }
82
+ fireAndForget(clipboard.writeText(text));
83
+ return true;
72
84
  };
73
85
  const formatBytes = (bytes) => {
74
86
  if (bytes === null || bytes === void 0) {
@@ -94,4 +106,4 @@ const formatTimestamp = (value, fallback = "") => {
94
106
  return Number.isNaN(date.getTime()) ? String(value) : date.toLocaleString();
95
107
  };
96
108
 
97
- export { adminRef as a, errorHint as b, callOptions as c, errorDocumentationUrl as d, errorMessage as e, fireAndForget as f, copyToClipboard as g, formatCell as h, formatTimestamp as i, formatBytes as j };
109
+ export { adminRef as a, errorHint as b, callOptions as c, errorDocumentationUrl as d, errorMessage as e, fireAndForget as f, copyToClipboard as g, formatCell as h, formatTimestamp as i, formatBytes as j, resolveOrigin as r };
@@ -1,6 +1,6 @@
1
1
  import { c } from 'react/compiler-runtime';
2
2
  import { useState, useEffect, createContext, use } from 'react';
3
- import { e as errorMessage, g as copyToClipboard, f as fireAndForget, c as callOptions, a as adminRef } from './internal-DTsYVn-g.js';
3
+ import { e as errorMessage, g as copyToClipboard, f as fireAndForget, c as callOptions, a as adminRef } from './internal-CYcbqMjX.js';
4
4
  import { SentIcon, Copy01Icon, Search01Icon } from '@hugeicons/core-free-icons';
5
5
  import { HugeiconsIcon } from '@hugeicons/react';
6
6
  import { I as Input } from './input-XH4r1Pt1.js';
@@ -21,11 +21,11 @@ import { B as Button } from './button-BhsN2uZH.js';
21
21
  import { Dialog } from '@base-ui/react/dialog';
22
22
  import { Tooltip as Tooltip$1 } from '@base-ui/react/tooltip';
23
23
  import { S as Skeleton } from './skeleton-CGhL0p20.js';
24
- import { u as useStudioFeatures, H as HomePanel } from './home-panel-CoGxi-oj.js';
24
+ import { u as useStudioFeatures, H as HomePanel } from './home-panel-TFcRf9Ui.js';
25
25
  import { StudioI18nProvider } from './StudioI18nProvider-B-tDCZIi.js';
26
26
  import { v as validateDataViewSearch } from './data-view-params-Cd6yRVbv.js';
27
- import { f as fireAndForget } from './internal-DTsYVn-g.js';
28
- import { CommandPalette, openCommandPalette } from './CommandPalette-BUPpbpMc.js';
27
+ import { f as fireAndForget } from './internal-CYcbqMjX.js';
28
+ import { CommandPalette, openCommandPalette } from './CommandPalette-X2tkbyHk.js';
29
29
 
30
30
  const DARK_MEDIA_QUERY = "(prefers-color-scheme: dark)";
31
31
  const store = () => {
@@ -2,7 +2,7 @@ import { c } from 'react/compiler-runtime';
2
2
  import { useT } from './DEFAULT_LOCALE-CiX4W7Kr.js';
3
3
  import { jsxDEV } from 'react/jsx-dev-runtime';
4
4
  import { useState, useRef, useMemo } from 'react';
5
- import { f as fireAndForget, e as errorMessage } from './internal-DTsYVn-g.js';
5
+ import { f as fireAndForget, e as errorMessage } from './internal-CYcbqMjX.js';
6
6
  import { useVirtualizer } from '@tanstack/react-virtual';
7
7
  import { c as cn } from './utils-B05Dmz_H.js';
8
8
  import { f as flooredRectObserver } from './virtual-rect-CVMUskSm.js';
@@ -2,7 +2,7 @@ import { c } from 'react/compiler-runtime';
2
2
  import { useLunora } from '@lunora/react';
3
3
  import { useQueryClient, useQuery, keepPreviousData } from '@tanstack/react-query';
4
4
  import { useState, useEffect } from 'react';
5
- import { a as adminRef, c as callOptions, f as fireAndForget, e as errorMessage } from './internal-DTsYVn-g.js';
5
+ import { a as adminRef, c as callOptions, f as fireAndForget, e as errorMessage } from './internal-CYcbqMjX.js';
6
6
 
7
7
  const adminQueryKey = (path, args, shardKey) => ["lunora-admin", path, args, shardKey.trim()];
8
8
  const RPC_LOOP_WINDOW_MS = 1e3;
@@ -1,8 +1,8 @@
1
1
  import { c } from 'react/compiler-runtime';
2
2
  import { useLunora } from '@lunora/react';
3
- import { a as useClientQuery } from './use-admin-query-BHPKmPuj.js';
3
+ import { a as useClientQuery } from './use-admin-query-CfHYWx5n.js';
4
4
  import { useState } from 'react';
5
- import { f as fireAndForget, e as errorMessage } from './internal-DTsYVn-g.js';
5
+ import { f as fireAndForget, e as errorMessage } from './internal-CYcbqMjX.js';
6
6
 
7
7
  const DEFAULT_AUTH_CONFIG = {
8
8
  capabilities: {
@@ -1 +1 @@
1
- import{a as $}from"./chunk-WXPWVBIY.js";import{a as W}from"./chunk-TDL7NEWA.js";import{a as _}from"./chunk-2K47A3P6.js";import{a as q}from"./chunk-AJIUI7DD.js";import"./chunk-XNJNSCLM.js";import{a as G,b as P,c as V,d as b,e as i,f as o}from"./chunk-GTM65MVX.js";import{a as y}from"./chunk-JSEXCW5Q.js";import{a as U}from"./chunk-K3GNLVYK.js";import{b as Q}from"./chunk-TBMYIZIO.js";import{R as w}from"./chunk-3CJW6NWG.js";import{c as L}from"./chunk-UK64ZSUW.js";import"./chunk-O3NAGRTR.js";import"./chunk-HV7G6DFP.js";import{a as g}from"./chunk-BOXSWNXZ.js";import{a as A}from"./chunk-TAD43CG5.js";import{b as H}from"./chunk-OIC7EJWI.js";import{a as k,e as B}from"./chunk-SEU5V7I6.js";import{b as T}from"./chunk-ZPP2KOR4.js";import"./chunk-CKSHCYGC.js";import{f as M}from"./chunk-GLUNBZRI.js";import"./chunk-ZHVTQ37P.js";import"./chunk-3OA7PECS.js";import{d as S,e as F,f as K,g as O,k as j,n as z}from"./chunk-PVZI3CXP.js";import"./chunk-GMSGZDDH.js";import{a as n,e as D,f as le,h as ce}from"./chunk-RRCPZMC2.js";var a=D(le(),1);var e=D(ce(),1);var ue=F(g.runMigration),we=n(({initialShardKey:J})=>{let X=M(),r=S(),[c,Y]=(0,a.useState)(J??""),[x,Z]=(0,a.useState)(""),[R,ee]=(0,a.useState)("up"),[f,re]=(0,a.useState)(!0),[u,N]=(0,a.useState)(!1),[d,h]=(0,a.useState)(null),[C,p]=(0,a.useState)(null),m=_(c.trim(),400),I=c.trim()===m,s=H(g.migrationStatus,{},{live:!0,shardKey:m}),l=s.data?.migrations??null,te=s.error,{errorSource:ae,liveError:ie}=s;(0,a.useEffect)(()=>{s.data!==void 0&&Q(m)},[s.data,m]);let oe=n(async()=>{let t=x.trim();if(t===""){p(r("Enter a migration id")),h(null);return}N(!0),p(null);try{let v=await X.query(ue,{direction:R,dryRun:f,id:t},K(c));h(v),s.refetch()}catch(v){h(null),p(O(v))}finally{N(!1)}},"run"),E=n(()=>{j(oe())},"runMigration"),ne=n(t=>{Z(t.target.value)},"onIdChange"),se=n(t=>{ee(t.target.value==="down"?"down":"up")},"onDirectionChange"),de=n(t=>{re(t.target.checked)},"onDryRunChange");return(0,e.jsxDEV)("div",{className:"flex flex-col gap-3","data-testid":"lunora-migrations",children:[(0,e.jsxDEV)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,e.jsxDEV)(U,{onChange:Y,testId:"mg-shard-input",value:c},void 0,!1),(0,e.jsxDEV)($,{message:ie,prefix:"mg"},void 0,!1)]},void 0,!0),te!==null&&(0,e.jsxDEV)(q,{error:ae,testId:"mg-status-error"},void 0,!1),l!==null&&l.length===0&&(0,e.jsxDEV)(A,{description:r("Data migrations you run against this shard will be tracked here."),icon:(0,e.jsxDEV)("svg",{"aria-hidden":"true",fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.6,viewBox:"0 0 24 24",children:(0,e.jsxDEV)("path",{d:"M4 12a8 8 0 0 1 13.7-5.6L20 8M20 4v4h-4M20 12a8 8 0 0 1-13.7 5.6L4 16m0 4v-4h4"},void 0,!1)},void 0,!1),testId:"mg-empty",title:r("No migrations have run on this shard.")},void 0,!1),l!==null&&l.length>0&&(0,e.jsxDEV)(k,{className:"overflow-hidden py-0",children:(0,e.jsxDEV)(B,{className:"px-0",children:(0,e.jsxDEV)(G,{"data-testid":"mg-table",children:[(0,e.jsxDEV)(P,{children:(0,e.jsxDEV)(b,{children:[(0,e.jsxDEV)(i,{children:r("id")},void 0,!1),(0,e.jsxDEV)(i,{children:r("direction")},void 0,!1),(0,e.jsxDEV)(i,{children:r("status")},void 0,!1),(0,e.jsxDEV)(i,{children:r("processed")},void 0,!1),(0,e.jsxDEV)(i,{children:r("changed")},void 0,!1),(0,e.jsxDEV)(i,{children:r("updated")},void 0,!1),(0,e.jsxDEV)(i,{children:r("error")},void 0,!1)]},void 0,!0)},void 0,!1),(0,e.jsxDEV)(V,{children:l.map(t=>(0,e.jsxDEV)(b,{"data-testid":`mg-row-${t.id}`,children:[(0,e.jsxDEV)(o,{children:t.id},void 0,!1),(0,e.jsxDEV)(o,{children:t.direction},void 0,!1),(0,e.jsxDEV)(o,{children:(0,e.jsxDEV)(T,{variant:"secondary",children:t.status},void 0,!1)},void 0,!1),(0,e.jsxDEV)(o,{children:t.processed},void 0,!1),(0,e.jsxDEV)(o,{children:t.changed},void 0,!1),(0,e.jsxDEV)(o,{children:z(t.updatedAt)},void 0,!1),(0,e.jsxDEV)(o,{children:t.error??""},void 0,!1)]},t.id,!0))},void 0,!1)]},void 0,!0)},void 0,!1)},void 0,!1),(0,e.jsxDEV)("div",{className:"flex flex-col gap-2 rounded-xl border border-border bg-card p-3 shadow-xs",children:[(0,e.jsxDEV)(y,{children:r("Run migration")},void 0,!1),(0,e.jsxDEV)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,e.jsxDEV)(w,{"aria-label":r("Migration id"),className:"w-auto","data-testid":"mg-id-input",onChange:ne,placeholder:r("migration id"),value:x},void 0,!1),(0,e.jsxDEV)("select",{"aria-label":r("Direction"),className:"flex h-9 rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring","data-testid":"mg-direction",onChange:se,value:R,children:[(0,e.jsxDEV)("option",{value:"up",children:r("up")},void 0,!1),(0,e.jsxDEV)("option",{value:"down",children:r("down")},void 0,!1)]},void 0,!0),(0,e.jsxDEV)(y,{className:"flex items-center gap-1.5",htmlFor:"mg-dry-run",children:[(0,e.jsxDEV)("input",{checked:f,className:"size-4 accent-primary","data-testid":"mg-dry-run",id:"mg-dry-run",onChange:de,type:"checkbox"},void 0,!1),r("Dry run")]},void 0,!0),f?(0,e.jsxDEV)(L,{"data-testid":"mg-run",disabled:u||!I,onClick:E,size:"sm",type:"button",children:r(u?"Running\u2026":"Run")},void 0,!1):(0,e.jsxDEV)(W,{confirmLabel:r(u?"Running\u2026":"Run migration?"),disabled:u||!I,onConfirm:E,testId:"mg-run",children:r("Run")},void 0,!1)]},void 0,!0)]},void 0,!0),C!==null&&(0,e.jsxDEV)("pre",{className:"text-sm text-destructive whitespace-pre-wrap","data-testid":"mg-run-error",role:"alert",children:C},void 0,!1),d!==null&&(0,e.jsxDEV)("p",{className:"text-sm text-muted-foreground","data-testid":"mg-run-result",children:[d.dryRun?r("Dry run: "):"",r("{status} \u2014 processed",{status:d.status}),d.processed,r(", changed"),d.changed]},void 0,!0)]},void 0,!0)},"MigrationsPanel");export{we as MigrationsPanel};
1
+ import{a as $}from"./chunk-UGUEC6BC.js";import{a as W}from"./chunk-YBGC4PPD.js";import{a as _}from"./chunk-2K47A3P6.js";import{a as q}from"./chunk-CACB34RQ.js";import"./chunk-XNJNSCLM.js";import{a as G,b as P,c as V,d as b,e as i,f as o}from"./chunk-GTM65MVX.js";import{a as y}from"./chunk-JSEXCW5Q.js";import{a as U}from"./chunk-UKDJ4H7I.js";import{b as Q}from"./chunk-TBMYIZIO.js";import{R as w}from"./chunk-3CJW6NWG.js";import{c as L}from"./chunk-UK64ZSUW.js";import"./chunk-O3NAGRTR.js";import"./chunk-HV7G6DFP.js";import{a as g}from"./chunk-BOXSWNXZ.js";import{a as A}from"./chunk-TAD43CG5.js";import{b as H}from"./chunk-C7WTJLC3.js";import{a as k,e as B}from"./chunk-SEU5V7I6.js";import{b as T}from"./chunk-ZPP2KOR4.js";import"./chunk-CKSHCYGC.js";import{f as M}from"./chunk-GLUNBZRI.js";import"./chunk-ZHVTQ37P.js";import"./chunk-3OA7PECS.js";import{d as S,e as F,f as K,g as O,k as j,o as z}from"./chunk-E75ANNWX.js";import"./chunk-GMSGZDDH.js";import{a as n,e as D,f as le,h as ce}from"./chunk-RRCPZMC2.js";var a=D(le(),1);var e=D(ce(),1);var ue=F(g.runMigration),we=n(({initialShardKey:J})=>{let X=M(),r=S(),[c,Y]=(0,a.useState)(J??""),[x,Z]=(0,a.useState)(""),[R,ee]=(0,a.useState)("up"),[f,re]=(0,a.useState)(!0),[u,N]=(0,a.useState)(!1),[d,h]=(0,a.useState)(null),[C,p]=(0,a.useState)(null),m=_(c.trim(),400),I=c.trim()===m,s=H(g.migrationStatus,{},{live:!0,shardKey:m}),l=s.data?.migrations??null,te=s.error,{errorSource:ae,liveError:ie}=s;(0,a.useEffect)(()=>{s.data!==void 0&&Q(m)},[s.data,m]);let oe=n(async()=>{let t=x.trim();if(t===""){p(r("Enter a migration id")),h(null);return}N(!0),p(null);try{let v=await X.query(ue,{direction:R,dryRun:f,id:t},K(c));h(v),s.refetch()}catch(v){h(null),p(O(v))}finally{N(!1)}},"run"),E=n(()=>{j(oe())},"runMigration"),ne=n(t=>{Z(t.target.value)},"onIdChange"),se=n(t=>{ee(t.target.value==="down"?"down":"up")},"onDirectionChange"),de=n(t=>{re(t.target.checked)},"onDryRunChange");return(0,e.jsxDEV)("div",{className:"flex flex-col gap-3","data-testid":"lunora-migrations",children:[(0,e.jsxDEV)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,e.jsxDEV)(U,{onChange:Y,testId:"mg-shard-input",value:c},void 0,!1),(0,e.jsxDEV)($,{message:ie,prefix:"mg"},void 0,!1)]},void 0,!0),te!==null&&(0,e.jsxDEV)(q,{error:ae,testId:"mg-status-error"},void 0,!1),l!==null&&l.length===0&&(0,e.jsxDEV)(A,{description:r("Data migrations you run against this shard will be tracked here."),icon:(0,e.jsxDEV)("svg",{"aria-hidden":"true",fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.6,viewBox:"0 0 24 24",children:(0,e.jsxDEV)("path",{d:"M4 12a8 8 0 0 1 13.7-5.6L20 8M20 4v4h-4M20 12a8 8 0 0 1-13.7 5.6L4 16m0 4v-4h4"},void 0,!1)},void 0,!1),testId:"mg-empty",title:r("No migrations have run on this shard.")},void 0,!1),l!==null&&l.length>0&&(0,e.jsxDEV)(k,{className:"overflow-hidden py-0",children:(0,e.jsxDEV)(B,{className:"px-0",children:(0,e.jsxDEV)(G,{"data-testid":"mg-table",children:[(0,e.jsxDEV)(P,{children:(0,e.jsxDEV)(b,{children:[(0,e.jsxDEV)(i,{children:r("id")},void 0,!1),(0,e.jsxDEV)(i,{children:r("direction")},void 0,!1),(0,e.jsxDEV)(i,{children:r("status")},void 0,!1),(0,e.jsxDEV)(i,{children:r("processed")},void 0,!1),(0,e.jsxDEV)(i,{children:r("changed")},void 0,!1),(0,e.jsxDEV)(i,{children:r("updated")},void 0,!1),(0,e.jsxDEV)(i,{children:r("error")},void 0,!1)]},void 0,!0)},void 0,!1),(0,e.jsxDEV)(V,{children:l.map(t=>(0,e.jsxDEV)(b,{"data-testid":`mg-row-${t.id}`,children:[(0,e.jsxDEV)(o,{children:t.id},void 0,!1),(0,e.jsxDEV)(o,{children:t.direction},void 0,!1),(0,e.jsxDEV)(o,{children:(0,e.jsxDEV)(T,{variant:"secondary",children:t.status},void 0,!1)},void 0,!1),(0,e.jsxDEV)(o,{children:t.processed},void 0,!1),(0,e.jsxDEV)(o,{children:t.changed},void 0,!1),(0,e.jsxDEV)(o,{children:z(t.updatedAt)},void 0,!1),(0,e.jsxDEV)(o,{children:t.error??""},void 0,!1)]},t.id,!0))},void 0,!1)]},void 0,!0)},void 0,!1)},void 0,!1),(0,e.jsxDEV)("div",{className:"flex flex-col gap-2 rounded-xl border border-border bg-card p-3 shadow-xs",children:[(0,e.jsxDEV)(y,{children:r("Run migration")},void 0,!1),(0,e.jsxDEV)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,e.jsxDEV)(w,{"aria-label":r("Migration id"),className:"w-auto","data-testid":"mg-id-input",onChange:ne,placeholder:r("migration id"),value:x},void 0,!1),(0,e.jsxDEV)("select",{"aria-label":r("Direction"),className:"flex h-9 rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring","data-testid":"mg-direction",onChange:se,value:R,children:[(0,e.jsxDEV)("option",{value:"up",children:r("up")},void 0,!1),(0,e.jsxDEV)("option",{value:"down",children:r("down")},void 0,!1)]},void 0,!0),(0,e.jsxDEV)(y,{className:"flex items-center gap-1.5",htmlFor:"mg-dry-run",children:[(0,e.jsxDEV)("input",{checked:f,className:"size-4 accent-primary","data-testid":"mg-dry-run",id:"mg-dry-run",onChange:de,type:"checkbox"},void 0,!1),r("Dry run")]},void 0,!0),f?(0,e.jsxDEV)(L,{"data-testid":"mg-run",disabled:u||!I,onClick:E,size:"sm",type:"button",children:r(u?"Running\u2026":"Run")},void 0,!1):(0,e.jsxDEV)(W,{confirmLabel:r(u?"Running\u2026":"Run migration?"),disabled:u||!I,onConfirm:E,testId:"mg-run",children:r("Run")},void 0,!1)]},void 0,!0)]},void 0,!0),C!==null&&(0,e.jsxDEV)("pre",{className:"text-sm text-destructive whitespace-pre-wrap","data-testid":"mg-run-error",role:"alert",children:C},void 0,!1),d!==null&&(0,e.jsxDEV)("p",{className:"text-sm text-muted-foreground","data-testid":"mg-run-result",children:[d.dryRun?r("Dry run: "):"",r("{status} \u2014 processed",{status:d.status}),d.processed,r(", changed"),d.changed]},void 0,!0)]},void 0,!0)},"MigrationsPanel");export{we as MigrationsPanel};
@@ -1 +1 @@
1
- import{a as S}from"./chunk-AJIUI7DD.js";import"./chunk-XNJNSCLM.js";import{a as w,b as A,c as E,d as m,e as s,f as l}from"./chunk-GTM65MVX.js";import{a as O}from"./chunk-VLXV72QE.js";import{a as k}from"./chunk-JSEXCW5Q.js";import{a as C}from"./chunk-BOXSWNXZ.js";import{a as u}from"./chunk-TAD43CG5.js";import{b as T}from"./chunk-OIC7EJWI.js";import{a as N,e as b}from"./chunk-SEU5V7I6.js";import{b as y}from"./chunk-ZPP2KOR4.js";import"./chunk-CKSHCYGC.js";import"./chunk-GLUNBZRI.js";import"./chunk-ZHVTQ37P.js";import"./chunk-3OA7PECS.js";import{d as h}from"./chunk-PVZI3CXP.js";import"./chunk-GMSGZDDH.js";import{a as d,e as p,f as D,h as H}from"./chunk-RRCPZMC2.js";var n=p(D(),1);var e=p(H(),1);var K=d(a=>{let t=a.trim();if(t.length===0)return{context:void 0,error:null};try{let o=JSON.parse(t);return o===null||typeof o!="object"||Array.isArray(o)?{context:void 0,error:"Targeting context must be a JSON object."}:{context:o,error:null}}catch{return{context:void 0,error:"Targeting context is not valid JSON."}}},"parseContext"),R='{ "targetingKey": "user-123", "plan": "premium" }',M=d(a=>a.type==="object"?JSON.stringify(a.value):String(a.value),"formatValue"),Y=d(({initialShardKey:a=""})=>{let t=h(),[o,F]=(0,n.useState)(""),{context:f,error:g}=K(o),I=(0,n.useMemo)(()=>f===void 0?{}:{context:f},[f]),{data:i,error:J,errorSource:L,liveError:j}=T(C.listFlags,I,{live:!0,shardKey:a}),v=i!==void 0,V=i?.configured??!1,x=(0,n.useMemo)(()=>Array.isArray(i?.flags)?[...i.flags].toSorted((r,B)=>r.key.localeCompare(B.key)):[],[i]),c;return v&&!V?c=(0,e.jsxDEV)(u,{description:t("No @lunora/flags provider is wired in this deployment. Add lunora/flags.ts with defineFlags({ provider }) to gate code paths on feature flags."),testId:"flags-unconfigured",title:t("No flags provider configured")},void 0,!1):v&&x.length===0?c=(0,e.jsxDEV)(u,{description:t('A flags provider is configured, but no handler reads a flag yet. Call ctx.flags.boolean("key", false) in a query, mutation, or action.'),testId:"flags-empty",title:t("No flags read")},void 0,!1):c=(0,e.jsxDEV)(N,{className:"overflow-hidden py-0",children:(0,e.jsxDEV)(b,{className:"px-0",children:(0,e.jsxDEV)(w,{"data-testid":"flags-table",children:[(0,e.jsxDEV)(A,{children:(0,e.jsxDEV)(m,{children:[(0,e.jsxDEV)(s,{children:t("Key")},void 0,!1),(0,e.jsxDEV)(s,{children:t("Type")},void 0,!1),(0,e.jsxDEV)(s,{children:t("Value")},void 0,!1),(0,e.jsxDEV)(s,{children:t("Reason")},void 0,!1),(0,e.jsxDEV)(s,{children:t("Variant")},void 0,!1)]},void 0,!0)},void 0,!1),(0,e.jsxDEV)(E,{children:x.map(r=>(0,e.jsxDEV)(m,{"data-testid":`flags-row-${r.key}`,children:[(0,e.jsxDEV)(l,{className:"font-mono text-xs",children:r.key},void 0,!1),(0,e.jsxDEV)(l,{className:"font-mono text-xs text-muted-foreground",children:r.type},void 0,!1),(0,e.jsxDEV)(l,{className:"font-mono text-xs",children:M(r)},void 0,!1),(0,e.jsxDEV)(l,{children:r.errorCode===void 0?(0,e.jsxDEV)("span",{className:"font-mono text-xs text-muted-foreground",children:r.reason??"\u2014"},void 0,!1):(0,e.jsxDEV)(y,{"data-testid":`flags-error-${r.key}`,variant:"destructive",children:r.errorCode},void 0,!1)},void 0,!1),(0,e.jsxDEV)(l,{className:"font-mono text-xs text-muted-foreground",children:r.variant??"\u2014"},void 0,!1)]},r.key,!0))},void 0,!1)]},void 0,!0)},void 0,!1)},void 0,!1),(0,e.jsxDEV)("div",{className:"flex flex-col gap-6","data-testid":"lunora-flags-panel",children:[J!==null&&(0,e.jsxDEV)(S,{error:L,testId:"flags-error"},void 0,!1),(0,e.jsxDEV)("p",{className:"text-sm text-muted-foreground",children:t('Feature flags are read in code with ctx.flags.<type>("key", default). They evaluate through the OpenFeature provider configured in lunora/flags.ts; edit the targeting context below to see how each flag resolves for a given audience.')},void 0,!1),(0,e.jsxDEV)("div",{className:"flex flex-col gap-2",children:[(0,e.jsxDEV)(k,{htmlFor:"flags-targeting-context",children:t("Targeting context (JSON)")},void 0,!1),(0,e.jsxDEV)(O,{className:"font-mono text-xs","data-testid":"flags-context-input",id:"flags-targeting-context",onChange:d(r=>{F(r.target.value)},"onChange"),placeholder:R,rows:3,value:o},void 0,!1),g!==null&&(0,e.jsxDEV)("p",{className:"text-xs text-destructive","data-testid":"flags-context-error",role:"alert",children:t(g)},void 0,!1),j!==void 0&&(0,e.jsxDEV)("p",{className:"text-xs text-amber-600 dark:text-amber-500","data-testid":"flags-live-error",role:"alert",children:t("Live updates unavailable; showing the last evaluation.")},void 0,!1)]},void 0,!0),c]},void 0,!0)},"FlagsPanel");export{Y as FlagsPanel};
1
+ import{a as S}from"./chunk-CACB34RQ.js";import"./chunk-XNJNSCLM.js";import{a as w,b as A,c as E,d as m,e as s,f as l}from"./chunk-GTM65MVX.js";import{a as O}from"./chunk-VLXV72QE.js";import{a as k}from"./chunk-JSEXCW5Q.js";import{a as C}from"./chunk-BOXSWNXZ.js";import{a as u}from"./chunk-TAD43CG5.js";import{b as T}from"./chunk-C7WTJLC3.js";import{a as N,e as b}from"./chunk-SEU5V7I6.js";import{b as y}from"./chunk-ZPP2KOR4.js";import"./chunk-CKSHCYGC.js";import"./chunk-GLUNBZRI.js";import"./chunk-ZHVTQ37P.js";import"./chunk-3OA7PECS.js";import{d as h}from"./chunk-E75ANNWX.js";import"./chunk-GMSGZDDH.js";import{a as d,e as p,f as D,h as H}from"./chunk-RRCPZMC2.js";var n=p(D(),1);var e=p(H(),1);var K=d(a=>{let t=a.trim();if(t.length===0)return{context:void 0,error:null};try{let o=JSON.parse(t);return o===null||typeof o!="object"||Array.isArray(o)?{context:void 0,error:"Targeting context must be a JSON object."}:{context:o,error:null}}catch{return{context:void 0,error:"Targeting context is not valid JSON."}}},"parseContext"),R='{ "targetingKey": "user-123", "plan": "premium" }',M=d(a=>a.type==="object"?JSON.stringify(a.value):String(a.value),"formatValue"),Y=d(({initialShardKey:a=""})=>{let t=h(),[o,F]=(0,n.useState)(""),{context:f,error:g}=K(o),I=(0,n.useMemo)(()=>f===void 0?{}:{context:f},[f]),{data:i,error:J,errorSource:L,liveError:j}=T(C.listFlags,I,{live:!0,shardKey:a}),v=i!==void 0,V=i?.configured??!1,x=(0,n.useMemo)(()=>Array.isArray(i?.flags)?[...i.flags].toSorted((r,B)=>r.key.localeCompare(B.key)):[],[i]),c;return v&&!V?c=(0,e.jsxDEV)(u,{description:t("No @lunora/flags provider is wired in this deployment. Add lunora/flags.ts with defineFlags({ provider }) to gate code paths on feature flags."),testId:"flags-unconfigured",title:t("No flags provider configured")},void 0,!1):v&&x.length===0?c=(0,e.jsxDEV)(u,{description:t('A flags provider is configured, but no handler reads a flag yet. Call ctx.flags.boolean("key", false) in a query, mutation, or action.'),testId:"flags-empty",title:t("No flags read")},void 0,!1):c=(0,e.jsxDEV)(N,{className:"overflow-hidden py-0",children:(0,e.jsxDEV)(b,{className:"px-0",children:(0,e.jsxDEV)(w,{"data-testid":"flags-table",children:[(0,e.jsxDEV)(A,{children:(0,e.jsxDEV)(m,{children:[(0,e.jsxDEV)(s,{children:t("Key")},void 0,!1),(0,e.jsxDEV)(s,{children:t("Type")},void 0,!1),(0,e.jsxDEV)(s,{children:t("Value")},void 0,!1),(0,e.jsxDEV)(s,{children:t("Reason")},void 0,!1),(0,e.jsxDEV)(s,{children:t("Variant")},void 0,!1)]},void 0,!0)},void 0,!1),(0,e.jsxDEV)(E,{children:x.map(r=>(0,e.jsxDEV)(m,{"data-testid":`flags-row-${r.key}`,children:[(0,e.jsxDEV)(l,{className:"font-mono text-xs",children:r.key},void 0,!1),(0,e.jsxDEV)(l,{className:"font-mono text-xs text-muted-foreground",children:r.type},void 0,!1),(0,e.jsxDEV)(l,{className:"font-mono text-xs",children:M(r)},void 0,!1),(0,e.jsxDEV)(l,{children:r.errorCode===void 0?(0,e.jsxDEV)("span",{className:"font-mono text-xs text-muted-foreground",children:r.reason??"\u2014"},void 0,!1):(0,e.jsxDEV)(y,{"data-testid":`flags-error-${r.key}`,variant:"destructive",children:r.errorCode},void 0,!1)},void 0,!1),(0,e.jsxDEV)(l,{className:"font-mono text-xs text-muted-foreground",children:r.variant??"\u2014"},void 0,!1)]},r.key,!0))},void 0,!1)]},void 0,!0)},void 0,!1)},void 0,!1),(0,e.jsxDEV)("div",{className:"flex flex-col gap-6","data-testid":"lunora-flags-panel",children:[J!==null&&(0,e.jsxDEV)(S,{error:L,testId:"flags-error"},void 0,!1),(0,e.jsxDEV)("p",{className:"text-sm text-muted-foreground",children:t('Feature flags are read in code with ctx.flags.<type>("key", default). They evaluate through the OpenFeature provider configured in lunora/flags.ts; edit the targeting context below to see how each flag resolves for a given audience.')},void 0,!1),(0,e.jsxDEV)("div",{className:"flex flex-col gap-2",children:[(0,e.jsxDEV)(k,{htmlFor:"flags-targeting-context",children:t("Targeting context (JSON)")},void 0,!1),(0,e.jsxDEV)(O,{className:"font-mono text-xs","data-testid":"flags-context-input",id:"flags-targeting-context",onChange:d(r=>{F(r.target.value)},"onChange"),placeholder:R,rows:3,value:o},void 0,!1),g!==null&&(0,e.jsxDEV)("p",{className:"text-xs text-destructive","data-testid":"flags-context-error",role:"alert",children:t(g)},void 0,!1),j!==void 0&&(0,e.jsxDEV)("p",{className:"text-xs text-amber-600 dark:text-amber-500","data-testid":"flags-live-error",role:"alert",children:t("Live updates unavailable; showing the last evaluation.")},void 0,!1)]},void 0,!0),c]},void 0,!0)},"FlagsPanel");export{Y as FlagsPanel};
@@ -1,3 +1,3 @@
1
- import{a as J}from"./chunk-TDL7NEWA.js";import{a as P}from"./chunk-VLXV72QE.js";import{a as B}from"./chunk-K3GNLVYK.js";import{b as j}from"./chunk-TBMYIZIO.js";import"./chunk-3CJW6NWG.js";import{c as D}from"./chunk-UK64ZSUW.js";import"./chunk-O3NAGRTR.js";import"./chunk-HV7G6DFP.js";import{a as f}from"./chunk-BOXSWNXZ.js";import{c as L}from"./chunk-OIC7EJWI.js";import{a as v,e as y}from"./chunk-SEU5V7I6.js";import"./chunk-CKSHCYGC.js";import{f as _}from"./chunk-GLUNBZRI.js";import"./chunk-ZHVTQ37P.js";import"./chunk-3OA7PECS.js";import{d as E,e as S,f as w,g as b,k as I}from"./chunk-PVZI3CXP.js";import{b as N}from"./chunk-GMSGZDDH.js";import{a as o,e as R,f as K,h as U}from"./chunk-RRCPZMC2.js";var c=R(K(),1);var e=R(U(),1);var V=S(f.exportShard),X=S(f.importShard),z=o(m=>m.map(a=>JSON.stringify(a)).join(`
1
+ import{a as J}from"./chunk-YBGC4PPD.js";import{a as P}from"./chunk-VLXV72QE.js";import{a as B}from"./chunk-UKDJ4H7I.js";import{b as j}from"./chunk-TBMYIZIO.js";import"./chunk-3CJW6NWG.js";import{c as D}from"./chunk-UK64ZSUW.js";import"./chunk-O3NAGRTR.js";import"./chunk-HV7G6DFP.js";import{a as f}from"./chunk-BOXSWNXZ.js";import{c as L}from"./chunk-C7WTJLC3.js";import{a as v,e as y}from"./chunk-SEU5V7I6.js";import"./chunk-CKSHCYGC.js";import{f as _}from"./chunk-GLUNBZRI.js";import"./chunk-ZHVTQ37P.js";import"./chunk-3OA7PECS.js";import{d as E,e as S,f as w,g as b,k as I}from"./chunk-E75ANNWX.js";import{b as N}from"./chunk-GMSGZDDH.js";import{a as o,e as R,f as K,h as U}from"./chunk-RRCPZMC2.js";var c=R(K(),1);var e=R(U(),1);var V=S(f.exportShard),X=S(f.importShard),z=o(m=>m.map(a=>JSON.stringify(a)).join(`
2
2
  `),"toNdjson"),G=o(m=>{let a=[],x=m.split(`
3
3
  `);for(let[r,n]of x.entries()){let h=n.trim();if(h==="")continue;let l=JSON.parse(h);if(typeof l!="object"||l===null)throw new N("INTERNAL",`line ${(r+1).toString()}: expected a { table, doc } object`);let s=l;if(typeof s.table!="string"||typeof s.doc!="object"||s.doc===null||Array.isArray(s.doc))throw new N("INTERNAL",`line ${(r+1).toString()}: expected a { table, doc } object`);a.push(s)}return a},"parseNdjson"),ie=o(({initialShardKey:m})=>{let a=_(),x=L(),r=E(),[n,h]=(0,c.useState)(m??""),[l,s]=(0,c.useState)(""),[C,p]=(0,c.useState)(!1),[T,u]=(0,c.useState)(null),[i,g]=(0,c.useState)(null),[A,O]=(0,c.useState)(null),$=o(async()=>{p(!0),u(null),g(null);try{let t=await a.query(V,{},w(n));j(n),s(z(t.rows)),O(t.rows.length)}catch(t){u(b(t))}finally{p(!1)}},"exportShard"),k=o(async()=>{p(!0),u(null),g(null),O(null);let t;try{t=G(l)}catch(d){u(r("Invalid NDJSON: {message}",{message:b(d)})),p(!1);return}try{let d=await a.query(X,{rows:t},w(n));j(n),g(d),x(f.readTablePage),x(f.listTables)}catch(d){u(b(d))}finally{p(!1)}},"importShard"),M=i===null?0:Object.values(i.inserted).reduce((t,d)=>t+d,0),q=o(()=>{I($())},"runExport"),F=o(()=>{I(k())},"runImport"),H=o(t=>{s(t.target.value)},"onNdjsonChange");return(0,e.jsxDEV)("div",{className:"flex flex-col gap-4","data-testid":"lunora-export-import",children:[(0,e.jsxDEV)(v,{className:"rounded-xl border border-border bg-card shadow-xs",children:[(0,e.jsxDEV)("header",{className:"border-b border-border px-4 py-3",children:(0,e.jsxDEV)("span",{className:"font-mono text-[11px] tracking-wide text-muted-foreground uppercase",children:r("Export")},void 0,!1)},void 0,!1),(0,e.jsxDEV)(y,{className:"flex flex-col gap-3 p-4",children:[(0,e.jsxDEV)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,e.jsxDEV)(B,{onChange:h,testId:"ei-shard-input",value:n},void 0,!1),(0,e.jsxDEV)(D,{"data-testid":"ei-export",disabled:C,onClick:q,type:"button",children:r("Export")},void 0,!1)]},void 0,!0),A!==null&&(0,e.jsxDEV)("p",{className:"text-sm text-muted-foreground","data-testid":"ei-export-result",children:r("Exported {count} rows.",{count:A})},void 0,!1)]},void 0,!0)]},void 0,!0),(0,e.jsxDEV)(v,{className:"rounded-xl border border-border bg-card shadow-xs",children:[(0,e.jsxDEV)("header",{className:"border-b border-border px-4 py-3",children:(0,e.jsxDEV)("span",{className:"font-mono text-[11px] tracking-wide text-muted-foreground uppercase",children:r("Import")},void 0,!1)},void 0,!1),(0,e.jsxDEV)(y,{className:"flex flex-col gap-3 p-4",children:[(0,e.jsxDEV)(P,{"aria-label":"NDJSON",className:"font-mono text-xs min-h-40 rounded-md","data-testid":"ei-ndjson",onChange:H,placeholder:'{"table":"messages","doc":{\u2026}}',value:l},void 0,!1),(0,e.jsxDEV)("div",{className:"flex flex-wrap items-center gap-2",children:(0,e.jsxDEV)(J,{confirmLabel:r("Import (writes rows)?"),disabled:C||l.trim()==="",onConfirm:F,testId:"ei-import",children:r("Import")},void 0,!1)},void 0,!1),i!==null&&(0,e.jsxDEV)("div",{className:"flex flex-col gap-2","data-testid":"ei-import-result",children:[(0,e.jsxDEV)("p",{className:"text-sm text-muted-foreground",children:r("Inserted {inserted}, {conflicts} conflicts, {errors} errors.",{conflicts:i.conflicts,errors:i.errors.length,inserted:M})},void 0,!1),i.errors.length>0&&(0,e.jsxDEV)("ul",{className:"flex flex-col gap-1","data-testid":"ei-import-errors",children:i.errors.map(t=>(0,e.jsxDEV)("li",{className:"text-xs text-destructive",children:r("line {line} ({table}): {message}",{line:t.line,message:t.message,table:t.table})},`${t.table}-${t.line.toString()}`,!1))},void 0,!1)]},void 0,!0)]},void 0,!0)]},void 0,!0),T!==null&&(0,e.jsxDEV)("p",{className:"text-sm text-destructive","data-testid":"ei-error",role:"alert",children:T},void 0,!1)]},void 0,!0)},"ExportImportPanel");export{ie as ExportImportPanel};
@@ -1,4 +1,4 @@
1
- import{a as R}from"./chunk-TQ36RWOP.js";import{R as C}from"./chunk-3CJW6NWG.js";import{c as k}from"./chunk-UK64ZSUW.js";import"./chunk-O3NAGRTR.js";import"./chunk-HV7G6DFP.js";import{a as w,e as N}from"./chunk-SEU5V7I6.js";import"./chunk-CKSHCYGC.js";import"./chunk-ZHVTQ37P.js";import"./chunk-3OA7PECS.js";import{d as b,g as S,k as T,l as L}from"./chunk-PVZI3CXP.js";import{a as f,e as y,f as W,g as j,h as D}from"./chunk-RRCPZMC2.js";var O=y(j(),1),v=y(W(),1);var t=y(D(),1);var I=f(s=>{let e=(0,O.c)(23),{destination:o}=s,h=b(),m;e[0]!==o.snippet?(m=f(()=>{L(o.snippet)},"t1"),e[0]=o.snippet,e[1]=m):m=e[1];let u=m,r;e[2]!==o.title?(r=(0,t.jsxDEV)("h4",{className:"text-sm font-semibold",children:o.title},void 0,!1),e[2]=o.title,e[3]=r):r=e[3];let a;e[4]!==o.description?(a=(0,t.jsxDEV)("p",{className:"text-sm text-muted-foreground",children:o.description},void 0,!1),e[4]=o.description,e[5]=a):a=e[5];let l;e[6]!==r||e[7]!==a?(l=(0,t.jsxDEV)("div",{children:[r,a]},void 0,!0),e[6]=r,e[7]=a,e[8]=l):l=e[8];let g=`drain-copy-${o.id}`,d;e[9]!==h?(d=h("Copy"),e[9]=h,e[10]=d):d=e[10];let i;e[11]!==u||e[12]!==g||e[13]!==d?(i=(0,t.jsxDEV)(k,{"data-testid":g,onClick:u,size:"sm",variant:"outline",children:d},void 0,!1),e[11]=u,e[12]=g,e[13]=d,e[14]=i):i=e[14];let n;e[15]!==l||e[16]!==i?(n=(0,t.jsxDEV)("div",{className:"flex items-start justify-between gap-3",children:[l,i]},void 0,!0),e[15]=l,e[16]=i,e[17]=n):n=e[17];let c;e[18]!==o.snippet?(c=(0,t.jsxDEV)("pre",{className:"mt-2 overflow-x-auto rounded bg-muted p-2 font-mono text-xs",children:o.snippet},void 0,!1),e[18]=o.snippet,e[19]=c):c=e[19];let p;return e[20]!==n||e[21]!==c?(p=(0,t.jsxDEV)(w,{className:"py-0","data-testid":"drain-card",children:(0,t.jsxDEV)(N,{className:"p-3",children:[n,c]},void 0,!0)},void 0,!1),e[20]=n,e[21]=c,e[22]=p):p=e[22],p},"DestinationRow"),F=f(()=>{let s=b(),e=[{description:s("Stream every request log to R2, a SIEM, or a third-party log service."),id:"logpush",snippet:["{",' "logpush": true',"}"].join(`
1
+ import{a as R}from"./chunk-TQ36RWOP.js";import{R as C}from"./chunk-3CJW6NWG.js";import{c as k}from"./chunk-UK64ZSUW.js";import"./chunk-O3NAGRTR.js";import"./chunk-HV7G6DFP.js";import{a as w,e as N}from"./chunk-SEU5V7I6.js";import"./chunk-CKSHCYGC.js";import"./chunk-ZHVTQ37P.js";import"./chunk-3OA7PECS.js";import{d as b,g as S,k as T,m as L}from"./chunk-E75ANNWX.js";import{a as f,e as y,f as W,g as j,h as D}from"./chunk-RRCPZMC2.js";var O=y(j(),1),v=y(W(),1);var t=y(D(),1);var I=f(s=>{let e=(0,O.c)(23),{destination:o}=s,h=b(),m;e[0]!==o.snippet?(m=f(()=>{L(o.snippet)},"t1"),e[0]=o.snippet,e[1]=m):m=e[1];let u=m,r;e[2]!==o.title?(r=(0,t.jsxDEV)("h4",{className:"text-sm font-semibold",children:o.title},void 0,!1),e[2]=o.title,e[3]=r):r=e[3];let a;e[4]!==o.description?(a=(0,t.jsxDEV)("p",{className:"text-sm text-muted-foreground",children:o.description},void 0,!1),e[4]=o.description,e[5]=a):a=e[5];let l;e[6]!==r||e[7]!==a?(l=(0,t.jsxDEV)("div",{children:[r,a]},void 0,!0),e[6]=r,e[7]=a,e[8]=l):l=e[8];let g=`drain-copy-${o.id}`,d;e[9]!==h?(d=h("Copy"),e[9]=h,e[10]=d):d=e[10];let i;e[11]!==u||e[12]!==g||e[13]!==d?(i=(0,t.jsxDEV)(k,{"data-testid":g,onClick:u,size:"sm",variant:"outline",children:d},void 0,!1),e[11]=u,e[12]=g,e[13]=d,e[14]=i):i=e[14];let n;e[15]!==l||e[16]!==i?(n=(0,t.jsxDEV)("div",{className:"flex items-start justify-between gap-3",children:[l,i]},void 0,!0),e[15]=l,e[16]=i,e[17]=n):n=e[17];let c;e[18]!==o.snippet?(c=(0,t.jsxDEV)("pre",{className:"mt-2 overflow-x-auto rounded bg-muted p-2 font-mono text-xs",children:o.snippet},void 0,!1),e[18]=o.snippet,e[19]=c):c=e[19];let p;return e[20]!==n||e[21]!==c?(p=(0,t.jsxDEV)(w,{className:"py-0","data-testid":"drain-card",children:(0,t.jsxDEV)(N,{className:"p-3",children:[n,c]},void 0,!0)},void 0,!1),e[20]=n,e[21]=c,e[22]=p):p=e[22],p},"DestinationRow"),F=f(()=>{let s=b(),e=[{description:s("Stream every request log to R2, a SIEM, or a third-party log service."),id:"logpush",snippet:["{",' "logpush": true',"}"].join(`
2
2
  `),title:s("Logpush")},{description:s("Send logs programmatically to a Worker for custom capture and forwarding."),id:"tail-worker",snippet:["{",' "tail_consumers": [{ "service": "my-log-forwarder" }]',"}"].join(`
3
3
  `),title:s("Tail Workers")},{description:s("Retain and query recent request logs directly in Cloudflare's dashboard."),id:"workers-logs",snippet:["{",' "observability": { "enabled": true }',"}"].join(`
4
4
  `),title:s("Workers Logs")}],[o,h]=(0,v.useState)(""),[m,u]=(0,v.useState)(!1),[r,a]=(0,v.useState)(null),l=f(async()=>{let i=o.trim();if(i==="")return;let n="fetch"in globalThis?globalThis.fetch:void 0;if(n===void 0){a({kind:"error",message:s("fetch is unavailable in this environment.")});return}let c={durationMs:12,function:"messages:list",outcome:"ok",shard:"root",source:"lunora",tablesRead:["messages"],tablesWritten:[],ts:new Date().toISOString(),type:"request"};u(!0),a(null);let p=performance.now();try{let x=await n(i,{body:JSON.stringify(c),headers:{"Content-Type":"application/json"},method:"POST"});a({kind:"success",latencyMs:Math.round(performance.now()-p),status:x.status})}catch(x){a({kind:"error",message:S(x)})}finally{u(!1)}},"sendTest"),g=f(()=>{T(l())},"onSendTest"),d=f(i=>{h(i.target.value)},"onWebhookUrlChange");return(0,t.jsxDEV)("div",{className:"flex flex-col gap-4","data-testid":"log-drains",children:[(0,t.jsxDEV)("div",{className:"flex flex-wrap items-center gap-3",children:(0,t.jsxDEV)("a",{className:"text-sm text-primary underline-offset-4 hover:underline","data-testid":"drain-cf-link",href:R,rel:"noreferrer",target:"_blank",children:s("Open in Cloudflare")},void 0,!1)},void 0,!1),(0,t.jsxDEV)("p",{className:"text-sm text-muted-foreground","data-testid":"drain-readonly-note",children:s("Lunora does not ship logs itself \u2014 forwarding is handled by Cloudflare. Configure a destination below, then test your collector.")},void 0,!1),(0,t.jsxDEV)("section",{className:"flex flex-col gap-3","data-testid":"drain-destinations",children:[(0,t.jsxDEV)("h3",{className:"font-mono text-[11px] tracking-wide text-muted-foreground uppercase",children:s("Cloudflare destinations")},void 0,!1),e.map(i=>(0,t.jsxDEV)(I,{destination:i},i.id,!1))]},void 0,!0),(0,t.jsxDEV)(w,{className:"py-0",children:(0,t.jsxDEV)(N,{className:"p-3",children:(0,t.jsxDEV)("section",{"data-testid":"drain-webhook",children:[(0,t.jsxDEV)("h3",{className:"mb-1 font-mono text-[11px] tracking-wide text-muted-foreground uppercase",children:s("Webhook test")},void 0,!1),(0,t.jsxDEV)("p",{className:"mb-2 text-sm text-muted-foreground",children:s("POST a sample Lunora request-log envelope to your collector to confirm it is reachable.")},void 0,!1),(0,t.jsxDEV)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,t.jsxDEV)(C,{className:"min-w-[20rem] flex-1","data-testid":"drain-webhook-url",onChange:d,placeholder:s("https://example.com/logs"),type:"url",value:o},void 0,!1),(0,t.jsxDEV)(k,{"data-testid":"drain-webhook-test",disabled:m||o.trim()==="",onClick:g,children:s(m?"Sending\u2026":"Send test event")},void 0,!1)]},void 0,!0),r!==null&&(0,t.jsxDEV)("p",{className:r.kind==="success"?"mt-2 text-sm text-muted-foreground":"mt-2 text-sm text-destructive","data-testid":"drain-webhook-result",role:r.kind==="error"?"alert":void 0,children:r.kind==="success"?s("Delivered \u2014 status {status} in {latency}ms",{latency:r.latencyMs,status:r.status}):s("Failed: {message}",{message:r.message})},void 0,!1)]},void 0,!0)},void 0,!1)},void 0,!1)]},void 0,!0)},"LogDrainsPanel");export{F as LogDrainsPanel};