@assistant-ui/x-generative-compiler 0.0.5 → 0.0.8

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.
@@ -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
@@ -345,6 +358,21 @@ export default defineToolkit({
345
358
  expect(code).not.toContain("defineGenerativeComponents");
346
359
  });
347
360
 
361
+ it("allows an exported module-scope JSONGenerativeUI instance", () => {
362
+ const src = `"use generative";
363
+ import { defineToolkit } from "@assistant-ui/react";
364
+ import { JSONGenerativeUI } from "@assistant-ui/react-generative-ui";
365
+ export const ui = new JSONGenerativeUI({ library: {} });
366
+ export default defineToolkit({ present: ui.present() });`;
367
+
368
+ expect(compileGenerative(src, { target: "server" }).code).toContain(
369
+ "ui.present()",
370
+ );
371
+ expect(compileGenerative(src, { target: "client" }).code).toContain(
372
+ "ui.present()",
373
+ );
374
+ });
375
+
348
376
  it("rejects an unknown method on a JSONGenerativeUI instance", () => {
349
377
  const src = `"use generative";
350
378
  import { defineToolkit } from "@assistant-ui/react";
@@ -356,6 +384,37 @@ export default defineToolkit({ present: ui.notARealMethod() });`;
356
384
  );
357
385
  });
358
386
 
