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