@open-feishu-card/adapter 0.3.5 → 0.3.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.
package/dist/index.js CHANGED
@@ -604,6 +604,85 @@ function parseMarkdown(content) {
604
604
  return out;
605
605
  }
606
606
 
607
+ // src/expand-dsl-colors.ts
608
+ function readColorRegistry(card) {
609
+ const config = isRecord(card.config) ? card.config : void 0;
610
+ const style = config && isRecord(config.style) ? config.style : void 0;
611
+ const color = style && isRecord(style.color) ? style.color : void 0;
612
+ if (!color) return {};
613
+ const out = {};
614
+ for (const [key, value] of Object.entries(color)) {
615
+ if (!isRecord(value)) continue;
616
+ const light = typeof value.light_mode === "string" ? value.light_mode : typeof value.lightMode === "string" ? value.lightMode : void 0;
617
+ const dark = typeof value.dark_mode === "string" ? value.dark_mode : typeof value.darkMode === "string" ? value.darkMode : void 0;
618
+ if (light && dark) out[key] = { light_mode: light, dark_mode: dark };
619
+ }
620
+ return out;
621
+ }
622
+ function isCustomColorAlias(value) {
623
+ return typeof value === "string" && value.startsWith("cus-");
624
+ }
625
+ function expandBackgroundStyleAlias(style, registry) {
626
+ if (!isCustomColorAlias(style)) return void 0;
627
+ const entry = registry[style];
628
+ if (!entry) return void 0;
629
+ return { light_mode: entry.light_mode, dark_mode: entry.dark_mode };
630
+ }
631
+ function expandTextStyleColor(textStyle, registry) {
632
+ if (!textStyle) return textStyle;
633
+ const color = typeof textStyle.color === "string" ? textStyle.color.trim() : void 0;
634
+ if (!isCustomColorAlias(color)) return textStyle;
635
+ const entry = registry[color];
636
+ if (!entry) return textStyle;
637
+ const { color: _drop, ...rest } = textStyle;
638
+ return {
639
+ ...rest,
640
+ customColor: { lightMode: entry.light_mode, darkMode: entry.dark_mode }
641
+ };
642
+ }
643
+ function expandMarkdownElements(elements, registry) {
644
+ if (!Array.isArray(elements)) return elements;
645
+ return elements.map((el) => expandMarkdownNode(el, registry));
646
+ }
647
+ function expandMarkdownNode(el, registry) {
648
+ const property = el.property ? { ...el.property } : void 0;
649
+ if (!property) return el;
650
+ let changed = property !== el.property;
651
+ if (Array.isArray(property.elements)) {
652
+ const next = expandMarkdownElements(property.elements, registry);
653
+ if (next !== property.elements) {
654
+ property.elements = next;
655
+ changed = true;
656
+ }
657
+ }
658
+ if (Array.isArray(property.items)) {
659
+ property.items = property.items.map((item) => {
660
+ if (!item || typeof item !== "object") return item;
661
+ const row = item;
662
+ if (!Array.isArray(row.elements)) return item;
663
+ const next = expandMarkdownElements(row.elements, registry);
664
+ if (next === row.elements) return item;
665
+ return { ...row, elements: next };
666
+ });
667
+ changed = true;
668
+ }
669
+ if (property.textStyle) {
670
+ const expanded = expandTextStyleColor(property.textStyle, registry);
671
+ if (expanded && expanded !== property.textStyle) {
672
+ property.textStyle = expanded;
673
+ changed = true;
674
+ }
675
+ }
676
+ return changed ? { ...el, property } : el;
677
+ }
678
+ function wrapMarkdownContentWithFontColor(content, fontColor) {
679
+ if (!fontColor || !content || /<font\s+color/i.test(content)) return content;
680
+ return `<font color='${fontColor}'>${content}</font>`;
681
+ }
682
+ function isRecord(v) {
683
+ return typeof v === "object" && v !== null && !Array.isArray(v);
684
+ }
685
+
607
686
  // src/dsl-to-raw.ts