387
+ it("allows an aliased JSONGenerativeUI import", () => {
388
+ const src = `"use generative";
389
+ import { defineToolkit } from "@assistant-ui/react";
390
+ import { JSONGenerativeUI as GenUI } from "@assistant-ui/react-generative-ui";
391
+ const ui = new GenUI({ library: {} });
392
+ export default defineToolkit({ present: ui.present() });`;
393
+
394
+ expect(compileGenerative(src, { target: "server" }).code).toContain(
395
+ "ui.present()",
396
+ );
397
+ expect(compileGenerative(src, { target: "client" }).code).toContain(
398
+ "ui.present()",
399
+ );
400
+ });
401
+
402
+ it("does not trust a local class named JSONGenerativeUI", () => {
403
+ const src = `"use generative";
404
+ import { defineToolkit } from "@assistant-ui/react";
405
+ class JSONGenerativeUI {
406
+ present() {
407
+ return makeTool();
408
+ }
409
+ }
410
+ const ui = new JSONGenerativeUI();
411
+ export default defineToolkit({ present: ui.present() });`;
412
+
413
+ expect(() => compileGenerative(src, { target: "server" })).toThrow(
414
+ /tool "present" cannot be `ui\.present\(\)`/,
415
+ );
416
+ });
417
+
359
418
  it("rejects a method call on an unknown (non-JSONGenerativeUI) object", () => {
360
419
  const src = `"use generative";
361
420
  import { defineToolkit } from "@assistant-ui/react";
@@ -407,6 +466,41 @@ export default defineToolkit({
407
466
  expect(client.trimStart().startsWith('"use client"')).toBe(true);
408
467
  });
409
468
 
469
+ it("splits an unstable_interactableTool entry: client keeps render, server drops it", () => {
470
+ const src = `"use generative";
471
+ import { z } from "zod";
472
+ import { Notepad } from "@/ui/notepad";
473
+ import { defineToolkit, unstable_interactableTool } from "@assistant-ui/react";
474
+ export default defineToolkit({
475
+ notepad: unstable_interactableTool({
476
+ description: "A notepad.",
477
+ stateSchema: z.object({ content: z.string() }),
478
+ render: (props) => <Notepad {...props} />,
479
+ }),
480
+ });`;
481
+ const server = compileGenerative(src, { target: "server" }).code;
482
+ expect(server).toContain("unstable_interactableTool({");
483
+ expect(server).toContain('description: "A notepad."');
484
+ expect(server).toContain("z.object");
485
+ expect(server).not.toMatch(/render\s*:/);
486
+ expect(server).not.toContain("@/ui/notepad");
487
+ expect(server).not.toContain("server-only");
488
+ const client = compileGenerative(src, { target: "client" }).code;
489
+ expect(client.trimStart().startsWith('"use client"')).toBe(true);
490
+ expect(client).toContain("<Notepad");
491
+ expect(client).toContain('import { Notepad } from "@/ui/notepad"');
492
+ });
493
+
494
+ it("rejects unstable_interactableTool not imported from an assistant-ui package", () => {
495
+ const src = `"use generative";
496
+ import { defineToolkit } from "@assistant-ui/react";
497
+ import { unstable_interactableTool } from "@/my-tools";
498
+ export default defineToolkit({ notepad: unstable_interactableTool({ render: () => null }) });`;
499
+ expect(() => compileGenerative(src, { target: "server" })).toThrow(
500
+ /inline object literal/,
501
+ );
502
+ });
503
+
410
504
  it("routes provider tool config", () => {
411
505
  const src = `"use generative";
412
506
  import { defineToolkit, providerTool } from "@assistant-ui/react";
@@ -559,6 +653,291 @@ export default defineToolkit({
559
653
  expect(client).toContain('from "./tools/weather"');
560
654
  });
561
655
 
656
+ it("allows unique tool names across more than two imported generative spreads", () => {
657
+ const filename = createMultiMergeFixture({
658
+ "tools/weather.tsx": `"use generative";
659
+ import { defineToolkit } from "@assistant-ui/react";
660
+ export default defineToolkit({
661
+ get_weather: { execute: async () => 1, render: () => null },
662
+ });`,
663
+ "tools/database.tsx": `"use generative";
664
+ import { defineToolkit } from "@assistant-ui/react";
665
+ export default defineToolkit({
666
+ query_db: { execute: async () => 1, render: () => null },
667
+ });`,
668
+ "tools/calendar.tsx": `"use generative";
669
+ import { defineToolkit } from "@assistant-ui/react";
670
+ export default defineToolkit({
671
+ create_event: { execute: async () => 1, render: () => null },
672
+ });`,
673
+ "tools/email.tsx": `"use generative";
674
+ import { defineToolkit } from "@assistant-ui/react";
675
+ export default defineToolkit({
676
+ send_email: { execute: async () => 1, render: () => null },
677
+ });`,
678
+ });
679
+ const src = `"use generative";
680
+ import { defineToolkit } from "@assistant-ui/react";
681
+ import weatherTools from "./tools/weather";
682
+ import databaseTools from "./tools/database";
683
+ import calendarTools from "./tools/calendar";
684
+ import emailTools from "./tools/email";
685
+ export default defineToolkit({
686
+ ...weatherTools,
687
+ ...databaseTools,
688
+ ...calendarTools,
689
+ ...emailTools,
690
+ });`;
691
+
692
+ const client = compileGenerative(src, { target: "client", filename }).code;
693
+ expect(client).toContain("...weatherTools");
694
+ expect(client).toContain("...databaseTools");
695
+ expect(client).toContain("...calendarTools");
696
+ expect(client).toContain("...emailTools");
697
+ });
698
+
699
+ it("warns about duplicate tool names across more than two imported generative spreads", () => {
700
+ const filename = createMultiMergeFixture({
701
+ "tools/weather.tsx": `"use generative";
702
+ import { defineToolkit } from "@assistant-ui/react";
703
+ export default defineToolkit({
704
+ get_weather: { execute: async () => 1, render: () => null },
705
+ search: { execute: async () => 1, render: () => null },
706
+ });`,
707
+ "tools/database.tsx": `"use generative";
708
+ import { defineToolkit } from "@assistant-ui/react";
709
+ export default defineToolkit({
710
+ query_db: { execute: async () => 1, render: () => null },
711
+ });`,
712
+ "tools/calendar.tsx": `"use generative";
713
+ import { defineToolkit } from "@assistant-ui/react";
714
+ export default defineToolkit({
715
+ search: { execute: async () => 1, render: () => null },
716
+ });`,
717
+ "tools/email.tsx": `"use generative";
718
+ import { defineToolkit } from "@assistant-ui/react";
719
+ export default defineToolkit({
720
+ send_email: { execute: async () => 1, render: () => null },
721
+ });`,
722
+ });
723
+ const src = `"use generative";
724
+ import { defineToolkit } from "@assistant-ui/react";
725
+ import weatherTools from "./tools/weather";
726
+ import databaseTools from "./tools/database";
727
+ import calendarTools from "./tools/calendar";
728
+ import emailTools from "./tools/email";
729
+ export default defineToolkit({
730
+ ...weatherTools,
731
+ ...databaseTools,
732
+ ...calendarTools,
733
+ ...emailTools,
734
+ });`;
735
+ const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
736
+
737
+ try {
738
+ const client = compileGenerative(src, {
739
+ target: "client",
740
+ filename,
741
+ }).code;
742
+
743
+ expect(client).toContain("...weatherTools");
744
+ expect(client).toContain("...databaseTools");
745
+ expect(client).toContain("...calendarTools");
746
+ expect(client).toContain("...emailTools");
747
+ expect(warn).toHaveBeenCalledWith(
748
+ expect.stringContaining("[assistant-ui/use-generative]"),
749
+ );
750
+ expect(warn).toHaveBeenCalledWith(
751
+ expect.stringContaining(
752
+ 'Duplicate tool name "search" while composing toolkits. ' +
753
+ "JavaScript object spread keeps the last definition.",
754
+ ),
755
+ );
756
+ } finally {
757
+ warn.mockRestore();
758
+ }
759
+ });
760
+
761
+ it("does not reuse imported toolkit names across compile calls", () => {
762
+ const filename = createMultiMergeFixture({
763
+ "tools/weather.tsx": `"use generative";
764
+ import { defineToolkit } from "@assistant-ui/react";
765
+ export default defineToolkit({
766
+ get_weather: { execute: async () => 1, render: () => null },
767
+ });`,
768
+ "tools/calendar.tsx": `"use generative";
769
+ import { defineToolkit } from "@assistant-ui/react";
770
+ export default defineToolkit({
771
+ search: { execute: async () => 1, render: () => null },
772
+ });`,
773
+ });
774
+ const src = `"use generative";
775
+ import { defineToolkit } from "@assistant-ui/react";
776
+ import weatherTools from "./tools/weather";
777
+ import calendarTools from "./tools/calendar";
778
+ export default defineToolkit({
779
+ ...weatherTools,
780
+ ...calendarTools,
781
+ });`;
782
+
783
+ compileGenerative(src, { target: "client", filename });
784
+ writeFileSync(
785
+ nodePath.join(nodePath.dirname(filename), "tools", "weather.tsx"),
786
+ `"use generative";
787
+ import { defineToolkit } from "@assistant-ui/react";
788
+ export default defineToolkit({
789
+ search: { execute: async () => 1, render: () => null },
790
+ });`,
791
+ );
792
+ const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
793
+
794
+ try {
795
+ compileGenerative(src, { target: "client", filename });
796
+
797
+ expect(warn).toHaveBeenCalledWith(
798
+ expect.stringContaining(
799
+ 'Duplicate tool name "search" while composing toolkits. ' +
800
+ "JavaScript object spread keeps the last definition.",
801
+ ),
802
+ );
803
+ } finally {
804
+ warn.mockRestore();
805
+ }
806
+ });
807
+
808
+ it("warns about duplicate tool names between local toolkit spreads", () => {
809
+ const src = `"use generative";
810
+ import { defineToolkit } from "@assistant-ui/react";
811
+ const weatherTools = defineToolkit({
812
+ get_weather: { execute: async () => 1, render: () => null },
813
+ search: { execute: async () => 1, render: () => null },
814
+ });
815
+ const databaseTools = defineToolkit({
816
+ query_db: { execute: async () => 1, render: () => null },
817
+ });
818
+ const calendarTools = defineToolkit({
819
+ search: { execute: async () => 1, render: () => null },
820
+ });
821
+ const emailTools = defineToolkit({
822
+ send_email: { execute: async () => 1, render: () => null },
823
+ });
824
+ export default defineToolkit({
825
+ ...weatherTools,
826
+ ...databaseTools,
827
+ ...calendarTools,
828
+ ...emailTools,
829
+ });`;
830
+ const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
831
+
832
+ try {
833
+ const client = compileGenerative(src, { target: "client" }).code;
834
+
835
+ expect(client).toContain("...weatherTools");
836
+ expect(client).toContain("...databaseTools");
837
+ expect(client).toContain("...calendarTools");
838
+ expect(client).toContain("...emailTools");
839
+ expect(warn).toHaveBeenCalledWith(
840
+ expect.stringContaining(
841
+ '[assistant-ui/use-generative] Duplicate tool name "search" while composing toolkits. ' +
842
+ "JavaScript object spread keeps the last definition.",
843
+ ),
844
+ );
845
+ } finally {
846
+ warn.mockRestore();
847
+ }
848
+ });
849
+
850
+ it("warns once across server and client compiles", () => {
851
+ const src = `"use generative";
852
+ import { defineToolkit } from "@assistant-ui/react";
853
+ const weatherTools = defineToolkit({
854
+ search: { execute: async () => 1, render: () => null },
855
+ });
856
+ const calendarTools = defineToolkit({
857
+ search: { execute: async () => 1, render: () => null },
858
+ });
859
+ export default defineToolkit({
860
+ ...weatherTools,
861
+ ...calendarTools,
862
+ });`;
863
+ const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
864
+
865
+ try {
866
+ compileGenerative(src, { target: "server" });
867
+ compileGenerative(src, { target: "client" });
868
+
869
+ expect(warn).toHaveBeenCalledTimes(1);
870
+ expect(warn).toHaveBeenCalledWith(
871
+ expect.stringContaining(
872
+ 'Duplicate tool name "search" while composing toolkits. ' +
873
+ "JavaScript object spread keeps the last definition.",
874
+ ),
875
+ );
876
+ } finally {
877
+ warn.mockRestore();
878
+ }
879
+ });
880
+
881
+ it("warns about duplicate names through nested local toolkit spreads", () => {
882
+ const src = `"use generative";
883
+ import { defineToolkit } from "@assistant-ui/react";
884
+ const baseTools = defineToolkit({
885
+ search: { execute: async () => 1, render: () => null },
886
+ });
887
+ const weatherTools = defineToolkit({
888
+ ...baseTools,
889
+ get_weather: { execute: async () => 1, render: () => null },
890
+ });
891
+ const calendarTools = defineToolkit({
892
+ search: { execute: async () => 1, render: () => null },
893
+ });
894
+ export default defineToolkit({
895
+ ...weatherTools,
896
+ ...calendarTools,
897
+ });`;
898
+ const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
899
+
900
+ try {
901
+ compileGenerative(src, { target: "client" });
902
+
903
+ expect(warn).toHaveBeenCalledWith(
904
+ expect.stringContaining(
905
+ 'Duplicate tool name "search" while composing toolkits. ' +
906
+ "JavaScript object spread keeps the last definition.",
907
+ ),
908
+ );
909
+ } finally {
910
+ warn.mockRestore();
911
+ }
912
+ });
913
+
914
+ it("does not warn again when spreading a fragment with an internal duplicate", () => {
915
+ const src = `"use generative";
916
+ import { defineToolkit } from "@assistant-ui/react";
917
+ const baseTools = defineToolkit({
918
+ search: { execute: async () => 1, render: () => null },
919
+ search: { execute: async () => 2, render: () => null },
920
+ });
921
+ export default defineToolkit({
922
+ ...baseTools,
923
+ });`;
924
+ const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
925
+
926
+ try {
927
+ compileGenerative(src, { target: "client" });
928
+
929
+ expect(warn).toHaveBeenCalledTimes(1);
930
+ expect(warn).toHaveBeenCalledWith(
931
+ expect.stringContaining(
932
+ 'Duplicate tool name "search" while composing toolkits. ' +
933
+ "JavaScript object spread keeps the last definition.",
934
+ ),
935
+ );
936
+ } finally {
937
+ warn.mockRestore();
938
+ }
939
+ });
940
+
562
941
  it("rejects spreading the default import of a non-generative module", () => {
563
942
  const filename = createMergeFixture(
564
943
  `export default { get_weather: { execute: async () => 1 } };\n`,
@@ -830,7 +1209,16 @@ export default defineToolkit({
830
1209
  `"use generative";\nimport { defineToolkit, externalTool } from "@assistant-ui/react";\nexport default defineToolkit({ search: { execute: externalTool() } });`,
831
1210
  { target: "client" },
832
1211
  ),
833
- ).toThrow(/external tool must declare a `render` or `renderText`/);
1212
+ ).toThrow(/external tool "search" must declare a `render` or `renderText`/);
1213
+ });
1214
+
1215
+ it("falls back to an unnamed external tool diagnostic for computed keys", () => {
1216
+ expect(() =>
1217
+ compileGenerative(
1218
+ `"use generative";\nimport { defineToolkit, externalTool } from "@assistant-ui/react";\nconst search = "search";\nexport default defineToolkit({ [search]: { execute: externalTool() } });`,
1219
+ { target: "client" },
1220
+ ),
1221
+ ).toThrow(/an external tool must declare a `render` or `renderText`/);
834
1222
  });
835
1223
  });
