@better-auth/core 1.6.25 → 1.6.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,14 +6,11 @@ import { AuthContext } from "../types/context.mjs";
6
6
  import "../types/index.mjs";
7
7
  import { OAuthProvider } from "../oauth2/oauth-provider.mjs";
8
8
  import "../oauth2/index.mjs";
9
- import { EndpointContext, EndpointOptions, StrictEndpoint } from "better-call";
9
+ import { EndpointHandler, EndpointOptions, MiddlewareHandler, StrictEndpoint } from "better-call";
10
10
  //#region src/api/index.d.ts
11
- declare const optionsMiddleware: <InputCtx extends import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>>(inputContext: InputCtx) => Promise<AuthContext>;
11
+ declare const optionsMiddleware: import("better-call").Middleware<import("better-call").MiddlewareOptions, <InputCtx extends import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>>(inputContext: InputCtx) => Promise<AuthContext>>;
12
12
  declare const createAuthMiddleware: {
13
- <Options extends import("better-call").MiddlewareOptions, R>(options: Options, handler: (ctx: import("better-call").MiddlewareContext<Options, {
14
- returned?: unknown | undefined;
15
- responseHeaders?: Headers | undefined;
16
- } & import("@better-auth/core").PluginContext<import("@better-auth/core").BetterAuthOptions> & import("@better-auth/core").InfoContext & {
13
+ <Options extends import("better-call").MiddlewareOptions, R>(options: Options, handler: (ctx: import("better-call").MiddlewareContext<Options, import("@better-auth/core").PluginContext<import("@better-auth/core").BetterAuthOptions> & import("@better-auth/core").InfoContext & {
17
14
  options: import("@better-auth/core").BetterAuthOptions;
18
15
  trustedOrigins: string[];
19
16
  trustedProviders: string[];
@@ -138,11 +135,11 @@ declare const createAuthMiddleware: {
138
135
  skipCSRFCheck: boolean;
139
136
  runInBackground: (promise: Promise<unknown>) => void;
140
137
  runInBackgroundOrAwait: (promise: Promise<unknown> | void) => import("@better-auth/core").Awaitable<unknown>;
141
- }>) => Promise<R>): (inputContext: import("better-call").MiddlewareInputContext<Options>) => Promise<R>;
142
- <Options extends import("better-call").MiddlewareOptions, R_1>(handler: (ctx: import("better-call").MiddlewareContext<Options, {
138
+ } & {
143
139
  returned?: unknown | undefined;
144
140
  responseHeaders?: Headers | undefined;
145
- } & import("@better-auth/core").PluginContext<import("@better-auth/core").BetterAuthOptions> & import("@better-auth/core").InfoContext & {
141
+ }>) => Promise<R>): import("better-call").Middleware<Options, (inputContext: import("better-call").MiddlewareInputContext<Options>) => Promise<R>>;
142
+ <Options extends import("better-call").MiddlewareOptions, R_1>(handler: (ctx: import("better-call").MiddlewareContext<Options, import("@better-auth/core").PluginContext<import("@better-auth/core").BetterAuthOptions> & import("@better-auth/core").InfoContext & {
146
143
  options: import("@better-auth/core").BetterAuthOptions;
147
144
  trustedOrigins: string[];
148
145
  trustedProviders: string[];
@@ -267,15 +264,19 @@ declare const createAuthMiddleware: {
267
264
  skipCSRFCheck: boolean;
268
265
  runInBackground: (promise: Promise<unknown>) => void;
269
266
  runInBackgroundOrAwait: (promise: Promise<unknown> | void) => import("@better-auth/core").Awaitable<unknown>;
270
- }>) => Promise<R_1>): (inputContext: import("better-call").MiddlewareInputContext<Options>) => Promise<R_1>;
267
+ } & {
268
+ returned?: unknown | undefined;
269
+ responseHeaders?: Headers | undefined;
270
+ }>) => Promise<R_1>): import("better-call").Middleware<Options, (inputContext: import("better-call").MiddlewareInputContext<Options>) => Promise<R_1>>;
271
271
  };
272
- type EndpointHandler<Path extends string, Options extends EndpointOptions, R> = (context: EndpointContext<Path, Options, AuthContext>) => Promise<R>;
273
- declare function createAuthEndpoint<Path extends string, Options extends EndpointOptions, R>(path: Path, options: Options, handler: EndpointHandler<Path, Options, R>): StrictEndpoint<Path, Options, R>;
274
- declare function createAuthEndpoint<Path extends string, Options extends EndpointOptions, R>(options: Options, handler: EndpointHandler<Path, Options, R>): StrictEndpoint<Path, Options, R>;
272
+ type AuthEndpointHandler<Path extends string, Options extends EndpointOptions, R> = EndpointHandler<Path, Options, R, AuthContext>;
273
+ type PathlessAuthEndpointHandler<Options extends EndpointOptions, R> = AuthEndpointHandler<string, Options, R>;
274
+ declare function createAuthEndpoint<Path extends string, Options extends EndpointOptions, R>(path: Path, options: Options, handler: AuthEndpointHandler<Path, Options, R>): StrictEndpoint<Path, Options, R>;
275
+ declare function createAuthEndpoint<InferredPath extends string, Options extends EndpointOptions, R>(options: Options, handler: PathlessAuthEndpointHandler<Options, R>): StrictEndpoint<InferredPath, Options, R>;
275
276
  declare namespace createAuthEndpoint {
276
- var serverOnly: <Path extends string, Options extends EndpointOptions, R>(options: Options, handler: EndpointHandler<Path, Options, R>) => StrictEndpoint<Path, Options, R>;
277
+ var serverOnly: <InferredPath extends string, Options extends EndpointOptions, R>(options: Options, handler: PathlessAuthEndpointHandler<Options, R>) => StrictEndpoint<InferredPath, Options, R>;
277
278
  }
278
279
  type AuthEndpoint<Path extends string, Opts extends EndpointOptions, R> = ReturnType<typeof createAuthEndpoint<Path, Opts, R>>;
279
- type AuthMiddleware = ReturnType<typeof createAuthMiddleware>;
280
+ type AuthMiddleware = MiddlewareHandler;
280
281
  //#endregion
281
282
  export { AuthEndpoint, AuthMiddleware, createAuthEndpoint, createAuthMiddleware, optionsMiddleware };
@@ -29,28 +29,24 @@ const optionsMiddleware = createMiddleware(async () => {
29
29
  const createAuthMiddleware = createMiddleware.create({ use: [optionsMiddleware, createMiddleware(async () => {
30
30
  return {};
31
31
  })] });
32
- const use = [optionsMiddleware];
33
- function createAuthEndpoint(pathOrOptions, handlerOrOptions, handlerOrNever) {
34
- const path = typeof pathOrOptions === "string" ? pathOrOptions : void 0;
35
- const options = typeof handlerOrOptions === "object" ? handlerOrOptions : pathOrOptions;
36
- const handler = typeof handlerOrOptions === "function" ? handlerOrOptions : handlerOrNever;
37
- const wrapped = async (ctx) => {
38
- const runtimeCtx = ctx;
32
+ const createEndpointWithAuthContext = createEndpoint.create({ use: [optionsMiddleware] });
33
+ function wrapEndpointHandler(handler) {
34
+ return async (context) => {
39
35
  try {
40
- return await runWithEndpointContext(ctx, () => handler(ctx));
41
- } catch (e) {
42
- attachResponseHeadersToAPIError(runtimeCtx.responseHeaders, e);
43
- throw e;
36
+ return await runWithEndpointContext(context, () => handler(context));
37
+ } catch (error) {
38
+ attachResponseHeadersToAPIError(context.responseHeaders, error);
39
+ throw error;
44
40
  }
45
41
  };
46
- if (path) return createEndpoint(path, {
47
- ...options,
48
- use: [...options?.use || [], ...use]
49
- }, wrapped);
50
- return createEndpoint({
51
- ...options,
52
- use: [...options?.use || [], ...use]
53
- }, wrapped);
42
+ }
43
+ function createAuthEndpoint(...args) {
44
+ if (args.length === 3) {
45
+ const [path, options, handler] = args;
46
+ return createEndpointWithAuthContext(path, options, wrapEndpointHandler(handler));
47
+ }
48
+ const [options, handler] = args;
49
+ return createEndpointWithAuthContext(options, wrapEndpointHandler(handler));
54
50
  }
55
51
  /**
56
52
  * Set `metadata.SERVER_ONLY` while preserving any existing metadata
@@ -2,7 +2,7 @@
2
2
  const symbol = Symbol.for("better-auth:global");
3
3
  let bind = null;
4
4
  const __context = {};
5
- const __betterAuthVersion = "1.6.25";
5
+ const __betterAuthVersion = "1.6.27";
6
6
  /**
7
7
  * We store context instance in the globalThis.
8
8
  *
@@ -2,7 +2,7 @@ import { ATTR_HTTP_RESPONSE_STATUS_CODE } from "./attributes.mjs";
2
2
  import { getOpenTelemetryAPI } from "./api.mjs";
3
3
  //#region src/instrumentation/tracer.ts
4
4
  const INSTRUMENTATION_SCOPE = "better-auth";
5
- const INSTRUMENTATION_VERSION = "1.6.25";
5
+ const INSTRUMENTATION_VERSION = "1.6.27";
6
6
  /**
7
7
  * Better-auth uses `throw ctx.redirect(url)` for flow control (e.g. OAuth
8
8
  * callbacks). These are APIErrors with 3xx status codes and should not be
@@ -0,0 +1,19 @@
1
+ //#region src/utils/email.d.ts
2
+ interface PlaceholderEmailOptions {
3
+ /**
4
+ * A stable identifier that distinguishes the account within the namespace.
5
+ */
6
+ identifier: string;
7
+ /**
8
+ * A namespace that distinguishes identical identifiers from different sources.
9
+ */
10
+ namespace: string;
11
+ }
12
+ /**
13
+ * Creates a stable, non-routable email address for an account without an email.
14
+ *
15
+ * @throws TypeError if the generated email is invalid.
16
+ */
17
+ declare function createPlaceholderEmail({ identifier, namespace }: PlaceholderEmailOptions): string;
18
+ //#endregion
19
+ export { PlaceholderEmailOptions, createPlaceholderEmail };
@@ -0,0 +1,18 @@
1
+ import * as z from "zod";
2
+ //#region src/utils/email.ts
3
+ /**
4
+ * @see https://www.rfc-editor.org/rfc/rfc6761.html#section-6.4
5
+ */
6
+ const PLACEHOLDER_EMAIL_DOMAIN = "placeholder.invalid";
7
+ /**
8
+ * Creates a stable, non-routable email address for an account without an email.
9
+ *
10
+ * @throws TypeError if the generated email is invalid.
11
+ */
12
+ function createPlaceholderEmail({ identifier, namespace }) {
13
+ const result = z.email().safeParse(`${identifier}@${namespace}.${PLACEHOLDER_EMAIL_DOMAIN}`);
14
+ if (!result.success) throw new TypeError("Invalid placeholder email");
15
+ return result.data;
16
+ }
17
+ //#endregion
18
+ export { createPlaceholderEmail };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@better-auth/core",
3
- "version": "1.6.25",
3
+ "version": "1.6.27",
4
4
  "description": "The most comprehensive authentication framework for TypeScript.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -155,9 +155,9 @@
155
155
  "@better-auth/utils": "0.4.2",
156
156
  "@better-fetch/fetch": "1.3.1",
157
157
  "@opentelemetry/api": "^1.9.0",
158
- "@opentelemetry/sdk-trace-base": "^1.30.0",
159
- "@opentelemetry/sdk-trace-node": "^1.30.0",
160
- "better-call": "1.3.7",
158
+ "@opentelemetry/sdk-trace-base": "^2.10.0",
159
+ "@opentelemetry/sdk-trace-node": "^2.10.0",
160
+ "better-call": "1.4.0",
161
161
  "@cloudflare/workers-types": "^4.20250121.0",
162
162
  "jose": "^6.1.3",
163
163
  "kysely": "^0.28.17 || ^0.29.0",
@@ -168,7 +168,7 @@
168
168
  "@better-auth/utils": "0.4.2",
169
169
  "@better-fetch/fetch": "1.3.1",
170
170
  "@opentelemetry/api": "^1.9.0",
171
- "better-call": "1.3.7",
171
+ "better-call": "1.4.0",
172
172
  "@cloudflare/workers-types": ">=4",
173
173
  "jose": "^6.1.0",
174
174
  "kysely": "^0.28.5 || ^0.29.0",
package/src/api/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type {
2
- EndpointContext,
2
+ EndpointHandler,
3
3
  EndpointOptions,
4
+ MiddlewareHandler,
4
5
  StrictEndpoint,
5
6
  } from "better-call";
6
7
  import {
@@ -56,13 +57,37 @@ export const createAuthMiddleware = createMiddleware.create({
56
57
  ],
57
58
  });
58
59
 
59
- const use = [optionsMiddleware];
60
+ const createEndpointWithAuthContext = createEndpoint.create({
61
+ use: [optionsMiddleware],
62
+ });
60
63
 
61
- type EndpointHandler<
64
+ type AuthEndpointHandler<
62
65
  Path extends string,
63
66
  Options extends EndpointOptions,
64
67
  R,
65
- > = (context: EndpointContext<Path, Options, AuthContext>) => Promise<R>;
68
+ > = EndpointHandler<Path, Options, R, AuthContext>;
69
+
70
+ type PathlessAuthEndpointHandler<
71
+ Options extends EndpointOptions,
72
+ R,
73
+ > = AuthEndpointHandler<string, Options, R>;
74
+
75
+ function wrapEndpointHandler<
76
+ Path extends string,
77
+ Options extends EndpointOptions,
78
+ R,
79
+ >(
80
+ handler: AuthEndpointHandler<Path, Options, R>,
81
+ ): AuthEndpointHandler<Path, Options, R> {
82
+ return async (context) => {
83
+ try {
84
+ return await runWithEndpointContext(context, () => handler(context));
85
+ } catch (error) {
86
+ attachResponseHeadersToAPIError(context.responseHeaders, error);
87
+ throw error;
88
+ }
89
+ };
90
+ }
66
91
 
67
92
  export function createAuthEndpoint<
68
93
  Path extends string,
@@ -71,65 +96,42 @@ export function createAuthEndpoint<
71
96
  >(
72
97
  path: Path,
73
98
  options: Options,
74
- handler: EndpointHandler<Path, Options, R>,
99
+ handler: AuthEndpointHandler<Path, Options, R>,
75
100
  ): StrictEndpoint<Path, Options, R>;
76
101
 
77
102
  export function createAuthEndpoint<
78
- Path extends string,
103
+ InferredPath extends string,
79
104
  Options extends EndpointOptions,
80
105
  R,
81
106
  >(
82
107
  options: Options,
83
- handler: EndpointHandler<Path, Options, R>,
84
- ): StrictEndpoint<Path, Options, R>;
108
+ handler: PathlessAuthEndpointHandler<Options, R>,
109
+ ): StrictEndpoint<InferredPath, Options, R>;
85
110
 
86
111
  export function createAuthEndpoint<
87
112
  Path extends string,
88
- Opts extends EndpointOptions,
113
+ Options extends EndpointOptions,
89
114
  R,
90
115
  >(
91
- pathOrOptions: Path | Opts,
92
- handlerOrOptions: EndpointHandler<Path, Opts, R> | Opts,
93
- handlerOrNever?: any,
116
+ ...args:
117
+ | [
118
+ path: Path,
119
+ options: Options,
120
+ handler: AuthEndpointHandler<Path, Options, R>,
121
+ ]
122
+ | [options: Options, handler: PathlessAuthEndpointHandler<Options, R>]
94
123
  ) {
95
- const path: Path | undefined =
96
- typeof pathOrOptions === "string" ? pathOrOptions : undefined;
97
- const options: Opts =
98
- typeof handlerOrOptions === "object"
99
- ? handlerOrOptions
100
- : (pathOrOptions as Opts);
101
- const handler: EndpointHandler<Path, Opts, R> =
102
- typeof handlerOrOptions === "function" ? handlerOrOptions : handlerOrNever;
103
-
104
- // todo: prettify the code, we want to call `runWithEndpointContext` to top level
105
- const wrapped: EndpointHandler<Path, Opts, R> = async (ctx) => {
106
- const runtimeCtx = ctx as unknown as { responseHeaders?: Headers };
107
- try {
108
- return await runWithEndpointContext(ctx as any, () => handler(ctx));
109
- } catch (e) {
110
- attachResponseHeadersToAPIError(runtimeCtx.responseHeaders, e);
111
- throw e;
112
- }
113
- };
114
-
115
- if (path) {
116
- return createEndpoint(
124
+ if (args.length === 3) {
125
+ const [path, options, handler] = args;
126
+ return createEndpointWithAuthContext(
117
127
  path,
118
- {
119
- ...options,
120
- use: [...(options?.use || []), ...use],
121
- },
122
- wrapped,
128
+ options,
129
+ wrapEndpointHandler(handler),
123
130
  );
124
131
  }
125
132
 
126
- return createEndpoint(
127
- {
128
- ...options,
129
- use: [...(options?.use || []), ...use],
130
- },
131
- wrapped,
132
- );
133
+ const [options, handler] = args;
134
+ return createEndpointWithAuthContext(options, wrapEndpointHandler(handler));
133
135
  }
134
136
 
135
137
  /**
@@ -168,18 +170,22 @@ function withServerOnly<Options extends EndpointOptions>(
168
170
  * ```
169
171
  */
170
172
  createAuthEndpoint.serverOnly = <
171
- Path extends string,
173
+ InferredPath extends string,
172
174
  Options extends EndpointOptions,
173
175
  R,
174
176
  >(
175
177
  options: Options,
176
- handler: EndpointHandler<Path, Options, R>,
177
- ): StrictEndpoint<Path, Options, R> =>
178
- createAuthEndpoint(withServerOnly(options), handler);
178
+ handler: PathlessAuthEndpointHandler<Options, R>,
179
+ ): StrictEndpoint<InferredPath, Options, R> =>
180
+ createAuthEndpoint<InferredPath, Options, R>(
181
+ withServerOnly(options),
182
+ handler,
183
+ );
179
184
 
180
185
  export type AuthEndpoint<
181
186
  Path extends string,
182
187
  Opts extends EndpointOptions,
183
188
  R,
184
189
  > = ReturnType<typeof createAuthEndpoint<Path, Opts, R>>;
185
- export type AuthMiddleware = ReturnType<typeof createAuthMiddleware>;
190
+
191
+ export type AuthMiddleware = MiddlewareHandler;
@@ -0,0 +1,36 @@
1
+ import * as z from "zod";
2
+
3
+ /**
4
+ * @see https://www.rfc-editor.org/rfc/rfc6761.html#section-6.4
5
+ */
6
+ const PLACEHOLDER_EMAIL_DOMAIN = "placeholder.invalid";
7
+
8
+ export interface PlaceholderEmailOptions {
9
+ /**
10
+ * A stable identifier that distinguishes the account within the namespace.
11
+ */
12
+ identifier: string;
13
+ /**
14
+ * A namespace that distinguishes identical identifiers from different sources.
15
+ */
16
+ namespace: string;
17
+ }
18
+
19
+ /**
20
+ * Creates a stable, non-routable email address for an account without an email.
21
+ *
22
+ * @throws TypeError if the generated email is invalid.
23
+ */
24
+ export function createPlaceholderEmail({
25
+ identifier,
26
+ namespace,
27
+ }: PlaceholderEmailOptions): string {
28
+ const result = z
29
+ .email()
30
+ .safeParse(`${identifier}@${namespace}.${PLACEHOLDER_EMAIL_DOMAIN}`);
31
+ if (!result.success) {
32
+ throw new TypeError("Invalid placeholder email");
33
+ }
34
+
35
+ return result.data;
36
+ }