Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: support excludes syntax from latest v6 alpha #17

Merged
merged 1 commit into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/metal-toys-juggle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"mikro-orm-find-dataloader": minor
---

fix: support excludes syntax from latest v6 alpha
4 changes: 2 additions & 2 deletions examples/graphql/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
},
"dependencies": {
"@graphql-tools/executor-http": "^1.0.5",
"@mikro-orm/core": "6.0.0-dev.261",
"@mikro-orm/sqlite": "6.0.0-dev.261",
"@mikro-orm/core": "6.0.0-dev.283",
"@mikro-orm/sqlite": "6.0.0-dev.283",
"graphql": "16.8.1",
"graphql-tag": "^2.12.6",
"graphql-yoga": "5.0.2",
Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@
"@changesets/cli": "^2.27.1",
"@types/eslint": "^8.44.9",
"@types/jest": "^29.5.11",
"@types/node": "^20.10.4",
"@typescript-eslint/eslint-plugin": "^6.14.0",
"@typescript-eslint/parser": "^6.14.0",
"eslint": "^8.55.0",
"@types/node": "^20.10.5",
"@typescript-eslint/eslint-plugin": "^6.15.0",
"@typescript-eslint/parser": "^6.15.0",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-config-standard-with-typescript": "^42.0.0",
"eslint-plugin-import": "^2.29.0",
"eslint-config-standard-with-typescript": "^43.0.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-jest": "^27.6.0",
"eslint-plugin-n": "^16.4.0",
"eslint-plugin-prettier": "^5.0.1",
Expand Down
4 changes: 2 additions & 2 deletions packages/find/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"tslib": "2.6.2"
},
"devDependencies": {
"@mikro-orm/core": "6.0.0-dev.261",
"@mikro-orm/sqlite": "6.0.0-dev.261"
"@mikro-orm/core": "6.0.0-dev.283",
"@mikro-orm/sqlite": "6.0.0-dev.283"
}
}
30 changes: 19 additions & 11 deletions packages/find/src/findDataloader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
type FilterItemValue,
type Scalar,
type ExpandProperty,
type ExpandQuery,
type ExpandScalar,
type EntityProps,
type EntityManager,
Expand All @@ -25,12 +24,15 @@ import type DataLoader from "dataloader";

export interface OperatorMapDataloader<T> {
// $and?: ExpandQuery<T>[];
$or?: Array<ExpandQuery<T>>;
$or?: Array<ExpandQueryDataloader<T>>;
// $eq?: ExpandScalar<T> | ExpandScalar<T>[];
// $ne?: ExpandScalar<T>;
// $in?: ExpandScalar<T>[];
// $nin?: ExpandScalar<T>[];
// $not?: ExpandQuery<T>;
// $none?: ExpandQuery<T>;
// $some?: ExpandQuery<T>;
// $every?: ExpandQuery<T>;
// $gt?: ExpandScalar<T>;
// $gte?: ExpandScalar<T>;
// $lt?: ExpandScalar<T>;
Expand All @@ -39,34 +41,36 @@ export interface OperatorMapDataloader<T> {
// $re?: string;
// $ilike?: string;
// $fulltext?: string;
// $overlap?: string[];
// $contains?: string[];
// $contained?: string[];
// $overlap?: string[] | object;
// $contains?: string[] | object;
// $contained?: string[] | object;
// $exists?: boolean;
}

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

export type QueryDataloader<T> = T extends object
export type ExpandQueryDataloader<T> = T extends object
? T extends Scalar
? never
: FilterQueryDataloader<T>
: FilterValueDataloader<T>;

export type FilterObjectDataloader<T> = {
-readonly [K in EntityKey<T>]?:
| QueryDataloader<ExpandProperty<T[K]>>
| ExpandQueryDataloader<ExpandProperty<T[K]>>
| FilterValueDataloader<ExpandProperty<T[K]>>
| null;
};

export type Compute<T> = {
[K in keyof T]: T[K];
} & {};
export type ExpandObjectDataloader<T> = T extends object
? T extends Scalar
? never
: FilterObjectDataloader<T>
: never;

export type ObjectQueryDataloader<T> = Compute<OperatorMapDataloader<T> & FilterObjectDataloader<T>>;
export type ObjectQueryDataloader<T> = OperatorMapDataloader<T> & ExpandObjectDataloader<T>;

// FilterQuery<T>
export type FilterQueryDataloader<T extends object> =
Expand Down Expand Up @@ -360,6 +364,7 @@ function updateQueryFilter<K extends object, P extends string = never>(
const curValue = (cur as Record<string, any[]>)[key]!;
if (Array.isArray(value)) {
// value.push(...curValue.reduce<any[]>((acc, cur) => acc.concat(cur), []));
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
value.push(...structuredClone(curValue));
} else {
updateQueryFilter([value], curValue);
Expand Down Expand Up @@ -465,6 +470,7 @@ export function getFindBatchLoadFn<Entity extends object>(
const res = entities[many ? "filter" : "find"]((entity) => {
return filterResult(entity, newFilter);
});
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
acc.push(...(Array.isArray(res) ? res : [res]));
return acc;
}, []);
Expand Down Expand Up @@ -493,6 +499,7 @@ export function getFindBatchLoadFn<Entity extends object>(
if (!entityValue.getItems().some((entity) => filterResult(entity, value))) {
return false;
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
} else if (!filterResult(entityValue as object, value)) {
return false;
}
Expand All @@ -514,6 +521,7 @@ export function optsMapToQueries<Entity extends object>(
populate: options.populate === true ? ["*"] : Array.from(options.populate),
}),
} satisfies Pick<FindOptions<any, any>, "populate">;
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
const entities = await em.find(entityName, filter, findOptions);
return [key, entities];
});
Expand Down
100 changes: 52 additions & 48 deletions packages/find/src/findRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,50 +17,50 @@ export interface IFindDataloaderEntityRepository<Entity extends object, D extend
extends EntityRepository<Entity> {
readonly dataloader: D;

find<Hint extends string = never, Fields extends string = never>(
find<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
where: FilterQuery<Entity>,
options?: { dataloader: false } & FindOptions<Entity, Hint, Fields>,
): Promise<Array<Loaded<Entity, Hint, Fields>>>;
find<Hint extends string = never, Fields extends string = never>(
options?: { dataloader: false } & FindOptions<Entity, Hint, Fields, Excludes>,
): Promise<Array<Loaded<Entity, Hint, Fields, Excludes>>>;
find<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
where: FilterQueryDataloader<Entity>,
options?: { dataloader: boolean } & Pick<FindOptions<Entity, Hint, Fields>, "populate">,
): Promise<Array<Loaded<Entity, Hint, Fields>>>;
find<Hint extends string = never, Fields extends string = never>(
options?: { dataloader: boolean } & Pick<FindOptions<Entity, Hint, Fields, Excludes>, "populate">,
): Promise<Array<Loaded<Entity, Hint, Fields, Excludes>>>;
find<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
where: D extends true ? FilterQueryDataloader<Entity> : FilterQueryDataloader<Entity> | FilterQuery<Entity>,
options?: { dataloader?: undefined } & (D extends true
? Pick<FindOptions<Entity, Hint, Fields>, "populate">
: FindOptions<Entity, Hint, Fields>),
): Promise<Array<Loaded<Entity, Hint, Fields>>>;
? Pick<FindOptions<Entity, Hint, Fields, Excludes>, "populate">
: FindOptions<Entity, Hint, Fields, Excludes>),
): Promise<Array<Loaded<Entity, Hint, Fields, Excludes>>>;

