@open-feishu-card/adapter 0.3.4 → 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -606,6 +606,65 @@ function parseMarkdown(content) {
606
606
  return out;
607
607
  }
608
608
 
609
+ // src/expand-dsl-colors.ts
610
+ function readColorRegistry(card) {
611
+ const config = isRecord(card.config) ? card.config : void 0;
612
+ const style = config && isRecord(config.style) ? config.style : void 0;
613
+ const color = style && isRecord(style.color) ? style.color : void 0;
614
+ if (!color) return {};
615
+ const out = {};
616
+ for (const [key, value] of Object.entries(color)) {
617
+ if (!isRecord(value)) continue;
618
+ const light = typeof value.light_mode === "string" ? value.light_mode : typeof value.lightMode === "string" ? value.lightMode : void 0;
619
+ const dark = typeof value.dark_mode === "string" ? value.dark_mode : typeof value.darkMode === "string" ? value.darkMode : void 0;
620
+ if (light && dark) out[key] = { light_mode: light, dark_mode: dark };
621
+ }
622
+ return out;
623
+ }
624
+ function isCustomColorAlias(value) {
625
+ return typeof value === "string" && value.startsWith("cus-");
626
+ }
627
+ function expandBackgroundStyleAlias(style, registry) {
628
+ if (!isCustomColorAlias(style)) return void 0;
629
+ const entry = registry[style];
630
+ if (!entry) return void 0;
631
+ return { light_mode: entry.light_mode, dark_mode: entry.dark_mode };
632
+ }
633
+ function expandTextStyleColor(textStyle, registry) {
634
+ if (!textStyle) return textStyle;
635
+ const color = typeof textStyle.color === "string" ? textStyle.color.trim() : void 0;
636
+ if (!isCustomColorAlias(color)) return textStyle;
637
+ const entry = registry[color];
638
+ if (!entry) return textStyle;
639
+ const { color: _drop, ...rest } = textStyle;
640
+ return {
641
+ ...rest,
642
+ customColor: { lightMode: entry.light_mode, darkMode: entry.dark_mode }
643
+ };
644
+ }
645
+ function expandMarkdownElements(elements, registry) {
646
+ if (!Array.isArray(elements)) return elements;
647
+ return elements.map((el) => {
648
+ const property = el.property ? { ...el.property } : void 0;
649
+ if (!property) return el;
650
+ if (Array.isArray(property.elements)) {
651
+ property.elements = expandMarkdownElements(property.elements, registry);
652
+ }
653
+ if (property.textStyle) {
654
+ const expanded = expandTextStyleColor(property.textStyle, registry);
655
+ if (expanded) property.textStyle = expanded;
656
+ }
657
+ return property === el.property ? el : { ...el, property };
658
+ });
659
+ }
660
+ function wrapMarkdownContentWithFontColor(content, fontColor) {
661
+ if (!fontColor || !content || /<font\s+color/i.test(content)) return content;
662
+ return `<font color='${fontColor}'>${content}</font>`;
663
+ }
664
+ function isRecord(v) {
665
+ return typeof v === "object" && v !== null && !Array.isArray(v);
666
+ }
667
+
609
668
  // src/dsl-to-raw.ts
