Add plain-JS create-user script for production
Deploy / deploy (push) Successful in 3m28s

ts-node is a devDependency and isn't available after a production
install; scripts/create-user.js only needs packages already in
dependencies so it runs on the deployed server.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
twotalesanimation
2026-08-18 15:40:16 +02:00
parent 9dcf310806
commit 3d0a6acaf1
2 changed files with 68 additions and 0 deletions
+1
View File
@@ -11,6 +11,7 @@
"db:migrate": "prisma migrate dev", "db:migrate": "prisma migrate dev",
"db:seed": "ts-node -P tsconfig.seed.json prisma/seed.ts", "db:seed": "ts-node -P tsconfig.seed.json prisma/seed.ts",
"db:create-user": "ts-node -P tsconfig.seed.json scripts/create-user.ts", "db:create-user": "ts-node -P tsconfig.seed.json scripts/create-user.ts",
"db:create-user:prod": "node scripts/create-user.js",
"db:studio": "prisma studio" "db:studio": "prisma studio"
}, },
"prisma": { "prisma": {
+67
View File
@@ -0,0 +1,67 @@
const fs = require("fs");
const path = require("path");
// Minimal .env loader (avoids depending on the `dotenv` package, which may
// not be installed in a production deployment that skipped devDependencies).
function loadEnvFile(file) {
if (!fs.existsSync(file)) return;
for (const line of fs.readFileSync(file, "utf8").split("\n")) {
const match = line.match(/^\s*([\w.-]+)\s*=\s*(.*)?\s*$/);
if (!match) continue;
const key = match[1];
let value = (match[2] ?? "").trim();
if (value.startsWith('"') && value.endsWith('"')) value = value.slice(1, -1);
else if (value.startsWith("'") && value.endsWith("'")) value = value.slice(1, -1);
if (!(key in process.env)) process.env[key] = value;
}
}
loadEnvFile(path.join(__dirname, "..", ".env"));
const { PrismaClient } = require("@prisma/client");
const { PrismaPg } = require("@prisma/adapter-pg");
const bcrypt = require("bcryptjs");
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL });
const prisma = new PrismaClient({ adapter });
async function main() {
const [, , email, password, name] = process.argv;
if (!email || !password) {
console.error("Usage: node scripts/create-user.js <email> <password> [name]");
process.exit(1);
}
if (password.length < 8) {
console.error("Password must be at least 8 characters long.");
process.exit(1);
}
const hashedPassword = await bcrypt.hash(password, 12);
const normalizedEmail = email.toLowerCase().trim();
const user = await prisma.user.upsert({
where: { email: normalizedEmail },
create: {
email: normalizedEmail,
password: hashedPassword,
name: name ?? null,
role: "ADMIN",
},
update: {
password: hashedPassword,
...(name ? { name } : {}),
},
});
console.log(`✅ User ready: ${user.email} (role: ${user.role})`);
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});