@marimo-team/islands 0.25.2 → 0.25.3-dev10
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/{ConnectedDataExplorerComponent-CNSxdKyJ.js → ConnectedDataExplorerComponent-CNMliVzw.js} +1 -1
- package/dist/{ErrorBoundary-HusVNio-.js → ErrorBoundary-BsqSMK9Y.js} +1 -1
- package/dist/{abnfDiagram-VCTEODGH-DQDjNXt3.js → abnfDiagram-VCTEODGH-D-Ez91gV.js} +2 -2
- package/dist/{any-language-editor-B9REGlD9.js → any-language-editor-DZ_YTVus.js} +1 -1
- package/dist/{architectureDiagram-5GKGNRK7-Nmls7Wxn.js → architectureDiagram-5GKGNRK7-CTpcNtO8.js} +1 -1
- package/dist/{chat-ui-BDpymeoe.js → chat-ui-0lKdOoQ3.js} +436 -437
- package/dist/{chunk-IMKFNOWR-CoIFEo-1.js → chunk-IMKFNOWR-DGxi-zeo.js} +1 -1
- package/dist/{chunk-SHT3W25Y-lHiGx3ZC.js → chunk-SHT3W25Y-CV9J3rAB.js} +1 -1
- package/dist/{chunk-SVP7TREG-BvsHIrY_.js → chunk-SVP7TREG-BL-9Fqgg.js} +1 -1
- package/dist/{chunk-TICWLB2K-BC8YIm_n.js → chunk-TICWLB2K-Cu_XMjDM.js} +1 -1
- package/dist/{classDiagram-ZZMXUADV-Bt98lkkv.js → classDiagram-ZZMXUADV-BXXV13Hq.js} +2 -2
- package/dist/{classDiagram-v2-VYDZK3BY-D9bfbcC3.js → classDiagram-v2-VYDZK3BY-B7FXJ1Cp.js} +2 -2
- package/dist/{code-visibility-4aW5326K.js → code-visibility-CXQvUXHT.js} +14 -14
- package/dist/{common-Cjo7bjRK.js → common-CuD-CAC-.js} +6704 -6409
- package/dist/{cynefinDiagram-5FMLGOSQ-CgWra7wt.js → cynefinDiagram-5FMLGOSQ-CH96rwba.js} +1 -1
- package/dist/{dagre-GXQ25YYZ-CFZ8-35c.js → dagre-GXQ25YYZ-BD3PmpFY.js} +1 -1
- package/dist/{data-grid-overlay-editor-CvdQXfSk.js → data-grid-overlay-editor-DgeyYmC1.js} +1 -1
- package/dist/{diagram-S7CK7UJ4-lCNQrW7d.js → diagram-S7CK7UJ4-BsSJJldB.js} +1 -1
- package/dist/{diagram-UQ7AKVKN-CQPQ6pP_.js → diagram-UQ7AKVKN-muQtNZc4.js} +1 -1
- package/dist/{diagram-VX7I27RA-Cf3b0llz.js → diagram-VX7I27RA-CdhuZAqR.js} +1 -1
- package/dist/{diagram-Z3DM3KII-Bt4QLrpn.js → diagram-Z3DM3KII-BD8mXjOj.js} +1 -1
- package/dist/{ebnfDiagram-PWID7BFC-D3NAyPFY.js → ebnfDiagram-PWID7BFC-BIN1sweE.js} +2 -2
- package/dist/{erDiagram-RLTQ6QDP-Tlu09_Nm.js → erDiagram-RLTQ6QDP-Ctp5cfoN.js} +1 -1
- package/dist/{error-banner-Da600cwz.js → error-banner-D-WCIiMt.js} +10 -5
- package/dist/{cells-C8iCYvLU.js → error-entries-DSvFWT_M.js} +2262 -2206
- package/dist/{feedback-button-ZuLnINhC.js → feedback-button-DZMj9PF3.js} +115 -116
- package/dist/{flowDiagram-HODETNUW-CAYbpJmV.js → flowDiagram-HODETNUW-3EfLrlFb.js} +2 -2
- package/dist/{formats-BGh2thRc.js → formats-CeOmU1MU.js} +1 -1
- package/dist/{glide-data-editor-qM9FSJA9.js → glide-data-editor-g_L8FLAC.js} +3 -3
- package/dist/{globals-Ci7B9t6C.js → globals-CYGlmBXb.js} +1 -1
- package/dist/{html-to-image-CZY1pIZH.js → html-to-image-B8s5SgGm.js} +23 -23
- package/dist/{infoDiagram-27XIBGKW-XrDxhr0x.js → infoDiagram-27XIBGKW-DipQoHxl.js} +1 -1
- package/dist/{ishikawaDiagram-5VMMS53U-CD1muzov.js → ishikawaDiagram-5VMMS53U-DgFMjSGz.js} +1 -1
- package/dist/{kanban-definition-UXKFOSKX-Dg9W142_.js → kanban-definition-UXKFOSKX-w1ACVjgl.js} +1 -1
- package/dist/main.js +164 -163
- package/dist/{mermaid-CiAXjLpA.js → mermaid-CHo49Yv-.js} +33 -33
- package/dist/{mindmap-definition-YA3MSWOX-DgCidgYJ.js → mindmap-definition-YA3MSWOX-CrT0KSfX.js} +1 -1
- package/dist/{number-overlay-editor-DunDxAzh.js → number-overlay-editor-9VRv-pdj.js} +1 -1
- package/dist/{pegDiagram-XKGWAZYB-coOYYKB6.js → pegDiagram-XKGWAZYB-BqvywNJA.js} +2 -2
- package/dist/{pieDiagram-E7YTZNPT-BnXTc3bj.js → pieDiagram-E7YTZNPT-BfxJ_XCc.js} +1 -1
- package/dist/{process-output-e4jj9Ijt.js → process-output-CKRXyszb.js} +3 -3
- package/dist/{railroadDiagram-O6MQD6OU-B28-u83n.js → railroadDiagram-O6MQD6OU-8vFLVTPu.js} +2 -2
- package/dist/{requirementDiagram-BXWQKSXE-CdYCTMu0.js → requirementDiagram-BXWQKSXE-a_MxGvxe.js} +1 -1
- package/dist/{reveal-component-A7HedxmE.js → reveal-component-C87mv9Mn.js} +4 -4
- package/dist/{sequenceDiagram-WJ2MYXX4-CM3aRAe_.js → sequenceDiagram-WJ2MYXX4-CXFMnxGh.js} +1 -1
- package/dist/{stateDiagram-D77RDMKH-DOZUMVj8.js → stateDiagram-D77RDMKH-DQeA_CwI.js} +2 -2
- package/dist/{stateDiagram-v2-MP3YSRHH-CISYxma6.js → stateDiagram-v2-MP3YSRHH-BxxQucm1.js} +2 -2
- package/dist/style.css +1 -1
- package/dist/{swimlanes-42K2YHIH-BkSppxp8.js → swimlanes-42K2YHIH-Do6L-cYg.js} +1 -1
- package/dist/{swimlanesDiagram-VR7AAH4N-c8G5pGxC.js → swimlanesDiagram-VR7AAH4N-DUzPvSVU.js} +2 -2
- package/dist/{timeline-definition-24CTP7MA-CaMQayqK.js → timeline-definition-24CTP7MA-D3c46WM5.js} +1 -1
- package/dist/{toDate-BNJf01u1.js → toDate-vIXljnsr.js} +39 -38
- package/dist/{vega-component-DG29TAB7.js → vega-component-DTG6zxaY.js} +3 -3
- package/dist/{vennDiagram-4TSXK5OY-CF8pfaK3.js → vennDiagram-4TSXK5OY-BSZD8JcZ.js} +1 -1
- package/dist/{wardleyDiagram-VM6X3IG4-dGPu39d-.js → wardleyDiagram-VM6X3IG4-48cUWkfA.js} +1 -1
- package/dist/{xychartDiagram-S5SC5T6Z-CP6-9q56.js → xychartDiagram-S5SC5T6Z-CswYgYeu.js} +1 -1
- package/package.json +5 -2
- package/src/__tests__/fixtures/{pair-preview.ts → pair-config.ts} +3 -2
- package/src/__tests__/host-imports.test.ts +100 -0
- package/src/__tests__/mount.test.ts +8 -8
- package/src/components/data-table/__tests__/context-menu.test.ts +176 -0
- package/src/components/data-table/__tests__/date-filter-inputs.test.tsx +24 -1
- package/src/components/data-table/__tests__/export-actions.test.tsx +329 -6
- package/src/components/data-table/context-menu.tsx +125 -26
- package/src/components/data-table/date-filter-inputs.tsx +15 -42
- package/src/components/data-table/export-actions.tsx +192 -116
- package/src/components/data-table/schemas.ts +14 -36
- package/src/components/data-table/utils.ts +18 -0
- package/src/components/editor/Output.tsx +9 -2
- package/src/components/editor/actions/__tests__/pair-with-agent-commands.test.ts +80 -252
- package/src/components/editor/actions/__tests__/pair-with-agent-modal.test.tsx +186 -34
- package/src/components/editor/actions/pair-with-agent-commands.ts +42 -51
- package/src/components/editor/actions/pair-with-agent-modal.tsx +96 -36
- package/src/components/editor/chrome/panels/error-panel.tsx +1 -0
- package/src/components/editor/chrome/wrapper/__tests__/attachment-status.test.tsx +372 -0
- package/src/components/editor/chrome/wrapper/footer-item.tsx +32 -24
- package/src/components/editor/chrome/wrapper/footer-items/attachment-status.tsx +237 -0
- package/src/components/editor/chrome/wrapper/footer.tsx +2 -0
- package/src/components/editor/errors/__tests__/send-error-report-button.test.tsx +548 -0
- package/src/components/editor/errors/send-error-report-button.tsx +69 -0
- package/src/components/editor/output/MarimoErrorOutput.tsx +21 -5
- package/src/components/editor/output/MarimoTracebackOutput.tsx +35 -20
- package/src/components/editor/output/__tests__/ansi-reduce.test.ts +18 -0
- package/src/components/editor/output/ansi-reduce.ts +6 -0
- package/src/core/attachments/__tests__/toast.test.tsx +58 -0
- package/src/core/attachments/state.ts +21 -0
- package/src/core/attachments/toast.ts +15 -0
- package/src/core/cells/__tests__/cells.test.ts +52 -0
- package/src/core/cells/__tests__/error-report.test.ts +139 -0
- package/src/core/cells/__tests__/session.test.ts +50 -1
- package/src/core/cells/error-report.ts +63 -0
- package/src/core/cells/session.ts +28 -1
- package/src/core/config/pair.ts +5 -3
- package/src/core/host/AGENTS.md +6 -0
- package/src/core/host/__tests__/protocol.test.ts +214 -0
- package/src/core/host/protocol.ts +1943 -0
- package/src/core/islands/__tests__/bootstrap.test.ts +26 -0
- package/src/core/islands/bootstrap.ts +1 -0
- package/src/core/websocket/__tests__/useMarimoKernelConnection.hook.test.tsx +193 -0
- package/src/core/websocket/useMarimoKernelConnection.tsx +9 -0
- package/src/mount.tsx +3 -3
- package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +84 -0
- package/src/utils/__tests__/dates.test.ts +116 -0
- package/src/utils/dates.ts +94 -0
- package/dist/error-entries-CzoYkIQZ.js +0 -56
|
@@ -9,7 +9,7 @@ import "./chunk-4HAMMTFA-D4eFPyFh.js";
|
|
|
9
9
|
import "./chunk-GVQU2GXP-Cwbt-lF0.js";
|
|
10
10
|
import "./chunk-L3NEJ4N5-n-zgIVSy.js";
|
|
11
11
|
import { o as n } from "./chunk-OSK3NFVY-DXa-Cxbn.js";
|
|
12
|
-
import { c as r } from "./mermaid-
|
|
12
|
+
import { c as r } from "./mermaid-CHo49Yv-.js";
|
|
13
13
|
//#region ../node_modules/.pnpm/mermaid@11.17.2/node_modules/mermaid/dist/chunks/mermaid.core/swimlanes-42K2YHIH.mjs
|
|
14
14
|
var i = 5, a = 1e-5, o = 1e-6;
|
|
15
15
|
function s(e) {
|
package/dist/{swimlanesDiagram-VR7AAH4N-c8G5pGxC.js → swimlanesDiagram-VR7AAH4N-DUzPvSVU.js}
RENAMED
|
@@ -9,11 +9,11 @@ import "./chunk-4HAMMTFA-D4eFPyFh.js";
|
|
|
9
9
|
import "./chunk-GVQU2GXP-Cwbt-lF0.js";
|
|
10
10
|
import "./chunk-L3NEJ4N5-n-zgIVSy.js";
|
|
11
11
|
import "./chunk-OSK3NFVY-DXa-Cxbn.js";
|
|
12
|
-
import "./mermaid-
|
|
12
|
+
import "./mermaid-CHo49Yv-.js";
|
|
13
13
|
import "./chunk-F27PBJKO-ufseIn5y.js";
|
|
14
14
|
import "./chunk-XXDRQBXY-Dnl5VBqG.js";
|
|
15
15
|
import "./chunk-POPQ4Y6H-hYOXbYH_.js";
|
|
16
|
-
import { r as t, t as n } from "./chunk-SHT3W25Y-
|
|
16
|
+
import { r as t, t as n } from "./chunk-SHT3W25Y-CV9J3rAB.js";
|
|
17
17
|
//#region ../node_modules/.pnpm/mermaid@11.17.2/node_modules/mermaid/dist/chunks/mermaid.core/swimlanesDiagram-VR7AAH4N.mjs
|
|
18
18
|
var r = n({
|
|
19
19
|
defaultLayout: "swimlane",
|
package/dist/{timeline-definition-24CTP7MA-CaMQayqK.js → timeline-definition-24CTP7MA-D3c46WM5.js}
RENAMED
|
@@ -3,7 +3,7 @@ import { p as t } from "./chunk-75Z2AOVW-D7gxIs2Q.js";
|
|
|
3
3
|
import { n, t as r } from "./src-CA_m4ONl.js";
|
|
4
4
|
import { n as i, t as a } from "./chunk-Y2CYZVJY-DKKS1VyV.js";
|
|
5
5
|
import { $ as o, J as s, a as c, b as l, et as u, nt as d, o as f, x as p } from "./chunk-DU6HZSFF-BwiyaNpg.js";
|
|
6
|
-
import { p as m } from "./mermaid-
|
|
6
|
+
import { p as m } from "./mermaid-CHo49Yv-.js";
|
|
7
7
|
//#region ../node_modules/.pnpm/mermaid@11.17.2/node_modules/mermaid/dist/chunks/mermaid.core/timeline-definition-24CTP7MA.mjs
|
|
8
8
|
var h = (function() {
|
|
9
9
|
var e = /* @__PURE__ */ i(function(e, t, n, r) {
|
|
@@ -465,54 +465,55 @@ function M({ href: e, queryParams: t, keys: n }) {
|
|
|
465
465
|
let m = f.toString();
|
|
466
466
|
return m ? `${o}?${m}${s}` : e;
|
|
467
467
|
}
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
468
|
+
//#endregion
|
|
469
|
+
//#region src/core/kernel/session.ts
|
|
470
|
+
var N = a(null), P = (0, O.init)({ length: 6 });
|
|
471
|
+
function F() {
|
|
472
|
+
return `s_${P()}`;
|
|
472
473
|
}
|
|
473
|
-
function
|
|
474
|
+
function I(e) {
|
|
474
475
|
return e ? /^s_[\da-z]{6}$/.test(e) : !1;
|
|
475
476
|
}
|
|
476
|
-
var
|
|
477
|
-
function
|
|
478
|
-
let e = o.get(v) === "edit", n = new URL(window.location.href).searchParams.get(s.sessionId), r =
|
|
477
|
+
var L = null;
|
|
478
|
+
function R() {
|
|
479
|
+
let e = o.get(v) === "edit", n = new URL(window.location.href).searchParams.get(s.sessionId), r = I(n) ? n : null;
|
|
479
480
|
return k((t) => {
|
|
480
481
|
if (!e) {
|
|
481
482
|
t.delete(s.sessionId), t.delete(s.kiosk);
|
|
482
483
|
return;
|
|
483
484
|
}
|
|
484
485
|
t.has(s.kiosk) || t.delete(s.sessionId);
|
|
485
|
-
}), r === null ? (t.debug("Starting a new session", { sessionId: n }),
|
|
486
|
+
}), r === null ? (t.debug("Starting a new session", { sessionId: n }), F()) : e ? (t.debug("Connecting to existing session", { sessionId: r }), r) : (t.debug("Ignoring session_id from URL outside the editor", { sessionId: r }), F());
|
|
486
487
|
}
|
|
487
|
-
function
|
|
488
|
-
return
|
|
488
|
+
function z() {
|
|
489
|
+
return L === null && (L = R()), L;
|
|
489
490
|
}
|
|
490
491
|
//#endregion
|
|
491
492
|
//#region src/core/static/static-state.ts
|
|
492
|
-
function
|
|
493
|
+
function B(e) {
|
|
493
494
|
if (typeof e != "object" || !e || Array.isArray(e)) return !1;
|
|
494
495
|
for (let t of Object.values(e)) if (typeof t != "string") return !1;
|
|
495
496
|
return !0;
|
|
496
497
|
}
|
|
497
|
-
function
|
|
498
|
+
function V(e) {
|
|
498
499
|
if (typeof e != "object" || !e || Array.isArray(e)) return !1;
|
|
499
500
|
let t = e;
|
|
500
|
-
return !(!
|
|
501
|
-
}
|
|
502
|
-
function V() {
|
|
503
|
-
let e = typeof window > "u" ? void 0 : window.__MARIMO_STATIC__;
|
|
504
|
-
return B(e) ? e : void 0;
|
|
501
|
+
return !(!B(t.files) || t.modelNotifications !== void 0 && !Array.isArray(t.modelNotifications));
|
|
505
502
|
}
|
|
506
503
|
function H() {
|
|
507
|
-
|
|
504
|
+
let e = typeof window > "u" ? void 0 : window.__MARIMO_STATIC__;
|
|
505
|
+
return V(e) ? e : void 0;
|
|
508
506
|
}
|
|
509
507
|
function U() {
|
|
510
|
-
|
|
508
|
+
return H() !== void 0;
|
|
509
|
+
}
|
|
510
|
+
function W() {
|
|
511
|
+
let e = H();
|
|
511
512
|
return l(e !== void 0, "Not a static notebook"), e.files;
|
|
512
513
|
}
|
|
513
514
|
//#endregion
|
|
514
515
|
//#region src/core/runtime/runtime.ts
|
|
515
|
-
var
|
|
516
|
+
var G = class {
|
|
516
517
|
initialHealthyCheck = new m();
|
|
517
518
|
config;
|
|
518
519
|
lazy;
|
|
@@ -535,7 +536,7 @@ var W = class {
|
|
|
535
536
|
return this.httpURL.origin === window.location.origin;
|
|
536
537
|
}
|
|
537
538
|
get isServerless() {
|
|
538
|
-
return p() || c() ||
|
|
539
|
+
return p() || c() || U();
|
|
539
540
|
}
|
|
540
541
|
formatHttpURL({ path: e = "", searchParams: t, restrictToKnownQueryParams: n = !0 }) {
|
|
541
542
|
let r = this.httpURL, i = new URLSearchParams(window.location.search);
|
|
@@ -559,7 +560,7 @@ var W = class {
|
|
|
559
560
|
searchParams: t,
|
|
560
561
|
restrictToKnownQueryParams: !1
|
|
561
562
|
});
|
|
562
|
-
return
|
|
563
|
+
return K(this.appendCrossOriginAuth(n).toString());
|
|
563
564
|
}
|
|
564
565
|
getSessionSearchParams(e) {
|
|
565
566
|
let t = new URL(this.config.url), n = new URLSearchParams(t.search);
|
|
@@ -645,17 +646,17 @@ var W = class {
|
|
|
645
646
|
}
|
|
646
647
|
headers() {
|
|
647
648
|
let e = {
|
|
648
|
-
"Marimo-Session-Id":
|
|
649
|
+
"Marimo-Session-Id": z(),
|
|
649
650
|
"Marimo-Server-Token": this.config.serverToken ?? "",
|
|
650
651
|
"x-runtime-url": this.httpURL.toString()
|
|
651
652
|
};
|
|
652
653
|
return this.config.authToken && (e.Authorization = `Bearer ${this.config.authToken}`), e;
|
|
653
654
|
}
|
|
654
655
|
sessionHeaders() {
|
|
655
|
-
return { "Marimo-Session-Id":
|
|
656
|
+
return { "Marimo-Session-Id": z() };
|
|
656
657
|
}
|
|
657
658
|
};
|
|
658
|
-
function
|
|
659
|
+
function K(e) {
|
|
659
660
|
if (!e.startsWith("http")) {
|
|
660
661
|
t.warn(`URL must start with http: ${e}`);
|
|
661
662
|
let n = new URL(e);
|
|
@@ -665,29 +666,29 @@ function G(e) {
|
|
|
665
666
|
}
|
|
666
667
|
//#endregion
|
|
667
668
|
//#region src/core/runtime/config.ts
|
|
668
|
-
function
|
|
669
|
+
function q() {
|
|
669
670
|
let e = new URL(document.baseURI);
|
|
670
671
|
return e.search = "", e.hash = "", e.toString();
|
|
671
672
|
}
|
|
672
|
-
var
|
|
673
|
+
var J = {
|
|
673
674
|
lazy: !0,
|
|
674
|
-
url:
|
|
675
|
-
},
|
|
676
|
-
let t = e(
|
|
677
|
-
return new
|
|
675
|
+
url: q()
|
|
676
|
+
}, Y = a(J), ee = a((e) => {
|
|
677
|
+
let t = e(Y);
|
|
678
|
+
return new G(t, t.lazy);
|
|
678
679
|
});
|
|
679
680
|
function X() {
|
|
680
|
-
return o.get(
|
|
681
|
+
return o.get(ee);
|
|
681
682
|
}
|
|
682
|
-
function
|
|
683
|
+
function te(e) {
|
|
683
684
|
if (e.startsWith("http")) return new URL(e);
|
|
684
685
|
let t = X().httpURL.toString();
|
|
685
686
|
return t.startsWith("blob:") && (t = t.replace("blob:", "")), new URL(e, t);
|
|
686
687
|
}
|
|
687
688
|
//#endregion
|
|
688
689
|
//#region ../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/constants.js
|
|
689
|
-
var
|
|
690
|
-
Z * 7, Z *
|
|
690
|
+
var ne = 365.2425, re = 6048e5, ie = 864e5, Z = 86400;
|
|
691
|
+
Z * 7, Z * ne / 12 * 3;
|
|
691
692
|
var Q = Symbol.for("constructDateFrom");
|
|
692
693
|
//#endregion
|
|
693
694
|
//#region ../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/constructFrom.js
|
|
@@ -696,8 +697,8 @@ function $(e, t) {
|
|
|
696
697
|
}
|
|
697
698
|
//#endregion
|
|
698
699
|
//#region ../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/toDate.js
|
|
699
|
-
function
|
|
700
|
+
function ae(e, t) {
|
|
700
701
|
return $(t || e, e);
|
|
701
702
|
}
|
|
702
703
|
//#endregion
|
|
703
|
-
export { u as S,
|
|
704
|
+
export { u as C, f as S, b as _, te as a, m as b, U as c, j as d, k as f, y as g, v as h, re as i, N as l, g as m, $ as n, X as o, D as p, ie as r, W as s, ae as t, M as u, x as v, p as x, _ as y };
|
|
@@ -3,15 +3,15 @@ import { g as t, h as n, m as r, o as i } from "./button-CvjkwdSk.js";
|
|
|
3
3
|
import { t as a } from "./react-sHtZdjeP.js";
|
|
4
4
|
import { t as o } from "./compiler-runtime-CldRdSsv.js";
|
|
5
5
|
import { t as s } from "./tooltip-BO1REbqs.js";
|
|
6
|
-
import {
|
|
6
|
+
import { C as c, a as l } from "./toDate-vIXljnsr.js";
|
|
7
7
|
import { t as u } from "./jsx-runtime-3BD1kT0s.js";
|
|
8
|
-
import { n as d } from "./error-banner-
|
|
8
|
+
import { n as d } from "./error-banner-D-WCIiMt.js";
|
|
9
9
|
import { t as f } from "./debounce-C3jyATpc.js";
|
|
10
10
|
import { A as p, n as ee } from "./useTheme-CRnjkku0.js";
|
|
11
11
|
import { c as m } from "./arrays-CN1djC4k.js";
|
|
12
12
|
import { t as te } from "./objects-CzUgoMIF.js";
|
|
13
13
|
import { t as h } from "./useAsyncData-Deh5kszT.js";
|
|
14
|
-
import { a as ne, i as re, n as ie, t as g } from "./formats-
|
|
14
|
+
import { a as ne, i as re, n as ie, t as g } from "./formats-CeOmU1MU.js";
|
|
15
15
|
import { M as ae, n as oe } from "./vega-loader.browser-DNST6uVf.js";
|
|
16
16
|
import { t as se } from "./react-vega-BED0DjiB.js";
|
|
17
17
|
import { a as ce, n as _ } from "./loader-BQOfjTIJ.js";
|
|
@@ -3,7 +3,7 @@ import { t } from "./src-CA_m4ONl.js";
|
|
|
3
3
|
import { n } from "./chunk-Y2CYZVJY-DKKS1VyV.js";
|
|
4
4
|
import { $ as r, H as i, K as a, U as o, a as s, b as c, c as l, et as u, f as d, nt as f, tt as p, v as m, w as h, y as g } from "./chunk-DU6HZSFF-BwiyaNpg.js";
|
|
5
5
|
import { t as _ } from "./rough.esm-CtV9AnV1.js";
|
|
6
|
-
import { p as v } from "./mermaid-
|
|
6
|
+
import { p as v } from "./mermaid-CHo49Yv-.js";
|
|
7
7
|
//#region ../node_modules/.pnpm/khroma@2.1.0/node_modules/khroma/dist/methods/transparentize.js
|
|
8
8
|
var y = (e, t) => p(e, "a", -t), b = 1e-10;
|
|
9
9
|
function x(e, t) {
|
|
@@ -2,7 +2,7 @@ import { i as e } from "./chunk-75Z2AOVW-D7gxIs2Q.js";
|
|
|
2
2
|
import { n as t } from "./src-CA_m4ONl.js";
|
|
3
3
|
import { n } from "./chunk-Y2CYZVJY-DKKS1VyV.js";
|
|
4
4
|
import { D as r, H as i, K as a, U as o, a as s, b as c, c as l, v as u, w as d, x as f, y as p } from "./chunk-DU6HZSFF-BwiyaNpg.js";
|
|
5
|
-
import { p as m } from "./mermaid-
|
|
5
|
+
import { p as m } from "./mermaid-CHo49Yv-.js";
|
|
6
6
|
import { n as h } from "./mermaid-parser.core-DxuSfYwJ.js";
|
|
7
7
|
import { t as g } from "./chunk-JWPE2WC7-DJvv1t8U.js";
|
|
8
8
|
//#region ../node_modules/.pnpm/mermaid@11.17.2/node_modules/mermaid/dist/chunks/mermaid.core/wardleyDiagram-VM6X3IG4.mjs
|
|
@@ -9,7 +9,7 @@ import { n as s } from "./chunk-Y2CYZVJY-DKKS1VyV.js";
|
|
|
9
9
|
import { D as c, H as l, K as u, U as d, a as f, b as p, c as m, f as h, v as g, w as _, y as v, z as y } from "./chunk-DU6HZSFF-BwiyaNpg.js";
|
|
10
10
|
import "./chunk-PWAF6VOD-CQw5qATZ.js";
|
|
11
11
|
import { t as b } from "./chunk-GMAD6QVW-BhaJx0X3.js";
|
|
12
|
-
import { p as x } from "./mermaid-
|
|
12
|
+
import { p as x } from "./mermaid-CHo49Yv-.js";
|
|
13
13
|
//#region ../node_modules/.pnpm/d3-scale@4.0.2/node_modules/d3-scale/src/band.js
|
|
14
14
|
function S() {
|
|
15
15
|
var e = t().unknown(void 0), r = e.domain, i = e.range, o = 0, s = 1, c, l, u = !1, d = 0, f = 0, p = .5;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@marimo-team/islands",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.3-dev10",
|
|
4
4
|
"main": "dist/main.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -183,7 +183,9 @@
|
|
|
183
183
|
"preview:islands": "cross-env VITE_MARIMO_VERSION='0.4.6' VITE_MARIMO_ISLANDS=true vite --config islands/vite.config.mts build",
|
|
184
184
|
"storybook": "storybook dev -p 6006",
|
|
185
185
|
"build-storybook": "storybook build",
|
|
186
|
-
"sync-katex-css": "node --experimental-strip-types scripts/sync-katex-css.ts"
|
|
186
|
+
"sync-katex-css": "node --experimental-strip-types scripts/sync-katex-css.ts",
|
|
187
|
+
"codegen": "node --experimental-strip-types scripts/generate-host-protocol.ts",
|
|
188
|
+
"codegen:check": "node --experimental-strip-types scripts/generate-host-protocol.ts --check"
|
|
187
189
|
},
|
|
188
190
|
"peerDependencies": {
|
|
189
191
|
"react": "^17 || ^18 || ^19",
|
|
@@ -212,6 +214,7 @@
|
|
|
212
214
|
"jsdom": "^24.1.3",
|
|
213
215
|
"msw": "^2.15.0",
|
|
214
216
|
"npm-run-all2": "^6.2.6",
|
|
217
|
+
"orval": "8.40.0",
|
|
215
218
|
"oxc-transform-react": "0.145.0",
|
|
216
219
|
"oxfmt": "^0.68.0",
|
|
217
220
|
"oxlint": "^1.83.0",
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
5
|
-
import {
|
|
5
|
+
import { pairConfigSchema } from "@/core/config/pair";
|
|
6
6
|
|
|
7
7
|
// Read the Python-owned resource only in tests to check the shared contract.
|
|
8
|
-
export const
|
|
8
|
+
export const PAIR_CONFIG = pairConfigSchema.parse({
|
|
9
9
|
command: "uvx marimo@latest",
|
|
10
|
+
hostEnabled: true,
|
|
10
11
|
templates: JSON.parse(
|
|
11
12
|
readFileSync(
|
|
12
13
|
path.resolve(
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import NodeChildProcess from "node:child_process";
|
|
4
|
+
import NodeFs from "node:fs";
|
|
5
|
+
import NodeOs from "node:os";
|
|
6
|
+
import NodePath from "node:path";
|
|
7
|
+
import NodeUrl from "node:url";
|
|
8
|
+
import { expect, it } from "vitest";
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
|
|
11
|
+
it("enforces host dependencies for runtime and type imports", () => {
|
|
12
|
+
const frontend = NodeUrl.fileURLToPath(
|
|
13
|
+
new NodeUrl.URL("../../", import.meta.url),
|
|
14
|
+
);
|
|
15
|
+
const directory = NodeFs.mkdtempSync(
|
|
16
|
+
NodePath.join(NodeOs.tmpdir(), "host-imports-"),
|
|
17
|
+
);
|
|
18
|
+
const files = {
|
|
19
|
+
"src/core/host/allowed.ts": `
|
|
20
|
+
import { atom } from "jotai/vanilla";
|
|
21
|
+
import { z } from "zod";
|
|
22
|
+
import { Logger } from "@/utils/Logger";
|
|
23
|
+
import type { Document } from "./document";
|
|
24
|
+
export * from "@/core/host/events";
|
|
25
|
+
type Event = import("./events").NotebookEvent;
|
|
26
|
+
void import("./protocol");
|
|
27
|
+
`,
|
|
28
|
+
"src/core/host/protocol.ts": `
|
|
29
|
+
import type { NotificationMessage as A } from "../kernel/messages";
|
|
30
|
+
import { type NotificationMessage as B } from "@/core/kernel/messages";
|
|
31
|
+
import { NotificationMessage as C } from "../kernel/messages";
|
|
32
|
+
import type { NotificationPayload } from "../kernel/messages";
|
|
33
|
+
`,
|
|
34
|
+
"src/core/host/forbidden.ts": `
|
|
35
|
+
import { useEffect } from "react";
|
|
36
|
+
import type { NotificationMessage } from "../kernel/messages";
|
|
37
|
+
export * from "../kernel/messages";
|
|
38
|
+
export { Logger } from "@/utils/Logger/../other";
|
|
39
|
+
void import("../kernel/messages");
|
|
40
|
+
type Message = import("../kernel/messages").NotificationMessage;
|
|
41
|
+
const module = require("../kernel/messages");
|
|
42
|
+
void import(module);
|
|
43
|
+
import "./__tests__/allowed";
|
|
44
|
+
import "./allowed.test";
|
|
45
|
+
`,
|
|
46
|
+
"src/core/host/__tests__/allowed.ts": `import { useEffect } from "react";`,
|
|
47
|
+
"src/core/host/allowed.test.ts": `import { useEffect } from "react";`,
|
|
48
|
+
"src/core/host/allowed.spec.ts": `import { useEffect } from "react";`,
|
|
49
|
+
"src/core/websocket/allowed.ts": `import { useEffect } from "react";`,
|
|
50
|
+
};
|
|
51
|
+
try {
|
|
52
|
+
for (const [path, source] of Object.entries(files)) {
|
|
53
|
+
const destination = NodePath.join(directory, path);
|
|
54
|
+
NodeFs.mkdirSync(NodePath.dirname(destination), { recursive: true });
|
|
55
|
+
NodeFs.writeFileSync(destination, source);
|
|
56
|
+
}
|
|
57
|
+
const result = NodeChildProcess.spawnSync(
|
|
58
|
+
NodePath.join(frontend, "node_modules/.bin/oxlint"),
|
|
59
|
+
[
|
|
60
|
+
"--config",
|
|
61
|
+
NodePath.join(frontend, ".oxlintrc.json"),
|
|
62
|
+
"--format",
|
|
63
|
+
"json",
|
|
64
|
+
directory,
|
|
65
|
+
],
|
|
66
|
+
{ cwd: frontend, encoding: "utf8" },
|
|
67
|
+
);
|
|
68
|
+
const report = z
|
|
69
|
+
.object({
|
|
70
|
+
diagnostics: z.array(
|
|
71
|
+
z.object({
|
|
72
|
+
severity: z.string(),
|
|
73
|
+
filename: z.string(),
|
|
74
|
+
labels: z.array(z.object({ span: z.object({ line: z.number() }) })),
|
|
75
|
+
}),
|
|
76
|
+
),
|
|
77
|
+
})
|
|
78
|
+
.parse(JSON.parse(result.stdout));
|
|
79
|
+
const errors = report.diagnostics.filter(
|
|
80
|
+
(diagnostic) => diagnostic.severity === "error",
|
|
81
|
+
);
|
|
82
|
+
expect(
|
|
83
|
+
errors
|
|
84
|
+
.map((error) => ({
|
|
85
|
+
file: NodePath.basename(error.filename),
|
|
86
|
+
line: error.labels[0].span.line,
|
|
87
|
+
}))
|
|
88
|
+
.toSorted((a, b) => a.file.localeCompare(b.file) || a.line - b.line),
|
|
89
|
+
).toEqual([
|
|
90
|
+
...[2, 3, 4, 5, 6, 7, 8, 9, 10, 11].map((line) => ({
|
|
91
|
+
file: "forbidden.ts",
|
|
92
|
+
line,
|
|
93
|
+
})),
|
|
94
|
+
...[2, 3, 4, 5].map((line) => ({ file: "protocol.ts", line })),
|
|
95
|
+
]);
|
|
96
|
+
expect(result.status).toBe(1);
|
|
97
|
+
} finally {
|
|
98
|
+
NodeFs.rmSync(directory, { recursive: true, force: true });
|
|
99
|
+
}
|
|
100
|
+
});
|
|
@@ -8,8 +8,8 @@ import { connectionAtom } from "@/core/network/connection";
|
|
|
8
8
|
import { store } from "@/core/state/jotai";
|
|
9
9
|
import { isStaticNotebook } from "@/core/static/static-state";
|
|
10
10
|
import { ConnectionState } from "@/core/websocket/types";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
11
|
+
import { pairConfigAtom } from "@/core/config/pair";
|
|
12
|
+
import { PAIR_CONFIG } from "./fixtures/pair-config";
|
|
13
13
|
import { mount, visibleForTesting } from "../mount";
|
|
14
14
|
|
|
15
15
|
// Mock React DOM
|
|
@@ -84,20 +84,20 @@ describe("mount", () => {
|
|
|
84
84
|
mockElement,
|
|
85
85
|
);
|
|
86
86
|
|
|
87
|
-
it("hydrates the server's Pair
|
|
88
|
-
const error = mountRead({
|
|
87
|
+
it("hydrates the server's Pair configuration", () => {
|
|
88
|
+
const error = mountRead({ pairConfig: PAIR_CONFIG });
|
|
89
89
|
|
|
90
90
|
expect(error).toBeUndefined();
|
|
91
|
-
expect(store.get(
|
|
91
|
+
expect(store.get(pairConfigAtom)).toEqual(PAIR_CONFIG);
|
|
92
92
|
});
|
|
93
93
|
|
|
94
|
-
it("
|
|
95
|
-
store.set(
|
|
94
|
+
it("clears Pair configuration when the server omits it", () => {
|
|
95
|
+
store.set(pairConfigAtom, PAIR_CONFIG);
|
|
96
96
|
|
|
97
97
|
const error = mountRead();
|
|
98
98
|
|
|
99
99
|
expect(error).toBeUndefined();
|
|
100
|
-
expect(store.get(
|
|
100
|
+
expect(store.get(pairConfigAtom)).toBeUndefined();
|
|
101
101
|
});
|
|
102
102
|
|
|
103
103
|
describe("connection state initialization", () => {
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
|
4
|
+
import { buildCellFilter } from "../context-menu";
|
|
5
|
+
|
|
6
|
+
describe("buildCellFilter", () => {
|
|
7
|
+
// Use a non-UTC, non-DST-ambiguous offset so date-only parsing bugs
|
|
8
|
+
// (UTC vs. local midnight) can't hide behind a host machine that
|
|
9
|
+
// happens to run in UTC.
|
|
10
|
+
let originalTimezone: string | undefined;
|
|
11
|
+
beforeAll(() => {
|
|
12
|
+
originalTimezone = process.env.TZ;
|
|
13
|
+
process.env.TZ = "America/New_York";
|
|
14
|
+
});
|
|
15
|
+
afterAll(() => {
|
|
16
|
+
process.env.TZ = originalTimezone;
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("builds an equality filter for a normal date value", () => {
|
|
20
|
+
const filter = buildCellFilter({
|
|
21
|
+
type: "date",
|
|
22
|
+
value: "2024-01-15",
|
|
23
|
+
comparison: "eq",
|
|
24
|
+
dataType: "date",
|
|
25
|
+
dtype: "date",
|
|
26
|
+
});
|
|
27
|
+
expect(filter).toEqual({
|
|
28
|
+
type: "date",
|
|
29
|
+
operator: "==",
|
|
30
|
+
// Must be local midnight, not `new Date("2024-01-15")` (UTC
|
|
31
|
+
// midnight), or the filter shifts by a day in UTC- timezones.
|
|
32
|
+
value: new Date(2024, 0, 15),
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("returns undefined for an empty-string date value in a non-temporal-looking context", () => {
|
|
37
|
+
const filter = buildCellFilter({
|
|
38
|
+
type: "date",
|
|
39
|
+
value: "",
|
|
40
|
+
comparison: "eq",
|
|
41
|
+
dataType: "date",
|
|
42
|
+
dtype: "date",
|
|
43
|
+
});
|
|
44
|
+
expect(filter).toBeUndefined();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("returns undefined for an unparsable date value instead of an Invalid Date filter", () => {
|
|
48
|
+
const filter = buildCellFilter({
|
|
49
|
+
type: "date",
|
|
50
|
+
value: "not-a-date",
|
|
51
|
+
comparison: "eq",
|
|
52
|
+
dataType: "date",
|
|
53
|
+
dtype: "date",
|
|
54
|
+
});
|
|
55
|
+
expect(filter).toBeUndefined();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("builds an equality filter for a normal datetime value", () => {
|
|
59
|
+
const filter = buildCellFilter({
|
|
60
|
+
type: "datetime",
|
|
61
|
+
value: "2024-01-15 08:30:00",
|
|
62
|
+
comparison: "eq",
|
|
63
|
+
dataType: "datetime",
|
|
64
|
+
dtype: "datetime64[ns]",
|
|
65
|
+
});
|
|
66
|
+
expect(filter).toEqual({
|
|
67
|
+
type: "datetime",
|
|
68
|
+
operator: "==",
|
|
69
|
+
value: new Date(2024, 0, 15, 8, 30, 0),
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("returns undefined for an unparsable datetime value", () => {
|
|
74
|
+
const filter = buildCellFilter({
|
|
75
|
+
type: "datetime",
|
|
76
|
+
value: "not-a-datetime",
|
|
77
|
+
comparison: "eq",
|
|
78
|
+
dataType: "datetime",
|
|
79
|
+
dtype: "datetime64[ns]",
|
|
80
|
+
});
|
|
81
|
+
expect(filter).toBeUndefined();
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it("builds an equality filter for a normal time value", () => {
|
|
85
|
+
const filter = buildCellFilter({
|
|
86
|
+
type: "time",
|
|
87
|
+
value: "08:30:00",
|
|
88
|
+
comparison: "eq",
|
|
89
|
+
dataType: "time",
|
|
90
|
+
});
|
|
91
|
+
expect(filter).toEqual({
|
|
92
|
+
type: "time",
|
|
93
|
+
operator: "==",
|
|
94
|
+
value: new Date(1970, 0, 1, 8, 30, 0),
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("returns undefined instead of an unparsable time value", () => {
|
|
99
|
+
const filter = buildCellFilter({
|
|
100
|
+
type: "time",
|
|
101
|
+
value: "25:00:00",
|
|
102
|
+
comparison: "eq",
|
|
103
|
+
dataType: "time",
|
|
104
|
+
});
|
|
105
|
+
expect(filter).toBeUndefined();
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("maps a NaT date value to is_null instead of an invalid Date filter", () => {
|
|
109
|
+
const filter = buildCellFilter({
|
|
110
|
+
type: "date",
|
|
111
|
+
value: "NaT",
|
|
112
|
+
comparison: "eq",
|
|
113
|
+
dataType: "date",
|
|
114
|
+
dtype: "date",
|
|
115
|
+
});
|
|
116
|
+
expect(filter).toEqual({ type: "date", operator: "is_null" });
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it("maps a NaT datetime value to is_not_null for the neq comparison", () => {
|
|
120
|
+
const filter = buildCellFilter({
|
|
121
|
+
type: "datetime",
|
|
122
|
+
value: "NaT",
|
|
123
|
+
comparison: "neq",
|
|
124
|
+
dataType: "datetime",
|
|
125
|
+
dtype: "datetime64[ns]",
|
|
126
|
+
});
|
|
127
|
+
expect(filter).toEqual({ type: "datetime", operator: "is_not_null" });
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it("does not treat the string 'NaT' in a non-temporal column as a sentinel", () => {
|
|
131
|
+
const filter = buildCellFilter({
|
|
132
|
+
type: "text",
|
|
133
|
+
value: "NaT",
|
|
134
|
+
comparison: "eq",
|
|
135
|
+
dataType: "string",
|
|
136
|
+
});
|
|
137
|
+
expect(filter).toEqual({ type: "text", operator: "equals", text: "NaT" });
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it("maps an actual null value to is_null", () => {
|
|
141
|
+
const filter = buildCellFilter({
|
|
142
|
+
type: "number",
|
|
143
|
+
value: null,
|
|
144
|
+
comparison: "eq",
|
|
145
|
+
dataType: "number",
|
|
146
|
+
});
|
|
147
|
+
expect(filter).toEqual({ type: "number", operator: "is_null" });
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it("builds a literal (always-false) equality filter for a NaN number value", () => {
|
|
151
|
+
// NaN is a real float value, not a missing-value marker like null/NaT,
|
|
152
|
+
// and the backend's is_null() (narwhals/polars semantics) doesn't match
|
|
153
|
+
// it, so it falls through to a normal (if unsatisfiable) == filter.
|
|
154
|
+
const filter = buildCellFilter({
|
|
155
|
+
type: "number",
|
|
156
|
+
value: Number.NaN,
|
|
157
|
+
comparison: "eq",
|
|
158
|
+
dataType: "number",
|
|
159
|
+
});
|
|
160
|
+
expect(filter).toEqual({
|
|
161
|
+
type: "number",
|
|
162
|
+
operator: "==",
|
|
163
|
+
value: Number.NaN,
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it("builds a literal equality filter for a normal number value", () => {
|
|
168
|
+
const filter = buildCellFilter({
|
|
169
|
+
type: "number",
|
|
170
|
+
value: 42,
|
|
171
|
+
comparison: "eq",
|
|
172
|
+
dataType: "number",
|
|
173
|
+
});
|
|
174
|
+
expect(filter).toEqual({ type: "number", operator: "==", value: 42 });
|
|
175
|
+
});
|
|
176
|
+
});
|
|
@@ -1,7 +1,30 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
import { describe, expect, it } from "vitest";
|
|
3
3
|
import { dateToLocalISODate } from "@/utils/dates";
|
|
4
|
-
import { parsePastedRange } from "../date-filter-inputs";
|
|
4
|
+
import { parsePastedDate, parsePastedRange } from "../date-filter-inputs";
|
|
5
|
+
|
|
6
|
+
describe("parsePastedDate", () => {
|
|
7
|
+
it("parses a time-only string for the time filter type", () => {
|
|
8
|
+
const result = parsePastedDate("time", "2:30 PM");
|
|
9
|
+
expect(result).toEqual(new Date(1970, 0, 1, 14, 30));
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it("parses a local ISO datetime for the datetime filter type", () => {
|
|
13
|
+
const result = parsePastedDate("datetime", "2026-02-01T08:30:00");
|
|
14
|
+
expect(result).toEqual(new Date(2026, 1, 1, 8, 30, 0));
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("falls back to the Date constructor for other formats", () => {
|
|
18
|
+
const result = parsePastedDate("datetime", "Feb 1, 2026 08:30:00");
|
|
19
|
+
expect(result).toBeDefined();
|
|
20
|
+
expect(result?.getFullYear()).toBe(2026);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("returns undefined for an empty or unparsable string", () => {
|
|
24
|
+
expect(parsePastedDate("date", "")).toBeUndefined();
|
|
25
|
+
expect(parsePastedDate("time", "not-a-time")).toBeUndefined();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
5
28
|
|
|
6
29
|
describe("parsePastedRange", () => {
|
|
7
30
|
it.each([
|