@formio/appserver-core

中文文档
2.26.4发布于 2026/11/07OSL-3.0TypeScriptCommonJS近 30 天下载 5511

Form.io应用程序服务器是用于服务单个项目模板(包括表格,资源,角色等)的表演者运行时间应用程序服务器,位于一个部署的端口. 目标是实现快速的 单一租户部署

中文使用文档
文档目录5 节
  1. Form.io 应用程序服务器 - 核心
  2. 许可证发放
  3. 模块
  4. 模块 API
  5. 窗体路线

Form.io 应用程序服务器 - 核心

Form.io应用程序服务器是用于服务单个项目模板(包括表格,资源,角色等)的表演者运行时间应用程序服务器,位于一个部署的端口. 目标是实现快速的单一租户部署,在您希望管理统一地点内所有表格和资源的地方,但将租户数据存储在自己的数据库中.

此库是 Form.io 应用程序服务器的企业核心. 它打算与@formio/appserver 库同时使用.

更多信息,请参见: https://github.com/formio/appserver 页面存档备份,存于互联网档案馆

许可证发放

企业项目需要持有许可证 appserver 选项; 通用代理网关(UAG)特性需要 uag 选项,包括 appserver。许可证配置的环境变量与 Form.io Entertainment 和 PDF 服务器相同,因此一个许可证可以运行全部.

Form.io主机服务项目(a) https: 结束点 form.io 或它的子域,例如 https://myproject.form.io 或者说 https://api.form.io/project/<id>)不需要许可证:它运行在Form.io's下,作为企业号版,并且允许Agentic Formflow(理由) hosted) (中文(简体) ). 当应用服务器拥有自己的数据库时,该豁免不适用(MONGO),当 TLS 证书验证关闭时(NODE_TLS_REJECT_UNAUTHORIZED=0),或时 NODE_EXTRA_CA_CERTS, (中文(简体) ), NODE_USE_SYSTEM_CA, (中文(简体) ), --use-system-ca 或者说 --use-openssl-ca 已经设定。 自营企业的部署总是需要许可证.

变量配置说明
英国语NAME一个Form.io许可证密钥。 为企业服务器签发的密钥由Form.io许可证服务器验证;离线许可证由本地验证.
(服务器本身,例如 UAG_LICENSE 或者说 APPSERVER_LICENSE(中文(简体) )license, (中文(简体) ), licenseName服务器自己的许可密钥,同样经过验证. licenseName 是它来自的变量,由哪个消息命名它.
缩写licenseRemote设定为 true 当密钥是离线许可时, 所以许可证服务器从不联系, 对于任何密钥.
服务器licenseServer验证在线密钥的许可服务器: Form.io的(form.io)之一https://*.form.io) (中文(简体) ). 默认为 https://license.form.io。 。 。 .
licenseType许可证服务器的用法类型计算此服务器的用法, 例如 uagServer默认为 appServer. 见下文.
licenseFeature服务器需要运行的特性, 例如 uag默认为 appserver. 见下文.

一个特征是,当任一键为项目的终点授予它,所以,一个表格.io许可证与 uag 选项在 LICENSE_KEY 本身就足够了,服务器自己的密钥只能添加到它上. LICENSE_KEY 仅在服务器本身的密钥丢失、无法使用或缺少时进行校验 uag 对于终点,所以一个部署 它自己的钥匙足够 从来没有发送 LICENSE_KEY 到许可服务器。 每把钥匙都靠自己来验证:一把失败会让对方的结果完好无损. 当两个特性都没有被许可时,其理由按其变量命名每个密钥.

向许可证服务器报告在线密钥 appServer 使用类型,每个项目终点一个环境,因此其范围必须包括 appServer设置的服务器 licenseType 改为在该类别下报告。 一个设置的服务器 licenseFeature 需要这一特点,而不是 appserver 装入工程。 无人机集 licenseType: 'uagServer' 财务报告和审定财务报表 licenseFeature: 'uag',因此它运行在许可证服务器接受的在线密钥上 uagServer (根据许可证计算) uagServers),或带有以下内容的离线许可证: uag 选项,为它所配置的项目服务 appserver 选项本身并不运行。 其条款每15分钟再次检查一次。 如果无法到达许可服务器,服务器继续按它最后一次确认的条件运行,从确认开始12小时;在许可的特性关闭后,直到可以再次到达.

