@databrainhq/mcp-server 0.3.0-rc.13 → 0.3.0-rc.15

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 (50) hide show
  1. package/.mcp.json +6 -1
  2. package/dist/apps/server.d.ts +102 -389
  3. package/dist/apps/server.js +5 -5
  4. package/dist/apps/stdio.d.ts +1 -2
  5. package/dist/apps/stdio.js +6 -6
  6. package/dist/{bundle-TDQXWIPM.js → bundle-QJNCUMNY.js} +2 -2
  7. package/dist/{chunk-Q5EYDKSA.js → chunk-2F7V6RZR.js} +511 -107
  8. package/dist/chunk-2F7V6RZR.js.map +1 -0
  9. package/dist/chunk-3AH56XX7.js +28 -0
  10. package/dist/chunk-3AH56XX7.js.map +1 -0
  11. package/dist/{chunk-AEQTEE5C.js → chunk-4E57ZRZO.js} +302 -63
  12. package/dist/chunk-4E57ZRZO.js.map +1 -0
  13. package/dist/{chunk-PSJVYD4W.js → chunk-6MD7KOAU.js} +11723 -10560
  14. package/dist/chunk-6MD7KOAU.js.map +1 -0
  15. package/dist/{chunk-HCYZN7I3.js → chunk-FJLRZJ4A.js} +10 -7
  16. package/dist/chunk-FJLRZJ4A.js.map +1 -0
  17. package/dist/{chunk-X44C5GW2.js → chunk-MUZ3KEJX.js} +63 -40
  18. package/dist/chunk-MUZ3KEJX.js.map +1 -0
  19. package/dist/{chunk-DTFYHLYN.js → chunk-NXE2A4WV.js} +26 -11
  20. package/dist/chunk-NXE2A4WV.js.map +1 -0
  21. package/dist/{chunk-233VGFHY.js → chunk-QQ6KNULX.js} +317 -147
  22. package/dist/chunk-QQ6KNULX.js.map +1 -0
  23. package/dist/chunk-V5JINLOA.js +506 -0
  24. package/dist/chunk-V5JINLOA.js.map +1 -0
  25. package/dist/cli.d.ts +16 -15
  26. package/dist/cli.js +134 -36
  27. package/dist/cli.js.map +1 -1
  28. package/dist/custom-chart/custom-runtime.js +6 -6
  29. package/dist/custom-chart/template/chart.ts +116 -28
  30. package/dist/custom-chart/template/icon.svg +1 -1
  31. package/dist/custom-chart/template/manifest.json +66 -12
  32. package/dist/custom-chart/template/sample-data.json +21 -3
  33. package/dist/index.d.ts +1 -2
  34. package/dist/index.js +67 -13
  35. package/dist/index.js.map +1 -1
  36. package/dist/{main-VEKNKWL5.js → main-2FKQQLWX.js} +489 -174
  37. package/dist/main-2FKQQLWX.js.map +1 -0
  38. package/dist/{test-only-LJGOY2QA.js → test-only-VH3FF5ML.js} +15 -9
  39. package/dist/test-only-VH3FF5ML.js.map +1 -0
  40. package/package.json +20 -9
  41. package/dist/chunk-233VGFHY.js.map +0 -1
  42. package/dist/chunk-AEQTEE5C.js.map +0 -1
  43. package/dist/chunk-DTFYHLYN.js.map +0 -1
  44. package/dist/chunk-HCYZN7I3.js.map +0 -1
  45. package/dist/chunk-PSJVYD4W.js.map +0 -1
  46. package/dist/chunk-Q5EYDKSA.js.map +0 -1
  47. package/dist/chunk-X44C5GW2.js.map +0 -1
  48. package/dist/main-VEKNKWL5.js.map +0 -1
  49. package/dist/test-only-LJGOY2QA.js.map +0 -1
  50. /package/dist/{bundle-TDQXWIPM.js.map → bundle-QJNCUMNY.js.map} +0 -0
@@ -7,10 +7,10 @@ import { join as join2, resolve as resolve2, sep } from "path";
7
7
  import { build as esbuild } from "esbuild";
8
8
 
9
9
  // src/custom-chart/assets.ts
10
- import { buildSync } from "esbuild";
11
10
  import { existsSync, readdirSync, readFileSync, statSync } from "fs";
12
11
  import { dirname, join, resolve } from "path";
13
12
  import { fileURLToPath } from "url";
13
+ import { buildSync } from "esbuild";
14
14
  var cachedDir;
