Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,10 @@ Now you can use the compiled TypeScript schema to instantiate a database client.
import { ZenStackClient } from '@zenstackhq/runtime';
import { schema } from './zenstack/schema';
import SQLite from 'better-sqlite3';
import { SqliteDialect } from 'kysely';

const client = new ZenStackClient(schema, {
dialectConfig: { database: new SQLite('./dev.db') },
dialect: new SqliteDialect({ database: new SQLite('./dev.db') }),
});
```

Expand All @@ -156,13 +157,14 @@ const client = new ZenStackClient(schema, {
```ts
import { ZenStackClient } from '@zenstackhq/runtime';
import { schema } from './zenstack/schema';
import { PostgresDialect } from 'kysely';
import { Pool } from 'pg';
import { parseIntoClientConfig } from 'pg-connection-string';

const client = new ZenStackClient(schema, {
dialectConfig: {
dialect: new PostgresDialect({
pool: new Pool(parseIntoClientConfig(process.env.DATABASE_URL)),
},
}),
});
```

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "zenstack-v3",
"version": "3.0.0-alpha.15",
"version": "3.0.0-alpha.16",
"description": "ZenStack",
"packageManager": "pnpm@10.12.1",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"publisher": "zenstack",
"displayName": "ZenStack CLI",
"description": "FullStack database toolkit with built-in access control and automatic API generation.",
"version": "3.0.0-alpha.15",
"version": "3.0.0-alpha.16",
"type": "module",
"author": {
"name": "ZenStack Team"
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/actions/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ import { ZenStackClient } from '@zenstackhq/runtime';
import { schema } from '${outputPath}/schema';

const client = new ZenStackClient(schema, {
dialectConfig: { ... }
dialect: { ... }
});
\`\`\`
`);
Expand Down
7 changes: 4 additions & 3 deletions packages/cli/src/actions/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,15 @@ model Post {
`;

export const STARTER_MAIN_TS = `import { ZenStackClient } from '@zenstackhq/runtime';
import { schema } from './zenstack/schema';
import SQLite from 'better-sqlite3';
import { SqliteDialect } from 'kysely';
import { schema } from './zenstack/schema';

async function main() {
const client = new ZenStackClient(schema, {
dialectConfig: {
dialect: new SqliteDialect({
database: new SQLite('./zenstack/dev.db'),
},
}),
});
const user = await client.user.create({
data: {
Expand Down
2 changes: 1 addition & 1 deletion packages/common-helpers/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/common-helpers",
"version": "3.0.0-alpha.15",
"version": "3.0.0-alpha.16",
"description": "ZenStack Common Helpers",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/create-zenstack/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "create-zenstack",
"version": "3.0.0-alpha.15",
"version": "3.0.0-alpha.16",
"description": "Create a new ZenStack project",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-config/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/eslint-config",
"version": "3.0.0-alpha.15",
"version": "3.0.0-alpha.16",
"type": "module",
"private": true,
"license": "MIT"
Expand Down
2 changes: 1 addition & 1 deletion packages/ide/vscode/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "zenstack",
"publisher": "zenstack",
"version": "3.0.0-alpha.15",
"version": "3.0.0-alpha.16",
"displayName": "ZenStack Language Tools",
"description": "VSCode extension for ZenStack ZModel language",
"private": true,
Expand Down
2 changes: 1 addition & 1 deletion packages/language/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/language",
"description": "ZenStack ZModel language specification",
"version": "3.0.0-alpha.15",
"version": "3.0.0-alpha.16",
"license": "MIT",
"author": "ZenStack Team",
"files": [
Expand Down
4 changes: 2 additions & 2 deletions packages/runtime/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/runtime",
"version": "3.0.0-alpha.15",
"version": "3.0.0-alpha.16",
"description": "ZenStack Runtime",
"type": "module",
"scripts": {
Expand Down Expand Up @@ -69,14 +69,14 @@
"@paralleldrive/cuid2": "^2.2.2",
"decimal.js": "^10.4.3",
"json-stable-stringify": "^1.3.0",
"kysely": "catalog:",
"nanoid": "^5.0.9",
"ts-pattern": "catalog:",
"ulid": "^3.0.0",
"uuid": "^11.0.5"
},
"peerDependencies": {
"better-sqlite3": "^11.8.1",
"kysely": "catalog:",
"pg": "^8.13.1",
"zod": "catalog:"
},
Expand Down
32 changes: 6 additions & 26 deletions packages/runtime/src/client/client-impl.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import { invariant, lowerCaseFirst } from '@zenstackhq/common-helpers';
import type { QueryExecutor, SqliteDialectConfig } from 'kysely';
import type { QueryExecutor } from 'kysely';
import {
CompiledQuery,
DefaultConnectionProvider,
DefaultQueryExecutor,
Kysely,
Log,
PostgresDialect,
sql,
SqliteDialect,
type KyselyProps,
type PostgresDialectConfig,
} from 'kysely';
import { match } from 'ts-pattern';
import type { GetModels, ProcedureDef, SchemaDef } from '../schema';
import type { AuthType } from '../schema/auth';
import type { UnwrapTuplePromises } from '../utils/type-utils';
Expand Down Expand Up @@ -88,18 +84,17 @@ export class ClientImpl<Schema extends SchemaDef> {
this.kyselyRaw = baseClient.kyselyRaw;
this.auth = baseClient.auth;
} else {
const dialect = this.getKyselyDialect();
const driver = new ZenStackDriver(dialect.createDriver(), new Log(this.$options.log ?? []));
const compiler = dialect.createQueryCompiler();
const adapter = dialect.createAdapter();
const driver = new ZenStackDriver(options.dialect.createDriver(), new Log(this.$options.log ?? []));
const compiler = options.dialect.createQueryCompiler();
const adapter = options.dialect.createAdapter();
const connectionProvider = new DefaultConnectionProvider(driver);

this.kyselyProps = {
config: {
dialect,
dialect: options.dialect,
log: this.$options.log,
},
dialect,
dialect: options.dialect,
driver,
executor: executor ?? new ZenStackQueryExecutor(this, driver, compiler, adapter, connectionProvider),
};
Expand Down Expand Up @@ -135,21 +130,6 @@ export class ClientImpl<Schema extends SchemaDef> {
return new ClientImpl(this.schema, this.$options, this, executor);
}

private getKyselyDialect() {
return match(this.schema.provider.type)
.with('sqlite', () => this.makeSqliteKyselyDialect())
.with('postgresql', () => this.makePostgresKyselyDialect())
.exhaustive();
}

private makePostgresKyselyDialect(): PostgresDialect {
return new PostgresDialect(this.options.dialectConfig as PostgresDialectConfig);
}

private makeSqliteKyselyDialect(): SqliteDialect {
return new SqliteDialect(this.options.dialectConfig as SqliteDialectConfig);
}

// overload for interactive transaction
$transaction<T>(
callback: (tx: ClientContract<Schema>) => Promise<T>,
Expand Down
16 changes: 5 additions & 11 deletions packages/runtime/src/client/options.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
import type { Expression, ExpressionBuilder, KyselyConfig, PostgresDialectConfig, SqliteDialectConfig } from 'kysely';
import type { DataSourceProvider, GetModel, GetModels, ProcedureDef, SchemaDef } from '../schema';
import type { Optional, PrependParameter } from '../utils/type-utils';
import type { Dialect, Expression, ExpressionBuilder, KyselyConfig } from 'kysely';
import type { GetModel, GetModels, ProcedureDef, SchemaDef } from '../schema';
import type { PrependParameter } from '../utils/type-utils';
import type { ClientContract, CRUD, ProcedureFunc } from './contract';
import type { BaseCrudDialect } from './crud/dialects/base';
import type { RuntimePlugin } from './plugin';
import type { ToKyselySchema } from './query-builder';

type DialectConfig<Provider extends DataSourceProvider> = Provider['type'] extends 'sqlite'
? Optional<SqliteDialectConfig, 'database'>
: Provider['type'] extends 'postgresql'
? Optional<PostgresDialectConfig, 'pool'>
: never;

export type ZModelFunctionContext<Schema extends SchemaDef> = {
dialect: BaseCrudDialect<Schema>;
model: GetModels<Schema>;
Expand All @@ -29,9 +23,9 @@ export type ZModelFunction<Schema extends SchemaDef> = (
*/
export type ClientOptions<Schema extends SchemaDef> = {
/**
* Database dialect configuration.
* Kysely dialect.
*/
dialectConfig: DialectConfig<Schema['provider']>;
dialect: Dialect;

/**
* Custom function definitions.
Expand Down
4 changes: 2 additions & 2 deletions packages/runtime/test/client-api/computed-fields.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ import { schema } from './schema';

async function main() {
const client = new ZenStackClient(schema, {
dialectConfig: {} as any,
dialect: {} as any,
computedFields: {
User: {
upperName: (eb) => eb.fn('upper', ['name']),
Expand Down Expand Up @@ -122,7 +122,7 @@ import { schema } from './schema';

async function main() {
const client = new ZenStackClient(schema, {
dialectConfig: {} as any,
dialect: {} as any,
computedFields: {
User: {
upperName: (eb) => eb.lit(null),
Expand Down
3 changes: 2 additions & 1 deletion packages/runtime/test/client-api/default-values.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { isCuid } from '@paralleldrive/cuid2';
import SQLite from 'better-sqlite3';
import { SqliteDialect } from 'kysely';
import { isValid as isValidUlid } from 'ulid';
import { validate as isValidUuid } from 'uuid';
import { describe, expect, it } from 'vitest';
Expand Down Expand Up @@ -68,7 +69,7 @@ const schema = {
describe('default values tests', () => {
it('supports generators', async () => {
const client = new ZenStackClient(schema, {
dialectConfig: { database: new SQLite(':memory:') },
dialect: new SqliteDialect({ database: new SQLite(':memory:') }),
});
await client.$pushSchema();

Expand Down
5 changes: 3 additions & 2 deletions packages/runtime/test/client-api/name-mapping.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import SQLite from 'better-sqlite3';
import { SqliteDialect } from 'kysely';
import { describe, expect, it } from 'vitest';
import { ZenStackClient } from '../../src';
import { type SchemaDef, ExpressionUtils } from '../../src/schema';
Expand Down Expand Up @@ -59,7 +60,7 @@ describe('Name mapping tests', () => {

it('works with model and implicit field mapping', async () => {
const client = new ZenStackClient(schema, {
dialectConfig: { database: new SQLite(':memory:') },
dialect: new SqliteDialect({ database: new SQLite(':memory:') }),
});
await client.$pushSchema();
const r1 = await client.foo.create({
Expand Down Expand Up @@ -91,7 +92,7 @@ describe('Name mapping tests', () => {

it('works with explicit field mapping', async () => {
const client = new ZenStackClient(schema, {
dialectConfig: { database: new SQLite(':memory:') },
dialect: new SqliteDialect({ database: new SQLite(':memory:') }),
});
await client.$pushSchema();
const r1 = await client.foo.create({
Expand Down
4 changes: 2 additions & 2 deletions packages/runtime/test/plugin/kysely-on-query.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import SQLite from 'better-sqlite3';
import { InsertQueryNode, Kysely, PrimitiveValueListNode, ValuesNode, type QueryResult } from 'kysely';
import { InsertQueryNode, Kysely, PrimitiveValueListNode, SqliteDialect, ValuesNode, type QueryResult } from 'kysely';
import { beforeEach, describe, expect, it } from 'vitest';
import { ZenStackClient, type ClientContract } from '../../src/client';
import { schema } from '../schemas/basic';
Expand All @@ -9,7 +9,7 @@ describe('Kysely onQuery tests', () => {

beforeEach(async () => {
_client = new ZenStackClient(schema, {
dialectConfig: { database: new SQLite(':memory:') },
dialect: new SqliteDialect({ database: new SQLite(':memory:') }),
});
await _client.$pushSchema();
});
Expand Down
6 changes: 2 additions & 4 deletions packages/runtime/test/plugin/mutation-hooks.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import SQLite from 'better-sqlite3';
import { DeleteQueryNode, InsertQueryNode, UpdateQueryNode } from 'kysely';
import { DeleteQueryNode, InsertQueryNode, SqliteDialect, UpdateQueryNode } from 'kysely';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { ZenStackClient, type ClientContract } from '../../src';
import { schema } from '../schemas/basic';
Expand All @@ -9,9 +9,7 @@ describe('Entity lifecycle tests', () => {

beforeEach(async () => {
_client = new ZenStackClient(schema, {
dialectConfig: {
database: new SQLite(':memory:'),
},
dialect: new SqliteDialect({ database: new SQLite(':memory:') }),
});
await _client.$pushSchema();
});
Expand Down
5 changes: 2 additions & 3 deletions packages/runtime/test/plugin/query-lifecycle.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import SQLite from 'better-sqlite3';
import { SqliteDialect } from 'kysely';
import { beforeEach, describe, expect, it } from 'vitest';
import { definePlugin, ZenStackClient, type ClientContract } from '../../src/client';
import { schema } from '../schemas/basic';
Expand All @@ -8,9 +9,7 @@ describe('Query interception tests', () => {

beforeEach(async () => {
_client = new ZenStackClient(schema, {
dialectConfig: {
database: new SQLite(':memory:'),
},
dialect: new SqliteDialect({ database: new SQLite(':memory:') }),
});
await _client.$pushSchema();
});
Expand Down
5 changes: 2 additions & 3 deletions packages/runtime/test/query-builder/query-builder.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createId } from '@paralleldrive/cuid2';
import SQLite from 'better-sqlite3';
import { SqliteDialect } from 'kysely';
import { describe, expect, it } from 'vitest';
import { ZenStackClient } from '../../src';
import { getSchema } from '../schemas/basic';
Expand All @@ -9,9 +10,7 @@ describe('Client API tests', () => {

it('works with queries', async () => {
const client = new ZenStackClient(schema, {
dialectConfig: {
database: new SQLite(':memory:'),
},
dialect: new SqliteDialect({ database: new SQLite(':memory:') }),
});
await client.$pushSchema();

Expand Down
5 changes: 2 additions & 3 deletions packages/runtime/test/schemas/delegate/typecheck.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import SQLite from 'better-sqlite3';
import { SqliteDialect } from 'kysely';
import { ZenStackClient } from '../../../dist';
import { schema } from './schema';

const client = new ZenStackClient(schema, {
dialectConfig: {
database: new SQLite('./zenstack/test.db'),
},
dialect: new SqliteDialect({ database: new SQLite('./zenstack/test.db') }),
});

async function find() {
Expand Down
5 changes: 2 additions & 3 deletions packages/runtime/test/schemas/typing/typecheck.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import SQLite from 'better-sqlite3';
import { SqliteDialect } from 'kysely';
import { ZenStackClient } from '../../../dist';
import { Role, type Identity, type IdentityProvider } from './models';
import { schema } from './schema';

const client = new ZenStackClient(schema, {
dialectConfig: {
database: new SQLite('./zenstack/test.db'),
},
dialect: new SqliteDialect({ database: new SQLite('./zenstack/test.db') }),
computedFields: {
User: {
postCount: (eb) =>
Expand Down
Loading