Explorar o código

fix(core): runtime-neutral legacy credential import (#41607)

Kit Langton hai 5 días
pai
achega
9d34029cd9

+ 4 - 3
packages/core/src/database/migration/20260805200742_import_legacy_credentials.ts

@@ -1,3 +1,4 @@
+import { readFile } from "node:fs/promises"
 import path from "node:path"
 import { sql } from "drizzle-orm"
 import { Effect, Option, Schema } from "effect"
@@ -41,9 +42,9 @@ export default migration
 
 export function importLegacyCredentials(tx: Parameters<DatabaseMigration.Migration["up"]>[0], filepath: string) {
   return Effect.gen(function* () {
-    const file = Bun.file(filepath)
-    if (!(yield* Effect.promise(() => file.exists()))) return
-    const input = Option.getOrUndefined(decodeJson(yield* Effect.promise(() => file.text())))
+    const content = yield* Effect.promise(() => readFile(filepath, "utf8").catch(() => undefined))
+    if (content === undefined) return
+    const input = Option.getOrUndefined(decodeJson(content))
     if (typeof input !== "object" || input === null || Array.isArray(input)) {
       return yield* Effect.fail(new Error("Legacy credential file must contain an object"))
     }

+ 14 - 0
packages/core/test/database-migration.test.ts

@@ -164,6 +164,20 @@ describe("DatabaseMigration", () => {
     expect(await Bun.file(source).text()).toBe(content)
   })
 
+  test("skips legacy credential import when the source file is absent", async () => {
+    await using tmp = await tmpdir()
+
+    await run(
+      Effect.gen(function* () {
+        const db = yield* makeDb
+        yield* DatabaseMigration.apply(db)
+        yield* db.transaction((tx) => importLegacyCredentials(tx, path.join(tmp.path, "missing-auth.json")))
+
+        expect(yield* db.all(sql`SELECT id FROM credential`)).toEqual([])
+      }),
+    )
+  })
+
   test("rolls back a failed migration without recording it", async () => {
     await run(
       Effect.gen(function* () {