@proteus-vue/compiler 0.3.0-beta.0 → 0.3.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +218 -0
- package/dist/es5.d.ts +11 -0
- package/dist/fluid-layout.d.ts +45 -0
- package/dist/index.d.ts +16 -4
- package/dist/index.js +20045 -434
- package/dist/ir/build.d.ts +14 -0
- package/dist/overrides.d.ts +2 -0
- package/dist/platform-macros.d.ts +20 -0
- package/dist/platform-variant.d.ts +72 -0
- package/dist/script.d.ts +18 -0
- package/dist/sfc-macros.d.ts +44 -0
- package/dist/svg-lower.d.ts +157 -0
- package/dist/tags.d.ts +13 -0
- package/dist/transforms/types.d.ts +6 -0
- package/dist/types.d.ts +1 -1
- package/dist/validate.d.ts +30 -0
- package/dist/vue-compat.d.ts +43 -0
- package/package.json +20 -12
- package/dist/explain.js +0 -59
- package/dist/overrides.js +0 -34
- package/dist/script.js +0 -318
- package/dist/style.js +0 -96
- package/dist/tags.js +0 -49
- package/dist/template.js +0 -337
- package/dist/trace.js +0 -18
- package/dist/transforms/registry.js +0 -48
- package/dist/transforms/script.js +0 -179
- package/dist/transforms/style.js +0 -74
- package/dist/transforms/template.js +0 -371
- package/dist/transforms/types.js +0 -7
- package/dist/transforms/validate.js +0 -50
- package/dist/types.js +0 -4
- package/dist/validate.js +0 -54
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CompileIR, ScriptIR, TemplateIR, TemplateTransformResult } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* 投影 TemplateTransformResult → TemplateIR(14 旁路字段 1:1 结构化)。
|
|
4
|
+
* 可选项缺省按「未出现 = 空集合/false」归一,保证 IR 快照确定性。
|
|
5
|
+
*/
|
|
6
|
+
export declare function buildTemplateIR(tpl: TemplateTransformResult): TemplateIR;
|
|
7
|
+
/**
|
|
8
|
+
* 组装 CompileIR 容器。
|
|
9
|
+
* M1:script 段留空(ScriptIR 类型已落地,内容随 M4 逐条迁入——script 侧当前无结构化旁路字段)。
|
|
10
|
+
* version 与 TemplateIR 演进同步 bump(见 compiler-types.ts CompileIR.version)。
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildCompileIR(tpl: TemplateTransformResult): CompileIR;
|
|
13
|
+
/** ScriptIR 缺省(确定性——纯模板/提取禁用时 script 段 = 全空数组而非 undefined) */
|
|
14
|
+
export declare function emptyScriptIR(): ScriptIR;
|
package/dist/overrides.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ export interface ResolvedOverrides {
|
|
|
9
9
|
semanticClass: Record<string, string>;
|
|
10
10
|
/** 被禁用的规则 ID 集合 */
|
|
11
11
|
disabled: Set<string>;
|
|
12
|
+
/** ★2026-09-09 支持矩阵 fail-fast:矩阵外语义「已原样输出」软警告升级为编译期 CompilerError(缺省 false) */
|
|
13
|
+
failFast: boolean;
|
|
12
14
|
}
|
|
13
15
|
/** 解析规则覆盖:合并 tags.ts 常量 + 覆盖补丁;未知规则 ID 编译期警告(防配置笔误) */
|
|
14
16
|
export declare function resolveOverrides(options?: TransformRuleOverrides): ResolvedOverrides;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { VariantPlatform } from './platform-variant';
|
|
2
|
+
export type { VariantPlatform };
|
|
3
|
+
/** 宏目标平台(= 变体解析目标;具体平台或族) */
|
|
4
|
+
export type PlatformTarget = VariantPlatform;
|
|
5
|
+
/**
|
|
6
|
+
* 平台宏替换:`__MP__`/`__WEB__`/`__NATIVE__`/`__IOS__`/`__ANDROID__`/`__HARMONY__`/`__TARGET__`
|
|
7
|
+
* → 该平台字面量。
|
|
8
|
+
*
|
|
9
|
+
* ★两种模式(踩坑后确立,2026-09-13):
|
|
10
|
+
* - `'template'`:**原始**标识符替换(word-boundary)。模板里 `v-if="__MP__"` 的标识符位于
|
|
11
|
+
* HTML 属性引号内、但语义是表达式——必须替换,故不做字符串跳过。
|
|
12
|
+
* - `'code'`:跳过字符串字面量与注释(脚本模式)。否则**代码示例字符串**(如
|
|
13
|
+
* `codes.x = '<p-button v-if="__MP__">'`)会被误改并破坏引号结构(实测事故)。
|
|
14
|
+
*/
|
|
15
|
+
export declare function applyPlatformMacros(source: string, platform: PlatformTarget, mode?: 'template' | 'code'): string;
|
|
16
|
+
/** 对整个 .vue 源码做宏替换:`<script>` 块用 code 模式(跳过字符串),其余(template 等)用 template 模式。
|
|
17
|
+
* Web 端的 vue 前置插件用(在 @vitejs/plugin-vue 解析前替换源码)。 */
|
|
18
|
+
export declare function applyPlatformMacrosInSfc(source: string, platform: PlatformTarget): string;
|
|
19
|
+
/** 供构建配置(vite define / esbuild define)复用的宏定义表 */
|
|
20
|
+
export declare function platformDefines(platform: PlatformTarget): Record<string, string>;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/** 具体平台(变体后缀可精确到具体平台/OS) */
|
|
2
|
+
export type ConcretePlatform = 'web' | 'mp' | 'ios' | 'android' | 'harmony';
|
|
3
|
+
/** 平台族(可作变体后缀;作为族内全部具体平台的回退) */
|
|
4
|
+
export type PlatformFamily = 'web' | 'mp' | 'native';
|
|
5
|
+
/** 变体解析目标:具体平台 或 平台族 */
|
|
6
|
+
export type VariantPlatform = ConcretePlatform | PlatformFamily;
|
|
7
|
+
/** 全部具体平台(顺序稳定) */
|
|
8
|
+
export declare const CONCRETE_PLATFORMS: readonly ConcretePlatform[];
|
|
9
|
+
/** 全部可选变体后缀(供文档/校验用;无连字符) */
|
|
10
|
+
export declare const VARIANT_SUFFIXES: readonly string[];
|
|
11
|
+
/** 兼容别名(旧名保留;VARIANT_PLATFORMS 保留供既有消费方) */
|
|
12
|
+
export declare const VARIANT_PLATFORMS: readonly VariantPlatform[];
|
|
13
|
+
/** 规范平台标识(未知返回 undefined——不猜,调用方自行决定 fail 策略) */
|
|
14
|
+
export declare function normalizePlatform(raw: string): VariantPlatform | undefined;
|
|
15
|
+
/** 该平台所属族(具体平台 → 族;族 → 自身) */
|
|
16
|
+
export declare function platformFamily(p: VariantPlatform): PlatformFamily;
|
|
17
|
+
/** 构建目标(config.platform)→ 规范平台 id('mp-weixin'→'mp'、'ios'→'ios' …) */
|
|
18
|
+
export declare function platformFromBuildTarget(target: string): VariantPlatform;
|
|
19
|
+
/**
|
|
20
|
+
* 某**解析目标**可接受的变体文件后缀(按优先级):精确平台 → 平台别名 → 族(含族别名)。
|
|
21
|
+
* 例:'ios' → ['ios','native','app'](iOS 专属优先,其次三端原生共用)
|
|
22
|
+
* 'mp' → ['mp','skyline'];'web' → ['web'];'native' → ['native','app']
|
|
23
|
+
*/
|
|
24
|
+
export declare function variantSuffixes(platform: VariantPlatform): string[];
|
|
25
|
+
/** 拆解文件名中的平台变体后缀(返回规范平台 + 原始后缀 token):
|
|
26
|
+
* `foo.web.ts` → { base:'foo.ts', platform:'web', suffix:'web' }
|
|
27
|
+
* `foo.ios.ts` → { base:'foo.ts', platform:'ios', suffix:'ios' }
|
|
28
|
+
* `foo.native.ts` → { base:'foo.ts', platform:'native', suffix:'native' }
|
|
29
|
+
* `foo.ts` → { base:'foo.ts', platform:undefined }
|
|
30
|
+
* ★后缀须位于**最后一个扩展名之前**(故 `a.web.config.ts` 的 `.web` 是业务名,不拆)。 */
|
|
31
|
+
export declare function splitVariant(filePath: string): {
|
|
32
|
+
base: string;
|
|
33
|
+
platform?: VariantPlatform;
|
|
34
|
+
suffix?: string;
|
|
35
|
+
};
|
|
36
|
+
/** 候选路径(按优先级):目标平台各后缀变体 → 无后缀基准。纯字符串运算,不触盘。 */
|
|
37
|
+
export declare function variantCandidates(filePath: string, platform: VariantPlatform): string[];
|
|
38
|
+
/** 解析(注入 exists 以便纯函数测试):返回首个存在的候选,无则 null。 */
|
|
39
|
+
export declare function resolvePlatformVariant(filePath: string, platform: VariantPlatform, exists: (p: string) => boolean): string | null;
|
|
40
|
+
/** 无扩展名导入的多扩展名解析(供 `./share` → `share.ios.ts` 场景):
|
|
41
|
+
* 后缀优先级外层、扩展名内层;平台变体 → 族变体 → 基准。 */
|
|
42
|
+
export declare function resolvePlatformVariantWithExts(baseNoExt: string, exts: readonly string[], platform: VariantPlatform, exists: (p: string) => boolean): string | null;
|
|
43
|
+
/**
|
|
44
|
+
* 该文件是否为「对目标平台无效」的变体(构建扫描时**排除**用)。
|
|
45
|
+
* 目标平台**可接受的全部后缀**(含族)之外 → 视为他端变体;无后缀(共享基准)→ false。
|
|
46
|
+
* 例:目标 'ios' 时 `.native.ts` **有效**(族回退),`.android.ts` 为他端。
|
|
47
|
+
*/
|
|
48
|
+
export declare function isForeignVariant(filePath: string, platform: VariantPlatform): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* 同一组文件中,为某个「逻辑名」挑选目标平台的有效文件(扫描/去重用)。
|
|
51
|
+
* 顺序:目标平台后缀(按优先级)→ 无后缀基准 → null。
|
|
52
|
+
*/
|
|
53
|
+
export declare function pickVariant(candidates: readonly string[], platform: VariantPlatform): string | null;
|
|
54
|
+
/**
|
|
55
|
+
* ★扫描期「有效文件集」:把一批文件按**逻辑名**(去变体后缀)分组,每组选目标平台那一份,
|
|
56
|
+
* 排除他端变体与「被变体覆盖的基准」。供 MP 目录扫描(每个变体不能当独立页面重复编译)。
|
|
57
|
+
*
|
|
58
|
+
* 例(platform='mp',输入 page.vue / page.web.vue / page.mp.vue / other.vue):
|
|
59
|
+
* → [page.mp.vue, other.vue](page.vue 被 page.mp.vue 覆盖、page.web.vue 是他端)
|
|
60
|
+
* 例(platform='ios',输入 s.ts / s.native.ts / s.android.ts):
|
|
61
|
+
* → [s.native.ts](族回退命中;android 是他端)
|
|
62
|
+
*/
|
|
63
|
+
export declare function effectiveVariants(files: readonly string[], platform: VariantPlatform): string[];
|
|
64
|
+
/**
|
|
65
|
+
* ★静态资源变体映射(第 3 层):把 public/ 下的文件列表按平台选出有效集,
|
|
66
|
+
* 并给出**去变体后缀**的产物相对路径(`assets/logo.ios.png` → `assets/logo.png`)。
|
|
67
|
+
* 于是模板里始终写 `src="/assets/logo.png"`,各端各自产出各自的图。
|
|
68
|
+
*/
|
|
69
|
+
export declare function mapPublicAssetVariants(relFiles: readonly string[], platform: VariantPlatform): Array<{
|
|
70
|
+
from: string;
|
|
71
|
+
to: string;
|
|
72
|
+
}>;
|
package/dist/script.d.ts
CHANGED
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
import type { ScriptTransformOptions, ScriptTransformResult, StyleTransformOptions } from './types';
|
|
2
|
+
export declare const REACTIVITY_RUNTIME_APIS: readonly ["reactive", "readonly", "shallowReactive", "shallowReadonly", "isReactive", "isReadonly", "isProxy", "isShallow", "toRaw", "toRef", "toRefs", "isRef", "markRaw", "triggerRef", "customRef", "proxyRefs"];
|
|
3
|
+
/** reactive 家族的 const 源类型(isRef 内联判定用:reactive/readonly 均非 ref-like → false) */
|
|
4
|
+
export declare const REACTIVE_SRC_TYPE: Record<string, string>;
|
|
5
|
+
/** 是否为走运行时 reactive 的 const 初始化调用(reactive(x)/readonly(x)/shallowReactive(x)/shallowReadonly(x)) */
|
|
6
|
+
export declare function isReactiveRuntimeInit(init: string): string | null;
|
|
7
|
+
/** 运行时守卫(读 ReactiveFlags 标记位,需 reactive 族真 Proxy 才有语义)——走 runtime-init 但在「函数调用初始化」警告里改准确地说明 */
|
|
8
|
+
export declare const REACTIVITY_RUNTIME_GUARDS: Set<string>;
|
|
9
|
+
/** 方法参数 AST → 产物参数文本(类型注解天然剔除;保留 ? 可选 / 默认值 / 展开;解构参数剥类型注解切片) */
|
|
10
|
+
export declare function astParamText(source: string, p: any): string;
|
|
11
|
+
/** ★2026-09-08 修复:runtime-init call 内裸 runtimeInit 名 → this.<name> 的**安全**改写。
|
|
12
|
+
* 旧的 `new RegExp('(?<!\\.)\\b' + n + '\\b')` 会误伤对象字面量 key(`reactive({ a: 1 })` 的 key a 若恰是
|
|
13
|
+
* runtimeInit 名 → `{ this.a: 1 }` 语法错误)与字符串内容。本函数字符级扫描:
|
|
14
|
+
* ① 跳过字符串(单/双/反引号,含转义)与单行注释;② 裸标识符后跟 `:`(对象完整 key,如 `{ a: 1 }`)不改写;
|
|
15
|
+
* ③ 否则(参数引用/链式 base)改 `<prefix><name>`(prefix 默认 `this.`——runtimeInit 实例属性;plain data 内联字段传
|
|
16
|
+
* `this.data.`)。简写 key(`{ a }`)暂无区分(其 value 语义保持裸引用,少见于 runtime-init call)。
|
|
17
|
+
* ★2026-09-09 const 裸引用缺口(p-popover TRIGGER_SELECTOR 真机根因):方法体复用时模板串 `${}` 内插值表达式
|
|
18
|
+
* 不能整体跳过(`${X}` 内裸名同样 ReferenceError)——插值内容递归走同一扫描(嵌套模板/字符串自然覆盖)。 */
|
|
19
|
+
export declare function rewriteInstanceRefsSafe(call: string, names: ReadonlySet<string>, prefix?: string): string;
|
|
2
20
|
/** base64 VLQ 编码(sourcemap mappings 字段) */
|
|
3
21
|
export declare function vlqEncode(value: number): string;
|
|
4
22
|
/** base64 VLQ 解码(测试验证用) */
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export interface MacroModelRef {
|
|
2
|
+
/** 源码里 defineModel 绑定的变量名(const m = defineModel() → m) */
|
|
3
|
+
varName: string;
|
|
4
|
+
/** 对应 v-model prop 名(默认 'modelValue',可 arg defineModel('title') → 'title') */
|
|
5
|
+
propName: string;
|
|
6
|
+
}
|
|
7
|
+
export interface SfcMacros {
|
|
8
|
+
/** compileScript 权威 bindings:name → 'props' | 'setup-ref' | 'setup-const' ...(Vue 官方语义分类) */
|
|
9
|
+
bindings: Record<string, string>;
|
|
10
|
+
/** props 规约名集合(bindings 里标 'props' 的) */
|
|
11
|
+
propNames: Set<string>;
|
|
12
|
+
/** defineModel 引用——const m = defineModel() 展开为 _useModel(__props, 'modelValue') 后提取 { varName: 变量名, propName } */
|
|
13
|
+
modelRefs: MacroModelRef[];
|
|
14
|
+
/** ★权威 emits(compileScript 展开的 emits 数组) */
|
|
15
|
+
emits: string[];
|
|
16
|
+
/** ★权威 props 元数据:name → { type, default? }(compileScript 权威展开,手写 extractProps 类型/默认值一致性校验基准) */
|
|
17
|
+
propsMeta: Record<string, {
|
|
18
|
+
type: string;
|
|
19
|
+
default?: unknown;
|
|
20
|
+
}>;
|
|
21
|
+
/** ★defineOptions 语义元数据:{ name?, inheritAttrs? }(compileScript 将 defineOptions 展开为组件 options 的 ...{} 段;name/inheritAttrs 权威值) */
|
|
22
|
+
defineOptions: {
|
|
23
|
+
name?: string;
|
|
24
|
+
inheritAttrs?: boolean;
|
|
25
|
+
};
|
|
26
|
+
/** 编译是否成功(失败返回空语义,调用方回退既有路径——不因 compileScript 抛错而崩编译) */
|
|
27
|
+
ok: boolean;
|
|
28
|
+
/** 原因(ok=false 时) */
|
|
29
|
+
error?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 用 @vue/compiler-sfc 的 compileScript 提取宏语义元数据(权威源)。
|
|
33
|
+
* @param source 完整 SFC 源码(<script setup> 宏包裹在内)
|
|
34
|
+
* @param filename 用于 id 生成(scopedId 不冲突)
|
|
35
|
+
* @returns bindings 语义分类 + props 规约 + defineModel 模型引用;失败回退空(不抛,调用方走既有路径)
|
|
36
|
+
*/
|
|
37
|
+
export declare function extractSfcMacros(source: string, filename?: string): SfcMacros;
|
|
38
|
+
/**
|
|
39
|
+
* ★模板表达式 var 改名(defineModel 落地):模板里 `{{ m }}` 读 data.m,但 model 的 prop 名是 'modelValue'(var m ≠ prop 名)——
|
|
40
|
+
* 需把插值 `{{ }}` 内的独立标识符 <var> 改为 <propName>,否则读不到(空)。仅改 `{{ }}` 内,避免误伤类名/属性。
|
|
41
|
+
* @param wxml 模板变换器产物(WXML 文本)
|
|
42
|
+
* @param modelRefs var→prop 映射(extractSfcMacros 的 modelRefs)
|
|
43
|
+
*/
|
|
44
|
+
export declare function renameModelVarsInWxml(wxml: string, modelRefs: MacroModelRef[]): string;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import type { ElementNode } from '@vue/compiler-dom';
|
|
2
|
+
/** ★2026-09-09 G-62 P2:Skyline `<image>` 渲染 SVG 的**实测特性支持表**(真机 spike: examples/pages/svg-p2-spike.vue)。
|
|
3
|
+
* 结论:Skyline image 的 SVG 渲染能力远超预期——mask/clipPath/渐变/transform/dasharray/opacity/filter 全部原生支持,
|
|
4
|
+
* 无需 canvas 路线(P2 因此大幅简化)。仅 use+symbol / text 不支持(实测空白)。 */
|
|
5
|
+
export declare const SVG_P2_SUPPORT: {
|
|
6
|
+
/** ✅ 实测支持(放行,无警告) */
|
|
7
|
+
readonly supported: readonly ["linearGradient", "radialGradient", "stop", "defs", "clipPath", "mask", "transform(translate/rotate/scale 矩阵)", "stroke-dasharray / stroke-dashoffset", "opacity / fill-opacity / stroke-opacity", "g(嵌套组)", "filter(feGaussianBlur 等)"];
|
|
8
|
+
/** ❌ 实测不支持(编译期诚实警告——渲染为空白)。★use/symbol 已由编译期展开解决(见 useExpanded) */
|
|
9
|
+
readonly unsupported: readonly ["text", "tspan"];
|
|
10
|
+
/** ★编译期展开解决(原始渲染空白,展开后完美渲染——真机实证) */
|
|
11
|
+
readonly useExpanded: readonly ["use", "symbol"];
|
|
12
|
+
};
|
|
13
|
+
/** 收集子树内**实测不支持**的 SVG 标签(去重,供诚实警告)。
|
|
14
|
+
* ★use/symbol 已由编译期展开处理——仅当 use 引用的 symbol **未在本文档定义**(外部 sprite)时,
|
|
15
|
+
* 展开失败才计入警告(键名 'use(外部引用)')。 */
|
|
16
|
+
export declare function collectUnsupportedSvgTags(node: ElementNode, acc?: Set<string>): Set<string>;
|
|
17
|
+
/** 序列化结果:静态 SVG → base64 data-URI;含动态绑定/不支持形态 → null(调用方警告) */
|
|
18
|
+
/** ★2026-09-09 事件命中:带事件的图形几何(编译期提取——运行时做坐标命中判定)。
|
|
19
|
+
* 真机实证:Skyline tap 事件无坐标,touchstart 的 touches[0] 带 pageX/pageY → 命中基于 touch。 */
|
|
20
|
+
export interface SvgHitShape {
|
|
21
|
+
/** 事件处理器名(页面/组件方法) */
|
|
22
|
+
handler: string;
|
|
23
|
+
/** 图形类型(命中判定算法选择) */
|
|
24
|
+
kind: 'circle' | 'rect' | 'ellipse' | 'path';
|
|
25
|
+
/** 几何参数(viewBox 坐标系):circle→cx,cy,r;rect→x,y,w,h;ellipse→cx,cy,rx,ry;path→采样点对 */
|
|
26
|
+
geom: Record<string, number | number[]>;
|
|
27
|
+
/** fill 是否 none(描边图形命中判定用 stroke 宽度;简化:仍按几何命中) */
|
|
28
|
+
strokeOnly?: boolean;
|
|
29
|
+
}
|
|
30
|
+
/** ★2026-09-09 text 提升:SVG <text> → 原生 <text> 叠加层(Skyline 丢弃 SVG 文字,编译期提取)。
|
|
31
|
+
* 坐标保留 viewBox 坐标系,由调用方按 image 尺寸换算为百分比定位。 */
|
|
32
|
+
export interface SvgTextNode {
|
|
33
|
+
/** 文本内容(静态——含插值则走动态路径不提升) */
|
|
34
|
+
content: string;
|
|
35
|
+
/** viewBox 坐标(x/y) */
|
|
36
|
+
x: number;
|
|
37
|
+
y: number;
|
|
38
|
+
/** 字号(viewBox 单位,无单位) */
|
|
39
|
+
fontSize: number;
|
|
40
|
+
/** 填充色 */
|
|
41
|
+
fill: string;
|
|
42
|
+
/** text-anchor: start/middle/end(默认 start) */
|
|
43
|
+
anchor: string;
|
|
44
|
+
/** font-weight(可选) */
|
|
45
|
+
fontWeight?: string;
|
|
46
|
+
}
|
|
47
|
+
/** ★2026-09-09 动画提升:SVG 整体变换动画 → CSS @keyframes(作用于 <image> 元素)。
|
|
48
|
+
* 实测:SVG 内部 SMIL 不播放(image 静态光栅化),但 CSS 动画对 image 元素**完全有效**(真机三帧 MD5 各异)。 */
|
|
49
|
+
export interface SvgAnimSpec {
|
|
50
|
+
/** 动画类型(映射到 CSS 变换) */
|
|
51
|
+
kind: 'rotate' | 'scale' | 'translate' | 'opacity';
|
|
52
|
+
/** 时长(如 2s) */
|
|
53
|
+
dur: string;
|
|
54
|
+
/** 缓动(如 linear/ease-in-out) */
|
|
55
|
+
timing: string;
|
|
56
|
+
/** 关键帧值(CSS 语义) */
|
|
57
|
+
from: string;
|
|
58
|
+
to: string;
|
|
59
|
+
/** 生成的 CSS 类名(调用方注入 wxss) */
|
|
60
|
+
className: string;
|
|
61
|
+
}
|
|
62
|
+
export interface SvgLowerResult {
|
|
63
|
+
/** data-URI(可直接作 <image src>) */
|
|
64
|
+
dataUri: string;
|
|
65
|
+
/** 原始 viewBox(用于推导 image 尺寸/比例) */
|
|
66
|
+
viewBox: string;
|
|
67
|
+
/** ★事件命中:带事件的图形表(空 = 无事件,不生成命中逻辑) */
|
|
68
|
+
hitShapes: SvgHitShape[];
|
|
69
|
+
/** ★text 提升:SVG 文字节点(编译期提取 → 调用方生成原生 <text> 叠加) */
|
|
70
|
+
texts: SvgTextNode[];
|
|
71
|
+
/** ★动画提升:可映射为 CSS 动画的整体变换(SVG 内部动画不播放,见 §11.1) */
|
|
72
|
+
anims: SvgAnimSpec[];
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 静态 SVG 子树 → <image> data-URI。
|
|
76
|
+
* 前提:调用方已确认 node.tag === 'svg'。含动态绑定 → 返回 null(调用方诚实警告,P1 处理)。
|
|
77
|
+
*/
|
|
78
|
+
export declare function lowerSvgToImage(node: ElementNode): SvgLowerResult | null;
|
|
79
|
+
/** 从 viewBox 推导宽高比(供 <image> 默认尺寸;失败 → 1:1) */
|
|
80
|
+
export declare function viewBoxRatio(viewBox: string): number;
|
|
81
|
+
/** 结构化片段:lit = 原样 SVG 文本;expr = 动态表达式;if = v-if 条件片段(含子片段) */
|
|
82
|
+
export type SvgPart = {
|
|
83
|
+
t: 'lit';
|
|
84
|
+
v: string;
|
|
85
|
+
} | {
|
|
86
|
+
t: 'expr';
|
|
87
|
+
v: string;
|
|
88
|
+
} | {
|
|
89
|
+
t: 'if';
|
|
90
|
+
cond: string;
|
|
91
|
+
parts: SvgPart[];
|
|
92
|
+
};
|
|
93
|
+
/** 动态 SVG 编译结果 */
|
|
94
|
+
export interface SvgDynamicResult {
|
|
95
|
+
/** 生成的 computed 名(模板 image src 引用) */
|
|
96
|
+
computedName: string;
|
|
97
|
+
/** 结构化片段树(script 侧改写 expr 内标识符后拼成模板字面量) */
|
|
98
|
+
parts: SvgPart[];
|
|
99
|
+
/** 依赖的标识符集合 */
|
|
100
|
+
deps: Set<string>;
|
|
101
|
+
/** viewBox(尺寸推导) */
|
|
102
|
+
viewBox: string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* 动态 SVG → 结构化片段树(script 侧改写 expr 标识符后拼接)。
|
|
106
|
+
* 返回 null:形态不支持(v-for 等)——调用方保持 svg-no-peer 警告。
|
|
107
|
+
*/
|
|
108
|
+
export declare function lowerSvgDynamic(node: ElementNode, computedName: string): SvgDynamicResult | null;
|
|
109
|
+
/** 场景节点(与运行时 engine.ts 的 SceneNode 同形——编译期产出) */
|
|
110
|
+
export interface SceneNodeIR {
|
|
111
|
+
tag: string;
|
|
112
|
+
attrs: Record<string, string | number>;
|
|
113
|
+
d?: string;
|
|
114
|
+
anims?: Array<{
|
|
115
|
+
attr: string;
|
|
116
|
+
transformType?: string;
|
|
117
|
+
values: string[];
|
|
118
|
+
dur: number;
|
|
119
|
+
delay: number;
|
|
120
|
+
repeat: boolean;
|
|
121
|
+
}>;
|
|
122
|
+
transform?: {
|
|
123
|
+
translate?: [number, number];
|
|
124
|
+
rotate?: number;
|
|
125
|
+
scale?: [number, number];
|
|
126
|
+
origin?: [number, number];
|
|
127
|
+
};
|
|
128
|
+
children?: SceneNodeIR[];
|
|
129
|
+
}
|
|
130
|
+
export interface SvgSceneIR {
|
|
131
|
+
viewBox: [number, number, number, number];
|
|
132
|
+
nodes: SceneNodeIR[];
|
|
133
|
+
duration: number;
|
|
134
|
+
/** ★2026-09-09 Canvas 渐变:defs 里的渐变定义(id → 类型/stops/坐标)——
|
|
135
|
+
* Canvas fillStyle 不认 `url(#id)`,需运行时 createLinearGradient/createRadialGradient */
|
|
136
|
+
gradients?: Record<string, {
|
|
137
|
+
type: 'linear' | 'radial';
|
|
138
|
+
stops: Array<{
|
|
139
|
+
offset: number;
|
|
140
|
+
color: string;
|
|
141
|
+
opacity?: number;
|
|
142
|
+
}>;
|
|
143
|
+
x1?: number;
|
|
144
|
+
y1?: number;
|
|
145
|
+
x2?: number;
|
|
146
|
+
y2?: number;
|
|
147
|
+
cx?: number;
|
|
148
|
+
cy?: number;
|
|
149
|
+
r?: number;
|
|
150
|
+
units?: string;
|
|
151
|
+
}>;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* SVG 子树 → SvgScene(canvas 通道)。
|
|
155
|
+
* 返回 null:无形状变化动画(无需 canvas——用 image/CSS 方案即可)。
|
|
156
|
+
*/
|
|
157
|
+
export declare function lowerSvgToScene(node: ElementNode): SvgSceneIR | null;
|
package/dist/tags.d.ts
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
1
|
export declare const TAG_MAP: Record<string, string>;
|
|
2
2
|
export declare const EVENT_MAP: Record<string, string>;
|
|
3
|
+
/**
|
|
4
|
+
* ★v-gesture:<kind> → MP 原生事件名(2026-09-18)。
|
|
5
|
+
*
|
|
6
|
+
* 只登记**有真实原生事件对等**的手势。未登记者在编译器走「剥离 + 明示替代」路径
|
|
7
|
+
* (pan/pinch/rotate/press —— MP 无简单事件对等:官方用 worklet 手势处理器**组件**
|
|
8
|
+
* `<pan-gesture-handler>` 等(属性为 `worklet:ongesture` + 协商),非事件属性)。
|
|
9
|
+
*
|
|
10
|
+
* 依据:EVENT_MAP 的 `click: 'tap'` / `longpress: 'longpress'` 即原生真实事件;
|
|
11
|
+
* 官方 view 通用事件表含 tap/longpress(另有 touchstart/move/end/cancel)。
|
|
12
|
+
*/
|
|
13
|
+
export declare const GESTURE_MP_EVENTS: Record<string, string>;
|
|
14
|
+
/** 无事件对等手势的**具体**替代指引(反黑盒:不笼统说「无对等机制」) */
|
|
15
|
+
export declare const MP_GESTURE_ALTERNATIVES: Record<string, string>;
|
|
3
16
|
export declare const SEMANTIC_CLASS: Record<string, string>;
|
|
@@ -24,10 +24,16 @@ export interface TransformRule {
|
|
|
24
24
|
phase: TransformPhase;
|
|
25
25
|
/** 人类可读标题 */
|
|
26
26
|
title: string;
|
|
27
|
+
/** ★#483 英文标题变体(仅含中文的标题必填——语言中立标题可省略,回退 title) */
|
|
28
|
+
titleEn?: string;
|
|
27
29
|
/** what:输入 → 输出 */
|
|
28
30
|
description: string;
|
|
31
|
+
/** ★#480 英文变体 of description(官网 Playground/EN 态取用;缺省回退中文)——新增规则必填,tests/transforms.test.ts 硬卡全覆盖 */
|
|
32
|
+
descriptionEn?: string;
|
|
29
33
|
/** why:平台约束 / 设计决策(关联 PROJECT_MEMORY.md 决策号) */
|
|
30
34
|
why: string;
|
|
35
|
+
/** ★#483 英文 why 变体(必填——官网 EN rules 目录消费;缺省回退中文) */
|
|
36
|
+
whyEn?: string;
|
|
31
37
|
/** when:触发条件 */
|
|
32
38
|
when: string;
|
|
33
39
|
/** 前后对照示例(真实源码 / 真实产物) */
|
package/dist/types.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export type { TransformPhase, TransformTraceEvent, TransformTrace, TransformRuleOverrides, StyleTransformOptions, TemplateTransformOptions, TemplateTransformResult, ScriptTransformOptions, ScriptTransformResult, CompileOptions, CompileResult, } from '@proteus-vue/types/compiler-types';
|
|
1
|
+
export type { TransformPhase, TransformTraceEvent, TransformTrace, TransformRuleOverrides, Renderer, StyleTransformOptions, TemplateTransformOptions, TemplateTransformResult, ScriptTransformOptions, ScriptTransformResult, CompileOptions, CompileResult, CompileIR, TemplateIR, ScriptIR, } from '@proteus-vue/types/compiler-types';
|
package/dist/validate.d.ts
CHANGED
|
@@ -9,6 +9,22 @@ export declare function validateJs(js: string): {
|
|
|
9
9
|
ok: boolean;
|
|
10
10
|
error?: string;
|
|
11
11
|
};
|
|
12
|
+
/**
|
|
13
|
+
* ★#505 平台 JS 标准校验:扫描产物残留的微信编译器不解析的 ES2020 语法(?? ?. ??= ||= &&=)。
|
|
14
|
+
* 跳过字符串/模板/注释/正则字面量(产物注释里的 ?? 是文本非代码——#504 dist 实证唯一 ?? 在注释);
|
|
15
|
+
* 报告首处行号+列号。逻辑从 scripts/check-script-compile.mjs tripwire 内建进产物自校验链,
|
|
16
|
+
* 使 babel 转译失败路径(es5.ts error 返回原样代码)在 compileVueSfc 内兜底报红,而非依赖外部门禁。
|
|
17
|
+
*/
|
|
18
|
+
export declare function scanMpUnsafeEs5(js: string): {
|
|
19
|
+
kind: string;
|
|
20
|
+
line: number;
|
|
21
|
+
col: number;
|
|
22
|
+
} | null;
|
|
23
|
+
/** ★#505 平台 JS 标准校验入口:残留 ES2020 → 校验失败(微信开发者工具 babel 不解析) */
|
|
24
|
+
export declare function validateMpJsPlatform(js: string): {
|
|
25
|
+
ok: boolean;
|
|
26
|
+
error?: string;
|
|
27
|
+
};
|
|
12
28
|
/** WXML 标签配对校验(先剥离注释,避免行号注释中的标签文本干扰) */
|
|
13
29
|
export declare function validateWxml(wxml: string): {
|
|
14
30
|
ok: boolean;
|
|
@@ -16,3 +32,17 @@ export declare function validateWxml(wxml: string): {
|
|
|
16
32
|
};
|
|
17
33
|
/** 校验整包编译结果,失败抛 CompilerError */
|
|
18
34
|
export declare function assertValidResult(result: CompileResult, filename: string): void;
|
|
35
|
+
/** 单条 wxml 平台违规(code = 官方 ParseErrorKind 蓝本) */
|
|
36
|
+
export interface WxmlPlatformIssue {
|
|
37
|
+
code: 'DataBindingNotAllowed' | 'DuplicatedAttribute' | 'AvoidUppercaseLetters' | 'UnsupportedSyntax' | 'InvalidAttribute' | 'DuplicatedStylePropertyNames';
|
|
38
|
+
message: string;
|
|
39
|
+
/** wxml 字符偏移(定位用) */
|
|
40
|
+
at: number;
|
|
41
|
+
}
|
|
42
|
+
/** wxml 平台标准扫描(蓝本 glass-easel ParseErrorKind) */
|
|
43
|
+
export declare function scanWxmlPlatformIssues(wxml: string): WxmlPlatformIssue[];
|
|
44
|
+
/** wxml 平台标准校验入口:任一官方错误码命中 → 校验失败 */
|
|
45
|
+
export declare function validateWxmlPlatform(wxml: string): {
|
|
46
|
+
ok: boolean;
|
|
47
|
+
error?: string;
|
|
48
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** 对齐状态 */
|
|
2
|
+
export type VueCompatStatus = 'aligned' | 'partial' | 'unsupported';
|
|
3
|
+
/** Vue 能力类别 */
|
|
4
|
+
export type VueCompatGroup = 'reactivity' | 'component' | 'lifecycle' | 'template' | 'sfc';
|
|
5
|
+
export interface VueCompatEntry {
|
|
6
|
+
/** Vue 公共 API / SFC 特性名(对齐 @vue/* 导出名或模板能力名) */
|
|
7
|
+
name: string;
|
|
8
|
+
group: VueCompatGroup;
|
|
9
|
+
/** 对齐状态 */
|
|
10
|
+
status: VueCompatStatus;
|
|
11
|
+
/** unsupported/partial 时:有降级策略 → true(编译期 warning);无 → false/undefined(编译期 error) */
|
|
12
|
+
degrade?: boolean;
|
|
13
|
+
/** 说明 / 替代建议(unsupported/partial 必填) */
|
|
14
|
+
note?: string;
|
|
15
|
+
/** 状态来源(vue-compat §1 / advance batch / roadmap / 实测评估) */
|
|
16
|
+
source: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* ★Vue 全能力基准线(SSOT)。随 Vue 版本演进:重拉 @vue/* 导出 + 复评状态(版本变更流程)。
|
|
20
|
+
* 不可置疑性:name 集 = @vue/runtime-core + @vue/reactivity + @vue/shared 公共导出 + SFC 模板/指令/内置组件面。
|
|
21
|
+
*/
|
|
22
|
+
export declare const VUE_COMPAT_MATRIX: VueCompatEntry[];
|
|
23
|
+
/** ★Vue 公共常量导出(编译期内联值):`const v = <name>` 时把裸标识符内联为字面量(替代运行时轮询 undefined)。
|
|
24
|
+
* 版本号与 02-api-gap 基线「Vue 全集权威来源」的 @vue/runtime-core@3.5.42 对齐;随 Vue 版本演进同步。 */
|
|
25
|
+
export declare const VUE_PUBLIC_CONSTS: Record<string, unknown>;
|
|
26
|
+
/** ★2026-09-09 别名机制(真机复测发现的命名错配):矩阵 template 组按**模板形态**登记(`<teleport>`/`<keep-alive>`…),
|
|
27
|
+
* 而开发者按 Vue 官方文档常写 PascalCase 组件导入(`import { Teleport } from 'vue'`)——同一能力两种写法,
|
|
28
|
+
* 未登记形态落 VUE_COMPAT_UNKNOWN 报「可能为 Vue 内部导出」= 矛盾结论(`<teleport>` 明明 aligned)。
|
|
29
|
+
* 别名表:PascalCase 导出名 → 已登记模板形态名。查询先查矩阵,未命中再查别名(返回同一 entry,状态一致)。 */
|
|
30
|
+
export declare const VUE_COMPAT_ALIASES: Record<string, string>;
|
|
31
|
+
/** ★2026-09-09 Vue 内部导出集合(@vue/runtime-core + @vue/reactivity + @vue/shared 的非用户面导出)。
|
|
32
|
+
* 这些符号开发者不应手写(编译期已生成对等结构 / 运行时内部机制 / SSR / 自定义渲染器)——
|
|
33
|
+
* 统一归 unsupported 并给出准确说明,替代「可能是 Vue 内部导出」的模糊兜底。
|
|
34
|
+
* 维护:Vue 版本升级后跑 tests/vue-compat-coverage.test.ts(对比运行时导出,新增未分类项即红)。 */
|
|
35
|
+
export declare const VUE_INTERNAL_EXPORTS: Set<string>;
|
|
36
|
+
/** ★矩阵外/未知的 Vue 命名导入处理:默认按 unsupported(无降级→error)——反黑盒兜底,防静默未定义引用 */
|
|
37
|
+
export declare const VUE_COMPAT_UNKNOWN: VueCompatEntry;
|
|
38
|
+
/** ★内部导出条目(VUE_INTERNAL_EXPORTS 命中时返回——准确说明替代「可能为内部导出」的模糊兜底) */
|
|
39
|
+
export declare const VUE_COMPAT_INTERNAL: VueCompatEntry;
|
|
40
|
+
/** 查询 Vue 能力的对齐状态;未登记 → 别名表 → 内部导出集合 → VUE_COMPAT_UNKNOWN(均 unsupported 无降级 → error) */
|
|
41
|
+
export declare function vueCompatStatus(name: string): VueCompatEntry;
|
|
42
|
+
/** 根据状态 + degrade 判断编译期提示级别:aligned=null(无提示);partial 或 (unsupported+degrade)=(warning);unsupported 无 degrade=(error) */
|
|
43
|
+
export declare function vueCompatLevel(entry: VueCompatEntry): 'none' | 'warning' | 'error';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@proteus-vue/compiler",
|
|
3
|
-
"version": "0.3.0-beta.
|
|
3
|
+
"version": "0.3.0-beta.3",
|
|
4
4
|
"description": "Proteus 编译引擎 —— 标准 Vue SFC → 小程序四件套(纯函数、零运行时依赖、规则注册表 + AI 说明书)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -23,20 +23,28 @@
|
|
|
23
23
|
"dist",
|
|
24
24
|
"README.md"
|
|
25
25
|
],
|
|
26
|
-
"scripts": {
|
|
27
|
-
"prepare": "npm run build",
|
|
28
|
-
"build": "tsc -p tsconfig.build.json --emitDeclarationOnly && esbuild src/index.ts src/style-safety/index.ts --bundle --format=esm --platform=node --outdir=dist --external:@vue/compiler-sfc --external:@vue/compiler-dom --external:@proteus-vue/contracts"
|
|
29
|
-
},
|
|
30
26
|
"peerDependencies": {
|
|
31
|
-
"@vue/compiler-
|
|
32
|
-
"@vue/compiler-
|
|
27
|
+
"@vue/compiler-dom": "^3.4",
|
|
28
|
+
"@vue/compiler-sfc": "^3.4"
|
|
33
29
|
},
|
|
34
30
|
"devDependencies": {
|
|
35
|
-
"@
|
|
36
|
-
"@
|
|
31
|
+
"@babel/parser": "7.29.8",
|
|
32
|
+
"@types/babel__core": "^7.20.5",
|
|
33
|
+
"@vue/compiler-dom": "^3.5.42",
|
|
34
|
+
"@vue/compiler-sfc": "^3.5.42"
|
|
37
35
|
},
|
|
38
36
|
"dependencies": {
|
|
39
|
-
"@
|
|
40
|
-
"@
|
|
37
|
+
"@babel/core": "^7.29.0",
|
|
38
|
+
"@babel/plugin-transform-logical-assignment-operators": "^7.29.0",
|
|
39
|
+
"@babel/plugin-transform-nullish-coalescing-operator": "^7.29.0",
|
|
40
|
+
"@babel/plugin-transform-numeric-separator": "^8.0.1",
|
|
41
|
+
"@babel/plugin-transform-object-rest-spread": "^7.29.0",
|
|
42
|
+
"@babel/plugin-transform-optional-chaining": "^7.29.0",
|
|
43
|
+
"@proteus-vue/component-ir": "0.2.0-beta.1",
|
|
44
|
+
"@proteus-vue/contracts": "0.1.1-beta.0",
|
|
45
|
+
"@proteus-vue/types": "0.2.0-beta.2"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsc -p tsconfig.build.json --emitDeclarationOnly && esbuild src/index.ts src/style-safety/index.ts --bundle --format=esm --platform=node --outdir=dist --external:@vue/compiler-sfc --external:@vue/compiler-dom --external:@proteus-vue/contracts --external:@proteus-vue/component-ir --external:@babel/core --external:@babel/plugin-transform-nullish-coalescing-operator --external:@babel/plugin-transform-optional-chaining --external:@babel/plugin-transform-logical-assignment-operators --external:@babel/plugin-transform-object-rest-spread"
|
|
41
49
|
}
|
|
42
|
-
}
|
|
50
|
+
}
|
package/dist/explain.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
// src/compiler/explain.ts
|
|
2
|
-
// explainTransform —— 阶段二核心:对一份 Vue SFC 输出它实际触发的全部转换规则(决策 trace)
|
|
3
|
-
// AI 用法:改完编译器 / 写完页面后,跑 explainTransform 看转换链路,理解"为什么产物是这样"。
|
|
4
|
-
import { parse as sfcParse } from '@vue/compiler-sfc';
|
|
5
|
-
import { transformTemplateToWxml } from './template';
|
|
6
|
-
import { transformScriptToPage } from './script';
|
|
7
|
-
import { transformStyleToWxss } from './style';
|
|
8
|
-
import { createTrace } from './trace';
|
|
9
|
-
/** 对一份 Vue SFC 源码执行全链路转换并收集决策 trace */
|
|
10
|
-
export function explainTransform(source, options = {}) {
|
|
11
|
-
const { descriptor } = sfcParse(source, { filename: options.filename ?? 'anonymous.vue' });
|
|
12
|
-
const styleOpts = { px2rpx: options.px2rpx ?? true, rpxRatio: options.rpxRatio ?? 2 };
|
|
13
|
-
const events = [];
|
|
14
|
-
// template 阶段(vModelBindings / usesNavigate 传给 script 阶段)
|
|
15
|
-
const tplTrace = createTrace('template');
|
|
16
|
-
const tpl = descriptor.template?.content ?? '';
|
|
17
|
-
const tplResult = transformTemplateToWxml(tpl, {
|
|
18
|
-
...styleOpts,
|
|
19
|
-
filename: options.filename,
|
|
20
|
-
annotateLines: options.annotateLines,
|
|
21
|
-
rules: options.rules,
|
|
22
|
-
trace: tplTrace,
|
|
23
|
-
});
|
|
24
|
-
events.push(...tplTrace.events);
|
|
25
|
-
// script 阶段
|
|
26
|
-
const setup = descriptor.scriptSetup?.content ?? descriptor.script?.content ?? '';
|
|
27
|
-
const scriptTrace = createTrace('script');
|
|
28
|
-
transformScriptToPage(setup, styleOpts, {
|
|
29
|
-
file: options.filename,
|
|
30
|
-
isComponent: options.isComponent,
|
|
31
|
-
vModelBindings: tplResult.vModelBindings,
|
|
32
|
-
usesNavigate: tplResult.usesNavigate,
|
|
33
|
-
rules: options.rules,
|
|
34
|
-
trace: scriptTrace,
|
|
35
|
-
});
|
|
36
|
-
events.push(...scriptTrace.events);
|
|
37
|
-
// style 阶段
|
|
38
|
-
const styleTrace = createTrace('style');
|
|
39
|
-
transformStyleToWxss(descriptor.styles.map((s) => s.content).join('\n'), { ...styleOpts, rules: options.rules, trace: styleTrace });
|
|
40
|
-
events.push(...styleTrace.events);
|
|
41
|
-
return { filename: options.filename, events };
|
|
42
|
-
}
|
|
43
|
-
/** 渲染决策 trace 为人类可读文本(按阶段分组 + 行号) */
|
|
44
|
-
export function formatTransformTrace(result) {
|
|
45
|
-
const phases = ['template', 'script', 'style', 'validate'];
|
|
46
|
-
const blocks = [];
|
|
47
|
-
for (const phase of phases) {
|
|
48
|
-
const evts = result.events.filter((e) => e.phase === phase);
|
|
49
|
-
if (!evts.length)
|
|
50
|
-
continue;
|
|
51
|
-
const lines = evts.map((e) => {
|
|
52
|
-
const line = e.line != null ? `L${e.line} ` : '';
|
|
53
|
-
const detail = [e.before, e.after].filter(Boolean).join(' → ');
|
|
54
|
-
return ` ${line}${e.ruleId}${detail ? `:${detail}` : ''}`;
|
|
55
|
-
});
|
|
56
|
-
blocks.push(`### ${phase} 阶段(${evts.length} 个决策)\n${lines.join('\n')}`);
|
|
57
|
-
}
|
|
58
|
-
return `# explainTransform ${result.filename ?? ''}\n\n${blocks.join('\n\n')}`;
|
|
59
|
-
}
|
package/dist/overrides.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
// src/compiler/overrides.ts
|
|
2
|
-
// 规则覆盖解析 —— ★底线循环 ①③:AI / proteus.config.ts 改写或禁用编译规则,编译器即时生效
|
|
3
|
-
// 所有转换函数(template/style/script)从本模块取"生效的映射表 + 禁用集",不再直接读 tags.ts 常量
|
|
4
|
-
import { TAG_MAP, EVENT_MAP, SEMANTIC_CLASS } from './tags';
|
|
5
|
-
import { getTransformRule } from './transforms/registry';
|
|
6
|
-
/** 解析规则覆盖:合并 tags.ts 常量 + 覆盖补丁;未知规则 ID 编译期警告(防配置笔误) */
|
|
7
|
-
export function resolveOverrides(options) {
|
|
8
|
-
const tagMap = { ...TAG_MAP };
|
|
9
|
-
const eventMap = { ...EVENT_MAP };
|
|
10
|
-
const semanticClass = { ...SEMANTIC_CLASS };
|
|
11
|
-
const disabled = new Set(options?.disabled ?? []);
|
|
12
|
-
for (const [ruleId, patch] of Object.entries(options?.mapping ?? {})) {
|
|
13
|
-
const rule = getTransformRule(ruleId);
|
|
14
|
-
if (!rule) {
|
|
15
|
-
console.warn(`[proteus] 规则覆盖引用了未注册的规则 ID:${ruleId}(已忽略,可用 listTransformRules() 查看合法 ID)`);
|
|
16
|
-
continue;
|
|
17
|
-
}
|
|
18
|
-
if (rule.id.startsWith('tag/'))
|
|
19
|
-
Object.assign(tagMap, patch);
|
|
20
|
-
else if (rule.id === 'event/click-to-tap')
|
|
21
|
-
Object.assign(eventMap, patch);
|
|
22
|
-
else if (rule.id === 'semantic/base-class')
|
|
23
|
-
Object.assign(semanticClass, patch);
|
|
24
|
-
else
|
|
25
|
-
console.warn(`[proteus] 规则 ${ruleId} 不支持 mapping 覆盖(仅 tag/* / event/click-to-tap / semantic/base-class)`);
|
|
26
|
-
}
|
|
27
|
-
// 自定义标签映射:AI 扩展新标签的入口(最高优先级)
|
|
28
|
-
Object.assign(tagMap, options?.customTags);
|
|
29
|
-
for (const id of disabled) {
|
|
30
|
-
if (!getTransformRule(id))
|
|
31
|
-
console.warn(`[proteus] 规则覆盖禁用了未注册的规则 ID:${id}(已忽略)`);
|
|
32
|
-
}
|
|
33
|
-
return { tagMap, eventMap, semanticClass, disabled };
|
|
34
|
-
}
|