@formspec/build

中文文档
0.1.0-alpha.70发布于 2026/08/21MITTypeScriptESM + CJS构建来源已验证近 30 天下载 4280

构建工具来编译 FormSpec 表格到 JSON Schema 和 UI Schema

中文使用文档
文档目录11 节
  1. 安装
  2. 公共条目
  3. 链式 DSL 生成
  4. 静态分析
  5. 静态构建背景
  6. 支持的TSDoc实例
  7. 扩展- 智能生成
  8. 处理生成失败
  9. 内部入口
  10. 主要出口
  11. 许可证

@ formspec/ 构建

用于 FormSpec 的建时计划生成.

本套件涵盖:

  • 将 DSL 链到 JSON Schema / UI Schema 汇编
  • 静态分析 TypeScript 类,接口,以及 TSDoc 标签的别名类型
  • 混合作者计划生成
  • 带有自定义供应商关键字的扩展意识计划生成

安装

pnpm add @formspec/build

大多数应用代码可以使用 formspec,但使用时 @formspec/build 直接当您需要静态分析或低等生成 API 时.

公共条目

入境点目的
@formspec/build公共建筑 API
@formspec/build/browser浏览器安全链- DSL 和 IR 表面
@formspec/build/internals不稳定的低水平IR/分析器 API

链式 DSL 生成

import { buildFormSchemas } from "@formspec/build";
import { field, formspec } from "@formspec/dsl";

const form = formspec(
  field.text("name", { required: true }),
  field.enum("status", ["draft", "published"] as const)
);

const { jsonSchema, uiSchema } = buildFormSchemas(form);

静态分析

generateSchemas() 是TSDoc支持生成的主要切入点.

import { generateSchemas } from "@formspec/build";

const { jsonSchema, uiSchema } = generateSchemas({
  filePath: "./src/forms.ts",
  typeName: "ProductConfig",
});

generateSchemasFromClass() 当输入绝对是类声明时仍可使用.

import { generateSchemasFromClass } from "@formspec/build";

const result = generateSchemasFromClass({
  filePath: "./src/forms.ts",
  className: "ProductConfig",
});

静态构建背景

在需要检查出口、申报时使用静态构建上下文 API, 或方法上的签名,然后决定产生什么计划.

