OpenAPI Codegen typescript generators
npm install @react-query-codegen/typescriptCollection of typescript generators & utils
Generate all #/components types. This generator is the foundation of other generators.
This is returning schemasFiles, the list of generated files (needed as config for other generators).
Generate useQuery & useMutation wrapper from react-query.
Example:
``ts
// openapi-codegen.config.ts
import { defineConfig } from "@openapi-codegen/cli";
import {
generateReactQueryComponents,
generateSchemaTypes,
} from "@openapi-codegen/typescript";
export default defineConfig({
petstore: {
from: {
/ file, url or github /
},
outputDir: "./petStore",
to: async (context) => {
const filenamePrefix = "petStore";
const { schemasFiles } = await generateSchemaTypes(context, {
filenamePrefix,
});
await generateReactQueryComponents(context, {
filenamePrefix,
schemasFiles,
});
},
},
});
`
This generator will generate 3 files:
- {filenamePrefix}Components.ts{filenamePrefix}Context.ts
- {filenamePrefix}Fetcher.ts
-
Only {filenamePrefix}Components.ts can’t be manually touch and will be regenerate at every openAPI changes.
The {filenamePrefix}Context.ts can be tweak to inject any props in the generated hooks, this is an example with some auth flow.
`tsPetStoreContext.ts
//
import type { QueryKey, UseQueryOptions } from "@tanstack/react-query";
export type PetStoreContext = {
fetcherOptions: {
/**
* Headers to inject in the fetcher
*/
headers?: {};
/**
* Query params to inject in the fetcher
*/
queryParams?: {};
};
queryOptions: {
/**
* Set this to false to disable automatic refetching when the query mounts or changes query keys.true
* Defaults to .
*/
enabled?: boolean;
};
/**
* Query key middleware.
*/
queryKeyFn: (queryKey: QueryKey) => QueryKey;
};
/**
* Context injected into every react-query hook wrappers
*
* @param queryOptions options from the useQuery wrapper
*/
export function usePetStoreContext<
TQueryFnData = unknown,
TError = unknown,
TData = TQueryFnData,
TQueryKey extends QueryKey = QueryKey
>(
queryOptions?: Omit<
UseQueryOptions
"queryKey" | "queryFn"
>
): BadassContext {
const token = window.localStorage.getItem("token");
return {
fetcherOptions: {
headers: {
authorization: token ? Bearer ${token} : undefined,`
},
},
queryOptions: {
enabled: Boolean(token) && (queryOptions?.enabled ?? true),
},
queryKeyFn: (queryKey) => queryKey,
};
}
You also need to tweak {filenamePrefix}Fetcher.ts, to inject your baseUrl and adjust the error management part to fullfil the ErrorType (you can search for the TODO keyword).
#### Usage
First of all, we need to have a working react-query context (more information here).
Now that we have all this generated code and properly configured {filenamePrefix}Fetcher.ts to talk to the correct server. This is time to try!
Assuming that you have a route with the verb GET and the operationId as listPets. You can simply use useListPets in a react component.
`tsx
import { useListPets } from "./petstoreComponents";
export const MyPage = () => {
const { data, isLoading, error } = useListPets(["listPets"]); // <- You need to add the react-query cache key
return
And for any mutation.
`tsx
import { useUpdatePet } from "./pestoreComponents";export const MyPage = () => {
const { mutate: updatePet } = useUpdatePet();
return (
onClick={() =>
updatePet({ pathParams: { id: "2" }, body: { name: "Biscuit" } })
}
>
Give a cute name
);
};
`$3
Generate some generic fetchers,
{filenamePrefix}Fetcher.ts can be customized to fit your needs.{filenamePrefix}Components.ts will use this fetcher with the OpenAPI types passed as generic.Utils
$3
Rename a component name in openAPI document and all related $ref.
Example:
`ts
// openapi-codegen.config.tsimport { defineConfig } from "@openapi-codegen/cli";
import {
generateReactQueryComponents,
generateSchemaTypes,
renameComponent,
} from "@openapi-codegen/typescript";
export default defineConfig({
myAPI: {
from: {
/ file, url or github /
},
outputDir: "./myAPI",
to: async (context) => {
// Rename
Foo to Bar
context.openAPIDocument = renameComponent({
openAPIDocument: context.openAPIDocument,
from: "#/components/schemas/Foo",
to: "#/components/schemas/Bar",
}); const filenamePrefix = "myAPI";
const { schemasFiles } = await generateSchemaTypes(context, {
filenamePrefix,
});
await generateReactQueryComponents(context, {
filenamePrefix,
schemasFiles,
});
},
},
});
`$3
Force the generation of a specific react-query hook.
Example:
`ts
// openapi-codegen.config.tsimport { defineConfig } from "@openapi-codegen/cli";
import {
generateReactQueryComponents,
generateSchemaTypes,
renameComponent,
} from "@openapi-codegen/typescript";
export default defineConfig({
myAPI: {
from: {
/ file, url or github /
},
outputDir: "./myAPI",
to: async (context) => {
// Force the usage of
useQuery for listPets
context.openAPIDocument = forceReactQueryComponent({
openAPIDocument: contextOpenAPIDocument
component: "useQuery",
operationId: "listPets"
}) const filenamePrefix = "myAPI";
const { schemasFiles } = await generateSchemaTypes(context, {
filenamePrefix,
});
await generateReactQueryComponents(context, {
filenamePrefix,
schemasFiles,
});
},
},
});
``| Property | Description | Type |
| --------------------------- | --------------------------------------------------- | ------------------------- |
| x-openapi-codegen-component | Force the generation of a specific react-query hook | "useMutate" \| "useQuery" |