Skip to content

Commit bbe8222

Browse files
authored
fix: support excludes syntax from latest v6 alpha (#17)
1 parent 34048ce commit bbe8222

File tree

7 files changed

+212
-195
lines changed

7 files changed

+212
-195
lines changed

.changeset/metal-toys-juggle.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"mikro-orm-find-dataloader": minor
3+
---
4+
5+
fix: support excludes syntax from latest v6 alpha

examples/graphql/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
},
1818
"dependencies": {
1919
"@graphql-tools/executor-http": "^1.0.5",
20-
"@mikro-orm/core": "6.0.0-dev.261",
21-
"@mikro-orm/sqlite": "6.0.0-dev.261",
20+
"@mikro-orm/core": "6.0.0-dev.283",
21+
"@mikro-orm/sqlite": "6.0.0-dev.283",
2222
"graphql": "16.8.1",
2323
"graphql-tag": "^2.12.6",
2424
"graphql-yoga": "5.0.2",

package.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@
2626
"@changesets/cli": "^2.27.1",
2727
"@types/eslint": "^8.44.9",
2828
"@types/jest": "^29.5.11",
29-
"@types/node": "^20.10.4",
30-
"@typescript-eslint/eslint-plugin": "^6.14.0",
31-
"@typescript-eslint/parser": "^6.14.0",
32-
"eslint": "^8.55.0",
29+
"@types/node": "^20.10.5",
30+
"@typescript-eslint/eslint-plugin": "^6.15.0",
31+
"@typescript-eslint/parser": "^6.15.0",
32+
"eslint": "^8.56.0",
3333
"eslint-config-prettier": "^9.1.0",
34-
"eslint-config-standard-with-typescript": "^42.0.0",
35-
"eslint-plugin-import": "^2.29.0",
34+
"eslint-config-standard-with-typescript": "^43.0.0",
35+
"eslint-plugin-import": "^2.29.1",
3636
"eslint-plugin-jest": "^27.6.0",
3737
"eslint-plugin-n": "^16.4.0",
3838
"eslint-plugin-prettier": "^5.0.1",

packages/find/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
"tslib": "2.6.2"
5555
},
5656
"devDependencies": {
57-
"@mikro-orm/core": "6.0.0-dev.261",
58-
"@mikro-orm/sqlite": "6.0.0-dev.261"
57+
"@mikro-orm/core": "6.0.0-dev.283",
58+
"@mikro-orm/sqlite": "6.0.0-dev.283"
5959
}
6060
}

packages/find/src/findDataloader.ts

