npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

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 + 飞书标签的类型安全拼接
  • 代码语言枚举、特殊字符转义

设计要点

  1. Zod 4:依赖 zod@^4,可使用 z.toJSONSchema()、统一 error 参数等 Zod 4 API。
  2. 字段描述:Schema / 字段一律 .describe(...)(不只写 JSDoc)。JSDoc 服务人类阅读;.describe() 会进入 JSON Schema 的 description,便于文档生成与工具消费。
  3. 判别联合:所有 body 组件通过 z.discriminatedUnion('tag', [...]) 组合;交互行为通过 type 判别(open_url | callback);图标通过 tag 判别(standard_icon | custom_icon)。
  4. 递归嵌套:分栏、表单、交互容器、折叠面板的 elements 使用 z.lazy(),经 element-ref 延迟绑定,避免循环依赖。
  5. 类型导出:每个核心 Schema 均导出 z.infer 类型,如 export type Button = z.infer<typeof ButtonSchema>。
  6. 必填/选填:字段必填性对齐飞书官方「字段说明」表格;表单内条件必填(如 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)。

文档来源

字段定义参考飞书开放平台: