Files
Emberfall/scripts/seed-dev.js
T
2026-10-21 10:01:35 +11:00

141 lines
4.6 KiB
JavaScript

#!/usr/bin/env node
// seed-dev.js — Create a demo account + hero for local testing.
// Safe to re-run (skips if demo user already exists).
// Skipped entirely when NODE_ENV=production.
// NOTE: NODE_ENV check must happen before any require() that loads config,
// because config throws on placeholder SESSION_SECRET in production.
if (process.env.NODE_ENV === 'production') {
console.log('seed-dev: NODE_ENV=production — skipping.');
process.exit(0);
}
const bcrypt = require('bcryptjs');
const { runMigrations } = require('./migrate');
const { getDb } = require('../src/db');
const time = require('../src/utils/time');
const DEMO_USERNAME = 'demo';
const DEMO_PASSWORD = 'demo123';
const DEMO_HERO_NAME = 'Aldric';
const DEMO_CLASS = 'warrior';
// Starter gear: a basic weapon + armor + potion for the demo hero.
const STARTER_ITEMS = [
{ slug: 'rusty-sword', qty: 1 }, // weapon, common, min_level 1
{ slug: 'leather-jerkin', qty: 1 }, // armor, common, min_level 1
{ slug: 'minor-healing-potion', qty: 2 }, // consumable, stackable
];
function getOrCreateDemoUser(db) {
const stmt = db.prepare(
'SELECT id, username FROM users WHERE username = ? COLLATE NOCASE'
);
const existing = stmt.get(DEMO_USERNAME);
if (existing) {
console.log(` Demo user "${DEMO_USERNAME}" already exists (id=${existing.id}).`);
return existing;
}
const passwordHash = bcrypt.hashSync(DEMO_PASSWORD, 12);
const result = db.prepare(
'INSERT INTO users (username, password_hash, created_at) VALUES (?, ?, ?)'
).run(DEMO_USERNAME, passwordHash, time.now());
console.log(` Created demo user "${DEMO_USERNAME}" (id=${result.lastInsertRowid}).`);
return { id: result.lastInsertRowid, username: DEMO_USERNAME };
}
function getOrCreateDemoHero(db, userId) {
const heroCheck = db.prepare(
'SELECT id FROM characters WHERE user_id = ?'
).get(userId);
if (heroCheck) {
console.log(` Demo hero already exists for user ${userId}.`);
return null;
}
const heroNameCheck = db.prepare(
'SELECT id FROM characters WHERE name = ? COLLATE NOCASE'
).get(DEMO_HERO_NAME);
if (heroNameCheck) {
console.log(` Hero name "${DEMO_HERO_NAME}" already taken.`);
return null;
}
// Get base stats for the class
const { getBaseStats } = require('../src/game/classes');
const { calcDerived } = require('../src/game/stats');
const baseStats = getBaseStats(DEMO_CLASS);
const hpCurrent = calcDerived(baseStats, 1, DEMO_CLASS).maxHp;
const { ENERGY_MAX } = require('../src/game/stats');
const now = time.now();
const result = db.prepare(
`INSERT INTO characters
(user_id, name, class, level, xp, gold, str, agi, int, vit,
unspent_points, hp_current, energy, energy_updated_at, kills, deaths, created_at)
VALUES (?, ?, ?, 1, 0, 100, ?, ?, ?, ?, 0, ?, ?, ?, 0, 0, ?)`
).run(
userId, DEMO_HERO_NAME,
DEMO_CLASS,
baseStats.str, baseStats.agi, baseStats.int, baseStats.vit,
hpCurrent, ENERGY_MAX, now, now
);
console.log(` Created demo hero "${DEMO_HERO_NAME}" (id=${result.lastInsertRowid}, class=${DEMO_CLASS}).`);
return { id: result.lastInsertRowid };
}
function giveStarterGear(db, characterId) {
const itemIds = [];
for (const { slug, qty } of STARTER_ITEMS) {
const item = db.prepare('SELECT id FROM items WHERE slug = ?').get(slug);
if (!item) {
console.warn(` WARNING: item "${slug}" not found in database.`);
continue;
}
itemIds.push({ itemId: item.id, qty });
}
const insertInv = db.prepare(
'INSERT INTO inventory (character_id, item_id, quantity, acquired_at) VALUES (?, ?, ?, ?)'
);
for (const { itemId, qty } of itemIds) {
insertInv.run(characterId, itemId, qty, time.now());
}
console.log(` Granted ${itemIds.length} starter item(s) to hero ${characterId}.`);
}
function seedDev() {
console.log('seed-dev: running migrations...');
runMigrations();
const db = getDb();
console.log('seed-dev: seeding demo account...');
const user = getOrCreateDemoUser(db);
const hero = getOrCreateDemoHero(db, user.id);
if (hero) {
giveStarterGear(db, hero.id);
}
console.log('');
console.log('═══════════════════════════════════════');
console.log(' Demo account ready!');
console.log(` Username: ${DEMO_USERNAME}`);
console.log(` Password: ${DEMO_PASSWORD}`);
console.log('═══════════════════════════════════════');
console.log('');
}
// Run if called directly
if (require.main === module) {
seedDev();
process.exit(0);
}
module.exports = { seedDev };