@open-feishu-card/adapter 0.3.13 → 0.3.15

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 CHANGED
@@ -1188,13 +1188,6 @@ function normalizeStoredCardColors(dsl, preRegistered) {
1188
1188
  light_mode: "rgba(100,106,115,1)",
1189
1189
  dark_mode: "rgba(166,166,166,1)"
1190
1190
  };
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
1191
  const config = dsl.config && typeof dsl.config === "object" ? dsl.config : {};
1199
1192
  dsl.config = config;
1200
1193
  const style = config.style && typeof config.style === "object" ? config.style : {};
@@ -1227,48 +1220,6 @@ function normalizeStoredCardColors(dsl, preRegistered) {
1227
1220
  applyDefaultFontColors(dsl.body);
1228
1221
  }
1229
1222
  }
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
1223
  function normalizeMarkdownInlineHexColors(obj, ensureAlias, keepFontTags = false) {
1273
1224
  const content = obj.content;
1274
1225
  const hexColor = (raw) => {
@@ -1732,7 +1683,14 @@ function unwrap(node, ctx) {
1732
1683
  const tp = isRecord3(text.property) ? text.property : {};
1733
1684
  const content = typeof tp.content === "string" ? tp.content : "";
1734
1685
  const textAlign = typeof tp.textAlign === "string" ? tp.textAlign : "left";
1735
- out.text = { tag: "plain_text", content, text_align: textAlign };
1686
+ const outText = { tag: "plain_text", content, text_align: textAlign };
1687
+ const ts = isRecord3(tp.textStyle) ? tp.textStyle : void 0;
1688
+ if (ts && typeof ts.size === "string") outText.text_size = ts.size;
1689
+ const { color } = resolveInlineStyle(ts, ctx);
1690
+ if (color) outText.text_color = color;
1691
+ out.text = outText;
1692
+ if (isRecord3(property.margin) && hasSide(property.margin)) out.margin = formatBox(property.margin);
1693
+ else if (typeof property.margin === "string") out.margin = property.margin;
1736
1694
  if (isRecord3(property.icon)) {
1737
1695
  out.icon = unwrap(property.icon, ctx);
1738
1696
  }
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
@@ -1186,13 +1186,6 @@ function normalizeStoredCardColors(dsl, preRegistered) {
1186
1186
  light_mode: "rgba(100,106,115,1)",
1187
1187
  dark_mode: "rgba(166,166,166,1)"
1188
1188
  };
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
1189
  const config = dsl.config && typeof dsl.config === "object" ? dsl.config : {};
1197
1190
  dsl.config = config;
1198
1191
  const style = config.style && typeof config.style === "object" ? config.style : {};
@@ -1225,48 +1218,6 @@ function normalizeStoredCardColors(dsl, preRegistered) {
1225
1218
  applyDefaultFontColors(dsl.body);
1226
1219
  }
1227
1220
  }
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
1221
  function normalizeMarkdownInlineHexColors(obj, ensureAlias, keepFontTags = false) {
1271
1222
  const content = obj.content;
1272
1223
  const hexColor = (raw) => {
@@ -1730,7 +1681,14 @@ function unwrap(node, ctx) {
1730
1681
  const tp = isRecord3(text.property) ? text.property : {};
1731
1682
  const content = typeof tp.content === "string" ? tp.content : "";
1732
1683
  const textAlign = typeof tp.textAlign === "string" ? tp.textAlign : "left";
1733
- out.text = { tag: "plain_text", content, text_align: textAlign };
1684
+ const outText = { tag: "plain_text", content, text_align: textAlign };
1685
+ const ts = isRecord3(tp.textStyle) ? tp.textStyle : void 0;
1686
+ if (ts && typeof ts.size === "string") outText.text_size = ts.size;
1687
+ const { color } = resolveInlineStyle(ts, ctx);
1688
+ if (color) outText.text_color = color;
1689
+ out.text = outText;
1690
+ if (isRecord3(property.margin) && hasSide(property.margin)) out.margin = formatBox(property.margin);
1691
+ else if (typeof property.margin === "string") out.margin = property.margin;
1734
1692
  if (isRecord3(property.icon)) {
1735
1693
  out.icon = unwrap(property.icon, ctx);
1736
1694
  }
@@ -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;;;;GAIG;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,CA+HN"}
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"}
@@ -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;AAorDD;;;;;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"}
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;AA8rDD;;;;;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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-feishu-card/adapter",
3
- "version": "0.3.13",
3
+ "version": "0.3.15",
4
4
  "description": "公开 DSL 与飞书内部 RAW JSON 的双向适配器;raw→DSL 对齐 feishu-raw-card-to-dsl",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",