From 0dbce199ae3f595c814896d64941c404269a0e82 Mon Sep 17 00:00:00 2001 From: "BENJAMIN\\bensh" Date: Mon, 21 Oct 2024 20:50:15 +0100 Subject: [PATCH 01/10] feat(db): Added dropAllTables to schema --- .../database/base/BaseDatabaseSchema.ts | 5 ++ .../database/interfaces/IDatabaseSchema.ts | 5 ++ .../domains/database/schema/MongoDBSchema.ts | 17 +++++ .../domains/database/schema/PostgresSchema.ts | 9 +++ src/tests/database/dbDropAllTables.test.ts | 65 +++++++++++++++++++ 5 files changed, 101 insertions(+) create mode 100644 src/tests/database/dbDropAllTables.test.ts diff --git a/src/core/domains/database/base/BaseDatabaseSchema.ts b/src/core/domains/database/base/BaseDatabaseSchema.ts index 8401e51ee..57c84e8f5 100644 --- a/src/core/domains/database/base/BaseDatabaseSchema.ts +++ b/src/core/domains/database/base/BaseDatabaseSchema.ts @@ -49,6 +49,11 @@ abstract class BaseDatabaseSchema; + /** + * Abstract method to drop all tables in the database + */ + abstract dropAllTables(): Promise; + } export default BaseDatabaseSchema \ No newline at end of file diff --git a/src/core/domains/database/interfaces/IDatabaseSchema.ts b/src/core/domains/database/interfaces/IDatabaseSchema.ts index 6cb661371..b64381924 100644 --- a/src/core/domains/database/interfaces/IDatabaseSchema.ts +++ b/src/core/domains/database/interfaces/IDatabaseSchema.ts @@ -33,4 +33,9 @@ export interface IDatabaseSchema { * @throws Error if the method is not implemented */ alterTable(name: string, ...args: any[]): Promise + + /** + * Drop all tables in the database + */ + dropAllTables(): Promise; } diff --git a/src/core/domains/database/schema/MongoDBSchema.ts b/src/core/domains/database/schema/MongoDBSchema.ts index 75b73fe98..6cdfae9c6 100644 --- a/src/core/domains/database/schema/MongoDBSchema.ts +++ b/src/core/domains/database/schema/MongoDBSchema.ts @@ -50,6 +50,23 @@ class MongoDBSchema extends BaseDatabaseSchema { throw new Error("Method not implemented."); } + /** + * Drop all tables in the database + * + * @returns A promise resolving when all tables have been dropped + */ + async dropAllTables(): Promise { + const mongoClient = this.driver.getClient(); + const db = mongoClient.db(); + + const collections = await db.listCollections().toArray(); + + for(const collection of collections) { + await db.dropCollection(collection.name); + } + + } + } export default MongoDBSchema \ No newline at end of file diff --git a/src/core/domains/database/schema/PostgresSchema.ts b/src/core/domains/database/schema/PostgresSchema.ts index 4f5ea3faf..d9fd1d9ec 100644 --- a/src/core/domains/database/schema/PostgresSchema.ts +++ b/src/core/domains/database/schema/PostgresSchema.ts @@ -116,6 +116,15 @@ class PostgresSchema extends BaseDatabaseSchema { return await queryInterface.tableExists(tableName); } + /** + * Drop all tables in the database + */ + async dropAllTables(): Promise { + const sequelize = this.driver.getClient(); + const queryInterface = sequelize.getQueryInterface(); + await queryInterface.dropAllTables(); + } + } export default PostgresSchema \ No newline at end of file diff --git a/src/tests/database/dbDropAllTables.test.ts b/src/tests/database/dbDropAllTables.test.ts new file mode 100644 index 000000000..43a38a0c8 --- /dev/null +++ b/src/tests/database/dbDropAllTables.test.ts @@ -0,0 +1,65 @@ +/* eslint-disable no-undef */ +import { describe, expect, test } from '@jest/globals'; +import Kernel from '@src/core/Kernel'; +import { App } from '@src/core/services/App'; +import testAppConfig from '@src/tests/config/testConfig'; +import { getTestConnectionNames } from '@src/tests/config/testDatabaseConfig'; +import TestDatabaseProvider from '@src/tests/providers/TestDatabaseProvider'; +import { DataTypes } from 'sequelize'; + +const connections = getTestConnectionNames() + +const createTable = async (connectionName: string) => { + const schema = App.container('db').schema(connectionName) + + schema.createTable('tests', { + name: DataTypes.STRING, + createdAt: DataTypes.DATE, + updatedAt: DataTypes.DATE + }) +} + +const dropTable = async (connectionName: string) => { + const schema = App.container('db').schema(connectionName) + + if(await schema.tableExists('tests')) { + await schema.dropTable('tests'); + } +} + + +describe('test partial search', () => { + + beforeAll(async () => { + await Kernel.boot({ + ...testAppConfig, + providers: [ + ...testAppConfig.providers, + new TestDatabaseProvider() + ] + }, {}) + + + for(const connectionName of connections) { + await dropTable(connectionName) + await createTable(connectionName) + } + }) + + test('test clearing schema', async () => { + + for(const connectionName of connections) { + const schema = App.container('db').schema(connectionName) + + await createTable(connectionName); + + const tableExists = await schema.tableExists('tests'); + expect(tableExists).toBe(true); + + await schema.dropAllTables() + + const tableExistsPostDropAllTables = await schema.tableExists('tests'); + expect(tableExistsPostDropAllTables).toBe(false); + } + }) +}); \ No newline at end of file From fc3338e70855441c97b5250fc3495ddf16b6da18 Mon Sep 17 00:00:00 2001 From: "BENJAMIN\\bensh" Date: Mon, 21 Oct 2024 21:33:05 +0100 Subject: [PATCH 02/10] refactor(CommandRegister): updated error message --- src/core/domains/console/exceptions/CommandRegisterException.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/domains/console/exceptions/CommandRegisterException.ts b/src/core/domains/console/exceptions/CommandRegisterException.ts index dc49bc881..56abc39dd 100644 --- a/src/core/domains/console/exceptions/CommandRegisterException.ts +++ b/src/core/domains/console/exceptions/CommandRegisterException.ts @@ -1,7 +1,7 @@ export default class CommandRegisterException extends Error { constructor(name: string) { - super(`Command '${name}' could not be registered`); + super(`Command '${name}' could not be registered. A command with the same signature may already exist.`); this.name = 'CommandRegisterException'; } From 1c676c534163aafc68c3585d722c54f203580ca5 Mon Sep 17 00:00:00 2001 From: "BENJAMIN\\bensh" Date: Mon, 21 Oct 2024 21:33:33 +0100 Subject: [PATCH 03/10] refactor(make): updated error message when file already exists --- src/core/domains/make/base/BaseMakeFileCommand.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/domains/make/base/BaseMakeFileCommand.ts b/src/core/domains/make/base/BaseMakeFileCommand.ts index 88947b5b1..29825f50d 100644 --- a/src/core/domains/make/base/BaseMakeFileCommand.ts +++ b/src/core/domains/make/base/BaseMakeFileCommand.ts @@ -103,7 +103,7 @@ export default class BaseMakeFileCommand extends BaseCommand { const name = this.getArguementByKey('name')?.value as string; if(this.makeFileService.existsInTargetDirectory()) { - throw new CommandExecutionException(`File already exists with name '${name}'`); + throw new CommandExecutionException(`File already exists with name '${name}', full path: ${this.makeFileService.getTargetDirFullPath()}`); } // Write the new file From 09d039bf7bdfc5bdd3e25695f76db6a28e3c874c Mon Sep 17 00:00:00 2001 From: "BENJAMIN\\bensh" Date: Mon, 21 Oct 2024 21:34:26 +0100 Subject: [PATCH 04/10] refactor(migration): Added BaseMigrationCommand, added migrationType config --- .../domains/migrations/base/BaseMigration.ts | 7 ++- .../migrations/base/BaseMigrationCommand.ts | 56 ++++++++++++++++++ .../domains/migrations/base/BaseSeeder.ts | 17 ++++++ .../migrations/commands/MigrateDownCommand.ts | 23 ++------ .../migrations/commands/MigrateUpCommand.ts | 22 ++----- .../migrations/enums/MigrationTypeEnum.ts | 6 ++ .../migrations/exceptions/MigrationError.ts | 8 +++ .../migrations/factory/MigrationFactory.ts | 8 ++- .../migrations/interfaces/IMigration.ts | 10 ++++ .../migrations/interfaces/IMigrationConfig.ts | 3 +- .../interfaces/IMigrationService.ts | 4 ++ .../migrations/models/MigrationModel.ts | 7 +++ .../migrations/providers/MigrationProvider.ts | 8 ++- .../migrations/schema/createPostgresSchema.ts | 4 ++ .../migrations/services/MigrationService.ts | 27 ++++++++- .../providers/TestMigrationProvider.ts | 4 +- src/tests/migration/seeder.test.ts | 57 +++++++++++++++++++ 17 files changed, 228 insertions(+), 43 deletions(-) create mode 100644 src/core/domains/migrations/base/BaseMigrationCommand.ts create mode 100644 src/core/domains/migrations/base/BaseSeeder.ts create mode 100644 src/core/domains/migrations/enums/MigrationTypeEnum.ts create mode 100644 src/core/domains/migrations/exceptions/MigrationError.ts create mode 100644 src/tests/migration/seeder.test.ts diff --git a/src/core/domains/migrations/base/BaseMigration.ts b/src/core/domains/migrations/base/BaseMigration.ts index 62ee96eb0..82f1fed87 100644 --- a/src/core/domains/migrations/base/BaseMigration.ts +++ b/src/core/domains/migrations/base/BaseMigration.ts @@ -1,4 +1,4 @@ -import { IMigration } from "@src/core/domains/migrations/interfaces/IMigration"; +import { IMigration, MigrationType } from "@src/core/domains/migrations/interfaces/IMigration"; import { App } from "@src/core/services/App"; /** @@ -20,6 +20,11 @@ abstract class BaseMigration implements IMigration { */ protected readonly documentManager = App.container('db').documentManager() + /** + * Define the type of migration. + */ + migrationType = 'schema' as MigrationType; + /** * databaseProvider specifies which database system this migration is designed for. * If undefined, the migration will run on the default provider. diff --git a/src/core/domains/migrations/base/BaseMigrationCommand.ts b/src/core/domains/migrations/base/BaseMigrationCommand.ts new file mode 100644 index 000000000..b1605cfb5 --- /dev/null +++ b/src/core/domains/migrations/base/BaseMigrationCommand.ts @@ -0,0 +1,56 @@ +import BaseCommand from "@src/core/domains/console/base/BaseCommand"; +import { IMigrationConfig } from "@src/core/domains/migrations/interfaces/IMigrationConfig"; +import MigrationService from "@src/core/domains/migrations/services/MigrationService"; + +import MigrationTypeEnum from "../enums/MigrationTypeEnum"; +import MigrationError from "../exceptions/MigrationError"; +import { IMigrationService } from "../interfaces/IMigrationService"; + + +abstract class BaseMigrationCommand extends BaseCommand { + + config!: IMigrationConfig; + + /** + * Constructor + * @param config + */ + constructor(config: IMigrationConfig = {}) { + super(config); + this.keepProcessAlive = config?.keepProcessAlive ?? this.keepProcessAlive; + } + + /** + * Get the migration service for schema migrations + * @returns + */ + getSchemaMigrationService(): IMigrationService { + if(typeof this.config.schemaMigrationDir !== 'string') { + throw new MigrationError('Schema migration directory is not set'); + } + + return new MigrationService({ + migrationType: MigrationTypeEnum.schema, + directory: this.config.schemaMigrationDir + }); + } + + /** + * Get the migration service for seeder migrations + * @returns An instance of IMigrationService configured for seeder migrations + */ + getSeederMigrationService(): IMigrationService { + if(typeof this.config.seederMigrationDir !== 'string') { + throw new MigrationError('Seeder migration directory is not set'); + } + + return new MigrationService({ + migrationType: MigrationTypeEnum.seeder, + directory: this.config.seederMigrationDir + }); + } + + +} + +export default BaseMigrationCommand diff --git a/src/core/domains/migrations/base/BaseSeeder.ts b/src/core/domains/migrations/base/BaseSeeder.ts new file mode 100644 index 000000000..f93d208b8 --- /dev/null +++ b/src/core/domains/migrations/base/BaseSeeder.ts @@ -0,0 +1,17 @@ +import { MigrationType } from "@src/core/domains/migrations/interfaces/IMigration"; + +import BaseMigration from "./BaseMigration"; + +/** + * BaseSeeder class serves as the foundation for all database seeders. + */ +abstract class BaseSeeder extends BaseMigration { + + /** + * The type of migration + */ + migrationType = 'seeder' as MigrationType; + +} + +export default BaseSeeder; \ No newline at end of file diff --git a/src/core/domains/migrations/commands/MigrateDownCommand.ts b/src/core/domains/migrations/commands/MigrateDownCommand.ts index ff8e948de..bc1397b30 100644 --- a/src/core/domains/migrations/commands/MigrateDownCommand.ts +++ b/src/core/domains/migrations/commands/MigrateDownCommand.ts @@ -1,8 +1,7 @@ -import BaseCommand from "@src/core/domains/console/base/BaseCommand"; -import { IMigrationConfig } from "@src/core/domains/migrations/interfaces/IMigrationConfig"; -import MigrationService from "@src/core/domains/migrations/services/MigrationService"; -class MigrateDownCommand extends BaseCommand { +import BaseMigrationCommand from "../base/BaseMigrationCommand"; + +class MigrateDownCommand extends BaseMigrationCommand { /** * Signature for the command. @@ -11,16 +10,6 @@ class MigrateDownCommand extends BaseCommand { description = 'Rollback migrations'; - /** - * Constructor. - * @param config - */ - constructor(config: IMigrationConfig = {}) { - super(config); - // Allow for configurable keepProcessAlive for testing purposes - this.keepProcessAlive = config?.keepProcessAlive ?? this.keepProcessAlive; - } - /** * Execute the command. */ @@ -29,9 +18,9 @@ class MigrateDownCommand extends BaseCommand { const batch = this.getArguementByKey('batch')?.value; // Run the migrations - const service = new MigrationService(this.config); - await service.boot(); - await service.down({ batch: batch ? parseInt(batch) : undefined }); + const schemaMigrationService = this.getSchemaMigrationService(); + await schemaMigrationService.boot(); + await schemaMigrationService.down({ batch: batch ? parseInt(batch) : undefined }); } } diff --git a/src/core/domains/migrations/commands/MigrateUpCommand.ts b/src/core/domains/migrations/commands/MigrateUpCommand.ts index 08f74f83e..33a8f2ac1 100644 --- a/src/core/domains/migrations/commands/MigrateUpCommand.ts +++ b/src/core/domains/migrations/commands/MigrateUpCommand.ts @@ -1,11 +1,10 @@ -import BaseCommand from "@src/core/domains/console/base/BaseCommand"; -import { IMigrationConfig } from "@src/core/domains/migrations/interfaces/IMigrationConfig"; -import MigrationService from "@src/core/domains/migrations/services/MigrationService"; + +import BaseMigrationCommand from "../base/BaseMigrationCommand"; /** * MigrateUpCommand class handles running up migrations */ -class MigrateUpCommand extends BaseCommand { +class MigrateUpCommand extends BaseMigrationCommand { /** * The signature of the command @@ -14,15 +13,6 @@ class MigrateUpCommand extends BaseCommand { description = 'Run up migrations'; - /** - * Constructor - * @param config - */ - constructor(config: IMigrationConfig = {}) { - super(config); - // Allow for configurable keepProcessAlive for testing purposes - this.keepProcessAlive = config?.keepProcessAlive ?? this.keepProcessAlive; - } /** * Execute the command @@ -33,9 +23,9 @@ class MigrateUpCommand extends BaseCommand { const group = this.getArguementByKey('group')?.value; // Run the migrations - const service = new MigrationService(this.config); - await service.boot(); - await service.up({ filterByFileName: file, group }); + const schemaMigrationService = this.getSchemaMigrationService(); + await schemaMigrationService.boot(); + await schemaMigrationService.up({ filterByFileName: file, group: group }); } } diff --git a/src/core/domains/migrations/enums/MigrationTypeEnum.ts b/src/core/domains/migrations/enums/MigrationTypeEnum.ts new file mode 100644 index 000000000..38d117c20 --- /dev/null +++ b/src/core/domains/migrations/enums/MigrationTypeEnum.ts @@ -0,0 +1,6 @@ +const MigrationTypeEnum = { + seeder: 'seeder', + schema: 'schema' +} as const; + +export default MigrationTypeEnum \ No newline at end of file diff --git a/src/core/domains/migrations/exceptions/MigrationError.ts b/src/core/domains/migrations/exceptions/MigrationError.ts new file mode 100644 index 000000000..a190ccdeb --- /dev/null +++ b/src/core/domains/migrations/exceptions/MigrationError.ts @@ -0,0 +1,8 @@ +export default class MigrationError extends Error { + + constructor(message: string = 'Migration error') { + super(message); + this.name = 'MigrationError'; + } + +} \ No newline at end of file diff --git a/src/core/domains/migrations/factory/MigrationFactory.ts b/src/core/domains/migrations/factory/MigrationFactory.ts index 503071c42..c706edcb8 100644 --- a/src/core/domains/migrations/factory/MigrationFactory.ts +++ b/src/core/domains/migrations/factory/MigrationFactory.ts @@ -1,11 +1,14 @@ import MigrationModel from "@src/core/domains/migrations/models/MigrationModel"; import { IModel, ModelConstructor } from "@src/core/interfaces/IModel"; +import { MigrationType } from "../interfaces/IMigration"; + type Props = { name: string; batch: number; checksum: string; + type: MigrationType; appliedAt: Date; } @@ -13,14 +16,15 @@ class MigrationFactory { /** * Create a migration model - * @param param0 + * @param param * @returns */ - create({ name, batch, checksum, appliedAt }: Props, modelCtor: ModelConstructor = MigrationModel): IModel { + create({ name, batch, checksum, type, appliedAt }: Props, modelCtor: ModelConstructor = MigrationModel): IModel { return new modelCtor({ name, batch, checksum, + type, appliedAt }); } diff --git a/src/core/domains/migrations/interfaces/IMigration.ts b/src/core/domains/migrations/interfaces/IMigration.ts index 502b14ee9..da1916444 100644 --- a/src/core/domains/migrations/interfaces/IMigration.ts +++ b/src/core/domains/migrations/interfaces/IMigration.ts @@ -1,3 +1,8 @@ +/** + * The type of migration + */ +export type MigrationType = 'schema' | 'seeder'; + export interface IMigration { /** @@ -10,6 +15,11 @@ export interface IMigration { */ group?: string; + /** + * Specify the type of migration + */ + migrationType: 'schema' | 'seeder'; + /** * Run the migrations up */ diff --git a/src/core/domains/migrations/interfaces/IMigrationConfig.ts b/src/core/domains/migrations/interfaces/IMigrationConfig.ts index 03ad3831e..9f1983d75 100644 --- a/src/core/domains/migrations/interfaces/IMigrationConfig.ts +++ b/src/core/domains/migrations/interfaces/IMigrationConfig.ts @@ -2,7 +2,8 @@ import { ModelConstructor } from "@src/core/interfaces/IModel"; export interface IMigrationConfig { - appMigrationsDir?: string; + schemaMigrationDir?: string; + seederMigrationDir?: string; keepProcessAlive?: boolean; modelCtor?: ModelConstructor; } \ No newline at end of file diff --git a/src/core/domains/migrations/interfaces/IMigrationService.ts b/src/core/domains/migrations/interfaces/IMigrationService.ts index 795b939bd..390ac3831 100644 --- a/src/core/domains/migrations/interfaces/IMigrationService.ts +++ b/src/core/domains/migrations/interfaces/IMigrationService.ts @@ -1,3 +1,5 @@ +import { MigrationType } from "./IMigration"; + /* eslint-disable no-unused-vars */ export interface IMigrationServiceOptions { filterByFileName?: string @@ -6,6 +8,8 @@ export interface IMigrationServiceOptions { } export interface IMigrationService { + boot(): Promise; up(options: IMigrationServiceOptions): Promise; down(options: IMigrationServiceOptions): Promise; + getMigrationType(): MigrationType; } \ No newline at end of file diff --git a/src/core/domains/migrations/models/MigrationModel.ts b/src/core/domains/migrations/models/MigrationModel.ts index a710bba65..40e352d55 100644 --- a/src/core/domains/migrations/models/MigrationModel.ts +++ b/src/core/domains/migrations/models/MigrationModel.ts @@ -21,6 +21,12 @@ export interface MigrationModelData extends IModelAttributes { */ checksum: string; + /** + * The type of the migration. + * eg. 'seeder' | 'schema' + */ + type: string; + /** * The time when the migration was applied. */ @@ -51,6 +57,7 @@ class MigrationModel extends Model { 'name', 'batch', 'checksum', + 'type', 'appliedAt' ] diff --git a/src/core/domains/migrations/providers/MigrationProvider.ts b/src/core/domains/migrations/providers/MigrationProvider.ts index f4a3eb449..f04817304 100644 --- a/src/core/domains/migrations/providers/MigrationProvider.ts +++ b/src/core/domains/migrations/providers/MigrationProvider.ts @@ -4,6 +4,8 @@ import MigrateUpCommand from "@src/core/domains/migrations/commands/MigrateUpCom import { IMigrationConfig } from "@src/core/domains/migrations/interfaces/IMigrationConfig"; import { App } from "@src/core/services/App"; +import MigrateFreshCommand from "../commands/MigrateFreshCommand"; + /** * MigrationProvider class handles all migration related tasks */ @@ -13,7 +15,8 @@ class MigrationProvider extends BaseProvider { * The default configuration for the migrations */ protected config: IMigrationConfig = { - appMigrationsDir: '@src/../src/app/migrations', + schemaMigrationDir: '@src/../src/app/migrations', + seederMigrationDir: '@src/../src/app/seeders', }; /** @@ -25,7 +28,8 @@ class MigrationProvider extends BaseProvider { App.container('console').register().registerAll([ MigrateUpCommand, - MigrateDownCommand + MigrateDownCommand, + MigrateFreshCommand ], this.config) } diff --git a/src/core/domains/migrations/schema/createPostgresSchema.ts b/src/core/domains/migrations/schema/createPostgresSchema.ts index 19de73338..4ddab2c8a 100644 --- a/src/core/domains/migrations/schema/createPostgresSchema.ts +++ b/src/core/domains/migrations/schema/createPostgresSchema.ts @@ -34,6 +34,10 @@ const createPostgresSchema = async (tableName: string = 'migrations') => { type: 'VARCHAR', allowNull: false }, + type: { + type: 'VARCHAR', + allowNull: false + }, appliedAt: { type: 'TIMESTAMPTZ', allowNull: false diff --git a/src/core/domains/migrations/services/MigrationService.ts b/src/core/domains/migrations/services/MigrationService.ts index afc8e96a0..799687305 100644 --- a/src/core/domains/migrations/services/MigrationService.ts +++ b/src/core/domains/migrations/services/MigrationService.ts @@ -1,6 +1,6 @@ import Repository from "@src/core/base/Repository"; import MigrationFactory from "@src/core/domains/migrations/factory/MigrationFactory"; -import { IMigration } from "@src/core/domains/migrations/interfaces/IMigration"; +import { IMigration, MigrationType } from "@src/core/domains/migrations/interfaces/IMigration"; import { IMigrationConfig } from "@src/core/domains/migrations/interfaces/IMigrationConfig"; import { IMigrationService, IMigrationServiceOptions } from "@src/core/domains/migrations/interfaces/IMigrationService"; import MigrationModel from "@src/core/domains/migrations/models/MigrationModel"; @@ -16,6 +16,11 @@ interface MigrationDetail { fileName: string, migration: IMigration } +type ConstructorProps = { + directory: string; + modelCtor?: ModelConstructor; + migrationType: MigrationType; +} /** * MigrationService class is responsible for handling migrations. @@ -32,11 +37,14 @@ class MigrationService implements IMigrationService { protected modelCtor!: ModelConstructor; - constructor(config: IMigrationConfig = {}) { + protected migrationType!: MigrationType; + + constructor(config: ConstructorProps = {} as ConstructorProps) { this.config = config; - this.fileService = new MigrationFileService(config.appMigrationsDir); + this.fileService = new MigrationFileService(config.directory); this.modelCtor = config.modelCtor ?? MigrationModel; this.repository = new Repository(this.modelCtor); + this.migrationType = config.migrationType; } async boot() { @@ -44,6 +52,14 @@ class MigrationService implements IMigrationService { await this.createSchema(); } + /** + * Get the migration type of this service + * @returns The migration type + */ + getMigrationType(): MigrationType { + return this.migrationType + } + /** * Get all migration details * @returns A record of all migration class instances, keyed by the filename @@ -57,6 +73,10 @@ class MigrationService implements IMigrationService { try { const migration = await this.fileService.getImportMigrationClass(fileName); + if(migration.migrationType !== this.migrationType) { + continue; + } + if (filterByFileName && fileName !== filterByFileName) { continue; } @@ -196,6 +216,7 @@ class MigrationService implements IMigrationService { name: fileName, batch: newBatchCount, checksum: fileChecksum, + type: this.migrationType, appliedAt: new Date(), }, this.modelCtor) await model.save(); diff --git a/src/tests/migration/providers/TestMigrationProvider.ts b/src/tests/migration/providers/TestMigrationProvider.ts index 0606ecb24..5a5657f45 100644 --- a/src/tests/migration/providers/TestMigrationProvider.ts +++ b/src/tests/migration/providers/TestMigrationProvider.ts @@ -17,12 +17,14 @@ class TestMigrationProvider extends MigrationProvider { */ const config: IMigrationConfig = { keepProcessAlive: true, - appMigrationsDir: '@src/../src/tests/migration/migrations', + schemaMigrationDir: '@src/../src/tests/migration/migrations', + seederMigrationDir: '@src/../src/tests/migration/seeders', modelCtor: TestMigrationModel } App.container('console').register().addCommandConfig([ (new MigrateUpCommand).signature, + (new MigrateDownCommand).signature, (new MigrateDownCommand).signature ], config) } diff --git a/src/tests/migration/seeder.test.ts b/src/tests/migration/seeder.test.ts new file mode 100644 index 000000000..f4b713690 --- /dev/null +++ b/src/tests/migration/seeder.test.ts @@ -0,0 +1,57 @@ +/* eslint-disable no-undef */ +import { describe } from '@jest/globals'; +import { IDatabaseSchema } from '@src/core/domains/database/interfaces/IDatabaseSchema'; +import Kernel from '@src/core/Kernel'; +import { App } from '@src/core/services/App'; +import testAppConfig from '@src/tests/config/testConfig'; +import TestMigrationProvider from '@src/tests/migration/providers/TestMigrationProvider'; +import TestConsoleProvider from '@src/tests/providers/TestConsoleProvider'; +import TestDatabaseProvider from '@src/tests/providers/TestDatabaseProvider'; + +describe('test migrations', () => { + + let schema: IDatabaseSchema; + + beforeAll(async () => { + await Kernel.boot({ + ...testAppConfig, + providers: [ + ...testAppConfig.providers, + new TestConsoleProvider(), + new TestDatabaseProvider(), + new TestMigrationProvider(), + ] + }, {}) + + /** + * Drop the test table if it exists + */ + if(await App.container('db').schema().tableExists('tests')) { + await App.container('db').schema().dropTable('tests'); + } + + schema = App.container('db').schema(); + }); + + afterAll(async () => { + await App.container('db').schema().dropTable('tests'); + }) + + test('test up migration', async () => { + + await App.container('console').reader(['migrate:up']).handle(); + + const tableExists = await schema.tableExists('tests'); + + expect(tableExists).toBe(true); + }); + + test('test down migration', async () => { + + await App.container('console').reader(['migrate:down']).handle(); + + const tableExists = await schema.tableExists('tests'); + + expect(tableExists).toBe(false); + }); +}); \ No newline at end of file From 0a2e020b53934fcf055eac315e63f24e8a42236b Mon Sep 17 00:00:00 2001 From: "BENJAMIN\\bensh" Date: Mon, 21 Oct 2024 21:34:38 +0100 Subject: [PATCH 05/10] feat(migration): Added MigrateFreshCommand --- .../commands/MigrateFreshCommand.ts | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/core/domains/migrations/commands/MigrateFreshCommand.ts diff --git a/src/core/domains/migrations/commands/MigrateFreshCommand.ts b/src/core/domains/migrations/commands/MigrateFreshCommand.ts new file mode 100644 index 000000000..6c007f666 --- /dev/null +++ b/src/core/domains/migrations/commands/MigrateFreshCommand.ts @@ -0,0 +1,47 @@ + +import { App } from "@src/core/services/App"; + +import BaseMigrationCommand from "../base/BaseMigrationCommand"; + +/** + * MigrateFresh class handles running fresh migrations + */ +class MigrateFreshCommand extends BaseMigrationCommand { + + /** + * The signature of the command + */ + public signature: string = 'migrate:fresh'; + + description = 'Drops all tables and runs fresh migrations'; + + + /** + * Execute the command + */ + async execute() { + if(!await this.confirm()) { + return; + } + + // Get the db schema helper + const schema = App.container('db').schema(); + + // Drop all tables + await schema.dropAllTables(); + + // Handle migrate:up + const console = App.container('console'); + await console.reader(['migrate:up']).handle(); + } + + private async confirm(): Promise { + this.input.writeLine('--- Confirm Action ---'); + const answer = await this.input.askQuestion('Are you sure you want to drop all tables and run fresh migrations? (y/n)'); + return answer === 'y'; + + } + +} + +export default MigrateFreshCommand From 31d0b1a21855e5366c8a44b1e0af2156b18619e2 Mon Sep 17 00:00:00 2001 From: "BENJAMIN\\bensh" Date: Tue, 22 Oct 2024 20:17:09 +0100 Subject: [PATCH 06/10] test(db): missing await on drop all tables test --- src/tests/database/dbDropAllTables.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/database/dbDropAllTables.test.ts b/src/tests/database/dbDropAllTables.test.ts index 43a38a0c8..af41ea3dc 100644 --- a/src/tests/database/dbDropAllTables.test.ts +++ b/src/tests/database/dbDropAllTables.test.ts @@ -56,7 +56,7 @@ describe('test partial search', () => { const tableExists = await schema.tableExists('tests'); expect(tableExists).toBe(true); - await schema.dropAllTables() + schema.dropAllTables() const tableExistsPostDropAllTables = await schema.tableExists('tests'); expect(tableExistsPostDropAllTables).toBe(false); From 493f988da803cecf463557b6c29bf78d4fb5a0c1 Mon Sep 17 00:00:00 2001 From: "BENJAMIN\\bensh" Date: Tue, 22 Oct 2024 20:17:35 +0100 Subject: [PATCH 07/10] refactor(db): wording on DocumentValidator error message --- src/core/domains/database/validator/DocumentValidator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/domains/database/validator/DocumentValidator.ts b/src/core/domains/database/validator/DocumentValidator.ts index bb830f4f8..b153df4ea 100644 --- a/src/core/domains/database/validator/DocumentValidator.ts +++ b/src/core/domains/database/validator/DocumentValidator.ts @@ -102,7 +102,7 @@ class DocumentValidator implements IDocumentValidator { if(document.id) { const response = returnOrThrow({ shouldThrow: this.throwExceptions, - throwable: new InvalidDocument(`An id property was not expected but found at index ${i}`), + throwable: new InvalidDocument(`An id property was NOT expected but found at index ${i}`), returns: false }) From 581504ae3f8b85d48c6fc049e3ca91cda0165f04 Mon Sep 17 00:00:00 2001 From: "BENJAMIN\\bensh" Date: Tue, 22 Oct 2024 20:18:36 +0100 Subject: [PATCH 08/10] feat(seeder): Added down method to BaseSeeder allowing it to be optional, added SeedCommand, upated MigrationService with missing query filter, throw errors --- .../domains/migrations/base/BaseSeeder.ts | 9 ++++++ .../migrations/commands/SeedCommand.ts | 30 +++++++++++++++++++ .../migrations/providers/MigrationProvider.ts | 4 ++- .../migrations/services/MigrationService.ts | 5 ++-- 4 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 src/core/domains/migrations/commands/SeedCommand.ts diff --git a/src/core/domains/migrations/base/BaseSeeder.ts b/src/core/domains/migrations/base/BaseSeeder.ts index f93d208b8..f46768a56 100644 --- a/src/core/domains/migrations/base/BaseSeeder.ts +++ b/src/core/domains/migrations/base/BaseSeeder.ts @@ -12,6 +12,15 @@ abstract class BaseSeeder extends BaseMigration { */ migrationType = 'seeder' as MigrationType; + /** + * Optional down method. + * + * @return {Promise} + */ + down(): Promise { + return Promise.resolve(); + } + } export default BaseSeeder; \ No newline at end of file diff --git a/src/core/domains/migrations/commands/SeedCommand.ts b/src/core/domains/migrations/commands/SeedCommand.ts new file mode 100644 index 000000000..87db5c8f3 --- /dev/null +++ b/src/core/domains/migrations/commands/SeedCommand.ts @@ -0,0 +1,30 @@ + +import BaseMigrationCommand from "../base/BaseMigrationCommand"; + +class SeedCommand extends BaseMigrationCommand { + + /** + * The signature of the command + */ + public signature: string = 'db:seed'; + + description = 'Run all seeders'; + + + /** + * Execute the command + */ + async execute() { + // Read the arguments + const file = this.getArguementByKey('file')?.value; + const group = this.getArguementByKey('group')?.value; + + // Run the migrations + const schemaMigrationService = this.getSeederMigrationService(); + await schemaMigrationService.boot(); + await schemaMigrationService.up({ filterByFileName: file, group: group }); + } + +} + +export default SeedCommand diff --git a/src/core/domains/migrations/providers/MigrationProvider.ts b/src/core/domains/migrations/providers/MigrationProvider.ts index f04817304..f1cb598fb 100644 --- a/src/core/domains/migrations/providers/MigrationProvider.ts +++ b/src/core/domains/migrations/providers/MigrationProvider.ts @@ -5,6 +5,7 @@ import { IMigrationConfig } from "@src/core/domains/migrations/interfaces/IMigra import { App } from "@src/core/services/App"; import MigrateFreshCommand from "../commands/MigrateFreshCommand"; +import SeedCommand from "../commands/SeedCommand"; /** * MigrationProvider class handles all migration related tasks @@ -29,7 +30,8 @@ class MigrationProvider extends BaseProvider { App.container('console').register().registerAll([ MigrateUpCommand, MigrateDownCommand, - MigrateFreshCommand + MigrateFreshCommand, + SeedCommand, ], this.config) } diff --git a/src/core/domains/migrations/services/MigrationService.ts b/src/core/domains/migrations/services/MigrationService.ts index 799687305..6c4dcec2b 100644 --- a/src/core/domains/migrations/services/MigrationService.ts +++ b/src/core/domains/migrations/services/MigrationService.ts @@ -88,8 +88,8 @@ class MigrationService implements IMigrationService { result.push({ fileName, migration }); } catch (err) { - if (err instanceof FileNotFoundError) { - continue; + if (err instanceof FileNotFoundError === false) { + throw err; } } } @@ -143,6 +143,7 @@ class MigrationService implements IMigrationService { // Get the migration results const results = await this.getMigrationResults({ + type: this.migrationType, batch: batchCount }); From c5611eff80bb2a84b4443de0633a4a92cf80ee70 Mon Sep 17 00:00:00 2001 From: "BENJAMIN\\bensh" Date: Tue, 22 Oct 2024 20:20:12 +0100 Subject: [PATCH 09/10] Fixed imports, formatting --- src/core/base/Factory.ts | 4 ++-- src/core/domains/migrations/base/BaseMigrationCommand.ts | 7 +++---- src/core/domains/migrations/base/BaseSeeder.ts | 3 +-- src/core/domains/migrations/commands/MigrateDownCommand.ts | 2 +- .../domains/migrations/commands/MigrateFreshCommand.ts | 3 +-- src/core/domains/migrations/commands/MigrateUpCommand.ts | 2 +- src/core/domains/migrations/commands/SeedCommand.ts | 2 +- src/core/domains/migrations/factory/MigrationFactory.ts | 3 +-- .../domains/migrations/interfaces/IMigrationService.ts | 2 +- src/core/domains/migrations/providers/MigrationProvider.ts | 5 ++--- src/tests/factory/TestMovieFaker.ts | 3 +-- src/tests/factory/factory.test.ts | 5 ++--- 12 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/core/base/Factory.ts b/src/core/base/Factory.ts index d93f8a9f7..4db909b79 100644 --- a/src/core/base/Factory.ts +++ b/src/core/base/Factory.ts @@ -2,8 +2,8 @@ import { faker } from "@faker-js/faker"; import { ICtor } from "@src/core/interfaces/ICtor"; import IFactory from "@src/core/interfaces/IFactory"; -import { IModel } from "../interfaces/IModel"; -import IModelAttributes from "../interfaces/IModelData"; +import { IModel } from "@src/core/interfaces/IModel"; +import IModelAttributes from "@src/core/interfaces/IModelData"; /** * Abstract base class for factories that create instances of a specific model. diff --git a/src/core/domains/migrations/base/BaseMigrationCommand.ts b/src/core/domains/migrations/base/BaseMigrationCommand.ts index b1605cfb5..68abc4e4f 100644 --- a/src/core/domains/migrations/base/BaseMigrationCommand.ts +++ b/src/core/domains/migrations/base/BaseMigrationCommand.ts @@ -1,11 +1,10 @@ import BaseCommand from "@src/core/domains/console/base/BaseCommand"; +import MigrationTypeEnum from "@src/core/domains/migrations/enums/MigrationTypeEnum"; +import MigrationError from "@src/core/domains/migrations/exceptions/MigrationError"; import { IMigrationConfig } from "@src/core/domains/migrations/interfaces/IMigrationConfig"; +import { IMigrationService } from "@src/core/domains/migrations/interfaces/IMigrationService"; import MigrationService from "@src/core/domains/migrations/services/MigrationService"; -import MigrationTypeEnum from "../enums/MigrationTypeEnum"; -import MigrationError from "../exceptions/MigrationError"; -import { IMigrationService } from "../interfaces/IMigrationService"; - abstract class BaseMigrationCommand extends BaseCommand { diff --git a/src/core/domains/migrations/base/BaseSeeder.ts b/src/core/domains/migrations/base/BaseSeeder.ts index f46768a56..432c9190e 100644 --- a/src/core/domains/migrations/base/BaseSeeder.ts +++ b/src/core/domains/migrations/base/BaseSeeder.ts @@ -1,7 +1,6 @@ +import BaseMigration from "@src/core/domains/migrations/base/BaseMigration"; import { MigrationType } from "@src/core/domains/migrations/interfaces/IMigration"; -import BaseMigration from "./BaseMigration"; - /** * BaseSeeder class serves as the foundation for all database seeders. */ diff --git a/src/core/domains/migrations/commands/MigrateDownCommand.ts b/src/core/domains/migrations/commands/MigrateDownCommand.ts index bc1397b30..a487c2787 100644 --- a/src/core/domains/migrations/commands/MigrateDownCommand.ts +++ b/src/core/domains/migrations/commands/MigrateDownCommand.ts @@ -1,5 +1,5 @@ -import BaseMigrationCommand from "../base/BaseMigrationCommand"; +import BaseMigrationCommand from "@src/core/domains/migrations/base/BaseMigrationCommand"; class MigrateDownCommand extends BaseMigrationCommand { diff --git a/src/core/domains/migrations/commands/MigrateFreshCommand.ts b/src/core/domains/migrations/commands/MigrateFreshCommand.ts index 6c007f666..43df03417 100644 --- a/src/core/domains/migrations/commands/MigrateFreshCommand.ts +++ b/src/core/domains/migrations/commands/MigrateFreshCommand.ts @@ -1,8 +1,7 @@ +import BaseMigrationCommand from "@src/core/domains/migrations/base/BaseMigrationCommand"; import { App } from "@src/core/services/App"; -import BaseMigrationCommand from "../base/BaseMigrationCommand"; - /** * MigrateFresh class handles running fresh migrations */ diff --git a/src/core/domains/migrations/commands/MigrateUpCommand.ts b/src/core/domains/migrations/commands/MigrateUpCommand.ts index 33a8f2ac1..0ab3a4850 100644 --- a/src/core/domains/migrations/commands/MigrateUpCommand.ts +++ b/src/core/domains/migrations/commands/MigrateUpCommand.ts @@ -1,5 +1,5 @@ -import BaseMigrationCommand from "../base/BaseMigrationCommand"; +import BaseMigrationCommand from "@src/core/domains/migrations/base/BaseMigrationCommand"; /** * MigrateUpCommand class handles running up migrations diff --git a/src/core/domains/migrations/commands/SeedCommand.ts b/src/core/domains/migrations/commands/SeedCommand.ts index 87db5c8f3..4ed9fea56 100644 --- a/src/core/domains/migrations/commands/SeedCommand.ts +++ b/src/core/domains/migrations/commands/SeedCommand.ts @@ -1,5 +1,5 @@ -import BaseMigrationCommand from "../base/BaseMigrationCommand"; +import BaseMigrationCommand from "@src/core/domains/migrations/base/BaseMigrationCommand"; class SeedCommand extends BaseMigrationCommand { diff --git a/src/core/domains/migrations/factory/MigrationFactory.ts b/src/core/domains/migrations/factory/MigrationFactory.ts index c706edcb8..ea0edbdec 100644 --- a/src/core/domains/migrations/factory/MigrationFactory.ts +++ b/src/core/domains/migrations/factory/MigrationFactory.ts @@ -1,8 +1,7 @@ +import { MigrationType } from "@src/core/domains/migrations/interfaces/IMigration"; import MigrationModel from "@src/core/domains/migrations/models/MigrationModel"; import { IModel, ModelConstructor } from "@src/core/interfaces/IModel"; -import { MigrationType } from "../interfaces/IMigration"; - type Props = { name: string; diff --git a/src/core/domains/migrations/interfaces/IMigrationService.ts b/src/core/domains/migrations/interfaces/IMigrationService.ts index 390ac3831..04c893a91 100644 --- a/src/core/domains/migrations/interfaces/IMigrationService.ts +++ b/src/core/domains/migrations/interfaces/IMigrationService.ts @@ -1,4 +1,4 @@ -import { MigrationType } from "./IMigration"; +import { MigrationType } from "@src/core/domains/migrations/interfaces/IMigration"; /* eslint-disable no-unused-vars */ export interface IMigrationServiceOptions { diff --git a/src/core/domains/migrations/providers/MigrationProvider.ts b/src/core/domains/migrations/providers/MigrationProvider.ts index f1cb598fb..be8804778 100644 --- a/src/core/domains/migrations/providers/MigrationProvider.ts +++ b/src/core/domains/migrations/providers/MigrationProvider.ts @@ -1,12 +1,11 @@ import BaseProvider from "@src/core/base/Provider"; import MigrateDownCommand from "@src/core/domains/migrations/commands/MigrateDownCommand"; +import MigrateFreshCommand from "@src/core/domains/migrations/commands/MigrateFreshCommand"; import MigrateUpCommand from "@src/core/domains/migrations/commands/MigrateUpCommand"; +import SeedCommand from "@src/core/domains/migrations/commands/SeedCommand"; import { IMigrationConfig } from "@src/core/domains/migrations/interfaces/IMigrationConfig"; import { App } from "@src/core/services/App"; -import MigrateFreshCommand from "../commands/MigrateFreshCommand"; -import SeedCommand from "../commands/SeedCommand"; - /** * MigrationProvider class handles all migration related tasks */ diff --git a/src/tests/factory/TestMovieFaker.ts b/src/tests/factory/TestMovieFaker.ts index 0782b72dc..6af281117 100644 --- a/src/tests/factory/TestMovieFaker.ts +++ b/src/tests/factory/TestMovieFaker.ts @@ -1,6 +1,5 @@ import Factory from "@src/core/base/Factory"; - -import { TestMovieModel } from "../models/models/TestMovie"; +import { TestMovieModel } from "@src/tests/models/models/TestMovie"; class TestMovieFactory extends Factory { diff --git a/src/tests/factory/factory.test.ts b/src/tests/factory/factory.test.ts index 272ea5c1b..72b35365b 100644 --- a/src/tests/factory/factory.test.ts +++ b/src/tests/factory/factory.test.ts @@ -2,9 +2,8 @@ import { describe } from '@jest/globals'; import Kernel from '@src/core/Kernel'; import testAppConfig from '@src/tests/config/testConfig'; - -import TestDatabaseProvider from '../providers/TestDatabaseProvider'; -import TestMovieFactory from './TestMovieFaker'; +import TestMovieFactory from '@src/tests/factory/TestMovieFaker'; +import TestDatabaseProvider from '@src/tests/providers/TestDatabaseProvider'; describe('test migrations', () => { From cb229461486fb3ae520cbfeac1512b28730a7c70 Mon Sep 17 00:00:00 2001 From: "BENJAMIN\\bensh" Date: Tue, 22 Oct 2024 20:28:39 +0100 Subject: [PATCH 10/10] feat(make): Added MakeSeederCommand --- src/core/base/Factory.ts | 1 - src/core/domains/auth/factory/userFactory.ts | 2 +- .../make/commands/MakeSeederCommand.ts | 19 +++++++++++ src/core/domains/make/consts/MakeTypes.ts | 2 ++ .../make/observers/ArgumentObserver.ts | 2 +- .../domains/make/providers/MakeProvider.ts | 2 ++ .../domains/make/templates/Seeder.ts.template | 32 +++++++++++++++++++ 7 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 src/core/domains/make/commands/MakeSeederCommand.ts create mode 100644 src/core/domains/make/templates/Seeder.ts.template diff --git a/src/core/base/Factory.ts b/src/core/base/Factory.ts index 4db909b79..b5e7b745f 100644 --- a/src/core/base/Factory.ts +++ b/src/core/base/Factory.ts @@ -1,7 +1,6 @@ import { faker } from "@faker-js/faker"; import { ICtor } from "@src/core/interfaces/ICtor"; import IFactory from "@src/core/interfaces/IFactory"; - import { IModel } from "@src/core/interfaces/IModel"; import IModelAttributes from "@src/core/interfaces/IModelData"; diff --git a/src/core/domains/auth/factory/userFactory.ts b/src/core/domains/auth/factory/userFactory.ts index cf718b8d6..244c5a3c7 100644 --- a/src/core/domains/auth/factory/userFactory.ts +++ b/src/core/domains/auth/factory/userFactory.ts @@ -1,4 +1,4 @@ -import User, { IUserData } from '@src/app/models/auth/User'; +import User from '@src/app/models/auth/User'; import Factory from '@src/core/base/Factory'; /** diff --git a/src/core/domains/make/commands/MakeSeederCommand.ts b/src/core/domains/make/commands/MakeSeederCommand.ts new file mode 100644 index 000000000..c121ebb08 --- /dev/null +++ b/src/core/domains/make/commands/MakeSeederCommand.ts @@ -0,0 +1,19 @@ +import BaseMakeFileCommand from "@src/core/domains/make/base/BaseMakeFileCommand"; +import MigrationFileService from "@src/core/domains/migrations/services/MigrationFilesService"; + +export default class MakeSeederCommand extends BaseMakeFileCommand { + + constructor() { + super({ + signature: 'make:seeder', + description: 'Creates a new database seeder', + makeType: 'Seeder', + args: ['name'], + endsWith: 'Seeder', + customFilename: (name: string) => { + return (new MigrationFileService).createDateFilename(name) + } + }) + } + +} \ No newline at end of file diff --git a/src/core/domains/make/consts/MakeTypes.ts b/src/core/domains/make/consts/MakeTypes.ts index 70d33c5f6..fd184e023 100644 --- a/src/core/domains/make/consts/MakeTypes.ts +++ b/src/core/domains/make/consts/MakeTypes.ts @@ -22,6 +22,7 @@ export const targetDirectories: Record = { Action: `${APP_PATH}/actions`, Validator: `${APP_PATH}/validators`, Migration: `${APP_PATH}/migrations`, + Seeder: `${APP_PATH}/seeders`, } as const; /** @@ -44,6 +45,7 @@ export const templates: Record = { Action: `${TEMPLATE_PATH}/Action.ts.template`, Validator: `${TEMPLATE_PATH}/Validator.ts.template`, Migration: `${TEMPLATE_PATH}/Migration.ts.template`, + Seeder: `${TEMPLATE_PATH}/Seeder.ts.template`, } as const; export default Object.freeze({ diff --git a/src/core/domains/make/observers/ArgumentObserver.ts b/src/core/domains/make/observers/ArgumentObserver.ts index 6fd94bc83..bdf89d2d7 100644 --- a/src/core/domains/make/observers/ArgumentObserver.ts +++ b/src/core/domains/make/observers/ArgumentObserver.ts @@ -44,7 +44,7 @@ class ArgumentObserver extend return data } - if(!data.name.endsWith(options.endsWith)) { + if(!data.name.toLowerCase().endsWith(options.endsWith.toLowerCase())) { data.name = `${data.name}${options.endsWith}` } diff --git a/src/core/domains/make/providers/MakeProvider.ts b/src/core/domains/make/providers/MakeProvider.ts index b130041f3..946e4f98f 100644 --- a/src/core/domains/make/providers/MakeProvider.ts +++ b/src/core/domains/make/providers/MakeProvider.ts @@ -14,6 +14,7 @@ import MakeSingletonCommand from "@src/core/domains/make/commands/MakeSingletonC import MakeSubscriberCommand from "@src/core/domains/make/commands/MakeSubscriberCommand"; import MakeValidatorCommand from "@src/core/domains/make/commands/MakeValidatorCommand"; import { App } from "@src/core/services/App"; +import MakeSeederCommand from "@src/core/domains/make/commands/MakeSeederCommand"; export default class MakeProvider extends BaseProvider { @@ -35,6 +36,7 @@ export default class MakeProvider extends BaseProvider { MakeActionCommand, MakeValidatorCommand, MakeMigrationCommand, + MakeSeederCommand ]) } diff --git a/src/core/domains/make/templates/Seeder.ts.template b/src/core/domains/make/templates/Seeder.ts.template new file mode 100644 index 000000000..025f71440 --- /dev/null +++ b/src/core/domains/make/templates/Seeder.ts.template @@ -0,0 +1,32 @@ +import { faker } from "@faker-js/faker"; +import hashPassword from "@src/core/domains/auth/utils/hashPassword"; +import BaseSeeder from "@src/core/domains/migrations/base/BaseSeeder"; + +import User, { IUserData } from "../models/auth/User"; + +export class #name# extends BaseSeeder { + + async up(): Promise { + + // Example: + // for (let i = 0; i < 10; i++) { + + // const data: IUserData = { + // email: faker.internet.email(), + // password: faker.internet.password(), + // hashedPassword: hashPassword(faker.internet.password()), + // roles: ['user'], + // groups: [], + // firstName: faker.person.firstName(), + // lastName: faker.person.lastName(), + // } + + // const user = new User(data); + // await user.save(); + // } + + } + +} + +export default #name# \ No newline at end of file