Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ QuantPilot is not a production live-trading system. It is a platform skeleton an

| Category | Technology |
|----------|------------|
| Language | TypeScript 5 (100% first-party source, no new JavaScript source files) |
| Language | TypeScript 5 (TypeScript-first first-party source; no new JavaScript source files in `apps`, `packages`, or `scripts`) |
| Frontend | React 18 + react-router-dom 6 |
| Build | Vite 5 |
| Styling | vanilla-extract |
Expand Down
2 changes: 1 addition & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ QuantPilot 不是一个可直接用于实盘的生产交易系统。它当前定

| 类别 | 技术 |
|------|------|
| 语言 | TypeScript 5(第一方源码 100%,禁止新增 JavaScript 源文件) |
| 语言 | TypeScript 5(第一方源码 TypeScript-first;`apps`、`packages`、`scripts` 中禁止新增 JavaScript 源文件) |
| 前端 | React 18 + react-router-dom 6 |
| 构建 | Vite 5 |
| 样式 | vanilla-extract |
Expand Down
25 changes: 19 additions & 6 deletions scripts/check-no-js-source.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { execFileSync } from 'node:child_process';
import { readdirSync } from 'node:fs';
import { join, relative } from 'node:path';

const repoRoot = process.cwd();
const sourceRoots = ['apps', 'packages', 'scripts'];
const blockedExtensions = new Set(['.js', '.mjs', '.cjs']);
const blockedExtensions = new Set(['.js', '.jsx', '.mjs', '.cjs']);
const ignoredDirs = new Set(['node_modules', 'dist', 'coverage', '.git', '.vite']);

function walk(dirPath: string, hits: string[]) {
Expand All @@ -25,24 +26,36 @@ function walk(dirPath: string, hits: string[]) {
}
}

function findTrackedJavaScriptFiles() {
const output = execFileSync('git', ['ls-files', '*.js', '*.jsx', '*.mjs', '*.cjs'], {
cwd: repoRoot,
encoding: 'utf8',
});

return output.split('\n').filter(Boolean);
}

function main() {
const hits: string[] = [];
const trackedHits = findTrackedJavaScriptFiles();

for (const sourceRoot of sourceRoots) {
walk(join(repoRoot, sourceRoot), hits);
}

if (hits.length > 0) {
console.error('JavaScript source files are not allowed in first-party source roots.');
console.error('Migrate these files to TypeScript instead:');
for (const hit of hits.sort()) {
const allHits = Array.from(new Set([...trackedHits, ...hits])).sort();

if (allHits.length > 0) {
console.error('JavaScript files are not allowed in first-party source or tracked files.');
console.error('Migrate these files to TypeScript or remove generated artifacts from Git:');
for (const hit of allHits) {
console.error(`- ${hit}`);
}
process.exitCode = 1;
return;
}

console.info('No JavaScript source files found in first-party source roots.');
console.info('No JavaScript files found in first-party source roots or Git-tracked files.');
}

main();
Loading