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