@open-feishu-card/adapter 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +148 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +148 -2
- package/dist/normalize-stored-colors.d.ts +14 -0
- package/dist/normalize-stored-colors.d.ts.map +1 -0
- package/dist/raw-to-dsl.d.ts.map +1 -1
- package/package.json +3 -2
package/dist/index.cjs
CHANGED
|
@@ -642,6 +642,10 @@ function convertHeader(header) {
|
|
|
642
642
|
const property = {};
|
|
643
643
|
for (const [k, v] of Object.entries(header)) {
|
|
644
644
|
if (k === "tag") continue;
|
|
645
|
+
if (k === "title" || k === "subtitle") {
|
|
646
|
+
property[k] = wrapHeaderText(v);
|
|
647
|
+
continue;
|
|
648
|
+
}
|
|
645
649
|
if (TEXT_LEAF_KEYS.has(k)) {
|
|
646
650
|
property[k] = wrapTextLeaf(v);
|
|
647
651
|
continue;
|
|
@@ -806,6 +810,22 @@ function wrapTextLeaf(v) {
|
|
|
806
810
|
}
|
|
807
811
|
return { tag: "plain_text", property: { content: "" } };
|
|
808
812
|
}
|
|
813
|
+
function wrapHeaderText(v) {
|
|
814
|
+
if (typeof v === "string") return { tag: "plain_text", property: { content: v } };
|
|
815
|
+
if (!isRecord(v)) return { tag: "plain_text", property: { content: "" } };
|
|
816
|
+
const tag = typeof v.tag === "string" ? v.tag : "plain_text";
|
|
817
|
+
const content = typeof v.content === "string" ? v.content : "";
|
|
818
|
+
if (tag === "lark_md" || tag === "markdown") {
|
|
819
|
+
return {
|
|
820
|
+
tag: "markdown",
|
|
821
|
+
property: {
|
|
822
|
+
elements: parseMarkdown(content),
|
|
823
|
+
originTag: "lark_md"
|
|
824
|
+
}
|
|
825
|
+
};
|
|
826
|
+
}
|
|
827
|
+
return wrapTextLeaf(v);
|
|
828
|
+
}
|
|
809
829
|
function behaviorsToActions(behaviors) {
|
|
810
830
|
const out = [];
|
|
811
831
|
for (const b of behaviors) {
|
|
@@ -962,10 +982,32 @@ function convertConfig(_node) {
|
|
|
962
982
|
return { update_multi: true };
|
|
963
983
|
}
|
|
964
984
|
function convertHeader2(node, ctx) {
|
|
965
|
-
const property = isRecord2(node.property) ? node.property :
|
|
985
|
+
const property = isRecord2(node.property) ? node.property : node;
|
|
966
986
|
const out = convertProperty(property, "header", ctx);
|
|
987
|
+
delete out.tag;
|
|
967
988
|
return out;
|
|
968
989
|
}
|
|
990
|
+
function convertHeaderText(rawValue, ctx) {
|
|
991
|
+
const tag = typeof rawValue.tag === "string" ? rawValue.tag : "";
|
|
992
|
+
const wrapped = isRecord2(rawValue.property);
|
|
993
|
+
const property = wrapped ? rawValue.property : rawValue;
|
|
994
|
+
if (tag === "plain_text") {
|
|
995
|
+
const content = typeof property.content === "string" ? property.content : "";
|
|
996
|
+
return { tag: "plain_text", content };
|
|
997
|
+
}
|
|
998
|
+
if (tag === "markdown" || tag === "lark_md") {
|
|
999
|
+
if (wrapped && Array.isArray(property.elements)) {
|
|
1000
|
+
const rebuilt = rebuildMarkdown(property, ctx);
|
|
1001
|
+
return { tag: "lark_md", content: typeof rebuilt.content === "string" ? rebuilt.content : "" };
|
|
1002
|
+
}
|
|
1003
|
+
const content = typeof property.content === "string" ? property.content : "";
|
|
1004
|
+
return { tag: "lark_md", content };
|
|
1005
|
+
}
|
|
1006
|
+
if (!wrapped && typeof rawValue.content === "string" && !tag) {
|
|
1007
|
+
return { tag: "plain_text", content: rawValue.content };
|
|
1008
|
+
}
|
|
1009
|
+
return void 0;
|
|
1010
|
+
}
|
|
969
1011
|
function convertBody2(node, ctx) {
|
|
970
1012
|
const property = isRecord2(node.property) ? node.property : node;
|
|
971
1013
|
return convertProperty(property, "body", ctx);
|
|
@@ -1264,6 +1306,10 @@ function convertField(rawKey, rawValue, ownerTag, ctx, siblings = {}) {
|
|
|
1264
1306
|
const p = isRecord2(rawValue.property) ? rawValue.property : {};
|
|
1265
1307
|
return [key, { tag: "plain_text", content: typeof p.content === "string" ? p.content : "" }];
|
|
1266
1308
|
}
|
|
1309
|
+
if (ownerTag === "header" && (key === "title" || key === "subtitle") && isRecord2(rawValue)) {
|
|
1310
|
+
const headerText = convertHeaderText(rawValue, ctx);
|
|
1311
|
+
if (headerText) return [key, headerText];
|
|
1312
|
+
}
|
|
1267
1313
|
if (ownerTag === "header" && key === "ud_icon" && isRecord2(rawValue) && rawValue.tag === "ud_icon") {
|
|
1268
1314
|
const p = isRecord2(rawValue.property) ? rawValue.property : {};
|
|
1269
1315
|
const token = typeof p.token === "string" ? p.token : void 0;
|
|
@@ -1815,8 +1861,109 @@ function degradeUnknown(el) {
|
|
|
1815
1861
|
return { tag: "unknown", raw_tag: rawTag, fallback: el };
|
|
1816
1862
|
}
|
|
1817
1863
|
|
|
1864
|
+
// src/normalize-stored-colors.ts
|
|
1865
|
+
function hexColorToRgba(hex) {
|
|
1866
|
+
const h = hex.trim().replace(/^#/, "");
|
|
1867
|
+
if (h.length === 8) {
|
|
1868
|
+
const r = parseInt(h.slice(0, 2), 16);
|
|
1869
|
+
const g = parseInt(h.slice(2, 4), 16);
|
|
1870
|
+
const b = parseInt(h.slice(4, 6), 16);
|
|
1871
|
+
const a = Math.round(parseInt(h.slice(6, 8), 16) / 255 * 100) / 100;
|
|
1872
|
+
return `rgba(${r},${g},${b},${a})`;
|
|
1873
|
+
}
|
|
1874
|
+
if (h.length === 6) {
|
|
1875
|
+
const r = parseInt(h.slice(0, 2), 16);
|
|
1876
|
+
const g = parseInt(h.slice(2, 4), 16);
|
|
1877
|
+
const b = parseInt(h.slice(4, 6), 16);
|
|
1878
|
+
return `rgba(${r},${g},${b},1)`;
|
|
1879
|
+
}
|
|
1880
|
+
return void 0;
|
|
1881
|
+
}
|
|
1882
|
+
function readCustomBackgroundStyle(node) {
|
|
1883
|
+
const raw = node.custom_background_style;
|
|
1884
|
+
if (!raw || typeof raw !== "object") return void 0;
|
|
1885
|
+
const o = raw;
|
|
1886
|
+
const lightRaw = typeof o.light_mode === "string" ? o.light_mode : void 0;
|
|
1887
|
+
const darkRaw = typeof o.dark_mode === "string" ? o.dark_mode : void 0;
|
|
1888
|
+
if (!lightRaw || !darkRaw) return void 0;
|
|
1889
|
+
const light = lightRaw.startsWith("#") ? hexColorToRgba(lightRaw) : lightRaw;
|
|
1890
|
+
const dark = darkRaw.startsWith("#") ? hexColorToRgba(darkRaw) : darkRaw;
|
|
1891
|
+
if (!light || !dark) return void 0;
|
|
1892
|
+
return { light_mode: light, dark_mode: dark };
|
|
1893
|
+
}
|
|
1894
|
+
function normalizeStoredCardColors(dsl) {
|
|
1895
|
+
const colorEntries = {};
|
|
1896
|
+
const styleKey = (entry) => `${entry.light_mode}|${entry.dark_mode}`;
|
|
1897
|
+
const keyToAlias = /* @__PURE__ */ new Map();
|
|
1898
|
+
let bgSeq = 0;
|
|
1899
|
+
const ensureAlias = (prefix, entry) => {
|
|
1900
|
+
const existing2 = keyToAlias.get(styleKey(entry));
|
|
1901
|
+
if (existing2) return existing2;
|
|
1902
|
+
const alias = `${prefix}-${bgSeq++}`;
|
|
1903
|
+
colorEntries[alias] = entry;
|
|
1904
|
+
keyToAlias.set(styleKey(entry), alias);
|
|
1905
|
+
return alias;
|
|
1906
|
+
};
|
|
1907
|
+
const walk = (node) => {
|
|
1908
|
+
if (Array.isArray(node)) {
|
|
1909
|
+
for (const child of node) walk(child);
|
|
1910
|
+
return;
|
|
1911
|
+
}
|
|
1912
|
+
if (!node || typeof node !== "object") return;
|
|
1913
|
+
const obj = node;
|
|
1914
|
+
if (obj.tag === "column") {
|
|
1915
|
+
const custom = readCustomBackgroundStyle(obj);
|
|
1916
|
+
if (custom) {
|
|
1917
|
+
obj.background_style = ensureAlias("cus-bg", custom);
|
|
1918
|
+
delete obj.custom_background_style;
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
for (const value of Object.values(obj)) walk(value);
|
|
1922
|
+
};
|
|
1923
|
+
walk(dsl.body);
|
|
1924
|
+
if (Object.keys(colorEntries).length === 0) return;
|
|
1925
|
+
const firstBg = colorEntries["cus-bg-0"] ?? Object.values(colorEntries)[0];
|
|
1926
|
+
if (firstBg) {
|
|
1927
|
+
const m = firstBg.light_mode.match(/^rgba\((\d+),(\d+),(\d+),/);
|
|
1928
|
+
if (m) {
|
|
1929
|
+
colorEntries["cus-accent"] = {
|
|
1930
|
+
light_mode: `rgba(${m[1]},${m[2]},${m[3]},1)`,
|
|
1931
|
+
dark_mode: firstBg.dark_mode.replace(/,\s*[\d.]+\)$/, ",1)")
|
|
1932
|
+
};
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1935
|
+
colorEntries["cus-muted"] ??= {
|
|
1936
|
+
light_mode: "rgba(100,106,115,1)",
|
|
1937
|
+
dark_mode: "rgba(166,166,166,1)"
|
|
1938
|
+
};
|
|
1939
|
+
const config = dsl.config && typeof dsl.config === "object" ? dsl.config : {};
|
|
1940
|
+
dsl.config = config;
|
|
1941
|
+
const style = config.style && typeof config.style === "object" ? config.style : {};
|
|
1942
|
+
config.style = style;
|
|
1943
|
+
const existing = style.color && typeof style.color === "object" ? style.color : {};
|
|
1944
|
+
style.color = { ...colorEntries, ...existing };
|
|
1945
|
+
if (!colorEntries["cus-accent"]) return;
|
|
1946
|
+
const applyDefaultFontColors = (node) => {
|
|
1947
|
+
if (Array.isArray(node)) {
|
|
1948
|
+
for (const child of node) applyDefaultFontColors(child);
|
|
1949
|
+
return;
|
|
1950
|
+
}
|
|
1951
|
+
if (!node || typeof node !== "object") return;
|
|
1952
|
+
const obj = node;
|
|
1953
|
+
if (obj.tag === "markdown" && obj.font_color === void 0) {
|
|
1954
|
+
const size = obj.text_size;
|
|
1955
|
+
const content = typeof obj.content === "string" ? obj.content : "";
|
|
1956
|
+
if (size === "small") obj.font_color = "cus-muted";
|
|
1957
|
+
else if (size === "heading" || content.includes("**")) obj.font_color = "cus-accent";
|
|
1958
|
+
}
|
|
1959
|
+
for (const value of Object.values(obj)) applyDefaultFontColors(value);
|
|
1960
|
+
};
|
|
1961
|
+
applyDefaultFontColors(dsl.body);
|
|
1962
|
+
}
|
|
1963
|
+
|
|
1818
1964
|
exports.degradeUnknown = degradeUnknown;
|
|
1819
1965
|
exports.dslToRaw = dslToRaw;
|
|
1820
1966
|
exports.isRawCardEnvelope = isRawCardEnvelope;
|
|
1967
|
+
exports.normalizeStoredCardColors = normalizeStoredCardColors;
|
|
1821
1968
|
exports.rawCardToDsl = rawCardToDsl;
|
|
1822
1969
|
exports.rawToDsl = rawToDsl;
|
package/dist/index.d.ts
CHANGED
|
@@ -8,5 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
export { dslToRaw } from './dsl-to-raw.js';
|
|
10
10
|
export { rawToDsl, rawCardToDsl, isRawCardEnvelope, degradeUnknown, } from './raw-to-dsl.js';
|
|
11
|
+
export { normalizeStoredCardColors } from './normalize-stored-colors.js';
|
|
12
|
+
export type { CustomColorEntry } from './normalize-stored-colors.js';
|
|
11
13
|
export type { CardElement, ElementProperty, JsonCard } from './types.js';
|
|
12
14
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,iBAAiB,EACjB,cAAc,GACf,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,iBAAiB,EACjB,cAAc,GACf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACzE,YAAY,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -640,6 +640,10 @@ function convertHeader(header) {
|
|
|
640
640
|
const property = {};
|
|
641
641
|
for (const [k, v] of Object.entries(header)) {
|
|
642
642
|
if (k === "tag") continue;
|
|
643
|
+
if (k === "title" || k === "subtitle") {
|
|
644
|
+
property[k] = wrapHeaderText(v);
|
|
645
|
+
continue;
|
|
646
|
+
}
|
|
643
647
|
if (TEXT_LEAF_KEYS.has(k)) {
|
|
644
648
|
property[k] = wrapTextLeaf(v);
|
|
645
649
|
continue;
|
|
@@ -804,6 +808,22 @@ function wrapTextLeaf(v) {
|
|
|
804
808
|
}
|
|
805
809
|
return { tag: "plain_text", property: { content: "" } };
|
|
806
810
|
}
|
|
811
|
+
function wrapHeaderText(v) {
|
|
812
|
+
if (typeof v === "string") return { tag: "plain_text", property: { content: v } };
|
|
813
|
+
if (!isRecord(v)) return { tag: "plain_text", property: { content: "" } };
|
|
814
|
+
const tag = typeof v.tag === "string" ? v.tag : "plain_text";
|
|
815
|
+
const content = typeof v.content === "string" ? v.content : "";
|
|
816
|
+
if (tag === "lark_md" || tag === "markdown") {
|
|
817
|
+
return {
|
|
818
|
+
tag: "markdown",
|
|
819
|
+
property: {
|
|
820
|
+
elements: parseMarkdown(content),
|
|
821
|
+
originTag: "lark_md"
|
|
822
|
+
}
|
|
823
|
+
};
|
|
824
|
+
}
|
|
825
|
+
return wrapTextLeaf(v);
|
|
826
|
+
}
|
|
807
827
|
function behaviorsToActions(behaviors) {
|
|
808
828
|
const out = [];
|
|
809
829
|
for (const b of behaviors) {
|
|
@@ -960,10 +980,32 @@ function convertConfig(_node) {
|
|
|
960
980
|
return { update_multi: true };
|
|
961
981
|
}
|
|
962
982
|
function convertHeader2(node, ctx) {
|
|
963
|
-
const property = isRecord2(node.property) ? node.property :
|
|
983
|
+
const property = isRecord2(node.property) ? node.property : node;
|
|
964
984
|
const out = convertProperty(property, "header", ctx);
|
|
985
|
+
delete out.tag;
|
|
965
986
|
return out;
|
|
966
987
|
}
|
|
988
|
+
function convertHeaderText(rawValue, ctx) {
|
|
989
|
+
const tag = typeof rawValue.tag === "string" ? rawValue.tag : "";
|
|
990
|
+
const wrapped = isRecord2(rawValue.property);
|
|
991
|
+
const property = wrapped ? rawValue.property : rawValue;
|
|
992
|
+
if (tag === "plain_text") {
|
|
993
|
+
const content = typeof property.content === "string" ? property.content : "";
|
|
994
|
+
return { tag: "plain_text", content };
|
|
995
|
+
}
|
|
996
|
+
if (tag === "markdown" || tag === "lark_md") {
|
|
997
|
+
if (wrapped && Array.isArray(property.elements)) {
|
|
998
|
+
const rebuilt = rebuildMarkdown(property, ctx);
|
|
999
|
+
return { tag: "lark_md", content: typeof rebuilt.content === "string" ? rebuilt.content : "" };
|
|
1000
|
+
}
|
|
1001
|
+
const content = typeof property.content === "string" ? property.content : "";
|
|
1002
|
+
return { tag: "lark_md", content };
|
|
1003
|
+
}
|
|
1004
|
+
if (!wrapped && typeof rawValue.content === "string" && !tag) {
|
|
1005
|
+
return { tag: "plain_text", content: rawValue.content };
|
|
1006
|
+
}
|
|
1007
|
+
return void 0;
|
|
1008
|
+
}
|
|
967
1009
|
function convertBody2(node, ctx) {
|
|
968
1010
|
const property = isRecord2(node.property) ? node.property : node;
|
|
969
1011
|
return convertProperty(property, "body", ctx);
|
|
@@ -1262,6 +1304,10 @@ function convertField(rawKey, rawValue, ownerTag, ctx, siblings = {}) {
|
|
|
1262
1304
|
const p = isRecord2(rawValue.property) ? rawValue.property : {};
|
|
1263
1305
|
return [key, { tag: "plain_text", content: typeof p.content === "string" ? p.content : "" }];
|
|
1264
1306
|
}
|
|
1307
|
+
if (ownerTag === "header" && (key === "title" || key === "subtitle") && isRecord2(rawValue)) {
|
|
1308
|
+
const headerText = convertHeaderText(rawValue, ctx);
|
|
1309
|
+
if (headerText) return [key, headerText];
|
|
1310
|
+
}
|
|
1265
1311
|
if (ownerTag === "header" && key === "ud_icon" && isRecord2(rawValue) && rawValue.tag === "ud_icon") {
|
|
1266
1312
|
const p = isRecord2(rawValue.property) ? rawValue.property : {};
|
|
1267
1313
|
const token = typeof p.token === "string" ? p.token : void 0;
|
|
@@ -1813,4 +1859,104 @@ function degradeUnknown(el) {
|
|
|
1813
1859
|
return { tag: "unknown", raw_tag: rawTag, fallback: el };
|
|
1814
1860
|
}
|
|
1815
1861
|
|
|
1816
|
-
|
|
1862
|
+
// src/normalize-stored-colors.ts
|
|
1863
|
+
function hexColorToRgba(hex) {
|
|
1864
|
+
const h = hex.trim().replace(/^#/, "");
|
|
1865
|
+
if (h.length === 8) {
|
|
1866
|
+
const r = parseInt(h.slice(0, 2), 16);
|
|
1867
|
+
const g = parseInt(h.slice(2, 4), 16);
|
|
1868
|
+
const b = parseInt(h.slice(4, 6), 16);
|
|
1869
|
+
const a = Math.round(parseInt(h.slice(6, 8), 16) / 255 * 100) / 100;
|
|
1870
|
+
return `rgba(${r},${g},${b},${a})`;
|
|
1871
|
+
}
|
|
1872
|
+
if (h.length === 6) {
|
|
1873
|
+
const r = parseInt(h.slice(0, 2), 16);
|
|
1874
|
+
const g = parseInt(h.slice(2, 4), 16);
|
|
1875
|
+
const b = parseInt(h.slice(4, 6), 16);
|
|
1876
|
+
return `rgba(${r},${g},${b},1)`;
|
|
1877
|
+
}
|
|
1878
|
+
return void 0;
|
|
1879
|
+
}
|
|
1880
|
+
function readCustomBackgroundStyle(node) {
|
|
1881
|
+
const raw = node.custom_background_style;
|
|
1882
|
+
if (!raw || typeof raw !== "object") return void 0;
|
|
1883
|
+
const o = raw;
|
|
1884
|
+
const lightRaw = typeof o.light_mode === "string" ? o.light_mode : void 0;
|
|
1885
|
+
const darkRaw = typeof o.dark_mode === "string" ? o.dark_mode : void 0;
|
|
1886
|
+
if (!lightRaw || !darkRaw) return void 0;
|
|
1887
|
+
const light = lightRaw.startsWith("#") ? hexColorToRgba(lightRaw) : lightRaw;
|
|
1888
|
+
const dark = darkRaw.startsWith("#") ? hexColorToRgba(darkRaw) : darkRaw;
|
|
1889
|
+
if (!light || !dark) return void 0;
|
|
1890
|
+
return { light_mode: light, dark_mode: dark };
|
|
1891
|
+
}
|
|
1892
|
+
function normalizeStoredCardColors(dsl) {
|
|
1893
|
+
const colorEntries = {};
|
|
1894
|
+
const styleKey = (entry) => `${entry.light_mode}|${entry.dark_mode}`;
|
|
1895
|
+
const keyToAlias = /* @__PURE__ */ new Map();
|
|
1896
|
+
let bgSeq = 0;
|
|
1897
|
+
const ensureAlias = (prefix, entry) => {
|
|
1898
|
+
const existing2 = keyToAlias.get(styleKey(entry));
|
|
1899
|
+
if (existing2) return existing2;
|
|
1900
|
+
const alias = `${prefix}-${bgSeq++}`;
|
|
1901
|
+
colorEntries[alias] = entry;
|
|
1902
|
+
keyToAlias.set(styleKey(entry), alias);
|
|
1903
|
+
return alias;
|
|
1904
|
+
};
|
|
1905
|
+
const walk = (node) => {
|
|
1906
|
+
if (Array.isArray(node)) {
|
|
1907
|
+
for (const child of node) walk(child);
|
|
1908
|
+
return;
|
|
1909
|
+
}
|
|
1910
|
+
if (!node || typeof node !== "object") return;
|
|
1911
|
+
const obj = node;
|
|
1912
|
+
if (obj.tag === "column") {
|
|
1913
|
+
const custom = readCustomBackgroundStyle(obj);
|
|
1914
|
+
if (custom) {
|
|
1915
|
+
obj.background_style = ensureAlias("cus-bg", custom);
|
|
1916
|
+
delete obj.custom_background_style;
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
for (const value of Object.values(obj)) walk(value);
|
|
1920
|
+
};
|
|
1921
|
+
walk(dsl.body);
|
|
1922
|
+
if (Object.keys(colorEntries).length === 0) return;
|
|
1923
|
+
const firstBg = colorEntries["cus-bg-0"] ?? Object.values(colorEntries)[0];
|
|
1924
|
+
if (firstBg) {
|
|
1925
|
+
const m = firstBg.light_mode.match(/^rgba\((\d+),(\d+),(\d+),/);
|
|
1926
|
+
if (m) {
|
|
1927
|
+
colorEntries["cus-accent"] = {
|
|
1928
|
+
light_mode: `rgba(${m[1]},${m[2]},${m[3]},1)`,
|
|
1929
|
+
dark_mode: firstBg.dark_mode.replace(/,\s*[\d.]+\)$/, ",1)")
|
|
1930
|
+
};
|
|
1931
|
+
}
|
|
1932
|
+
}
|
|
1933
|
+
colorEntries["cus-muted"] ??= {
|
|
1934
|
+
light_mode: "rgba(100,106,115,1)",
|
|
1935
|
+
dark_mode: "rgba(166,166,166,1)"
|
|
1936
|
+
};
|
|
1937
|
+
const config = dsl.config && typeof dsl.config === "object" ? dsl.config : {};
|
|
1938
|
+
dsl.config = config;
|
|
1939
|
+
const style = config.style && typeof config.style === "object" ? config.style : {};
|
|
1940
|
+
config.style = style;
|
|
1941
|
+
const existing = style.color && typeof style.color === "object" ? style.color : {};
|
|
1942
|
+
style.color = { ...colorEntries, ...existing };
|
|
1943
|
+
if (!colorEntries["cus-accent"]) return;
|
|
1944
|
+
const applyDefaultFontColors = (node) => {
|
|
1945
|
+
if (Array.isArray(node)) {
|
|
1946
|
+
for (const child of node) applyDefaultFontColors(child);
|
|
1947
|
+
return;
|
|
1948
|
+
}
|
|
1949
|
+
if (!node || typeof node !== "object") return;
|
|
1950
|
+
const obj = node;
|
|
1951
|
+
if (obj.tag === "markdown" && obj.font_color === void 0) {
|
|
1952
|
+
const size = obj.text_size;
|
|
1953
|
+
const content = typeof obj.content === "string" ? obj.content : "";
|
|
1954
|
+
if (size === "small") obj.font_color = "cus-muted";
|
|
1955
|
+
else if (size === "heading" || content.includes("**")) obj.font_color = "cus-accent";
|
|
1956
|
+
}
|
|
1957
|
+
for (const value of Object.values(obj)) applyDefaultFontColors(value);
|
|
1958
|
+
};
|
|
1959
|
+
applyDefaultFontColors(dsl.body);
|
|
1960
|
+
}
|
|
1961
|
+
|
|
1962
|
+
export { degradeUnknown, dslToRaw, isRawCardEnvelope, normalizeStoredCardColors, rawCardToDsl, rawToDsl };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 飞书存储卡片时会将 config.style.color 的 cus-N 展开为 custom_background_style(#RRGGBBAA),
|
|
3
|
+
* 并丢弃 config.style 与 markdown.font_color。回读底稿后须 normalize,否则 modify 再发会丢色。
|
|
4
|
+
*/
|
|
5
|
+
export type CustomColorEntry = {
|
|
6
|
+
light_mode: string;
|
|
7
|
+
dark_mode: string;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* 将飞书回读的 custom_background_style 还原为可再次发送的 background_style cus-N + config.style.color。
|
|
11
|
+
* 若 markdown 缺少 font_color,按 text_size / 加粗内容补 cus-accent / cus-muted(飞书回读会丢 font_color)。
|
|
12
|
+
*/
|
|
13
|
+
export declare function normalizeStoredCardColors(dsl: Record<string, unknown>): void;
|
|
14
|
+
//# sourceMappingURL=normalize-stored-colors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-stored-colors.d.ts","sourceRoot":"","sources":["../src/normalize-stored-colors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,gBAAgB,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAmCzE;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAoF5E"}
|
package/dist/raw-to-dsl.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"raw-to-dsl.d.ts","sourceRoot":"","sources":["../src/raw-to-dsl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAWH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAIzD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAcvD;
|
|
1
|
+
{"version":3,"file":"raw-to-dsl.d.ts","sourceRoot":"","sources":["../src/raw-to-dsl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAWH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAIzD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAcvD;AAmgDD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CA8C9C;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAGnF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-feishu-card/adapter",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "公开 DSL 与飞书内部 RAW JSON 的双向适配器;raw→DSL 对齐 feishu-raw-card-to-dsl",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"tsup": "^8.3.5",
|
|
22
22
|
"tsx": "^4.19.3",
|
|
23
23
|
"typescript": "^7.0.2",
|
|
24
|
-
"vitest": "^2.1.9"
|
|
24
|
+
"vitest": "^2.1.9",
|
|
25
|
+
"@open-feishu-card/schema": "0.1.4"
|
|
25
26
|
},
|
|
26
27
|
"license": "MIT",
|
|
27
28
|
"publishConfig": {
|