import { Database } from "sqlite-async"; import { hashSync } from "bcryptjs"; import { faker } from "@faker-js/faker"; import { range } from "./util"; const createTable = async ( db: Database, name: string, schema: string, ): Promise => { await db.run(`DROP TABLE IF EXISTS ${name}`); await db.run(`CREATE TABLE IF NOT EXISTS ${name} (${schema})`); }; export const testUser = { username: "test@test.test", password: "password@123", fullname: "Test User", }; export const seed = async (db: Database): Promise => { await createTable( db, "users", ` id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT UNIQUE, password TEXT, fullname TEXT, created DATETIME DEFAULT CURRENT_TIMESTAMP `, ); await createTable( db, "accounts", ` id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER, name TEXT, iban TEXT UNIQUE `, ); await createTable( db, "cards", ` id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER, number TEXT, expiry TEXT, cvv TEXT `, ); await createTable( db, "transactions", ` id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER, account_id INTEGER, amount REAL, type TEXT, description TEXT, date datetime `, ); const hash = hashSync(testUser.password, 10); const { lastID: userId } = await db.run( "INSERT INTO users (username, password, fullname) VALUES (?, ?, ?);", [testUser.username, hash, testUser.fullname], ); // Seed accounts const accounts = range(5) .map( () => `(${userId}, '${faker.finance.accountName()} ', '${faker.finance.iban()}')`, ) .join(", "); await db.run(`INSERT INTO accounts (user_id, name, iban) VALUES ${accounts}`); // Seed cards const cards = range(5).map(() => [ userId, faker.finance.creditCardNumber(), faker.date.future().toISOString().slice(0, 7).replace("-", "/"), faker.finance.creditCardCVV(), ]); await db.run( `INSERT INTO cards (user_id, number, expiry, cvv) VALUES ${cards .map(() => "(?, ?, ?, ?)") .join(", ")}`, cards.flat(), ); const accountIds = ( await db.all<{ id: number }>("SELECT id FROM accounts WHERE user_id = ?", [ userId, ]) ).map(({ id }) => id); await Promise.all( accountIds.map(async (accountId) => { const transactions = range(1000).map(() => [ userId, accountId, faker.finance.amount({ min: -1500, max: 2500, dec: 2 }), faker.finance.transactionType(), faker.commerce.productName(), faker.date.recent({ days: 30 }).toISOString(), ]); // Seed transactions db.run( `INSERT INTO transactions (user_id, account_id, amount, type, description, date) VALUES ${transactions .map(() => "(?, ?, ?, ?, ?, ?)") .join(", ")}`, transactions.flat(), ); }), ); };