import { Injectable } from "@nestjs/common"; import { hash } from "bcrypt"; import { Metadata, Permission, Role, User } from "src/entities"; import { PermissionAction } from "src/enums/permissions.enum"; import { TablesNames } from "src/enums/tables.enum"; import { UserRole } from "src/enums/users.enum"; import { DataSource, Not } from "typeorm"; // These are initial data should exist so the app would work @Injectable() export class InitialDataSeederService { constructor(private readonly dataSource: DataSource) {} private async seedMetadata() { console.log("🚀 Seeding Metadata table with INITIAL DATA..."); const repo = this.dataSource.getRepository(Metadata); const existing = await repo.findOneBy({ id: 1 }); if (!existing) { const metadata = repo.create({ id: 1, name: "Raven", logo: "/logo.png", phoneNumber: "788424973", slogan: "Generated By Raven Nest @ https://www.npmjs.com/package/@kaiserleap/raven", }); await repo.upsert(metadata, ["id"]); console.log( "🟢 Seeding Metadata table with INITIAL DATA is done successfully." ); } else { console.log( "🟨 Seeding Metadata table with INITIAL DATA was done earlier." ); } } private async seedRole(role) { console.log(`🚀 Seeding Role table with INITIAL DATA of ${role}...`); const repo = this.dataSource.getRepository(Role); const existingRole = await repo.findOneBy({ name: role, }); if (!existingRole) { const roleData = repo.create({ name: role, }); await repo.save(roleData); console.log( `🟢 Seeding Role table with INITIAL DATA of ${role} is done successfully.` ); } else { console.log( `🟨 Seeding Role table with INITIAL DATA of ${role} was done earlier.` ); } } private async seedBasicRoles() { console.log("🚀 Seeding Role table with INITIAL DATA..."); const rolesToSeed = [ UserRole.ADMIN, UserRole.PUBLIC, ]; for (const role of rolesToSeed) { await this.seedRole(role); } } private async seedInitialPermissions() { console.log("🚀 Seeding Permission table with INITIAL DATA..."); const permissions: { action: PermissionAction; table: TablesNames; role: Role; }[] = []; const repo = this.dataSource.getRepository(Permission); const tables = Object.values(TablesNames).filter((table) => { switch (table) { case "role": case "permission": case "user": APP_HEALTH_CHECK_TABLE_PLACEHOLDER return false; default: return true; } }); const actions = Object.values(PermissionAction).filter((table) => { switch (table) { case "delete": return false; default: return true; } }); const rolesRepo = this.dataSource.getRepository(Role); const authRoles = await rolesRepo.find({ where: { name: Not(UserRole.PUBLIC) }, }); tables?.forEach(async (table) => { actions?.forEach(async (action) => { authRoles?.forEach(async (role) => { permissions.push({ action, table, role, }); }); }); }); const publicRole = await rolesRepo.findOneBy({ name: UserRole.PUBLIC, }); if (publicRole) { const customPermissions = [ { role: publicRole, table: TablesNames.METADATA, action: PermissionAction.GET_ALL, }, { role: publicRole, table: TablesNames.METADATA, action: PermissionAction.GET_ONE, }, { role: publicRole, table: TablesNames.AUTH, action: PermissionAction.CREATE, }, APP_HEALTH_CHECK_PERMISSIONS_PLACEHOLDER ]; customPermissions.forEach((per) => permissions.push(per)); } authRoles.forEach((role) => permissions.push({ action: PermissionAction.DELETE, table: TablesNames.FILE, role, }) ); for (const permission of permissions) { const { role, action, table } = permission; const existing = await repo.findOne({ where: { role: { id: role.id }, action, table, }, relations: ["role"], }); const description = "Allowing " + role.name + " to " + action + " @ " + table + " table."; if (!existing) { console.log( `🚀 Seeding Permission table with INITIAL DATA of ${description}...` ); const permissionData = repo.create({ action, table, description, role, }); await repo.save(permissionData); console.log( `🟢 Seeding Permission table with INITIAL DATA of ${description} is done successfully.` ); } else { console.log( `🟨 Seeding Permission table with INITIAL DATA of ${description} was done earlier.` ); } } } private async seedUser({ user: { username = "", email = "", role = UserRole.ADMIN, password = "", }, }) { console.log( `🚀 Seeding User table with INITIAL DATA of ${username}...` ); const userRepo = this.dataSource.getRepository(User); const existing = await userRepo.findOneBy({ username }); if (!existing) { const userData = userRepo.create({ username, password, email, role, }); const user = await userRepo.save(userData); console.log( `🟢 Seeding User table with INITIAL DATA of ${username} is done successfully.` ); } else { console.log( `🟨 Seeding User table with INITIAL DATA of ${username} was done earlier.` ); } } private async seedUsers() { console.log("🚀 Seeding User table with INITIAL DATA..."); const usersToSeed = [ { user: { username: "example", password: await hash("s5Rsa2?#sd1154", 12), role: UserRole.ADMIN, email: "example@example.com", }, }, ]; for (const user of usersToSeed) { await this.seedUser(user); } } async seed() { console.log("🚀🚀 Seeding tables with INITIAL DATA..."); await this.seedMetadata(); await this.seedBasicRoles(); await this.seedInitialPermissions(); await this.seedUsers(); console.log("✅ All tables seeded with INITIAL DATA successfully."); } }