Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: merge from dev #1205

Merged
merged 1 commit into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/update-samples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jobs:
'zenstackhq/sample-todo-nextjs-tanstack',
'zenstackhq/sample-todo-trpc',
'zenstackhq/sample-todo-sveltekit',
'zenstackhq/sample-todo-nuxt',
]

steps:
Expand Down
27 changes: 21 additions & 6 deletions packages/plugins/tanstack-query/src/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ function generateQueryHook(
const capOperation = upperCaseFirst(operation);

const argsType = overrideInputType ?? `Prisma.${model}${capOperation}Args`;
const inputType = `Prisma.SelectSubset<TArgs, ${argsType}>`;
const inputType = makeQueryArgsType(target, argsType);

const infinite = generateMode.includes('Infinite');
const suspense = generateMode.includes('Suspense');
Expand Down Expand Up @@ -567,6 +567,7 @@ function makeBaseImports(target: TargetFramework, version: TanStackVersion) {
return [
`import type { UseMutationOptions, UseQueryOptions, UseInfiniteQueryOptions, InfiniteData } from '@tanstack/vue-query';`,
`import { getHooksContext } from '${runtimeImportBase}/${target}';`,
`import type { MaybeRefOrGetter, ComputedRef } from 'vue';`,
...shared,
];
}
Expand All @@ -586,6 +587,15 @@ function makeBaseImports(target: TargetFramework, version: TanStackVersion) {
}
}

function makeQueryArgsType(target: string, argsType: string) {
const type = `Prisma.SelectSubset<TArgs, ${argsType}>`;
if (target === 'vue') {
return `MaybeRefOrGetter<${type}> | ComputedRef<${type}>`;
} else {
return type;
}
}

