@ptengine/lp-editor-core 1.0.0-alpha.2 → 1.0.0-alpha.4
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/README.md +28 -3
- package/dist/golden/component-cases.json +550 -0
- package/dist/golden/fixtures/page/01-etvos-article-lp.html +1 -1
- package/dist/golden/fixtures/page/02-vivaia-campaign-lp.html +1 -1
- package/dist/golden/fixtures/popup/14-back-to-school-email-form.html +1 -1
- package/dist/golden/fixtures/popup/15-xtool-ebook-split-form.html +1 -1
- package/dist/golden/fixtures/popup/16-880-off-gradient-form.html +1 -1
- package/dist/golden/fixtures/popup/README.md +9 -4
- package/dist/golden/manifest.json +421 -6
- package/dist/golden/verify.mjs +36 -2
- package/dist/index.d.ts +585 -246
- package/dist/index.js +1047 -83
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/golden/verify.mjs
CHANGED
|
@@ -39,13 +39,20 @@ const core = await import(join(here, '..', 'index.js'));
|
|
|
39
39
|
const manifest = JSON.parse(readFileSync(join(here, 'manifest.json'), 'utf8'));
|
|
40
40
|
const opsData = JSON.parse(readFileSync(join(here, 'ops-cases.json'), 'utf8'));
|
|
41
41
|
const opsByName = new Map(opsData.cases.map(c => [c.name, c]));
|
|
42
|
+
const componentData = JSON.parse(readFileSync(join(here, 'component-cases.json'), 'utf8'));
|
|
43
|
+
const componentByName = new Map(componentData.cases.map(c => [c.name, c]));
|
|
42
44
|
|
|
43
45
|
const DOMParser = new JSDOM('').window.DOMParser;
|
|
44
|
-
const { parse } = core.createCore({ DOMParser });
|
|
46
|
+
const { parse, wrap } = core.createCore({ DOMParser });
|
|
45
47
|
const hostDoc = parse('<!DOCTYPE html><body>');
|
|
46
48
|
|
|
47
49
|
const sha = s => createHash('sha256').update(s, 'utf8').digest('hex');
|
|
48
50
|
|
|
51
|
+
/** 同一份输入的片段条目哈希,供 wrap 分支内联断言往返一致。 */
|
|
52
|
+
const fragmentSha = new Map(
|
|
53
|
+
manifest.fixtures.filter(f => f.kind === 'fragment').map(f => [f.input, f.sha256])
|
|
54
|
+
);
|
|
55
|
+
|
|
49
56
|
function compute(entry) {
|
|
50
57
|
if (entry.kind === 'document') {
|
|
51
58
|
return core.serialize(parse(readFileSync(join(here, entry.input), 'utf8')));
|
|
@@ -55,13 +62,40 @@ function compute(entry) {
|
|
|
55
62
|
core.parseFragment(hostDoc, readFileSync(join(here, entry.input), 'utf8'))
|
|
56
63
|
);
|
|
57
64
|
}
|
|
65
|
+
if (entry.kind === 'wrap') {
|
|
66
|
+
const html = readFileSync(join(here, entry.input), 'utf8');
|
|
67
|
+
const doc = wrap(html);
|
|
68
|
+
// 往返:剥回来的片段,规范序列化后必须与同名 fragment 条目逐字节相同。
|
|
69
|
+
// 这条不单列清单条目,就地断言 —— 包裹有损的话症状滞后数天,必须在这里挡住。
|
|
70
|
+
const expected = fragmentSha.get(entry.input);
|
|
71
|
+
if (expected === undefined) {
|
|
72
|
+
throw new Error(`清单里缺少 ${entry.input} 的 fragment 条目,往返无从比对`);
|
|
73
|
+
}
|
|
74
|
+
const roundTrip = sha(core.serialize(core.unwrap(doc)));
|
|
75
|
+
if (roundTrip !== expected) {
|
|
76
|
+
throw new Error(
|
|
77
|
+
`wrap/unwrap 往返不一致\n 期望 ${expected}\n 实际 ${roundTrip}`
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
return core.serialize(doc);
|
|
81
|
+
}
|
|
82
|
+
// 组件三件产物。css / js 的「输入」就是类型 id(它们不吃设置),
|
|
83
|
+
// html 的输入是取样文件里的一条用例。
|
|
84
|
+
if (entry.kind === 'component-css') return core.components.renderCss(entry.input.split('#')[1]);
|
|
85
|
+
if (entry.kind === 'component-js') return core.components.renderJs(entry.input.split('#')[1]);
|
|
86
|
+
if (entry.kind === 'component-html') {
|
|
87
|
+
const name = entry.input.split('#')[1];
|
|
88
|
+
const c = componentByName.get(name);
|
|
89
|
+
if (!c) throw new Error(`component-cases.json 里找不到用例 ${name}`);
|
|
90
|
+
return core.components.renderHtml(c.type, c.settings, c.id);
|
|
91
|
+
}
|
|
58
92
|
if (entry.kind === 'apply') {
|
|
59
93
|
const name = entry.input.split('#')[1];
|
|
60
94
|
const c = opsByName.get(name);
|
|
61
95
|
if (!c) throw new Error(`ops-cases.json 里找不到用例 ${name}`);
|
|
62
96
|
const html = opsData.wrapper.replace('{{HEAD_EXTRA}}', '').replace('{{BODY}}', c.body);
|
|
63
97
|
const doc = parse(html);
|
|
64
|
-
const r = core.apply(doc, c.ops
|
|
98
|
+
const r = core.apply(doc, c.ops);
|
|
65
99
|
if (!r.ok) throw new Error(`apply 失败 ${r.error.code} @${r.failedIndex}`);
|
|
66
100
|
return core.serialize(doc);
|
|
67
101
|
}
|