836
1224
 
@@ -956,7 +1344,7 @@ export default { weather: { execute: async () => 1, render: () => null } };`;
956
1344
  `"use generative";\nimport { defineToolkit } from "@assistant-ui/react";\nexport default defineToolkit({ weather: makeTool() });`,
957
1345
  { target: "server" },
958
1346
  ),
959
- ).toThrow(/inline object literal/);
1347
+ ).toThrow(/tool "weather" cannot be `makeTool\(\)`/);
960
1348
  });
961
1349
 
962
1350
  it("requires a render for human tools", () => {
@@ -965,7 +1353,16 @@ export default { weather: { execute: async () => 1, render: () => null } };`;
965
1353
  `"use generative";\nimport { defineToolkit, humanTool } from "@assistant-ui/react";\nexport default defineToolkit({ ask: { execute: humanTool() } });`,
966
1354
  { target: "client" },
967
1355
  ),
968
- ).toThrow(/must declare a `render`/);
1356
+ ).toThrow(/human tool "ask" must declare a `render`/);
1357
+ });
1358
+
1359
+ it("falls back to an unnamed human tool diagnostic for computed keys", () => {
1360
+ expect(() =>
1361
+ compileGenerative(
1362
+ `"use generative";\nimport { defineToolkit, humanTool } from "@assistant-ui/react";\nconst ask = "ask";\nexport default defineToolkit({ [ask]: { execute: humanTool() } });`,
1363
+ { target: "client" },
1364
+ ),
1365
+ ).toThrow(/a human tool must declare a `render`/);
969
1366
  });
