@anov/cic-standard-sdk 0.0.20 → 0.0.21

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.
@@ -0,0 +1,476 @@
1
+ /**
2
+ * @file cic.manifest.ts
3
+ * @description CIC 需求表(CICManifest)类型定义
4
+ *
5
+ * ┌─────────────────────────────────────────────────────────────────────┐
6
+ * │ 职责定位 │
7
+ * │ 本文件是"应用侧视角"的完整声明,描述一个 CIC 应用需要什么、 │
8
+ * │ 如何消费、怎样注册组件。 │
9
+ * │ │
10
+ * │ 对应关系: │
11
+ * │ CICManifest(需求表) ←→ RuntimeManifest(供给表) │
12
+ * │ 两者由 resolveManifest() 完成匹配,产出 ResolvedManifest │
13
+ * └─────────────────────────────────────────────────────────────────────┘
14
+ *
15
+ * 设计原则:
16
+ * 1. 应用只声明"要什么",不关心"从哪里来"(由供给表决定)
17
+ * 2. strategy 是全局策略,单条 requires[].consume 可覆盖
18
+ * 3. 所有路径都是逻辑路径,由 alias / importMap 展开为物理路径
19
+ */
20
+ /**
21
+ * 目标运行平台
22
+ * web —— 普通浏览器页面(主流场景)
23
+ * electron —— Electron 桌面应用,window 对象来自 BrowserWindow
24
+ * miniapp —— 小程序等受限环境,不支持动态 importMap
25
+ */
26
+ export type EnginePlatform = 'web' | 'electron' | 'miniapp';
27
+ /**
28
+ * JS 框架运行时
29
+ * Adapter 层根据此字段选择对应实现(Vue3Adapter / ReactAdapter...)
30
+ */
31
+ export type EngineRuntime = 'vue3' | 'vue2' | 'react' | 'svelte';
32
+ /**
33
+ * 运行模式
34
+ * development —— 开发模式,使用 binding.src(本地/开发服务器路径)
35
+ * production —— 生产模式,使用 binding.prodSrc(CDN / 部署路径)
36
+ * staging —— 预发布,行为同 production 但可开启额外日志
37
+ *
38
+ * ⚠️ RuntimeManifest.engine.mode 决定 Loader 选 src 还是 prodSrc,
39
+ * 此处是 CICManifest 对运行模式的"期望声明",通常由构建工具注入。
40
+ */
41
+ export type EngineMode = 'development' | 'production' | 'staging';
42
+ /** semver 具体版本字符串,如 "3.4.21"(非范围) */
43
+ export type SemverString = string;
44
+ /**
45
+ * semver 版本范围,如 "^3.0.0" "~1.2.0" ">= 2.0.0"
46
+ * Loader 使用 checkVersion() 按以下规则校验:
47
+ * ^x.y.z —— 主版本相同且 >= base(兼容版本)
48
+ * ~x.y.z —— 主版本 + 次版本相同且 >= base(补丁兼容)
49
+ * x.y.z —— 精确匹配
50
+ */
51
+ export type SemverRange = string;
52
+ /** URL 路径,相对路径(./xxx)或绝对路径(/xxx 或 https://...) */
53
+ export type UrlPath = string;
54
+ /**
55
+ * window 对象属性路径,支持链式,如:
56
+ * "Vue" → window.Vue
57
+ * "MyLib.Core" → window.MyLib.Core
58
+ * "NS.Sub.Plugin" → window.NS.Sub.Plugin
59
+ */
60
+ export type WindowPath = string;
61
+ /**
62
+ * ESM import specifier(模块标识符),如:
63
+ * "vue" → import { ref } from 'vue'
64
+ * "@anov/core" → import Core from '@anov/core'
65
+ * "cdn/button" → 通过 importMap cdn/ 前缀展开
66
+ */
67
+ export type Specifier = string;
68
+ /** 环境变量表:值只允许基本类型,禁止对象/数组(序列化安全) */
69
+ export type EnvRecord = Record<string, string | number | boolean>;
70
+ /**
71
+ * importMap scopes 结构:
72
+ * key —— 作用域 URL 前缀(如 "/pages/admin/")
73
+ * value —— 该作用域内的 specifier → URL 覆盖映射
74
+ *
75
+ * 典型用途:同一 specifier 在不同路径下解析到不同版本
76
+ * "/legacy/" → { vue: "/vendor/vue2.esm.js" } // 兼容组件用 Vue 2
77
+ */
78
+ export type ScopesMap = Record<UrlPath, Record<Specifier, UrlPath>>;
79
+ /**
80
+ * 标准 W3C importMap 结构
81
+ *
82
+ * 三层合并优先级(低 → 高):
83
+ * runtime.importMap(基础前缀)
84
+ * ↑
85
+ * resolveManifest 供需匹配生成(ESM 直连 + shimB data: URL)
86
+ * ↑
87
+ * alias 展开(cic.modules.alias → imports)
88
+ * ↑
89
+ * cic.modules.importMap(应用显式声明,最高优先级)
90
+ *
91
+ * scopes 深度合并(非 spread 整体覆盖):
92
+ * 同 scope key 下的 imports 按 key 级覆盖(见 mergeScopes 实现)
93
+ */
94
+ export interface ImportMap {
95
+ imports: Record<Specifier, UrlPath>;
96
+ /**
97
+ * 作用域映射,可选。
98
+ * 不支持的平台(如部分小程序)应忽略此字段。
99
+ * V2 中 resolveManifest 不向 scopes 写入供需生成的映射,仅做透传合并。
100
+ */
101
+ scopes?: ScopesMap;
102
+ }
103
+ /**
104
+ * 模块整体消费策略(cic.modules.strategy)
105
+ * 作为 requires[].consume 字段的默认值来源,单条可覆盖。
106
+ *
107
+ * 推导规则(defaultConsume 函数实现):
108
+ * 'importmap' → consume 默认 'esm'
109
+ * 适用场景:纯 ESM 项目,所有依赖通过 import specifier 消费
110
+ * 'global' → consume 默认 'global'
111
+ * 适用场景:遗留项目,所有依赖挂 window,通过 window.X 访问
112
+ * 'hybrid' → consume 默认 'both'
113
+ * 适用场景:迁移期,同一依赖既要 window 兼容旧插件,又要 ESM 给新代码
114
+ *
115
+ * 优先级:requires[n].consume(显式)> strategy(默认推导)
116
+ */
117
+ export type ModuleStrategy = 'importmap' | 'global' | 'hybrid';
118
+ /**
119
+ * 单依赖的消费形态
120
+ * 'esm' —— 只需要 import specifier,不需要 window 全局
121
+ * 'global' —— 只需要 window.X,不需要 importMap 映射
122
+ * 'both' —— 两种都需要(过渡期最常见,旧插件 + 新模块并存)
123
+ *
124
+ * Loader 供需匹配矩阵(consume × 供给形态):
125
+ * 供给\需求 esm global both
126
+ * esm+global direct-esm direct-global direct-esm + direct-global
127
+ * 只有 esm direct-esm shimA direct-esm + shimA
128
+ * 只有 global shimB direct-global shimB + direct-global
129
+ * 无供给 host-injected 检查 / skipped
130
+ */
131
+ export type ConsumeMode = 'esm' | 'global' | 'both';
132
+ /**
133
+ * 单条外部依赖的消费声明(cic.modules.requires[])
134
+ *
135
+ * 最小声明示例(strategy:'importmap' 下,所有字段可推导):
136
+ * { id: 'vue', version: '^3.4.0' }
137
+ * → consume 默认 'esm'(来自 strategy)
138
+ * → specifier 默认 'vue'(来自 id)
139
+ *
140
+ * 完整声明示例(策略为 hybrid,显式覆盖所有字段):
141
+ * {
142
+ * id: 'vue',
143
+ * version: '^3.4.0',
144
+ * required: true,
145
+ * consume: 'both',
146
+ * specifier: 'vue',
147
+ * global: 'Vue',
148
+ * dependencies: []
149
+ * }
150
+ */
151
+ export interface CICRequires {
152
+ /**
153
+ * 依赖标识符,与 RuntimeManifest.provides 的 key 对应。
154
+ * 通常与 npm 包名一致,如 'vue' '@anov/charts'。
155
+ */
156
+ id: string;
157
+ /**
158
+ * 版本范围约束(semver range)。
159
+ * Loader 用 checkVersion(provides[id].version, version) 校验。
160
+ * 未填则跳过版本校验(versionSatisfied → 'unknown')。
161
+ */
162
+ version?: SemverRange;
163
+ /**
164
+ * 是否必需,默认 true。
165
+ *
166
+ * required=true(默认):
167
+ * - 版本不满足 → 抛出错误,中止 resolveManifest
168
+ * - host-injected 检查失败(window 不存在)→ 抛出错误
169
+ * - 供给表无记录 + window 不存在 → 抛出错误
170
+ *
171
+ * required=false:
172
+ * - 版本不满足 → strategy='skipped',记录 warning,继续
173
+ * - host-injected 检查失败 → strategy='skipped',记录 warning,继续
174
+ * - 依赖加载失败 → 忽略,继续执行后续任务
175
+ */
176
+ required?: boolean;
177
+ /**
178
+ * 消费形态。未填时从 cic.modules.strategy 推导(见 ModuleStrategy 注释)。
179
+ * 显式声明优先级高于 strategy 推导。
180
+ */
181
+ consume?: ConsumeMode;
182
+ /**
183
+ * consume 包含 'esm' 时,注册到 importMap 的 import specifier。
184
+ * 未填时按以下优先级取值:
185
+ * ext.specifier > provides[id].bindings.esm.specifier > ext.id
186
+ *
187
+ * 建议总是显式声明,避免依赖供给表的内部字段。
188
+ */
189
+ specifier?: Specifier;
190
+ /**
191
+ * consume 包含 'global' 时,期望挂载到 window 的属性路径。
192
+ * 未填时按以下优先级取值:
193
+ * ext.global > provides[id].bindings.global.window > ext.id
194
+ *
195
+ * 支持链式路径,如 'MyLib.Core'(对应 window.MyLib.Core)。
196
+ */
197
+ global?: WindowPath;
198
+ /**
199
+ * 加载顺序约束(拓扑排序依赖列表)。
200
+ * 填写其他 requires[n].id,Loader 保证被依赖项先加载。
201
+ *
202
+ * 示例:vue-router 必须在 vue 加载完成后再加载
203
+ * { id: 'vue-router', dependencies: ['vue'] }
204
+ *
205
+ * 循环依赖会被 topoSort 检测并抛出错误。
206
+ */
207
+ dependencies?: string[];
208
+ }
209
+ /**
210
+ * 组件装配覆盖规则(cic.components.adapters[])
211
+ *
212
+ * 优先级:adapters(按 match 精确覆盖)> components.strategy(全局默认)
213
+ * 注册顺序:registry(静态,最先)→ adapters(动态匹配)→ strategy 兜底
214
+ *
215
+ * kind 决定注册路径:
216
+ * plugin —— 作为插件安装,调用 app.use(mod, options)
217
+ * component —— 作为组件注册,调用 app.component(name, mod)
218
+ * module —— 调用模块的指定方法,如 mod.init(app, options)
219
+ * global —— 从 window.globalName 读取后注册(遗留/CDN 场景)
220
+ */
221
+ export interface ComponentAdapter {
222
+ /**
223
+ * glob 匹配模式,匹配组件/库的标识符(通常是 import specifier 或包名)。
224
+ * 示例:
225
+ * '*' —— 匹配所有(通配兜底)
226
+ * '@arco-design/web-vue' —— 精确匹配
227
+ * 'cdn/**\/*.js' —— 路径通配
228
+ */
229
+ match: string;
230
+ /**
231
+ * 装配种类,决定注册方式。详见上方注释。
232
+ */
233
+ kind: 'plugin' | 'component' | 'module' | 'global';
234
+ /**
235
+ * 注册配置(可选,kind 为 plugin/module 时常用)。
236
+ * method —— 调用的方法名(默认:plugin→'use',module→'install')
237
+ * target —— 注册目标(默认:当前 app 实例),如 'app' 'router'
238
+ * options —— 传递给 method 的选项对象
239
+ */
240
+ register?: {
241
+ method?: string;
242
+ target?: string;
243
+ options?: Record<string, unknown>;
244
+ };
245
+ /**
246
+ * 是否必需,默认 true。
247
+ * false 时注册失败只记录 warning,不阻断挂载流程。
248
+ */
249
+ required?: boolean;
250
+ /** 加载顺序约束,填写其他 adapter.match 值 */
251
+ dependencies?: string[];
252
+ /**
253
+ * 是否异步注册(async: true)。
254
+ * true 时 Adapter 不等待注册完成直接继续,适合非阻塞的懒加载组件库。
255
+ * 注意:异步注册的组件在首次渲染时可能尚未就绪。
256
+ */
257
+ async?: boolean;
258
+ /**
259
+ * 实例初始化钩子(组件/插件挂载后执行额外初始化逻辑)。
260
+ *
261
+ * when —— 触发时机:'mounted'(DOM 挂载后)或 'ready'(框架生命周期就绪后)
262
+ * method —— 调用的实例方法名
263
+ * options —— 传递给方法的参数
264
+ * guard —— 执行前提条件表达式(falsy 则跳过 instanceInit)
265
+ *
266
+ * 示例(图表库在挂载后调用 setTheme):
267
+ * instanceInit: { when: 'mounted', method: 'setTheme', options: { theme: 'dark' } }
268
+ */
269
+ instanceInit?: {
270
+ when?: 'mounted' | 'ready';
271
+ method: string;
272
+ options?: Record<string, unknown>;
273
+ guard?: string;
274
+ };
275
+ /**
276
+ * kind:'global' 时,从 window 读取的属性路径(WindowPath)。
277
+ * 未填时使用 match 字段值。
278
+ *
279
+ * 示例:match='echarts', globalName='echarts' → 读取 window.echarts
280
+ */
281
+ globalName?: string;
282
+ }
283
+ /**
284
+ * CIC 需求清单(应用侧,由 CIC 平台或构建工具生成)
285
+ *
286
+ * 字段分组:
287
+ * engine —— 应用对运行时环境的最低要求
288
+ * modules —— 模块解析策略与外部依赖声明
289
+ * components —— 组件注册策略(仅影响 Adapter 层,不影响 Loader)
290
+ * export —— 应用向宿主暴露依赖时的排除声明
291
+ * env —— 应用侧环境变量覆盖(覆盖 runtime.env 同名字段)
292
+ * extensions —— 业务扩展字段(Loader 不处理,原样透传)
293
+ *
294
+ * 注意:CICManifest 没有 entry 字段,应用入口由 RuntimeManifest.entry 指定,
295
+ * 或由 manifest-loader 从固定约定路径(./src/main.js)加载。
296
+ */
297
+ export interface CICManifest {
298
+ /**
299
+ * 需求表格式版本(semver),用于 Loader 兼容性检测。
300
+ * 与 RuntimeManifest.version 独立,各自演进。
301
+ */
302
+ version: SemverString;
303
+ /**
304
+ * 应用对运行时环境的需求声明。
305
+ * Loader 会校验 runtime.engine 是否满足以下约束。
306
+ */
307
+ engine: {
308
+ platform: EnginePlatform;
309
+ runtime: EngineRuntime;
310
+ /**
311
+ * 期望的框架版本范围(semver range)。
312
+ * 用于与 RuntimeManifest.engine.version 进行校验。
313
+ * 未填则跳过版本校验。
314
+ */
315
+ version?: SemverRange;
316
+ };
317
+ /** 模块解析配置 */
318
+ modules: {
319
+ /**
320
+ * 模块消费整体策略,决定 requires[].consume 的默认值。
321
+ * 详见 ModuleStrategy 类型注释中的推导规则。
322
+ *
323
+ * 最佳实践:
324
+ * 纯新项目 → 'importmap'(最简,全部 ESM)
325
+ * 全遗留项目 → 'global'(全部 window 全局)
326
+ * 迁移期/混合 → 'hybrid'(逐条 requires 精细控制)
327
+ */
328
+ strategy: ModuleStrategy;
329
+ /**
330
+ * 应用显式声明的 importMap(合并优先级最高)。
331
+ * 典型用途:指定特定 specifier 使用应用自己打包的版本,
332
+ * 而不是宿主 runtime 提供的版本。
333
+ *
334
+ * ⚠️ 此字段会完全覆盖供需匹配生成的同名 specifier 映射。
335
+ * 谨慎填写,避免绕过版本校验。
336
+ */
337
+ importMap?: ImportMap;
338
+ /**
339
+ * 外部依赖需求列表(即"需求表的核心")。
340
+ * 字段名用 requires(而非 externals)更直观表达"应用向宿主要求的依赖"。
341
+ * 每条声明对应供给表中的一个 ProvideEntry。
342
+ *
343
+ * 空列表或未填 → 跳过供需匹配,直接使用 runtime.importMap 和 cic.modules.importMap。
344
+ */
345
+ requires?: CICRequires[];
346
+ /**
347
+ * 模块路径基础 URL(路径前缀,不含文件名)。
348
+ * 用于将相对路径的模块 URL 转换为绝对路径。
349
+ *
350
+ * 区别于 RuntimeManifest.engine.devServerURL(开发服务器地址)。
351
+ * 此字段是应用自己的模块基础路径,devServerURL 是宿主运行时的服务地址。
352
+ */
353
+ baseURL?: string;
354
+ /**
355
+ * 路径别名(Loader 预处理阶段展开为 importMap.imports 条目)。
356
+ *
357
+ * 规则:
358
+ * - prefix alias 必须以 '/' 结尾(如 '@/'、'cdn/')
359
+ * - 展开后进入 importMap.imports,优先级同 cic.modules.importMap
360
+ * - Loader 校验格式(expandAlias 函数),非 '/' 结尾直接抛出错误
361
+ * - 展开后的路径解析由浏览器 importMap 原生处理,Loader 不另实现匹配
362
+ *
363
+ * 示例:
364
+ * alias: { '@/': '/src/', 'cdn/': '/anov-prod/mgt/ui/' }
365
+ * → importMap.imports['@/'] = '/src/'
366
+ * → importMap.imports['cdn/'] = '/anov-prod/mgt/ui/'
367
+ */
368
+ alias?: Record<string, string>;
369
+ /**
370
+ * 应用自身需要预加载的模块路径列表。
371
+ * 与 RuntimeManifest.preload 合并去重,在 importMap 注入后由 Loader 动态插入
372
+ * <link rel="modulepreload"> 标签。
373
+ *
374
+ * ⚠️ 不能写在 HTML 里:HTML 解析阶段触发 modulepreload 时 importMap 尚未注入,
375
+ * module graph 解析失败。必须由 Loader 在 importMap 注入后动态插入。
376
+ */
377
+ preload?: UrlPath[];
378
+ /**
379
+ * 依赖加载失败的降级策略。
380
+ * strategy: 'global' —— 降级读取 window 全局变量
381
+ * strategy: 'cdn' —— 从备用 CDN 重新加载
382
+ * mapping —— specifier → 降级目标的映射
383
+ * cdnBase —— 备用 CDN 基础 URL(strategy:'cdn' 时使用)
384
+ *
385
+ * ⚠️ V2 中 fallback 仅在 required=false 时生效,
386
+ * required=true 的依赖加载失败直接报错,不走 fallback。
387
+ */
388
+ fallback?: {
389
+ strategy: 'global' | 'cdn';
390
+ mapping?: Record<string, string>;
391
+ cdnBase?: string;
392
+ };
393
+ };
394
+ /**
395
+ * 组件注册配置(仅影响 Adapter 层,Loader 不处理此字段)。
396
+ * Adapter 在 register 阶段读取此配置完成组件装配。
397
+ */
398
+ components?: {
399
+ /**
400
+ * 组件注册默认策略,作为 adapters[].kind 的兜底。
401
+ * global —— 全局注册,所有页面可用(适合基础组件库)
402
+ * local —— 局部注册,仅在声明页面可用(适合业务组件)
403
+ * lazy —— 懒加载注册,首次使用时才加载(适合大型可选组件)
404
+ */
405
+ strategy?: 'global' | 'local' | 'lazy';
406
+ /**
407
+ * 按 match 精确覆盖注册方式,优先级高于 strategy。
408
+ * 注册执行顺序:按 dependencies 拓扑排序后顺序执行。
409
+ * 与 registry 冲突时:registry 优先(静态声明高于动态匹配),记录 warning。
410
+ */
411
+ adapters?: ComponentAdapter[];
412
+ /** 全局组件名称前缀,统一给注册的组件加前缀(如 'Cic' → CicButton) */
413
+ prefix?: string;
414
+ /**
415
+ * 组件命名规范,决定从文件名生成组件名的方式。
416
+ * 支持内置规范(PascalCase 最常用)和自定义字符串。
417
+ */
418
+ naming?: 'kebab-case' | 'PascalCase' | 'camelCase' | (string & {});
419
+ /**
420
+ * 静态组件注册表(key: 组件名,value: 模块路径)。
421
+ * 优先级高于 adapters 动态匹配。
422
+ *
423
+ * 与 requires 冲突(同一模块同时出现)时:
424
+ * registry 的路径优先,记录 warning,不报错。
425
+ *
426
+ * 示例:
427
+ * registry: { DataTable: '@/components/DataTable/index.ts' }
428
+ * → Adapter 调用 import('@/components/DataTable/index.ts') 后注册为 DataTable
429
+ */
430
+ registry?: Record<string, string>;
431
+ /**
432
+ * 同名组件冲突处理策略,默认 'warn'。
433
+ * 'warn' —— 记录 warning,后注册者覆盖先注册者(安全兜底)
434
+ * 'error' —— 抛出错误,中止注册流程(严格模式)
435
+ * 'replace' —— 静默覆盖,不记录任何日志(性能优先)
436
+ */
437
+ conflictPolicy?: 'warn' | 'error' | 'replace';
438
+ };
439
+ /**
440
+ * 应用向宿主声明"哪些依赖由宿主统一注入、无需应用自带"。
441
+ * 构建工具(如 Vite)据此生成 rollupOptions.external,
442
+ * 避免把 vue/pinia 等打包进应用 bundle。
443
+ *
444
+ * 注意:这是构建阶段的声明,运行时 Loader 不读取此字段。
445
+ */
446
+ export?: {
447
+ /** 排除的依赖 id 列表(对应 rollupOptions.external) */
448
+ excludeDeps?: string[];
449
+ /** 排除原因(文档用途,供构建日志展示) */
450
+ reason?: string;
451
+ };
452
+ /**
453
+ * 应用侧环境变量,覆盖 RuntimeManifest.env 中的同名字段。
454
+ * 合并规则:{ ...runtime.env, ...cic.env }(cic 优先)
455
+ * 合并结果写入 window.__ENV__ 和 ResolvedManifest.env。
456
+ */
457
+ env?: EnvRecord;
458
+ /**
459
+ * 业务扩展字段,Loader 不处理,原样透传到 ResolvedManifest.cic.extensions。
460
+ * 适合存放多租户配置、国际化标识等平台特定数据。
461
+ *
462
+ * 示例:{ tenant: 'default', locale: 'zh-CN' }
463
+ */
464
+ extensions?: Record<string, unknown>;
465
+ }
466
+ /**
467
+ * CICManifest 完整配置示例
468
+ *
469
+ * 场景说明:
470
+ * - 使用 hybrid 策略(Vue 既要 ESM 又要 global,便于旧插件兼容)
471
+ * - echarts 只需要 global(遗留图表插件通过 window.echarts 访问)
472
+ * - @anov/charts 只需要 ESM(新模块,只有 import 访问)
473
+ * - @arco-design/web-vue 作为插件全局安装
474
+ * - DataTable / SmartForm 从本地路径静态注册
475
+ */
476
+ export declare const CICManifestExample: CICManifest;