From fd7256014beb9ee2da225e26e6bce5ef2c0f7761 Mon Sep 17 00:00:00 2001 From: Dylan Vanmali Date: Tue, 2 Dec 2025 10:24:22 -0800 Subject: [PATCH] fix(db-adapter): string[] and number[] fieldTypes incorrectly parsed for plugins (#4237) --- .../src/adapters/adapter-factory/index.ts | 13 ++++ .../test/adapter-factory.test.ts | 76 +++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/packages/better-auth/src/adapters/adapter-factory/index.ts b/packages/better-auth/src/adapters/adapter-factory/index.ts index 978d9f87bd..3cc703af54 100644 --- a/packages/better-auth/src/adapters/adapter-factory/index.ts +++ b/packages/better-auth/src/adapters/adapter-factory/index.ts @@ -247,6 +247,13 @@ export const createAdapterFactory = fieldAttributes!.type === "json" ) { newValue = JSON.stringify(newValue); + } else if ( + config.supportsJSON === false && + Array.isArray(newValue) && + (fieldAttributes!.type === "string[]" || + fieldAttributes!.type === "number[]") + ) { + newValue = JSON.stringify(newValue); } else if ( config.supportsDates === false && newValue instanceof Date && @@ -335,6 +342,12 @@ export const createAdapterFactory = field.type === "json" ) { newValue = safeJSONParse(newValue); + } else if ( + config.supportsJSON === false && + typeof newValue === "string" && + (field.type === "string[]" || field.type === "number[]") + ) { + newValue = safeJSONParse(newValue); } else if ( config.supportsDates === false && typeof newValue === "string" && diff --git a/packages/better-auth/src/adapters/adapter-factory/test/adapter-factory.test.ts b/packages/better-auth/src/adapters/adapter-factory/test/adapter-factory.test.ts index 71a8f5b444..672cbf1176 100644 --- a/packages/better-auth/src/adapters/adapter-factory/test/adapter-factory.test.ts +++ b/packages/better-auth/src/adapters/adapter-factory/test/adapter-factory.test.ts @@ -522,6 +522,82 @@ describe("Create Adapter Helper", async () => { expect(createFALSEParameters.data.emailVerified).toBe(0); }); + test("Should modify string[] type to TEXT if the DB doesn't support it. And expect the result to be transformed back to string[]", async () => { + const createJSONParameters: { data: { preferences: string } } = + await new Promise(async (r) => { + const adapter = await createTestAdapter({ + config: { + supportsJSON: false, + }, + options: { + user: { + additionalFields: { + preferences: { + type: "string[]", + }, + }, + }, + }, + adapter(args_0) { + return { + async create(data) { + r(data as any); + return data.data; + }, + }; + }, + }); + const obj = { preferences: ["medium", "large"] }; + const res = await adapter.create({ + model: "user", + data: obj, + }); + expect(res).toHaveProperty("preferences"); + expect(res.preferences).toEqual(obj.preferences); + }); + expect(createJSONParameters.data).toHaveProperty("preferences"); + expect(createJSONParameters.data.preferences).toEqual( + '[\"medium\",\"large\"]', + ); + }); + + test("Should modify number[] type to TEXT if the DB doesn't support it. And expect the result to be transformed back to number[]", async () => { + const createJSONParameters: { data: { preferences: string } } = + await new Promise(async (r) => { + const adapter = await createTestAdapter({ + config: { + supportsJSON: false, + }, + options: { + user: { + additionalFields: { + preferences: { + type: "number[]", + }, + }, + }, + }, + adapter(args_0) { + return { + async create(data) { + r(data as any); + return data.data; + }, + }; + }, + }); + const obj = { preferences: [6, 7] }; + const res = await adapter.create({ + model: "user", + data: obj, + }); + expect(res).toHaveProperty("preferences"); + expect(res.preferences).toEqual(obj.preferences); + }); + expect(createJSONParameters.data).toHaveProperty("preferences"); + expect(createJSONParameters.data.preferences).toEqual("[6,7]"); + }); + test("Should modify JSON type to TEXT if the DB doesn't support it. And expect the result to be transformed back to JSON", async () => { const createJSONParameters: { data: { preferences: string } } = await new Promise(async (r) => {