From 695e826dcf2ce8ed44588427e323f47350cddac9 Mon Sep 17 00:00:00 2001 From: imbytecat Date: Sat, 25 Apr 2026 14:23:08 +0800 Subject: [PATCH] =?UTF-8?q?refactor(types):=20=E6=B6=88=E9=99=A4=E9=9D=9E?= =?UTF-8?q?=E5=BF=85=E8=A6=81=20as=20=E9=80=83=E9=80=B8=EF=BC=8C=E9=94=81?= =?UTF-8?q?=E7=B4=A7=20strict=20=E6=94=BF=E7=AD=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 按 Oracle 复核处置全仓 5 处类型断言: - fields.ts: as const → satisfies Record - compile.ts: as readonly string[] → ReadonlySet.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,防止后续漂移。 --- biome.json | 7 +++++++ compile.ts | 5 +++-- embed-migrations.ts | 24 +++++++++++++++++++----- src/server/api/interceptors.ts | 3 ++- src/server/db/fields.ts | 8 +++++++- 5 files changed, 38 insertions(+), 9 deletions(-) diff --git a/biome.json b/biome.json index 927d7d8..1292631 100644 --- a/biome.json +++ b/biome.json @@ -24,6 +24,13 @@ }, "correctness": { "noReactPropAssignments": "error" + }, + "style": { + "noNonNullAssertion": "error" + }, + "suspicious": { + "noExplicitAny": "error", + "noTsIgnore": "error" } } }, diff --git a/compile.ts b/compile.ts index 301bf65..7a9471b 100644 --- a/compile.ts +++ b/compile.ts @@ -12,8 +12,9 @@ const SUPPORTED_TARGETS: readonly Bun.Build.CompileTarget[] = [ 'bun-linux-arm64', ] -const isSupportedTarget = (value: string): value is Bun.Build.CompileTarget => - (SUPPORTED_TARGETS as readonly string[]).includes(value) +const SUPPORTED_TARGET_SET: ReadonlySet = 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' } }, diff --git a/embed-migrations.ts b/embed-migrations.ts index 8285ba2..cda7516 100644 --- a/embed-migrations.ts +++ b/embed-migrations.ts @@ -1,17 +1,31 @@ import { existsSync } from 'node:fs' import { readFile, writeFile } from 'node:fs/promises' +import { z } from 'zod' const JOURNAL = './drizzle/meta/_journal.json' const OUTPUT = './src/server/db/migrations.gen.ts' const SQL_RELATIVE_FROM_OUTPUT = '../../../drizzle' -type JournalEntry = { idx: number; tag: string; when: number; breakpoints: boolean } -type Journal = { entries: JournalEntry[] } +const journalEntrySchema = z.object({ + idx: z.number(), + tag: z.string(), + when: z.number(), + breakpoints: z.boolean(), +}) +const journalSchema = z.object({ entries: z.array(journalEntrySchema).default([]) }) + +type JournalEntry = z.infer + +const readJournalEntries = async (): Promise => { + if (!existsSync(JOURNAL)) { + return [] + } + const raw: unknown = JSON.parse(await readFile(JOURNAL, 'utf-8')) + return journalSchema.parse(raw).entries.sort((a, b) => a.idx - b.idx) +} const main = async () => { - const entries: JournalEntry[] = existsSync(JOURNAL) - ? ((JSON.parse(await readFile(JOURNAL, 'utf-8')) as Journal).entries ?? []).sort((a, b) => a.idx - b.idx) - : [] + const entries = await readJournalEntries() const imports = entries .map((e) => `import sql_${e.idx} from '${SQL_RELATIVE_FROM_OUTPUT}/${e.tag}.sql' with { type: 'text' }`) diff --git a/src/server/api/interceptors.ts b/src/server/api/interceptors.ts index 1b0fbb7..8ba6f18 100644 --- a/src/server/api/interceptors.ts +++ b/src/server/api/interceptors.ts @@ -8,7 +8,8 @@ export const logError = (error: unknown) => { export const handleValidationError = (error: unknown) => { if (error instanceof ORPCError && error.code === 'BAD_REQUEST' && error.cause instanceof ValidationError) { - // ORPC ValidationError.issues are Zod issues in this app. + // ORPC widens issues to the Standard Schema shape; every contract here is built from Zod/drizzle-zod, + // so the runtime objects are Zod issues. Rehydrate to reuse z.prettifyError / z.flattenError. const zodError = new z.ZodError(error.cause.issues as z.core.$ZodIssue[]) throw new ORPCError('INPUT_VALIDATION_FAILED', { diff --git a/src/server/db/fields.ts b/src/server/db/fields.ts index f7868d9..e02b497 100644 --- a/src/server/db/fields.ts +++ b/src/server/db/fields.ts @@ -12,4 +12,10 @@ export const generatedFields = { .$onUpdateFn(() => new Date()), } -export const generatedFieldKeys = { id: true, createdAt: true, updatedAt: true } as const +type GeneratedFieldKey = keyof typeof generatedFields + +export const generatedFieldKeys = { + id: true, + createdAt: true, + updatedAt: true, +} satisfies Record