@tbox.cn/app-toolkit 0.2.0 → 0.3.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 CHANGED
@@ -1268,6 +1268,12 @@ interface NpmModuleEntry {
1268
1268
  mode: ModuleMode;
1269
1269
  /** 3-way merge 基线(codegen 模式) */
1270
1270
  baseVersion?: string;
1271
+ /**
1272
+ * 条目类别(单一模板统一化 W2-4):'ui-kit' = 壳 UI 组件包——create 全量继承后
1273
+ * 不再承担保留判据(模板 manifest = 出厂装配真源);现职 = update 三方合并锚 +
1274
+ * sync-agent-ui-kit 副本 identity 标记(由该脚本派生维护)。
1275
+ */
1276
+ kind?: 'ui-kit';
1271
1277
  }
1272
1278
  interface AppManifest {
1273
1279
  templateVersion: string;
@@ -1429,8 +1435,9 @@ declare function reconcileOrphanCredentials(appDir: string): OrphanIssue[];
1429
1435
  * 7 严格整文档校验(contracts parseIntegrationsConfig——触发 = !noDiff ∥ 有凭据输入)
1430
1436
  * 8 凭据工件落盘(**后置于校验通过**——防「凭据已写 + zod 拒绝」不一致态;
1431
1437
  * dryRun → writeCredentialArtifacts 零写盘 + existsSync 预览)
1432
- * 9 finalize:written = integrations 实写 凭据实写(**D-B2**);files 分列两类路径;
1433
- * restartScheduled = written && onApplied(凭据影响 boot 装配——重启正当);写后缓存失效
1438
+ * 9 finalize(D35):planned = 将触碰(files 预览单源——dryRun 响应 ≡ 同 body 真实写,files 逐字对称);
1439
+ * written = 实写(!dryRun 派生,D-B2);restartScheduled = written && onApplied(凭据影响 boot 装配——
1440
+ * 重启正当);写后缓存失效
1434
1441
  * 归一化:N1 模块节点 {} → 删 domains[键];N3 服务节点 {} 不归一化(显式通配激活 = 合法 TIER0 态);
1435
1442
  * N2 已随 ?instance= 退役。dryRun(PUT only):复读完整管线不落盘不排程。
1436
1443
  * DELETE:节点移除 + 孤儿凭据写后对账(覆盖 DELETE 与 PUT 替换两类来源,只报告不清理——D9)。
@@ -1521,7 +1528,7 @@ declare function contractsNotResolvedMessage(contracts: {
1521
1528
  }): string;
1522
1529
 
1523
1530
  /**
1524
- * DTO 全量(api.md §3 字段级单源落源——28 类型;演进 additive-only,铁律 #8)。
1531
+ * DTO 全量(api.md §3 字段级单源落源——36 类型;演进 additive-only,铁律 #8)。
1525
1532
  * agtcodingbox / tbox-ai-coding 经 `import type` 消费(L2 DTO 单源——API 层零类型镜像)。
1526
1533
  * 词汇七概念:app / module / service / instance / provider / integration / resolution。
1527
1534
  * 弃用词汇清单见 api.md §3 尾(component/slot/scope/configMode/…——防复活)。
@@ -1530,12 +1537,14 @@ declare function contractsNotResolvedMessage(contracts: {
1530
1537
  type ServiceStatus = 'ok' | 'service-not-configured' | 'instance-not-found' | 'instance-disabled' | 'binding-unresolved';
1531
1538
  /** 四配置层(instance 为 map 字段层) */
1532
1539
  type BindingLayer = 'app' | 'module' | 'service' | 'instance';
1533
- /** 纯模块清单(无 services——卡片展开走 /modules/:m */
1540
+ /** 纯模块清单(无 services——卡片展开走 /modules/:m);provider 家族包不在清单
1541
+ * (供给/实施载体非可配置业务模块——供给轴归 /providers;判定 = install id / 包名
1542
+ * basename 去 scope 后 `provider-` 前缀;已装 provider 详情 GET /modules/:m 仍 200) */
1534
1543
  interface ModulesView {
1535
1544
  modules: ModuleDeclaration[];
1536
1545
  }
1537
1546
  interface ModuleDeclaration {
1538
- /** install id(packages/ 目录名 / .tbox/app.json entry.id */
1547
+ /** install id(packages/ 目录名 / .tbox/app.json entry.id)——恒业务模块(provider 家族不在本清单) */
1539
1548
  id: string;
1540
1549
  /** 包名 */
1541
1550
  name: string;
@@ -1567,6 +1576,9 @@ interface ModuleDetailView {
1567
1576
  serviceResolutions?: ServiceResolutionsView | null;
1568
1577
  /** v4.4 D32:include=integrationSchemas 层级富化(多域/零域/共享键/未绑定 → null) */
1569
1578
  integrationSchemas?: LayerIntegrationSchemas | null;
1579
+ /** v4.6 D36:include=integrationFieldRegistry 集成字段注册表(null 语义镜像 integrationSchemas;
1580
+ * 未知厂商/零足迹 → 非 null 空集 + unsupplied 回填——D37 轴参假想计算同此) */
1581
+ integrationFieldRegistry?: IntegrationFieldRegistryView | null;
1570
1582
  }
1571
1583
  /** 模块域厂商绑定解析(v4.4 D34——静态文件事实;规则 ≡ 谓词 #7 域级,resolveDomainBinding 单源) */
1572
1584
  interface ProviderBinding {
@@ -1586,6 +1598,29 @@ interface LayerIntegrationSchemas {
1586
1598
  configSchema: object | null;
1587
1599
  }>;
1588
1600
  }
1601
+ /** v4.6 D36:集成字段注册表(层级表单服务端预计算——合并代数 R1/R2/R3 服务端单源;
1602
+ * 消费 resolveLayerIntegrationSchemas 产物构造,禁旁路直取 serviceSchemas) */
1603
+ interface IntegrationFieldRegistryView {
1604
+ /** echo:本注册表计算口径(假想时 = 轴参值——D37) */
1605
+ provider: string;
1606
+ /** 作用域内 configSchema === null 的服务(UI「未提供参数模板」提示行) */
1607
+ schemaless: string[];
1608
+ /** module 轴 = demand − 该厂商供给(Set 去重保序);app 轴恒 [](结构性:足迹 ⊆ 供给) */
1609
+ unsupplied: string[];
1610
+ /** 作用域内全部非 null schema 的 additionalProperties 均 ≠ false(聚合;空真) */
1611
+ additionalPropertiesAllowed: boolean;
1612
+ /** 逐 key 合并产物(首声明插入序 = scope 遍历序:app 字母序 / module demand 序) */
1613
+ fields: Array<{
1614
+ key: string;
1615
+ /** null = 类型不可调和(R3/R2 异构/R1 enum 不等——冲突折叠,客户端 RawJson 保真) */
1616
+ schema: object | null;
1617
+ /** required 聚合 = sources.some(s => s.required);conflict 字段照常聚合 */
1618
+ sources: Array<{
1619
+ service: string;
1620
+ required: boolean;
1621
+ }>;
1622
+ }>;
1623
+ }
1589
1624
  /** GET /app(应用静态视图:平台服务 + root 原值) */
1590
1625
  interface AppView {
1591
1626
  /** 平台服务(v4.4 D29:服务词汇 − 模块占用——与模块 demand 同型 ServiceDemand[];
@@ -1597,6 +1632,9 @@ interface AppView {
1597
1632
  serviceResolutions?: ServiceResolutionsView | null;
1598
1633
  /** v4.4 D32:include=integrationSchemas 层级富化(root.provider 缺席 → null) */
1599
1634
  integrationSchemas?: LayerIntegrationSchemas | null;
1635
+ /** v4.6 D36:include=integrationFieldRegistry 集成字段注册表(root.provider 缺席且无轴参 → null;
1636
+ * 未知厂商/零足迹 → 非 null 空集——D37 轴参假想计算同此) */
1637
+ integrationFieldRegistry?: IntegrationFieldRegistryView | null;
1600
1638
  }
1601
1639
  /** GET /services/:service(服务静态单体) */
1602
1640
  interface ServiceDetail extends ServiceDemand {
@@ -1609,6 +1647,17 @@ interface ServiceDetail extends ServiceDemand {
1609
1647
  integration: ServiceIntegrationNode | null;
1610
1648
  /** 供给该服务的厂商名单(catalog 静态切片——picker 数据源) */
1611
1649
  suppliedBy: string[];
1650
+ /** v4.7 D38:include=integrationSchemas 生效绑定富化(三态:null 全链未绑定 /
1651
+ * 绑定无可计算 schema / 含 schema;malformed 节点 → null——不放行域级联) */
1652
+ integrationSchemas?: ServiceIntegrationSchemas | null;
1653
+ }
1654
+ /** 服务级生效绑定 schema(v4.7 D38 静态轴富化——零 contracts,永不 503;实例层无条件排除:
1655
+ * node 级口径 ≠ resolution 默认实例口径,api.md §4.4 注) */
1656
+ interface ServiceIntegrationSchemas {
1657
+ /** 生效厂商:显式(含内联声明名)?? domains[首段].provider ?? root.provider */
1658
+ provider: string;
1659
+ /** catalog 复合键(多 impl 声明序首个)> 内联 ref;miss(未知厂商/未供给/内联缺 ref)→ null(富化非门控) */
1660
+ configSchema: object | null;
1612
1661
  }
1613
1662
  /** GET /service-resolutions(批量求值 · 唯一求值集合面) */
1614
1663
  interface ServiceResolutionsView {
@@ -1840,14 +1889,7 @@ interface ViewSnapshot {
1840
1889
  contracts: ResolvedContracts;
1841
1890
  }
1842
1891
 
1843
- /**
1844
- * 需求轴/模块静态投影(views/modules;C4)。静态端点结构性零求值(铁律 #3——
1845
- * 无 resolution/issues/contracts 键,永不 503)。
1846
- * v4.4 D34:domainKeys/providerBindings/configEditable 显式化;integration 仅单域
1847
- * (writable)时在场——多域/零域/共享键无单键落点;多域回退兜底键机器拆除
1848
- * (派生统一 = domainOfService 去重集合,moduleDomainWritable 单源)。
1849
- */
1850
- /** GET /modules:纯模块清单(demand 不在——卡片展开 = GET /modules/:m) */
1892
+ /** GET /modules:纯模块清单(demand 不在——卡片展开 = GET /modules/:m;provider 家族包不在清单) */
1851
1893
  declare function loadModulesView(snapshot: ViewSnapshot): {
1852
1894
  modules: ModuleDeclaration[];
1853
1895
  };
@@ -1893,24 +1935,40 @@ declare function loadServiceResolutionsView(snapshot: ViewSnapshot, issues: Inte
1893
1935
  declare function loadServiceResolutionDetail(service: string, snapshot: ViewSnapshot, allIssues: IntegrationIssue[]): ServiceResolutionDetail;
1894
1936
 
1895
1937
  /**
1896
- * 层级 config schema 计算视图(v4.4 D32——静态轴富化,零 contracts 求值)。
1897
- * config 表单结构三形态同源(P10):槽级组合单体(providers.ts)/ 层级内嵌(本文件——
1898
- * /app、/modules/:m include)/ 供给轴批量(providers.ts include——切换态)。
1938
+ * 层级/服务级 config schema 计算视图(v4.4 D32——静态轴富化,零 contracts 求值;v4.7 D38 服务级)。
1939
+ * config 表单结构四形态同源(P10):槽级组合单体(providers.ts)/ 层级内嵌(本文件——
1940
+ * /app、/modules/:m include)/ 供给轴批量(providers.ts include——切换态)/ 服务级生效绑定
1941
+ * (本文件 loadServiceIntegrationSchemas——/services/:s include)。
1899
1942
  *
1900
1943
  * 计算规则(D32 裁决):禁交集——config 五层浅合并下「部分服务认识的字段」合法(谓词 #7
1901
1944
  * 并集键集同依据);禁合成单一 schema——required/title 冲突的有损代数;产物 = 扁平映射,
1902
1945
  * 分组归客户端纯呈现。层级 schema = 表单引导**非写入门禁**(P16——写路径校验权威恒在谓词
1903
1946
  * #7 键集 + ajv 凭据链;root 级口径差:#7 = 引用厂商并集,表单 = 层生效厂商单厂商作用域)。
1947
+ *
1948
+ * v4.6(D36/D37 additive 精化):**原始投影**(loadApp/loadModuleIntegrationSchemas)原样保留
1949
+ * 为诊断面 / registry 输入;**消费投影** = buildIntegrationFieldRegistry(字段级合并代数
1950
+ * R1/R2/R3 服务端单源,conflict 折叠 schema:null);**轴向假想绑定** = formProviderOf
1951
+ * (override ?? 实际解析——双投影同源同口径,formViews 装配层一次计算两投影)。
1952
+ * 单源三锚:层级 schema 计算 = resolveLayerIntegrationSchemas / 生效厂商解析 = formProviderOf /
1953
+ * 合并代数 = buildIntegrationFieldRegistry。
1904
1954
  */
1905
- /** 核心纯函数:显式作用域(provider null → 整字段 null;services 逐项 serviceSchemas 复合键 +
1906
- * readSchemaRef——既有解析路径零新读;供给在场未声明 = null,mock 合法) */
1955
+ /** 核心纯函数:显式作用域(provider null → 整字段 null;services 逐项 resolveServiceConfigSchema
1956
+ * 复合解析——v4.7 D38 收口,零新读取路径;供给在场未声明 = null,mock 合法) */
1957
+ declare function resolveLayerIntegrationSchemas(snapshot: ViewSnapshot, provider: string, services: readonly string[]): LayerIntegrationSchemas;
1907
1958
  declare function resolveLayerIntegrationSchemas(snapshot: ViewSnapshot, provider: string | null, services: readonly string[]): LayerIntegrationSchemas | null;
1908
- /** app 级 loader:生效厂商 = root.provider(非空字符串,缺席 整字段 null——D32「未绑定」);
1909
- * 作用域 = 该厂商供给足迹全量(≠ AppView.services——root.config 流向包括模块服务在内的所有服务) */
1959
+ /** app 级 loader(v4.6 委托化——签名零改动,公开面保持;假想态归 loadAppFormViews override 参) */
1910
1960
  declare function loadAppIntegrationSchemas(snapshot: ViewSnapshot): LayerIntegrationSchemas | null;
1911
- /** module 级 loader:仅 writable 单域;生效厂商 = resolveDomainBinding(D32/R4 单源);
1912
- * 作用域 = demand ∩ 该厂商供给;多域/零域/共享键/未绑定 → 整字段 null(表单降级 = ExtraFields) */
1961
+ /** module 级 loader(v4.6 委托化——同上;多域/零域/共享键/未绑定 整字段 null,表单降级 = ExtraFields) */
1913
1962
  declare function loadModuleIntegrationSchemas(snapshot: ViewSnapshot, moduleId: string): LayerIntegrationSchemas | null;
1963
+ /** 服务级 loader(v4.7 D38):四分支穷举(node.provider = 文件 services[s].provider 逐字原值;
1964
+ * 实例层无条件排除——node 级口径);非空三分支归约一次复合解析。
1965
+ * ① undefined/'' → resolveDomainBinding 域级联(域 + root 双缺 → 整字段 null)
1966
+ * ② 非空 string → bare:catalog miss(未知厂商/未供给)→ configSchema:null 不 404(富化非门控)
1967
+ * ③ 受控内联(isControlledInlineProvider 单源)→ 名 = p.provider;catalog 复合键 > p.configSchema ref
1968
+ * (H9 逃逸 400 照抛——readInlineSchema 共享路径)
1969
+ * ④ 其余(null/数组/原始值/坏对象)→ 整字段 null(≡ 谓词 #5 INLINE_PROVIDER_INVALID 同判——
1970
+ * 不放行域级联,防错误 schema 污染坏节点) */
1971
+ declare function loadServiceIntegrationSchemas(snapshot: ViewSnapshot, service: string): ServiceIntegrationSchemas | null;
1914
1972
 
1915
1973
  /**
1916
1974
  * 凭据状态轴投影(views/credentials;v4.4 D33 独立端点 GET /credentials):
@@ -1940,7 +1998,9 @@ declare function loadCredentialTypesView(snapshot: ViewSnapshot, provider?: stri
1940
1998
 
1941
1999
  /**
1942
2000
  * createAppToolkit(C4 工厂;v4.4——24 方法 = 11 读(含 credentials/credential-types 双端点)
1943
- * + 4 写 + 9 迁移面;loadApp/loadModule/loadProvider 增 include 选项)。
2001
+ * + 4 写 + 9 迁移面;loadApp/loadModule/loadProvider 增 include 选项;v4.6——loadApp/loadModule
2002
+ * += 轴向假想绑定选项(appProvider/moduleProvider,D37);表单双投影经 formViews 单点装配;
2003
+ * v4.7——loadService 增 include 选项(服务级生效绑定 schema 单体))。
1944
2004
  * AppToolkit = AppToolkitRead & AppToolkitWrite & AppToolkitInternals——
1945
2005
  * Read+Write = HTTP 直通面 additive 冻结(L1 端点↔方法 1:1,L3 命名镜像:Integration=节点级 /
1946
2006
  * Config=文件级);Internals = CLI/doctor/桥消费(自由演进)。
@@ -1962,13 +2022,19 @@ interface AppToolkitOptions {
1962
2022
  /** ── HTTP 直通面(11 读;L1 镜像律:方法名 = load + URL 资源段;query → 选项字段 L4)── */
1963
2023
  interface AppToolkitRead {
1964
2024
  loadModules(): Promise<ModulesView>;
2025
+ /** v4.6 D37:moduleProvider = 轴向假想绑定(缺席/空串 ≡ 按实际配置解析;需与表单 include 键同现) */
1965
2026
  loadModule(moduleId: string, o?: {
1966
2027
  include?: string[];
2028
+ moduleProvider?: string;
1967
2029
  }): Promise<ModuleDetailView>;
2030
+ /** v4.6 D37:appProvider = 轴向假想绑定(缺席/空串 ≡ 按实际配置解析;需与表单 include 键同现) */
1968
2031
  loadApp(o?: {
1969
2032
  include?: string[];
2033
+ appProvider?: string;
1970
2034
  }): Promise<AppView>;
1971
- loadService(service: string): Promise<ServiceDetail>;
2035
+ loadService(service: string, o?: {
2036
+ include?: string[];
2037
+ }): Promise<ServiceDetail>;
1972
2038
  loadServiceResolutions(services?: string[]): Promise<ServiceResolutionsView>;
1973
2039
  loadServiceResolution(service: string): Promise<ServiceResolutionDetail>;
1974
2040
  loadProviders(): Promise<ProvidersView>;
@@ -2031,4 +2097,4 @@ interface AppToolkitInternals {
2031
2097
  type AppToolkit = AppToolkitRead & AppToolkitWrite & AppToolkitInternals;
2032
2098
  declare function createAppToolkit(appDir: string, options?: AppToolkitOptions): AppToolkit;
2033
2099
 
2034
- 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 DeclaredModuleInfo, type EffectiveBinding, type EnvExpansionResult, type EvaluationExports, type FileCache, type InlineVendorDeclaration, type IntegrationIssue, type IntegrationServiceIssue, type IntegrationServicePredicateInput, type LayerIntegrationSchemas, type MiniappContainerEntry, type MockBindingsResult, type ModuleDeclaration, type ModuleDescriptor, type ModuleDetailView, type ModuleIntegrationNode, type ModuleMode, type ModulesView, type NpmModuleEntry, type OrphanIssue, type ParseModuleResult, type PlannedCredential, type PredicateAssembly, type PredicateContracts, type PredicateIoInputs, type ProviderBinding, type ProviderDetail, type ProviderEntry, type ProviderServiceDetail, type ProviderServiceSchemas, type ProviderServiceSchemasResult, type ProviderSlotContrib, type ProvidersView, type ReadIntegrationsResult, type ResolvedContracts, type ResolvedInstance, type ResolvedModule, type ResourceNeedContrib, SAFE_NAME_PATTERN, type SaveResult, type ServiceDemand, type ServiceDetail, type ServiceInstanceNode, type ServiceIntegrationNode, type ServiceNeedContrib, type ServiceResolution, type ServiceResolutionDetail, type ServiceResolutionEntry, type ServiceResolutionsView, type ServiceStatus, type StemInput, type SupplyLookup, type ViewContext, type ViewSnapshot, type WalkCatalog, type WalkManifestsResult, type WalkModuleInfo, type WalkProviderEntry, type WriteCore, type WriteCoreOptions, type WriteOptions, assertValidModuleId, buildPredicateAssembly, checkInstanceKeys, collectDeclaredModules, contractsNotResolvedMessage, createAppToolkit, createFileCache, createWriteCore, credentialArtifactExists, deepEqual, deriveStem, echoForRef, ensureDir, ensureMockBindings, evaluateIntegrationServices, expandEnvVars, extractModuleIdFromSource, invalidateContractsResolver, isControlledInlineProvider, isValidModuleId, loadAppIntegrationSchemas, loadAppView, loadCredentialTypesView, loadCredentialsView, loadModuleDetailView, loadModuleIntegrationSchemas, loadModulesView, loadProviderCatalog, loadProviderCatalogRaw, loadProviderDetailView, loadProviderServiceDetailView, loadProvidersView, loadServiceDetailView, loadServiceResolutionDetail, loadServiceResolutionsView, manifestPath, maskCredentialValues, moduleDependencySchema, moduleDescriptorSchema, pageContribSchema, parseModuleDescriptor, providerSlotContribSchema, readAppManifest, readAppManifestFull, readCredentialFile, readIntegrationsConfig, readIntegrationsStrict, reconcileOrphanCredentials, refToEnvKey, removeNpmModule, resolveContractsForApp, resolveContractsForApp as resolveContractsForAppExport, resolveLayerIntegrationSchemas, resolveServiceSummary, resourceNeedContribSchema, serviceNeedContribSchema, stemToFilePath, stemToRef, tabContribSchema, updateNpmModule, upsertMiniappContainer, upsertNpmModule, walkManifests, writeAppManifest, writeAtomic, writeCredentialFile };
2100
+ 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 DeclaredModuleInfo, type EffectiveBinding, type EnvExpansionResult, type EvaluationExports, type FileCache, type InlineVendorDeclaration, type IntegrationFieldRegistryView, type IntegrationIssue, type IntegrationServiceIssue, type IntegrationServicePredicateInput, type LayerIntegrationSchemas, type MiniappContainerEntry, type MockBindingsResult, type ModuleDeclaration, type ModuleDescriptor, type ModuleDetailView, type ModuleIntegrationNode, type ModuleMode, type ModulesView, type NpmModuleEntry, type OrphanIssue, type ParseModuleResult, type PlannedCredential, type PredicateAssembly, type PredicateContracts, type PredicateIoInputs, type ProviderBinding, type ProviderDetail, type ProviderEntry, type ProviderServiceDetail, type ProviderServiceSchemas, type ProviderServiceSchemasResult, type ProviderSlotContrib, type ProvidersView, type ReadIntegrationsResult, type ResolvedContracts, type ResolvedInstance, type ResolvedModule, type ResourceNeedContrib, SAFE_NAME_PATTERN, type SaveResult, type ServiceDemand, type ServiceDetail, type ServiceInstanceNode, type ServiceIntegrationNode, type ServiceIntegrationSchemas, type ServiceNeedContrib, type ServiceResolution, type ServiceResolutionDetail, type ServiceResolutionEntry, type ServiceResolutionsView, type ServiceStatus, type StemInput, type SupplyLookup, type ViewContext, type ViewSnapshot, type WalkCatalog, type WalkManifestsResult, type WalkModuleInfo, type WalkProviderEntry, type WriteCore, type WriteCoreOptions, type WriteOptions, assertValidModuleId, buildPredicateAssembly, checkInstanceKeys, collectDeclaredModules, contractsNotResolvedMessage, createAppToolkit, createFileCache, createWriteCore, credentialArtifactExists, deepEqual, deriveStem, echoForRef, ensureDir, ensureMockBindings, evaluateIntegrationServices, expandEnvVars, extractModuleIdFromSource, invalidateContractsResolver, isControlledInlineProvider, isValidModuleId, loadAppIntegrationSchemas, loadAppView, loadCredentialTypesView, loadCredentialsView, loadModuleDetailView, loadModuleIntegrationSchemas, loadModulesView, loadProviderCatalog, loadProviderCatalogRaw, loadProviderDetailView, loadProviderServiceDetailView, loadProvidersView, loadServiceDetailView, loadServiceIntegrationSchemas, loadServiceResolutionDetail, loadServiceResolutionsView, manifestPath, maskCredentialValues, moduleDependencySchema, moduleDescriptorSchema, pageContribSchema, parseModuleDescriptor, providerSlotContribSchema, readAppManifest, readAppManifestFull, readCredentialFile, readIntegrationsConfig, readIntegrationsStrict, reconcileOrphanCredentials, refToEnvKey, removeNpmModule, resolveContractsForApp, resolveContractsForApp as resolveContractsForAppExport, resolveLayerIntegrationSchemas, resolveServiceSummary, resourceNeedContribSchema, serviceNeedContribSchema, stemToFilePath, stemToRef, tabContribSchema, updateNpmModule, upsertMiniappContainer, upsertNpmModule, walkManifests, writeAppManifest, writeAtomic, writeCredentialFile };
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
- import{a as me,b as T,c as ve}from"./chunk-KPD3LUH4.js";import{z as h}from"zod";var L=/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/,Dn=h.object({cardType:h.string(),schemaVersion:h.number().optional()}),He=h.object({route:h.string(),component:h.string()}),Ze=h.object({route:h.string(),label:h.string().optional(),icon:h.string().optional(),order:h.number().optional()}),Ge=h.object({id:h.string(),range:h.string().optional(),required:h.boolean().default(!0)}),qe=h.object({service:h.string(),provider:h.string().regex(L,"provider 名含非法字符(需 /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/)"),implementation:h.string(),credentialType:h.string(),local:h.boolean().optional(),configSchema:h.string().optional(),credentialSchema:h.string().optional()}),Qe=h.object({service:h.string(),optional:h.boolean().default(!0),defaults:h.array(h.object({provider:h.string().regex(L,"provider 名含非法字符(需 /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/)"),implementation:h.string()})).default([]),title:h.string().optional(),description:h.string().optional()}),Xe=h.object({id:h.string(),type:h.string()}),en=h.object({schemaVersion:h.number().default(1),name:h.string(),version:h.string().default("0.0.0"),kind:h.enum(["platform","business","third-party"]).default("business"),risk:h.object({level:h.enum(["high","medium","low"]).default("low"),writeBoundary:h.enum(["sdk-enforced","source"]).default("source")}).default({}),distribution:h.object({defaultMode:h.enum(["hybrid","sdk","codegen","local"]).default("codegen")}).default({}),contributes:h.object({handlers:h.array(h.string()).default([]),tools:h.array(h.string()).default([]),cards:h.array(Dn).default([]),routes:h.array(h.string()).default([]),pages:h.array(He).default([]),tabs:h.array(Ze).default([]),providers:h.object({slots:h.array(qe).default([])}).default({}),services:h.array(Qe).default([]),resources:h.array(Xe).default([])}).default({}),dependencies:h.object({modules:h.array(Ge).default([])}).default({}),env:h.array(h.string()).default([])}).strict();function G(e){let n=en.safeParse(e);return n.success?{ok:!0,value:n.data}:{ok:!1,errors:n.error.issues.map(r=>`${r.path.join(".")||"(root)"}: ${r.message}`)}}var Vn=/\$\$?\{([A-Z][A-Z0-9_]*)\}/g;function $n(e){return JSON.stringify(e).slice(1,-1)}function _n(e,n=process.env){let r=[],t=e.replace(Vn,(s,i)=>{if(s.startsWith("$$"))return s.slice(1);let o=n[i];return o===void 0?(r.push(i),s):$n(o)});return r.length>0?{missing:r}:{text:t,missing:[]}}import{mkdirSync as Fn,existsSync as nn,readFileSync as Ln,writeFileSync as Wn}from"fs";import{dirname as Bn,join as tn}from"path";function re(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 A=class extends Error{code;httpStatus;fields;constructor(n,r,t,s){super(t),this.name="AppToolkitError",this.code=n,this.httpStatus=r,this.fields=s}};function ye(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 ie(e,n){if(n!==void 0&&(n.includes("/")||n.includes("\\")||n.includes("..")))throw new A("VALIDATION_FAILED",400,`凭据 stem 派生输入含路径敌对字符(${e})——拒绝派生`)}function B(e){if(ie("provider",e.provider),ie("service",e.service),ie("instanceId",e.instanceId),ie("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 Kn(e){return`secret://${e}`}function F(e){return`config/credentials/${e}.json`}function q(e,n){let r=tn(e,F(n));if(!nn(r))return null;try{let t=JSON.parse(Ln(r,"utf8"));if(typeof t.type!="string")return null;let{type:s,...i}=t,o={};for(let[m,p]of Object.entries(i))typeof p=="string"&&(o[m]=p);return{type:s,values:o}}catch{return null}}function Se(e,n,r){let t=tn(e,F(n)),s=nn(t);return Fn(Bn(t),{recursive:!0}),Wn(t,`${JSON.stringify({type:r.type,...r.values},null,2)}
2
- `,"utf8"),s}import{mkdirSync as zn,renameSync as Un,writeFileSync as Jn}from"fs";import{dirname as Yn}from"path";function $(e,n){rn(Yn(e));let r=`${e}.tmp-${process.pid}-${Date.now()}`;Jn(r,n,"utf8"),Un(r,e)}function rn(e){zn(e,{recursive:!0})}function K(e){let n=e.indexOf(".");return n===-1?e:e.slice(0,n)}function _(e,n){let r=e?.domains?.[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 z(e,n){let r=[...new Set((n.descriptor.contributes.services??[]).map(i=>K(i.service)))].sort();if(r.length===0)return{writable:!1,reason:"zero-domain",domainKeys:[]};if(r.length>1)return{writable:!1,reason:"multi-domain",domainKeys:r};let t=r[0],s=new Set;for(let[i,o]of Object.entries(e.catalog.services))if(K(i)===t)for(let m of o.owners)s.add(m);return s.size>1?{writable:!1,reason:"shared-key",domainKeys:[t],domainKey:t,coOwners:[...s].sort()}:{writable:!0,domainKeys:[t],domainKey:t}}function on(e,n){let r=e.find(t=>t.pkg===n||`@app/${t.id}`===n);return r?r.id:n.startsWith("@app/")?n.slice(5):n}function sn(e,n){return[...new Set(Object.values(e.providers[n]??{}).flatMap(r=>r.services))].sort()}function we(e){if(!e||typeof e!="object")return!1;let n=Object.keys(e),r=new Set(["provider","credentialType","configSchema"]);if(!n.every(s=>r.has(s)))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 an(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 he(e,n){let r=new Set(n),t=[],s=(i,o)=>{let m=an(i,o,r);m&&t.push(m)};for(let i of Object.keys(e.configByInstance??{}))s(i,"configByInstance");for(let i of Object.keys(e.credentialRefByInstance??{}))s(i,"credentialRefByInstance");for(let[i,o]of Object.entries(e.services??{}))for(let m of Object.keys(o.instances??{}))s(m,`services.${i}.instances`);return t}function oe(e){let n=[],r=e.contracts,{integrations:t,suppliedProviders:s,demandedServices:i,supplies:o,malls:m,credentialSchemaMissing:p,vendorConfigKeys:u,vendorConfigSchemaMissing:g,credentialFileMissing:w,credentialFileType:d,realmSwitchHints:v,moduleResourceNeeds:I}=e,a=m?new Set(m):void 0;for(let c of v??[])n.push({severity:"warning",code:"REALM_SWITCH_HINT",message:c});let l=new Set(Object.keys(s).map(c=>c.slice(0,c.indexOf("\0"))).filter(c=>c.length>0)),f=(c,S,C,R)=>{if(typeof C?.provider=="string"&&typeof C.implementation=="string"&&C.provider&&C.implementation)return s[Q(C.provider,C.implementation)]?.credentialType;if(typeof S.provider=="string"&&typeof S.implementation=="string")return s[Q(S.provider,S.implementation)]?.credentialType;let x=S.provider?.credentialType;if(typeof x=="string")return x;if(!o)return;let M=R??Object.keys(S.instances??{})[0]??"",O=r.resolveEffectiveService(t,c,M,o);if(!(O.status!=="ok"||typeof O.effective.provider!="string"))return s[Q(O.effective.provider,O.effective.implementation)]?.credentialType};if(w||d)for(let[c,S]of Object.entries(t.services))for(let[C,R]of Object.entries(S.instances??{})){if(R.enabled===!1)continue;let x=R.credentialRef??S.credentialRef??t.credentialRefByInstance?.[C]??t.credentialRef;if(typeof x!="string"||!x.startsWith("secret://"))continue;let M=x.slice(9);w?.[M]===!0&&n.push({severity:"error",code:"CREDENTIAL_FILE_MISSING",service:c,instance:C,message:`integrations: 凭据文件缺失 ${M}(${c}@${C} effective ref=${x};档内 config/credentials/ 无此文件)`});let O=d?.[M];if(O){let N=f(c,S,R,C);N&&O!==N&&n.push({severity:"error",code:"CREDENTIAL_TYPE_MISMATCH",service:c,instance:C,message:`integrations: 凭据文件 ${M}.json type=${O} 与绑定 credentialType ${N} 不一致(${c}@${C}——transport 创建期将按 type 选策略)`})}}let b=(c,S)=>{if(!a)return;let C=an(c,S,a);C&&n.push(C)};for(let[c]of Object.entries(t.configByInstance??{}))b(c,"configByInstance");for(let[c]of Object.entries(t.credentialRefByInstance??{}))b(c,"credentialRefByInstance");let E=Object.entries(t.services).filter(([,c])=>c.instances==null||c.instances["*"]!=null).map(([c])=>c);if(E.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: 激活形态不对称(通配:${E.join(", ")};显式键集:${c.join(", ")})——动态 mallId 将在显式键集槽上 INSTANCE_NOT_FOUND(provider 业务限制表达位),确认是否齐步`})}let y=r.normalizeInstances({instances:t.instances,defaultInstanceId:t.defaultInstanceId});y.instances.length>=2&&y.defaultInstanceId===null&&n.push({severity:"warning",code:"MULTI_INSTANCE_NO_DEFAULT",message:`integrations: ${y.instances.length} 个部署实例(${y.instances.map(c=>c.id).join(", ")})均无 defaultInstanceId——无 scope 参数访问将落全局会话(默认商圈不注入)`});for(let[c,S]of Object.entries(t.services)){if(i[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"&&!s[Q(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&&!we(S.provider)&&n.push({severity:"error",code:"INLINE_PROVIDER_INVALID",service:c,message:`integrations: 内联 provider 超受控形状(${c} 槽级;允许键 provider/credentialType/configSchema)`}),p){let R=f(c,S);R&&p[R]===!0&&n.push({severity:"error",code:"SCHEMA_FILE_MISSING",service:c,message:`integrations: credentialType ${R} 的 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[R,x]of Object.entries(S.instances??{})){b(R,`services.${c}.instances`);let M=x.provider!==void 0,O=x.implementation!==void 0;if(O&&!M&&n.push({severity:"error",code:"IMPL_WITHOUT_PROVIDER",service:c,instance:R,message:`integrations: 实例级 implementation 需伴随 provider(${c}@${R}——impl-only 禁止,provider 是绑定组头)`}),M&&O){let N=x.provider,D=x.implementation;typeof N=="string"&&typeof D=="string"?s[Q(N,D)]||n.push({severity:"error",code:"INSTANCE_SUPPLY_UNMATCHED",service:c,instance:R,message:`integrations: 实例级 provider 覆盖 ${N}/${D} 未命中已装供给(${c}@${R})`}):we(N)||n.push({severity:"error",code:"INLINE_PROVIDER_INVALID",service:c,instance:R,message:`integrations: 实例级内联 provider 超受控形状(${c}@${R})`})}}}for(let[c,S]of[["root",t.provider],...Object.entries(t.domains??{}).map(([C,R])=>[`domains.${C}`,R?.provider])])typeof S!="string"||S.length===0||l.has(S)||n.push({severity:"error",code:"VENDOR_NOT_INSTALLED",module:c.startsWith("domains.")?c.slice(8):void 0,message:`integrations: ${c} provider ${S} 未命中已装供给——装对应 provider 包或 provider use 改绑`});if(o)for(let[c,S]of Object.entries(t.services)){let C=S.instances?Object.keys(S.instances):[""];for(let R of C){let x=r.resolveEffectiveService(t,c,R,o);x.status==="binding-unresolved"&&n.push({severity:"error",code:"BINDING_UNRESOLVED",service:c,instance:R||void 0,message:`integrations: ${x.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 是绑定组头)`});let k=new Set([...Object.keys(t.services).map(c=>r.moduleDomainOf(c)),...Object.keys(i).map(c=>r.moduleDomainOf(c))]);for(let c of Object.keys(t.domains??{}))k.has(c)||n.push({severity:"warning",code:"DOMAIN_KEY_UNMATCHED",module:c,message:`integrations: domains.${c} 无对应槽位或需求声明(域前缀拼写错误?——键 = 槽位 id 点分前缀)`});if(u){let c=new Set,S=!1,C=R=>{typeof R!="string"||R.length===0||(u[R]&&c.add(R),!u[R]&&!g?.[R]&&(S=!0),g?.[R]&&(S=!0))};C(t.provider);for(let R of Object.values(t.domains??{}))C(R?.provider);for(let R of Object.values(t.services)){let x=R.provider;C(typeof R.provider=="string"?R.provider:x?.provider)}if(c.size>0&&!S){let R=new Set;for(let M of c)for(let O of u[M]??[])R.add(O);let x=(M,O,N)=>{for(let[D]of Object.entries(M??{}))(N??R).has(D)||n.push({severity:"error",code:"DOMAIN_CONFIG_INVALID",message:`integrations: ${O} 键 ${D} 不在引用厂商(${[...c].join("/")})任何槽 schema properties 内(死配置)`})};x(t.config,"root.config");for(let[M,O]of Object.entries(t.configByInstance??{}))x(O,`root.configByInstance[${M}]`);for(let[M,O]of Object.entries(t.domains??{})){if(!O?.config)continue;let N=_(t,M).provider??void 0;if(N===void 0){x(O.config,`domains.${M}.config`);continue}let D=u[N];!D||g?.[N]||x(O.config,`domains.${M}.config`,new Set(D))}}}for(let[c,S]of Object.entries(i)){let C=t.services[c];if(!C){n.push({severity:"warning",code:"SLOT_NOT_CONFIGURED",service:c,message:`integrations: 服务槽 ${c}(需求方 ${S.owners.join(", ")})未配置${S.optional?"(可选槽)":"(必需槽——模块将走降级链)"}`});continue}let R=Object.entries(C.instances??{}).filter(([,x])=>x.enabled===!1).map(([x])=>x);R.length>0&&n.push({severity:"warning",code:"INSTANCE_DISABLED",service:c,instance:R.join(", "),message:`integrations: ${c} 实例禁用(${R.join(", ")})`})}for(let[c,S]of Object.entries(t.modules??{})){let C=I?.[c];I&&!(c in I)&&n.push({severity:"warning",code:"RESOURCE_NOT_DECLARED",module:c,message:`integrations: modules.${c} 未命中已装模块(键 = install id——检查 .tbox/app.json entry.id / packages/ 目录名)`});for(let[R,x]of Object.entries(S?.resources??{})){let M=x?.type;(typeof M!="string"||!r.RESOURCE_TYPE_IDS.includes(M))&&n.push({severity:"error",code:"RESOURCE_TYPE_UNKNOWN",module:c,message:`integrations: modules.${c}.resources.${R} type 非法(${String(M)};词汇表 = ${r.RESOURCE_TYPE_IDS.join("/")})`}),C&&C.size>0&&!C.has(R)&&n.push({severity:"warning",code:"RESOURCE_NOT_DECLARED",module:c,message:`integrations: modules.${c}.resources.${R} 未被模块 manifest contributes.resources 声明`})}}return n}function Q(e,n){return`${e}\0${n}`}import{existsSync as Ie,readFileSync as Hn,readdirSync as Zn}from"fs";import{join as se}from"path";function ln(e){return e.replaceAll("-","_").toUpperCase()}function cn(e){if(!Ie(e))return null;try{let n=JSON.parse(Hn(e,"utf8"));return n&&typeof n=="object"?n:null}catch{return null}}function Gn(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 Re(e,n,r,t=process.env){let s={};for(let[y,k]of Object.entries(n.catalog.providers))for(let[c,S]of Object.entries(k))s[`${y}\0${c}`]={services:[...S.services],owner:S.owner,credentialType:S.credentialType};let i={};for(let[y,k]of Object.entries(n.catalog.services))i[y]={optional:k.optional,owners:[...k.owners]};let o={},m={},p={},u={};for(let y of n.modules){u[y.id]=new Set((y.descriptor.contributes.resources??[]).map(k=>k.id));for(let k of y.descriptor.contributes.providers?.slots??[]){if(k.configSchema){let c=cn(se(y.dir,k.configSchema));if(c){let S=o[k.provider]??=new Set;for(let C of Gn(c))S.add(C)}else m[k.provider]=!0}k.credentialSchema&&!Ie(se(y.dir,k.credentialSchema))&&(p[k.credentialType]=!0)}}let g={},w=new Set,d=se(e,"config","credentials");if(Ie(d))for(let y of Zn(d)){if(!y.endsWith(".json"))continue;let k=y.slice(0,-5);w.add(k);let c=cn(se(d,y));c&&typeof c.type=="string"&&(g[k]=c.type)}let v=r,I=[],a=y=>{typeof y=="string"&&y.startsWith("secret://")&&I.push(y)};for(let y of Object.values(v.services??{}))if(y&&typeof y=="object"){a(y.credentialRef);for(let k of Object.values(y.instances??{}))k&&typeof k=="object"&&a(k.credentialRef)}for(let y of Object.values(v.credentialRefByInstance??{}))a(y);a(v.credentialRef);let l={};for(let y of I){let k=y.slice(9);t[ln(k)]===void 0&&(w.has(k)||(l[k]=!0))}let f=[];for(let[y,k]of Object.entries(v.services??{})){let c=k&&typeof k=="object"&&typeof k.provider=="string"?k.provider:void 0;for(let[S,C]of Object.entries((k&&typeof k=="object"?k.instances:void 0)??{})){let R=C&&typeof C=="object"&&typeof C.provider=="string"?C.provider:void 0;c&&R&&R!==c&&f.push(`integrations: ${y}@${S} 实现覆盖跨厂商(${c} → ${R})——凭据域切换,确认该 mall 对应凭据在场`)}}let E=((Array.isArray(v.instances)?v.instances:void 0)??[]).map(y=>y&&typeof y=="object"&&typeof y.id=="string"?y.id:void 0).filter(y=>typeof y=="string");return{suppliedProviders:s,demandedServices:i,credentialFileMissing:l,credentialFileType:g,credentialSchemaMissing:p,vendorConfigKeys:o,vendorConfigSchemaMissing:m,realmSwitchHints:f,moduleResourceNeeds:u,...E.length>0?{malls:E}:{}}}import{existsSync as V,readdirSync as be,readFileSync as U}from"fs";import{join as j}from"path";import{existsSync as qn,readFileSync as dn,mkdirSync as Qn,writeFileSync as Xn}from"fs";import un from"path";function ae(e){return un.join(e,".tbox","app.json")}function pn(e){let n=ae(e);if(!qn(n))return null;try{let r=JSON.parse(dn(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 et(e,n){let r=ae(e);Qn(un.dirname(r),{recursive:!0}),Xn(r,`${JSON.stringify(n,null,2)}
3
- `,"utf8")}function ke(e){let n=pn(e);if(n===null)return null;let r=ae(e);try{let t=JSON.parse(dn(r,"utf8"));return{...n,miniappContainers:Array.isArray(t?.miniappContainers)?t.miniappContainers:[]}}catch{return{...n,miniappContainers:[]}}}function nt(e,n){let r=e.npmModules.filter(t=>t.id!==n.id);return{...e,npmModules:[...r,n]}}function tt(e,n){return{...e,npmModules:e.npmModules.filter(r=>r.id!==n)}}function rt(e,n){let r=(e.miniappContainers??[]).filter(t=>t.id!==n.id);return{...e,miniappContainers:[...r,n]}}function it(e,n,r){return{...e,npmModules:e.npmModules.map(t=>t.id===n?{...t,...r}:t)}}function fn(e){return/^[a-z0-9]+(-[a-z0-9]+)*$/.test(e)&&!e.includes("..")}function ot(e,n){if(!fn(e))throw new Error(`非法模块 id "${e}"(来自 ${n}):仅允许小写字母/数字/中划线`)}function ce(e,n){let r=t=>{try{let s=JSON.parse(t),i=G(s);if(i.ok)return{kind:"strict",name:i.value.name,version:i.value.version,descriptor:i.value,contributes:i.value.contributes};if(s&&typeof s=="object"&&"contributes"in s){let o=s;return{kind:"loose",...typeof o.name=="string"?{name:o.name}:{},contributes:{providers:o.contributes?.providers,services:o.contributes?.services}}}return null}catch{return null}};if(n)return n.read(e,r)??null;if(!V(e))return null;try{return r(U(e,"utf8"))}catch{return null}}function st(e){let n=j(e,".tbox","app.json");if(!V(n))return[];try{let r=JSON.parse(U(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=j(e,".tbox-dev.local"),r=j(n,"dev-manifest.json");if(!V(r))return[];try{let t=JSON.parse(U(r,"utf8")),s=[];for(let[i,o]of Object.entries(t.redirects??{}))typeof o!="string"||!i.startsWith("@tbox.cn/app-")||s.push({pkg:i,dir:j(n,o)});return s}catch{return[]}}function ct(e,n){let r=[],t=[e];for(let i of["apps","packages"]){let o=j(e,i);if(V(o))try{for(let m of be(o,{withFileTypes:!0}))m.isDirectory()&&t.push(j(o,m.name))}catch{}}let s=new Set;for(let i of t){let o=j(i,"node_modules","@tbox.cn");if(!V(o))continue;let m=[];try{m=be(o)}catch{continue}for(let p of m){let u=j(o,p);if(s.has(u))continue;s.add(u);let g=j(u,"service-slots.json");if(!V(g))continue;let w=v=>{try{let I=JSON.parse(v);if(Array.isArray(I.slots))return I.slots.filter(a=>typeof a=="string")}catch{}return null},d=n?n.read(g,w):w(U(g,"utf8"));d!=null&&r.push({dir:u,slots:d})}}return r}function P(e,n){let r=[],t={providers:{},services:{},credentialTypes:{}},s={},i=[],o=new Set,m=new Map,p=(d,v,I)=>{for(let a of d){let l=t.providers[a.provider]??={},f=l[a.implementation];f?f.services.includes(a.service)||f.services.push(a.service):(l[a.implementation]={provider:a.provider,implementation:a.implementation,credentialType:a.credentialType,owner:v,...a.local?{local:!0}:{},...a.configSchema?{configSchema:a.configSchema}:{},...a.credentialSchema?{credentialSchema:a.credentialSchema}:{},services:[a.service]},t.credentialTypes[a.credentialType]??={owner:v,packageDir:I,...a.credentialSchema?{credentialSchema:a.credentialSchema}:{}});let b=`${a.provider}\0${a.service}`;s[b]||(s[b]={...a.configSchema?{configSchema:a.configSchema}:{},...a.credentialSchema?{credentialSchema:a.credentialSchema}:{},packageDir:I})}},u=(d,v)=>{let I=d.optional!==!1,a=d.defaults??[],l=t.services[d.service];if(l){l.optional=l.optional&&I;let E=new Set(l.defaults.map(y=>`${y.provider}\0${y.implementation}`));for(let y of a){let k=`${y.provider}\0${y.implementation}`;E.has(k)||(l.defaults.push(y),E.add(k))}l.owners.includes(v)||l.owners.push(v);return}t.services[d.service]={optional:I,defaults:[...a],...d.title?{title:d.title}:{},...d.description?{description:d.description}:{},owners:[v]};let f=d.service.includes(".")?d.service.slice(0,d.service.indexOf(".")):d.service,b=m.get(f);b===void 0?m.set(f,v):b!==v&&i.push({severity:"warning",code:"DOMAIN_KEY_CONFLICT",module:v,message:`域键 ${f} 被多模块声明(${b} 与 ${v})——domains 换算歧义(P13)`})};for(let d of st(e)){if(o.has(d.id))continue;let v=j(e,"packages",d.id),I=j(e,"node_modules",...d.package.split("/")),a=ce(j(v,"tbox.module.json"),n)??ce(j(I,"tbox.module.json"),n);if(!a)continue;o.add(d.id);let l=V(j(v,"tbox.module.json"))?v:I,f=a.contributes;a.kind==="strict"&&r.push({id:d.id,dir:l,pkg:d.mode==="sdk"?d.package:`@app/${d.id}`,descriptor:a.descriptor});let b=f.providers?.slots??[];b.length&&p(b,d.package,l);let E=f.services??[];if(E.length)for(let y of E)u(y,d.package)}for(let{pkg:d,dir:v}of at(e)){let I=ce(j(v,"tbox.module.json"),n);if(!I?.name||o.has(I.name))continue;o.add(I.name);let a=I.contributes.providers?.slots??[];a.length&&p(a,d,v);let l=I.contributes.services??[];if(l.length)for(let f of l)u(f,d)}let g=j(e,"packages");if(V(g)){let d=[];try{d=be(g,{withFileTypes:!0}).filter(v=>v.isDirectory()).map(v=>v.name)}catch{}for(let v of d){if(o.has(v))continue;let I=j(g,v),a=ce(j(I,"tbox.module.json"),n);if(!a)continue;let l=a.name??v;if(o.has(l))continue;o.add(l);let f=a.contributes;a.kind==="strict"&&r.push({id:l,dir:I,pkg:`@app/${l}`,descriptor:a.descriptor});let b=f.providers?.slots??[];b.length&&p(b,`@app/${l}`,I);let E=f.services??[];if(E.length)for(let y of E)u(y,`@app/${l}`)}}let w=new Set;for(let d of ct(e,n))for(let v of d.slots)w.add(v);return{modules:r,catalog:t,serviceSchemas:s,vocabulary:[...w].sort(),domainKeyIssues:i}}function gn(e,n,r){let t=j(e,"src",n,"index.ts");if(!V(t))return!1;try{let s=U(t,"utf8");return new RegExp(`export\\s+const\\s+${r}\\b`).test(s)}catch{return!1}}function lt(e){let n=j(e,"src","server","index.ts");if(!V(n))return"";try{return U(n,"utf8")}catch{return""}}function mn(e){return e.match(/declaration\s*:\s*\{[\s\S]*?moduleId\s*:\s*['"]([^'"]+)['"]/)?.[1]}function dt(e){let n=[],r=P(e),t=ke(e),s=new Map;for(let i of t?.npmModules??[])s.set(i.id,i.mode);for(let i of r.modules){let o=s.get(i.id)??"local",m=gn(i.dir,"server","serverModule"),p=i.descriptor.contributes;n.push({id:i.id,pkg:o==="sdk"?i.pkg:`@app/${i.id}`,mode:o,hasServerEntry:m,hasClientEntry:gn(i.dir,"client","clientModule"),hasCards:(p.cards?.length??0)>0,...m?{moduleId:mn(lt(i.dir))}:{}})}return n.sort((i,o)=>i.id.localeCompare(o.id))}import{existsSync as ar,readFileSync as cr}from"fs";import{join as dr,resolve as ur}from"path";function Ce(e){return P(e).catalog}function vn(e){let n=P(e).catalog,r={};for(let[i,o]of Object.entries(n.providers)){r[i]={};for(let[m,p]of Object.entries(o))r[i][m]={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[i,o]of Object.entries(n.services))t[i]={optional:o.optional,defaults:o.defaults.map(m=>({...m})),owners:[...o.owners]};let s={};for(let[i,o]of Object.entries(n.credentialTypes))s[i]={owner:o.owner,...o.credentialSchema?{credentialSchema:o.credentialSchema}:{}};return{providers:r,services:t,credentialTypes:s}}import{existsSync as ut,readFileSync as pt}from"fs";import{join as yn}from"path";var ft=yn("config","integrations.json");function J(e,n){let r=yn(e,ft),t=s=>JSON.parse(s);if(n)return n.read(r,t)??null;if(!ut(r))return null;try{return t(pt(r,"utf8"))}catch{return null}}async function Sn(e,n){let r=await T(e),t=J(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(s){if(s instanceof Error&&Array.isArray(s.issues)){let i=s.issues.filter(o=>Array.isArray(o.path)).map(o=>o.path.map(String).join(".")).filter(o=>o.length>0);throw new A("VALIDATION_FAILED",400,"integrations.json 校验失败",i.length>0?i:void 0)}throw new A("VALIDATION_FAILED",400,s instanceof Error?s.message:String(s))}return{config:t,strict:!1,contracts:r}}function X(e,n,r){return e.includes(r)||n.includes(r)}import{existsSync as kn,readFileSync as bn}from"fs";import{join as Y,resolve as yt}from"path";import St from"ajv";var ee=["provider","config","configByInstance","credentialRef","credentialRefByInstance","instances","defaultInstanceId"];import{readdirSync as gt,existsSync as le,readFileSync as mt}from"fs";import{join as de}from"path";function wn(e,n,r){let t=[];if(n){let s=B({provider:e});t.push({stem:s,ref:`secret://${s}`,input:n})}for(let[s,i]of Object.entries(r??{})){let o=B({provider:e,instanceId:s});t.push({instanceId:s,stem:o,ref:`secret://${o}`,input:i})}return t}function hn(e,n,r,t,s){let i=[];if(t){let o=B({provider:e,service:n});i.push({stem:o,ref:`secret://${o}`,input:t})}for(let[o,m]of Object.entries(s??{})){let p=B({provider:e,instanceId:o,domain:r});i.push({instanceId:o,stem:p,ref:`secret://${p}`,input:m})}return i}function Ee(e,n,r){return n.map(t=>({stem:t.stem,ref:t.ref,overwrote:r?le(de(e,F(t.stem))):Se(e,t.stem,t.input)}))}function vt(e,n){return le(de(e,F(n)))}function Ae(e,n){if(typeof e=="string"){e.startsWith("secret://")&&n.add(e.slice(9));return}if(Array.isArray(e)){for(let r of e)Ae(r,n);return}if(e&&typeof e=="object")for(let r of Object.values(e))Ae(r,n)}function xe(e){let n=de(e,"config","credentials"),r=new Set,t=de(e,"config","integrations.json");if(le(t))try{Ae(JSON.parse(mt(t,"utf8")),r)}catch{}let s=[];if(!le(n))return s;let i=[];try{i=gt(n).filter(o=>o.endsWith(".json")).map(o=>o.slice(0,-5))}catch{return s}for(let o of i.sort()){if(r.has(o))continue;let m=q(e,o);s.push({severity:"warning",code:"ORPHANED_CREDENTIAL",message:`config/credentials/${o}.json 不再被引用(凭据文件保留,可手动清理)`})}return s}var W=Y("config","integrations.json");function H(e,n){if(e===n)return!0;if(Array.isArray(e)&&Array.isArray(n))return e.length!==n.length?!1:e.every((r,t)=>H(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(s=>H(e[s],n[s]))}return!1}function fe(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"&&!L.test(t))throw new A("VALIDATION_FAILED",400,`${r} 名含非法字符(需 /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/)`,[`${n}.${r}`]);fe(t,`${n}.${r}`)}}function ue(e,n,r){if(!(!e||typeof e!="object"||Array.isArray(e))){for(let t of Object.keys(e))if(!(r&&(t==="*"||t==="**"))&&!L.test(t))throw new A("VALIDATION_FAILED",400,`${n} 键 ${t} 含非法字符(需 /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/)——进凭据 stem 派生,防路径逃逸`,[n])}}function In(e,n,r){if(r==="root"){let t=e.instances;Array.isArray(t)&&t.forEach((s,i)=>{let o=s&&typeof s=="object"?s.id:void 0;if(typeof o=="string"&&!L.test(o))throw new A("VALIDATION_FAILED",400,`instances[${i}].id 含非法字符(需 /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/)`,[`root.instances[${i}].id`])}),ue(e.configByInstance,"root.configByInstance",!1),ue(e.credentialRefByInstance,"root.credentialRefByInstance",!1)}else ue(e.instances,"services.instances",!0);ue(n.credentialsByInstance,"credentialsByInstance",!1)}function pe(e,n){let r=Y(e,W),t=s=>JSON.parse(s);if(n)return n.read(r,t)??null;if(!kn(r))return null;try{return t(bn(r,"utf8"))}catch{return null}}function Oe(e){let n=(e.instances??[]).map(r=>r.id);return n.length===0?[]:he(e,n)}function wt(e,n,r,t){let{catalog:s}=P(e,t),i=s.providers[n];if(!i)return;let o=new Set;for(let m of Object.values(i))(r===void 0||m.services.includes(r))&&o.add(m.credentialType);return o.size===1?[...o][0]:void 0}function Rn(e,n,r,t,s,i){if(typeof t.type!="string"||t.type.length===0)throw new A("VALIDATION_FAILED",400,"凭据 type 缺失或为空字符串",["credentials.type"]);let o=s??wt(e,n,r,i);if(o!==void 0&&o!=="-"&&t.type!==o)throw new A("VALIDATION_FAILED",400,`凭据 type=${t.type} 与绑定 credentialType ${o} 不一致`,["credentials.type"]);if(r===void 0)return;let{serviceSchemas:m}=P(e,i),p=m[`${n}\0${r}`];if(!p?.credentialSchema)return;let u=yt(p.packageDir,p.credentialSchema);if(kn(u))try{let w=new St({allErrors:!0}).compile(JSON.parse(bn(u,"utf8")));if(!w({type:t.type,...t.values})){let d=(w.errors??[]).map(v=>`credentials.values.${String(v.instancePath||v.params?.missingProperty||"").replace(/^\//,"")}`);throw new A("VALIDATION_FAILED",400,"凭据字段校验失败(ajv 字段级)",d)}}catch(g){if(g instanceof A)throw g}}function Te(e,n={}){let{onApplied:r,cache:t}=n;function s(u,g,w,d,v){let I=!d&&u!==null;I&&($(Y(e,W),`${JSON.stringify(u,null,2)}
4
- `),t?.invalidate([Y(e,W)]));let a=I||v,l=a&&r!==void 0;l&&r?.();let f=[];return I&&f.push(W),v&&f.push(...g.map(b=>`config/credentials/${b.stem}.json`)),{written:a,restartScheduled:l,files:f,credentials:g,issues:w}}let i;async function o(){i=await T(e)}function m(u,g){return u.filter(w=>Array.isArray(w.path)).map(w=>{let d=w.path.map(String).join(".");return g!==""&&d.startsWith(g)&&d.length>g.length?d.slice(g.length):d}).filter(w=>w.length>0)}function p(u,g,w){let d=i;if(!d||!d.strictValidation||!d.module.parseIntegrationsConfig)throw new A("CONTRACTS_NOT_RESOLVED",503,"contracts 严格校验面不可用(需 ≥0.9)——写路径门控失败(工厂边缘断言应先行拦截)");try{d.module.parseIntegrationsConfig(u)}catch(v){throw v instanceof Error&&Array.isArray(v.issues)?new A("VALIDATION_FAILED",400,"节点 schema 校验失败",m(v.issues,w)):new A("VALIDATION_FAILED",400,v instanceof Error?v.message:String(v))}}return{warmup:o,applyApp(u,g={}){fe(u,"root"),In(u,g,"root");let w=[],d=pe(e,t),v=d??{services:{}};d===null&&w.push({severity:"warning",code:"SKELETON_MATERIALIZED",message:"config/integrations.json 缺席——已物化骨架(写时自动初始化;R13 语义翻转提示)"});let I={...v};for(let c of ee)c in u||delete I[c];for(let[c,S]of Object.entries(u))I[c]=S;let a=typeof I.provider=="string"?I.provider:"app",l=wn(a,g.credentials,g.credentialsByInstance);for(let c of l)Rn(e,a,void 0,c.input,void 0,t);let f=l.find(c=>c.instanceId===void 0);if(g.credentials&&f&&(I.credentialRef=f.ref),g.credentialsByInstance){let c={...I.credentialRefByInstance??{}};for(let S of l)S.instanceId!==void 0&&(c[S.instanceId]=S.ref);I.credentialRefByInstance=c}let b=g.credentials!==void 0||g.credentialsByInstance!==void 0,E=H(d,I);if(E&&!b)return{written:!1,restartScheduled:!1,files:[],credentials:[],issues:w};p(I,w,"");let y=g.dryRun===!0,k=Ee(e,l,y);return w.push(...Oe(I)),s(E?null:I,k,w,g.dryRun,!y&&l.length>0)},applyModule(u,g,w={}){fe(g,"root");let{modules:d,catalog:v}=P(e,t),I=d.find(c=>c.id===u);if(!I)throw new A("MODULE_NOT_FOUND",404,`模块 ${u} 非已装模块`);let a=z({modules:d,catalog:v},I);if(!a.writable)throw a.reason==="multi-domain"?new A("VALIDATION_FAILED",400,`模块 ${u} 跨 ${a.domainKeys.length} 个域(${a.domainKeys.join("、")})——模块级统一配置仅支持单域模块,请按服务级配置(编辑各服务行)`):a.reason==="zero-domain"?new A("VALIDATION_FAILED",400,`模块 ${u} 无服务需求声明,无域配置位`):new A("VALIDATION_FAILED",400,`域键 ${a.domainKey} 由 ${a.coOwners.map(c=>on(d,c)).join("、")} 共用——写通道拒绝歧义操作,请按服务级配置`);let l=a.domainKey,f=[],b=pe(e,t);if(b===null&&Object.keys(g).length===0)return{written:!1,restartScheduled:!1,files:[],credentials:[],issues:f};b===null&&f.push({severity:"warning",code:"SKELETON_MATERIALIZED",message:"config/integrations.json 缺席——已物化骨架(写时自动初始化;R13 语义翻转提示)"});let E=b??{services:{}},y={...E.domains??{}},k={...E,domains:y};return Object.keys(g).length===0?delete y[l]:y[l]={...g},H(b,k)?{written:!1,restartScheduled:!1,files:[],credentials:[],issues:f}:(p(k,f,`domains.${l}.`),f.push(...Oe(k)),s(k,[],f,w.dryRun,!1))},applyService(u,g,w={}){fe(g,"root"),In(g,w,"slot");let d=[],v=pe(e,t);if(!X(P(e,t).vocabulary,Object.keys(v?.services??{}),u))throw new A("SERVICE_NOT_FOUND",404,`服务 ${u} 不在服务词汇(已装契约包 ∪ 已配置)`);v===null&&d.push({severity:"warning",code:"SKELETON_MATERIALIZED",message:"config/integrations.json 缺席——已物化骨架(写时自动初始化;R13 语义翻转提示)"});let I=v??{services:{}},a={...I.services??{}},l={...I,services:a};a[u]={...g};let f=g.provider,b=f!==null&&typeof f=="object"?f:void 0,E=typeof f=="string"?f:typeof b?.provider=="string"?b.provider:"app",y=u.includes(".")?u.slice(0,u.indexOf(".")):u,k=hn(E,u,y,w.credentials,w.credentialsByInstance);for(let O of k)Rn(e,E,u,O.input,typeof b?.credentialType=="string"?b.credentialType:void 0,t);let c=a[u],S=k.find(O=>O.instanceId===void 0);if(w.credentials&&S&&(c.credentialRef=S.ref),w.credentialsByInstance){let O={...c.instances??{}};for(let N of k){if(N.instanceId===void 0)continue;let D={...O[N.instanceId]??{}};D.credentialRef=N.ref,O[N.instanceId]=D}c.instances=O}let C=w.credentials!==void 0||w.credentialsByInstance!==void 0,R=H(v,l);if(R&&!C)return{written:!1,restartScheduled:!1,files:[],credentials:[],issues:d};p(l,d,`services.${u}.`);let x=w.dryRun===!0,M=Ee(e,k,x);return d.push(...Oe(l)),s(R?null:l,M,d,w.dryRun,!x&&k.length>0)},deleteService(u){let g=[],w=pe(e,t);if(!X(P(e,t).vocabulary,Object.keys(w?.services??{}),u))throw new A("SERVICE_NOT_FOUND",404,`服务 ${u} 不在服务词汇(已装契约包 ∪ 已配置)`);let d={...w?.services??{}};if(!(u in d))return{written:!1,restartScheduled:!1,files:[],credentials:[],issues:g};delete d[u];let v={...w??{services:{}},services:d};$(Y(e,W),`${JSON.stringify(v,null,2)}
5
- `),t?.invalidate([Y(e,W)]),g.push(...xe(e));let I=r!==void 0;return I&&r?.(),{written:!0,restartScheduled:I,files:[W],credentials:[],issues:g}}}}import{existsSync as ht}from"fs";import{join as It}from"path";function Me(e){let n=It(e,"config","integrations.json");if(ht(n))return{generated:!1,reason:"in-place",services:[]};let r=[];for(let i of P(e).modules)for(let o of i.descriptor.contributes.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={},s=new Set(r.map(i=>i.provider));if(s.size===1){let[i]=s;for(let o of r)t[o.service]={};$(n,`${JSON.stringify({provider:i,services:t},null,2)}
6
- `)}else{for(let i of r)t[i.service]={provider:i.provider,implementation:i.implementation};$(n,`${JSON.stringify({services:t},null,2)}
7
- `)}return{generated:!0,reason:"generated",services:r.map(i=>i.service).sort()}}function je(e){return{modules:e.walk.modules.map(r=>({id:r.id,name:r.descriptor.name,title:r.descriptor.name,description:""})).sort((r,t)=>r.id.localeCompare(t.id))}}function Ne(e,n){let r=e.walk.modules.find(p=>p.id===n);if(!r)throw new A("MODULE_NOT_FOUND",404,`模块 ${n} 非已装模块`);let t=(r.descriptor.contributes.services??[]).map(p=>({service:p.service,...p.title?{title:p.title}:{},...p.description?{description:p.description}:{},required:p.optional===!1})),s=z(e.walk,r),i=e.integrations?.domains??{},o=s.writable?i[s.domainKey]??null:null,m=s.domainKeys.map(p=>{let u=_(e.integrations,p);return{domain:p,effective:u.provider,layer:u.layer}});return{domainKeys:[...s.domainKeys],integration:o,providerBindings:m,configEditable:s.writable,services:t}}function Cn(e,n){let r=P(e.appDir,e.cache),t=J(e.appDir,e.cache);return{appDir:e.appDir,walk:r,catalog:r.catalog,integrations:t,contracts:n}}function An(e){let n=new Set;for(let r of e.modules){for(let t of r.descriptor.contributes.services??[])n.add(t.service);for(let t of r.descriptor.contributes.providers?.slots??[])n.add(t.service)}return n}function ge(e,n,r){let t=e.providers[n];return t?Object.values(t).some(s=>s.services.includes(r)):!1}function En(e,n){let r=[];for(let[t,s]of Object.entries(e.providers))Object.values(s).some(i=>i.services.includes(n))&&r.push(t);return r.sort()}function Pe(e){let n=An(e.walk),r=e.walk.vocabulary.filter(i=>!n.has(i)).map(i=>({service:i,required:!1})),t=e.integrations,s=null;if(t){let i={};for(let o of ee)o in t&&(i[o]=t[o]);s=i}return{services:r,integration:s}}function De(e,n){let r=e.integrations?.services??{},t=e.catalog.services[n];if(!X(e.walk.vocabulary,Object.keys(r),n))throw new A("SERVICE_NOT_FOUND",404,`服务 ${n} 不在服务词汇(已装契约包 ∪ 已配置)`);let s=r[n]??null;return{service:n,...t?.title?{title:t.title}:{title:n},...t?.description?{description:t.description}:{},required:t?!t.optional:!1,defaults:t?t.defaults.map(i=>({...i})):[],integration:s,suppliedBy:En(e.catalog,n)}}import{existsSync as Tn,readFileSync as Mn,realpathSync as xn}from"fs";import{isAbsolute as Rt,join as kt,relative as bt,resolve as On,sep as Ct}from"path";function Ve(e){let n=[];for(let[r,t]of Object.entries(e.catalog.providers)){let s=Object.values(t);s.length!==0&&n.push({provider:r,local:s.every(i=>i.local===!0),owner:s[0].owner})}return{providers:n.sort((r,t)=>r.provider.localeCompare(t.provider))}}function $e(e,n,r){let t=e.catalog.providers[n];if(!t)throw new A("PROVIDER_NOT_FOUND",404,`厂商 ${n} 不 ∈ catalog(内联声明厂商无包级档案——身份与表单经组合端点暴露)`);let s={};for(let o of Object.values(t))for(let m of o.services)(s[m]??={implementations:[]}).implementations.push({implementation:o.implementation,credentialType:o.credentialType});if(r?.has("integrationSchemas"))for(let[o,m]of Object.entries(s)){let p=e.walk.serviceSchemas[`${n}\0${o}`];m.integrationSchemas={configSchema:p?Z(e.appDir,p.packageDir,p.configSchema):null}}let i=Object.values(t);return{provider:n,local:i.every(o=>o.local===!0),owner:i[0].owner,services:s}}function _e(e,n,r){let t=e.catalog.providers[n],s=e.integrations?.services??{},i=[];if(t)for(let g of Object.values(t))g.services.includes(r)&&i.push({implementation:g.implementation,credentialType:g.credentialType});let o=s[r]?.provider,m=o&&typeof o=="object"&&o.provider===n?o:void 0;if(i.length===0&&!m)throw t?new A("SUPPLY_NOT_FOUND",404,`厂商 ${n} 未供给服务 ${r}(AI 帮我实现流:PUT 显式绑定后实施)`):new A("PROVIDER_NOT_FOUND",404,`厂商 ${n} 完全未知(不 ∈ catalog 且无任何内联声明)`);i.length===0&&m&&i.push({implementation:s[r]?.implementation??`${n}-inline@1`,credentialType:m.credentialType});let p=null,u=e.walk.serviceSchemas[`${n}\0${r}`];if(u)p=Z(e.appDir,u.packageDir,u.configSchema);else if(m){let g=o?.configSchema;typeof g=="string"&&(p=At(e.appDir,g))}return{provider:n,service:r,implementations:i,integrationSchemas:{configSchema:p}}}function Z(e,n,r){if(!r)return null;let t=kt(n,r);if(!Tn(t))return null;try{return JSON.parse(Mn(t,"utf8"))}catch{return null}}function At(e,n){let r=On(e,"config","schemas"),t=On(e,n),s=bt(r,t);if(s===""||s.startsWith("..")||Rt(s))throw new A("VALIDATION_FAILED",400,"configSchema 引用必须落在 config/schemas/ 内(禁路径逃逸)",["provider.configSchema"]);if(!Tn(t))return null;let i,o;try{i=xn(r),o=xn(t)}catch{return null}if(o!==i&&!o.startsWith(i+Ct))throw new A("VALIDATION_FAILED",400,"configSchema 引用经 symlink 逃逸出 config/schemas/(realpath 复核拒绝)",["provider.configSchema"]);try{return JSON.parse(Mn(t,"utf8"))}catch{return null}}function jn(e){return{version:e.version,evaluation:e.evaluation,strictValidation:e.strictValidation,notes:[...e.notes]}}function Nn(e,n,r){let t=e.integrations,s=K(n),i=t?.services?.[n],o=i?.instances?.[r]??i?.instances?.["*"];return o&&o.provider!==void 0?"instance":i?.provider!==void 0?"service":_(t,s).layer==="module"?"module":typeof t?.provider=="string"&&t.provider.length>0?"app":null}function Pn(e,n,r,t,s){let i=n.resolveEffectiveService(e.integrations,r,t,s);if(i.status==="ok"&&i.effective){let o=i.effective.provider,m=typeof o=="string"?o:String(o?.provider??"");return{status:"ok",provider:m,implementation:i.effective.implementation,effective:{provider:m,implementation:i.effective.implementation,...i.effective.config!==void 0?{config:{...i.effective.config}}:{},...i.effective.credentialRef!==void 0?{credentialRef:i.effective.credentialRef}:{},layer:Nn(e,r,t)??"app"}}}return i.status==="binding-unresolved"?{status:"binding-unresolved",statusMessage:i.message}:{status:i.status}}function Fe(e){let n=e.contracts.module;if(!n.resolveEffectiveService||!n.normalizeInstances)throw new A("CONTRACTS_NOT_RESOLVED",503,"contracts 求值面缺席(契约包形态异常)——重新安装或升级应用 @tbox.cn/app-contracts 后重试");return n}function Le(e,n){let r=Fe(n),{integrations:t,catalog:s}=n,i=r.buildSupplyLookup(s),o=t,p=r.normalizeInstances({instances:o?.instances,defaultInstanceId:o?.defaultInstanceId}).defaultInstanceId??"*",u=Pn(n,r,e,p,i),g=Nn(n,e,p),w=n.integrations?.services?.[e]?.provider,d=u.provider??(typeof w=="string"?w:typeof w=="object"&&w?String(w.provider):void 0),v=new Set(Object.keys(n.catalog.providers)),I=d!==void 0&&v.has(d)?Et(n.catalog,d,e):void 0,a=s.services[e],l=a!==void 0?!a.optional:void 0,f=a?.owners[0];return{status:u.status,...u.statusMessage?{statusMessage:u.statusMessage}:{},...d!==void 0?{provider:d}:{},...d!==void 0&&g!==null?{layer:g}:{},...I!==void 0?{supplied:I}:{},...f!==void 0?{module:f}:{},...l!==void 0?{required:l}:{}}}function Et(e,n,r){return ge(e,n,r)}function ne(e,n,r){let t=new Set([...e.walk.vocabulary,...Object.keys(e.catalog.services)]),s=e.integrations?.services??{};for(let o of Object.keys(s))t.add(o);let i={};for(let o of[...t].sort())r&&!r.includes(o)||(i[o]=Le(o,e));return{contracts:jn(e.contracts),resolutions:i,issues:n}}function We(e,n,r){let t=Fe(n),s=t.buildSupplyLookup(n.catalog),i=n.integrations,m=t.normalizeInstances({instances:i?.instances,defaultInstanceId:i?.defaultInstanceId}).instances.map(a=>a.id),p=n.integrations?.services?.[e],u=p?.instances?Object.keys(p.instances):void 0,g;m.length>0?(g=[...m],u?.includes("*")&&g.push("*")):u!==void 0&&u.length>0?g=u.includes("*")?["*"]:u:g=[];let w=g.map(a=>{let l=Pn(n,t,e,a,s);return{instanceId:a,status:l.status,...l.statusMessage?{statusMessage:l.statusMessage}:{},...l.effective?{effective:l.effective}:{}}}),d=xt(n,e),I={...Le(e,n),instances:w,inheritance:d};return{contracts:jn(n.contracts),resolution:I,issues:r.filter(a=>a.service===e)}}function xt(e,n){let r=e.integrations,t=K(n),s=r?.services?.[n],i=e.integrations,m=Fe(e).normalizeInstances({instances:i?.instances,defaultInstanceId:i?.defaultInstanceId}).defaultInstanceId??"*",p=s?.instances?.[m]??s?.instances?.["*"],u=_(r,t);return[{layer:"app",...r?.provider?{provider:r.provider}:{}},{layer:"module",...u.layer==="module"&&u.provider?{provider:u.provider}:{}},{layer:"service",...typeof s?.provider=="string"?{provider:s.provider}:{},...s?.implementation?{implementation:s.implementation}:{}},{layer:"instance",...p?.provider?{provider:p.provider}:{},...p?.implementation?{implementation:p.implementation}:{}}]}function Be(e,n,r){if(n===null)return null;let t={};for(let s of r){let i=e.walk.serviceSchemas[`${n}\0${s}`];t[s]={configSchema:i?Z(e.appDir,i.packageDir,i.configSchema):null}}return{provider:n,services:t}}function Ke(e){let n=e.integrations?.provider,r=typeof n=="string"&&n.length>0?n:null;return r===null?null:Be(e,r,sn(e.catalog,r))}function ze(e,n){let r=e.walk.modules.find(o=>o.id===n);if(!r)return null;let t=z(e.walk,r);if(!t.writable)return null;let s=_(e.integrations,t.domainKey).provider;if(s===null)return null;let i=(r.descriptor.contributes.services??[]).map(o=>o.service);return Be(e,s,i.filter(o=>ge(e.catalog,s,o)))}function te(e,n){if(n===void 0||!n.startsWith("secret://"))return;let r=n.slice(9),t=q(e,r);if(t)return{type:t.type,ref:n,file:F(r),masked:re(t.values)}}function Ue(e){let n=e.integrations,r={credential:te(e.appDir,typeof n?.credentialRef=="string"?n.credentialRef:void 0)??null,byInstance:{}};for(let{id:s}of n?.instances??[]){let i=n?.credentialRefByInstance?.[s];i!==void 0&&(r.byInstance[s]=te(e.appDir,i)??null)}let t={};for(let[s,i]of Object.entries(n?.services??{})){let o={credential:te(e.appDir,i.credentialRef)??null,byInstance:{}};for(let[m,p]of Object.entries(i.instances??{}))o.byInstance[m]=te(e.appDir,p.credentialRef)??null;t[s]=o}return{app:r,services:t}}function Je(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 s=e.catalog.credentialTypes[t];return{credentialType:t,owner:s?.owner??"",credentialSchema:s?Z(e.appDir,s.packageDir,s.credentialSchema):null}})}}import Ot from"path";var Tt={app:["serviceResolutions","integrationSchemas"],module:["serviceResolutions","integrationSchemas"],provider:["integrationSchemas"]};function Ye(e,n){if(!n||n.length===0)return new Set;let r=Tt[e],t=[...new Set(n)].filter(s=>!r.includes(s));if(t.length>0)throw new A("VALIDATION_FAILED",400,`include 含未知或不适用于本端点的键:${t.join("、")}(白名单:${r.join("、")})`,["include"]);return new Set(n)}function Mt(e,n={}){let r=me(),t=Promise.resolve(),s={appDir:e,cache:r};function i(a){if(!a.strictValidation)throw new A("CONTRACTS_NOT_RESOLVED",503,ye(a))}function o(a){return Cn(s,a)}async function m(){let a=await T(e),l=o(a),f=l.integrations;if(f===null)return[];let b={resolveEffectiveService:p(a.module.resolveEffectiveService,"resolveEffectiveService"),buildSupplyLookup:p(a.module.buildSupplyLookup,"buildSupplyLookup"),moduleDomainOf:p(a.module.moduleDomainOf,"moduleDomainOf"),normalizeInstances:p(a.module.normalizeInstances,"normalizeInstances"),RESOURCE_TYPE_IDS:a.module.RESOURCE_TYPE_IDS??[]},E=Re(e,l.walk,f,process.env);return oe({contracts:b,integrations:f,supplies:b.buildSupplyLookup(l.catalog),...E})}function p(a,l){if(typeof a!="function")throw new A("CONTRACTS_NOT_RESOLVED",503,`contracts 求值面 ${l} 缺席(形态异常)`);return a}function u(a){let l=t.then(a,a);return t=l.catch(()=>{}),l}let g={async loadModules(){let a=await T(e);return je(o(a))},async loadModule(a,l){let f=Ye("module",l?.include),b=await T(e),E=o(b),y=Ne(E,a);return f.has("serviceResolutions")&&(y.serviceResolutions=b.evaluation&&b.strictValidation?await m().then(k=>ne(E,k,y.services.map(c=>c.service))):null),f.has("integrationSchemas")&&(y.integrationSchemas=ze(E,a)),y},async loadApp(a){let l=Ye("app",a?.include),f=await T(e),b=o(f),E=Pe(b);return l.has("serviceResolutions")&&(E.serviceResolutions=f.evaluation&&f.strictValidation?await m().then(y=>ne(b,y)):null),l.has("integrationSchemas")&&(E.integrationSchemas=Ke(b)),E},async loadService(a){let l=await T(e);return De(o(l),a)},async loadServiceResolutions(a){let l=await T(e);i(l);let f=await m();return ne(o(l),f,a)},async loadServiceResolution(a){let l=await T(e);i(l);let f=await m();return We(a,o(l),f)},async loadProviders(){let a=await T(e);return Ve(o(a))},async loadProvider(a,l){let f=Ye("provider",l?.include),b=await T(e);return $e(o(b),a,f)},async loadProviderService(a,l){let f=await T(e);return _e(o(f),a,l)},async loadCredentials(){let a=await T(e);return Ue(o(a))},async loadCredentialTypes(a){let l=await T(e);return Je(o(l),a)}},w=Te(e,{onApplied:n.onApplied,cache:r}),d={async writeAppIntegration(a,l){await w.warmup();let f=await T(e);return i(f),u(()=>w.applyApp(a,l))},async writeModuleIntegration(a,l,f){await w.warmup();let b=await T(e);return i(b),u(()=>w.applyModule(a,l,f))},async writeServiceIntegration(a,l,f){await w.warmup();let b=await T(e);return i(b),u(()=>w.applyService(a,l,f))},async deleteServiceIntegration(a){await w.warmup();let l=await T(e);return i(l),u(()=>w.deleteService(a))}},v={invalidate(){r.invalidate(),ve(e)},async resolveContracts(){return T(e)},walkManifests(){return I(e)},parseModuleDescriptor(a){return G(a)},loadProviderCatalogRaw(){return Ce(e)},async readIntegrationsConfig(){return J(e,r)},async writeIntegrationsConfig(a){await w.warmup();let l=await T(e);return i(l),u(()=>jt(e,a,r))},async ensureMockBindings(){await w.warmup();let a=await T(e);return i(a),u(()=>Me(e))},async evaluateIntegrationServices(a){await w.warmup();let l=await T(e);i(l);let f={resolveEffectiveService:p(l.module.resolveEffectiveService,"resolveEffectiveService"),buildSupplyLookup:p(l.module.buildSupplyLookup,"buildSupplyLookup"),moduleDomainOf:p(l.module.moduleDomainOf,"moduleDomainOf"),normalizeInstances:p(l.module.normalizeInstances,"normalizeInstances"),RESOURCE_TYPE_IDS:l.module.RESOURCE_TYPE_IDS??[]};return oe({...a,contracts:f})}};function I(a){return P(a,r)}return{...g,...d,...v}}function jt(e,n,r){let t=Ot.join(e,"config","integrations.json");$(t,`${JSON.stringify(n,null,2)}
8
- `),r.invalidate([t])}export{ee as APP_INTEGRATION_NODE_KEYS,A as AppToolkitError,L as SAFE_NAME_PATTERN,ot as assertValidModuleId,Re as buildPredicateAssembly,he as checkInstanceKeys,dt as collectDeclaredModules,ye as contractsNotResolvedMessage,Mt as createAppToolkit,me as createFileCache,Te as createWriteCore,vt as credentialArtifactExists,H as deepEqual,B as deriveStem,te as echoForRef,rn as ensureDir,Me as ensureMockBindings,oe as evaluateIntegrationServices,_n as expandEnvVars,mn as extractModuleIdFromSource,ve as invalidateContractsResolver,we as isControlledInlineProvider,fn as isValidModuleId,Ke as loadAppIntegrationSchemas,Pe as loadAppView,Je as loadCredentialTypesView,Ue as loadCredentialsView,Ne as loadModuleDetailView,ze as loadModuleIntegrationSchemas,je as loadModulesView,vn as loadProviderCatalog,Ce as loadProviderCatalogRaw,$e as loadProviderDetailView,_e as loadProviderServiceDetailView,Ve as loadProvidersView,De as loadServiceDetailView,We as loadServiceResolutionDetail,ne as loadServiceResolutionsView,ae as manifestPath,re as maskCredentialValues,Ge as moduleDependencySchema,en as moduleDescriptorSchema,He as pageContribSchema,G as parseModuleDescriptor,qe as providerSlotContribSchema,pn as readAppManifest,ke as readAppManifestFull,q as readCredentialFile,J as readIntegrationsConfig,Sn as readIntegrationsStrict,xe as reconcileOrphanCredentials,ln as refToEnvKey,tt as removeNpmModule,T as resolveContractsForApp,T as resolveContractsForAppExport,Be as resolveLayerIntegrationSchemas,Le as resolveServiceSummary,Xe as resourceNeedContribSchema,Qe as serviceNeedContribSchema,F as stemToFilePath,Kn as stemToRef,Ze as tabContribSchema,it as updateNpmModule,rt as upsertMiniappContainer,nt as upsertNpmModule,P as walkManifests,et as writeAppManifest,$ as writeAtomic,Se as writeCredentialFile};
1
+ import{a as Se,b as M,c as we}from"./chunk-KPD3LUH4.js";import{z as h}from"zod";var W=/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/,zn=h.object({cardType:h.string(),schemaVersion:h.number().optional()}),Ge=h.object({route:h.string(),component:h.string()}),Qe=h.object({route:h.string(),label:h.string().optional(),icon:h.string().optional(),order:h.number().optional()}),Xe=h.object({id:h.string(),range:h.string().optional(),required:h.boolean().default(!0)}),en=h.object({service:h.string(),provider:h.string().regex(W,"provider 名含非法字符(需 /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/)"),implementation:h.string(),credentialType:h.string(),local:h.boolean().optional(),configSchema:h.string().optional(),credentialSchema:h.string().optional()}),nn=h.object({service:h.string(),optional:h.boolean().default(!0),defaults:h.array(h.object({provider:h.string().regex(W,"provider 名含非法字符(需 /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/)"),implementation:h.string()})).default([]),title:h.string().optional(),description:h.string().optional()}),tn=h.object({id:h.string(),type:h.string()}),rn=h.object({schemaVersion:h.number().default(1),name:h.string(),version:h.string().default("0.0.0"),kind:h.enum(["platform","business","third-party"]).default("business"),risk:h.object({level:h.enum(["high","medium","low"]).default("low"),writeBoundary:h.enum(["sdk-enforced","source"]).default("source")}).default({}),distribution:h.object({defaultMode:h.enum(["hybrid","sdk","codegen","local"]).default("codegen")}).default({}),contributes:h.object({handlers:h.array(h.string()).default([]),tools:h.array(h.string()).default([]),cards:h.array(zn).default([]),routes:h.array(h.string()).default([]),pages:h.array(Ge).default([]),tabs:h.array(Qe).default([]),providers:h.object({slots:h.array(en).default([])}).default({}),services:h.array(nn).default([]),resources:h.array(tn).default([])}).default({}),dependencies:h.object({modules:h.array(Xe).default([])}).default({}),env:h.array(h.string()).default([])}).strict();function G(e){let n=rn.safeParse(e);return n.success?{ok:!0,value:n.data}:{ok:!1,errors:n.error.issues.map(r=>`${r.path.join(".")||"(root)"}: ${r.message}`)}}var Un=/\$\$?\{([A-Z][A-Z0-9_]*)\}/g;function Jn(e){return JSON.stringify(e).slice(1,-1)}function Yn(e,n=process.env){let r=[],t=e.replace(Un,(i,o)=>{if(i.startsWith("$$"))return i.slice(1);let s=n[o];return s===void 0?(r.push(o),i):Jn(s)});return r.length>0?{missing:r}:{text:t,missing:[]}}import{mkdirSync as Hn,existsSync as on,readFileSync as Zn,writeFileSync as qn}from"fs";import{dirname as Gn,join as sn}from"path";function oe(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 A=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 he(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 se(e,n){if(n!==void 0&&(n.includes("/")||n.includes("\\")||n.includes("..")))throw new A("VALIDATION_FAILED",400,`凭据 stem 派生输入含路径敌对字符(${e})——拒绝派生`)}function z(e){if(se("provider",e.provider),se("service",e.service),se("instanceId",e.instanceId),se("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 Qn(e){return`secret://${e}`}function D(e){return`config/credentials/${e}.json`}function Q(e,n){let r=sn(e,D(n));if(!on(r))return null;try{let t=JSON.parse(Zn(r,"utf8"));if(typeof t.type!="string")return null;let{type:i,...o}=t,s={};for(let[f,u]of Object.entries(o))typeof u=="string"&&(s[f]=u);return{type:i,values:s}}catch{return null}}function Re(e,n,r){let t=sn(e,D(n)),i=on(t);return Hn(Gn(t),{recursive:!0}),qn(t,`${JSON.stringify({type:r.type,...r.values},null,2)}
2
+ `,"utf8"),i}import{mkdirSync as Xn,renameSync as et,writeFileSync as nt}from"fs";import{dirname as tt}from"path";function _(e,n){an(tt(e));let r=`${e}.tmp-${process.pid}-${Date.now()}`;nt(r,n,"utf8"),et(r,e)}function an(e){Xn(e,{recursive:!0})}function L(e){let n=e.indexOf(".");return n===-1?e:e.slice(0,n)}function F(e,n){let r=e?.domains?.[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 U(e,n){let r=[...new Set((n.descriptor.contributes.services??[]).map(o=>L(o.service)))].sort();if(r.length===0)return{writable:!1,reason:"zero-domain",domainKeys:[]};if(r.length>1)return{writable:!1,reason:"multi-domain",domainKeys:r};let t=r[0],i=new Set;for(let[o,s]of Object.entries(e.catalog.services))if(L(o)===t)for(let f of s.owners)i.add(f);return i.size>1?{writable:!1,reason:"shared-key",domainKeys:[t],domainKey:t,coOwners:[...i].sort()}:{writable:!0,domainKeys:[t],domainKey:t}}function cn(e,n){let r=e.find(t=>t.pkg===n||`@app/${t.id}`===n);return r?r.id:n.startsWith("@app/")?n.slice(5):n}function ln(e,n){return[...new Set(Object.values(e.providers[n]??{}).flatMap(r=>r.services))].sort()}function ee(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 dn(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 Ie(e,n){let r=new Set(n),t=[],i=(o,s)=>{let f=dn(o,s,r);f&&t.push(f)};for(let o of Object.keys(e.configByInstance??{}))i(o,"configByInstance");for(let o of Object.keys(e.credentialRefByInstance??{}))i(o,"credentialRefByInstance");for(let[o,s]of Object.entries(e.services??{}))for(let f of Object.keys(s.instances??{}))i(f,`services.${o}.instances`);return t}function ae(e){let n=[],r=e.contracts,{integrations:t,suppliedProviders:i,demandedServices:o,supplies:s,malls:f,credentialSchemaMissing:u,vendorConfigKeys:p,vendorConfigSchemaMissing:v,credentialFileMissing:S,credentialFileType:d,realmSwitchHints:y,moduleResourceNeeds:R}=e,a=f?new Set(f):void 0;for(let c of y??[])n.push({severity:"warning",code:"REALM_SWITCH_HINT",message:c});let l=new Set(Object.keys(i).map(c=>c.slice(0,c.indexOf("\0"))).filter(c=>c.length>0)),g=(c,w,x,k)=>{if(typeof x?.provider=="string"&&typeof x.implementation=="string"&&x.provider&&x.implementation)return i[X(x.provider,x.implementation)]?.credentialType;if(typeof w.provider=="string"&&typeof w.implementation=="string")return i[X(w.provider,w.implementation)]?.credentialType;let E=w.provider?.credentialType;if(typeof E=="string")return E;if(!s)return;let T=k??Object.keys(w.instances??{})[0]??"",O=r.resolveEffectiveService(t,c,T,s);if(!(O.status!=="ok"||typeof O.effective.provider!="string"))return i[X(O.effective.provider,O.effective.implementation)]?.credentialType};if(S||d)for(let[c,w]of Object.entries(t.services))for(let[x,k]of Object.entries(w.instances??{})){if(k.enabled===!1)continue;let E=k.credentialRef??w.credentialRef??t.credentialRefByInstance?.[x]??t.credentialRef;if(typeof E!="string"||!E.startsWith("secret://"))continue;let T=E.slice(9);S?.[T]===!0&&n.push({severity:"error",code:"CREDENTIAL_FILE_MISSING",service:c,instance:x,message:`integrations: 凭据文件缺失 ${T}(${c}@${x} effective ref=${E};档内 config/credentials/ 无此文件)`});let O=d?.[T];if(O){let P=g(c,w,k,x);P&&O!==P&&n.push({severity:"error",code:"CREDENTIAL_TYPE_MISMATCH",service:c,instance:x,message:`integrations: 凭据文件 ${T}.json type=${O} 与绑定 credentialType ${P} 不一致(${c}@${x}——transport 创建期将按 type 选策略)`})}}let b=(c,w)=>{if(!a)return;let x=dn(c,w,a);x&&n.push(x)};for(let[c]of Object.entries(t.configByInstance??{}))b(c,"configByInstance");for(let[c]of Object.entries(t.credentialRefByInstance??{}))b(c,"credentialRefByInstance");let C=Object.entries(t.services).filter(([,c])=>c.instances==null||c.instances["*"]!=null).map(([c])=>c);if(C.length>0){let c=Object.entries(t.services).filter(([,w])=>w.instances!=null&&w.instances["*"]==null).map(([w])=>w);c.length>0&&n.push({severity:"warning",code:"WILDCARD_ALIGNMENT",message:`integrations: 激活形态不对称(通配:${C.join(", ")};显式键集:${c.join(", ")})——动态 mallId 将在显式键集槽上 INSTANCE_NOT_FOUND(provider 业务限制表达位),确认是否齐步`})}let m=r.normalizeInstances({instances:t.instances,defaultInstanceId:t.defaultInstanceId});m.instances.length>=2&&m.defaultInstanceId===null&&n.push({severity:"warning",code:"MULTI_INSTANCE_NO_DEFAULT",message:`integrations: ${m.instances.length} 个部署实例(${m.instances.map(c=>c.id).join(", ")})均无 defaultInstanceId——无 scope 参数访问将落全局会话(默认商圈不注入)`});for(let[c,w]of Object.entries(t.services)){if(o[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 w.provider=="string"?typeof w.implementation=="string"&&!i[X(w.provider,w.implementation)]&&n.push({severity:"error",code:"INSTANCE_SUPPLY_UNMATCHED",service:c,message:`integrations: provider ${w.provider}/${w.implementation} 未命中已装供给(${c} 槽级)——装对应 provider 包或改绑`}):w.provider!==void 0&&!ee(w.provider)&&n.push({severity:"error",code:"INLINE_PROVIDER_INVALID",service:c,message:`integrations: 内联 provider 超受控形状(${c} 槽级;允许键 provider/credentialType/configSchema)`}),u){let k=g(c,w);k&&u[k]===!0&&n.push({severity:"error",code:"SCHEMA_FILE_MISSING",service:c,message:`integrations: credentialType ${k} 的 schema 引用不存在(${c};manifest 声明指向缺失文件)`})}typeof w.provider=="object"&&typeof w.implementation!="string"&&n.push({severity:"error",code:"IMPL_WITHOUT_PROVIDER",service:c,message:`integrations: 内联厂商声明必须同时提供 implementation(${c} 槽级)`});for(let[k,E]of Object.entries(w.instances??{})){b(k,`services.${c}.instances`);let T=E.provider!==void 0,O=E.implementation!==void 0;if(O&&!T&&n.push({severity:"error",code:"IMPL_WITHOUT_PROVIDER",service:c,instance:k,message:`integrations: 实例级 implementation 需伴随 provider(${c}@${k}——impl-only 禁止,provider 是绑定组头)`}),T&&O){let P=E.provider,V=E.implementation;typeof P=="string"&&typeof V=="string"?i[X(P,V)]||n.push({severity:"error",code:"INSTANCE_SUPPLY_UNMATCHED",service:c,instance:k,message:`integrations: 实例级 provider 覆盖 ${P}/${V} 未命中已装供给(${c}@${k})`}):ee(P)||n.push({severity:"error",code:"INLINE_PROVIDER_INVALID",service:c,instance:k,message:`integrations: 实例级内联 provider 超受控形状(${c}@${k})`})}}}for(let[c,w]of[["root",t.provider],...Object.entries(t.domains??{}).map(([x,k])=>[`domains.${x}`,k?.provider])])typeof w!="string"||w.length===0||l.has(w)||n.push({severity:"error",code:"VENDOR_NOT_INSTALLED",module:c.startsWith("domains.")?c.slice(8):void 0,message:`integrations: ${c} provider ${w} 未命中已装供给——装对应 provider 包或 provider use 改绑`});if(s)for(let[c,w]of Object.entries(t.services)){let x=w.instances?Object.keys(w.instances):[""];for(let k of x){let E=r.resolveEffectiveService(t,c,k,s);E.status==="binding-unresolved"&&n.push({severity:"error",code:"BINDING_UNRESOLVED",service:c,instance:k||void 0,message:`integrations: ${E.message}`})}}for(let[c,w]of Object.entries(t.services))w.implementation!==void 0&&w.provider===void 0&&n.push({severity:"error",code:"IMPL_WITHOUT_PROVIDER",service:c,message:`integrations: 槽级 implementation 需伴随 provider(${c}——impl-only 禁止,provider 是绑定组头)`});let I=new Set([...Object.keys(t.services).map(c=>r.moduleDomainOf(c)),...Object.keys(o).map(c=>r.moduleDomainOf(c))]);for(let c of Object.keys(t.domains??{}))I.has(c)||n.push({severity:"warning",code:"DOMAIN_KEY_UNMATCHED",module:c,message:`integrations: domains.${c} 无对应槽位或需求声明(域前缀拼写错误?——键 = 槽位 id 点分前缀)`});if(p){let c=new Set,w=!1,x=k=>{typeof k!="string"||k.length===0||(p[k]&&c.add(k),!p[k]&&!v?.[k]&&(w=!0),v?.[k]&&(w=!0))};x(t.provider);for(let k of Object.values(t.domains??{}))x(k?.provider);for(let k of Object.values(t.services)){let E=k.provider;x(typeof k.provider=="string"?k.provider:E?.provider)}if(c.size>0&&!w){let k=new Set;for(let T of c)for(let O of p[T]??[])k.add(O);let E=(T,O,P)=>{for(let[V]of Object.entries(T??{}))(P??k).has(V)||n.push({severity:"error",code:"DOMAIN_CONFIG_INVALID",message:`integrations: ${O} 键 ${V} 不在引用厂商(${[...c].join("/")})任何槽 schema properties 内(死配置)`})};E(t.config,"root.config");for(let[T,O]of Object.entries(t.configByInstance??{}))E(O,`root.configByInstance[${T}]`);for(let[T,O]of Object.entries(t.domains??{})){if(!O?.config)continue;let P=F(t,T).provider??void 0;if(P===void 0){E(O.config,`domains.${T}.config`);continue}let V=p[P];!V||v?.[P]||E(O.config,`domains.${T}.config`,new Set(V))}}}for(let[c,w]of Object.entries(o)){let x=t.services[c];if(!x){n.push({severity:"warning",code:"SLOT_NOT_CONFIGURED",service:c,message:`integrations: 服务槽 ${c}(需求方 ${w.owners.join(", ")})未配置${w.optional?"(可选槽)":"(必需槽——模块将走降级链)"}`});continue}let k=Object.entries(x.instances??{}).filter(([,E])=>E.enabled===!1).map(([E])=>E);k.length>0&&n.push({severity:"warning",code:"INSTANCE_DISABLED",service:c,instance:k.join(", "),message:`integrations: ${c} 实例禁用(${k.join(", ")})`})}for(let[c,w]of Object.entries(t.modules??{})){let x=R?.[c];R&&!(c in R)&&n.push({severity:"warning",code:"RESOURCE_NOT_DECLARED",module:c,message:`integrations: modules.${c} 未命中已装模块(键 = install id——检查 .tbox/app.json entry.id / packages/ 目录名)`});for(let[k,E]of Object.entries(w?.resources??{})){let T=E?.type;(typeof T!="string"||!r.RESOURCE_TYPE_IDS.includes(T))&&n.push({severity:"error",code:"RESOURCE_TYPE_UNKNOWN",module:c,message:`integrations: modules.${c}.resources.${k} type 非法(${String(T)};词汇表 = ${r.RESOURCE_TYPE_IDS.join("/")})`}),x&&x.size>0&&!x.has(k)&&n.push({severity:"warning",code:"RESOURCE_NOT_DECLARED",module:c,message:`integrations: modules.${c}.resources.${k} 未被模块 manifest contributes.resources 声明`})}}return n}function X(e,n){return`${e}\0${n}`}import{existsSync as ke,readFileSync as rt,readdirSync as it}from"fs";import{join as ce}from"path";function pn(e){return e.replaceAll("-","_").toUpperCase()}function un(e){if(!ke(e))return null;try{let n=JSON.parse(rt(e,"utf8"));return n&&typeof n=="object"?n:null}catch{return null}}function ot(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 be(e,n,r,t=process.env){let i={};for(let[m,I]of Object.entries(n.catalog.providers))for(let[c,w]of Object.entries(I))i[`${m}\0${c}`]={services:[...w.services],owner:w.owner,credentialType:w.credentialType};let o={};for(let[m,I]of Object.entries(n.catalog.services))o[m]={optional:I.optional,owners:[...I.owners]};let s={},f={},u={},p={};for(let m of n.modules){p[m.id]=new Set((m.descriptor.contributes.resources??[]).map(I=>I.id));for(let I of m.descriptor.contributes.providers?.slots??[]){if(I.configSchema){let c=un(ce(m.dir,I.configSchema));if(c){let w=s[I.provider]??=new Set;for(let x of ot(c))w.add(x)}else f[I.provider]=!0}I.credentialSchema&&!ke(ce(m.dir,I.credentialSchema))&&(u[I.credentialType]=!0)}}let v={},S=new Set,d=ce(e,"config","credentials");if(ke(d))for(let m of it(d)){if(!m.endsWith(".json"))continue;let I=m.slice(0,-5);S.add(I);let c=un(ce(d,m));c&&typeof c.type=="string"&&(v[I]=c.type)}let y=r,R=[],a=m=>{typeof m=="string"&&m.startsWith("secret://")&&R.push(m)};for(let m of Object.values(y.services??{}))if(m&&typeof m=="object"){a(m.credentialRef);for(let I of Object.values(m.instances??{}))I&&typeof I=="object"&&a(I.credentialRef)}for(let m of Object.values(y.credentialRefByInstance??{}))a(m);a(y.credentialRef);let l={};for(let m of R){let I=m.slice(9);t[pn(I)]===void 0&&(S.has(I)||(l[I]=!0))}let g=[];for(let[m,I]of Object.entries(y.services??{})){let c=I&&typeof I=="object"&&typeof I.provider=="string"?I.provider:void 0;for(let[w,x]of Object.entries((I&&typeof I=="object"?I.instances:void 0)??{})){let k=x&&typeof x=="object"&&typeof x.provider=="string"?x.provider:void 0;c&&k&&k!==c&&g.push(`integrations: ${m}@${w} 实现覆盖跨厂商(${c} → ${k})——凭据域切换,确认该 mall 对应凭据在场`)}}let C=((Array.isArray(y.instances)?y.instances:void 0)??[]).map(m=>m&&typeof m=="object"&&typeof m.id=="string"?m.id:void 0).filter(m=>typeof m=="string");return{suppliedProviders:i,demandedServices:o,credentialFileMissing:l,credentialFileType:v,credentialSchemaMissing:u,vendorConfigKeys:s,vendorConfigSchemaMissing:f,realmSwitchHints:g,moduleResourceNeeds:p,...C.length>0?{malls:C}:{}}}import{existsSync as $,readdirSync as Ce,readFileSync as J}from"fs";import{join as j}from"path";import{existsSync as st,readFileSync as fn,mkdirSync as at,writeFileSync as ct}from"fs";import gn from"path";function le(e){return gn.join(e,".tbox","app.json")}function mn(e){let n=le(e);if(!st(n))return null;try{let r=JSON.parse(fn(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 lt(e,n){let r=le(e);at(gn.dirname(r),{recursive:!0}),ct(r,`${JSON.stringify(n,null,2)}
3
+ `,"utf8")}function Ae(e){let n=mn(e);if(n===null)return null;let r=le(e);try{let t=JSON.parse(fn(r,"utf8"));return{...n,miniappContainers:Array.isArray(t?.miniappContainers)?t.miniappContainers:[]}}catch{return{...n,miniappContainers:[]}}}function dt(e,n){let r=e.npmModules.filter(t=>t.id!==n.id);return{...e,npmModules:[...r,n]}}function ut(e,n){return{...e,npmModules:e.npmModules.filter(r=>r.id!==n)}}function pt(e,n){let r=(e.miniappContainers??[]).filter(t=>t.id!==n.id);return{...e,miniappContainers:[...r,n]}}function ft(e,n,r){return{...e,npmModules:e.npmModules.map(t=>t.id===n?{...t,...r}:t)}}function vn(e){return/^[a-z0-9]+(-[a-z0-9]+)*$/.test(e)&&!e.includes("..")}function gt(e,n){if(!vn(e))throw new Error(`非法模块 id "${e}"(来自 ${n}):仅允许小写字母/数字/中划线`)}function de(e,n){let r=t=>{try{let i=JSON.parse(t),o=G(i);if(o.ok)return{kind:"strict",name:o.value.name,version:o.value.version,descriptor:o.value,contributes:o.value.contributes};if(i&&typeof i=="object"&&"contributes"in i){let s=i;return{kind:"loose",...typeof s.name=="string"?{name:s.name}:{},contributes:{providers:s.contributes?.providers,services:s.contributes?.services}}}return null}catch{return null}};if(n)return n.read(e,r)??null;if(!$(e))return null;try{return r(J(e,"utf8"))}catch{return null}}function mt(e){let n=j(e,".tbox","app.json");if(!$(n))return[];try{let r=JSON.parse(J(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 vt(e){let n=j(e,".tbox-dev.local"),r=j(n,"dev-manifest.json");if(!$(r))return[];try{let t=JSON.parse(J(r,"utf8")),i=[];for(let[o,s]of Object.entries(t.redirects??{}))typeof s!="string"||!o.startsWith("@tbox.cn/app-")||i.push({pkg:o,dir:j(n,s)});return i}catch{return[]}}function yt(e,n){let r=[],t=[e];for(let o of["apps","packages"]){let s=j(e,o);if($(s))try{for(let f of Ce(s,{withFileTypes:!0}))f.isDirectory()&&t.push(j(s,f.name))}catch{}}let i=new Set;for(let o of t){let s=j(o,"node_modules","@tbox.cn");if(!$(s))continue;let f=[];try{f=Ce(s)}catch{continue}for(let u of f){let p=j(s,u);if(i.has(p))continue;i.add(p);let v=j(p,"service-slots.json");if(!$(v))continue;let S=y=>{try{let R=JSON.parse(y);if(Array.isArray(R.slots))return R.slots.filter(a=>typeof a=="string")}catch{}return null},d=n?n.read(v,S):S(J(v,"utf8"));d!=null&&r.push({dir:p,slots:d})}}return r}function N(e,n){let r=[],t={providers:{},services:{},credentialTypes:{}},i={},o=[],s=new Set,f=new Map,u=(d,y,R)=>{for(let a of d){let l=t.providers[a.provider]??={},g=l[a.implementation];g?g.services.includes(a.service)||g.services.push(a.service):(l[a.implementation]={provider:a.provider,implementation:a.implementation,credentialType:a.credentialType,owner:y,...a.local?{local:!0}:{},...a.configSchema?{configSchema:a.configSchema}:{},...a.credentialSchema?{credentialSchema:a.credentialSchema}:{},services:[a.service]},t.credentialTypes[a.credentialType]??={owner:y,packageDir:R,...a.credentialSchema?{credentialSchema:a.credentialSchema}:{}});let b=`${a.provider}\0${a.service}`;i[b]||(i[b]={...a.configSchema?{configSchema:a.configSchema}:{},...a.credentialSchema?{credentialSchema:a.credentialSchema}:{},packageDir:R})}},p=(d,y)=>{let R=d.optional!==!1,a=d.defaults??[],l=t.services[d.service];if(l){l.optional=l.optional&&R;let C=new Set(l.defaults.map(m=>`${m.provider}\0${m.implementation}`));for(let m of a){let I=`${m.provider}\0${m.implementation}`;C.has(I)||(l.defaults.push(m),C.add(I))}l.owners.includes(y)||l.owners.push(y);return}t.services[d.service]={optional:R,defaults:[...a],...d.title?{title:d.title}:{},...d.description?{description:d.description}:{},owners:[y]};let g=d.service.includes(".")?d.service.slice(0,d.service.indexOf(".")):d.service,b=f.get(g);b===void 0?f.set(g,y):b!==y&&o.push({severity:"warning",code:"DOMAIN_KEY_CONFLICT",module:y,message:`域键 ${g} 被多模块声明(${b} 与 ${y})——domains 换算歧义(P13)`})};for(let d of mt(e)){if(s.has(d.id))continue;let y=j(e,"packages",d.id),R=j(e,"node_modules",...d.package.split("/")),a=de(j(y,"tbox.module.json"),n)??de(j(R,"tbox.module.json"),n);if(!a)continue;s.add(d.id);let l=$(j(y,"tbox.module.json"))?y:R,g=a.contributes;a.kind==="strict"&&r.push({id:d.id,dir:l,pkg:d.mode==="sdk"?d.package:`@app/${d.id}`,descriptor:a.descriptor});let b=g.providers?.slots??[];b.length&&u(b,d.package,l);let C=g.services??[];if(C.length)for(let m of C)p(m,d.package)}for(let{pkg:d,dir:y}of vt(e)){let R=de(j(y,"tbox.module.json"),n);if(!R?.name||s.has(R.name))continue;s.add(R.name);let a=R.contributes.providers?.slots??[];a.length&&u(a,d,y);let l=R.contributes.services??[];if(l.length)for(let g of l)p(g,d)}let v=j(e,"packages");if($(v)){let d=[];try{d=Ce(v,{withFileTypes:!0}).filter(y=>y.isDirectory()).map(y=>y.name)}catch{}for(let y of d){if(s.has(y))continue;let R=j(v,y),a=de(j(R,"tbox.module.json"),n);if(!a)continue;let l=a.name??y;if(s.has(l))continue;s.add(l);let g=a.contributes;a.kind==="strict"&&r.push({id:l,dir:R,pkg:`@app/${l}`,descriptor:a.descriptor});let b=g.providers?.slots??[];b.length&&u(b,`@app/${l}`,R);let C=g.services??[];if(C.length)for(let m of C)p(m,`@app/${l}`)}}let S=new Set;for(let d of yt(e,n))for(let y of d.slots)S.add(y);return{modules:r,catalog:t,serviceSchemas:i,vocabulary:[...S].sort(),domainKeyIssues:o}}function yn(e,n,r){let t=j(e,"src",n,"index.ts");if(!$(t))return!1;try{let i=J(t,"utf8");return new RegExp(`export\\s+const\\s+${r}\\b`).test(i)}catch{return!1}}function St(e){let n=j(e,"src","server","index.ts");if(!$(n))return"";try{return J(n,"utf8")}catch{return""}}function Sn(e){return e.match(/declaration\s*:\s*\{[\s\S]*?moduleId\s*:\s*['"]([^'"]+)['"]/)?.[1]}function wt(e){let n=[],r=N(e),t=Ae(e),i=new Map;for(let o of t?.npmModules??[])i.set(o.id,o.mode);for(let o of r.modules){let s=i.get(o.id)??"local",f=yn(o.dir,"server","serverModule"),u=o.descriptor.contributes;n.push({id:o.id,pkg:s==="sdk"?o.pkg:`@app/${o.id}`,mode:s,hasServerEntry:f,hasClientEntry:yn(o.dir,"client","clientModule"),hasCards:(u.cards?.length??0)>0,...f?{moduleId:Sn(St(o.dir))}:{}})}return n.sort((o,s)=>o.id.localeCompare(s.id))}import{existsSync as kr,readFileSync as br}from"fs";import{join as Cr,resolve as xr}from"path";function xe(e){return N(e).catalog}function wn(e){let n=N(e).catalog,r={};for(let[o,s]of Object.entries(n.providers)){r[o]={};for(let[f,u]of Object.entries(s))r[o][f]={provider:u.provider,implementation:u.implementation,credentialType:u.credentialType,owner:u.owner,...u.local?{local:!0}:{},...u.configSchema?{configSchema:u.configSchema}:{},...u.credentialSchema?{credentialSchema:u.credentialSchema}:{},services:[...u.services]}}let t={};for(let[o,s]of Object.entries(n.services))t[o]={optional:s.optional,defaults:s.defaults.map(f=>({...f})),owners:[...s.owners]};let i={};for(let[o,s]of Object.entries(n.credentialTypes))i[o]={owner:s.owner,...s.credentialSchema?{credentialSchema:s.credentialSchema}:{}};return{providers:r,services:t,credentialTypes:i}}import{existsSync as ht,readFileSync as Rt}from"fs";import{join as hn}from"path";var It=hn("config","integrations.json");function Y(e,n){let r=hn(e,It),t=i=>JSON.parse(i);if(n)return n.read(r,t)??null;if(!ht(r))return null;try{return t(Rt(r,"utf8"))}catch{return null}}async function Rn(e,n){let r=await M(e),t=Y(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 o=i.issues.filter(s=>Array.isArray(s.path)).map(s=>s.path.map(String).join(".")).filter(s=>s.length>0);throw new A("VALIDATION_FAILED",400,"integrations.json 校验失败",o.length>0?o:void 0)}throw new A("VALIDATION_FAILED",400,i instanceof Error?i.message:String(i))}return{config:t,strict:!1,contracts:r}}function ne(e,n,r){return e.includes(r)||n.includes(r)}import{existsSync as Cn,readFileSync as xn}from"fs";import{join as H,resolve as Ct}from"path";import xt from"ajv";var te=["provider","config","configByInstance","credentialRef","credentialRefByInstance","instances","defaultInstanceId"];import{readdirSync as kt,existsSync as ue,readFileSync as bt}from"fs";import{join as pe}from"path";function In(e,n,r){let t=[];if(n){let i=z({provider:e});t.push({stem:i,ref:`secret://${i}`,input:n})}for(let[i,o]of Object.entries(r??{})){let s=z({provider:e,instanceId:i});t.push({instanceId:i,stem:s,ref:`secret://${s}`,input:o})}return t}function kn(e,n,r,t,i){let o=[];if(t){let s=z({provider:e,service:n});o.push({stem:s,ref:`secret://${s}`,input:t})}for(let[s,f]of Object.entries(i??{})){let u=z({provider:e,instanceId:s,domain:r});o.push({instanceId:s,stem:u,ref:`secret://${u}`,input:f})}return o}function Oe(e,n,r){return n.map(t=>({stem:t.stem,ref:t.ref,overwrote:r?ue(pe(e,D(t.stem))):Re(e,t.stem,t.input)}))}function At(e,n){return ue(pe(e,D(n)))}function Ee(e,n){if(typeof e=="string"){e.startsWith("secret://")&&n.add(e.slice(9));return}if(Array.isArray(e)){for(let r of e)Ee(r,n);return}if(e&&typeof e=="object")for(let r of Object.values(e))Ee(r,n)}function Me(e){let n=pe(e,"config","credentials"),r=new Set,t=pe(e,"config","integrations.json");if(ue(t))try{Ee(JSON.parse(bt(t,"utf8")),r)}catch{}let i=[];if(!ue(n))return i;let o=[];try{o=kt(n).filter(s=>s.endsWith(".json")).map(s=>s.slice(0,-5))}catch{return i}for(let s of o.sort()){if(r.has(s))continue;let f=Q(e,s);i.push({severity:"warning",code:"ORPHANED_CREDENTIAL",message:`${D(s)} 不再被引用(凭据文件保留,可手动清理)`})}return i}var B=H("config","integrations.json");function Z(e,n){if(e===n)return!0;if(Array.isArray(e)&&Array.isArray(n))return e.length!==n.length?!1:e.every((r,t)=>Z(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=>Z(e[i],n[i]))}return!1}function me(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"&&!W.test(t))throw new A("VALIDATION_FAILED",400,`${r} 名含非法字符(需 /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/)`,[`${n}.${r}`]);me(t,`${n}.${r}`)}}function fe(e,n,r){if(!(!e||typeof e!="object"||Array.isArray(e))){for(let t of Object.keys(e))if(!(r&&(t==="*"||t==="**"))&&!W.test(t))throw new A("VALIDATION_FAILED",400,`${n} 键 ${t} 含非法字符(需 /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/)——进凭据 stem 派生,防路径逃逸`,[n])}}function bn(e,n,r){if(r==="root"){let t=e.instances;Array.isArray(t)&&t.forEach((i,o)=>{let s=i&&typeof i=="object"?i.id:void 0;if(typeof s=="string"&&!W.test(s))throw new A("VALIDATION_FAILED",400,`instances[${o}].id 含非法字符(需 /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/)`,[`root.instances[${o}].id`])}),fe(e.configByInstance,"root.configByInstance",!1),fe(e.credentialRefByInstance,"root.credentialRefByInstance",!1)}else fe(e.instances,"services.instances",!0);fe(n.credentialsByInstance,"credentialsByInstance",!1)}function ge(e,n){let r=H(e,B),t=i=>JSON.parse(i);if(n)return n.read(r,t)??null;if(!Cn(r))return null;try{return t(xn(r,"utf8"))}catch{return null}}function Te(e){let n=(e.instances??[]).map(r=>r.id);return n.length===0?[]:Ie(e,n)}function Et(e,n,r,t){let{catalog:i}=N(e,t),o=i.providers[n];if(!o)return;let s=new Set;for(let f of Object.values(o))(r===void 0||f.services.includes(r))&&s.add(f.credentialType);return s.size===1?[...s][0]:void 0}function An(e,n,r,t,i,o){if(typeof t.type!="string"||t.type.length===0)throw new A("VALIDATION_FAILED",400,"凭据 type 缺失或为空字符串",["credentials.type"]);let s=i??Et(e,n,r,o);if(s!==void 0&&s!=="-"&&t.type!==s)throw new A("VALIDATION_FAILED",400,`凭据 type=${t.type} 与绑定 credentialType ${s} 不一致`,["credentials.type"]);if(r===void 0)return;let{serviceSchemas:f}=N(e,o),u=f[`${n}\0${r}`];if(!u?.credentialSchema)return;let p=Ct(u.packageDir,u.credentialSchema);if(Cn(p))try{let S=new xt({allErrors:!0}).compile(JSON.parse(xn(p,"utf8")));if(!S({type:t.type,...t.values})){let d=(S.errors??[]).map(y=>`credentials.values.${String(y.instancePath||y.params?.missingProperty||"").replace(/^\//,"")}`);throw new A("VALIDATION_FAILED",400,"凭据字段校验失败(ajv 字段级)",d)}}catch(v){if(v instanceof A)throw v}}function je(e,n={}){let{onApplied:r,cache:t}=n;function i(p,v,S,d){let y=p!==null,R=v.length>0,a=!d&&y,l=!d&&R;a&&(_(H(e,B),`${JSON.stringify(p,null,2)}
4
+ `),t?.invalidate([H(e,B)]));let g=a||l,b=g&&r!==void 0;b&&r?.();let C=[];return y&&C.push(B),R&&C.push(...v.map(m=>D(m.stem))),{written:g,restartScheduled:b,files:C,credentials:v,issues:S}}let o;async function s(){o=await M(e)}function f(p,v){return p.filter(S=>Array.isArray(S.path)).map(S=>{let d=S.path.map(String).join(".");return v!==""&&d.startsWith(v)&&d.length>v.length?d.slice(v.length):d}).filter(S=>S.length>0)}function u(p,v,S){let d=o;if(!d||!d.strictValidation||!d.module.parseIntegrationsConfig)throw new A("CONTRACTS_NOT_RESOLVED",503,"contracts 严格校验面不可用(需 ≥0.9)——写路径门控失败(工厂边缘断言应先行拦截)");try{d.module.parseIntegrationsConfig(p)}catch(y){throw y instanceof Error&&Array.isArray(y.issues)?new A("VALIDATION_FAILED",400,"节点 schema 校验失败",f(y.issues,S)):new A("VALIDATION_FAILED",400,y instanceof Error?y.message:String(y))}}return{warmup:s,applyApp(p,v={}){me(p,"root"),bn(p,v,"root");let S=[],d=ge(e,t),y=d??{services:{}};d===null&&S.push({severity:"warning",code:"SKELETON_MATERIALIZED",message:"config/integrations.json 缺席——已物化骨架(写时自动初始化;R13 语义翻转提示)"});let R={...y};for(let c of te)c in p||delete R[c];for(let[c,w]of Object.entries(p))R[c]=w;let a=typeof R.provider=="string"?R.provider:"app",l=In(a,v.credentials,v.credentialsByInstance);for(let c of l)An(e,a,void 0,c.input,void 0,t);let g=l.find(c=>c.instanceId===void 0);if(v.credentials&&g&&(R.credentialRef=g.ref),v.credentialsByInstance){let c={...R.credentialRefByInstance??{}};for(let w of l)w.instanceId!==void 0&&(c[w.instanceId]=w.ref);R.credentialRefByInstance=c}let b=v.credentials!==void 0||v.credentialsByInstance!==void 0,C=Z(d,R);if(C&&!b)return{written:!1,restartScheduled:!1,files:[],credentials:[],issues:S};u(R,S,"");let m=v.dryRun===!0,I=Oe(e,l,m);return S.push(...Te(R)),i(C?null:R,I,S,v.dryRun)},applyModule(p,v,S={}){me(v,"root");let{modules:d,catalog:y}=N(e,t),R=d.find(c=>c.id===p);if(!R)throw new A("MODULE_NOT_FOUND",404,`模块 ${p} 非已装模块`);let a=U({modules:d,catalog:y},R);if(!a.writable)throw a.reason==="multi-domain"?new A("VALIDATION_FAILED",400,`模块 ${p} 跨 ${a.domainKeys.length} 个域(${a.domainKeys.join("、")})——模块级统一配置仅支持单域模块,请按服务级配置(编辑各服务行)`):a.reason==="zero-domain"?new A("VALIDATION_FAILED",400,`模块 ${p} 无服务需求声明,无域配置位`):new A("VALIDATION_FAILED",400,`域键 ${a.domainKey} 由 ${a.coOwners.map(c=>cn(d,c)).join("、")} 共用——写通道拒绝歧义操作,请按服务级配置`);let l=a.domainKey,g=[],b=ge(e,t);if(b===null&&Object.keys(v).length===0)return{written:!1,restartScheduled:!1,files:[],credentials:[],issues:g};b===null&&g.push({severity:"warning",code:"SKELETON_MATERIALIZED",message:"config/integrations.json 缺席——已物化骨架(写时自动初始化;R13 语义翻转提示)"});let C=b??{services:{}},m={...C.domains??{}},I={...C,domains:m};return Object.keys(v).length===0?delete m[l]:m[l]={...v},Z(b,I)?{written:!1,restartScheduled:!1,files:[],credentials:[],issues:g}:(u(I,g,`domains.${l}.`),g.push(...Te(I)),i(I,[],g,S.dryRun))},applyService(p,v,S={}){me(v,"root"),bn(v,S,"slot");let d=[],y=ge(e,t);if(!ne(N(e,t).vocabulary,Object.keys(y?.services??{}),p))throw new A("SERVICE_NOT_FOUND",404,`服务 ${p} 不在服务词汇(已装契约包 ∪ 已配置)`);y===null&&d.push({severity:"warning",code:"SKELETON_MATERIALIZED",message:"config/integrations.json 缺席——已物化骨架(写时自动初始化;R13 语义翻转提示)"});let R=y??{services:{}},a={...R.services??{}},l={...R,services:a};a[p]={...v};let g=v.provider,b=g!==null&&typeof g=="object"?g:void 0,C=typeof g=="string"?g:typeof b?.provider=="string"?b.provider:"app",m=p.includes(".")?p.slice(0,p.indexOf(".")):p,I=kn(C,p,m,S.credentials,S.credentialsByInstance);for(let O of I)An(e,C,p,O.input,typeof b?.credentialType=="string"?b.credentialType:void 0,t);let c=a[p],w=I.find(O=>O.instanceId===void 0);if(S.credentials&&w&&(c.credentialRef=w.ref),S.credentialsByInstance){let O={...c.instances??{}};for(let P of I){if(P.instanceId===void 0)continue;let V={...O[P.instanceId]??{}};V.credentialRef=P.ref,O[P.instanceId]=V}c.instances=O}let x=S.credentials!==void 0||S.credentialsByInstance!==void 0,k=Z(y,l);if(k&&!x)return{written:!1,restartScheduled:!1,files:[],credentials:[],issues:d};u(l,d,`services.${p}.`);let E=S.dryRun===!0,T=Oe(e,I,E);return d.push(...Te(l)),i(k?null:l,T,d,S.dryRun)},deleteService(p){let v=[],S=ge(e,t);if(!ne(N(e,t).vocabulary,Object.keys(S?.services??{}),p))throw new A("SERVICE_NOT_FOUND",404,`服务 ${p} 不在服务词汇(已装契约包 ∪ 已配置)`);let d={...S?.services??{}};if(!(p in d))return{written:!1,restartScheduled:!1,files:[],credentials:[],issues:v};delete d[p];let y={...S??{services:{}},services:d};_(H(e,B),`${JSON.stringify(y,null,2)}
5
+ `),t?.invalidate([H(e,B)]),v.push(...Me(e));let R=r!==void 0;return R&&r?.(),{written:!0,restartScheduled:R,files:[B],credentials:[],issues:v}}}}import{existsSync as Ot}from"fs";import{join as Mt}from"path";function Pe(e){let n=Mt(e,"config","integrations.json");if(Ot(n))return{generated:!1,reason:"in-place",services:[]};let r=[];for(let o of N(e).modules)for(let s of o.descriptor.contributes.providers?.slots??[])s.local===!0&&r.push({service:s.service,provider:s.provider,implementation:s.implementation});if(r.length===0)return{generated:!1,reason:"no-local-slots",services:[]};let t={},i=new Set(r.map(o=>o.provider));if(i.size===1){let[o]=i;for(let s of r)t[s.service]={};_(n,`${JSON.stringify({provider:o,services:t},null,2)}
6
+ `)}else{for(let o of r)t[o.service]={provider:o.provider,implementation:o.implementation};_(n,`${JSON.stringify({services:t},null,2)}
7
+ `)}return{generated:!0,reason:"generated",services:r.map(o=>o.service).sort()}}function En(e){return e.replace(/^@tbox\.cn\/app-/,"").replace(/^@[^/]+\//,"")}function Tt(e){return En(e.id).startsWith("provider-")||En(e.pkg).startsWith("provider-")}function Ne(e){return{modules:e.walk.modules.filter(r=>!Tt(r)).map(r=>({id:r.id,name:r.descriptor.name,title:r.descriptor.name,description:""})).sort((r,t)=>r.id.localeCompare(t.id))}}function Ve(e,n){let r=e.walk.modules.find(u=>u.id===n);if(!r)throw new A("MODULE_NOT_FOUND",404,`模块 ${n} 非已装模块`);let t=(r.descriptor.contributes.services??[]).map(u=>({service:u.service,...u.title?{title:u.title}:{},...u.description?{description:u.description}:{},required:u.optional===!1})),i=U(e.walk,r),o=e.integrations?.domains??{},s=i.writable?o[i.domainKey]??null:null,f=i.domainKeys.map(u=>{let p=F(e.integrations,u);return{domain:u,effective:p.provider,layer:p.layer}});return{domainKeys:[...i.domainKeys],integration:s,providerBindings:f,configEditable:i.writable,services:t}}function On(e,n){let r=N(e.appDir,e.cache),t=Y(e.appDir,e.cache);return{appDir:e.appDir,walk:r,catalog:r.catalog,integrations:t,contracts:n}}function Mn(e){let n=new Set;for(let r of e.modules){for(let t of r.descriptor.contributes.services??[])n.add(t.service);for(let t of r.descriptor.contributes.providers?.slots??[])n.add(t.service)}return n}function ve(e,n,r){let t=e.providers[n];return t?Object.values(t).some(i=>i.services.includes(r)):!1}function Tn(e,n){let r=[];for(let[t,i]of Object.entries(e.providers))Object.values(i).some(o=>o.services.includes(n))&&r.push(t);return r.sort()}function De(e){let n=Mn(e.walk),r=e.walk.vocabulary.filter(o=>!n.has(o)).map(o=>({service:o,required:!1})),t=e.integrations,i=null;if(t){let o={};for(let s of te)s in t&&(o[s]=t[s]);i=o}return{services:r,integration:i}}function Fe(e,n){let r=e.integrations?.services??{},t=e.catalog.services[n];if(!ne(e.walk.vocabulary,Object.keys(r),n))throw new A("SERVICE_NOT_FOUND",404,`服务 ${n} 不在服务词汇(已装契约包 ∪ 已配置)`);let i=r[n]??null;return{service:n,...t?.title?{title:t.title}:{title:n},...t?.description?{description:t.description}:{},required:t?!t.optional:!1,defaults:t?t.defaults.map(o=>({...o})):[],integration:i,suppliedBy:Tn(e.catalog,n)}}import{existsSync as Nn,readFileSync as Vn,realpathSync as jn}from"fs";import{isAbsolute as jt,join as Pt,relative as Nt,resolve as Pn,sep as Vt}from"path";function $e(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(o=>o.local===!0),owner:i[0].owner})}return{providers:n.sort((r,t)=>r.provider.localeCompare(t.provider))}}function _e(e,n,r){let t=e.catalog.providers[n];if(!t)throw new A("PROVIDER_NOT_FOUND",404,`厂商 ${n} 不 ∈ catalog(内联声明厂商无包级档案——身份与表单经组合端点暴露)`);let i={};for(let s of Object.values(t))for(let f of s.services)(i[f]??={implementations:[]}).implementations.push({implementation:s.implementation,credentialType:s.credentialType});if(r?.has("integrationSchemas"))for(let[s,f]of Object.entries(i))f.integrationSchemas={configSchema:K(e,n,s)};let o=Object.values(t);return{provider:n,local:o.every(s=>s.local===!0),owner:o[0].owner,services:i}}function Le(e,n,r){let t=e.catalog.providers[n],i=e.integrations?.services??{},o=[];if(t)for(let p of Object.values(t))p.services.includes(r)&&o.push({implementation:p.implementation,credentialType:p.credentialType});let s=i[r]?.provider,f=s&&typeof s=="object"&&s.provider===n?s:void 0;if(o.length===0&&!f)throw t?new A("SUPPLY_NOT_FOUND",404,`厂商 ${n} 未供给服务 ${r}(AI 帮我实现流:PUT 显式绑定后实施)`):new A("PROVIDER_NOT_FOUND",404,`厂商 ${n} 完全未知(不 ∈ catalog 且无任何内联声明)`);o.length===0&&f&&o.push({implementation:i[r]?.implementation??`${n}-inline@1`,credentialType:f.credentialType});let u=K(e,n,r,f?s?.configSchema:void 0);return{provider:n,service:r,implementations:o,integrationSchemas:{configSchema:u}}}function K(e,n,r,t){let i=e.walk.serviceSchemas[`${n}\0${r}`];return i?We(e.appDir,i.packageDir,i.configSchema):typeof t=="string"?Dt(e.appDir,t):null}function We(e,n,r){if(!r)return null;let t=Pt(n,r);if(!Nn(t))return null;try{return JSON.parse(Vn(t,"utf8"))}catch{return null}}function Dt(e,n){let r=Pn(e,"config","schemas"),t=Pn(e,n),i=Nt(r,t);if(i===""||i.startsWith("..")||jt(i))throw new A("VALIDATION_FAILED",400,"configSchema 引用必须落在 config/schemas/ 内(禁路径逃逸)",["provider.configSchema"]);if(!Nn(t))return null;let o,s;try{o=jn(r),s=jn(t)}catch{return null}if(s!==o&&!s.startsWith(o+Vt))throw new A("VALIDATION_FAILED",400,"configSchema 引用经 symlink 逃逸出 config/schemas/(realpath 复核拒绝)",["provider.configSchema"]);try{return JSON.parse(Vn(t,"utf8"))}catch{return null}}function Dn(e){return{version:e.version,evaluation:e.evaluation,strictValidation:e.strictValidation,notes:[...e.notes]}}function Fn(e,n,r){let t=e.integrations,i=L(n),o=t?.services?.[n],s=o?.instances?.[r]??o?.instances?.["*"];return s&&s.provider!==void 0?"instance":o?.provider!==void 0?"service":F(t,i).layer==="module"?"module":typeof t?.provider=="string"&&t.provider.length>0?"app":null}function $n(e,n,r,t,i){let o=n.resolveEffectiveService(e.integrations,r,t,i);if(o.status==="ok"&&o.effective){let s=o.effective.provider,f=typeof s=="string"?s:String(s?.provider??"");return{status:"ok",provider:f,implementation:o.effective.implementation,effective:{provider:f,implementation:o.effective.implementation,...o.effective.config!==void 0?{config:{...o.effective.config}}:{},...o.effective.credentialRef!==void 0?{credentialRef:o.effective.credentialRef}:{},layer:Fn(e,r,t)??"app"}}}return o.status==="binding-unresolved"?{status:"binding-unresolved",statusMessage:o.message}:{status:o.status}}function Be(e){let n=e.contracts.module;if(!n.resolveEffectiveService||!n.normalizeInstances)throw new A("CONTRACTS_NOT_RESOLVED",503,"contracts 求值面缺席(契约包形态异常)——重新安装或升级应用 @tbox.cn/app-contracts 后重试");return n}function Ke(e,n){let r=Be(n),{integrations:t,catalog:i}=n,o=r.buildSupplyLookup(i),s=t,u=r.normalizeInstances({instances:s?.instances,defaultInstanceId:s?.defaultInstanceId}).defaultInstanceId??"*",p=$n(n,r,e,u,o),v=Fn(n,e,u),S=n.integrations?.services?.[e]?.provider,d=p.provider??(typeof S=="string"?S:typeof S=="object"&&S?String(S.provider):void 0),y=new Set(Object.keys(n.catalog.providers)),R=d!==void 0&&y.has(d)?Ft(n.catalog,d,e):void 0,a=i.services[e],l=a!==void 0?!a.optional:void 0,g=a?.owners[0];return{status:p.status,...p.statusMessage?{statusMessage:p.statusMessage}:{},...d!==void 0?{provider:d}:{},...d!==void 0&&v!==null?{layer:v}:{},...R!==void 0?{supplied:R}:{},...g!==void 0?{module:g}:{},...l!==void 0?{required:l}:{}}}function Ft(e,n,r){return ve(e,n,r)}function re(e,n,r){let t=new Set([...e.walk.vocabulary,...Object.keys(e.catalog.services)]),i=e.integrations?.services??{};for(let s of Object.keys(i))t.add(s);let o={};for(let s of[...t].sort())r&&!r.includes(s)||(o[s]=Ke(s,e));return{contracts:Dn(e.contracts),resolutions:o,issues:n}}function ze(e,n,r){let t=Be(n),i=t.buildSupplyLookup(n.catalog),o=n.integrations,f=t.normalizeInstances({instances:o?.instances,defaultInstanceId:o?.defaultInstanceId}).instances.map(a=>a.id),u=n.integrations?.services?.[e],p=u?.instances?Object.keys(u.instances):void 0,v;f.length>0?(v=[...f],p?.includes("*")&&v.push("*")):p!==void 0&&p.length>0?v=p.includes("*")?["*"]:p:v=[];let S=v.map(a=>{let l=$n(n,t,e,a,i);return{instanceId:a,status:l.status,...l.statusMessage?{statusMessage:l.statusMessage}:{},...l.effective?{effective:l.effective}:{}}}),d=$t(n,e),R={...Ke(e,n),instances:S,inheritance:d};return{contracts:Dn(n.contracts),resolution:R,issues:r.filter(a=>a.service===e)}}function $t(e,n){let r=e.integrations,t=L(n),i=r?.services?.[n],o=e.integrations,f=Be(e).normalizeInstances({instances:o?.instances,defaultInstanceId:o?.defaultInstanceId}).defaultInstanceId??"*",u=i?.instances?.[f]??i?.instances?.["*"],p=F(r,t);return[{layer:"app",...r?.provider?{provider:r.provider}:{}},{layer:"module",...p.layer==="module"&&p.provider?{provider:p.provider}:{}},{layer:"service",...typeof i?.provider=="string"?{provider:i.provider}:{},...i?.implementation?{implementation:i.implementation}:{}},{layer:"instance",...u?.provider?{provider:u.provider}:{},...u?.implementation?{implementation:u.implementation}:{}}]}function Ue(e,n,r){if(n===null)return null;let t={};for(let i of r)t[i]={configSchema:K(e,n,i)};return{provider:n,services:t}}function q(e){return e===null||typeof e!="object"?JSON.stringify(e??null):Array.isArray(e)?`[${e.map(q).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${q(e[r])}`).join(",")}}`}var _t="\0no-enum";function Lt(e){let n=e.enum;return Array.isArray(n)?`[${[...new Set(n.map(q))].sort().join(",")}]`:_t}function Wt(e){if(!e||typeof e!="object"||Array.isArray(e))return null;let n=e.type;return n===void 0?null:q(n)}function Bt(e){let n=e.map(t=>Wt(t.subschema));if(n.some(t=>t===null)||new Set(n).size>1)return null;if(n[0]==='"object"'){let t=q(e[0].subschema);return e.every(i=>q(i.subschema)===t)?e[0].subschema:null}return new Set(e.map(t=>Lt(t.subschema))).size===1?e[0].subschema:null}function _n(e,n){let r=[],t=!0,i=new Map;for(let[s,f]of Object.entries(e.services)){let u=f.configSchema;if(u===null){r.push(s);continue}if(!u||typeof u!="object"||Array.isArray(u))continue;let p=u;p.additionalProperties===!1&&(t=!1);let v=p.properties;if(!v||typeof v!="object"||Array.isArray(v))continue;let S=Array.isArray(p.required)?p.required:[];for(let d of Object.keys(v)){let y=i.get(d)??[];y.push({service:s,subschema:v[d],required:S.includes(d)}),i.set(d,y)}}let o=[];for(let[s,f]of i)o.push({key:s,schema:Bt(f),sources:f.map(({service:u,required:p})=>({service:u,required:p}))});return{provider:e.provider,schemaless:r,unsupplied:[...n?.unsupplied??[]],additionalPropertiesAllowed:t,fields:o}}function Ln(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 f=n.integrations?.provider;return typeof f=="string"&&f.length>0?f:null}let o=n.walk.modules.find(f=>f.id===r);if(!o)return null;let s=U(n.walk,o);return s.writable?i!==void 0?i:F(n.integrations,s.domainKey).provider:null}var Wn={integrationSchemas:null,integrationFieldRegistry:null};function Je(e,n){let r=Ln("app",e,void 0,n);if(r===null)return Wn;let t=Ue(e,r,ln(e.catalog,r));return{integrationSchemas:t,integrationFieldRegistry:_n(t)}}function Ye(e,n,r){let t=Ln("module",e,n,r),i=e.walk.modules.find(u=>u.id===n);if(t===null||!i)return Wn;let o=(i.descriptor.contributes.services??[]).map(u=>u.service),s=u=>ve(e.catalog,t,u),f=Ue(e,t,o.filter(s));return{integrationSchemas:f,integrationFieldRegistry:_n(f,{unsupplied:[...new Set(o.filter(u=>!s(u)))]})}}function Kt(e){return Je(e).integrationSchemas}function zt(e,n){return Ye(e,n).integrationSchemas}function He(e,n){let r=e.integrations?.services?.[n]?.provider;if(r===void 0||r===""){let t=F(e.integrations,L(n));return t.provider===null?null:{provider:t.provider,configSchema:K(e,t.provider,n)}}if(typeof r=="string")return{provider:r,configSchema:K(e,r,n)};if(ee(r)){let t=r;return{provider:t.provider,configSchema:K(e,t.provider,n,t.configSchema)}}return null}function ie(e,n){if(n===void 0||!n.startsWith("secret://"))return;let r=n.slice(9),t=Q(e,r);if(t)return{type:t.type,ref:n,file:D(r),masked:oe(t.values)}}function Ze(e){let n=e.integrations,r={credential:ie(e.appDir,typeof n?.credentialRef=="string"?n.credentialRef:void 0)??null,byInstance:{}};for(let{id:i}of n?.instances??[]){let o=n?.credentialRefByInstance?.[i];o!==void 0&&(r.byInstance[i]=ie(e.appDir,o)??null)}let t={};for(let[i,o]of Object.entries(n?.services??{})){let s={credential:ie(e.appDir,o.credentialRef)??null,byInstance:{}};for(let[f,u]of Object.entries(o.instances??{}))s.byInstance[f]=ie(e.appDir,u.credentialRef)??null;t[i]=s}return{app:r,services:t}}function qe(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?We(e.appDir,i.packageDir,i.credentialSchema):null}})}}import Ut from"path";var Jt={app:["serviceResolutions","integrationSchemas","integrationFieldRegistry"],module:["serviceResolutions","integrationSchemas","integrationFieldRegistry"],provider:["integrationSchemas"],service:["integrationSchemas"]};function ye(e,n){if(!n||n.length===0)return new Set;let r=Jt[e],t=[...new Set(n)].filter(i=>!r.includes(i));if(t.length>0)throw new A("VALIDATION_FAILED",400,`include 含未知或不适用于本端点的键:${t.join("、")}(白名单:${r.join("、")})`,["include"]);return new Set(n)}var Bn=["integrationSchemas","integrationFieldRegistry"];function Kn(e,n,r){if(!(typeof n!="string"||n.length===0)&&!Bn.some(t=>r.has(t)))throw new A("VALIDATION_FAILED",400,`参数 ${e} 需与表单 include 键(${Bn.join("、")})同现——轴参仅重定向表单层双投影`,[e])}function Yt(e,n={}){let r=Se(),t=Promise.resolve(),i={appDir:e,cache:r};function o(a){if(!a.strictValidation)throw new A("CONTRACTS_NOT_RESOLVED",503,he(a))}function s(a){return On(i,a)}async function f(){let a=await M(e),l=s(a),g=l.integrations;if(g===null)return[];let b={resolveEffectiveService:u(a.module.resolveEffectiveService,"resolveEffectiveService"),buildSupplyLookup:u(a.module.buildSupplyLookup,"buildSupplyLookup"),moduleDomainOf:u(a.module.moduleDomainOf,"moduleDomainOf"),normalizeInstances:u(a.module.normalizeInstances,"normalizeInstances"),RESOURCE_TYPE_IDS:a.module.RESOURCE_TYPE_IDS??[]},C=be(e,l.walk,g,process.env);return ae({contracts:b,integrations:g,supplies:b.buildSupplyLookup(l.catalog),...C})}function u(a,l){if(typeof a!="function")throw new A("CONTRACTS_NOT_RESOLVED",503,`contracts 求值面 ${l} 缺席(形态异常)`);return a}function p(a){let l=t.then(a,a);return t=l.catch(()=>{}),l}let v={async loadModules(){let a=await M(e);return Ne(s(a))},async loadModule(a,l){let g=ye("module",l?.include);Kn("moduleProvider",l?.moduleProvider,g);let b=await M(e),C=s(b),m=Ve(C,a);if(g.has("serviceResolutions")&&(m.serviceResolutions=b.evaluation&&b.strictValidation?await f().then(I=>re(C,I,m.services.map(c=>c.service))):null),g.has("integrationSchemas")||g.has("integrationFieldRegistry")){let I=Ye(C,a,l?.moduleProvider);g.has("integrationSchemas")&&(m.integrationSchemas=I.integrationSchemas),g.has("integrationFieldRegistry")&&(m.integrationFieldRegistry=I.integrationFieldRegistry)}return m},async loadApp(a){let l=ye("app",a?.include);Kn("appProvider",a?.appProvider,l);let g=await M(e),b=s(g),C=De(b);if(l.has("serviceResolutions")&&(C.serviceResolutions=g.evaluation&&g.strictValidation?await f().then(m=>re(b,m)):null),l.has("integrationSchemas")||l.has("integrationFieldRegistry")){let m=Je(b,a?.appProvider);l.has("integrationSchemas")&&(C.integrationSchemas=m.integrationSchemas),l.has("integrationFieldRegistry")&&(C.integrationFieldRegistry=m.integrationFieldRegistry)}return C},async loadService(a,l){let g=ye("service",l?.include),b=await M(e),C=s(b),m=Fe(C,a);return g.has("integrationSchemas")&&(m.integrationSchemas=He(C,a)),m},async loadServiceResolutions(a){let l=await M(e);o(l);let g=await f();return re(s(l),g,a)},async loadServiceResolution(a){let l=await M(e);o(l);let g=await f();return ze(a,s(l),g)},async loadProviders(){let a=await M(e);return $e(s(a))},async loadProvider(a,l){let g=ye("provider",l?.include),b=await M(e);return _e(s(b),a,g)},async loadProviderService(a,l){let g=await M(e);return Le(s(g),a,l)},async loadCredentials(){let a=await M(e);return Ze(s(a))},async loadCredentialTypes(a){let l=await M(e);return qe(s(l),a)}},S=je(e,{onApplied:n.onApplied,cache:r}),d={async writeAppIntegration(a,l){await S.warmup();let g=await M(e);return o(g),p(()=>S.applyApp(a,l))},async writeModuleIntegration(a,l,g){await S.warmup();let b=await M(e);return o(b),p(()=>S.applyModule(a,l,g))},async writeServiceIntegration(a,l,g){await S.warmup();let b=await M(e);return o(b),p(()=>S.applyService(a,l,g))},async deleteServiceIntegration(a){await S.warmup();let l=await M(e);return o(l),p(()=>S.deleteService(a))}},y={invalidate(){r.invalidate(),we(e)},async resolveContracts(){return M(e)},walkManifests(){return R(e)},parseModuleDescriptor(a){return G(a)},loadProviderCatalogRaw(){return xe(e)},async readIntegrationsConfig(){return Y(e,r)},async writeIntegrationsConfig(a){await S.warmup();let l=await M(e);return o(l),p(()=>Ht(e,a,r))},async ensureMockBindings(){await S.warmup();let a=await M(e);return o(a),p(()=>Pe(e))},async evaluateIntegrationServices(a){await S.warmup();let l=await M(e);o(l);let g={resolveEffectiveService:u(l.module.resolveEffectiveService,"resolveEffectiveService"),buildSupplyLookup:u(l.module.buildSupplyLookup,"buildSupplyLookup"),moduleDomainOf:u(l.module.moduleDomainOf,"moduleDomainOf"),normalizeInstances:u(l.module.normalizeInstances,"normalizeInstances"),RESOURCE_TYPE_IDS:l.module.RESOURCE_TYPE_IDS??[]};return ae({...a,contracts:g})}};function R(a){return N(a,r)}return{...v,...d,...y}}function Ht(e,n,r){let t=Ut.join(e,"config","integrations.json");_(t,`${JSON.stringify(n,null,2)}
8
+ `),r.invalidate([t])}export{te as APP_INTEGRATION_NODE_KEYS,A as AppToolkitError,W as SAFE_NAME_PATTERN,gt as assertValidModuleId,be as buildPredicateAssembly,Ie as checkInstanceKeys,wt as collectDeclaredModules,he as contractsNotResolvedMessage,Yt as createAppToolkit,Se as createFileCache,je as createWriteCore,At as credentialArtifactExists,Z as deepEqual,z as deriveStem,ie as echoForRef,an as ensureDir,Pe as ensureMockBindings,ae as evaluateIntegrationServices,Yn as expandEnvVars,Sn as extractModuleIdFromSource,we as invalidateContractsResolver,ee as isControlledInlineProvider,vn as isValidModuleId,Kt as loadAppIntegrationSchemas,De as loadAppView,qe as loadCredentialTypesView,Ze as loadCredentialsView,Ve as loadModuleDetailView,zt as loadModuleIntegrationSchemas,Ne as loadModulesView,wn as loadProviderCatalog,xe as loadProviderCatalogRaw,_e as loadProviderDetailView,Le as loadProviderServiceDetailView,$e as loadProvidersView,Fe as loadServiceDetailView,He as loadServiceIntegrationSchemas,ze as loadServiceResolutionDetail,re as loadServiceResolutionsView,le as manifestPath,oe as maskCredentialValues,Xe as moduleDependencySchema,rn as moduleDescriptorSchema,Ge as pageContribSchema,G as parseModuleDescriptor,en as providerSlotContribSchema,mn as readAppManifest,Ae as readAppManifestFull,Q as readCredentialFile,Y as readIntegrationsConfig,Rn as readIntegrationsStrict,Me as reconcileOrphanCredentials,pn as refToEnvKey,ut as removeNpmModule,M as resolveContractsForApp,M as resolveContractsForAppExport,Ue as resolveLayerIntegrationSchemas,Ke as resolveServiceSummary,tn as resourceNeedContribSchema,nn as serviceNeedContribSchema,D as stemToFilePath,Qn as stemToRef,Qe as tabContribSchema,ft as updateNpmModule,pt as upsertMiniappContainer,dt as upsertNpmModule,N as walkManifests,lt as writeAppManifest,_ as writeAtomic,Re as writeCredentialFile};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tbox.cn/app-toolkit",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "description": "tbox 应用工具面(运行面/工具面对仗:app-sdk 给运行的应用用,app-toolkit 给操作应用的工具用)——模块解析、集成配置求值/校验/写入内核,contracts 经应用侧动态解析(沙箱与目标应用版本解耦)。",
6
6
  "exports": {
@@ -18,7 +18,7 @@
18
18
  "zod": "3.25.76"
19
19
  },
20
20
  "devDependencies": {
21
- "@tbox.cn/app-contracts": "0.9.0",
21
+ "@tbox.cn/app-contracts": "0.10.0",
22
22
  "typescript": "5.9.3",
23
23
  "tsup": "8.5.1",
24
24
  "vitest": "4.1.10",
@@ -20,6 +20,12 @@ export interface NpmModuleEntry {
20
20
  mode: ModuleMode;
21
21
  /** 3-way merge 基线(codegen 模式) */
22
22
  baseVersion?: string;
23
+ /**
24
+ * 条目类别(单一模板统一化 W2-4):'ui-kit' = 壳 UI 组件包——create 全量继承后
25
+ * 不再承担保留判据(模板 manifest = 出厂装配真源);现职 = update 三方合并锚 +
26
+ * sync-agent-ui-kit 副本 identity 标记(由该脚本派生维护)。
27
+ */
28
+ kind?: 'ui-kit';
23
29
  }
24
30
 
25
31
  export interface AppManifest {