Skip to content

Commit c76ae24

Browse files
authored
Merge pull request #137 from zenstackhq/dev
merge dev to main (v3.0.0-alpha.17)
2 parents 94a0c6f + aeffd32 commit c76ae24

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+572
-117
lines changed

README.md

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ npm install -D @types/pg
118118
Run the following command to sync schema to the database for local development:
119119

120120
```bash
121-
npx zenstack db push
121+
npx zen db push
122122
```
123123

124124
> Under the hood, the command uses `prisma db push` to do the job.
@@ -127,17 +127,17 @@ See [database migration](#database-migration) for how to use migration to manage
127127

128128
## Compiling ZModel schema
129129

130-
ZModel needs to be compiled to TypeScript before being used to create a database client. Simply run the following command:
130+
ZModel needs to be compiled to TypeScript before being used to create a database db. Simply run the following command:
131131

132132
```bash
133-
npx zenstack generate
133+
npx zen generate
134134
```
135135

136136
A `schema.ts` file will be created inside the `zenstack` folder. The file should be included as part of your source tree for compilation/bundling. You may choose to include or ignore it in source control (and generate on the fly during build). Just remember to rerun the "generate" command whenever you make changes to the ZModel schema.
137137

138138
## Creating ZenStack client
139139

140-
Now you can use the compiled TypeScript schema to instantiate a database client.
140+
Now you can use the compiled TypeScript schema to instantiate a database db.
141141

142142
### SQLite
143143

@@ -147,7 +147,7 @@ import { schema } from './zenstack/schema';
147147
import SQLite from 'better-sqlite3';
148148
import { SqliteDialect } from 'kysely';
149149

150-
const client = new ZenStackClient(schema, {
150+
const db = new ZenStackClient(schema, {
151151
dialect: new SqliteDialect({ database: new SQLite('./dev.db') }),
152152
});
153153
```
@@ -159,11 +159,10 @@ import { ZenStackClient } from '@zenstackhq/runtime';
159159
import { schema } from './zenstack/schema';
160160
import { PostgresDialect } from 'kysely';
161161
import { Pool } from 'pg';
162-
import { parseIntoClientConfig } from 'pg-connection-string';
163162

164-
const client = new ZenStackClient(schema, {
163+
const db = new ZenStackClient(schema, {
165164
dialect: new PostgresDialect({
166-
pool: new Pool(parseIntoClientConfig(process.env.DATABASE_URL)),
165+
pool: new Pool({ connectionString: process.env.DATABASE_URL }),
167166
}),
168167
});
169168
```
@@ -177,20 +176,20 @@ const client = new ZenStackClient(schema, {
177176
A few quick examples:
178177

179178
```ts
180-
const user = await client.user.create({
179+
const user = await db.user.create({
181180
data: {
182181
name: 'Alex',
183182
184183
posts: { create: { title: 'Hello world' } },
185184
},
186185
});
187186

188-
const userWithPosts = await client.user.findUnique({
187+
const userWithPosts = await db.user.findUnique({
189188
where: { id: user.id },
190189
include: { posts: true },
191190
});
192191

193-
const groupedPosts = await client.post.groupBy({
192+
const groupedPosts = await db.post.groupBy({
194193
by: 'published',
195194
_count: true,
196195
});
@@ -205,7 +204,7 @@ ZenStack uses Kysely to handle database operations, and it also directly exposes
205204
Please check [Kysely documentation](https://kysely.dev/docs/intro) for more details. Here're a few quick examples:
206205

207206
```ts
208-
await client.$qb
207+
await db.$qb
209208
.selectFrom('User')
210209
.leftJoin('Post', 'Post.authorId', 'User.id')
211210
.select(['User.id', 'User.email', 'Post.title'])
@@ -215,7 +214,7 @@ await client.$qb
215214
Query builder can also be "blended" into ORM API calls as a local escape hatch for building complex filter conditions. It allows for greater flexibility without forcing you to entirely resort to the query builder API.
216215

217216
```ts
218-
await client.user.findMany({
217+
await db.user.findMany({
219218
where: {
220219
age: { gt: 18 },
221220
// "eb" is a Kysely expression builder
@@ -243,7 +242,7 @@ ZenStack v3 allows you to define database-evaluated computed fields with the fol
243242
2. Provide its implementation using query builder when constructing `ZenStackClient`
244243
245244
```ts
246-
const client = new ZenStackClient(schema, {
245+
const db = new ZenStackClient(schema, {
247246
...
248247
computedFields: {
249248
User: {
@@ -279,7 +278,7 @@ _Coming soon..._
279278
280279
### Runtime plugins
281280
282-
V3 introduces a new runtime plugin mechanism that allows you to tap into the ORM's query execution in various ways. A plugin implements the [RuntimePlugin](./packages/runtime/src/client/plugin.ts#L121) interface, and can be installed with the `ZenStackClient.$use` API.
281+
V3 introduces a new runtime plugin mechanism that allows you to tap into the ORM's query execution in various ways. A plugin implements the [RuntimePlugin](./packages/runtime/src/client/plugin.ts#L121) interface, and can be installed with the `ZenStackdb.$use` API.
283282
284283
You can use a plugin to achieve the following goals:
285284
@@ -288,7 +287,7 @@ You can use a plugin to achieve the following goals:
288287
ORM query interception allows you to intercept the high-level ORM API calls. The interceptor's configuration is compatible with Prisma's [query client extension](https://www.prisma.io/docs/orm/prisma-client/client-extensions/query).
289288
290289
```ts
291-
client.$use({
290+
db.$use({
292291
id: 'cost-logger',
293292
onQuery: {
294293
$allModels: {
@@ -312,7 +311,7 @@ Kysely query interception allows you to intercept the low-level query builder AP
312311
Kysely query interception works against the low-level Kysely `OperationNode` structures. It's harder to implement but can guarantee intercepting all CRUD operations.
313312

314313
```ts
315-
client.$use({
314+
db.$use({
316315
id: 'insert-interception-plugin',
317316
onKyselyQuery({query, proceed}) {
318317
if (query.kind === 'InsertQueryNode') {
@@ -332,7 +331,7 @@ function sanitizeInsertData(query: InsertQueryNode) {
332331
Another popular interception use case is, instead of intercepting calls, "listening on" entity changes.
333332

334333
```ts
335-
client.$use({
334+
db.$use({
336335
id: 'mutation-hook-plugin',
337336
beforeEntityMutation({ model, action }) {
338337
console.log(`Before ${model} ${action}`);
@@ -346,7 +345,7 @@ client.$use({
346345
You can provide an extra `mutationInterceptionFilter` to control what to intercept, and opt in for loading the affected entities before and/or after the mutation.
347346

348347
```ts
349-
client.$use({
348+
db.$use({
350349
id: 'mutation-hook-plugin',
351350
mutationInterceptionFilter: ({ model }) => {
352351
return {
@@ -375,19 +374,19 @@ ZenStack v3 delegates database schema migration to Prisma. The CLI provides Pris
375374
- Sync schema to dev database and create a migration record:
376375

377376
```bash
378-
npx zenstack migrate dev
377+
npx zen migrate dev
379378
```
380379

381380
- Deploy new migrations:
382381

383382
```bash
384-
npx zenstack migrate deploy
383+
npx zen migrate deploy
385384
```
386385

387386
- Reset dev database
388387

389388
```bash
390-
npx zenstack migrate reset
389+
npx zen migrate reset
391390
```
392391

393392
See [Prisma Migrate](https://www.prisma.io/docs/orm/prisma-migrate) documentation for more details.
@@ -398,7 +397,7 @@ See [Prisma Migrate](https://www.prisma.io/docs/orm/prisma-migrate) documentatio
398397
1. Remove "@prisma/client" dependency
399398
1. Install "better-sqlite3" or "pg" based on database type
400399
1. Move "schema.prisma" to "zenstack" folder and rename it to "schema.zmodel"
401-
1. Run `npx zenstack generate`
400+
1. Run `npx zen generate`
402401
1. Replace `new PrismaClient()` with `new ZenStackClient(schema, { ... })`
403402
404403
# Limitations

TODO.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
- [x] validate
1111
- [ ] format
1212
- [ ] db seed
13+
- [ ] plugin mechanism
14+
- [ ] built-in plugins
15+
- [ ] ts
16+
- [ ] prisma
1317
- [ ] ZModel
1418
- [ ] Import
1519
- [ ] View support
@@ -73,6 +77,7 @@
7377
- [x] Compound ID
7478
- [ ] Cross field comparison
7579
- [x] Many-to-many relation
80+
- [ ] Self relation
7681
- [ ] Empty AND/OR/NOT behavior
7782
- [x] Logging
7883
- [x] Error system

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "zenstack-v3",
3-
"version": "3.0.0-alpha.16",
3+
"version": "3.0.0-alpha.17",
44
"description": "ZenStack",
55
"packageManager": "[email protected]",
66
"scripts": {

packages/cli/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"publisher": "zenstack",
44
"displayName": "ZenStack CLI",
55
"description": "FullStack database toolkit with built-in access control and automatic API generation.",
6-
"version": "3.0.0-alpha.16",
6+
"version": "3.0.0-alpha.17",
77
"type": "module",
88
"author": {
99
"name": "ZenStack Team"
@@ -49,6 +49,7 @@
4949
"@zenstackhq/runtime": "workspace:*",
5050
"@zenstackhq/testtools": "workspace:*",
5151
"@zenstackhq/typescript-config": "workspace:*",
52+
"@zenstackhq/vitest-config": "workspace:*",
5253
"better-sqlite3": "^11.8.1",
5354
"tmp": "catalog:"
5455
}

packages/cli/src/actions/action-utils.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,10 @@ export function getSchemaFile(file?: string) {
3636
export async function loadSchemaDocument(schemaFile: string) {
3737
const loadResult = await loadDocument(schemaFile);
3838
if (!loadResult.success) {
39-
console.error(colors.red('Error loading schema:'));
4039
loadResult.errors.forEach((err) => {
4140
console.error(colors.red(err));
4241
});
43-
throw new CliError('Failed to load schema');
42+
throw new CliError('Schema contains errors. See above for details.');
4443
}
4544
loadResult.warnings.forEach((warn) => {
4645
console.warn(colors.yellow(warn));

packages/cli/src/actions/generate.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@ import { schema } from '${outputPath}/schema';
5252
const client = new ZenStackClient(schema, {
5353
dialect: { ... }
5454
});
55-
\`\`\`
56-
`);
55+
\`\`\``);
5756
}
5857
}
5958

packages/cli/src/index.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { ZModelLanguageMetaData } from '@zenstackhq/language';
22
import colors from 'colors';
3-
import { Command, Option } from 'commander';
3+
import { Command, CommanderError, Option } from 'commander';
44
import * as actions from './actions';
5+
import { CliError } from './cli-error';
56
import { getVersion } from './utils/version-utils';
67

78
const generateAction = async (options: Parameters<typeof actions.generate>[0]): Promise<void> => {
@@ -125,4 +126,17 @@ export function createProgram() {
125126
}
126127

127128
const program = createProgram();
128-
program.parse(process.argv);
129+
130+
program.parseAsync().catch((err) => {
131+
if (err instanceof CliError) {
132+
console.error(colors.red(err.message));
133+
process.exit(1);
134+
} else if (err instanceof CommanderError) {
135+
// errors are already reported, just exit
136+
process.exit(err.exitCode);
137+
} else {
138+
console.error(colors.red('An unexpected error occurred:'));
139+
console.error(err);
140+
process.exit(1);
141+
}
142+
});

packages/cli/vitest.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1+
import base from '@zenstackhq/vitest-config/base';
12
import { defineConfig, mergeConfig } from 'vitest/config';
2-
import base from '../../vitest.base.config';
33

44
export default mergeConfig(base, defineConfig({}));

packages/common-helpers/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@zenstackhq/common-helpers",
3-
"version": "3.0.0-alpha.16",
3+
"version": "3.0.0-alpha.17",
44
"description": "ZenStack Common Helpers",
55
"type": "module",
66
"scripts": {

packages/create-zenstack/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "create-zenstack",
3-
"version": "3.0.0-alpha.16",
3+
"version": "3.0.0-alpha.17",
44
"description": "Create a new ZenStack project",
55
"type": "module",
66
"scripts": {

0 commit comments

Comments
 (0)