better-auth
Version:
The most comprehensive authentication framework for TypeScript.
106 lines (105 loc) • 3.96 kB
JavaScript
import { getBaseURL } from "../utils/url.mjs";
import { parseJSON } from "./parser.mjs";
import { redirectPlugin } from "./fetch-plugins.mjs";
import { getSessionAtom } from "./session-atom.mjs";
import { defu as defu$1 } from "defu";
import { createFetch } from "@better-fetch/fetch";
//#region src/client/config.ts
const resolvePublicAuthUrl = (basePath) => {
if (typeof process === "undefined") return void 0;
const path = basePath ?? "/api/auth";
if (process.env.NEXT_PUBLIC_AUTH_URL) return process.env.NEXT_PUBLIC_AUTH_URL;
if (typeof window === "undefined") {
if (process.env.NEXTAUTH_URL) try {
return process.env.NEXTAUTH_URL;
} catch {}
if (process.env.VERCEL_URL) try {
const protocol = process.env.VERCEL_URL.startsWith("http") ? "" : "https://";
return `${new URL(`${protocol}${process.env.VERCEL_URL}`).origin}${path}`;
} catch {}
}
};
const getClientConfig = (options, loadEnv) => {
const isCredentialsSupported = "credentials" in Request.prototype;
const baseURL = getBaseURL(options?.baseURL, options?.basePath, void 0, loadEnv) ?? resolvePublicAuthUrl(options?.basePath) ?? "/api/auth";
const pluginsFetchPlugins = options?.plugins?.flatMap((plugin) => plugin.fetchPlugins).filter((pl) => pl !== void 0) || [];
const lifeCyclePlugin = {
id: "lifecycle-hooks",
name: "lifecycle-hooks",
hooks: {
onSuccess: options?.fetchOptions?.onSuccess,
onError: options?.fetchOptions?.onError,
onRequest: options?.fetchOptions?.onRequest,
onResponse: options?.fetchOptions?.onResponse
}
};
const { onSuccess: _onSuccess, onError: _onError, onRequest: _onRequest, onResponse: _onResponse, ...restOfFetchOptions } = options?.fetchOptions || {};
const $fetch = createFetch({
baseURL,
...isCredentialsSupported ? { credentials: "include" } : {},
method: "GET",
jsonParser(text) {
if (!text) return null;
return parseJSON(text, { strict: false });
},
customFetchImpl: fetch,
...restOfFetchOptions,
plugins: [
lifeCyclePlugin,
...restOfFetchOptions.plugins || [],
...options?.disableDefaultFetchPlugins ? [] : [redirectPlugin],
...pluginsFetchPlugins
]
});
const { $sessionSignal, session, broadcastSessionUpdate } = getSessionAtom($fetch, options);
const plugins = options?.plugins || [];
let pluginsActions = {};
const pluginsAtoms = {
$sessionSignal,
session
};
const pluginPathMethods = {
"/sign-out": "POST",
"/revoke-sessions": "POST",
"/revoke-other-sessions": "POST",
"/delete-user": "POST"
};
const atomListeners = [{
signal: "$sessionSignal",
matcher(path) {
return path === "/sign-out" || path === "/update-user" || path === "/update-session" || path === "/sign-up/email" || path === "/sign-in/email" || path === "/delete-user" || path === "/verify-email" || path === "/revoke-sessions" || path === "/revoke-session" || path === "/revoke-other-sessions" || path === "/change-email" || path === "/change-password";
},
callback(path) {
if (path === "/sign-out") broadcastSessionUpdate("signout");
else if (path === "/update-user" || path === "/update-session") broadcastSessionUpdate("updateUser");
}
}];
for (const plugin of plugins) {
if (plugin.getAtoms) Object.assign(pluginsAtoms, plugin.getAtoms?.($fetch));
if (plugin.pathMethods) Object.assign(pluginPathMethods, plugin.pathMethods);
if (plugin.atomListeners) atomListeners.push(...plugin.atomListeners);
}
const $store = {
notify: (signal) => {
pluginsAtoms[signal].set(!pluginsAtoms[signal].get());
},
listen: (signal, listener) => {
pluginsAtoms[signal].subscribe(listener);
},
atoms: pluginsAtoms
};
for (const plugin of plugins) if (plugin.getActions) pluginsActions = defu$1(plugin.getActions?.($fetch, $store, options) ?? {}, pluginsActions);
return {
get baseURL() {
return baseURL;
},
pluginsActions,
pluginsAtoms,
pluginPathMethods,
atomListeners,
$fetch,
$store
};
};
//#endregion
export { getClientConfig };