snapshot of https://github.com/tldraw/tldraw.git (main, 2026-09-23; blobs > 131072B omitted)
Some checks failed
Deploy analytics worker / Deploy analytics worker to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
i18n upload strings / Upload latest strings (push) Failing after 1s
Deploy bemo / Deploy bemo to ${{ (github.ref == 'refs/heads/bemo-production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
Deploy grafana resources / ${{ github.event_name == 'push' && 'Deploy grafana resources' || 'Validate grafana resources (dry run)' }} (push) Failing after 0s
End to end tests (dotcom) / Check for relevant changes (push) Failing after 0s
End to end tests (examples) / Check for relevant changes (push) Failing after 0s
End to end tests (mermaid readability) / Check for relevant changes (push) Failing after 1s
End to end tests (perf) / Check for relevant changes (push) Failing after 0s
Publish editor extensions / Publish editor extensions (push) Failing after 1s
Publish SDK packages / Remove the publish-packages label (push) Has been skipped
Checks / Tests & checks (push) Has been cancelled
Checks / Build all projects (push) Has been cancelled
Deploy templates / Deploy templates (push) Has been cancelled
End to end tests (dotcom) / End to end tests (dotcom) (push) Has been cancelled
End to end tests (mermaid readability) / End to end tests (mermaid readability) (push) Has been cancelled
End to end tests (perf) / End to end tests (perf) (push) Has been cancelled
Deploy .com / Deploy dotcom to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Has been cancelled
End to end tests (examples) / End to end tests (examples) (push) Has been cancelled
Publish SDK packages / Publish SDK packages (push) Has been cancelled
Publish SDK packages / Tell user released version (push) Has been cancelled
Publish SDK packages / Publishes code templates to separate repositories (push) Has been cancelled
Publish SDK packages / Deploys the template demos with the new SDK version (push) Has been cancelled
Some checks failed
Deploy analytics worker / Deploy analytics worker to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
i18n upload strings / Upload latest strings (push) Failing after 1s
Deploy bemo / Deploy bemo to ${{ (github.ref == 'refs/heads/bemo-production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
Deploy grafana resources / ${{ github.event_name == 'push' && 'Deploy grafana resources' || 'Validate grafana resources (dry run)' }} (push) Failing after 0s
End to end tests (dotcom) / Check for relevant changes (push) Failing after 0s
End to end tests (examples) / Check for relevant changes (push) Failing after 0s
End to end tests (mermaid readability) / Check for relevant changes (push) Failing after 1s
End to end tests (perf) / Check for relevant changes (push) Failing after 0s
Publish editor extensions / Publish editor extensions (push) Failing after 1s
Publish SDK packages / Remove the publish-packages label (push) Has been skipped
Checks / Tests & checks (push) Has been cancelled
Checks / Build all projects (push) Has been cancelled
Deploy templates / Deploy templates (push) Has been cancelled
End to end tests (dotcom) / End to end tests (dotcom) (push) Has been cancelled
End to end tests (mermaid readability) / End to end tests (mermaid readability) (push) Has been cancelled
End to end tests (perf) / End to end tests (perf) (push) Has been cancelled
Deploy .com / Deploy dotcom to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Has been cancelled
End to end tests (examples) / End to end tests (examples) (push) Has been cancelled
Publish SDK packages / Publish SDK packages (push) Has been cancelled
Publish SDK packages / Tell user released version (push) Has been cancelled
Publish SDK packages / Publishes code templates to separate repositories (push) Has been cancelled
Publish SDK packages / Deploys the template demos with the new SDK version (push) Has been cancelled
This commit is contained in:
150
internal/scripts/typecheck.ts
Normal file
150
internal/scripts/typecheck.ts
Normal file
@@ -0,0 +1,150 @@
|
||||
import { execFile, execFileSync } from 'child_process'
|
||||
import path, { join } from 'path'
|
||||
import { REPO_ROOT, readJsonIfExists } from './lib/file'
|
||||
import { getAllWorkspacePackages } from './lib/workspace'
|
||||
|
||||
async function main() {
|
||||
const allWorkspaces = await getAllWorkspacePackages()
|
||||
const tsconfigFiles: string[] = []
|
||||
for (const workspace of allWorkspaces) {
|
||||
const tsconfigFile = path.join(workspace.path, 'tsconfig.json')
|
||||
const tsconfigExists = await readJsonIfExists(tsconfigFile)
|
||||
if (tsconfigExists) tsconfigFiles.push(tsconfigFile)
|
||||
}
|
||||
|
||||
const args = ['--build']
|
||||
const isWatchMode = process.argv.includes('--watch')
|
||||
if (process.argv.includes('--force')) args.push('--force')
|
||||
if (isWatchMode) args.push('--watch')
|
||||
if (process.argv.includes('--preserveWatchOutput')) args.push('--preserveWatchOutput')
|
||||
if (process.argv.includes('--extendedDiagnostics')) args.push('--extendedDiagnostics')
|
||||
|
||||
const compilerPath = join(REPO_ROOT, 'node_modules/.bin/tsc')
|
||||
|
||||
// tsc currently struggles to resolve some workspace package imports on a fresh checkout
|
||||
// when all projects are passed in a single --build invocation. Building package
|
||||
// workspaces first in topological order (leaves before dependents) produces the
|
||||
// declaration outputs needed for the full graph.
|
||||
const packageTsconfigFiles = tsconfigFiles.filter((file) =>
|
||||
file.includes(`${path.sep}packages${path.sep}`)
|
||||
)
|
||||
if (packageTsconfigFiles.length > 0) {
|
||||
const sortedPackageTsconfigFiles = await topoSortTsconfigs(packageTsconfigFiles)
|
||||
const bootstrapArgs = ['--build']
|
||||
if (process.argv.includes('--force')) bootstrapArgs.push('--force')
|
||||
for (const tsconfigFile of sortedPackageTsconfigFiles) {
|
||||
execFileSync(compilerPath, [...bootstrapArgs, tsconfigFile], { stdio: 'inherit' })
|
||||
}
|
||||
}
|
||||
|
||||
// In watch mode, use execFileSync with inherited stdio - it handles everything
|
||||
if (isWatchMode) {
|
||||
execFileSync(compilerPath, [...args, ...tsconfigFiles], { stdio: 'inherit' })
|
||||
return
|
||||
}
|
||||
|
||||
// In non-watch mode, capture output so we can show a clear error summary
|
||||
const output: string[] = []
|
||||
const errors: string[] = []
|
||||
|
||||
return new Promise<void>((resolve) => {
|
||||
const childProcess = execFile(
|
||||
compilerPath,
|
||||
[...args, ...tsconfigFiles],
|
||||
{ cwd: REPO_ROOT },
|
||||
(err) => {
|
||||
if (err) {
|
||||
// Extract TypeScript errors from the output
|
||||
const allOutput = output.join('') + errors.join('')
|
||||
const tsErrors = allOutput.split('\n').filter((line) => {
|
||||
// Match TypeScript error lines like: "file.ts(123,4): error TS2304: ..."
|
||||
return /\.(ts|tsx|js|jsx)\(\d+,\d+\):\s+error\s+TS\d+:/i.test(line)
|
||||
})
|
||||
|
||||
// Display a clear error summary at the end
|
||||
console.error('\n' + '='.repeat(80))
|
||||
console.error('❌ TypeScript type checking failed')
|
||||
console.error('='.repeat(80) + '\n')
|
||||
|
||||
if (tsErrors.length > 0) {
|
||||
console.error('TypeScript errors:')
|
||||
tsErrors.forEach((error) => console.error(error))
|
||||
console.error('')
|
||||
} else if (errors.length > 0) {
|
||||
// Fallback: show stderr if we couldn't extract specific errors
|
||||
console.error('Error output:')
|
||||
console.error(errors.join(''))
|
||||
console.error('')
|
||||
}
|
||||
|
||||
console.error('Please fix the errors above and try again.')
|
||||
console.error('='.repeat(80) + '\n')
|
||||
process.exit(err.code || 1)
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
// Capture and display stdout in real-time
|
||||
childProcess.stdout?.on('data', (chunk) => {
|
||||
const text = chunk.toString()
|
||||
output.push(text)
|
||||
process.stdout.write(text)
|
||||
})
|
||||
|
||||
// Capture and display stderr in real-time
|
||||
childProcess.stderr?.on('data', (chunk) => {
|
||||
const text = chunk.toString()
|
||||
errors.push(text)
|
||||
process.stderr.write(text)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort tsconfig files in topological order based on their `references` fields,
|
||||
* so that leaf packages (no dependencies) come first and dependents come after
|
||||
* all their dependencies. This is needed because tsc --build doesn't always
|
||||
* resolve the reference graph correctly on a fresh checkout.
|
||||
*/
|
||||
async function topoSortTsconfigs(tsconfigFiles: string[]): Promise<string[]> {
|
||||
const dirToFile = new Map<string, string>()
|
||||
const deps = new Map<string, string[]>()
|
||||
|
||||
for (const file of tsconfigFiles) {
|
||||
const dir = path.dirname(file)
|
||||
dirToFile.set(dir, file)
|
||||
const tsconfig = await readJsonIfExists(file)
|
||||
const refs: string[] = []
|
||||
if (tsconfig?.references) {
|
||||
for (const ref of tsconfig.references) {
|
||||
refs.push(path.resolve(dir, ref.path))
|
||||
}
|
||||
}
|
||||
deps.set(dir, refs)
|
||||
}
|
||||
|
||||
const visited = new Set<string>()
|
||||
const sorted: string[] = []
|
||||
|
||||
function visit(dir: string) {
|
||||
if (visited.has(dir)) return
|
||||
visited.add(dir)
|
||||
for (const dep of deps.get(dir) ?? []) {
|
||||
if (dirToFile.has(dep)) visit(dep)
|
||||
}
|
||||
sorted.push(dirToFile.get(dir)!)
|
||||
}
|
||||
|
||||
for (const dir of dirToFile.keys()) {
|
||||
visit(dir)
|
||||
}
|
||||
|
||||
return sorted
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error('Unexpected error:', err)
|
||||
process.exit(1)
|
||||
})
|
||||
Reference in New Issue
Block a user