+19-11
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {
1111
type FilterItemValue,
1212
type Scalar,
1313
type ExpandProperty,
14-
type ExpandQuery,
1514
type ExpandScalar,
1615
type EntityProps,
1716
type EntityManager,
@@ -25,12 +24,15 @@ import type DataLoader from "dataloader";
2524

2625
export interface OperatorMapDataloader<T> {
2726
// $and?: ExpandQuery<T>[];
28-
$or?: Array<ExpandQuery<T>>;
27+
$or?: Array<ExpandQueryDataloader<T>>;
2928
// $eq?: ExpandScalar<T> | ExpandScalar<T>[];
3029
// $ne?: ExpandScalar<T>;
3130
// $in?: ExpandScalar<T>[];
3231
// $nin?: ExpandScalar<T>[];
3332
// $not?: ExpandQuery<T>;
33+
// $none?: ExpandQuery<T>;
34+
// $some?: ExpandQuery<T>;
35+
// $every?: ExpandQuery<T>;
3436
// $gt?: ExpandScalar<T>;
3537
// $gte?: ExpandScalar<T>;
3638
// $lt?: ExpandScalar<T>;
@@ -39,34 +41,36 @@ export interface OperatorMapDataloader<T> {
3941
// $re?: string;
4042
// $ilike?: string;
4143
// $fulltext?: string;
42-
// $overlap?: string[];
43-
// $contains?: string[];
44-
// $contained?: string[];
44+
// $overlap?: string[] | object;
45+
// $contains?: string[] | object;
46+
// $contained?: string[] | object;
4547
// $exists?: boolean;
4648
}
4749

4850
export type FilterValueDataloader<T> =
4951
/* OperatorMapDataloader<FilterItemValue<T>> | */
5052
FilterItemValue<T> | FilterItemValue<T>[] | null;
5153

52-
export type QueryDataloader<T> = T extends object
54+
export type ExpandQueryDataloader<T> = T extends object
5355
? T extends Scalar
5456
? never
5557
: FilterQueryDataloader<T>
5658
: FilterValueDataloader<T>;
5759

5860
export type FilterObjectDataloader<T> = {
5961
-readonly [K in EntityKey<T>]?:
60-
| QueryDataloader<ExpandProperty<T[K]>>
62+
| ExpandQueryDataloader<ExpandProperty<T[K]>>
6163
| FilterValueDataloader<ExpandProperty<T[K]>>
6264
| null;
6365
};
6466

65-
export type Compute<T> = {
66-
[K in keyof T]: T[K];
67-
} & {};
67+
export type ExpandObjectDataloader<T> = T extends object
68+
? T extends Scalar
69+
? never
70+
: FilterObjectDataloader<T>
71+
: never;
6872

69-
export type ObjectQueryDataloader<T> = Compute<OperatorMapDataloader<T> & FilterObjectDataloader<T>>;
73+
export type ObjectQueryDataloader<T> = OperatorMapDataloader<T> & ExpandObjectDataloader<T>;
7074

7175
// FilterQuery<T>
7276
export type FilterQueryDataloader<T extends object> =
@@ -360,6 +364,7 @@ function updateQueryFilter<K extends object, P extends string = never>(
360364
const curValue = (cur as Record<string, any[]>)[key]!;
361365
if (Array.isArray(value)) {
362366
// value.push(...curValue.reduce<any[]>((acc, cur) => acc.concat(cur), []));
367+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
363368
value.push(...structuredClone(curValue));
364369
} else {
365370
updateQueryFilter([value], curValue);
@@ -465,6 +470,7 @@ export function getFindBatchLoadFn<Entity extends object>(
465470
const res = entities[many ? "filter" : "find"]((entity) => {
466471
return filterResult(entity, newFilter);
467472
});
473+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
468474
acc.push(...(Array.isArray(res) ? res : [res]));
469475
return acc;
470476
}, []);
@@ -493,6 +499,7 @@ export function getFindBatchLoadFn<Entity extends object>(
493499
if (!entityValue.getItems().some((entity) => filterResult(entity, value))) {
494500
return false;
495501
}
502+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
496503
} else if (!filterResult(entityValue as object, value)) {
497504
return false;
498505
}
@@ -514,6 +521,7 @@ export function optsMapToQueries<Entity extends object>(
514521
populate: options.populate === true ? ["*"] : Array.from(options.populate),
515522
}),
516523
} satisfies Pick<FindOptions<any, any>, "populate">;
524+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
517525
const entities = await em.find(entityName, filter, findOptions);
518526
return [key, entities];
519527
});

packages/find/src/findRepository.ts

+52-48
Original file line numberDiff line numberDiff line change
@@ -17,50 +17,50 @@ export interface IFindDataloaderEntityRepository<Entity extends object, D extend
1717
extends EntityRepository<Entity> {
1818
readonly dataloader: D;
1919

20-
find<Hint extends string = never, Fields extends string = never>(
20+
find<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
2121
where: FilterQuery<Entity>,
22-
options?: { dataloader: false } & FindOptions<Entity, Hint, Fields>,
23-
): Promise<Array<Loaded<Entity, Hint, Fields>>>;
24-
find<Hint extends string = never, Fields extends string = never>(
22+
options?: { dataloader: false } & FindOptions<Entity, Hint, Fields, Excludes>,
23+
): Promise<Array<Loaded<Entity, Hint, Fields, Excludes>>>;
24+
find<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
2525
where: FilterQueryDataloader<Entity>,
26-
options?: { dataloader: boolean } & Pick<FindOptions<Entity, Hint, Fields>, "populate">,
27-
): Promise<Array<Loaded<Entity, Hint, Fields>>>;
28-
find<Hint extends string = never, Fields extends string = never>(
26+
options?: { dataloader: boolean } & Pick<FindOptions<Entity, Hint, Fields, Excludes>, "populate">,
27+
): Promise<Array<Loaded<Entity, Hint, Fields, Excludes>>>;
28+
find<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
2929
where: D extends true ? FilterQueryDataloader<Entity> : FilterQueryDataloader<Entity> | FilterQuery<Entity>,
3030
options?: { dataloader?: undefined } & (D extends true
31-
? Pick<FindOptions<Entity, Hint, Fields>, "populate">
32-
: FindOptions<Entity, Hint, Fields>),
33-
): Promise<Array<Loaded<Entity, Hint, Fields>>>;
31+
? Pick<FindOptions<Entity, Hint, Fields, Excludes>, "populate">
32+
: FindOptions<Entity, Hint, Fields, Excludes>),
33+
): Promise<Array<Loaded<Entity, Hint, Fields, Excludes>>>;
3434

