mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 02:21:13 +00:00
refactor(core): Decouple database entity registration (#15871)
Co-authored-by: Danny Martini <danny@n8n.io>
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import { Container } from '@n8n/di';
|
||||
|
||||
import { N8nModule } from '../module';
|
||||
import { BackendModule } from '../module';
|
||||
import { ModuleMetadata } from '../module-metadata';
|
||||
|
||||
describe('@N8nModule Decorator', () => {
|
||||
describe('@BackendModule decorator', () => {
|
||||
let moduleMetadata: ModuleMetadata;
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -14,7 +14,7 @@ describe('@N8nModule Decorator', () => {
|
||||
});
|
||||
|
||||
it('should register module in ModuleMetadata', () => {
|
||||
@N8nModule()
|
||||
@BackendModule()
|
||||
class TestModule {
|
||||
initialize() {}
|
||||
}
|
||||
@@ -26,17 +26,17 @@ describe('@N8nModule Decorator', () => {
|
||||
});
|
||||
|
||||
it('should register multiple modules', () => {
|
||||
@N8nModule()
|
||||
@BackendModule()
|
||||
class FirstModule {
|
||||
initialize() {}
|
||||
}
|
||||
|
||||
@N8nModule()
|
||||
@BackendModule()
|
||||
class SecondModule {
|
||||
initialize() {}
|
||||
}
|
||||
|
||||
@N8nModule()
|
||||
@BackendModule()
|
||||
class ThirdModule {
|
||||
initialize() {}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ describe('@N8nModule Decorator', () => {
|
||||
});
|
||||
|
||||
it('should work with modules without initialize method', () => {
|
||||
@N8nModule()
|
||||
@BackendModule()
|
||||
class TestModule {}
|
||||
|
||||
const registeredModules = Array.from(moduleMetadata.getModules());
|
||||
@@ -62,7 +62,7 @@ describe('@N8nModule Decorator', () => {
|
||||
it('should support async initialize method', async () => {
|
||||
const mockInitialize = jest.fn();
|
||||
|
||||
@N8nModule()
|
||||
@BackendModule()
|
||||
class TestModule {
|
||||
async initialize() {
|
||||
mockInitialize();
|
||||
@@ -81,10 +81,10 @@ describe('@N8nModule Decorator', () => {
|
||||
|
||||
describe('ModuleMetadata', () => {
|
||||
it('should allow retrieving and checking registered modules', () => {
|
||||
@N8nModule()
|
||||
@BackendModule()
|
||||
class FirstModule {}
|
||||
|
||||
@N8nModule()
|
||||
@BackendModule()
|
||||
class SecondModule {}
|
||||
|
||||
const registeredModules = Array.from(moduleMetadata.getModules());
|
||||
@@ -95,7 +95,7 @@ describe('@N8nModule Decorator', () => {
|
||||
});
|
||||
|
||||
it('should apply Service decorator', () => {
|
||||
@N8nModule()
|
||||
@BackendModule()
|
||||
class TestModule {}
|
||||
|
||||
expect(Container.has(TestModule)).toBe(true);
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export { BaseN8nModule, N8nModule } from './module';
|
||||
export { ModuleInterface, BackendModule, EntityClass } from './module';
|
||||
export { ModuleMetadata } from './module-metadata';
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Service } from '@n8n/di';
|
||||
|
||||
import type { Module } from './module';
|
||||
import type { ModuleClass } from './module';
|
||||
|
||||
@Service()
|
||||
export class ModuleMetadata {
|
||||
private readonly modules: Set<Module> = new Set();
|
||||
private readonly modules: Set<ModuleClass> = new Set();
|
||||
|
||||
register(module: Module) {
|
||||
register(module: ModuleClass) {
|
||||
this.modules.add(module);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,14 +2,30 @@ import { Container, Service, type Constructable } from '@n8n/di';
|
||||
|
||||
import { ModuleMetadata } from './module-metadata';
|
||||
|
||||
export interface BaseN8nModule {
|
||||
initialize?(): void | Promise<void>;
|
||||
/**
|
||||
* Structurally similar (not identical) interface to typeorm's `BaseEntity`
|
||||
* to prevent importing `@n8n/typeorm` into `@n8n/decorators`.
|
||||
*/
|
||||
export interface BaseEntity {
|
||||
hasId(): boolean;
|
||||
save(options?: unknown): Promise<this>;
|
||||
remove(options?: unknown): Promise<this>;
|
||||
softRemove(options?: unknown): Promise<this>;
|
||||
recover(options?: unknown): Promise<this>;
|
||||
reload(): Promise<void>;
|
||||
}
|
||||
|
||||
export type Module = Constructable<BaseN8nModule>;
|
||||
export type EntityClass = new () => BaseEntity;
|
||||
|
||||
export const N8nModule = (): ClassDecorator => (target) => {
|
||||
Container.get(ModuleMetadata).register(target as unknown as Module);
|
||||
export interface ModuleInterface {
|
||||
init?(): void | Promise<void>;
|
||||
entities?(): EntityClass[];
|
||||
}
|
||||
|
||||
export type ModuleClass = Constructable<ModuleInterface>;
|
||||
|
||||
export const BackendModule = (): ClassDecorator => (target) => {
|
||||
Container.get(ModuleMetadata).register(target as unknown as ModuleClass);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
return Service()(target);
|
||||
|
||||
Reference in New Issue
Block a user