Workbench 与配置

Valibot 配置表单

用一个 Valibot object schema 同时驱动 Plugin 配置、字段信息和 Web 表单。

给配置字段加标题、说明、控件偏好时,使用 valibot-form metadata。Plugin 仍只声明一份 Valibot schema, Workbench 会自动显示配置表单;无需为普通配置另外编写 React 页面。

先给一个字段加标题

import { , , ,  } from '@pluxel/runtime'

@()
export class  extends  {
	private readonly  = this..(
		.({
			: .(.(.(), .({ : '启用服务' })), true),
		}),
	)
}

构建并运行插件,标准配置页应出现“启用服务”开关,初始值为开启。 f.formMeta() 只描述显示方式;字段是否必填、默认值和有效范围仍由 Valibot 决定。 保存与运行时应用的区别见插件配置

最小配置与渲染结果

下面是覆盖多种控件的完整参考例子。按需查找开关、分段选择、URL、整数、嵌套对象和列表; 无需在第一个 Plugin 中一次性采用全部控件。展开预览可直接操作表单,比较原始 Input 与校验后的 Output。


const  = .({
	: .(
		.(
			.(),
			.({
				: '启用示例服务',
				: 'schema 默认值会进入 normalized config',
				: { : 'runtime', : '运行时' },
			}),
		),
		true,
	),
	: .(
		.(
			.(['development', 'production'] as ),
			.({ : '运行环境', : 'runtime' }),
			.({
				: 'segmented',
				: { : '开发', : '生产' },
			}),
		),
		'development',
	),
	: .(
		.(
			.(),
			.(),
			.({
				: '上游地址',
				: 'URL 约束来自 schema;表单只负责编辑。',
				: { : 'network', : '网络与重试' },
			}),
			.({ : 'https://api.example.com' }),
		),
		'https://api.example.com',
	),
	: .(
		.(
			.(),
			.(),
			.(1),
			.(65535),
			.({ : '监听端口', : 'network' }),
			.({ : 1 }),
		),
		8787,
	),
	: .(
		.(
			.({
				: .(
					.(
						.(),
						.(),
						.(1),
						.(10),
						.({ : '最大次数' }),
						.({ : 1 }),
					),
					3,
				),
				: .(
					.(
						.(),
						.(),
						.(100),
						.({ : '退避时间(毫秒)' }),
						.({ : 100 }),
					),
					250,
				),
			}),
			.({ : '重试策略', : 'network' }),
			.({ : 'card', : 2 }),
		),
		{
			: 3,
			: 250,
		},
	),
	: .(
		.(
			.(.(.(), .())),
			.({ : '允许的 Origin', : 'network' }),
			.({
				: 'list',
				: 'Origin',
				: '添加 Origin',
				: 'https://api.example.com',
			}),
		),
		['https://api.example.com'],
	),
})

@({ : 'Example' })
export class  extends  {
	private readonly  = this..()

	override () {
		(this.., { : this.. })
	}
}
配置渲染预览 · 表单、Input 与 Output

当字段既有默认值又有表单 metadata 时,让 v.optional() 包住完成后的 v.pipe()v.optional(v.pipe(base, constraints, metadata), default)。这样默认值属于外层可选语义,字段 extractor 解包 optional 后仍能读取内层 metadata;不要写成 v.pipe(v.optional(base, default), metadata)

注意:configs.use() 要放在 Plugin class 的普通顶层 field;不要在 constructor 读取 config,不要使用 #private,每个具体 Plugin 只声明一个 object schema。

metadata 做什么

valibot-form 的 core entry 不依赖 React/Mantine,适合 runtime config、CLI prompt、配置文件编辑器和 schema inspection:

import * as  from 'valibot'
import * as  from 'valibot-form'

const  = .({
	: .(
		.(['development', 'production'] as ),
		.({ : '运行环境' }),
		.({
			: 'segmented',
			: { : '开发', : '生产' },
		}),
	),
})

const  = .()

常用映射:

Valibot schemametadata默认 web 控件
v.string()stringMetaTextInput
v.number()numberMetaNumberInput
v.boolean()Switch
v.picklist()picklistMetaSelect
v.array()arrayMetaList
v.record()recordMetaTable
v.object()objectMetaCard/stack
v.variant() / unionunionMetaSelect/segmented

类型入口

类型直接从 package 源码导出。下面的示例由 Twoslash 对当前 workspace 类型检查,不在文档中维护另一份类型声明:

import type { FormMeta,  } from 'valibot-form'
import type {  } from 'valibot-form/web'

type MetadataKeys = keyof FormMeta
type MetadataKeys = keyof FormMeta
type FormProps = keyof <>
type FormProps = "schema" | keyof AutoFormSharedProps | "fields" | "formOpts"

formMeta()title / description 使用 Valibot 标准 metadata,help、section、layout、disabled、readOnly 和 hidden 仍是表单展示偏好;类型对应的 *Meta() 只负责控件偏好。requiredness、选项、格式和范围仍来自 Valibot schema,例如 v.optional()v.url()v.minValue()v.maxValue()v.integer()。原生 v.title()v.description()v.metadata({ title, description }) 也会按 pipe 顺序互操作,但标准示例使用一次 formMeta() 集中声明。

需要编辑 schema 或查看类型补全时,打开独立的配置 Playground

Web adapter

只有在自己的 React 应用中需要自动表单,才从 valibot-form/web 导入。标准 Workbench 配置页已包含它。 独立应用需要安装 React、Mantine、TanStack Form、Tabler Icons 和 dnd-kit:

npx nypm add valibot-form valibot react react-dom @mantine/core @mantine/hooks @tanstack/react-form @tabler/icons-react @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities

export function () {
	return (
		<>
			<
				={}
				={{
					: { : 'development' },
					: async ({  }) => (),
				}}
			>
				<. />
				<.>
					{({ , , , ,  }) => (
						<>
							< ="button" ={() => ()} ={! || }>
								重置
							</>
							< ="button" ={} ={! || }>
								保存
							</>
						</>
					)}
				</.>
			</>
		</>
	)
}

上例是独立 React 应用,因此自行导入 Mantine CSS。放进 Workbench View 时,仍需自己的 MantineProvider, 但应删除 @mantine/core/styles.css 导入,基础 CSS 已由宿主加载;见页面资源参考

AutoForm 负责根据 schema metadata 规划和渲染字段;配置 authority 仍然是 runtime 的 configs.use() 校验流程。把表单值送回 host API 前,服务端必须再次用同一个 schema 校验,不能把浏览器表单当作信任边界。

与 Pluxel 配置界面的边界

valibot-form 提供 schema metadata、字段提取和可选 Web adapter,不提供 Pluxel Plugin 发现、配置传输或持久化 API。自定义配置界面应直接接收 browser-safe 的 schema,并通过应用自己的服务端接口提交修改;服务端继续使用同一 schema 校验输入。

Pluxel Workbench 内置的 Plugin 配置页由宿主读取 runtime config metadata。Plugin 作者只声明 this.configs.use(Config),不调用 Workbench 内部的 schema projection 或配置 patch 实现。

检查清单

  • schema 是 object 或 intersect,适合 AutoForm
  • 默认值写在 v.optional(v.pipe(...metadata), default),没有业务 fallback,也不会在解包 optional 时丢失 metadata。
  • configs.use() 是 class 顶层普通 field,且 Plugin 只有一个 config field。
  • server runtime 是最终校验者;browser 表单只提供编辑体验。
  • core 工具需要 schema 时只 import valibot-form,不把 React/Mantine 带入 server bundle。

最后更新于

本页目录