How to query the related in-depth data in typeORM?

I currently have six table instances: module, codefunc, link, combo, node, and edge.

And there are the following relationships:

module 1:1 combo
codefunc 1:1 node
link 1:1 edge

enter image description here

The detail typeORM entities:

@Entity()
@Unique(['path', 'moduleName'])
export class ComboModule {
  @PrimaryGeneratedColumn()
  id: number | undefined

  // Combo
  @OneToOne(type => Combo)
  @JoinColumn()
  combo: Combo | undefined;

  @Column({
    type: 'varchar',
  })
  path: string

  @Column({
    type: 'varchar',
  })
  moduleName: string

  @Column({
    type: 'text'
  })
  desc?: string

  @ManyToOne(type => ComboModule)
  parent?: ComboModule | null

  @OneToMany(type => NodeCodeFunc, codeFunc => codeFunc.module)
  codeFuncs: NodeCodeFunc[] | undefined

  @Column({
    default: false,
    type: 'boolean'
  })
  isDeleted: boolean | undefined

  @CreateDateColumn()
  createDate?: Date

  @UpdateDateColumn()
  updateDate?: Date

  constructor(moduleName: string = '', path: string, desc: string | undefined = '',  parent: ComboModule| null) {

    this.moduleName = moduleName
    this.desc = desc
    this.path = path
    this.parent = parent
  }
}


@Entity()
export class EdgeCommonSupport {
  @PrimaryGeneratedColumn()
  id: number | undefined

  // Combo
  @OneToOne(type => Edge)
  @JoinColumn()
  edge: Edge | undefined;

  @Column({
    type: 'varchar',
    default: 'support' 
  })
  supportName: string | undefined

  @Column({
    type: 'text'
  })
  desc?: string

  @Column({
    default: false,
    type: 'boolean'
  })
  isDeleted: boolean | undefined

  @CreateDateColumn()
  createDate?: Date

  @UpdateDateColumn()
  updateDate?: Date

  constructor(supportName: string = '', desc: string | undefined = '' ) {
    this.supportName = supportName
    this.desc = desc
  }
}

@Entity()
@Unique(['path', 'codefuncName'])
export class NodeCodeFunc {
  @PrimaryGeneratedColumn()
  id: number | undefined

  // Combo
  @OneToOne(type => Node)
  @JoinColumn()
  node: Node | undefined;

  @Column({
    type: 'varchar',
  })
  path: string | undefined

  @Column({
    type: 'varchar',
  })
  codefuncName: string

  @Column({
    type: 'text'
  })
  desc?: string

  @ManyToOne(type => ComboModule, module => module.codeFuncs)
  module: ComboModule | null

  @Column({
    default: false,
    type: 'boolean'
  })
  isDeleted: boolean | undefined

  @CreateDateColumn()
  createDate?: Date

  @UpdateDateColumn()
  updateDate?: Date

  constructor(path: string, codefuncName: string = '', desc: string | undefined = '', module: ComboModule | null) {

    this.path = path
    this.codefuncName = codefuncName
    this.desc = desc
    this.module = module
  }
}


@Entity()
export class Node {
  @PrimaryGeneratedColumn()
  id: number | undefined

  // ProjMod
  @ManyToOne(type => ProjMod, projMod => projMod.Nodes)
  projMod: ProjMod

  @Column({
    default: false,
    type: 'boolean'
  })
  isDeleted: boolean | undefined

  @CreateDateColumn()
  createDate?: Date

  @UpdateDateColumn()
  updateDate?: Date

  constructor(projMod: ProjMod) {
    this.projMod = projMod
  }
}

export const EdgeConnectType = {
  NodeToNode: 'NodeToNode',
  NodeToCombo: 'NodeToCombo',
  ComboToCombo: 'ComboToCombo',
  ComboToNode: 'ComboToNode'
}

@Entity()
export class Edge {
  @PrimaryGeneratedColumn()
  id: number | undefined

  // ProjMod
  @ManyToOne(type => ProjMod, projMod => projMod.Nodes)
  projMod: ProjMod

  @Column({
    type: 'varchar',
    nullable: true,
    default: EdgeConnectType.NodeToNode
  })
  connecttype: string | undefined

  // Node:source
  @OneToOne(type => Node)
  @JoinColumn()
  NodeSource?: Node

  // Node:target
  @OneToOne(type => Node)
  @JoinColumn()
  NodeTarget?: Node

  // Combo:source
  @OneToOne(type => Combo)
  @JoinColumn()
  ComboSource?: Combo

  // Combo:target
  @OneToOne(type => Combo)
  @JoinColumn()
  ComboTarget?: Combo

  @Column({
    default: false,
    type: 'boolean'
  })
  isDeleted: boolean | undefined

  @CreateDateColumn()
  createDate?: Date

  @UpdateDateColumn()
  updateDate?: Date

  constructor(projMod: ProjMod) {
    this.projMod = projMod
  }
}

@Entity()
export class Combo {
  @PrimaryGeneratedColumn()
  id: number | undefined

  // ProjMod
  @ManyToOne(type => ProjMod, projMod => projMod.Nodes)
  projMod: ProjMod

  @Column({
    default: false,
    type: 'boolean'
  })
  isDeleted: boolean | undefined

  @CreateDateColumn()
  createDate?: Date

  @UpdateDateColumn()
  updateDate?: Date

  constructor(projMod: ProjMod) {
    this.projMod = projMod
  }
}

I can query out module (and its combo) + codefuncs (and its node).

For example, in the following way(fine-tuning may be required):

export const ModulesWithCodefuncs = publicProcedure.input(z.object({
  projModId: z.number()
})).query(async ({input: {projModId}}) => {

  const modules = await dataBase.getRepository(ComboModule)
 .createQueryBuilder('ComboModule')
 .where("combo.projMod.isDeleted = :isDeleted", { isDeleted: false })
 .andWhere("combo.projMod.id = :projModId", { projModId: projModId })
 .leftJoinAndSelect('ComboModule.combo', 'combo')
 .leftJoinAndSelect('ComboModule.codeFuncs', 'codeFuncs')
 .getMany()

  return modules
})

But now I also want to query out the related edges(because there also has many edges source/target in other projMod). How should I do it?


EDIT-01

I don’t have any idea about how to query it out through typeorm.

The only thing that comes to my mind is to query out all the edges and the module + codefunc queried here, and then iterate through the edges, judging whether the source/target of the edge belongs to module/codefunc, and keep it if it exists.