findOne<Hint extends string = never, Fields extends string = never>(
findOne<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
where: FilterQuery<Entity>,
options?: { dataloader: false } & FindOneOptions<Entity, Hint, Fields>,
): Promise<Loaded<Entity, Hint, Fields> | null>;
findOne<Hint extends string = never, Fields extends string = never>(
options?: { dataloader: false } & FindOneOptions<Entity, Hint, Fields, Excludes>,
): Promise<Loaded<Entity, Hint, Fields, Excludes> | null>;
findOne<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
where: FilterQueryDataloader<Entity>,
options?: { dataloader: boolean } & Pick<FindOneOptions<Entity, Hint, Fields>, "populate">,
): Promise<Loaded<Entity, Hint, Fields> | null>;
findOne<Hint extends string = never, Fields extends string = never>(
options?: { dataloader: boolean } & Pick<FindOneOptions<Entity, Hint, Fields, Excludes>, "populate">,
): Promise<Loaded<Entity, Hint, Fields, Excludes> | null>;
findOne<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
where: D extends true ? FilterQueryDataloader<Entity> : FilterQueryDataloader<Entity> | FilterQuery<Entity>,
options?: { dataloader?: undefined } & (D extends true
? Pick<FindOneOptions<Entity, Hint, Fields>, "populate">
: FindOneOptions<Entity, Hint, Fields>),
): Promise<Loaded<Entity, Hint, Fields> | null>;
? Pick<FindOneOptions<Entity, Hint, Fields, Excludes>, "populate">
: FindOneOptions<Entity, Hint, Fields, Excludes>),
): Promise<Loaded<Entity, Hint, Fields, Excludes> | null>;

