Files
2026-09-03 08:38:17 +08:00

42 lines
2.5 KiB
JavaScript

// Inspect actual native resources, not merely the source template or H5 output.
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import { resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import ts from 'typescript';
const root = fileURLToPath(new URL('../', import.meta.url));
const output = resolve(root, process.argv[2] || 'dist/build/app');
const service = readFileSync(resolve(output, 'app-service.js'), 'utf8');
assert.ok(service.includes('data:image/svg+xml;charset=utf-8,'), 'App bundle is missing embedded icon data');
assert.ok(service.includes('-webkit-mask-image') && service.includes('mask-image'), 'App bundle is missing mask bindings');
const ast = ts.createSourceFile('app-service.js', service, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
function visit(node) {
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)
&& ['resolveComponent', 'createElementVNode', 'createVNode', 'createElementBlock'].includes(node.expression.name.text)
&& node.arguments.length > 0
&& ts.isStringLiteral(node.arguments[0]) && ['svg', 'path'].includes(node.arguments[0].text)) {
throw new Error(`Native bundle still contains an unsupported ${node.arguments[0].text} template element`);
}
ts.forEachChild(node, visit);
}
visit(ast);
for (const page of ['home', 'nearby', 'messages', 'feed', 'profile', 'chat', 'membership']) {
const css = readFileSync(resolve(output, `pages/${page}/index.css`), 'utf8');
assert.match(css, /\.app-icon\[/, `${page}: missing shared icon CSS`);
for (const declaration of ['background-color:currentColor', '-webkit-mask-size:100% 100%', 'mask-size:100% 100%']) {
assert.ok(css.includes(declaration), `${page}: missing ${declaration}`);
}
if (['home', 'nearby', 'messages', 'feed', 'profile'].includes(page)) {
const button = css.match(/\.nav-item\[[^\]]+\]\{([^}]+)\}/)?.[1];
for (const declaration of ['width:100%', 'margin:0', 'overflow:visible', 'line-height:1']) {
assert.ok(button?.split(';').includes(declaration), `${page}: bottom tab missing ${declaration}`);
}
const badge = css.match(/\.badge\[[^\]]+\]\{([^}]+)\}/)?.[1];
for (const declaration of ['display:flex', 'white-space:nowrap', 'pointer-events:none']) {
assert.ok(badge?.split(';').includes(declaration), `${page}: unread badge missing ${declaration}`);
}
}
}
console.log('App 图标产物检查通过:内置图形、WebKit 兼容样式、消息角标防裁切样式齐全,无原始 SVG 模板组件。');