feishu-card-zod
v0.1.0
Published
飞书卡片 JSON 2.0 的模块化 Zod Schema
Readme
feishu-card-zod
飞书卡片 JSON 2.0 的模块化 Zod 4 Schema,严格按官方文档字段拆分,并用 tag / type 判别联合获得良好的 TypeScript 推导。
字段与 Schema 均带有 .describe(),可直接通过 z.toJSONSchema() 导出带 description 的 JSON Schema。
安装
npm install feishu-card-zod zod@^4快速使用
import { FeishuCardSchema, type FeishuCard } from 'feishu-card-zod';
const card: FeishuCard = {
schema: '2.0',
header: {
title: { tag: 'plain_text', content: '你好' },
},
body: {
elements: [
{
tag: 'markdown',
content: '**Hello** Feishu Card',
},
{
tag: 'button',
text: { tag: 'plain_text', content: '打开文档' },
behaviors: [
{
type: 'open_url',
default_url: 'https://open.feishu.cn',
},
],
},
],
},
};
const parsed = FeishuCardSchema.parse(card);推荐业务侧使用强制 schema: "2.0" 的变体:
import { FeishuCardV2Schema } from 'feishu-card-zod';
FeishuCardV2Schema.parse(card);模块结构
src/
common/ # 文本、图标、链接、behaviors、confirm 等共享原语
markdown/ # 富文本(核心):组件 Schema、扩展标签、内容构建器
content/ # 展示类:div / img / table / chart ...
interactive/ # 交互类:button / input / select_* / date_picker ...
containers/ # 容器类:column_set / form / interactive_container ...
header.ts # 标题 HeaderSchema
config.ts # ConfigSchema / BodySchema
element.ts # ElementSchema = discriminatedUnion('tag', ...)
card.ts # FeishuCardSchema 根 Schema富文本(重点)
富文本不是 content 里的一个薄包装,而是独立模块 src/markdown/:
import { markdown, MarkdownSchema } from 'feishu-card-zod';
const content = markdown()
.heading(1, '告警')
.br()
.font({ text: 'P0', color: 'red' })
.text(' ')
.at({ id: 'ou_xxx' })
.br()
.link({ text: '文档', url: 'https://open.feishu.cn', icon: 'chat_outlined' })
.build();
const element = MarkdownSchema.parse({
tag: 'markdown',
content,
text_size: 'normal',
});模块包含:
MarkdownSchema:组件字段(含官方字号枚举、href旧语法)- 扩展标签 Schema +
render*:at/person/link/text_tag/number_tag/local_datetime/font/audio… markdown()构建器:标准 Markdown + 飞书标签的类型安全拼接- 代码语言枚举、特殊字符转义
设计要点
- Zod 4:依赖
zod@^4,可使用z.toJSONSchema()、统一error参数等 Zod 4 API。 - 字段描述:Schema / 字段一律
.describe(...)(不只写 JSDoc)。JSDoc 服务人类阅读;.describe()会进入 JSON Schema 的description,便于文档生成与工具消费。 - 判别联合:所有 body 组件通过
z.discriminatedUnion('tag', [...])组合;交互行为通过type判别(open_url|callback);图标通过tag判别(standard_icon|custom_icon)。 - 递归嵌套:分栏、表单、交互容器、折叠面板的
elements使用z.lazy(),经element-ref延迟绑定,避免循环依赖。 - 类型导出:每个核心 Schema 均导出
z.infer类型,如export type Button = z.infer<typeof ButtonSchema>。 - 必填/选填:字段必填性对齐飞书官方「字段说明」表格;表单内条件必填(如
name、form_action_type)保留为 optional,便于单独复用组件 Schema,可按需叠加superRefine。
导出 JSON Schema 示例
import { z } from 'zod';
import { FeishuCardSchema } from 'feishu-card-zod';
const jsonSchema = z.toJSONSchema(FeishuCardSchema);
// jsonSchema.description / properties.*.description 均来自 .describe()脚本
npm install
npm run typecheck
npm test
npm run build发布
推送版本 tag 后,GitHub Actions 会自动发布到 npm:
# 1. 更新 package.json 中的 version(如 0.1.0)
# 2. 提交并推送到 main
git tag v0.1.0
git push origin v0.1.0仓库需配置 Secret NPM_TOKEN(npm Automation token)。
文档来源
字段定义参考飞书开放平台:
