Skip to content

Commit

Permalink
fix(tanstack): incorrect InfiniteData import for vue-query (#1498)
Browse files Browse the repository at this point in the history
  • Loading branch information
ymc9 authored Jun 11, 2024
1 parent 627c40b commit 92f187f
Show file tree
Hide file tree
Showing 16 changed files with 228 additions and 17 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "zenstack-monorepo",
"version": "2.2.0",
"version": "2.2.1",
"description": "",
"scripts": {
"build": "pnpm -r build",
Expand Down
2 changes: 1 addition & 1 deletion packages/ide/jetbrains/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ plugins {
}

group = "dev.zenstack"
version = "2.2.0"
version = "2.2.1"

repositories {
mavenCentral()
Expand Down
2 changes: 1 addition & 1 deletion packages/ide/jetbrains/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jetbrains",
"version": "2.2.0",
"version": "2.2.1",
"displayName": "ZenStack JetBrains IDE Plugin",
"description": "ZenStack JetBrains IDE plugin",
"homepage": "https://zenstack.dev",
Expand Down
2 changes: 1 addition & 1 deletion packages/language/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/language",
"version": "2.2.0",
"version": "2.2.1",
"displayName": "ZenStack modeling language compiler",
"description": "ZenStack modeling language compiler",
"homepage": "https://zenstack.dev",
Expand Down
2 changes: 1 addition & 1 deletion packages/misc/redwood/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/redwood",
"displayName": "ZenStack RedwoodJS Integration",
"version": "2.2.0",
"version": "2.2.1",
"description": "CLI and runtime for integrating ZenStack with RedwoodJS projects.",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/openapi/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/openapi",
"displayName": "ZenStack Plugin and Runtime for OpenAPI",
"version": "2.2.0",
"version": "2.2.1",
"description": "ZenStack plugin and runtime supporting OpenAPI",
"main": "index.js",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/swr/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/swr",
"displayName": "ZenStack plugin for generating SWR hooks",
"version": "2.2.0",
"version": "2.2.1",
"description": "ZenStack plugin for generating SWR hooks",
"main": "index.js",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/tanstack-query/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/tanstack-query",
"displayName": "ZenStack plugin for generating tanstack-query hooks",
"version": "2.2.0",
"version": "2.2.1",
"description": "ZenStack plugin for generating tanstack-query hooks",
"main": "index.js",
"exports": {
Expand Down
213 changes: 212 additions & 1 deletion packages/plugins/tanstack-query/src/runtime-v5/vue.ts
Original file line number Diff line number Diff line change
@@ -1 +1,212 @@
export * from '../runtime/vue';
/* eslint-disable @typescript-eslint/ban-types */
/* eslint-disable @typescript-eslint/no-explicit-any */
import {
useInfiniteQuery,
useMutation,
useQuery,
useQueryClient,
type InfiniteData,
type QueryKey,
type UseInfiniteQueryOptions,
type UseMutationOptions,
type UseQueryOptions,
} from '@tanstack/vue-query';
import type { ModelMeta } from '@zenstackhq/runtime/cross';
import { computed, inject, provide, toValue, type ComputedRef, type MaybeRefOrGetter } from 'vue';
import {
APIContext,
DEFAULT_QUERY_ENDPOINT,
fetcher,
getQueryKey,
makeUrl,
marshal,
setupInvalidation,
setupOptimisticUpdate,
type ExtraMutationOptions,
type ExtraQueryOptions,
type FetchFn,
} from '../runtime/common';

export { APIContext as RequestHandlerContext } from '../runtime/common';

export const VueQueryContextKey = 'zenstack-vue-query-context';

/**
* Provide context for the generated TanStack Query hooks.
*/
export function provideHooksContext(context: APIContext) {
provide<APIContext>(VueQueryContextKey, context);
}

/**
* Hooks context.
*/
export function getHooksContext() {
const { endpoint, ...rest } = inject<APIContext>(VueQueryContextKey, {
endpoint: DEFAULT_QUERY_ENDPOINT,
fetch: undefined,
logging: false,
});
return { endpoint: endpoint ?? DEFAULT_QUERY_ENDPOINT, ...rest };
}

/**
* Creates a vue-query query.
*
* @param model The name of the model under query.
* @param url The request URL.
* @param args The request args object, URL-encoded and appended as "?q=" parameter
* @param options The vue-query options object
* @param fetch The fetch function to use for sending the HTTP request
* @returns useQuery hook
*/
export function useModelQuery<TQueryFnData, TData, TError>(
model: string,
url: string,
args?: MaybeRefOrGetter<unknown> | ComputedRef<unknown>,
options?:
| MaybeRefOrGetter<Omit<UseQueryOptions<TQueryFnData, TError, TData>, 'queryKey'> & ExtraQueryOptions>
| ComputedRef<Omit<UseQueryOptions<TQueryFnData, TError, TData>, 'queryKey'> & ExtraQueryOptions>,
fetch?: FetchFn
) {
const queryOptions = computed(() => {
const optionsValue = toValue<
(Omit<UseQueryOptions<TQueryFnData, TError, TData>, 'queryKey'> & ExtraQueryOptions) | undefined
>(options);
return {
queryKey: getQueryKey(model, url, args, {
infinite: false,
optimisticUpdate: optionsValue?.optimisticUpdate !== false,
}),
queryFn: ({ queryKey }: { queryKey: QueryKey }) => {
const [_prefix, _model, _op, args] = queryKey;
const reqUrl = makeUrl(url, toValue(args));
return fetcher<TQueryFnData, false>(reqUrl, undefined, fetch, false);
},
...optionsValue,
};
});
return useQuery<TQueryFnData, TError, TData>(queryOptions);
}

/**
* Creates a vue-query infinite query.
*
* @param model The name of the model under query.
* @param url The request URL.
* @param args The initial request args object, URL-encoded and appended as "?q=" parameter
* @param options The vue-query infinite query options object
* @param fetch The fetch function to use for sending the HTTP request
* @returns useInfiniteQuery hook
*/
export function useInfiniteModelQuery<TQueryFnData, TData, TError>(
model: string,
url: string,
args?: MaybeRefOrGetter<unknown> | ComputedRef<unknown>,
options?:
| MaybeRefOrGetter<
Omit<UseInfiniteQueryOptions<TQueryFnData, TError, InfiniteData<TData>>, 'queryKey' | 'initialPageParam'>
>
| ComputedRef<
Omit<UseInfiniteQueryOptions<TQueryFnData, TError, InfiniteData<TData>>, 'queryKey' | 'initialPageParam'>
>,
fetch?: FetchFn
) {
// CHECKME: vue-query's `useInfiniteQuery`'s input typing seems wrong
const queryOptions: any = computed(() => ({
queryKey: getQueryKey(model, url, args, { infinite: true, optimisticUpdate: false }),
queryFn: ({ queryKey, pageParam }: { queryKey: QueryKey; pageParam?: unknown }) => {
const [_prefix, _model, _op, args] = queryKey;
const reqUrl = makeUrl(url, pageParam ?? toValue(args));
return fetcher<TQueryFnData, false>(reqUrl, undefined, fetch, false);
},
initialPageParam: toValue(args),
...toValue(options),
}));

return useInfiniteQuery<TQueryFnData, TError, InfiniteData<TData>>(queryOptions);
}

/**
* Creates a mutation with vue-query.
*
* @param model The name of the model under mutation.
* @param method The HTTP method.
* @param modelMeta The model metadata.
* @param url The request URL.
* @param options The vue-query options.
* @param fetch The fetch function to use for sending the HTTP request
* @param checkReadBack Whether to check for read back errors and return undefined if found.
* @returns useMutation hooks
*/
export function useModelMutation<
TArgs,
TError,
R = any,
C extends boolean = boolean,
Result = C extends true ? R | undefined : R
>(
model: string,
method: 'POST' | 'PUT' | 'DELETE',
url: string,
modelMeta: ModelMeta,
options?:
| MaybeRefOrGetter<
Omit<UseMutationOptions<Result, TError, TArgs, unknown>, 'mutationFn'> & ExtraMutationOptions
>
| ComputedRef<Omit<UseMutationOptions<Result, TError, TArgs, unknown>, 'mutationFn'> & ExtraMutationOptions>,
fetch?: FetchFn,
checkReadBack?: C
) {
const queryClient = useQueryClient();
const mutationFn = (data: any) => {
const reqUrl = method === 'DELETE' ? makeUrl(url, data) : url;
const fetchInit: RequestInit = {
method,
...(method !== 'DELETE' && {
headers: {
'content-type': 'application/json',
},
body: marshal(data),
}),
};
return fetcher<R, C>(reqUrl, fetchInit, fetch, checkReadBack) as Promise<Result>;
};

const optionsValue = toValue<
(Omit<UseMutationOptions<Result, TError, TArgs, unknown>, 'mutationFn'> & ExtraMutationOptions) | undefined
>(options);
// TODO: figure out the typing problem
const finalOptions: any = computed(() => ({ ...optionsValue, mutationFn }));
const operation = url.split('/').pop();
const invalidateQueries = optionsValue?.invalidateQueries !== false;
const optimisticUpdate = !!optionsValue?.optimisticUpdate;

if (operation) {
const { logging } = getHooksContext();
if (invalidateQueries) {
setupInvalidation(
model,
operation,
modelMeta,
toValue(finalOptions),
(predicate) => queryClient.invalidateQueries({ predicate }),
logging
);
}

if (optimisticUpdate) {
setupOptimisticUpdate(
model,
operation,
modelMeta,
toValue(finalOptions),
queryClient.getQueryCache().getAll(),
(queryKey, data) => queryClient.setQueryData<unknown>(queryKey, data),
invalidateQueries ? (predicate) => queryClient.invalidateQueries({ predicate }) : undefined,
logging
);
}
}
return useMutation<Result, TError, TArgs>(finalOptions);
}
4 changes: 2 additions & 2 deletions packages/plugins/tanstack-query/src/runtime/vue.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/* eslint-disable @typescript-eslint/ban-types */
/* eslint-disable @typescript-eslint/no-explicit-any */
import type { InfiniteData } from '@tanstack/react-query-v5';
import {
useInfiniteQuery,
useMutation,
useQuery,
useQueryClient,
type InfiniteData,
type QueryKey,
type UseInfiniteQueryOptions,
type UseMutationOptions,
Expand Down Expand Up @@ -124,7 +124,7 @@ export function useInfiniteModelQuery<TQueryFnData, TData, TError>(
...toValue(options),
}));

return useInfiniteQuery<TQueryFnData, TError, InfiniteData<TData>>(queryOptions);
return useInfiniteQuery<TQueryFnData, TError, TData>(queryOptions);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/trpc/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/trpc",
"displayName": "ZenStack plugin for tRPC",
"version": "2.2.0",
"version": "2.2.1",
"description": "ZenStack plugin for tRPC",
"main": "index.js",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/runtime/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/runtime",
"displayName": "ZenStack Runtime Library",
"version": "2.2.0",
"version": "2.2.1",
"description": "Runtime of ZenStack for both client-side and server-side environments.",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion packages/schema/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"publisher": "zenstack",
"displayName": "ZenStack Language Tools",
"description": "Build scalable web apps with minimum code by defining authorization and validation rules inside the data schema that closer to the database",
"version": "2.2.0",
"version": "2.2.1",
"author": {
"name": "ZenStack Team"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/sdk",
"version": "2.2.0",
"version": "2.2.1",
"description": "ZenStack plugin development SDK",
"main": "index.js",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/server/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/server",
"version": "2.2.0",
"version": "2.2.1",
"displayName": "ZenStack Server-side Adapters",
"description": "ZenStack server-side adapters",
"homepage": "https://zenstack.dev",
Expand Down
2 changes: 1 addition & 1 deletion packages/testtools/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/testtools",
"version": "2.2.0",
"version": "2.2.1",
"description": "ZenStack Test Tools",
"main": "index.js",
"private": true,
Expand Down

0 comments on commit 92f187f

Please sign in to comment.