@open-feishu-card/adapter 0.2.0 → 0.3.0

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.
@@ -1,8 +1,62 @@
1
- /** 未知/私有组件自动降级:包一层 unknown 节点,原始 RAW 保留在 fallback。 */
1
+ /**
2
+ * RAW → 公开 DSL(JSON Schema 2.0)。
3
+ *
4
+ * 本文件完整移植自 `feishu-raw-card-to-dsl`(保持算法与行为一致)。
5
+ * monorepo 额外导出 `rawToDsl`(兼容本地 RAW / envelope)与可选的 `degradeUnknown`。
6
+ *
7
+ * Convert the editor-internal "raw_card_content" payload returned by
8
+ * `im.message.get?card_msg_content_type=raw_card_content` into the public
9
+ * JSON Schema 2.0 DSL we author and send.
10
+ *
11
+ * The raw payload differs from the public DSL in several ways:
12
+ * 1. Every node is wrapped as { id, tag, property: { ...real fields... } }.
13
+ * 2. Field names are camelCase (textAlign, backgroundStyle, imageID, ...).
14
+ * 3. Box fields (padding/margin) are objects { bottom:{type,value}, ... }
15
+ * instead of "Tpx Rpx Bpx Lpx" strings; scalar pixels (corner_radius,
16
+ * icon size) are similarly objectified.
17
+ * 4. Images carry imageID (numeric) which indexes into a separate
18
+ * json_attachment.images table to recover the real img_key.
19
+ * 5. Markdown is split into per-segment children (plain_text / link / br /
20
+ * at_all / person_v1 / text_tag / code_span / ...) under a wrapper
21
+ * element with originTag:'markdown'; we re-stitch them back into a
22
+ * single content string with inline markers.
23
+ * 6. Header is wrapped as `tag: 'card_header'` and its icon shows up as a
24
+ * sibling `udIcon` wrapper around an inner `ud_icon` element.
25
+ * 7. Editor mirrors the same value twice — a coarse enum (width:'auto')
26
+ * alongside a precise echo (widthValue:{type:'pixels',value:72}). We
27
+ * project the precise echo back onto the enum when it disagrees.
28
+ * 8. Most nodes carry editor defaults (disabled:false, vertical_align:
29
+ * 'top', flex_mode:'none', background_style:'default') that the public
30
+ * DSL omits. We strip them.
31
+ * 9. The whole thing is double-stringified into body.content as
32
+ * { json_card: "<stringified card>", json_attachment: { images, at_users? } }.
33
+ *
34
+ * Why we do this: the documented user_card_content path drops fields whose
35
+ * values match a server-side default (notably `column.padding` on a column
36
+ * with `background_style`), which silently breaks layouts on round-trip.
37
+ * The raw payload preserves them. We project raw -> public DSL on the read
38
+ * path so downstream code (patch_lark_card, archives, the model's mental
39
+ * model) keeps working against the only format that has a public spec.
40
+ *
41
+ * No public spec exists for the raw payload. The mapping below is sample-
42
+ * driven, derived from diffing rawCardToDsl(raw) against archived public DSL
43
+ * for ~250 cards we previously sent. When the converter encounters something
44
+ * it does not recognize, it keeps the original key/value (snake-cased) so
45
+ * downstream sees an unknown field rather than silently losing data.
46
+ */
47
+ export declare function isRawCardEnvelope(value: unknown): boolean;
48
+ export declare function rawCardToDsl(envelope: unknown): unknown;
49
+ /**
50
+ * Flexible entry used by this monorepo:
51
+ * - raw envelope (`json_card` + `card_schema`) → same as `rawCardToDsl`
52
+ * - already-parsed `{ json_card: object, json_attachment? }`
53
+ * - `{ card: ... }` / bare card (e.g. output of `dslToRaw`) → `convertRoot`
54
+ */
55
+ export declare function rawToDsl(raw: unknown): unknown;
56
+ /**
57
+ * Optional helper: wrap a private/unknown element as
58
+ * `{ tag: 'unknown', raw_tag, fallback }`.
59
+ * Not applied automatically by `rawToDsl` / `rawCardToDsl` (parity with upstream).
60
+ */
2
61
  export declare function degradeUnknown(el: Record<string, unknown>): Record<string, unknown>;
