Skip to content

Commit 51484a7

Browse files
authored
fix: fix react-query code-gen and improve mutation options merging (#314)
1 parent 21ccddb commit 51484a7

File tree

15 files changed

+75
-52
lines changed

15 files changed

+75
-52
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "zenstack-monorepo",
3-
"version": "1.0.0-alpha.94",
3+
"version": "1.0.0-alpha.95",
44
"description": "",
55
"scripts": {
66
"build": "pnpm -r build",

packages/language/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@zenstackhq/language",
3-
"version": "1.0.0-alpha.94",
3+
"version": "1.0.0-alpha.95",
44
"displayName": "ZenStack modeling language compiler",
55
"description": "ZenStack modeling language compiler",
66
"homepage": "https://zenstack.dev",

packages/next/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@zenstackhq/next",
3-
"version": "1.0.0-alpha.94",
3+
"version": "1.0.0-alpha.95",
44
"displayName": "ZenStack Next.js integration",
55
"description": "ZenStack Next.js integration",
66
"homepage": "https://zenstack.dev",

packages/plugins/openapi/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@zenstackhq/openapi",
33
"displayName": "ZenStack Plugin and Runtime for OpenAPI",
4-
"version": "1.0.0-alpha.94",
4+
"version": "1.0.0-alpha.95",
55
"description": "ZenStack plugin and runtime supporting OpenAPI",
66
"main": "index.js",
77
"repository": {

packages/plugins/react/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@zenstackhq/react",
33
"displayName": "ZenStack plugin and runtime for ReactJS",
4-
"version": "1.0.0-alpha.94",
4+
"version": "1.0.0-alpha.95",
55
"description": "ZenStack plugin and runtime for ReactJS",
66
"main": "index.js",
77
"repository": {

packages/plugins/react/src/generator/react-query.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { DMMF } from '@prisma/generator-helper';
22
import { getDataModels, PluginError, PluginOptions } from '@zenstackhq/sdk';
33
import { DataModel, Model } from '@zenstackhq/sdk/ast';
4-
import { paramCase, pascalCase } from 'change-case';
4+
import { camelCase, paramCase, pascalCase } from 'change-case';
55
import * as path from 'path';
66
import { Project, SourceFile, VariableDeclarationKind } from 'ts-morph';
77

@@ -71,7 +71,9 @@ function generateQueryHook(
7171

7272
func.addStatements([
7373
'const { endpoint } = useContext(RequestHandlerContext);',
74-
`return request.query<${returnType}>('${model}', \`\${endpoint}/${model}/${operation}\`, args, options);`,
74+
`return request.query<${returnType}>('${model}', \`\${endpoint}/${camelCase(
75+
model
76+
)}/${operation}\`, args, options);`,
7577
]);
7678
}
7779

@@ -117,7 +119,7 @@ function generateMutationHook(
117119
initializer: `
118120
request.${httpVerb}Mutation<${argsType}, ${
119121
overrideReturnType ?? model
120-
}>('${model}', \`\${endpoint}/${model}/${operation}\`, options, invalidateQueries)
122+
}>('${model}', \`\${endpoint}/${camelCase(model)}/${operation}\`, options, invalidateQueries)
121123
`,
122124
},
123125
],
@@ -173,7 +175,7 @@ function generateModelHooks(project: Project, outDir: string, model: DataModel,
173175

174176
// createMany
175177
if (mapping.createMany) {
176-
generateMutationHook(sf, model.name, 'createMany', 'post');
178+
generateMutationHook(sf, model.name, 'createMany', 'post', 'Prisma.BatchPayload');
177179
}
178180

179181
// findMany

packages/plugins/react/src/runtime/react-query.ts

Lines changed: 54 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
2-
import { useMutation, UseMutationOptions, useQuery, useQueryClient, UseQueryOptions } from '@tanstack/react-query';
2+
import {
3+
useMutation,
4+
useQuery,
5+
useQueryClient,
6+
type MutateFunction,
7+
type QueryClient,
8+
type UseMutationOptions,
9+
type UseQueryOptions,
10+
} from '@tanstack/react-query';
311
import { marshal, registerSerializers } from '../serialization-utils';
412
import { fetcher, makeUrl } from './utils';
513

@@ -43,19 +51,17 @@ export function postMutation<T, R = any>(
4351
invalidateQueries = true
4452
) {
4553
const queryClient = useQueryClient();
46-
const mutation = useMutation<R, unknown, T>({
47-
mutationFn: (data: any) =>
48-
fetcher<R>(url, {
49-
method: 'POST',
50-
headers: {
51-
'content-type': 'application/json',
52-
},
53-
body: marshal(data),
54-
}),
55-
...options,
56-
onSuccess: invalidateQueries ? () => queryClient.invalidateQueries([QUERY_KEY_PREFIX + model]) : undefined,
57-
});
54+
const mutationFn = (data: any) =>
55+
fetcher<R>(url, {
56+
method: 'POST',
57+
headers: {
58+
'content-type': 'application/json',
59+
},
60+
body: marshal(data),
61+
});
5862

63+
const finalOptions = mergeOptions<T, R>(model, options, invalidateQueries, mutationFn, queryClient);
64+
const mutation = useMutation<R, unknown, T>(finalOptions);
5965
return mutation;
6066
}
6167

@@ -75,19 +81,17 @@ export function putMutation<T, R = any>(
7581
invalidateQueries = true
7682
) {
7783
const queryClient = useQueryClient();
78-
const mutation = useMutation<R, unknown, T>({
79-
mutationFn: (data: any) =>
80-
fetcher<R>(url, {
81-
method: 'PUT',
82-
headers: {
83-
'content-type': 'application/json',
84-
},
85-
body: marshal(data),
86-
}),
87-
...options,
88-
onSuccess: invalidateQueries ? () => queryClient.invalidateQueries([QUERY_KEY_PREFIX + model]) : undefined,
89-
});
84+
const mutationFn = (data: any) =>
85+
fetcher<R>(url, {
86+
method: 'PUT',
87+
headers: {
88+
'content-type': 'application/json',
89+
},
90+
body: marshal(data),
91+
});
9092

93+
const finalOptions = mergeOptions<T, R>(model, options, invalidateQueries, mutationFn, queryClient);
94+
const mutation = useMutation<R, unknown, T>(finalOptions);
9195
return mutation;
9296
}
9397

@@ -107,14 +111,31 @@ export function deleteMutation<T, R = any>(
107111
invalidateQueries = true
108112
) {
109113
const queryClient = useQueryClient();
110-
const mutation = useMutation<R, unknown, T>({
111-
mutationFn: (data: any) =>
112-
fetcher<R>(makeUrl(url, data), {
113-
method: 'DELETE',
114-
}),
115-
...options,
116-
onSuccess: invalidateQueries ? () => queryClient.invalidateQueries([QUERY_KEY_PREFIX + model]) : undefined,
117-
});
114+
const mutationFn = (data: any) =>
115+
fetcher<R>(makeUrl(url, data), {
116+
method: 'DELETE',
117+
});
118118

119+
const finalOptions = mergeOptions<T, R>(model, options, invalidateQueries, mutationFn, queryClient);
120+
const mutation = useMutation<R, unknown, T>(finalOptions);
119121
return mutation;
120122
}
123+
124+
function mergeOptions<T, R = any>(
125+
model: string,
126+
options: Omit<UseMutationOptions<R, unknown, T, unknown>, 'mutationFn'> | undefined,
127+
invalidateQueries: boolean,
128+
mutationFn: MutateFunction<R, unknown, T>,
129+
queryClient: QueryClient
130+
): UseMutationOptions<R, unknown, T, unknown> {
131+
const result = { ...options, mutationFn };
132+
if (options?.onSuccess || invalidateQueries) {
133+
result.onSuccess = (...args) => {
134+
if (invalidateQueries) {
135+
queryClient.invalidateQueries([QUERY_KEY_PREFIX + model]);
136+
}
137+
return options?.onSuccess?.(...args);
138+
};
139+
}
140+
return result;
141+
}

packages/plugins/trpc/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@zenstackhq/trpc",
33
"displayName": "ZenStack plugin for tRPC",
4-
"version": "1.0.0-alpha.94",
4+
"version": "1.0.0-alpha.95",
55
"description": "ZenStack plugin for tRPC",
66
"main": "index.js",
77
"repository": {

packages/runtime/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@zenstackhq/runtime",
33
"displayName": "ZenStack Runtime Library",
4-
"version": "1.0.0-alpha.94",
4+
"version": "1.0.0-alpha.95",
55
"description": "Runtime of ZenStack for both client-side and server-side environments.",
66
"repository": {
77
"type": "git",

packages/runtime/src/enhancements/proxy.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ export function makeProxy<T extends PrismaProxyHandler>(
165165
name = 'unnamed_enhancer',
166166
inTransaction = false
167167
) {
168-
const models = Object.keys(modelMeta.fields);
168+
const models = Object.keys(modelMeta.fields).map((k) => k.toLowerCase());
169169
const proxy = new Proxy(prisma, {
170170
get: (target: any, prop: string | symbol, receiver: any) => {
171171
// enhancer metadata
@@ -206,7 +206,7 @@ export function makeProxy<T extends PrismaProxyHandler>(
206206
}
207207
}
208208

209-
if (typeof prop !== 'string' || prop.startsWith('$') || !models.includes(prop)) {
209+
if (typeof prop !== 'string' || prop.startsWith('$') || !models.includes(prop.toLowerCase())) {
210210
// skip non-model fields
211211
return Reflect.get(target, prop, receiver);
212212
}

packages/schema/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"publisher": "zenstack",
44
"displayName": "ZenStack Language Tools",
55
"description": "A toolkit for building secure CRUD apps with Next.js + Typescript",
6-
"version": "1.0.0-alpha.94",
6+
"version": "1.0.0-alpha.95",
77
"author": {
88
"name": "ZenStack Team"
99
},

packages/sdk/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@zenstackhq/sdk",
3-
"version": "1.0.0-alpha.94",
3+
"version": "1.0.0-alpha.95",
44
"description": "ZenStack plugin development SDK",
55
"main": "index.js",
66
"scripts": {

packages/server/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@zenstackhq/server",
3-
"version": "1.0.0-alpha.94",
3+
"version": "1.0.0-alpha.95",
44
"displayName": "ZenStack Server-side Adapters",
55
"description": "ZenStack server-side adapters",
66
"homepage": "https://zenstack.dev",

packages/testtools/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@zenstackhq/testtools",
3-
"version": "1.0.0-alpha.94",
3+
"version": "1.0.0-alpha.95",
44
"description": "ZenStack Test Tools",
55
"main": "index.js",
66
"publishConfig": {

tests/integration/test-run/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)