在线密钥未验证时 NODE_TLS_REJECT_UNAUTHORIZED=0, (中文(简体) ), NODE_EXTRA_CA_CERTS, (中文(简体) ), NODE_USE_SYSTEM_CA=1, (中文(简体) ), --use-openssl-ca 或者说 --use-system-ca 设置; 使用离线许可证(LICENSE_REMOTE这里.

一旦12小时用完,或在重启之后,企业号项目在许可证服务器确认许可证之前不会加载.

模块

server.use(module) 添加一个模块:它的配置,动作,钩子,提供者,处理器,插件类型和插件,下面还有它的模块密钥. 它还需要一份模块清单,依次使用,以便: server.use([first, second])。 。 。 .

server.use({
    name: 'word-count', title: 'Word count', version: '1.0.0', apiVersion: 1,
    settings: (config, env) => ({ max: Number(config.wordCount?.max ?? env.WORD_COUNT_MAX ?? 1000) }),
    routes: {
        form: {
            'POST /words/count': {
                handler: (req, res, api) => {
                    const words = String(req.body?.text || '').split(/\s+/).filter(Boolean).length;
                    if (words > api.settings.max) throw api.errors.create(413, `At most ${api.settings.max} words.`, 'too_many_words');
                    return { words };
                }
            }
        }
    },
    components: [{ type: 'wordcount', script: new URL('./dist/wordcount.js', import.meta.url) }],
    initialize: (api) => api.log.info(`at most ${api.settings.max} words`),
    plugins: [/* ... */]
});
  • 身份证明. name (小写字母和数字,单词加上 -, (中文(简体) ), title, (中文(简体) ), version 财务报告和审定财务报表 apiVersion,该模块的 API 版本被写到对面。 一个模块与 settings, (中文(简体) ), routes, (中文(简体) ), components, (中文(简体) ), initialize, (中文(简体) ), close 函数 pluginTypes 需要一个 name 还有一个 apiVersion; 服务器不提供停止启动的API版本. host 将服务器命名为模块需要( n)'uag':其他服务器在启动时拒绝. 一个模块 name 已使用不再使用;其另一个版本停止启动。 一个命名于 config.modules.disabled 未使用. use() 使用 ES 模块命名空间( S)require() a 默认导出.
  • settings(config, env) 在项目加载前,使用服务器的配置和环境,称为一次。 它返回一个普通对象(从不承诺),即 api.settings,冷冻;一个会抛出停止启动的错误,命名模块。 模块键在之前使用 router() 或者说 initialize();一个用后停止启动.
  • routes.form 地图 "<METHOD> /<path>" 改为 { name?, access?, rateLimit?, handler(req, res, api) }每张表格上挂有 formRoutes (见下文). name (默认: 模块的名称) 是主机速率限制的操作, 并且 rateLimit: { limit, windowMs } 默认操作员设置的覆盖。 接线员跑之前 呼叫员需要一个 access 关于表格上提交的表格:默认 ['create', 'update']· ; access: false 把支票交给处理者. req.form 是窗体( e)id, (中文(简体) ), name, (中文(简体) ), path, (中文(简体) ), title,以及 definition,它的JSON, , req.auth 打电话者和 req.signal 当客户端消失时中止 。 操作者回答,或返回 JSON 回答,或扔 api.errors.create(status, message, code)任何其它错误被回答500, 没有细节, 处理器开始后的一个错误 以一个 failed 活动。 有两个模块可能不会定义相同的路由(与之相匹配的快递:大小写不敏感,没有后继斜线),一个路由可能不会使用窗体自己的路由(S/, (中文(简体) ), /submission, (中文(简体) ), /exists, (中文(简体) ), /action, (中文(简体) ), /actions和那些宿主加起来.
  • components: formio.js组件, { type, script, style? } 作为文件路径或文件 URL. script 是一个经典的浏览器脚本,可以注册组件(已构建,而不是ES模块):服务器在启动时解析,并拒绝不解析,因为浏览器将每个组件都用一个脚本来获取. 它检查文件是否存在,没有两个模块定义一个类型,并保存在其中 server.modules.components();宿主为他们服务.
  • pluginTypes 可能是模块的API的一个函数, (api) => [...],用于需要它的插件类型.
  • initialize(api) 运行一次,在插件启动后,在任何请求之前;错误停止启动. close(api) 当服务器被销毁时运行( r)await server.destroy()),按倒序使用模块.
  • 列表(上册). 一个模块 apiVersion 列在 GET {project}/plugins 作为 module:<name>,带有路径和组件类型,从未设置过.

模块 API

一个模块得到一个 api,第1版的路线, initialize, (中文(简体) ), close 函数 pluginTypes数字 :

成员它会做什么
apiVersion, (中文(简体) ), name, (中文(简体) ), settings模块的API版本,名称和解析设置.
host运行它的服务器 : { name, version } (单位:千美元)appserver,或东道主自己的名字).
log.info, (中文(简体) ), log.warn, (中文(简体) ), log.error以模块名称为前缀的日志行.
plugins.get(type, name), (中文(简体) ), plugins.list(type), (中文(简体) ), plugins.settings(type, name)启用的插件和插件的操作员设置 .
requireAccess(auth, form, methods)投出403 除非呼叫者拥有其中之一 methods 在表格的提交.
files.read(form, value, auth, { maxBytes, component, signal })一个被存储的文件的字节,随呼叫者的证书和组件的存储检查一起读取.
forms.componentAt(form, path), (中文(简体) ), forms.componentByKey(form, key)存储窗体的一个组件,通过数据路径(忽略了行索引)或密钥.
errors.create(status, message, code), (中文(简体) ), errors.is(err)一个错误用该状态、消息和代码回答 .
stream(req, res, run, { heartbeatMs })答复 { result } 带什么 run({ signal, progress }) 返回,或向接受 text/event-stream, (中文(简体) ), progress 事件,然后 done 或者说 failed。 。 。 .

一个主机服务器扩展了模块:一个子类可以覆盖这些.

覆盖它的设定
hostName, (中文(简体) ), hostVersion服务器名称, 模块需要使用 host,及其版本(api.host) (中文(简体) ).
moduleApiVersions服务器提供的API版本([1]) (中文(简体) ).
createModuleApi(module)API,每个模块一个: { ...super.createModuleApi(module), ...more }。一个东道主会增加成员,但不会删除成员.
moduleClaims(definition)一个模块还声称,其他任何人都不能(如主机的MCP工具)作为标签; server.modules.claim(label, owner) 记录服务器本身.
reservedRouteNames路由名称(速率限制操作)模块可能不取.
moduleRouteHandlers(project, route, module){ before, wrap }: 在每个模块路径之前的中间软件( 呼叫器检查、 身体限制、 请求 id) , 以及环绕其运行的包装器( 速率限制由 route.name,错误形状).
moduleErrorBody(req, err)机体一个失败的路径答案,和一个 failed 事件载体( e){ status, error, code }) (中文(简体) ).
reservedFormPaths第一个路径段模块路由可能无法使用.

