Frontend code generator
Automatic generating typescript types from graphql.
GraphQL Code Generator
Graphql codegenerator is a package, that provide feature of generating typescript files from graphql schema. doc
How to generate types
With this command, we generate git-ignored files in the app/frontend/src/shared/graphql_schema folder. This file contains GraphQL schema from which we generate TypeScript types into app/frontend/src/shared/types/schemaTypes.generated.ts. Additionally, for each GraphQL query/mutation definition file, a separate type file is generated. These generated types can be used in the TypeScript code. Each generated file has the .generated.ts suffix. After generating the types, we can commit and push them with Git."
Using generated types
Example of using EasyProductBacklogItemMutation and EasyProductBacklogItemAttrs generated types in api service PbiApi:
import { ApolloClient } from "@apollo/client/core";
import apolloClient from "../../../shared/plugins/apolloClient";
import { COLUMN_TO_REFINE } from "../constants";
import { handleErrors } from "../../../shared/api/utils";
import { ApiResult } from "../../../shared/types/graphql";
import { createUpdateProductBacklogItemMutation } from "../graphql/productBacklogItem";
import { EasyProductBacklogItemMutation } from "../graphql/productBacklogItem.generated";
import { EasyProductBacklogItemAttrs } from "../../../shared/types/schemaTypes.generated";
export class PbiApi {
constructor(private readonly apolloClient: ApolloClient<object>) {}
public async createPbi(pbi: EasyProductBacklogItemAttrs) {
const { data, errors } = await this.apolloClient.mutate<EasyProductBacklogItemMutation>({
mutation: createUpdateProductBacklogItemMutation,
variables: {
attributes: {
status: COLUMN_TO_REFINE.key,
...pbi,
},
},
});
handleErrors(data?.easyProductBacklogItem as ApiResult, errors);
}
}
const pbiApi = new PbiApi(apolloClient);
export default pbiApi;
Runtime GraphQL schema enum values
schemaTypes.generated.ts is generated from the GraphQL schema and is safe to use as a TypeScript type source. When the application needs GraphQL schema enum values at runtime, do not import those enum values directly from schemaTypes.generated.ts.
Runtime imports from schemaTypes.generated.ts make Vite/Rollup resolve that generated file during the app build. If the generated schema type file is missing, the build can fail even when the code only needs stable enum string values.
Use the manually maintained runtime enum module instead:
import { PROMPT_TEMPLATE_USED_FOR } from "@/src/shared/types/schemaEnums";
import type { PromptTemplateUsedFor } from "@/src/shared/types/schemaEnums";
if (usedFor === PROMPT_TEMPLATE_USED_FOR.WriteAssistant) {
// runtime-safe enum comparison
}
Avoid runtime enum imports from the generated schema type file:
import { PromptTemplateUsedFor } from "@/src/shared/types/schemaTypes.generated";
if (usedFor === PromptTemplateUsedFor.WriteAssistant) {
// avoid this for runtime code
}
Rules for GraphQL schema enums:
- Put runtime-used GraphQL schema enum constants in
app/frontend/src/shared/types/schemaEnums.ts. - Export enum constants as uppercase names, for example
PROMPT_TEMPLATE_USED_FOR. - Export the derived PascalCase type from the same module, for example
PromptTemplateUsedFor. - Keep generated schema imports type-only in application code:
import type { ... } from "@/src/shared/types/schemaTypes.generated". - Do not manually edit
schemaTypes.generated.tsor any other*.generated.tsfile. Regenerate GraphQL outputs when the schema changes.
schemaEnums.ts still type-checks its manual enum values against schemaTypes.generated.ts when generated files are present. This catches missing enum keys, extra enum keys, and mismatched string values during TypeScript validation, while keeping runtime app code independent from the generated schema type module.
When adding a new runtime enum, follow the existing pattern in schemaEnums.ts:
const PROMPT_TEMPLATE_USED_FOR_VALUES = {
Ask: "ask",
HelpdeskAssistant: "helpdesk_assistant",
ReadAssistant: "read_assistant",
WriteAssistant: "write_assistant",
} as const satisfies GraphqlEnumShape<SchemaEnumObject<"PromptTemplateUsedFor">>;
export const PROMPT_TEMPLATE_USED_FOR = PROMPT_TEMPLATE_USED_FOR_VALUES as GraphqlEnumObject<
typeof PROMPT_TEMPLATE_USED_FOR_VALUES,
SchemaEnum<"PromptTemplateUsedFor">
>;
export type PromptTemplateUsedFor = ObjectValues<typeof PROMPT_TEMPLATE_USED_FOR>;
Validate enum consistency with generated files present: