
NocoBase EnvVariableInput 组件详解面向$env环境变量的安全输入方案【免费下载链接】nocobaseNocoBase is an open-source AI no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobaseEnvVariableInput是 NocoBase client-v2 中面向环境变量的单行输入组件它只暴露$env命名空间专门用于密钥、凭证、连接参数等敏感字段的配置。读完本文你将掌握该组件的完整用法、password遮盖模式的底层机制、值与{{ $env.X.Y }}表达式之间的双向转换原理以及它如何与 environment-variables 插件协同工作。组件定位与适用场景在 NocoBase 的业务系统构建中很多字段的值不应硬编码而应引用部署环境提供的变量——例如 S3 的 Access Key、OAuth 的 client secret、SMTP 连接参数等。官方文档对EnvVariableInput的定位是EnvVariableInput是面向环境变量的输入组件。它只暴露$env命名空间适合密钥、凭证和连接参数。它本质上是通用 VariableInput 的受限变体在源码 EnvVariableInput.tsx 中组件内部以namespaces{ENV_NAMESPACES}即[$env]调用VariableInput把变量选择器的可选范围牢牢限定在$env一棵树上避免用户误选$user等其他命名空间的变量。典型使用场景包括表单中的密钥/凭证字段Access Key Secret、API Key、OAuth Secret连接参数Base URL、SMTP 端口任何「要么填字面值、要么引用环境变量」的单行短文本字段。如果你需要字段同时支持类型化常量数字、布尔、日期和变量引用请改用 TypedVariableInput如果只是普通字面量输入直接使用 Antd 原生Input即可。基本用法从nocobase/client-v2引入组件后配合 AntdForm.Item即可直接使用import { EnvVariableInput } from nocobase/client-v2; Form.Item name{[options, accessKeySecret]} label{t(Access Key Secret)} EnvVariableInput password / /Form.Item;name{[options, accessKeySecret]}将值嵌套存储在表单数据的options.accessKeySecret中password开启遮盖模式详见下文组件是受控组件通过value/onChange与表单联动因此也可以不依赖Form.Item单独使用。仓库中的官方演示 env-variable-input.tsx 给出了一个更完整的形态用initialValues预置{{ $env.ACCESS_KEY_SECRET }}表达式配合placeholderInput secret or select env variable提示用户既可输入密钥字面值也可选择环境变量import React from react; import { Application, EnvVariableInput, Plugin } from nocobase/client-v2; import { Form } from antd; function DemoPage() { return ( Form layoutvertical style{{ maxWidth: 420 }} initialValues{{ accessKeySecret: {{ $env.ACCESS_KEY_SECRET }} }} Form.Item nameaccessKeySecret labelAccess Key Secret EnvVariableInput password placeholderInput secret or select env variable / /Form.Item /Form ); }password 模式密钥遮盖的实现原理password是该组件最具安全价值的能力。官方文档的描述是开启password后非变量字面值会用 AntdInput.Password遮盖变量表达式仍然可以通过变量选择器编辑。也就是说遮盖是有条件的。从源码 EnvVariableInput.tsx 可以看到完整判定逻辑const isVariableExpr (value?: string) typeof value string /\{\{\s*[^{}]?\s*\}\}/.test(value); if (password rest.value !isVariableExpr(rest.value)) { return ( Input.Password disabled{rest.disabled} placeholder{rest.placeholder} value{rest.value} onChange{(event) rest.onChange?.(event.target.value)} autoFocus / ); } return VariableInput {...rest} namespaces{ENV_NAMESPACES} converters{converters} /;具体行为当前值passwordfalsepasswordtrue字面值如my-secret普通可编辑文本AntdInput.Password遮盖显示可继续编辑变量表达式如{{ $env.API_KEY }}渲染为变量 pill可编辑仍渲染为变量 pill不被遮盖仍可通过变量选择器编辑这套行为被测试用例 EnvVariableInput.test.tsx 严格验证明文值my-secret在password下输入框的type属性为password而{{ $env.API_KEY }}在passwordtrue时依旧以带nb-variable-tag样式的 pill 展示且不会以明文文本出现。这样设计的原因很直观变量表达式本身不包含敏感信息只是对$env树上某个键的引用真正敏感的是被引用的值存储于服务端而用户在输入框里直接敲入的明文密钥才需要遮盖保护。API 一览官方文档给出的完整参数如下参数类型说明valuestring当前值onChange(value: string) void值变化回调addonBeforeReact.ReactNode前置内容disabledboolean是否禁用passwordboolean是否遮盖非变量字面值placeholderstring占位文字从源码 EnvVariableInputProps 可以看到这些 props 与接口一一对应。其中disabled在两种渲染分支Input.Password与变量编辑器下都会生效测试 EnvVariableInput.test.tsx 验证了禁用时编辑器contenteditable为falseplaceholder在变量编辑分支下会映射到data-placeholder属性见测试 L156-L164。值格式{{ $env.X.Y }}与变量的双向转换EnvVariableInput存储的值是形如{{ $env.ACCESS_KEY_SECRET }}、{{ $env.foo.bar }}的字符串——这是 NocoBase 服务端模板Handlebars 风格兼容的表达式格式。为了让变量选择器的内部路径表示如[$env, foo, bar]与存储字符串互相转换组件导出了两个工具函数并作为converters注入底层VariableHybridInputparseEnvPath字符串 → 路径数组源码 parseEnvPath 只接受「整个输入恰好是一个$env表达式」的情况锚定正则^\{\{\s*(\$env\.[^{}]?)\s*\}\}$并将其拆分为路径parseEnvPath({{ $env.API_KEY }}) // [$env, API_KEY] parseEnvPath({{ $env.foo.bar.baz }}) // [$env, foo, bar, baz] parseEnvPath( {{ $env.API_KEY }} ) // [$env, API_KEY]自动去空白 parseEnvPath(plain value) // undefined parseEnvPath({{ $user.name }}) // undefined非 $env 命名空间 parseEnvPath(prefix {{ $env.API_KEY }}) // undefined混合内容 parseEnvPath() // undefined以上行为在测试 EnvVariableInput.test.tsx 中逐一断言。注意「混合内容」前缀/后缀夹杂变量会被判定为 undefined这正是单行纯变量输入与 VariableTextArea 多行自由文本输入的区别。formatEnvPath路径数组 → 字符串formatEnvPath 负责把变量选择器选中的 meta tree 节点还原为服务端可用的表达式保证值「经 API 往返后字节稳定」formatEnvPath({ paths: [$env, API_KEY] }) // {{ $env.API_KEY }} formatEnvPath({ paths: [$env, foo, bar] }) // {{ $env.foo.bar }} formatEnvPath({ paths: [$user, name] }) // undefined拒绝非 $env formatEnvPath({ paths: [$env] }) // undefined仅有根节点 formatEnvPath(undefined) // undefined函数会先检查paths[0] ! $env || paths.length 2只有选中了$env下至少一级属性时才会生成表达式测试见 L81-L102。这两个转换器连同ENV_EXPR_REGEXP全局匹配$env变量用于渲染 pill一起由组件通过useMemo构造并注入VariableInputconst converters useMemoVariableHybridInputConverters( () ({ formatPathToValue: formatEnvPath, parseValueToPath: parseEnvPath, variableRegExp: ENV_EXPR_REGEXP, }), [], );这种「自定义 converters 收敛到单一命名空间」的模式正是VariableInput文档中converters参数所描述的典型用途见 variable-input.md。底层依赖$env变量树从哪来EnvVariableInput本身不产生变量数据它消费的是 flow-engine context 上的$env属性树。组件源码注释明确指出The$envtree is provided by the environment-variables pluginsflowEngine.context.defineProperty($env, ...); this component degrades gracefully to an empty picker when no env variables are defined.也就是说当环境中没有定义任何环境变量时变量选择器打开后为空组件仍可正常用于输入字面值——这是「优雅降级」设计。$env树的注册逻辑位于 environment-variables 插件见 registerEnvProperty.ts。核心要点数据来源通过 APIenvironmentVariables?paginatefalse惰性拉取环境变量列表首次读取时请求并由 flow-engine context 缓存选择器展开时不会重复请求meta 树结构每个变量名对应一个{ type: string, title: name }的属性节点其中type: secret的变量也被建模为字符串类型框架无关该注册函数不依赖 React hooks 或nocobase/client通过参数注入apiClient和翻译函数t可同时服务于 client-v2 与 v1 两套运行时。服务端对应的数据集合定义在 environmentVariables.ts包含三个字段字段类型说明namestring主键变量名需匹配^[A-Za-z][A-Za-z0-9_]*$见 re.tstypestringdefault或secretvaluetext变量值变量名只能以字母开头、由字母数字下划线组成这个约束保证了{{ $env.X.Y }}表达式能被可靠解析。字段命名空间中$env这个约定也贯穿于 flow-engine 的工作流变量选项例如 useWorkflowVariableOptions.tsx 中同样会读取该属性树。实战建议密钥字段务必开启passwordaccessKeySecret、apiKey、oauthSecret这类字段直接加password属性明文字面值会被Input.Password遮盖值优先用表达式而非明文在 environment-variables 插件 中先定义好变量再在表单里通过变量选择器引用{{ $env.XXX }}让密钥只存在于服务端注意变量命名约束环境变量名必须匹配^[A-Za-z][A-Za-z0-9_]*$含连字符或中文的键无法注册理解降级行为未安装/未启用 environment-variables 插件或变量列表为空时选择器为空但不影响字面值输入区分兄弟组件纯字面量用 AntdInput纯$env变量用EnvVariableInput通用变量用 VariableInput常量变量混合用 TypedVariableInput多行模板文本用 VariableTextArea。相关链接VariableInput — 通用单行变量输入TypedVariableInput — 同时支持常量和变量组件源码 与 单元测试$env 变量注册实现 与 数据集合定义官方演示 Demo【免费下载链接】nocobaseNocoBase is an open-source AI no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考