一个插件可以给定义其类型的模块命名 module (单位:千美元)module: '@scope/package/modules/name':当该类型缺失时,启动会说使用该模块.

窗体路线

routes.form 是模块在每个窗体上添加路由的通常方式。 在它下面,模块可以将任何快取路由器添加到每个形式上,并带有 formRoutes: 快速路由器(或 (req, res, next) 中间软件),或其中的列表,被挂入到每个窗体的路径上,没有访问权限检查,冲突检查或主机中间软件.

const { Router } = require('express');

const routes = Router();
routes.post('/echo', (req, res) => res.json({ form: req.form.form.name, user: req.auth?.user?._id }));

server.use({ formRoutes: routes });
  • 路由器按其路径安装在每个表格的路线上(/{formPath}/echo并按其编号/form/{formId}/echo),包括管理员在内的每个呼叫者,在表格本身的提供者和提交路线之前. req.form 是窗体和 req.auth 呼叫者,已经认证。 路线检查了打电话者对它所作所为的访问.
  • 团队下方的门户团队成员通过路径联系他们,从而产生提交需求(team_write 如代理操作; 以 id 表示, 仅作为管理员.
  • 请求路由器不回答( 它呼叫 next(),对于一个它不服务的形式,比如说)继续到下一个路由器,然后继续到表单自己的路线,仿佛模块不存在一样. 路由器从 req.form 因此,他们总是看到现在的表格.
  • 每个模块的路由器附加在 use() 命令,在模块的其余部分被应用后:一个失败的模块将不添加。 他们修过一次 router() 已构建服务器的路径: 在拒绝后添加更多 .
  • 路由错误 next(err),或者抛出,去服务器的错误处理,就像其他任何路径一样.
  • use() 拒绝 formRoutes 不属于路由器或中间软件(窗体的函数, (form) => router,没有。 信件以 调试,将列表中的每个模块命名为 source[i]: 运行 DEBUG=formio:* 看到他们.

版本与发布记录

@formio/appserver-core 共发布 132 个版本,首次发布于 2023/04/27;过去 12 个月发布了 49 个版本。

版本发布日期距今
2.26.4latest2026/11/078 天前
2.26.32026/11/069 天前
2.26.22026/11/069 天前
2.26.12026/11/0610 天前
2.26.02026/11/0510 天前
2.25.22026/10/3116 天前

其他发布通道:dev → 2.0.0-dev.38,rc → 2.13.1。

关于 @formio/appserver-core 的常见问题

@formio/appserver-core 是什么?

Form.io应用程序服务器是用于服务单个项目模板(包括表格,资源,角色等)的表演者运行时间应用程序服务器,位于一个部署的端口. 目标是实现快速的 单一租户部署

如何安装 @formio/appserver-core?

在项目目录运行 npm install @formio/appserver-core,或使用 pnpm add / yarn add / bun add。

@formio/appserver-core 支持 TypeScript 吗?

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

@formio/appserver-core 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@formio/appserver-core 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@formio/appserver-core 可以商用吗?

@formio/appserver-core 使用 OSL-3.0 许可。声明的许可为 OSL-3.0,请阅读许可原文确认使用条件。以上为概括,不构成法律意见,请以许可原文为准。

@formio/appserver-core 的下载量有多少?

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

@formio/appserver-core 还在维护吗?

最新版本 2.26.4 发布于 2026/11/07(8 天前);至今共发布 132 个版本,其中过去 12 个月发布了 49 个;首次发布于 2023/04/27。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。