@tbox.cn/app-toolkit 0.1.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/LICENSE +21 -0
- package/README.md +50 -0
- package/dist/chunk-VV3ERZXS.js +1 -0
- package/dist/contracts-resolver-QM4FBQQV.js +1 -0
- package/dist/index.d.ts +1909 -0
- package/dist/index.js +8 -0
- package/package.json +47 -0
- package/src/assembly/app-manifest.ts +132 -0
- package/src/assembly/provider-catalog.ts +167 -0
- package/src/assembly/walk-manifests.ts +461 -0
- package/src/core/contracts-expected.ts +31 -0
- package/src/core/contracts-resolver.ts +274 -0
- package/src/core/credential-format.ts +98 -0
- package/src/core/credential-mask.ts +19 -0
- package/src/core/env-expansion.ts +51 -0
- package/src/core/errors.ts +46 -0
- package/src/core/file-cache.ts +65 -0
- package/src/core/fskit.ts +21 -0
- package/src/core/module-schema.ts +139 -0
- package/src/dto.ts +298 -0
- package/src/factory.ts +297 -0
- package/src/index.ts +137 -0
- package/src/integrations/credentials.ts +153 -0
- package/src/integrations/mock-bindings.ts +55 -0
- package/src/integrations/predicate-io.ts +199 -0
- package/src/integrations/predicate.ts +598 -0
- package/src/integrations/read.ts +53 -0
- package/src/integrations/write.ts +448 -0
- package/src/views/app.ts +28 -0
- package/src/views/context.ts +70 -0
- package/src/views/modules.ts +48 -0
- package/src/views/providers.ts +165 -0
- package/src/views/service-detail.ts +32 -0
- package/src/views/service-resolutions.ts +323 -0
- package/tests/contracts-resolver.test.ts +203 -0
- package/tests/demo-app.ts +146 -0
- package/tests/dev-manifest-catalog.test.ts +114 -0
- package/tests/error-name-safety.test.ts +26 -0
- package/tests/file-cache.test.ts +242 -0
- package/tests/import-layers.test.ts +111 -0
- package/tests/module-schema.test.ts +84 -0
- package/tests/naming-alignment.test.ts +50 -0
- package/tests/views.test.ts +427 -0
- package/tests/write-core.test.ts +188 -0
- package/tsconfig.json +11 -0
- package/tsup.config.ts +29 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* tbox.module.json schema v1(001 §3.6 字段名,003 §4.1 schema v1 定版)。
|
|
5
|
+
* app-toolkit 单一校验源(自 CLI module-schema.ts 迁入;CLI 经 re-export 消费)。
|
|
6
|
+
*
|
|
7
|
+
* 迁移改造(ai-build C2-5):
|
|
8
|
+
* - resourceNeedContribSchema 的 type 由 `z.enum(RESOURCE_TYPE_IDS)` 放宽为 `z.string()`——
|
|
9
|
+
* 词汇校验移谓词、经 contracts 动态解析取 RESOURCE_TYPE_IDS(比静态 enum 更忠实应用版本);
|
|
10
|
+
* - demand meta additive:serviceNeedContribSchema 增 title?/description?(服务展示元数据,
|
|
11
|
+
* manifest demand 侧 additive 扩展,catalog 聚合顺带携带——api.md ServiceDemand 对齐);
|
|
12
|
+
* - 安全钉子(H9b):provider 名与 instance id 进凭据 stem 派生,字符集 pattern
|
|
13
|
+
* `/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/` 为第一道防线(stem 派生处另有断言防线——纵深防御)。
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/** 输入字符集(安全钉子①):provider 名 / instanceId 恒经此 pattern(进凭据 stem 派生的输入) */
|
|
17
|
+
export const SAFE_NAME_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;
|
|
18
|
+
|
|
19
|
+
const cardContribSchema = z.object({
|
|
20
|
+
cardType: z.string(),
|
|
21
|
+
schemaVersion: z.number().optional(),
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
export const pageContribSchema = z.object({
|
|
25
|
+
route: z.string(),
|
|
26
|
+
component: z.string(),
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
export const tabContribSchema = z.object({
|
|
30
|
+
route: z.string(),
|
|
31
|
+
label: z.string().optional(),
|
|
32
|
+
icon: z.string().optional(),
|
|
33
|
+
order: z.number().optional(),
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
export const moduleDependencySchema = z.object({
|
|
37
|
+
id: z.string(),
|
|
38
|
+
range: z.string().optional(),
|
|
39
|
+
required: z.boolean().default(true),
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
/** provider 供给槽声明(integrations v2:contributes.providers.slots 元素;
|
|
43
|
+
* provider = 厂商名(catalog 嵌套第一轴)、implementation = 'id@version'(第二轴)) */
|
|
44
|
+
export const providerSlotContribSchema = z.object({
|
|
45
|
+
service: z.string(),
|
|
46
|
+
provider: z.string().regex(SAFE_NAME_PATTERN, 'provider 名含非法字符(需 /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/)'),
|
|
47
|
+
implementation: z.string(),
|
|
48
|
+
credentialType: z.string(),
|
|
49
|
+
local: z.boolean().optional(),
|
|
50
|
+
configSchema: z.string().optional(),
|
|
51
|
+
credentialSchema: z.string().optional(),
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
/** 服务需求槽声明(contributes.services 元素;业务模块声明消费——catalog 需求侧聚合源) */
|
|
55
|
+
export const serviceNeedContribSchema = z.object({
|
|
56
|
+
service: z.string(),
|
|
57
|
+
optional: z.boolean().default(true),
|
|
58
|
+
defaults: z
|
|
59
|
+
.array(
|
|
60
|
+
z.object({
|
|
61
|
+
provider: z.string().regex(SAFE_NAME_PATTERN, 'provider 名含非法字符(需 /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/)'),
|
|
62
|
+
implementation: z.string(),
|
|
63
|
+
}),
|
|
64
|
+
)
|
|
65
|
+
.default([]),
|
|
66
|
+
// demand meta additive(api.md ServiceDemand):服务展示元数据,缺席 UI 回退 service id
|
|
67
|
+
title: z.string().optional(),
|
|
68
|
+
description: z.string().optional(),
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
/** 资源需求声明(contributes.resources 元素;type 放宽为 string——词汇校验移谓词经 resolver 取词表) */
|
|
72
|
+
export const resourceNeedContribSchema = z.object({
|
|
73
|
+
id: z.string(),
|
|
74
|
+
type: z.string(),
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
export const moduleDescriptorSchema = z
|
|
78
|
+
.object({
|
|
79
|
+
schemaVersion: z.number().default(1),
|
|
80
|
+
name: z.string(),
|
|
81
|
+
version: z.string().default('0.0.0'),
|
|
82
|
+
kind: z.enum(['platform', 'business', 'third-party']).default('business'),
|
|
83
|
+
risk: z
|
|
84
|
+
.object({
|
|
85
|
+
level: z.enum(['high', 'medium', 'low']).default('low'),
|
|
86
|
+
writeBoundary: z.enum(['sdk-enforced', 'source']).default('source'),
|
|
87
|
+
})
|
|
88
|
+
.default({}),
|
|
89
|
+
distribution: z
|
|
90
|
+
.object({
|
|
91
|
+
defaultMode: z.enum(['hybrid', 'sdk', 'codegen', 'local']).default('codegen'),
|
|
92
|
+
})
|
|
93
|
+
.default({}),
|
|
94
|
+
contributes: z
|
|
95
|
+
.object({
|
|
96
|
+
handlers: z.array(z.string()).default([]),
|
|
97
|
+
tools: z.array(z.string()).default([]),
|
|
98
|
+
cards: z.array(cardContribSchema).default([]),
|
|
99
|
+
routes: z.array(z.string()).default([]),
|
|
100
|
+
pages: z.array(pageContribSchema).default([]),
|
|
101
|
+
tabs: z.array(tabContribSchema).default([]),
|
|
102
|
+
providers: z
|
|
103
|
+
.object({
|
|
104
|
+
slots: z.array(providerSlotContribSchema).default([]),
|
|
105
|
+
})
|
|
106
|
+
.default({}),
|
|
107
|
+
services: z.array(serviceNeedContribSchema).default([]),
|
|
108
|
+
resources: z.array(resourceNeedContribSchema).default([]),
|
|
109
|
+
})
|
|
110
|
+
.default({}),
|
|
111
|
+
dependencies: z
|
|
112
|
+
.object({
|
|
113
|
+
modules: z.array(moduleDependencySchema).default([]),
|
|
114
|
+
})
|
|
115
|
+
.default({}),
|
|
116
|
+
env: z.array(z.string()).default([]),
|
|
117
|
+
})
|
|
118
|
+
.strict();
|
|
119
|
+
|
|
120
|
+
export type ModuleDescriptor = z.infer<typeof moduleDescriptorSchema>;
|
|
121
|
+
export type CardContrib = z.infer<typeof cardContribSchema>;
|
|
122
|
+
export type ProviderSlotContrib = z.infer<typeof providerSlotContribSchema>;
|
|
123
|
+
export type ServiceNeedContrib = z.infer<typeof serviceNeedContribSchema>;
|
|
124
|
+
export type ResourceNeedContrib = z.infer<typeof resourceNeedContribSchema>;
|
|
125
|
+
|
|
126
|
+
export type ParseModuleResult =
|
|
127
|
+
| { ok: true; value: ModuleDescriptor }
|
|
128
|
+
| { ok: false; errors: string[] };
|
|
129
|
+
|
|
130
|
+
export function parseModuleDescriptor(raw: unknown): ParseModuleResult {
|
|
131
|
+
const result = moduleDescriptorSchema.safeParse(raw);
|
|
132
|
+
if (result.success) return { ok: true, value: result.data };
|
|
133
|
+
return {
|
|
134
|
+
ok: false,
|
|
135
|
+
errors: result.error.issues.map(
|
|
136
|
+
(issue) => `${issue.path.join('.') || '(root)'}: ${issue.message}`,
|
|
137
|
+
),
|
|
138
|
+
};
|
|
139
|
+
}
|
package/src/dto.ts
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DTO 全量(api.md §3 字段级单源落源——28 类型;演进 additive-only,铁律 #8)。
|
|
3
|
+
* agtcodingbox / tbox-ai-coding 经 `import type` 消费(L2 DTO 单源——API 层零类型镜像)。
|
|
4
|
+
* 词汇七概念:app / module / service / instance / provider / integration / resolution。
|
|
5
|
+
* 弃用词汇清单见 api.md §3 尾(component/slot/scope/configMode/…——防复活)。
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// ===== 词汇基线 =====
|
|
9
|
+
|
|
10
|
+
/** contracts 求值五态原样(EffectiveServiceResolution.status) */
|
|
11
|
+
export type ServiceStatus =
|
|
12
|
+
| 'ok'
|
|
13
|
+
| 'service-not-configured'
|
|
14
|
+
| 'instance-not-found'
|
|
15
|
+
| 'instance-disabled'
|
|
16
|
+
| 'binding-unresolved';
|
|
17
|
+
|
|
18
|
+
/** 四配置层(instance 为 map 字段层) */
|
|
19
|
+
export type BindingLayer = 'app' | 'module' | 'service' | 'instance';
|
|
20
|
+
|
|
21
|
+
// ===== 需求轴(GET /modules · 静态)=====
|
|
22
|
+
|
|
23
|
+
/** 纯模块清单(无 services——卡片展开走 /modules/:m) */
|
|
24
|
+
export interface ModulesView {
|
|
25
|
+
modules: ModuleDeclaration[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface ModuleDeclaration {
|
|
29
|
+
/** install id(packages/ 目录名 / .tbox/app.json entry.id) */
|
|
30
|
+
id: string;
|
|
31
|
+
/** 包名 */
|
|
32
|
+
name: string;
|
|
33
|
+
title: string;
|
|
34
|
+
description: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** 服务需求声明(模块 demand 单元;defaults 唯一落位 ServiceDetail) */
|
|
38
|
+
export interface ServiceDemand {
|
|
39
|
+
service: string;
|
|
40
|
+
/** manifest demand meta;缺席 UI 回退 service id */
|
|
41
|
+
title?: string;
|
|
42
|
+
description?: string;
|
|
43
|
+
/** demand optional !== false(多模块 OR 聚合见 resolution echo) */
|
|
44
|
+
required: boolean;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// ===== 静态单体视图 =====
|
|
48
|
+
|
|
49
|
+
/** GET /modules/:module(模块静态一站式 · PUT 读对偶) */
|
|
50
|
+
export interface ModuleDetailView {
|
|
51
|
+
/** domains[换算键] 节点原值;未配置 = null */
|
|
52
|
+
integration: ModuleIntegrationNode | null;
|
|
53
|
+
/** 本模块 demand(卡片展开 + 编辑器静态上下文自足) */
|
|
54
|
+
services: ServiceDemand[];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** GET /app(应用静态视图:平台服务 + root 原值) */
|
|
58
|
+
export interface AppView {
|
|
59
|
+
/** 平台服务 id(服务词汇 − 模块占用;owner/标题 UI 按首点段派生) */
|
|
60
|
+
services: string[];
|
|
61
|
+
/** root 节点原值;文件缺席 = null */
|
|
62
|
+
integration: AppIntegrationNode | null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** GET /services/:service(服务静态单体) */
|
|
66
|
+
export interface ServiceDetail extends ServiceDemand {
|
|
67
|
+
/** manifest 预填(唯一落位) */
|
|
68
|
+
defaults: Array<{ provider: string; implementation: string }>;
|
|
69
|
+
/** 文件 services[s] 逐字原值(编辑预填源);无声明 = null */
|
|
70
|
+
integration: ServiceIntegrationNode | null;
|
|
71
|
+
/** 供给该服务的厂商名单(catalog 静态切片——picker 数据源) */
|
|
72
|
+
suppliedBy: string[];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// ===== 求值轴 =====
|
|
76
|
+
|
|
77
|
+
/** GET /service-resolutions(批量求值 · 唯一求值集合面) */
|
|
78
|
+
export interface ServiceResolutionsView {
|
|
79
|
+
/** P6 contracts echo(仅求值轴两端点携带) */
|
|
80
|
+
contracts: ContractsResolution;
|
|
81
|
+
/** 键集 = 服务词汇 ∪ 已配置(模块/平台/孤儿全量) */
|
|
82
|
+
resolutions: Record<string, ServiceResolutionEntry>;
|
|
83
|
+
/** 谓词全量(doctor 同源;恒全量——subset 消费方客户端过滤) */
|
|
84
|
+
issues: IntegrationIssue[];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** 求值摘要单元(行内嵌;P14 单一形状) */
|
|
88
|
+
export interface ServiceResolutionEntry {
|
|
89
|
+
/** 默认实例口径(normalizeInstances 委托) */
|
|
90
|
+
status: ServiceStatus;
|
|
91
|
+
statusMessage?: string;
|
|
92
|
+
/** 最特异声明层厂商名(跨层事实) */
|
|
93
|
+
provider?: string;
|
|
94
|
+
/** provider 在场时在场:(provider, service) ∈ 供给关系 */
|
|
95
|
+
supplied?: boolean;
|
|
96
|
+
/** owner 模块 install id;平台服务/孤儿缺席 */
|
|
97
|
+
module?: string;
|
|
98
|
+
/** demand echo(OR 聚合);平台/孤儿恒 false;集成就绪判定单源(§7) */
|
|
99
|
+
required?: boolean;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** 求值完整结构(extends = 列表项 ⊂ 单体的编译期保证——P14) */
|
|
103
|
+
export interface ServiceResolution extends ServiceResolutionEntry {
|
|
104
|
+
/** P4 枚举规则(全实例逐一;默认实例求值 = 摘要基,不重复头部) */
|
|
105
|
+
instances: ResolvedInstance[];
|
|
106
|
+
inheritance: Array<{ layer: BindingLayer; provider?: string; implementation?: string }>;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** GET /service-resolutions/:service(求值单体) */
|
|
110
|
+
export interface ServiceResolutionDetail {
|
|
111
|
+
contracts: ContractsResolution;
|
|
112
|
+
resolution: ServiceResolution;
|
|
113
|
+
/** service === :service 过滤子集 */
|
|
114
|
+
issues: IntegrationIssue[];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// ===== 集成节点(文件镜像 = PUT body)=====
|
|
118
|
+
|
|
119
|
+
/** root 节点 */
|
|
120
|
+
export interface AppIntegrationNode {
|
|
121
|
+
/** 恒字符串(app/module 级无内联形态) */
|
|
122
|
+
provider?: string;
|
|
123
|
+
config?: Record<string, unknown>;
|
|
124
|
+
configByInstance?: Record<string, Record<string, unknown>>;
|
|
125
|
+
credentialRef?: string;
|
|
126
|
+
credentialRefByInstance?: Record<string, string>;
|
|
127
|
+
/** 整组替换(id 字符集受输入约束①) */
|
|
128
|
+
instances?: Array<{ id: string; name: string; attributes?: Record<string, unknown> }>;
|
|
129
|
+
defaultInstanceId?: string | null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** AppIntegrationNode 键集单源(runtime const——write applyApp 全量替换白名单
|
|
133
|
+
* (缺席根键删除;services/domains/modules 域不在其中)+ views/app 投影(GET 预填 ≡ PUT body,
|
|
134
|
+
* D21/L1——文件含 services/domains 但 root 节点投影只含本键集)) */
|
|
135
|
+
export const APP_INTEGRATION_NODE_KEYS = [
|
|
136
|
+
'provider',
|
|
137
|
+
'config',
|
|
138
|
+
'configByInstance',
|
|
139
|
+
'credentialRef',
|
|
140
|
+
'credentialRefByInstance',
|
|
141
|
+
'instances',
|
|
142
|
+
'defaultInstanceId',
|
|
143
|
+
] as const;
|
|
144
|
+
|
|
145
|
+
/** 模块域节点(恒字符串 provider——域层无凭据位,契约事实) */
|
|
146
|
+
export interface ModuleIntegrationNode {
|
|
147
|
+
provider?: string;
|
|
148
|
+
config?: Record<string, unknown>;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** services[s] 整节点 */
|
|
152
|
+
export interface ServiceIntegrationNode {
|
|
153
|
+
/** 对象 = 自定义 API(仅槽级,P2) */
|
|
154
|
+
provider?: string | InlineVendorDeclaration;
|
|
155
|
+
/** 内联 provider 时必填 */
|
|
156
|
+
implementation?: string;
|
|
157
|
+
config?: Record<string, unknown>;
|
|
158
|
+
credentialRef?: string;
|
|
159
|
+
/** 键 = instanceId / '*'(随节点全量替换) */
|
|
160
|
+
instances?: Record<string, ServiceInstanceNode>;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** services[s].instances[k] 节点 */
|
|
164
|
+
export interface ServiceInstanceNode {
|
|
165
|
+
/** provider 恒字符串(内联仅槽级合法) */
|
|
166
|
+
provider?: string;
|
|
167
|
+
implementation?: string;
|
|
168
|
+
config?: Record<string, unknown>;
|
|
169
|
+
credentialRef?: string;
|
|
170
|
+
/** 缺省 true;false → instance-disabled */
|
|
171
|
+
enabled?: boolean;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export interface InlineVendorDeclaration {
|
|
175
|
+
provider: string;
|
|
176
|
+
credentialType: string;
|
|
177
|
+
configSchema?: string;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// ===== 凭据工件输入(唯一写侧扩展,不在文件节点内)=====
|
|
181
|
+
|
|
182
|
+
export interface CredentialValues {
|
|
183
|
+
type: string;
|
|
184
|
+
values: Record<string, string>;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// ===== 解析产物条目 =====
|
|
188
|
+
|
|
189
|
+
export interface ResolvedInstance {
|
|
190
|
+
/** 注册表 id;'*' = 通配 */
|
|
191
|
+
instanceId: string;
|
|
192
|
+
status: ServiceStatus;
|
|
193
|
+
/** 逐实例诊断(binding-unresolved 等直投) */
|
|
194
|
+
statusMessage?: string;
|
|
195
|
+
/** 该实例合并结果 */
|
|
196
|
+
effective?: EffectiveBinding;
|
|
197
|
+
/** 掩码回显 */
|
|
198
|
+
credential?: CredentialEcho;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// ===== 供给轴(静态)=====
|
|
202
|
+
|
|
203
|
+
/** GET /providers:厂商基本信息 */
|
|
204
|
+
export interface ProvidersView {
|
|
205
|
+
providers: ProviderEntry[];
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export interface ProviderEntry {
|
|
209
|
+
provider: string;
|
|
210
|
+
/** Mock 旗标(provider 级聚合) */
|
|
211
|
+
local: boolean;
|
|
212
|
+
/** 供给声明来源包名 */
|
|
213
|
+
owner: string;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/** GET /providers/:provider:供给足迹 */
|
|
217
|
+
export interface ProviderDetail {
|
|
218
|
+
provider: string;
|
|
219
|
+
local: boolean;
|
|
220
|
+
owner: string;
|
|
221
|
+
/** per (provider, service) 保真,同厂商异构合法;★ implementations 恒数组(H1——
|
|
222
|
+
* 多元素 = 升级窗口,UI 出 impl 选择器,PUT 显式钉版) */
|
|
223
|
+
services: Record<
|
|
224
|
+
string,
|
|
225
|
+
{ implementations: Array<{ implementation: string; credentialType: string }> }
|
|
226
|
+
>;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/** GET /providers/:p/services/:s:表单 schema 唯一暴露面 */
|
|
230
|
+
export interface ProviderServiceDetail {
|
|
231
|
+
provider: string;
|
|
232
|
+
service: string;
|
|
233
|
+
/** ★ 恒数组(通常 1) */
|
|
234
|
+
implementations: Array<{ implementation: string; credentialType: string }>;
|
|
235
|
+
/** 厂商集成该服务的表单 schema(integration 域专属) */
|
|
236
|
+
integrationSchemas: {
|
|
237
|
+
/** raw draft 2020-12 原文零转换;供给在场未声明 = null(mock 合法);解析自默认 impl */
|
|
238
|
+
configSchema: object | null;
|
|
239
|
+
credentialSchema: object | null;
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// ===== 通用 =====
|
|
244
|
+
|
|
245
|
+
export interface EffectiveBinding {
|
|
246
|
+
/** custom 时 provider = 内联声明厂商名 */
|
|
247
|
+
provider: string;
|
|
248
|
+
implementation: string;
|
|
249
|
+
config?: Record<string, unknown>;
|
|
250
|
+
/** 'secret://{stem}' */
|
|
251
|
+
credentialRef?: string;
|
|
252
|
+
layer: BindingLayer;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/** GET 永无真值 */
|
|
256
|
+
export interface CredentialEcho {
|
|
257
|
+
/** credentialType(manifest 对齐) */
|
|
258
|
+
type: string;
|
|
259
|
+
/** 'secret://{stem}' */
|
|
260
|
+
ref: string;
|
|
261
|
+
/** 'config/credentials/{stem}.json' */
|
|
262
|
+
file: string;
|
|
263
|
+
/** 前 2 字符 + '****';≤4 字符全掩码;null = 缺字段 */
|
|
264
|
+
masked: Record<string, string | null>;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export interface ContractsResolution {
|
|
268
|
+
version: string | null;
|
|
269
|
+
evaluation: boolean;
|
|
270
|
+
strictValidation: boolean;
|
|
271
|
+
notes: string[];
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/** 字段级真源 = 谓词结构化输出(H7) */
|
|
275
|
+
export interface IntegrationIssue {
|
|
276
|
+
severity: 'error' | 'warning';
|
|
277
|
+
/** 枚举单源 = 谓词文件头检查族编号映射(additive-only) */
|
|
278
|
+
code: string;
|
|
279
|
+
message: string;
|
|
280
|
+
service?: string;
|
|
281
|
+
module?: string;
|
|
282
|
+
instance?: string;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// ===== 写响应(全族同型)=====
|
|
286
|
+
|
|
287
|
+
export interface SaveResult {
|
|
288
|
+
/** no-diff / dryRun → false */
|
|
289
|
+
written: boolean;
|
|
290
|
+
/** 恒 false 当 dryRun / no-diff / 应用未运行(onApplied 协作点回填) */
|
|
291
|
+
restartScheduled: boolean;
|
|
292
|
+
/** 触碰文件清单(dryRun 恒 []) */
|
|
293
|
+
files: string[];
|
|
294
|
+
/** 凭据工件(0..n;dryRun = 将创建的工件——确定性 stem 派生预览) */
|
|
295
|
+
credentials: Array<{ stem: string; ref: string; overwrote: boolean }>;
|
|
296
|
+
/** 写后谓词复查全量(dryRun 假想态唯一暴露面;含 ORPHANED_CREDENTIAL 等) */
|
|
297
|
+
issues: IntegrationIssue[];
|
|
298
|
+
}
|