@better-auth/cli 1.3.8-beta.3 → 1.3.8-beta.5
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/index.mjs +447 -25
- package/package.json +4 -10
package/dist/index.mjs
CHANGED
|
@@ -4,13 +4,12 @@ import { parse } from 'dotenv';
|
|
|
4
4
|
import semver from 'semver';
|
|
5
5
|
import prettier, { format } from 'prettier';
|
|
6
6
|
import * as z from 'zod/v4';
|
|
7
|
-
import fs
|
|
7
|
+
import fs, { existsSync, readFileSync } from 'fs';
|
|
8
8
|
import path from 'path';
|
|
9
9
|
import fs$1 from 'fs/promises';
|
|
10
|
-
import fs from 'fs-extra';
|
|
11
10
|
import chalk from 'chalk';
|
|
12
11
|
import { intro, log, outro, confirm, isCancel, cancel, spinner, text, select, multiselect } from '@clack/prompts';
|
|
13
|
-
import { exec } from 'child_process';
|
|
12
|
+
import { exec, execSync } from 'child_process';
|
|
14
13
|
import { logger, BetterAuthError, createTelemetry, getTelemetryAuthConfig, capitalizeFirstLetter } from 'better-auth';
|
|
15
14
|
import Crypto from 'crypto';
|
|
16
15
|
import yoctoSpinner from 'yocto-spinner';
|
|
@@ -28,11 +27,7 @@ import 'dotenv/config';
|
|
|
28
27
|
|
|
29
28
|
function getPackageInfo(cwd) {
|
|
30
29
|
const packageJsonPath = cwd ? path.join(cwd, "package.json") : path.join("package.json");
|
|
31
|
-
|
|
32
|
-
return fs.readJSONSync(packageJsonPath);
|
|
33
|
-
} catch (error) {
|
|
34
|
-
throw error;
|
|
35
|
-
}
|
|
30
|
+
return JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
36
31
|
}
|
|
37
32
|
|
|
38
33
|
function installDependencies({
|
|
@@ -1074,7 +1069,7 @@ async function initAction(opts) {
|
|
|
1074
1069
|
process.exit(0);
|
|
1075
1070
|
}
|
|
1076
1071
|
if (packageManagerPreference === void 0) {
|
|
1077
|
-
packageManagerPreference = await getPackageManager();
|
|
1072
|
+
packageManagerPreference = await getPackageManager$1();
|
|
1078
1073
|
}
|
|
1079
1074
|
if (shouldInstallBetterAuthDep) {
|
|
1080
1075
|
s2.start(
|
|
@@ -1114,7 +1109,7 @@ async function initAction(opts) {
|
|
|
1114
1109
|
}
|
|
1115
1110
|
if (shouldInstallBetterAuthDep) {
|
|
1116
1111
|
if (packageManagerPreference === void 0) {
|
|
1117
|
-
packageManagerPreference = await getPackageManager();
|
|
1112
|
+
packageManagerPreference = await getPackageManager$1();
|
|
1118
1113
|
}
|
|
1119
1114
|
const s2 = spinner({ indicator: "dots" });
|
|
1120
1115
|
s2.start(
|
|
@@ -1342,7 +1337,7 @@ async function initAction(opts) {
|
|
|
1342
1337
|
if (shouldInstallDeps) {
|
|
1343
1338
|
const s2 = spinner({ indicator: "dots" });
|
|
1344
1339
|
if (packageManagerPreference === void 0) {
|
|
1345
|
-
packageManagerPreference = await getPackageManager();
|
|
1340
|
+
packageManagerPreference = await getPackageManager$1();
|
|
1346
1341
|
}
|
|
1347
1342
|
s2.start(
|
|
1348
1343
|
`Installing dependencies using ${chalk.bold(
|
|
@@ -1591,7 +1586,7 @@ async function getLatestNpmVersion(packageName) {
|
|
|
1591
1586
|
throw error?.message;
|
|
1592
1587
|
}
|
|
1593
1588
|
}
|
|
1594
|
-
async function getPackageManager() {
|
|
1589
|
+
async function getPackageManager$1() {
|
|
1595
1590
|
const { hasBun, hasPnpm } = await checkPackageManagers();
|
|
1596
1591
|
if (!hasBun && !hasPnpm) return "npm";
|
|
1597
1592
|
const packageManagerOptions = [];
|
|
@@ -1694,9 +1689,9 @@ function getSvelteKitPathAliases(cwd) {
|
|
|
1694
1689
|
const svelteConfigPath = path.join(cwd, "svelte.config.js");
|
|
1695
1690
|
const svelteConfigTsPath = path.join(cwd, "svelte.config.ts");
|
|
1696
1691
|
let isSvelteKitProject = false;
|
|
1697
|
-
if (fs
|
|
1692
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
1698
1693
|
try {
|
|
1699
|
-
const packageJson = JSON.parse(fs
|
|
1694
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
1700
1695
|
const deps = {
|
|
1701
1696
|
...packageJson.dependencies,
|
|
1702
1697
|
...packageJson.devDependencies
|
|
@@ -1706,19 +1701,19 @@ function getSvelteKitPathAliases(cwd) {
|
|
|
1706
1701
|
}
|
|
1707
1702
|
}
|
|
1708
1703
|
if (!isSvelteKitProject) {
|
|
1709
|
-
isSvelteKitProject = fs
|
|
1704
|
+
isSvelteKitProject = fs.existsSync(svelteConfigPath) || fs.existsSync(svelteConfigTsPath);
|
|
1710
1705
|
}
|
|
1711
1706
|
if (!isSvelteKitProject) {
|
|
1712
1707
|
return aliases;
|
|
1713
1708
|
}
|
|
1714
1709
|
const libPaths = [path.join(cwd, "src", "lib"), path.join(cwd, "lib")];
|
|
1715
1710
|
for (const libPath of libPaths) {
|
|
1716
|
-
if (fs
|
|
1711
|
+
if (fs.existsSync(libPath)) {
|
|
1717
1712
|
aliases["$lib"] = libPath;
|
|
1718
1713
|
const commonSubPaths = ["server", "utils", "components", "stores"];
|
|
1719
1714
|
for (const subPath of commonSubPaths) {
|
|
1720
1715
|
const subDir = path.join(libPath, subPath);
|
|
1721
|
-
if (fs
|
|
1716
|
+
if (fs.existsSync(subDir)) {
|
|
1722
1717
|
aliases[`$lib/${subPath}`] = subDir;
|
|
1723
1718
|
}
|
|
1724
1719
|
}
|
|
@@ -1737,9 +1732,9 @@ function getSvelteConfigAliases(cwd) {
|
|
|
1737
1732
|
path.join(cwd, "svelte.config.ts")
|
|
1738
1733
|
];
|
|
1739
1734
|
for (const configPath of configPaths) {
|
|
1740
|
-
if (fs
|
|
1735
|
+
if (fs.existsSync(configPath)) {
|
|
1741
1736
|
try {
|
|
1742
|
-
const content = fs
|
|
1737
|
+
const content = fs.readFileSync(configPath, "utf-8");
|
|
1743
1738
|
const aliasMatch = content.match(/alias\s*:\s*\{([^}]+)\}/);
|
|
1744
1739
|
if (aliasMatch && aliasMatch[1]) {
|
|
1745
1740
|
const aliasContent = aliasMatch[1];
|
|
@@ -1875,9 +1870,9 @@ function resolveReferencePath(configDir, refPath) {
|
|
|
1875
1870
|
if (refPath.endsWith(".json")) {
|
|
1876
1871
|
return resolvedPath;
|
|
1877
1872
|
}
|
|
1878
|
-
if (fs
|
|
1873
|
+
if (fs.existsSync(resolvedPath)) {
|
|
1879
1874
|
try {
|
|
1880
|
-
const stats = fs
|
|
1875
|
+
const stats = fs.statSync(resolvedPath);
|
|
1881
1876
|
if (stats.isFile()) {
|
|
1882
1877
|
return resolvedPath;
|
|
1883
1878
|
}
|
|
@@ -1891,7 +1886,7 @@ function getPathAliasesRecursive(tsconfigPath, visited = /* @__PURE__ */ new Set
|
|
|
1891
1886
|
return {};
|
|
1892
1887
|
}
|
|
1893
1888
|
visited.add(tsconfigPath);
|
|
1894
|
-
if (!fs
|
|
1889
|
+
if (!fs.existsSync(tsconfigPath)) {
|
|
1895
1890
|
logger.warn(`Referenced tsconfig not found: ${tsconfigPath}`);
|
|
1896
1891
|
return {};
|
|
1897
1892
|
}
|
|
@@ -1928,7 +1923,7 @@ function getPathAliasesRecursive(tsconfigPath, visited = /* @__PURE__ */ new Set
|
|
|
1928
1923
|
}
|
|
1929
1924
|
function getPathAliases(cwd) {
|
|
1930
1925
|
const tsConfigPath = path.join(cwd, "tsconfig.json");
|
|
1931
|
-
if (!fs
|
|
1926
|
+
if (!fs.existsSync(tsConfigPath)) {
|
|
1932
1927
|
return null;
|
|
1933
1928
|
}
|
|
1934
1929
|
try {
|
|
@@ -2342,8 +2337,13 @@ const generateDrizzleSchema = async ({
|
|
|
2342
2337
|
type += `.default(${attr.defaultValue})`;
|
|
2343
2338
|
}
|
|
2344
2339
|
}
|
|
2340
|
+
if (attr.onUpdate && attr.type === "date") {
|
|
2341
|
+
if (typeof attr.onUpdate === "function") {
|
|
2342
|
+
type += `.$onUpdate(${attr.onUpdate})`;
|
|
2343
|
+
}
|
|
2344
|
+
}
|
|
2345
2345
|
return `${field}: ${type}${attr.required ? ".notNull()" : ""}${attr.unique ? ".unique()" : ""}${attr.references ? `.references(()=> ${getModelName(
|
|
2346
|
-
attr.references.model,
|
|
2346
|
+
tables[attr.references.model]?.modelName || attr.references.model,
|
|
2347
2347
|
adapter.options
|
|
2348
2348
|
)}.${attr.references.field}, { onDelete: '${attr.references.onDelete || "cascade"}' })` : ""}`;
|
|
2349
2349
|
}).join(",\n ")}
|
|
@@ -2899,6 +2899,11 @@ async function loginAction(opts) {
|
|
|
2899
2899
|
"\n\u{1F4DD} Note: This was a demo authentication for testing purposes."
|
|
2900
2900
|
)
|
|
2901
2901
|
);
|
|
2902
|
+
console.log(
|
|
2903
|
+
chalk.blue(
|
|
2904
|
+
"\nFor more information, visit: https://better-auth.com/docs/plugins/device-authorization"
|
|
2905
|
+
)
|
|
2906
|
+
);
|
|
2902
2907
|
}
|
|
2903
2908
|
} catch (err) {
|
|
2904
2909
|
spinner.stop();
|
|
@@ -2998,6 +3003,423 @@ const login = new Command("login").description(
|
|
|
2998
3003
|
"Demo: Test device authorization flow with Better Auth demo server"
|
|
2999
3004
|
).option("--server-url <url>", "The Better Auth server URL", DEMO_URL).option("--client-id <id>", "The OAuth client ID", CLIENT_ID).action(loginAction);
|
|
3000
3005
|
|
|
3006
|
+
function getSystemInfo() {
|
|
3007
|
+
const platform = os.platform();
|
|
3008
|
+
const arch = os.arch();
|
|
3009
|
+
const version = os.version();
|
|
3010
|
+
const release = os.release();
|
|
3011
|
+
const cpus = os.cpus();
|
|
3012
|
+
const memory = os.totalmem();
|
|
3013
|
+
const freeMemory = os.freemem();
|
|
3014
|
+
return {
|
|
3015
|
+
platform,
|
|
3016
|
+
arch,
|
|
3017
|
+
version,
|
|
3018
|
+
release,
|
|
3019
|
+
cpuCount: cpus.length,
|
|
3020
|
+
cpuModel: cpus[0]?.model || "Unknown",
|
|
3021
|
+
totalMemory: `${(memory / 1024 / 1024 / 1024).toFixed(2)} GB`,
|
|
3022
|
+
freeMemory: `${(freeMemory / 1024 / 1024 / 1024).toFixed(2)} GB`
|
|
3023
|
+
};
|
|
3024
|
+
}
|
|
3025
|
+
function getNodeInfo() {
|
|
3026
|
+
return {
|
|
3027
|
+
version: process.version,
|
|
3028
|
+
env: process.env.NODE_ENV || "development"
|
|
3029
|
+
};
|
|
3030
|
+
}
|
|
3031
|
+
function getPackageManager() {
|
|
3032
|
+
const userAgent = process.env.npm_config_user_agent || "";
|
|
3033
|
+
if (userAgent.includes("yarn")) {
|
|
3034
|
+
return { name: "yarn", version: getVersion("yarn") };
|
|
3035
|
+
}
|
|
3036
|
+
if (userAgent.includes("pnpm")) {
|
|
3037
|
+
return { name: "pnpm", version: getVersion("pnpm") };
|
|
3038
|
+
}
|
|
3039
|
+
if (userAgent.includes("bun")) {
|
|
3040
|
+
return { name: "bun", version: getVersion("bun") };
|
|
3041
|
+
}
|
|
3042
|
+
return { name: "npm", version: getVersion("npm") };
|
|
3043
|
+
}
|
|
3044
|
+
function getVersion(command) {
|
|
3045
|
+
try {
|
|
3046
|
+
const output = execSync(`${command} --version`, { encoding: "utf8" });
|
|
3047
|
+
return output.trim();
|
|
3048
|
+
} catch {
|
|
3049
|
+
return "Not installed";
|
|
3050
|
+
}
|
|
3051
|
+
}
|
|
3052
|
+
function getFrameworkInfo(projectRoot) {
|
|
3053
|
+
const packageJsonPath = path.join(projectRoot, "package.json");
|
|
3054
|
+
if (!existsSync(packageJsonPath)) {
|
|
3055
|
+
return null;
|
|
3056
|
+
}
|
|
3057
|
+
try {
|
|
3058
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
3059
|
+
const deps = {
|
|
3060
|
+
...packageJson.dependencies,
|
|
3061
|
+
...packageJson.devDependencies
|
|
3062
|
+
};
|
|
3063
|
+
const frameworks = {
|
|
3064
|
+
next: deps["next"],
|
|
3065
|
+
react: deps["react"],
|
|
3066
|
+
vue: deps["vue"],
|
|
3067
|
+
nuxt: deps["nuxt"],
|
|
3068
|
+
svelte: deps["svelte"],
|
|
3069
|
+
"@sveltejs/kit": deps["@sveltejs/kit"],
|
|
3070
|
+
express: deps["express"],
|
|
3071
|
+
fastify: deps["fastify"],
|
|
3072
|
+
hono: deps["hono"],
|
|
3073
|
+
remix: deps["@remix-run/react"],
|
|
3074
|
+
astro: deps["astro"],
|
|
3075
|
+
solid: deps["solid-js"],
|
|
3076
|
+
qwik: deps["@builder.io/qwik"]
|
|
3077
|
+
};
|
|
3078
|
+
const installedFrameworks = Object.entries(frameworks).filter(([_, version]) => version).map(([name, version]) => ({ name, version }));
|
|
3079
|
+
return installedFrameworks.length > 0 ? installedFrameworks : null;
|
|
3080
|
+
} catch {
|
|
3081
|
+
return null;
|
|
3082
|
+
}
|
|
3083
|
+
}
|
|
3084
|
+
function getDatabaseInfo(projectRoot) {
|
|
3085
|
+
const packageJsonPath = path.join(projectRoot, "package.json");
|
|
3086
|
+
if (!existsSync(packageJsonPath)) {
|
|
3087
|
+
return null;
|
|
3088
|
+
}
|
|
3089
|
+
try {
|
|
3090
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
3091
|
+
const deps = {
|
|
3092
|
+
...packageJson.dependencies,
|
|
3093
|
+
...packageJson.devDependencies
|
|
3094
|
+
};
|
|
3095
|
+
const databases = {
|
|
3096
|
+
"better-sqlite3": deps["better-sqlite3"],
|
|
3097
|
+
"@libsql/client": deps["@libsql/client"],
|
|
3098
|
+
"@libsql/kysely-libsql": deps["@libsql/kysely-libsql"],
|
|
3099
|
+
mysql2: deps["mysql2"],
|
|
3100
|
+
pg: deps["pg"],
|
|
3101
|
+
postgres: deps["postgres"],
|
|
3102
|
+
"@prisma/client": deps["@prisma/client"],
|
|
3103
|
+
drizzle: deps["drizzle-orm"],
|
|
3104
|
+
kysely: deps["kysely"],
|
|
3105
|
+
mongodb: deps["mongodb"],
|
|
3106
|
+
"@neondatabase/serverless": deps["@neondatabase/serverless"],
|
|
3107
|
+
"@vercel/postgres": deps["@vercel/postgres"],
|
|
3108
|
+
"@planetscale/database": deps["@planetscale/database"]
|
|
3109
|
+
};
|
|
3110
|
+
const installedDatabases = Object.entries(databases).filter(([_, version]) => version).map(([name, version]) => ({ name, version }));
|
|
3111
|
+
return installedDatabases.length > 0 ? installedDatabases : null;
|
|
3112
|
+
} catch {
|
|
3113
|
+
return null;
|
|
3114
|
+
}
|
|
3115
|
+
}
|
|
3116
|
+
function sanitizeBetterAuthConfig(config) {
|
|
3117
|
+
if (!config) return null;
|
|
3118
|
+
const sanitized = JSON.parse(JSON.stringify(config));
|
|
3119
|
+
const sensitiveKeys = [
|
|
3120
|
+
"secret",
|
|
3121
|
+
"clientSecret",
|
|
3122
|
+
"clientId",
|
|
3123
|
+
"authToken",
|
|
3124
|
+
"apiKey",
|
|
3125
|
+
"apiSecret",
|
|
3126
|
+
"privateKey",
|
|
3127
|
+
"publicKey",
|
|
3128
|
+
"password",
|
|
3129
|
+
"token",
|
|
3130
|
+
"webhook",
|
|
3131
|
+
"connectionString",
|
|
3132
|
+
"databaseUrl",
|
|
3133
|
+
"databaseURL",
|
|
3134
|
+
"TURSO_AUTH_TOKEN",
|
|
3135
|
+
"TURSO_DATABASE_URL",
|
|
3136
|
+
"MYSQL_DATABASE_URL",
|
|
3137
|
+
"DATABASE_URL",
|
|
3138
|
+
"POSTGRES_URL",
|
|
3139
|
+
"MONGODB_URI",
|
|
3140
|
+
"stripeKey",
|
|
3141
|
+
"stripeWebhookSecret"
|
|
3142
|
+
];
|
|
3143
|
+
const allowedKeys = [
|
|
3144
|
+
"baseURL",
|
|
3145
|
+
"callbackURL",
|
|
3146
|
+
"redirectURL",
|
|
3147
|
+
"trustedOrigins",
|
|
3148
|
+
"appName"
|
|
3149
|
+
];
|
|
3150
|
+
function redactSensitive(obj, parentKey) {
|
|
3151
|
+
if (typeof obj !== "object" || obj === null) {
|
|
3152
|
+
if (parentKey && typeof obj === "string" && obj.length > 0) {
|
|
3153
|
+
if (allowedKeys.some(
|
|
3154
|
+
(allowed) => parentKey.toLowerCase() === allowed.toLowerCase()
|
|
3155
|
+
)) {
|
|
3156
|
+
return obj;
|
|
3157
|
+
}
|
|
3158
|
+
const lowerKey = parentKey.toLowerCase();
|
|
3159
|
+
if (sensitiveKeys.some((key) => {
|
|
3160
|
+
const lowerSensitiveKey = key.toLowerCase();
|
|
3161
|
+
return lowerKey === lowerSensitiveKey || lowerKey.endsWith(lowerSensitiveKey);
|
|
3162
|
+
})) {
|
|
3163
|
+
return "[REDACTED]";
|
|
3164
|
+
}
|
|
3165
|
+
}
|
|
3166
|
+
return obj;
|
|
3167
|
+
}
|
|
3168
|
+
if (Array.isArray(obj)) {
|
|
3169
|
+
return obj.map((item) => redactSensitive(item, parentKey));
|
|
3170
|
+
}
|
|
3171
|
+
const result = {};
|
|
3172
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
3173
|
+
if (allowedKeys.some(
|
|
3174
|
+
(allowed) => key.toLowerCase() === allowed.toLowerCase()
|
|
3175
|
+
)) {
|
|
3176
|
+
result[key] = value;
|
|
3177
|
+
continue;
|
|
3178
|
+
}
|
|
3179
|
+
const lowerKey = key.toLowerCase();
|
|
3180
|
+
if (sensitiveKeys.some((sensitiveKey) => {
|
|
3181
|
+
const lowerSensitiveKey = sensitiveKey.toLowerCase();
|
|
3182
|
+
return lowerKey === lowerSensitiveKey || lowerKey.endsWith(lowerSensitiveKey);
|
|
3183
|
+
})) {
|
|
3184
|
+
if (typeof value === "string" && value.length > 0) {
|
|
3185
|
+
result[key] = "[REDACTED]";
|
|
3186
|
+
} else if (typeof value === "object" && value !== null) {
|
|
3187
|
+
result[key] = redactSensitive(value, key);
|
|
3188
|
+
} else {
|
|
3189
|
+
result[key] = value;
|
|
3190
|
+
}
|
|
3191
|
+
} else {
|
|
3192
|
+
result[key] = redactSensitive(value, key);
|
|
3193
|
+
}
|
|
3194
|
+
}
|
|
3195
|
+
return result;
|
|
3196
|
+
}
|
|
3197
|
+
if (sanitized.database) {
|
|
3198
|
+
if (typeof sanitized.database === "string") {
|
|
3199
|
+
sanitized.database = "[REDACTED]";
|
|
3200
|
+
} else if (sanitized.database.url) {
|
|
3201
|
+
sanitized.database.url = "[REDACTED]";
|
|
3202
|
+
}
|
|
3203
|
+
if (sanitized.database.authToken) {
|
|
3204
|
+
sanitized.database.authToken = "[REDACTED]";
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3207
|
+
if (sanitized.socialProviders) {
|
|
3208
|
+
for (const provider in sanitized.socialProviders) {
|
|
3209
|
+
if (sanitized.socialProviders[provider]) {
|
|
3210
|
+
sanitized.socialProviders[provider] = redactSensitive(
|
|
3211
|
+
sanitized.socialProviders[provider],
|
|
3212
|
+
provider
|
|
3213
|
+
);
|
|
3214
|
+
}
|
|
3215
|
+
}
|
|
3216
|
+
}
|
|
3217
|
+
if (sanitized.emailAndPassword?.sendResetPassword) {
|
|
3218
|
+
sanitized.emailAndPassword.sendResetPassword = "[Function]";
|
|
3219
|
+
}
|
|
3220
|
+
if (sanitized.emailVerification?.sendVerificationEmail) {
|
|
3221
|
+
sanitized.emailVerification.sendVerificationEmail = "[Function]";
|
|
3222
|
+
}
|
|
3223
|
+
if (sanitized.plugins && Array.isArray(sanitized.plugins)) {
|
|
3224
|
+
sanitized.plugins = sanitized.plugins.map((plugin) => {
|
|
3225
|
+
if (typeof plugin === "function") {
|
|
3226
|
+
return "[Plugin Function]";
|
|
3227
|
+
}
|
|
3228
|
+
if (plugin && typeof plugin === "object") {
|
|
3229
|
+
const pluginName = plugin.id || plugin.name || "unknown";
|
|
3230
|
+
return {
|
|
3231
|
+
name: pluginName,
|
|
3232
|
+
config: redactSensitive(plugin.config || plugin)
|
|
3233
|
+
};
|
|
3234
|
+
}
|
|
3235
|
+
return plugin;
|
|
3236
|
+
});
|
|
3237
|
+
}
|
|
3238
|
+
return redactSensitive(sanitized);
|
|
3239
|
+
}
|
|
3240
|
+
async function getBetterAuthInfo(projectRoot, configPath, suppressLogs = false) {
|
|
3241
|
+
try {
|
|
3242
|
+
const originalLog = console.log;
|
|
3243
|
+
const originalWarn = console.warn;
|
|
3244
|
+
const originalError = console.error;
|
|
3245
|
+
if (suppressLogs) {
|
|
3246
|
+
console.log = () => {
|
|
3247
|
+
};
|
|
3248
|
+
console.warn = () => {
|
|
3249
|
+
};
|
|
3250
|
+
console.error = () => {
|
|
3251
|
+
};
|
|
3252
|
+
}
|
|
3253
|
+
try {
|
|
3254
|
+
const config = await getConfig({
|
|
3255
|
+
cwd: projectRoot,
|
|
3256
|
+
configPath,
|
|
3257
|
+
shouldThrowOnError: false
|
|
3258
|
+
});
|
|
3259
|
+
const packageInfo = await getPackageInfo();
|
|
3260
|
+
return {
|
|
3261
|
+
version: packageInfo.version || "Unknown",
|
|
3262
|
+
config: sanitizeBetterAuthConfig(config)
|
|
3263
|
+
};
|
|
3264
|
+
} finally {
|
|
3265
|
+
if (suppressLogs) {
|
|
3266
|
+
console.log = originalLog;
|
|
3267
|
+
console.warn = originalWarn;
|
|
3268
|
+
console.error = originalError;
|
|
3269
|
+
}
|
|
3270
|
+
}
|
|
3271
|
+
} catch (error) {
|
|
3272
|
+
return {
|
|
3273
|
+
version: "Unknown",
|
|
3274
|
+
config: null,
|
|
3275
|
+
error: error instanceof Error ? error.message : "Failed to load Better Auth config"
|
|
3276
|
+
};
|
|
3277
|
+
}
|
|
3278
|
+
}
|
|
3279
|
+
function formatOutput(data, indent = 0) {
|
|
3280
|
+
const spaces = " ".repeat(indent);
|
|
3281
|
+
if (data === null || data === void 0) {
|
|
3282
|
+
return `${spaces}${chalk.gray("N/A")}`;
|
|
3283
|
+
}
|
|
3284
|
+
if (typeof data === "string" || typeof data === "number" || typeof data === "boolean") {
|
|
3285
|
+
return `${spaces}${data}`;
|
|
3286
|
+
}
|
|
3287
|
+
if (Array.isArray(data)) {
|
|
3288
|
+
if (data.length === 0) {
|
|
3289
|
+
return `${spaces}${chalk.gray("[]")}`;
|
|
3290
|
+
}
|
|
3291
|
+
return data.map((item) => formatOutput(item, indent)).join("\n");
|
|
3292
|
+
}
|
|
3293
|
+
if (typeof data === "object") {
|
|
3294
|
+
const entries = Object.entries(data);
|
|
3295
|
+
if (entries.length === 0) {
|
|
3296
|
+
return `${spaces}${chalk.gray("{}")}`;
|
|
3297
|
+
}
|
|
3298
|
+
return entries.map(([key, value]) => {
|
|
3299
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
3300
|
+
return `${spaces}${chalk.cyan(key)}:
|
|
3301
|
+
${formatOutput(value, indent + 2)}`;
|
|
3302
|
+
}
|
|
3303
|
+
return `${spaces}${chalk.cyan(key)}: ${formatOutput(value, 0)}`;
|
|
3304
|
+
}).join("\n");
|
|
3305
|
+
}
|
|
3306
|
+
return `${spaces}${JSON.stringify(data)}`;
|
|
3307
|
+
}
|
|
3308
|
+
const info = new Command("info").description("Display system and Better Auth configuration information").option("--cwd <cwd>", "The working directory", process.cwd()).option("--config <config>", "Path to the Better Auth configuration file").option("-j, --json", "Output as JSON").option("-c, --copy", "Copy output to clipboard (requires pbcopy/xclip)").action(async (options) => {
|
|
3309
|
+
const projectRoot = path.resolve(options.cwd || process.cwd());
|
|
3310
|
+
const systemInfo = getSystemInfo();
|
|
3311
|
+
const nodeInfo = getNodeInfo();
|
|
3312
|
+
const packageManager = getPackageManager();
|
|
3313
|
+
const frameworks = getFrameworkInfo(projectRoot);
|
|
3314
|
+
const databases = getDatabaseInfo(projectRoot);
|
|
3315
|
+
const betterAuthInfo = await getBetterAuthInfo(
|
|
3316
|
+
projectRoot,
|
|
3317
|
+
options.config,
|
|
3318
|
+
options.json
|
|
3319
|
+
);
|
|
3320
|
+
const fullInfo = {
|
|
3321
|
+
system: systemInfo,
|
|
3322
|
+
node: nodeInfo,
|
|
3323
|
+
packageManager,
|
|
3324
|
+
frameworks,
|
|
3325
|
+
databases,
|
|
3326
|
+
betterAuth: betterAuthInfo
|
|
3327
|
+
};
|
|
3328
|
+
if (options.json) {
|
|
3329
|
+
const jsonOutput = JSON.stringify(fullInfo, null, 2);
|
|
3330
|
+
console.log(jsonOutput);
|
|
3331
|
+
if (options.copy) {
|
|
3332
|
+
try {
|
|
3333
|
+
const platform = os.platform();
|
|
3334
|
+
if (platform === "darwin") {
|
|
3335
|
+
execSync("pbcopy", { input: jsonOutput });
|
|
3336
|
+
console.log(chalk.green("\n\u2713 Copied to clipboard"));
|
|
3337
|
+
} else if (platform === "linux") {
|
|
3338
|
+
execSync("xclip -selection clipboard", { input: jsonOutput });
|
|
3339
|
+
console.log(chalk.green("\n\u2713 Copied to clipboard"));
|
|
3340
|
+
} else if (platform === "win32") {
|
|
3341
|
+
execSync("clip", { input: jsonOutput });
|
|
3342
|
+
console.log(chalk.green("\n\u2713 Copied to clipboard"));
|
|
3343
|
+
}
|
|
3344
|
+
} catch {
|
|
3345
|
+
console.log(chalk.yellow("\n\u26A0 Could not copy to clipboard"));
|
|
3346
|
+
}
|
|
3347
|
+
}
|
|
3348
|
+
return;
|
|
3349
|
+
}
|
|
3350
|
+
console.log(chalk.bold("\n\u{1F4CA} Better Auth System Information\n"));
|
|
3351
|
+
console.log(chalk.gray("=".repeat(50)));
|
|
3352
|
+
console.log(chalk.bold.white("\n\u{1F5A5}\uFE0F System Information:"));
|
|
3353
|
+
console.log(formatOutput(systemInfo, 2));
|
|
3354
|
+
console.log(chalk.bold.white("\n\u{1F4E6} Node.js:"));
|
|
3355
|
+
console.log(formatOutput(nodeInfo, 2));
|
|
3356
|
+
console.log(chalk.bold.white("\n\u{1F4E6} Package Manager:"));
|
|
3357
|
+
console.log(formatOutput(packageManager, 2));
|
|
3358
|
+
if (frameworks) {
|
|
3359
|
+
console.log(chalk.bold.white("\n\u{1F680} Frameworks:"));
|
|
3360
|
+
console.log(formatOutput(frameworks, 2));
|
|
3361
|
+
}
|
|
3362
|
+
if (databases) {
|
|
3363
|
+
console.log(chalk.bold.white("\n\u{1F4BE} Database Clients:"));
|
|
3364
|
+
console.log(formatOutput(databases, 2));
|
|
3365
|
+
}
|
|
3366
|
+
console.log(chalk.bold.white("\n\u{1F510} Better Auth:"));
|
|
3367
|
+
if (betterAuthInfo.error) {
|
|
3368
|
+
console.log(` ${chalk.red("Error:")} ${betterAuthInfo.error}`);
|
|
3369
|
+
} else {
|
|
3370
|
+
console.log(` ${chalk.cyan("Version")}: ${betterAuthInfo.version}`);
|
|
3371
|
+
if (betterAuthInfo.config) {
|
|
3372
|
+
console.log(` ${chalk.cyan("Configuration")}:`);
|
|
3373
|
+
console.log(formatOutput(betterAuthInfo.config, 4));
|
|
3374
|
+
}
|
|
3375
|
+
}
|
|
3376
|
+
console.log(chalk.gray("\n" + "=".repeat(50)));
|
|
3377
|
+
console.log(chalk.gray("\n\u{1F4A1} Tip: Use --json flag for JSON output"));
|
|
3378
|
+
console.log(chalk.gray("\u{1F4A1} Use --copy flag to copy output to clipboard"));
|
|
3379
|
+
console.log(
|
|
3380
|
+
chalk.gray("\u{1F4A1} When reporting issues, include this information\n")
|
|
3381
|
+
);
|
|
3382
|
+
if (options.copy) {
|
|
3383
|
+
const textOutput = `
|
|
3384
|
+
Better Auth System Information
|
|
3385
|
+
==============================
|
|
3386
|
+
|
|
3387
|
+
System Information:
|
|
3388
|
+
${JSON.stringify(systemInfo, null, 2)}
|
|
3389
|
+
|
|
3390
|
+
Node.js:
|
|
3391
|
+
${JSON.stringify(nodeInfo, null, 2)}
|
|
3392
|
+
|
|
3393
|
+
Package Manager:
|
|
3394
|
+
${JSON.stringify(packageManager, null, 2)}
|
|
3395
|
+
|
|
3396
|
+
Frameworks:
|
|
3397
|
+
${JSON.stringify(frameworks, null, 2)}
|
|
3398
|
+
|
|
3399
|
+
Database Clients:
|
|
3400
|
+
${JSON.stringify(databases, null, 2)}
|
|
3401
|
+
|
|
3402
|
+
Better Auth:
|
|
3403
|
+
${JSON.stringify(betterAuthInfo, null, 2)}
|
|
3404
|
+
`;
|
|
3405
|
+
try {
|
|
3406
|
+
const platform = os.platform();
|
|
3407
|
+
if (platform === "darwin") {
|
|
3408
|
+
execSync("pbcopy", { input: textOutput });
|
|
3409
|
+
console.log(chalk.green("\u2713 Copied to clipboard"));
|
|
3410
|
+
} else if (platform === "linux") {
|
|
3411
|
+
execSync("xclip -selection clipboard", { input: textOutput });
|
|
3412
|
+
console.log(chalk.green("\u2713 Copied to clipboard"));
|
|
3413
|
+
} else if (platform === "win32") {
|
|
3414
|
+
execSync("clip", { input: textOutput });
|
|
3415
|
+
console.log(chalk.green("\u2713 Copied to clipboard"));
|
|
3416
|
+
}
|
|
3417
|
+
} catch {
|
|
3418
|
+
console.log(chalk.yellow("\u26A0 Could not copy to clipboard"));
|
|
3419
|
+
}
|
|
3420
|
+
}
|
|
3421
|
+
});
|
|
3422
|
+
|
|
3001
3423
|
process.on("SIGINT", () => process.exit(0));
|
|
3002
3424
|
process.on("SIGTERM", () => process.exit(0));
|
|
3003
3425
|
async function main() {
|
|
@@ -3007,7 +3429,7 @@ async function main() {
|
|
|
3007
3429
|
packageInfo = await getPackageInfo();
|
|
3008
3430
|
} catch (error) {
|
|
3009
3431
|
}
|
|
3010
|
-
program.addCommand(init).addCommand(migrate).addCommand(generate).addCommand(generateSecret).addCommand(login).version(packageInfo.version || "1.1.2").description("Better Auth CLI").action(() => program.help());
|
|
3432
|
+
program.addCommand(init).addCommand(migrate).addCommand(generate).addCommand(generateSecret).addCommand(info).addCommand(login).version(packageInfo.version || "1.1.2").description("Better Auth CLI").action(() => program.help());
|
|
3011
3433
|
program.parse();
|
|
3012
3434
|
}
|
|
3013
3435
|
main();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-auth/cli",
|
|
3
|
-
"version": "1.3.8-beta.
|
|
3
|
+
"version": "1.3.8-beta.5",
|
|
4
4
|
"description": "The CLI for Better Auth",
|
|
5
5
|
"module": "dist/index.mjs",
|
|
6
6
|
"repository": {
|
|
@@ -26,12 +26,9 @@
|
|
|
26
26
|
"exports": "./dist/index.mjs",
|
|
27
27
|
"bin": "./dist/index.mjs",
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@types/diff": "^7.0.1",
|
|
30
|
-
"@types/fs-extra": "^11.0.4",
|
|
31
29
|
"tsx": "^4.20.4",
|
|
32
30
|
"typescript": "^5.9.2",
|
|
33
|
-
"unbuild": "^3.5.0"
|
|
34
|
-
"zod": "^4.0.0"
|
|
31
|
+
"unbuild": "^3.5.0"
|
|
35
32
|
},
|
|
36
33
|
"dependencies": {
|
|
37
34
|
"@babel/core": "^7.0.0",
|
|
@@ -48,7 +45,6 @@
|
|
|
48
45
|
"commander": "^12.1.0",
|
|
49
46
|
"dotenv": "^16.4.7",
|
|
50
47
|
"drizzle-orm": "^0.33.0",
|
|
51
|
-
"fs-extra": "^11.3.0",
|
|
52
48
|
"get-tsconfig": "^4.8.1",
|
|
53
49
|
"open": "^10.1.0",
|
|
54
50
|
"prettier": "^3.4.2",
|
|
@@ -57,10 +53,8 @@
|
|
|
57
53
|
"semver": "^7.7.1",
|
|
58
54
|
"tinyexec": "^0.3.1",
|
|
59
55
|
"yocto-spinner": "^0.1.1",
|
|
60
|
-
"
|
|
61
|
-
|
|
62
|
-
"peerDependencies": {
|
|
63
|
-
"zod": "3.25.0 || ^4.0.0"
|
|
56
|
+
"zod": "^4.0.0",
|
|
57
|
+
"better-auth": "1.3.8-beta.5"
|
|
64
58
|
},
|
|
65
59
|
"files": [
|
|
66
60
|
"dist"
|