970
1367
 
971
1368
  it("requires a render or renderText for frontend tools", () => {
@@ -974,7 +1371,16 @@ export default { weather: { execute: async () => 1, render: () => null } };`;
974
1371
  `"use generative";\nimport { defineToolkit } from "@assistant-ui/react";\nexport default defineToolkit({ toast: { execute: async () => { "use client"; return 1; } } });`,
975
1372
  { target: "client" },
976
1373
  ),
977
- ).toThrow(/must declare a `render` or `renderText`/);
1374
+ ).toThrow(/frontend tool "toast" must declare a `render` or `renderText`/);
1375
+ });
1376
+
1377
+ it("falls back to an unnamed frontend tool diagnostic for computed keys", () => {
1378
+ expect(() =>
1379
+ compileGenerative(
1380
+ `"use generative";\nimport { defineToolkit } from "@assistant-ui/react";\nconst toast = "toast";\nexport default defineToolkit({ [toast]: { execute: async () => { "use client"; return 1; } } });`,
1381
+ { target: "client" },
1382
+ ),
1383
+ ).toThrow(/a frontend tool must declare a `render` or `renderText`/);
978
1384
  });
979
1385
 
980
1386
  it("requires every tool to declare an execute", () => {
@@ -983,7 +1389,16 @@ export default { weather: { execute: async () => 1, render: () => null } };`;
983
1389
  `"use generative";\nimport { defineToolkit } from "@assistant-ui/react";\nexport default defineToolkit({ ask: { render: () => null } });`,
984
1390
  { target: "client" },
985
1391
  ),
986
- ).toThrow(/must declare an `execute`/);
1392
+ ).toThrow(/tool "ask" must declare an `execute`/);
1393
+ });
1394
+
1395
+ it("falls back to an unnamed execute diagnostic for computed keys", () => {
1396
+ expect(() =>
1397
+ compileGenerative(
1398
+ `"use generative";\nimport { defineToolkit } from "@assistant-ui/react";\nconst ask = "ask";\nexport default defineToolkit({ [ask]: { render: () => null } });`,
1399
+ { target: "client" },
1400
+ ),
1401
+ ).toThrow(/every tool must declare an `execute`/);
987
1402
  });
