From 75aa7634cecf64b9d35f01e1d931443bb6be07e2 Mon Sep 17 00:00:00 2001 From: ping-maxwell Date: Sun, 31 May 2026 23:06:12 +1000 Subject: [PATCH] fix --- .../kysely-adapter-inline-capitalize.md | 9 +++++++ .../kysely-adapter/src/kysely-adapter.test.ts | 27 +++++++++++++++++++ packages/kysely-adapter/src/kysely-adapter.ts | 12 ++++++++- 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 .changeset/kysely-adapter-inline-capitalize.md diff --git a/.changeset/kysely-adapter-inline-capitalize.md b/.changeset/kysely-adapter-inline-capitalize.md new file mode 100644 index 0000000000..b03c014269 --- /dev/null +++ b/.changeset/kysely-adapter-inline-capitalize.md @@ -0,0 +1,9 @@ +--- +"@better-auth/kysely-adapter": patch +--- + +Drop the `@better-auth/core/utils/string` subpath import from the kysely adapter and inline the tiny `capitalizeFirstLetter` helper instead. + +When a stale `@better-auth/cli@1.4.x` is left in a project's dependencies (for example after upgrading `better-auth` without renaming the CLI to `auth`), package managers can hoist the older `@better-auth/core@1.4.x` (which the legacy CLI pins as a regular dependency) to the top of `node_modules`. That older core only declares `./utils` in its `exports` map; it lacks the `./utils/*` wildcard added in 1.5+. Resolving `@better-auth/core/utils/string` from the adapter therefore failed with `ERR_PACKAGE_PATH_NOT_EXPORTED` (Node) or `Module not found: Can't resolve '@better-auth/core/utils/string'` (Webpack/Turbopack). Inlining the helper removes the fragile subpath import so the adapter loads even when an older core is shadowed onto the resolution path. + +@see https://github.com/better-auth/better-auth/issues/9767 diff --git a/packages/kysely-adapter/src/kysely-adapter.test.ts b/packages/kysely-adapter/src/kysely-adapter.test.ts index e809cc1738..06b6572936 100644 --- a/packages/kysely-adapter/src/kysely-adapter.test.ts +++ b/packages/kysely-adapter/src/kysely-adapter.test.ts @@ -1,3 +1,5 @@ +import { readFileSync } from "node:fs"; +import path from "node:path"; import { Kysely, SqliteDialect } from "kysely"; import { describe, expect, it, vi } from "vitest"; import { kyselyAdapter } from "./kysely-adapter"; @@ -60,4 +62,29 @@ describe("kysely-adapter", () => { ); expect(deleteQuery.returningAll).toHaveBeenCalledTimes(1); }); + + /** + * Stale installs of `@better-auth/cli@1.4.x` pin `@better-auth/core@1.4.x` + * as a regular dependency, so package managers can hoist that older core + * to the top of `node_modules` and shadow the newer core this adapter is + * compiled against. The 1.4.x core only exposes `./utils` (no wildcard), + * so any `@better-auth/core/utils/` subpath import here will throw + * `ERR_PACKAGE_PATH_NOT_EXPORTED` at bundle/resolve time. Keep this + * adapter free of `@better-auth/core/utils/*` imports. + * + * @see https://github.com/better-auth/better-auth/issues/9767 + */ + it("does not import from @better-auth/core/utils/* subpaths", () => { + const source = readFileSync( + path.join(__dirname, "kysely-adapter.ts"), + "utf8", + ); + const importLines = source + .split("\n") + .filter((line) => /^\s*import\b/.test(line)); + const offenders = importLines.filter((line) => + /@better-auth\/core\/utils\//.test(line), + ); + expect(offenders).toEqual([]); + }); }); diff --git a/packages/kysely-adapter/src/kysely-adapter.ts b/packages/kysely-adapter/src/kysely-adapter.ts index 4f80c22cc3..a56df4fd94 100644 --- a/packages/kysely-adapter/src/kysely-adapter.ts +++ b/packages/kysely-adapter/src/kysely-adapter.ts @@ -9,7 +9,6 @@ import type { } from "@better-auth/core/db/adapter"; import { createAdapterFactory } from "@better-auth/core/db/adapter"; import { logger } from "@better-auth/core/env"; -import { capitalizeFirstLetter } from "@better-auth/core/utils/string"; import type { InsertQueryBuilder, Kysely, @@ -26,6 +25,17 @@ import { } from "./query-builders"; import type { KyselyDatabaseType } from "./types"; +// Inlined locally to avoid relying on the `@better-auth/core/utils/*` +// wildcard subpath export. When users have a stale `@better-auth/cli@1.4.x` +// installed, package managers can hoist `@better-auth/core@1.4.x` (which +// only exposes `./utils`, not `./utils/*`) to the top of `node_modules`, +// shadowing the newer core that this adapter was built against and +// breaking subpath imports at bundle/resolve time. +// @see https://github.com/better-auth/better-auth/issues/9767 +function capitalizeFirstLetter(str: string) { + return str.charAt(0).toUpperCase() + str.slice(1); +} + interface KyselyAdapterConfig { /** * Database type.