608
687
  var KEY_RENAME = {
609
688
  text_align: "textAlign",
@@ -629,14 +708,22 @@ var KEY_RENAME = {
629
708
  };
630
709
  var TEXT_LEAF_KEYS = /* @__PURE__ */ new Set(["title", "subtitle", "alt", "hover_tips", "placeholder"]);
631
710
  function dslToRaw(dsl) {
632
- const root = isRecord(dsl) ? dsl : {};
633
- const card = isRecord(root.card) ? root.card : isRecord(root.json_card) ? root.json_card : root;
711
+ const root = isRecord2(dsl) ? dsl : {};
712
+ const card = unwrapCard(root);
713
+ const colors = readColorRegistry(card);
634
714
  const out = { schema: typeof card.schema === "string" ? card.schema : "2.0" };
635
- if (isRecord(card.header)) out.header = convertHeader(card.header);
636
- if (isRecord(card.body)) out.body = convertBody(card.body);
715
+ if (isRecord2(card.config)) out.config = { ...card.config };
716
+ if (isRecord2(card.header)) out.header = convertHeader(card.header, colors);
717
+ if (isRecord2(card.body)) out.body = convertBody(card.body, colors);
637
718
  return out;
638
719
  }
639
- function convertHeader(header) {
720
+ function unwrapCard(root) {
721
+ if (isRecord2(root.dsl)) return root.dsl;
722
+ if (isRecord2(root.card)) return root.card;
723
+ if (isRecord2(root.json_card)) return root.json_card;
724
+ return root;
725
+ }
726
+ function convertHeader(header, colors) {
640
727
  const property = {};
641
728
  for (const [k, v] of Object.entries(header)) {
642
729
  if (k === "tag") continue;
@@ -648,32 +735,32 @@ function convertHeader(header) {
648
735
  property[k] = wrapTextLeaf(v);
649
736
  continue;
650
737
  }
651
- if ((k === "icon" || k === "ud_icon") && isRecord(v)) {
652
- property[k === "ud_icon" ? "udIcon" : "icon"] = convertEl(v);
738
+ if ((k === "icon" || k === "ud_icon") && isRecord2(v)) {
739
+ property[k === "ud_icon" ? "udIcon" : "icon"] = convertEl(v, colors);
653
740
  continue;
654
741
  }
655
742
  if (k === "text_tag_list" && Array.isArray(v)) {
656
- property.text_tag_list = v.map(convertNode);
743
+ property.text_tag_list = v.map((item) => convertNode(item, colors));
657
744
  continue;
658
745
  }
659
- property[renameKey(k)] = coerceValue(k, v);
746
+ property[renameKey(k)] = coerceValue(k, v, colors);
660
747
  }
661
748
  return { tag: "card_header", property };
662
749
  }
663
- function convertBody(body) {
664
- const property = buildProperty(body, "body");
665
- const elements = Array.isArray(body.elements) ? body.elements.map(convertNode) : [];
750
+ function convertBody(body, colors) {
751
+ const property = buildProperty(body, "body", colors);
752
+ const elements = Array.isArray(body.elements) ? body.elements.map((n) => convertNode(n, colors)) : [];
666
753
  property.elements = elements.filter(Boolean);
667
754
  return { tag: "body", property };
668
755
  }
669
- function convertNode(node) {
670
- if (isRecord(node) && typeof node.tag === "string") return convertEl(node);
756
+ function convertNode(node, colors) {
757
+ if (isRecord2(node) && typeof node.tag === "string") return convertEl(node, colors);
671
758
  return node;
672
759
  }
673
- function convertEl(el) {
760
+ function convertEl(el, colors) {
674
761
  const tag = String(el.tag);
675
762
  if (tag === "person") {
676
- const property = buildProperty(el, "person_v1");
763
+ const property = buildProperty(el, "person_v1", colors);
677
764
  if (property.style === "capsule") {
678
765
  property.pillShaped = true;
679
766
  delete property.style;
@@ -681,16 +768,22 @@ function convertEl(el) {
681
768
  return { tag: "person_v1", property };
682
769
  }
683
770
  if (tag === "markdown" || tag === "lark_md") {
684
- const property = buildProperty(el, "markdown");
685
- if (typeof el.content === "string") property.elements = parseMarkdown(el.content);
771
+ const property = buildProperty(el, "markdown", colors);
772
+ const fontColor = typeof el.font_color === "string" ? el.font_color : void 0;
773
+ let content = typeof el.content === "string" ? el.content : "";
774
+ content = wrapMarkdownContentWithFontColor(content, fontColor);
775
+ if (content) {
776
+ property.elements = expandMarkdownElements(parseMarkdown(content), colors);
777
+ }
686
778
  delete property.content;
779
+ delete property.font_color;
687
780
  return { tag: "markdown", property };
688
781
  }
689
782
  if (tag === "table") {
690
- return { tag, property: convertTableProperty(el) };
783
+ return { tag, property: convertTableProperty(el, colors) };
691
784
  }
692
785
  if (tag === "audio" || tag === "video") {
693
- const property = buildProperty(el, tag);
786
+ const property = buildProperty(el, tag, colors);
694
787
  if (tag === "audio" && el.width != null) {
695
788
  delete property.width;
696
789
  if (el.width === "fill" || el.width === "default") {
@@ -708,14 +801,14 @@ function convertEl(el) {
708
801
  }
709
802
  return { tag, property };
710
803
  }
711
- return { tag, property: buildProperty(el, tag) };
804
+ return { tag, property: buildProperty(el, tag, colors) };
712
805
  }
713
- function convertTableProperty(el) {
714
- const property = buildProperty(el, "table");
806
+ function convertTableProperty(el, colors) {
807
+ const property = buildProperty(el, "table", colors);
715
808
  const columns = Array.isArray(property.columns) ? property.columns : [];
716
809
  const mdColNames = /* @__PURE__ */ new Set();
717
810
  for (const col of columns) {
718
- if (!isRecord(col)) continue;
811
+ if (!isRecord2(col)) continue;
719
812
  const dt = col.data_type ?? col.dataType;
720
813
  if (dt === "lark_md" || dt === "markdown") {
721
814
  const name = typeof col.name === "string" ? col.name : "";
@@ -724,7 +817,7 @@ function convertTableProperty(el) {
724
817
  }
725
818
  if (!mdColNames.size || !Array.isArray(property.rows)) return property;
726
819
  property.rows = property.rows.map((row) => {
727
- if (!isRecord(row)) return row;
820
+ if (!isRecord2(row)) return row;
728
821
  const out = { ...row };
729
822
  for (const name of mdColNames) {
730
823
  const cell = out[name];
@@ -732,7 +825,10 @@ function convertTableProperty(el) {
732
825
  out[name] = {
733
826
  data: {
734
827
  tag: "markdown",
735
- property: { elements: parseMarkdown(cell), originTag: "lark_md" }
828
+ property: {
829
+ elements: expandMarkdownElements(parseMarkdown(cell), colors),
830
+ originTag: "lark_md"
831
+ }
736
832
  }
737
833
  };
738
834
  }
@@ -741,10 +837,29 @@ function convertTableProperty(el) {
741
837
  });
742
838
  return property;
743
839
  }
744
- function buildProperty(el, tag) {
840
+ function buildProperty(el, tag, colors) {
745
841
  const property = {};
746
842
  for (const [k, v] of Object.entries(el)) {
747
843
  if (k === "tag" || k === "id") continue;
844
+ if ((k === "background_style" || k === "backgroundStyle") && (tag === "column" || tag === "column_set")) {
845
+ const renamed = renameKey(k);
846
+ property[renamed] = v;
847
+ const expanded = expandBackgroundStyleAlias(v, colors);
848
+ if (expanded) property.customBackgroundStyle = expanded;
849
+ continue;
850
+ }
851
+ if ((k === "border_color" || k === "borderColor") && tag === "interactive_container") {
852
+ const renamed = renameKey(k);
853
+ property[renamed] = v;
854
+ const expanded = expandBackgroundStyleAlias(v, colors);
855
+ if (expanded) {
856
+ property.customBorderColor = {
857
+ lightMode: expanded.light_mode,
858
+ darkMode: expanded.dark_mode
859
+ };
860
+ }
861
+ continue;
862
+ }
748
863
  if (tag === "column" && k === "width" && typeof v === "string") {
749
864
  const px = pxValue(v);
750
865
  if (px != null) {
@@ -757,15 +872,15 @@ function buildProperty(el, tag) {
757
872
  continue;
758
873
  }
759
874
  if (k === "text") {
760
- if (tag === "checker" && isRecord(v) && (v.tag === "markdown" || v.tag === "lark_md")) {
761
- property.text = convertEl(v);
875
+ if (tag === "checker" && isRecord2(v) && (v.tag === "markdown" || v.tag === "lark_md")) {
876
+ property.text = convertEl(v, colors);
762
877
  } else {
763
878
  property.text = wrapTextLeaf(v);
764
879
  }
765
880
  continue;
766
881
  }
767
- if ((k === "icon" || k === "ud_icon") && isRecord(v)) {
768
- property[k === "ud_icon" ? "udIcon" : "icon"] = convertEl(v);
882
+ if ((k === "icon" || k === "ud_icon") && isRecord2(v)) {
883
+ property[k === "ud_icon" ? "udIcon" : "icon"] = convertEl(v, colors);
769
884
  continue;
770
885
  }
771
886
  if (k === "behaviors" && Array.isArray(v)) {
@@ -776,21 +891,21 @@ function buildProperty(el, tag) {
776
891
  property.url = normalizeUrl(v);
777
892
  continue;
778
893
  }
779
- if (k === "button_area" && isRecord(v)) {
894
+ if (k === "button_area" && isRecord2(v)) {
780
895
  const area = { ...v };
781
- if (Array.isArray(v.buttons)) area.buttons = v.buttons.map(convertNode);
896
+ if (Array.isArray(v.buttons)) area.buttons = v.buttons.map((b) => convertNode(b, colors));
782
897
  property.button_area = area;
783
898
  continue;
784
899
  }
785
- property[renameKey(k)] = coerceValue(k, v);
900
+ property[renameKey(k)] = coerceValue(k, v, colors);
786
901
  }
787
902
  return property;
788
903
  }
789
- function coerceValue(key, value) {
904
+ function coerceValue(key, value, colors) {
790
905
  if ((key === "padding" || key === "margin") && typeof value === "string") {
791
906
  return parseBox(value);
792
907
  }
793
- if (Array.isArray(value)) return value.map(convertNode);
908
+ if (Array.isArray(value)) return value.map((item) => convertNode(item, colors));
794
909
  if (key === "url") return normalizeUrl(value);
795
910
  return value;
796
911
  }
@@ -799,7 +914,7 @@ function renameKey(k) {
799
914
  }
800
915
  function wrapTextLeaf(v) {
801
916
  if (typeof v === "string") return { tag: "plain_text", property: { content: v } };
802
- if (isRecord(v)) {
917
+ if (isRecord2(v)) {
803
918
  const property = { content: typeof v.content === "string" ? v.content : "" };
804
919
  if (typeof v.text_align === "string") property.textAlign = v.text_align;
805
920
  if (typeof v.text_size === "string") property.text_size = v.text_size;
@@ -810,7 +925,7 @@ function wrapTextLeaf(v) {
810
925
  }
811
926
  function wrapHeaderText(v) {
812
927
  if (typeof v === "string") return { tag: "plain_text", property: { content: v } };
813
- if (!isRecord(v)) return { tag: "plain_text", property: { content: "" } };
928
+ if (!isRecord2(v)) return { tag: "plain_text", property: { content: "" } };
814
929
  const tag = typeof v.tag === "string" ? v.tag : "plain_text";
815
930
  const content = typeof v.content === "string" ? v.content : "";
816
931
  if (tag === "lark_md" || tag === "markdown") {
@@ -827,7 +942,7 @@ function wrapHeaderText(v) {
827
942
  function behaviorsToActions(behaviors) {
828
943
  const out = [];
829
944
  for (const b of behaviors) {
830
- if (!isRecord(b)) continue;
945
+ if (!isRecord2(b)) continue;
831
946
  const type = typeof b.type === "string" ? b.type : "open_url";
832
947
  out.push({ type, action: { url: normalizeUrl(b.default_url) } });
833
948
  }
@@ -835,7 +950,7 @@ function behaviorsToActions(behaviors) {
835
950
  }
836
951
  function normalizeUrl(v) {
837
952
  if (typeof v === "string") return v;
838
- if (isRecord(v)) return v;
953
+ if (isRecord2(v)) return v;
839
954
  return v;
840
955
  }
841
956
  function parseBox(s) {
@@ -862,24 +977,25 @@ function pxValue(s) {
862
977
  const n = Number(s);
863
978
  return Number.isFinite(n) ? n : null;
864
979
  }
865
- function isRecord(v) {
980
+ function isRecord2(v) {
866
981
  return typeof v === "object" && v !== null && !Array.isArray(v);
867
982
  }
868
983
 
869
984
  // src/normalize-stored-colors.ts
870
985
  function createColorRegistry() {
871
- return { entries: {}, keyToAlias: /* @__PURE__ */ new Map(), bgSeq: 0, textSeq: 0 };
986
+ return { entries: {}, bgKeyToAlias: /* @__PURE__ */ new Map(), textKeyToAlias: /* @__PURE__ */ new Map(), bgSeq: 0, textSeq: 0 };
872
987
  }
873
988
  function colorEntryKey(entry) {
874
989
  return `${entry.light_mode}|${entry.dark_mode}`;
875
990
  }
876
991
  function registerColorEntry(registry, entry, prefix) {
877
992
  const key = colorEntryKey(entry);
878
- const existing = registry.keyToAlias.get(key);
993
+ const map = prefix === "cus-bg" ? registry.bgKeyToAlias : registry.textKeyToAlias;
994
+ const existing = map.get(key);
879
995
  if (existing) return existing;
880
996
  const alias = prefix === "cus-bg" ? `cus-bg-${registry.bgSeq++}` : `cus-text-${registry.textSeq++}`;
881
997
  registry.entries[alias] = entry;
882
- registry.keyToAlias.set(key, alias);
998
+ map.set(key, alias);
883
999
  return alias;
884
1000
  }
885
1001
  function hexColorToRgba(hex) {
@@ -899,29 +1015,36 @@ function hexColorToRgba(hex) {
899
1015
  }
900
1016
  return void 0;
901
1017
  }
902
- function readCustomBackgroundStyle(node) {
903
- const raw = node.custom_background_style;
1018
+ function readThemeColorPair(raw) {
904
1019
  if (!raw || typeof raw !== "object") return void 0;
905
1020
  const o = raw;
906
- const lightRaw = typeof o.light_mode === "string" ? o.light_mode : void 0;
907
- const darkRaw = typeof o.dark_mode === "string" ? o.dark_mode : void 0;
1021
+ const lightRaw = typeof o.light_mode === "string" ? o.light_mode : typeof o.lightMode === "string" ? o.lightMode : void 0;
1022
+ const darkRaw = typeof o.dark_mode === "string" ? o.dark_mode : typeof o.darkMode === "string" ? o.darkMode : void 0;
908
1023
  if (!lightRaw || !darkRaw) return void 0;
909
1024
  const light = lightRaw.startsWith("#") ? hexColorToRgba(lightRaw) : lightRaw;
910
1025
  const dark = darkRaw.startsWith("#") ? hexColorToRgba(darkRaw) : darkRaw;
911
1026
  if (!light || !dark) return void 0;
912
1027
  return { light_mode: light, dark_mode: dark };
913
1028
  }
1029
+ function readCustomBackgroundStyle(node) {
1030
+ return readThemeColorPair(node.custom_background_style);
1031
+ }
1032
+ function readCustomBorderColor(node) {
1033
+ return readThemeColorPair(node.custom_border_color ?? node.customBorderColor);
1034
+ }
914
1035
  function normalizeStoredCardColors(dsl, preRegistered) {
915
1036
  const colorEntries = { ...preRegistered?.entries ?? {} };
916
- const keyToAlias = new Map(preRegistered?.keyToAlias ?? []);
1037
+ const bgKeyToAlias = new Map(preRegistered?.bgKeyToAlias ?? []);
1038
+ const textKeyToAlias = new Map(preRegistered?.textKeyToAlias ?? []);
917
1039
  let bgSeq = preRegistered?.bgSeq ?? 0;
918
1040
  let textSeq = preRegistered?.textSeq ?? 0;
919
1041
  const ensureAlias = (prefix, entry) => {
920
- const existing2 = keyToAlias.get(colorEntryKey(entry));
1042
+ const map = prefix === "cus-bg" ? bgKeyToAlias : textKeyToAlias;
1043
+ const existing2 = map.get(colorEntryKey(entry));
921
1044
  if (existing2) return existing2;
922
1045
  const alias = prefix === "cus-bg" ? `cus-bg-${bgSeq++}` : `cus-text-${textSeq++}`;
923
1046
  colorEntries[alias] = entry;
924
- keyToAlias.set(colorEntryKey(entry), alias);
1047
+ map.set(colorEntryKey(entry), alias);
925
1048
  return alias;
926
1049
  };
927
1050
  const walk = (node) => {
@@ -938,6 +1061,14 @@ function normalizeStoredCardColors(dsl, preRegistered) {
938
1061
  delete obj.custom_background_style;
939
1062
  }
940
1063
  }
1064
+ if (obj.tag === "interactive_container") {
1065
+ const border = readCustomBorderColor(obj);
1066
+ if (border) {
1067
+ obj.border_color = ensureAlias("cus-bg", border);
1068
+ delete obj.custom_border_color;
1069
+ delete obj.customBorderColor;
1070
+ }
1071
+ }
941
1072
  if (obj.tag === "markdown" && typeof obj.content === "string") {
942
1073
  normalizeMarkdownInlineHexColors(obj, ensureAlias, !!preRegistered);
943
1074
  }
@@ -982,11 +1113,17 @@ function normalizeStoredCardColors(dsl, preRegistered) {
982
1113
  }
983
1114
  if (!node || typeof node !== "object") return;
984
1115
  const obj = node;
985
- if (obj.tag === "markdown" && obj.font_color === void 0) {
986
- const size = obj.text_size;
987
- const content = typeof obj.content === "string" ? obj.content : "";
988
- if (size === "small") obj.font_color = "cus-muted";
989
- else if (size === "heading" || content.includes("**")) obj.font_color = "cus-accent";
1116
+ if (obj.tag === "markdown" && typeof obj.content === "string") {
1117
+ delete obj.font_color;
1118
+ const content = obj.content;
1119
+ if (!/<font\s+color=/i.test(content)) {
1120
+ const size = obj.text_size;
1121
+ if (size === "small") {
1122
+ obj.content = wrapMarkdownContentWithFontColor(content, "cus-muted");
1123
+ } else if (size === "heading" || content.includes("**")) {
1124
+ obj.content = wrapMarkdownContentWithFontColor(content, "cus-accent");
1125
+ }
1126
+ }
990
1127
  }
991
1128
  for (const value of Object.values(obj)) applyDefaultFontColors(value);
992
1129
  };
@@ -1051,8 +1188,8 @@ function normalizeMarkdownInlineHexColors(obj, ensureAlias, keepFontTags = false
1051
1188
  const entry = hexColor(single[1]);
1052
1189
  if (entry) {
1053
1190
  const alias = ensureAlias("cus-text", entry);
1054
- if (obj.font_color === void 0) obj.font_color = alias;
1055
- obj.content = single[2];
1191
+ delete obj.font_color;
1192
+ obj.content = `<font color='${alias}'>${single[2]}</font>`;
1056
1193
  return;
1057
1194
  }
1058
1195
  }
@@ -1117,6 +1254,12 @@ function resolveCustomBackgroundLight(property) {
1117
1254
  const custom = p.custom_background_style ?? p.customBackgroundStyle;
1118
1255
  return readThemeColorLight(custom);
1119
1256
  }
1257
+ function resolveCustomBorderLight(property) {
1258
+ if (!property || typeof property !== "object") return void 0;
1259
+ const p = property;
1260
+ const custom = p.custom_border_color ?? p.customBorderColor;
1261
+ return readThemeColorLight(custom);
1262
+ }
1120
1263
 
1121
1264
  // src/raw-to-dsl.ts
1122
1265
  function isRawCardEnvelope(value) {
@@ -1227,27 +1370,58 @@ var VALUE_ECHO_TARGETS = {
1227
1370
  size_value: "size"
1228
1371
  };
1229
1372
  function convertRoot(root, ctx) {
1230
- if (!isRecord2(root)) return root;
1373
+ if (!isRecord3(root)) return root;
1231
1374
  const out = {};
1232
1375
  out.schema = typeof root.schema === "string" ? root.schema : "2.0";
1233
- out.config = convertConfig(isRecord2(root.config) ? root.config : {});
1234
- if (isRecord2(root.body)) out.body = convertBody2(root.body, ctx);
1235
- if (isRecord2(root.header)) out.header = convertHeader2(root.header, ctx);
1376
+ out.config = convertConfig(isRecord3(root.config) ? root.config : {});
1377
+ if (isRecord3(root.body)) out.body = convertBody2(root.body, ctx);
1378
+ if (isRecord3(root.header)) out.header = convertHeader2(root.header, ctx);
1236
1379
  normalizeStoredCardColors(out, ctx.colors);
1237
1380
  return out;
1238
1381
  }
1239
- function convertConfig(_node) {
1240
- return { update_multi: true };
1382
+ function convertConfig(node) {
1383
+ const out = { update_multi: true };
1384
+ if (node.streamingMode === true || node.streaming_mode === true) {
1385
+ out.streaming_mode = true;
1386
+ }
1387
+ if (node.enableForwardInteraction === true || node.enable_forward_interaction === true) {
1388
+ out.enable_forward_interaction = true;
1389
+ }
1390
+ if (node.enableForward === false || node.enable_forward === false) {
1391
+ out.enable_forward = false;
1392
+ }
1393
+ if (typeof node.widthMode === "string") out.width_mode = node.widthMode;
1394
+ else if (typeof node.width_mode === "string") out.width_mode = node.width_mode;
1395
+ const summaryRaw = isRecord3(node.summary) ? node.summary : void 0;
1396
+ if (summaryRaw) {
1397
+ const summary = {};
1398
+ if (typeof summaryRaw.content === "string") summary.content = summaryRaw.content;
1399
+ if (isRecord3(summaryRaw.i18nContent)) summary.i18n_content = summaryRaw.i18nContent;
1400
+ else if (isRecord3(summaryRaw.i18n_content)) summary.i18n_content = summaryRaw.i18n_content;
1401
+ if (Object.keys(summary).length) out.summary = summary;
1402
+ }
1403
+ const streamingRaw = isRecord3(node.streamingConfig) ? node.streamingConfig : isRecord3(node.streaming_config) ? node.streaming_config : void 0;
1404
+ if (streamingRaw) {
1405
+ const sc = {};
1406
+ if (streamingRaw.printStrategy != null) sc.print_strategy = streamingRaw.printStrategy;
1407
+ else if (streamingRaw.print_strategy != null) sc.print_strategy = streamingRaw.print_strategy;
1408
+ if (streamingRaw.printFrequencyMs != null) sc.print_frequency_ms = streamingRaw.printFrequencyMs;
1409
+ else if (streamingRaw.print_frequency_ms != null) sc.print_frequency_ms = streamingRaw.print_frequency_ms;
1410
+ if (streamingRaw.printStep != null) sc.print_step = streamingRaw.printStep;
1411
+ else if (streamingRaw.print_step != null) sc.print_step = streamingRaw.print_step;
1412
+ if (Object.keys(sc).length) out.streaming_config = sc;
1413
+ }
1414
+ return out;
1241
1415
  }
1242
1416
  function convertHeader2(node, ctx) {
1243
- const property = isRecord2(node.property) ? node.property : node;
1417
+ const property = isRecord3(node.property) ? node.property : node;
1244
1418
  const out = convertProperty(property, "header", ctx);
1245
1419
  delete out.tag;
1246
1420
  return out;
1247
1421
  }
1248
1422
  function convertHeaderText(rawValue, ctx) {
1249
1423
  const tag = typeof rawValue.tag === "string" ? rawValue.tag : "";
1250
- const wrapped = isRecord2(rawValue.property);
1424
+ const wrapped = isRecord3(rawValue.property);
1251
1425
  const property = wrapped ? rawValue.property : rawValue;
1252
1426
  if (tag === "plain_text") {
1253
1427
  const content = typeof property.content === "string" ? property.content : "";
@@ -1267,12 +1441,12 @@ function convertHeaderText(rawValue, ctx) {
1267
1441
  return void 0;
1268
1442
  }
1269
1443
  function convertBody2(node, ctx) {
1270
- const property = isRecord2(node.property) ? node.property : node;
1444
+ const property = isRecord3(node.property) ? node.property : node;
1271
1445
  return convertProperty(property, "body", ctx);
1272
1446
  }
1273
1447
  function unwrap(node, ctx) {
1274
1448
  const tag = typeof node.tag === "string" ? node.tag : void 0;
1275
- const property = isRecord2(node.property) ? node.property : {};
1449
+ const property = isRecord3(node.property) ? node.property : {};
1276
1450
  if (tag === "markdown") return rebuildMarkdown(property, ctx);
1277
1451
  if (tag === "plain_text") {
1278
1452
  const content = typeof property.content === "string" ? property.content : "";
@@ -1286,7 +1460,7 @@ function unwrap(node, ctx) {
1286
1460
  const heightPx = isPixelScalar(property.heightValue) ? pixelOf(property.heightValue) : void 0;
1287
1461
  if (widthPx !== void 0 && heightPx !== void 0) {
1288
1462
  out.size = `${widthPx}px ${heightPx}px`;
1289
- } else if (isRecord2(property.size) && hasSide(property.size)) out.size = formatBox(property.size);
1463
+ } else if (isRecord3(property.size) && hasSide(property.size)) out.size = formatBox(property.size);
1290
1464
  else if (isPixelScalar(property.size)) out.size = `${pixelOf(property.size)}px`;
1291
1465
  else if (typeof property.size === "string") out.size = property.size;
1292
1466
  return out;
@@ -1308,7 +1482,7 @@ function unwrap(node, ctx) {
1308
1482
  const out = { tag: "table" };
1309
1483
  const rawColumns = Array.isArray(property.columns) ? property.columns : [];
1310
1484
  out.columns = rawColumns.map((col) => {
1311
- if (!isRecord2(col)) return {};
1485
+ if (!isRecord3(col)) return {};
1312
1486
  const c = {};
1313
1487
  if (typeof col.name === "string") c.name = col.name;
1314
1488
  const displayName = typeof col.displayName === "string" ? col.displayName : typeof col.display_name === "string" ? col.display_name : void 0;
@@ -1318,22 +1492,22 @@ function unwrap(node, ctx) {
1318
1492
  const hAlign = typeof col.horizontalAlign === "string" ? col.horizontalAlign : typeof col.horizontal_align === "string" ? col.horizontal_align : void 0;
1319
1493
  if (hAlign !== void 0) c.horizontal_align = hAlign;
1320
1494
  const wv = col.widthValue;
1321
- if (isRecord2(wv)) {
1495
+ if (isRecord3(wv)) {
1322
1496
  if (wv.type === "pixels" && typeof wv.value === "number") c.width = `${wv.value}px`;
1323
1497
  else if (typeof wv.value === "string") c.width = wv.value;
1324
1498
  } else if (typeof col.width === "string" || typeof col.width === "number") {
1325
1499
  c.width = col.width;
1326
1500
  }
1327
- if (isRecord2(col.format)) c.format = col.format;
1501
+ if (isRecord3(col.format)) c.format = col.format;
1328
1502
  return c;
1329
1503
  });
1330
1504
  const rawRows = Array.isArray(property.rows) ? property.rows : [];
1331
1505
  out.rows = rawRows.map((row) => {
1332
- if (!isRecord2(row)) return {};
1506
+ if (!isRecord3(row)) return {};
1333
1507
  const r = {};
1334
1508
  for (const [k, cell] of Object.entries(row)) {
1335
- let value = isRecord2(cell) && "data" in cell ? cell.data : cell;
1336
- if (isRecord2(value) && value.tag === "markdown" && isRecord2(value.property)) {
1509
+ let value = isRecord3(cell) && "data" in cell ? cell.data : cell;
1510
+ if (isRecord3(value) && value.tag === "markdown" && isRecord3(value.property)) {
1337
1511
  const elements = Array.isArray(value.property.elements) ? value.property.elements : [];
1338
1512
  value = renderChildren(elements, ctx).content;
1339
1513
  }
@@ -1341,13 +1515,13 @@ function unwrap(node, ctx) {
1341
1515
  }
1342
1516
  return r;
1343
1517
  });
1344
- if (isRecord2(property.headerStyle)) {
1518
+ if (isRecord3(property.headerStyle)) {
1345
1519
  const hs = {};
1346
1520
  for (const [k, v] of Object.entries(property.headerStyle)) {
1347
1521
  const sk = snake(k);
1348
1522
  if (sk === "platform_text_size") continue;
1349
1523
  if (sk === "lines_value") {
1350
- if (isRecord2(v) && typeof v.value === "number") hs.lines = v.value;
1524
+ if (isRecord3(v) && typeof v.value === "number") hs.lines = v.value;
1351
1525
  continue;
1352
1526
  }
1353
1527
  hs[sk] = v;
@@ -1355,7 +1529,7 @@ function unwrap(node, ctx) {
1355
1529
  out.header_style = hs;
1356
1530
  }
1357
1531
  const rhv = property.rowHeightValue;
1358
- if (isRecord2(rhv) && typeof rhv.value === "string") out.row_height = rhv.value;
1532
+ if (isRecord3(rhv) && typeof rhv.value === "string") out.row_height = rhv.value;
1359
1533
  else if (typeof property.rowHeight === "string") out.row_height = property.rowHeight;
1360
1534
  if (typeof property.pageSize === "number") out.page_size = property.pageSize;
1361
1535
  if (typeof property.freezeFirstColumn === "boolean") out.freeze_first_column = property.freezeFirstColumn;
@@ -1390,7 +1564,7 @@ function unwrap(node, ctx) {
1390
1564
  if (typeof property.showAvatar === "boolean") out.show_avatar = property.showAvatar;
1391
1565
  if (typeof property.showName === "boolean") out.show_name = property.showName;
1392
1566
  if (typeof property.style === "string") out.style = property.style;
1393
- if (isRecord2(property.margin) && hasSide(property.margin)) out.margin = formatBox(property.margin);
1567
+ if (isRecord3(property.margin) && hasSide(property.margin)) out.margin = formatBox(property.margin);
1394
1568
  else if (typeof property.margin === "string") out.margin = property.margin;
1395
1569
  return out;
1396
1570
  }
@@ -1402,17 +1576,17 @@ function unwrap(node, ctx) {
1402
1576
  if (typeof property.lines === "number") out.lines = property.lines;
1403
1577
  if (typeof property.dropInvalidUserID === "boolean") out.drop_invalid_user_id = property.dropInvalidUserID;
1404
1578
  else if (typeof property.drop_invalid_user_id === "boolean") out.drop_invalid_user_id = property.drop_invalid_user_id;
1405
- if (isRecord2(property.margin) && hasSide(property.margin)) out.margin = formatBox(property.margin);
1579
+ if (isRecord3(property.margin) && hasSide(property.margin)) out.margin = formatBox(property.margin);
1406
1580
  else if (typeof property.margin === "string") out.margin = property.margin;
1407
1581
  const rawPersons = Array.isArray(property.persons) ? property.persons : [];
1408
1582
  out.persons = rawPersons.map((p) => {
1409
- if (!isRecord2(p)) return void 0;
1583
+ if (!isRecord3(p)) return void 0;
1410
1584
  const id = typeof p.id === "string" ? p.id : typeof p.userID === "string" ? p.userID : void 0;
1411
1585
  return id ? { id } : void 0;
1412
1586
  }).filter((p) => p !== void 0);
1413
- const iconSrc = isRecord2(property.icon) ? property.icon : isRecord2(property.udIcon) ? property.udIcon : void 0;
1587
+ const iconSrc = isRecord3(property.icon) ? property.icon : isRecord3(property.udIcon) ? property.udIcon : void 0;
1414
1588
  if (iconSrc) {
1415
- const ip = isRecord2(iconSrc.property) ? iconSrc.property : iconSrc;
1589
+ const ip = isRecord3(iconSrc.property) ? iconSrc.property : iconSrc;
1416
1590
  const icon = {};
1417
1591
  const iconTag = typeof iconSrc.tag === "string" ? iconSrc.tag : typeof ip.tag === "string" ? ip.tag : "standard_icon";
1418
1592
  icon.tag = iconTag === "ud_icon" ? "standard_icon" : iconTag;
@@ -1424,25 +1598,25 @@ function unwrap(node, ctx) {
1424
1598
  }
1425
1599
  return out;
1426
1600
  }
1427
- if (tag === "div" && isRecord2(property.text) && property.fields === void 0) {
1601
+ if (tag === "div" && isRecord3(property.text) && property.fields === void 0) {
1428
1602
  const text = property.text;
1429
1603
  const textTag = typeof text.tag === "string" ? text.tag : "";
1430
- if ((textTag === "markdown" || textTag === "lark_md") && isRecord2(text.property)) {
1604
+ if ((textTag === "markdown" || textTag === "lark_md") && isRecord3(text.property)) {
1431
1605
  return unwrap(text, ctx);
1432
1606
  }
1433
1607
  if (textTag === "plain_text") {
1434
1608
  const out = { tag: "div" };
1435
1609
  const widthVal = property.widthValue;
1436
- if (isRecord2(widthVal) && typeof widthVal.value === "string" && typeof widthVal.type === "string" && widthVal.type.startsWith("builtin_")) {
1610
+ if (isRecord3(widthVal) && typeof widthVal.value === "string" && typeof widthVal.type === "string" && widthVal.type.startsWith("builtin_")) {
1437
1611
  out.width = widthVal.value;
1438
1612
  } else if (typeof property.width === "string") {
1439
1613
  out.width = property.width;
1440
1614
  }
1441
- const tp = isRecord2(text.property) ? text.property : {};
1615
+ const tp = isRecord3(text.property) ? text.property : {};
1442
1616
  const content = typeof tp.content === "string" ? tp.content : "";
1443
1617
  const textAlign = typeof tp.textAlign === "string" ? tp.textAlign : "left";
1444
1618
  out.text = { tag: "plain_text", content, text_align: textAlign };
1445
- if (isRecord2(property.icon)) {
1619
+ if (isRecord3(property.icon)) {
1446
1620
  out.icon = unwrap(property.icon, ctx);
1447
1621
  }
1448
1622
  return out;
@@ -1469,7 +1643,7 @@ function convertProperty(property, ownerTag, ctx) {
1469
1643
  const echoVal = out[echoKey];
1470
1644
  const enumVal = out[enumKey];
1471
1645
  delete out[echoKey];
1472
- if (!isRecord2(echoVal)) continue;
1646
+ if (!isRecord3(echoVal)) continue;
1473
1647
  const echoType = typeof echoVal.type === "string" ? echoVal.type : "";
1474
1648
  const echoValue = echoVal.value;
1475
1649
  if (echoType.includes("pixels") && typeof echoValue === "number") {
@@ -1478,7 +1652,7 @@ function convertProperty(property, ownerTag, ctx) {
1478
1652
  }
1479
1653
  continue;
1480
1654
  }
1481
- if (echoType === "aspect_ratio" && isRecord2(echoValue)) {
1655
+ if (echoType === "aspect_ratio" && isRecord3(echoValue)) {
1482
1656
  const w = echoValue.width;
1483
1657
  const h = echoValue.height;
1484
1658
  if (typeof w === "number" && typeof h === "number") {
@@ -1486,7 +1660,7 @@ function convertProperty(property, ownerTag, ctx) {
1486
1660
  }
1487
1661
  continue;
1488
1662
  }
1489
- if (echoType === "width_height_pixels" && isRecord2(echoValue)) {
1663
+ if (echoType === "width_height_pixels" && isRecord3(echoValue)) {
1490
1664
  const w = echoValue.width;
1491
1665
  const h = echoValue.height;
1492
1666
  if (typeof w === "number" && typeof h === "number") {
@@ -1526,7 +1700,7 @@ function convertField(rawKey, rawValue, ownerTag, ctx, siblings = {}) {
1526
1700
  if (key === "actions" && Array.isArray(rawValue) && rawValue.length === 0) {
1527
1701
  return DROP;
1528
1702
  }
1529
- if ((key === "padding" || key === "margin") && isRecord2(rawValue) && hasSide(rawValue)) {
1703
+ if ((key === "padding" || key === "margin") && isRecord3(rawValue) && hasSide(rawValue)) {
1530
1704
  return [key, formatBox(rawValue)];
1531
1705
  }
1532
1706
  if (key in VALUE_ECHO_TARGETS) {
@@ -1556,25 +1730,25 @@ function convertField(rawKey, rawValue, ownerTag, ctx, siblings = {}) {
1556
1730
  return DROP;
1557
1731
  }
1558
1732
  if (ownerTag === "video" && VIDEO_RAW_ONLY_FIELDS.has(key)) return DROP;
1559
- if ((key === "alt" || key === "hover_tips") && isRecord2(rawValue) && rawValue.tag === "plain_text") {
1560
- const p = isRecord2(rawValue.property) ? rawValue.property : {};
1733
+ if ((key === "alt" || key === "hover_tips") && isRecord3(rawValue) && rawValue.tag === "plain_text") {
1734
+ const p = isRecord3(rawValue.property) ? rawValue.property : {};
1561
1735
  return [key, { tag: "plain_text", content: typeof p.content === "string" ? p.content : "" }];
1562
1736
  }
1563
- if (key === "text" && isRecord2(rawValue) && rawValue.tag === "plain_text") {
1564
- const p = isRecord2(rawValue.property) ? rawValue.property : {};
1737
+ if (key === "text" && isRecord3(rawValue) && rawValue.tag === "plain_text") {
1738
+ const p = isRecord3(rawValue.property) ? rawValue.property : {};
1565
1739
  return [key, { tag: "plain_text", content: typeof p.content === "string" ? p.content : "" }];
1566
1740
  }
1567
- if (ownerTag === "header" && (key === "title" || key === "subtitle") && isRecord2(rawValue)) {
1741
+ if (ownerTag === "header" && (key === "title" || key === "subtitle") && isRecord3(rawValue)) {
1568
1742
  const headerText = convertHeaderText(rawValue, ctx);
1569
1743
  if (headerText) return [key, headerText];
1570
1744
  }
1571
- if (ownerTag === "header" && key === "ud_icon" && isRecord2(rawValue) && rawValue.tag === "ud_icon") {
1572
- const p = isRecord2(rawValue.property) ? rawValue.property : {};
1745
+ if (ownerTag === "header" && key === "ud_icon" && isRecord3(rawValue) && rawValue.tag === "ud_icon") {
1746
+ const p = isRecord3(rawValue.property) ? rawValue.property : {};
1573
1747
  const token = typeof p.token === "string" ? p.token : void 0;
1574
1748
  if (!token) return DROP;
1575
1749
  return ["icon", { tag: "standard_icon", token }];
1576
1750
  }
1577
- if (ownerTag === "collapsible_panel" && key === "header" && isRecord2(rawValue)) {
1751
+ if (ownerTag === "collapsible_panel" && key === "header" && isRecord3(rawValue)) {
1578
1752
  const cleaned = {};
1579
1753
  for (const [k, v] of Object.entries(rawValue)) {
1580
1754
  const sk = snake(k);
@@ -1591,8 +1765,8 @@ function convertField(rawKey, rawValue, ownerTag, ctx, siblings = {}) {
1591
1765
  if (ownerTag === "button" && key === "actions" && Array.isArray(rawValue)) {
1592
1766
  const openUrls = [];
1593
1767
  for (const a of rawValue) {
1594
- if (!isRecord2(a)) continue;
1595
- const inner = isRecord2(a.action) ? a.action : {};
1768
+ if (!isRecord3(a)) continue;
1769
+ const inner = isRecord3(a.action) ? a.action : {};
1596
1770
  const t = typeof a.type === "string" ? a.type : void 0;
1597
1771
  if (t === "open_url" && typeof inner.url === "string") openUrls.push(inner.url);
1598
1772
  }
@@ -1607,8 +1781,8 @@ function convertField(rawKey, rawValue, ownerTag, ctx, siblings = {}) {
1607
1781
  }
1608
1782
  if (ownerTag === "interactive_container" && key === "actions" && Array.isArray(rawValue)) {
1609
1783
  const behaviors = rawValue.map((a) => {
1610
- if (!isRecord2(a)) return void 0;
1611
- const inner = isRecord2(a.action) ? a.action : {};
1784
+ if (!isRecord3(a)) return void 0;
1785
+ const inner = isRecord3(a.action) ? a.action : {};
1612
1786
  const t = typeof a.type === "string" ? a.type : void 0;
1613
1787
  if (t === "open_url" && typeof inner.url === "string") {
1614
1788
  return { type: "open_url", default_url: inner.url };
@@ -1621,7 +1795,7 @@ function convertField(rawKey, rawValue, ownerTag, ctx, siblings = {}) {
1621
1795
  if (behaviors.length === 0) return DROP;
1622
1796
  return ["behaviors", behaviors];
1623
1797
  }
1624
- if (key === "border" && isRecord2(rawValue)) {
1798
+ if (key === "border" && isRecord3(rawValue)) {
1625
1799
  const b = rawValue;
1626
1800
  const out = {};
1627
1801
  if (typeof b.borderColor === "string") out.color = b.borderColor;
@@ -1635,7 +1809,7 @@ function convertField(rawKey, rawValue, ownerTag, ctx, siblings = {}) {
1635
1809
  }
1636
1810
  return [key, out];
1637
1811
  }
1638
- if (key === "url" && isRecord2(rawValue)) {
1812
+ if (key === "url" && isRecord3(rawValue)) {
1639
1813
  const v = rawValue;
1640
1814
  const main = typeof v.url === "string" ? v.url : "";
1641
1815
  const others = ["androidURL", "iosURL", "pcURL", "harmonyURL"].map((k) => v[k]).filter((x) => typeof x === "string" && x.length > 0);
@@ -1676,7 +1850,7 @@ function renderInlineAudio(prop) {
1676
1850
  if (bg) attrs.push(`background_color='${bg}'`);
1677
1851
  const fill = typeof prop.fillColor === "string" ? prop.fillColor : typeof prop.fill_color === "string" ? prop.fill_color : void 0;
1678
1852
  if (fill) attrs.push(`fill_color='${fill}'`);
1679
- const urlObj = isRecord2(prop.url) ? prop.url : void 0;
1853
+ const urlObj = isRecord3(prop.url) ? prop.url : void 0;
1680
1854
  if (urlObj) {
1681
1855
  if (typeof urlObj.url === "string" && urlObj.url) attrs.push(`fallback_url='${urlObj.url}'`);
1682
1856
  if (typeof urlObj.pcURL === "string" && urlObj.pcURL) attrs.push(`fallback_pc_url='${urlObj.pcURL}'`);
@@ -1690,9 +1864,9 @@ function renderInlineAudio(prop) {
1690
1864
  } else if (typeof prop.fallback_url === "string" && prop.fallback_url) {
1691
1865
  attrs.push(`fallback_url='${prop.fallback_url}'`);
1692
1866
  }
1693
- const fb = isRecord2(prop.fallbackText) ? prop.fallbackText : isRecord2(prop.fallback_text) ? prop.fallback_text : void 0;
1867
+ const fb = isRecord3(prop.fallbackText) ? prop.fallbackText : isRecord3(prop.fallback_text) ? prop.fallback_text : void 0;
1694
1868
  if (fb) {
1695
- const fbProp = isRecord2(fb.property) ? fb.property : fb;
1869
+ const fbProp = isRecord3(fb.property) ? fb.property : fb;
1696
1870
  const fbContent = typeof fbProp.content === "string" ? fbProp.content : typeof fb.content === "string" ? fb.content : "";
1697
1871
  if (fbContent) attrs.push(`fallback_text='${fbContent}'`);
1698
1872
  }
@@ -1716,7 +1890,7 @@ function rebuildMarkdown(property, ctx) {
1716
1890
  if (rawKey === "elements" || rawKey === "markdownElements" || rawKey === "originTag") continue;
1717
1891
  if (rawKey === "udIcon") continue;
1718
1892
  if (rawKey === "textStyle") {
1719
- const ts = isRecord2(rawValue) ? rawValue : {};
1893
+ const ts = isRecord3(rawValue) ? rawValue : {};
1720
1894
  const size = typeof ts.size === "string" ? ts.size : void 0;
1721
1895
  if (size) out.text_size = size;
1722
1896
  continue;
@@ -1792,7 +1966,7 @@ function renderChildren(children, ctx) {
1792
1966
  buffer = [];
1793
1967
  }
1794
1968
  for (const child of children) {
1795
- if (!isRecord2(child)) continue;
1969
+ if (!isRecord3(child)) continue;
1796
1970
  const inline = childToInlineSegment(child, ctx);
1797
1971
  if (inline) {
1798
1972
  buffer.push(inline);
@@ -1806,8 +1980,8 @@ function renderChildren(children, ctx) {
1806
1980
  }
1807
1981
  function childToInlineSegment(child, ctx) {
1808
1982
  const tag = child.tag;
1809
- const prop = isRecord2(child.property) ? child.property : {};
1810
- const ts = isRecord2(prop.textStyle) ? prop.textStyle : void 0;
1983
+ const prop = isRecord3(child.property) ? child.property : {};
1984
+ const ts = isRecord3(prop.textStyle) ? prop.textStyle : void 0;
1811
1985
  const { bold, color, colorKind } = resolveInlineStyle(ts, ctx);
1812
1986
  switch (tag) {
1813
1987
  case "plain_text":
@@ -1826,7 +2000,7 @@ function childToInlineSegment(child, ctx) {
1826
2000
  };
1827
2001
  case "link": {
1828
2002
  const text = typeof prop.content === "string" ? prop.content : "";
1829
- const urlObj = isRecord2(prop.url) ? prop.url : void 0;
2003
+ const urlObj = isRecord3(prop.url) ? prop.url : void 0;
1830
2004
  const url = urlObj && typeof urlObj.url === "string" ? urlObj.url : "";
1831
2005
  return { content: `[${text}](${url})`, bold, color, colorKind };
1832
2006
  }
@@ -1838,8 +2012,8 @@ function childToInlineSegment(child, ctx) {
1838
2012
  }
1839
2013
  case "text_tag": {
1840
2014
  const tagColor = typeof prop.color === "string" ? prop.color : void 0;
1841
- const inner = isRecord2(prop.text) ? prop.text : void 0;
1842
- const innerProp = inner && isRecord2(inner.property) ? inner.property : void 0;
2015
+ const inner = isRecord3(prop.text) ? prop.text : void 0;
2016
+ const innerProp = inner && isRecord3(inner.property) ? inner.property : void 0;
1843
2017
  const innerContent = innerProp && typeof innerProp.content === "string" ? innerProp.content : "";
1844
2018
  const rendered = tagColor ? `<text_tag color='${tagColor}'>${innerContent}</text_tag>` : `<text_tag>${innerContent}</text_tag>`;
1845
2019
  return { content: rendered, bold: false };
@@ -1863,11 +2037,11 @@ function childToInlineSegment(child, ctx) {
1863
2037
  }
1864
2038
  function childToMarkdown(child, ctx) {
1865
2039
  const tag = child.tag;
1866
- const prop = isRecord2(child.property) ? child.property : {};
2040
+ const prop = isRecord3(child.property) ? child.property : {};
1867
2041
  switch (tag) {
1868
2042
  case "plain_text": {
1869
2043
  const content = typeof prop.content === "string" ? prop.content : "";
1870
- const ts = isRecord2(prop.textStyle) ? prop.textStyle : void 0;
2044
+ const ts = isRecord3(prop.textStyle) ? prop.textStyle : void 0;
1871
2045
  const { bold, color } = resolveInlineStyle(ts, ctx);
1872
2046
  return wrapEmphasis(content, bold, color);
1873
2047
  }
@@ -1890,7 +2064,7 @@ function childToMarkdown(child, ctx) {
1890
2064
  return renderInlineAudio(prop);
1891
2065
  case "link": {
1892
2066
  const text = typeof prop.content === "string" ? prop.content : "";
1893
- const urlObj = isRecord2(prop.url) ? prop.url : void 0;
2067
+ const urlObj = isRecord3(prop.url) ? prop.url : void 0;
1894
2068
  const url = urlObj && typeof urlObj.url === "string" ? urlObj.url : "";
1895
2069
  return `[${text}](${url})`;
1896
2070
  }
@@ -1900,8 +2074,8 @@ function childToMarkdown(child, ctx) {
1900
2074
  }
1901
2075
  case "text_tag": {
1902
2076
  const color = typeof prop.color === "string" ? prop.color : void 0;
1903
- const inner = isRecord2(prop.text) ? prop.text : void 0;
1904
- const innerProp = inner && isRecord2(inner.property) ? inner.property : void 0;
2077
+ const inner = isRecord3(prop.text) ? prop.text : void 0;
2078
+ const innerProp = inner && isRecord3(inner.property) ? inner.property : void 0;
1905
2079
  const innerContent = innerProp && typeof innerProp.content === "string" ? innerProp.content : "";
1906
2080
  if (color) return `<text_tag color='${color}'>${innerContent}</text_tag>`;
1907
2081
  return `<text_tag>${innerContent}</text_tag>`;
@@ -1910,11 +2084,11 @@ function childToMarkdown(child, ctx) {
1910
2084
  const lang = typeof prop.language === "string" ? prop.language : "";
1911
2085
  const blocks = Array.isArray(prop.contents) ? prop.contents : [];
1912
2086
  const lines = blocks.map((blk) => {
1913
- if (!isRecord2(blk)) return "";
2087
+ if (!isRecord3(blk)) return "";
1914
2088
  const inner = Array.isArray(blk.contents) ? blk.contents : [];
1915
2089
  let line = "";
1916
2090
  for (const seg of inner) {
1917
- if (isRecord2(seg) && typeof seg.content === "string") line += seg.content;
2091
+ if (isRecord3(seg) && typeof seg.content === "string") line += seg.content;
1918
2092
  }
1919
2093
  return line;
1920
2094
  });
@@ -1930,14 +2104,14 @@ ${body}
1930
2104
  const lines = [];
1931
2105
  const levelCounters = [];
1932
2106
  for (const item of items) {
1933
- if (!isRecord2(item)) continue;
2107
+ if (!isRecord3(item)) continue;
1934
2108
  const level = typeof item.level === "number" ? item.level : 0;
1935
2109
  const type = typeof item.type === "string" ? item.type : "ul";
1936
2110
  const indent = " ".repeat(level);
1937
2111
  const inner = Array.isArray(item.elements) ? item.elements : [];
1938
2112
  let text = "";
1939
2113
  for (const seg of inner) {
1940
- if (!isRecord2(seg)) continue;
2114
+ if (!isRecord3(seg)) continue;
1941
2115
  text += childToMarkdown(seg, ctx);
1942
2116
  }
1943
2117
  if (type === "ol") {
@@ -1966,7 +2140,7 @@ ${lines.join("\n")}
1966
2140
  const inner = Array.isArray(prop.elements) ? prop.elements : [];
1967
2141
  let body = "";
1968
2142
  for (const seg of inner) {
1969
- if (isRecord2(seg)) body += childToMarkdown(seg, ctx);
2143
+ if (isRecord3(seg)) body += childToMarkdown(seg, ctx);
1970
2144
  }
1971
2145
  return `
1972
2146
 
@@ -1982,18 +2156,18 @@ ${"#".repeat(level)} ${body}
1982
2156
  const rows = Array.isArray(prop.rows) ? prop.rows : [];
1983
2157
  if (columns.length === 0) return "";
1984
2158
  const headers = columns.map(
1985
- (col) => isRecord2(col) && typeof col.displayName === "string" ? col.displayName : ""
2159
+ (col) => isRecord3(col) && typeof col.displayName === "string" ? col.displayName : ""
1986
2160
  );
1987
2161
  const headerLine = `| ${headers.join(" | ")} |`;
1988
2162
  const separator = `| ${columns.map(() => "--------").join(" | ")} |`;
1989
2163
  const bodyLines = rows.map((row) => {
1990
- if (!isRecord2(row)) return `| ${columns.map(() => "").join(" | ")} |`;
2164
+ if (!isRecord3(row)) return `| ${columns.map(() => "").join(" | ")} |`;
1991
2165
  const cells = columns.map((col) => {
1992
- const name = isRecord2(col) && typeof col.name === "string" ? col.name : "";
1993
- const cell = isRecord2(row[name]) ? row[name] : void 0;
1994
- const data = cell && isRecord2(cell.data) ? cell.data : void 0;
2166
+ const name = isRecord3(col) && typeof col.name === "string" ? col.name : "";
2167
+ const cell = isRecord3(row[name]) ? row[name] : void 0;
2168
+ const data = cell && isRecord3(cell.data) ? cell.data : void 0;
1995
2169
  if (!data || data.tag !== "markdown") return "";
1996
- const cellProp = isRecord2(data.property) ? data.property : {};
2170
+ const cellProp = isRecord3(data.property) ? data.property : {};
1997
2171
  const inner = Array.isArray(cellProp.elements) ? cellProp.elements : [];
1998
2172
  const { content: text } = renderChildren(inner, ctx);
1999
2173
  return text.replace(/\|/g, "\\|").replace(/\n/g, " ");
@@ -2012,7 +2186,7 @@ ${bodyLines.join("\n")}
2012
2186
  const inner = Array.isArray(prop.elements) ? prop.elements : [];
2013
2187
  let body = "";
2014
2188
  for (const seg of inner) {
2015
- if (isRecord2(seg)) body += childToMarkdown(seg, ctx);
2189
+ if (isRecord3(seg)) body += childToMarkdown(seg, ctx);
2016
2190
  }
2017
2191
  return `
2018
2192
 
@@ -2027,14 +2201,14 @@ ${bodyLines.join("\n")}
2027
2201
  function convertGeneric(value, ctx) {
2028
2202
  if (Array.isArray(value)) {
2029
2203
  return value.map((item) => {
2030
- if (isRecord2(item) && typeof item.tag === "string" && isRecord2(item.property)) {
2204
+ if (isRecord3(item) && typeof item.tag === "string" && isRecord3(item.property)) {
2031
2205
  return unwrap(item, ctx);
2032
2206
  }
2033
2207
  return convertGeneric(item, ctx);
2034
2208
  });
2035
2209
  }
2036
- if (isRecord2(value)) {
2037
- if (typeof value.tag === "string" && isRecord2(value.property)) {
2210
+ if (isRecord3(value)) {
2211
+ if (typeof value.tag === "string" && isRecord3(value.property)) {
2038
2212
  return unwrap(value, ctx);
2039
2213
  }
2040
2214
  if (hasSide(value)) {
@@ -2051,7 +2225,7 @@ function convertGeneric(value, ctx) {
2051
2225
  }
2052
2226
  return value;
2053
2227
  }
2054
- function isRecord2(v) {
2228
+ function isRecord3(v) {
2055
2229
  return typeof v === "object" && v !== null && !Array.isArray(v);
2056
2230
  }
2057
2231
  function resolveAttachmentImgKey(rawValue, ctx) {
@@ -2067,7 +2241,7 @@ function normalizeVideoCover(rawValue, ctx) {
2067
2241
  const imgKey2 = resolveAttachmentImgKey(rawValue, ctx);
2068
2242
  return imgKey2 ? { img_key: imgKey2 } : void 0;
2069
2243
  }
2070
- if (!isRecord2(rawValue)) return void 0;
2244
+ if (!isRecord3(rawValue)) return void 0;
2071
2245
  if (typeof rawValue.img_key === "string" && rawValue.img_key) {
2072
2246
  return { img_key: rawValue.img_key };
2073
2247
  }
@@ -2076,17 +2250,17 @@ function normalizeVideoCover(rawValue, ctx) {
2076
2250
  return imgKey ? { img_key: imgKey } : void 0;
2077
2251
  }
2078
2252
  function hasSide(v) {
2079
- return ("top" in v || "bottom" in v || "left" in v || "right" in v) && Object.values(v).some((side) => isRecord2(side) && "type" in side && "value" in side);
2253
+ return ("top" in v || "bottom" in v || "left" in v || "right" in v) && Object.values(v).some((side) => isRecord3(side) && "type" in side && "value" in side);
2080
2254
  }
2081
2255
  function formatBox(v) {
2082
2256
  return `${pixelOf(v.top)}px ${pixelOf(v.right)}px ${pixelOf(v.bottom)}px ${pixelOf(v.left)}px`;
2083
2257
  }
2084
2258
  function isPixelScalar(v) {
2085
- if (!isRecord2(v)) return false;
2259
+ if (!isRecord3(v)) return false;
2086
2260
  return typeof v.type === "string" && v.type.includes("pixels") && typeof v.value === "number";
2087
2261
  }
2088
2262
  function pixelOf(side) {
2089
- if (!isRecord2(side)) return 0;
2263
+ if (!isRecord3(side)) return 0;
2090
2264
  const v = side.value;
2091
2265
  if (typeof v === "number") return v;
2092
2266
  if (typeof v === "string") {
@@ -2107,8 +2281,8 @@ function rawToDsl(raw) {
2107
2281
  return raw;
2108
2282
  }
2109
2283
  }
2110
- if (!isRecord2(raw)) return raw;
2111
- if (typeof raw.json_card === "string" || isRecord2(raw.json_card)) {
2284
+ if (!isRecord3(raw)) return raw;
2285
+ if (typeof raw.json_card === "string" || isRecord3(raw.json_card)) {
2112
2286
  let inner = raw.json_card;
2113
2287
  if (typeof inner === "string") {
2114
2288
  try {
@@ -2117,16 +2291,16 @@ function rawToDsl(raw) {
2117
2291
  return raw;
2118
2292
  }
2119
2293
  }
2120
- const attachment = isRecord2(raw.json_attachment) ? raw.json_attachment : {};
2294
+ const attachment = isRecord3(raw.json_attachment) ? raw.json_attachment : {};
2121
2295
  const ctx = makeCtx({
2122
- images: isRecord2(attachment.images) ? attachment.images : {},
2123
- atUsers: isRecord2(attachment.at_users) ? attachment.at_users : {}
2296
+ images: isRecord3(attachment.images) ? attachment.images : {},
2297
+ atUsers: isRecord3(attachment.at_users) ? attachment.at_users : {}
2124
2298
  });
2125
2299
  return convertRoot(inner, ctx);
2126
2300
  }
2127
- if (isRecord2(raw.card)) {
2301
+ if (isRecord3(raw.card)) {
2128
2302
  const card = raw.card;
2129
- if (typeof card.json_card === "string" || isRecord2(card.json_card)) {
2303
+ if (typeof card.json_card === "string" || isRecord3(card.json_card)) {
2130
2304
  return rawToDsl(card);
2131
2305
  }
2132
2306
  return convertRoot(card, makeCtx());
@@ -2141,4 +2315,4 @@ function degradeUnknown(el) {
2141
2315
  return { tag: "unknown", raw_tag: rawTag, fallback: el };
2142
2316
  }
2143
2317
 
2144
- export { createColorRegistry, degradeUnknown, dslToRaw, isCustomHexColor, isRawCardEnvelope, normalizeStoredCardColors, rawCardToDsl, rawToDsl, readThemeColorDark, readThemeColorLight, registerColorEntry, resolveCustomBackgroundLight, resolveTextStyleColor, resolveTextStyleCustomColorPair, themePairToColorEntry };
2318
+ export { createColorRegistry, degradeUnknown, dslToRaw, isCustomHexColor, isRawCardEnvelope, normalizeStoredCardColors, rawCardToDsl, rawToDsl, readThemeColorDark, readThemeColorLight, registerColorEntry, resolveCustomBackgroundLight, resolveCustomBorderLight, resolveTextStyleColor, resolveTextStyleCustomColorPair, themePairToColorEntry };