function makeQueryOptions(
target: string,
returnType: string,
Expand All @@ -604,10 +614,12 @@ function makeQueryOptions(
}InfiniteQueryOptions<${returnType}, TError, InfiniteData<${dataType}>>, 'queryKey'>`
: `Omit<Use${suspense ? 'Suspense' : ''}QueryOptions<${returnType}, TError, ${dataType}>, 'queryKey'>`
)
.with(
'vue',
() => `Omit<Use${infinite ? 'Infinite' : ''}QueryOptions<${returnType}, TError, ${dataType}>, 'queryKey'>`
)
.with('vue', () => {
const baseOption = `Omit<Use${
infinite ? 'Infinite' : ''
}QueryOptions<${returnType}, TError, ${dataType}>, 'queryKey'>`;
return `MaybeRefOrGetter<${baseOption}> | ComputedRef<${baseOption}>`;
})
.with('svelte', () =>
infinite
? version === 'v4'
Expand All @@ -632,7 +644,10 @@ function makeQueryOptions(
function makeMutationOptions(target: string, returnType: string, argsType: string) {
let result = match(target)
.with('react', () => `UseMutationOptions<${returnType}, DefaultError, ${argsType}>`)
.with('vue', () => `UseMutationOptions<${returnType}, DefaultError, ${argsType}, unknown>`)
.with('vue', () => {
const baseOption = `UseMutationOptions<${returnType}, DefaultError, ${argsType}, unknown>`;
return `MaybeRefOrGetter<${baseOption}> | ComputedRef<${baseOption}>`;
})
.with('svelte', () => `MutationOptions<${returnType}, DefaultError, ${argsType}>`)
.otherwise(() => {
throw new PluginError(name, `Unsupported target: ${target}`);
Expand Down
74 changes: 50 additions & 24 deletions packages/plugins/tanstack-query/src/runtime/vue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import {
useMutation,
useQuery,
useQueryClient,
type QueryKey,
type UseInfiniteQueryOptions,
type UseMutationOptions,
type UseQueryOptions,
} from '@tanstack/vue-query';
import type { ModelMeta } from '@zenstackhq/runtime/cross';
import { inject, provide } from 'vue';
import { computed, inject, provide, toValue, type ComputedRef, type MaybeRefOrGetter } from 'vue';
import {
APIContext,
DEFAULT_QUERY_ENDPOINT,
Expand Down Expand Up @@ -61,19 +62,30 @@ export function getHooksContext() {
export function useModelQuery<TQueryFnData, TData, TError>(
model: string,
url: string,
args?: unknown,
options?: Omit<UseQueryOptions<TQueryFnData, TError, TData>, 'queryKey'> & ExtraQueryOptions,
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 reqUrl = makeUrl(url, args);
return useQuery<TQueryFnData, TError, TData>({
queryKey: getQueryKey(model, url, args, {
infinite: false,
optimisticUpdate: options?.optimisticUpdate !== false,
}),
queryFn: () => fetcher<TQueryFnData, false>(reqUrl, undefined, fetch, false),
...options,
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);
}

/**
Expand All @@ -89,17 +101,24 @@ export function useModelQuery<TQueryFnData, TData, TError>(
export function useInfiniteModelQuery<TQueryFnData, TData, TError>(
model: string,
url: string,
args?: unknown,
options?: Omit<UseInfiniteQueryOptions<TQueryFnData, TError, TData>, 'queryKey'>,
args?: MaybeRefOrGetter<unknown> | ComputedRef<unknown>,
options?:
| MaybeRefOrGetter<Omit<UseInfiniteQueryOptions<TQueryFnData, TError, TData>, 'queryKey'>>
| ComputedRef<Omit<UseInfiniteQueryOptions<TQueryFnData, TError, TData>, 'queryKey'>>,
fetch?: FetchFn
) {
return useInfiniteQuery<TQueryFnData, TError, TData>({
// CHECKME: vue-query's `useInfiniteQuery`'s input typing seems wrong
const queryOptions: any = computed(() => ({
queryKey: getQueryKey(model, url, args, { infinite: true, optimisticUpdate: false }),
queryFn: ({ pageParam }) => {
return fetcher<TQueryFnData, false>(makeUrl(url, pageParam ?? args), undefined, fetch, 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);
},
...options,
});
...toValue(options),
}));

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

/**
Expand All @@ -125,7 +144,11 @@ export function useModelMutation<
method: 'POST' | 'PUT' | 'DELETE',
url: string,
modelMeta: ModelMeta,
options?: Omit<UseMutationOptions<Result, TError, TArgs, unknown>, 'mutationFn'> & ExtraMutationOptions,
options?:
| MaybeRefOrGetter<
Omit<UseMutationOptions<Result, TError, TArgs, unknown>, 'mutationFn'> & ExtraMutationOptions
>
| ComputedRef<Omit<UseMutationOptions<Result, TError, TArgs, unknown>, 'mutationFn'> & ExtraMutationOptions>,
fetch?: FetchFn,
checkReadBack?: C
) {
Expand All @@ -144,11 +167,14 @@ export function useModelMutation<
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 = { ...options, mutationFn };
const finalOptions: any = computed(() => ({ ...optionsValue, mutationFn }));
const operation = url.split('/').pop();
const invalidateQueries = options?.invalidateQueries !== false;
const optimisticUpdate = !!options?.optimisticUpdate;
const invalidateQueries = optionsValue?.invalidateQueries !== false;
const optimisticUpdate = !!optionsValue?.optimisticUpdate;

if (operation) {
const { logging } = getHooksContext();
Expand All @@ -157,7 +183,7 @@ export function useModelMutation<
model,
operation,
modelMeta,
finalOptions,
toValue(finalOptions),
(predicate) => queryClient.invalidateQueries({ predicate }),
logging
);
Expand All @@ -168,7 +194,7 @@ export function useModelMutation<
model,
operation,
modelMeta,
finalOptions,
toValue(finalOptions),
queryClient.getQueryCache().getAll(),
(queryKey, data) => queryClient.setQueryData<unknown>(queryKey, data),
invalidateQueries ? (predicate) => queryClient.invalidateQueries({ predicate }) : undefined,
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/trpc/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ export function generateRouterTypingImports(sourceFile: SourceFile, options: Plu

// eslint-disable-next-line @typescript-eslint/no-unused-vars
export function generateRouterSchemaImport(sourceFile: SourceFile, zodSchemasImport: string) {
sourceFile.addStatements(`import $Schema from '${zodSchemasImport}/input';`);
sourceFile.addStatements(`import * as $Schema from '${zodSchemasImport}/input';`);
}

export function generateHelperImport(sourceFile: SourceFile) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable */
import { type RouterFactory, type ProcBuilder, type BaseConfig, db } from '.';
import $Schema from '@zenstackhq/runtime/zod/input';
import * as $Schema from '@zenstackhq/runtime/zod/input';
import { checkRead, checkMutate } from '../helper';
import type { Prisma } from '@prisma/client';
import type {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable */
import { type RouterFactory, type ProcBuilder, type BaseConfig, db } from '.';
import $Schema from '@zenstackhq/runtime/zod/input';
import * as $Schema from '@zenstackhq/runtime/zod/input';
import { checkRead, checkMutate } from '../helper';
import type { Prisma } from '@prisma/client';
import type {
Expand Down
1 change: 1 addition & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 0 additions & 56 deletions tests/integration/tests/regression/issue-1162.test.ts

This file was deleted.

Loading