988
1403
 
989
1404
  it("infers `human` from execute: humanTool() and drops it on both builds", () => {
@@ -1068,17 +1483,34 @@ export default defineToolkit({
1068
1483
  import { defineToolkit, providerTool } from "@assistant-ui/react";
1069
1484
  export default defineToolkit({
1070
1485
  web_search: {
1071
- render: () => null,
1486
+ providerId: "openai.web_search_preview",
1487
+ execute: providerTool({
1488
+ providerId: "openai.web_search_preview",
1489
+ args: {},
1490
+ }),
1491
+ },
1492
+ });`;
1493
+
1494
+ expect(() => compileGenerative(src, { target: "server" })).toThrow(
1495
+ /`providerTool\(\.\.\.\)` config for "web_search" duplicates "providerId"/,
1496
+ );
1497
+ });
1498
+
1499
+ it("rejects duplicate providerTool config properties with the duplicated key", () => {
1500
+ const src = `"use generative";
1501
+ import { defineToolkit, providerTool } from "@assistant-ui/react";
1502
+ export default defineToolkit({
1503
+ web_search: {
1072
1504
  execute: providerTool({
1073
1505
  providerId: "openai.web_search_preview",
1506
+ providerId: "openai.web_search_preview_2",
1074
1507
  args: {},
1075
- render: "duplicate",
1076
1508
  }),
1077
1509
  },
1078
1510
  });`;
1079
1511
 
1080
1512
  expect(() => compileGenerative(src, { target: "server" })).toThrow(
1081
- /cannot duplicate tool properties/,
1513
+ /`providerTool\(\.\.\.\)` config for "web_search" duplicates "providerId"/,
1082
1514
  );
1083
1515
  });
1084
1516
 
@@ -1097,6 +1529,42 @@ export default defineToolkit({
1097
1529
  true,
1098
1530
  );
1099
1531
  expect(isGenerativeModule(`// a comment\n"use generative";\n`)).toBe(true);
1532
+ expect(isGenerativeModule(`"use generative"\nexport default {};`)).toBe(
1533
+ true,
1534
+ );
1535
+ expect(
1536
+ isGenerativeModule(`"use generative" // comment\nexport default {};`),
1537
+ ).toBe(true);
1538
+ expect(
1539
+ isGenerativeModule(`"use generative" /* comment */;\nexport default {};`),
1540
+ ).toBe(true);
1100
1541
  expect(isGenerativeModule(`export default {};`)).toBe(false);
1542
+ expect(
1543
+ isGenerativeModule(`"use generative" + suffix;\nexport default {};`),
1544
+ ).toBe(false);
1545
+ expect(
1546
+ isGenerativeModule(`"use generative"\n+ suffix;\nexport default {};`),
1547
+ ).toBe(false);
1548
+ expect(
1549
+ isGenerativeModule(`"use generative".toString();\nexport default {};`),
1550
+ ).toBe(false);
1551
+ expect(
1552
+ isGenerativeModule(`"use generative"\n.toString();\nexport default {};`),
1553
+ ).toBe(false);
1554
+ expect(
1555
+ isGenerativeModule(
1556
+ `"use generative" // comment\n+ suffix;\nexport default {};`,
1557
+ ),
1558
+ ).toBe(false);
1559
+ expect(
1560
+ isGenerativeModule(
1561
+ `"use generative" /* no line break */ + suffix;\nexport default {};`,
1562
+ ),
1563
+ ).toBe(false);
1564
+ expect(
1565
+ isGenerativeModule(
1566
+ `"use generative" /* first line\nsecond line */ + suffix;\nexport default {};`,
1567
+ ),
1568
+ ).toBe(false);
1101
1569
  });
1102
1570
  });