mirror of
https://github.com/zenstackhq/zenstack
synced 2026-05-24 10:08:55 +00:00
feat: tanstack-query v5 support (#788)
This commit is contained in:
parent
8a370dbfea
commit
0d04d8e6da
13 changed files with 759 additions and 89 deletions
|
|
@ -34,6 +34,30 @@
|
|||
"require": "./runtime/svelte.js",
|
||||
"default": "./runtime/svelte.js",
|
||||
"types": "./runtime/svelte.d.ts"
|
||||
},
|
||||
"./runtime-v5": {
|
||||
"import": "./runtime-v5/index.mjs",
|
||||
"require": "./runtime-v5/index.js",
|
||||
"default": "./runtime-v5/index.js",
|
||||
"types": "./runtime-v5/index.d.ts"
|
||||
},
|
||||
"./runtime-v5/react": {
|
||||
"import": "./runtime-v5/react.mjs",
|
||||
"require": "./runtime-v5/react.js",
|
||||
"default": "./runtime-v5/react.js",
|
||||
"types": "./runtime-v5/react.d.ts"
|
||||
},
|
||||
"./runtime-v5/vue": {
|
||||
"import": "./runtime-v5/vue.mjs",
|
||||
"require": "./runtime-v5/vue.js",
|
||||
"default": "./runtime-v5/vue.js",
|
||||
"types": "./runtime-v5/vue.d.ts"
|
||||
},
|
||||
"./runtime-v5/svelte": {
|
||||
"import": "./runtime-v5/svelte.mjs",
|
||||
"require": "./runtime-v5/svelte.js",
|
||||
"default": "./runtime-v5/svelte.js",
|
||||
"types": "./runtime-v5/svelte.d.ts"
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
|
|
@ -42,8 +66,8 @@
|
|||
},
|
||||
"scripts": {
|
||||
"clean": "rimraf dist",
|
||||
"build": "pnpm lint && pnpm clean && tsc && tsup-node && copyfiles ./package.json ./README.md ./LICENSE dist && pnpm pack dist --pack-destination '../../../../.build'",
|
||||
"watch": "concurrently \"tsc --watch\" \"tsup-node --watch\"",
|
||||
"build": "pnpm lint && pnpm clean && tsc && tsup-node --config ./tsup.config.ts && tsup-node --config ./tsup-v5.config.ts && node scripts/postbuild && copyfiles ./package.json ./README.md ./LICENSE dist && pnpm pack dist --pack-destination '../../../../.build'",
|
||||
"watch": "concurrently \"tsc --watch\" \"tsup-node --config ./tsup.config.ts --watch\" \"tsup-node --config ./tsup-v5.config.ts --watch\"",
|
||||
"lint": "eslint src --ext ts",
|
||||
"test": "ZENSTACK_TEST=1 jest",
|
||||
"prepublishOnly": "pnpm build",
|
||||
|
|
@ -71,7 +95,9 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@tanstack/react-query": "^4.29.7",
|
||||
"@tanstack/react-query-v5": "npm:@tanstack/react-query@^5.0.0",
|
||||
"@tanstack/svelte-query": "^4.29.7",
|
||||
"@tanstack/svelte-query-v5": "npm:@tanstack/svelte-query@^5.0.0",
|
||||
"@tanstack/vue-query": "^4.37.0",
|
||||
"@types/jest": "^29.5.0",
|
||||
"@types/node": "^18.0.0",
|
||||
|
|
@ -82,6 +108,7 @@
|
|||
"copyfiles": "^2.4.1",
|
||||
"jest": "^29.5.0",
|
||||
"react": "18.2.0",
|
||||
"replace-in-file": "^7.0.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"svelte": "^4.2.1",
|
||||
"swr": "^2.0.3",
|
||||
|
|
|
|||
24
packages/plugins/tanstack-query/scripts/postbuild.js
Executable file
24
packages/plugins/tanstack-query/scripts/postbuild.js
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
// tsup doesn't replace npm dependency aliases in the dist files, so we have to do it manually
|
||||
|
||||
const replace = require('replace-in-file');
|
||||
|
||||
console.log('Replacing @tanstack/react-query-v5');
|
||||
replace.sync({
|
||||
files: 'dist/runtime-v5/react*(.d.ts|.d.mts|.js|.mjs)',
|
||||
from: /@tanstack\/react-query-v5/g,
|
||||
to: '@tanstack/react-query',
|
||||
});
|
||||
|
||||
console.log('Replacing @tanstack/svelte-query-v5');
|
||||
replace.sync({
|
||||
files: 'dist/runtime-v5/svelte*(.d.ts|.d.mts|.js|.mjs)',
|
||||
from: /@tanstack\/svelte-query-v5/g,
|
||||
to: '@tanstack/svelte-query',
|
||||
});
|
||||
|
||||
console.log('Replacing @tanstack/vue-query-v5');
|
||||
replace.sync({
|
||||
files: 'dist/runtime-v5/vue*(.d.ts|.d.mts|.js|.mjs)',
|
||||
from: /@tanstack\/vue-query-v5/g,
|
||||
to: '@tanstack/vue-query',
|
||||
});
|
||||
|
|
@ -21,6 +21,7 @@ import { name } from '.';
|
|||
|
||||
const supportedTargets = ['react', 'vue', 'svelte'];
|
||||
type TargetFramework = (typeof supportedTargets)[number];
|
||||
type TanStackVersion = 'v4' | 'v5';
|
||||
|
||||
export async function generate(model: Model, options: PluginOptions, dmmf: DMMF.Document) {
|
||||
let outDir = requireOption<string>(options, 'output');
|
||||
|
|
@ -38,7 +39,12 @@ export async function generate(model: Model, options: PluginOptions, dmmf: DMMF.
|
|||
);
|
||||
}
|
||||
|
||||
generateIndex(project, outDir, models, target);
|
||||
const version = typeof options.version === 'string' ? options.version : 'v4';
|
||||
if (version !== 'v4' && version !== 'v5') {
|
||||
throw new PluginError(options.name, `Unsupported version "${version}": use "v4" or "v5"`);
|
||||
}
|
||||
|
||||
generateIndex(project, outDir, models, target, version);
|
||||
|
||||
models.forEach((dataModel) => {
|
||||
const mapping = dmmf.mappings.modelOperations.find((op) => op.model === dataModel.name);
|
||||
|
|
@ -46,7 +52,7 @@ export async function generate(model: Model, options: PluginOptions, dmmf: DMMF.
|
|||
warnings.push(`Unable to find mapping for model ${dataModel.name}`);
|
||||
return;
|
||||
}
|
||||
generateModelHooks(target, project, outDir, dataModel, mapping);
|
||||
generateModelHooks(target, version, project, outDir, dataModel, mapping);
|
||||
});
|
||||
|
||||
await saveProject(project);
|
||||
|
|
@ -55,6 +61,7 @@ export async function generate(model: Model, options: PluginOptions, dmmf: DMMF.
|
|||
|
||||
function generateQueryHook(
|
||||
target: TargetFramework,
|
||||
version: TanStackVersion,
|
||||
sf: SourceFile,
|
||||
model: string,
|
||||
operation: string,
|
||||
|
|
@ -71,7 +78,7 @@ function generateQueryHook(
|
|||
const inputType = `Prisma.SelectSubset<T, ${argsType}>`;
|
||||
const returnType =
|
||||
overrideReturnType ?? (returnArray ? `Array<Prisma.${model}GetPayload<T>>` : `Prisma.${model}GetPayload<T>`);
|
||||
const optionsType = makeQueryOptions(target, returnType, infinite);
|
||||
const optionsType = makeQueryOptions(target, returnType, infinite, version);
|
||||
|
||||
const func = sf.addFunction({
|
||||
name: `use${infinite ? 'Infinite' : ''}${capOperation}${model}`,
|
||||
|
|
@ -89,9 +96,14 @@ function generateQueryHook(
|
|||
isExported: true,
|
||||
});
|
||||
|
||||
if (version === 'v5' && infinite && ['react', 'svelte'].includes(target)) {
|
||||
// initialPageParam and getNextPageParam options are required in v5
|
||||
func.addStatements([`options = options ?? { initialPageParam: undefined, getNextPageParam: () => null };`]);
|
||||
}
|
||||
|
||||
func.addStatements([
|
||||
makeGetContext(target),
|
||||
`return ${infinite ? 'infiniteQuery' : 'query'}<${returnType}>('${model}', \`\${endpoint}/${lowerCaseFirst(
|
||||
`return ${infinite ? 'infiniteQuery' : 'query'}('${model}', \`\${endpoint}/${lowerCaseFirst(
|
||||
model
|
||||
)}/${operation}\`, args, options, fetch);`,
|
||||
]);
|
||||
|
|
@ -217,6 +229,7 @@ function generateMutationHook(
|
|||
|
||||
function generateModelHooks(
|
||||
target: TargetFramework,
|
||||
version: TanStackVersion,
|
||||
project: Project,
|
||||
outDir: string,
|
||||
model: DataModel,
|
||||
|
|
@ -235,7 +248,7 @@ function generateModelHooks(
|
|||
isTypeOnly: true,
|
||||
moduleSpecifier: prismaImport,
|
||||
});
|
||||
sf.addStatements(makeBaseImports(target));
|
||||
sf.addStatements(makeBaseImports(target, version));
|
||||
|
||||
// create is somehow named "createOne" in the DMMF
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
|
@ -251,19 +264,31 @@ function generateModelHooks(
|
|||
// findMany
|
||||
if (mapping.findMany) {
|
||||
// regular findMany
|
||||
generateQueryHook(target, sf, model.name, 'findMany', true, true);
|
||||
generateQueryHook(target, version, sf, model.name, 'findMany', true, true);
|
||||
// infinite findMany
|
||||
generateQueryHook(target, sf, model.name, 'findMany', true, true, undefined, undefined, undefined, true);
|
||||
generateQueryHook(
|
||||
target,
|
||||
version,
|
||||
sf,
|
||||
model.name,
|
||||
'findMany',
|
||||
true,
|
||||
true,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
// findUnique
|
||||
if (mapping.findUnique) {
|
||||
generateQueryHook(target, sf, model.name, 'findUnique', false, false);
|
||||
generateQueryHook(target, version, sf, model.name, 'findUnique', false, false);
|
||||
}
|
||||
|
||||
// findFirst
|
||||
if (mapping.findFirst) {
|
||||
generateQueryHook(target, sf, model.name, 'findFirst', false, true);
|
||||
generateQueryHook(target, version, sf, model.name, 'findFirst', false, true);
|
||||
}
|
||||
|
||||
// update
|
||||
|
|
@ -301,6 +326,7 @@ function generateModelHooks(
|
|||
if (mapping.aggregate) {
|
||||
generateQueryHook(
|
||||
target,
|
||||
version,
|
||||
sf,
|
||||
modelNameCap,
|
||||
'aggregate',
|
||||
|
|
@ -385,6 +411,7 @@ function generateModelHooks(
|
|||
|
||||
generateQueryHook(
|
||||
target,
|
||||
version,
|
||||
sf,
|
||||
model.name,
|
||||
'groupBy',
|
||||
|
|
@ -400,6 +427,7 @@ function generateModelHooks(
|
|||
{
|
||||
generateQueryHook(
|
||||
target,
|
||||
version,
|
||||
sf,
|
||||
model.name,
|
||||
'count',
|
||||
|
|
@ -410,22 +438,25 @@ function generateModelHooks(
|
|||
}
|
||||
}
|
||||
|
||||
function generateIndex(project: Project, outDir: string, models: DataModel[], target: string) {
|
||||
function generateIndex(
|
||||
project: Project,
|
||||
outDir: string,
|
||||
models: DataModel[],
|
||||
target: string,
|
||||
version: TanStackVersion
|
||||
) {
|
||||
const sf = project.createSourceFile(path.join(outDir, 'index.ts'), undefined, { overwrite: true });
|
||||
sf.addStatements(models.map((d) => `export * from './${paramCase(d.name)}';`));
|
||||
const runtimeImportBase = makeRuntimeImportBase(version);
|
||||
switch (target) {
|
||||
case 'react':
|
||||
sf.addStatements(`export { Provider } from '@zenstackhq/tanstack-query/runtime/react';`);
|
||||
sf.addStatements(`export { Provider } from '${runtimeImportBase}/react';`);
|
||||
break;
|
||||
case 'vue':
|
||||
sf.addStatements(
|
||||
`export { VueQueryContextKey, provideHooksContext } from '@zenstackhq/tanstack-query/runtime/vue';`
|
||||
);
|
||||
sf.addStatements(`export { VueQueryContextKey, provideHooksContext } from '${runtimeImportBase}/vue';`);
|
||||
break;
|
||||
case 'svelte':
|
||||
sf.addStatements(
|
||||
`export { SvelteQueryContextKey, setHooksContext } from '@zenstackhq/tanstack-query/runtime/svelte';`
|
||||
);
|
||||
sf.addStatements(`export { SvelteQueryContextKey, setHooksContext } from '${runtimeImportBase}/svelte';`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -443,23 +474,24 @@ function makeGetContext(target: TargetFramework) {
|
|||
}
|
||||
}
|
||||
|
||||
function makeBaseImports(target: TargetFramework) {
|
||||
function makeBaseImports(target: TargetFramework, version: TanStackVersion) {
|
||||
const runtimeImportBase = makeRuntimeImportBase(version);
|
||||
const shared = [
|
||||
`import { query, infiniteQuery, postMutation, putMutation, deleteMutation } from '@zenstackhq/tanstack-query/runtime/${target}';`,
|
||||
`import type { PickEnumerable, CheckSelect } from '@zenstackhq/tanstack-query/runtime';`,
|
||||
`import { query, infiniteQuery, postMutation, putMutation, deleteMutation } from '${runtimeImportBase}/${target}';`,
|
||||
`import type { PickEnumerable, CheckSelect } from '${runtimeImportBase}';`,
|
||||
];
|
||||
switch (target) {
|
||||
case 'react':
|
||||
return [
|
||||
`import { useContext } from 'react';`,
|
||||
`import type { UseMutationOptions, UseQueryOptions, UseInfiniteQueryOptions } from '@tanstack/react-query';`,
|
||||
`import { RequestHandlerContext } from '@zenstackhq/tanstack-query/runtime/${target}';`,
|
||||
`import type { UseMutationOptions, UseQueryOptions, UseInfiniteQueryOptions, InfiniteData } from '@tanstack/react-query';`,
|
||||
`import { RequestHandlerContext } from '${runtimeImportBase}/${target}';`,
|
||||
...shared,
|
||||
];
|
||||
case 'vue':
|
||||
return [
|
||||
`import type { UseMutationOptions, UseQueryOptions, UseInfiniteQueryOptions } from '@tanstack/vue-query';`,
|
||||
`import { getContext } from '@zenstackhq/tanstack-query/runtime/${target}';`,
|
||||
`import type { UseMutationOptions, UseQueryOptions, UseInfiniteQueryOptions, InfiniteData } from '@tanstack/vue-query';`,
|
||||
`import { getContext } from '${runtimeImportBase}/${target}';`,
|
||||
...shared,
|
||||
];
|
||||
case 'svelte':
|
||||
|
|
@ -467,7 +499,10 @@ function makeBaseImports(target: TargetFramework) {
|
|||
`import { getContext } from 'svelte';`,
|
||||
`import { derived } from 'svelte/store';`,
|
||||
`import type { MutationOptions, QueryOptions, CreateInfiniteQueryOptions } from '@tanstack/svelte-query';`,
|
||||
`import { SvelteQueryContextKey, type RequestHandlerContext } from '@zenstackhq/tanstack-query/runtime/${target}';`,
|
||||
...(version === 'v5'
|
||||
? [`import type { InfiniteData, StoreOrVal } from '@tanstack/svelte-query';`]
|
||||
: []),
|
||||
`import { SvelteQueryContextKey, type RequestHandlerContext } from '${runtimeImportBase}/${target}';`,
|
||||
...shared,
|
||||
];
|
||||
default:
|
||||
|
|
@ -475,13 +510,24 @@ function makeBaseImports(target: TargetFramework) {
|
|||
}
|
||||
}
|
||||
|
||||
function makeQueryOptions(target: string, returnType: string, infinite: boolean) {
|
||||
function makeQueryOptions(target: string, returnType: string, infinite: boolean, version: TanStackVersion) {
|
||||
switch (target) {
|
||||
case 'react':
|
||||
return infinite
|
||||
? version === 'v4'
|
||||
? `Omit<UseInfiniteQueryOptions<${returnType}>, 'queryKey'>`
|
||||
: `Omit<UseInfiniteQueryOptions<${returnType}, unknown, InfiniteData<${returnType}>>, 'queryKey'>`
|
||||
: `Omit<UseQueryOptions<${returnType}>, 'queryKey'>`;
|
||||
case 'vue':
|
||||
return `Use${infinite ? 'Infinite' : ''}QueryOptions<${returnType}>`;
|
||||
return `Omit<Use${infinite ? 'Infinite' : ''}QueryOptions<${returnType}>, 'queryKey'>`;
|
||||
case 'svelte':
|
||||
return `${infinite ? 'CreateInfinite' : ''}QueryOptions<${returnType}>`;
|
||||
return infinite
|
||||
? version === 'v4'
|
||||
? `Omit<CreateInfiniteQueryOptions<${returnType}>, 'queryKey'>`
|
||||
: `StoreOrVal<Omit<CreateInfiniteQueryOptions<${returnType}, unknown, InfiniteData<${returnType}>>, 'queryKey'>>`
|
||||
: version === 'v4'
|
||||
? `Omit<QueryOptions<${returnType}>, 'queryKey'>`
|
||||
: `StoreOrVal<Omit<QueryOptions<${returnType}>, 'queryKey'>>`;
|
||||
default:
|
||||
throw new PluginError(name, `Unsupported target: ${target}`);
|
||||
}
|
||||
|
|
@ -499,3 +545,7 @@ function makeMutationOptions(target: string, returnType: string, argsType: strin
|
|||
throw new PluginError(name, `Unsupported target: ${target}`);
|
||||
}
|
||||
}
|
||||
|
||||
function makeRuntimeImportBase(version: TanStackVersion) {
|
||||
return `@zenstackhq/tanstack-query/runtime${version === 'v5' ? '-v5' : ''}`;
|
||||
}
|
||||
|
|
|
|||
2
packages/plugins/tanstack-query/src/runtime-v5/index.ts
Normal file
2
packages/plugins/tanstack-query/src/runtime-v5/index.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
export * from '../runtime/prisma-types';
|
||||
export type { FetchFn } from '../runtime/common';
|
||||
211
packages/plugins/tanstack-query/src/runtime-v5/react.ts
Normal file
211
packages/plugins/tanstack-query/src/runtime-v5/react.ts
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import {
|
||||
useInfiniteQuery,
|
||||
useMutation,
|
||||
useQuery,
|
||||
useQueryClient,
|
||||
type InfiniteData,
|
||||
type MutateFunction,
|
||||
type QueryClient,
|
||||
type UseInfiniteQueryOptions,
|
||||
type UseMutationOptions,
|
||||
type UseQueryOptions,
|
||||
} from '@tanstack/react-query-v5';
|
||||
import { createContext } from 'react';
|
||||
import {
|
||||
DEFAULT_QUERY_ENDPOINT,
|
||||
FetchFn,
|
||||
QUERY_KEY_PREFIX,
|
||||
fetcher,
|
||||
makeUrl,
|
||||
marshal,
|
||||
type APIContext,
|
||||
} from '../runtime/common';
|
||||
|
||||
/**
|
||||
* Context for configuring react hooks.
|
||||
*/
|
||||
export const RequestHandlerContext = createContext<APIContext>({
|
||||
endpoint: DEFAULT_QUERY_ENDPOINT,
|
||||
fetch: undefined,
|
||||
});
|
||||
|
||||
/**
|
||||
* Context provider.
|
||||
*/
|
||||
export const Provider = RequestHandlerContext.Provider;
|
||||
|
||||
/**
|
||||
* Creates a react-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 react-query options object
|
||||
* @returns useQuery hook
|
||||
*/
|
||||
export function query<R>(
|
||||
model: string,
|
||||
url: string,
|
||||
args?: unknown,
|
||||
options?: Omit<UseQueryOptions<R>, 'queryKey'>,
|
||||
fetch?: FetchFn
|
||||
) {
|
||||
const reqUrl = makeUrl(url, args);
|
||||
return useQuery({
|
||||
queryKey: [QUERY_KEY_PREFIX + model, url, args],
|
||||
queryFn: () => fetcher<R, false>(reqUrl, undefined, fetch, false),
|
||||
...options,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a react-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 react-query infinite query options object
|
||||
* @returns useInfiniteQuery hook
|
||||
*/
|
||||
export function infiniteQuery<R>(
|
||||
model: string,
|
||||
url: string,
|
||||
args: unknown,
|
||||
options: Omit<UseInfiniteQueryOptions<R, unknown, InfiniteData<R>>, 'queryKey'>,
|
||||
fetch?: FetchFn
|
||||
) {
|
||||
return useInfiniteQuery({
|
||||
queryKey: [QUERY_KEY_PREFIX + model, url, args],
|
||||
queryFn: ({ pageParam }) => {
|
||||
return fetcher<R, false>(makeUrl(url, pageParam ?? args), undefined, fetch, false);
|
||||
},
|
||||
...options,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a POST mutation with react-query.
|
||||
*
|
||||
* @param model The name of the model under mutation.
|
||||
* @param url The request URL.
|
||||
* @param options The react-query options.
|
||||
* @param invalidateQueries Whether to invalidate queries after mutation.
|
||||
* @returns useMutation hooks
|
||||
*/
|
||||
export function postMutation<T, R = any, C extends boolean = boolean, Result = C extends true ? R | undefined : R>(
|
||||
model: string,
|
||||
url: string,
|
||||
options?: Omit<UseMutationOptions<Result, unknown, T>, 'mutationFn'>,
|
||||
fetch?: FetchFn,
|
||||
invalidateQueries = true,
|
||||
checkReadBack?: C
|
||||
) {
|
||||
const queryClient = useQueryClient();
|
||||
const mutationFn = (data: any) =>
|
||||
fetcher<R, C>(
|
||||
url,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
body: marshal(data),
|
||||
},
|
||||
fetch,
|
||||
checkReadBack
|
||||
) as Promise<Result>;
|
||||
|
||||
const finalOptions = mergeOptions(model, options, invalidateQueries, mutationFn, queryClient);
|
||||
const mutation = useMutation(finalOptions);
|
||||
return mutation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a PUT mutation with react-query.
|
||||
*
|
||||
* @param model The name of the model under mutation.
|
||||
* @param url The request URL.
|
||||
* @param options The react-query options.
|
||||
* @param invalidateQueries Whether to invalidate queries after mutation.
|
||||
* @returns useMutation hooks
|
||||
*/
|
||||
export function putMutation<T, R = any, C extends boolean = boolean, Result = C extends true ? R | undefined : R>(
|
||||
model: string,
|
||||
url: string,
|
||||
options?: Omit<UseMutationOptions<Result, unknown, T>, 'mutationFn'>,
|
||||
fetch?: FetchFn,
|
||||
invalidateQueries = true,
|
||||
checkReadBack?: C
|
||||
) {
|
||||
const queryClient = useQueryClient();
|
||||
const mutationFn = (data: any) =>
|
||||
fetcher<R, C>(
|
||||
url,
|
||||
{
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
body: marshal(data),
|
||||
},
|
||||
fetch,
|
||||
checkReadBack
|
||||
) as Promise<Result>;
|
||||
|
||||
const finalOptions = mergeOptions(model, options, invalidateQueries, mutationFn, queryClient);
|
||||
const mutation = useMutation(finalOptions);
|
||||
return mutation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a DELETE mutation with react-query.
|
||||
*
|
||||
* @param model The name of the model under mutation.
|
||||
* @param url The request URL.
|
||||
* @param options The react-query options.
|
||||
* @param invalidateQueries Whether to invalidate queries after mutation.
|
||||
* @returns useMutation hooks
|
||||
*/
|
||||
export function deleteMutation<T, R = any, C extends boolean = boolean, Result = C extends true ? R | undefined : R>(
|
||||
model: string,
|
||||
url: string,
|
||||
options?: Omit<UseMutationOptions<Result, unknown, T>, 'mutationFn'>,
|
||||
fetch?: FetchFn,
|
||||
invalidateQueries = true,
|
||||
checkReadBack?: C
|
||||
) {
|
||||
const queryClient = useQueryClient();
|
||||
const mutationFn = (data: any) =>
|
||||
fetcher<R, C>(
|
||||
makeUrl(url, data),
|
||||
{
|
||||
method: 'DELETE',
|
||||
},
|
||||
fetch,
|
||||
checkReadBack
|
||||
) as Promise<Result>;
|
||||
|
||||
const finalOptions = mergeOptions(model, options, invalidateQueries, mutationFn, queryClient);
|
||||
const mutation = useMutation(finalOptions);
|
||||
return mutation;
|
||||
}
|
||||
|
||||
function mergeOptions<T, R = any>(
|
||||
model: string,
|
||||
options: Omit<UseMutationOptions<R, unknown, T, unknown>, 'mutationFn'> | undefined,
|
||||
invalidateQueries: boolean,
|
||||
mutationFn: MutateFunction<R, unknown, T>,
|
||||
queryClient: QueryClient
|
||||
): UseMutationOptions<R, unknown, T, unknown> {
|
||||
const result = { ...options, mutationFn };
|
||||
if (options?.onSuccess || invalidateQueries) {
|
||||
result.onSuccess = (...args) => {
|
||||
if (invalidateQueries) {
|
||||
queryClient.invalidateQueries({ queryKey: [QUERY_KEY_PREFIX + model] });
|
||||
}
|
||||
return options?.onSuccess?.(...args);
|
||||
};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
243
packages/plugins/tanstack-query/src/runtime-v5/svelte.ts
Normal file
243
packages/plugins/tanstack-query/src/runtime-v5/svelte.ts
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import {
|
||||
createInfiniteQuery,
|
||||
createMutation,
|
||||
createQuery,
|
||||
useQueryClient,
|
||||
type CreateInfiniteQueryOptions,
|
||||
type InfiniteData,
|
||||
type MutateFunction,
|
||||
type MutationOptions,
|
||||
type QueryClient,
|
||||
type StoreOrVal,
|
||||
} from '@tanstack/svelte-query-v5';
|
||||
import { QueryOptions } from '@tanstack/vue-query';
|
||||
import { setContext } from 'svelte';
|
||||
import { Readable, derived } from 'svelte/store';
|
||||
import { APIContext, FetchFn, QUERY_KEY_PREFIX, fetcher, makeUrl, marshal } from '../runtime/common';
|
||||
|
||||
export { APIContext as RequestHandlerContext } from '../runtime/common';
|
||||
|
||||
/**
|
||||
* Key for setting and getting the global query context.
|
||||
*/
|
||||
export const SvelteQueryContextKey = 'zenstack-svelte-query-context';
|
||||
|
||||
/**
|
||||
* Set context for the generated TanStack Query hooks.
|
||||
*/
|
||||
export function setHooksContext(context: APIContext) {
|
||||
setContext(SvelteQueryContextKey, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a svelte-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 svelte-query options object
|
||||
* @returns useQuery hook
|
||||
*/
|
||||
export function query<R>(
|
||||
model: string,
|
||||
url: string,
|
||||
args?: unknown,
|
||||
options?: StoreOrVal<Omit<QueryOptions<R>, 'queryKey'>>,
|
||||
fetch?: FetchFn
|
||||
) {
|
||||
const reqUrl = makeUrl(url, args);
|
||||
const queryKey = [QUERY_KEY_PREFIX + model, url, args];
|
||||
const queryFn = () => fetcher<R, false>(reqUrl, undefined, fetch, false);
|
||||
|
||||
let mergedOpt: any;
|
||||
if (isStore(options)) {
|
||||
// options is store
|
||||
mergedOpt = derived([options], ([$opt]) => {
|
||||
return {
|
||||
queryKey,
|
||||
queryFn,
|
||||
...($opt as object),
|
||||
};
|
||||
});
|
||||
} else {
|
||||
// options is value
|
||||
mergedOpt = {
|
||||
queryKey,
|
||||
queryFn,
|
||||
...options,
|
||||
};
|
||||
}
|
||||
return createQuery(mergedOpt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a svelte-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 svelte-query infinite query options object
|
||||
* @returns useQuery hook
|
||||
*/
|
||||
export function infiniteQuery<R>(
|
||||
model: string,
|
||||
url: string,
|
||||
args: unknown,
|
||||
options: StoreOrVal<Omit<CreateInfiniteQueryOptions<R, unknown, InfiniteData<R>>, 'queryKey'>>,
|
||||
fetch?: FetchFn
|
||||
) {
|
||||
const queryKey = [QUERY_KEY_PREFIX + model, url, args];
|
||||
const queryFn = ({ pageParam }: { pageParam: unknown }) =>
|
||||
fetcher<R, false>(makeUrl(url, pageParam ?? args), undefined, fetch, false);
|
||||
|
||||
let mergedOpt: StoreOrVal<CreateInfiniteQueryOptions<R, unknown, InfiniteData<R>>>;
|
||||
if (isStore<CreateInfiniteQueryOptions<R, unknown, InfiniteData<R>>>(options)) {
|
||||
// options is store
|
||||
mergedOpt = derived([options], ([$opt]) => {
|
||||
return {
|
||||
queryKey,
|
||||
queryFn,
|
||||
...$opt,
|
||||
};
|
||||
});
|
||||
} else {
|
||||
// options is value
|
||||
mergedOpt = {
|
||||
queryKey,
|
||||
queryFn,
|
||||
...options,
|
||||
};
|
||||
}
|
||||
return createInfiniteQuery<R, unknown, InfiniteData<R>>(mergedOpt);
|
||||
}
|
||||
|
||||
function isStore<T>(opt: unknown): opt is Readable<T> {
|
||||
return typeof (opt as any)?.subscribe === 'function';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a POST mutation with svelte-query.
|
||||
*
|
||||
* @param model The name of the model under mutation.
|
||||
* @param url The request URL.
|
||||
* @param options The svelte-query options.
|
||||
* @param invalidateQueries Whether to invalidate queries after mutation.
|
||||
* @returns useMutation hooks
|
||||
*/
|
||||
export function postMutation<T, R = any, C extends boolean = boolean, Result = C extends true ? R | undefined : R>(
|
||||
model: string,
|
||||
url: string,
|
||||
options?: Omit<MutationOptions<Result, unknown, T>, 'mutationFn'>,
|
||||
fetch?: FetchFn,
|
||||
invalidateQueries = true,
|
||||
checkReadBack?: C
|
||||
) {
|
||||
const queryClient = useQueryClient();
|
||||
const mutationFn = (data: any) =>
|
||||
fetcher<R, C>(
|
||||
url,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
body: marshal(data),
|
||||
},
|
||||
fetch,
|
||||
checkReadBack
|
||||
) as Promise<Result>;
|
||||
|
||||
const finalOptions = mergeOptions(model, options, invalidateQueries, mutationFn, queryClient);
|
||||
const mutation = createMutation(finalOptions);
|
||||
return mutation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a PUT mutation with svelte-query.
|
||||
*
|
||||
* @param model The name of the model under mutation.
|
||||
* @param url The request URL.
|
||||
* @param options The svelte-query options.
|
||||
* @param invalidateQueries Whether to invalidate queries after mutation.
|
||||
* @returns useMutation hooks
|
||||
*/
|
||||
export function putMutation<T, R = any, C extends boolean = boolean, Result = C extends true ? R | undefined : R>(
|
||||
model: string,
|
||||
url: string,
|
||||
options?: Omit<MutationOptions<Result, unknown, T>, 'mutationFn'>,
|
||||
fetch?: FetchFn,
|
||||
invalidateQueries = true,
|
||||
checkReadBack?: C
|
||||
) {
|
||||
const queryClient = useQueryClient();
|
||||
const mutationFn = (data: any) =>
|
||||
fetcher<R, C>(
|
||||
url,
|
||||
{
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
body: marshal(data),
|
||||
},
|
||||
fetch,
|
||||
checkReadBack
|
||||
) as Promise<Result>;
|
||||
|
||||
const finalOptions = mergeOptions(model, options, invalidateQueries, mutationFn, queryClient);
|
||||
const mutation = createMutation(finalOptions);
|
||||
return mutation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a DELETE mutation with svelte-query.
|
||||
*
|
||||
* @param model The name of the model under mutation.
|
||||
* @param url The request URL.
|
||||
* @param options The svelte-query options.
|
||||
* @param invalidateQueries Whether to invalidate queries after mutation.
|
||||
* @returns useMutation hooks
|
||||
*/
|
||||
export function deleteMutation<T, R = any, C extends boolean = boolean, Result = C extends true ? R | undefined : R>(
|
||||
model: string,
|
||||
url: string,
|
||||
options?: Omit<MutationOptions<Result, unknown, T>, 'mutationFn'>,
|
||||
fetch?: FetchFn,
|
||||
invalidateQueries = true,
|
||||
checkReadBack?: C
|
||||
) {
|
||||
const queryClient = useQueryClient();
|
||||
const mutationFn = (data: any) =>
|
||||
fetcher<R, C>(
|
||||
makeUrl(url, data),
|
||||
{
|
||||
method: 'DELETE',
|
||||
},
|
||||
fetch,
|
||||
checkReadBack
|
||||
) as Promise<Result>;
|
||||
|
||||
const finalOptions = mergeOptions(model, options, invalidateQueries, mutationFn, queryClient);
|
||||
const mutation = createMutation(finalOptions);
|
||||
return mutation;
|
||||
}
|
||||
|
||||
function mergeOptions<T, R = any>(
|
||||
model: string,
|
||||
options: Omit<MutationOptions<R, unknown, T, unknown>, 'mutationFn'> | undefined,
|
||||
invalidateQueries: boolean,
|
||||
mutationFn: MutateFunction<R, unknown, T>,
|
||||
queryClient: QueryClient
|
||||
): MutationOptions<R, unknown, T, unknown> {
|
||||
const result = { ...options, mutationFn };
|
||||
if (options?.onSuccess || invalidateQueries) {
|
||||
result.onSuccess = (...args) => {
|
||||
if (invalidateQueries) {
|
||||
queryClient.invalidateQueries({ queryKey: [QUERY_KEY_PREFIX + model] });
|
||||
}
|
||||
return options?.onSuccess?.(...args);
|
||||
};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
1
packages/plugins/tanstack-query/src/runtime-v5/vue.ts
Normal file
1
packages/plugins/tanstack-query/src/runtime-v5/vue.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export * from '../runtime/vue';
|
||||
|
|
@ -43,7 +43,13 @@ export const Provider = RequestHandlerContext.Provider;
|
|||
* @param options The react-query options object
|
||||
* @returns useQuery hook
|
||||
*/
|
||||
export function query<R>(model: string, url: string, args?: unknown, options?: UseQueryOptions<R>, fetch?: FetchFn) {
|
||||
export function query<R>(
|
||||
model: string,
|
||||
url: string,
|
||||
args?: unknown,
|
||||
options?: Omit<UseQueryOptions<R>, 'queryKey'>,
|
||||
fetch?: FetchFn
|
||||
) {
|
||||
const reqUrl = makeUrl(url, args);
|
||||
return useQuery<R>({
|
||||
queryKey: [QUERY_KEY_PREFIX + model, url, args],
|
||||
|
|
@ -65,7 +71,7 @@ export function infiniteQuery<R>(
|
|||
model: string,
|
||||
url: string,
|
||||
args?: unknown,
|
||||
options?: UseInfiniteQueryOptions<R>,
|
||||
options?: Omit<UseInfiniteQueryOptions<R>, 'queryKey'>,
|
||||
fetch?: FetchFn
|
||||
) {
|
||||
return useInfiniteQuery<R>({
|
||||
|
|
@ -109,8 +115,8 @@ export function postMutation<T, R = any, C extends boolean = boolean, Result = C
|
|||
checkReadBack
|
||||
) as Promise<Result>;
|
||||
|
||||
const finalOptions = mergeOptions<T, Result>(model, options, invalidateQueries, mutationFn, queryClient);
|
||||
const mutation = useMutation<Result, unknown, T>(finalOptions);
|
||||
const finalOptions = mergeOptions(model, options, invalidateQueries, mutationFn, queryClient);
|
||||
const mutation = useMutation(finalOptions);
|
||||
return mutation;
|
||||
}
|
||||
|
||||
|
|
@ -146,8 +152,8 @@ export function putMutation<T, R = any, C extends boolean = boolean, Result = C
|
|||
checkReadBack
|
||||
) as Promise<Result>;
|
||||
|
||||
const finalOptions = mergeOptions<T, Result>(model, options, invalidateQueries, mutationFn, queryClient);
|
||||
const mutation = useMutation<Result, unknown, T>(finalOptions);
|
||||
const finalOptions = mergeOptions(model, options, invalidateQueries, mutationFn, queryClient);
|
||||
const mutation = useMutation(finalOptions);
|
||||
return mutation;
|
||||
}
|
||||
|
||||
|
|
@ -179,8 +185,8 @@ export function deleteMutation<T, R = any, C extends boolean = boolean, Result =
|
|||
checkReadBack
|
||||
) as Promise<Result>;
|
||||
|
||||
const finalOptions = mergeOptions<T, Result>(model, options, invalidateQueries, mutationFn, queryClient);
|
||||
const mutation = useMutation<Result, unknown, T>(finalOptions);
|
||||
const finalOptions = mergeOptions(model, options, invalidateQueries, mutationFn, queryClient);
|
||||
const mutation = useMutation(finalOptions);
|
||||
return mutation;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,13 @@ export function setHooksContext(context: APIContext) {
|
|||
* @param options The svelte-query options object
|
||||
* @returns useQuery hook
|
||||
*/
|
||||
export function query<R>(model: string, url: string, args?: unknown, options?: QueryOptions<R>, fetch?: FetchFn) {
|
||||
export function query<R>(
|
||||
model: string,
|
||||
url: string,
|
||||
args?: unknown,
|
||||
options?: Omit<QueryOptions<R>, 'queryKey'>,
|
||||
fetch?: FetchFn
|
||||
) {
|
||||
const reqUrl = makeUrl(url, args);
|
||||
return createQuery<R>({
|
||||
queryKey: [QUERY_KEY_PREFIX + model, url, args],
|
||||
|
|
@ -58,7 +64,7 @@ export function infiniteQuery<R>(
|
|||
model: string,
|
||||
url: string,
|
||||
args?: unknown,
|
||||
options?: CreateInfiniteQueryOptions<R>,
|
||||
options?: Omit<CreateInfiniteQueryOptions<R>, 'queryKey'>,
|
||||
fetch?: FetchFn
|
||||
) {
|
||||
return createInfiniteQuery<R>({
|
||||
|
|
@ -100,8 +106,8 @@ export function postMutation<T, R = any, C extends boolean = boolean, Result = C
|
|||
checkReadBack
|
||||
) as Promise<Result>;
|
||||
|
||||
const finalOptions = mergeOptions<T, Result>(model, options, invalidateQueries, mutationFn, queryClient);
|
||||
const mutation = createMutation<Result, unknown, T>(finalOptions);
|
||||
const finalOptions = mergeOptions(model, options, invalidateQueries, mutationFn, queryClient);
|
||||
const mutation = createMutation(finalOptions);
|
||||
return mutation;
|
||||
}
|
||||
|
||||
|
|
@ -137,8 +143,8 @@ export function putMutation<T, R = any, C extends boolean = boolean, Result = C
|
|||
checkReadBack
|
||||
) as Promise<Result>;
|
||||
|
||||
const finalOptions = mergeOptions<T, Result>(model, options, invalidateQueries, mutationFn, queryClient);
|
||||
const mutation = createMutation<Result, unknown, T>(finalOptions);
|
||||
const finalOptions = mergeOptions(model, options, invalidateQueries, mutationFn, queryClient);
|
||||
const mutation = createMutation(finalOptions);
|
||||
return mutation;
|
||||
}
|
||||
|
||||
|
|
@ -170,8 +176,8 @@ export function deleteMutation<T, R = any, C extends boolean = boolean, Result =
|
|||
checkReadBack
|
||||
) as Promise<Result>;
|
||||
|
||||
const finalOptions = mergeOptions<T, Result>(model, options, invalidateQueries, mutationFn, queryClient);
|
||||
const mutation = createMutation<Result, unknown, T>(finalOptions);
|
||||
const finalOptions = mergeOptions(model, options, invalidateQueries, mutationFn, queryClient);
|
||||
const mutation = createMutation(finalOptions);
|
||||
return mutation;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ model Foo {
|
|||
}
|
||||
`;
|
||||
|
||||
it('react-query run plugin', async () => {
|
||||
it('react-query run plugin v4', async () => {
|
||||
await loadSchema(
|
||||
`
|
||||
plugin tanstack {
|
||||
|
|
@ -59,18 +59,36 @@ ${sharedModel}
|
|||
{
|
||||
provider: 'postgresql',
|
||||
pushDb: false,
|
||||
extraDependencies: [
|
||||
`${origDir}/dist`,
|
||||
'react@18.2.0',
|
||||
'@types/react@18.2.0',
|
||||
'@tanstack/react-query@4.29.7',
|
||||
],
|
||||
extraDependencies: ['react@18.2.0', '@types/react@18.2.0', '@tanstack/react-query@4.29.7'],
|
||||
copyDependencies: [`${origDir}/dist`],
|
||||
compile: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('vue-query run plugin', async () => {
|
||||
it('react-query run plugin v5', async () => {
|
||||
await loadSchema(
|
||||
`
|
||||
plugin tanstack {
|
||||
provider = '${process.cwd()}/dist'
|
||||
output = '$projectRoot/hooks'
|
||||
target = 'react'
|
||||
version = 'v5'
|
||||
}
|
||||
|
||||
${sharedModel}
|
||||
`,
|
||||
{
|
||||
provider: 'postgresql',
|
||||
pushDb: false,
|
||||
extraDependencies: ['react@18.2.0', '@types/react@18.2.0', '@tanstack/react-query@^5.0.0'],
|
||||
copyDependencies: [`${origDir}/dist`],
|
||||
compile: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('vue-query run plugin v4', async () => {
|
||||
await loadSchema(
|
||||
`
|
||||
plugin tanstack {
|
||||
|
|
@ -84,13 +102,36 @@ ${sharedModel}
|
|||
{
|
||||
provider: 'postgresql',
|
||||
pushDb: false,
|
||||
extraDependencies: [`${origDir}/dist`, 'vue@^3.3.4', '@tanstack/vue-query@4.37.0'],
|
||||
extraDependencies: ['vue@^3.3.4', '@tanstack/vue-query@4.37.0'],
|
||||
copyDependencies: [`${origDir}/dist`],
|
||||
compile: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('svelte-query run plugin', async () => {
|
||||
it('vue-query run plugin v5', async () => {
|
||||
await loadSchema(
|
||||
`
|
||||
plugin tanstack {
|
||||
provider = '${process.cwd()}/dist'
|
||||
output = '$projectRoot/hooks'
|
||||
target = 'vue'
|
||||
version = 'v5'
|
||||
}
|
||||
|
||||
${sharedModel}
|
||||
`,
|
||||
{
|
||||
provider: 'postgresql',
|
||||
pushDb: false,
|
||||
extraDependencies: ['vue@^3.3.4', '@tanstack/vue-query@latest'],
|
||||
copyDependencies: [`${origDir}/dist`],
|
||||
compile: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('svelte-query run plugin v4', async () => {
|
||||
await loadSchema(
|
||||
`
|
||||
plugin tanstack {
|
||||
|
|
@ -104,7 +145,30 @@ ${sharedModel}
|
|||
{
|
||||
provider: 'postgresql',
|
||||
pushDb: false,
|
||||
extraDependencies: [`${origDir}/dist`, 'svelte@^3.0.0', '@tanstack/svelte-query@4.29.7'],
|
||||
extraDependencies: ['svelte@^3.0.0', '@tanstack/svelte-query@4.29.7'],
|
||||
copyDependencies: [`${origDir}/dist`],
|
||||
compile: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('svelte-query run plugin v5', async () => {
|
||||
await loadSchema(
|
||||
`
|
||||
plugin tanstack {
|
||||
provider = '${process.cwd()}/dist'
|
||||
output = '$projectRoot/hooks'
|
||||
target = 'svelte'
|
||||
version = 'v5'
|
||||
}
|
||||
|
||||
${sharedModel}
|
||||
`,
|
||||
{
|
||||
provider: 'postgresql',
|
||||
pushDb: false,
|
||||
extraDependencies: ['svelte@^3.0.0', '@tanstack/svelte-query@^5.0.0'],
|
||||
copyDependencies: [`${origDir}/dist`],
|
||||
compile: true,
|
||||
}
|
||||
);
|
||||
|
|
|
|||
11
packages/plugins/tanstack-query/tsup-v5.config.ts
Normal file
11
packages/plugins/tanstack-query/tsup-v5.config.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { defineConfig } from 'tsup';
|
||||
|
||||
export default defineConfig({
|
||||
entry: ['src/runtime-v5/index.ts', 'src/runtime-v5/react.ts', 'src/runtime-v5/vue.ts', 'src/runtime-v5/svelte.ts'],
|
||||
outDir: 'dist/runtime-v5',
|
||||
splitting: false,
|
||||
sourcemap: true,
|
||||
clean: true,
|
||||
dts: true,
|
||||
format: ['cjs', 'esm'],
|
||||
});
|
||||
|
|
@ -96,6 +96,7 @@ export type SchemaLoadOptions = {
|
|||
pushDb?: boolean;
|
||||
fullZod?: boolean;
|
||||
extraDependencies?: string[];
|
||||
copyDependencies?: string[];
|
||||
compile?: boolean;
|
||||
customSchemaFilePath?: string;
|
||||
output?: string;
|
||||
|
|
@ -202,6 +203,11 @@ export async function loadSchema(schema: string, options?: SchemaLoadOptions) {
|
|||
run(`npm install ${dep}`);
|
||||
});
|
||||
|
||||
opt.copyDependencies?.forEach((dep) => {
|
||||
const pkgJson = JSON.parse(fs.readFileSync(path.join(dep, 'package.json'), { encoding: 'utf-8' }));
|
||||
fs.cpSync(dep, path.join(projectRoot, 'node_modules', pkgJson.name), { recursive: true, force: true });
|
||||
});
|
||||
|
||||
const PrismaClient = require(path.join(projectRoot, 'node_modules/.prisma/client')).PrismaClient;
|
||||
let prisma = new PrismaClient({ log: ['info', 'warn', 'error'] });
|
||||
|
||||
|
|
|
|||
|
|
@ -246,9 +246,15 @@ importers:
|
|||
'@tanstack/react-query':
|
||||
specifier: ^4.29.7
|
||||
version: 4.29.7(react-dom@18.2.0)(react@18.2.0)
|
||||
'@tanstack/react-query-v5':
|
||||
specifier: npm:@tanstack/react-query@^5.0.0
|
||||
version: /@tanstack/react-query@5.0.5(react@18.2.0)
|
||||
'@tanstack/svelte-query':
|
||||
specifier: ^4.29.7
|
||||
version: 4.29.7(svelte@4.2.1)
|
||||
'@tanstack/svelte-query-v5':
|
||||
specifier: npm:@tanstack/svelte-query@^5.0.0
|
||||
version: /@tanstack/svelte-query@5.3.0(svelte@4.2.1)
|
||||
'@tanstack/vue-query':
|
||||
specifier: ^4.37.0
|
||||
version: 4.37.0(vue@3.3.4)
|
||||
|
|
@ -279,6 +285,9 @@ importers:
|
|||
react:
|
||||
specifier: 18.2.0
|
||||
version: 18.2.0
|
||||
replace-in-file:
|
||||
specifier: ^7.0.1
|
||||
version: 7.0.1
|
||||
rimraf:
|
||||
specifier: ^3.0.2
|
||||
version: 3.0.2
|
||||
|
|
@ -714,7 +723,7 @@ importers:
|
|||
devDependencies:
|
||||
'@sveltejs/kit':
|
||||
specifier: 1.21.0
|
||||
version: 1.21.0(svelte@4.0.5)(vite@4.4.11)
|
||||
version: 1.21.0(svelte@4.2.1)(vite@4.4.11)
|
||||
'@types/body-parser':
|
||||
specifier: ^1.19.2
|
||||
version: 1.19.2
|
||||
|
|
@ -4168,7 +4177,7 @@ packages:
|
|||
'@sinonjs/commons': 3.0.0
|
||||
dev: true
|
||||
|
||||
/@sveltejs/kit@1.21.0(svelte@4.0.5)(vite@4.4.11):
|
||||
/@sveltejs/kit@1.21.0(svelte@4.2.1)(vite@4.4.11):
|
||||
resolution: {integrity: sha512-CBsYoI34SjtOQp0eG85dmVnvTR3Pjs8VgAQhO0CgQja9BIorKl808F1X8EunPhCcyek5r5lKQE1Mmbi0RuzHqA==}
|
||||
engines: {node: ^16.14 || >=18}
|
||||
hasBin: true
|
||||
|
|
@ -4177,7 +4186,7 @@ packages:
|
|||
svelte: ^3.54.0 || ^4.0.0-next.0
|
||||
vite: ^4.0.0
|
||||
dependencies:
|
||||
'@sveltejs/vite-plugin-svelte': 2.4.2(svelte@4.0.5)(vite@4.4.11)
|
||||
'@sveltejs/vite-plugin-svelte': 2.4.2(svelte@4.2.1)(vite@4.4.11)
|
||||
'@types/cookie': 0.5.1
|
||||
cookie: 0.5.0
|
||||
devalue: 4.3.2
|
||||
|
|
@ -4188,14 +4197,14 @@ packages:
|
|||
sade: 1.8.1
|
||||
set-cookie-parser: 2.6.0
|
||||
sirv: 2.0.3
|
||||
svelte: 4.0.5
|
||||
svelte: 4.2.1
|
||||
undici: 5.22.1
|
||||
vite: 4.4.11(@types/node@18.0.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@sveltejs/vite-plugin-svelte-inspector@1.0.3(@sveltejs/vite-plugin-svelte@2.4.2)(svelte@4.0.5)(vite@4.4.11):
|
||||
/@sveltejs/vite-plugin-svelte-inspector@1.0.3(@sveltejs/vite-plugin-svelte@2.4.2)(svelte@4.2.1)(vite@4.4.11):
|
||||
resolution: {integrity: sha512-Khdl5jmmPN6SUsVuqSXatKpQTMIifoQPDanaxC84m9JxIibWvSABJyHpyys0Z+1yYrxY5TTEQm+6elh0XCMaOA==}
|
||||
engines: {node: ^14.18.0 || >= 16}
|
||||
peerDependencies:
|
||||
|
|
@ -4203,28 +4212,28 @@ packages:
|
|||
svelte: ^3.54.0 || ^4.0.0
|
||||
vite: ^4.0.0
|
||||
dependencies:
|
||||
'@sveltejs/vite-plugin-svelte': 2.4.2(svelte@4.0.5)(vite@4.4.11)
|
||||
'@sveltejs/vite-plugin-svelte': 2.4.2(svelte@4.2.1)(vite@4.4.11)
|
||||
debug: 4.3.4
|
||||
svelte: 4.0.5
|
||||
svelte: 4.2.1
|
||||
vite: 4.4.11(@types/node@18.0.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@sveltejs/vite-plugin-svelte@2.4.2(svelte@4.0.5)(vite@4.4.11):
|
||||
/@sveltejs/vite-plugin-svelte@2.4.2(svelte@4.2.1)(vite@4.4.11):
|
||||
resolution: {integrity: sha512-ePfcC48ftMKhkT0OFGdOyycYKnnkT6i/buzey+vHRTR/JpQvuPzzhf1PtKqCDQfJRgoPSN2vscXs6gLigx/zGw==}
|
||||
engines: {node: ^14.18.0 || >= 16}
|
||||
peerDependencies:
|
||||
svelte: ^3.54.0 || ^4.0.0
|
||||
vite: ^4.0.0
|
||||
dependencies:
|
||||
'@sveltejs/vite-plugin-svelte-inspector': 1.0.3(@sveltejs/vite-plugin-svelte@2.4.2)(svelte@4.0.5)(vite@4.4.11)
|
||||
'@sveltejs/vite-plugin-svelte-inspector': 1.0.3(@sveltejs/vite-plugin-svelte@2.4.2)(svelte@4.2.1)(vite@4.4.11)
|
||||
debug: 4.3.4
|
||||
deepmerge: 4.3.1
|
||||
kleur: 4.1.5
|
||||
magic-string: 0.30.4
|
||||
svelte: 4.0.5
|
||||
svelte-hmr: 0.15.2(svelte@4.0.5)
|
||||
svelte: 4.2.1
|
||||
svelte-hmr: 0.15.2(svelte@4.2.1)
|
||||
vite: 4.4.11(@types/node@18.0.0)
|
||||
vitefu: 0.2.4(vite@4.4.11)
|
||||
transitivePeerDependencies:
|
||||
|
|
@ -4262,6 +4271,10 @@ packages:
|
|||
resolution: {integrity: sha512-DJSilV5+ytBP1FbFcEJovv4rnnm/CokuVvrBEtW/Va9DvuJ3HksbXUJEpI0aV1KtuL4ZoO9AVE6PyNLzF7tLeA==}
|
||||
dev: true
|
||||
|
||||
/@tanstack/query-core@5.0.5:
|
||||
resolution: {integrity: sha512-MThCETMkHDHTnFZHp71L+SqTtD5d6XHftFCVR1xRJdWM3qGrlQ2VCXaj0SKVcyJej2e1Opa2c7iknu1llxCDNQ==}
|
||||
dev: true
|
||||
|
||||
/@tanstack/react-query@4.28.0(react@18.2.0):
|
||||
resolution: {integrity: sha512-8cGBV5300RHlvYdS4ea+G1JcZIt5CIuprXYFnsWggkmGoC0b5JaqG0fIX3qwDL9PTNkKvG76NGThIWbpXivMrQ==}
|
||||
peerDependencies:
|
||||
|
|
@ -4297,6 +4310,22 @@ packages:
|
|||
use-sync-external-store: 1.2.0(react@18.2.0)
|
||||
dev: true
|
||||
|
||||
/@tanstack/react-query@5.0.5(react@18.2.0):
|
||||
resolution: {integrity: sha512-ZG0Q4HZ0iuI8mWiZ2/MdVYPHbrmAVhMn7+gLOkxJh6zLIgCL4luSZlohzN5Xt4MjxfxxWioO1nemwpudaTsmQg==}
|
||||
peerDependencies:
|
||||
react: ^18.0.0
|
||||
react-dom: ^18.0.0
|
||||
react-native: '*'
|
||||
peerDependenciesMeta:
|
||||
react-dom:
|
||||
optional: true
|
||||
react-native:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@tanstack/query-core': 5.0.5
|
||||
react: 18.2.0
|
||||
dev: true
|
||||
|
||||
/@tanstack/svelte-query@4.29.7(svelte@4.2.1):
|
||||
resolution: {integrity: sha512-+GvOcGEiFZYj91luPcIIVakmDqXkS5tyWlBLf/zg9E9hohq7SiGug9C9DUWwvSBk80JefAOCioja5jrumrPp6Q==}
|
||||
peerDependencies:
|
||||
|
|
@ -4306,6 +4335,15 @@ packages:
|
|||
svelte: 4.2.1
|
||||
dev: true
|
||||
|
||||
/@tanstack/svelte-query@5.3.0(svelte@4.2.1):
|
||||
resolution: {integrity: sha512-gGC2jh7VV2F2rZygLVbvGxYbwFIW7d3rrY8iuozDOHvBft/y8/rU9aNzm/vrOdsPt2TMF3IgS3diDlp+21z6Lw==}
|
||||
peerDependencies:
|
||||
svelte: '>=3 <5'
|
||||
dependencies:
|
||||
'@tanstack/query-core': 5.0.5
|
||||
svelte: 4.2.1
|
||||
dev: true
|
||||
|
||||
/@tanstack/vue-query@4.37.0(vue@3.3.4):
|
||||
resolution: {integrity: sha512-ZZvlEuXzCwM9QYS1GCf9FTo1XycBxPSvjJbIHXTU2iZuUla02EzTO7R9QOnML6FRQRzD3n5Eyn2v6zbhCHS/qA==}
|
||||
peerDependencies:
|
||||
|
|
@ -13112,32 +13150,13 @@ packages:
|
|||
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
/svelte-hmr@0.15.2(svelte@4.0.5):
|
||||
/svelte-hmr@0.15.2(svelte@4.2.1):
|
||||
resolution: {integrity: sha512-q/bAruCvFLwvNbeE1x3n37TYFb3mTBJ6TrCq6p2CoFbSTNhDE9oAtEfpy+wmc9So8AG0Tja+X0/mJzX9tSfvIg==}
|
||||
engines: {node: ^12.20 || ^14.13.1 || >= 16}
|
||||
peerDependencies:
|
||||
svelte: ^3.19.0 || ^4.0.0-next.0
|
||||
dependencies:
|
||||
svelte: 4.0.5
|
||||
dev: true
|
||||
|
||||
/svelte@4.0.5:
|
||||
resolution: {integrity: sha512-PHKPWP1wiWHBtsE57nCb8xiWB3Ht7/3Kvi3jac0XIxUM2rep8alO7YoAtgWeGD7++tFy46krilOrPW0mG3Dx+A==}
|
||||
engines: {node: '>=16'}
|
||||
dependencies:
|
||||
'@ampproject/remapping': 2.2.1
|
||||
'@jridgewell/sourcemap-codec': 1.4.15
|
||||
'@jridgewell/trace-mapping': 0.3.18
|
||||
acorn: 8.10.0
|
||||
aria-query: 5.3.0
|
||||
axobject-query: 3.2.1
|
||||
code-red: 1.0.3
|
||||
css-tree: 2.3.1
|
||||
estree-walker: 3.0.3
|
||||
is-reference: 3.0.1
|
||||
locate-character: 3.0.0
|
||||
magic-string: 0.30.4
|
||||
periscopic: 3.1.0
|
||||
svelte: 4.2.1
|
||||
dev: true
|
||||
|
||||
/svelte@4.2.1:
|
||||
|
|
|
|||
Loading…
Reference in a new issue