@assistant-ui/x-generative-compiler 0.0.5 → 0.0.6
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/compile.d.ts.map +1 -1
- package/dist/compile.js +247 -36
- package/dist/compile.js.map +1 -1
- package/dist/package.js +1 -1
- package/package.json +9 -9
- package/src/compile.test.ts +390 -4
- package/src/compile.ts +397 -36
package/src/compile.test.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import * as nodePath from "node:path";
|
|
4
|
-
import { describe, it, expect } from "vitest";
|
|
4
|
+
import { describe, it, expect, vi } from "vitest";
|
|
5
5
|
import {
|
|
6
6
|
compileGenerative,
|
|
7
7
|
isGenerativeModule,
|
|
@@ -86,6 +86,19 @@ function createMergeFixture(childSource: string): string {
|
|
|
86
86
|
return nodePath.join(appRoot, "src", "toolkit.tsx");
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
function createMultiMergeFixture(files: Record<string, string>): string {
|
|
90
|
+
const appRoot = mkdtempSync(
|
|
91
|
+
nodePath.join(tmpdir(), "aui-generative-merge-many-"),
|
|
92
|
+
);
|
|
93
|
+
const srcRoot = nodePath.join(appRoot, "src");
|
|
94
|
+
for (const [relativePath, source] of Object.entries(files)) {
|
|
95
|
+
const file = nodePath.join(srcRoot, relativePath);
|
|
96
|
+
mkdirSync(nodePath.dirname(file), { recursive: true });
|
|
97
|
+
writeFileSync(file, source);
|
|
98
|
+
}
|
|
99
|
+
return nodePath.join(srcRoot, "toolkit.tsx");
|
|
100
|
+
}
|
|
101
|
+
|
|
89
102
|
/**
|
|
90
103
|
* Like {@link createMergeFixture}, but also writes a (JSONC) `tsconfig.json`
|
|
91
104
|
* with a `@/*` path alias so alias resolution can be exercised. The child lives
|
|
@@ -407,6 +420,41 @@ export default defineToolkit({
|
|
|
407
420
|
expect(client.trimStart().startsWith('"use client"')).toBe(true);
|
|
408
421
|
});
|
|
409
422
|
|
|
423
|
+
it("splits an unstable_interactableTool entry: client keeps render, server drops it", () => {
|
|
424
|
+
const src = `"use generative";
|
|
425
|
+
import { z } from "zod";
|
|
426
|
+
import { Notepad } from "@/ui/notepad";
|
|
427
|
+
import { defineToolkit, unstable_interactableTool } from "@assistant-ui/react";
|
|
428
|
+
export default defineToolkit({
|
|
429
|
+
notepad: unstable_interactableTool({
|
|
430
|
+
description: "A notepad.",
|
|
431
|
+
stateSchema: z.object({ content: z.string() }),
|
|
432
|
+
render: (props) => <Notepad {...props} />,
|
|
433
|
+
}),
|
|
434
|
+
});`;
|
|
435
|
+
const server = compileGenerative(src, { target: "server" }).code;
|
|
436
|
+
expect(server).toContain("unstable_interactableTool({");
|
|
437
|
+
expect(server).toContain('description: "A notepad."');
|
|
438
|
+
expect(server).toContain("z.object");
|
|
439
|
+
expect(server).not.toMatch(/render\s*:/);
|
|
440
|
+
expect(server).not.toContain("@/ui/notepad");
|
|
441
|
+
expect(server).not.toContain("server-only");
|
|
442
|
+
const client = compileGenerative(src, { target: "client" }).code;
|
|
443
|
+
expect(client.trimStart().startsWith('"use client"')).toBe(true);
|
|
444
|
+
expect(client).toContain("<Notepad");
|
|
445
|
+
expect(client).toContain('import { Notepad } from "@/ui/notepad"');
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
it("rejects unstable_interactableTool not imported from an assistant-ui package", () => {
|
|
449
|
+
const src = `"use generative";
|
|
450
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
451
|
+
import { unstable_interactableTool } from "@/my-tools";
|
|
452
|
+
export default defineToolkit({ notepad: unstable_interactableTool({ render: () => null }) });`;
|
|
453
|
+
expect(() => compileGenerative(src, { target: "server" })).toThrow(
|
|
454
|
+
/inline object literal/,
|
|
455
|
+
);
|
|
456
|
+
});
|
|
457
|
+
|
|
410
458
|
it("routes provider tool config", () => {
|
|
411
459
|
const src = `"use generative";
|
|
412
460
|
import { defineToolkit, providerTool } from "@assistant-ui/react";
|
|
@@ -559,6 +607,291 @@ export default defineToolkit({
|
|
|
559
607
|
expect(client).toContain('from "./tools/weather"');
|
|
560
608
|
});
|
|
561
609
|
|
|
610
|
+
it("allows unique tool names across more than two imported generative spreads", () => {
|
|
611
|
+
const filename = createMultiMergeFixture({
|
|
612
|
+
"tools/weather.tsx": `"use generative";
|
|
613
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
614
|
+
export default defineToolkit({
|
|
615
|
+
get_weather: { execute: async () => 1, render: () => null },
|
|
616
|
+
});`,
|
|
617
|
+
"tools/database.tsx": `"use generative";
|
|
618
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
619
|
+
export default defineToolkit({
|
|
620
|
+
query_db: { execute: async () => 1, render: () => null },
|
|
621
|
+
});`,
|
|
622
|
+
"tools/calendar.tsx": `"use generative";
|
|
623
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
624
|
+
export default defineToolkit({
|
|
625
|
+
create_event: { execute: async () => 1, render: () => null },
|
|
626
|
+
});`,
|
|
627
|
+
"tools/email.tsx": `"use generative";
|
|
628
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
629
|
+
export default defineToolkit({
|
|
630
|
+
send_email: { execute: async () => 1, render: () => null },
|
|
631
|
+
});`,
|
|
632
|
+
});
|
|
633
|
+
const src = `"use generative";
|
|
634
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
635
|
+
import weatherTools from "./tools/weather";
|
|
636
|
+
import databaseTools from "./tools/database";
|
|
637
|
+
import calendarTools from "./tools/calendar";
|
|
638
|
+
import emailTools from "./tools/email";
|
|
639
|
+
export default defineToolkit({
|
|
640
|
+
...weatherTools,
|
|
641
|
+
...databaseTools,
|
|
642
|
+
...calendarTools,
|
|
643
|
+
...emailTools,
|
|
644
|
+
});`;
|
|
645
|
+
|
|
646
|
+
const client = compileGenerative(src, { target: "client", filename }).code;
|
|
647
|
+
expect(client).toContain("...weatherTools");
|
|
648
|
+
expect(client).toContain("...databaseTools");
|
|
649
|
+
expect(client).toContain("...calendarTools");
|
|
650
|
+
expect(client).toContain("...emailTools");
|
|
651
|
+
});
|
|
652
|
+
|
|
653
|
+
it("warns about duplicate tool names across more than two imported generative spreads", () => {
|
|
654
|
+
const filename = createMultiMergeFixture({
|
|
655
|
+
"tools/weather.tsx": `"use generative";
|
|
656
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
657
|
+
export default defineToolkit({
|
|
658
|
+
get_weather: { execute: async () => 1, render: () => null },
|
|
659
|
+
search: { execute: async () => 1, render: () => null },
|
|
660
|
+
});`,
|
|
661
|
+
"tools/database.tsx": `"use generative";
|
|
662
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
663
|
+
export default defineToolkit({
|
|
664
|
+
query_db: { execute: async () => 1, render: () => null },
|
|
665
|
+
});`,
|
|
666
|
+
"tools/calendar.tsx": `"use generative";
|
|
667
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
668
|
+
export default defineToolkit({
|
|
669
|
+
search: { execute: async () => 1, render: () => null },
|
|
670
|
+
});`,
|
|
671
|
+
"tools/email.tsx": `"use generative";
|
|
672
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
673
|
+
export default defineToolkit({
|
|
674
|
+
send_email: { execute: async () => 1, render: () => null },
|
|
675
|
+
});`,
|
|
676
|
+
});
|
|
677
|
+
const src = `"use generative";
|
|
678
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
679
|
+
import weatherTools from "./tools/weather";
|
|
680
|
+
import databaseTools from "./tools/database";
|
|
681
|
+
import calendarTools from "./tools/calendar";
|
|
682
|
+
import emailTools from "./tools/email";
|
|
683
|
+
export default defineToolkit({
|
|
684
|
+
...weatherTools,
|
|
685
|
+
...databaseTools,
|
|
686
|
+
...calendarTools,
|
|
687
|
+
...emailTools,
|
|
688
|
+
});`;
|
|
689
|
+
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
690
|
+
|
|
691
|
+
try {
|
|
692
|
+
const client = compileGenerative(src, {
|
|
693
|
+
target: "client",
|
|
694
|
+
filename,
|
|
695
|
+
}).code;
|
|
696
|
+
|
|
697
|
+
expect(client).toContain("...weatherTools");
|
|
698
|
+
expect(client).toContain("...databaseTools");
|
|
699
|
+
expect(client).toContain("...calendarTools");
|
|
700
|
+
expect(client).toContain("...emailTools");
|
|
701
|
+
expect(warn).toHaveBeenCalledWith(
|
|
702
|
+
expect.stringContaining("[assistant-ui/use-generative]"),
|
|
703
|
+
);
|
|
704
|
+
expect(warn).toHaveBeenCalledWith(
|
|
705
|
+
expect.stringContaining(
|
|
706
|
+
'Duplicate tool name "search" while composing toolkits. ' +
|
|
707
|
+
"JavaScript object spread keeps the last definition.",
|
|
708
|
+
),
|
|
709
|
+
);
|
|
710
|
+
} finally {
|
|
711
|
+
warn.mockRestore();
|
|
712
|
+
}
|
|
713
|
+
});
|
|
714
|
+
|
|
715
|
+
it("does not reuse imported toolkit names across compile calls", () => {
|
|
716
|
+
const filename = createMultiMergeFixture({
|
|
717
|
+
"tools/weather.tsx": `"use generative";
|
|
718
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
719
|
+
export default defineToolkit({
|
|
720
|
+
get_weather: { execute: async () => 1, render: () => null },
|
|
721
|
+
});`,
|
|
722
|
+
"tools/calendar.tsx": `"use generative";
|
|
723
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
724
|
+
export default defineToolkit({
|
|
725
|
+
search: { execute: async () => 1, render: () => null },
|
|
726
|
+
});`,
|
|
727
|
+
});
|
|
728
|
+
const src = `"use generative";
|
|
729
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
730
|
+
import weatherTools from "./tools/weather";
|
|
731
|
+
import calendarTools from "./tools/calendar";
|
|
732
|
+
export default defineToolkit({
|
|
733
|
+
...weatherTools,
|
|
734
|
+
...calendarTools,
|
|
735
|
+
});`;
|
|
736
|
+
|
|
737
|
+
compileGenerative(src, { target: "client", filename });
|
|
738
|
+
writeFileSync(
|
|
739
|
+
nodePath.join(nodePath.dirname(filename), "tools", "weather.tsx"),
|
|
740
|
+
`"use generative";
|
|
741
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
742
|
+
export default defineToolkit({
|
|
743
|
+
search: { execute: async () => 1, render: () => null },
|
|
744
|
+
});`,
|
|
745
|
+
);
|
|
746
|
+
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
747
|
+
|
|
748
|
+
try {
|
|
749
|
+
compileGenerative(src, { target: "client", filename });
|
|
750
|
+
|
|
751
|
+
expect(warn).toHaveBeenCalledWith(
|
|
752
|
+
expect.stringContaining(
|
|
753
|
+
'Duplicate tool name "search" while composing toolkits. ' +
|
|
754
|
+
"JavaScript object spread keeps the last definition.",
|
|
755
|
+
),
|
|
756
|
+
);
|
|
757
|
+
} finally {
|
|
758
|
+
warn.mockRestore();
|
|
759
|
+
}
|
|
760
|
+
});
|
|
761
|
+
|
|
762
|
+
it("warns about duplicate tool names between local toolkit spreads", () => {
|
|
763
|
+
const src = `"use generative";
|
|
764
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
765
|
+
const weatherTools = defineToolkit({
|
|
766
|
+
get_weather: { execute: async () => 1, render: () => null },
|
|
767
|
+
search: { execute: async () => 1, render: () => null },
|
|
768
|
+
});
|
|
769
|
+
const databaseTools = defineToolkit({
|
|
770
|
+
query_db: { execute: async () => 1, render: () => null },
|
|
771
|
+
});
|
|
772
|
+
const calendarTools = defineToolkit({
|
|
773
|
+
search: { execute: async () => 1, render: () => null },
|
|
774
|
+
});
|
|
775
|
+
const emailTools = defineToolkit({
|
|
776
|
+
send_email: { execute: async () => 1, render: () => null },
|
|
777
|
+
});
|
|
778
|
+
export default defineToolkit({
|
|
779
|
+
...weatherTools,
|
|
780
|
+
...databaseTools,
|
|
781
|
+
...calendarTools,
|
|
782
|
+
...emailTools,
|
|
783
|
+
});`;
|
|
784
|
+
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
785
|
+
|
|
786
|
+
try {
|
|
787
|
+
const client = compileGenerative(src, { target: "client" }).code;
|
|
788
|
+
|
|
789
|
+
expect(client).toContain("...weatherTools");
|
|
790
|
+
expect(client).toContain("...databaseTools");
|
|
791
|
+
expect(client).toContain("...calendarTools");
|
|
792
|
+
expect(client).toContain("...emailTools");
|
|
793
|
+
expect(warn).toHaveBeenCalledWith(
|
|
794
|
+
expect.stringContaining(
|
|
795
|
+
'[assistant-ui/use-generative] Duplicate tool name "search" while composing toolkits. ' +
|
|
796
|
+
"JavaScript object spread keeps the last definition.",
|
|
797
|
+
),
|
|
798
|
+
);
|
|
799
|
+
} finally {
|
|
800
|
+
warn.mockRestore();
|
|
801
|
+
}
|
|
802
|
+
});
|
|
803
|
+
|
|
804
|
+
it("warns once across server and client compiles", () => {
|
|
805
|
+
const src = `"use generative";
|
|
806
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
807
|
+
const weatherTools = defineToolkit({
|
|
808
|
+
search: { execute: async () => 1, render: () => null },
|
|
809
|
+
});
|
|
810
|
+
const calendarTools = defineToolkit({
|
|
811
|
+
search: { execute: async () => 1, render: () => null },
|
|
812
|
+
});
|
|
813
|
+
export default defineToolkit({
|
|
814
|
+
...weatherTools,
|
|
815
|
+
...calendarTools,
|
|
816
|
+
});`;
|
|
817
|
+
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
818
|
+
|
|
819
|
+
try {
|
|
820
|
+
compileGenerative(src, { target: "server" });
|
|
821
|
+
compileGenerative(src, { target: "client" });
|
|
822
|
+
|
|
823
|
+
expect(warn).toHaveBeenCalledTimes(1);
|
|
824
|
+
expect(warn).toHaveBeenCalledWith(
|
|
825
|
+
expect.stringContaining(
|
|
826
|
+
'Duplicate tool name "search" while composing toolkits. ' +
|
|
827
|
+
"JavaScript object spread keeps the last definition.",
|
|
828
|
+
),
|
|
829
|
+
);
|
|
830
|
+
} finally {
|
|
831
|
+
warn.mockRestore();
|
|
832
|
+
}
|
|
833
|
+
});
|
|
834
|
+
|
|
835
|
+
it("warns about duplicate names through nested local toolkit spreads", () => {
|
|
836
|
+
const src = `"use generative";
|
|
837
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
838
|
+
const baseTools = defineToolkit({
|
|
839
|
+
search: { execute: async () => 1, render: () => null },
|
|
840
|
+
});
|
|
841
|
+
const weatherTools = defineToolkit({
|
|
842
|
+
...baseTools,
|
|
843
|
+
get_weather: { execute: async () => 1, render: () => null },
|
|
844
|
+
});
|
|
845
|
+
const calendarTools = defineToolkit({
|
|
846
|
+
search: { execute: async () => 1, render: () => null },
|
|
847
|
+
});
|
|
848
|
+
export default defineToolkit({
|
|
849
|
+
...weatherTools,
|
|
850
|
+
...calendarTools,
|
|
851
|
+
});`;
|
|
852
|
+
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
853
|
+
|
|
854
|
+
try {
|
|
855
|
+
compileGenerative(src, { target: "client" });
|
|
856
|
+
|
|
857
|
+
expect(warn).toHaveBeenCalledWith(
|
|
858
|
+
expect.stringContaining(
|
|
859
|
+
'Duplicate tool name "search" while composing toolkits. ' +
|
|
860
|
+
"JavaScript object spread keeps the last definition.",
|
|
861
|
+
),
|
|
862
|
+
);
|
|
863
|
+
} finally {
|
|
864
|
+
warn.mockRestore();
|
|
865
|
+
}
|
|
866
|
+
});
|
|
867
|
+
|
|
868
|
+
it("does not warn again when spreading a fragment with an internal duplicate", () => {
|
|
869
|
+
const src = `"use generative";
|
|
870
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
871
|
+
const baseTools = defineToolkit({
|
|
872
|
+
search: { execute: async () => 1, render: () => null },
|
|
873
|
+
search: { execute: async () => 2, render: () => null },
|
|
874
|
+
});
|
|
875
|
+
export default defineToolkit({
|
|
876
|
+
...baseTools,
|
|
877
|
+
});`;
|
|
878
|
+
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
879
|
+
|
|
880
|
+
try {
|
|
881
|
+
compileGenerative(src, { target: "client" });
|
|
882
|
+
|
|
883
|
+
expect(warn).toHaveBeenCalledTimes(1);
|
|
884
|
+
expect(warn).toHaveBeenCalledWith(
|
|
885
|
+
expect.stringContaining(
|
|
886
|
+
'Duplicate tool name "search" while composing toolkits. ' +
|
|
887
|
+
"JavaScript object spread keeps the last definition.",
|
|
888
|
+
),
|
|
889
|
+
);
|
|
890
|
+
} finally {
|
|
891
|
+
warn.mockRestore();
|
|
892
|
+
}
|
|
893
|
+
});
|
|
894
|
+
|
|
562
895
|
it("rejects spreading the default import of a non-generative module", () => {
|
|
563
896
|
const filename = createMergeFixture(
|
|
564
897
|
`export default { get_weather: { execute: async () => 1 } };\n`,
|
|
@@ -1068,17 +1401,34 @@ export default defineToolkit({
|
|
|
1068
1401
|
import { defineToolkit, providerTool } from "@assistant-ui/react";
|
|
1069
1402
|
export default defineToolkit({
|
|
1070
1403
|
web_search: {
|
|
1071
|
-
|
|
1404
|
+
providerId: "openai.web_search_preview",
|
|
1072
1405
|
execute: providerTool({
|
|
1073
1406
|
providerId: "openai.web_search_preview",
|
|
1074
1407
|
args: {},
|
|
1075
|
-
render: "duplicate",
|
|
1076
1408
|
}),
|
|
1077
1409
|
},
|
|
1078
1410
|
});`;
|
|
1079
1411
|
|
|
1080
1412
|
expect(() => compileGenerative(src, { target: "server" })).toThrow(
|
|
1081
|
-
|
|
1413
|
+
/`providerTool\(\.\.\.\)` config for "web_search" duplicates "providerId"/,
|
|
1414
|
+
);
|
|
1415
|
+
});
|
|
1416
|
+
|
|
1417
|
+
it("rejects duplicate providerTool config properties with the duplicated key", () => {
|
|
1418
|
+
const src = `"use generative";
|
|
1419
|
+
import { defineToolkit, providerTool } from "@assistant-ui/react";
|
|
1420
|
+
export default defineToolkit({
|
|
1421
|
+
web_search: {
|
|
1422
|
+
execute: providerTool({
|
|
1423
|
+
providerId: "openai.web_search_preview",
|
|
1424
|
+
providerId: "openai.web_search_preview_2",
|
|
1425
|
+
args: {},
|
|
1426
|
+
}),
|
|
1427
|
+
},
|
|
1428
|
+
});`;
|
|
1429
|
+
|
|
1430
|
+
expect(() => compileGenerative(src, { target: "server" })).toThrow(
|
|
1431
|
+
/`providerTool\(\.\.\.\)` config for "web_search" duplicates "providerId"/,
|
|
1082
1432
|
);
|
|
1083
1433
|
});
|
|
1084
1434
|
|
|
@@ -1097,6 +1447,42 @@ export default defineToolkit({
|
|
|
1097
1447
|
true,
|
|
1098
1448
|
);
|
|
1099
1449
|
expect(isGenerativeModule(`// a comment\n"use generative";\n`)).toBe(true);
|
|
1450
|
+
expect(isGenerativeModule(`"use generative"\nexport default {};`)).toBe(
|
|
1451
|
+
true,
|
|
1452
|
+
);
|
|
1453
|
+
expect(
|
|
1454
|
+
isGenerativeModule(`"use generative" // comment\nexport default {};`),
|
|
1455
|
+
).toBe(true);
|
|
1456
|
+
expect(
|
|
1457
|
+
isGenerativeModule(`"use generative" /* comment */;\nexport default {};`),
|
|
1458
|
+
).toBe(true);
|
|
1100
1459
|
expect(isGenerativeModule(`export default {};`)).toBe(false);
|
|
1460
|
+
expect(
|
|
1461
|
+
isGenerativeModule(`"use generative" + suffix;\nexport default {};`),
|
|
1462
|
+
).toBe(false);
|
|
1463
|
+
expect(
|
|
1464
|
+
isGenerativeModule(`"use generative"\n+ suffix;\nexport default {};`),
|
|
1465
|
+
).toBe(false);
|
|
1466
|
+
expect(
|
|
1467
|
+
isGenerativeModule(`"use generative".toString();\nexport default {};`),
|
|
1468
|
+
).toBe(false);
|
|
1469
|
+
expect(
|
|
1470
|
+
isGenerativeModule(`"use generative"\n.toString();\nexport default {};`),
|
|
1471
|
+
).toBe(false);
|
|
1472
|
+
expect(
|
|
1473
|
+
isGenerativeModule(
|
|
1474
|
+
`"use generative" // comment\n+ suffix;\nexport default {};`,
|
|
1475
|
+
),
|
|
1476
|
+
).toBe(false);
|
|
1477
|
+
expect(
|
|
1478
|
+
isGenerativeModule(
|
|
1479
|
+
`"use generative" /* no line break */ + suffix;\nexport default {};`,
|
|
1480
|
+
),
|
|
1481
|
+
).toBe(false);
|
|
1482
|
+
expect(
|
|
1483
|
+
isGenerativeModule(
|
|
1484
|
+
`"use generative" /* first line\nsecond line */ + suffix;\nexport default {};`,
|
|
1485
|
+
),
|
|
1486
|
+
).toBe(false);
|
|
1101
1487
|
});
|
|
1102
1488
|
});
|