diff --git a/README.md b/README.md index 2316cd15b..a976aef69 100644 --- a/README.md +++ b/README.md @@ -272,7 +272,7 @@ export const getServerSideProps: GetServerSideProps = async () => { ### [Database hosting considerations](/docs/ref/database-hosting-considerations.md) -### [Setup logging](/docs/ref/setup-logging.md) +### [Setting up logging](/docs/ref/setup-logging.md) ## Reach out to us for issues, feedback and ideas! diff --git a/docs/ref/setup-logging.md b/docs/ref/setup-logging.md index 7e5194e27..ee8c0cfdd 100644 --- a/docs/ref/setup-logging.md +++ b/docs/ref/setup-logging.md @@ -1,24 +1,24 @@ -# Setup Logging +# Setting Up Logging ZenStack uses the following levels to control server-side logging: -1. error +- error Error level logging -1. warn +- warn Warning level logging -1. info +- info Info level logging -1. verbose +- verbose Verbose level logging -1. query +- query Detailed database query logging @@ -28,7 +28,24 @@ You can turn log levels on and off in `zenstack.config.json`: ```json { - "log": ["verbose", "info", "warn"] + "log": ["verbose", "info"] +} +``` + +The settings shown above is an shorthand for: + +```json +{ + "log": [ + { + "level": "verbose", + "emit": "stdout" + }, + { + "level": "info", + "emit": "stdout" + } + ] } ``` diff --git a/package.json b/package.json index 5f9c2d7fc..cd0358ae9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zenstack-monorepo", - "version": "0.2.9", + "version": "0.2.10", "description": "", "scripts": { "build": "pnpm -r build", diff --git a/packages/internal/package.json b/packages/internal/package.json index 895906c38..64b09387d 100644 --- a/packages/internal/package.json +++ b/packages/internal/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/internal", - "version": "0.2.9", + "version": "0.2.10", "displayName": "ZenStack Internal Library", "description": "ZenStack internal runtime library. This package is for supporting runtime functionality of ZenStack and not supposed to be used directly.", "repository": { diff --git a/packages/runtime/package.json b/packages/runtime/package.json index 0da45ec7b..ae62c212e 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/runtime", "displayName": "ZenStack Runtime Library", - "version": "0.2.9", + "version": "0.2.10", "description": "This package contains runtime library for consuming client and server side code generated by ZenStack.", "repository": { "type": "git", diff --git a/packages/schema/package.json b/packages/schema/package.json index 3dbe8e7bd..cd81f01f9 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -3,7 +3,7 @@ "publisher": "zenstack", "displayName": "ZenStack Language Tools", "description": "ZenStack is a toolkit that simplifies full-stack development", - "version": "0.2.9", + "version": "0.2.10", "author": { "name": "ZenStack Team" }, diff --git a/packages/schema/src/generator/prisma/query-guard-generator.ts b/packages/schema/src/generator/prisma/query-guard-generator.ts index f0cbf7fbc..84204a77d 100644 --- a/packages/schema/src/generator/prisma/query-guard-generator.ts +++ b/packages/schema/src/generator/prisma/query-guard-generator.ts @@ -160,7 +160,8 @@ export default class QueryGuardGenerator { .addBody(); func.addStatements( - `const user = context.user ?? { id: '${UNKNOWN_USER_ID}' };` + // make suer user id is always available + `const user = context.user?.id ? context.user : { ...context.user, id: '${UNKNOWN_USER_ID}' };` ); // r = ; diff --git a/samples/todo/package-lock.json b/samples/todo/package-lock.json index 244c5595a..12f7a96c5 100644 --- a/samples/todo/package-lock.json +++ b/samples/todo/package-lock.json @@ -1,17 +1,17 @@ { "name": "todo", - "version": "0.2.9", + "version": "0.2.10", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "todo", - "version": "0.2.9", + "version": "0.2.10", "dependencies": { "@heroicons/react": "^2.0.12", "@prisma/client": "^4.4.0", - "@zenstackhq/internal": "^0.2.9", - "@zenstackhq/runtime": "^0.2.9", + "@zenstackhq/internal": "^0.2.10", + "@zenstackhq/runtime": "^0.2.10", "bcryptjs": "^2.4.3", "daisyui": "^2.31.0", "moment": "^2.29.4", @@ -35,7 +35,7 @@ "postcss": "^8.4.16", "tailwindcss": "^3.1.8", "typescript": "^4.6.2", - "zenstack": "^0.2.9" + "zenstack": "^0.2.10" } }, "node_modules/@babel/code-frame": { @@ -722,9 +722,9 @@ } }, "node_modules/@zenstackhq/internal": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@zenstackhq/internal/-/internal-0.2.9.tgz", - "integrity": "sha512-Hq+JfXZ9s0v9m085V53kSwlLcZXlNMktuU4DHjiIlPFkTBssYZXphg0FxKHEhfA+FQct1vwDagIAB0UsZyYScg==", + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@zenstackhq/internal/-/internal-0.2.10.tgz", + "integrity": "sha512-w7yqWrbB+y2QVkKbEJmBtklIQ4gtK0LjzzGxph7ZHIQHP6E1nWFuqwweu4ALdkbufA9pGoxmoTJ0LZ5H1zpF/Q==", "dependencies": { "bcryptjs": "^2.4.3", "colors": "^1.4.0", @@ -740,9 +740,9 @@ } }, "node_modules/@zenstackhq/runtime": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@zenstackhq/runtime/-/runtime-0.2.9.tgz", - "integrity": "sha512-l2DqjAqKQe4bCyu0mta1WKtDKNE4/VH51n4UfOTy6xCTSqmTTqTRdEqWypC2u52yMzrRb8re5c749HN8B0OL7A==", + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@zenstackhq/runtime/-/runtime-0.2.10.tgz", + "integrity": "sha512-Xk2BALRdXXUZC7XmlqaD3oH+fp8ix3sSbYjc+mxfNIkZK67am6QkGF+4ggnKZwWi1BDHXP75+mtAHbWcJkEEOw==", "dependencies": { "@zenstackhq/internal": "latest" }, @@ -4520,12 +4520,12 @@ } }, "node_modules/zenstack": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/zenstack/-/zenstack-0.2.9.tgz", - "integrity": "sha512-qLEM04i5T2rByrgCf8AWgc1LvBa4f3+IsxxBK+DtwiRaNPfYaZB7Z7Nck1vLHlu8S2eas/Sxm+DmeCiX5NlsyA==", + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/zenstack/-/zenstack-0.2.10.tgz", + "integrity": "sha512-AsIP25k0qV/u7AegDrG38TbzOFIeccU1RIT9XDr4ae7c05RwD9+dniIgjNxO1AzvqZWl+hYQH7/ZGrMEcXQ0Mw==", "dev": true, "dependencies": { - "@zenstackhq/internal": "0.2.9", + "@zenstackhq/internal": "0.2.10", "change-case": "^4.1.2", "chevrotain": "^9.1.0", "colors": "^1.4.0", @@ -5017,9 +5017,9 @@ } }, "@zenstackhq/internal": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@zenstackhq/internal/-/internal-0.2.9.tgz", - "integrity": "sha512-Hq+JfXZ9s0v9m085V53kSwlLcZXlNMktuU4DHjiIlPFkTBssYZXphg0FxKHEhfA+FQct1vwDagIAB0UsZyYScg==", + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@zenstackhq/internal/-/internal-0.2.10.tgz", + "integrity": "sha512-w7yqWrbB+y2QVkKbEJmBtklIQ4gtK0LjzzGxph7ZHIQHP6E1nWFuqwweu4ALdkbufA9pGoxmoTJ0LZ5H1zpF/Q==", "requires": { "bcryptjs": "^2.4.3", "colors": "^1.4.0", @@ -5029,9 +5029,9 @@ } }, "@zenstackhq/runtime": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@zenstackhq/runtime/-/runtime-0.2.9.tgz", - "integrity": "sha512-l2DqjAqKQe4bCyu0mta1WKtDKNE4/VH51n4UfOTy6xCTSqmTTqTRdEqWypC2u52yMzrRb8re5c749HN8B0OL7A==", + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@zenstackhq/runtime/-/runtime-0.2.10.tgz", + "integrity": "sha512-Xk2BALRdXXUZC7XmlqaD3oH+fp8ix3sSbYjc+mxfNIkZK67am6QkGF+4ggnKZwWi1BDHXP75+mtAHbWcJkEEOw==", "requires": { "@zenstackhq/internal": "latest" } @@ -7766,12 +7766,12 @@ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" }, "zenstack": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/zenstack/-/zenstack-0.2.9.tgz", - "integrity": "sha512-qLEM04i5T2rByrgCf8AWgc1LvBa4f3+IsxxBK+DtwiRaNPfYaZB7Z7Nck1vLHlu8S2eas/Sxm+DmeCiX5NlsyA==", + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/zenstack/-/zenstack-0.2.10.tgz", + "integrity": "sha512-AsIP25k0qV/u7AegDrG38TbzOFIeccU1RIT9XDr4ae7c05RwD9+dniIgjNxO1AzvqZWl+hYQH7/ZGrMEcXQ0Mw==", "dev": true, "requires": { - "@zenstackhq/internal": "0.2.9", + "@zenstackhq/internal": "0.2.10", "change-case": "^4.1.2", "chevrotain": "^9.1.0", "colors": "^1.4.0", diff --git a/samples/todo/package.json b/samples/todo/package.json index 16d1f3739..62e2a17e4 100644 --- a/samples/todo/package.json +++ b/samples/todo/package.json @@ -1,6 +1,6 @@ { "name": "todo", - "version": "0.2.9", + "version": "0.2.10", "private": true, "scripts": { "dev": "next dev", @@ -17,8 +17,8 @@ "dependencies": { "@heroicons/react": "^2.0.12", "@prisma/client": "^4.4.0", - "@zenstackhq/internal": "^0.2.9", - "@zenstackhq/runtime": "^0.2.9", + "@zenstackhq/internal": "^0.2.10", + "@zenstackhq/runtime": "^0.2.10", "bcryptjs": "^2.4.3", "daisyui": "^2.31.0", "moment": "^2.29.4", @@ -42,6 +42,6 @@ "postcss": "^8.4.16", "tailwindcss": "^3.1.8", "typescript": "^4.6.2", - "zenstack": "^0.2.9" + "zenstack": "^0.2.10" } } diff --git a/tests/integration/tests/todo-e2e.test.ts b/tests/integration/tests/todo-e2e.test.ts index d7ffbb001..c19d821da 100644 --- a/tests/integration/tests/todo-e2e.test.ts +++ b/tests/integration/tests/todo-e2e.test.ts @@ -298,6 +298,26 @@ describe('Todo E2E Tests', () => { await list1CredClientUser1.get('/').expect(404); }); + it('todo list with empty user id', async () => { + await createSpaceAndUsers(); + + await makeClient('/api/data/List', user1.id) + .post('/') + .send({ + data: { + id: 'list1', + title: 'List 1', + owner: { connect: { id: user1.id } }, + space: { connect: { id: space1.id } }, + }, + }) + .expect(201); + + await makeClient('/api/data/List', '') + .get('/') + .expect((resp) => expect(resp.body).toHaveLength(0)); + }); + it('todo', async () => { await createSpaceAndUsers(); diff --git a/tests/integration/tests/utils.ts b/tests/integration/tests/utils.ts index b9b20d760..825e8a3b8 100644 --- a/tests/integration/tests/utils.ts +++ b/tests/integration/tests/utils.ts @@ -52,7 +52,10 @@ export async function setup(schemaFile: string) { const options: RequestHandlerOptions = { async getServerUser(req: NextApiRequest, res: NextApiResponse) { - if (req.cookies.userId) { + if (req.cookies.userId === '') { + // simulate "undefined" user id + return {} as { id: string}; + } else if (req.cookies.userId) { return { id: req.cookies.userId }; } else { return undefined; @@ -108,7 +111,7 @@ export function makeClient(apiPath: string, userId?: string, queryArgs?: any) { prop: string | symbol, receiver: any ) { - if (!userId) { + if (userId === undefined) { return Reflect.get(target, prop, receiver); } @@ -119,6 +122,7 @@ export function makeClient(apiPath: string, userId?: string, queryArgs?: any) { case 'del': case 'delete': return (url: string) => { + // use userId cookie to simulate a logged in user return target[prop](url).set('Cookie', [ `userId=${userId}`, ]);