프로필 UI 글자 크기를 네 단계와 공통 축소 규칙으로 통일한다
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { createRequire } from 'node:module';
|
||||
import { pathToFileURL, fileURLToPath } from 'node:url';
|
||||
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
|
||||
const require = createRequire(path.join(root, 'app/game-frontend/package.json'));
|
||||
const ts = require('typescript');
|
||||
const out = path.join(process.env.TYPOGRAPHY_OUTPUT_DIR ?? path.join(root, 'test-results/typography-audit'), 'modules');
|
||||
fs.mkdirSync(out, { recursive: true });
|
||||
const cache = new Map();
|
||||
export async function fixture(relative) {
|
||||
const url = compile(path.join(root, relative));
|
||||
return import(url);
|
||||
}
|
||||
function compile(filename) {
|
||||
if (cache.has(filename)) return cache.get(filename);
|
||||
const target = path.join(
|
||||
out,
|
||||
path
|
||||
.relative(root, filename)
|
||||
.replaceAll('/', '__')
|
||||
.replace(/\.tsx?$/, '.mjs')
|
||||
);
|
||||
const url = pathToFileURL(target).href;
|
||||
cache.set(filename, url);
|
||||
let source = fs
|
||||
.readFileSync(filename, 'utf8')
|
||||
.replaceAll('import.meta.url', JSON.stringify(pathToFileURL(filename).href))
|
||||
.replaceAll('import.meta.dirname', JSON.stringify(path.dirname(filename)));
|
||||
const ast = ts.createSourceFile(filename, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
||||
const pieces = [],
|
||||
names = [];
|
||||
for (const node of ast.statements) {
|
||||
// Reuse only original fixture definitions, never register/execute the tests.
|
||||
if (
|
||||
ts.isImportDeclaration(node) ||
|
||||
ts.isTypeAliasDeclaration(node) ||
|
||||
ts.isInterfaceDeclaration(node) ||
|
||||
ts.isFunctionDeclaration(node) ||
|
||||
ts.isClassDeclaration(node) ||
|
||||
ts.isVariableStatement(node)
|
||||
) {
|
||||
pieces.push(node.getFullText(ast));
|
||||
if (ts.isVariableStatement(node))
|
||||
for (const dec of node.declarationList.declarations)
|
||||
if (ts.isIdentifier(dec.name)) names.push(dec.name.text);
|
||||
if (ts.isFunctionDeclaration(node) && node.name) names.push(node.name.text);
|
||||
}
|
||||
}
|
||||
const isSpec = filename.endsWith('.spec.ts');
|
||||
const input = isSpec ? pieces.join('\n') + '\nexport { ' + names.join(', ') + ' };' : source;
|
||||
let js = ts.transpileModule(input, {
|
||||
compilerOptions: { target: ts.ScriptTarget.ES2022, module: ts.ModuleKind.ESNext },
|
||||
}).outputText;
|
||||
js = js.replace(/(from\s*|import\s*)['"]([^'"]+)['"]/g, (match, prefix, spec) => {
|
||||
if (spec.startsWith('node:')) return match;
|
||||
let dest;
|
||||
if (spec.startsWith('.')) {
|
||||
dest = path.resolve(path.dirname(filename), spec);
|
||||
if (!fs.existsSync(dest) && dest.endsWith('.js')) dest = dest.replace(/\.js$/, '.ts');
|
||||
if (!fs.existsSync(dest)) {
|
||||
if (fs.existsSync(dest + '.ts')) dest += '.ts';
|
||||
else if (fs.existsSync(dest + '.js')) dest += '.js';
|
||||
}
|
||||
dest = dest.endsWith('.ts') ? compile(dest) : pathToFileURL(dest).href;
|
||||
} else {
|
||||
let resolved = createRequire(filename).resolve(spec);
|
||||
if (spec === '@playwright/test') resolved = resolved.replace(/index\.js$/, 'index.mjs');
|
||||
dest = pathToFileURL(resolved).href;
|
||||
}
|
||||
return prefix + JSON.stringify(dest);
|
||||
});
|
||||
fs.writeFileSync(target, js);
|
||||
return url;
|
||||
}
|
||||
Reference in New Issue
Block a user