This commit is contained in:
ping-maxwell
2026-05-31 23:06:12 +10:00
parent 13abc7922b
commit 75aa7634ce
3 changed files with 47 additions and 1 deletions
@@ -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
@@ -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/<name>` 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([]);
});
});
+11 -1
View File
@@ -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.