Files
Codex 0d9320fe1d refactor: extract the base styles and finish the aggregator (#266 slice 5/5)
52 блока host/переменных/кросс-поверхностных групп → src/styles/base.styles.ts;
styles.ts — 19-строчный сборщик [base, plan, devices, chrome, dialogs] с
задокументированным контрактом порядка каскада. Два оставшихся мутантных
якоря (:host-гейт ховера устройств) переадресованы на base.styles.ts.

Юниты инвариантов (test/styles-split.test.mjs): состав и порядок сборщика;
непересечение (scope+селектор) между файлами — единственное именованное
исключение: кросс-поверхностная группа «:host(...) .dev:hover, .dev:focus-
visible» живёт в base по §1.1; выживание медиа-обёрток — 2 forced-colors и
10 prefers-reduced-motion (в ТЗ и ревью фигурировали 8 — фактический счёт по
исходнику 10, юнит держит точное число). fix-test-build научился точке в
имени модуля (styles/base.styles → .js). ARCHITECTURE.md — раздел Styles.

Refactor-proof diff (scope-ключ) пуст; golden 129/129 без переприёмки; смоки
plan_snap_overlay/preloader OK; npm test 1318/0; бандл 1 291 440 → 1 291 458
(+18 байт).

Issue: #266
User-Visible: no
2026-08-26 01:34:20 +03:00

29 lines
1.1 KiB
JavaScript

// tsc keeps extensionless relative imports; Node ESM requires explicit ".js".
// Walk the complete output tree: feature modules may import siblings from a
// nested directory, and a root-only pass leaves those suites unable to start.
import { readdirSync, readFileSync, writeFileSync } from 'node:fs';
import { extname, join } from 'node:path';
const patchImports = (dir) => {
for (const entry of readdirSync(dir, { withFileTypes: true })) {
const path = join(dir, entry.name);
if (entry.isDirectory()) {
patchImports(path);
continue;
}
if (!entry.name.endsWith('.js')) continue;
const source = readFileSync(path, 'utf8').replace(
/(from\s+['"]|import\s*\(\s*['"])(\.\.?\/[^'"]+)(['"])/g,
(match, prefix, specifier, suffix) => (
// A dot inside the module NAME is not an extension: `./styles/base.styles`
// must still get `.js` (#266). Only real loader extensions pass through.
['.js', '.mjs', '.json'].includes(extname(specifier))
? match : `${prefix}${specifier}.js${suffix}`
),
);
writeFileSync(path, source);
}
};
patchImports('test-build');