15
15
  function customChartAssetDir() {
16
16
  if (cachedDir) return cachedDir;
@@ -311,9 +311,10 @@ var cleanAttributes = (element, rawAttributes) => {
311
311
  let dropElement = false;
312
312
  const kept = [];
313
313
  ATTRIBUTE_RE.lastIndex = 0;
314
- let match;
315
- while ((match = ATTRIBUTE_RE.exec(rawAttributes)) !== null) {
314
+ let match = ATTRIBUTE_RE.exec(rawAttributes);
315
+ while (match !== null) {
316
316
  const [whole, name, dq, sq, bare] = match;
317
+ match = ATTRIBUTE_RE.exec(rawAttributes);
317
318
  if (!name || name === "/") continue;
318
319
  const lower = name.toLowerCase();
319
320
  const value = dq ?? sq ?? bare ?? "";
@@ -464,17 +465,47 @@ var MAX_OPTIONS = 32;
464
465
  // src/custom-chart/icon.ts
465
466
  var UNSAFE = "bundle.icon.unsafe";
466
467
  var RULES = [
467
- { pattern: /<\s*script\b/i, message: "Remove every <script> element from icon.svg." },
468
- { pattern: /<\s*foreignObject\b/i, message: "Remove every <foreignObject> element from icon.svg." },
469
- { pattern: /<\s*image\b/i, message: "Remove every <image> element from icon.svg. Draw with paths and shapes." },
470
- { pattern: /[\s/]on[a-z]+\s*=/i, message: "Remove every on*= event attribute from icon.svg." },
468
+ {
469
+ pattern: /<\s*script\b/i,
470
+ message: "Remove every <script> element from icon.svg."
471
+ },
472
+ {
473
+ pattern: /<\s*foreignObject\b/i,
474
+ message: "Remove every <foreignObject> element from icon.svg."
475
+ },
476
+ {
477
+ pattern: /<\s*image\b/i,
478
+ message: "Remove every <image> element from icon.svg. Draw with paths and shapes."
479
+ },
480
+ {
481
+ pattern: /[\s/]on[a-z]+\s*=/i,
482
+ message: "Remove every on*= event attribute from icon.svg."
483
+ },
471
484
  { pattern: /<!--/, message: "Remove every <!-- comment --> from icon.svg." },
472
- { pattern: /<!(?:ENTITY|DOCTYPE)\b/i, message: "Remove the DOCTYPE and entity declarations from icon.svg." },
473
- { pattern: /<!\[CDATA\[/, message: "Remove every CDATA section from icon.svg." },
474
- { pattern: /(?:xlink:)?href\s*=\s*["']\s*(?!#)/i, message: "Every href in icon.svg must start with # (no external or data references)." },
475
- { pattern: /javascript\s*:/i, message: "Remove every javascript: reference from icon.svg." },
476
- { pattern: /@import|expression\s*\(|-moz-binding/i, message: "Remove @import, expression() and -moz-binding from icon.svg styles." },
477
- { pattern: /url\s*\(\s*['"]?\s*(?!#)/i, message: "Every url() in icon.svg must point at a same-document #id." }
485
+ {
486
+ pattern: /<!(?:ENTITY|DOCTYPE)\b/i,
487
+ message: "Remove the DOCTYPE and entity declarations from icon.svg."
488
+ },
489
+ {
490
+ pattern: /<!\[CDATA\[/,
491
+ message: "Remove every CDATA section from icon.svg."
492
+ },
493
+ {
494
+ pattern: /(?:xlink:)?href\s*=\s*["']\s*(?!#)/i,
495
+ message: "Every href in icon.svg must start with # (no external or data references)."
496
+ },
497
+ {
498
+ pattern: /javascript\s*:/i,
499
+ message: "Remove every javascript: reference from icon.svg."
500
+ },
501
+ {
502
+ pattern: /@import|expression\s*\(|-moz-binding/i,
503
+ message: "Remove @import, expression() and -moz-binding from icon.svg styles."
504
+ },
505
+ {
506
+ pattern: /url\s*\(\s*['"]?\s*(?!#)/i,
507
+ message: "Every url() in icon.svg must point at a same-document #id."
508
+ }
478
509
  ];
479
510
  var GENERIC_UNSAFE = "icon.svg must use only plain SVG drawing elements and attributes: no script, event handlers, foreignObject, image, animation, external hrefs, url() styles, comments, DOCTYPE or unknown attributes.";
480
511
  var XML_DECLARATION = /^\s*<\?xml[^>]*\?>\s*/i;
@@ -484,18 +515,38 @@ function isSingleSvgRoot(svg) {
484
515
  }
485
516
  function validateIcon(svg, path = "/icon.svg") {
486
517
  if (typeof svg !== "string" || svg.trim().length === 0) {
487
- return [{ code: "bundle.icon.required", path, message: "icon.svg is required and must not be empty." }];
518
+ return [
519
+ {
520
+ code: "bundle.icon.required",
521
+ path,
522
+ message: "icon.svg is required and must not be empty."
523
+ }
524
+ ];
488
525
  }
489
526
  if (Buffer.byteLength(svg, "utf8") > MAX_ICON_BYTES) {
490
- return [{ code: "bundle.icon.size", path, message: `icon.svg must be at most ${MAX_ICON_BYTES} bytes.` }];
527
+ return [
528
+ {
529
+ code: "bundle.icon.size",
530
+ path,
531
+ message: `icon.svg must be at most ${MAX_ICON_BYTES} bytes.`
532
+ }
533
+ ];
491
534
  }
492
535
  const cleaned = sanitizeSvg(svg);
493
536
  if (!cleaned.isSvg || !isSingleSvgRoot(cleaned.svg)) {
494
- return [{ code: "bundle.icon.notSvg", path, message: "icon.svg must be one <svg> element with nothing after it." }];
537
+ return [
538
+ {
539
+ code: "bundle.icon.notSvg",
540
+ path,
541
+ message: "icon.svg must be one <svg> element with nothing after it."
542
+ }
543
+ ];
495
544
  }
496
545
  if (cleaned.removed > 0 || /<\s*image\b/i.test(svg)) {
497
546
  const rule = RULES.find((candidate) => candidate.pattern.test(svg));
498
- return [{ code: UNSAFE, path, message: rule ? rule.message : GENERIC_UNSAFE }];
547
+ return [
548
+ { code: UNSAFE, path, message: rule ? rule.message : GENERIC_UNSAFE }
549
+ ];
499
550
  }
500
551
  return [];
501
552
  }
@@ -559,13 +610,21 @@ var Collector = class {
559
610
  let ok = true;
560
611
  for (const key of Object.keys(value)) {
561
612
  if (!allowed.has(key)) {
562
- this.add(`${scope}.unknownKey`, `${path}/${key}`, `Remove "${key}". It is not a known key here.`);
613
+ this.add(
614
+ `${scope}.unknownKey`,
615
+ `${path}/${key}`,
616
+ `Remove "${key}". It is not a known key here.`
617
+ );
563
618
  ok = false;
564
619
  }
565
620
  }
566
621
  for (const key of required) {
567
622
  if (!Object.hasOwn(value, key)) {
568
- this.add(missingCode(key), `${path}/${key}`, `Add the required key "${key}".`);
623
+ this.add(
624
+ missingCode(key),
625
+ `${path}/${key}`,
626
+ `Add the required key "${key}".`
627
+ );
569
628
  ok = false;
570
629
  }
571
630
  }
@@ -577,29 +636,64 @@ function validateSlot(c, value, path, v2) {
577
636
  c.add("manifest.slot.invalid", path, "A slot must be an object.");
578
637
  return;
579
638
  }
580
- if (!c.checkKeys(value, path, "manifest.slot", V1_SLOT_KEYS, v2 ? V2_SLOT_EXTRA_KEYS : [])) return;
639
+ if (!c.checkKeys(
640
+ value,
641
+ path,
642
+ "manifest.slot",
643
+ V1_SLOT_KEYS,
644
+ v2 ? V2_SLOT_EXTRA_KEYS : []
645
+ ))
646
+ return;
581
647
  if (!isId(value.id)) {
582
- c.add("manifest.slot.id", `${path}/id`, "A slot id is lowercase, starts with a letter, and uses only a-z, 0-9, _ and -, up to 64 characters.");
648
+ c.add(
649
+ "manifest.slot.id",
650
+ `${path}/id`,
651
+ "A slot id is lowercase, starts with a letter, and uses only a-z, 0-9, _ and -, up to 64 characters."
652
+ );
583
653
  }
584
654
  if (!isText(value.label)) {
585
- c.add("manifest.slot.label", `${path}/label`, `A slot label is 1 to ${MAX_TEXT} characters.`);
655
+ c.add(
656
+ "manifest.slot.label",
657
+ `${path}/label`,
658
+ `A slot label is 1 to ${MAX_TEXT} characters.`
659
+ );
586
660
  }
587
661
  const role = value.role;
588
662
  if (role !== "dimension" && role !== "measure") {
589
- c.add("manifest.slot.role", `${path}/role`, 'A slot role is "dimension" or "measure".');
663
+ c.add(
664
+ "manifest.slot.role",
665
+ `${path}/role`,
666
+ 'A slot role is "dimension" or "measure".'
667
+ );
590
668
  }
591
669
  if (typeof value.required !== "boolean") {
592
- c.add("manifest.slot.required", `${path}/required`, "required is true or false.");
670
+ c.add(
671
+ "manifest.slot.required",
672
+ `${path}/required`,
673
+ "required is true or false."
674
+ );
593
675
  }
594
676
  const types = value.types;
595
677
  const typesOk = Array.isArray(types) && types.length > 0 && types.length <= 3 && new Set(types).size === types.length && types.every((type) => FIELD_TYPES.includes(type));
596
678
  if (!typesOk) {
597
- c.add("manifest.slot.types", `${path}/types`, 'types is a list of 1 to 3 distinct values from "string", "number" and "boolean".');
679
+ c.add(
680
+ "manifest.slot.types",
681
+ `${path}/types`,
682
+ 'types is a list of 1 to 3 distinct values from "string", "number" and "boolean".'
683
+ );
598
684
  } else if (role === "measure" && (types.length !== 1 || types[0] !== "number")) {
599
- c.add("manifest.slot.types", `${path}/types`, 'A measure slot accepts only ["number"].');
685
+ c.add(
686
+ "manifest.slot.types",
687
+ `${path}/types`,
688
+ 'A measure slot accepts only ["number"].'
689
+ );
600
690
  }
601
691
  if (Object.hasOwn(value, "description") && !isText(value.description)) {
602
- c.add("manifest.slot.description", `${path}/description`, `A slot description is 1 to ${MAX_TEXT} characters.`);
692
+ c.add(
693
+ "manifest.slot.description",
694
+ `${path}/description`,
695
+ `A slot description is 1 to ${MAX_TEXT} characters.`
696
+ );
603
697
  }
604
698
  }
605
699
  function validateOption(c, value, path, v2) {
@@ -609,7 +703,11 @@ function validateOption(c, value, path, v2) {
609
703
  }
610
704
  const id = value.id;
611
705
  if (typeof id === "string" && (id === "theme" || id.startsWith("theme."))) {
612
- c.add("manifest.option.reserved", `${path}/id`, 'The option id "theme" (and any id starting with "theme.") is reserved for the host theme.');
706
+ c.add(
707
+ "manifest.option.reserved",
708
+ `${path}/id`,
709
+ 'The option id "theme" (and any id starting with "theme.") is reserved for the host theme.'
710
+ );
613
711
  return;
614
712
  }
615
713
  const type = typeof value.type === "string" ? value.type : "";
@@ -622,46 +720,89 @@ function validateOption(c, value, path, v2) {
622
720
  );
623
721
  return;
624
722
  }
625
- if (!c.checkKeys(value, path, "manifest.option", [...OPTION_BASE_KEYS, ...typeKeys], v2 ? V2_OPTION_EXTRA_KEYS[type] : [])) return;
723
+ if (!c.checkKeys(
724
+ value,
725
+ path,
726
+ "manifest.option",
727
+ [...OPTION_BASE_KEYS, ...typeKeys],
728
+ v2 ? V2_OPTION_EXTRA_KEYS[type] : []
729
+ ))
730
+ return;
626
731
  if (!isId(id)) {
627
- c.add("manifest.option.id", `${path}/id`, "An option id is lowercase, starts with a letter, and uses only a-z, 0-9, _ and -, up to 64 characters.");
732
+ c.add(
733
+ "manifest.option.id",
734
+ `${path}/id`,
735
+ "An option id is lowercase, starts with a letter, and uses only a-z, 0-9, _ and -, up to 64 characters."
736
+ );
628
737
  }
629
738
  if (!isText(value.label)) {
630
- c.add("manifest.option.label", `${path}/label`, `An option label is 1 to ${MAX_TEXT} characters.`);
739
+ c.add(
740
+ "manifest.option.label",
741
+ `${path}/label`,
742
+ `An option label is 1 to ${MAX_TEXT} characters.`
743
+ );
631
744
  }
632
745
  if (Object.hasOwn(value, "group") && !isText(value.group, MAX_GROUP)) {
633
- c.add("manifest.option.group", `${path}/group`, `An option group is 1 to ${MAX_GROUP} characters.`);
746
+ c.add(
747
+ "manifest.option.group",
748
+ `${path}/group`,
749
+ `An option group is 1 to ${MAX_GROUP} characters.`
750
+ );
634
751
  }
635
752
  switch (type) {
636
753
  case "boolean":
637
754
  if (typeof value.default !== "boolean") {
638
- c.add("manifest.option.default", `${path}/default`, "A boolean default is true or false.");
755
+ c.add(
756
+ "manifest.option.default",
757
+ `${path}/default`,
758
+ "A boolean default is true or false."
759
+ );
639
760
  }
640
761
  break;
641
762
  case "number": {
642
763
  const rangeOk = isFiniteNumber(value.min) && isFiniteNumber(value.max) && value.min <= value.max;
643
764
  if (!rangeOk) {
644
- c.add("manifest.option.range", `${path}/min`, "Set finite min and max with min <= max.");
765
+ c.add(
766
+ "manifest.option.range",
767
+ `${path}/min`,
768
+ "Set finite min and max with min <= max."
769
+ );
645
770
  break;
646
771
  }
647
772
  const min = value.min;
648
773
  const max = value.max;
649
774
  if (!isFiniteNumber(value.default) || value.default < min || value.default > max) {
650
- c.add("manifest.option.default", `${path}/default`, "A number default is a finite number between min and max.");
775
+ c.add(
776
+ "manifest.option.default",
777
+ `${path}/default`,
778
+ "A number default is a finite number between min and max."
779
+ );
651
780
  }
652
781
  if (Object.hasOwn(value, "step") && (!isFiniteNumber(value.step) || value.step <= 0 || value.step > max - min)) {
653
- c.add("manifest.option.step", `${path}/step`, "step is a positive number no larger than max - min.");
782
+ c.add(
783
+ "manifest.option.step",
784
+ `${path}/step`,
785
+ "step is a positive number no larger than max - min."
786
+ );
654
787
  }
655
788
  break;
656
789
  }
657
790
  case "string": {
658
791
  const maxLength = value.maxLength;
659
792
  if (!isFiniteNumber(maxLength) || !Number.isInteger(maxLength) || maxLength < 1 || maxLength > MAX_STRING_OPTION_LENGTH) {
660
- c.add("manifest.option.maxLength", `${path}/maxLength`, `A string option needs an integer "maxLength" from 1 to ${MAX_STRING_OPTION_LENGTH}.`);
793
+ c.add(
794
+ "manifest.option.maxLength",
795
+ `${path}/maxLength`,
796
+ `A string option needs an integer "maxLength" from 1 to ${MAX_STRING_OPTION_LENGTH}.`
797
+ );
661
798
  break;
662
799
  }
663
800
  if (typeof value.default !== "string" || value.default.length > maxLength) {
664
- c.add("manifest.option.default", `${path}/default`, "A string default is a string no longer than maxLength.");
801
+ c.add(
802
+ "manifest.option.default",
803
+ `${path}/default`,
804
+ "A string default is a string no longer than maxLength."
805
+ );
665
806
  }
666
807
  break;
667
808
  }
@@ -671,17 +812,29 @@ function validateOption(c, value, path, v2) {
671
812
  (choice) => isRecord(choice) && Object.keys(choice).length === 2 && isId(choice.value) && isText(choice.label)
672
813
  ) && new Set(choices.map((choice) => choice.value)).size === choices.length;
673
814
  if (!choicesOk) {
674
- c.add("manifest.option.choices", `${path}/choices`, `choices is a list of 1 to ${MAX_CHOICES} distinct { value, label } pairs; a value follows the id rule.`);
815
+ c.add(
816
+ "manifest.option.choices",
817
+ `${path}/choices`,
818
+ `choices is a list of 1 to ${MAX_CHOICES} distinct { value, label } pairs; a value follows the id rule.`
819
+ );
675
820
  break;
676
821
  }
677
822
  if (!choices.some((choice) => choice.value === value.default)) {
678
- c.add("manifest.option.default", `${path}/default`, "A select default is the value of one of its choices.");
823
+ c.add(
824
+ "manifest.option.default",
825
+ `${path}/default`,
826
+ "A select default is the value of one of its choices."
827
+ );
679
828
  }
680
829
  break;
681
830
  }
682
831
  case "color":
683
832
  if (typeof value.default !== "string" || !COLOR_PATTERN.test(value.default)) {
684
- c.add("manifest.option.color", `${path}/default`, 'A color default is a 6 digit hex colour like "#3366cc".');
833
+ c.add(
834
+ "manifest.option.color",
835
+ `${path}/default`,
836
+ 'A color default is a 6 digit hex colour like "#3366cc".'
837
+ );
685
838
  }
686
839
  break;
687
840
  default:
@@ -691,44 +844,90 @@ function validateOption(c, value, path, v2) {
691
844
  function validateTranslations(c, value, slots, options) {
692
845
  const path = "/translations";
693
846
  if (!isRecord(value)) {
694
- c.add("manifest.translations.invalid", path, "translations is an object keyed by language code.");
847
+ c.add(
848
+ "manifest.translations.invalid",
849
+ path,
850
+ "translations is an object keyed by language code."
851
+ );
695
852
  return;
696
853
  }
697
854
  for (const [language, entry] of Object.entries(value)) {
698
855
  const langPath = `${path}/${language}`;
699
856
  if (!LANGUAGE_PATTERN.test(language)) {
700
- c.add("manifest.translations.language", langPath, `"${language}" is not a language code like "fr" or "pt-BR".`);
857
+ c.add(
858
+ "manifest.translations.language",
859
+ langPath,
860
+ `"${language}" is not a language code like "fr" or "pt-BR".`
861
+ );
701
862
  continue;
702
863
  }
703
864
  if (!isRecord(entry)) {
704
- c.add("manifest.translations.invalid", langPath, "A translation is an object with optional name, description, slots and options.");
865
+ c.add(
866
+ "manifest.translations.invalid",
867
+ langPath,
868
+ "A translation is an object with optional name, description, slots and options."
869
+ );
705
870
  continue;
706
871
  }
707
- if (!c.checkKeys(entry, langPath, "manifest.translations", [], TRANSLATION_KEYS)) continue;
872
+ if (!c.checkKeys(
873
+ entry,
874
+ langPath,
875
+ "manifest.translations",
876
+ [],
877
+ TRANSLATION_KEYS
878
+ ))
879
+ continue;
708
880
  for (const key of ["name", "description"]) {
709
881
  if (Object.hasOwn(entry, key) && !isTranslationText(entry[key])) {
710
- c.add("manifest.translations.text", `${langPath}/${key}`, `A translated string is at most ${MAX_TEXT} characters.`);
882
+ c.add(
883
+ "manifest.translations.text",
884
+ `${langPath}/${key}`,
885
+ `A translated string is at most ${MAX_TEXT} characters.`
886
+ );
711
887
  }
712
888
  }
713
889
  if (Object.hasOwn(entry, "slots")) {
714
890
  const entrySlots = entry.slots;
715
891
  if (!isRecord(entrySlots)) {
716
- c.add("manifest.translations.invalid", `${langPath}/slots`, "slots is an object keyed by slot id.");
892
+ c.add(
893
+ "manifest.translations.invalid",
894
+ `${langPath}/slots`,
895
+ "slots is an object keyed by slot id."
896
+ );
717
897
  } else {
718
898
  for (const [slotId, slotEntry] of Object.entries(entrySlots)) {
719
899
  const slotPath = `${langPath}/slots/${slotId}`;
720
900
  if (!slots.some((slot) => slot.id === slotId)) {
721
- c.add("manifest.translations.slot", slotPath, `"${slotId}" is not a slot id in this manifest.`);
901
+ c.add(
902
+ "manifest.translations.slot",
903
+ slotPath,
904
+ `"${slotId}" is not a slot id in this manifest.`
905
+ );
722
906
  continue;
723
907
  }
724
908
  if (!isRecord(slotEntry)) {
725
- c.add("manifest.translations.invalid", slotPath, "A slot translation is an object with optional label and description.");
909
+ c.add(
910
+ "manifest.translations.invalid",
911
+ slotPath,
912
+ "A slot translation is an object with optional label and description."
913
+ );
726
914
  continue;
727
915
  }
728
- if (!c.checkKeys(slotEntry, slotPath, "manifest.translations", [], SLOT_TRANSLATION_KEYS)) continue;
916
+ if (!c.checkKeys(
917
+ slotEntry,
918
+ slotPath,
919
+ "manifest.translations",
920
+ [],
921
+ SLOT_TRANSLATION_KEYS
922
+ ))
923
+ continue;
729
924
  for (const key of ["label", "description"]) {
730
925
  if (Object.hasOwn(slotEntry, key) && !isTranslationText(slotEntry[key])) {
731
- c.add("manifest.translations.text", `${slotPath}/${key}`, `A translated string is at most ${MAX_TEXT} characters.`);
926
+ c.add(
927
+ "manifest.translations.text",
928
+ `${slotPath}/${key}`,
929
+ `A translated string is at most ${MAX_TEXT} characters.`
930
+ );
732
931
  }
733
932
  }
734
933
  }
@@ -737,37 +936,74 @@ function validateTranslations(c, value, slots, options) {
737
936
  if (Object.hasOwn(entry, "options")) {
738
937
  const entryOptions = entry.options;
739
938
  if (!isRecord(entryOptions)) {
740
- c.add("manifest.translations.invalid", `${langPath}/options`, "options is an object keyed by option id.");
939
+ c.add(
940
+ "manifest.translations.invalid",
941
+ `${langPath}/options`,
942
+ "options is an object keyed by option id."
943
+ );
741
944
  } else {
742
945
  for (const [optionId, optionEntry] of Object.entries(entryOptions)) {
743
946
  const optionPath = `${langPath}/options/${optionId}`;
744
947
  const option = options.find((item) => item.id === optionId);
745
948
  if (!option) {
746
- c.add("manifest.translations.option", optionPath, `"${optionId}" is not an option id in this manifest.`);
949
+ c.add(
950
+ "manifest.translations.option",
951
+ optionPath,
952
+ `"${optionId}" is not an option id in this manifest.`
953
+ );
747
954
  continue;
748
955
  }
749
956
  if (!isRecord(optionEntry)) {
750
- c.add("manifest.translations.invalid", optionPath, "An option translation is an object with optional label, group and choices.");
957
+ c.add(
958
+ "manifest.translations.invalid",
959
+ optionPath,
960
+ "An option translation is an object with optional label, group and choices."
961
+ );
751
962
  continue;
752
963
  }
753
- if (!c.checkKeys(optionEntry, optionPath, "manifest.translations", [], OPTION_TRANSLATION_KEYS)) continue;
964
+ if (!c.checkKeys(
965
+ optionEntry,
966
+ optionPath,
967
+ "manifest.translations",
968
+ [],
969
+ OPTION_TRANSLATION_KEYS
970
+ ))
971
+ continue;
754
972
  for (const key of ["label", "group"]) {
755
973
  if (Object.hasOwn(optionEntry, key) && !isTranslationText(optionEntry[key])) {
756
- c.add("manifest.translations.text", `${optionPath}/${key}`, `A translated string is at most ${MAX_TEXT} characters.`);
974
+ c.add(
975
+ "manifest.translations.text",
976
+ `${optionPath}/${key}`,
977
+ `A translated string is at most ${MAX_TEXT} characters.`
978
+ );
757
979
  }
758
980
  }
759
981
  if (!Object.hasOwn(optionEntry, "choices")) continue;
760
982
  const choices = optionEntry.choices;
761
983
  if (!isRecord(choices)) {
762
- c.add("manifest.translations.invalid", `${optionPath}/choices`, "choices is an object keyed by choice value.");
984
+ c.add(
985
+ "manifest.translations.invalid",
986
+ `${optionPath}/choices`,
987
+ "choices is an object keyed by choice value."
988
+ );
763
989
  continue;
764
990
  }
765
991
  for (const [choiceValue, label] of Object.entries(choices)) {
766
992
  const choicePath = `${optionPath}/choices/${choiceValue}`;
767
- if (option.type !== "select" || !(option.choices ?? []).some((choice) => choice.value === choiceValue)) {
768
- c.add("manifest.translations.choice", choicePath, `"${choiceValue}" is not a choice of option "${optionId}".`);
993
+ if (option.type !== "select" || !(option.choices ?? []).some(
994
+ (choice) => choice.value === choiceValue
995
+ )) {
996
+ c.add(
997
+ "manifest.translations.choice",
998
+ choicePath,
999
+ `"${choiceValue}" is not a choice of option "${optionId}".`
1000
+ );
769
1001
  } else if (!isTranslationText(label)) {
770
- c.add("manifest.translations.text", choicePath, `A translated string is at most ${MAX_TEXT} characters.`);
1002
+ c.add(
1003
+ "manifest.translations.text",
1004
+ choicePath,
1005
+ `A translated string is at most ${MAX_TEXT} characters.`
1006
+ );
771
1007
  }
772
1008
  }
773
1009
  }
@@ -783,24 +1019,51 @@ function validateManifest(value) {
783
1019
  }
784
1020
  const schemaVersion = value.schemaVersion;
785
1021
  if (schemaVersion !== 1 && schemaVersion !== 2) {
786
- c.add("manifest.schemaVersion.unsupported", "/schemaVersion", "schemaVersion must be 1 or 2.");
1022
+ c.add(
1023
+ "manifest.schemaVersion.unsupported",
1024
+ "/schemaVersion",
1025
+ "schemaVersion must be 1 or 2."
1026
+ );
787
1027
  return c.problems;
788
1028
  }
789
1029
  const v2 = schemaVersion === 2;
790
- if (!c.checkKeys(value, "", "manifest", V1_TOP_KEYS, v2 ? V2_TOP_EXTRA_KEYS : [], (key) => `manifest.${key}.required`)) {
1030
+ if (!c.checkKeys(
1031
+ value,
1032
+ "",
1033
+ "manifest",
1034
+ V1_TOP_KEYS,
1035
+ v2 ? V2_TOP_EXTRA_KEYS : [],
1036
+ (key) => `manifest.${key}.required`
1037
+ )) {
791
1038
  return c.problems;
792
1039
  }
793
1040
  if (!isId(value.id)) {
794
- c.add("manifest.id.invalid", "/id", 'id is lowercase, starts with a letter, and uses only a-z, 0-9, _ and -, up to 64 characters. It becomes the chart type "custom:<id>".');
1041
+ c.add(
1042
+ "manifest.id.invalid",
1043
+ "/id",
1044
+ 'id is lowercase, starts with a letter, and uses only a-z, 0-9, _ and -, up to 64 characters. It becomes the chart type "custom:<id>".'
1045
+ );
795
1046
  }
796
1047
  if (!isText(value.name)) {
797
- c.add("manifest.name.invalid", "/name", `name is 1 to ${MAX_TEXT} characters.`);
1048
+ c.add(
1049
+ "manifest.name.invalid",
1050
+ "/name",
1051
+ `name is 1 to ${MAX_TEXT} characters.`
1052
+ );
798
1053
  }
799
1054
  if (Object.hasOwn(value, "version") && (typeof value.version !== "string" || !SEMVER_PATTERN.test(value.version))) {
800
- c.add("manifest.version.invalid", "/version", 'version is a semver string like "1.2.0".');
1055
+ c.add(
1056
+ "manifest.version.invalid",
1057
+ "/version",
1058
+ 'version is a semver string like "1.2.0".'
1059
+ );
801
1060
  }
802
1061
  if (Object.hasOwn(value, "description") && !isText(value.description, MAX_DESCRIPTION)) {
803
- c.add("manifest.description.invalid", "/description", `description is 1 to ${MAX_DESCRIPTION} characters.`);
1062
+ c.add(
1063
+ "manifest.description.invalid",
1064
+ "/description",
1065
+ `description is 1 to ${MAX_DESCRIPTION} characters.`
1066
+ );
804
1067
  }
805
1068
  const slots = value.slots;
806
1069
  if (!Array.isArray(slots)) {
@@ -808,30 +1071,54 @@ function validateManifest(value) {
808
1071
  } else if (slots.length === 0) {
809
1072
  c.add("manifest.slots.empty", "/slots", "Declare at least one slot.");
810
1073
  } else if (slots.length > MAX_SLOTS) {
811
- c.add("manifest.slots.tooMany", "/slots", `Declare at most ${MAX_SLOTS} slots.`);
1074
+ c.add(
1075
+ "manifest.slots.tooMany",
1076
+ "/slots",
1077
+ `Declare at most ${MAX_SLOTS} slots.`
1078
+ );
812
1079
  } else {
813
- slots.forEach((slot, index) => validateSlot(c, slot, `/slots/${index}`, v2));
1080
+ for (const [index, slot] of slots.entries()) {
1081
+ validateSlot(c, slot, `/slots/${index}`, v2);
1082
+ }
814
1083
  const seen = /* @__PURE__ */ new Set();
815
1084
  slots.forEach((slot, index) => {
816
1085
  if (!isRecord(slot) || typeof slot.id !== "string") return;
817
1086
  if (seen.has(slot.id)) {
818
- c.add("manifest.slot.duplicate", `/slots/${index}/id`, `Slot id "${slot.id}" is used more than once.`);
1087
+ c.add(
1088
+ "manifest.slot.duplicate",
1089
+ `/slots/${index}/id`,
1090
+ `Slot id "${slot.id}" is used more than once.`
1091
+ );
819
1092
  }
820
1093
  seen.add(slot.id);
821
1094
  });
822
1095
  }
823
1096
  const options = value.options;
824
1097
  if (!Array.isArray(options)) {
825
- c.add("manifest.options.invalid", "/options", "options must be an array (it may be empty).");
1098
+ c.add(
1099
+ "manifest.options.invalid",
1100
+ "/options",
1101
+ "options must be an array (it may be empty)."
1102
+ );
826
1103
  } else if (options.length > MAX_OPTIONS) {
827
- c.add("manifest.options.tooMany", "/options", `Declare at most ${MAX_OPTIONS} options.`);
1104
+ c.add(
1105
+ "manifest.options.tooMany",
1106
+ "/options",
1107
+ `Declare at most ${MAX_OPTIONS} options.`
1108
+ );
828
1109
  } else {
829
- options.forEach((option, index) => validateOption(c, option, `/options/${index}`, v2));
1110
+ for (const [index, option] of options.entries()) {
1111
+ validateOption(c, option, `/options/${index}`, v2);
1112
+ }
830
1113
  const seen = /* @__PURE__ */ new Set();
831
1114
  options.forEach((option, index) => {
832
1115
  if (!isRecord(option) || typeof option.id !== "string") return;
833
1116
  if (seen.has(option.id)) {
834
- c.add("manifest.option.duplicate", `/options/${index}/id`, `Option id "${option.id}" is used more than once.`);
1117
+ c.add(
1118
+ "manifest.option.duplicate",
1119
+ `/options/${index}/id`,
1120
+ `Option id "${option.id}" is used more than once.`
1121
+ );
835
1122
  }
836
1123
  seen.add(option.id);
837
1124
  });
@@ -845,7 +1132,11 @@ function validateManifest(value) {
845
1132
  );
846
1133
  }
847
1134
  if (c.problems.length === 0 && jsonBytes(value) > MAX_MANIFEST_BYTES) {
848
- c.add("manifest.size", "", `manifest.json must be at most ${MAX_MANIFEST_BYTES} bytes as JSON.`);
1135
+ c.add(
1136
+ "manifest.size",
1137
+ "",
1138
+ `manifest.json must be at most ${MAX_MANIFEST_BYTES} bytes as JSON.`
1139
+ );
849
1140
  }
850
1141
  return c.problems;
851
1142
  }
@@ -877,13 +1168,14 @@ var manifestSchema = z.object({
877
1168
  description: z.string().optional(),
878
1169
  slots: z.array(slotSchema),
879
1170
  options: z.array(optionSchema),
880
- translations: z.record(z.unknown()).optional()
1171
+ translations: z.record(z.string(), z.unknown()).optional()
881
1172
  });
882
1173
  function sortKeys(value) {
883
1174
  if (Array.isArray(value)) return value.map((item) => sortKeys(item));
884
1175
  if (isRecord(value)) {
885
1176
  const out = {};
886
- for (const key of Object.keys(value).sort()) out[key] = sortKeys(value[key]);
1177
+ for (const key of Object.keys(value).sort())
1178
+ out[key] = sortKeys(value[key]);
887
1179
  return out;
888
1180
  }
889
1181
  return value;
@@ -891,14 +1183,22 @@ function sortKeys(value) {
891
1183
 
892
1184
  // src/custom-chart/zip.ts
893
1185
  import { strFromU8, strToU8, unzipSync, zipSync } from "fflate";
894
- var BUNDLE_ZIP_FILES = ["index.js", "manifest.json", "icon.svg", "index.css"];
1186
+ var BUNDLE_ZIP_FILES = [
1187
+ "index.js",
1188
+ "manifest.json",
1189
+ "icon.svg",
1190
+ "index.css"
1191
+ ];
895
1192
  function writeBundleZip(files) {
896
1193
  const entries = {};
897
1194
  for (const name of BUNDLE_ZIP_FILES) {
898
1195
  const content = files[name];
899
1196
  if (typeof content === "string") entries[name] = strToU8(content);
900
1197
  }
901
- return zipSync(entries, { level: 6, mtime: /* @__PURE__ */ new Date("2000-01-01T00:00:00Z") });
1198
+ return zipSync(entries, {
1199
+ level: 6,
1200
+ mtime: /* @__PURE__ */ new Date("2000-01-01T00:00:00Z")
1201
+ });
902
1202
  }
903
1203
 
904
1204
  // src/custom-chart/bundle.ts
@@ -919,9 +1219,17 @@ function validateBundle(input) {
919
1219
  const problems = validateManifest(input.manifest);
920
1220
  if (input.bundleJs !== void 0) {
921
1221
  if (typeof input.bundleJs !== "string") {
922
- problems.push({ code: "bundle.js.type", path: "/bundleJs", message: "bundleJs must be a string." });
1222
+ problems.push({
1223
+ code: "bundle.js.type",
1224
+ path: "/bundleJs",
1225
+ message: "bundleJs must be a string."
1226
+ });
923
1227
  } else if (input.bundleJs.trim().length === 0) {
924
- problems.push({ code: "bundle.js.empty", path: "/bundleJs", message: "bundleJs must contain JavaScript." });
1228
+ problems.push({
1229
+ code: "bundle.js.empty",
1230
+ path: "/bundleJs",
1231
+ message: "bundleJs must contain JavaScript."
1232
+ });
925
1233
  } else if (utf8Bytes(input.bundleJs) > MAX_BUNDLE_JS_BYTES) {
926
1234
  problems.push({
927
1235
  code: "bundle.js.size",
@@ -932,7 +1240,11 @@ function validateBundle(input) {
932
1240
  }
933
1241
  if (input.bundleCss !== void 0) {
934
1242
  if (typeof input.bundleCss !== "string") {
935
- problems.push({ code: "bundle.css.type", path: "/bundleCss", message: "bundleCss must be a string when present." });
1243
+ problems.push({
1244
+ code: "bundle.css.type",
1245
+ path: "/bundleCss",
1246
+ message: "bundleCss must be a string when present."
1247
+ });
936
1248
  } else if (utf8Bytes(input.bundleCss) > MAX_BUNDLE_CSS_BYTES) {
937
1249
  problems.push({
938
1250
  code: "bundle.css.size",
@@ -941,7 +1253,8 @@ function validateBundle(input) {
941
1253
  });
942
1254
  }
943
1255
  }
944
- if (input.iconSvg !== void 0) problems.push(...validateIcon(input.iconSvg, "/iconSvg"));
1256
+ if (input.iconSvg !== void 0)
1257
+ problems.push(...validateIcon(input.iconSvg, "/iconSvg"));
945
1258
  return problems;
946
1259
  }
947
1260
  function readProject(dirInput) {
@@ -950,7 +1263,11 @@ function readProject(dirInput) {
950
1263
  const project = { dir, manifest: void 0, problems };
951
1264
  const manifestPath = join2(dir, "manifest.json");
952
1265
  if (!existsSync2(manifestPath)) {
953
- problems.push({ code: "project.manifest.missing", path: "/manifest.json", message: `No manifest.json in ${dir}.` });
1266
+ problems.push({
1267
+ code: "project.manifest.missing",
1268
+ path: "/manifest.json",
1269
+ message: `No manifest.json in ${dir}.`
1270
+ });
954
1271
  } else {
955
1272
  project.manifestText = readFileSync2(manifestPath, "utf8");
956
1273
  try {
@@ -965,7 +1282,11 @@ function readProject(dirInput) {
965
1282
  }
966
1283
  const entry = ["chart.ts", "chart.js"].map((name) => join2(dir, name)).find((path) => existsSync2(path));
967
1284
  if (!entry) {
968
- problems.push({ code: "project.chart.missing", path: "/chart.ts", message: `No chart.ts in ${dir}. It must export render(ctx).` });
1285
+ problems.push({
1286
+ code: "project.chart.missing",
1287
+ path: "/chart.ts",
1288
+ message: `No chart.ts in ${dir}. It must export render(ctx).`
1289
+ });
969
1290
  } else {
970
1291
  project.chartEntry = entry;
971
1292
  }
@@ -973,7 +1294,11 @@ function readProject(dirInput) {
973
1294
  if (existsSync2(cssPath)) project.css = readFileSync2(cssPath, "utf8");
974
1295
  const iconPath = join2(dir, "icon.svg");
975
1296
  if (!existsSync2(iconPath)) {
976
- problems.push({ code: "bundle.icon.required", path: "/icon.svg", message: `No icon.svg in ${dir}.` });
1297
+ problems.push({
1298
+ code: "bundle.icon.required",
1299
+ path: "/icon.svg",
1300
+ message: `No icon.svg in ${dir}.`
1301
+ });
977
1302
  } else {
978
1303
  project.icon = readFileSync2(iconPath, "utf8");
979
1304
  }
@@ -994,21 +1319,34 @@ function readProject(dirInput) {
994
1319
  function validateProject(dir) {
995
1320
  const project = readProject(dir);
996
1321
  const problems = [...project.problems];
997
- if (project.manifest !== void 0) problems.push(...validateManifest(project.manifest));
998
- if (project.icon !== void 0) problems.push(...validateIcon(sanitizeIcon(project.icon)));
1322
+ if (project.manifest !== void 0)
1323
+ problems.push(...validateManifest(project.manifest));
1324
+ if (project.icon !== void 0)
1325
+ problems.push(...validateIcon(sanitizeIcon(project.icon)));
999
1326
  if (project.css !== void 0 && utf8Bytes(project.css) > MAX_BUNDLE_CSS_BYTES) {
1000
- problems.push({ code: "bundle.css.size", path: "/chart.css", message: `chart.css must be at most ${MAX_BUNDLE_CSS_BYTES} bytes.` });
1327
+ problems.push({
1328
+ code: "bundle.css.size",
1329
+ path: "/chart.css",
1330
+ message: `chart.css must be at most ${MAX_BUNDLE_CSS_BYTES} bytes.`
1331
+ });
1001
1332
  }
1002
1333
  return { ok: problems.length === 0, problems, project };
1003
1334
  }
1004
- var DIST_FILES = ["index.js", "manifest.json", "icon.svg", "index.css", "bundle.zip"];
1335
+ var DIST_FILES = [
1336
+ "index.js",
1337
+ "manifest.json",
1338
+ "icon.svg",
1339
+ "index.css",
1340
+ "bundle.zip"
1341
+ ];
1005
1342
  function insideProjectOnly(dir) {
1006
1343
  const root = dir.endsWith(sep) ? dir : `${dir}${sep}`;
1007
1344
  return {
1008
1345
  name: "databrain-inside-project-only",
1009
1346
  setup(build) {
1010
1347
  build.onResolve({ filter: /.*/ }, async (args) => {
1011
- if (args.kind === "entry-point" || args.pluginData?.databrainChecked) return void 0;
1348
+ if (args.kind === "entry-point" || args.pluginData?.databrainChecked)
1349
+ return void 0;
1012
1350
  const resolved = await build.resolve(args.path, {
1013
1351
  kind: args.kind,
1014
1352
  resolveDir: args.resolveDir,
@@ -1016,7 +1354,8 @@ function insideProjectOnly(dir) {
1016
1354
  pluginData: { databrainChecked: true }
1017
1355
  });
1018
1356
  if (resolved.errors.length > 0) return { errors: resolved.errors };
1019
- if (resolved.external || resolved.path.startsWith(root)) return resolved;
1357
+ if (resolved.external || resolved.path.startsWith(root))
1358
+ return resolved;
1020
1359
  return {
1021
1360
  errors: [
1022
1361
  {
@@ -1072,10 +1411,18 @@ async function buildProject(dir, options = {}) {
1072
1411
  if (Array.isArray(errors) && errors.length > 0) {
1073
1412
  for (const error of errors) {
1074
1413
  const where = error.location ? `${error.location.file ?? "chart.ts"}:${error.location.line ?? 0}` : "chart.ts";
1075
- problems.push({ code: "bundle.build.failed", path: `/${where}`, message: error.text });
1414
+ problems.push({
1415
+ code: "bundle.build.failed",
1416
+ path: `/${where}`,
1417
+ message: error.text
1418
+ });
1076
1419
  }
1077
1420
  } else {
1078
- problems.push({ code: "bundle.build.failed", path: "/chart.ts", message: err.message });
1421
+ problems.push({
1422
+ code: "bundle.build.failed",
1423
+ path: "/chart.ts",
1424
+ message: err.message
1425
+ });
1079
1426
  }
1080
1427
  return { ok: false, problems, written: [] };
1081
1428
  }
@@ -1101,7 +1448,8 @@ globalThis.__dbnCustomChart=__dbnCustomChart;
1101
1448
  if (options.write !== false) {
1102
1449
  const dist = join2(project.dir, "dist");
1103
1450
  mkdirSync(dist, { recursive: true });
1104
- const manifestJson = JSON.stringify(manifest, null, 2) + "\n";
1451
+ const manifestJson = `${JSON.stringify(manifest, null, 2)}
1452
+ `;
1105
1453
  const write = (name, content) => {
1106
1454
  const path = join2(dist, name);
1107
1455
  writeFileSync(path, content);
@@ -1129,7 +1477,11 @@ function readDist(dir) {
1129
1477
  const need = ["index.js", "manifest.json", "icon.svg"];
1130
1478
  for (const name of need) {
1131
1479
  if (!existsSync2(join2(dist, name))) {
1132
- problems.push({ code: "project.dist.missing", path: `/dist/${name}`, message: `dist/${name} is missing. Run databrain custom-chart build first.` });
1480
+ problems.push({
1481
+ code: "project.dist.missing",
1482
+ path: `/dist/${name}`,
1483
+ message: `dist/${name} is missing. Run databrain custom-chart build first.`
1484
+ });
1133
1485
  }
1134
1486
  }
1135
1487
  if (problems.length > 0) return { problems };
@@ -1137,7 +1489,15 @@ function readDist(dir) {
1137
1489
  try {
1138
1490
  manifest = JSON.parse(readFileSync2(join2(dist, "manifest.json"), "utf8"));
1139
1491
  } catch (err) {
1140
- return { problems: [{ code: "project.dist.parse", path: "/dist/manifest.json", message: err.message }] };
1492
+ return {
1493
+ problems: [
1494
+ {
1495
+ code: "project.dist.parse",
1496
+ path: "/dist/manifest.json",
1497
+ message: err.message
1498
+ }
1499
+ ]
1500
+ };
1141
1501
  }
1142
1502
  const manifestProblems = validateManifest(manifest);
1143
1503
  if (manifestProblems.length > 0) return { problems: manifestProblems };
@@ -1158,16 +1518,31 @@ async function buildSource(input) {
1158
1518
  const manifest = input.manifest;
1159
1519
  try {
1160
1520
  const common = {
1161
- stdin: { contents: input.chartTs, loader: "ts", sourcefile: "chart.ts" },
1521
+ stdin: {
1522
+ contents: input.chartTs,
1523
+ loader: "ts",
1524
+ sourcefile: "chart.ts"
1525
+ },
1162
1526
  bundle: true,
1163
1527
  platform: "browser",
1164
1528
  target: "es2020",
1165
1529
  write: false,
1166
1530
  legalComments: "none",
1167
1531
  logLevel: "silent",
1168
- plugins: [{ name: "no-host-imports", setup(build) {
1169
- build.onResolve({ filter: /.*/ }, (args) => ({ errors: [{ text: `Import "${args.path}" is unavailable in hosted chart source. Use browser APIs or pass a prebuilt bundle.` }] }));
1170
- } }]
1532
+ plugins: [
1533
+ {
1534
+ name: "no-host-imports",
1535
+ setup(build) {
1536
+ build.onResolve({ filter: /.*/ }, (args) => ({
1537
+ errors: [
1538
+ {
1539
+ text: `Import "${args.path}" is unavailable in hosted chart source. Use browser APIs or pass a prebuilt bundle.`
1540
+ }
1541
+ ]
1542
+ }));
1543
+ }
1544
+ }
1545
+ ]
1171
1546
  };
1172
1547
  let shape = await esbuild({ ...common, format: "esm", metafile: true });
1173
1548
  if (!Object.values(shape.metafile.outputs)[0]?.exports.includes("render")) {
@@ -1175,9 +1550,24 @@ async function buildSource(input) {
1175
1550
  shape = await esbuild({ ...common, format: "esm", metafile: true });
1176
1551
  }
1177
1552
  if (!Object.values(shape.metafile.outputs)[0]?.exports.includes("render")) {
1178
- return { ok: false, problems: [{ code: "bundle.build.noRender", path: "/chart.ts", message: "Export function render(ctx)." }], written: [] };
1553
+ return {
1554
+ ok: false,
1555
+ problems: [
1556
+ {
1557
+ code: "bundle.build.noRender",
1558
+ path: "/chart.ts",
1559
+ message: "Export function render(ctx)."
1560
+ }
1561
+ ],
1562
+ written: []
1563
+ };
1179
1564
  }
1180
- const built = await esbuild({ ...common, format: "iife", globalName: "__dbnCustomChart", minify: true });
1565
+ const built = await esbuild({
1566
+ ...common,
1567
+ format: "iife",
1568
+ globalName: "__dbnCustomChart",
1569
+ minify: true
1570
+ });
1181
1571
  const bundle = {
1182
1572
  manifest,
1183
1573
  bundleCss: input.bundleCss,
@@ -1193,20 +1583,34 @@ globalThis.__dbnCustomChart=__dbnCustomChart;
1193
1583
  ok: true,
1194
1584
  problems: [],
1195
1585
  written: [],
1196
- outputs: { ...bundle, contentHash: contentHash(bundle), sizeBytes: bundleSizeBytes(bundle) }
1586
+ outputs: {
1587
+ ...bundle,
1588
+ contentHash: contentHash(bundle),
1589
+ sizeBytes: bundleSizeBytes(bundle)
1590
+ }
1197
1591
  };
1198
1592
  } catch (error) {
1199
- return { ok: false, problems: [{ code: "bundle.build.failed", path: "/chart.ts", message: error.message }], written: [] };
1593
+ return {
1594
+ ok: false,
1595
+ problems: [
1596
+ {
1597
+ code: "bundle.build.failed",
1598
+ path: "/chart.ts",
1599
+ message: error.message
1600
+ }
1601
+ ],
1602
+ written: []
1603
+ };
1200
1604
  }
1201
1605
  }
1202
1606
 
1203
1607
  export {
1204
- readTemplateFiles,
1205
- readCustomChartBrowserRuntime,
1206
1608
  MAX_MANIFEST_BYTES,
1207
1609
  MAX_BUNDLE_JS_BYTES,
1208
1610
  MAX_BUNDLE_CSS_BYTES,
1209
1611
  MAX_ICON_BYTES,
1612
+ readTemplateFiles,
1613
+ readCustomChartBrowserRuntime,
1210
1614
  isId,
1211
1615
  validateManifest,
1212
1616
  slotSchema,
@@ -1221,4 +1625,4 @@ export {
1221
1625
  readDist,
1222
1626
  buildSource
1223
1627
  };
1224
- //# sourceMappingURL=chunk-Q5EYDKSA.js.map
1628
+ //# sourceMappingURL=chunk-2F7V6RZR.js.map