Skip to content

Commit

Permalink
continue repositories and types rework
Browse files Browse the repository at this point in the history
  • Loading branch information
adrien2p committed Nov 12, 2024
1 parent 27ea828 commit afd19d2
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 100 deletions.
4 changes: 2 additions & 2 deletions packages/core/types/src/dal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export interface BaseFilterable<T> {
/**
* The options to apply when retrieving an item.
*/
export interface OptionsQuery<T, P extends string = never> {
export interface OptionsQuery<T> {
/**
* Relations to populate in the retrieved items.
*/
Expand Down Expand Up @@ -73,7 +73,7 @@ export type FindOptions<T = any> = {
/**
* The options to apply when retrieving the items.
*/
options?: OptionsQuery<InferEntityType<T>, any>
options?: OptionsQuery<InferEntityType<T>>
}

/**
Expand Down
65 changes: 43 additions & 22 deletions packages/core/types/src/dal/repository-service.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
import { RepositoryTransformOptions } from "../common"
import { Context } from "../shared-context"
import {
BaseFilterable,
FilterQuery,
FilterQuery as InternalFilterQuery,
FindOptions,
UpsertWithReplaceConfig,
} from "./index"
import { EntityClass } from "@mikro-orm/core"
import { IDmlEntity, InferTypeOf } from "../dml"

type EntityClassName = string
type EntityValues = { id: string }[]

/**
* Either infer the properties from a DML object or from a Mikro orm class prototype.
*/
export type InferRepositoryReturnType<T> = T extends IDmlEntity<any, any>
? InferTypeOf<T>
: EntityClass<T>["prototype"]

export type PerformedActions = {
created: Record<EntityClassName, EntityValues>
updated: Record<EntityClassName, EntityValues>
Expand All @@ -22,7 +29,7 @@ export type PerformedActions = {
* This layer helps to separate the business logic (service layer) from accessing the
* ORM directly and allows to switch to another ORM without changing the business logic.
*/
interface BaseRepositoryService<T = any> {
interface BaseRepositoryService {
transaction<TManager = unknown>(
task: (transactionManager: TManager) => Promise<any>,
context?: {
Expand All @@ -42,22 +49,28 @@ interface BaseRepositoryService<T = any> {
): Promise<TOutput>
}

export interface RepositoryService<T = any> extends BaseRepositoryService<T> {
find(options?: FindOptions<T>, context?: Context): Promise<T[]>
export interface RepositoryService<T = any> extends BaseRepositoryService {
find(
options?: FindOptions<T>,
context?: Context
): Promise<InferRepositoryReturnType<T>[]>

findAndCount(
options?: FindOptions<T>,
context?: Context
): Promise<[T[], number]>

create(data: any[], context?: Context): Promise<T[]>
): Promise<[InferRepositoryReturnType<T>[], number]>

update(data: { entity; update }[], context?: Context): Promise<T[]>
create(
data: any[],
context?: Context
): Promise<InferRepositoryReturnType<T>[]>

delete(
idsOrPKs: FilterQuery<T> & BaseFilterable<FilterQuery<T>>,
update(
data: { entity; update }[],
context?: Context
): Promise<void>
): Promise<InferRepositoryReturnType<T>[]>

delete(idsOrPKs: FindOptions<T>["where"], context?: Context): Promise<void>

/**
* Soft delete entities and cascade to related entities if configured.
Expand All @@ -74,37 +87,45 @@ export interface RepositoryService<T = any> extends BaseRepositoryService<T> {
| InternalFilterQuery
| InternalFilterQuery[],
context?: Context
): Promise<[T[], Record<string, unknown[]>]>
): Promise<[InferRepositoryReturnType<T>[], Record<string, unknown[]>]>

restore(
idsOrFilter: string[] | InternalFilterQuery,
context?: Context
): Promise<[T[], Record<string, unknown[]>]>
): Promise<[InferRepositoryReturnType<T>[], Record<string, unknown[]>]>

upsert(data: any[], context?: Context): Promise<T[]>
upsert(
data: any[],
context?: Context
): Promise<InferRepositoryReturnType<T>[]>

upsertWithReplace(
data: any[],
config?: UpsertWithReplaceConfig<T>,
config?: UpsertWithReplaceConfig<InferRepositoryReturnType<T>>,
context?: Context
): Promise<{ entities: T[]; performedActions: PerformedActions }>
): Promise<{
entities: InferRepositoryReturnType<T>[]
performedActions: PerformedActions
}>
}

export interface TreeRepositoryService<T = any>
extends BaseRepositoryService<T> {
export interface TreeRepositoryService<T = any> extends BaseRepositoryService {
find(
options?: FindOptions<T>,
transformOptions?: RepositoryTransformOptions,
context?: Context
): Promise<T[]>
): Promise<InferRepositoryReturnType<T>[]>

findAndCount(
options?: FindOptions<T>,
transformOptions?: RepositoryTransformOptions,
context?: Context
): Promise<[T[], number]>
): Promise<[InferRepositoryReturnType<T>[], number]>

create(data: unknown[], context?: Context): Promise<T[]>
create(
data: unknown[],
context?: Context
): Promise<InferRepositoryReturnType<T>[]>

delete(ids: string[], context?: Context): Promise<void>
}
Expand Down
40 changes: 23 additions & 17 deletions packages/core/types/src/dal/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Constructor } from "../modules-sdk"

type ExpandProperty<T> = T extends (infer U)[] ? NonNullable<U> : NonNullable<T>

export type Dictionary<T = any> = {
Expand Down Expand Up @@ -84,25 +86,29 @@ type FilterValue<T> =

type PrevLimit = [never, 0, 1, 2]

export type FilterQueryProperties<T, Prev extends number = 3> = {
[Key in keyof T]?: T[Key] extends
| boolean
| number
| string
| bigint
| symbol
| Date
? T[Key] | OperatorMap<T[Key]>
: T[Key] extends infer U
? U extends { [x: number]: infer V }
? V extends object
? FilterQuery<Partial<V>, PrevLimit[Prev]>
: never
: never
: never
}

export type FilterQuery<T = any, Prev extends number = 3> = Prev extends never
? never
: {
[Key in keyof T]?: T[Key] extends
| boolean
| number
| string
| bigint
| symbol
| Date
? T[Key] | OperatorMap<T[Key]>
: T[Key] extends infer U
? U extends { [x: number]: infer V }
? V extends object
? FilterQuery<Partial<V>, PrevLimit[Prev]>
: never
: never
: never
}
: T extends Constructor<infer Prototype>
? FilterQueryProperties<Prototype, Prev>
: FilterQueryProperties<T, Prev>

declare type QueryOrder = "ASC" | "DESC" | "asc" | "desc"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,9 @@ class Entity3 {
}
}

const Entity1Repository = mikroOrmBaseRepositoryFactory<Entity1>(Entity1)
const Entity2Repository = mikroOrmBaseRepositoryFactory<Entity2>(Entity2)
const Entity3Repository = mikroOrmBaseRepositoryFactory<Entity3>(Entity3)
const Entity1Repository = mikroOrmBaseRepositoryFactory(Entity1)
const Entity2Repository = mikroOrmBaseRepositoryFactory(Entity2)
const Entity3Repository = mikroOrmBaseRepositoryFactory(Entity3)

describe("mikroOrmRepository", () => {
let orm!: MikroORM
Expand Down
Loading

0 comments on commit afd19d2

Please sign in to comment.