Created
December 6, 2022 22:20
-
-
Save GrantJamesPowell/c0416d79cf0f265edccd97be6e8042a5 to your computer and use it in GitHub Desktop.
Typeorm Select
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Primitive, Simplify } from 'type-fest'; | |
import { | |
EntityManager, | |
EntityTarget, | |
FindOptionsOrder, | |
FindOptionsRelations, | |
FindOptionsWhere, | |
ObjectLiteral, | |
} from 'typeorm'; | |
export type Defined<T> = T extends undefined ? never : T; | |
declare const embeddedMarker: unique symbol; | |
export type Embedded<T = {}> = T & { [embeddedMarker]: true }; | |
export const embed = <T extends {}>(x: T): Embedded<T> => x as Embedded<T>; | |
type NonRelationProperty = Primitive | Function | Date | Embedded; | |
export type Selection<Entity> = FindOptionsRelations<Entity>; | |
export type ShouldKeepProperty< | |
Entity, | |
Relations extends FindOptionsRelations<Entity> | |
> = keyof { | |
[Property in keyof Entity as NonNullable<Entity[Property]> extends | |
| NonRelationProperty | |
| NonRelationProperty[] | |
? Property | |
: Relations[Property] extends true | object | |
? Property | |
: never]-?: unknown; | |
}; | |
export type SelectProperty< | |
Entity, | |
Relations extends Selection<Entity>, | |
Property extends keyof Entity | |
> = NonNullable<Entity[Property]> extends | |
| NonRelationProperty | |
| NonRelationProperty[] | |
? Defined<Entity[Property]> | |
: NonNullable<Entity[Property]> extends (infer Relation)[] | |
? Relations[Property] extends true | |
? Select<Relation, {}>[] | |
: Relations[Property] extends FindOptionsRelations<NonNullable<Relation>> | |
? Select<Relation, Relations[Property]>[] | |
: unknown | |
: Relations[Property] extends true | |
? Select<Defined<Entity[Property]>, {}> | |
: Relations[Property] extends FindOptionsRelations< | |
NonNullable<Defined<Entity[Property]>> | |
> | |
? Select<Defined<Entity[Property]>, Relations[Property]> | |
: unknown; | |
export type Select< | |
Entity, | |
Relations extends Selection<Entity> = {} | |
> = Simplify<{ | |
[Property in keyof Entity as Property extends ShouldKeepProperty< | |
Entity, | |
Relations | |
> | |
? Property | |
: never]-?: SelectProperty<Entity, Relations, Property>; | |
}>; | |
type Options<Entity, Relations extends FindOptionsRelations<Entity>> = { | |
relations?: Relations; | |
where?: FindOptionsWhere<Entity>; | |
order?: FindOptionsOrder<Entity>; | |
}; | |
export const select = async < | |
Entity extends ObjectLiteral, | |
Relations extends FindOptionsRelations<Entity> = {} | |
>( | |
db: EntityManager, | |
entity: EntityTarget<Entity>, | |
options?: Options<Entity, Relations> | |
): Promise<Select<Entity, Relations>[]> => | |
db.find(entity, options ?? {}) as any; | |
export const selectOne = async < | |
Entity extends ObjectLiteral, | |
Relations extends FindOptionsRelations<Entity> = {} | |
>( | |
db: EntityManager, | |
entity: EntityTarget<Entity>, | |
options?: Options<Entity, Relations> | |
): Promise<Select<Entity, Relations> | null> => | |
db.findOne(entity, options ?? {}) as any; | |
export const selectOneOrFail = async < | |
Entity extends ObjectLiteral, | |
Relations extends FindOptionsRelations<Entity> = {} | |
>( | |
db: EntityManager, | |
entity: EntityTarget<Entity>, | |
options?: Options<Entity, Relations> | |
): Promise<Select<Entity, Relations>> => | |
db.findOneOrFail(entity, options ?? {}) as any; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment