@aalis/schema-config 0.13.1 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -12
- package/dist/index.d.ts +195 -38
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +506 -115
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,28 +1,95 @@
|
|
|
1
1
|
# @aalis/schema-config
|
|
2
2
|
|
|
3
|
-
配置表单 Schema 词汇契约包:`ConfigSchema` / `SchemaField` / `SchemaGroup` / `SchemaArray` 及 `SchemaFieldTypes`
|
|
3
|
+
配置表单 Schema 词汇契约包:`ConfigSchema` / `SchemaField` / `SchemaGroup` / `SchemaArray` 及 `SchemaFieldTypes` 扩展点;声明与读取插件配置的 `defineConfig` / `ConfigOf` / `parseConfig`;对这套词汇的中立解释函数 `defaultsFrom` / `deepMergeDefaults` / `validateConfig` / `removeExtraFields`,密钥引用的类型与工具 `SecretRef` / `isSecretRef` / `mapSecretFields` / `SecretPosition`,配置危险键闸与拷贝 `isUnsafeConfigKey` / `cloneConfigObject`,以及插件因配置问题无法激活时在 `apply` 里抛出的 `configError` / `missingConfigError`(后者用于缺必填项;name 为 `ConfigError`、不带 stack,激活失败日志只有一行,不像程序崩溃)。
|
|
4
4
|
|
|
5
|
-
`@aalis/core` 把插件的 `configSchema` 当作 opaque 数据透传、不解释任何字段;表单词汇(label / options / textarea
|
|
5
|
+
`@aalis/core` 把插件的 `configSchema` 当作 opaque 数据透传、不解释任何字段;表单词汇(label / options / textarea …)属呈现层,统一住在本包。同一份 schema 既是表单描述,又是插件配置值类型的来源(`ConfigOf`)和运行时解析规则(`parseConfig`);渲染宿主(WebUI)与宿主政策(runtime 的配置同步)也用它消费 schema。
|
|
6
6
|
|
|
7
7
|
零运行时依赖:对 `@aalis/core` 只有 type-only 锚点(以 peer 依赖声明)。字段类型可由其他 api 包经 declaration merging 扩展(如 `api-llm` 注入 `'llm-ref'`)。
|
|
8
8
|
|
|
9
|
+
## 声明与读取
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { config, definePlugin, logger } from '@aalis/core';
|
|
13
|
+
import { defineConfig, parseConfig } from '@aalis/schema-config';
|
|
14
|
+
|
|
15
|
+
const configSchema = defineConfig({
|
|
16
|
+
apiKey: { type: 'string', label: 'API Key', required: true, secret: true },
|
|
17
|
+
port: { type: 'number', label: '端口', default: 8080, min: 1, max: 65535, integer: true },
|
|
18
|
+
mode: {
|
|
19
|
+
type: 'select',
|
|
20
|
+
label: '模式',
|
|
21
|
+
default: 'fast',
|
|
22
|
+
options: [
|
|
23
|
+
{ label: '快', value: 'fast' },
|
|
24
|
+
{ label: '稳', value: 'safe' },
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
export default definePlugin({
|
|
30
|
+
name: '@your-scope/plugin-x',
|
|
31
|
+
configSchema,
|
|
32
|
+
uses: { config, logger },
|
|
33
|
+
apply({ config, logger }) {
|
|
34
|
+
const cfg = parseConfig(configSchema, config.use, logger.use);
|
|
35
|
+
// cfg: { apiKey: string; port: number; mode: 'fast' | 'safe' }
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
- **`defineConfig(schema)`**:运行时原样返回传入的对象(不冻结、不加任何属性,WebUI 读的就是这个活对象),类型层保留字面量,返回值可直接放进 `definePlugin({ configSchema })`。不要给变量标 `ConfigSchema` 类型注解,注解会把字面量拓宽掉,`ConfigOf` 只能推出宽类型。推出的类型里各属性只读、`options` 是字面量元组;需要在运行时改写 schema(如按已注册的服务补全选项)时,经 `ConfigSchema` 或 `SchemaField` 类型的引用改写。
|
|
41
|
+
- **`ConfigOf<S>`**:从 schema 推导配置值类型。字段取 `SchemaFieldTypes` 里登记的取值类型(见下表);select / multiselect 有静态 `options`、没有 `dynamicOptions` 且 `allowCustom` 不为 `true` 时收窄为选项值的字面量联合,数字选项对应数字字面量。有 `default` 或 `required: true` 的字段必定存在,其余为可选;分组推为嵌套对象,总是存在;数组推为元素类型的数组,元素按同一规则推导。
|
|
42
|
+
- **`parseConfig(schema, raw, logger?)`**:按 schema 解析插件拿到的配置,返回 `ConfigOf` 类型的新对象,不改入参。之后的夹紧、跨字段约束等核对作用于返回值。
|
|
43
|
+
|
|
9
44
|
## 字段类型
|
|
10
45
|
|
|
11
|
-
|
|
46
|
+
本包内置的中立类型。「判定」一列是 `validateConfig` 与 `parseConfig` 共用的逐字段规则:
|
|
12
47
|
|
|
13
|
-
| type |
|
|
48
|
+
| type | 取值类型(`ConfigOf`) | 判定 |
|
|
14
49
|
|---|---|---|
|
|
15
|
-
| `string` / `textarea` | `string` |
|
|
16
|
-
| `number` |
|
|
17
|
-
| `boolean` | `boolean` |
|
|
18
|
-
| `select` | `string`
|
|
19
|
-
| `multiselect` | `
|
|
20
|
-
| `list` | `string[]` |
|
|
21
|
-
| `map` | `Record<string, string>` |
|
|
50
|
+
| `string` / `textarea` | `string` | 字符串;有限数字按字符串收;声明了 `pattern` 时按正则匹配;声明了 `format` 时按路径写法判定 |
|
|
51
|
+
| `number` | `number` | 有限数值;去掉首尾空白后非空、能完整解析为有限数的字符串按数字收;`min` / `max` / `integer` |
|
|
52
|
+
| `boolean` | `boolean` | 类型,不做转换 |
|
|
53
|
+
| `select` | 选项值的字面量联合,否则 `string` | 字符串或有限数字;有静态 `options`、没有 `dynamicOptions` 且 `allowCustom` 不为 `true` 时须是某个选项值 |
|
|
54
|
+
| `multiselect` | 选项值字面量联合的数组,否则 `string[]` | 数组;元素同 `select`;集合语义,WebUI 以勾选框编辑,不能表达重复项 |
|
|
55
|
+
| `list` | `string[]` | 数组,元素按字符串判定;有序,允许重复(如命令行参数) |
|
|
56
|
+
| `map` | `Record<string, string>` | 对象,每个值按字符串判定(如环境变量表) |
|
|
57
|
+
|
|
58
|
+
- **标量宽容**:YAML 里不加引号的纯数字(QQ 号、口令、端口、环境变量值)在期望字符串的位置照常可用,加了引号的数字在期望数字的位置照常可用;`parseConfig` 返回换算后的值。
|
|
59
|
+
- **`format`**:写宿主文件路径的 `string` / `textarea` 字段声明。`'absolute-path'` 只收绝对路径(`/…`、`C:\…` 或 `\\…`);`'executable'` 另收不含路径分隔符的命令名(按 PATH 查找),`C:foo` 这类带盘符的相对写法不算。判定忽略首尾空白,交给插件的值也去掉首尾空白;空串与只有空白都表示未填、不查(`required` 字段算缺失);只按写法判定、与宿主平台无关,Windows 形状的绝对路径在 POSIX 宿主上同样通过。配置里的相对路径没有可靠的基准(宿主进程的 cwd 不带语义),所以不收。
|
|
60
|
+
- **选项即取值范围**:选项按字符串比较,`parseConfig` 取选项声明的原值(WebUI 把数字选项存成字符串,读出时归位成数字)。
|
|
61
|
+
- **`dynamicOptions` / `allowCustom`**:两者影响取值判定,由本包声明。`dynamicOptions` 是动态选项来源的服务名(WebUI 经 webui-server 调该服务的 `listModels()` 或等价方法获取选项),声明后静态 `options` 不再是取值范围,只查取值是字符串或数字;`allowCustom` 表示接受选项之外的值,不查是否在选项内:WebUI 给 multiselect 提供手动输入;select 用它表示静态选项不全(例如由插件在运行时补全选项的字段)。
|
|
62
|
+
- **扩展字段类型**:api 包经 declaration merging 往 `SchemaFieldTypes` 登记类型名与取值类型(如 `'llm-ref': ModelRef`),`ConfigOf` 据此推导。本包不校验外来类型的取值:`validateConfig` 跳过,`parseConfig` 除把 `''` 当作未配置外原样透传。
|
|
63
|
+
|
|
64
|
+
## 密钥字段(`secret`)
|
|
65
|
+
|
|
66
|
+
`secret: true` 表示字段的值是凭据(API key、token、可能带账号密码的连接串),由本包声明,各宿主都按它处理:值不放在配置文档里,存进宿主的密钥存储(Node 宿主 `@aalis/runtime` 用家目录的 `secrets.yaml`),文档里只写引用 `{ $secret: '<键>' }`(类型 `SecretRef`),宿主把配置交给插件之前解析回原值,展示与回传都不给原值。标在 `map`、`list` 等非标量字段上时整个值算一个密钥。名字像凭据却不是凭据的字段(如 `maxTokens`)写 `secret: false` 表明已判断过。本包只声明词汇,不读写密钥存储。
|
|
67
|
+
|
|
68
|
+
- **`isSecretRef(value)`**:是不是引用,即只有 `$secret` 一个自有键、值为非空字符串的纯对象。只在 `secret: true` 的字段上有这层含义。
|
|
69
|
+
- **`mapSecretFields(schema, config, fn)`**:逐个处理配置里密钥字段上的值(顶层、分组内、数组元素内;值为 `undefined` 的跳过),`fn` 收到值与位置 `SecretPosition`(`path` 是点号路径,数组元素里的不带下标;`inArray` 表示在数组元素里),`fn` 返回 `undefined` 时删掉这个键。不改入参:有改动时返回浅拷贝(没动到的部分与入参共享),没有改动时返回入参本身,调用方要改写结果请先复制。宿主拆出、解析密钥与给呈现方去掉密钥都用它。
|
|
70
|
+
- **`validateConfig`** 校验的是文档:密钥字段上的引用算合法,不查键在不在。
|
|
71
|
+
- **`parseConfig`** 给插件用:密钥字段上仍是引用,说明宿主没能解析它(键不在密钥存储里),一律不可恢复,消息点名键名;不看 `default` 与 `onInvalid`,在数组元素里也让整次解析失败,不只丢这一条元素。回落默认值会悄悄连上别的东西(例如默认的本机数据库),所以不回落。
|
|
72
|
+
- **`defaultsFrom`** 不产出密钥字段:派生结果会被宿主写进配置文档,密钥的默认值不进文档;`parseConfig` 照常补上默认值。
|
|
73
|
+
|
|
74
|
+
## parseConfig 的处置
|
|
75
|
+
|
|
76
|
+
- **缺失**:`undefined` 与 `null`(YAML 裸键);`required` 字段另把 `''` 当作缺失(WebUI 与脚手架用 `''` 表示未填;声明了 `format` 的只有空白也算),外来类型的 `''` 一律当作缺失(WebUI 给未选的 `llm-ref` 存 `''`)。有 `default` 用 `default` 的拷贝;无 `default` 且 `required` 不可恢复;否则省略该键。
|
|
77
|
+
- **无效**(不符合上表的判定):未声明 `onInvalid` 时保持宽容处置:有 `default` 回落并告警;无 `default` 且 `required` 不可恢复;否则省略并告警。字段声明 `onInvalid: 'error'` 时,显式无效值即使有 `default` 也抛 `ConfigError`;它不改变 `required` 的缺省含义,`undefined` / `null` 仍走上述缺省规则。
|
|
78
|
+
- **list / map / multiselect**:默认坏元素、坏值逐个丢弃并告警,其余保留;稀疏数组的空位和 map 的保留键也属于坏成员。严格字段只要含一个坏成员就拒绝整个值,不返回部分结果。
|
|
79
|
+
- **分组**:值不是对象时默认告警,整组按空对象解析,子字段各取默认值。显式给非对象且分组含严格字段时拒绝;`undefined` / `null` 仍视为缺省。
|
|
80
|
+
- **数组**:值不是数组按无效处理,含严格元素字段时显式无效的数组值会被拒绝;元素不是对象、或元素内有不可恢复的字段时只丢这一条元素并告警,邻居元素照常解析;元素字段的默认值逐元素补齐(runtime 的配置同步不补数组元素的默认值)。
|
|
81
|
+
- **整体配置**:显式非对象且 schema 含严格字段时拒绝;`undefined` / `null` 仍视为缺省。严格错误说明字段路径与安全的类型或约束原因;集合的下标可定位,map 的键可能含密钥,因此错误只定位到 map 字段,不写用户值或键。
|
|
82
|
+
- **schema 外的键**:丢弃并告警。runtime 已先裁掉顶层与分组内的,这里主要覆盖数组元素,以及不经 runtime 的宿主。
|
|
83
|
+
- **不可恢复**(顶层或分组内):缺失抛 `missingConfigError`,无效抛 `configError`,插件随之进 error 态,在 WebUI 保存或配置文件热重载后重试激活。密钥字段上没被解析的引用见上节,在任何位置都不可恢复。
|
|
84
|
+
- **告警文案**:`配置项 <路径> <原因>,改用默认值 <JSON>`、`配置项 <路径> <原因>,已忽略`、`配置项 <数组路径>[i] 已忽略:<字段> <原因>`。只写路径、类型名与约束,不写原值(可能是密钥);默认值会写出。
|
|
85
|
+
|
|
86
|
+
数组也可声明 `onInvalid: 'error'`:非对象元素或元素内不可恢复的字段会拒绝整个数组,避免丢弃坏项后触发空数组的业务默认;元素内普通字段仍按自身的回落策略解析。未声明时继续逐项跳过,适合相互独立的 server 列表。
|
|
87
|
+
|
|
88
|
+
`validateConfig(schema, config)` 用同一份判定做只读检查,返回问题清单(`kind` 为 `missing` 或 `invalid`),不转换、不回填、不裁剪;它把 `undefined` / `null` 当作未配置,`required` 字段另把 `''`(声明了 `format` 的字符串只有空白也算)当作缺失,与 `parseConfig` 同一判定;只在 `required` 且无 `default` 时报缺,声明了 `default` 的永远不算缺。`onInvalid` 改变 `parseConfig` 的处置,不改变校验器的判定或报告。宿主用它告警或拦截保存:runtime 的配置同步对启用中的插件打告警,WebUI 保存插件配置时拒绝本次新引入的 `invalid`。
|
|
22
89
|
|
|
23
90
|
`list` 与 `map` 的补充约定:
|
|
24
91
|
|
|
25
|
-
- **默认值**:`default` 分别写数组与对象,`defaultsFrom`
|
|
92
|
+
- **默认值**:`default` 分别写数组与对象,`defaultsFrom` 按值拷贝(`secret: true` 的除外)。`deepMergeDefaults` 合并默认值时递归合并对象(runtime 的配置同步与 WebUI 保存插件配置都用它),因此顶层或分组里的 `map` 会按键补齐:默认映射中的键总会回到用户配置里,删掉也无效。需要用户可删除的预置条目时,默认值写 `{}`,由插件代码兜底。`list` 不参与合并,用户配置了就整体采用。
|
|
26
93
|
- **未知字段裁剪**:`removeExtraFields` 把 `map` 当作叶子整体保留,不按键裁剪。
|
|
27
94
|
- **缺省 UI**(WebUI 的 SchemaForm):两者都渲染为多行文本框。`list` 每行一项,空白行忽略;`map` 每行一条 `KEY=VALUE`,按第一个 `=` 切分,键去掉首尾空白,值原样保留,缺少 `=` 或键为空的行不保存。现有的数字、布尔项或值按字符串显示,编辑后写成字符串;其余无法按这套规则逐行表达的值(项或值本身含换行、`list` 含空白项、`null`、嵌套的数组或对象等)会让该字段只读显示,需在配置文件中编辑。旧版存下的空串按空列表 / 空映射显示,保存时写成 `[]` / `{}`。
|
|
28
95
|
|
|
@@ -40,3 +107,5 @@
|
|
|
40
107
|
就是一次 minor,届时所有已发布消费者的范围会拒收新版,node_modules 里出现两份副本——而
|
|
41
108
|
declaration merging 是按模块副本生效的,`SchemaFieldTypes` / `SchemaField` 的合并面会就此裂开
|
|
42
109
|
(一份合并了 `'llm-ref'`,另一份没有)。宽区间让整个 0.x 段自由流动,加词汇零级联。
|
|
110
|
+
|
|
111
|
+
解析以调用方传入的值为准。宿主与 Core 的配置拷贝会移除 `__proto__` / `constructor` / `prototype` 保留键,`parseConfig` 无法诊断在上游已被删除的条目;配置字典(含 env)不能使用这些键。
|
package/dist/index.d.ts
CHANGED
|
@@ -2,35 +2,39 @@
|
|
|
2
2
|
* Schema 字段类型注册表 —— declaration merging 扩展点。
|
|
3
3
|
*
|
|
4
4
|
* 本包只内置基础类型;带业务语义的类型由对应 api 包合并声明
|
|
5
|
-
* (如 `'llm-ref'` 由 @aalis/api-llm 注入)。key 即类型名,value
|
|
5
|
+
* (如 `'llm-ref'` 由 @aalis/api-llm 注入)。key 即类型名,value 是该类型的取值类型,
|
|
6
|
+
* {@link ConfigOf} 据此推导配置值类型。
|
|
6
7
|
*
|
|
7
8
|
* ```ts
|
|
8
9
|
* declare module '@aalis/schema-config' {
|
|
9
10
|
* interface SchemaFieldTypes {
|
|
10
|
-
* 'llm-ref':
|
|
11
|
+
* 'llm-ref': ModelRef;
|
|
11
12
|
* }
|
|
12
13
|
* }
|
|
13
14
|
* ```
|
|
15
|
+
*
|
|
16
|
+
* 外来类型的取值不经本包校验:parseConfig 除把 `''` 当作未配置外原样透传,value 只是类型层的声明。
|
|
14
17
|
*/
|
|
15
18
|
export interface SchemaFieldTypes {
|
|
16
|
-
string:
|
|
17
|
-
number:
|
|
18
|
-
boolean:
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
|
|
19
|
+
string: string;
|
|
20
|
+
number: number;
|
|
21
|
+
boolean: boolean;
|
|
22
|
+
/** 有静态 options、没有 dynamicOptions 且 allowCustom 不为 true 时,ConfigOf 收窄为选项值的字面量联合 */
|
|
23
|
+
select: string;
|
|
24
|
+
/** 有静态 options、没有 dynamicOptions 且 allowCustom 不为 true 时,ConfigOf 收窄为选项值字面量联合的数组 */
|
|
25
|
+
multiselect: string[];
|
|
26
|
+
textarea: string;
|
|
27
|
+
/** 有序字符串列表:保序、允许重复;与 multiselect 的集合语义不同 */
|
|
28
|
+
list: string[];
|
|
29
|
+
/** 字符串映射,如环境变量表 */
|
|
30
|
+
map: Record<string, string>;
|
|
26
31
|
}
|
|
27
32
|
export type SchemaFieldType = keyof SchemaFieldTypes & string;
|
|
28
33
|
/**
|
|
29
34
|
* 单个配置字段。
|
|
30
35
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* (@aalis/api-webui)通过 declaration merging 注入。
|
|
36
|
+
* 声明各渲染宿主共需的字段、影响取值判定的属性(`dynamicOptions` / `allowCustom`)与各宿主都按它处理的
|
|
37
|
+
* `secret`;只影响单一宿主呈现的交互属性由消费它们的宿主 api 包通过 declaration merging 注入。
|
|
34
38
|
*/
|
|
35
39
|
export interface SchemaField {
|
|
36
40
|
type: SchemaFieldType;
|
|
@@ -38,22 +42,76 @@ export interface SchemaField {
|
|
|
38
42
|
description?: string;
|
|
39
43
|
default?: unknown;
|
|
40
44
|
required?: boolean;
|
|
41
|
-
/**
|
|
45
|
+
/** 显式配置的值无效时拒绝激活;缺省仍按 default / required 处理,省略时保持宽容回落 */
|
|
46
|
+
onInvalid?: 'error';
|
|
47
|
+
/**
|
|
48
|
+
* select / multiselect 类型的静态选项。没有 dynamicOptions、allowCustom 不为 true 时即取值范围:
|
|
49
|
+
* 值按字符串与选项值比较,parseConfig 取选项声明的原值(数字选项存成字符串也能归位)
|
|
50
|
+
*/
|
|
42
51
|
options?: Array<{
|
|
43
52
|
label: string;
|
|
44
53
|
value: string | number;
|
|
45
54
|
}>;
|
|
46
|
-
/**
|
|
55
|
+
/**
|
|
56
|
+
* select / multiselect 的动态选项来源:服务名(WebUI 经 webui-server 调该服务的 listModels() 或等价方法获取选项)。
|
|
57
|
+
* 声明后静态 options 不再是取值范围:parseConfig / validateConfig 只查取值是字符串或数字,ConfigOf 推为 string / string[]
|
|
58
|
+
*/
|
|
59
|
+
dynamicOptions?: string;
|
|
60
|
+
/**
|
|
61
|
+
* 是否允许选项之外的值。为 true 时 parseConfig / validateConfig 不查取值是否在选项内,ConfigOf 推为 string / string[]。
|
|
62
|
+
* WebUI 只给 multiselect 提供手动输入;select 用它表示静态选项不全(例如由插件在运行时补全选项的字段)
|
|
63
|
+
*/
|
|
64
|
+
allowCustom?: boolean;
|
|
65
|
+
/** number:数值下限(含),validateConfig 与 parseConfig 强制。无 default 的 number 表单不预填(留空=走服务端默认),带 min 仍建议声明 default 以免长期处于缺失告警 */
|
|
47
66
|
min?: number;
|
|
48
|
-
/** number:数值上限(含),validateConfig 强制 */
|
|
67
|
+
/** number:数值上限(含),validateConfig 与 parseConfig 强制 */
|
|
49
68
|
max?: number;
|
|
50
|
-
/** number:仅接受整数,validateConfig 强制 */
|
|
69
|
+
/** number:仅接受整数,validateConfig 与 parseConfig 强制 */
|
|
51
70
|
integer?: boolean;
|
|
52
|
-
/** number:步进——纯 UI
|
|
71
|
+
/** number:步进——纯 UI 提示(浮点取模不可靠),不校验 */
|
|
53
72
|
step?: number;
|
|
54
|
-
/** string / textarea:正则约束(RegExp 源文本,test() 子串语义——要整串匹配请显式 ^…$),validateConfig 强制;模式本身非法则跳过该检查 */
|
|
73
|
+
/** string / textarea:正则约束(RegExp 源文本,test() 子串语义——要整串匹配请显式 ^…$),validateConfig 与 parseConfig 强制;模式本身非法则跳过该检查 */
|
|
55
74
|
pattern?: string;
|
|
75
|
+
/**
|
|
76
|
+
* string / textarea:宿主文件路径的写法,validateConfig 与 parseConfig 强制;判定忽略首尾空白,parseConfig 交出的值也去掉首尾空白;
|
|
77
|
+
* 空串与只有空白都表示未填(required 字段算缺失),不查。
|
|
78
|
+
* 配置里的相对路径没有可靠的基准(宿主进程的 cwd 不带语义),所以路径一律写绝对路径:
|
|
79
|
+
* - `absolute-path`:绝对路径(`/…`、`C:\…` 或 `\\…`);
|
|
80
|
+
* - `executable`:可执行文件,绝对路径或不含路径分隔符的命令名(按 PATH 查找;`C:foo` 这类带盘符的相对写法不算)。
|
|
81
|
+
* 只按写法判定、与宿主平台无关:Windows 形状的绝对路径在 POSIX 宿主上也算通过。
|
|
82
|
+
*/
|
|
83
|
+
format?: 'absolute-path' | 'executable';
|
|
84
|
+
/**
|
|
85
|
+
* 值是凭据(API key、token、带账号密码的连接串)。宿主不把它放在配置文档里:值存进宿主的密钥存储
|
|
86
|
+
* (Node 宿主是家目录的 `secrets.yaml`),文档里只写引用 {@link SecretRef},交给插件之前解析回原值;
|
|
87
|
+
* 展示与回传都不给原值。标在 map、list 上时整个值算一个密钥。插件照常经 parseConfig 读到原值;
|
|
88
|
+
* 引用没被宿主解析(键不在密钥存储里)时 parseConfig 拒绝激活,不回落默认值。
|
|
89
|
+
* 名字像凭据却不是凭据的字段(如 `maxTokens`)写 `false` 表明已判断过
|
|
90
|
+
*/
|
|
91
|
+
secret?: boolean;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* 配置文档里密钥字段的值:指向宿主密钥存储里的一个键。几个字段可以指向同一个键。
|
|
95
|
+
* 只在 `secret: true` 的字段上有这层含义;别的字段上它只是一个普通对象。
|
|
96
|
+
*/
|
|
97
|
+
export interface SecretRef {
|
|
98
|
+
$secret: string;
|
|
99
|
+
}
|
|
100
|
+
/** 是不是密钥引用:只有 `$secret` 一个自有键、值为非空字符串的纯对象 */
|
|
101
|
+
export declare function isSecretRef(value: unknown): value is SecretRef;
|
|
102
|
+
/** 密钥字段在 schema 里的位置,交给 {@link mapSecretFields} 的回调 */
|
|
103
|
+
export interface SecretPosition {
|
|
104
|
+
/** 点号路径,数组元素里的字段不带下标:`apiKey`、`auth.token`、`connections.accessToken` */
|
|
105
|
+
path: string;
|
|
106
|
+
/** 字段在数组元素里(同一个 path 对应多个值) */
|
|
107
|
+
inArray: boolean;
|
|
56
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* 逐个处理配置里密钥字段上的值(顶层、分组内、数组元素内;值为 undefined 的不处理),不改入参:有改动时返回浅拷贝
|
|
111
|
+
* (没动到的部分与入参共享),没有改动时返回入参本身,调用方要改写结果请先复制。回调返回 undefined 时删掉这个键。
|
|
112
|
+
* 宿主拆出、解析密钥与给呈现方去掉密钥都用它,密钥字段的位置只在这里认。
|
|
113
|
+
*/
|
|
114
|
+
export declare function mapSecretFields(schema: ConfigSchema | undefined, config: Record<string, unknown>, fn: (value: unknown, at: SecretPosition) => unknown): Record<string, unknown>;
|
|
57
115
|
export interface SchemaGroup {
|
|
58
116
|
label?: string;
|
|
59
117
|
description?: string;
|
|
@@ -67,9 +125,71 @@ export interface SchemaArray {
|
|
|
67
125
|
/** 数组每个元素的字段定义 */
|
|
68
126
|
items: Record<string, SchemaField>;
|
|
69
127
|
default?: unknown[];
|
|
128
|
+
/** 遇到非对象元素或元素内不可恢复的字段时拒绝整个数组;默认只丢弃该元素。 */
|
|
129
|
+
onInvalid?: 'error';
|
|
70
130
|
}
|
|
71
131
|
/** 配置 Schema:顶层 key 可以是字段、分组或数组 */
|
|
72
132
|
export type ConfigSchema = Record<string, SchemaField | SchemaGroup | SchemaArray>;
|
|
133
|
+
/**
|
|
134
|
+
* 声明插件的配置 schema:运行时原样返回传入的对象(不冻结、不加任何属性),类型层保留字面量,
|
|
135
|
+
* 供 {@link ConfigOf} 推出配置值类型。返回值可直接放进 `definePlugin({ configSchema })`。
|
|
136
|
+
*
|
|
137
|
+
* 别给变量标 `ConfigSchema` 类型注解:注解会把字面量拓宽掉,ConfigOf 只能推出宽类型。
|
|
138
|
+
* 推出的类型里各属性是只读的、options 是字面量元组;要在运行时改写 schema(WebUI 读的是这个活对象),
|
|
139
|
+
* 经 `ConfigSchema` 类型的引用改写(如 `const live: ConfigSchema = configSchema`)。
|
|
140
|
+
*/
|
|
141
|
+
export declare function defineConfig<const S extends ConfigSchema>(schema: S): S;
|
|
142
|
+
/** 展开交叉类型,悬停提示显示成一个对象 */
|
|
143
|
+
type Flatten<T> = {
|
|
144
|
+
[K in keyof T]: T[K];
|
|
145
|
+
} & {};
|
|
146
|
+
/** parseConfig 成功后必定存在的条目:分组、required 字段、声明了 default 的字段与数组 */
|
|
147
|
+
type IsPresent<E> = E extends {
|
|
148
|
+
fields: unknown;
|
|
149
|
+
} ? true : E extends {
|
|
150
|
+
required: true;
|
|
151
|
+
} ? true : E extends {
|
|
152
|
+
default: infer D;
|
|
153
|
+
} ? [D] extends [undefined] ? false : true : false;
|
|
154
|
+
type HasDynamicOptions<E> = E extends {
|
|
155
|
+
dynamicOptions: infer D;
|
|
156
|
+
} ? ([D] extends [undefined] ? false : true) : false;
|
|
157
|
+
/** allowCustom 不是字面量 false 时按可能允许算:宽类型总是安全的 */
|
|
158
|
+
type AllowsCustom<E> = E extends {
|
|
159
|
+
allowCustom: infer A;
|
|
160
|
+
} ? (true extends A ? true : false) : false;
|
|
161
|
+
type StaticOptionValue<E> = E extends {
|
|
162
|
+
options: ReadonlyArray<{
|
|
163
|
+
value: infer V;
|
|
164
|
+
}>;
|
|
165
|
+
} ? V : never;
|
|
166
|
+
/** 有非空静态 options 且没有动态来源时收窄为选项值的字面量联合,否则取宽类型 */
|
|
167
|
+
type ChoiceValue<E> = HasDynamicOptions<E> extends true ? string : [StaticOptionValue<E>] extends [never] ? string : StaticOptionValue<E>;
|
|
168
|
+
type FieldValue<E> = E extends {
|
|
169
|
+
type: 'select';
|
|
170
|
+
} ? AllowsCustom<E> extends true ? string : ChoiceValue<E> : E extends {
|
|
171
|
+
type: 'multiselect';
|
|
172
|
+
} ? (AllowsCustom<E> extends true ? string : ChoiceValue<E>)[] : E extends {
|
|
173
|
+
type: infer T extends keyof SchemaFieldTypes;
|
|
174
|
+
} ? SchemaFieldTypes[T] : unknown;
|
|
175
|
+
type EntryValue<E> = E extends {
|
|
176
|
+
fields: infer F extends ConfigSchema;
|
|
177
|
+
} ? ConfigOf<F> : E extends {
|
|
178
|
+
type: 'array';
|
|
179
|
+
items: infer I extends ConfigSchema;
|
|
180
|
+
} ? ConfigOf<I>[] : FieldValue<E>;
|
|
181
|
+
/**
|
|
182
|
+
* 从 schema 推导 {@link parseConfig} 返回的配置值类型(schema 须经 {@link defineConfig} 声明才保留字面量)。
|
|
183
|
+
*
|
|
184
|
+
* - 字段取 {@link SchemaFieldTypes} 里登记的取值类型;select / multiselect 见该注册表的说明
|
|
185
|
+
* - 有 default 或 `required: true` 的字段必定存在,其余为可选(parseConfig 省略未配置的键)
|
|
186
|
+
* - 分组推为嵌套对象,总是存在;数组推为元素类型的数组,元素按同一规则推导
|
|
187
|
+
*/
|
|
188
|
+
export type ConfigOf<S extends ConfigSchema> = Flatten<{
|
|
189
|
+
-readonly [K in keyof S as IsPresent<S[K]> extends true ? K : never]: EntryValue<S[K]>;
|
|
190
|
+
} & {
|
|
191
|
+
-readonly [K in keyof S as IsPresent<S[K]> extends true ? never : K]?: EntryValue<S[K]>;
|
|
192
|
+
}>;
|
|
73
193
|
/**
|
|
74
194
|
* core 基础设施配置(name / logLevel / slowThresholdMs)的表单描述。
|
|
75
195
|
*
|
|
@@ -78,7 +198,7 @@ export type ConfigSchema = Record<string, SchemaField | SchemaGroup | SchemaArra
|
|
|
78
198
|
*/
|
|
79
199
|
export declare const CORE_CONFIG_SCHEMA: ConfigSchema;
|
|
80
200
|
/**
|
|
81
|
-
* 从 ConfigSchema
|
|
201
|
+
* 从 ConfigSchema 派生默认配置(密钥字段除外)。
|
|
82
202
|
*
|
|
83
203
|
* ConfigSchema 是插件配置的**唯一声明来源**:每个字段的 `default` 就是运行时默认值,
|
|
84
204
|
* 不存在第二份手抄的默认值对象。宿主在注册插件前用本函数派生出默认配置并深合并进配置文档,
|
|
@@ -88,8 +208,16 @@ export declare const CORE_CONFIG_SCHEMA: ConfigSchema;
|
|
|
88
208
|
* - SchemaField / SchemaArray:取 `default`(没写 default 的字段不产出键,
|
|
89
209
|
* 等同于「该字段无默认值」——读取方自行处理 undefined)
|
|
90
210
|
* - SchemaGroup:递归 `fields`,总是产出嵌套对象(即使子字段全无默认值)
|
|
211
|
+
* - `secret: true` 的字段不产出:派生结果会被写进配置文档,密钥的默认值不进文档(map 的默认值还会被深合并进
|
|
212
|
+
* 引用对象),插件经 parseConfig 照常补上
|
|
91
213
|
*/
|
|
92
214
|
export declare function defaultsFrom(schema: ConfigSchema | undefined): Record<string, unknown>;
|
|
215
|
+
/**
|
|
216
|
+
* 把默认值(通常是 {@link defaultsFrom} 的结果)深合并进配置:只填充缺失的键,已有的值(含显式 null)不覆盖。
|
|
217
|
+
* 嵌套对象递归合并,只写了半块的分组照样补齐其余默认子键;数组与基础类型按「已存在则保留」处理。
|
|
218
|
+
* 宿主的配置同步与 WebUI 保存插件配置用同一个合并,两条路径写出的配置形状一致。
|
|
219
|
+
*/
|
|
220
|
+
export declare function deepMergeDefaults(defaults: Record<string, unknown>, current: Record<string, unknown>): Record<string, unknown>;
|
|
93
221
|
/**
|
|
94
222
|
* validateConfig 发现的单条问题。path 以点号/下标定位(如 `server.port`、`hosts[2]`)。
|
|
95
223
|
* kind 区分两类性质不同的问题,供调用方分级处置:
|
|
@@ -101,38 +229,66 @@ export interface SchemaIssue {
|
|
|
101
229
|
message: string;
|
|
102
230
|
kind: 'missing' | 'invalid';
|
|
103
231
|
}
|
|
232
|
+
/** 字段类型是不是本包内置的:内置类型的取值经 validateConfig 与 parseConfig 校验,外来类型(如 'llm-ref')的不经 */
|
|
233
|
+
export declare function isBuiltinFieldType(type: string): boolean;
|
|
104
234
|
/**
|
|
105
235
|
* 按 ConfigSchema 对配置做只读结构校验,返回问题清单(空数组 = 无问题)。
|
|
106
236
|
*
|
|
107
237
|
* 定位与边界:
|
|
108
|
-
* - **只读**:不转换、不回填、不裁剪——回填是 defaultsFrom,裁剪是 removeExtraFields。
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
238
|
+
* - **只读**:不转换、不回填、不裁剪——回填是 defaultsFrom,裁剪是 removeExtraFields,取值是 parseConfig。
|
|
239
|
+
* 逐字段判定与 parseConfig 共用同一份:这里报 invalid 的值,parseConfig 会回落、忽略或拒绝。
|
|
240
|
+
* 校验器出错的最大代价必须始终是"少一条警告",因此它对畸形 schema 不抛错。
|
|
241
|
+
* - **只解释本包的词汇**:type/required、约束键、影响取值的 dynamicOptions/allowCustom 与 secret;
|
|
242
|
+
* 宿主经 declaration merging 注入的呈现属性一概不解读。
|
|
243
|
+
* - **校验的是文档**:`secret` 字段上的 {@link SecretRef} 算合法(值在宿主的密钥存储里),不查引用的键在不在。
|
|
244
|
+
* - **标量宽容**:期望字符串的位置(string/textarea、list 元素、map 值、选项比较)接受有限数字;
|
|
245
|
+
* 期望数字的位置接受去掉首尾空白后能完整解析为有限数的字符串。boolean 不做转换。
|
|
246
|
+
* - **options 即取值范围**:select 有静态 options、没有 dynamicOptions 且 allowCustom 不为 true 时,值须是
|
|
247
|
+
* 某个选项值(按字符串比较);multiselect 同样逐元素判定。
|
|
115
248
|
* - **约束键**:number 强制 min/max(含边界)与 integer,string/textarea 强制
|
|
116
|
-
* pattern
|
|
249
|
+
* pattern(模式非法则跳过该检查)与 format(空串与只有空白不查);step 是纯 UI 提示不校验。约束只在类型
|
|
117
250
|
* 检查通过后评估——类型都不对时报类型错,不叠报约束错。
|
|
118
|
-
* - **list / map**:list
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
* 未声明 default 时报缺——顶层/分组的默认值在调用点已合并,数组元素的默认值
|
|
251
|
+
* - **list / map**:list 须为数组、map 须为对象,逐元素 / 逐值报错,路径形如 `args[1]`、`env.KEY`。
|
|
252
|
+
* - **宽容缺失**:undefined 与 null(YAML 裸键)视为"未配置",required 字段的 `''` 也算未配置(WebUI 与脚手架
|
|
253
|
+
* 用 `''` 表示未填,与 parseConfig 一致;声明了 format 的只有空白也算;空数组仍算已配置),仅在 required 且未声明 default 时报缺——顶层/分组的默认值在调用点已合并,数组元素的默认值
|
|
122
254
|
* 不参与合并(defaultsFrom 把 SchemaArray 当叶子),靠 default 声明本身放行。
|
|
123
255
|
*
|
|
124
|
-
* 政策留给调用方:config-sync 对启用插件打 warn
|
|
125
|
-
*
|
|
126
|
-
* (存量问题与 `missing` 放行——拦新不追旧,半成品配置允许落盘)。
|
|
256
|
+
* 政策留给调用方:config-sync 对启用插件打 warn(禁用插件的配置是休眠数据,不告警),
|
|
257
|
+
* webui 的 PUT 只拦**新增**的 `invalid`(存量问题与 `missing` 放行——拦新不追旧,半成品配置允许落盘)。
|
|
127
258
|
*/
|
|
128
259
|
export declare function validateConfig(schema: ConfigSchema | undefined, config: Record<string, unknown>): SchemaIssue[];
|
|
260
|
+
/**
|
|
261
|
+
* 按 schema 解析插件拿到的配置,返回 {@link ConfigOf} 类型的新对象(不改入参)。插件在 apply 里用它读配置:
|
|
262
|
+
* `const cfg = parseConfig(configSchema, caps.config, caps.logger)`,之后的夹紧、跨字段约束等核对作用于 cfg。
|
|
263
|
+
*
|
|
264
|
+
* - **缺失**:undefined 与 null;required 字段另把 `''` 当作缺失(WebUI 与脚手架用 `''` 表示未填;声明了 format 的
|
|
265
|
+
* 只有空白也算),外来类型的 `''` 一律当作缺失。有 default 用 default(拷贝),无 default 且 required 不可恢复,否则省略该键。
|
|
266
|
+
* - **无效**:逐字段判定与 validateConfig 共用(标量宽容、选项即取值范围、约束键)。
|
|
267
|
+
* 默认有 default 回落并告警;无 default 且 required 不可恢复;否则省略并告警。
|
|
268
|
+
* `onInvalid: 'error'` 的字段遇到显式无效值或坏集合成员时,即使有 default 也不可恢复。
|
|
269
|
+
* - **外来类型**:除 `''` 外原样透传,不校验。
|
|
270
|
+
* - **密钥字段**:宿主交给插件之前已把引用解析成原值;`secret` 字段上仍是 {@link SecretRef},说明引用的键不在
|
|
271
|
+
* 宿主的密钥存储里,一律不可恢复(不回落 default,数组元素里的也不只丢这一条),消息点名键名。owner 写了引用,
|
|
272
|
+
* 引用落空就是配置错误,回落默认值会悄悄连上别的东西(例如默认的本机数据库)。
|
|
273
|
+
* - **list / map / multiselect**:默认坏元素、坏值逐个丢弃并告警;严格字段拒绝整个值。
|
|
274
|
+
* - **分组**:值不是对象时默认告警并按空对象解析;含严格字段时拒绝显式无效的分组值。
|
|
275
|
+
* - **数组**:值不是数组按无效处理,含严格元素字段时拒绝显式无效的数组值;元素不是对象、或元素内有不可恢复的字段时只丢这一条元素并告警;
|
|
276
|
+
* 数组自身声明 `onInvalid: 'error'` 时不丢元素而是拒绝整个数组。元素字段的默认值逐元素补齐。
|
|
277
|
+
* - **schema 外的键**:丢弃并告警。
|
|
278
|
+
* - **不可恢复**(顶层或分组内):缺失抛 {@link missingConfigError},无效抛 {@link configError},插件随之进 error 态。
|
|
279
|
+
*
|
|
280
|
+
* 告警只写路径、类型名与约束,不写原值(可能是密钥);默认值可以写。
|
|
281
|
+
*/
|
|
282
|
+
export declare function parseConfig<S extends ConfigSchema>(schema: S, raw: unknown, logger?: {
|
|
283
|
+
warn(message: string): void;
|
|
284
|
+
}): ConfigOf<S>;
|
|
129
285
|
/**
|
|
130
286
|
* 按 schema 键集裁掉未知字段。configSchema 是插件配置的**唯一声明来源**(默认值也从它派生),
|
|
131
287
|
* 所以它的键集就是完整的白名单:不在 schema 里的字段,要么是用户手写的错别字,
|
|
132
288
|
* 要么是已废弃的旧字段,裁掉即归位。无 schema 的插件不裁(见调用方守卫)。
|
|
133
289
|
*
|
|
134
290
|
* 被裁的键写入 `removed`(带点号前缀)——静默裁剪会让「字段被吃掉」与「用户没配」不可分辨。
|
|
135
|
-
* `type: 'array'` 的值整段保留(数组元素结构由 validateConfig 解释,不在这里拆)。
|
|
291
|
+
* `type: 'array'` 的值整段保留(数组元素结构由 validateConfig / parseConfig 解释,不在这里拆)。
|
|
136
292
|
*/
|
|
137
293
|
export declare function removeExtraFields(config: Record<string, unknown>, schema: Record<string, unknown>, removed?: string[], prefix?: string): Record<string, unknown>;
|
|
138
294
|
/**
|
|
@@ -156,4 +312,5 @@ declare module '@aalis/core' {
|
|
|
156
312
|
configSchema?: ConfigSchema;
|
|
157
313
|
}
|
|
158
314
|
}
|
|
315
|
+
export {};
|
|
159
316
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|