Skip to content

Commit

Permalink
feat(fetch): support custom mutator (#1457)
Browse files Browse the repository at this point in the history
* feat(fetch): regenerate client by `orval 6.30.2`

* feat(fetch): support custom mutator

* chore(fetch): add custom custom mutator to sample app
  • Loading branch information
soartec-lab authored Jun 17, 2024
1 parent f296491 commit 95a2932
Show file tree
Hide file tree
Showing 21 changed files with 99 additions and 42 deletions.
25 changes: 13 additions & 12 deletions packages/fetch/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const generateRequestFunction = (
queryParams,
operationName,
response,
mutator,
body,
props,
verb,
Expand Down Expand Up @@ -94,17 +95,15 @@ ${
? `body: JSON.stringify(${requestBodyParams})`
: '';

const fetchResponseImplementation = `const res = await fetch(
${getUrlFnName}(${getUrlFnProperties}),
{${globalFetchOptions ? '\n' : ''} ${globalFetchOptions}
${isRequestOptions ? '...options,' : ''}
${fetchMethodOption}${fetchBodyOption ? ',' : ''}
${fetchBodyOption}
}
)
return res.json()
const fetchFnOptions = `${getUrlFnName}(${getUrlFnProperties}),
{${globalFetchOptions ? '\n' : ''} ${globalFetchOptions}
${isRequestOptions ? '...options,' : ''}
${fetchMethodOption}${fetchBodyOption ? ',' : ''}
${fetchBodyOption}
}
`;
const fetchResponseImplementation = `const res = await fetch(${fetchFnOptions})\n\nreturn res.json()`;
const customFetchResponseImplementation = `return ${mutator?.name}<${retrunType}>(${fetchFnOptions});`;

const bodyForm = generateFormDataAndUrlEncodedFunction({
formData,
Expand All @@ -114,8 +113,10 @@ ${
isFormUrlEncoded,
});

const fetchImplementationBody =
`${bodyForm ? ` ${bodyForm}\n` : ''}` + ` ${fetchResponseImplementation}`;
const fetchImplementationBody = mutator
? customFetchResponseImplementation
: `${bodyForm ? ` ${bodyForm}\n` : ''}` +
` ${fetchResponseImplementation}`;
const fetchImplementation = `export const ${operationName} = async (${args}): ${retrunType} => {\n${fetchImplementationBody}}`;

const implementation =
Expand Down
2 changes: 1 addition & 1 deletion samples/next-app-with-fetch/app/gen/models/cat.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Generated by orval v6.29.1 🍺
* Generated by orval v6.30.2 🍺
* Do not edit manually.
* Swagger Petstore
* OpenAPI spec version: 1.0.0
Expand Down
2 changes: 1 addition & 1 deletion samples/next-app-with-fetch/app/gen/models/catType.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Generated by orval v6.29.1 🍺
* Generated by orval v6.30.2 🍺
* Do not edit manually.
* Swagger Petstore
* OpenAPI spec version: 1.0.0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Generated by orval v6.29.1 🍺
* Generated by orval v6.30.2 🍺
* Do not edit manually.
* Swagger Petstore
* OpenAPI spec version: 1.0.0
Expand Down
2 changes: 1 addition & 1 deletion samples/next-app-with-fetch/app/gen/models/dachshund.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Generated by orval v6.29.1 🍺
* Generated by orval v6.30.2 🍺
* Do not edit manually.
* Swagger Petstore
* OpenAPI spec version: 1.0.0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Generated by orval v6.29.1 🍺
* Generated by orval v6.30.2 🍺
* Do not edit manually.
* Swagger Petstore
* OpenAPI spec version: 1.0.0
Expand Down
2 changes: 1 addition & 1 deletion samples/next-app-with-fetch/app/gen/models/dog.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Generated by orval v6.29.1 🍺
* Generated by orval v6.30.2 🍺
* Do not edit manually.
* Swagger Petstore
* OpenAPI spec version: 1.0.0
Expand Down
2 changes: 1 addition & 1 deletion samples/next-app-with-fetch/app/gen/models/dogType.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Generated by orval v6.29.1 🍺
* Generated by orval v6.30.2 🍺
* Do not edit manually.
* Swagger Petstore
* OpenAPI spec version: 1.0.0
Expand Down
2 changes: 1 addition & 1 deletion samples/next-app-with-fetch/app/gen/models/error.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Generated by orval v6.29.1 🍺
* Generated by orval v6.30.2 🍺
* Do not edit manually.
* Swagger Petstore
* OpenAPI spec version: 1.0.0
Expand Down
2 changes: 1 addition & 1 deletion samples/next-app-with-fetch/app/gen/models/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Generated by orval v6.29.1 🍺
* Generated by orval v6.30.2 🍺
* Do not edit manually.
* Swagger Petstore
* OpenAPI spec version: 1.0.0
Expand Down
2 changes: 1 addition & 1 deletion samples/next-app-with-fetch/app/gen/models/labradoodle.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Generated by orval v6.29.1 🍺
* Generated by orval v6.30.2 🍺
* Do not edit manually.
* Swagger Petstore
* OpenAPI spec version: 1.0.0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Generated by orval v6.29.1 🍺
* Generated by orval v6.30.2 🍺
* Do not edit manually.
* Swagger Petstore
* OpenAPI spec version: 1.0.0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Generated by orval v6.29.1 🍺
* Generated by orval v6.30.2 🍺
* Do not edit manually.
* Swagger Petstore
* OpenAPI spec version: 1.0.0
Expand Down
2 changes: 1 addition & 1 deletion samples/next-app-with-fetch/app/gen/models/pet.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Generated by orval v6.29.1 🍺
* Generated by orval v6.30.2 🍺
* Do not edit manually.
* Swagger Petstore
* OpenAPI spec version: 1.0.0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Generated by orval v6.29.1 🍺
* Generated by orval v6.30.2 🍺
* Do not edit manually.
* Swagger Petstore
* OpenAPI spec version: 1.0.0
Expand Down
2 changes: 1 addition & 1 deletion samples/next-app-with-fetch/app/gen/models/petCountry.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Generated by orval v6.29.1 🍺
* Generated by orval v6.30.2 🍺
* Do not edit manually.
* Swagger Petstore
* OpenAPI spec version: 1.0.0
Expand Down
2 changes: 1 addition & 1 deletion samples/next-app-with-fetch/app/gen/models/pets.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Generated by orval v6.29.1 🍺
* Generated by orval v6.30.2 🍺
* Do not edit manually.
* Swagger Petstore
* OpenAPI spec version: 1.0.0
Expand Down
2 changes: 1 addition & 1 deletion samples/next-app-with-fetch/app/gen/pets/pets.msw.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Generated by orval v6.29.1 🍺
* Generated by orval v6.30.2 🍺
* Do not edit manually.
* Swagger Petstore
* OpenAPI spec version: 1.0.0
Expand Down
19 changes: 6 additions & 13 deletions samples/next-app-with-fetch/app/gen/pets/pets.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Generated by orval v6.29.1 🍺
* Generated by orval v6.30.2 🍺
* Do not edit manually.
* Swagger Petstore
* OpenAPI spec version: 1.0.0
Expand All @@ -10,6 +10,7 @@ import type {
Pet,
Pets,
} from '.././models';
import { customFetch } from '../../../custom-fetch';

// https://stackoverflow.com/questions/49579094/typescript-conditional-types-filter-out-readonly-properties-pick-only-requir/49579497#49579497
type IfEquals<X, Y, A = X, B = never> =
Expand Down Expand Up @@ -60,12 +61,10 @@ export const listPets = async (
params?: ListPetsParams,
options?: RequestInit,
): Promise<Pets> => {
const res = await fetch(getListPetsUrl(params), {
return customFetch<Promise<Pets>>(getListPetsUrl(params), {
...options,
method: 'GET',
});

return res.json();
};

/**
Expand All @@ -79,13 +78,11 @@ export const createPets = async (
createPetsBodyItem: CreatePetsBodyItem[],
options?: RequestInit,
): Promise<Pet> => {
const res = await fetch(getCreatePetsUrl(), {
return customFetch<Promise<Pet>>(getCreatePetsUrl(), {
...options,
method: 'POST',
body: JSON.stringify(createPetsBodyItem),
});

return res.json();
};

/**
Expand All @@ -99,13 +96,11 @@ export const updatePets = async (
pet: NonReadonly<Pet>,
options?: RequestInit,
): Promise<Pet> => {
const res = await fetch(getUpdatePetsUrl(), {
return customFetch<Promise<Pet>>(getUpdatePetsUrl(), {
...options,
method: 'PUT',
body: JSON.stringify(pet),
});

return res.json();
};

/**
Expand All @@ -119,10 +114,8 @@ export const showPetById = async (
petId: string,
options?: RequestInit,
): Promise<Pet> => {
const res = await fetch(getShowPetByIdUrl(petId), {
return customFetch<Promise<Pet>>(getShowPetByIdUrl(petId), {
...options,
method: 'GET',
});

return res.json();
};
57 changes: 57 additions & 0 deletions samples/next-app-with-fetch/custom-fetch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// NOTE: Supports cases where `content-type` is other than `json`
const getBody = <T>(c: Response | Request): Promise<T> => {
const contentType = c.headers.get('content-type');

if (contentType && contentType.includes('application/json')) {
return c.json();
}

if (contentType && contentType.includes('application/pdf')) {
return c.blob() as Promise<T>;
}

return c.text() as Promise<T>;
};

// NOTE: Update just base url
const getUrl = (contextUrl: string): string => {
const url = new URL(contextUrl);
const pathname = url.pathname;
const search = url.search;
const baseUrl =
process.env.NODE_ENV === 'production'
? 'productionBaseUrl'
: 'http://localhost:3000';

const requestUrl = new URL(`${baseUrl}${pathname}${search}`);

return requestUrl.toString();
};

// NOTE: Add headers
const getHeaders = (headers?: HeadersInit): HeadersInit => {
return {
...headers,
Authorization: 'token',
'Content-Type': 'multipart/form-data',
};
};

export const customFetch = async <T>(
url: string,
options: RequestInit,
): Promise<T> => {
const requestUrl = getUrl(url);
const requestHeaders = getHeaders(options.headers);

const requestInit: RequestInit = {
...options,
headers: requestHeaders,
};

const request = new Request(requestUrl, requestInit);
const response = await fetch(request);
const data = await getBody<T>(response);

return data;
};
6 changes: 6 additions & 0 deletions samples/next-app-with-fetch/orval.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ export default defineConfig({
baseUrl: 'http://localhost:3000',
mock: true,
prettier: true,
override: {
mutator: {
path: './custom-fetch.ts',
name: 'customFetch',
},
},
},
input: {
target: './petstore.yaml',
Expand Down

0 comments on commit 95a2932

Please sign in to comment.