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
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-beta.31",
"version": "3.0.0-beta.32",
"description": "ZenStack",
"packageManager": "[email protected]",
"type": "module",
Expand Down
2 changes: 1 addition & 1 deletion packages/auth-adapters/better-auth/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/better-auth",
"version": "3.0.0-beta.31",
"version": "3.0.0-beta.32",
"description": "ZenStack Better Auth Adapter. This adapter is modified from better-auth's Prisma adapter.",
"type": "module",
"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-beta.31",
"version": "3.0.0-beta.32",
"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 @@ -36,7 +36,7 @@ export async function run(options: Options) {

\`\`\`ts
import { ZenStackClient } from '@zenstackhq/orm';
import { schema } from '${outputPath}/schema';
import { schema } from '${path.relative('.', outputPath)}/schema';

const client = new ZenStackClient(schema, {
dialect: { ... }
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/actions/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ model Post {
title String @length(1, 256)
content String
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
authorId String
}
`;
Expand Down
2 changes: 1 addition & 1 deletion packages/clients/tanstack-query/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/tanstack-query",
"version": "3.0.0-beta.31",
"version": "3.0.0-beta.32",
"description": "TanStack Query Client for consuming ZenStack v3's CRUD service",
"main": "index.js",
"type": "module",
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-beta.31",
"version": "3.0.0-beta.32",
"description": "ZenStack Common Helpers",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/config/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-beta.31",
"version": "3.0.0-beta.32",
"type": "module",
"private": true,
"license": "MIT"
Expand Down
2 changes: 1 addition & 1 deletion packages/config/typescript-config/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/typescript-config",
"version": "3.0.0-beta.31",
"version": "3.0.0-beta.32",
"private": true,
"license": "MIT"
}
2 changes: 1 addition & 1 deletion packages/config/vitest-config/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/vitest-config",
"type": "module",
"version": "3.0.0-beta.31",
"version": "3.0.0-beta.32",
"private": true,
"license": "MIT",
"exports": {
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-beta.31",
"version": "3.0.0-beta.32",
"description": "Create a new ZenStack project",
"type": "module",
"scripts": {
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-v3",
"publisher": "zenstack",
"version": "3.0.14",
"version": "3.0.15",
"displayName": "ZenStack V3 Language Tools",
"description": "VSCode extension for ZenStack (v3) 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-beta.31",
"version": "3.0.0-beta.32",
"license": "MIT",
"author": "ZenStack Team",
"files": [
Expand Down
2 changes: 1 addition & 1 deletion packages/orm/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/orm",
"version": "3.0.0-beta.31",
"version": "3.0.0-beta.32",
"description": "ZenStack ORM",
"type": "module",
"scripts": {
Expand Down
99 changes: 36 additions & 63 deletions packages/orm/src/client/crud-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,50 +139,34 @@ type ModelSelectResult<
Options extends QueryOptions<Schema>,
> = {
[Key in keyof Select as Select[Key] extends false | undefined
? never
: Key extends keyof Omit
? Omit[Key] extends true
? never
: Key
: Key extends '_count'
? Select[Key] extends SelectCount<Schema, Model>
? Key
: never
? // not selected
never
: Key extends '_count'
? // select "_count"
Select[Key] extends SelectCount<Schema, Model>
? Key
: never
: Key extends keyof Omit
? Omit[Key] extends true
? // omit
never
: Key
: Key]: Key extends '_count'
? SelectCountResult<Schema, Model, Select[Key]>
? // select "_count" result
SelectCountResult<Schema, Model, Select[Key]>
: Key extends NonRelationFields<Schema, Model>
? MapModelFieldType<Schema, Model, Key>
? // scalar field result
MapModelFieldType<Schema, Model, Key>
: Key extends RelationFields<Schema, Model>
? Select[Key] extends FindArgs<
? // relation field result (recurse)
ModelResult<
Schema,
RelationFieldType<Schema, Model, Key>,
Select[Key],
Options,
ModelFieldIsOptional<Schema, Model, Key>,
FieldIsArray<Schema, Model, Key>
>
? 'select' extends keyof Select[Key]
? ModelResult<
Schema,
RelationFieldType<Schema, Model, Key>,
Pick<Select[Key], 'select'>,
Options,
ModelFieldIsOptional<Schema, Model, Key>,
FieldIsArray<Schema, Model, Key>
>
: ModelResult<
Schema,
RelationFieldType<Schema, Model, Key>,
Pick<Select[Key], 'include' | 'omit'>,
Options,
ModelFieldIsOptional<Schema, Model, Key>,
FieldIsArray<Schema, Model, Key>
>
: DefaultModelResult<
Schema,
RelationFieldType<Schema, Model, Key>,
Omit,
Options,
ModelFieldIsOptional<Schema, Model, Key>,
FieldIsArray<Schema, Model, Key>
>
: never;
};

Expand All @@ -204,40 +188,29 @@ export type ModelResult<
Array = false,
> = WrapType<
Args extends {
select: infer S;
omit?: infer O;
}
select: infer S extends object;
omit?: infer O extends object;
} & Record<string, unknown>
? ModelSelectResult<Schema, Model, S, O, Options>
: Args extends {
include: infer I;
omit?: infer O;
}
? DefaultModelResult<Schema, Model, O, Options, false, false> & {
include: infer I extends object;
omit?: infer O extends object;
} & Record<string, unknown>
? // select all non-omitted scalar fields
DefaultModelResult<Schema, Model, O, Options, false, false> & {
// recurse for "include" relations
[Key in keyof I & RelationFields<Schema, Model> as I[Key] extends false | undefined
? never
: Key]: I[Key] extends FindArgs<
: Key]: ModelResult<
Schema,
RelationFieldType<Schema, Model, Key>,
I[Key],
Options,
ModelFieldIsOptional<Schema, Model, Key>,
FieldIsArray<Schema, Model, Key>
>
? ModelResult<
Schema,
RelationFieldType<Schema, Model, Key>,
I[Key],
Options,
ModelFieldIsOptional<Schema, Model, Key>,
FieldIsArray<Schema, Model, Key>
>
: DefaultModelResult<
Schema,
RelationFieldType<Schema, Model, Key>,
undefined,
Options,
ModelFieldIsOptional<Schema, Model, Key>,
FieldIsArray<Schema, Model, Key>
>;
>;
}
: Args extends { omit: infer O }
: Args extends { omit: infer O } & Record<string, unknown>
? DefaultModelResult<Schema, Model, O, Options, false, false>
: DefaultModelResult<Schema, Model, undefined, Options, false, false>,
Optional,
Expand Down
12 changes: 8 additions & 4 deletions packages/orm/src/client/query-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,26 +232,30 @@ export function getManyToManyRelation(schema: SchemaDef, model: string, field: s
if (!fieldDef.array || !fieldDef.relation?.opposite) {
return undefined;
}

// in case the m2m relation field is inherited from a delegate base, get the base model
const realModel = fieldDef.originModel ?? model;

const oppositeFieldDef = requireField(schema, fieldDef.type, fieldDef.relation.opposite);
if (oppositeFieldDef.array) {
// Prisma's convention for many-to-many relation:
// - model are sorted alphabetically by name
// - join table is named _<model1>To<model2>, unless an explicit name is provided by `@relation`
// - foreign keys are named A and B (based on the order of the model)
const sortedModelNames = [model, fieldDef.type].sort();
const sortedModelNames = [realModel, fieldDef.type].sort();

let orderedFK: [string, string];
if (model !== fieldDef.type) {
if (realModel !== fieldDef.type) {
// not a self-relation, model name's sort order determines fk order
orderedFK = sortedModelNames[0] === model ? ['A', 'B'] : ['B', 'A'];
orderedFK = sortedModelNames[0] === realModel ? ['A', 'B'] : ['B', 'A'];
} else {
// for self-relations, since model names are identical, relation field name's
// sort order determines fk order
const sortedFieldNames = [field, oppositeFieldDef.name].sort();
orderedFK = sortedFieldNames[0] === field ? ['A', 'B'] : ['B', 'A'];
}

const modelIdFields = requireIdFields(schema, model);
const modelIdFields = requireIdFields(schema, realModel);
invariant(modelIdFields.length === 1, 'Only single-field ID is supported for many-to-many relation');
const otherIdFields = requireIdFields(schema, fieldDef.type);
invariant(otherIdFields.length === 1, 'Only single-field ID is supported for many-to-many relation');
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/policy/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/plugin-policy",
"version": "3.0.0-beta.31",
"version": "3.0.0-beta.32",
"description": "ZenStack Policy Plugin",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/schema/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/schema",
"version": "3.0.0-beta.31",
"version": "3.0.0-beta.32",
"description": "ZenStack Runtime Schema",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/sdk",
"version": "3.0.0-beta.31",
"version": "3.0.0-beta.32",
"description": "ZenStack SDK",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/server/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/server",
"version": "3.0.0-beta.31",
"version": "3.0.0-beta.32",
"description": "ZenStack automatic CRUD API handlers and server adapters",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/testtools/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/testtools",
"version": "3.0.0-beta.31",
"version": "3.0.0-beta.32",
"description": "ZenStack Test Tools",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/zod/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/zod",
"version": "3.0.0-beta.31",
"version": "3.0.0-beta.32",
"description": "",
"type": "module",
"main": "index.js",
Expand Down
2 changes: 1 addition & 1 deletion samples/next.js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "next.js",
"version": "3.0.0-beta.31",
"version": "3.0.0-beta.32",
"private": true,
"scripts": {
"generate": "zen generate --lite",
Expand Down
2 changes: 1 addition & 1 deletion samples/orm/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sample-blog",
"version": "3.0.0-beta.31",
"version": "3.0.0-beta.32",
"description": "",
"main": "index.js",
"private": true,
Expand Down
1 change: 1 addition & 0 deletions tests/e2e/orm/schemas/typing/typecheck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ async function find() {
select: {
posts: {
where: { title: 'Foo' },
take: 1,
select: {
author: {
select: {
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "e2e",
"version": "3.0.0-beta.31",
"version": "3.0.0-beta.32",
"private": true,
"type": "module",
"scripts": {
Expand Down
8 changes: 4 additions & 4 deletions tests/regression/package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"name": "regression",
"version": "3.0.0-beta.31",
"version": "3.0.0-beta.32",
"private": true,
"type": "module",
"scripts": {
"build": "pnpm run generate",
"generate": "tsx ../../scripts/test-generate.ts ./test",
"test": "pnpm generate && tsc && vitest run"
"build": "pnpm run test:generate",
"test:generate": "tsx ../../scripts/test-generate.ts ./test",
"test": "pnpm test:generate && tsc && vitest run"
},
"dependencies": {
"@zenstackhq/testtools": "workspace:*",
Expand Down
Loading