@tbox.cn/app-toolkit 0.5.0 → 0.6.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/dist/index.d.ts +65 -12
- package/dist/index.js +8 -8
- package/package.json +1 -1
- package/src/core/module-schema.ts +3 -0
- package/src/dto.ts +35 -3
- package/src/factory.ts +18 -10
- package/src/index.ts +2 -0
- package/src/integrations/write.ts +4 -0
- package/src/views/context.ts +4 -2
- package/src/views/integration-schemas.ts +17 -3
- package/src/views/modules.ts +66 -4
- package/tests/module-resources.test.ts +148 -0
- package/tests/module-schema.test.ts +14 -0
- package/tests/views.test.ts +297 -89
- package/tests/write-core.test.ts +34 -0
package/dist/index.d.ts
CHANGED
|
@@ -163,6 +163,7 @@ declare const moduleDescriptorSchema: z.ZodObject<{
|
|
|
163
163
|
id: z.ZodString;
|
|
164
164
|
name: z.ZodOptional<z.ZodString>;
|
|
165
165
|
description: z.ZodOptional<z.ZodString>;
|
|
166
|
+
hidden: z.ZodOptional<z.ZodBoolean>;
|
|
166
167
|
version: z.ZodDefault<z.ZodString>;
|
|
167
168
|
kind: z.ZodDefault<z.ZodEnum<["platform", "business", "third-party"]>>;
|
|
168
169
|
risk: z.ZodDefault<z.ZodObject<{
|
|
@@ -510,11 +511,13 @@ declare const moduleDescriptorSchema: z.ZodObject<{
|
|
|
510
511
|
env: string[];
|
|
511
512
|
name?: string | undefined;
|
|
512
513
|
description?: string | undefined;
|
|
514
|
+
hidden?: boolean | undefined;
|
|
513
515
|
}, {
|
|
514
516
|
id: string;
|
|
515
517
|
schemaVersion?: number | undefined;
|
|
516
518
|
name?: string | undefined;
|
|
517
519
|
description?: string | undefined;
|
|
520
|
+
hidden?: boolean | undefined;
|
|
518
521
|
version?: string | undefined;
|
|
519
522
|
kind?: "platform" | "business" | "third-party" | undefined;
|
|
520
523
|
risk?: {
|
|
@@ -1761,6 +1764,9 @@ interface ModuleDeclaration {
|
|
|
1761
1764
|
/** 展示名(v7 词汇统一:manifest name ?? id——恒有值) */
|
|
1762
1765
|
name: string;
|
|
1763
1766
|
description: string;
|
|
1767
|
+
/** 隐藏模块(additive——manifest hidden === true 时携带;默认清单已过滤,本字段仅供
|
|
1768
|
+
* ?includeHidden=true 可见时徽标呈现) */
|
|
1769
|
+
hidden?: boolean;
|
|
1764
1770
|
}
|
|
1765
1771
|
/** 服务需求声明(模块 demand 单元 / 平台服务条目——v4.4 D29 双端点同型;defaults 唯一落位 ServiceDetail) */
|
|
1766
1772
|
interface ServiceDemand {
|
|
@@ -1777,11 +1783,17 @@ interface ModuleDetailView {
|
|
|
1777
1783
|
name: string;
|
|
1778
1784
|
/** B1 additive:模块 meta 描述(manifest description;兜底 '') */
|
|
1779
1785
|
description: string;
|
|
1786
|
+
/** 隐藏模块(additive——manifest hidden === true 时携带;详情恒 200 不受清单过滤影响,
|
|
1787
|
+
* 本字段仅供面板徽标呈现) */
|
|
1788
|
+
hidden?: boolean;
|
|
1780
1789
|
/** v6 所有权模型:模块归属服务(declare.owns 展平,排序;零归属 = [])——
|
|
1781
1790
|
* v5 domainKeys 退役(破坏性更名;面板 presence-detection 双读义务见 api.md §3) */
|
|
1782
1791
|
ownedServices: string[];
|
|
1783
|
-
/** modules[install id] 集成位原值(provider/config;resources
|
|
1792
|
+
/** modules[install id] 集成位原值(provider/config;resources 不投影——见 resources 字段);未配置 = null */
|
|
1784
1793
|
integration: ModuleIntegrationNode | null;
|
|
1794
|
+
/** 模块资源只读镜像(N2 读半边——写侧 resources 恒保全;含 ref 台账展开态 resolvedDatasetId);
|
|
1795
|
+
* 无模块键/无资源节 = null */
|
|
1796
|
+
resources?: ModuleResourcesEcho | null;
|
|
1785
1797
|
/** v6 单数化(v5 providerBindings[] 退役):模块级厂商绑定解析(resolveModuleBinding 单源;
|
|
1786
1798
|
* 单值作用于全部 ownedServices) */
|
|
1787
1799
|
binding: ModuleBinding | null;
|
|
@@ -1869,13 +1881,16 @@ interface ServiceDetail extends ServiceDemand {
|
|
|
1869
1881
|
* 绑定无可计算 schema / 含 schema;malformed 节点 → null——不放行域级联) */
|
|
1870
1882
|
integrationSchemas?: ServiceIntegrationSchemas | null;
|
|
1871
1883
|
/** G 批:include=integrationFieldRegistry 服务轴注册表(loadServiceFieldRegistry——
|
|
1872
|
-
* 四分支链推导复用 D38;fields = 该 schema 全部字段带 global 旗标;null 语义镜像 D38
|
|
1884
|
+
* 四分支链推导复用 D38;fields = 该 schema 全部字段带 global 旗标;null 语义镜像 D38。
|
|
1885
|
+
* v5.1 D39:serviceProvider 轴参 = 假想重定向——仅表单投影按 X 计算,带非空轴参时
|
|
1886
|
+
* registry 恒非 null(豁免链③不镜像实际态 null);同构 ≡ PUT 改写 provider 后实读) */
|
|
1873
1887
|
integrationFieldRegistry?: IntegrationFieldRegistryView | null;
|
|
1874
1888
|
}
|
|
1875
1889
|
/** 服务级生效绑定 schema(v4.7 D38 静态轴富化——零 contracts,永不 503;实例层无条件排除:
|
|
1876
1890
|
* node 级口径 ≠ resolution 默认实例口径,api.md §4.4 注) */
|
|
1877
1891
|
interface ServiceIntegrationSchemas {
|
|
1878
|
-
/** 生效厂商:显式(含内联声明名)?? modules[ownerOf].provider ?? root.provider
|
|
1892
|
+
/** 生效厂商:显式(含内联声明名)?? modules[ownerOf].provider ?? root.provider;
|
|
1893
|
+
* v5.1 D39:serviceProvider 轴参在场时 = 假想短路值(非链解析产物) */
|
|
1879
1894
|
provider: string;
|
|
1880
1895
|
/** catalog 复合键(多 impl 声明序首个)> 内联 ref;miss(未知厂商/未供给/内联缺 ref)→ null(富化非门控) */
|
|
1881
1896
|
configSchema: object | null;
|
|
@@ -1952,6 +1967,24 @@ interface ModuleIntegrationNode {
|
|
|
1952
1967
|
/** ModuleIntegrationNode 可写键集单源(v6——write applyModule 全量替换白名单
|
|
1953
1968
|
* (键集外 400;resources 恒随既有节点保全)+ views/modules 投影(GET ≡ PUT,三同构)) */
|
|
1954
1969
|
declare const MODULE_INTEGRATION_NODE_KEYS: readonly ["provider", "config"];
|
|
1970
|
+
/** 模块资源回显(只读投影——N2 读半边:写侧仍仅 provider/config,resources 恒保全)。
|
|
1971
|
+
* 原值文件镜像(L1)+ ref 台账展开态:`ref` 在场且同目录 knowledge.json 命中时
|
|
1972
|
+
* `resolvedDatasetId` = 台账 datasetId(镜像 SDK resolveKnowledge 展开语义),未命中/台账缺失 = null。
|
|
1973
|
+
* 路径锚定边界:视图恒读 `<appDir>/config/`(与 toolkit readIntegrationsConfig 同源——
|
|
1974
|
+
* `TBOX_INTEGRATIONS_FILE` 为 SDK 运行时逃生舱,视图不跟随,既有分叉)。 */
|
|
1975
|
+
interface ModuleResourceEcho {
|
|
1976
|
+
type: 'knowledge';
|
|
1977
|
+
/** 文件原值直填 datasetId(与 ref 互斥使用——并存时 SDK 侧 datasetId 优先) */
|
|
1978
|
+
datasetId?: string;
|
|
1979
|
+
/** 文件原值 ref(台账引用——knowledge.json knowledge_bases 键) */
|
|
1980
|
+
ref?: string;
|
|
1981
|
+
/** 展开态:datasetId 直填时 = 该值;ref 命中台账 = 台账 datasetId;ref 未命中/台账缺失 = null */
|
|
1982
|
+
resolvedDatasetId: string | null;
|
|
1983
|
+
topK?: number;
|
|
1984
|
+
scoreThreshold?: number;
|
|
1985
|
+
}
|
|
1986
|
+
/** modules[install id].resources 只读镜像(键 = 资源 id;无模块键/无资源 = null) */
|
|
1987
|
+
type ModuleResourcesEcho = Record<string, ModuleResourceEcho>;
|
|
1955
1988
|
/** services[s] 整节点 */
|
|
1956
1989
|
interface ServiceIntegrationNode {
|
|
1957
1990
|
/** 对象 = 自定义 API(仅槽级,P2) */
|
|
@@ -2121,10 +2154,15 @@ interface ViewSnapshot {
|
|
|
2121
2154
|
catalog: WalkCatalog;
|
|
2122
2155
|
integrations: Record<string, unknown> | null;
|
|
2123
2156
|
contracts: ResolvedContracts;
|
|
2157
|
+
/** 文件读原语透传(可选——resources 台账惰性读等 stat 指纹缓存消费;缺席 = 调用方直读) */
|
|
2158
|
+
cache?: FileCache;
|
|
2124
2159
|
}
|
|
2125
2160
|
|
|
2126
|
-
/** GET /modules:纯模块清单(demand 不在——卡片展开 = GET /modules/:m;provider
|
|
2127
|
-
|
|
2161
|
+
/** GET /modules:纯模块清单(demand 不在——卡片展开 = GET /modules/:m;provider 家族包不在清单;
|
|
2162
|
+
* hidden 模块默认过滤——includeHidden = true 可见并携带 hidden: true 徽标) */
|
|
2163
|
+
declare function loadModulesView(snapshot: ViewSnapshot, opts?: {
|
|
2164
|
+
includeHidden?: boolean;
|
|
2165
|
+
}): {
|
|
2128
2166
|
modules: ModuleDeclaration[];
|
|
2129
2167
|
};
|
|
2130
2168
|
/** GET /modules/:module:模块静态一站式(modules[install id] 集成位原值 + demand;PUT 读对偶) */
|
|
@@ -2211,13 +2249,21 @@ declare function loadModuleIntegrationSchemas(snapshot: ViewSnapshot, moduleId:
|
|
|
2211
2249
|
* ③ 受控内联(isControlledInlineProvider 单源)→ 名 = p.provider;catalog 复合键 > p.configSchema ref
|
|
2212
2250
|
* (H9 逃逸 400 照抛——readInlineSchema 共享路径)
|
|
2213
2251
|
* ④ 其余(null/数组/原始值/坏对象)→ 整字段 null(≡ 谓词 #5 INLINE_PROVIDER_INVALID 同判——
|
|
2214
|
-
* 不放行域级联,防错误 schema 污染坏节点)
|
|
2215
|
-
|
|
2252
|
+
* 不放行域级联,防错误 schema 污染坏节点)
|
|
2253
|
+
* v5.1 D39:serviceProvider = 服务轴向假想绑定(缺席/空串 ≡ 按实际解析——I3 归一单点在此头部,
|
|
2254
|
+
* registry 侧不重复归一);非空轴参 → 短路 bare 解析(镜像 formProviderOf「输入替换非分支复制」先例:
|
|
2255
|
+
* 任一原分支改写 provider 为 X 后实读都进 bare 分支,同构承诺 by construction)。短路在节点读取之前——
|
|
2256
|
+
* 豁免链三分支(D39 与 D38 四分支的有意分歧:预览与坏文件解耦):malformed(分支④)不污染假想 /
|
|
2257
|
+
* 内联 ref 不读取(假想态无 H9 逃逸 400;catalog 命中的 manifest 声明路径照读,与节点声明的
|
|
2258
|
+
* 用户可控路径不同性)/ 全链未绑定时假想仍非 null(服务轴恒可写,无 module 轴零归属对应物)。 */
|
|
2259
|
+
declare function loadServiceIntegrationSchemas(snapshot: ViewSnapshot, service: string, serviceProvider?: string): ServiceIntegrationSchemas | null;
|
|
2216
2260
|
/** G 批:服务轴字段注册表(D38 四分支链复用——消费 loadServiceIntegrationSchemas 单源;
|
|
2217
2261
|
* 伪层 {provider, services: {[s]: {configSchema}}} → buildIntegrationFieldRegistry——
|
|
2218
2262
|
* fields = 该 schema 全部字段带 global 旗标;configSchema null → schemaless=[service]
|
|
2219
|
-
* 非 null 空集;schemas 整体 null(全链未绑定/坏节点)→ registry null——镜像 D38
|
|
2220
|
-
|
|
2263
|
+
* 非 null 空集;schemas 整体 null(全链未绑定/坏节点)→ registry null——镜像 D38 语义)。
|
|
2264
|
+
* v5.1 D39:serviceProvider = 服务轴向假想绑定,纯透传(I1 单源——归一与短路都在链函数头部;
|
|
2265
|
+
* 轴参仅重定向表单层投影,global 旗标全量透传语义不变)。 */
|
|
2266
|
+
declare function loadServiceFieldRegistry(snapshot: ViewSnapshot, service: string, serviceProvider?: string): IntegrationFieldRegistryView | null;
|
|
2221
2267
|
|
|
2222
2268
|
/**
|
|
2223
2269
|
* 凭据状态轴投影(views/credentials;v4.4 D33 独立端点 GET /credentials):
|
|
@@ -2249,7 +2295,8 @@ declare function loadCredentialTypesView(snapshot: ViewSnapshot, provider?: stri
|
|
|
2249
2295
|
* createAppToolkit(C4 工厂;v4.4——24 方法 = 11 读(含 credentials/credential-types 双端点)
|
|
2250
2296
|
* + 4 写 + 9 迁移面;loadApp/loadModule/loadProvider 增 include 选项;v4.6——loadApp/loadModule
|
|
2251
2297
|
* += 轴向假想绑定选项(appProvider/moduleProvider,D37);表单双投影经 formViews 单点装配;
|
|
2252
|
-
* v4.7——loadService 增 include 选项(服务级生效绑定 schema
|
|
2298
|
+
* v4.7——loadService 增 include 选项(服务级生效绑定 schema 单体);v5.1 D39——loadService
|
|
2299
|
+
* += serviceProvider 轴参(服务轴向假想绑定,三轴收口))。
|
|
2253
2300
|
* AppToolkit = AppToolkitRead & AppToolkitWrite & AppToolkitInternals——
|
|
2254
2301
|
* Read+Write = HTTP 直通面 additive 冻结(L1 端点↔方法 1:1,L3 命名镜像:Integration=节点级 /
|
|
2255
2302
|
* Config=文件级);Internals = CLI/doctor/桥消费(自由演进)。
|
|
@@ -2272,7 +2319,10 @@ interface AppToolkitOptions {
|
|
|
2272
2319
|
* **双键契约(v7 词汇统一)**:资源路径参数双键寻址(id 优先、唯一展示名兜底——resolve-key
|
|
2273
2320
|
* 单点;多命中 404 带候选);query 过滤参数(loadServiceResolutions services?)恒 id-only。 */
|
|
2274
2321
|
interface AppToolkitRead {
|
|
2275
|
-
|
|
2322
|
+
/** GET /modules:hidden 模块默认过滤(includeHidden = true 可见——对齐 ?dryRun 布尔参数先例) */
|
|
2323
|
+
loadModules(o?: {
|
|
2324
|
+
includeHidden?: boolean;
|
|
2325
|
+
}): Promise<ModulesView>;
|
|
2276
2326
|
/** v4.6 D37:moduleProvider = 轴向假想绑定(缺席/空串 ≡ 按实际配置解析;需与表单 include 键同现)。
|
|
2277
2327
|
* moduleId = 双键(id 优先、唯一展示名兜底)。 */
|
|
2278
2328
|
loadModule(moduleId: string, o?: {
|
|
@@ -2284,8 +2334,11 @@ interface AppToolkitRead {
|
|
|
2284
2334
|
include?: string[];
|
|
2285
2335
|
appProvider?: string;
|
|
2286
2336
|
}): Promise<AppView>;
|
|
2337
|
+
/** v5.1 D39:serviceProvider = 服务轴向假想绑定(缺席/空串 ≡ 按实际配置解析;需与表单 include
|
|
2338
|
+
* 键同现)——假想重定向仅表单双投影,integration/suppliedBy/defaults 恒实际态(I2) */
|
|
2287
2339
|
loadService(service: string, o?: {
|
|
2288
2340
|
include?: string[];
|
|
2341
|
+
serviceProvider?: string;
|
|
2289
2342
|
}): Promise<ServiceDetail>;
|
|
2290
2343
|
loadServiceResolutions(services?: string[]): Promise<ServiceResolutionsView>;
|
|
2291
2344
|
loadServiceResolution(service: string): Promise<ServiceResolutionDetail>;
|
|
@@ -2350,4 +2403,4 @@ interface AppToolkitInternals {
|
|
|
2350
2403
|
type AppToolkit = AppToolkitRead & AppToolkitWrite & AppToolkitInternals;
|
|
2351
2404
|
declare function createAppToolkit(appDir: string, options?: AppToolkitOptions): AppToolkit;
|
|
2352
2405
|
|
|
2353
|
-
export { APP_INTEGRATION_NODE_KEYS, type AppIntegrationNode, type AppManifest, type AppManifestFull, type AppToolkit, AppToolkitError, type AppToolkitErrorCode, type AppToolkitInternals, type AppToolkitOptions, type AppToolkitRead, type AppToolkitWrite, type AppView, type AppliedCredential, type BindingLayer, type BridgeProviderCatalog, type CardContrib, type ContractsResolution, type CredentialBindingEcho, type CredentialEcho, type CredentialFile, type CredentialInput, type CredentialTypeEntry, type CredentialTypesView, type CredentialValues, type CredentialsView, type DeclarationIssue, type DeclaredModuleInfo, type EffectiveBinding, type EnvExpansionResult, type EvaluationExports, type FileCache, type InlineVendorDeclaration, type IntegrationFieldRegistryView, type IntegrationIssue, type IntegrationServiceIssue, type IntegrationServicePredicateInput, type LayerIntegrationSchemas, MODULE_INTEGRATION_NODE_KEYS, type MiniappContainerEntry, type MockBindingsResult, type ModuleBinding, type ModuleDeclaration, type ModuleDescriptor, type ModuleDetailView, type ModuleIntegrationNode, type ModuleMode, type ModuleOwnershipWritability, type ModulesView, type NpmModuleEntry, type OrphanIssue, type ParseModuleResult, type PlannedCredential, type PredicateAssembly, type PredicateContracts, type PredicateIoInputs, type ProviderDetail, type ProviderEntry, type ProviderServiceDetail, type ProviderServiceSchemas, type ProviderServiceSchemasResult, type ProviderSlotContrib, type ProvidersView, type PruneResult, type ReadIntegrationsResult, type ResolvedContracts, type ResolvedInstance, type ResolvedModule, type ResourceNeedContrib, SAFE_NAME_PATTERN, type SaveResult, type ServiceConsumeContrib, type ServiceDemand, type ServiceDetail, type ServiceInstanceNode, type ServiceIntegrationNode, type ServiceIntegrationSchemas, type ServiceOwnContrib, type ServiceResolution, type ServiceResolutionDetail, type ServiceResolutionEntry, type ServiceResolutionsView, type ServiceStatus, type SlotMeta, type StemInput, type SupplyLookup, type ViewContext, type ViewSnapshot, type WalkCatalog, type WalkManifestsResult, type WalkModuleInfo, type WalkProviderEntry, type WriteCore, type WriteCoreOptions, type WriteOptions, assertValidModuleId, buildIntegrationFieldRegistry, buildOwnershipMap, buildPredicateAssembly, checkInstanceKeys, collectDeclaredModules, contractsNotResolvedMessage, createAppToolkit, createFileCache, createWriteCore, credentialArtifactExists, deepEqual, deriveStem, echoForRef, ensureDir, ensureMockBindings, evaluateAppIntegrationIssues, evaluateIntegrationServices, expandEnvVars, extractModuleIdFromSource, formProviderOf, invalidateContractsResolver, isControlledInlineProvider, isValidModuleId, loadAppIntegrationSchemas, loadAppView, loadCredentialTypesView, loadCredentialsView, loadModuleDetailView, loadModuleIntegrationSchemas, loadModulesView, loadProviderCatalog, loadProviderCatalogRaw, loadProviderDetailView, loadProviderServiceDetailView, loadProvidersView, loadServiceDetailView, loadServiceFieldRegistry, loadServiceIntegrationSchemas, loadServiceResolutionDetail, loadServiceResolutionsView, manifestPath, maskCredentialValues, moduleDependencySchema, moduleDescriptorSchema, moduleOwnershipWritable, pageContribSchema, parseModuleDescriptor, providerFootprint, providerSlotContribSchema, pruneIntegrationBindings, readAppManifest, readAppManifestFull, readCredentialFile, readIntegrationsConfig, readIntegrationsStrict, reconcileOrphanCredentials, refToEnvKey, removeNpmModule, resolveContractsForApp, resolveContractsForApp as resolveContractsForAppExport, resolveLayerIntegrationSchemas, resolveModuleBinding, resolveModuleKey, resolveServiceKey, resolveServiceSummary, resourceNeedContribSchema, serviceConsumeContribSchema, serviceOwnContribSchema, stemToFilePath, stemToRef, tabContribSchema, updateNpmModule, upsertMiniappContainer, upsertNpmModule, walkManifests, writeAppManifest, writeAtomic, writeCredentialFile };
|
|
2406
|
+
export { APP_INTEGRATION_NODE_KEYS, type AppIntegrationNode, type AppManifest, type AppManifestFull, type AppToolkit, AppToolkitError, type AppToolkitErrorCode, type AppToolkitInternals, type AppToolkitOptions, type AppToolkitRead, type AppToolkitWrite, type AppView, type AppliedCredential, type BindingLayer, type BridgeProviderCatalog, type CardContrib, type ContractsResolution, type CredentialBindingEcho, type CredentialEcho, type CredentialFile, type CredentialInput, type CredentialTypeEntry, type CredentialTypesView, type CredentialValues, type CredentialsView, type DeclarationIssue, type DeclaredModuleInfo, type EffectiveBinding, type EnvExpansionResult, type EvaluationExports, type FileCache, type InlineVendorDeclaration, type IntegrationFieldRegistryView, type IntegrationIssue, type IntegrationServiceIssue, type IntegrationServicePredicateInput, type LayerIntegrationSchemas, MODULE_INTEGRATION_NODE_KEYS, type MiniappContainerEntry, type MockBindingsResult, type ModuleBinding, type ModuleDeclaration, type ModuleDescriptor, type ModuleDetailView, type ModuleIntegrationNode, type ModuleMode, type ModuleOwnershipWritability, type ModuleResourceEcho, type ModuleResourcesEcho, type ModulesView, type NpmModuleEntry, type OrphanIssue, type ParseModuleResult, type PlannedCredential, type PredicateAssembly, type PredicateContracts, type PredicateIoInputs, type ProviderDetail, type ProviderEntry, type ProviderServiceDetail, type ProviderServiceSchemas, type ProviderServiceSchemasResult, type ProviderSlotContrib, type ProvidersView, type PruneResult, type ReadIntegrationsResult, type ResolvedContracts, type ResolvedInstance, type ResolvedModule, type ResourceNeedContrib, SAFE_NAME_PATTERN, type SaveResult, type ServiceConsumeContrib, type ServiceDemand, type ServiceDetail, type ServiceInstanceNode, type ServiceIntegrationNode, type ServiceIntegrationSchemas, type ServiceOwnContrib, type ServiceResolution, type ServiceResolutionDetail, type ServiceResolutionEntry, type ServiceResolutionsView, type ServiceStatus, type SlotMeta, type StemInput, type SupplyLookup, type ViewContext, type ViewSnapshot, type WalkCatalog, type WalkManifestsResult, type WalkModuleInfo, type WalkProviderEntry, type WriteCore, type WriteCoreOptions, type WriteOptions, assertValidModuleId, buildIntegrationFieldRegistry, buildOwnershipMap, buildPredicateAssembly, checkInstanceKeys, collectDeclaredModules, contractsNotResolvedMessage, createAppToolkit, createFileCache, createWriteCore, credentialArtifactExists, deepEqual, deriveStem, echoForRef, ensureDir, ensureMockBindings, evaluateAppIntegrationIssues, evaluateIntegrationServices, expandEnvVars, extractModuleIdFromSource, formProviderOf, invalidateContractsResolver, isControlledInlineProvider, isValidModuleId, loadAppIntegrationSchemas, loadAppView, loadCredentialTypesView, loadCredentialsView, loadModuleDetailView, loadModuleIntegrationSchemas, loadModulesView, loadProviderCatalog, loadProviderCatalogRaw, loadProviderDetailView, loadProviderServiceDetailView, loadProvidersView, loadServiceDetailView, loadServiceFieldRegistry, loadServiceIntegrationSchemas, loadServiceResolutionDetail, loadServiceResolutionsView, manifestPath, maskCredentialValues, moduleDependencySchema, moduleDescriptorSchema, moduleOwnershipWritable, pageContribSchema, parseModuleDescriptor, providerFootprint, providerSlotContribSchema, pruneIntegrationBindings, readAppManifest, readAppManifestFull, readCredentialFile, readIntegrationsConfig, readIntegrationsStrict, reconcileOrphanCredentials, refToEnvKey, removeNpmModule, resolveContractsForApp, resolveContractsForApp as resolveContractsForAppExport, resolveLayerIntegrationSchemas, resolveModuleBinding, resolveModuleKey, resolveServiceKey, resolveServiceSummary, resourceNeedContribSchema, serviceConsumeContribSchema, serviceOwnContribSchema, stemToFilePath, stemToRef, tabContribSchema, updateNpmModule, upsertMiniappContainer, upsertNpmModule, walkManifests, writeAppManifest, writeAtomic, writeCredentialFile };
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import{a as je,b as T,c as Te}from"./chunk-WUULQDOV.js";import{z as I}from"zod";var
|
|
2
|
-
`,"utf8"),
|
|
3
|
-
`,"utf8")}function De(e){let n=En(e);if(n===null)return null;let r=ve(e);try{let t=JSON.parse(Cn(r,"utf8"));return{...n,miniappContainers:Array.isArray(t?.miniappContainers)?t.miniappContainers:[]}}catch{return{...n,miniappContainers:[]}}}function ht(e,n){let r=e.npmModules.filter(t=>t.id!==n.id);return{...e,npmModules:[...r,n]}}function Rt(e,n){return{...e,npmModules:e.npmModules.filter(r=>r.id!==n)}}function It(e,n){let r=(e.miniappContainers??[]).filter(t=>t.id!==n.id);return{...e,miniappContainers:[...r,n]}}function kt(e,n,r){return{...e,npmModules:e.npmModules.map(t=>t.id===n?{...t,...r}:t)}}function On(e){return/^[a-z0-9]+(-[a-z0-9]+)*$/.test(e)&&!e.includes("..")}function bt(e,n){if(!On(e))throw new Error(`非法模块 id "${e}"(来自 ${n}):仅允许小写字母/数字/中划线`)}function xn(e){try{let n=JSON.parse(e);if(!Array.isArray(n.slots))return null;let r=n.slots.filter(o=>typeof o=="string"),t={};if(n.meta&&typeof n.meta=="object"&&!Array.isArray(n.meta))for(let[o,s]of Object.entries(n.meta)){if(!s||typeof s!="object"||Array.isArray(s))continue;let{name:i,description:d}=s,p={};typeof i=="string"&&i.length>0&&(p.name=i),typeof d=="string"&&d.length>0&&(p.description=d),(p.name!==void 0||p.description!==void 0)&&(t[o]=p)}return{slots:r,meta:t}}catch{return null}}function ye(e,n){let r=t=>{try{let o=JSON.parse(t),s=ie(o);if(s.ok)return{kind:"strict",id:s.value.id,version:s.value.version,descriptor:s.value,declare:s.value.declare};if(s.legacy)return{kind:"legacy",detail:s.errors.join("; ")};if(o&&typeof o=="object"&&"declare"in o){let i=o;return{kind:"loose",...typeof i.id=="string"?{id:i.id}:{},declare:{providers:i.declare?.providers,consumes:i.declare?.consumes}}}return null}catch{return null}};if(n)return n.read(e,r)??null;if(!F(e))return null;try{return r(X(e,"utf8"))}catch{return null}}function Ct(e){let n=P(e,".tbox","app.json");if(!F(n))return[];try{let r=JSON.parse(X(n,"utf8"));return Array.isArray(r.npmModules)?r.npmModules.filter(t=>!!t&&typeof t=="object"&&typeof t.id=="string"&&typeof t.package=="string"):[]}catch{return[]}}function At(e){let n=P(e,".tbox-dev.local"),r=P(n,"dev-manifest.json");if(!F(r))return[];try{let t=JSON.parse(X(r,"utf8")),o=[];for(let[s,i]of Object.entries(t.redirects??{}))typeof i!="string"||!s.startsWith("@tbox.cn/app-")||o.push({pkg:s,dir:P(n,i)});return o}catch{return[]}}function Et(e,n){let r=[],t=[e];for(let i of["apps","packages"]){let d=P(e,i);if(F(d))try{for(let p of Fe(d,{withFileTypes:!0}))p.isDirectory()&&t.push(P(d,p.name))}catch{}}let o=new Set,s=(i,d)=>{let p=n?n.read(d,xn):xn(X(d,"utf8"));p!=null&&r.push({dir:i,slots:p.slots,meta:p.meta})};for(let i of t){let d=P(i,"node_modules","@tbox.cn");if(!F(d))continue;let p=[];try{p=Fe(d)}catch{continue}for(let l of p){let m=P(d,l);if(o.has(m))continue;o.add(m);let k=P(m,"service-slots.json"),R=P(m,"src","service-slots.json");F(k)?s(m,k):F(R)&&s(m,R)}}for(let i of t)for(let d of[P(i,"service-slots.json"),P(i,"src","service-slots.json")])F(d)&&s(i,d);return r}function V(e,n){let r=[],t={providers:{},services:{},credentialTypes:{}},o={},s=[],i={},d=new Set,p=(a,g,h,y)=>{for(let u of a){let v=t.providers[u.provider]??={},b=v[u.implementation];b?b.services.includes(u.service)||b.services.push(u.service):(v[u.implementation]={provider:u.provider,implementation:u.implementation,credentialType:u.credentialType,owner:g,...y?.name?{name:y.name}:{},...y?.description?{description:y.description}:{},...u.local?{local:!0}:{},...u.configSchema?{configSchema:u.configSchema}:{},...u.credentialSchema?{credentialSchema:u.credentialSchema}:{},services:[u.service]},t.credentialTypes[u.credentialType]??={owner:g,packageDir:h,...u.credentialSchema?{credentialSchema:u.credentialSchema}:{}});let c=`${u.provider}\0${u.service}`;o[c]||(o[c]={...u.configSchema?{configSchema:u.configSchema}:{},...u.credentialSchema?{credentialSchema:u.credentialSchema}:{},packageDir:h})}},l=a=>a.kind==="strict"?{name:a.descriptor.name,description:a.descriptor.description}:void 0,m=(a,g)=>{for(let h of a){let y=i[h];y===void 0?i[h]=g:y!==g&&s.push({severity:"error",code:"OWNERSHIP_CONFLICT",module:g,message:`服务 ${h} 归属冲突:${y} 与 ${g} 均声明 owns(先声明 ${y} 胜出)——修正 manifest declare.owns 互斥`})}},k=(a,g)=>{a.kind==="legacy"&&s.push({severity:"error",code:"OLD_MANIFEST_KEY",module:g,message:`${g}:${a.detail}`})},R=a=>a.kind==="strict"||a.kind==="loose"?a.declare:null,w=(a,g)=>{let h=a.optional!==!1,y=a.defaults??[],u=t.services[a.service];if(u){u.optional=u.optional&&h;let v=new Set(u.defaults.map(b=>`${b.provider}\0${b.implementation}`));for(let b of y){let c=`${b.provider}\0${b.implementation}`;v.has(c)||(u.defaults.push(b),v.add(c))}u.owners.includes(g)||u.owners.push(g);return}t.services[a.service]={optional:h,defaults:[...y],...a.name?{name:a.name}:{},...a.description?{description:a.description}:{},owners:[g]}};for(let a of Ct(e)){if(d.has(a.id))continue;let g=P(e,"packages",a.id),h=P(e,"node_modules",...a.package.split("/")),y=ye(P(g,"tbox.module.json"),n)??ye(P(h,"tbox.module.json"),n);if(y?.kind==="legacy"){k(y,a.id),d.add(a.id);continue}if(!y)continue;d.add(a.id);let u=F(P(g,"tbox.module.json"))?g:h,v=R(y);y.kind==="strict"&&r.push({id:a.id,dir:u,pkg:a.mode==="sdk"?a.package:`@app/${a.id}`,descriptor:y.descriptor});let b=v?.providers?.slots??[];b.length&&p(b,a.package,u,l(y));let c=v?.consumes??[];for(let E of c)w(E,a.package);let S=y.kind==="strict"?y.descriptor.declare.owns:[];S.length&&m(S.map(E=>E.service),a.id)}for(let{pkg:a,dir:g}of At(e)){let h=ye(P(g,"tbox.module.json"),n);if(h?.kind==="legacy"){k(h,a);continue}if(!h?.id||d.has(h.id))continue;d.add(h.id);let y=R(h),u=y?.providers?.slots??[];u.length&&p(u,a,g,l(h));let v=y?.consumes??[];for(let c of v)w(c,a);let b=h.kind==="strict"?h.descriptor.declare.owns:[];b.length&&m(b.map(c=>c.service),h.id)}let A=P(e,"packages");if(F(A)){let a=[];try{a=Fe(A,{withFileTypes:!0}).filter(g=>g.isDirectory()).map(g=>g.name)}catch{}for(let g of a){if(d.has(g))continue;let h=P(A,g),y=ye(P(h,"tbox.module.json"),n);if(y?.kind==="legacy"){k(y,g),d.add(g);continue}if(!y)continue;let u=y.id??g;if(d.has(u))continue;d.add(u);let v=R(y);y.kind==="strict"&&r.push({id:u,dir:h,pkg:`@app/${u}`,descriptor:y.descriptor});let b=v?.providers?.slots??[];b.length&&p(b,`@app/${u}`,h,l(y));let c=v?.consumes??[];for(let E of c)w(E,`@app/${u}`);let S=y.kind==="strict"?y.descriptor.declare.owns:[];S.length&&m(S.map(E=>E.service),u)}}let O=new Set,f={};for(let a of Et(e,n)){for(let g of a.slots)O.add(g);for(let[g,h]of Object.entries(a.meta))f[g]===void 0&&(f[g]=h)}return{modules:r,catalog:t,serviceSchemas:o,vocabulary:[...O].sort(),slotMeta:f,ownership:i,declarationIssues:s}}function Mn(e,n,r){let t=P(e,"src",n,"index.ts");if(!F(t))return!1;try{let o=X(t,"utf8");return new RegExp(`export\\s+const\\s+${r}\\b`).test(o)}catch{return!1}}function Ot(e){let n=P(e,"src","server","index.ts");if(!F(n))return"";try{return X(n,"utf8")}catch{return""}}function jn(e){return e.match(/declaration\s*:\s*\{[\s\S]*?moduleId\s*:\s*['"]([^'"]+)['"]/)?.[1]}function xt(e){let n=[],r=V(e),t=De(e),o=new Map;for(let s of t?.npmModules??[])o.set(s.id,s.mode);for(let s of r.modules){let i=o.get(s.id)??"local",d=Mn(s.dir,"server","serverModule"),p=s.descriptor.declare;n.push({id:s.id,pkg:i==="sdk"?s.pkg:`@app/${s.id}`,mode:i,hasServerEntry:d,hasClientEntry:Mn(s.dir,"client","clientModule"),hasCards:(p.cards?.length??0)>0,...d?{moduleId:jn(Ot(s.dir))}:{}})}return n.sort((s,i)=>s.id.localeCompare(i.id))}function Mt(e){return V(e).ownership}function L(e,n){let r=e?.modules?.[n]?.provider;if(typeof r=="string"&&r.length>0)return{provider:r,layer:"module"};let t=e?.provider;return typeof t=="string"&&t.length>0?{provider:t,layer:"app"}:{provider:null,layer:null}}function K(e,n){let r=(n.descriptor.declare.owns??[]).map(t=>t.service).sort();return r.length===0?{writable:!1,reason:"zero-ownership",ownedServices:[]}:{writable:!0,ownedServices:r}}function _e(e,n){return[...new Set(Object.values(e.providers[n]??{}).flatMap(r=>r.services))].sort()}function J(e){if(!e||typeof e!="object")return!1;let n=Object.keys(e),r=new Set(["provider","credentialType","configSchema"]);if(!n.every(o=>r.has(o)))return!1;let t=e;return typeof t.provider=="string"&&t.provider.length>0&&typeof t.credentialType=="string"&&t.credentialType.length>0&&(t.configSchema===void 0||typeof t.configSchema=="string")}function Tn(e,n,r){return e==="*"||r.has(e)?null:{severity:"error",code:"INSTANCE_KEY_NOT_REGISTERED",instance:e,message:`integrations: ${n} 键 ${e} 不在 malls 白名单内(${[...r].join(", ")})`}}function $e(e,n){let r=new Set(n),t=[],o=(s,i)=>{let d=Tn(s,i,r);d&&t.push(d)};for(let s of Object.keys(e.configByInstance??{}))o(s,"configByInstance");for(let s of Object.keys(e.credentialRefByInstance??{}))o(s,"credentialRefByInstance");for(let[s,i]of Object.entries(e.services??{}))for(let d of Object.keys(i.instances??{}))o(d,`services.${s}.instances`);return t}function ee(e){let n=[],r=e.contracts,{integrations:t,suppliedProviders:o,demandedServices:s,supplies:i,malls:d,credentialSchemaMissing:p,vendorConfigKeys:l,vendorGlobalConfigKeys:m,vendorConfigSchemaMissing:k,credentialFileMissing:R,credentialFileType:w,realmSwitchHints:A,moduleResourceNeeds:O,ownership:f,installedModuleIds:a}=e,g=d?new Set(d):void 0;for(let c of A??[])n.push({severity:"warning",code:"REALM_SWITCH_HINT",message:c});let h=new Set(Object.keys(o).map(c=>c.slice(0,c.indexOf("\0"))).filter(c=>c.length>0)),y=(c,S,E,C)=>{if(typeof E?.provider=="string"&&typeof E.implementation=="string"&&E.provider&&E.implementation)return o[se(E.provider,E.implementation)]?.credentialType;if(typeof S.provider=="string"&&typeof S.implementation=="string")return o[se(S.provider,S.implementation)]?.credentialType;let M=S.provider?.credentialType;if(typeof M=="string")return M;if(!i)return;let N=C??Object.keys(S.instances??{})[0]??"",j=r.resolveEffectiveService(t,c,N,i,f);if(!(j.status!=="ok"||typeof j.effective.provider!="string"))return o[se(j.effective.provider,j.effective.implementation)]?.credentialType};if(R||w)for(let[c,S]of Object.entries(t.services))for(let[E,C]of Object.entries(S.instances??{})){if(C.enabled===!1)continue;let M=C.credentialRef??S.credentialRef??t.credentialRefByInstance?.[E]??t.credentialRef;if(typeof M!="string"||!M.startsWith("secret://"))continue;let N=M.slice(9);R?.[N]===!0&&n.push({severity:"error",code:"CREDENTIAL_FILE_MISSING",service:c,instance:E,message:`integrations: 凭据文件缺失 ${N}(${c}@${E} effective ref=${M};档内 config/credentials/ 无此文件)`});let j=w?.[N];if(j){let D=y(c,S,C,E);D&&j!==D&&n.push({severity:"error",code:"CREDENTIAL_TYPE_MISMATCH",service:c,instance:E,message:`integrations: 凭据文件 ${N}.json type=${j} 与绑定 credentialType ${D} 不一致(${c}@${E}——transport 创建期将按 type 选策略)`})}}let u=(c,S)=>{if(!g)return;let E=Tn(c,S,g);E&&n.push(E)};for(let[c]of Object.entries(t.configByInstance??{}))u(c,"configByInstance");for(let[c]of Object.entries(t.credentialRefByInstance??{}))u(c,"credentialRefByInstance");let v=Object.entries(t.services).filter(([,c])=>c.instances==null||c.instances["*"]!=null).map(([c])=>c);if(v.length>0){let c=Object.entries(t.services).filter(([,S])=>S.instances!=null&&S.instances["*"]==null).map(([S])=>S);c.length>0&&n.push({severity:"warning",code:"WILDCARD_ALIGNMENT",message:`integrations: 激活形态不对称(通配:${v.join(", ")};显式键集:${c.join(", ")})——动态 mallId 将在显式键集槽上 INSTANCE_NOT_FOUND(provider 业务限制表达位),确认是否齐步`})}let b=r.normalizeInstances({instances:t.instances,defaultInstanceId:t.defaultInstanceId});b.instances.length>=2&&b.defaultInstanceId===null&&n.push({severity:"warning",code:"MULTI_INSTANCE_NO_DEFAULT",message:`integrations: ${b.instances.length} 个部署实例(${b.instances.map(c=>c.id).join(", ")})均无 defaultInstanceId——无 scope 参数访问将落全局会话(默认商圈不注入)`});for(let[c,S]of Object.entries(t.services)){if(s[c]||n.push({severity:"warning",code:"SLOT_NOT_DECLARED",service:c,message:`integrations: 服务槽 ${c} 无消费方声明(拼写错误或需求方未安装)——若为拆分前旧槽位词汇(member.main/parking.main/promotion.read/shopping-guide.main),参照 cookbook·app-config 槽位迁移配方展开为新槽`}),typeof S.provider=="string"?typeof S.implementation=="string"&&!o[se(S.provider,S.implementation)]&&n.push({severity:"error",code:"INSTANCE_SUPPLY_UNMATCHED",service:c,message:`integrations: provider ${S.provider}/${S.implementation} 未命中已装供给(${c} 槽级)——装对应 provider 包或改绑`}):S.provider!==void 0&&!J(S.provider)&&n.push({severity:"error",code:"INLINE_PROVIDER_INVALID",service:c,message:`integrations: 内联 provider 超受控形状(${c} 槽级;允许键 provider/credentialType/configSchema)`}),p){let C=y(c,S);C&&p[C]===!0&&n.push({severity:"error",code:"SCHEMA_FILE_MISSING",service:c,message:`integrations: credentialType ${C} 的 schema 引用不存在(${c};manifest 声明指向缺失文件)`})}typeof S.provider=="object"&&typeof S.implementation!="string"&&n.push({severity:"error",code:"IMPL_WITHOUT_PROVIDER",service:c,message:`integrations: 内联厂商声明必须同时提供 implementation(${c} 槽级)`});for(let[C,M]of Object.entries(S.instances??{})){u(C,`services.${c}.instances`);let N=M.provider!==void 0,j=M.implementation!==void 0;if(j&&!N&&n.push({severity:"error",code:"IMPL_WITHOUT_PROVIDER",service:c,instance:C,message:`integrations: 实例级 implementation 需伴随 provider(${c}@${C}——impl-only 禁止,provider 是绑定组头)`}),N&&j){let D=M.provider,W=M.implementation;typeof D=="string"&&typeof W=="string"?o[se(D,W)]||n.push({severity:"error",code:"INSTANCE_SUPPLY_UNMATCHED",service:c,instance:C,message:`integrations: 实例级 provider 覆盖 ${D}/${W} 未命中已装供给(${c}@${C})`}):J(D)||n.push({severity:"error",code:"INLINE_PROVIDER_INVALID",service:c,instance:C,message:`integrations: 实例级内联 provider 超受控形状(${c}@${C})`})}}}for(let[c,S]of[["root",t.provider],...Object.entries(t.modules??{}).map(([E,C])=>[`modules.${E}`,C?.provider])])typeof S!="string"||S.length===0||h.has(S)||n.push({severity:"error",code:"VENDOR_NOT_INSTALLED",module:c.startsWith("modules.")?c.slice(8):void 0,message:`integrations: ${c} provider ${S} 未命中已装供给——装对应 provider 包或 provider use 改绑`});if(i)for(let[c,S]of Object.entries(t.services)){let E=S.instances?Object.keys(S.instances):[""];for(let C of E){let M=r.resolveEffectiveService(t,c,C,i,f);M.status==="binding-unresolved"&&n.push({severity:"error",code:"BINDING_UNRESOLVED",service:c,instance:C||void 0,message:`integrations: ${M.message}`})}}for(let[c,S]of Object.entries(t.services))S.implementation!==void 0&&S.provider===void 0&&n.push({severity:"error",code:"IMPL_WITHOUT_PROVIDER",service:c,message:`integrations: 槽级 implementation 需伴随 provider(${c}——impl-only 禁止,provider 是绑定组头)`});for(let[c,S]of Object.entries(t.modules??{})){if(!(S?.provider!==void 0||S?.config!==void 0))continue;let C=a?!a.has(c):!1,M=0;if(f)for(let j of Object.values(f))j===c&&(M+=1);if(C||!(f===void 0)&&M===0){let j=C?"未安装(键 = install id)":"未声明任何 owns(无模块级配置位)";n.push({severity:"error",code:"MODULE_CONFIG_DEAD",module:c,message:`integrations: modules.${c} 携带 provider/config 但模块${j}(MODULE_CONFIG_DEAD——模块级集成位作用于 declare.owns 服务,改 declare.owns 或删除该节点)`})}}if(l){let c=new Set,S=!1,E=C=>{typeof C!="string"||C.length===0||(l[C]&&c.add(C),!l[C]&&!k?.[C]&&(S=!0),k?.[C]&&(S=!0))};E(t.provider);for(let C of Object.values(t.modules??{}))E(C?.provider);for(let C of Object.values(t.services)){let M=C.provider;E(typeof C.provider=="string"?C.provider:M?.provider)}if(c.size>0&&!S){let C=new Set;for(let j of c)for(let D of l[j]??[])C.add(D);let M=new Set;for(let j of c)for(let D of m?.[j]??[])M.add(D);let N=(j,D,W,Z)=>{for(let[q]of Object.entries(j??{}))(W??C).has(q)?Z&&Z.size>0&&!Z.has(q)&&n.push({severity:"warning",code:"GLOBAL_FIELD_UNDECLARED",message:`integrations: ${D} 键 ${q} 过 schema 校验但未声明 x-tbox-global(不进应用/模块全局表单;已配置值照常生效——如需全局编辑请在 provider schema 标记)`}):n.push({severity:"error",code:"DOMAIN_CONFIG_INVALID",message:`integrations: ${D} 键 ${q} 不在引用厂商(${[...c].join("/")})任何槽 schema properties 内(死配置)`})};N(t.config,"root.config",void 0,M);for(let[j,D]of Object.entries(t.configByInstance??{}))N(D,`root.configByInstance[${j}]`,void 0,M);for(let[j,D]of Object.entries(t.modules??{})){if(!D?.config)continue;let W=L(t,j).provider??void 0;if(W===void 0){N(D.config,`modules.${j}.config`,void 0,M);continue}let Z=l[W];if(!Z||k?.[W])continue;let q=m?.[W];N(D.config,`modules.${j}.config`,new Set(Z),q)}}}for(let[c,S]of Object.entries(s)){let E=t.services[c];if(!E){n.push({severity:"warning",code:"SLOT_NOT_CONFIGURED",service:c,message:`integrations: 服务槽 ${c}(需求方 ${S.owners.join(", ")})未配置${S.optional?"(可选槽)":"(必需槽——模块将走降级链)"}`});continue}let C=Object.entries(E.instances??{}).filter(([,M])=>M.enabled===!1).map(([M])=>M);C.length>0&&n.push({severity:"warning",code:"INSTANCE_DISABLED",service:c,instance:C.join(", "),message:`integrations: ${c} 实例禁用(${C.join(", ")})`})}for(let[c,S]of Object.entries(t.modules??{})){let E=O?.[c];O&&!(c in O)&&n.push({severity:"warning",code:"RESOURCE_NOT_DECLARED",module:c,message:`integrations: modules.${c} 未命中已装模块(键 = install id——检查 .tbox/app.json entry.id / packages/ 目录名)`});for(let[C,M]of Object.entries(S?.resources??{})){let N=M?.type;(typeof N!="string"||!r.RESOURCE_TYPE_IDS.includes(N))&&n.push({severity:"error",code:"RESOURCE_TYPE_UNKNOWN",module:c,message:`integrations: modules.${c}.resources.${C} type 非法(${String(N)};词汇表 = ${r.RESOURCE_TYPE_IDS.join("/")})`}),E&&E.size>0&&!E.has(C)&&n.push({severity:"warning",code:"RESOURCE_NOT_DECLARED",module:c,message:`integrations: modules.${c}.resources.${C} 未被模块 manifest declare.resources 声明`})}}return n}function se(e,n){return`${e}\0${n}`}import{existsSync as Le,readFileSync as jt,readdirSync as Tt}from"fs";import{join as Se}from"path";function Pn(e){return e.replaceAll("-","_").toUpperCase()}function Nn(e){if(!Le(e))return null;try{let n=JSON.parse(jt(e,"utf8"));return n&&typeof n=="object"?n:null}catch{return null}}function Nt(e){let n=new Set,r=e.properties;if(r&&typeof r=="object"&&!Array.isArray(r))for(let t of Object.keys(r))n.add(t);return n}function ae(e,n,r,t=process.env){let o={};for(let[u,v]of Object.entries(n.catalog.providers))for(let[b,c]of Object.entries(v))o[`${u}\0${b}`]={services:[...c.services],owner:c.owner,credentialType:c.credentialType};let s={};for(let[u,v]of Object.entries(n.catalog.services))s[u]={optional:v.optional,owners:[...v.owners]};let i={},d={},p={},l={},m={};for(let u of n.modules){m[u.id]=new Set((u.descriptor.declare.resources??[]).map(v=>v.id));for(let v of u.descriptor.declare.providers?.slots??[]){if(v.configSchema){let b=Nn(Se(u.dir,v.configSchema));if(b){let c=i[v.provider]??=new Set,S=d[v.provider]??=new Set;for(let C of Nt(b))c.add(C);let E=b.properties;if(E&&typeof E=="object"&&!Array.isArray(E))for(let[C,M]of Object.entries(E))M&&typeof M=="object"&&M["x-tbox-global"]===!0&&S.add(C)}else p[v.provider]=!0}v.credentialSchema&&!Le(Se(u.dir,v.credentialSchema))&&(l[v.credentialType]=!0)}}let k={},R=new Set,w=Se(e,"config","credentials");if(Le(w))for(let u of Tt(w)){if(!u.endsWith(".json"))continue;let v=u.slice(0,-5);R.add(v);let b=Nn(Se(w,u));b&&typeof b.type=="string"&&(k[v]=b.type)}let A=r,O=[],f=u=>{typeof u=="string"&&u.startsWith("secret://")&&O.push(u)};for(let u of Object.values(A.services??{}))if(u&&typeof u=="object"){f(u.credentialRef);for(let v of Object.values(u.instances??{}))v&&typeof v=="object"&&f(v.credentialRef)}for(let u of Object.values(A.credentialRefByInstance??{}))f(u);f(A.credentialRef);let a={};for(let u of O){let v=u.slice(9);t[Pn(v)]===void 0&&(R.has(v)||(a[v]=!0))}let g=[];for(let[u,v]of Object.entries(A.services??{})){let b=v&&typeof v=="object"&&typeof v.provider=="string"?v.provider:void 0;for(let[c,S]of Object.entries((v&&typeof v=="object"?v.instances:void 0)??{})){let E=S&&typeof S=="object"&&typeof S.provider=="string"?S.provider:void 0;b&&E&&E!==b&&g.push(`integrations: ${u}@${c} 实现覆盖跨厂商(${b} → ${E})——凭据域切换,确认该 mall 对应凭据在场`)}}let y=((Array.isArray(A.instances)?A.instances:void 0)??[]).map(u=>u&&typeof u=="object"&&typeof u.id=="string"?u.id:void 0).filter(u=>typeof u=="string");return{suppliedProviders:o,demandedServices:s,credentialFileMissing:a,credentialFileType:k,credentialSchemaMissing:l,vendorConfigKeys:i,vendorGlobalConfigKeys:d,vendorConfigSchemaMissing:p,realmSwitchHints:g,moduleResourceNeeds:m,...y.length>0?{malls:y}:{},ownership:n.ownership,installedModuleIds:new Set([...n.modules.map(u=>u.id),...new Set(Object.values(n.ownership))])}}import{existsSync as Ur,readFileSync as zr}from"fs";import{join as Jr,resolve as Gr}from"path";function We(e){return V(e).catalog}function we(e){let n=V(e).catalog,r={};for(let[s,i]of Object.entries(n.providers)){r[s]={};for(let[d,p]of Object.entries(i))r[s][d]={provider:p.provider,implementation:p.implementation,credentialType:p.credentialType,owner:p.owner,...p.local?{local:!0}:{},...p.configSchema?{configSchema:p.configSchema}:{},...p.credentialSchema?{credentialSchema:p.credentialSchema}:{},services:[...p.services]}}let t={};for(let[s,i]of Object.entries(n.services))t[s]={optional:i.optional,defaults:i.defaults.map(d=>({...d})),owners:[...i.owners]};let o={};for(let[s,i]of Object.entries(n.credentialTypes))o[s]={owner:i.owner,...i.credentialSchema?{credentialSchema:i.credentialSchema}:{}};return{providers:r,services:t,credentialTypes:o}}async function Be(e,n,r,t=process.env){let o=r.module,s=V(e),i=o.buildSupplyLookup(we(e)),d=ae(e,s,n,t);return ee({contracts:o,integrations:n,supplies:i,...d})}import{existsSync as Lt,rmSync as Wt}from"fs";import{join as Bt}from"path";import{existsSync as Pt,readFileSync as Vt}from"fs";import{join as Vn}from"path";var Dt=Vn("config","integrations.json");function B(e,n){let r=Vn(e,Dt),t=o=>JSON.parse(o);if(n)return n.read(r,t)??null;if(!Pt(r))return null;try{return t(Vt(r,"utf8"))}catch{return null}}async function Dn(e,n){let r=await T(e),t=B(e,n);if(t===null)return{config:null,strict:!1,contracts:r};if(r.strictValidation&&r.module.parseIntegrationsConfig)try{return{config:r.module.parseIntegrationsConfig(t),strict:!0,contracts:r}}catch(o){if(o instanceof Error&&Array.isArray(o.issues)){let s=o.issues.filter(i=>Array.isArray(i.path)).map(i=>i.path.map(String).join(".")).filter(i=>i.length>0);throw new x("VALIDATION_FAILED",400,"integrations.json 校验失败",s.length>0?s:void 0)}throw new x("VALIDATION_FAILED",400,o instanceof Error?o.message:String(o))}return{config:t,strict:!1,contracts:r}}function ce(e,n,r){return e.includes(r)||n.includes(r)}import{readdirSync as Ft,existsSync as he,readFileSync as _t}from"fs";import{join as Re}from"path";function Fn(e,n,r){let t=[];if(n){let o=Q({provider:e});t.push({stem:o,ref:`secret://${o}`,input:n})}for(let[o,s]of Object.entries(r??{})){let i=Q({provider:e,instanceId:o});t.push({instanceId:o,stem:i,ref:`secret://${i}`,input:s})}return t}function _n(e,n,r,t,o){let s=[];if(t){let i=Q({provider:e,service:n});s.push({stem:i,ref:`secret://${i}`,input:t})}for(let[i,d]of Object.entries(o??{})){let p=Q({provider:e,instanceId:i,domain:r});s.push({instanceId:i,stem:p,ref:`secret://${p}`,input:d})}return s}function ze(e,n,r){return n.map(t=>({stem:t.stem,ref:t.ref,overwrote:r?he(Re(e,_(t.stem))):Ve(e,t.stem,t.input)}))}function $t(e,n){return he(Re(e,_(n)))}function Ue(e,n){if(typeof e=="string"){e.startsWith("secret://")&&n.add(e.slice(9));return}if(Array.isArray(e)){for(let r of e)Ue(r,n);return}if(e&&typeof e=="object")for(let r of Object.values(e))Ue(r,n)}function le(e){let n=Re(e,"config","credentials"),r=new Set,t=Re(e,"config","integrations.json");if(he(t))try{Ue(JSON.parse(_t(t,"utf8")),r)}catch{}let o=[];if(!he(n))return o;let s=[];try{s=Ft(n).filter(i=>i.endsWith(".json")).map(i=>i.slice(0,-5))}catch{return o}for(let i of s.sort()){if(r.has(i))continue;let d=oe(e,i);o.push({severity:"warning",code:"ORPHANED_CREDENTIAL",message:`${_(i)} 不再被引用(凭据文件保留,可手动清理)`})}return o}function Ie(e){if(typeof e=="string")return e.length>0?e:void 0;if(e&&typeof e=="object"&&J(e)){let n=e.provider;return n.length>0?n:void 0}}async function Ut(e){let n=Bt(e,"config","integrations.json"),r=B(e);if(r===null)return{removed:[],orphanCredentials:[],skipped:"not-configured"};let t=await T(e);if(!t.strictValidation)return{removed:[],orphanCredentials:[],skipped:"predicate-unavailable"};let o;try{let w=Ne(JSON.stringify(r),process.env);if(w.missing.length>0||w.text===void 0)return{removed:[],orphanCredentials:[],skipped:"predicate-unavailable"};o=JSON.parse(w.text)}catch{return{removed:[],orphanCredentials:[],skipped:"predicate-unavailable"}}let s;try{s=await Be(e,o,t,process.env)}catch{return{removed:[],orphanCredentials:[],skipped:"predicate-unavailable"}}let i=V(e),d=new Set(Object.keys(i.catalog.providers)),p=i.ownership,l=structuredClone(r);l.services??={};let m=[];for(let w of s)if(w.severity==="error"){if(w.code==="VENDOR_NOT_INSTALLED")if(w.module){let O=(l.modules??{})[w.module];O?.provider&&(m.push(`modules.${w.module}.provider=${String(O.provider)}`),delete O.provider,Object.keys(O).length===0&&delete l.modules[w.module])}else l.provider&&(m.push(`root.provider=${l.provider}`),delete l.provider);else if(w.code==="MODULE_CONFIG_DEAD"&&w.module){let A=l.modules??{};if(A[w.module]){let O=A[w.module],f=[O.provider!==void 0?"provider":void 0,O.config!==void 0?"config":void 0,O.resources!==void 0?"resources":void 0].filter(Boolean);m.push(`modules.${w.module}(${f.join("+")} 整节点)`),delete l.modules[w.module]}}else if(w.code==="BINDING_UNRESOLVED"&&w.service){let A=l.services[w.service];if(!A)continue;let O=p[w.service];if([w.instance?Ie(A.instances?.[w.instance]?.provider):void 0,Ie(A.provider),O!==void 0?Ie(l.modules?.[O]?.provider):void 0,Ie(l.provider)].filter(a=>typeof a=="string").some(a=>d.has(a)))continue;if(w.instance){let a=A.instances;if(!a||!(w.instance in a))continue;delete a[w.instance],m.push(`services.${w.service}.instances.${w.instance}`),Object.keys(a).length===0&&delete A.instances,Object.keys(A).length===0&&delete l.services[w.service]}else delete l.services[w.service],m.push(`services.${w.service}`)}}if(Object.keys(l.services).length===0&&delete l.services,m.length===0)return{removed:m,orphanCredentials:[]};let k=!l.provider&&Object.keys(l.services??{}).length===0&&Object.keys(l.config??{}).length===0&&Object.keys(l.configByInstance??{}).length===0&&!l.credentialRef&&Object.keys(l.credentialRefByInstance??{}).length===0&&(l.instances??[]).length===0&&l.defaultInstanceId==null&&Object.keys(l.modules??{}).length===0;if(!k&&(l.services??={},typeof t.module.parseIntegrationsConfig=="function"))try{t.module.parseIntegrationsConfig(l)}catch{return{removed:[],orphanCredentials:[],skipped:"validation-failed"}}let R=[];return k?Lt(n)&&Wt(n,{force:!0}):$(n,`${JSON.stringify(l,null,2)}
|
|
4
|
-
`),
|
|
5
|
-
`),t?.invalidate([
|
|
6
|
-
`),t?.invalidate([
|
|
1
|
+
import{a as je,b as T,c as Te}from"./chunk-WUULQDOV.js";import{z as I}from"zod";var K=/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/,ot=I.object({cardType:I.string(),schemaVersion:I.number().optional()}),gn=I.object({route:I.string(),component:I.string()}),mn=I.object({route:I.string(),label:I.string().optional(),icon:I.string().optional(),order:I.number().optional()}),vn=I.object({id:I.string(),range:I.string().optional(),required:I.boolean().default(!0)}),yn=I.object({service:I.string(),provider:I.string().regex(K,"provider 名含非法字符(需 /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/)"),implementation:I.string(),credentialType:I.string(),local:I.boolean().optional(),configSchema:I.string().optional(),credentialSchema:I.string().optional()}),Sn=I.object({service:I.string(),optional:I.boolean().default(!0),defaults:I.array(I.object({provider:I.string().regex(K,"provider 名含非法字符(需 /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/)"),implementation:I.string()})).default([]),name:I.string().optional(),description:I.string().optional()}),wn=I.object({service:I.string()}).strict(),hn=I.object({id:I.string(),type:I.string()}),Rn=I.object({schemaVersion:I.number().default(1),id:I.string(),name:I.string().optional(),description:I.string().optional(),hidden:I.boolean().optional(),version:I.string().default("0.0.0"),kind:I.enum(["platform","business","third-party"]).default("business"),risk:I.object({level:I.enum(["high","medium","low"]).default("low"),writeBoundary:I.enum(["sdk-enforced","source"]).default("source")}).default({}),distribution:I.object({defaultMode:I.enum(["hybrid","sdk","codegen","local"]).default("codegen")}).default({}),declare:I.object({handlers:I.array(I.string()).default([]),tools:I.array(I.string()).default([]),cards:I.array(ot).default([]),routes:I.array(I.string()).default([]),pages:I.array(gn).default([]),tabs:I.array(mn).default([]),providers:I.object({slots:I.array(yn).default([])}).default({}),owns:I.array(wn).default([]),consumes:I.array(Sn).default([]),resources:I.array(hn).default([])}).default({}),dependencies:I.object({modules:I.array(vn).default([])}).default({}),env:I.array(I.string()).default([])}).strict();function st(e){if(!e||typeof e!="object"||Array.isArray(e))return[];let n=[],r=e;"contributes"in r&&n.push("(root): manifest 旧键 `contributes` 已更名 `declare`(v6 声明面)——codegen 副本经 `module update --source` 重新生成 / sdk 模式升级模块包 / 手改两键");let t=r.declare;t&&typeof t=="object"&&!Array.isArray(t)&&"services"in t&&n.push("declare: manifest 旧键 `declare.services` 已更名 `declare.consumes`(消费关系定向化)——同上三路径升级"),!("id"in r)&&"name"in r&&n.push("(root): manifest 标识键 `name` 已更名 `id`(v7 词汇统一)——codegen 副本经 `module update --source` 重新生成 / sdk 模式升级模块包 / 手改两键");let i=t&&typeof t=="object"&&!Array.isArray(t)?t:void 0,s=Array.isArray(i?.consumes)&&i.consumes.some(o=>o!==null&&typeof o=="object"&&"title"in o);return("title"in r||s)&&n.push("(root): manifest 展示名键 `title` 已更名 `name`(v7 词汇统一;declare.consumes[].title 同步改 name)——同上三路径升级"),n}function oe(e){let n=st(e);if(n.length>0)return{ok:!1,errors:n,legacy:!0};let r=Rn.safeParse(e);return r.success?{ok:!0,value:r.data}:{ok:!1,errors:r.error.issues.map(t=>`${t.path.join(".")||"(root)"}: ${t.message}`)}}var at=/\$\$?\{([A-Z][A-Z0-9_]*)(?::-([^}]*))?\}/g;function In(e){return JSON.stringify(e).slice(1,-1)}function Ne(e,n=process.env){let r=[],t=e.replace(at,(i,s,o)=>{if(i.startsWith("$$"))return i.slice(1);let d=n[s];return d!==void 0?In(d):o!==void 0?In(o):(r.push(s),i)});return r.length>0?{missing:r}:{text:t,missing:[]}}import{mkdirSync as ct,existsSync as kn,readFileSync as dt,writeFileSync as lt}from"fs";import{dirname as ut,join as bn}from"path";function ge(e){let n={};for(let[r,t]of Object.entries(e)){if(typeof t!="string"){n[r]=null;continue}n[r]=t.length<=4?"****":`${t.slice(0,2)}****`}return n}var M=class extends Error{code;httpStatus;fields;constructor(n,r,t,i){super(t),this.name="AppToolkitError",this.code=n,this.httpStatus=r,this.fields=i}};function Pe(e){return e.notes.length>0?e.notes[0]:e.version===null?"contracts 不可解析(未安装)——检查应用依赖安装后重试":e.strictValidation?"contracts workspace 源码态未构建——执行 pnpm --filter @tbox.cn/app-contracts build 后重试":`contracts ${e.version} 无严格校验面(需 ≥0.9.0)——升级应用 @tbox.cn/app-contracts 依赖后可用`}function me(e,n){if(n!==void 0&&(n.includes("/")||n.includes("\\")||n.includes("..")))throw new M("VALIDATION_FAILED",400,`凭据 stem 派生输入含路径敌对字符(${e})——拒绝派生`)}function Q(e){if(me("provider",e.provider),me("service",e.service),me("instanceId",e.instanceId),me("domain",e.domain),e.instanceId!==void 0){let n=e.domain??e.service??"global";return`${e.provider}-${e.instanceId}-${n}`}return e.service!==void 0?`${e.provider}-${e.service}`:`${e.provider}-global`}function pt(e){return`secret://${e}`}function _(e){return`config/credentials/${e}.json`}function se(e,n){let r=bn(e,_(n));if(!kn(r))return null;try{let t=JSON.parse(dt(r,"utf8"));if(typeof t.type!="string")return null;let{type:i,...s}=t,o={};for(let[d,p]of Object.entries(s))typeof p=="string"&&(o[d]=p);return{type:i,values:o}}catch{return null}}function Ve(e,n,r){let t=bn(e,_(n)),i=kn(t);return ct(ut(t),{recursive:!0}),lt(t,`${JSON.stringify({type:r.type,...r.values},null,2)}
|
|
2
|
+
`,"utf8"),i}import{mkdirSync as ft,renameSync as gt,writeFileSync as mt}from"fs";import{dirname as vt}from"path";function $(e,n){Cn(vt(e));let r=`${e}.tmp-${process.pid}-${Date.now()}`;mt(r,n,"utf8"),gt(r,e)}function Cn(e){ft(e,{recursive:!0})}import{existsSync as F,readdirSync as Fe,readFileSync as X}from"fs";import{join as P}from"path";import{existsSync as yt,readFileSync as An,mkdirSync as St,writeFileSync as wt}from"fs";import En from"path";function ve(e){return En.join(e,".tbox","app.json")}function On(e){let n=ve(e);if(!yt(n))return null;try{let r=JSON.parse(An(n,"utf8")),t=r?.templateVersion;return typeof t!="string"||t.trim().length===0?null:{templateVersion:t.trim(),npmModules:Array.isArray(r?.npmModules)?r.npmModules:[]}}catch{return null}}function ht(e,n){let r=ve(e);St(En.dirname(r),{recursive:!0}),wt(r,`${JSON.stringify(n,null,2)}
|
|
3
|
+
`,"utf8")}function De(e){let n=On(e);if(n===null)return null;let r=ve(e);try{let t=JSON.parse(An(r,"utf8"));return{...n,miniappContainers:Array.isArray(t?.miniappContainers)?t.miniappContainers:[]}}catch{return{...n,miniappContainers:[]}}}function Rt(e,n){let r=e.npmModules.filter(t=>t.id!==n.id);return{...e,npmModules:[...r,n]}}function It(e,n){return{...e,npmModules:e.npmModules.filter(r=>r.id!==n)}}function kt(e,n){let r=(e.miniappContainers??[]).filter(t=>t.id!==n.id);return{...e,miniappContainers:[...r,n]}}function bt(e,n,r){return{...e,npmModules:e.npmModules.map(t=>t.id===n?{...t,...r}:t)}}function Mn(e){return/^[a-z0-9]+(-[a-z0-9]+)*$/.test(e)&&!e.includes("..")}function Ct(e,n){if(!Mn(e))throw new Error(`非法模块 id "${e}"(来自 ${n}):仅允许小写字母/数字/中划线`)}function xn(e){try{let n=JSON.parse(e);if(!Array.isArray(n.slots))return null;let r=n.slots.filter(i=>typeof i=="string"),t={};if(n.meta&&typeof n.meta=="object"&&!Array.isArray(n.meta))for(let[i,s]of Object.entries(n.meta)){if(!s||typeof s!="object"||Array.isArray(s))continue;let{name:o,description:d}=s,p={};typeof o=="string"&&o.length>0&&(p.name=o),typeof d=="string"&&d.length>0&&(p.description=d),(p.name!==void 0||p.description!==void 0)&&(t[i]=p)}return{slots:r,meta:t}}catch{return null}}function ye(e,n){let r=t=>{try{let i=JSON.parse(t),s=oe(i);if(s.ok)return{kind:"strict",id:s.value.id,version:s.value.version,descriptor:s.value,declare:s.value.declare};if(s.legacy)return{kind:"legacy",detail:s.errors.join("; ")};if(i&&typeof i=="object"&&"declare"in i){let o=i;return{kind:"loose",...typeof o.id=="string"?{id:o.id}:{},declare:{providers:o.declare?.providers,consumes:o.declare?.consumes}}}return null}catch{return null}};if(n)return n.read(e,r)??null;if(!F(e))return null;try{return r(X(e,"utf8"))}catch{return null}}function At(e){let n=P(e,".tbox","app.json");if(!F(n))return[];try{let r=JSON.parse(X(n,"utf8"));return Array.isArray(r.npmModules)?r.npmModules.filter(t=>!!t&&typeof t=="object"&&typeof t.id=="string"&&typeof t.package=="string"):[]}catch{return[]}}function Et(e){let n=P(e,".tbox-dev.local"),r=P(n,"dev-manifest.json");if(!F(r))return[];try{let t=JSON.parse(X(r,"utf8")),i=[];for(let[s,o]of Object.entries(t.redirects??{}))typeof o!="string"||!s.startsWith("@tbox.cn/app-")||i.push({pkg:s,dir:P(n,o)});return i}catch{return[]}}function Ot(e,n){let r=[],t=[e];for(let o of["apps","packages"]){let d=P(e,o);if(F(d))try{for(let p of Fe(d,{withFileTypes:!0}))p.isDirectory()&&t.push(P(d,p.name))}catch{}}let i=new Set,s=(o,d)=>{let p=n?n.read(d,xn):xn(X(d,"utf8"));p!=null&&r.push({dir:o,slots:p.slots,meta:p.meta})};for(let o of t){let d=P(o,"node_modules","@tbox.cn");if(!F(d))continue;let p=[];try{p=Fe(d)}catch{continue}for(let c of p){let f=P(d,c);if(i.has(f))continue;i.add(f);let k=P(f,"service-slots.json"),w=P(f,"src","service-slots.json");F(k)?s(f,k):F(w)&&s(f,w)}}for(let o of t)for(let d of[P(o,"service-slots.json"),P(o,"src","service-slots.json")])F(d)&&s(o,d);return r}function V(e,n){let r=[],t={providers:{},services:{},credentialTypes:{}},i={},s=[],o={},d=new Set,p=(a,m,R,S)=>{for(let u of a){let v=t.providers[u.provider]??={},b=v[u.implementation];b?b.services.includes(u.service)||b.services.push(u.service):(v[u.implementation]={provider:u.provider,implementation:u.implementation,credentialType:u.credentialType,owner:m,...S?.name?{name:S.name}:{},...S?.description?{description:S.description}:{},...u.local?{local:!0}:{},...u.configSchema?{configSchema:u.configSchema}:{},...u.credentialSchema?{credentialSchema:u.credentialSchema}:{},services:[u.service]},t.credentialTypes[u.credentialType]??={owner:m,packageDir:R,...u.credentialSchema?{credentialSchema:u.credentialSchema}:{}});let l=`${u.provider}\0${u.service}`;i[l]||(i[l]={...u.configSchema?{configSchema:u.configSchema}:{},...u.credentialSchema?{credentialSchema:u.credentialSchema}:{},packageDir:R})}},c=a=>a.kind==="strict"?{name:a.descriptor.name,description:a.descriptor.description}:void 0,f=(a,m)=>{for(let R of a){let S=o[R];S===void 0?o[R]=m:S!==m&&s.push({severity:"error",code:"OWNERSHIP_CONFLICT",module:m,message:`服务 ${R} 归属冲突:${S} 与 ${m} 均声明 owns(先声明 ${S} 胜出)——修正 manifest declare.owns 互斥`})}},k=(a,m)=>{a.kind==="legacy"&&s.push({severity:"error",code:"OLD_MANIFEST_KEY",module:m,message:`${m}:${a.detail}`})},w=a=>a.kind==="strict"||a.kind==="loose"?a.declare:null,y=(a,m)=>{let R=a.optional!==!1,S=a.defaults??[],u=t.services[a.service];if(u){u.optional=u.optional&&R;let v=new Set(u.defaults.map(b=>`${b.provider}\0${b.implementation}`));for(let b of S){let l=`${b.provider}\0${b.implementation}`;v.has(l)||(u.defaults.push(b),v.add(l))}u.owners.includes(m)||u.owners.push(m);return}t.services[a.service]={optional:R,defaults:[...S],...a.name?{name:a.name}:{},...a.description?{description:a.description}:{},owners:[m]}};for(let a of At(e)){if(d.has(a.id))continue;let m=P(e,"packages",a.id),R=P(e,"node_modules",...a.package.split("/")),S=ye(P(m,"tbox.module.json"),n)??ye(P(R,"tbox.module.json"),n);if(S?.kind==="legacy"){k(S,a.id),d.add(a.id);continue}if(!S)continue;d.add(a.id);let u=F(P(m,"tbox.module.json"))?m:R,v=w(S);S.kind==="strict"&&r.push({id:a.id,dir:u,pkg:a.mode==="sdk"?a.package:`@app/${a.id}`,descriptor:S.descriptor});let b=v?.providers?.slots??[];b.length&&p(b,a.package,u,c(S));let l=v?.consumes??[];for(let E of l)y(E,a.package);let h=S.kind==="strict"?S.descriptor.declare.owns:[];h.length&&f(h.map(E=>E.service),a.id)}for(let{pkg:a,dir:m}of Et(e)){let R=ye(P(m,"tbox.module.json"),n);if(R?.kind==="legacy"){k(R,a);continue}if(!R?.id||d.has(R.id))continue;d.add(R.id);let S=w(R),u=S?.providers?.slots??[];u.length&&p(u,a,m,c(R));let v=S?.consumes??[];for(let l of v)y(l,a);let b=R.kind==="strict"?R.descriptor.declare.owns:[];b.length&&f(b.map(l=>l.service),R.id)}let A=P(e,"packages");if(F(A)){let a=[];try{a=Fe(A,{withFileTypes:!0}).filter(m=>m.isDirectory()).map(m=>m.name)}catch{}for(let m of a){if(d.has(m))continue;let R=P(A,m),S=ye(P(R,"tbox.module.json"),n);if(S?.kind==="legacy"){k(S,m),d.add(m);continue}if(!S)continue;let u=S.id??m;if(d.has(u))continue;d.add(u);let v=w(S);S.kind==="strict"&&r.push({id:u,dir:R,pkg:`@app/${u}`,descriptor:S.descriptor});let b=v?.providers?.slots??[];b.length&&p(b,`@app/${u}`,R,c(S));let l=v?.consumes??[];for(let E of l)y(E,`@app/${u}`);let h=S.kind==="strict"?S.descriptor.declare.owns:[];h.length&&f(h.map(E=>E.service),u)}}let O=new Set,g={};for(let a of Ot(e,n)){for(let m of a.slots)O.add(m);for(let[m,R]of Object.entries(a.meta))g[m]===void 0&&(g[m]=R)}return{modules:r,catalog:t,serviceSchemas:i,vocabulary:[...O].sort(),slotMeta:g,ownership:o,declarationIssues:s}}function jn(e,n,r){let t=P(e,"src",n,"index.ts");if(!F(t))return!1;try{let i=X(t,"utf8");return new RegExp(`export\\s+const\\s+${r}\\b`).test(i)}catch{return!1}}function Mt(e){let n=P(e,"src","server","index.ts");if(!F(n))return"";try{return X(n,"utf8")}catch{return""}}function Tn(e){return e.match(/declaration\s*:\s*\{[\s\S]*?moduleId\s*:\s*['"]([^'"]+)['"]/)?.[1]}function xt(e){let n=[],r=V(e),t=De(e),i=new Map;for(let s of t?.npmModules??[])i.set(s.id,s.mode);for(let s of r.modules){let o=i.get(s.id)??"local",d=jn(s.dir,"server","serverModule"),p=s.descriptor.declare;n.push({id:s.id,pkg:o==="sdk"?s.pkg:`@app/${s.id}`,mode:o,hasServerEntry:d,hasClientEntry:jn(s.dir,"client","clientModule"),hasCards:(p.cards?.length??0)>0,...d?{moduleId:Tn(Mt(s.dir))}:{}})}return n.sort((s,o)=>s.id.localeCompare(o.id))}function jt(e){return V(e).ownership}function L(e,n){let r=e?.modules?.[n]?.provider;if(typeof r=="string"&&r.length>0)return{provider:r,layer:"module"};let t=e?.provider;return typeof t=="string"&&t.length>0?{provider:t,layer:"app"}:{provider:null,layer:null}}function J(e,n){let r=(n.descriptor.declare.owns??[]).map(t=>t.service).sort();return r.length===0?{writable:!1,reason:"zero-ownership",ownedServices:[]}:{writable:!0,ownedServices:r}}function _e(e,n){return[...new Set(Object.values(e.providers[n]??{}).flatMap(r=>r.services))].sort()}function G(e){if(!e||typeof e!="object")return!1;let n=Object.keys(e),r=new Set(["provider","credentialType","configSchema"]);if(!n.every(i=>r.has(i)))return!1;let t=e;return typeof t.provider=="string"&&t.provider.length>0&&typeof t.credentialType=="string"&&t.credentialType.length>0&&(t.configSchema===void 0||typeof t.configSchema=="string")}function Nn(e,n,r){return e==="*"||r.has(e)?null:{severity:"error",code:"INSTANCE_KEY_NOT_REGISTERED",instance:e,message:`integrations: ${n} 键 ${e} 不在 malls 白名单内(${[...r].join(", ")})`}}function $e(e,n){let r=new Set(n),t=[],i=(s,o)=>{let d=Nn(s,o,r);d&&t.push(d)};for(let s of Object.keys(e.configByInstance??{}))i(s,"configByInstance");for(let s of Object.keys(e.credentialRefByInstance??{}))i(s,"credentialRefByInstance");for(let[s,o]of Object.entries(e.services??{}))for(let d of Object.keys(o.instances??{}))i(d,`services.${s}.instances`);return t}function ee(e){let n=[],r=e.contracts,{integrations:t,suppliedProviders:i,demandedServices:s,supplies:o,malls:d,credentialSchemaMissing:p,vendorConfigKeys:c,vendorGlobalConfigKeys:f,vendorConfigSchemaMissing:k,credentialFileMissing:w,credentialFileType:y,realmSwitchHints:A,moduleResourceNeeds:O,ownership:g,installedModuleIds:a}=e,m=d?new Set(d):void 0;for(let l of A??[])n.push({severity:"warning",code:"REALM_SWITCH_HINT",message:l});let R=new Set(Object.keys(i).map(l=>l.slice(0,l.indexOf("\0"))).filter(l=>l.length>0)),S=(l,h,E,C)=>{if(typeof E?.provider=="string"&&typeof E.implementation=="string"&&E.provider&&E.implementation)return i[ae(E.provider,E.implementation)]?.credentialType;if(typeof h.provider=="string"&&typeof h.implementation=="string")return i[ae(h.provider,h.implementation)]?.credentialType;let x=h.provider?.credentialType;if(typeof x=="string")return x;if(!o)return;let N=C??Object.keys(h.instances??{})[0]??"",j=r.resolveEffectiveService(t,l,N,o,g);if(!(j.status!=="ok"||typeof j.effective.provider!="string"))return i[ae(j.effective.provider,j.effective.implementation)]?.credentialType};if(w||y)for(let[l,h]of Object.entries(t.services))for(let[E,C]of Object.entries(h.instances??{})){if(C.enabled===!1)continue;let x=C.credentialRef??h.credentialRef??t.credentialRefByInstance?.[E]??t.credentialRef;if(typeof x!="string"||!x.startsWith("secret://"))continue;let N=x.slice(9);w?.[N]===!0&&n.push({severity:"error",code:"CREDENTIAL_FILE_MISSING",service:l,instance:E,message:`integrations: 凭据文件缺失 ${N}(${l}@${E} effective ref=${x};档内 config/credentials/ 无此文件)`});let j=y?.[N];if(j){let D=S(l,h,C,E);D&&j!==D&&n.push({severity:"error",code:"CREDENTIAL_TYPE_MISMATCH",service:l,instance:E,message:`integrations: 凭据文件 ${N}.json type=${j} 与绑定 credentialType ${D} 不一致(${l}@${E}——transport 创建期将按 type 选策略)`})}}let u=(l,h)=>{if(!m)return;let E=Nn(l,h,m);E&&n.push(E)};for(let[l]of Object.entries(t.configByInstance??{}))u(l,"configByInstance");for(let[l]of Object.entries(t.credentialRefByInstance??{}))u(l,"credentialRefByInstance");let v=Object.entries(t.services).filter(([,l])=>l.instances==null||l.instances["*"]!=null).map(([l])=>l);if(v.length>0){let l=Object.entries(t.services).filter(([,h])=>h.instances!=null&&h.instances["*"]==null).map(([h])=>h);l.length>0&&n.push({severity:"warning",code:"WILDCARD_ALIGNMENT",message:`integrations: 激活形态不对称(通配:${v.join(", ")};显式键集:${l.join(", ")})——动态 mallId 将在显式键集槽上 INSTANCE_NOT_FOUND(provider 业务限制表达位),确认是否齐步`})}let b=r.normalizeInstances({instances:t.instances,defaultInstanceId:t.defaultInstanceId});b.instances.length>=2&&b.defaultInstanceId===null&&n.push({severity:"warning",code:"MULTI_INSTANCE_NO_DEFAULT",message:`integrations: ${b.instances.length} 个部署实例(${b.instances.map(l=>l.id).join(", ")})均无 defaultInstanceId——无 scope 参数访问将落全局会话(默认商圈不注入)`});for(let[l,h]of Object.entries(t.services)){if(s[l]||n.push({severity:"warning",code:"SLOT_NOT_DECLARED",service:l,message:`integrations: 服务槽 ${l} 无消费方声明(拼写错误或需求方未安装)——若为拆分前旧槽位词汇(member.main/parking.main/promotion.read/shopping-guide.main),参照 cookbook·app-config 槽位迁移配方展开为新槽`}),typeof h.provider=="string"?typeof h.implementation=="string"&&!i[ae(h.provider,h.implementation)]&&n.push({severity:"error",code:"INSTANCE_SUPPLY_UNMATCHED",service:l,message:`integrations: provider ${h.provider}/${h.implementation} 未命中已装供给(${l} 槽级)——装对应 provider 包或改绑`}):h.provider!==void 0&&!G(h.provider)&&n.push({severity:"error",code:"INLINE_PROVIDER_INVALID",service:l,message:`integrations: 内联 provider 超受控形状(${l} 槽级;允许键 provider/credentialType/configSchema)`}),p){let C=S(l,h);C&&p[C]===!0&&n.push({severity:"error",code:"SCHEMA_FILE_MISSING",service:l,message:`integrations: credentialType ${C} 的 schema 引用不存在(${l};manifest 声明指向缺失文件)`})}typeof h.provider=="object"&&typeof h.implementation!="string"&&n.push({severity:"error",code:"IMPL_WITHOUT_PROVIDER",service:l,message:`integrations: 内联厂商声明必须同时提供 implementation(${l} 槽级)`});for(let[C,x]of Object.entries(h.instances??{})){u(C,`services.${l}.instances`);let N=x.provider!==void 0,j=x.implementation!==void 0;if(j&&!N&&n.push({severity:"error",code:"IMPL_WITHOUT_PROVIDER",service:l,instance:C,message:`integrations: 实例级 implementation 需伴随 provider(${l}@${C}——impl-only 禁止,provider 是绑定组头)`}),N&&j){let D=x.provider,W=x.implementation;typeof D=="string"&&typeof W=="string"?i[ae(D,W)]||n.push({severity:"error",code:"INSTANCE_SUPPLY_UNMATCHED",service:l,instance:C,message:`integrations: 实例级 provider 覆盖 ${D}/${W} 未命中已装供给(${l}@${C})`}):G(D)||n.push({severity:"error",code:"INLINE_PROVIDER_INVALID",service:l,instance:C,message:`integrations: 实例级内联 provider 超受控形状(${l}@${C})`})}}}for(let[l,h]of[["root",t.provider],...Object.entries(t.modules??{}).map(([E,C])=>[`modules.${E}`,C?.provider])])typeof h!="string"||h.length===0||R.has(h)||n.push({severity:"error",code:"VENDOR_NOT_INSTALLED",module:l.startsWith("modules.")?l.slice(8):void 0,message:`integrations: ${l} provider ${h} 未命中已装供给——装对应 provider 包或 provider use 改绑`});if(o)for(let[l,h]of Object.entries(t.services)){let E=h.instances?Object.keys(h.instances):[""];for(let C of E){let x=r.resolveEffectiveService(t,l,C,o,g);x.status==="binding-unresolved"&&n.push({severity:"error",code:"BINDING_UNRESOLVED",service:l,instance:C||void 0,message:`integrations: ${x.message}`})}}for(let[l,h]of Object.entries(t.services))h.implementation!==void 0&&h.provider===void 0&&n.push({severity:"error",code:"IMPL_WITHOUT_PROVIDER",service:l,message:`integrations: 槽级 implementation 需伴随 provider(${l}——impl-only 禁止,provider 是绑定组头)`});for(let[l,h]of Object.entries(t.modules??{})){if(!(h?.provider!==void 0||h?.config!==void 0))continue;let C=a?!a.has(l):!1,x=0;if(g)for(let j of Object.values(g))j===l&&(x+=1);if(C||!(g===void 0)&&x===0){let j=C?"未安装(键 = install id)":"未声明任何 owns(无模块级配置位)";n.push({severity:"error",code:"MODULE_CONFIG_DEAD",module:l,message:`integrations: modules.${l} 携带 provider/config 但模块${j}(MODULE_CONFIG_DEAD——模块级集成位作用于 declare.owns 服务,改 declare.owns 或删除该节点)`})}}if(c){let l=new Set,h=!1,E=C=>{typeof C!="string"||C.length===0||(c[C]&&l.add(C),!c[C]&&!k?.[C]&&(h=!0),k?.[C]&&(h=!0))};E(t.provider);for(let C of Object.values(t.modules??{}))E(C?.provider);for(let C of Object.values(t.services)){let x=C.provider;E(typeof C.provider=="string"?C.provider:x?.provider)}if(l.size>0&&!h){let C=new Set;for(let j of l)for(let D of c[j]??[])C.add(D);let x=new Set;for(let j of l)for(let D of f?.[j]??[])x.add(D);let N=(j,D,W,Z)=>{for(let[q]of Object.entries(j??{}))(W??C).has(q)?Z&&Z.size>0&&!Z.has(q)&&n.push({severity:"warning",code:"GLOBAL_FIELD_UNDECLARED",message:`integrations: ${D} 键 ${q} 过 schema 校验但未声明 x-tbox-global(不进应用/模块全局表单;已配置值照常生效——如需全局编辑请在 provider schema 标记)`}):n.push({severity:"error",code:"DOMAIN_CONFIG_INVALID",message:`integrations: ${D} 键 ${q} 不在引用厂商(${[...l].join("/")})任何槽 schema properties 内(死配置)`})};N(t.config,"root.config",void 0,x);for(let[j,D]of Object.entries(t.configByInstance??{}))N(D,`root.configByInstance[${j}]`,void 0,x);for(let[j,D]of Object.entries(t.modules??{})){if(!D?.config)continue;let W=L(t,j).provider??void 0;if(W===void 0){N(D.config,`modules.${j}.config`,void 0,x);continue}let Z=c[W];if(!Z||k?.[W])continue;let q=f?.[W];N(D.config,`modules.${j}.config`,new Set(Z),q)}}}for(let[l,h]of Object.entries(s)){let E=t.services[l];if(!E){n.push({severity:"warning",code:"SLOT_NOT_CONFIGURED",service:l,message:`integrations: 服务槽 ${l}(需求方 ${h.owners.join(", ")})未配置${h.optional?"(可选槽)":"(必需槽——模块将走降级链)"}`});continue}let C=Object.entries(E.instances??{}).filter(([,x])=>x.enabled===!1).map(([x])=>x);C.length>0&&n.push({severity:"warning",code:"INSTANCE_DISABLED",service:l,instance:C.join(", "),message:`integrations: ${l} 实例禁用(${C.join(", ")})`})}for(let[l,h]of Object.entries(t.modules??{})){let E=O?.[l];O&&!(l in O)&&n.push({severity:"warning",code:"RESOURCE_NOT_DECLARED",module:l,message:`integrations: modules.${l} 未命中已装模块(键 = install id——检查 .tbox/app.json entry.id / packages/ 目录名)`});for(let[C,x]of Object.entries(h?.resources??{})){let N=x?.type;(typeof N!="string"||!r.RESOURCE_TYPE_IDS.includes(N))&&n.push({severity:"error",code:"RESOURCE_TYPE_UNKNOWN",module:l,message:`integrations: modules.${l}.resources.${C} type 非法(${String(N)};词汇表 = ${r.RESOURCE_TYPE_IDS.join("/")})`}),E&&E.size>0&&!E.has(C)&&n.push({severity:"warning",code:"RESOURCE_NOT_DECLARED",module:l,message:`integrations: modules.${l}.resources.${C} 未被模块 manifest declare.resources 声明`})}}return n}function ae(e,n){return`${e}\0${n}`}import{existsSync as Le,readFileSync as Tt,readdirSync as Nt}from"fs";import{join as Se}from"path";function Vn(e){return e.replaceAll("-","_").toUpperCase()}function Pn(e){if(!Le(e))return null;try{let n=JSON.parse(Tt(e,"utf8"));return n&&typeof n=="object"?n:null}catch{return null}}function Pt(e){let n=new Set,r=e.properties;if(r&&typeof r=="object"&&!Array.isArray(r))for(let t of Object.keys(r))n.add(t);return n}function ce(e,n,r,t=process.env){let i={};for(let[u,v]of Object.entries(n.catalog.providers))for(let[b,l]of Object.entries(v))i[`${u}\0${b}`]={services:[...l.services],owner:l.owner,credentialType:l.credentialType};let s={};for(let[u,v]of Object.entries(n.catalog.services))s[u]={optional:v.optional,owners:[...v.owners]};let o={},d={},p={},c={},f={};for(let u of n.modules){f[u.id]=new Set((u.descriptor.declare.resources??[]).map(v=>v.id));for(let v of u.descriptor.declare.providers?.slots??[]){if(v.configSchema){let b=Pn(Se(u.dir,v.configSchema));if(b){let l=o[v.provider]??=new Set,h=d[v.provider]??=new Set;for(let C of Pt(b))l.add(C);let E=b.properties;if(E&&typeof E=="object"&&!Array.isArray(E))for(let[C,x]of Object.entries(E))x&&typeof x=="object"&&x["x-tbox-global"]===!0&&h.add(C)}else p[v.provider]=!0}v.credentialSchema&&!Le(Se(u.dir,v.credentialSchema))&&(c[v.credentialType]=!0)}}let k={},w=new Set,y=Se(e,"config","credentials");if(Le(y))for(let u of Nt(y)){if(!u.endsWith(".json"))continue;let v=u.slice(0,-5);w.add(v);let b=Pn(Se(y,u));b&&typeof b.type=="string"&&(k[v]=b.type)}let A=r,O=[],g=u=>{typeof u=="string"&&u.startsWith("secret://")&&O.push(u)};for(let u of Object.values(A.services??{}))if(u&&typeof u=="object"){g(u.credentialRef);for(let v of Object.values(u.instances??{}))v&&typeof v=="object"&&g(v.credentialRef)}for(let u of Object.values(A.credentialRefByInstance??{}))g(u);g(A.credentialRef);let a={};for(let u of O){let v=u.slice(9);t[Vn(v)]===void 0&&(w.has(v)||(a[v]=!0))}let m=[];for(let[u,v]of Object.entries(A.services??{})){let b=v&&typeof v=="object"&&typeof v.provider=="string"?v.provider:void 0;for(let[l,h]of Object.entries((v&&typeof v=="object"?v.instances:void 0)??{})){let E=h&&typeof h=="object"&&typeof h.provider=="string"?h.provider:void 0;b&&E&&E!==b&&m.push(`integrations: ${u}@${l} 实现覆盖跨厂商(${b} → ${E})——凭据域切换,确认该 mall 对应凭据在场`)}}let S=((Array.isArray(A.instances)?A.instances:void 0)??[]).map(u=>u&&typeof u=="object"&&typeof u.id=="string"?u.id:void 0).filter(u=>typeof u=="string");return{suppliedProviders:i,demandedServices:s,credentialFileMissing:a,credentialFileType:k,credentialSchemaMissing:c,vendorConfigKeys:o,vendorGlobalConfigKeys:d,vendorConfigSchemaMissing:p,realmSwitchHints:m,moduleResourceNeeds:f,...S.length>0?{malls:S}:{},ownership:n.ownership,installedModuleIds:new Set([...n.modules.map(u=>u.id),...new Set(Object.values(n.ownership))])}}import{existsSync as Hr,readFileSync as Yr}from"fs";import{join as qr,resolve as Qr}from"path";function We(e){return V(e).catalog}function we(e){let n=V(e).catalog,r={};for(let[s,o]of Object.entries(n.providers)){r[s]={};for(let[d,p]of Object.entries(o))r[s][d]={provider:p.provider,implementation:p.implementation,credentialType:p.credentialType,owner:p.owner,...p.local?{local:!0}:{},...p.configSchema?{configSchema:p.configSchema}:{},...p.credentialSchema?{credentialSchema:p.credentialSchema}:{},services:[...p.services]}}let t={};for(let[s,o]of Object.entries(n.services))t[s]={optional:o.optional,defaults:o.defaults.map(d=>({...d})),owners:[...o.owners]};let i={};for(let[s,o]of Object.entries(n.credentialTypes))i[s]={owner:o.owner,...o.credentialSchema?{credentialSchema:o.credentialSchema}:{}};return{providers:r,services:t,credentialTypes:i}}async function Be(e,n,r,t=process.env){let i=r.module,s=V(e),o=i.buildSupplyLookup(we(e)),d=ce(e,s,n,t);return ee({contracts:i,integrations:n,supplies:o,...d})}import{existsSync as Wt,rmSync as Bt}from"fs";import{join as Ut}from"path";import{existsSync as Vt,readFileSync as Dt}from"fs";import{join as Dn}from"path";var Ft=Dn("config","integrations.json");function B(e,n){let r=Dn(e,Ft),t=i=>JSON.parse(i);if(n)return n.read(r,t)??null;if(!Vt(r))return null;try{return t(Dt(r,"utf8"))}catch{return null}}async function Fn(e,n){let r=await T(e),t=B(e,n);if(t===null)return{config:null,strict:!1,contracts:r};if(r.strictValidation&&r.module.parseIntegrationsConfig)try{return{config:r.module.parseIntegrationsConfig(t),strict:!0,contracts:r}}catch(i){if(i instanceof Error&&Array.isArray(i.issues)){let s=i.issues.filter(o=>Array.isArray(o.path)).map(o=>o.path.map(String).join(".")).filter(o=>o.length>0);throw new M("VALIDATION_FAILED",400,"integrations.json 校验失败",s.length>0?s:void 0)}throw new M("VALIDATION_FAILED",400,i instanceof Error?i.message:String(i))}return{config:t,strict:!1,contracts:r}}function de(e,n,r){return e.includes(r)||n.includes(r)}import{readdirSync as _t,existsSync as he,readFileSync as $t}from"fs";import{join as Re}from"path";function _n(e,n,r){let t=[];if(n){let i=Q({provider:e});t.push({stem:i,ref:`secret://${i}`,input:n})}for(let[i,s]of Object.entries(r??{})){let o=Q({provider:e,instanceId:i});t.push({instanceId:i,stem:o,ref:`secret://${o}`,input:s})}return t}function $n(e,n,r,t,i){let s=[];if(t){let o=Q({provider:e,service:n});s.push({stem:o,ref:`secret://${o}`,input:t})}for(let[o,d]of Object.entries(i??{})){let p=Q({provider:e,instanceId:o,domain:r});s.push({instanceId:o,stem:p,ref:`secret://${p}`,input:d})}return s}function ze(e,n,r){return n.map(t=>({stem:t.stem,ref:t.ref,overwrote:r?he(Re(e,_(t.stem))):Ve(e,t.stem,t.input)}))}function Lt(e,n){return he(Re(e,_(n)))}function Ue(e,n){if(typeof e=="string"){e.startsWith("secret://")&&n.add(e.slice(9));return}if(Array.isArray(e)){for(let r of e)Ue(r,n);return}if(e&&typeof e=="object")for(let r of Object.values(e))Ue(r,n)}function ne(e){let n=Re(e,"config","credentials"),r=new Set,t=Re(e,"config","integrations.json");if(he(t))try{Ue(JSON.parse($t(t,"utf8")),r)}catch{}let i=[];if(!he(n))return i;let s=[];try{s=_t(n).filter(o=>o.endsWith(".json")).map(o=>o.slice(0,-5))}catch{return i}for(let o of s.sort()){if(r.has(o))continue;let d=se(e,o);i.push({severity:"warning",code:"ORPHANED_CREDENTIAL",message:`${_(o)} 不再被引用(凭据文件保留,可手动清理)`})}return i}function Ie(e){if(typeof e=="string")return e.length>0?e:void 0;if(e&&typeof e=="object"&&G(e)){let n=e.provider;return n.length>0?n:void 0}}async function zt(e){let n=Ut(e,"config","integrations.json"),r=B(e);if(r===null)return{removed:[],orphanCredentials:[],skipped:"not-configured"};let t=await T(e);if(!t.strictValidation)return{removed:[],orphanCredentials:[],skipped:"predicate-unavailable"};let i;try{let y=Ne(JSON.stringify(r),process.env);if(y.missing.length>0||y.text===void 0)return{removed:[],orphanCredentials:[],skipped:"predicate-unavailable"};i=JSON.parse(y.text)}catch{return{removed:[],orphanCredentials:[],skipped:"predicate-unavailable"}}let s;try{s=await Be(e,i,t,process.env)}catch{return{removed:[],orphanCredentials:[],skipped:"predicate-unavailable"}}let o=V(e),d=new Set(Object.keys(o.catalog.providers)),p=o.ownership,c=structuredClone(r);c.services??={};let f=[];for(let y of s)if(y.severity==="error"){if(y.code==="VENDOR_NOT_INSTALLED")if(y.module){let O=(c.modules??{})[y.module];O?.provider&&(f.push(`modules.${y.module}.provider=${String(O.provider)}`),delete O.provider,Object.keys(O).length===0&&delete c.modules[y.module])}else c.provider&&(f.push(`root.provider=${c.provider}`),delete c.provider);else if(y.code==="MODULE_CONFIG_DEAD"&&y.module){let A=c.modules??{};if(A[y.module]){let O=A[y.module],g=[O.provider!==void 0?"provider":void 0,O.config!==void 0?"config":void 0,O.resources!==void 0?"resources":void 0].filter(Boolean);f.push(`modules.${y.module}(${g.join("+")} 整节点)`),delete c.modules[y.module]}}else if(y.code==="BINDING_UNRESOLVED"&&y.service){let A=c.services[y.service];if(!A)continue;let O=p[y.service];if([y.instance?Ie(A.instances?.[y.instance]?.provider):void 0,Ie(A.provider),O!==void 0?Ie(c.modules?.[O]?.provider):void 0,Ie(c.provider)].filter(a=>typeof a=="string").some(a=>d.has(a)))continue;if(y.instance){let a=A.instances;if(!a||!(y.instance in a))continue;delete a[y.instance],f.push(`services.${y.service}.instances.${y.instance}`),Object.keys(a).length===0&&delete A.instances,Object.keys(A).length===0&&delete c.services[y.service]}else delete c.services[y.service],f.push(`services.${y.service}`)}}if(Object.keys(c.services).length===0&&delete c.services,f.length===0)return{removed:f,orphanCredentials:[]};let k=!c.provider&&Object.keys(c.services??{}).length===0&&Object.keys(c.config??{}).length===0&&Object.keys(c.configByInstance??{}).length===0&&!c.credentialRef&&Object.keys(c.credentialRefByInstance??{}).length===0&&(c.instances??[]).length===0&&c.defaultInstanceId==null&&Object.keys(c.modules??{}).length===0;if(!k&&(c.services??={},typeof t.module.parseIntegrationsConfig=="function"))try{t.module.parseIntegrationsConfig(c)}catch{return{removed:[],orphanCredentials:[],skipped:"validation-failed"}}let w=[];return k?Wt(n)&&Bt(n,{force:!0}):$(n,`${JSON.stringify(c,null,2)}
|
|
4
|
+
`),w=ne(e).map(y=>y.message),{removed:f,orphanCredentials:w}}function ke(e,n){let r=e.modules.find(i=>i.id===n);if(r)return r;let t=e.modules.filter(i=>(i.descriptor.name??i.descriptor.id)===n);if(t.length===1)return t[0];throw t.length>1?new M("MODULE_NOT_FOUND",404,`模块展示名「${n}」命中多个模块:${t.map(i=>`${i.descriptor.name}(id=${i.id})`).join(" / ")}——请改用模块 id 寻址`):new M("MODULE_NOT_FOUND",404,`模块 ${n} 非已装模块(id / 展示名均未命中)`)}function H(e,n,r){let t=new Set;for(let o of Object.values(e.catalog.providers))for(let d of Object.values(o))for(let p of d.services)t.add(p);if(e.vocabulary.includes(r)||Object.hasOwn(e.catalog.services,r)||t.has(r)||n.includes(r))return r;let i=[],s=o=>{i.includes(o)||i.push(o)};for(let o of e.vocabulary)(e.slotMeta[o]?.name??e.catalog.services[o]?.name)===r&&s(o);for(let[o,d]of Object.entries(e.catalog.services))d.name===r&&s(o);if(i.length===1)return i[0];throw i.length>1?new M("SERVICE_NOT_FOUND",404,`服务展示名「${r}」命中多个服务:${i.join(" / ")}——请改用服务 id 寻址`):new M("SERVICE_NOT_FOUND",404,`服务 ${r} 不在服务词汇(已装契约包 ∪ 已配置)`)}import{existsSync as Bn,readFileSync as Un}from"fs";import{join as te,resolve as Kt}from"path";import Jt from"ajv";var le=["provider","config","configByInstance","credentialRef","credentialRefByInstance","instances","defaultInstanceId"],ue=["provider","config"];var Y=te("config","integrations.json");function re(e,n){if(e===n)return!0;if(Array.isArray(e)&&Array.isArray(n))return e.length!==n.length?!1:e.every((r,t)=>re(r,n[t]));if(e&&n&&typeof e=="object"&&typeof n=="object"){let r=Object.keys(e),t=Object.keys(n);return r.length!==t.length?!1:r.every(i=>re(e[i],n[i]))}return!1}function Ae(e,n){if(typeof e!="string"&&e&&typeof e=="object")for(let[r,t]of Object.entries(e)){if((r==="provider"||r==="instanceId")&&typeof t=="string"&&!K.test(t))throw new M("VALIDATION_FAILED",400,`${r} 名含非法字符(需 /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/)`,[`${n}.${r}`]);Ae(t,`${n}.${r}`)}}function be(e,n,r){if(!(!e||typeof e!="object"||Array.isArray(e))){for(let t of Object.keys(e))if(!(r&&(t==="*"||t==="**"))&&!K.test(t))throw new M("VALIDATION_FAILED",400,`${n} 键 ${t} 含非法字符(需 /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/)——进凭据 stem 派生,防路径逃逸`,[n])}}function Ln(e,n,r){if(r==="root"){let t=e.instances;Array.isArray(t)&&t.forEach((i,s)=>{let o=i&&typeof i=="object"?i.id:void 0;if(typeof o=="string"&&!K.test(o))throw new M("VALIDATION_FAILED",400,`instances[${s}].id 含非法字符(需 /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/)`,[`root.instances[${s}].id`])}),be(e.configByInstance,"root.configByInstance",!1),be(e.credentialRefByInstance,"root.credentialRefByInstance",!1)}else be(e.instances,"services.instances",!0);be(n.credentialsByInstance,"credentialsByInstance",!1)}function Ce(e,n){let r=te(e,Y),t=i=>JSON.parse(i);if(n)return n.read(r,t)??null;if(!Bn(r))return null;try{return t(Un(r,"utf8"))}catch{return null}}function Ke(e){let n=(e.instances??[]).map(r=>r.id);return n.length===0?[]:$e(e,n)}function Gt(e,n,r,t){let{catalog:i}=V(e,t),s=i.providers[n];if(!s)return;let o=new Set;for(let d of Object.values(s))(r===void 0||d.services.includes(r))&&o.add(d.credentialType);return o.size===1?[...o][0]:void 0}function Wn(e,n,r,t,i,s){if(typeof t.type!="string"||t.type.length===0)throw new M("VALIDATION_FAILED",400,"凭据 type 缺失或为空字符串",["credentials.type"]);let o=i??Gt(e,n,r,s);if(o!==void 0&&o!=="-"&&t.type!==o)throw new M("VALIDATION_FAILED",400,`凭据 type=${t.type} 与绑定 credentialType ${o} 不一致`,["credentials.type"]);if(r===void 0)return;let{serviceSchemas:d}=V(e,s),p=d[`${n}\0${r}`];if(!p?.credentialSchema)return;let c=Kt(p.packageDir,p.credentialSchema);if(Bn(c))try{let k=new Jt({allErrors:!0}).compile(JSON.parse(Un(c,"utf8")));if(!k({type:t.type,...t.values})){let w=(k.errors??[]).map(y=>`credentials.values.${String(y.instancePath||y.params?.missingProperty||"").replace(/^\//,"")}`);throw new M("VALIDATION_FAILED",400,"凭据字段校验失败(ajv 字段级)",w)}}catch(f){if(f instanceof M)throw f}}function Je(e,n={}){let{onApplied:r,cache:t}=n;function i(c,f,k,w){let y=c!==null,A=f.length>0,O=!w&&y,g=!w&&A;O&&($(te(e,Y),`${JSON.stringify(c,null,2)}
|
|
5
|
+
`),t?.invalidate([te(e,Y)]));let a=O||g;a&&k.push(...ne(e));let m=a&&r!==void 0;m&&r?.();let R=[];return y&&R.push(Y),A&&R.push(...f.map(S=>_(S.stem))),{written:a,restartScheduled:m,files:R,credentials:f,issues:k}}let s;async function o(){s=await T(e)}function d(c,f){return c.filter(k=>Array.isArray(k.path)).map(k=>{let w=k.path.map(String).join(".");return f!==""&&w.startsWith(f)&&w.length>f.length?w.slice(f.length):w}).filter(k=>k.length>0)}function p(c,f,k){let w=s;if(!w||!w.strictValidation||!w.module.parseIntegrationsConfig)throw new M("CONTRACTS_NOT_RESOLVED",503,"contracts 严格校验面不可用(需 ≥0.9)——写路径门控失败(工厂边缘断言应先行拦截)");try{w.module.parseIntegrationsConfig(c)}catch(y){throw y instanceof Error&&Array.isArray(y.issues)?new M("VALIDATION_FAILED",400,"节点 schema 校验失败",d(y.issues,k)):new M("VALIDATION_FAILED",400,y instanceof Error?y.message:String(y))}}return{warmup:o,applyApp(c,f={}){Ae(c,"root"),Ln(c,f,"root");let k=[],w=Ce(e,t),y=w??{services:{}};w===null&&k.push({severity:"warning",code:"SKELETON_MATERIALIZED",message:"config/integrations.json 缺席——已物化骨架(写时自动初始化;R13 语义翻转提示)"});let A={...y};for(let v of le)v in c||delete A[v];for(let[v,b]of Object.entries(c))A[v]=b;let O=typeof A.provider=="string"?A.provider:"app",g=_n(O,f.credentials,f.credentialsByInstance);for(let v of g)Wn(e,O,void 0,v.input,void 0,t);let a=g.find(v=>v.instanceId===void 0);if(f.credentials&&a&&(A.credentialRef=a.ref),f.credentialsByInstance){let v={...A.credentialRefByInstance??{}};for(let b of g)b.instanceId!==void 0&&(v[b.instanceId]=b.ref);A.credentialRefByInstance=v}let m=f.credentials!==void 0||f.credentialsByInstance!==void 0,R=re(w,A);if(R&&!m)return{written:!1,restartScheduled:!1,files:[],credentials:[],issues:k};p(A,k,"");let S=f.dryRun===!0,u=ze(e,g,S);return k.push(...Ke(A)),i(R?null:A,u,k,f.dryRun)},applyModule(c,f,k={}){Ae(f,"root");let{modules:w,catalog:y,ownership:A}=V(e,t),O=w.find(l=>l.id===c);if(!O)throw new M("MODULE_NOT_FOUND",404,`模块 ${c} 非已装模块`);if(!J({modules:w,catalog:y,ownership:A},O).writable)throw new M("VALIDATION_FAILED",400,`模块 ${c} 未声明任何 declare.owns——无模块级配置位(模块级 provider/config 作用于归属服务)`);let a=[],m=Ce(e,t);if(m===null&&Object.keys(f).length===0)return{written:!1,restartScheduled:!1,files:[],credentials:[],issues:a};m===null&&a.push({severity:"warning",code:"SKELETON_MATERIALIZED",message:"config/integrations.json 缺席——已物化骨架(写时自动初始化;R13 语义翻转提示)"});let R=m??{services:{}},S={...R.modules??{}},u={...S[c]??{}};for(let l of Object.keys(f))if(!ue.includes(l))throw new M("VALIDATION_FAILED",400,`模块集成位仅接受 ${ue.join("/")} 键(收到 ${l})`,[l]);let v={...u};for(let l of ue){let h=f[l];h==null||h===""||typeof h=="object"&&!Array.isArray(h)&&Object.keys(h).length===0?delete v[l]:v[l]=h}Object.keys(v).length===0?delete S[c]:S[c]=v;let b={...R,modules:S};return re(m,b)?{written:!1,restartScheduled:!1,files:[],credentials:[],issues:a}:(p(b,a,`modules.${c}.`),a.push(...Ke(b)),i(b,[],a,k.dryRun))},applyService(c,f,k={}){Ae(f,"root"),Ln(f,k,"slot");let w=[],y=Ce(e,t);if(!de(V(e,t).vocabulary,Object.keys(y?.services??{}),c))throw new M("SERVICE_NOT_FOUND",404,`服务 ${c} 不在服务词汇(已装契约包 ∪ 已配置)`);y===null&&w.push({severity:"warning",code:"SKELETON_MATERIALIZED",message:"config/integrations.json 缺席——已物化骨架(写时自动初始化;R13 语义翻转提示)"});let A=y??{services:{}},O={...A.services??{}},g={...A,services:O};O[c]={...f};let a=f.provider,m=a!==null&&typeof a=="object"?a:void 0,R=typeof a=="string"?a:typeof m?.provider=="string"?m.provider:"app",S=c.includes(".")?c.slice(0,c.indexOf(".")):c,u=$n(R,c,S,k.credentials,k.credentialsByInstance);for(let x of u)Wn(e,R,c,x.input,typeof m?.credentialType=="string"?m.credentialType:void 0,t);let v=O[c],b=u.find(x=>x.instanceId===void 0);if(k.credentials&&b&&(v.credentialRef=b.ref),k.credentialsByInstance){let x={...v.instances??{}};for(let N of u){if(N.instanceId===void 0)continue;let j={...x[N.instanceId]??{}};j.credentialRef=N.ref,x[N.instanceId]=j}v.instances=x}let l=k.credentials!==void 0||k.credentialsByInstance!==void 0,h=re(y,g);if(h&&!l)return{written:!1,restartScheduled:!1,files:[],credentials:[],issues:w};p(g,w,`services.${c}.`);let E=k.dryRun===!0,C=ze(e,u,E);return w.push(...Ke(g)),i(h?null:g,C,w,k.dryRun)},deleteService(c){let f=[],k=Ce(e,t);if(!de(V(e,t).vocabulary,Object.keys(k?.services??{}),c))throw new M("SERVICE_NOT_FOUND",404,`服务 ${c} 不在服务词汇(已装契约包 ∪ 已配置)`);let w={...k?.services??{}};if(!(c in w))return{written:!1,restartScheduled:!1,files:[],credentials:[],issues:f};delete w[c];let y={...k??{services:{}},services:w};$(te(e,Y),`${JSON.stringify(y,null,2)}
|
|
6
|
+
`),t?.invalidate([te(e,Y)]),f.push(...ne(e));let A=r!==void 0;return A&&r?.(),{written:!0,restartScheduled:A,files:[Y],credentials:[],issues:f}}}}import{existsSync as Ht}from"fs";import{join as Yt}from"path";function Ge(e){let n=Yt(e,"config","integrations.json");if(Ht(n))return{generated:!1,reason:"in-place",services:[]};let r=[];for(let s of V(e).modules)for(let o of s.descriptor.declare.providers?.slots??[])o.local===!0&&r.push({service:o.service,provider:o.provider,implementation:o.implementation});if(r.length===0)return{generated:!1,reason:"no-local-slots",services:[]};let t={},i=new Set(r.map(s=>s.provider));if(i.size===1){let[s]=i;for(let o of r)t[o.service]={};$(n,`${JSON.stringify({provider:s,services:t},null,2)}
|
|
7
7
|
`)}else{for(let s of r)t[s.service]={provider:s.provider,implementation:s.implementation};$(n,`${JSON.stringify({services:t},null,2)}
|
|
8
|
-
`)}return{generated:!0,reason:"generated",services:r.map(s=>s.service).sort()}}function Un(e,n){let r=V(e.appDir,e.cache),t=B(e.appDir,e.cache);return{appDir:e.appDir,walk:r,catalog:r.catalog,integrations:t,contracts:n}}function zn(e){let n=new Set;for(let r of e.modules){for(let t of r.descriptor.declare.owns??[])n.add(t.service);for(let t of r.descriptor.declare.consumes??[])n.add(t.service);for(let t of r.descriptor.declare.providers?.slots??[])n.add(t.service)}return n}function Ee(e,n,r){let t=e.providers[n];return t?Object.values(t).some(o=>o.services.includes(r)):!1}function Kn(e,n){let r=[];for(let[t,o]of Object.entries(e.providers))Object.values(o).some(s=>s.services.includes(n))&&r.push(t);return r.sort()}function U(e,n){let r=e.slotMeta[n],t=e.catalog.services[n],o=r?.name??t?.name??n,s=r?.description??t?.description;return{name:o,...s!==void 0?{description:s}:{}}}function Jn(e){return e.replace(/^@tbox\.cn\/app-/,"").replace(/^@[^/]+\//,"")}function Ht(e){return Jn(e.id).startsWith("provider-")||Jn(e.pkg).startsWith("provider-")}function Ye(e){return{modules:e.walk.modules.filter(r=>!Ht(r)).map(r=>({id:r.id,name:r.descriptor.name??r.descriptor.id,description:r.descriptor.description??""})).sort((r,t)=>r.id.localeCompare(t.id))}}function He(e,n){let r=e.walk.modules.find(l=>l.id===n);if(!r)throw new x("MODULE_NOT_FOUND",404,`模块 ${n} 非已装模块`);let t=(r.descriptor.declare.consumes??[]).map(l=>{let m=U(e.walk,l.service);return{service:l.service,name:m.name,...m.description!==void 0?{description:m.description}:{},required:l.optional===!1}}),o=K(e.walk,r),i=(e.integrations?.modules??{})[n],d=i?{...typeof i.provider=="string"?{provider:i.provider}:{},...i.config&&typeof i.config=="object"&&!Array.isArray(i.config)?{config:i.config}:{}}:null,p=L(e.integrations,n);return{name:r.descriptor.name??r.descriptor.id,description:r.descriptor.description??"",ownedServices:o.ownedServices,integration:d,binding:{provider:p.provider,layer:p.layer},configEditable:o.writable,services:t}}function Ze(e){let n=zn(e.walk),r=e.walk.vocabulary.filter(s=>!n.has(s)).map(s=>{let i=U(e.walk,s);return{service:s,name:i.name,...i.description!==void 0?{description:i.description}:{},required:!1}}),t=e.integrations,o=null;if(t){let s={};for(let i of de)i in t&&(s[i]=t[i]);o=s}return{services:r,integration:o}}function qe(e,n){let r=e.integrations?.services??{},t=e.catalog.services[n];if(!ce(e.walk.vocabulary,Object.keys(r),n))throw new x("SERVICE_NOT_FOUND",404,`服务 ${n} 不在服务词汇(已装契约包 ∪ 已配置)`);let o=r[n]??null,s=U(e.walk,n);return{service:n,name:s.name,...s.description!==void 0?{description:s.description}:{},required:t?!t.optional:!1,defaults:t?t.defaults.map(i=>({...i})):[],integration:o,suppliedBy:Kn(e.catalog,n)}}import{existsSync as Hn,readFileSync as Zn,realpathSync as Gn}from"fs";import{isAbsolute as Zt,join as qt,relative as Qt,resolve as Yn,sep as Xt}from"path";function Qe(e){let n=[];for(let[r,t]of Object.entries(e.catalog.providers)){let o=Object.values(t);o.length!==0&&n.push({provider:r,local:o.every(s=>s.local===!0),owner:o[0].owner,...o[0].name?{name:o[0].name}:{},...o[0].description?{description:o[0].description}:{}})}return{providers:n.sort((r,t)=>r.provider.localeCompare(t.provider))}}function Xe(e,n,r){let t=e.catalog.providers[n];if(!t)throw new x("PROVIDER_NOT_FOUND",404,`厂商 ${n} 不 ∈ catalog(内联声明厂商无包级档案——身份与表单经组合端点暴露)`);let o={};for(let i of Object.values(t))for(let d of i.services)(o[d]??={implementations:[]}).implementations.push({implementation:i.implementation,credentialType:i.credentialType});for(let[i,d]of Object.entries(o)){let p=U(e.walk,i);d.name=p.name,p.description!==void 0&&(d.description=p.description)}if(r?.has("integrationSchemas"))for(let[i,d]of Object.entries(o))d.integrationSchemas={configSchema:H(e,n,i)};let s=Object.values(t);return{provider:n,local:s.every(i=>i.local===!0),owner:s[0].owner,...s[0].name?{name:s[0].name}:{},...s[0].description?{description:s[0].description}:{},services:o}}function en(e,n,r){let t=e.catalog.providers[n],o=e.integrations?.services??{},s=[];if(t)for(let l of Object.values(t))l.services.includes(r)&&s.push({implementation:l.implementation,credentialType:l.credentialType});let i=o[r]?.provider,d=i&&typeof i=="object"&&i.provider===n?i:void 0;if(s.length===0&&!d)throw t?new x("SUPPLY_NOT_FOUND",404,`厂商 ${n} 未供给服务 ${r}(AI 帮我实现流:PUT 显式绑定后实施)`):new x("PROVIDER_NOT_FOUND",404,`厂商 ${n} 完全未知(不 ∈ catalog 且无任何内联声明)`);s.length===0&&d&&s.push({implementation:o[r]?.implementation??`${n}-inline@1`,credentialType:d.credentialType});let p=H(e,n,r,d?i?.configSchema:void 0);return{provider:n,service:r,implementations:s,integrationSchemas:{configSchema:p}}}function H(e,n,r,t){let o=e.walk.serviceSchemas[`${n}\0${r}`];return o?nn(e.appDir,o.packageDir,o.configSchema):typeof t=="string"?er(e.appDir,t):null}function nn(e,n,r){if(!r)return null;let t=qt(n,r);if(!Hn(t))return null;try{return JSON.parse(Zn(t,"utf8"))}catch{return null}}function er(e,n){let r=Yn(e,"config","schemas"),t=Yn(e,n),o=Qt(r,t);if(o===""||o.startsWith("..")||Zt(o))throw new x("VALIDATION_FAILED",400,"configSchema 引用必须落在 config/schemas/ 内(禁路径逃逸)",["provider.configSchema"]);if(!Hn(t))return null;let s,i;try{s=Gn(r),i=Gn(t)}catch{return null}if(i!==s&&!i.startsWith(s+Xt))throw new x("VALIDATION_FAILED",400,"configSchema 引用经 symlink 逃逸出 config/schemas/(realpath 复核拒绝)",["provider.configSchema"]);try{return JSON.parse(Zn(t,"utf8"))}catch{return null}}function qn(e){return{version:e.version,evaluation:e.evaluation,strictValidation:e.strictValidation,notes:[...e.notes]}}function Qn(e,n,r){let t=e.integrations,o=t?.services?.[n],s=o?.instances?.[r]??o?.instances?.["*"];if(s&&s.provider!==void 0)return"instance";if(o?.provider!==void 0)return"service";let i=e.walk.ownership[n];return i!==void 0&&L(e.integrations,i).layer==="module"?"module":typeof t?.provider=="string"&&t.provider.length>0?"app":null}function Xn(e,n,r,t,o){let s=n.resolveEffectiveService(e.integrations,r,t,o);if(s.status==="ok"&&s.effective){let i=s.effective.provider,d=typeof i=="string"?i:String(i?.provider??"");return{status:"ok",provider:d,implementation:s.effective.implementation,effective:{provider:d,implementation:s.effective.implementation,...s.effective.config!==void 0?{config:{...s.effective.config}}:{},...s.effective.credentialRef!==void 0?{credentialRef:s.effective.credentialRef}:{},layer:Qn(e,r,t)??"app"}}}return s.status==="binding-unresolved"?{status:"binding-unresolved",statusMessage:s.message}:{status:s.status}}function tn(e){let n=e.contracts.module;if(!n.resolveEffectiveService||!n.normalizeInstances)throw new x("CONTRACTS_NOT_RESOLVED",503,"contracts 求值面缺席(契约包形态异常)——重新安装或升级应用 @tbox.cn/app-contracts 后重试");return n}function rn(e,n){let r=tn(n),{integrations:t,catalog:o}=n,s=r.buildSupplyLookup(o),i=t,p=r.normalizeInstances({instances:i?.instances,defaultInstanceId:i?.defaultInstanceId}).defaultInstanceId??"*",l=Xn(n,r,e,p,s),m=Qn(n,e,p),k=n.integrations?.services?.[e]?.provider,R=l.provider??(typeof k=="string"?k:typeof k=="object"&&k?String(k.provider):void 0),w=new Set(Object.keys(n.catalog.providers)),A=R!==void 0&&w.has(R)?nr(n.catalog,R,e):void 0,O=o.services[e],f=O!==void 0?!O.optional:void 0,a=O?.owners[0];return{status:l.status,...l.statusMessage?{statusMessage:l.statusMessage}:{},...R!==void 0?{provider:R}:{},...R!==void 0&&m!==null?{layer:m}:{},...A!==void 0?{supplied:A}:{},...a!==void 0?{module:a}:{},...f!==void 0?{required:f}:{}}}function nr(e,n,r){return Ee(e,n,r)}function pe(e,n,r){let t=new Set([...e.walk.vocabulary,...Object.keys(e.catalog.services)]),o=e.integrations?.services??{};for(let i of Object.keys(o))t.add(i);let s={};for(let i of[...t].sort())r&&!r.includes(i)||(s[i]=rn(i,e));return{contracts:qn(e.contracts),resolutions:s,issues:n}}function on(e,n,r){let t=tn(n),o=t.buildSupplyLookup(n.catalog),s=n.integrations,d=t.normalizeInstances({instances:s?.instances,defaultInstanceId:s?.defaultInstanceId}).instances.map(O=>O.id),p=n.integrations?.services?.[e],l=p?.instances?Object.keys(p.instances):void 0,m;d.length>0?(m=[...d],l?.includes("*")&&m.push("*")):l!==void 0&&l.length>0?m=l.includes("*")?["*"]:l:m=[];let k=m.map(O=>{let f=Xn(n,t,e,O,o);return{instanceId:O,status:f.status,...f.statusMessage?{statusMessage:f.statusMessage}:{},...f.effective?{effective:f.effective}:{}}}),R=tr(n,e),A={...rn(e,n),instances:k,inheritance:R};return{contracts:qn(n.contracts),resolution:A,issues:r.filter(O=>O.service===e)}}function tr(e,n){let r=e.integrations,t=r?.services?.[n],o=e.integrations,i=tn(e).normalizeInstances({instances:o?.instances,defaultInstanceId:o?.defaultInstanceId}).defaultInstanceId??"*",d=t?.instances?.[i]??t?.instances?.["*"],p=e.walk.ownership[n],l=p!==void 0?L(r,p):{provider:null,layer:null};return[{layer:"app",...r?.provider?{provider:r.provider}:{}},{layer:"module",...l.layer==="module"&&l.provider?{provider:l.provider}:{}},{layer:"service",...typeof t?.provider=="string"?{provider:t.provider}:{},...t?.implementation?{implementation:t.implementation}:{}},{layer:"instance",...d?.provider?{provider:d.provider}:{},...d?.implementation?{implementation:d.implementation}:{}}]}function sn(e,n,r){if(n===null)return null;let t={};for(let o of r)t[o]={configSchema:H(e,n,o)};return{provider:n,services:t}}function re(e){return e===null||typeof e!="object"?JSON.stringify(e??null):Array.isArray(e)?`[${e.map(re).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${re(e[r])}`).join(",")}}`}var rr="\0no-enum";function ir(e){let n=e.enum;return Array.isArray(n)?`[${[...new Set(n.map(re))].sort().join(",")}]`:rr}function or(e){if(!e||typeof e!="object"||Array.isArray(e))return null;let n=e.type;return n===void 0?null:re(n)}function sr(e){let n=e.map(t=>or(t.subschema));if(n.some(t=>t===null)||new Set(n).size>1)return null;if(n[0]==='"object"'){let t=re(e[0].subschema);return e.every(o=>re(o.subschema)===t)?e[0].subschema:null}return new Set(e.map(t=>ir(t.subschema))).size===1?e[0].subschema:null}function Oe(e,n){let r=[],t=!0,o=new Map;for(let[i,d]of Object.entries(e.services)){let p=d.configSchema;if(p===null){r.push(i);continue}if(!p||typeof p!="object"||Array.isArray(p))continue;let l=p;l.additionalProperties===!1&&(t=!1);let m=l.properties;if(!m||typeof m!="object"||Array.isArray(m))continue;let k=Array.isArray(l.required)?l.required:[];for(let R of Object.keys(m)){let w=o.get(R)??[];w.push({service:i,subschema:m[R],required:k.includes(R)}),o.set(R,w)}}let s=[];for(let[i,d]of o)s.push({key:i,schema:sr(d),sources:d.map(({service:p,required:l})=>({service:p,required:l})),global:d.some(p=>!!p.subschema&&typeof p.subschema=="object"&&p.subschema["x-tbox-global"]===!0)});return{provider:e.provider,schemaless:r,unsupplied:[...n?.unsupplied??[]],additionalPropertiesAllowed:t,fields:s}}function an(e,n,r,t){let o=typeof t=="string"&&t.length>0?t:void 0;if(e==="app"){if(o!==void 0)return o;let d=n.integrations?.provider;return typeof d=="string"&&d.length>0?d:null}let s=n.walk.modules.find(d=>d.id===r);return!s||!K(n.walk,s).writable?null:o!==void 0?o:L(n.integrations,s.id).provider}var et={integrationSchemas:null,integrationFieldRegistry:null};function nt(e){return{...e,fields:e.fields.filter(n=>n.global)}}function cn(e,n){let r=an("app",e,void 0,n);if(r===null)return et;let t=sn(e,r,_e(e.catalog,r));return{integrationSchemas:t,integrationFieldRegistry:nt(Oe(t))}}function ln(e,n,r){let t=an("module",e,n,r),o=e.walk.modules.find(p=>p.id===n);if(t===null||!o)return et;let s=(o.descriptor.declare.owns??[]).map(p=>p.service),i=p=>Ee(e.catalog,t,p),d=sn(e,t,s.filter(i));return{integrationSchemas:d,integrationFieldRegistry:nt(Oe(d,{unsupplied:[...new Set(s.filter(p=>!i(p)))]}))}}function ar(e){return cn(e).integrationSchemas}function cr(e,n){return ln(e,n).integrationSchemas}function lr(e,n){let r=e.walk.ownership[n];if(r!==void 0)return L(e.integrations,r).provider;let t=e.integrations?.provider;return typeof t=="string"&&t.length>0?t:null}function xe(e,n){let r=e.integrations?.services?.[n]?.provider;if(r===void 0||r===""){let t=lr(e,n);return t===null?null:{provider:t,configSchema:H(e,t,n)}}if(typeof r=="string")return{provider:r,configSchema:H(e,r,n)};if(J(r)){let t=r;return{provider:t.provider,configSchema:H(e,t.provider,n,t.configSchema)}}return null}function dn(e,n){let r=xe(e,n);if(r===null)return null;let t={provider:r.provider,services:{[n]:{configSchema:r.configSchema}}};return Oe(t)}function fe(e,n){if(n===void 0||!n.startsWith("secret://"))return;let r=n.slice(9),t=oe(e,r);if(t)return{type:t.type,ref:n,file:_(r),masked:ge(t.values)}}function un(e){let n=e.integrations,r={credential:fe(e.appDir,typeof n?.credentialRef=="string"?n.credentialRef:void 0)??null,byInstance:{}};for(let{id:o}of n?.instances??[]){let s=n?.credentialRefByInstance?.[o];s!==void 0&&(r.byInstance[o]=fe(e.appDir,s)??null)}let t={};for(let[o,s]of Object.entries(n?.services??{})){let i={credential:fe(e.appDir,s.credentialRef)??null,byInstance:{}};for(let[d,p]of Object.entries(s.instances??{}))i.byInstance[d]=fe(e.appDir,p.credentialRef)??null;t[o]=i}return{app:r,services:t}}function pn(e,n){return{types:(n===void 0?Object.keys(e.catalog.credentialTypes):[...new Set(Object.values(e.catalog.providers[n]??{}).map(t=>t.credentialType))]).sort().map(t=>{let o=e.catalog.credentialTypes[t];return{credentialType:t,owner:o?.owner??"",credentialSchema:o?nn(e.appDir,o.packageDir,o.credentialSchema):null}})}}import dr from"path";var ur={app:["serviceResolutions","integrationSchemas","integrationFieldRegistry"],module:["serviceResolutions","integrationSchemas","integrationFieldRegistry"],provider:["integrationSchemas"],service:["integrationSchemas","integrationFieldRegistry"]};function Me(e,n){if(!n||n.length===0)return new Set;let r=ur[e],t=[...new Set(n)].filter(o=>!r.includes(o));if(t.length>0)throw new x("VALIDATION_FAILED",400,`include 含未知或不适用于本端点的键:${t.join("、")}(白名单:${r.join("、")})`,["include"]);return new Set(n)}var tt=["integrationSchemas","integrationFieldRegistry"];function rt(e,n,r){if(!(typeof n!="string"||n.length===0)&&!tt.some(t=>r.has(t)))throw new x("VALIDATION_FAILED",400,`参数 ${e} 需与表单 include 键(${tt.join("、")})同现——轴参仅重定向表单层双投影`,[e])}function pr(e,n={}){let r=je(),t=Promise.resolve(),o={appDir:e,cache:r};function s(f){if(!f.strictValidation)throw new x("CONTRACTS_NOT_RESOLVED",503,Pe(f));if(!f.ownershipBindingV6)throw new x("CONTRACTS_NOT_RESOLVED",503,`contracts ${f.version??"(版本未知)"} 不支持 v6 modules 绑定形状(OWNERSHIP_BINDING_V6 标记缺席)——升级应用 @tbox.cn/app-contracts 依赖后可用`)}function i(f){return Un(o,f)}function d(f){let a=f.integrations?.services;return a&&typeof a=="object"?Object.keys(a):[]}async function p(){let f=await T(e),a=i(f),g=a.integrations;if(g===null)return[];let h={resolveEffectiveService:l(f.module.resolveEffectiveService,"resolveEffectiveService"),buildSupplyLookup:l(f.module.buildSupplyLookup,"buildSupplyLookup"),normalizeInstances:l(f.module.normalizeInstances,"normalizeInstances"),RESOURCE_TYPE_IDS:f.module.RESOURCE_TYPE_IDS??[]},y=ae(e,a.walk,g,process.env);return ee({contracts:h,integrations:g,supplies:h.buildSupplyLookup(a.catalog),...y})}function l(f,a){if(typeof f!="function")throw new x("CONTRACTS_NOT_RESOLVED",503,`contracts 求值面 ${a} 缺席(形态异常)`);return f}function m(f){let a=t.then(f,f);return t=a.catch(()=>{}),a}let k={async loadModules(){let f=await T(e);return Ye(i(f))},async loadModule(f,a){let g=Me("module",a?.include);rt("moduleProvider",a?.moduleProvider,g);let h=await T(e),y=i(h),u=ke(y.walk,f),v=He(y,u.id);if(g.has("serviceResolutions")&&(v.serviceResolutions=h.evaluation&&h.strictValidation?await p().then(b=>pe(y,b,v.services.map(c=>c.service))):null),g.has("integrationSchemas")||g.has("integrationFieldRegistry")){let b=ln(y,u.id,a?.moduleProvider);g.has("integrationSchemas")&&(v.integrationSchemas=b.integrationSchemas),g.has("integrationFieldRegistry")&&(v.integrationFieldRegistry=b.integrationFieldRegistry)}return v},async loadApp(f){let a=Me("app",f?.include);rt("appProvider",f?.appProvider,a);let g=await T(e),h=i(g),y=Ze(h);if(a.has("serviceResolutions")&&(y.serviceResolutions=g.evaluation&&g.strictValidation?await p().then(u=>pe(h,u)):null),a.has("integrationSchemas")||a.has("integrationFieldRegistry")){let u=cn(h,f?.appProvider);a.has("integrationSchemas")&&(y.integrationSchemas=u.integrationSchemas),a.has("integrationFieldRegistry")&&(y.integrationFieldRegistry=u.integrationFieldRegistry)}return y},async loadService(f,a){let g=Me("service",a?.include),h=await T(e),y=i(h),u=G(y.walk,d(y),f),v=qe(y,u);return g.has("integrationSchemas")&&(v.integrationSchemas=xe(y,u)),g.has("integrationFieldRegistry")&&(v.integrationFieldRegistry=dn(y,u)),v},async loadServiceResolutions(f){let a=await T(e);s(a);let g=await p();return pe(i(a),g,f)},async loadServiceResolution(f){let a=await T(e);s(a);let g=i(a),h=G(g.walk,d(g),f),y=await p();return on(h,g,y)},async loadProviders(){let f=await T(e);return Qe(i(f))},async loadProvider(f,a){let g=Me("provider",a?.include),h=await T(e);return Xe(i(h),f,g)},async loadProviderService(f,a){let g=await T(e),h=i(g),y=G(h.walk,d(h),a);return en(h,f,y)},async loadCredentials(){let f=await T(e);return un(i(f))},async loadCredentialTypes(f){let a=await T(e);return pn(i(a),f)}},R=Je(e,{onApplied:n.onApplied,cache:r}),w={async writeAppIntegration(f,a){await R.warmup();let g=await T(e);return s(g),m(()=>R.applyApp(f,a))},async writeModuleIntegration(f,a,g){await R.warmup();let h=await T(e);return s(h),m(()=>{let y=ke(i(h).walk,f);return R.applyModule(y.id,a,g)})},async writeServiceIntegration(f,a,g){await R.warmup();let h=await T(e);return s(h),m(()=>{let y=i(h),u=G(y.walk,d(y),f);return R.applyService(u,a,g)})},async deleteServiceIntegration(f){await R.warmup();let a=await T(e);return s(a),m(()=>{let g=i(a),h=G(g.walk,d(g),f);return R.deleteService(h)})}},A={invalidate(){r.invalidate(),Te(e)},async resolveContracts(){return T(e)},walkManifests(){return O(e)},parseModuleDescriptor(f){return ie(f)},loadProviderCatalogRaw(){return We(e)},async readIntegrationsConfig(){return B(e,r)},async writeIntegrationsConfig(f){await R.warmup();let a=await T(e);return s(a),m(()=>fr(e,f,r))},async ensureMockBindings(){await R.warmup();let f=await T(e);return s(f),m(()=>Ge(e))},async evaluateIntegrationServices(f){await R.warmup();let a=await T(e);s(a);let g={resolveEffectiveService:l(a.module.resolveEffectiveService,"resolveEffectiveService"),buildSupplyLookup:l(a.module.buildSupplyLookup,"buildSupplyLookup"),normalizeInstances:l(a.module.normalizeInstances,"normalizeInstances"),RESOURCE_TYPE_IDS:a.module.RESOURCE_TYPE_IDS??[]};return ee({...f,contracts:g})}};function O(f){return V(f,r)}return{...k,...w,...A}}function fr(e,n,r){let t=dr.join(e,"config","integrations.json");$(t,`${JSON.stringify(n,null,2)}
|
|
9
|
-
`),r.invalidate([t])}export{
|
|
8
|
+
`)}return{generated:!0,reason:"generated",services:r.map(s=>s.service).sort()}}import{existsSync as Zt,readFileSync as qt}from"fs";import{join as Hn}from"path";function zn(e,n){let r=V(e.appDir,e.cache),t=B(e.appDir,e.cache);return{appDir:e.appDir,walk:r,catalog:r.catalog,integrations:t,contracts:n,...e.cache?{cache:e.cache}:{}}}function Kn(e){let n=new Set;for(let r of e.modules){for(let t of r.descriptor.declare.owns??[])n.add(t.service);for(let t of r.descriptor.declare.consumes??[])n.add(t.service);for(let t of r.descriptor.declare.providers?.slots??[])n.add(t.service)}return n}function Ee(e,n,r){let t=e.providers[n];return t?Object.values(t).some(i=>i.services.includes(r)):!1}function Jn(e,n){let r=[];for(let[t,i]of Object.entries(e.providers))Object.values(i).some(s=>s.services.includes(n))&&r.push(t);return r.sort()}function U(e,n){let r=e.slotMeta[n],t=e.catalog.services[n],i=r?.name??t?.name??n,s=r?.description??t?.description;return{name:i,...s!==void 0?{description:s}:{}}}var Qt=Hn("config","knowledge.json");function Xt(e,n,r){let i=r[n]?.resources;if(!i||typeof i!="object"||Array.isArray(i))return null;let s=Hn(e.appDir,Qt),o={};if(Zt(s))try{o=(e.cache?.read(s,c=>JSON.parse(c))??JSON.parse(qt(s,"utf8"))).knowledge_bases??{}}catch{o={}}let d={};for(let[p,c]of Object.entries(i)){if(!c||typeof c!="object"||Array.isArray(c))continue;let f=c,k=f.type==="knowledge"?"knowledge":String(f.type??"knowledge"),w=typeof f.datasetId=="string"&&f.datasetId!==""?f.datasetId:void 0,y=typeof f.ref=="string"&&f.ref!==""?f.ref:void 0,A=w??(y!==void 0&&typeof o[y]?.datasetId=="string"?o[y].datasetId:null),O={type:k,...w!==void 0?{datasetId:w}:{},...y!==void 0?{ref:y}:{},resolvedDatasetId:A,...typeof f.topK=="number"?{topK:f.topK}:{},...typeof f.scoreThreshold=="number"?{scoreThreshold:f.scoreThreshold}:{}};d[p]=O}return Object.keys(d).length>0?d:null}function Gn(e){return e.replace(/^@tbox\.cn\/app-/,"").replace(/^@[^/]+\//,"")}function er(e){return Gn(e.id).startsWith("provider-")||Gn(e.pkg).startsWith("provider-")}function He(e,n={}){return{modules:e.walk.modules.filter(t=>!er(t)).filter(t=>n.includeHidden===!0||t.descriptor.hidden!==!0).map(t=>({id:t.id,name:t.descriptor.name??t.descriptor.id,description:t.descriptor.description??"",...t.descriptor.hidden===!0?{hidden:!0}:{}})).sort((t,i)=>t.id.localeCompare(i.id))}}function Ye(e,n){let r=e.walk.modules.find(c=>c.id===n);if(!r)throw new M("MODULE_NOT_FOUND",404,`模块 ${n} 非已装模块`);let t=(r.descriptor.declare.consumes??[]).map(c=>{let f=U(e.walk,c.service);return{service:c.service,name:f.name,...f.description!==void 0?{description:f.description}:{},required:c.optional===!1}}),i=J(e.walk,r),s=e.integrations?.modules??{},o=s[n],d=o?{...typeof o.provider=="string"?{provider:o.provider}:{},...o.config&&typeof o.config=="object"&&!Array.isArray(o.config)?{config:o.config}:{}}:null,p=L(e.integrations,n);return{name:r.descriptor.name??r.descriptor.id,description:r.descriptor.description??"",...r.descriptor.hidden===!0?{hidden:!0}:{},ownedServices:i.ownedServices,integration:d,resources:Xt(e,n,s),binding:{provider:p.provider,layer:p.layer},configEditable:i.writable,services:t}}function Ze(e){let n=Kn(e.walk),r=e.walk.vocabulary.filter(s=>!n.has(s)).map(s=>{let o=U(e.walk,s);return{service:s,name:o.name,...o.description!==void 0?{description:o.description}:{},required:!1}}),t=e.integrations,i=null;if(t){let s={};for(let o of le)o in t&&(s[o]=t[o]);i=s}return{services:r,integration:i}}function qe(e,n){let r=e.integrations?.services??{},t=e.catalog.services[n];if(!de(e.walk.vocabulary,Object.keys(r),n))throw new M("SERVICE_NOT_FOUND",404,`服务 ${n} 不在服务词汇(已装契约包 ∪ 已配置)`);let i=r[n]??null,s=U(e.walk,n);return{service:n,name:s.name,...s.description!==void 0?{description:s.description}:{},required:t?!t.optional:!1,defaults:t?t.defaults.map(o=>({...o})):[],integration:i,suppliedBy:Jn(e.catalog,n)}}import{existsSync as qn,readFileSync as Qn,realpathSync as Yn}from"fs";import{isAbsolute as nr,join as tr,relative as rr,resolve as Zn,sep as ir}from"path";function Qe(e){let n=[];for(let[r,t]of Object.entries(e.catalog.providers)){let i=Object.values(t);i.length!==0&&n.push({provider:r,local:i.every(s=>s.local===!0),owner:i[0].owner,...i[0].name?{name:i[0].name}:{},...i[0].description?{description:i[0].description}:{}})}return{providers:n.sort((r,t)=>r.provider.localeCompare(t.provider))}}function Xe(e,n,r){let t=e.catalog.providers[n];if(!t)throw new M("PROVIDER_NOT_FOUND",404,`厂商 ${n} 不 ∈ catalog(内联声明厂商无包级档案——身份与表单经组合端点暴露)`);let i={};for(let o of Object.values(t))for(let d of o.services)(i[d]??={implementations:[]}).implementations.push({implementation:o.implementation,credentialType:o.credentialType});for(let[o,d]of Object.entries(i)){let p=U(e.walk,o);d.name=p.name,p.description!==void 0&&(d.description=p.description)}if(r?.has("integrationSchemas"))for(let[o,d]of Object.entries(i))d.integrationSchemas={configSchema:z(e,n,o)};let s=Object.values(t);return{provider:n,local:s.every(o=>o.local===!0),owner:s[0].owner,...s[0].name?{name:s[0].name}:{},...s[0].description?{description:s[0].description}:{},services:i}}function en(e,n,r){let t=e.catalog.providers[n],i=e.integrations?.services??{},s=[];if(t)for(let c of Object.values(t))c.services.includes(r)&&s.push({implementation:c.implementation,credentialType:c.credentialType});let o=i[r]?.provider,d=o&&typeof o=="object"&&o.provider===n?o:void 0;if(s.length===0&&!d)throw t?new M("SUPPLY_NOT_FOUND",404,`厂商 ${n} 未供给服务 ${r}(AI 帮我实现流:PUT 显式绑定后实施)`):new M("PROVIDER_NOT_FOUND",404,`厂商 ${n} 完全未知(不 ∈ catalog 且无任何内联声明)`);s.length===0&&d&&s.push({implementation:i[r]?.implementation??`${n}-inline@1`,credentialType:d.credentialType});let p=z(e,n,r,d?o?.configSchema:void 0);return{provider:n,service:r,implementations:s,integrationSchemas:{configSchema:p}}}function z(e,n,r,t){let i=e.walk.serviceSchemas[`${n}\0${r}`];return i?nn(e.appDir,i.packageDir,i.configSchema):typeof t=="string"?or(e.appDir,t):null}function nn(e,n,r){if(!r)return null;let t=tr(n,r);if(!qn(t))return null;try{return JSON.parse(Qn(t,"utf8"))}catch{return null}}function or(e,n){let r=Zn(e,"config","schemas"),t=Zn(e,n),i=rr(r,t);if(i===""||i.startsWith("..")||nr(i))throw new M("VALIDATION_FAILED",400,"configSchema 引用必须落在 config/schemas/ 内(禁路径逃逸)",["provider.configSchema"]);if(!qn(t))return null;let s,o;try{s=Yn(r),o=Yn(t)}catch{return null}if(o!==s&&!o.startsWith(s+ir))throw new M("VALIDATION_FAILED",400,"configSchema 引用经 symlink 逃逸出 config/schemas/(realpath 复核拒绝)",["provider.configSchema"]);try{return JSON.parse(Qn(t,"utf8"))}catch{return null}}function Xn(e){return{version:e.version,evaluation:e.evaluation,strictValidation:e.strictValidation,notes:[...e.notes]}}function et(e,n,r){let t=e.integrations,i=t?.services?.[n],s=i?.instances?.[r]??i?.instances?.["*"];if(s&&s.provider!==void 0)return"instance";if(i?.provider!==void 0)return"service";let o=e.walk.ownership[n];return o!==void 0&&L(e.integrations,o).layer==="module"?"module":typeof t?.provider=="string"&&t.provider.length>0?"app":null}function nt(e,n,r,t,i){let s=n.resolveEffectiveService(e.integrations,r,t,i);if(s.status==="ok"&&s.effective){let o=s.effective.provider,d=typeof o=="string"?o:String(o?.provider??"");return{status:"ok",provider:d,implementation:s.effective.implementation,effective:{provider:d,implementation:s.effective.implementation,...s.effective.config!==void 0?{config:{...s.effective.config}}:{},...s.effective.credentialRef!==void 0?{credentialRef:s.effective.credentialRef}:{},layer:et(e,r,t)??"app"}}}return s.status==="binding-unresolved"?{status:"binding-unresolved",statusMessage:s.message}:{status:s.status}}function tn(e){let n=e.contracts.module;if(!n.resolveEffectiveService||!n.normalizeInstances)throw new M("CONTRACTS_NOT_RESOLVED",503,"contracts 求值面缺席(契约包形态异常)——重新安装或升级应用 @tbox.cn/app-contracts 后重试");return n}function rn(e,n){let r=tn(n),{integrations:t,catalog:i}=n,s=r.buildSupplyLookup(i),o=t,p=r.normalizeInstances({instances:o?.instances,defaultInstanceId:o?.defaultInstanceId}).defaultInstanceId??"*",c=nt(n,r,e,p,s),f=et(n,e,p),k=n.integrations?.services?.[e]?.provider,w=c.provider??(typeof k=="string"?k:typeof k=="object"&&k?String(k.provider):void 0),y=new Set(Object.keys(n.catalog.providers)),A=w!==void 0&&y.has(w)?sr(n.catalog,w,e):void 0,O=i.services[e],g=O!==void 0?!O.optional:void 0,a=O?.owners[0];return{status:c.status,...c.statusMessage?{statusMessage:c.statusMessage}:{},...w!==void 0?{provider:w}:{},...w!==void 0&&f!==null?{layer:f}:{},...A!==void 0?{supplied:A}:{},...a!==void 0?{module:a}:{},...g!==void 0?{required:g}:{}}}function sr(e,n,r){return Ee(e,n,r)}function pe(e,n,r){let t=new Set([...e.walk.vocabulary,...Object.keys(e.catalog.services)]),i=e.integrations?.services??{};for(let o of Object.keys(i))t.add(o);let s={};for(let o of[...t].sort())r&&!r.includes(o)||(s[o]=rn(o,e));return{contracts:Xn(e.contracts),resolutions:s,issues:n}}function on(e,n,r){let t=tn(n),i=t.buildSupplyLookup(n.catalog),s=n.integrations,d=t.normalizeInstances({instances:s?.instances,defaultInstanceId:s?.defaultInstanceId}).instances.map(O=>O.id),p=n.integrations?.services?.[e],c=p?.instances?Object.keys(p.instances):void 0,f;d.length>0?(f=[...d],c?.includes("*")&&f.push("*")):c!==void 0&&c.length>0?f=c.includes("*")?["*"]:c:f=[];let k=f.map(O=>{let g=nt(n,t,e,O,i);return{instanceId:O,status:g.status,...g.statusMessage?{statusMessage:g.statusMessage}:{},...g.effective?{effective:g.effective}:{}}}),w=ar(n,e),A={...rn(e,n),instances:k,inheritance:w};return{contracts:Xn(n.contracts),resolution:A,issues:r.filter(O=>O.service===e)}}function ar(e,n){let r=e.integrations,t=r?.services?.[n],i=e.integrations,o=tn(e).normalizeInstances({instances:i?.instances,defaultInstanceId:i?.defaultInstanceId}).defaultInstanceId??"*",d=t?.instances?.[o]??t?.instances?.["*"],p=e.walk.ownership[n],c=p!==void 0?L(r,p):{provider:null,layer:null};return[{layer:"app",...r?.provider?{provider:r.provider}:{}},{layer:"module",...c.layer==="module"&&c.provider?{provider:c.provider}:{}},{layer:"service",...typeof t?.provider=="string"?{provider:t.provider}:{},...t?.implementation?{implementation:t.implementation}:{}},{layer:"instance",...d?.provider?{provider:d.provider}:{},...d?.implementation?{implementation:d.implementation}:{}}]}function sn(e,n,r){if(n===null)return null;let t={};for(let i of r)t[i]={configSchema:z(e,n,i)};return{provider:n,services:t}}function ie(e){return e===null||typeof e!="object"?JSON.stringify(e??null):Array.isArray(e)?`[${e.map(ie).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${ie(e[r])}`).join(",")}}`}var cr="\0no-enum";function dr(e){let n=e.enum;return Array.isArray(n)?`[${[...new Set(n.map(ie))].sort().join(",")}]`:cr}function lr(e){if(!e||typeof e!="object"||Array.isArray(e))return null;let n=e.type;return n===void 0?null:ie(n)}function ur(e){let n=e.map(t=>lr(t.subschema));if(n.some(t=>t===null)||new Set(n).size>1)return null;if(n[0]==='"object"'){let t=ie(e[0].subschema);return e.every(i=>ie(i.subschema)===t)?e[0].subschema:null}return new Set(e.map(t=>dr(t.subschema))).size===1?e[0].subschema:null}function Oe(e,n){let r=[],t=!0,i=new Map;for(let[o,d]of Object.entries(e.services)){let p=d.configSchema;if(p===null){r.push(o);continue}if(!p||typeof p!="object"||Array.isArray(p))continue;let c=p;c.additionalProperties===!1&&(t=!1);let f=c.properties;if(!f||typeof f!="object"||Array.isArray(f))continue;let k=Array.isArray(c.required)?c.required:[];for(let w of Object.keys(f)){let y=i.get(w)??[];y.push({service:o,subschema:f[w],required:k.includes(w)}),i.set(w,y)}}let s=[];for(let[o,d]of i)s.push({key:o,schema:ur(d),sources:d.map(({service:p,required:c})=>({service:p,required:c})),global:d.some(p=>!!p.subschema&&typeof p.subschema=="object"&&p.subschema["x-tbox-global"]===!0)});return{provider:e.provider,schemaless:r,unsupplied:[...n?.unsupplied??[]],additionalPropertiesAllowed:t,fields:s}}function an(e,n,r,t){let i=typeof t=="string"&&t.length>0?t:void 0;if(e==="app"){if(i!==void 0)return i;let d=n.integrations?.provider;return typeof d=="string"&&d.length>0?d:null}let s=n.walk.modules.find(d=>d.id===r);return!s||!J(n.walk,s).writable?null:i!==void 0?i:L(n.integrations,s.id).provider}var tt={integrationSchemas:null,integrationFieldRegistry:null};function rt(e){return{...e,fields:e.fields.filter(n=>n.global)}}function cn(e,n){let r=an("app",e,void 0,n);if(r===null)return tt;let t=sn(e,r,_e(e.catalog,r));return{integrationSchemas:t,integrationFieldRegistry:rt(Oe(t))}}function dn(e,n,r){let t=an("module",e,n,r),i=e.walk.modules.find(p=>p.id===n);if(t===null||!i)return tt;let s=(i.descriptor.declare.owns??[]).map(p=>p.service),o=p=>Ee(e.catalog,t,p),d=sn(e,t,s.filter(o));return{integrationSchemas:d,integrationFieldRegistry:rt(Oe(d,{unsupplied:[...new Set(s.filter(p=>!o(p)))]}))}}function pr(e){return cn(e).integrationSchemas}function fr(e,n){return dn(e,n).integrationSchemas}function gr(e,n){let r=e.walk.ownership[n];if(r!==void 0)return L(e.integrations,r).provider;let t=e.integrations?.provider;return typeof t=="string"&&t.length>0?t:null}function Me(e,n,r){let t=typeof r=="string"&&r.length>0?r:void 0;if(t!==void 0)return{provider:t,configSchema:z(e,t,n)};let i=e.integrations?.services?.[n]?.provider;if(i===void 0||i===""){let s=gr(e,n);return s===null?null:{provider:s,configSchema:z(e,s,n)}}if(typeof i=="string")return{provider:i,configSchema:z(e,i,n)};if(G(i)){let s=i;return{provider:s.provider,configSchema:z(e,s.provider,n,s.configSchema)}}return null}function ln(e,n,r){let t=Me(e,n,r);if(t===null)return null;let i={provider:t.provider,services:{[n]:{configSchema:t.configSchema}}};return Oe(i)}function fe(e,n){if(n===void 0||!n.startsWith("secret://"))return;let r=n.slice(9),t=se(e,r);if(t)return{type:t.type,ref:n,file:_(r),masked:ge(t.values)}}function un(e){let n=e.integrations,r={credential:fe(e.appDir,typeof n?.credentialRef=="string"?n.credentialRef:void 0)??null,byInstance:{}};for(let{id:i}of n?.instances??[]){let s=n?.credentialRefByInstance?.[i];s!==void 0&&(r.byInstance[i]=fe(e.appDir,s)??null)}let t={};for(let[i,s]of Object.entries(n?.services??{})){let o={credential:fe(e.appDir,s.credentialRef)??null,byInstance:{}};for(let[d,p]of Object.entries(s.instances??{}))o.byInstance[d]=fe(e.appDir,p.credentialRef)??null;t[i]=o}return{app:r,services:t}}function pn(e,n){return{types:(n===void 0?Object.keys(e.catalog.credentialTypes):[...new Set(Object.values(e.catalog.providers[n]??{}).map(t=>t.credentialType))]).sort().map(t=>{let i=e.catalog.credentialTypes[t];return{credentialType:t,owner:i?.owner??"",credentialSchema:i?nn(e.appDir,i.packageDir,i.credentialSchema):null}})}}import mr from"path";var vr={app:["serviceResolutions","integrationSchemas","integrationFieldRegistry"],module:["serviceResolutions","integrationSchemas","integrationFieldRegistry"],provider:["integrationSchemas"],service:["integrationSchemas","integrationFieldRegistry"]};function xe(e,n){if(!n||n.length===0)return new Set;let r=vr[e],t=[...new Set(n)].filter(i=>!r.includes(i));if(t.length>0)throw new M("VALIDATION_FAILED",400,`include 含未知或不适用于本端点的键:${t.join("、")}(白名单:${r.join("、")})`,["include"]);return new Set(n)}var it=["integrationSchemas","integrationFieldRegistry"];function fn(e,n,r){if(!(typeof n!="string"||n.length===0)&&!it.some(t=>r.has(t)))throw new M("VALIDATION_FAILED",400,`参数 ${e} 需与表单 include 键(${it.join("、")})同现——轴参仅重定向表单层双投影`,[e])}function yr(e,n={}){let r=je(),t=Promise.resolve(),i={appDir:e,cache:r};function s(g){if(!g.strictValidation)throw new M("CONTRACTS_NOT_RESOLVED",503,Pe(g));if(!g.ownershipBindingV6)throw new M("CONTRACTS_NOT_RESOLVED",503,`contracts ${g.version??"(版本未知)"} 不支持 v6 modules 绑定形状(OWNERSHIP_BINDING_V6 标记缺席)——升级应用 @tbox.cn/app-contracts 依赖后可用`)}function o(g){return zn(i,g)}function d(g){let a=g.integrations?.services;return a&&typeof a=="object"?Object.keys(a):[]}async function p(){let g=await T(e),a=o(g),m=a.integrations;if(m===null)return[];let R={resolveEffectiveService:c(g.module.resolveEffectiveService,"resolveEffectiveService"),buildSupplyLookup:c(g.module.buildSupplyLookup,"buildSupplyLookup"),normalizeInstances:c(g.module.normalizeInstances,"normalizeInstances"),RESOURCE_TYPE_IDS:g.module.RESOURCE_TYPE_IDS??[]},S=ce(e,a.walk,m,process.env);return ee({contracts:R,integrations:m,supplies:R.buildSupplyLookup(a.catalog),...S})}function c(g,a){if(typeof g!="function")throw new M("CONTRACTS_NOT_RESOLVED",503,`contracts 求值面 ${a} 缺席(形态异常)`);return g}function f(g){let a=t.then(g,g);return t=a.catch(()=>{}),a}let k={async loadModules(g){let a=await T(e);return He(o(a),g)},async loadModule(g,a){let m=xe("module",a?.include);fn("moduleProvider",a?.moduleProvider,m);let R=await T(e),S=o(R),u=ke(S.walk,g),v=Ye(S,u.id);if(m.has("serviceResolutions")&&(v.serviceResolutions=R.evaluation&&R.strictValidation?await p().then(b=>pe(S,b,v.services.map(l=>l.service))):null),m.has("integrationSchemas")||m.has("integrationFieldRegistry")){let b=dn(S,u.id,a?.moduleProvider);m.has("integrationSchemas")&&(v.integrationSchemas=b.integrationSchemas),m.has("integrationFieldRegistry")&&(v.integrationFieldRegistry=b.integrationFieldRegistry)}return v},async loadApp(g){let a=xe("app",g?.include);fn("appProvider",g?.appProvider,a);let m=await T(e),R=o(m),S=Ze(R);if(a.has("serviceResolutions")&&(S.serviceResolutions=m.evaluation&&m.strictValidation?await p().then(u=>pe(R,u)):null),a.has("integrationSchemas")||a.has("integrationFieldRegistry")){let u=cn(R,g?.appProvider);a.has("integrationSchemas")&&(S.integrationSchemas=u.integrationSchemas),a.has("integrationFieldRegistry")&&(S.integrationFieldRegistry=u.integrationFieldRegistry)}return S},async loadService(g,a){let m=xe("service",a?.include);fn("serviceProvider",a?.serviceProvider,m);let R=await T(e),S=o(R),u=H(S.walk,d(S),g),v=qe(S,u);return m.has("integrationSchemas")&&(v.integrationSchemas=Me(S,u,a?.serviceProvider)),m.has("integrationFieldRegistry")&&(v.integrationFieldRegistry=ln(S,u,a?.serviceProvider)),v},async loadServiceResolutions(g){let a=await T(e);s(a);let m=await p();return pe(o(a),m,g)},async loadServiceResolution(g){let a=await T(e);s(a);let m=o(a),R=H(m.walk,d(m),g),S=await p();return on(R,m,S)},async loadProviders(){let g=await T(e);return Qe(o(g))},async loadProvider(g,a){let m=xe("provider",a?.include),R=await T(e);return Xe(o(R),g,m)},async loadProviderService(g,a){let m=await T(e),R=o(m),S=H(R.walk,d(R),a);return en(R,g,S)},async loadCredentials(){let g=await T(e);return un(o(g))},async loadCredentialTypes(g){let a=await T(e);return pn(o(a),g)}},w=Je(e,{onApplied:n.onApplied,cache:r}),y={async writeAppIntegration(g,a){await w.warmup();let m=await T(e);return s(m),f(()=>w.applyApp(g,a))},async writeModuleIntegration(g,a,m){await w.warmup();let R=await T(e);return s(R),f(()=>{let S=ke(o(R).walk,g);return w.applyModule(S.id,a,m)})},async writeServiceIntegration(g,a,m){await w.warmup();let R=await T(e);return s(R),f(()=>{let S=o(R),u=H(S.walk,d(S),g);return w.applyService(u,a,m)})},async deleteServiceIntegration(g){await w.warmup();let a=await T(e);return s(a),f(()=>{let m=o(a),R=H(m.walk,d(m),g);return w.deleteService(R)})}},A={invalidate(){r.invalidate(),Te(e)},async resolveContracts(){return T(e)},walkManifests(){return O(e)},parseModuleDescriptor(g){return oe(g)},loadProviderCatalogRaw(){return We(e)},async readIntegrationsConfig(){return B(e,r)},async writeIntegrationsConfig(g){await w.warmup();let a=await T(e);return s(a),f(()=>Sr(e,g,r))},async ensureMockBindings(){await w.warmup();let g=await T(e);return s(g),f(()=>Ge(e))},async evaluateIntegrationServices(g){await w.warmup();let a=await T(e);s(a);let m={resolveEffectiveService:c(a.module.resolveEffectiveService,"resolveEffectiveService"),buildSupplyLookup:c(a.module.buildSupplyLookup,"buildSupplyLookup"),normalizeInstances:c(a.module.normalizeInstances,"normalizeInstances"),RESOURCE_TYPE_IDS:a.module.RESOURCE_TYPE_IDS??[]};return ee({...g,contracts:m})}};function O(g){return V(g,r)}return{...k,...y,...A}}function Sr(e,n,r){let t=mr.join(e,"config","integrations.json");$(t,`${JSON.stringify(n,null,2)}
|
|
9
|
+
`),r.invalidate([t])}export{le as APP_INTEGRATION_NODE_KEYS,M as AppToolkitError,ue as MODULE_INTEGRATION_NODE_KEYS,K as SAFE_NAME_PATTERN,Ct as assertValidModuleId,Oe as buildIntegrationFieldRegistry,jt as buildOwnershipMap,ce as buildPredicateAssembly,$e as checkInstanceKeys,xt as collectDeclaredModules,Pe as contractsNotResolvedMessage,yr as createAppToolkit,je as createFileCache,Je as createWriteCore,Lt as credentialArtifactExists,re as deepEqual,Q as deriveStem,fe as echoForRef,Cn as ensureDir,Ge as ensureMockBindings,Be as evaluateAppIntegrationIssues,ee as evaluateIntegrationServices,Ne as expandEnvVars,Tn as extractModuleIdFromSource,an as formProviderOf,Te as invalidateContractsResolver,G as isControlledInlineProvider,Mn as isValidModuleId,pr as loadAppIntegrationSchemas,Ze as loadAppView,pn as loadCredentialTypesView,un as loadCredentialsView,Ye as loadModuleDetailView,fr as loadModuleIntegrationSchemas,He as loadModulesView,we as loadProviderCatalog,We as loadProviderCatalogRaw,Xe as loadProviderDetailView,en as loadProviderServiceDetailView,Qe as loadProvidersView,qe as loadServiceDetailView,ln as loadServiceFieldRegistry,Me as loadServiceIntegrationSchemas,on as loadServiceResolutionDetail,pe as loadServiceResolutionsView,ve as manifestPath,ge as maskCredentialValues,vn as moduleDependencySchema,Rn as moduleDescriptorSchema,J as moduleOwnershipWritable,gn as pageContribSchema,oe as parseModuleDescriptor,_e as providerFootprint,yn as providerSlotContribSchema,zt as pruneIntegrationBindings,On as readAppManifest,De as readAppManifestFull,se as readCredentialFile,B as readIntegrationsConfig,Fn as readIntegrationsStrict,ne as reconcileOrphanCredentials,Vn as refToEnvKey,It as removeNpmModule,T as resolveContractsForApp,T as resolveContractsForAppExport,sn as resolveLayerIntegrationSchemas,L as resolveModuleBinding,ke as resolveModuleKey,H as resolveServiceKey,rn as resolveServiceSummary,hn as resourceNeedContribSchema,Sn as serviceConsumeContribSchema,wn as serviceOwnContribSchema,_ as stemToFilePath,pt as stemToRef,mn as tabContribSchema,bt as updateNpmModule,kt as upsertMiniappContainer,Rt as upsertNpmModule,V as walkManifests,ht as writeAppManifest,$ as writeAtomic,Ve as writeCredentialFile};
|
package/package.json
CHANGED
|
@@ -104,6 +104,9 @@ export const moduleDescriptorSchema = z
|
|
|
104
104
|
id: z.string(),
|
|
105
105
|
name: z.string().optional(),
|
|
106
106
|
description: z.string().optional(),
|
|
107
|
+
// 隐藏模块(展示元数据轴,与 name/description 同层):仅影响 toolkit GET /modules 清单默认过滤
|
|
108
|
+
// (?includeHidden=true 可见);detail 端点/装配/doctor/predicate 零影响
|
|
109
|
+
hidden: z.boolean().optional(),
|
|
107
110
|
version: z.string().default('0.0.0'),
|
|
108
111
|
kind: z.enum(['platform', 'business', 'third-party']).default('business'),
|
|
109
112
|
risk: z
|