35-
findOne<Hint extends string = never, Fields extends string = never>(
35+
findOne<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
3636
where: FilterQuery<Entity>,
37-
options?: { dataloader: false } & FindOneOptions<Entity, Hint, Fields>,
38-
): Promise<Loaded<Entity, Hint, Fields> | null>;
39-
findOne<Hint extends string = never, Fields extends string = never>(
37+
options?: { dataloader: false } & FindOneOptions<Entity, Hint, Fields, Excludes>,
38+
): Promise<Loaded<Entity, Hint, Fields, Excludes> | null>;
39+
findOne<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
4040
where: FilterQueryDataloader<Entity>,
41-
options?: { dataloader: boolean } & Pick<FindOneOptions<Entity, Hint, Fields>, "populate">,
42-
): Promise<Loaded<Entity, Hint, Fields> | null>;
43-
findOne<Hint extends string = never, Fields extends string = never>(
41+
options?: { dataloader: boolean } & Pick<FindOneOptions<Entity, Hint, Fields, Excludes>, "populate">,
42+
): Promise<Loaded<Entity, Hint, Fields, Excludes> | null>;
43+
findOne<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
4444
where: D extends true ? FilterQueryDataloader<Entity> : FilterQueryDataloader<Entity> | FilterQuery<Entity>,
4545
options?: { dataloader?: undefined } & (D extends true
46-
? Pick<FindOneOptions<Entity, Hint, Fields>, "populate">
47-
: FindOneOptions<Entity, Hint, Fields>),
48-
): Promise<Loaded<Entity, Hint, Fields> | null>;
46+
? Pick<FindOneOptions<Entity, Hint, Fields, Excludes>, "populate">
47+
: FindOneOptions<Entity, Hint, Fields, Excludes>),
48+
): Promise<Loaded<Entity, Hint, Fields, Excludes> | null>;
4949

50-
findOneOrFail<Hint extends string = never, Fields extends string = never>(
50+
findOneOrFail<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
5151
where: FilterQuery<Entity>,
52-
options?: { dataloader: false } & FindOneOrFailOptions<Entity, Hint, Fields>,
53-
): Promise<Loaded<Entity, Hint, Fields>>;
54-
findOneOrFail<Hint extends string = never, Fields extends string = never>(
52+
options?: { dataloader: false } & FindOneOrFailOptions<Entity, Hint, Fields, Excludes>,
53+
): Promise<Loaded<Entity, Hint, Fields, Excludes>>;
54+
findOneOrFail<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
5555
where: FilterQueryDataloader<Entity>,
56-
options?: { dataloader: boolean } & Pick<FindOneOrFailOptions<Entity, Hint, Fields>, "populate">,
57-
): Promise<Loaded<Entity, Hint, Fields>>;
58-
findOneOrFail<Hint extends string = never, Fields extends string = never>(
56+
options?: { dataloader: boolean } & Pick<FindOneOrFailOptions<Entity, Hint, Fields, Excludes>, "populate">,
57+
): Promise<Loaded<Entity, Hint, Fields, Excludes>>;
58+
findOneOrFail<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
5959
where: D extends true ? FilterQueryDataloader<Entity> : FilterQueryDataloader<Entity> | FilterQuery<Entity>,
6060
options?: { dataloader?: undefined } & (D extends true
61-
? Pick<FindOneOrFailOptions<Entity, Hint, Fields>, "populate">
62-
: FindOneOrFailOptions<Entity, Hint, Fields>),
63-
): Promise<Loaded<Entity, Hint, Fields>>;
61+
? Pick<FindOneOrFailOptions<Entity, Hint, Fields, Excludes>, "populate">
62+
: FindOneOrFailOptions<Entity, Hint, Fields, Excludes>),
63+
): Promise<Loaded<Entity, Hint, Fields, Excludes>>;
6464
}
6565

