fix: resolve build imports before linting
Backend verify / commits (pull_request) Successful in 29s
Backend verify / security (pull_request) Successful in 8s
Backend verify / verify (pull_request) Failing after 11m25s

Resolve dist imports in runtime scripts against their TypeScript sources.

Keep missing-module checks enabled and cover absent build output in the lint gate.

Verified npm ci, prisma generate and full verify with dist absent at startup.
This commit is contained in:
2026-09-28 15:48:44 +03:00
parent 33a5135741
commit 7d2262fb43
2 changed files with 41 additions and 0 deletions
+29
View File
@@ -1,9 +1,38 @@
const { ESLint } = require('eslint');
const assert = require('node:assert/strict');
const { mkdtempSync, rmSync, writeFileSync } = require('node:fs');
const { basename, join } = require('node:path');
const { test } = require('node:test');
const eslint = new ESLint();
test('runtime scripts resolve build imports against sources before dist exists', async () => {
const directory = mkdtempSync(join(process.cwd(), '.eslint-require-'));
try {
// eslint-disable-next-line security/detect-non-literal-fs-filename -- Test-owned temporary source with no compiled counterpart.
writeFileSync(join(directory, 'entry.ts'), 'export const value = true;');
for (const [filePath, prefix] of [
['scripts/generate-openapi.cjs', '../'],
['test/runtime-check.cjs', '../'],
['test/fixtures/tbank-sync-crash.cjs', '../../'],
]) {
const source = `${prefix}dist/${basename(directory)}/entry`;
const [result] = await eslint.lintText(
`require('${source}.js'); require('${source}'); require('node:fs'); require('eslint'); require('${source}-missing.js'); require('${prefix}missing-local.cjs'); require('wealthledger-missing-package');`,
{ filePath },
);
assert.equal(result.fatalErrorCount, 0, filePath);
const missing = result.messages.filter(({ ruleId }) => ruleId === 'n/no-missing-require');
assert.equal(missing.length, 3, filePath);
for (const target of [`${source}-missing.js`, `${prefix}missing-local.cjs`, 'wealthledger-missing-package']) {
assert.ok(missing.some(({ message }) => message.includes(`'${target}'`)), target);
}
}
} finally {
rmSync(directory, { recursive: true, force: true });
}
});
// Protect the quality gate's file scopes when configs or plugin versions change.
test('typed application code enforces async and unsafe-type checks', async () => {
const [result] = await eslint.lintText(