此工作流程中的公共助手 :

  • createStaticBuildContext(filePath) - 从文件中创建可重复使用的编译器后置上下文.
  • createStaticBuildContextFromProgram(program, filePath) - 重新使用主机拥有 ts.Program。 。 。 .
  • resolveModuleExport(context, exportName?) - 解决任何出口的符号,包括功能和其他非化学申报.
  • resolveModuleExportDeclaration(context, exportName?) - 只解决计划来源的申报(class, (中文(简体) ), interface, (中文(简体) ), type (别名).
  • resolveDeclarationMetadata(...) - 利用FormSpec的主动元数据政策,解决命名类型、方法和属性的元数据.
  • generateSchemasFromDeclaration(...) - 产生一个解决的 计划源声明.
  • generateSchemasFromParameter(...) - 从方法或函数参数声明生成.
  • generateSchemasFromReturnType(...) - 从方法或函数返回类型生成,待取 Promise<T>- 代代相传.
  • generateSchemasFromType(...) - 直接从解决后产生 ts.Type。 。 。 .

使用 resolveModuleExportDeclaration(...) 当你的工具想要 提交一个解决 直接声明为 generateSchemasFromDeclaration(...)启用 resolveModuleExport(...) 当您首先需要更低级的 TypeScript 访问时, 例如检查一个函数 输出,然后从其中一种签名类型生成计划.

import * as ts from "typescript";
import {
  createStaticBuildContext,
  generateSchemasFromDeclaration,
  generateSchemasFromParameter,
  generateSchemasFromReturnType,
  resolveDeclarationMetadata,
  resolveModuleExport,
  resolveModuleExportDeclaration,
} from "@formspec/build";

const context = createStaticBuildContext("./src/service.ts");
const serviceDeclaration = resolveModuleExportDeclaration(context, "PaymentService");

if (serviceDeclaration && ts.isClassDeclaration(serviceDeclaration)) {
  const submitMethod = serviceDeclaration.members.find(
    (member): member is ts.MethodDeclaration =>
      ts.isMethodDeclaration(member) &&
      ts.isIdentifier(member.name) &&
      member.name.text === "submit"
  );

  if (submitMethod?.parameters[0]) {
    const methodMetadata = resolveDeclarationMetadata({
      context,
      declaration: submitMethod,
    });
    const inputSchemas = generateSchemasFromParameter({
      context,
      parameter: submitMethod.parameters[0],
    });
  }
}

const inputDeclaration = resolveModuleExportDeclaration(context, "SubmitInput");
if (inputDeclaration) {
  const inputSchemas = generateSchemasFromDeclaration({
    context,
    declaration: inputDeclaration,
  });
}

const paymentSymbol = resolveModuleExport(context, "submitPayment");
const paymentDeclaration = paymentSymbol?.declarations?.find(ts.isFunctionDeclaration);
if (paymentDeclaration) {
  const outputSchemas = generateSchemasFromReturnType({
    context,
    declaration: paymentDeclaration,
  });
}

如果你已经拥有一个 ts.Program,使用时 createStaticBuildContextFromProgram(program, filePath) 而不是让FormSpec创建一个。 如果您的工具已经解决了原始 ts.Type 或签字声明、使用 generateSchemasFromType(...) 或者说 generateSchemasFromReturnType(...) 直接说.

这是用于构建时段分析工作流程的辅助公共路径 需求 @formspec/build/internals。 。 。 .

支持的TSDoc实例

export interface ProductConfig {
  /** @displayName Product Name @minLength 1 */
  name: string;

  /** @format email */
  supportEmail?: string;

  /** @placeholder Search products */
  query?: string;

  /** @minimum 0 @maximum 9999.99 */
  price: number;

  /** @uniqueItems */
  tags: string[];
}

扩展- 智能生成

静态分析和混合作者生成 API 接受 extensionRegistry 财务报告和审定财务报表 vendorPrefix链式 DSL 生成接受 vendorPrefix,但不会 extensionRegistry。 。 。 .

import { createExtensionRegistry, generateSchemas } from "@formspec/build";

const registry = createExtensionRegistry([myExtension]);

const result = generateSchemas({
  filePath: "./src/forms.ts",
  typeName: "Invoice",
  extensionRegistry: registry,
  vendorPrefix: "x-acme",
});

世代在排放出计划之前验证犬类IR. 无效的输入失败生成, 结构化的诊断代码在抛出错误中浮出水面 .

处理生成失败

静态生成目前使用关于主要切入点的明显错误报告:

  • generateSchemas({ ..., errorReporting: "throw" }) 财务报告和审定财务报表 generateSchemasFromProgram({ ..., errorReporting: "throw" }) 保持简单的扔出错误的合同.
  • generateSchemas({ ..., errorReporting: "diagnostics" }) 财务报告和审定财务报表 generateSchemasFromProgram({ ..., errorReporting: "diagnostics" }) 返回结构化诊断,而不是投放分析和验证失败.
  • generateSchemasBatch() 财务报告和审定财务报表 generateSchemasBatchFromProgram() 继续通过多个目标返回每个目标的诊断.

使用 "throw" 模式。 使用 "diagnostics" 模式中,当您想要在一条通道中尽可能多地显示反馈,特别是在编辑器、CI或迁移工具中。 年长者 generateSchemasDetailed() 财务报告和审定财务报表 generateSchemasFromProgramDetailed() 包装纸仅作为已贬值的相容 shims 保留.

import { generateSchemas, generateSchemasBatch } from "@formspec/build";

try {
  const { jsonSchema, uiSchema } = generateSchemas({
    filePath: "./src/forms.ts",
    typeName: "Invoice",
    errorReporting: "throw",
  });
} catch (error) {
  const message = error instanceof Error ? error.message : String(error);

  if (message.includes("UNSUPPORTED_CUSTOM_TYPE_OVERRIDE")) {
    // An extension tried to override a TS global built-in such as Date or Array
  } else if (message.includes("SYNTHETIC_SETUP_FAILURE")) {
    // Extension setup failed before tag type-checking could run
  } else if (message.includes("TYPE_MISMATCH")) {
    // A tag was applied to an incompatible field or target type
  }

  throw error;
}

const detailed = generateSchemas({
  filePath: "./src/forms.ts",
  typeName: "Invoice",
  errorReporting: "diagnostics",
});

if (!detailed.ok) {
  for (const diagnostic of detailed.diagnostics) {
    console.error(`${diagnostic.code}: ${diagnostic.message}`);
  }
}

const batch = generateSchemasBatch({
  targets: [
    { filePath: "./src/forms.ts", typeName: "Invoice" },
    { filePath: "./src/forms.ts", typeName: "PaymentTerms" },
  ],
});

for (const result of batch) {
  if (!result.ok) {
    console.error(
      `${result.typeName} failed: ${result.diagnostics.map((diagnostic) => diagnostic.code).join(", ")}`
    );
  }
}

用于扩展后静态分析失败的最相关代码有:

  • UNSUPPORTED_CUSTOM_TYPE_OVERRIDE 对于与不支持的 TypeScript 全球内置相冲突的扩展自定义类型.
  • SYNTHETIC_SETUP_FAILURE 用于无效或相冲突的扩展自定义类型注册和其他合成编译器设置失败.
  • TYPE_MISMATCH 用于作者源中的普通标签类型相容性.
  • TYPE_NOT_FOUND 当请求的导出目标无法解决时.
  • UNSUPPORTED_ROOT_TYPE 财务报告和审定财务报表 DUPLICATE_ROOT_PROPERTIES 当所请求的类型别名不能被当作一个chema root.
  • PROGRAM_CONTEXT_FAILURE 当软件包无法为请求的文件创建或再使用 TypeScript 程序时.

作为拇指规则, UNSUPPORTED_CUSTOM_TYPE_OVERRIDE 财务报告和审定财务报表 SYNTHETIC_SETUP_FAILURE 显示扩展配置问题,同时 TYPE_MISMATCH 通常表示分析出源中的作者错误.

内部入口

低级犬类IR生成器,分析器原始器,验证辅助器被故意不再从包根输出出. 如果你需要那些不稳定的内脏 在单体内,从 @formspec/build/internals。 。 。 .

主要出口

  • buildFormSchemas(form, options?)
  • generateJsonSchema(form, options?)
  • generateUiSchema(form)
  • writeSchemas(form, options)
  • generateSchemas(options)
  • generateSchemasFromClass(options)
  • generateSchemasFromProgram(options)
  • generateSchemasBatch(options)
  • generateSchemasBatchFromProgram(options)
  • buildMixedAuthoringSchemas(options)
  • createExtensionRegistry(extensions)

writeSchemas() 是用于写出文件的链- DSL 便利包装器 。 扩展登记册适用于上面的静态分析和混合授权生成流程,不适用于 writeSchemas()。 。 。 .

许可证

这个包是FormSpec monorepo的一部分,根据MIT许可证发行. 见 自由主义 详细情况.

版本与发布记录

@formspec/build 共发布 57 个版本,首次发布于 2026/01/29;过去 12 个月发布了 57 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.1.0-alpha.70latest2026/08/212 个月前
0.1.0-alpha.632026/04/246 个月前
0.1.0-alpha.612026/04/236 个月前
0.1.0-alpha.592026/04/226 个月前
0.1.0-alpha.582026/04/216 个月前
0.1.0-alpha.572026/04/206 个月前

其他发布通道:alpha → 0.1.0-alpha.1。

关于 @formspec/build 的常见问题

@formspec/build 是什么?

构建工具来编译 FormSpec 表格到 JSON Schema 和 UI Schema

如何安装 @formspec/build?

在项目目录运行 npm install @formspec/build,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:typescript(>=5.7.3 <7)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。它还提供命令行工具 formspec-build,可以用 npx formspec-build 直接运行。

@formspec/build 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@formspec/build 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@formspec/build 可以商用吗?

@formspec/build 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@formspec/build 的下载量有多少?

根据 npm 官方下载统计,@formspec/build 在 2026/10/16 – 2026/11/14 这 30 天内被下载 4,280 次,日均约 143 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@formspec/build 还在维护吗?

最新版本 0.1.0-alpha.70 发布于 2026/08/21(2 个月前);至今共发布 57 个版本,其中过去 12 个月发布了 57 个;首次发布于 2026/01/29。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。