6666
export type FindDataloaderEntityRepositoryCtor<Entity extends object, D extends boolean> = new (
@@ -78,13 +78,13 @@ export function getFindDataloaderEntityRepository<Entity extends object, D exten
7878
readonly dataloader = defaultEnabled;
7979
private readonly findLoader = new DataLoader(getFindBatchLoadFn(this.em, this.entityName));
8080

81-
async find<Hint extends string = never, Fields extends string = never>(
81+
async find<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
8282
where: FilterQueryDataloader<Entity> | FilterQuery<Entity>,
8383
options?: { dataloader?: boolean } & (
84-
| Pick<FindOptions<Entity, Hint, Fields>, "populate">
85-
| FindOptions<Entity, Hint, Fields>
84+
| Pick<FindOptions<Entity, Hint, Fields, Excludes>, "populate">
85+
| FindOptions<Entity, Hint, Fields, Excludes>
8686
),
87-
): Promise<Array<Loaded<Entity, Hint, Fields>>> {
87+
): Promise<Array<Loaded<Entity, Hint, Fields, Excludes>>> {
8888
const entityName = Utils.className(this.entityName);
8989
const res = await (options?.dataloader ?? this.dataloader
9090
? this.findLoader.load({
@@ -94,17 +94,17 @@ export function getFindDataloaderEntityRepository<Entity extends object, D exten
9494
options,
9595
many: true,
9696
})
97-
: this.em.find<Entity, Hint, Fields>(this.entityName, where as FilterQuery<Entity>, options));
98-
return res as Array<Loaded<Entity, Hint, Fields>>;
97+
: this.em.find<Entity, Hint, Fields, Excludes>(this.entityName, where as FilterQuery<Entity>, options));
98+
return res as Array<Loaded<Entity, Hint, Fields, Excludes>>;
9999
}
100100

101-
async findOne<Hint extends string = never, Fields extends string = never>(
101+
async findOne<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
102102
where: FilterQueryDataloader<Entity> | FilterQuery<Entity>,
103103
options?: { dataloader?: boolean } & (
104-
| Pick<FindOneOptions<Entity, Hint, Fields>, "populate">
105-
| FindOneOptions<Entity, Hint, Fields>
104+
| Pick<FindOneOptions<Entity, Hint, Fields, Excludes>, "populate">
105+
| FindOneOptions<Entity, Hint, Fields, Excludes>
106106
),
107-
): Promise<Loaded<Entity, Hint, Fields> | null> {
107+
): Promise<Loaded<Entity, Hint, Fields, Excludes> | null> {
108108
const entityName = Utils.className(this.entityName);
109109
const res = await (options?.dataloader ?? this.dataloader
110110
? this.findLoader.load({
@@ -114,17 +114,17 @@ export function getFindDataloaderEntityRepository<Entity extends object, D exten
114114
options,
115115
many: false,
116116
})
117-
: this.em.findOne<Entity, Hint, Fields>(this.entityName, where as FilterQuery<Entity>, options));
118-
return res as Loaded<Entity, Hint, Fields> | null;
117+
: this.em.findOne<Entity, Hint, Fields, Excludes>(this.entityName, where as FilterQuery<Entity>, options));
118+
return res as Loaded<Entity, Hint, Fields, Excludes> | null;
119119
}
120120

121-
async findOneOrFail<Hint extends string = never, Fields extends string = never>(
121+
async findOneOrFail<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
122122
where: FilterQueryDataloader<Entity> | FilterQuery<Entity>,
123123
options?: { dataloader?: boolean } & (
124-
| Pick<FindOneOrFailOptions<Entity, Hint, Fields>, "populate">
125-
| FindOneOrFailOptions<Entity, Hint, Fields>
124+
| Pick<FindOneOrFailOptions<Entity, Hint, Fields, Excludes>, "populate">
125+
| FindOneOrFailOptions<Entity, Hint, Fields, Excludes>
126126
),
127-
): Promise<Loaded<Entity, Hint, Fields>> {
127+
): Promise<Loaded<Entity, Hint, Fields, Excludes>> {
128128
const entityName = Utils.className(this.entityName);
129129
const res = await (options?.dataloader ?? this.dataloader
130130
? this.findLoader.load({
@@ -134,11 +134,15 @@ export function getFindDataloaderEntityRepository<Entity extends object, D exten
134134
options,
135135
many: false,
136136
})
137-
: this.em.findOneOrFail<Entity, Hint, Fields>(this.entityName, where as FilterQuery<Entity>, options));
137+
: this.em.findOneOrFail<Entity, Hint, Fields, Excludes>(
138+
this.entityName,
139+
where as FilterQuery<Entity>,
140+
options,
141+
));
138142
if (res == null) {
139143
throw new Error("Cannot find result");
140144
}
141-
return res as Loaded<Entity, Hint, Fields>;
145+
return res as Loaded<Entity, Hint, Fields, Excludes>;
142146
}
143147
}
144148

0 commit comments

Comments
 (0)