UNPKG

@reliverse/rse

Version:

@reliverse/rse is your all-in-one companion for bootstrapping and improving any kind of projects (especially web apps built with frameworks like Next.js) — whether you're kicking off something new or upgrading an existing app. It is also a little AI-power

174 lines (173 loc) 6.24 kB
import babelPresetReact from "@babel/preset-react"; import babelPresetTypeScript from "@babel/preset-typescript"; import { pathExists } from "@reliverse/relifso"; import { logger } from "better-auth"; import { BetterAuthError } from "better-auth"; import { loadConfig } from "c12"; import path from "path"; import { addSvelteKitEnvModules } from "./add-svelte-kit-env-modules.js"; import { getTsconfigInfo } from "./get-tsconfig-info.js"; let possiblePaths = [ "auth.ts", "auth.tsx", "auth.js", "auth.jsx", "auth.server.js", "auth.server.ts" ]; possiblePaths = [ ...possiblePaths, ...possiblePaths.map((it) => `lib/server/${it}`), ...possiblePaths.map((it) => `server/${it}`), ...possiblePaths.map((it) => `lib/${it}`), ...possiblePaths.map((it) => `utils/${it}`) ]; possiblePaths = [ ...possiblePaths, ...possiblePaths.map((it) => `src/${it}`), ...possiblePaths.map((it) => `app/${it}`) ]; async function getPathAliases(cwd) { const tsConfigPath = path.join(cwd, "tsconfig.json"); if (!await pathExists(tsConfigPath)) { return null; } try { const tsConfig = await getTsconfigInfo(cwd); const { paths = {}, baseUrl = "." } = tsConfig.compilerOptions || {}; const result = {}; const obj = Object.entries(paths); for (const [alias, aliasPaths] of obj) { for (const aliasedPath of aliasPaths) { const resolvedBaseUrl = path.join(cwd, baseUrl); const finalAlias = alias.endsWith("*") ? alias.slice(0, -1) : alias; const finalAliasedPath = aliasedPath.endsWith("*") ? aliasedPath.slice(0, -1) : aliasedPath; result[finalAlias || ""] = path.join(resolvedBaseUrl, finalAliasedPath); } } addSvelteKitEnvModules(result); return result; } catch (error) { console.error(error); throw new BetterAuthError("Error parsing tsconfig.json"); } } const jitiOptions = async (cwd) => { const alias = await getPathAliases(cwd) || {}; return { transformOptions: { babel: { presets: [ [ babelPresetTypeScript, { isTSX: true, allExtensions: true } ], [babelPresetReact, { runtime: "automatic" }] ] } }, extensions: [".ts", ".tsx", ".js", ".jsx"], alias }; }; export async function getConfig({ cwd, configPath, shouldThrowOnError = false }) { try { let configFile = null; if (configPath) { let resolvedPath = path.join(cwd, configPath); if (await pathExists(configPath)) resolvedPath = configPath; const { config } = await loadConfig({ configFile: resolvedPath, dotenv: true, jitiOptions: await jitiOptions(cwd) }); if (!config.auth && !config.default) { if (shouldThrowOnError) { throw new Error( `Couldn't read your auth config in ${resolvedPath}. Make sure to default export your auth instance or to export as a variable named auth.` ); } logger.error( `[#better-auth]: Couldn't read your auth config in ${resolvedPath}. Make sure to default export your auth instance or to export as a variable named auth.` ); process.exit(1); } configFile = config.auth?.options || config.default?.options || null; } if (!configFile) { for (const possiblePath of possiblePaths) { try { const { config } = await loadConfig({ configFile: possiblePath, jitiOptions: await jitiOptions(cwd) }); const hasConfig = Object.keys(config).length > 0; if (hasConfig) { configFile = config.auth?.options || config.default?.options || null; if (!configFile) { if (shouldThrowOnError) { throw new Error( "Couldn't read your auth config. Make sure to default export your auth instance or to export as a variable named auth." ); } logger.error("[#better-auth]: Couldn't read your auth config."); console.log(""); logger.info( "[#better-auth]: Make sure to default export your auth instance or to export as a variable named auth." ); process.exit(1); } break; } } catch (e) { if (typeof e === "object" && e && "message" in e && typeof e.message === "string" && e.message.includes( "This module cannot be imported from a Client Component module" )) { if (shouldThrowOnError) { throw new Error( `Please remove import 'server-only' from your auth config file temporarily. The CLI cannot resolve the configuration with it included. You can re-add it after running the CLI.` ); } logger.error( `Please remove import 'server-only' from your auth config file temporarily. The CLI cannot resolve the configuration with it included. You can re-add it after running the CLI.` ); process.exit(1); } if (shouldThrowOnError) { throw e; } logger.error("[#better-auth]: Couldn't read your auth config.", e); process.exit(1); } } } return configFile; } catch (e) { if (typeof e === "object" && e && "message" in e && typeof e.message === "string" && e.message.includes( "This module cannot be imported from a Client Component module" )) { if (shouldThrowOnError) { throw new Error( `Please remove import 'server-only' from your auth config file temporarily. The CLI cannot resolve the configuration with it included. You can re-add it after running the CLI.` ); } logger.error( `Please remove import 'server-only' from your auth config file temporarily. The CLI cannot resolve the configuration with it included. You can re-add it after running the CLI.` ); process.exit(1); } if (shouldThrowOnError) { throw e; } logger.error("Couldn't read your auth config.", e); process.exit(1); } } export { possiblePaths };