@rebasepro/cli 0.1.2 → 0.2.3
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/LICENSE +17 -196
- package/dist/commands/init.d.ts +1 -1
- package/dist/index.cjs +194 -49
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +179 -33
- package/dist/index.es.js.map +1 -1
- package/package.json +18 -11
- package/templates/template/.cursorrules +2 -0
- package/templates/template/.env.example +8 -1
- package/templates/template/.github/copilot-instructions.md +2 -0
- package/templates/template/.windsurfrules +2 -0
- package/templates/template/README.md +3 -3
- package/templates/template/ai-instructions.md +14 -0
- package/templates/template/backend/Dockerfile +1 -1
- package/templates/template/backend/drizzle.config.ts +11 -5
- package/templates/template/backend/package.json +4 -3
- package/templates/template/backend/src/env.ts +2 -43
- package/templates/template/backend/src/index.ts +10 -12
- package/templates/template/config/collections/index.ts +6 -4
- package/templates/template/config/collections/posts.ts +6 -26
- package/templates/template/config/collections/roles.ts +72 -0
- package/templates/template/config/collections/users.ts +141 -0
- package/templates/template/config/index.ts +1 -1
- package/templates/template/config/package.json +2 -1
- package/templates/template/docker-compose.yml +3 -3
- package/templates/template/frontend/package.json +3 -1
- package/templates/template/frontend/src/App.tsx +3 -3
- package/templates/template/frontend/src/virtual.d.ts +6 -0
- package/templates/template/frontend/tsconfig.json +3 -2
- package/templates/template/frontend/vite.config.ts +1 -1
- package/templates/template/pnpm-workspace.yaml +7 -0
package/dist/index.es.js
CHANGED
|
@@ -3,9 +3,10 @@ import arg from "arg";
|
|
|
3
3
|
import inquirer from "inquirer";
|
|
4
4
|
import path from "path";
|
|
5
5
|
import fs from "fs";
|
|
6
|
+
import net from "net";
|
|
6
7
|
import { promisify } from "util";
|
|
7
|
-
import execa from "execa";
|
|
8
|
-
import
|
|
8
|
+
import { execa, execaCommandSync } from "execa";
|
|
9
|
+
import { cp } from "fs/promises";
|
|
9
10
|
import { fileURLToPath } from "url";
|
|
10
11
|
import crypto from "crypto";
|
|
11
12
|
import { generateSDK } from "@rebasepro/sdk-generator";
|
|
@@ -51,7 +52,6 @@ function getPMCommands(pm) {
|
|
|
51
52
|
};
|
|
52
53
|
}
|
|
53
54
|
const access = promisify(fs.access);
|
|
54
|
-
const copy = promisify(ncp);
|
|
55
55
|
const __filename$2 = fileURLToPath(import.meta.url);
|
|
56
56
|
const __dirname$2 = path.dirname(__filename$2);
|
|
57
57
|
function findParentDir(currentDir, targetName) {
|
|
@@ -78,8 +78,12 @@ async function promptForOptions(rawArgs, pm) {
|
|
|
78
78
|
{
|
|
79
79
|
"--git": Boolean,
|
|
80
80
|
"--install": Boolean,
|
|
81
|
+
"--database-url": String,
|
|
82
|
+
"--introspect": Boolean,
|
|
83
|
+
"--yes": Boolean,
|
|
81
84
|
"-g": "--git",
|
|
82
|
-
"-i": "--install"
|
|
85
|
+
"-i": "--install",
|
|
86
|
+
"-y": "--yes"
|
|
83
87
|
},
|
|
84
88
|
{
|
|
85
89
|
argv: rawArgs.slice(3),
|
|
@@ -88,6 +92,24 @@ async function promptForOptions(rawArgs, pm) {
|
|
|
88
92
|
}
|
|
89
93
|
);
|
|
90
94
|
const nameArg = args._[0];
|
|
95
|
+
const isNonInteractive = args["--yes"] || false;
|
|
96
|
+
if (isNonInteractive) {
|
|
97
|
+
const projectName2 = nameArg || "my-rebase-app";
|
|
98
|
+
const targetDirectory2 = path.resolve(process.cwd(), projectName2);
|
|
99
|
+
const templateDirectory2 = path.resolve(cliRoot, "templates", "template");
|
|
100
|
+
const pmCommands2 = getPMCommands(pm);
|
|
101
|
+
return {
|
|
102
|
+
projectName: path.basename(targetDirectory2),
|
|
103
|
+
git: args["--git"] ?? false,
|
|
104
|
+
installDeps: args["--install"] ?? false,
|
|
105
|
+
targetDirectory: targetDirectory2,
|
|
106
|
+
templateDirectory: templateDirectory2,
|
|
107
|
+
databaseUrl: args["--database-url"] || void 0,
|
|
108
|
+
introspect: args["--introspect"] || false,
|
|
109
|
+
pm,
|
|
110
|
+
pmCommands: pmCommands2
|
|
111
|
+
};
|
|
112
|
+
}
|
|
91
113
|
const questions = [];
|
|
92
114
|
if (!nameArg) {
|
|
93
115
|
questions.push({
|
|
@@ -167,9 +189,8 @@ async function createProject(options) {
|
|
|
167
189
|
}
|
|
168
190
|
console.log(chalk.gray(" Copying project files..."));
|
|
169
191
|
try {
|
|
170
|
-
await
|
|
171
|
-
|
|
172
|
-
dot: true,
|
|
192
|
+
await cp(options.templateDirectory, options.targetDirectory, {
|
|
193
|
+
recursive: true,
|
|
173
194
|
filter: (source) => {
|
|
174
195
|
const basename = path.basename(source);
|
|
175
196
|
return basename !== "node_modules" && basename !== ".DS_Store";
|
|
@@ -180,7 +201,7 @@ async function createProject(options) {
|
|
|
180
201
|
process.exit(1);
|
|
181
202
|
}
|
|
182
203
|
await replacePlaceholders(options);
|
|
183
|
-
configureEnvFile(options.targetDirectory, options.databaseUrl);
|
|
204
|
+
await configureEnvFile(options.targetDirectory, options.databaseUrl);
|
|
184
205
|
if (options.git) {
|
|
185
206
|
console.log(chalk.gray(" Initializing git repository..."));
|
|
186
207
|
try {
|
|
@@ -240,8 +261,8 @@ async function createProject(options) {
|
|
|
240
261
|
console.log(chalk.gray(" # Your database is configured! Start the dev server:"));
|
|
241
262
|
} else {
|
|
242
263
|
console.log(chalk.gray(" # A local database configuration has been generated in .env."));
|
|
243
|
-
console.log(chalk.gray(" # If using the included docker-compose.yml, start
|
|
244
|
-
console.log(` ${chalk.cyan("docker compose up -d")}`);
|
|
264
|
+
console.log(chalk.gray(" # If using the included docker-compose.yml, start the database with:"));
|
|
265
|
+
console.log(` ${chalk.cyan("docker compose up -d db")}`);
|
|
245
266
|
console.log("");
|
|
246
267
|
console.log(chalk.gray(" # Then start the dev server:"));
|
|
247
268
|
}
|
|
@@ -261,6 +282,7 @@ async function replacePlaceholders(options) {
|
|
|
261
282
|
"backend/package.json",
|
|
262
283
|
"config/package.json",
|
|
263
284
|
"frontend/index.html",
|
|
285
|
+
"pnpm-workspace.yaml",
|
|
264
286
|
"README.md"
|
|
265
287
|
];
|
|
266
288
|
const packageJsonPath = path.resolve(cliRoot, "package.json");
|
|
@@ -273,6 +295,10 @@ async function replacePlaceholders(options) {
|
|
|
273
295
|
const viewBin = "npm";
|
|
274
296
|
const getPackageVersion = async (pkgName) => {
|
|
275
297
|
if (versionCache.has(pkgName)) return versionCache.get(pkgName);
|
|
298
|
+
if (process.env.REBASE_E2E === "true") {
|
|
299
|
+
versionCache.set(pkgName, cliVersion);
|
|
300
|
+
return cliVersion;
|
|
301
|
+
}
|
|
276
302
|
let versionToUse = cliVersion;
|
|
277
303
|
try {
|
|
278
304
|
const { stdout } = await execa(viewBin, ["view", `${pkgName}@${cliVersion}`, "version"]);
|
|
@@ -321,7 +347,26 @@ async function replacePlaceholders(options) {
|
|
|
321
347
|
fs.writeFileSync(fullPath, content, "utf-8");
|
|
322
348
|
}
|
|
323
349
|
}
|
|
324
|
-
function
|
|
350
|
+
async function isPortAvailable(port) {
|
|
351
|
+
return new Promise((resolve) => {
|
|
352
|
+
const server = net.createServer();
|
|
353
|
+
server.once("error", () => {
|
|
354
|
+
resolve(false);
|
|
355
|
+
});
|
|
356
|
+
server.once("listening", () => {
|
|
357
|
+
server.close(() => resolve(true));
|
|
358
|
+
});
|
|
359
|
+
server.listen(port);
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
async function findAvailablePort(startPort) {
|
|
363
|
+
let port = startPort;
|
|
364
|
+
while (!await isPortAvailable(port)) {
|
|
365
|
+
port++;
|
|
366
|
+
}
|
|
367
|
+
return port;
|
|
368
|
+
}
|
|
369
|
+
async function configureEnvFile(targetDirectory, databaseUrl) {
|
|
325
370
|
const envExamplePath = path.join(targetDirectory, ".env.example");
|
|
326
371
|
const envPath = path.join(targetDirectory, ".env");
|
|
327
372
|
if (fs.existsSync(envExamplePath) && !fs.existsSync(envPath)) {
|
|
@@ -339,10 +384,21 @@ function configureEnvFile(targetDirectory, databaseUrl) {
|
|
|
339
384
|
`DATABASE_URL=${databaseUrl}`
|
|
340
385
|
);
|
|
341
386
|
} else {
|
|
387
|
+
const dbPort = await findAvailablePort(5432);
|
|
342
388
|
envContent = envContent.replace(
|
|
343
389
|
/^DATABASE_URL=.*$/m,
|
|
344
|
-
`DATABASE_URL=postgresql://rebase:${dbPassword}@localhost
|
|
390
|
+
`DATABASE_URL=postgresql://rebase:${dbPassword}@localhost:${dbPort}/rebase?options=-c%20search_path=public
|
|
391
|
+
DATABASE_PASSWORD=${dbPassword}`
|
|
345
392
|
);
|
|
393
|
+
const dockerComposePath = path.join(targetDirectory, "docker-compose.yml");
|
|
394
|
+
if (fs.existsSync(dockerComposePath)) {
|
|
395
|
+
let dockerComposeContent = fs.readFileSync(dockerComposePath, "utf-8");
|
|
396
|
+
dockerComposeContent = dockerComposeContent.replace(
|
|
397
|
+
/-\s*"5432:5432"/g,
|
|
398
|
+
`- "${dbPort}:5432"`
|
|
399
|
+
);
|
|
400
|
+
fs.writeFileSync(dockerComposePath, dockerComposeContent, "utf-8");
|
|
401
|
+
}
|
|
346
402
|
}
|
|
347
403
|
fs.writeFileSync(envPath, envContent, "utf-8");
|
|
348
404
|
}
|
|
@@ -440,6 +496,7 @@ async function generateSdkCommand(args) {
|
|
|
440
496
|
console.log("");
|
|
441
497
|
console.log(chalk.cyan(" → Loading collection definitions..."));
|
|
442
498
|
const collections = await loadCollections(resolvedCollectionsDir);
|
|
499
|
+
collections.sort((a, b) => a.slug.localeCompare(b.slug));
|
|
443
500
|
if (collections.length === 0) {
|
|
444
501
|
console.log(chalk.red(" ✗ No collections found. Nothing to generate."));
|
|
445
502
|
process.exit(1);
|
|
@@ -499,15 +556,20 @@ function getActiveBackendPlugin(backendDir) {
|
|
|
499
556
|
if (!fs.existsSync(pkgPath)) return null;
|
|
500
557
|
try {
|
|
501
558
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
502
|
-
const deps = {
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
559
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
560
|
+
const candidates = Object.keys(deps).filter(
|
|
561
|
+
(dep) => dep.startsWith("@rebasepro/server-") && dep !== "@rebasepro/server-core"
|
|
562
|
+
);
|
|
563
|
+
if (candidates.length === 0) return null;
|
|
564
|
+
if (candidates.includes("@rebasepro/server-postgresql")) {
|
|
565
|
+
return "@rebasepro/server-postgresql";
|
|
566
|
+
}
|
|
567
|
+
for (const candidate of candidates) {
|
|
568
|
+
if (resolvePluginCliScript(backendDir, candidate)) {
|
|
569
|
+
return candidate;
|
|
509
570
|
}
|
|
510
571
|
}
|
|
572
|
+
return candidates[0];
|
|
511
573
|
} catch {
|
|
512
574
|
}
|
|
513
575
|
return null;
|
|
@@ -569,7 +631,7 @@ function requireProjectRoot() {
|
|
|
569
631
|
if (!root) {
|
|
570
632
|
console.error(chalk.red("✗ Could not find a Rebase project root."));
|
|
571
633
|
console.error(chalk.gray(" Make sure you are inside a Rebase project directory"));
|
|
572
|
-
console.error(chalk.gray(" (one with backend/, frontend/, and
|
|
634
|
+
console.error(chalk.gray(" (one with backend/, frontend/, and config/ directories)."));
|
|
573
635
|
process.exit(1);
|
|
574
636
|
}
|
|
575
637
|
return root;
|
|
@@ -752,10 +814,12 @@ async function devCommand(rawArgs) {
|
|
|
752
814
|
"--backend-only": Boolean,
|
|
753
815
|
"--frontend-only": Boolean,
|
|
754
816
|
"--port": Number,
|
|
817
|
+
"--generate": Boolean,
|
|
755
818
|
"--help": Boolean,
|
|
756
819
|
"-b": "--backend-only",
|
|
757
820
|
"-f": "--frontend-only",
|
|
758
821
|
"-p": "--port",
|
|
822
|
+
"-g": "--generate",
|
|
759
823
|
"-h": "--help"
|
|
760
824
|
},
|
|
761
825
|
{
|
|
@@ -773,6 +837,7 @@ async function devCommand(rawArgs) {
|
|
|
773
837
|
const frontendDir = findFrontendDir(projectRoot);
|
|
774
838
|
const backendOnly = args["--backend-only"] || false;
|
|
775
839
|
const frontendOnly = args["--frontend-only"] || false;
|
|
840
|
+
const shouldGenerate = args["--generate"] || process.env.REBASE_AUTO_GENERATE === "true" || process.env.REBASE_GENERATE === "true";
|
|
776
841
|
const startPort = resolveStartPort(projectRoot, args["--port"]);
|
|
777
842
|
console.log("");
|
|
778
843
|
console.log(chalk.bold(" 🚀 Rebase Dev Server"));
|
|
@@ -792,10 +857,10 @@ async function devCommand(rawArgs) {
|
|
|
792
857
|
console.log("");
|
|
793
858
|
console.log(chalk.cyan("┌────────────────────────────────────────────────────────────┐"));
|
|
794
859
|
console.log(chalk.cyan("│ │"));
|
|
795
|
-
console.log(chalk.cyan("│
|
|
860
|
+
console.log(chalk.cyan("│ ✦ Rebase Admin App is ready! │"));
|
|
796
861
|
const cleanUrl = stripAnsi(frontendUrl);
|
|
797
|
-
const paddedUrl = cleanUrl.padEnd(
|
|
798
|
-
console.log(chalk.cyan("│
|
|
862
|
+
const paddedUrl = cleanUrl.padEnd(41);
|
|
863
|
+
console.log(chalk.cyan("│ ➜ Frontend URL: ") + chalk.white(paddedUrl) + chalk.cyan("│"));
|
|
799
864
|
console.log(chalk.cyan("│ │"));
|
|
800
865
|
console.log(chalk.cyan("└────────────────────────────────────────────────────────────┘"));
|
|
801
866
|
console.log("");
|
|
@@ -814,7 +879,7 @@ async function devCommand(rawArgs) {
|
|
|
814
879
|
if (child.pid && !child.killed) {
|
|
815
880
|
try {
|
|
816
881
|
if (process.platform === "win32") {
|
|
817
|
-
|
|
882
|
+
execaCommandSync(`taskkill /pid ${child.pid} /T /F`);
|
|
818
883
|
} else {
|
|
819
884
|
process.kill(-child.pid, "SIGKILL");
|
|
820
885
|
}
|
|
@@ -892,9 +957,67 @@ async function devCommand(rawArgs) {
|
|
|
892
957
|
console.log(` ${chalk.cyan("▶")} Backend: ${chalk.gray(backendDir)}`);
|
|
893
958
|
console.log(` ${chalk.gray("↳ PORT")} = ${chalk.white(String(startPort))}`);
|
|
894
959
|
let frontendLaunched = false;
|
|
960
|
+
if (shouldGenerate) {
|
|
961
|
+
console.log(chalk.gray(" → Ensuring schema and SDK are generated on start..."));
|
|
962
|
+
try {
|
|
963
|
+
const activePlugin = getActiveBackendPlugin(backendDir);
|
|
964
|
+
const pluginCli = activePlugin ? resolvePluginCliScript(backendDir, activePlugin) : null;
|
|
965
|
+
if (pluginCli) {
|
|
966
|
+
await execa(tsxBin, [pluginCli, "schema", "generate"], {
|
|
967
|
+
cwd: backendDir,
|
|
968
|
+
stdio: "inherit",
|
|
969
|
+
env
|
|
970
|
+
});
|
|
971
|
+
}
|
|
972
|
+
await execa("npx", ["rebase", "generate-sdk"], {
|
|
973
|
+
cwd: projectRoot,
|
|
974
|
+
stdio: "inherit",
|
|
975
|
+
env
|
|
976
|
+
});
|
|
977
|
+
console.log(chalk.green(" ✓ Initial schema and SDK generated successfully.\n"));
|
|
978
|
+
} catch (err) {
|
|
979
|
+
console.error(chalk.red(` ✗ Initial schema/SDK generation failed: ${err.message || err}
|
|
980
|
+
`));
|
|
981
|
+
}
|
|
982
|
+
const collectionsDir = path.join(projectRoot, "config", "collections");
|
|
983
|
+
if (fs.existsSync(collectionsDir)) {
|
|
984
|
+
let watchDebounce = null;
|
|
985
|
+
fs.watch(collectionsDir, { recursive: true }, (eventType, filename) => {
|
|
986
|
+
if (!filename || filename.startsWith(".") || filename.endsWith(".tmp")) return;
|
|
987
|
+
if (watchDebounce) clearTimeout(watchDebounce);
|
|
988
|
+
watchDebounce = setTimeout(async () => {
|
|
989
|
+
console.log(chalk.yellow(`
|
|
990
|
+
🔄 Collection change detected (${filename}). Regenerating schema & SDK...`));
|
|
991
|
+
try {
|
|
992
|
+
const activePlugin = getActiveBackendPlugin(backendDir);
|
|
993
|
+
const pluginCli = activePlugin ? resolvePluginCliScript(backendDir, activePlugin) : null;
|
|
994
|
+
if (pluginCli) {
|
|
995
|
+
await execa(tsxBin, [pluginCli, "schema", "generate"], {
|
|
996
|
+
cwd: backendDir,
|
|
997
|
+
stdio: "inherit",
|
|
998
|
+
env
|
|
999
|
+
});
|
|
1000
|
+
}
|
|
1001
|
+
await execa("npx", ["rebase", "generate-sdk"], {
|
|
1002
|
+
cwd: projectRoot,
|
|
1003
|
+
stdio: "inherit",
|
|
1004
|
+
env
|
|
1005
|
+
});
|
|
1006
|
+
console.log(chalk.green(" ✓ Schema & SDK regenerated successfully. Hono will reload."));
|
|
1007
|
+
} catch (err) {
|
|
1008
|
+
console.error(chalk.red(` ✗ Failed to regenerate schema/SDK: ${err.message || err}`));
|
|
1009
|
+
}
|
|
1010
|
+
}, 300);
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
const watchArgs = ["watch", "--conditions", "development", "src/index.ts"];
|
|
1015
|
+
if (!shouldGenerate) {
|
|
1016
|
+
watchArgs.splice(1, 0, `--watch="${path.join("..", "config", "**", "*")}"`);
|
|
1017
|
+
}
|
|
895
1018
|
const backendChild = execa(
|
|
896
1019
|
tsxBin,
|
|
897
|
-
|
|
1020
|
+
watchArgs,
|
|
898
1021
|
{
|
|
899
1022
|
cwd: backendDir,
|
|
900
1023
|
stdio: ["inherit", "pipe", "pipe"],
|
|
@@ -967,6 +1090,7 @@ ${chalk.green.bold("Options")}
|
|
|
967
1090
|
${chalk.blue("--backend-only, -b")} Only start the backend server
|
|
968
1091
|
${chalk.blue("--frontend-only, -f")} Only start the frontend server
|
|
969
1092
|
${chalk.blue("--port, -p")} Backend port (default: auto-detected per project)
|
|
1093
|
+
${chalk.blue("--generate, -g")} Enable automatic schema and SDK generation on startup and file changes
|
|
970
1094
|
|
|
971
1095
|
${chalk.green.bold("Description")}
|
|
972
1096
|
Starts both the backend (tsx watch + Hono) and frontend (Vite)
|
|
@@ -979,6 +1103,10 @@ ${chalk.green.bold("Description")}
|
|
|
979
1103
|
If the assigned port is already in use, the server will automatically
|
|
980
1104
|
try the next available port. The frontend is started only after the
|
|
981
1105
|
backend is ready, and VITE_API_URL is injected automatically.
|
|
1106
|
+
|
|
1107
|
+
By default, automatic schema and SDK generation is disabled on startup
|
|
1108
|
+
and file changes. Pass --generate (-g) or set REBASE_AUTO_GENERATE=true
|
|
1109
|
+
in your environment to enable it.
|
|
982
1110
|
`);
|
|
983
1111
|
}
|
|
984
1112
|
async function buildCommand() {
|
|
@@ -1073,12 +1201,12 @@ async function resetPassword(rawArgs) {
|
|
|
1073
1201
|
env.DOTENV_CONFIG_PATH = envFile;
|
|
1074
1202
|
}
|
|
1075
1203
|
const scriptContent = `
|
|
1076
|
-
import { createPostgresDatabaseConnection } from "@rebasepro/server-
|
|
1077
|
-
import { hashPassword } from "@rebasepro/server-core
|
|
1204
|
+
import { createPostgresDatabaseConnection } from "@rebasepro/server-postgresql";
|
|
1205
|
+
import { hashPassword } from "@rebasepro/server-core";
|
|
1078
1206
|
import { eq } from "drizzle-orm";
|
|
1079
|
-
import { users } from "@rebasepro/server-core/src/db/auth-schema";
|
|
1080
1207
|
import * as dotenv from "dotenv";
|
|
1081
1208
|
import path from "path";
|
|
1209
|
+
import fs from "fs";
|
|
1082
1210
|
|
|
1083
1211
|
dotenv.config({ path: "${envFile || path.join(projectRoot, ".env")}" });
|
|
1084
1212
|
|
|
@@ -1089,12 +1217,30 @@ async function resetPassword() {
|
|
|
1089
1217
|
const { db } = createPostgresDatabaseConnection(process.env.DATABASE_URL!);
|
|
1090
1218
|
const hash = await hashPassword(newPassword);
|
|
1091
1219
|
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
.
|
|
1220
|
+
let usersTable;
|
|
1221
|
+
try {
|
|
1222
|
+
const schemaPath = path.resolve("./src/schema.generated.ts");
|
|
1223
|
+
if (fs.existsSync(schemaPath)) {
|
|
1224
|
+
const schema = await import("file://" + schemaPath);
|
|
1225
|
+
usersTable = schema.users || schema.tables?.users;
|
|
1226
|
+
}
|
|
1227
|
+
} catch (e) {
|
|
1228
|
+
// ignore and fallback
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
if (!usersTable) {
|
|
1232
|
+
const pgServer = await import("@rebasepro/server-postgresql");
|
|
1233
|
+
usersTable = pgServer.users;
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
const passwordHashKey = (usersTable.passwordHash || "passwordHash" in usersTable) ? "passwordHash" : "password_hash";
|
|
1237
|
+
|
|
1238
|
+
const result = await db.update(usersTable)
|
|
1239
|
+
.set({ [passwordHashKey]: hash })
|
|
1240
|
+
.where(eq(usersTable.email, email))
|
|
1095
1241
|
.returning({
|
|
1096
|
-
id:
|
|
1097
|
-
email:
|
|
1242
|
+
id: usersTable.id,
|
|
1243
|
+
email: usersTable.email
|
|
1098
1244
|
});
|
|
1099
1245
|
|
|
1100
1246
|
if (result.length > 0) {
|