Skip to content

Commit 53716c9

Browse files
authored
feat: implementing sveltekit adapter and refactor server package (#418)
1 parent 9351fc9 commit 53716c9

31 files changed

+1057
-219
lines changed

packages/plugins/tanstack-query/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"build": "pnpm lint && pnpm clean && tsc && copyfiles ./package.json ./README.md ./LICENSE 'res/**/*' dist",
1414
"watch": "tsc --watch",
1515
"lint": "eslint src --ext ts",
16+
"test": "jest",
1617
"prepublishOnly": "pnpm build",
1718
"publish-dev": "pnpm publish --tag dev"
1819
},
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
function marshal(value: unknown) {
2+
return JSON.stringify(value);
3+
}
4+
5+
function unmarshal(value: string) {
6+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
7+
return JSON.parse(value) as any;
8+
}
9+
10+
function makeUrl(url: string, args: unknown) {
11+
return args ? url + `?q=${encodeURIComponent(JSON.stringify(args))}` : url;
12+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import superjson from 'superjson';
2+
3+
function marshal(value: unknown) {
4+
return superjson.stringify(value);
5+
}
6+
7+
function unmarshal(value: string) {
8+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
9+
const j = JSON.parse(value) as any;
10+
if (j?.json) {
11+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
12+
return superjson.parse<any>(value);
13+
} else {
14+
return j;
15+
}
16+
}
17+
18+
function makeUrl(url: string, args: unknown) {
19+
return args ? url + `?q=${encodeURIComponent(superjson.stringify(args))}` : url;
20+
}

packages/plugins/tanstack-query/res/react/helper.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export const Provider = RequestHandlerContext.Provider;
2828
*
2929
* @param model The name of the model under query.
3030
* @param url The request URL.
31-
* @param args The request args object, which will be superjson-stringified and appended as "?q=" parameter
31+
* @param args The request args object, URL-encoded and appended as "?q=" parameter
3232
* @param options The react-query options object
3333
* @returns useQuery hook
3434
*/

packages/plugins/tanstack-query/res/shared.ts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import superjson from 'superjson';
2-
31
/**
42
* The default query endpoint.
53
*/
@@ -17,13 +15,6 @@ export type RequestHandlerContext = {
1715
endpoint: string;
1816
};
1917

20-
/**
21-
* Builds a request URL with optional args.
22-
*/
23-
export function makeUrl(url: string, args: unknown) {
24-
return args ? url + `?q=${encodeURIComponent(marshal(args))}` : url;
25-
}
26-
2718
async function fetcher<R>(url: string, options?: RequestInit) {
2819
const res = await fetch(url, options);
2920
if (!res.ok) {
@@ -43,12 +34,3 @@ async function fetcher<R>(url: string, options?: RequestInit) {
4334
throw err;
4435
}
4536
}
46-
47-
export function marshal(value: unknown) {
48-
return superjson.stringify(value);
49-
}
50-
51-
export function unmarshal(value: string) {
52-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
53-
return superjson.parse<any>(value);
54-
}

packages/plugins/tanstack-query/res/svelte/helper.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export const SvelteQueryContextKey = 'zenstack-svelte-query-context';
2020
*
2121
* @param model The name of the model under query.
2222
* @param url The request URL.
23-
* @param args The request args object, which will be superjson-stringified and appended as "?q=" parameter
23+
* @param args The request args object, URL-encoded and appended as "?q=" parameter
2424
* @param options The svelte-query options object
2525
* @returns useQuery hook
2626
*/

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export async function generate(model: Model, options: PluginOptions, dmmf: DMMF.
3535
}
3636

3737
generateIndex(project, outDir, models);
38-
generateHelper(target, project, outDir);
38+
generateHelper(target, project, outDir, options.useSuperJson === true);
3939

4040
models.forEach((dataModel) => {
4141
const mapping = dmmf.mappings.modelOperations.find((op) => op.model === dataModel.name);
@@ -385,7 +385,7 @@ function generateIndex(project: Project, outDir: string, models: DataModel[]) {
385385
sf.addStatements(`export * from './_helper';`);
386386
}
387387

388-
function generateHelper(target: TargetFramework, project: Project, outDir: string) {
388+
function generateHelper(target: TargetFramework, project: Project, outDir: string, useSuperJson: boolean) {
389389
let srcFile: string;
390390
switch (target) {
391391
case 'react':
@@ -398,10 +398,15 @@ function generateHelper(target: TargetFramework, project: Project, outDir: strin
398398
throw new PluginError(`Unsupported target: ${target}`);
399399
}
400400

401-
// merge content of `shared.ts` and `helper.ts`
401+
// merge content of `shared.ts`, `helper.ts` and `marshal-?.ts`
402402
const sharedContent = fs.readFileSync(path.join(__dirname, './res/shared.ts'), 'utf-8');
403403
const helperContent = fs.readFileSync(srcFile, 'utf-8');
404-
project.createSourceFile(path.join(outDir, '_helper.ts'), `${sharedContent}\n${helperContent}`, {
404+
const marshalContent = fs.readFileSync(
405+
path.join(__dirname, useSuperJson ? './res/marshal-superjson.ts' : './res/marshal-json.ts'),
406+
'utf-8'
407+
);
408+
409+
project.createSourceFile(path.join(outDir, '_helper.ts'), `${sharedContent}\n${helperContent}\n${marshalContent}`, {
405410
overwrite: true,
406411
});
407412
}

packages/plugins/tanstack-query/tests/plugin.test.ts

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ model Foo {
4040
}
4141
`;
4242

43-
it('react-query generator', async () => {
43+
it('react-query generator regular json', async () => {
4444
await loadSchema(
4545
`
4646
plugin tanstack {
@@ -49,6 +49,25 @@ plugin tanstack {
4949
target = 'react'
5050
}
5151
52+
${sharedModel}
53+
`,
54+
true,
55+
false,
56+
[`${origDir}/dist`, 'react', '@types/react', '@tanstack/react-query'],
57+
true
58+
);
59+
});
60+
61+
it('react-query generator superjson', async () => {
62+
await loadSchema(
63+
`
64+
plugin tanstack {
65+
provider = '${process.cwd()}/dist'
66+
output = '$projectRoot/hooks'
67+
target = 'react'
68+
useSuperJson = true
69+
}
70+
5271
${sharedModel}
5372
`,
5473
true,
@@ -58,13 +77,32 @@ ${sharedModel}
5877
);
5978
});
6079

61-
it('svelte-query generator', async () => {
80+
it('svelte-query generator regular json', async () => {
81+
await loadSchema(
82+
`
83+
plugin tanstack {
84+
provider = '${process.cwd()}/dist'
85+
output = '$projectRoot/hooks'
86+
target = 'svelte'
87+
}
88+
89+
${sharedModel}
90+
`,
91+
true,
92+
false,
93+
[`${origDir}/dist`, 'svelte', '@types/react', '@tanstack/svelte-query'],
94+
true
95+
);
96+
});
97+
98+
it('svelte-query generator superjson', async () => {
6299
await loadSchema(
63100
`
64101
plugin tanstack {
65102
provider = '${process.cwd()}/dist'
66103
output = '$projectRoot/hooks'
67104
target = 'svelte'
105+
useSuperJson = true
68106
}
69107
70108
${sharedModel}

packages/server/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"@zenstackhq/sdk": "workspace:*",
2929
"change-case": "^4.1.2",
3030
"lower-case-first": "^2.0.2",
31+
"superjson": "^1.11.0",
3132
"tiny-invariant": "^1.3.1",
3233
"ts-japi": "^1.8.0",
3334
"upper-case-first": "^2.0.2",
@@ -36,6 +37,7 @@
3637
"zod-validation-error": "^0.2.1"
3738
},
3839
"devDependencies": {
40+
"@sveltejs/kit": "^1.16.3",
3941
"@types/body-parser": "^1.19.2",
4042
"@types/express": "^4.17.17",
4143
"@types/jest": "^29.5.0",
@@ -48,6 +50,7 @@
4850
"express": "^4.18.2",
4951
"fastify": "^4.14.1",
5052
"fastify-plugin": "^4.5.0",
53+
"isomorphic-fetch": "^3.0.0",
5154
"jest": "^29.5.0",
5255
"rimraf": "^3.0.2",
5356
"supertest": "^6.3.3",

packages/server/src/api/rest/index.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
2-
/* eslint-disable @typescript-eslint/no-unused-vars */
32
import {
43
DbClientContract,
54
FieldInfo,
@@ -16,7 +15,7 @@ import { DataDocument, Linker, Paginator, Relator, Serializer, SerializerOptions
1615
import UrlPattern from 'url-pattern';
1716
import z from 'zod';
1817
import { fromZodError } from 'zod-validation-error';
19-
import { LoggerConfig, RequestContext, Response } from '../types';
18+
import { LoggerConfig, RequestContext, Response } from '../../types';
2019
import { getZodSchema, logWarning, stripAuxFields } from '../utils';
2120

2221
const urlPatterns = {
@@ -320,7 +319,7 @@ class RequestHandler {
320319
let match = urlPatterns.single.match(path);
321320
if (match) {
322321
// resource deletion
323-
return await this.processDelete(prisma, match.type, match.id, query);
322+
return await this.processDelete(prisma, match.type, match.id);
324323
}
325324

326325
match = urlPatterns.relationship.match(path);
@@ -899,12 +898,7 @@ class RequestHandler {
899898
}
900899
}
901900

902-
private async processDelete(
903-
prisma: DbClientContract,
904-
type: any,
905-
resourceId: string,
906-
query: Record<string, string | string[]> | undefined
907-
): Promise<Response> {
901+
private async processDelete(prisma: DbClientContract, type: any, resourceId: string): Promise<Response> {
908902
const typeInfo = this.typeMap[type];
909903
if (!typeInfo) {
910904
return this.makeUnsupportedModelError(type);

packages/server/src/api/rpc/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
isPrismaClientValidationError,
66
} from '@zenstackhq/runtime';
77
import { ModelZodSchema } from '@zenstackhq/runtime/zod';
8-
import { LoggerConfig, RequestContext, Response } from '../types';
8+
import { LoggerConfig, RequestContext, Response } from '../../types';
99
import { logError, stripAuxFields, zodValidate } from '../utils';
1010

1111
/**

packages/server/src/api/types.ts

Lines changed: 0 additions & 48 deletions
This file was deleted.

packages/server/src/api/utils.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { ModelZodSchema } from '@zenstackhq/runtime/zod';
33
import { upperCaseFirst } from 'upper-case-first';
44
import { fromZodError } from 'zod-validation-error';
55
import { AUXILIARY_FIELDS } from '@zenstackhq/sdk';
6-
import { LoggerConfig } from './types';
6+
import { LoggerConfig } from '../types';
77

88
export function getZodSchema(zodSchemas: ModelZodSchema, model: string, operation: keyof DbOperations) {
99
if (zodSchemas[model]) {
@@ -42,11 +42,19 @@ export function logError(logger: LoggerConfig | undefined | null, message: strin
4242
}
4343
}
4444

45-
export function logWarning(logger: LoggerConfig | undefined | null, message: string, code?: string) {
45+
export function logWarning(logger: LoggerConfig | undefined | null, message: string) {
4646
if (logger === undefined) {
47-
console.warn(`@zenstackhq/server: error ${code ? '[' + code + ']' : ''}, ${message}`);
47+
console.warn(`@zenstackhq/server: ${message}`);
4848
} else if (logger?.warn) {
49-
logger.warn(message, code);
49+
logger.warn(message);
50+
}
51+
}
52+
53+
export function logInfo(logger: LoggerConfig | undefined | null, message: string) {
54+
if (logger === undefined) {
55+
console.log(`@zenstackhq/server: ${message}`);
56+
} else if (logger?.info) {
57+
logger.info(message);
5058
}
5159
}
5260

packages/server/src/express/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export { default as ZenStackMiddleware } from './middleware';
2+
export * from './middleware';

0 commit comments

Comments
 (0)