3
- /** RAW envelope(可能是 {json_card:{card}} / {card} / 直接 card)→ DSL 卡片对象 */
4
- export declare function rawToDsl(raw: unknown): Record<string, unknown>;
5
- /** DSL → RAW(重导出,统一入口) */
6
- export { dslToRaw } from './dsl-to-raw.js';
7
- export type { CardElement, ElementProperty, JsonCard } from './types.js';
8
62
  //# sourceMappingURL=raw-to-dsl.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"raw-to-dsl.d.ts","sourceRoot":"","sources":["../src/raw-to-dsl.ts"],"names":[],"mappings":"AAqDA,sDAAsD;AACtD,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAGnF;AAED,wEAAwE;AACxE,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiB9D;AAyGD,0BAA0B;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
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;AAo9CD;;;;;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,23 +1,27 @@
1
1
  {
2
2
  "name": "@open-feishu-card/adapter",
3
- "version": "0.2.0",
4
- "description": "公开 DSL 与飞书内部 RAW JSON 的双向适配器,支持未知组件自动降级 (Fallback)",
3
+ "version": "0.3.0",
4
+ "description": "公开 DSL 与飞书内部 RAW JSON 的双向适配器;raw→DSL 对齐 feishu-raw-card-to-dsl",
5
5
  "type": "module",
6
- "main": "./dist/index.js",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
7
8
  "types": "./dist/index.d.ts",
8
9
  "exports": {
9
10
  ".": {
10
11
  "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js"
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
12
14
  }
13
15
  },
14
16
  "files": [
15
17
  "dist"
16
18
  ],
17
19
  "devDependencies": {
20
+ "@types/node": "^22.20.1",
21
+ "tsup": "^8.3.5",
18
22
  "tsx": "^4.19.3",
19
23
  "typescript": "^7.0.2",
20
- "@types/node": "^22.20.1"
24
+ "vitest": "^2.1.9"
21
25
  },
22
26
  "license": "MIT",
23
27
  "publishConfig": {
@@ -29,8 +33,8 @@
29
33
  "directory": "packages/adapter"
30
34
  },
31
35
  "scripts": {
32
- "build": "tsc -p tsconfig.json",
36
+ "build": "tsup && tsc -p tsconfig.json --emitDeclarationOnly",
33
37
  "typecheck": "tsc --noEmit -p tsconfig.json",
34
- "test": "tsx --test test/*.test.ts"
38
+ "test": "tsx --test test/adapter.test.ts && vitest run"
35
39
  }
36
40
  }