findOneOrFail<Hint extends string = never, Fields extends string = never>(
findOneOrFail<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
where: FilterQuery<Entity>,
options?: { dataloader: false } & FindOneOrFailOptions<Entity, Hint, Fields>,
): Promise<Loaded<Entity, Hint, Fields>>;
findOneOrFail<Hint extends string = never, Fields extends string = never>(
options?: { dataloader: false } & FindOneOrFailOptions<Entity, Hint, Fields, Excludes>,
): Promise<Loaded<Entity, Hint, Fields, Excludes>>;
findOneOrFail<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
where: FilterQueryDataloader<Entity>,
options?: { dataloader: boolean } & Pick<FindOneOrFailOptions<Entity, Hint, Fields>, "populate">,
): Promise<Loaded<Entity, Hint, Fields>>;
findOneOrFail<Hint extends string = never, Fields extends string = never>(
options?: { dataloader: boolean } & Pick<FindOneOrFailOptions<Entity, Hint, Fields, Excludes>, "populate">,
): Promise<Loaded<Entity, Hint, Fields, Excludes>>;
findOneOrFail<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
where: D extends true ? FilterQueryDataloader<Entity> : FilterQueryDataloader<Entity> | FilterQuery<Entity>,
options?: { dataloader?: undefined } & (D extends true
? Pick<FindOneOrFailOptions<Entity, Hint, Fields>, "populate">
: FindOneOrFailOptions<Entity, Hint, Fields>),
): Promise<Loaded<Entity, Hint, Fields>>;
? Pick<FindOneOrFailOptions<Entity, Hint, Fields, Excludes>, "populate">
: FindOneOrFailOptions<Entity, Hint, Fields, Excludes>),
): Promise<Loaded<Entity, Hint, Fields, Excludes>>;
}

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

async find<Hint extends string = never, Fields extends string = never>(
async find<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
where: FilterQueryDataloader<Entity> | FilterQuery<Entity>,
options?: { dataloader?: boolean } & (
| Pick<FindOptions<Entity, Hint, Fields>, "populate">
| FindOptions<Entity, Hint, Fields>
| Pick<FindOptions<Entity, Hint, Fields, Excludes>, "populate">
| FindOptions<Entity, Hint, Fields, Excludes>
),
): Promise<Array<Loaded<Entity, Hint, Fields>>> {
): Promise<Array<Loaded<Entity, Hint, Fields, Excludes>>> {
const entityName = Utils.className(this.entityName);
const res = await (options?.dataloader ?? this.dataloader
? this.findLoader.load({
Expand All @@ -94,17 +94,17 @@ export function getFindDataloaderEntityRepository<Entity extends object, D exten
options,
many: true,
})
: this.em.find<Entity, Hint, Fields>(this.entityName, where as FilterQuery<Entity>, options));
return res as Array<Loaded<Entity, Hint, Fields>>;
: this.em.find<Entity, Hint, Fields, Excludes>(this.entityName, where as FilterQuery<Entity>, options));
return res as Array<Loaded<Entity, Hint, Fields, Excludes>>;
}

async findOne<Hint extends string = never, Fields extends string = never>(
async findOne<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
where: FilterQueryDataloader<Entity> | FilterQuery<Entity>,
options?: { dataloader?: boolean } & (
| Pick<FindOneOptions<Entity, Hint, Fields>, "populate">
| FindOneOptions<Entity, Hint, Fields>
| Pick<FindOneOptions<Entity, Hint, Fields, Excludes>, "populate">
| FindOneOptions<Entity, Hint, Fields, Excludes>
),
): Promise<Loaded<Entity, Hint, Fields> | null> {
): Promise<Loaded<Entity, Hint, Fields, Excludes> | null> {
const entityName = Utils.className(this.entityName);
const res = await (options?.dataloader ?? this.dataloader
? this.findLoader.load({
Expand All @@ -114,17 +114,17 @@ export function getFindDataloaderEntityRepository<Entity extends object, D exten
options,
many: false,
})
: this.em.findOne<Entity, Hint, Fields>(this.entityName, where as FilterQuery<Entity>, options));
return res as Loaded<Entity, Hint, Fields> | null;
: this.em.findOne<Entity, Hint, Fields, Excludes>(this.entityName, where as FilterQuery<Entity>, options));
return res as Loaded<Entity, Hint, Fields, Excludes> | null;
}

async findOneOrFail<Hint extends string = never, Fields extends string = never>(
async findOneOrFail<Hint extends string = never, Fields extends string = "*", Excludes extends string = never>(
where: FilterQueryDataloader<Entity> | FilterQuery<Entity>,
options?: { dataloader?: boolean } & (
| Pick<FindOneOrFailOptions<Entity, Hint, Fields>, "populate">
| FindOneOrFailOptions<Entity, Hint, Fields>
| Pick<FindOneOrFailOptions<Entity, Hint, Fields, Excludes>, "populate">
| FindOneOrFailOptions<Entity, Hint, Fields, Excludes>
),
): Promise<Loaded<Entity, Hint, Fields>> {
): Promise<Loaded<Entity, Hint, Fields, Excludes>> {
const entityName = Utils.className(this.entityName);
const res = await (options?.dataloader ?? this.dataloader
? this.findLoader.load({
Expand All @@ -134,11 +134,15 @@ export function getFindDataloaderEntityRepository<Entity extends object, D exten
options,
many: false,
})
: this.em.findOneOrFail<Entity, Hint, Fields>(this.entityName, where as FilterQuery<Entity>, options));
: this.em.findOneOrFail<Entity, Hint, Fields, Excludes>(
this.entityName,
where as FilterQuery<Entity>,
options,
));
if (res == null) {
throw new Error("Cannot find result");
}
return res as Loaded<Entity, Hint, Fields>;
return res as Loaded<Entity, Hint, Fields, Excludes>;
}
}

Expand Down
Loading
Loading