sikanhe / gqtx

Code-first Typescript GraphQL Server without codegen or metaprogramming
458 stars 13 forks source link

feat: field extensions #36

Closed n1ru4l closed 3 years ago

n1ru4l commented 3 years ago
type GraphQLExtensions = {
  field: {
    liveQuery?: {
      collectResourceIdentifiers: (
        src: any,
        args: any
      ) => Iterable<string> | string | null;
    };
  };
};

export const t = createTypesFactory<GraphQLContextType, GraphQLExtensions>();

t.field("note", {
  type: GraphQLNoteType,
  args: {
    documentId: t.arg(t.NonNullInput(t.ID))
  },
  extensions: {
    liveQuery: {
      collectResourceIdentifiers: (_: any, args: any) =>
        `Note:${args.documentId}`
    }
  },
  resolve: (_, args, context) => RT.run(resolveNote(args.documentId), context)
});

This allows typing the available extensions for t.field and t.objectType. I have not figured out whether it would be possible to also make the arguments of the extensions field depending on the provided arguments. For E.g. my liveQuery.collectResourceIdentifiers implementation always calls the function with the source object and the args. However other extensions could do something completely different. @sikanhe Please let me know what you think.

sikanhe commented 3 years ago

On the first look it seems like it requires some kind of Higher Kinded Typing to make possible...

n1ru4l commented 3 years ago

I guess the higher typing (if even possible) could always be introduced at a later point. @sikanhe Any more feedback on this? Could we merge and ship this?

sikanhe commented 3 years ago

@n1ru4l looks good with me