@@ -1,325 +0,0 @@
1
- import { parseMarkdown } from './md-parse.js';
2
- /**
3
- * 渲染器「只读 camelCase」的字段:DSL 用 snake_case 写,必须改名才能渲染出来。
4
- * 依据 components.ts / registry.ts 逐字段核对(dual-read 的字段不在此列,透传即可)。
5
- */
6
- const KEY_RENAME = {
7
- text_align: 'textAlign',
8
- text_style: 'textStyle',
9
- background_style: 'backgroundStyle',
10
- background_color: 'backgroundColor',
11
- user_id: 'userID',
12
- show_avatar: 'showAvatar',
13
- show_name: 'showName',
14
- has_border: 'hasBorder',
15
- hover_tips: 'hoverTips',
16
- pill_shaped: 'pillShaped',
17
- tag_style: 'tagStyle',
18
- scale_type: 'scaleType',
19
- drop_invalid_user_id: 'dropInvalidUserID',
20
- // video / audio
21
- file_key: 'fileID',
22
- audio_id: 'audioID',
23
- show_progress_bar: 'showProgressBar',
24
- show_time: 'showTime',
25
- enable_download: 'enableDownload',
26
- fill_color: 'fillColor',
27
- };
28
- /** 需要把「文本叶子」归一成 { tag:'plain_text', property:{content} } 的字段名 */
29
- const TEXT_LEAF_KEYS = new Set(['title', 'subtitle', 'alt', 'hover_tips', 'placeholder']);
30
- /** DSL 顶层 → JsonCard(渲染器输入)。 */
31
- export function dslToRaw(dsl) {
32
- const root = isRecord(dsl) ? dsl : {};
33
- // 允许调用方直接传 { card: {...} } 或 { json_card: {...} } 外层包装
34
- const card = isRecord(root.card) ? root.card : isRecord(root.json_card) ? root.json_card : root;
35
- const out = { schema: typeof card.schema === 'string' ? card.schema : '2.0' };
36
- if (isRecord(card.header))
37
- out.header = convertHeader(card.header);
38
- if (isRecord(card.body))
39
- out.body = convertBody(card.body);
40
- return out;
41
- }
42
- function convertHeader(header) {
43
- const property = {};
44
- for (const [k, v] of Object.entries(header)) {
45
- if (k === 'tag')
46
- continue;
47
- if (TEXT_LEAF_KEYS.has(k)) {
48
- property[k] = wrapTextLeaf(v);
49
- continue;
50
- }
51
- // 前置图标:icon / ud_icon(与 body 元素同规则)
52
- if ((k === 'icon' || k === 'ud_icon') && isRecord(v)) {
53
- property[k === 'ud_icon' ? 'udIcon' : 'icon'] = convertEl(v);
54
- continue;
55
- }
56
- // text_tag_list 里的 text_tag 需递归 convertEl(否则 text 叶子仍是扁平 DSL)
57
- if (k === 'text_tag_list' && Array.isArray(v)) {
58
- property.text_tag_list = v.map(convertNode);
59
- continue;
60
- }
61
- property[renameKey(k)] = coerceValue(k, v);
62
- }
63
- return { tag: 'card_header', property };
64
- }
65
- function convertBody(body) {
66
- // 除 elements 外,body 还可带 padding / vertical_spacing 等容器级字段——一并搬进 property
67
- // (buildProperty 会做 box 简写→对象、snake→camel 等转换),否则 body 组件读不到、间距/内边距回退默认。
68
- const property = buildProperty(body, 'body');
69
- const elements = Array.isArray(body.elements) ? body.elements.map(convertNode) : [];
70
- property.elements = elements.filter(Boolean);
71
- return { tag: 'body', property };
72
- }
73
- /** 数组项 / 子元素统一入口:元素对象走 convertEl,其它原样递归 */
74
- function convertNode(node) {
75
- if (isRecord(node) && typeof node.tag === 'string')
76
- return convertEl(node);
77
- return node;
78
- }
79
- /**
80
- * 单个 DSL 元素(扁平、snake_case)→ RAW 元素({ tag, property })。
81
- */
82
- function convertEl(el) {
83
- const tag = String(el.tag);
84
- // person → person_v1(渲染器注册的是 person_v1 / person_list)
85
- // DSL style:"capsule" → pillShaped(与 markdown <person style=capsule> 一致)
86
- if (tag === 'person') {
87
- const property = buildProperty(el, 'person_v1');
88
- // ElementProperty.style 类型偏图标对象;DSL person 的 style 是 "capsule"|"normal" 字符串
89
- if (property.style === 'capsule') {
90
- property.pillShaped = true;
91
- delete property.style;
92
- }
93
- return { tag: 'person_v1', property };
94
- }
95
- // markdown / lark_md:content 字符串 → 子元素树。
96
- // lark_md 是飞书旧名(checker.text / div.text 仍常用),统一归一为 markdown 再解析。
97
- if (tag === 'markdown' || tag === 'lark_md') {
98
- const property = buildProperty(el, 'markdown');
99
- if (typeof el.content === 'string')
100
- property.elements = parseMarkdown(el.content);
101
- delete property.content;
102
- return { tag: 'markdown', property };
103
- }
104
- // table:lark_md / markdown 列的单元格字符串 → 与真机 RAW 一致的 markdown 元素树。
105
- // 否则渲染期只能当纯文本,"<font color='green'>**▲**</font>" 会原样漏到 HTML。
106
- if (tag === 'table') {
107
- return { tag, property: convertTableProperty(el) };
108
- }
109
- // audio / video:width 枚举 → widthValue;视频封面 image_key → coverImageID。
110
- if (tag === 'audio' || tag === 'video') {
111
- const property = buildProperty(el, tag);
112
- if (tag === 'audio' && el.width != null) {
113
- delete property.width;
114
- if (el.width === 'fill' || el.width === 'default') {
115
- property.widthValue = { type: 'builtin_width', value: el.width };
116
- }
117
- else if (typeof el.width === 'string') {
118
- const px = pxValue(el.width);
119
- if (px != null)
120
- property.widthValue = { type: 'pixels', value: px };
121
- }
122
- }
123
- if (tag === 'video') {
124
- const cover = el.image_key ?? el.cover_image_key ?? el.coverImageID;
125
- if (typeof cover === 'string' && cover)
126
- property.coverImageID = cover;
127
- delete property.image_key;
128
- delete property.cover_image_key;
129
- }
130
- return { tag, property };
131
- }
132
- return { tag, property: buildProperty(el, tag) };
133
- }
134
- /**
135
- * table 专用:在通用 buildProperty 之后,把 markdown 列的字符串单元格
136
- * 转成 { data: { tag:'markdown', property:{ elements } } }(对齐真机 RAW 形态)。
137
- */
138
- function convertTableProperty(el) {
139
- const property = buildProperty(el, 'table');
140
- const columns = Array.isArray(property.columns) ? property.columns : [];
141
- const mdColNames = new Set();
142
- for (const col of columns) {
143
- if (!isRecord(col))
144
- continue;
145
- const dt = col.data_type ?? col.dataType;
146
- if (dt === 'lark_md' || dt === 'markdown') {
147
- const name = typeof col.name === 'string' ? col.name : '';
148
- if (name)
149
- mdColNames.add(name);
150
- }
151
- }
152
- if (!mdColNames.size || !Array.isArray(property.rows))
153
- return property;
154
- property.rows = property.rows.map((row) => {
155
- if (!isRecord(row))
156
- return row;
157
- const out = { ...row };
158
- for (const name of mdColNames) {
159
- const cell = out[name];
160
- // 已是 { data: … } / markdown 元素则不动(幂等);只转裸字符串。
161
- if (typeof cell === 'string') {
162
- out[name] = {
163
- data: {
164
- tag: 'markdown',
165
- property: { elements: parseMarkdown(cell), originTag: 'lark_md' },
166
- },
167
- };
168
- }
169
- }
170
- return out;
171
- });
172
- return property;
173
- }
174
- /** 把 DSL 元素的扁平字段(除 tag/id)搬进 property,逐字段做必要转换。 */
175
- function buildProperty(el, tag) {
176
- const property = {};
177
- for (const [k, v] of Object.entries(el)) {
178
- if (k === 'tag' || k === 'id')
179
- continue; // 渲染器不读 id
180
- // column 定宽 "Npx" → widthValue(渲染器 column 靠 widthValue.value 判定定宽;
181
- // 直接留 width:"100px" 字符串会被当成权重列,图片按列宽渲染会错位)
182
- if (tag === 'column' && k === 'width' && typeof v === 'string') {
183
- const px = pxValue(v);
184
- if (px != null) {
185
- property.widthValue = { type: 'pixels', value: px };
186
- continue;
187
- }
188
- }
189
- // 文本叶子:title/subtitle/alt/hover_tips/placeholder → {tag:plain_text,property:{content}}
190
- if (TEXT_LEAF_KEYS.has(k)) {
191
- property[renameKey(k)] = wrapTextLeaf(v);
192
- continue;
193
- }
194
- // button.text / text_tag.text:归一为 plain_text 叶子(渲染器 extractPlainText / extractText)
195
- // checker.text 若为 markdown / lark_md:必须走 convertEl(content → parseMarkdown),
196
- // 否则 <text_tag>/<font> 会作为字面量漏到 HTML。其它父级的 text 仍走 wrapTextLeaf,
197
- // 避免 header.title / text_tag.text 误走 markdown 后 content 被删、读不到字。
198
- if (k === 'text') {
199
- if (tag === 'checker' && isRecord(v) && (v.tag === 'markdown' || v.tag === 'lark_md')) {
200
- property.text = convertEl(v);
201
- }
202
- else {
203
- property.text = wrapTextLeaf(v);
204
- }
205
- continue;
206
- }
207
- // 前置图标
208
- if ((k === 'icon' || k === 'ud_icon') && isRecord(v)) {
209
- property[k === 'ud_icon' ? 'udIcon' : 'icon'] = convertEl(v);
210
- continue;
211
- }
212
- // 点击行为:button / interactive_container / checker 的 behaviors|multi_url → 渲染器读的 actions|url
213
- if (k === 'behaviors' && Array.isArray(v)) {
214
- property.actions = behaviorsToActions(v);
215
- continue;
216
- }
217
- if (k === 'multi_url') {
218
- property.url = normalizeUrl(v);
219
- continue;
220
- }
221
- // checker.button_area:嵌套 buttons 需递归 convertEl(否则仍是扁平 DSL,渲不出)
222
- if (k === 'button_area' && isRecord(v)) {
223
- const area = { ...v };
224
- if (Array.isArray(v.buttons))
225
- area.buttons = v.buttons.map(convertNode);
226
- property.button_area = area;
227
- continue;
228
- }
229
- property[renameKey(k)] = coerceValue(k, v);
230
- }
231
- return property;
232
- }
233
- /**
234
- * 字段值转换:box 简写字符串→对象、子元素数组递归、url 归一,其余透传。
235
- * (column 定宽 width→widthValue 在 buildProperty 里就地处理,不走这里。)
236
- */
237
- function coerceValue(key, value) {
238
- // padding / margin:CSS 简写字符串 → { top/right/bottom/left:{type:'pixels',value} }
239
- if ((key === 'padding' || key === 'margin') && typeof value === 'string') {
240
- return parseBox(value);
241
- }
242
- // 子元素容器:elements / columns / actions / persons / items 里的元素递归转换
243
- if (Array.isArray(value))
244
- return value.map(convertNode);
245
- // url 对象/字符串:保持渲染器 resolveURL 认得的形态
246
- if (key === 'url')
247
- return normalizeUrl(value);
248
- return value;
249
- }
250
- /* ------------------------------------------------------------------ *
251
- * 小工具
252
- * ------------------------------------------------------------------ */
253
- function renameKey(k) {
254
- return KEY_RENAME[k] || k;
255
- }
256
- /** 文本叶子 → { tag:'plain_text', property:{content, textAlign?, text_size?, text_color?} } */
257
- function wrapTextLeaf(v) {
258
- if (typeof v === 'string')
259
- return { tag: 'plain_text', property: { content: v } };
260
- if (isRecord(v)) {
261
- const property = { content: typeof v.content === 'string' ? v.content : '' };
262
- if (typeof v.text_align === 'string')
263
- property.textAlign = v.text_align;
264
- // checker 等组件的 text 叶子会带 text_size / text_color(DSL snake_case)
265
- if (typeof v.text_size === 'string')
266
- property.text_size = v.text_size;
267
- if (typeof v.text_color === 'string')
268
- property.text_color = v.text_color;
269
- return { tag: typeof v.tag === 'string' ? v.tag : 'plain_text', property };
270
- }
271
- return { tag: 'plain_text', property: { content: '' } };
272
- }
273
- /** behaviors:[{type,default_url}] → actions:[{type,action:{url}}](渲染器读 actions[].action.url) */
274
- function behaviorsToActions(behaviors) {
275
- const out = [];
276
- for (const b of behaviors) {
277
- if (!isRecord(b))
278
- continue;
279
- const type = typeof b.type === 'string' ? b.type : 'open_url';
280
- out.push({ type, action: { url: normalizeUrl(b.default_url) } });
281
- }
282
- return out;
283
- }
284
- /** url 归一:字符串直返;对象取 .url(多端字段交给渲染器 resolveURL 处理) */
285
- function normalizeUrl(v) {
286
- if (typeof v === 'string')
287
- return v;
288
- if (isRecord(v))
289
- return v; // {url, pc_url,...} —— resolveURL 认 url/pcURL 等
290
- return v;
291
- }
292
- /** "12px" / "12px 8px" / "1px 2px 3px 4px" → { top/right/bottom/left:{type:'pixels',value} } */
293
- function parseBox(s) {
294
- const nums = s.trim().split(/\s+/).map((t) => pxValue(t) ?? 0);
295
- let t = 0, r = 0, b = 0, l = 0;
296
- if (nums.length === 1) {
297
- t = r = b = l = nums[0];
298
- }
299
- else if (nums.length === 2) {
300
- t = b = nums[0];
301
- r = l = nums[1];
302
- }
303
- else if (nums.length === 3) {
304
- t = nums[0];
305
- r = l = nums[1];
306
- b = nums[2];
307
- }
308
- else if (nums.length >= 4) {
309
- [t, r, b, l] = nums;
310
- }
311
- const px = (value) => ({ type: 'pixels', value });
312
- return { top: px(t), right: px(r), bottom: px(b), left: px(l) };
313
- }
314
- /** "12px" → 12;"12" → 12;非像素返回 null */
315
- function pxValue(s) {
316
- const m = /^(-?\d+(?:\.\d+)?)px?$/.exec(s.trim());
317
- if (m)
318
- return Number(m[1]);
319
- const n = Number(s);
320
- return Number.isFinite(n) ? n : null;
321
- }
322
- function isRecord(v) {
323
- return typeof v === 'object' && v !== null && !Array.isArray(v);
324
- }
325
- //# sourceMappingURL=dsl-to-raw.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dsl-to-raw.js","sourceRoot":"","sources":["../src/dsl-to-raw.ts"],"names":[],"mappings":"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"}