Support additional fields
mizdra opened this issue · 2 comments
blocked by: #73
Problem
Alias is a feature that allows you to change the result of a field to any name you want.
This can be used to generate a response with a field that does not exist in Author
type.
const query = graphql`
query ExampleQuery @raw_response_type {
author(id: "1") {
id
name
name2 # alias
}
}
`;
const data = useClientQuery(query);
console.log(data);
// output:
// {
// author: {
// id: "1",
// name: "Mikami Komata",
// name2: "Mikami Komata",
// },
// }
However, graphql-codegen-typescript-fabbrica cannot generate alias-derived fields. This makes it difficult to build responses for queries that use aliases.
const AuthorFactory = defineAuthorFactory({
defaultFields: {
id: dynamic(({ seq }) => `Author-${seq}`),
name: "Komata Mikami",
},
});
const author = await AuthorFactory.build();
// ^? { id: string, name: string }
const dummyResponse: ExampleQuery$rawResponse = { author };
// ^^^^^^^^^^^^^ error: author.name2 is missing
Solution
Allow defaultFields
to accept alias-derived fields. The interface is designed with reference to Quramy/prisma-fabbrica#252.
import { type OptionalAuthor } from '../__generated__/fabbrica';
const AuthorFactory = defineAuthorFactory.withAdditionalFields<{ name2: OptionalAuthor['name'] }>()({
defaultFields: {
id: dynamic(({ seq }) => `Author-${seq}`),
name: "Komata Mikami",
name2: "Komata Mikami", // alias-derived field
},
});
const author = await AuthorFactory.build();
// ^? { id: string, name: string, name2: string }
const dummyResponse: ExampleQuery$rawResponse = { author }; // ok
Drawbacks
In the current implementation of graphql-codegen-typescript-fabbrica, fields not included in type are treated as transient fields. transient fields are not included in the built data.
Therefore, to implement this proposal, we have to change the interface of transient fields.
graphql-codegen-typescript-fabbrica excludes properties other than field (__typename
, id
, name
) of its type from the build result.
- https://stackblitz.com/edit/playground-graphql-codegen-typescript-fabbrica-nvazzz?file=__generated__%2Ffabbrica.ts%3AL17,src%2Findex.test.ts&view=editor
- https://stackblitz.com/edit/playground-graphql-codegen-typescript-fabbrica-nvazzz?file=__generated__%2Ffabbrica.ts%3AL38,src%2Findex.test.ts,node_modules%2F%40mizdra%2Fgraphql-codegen-typescript-fabbrica%2Fdist%2Fhelper%2Ffactory.d.ts,node_modules%2F%40mizdra%2Fgraphql-codegen-typescript-fabbrica%2Fdist%2Fhelper%2Findex.d.ts&view=editor
So, if you pass a field such as name2
to the build function, it will not be included in the build result. This limitation is implemented for transient fields.
Therefore, implementing alias-derived fields requires a change in the implementation of transient fields.
This feature supports any additional fields, not just fields for aliases.
I think the feature should be renamed from "alias fields" to "additional fields".