@7nohe/openapi-react-query-codegen
Version:
OpenAPI React Query Codegen
163 lines (162 loc) • 5.2 kB
JavaScript
import { IndentationText, NewLineKind, Project, QuoteKind, StructureKind, } from "ts-morph";
/**
* Create a shared ts-morph Project for code generation.
* Uses consistent formatting settings to match existing output.
*/
export function createGenerationProject() {
return new Project({
useInMemoryFileSystem: true,
compilerOptions: {
strict: true,
},
manipulationSettings: {
indentationText: IndentationText.TwoSpaces,
newLineKind: NewLineKind.LineFeed,
quoteKind: QuoteKind.Double,
useTrailingCommas: true,
},
});
}
/**
* Build import structure for the Options type.
* sdk.gen re-exports Options extended with `client` and `meta`, which the
* base client Options lacks; hooks must accept those properties.
*/
export function buildClientImport(_ctx) {
return {
kind: StructureKind.ImportDeclaration,
moduleSpecifier: "../requests/sdk.gen",
namedImports: [{ name: "Options", isTypeOnly: true }],
};
}
/**
* Build import structure for TanStack Query.
*/
export function buildQueryImport() {
return {
kind: StructureKind.ImportDeclaration,
moduleSpecifier: "@tanstack/react-query",
namedImports: [
{ name: "QueryClient", isTypeOnly: true },
{ name: "useQuery" },
{ name: "useSuspenseQuery" },
{ name: "useInfiniteQuery" },
{ name: "useSuspenseInfiniteQuery" },
{ name: "useMutation" },
{ name: "UseQueryResult", isTypeOnly: true },
{ name: "UseQueryOptions", isTypeOnly: true },
{ name: "UseInfiniteQueryOptions", isTypeOnly: true },
{ name: "UseSuspenseInfiniteQueryOptions", isTypeOnly: true },
{ name: "UseMutationOptions", isTypeOnly: true },
{ name: "UseMutationResult", isTypeOnly: true },
{ name: "UseSuspenseQueryOptions", isTypeOnly: true },
{ name: "InfiniteData", isTypeOnly: true },
{ name: "FetchQueryOptions", isTypeOnly: true },
{ name: "FetchInfiniteQueryOptions", isTypeOnly: true },
{ name: "GetNextPageParamFunction", isTypeOnly: true },
{ name: "EnsureQueryDataOptions", isTypeOnly: true },
],
};
}
/**
* Build import structure for the queryOptions/infiniteQueryOptions helpers.
*/
export function buildQueryOptionsImport() {
return {
kind: StructureKind.ImportDeclaration,
moduleSpecifier: "@tanstack/react-query",
namedImports: [
{ name: "queryOptions" },
{ name: "infiniteQueryOptions" },
{ name: "UseInfiniteQueryOptions", isTypeOnly: true },
],
};
}
/**
* Build import structure for services.
*/
export function buildServiceImport(ctx) {
return {
kind: StructureKind.ImportDeclaration,
moduleSpecifier: "../requests/sdk.gen",
namedImports: ctx.serviceNames.map((name) => ({ name })),
};
}
/**
* Build import structure for models.
* Emitted as a type-only import so generated code compiles under
* `verbatimModuleSyntax` (enabled by default in recent Vite templates).
*/
export function buildModelImport(ctx) {
if (ctx.modelNames.length === 0) {
return null;
}
return {
kind: StructureKind.ImportDeclaration,
moduleSpecifier: "../requests/types.gen",
isTypeOnly: true,
namedImports: ctx.modelNames.map((name) => ({ name })),
};
}
/**
* Build import structure for axios error type.
*/
export function buildAxiosErrorImport() {
return {
kind: StructureKind.ImportDeclaration,
moduleSpecifier: "axios",
namedImports: [{ name: "AxiosError" }],
};
}
/**
* Build import for Common namespace.
*/
export function buildCommonImport() {
return {
kind: StructureKind.ImportDeclaration,
moduleSpecifier: "./common",
namespaceImport: "Common",
};
}
/**
* Build all imports needed for the common file.
*/
export function buildCommonFileImports(ctx) {
const imports = [
buildClientImport(ctx),
buildQueryImport(),
buildServiceImport(ctx),
];
const modelImport = buildModelImport(ctx);
if (modelImport) {
imports.push(modelImport);
}
if (ctx.client === "@hey-api/client-axios") {
imports.push(buildAxiosErrorImport());
}
return imports;
}
/**
* Build all imports needed for hook files (queries, suspense, infinite).
*/
export function buildHookFileImports(ctx) {
return [buildCommonImport(), ...buildCommonFileImports(ctx)];
}
/**
* Build all imports needed for the queryOptions file.
* Narrower than the hook file imports: queryOptions only needs the
* queryOptions/infiniteQueryOptions helpers, not the TanStack hooks.
*/
export function buildQueryOptionsFileImports(ctx) {
const imports = [
buildCommonImport(),
buildQueryOptionsImport(),
buildClientImport(ctx),
buildServiceImport(ctx),
];
const modelImport = buildModelImport(ctx);
if (modelImport) {
imports.push(modelImport);
}
return imports;
}