@zenstackhq/tanstack-query 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/generator.js +70 -37
- package/generator.js.map +1 -1
- package/package.json +40 -9
- package/runtime/common-5e18c135.d.ts +32 -0
- package/runtime/index.d.mts +1 -1
- package/runtime/index.d.ts +1 -1
- package/runtime/index.js +34 -0
- package/runtime/index.js.map +1 -1
- package/runtime/index.mjs +15 -0
- package/runtime/index.mjs.map +1 -1
- package/runtime/react.d.mts +17 -26
- package/runtime/react.d.ts +17 -26
- package/runtime/react.js +105 -72
- package/runtime/react.js.map +1 -1
- package/runtime/react.mjs +102 -68
- package/runtime/react.mjs.map +1 -1
- package/runtime/svelte.d.mts +16 -25
- package/runtime/svelte.d.ts +16 -25
- package/runtime/svelte.js +97 -71
- package/runtime/svelte.js.map +1 -1
- package/runtime/svelte.mjs +93 -66
- package/runtime/svelte.mjs.map +1 -1
- package/runtime/vue.d.mts +17 -27
- package/runtime/vue.d.ts +17 -27
- package/runtime/vue.js +105 -77
- package/runtime/vue.js.map +1 -1
- package/runtime/vue.mjs +101 -71
- package/runtime/vue.mjs.map +1 -1
- package/runtime-v5/common-5e18c135.d.ts +32 -0
- package/runtime-v5/index.d.mts +20 -0
- package/runtime-v5/index.d.ts +20 -0
- package/runtime-v5/index.js +53 -0
- package/runtime-v5/index.js.map +1 -0
- package/runtime-v5/index.mjs +16 -0
- package/runtime-v5/index.mjs.map +1 -0
- package/runtime-v5/react.d.mts +45 -0
- package/runtime-v5/react.d.ts +45 -0
- package/runtime-v5/react.js +269 -0
- package/runtime-v5/react.js.map +1 -0
- package/runtime-v5/react.mjs +237 -0
- package/runtime-v5/react.mjs.map +1 -0
- package/runtime-v5/svelte.d.mts +56 -0
- package/runtime-v5/svelte.d.ts +56 -0
- package/runtime-v5/svelte.js +296 -0
- package/runtime-v5/svelte.js.map +1 -0
- package/runtime-v5/svelte.mjs +264 -0
- package/runtime-v5/svelte.mjs.map +1 -0
- package/runtime-v5/vue.d.mts +52 -0
- package/runtime-v5/vue.d.ts +52 -0
- package/runtime-v5/vue.js +274 -0
- package/runtime-v5/vue.js.map +1 -0
- package/runtime-v5/vue.mjs +240 -0
- package/runtime-v5/vue.mjs.map +1 -0
- package/runtime/common-83308e88.d.ts +0 -19
package/runtime/vue.js
CHANGED
|
@@ -22,6 +22,18 @@ var __spreadValues = (a, b) => {
|
|
|
22
22
|
return a;
|
|
23
23
|
};
|
|
24
24
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
25
|
+
var __objRest = (source, exclude) => {
|
|
26
|
+
var target = {};
|
|
27
|
+
for (var prop in source)
|
|
28
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
29
|
+
target[prop] = source[prop];
|
|
30
|
+
if (source != null && __getOwnPropSymbols)
|
|
31
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
32
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
33
|
+
target[prop] = source[prop];
|
|
34
|
+
}
|
|
35
|
+
return target;
|
|
36
|
+
};
|
|
25
37
|
var __export = (target, all) => {
|
|
26
38
|
for (var name in all)
|
|
27
39
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -68,13 +80,11 @@ var __async = (__this, __arguments, generator) => {
|
|
|
68
80
|
var vue_exports = {};
|
|
69
81
|
__export(vue_exports, {
|
|
70
82
|
VueQueryContextKey: () => VueQueryContextKey,
|
|
71
|
-
|
|
72
|
-
getContext: () => getContext,
|
|
73
|
-
infiniteQuery: () => infiniteQuery,
|
|
74
|
-
postMutation: () => postMutation,
|
|
83
|
+
getHooksContext: () => getHooksContext,
|
|
75
84
|
provideHooksContext: () => provideHooksContext,
|
|
76
|
-
|
|
77
|
-
|
|
85
|
+
useInfiniteModelQuery: () => useInfiniteModelQuery,
|
|
86
|
+
useModelMutation: () => useModelMutation,
|
|
87
|
+
useModelQuery: () => useModelQuery
|
|
78
88
|
});
|
|
79
89
|
module.exports = __toCommonJS(vue_exports);
|
|
80
90
|
var import_vue_query = require("@tanstack/vue-query");
|
|
@@ -82,9 +92,10 @@ var import_vue = require("vue");
|
|
|
82
92
|
|
|
83
93
|
// src/runtime/common.ts
|
|
84
94
|
var import_browser = require("@zenstackhq/runtime/browser");
|
|
95
|
+
var import_cross = require("@zenstackhq/runtime/cross");
|
|
85
96
|
var crossFetch = __toESM(require("cross-fetch"));
|
|
86
97
|
var DEFAULT_QUERY_ENDPOINT = "/api/model";
|
|
87
|
-
var QUERY_KEY_PREFIX = "zenstack
|
|
98
|
+
var QUERY_KEY_PREFIX = "zenstack";
|
|
88
99
|
function fetcher(url, options, fetch2, checkReadBack) {
|
|
89
100
|
return __async(this, null, function* () {
|
|
90
101
|
var _a, _b, _c;
|
|
@@ -111,6 +122,13 @@ function fetcher(url, options, fetch2, checkReadBack) {
|
|
|
111
122
|
}
|
|
112
123
|
});
|
|
113
124
|
}
|
|
125
|
+
function getQueryKey(model, urlOrOperation, args) {
|
|
126
|
+
if (!urlOrOperation) {
|
|
127
|
+
throw new Error("Invalid urlOrOperation");
|
|
128
|
+
}
|
|
129
|
+
const operation = urlOrOperation.split("/").pop();
|
|
130
|
+
return [QUERY_KEY_PREFIX, model, operation, args];
|
|
131
|
+
}
|
|
114
132
|
function marshal(value) {
|
|
115
133
|
const { data, meta } = (0, import_browser.serialize)(value);
|
|
116
134
|
if (meta) {
|
|
@@ -140,105 +158,115 @@ function makeUrl(url, args) {
|
|
|
140
158
|
}
|
|
141
159
|
return result;
|
|
142
160
|
}
|
|
161
|
+
function setupInvalidation(model, operation, modelMeta, options, invalidate, logging = false) {
|
|
162
|
+
const origOnSuccess = options == null ? void 0 : options.onSuccess;
|
|
163
|
+
options.onSuccess = (...args) => __async(this, null, function* () {
|
|
164
|
+
const [_, variables] = args;
|
|
165
|
+
const predicate = yield getInvalidationPredicate(
|
|
166
|
+
model,
|
|
167
|
+
operation,
|
|
168
|
+
variables,
|
|
169
|
+
modelMeta,
|
|
170
|
+
logging
|
|
171
|
+
);
|
|
172
|
+
yield invalidate(predicate);
|
|
173
|
+
return origOnSuccess == null ? void 0 : origOnSuccess(...args);
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
function getInvalidationPredicate(model, operation, mutationArgs, modelMeta, logging = false) {
|
|
177
|
+
return __async(this, null, function* () {
|
|
178
|
+
const mutatedModels = yield (0, import_cross.getMutatedModels)(model, operation, mutationArgs, modelMeta);
|
|
179
|
+
return ({ queryKey }) => {
|
|
180
|
+
const [_model, queryModel, queryOp, args] = queryKey;
|
|
181
|
+
if (mutatedModels.includes(queryModel)) {
|
|
182
|
+
if (logging) {
|
|
183
|
+
console.log(`Invalidating query [${queryKey}] due to mutation "${model}.${operation}"`);
|
|
184
|
+
}
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
if (args) {
|
|
188
|
+
if (findNestedRead(queryModel, mutatedModels, modelMeta, args)) {
|
|
189
|
+
if (logging) {
|
|
190
|
+
console.log(`Invalidating query [${queryKey}] due to mutation "${model}.${operation}"`);
|
|
191
|
+
}
|
|
192
|
+
return true;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return false;
|
|
196
|
+
};
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
function findNestedRead(visitingModel, targetModels, modelMeta, args) {
|
|
200
|
+
const modelsRead = (0, import_cross.getReadModels)(visitingModel, modelMeta, args);
|
|
201
|
+
return targetModels.some((m) => modelsRead.includes(m));
|
|
202
|
+
}
|
|
143
203
|
|
|
144
204
|
// src/runtime/vue.ts
|
|
145
205
|
var VueQueryContextKey = "zenstack-vue-query-context";
|
|
146
206
|
function provideHooksContext(context) {
|
|
147
207
|
(0, import_vue.provide)(VueQueryContextKey, context);
|
|
148
208
|
}
|
|
149
|
-
function
|
|
150
|
-
|
|
209
|
+
function getHooksContext() {
|
|
210
|
+
const _a = (0, import_vue.inject)(VueQueryContextKey, {
|
|
151
211
|
endpoint: DEFAULT_QUERY_ENDPOINT,
|
|
152
|
-
fetch: void 0
|
|
153
|
-
|
|
212
|
+
fetch: void 0,
|
|
213
|
+
logging: false
|
|
214
|
+
}), { endpoint } = _a, rest = __objRest(_a, ["endpoint"]);
|
|
215
|
+
return __spreadValues({ endpoint: endpoint != null ? endpoint : DEFAULT_QUERY_ENDPOINT }, rest);
|
|
154
216
|
}
|
|
155
|
-
function
|
|
217
|
+
function useModelQuery(model, url, args, options, fetch2) {
|
|
156
218
|
const reqUrl = makeUrl(url, args);
|
|
157
219
|
return (0, import_vue_query.useQuery)(__spreadValues({
|
|
158
|
-
queryKey:
|
|
220
|
+
queryKey: getQueryKey(model, url, args),
|
|
159
221
|
queryFn: () => fetcher(reqUrl, void 0, fetch2, false)
|
|
160
222
|
}, options));
|
|
161
223
|
}
|
|
162
|
-
function
|
|
224
|
+
function useInfiniteModelQuery(model, url, args, options, fetch2) {
|
|
163
225
|
return (0, import_vue_query.useInfiniteQuery)(__spreadValues({
|
|
164
|
-
queryKey:
|
|
226
|
+
queryKey: getQueryKey(model, url, args),
|
|
165
227
|
queryFn: ({ pageParam }) => {
|
|
166
228
|
return fetcher(makeUrl(url, pageParam != null ? pageParam : args), void 0, fetch2, false);
|
|
167
229
|
}
|
|
168
230
|
}, options));
|
|
169
231
|
}
|
|
170
|
-
function
|
|
232
|
+
function useModelMutation(model, method, url, modelMeta, options, fetch2, invalidateQueries = true, checkReadBack) {
|
|
171
233
|
const queryClient = (0, import_vue_query.useQueryClient)();
|
|
172
|
-
const mutationFn = (data) =>
|
|
173
|
-
url,
|
|
174
|
-
{
|
|
175
|
-
method
|
|
234
|
+
const mutationFn = (data) => {
|
|
235
|
+
const reqUrl = method === "DELETE" ? makeUrl(url, data) : url;
|
|
236
|
+
const fetchInit = __spreadValues({
|
|
237
|
+
method
|
|
238
|
+
}, method !== "DELETE" && {
|
|
176
239
|
headers: {
|
|
177
240
|
"content-type": "application/json"
|
|
178
241
|
},
|
|
179
242
|
body: marshal(data)
|
|
180
|
-
}
|
|
181
|
-
fetch2,
|
|
182
|
-
|
|
183
|
-
);
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
body: marshal(data)
|
|
198
|
-
},
|
|
199
|
-
fetch2,
|
|
200
|
-
checkReadBack
|
|
201
|
-
);
|
|
202
|
-
const finalOptions = mergeOptions(model, options, invalidateQueries, mutationFn, queryClient);
|
|
203
|
-
const mutation = (0, import_vue_query.useMutation)(finalOptions);
|
|
204
|
-
return mutation;
|
|
205
|
-
}
|
|
206
|
-
function deleteMutation(model, url, options, fetch2, invalidateQueries = true, checkReadBack) {
|
|
207
|
-
const queryClient = (0, import_vue_query.useQueryClient)();
|
|
208
|
-
const mutationFn = (data) => fetcher(
|
|
209
|
-
makeUrl(url, data),
|
|
210
|
-
{
|
|
211
|
-
method: "DELETE"
|
|
212
|
-
},
|
|
213
|
-
fetch2,
|
|
214
|
-
checkReadBack
|
|
215
|
-
);
|
|
216
|
-
const finalOptions = mergeOptions(model, options, invalidateQueries, mutationFn, queryClient);
|
|
217
|
-
const mutation = (0, import_vue_query.useMutation)(finalOptions);
|
|
218
|
-
return mutation;
|
|
219
|
-
}
|
|
220
|
-
function mergeOptions(model, options, invalidateQueries, mutationFn, queryClient) {
|
|
221
|
-
const result = __spreadProps(__spreadValues({}, options), { mutationFn });
|
|
222
|
-
if ((options == null ? void 0 : options.onSuccess) || invalidateQueries) {
|
|
223
|
-
result.onSuccess = (...args) => {
|
|
224
|
-
var _a;
|
|
225
|
-
if (invalidateQueries) {
|
|
226
|
-
queryClient.invalidateQueries([QUERY_KEY_PREFIX + model]);
|
|
227
|
-
}
|
|
228
|
-
return (_a = options == null ? void 0 : options.onSuccess) == null ? void 0 : _a.call(options, ...args);
|
|
229
|
-
};
|
|
243
|
+
});
|
|
244
|
+
return fetcher(reqUrl, fetchInit, fetch2, checkReadBack);
|
|
245
|
+
};
|
|
246
|
+
const finalOptions = __spreadProps(__spreadValues({}, options), { mutationFn });
|
|
247
|
+
if (invalidateQueries) {
|
|
248
|
+
const { logging } = getHooksContext();
|
|
249
|
+
const operation = url.split("/").pop();
|
|
250
|
+
if (operation) {
|
|
251
|
+
setupInvalidation(
|
|
252
|
+
model,
|
|
253
|
+
operation,
|
|
254
|
+
modelMeta,
|
|
255
|
+
finalOptions,
|
|
256
|
+
(predicate) => queryClient.invalidateQueries({ predicate }),
|
|
257
|
+
logging
|
|
258
|
+
);
|
|
259
|
+
}
|
|
230
260
|
}
|
|
231
|
-
return
|
|
261
|
+
return (0, import_vue_query.useMutation)(finalOptions);
|
|
232
262
|
}
|
|
233
263
|
// Annotate the CommonJS export names for ESM import in node:
|
|
234
264
|
0 && (module.exports = {
|
|
235
265
|
VueQueryContextKey,
|
|
236
|
-
|
|
237
|
-
getContext,
|
|
238
|
-
infiniteQuery,
|
|
239
|
-
postMutation,
|
|
266
|
+
getHooksContext,
|
|
240
267
|
provideHooksContext,
|
|
241
|
-
|
|
242
|
-
|
|
268
|
+
useInfiniteModelQuery,
|
|
269
|
+
useModelMutation,
|
|
270
|
+
useModelQuery
|
|
243
271
|
});
|
|
244
272
|
//# sourceMappingURL=vue.js.map
|
package/runtime/vue.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/runtime/vue.ts","../../src/runtime/common.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/ban-types */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n useInfiniteQuery,\n useMutation,\n useQuery,\n useQueryClient,\n type MutateFunction,\n type QueryClient,\n type UseInfiniteQueryOptions,\n type UseMutationOptions,\n type UseQueryOptions,\n} from '@tanstack/vue-query';\nimport { inject, provide } from 'vue';\nimport { APIContext, DEFAULT_QUERY_ENDPOINT, FetchFn, QUERY_KEY_PREFIX, fetcher, makeUrl, marshal } from './common';\n\nexport { APIContext as RequestHandlerContext } from './common';\n\nexport const VueQueryContextKey = 'zenstack-vue-query-context';\n\n/**\n * Provide context for the generated TanStack Query hooks.\n */\nexport function provideHooksContext(context: APIContext) {\n provide<APIContext>(VueQueryContextKey, context);\n}\n\nexport function getContext() {\n return inject<APIContext>(VueQueryContextKey, {\n endpoint: DEFAULT_QUERY_ENDPOINT,\n fetch: undefined,\n });\n}\n\n/**\n * Creates a vue-query query.\n *\n * @param model The name of the model under query.\n * @param url The request URL.\n * @param args The request args object, URL-encoded and appended as \"?q=\" parameter\n * @param options The vue-query options object\n * @returns useQuery hook\n */\nexport function query<R>(model: string, url: string, args?: unknown, options?: UseQueryOptions<R>, fetch?: FetchFn) {\n const reqUrl = makeUrl(url, args);\n return useQuery<R>({\n queryKey: [QUERY_KEY_PREFIX + model, url, args],\n queryFn: () => fetcher<R, false>(reqUrl, undefined, fetch, false),\n ...options,\n });\n}\n\n/**\n * Creates a vue-query infinite query.\n *\n * @param model The name of the model under query.\n * @param url The request URL.\n * @param args The initial request args object, URL-encoded and appended as \"?q=\" parameter\n * @param options The vue-query infinite query options object\n * @returns useInfiniteQuery hook\n */\nexport function infiniteQuery<R>(\n model: string,\n url: string,\n args?: unknown,\n options?: UseInfiniteQueryOptions<R>,\n fetch?: FetchFn\n) {\n return useInfiniteQuery<R>({\n queryKey: [QUERY_KEY_PREFIX + model, url, args],\n queryFn: ({ pageParam }) => {\n return fetcher<R, false>(makeUrl(url, pageParam ?? args), undefined, fetch, false);\n },\n ...options,\n });\n}\n\n/**\n * Creates a POST mutation with vue-query.\n *\n * @param model The name of the model under mutation.\n * @param url The request URL.\n * @param options The vue-query options.\n * @param invalidateQueries Whether to invalidate queries after mutation.\n * @returns useMutation hooks\n */\nexport function postMutation<T, R = any, C extends boolean = boolean, Result = C extends true ? R | undefined : R>(\n model: string,\n url: string,\n options?: Omit<UseMutationOptions<Result, unknown, T, unknown>, 'mutationFn'>,\n fetch?: FetchFn,\n invalidateQueries = true,\n checkReadBack?: C\n) {\n const queryClient = useQueryClient();\n const mutationFn = (data: any) =>\n fetcher<R, C>(\n url,\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n },\n body: marshal(data),\n },\n fetch,\n checkReadBack\n ) as Promise<Result>;\n\n // TODO: figure out the typing problem\n const finalOptions: any = mergeOptions<T, Result>(model, options, invalidateQueries, mutationFn, queryClient);\n const mutation = useMutation<Result, unknown, T>(finalOptions);\n return mutation;\n}\n\n/**\n * Creates a PUT mutation with vue-query.\n *\n * @param model The name of the model under mutation.\n * @param url The request URL.\n * @param options The vue-query options.\n * @param invalidateQueries Whether to invalidate queries after mutation.\n * @returns useMutation hooks\n */\nexport function putMutation<T, R = any, C extends boolean = boolean, Result = C extends true ? R | undefined : R>(\n model: string,\n url: string,\n options?: Omit<UseMutationOptions<Result, unknown, T, unknown>, 'mutationFn'>,\n fetch?: FetchFn,\n invalidateQueries = true,\n checkReadBack?: C\n) {\n const queryClient = useQueryClient();\n const mutationFn = (data: any) =>\n fetcher<R, C>(\n url,\n {\n method: 'PUT',\n headers: {\n 'content-type': 'application/json',\n },\n body: marshal(data),\n },\n fetch,\n checkReadBack\n ) as Promise<Result>;\n\n // TODO: figure out the typing problem\n const finalOptions: any = mergeOptions<T, Result>(model, options, invalidateQueries, mutationFn, queryClient);\n const mutation = useMutation<Result, unknown, T>(finalOptions);\n return mutation;\n}\n\n/**\n * Creates a DELETE mutation with vue-query.\n *\n * @param model The name of the model under mutation.\n * @param url The request URL.\n * @param options The vue-query options.\n * @param invalidateQueries Whether to invalidate queries after mutation.\n * @returns useMutation hooks\n */\nexport function deleteMutation<T, R = any, C extends boolean = boolean, Result = C extends true ? R | undefined : R>(\n model: string,\n url: string,\n options?: Omit<UseMutationOptions<Result, unknown, T, unknown>, 'mutationFn'>,\n fetch?: FetchFn,\n invalidateQueries = true,\n checkReadBack?: C\n) {\n const queryClient = useQueryClient();\n const mutationFn = (data: any) =>\n fetcher<R, C>(\n makeUrl(url, data),\n {\n method: 'DELETE',\n },\n fetch,\n checkReadBack\n ) as Promise<Result>;\n\n // TODO: figure out the typing problem\n const finalOptions: any = mergeOptions<T, Result>(model, options, invalidateQueries, mutationFn, queryClient);\n const mutation = useMutation<Result, unknown, T>(finalOptions);\n return mutation;\n}\n\nfunction mergeOptions<T, R = any>(\n model: string,\n options: Omit<UseMutationOptions<R, unknown, T, unknown>, 'mutationFn'> | undefined,\n invalidateQueries: boolean,\n mutationFn: MutateFunction<R, unknown, T>,\n queryClient: QueryClient\n): UseMutationOptions<R, unknown, T, unknown> {\n const result = { ...options, mutationFn };\n if (options?.onSuccess || invalidateQueries) {\n result.onSuccess = (...args) => {\n if (invalidateQueries) {\n queryClient.invalidateQueries([QUERY_KEY_PREFIX + model]);\n }\n return options?.onSuccess?.(...args);\n };\n }\n return result;\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { deserialize, serialize } from '@zenstackhq/runtime/browser';\nimport * as crossFetch from 'cross-fetch';\n\n/**\n * The default query endpoint.\n */\nexport const DEFAULT_QUERY_ENDPOINT = '/api/model';\n\n/**\n * Prefix for react-query keys.\n */\nexport const QUERY_KEY_PREFIX = 'zenstack:';\n\n/**\n * Function signature for `fetch`.\n */\nexport type FetchFn = (url: string, options?: RequestInit) => Promise<Response>;\n\n/**\n * Context type for configuring the hooks.\n */\nexport type APIContext = {\n /**\n * The endpoint to use for the queries.\n */\n endpoint?: string;\n\n /**\n * A custom fetch function for sending the HTTP requests.\n */\n fetch?: FetchFn;\n};\n\nexport async function fetcher<R, C extends boolean>(\n url: string,\n options?: RequestInit,\n fetch?: FetchFn,\n checkReadBack?: C\n): Promise<C extends true ? R | undefined : R> {\n const _fetch = fetch ?? crossFetch.fetch;\n const res = await _fetch(url, options);\n if (!res.ok) {\n const errData = unmarshal(await res.text());\n if (\n checkReadBack !== false &&\n errData.error?.prisma &&\n errData.error?.code === 'P2004' &&\n errData.error?.reason === 'RESULT_NOT_READABLE'\n ) {\n // policy doesn't allow mutation result to be read back, just return undefined\n return undefined as any;\n }\n const error: Error & { info?: unknown; status?: number } = new Error(\n 'An error occurred while fetching the data.'\n );\n error.info = errData.error;\n error.status = res.status;\n throw error;\n }\n\n const textResult = await res.text();\n try {\n return unmarshal(textResult).data as R;\n } catch (err) {\n console.error(`Unable to deserialize data:`, textResult);\n throw err;\n }\n}\n\nexport function marshal(value: unknown) {\n const { data, meta } = serialize(value);\n if (meta) {\n return JSON.stringify({ ...(data as any), meta: { serialization: meta } });\n } else {\n return JSON.stringify(data);\n }\n}\n\nexport function unmarshal(value: string) {\n const parsed = JSON.parse(value);\n if (parsed.data && parsed.meta?.serialization) {\n const deserializedData = deserialize(parsed.data, parsed.meta.serialization);\n return { ...parsed, data: deserializedData };\n } else {\n return parsed;\n }\n}\n\nexport function makeUrl(url: string, args: unknown) {\n if (!args) {\n return url;\n }\n\n const { data, meta } = serialize(args);\n let result = `${url}?q=${encodeURIComponent(JSON.stringify(data))}`;\n if (meta) {\n result += `&meta=${encodeURIComponent(JSON.stringify({ serialization: meta }))}`;\n }\n return result;\n}\n"],"mappings":"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","names":["fetch","fetch"]}
|
|
1
|
+
{"version":3,"sources":["../../src/runtime/vue.ts","../../src/runtime/common.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/ban-types */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n useInfiniteQuery,\n useMutation,\n useQuery,\n useQueryClient,\n type UseInfiniteQueryOptions,\n type UseMutationOptions,\n type UseQueryOptions,\n} from '@tanstack/vue-query';\nimport type { ModelMeta } from '@zenstackhq/runtime/cross';\nimport { inject, provide } from 'vue';\nimport {\n APIContext,\n DEFAULT_QUERY_ENDPOINT,\n FetchFn,\n fetcher,\n getQueryKey,\n makeUrl,\n marshal,\n setupInvalidation,\n} from './common';\n\nexport { APIContext as RequestHandlerContext } from './common';\n\nexport const VueQueryContextKey = 'zenstack-vue-query-context';\n\n/**\n * Provide context for the generated TanStack Query hooks.\n */\nexport function provideHooksContext(context: APIContext) {\n provide<APIContext>(VueQueryContextKey, context);\n}\n\n/**\n * Hooks context.\n */\nexport function getHooksContext() {\n const { endpoint, ...rest } = inject<APIContext>(VueQueryContextKey, {\n endpoint: DEFAULT_QUERY_ENDPOINT,\n fetch: undefined,\n logging: false,\n });\n return { endpoint: endpoint ?? DEFAULT_QUERY_ENDPOINT, ...rest };\n}\n\n/**\n * Creates a vue-query query.\n *\n * @param model The name of the model under query.\n * @param url The request URL.\n * @param args The request args object, URL-encoded and appended as \"?q=\" parameter\n * @param options The vue-query options object\n * @returns useQuery hook\n */\nexport function useModelQuery<R>(\n model: string,\n url: string,\n args?: unknown,\n options?: UseQueryOptions<R>,\n fetch?: FetchFn\n) {\n const reqUrl = makeUrl(url, args);\n return useQuery<R>({\n queryKey: getQueryKey(model, url, args),\n queryFn: () => fetcher<R, false>(reqUrl, undefined, fetch, false),\n ...options,\n });\n}\n\n/**\n * Creates a vue-query infinite query.\n *\n * @param model The name of the model under query.\n * @param url The request URL.\n * @param args The initial request args object, URL-encoded and appended as \"?q=\" parameter\n * @param options The vue-query infinite query options object\n * @returns useInfiniteQuery hook\n */\nexport function useInfiniteModelQuery<R>(\n model: string,\n url: string,\n args?: unknown,\n options?: UseInfiniteQueryOptions<R>,\n fetch?: FetchFn\n) {\n return useInfiniteQuery<R>({\n queryKey: getQueryKey(model, url, args),\n queryFn: ({ pageParam }) => {\n return fetcher<R, false>(makeUrl(url, pageParam ?? args), undefined, fetch, false);\n },\n ...options,\n });\n}\n\n/**\n * Creates a mutation with vue-query.\n *\n * @param model The name of the model under mutation.\n * @param method The HTTP method.\n * @param modelMeta The model metadata.\n * @param url The request URL.\n * @param options The vue-query options.\n * @param invalidateQueries Whether to invalidate queries after mutation.\n * @returns useMutation hooks\n */\nexport function useModelMutation<T, R = any, C extends boolean = boolean, Result = C extends true ? R | undefined : R>(\n model: string,\n method: 'POST' | 'PUT' | 'DELETE',\n url: string,\n modelMeta: ModelMeta,\n options?: Omit<UseMutationOptions<Result, unknown, T, unknown>, 'mutationFn'>,\n fetch?: FetchFn,\n invalidateQueries = true,\n checkReadBack?: C\n) {\n const queryClient = useQueryClient();\n const mutationFn = (data: any) => {\n const reqUrl = method === 'DELETE' ? makeUrl(url, data) : url;\n const fetchInit: RequestInit = {\n method,\n ...(method !== 'DELETE' && {\n headers: {\n 'content-type': 'application/json',\n },\n body: marshal(data),\n }),\n };\n return fetcher<R, C>(reqUrl, fetchInit, fetch, checkReadBack) as Promise<Result>;\n };\n\n // TODO: figure out the typing problem\n const finalOptions: any = { ...options, mutationFn };\n if (invalidateQueries) {\n const { logging } = getHooksContext();\n const operation = url.split('/').pop();\n if (operation) {\n setupInvalidation(\n model,\n operation,\n modelMeta,\n finalOptions,\n (predicate) => queryClient.invalidateQueries({ predicate }),\n logging\n );\n }\n }\n return useMutation<Result, unknown, T>(finalOptions);\n}\n","/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { deserialize, serialize } from '@zenstackhq/runtime/browser';\nimport { getMutatedModels, getReadModels, type ModelMeta, type PrismaWriteActionType } from '@zenstackhq/runtime/cross';\nimport * as crossFetch from 'cross-fetch';\n\n/**\n * The default query endpoint.\n */\nexport const DEFAULT_QUERY_ENDPOINT = '/api/model';\n\n/**\n * Prefix for react-query keys.\n */\nexport const QUERY_KEY_PREFIX = 'zenstack';\n\n/**\n * Function signature for `fetch`.\n */\nexport type FetchFn = (url: string, options?: RequestInit) => Promise<Response>;\n\n/**\n * Context type for configuring the hooks.\n */\nexport type APIContext = {\n /**\n * The endpoint to use for the queries.\n */\n endpoint?: string;\n\n /**\n * A custom fetch function for sending the HTTP requests.\n */\n fetch?: FetchFn;\n\n /**\n * If logging is enabled.\n */\n logging?: boolean;\n};\n\nexport async function fetcher<R, C extends boolean>(\n url: string,\n options?: RequestInit,\n fetch?: FetchFn,\n checkReadBack?: C\n): Promise<C extends true ? R | undefined : R> {\n const _fetch = fetch ?? crossFetch.fetch;\n const res = await _fetch(url, options);\n if (!res.ok) {\n const errData = unmarshal(await res.text());\n if (\n checkReadBack !== false &&\n errData.error?.prisma &&\n errData.error?.code === 'P2004' &&\n errData.error?.reason === 'RESULT_NOT_READABLE'\n ) {\n // policy doesn't allow mutation result to be read back, just return undefined\n return undefined as any;\n }\n const error: Error & { info?: unknown; status?: number } = new Error(\n 'An error occurred while fetching the data.'\n );\n error.info = errData.error;\n error.status = res.status;\n throw error;\n }\n\n const textResult = await res.text();\n try {\n return unmarshal(textResult).data as R;\n } catch (err) {\n console.error(`Unable to deserialize data:`, textResult);\n throw err;\n }\n}\n\ntype QueryKey = [string /* prefix */, string /* model */, string /* operation */, unknown /* args */];\n\n/**\n * Computes query key for the given model, operation and query args.\n * @param model Model name.\n * @param urlOrOperation Prisma operation (e.g, `findMany`) or request URL. If it's a URL, the last path segment will be used as the operation name.\n * @param args Prisma query arguments.\n * @returns Query key\n */\nexport function getQueryKey(model: string, urlOrOperation: string, args: unknown): QueryKey {\n if (!urlOrOperation) {\n throw new Error('Invalid urlOrOperation');\n }\n const operation = urlOrOperation.split('/').pop();\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return [QUERY_KEY_PREFIX, model, operation!, args];\n}\n\nexport function marshal(value: unknown) {\n const { data, meta } = serialize(value);\n if (meta) {\n return JSON.stringify({ ...(data as any), meta: { serialization: meta } });\n } else {\n return JSON.stringify(data);\n }\n}\n\nexport function unmarshal(value: string) {\n const parsed = JSON.parse(value);\n if (parsed.data && parsed.meta?.serialization) {\n const deserializedData = deserialize(parsed.data, parsed.meta.serialization);\n return { ...parsed, data: deserializedData };\n } else {\n return parsed;\n }\n}\n\nexport function makeUrl(url: string, args: unknown) {\n if (!args) {\n return url;\n }\n\n const { data, meta } = serialize(args);\n let result = `${url}?q=${encodeURIComponent(JSON.stringify(data))}`;\n if (meta) {\n result += `&meta=${encodeURIComponent(JSON.stringify({ serialization: meta }))}`;\n }\n return result;\n}\n\ntype InvalidationPredicate = ({ queryKey }: { queryKey: readonly unknown[] }) => boolean;\n\n// sets up invalidation hook for a mutation\nexport function setupInvalidation(\n model: string,\n operation: string,\n modelMeta: ModelMeta,\n options: { onSuccess?: (...args: any[]) => any },\n invalidate: (predicate: InvalidationPredicate) => Promise<void>,\n logging = false\n) {\n const origOnSuccess = options?.onSuccess;\n options.onSuccess = async (...args: unknown[]) => {\n const [_, variables] = args;\n const predicate = await getInvalidationPredicate(\n model,\n operation as PrismaWriteActionType,\n variables,\n modelMeta,\n logging\n );\n await invalidate(predicate);\n return origOnSuccess?.(...args);\n };\n}\n\n// gets a predicate for evaluating whether a query should be invalidated\nasync function getInvalidationPredicate(\n model: string,\n operation: PrismaWriteActionType,\n mutationArgs: any,\n modelMeta: ModelMeta,\n logging = false\n) {\n const mutatedModels = await getMutatedModels(model, operation, mutationArgs, modelMeta);\n\n return ({ queryKey }: { queryKey: readonly unknown[] }) => {\n const [_model, queryModel, queryOp, args] = queryKey as QueryKey;\n\n if (mutatedModels.includes(queryModel)) {\n // direct match\n if (logging) {\n console.log(`Invalidating query [${queryKey}] due to mutation \"${model}.${operation}\"`);\n }\n return true;\n }\n\n if (args) {\n // traverse query args to find nested reads that match the model under mutation\n if (findNestedRead(queryModel, mutatedModels, modelMeta, args)) {\n if (logging) {\n console.log(`Invalidating query [${queryKey}] due to mutation \"${model}.${operation}\"`);\n }\n return true;\n }\n }\n\n return false;\n };\n}\n\n// find nested reads that match the given models\nfunction findNestedRead(visitingModel: string, targetModels: string[], modelMeta: ModelMeta, args: any) {\n const modelsRead = getReadModels(visitingModel, modelMeta, args);\n return targetModels.some((m) => modelsRead.includes(m));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,uBAQO;AAEP,iBAAgC;;;ACVhC,qBAAuC;AACvC,mBAA4F;AAC5F,iBAA4B;AAKrB,IAAM,yBAAyB;AAK/B,IAAM,mBAAmB;AA2BhC,SAAsB,QAClB,KACA,SACAA,QACA,eAC2C;AAAA;AA9C/C;AA+CI,UAAM,SAASA,UAAA,OAAAA,SAAoB;AACnC,UAAM,MAAM,MAAM,OAAO,KAAK,OAAO;AACrC,QAAI,CAAC,IAAI,IAAI;AACT,YAAM,UAAU,UAAU,MAAM,IAAI,KAAK,CAAC;AAC1C,UACI,kBAAkB,WAClB,aAAQ,UAAR,mBAAe,aACf,aAAQ,UAAR,mBAAe,UAAS,aACxB,aAAQ,UAAR,mBAAe,YAAW,uBAC5B;AAEE,eAAO;AAAA,MACX;AACA,YAAM,QAAqD,IAAI;AAAA,QAC3D;AAAA,MACJ;AACA,YAAM,OAAO,QAAQ;AACrB,YAAM,SAAS,IAAI;AACnB,YAAM;AAAA,IACV;AAEA,UAAM,aAAa,MAAM,IAAI,KAAK;AAClC,QAAI;AACA,aAAO,UAAU,UAAU,EAAE;AAAA,IACjC,SAAS,KAAK;AACV,cAAQ,MAAM,+BAA+B,UAAU;AACvD,YAAM;AAAA,IACV;AAAA,EACJ;AAAA;AAWO,SAAS,YAAY,OAAe,gBAAwB,MAAyB;AACxF,MAAI,CAAC,gBAAgB;AACjB,UAAM,IAAI,MAAM,wBAAwB;AAAA,EAC5C;AACA,QAAM,YAAY,eAAe,MAAM,GAAG,EAAE,IAAI;AAEhD,SAAO,CAAC,kBAAkB,OAAO,WAAY,IAAI;AACrD;AAEO,SAAS,QAAQ,OAAgB;AACpC,QAAM,EAAE,MAAM,KAAK,QAAI,0BAAU,KAAK;AACtC,MAAI,MAAM;AACN,WAAO,KAAK,UAAU,iCAAM,OAAN,EAAoB,MAAM,EAAE,eAAe,KAAK,EAAE,EAAC;AAAA,EAC7E,OAAO;AACH,WAAO,KAAK,UAAU,IAAI;AAAA,EAC9B;AACJ;AAEO,SAAS,UAAU,OAAe;AAxGzC;AAyGI,QAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,MAAI,OAAO,UAAQ,YAAO,SAAP,mBAAa,gBAAe;AAC3C,UAAM,uBAAmB,4BAAY,OAAO,MAAM,OAAO,KAAK,aAAa;AAC3E,WAAO,iCAAK,SAAL,EAAa,MAAM,iBAAiB;AAAA,EAC/C,OAAO;AACH,WAAO;AAAA,EACX;AACJ;AAEO,SAAS,QAAQ,KAAa,MAAe;AAChD,MAAI,CAAC,MAAM;AACP,WAAO;AAAA,EACX;AAEA,QAAM,EAAE,MAAM,KAAK,QAAI,0BAAU,IAAI;AACrC,MAAI,SAAS,GAAG,GAAG,MAAM,mBAAmB,KAAK,UAAU,IAAI,CAAC,CAAC;AACjE,MAAI,MAAM;AACN,cAAU,SAAS,mBAAmB,KAAK,UAAU,EAAE,eAAe,KAAK,CAAC,CAAC,CAAC;AAAA,EAClF;AACA,SAAO;AACX;AAKO,SAAS,kBACZ,OACA,WACA,WACA,SACA,YACA,UAAU,OACZ;AACE,QAAM,gBAAgB,mCAAS;AAC/B,UAAQ,YAAY,IAAU,SAAoB;AAC9C,UAAM,CAAC,GAAG,SAAS,IAAI;AACvB,UAAM,YAAY,MAAM;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACJ;AACA,UAAM,WAAW,SAAS;AAC1B,WAAO,+CAAgB,GAAG;AAAA,EAC9B;AACJ;AAGA,SAAe,yBACX,OACA,WACA,cACA,WACA,UAAU,OACZ;AAAA;AACE,UAAM,gBAAgB,UAAM,+BAAiB,OAAO,WAAW,cAAc,SAAS;AAEtF,WAAO,CAAC,EAAE,SAAS,MAAwC;AACvD,YAAM,CAAC,QAAQ,YAAY,SAAS,IAAI,IAAI;AAE5C,UAAI,cAAc,SAAS,UAAU,GAAG;AAEpC,YAAI,SAAS;AACT,kBAAQ,IAAI,uBAAuB,QAAQ,sBAAsB,KAAK,IAAI,SAAS,GAAG;AAAA,QAC1F;AACA,eAAO;AAAA,MACX;AAEA,UAAI,MAAM;AAEN,YAAI,eAAe,YAAY,eAAe,WAAW,IAAI,GAAG;AAC5D,cAAI,SAAS;AACT,oBAAQ,IAAI,uBAAuB,QAAQ,sBAAsB,KAAK,IAAI,SAAS,GAAG;AAAA,UAC1F;AACA,iBAAO;AAAA,QACX;AAAA,MACJ;AAEA,aAAO;AAAA,IACX;AAAA,EACJ;AAAA;AAGA,SAAS,eAAe,eAAuB,cAAwB,WAAsB,MAAW;AACpG,QAAM,iBAAa,4BAAc,eAAe,WAAW,IAAI;AAC/D,SAAO,aAAa,KAAK,CAAC,MAAM,WAAW,SAAS,CAAC,CAAC;AAC1D;;;ADtKO,IAAM,qBAAqB;AAK3B,SAAS,oBAAoB,SAAqB;AACrD,0BAAoB,oBAAoB,OAAO;AACnD;AAKO,SAAS,kBAAkB;AAC9B,QAA8B,4BAAmB,oBAAoB;AAAA,IACjE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,SAAS;AAAA,EACb,CAAC,GAJO,WAvCZ,IAuCkC,IAAT,iBAAS,IAAT,CAAb;AAKR,SAAO,iBAAE,UAAU,8BAAY,0BAA2B;AAC9D;AAWO,SAAS,cACZ,OACA,KACA,MACA,SACAC,QACF;AACE,QAAM,SAAS,QAAQ,KAAK,IAAI;AAChC,aAAO,2BAAY;AAAA,IACf,UAAU,YAAY,OAAO,KAAK,IAAI;AAAA,IACtC,SAAS,MAAM,QAAkB,QAAQ,QAAWA,QAAO,KAAK;AAAA,KAC7D,QACN;AACL;AAWO,SAAS,sBACZ,OACA,KACA,MACA,SACAA,QACF;AACE,aAAO,mCAAoB;AAAA,IACvB,UAAU,YAAY,OAAO,KAAK,IAAI;AAAA,IACtC,SAAS,CAAC,EAAE,UAAU,MAAM;AACxB,aAAO,QAAkB,QAAQ,KAAK,gCAAa,IAAI,GAAG,QAAWA,QAAO,KAAK;AAAA,IACrF;AAAA,KACG,QACN;AACL;AAaO,SAAS,iBACZ,OACA,QACA,KACA,WACA,SACAA,QACA,oBAAoB,MACpB,eACF;AACE,QAAM,kBAAc,iCAAe;AACnC,QAAM,aAAa,CAAC,SAAc;AAC9B,UAAM,SAAS,WAAW,WAAW,QAAQ,KAAK,IAAI,IAAI;AAC1D,UAAM,YAAyB;AAAA,MAC3B;AAAA,OACI,WAAW,YAAY;AAAA,MACvB,SAAS;AAAA,QACL,gBAAgB;AAAA,MACpB;AAAA,MACA,MAAM,QAAQ,IAAI;AAAA,IACtB;AAEJ,WAAO,QAAc,QAAQ,WAAWA,QAAO,aAAa;AAAA,EAChE;AAGA,QAAM,eAAoB,iCAAK,UAAL,EAAc,WAAW;AACnD,MAAI,mBAAmB;AACnB,UAAM,EAAE,QAAQ,IAAI,gBAAgB;AACpC,UAAM,YAAY,IAAI,MAAM,GAAG,EAAE,IAAI;AACrC,QAAI,WAAW;AACX;AAAA,QACI;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,CAAC,cAAc,YAAY,kBAAkB,EAAE,UAAU,CAAC;AAAA,QAC1D;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AACA,aAAO,8BAAgC,YAAY;AACvD;","names":["fetch","fetch"]}
|
package/runtime/vue.mjs
CHANGED
|
@@ -17,6 +17,18 @@ var __spreadValues = (a, b) => {
|
|
|
17
17
|
return a;
|
|
18
18
|
};
|
|
19
19
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
+
var __objRest = (source, exclude) => {
|
|
21
|
+
var target = {};
|
|
22
|
+
for (var prop in source)
|
|
23
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
24
|
+
target[prop] = source[prop];
|
|
25
|
+
if (source != null && __getOwnPropSymbols)
|
|
26
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
27
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
28
|
+
target[prop] = source[prop];
|
|
29
|
+
}
|
|
30
|
+
return target;
|
|
31
|
+
};
|
|
20
32
|
var __async = (__this, __arguments, generator) => {
|
|
21
33
|
return new Promise((resolve, reject) => {
|
|
22
34
|
var fulfilled = (value) => {
|
|
@@ -49,9 +61,10 @@ import { inject, provide } from "vue";
|
|
|
49
61
|
|
|
50
62
|
// src/runtime/common.ts
|
|
51
63
|
import { deserialize, serialize } from "@zenstackhq/runtime/browser";
|
|
64
|
+
import { getMutatedModels, getReadModels } from "@zenstackhq/runtime/cross";
|
|
52
65
|
import * as crossFetch from "cross-fetch";
|
|
53
66
|
var DEFAULT_QUERY_ENDPOINT = "/api/model";
|
|
54
|
-
var QUERY_KEY_PREFIX = "zenstack
|
|
67
|
+
var QUERY_KEY_PREFIX = "zenstack";
|
|
55
68
|
function fetcher(url, options, fetch2, checkReadBack) {
|
|
56
69
|
return __async(this, null, function* () {
|
|
57
70
|
var _a, _b, _c;
|
|
@@ -78,6 +91,13 @@ function fetcher(url, options, fetch2, checkReadBack) {
|
|
|
78
91
|
}
|
|
79
92
|
});
|
|
80
93
|
}
|
|
94
|
+
function getQueryKey(model, urlOrOperation, args) {
|
|
95
|
+
if (!urlOrOperation) {
|
|
96
|
+
throw new Error("Invalid urlOrOperation");
|
|
97
|
+
}
|
|
98
|
+
const operation = urlOrOperation.split("/").pop();
|
|
99
|
+
return [QUERY_KEY_PREFIX, model, operation, args];
|
|
100
|
+
}
|
|
81
101
|
function marshal(value) {
|
|
82
102
|
const { data, meta } = serialize(value);
|
|
83
103
|
if (meta) {
|
|
@@ -107,104 +127,114 @@ function makeUrl(url, args) {
|
|
|
107
127
|
}
|
|
108
128
|
return result;
|
|
109
129
|
}
|
|
130
|
+
function setupInvalidation(model, operation, modelMeta, options, invalidate, logging = false) {
|
|
131
|
+
const origOnSuccess = options == null ? void 0 : options.onSuccess;
|
|
132
|
+
options.onSuccess = (...args) => __async(this, null, function* () {
|
|
133
|
+
const [_, variables] = args;
|
|
134
|
+
const predicate = yield getInvalidationPredicate(
|
|
135
|
+
model,
|
|
136
|
+
operation,
|
|
137
|
+
variables,
|
|
138
|
+
modelMeta,
|
|
139
|
+
logging
|
|
140
|
+
);
|
|
141
|
+
yield invalidate(predicate);
|
|
142
|
+
return origOnSuccess == null ? void 0 : origOnSuccess(...args);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
function getInvalidationPredicate(model, operation, mutationArgs, modelMeta, logging = false) {
|
|
146
|
+
return __async(this, null, function* () {
|
|
147
|
+
const mutatedModels = yield getMutatedModels(model, operation, mutationArgs, modelMeta);
|
|
148
|
+
return ({ queryKey }) => {
|
|
149
|
+
const [_model, queryModel, queryOp, args] = queryKey;
|
|
150
|
+
if (mutatedModels.includes(queryModel)) {
|
|
151
|
+
if (logging) {
|
|
152
|
+
console.log(`Invalidating query [${queryKey}] due to mutation "${model}.${operation}"`);
|
|
153
|
+
}
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
if (args) {
|
|
157
|
+
if (findNestedRead(queryModel, mutatedModels, modelMeta, args)) {
|
|
158
|
+
if (logging) {
|
|
159
|
+
console.log(`Invalidating query [${queryKey}] due to mutation "${model}.${operation}"`);
|
|
160
|
+
}
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return false;
|
|
165
|
+
};
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
function findNestedRead(visitingModel, targetModels, modelMeta, args) {
|
|
169
|
+
const modelsRead = getReadModels(visitingModel, modelMeta, args);
|
|
170
|
+
return targetModels.some((m) => modelsRead.includes(m));
|
|
171
|
+
}
|
|
110
172
|
|
|
111
173
|
// src/runtime/vue.ts
|
|
112
174
|
var VueQueryContextKey = "zenstack-vue-query-context";
|
|
113
175
|
function provideHooksContext(context) {
|
|
114
176
|
provide(VueQueryContextKey, context);
|
|
115
177
|
}
|
|
116
|
-
function
|
|
117
|
-
|
|
178
|
+
function getHooksContext() {
|
|
179
|
+
const _a = inject(VueQueryContextKey, {
|
|
118
180
|
endpoint: DEFAULT_QUERY_ENDPOINT,
|
|
119
|
-
fetch: void 0
|
|
120
|
-
|
|
181
|
+
fetch: void 0,
|
|
182
|
+
logging: false
|
|
183
|
+
}), { endpoint } = _a, rest = __objRest(_a, ["endpoint"]);
|
|
184
|
+
return __spreadValues({ endpoint: endpoint != null ? endpoint : DEFAULT_QUERY_ENDPOINT }, rest);
|
|
121
185
|
}
|
|
122
|
-
function
|
|
186
|
+
function useModelQuery(model, url, args, options, fetch2) {
|
|
123
187
|
const reqUrl = makeUrl(url, args);
|
|
124
188
|
return useQuery(__spreadValues({
|
|
125
|
-
queryKey:
|
|
189
|
+
queryKey: getQueryKey(model, url, args),
|
|
126
190
|
queryFn: () => fetcher(reqUrl, void 0, fetch2, false)
|
|
127
191
|
}, options));
|
|
128
192
|
}
|
|
129
|
-
function
|
|
193
|
+
function useInfiniteModelQuery(model, url, args, options, fetch2) {
|
|
130
194
|
return useInfiniteQuery(__spreadValues({
|
|
131
|
-
queryKey:
|
|
195
|
+
queryKey: getQueryKey(model, url, args),
|
|
132
196
|
queryFn: ({ pageParam }) => {
|
|
133
197
|
return fetcher(makeUrl(url, pageParam != null ? pageParam : args), void 0, fetch2, false);
|
|
134
198
|
}
|
|
135
199
|
}, options));
|
|
136
200
|
}
|
|
137
|
-
function
|
|
201
|
+
function useModelMutation(model, method, url, modelMeta, options, fetch2, invalidateQueries = true, checkReadBack) {
|
|
138
202
|
const queryClient = useQueryClient();
|
|
139
|
-
const mutationFn = (data) =>
|
|
140
|
-
url,
|
|
141
|
-
{
|
|
142
|
-
method
|
|
203
|
+
const mutationFn = (data) => {
|
|
204
|
+
const reqUrl = method === "DELETE" ? makeUrl(url, data) : url;
|
|
205
|
+
const fetchInit = __spreadValues({
|
|
206
|
+
method
|
|
207
|
+
}, method !== "DELETE" && {
|
|
143
208
|
headers: {
|
|
144
209
|
"content-type": "application/json"
|
|
145
210
|
},
|
|
146
211
|
body: marshal(data)
|
|
147
|
-
}
|
|
148
|
-
fetch2,
|
|
149
|
-
|
|
150
|
-
);
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
body: marshal(data)
|
|
165
|
-
},
|
|
166
|
-
fetch2,
|
|
167
|
-
checkReadBack
|
|
168
|
-
);
|
|
169
|
-
const finalOptions = mergeOptions(model, options, invalidateQueries, mutationFn, queryClient);
|
|
170
|
-
const mutation = useMutation(finalOptions);
|
|
171
|
-
return mutation;
|
|
172
|
-
}
|
|
173
|
-
function deleteMutation(model, url, options, fetch2, invalidateQueries = true, checkReadBack) {
|
|
174
|
-
const queryClient = useQueryClient();
|
|
175
|
-
const mutationFn = (data) => fetcher(
|
|
176
|
-
makeUrl(url, data),
|
|
177
|
-
{
|
|
178
|
-
method: "DELETE"
|
|
179
|
-
},
|
|
180
|
-
fetch2,
|
|
181
|
-
checkReadBack
|
|
182
|
-
);
|
|
183
|
-
const finalOptions = mergeOptions(model, options, invalidateQueries, mutationFn, queryClient);
|
|
184
|
-
const mutation = useMutation(finalOptions);
|
|
185
|
-
return mutation;
|
|
186
|
-
}
|
|
187
|
-
function mergeOptions(model, options, invalidateQueries, mutationFn, queryClient) {
|
|
188
|
-
const result = __spreadProps(__spreadValues({}, options), { mutationFn });
|
|
189
|
-
if ((options == null ? void 0 : options.onSuccess) || invalidateQueries) {
|
|
190
|
-
result.onSuccess = (...args) => {
|
|
191
|
-
var _a;
|
|
192
|
-
if (invalidateQueries) {
|
|
193
|
-
queryClient.invalidateQueries([QUERY_KEY_PREFIX + model]);
|
|
194
|
-
}
|
|
195
|
-
return (_a = options == null ? void 0 : options.onSuccess) == null ? void 0 : _a.call(options, ...args);
|
|
196
|
-
};
|
|
212
|
+
});
|
|
213
|
+
return fetcher(reqUrl, fetchInit, fetch2, checkReadBack);
|
|
214
|
+
};
|
|
215
|
+
const finalOptions = __spreadProps(__spreadValues({}, options), { mutationFn });
|
|
216
|
+
if (invalidateQueries) {
|
|
217
|
+
const { logging } = getHooksContext();
|
|
218
|
+
const operation = url.split("/").pop();
|
|
219
|
+
if (operation) {
|
|
220
|
+
setupInvalidation(
|
|
221
|
+
model,
|
|
222
|
+
operation,
|
|
223
|
+
modelMeta,
|
|
224
|
+
finalOptions,
|
|
225
|
+
(predicate) => queryClient.invalidateQueries({ predicate }),
|
|
226
|
+
logging
|
|
227
|
+
);
|
|
228
|
+
}
|
|
197
229
|
}
|
|
198
|
-
return
|
|
230
|
+
return useMutation(finalOptions);
|
|
199
231
|
}
|
|
200
232
|
export {
|
|
201
233
|
VueQueryContextKey,
|
|
202
|
-
|
|
203
|
-
getContext,
|
|
204
|
-
infiniteQuery,
|
|
205
|
-
postMutation,
|
|
234
|
+
getHooksContext,
|
|
206
235
|
provideHooksContext,
|
|
207
|
-
|
|
208
|
-
|
|
236
|
+
useInfiniteModelQuery,
|
|
237
|
+
useModelMutation,
|
|
238
|
+
useModelQuery
|
|
209
239
|
};
|
|
210
240
|
//# sourceMappingURL=vue.mjs.map
|
package/runtime/vue.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/runtime/vue.ts","../../src/runtime/common.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/ban-types */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n useInfiniteQuery,\n useMutation,\n useQuery,\n useQueryClient,\n type MutateFunction,\n type QueryClient,\n type UseInfiniteQueryOptions,\n type UseMutationOptions,\n type UseQueryOptions,\n} from '@tanstack/vue-query';\nimport { inject, provide } from 'vue';\nimport { APIContext, DEFAULT_QUERY_ENDPOINT, FetchFn, QUERY_KEY_PREFIX, fetcher, makeUrl, marshal } from './common';\n\nexport { APIContext as RequestHandlerContext } from './common';\n\nexport const VueQueryContextKey = 'zenstack-vue-query-context';\n\n/**\n * Provide context for the generated TanStack Query hooks.\n */\nexport function provideHooksContext(context: APIContext) {\n provide<APIContext>(VueQueryContextKey, context);\n}\n\nexport function getContext() {\n return inject<APIContext>(VueQueryContextKey, {\n endpoint: DEFAULT_QUERY_ENDPOINT,\n fetch: undefined,\n });\n}\n\n/**\n * Creates a vue-query query.\n *\n * @param model The name of the model under query.\n * @param url The request URL.\n * @param args The request args object, URL-encoded and appended as \"?q=\" parameter\n * @param options The vue-query options object\n * @returns useQuery hook\n */\nexport function query<R>(model: string, url: string, args?: unknown, options?: UseQueryOptions<R>, fetch?: FetchFn) {\n const reqUrl = makeUrl(url, args);\n return useQuery<R>({\n queryKey: [QUERY_KEY_PREFIX + model, url, args],\n queryFn: () => fetcher<R, false>(reqUrl, undefined, fetch, false),\n ...options,\n });\n}\n\n/**\n * Creates a vue-query infinite query.\n *\n * @param model The name of the model under query.\n * @param url The request URL.\n * @param args The initial request args object, URL-encoded and appended as \"?q=\" parameter\n * @param options The vue-query infinite query options object\n * @returns useInfiniteQuery hook\n */\nexport function infiniteQuery<R>(\n model: string,\n url: string,\n args?: unknown,\n options?: UseInfiniteQueryOptions<R>,\n fetch?: FetchFn\n) {\n return useInfiniteQuery<R>({\n queryKey: [QUERY_KEY_PREFIX + model, url, args],\n queryFn: ({ pageParam }) => {\n return fetcher<R, false>(makeUrl(url, pageParam ?? args), undefined, fetch, false);\n },\n ...options,\n });\n}\n\n/**\n * Creates a POST mutation with vue-query.\n *\n * @param model The name of the model under mutation.\n * @param url The request URL.\n * @param options The vue-query options.\n * @param invalidateQueries Whether to invalidate queries after mutation.\n * @returns useMutation hooks\n */\nexport function postMutation<T, R = any, C extends boolean = boolean, Result = C extends true ? R | undefined : R>(\n model: string,\n url: string,\n options?: Omit<UseMutationOptions<Result, unknown, T, unknown>, 'mutationFn'>,\n fetch?: FetchFn,\n invalidateQueries = true,\n checkReadBack?: C\n) {\n const queryClient = useQueryClient();\n const mutationFn = (data: any) =>\n fetcher<R, C>(\n url,\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n },\n body: marshal(data),\n },\n fetch,\n checkReadBack\n ) as Promise<Result>;\n\n // TODO: figure out the typing problem\n const finalOptions: any = mergeOptions<T, Result>(model, options, invalidateQueries, mutationFn, queryClient);\n const mutation = useMutation<Result, unknown, T>(finalOptions);\n return mutation;\n}\n\n/**\n * Creates a PUT mutation with vue-query.\n *\n * @param model The name of the model under mutation.\n * @param url The request URL.\n * @param options The vue-query options.\n * @param invalidateQueries Whether to invalidate queries after mutation.\n * @returns useMutation hooks\n */\nexport function putMutation<T, R = any, C extends boolean = boolean, Result = C extends true ? R | undefined : R>(\n model: string,\n url: string,\n options?: Omit<UseMutationOptions<Result, unknown, T, unknown>, 'mutationFn'>,\n fetch?: FetchFn,\n invalidateQueries = true,\n checkReadBack?: C\n) {\n const queryClient = useQueryClient();\n const mutationFn = (data: any) =>\n fetcher<R, C>(\n url,\n {\n method: 'PUT',\n headers: {\n 'content-type': 'application/json',\n },\n body: marshal(data),\n },\n fetch,\n checkReadBack\n ) as Promise<Result>;\n\n // TODO: figure out the typing problem\n const finalOptions: any = mergeOptions<T, Result>(model, options, invalidateQueries, mutationFn, queryClient);\n const mutation = useMutation<Result, unknown, T>(finalOptions);\n return mutation;\n}\n\n/**\n * Creates a DELETE mutation with vue-query.\n *\n * @param model The name of the model under mutation.\n * @param url The request URL.\n * @param options The vue-query options.\n * @param invalidateQueries Whether to invalidate queries after mutation.\n * @returns useMutation hooks\n */\nexport function deleteMutation<T, R = any, C extends boolean = boolean, Result = C extends true ? R | undefined : R>(\n model: string,\n url: string,\n options?: Omit<UseMutationOptions<Result, unknown, T, unknown>, 'mutationFn'>,\n fetch?: FetchFn,\n invalidateQueries = true,\n checkReadBack?: C\n) {\n const queryClient = useQueryClient();\n const mutationFn = (data: any) =>\n fetcher<R, C>(\n makeUrl(url, data),\n {\n method: 'DELETE',\n },\n fetch,\n checkReadBack\n ) as Promise<Result>;\n\n // TODO: figure out the typing problem\n const finalOptions: any = mergeOptions<T, Result>(model, options, invalidateQueries, mutationFn, queryClient);\n const mutation = useMutation<Result, unknown, T>(finalOptions);\n return mutation;\n}\n\nfunction mergeOptions<T, R = any>(\n model: string,\n options: Omit<UseMutationOptions<R, unknown, T, unknown>, 'mutationFn'> | undefined,\n invalidateQueries: boolean,\n mutationFn: MutateFunction<R, unknown, T>,\n queryClient: QueryClient\n): UseMutationOptions<R, unknown, T, unknown> {\n const result = { ...options, mutationFn };\n if (options?.onSuccess || invalidateQueries) {\n result.onSuccess = (...args) => {\n if (invalidateQueries) {\n queryClient.invalidateQueries([QUERY_KEY_PREFIX + model]);\n }\n return options?.onSuccess?.(...args);\n };\n }\n return result;\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { deserialize, serialize } from '@zenstackhq/runtime/browser';\nimport * as crossFetch from 'cross-fetch';\n\n/**\n * The default query endpoint.\n */\nexport const DEFAULT_QUERY_ENDPOINT = '/api/model';\n\n/**\n * Prefix for react-query keys.\n */\nexport const QUERY_KEY_PREFIX = 'zenstack:';\n\n/**\n * Function signature for `fetch`.\n */\nexport type FetchFn = (url: string, options?: RequestInit) => Promise<Response>;\n\n/**\n * Context type for configuring the hooks.\n */\nexport type APIContext = {\n /**\n * The endpoint to use for the queries.\n */\n endpoint?: string;\n\n /**\n * A custom fetch function for sending the HTTP requests.\n */\n fetch?: FetchFn;\n};\n\nexport async function fetcher<R, C extends boolean>(\n url: string,\n options?: RequestInit,\n fetch?: FetchFn,\n checkReadBack?: C\n): Promise<C extends true ? R | undefined : R> {\n const _fetch = fetch ?? crossFetch.fetch;\n const res = await _fetch(url, options);\n if (!res.ok) {\n const errData = unmarshal(await res.text());\n if (\n checkReadBack !== false &&\n errData.error?.prisma &&\n errData.error?.code === 'P2004' &&\n errData.error?.reason === 'RESULT_NOT_READABLE'\n ) {\n // policy doesn't allow mutation result to be read back, just return undefined\n return undefined as any;\n }\n const error: Error & { info?: unknown; status?: number } = new Error(\n 'An error occurred while fetching the data.'\n );\n error.info = errData.error;\n error.status = res.status;\n throw error;\n }\n\n const textResult = await res.text();\n try {\n return unmarshal(textResult).data as R;\n } catch (err) {\n console.error(`Unable to deserialize data:`, textResult);\n throw err;\n }\n}\n\nexport function marshal(value: unknown) {\n const { data, meta } = serialize(value);\n if (meta) {\n return JSON.stringify({ ...(data as any), meta: { serialization: meta } });\n } else {\n return JSON.stringify(data);\n }\n}\n\nexport function unmarshal(value: string) {\n const parsed = JSON.parse(value);\n if (parsed.data && parsed.meta?.serialization) {\n const deserializedData = deserialize(parsed.data, parsed.meta.serialization);\n return { ...parsed, data: deserializedData };\n } else {\n return parsed;\n }\n}\n\nexport function makeUrl(url: string, args: unknown) {\n if (!args) {\n return url;\n }\n\n const { data, meta } = serialize(args);\n let result = `${url}?q=${encodeURIComponent(JSON.stringify(data))}`;\n if (meta) {\n result += `&meta=${encodeURIComponent(JSON.stringify({ serialization: meta }))}`;\n }\n return result;\n}\n"],"mappings":"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","names":["fetch","fetch"]}
|
|
1
|
+
{"version":3,"sources":["../../src/runtime/vue.ts","../../src/runtime/common.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/ban-types */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n useInfiniteQuery,\n useMutation,\n useQuery,\n useQueryClient,\n type UseInfiniteQueryOptions,\n type UseMutationOptions,\n type UseQueryOptions,\n} from '@tanstack/vue-query';\nimport type { ModelMeta } from '@zenstackhq/runtime/cross';\nimport { inject, provide } from 'vue';\nimport {\n APIContext,\n DEFAULT_QUERY_ENDPOINT,\n FetchFn,\n fetcher,\n getQueryKey,\n makeUrl,\n marshal,\n setupInvalidation,\n} from './common';\n\nexport { APIContext as RequestHandlerContext } from './common';\n\nexport const VueQueryContextKey = 'zenstack-vue-query-context';\n\n/**\n * Provide context for the generated TanStack Query hooks.\n */\nexport function provideHooksContext(context: APIContext) {\n provide<APIContext>(VueQueryContextKey, context);\n}\n\n/**\n * Hooks context.\n */\nexport function getHooksContext() {\n const { endpoint, ...rest } = inject<APIContext>(VueQueryContextKey, {\n endpoint: DEFAULT_QUERY_ENDPOINT,\n fetch: undefined,\n logging: false,\n });\n return { endpoint: endpoint ?? DEFAULT_QUERY_ENDPOINT, ...rest };\n}\n\n/**\n * Creates a vue-query query.\n *\n * @param model The name of the model under query.\n * @param url The request URL.\n * @param args The request args object, URL-encoded and appended as \"?q=\" parameter\n * @param options The vue-query options object\n * @returns useQuery hook\n */\nexport function useModelQuery<R>(\n model: string,\n url: string,\n args?: unknown,\n options?: UseQueryOptions<R>,\n fetch?: FetchFn\n) {\n const reqUrl = makeUrl(url, args);\n return useQuery<R>({\n queryKey: getQueryKey(model, url, args),\n queryFn: () => fetcher<R, false>(reqUrl, undefined, fetch, false),\n ...options,\n });\n}\n\n/**\n * Creates a vue-query infinite query.\n *\n * @param model The name of the model under query.\n * @param url The request URL.\n * @param args The initial request args object, URL-encoded and appended as \"?q=\" parameter\n * @param options The vue-query infinite query options object\n * @returns useInfiniteQuery hook\n */\nexport function useInfiniteModelQuery<R>(\n model: string,\n url: string,\n args?: unknown,\n options?: UseInfiniteQueryOptions<R>,\n fetch?: FetchFn\n) {\n return useInfiniteQuery<R>({\n queryKey: getQueryKey(model, url, args),\n queryFn: ({ pageParam }) => {\n return fetcher<R, false>(makeUrl(url, pageParam ?? args), undefined, fetch, false);\n },\n ...options,\n });\n}\n\n/**\n * Creates a mutation with vue-query.\n *\n * @param model The name of the model under mutation.\n * @param method The HTTP method.\n * @param modelMeta The model metadata.\n * @param url The request URL.\n * @param options The vue-query options.\n * @param invalidateQueries Whether to invalidate queries after mutation.\n * @returns useMutation hooks\n */\nexport function useModelMutation<T, R = any, C extends boolean = boolean, Result = C extends true ? R | undefined : R>(\n model: string,\n method: 'POST' | 'PUT' | 'DELETE',\n url: string,\n modelMeta: ModelMeta,\n options?: Omit<UseMutationOptions<Result, unknown, T, unknown>, 'mutationFn'>,\n fetch?: FetchFn,\n invalidateQueries = true,\n checkReadBack?: C\n) {\n const queryClient = useQueryClient();\n const mutationFn = (data: any) => {\n const reqUrl = method === 'DELETE' ? makeUrl(url, data) : url;\n const fetchInit: RequestInit = {\n method,\n ...(method !== 'DELETE' && {\n headers: {\n 'content-type': 'application/json',\n },\n body: marshal(data),\n }),\n };\n return fetcher<R, C>(reqUrl, fetchInit, fetch, checkReadBack) as Promise<Result>;\n };\n\n // TODO: figure out the typing problem\n const finalOptions: any = { ...options, mutationFn };\n if (invalidateQueries) {\n const { logging } = getHooksContext();\n const operation = url.split('/').pop();\n if (operation) {\n setupInvalidation(\n model,\n operation,\n modelMeta,\n finalOptions,\n (predicate) => queryClient.invalidateQueries({ predicate }),\n logging\n );\n }\n }\n return useMutation<Result, unknown, T>(finalOptions);\n}\n","/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { deserialize, serialize } from '@zenstackhq/runtime/browser';\nimport { getMutatedModels, getReadModels, type ModelMeta, type PrismaWriteActionType } from '@zenstackhq/runtime/cross';\nimport * as crossFetch from 'cross-fetch';\n\n/**\n * The default query endpoint.\n */\nexport const DEFAULT_QUERY_ENDPOINT = '/api/model';\n\n/**\n * Prefix for react-query keys.\n */\nexport const QUERY_KEY_PREFIX = 'zenstack';\n\n/**\n * Function signature for `fetch`.\n */\nexport type FetchFn = (url: string, options?: RequestInit) => Promise<Response>;\n\n/**\n * Context type for configuring the hooks.\n */\nexport type APIContext = {\n /**\n * The endpoint to use for the queries.\n */\n endpoint?: string;\n\n /**\n * A custom fetch function for sending the HTTP requests.\n */\n fetch?: FetchFn;\n\n /**\n * If logging is enabled.\n */\n logging?: boolean;\n};\n\nexport async function fetcher<R, C extends boolean>(\n url: string,\n options?: RequestInit,\n fetch?: FetchFn,\n checkReadBack?: C\n): Promise<C extends true ? R | undefined : R> {\n const _fetch = fetch ?? crossFetch.fetch;\n const res = await _fetch(url, options);\n if (!res.ok) {\n const errData = unmarshal(await res.text());\n if (\n checkReadBack !== false &&\n errData.error?.prisma &&\n errData.error?.code === 'P2004' &&\n errData.error?.reason === 'RESULT_NOT_READABLE'\n ) {\n // policy doesn't allow mutation result to be read back, just return undefined\n return undefined as any;\n }\n const error: Error & { info?: unknown; status?: number } = new Error(\n 'An error occurred while fetching the data.'\n );\n error.info = errData.error;\n error.status = res.status;\n throw error;\n }\n\n const textResult = await res.text();\n try {\n return unmarshal(textResult).data as R;\n } catch (err) {\n console.error(`Unable to deserialize data:`, textResult);\n throw err;\n }\n}\n\ntype QueryKey = [string /* prefix */, string /* model */, string /* operation */, unknown /* args */];\n\n/**\n * Computes query key for the given model, operation and query args.\n * @param model Model name.\n * @param urlOrOperation Prisma operation (e.g, `findMany`) or request URL. If it's a URL, the last path segment will be used as the operation name.\n * @param args Prisma query arguments.\n * @returns Query key\n */\nexport function getQueryKey(model: string, urlOrOperation: string, args: unknown): QueryKey {\n if (!urlOrOperation) {\n throw new Error('Invalid urlOrOperation');\n }\n const operation = urlOrOperation.split('/').pop();\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return [QUERY_KEY_PREFIX, model, operation!, args];\n}\n\nexport function marshal(value: unknown) {\n const { data, meta } = serialize(value);\n if (meta) {\n return JSON.stringify({ ...(data as any), meta: { serialization: meta } });\n } else {\n return JSON.stringify(data);\n }\n}\n\nexport function unmarshal(value: string) {\n const parsed = JSON.parse(value);\n if (parsed.data && parsed.meta?.serialization) {\n const deserializedData = deserialize(parsed.data, parsed.meta.serialization);\n return { ...parsed, data: deserializedData };\n } else {\n return parsed;\n }\n}\n\nexport function makeUrl(url: string, args: unknown) {\n if (!args) {\n return url;\n }\n\n const { data, meta } = serialize(args);\n let result = `${url}?q=${encodeURIComponent(JSON.stringify(data))}`;\n if (meta) {\n result += `&meta=${encodeURIComponent(JSON.stringify({ serialization: meta }))}`;\n }\n return result;\n}\n\ntype InvalidationPredicate = ({ queryKey }: { queryKey: readonly unknown[] }) => boolean;\n\n// sets up invalidation hook for a mutation\nexport function setupInvalidation(\n model: string,\n operation: string,\n modelMeta: ModelMeta,\n options: { onSuccess?: (...args: any[]) => any },\n invalidate: (predicate: InvalidationPredicate) => Promise<void>,\n logging = false\n) {\n const origOnSuccess = options?.onSuccess;\n options.onSuccess = async (...args: unknown[]) => {\n const [_, variables] = args;\n const predicate = await getInvalidationPredicate(\n model,\n operation as PrismaWriteActionType,\n variables,\n modelMeta,\n logging\n );\n await invalidate(predicate);\n return origOnSuccess?.(...args);\n };\n}\n\n// gets a predicate for evaluating whether a query should be invalidated\nasync function getInvalidationPredicate(\n model: string,\n operation: PrismaWriteActionType,\n mutationArgs: any,\n modelMeta: ModelMeta,\n logging = false\n) {\n const mutatedModels = await getMutatedModels(model, operation, mutationArgs, modelMeta);\n\n return ({ queryKey }: { queryKey: readonly unknown[] }) => {\n const [_model, queryModel, queryOp, args] = queryKey as QueryKey;\n\n if (mutatedModels.includes(queryModel)) {\n // direct match\n if (logging) {\n console.log(`Invalidating query [${queryKey}] due to mutation \"${model}.${operation}\"`);\n }\n return true;\n }\n\n if (args) {\n // traverse query args to find nested reads that match the model under mutation\n if (findNestedRead(queryModel, mutatedModels, modelMeta, args)) {\n if (logging) {\n console.log(`Invalidating query [${queryKey}] due to mutation \"${model}.${operation}\"`);\n }\n return true;\n }\n }\n\n return false;\n };\n}\n\n// find nested reads that match the given models\nfunction findNestedRead(visitingModel: string, targetModels: string[], modelMeta: ModelMeta, args: any) {\n const modelsRead = getReadModels(visitingModel, modelMeta, args);\n return targetModels.some((m) => modelsRead.includes(m));\n}\n"],"mappings":"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","names":["fetch","fetch"]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Function signature for `fetch`.
|
|
3
|
+
*/
|
|
4
|
+
type FetchFn = (url: string, options?: RequestInit) => Promise<Response>;
|
|
5
|
+
/**
|
|
6
|
+
* Context type for configuring the hooks.
|
|
7
|
+
*/
|
|
8
|
+
type APIContext = {
|
|
9
|
+
/**
|
|
10
|
+
* The endpoint to use for the queries.
|
|
11
|
+
*/
|
|
12
|
+
endpoint?: string;
|
|
13
|
+
/**
|
|
14
|
+
* A custom fetch function for sending the HTTP requests.
|
|
15
|
+
*/
|
|
16
|
+
fetch?: FetchFn;
|
|
17
|
+
/**
|
|
18
|
+
* If logging is enabled.
|
|
19
|
+
*/
|
|
20
|
+
logging?: boolean;
|
|
21
|
+
};
|
|
22
|
+
type QueryKey = [string, string, string, unknown];
|
|
23
|
+
/**
|
|
24
|
+
* Computes query key for the given model, operation and query args.
|
|
25
|
+
* @param model Model name.
|
|
26
|
+
* @param urlOrOperation Prisma operation (e.g, `findMany`) or request URL. If it's a URL, the last path segment will be used as the operation name.
|
|
27
|
+
* @param args Prisma query arguments.
|
|
28
|
+
* @returns Query key
|
|
29
|
+
*/
|
|
30
|
+
declare function getQueryKey(model: string, urlOrOperation: string, args: unknown): QueryKey;
|
|
31
|
+
|
|
32
|
+
export { APIContext as A, FetchFn as F, getQueryKey as g };
|