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