@open-feishu-card/adapter 0.3.14 → 0.3.16
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 +63 -57
- package/dist/index.d.ts +1 -1
- package/dist/index.js +63 -57
- package/dist/normalize-stored-colors.d.ts +2 -0
- package/dist/normalize-stored-colors.d.ts.map +1 -1
- package/dist/raw-to-dsl.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -768,6 +768,14 @@ function convertNode(node, colors) {
|
|
|
768
768
|
if (isRecord2(node) && typeof node.tag === "string") return convertEl(node, colors);
|
|
769
769
|
return node;
|
|
770
770
|
}
|
|
771
|
+
var PUBLIC_ELEMENT_ID_RE = /^[A-Za-z][A-Za-z0-9_]{0,19}$/;
|
|
772
|
+
function withRawElementId(el, raw) {
|
|
773
|
+
const eid = typeof el.element_id === "string" ? el.element_id : void 0;
|
|
774
|
+
if (eid && PUBLIC_ELEMENT_ID_RE.test(eid)) {
|
|
775
|
+
raw.id = eid;
|
|
776
|
+
}
|
|
777
|
+
return raw;
|
|
778
|
+
}
|
|
771
779
|
function convertEl(el, colors) {
|
|
772
780
|
const tag = String(el.tag);
|
|
773
781
|
if (tag === "person") {
|
|
@@ -776,13 +784,16 @@ function convertEl(el, colors) {
|
|
|
776
784
|
property.pillShaped = true;
|
|
777
785
|
delete property.style;
|
|
778
786
|
}
|
|
779
|
-
return { tag: "person_v1", property };
|
|
787
|
+
return withRawElementId(el, { tag: "person_v1", property });
|
|
780
788
|
}
|
|
781
789
|
if (tag === "avatar") {
|
|
782
|
-
return { tag: "avatar", property: buildProperty(el, "avatar", colors) };
|
|
790
|
+
return withRawElementId(el, { tag: "avatar", property: buildProperty(el, "avatar", colors) });
|
|
783
791
|
}
|
|
784
792
|
if (tag === "picker_date") {
|
|
785
|
-
return
|
|
793
|
+
return withRawElementId(el, {
|
|
794
|
+
tag: "date_picker",
|
|
795
|
+
property: buildProperty(el, "date_picker", colors)
|
|
796
|
+
});
|
|
786
797
|
}
|
|
787
798
|
if (tag === "markdown" || tag === "lark_md") {
|
|
788
799
|
const property = buildProperty(el, "markdown", colors);
|
|
@@ -794,10 +805,10 @@ function convertEl(el, colors) {
|
|
|
794
805
|
}
|
|
795
806
|
delete property.content;
|
|
796
807
|
delete property.font_color;
|
|
797
|
-
return { tag: "markdown", property };
|
|
808
|
+
return withRawElementId(el, { tag: "markdown", property });
|
|
798
809
|
}
|
|
799
810
|
if (tag === "table") {
|
|
800
|
-
return { tag, property: convertTableProperty(el, colors) };
|
|
811
|
+
return withRawElementId(el, { tag, property: convertTableProperty(el, colors) });
|
|
801
812
|
}
|
|
802
813
|
if (tag === "audio" || tag === "video") {
|
|
803
814
|
const property = buildProperty(el, tag, colors);
|
|
@@ -816,9 +827,9 @@ function convertEl(el, colors) {
|
|
|
816
827
|
delete property.image_key;
|
|
817
828
|
delete property.cover_image_key;
|
|
818
829
|
}
|
|
819
|
-
return { tag, property };
|
|
830
|
+
return withRawElementId(el, { tag, property });
|
|
820
831
|
}
|
|
821
|
-
return { tag, property: buildProperty(el, tag, colors) };
|
|
832
|
+
return withRawElementId(el, { tag, property: buildProperty(el, tag, colors) });
|
|
822
833
|
}
|
|
823
834
|
function convertTableProperty(el, colors) {
|
|
824
835
|
const property = buildProperty(el, "table", colors);
|
|
@@ -857,7 +868,14 @@ function convertTableProperty(el, colors) {
|
|
|
857
868
|
function buildProperty(el, tag, colors) {
|
|
858
869
|
const property = {};
|
|
859
870
|
for (const [k, v] of Object.entries(el)) {
|
|
860
|
-
if (k === "tag" || k === "id") continue;
|
|
871
|
+
if (k === "tag" || k === "id" || k === "element_id") continue;
|
|
872
|
+
if ((tag === "column_set" || tag === "column") && k === "action" && isRecord2(v)) {
|
|
873
|
+
const multi = isRecord2(v.multi_url) ? v.multi_url : void 0;
|
|
874
|
+
if (multi && (typeof multi.url === "string" || typeof multi.default_url === "string")) {
|
|
875
|
+
property.actions = [multiUrlToOpenUrlAction(multi)];
|
|
876
|
+
}
|
|
877
|
+
continue;
|
|
878
|
+
}
|
|
861
879
|
if ((k === "background_style" || k === "backgroundStyle") && (tag === "column" || tag === "column_set" || tag === "interactive_container")) {
|
|
862
880
|
const renamed = renameKey(k);
|
|
863
881
|
property[renamed] = v;
|
|
@@ -1007,6 +1025,16 @@ function behaviorsToActions(behaviors) {
|
|
|
1007
1025
|
}
|
|
1008
1026
|
return out;
|
|
1009
1027
|
}
|
|
1028
|
+
function multiUrlToOpenUrlAction(multi) {
|
|
1029
|
+
const url = typeof multi.url === "string" ? multi.url : typeof multi.default_url === "string" ? multi.default_url : "";
|
|
1030
|
+
const action = { url };
|
|
1031
|
+
if (typeof multi.pc_url === "string" && multi.pc_url) action.pcURL = multi.pc_url;
|
|
1032
|
+
if (typeof multi.ios_url === "string" && multi.ios_url) action.iosURL = multi.ios_url;
|
|
1033
|
+
if (typeof multi.android_url === "string" && multi.android_url) {
|
|
1034
|
+
action.androidURL = multi.android_url;
|
|
1035
|
+
}
|
|
1036
|
+
return { type: "open_url", action };
|
|
1037
|
+
}
|
|
1010
1038
|
function normalizeUrl(v) {
|
|
1011
1039
|
if (typeof v === "string") return v;
|
|
1012
1040
|
if (isRecord2(v)) return v;
|
|
@@ -1188,13 +1216,6 @@ function normalizeStoredCardColors(dsl, preRegistered) {
|
|
|
1188
1216
|
light_mode: "rgba(100,106,115,1)",
|
|
1189
1217
|
dark_mode: "rgba(166,166,166,1)"
|
|
1190
1218
|
};
|
|
1191
|
-
const aliasRenames = /* @__PURE__ */ new Map();
|
|
1192
|
-
for (const to of ["cus-accent", "cus-muted"]) {
|
|
1193
|
-
for (const [from, target] of unifyMatchingAlias(colorEntries, "cus-text", to)) {
|
|
1194
|
-
aliasRenames.set(from, target);
|
|
1195
|
-
}
|
|
1196
|
-
}
|
|
1197
|
-
remapColorReferences(dsl.body, aliasRenames);
|
|
1198
1219
|
const config = dsl.config && typeof dsl.config === "object" ? dsl.config : {};
|
|
1199
1220
|
dsl.config = config;
|
|
1200
1221
|
const style = config.style && typeof config.style === "object" ? config.style : {};
|
|
@@ -1227,48 +1248,6 @@ function normalizeStoredCardColors(dsl, preRegistered) {
|
|
|
1227
1248
|
applyDefaultFontColors(dsl.body);
|
|
1228
1249
|
}
|
|
1229
1250
|
}
|
|
1230
|
-
function unifyMatchingAlias(entries, fromPrefix, to) {
|
|
1231
|
-
const renames = /* @__PURE__ */ new Map();
|
|
1232
|
-
const target = entries[to];
|
|
1233
|
-
if (!target) return renames;
|
|
1234
|
-
for (const alias of Object.keys(entries)) {
|
|
1235
|
-
if (alias === to) continue;
|
|
1236
|
-
if (!alias.startsWith(`${fromPrefix}-`) && alias !== fromPrefix) continue;
|
|
1237
|
-
const entry = entries[alias];
|
|
1238
|
-
const matches = to === "cus-accent" || to === "cus-muted" ? entry.light_mode === target.light_mode : colorEntryKey(entry) === colorEntryKey(target);
|
|
1239
|
-
if (matches) {
|
|
1240
|
-
renames.set(alias, to);
|
|
1241
|
-
delete entries[alias];
|
|
1242
|
-
}
|
|
1243
|
-
}
|
|
1244
|
-
return renames;
|
|
1245
|
-
}
|
|
1246
|
-
function remapColorReferences(node, aliasRenames) {
|
|
1247
|
-
const remap = (alias) => {
|
|
1248
|
-
if (!alias) return alias;
|
|
1249
|
-
return aliasRenames.get(alias) ?? alias;
|
|
1250
|
-
};
|
|
1251
|
-
const walk = (n) => {
|
|
1252
|
-
if (Array.isArray(n)) {
|
|
1253
|
-
for (const c of n) walk(c);
|
|
1254
|
-
return;
|
|
1255
|
-
}
|
|
1256
|
-
if (!n || typeof n !== "object") return;
|
|
1257
|
-
const obj = n;
|
|
1258
|
-
if (typeof obj.font_color === "string") obj.font_color = remap(obj.font_color);
|
|
1259
|
-
if (typeof obj.content === "string" && obj.content.includes("<font")) {
|
|
1260
|
-
obj.content = obj.content.replace(
|
|
1261
|
-
/<font color=['"]([^'"]+)['"]>/g,
|
|
1262
|
-
(_m, color) => {
|
|
1263
|
-
const next = remap(color);
|
|
1264
|
-
return next ? `<font color='${next}'>` : _m;
|
|
1265
|
-
}
|
|
1266
|
-
);
|
|
1267
|
-
}
|
|
1268
|
-
for (const value of Object.values(obj)) walk(value);
|
|
1269
|
-
};
|
|
1270
|
-
walk(node);
|
|
1271
|
-
}
|
|
1272
1251
|
function normalizeMarkdownInlineHexColors(obj, ensureAlias, keepFontTags = false) {
|
|
1273
1252
|
const content = obj.content;
|
|
1274
1253
|
const hexColor = (raw) => {
|
|
@@ -1541,7 +1520,23 @@ function convertBody2(node, ctx) {
|
|
|
1541
1520
|
const property = isRecord3(node.property) ? node.property : node;
|
|
1542
1521
|
return convertProperty(property, "body", ctx);
|
|
1543
1522
|
}
|
|
1523
|
+
var PUBLIC_ELEMENT_ID_RE2 = /^[A-Za-z][A-Za-z0-9_]{0,19}$/;
|
|
1524
|
+
function isPublicElementId(id) {
|
|
1525
|
+
return PUBLIC_ELEMENT_ID_RE2.test(id);
|
|
1526
|
+
}
|
|
1527
|
+
function attachPublicElementId(node, result) {
|
|
1528
|
+
if (!isRecord3(result)) return result;
|
|
1529
|
+
if (typeof result.element_id === "string" && isPublicElementId(result.element_id)) {
|
|
1530
|
+
return result;
|
|
1531
|
+
}
|
|
1532
|
+
const rawId = typeof node.id === "string" ? node.id : typeof node.element_id === "string" ? node.element_id : void 0;
|
|
1533
|
+
if (!rawId || !isPublicElementId(rawId)) return result;
|
|
1534
|
+
return { ...result, element_id: rawId };
|
|
1535
|
+
}
|
|
1544
1536
|
function unwrap(node, ctx) {
|
|
1537
|
+
return attachPublicElementId(node, unwrapInner(node, ctx));
|
|
1538
|
+
}
|
|
1539
|
+
function unwrapInner(node, ctx) {
|
|
1545
1540
|
const tag = typeof node.tag === "string" ? node.tag : void 0;
|
|
1546
1541
|
const property = isRecord3(node.property) ? node.property : {};
|
|
1547
1542
|
if (tag === "markdown") return rebuildMarkdown(property, ctx);
|
|
@@ -1963,6 +1958,17 @@ function convertField(rawKey, rawValue, ownerTag, ctx, siblings = {}) {
|
|
|
1963
1958
|
if (behaviors.length === 0) return DROP;
|
|
1964
1959
|
return ["behaviors", behaviors];
|
|
1965
1960
|
}
|
|
1961
|
+
if ((ownerTag === "column_set" || ownerTag === "column") && key === "actions" && Array.isArray(rawValue)) {
|
|
1962
|
+
for (const a of rawValue) {
|
|
1963
|
+
if (!isRecord3(a)) continue;
|
|
1964
|
+
if (a.type !== "open_url") continue;
|
|
1965
|
+
const inner = isRecord3(a.action) ? a.action : {};
|
|
1966
|
+
const fields = projectOpenUrlFields(inner);
|
|
1967
|
+
if (!fields) continue;
|
|
1968
|
+
return ["action", { multi_url: openUrlFieldsToMultiUrl(fields) }];
|
|
1969
|
+
}
|
|
1970
|
+
return DROP;
|
|
1971
|
+
}
|
|
1966
1972
|
if (key === "border" && isRecord3(rawValue)) {
|
|
1967
1973
|
const b = rawValue;
|
|
1968
1974
|
const out = {};
|
package/dist/index.d.ts
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* @open-feishu-card/adapter
|
|
3
3
|
*
|
|
4
4
|
* 公开 DSL(JSON Schema 2.0)↔ 飞书内部 RAW JSON 的双向适配器。
|
|
5
|
+
* 目标:完全无损的双向转换(见 AGENTS.md)。
|
|
5
6
|
* - dslToRaw: 公开 DSL → 渲染器认得的 RAW 形态
|
|
6
7
|
* - rawToDsl / rawCardToDsl: RAW envelope → 公开 DSL
|
|
7
|
-
* (raw→DSL 完整对齐 feishu-raw-card-to-dsl)
|
|
8
8
|
*/
|
|
9
9
|
export { dslToRaw } from './dsl-to-raw.js';
|
|
10
10
|
export { rawToDsl, rawCardToDsl, isRawCardEnvelope, degradeUnknown, } from './raw-to-dsl.js';
|
package/dist/index.js
CHANGED
|
@@ -766,6 +766,14 @@ function convertNode(node, colors) {
|
|
|
766
766
|
if (isRecord2(node) && typeof node.tag === "string") return convertEl(node, colors);
|
|
767
767
|
return node;
|
|
768
768
|
}
|
|
769
|
+
var PUBLIC_ELEMENT_ID_RE = /^[A-Za-z][A-Za-z0-9_]{0,19}$/;
|
|
770
|
+
function withRawElementId(el, raw) {
|
|
771
|
+
const eid = typeof el.element_id === "string" ? el.element_id : void 0;
|
|
772
|
+
if (eid && PUBLIC_ELEMENT_ID_RE.test(eid)) {
|
|
773
|
+
raw.id = eid;
|
|
774
|
+
}
|
|
775
|
+
return raw;
|
|
776
|
+
}
|
|
769
777
|
function convertEl(el, colors) {
|
|
770
778
|
const tag = String(el.tag);
|
|
771
779
|
if (tag === "person") {
|
|
@@ -774,13 +782,16 @@ function convertEl(el, colors) {
|
|
|
774
782
|
property.pillShaped = true;
|
|
775
783
|
delete property.style;
|
|
776
784
|
}
|
|
777
|
-
return { tag: "person_v1", property };
|
|
785
|
+
return withRawElementId(el, { tag: "person_v1", property });
|
|
778
786
|
}
|
|
779
787
|
if (tag === "avatar") {
|
|
780
|
-
return { tag: "avatar", property: buildProperty(el, "avatar", colors) };
|
|
788
|
+
return withRawElementId(el, { tag: "avatar", property: buildProperty(el, "avatar", colors) });
|
|
781
789
|
}
|
|
782
790
|
if (tag === "picker_date") {
|
|
783
|
-
return
|
|
791
|
+
return withRawElementId(el, {
|
|
792
|
+
tag: "date_picker",
|
|
793
|
+
property: buildProperty(el, "date_picker", colors)
|
|
794
|
+
});
|
|
784
795
|
}
|
|
785
796
|
if (tag === "markdown" || tag === "lark_md") {
|
|
786
797
|
const property = buildProperty(el, "markdown", colors);
|
|
@@ -792,10 +803,10 @@ function convertEl(el, colors) {
|
|
|
792
803
|
}
|
|
793
804
|
delete property.content;
|
|
794
805
|
delete property.font_color;
|
|
795
|
-
return { tag: "markdown", property };
|
|
806
|
+
return withRawElementId(el, { tag: "markdown", property });
|
|
796
807
|
}
|
|
797
808
|
if (tag === "table") {
|
|
798
|
-
return { tag, property: convertTableProperty(el, colors) };
|
|
809
|
+
return withRawElementId(el, { tag, property: convertTableProperty(el, colors) });
|
|
799
810
|
}
|
|
800
811
|
if (tag === "audio" || tag === "video") {
|
|
801
812
|
const property = buildProperty(el, tag, colors);
|
|
@@ -814,9 +825,9 @@ function convertEl(el, colors) {
|
|
|
814
825
|
delete property.image_key;
|
|
815
826
|
delete property.cover_image_key;
|
|
816
827
|
}
|
|
817
|
-
return { tag, property };
|
|
828
|
+
return withRawElementId(el, { tag, property });
|
|
818
829
|
}
|
|
819
|
-
return { tag, property: buildProperty(el, tag, colors) };
|
|
830
|
+
return withRawElementId(el, { tag, property: buildProperty(el, tag, colors) });
|
|
820
831
|
}
|
|
821
832
|
function convertTableProperty(el, colors) {
|
|
822
833
|
const property = buildProperty(el, "table", colors);
|
|
@@ -855,7 +866,14 @@ function convertTableProperty(el, colors) {
|
|
|
855
866
|
function buildProperty(el, tag, colors) {
|
|
856
867
|
const property = {};
|
|
857
868
|
for (const [k, v] of Object.entries(el)) {
|
|
858
|
-
if (k === "tag" || k === "id") continue;
|
|
869
|
+
if (k === "tag" || k === "id" || k === "element_id") continue;
|
|
870
|
+
if ((tag === "column_set" || tag === "column") && k === "action" && isRecord2(v)) {
|
|
871
|
+
const multi = isRecord2(v.multi_url) ? v.multi_url : void 0;
|
|
872
|
+
if (multi && (typeof multi.url === "string" || typeof multi.default_url === "string")) {
|
|
873
|
+
property.actions = [multiUrlToOpenUrlAction(multi)];
|
|
874
|
+
}
|
|
875
|
+
continue;
|
|
876
|
+
}
|
|
859
877
|
if ((k === "background_style" || k === "backgroundStyle") && (tag === "column" || tag === "column_set" || tag === "interactive_container")) {
|
|
860
878
|
const renamed = renameKey(k);
|
|
861
879
|
property[renamed] = v;
|
|
@@ -1005,6 +1023,16 @@ function behaviorsToActions(behaviors) {
|
|
|
1005
1023
|
}
|
|
1006
1024
|
return out;
|
|
1007
1025
|
}
|
|
1026
|
+
function multiUrlToOpenUrlAction(multi) {
|
|
1027
|
+
const url = typeof multi.url === "string" ? multi.url : typeof multi.default_url === "string" ? multi.default_url : "";
|
|
1028
|
+
const action = { url };
|
|
1029
|
+
if (typeof multi.pc_url === "string" && multi.pc_url) action.pcURL = multi.pc_url;
|
|
1030
|
+
if (typeof multi.ios_url === "string" && multi.ios_url) action.iosURL = multi.ios_url;
|
|
1031
|
+
if (typeof multi.android_url === "string" && multi.android_url) {
|
|
1032
|
+
action.androidURL = multi.android_url;
|
|
1033
|
+
}
|
|
1034
|
+
return { type: "open_url", action };
|
|
1035
|
+
}
|
|
1008
1036
|
function normalizeUrl(v) {
|
|
1009
1037
|
if (typeof v === "string") return v;
|
|
1010
1038
|
if (isRecord2(v)) return v;
|
|
@@ -1186,13 +1214,6 @@ function normalizeStoredCardColors(dsl, preRegistered) {
|
|
|
1186
1214
|
light_mode: "rgba(100,106,115,1)",
|
|
1187
1215
|
dark_mode: "rgba(166,166,166,1)"
|
|
1188
1216
|
};
|
|
1189
|
-
const aliasRenames = /* @__PURE__ */ new Map();
|
|
1190
|
-
for (const to of ["cus-accent", "cus-muted"]) {
|
|
1191
|
-
for (const [from, target] of unifyMatchingAlias(colorEntries, "cus-text", to)) {
|
|
1192
|
-
aliasRenames.set(from, target);
|
|
1193
|
-
}
|
|
1194
|
-
}
|
|
1195
|
-
remapColorReferences(dsl.body, aliasRenames);
|
|
1196
1217
|
const config = dsl.config && typeof dsl.config === "object" ? dsl.config : {};
|
|
1197
1218
|
dsl.config = config;
|
|
1198
1219
|
const style = config.style && typeof config.style === "object" ? config.style : {};
|
|
@@ -1225,48 +1246,6 @@ function normalizeStoredCardColors(dsl, preRegistered) {
|
|
|
1225
1246
|
applyDefaultFontColors(dsl.body);
|
|
1226
1247
|
}
|
|
1227
1248
|
}
|
|
1228
|
-
function unifyMatchingAlias(entries, fromPrefix, to) {
|
|
1229
|
-
const renames = /* @__PURE__ */ new Map();
|
|
1230
|
-
const target = entries[to];
|
|
1231
|
-
if (!target) return renames;
|
|
1232
|
-
for (const alias of Object.keys(entries)) {
|
|
1233
|
-
if (alias === to) continue;
|
|
1234
|
-
if (!alias.startsWith(`${fromPrefix}-`) && alias !== fromPrefix) continue;
|
|
1235
|
-
const entry = entries[alias];
|
|
1236
|
-
const matches = to === "cus-accent" || to === "cus-muted" ? entry.light_mode === target.light_mode : colorEntryKey(entry) === colorEntryKey(target);
|
|
1237
|
-
if (matches) {
|
|
1238
|
-
renames.set(alias, to);
|
|
1239
|
-
delete entries[alias];
|
|
1240
|
-
}
|
|
1241
|
-
}
|
|
1242
|
-
return renames;
|
|
1243
|
-
}
|
|
1244
|
-
function remapColorReferences(node, aliasRenames) {
|
|
1245
|
-
const remap = (alias) => {
|
|
1246
|
-
if (!alias) return alias;
|
|
1247
|
-
return aliasRenames.get(alias) ?? alias;
|
|
1248
|
-
};
|
|
1249
|
-
const walk = (n) => {
|
|
1250
|
-
if (Array.isArray(n)) {
|
|
1251
|
-
for (const c of n) walk(c);
|
|
1252
|
-
return;
|
|
1253
|
-
}
|
|
1254
|
-
if (!n || typeof n !== "object") return;
|
|
1255
|
-
const obj = n;
|
|
1256
|
-
if (typeof obj.font_color === "string") obj.font_color = remap(obj.font_color);
|
|
1257
|
-
if (typeof obj.content === "string" && obj.content.includes("<font")) {
|
|
1258
|
-
obj.content = obj.content.replace(
|
|
1259
|
-
/<font color=['"]([^'"]+)['"]>/g,
|
|
1260
|
-
(_m, color) => {
|
|
1261
|
-
const next = remap(color);
|
|
1262
|
-
return next ? `<font color='${next}'>` : _m;
|
|
1263
|
-
}
|
|
1264
|
-
);
|
|
1265
|
-
}
|
|
1266
|
-
for (const value of Object.values(obj)) walk(value);
|
|
1267
|
-
};
|
|
1268
|
-
walk(node);
|
|
1269
|
-
}
|
|
1270
1249
|
function normalizeMarkdownInlineHexColors(obj, ensureAlias, keepFontTags = false) {
|
|
1271
1250
|
const content = obj.content;
|
|
1272
1251
|
const hexColor = (raw) => {
|
|
@@ -1539,7 +1518,23 @@ function convertBody2(node, ctx) {
|
|
|
1539
1518
|
const property = isRecord3(node.property) ? node.property : node;
|
|
1540
1519
|
return convertProperty(property, "body", ctx);
|
|
1541
1520
|
}
|
|
1521
|
+
var PUBLIC_ELEMENT_ID_RE2 = /^[A-Za-z][A-Za-z0-9_]{0,19}$/;
|
|
1522
|
+
function isPublicElementId(id) {
|
|
1523
|
+
return PUBLIC_ELEMENT_ID_RE2.test(id);
|
|
1524
|
+
}
|
|
1525
|
+
function attachPublicElementId(node, result) {
|
|
1526
|
+
if (!isRecord3(result)) return result;
|
|
1527
|
+
if (typeof result.element_id === "string" && isPublicElementId(result.element_id)) {
|
|
1528
|
+
return result;
|
|
1529
|
+
}
|
|
1530
|
+
const rawId = typeof node.id === "string" ? node.id : typeof node.element_id === "string" ? node.element_id : void 0;
|
|
1531
|
+
if (!rawId || !isPublicElementId(rawId)) return result;
|
|
1532
|
+
return { ...result, element_id: rawId };
|
|
1533
|
+
}
|
|
1542
1534
|
function unwrap(node, ctx) {
|
|
1535
|
+
return attachPublicElementId(node, unwrapInner(node, ctx));
|
|
1536
|
+
}
|
|
1537
|
+
function unwrapInner(node, ctx) {
|
|
1543
1538
|
const tag = typeof node.tag === "string" ? node.tag : void 0;
|
|
1544
1539
|
const property = isRecord3(node.property) ? node.property : {};
|
|
1545
1540
|
if (tag === "markdown") return rebuildMarkdown(property, ctx);
|
|
@@ -1961,6 +1956,17 @@ function convertField(rawKey, rawValue, ownerTag, ctx, siblings = {}) {
|
|
|
1961
1956
|
if (behaviors.length === 0) return DROP;
|
|
1962
1957
|
return ["behaviors", behaviors];
|
|
1963
1958
|
}
|
|
1959
|
+
if ((ownerTag === "column_set" || ownerTag === "column") && key === "actions" && Array.isArray(rawValue)) {
|
|
1960
|
+
for (const a of rawValue) {
|
|
1961
|
+
if (!isRecord3(a)) continue;
|
|
1962
|
+
if (a.type !== "open_url") continue;
|
|
1963
|
+
const inner = isRecord3(a.action) ? a.action : {};
|
|
1964
|
+
const fields = projectOpenUrlFields(inner);
|
|
1965
|
+
if (!fields) continue;
|
|
1966
|
+
return ["action", { multi_url: openUrlFieldsToMultiUrl(fields) }];
|
|
1967
|
+
}
|
|
1968
|
+
return DROP;
|
|
1969
|
+
}
|
|
1964
1970
|
if (key === "border" && isRecord3(rawValue)) {
|
|
1965
1971
|
const b = rawValue;
|
|
1966
1972
|
const out = {};
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* 飞书存储卡片时会将 config.style.color 的 cus-N 展开为 custom_background_style(#RRGGBBAA),
|
|
3
3
|
* 并丢弃 config.style 与 markdown 内联字色。回读底稿后须 normalize,否则 modify 再发会丢色。
|
|
4
4
|
* 公开 DSL 用 content 内 <font color='cus-N'> 表达字色(飞书发送接口不接受 markdown.font_color)。
|
|
5
|
+
*
|
|
6
|
+
* 原则:RAW↔DSL 双向无损(见 AGENTS.md)。显式字色/背景色只做 alias 登记,不得合并进语义 token。
|
|
5
7
|
*/
|
|
6
8
|
export type CustomColorEntry = {
|
|
7
9
|
light_mode: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize-stored-colors.d.ts","sourceRoot":"","sources":["../src/normalize-stored-colors.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"normalize-stored-colors.d.ts","sourceRoot":"","sources":["../src/normalize-stored-colors.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,MAAM,MAAM,gBAAgB,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzE,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC1C,sDAAsD;IACtD,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,wBAAgB,mBAAmB,IAAI,aAAa,CAEnD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAE7D;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,aAAa,EACvB,KAAK,EAAE,gBAAgB,EACvB,MAAM,EAAE,QAAQ,GAAG,UAAU,GAC5B,MAAM,CAWR;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAgB9D;AA8DD;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,aAAa,CAAC,EAAE,aAAa,GAC5B,IAAI,CA0HN"}
|
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;AAwBH,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;AAwBH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAIzD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAcvD;AAqvDD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CA8C9C;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAGnF"}
|