lolopinto / ent

MIT License
51 stars 6 forks source link

AssocEdgeQueryBase classes generated from pattern edges don't include chain query methods #1818

Open Swahvay opened 3 months ago

Swahvay commented 3 months ago

I have a Pattern Entry defined as such:

export const Entry: Pattern = {
  name: 'Entry',
  fields: {
    competitionID: UUIDType({
      fieldEdge: {
        schema: 'Competition',
        inverseEdge: {
          name: 'entries',
          hideFromGraphQL: true,
        },
      },
      index: true,
    }),
    // More fields
  },

  edges: [
    {
      name: 'horsesInEntry',
      schemaName: 'Horse',
      inverseEdge: { name: 'competitionEntries' },
    },
  ],
};

The resulting codegen correctly creates a query method on the base mixin:

export interface IEntryBase<TViewer extends Viewer = Viewer>
  extends Ent<TViewer> {
  competitionId: ID;
  queryHorsesInEntry(): ObjectToHorsesInEntryQuery;
}

However, the queryEntries() method on the Competition ent is defined as such:

queryEntries(): CompetitionToEntriesQuery {
  return CompetitionToEntriesQuery.query(this.viewer, this.id);
}
export abstract class CompetitionToEntriesQueryBase extends AssocEdgeQueryBase<
  Competition,
  Ent<BarnlogViewer>,
  CompetitionToEntriesEdge,
  BarnlogViewer
> {
  constructor(
    viewer: BarnlogViewer,
    src: EdgeQuerySource<Competition, Ent<BarnlogViewer>, BarnlogViewer>,
  ) {
    super(
      viewer,
      src,
      competitionToEntriesCountLoaderFactory,
      competitionToEntriesDataLoaderFactory,
      (str) => getLoaderOptions(str as NodeType),
    );
  }

  static query<T extends CompetitionToEntriesQueryBase>(
    this: new (
      viewer: BarnlogViewer,
      src: EdgeQuerySource<Competition, Ent<BarnlogViewer>>,
    ) => T,
    viewer: BarnlogViewer,
    src: EdgeQuerySource<Competition, Ent<BarnlogViewer>>,
  ): T {
    return new this(viewer, src);
  }

  sourceEnt(id: ID) {
    return Competition.load(this.viewer, id);
  }
}

The two main errors are that the AssocEdgeQueryBase generics should be defined like this:

  export abstract class CompetitionToEntriesQueryBase extends AssocEdgeQueryBase<
    Competition,
-   Ent<BarnlogViewer>,
+   IEntry<BarnlogViewer>,
    CompetitionToEntriesEdge,
    BarnlogViewer
  > {

And the other is that it is missing the queryHorsesInEntry() method so that I can chain query methods:

const horses = await competition.queryEntries().queryHorsesInEntry().queryEnts();