@convex-dev/better-auth 0.9.10 → 0.10.0
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.
- package/dist/auth-config.d.ts +43 -0
- package/dist/auth-config.d.ts.map +1 -0
- package/dist/auth-config.js +45 -0
- package/dist/auth-config.js.map +1 -0
- package/dist/auth-options.d.ts +3 -0
- package/dist/auth-options.d.ts.map +1 -0
- package/dist/auth-options.js +41 -0
- package/dist/auth-options.js.map +1 -0
- package/dist/auth.d.ts +1 -3
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +2 -42
- package/dist/auth.js.map +1 -1
- package/dist/client/{adapterUtils.d.ts → adapter-utils.d.ts} +15 -15
- package/dist/client/adapter-utils.d.ts.map +1 -0
- package/dist/client/{adapterUtils.js → adapter-utils.js} +1 -1
- package/dist/client/adapter-utils.js.map +1 -0
- package/dist/client/adapter.d.ts +1 -2
- package/dist/client/adapter.d.ts.map +1 -1
- package/dist/client/adapter.js +4 -4
- package/dist/client/adapter.js.map +1 -1
- package/dist/client/create-api.d.ts +139 -0
- package/dist/client/create-api.d.ts.map +1 -0
- package/dist/client/create-api.js +204 -0
- package/dist/client/create-api.js.map +1 -0
- package/dist/client/create-client.d.ts +183 -0
- package/dist/client/create-client.d.ts.map +1 -0
- package/dist/client/create-client.js +311 -0
- package/dist/client/create-client.js.map +1 -0
- package/dist/client/{createSchema.d.ts → create-schema.d.ts} +1 -1
- package/dist/client/create-schema.d.ts.map +1 -0
- package/dist/client/{createSchema.js → create-schema.js} +11 -5
- package/dist/client/create-schema.js.map +1 -0
- package/dist/client/index.d.ts +4 -279
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +6 -476
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/component.d.ts +0 -3
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/adapter.d.ts +19 -21
- package/dist/component/adapter.d.ts.map +1 -1
- package/dist/component/adapter.js +2 -2
- package/dist/component/adapter.js.map +1 -1
- package/dist/component/schema.d.ts +50 -50
- package/dist/nextjs/client.d.ts +4 -0
- package/dist/nextjs/client.d.ts.map +1 -0
- package/dist/nextjs/client.js +37 -0
- package/dist/nextjs/client.js.map +1 -0
- package/dist/nextjs/index.d.ts +19 -7
- package/dist/nextjs/index.d.ts.map +1 -1
- package/dist/nextjs/index.js +90 -36
- package/dist/nextjs/index.js.map +1 -1
- package/dist/plugins/convex/client.d.ts +1 -1
- package/dist/plugins/convex/client.d.ts.map +1 -1
- package/dist/plugins/convex/client.js +0 -1
- package/dist/plugins/convex/client.js.map +1 -1
- package/dist/plugins/convex/index.d.ts +239 -227
- package/dist/plugins/convex/index.d.ts.map +1 -1
- package/dist/plugins/convex/index.js +191 -37
- package/dist/plugins/convex/index.js.map +1 -1
- package/dist/plugins/cross-domain/client.d.ts +3 -3
- package/dist/plugins/cross-domain/client.d.ts.map +1 -1
- package/dist/plugins/cross-domain/index.d.ts +15 -70
- package/dist/plugins/cross-domain/index.d.ts.map +1 -1
- package/dist/plugins/cross-domain/index.js +8 -0
- package/dist/plugins/cross-domain/index.js.map +1 -1
- package/dist/react/index.d.ts +52 -2
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +133 -9
- package/dist/react/index.js.map +1 -1
- package/dist/react-start/index.d.ts +11 -41
- package/dist/react-start/index.d.ts.map +1 -1
- package/dist/react-start/index.js +82 -106
- package/dist/react-start/index.js.map +1 -1
- package/dist/utils/index.d.ts +20 -2
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +54 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +19 -12
- package/src/auth-config.ts +82 -0
- package/src/auth-options.ts +54 -0
- package/src/auth.ts +3 -56
- package/src/client/adapter.ts +5 -5
- package/src/client/create-api.ts +337 -0
- package/src/client/create-client.ts +446 -0
- package/src/client/{createSchema.ts → create-schema.ts} +10 -4
- package/src/client/index.ts +22 -786
- package/src/component/_generated/component.ts +0 -7
- package/src/component/adapter.ts +2 -3
- package/src/nextjs/client.tsx +52 -0
- package/src/nextjs/index.ts +138 -45
- package/src/plugins/convex/client.ts +1 -1
- package/src/plugins/convex/index.ts +337 -51
- package/src/plugins/cross-domain/index.ts +10 -2
- package/src/react/index.tsx +195 -9
- package/src/react-start/index.ts +126 -171
- package/src/test.ts +1 -1
- package/src/utils/index.ts +96 -1
- package/dist/client/adapterUtils.d.ts.map +0 -1
- package/dist/client/adapterUtils.js.map +0 -1
- package/dist/client/createSchema.d.ts.map +0 -1
- package/dist/client/createSchema.js.map +0 -1
- /package/src/client/{adapterUtils.ts → adapter-utils.ts} +0 -0
|
@@ -1028,13 +1028,6 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
1028
1028
|
any,
|
|
1029
1029
|
Name
|
|
1030
1030
|
>;
|
|
1031
|
-
migrationRemoveUserId: FunctionReference<
|
|
1032
|
-
"mutation",
|
|
1033
|
-
"internal",
|
|
1034
|
-
{ userId: string },
|
|
1035
|
-
any,
|
|
1036
|
-
Name
|
|
1037
|
-
>;
|
|
1038
1031
|
updateMany: FunctionReference<
|
|
1039
1032
|
"mutation",
|
|
1040
1033
|
"internal",
|
package/src/component/adapter.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createApi } from "../client/index.js";
|
|
2
|
-
import {
|
|
2
|
+
import { options } from "../auth-options.js";
|
|
3
3
|
import schema from "./schema.js";
|
|
4
4
|
|
|
5
5
|
export const {
|
|
@@ -10,5 +10,4 @@ export const {
|
|
|
10
10
|
updateMany,
|
|
11
11
|
deleteOne,
|
|
12
12
|
deleteMany,
|
|
13
|
-
|
|
14
|
-
} = createApi(schema, () => auth);
|
|
13
|
+
} = createApi(schema, () => options);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type Preloaded, useConvexAuth, useQuery } from "convex/react";
|
|
2
|
+
import { type FunctionReference, makeFunctionReference } from "convex/server";
|
|
3
|
+
import { jsonToConvex } from "convex/values";
|
|
4
|
+
import { useEffect, useMemo, useState } from "react";
|
|
5
|
+
|
|
6
|
+
const useConvexPreloadedQuery = <Query extends FunctionReference<"query">>(
|
|
7
|
+
preloadedQuery: Preloaded<Query>,
|
|
8
|
+
{ requireAuth = true }: { requireAuth?: boolean } = {}
|
|
9
|
+
): Query["_returnType"] => {
|
|
10
|
+
const { isLoading, isAuthenticated } = useConvexAuth();
|
|
11
|
+
const [preloadExpired, setPreloadExpired] = useState(false);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (requireAuth && !isLoading && !isAuthenticated) {
|
|
14
|
+
setPreloadExpired(true);
|
|
15
|
+
}
|
|
16
|
+
}, [requireAuth, isLoading, isAuthenticated]);
|
|
17
|
+
const args = useMemo(
|
|
18
|
+
() => jsonToConvex(preloadedQuery._argsJSON),
|
|
19
|
+
[preloadedQuery._argsJSON]
|
|
20
|
+
) as Query["_args"];
|
|
21
|
+
const preloadedResult = useMemo(
|
|
22
|
+
() => jsonToConvex(preloadedQuery._valueJSON),
|
|
23
|
+
[preloadedQuery._valueJSON]
|
|
24
|
+
);
|
|
25
|
+
const result = useQuery(
|
|
26
|
+
makeFunctionReference(preloadedQuery._name) as Query,
|
|
27
|
+
requireAuth && !isAuthenticated ? ("skip" as const) : args
|
|
28
|
+
);
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (result !== undefined) {
|
|
31
|
+
setPreloadExpired(true);
|
|
32
|
+
}
|
|
33
|
+
}, [result]);
|
|
34
|
+
if (requireAuth) {
|
|
35
|
+
return preloadExpired ? result : preloadedResult;
|
|
36
|
+
}
|
|
37
|
+
return result === undefined ? preloadedResult : result;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const usePreloadedAuthQuery = <Query extends FunctionReference<"query">>(
|
|
41
|
+
preloadedQuery: Preloaded<Query>
|
|
42
|
+
): Query["_returnType"] | null => {
|
|
43
|
+
const { isLoading } = useConvexAuth();
|
|
44
|
+
const latestData = useConvexPreloadedQuery(preloadedQuery);
|
|
45
|
+
const [data, setData] = useState(latestData);
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
if (!isLoading) {
|
|
48
|
+
setData(latestData);
|
|
49
|
+
}
|
|
50
|
+
}, [latestData, isLoading]);
|
|
51
|
+
return data;
|
|
52
|
+
};
|
package/src/nextjs/index.ts
CHANGED
|
@@ -1,56 +1,149 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { stripIndent } from "common-tags";
|
|
2
|
+
import {
|
|
3
|
+
fetchAction,
|
|
4
|
+
fetchMutation,
|
|
5
|
+
fetchQuery,
|
|
6
|
+
preloadQuery,
|
|
7
|
+
} from "convex/nextjs";
|
|
8
|
+
import type { Preloaded } from "convex/react";
|
|
9
|
+
import {
|
|
10
|
+
type ArgsAndOptions,
|
|
11
|
+
type FunctionReference,
|
|
12
|
+
type FunctionReturnType,
|
|
13
|
+
} from "convex/server";
|
|
14
|
+
import React from "react";
|
|
15
|
+
import { getToken, type GetTokenOptions } from "../utils/index.js";
|
|
16
|
+
import type { EmptyObject } from "convex-helpers";
|
|
5
17
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
console.warn(
|
|
27
|
-
`Looking for secure cookie ${cookie.name} but found insecure cookie ${insecureCookie.name}`
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
if (!isSecure && secureCookie) {
|
|
31
|
-
console.warn(
|
|
32
|
-
`Looking for insecure cookie ${cookie.name} but found secure cookie ${secureCookie.name}`
|
|
33
|
-
);
|
|
34
|
-
}
|
|
18
|
+
// Caching supported for React 19+ only
|
|
19
|
+
const cache =
|
|
20
|
+
React.cache ||
|
|
21
|
+
((fn: (...args: any[]) => any) => {
|
|
22
|
+
return (...args: any[]) => fn(...args);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const parseConvexSiteUrl = (url: string) => {
|
|
26
|
+
if (!url) {
|
|
27
|
+
throw new Error(stripIndent`
|
|
28
|
+
CONVEX_SITE_URL is not set.
|
|
29
|
+
This is automatically set in the Convex backend, but must be set in the Next.js environment.
|
|
30
|
+
For local development, this can be set in the .env.local file.
|
|
31
|
+
`);
|
|
32
|
+
}
|
|
33
|
+
if (url.endsWith(".convex.cloud")) {
|
|
34
|
+
throw new Error(stripIndent`
|
|
35
|
+
CONVEX_SITE_URL should be set to your Convex Site URL, which ends in .convex.site.
|
|
36
|
+
Currently set to ${url}.
|
|
37
|
+
`);
|
|
35
38
|
}
|
|
36
|
-
return
|
|
39
|
+
return url;
|
|
37
40
|
};
|
|
38
41
|
|
|
39
|
-
const handler = (request: Request,
|
|
42
|
+
const handler = (request: Request, siteUrl: string) => {
|
|
40
43
|
const requestUrl = new URL(request.url);
|
|
41
|
-
const
|
|
42
|
-
opts?.convexSiteUrl ?? process.env.NEXT_PUBLIC_CONVEX_SITE_URL;
|
|
43
|
-
if (!convexSiteUrl) {
|
|
44
|
-
throw new Error("NEXT_PUBLIC_CONVEX_SITE_URL is not set");
|
|
45
|
-
}
|
|
46
|
-
const nextUrl = `${convexSiteUrl}${requestUrl.pathname}${requestUrl.search}`;
|
|
44
|
+
const nextUrl = `${siteUrl}${requestUrl.pathname}${requestUrl.search}`;
|
|
47
45
|
const newRequest = new Request(nextUrl, request);
|
|
48
46
|
newRequest.headers.set("accept-encoding", "application/json");
|
|
49
|
-
newRequest.headers.set("host",
|
|
47
|
+
newRequest.headers.set("host", siteUrl);
|
|
50
48
|
return fetch(newRequest, { method: request.method, redirect: "manual" });
|
|
51
49
|
};
|
|
52
50
|
|
|
53
|
-
|
|
54
|
-
GET: (request: Request) => handler(request,
|
|
55
|
-
POST: (request: Request) => handler(request,
|
|
51
|
+
const nextJsHandler = (siteUrl: string) => ({
|
|
52
|
+
GET: (request: Request) => handler(request, siteUrl),
|
|
53
|
+
POST: (request: Request) => handler(request, siteUrl),
|
|
56
54
|
});
|
|
55
|
+
|
|
56
|
+
type OptionalArgs<FuncRef extends FunctionReference<any, any>> =
|
|
57
|
+
FuncRef["_args"] extends EmptyObject
|
|
58
|
+
? [args?: EmptyObject]
|
|
59
|
+
: [args: FuncRef["_args"]];
|
|
60
|
+
|
|
61
|
+
const getArgsAndOptions = <FuncRef extends FunctionReference<any, any>>(
|
|
62
|
+
args: OptionalArgs<FuncRef>,
|
|
63
|
+
token?: string
|
|
64
|
+
): ArgsAndOptions<FuncRef, { token?: string }> => {
|
|
65
|
+
return [args[0], { token }];
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const convexBetterAuthNextJs = (
|
|
69
|
+
opts: GetTokenOptions & { convexUrl: string; convexSiteUrl: string }
|
|
70
|
+
) => {
|
|
71
|
+
const siteUrl = parseConvexSiteUrl(opts.convexSiteUrl);
|
|
72
|
+
|
|
73
|
+
const cachedGetToken = cache(
|
|
74
|
+
async ({ forceRefresh }: { forceRefresh?: boolean } = {}) => {
|
|
75
|
+
const headers = await (await import("next/headers.js")).headers();
|
|
76
|
+
return getToken(siteUrl, headers, { ...opts, forceRefresh });
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
const callWithToken = async <
|
|
81
|
+
FnType extends "query" | "mutation" | "action",
|
|
82
|
+
Fn extends FunctionReference<FnType>,
|
|
83
|
+
>(
|
|
84
|
+
fn: (token?: string) => Promise<FunctionReturnType<Fn>>
|
|
85
|
+
): Promise<FunctionReturnType<Fn>> => {
|
|
86
|
+
const token = await cachedGetToken();
|
|
87
|
+
try {
|
|
88
|
+
return await fn(token?.token);
|
|
89
|
+
} catch (error) {
|
|
90
|
+
if (
|
|
91
|
+
!opts?.jwtCache?.enabled ||
|
|
92
|
+
token.isFresh ||
|
|
93
|
+
opts.jwtCache.isAuthError(error)
|
|
94
|
+
) {
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
const newToken = await cachedGetToken({ forceRefresh: true });
|
|
98
|
+
return await fn(newToken.token);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
getToken: async () => {
|
|
104
|
+
const token = await cachedGetToken();
|
|
105
|
+
return token.token;
|
|
106
|
+
},
|
|
107
|
+
handler: nextJsHandler(siteUrl),
|
|
108
|
+
isAuthenticated: async () => {
|
|
109
|
+
const token = await cachedGetToken();
|
|
110
|
+
return !!token.token;
|
|
111
|
+
},
|
|
112
|
+
preloadAuthQuery: async <Query extends FunctionReference<"query">>(
|
|
113
|
+
query: Query,
|
|
114
|
+
...args: OptionalArgs<Query>
|
|
115
|
+
): Promise<Preloaded<Query>> => {
|
|
116
|
+
return callWithToken((token?: string) => {
|
|
117
|
+
const argsAndOptions = getArgsAndOptions(args, token);
|
|
118
|
+
return preloadQuery(query, ...argsAndOptions);
|
|
119
|
+
});
|
|
120
|
+
},
|
|
121
|
+
fetchAuthQuery: async <Query extends FunctionReference<"query">>(
|
|
122
|
+
query: Query,
|
|
123
|
+
...args: OptionalArgs<Query>
|
|
124
|
+
): Promise<FunctionReturnType<Query>> => {
|
|
125
|
+
return callWithToken((token?: string) => {
|
|
126
|
+
const argsAndOptions = getArgsAndOptions(args, token);
|
|
127
|
+
return fetchQuery(query, ...argsAndOptions);
|
|
128
|
+
});
|
|
129
|
+
},
|
|
130
|
+
fetchAuthMutation: async <Mutation extends FunctionReference<"mutation">>(
|
|
131
|
+
mutation: Mutation,
|
|
132
|
+
...args: OptionalArgs<Mutation>
|
|
133
|
+
): Promise<FunctionReturnType<Mutation>> => {
|
|
134
|
+
return callWithToken((token?: string) => {
|
|
135
|
+
const argsAndOptions = getArgsAndOptions(args, token);
|
|
136
|
+
return fetchMutation(mutation, ...argsAndOptions);
|
|
137
|
+
});
|
|
138
|
+
},
|
|
139
|
+
fetchAuthAction: async <Action extends FunctionReference<"action">>(
|
|
140
|
+
action: Action,
|
|
141
|
+
...args: OptionalArgs<Action>
|
|
142
|
+
): Promise<FunctionReturnType<Action>> => {
|
|
143
|
+
return callWithToken((token?: string) => {
|
|
144
|
+
const argsAndOptions = getArgsAndOptions(args, token);
|
|
145
|
+
return fetchAction(action, ...argsAndOptions);
|
|
146
|
+
});
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
};
|