610
669
  var KEY_RENAME = {
611
670
  text_align: "textAlign",
@@ -631,14 +690,22 @@ var KEY_RENAME = {
631
690
  };
632
691
  var TEXT_LEAF_KEYS = /* @__PURE__ */ new Set(["title", "subtitle", "alt", "hover_tips", "placeholder"]);
633
692
  function dslToRaw(dsl) {
634
- const root = isRecord(dsl) ? dsl : {};
635
- const card = isRecord(root.card) ? root.card : isRecord(root.json_card) ? root.json_card : root;
693
+ const root = isRecord2(dsl) ? dsl : {};
694
+ const card = unwrapCard(root);
695
+ const colors = readColorRegistry(card);
636
696
  const out = { schema: typeof card.schema === "string" ? card.schema : "2.0" };
637
- if (isRecord(card.header)) out.header = convertHeader(card.header);
638
- if (isRecord(card.body)) out.body = convertBody(card.body);
697
+ if (isRecord2(card.config)) out.config = { ...card.config };
698
+ if (isRecord2(card.header)) out.header = convertHeader(card.header, colors);
699
+ if (isRecord2(card.body)) out.body = convertBody(card.body, colors);
639
700
  return out;
640
701
  }
641
- function convertHeader(header) {
702
+ function unwrapCard(root) {
703
+ if (isRecord2(root.dsl)) return root.dsl;
704
+ if (isRecord2(root.card)) return root.card;
705
+ if (isRecord2(root.json_card)) return root.json_card;
706
+ return root;
707
+ }
708
+ function convertHeader(header, colors) {
642
709
  const property = {};
643
710
  for (const [k, v] of Object.entries(header)) {
644
711
  if (k === "tag") continue;
@@ -650,32 +717,32 @@ function convertHeader(header) {
650
717
  property[k] = wrapTextLeaf(v);
651
718
  continue;
652
719
  }
653
- if ((k === "icon" || k === "ud_icon") && isRecord(v)) {
654
- property[k === "ud_icon" ? "udIcon" : "icon"] = convertEl(v);
720
+ if ((k === "icon" || k === "ud_icon") && isRecord2(v)) {
721
+ property[k === "ud_icon" ? "udIcon" : "icon"] = convertEl(v, colors);
655
722
  continue;
656
723
  }
657
724
  if (k === "text_tag_list" && Array.isArray(v)) {
658
- property.text_tag_list = v.map(convertNode);
725
+ property.text_tag_list = v.map((item) => convertNode(item, colors));
659
726
  continue;
660
727
  }
661
- property[renameKey(k)] = coerceValue(k, v);
728
+ property[renameKey(k)] = coerceValue(k, v, colors);
662
729
  }
663
730
  return { tag: "card_header", property };
664
731
  }
665
- function convertBody(body) {
666
- const property = buildProperty(body, "body");
667
- const elements = Array.isArray(body.elements) ? body.elements.map(convertNode) : [];
732
+ function convertBody(body, colors) {
733
+ const property = buildProperty(body, "body", colors);
734
+ const elements = Array.isArray(body.elements) ? body.elements.map((n) => convertNode(n, colors)) : [];
668
735
  property.elements = elements.filter(Boolean);
669
736
  return { tag: "body", property };
670
737
  }
671
- function convertNode(node) {
672
- if (isRecord(node) && typeof node.tag === "string") return convertEl(node);
738
+ function convertNode(node, colors) {
739
+ if (isRecord2(node) && typeof node.tag === "string") return convertEl(node, colors);
673
740
  return node;
674
741
  }
675
- function convertEl(el) {
742
+ function convertEl(el, colors) {
676
743
  const tag = String(el.tag);
677
744
  if (tag === "person") {
678
- const property = buildProperty(el, "person_v1");
745
+ const property = buildProperty(el, "person_v1", colors);
679
746
  if (property.style === "capsule") {
680
747
  property.pillShaped = true;
681
748
  delete property.style;
@@ -683,16 +750,22 @@ function convertEl(el) {
683
750
  return { tag: "person_v1", property };
684
751
  }
685
752
  if (tag === "markdown" || tag === "lark_md") {
686
- const property = buildProperty(el, "markdown");
687
- if (typeof el.content === "string") property.elements = parseMarkdown(el.content);
753
+ const property = buildProperty(el, "markdown", colors);
754
+ const fontColor = typeof el.font_color === "string" ? el.font_color : void 0;
755
+ let content = typeof el.content === "string" ? el.content : "";
756
+ content = wrapMarkdownContentWithFontColor(content, fontColor);
757
+ if (content) {
758
+ property.elements = expandMarkdownElements(parseMarkdown(content), colors);
759
+ }
688
760
  delete property.content;
761
+ delete property.font_color;
689
762
  return { tag: "markdown", property };
690
763
  }
691
764
  if (tag === "table") {
692
- return { tag, property: convertTableProperty(el) };
765
+ return { tag, property: convertTableProperty(el, colors) };
693
766
  }
694
767
  if (tag === "audio" || tag === "video") {
695
- const property = buildProperty(el, tag);
768
+ const property = buildProperty(el, tag, colors);
696
769
  if (tag === "audio" && el.width != null) {
697
770
  delete property.width;
698
771
  if (el.width === "fill" || el.width === "default") {
@@ -710,14 +783,14 @@ function convertEl(el) {
710
783
  }
711
784
  return { tag, property };
712
785
  }
713
- return { tag, property: buildProperty(el, tag) };
786
+ return { tag, property: buildProperty(el, tag, colors) };
714
787
  }
715
- function convertTableProperty(el) {
716
- const property = buildProperty(el, "table");
788
+ function convertTableProperty(el, colors) {
789
+ const property = buildProperty(el, "table", colors);
717
790
  const columns = Array.isArray(property.columns) ? property.columns : [];
718
791
  const mdColNames = /* @__PURE__ */ new Set();
719
792
  for (const col of columns) {
720
- if (!isRecord(col)) continue;
793
+ if (!isRecord2(col)) continue;
721
794
  const dt = col.data_type ?? col.dataType;
722
795
  if (dt === "lark_md" || dt === "markdown") {
723
796
  const name = typeof col.name === "string" ? col.name : "";
@@ -726,7 +799,7 @@ function convertTableProperty(el) {
726
799
  }
727
800
  if (!mdColNames.size || !Array.isArray(property.rows)) return property;
728
801
  property.rows = property.rows.map((row) => {
729
- if (!isRecord(row)) return row;
802
+ if (!isRecord2(row)) return row;
730
803
  const out = { ...row };
731
804
  for (const name of mdColNames) {
732
805
  const cell = out[name];
@@ -734,7 +807,10 @@ function convertTableProperty(el) {
734
807
  out[name] = {
735
808
  data: {
736
809
  tag: "markdown",
737
- property: { elements: parseMarkdown(cell), originTag: "lark_md" }
810
+ property: {
811
+ elements: expandMarkdownElements(parseMarkdown(cell), colors),
812
+ originTag: "lark_md"
813
+ }
738
814
  }
739
815
  };
740
816
  }
@@ -743,10 +819,17 @@ function convertTableProperty(el) {
743
819
  });
744
820
  return property;
745
821
  }
746
- function buildProperty(el, tag) {
822
+ function buildProperty(el, tag, colors) {
747
823
  const property = {};
748
824
  for (const [k, v] of Object.entries(el)) {
749
825
  if (k === "tag" || k === "id") continue;
826
+ if ((k === "background_style" || k === "backgroundStyle") && (tag === "column" || tag === "column_set")) {
827
+ const renamed = renameKey(k);
828
+ property[renamed] = v;
829
+ const expanded = expandBackgroundStyleAlias(v, colors);
830
+ if (expanded) property.customBackgroundStyle = expanded;
831
+ continue;
832
+ }
750
833
  if (tag === "column" && k === "width" && typeof v === "string") {
751
834
  const px = pxValue(v);
752
835
  if (px != null) {
@@ -759,15 +842,15 @@ function buildProperty(el, tag) {
759
842
  continue;
760
843
  }
761
844
  if (k === "text") {
762
- if (tag === "checker" && isRecord(v) && (v.tag === "markdown" || v.tag === "lark_md")) {
763
- property.text = convertEl(v);
845
+ if (tag === "checker" && isRecord2(v) && (v.tag === "markdown" || v.tag === "lark_md")) {
846
+ property.text = convertEl(v, colors);
764
847
  } else {
765
848
  property.text = wrapTextLeaf(v);
766
849
  }
767
850
  continue;
768
851
  }
769
- if ((k === "icon" || k === "ud_icon") && isRecord(v)) {
770
- property[k === "ud_icon" ? "udIcon" : "icon"] = convertEl(v);
852
+ if ((k === "icon" || k === "ud_icon") && isRecord2(v)) {
853
+ property[k === "ud_icon" ? "udIcon" : "icon"] = convertEl(v, colors);
771
854
  continue;
772
855
  }
773
856
  if (k === "behaviors" && Array.isArray(v)) {
@@ -778,21 +861,21 @@ function buildProperty(el, tag) {
778
861
  property.url = normalizeUrl(v);
779
862
  continue;
780
863
  }
781
- if (k === "button_area" && isRecord(v)) {
864
+ if (k === "button_area" && isRecord2(v)) {
782
865
  const area = { ...v };
783
- if (Array.isArray(v.buttons)) area.buttons = v.buttons.map(convertNode);
866
+ if (Array.isArray(v.buttons)) area.buttons = v.buttons.map((b) => convertNode(b, colors));
784
867
  property.button_area = area;
785
868
  continue;
786
869
  }
787
- property[renameKey(k)] = coerceValue(k, v);
870
+ property[renameKey(k)] = coerceValue(k, v, colors);
788
871
  }
789
872
  return property;
790
873
  }
791
- function coerceValue(key, value) {
874
+ function coerceValue(key, value, colors) {
792
875
  if ((key === "padding" || key === "margin") && typeof value === "string") {
793
876
  return parseBox(value);
794
877
  }
795
- if (Array.isArray(value)) return value.map(convertNode);
878
+ if (Array.isArray(value)) return value.map((item) => convertNode(item, colors));
796
879
  if (key === "url") return normalizeUrl(value);
797
880
  return value;
798
881
  }
@@ -801,7 +884,7 @@ function renameKey(k) {
801
884
  }
802
885
  function wrapTextLeaf(v) {
803
886
  if (typeof v === "string") return { tag: "plain_text", property: { content: v } };
804
- if (isRecord(v)) {
887
+ if (isRecord2(v)) {
805
888
  const property = { content: typeof v.content === "string" ? v.content : "" };
806
889
  if (typeof v.text_align === "string") property.textAlign = v.text_align;
807
890
  if (typeof v.text_size === "string") property.text_size = v.text_size;
@@ -812,7 +895,7 @@ function wrapTextLeaf(v) {
812
895
  }
813
896
  function wrapHeaderText(v) {
814
897
  if (typeof v === "string") return { tag: "plain_text", property: { content: v } };
815
- if (!isRecord(v)) return { tag: "plain_text", property: { content: "" } };
898
+ if (!isRecord2(v)) return { tag: "plain_text", property: { content: "" } };
816
899
  const tag = typeof v.tag === "string" ? v.tag : "plain_text";
817
900
  const content = typeof v.content === "string" ? v.content : "";
818
901
  if (tag === "lark_md" || tag === "markdown") {
@@ -829,7 +912,7 @@ function wrapHeaderText(v) {
829
912
  function behaviorsToActions(behaviors) {
830
913
  const out = [];
831
914
  for (const b of behaviors) {
832
- if (!isRecord(b)) continue;
915
+ if (!isRecord2(b)) continue;
833
916
  const type = typeof b.type === "string" ? b.type : "open_url";
834
917
  out.push({ type, action: { url: normalizeUrl(b.default_url) } });
835
918
  }
@@ -837,7 +920,7 @@ function behaviorsToActions(behaviors) {
837
920
  }
838
921
  function normalizeUrl(v) {
839
922
  if (typeof v === "string") return v;
840
- if (isRecord(v)) return v;
923
+ if (isRecord2(v)) return v;
841
924
  return v;
842
925
  }
843
926
  function parseBox(s) {
@@ -864,7 +947,7 @@ function pxValue(s) {
864
947
  const n = Number(s);
865
948
  return Number.isFinite(n) ? n : null;
866
949
  }
867
- function isRecord(v) {
950
+ function isRecord2(v) {
868
951
  return typeof v === "object" && v !== null && !Array.isArray(v);
869
952
  }
870
953
 
@@ -941,7 +1024,7 @@ function normalizeStoredCardColors(dsl, preRegistered) {
941
1024
  }
942
1025
  }
943
1026
  if (obj.tag === "markdown" && typeof obj.content === "string") {
944
- normalizeMarkdownInlineHexColors(obj, ensureAlias);
1027
+ normalizeMarkdownInlineHexColors(obj, ensureAlias, !!preRegistered);
945
1028
  }
946
1029
  for (const value of Object.values(obj)) walk(value);
947
1030
  };
@@ -976,22 +1059,24 @@ function normalizeStoredCardColors(dsl, preRegistered) {
976
1059
  const existing = style.color && typeof style.color === "object" ? style.color : {};
977
1060
  style.color = { ...colorEntries, ...existing };
978
1061
  if (!colorEntries["cus-accent"]) return;
979
- const applyDefaultFontColors = (node) => {
980
- if (Array.isArray(node)) {
981
- for (const child of node) applyDefaultFontColors(child);
982
- return;
983
- }
984
- if (!node || typeof node !== "object") return;
985
- const obj = node;
986
- if (obj.tag === "markdown" && obj.font_color === void 0) {
987
- const size = obj.text_size;
988
- const content = typeof obj.content === "string" ? obj.content : "";
989
- if (size === "small") obj.font_color = "cus-muted";
990
- else if (size === "heading" || content.includes("**")) obj.font_color = "cus-accent";
991
- }
992
- for (const value of Object.values(obj)) applyDefaultFontColors(value);
993
- };
994
- applyDefaultFontColors(dsl.body);
1062
+ if (!preRegistered) {
1063
+ const applyDefaultFontColors = (node) => {
1064
+ if (Array.isArray(node)) {
1065
+ for (const child of node) applyDefaultFontColors(child);
1066
+ return;
1067
+ }
1068
+ if (!node || typeof node !== "object") return;
1069
+ const obj = node;
1070
+ if (obj.tag === "markdown" && obj.font_color === void 0) {
1071
+ const size = obj.text_size;
1072
+ const content = typeof obj.content === "string" ? obj.content : "";
1073
+ if (size === "small") obj.font_color = "cus-muted";
1074
+ else if (size === "heading" || content.includes("**")) obj.font_color = "cus-accent";
1075
+ }
1076
+ for (const value of Object.values(obj)) applyDefaultFontColors(value);
1077
+ };
1078
+ applyDefaultFontColors(dsl.body);
1079
+ }
995
1080
  }
996
1081
  function unifyMatchingAlias(entries, fromPrefix, to) {
997
1082
  const renames = /* @__PURE__ */ new Map();
@@ -1035,7 +1120,7 @@ function remapColorReferences(node, aliasRenames) {
1035
1120
  };
1036
1121
  walk(node);
1037
1122
  }
1038
- function normalizeMarkdownInlineHexColors(obj, ensureAlias) {
1123
+ function normalizeMarkdownInlineHexColors(obj, ensureAlias, keepFontTags = false) {
1039
1124
  const content = obj.content;
1040
1125
  const hexColor = (raw) => {
1041
1126
  const v = raw.trim();
@@ -1047,7 +1132,7 @@ function normalizeMarkdownInlineHexColors(obj, ensureAlias) {
1047
1132
  return void 0;
1048
1133
  };
1049
1134
  const single = content.match(/^<font color=['"]([^'"]+)['"]\s*>([\s\S]*)<\/font>$/);
1050
- if (single) {
1135
+ if (single && !keepFontTags) {
1051
1136
  const entry = hexColor(single[1]);
1052
1137
  if (entry) {
1053
1138
  const alias = ensureAlias("cus-text", entry);
@@ -1227,12 +1312,12 @@ var VALUE_ECHO_TARGETS = {
1227
1312
  size_value: "size"
1228
1313
  };
1229
1314
  function convertRoot(root, ctx) {
1230
- if (!isRecord2(root)) return root;
1315
+ if (!isRecord3(root)) return root;
1231
1316
  const out = {};
1232
1317
  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);
1318
+ out.config = convertConfig(isRecord3(root.config) ? root.config : {});
1319
+ if (isRecord3(root.body)) out.body = convertBody2(root.body, ctx);
1320
+ if (isRecord3(root.header)) out.header = convertHeader2(root.header, ctx);
1236
1321
  normalizeStoredCardColors(out, ctx.colors);
1237
1322
  return out;
1238
1323
  }
@@ -1240,14 +1325,14 @@ function convertConfig(_node) {
1240
1325
  return { update_multi: true };
1241
1326
  }
1242
1327
  function convertHeader2(node, ctx) {
1243
- const property = isRecord2(node.property) ? node.property : node;
1328
+ const property = isRecord3(node.property) ? node.property : node;
1244
1329
  const out = convertProperty(property, "header", ctx);
1245
1330
  delete out.tag;
1246
1331
  return out;
1247
1332
  }
1248
1333
  function convertHeaderText(rawValue, ctx) {
1249
1334
  const tag = typeof rawValue.tag === "string" ? rawValue.tag : "";
1250
- const wrapped = isRecord2(rawValue.property);
1335
+ const wrapped = isRecord3(rawValue.property);
1251
1336
  const property = wrapped ? rawValue.property : rawValue;
1252
1337
  if (tag === "plain_text") {
1253
1338
  const content = typeof property.content === "string" ? property.content : "";
@@ -1267,12 +1352,12 @@ function convertHeaderText(rawValue, ctx) {
1267
1352
  return void 0;
1268
1353
  }
1269
1354
  function convertBody2(node, ctx) {
1270
- const property = isRecord2(node.property) ? node.property : node;
1355
+ const property = isRecord3(node.property) ? node.property : node;
1271
1356
  return convertProperty(property, "body", ctx);
1272
1357
  }
1273
1358
  function unwrap(node, ctx) {
1274
1359
  const tag = typeof node.tag === "string" ? node.tag : void 0;
1275
- const property = isRecord2(node.property) ? node.property : {};
1360
+ const property = isRecord3(node.property) ? node.property : {};
1276
1361
  if (tag === "markdown") return rebuildMarkdown(property, ctx);
1277
1362
  if (tag === "plain_text") {
1278
1363
  const content = typeof property.content === "string" ? property.content : "";
@@ -1286,7 +1371,7 @@ function unwrap(node, ctx) {
1286
1371
  const heightPx = isPixelScalar(property.heightValue) ? pixelOf(property.heightValue) : void 0;
1287
1372
  if (widthPx !== void 0 && heightPx !== void 0) {
1288
1373
  out.size = `${widthPx}px ${heightPx}px`;
1289
- } else if (isRecord2(property.size) && hasSide(property.size)) out.size = formatBox(property.size);
1374
+ } else if (isRecord3(property.size) && hasSide(property.size)) out.size = formatBox(property.size);
1290
1375
  else if (isPixelScalar(property.size)) out.size = `${pixelOf(property.size)}px`;
1291
1376
  else if (typeof property.size === "string") out.size = property.size;
1292
1377
  return out;
@@ -1308,7 +1393,7 @@ function unwrap(node, ctx) {
1308
1393
  const out = { tag: "table" };
1309
1394
  const rawColumns = Array.isArray(property.columns) ? property.columns : [];
1310
1395
  out.columns = rawColumns.map((col) => {
1311
- if (!isRecord2(col)) return {};
1396
+ if (!isRecord3(col)) return {};
1312
1397
  const c = {};
1313
1398
  if (typeof col.name === "string") c.name = col.name;
1314
1399
  const displayName = typeof col.displayName === "string" ? col.displayName : typeof col.display_name === "string" ? col.display_name : void 0;
@@ -1318,22 +1403,22 @@ function unwrap(node, ctx) {
1318
1403
  const hAlign = typeof col.horizontalAlign === "string" ? col.horizontalAlign : typeof col.horizontal_align === "string" ? col.horizontal_align : void 0;
1319
1404
  if (hAlign !== void 0) c.horizontal_align = hAlign;
1320
1405
  const wv = col.widthValue;
1321
- if (isRecord2(wv)) {
1406
+ if (isRecord3(wv)) {
1322
1407
  if (wv.type === "pixels" && typeof wv.value === "number") c.width = `${wv.value}px`;
1323
1408
  else if (typeof wv.value === "string") c.width = wv.value;
1324
1409
  } else if (typeof col.width === "string" || typeof col.width === "number") {
1325
1410
  c.width = col.width;
1326
1411
  }
1327
- if (isRecord2(col.format)) c.format = col.format;
1412
+ if (isRecord3(col.format)) c.format = col.format;
1328
1413
  return c;
1329
1414
  });
1330
1415
  const rawRows = Array.isArray(property.rows) ? property.rows : [];
1331
1416
  out.rows = rawRows.map((row) => {
1332
- if (!isRecord2(row)) return {};
1417
+ if (!isRecord3(row)) return {};
1333
1418
  const r = {};
1334
1419
  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)) {
1420
+ let value = isRecord3(cell) && "data" in cell ? cell.data : cell;
1421
+ if (isRecord3(value) && value.tag === "markdown" && isRecord3(value.property)) {
1337
1422
  const elements = Array.isArray(value.property.elements) ? value.property.elements : [];
1338
1423
  value = renderChildren(elements, ctx).content;
1339
1424
  }
@@ -1341,13 +1426,13 @@ function unwrap(node, ctx) {
1341
1426
  }
1342
1427
  return r;
1343
1428
  });
1344
- if (isRecord2(property.headerStyle)) {
1429
+ if (isRecord3(property.headerStyle)) {
1345
1430
  const hs = {};
1346
1431
  for (const [k, v] of Object.entries(property.headerStyle)) {
1347
1432
  const sk = snake(k);
1348
1433
  if (sk === "platform_text_size") continue;
1349
1434
  if (sk === "lines_value") {
1350
- if (isRecord2(v) && typeof v.value === "number") hs.lines = v.value;
1435
+ if (isRecord3(v) && typeof v.value === "number") hs.lines = v.value;
1351
1436
  continue;
1352
1437
  }
1353
1438
  hs[sk] = v;
@@ -1355,7 +1440,7 @@ function unwrap(node, ctx) {
1355
1440
  out.header_style = hs;
1356
1441
  }
1357
1442
  const rhv = property.rowHeightValue;
1358
- if (isRecord2(rhv) && typeof rhv.value === "string") out.row_height = rhv.value;
1443
+ if (isRecord3(rhv) && typeof rhv.value === "string") out.row_height = rhv.value;
1359
1444
  else if (typeof property.rowHeight === "string") out.row_height = property.rowHeight;
1360
1445
  if (typeof property.pageSize === "number") out.page_size = property.pageSize;
1361
1446
  if (typeof property.freezeFirstColumn === "boolean") out.freeze_first_column = property.freezeFirstColumn;
@@ -1390,7 +1475,7 @@ function unwrap(node, ctx) {
1390
1475
  if (typeof property.showAvatar === "boolean") out.show_avatar = property.showAvatar;
1391
1476
  if (typeof property.showName === "boolean") out.show_name = property.showName;
1392
1477
  if (typeof property.style === "string") out.style = property.style;
1393
- if (isRecord2(property.margin) && hasSide(property.margin)) out.margin = formatBox(property.margin);
1478
+ if (isRecord3(property.margin) && hasSide(property.margin)) out.margin = formatBox(property.margin);
1394
1479
  else if (typeof property.margin === "string") out.margin = property.margin;
1395
1480
  return out;
1396
1481
  }
@@ -1402,17 +1487,17 @@ function unwrap(node, ctx) {
1402
1487
  if (typeof property.lines === "number") out.lines = property.lines;
1403
1488
  if (typeof property.dropInvalidUserID === "boolean") out.drop_invalid_user_id = property.dropInvalidUserID;
1404
1489
  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);
1490
+ if (isRecord3(property.margin) && hasSide(property.margin)) out.margin = formatBox(property.margin);
1406
1491
  else if (typeof property.margin === "string") out.margin = property.margin;
1407
1492
  const rawPersons = Array.isArray(property.persons) ? property.persons : [];
1408
1493
  out.persons = rawPersons.map((p) => {
1409
- if (!isRecord2(p)) return void 0;
1494
+ if (!isRecord3(p)) return void 0;
1410
1495
  const id = typeof p.id === "string" ? p.id : typeof p.userID === "string" ? p.userID : void 0;
1411
1496
  return id ? { id } : void 0;
1412
1497
  }).filter((p) => p !== void 0);
1413
- const iconSrc = isRecord2(property.icon) ? property.icon : isRecord2(property.udIcon) ? property.udIcon : void 0;
1498
+ const iconSrc = isRecord3(property.icon) ? property.icon : isRecord3(property.udIcon) ? property.udIcon : void 0;
1414
1499
  if (iconSrc) {
1415
- const ip = isRecord2(iconSrc.property) ? iconSrc.property : iconSrc;
1500
+ const ip = isRecord3(iconSrc.property) ? iconSrc.property : iconSrc;
1416
1501
  const icon = {};
1417
1502
  const iconTag = typeof iconSrc.tag === "string" ? iconSrc.tag : typeof ip.tag === "string" ? ip.tag : "standard_icon";
1418
1503
  icon.tag = iconTag === "ud_icon" ? "standard_icon" : iconTag;
@@ -1424,25 +1509,25 @@ function unwrap(node, ctx) {
1424
1509
  }
1425
1510
  return out;
1426
1511
  }
1427
- if (tag === "div" && isRecord2(property.text) && property.fields === void 0) {
1512
+ if (tag === "div" && isRecord3(property.text) && property.fields === void 0) {
1428
1513
  const text = property.text;
1429
1514
  const textTag = typeof text.tag === "string" ? text.tag : "";
1430
- if ((textTag === "markdown" || textTag === "lark_md") && isRecord2(text.property)) {
1515
+ if ((textTag === "markdown" || textTag === "lark_md") && isRecord3(text.property)) {
1431
1516
  return unwrap(text, ctx);
1432
1517
  }
1433
1518
  if (textTag === "plain_text") {
1434
1519
  const out = { tag: "div" };
1435
1520
  const widthVal = property.widthValue;
1436
- if (isRecord2(widthVal) && typeof widthVal.value === "string" && typeof widthVal.type === "string" && widthVal.type.startsWith("builtin_")) {
1521
+ if (isRecord3(widthVal) && typeof widthVal.value === "string" && typeof widthVal.type === "string" && widthVal.type.startsWith("builtin_")) {
1437
1522
  out.width = widthVal.value;
1438
1523
  } else if (typeof property.width === "string") {
1439
1524
  out.width = property.width;
1440
1525
  }
1441
- const tp = isRecord2(text.property) ? text.property : {};
1526
+ const tp = isRecord3(text.property) ? text.property : {};
1442
1527
  const content = typeof tp.content === "string" ? tp.content : "";
1443
1528
  const textAlign = typeof tp.textAlign === "string" ? tp.textAlign : "left";
1444
1529
  out.text = { tag: "plain_text", content, text_align: textAlign };
1445
- if (isRecord2(property.icon)) {
1530
+ if (isRecord3(property.icon)) {
1446
1531
  out.icon = unwrap(property.icon, ctx);
1447
1532
  }
1448
1533
  return out;
@@ -1469,7 +1554,7 @@ function convertProperty(property, ownerTag, ctx) {
1469
1554
  const echoVal = out[echoKey];
1470
1555
  const enumVal = out[enumKey];
1471
1556
  delete out[echoKey];
1472
- if (!isRecord2(echoVal)) continue;
1557
+ if (!isRecord3(echoVal)) continue;
1473
1558
  const echoType = typeof echoVal.type === "string" ? echoVal.type : "";
1474
1559
  const echoValue = echoVal.value;
1475
1560
  if (echoType.includes("pixels") && typeof echoValue === "number") {
@@ -1478,7 +1563,7 @@ function convertProperty(property, ownerTag, ctx) {
1478
1563
  }
1479
1564
  continue;
1480
1565
  }
1481
- if (echoType === "aspect_ratio" && isRecord2(echoValue)) {
1566
+ if (echoType === "aspect_ratio" && isRecord3(echoValue)) {
1482
1567
  const w = echoValue.width;
1483
1568
  const h = echoValue.height;
1484
1569
  if (typeof w === "number" && typeof h === "number") {
@@ -1486,7 +1571,7 @@ function convertProperty(property, ownerTag, ctx) {
1486
1571
  }
1487
1572
  continue;
1488
1573
  }
1489
- if (echoType === "width_height_pixels" && isRecord2(echoValue)) {
1574
+ if (echoType === "width_height_pixels" && isRecord3(echoValue)) {
1490
1575
  const w = echoValue.width;
1491
1576
  const h = echoValue.height;
1492
1577
  if (typeof w === "number" && typeof h === "number") {
@@ -1526,7 +1611,7 @@ function convertField(rawKey, rawValue, ownerTag, ctx, siblings = {}) {
1526
1611
  if (key === "actions" && Array.isArray(rawValue) && rawValue.length === 0) {
1527
1612
  return DROP;
1528
1613
  }
1529
- if ((key === "padding" || key === "margin") && isRecord2(rawValue) && hasSide(rawValue)) {
1614
+ if ((key === "padding" || key === "margin") && isRecord3(rawValue) && hasSide(rawValue)) {
1530
1615
  return [key, formatBox(rawValue)];
1531
1616
  }
1532
1617
  if (key in VALUE_ECHO_TARGETS) {
@@ -1556,25 +1641,25 @@ function convertField(rawKey, rawValue, ownerTag, ctx, siblings = {}) {
1556
1641
  return DROP;
1557
1642
  }
1558
1643
  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 : {};
1644
+ if ((key === "alt" || key === "hover_tips") && isRecord3(rawValue) && rawValue.tag === "plain_text") {
1645
+ const p = isRecord3(rawValue.property) ? rawValue.property : {};
1561
1646
  return [key, { tag: "plain_text", content: typeof p.content === "string" ? p.content : "" }];
1562
1647
  }
1563
- if (key === "text" && isRecord2(rawValue) && rawValue.tag === "plain_text") {
1564
- const p = isRecord2(rawValue.property) ? rawValue.property : {};
1648
+ if (key === "text" && isRecord3(rawValue) && rawValue.tag === "plain_text") {
1649
+ const p = isRecord3(rawValue.property) ? rawValue.property : {};
1565
1650
  return [key, { tag: "plain_text", content: typeof p.content === "string" ? p.content : "" }];
1566
1651
  }
1567
- if (ownerTag === "header" && (key === "title" || key === "subtitle") && isRecord2(rawValue)) {
1652
+ if (ownerTag === "header" && (key === "title" || key === "subtitle") && isRecord3(rawValue)) {
1568
1653
  const headerText = convertHeaderText(rawValue, ctx);
1569
1654
  if (headerText) return [key, headerText];
1570
1655
  }
1571
- if (ownerTag === "header" && key === "ud_icon" && isRecord2(rawValue) && rawValue.tag === "ud_icon") {
1572
- const p = isRecord2(rawValue.property) ? rawValue.property : {};
1656
+ if (ownerTag === "header" && key === "ud_icon" && isRecord3(rawValue) && rawValue.tag === "ud_icon") {
1657
+ const p = isRecord3(rawValue.property) ? rawValue.property : {};
1573
1658
  const token = typeof p.token === "string" ? p.token : void 0;
1574
1659
  if (!token) return DROP;
1575
1660
  return ["icon", { tag: "standard_icon", token }];
1576
1661
  }
1577
- if (ownerTag === "collapsible_panel" && key === "header" && isRecord2(rawValue)) {
1662
+ if (ownerTag === "collapsible_panel" && key === "header" && isRecord3(rawValue)) {
1578
1663
  const cleaned = {};
1579
1664
  for (const [k, v] of Object.entries(rawValue)) {
1580
1665
  const sk = snake(k);
@@ -1591,8 +1676,8 @@ function convertField(rawKey, rawValue, ownerTag, ctx, siblings = {}) {
1591
1676
  if (ownerTag === "button" && key === "actions" && Array.isArray(rawValue)) {
1592
1677
  const openUrls = [];
1593
1678
  for (const a of rawValue) {
1594
- if (!isRecord2(a)) continue;
1595
- const inner = isRecord2(a.action) ? a.action : {};
1679
+ if (!isRecord3(a)) continue;
1680
+ const inner = isRecord3(a.action) ? a.action : {};
1596
1681
  const t = typeof a.type === "string" ? a.type : void 0;
1597
1682
  if (t === "open_url" && typeof inner.url === "string") openUrls.push(inner.url);
1598
1683
  }
@@ -1607,8 +1692,8 @@ function convertField(rawKey, rawValue, ownerTag, ctx, siblings = {}) {
1607
1692
  }
1608
1693
  if (ownerTag === "interactive_container" && key === "actions" && Array.isArray(rawValue)) {
1609
1694
  const behaviors = rawValue.map((a) => {
1610
- if (!isRecord2(a)) return void 0;
1611
- const inner = isRecord2(a.action) ? a.action : {};
1695
+ if (!isRecord3(a)) return void 0;
1696
+ const inner = isRecord3(a.action) ? a.action : {};
1612
1697
  const t = typeof a.type === "string" ? a.type : void 0;
1613
1698
  if (t === "open_url" && typeof inner.url === "string") {
1614
1699
  return { type: "open_url", default_url: inner.url };
@@ -1621,7 +1706,7 @@ function convertField(rawKey, rawValue, ownerTag, ctx, siblings = {}) {
1621
1706
  if (behaviors.length === 0) return DROP;
1622
1707
  return ["behaviors", behaviors];
1623
1708
  }
1624
- if (key === "border" && isRecord2(rawValue)) {
1709
+ if (key === "border" && isRecord3(rawValue)) {
1625
1710
  const b = rawValue;
1626
1711
  const out = {};
1627
1712
  if (typeof b.borderColor === "string") out.color = b.borderColor;
@@ -1635,7 +1720,7 @@ function convertField(rawKey, rawValue, ownerTag, ctx, siblings = {}) {
1635
1720
  }
1636
1721
  return [key, out];
1637
1722
  }
1638
- if (key === "url" && isRecord2(rawValue)) {
1723
+ if (key === "url" && isRecord3(rawValue)) {
1639
1724
  const v = rawValue;
1640
1725
  const main = typeof v.url === "string" ? v.url : "";
1641
1726
  const others = ["androidURL", "iosURL", "pcURL", "harmonyURL"].map((k) => v[k]).filter((x) => typeof x === "string" && x.length > 0);
@@ -1676,7 +1761,7 @@ function renderInlineAudio(prop) {
1676
1761
  if (bg) attrs.push(`background_color='${bg}'`);
1677
1762
  const fill = typeof prop.fillColor === "string" ? prop.fillColor : typeof prop.fill_color === "string" ? prop.fill_color : void 0;
1678
1763
  if (fill) attrs.push(`fill_color='${fill}'`);
1679
- const urlObj = isRecord2(prop.url) ? prop.url : void 0;
1764
+ const urlObj = isRecord3(prop.url) ? prop.url : void 0;
1680
1765
  if (urlObj) {
1681
1766
  if (typeof urlObj.url === "string" && urlObj.url) attrs.push(`fallback_url='${urlObj.url}'`);
1682
1767
  if (typeof urlObj.pcURL === "string" && urlObj.pcURL) attrs.push(`fallback_pc_url='${urlObj.pcURL}'`);
@@ -1690,9 +1775,9 @@ function renderInlineAudio(prop) {
1690
1775
  } else if (typeof prop.fallback_url === "string" && prop.fallback_url) {
1691
1776
  attrs.push(`fallback_url='${prop.fallback_url}'`);
1692
1777
  }
1693
- const fb = isRecord2(prop.fallbackText) ? prop.fallbackText : isRecord2(prop.fallback_text) ? prop.fallback_text : void 0;
1778
+ const fb = isRecord3(prop.fallbackText) ? prop.fallbackText : isRecord3(prop.fallback_text) ? prop.fallback_text : void 0;
1694
1779
  if (fb) {
1695
- const fbProp = isRecord2(fb.property) ? fb.property : fb;
1780
+ const fbProp = isRecord3(fb.property) ? fb.property : fb;
1696
1781
  const fbContent = typeof fbProp.content === "string" ? fbProp.content : typeof fb.content === "string" ? fb.content : "";
1697
1782
  if (fbContent) attrs.push(`fallback_text='${fbContent}'`);
1698
1783
  }
@@ -1710,14 +1795,13 @@ function resolveAtUserId(prop, ctx) {
1710
1795
  function rebuildMarkdown(property, ctx) {
1711
1796
  const out = { tag: "markdown" };
1712
1797
  const elements = Array.isArray(property.elements) ? property.elements : [];
1713
- const { content, uniformFontColor } = renderChildren(elements, ctx);
1798
+ const { content } = renderChildren(elements, ctx);
1714
1799
  if (content) out.content = content;
1715
- if (uniformFontColor) out.font_color = uniformFontColor;
1716
1800
  for (const [rawKey, rawValue] of Object.entries(property)) {
1717
1801
  if (rawKey === "elements" || rawKey === "markdownElements" || rawKey === "originTag") continue;
1718
1802
  if (rawKey === "udIcon") continue;
1719
1803
  if (rawKey === "textStyle") {
1720
- const ts = isRecord2(rawValue) ? rawValue : {};
1804
+ const ts = isRecord3(rawValue) ? rawValue : {};
1721
1805
  const size = typeof ts.size === "string" ? ts.size : void 0;
1722
1806
  if (size) out.text_size = size;
1723
1807
  continue;
@@ -1730,7 +1814,7 @@ function rebuildMarkdown(property, ctx) {
1730
1814
  }
1731
1815
  return out;
1732
1816
  }
1733
- function wrapEmphasis(text, bold, color, colorKind, inlineCustomFont = false) {
1817
+ function wrapEmphasis(text, bold, color) {
1734
1818
  if (!bold && !color) return text;
1735
1819
  const lead = text.match(/^\s*/)[0];
1736
1820
  const trail = text.match(/\s*$/)[0];
@@ -1738,10 +1822,7 @@ function wrapEmphasis(text, bold, color, colorKind, inlineCustomFont = false) {
1738
1822
  if (core.length === 0) return text;
1739
1823
  let wrapped = core;
1740
1824
  if (bold) wrapped = `**${wrapped}**`;
1741
- if (color) {
1742
- if (colorKind === "enum") wrapped = `<font color='${color}'>${wrapped}</font>`;
1743
- else if (colorKind === "custom" && inlineCustomFont) wrapped = `<font color='${color}'>${wrapped}</font>`;
1744
- }
1825
+ if (color) wrapped = `<font color='${color}'>${wrapped}</font>`;
1745
1826
  return lead + wrapped + trail;
1746
1827
  }
1747
1828
  function resolveInlineStyle(ts, ctx) {
@@ -1769,20 +1850,14 @@ function resolveInlineStyle(ts, ctx) {
1769
1850
  function renderChildren(children, ctx) {
1770
1851
  let out = "";
1771
1852
  let buffer = [];
1772
- let uniformFontColor;
1773
1853
  function flushBuffer() {
1774
1854
  if (buffer.length === 0) return;
1775
- const customColors = buffer.filter((s) => s.colorKind === "custom" && s.color).map((s) => s.color);
1776
- const hasEnumColor = buffer.some((s) => s.colorKind === "enum" && s.color);
1777
- const uniformCustom = customColors.length > 0 && !hasEnumColor && customColors.every((c) => c === customColors[0]) ? customColors[0] : void 0;
1778
- if (uniformCustom) uniformFontColor = uniformCustom;
1779
1855
  let group = [];
1780
1856
  function emitGroup() {
1781
1857
  if (group.length === 0) return;
1782
1858
  const inner = group.map((s) => s.content).join("");
1783
- const { bold, color, colorKind } = group[0];
1784
- const inlineCustomFont = colorKind === "custom" && !!color && color !== uniformCustom;
1785
- out += wrapEmphasis(inner, bold, color, colorKind, inlineCustomFont);
1859
+ const { bold, color } = group[0];
1860
+ out += wrapEmphasis(inner, bold, color);
1786
1861
  group = [];
1787
1862
  }
1788
1863
  for (const seg of buffer) {
@@ -1802,7 +1877,7 @@ function renderChildren(children, ctx) {
1802
1877
  buffer = [];
1803
1878
  }
1804
1879
  for (const child of children) {
1805
- if (!isRecord2(child)) continue;
1880
+ if (!isRecord3(child)) continue;
1806
1881
  const inline = childToInlineSegment(child, ctx);
1807
1882
  if (inline) {
1808
1883
  buffer.push(inline);
@@ -1812,12 +1887,12 @@ function renderChildren(children, ctx) {
1812
1887
  out += childToMarkdown(child, ctx);
1813
1888
  }
1814
1889
  flushBuffer();
1815
- return { content: out, uniformFontColor };
1890
+ return { content: out };
1816
1891
  }
1817
1892
  function childToInlineSegment(child, ctx) {
1818
1893
  const tag = child.tag;
1819
- const prop = isRecord2(child.property) ? child.property : {};
1820
- const ts = isRecord2(prop.textStyle) ? prop.textStyle : void 0;
1894
+ const prop = isRecord3(child.property) ? child.property : {};
1895
+ const ts = isRecord3(prop.textStyle) ? prop.textStyle : void 0;
1821
1896
  const { bold, color, colorKind } = resolveInlineStyle(ts, ctx);
1822
1897
  switch (tag) {
1823
1898
  case "plain_text":
@@ -1836,7 +1911,7 @@ function childToInlineSegment(child, ctx) {
1836
1911
  };
1837
1912
  case "link": {
1838
1913
  const text = typeof prop.content === "string" ? prop.content : "";
1839
- const urlObj = isRecord2(prop.url) ? prop.url : void 0;
1914
+ const urlObj = isRecord3(prop.url) ? prop.url : void 0;
1840
1915
  const url = urlObj && typeof urlObj.url === "string" ? urlObj.url : "";
1841
1916
  return { content: `[${text}](${url})`, bold, color, colorKind };
1842
1917
  }
@@ -1848,8 +1923,8 @@ function childToInlineSegment(child, ctx) {
1848
1923
  }
1849
1924
  case "text_tag": {
1850
1925
  const tagColor = typeof prop.color === "string" ? prop.color : void 0;
1851
- const inner = isRecord2(prop.text) ? prop.text : void 0;
1852
- const innerProp = inner && isRecord2(inner.property) ? inner.property : void 0;
1926
+ const inner = isRecord3(prop.text) ? prop.text : void 0;
1927
+ const innerProp = inner && isRecord3(inner.property) ? inner.property : void 0;
1853
1928
  const innerContent = innerProp && typeof innerProp.content === "string" ? innerProp.content : "";
1854
1929
  const rendered = tagColor ? `<text_tag color='${tagColor}'>${innerContent}</text_tag>` : `<text_tag>${innerContent}</text_tag>`;
1855
1930
  return { content: rendered, bold: false };
@@ -1873,13 +1948,13 @@ function childToInlineSegment(child, ctx) {
1873
1948
  }
1874
1949
  function childToMarkdown(child, ctx) {
1875
1950
  const tag = child.tag;
1876
- const prop = isRecord2(child.property) ? child.property : {};
1951
+ const prop = isRecord3(child.property) ? child.property : {};
1877
1952
  switch (tag) {
1878
1953
  case "plain_text": {
1879
1954
  const content = typeof prop.content === "string" ? prop.content : "";
1880
- const ts = isRecord2(prop.textStyle) ? prop.textStyle : void 0;
1881
- const { bold, color, colorKind } = resolveInlineStyle(ts, ctx);
1882
- return wrapEmphasis(content, bold, color, colorKind, colorKind === "custom");
1955
+ const ts = isRecord3(prop.textStyle) ? prop.textStyle : void 0;
1956
+ const { bold, color } = resolveInlineStyle(ts, ctx);
1957
+ return wrapEmphasis(content, bold, color);
1883
1958
  }
1884
1959
  case "br":
1885
1960
  return "\n";
@@ -1900,7 +1975,7 @@ function childToMarkdown(child, ctx) {
1900
1975
  return renderInlineAudio(prop);
1901
1976
  case "link": {
1902
1977
  const text = typeof prop.content === "string" ? prop.content : "";
1903
- const urlObj = isRecord2(prop.url) ? prop.url : void 0;
1978
+ const urlObj = isRecord3(prop.url) ? prop.url : void 0;
1904
1979
  const url = urlObj && typeof urlObj.url === "string" ? urlObj.url : "";
1905
1980
  return `[${text}](${url})`;
1906
1981
  }
@@ -1910,8 +1985,8 @@ function childToMarkdown(child, ctx) {
1910
1985
  }
1911
1986
  case "text_tag": {
1912
1987
  const color = typeof prop.color === "string" ? prop.color : void 0;
1913
- const inner = isRecord2(prop.text) ? prop.text : void 0;
1914
- const innerProp = inner && isRecord2(inner.property) ? inner.property : void 0;
1988
+ const inner = isRecord3(prop.text) ? prop.text : void 0;
1989
+ const innerProp = inner && isRecord3(inner.property) ? inner.property : void 0;
1915
1990
  const innerContent = innerProp && typeof innerProp.content === "string" ? innerProp.content : "";
1916
1991
  if (color) return `<text_tag color='${color}'>${innerContent}</text_tag>`;
1917
1992
  return `<text_tag>${innerContent}</text_tag>`;
@@ -1920,11 +1995,11 @@ function childToMarkdown(child, ctx) {
1920
1995
  const lang = typeof prop.language === "string" ? prop.language : "";
1921
1996
  const blocks = Array.isArray(prop.contents) ? prop.contents : [];
1922
1997
  const lines = blocks.map((blk) => {
1923
- if (!isRecord2(blk)) return "";
1998
+ if (!isRecord3(blk)) return "";
1924
1999
  const inner = Array.isArray(blk.contents) ? blk.contents : [];
1925
2000
  let line = "";
1926
2001
  for (const seg of inner) {
1927
- if (isRecord2(seg) && typeof seg.content === "string") line += seg.content;
2002
+ if (isRecord3(seg) && typeof seg.content === "string") line += seg.content;
1928
2003
  }
1929
2004
  return line;
1930
2005
  });
@@ -1940,14 +2015,14 @@ ${body}
1940
2015
  const lines = [];
1941
2016
  const levelCounters = [];
1942
2017
  for (const item of items) {
1943
- if (!isRecord2(item)) continue;
2018
+ if (!isRecord3(item)) continue;
1944
2019
  const level = typeof item.level === "number" ? item.level : 0;
1945
2020
  const type = typeof item.type === "string" ? item.type : "ul";
1946
2021
  const indent = " ".repeat(level);
1947
2022
  const inner = Array.isArray(item.elements) ? item.elements : [];
1948
2023
  let text = "";
1949
2024
  for (const seg of inner) {
1950
- if (!isRecord2(seg)) continue;
2025
+ if (!isRecord3(seg)) continue;
1951
2026
  text += childToMarkdown(seg, ctx);
1952
2027
  }
1953
2028
  if (type === "ol") {
@@ -1976,7 +2051,7 @@ ${lines.join("\n")}
1976
2051
  const inner = Array.isArray(prop.elements) ? prop.elements : [];
1977
2052
  let body = "";
1978
2053
  for (const seg of inner) {
1979
- if (isRecord2(seg)) body += childToMarkdown(seg, ctx);
2054
+ if (isRecord3(seg)) body += childToMarkdown(seg, ctx);
1980
2055
  }
1981
2056
  return `
1982
2057
 
@@ -1992,18 +2067,18 @@ ${"#".repeat(level)} ${body}
1992
2067
  const rows = Array.isArray(prop.rows) ? prop.rows : [];
1993
2068
  if (columns.length === 0) return "";
1994
2069
  const headers = columns.map(
1995
- (col) => isRecord2(col) && typeof col.displayName === "string" ? col.displayName : ""
2070
+ (col) => isRecord3(col) && typeof col.displayName === "string" ? col.displayName : ""
1996
2071
  );
1997
2072
  const headerLine = `| ${headers.join(" | ")} |`;
1998
2073
  const separator = `| ${columns.map(() => "--------").join(" | ")} |`;
1999
2074
  const bodyLines = rows.map((row) => {
2000
- if (!isRecord2(row)) return `| ${columns.map(() => "").join(" | ")} |`;
2075
+ if (!isRecord3(row)) return `| ${columns.map(() => "").join(" | ")} |`;
2001
2076
  const cells = columns.map((col) => {
2002
- const name = isRecord2(col) && typeof col.name === "string" ? col.name : "";
2003
- const cell = isRecord2(row[name]) ? row[name] : void 0;
2004
- const data = cell && isRecord2(cell.data) ? cell.data : void 0;
2077
+ const name = isRecord3(col) && typeof col.name === "string" ? col.name : "";
2078
+ const cell = isRecord3(row[name]) ? row[name] : void 0;
2079
+ const data = cell && isRecord3(cell.data) ? cell.data : void 0;
2005
2080
  if (!data || data.tag !== "markdown") return "";
2006
- const cellProp = isRecord2(data.property) ? data.property : {};
2081
+ const cellProp = isRecord3(data.property) ? data.property : {};
2007
2082
  const inner = Array.isArray(cellProp.elements) ? cellProp.elements : [];
2008
2083
  const { content: text } = renderChildren(inner, ctx);
2009
2084
  return text.replace(/\|/g, "\\|").replace(/\n/g, " ");
@@ -2022,7 +2097,7 @@ ${bodyLines.join("\n")}
2022
2097
  const inner = Array.isArray(prop.elements) ? prop.elements : [];
2023
2098
  let body = "";
2024
2099
  for (const seg of inner) {
2025
- if (isRecord2(seg)) body += childToMarkdown(seg, ctx);
2100
+ if (isRecord3(seg)) body += childToMarkdown(seg, ctx);
2026
2101
  }
2027
2102
  return `
2028
2103
 
@@ -2037,14 +2112,14 @@ ${bodyLines.join("\n")}
2037
2112
  function convertGeneric(value, ctx) {
2038
2113
  if (Array.isArray(value)) {
2039
2114
  return value.map((item) => {
2040
- if (isRecord2(item) && typeof item.tag === "string" && isRecord2(item.property)) {
2115
+ if (isRecord3(item) && typeof item.tag === "string" && isRecord3(item.property)) {
2041
2116
  return unwrap(item, ctx);
2042
2117
  }
2043
2118
  return convertGeneric(item, ctx);
2044
2119
  });
2045
2120
  }
2046
- if (isRecord2(value)) {
2047
- if (typeof value.tag === "string" && isRecord2(value.property)) {
2121
+ if (isRecord3(value)) {
2122
+ if (typeof value.tag === "string" && isRecord3(value.property)) {
2048
2123
  return unwrap(value, ctx);
2049
2124
  }
2050
2125
  if (hasSide(value)) {
@@ -2061,7 +2136,7 @@ function convertGeneric(value, ctx) {
2061
2136
  }
2062
2137
  return value;
2063
2138
  }
2064
- function isRecord2(v) {
2139
+ function isRecord3(v) {
2065
2140
  return typeof v === "object" && v !== null && !Array.isArray(v);
2066
2141
  }
2067
2142
  function resolveAttachmentImgKey(rawValue, ctx) {
@@ -2077,7 +2152,7 @@ function normalizeVideoCover(rawValue, ctx) {
2077
2152
  const imgKey2 = resolveAttachmentImgKey(rawValue, ctx);
2078
2153
  return imgKey2 ? { img_key: imgKey2 } : void 0;
2079
2154
  }
2080
- if (!isRecord2(rawValue)) return void 0;
2155
+ if (!isRecord3(rawValue)) return void 0;
2081
2156
  if (typeof rawValue.img_key === "string" && rawValue.img_key) {
2082
2157
  return { img_key: rawValue.img_key };
2083
2158
  }
@@ -2086,17 +2161,17 @@ function normalizeVideoCover(rawValue, ctx) {
2086
2161
  return imgKey ? { img_key: imgKey } : void 0;
2087
2162
  }
2088
2163
  function hasSide(v) {
2089
- 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);
2164
+ 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);
2090
2165
  }
2091
2166
  function formatBox(v) {
2092
2167
  return `${pixelOf(v.top)}px ${pixelOf(v.right)}px ${pixelOf(v.bottom)}px ${pixelOf(v.left)}px`;
2093
2168
  }
2094
2169
  function isPixelScalar(v) {
2095
- if (!isRecord2(v)) return false;
2170
+ if (!isRecord3(v)) return false;
2096
2171
  return typeof v.type === "string" && v.type.includes("pixels") && typeof v.value === "number";
2097
2172
  }
2098
2173
  function pixelOf(side) {
2099
- if (!isRecord2(side)) return 0;
2174
+ if (!isRecord3(side)) return 0;
2100
2175
  const v = side.value;
2101
2176
  if (typeof v === "number") return v;
2102
2177
  if (typeof v === "string") {
@@ -2117,8 +2192,8 @@ function rawToDsl(raw) {
2117
2192
  return raw;
2118
2193
  }
2119
2194
  }
2120
- if (!isRecord2(raw)) return raw;
2121
- if (typeof raw.json_card === "string" || isRecord2(raw.json_card)) {
2195
+ if (!isRecord3(raw)) return raw;
2196
+ if (typeof raw.json_card === "string" || isRecord3(raw.json_card)) {
2122
2197
  let inner = raw.json_card;
2123
2198
  if (typeof inner === "string") {
2124
2199
  try {
@@ -2127,16 +2202,16 @@ function rawToDsl(raw) {
2127
2202
  return raw;
2128
2203
  }
2129
2204
  }
2130
- const attachment = isRecord2(raw.json_attachment) ? raw.json_attachment : {};
2205
+ const attachment = isRecord3(raw.json_attachment) ? raw.json_attachment : {};
2131
2206
  const ctx = makeCtx({
2132
- images: isRecord2(attachment.images) ? attachment.images : {},
2133
- atUsers: isRecord2(attachment.at_users) ? attachment.at_users : {}
2207
+ images: isRecord3(attachment.images) ? attachment.images : {},
2208
+ atUsers: isRecord3(attachment.at_users) ? attachment.at_users : {}
2134
2209
  });
2135
2210
  return convertRoot(inner, ctx);
2136
2211
  }
2137
- if (isRecord2(raw.card)) {
2212
+ if (isRecord3(raw.card)) {
2138
2213
  const card = raw.card;
2139
- if (typeof card.json_card === "string" || isRecord2(card.json_card)) {
2214
+ if (typeof card.json_card === "string" || isRecord3(card.json_card)) {
2140
2215
  return rawToDsl(card);
2141
2216
  }
2142
2217
  return convertRoot(card, makeCtx());