@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/custom-colors.d.ts +1 -1
- package/dist/dsl-to-raw.d.ts.map +1 -1
- package/dist/expand-dsl-colors.d.ts +24 -0
- package/dist/expand-dsl-colors.d.ts.map +1 -0
- package/dist/index.cjs +241 -166
- package/dist/index.js +241 -166
- package/dist/normalize-stored-colors.d.ts.map +1 -1
- package/dist/raw-to-dsl.d.ts.map +1 -1
- package/dist/types.d.ts +12 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
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 =
|
|
635
|
-
const card =
|
|
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 (
|
|
638
|
-
if (
|
|
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
|
|
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") &&
|
|
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 (
|
|
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
|
-
|
|
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 (!
|
|
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 (!
|
|
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: {
|
|
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" &&
|
|
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") &&
|
|
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" &&
|
|
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 (
|
|
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 (!
|
|
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 (!
|
|
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 (
|
|
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
|
|
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
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
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 (!
|
|
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(
|
|
1234
|
-
if (
|
|
1235
|
-
if (
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 (
|
|
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 (!
|
|
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 (
|
|
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 (
|
|
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 (!
|
|
1417
|
+
if (!isRecord3(row)) return {};
|
|
1333
1418
|
const r = {};
|
|
1334
1419
|
for (const [k, cell] of Object.entries(row)) {
|
|
1335
|
-
let value =
|
|
1336
|
-
if (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (!
|
|
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 =
|
|
1498
|
+
const iconSrc = isRecord3(property.icon) ? property.icon : isRecord3(property.udIcon) ? property.udIcon : void 0;
|
|
1414
1499
|
if (iconSrc) {
|
|
1415
|
-
const ip =
|
|
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" &&
|
|
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") &&
|
|
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 (
|
|
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 =
|
|
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 (
|
|
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 (!
|
|
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" &&
|
|
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" &&
|
|
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") &&
|
|
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") &&
|
|
1560
|
-
const p =
|
|
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" &&
|
|
1564
|
-
const p =
|
|
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") &&
|
|
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" &&
|
|
1572
|
-
const p =
|
|
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" &&
|
|
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 (!
|
|
1595
|
-
const inner =
|
|
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 (!
|
|
1611
|
-
const inner =
|
|
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" &&
|
|
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" &&
|
|
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 =
|
|
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 =
|
|
1778
|
+
const fb = isRecord3(prop.fallbackText) ? prop.fallbackText : isRecord3(prop.fallback_text) ? prop.fallback_text : void 0;
|
|
1694
1779
|
if (fb) {
|
|
1695
|
-
const fbProp =
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
1784
|
-
|
|
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 (!
|
|
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
|
|
1890
|
+
return { content: out };
|
|
1816
1891
|
}
|
|
1817
1892
|
function childToInlineSegment(child, ctx) {
|
|
1818
1893
|
const tag = child.tag;
|
|
1819
|
-
const prop =
|
|
1820
|
-
const ts =
|
|
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 =
|
|
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 =
|
|
1852
|
-
const innerProp = inner &&
|
|
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 =
|
|
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 =
|
|
1881
|
-
const { bold, color
|
|
1882
|
-
return wrapEmphasis(content, bold, color
|
|
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 =
|
|
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 =
|
|
1914
|
-
const innerProp = inner &&
|
|
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 (!
|
|
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 (
|
|
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 (!
|
|
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 (!
|
|
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 (
|
|
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) =>
|
|
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 (!
|
|
2075
|
+
if (!isRecord3(row)) return `| ${columns.map(() => "").join(" | ")} |`;
|
|
2001
2076
|
const cells = columns.map((col) => {
|
|
2002
|
-
const name =
|
|
2003
|
-
const cell =
|
|
2004
|
-
const data = cell &&
|
|
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 =
|
|
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 (
|
|
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 (
|
|
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 (
|
|
2047
|
-
if (typeof value.tag === "string" &&
|
|
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
|
|
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 (!
|
|
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) =>
|
|
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 (!
|
|
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 (!
|
|
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 (!
|
|
2121
|
-
if (typeof raw.json_card === "string" ||
|
|
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 =
|
|
2205
|
+
const attachment = isRecord3(raw.json_attachment) ? raw.json_attachment : {};
|
|
2131
2206
|
const ctx = makeCtx({
|
|
2132
|
-
images:
|
|
2133
|
-
atUsers:
|
|
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 (
|
|
2212
|
+
if (isRecord3(raw.card)) {
|
|
2138
2213
|
const card = raw.card;
|
|
2139
|
-
if (typeof card.json_card === "string" ||
|
|
2214
|
+
if (typeof card.json_card === "string" || isRecord3(card.json_card)) {
|
|
2140
2215
|
return rawToDsl(card);
|
|
2141
2216
|
}
|
|
2142
2217
|
return convertRoot(card, makeCtx());
|