Skip to content

Commit

Permalink
merge dev to main (v2.7.4) (#1808)
Browse files Browse the repository at this point in the history
Co-authored-by: Amruth Pillai <[email protected]>
Co-authored-by: Thomas Sunde Nielsen <[email protected]>
  • Loading branch information
3 people authored Oct 25, 2024
1 parent bb5f290 commit df9b0ff
Show file tree
Hide file tree
Showing 23 changed files with 167 additions and 79 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "zenstack-monorepo",
"version": "2.7.3",
"version": "2.7.4",
"description": "",
"scripts": {
"build": "pnpm -r build",
Expand Down
2 changes: 1 addition & 1 deletion packages/ide/jetbrains/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ plugins {
}

group = "dev.zenstack"
version = "2.7.3"
version = "2.7.4"

repositories {
mavenCentral()
Expand Down
2 changes: 1 addition & 1 deletion packages/ide/jetbrains/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jetbrains",
"version": "2.7.3",
"version": "2.7.4",
"displayName": "ZenStack JetBrains IDE Plugin",
"description": "ZenStack JetBrains IDE plugin",
"homepage": "https://zenstack.dev",
Expand Down
2 changes: 1 addition & 1 deletion packages/language/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/language",
"version": "2.7.3",
"version": "2.7.4",
"displayName": "ZenStack modeling language compiler",
"description": "ZenStack modeling language compiler",
"homepage": "https://zenstack.dev",
Expand Down
2 changes: 1 addition & 1 deletion packages/misc/redwood/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/redwood",
"displayName": "ZenStack RedwoodJS Integration",
"version": "2.7.3",
"version": "2.7.4",
"description": "CLI and runtime for integrating ZenStack with RedwoodJS projects.",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/openapi/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/openapi",
"displayName": "ZenStack Plugin and Runtime for OpenAPI",
"version": "2.7.3",
"version": "2.7.4",
"description": "ZenStack plugin and runtime supporting OpenAPI",
"main": "index.js",
"repository": {
Expand Down
6 changes: 4 additions & 2 deletions packages/plugins/openapi/src/rest-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -847,8 +847,10 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase {

private generateModelEntity(model: DataModel, mode: 'read' | 'create' | 'update'): OAPI.SchemaObject {
const idFields = model.fields.filter((f) => isIdField(f));
// For compound ids, each component is also exposed as a separate field
const fields = idFields.length > 1 ? model.fields : model.fields.filter((f) => !isIdField(f));
// For compound ids each component is also exposed as a separate fields for read operations,
// but not required for write operations
const fields =
idFields.length > 1 && mode === 'read' ? model.fields : model.fields.filter((f) => !isIdField(f));

const attributes: Record<string, OAPI.SchemaObject> = {};
const relationships: Record<string, OAPI.ReferenceObject | OAPI.SchemaObject> = {};
Expand Down
15 changes: 0 additions & 15 deletions packages/plugins/openapi/tests/baseline/rest-3.0.0.baseline.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3143,14 +3143,6 @@ components:
type: string
attributes:
type: object
required:
- postId
- userId
properties:
postId:
type: string
userId:
type: string
relationships:
type: object
properties:
Expand Down Expand Up @@ -3178,13 +3170,6 @@ components:
type: string
type:
type: string
attributes:
type: object
properties:
postId:
type: string
userId:
type: string
relationships:
type: object
properties:
Expand Down
17 changes: 0 additions & 17 deletions packages/plugins/openapi/tests/baseline/rest-3.1.0.baseline.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3155,16 +3155,6 @@ components:
properties:
type:
type: string
attributes:
type: object
required:
- postId
- userId
properties:
postId:
type: string
userId:
type: string
relationships:
type: object
properties:
Expand Down Expand Up @@ -3192,13 +3182,6 @@ components:
type: string
type:
type: string
attributes:
type: object
properties:
postId:
type: string
userId:
type: string
relationships:
type: object
properties:
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/swr/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/swr",
"displayName": "ZenStack plugin for generating SWR hooks",
"version": "2.7.3",
"version": "2.7.4",
"description": "ZenStack plugin for generating SWR hooks",
"main": "index.js",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/tanstack-query/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/tanstack-query",
"displayName": "ZenStack plugin for generating tanstack-query hooks",
"version": "2.7.3",
"version": "2.7.4",
"description": "ZenStack plugin for generating tanstack-query hooks",
"main": "index.js",
"exports": {
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/trpc/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/trpc",
"displayName": "ZenStack plugin for tRPC",
"version": "2.7.3",
"version": "2.7.4",
"description": "ZenStack plugin for tRPC",
"main": "index.js",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/runtime/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/runtime",
"displayName": "ZenStack Runtime Library",
"version": "2.7.3",
"version": "2.7.4",
"description": "Runtime of ZenStack for both client-side and server-side environments.",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion packages/schema/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"publisher": "zenstack",
"displayName": "ZenStack Language Tools",
"description": "FullStack enhancement for Prisma ORM: seamless integration from database to UI",
"version": "2.7.3",
"version": "2.7.4",
"author": {
"name": "ZenStack Team"
},
Expand Down
23 changes: 13 additions & 10 deletions packages/schema/src/plugins/enhancer/enhance/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -515,15 +515,11 @@ export function enhance(prisma: any, context?: EnhancementContext<${authTypePara
return source;
}

private removeCreateFromDelegateInput(
typeAlias: TypeAliasDeclaration,
delegateModels: DelegateInfo,
source: string
) {
private removeCreateFromDelegateInput(typeAlias: TypeAliasDeclaration, delegateInfo: DelegateInfo, source: string) {
// remove create/connectOrCreate/upsert fields from delegate's input types because
// delegate models cannot be created directly
const typeName = typeAlias.getName();
const delegateModelNames = delegateModels.map(([delegate]) => delegate.name);
const delegateModelNames = delegateInfo.map(([delegate]) => delegate.name);
const delegateCreateUpdateInputRegex = new RegExp(
`^(${delegateModelNames.join('|')})(Unchecked)?(Create|Update).*Input$`
);
Expand All @@ -538,17 +534,24 @@ export function enhance(prisma: any, context?: EnhancementContext<${authTypePara
return source;
}

private readonly ModelCreateUpdateInputRegex = /(\S+)(Unchecked)?(Create|Update).*Input/;

private removeDiscriminatorFromConcreteInput(
typeAlias: TypeAliasDeclaration,
_delegateInfo: DelegateInfo,
delegateInfo: DelegateInfo,
source: string
) {
// remove discriminator field from the create/update input because discriminator cannot be set directly
const typeName = typeAlias.getName();

const match = typeName.match(this.ModelCreateUpdateInputRegex);
const delegateModelNames = delegateInfo.map(([delegate]) => delegate.name);
const concreteModelNames = delegateInfo
.map(([_, concretes]) => concretes.flatMap((c) => c.name))
.flatMap((name) => name);
const allModelNames = [...new Set([...delegateModelNames, ...concreteModelNames])];
const concreteCreateUpdateInputRegex = new RegExp(
`^(${allModelNames.join('|')})(Unchecked)?(Create|Update).*Input$`
);

const match = typeName.match(concreteCreateUpdateInputRegex);
if (match) {
const modelName = match[1];
const dataModel = this.model.declarations.find(
Expand Down
5 changes: 4 additions & 1 deletion packages/schema/src/plugins/zod/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
isEnumFieldReference,
isForeignKeyField,
isFromStdlib,
isIdField,
parseOptionAsStrings,
resolvePath,
} from '@zenstackhq/sdk';
Expand Down Expand Up @@ -291,8 +292,10 @@ export class ZodSchemaGenerator {
sf.replaceWithText((writer) => {
const scalarFields = model.fields.filter(
(field) =>
// id fields are always included
isIdField(field) ||
// regular fields only
!isDataModel(field.type.reference?.ref) && !isForeignKeyField(field)
(!isDataModel(field.type.reference?.ref) && !isForeignKeyField(field))
);

const relations = model.fields.filter((field) => isDataModel(field.type.reference?.ref));
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": "2.7.3",
"version": "2.7.4",
"description": "ZenStack plugin development SDK",
"main": "index.js",
"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": "2.7.3",
"version": "2.7.4",
"displayName": "ZenStack Server-side Adapters",
"description": "ZenStack server-side adapters",
"homepage": "https://zenstack.dev",
Expand Down
54 changes: 38 additions & 16 deletions packages/server/src/api/rest/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -720,8 +720,9 @@ class RequestHandler extends APIHandlerBase {
const attributes: any = parsed.data.attributes;

if (attributes) {
const schemaName = `${upperCaseFirst(type)}${upperCaseFirst(mode)}Schema`;
// zod-parse attributes if a schema is provided
// use the zod schema (that only contains non-relation fields) to validate the payload,
// if available
const schemaName = `${upperCaseFirst(type)}${upperCaseFirst(mode)}ScalarSchema`;
const payloadSchema = zodSchemas?.models?.[schemaName];
if (payloadSchema) {
const parsed = payloadSchema.safeParse(attributes);
Expand Down Expand Up @@ -756,6 +757,7 @@ class RequestHandler extends APIHandlerBase {
}

const { error, attributes, relationships } = this.processRequestBody(type, requestBody, zodSchemas, 'create');

if (error) {
return error;
}
Expand All @@ -776,18 +778,16 @@ class RequestHandler extends APIHandlerBase {

if (relationInfo.isCollection) {
createPayload.data[key] = {
connect: enumerate(data.data).map((item: any) => ({
[this.makePrismaIdKey(relationInfo.idFields)]: item.id,
})),
connect: enumerate(data.data).map((item: any) =>
this.makeIdConnect(relationInfo.idFields, item.id)
),
};
} else {
if (typeof data.data !== 'object') {
return this.makeError('invalidRelationData');
}
createPayload.data[key] = {
connect: {
[this.makePrismaIdKey(relationInfo.idFields)]: data.data.id,
},
connect: this.makeIdConnect(relationInfo.idFields, data.data.id),
};
}

Expand Down Expand Up @@ -868,9 +868,7 @@ class RequestHandler extends APIHandlerBase {
} else {
updateArgs.data = {
[relationship]: {
connect: {
[this.makePrismaIdKey(relationInfo.idFields)]: parsed.data.data.id,
},
connect: this.makeIdConnect(relationInfo.idFields, parsed.data.data.id),
},
};
}
Expand Down Expand Up @@ -1236,11 +1234,11 @@ class RequestHandler extends APIHandlerBase {
return r.toString();
}

private makePrismaIdFilter(idFields: FieldInfo[], resourceId: string) {
private makePrismaIdFilter(idFields: FieldInfo[], resourceId: string, nested: boolean = true) {
const decodedId = decodeURIComponent(resourceId);
if (idFields.length === 1) {
return { [idFields[0].name]: this.coerce(idFields[0].type, decodedId) };
} else {
} else if (nested) {
return {
// TODO: support `@@id` with custom name
[idFields.map((idf) => idf.name).join(prismaIdDivider)]: idFields.reduce(
Expand All @@ -1251,6 +1249,14 @@ class RequestHandler extends APIHandlerBase {
{}
),
};
} else {
return idFields.reduce(
(acc, curr, idx) => ({
...acc,
[curr.name]: this.coerce(curr.type, decodedId.split(this.idDivider)[idx]),
}),
{}
);
}
}

Expand All @@ -1261,6 +1267,22 @@ class RequestHandler extends APIHandlerBase {
return idFields.reduce((acc, curr) => ({ ...acc, [curr.name]: true }), {});
}

private makeIdConnect(idFields: FieldInfo[], id: string | number) {
if (idFields.length === 1) {
return { [idFields[0].name]: this.coerce(idFields[0].type, id) };
} else {
return {
[this.makePrismaIdKey(idFields)]: idFields.reduce(
(acc, curr, idx) => ({
...acc,
[curr.name]: this.coerce(curr.type, `${id}`.split(this.idDivider)[idx]),
}),
{}
),
};
}
}

private makeIdKey(idFields: FieldInfo[]) {
return idFields.map((idf) => idf.name).join(this.idDivider);
}
Expand Down Expand Up @@ -1594,11 +1616,11 @@ class RequestHandler extends APIHandlerBase {
const values = value.split(',').filter((i) => i);
const filterValue =
values.length > 1
? { OR: values.map((v) => this.makePrismaIdFilter(info.idFields, v)) }
: this.makePrismaIdFilter(info.idFields, value);
? { OR: values.map((v) => this.makePrismaIdFilter(info.idFields, v, false)) }
: this.makePrismaIdFilter(info.idFields, value, false);
return { some: filterValue };
} else {
return { is: this.makePrismaIdFilter(info.idFields, value) };
return { is: this.makePrismaIdFilter(info.idFields, value, false) };
}
} else {
const coerced = this.coerce(fieldInfo.type, value);
Expand Down
Loading

0 comments on commit df9b0ff

Please sign in to comment.