fix return type of instrumentBetterAuth

This commit is contained in:
Alex Holovach
2025-10-05 06:39:29 -05:00
parent 16216c6d76
commit 2c097f9d76
2 changed files with 33 additions and 24 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@kubiks/otel-better-auth": patch
---
Fix return type of instrumentBetterAuth function.
+28 -24
View File
@@ -6,7 +6,7 @@ import {
type Span, type Span,
type Tracer, type Tracer,
} from "@opentelemetry/api"; } from "@opentelemetry/api";
import type { Auth, BetterAuthPlugin, betterAuth } from "better-auth"; import type { Auth, BetterAuthPlugin } from "better-auth";
import { createAuthMiddleware } from "better-auth/api"; import { createAuthMiddleware } from "better-auth/api";
const DEFAULT_TRACER_NAME = "@kubiks/otel-better-auth"; const DEFAULT_TRACER_NAME = "@kubiks/otel-better-auth";
@@ -44,16 +44,21 @@ interface InstrumentedAuth {
[INSTRUMENTED_FLAG]?: true; [INSTRUMENTED_FLAG]?: true;
} }
type BetterAuthInstance = ReturnType<typeof betterAuth>; type AnyAuth = Auth<any>;
type BetterAuthInstanceOptions = BetterAuthInstance["options"];
type AuthWithOptions< type AuthWithPlugins<TAuth extends AnyAuth> = TAuth extends {
Options extends BetterAuthInstanceOptions = BetterAuthInstanceOptions, options: infer Options;
> = Omit<Auth<Options>, "options"> & { }
options: Options & { ? TAuth & {
plugins?: BetterAuthPlugin[] | Iterable<BetterAuthPlugin>; options: Options & {
}; plugins?: BetterAuthPlugin[] | Iterable<BetterAuthPlugin>;
}; };
}
: TAuth & {
options: {
plugins?: BetterAuthPlugin[] | Iterable<BetterAuthPlugin>;
};
};
/** /**
* Ends a span with an error status and exception recording. * Ends a span with an error status and exception recording.
@@ -187,11 +192,11 @@ const API_METHOD_METADATA: Record<
/** /**
* Instruments a Better Auth instance with OpenTelemetry tracing. * Instruments a Better Auth instance with OpenTelemetry tracing.
*/ */
function instrumentServer<O extends Record<string, any> = any>( function instrumentServer<TAuth extends AnyAuth>(
server: Auth<O>, server: TAuth,
tracer: Tracer, tracer: Tracer,
): Auth<O> { ): TAuth {
const api = server.api as any; // Cast to any to allow property assignment const api = (server as AnyAuth).api as Record<string, any>;
const instrumentedMethods = new Set<string>(); const instrumentedMethods = new Set<string>();
// First, instrument all known API methods with specific metadata // First, instrument all known API methods with specific metadata
@@ -242,13 +247,11 @@ function instrumentServer<O extends Record<string, any> = any>(
return server; return server;
} }
function ensureOtelPlugin< function ensureOtelPlugin<TAuth extends AnyAuth>(
Options extends BetterAuthInstanceOptions = BetterAuthInstanceOptions, auth: TAuth,
>(
auth: Auth<Options>,
config: InstrumentBetterAuthConfig & { tracer: Tracer }, config: InstrumentBetterAuthConfig & { tracer: Tracer },
): void { ): void {
const authWithOptions = auth as AuthWithOptions<Options>; const authWithOptions = auth as AuthWithPlugins<TAuth>;
const options = authWithOptions.options; const options = authWithOptions.options;
const existingPlugins = options.plugins; const existingPlugins = options.plugins;
const pluginsArray = Array.isArray(existingPlugins) const pluginsArray = Array.isArray(existingPlugins)
@@ -303,14 +306,15 @@ function ensureOtelPlugin<
* await auth.api.getSession({ headers }); * await auth.api.getSession({ headers });
* ``` * ```
*/ */
export function instrumentBetterAuth< export function instrumentBetterAuth<TAuth extends AnyAuth>(
Options extends BetterAuthInstanceOptions = BetterAuthInstanceOptions, auth: TAuth,
>(auth: Auth<Options>, config?: InstrumentBetterAuthConfig): Auth<Options> { config?: InstrumentBetterAuthConfig,
): TAuth {
if (!auth || typeof auth !== "object") { if (!auth || typeof auth !== "object") {
return auth; return auth;
} }
if ((auth as Auth<Options> & InstrumentedAuth)[INSTRUMENTED_FLAG]) { if ((auth as TAuth & InstrumentedAuth)[INSTRUMENTED_FLAG]) {
return auth; return auth;
} }
@@ -322,7 +326,7 @@ export function instrumentBetterAuth<
ensureOtelPlugin(auth, { tracerName, tracer }); ensureOtelPlugin(auth, { tracerName, tracer });
instrumentServer(auth, tracer); instrumentServer(auth, tracer);
(auth as Auth<Options> & InstrumentedAuth)[INSTRUMENTED_FLAG] = true; (auth as TAuth & InstrumentedAuth)[INSTRUMENTED_FLAG] = true;
return auth; return auth;
} }