Skip to content

Commit

Permalink
feat(core): deprecate UseRequestContext decorator (#4744)
Browse files Browse the repository at this point in the history
  • Loading branch information
ruscon committed Sep 25, 2023
1 parent 644fc68 commit 280733f
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 2 deletions.
22 changes: 22 additions & 0 deletions packages/core/src/decorators/CreateRequestContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { MikroORM } from '../MikroORM';
import { RequestContext } from '../utils/RequestContext';

export function CreateRequestContext<T>(getContext?: MikroORM | ((type?: T) => MikroORM)): MethodDecorator {
return function (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = async function (this: T, ...args: any[]) {
/* istanbul ignore next */
const orm = getContext instanceof MikroORM ? getContext : (getContext?.(this) ?? (this as any).orm);

if (!(orm as unknown instanceof MikroORM)) {
throw new Error('@CreateRequestContext() decorator can only be applied to methods of classes with `orm: MikroORM` property, or with a callback parameter like `@CreateRequestContext(() => orm)`');
}

return await RequestContext.createAsync(orm.em, async () => {
return originalMethod.apply(this, args);
});
};

return descriptor;
};
}
1 change: 1 addition & 0 deletions packages/core/src/decorators/UseRequestContext.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { MikroORM } from '../MikroORM';
import { RequestContext } from '../utils/RequestContext';

/** @deprecated use `@CreateRequestContext()` instead, `@UseRequestContext()` will be removed in v6 */
export function UseRequestContext<T>(getContext?: MikroORM | ((type?: T) => MikroORM)): MethodDecorator {
return function (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/decorators/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ export * from './Embedded';
export * from './Filter';
export * from './Subscriber';
export * from './UseRequestContext';
export * from './CreateRequestContext';
export * from './hooks';
73 changes: 71 additions & 2 deletions tests/decorators.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
import { ManyToMany, ManyToOne, MikroORM, OneToMany, OneToOne, Property, MetadataStorage, ReferenceType, Utils, Subscriber, UseRequestContext } from '@mikro-orm/core';
import {
ManyToMany,
ManyToOne,
MikroORM,
OneToMany,
OneToOne,
Property,
MetadataStorage,
ReferenceType,
Utils,
Subscriber,
UseRequestContext,
CreateRequestContext,
} from '@mikro-orm/core';
import type { Dictionary } from '@mikro-orm/core';
import { Test } from './entities';

Expand All @@ -15,6 +28,37 @@ class TestClass {

constructor(private readonly orm: MikroORM) {}

@CreateRequestContext()
async asyncMethodReturnsValue() {
return TEST_VALUE;
}

@CreateRequestContext()
methodReturnsValue() {
return TEST_VALUE;
}

@CreateRequestContext()
async asyncMethodReturnsNothing() {
//
}

@CreateRequestContext()
methodReturnsNothing() {
//
}

@CreateRequestContext(() => DI.orm)
methodWithCallback() {
//
}

}

class TestClass2 {

constructor(private readonly orm: MikroORM) {}

@UseRequestContext()
async asyncMethodReturnsValue() {
return TEST_VALUE;
Expand Down Expand Up @@ -109,7 +153,7 @@ describe('decorators', () => {
expect(ret3).toBeUndefined();
});

test('UseRequestContext', async () => {
test('CreateRequestContext', async () => {
const orm = Object.create(MikroORM.prototype, { em: { value: { name: 'default', fork: jest.fn() } } });
const test = new TestClass(orm);

Expand All @@ -130,6 +174,31 @@ describe('decorators', () => {
const ret6 = await test2.methodWithCallback();
expect(ret6).toBeUndefined();

const err = '@CreateRequestContext() decorator can only be applied to methods of classes with `orm: MikroORM` property, or with a callback parameter like `@CreateRequestContext(() => orm)`';
await expect(test2.asyncMethodReturnsValue()).rejects.toThrow(err);
});

test('UseRequestContext', async () => {
const orm = Object.create(MikroORM.prototype, { em: { value: { name: 'default', fork: jest.fn() } } });
const test = new TestClass2(orm);

const ret1 = await test.asyncMethodReturnsValue();
expect(ret1).toEqual(TEST_VALUE);
const ret2 = await test.methodReturnsValue();
expect(ret2).toEqual(TEST_VALUE);
const ret3 = await test.asyncMethodReturnsNothing();
expect(ret3).toBeUndefined();
const ret4 = await test.methodReturnsNothing();
expect(ret4).toBeUndefined();
const ret5 = await test.methodWithCallback();
expect(ret5).toBeUndefined();

const notOrm = jest.fn() as unknown as MikroORM;
const test2 = new TestClass2(notOrm);
DI.orm = orm;
const ret6 = await test2.methodWithCallback();
expect(ret6).toBeUndefined();

const err = '@UseRequestContext() decorator can only be applied to methods of classes with `orm: MikroORM` property, or with a callback parameter like `@UseRequestContext(() => orm)`';
await expect(test2.asyncMethodReturnsValue()).rejects.toThrow(err);
});
Expand Down

0 comments on commit 280733f

Please sign in to comment.