API client (Orval)
fleapo-marketplace/src/api/ is generated by Orval from the marketplace's OpenAPI spec.
Config (orval.config.ts)
export default {
api: {
input: "./openapi.transformed.json", // openapi.json with ApiResponseDto envelope stripped
output: {
mode: "tags-split", // one file per OpenAPI tag
target: "src/api",
client: "react-query",
override: {
mutator: { path: "src/lib/orval-mutator.ts", name: "customFetch" },
query: { useQuery: true, useMutation: true },
fetchOptions: { includeHttpStatusReturnType: false },
},
},
},
};
Each tag generates a folder with hooks and a .schemas.ts types file.
Mutator (src/lib/orval-mutator.ts)
Custom fetch handler used by every generated hook. Responsibilities:
- Base URL —
import.meta.env.VITE_API_BASE_URLorhttp://localhost:3000. credentials: "include"so the cookie is sent cross-origin.Content-Type: application/jsonfor JSON bodies.- Unwrap the
ApiResponseDtoenvelope so React Query stores the innerdata. - Throw on non-2xx with
error.codeanderror.messageattached.
Spec transformation
openapi.json (produced by NestJS Swagger) wraps every response in ApiResponseDto<T>. If Orval consumed this raw, every generated type would be ApiResponseDto<...> and components would have to drill through .data.
A small script transforms the spec: it walks every response schema, finds ApiResponseDto<T> shapes, and replaces them with T. The result is committed to openapi.transformed.json. Orval reads only the transformed version.
Regenerating
cd fleapo-marketplace
# After the backend's openapi.json changes:
pnpm run gen:openapi # transforms openapi.json → openapi.transformed.json
pnpm orval # generates src/api/
Commit the resulting changes.
Manual API calls
Some legacy code uses the hand-rolled src/lib/api-client.ts (get, post, patch, delete) — same fetch wrapper without React Query. Prefer the generated hooks for new code.
Environment
VITE_API_BASE_URL=http://localhost:3000 # dev
VITE_API_BASE_URL=https://api.fleapo.ai # prod
Set per environment in .env.local / Cloudflare Pages env vars.
How this site relates
The docs site does not import the generated client. It reads the same openapi.json via docusaurus-plugin-openapi-docs to produce the API Reference.
When the spec changes, run both:
# in fleapo-marketplace
pnpm run gen:openapi && pnpm orval
# in marketplace-docs
pnpm refresh-api