Files
fullstack-starter/compile.ts
T
imbytecat 695e826dcf refactor(types): 消除非必要 as 逃逸,锁紧 strict 政策
按 Oracle 复核处置全仓 5 处类型断言:

- fields.ts: as const → satisfies Record<GeneratedFieldKey, true>
- compile.ts: as readonly string[] → ReadonlySet<string>.has()
- embed-migrations.ts: JSON.parse as Journal → Zod schema 运行时校验,JSON.parse 显式 unknown
- interceptors.ts: 唯一保留的跨包断言(ORPC→Zod)注释扩写为完整背景
- router.tsx: satisfies 非 cast,保留

biome.json 增配 noExplicitAny / noTsIgnore / noNonNullAssertion,防止后续漂移。
2026-04-25 14:23:08 +08:00

72 lines
2.0 KiB
TypeScript

import { mkdir, rm } from 'node:fs/promises'
import { parseArgs } from 'node:util'
const ENTRYPOINT = 'bin.ts'
const OUTDIR = 'out'
const SUPPORTED_TARGETS: readonly Bun.Build.CompileTarget[] = [
'bun-windows-x64',
'bun-darwin-arm64',
'bun-darwin-x64',
'bun-linux-x64',
'bun-linux-arm64',
]
const SUPPORTED_TARGET_SET: ReadonlySet<string> = new Set(SUPPORTED_TARGETS)
const isSupportedTarget = (value: string): value is Bun.Build.CompileTarget => SUPPORTED_TARGET_SET.has(value)
const { values } = parseArgs({
options: { target: { type: 'string' } },
strict: true,
allowPositionals: false,
})
const resolveTarget = (): Bun.Build.CompileTarget => {
if (values.target !== undefined) {
if (!isSupportedTarget(values.target)) {
throw new Error(`Invalid target: ${values.target}\nAllowed: ${SUPPORTED_TARGETS.join(', ')}`)
}
return values.target
}
const os = process.platform === 'win32' ? 'windows' : process.platform
const candidate = `bun-${os}-${process.arch}`
if (!isSupportedTarget(candidate)) {
throw new Error(`Unsupported host: ${process.platform}-${process.arch}`)
}
return candidate
}
const main = async () => {
const target = resolveTarget()
const suffix = target.replace('bun-', '')
const outfile = `server-${suffix}`
await mkdir(OUTDIR, { recursive: true })
await Promise.all([rm(`${OUTDIR}/${outfile}`, { force: true }), rm(`${OUTDIR}/${outfile}.exe`, { force: true })])
const result = await Bun.build({
entrypoints: [ENTRYPOINT],
outdir: OUTDIR,
compile: { outfile, target },
minify: true,
bytecode: true,
sourcemap: 'inline',
})
if (!result.success) {
throw new Error(result.logs.map(String).join('\n'))
}
// Bun bundler still writes *.js.map next to the binary even with inline sourcemap.
await rm(`${OUTDIR}/${ENTRYPOINT.replace(/\.ts$/, '')}.js.map`, { force: true })
console.log(`${target}${OUTDIR}/${outfile}`)
}
main().catch((err) => {
console.error('❌', err instanceof Error ? err.message : err)
process.exit(1)
})