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

@skopon-cool/form-sdk

v0.6.1

Published

Skopon form rendering SDK (A2UI + form_definition) with submit helpers

Downloads

1,424

Readme

@skopon-cool/form-sdk

Skopon 表单渲染 SDK:基于 A2UI v0.9 + skopon 自定义 catalog,统一渲染 form_definition、A2UI surface 与增量 message 流,并提供 Ask User 提交能力(默认复制 curl,可选 POST JSON)。

Monorepo 开发(skopon-admin)

本目录是 SDK 唯一源码。发版与修改约定见 PUBLISH.md

严禁front/node_modules/@skopon-cool/form-sdk 改代码并 npm publish

安装

方式一:一键安装(推荐 Agent 客户端)

安装 meta 包,自动带上 SDK 及全部 peer 依赖(reactantd@a2ui/* 等):

npm install @skopon-cool/form-sdk-bundle

使用方式与主包相同,可从 bundle 直接 import:

import '@skopon-cool/form-sdk-bundle/styles.css'
import { AskUserFormCard, createFormClient } from '@skopon-cool/form-sdk-bundle'

方式二:手动安装主包 + peer

若宿主项目已有 React / Ant Design,只需补装 SDK 与 A2UI peer:

npm install @skopon-cool/form-sdk react react-dom antd @a2ui/react @a2ui/web_core @ant-design/icons

dayjszod 已作为 SDK 普通依赖随包安装,无需单独安装

Peer dependencies 说明

| 包 | 说明 | | -------------------------------- | -------------------------------------------------- | | react / react-dom | 须与宿主共用同一实例,不可由 SDK 内嵌 | | antd / @ant-design/icons | 表单控件与图标;SDK 内置 Skopon 主题,也可由宿主全局 ConfigProvider 覆盖 | | @a2ui/react / @a2ui/web_core | A2UI 渲染栈(SDK 内部使用,宿主无需写 A2UI 代码) |

样式与主题(0.2.0+ 开箱即用)

form-sdk.css 已内置 Skopon 设计令牌(@radix-ui/colors + 语义 CSS 变量)与表单组件样式。无需在宿主复制 tokens.cssantdTheme

import '@skopon-cool/form-sdk/styles.css'
// 或 import '@skopon-cool/form-sdk'(入口侧效自动加载样式)

SkoponFormRendererAskUserFormCardSkoponA2uiStreamRenderer 内部已包裹 SkoponFormProvider(墨绿 antd 主题)。也可手动使用:

import { SkoponFormProvider, skoponAntdTheme } from '@skopon-cool/form-sdk'

<SkoponFormProvider locale={zhCN}>
  <AskUserFormCard ... />
</SkoponFormProvider>

高级定制:SkoponFormProvidertheme 可覆盖默认主题;skoponAntdTheme / skoponBrandColors 可单独导出复用。

渲染 form_definition

SkoponFormRendererdoc 内容(非引用)决定是否重建内部 processor;相同内容的 doc 即使用新对象引用传入也不会清空用户已填写的值。若需强制刷新表单,请变更 doc 的实际内容或 surfaceId

import { SkoponFormRenderer, blocksToA2ui, resolveSurfaceFromFormDefinition } from '@skopon-cool/form-sdk'

const surface = resolveSurfaceFromFormDefinition(formDefinition)
// 或
const surface = blocksToA2ui(formDefinition)

<SkoponFormRenderer doc={surface} interactive />

网页展示块(0.5.0+)

web 是不参与表单提交的展示块,通过 SkoponWeb A2UI 组件以内嵌 iframe 展示网页。行内高度默认 360px,可配置范围为 200–1200px;右下角按钮可在大尺寸 Modal 中扩展查看。

const definition = {
  blocks: [
    {
      id: 'company-site',
      type: 'web',
      label: '公司官网',
      help: '点击右下角按钮扩展查看',
      webUrl: 'https://example.com',
      webHeight: 480,
    },
  ],
}
  • 支持 http://https:// 绝对地址,以及 /./../ 开头的同源相对地址。
  • 拒绝 javascript:data: 和 protocol-relative 地址;非法地址只显示占位状态,不会写入 iframe src
  • iframe 不使用 sandbox,以兼容网页脚本、登录和表单能力。仅嵌入可信地址。
  • SDK 保证宿主组件和 Modal 不产生横向溢出,但无法修改跨域网页内部的滚动行为。
  • 目标站点若设置 X-Frame-Options、CSP frame-ancestors,或被浏览器判定为混合内容,仍可能拒绝嵌入。
  • 扩展与收起会重新加载网页;关闭动画期间 SDK 会先卸载 Modal iframe,确保同一地址不会同时运行两份。

A2UI 增量流

import { SkoponA2uiStreamRenderer } from '@skopon-cool/form-sdk'

<SkoponA2uiStreamRenderer messages={incomingMessages} interactive />

Ask User(QA / 流程 AI 聊天)

payload 须为 blocksJson{ title?, description?, blocks[] }),与表单编辑器 Blocks Json 同形。前端按 form_unique_id 拉取表单后与 payload.blocks 按 name 交集渲染卡片;payload 中表单外的块不在卡片展示,但提交 curl 时会合并进 body 并以注释标注为额外字段。

鉴权与 Token 缓存

SDK 请求(表单详情、简历搜索、案例列表、文件上传)默认从宿主登录时写入的浏览器缓存读取 token,无需每次手写 getHeaders

| 项 | 默认值 | | --- | ------------------------------- | | 存储 | sessionStorage | | 键名 | auth_user | | 字段 | JSON 内的 token | | API 根地址 | JSON 内可选的 skopon_api_base_url;缺失时使用当前 Origin 的 /api/v1 | | 请求头 | Authorization: Bearer <token> |

与 skopon-admin 登录约定一致:登录接口返回 token 后写入 auth_user。SDK 宿主可同时写入已包含 /api/v1skopon_api_base_url

sessionStorage.setItem('auth_user', JSON.stringify({
  username,
  displayName,
  token,
  skopon_api_base_url: 'https://admin-test.hibot.lol/api/skopon/api/v1',
}))

若宿主使用不同缓存键或字段名,创建 client 时传入 authStorage

createSkoponSdkClients({
  baseUrl: '/api/v1',
  authStorage: { storageKey: 'my_session', tokenField: 'accessToken' },
})

显式 getHeaders 仍优先于 authStorage(用于自定义鉴权逻辑)。

文件上传

FileUpload 选择文件后会立即调用 POST {skopon_api_base_url}/univ/upload/cdn,通过后端上传至七牛 CDN。例如配置为 https://admin-test.hibot.lol/api/skopon/api/v1 时,最终请求 https://admin-test.hibot.lol/api/skopon/api/v1/univ/upload/cdn。未配置时回退到当前 Origin 的 /api/v1/univ/upload/cdn

上传请求固定从 sessionStorage.auth_user 读取 tokenskopon_api_base_url,超时为 120 秒,不受 createSkoponSdkClientsbaseUrl / getHeaders / authStorage 选项影响。

  • 表单字段始终为七牛 URL 数组;即使 maxCount=1 也是 string[]
  • 历史单字符串值会在加载时转换为单元素数组。
  • 上传期间 AskUserFormCard 不允许提交;删除上传中项或卸载组件会取消请求。
  • 删除表单项只会移除字段 URL,不会删除七牛对象。
  • 服务端当前不允许 ZIP、RAR 和 7z;即使编辑器已配置这些类型,上传仍会返回类型错误。

直接使用 SkoponFormRenderer 时,可通过 onUploadingChange 获取所有文件组件的聚合上传状态:

<SkoponFormRenderer
  doc={surface}
  onUploadingChange={(uploading) => setSubmitDisabled(uploading)}
/>

Ask User 完整集成(推荐)

import { AskUserFormCard, createSkoponSdkClients } from '@skopon-cool/form-sdk'

const { fetchDetail, resumeSearch, caseSearch } = createSkoponSdkClients({
  baseUrl: '/api/v1',
})

<AskUserFormCard
  payload={message.payload}
  formUniqueId={message.form_unique_id}
  callbackUrl={message.callback_url}
  fetchFormDetail={fetchDetail}
  resumeSearch={resumeSearch}
  caseSearch={caseSearch}
  submitMode="curl"
/>
  • resumeSearch:简历多选(resume_multiselect必需,否则显示「未配置简历搜索服务」
  • caseSearch:案例多选(case_multiselect必需,否则显示「未配置案例搜索服务」
  • 简历搜索:GET /api/v1/univ/resume/search(需 univ:resume:search 权限)
  • 案例列表:GET /api/v1/univ/case/list

单独使用各 client

import {
  createFormClient,
  createResumeSearchClient,
  createCaseSearchClient,
  resolveSkoponAuthHeaders,
} from '@skopon-cool/form-sdk'

const headers = resolveSkoponAuthHeaders()

const client = createFormClient({ baseUrl: '/api/v1' })
const resumeSearch = createResumeSearchClient({ baseUrl: '/api/v1' })
const caseSearch = createCaseSearchClient({ baseUrl: '/api/v1' })

SkoponFormRenderer 直接使用

渲染含简历/案例块的 surface 时同样需注入:

<SkoponFormRenderer
  doc={surface}
  resumeSearch={resumeSearch}
  caseSearch={caseSearch}
/>

旧版最小示例(仅表单详情,无简历/案例块时)

import { AskUserFormCard, createFormClient } from '@skopon-cool/form-sdk'

const client = createFormClient({ baseUrl: '/api/v1' })

<AskUserFormCard
  payload={message.payload}
  formUniqueId={message.form_unique_id}
  callbackUrl={message.callback_url}
  fetchFormDetail={client.fetchDetail}
  submitMode="curl"
/>

未传 resumeSearch / caseSearch 时,对应组件会提示未配置搜索服务。

提交

  • submitMode: 'curl'(默认):复制 curl 到剪贴板(卡片填值 + 额外字段,extra 段含 // 额外字段(未在卡片展示) 注释)
  • submitMode: 'post'submitFormJson(callbackUrl, { ...cardValues, ...extraValues }) POST 合法 JSON

文件块说明file 类型字段在 SDK 内仅将文件名写入表单值并随提交发出,不包含文件二进制或 URL。若业务需要真实文件上传,请在宿主侧接入上传 API,或将文件块改为其他采集方式。

独立工具:

import { buildAskUserCurlStatement, buildCurlStatement, submitFormJson } from '@skopon-cool/form-sdk'

从 form_bp 拉取详情

import { createFormClient } from '@skopon-cool/form-sdk'

const client = createFormClient({
  baseUrl: '/api/v1',
  detailPath: '/dev/form/detail',
})

const detail = await client.fetchDetail({ formUniqueId: 'formuid-xxx' })

未传 getHeaders 时自动从 sessionStorage['auth_user'].token 读取 Bearer token。

发布

cd sdk/front/form && npm publish --access public
cd sdk/front/form-bundle && npm publish --access public