Skip to content

Commit

Permalink
feat(query): add prefetch functions (orval-labs#956)
Browse files Browse the repository at this point in the history
* feat(query): add prefetch functions

* feat(query): add prefetch functions doc

* feat(query): prefetch functions add types

* feat(query): prefetch functions generate samples

* feat(query): prefetch functions fix pageParam

* feat(query): prefetch functions fix samples

* Update object.ts

* feat(query): prefetch functions fix after review

---------

Co-authored-by: Melloware <[email protected]>
  • Loading branch information
georgiev-anton and melloware authored Nov 7, 2023
1 parent 7a95876 commit 313c8b0
Show file tree
Hide file tree
Showing 12 changed files with 94 additions and 31 deletions.
24 changes: 12 additions & 12 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,23 @@ diverse, inclusive, and healthy community.
Examples of behavior that contributes to a positive environment for our
community include:

* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the overall
- Focusing on what is best not just for us as individuals, but for the overall
community

Examples of unacceptable behavior include:

* The use of sexualized language or imagery, and sexual attention or advances of
- The use of sexualized language or imagery, and sexual attention or advances of
any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email address,
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email address,
without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
- Other conduct which could reasonably be considered inappropriate in a
professional setting

## Enforcement Responsibilities
Expand Down Expand Up @@ -119,8 +119,8 @@ version 2.1, available at
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].

Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
[Mozilla's code of conduct enforcement ladder][mozilla coc].

For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
[https://www.contributor-covenant.org/faq][faq]. Translations are available at
[https://www.contributor-covenant.org/translations][translations].
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ You can find below some samples
- [angular app](https://github.com/anymaniax/orval/tree/master/samples/angular-app)

### All Thanks To Our Contributors:

<a href="https://github.com/anymaniax/orval/graphs/contributors">
<img src="https://contrib.rocks/image?repo=anymaniax/orval" />
</a>
34 changes: 33 additions & 1 deletion docs/src/pages/reference/configuration/output.md
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,38 @@ Type: `Boolean`.

Use to generate a <a href="https://tanstack.com/query/latest/docs/react/reference/useInfiniteQuery" target="_blank">useInfiniteQuery</a> custom hook.

##### usePrefetch

Type: `Boolean`.

Use to generate a <a href="https://tanstack.com/query/v4/docs/react/guides/prefetching" target="_blank">prefetching</a> functions.
This may be useful for the NextJS SSR or any prefetching situations.

Example generated function:

```js
export const prefetchGetCategories = async <
TData = Awaited<ReturnType<typeof getCategories>>,
TError = ErrorType<unknown>,
>(
queryClient: QueryClient,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getCategories>>,
TError,
TData,
>,
request?: SecondParameter<typeof customAxiosInstance>,
},
): Promise<QueryClient> => {
const queryOptions = getGetCategoriesQueryOptions(options);

await queryClient.prefetchQuery(queryOptions);

return queryClient;
};
```

##### useInfiniteQueryParam

Type: `String`.
Expand Down Expand Up @@ -691,7 +723,7 @@ module.exports = {
mock: {
properties: {
'/tag|name/': 'jon', // Matches every property named 'tag' or 'name', including nested ones
'/.*\.user\.id/': faker.string.uuid(), // Matches every property named 'id', inside an object named 'user', including nested ones
'/.*.user.id/': faker.string.uuid(), // Matches every property named 'id', inside an object named 'user', including nested ones
email: () => faker.internet.email(), // Matches only the property 'email'
'user.id': () => faker.string.uuid(), // Matches only the full path 'user.id'
},
Expand Down
3 changes: 1 addition & 2 deletions packages/core/src/getters/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,7 @@ export const getObject = ({
}

return {
value:
(item.type === 'object' ? '{ [key: string]: any }' : 'unknown') + nullable,
value: (item.type === 'object' ? '{ [key: string]: any }' : 'unknown') + nullable,
imports: [],
schemas: [],
isEnum: false,
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ export type NormalizedQueryOptions = {
useInfinite?: boolean;
useSuspenseInfiniteQuery?: boolean;
useInfiniteQueryParam?: string;
usePrefetch?: boolean;
options?: any;
queryKey?: NormalizedMutator;
queryOptions?: NormalizedMutator;
Expand All @@ -331,6 +332,7 @@ export type QueryOptions = {
useInfinite?: boolean;
useSuspenseInfiniteQuery?: boolean;
useInfiniteQueryParam?: string;
usePrefetch?: boolean;
options?: any;
queryKey?: Mutator;
queryOptions?: Mutator;
Expand Down
22 changes: 11 additions & 11 deletions packages/core/src/writers/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,21 +116,21 @@ export const writeSchemas = async ({
const stringData = data.toString();

const importStatements = schemas
.filter((schema) => {
return (
!stringData.includes(`export * from './${camel(schema.name)}'`) &&
!stringData.includes(`export * from "./${camel(schema.name)}"`)
);
})
.map((schema) => `export * from './${camel(schema.name)}';`);
.filter((schema) => {
return (
!stringData.includes(`export * from './${camel(schema.name)}'`) &&
!stringData.includes(`export * from "./${camel(schema.name)}"`)
);
})
.map((schema) => `export * from './${camel(schema.name)}';`);

const currentFileExports = (stringData
.match(/export \* from(.*)('|")/g)
?.map((s) => s + ';') ?? []) as string[];
.match(/export \* from(.*)('|")/g)
?.map((s) => s + ';') ?? []) as string[];

const exports = [...currentFileExports, ...importStatements]
.sort()
.join('\n');
.sort()
.join('\n');

const fileContent = `${header}\n${exports}`;

Expand Down
3 changes: 3 additions & 0 deletions packages/orval/src/utils/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,9 @@ const normalizeQueryOptions = (
}

return {
...(!isUndefined(queryOptions.usePrefetch)
? { usePrefetch: queryOptions.usePrefetch }
: {}),
...(!isUndefined(queryOptions.useQuery)
? { useQuery: queryOptions.useQuery }
: {}),
Expand Down
24 changes: 23 additions & 1 deletion packages/query/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ const REACT_QUERY_DEPENDENCIES_V3: GeneratorDependency[] = [
{ name: 'UseQueryResult' },
{ name: 'UseInfiniteQueryResult' },
{ name: 'QueryKey' },
{ name: 'QueryClient' },
],
dependency: 'react-query',
},
Expand All @@ -178,6 +179,7 @@ const REACT_QUERY_DEPENDENCIES: GeneratorDependency[] = [
{ name: 'UseInfiniteQueryResult' },
{ name: 'UseSuspenseInfiniteQueryResult' },
{ name: 'QueryKey' },
{ name: 'QueryClient' },
{ name: 'InfiniteData' },
],
dependency: '@tanstack/react-query',
Expand Down Expand Up @@ -803,6 +805,7 @@ const generateQueryImplementation = ({
hasSvelteQueryV4,
hasQueryV5,
doc,
usePrefetch,
}: {
queryOption: {
name: string;
Expand Down Expand Up @@ -830,6 +833,7 @@ const generateQueryImplementation = ({
hasSvelteQueryV4: boolean;
hasQueryV5: boolean;
doc?: string;
usePrefetch?: boolean;
}) => {
const queryProps = toObjectString(props, 'implementation');

Expand Down Expand Up @@ -1031,7 +1035,24 @@ ${doc}export const ${camel(
};
return query;
}\n`;
}\n
${
usePrefetch
? `${doc}export const ${camel(
`prefetch-${name}`,
)} = async <TData = Awaited<ReturnType<${dataType}>>, TError = ${errorType}>(\n queryClient: QueryClient, ${queryProps} ${queryArguments}\n ): Promise<QueryClient> => {
const ${queryOptionsVarName} = ${queryOptionsFnName}(${queryProperties}${
queryProperties ? ',' : ''
}${isRequestOptions ? 'options' : 'queryOptions'})
await queryClient.${camel(`prefetch-${type}`)}(${queryOptionsVarName});
return queryClient;
}\n`
: ''
}
`;
};

const generateQueryHook = async (
Expand Down Expand Up @@ -1218,6 +1239,7 @@ const generateQueryHook = async (
hasSvelteQueryV4,
hasQueryV5,
doc,
usePrefetch: query.usePrefetch,
}),
'',
)}
Expand Down
1 change: 1 addition & 0 deletions packages/query/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const normalizeQueryOptions = (
outputWorkspace: string,
): NormalizedQueryOptions => {
return {
...(queryOptions.usePrefetch ? { usePrefetch: true } : {}),
...(queryOptions.useQuery ? { useQuery: true } : {}),
...(queryOptions.useInfinite ? { useInfinite: true } : {}),
...(queryOptions.useInfiniteQueryParam
Expand Down
2 changes: 1 addition & 1 deletion packages/zod/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ const parseZodValidationSchemaDefinition = (
if (fn === 'additionalProperties') {
const value = args.functions.map(parseProperty).join('');
const valueWithZod = `${value.startsWith('.') ? 'zod' : ''}${value}`;
consts += args.consts
consts += args.consts;
return `zod.record(zod.string(), ${valueWithZod})`;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ export const getListPetsInfiniteQueryOptions = <
Awaited<ReturnType<typeof listPets>>,
QueryKey,
ListPetsParams['limit']
> = ({ pageParam }) => listPets({ limit: pageParam, ...params }, version);
> = ({ pageParam }) =>
listPets({ ...params, limit: pageParam || params.page }, version);

return {
queryKey,
Expand Down Expand Up @@ -348,7 +349,8 @@ export const getListPetsSuspenseInfiniteQueryOptions = <
Awaited<ReturnType<typeof listPets>>,
QueryKey,
ListPetsParams['limit']
> = ({ pageParam }) => listPets({ limit: pageParam, ...params }, version);
> = ({ pageParam }) =>
listPets({ ...params, limit: pageParam || params.page }, version);

return {
queryKey,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ export const getListPetsInfiniteQueryOptions = <
const queryFn: QueryFunction<Awaited<ReturnType<typeof listPets>>> = ({
signal,
pageParam,
}) => listPets({ limit: pageParam, ...params }, version, signal);
}) =>
listPets({ ...params, limit: pageParam || params.page }, version, signal);

return {
queryKey,
Expand Down

0 comments on commit 313c8b0

Please sign in to comment.