diff --git a/package.json b/package.json index b7a9cb9f5..4268a43b0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zenstack-monorepo", - "version": "2.18.0", + "version": "2.18.1", "description": "", "scripts": { "build": "pnpm -r --filter=\"!./packages/ide/*\" build", diff --git a/packages/ide/jetbrains/CHANGELOG.md b/packages/ide/jetbrains/CHANGELOG.md index ef902413f..7fbeaefff 100644 --- a/packages/ide/jetbrains/CHANGELOG.md +++ b/packages/ide/jetbrains/CHANGELOG.md @@ -4,6 +4,12 @@ ### Fixed +- Views are not required to have a unique identifying field marked with `@id` or `@unique`. + +## 2.17.0 + +### Fixed + - Support `@db.Json` and `@db.JsonB` attributes on strongly typed JSON fields. ## 2.16.0 diff --git a/packages/ide/jetbrains/build.gradle.kts b/packages/ide/jetbrains/build.gradle.kts index d9d2fac1a..91262623e 100644 --- a/packages/ide/jetbrains/build.gradle.kts +++ b/packages/ide/jetbrains/build.gradle.kts @@ -9,7 +9,7 @@ plugins { } group = "dev.zenstack" -version = "2.18.0" +version = "2.18.1" repositories { mavenCentral() diff --git a/packages/ide/jetbrains/package.json b/packages/ide/jetbrains/package.json index 1a6d6988e..9193879bf 100644 --- a/packages/ide/jetbrains/package.json +++ b/packages/ide/jetbrains/package.json @@ -1,6 +1,6 @@ { "name": "jetbrains", - "version": "2.18.0", + "version": "2.18.1", "displayName": "ZenStack JetBrains IDE Plugin", "description": "ZenStack JetBrains IDE plugin", "homepage": "https://zenstack.dev", diff --git a/packages/language/package.json b/packages/language/package.json index a2e1e1b69..4708d40a4 100644 --- a/packages/language/package.json +++ b/packages/language/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/language", - "version": "2.18.0", + "version": "2.18.1", "displayName": "ZenStack modeling language compiler", "description": "ZenStack modeling language compiler", "homepage": "https://zenstack.dev", diff --git a/packages/misc/redwood/package.json b/packages/misc/redwood/package.json index 0e9f68bd4..5bb13c1df 100644 --- a/packages/misc/redwood/package.json +++ b/packages/misc/redwood/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/redwood", "displayName": "ZenStack RedwoodJS Integration", - "version": "2.18.0", + "version": "2.18.1", "description": "CLI and runtime for integrating ZenStack with RedwoodJS projects.", "repository": { "type": "git", diff --git a/packages/plugins/openapi/package.json b/packages/plugins/openapi/package.json index 84e8eb5c3..aca31830e 100644 --- a/packages/plugins/openapi/package.json +++ b/packages/plugins/openapi/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/openapi", "displayName": "ZenStack Plugin and Runtime for OpenAPI", - "version": "2.18.0", + "version": "2.18.1", "description": "ZenStack plugin and runtime supporting OpenAPI", "main": "index.js", "repository": { diff --git a/packages/plugins/openapi/src/generator-base.ts b/packages/plugins/openapi/src/generator-base.ts index 9dc94a57c..f91423346 100644 --- a/packages/plugins/openapi/src/generator-base.ts +++ b/packages/plugins/openapi/src/generator-base.ts @@ -15,7 +15,9 @@ export abstract class OpenAPIGeneratorBase { abstract generate(): PluginResult; protected get includedModels() { - return getDataModels(this.model).filter((d) => !hasAttribute(d, '@@openapi.ignore')); + const includeOpenApiIgnored = this.getOption('includeOpenApiIgnored', false); + const models = getDataModels(this.model); + return includeOpenApiIgnored ? models : models.filter((d) => !hasAttribute(d, '@@openapi.ignore')); } protected wrapArray( diff --git a/packages/plugins/openapi/src/rpc-generator.ts b/packages/plugins/openapi/src/rpc-generator.ts index 1a8f3630e..0adb3ed8c 100644 --- a/packages/plugins/openapi/src/rpc-generator.ts +++ b/packages/plugins/openapi/src/rpc-generator.ts @@ -1,7 +1,7 @@ // Inspired by: https://github.com/omar-dulaimi/prisma-trpc-generator import { PluginError, PluginOptions, analyzePolicies, requireOption, resolvePath } from '@zenstackhq/sdk'; -import { DataModel, Model, isDataModel } from '@zenstackhq/sdk/ast'; +import { DataModel, Model, TypeDef, TypeDefField, TypeDefFieldType, isDataModel, isEnum, isTypeDef } from '@zenstackhq/sdk/ast'; import { AggregateOperationSupport, addMissingInputObjectTypesForAggregate, @@ -649,12 +649,27 @@ export class RPCOpenAPIGenerator extends OpenAPIGeneratorBase { for (const _enum of [...(this.dmmf.schema.enumTypes.model ?? []), ...this.dmmf.schema.enumTypes.prisma]) { schemas[upperCaseFirst(_enum.name)] = this.generateEnumComponent(_enum); } + + // Also add enums from AST that might not be in DMMF (e.g., only used in TypeDefs) + for (const enumDecl of this.model.declarations.filter(isEnum)) { + if (!schemas[upperCaseFirst(enumDecl.name)]) { + schemas[upperCaseFirst(enumDecl.name)] = { + type: 'string', + enum: enumDecl.fields.map(f => f.name) + }; + } + } // data models for (const model of this.dmmf.datamodel.models) { schemas[upperCaseFirst(model.name)] = this.generateEntityComponent(model); } + // type defs + for (const typeDef of this.model.declarations.filter(isTypeDef)) { + schemas[upperCaseFirst(typeDef.name)] = this.generateTypeDefComponent(typeDef); + } + for (const input of this.inputObjectTypes) { schemas[upperCaseFirst(input.name)] = this.generateInputComponent(input); } @@ -737,7 +752,7 @@ export class RPCOpenAPIGenerator extends OpenAPIGeneratorBase { const required: string[] = []; for (const field of model.fields) { - properties[field.name] = this.generateField(field); + properties[field.name] = this.generateField(field, model.name); if (field.isRequired && !(field.relationName && field.isList)) { required.push(field.name); } @@ -750,7 +765,22 @@ export class RPCOpenAPIGenerator extends OpenAPIGeneratorBase { return result; } - private generateField(def: { kind: DMMF.FieldKind; type: string; isList: boolean; isRequired: boolean }) { + private generateField(def: { kind: DMMF.FieldKind; type: string; isList: boolean; isRequired: boolean; name?: string }, modelName?: string) { + // For Json fields, check if there's a corresponding TypeDef in the original model + if (def.kind === 'scalar' && def.type === 'Json' && modelName && def.name) { + const dataModel = this.model.declarations.find(d => isDataModel(d) && d.name === modelName) as DataModel; + if (dataModel) { + const field = dataModel.fields.find(f => f.name === def.name); + if (field?.type.reference?.ref && isTypeDef(field.type.reference.ref)) { + // This Json field references a TypeDef + return this.wrapArray( + this.wrapNullable(this.ref(field.type.reference.ref.name, true), !def.isRequired), + def.isList + ); + } + } + } + switch (def.kind) { case 'scalar': return this.wrapArray(this.prismaTypeToOpenAPIType(def.type, !def.isRequired), def.isList); @@ -816,6 +846,47 @@ export class RPCOpenAPIGenerator extends OpenAPIGeneratorBase { return result; } + private generateTypeDefComponent(typeDef: TypeDef): OAPI.SchemaObject { + const schema: OAPI.SchemaObject = { + type: 'object', + description: `The "${typeDef.name}" TypeDef`, + properties: typeDef.fields.reduce((acc, field) => { + acc[field.name] = this.generateTypeDefField(field); + return acc; + }, {} as Record), + }; + + const required = typeDef.fields.filter((f) => !f.type.optional).map((f) => f.name); + if (required.length > 0) { + schema.required = required; + } + + return schema; + } + + private generateTypeDefField(field: TypeDefField): OAPI.ReferenceObject | OAPI.SchemaObject { + return this.wrapArray( + this.wrapNullable(this.typeDefFieldTypeToOpenAPISchema(field.type), field.type.optional), + field.type.array + ); + } + + private typeDefFieldTypeToOpenAPISchema(type: TypeDefFieldType): OAPI.ReferenceObject | OAPI.SchemaObject { + // For references to other types (TypeDef, Enum, Model) + if (type.reference?.ref) { + return this.ref(type.reference.ref.name, true); + } + + // For scalar types, reuse the existing mapping logic + // Note: Json type is handled as empty schema for consistency + return match(type.type) + .with('Json', () => ({} as OAPI.SchemaObject)) + .otherwise((t) => { + // Delegate to prismaTypeToOpenAPIType for all other scalar types + return this.prismaTypeToOpenAPIType(String(t), false); + }); + } + private setInputRequired(fields: readonly DMMF.SchemaArg[], result: OAPI.NonArraySchemaObject) { const required = fields.filter((f) => f.isRequired).map((f) => f.name); if (required.length > 0) { @@ -839,7 +910,12 @@ export class RPCOpenAPIGenerator extends OpenAPIGeneratorBase { .with(P.union('Boolean', 'True'), () => ({ type: 'boolean' })) .with('DateTime', () => ({ type: 'string', format: 'date-time' })) .with('Bytes', () => ({ type: 'string', format: 'byte' })) - .with(P.union('JSON', 'Json'), () => ({})) + .with(P.union('JSON', 'Json'), () => { + // For Json fields, check if there's a specific TypeDef reference + // Otherwise, return empty schema for arbitrary JSON + const isTypeDefType = this.model.declarations.some(d => isTypeDef(d) && d.name === type); + return isTypeDefType ? this.ref(type, false) : {}; + }) .otherwise((type) => this.ref(type.toString(), false)); return this.wrapNullable(result, nullable); diff --git a/packages/plugins/openapi/tests/baseline/rpc-type-coverage-3.0.0.baseline.yaml b/packages/plugins/openapi/tests/baseline/rpc-type-coverage-3.0.0.baseline.yaml index d4aa6f8cf..eaea71827 100644 --- a/packages/plugins/openapi/tests/baseline/rpc-type-coverage-3.0.0.baseline.yaml +++ b/packages/plugins/openapi/tests/baseline/rpc-type-coverage-3.0.0.baseline.yaml @@ -19,16 +19,33 @@ components: - decimal - boolean - bytes + - json + - plainJson SortOrder: type: string enum: - asc - desc + NullableJsonNullValueInput: + type: string + enum: + - DbNull + - JsonNull + JsonNullValueInput: + type: string + enum: + - JsonNull QueryMode: type: string enum: - default - insensitive + JsonNullValueFilter: + type: string + enum: + - DbNull + - JsonNull + - AnyNull NullsOrder: type: string enum: @@ -60,6 +77,11 @@ components: type: string format: byte nullable: true + json: + allOf: + - $ref: '#/components/schemas/Meta' + nullable: true + plainJson: {} required: - id - string @@ -69,6 +91,15 @@ components: - float - decimal - boolean + - plainJson + Meta: + type: object + description: The "Meta" TypeDef + properties: + something: + type: string + required: + - something FooWhereInput: type: object properties: @@ -129,6 +160,10 @@ components: - type: string format: byte nullable: true + json: + $ref: '#/components/schemas/JsonNullableFilter' + plainJson: + $ref: '#/components/schemas/JsonFilter' FooOrderByWithRelationInput: type: object properties: @@ -152,6 +187,12 @@ components: oneOf: - $ref: '#/components/schemas/SortOrder' - $ref: '#/components/schemas/SortOrderInput' + json: + oneOf: + - $ref: '#/components/schemas/SortOrder' + - $ref: '#/components/schemas/SortOrderInput' + plainJson: + $ref: '#/components/schemas/SortOrder' FooWhereUniqueInput: type: object properties: @@ -210,6 +251,10 @@ components: - type: string format: byte nullable: true + json: + $ref: '#/components/schemas/JsonNullableFilter' + plainJson: + $ref: '#/components/schemas/JsonFilter' FooScalarWhereWithAggregatesInput: type: object properties: @@ -270,6 +315,10 @@ components: - type: string format: byte nullable: true + json: + $ref: '#/components/schemas/JsonNullableWithAggregatesFilter' + plainJson: + $ref: '#/components/schemas/JsonWithAggregatesFilter' FooCreateInput: type: object properties: @@ -296,6 +345,14 @@ components: type: string format: byte nullable: true + json: + oneOf: + - $ref: '#/components/schemas/NullableJsonNullValueInput' + - {} + plainJson: + oneOf: + - $ref: '#/components/schemas/JsonNullValueInput' + - {} required: - string - int @@ -304,6 +361,7 @@ components: - float - decimal - boolean + - plainJson FooUpdateInput: type: object properties: @@ -348,6 +406,14 @@ components: format: byte - $ref: '#/components/schemas/NullableBytesFieldUpdateOperationsInput' nullable: true + json: + oneOf: + - $ref: '#/components/schemas/NullableJsonNullValueInput' + - {} + plainJson: + oneOf: + - $ref: '#/components/schemas/JsonNullValueInput' + - {} FooCreateManyInput: type: object properties: @@ -374,6 +440,14 @@ components: type: string format: byte nullable: true + json: + oneOf: + - $ref: '#/components/schemas/NullableJsonNullValueInput' + - {} + plainJson: + oneOf: + - $ref: '#/components/schemas/JsonNullValueInput' + - {} required: - string - int @@ -382,6 +456,7 @@ components: - float - decimal - boolean + - plainJson FooUpdateManyMutationInput: type: object properties: @@ -426,6 +501,14 @@ components: format: byte - $ref: '#/components/schemas/NullableBytesFieldUpdateOperationsInput' nullable: true + json: + oneOf: + - $ref: '#/components/schemas/NullableJsonNullValueInput' + - {} + plainJson: + oneOf: + - $ref: '#/components/schemas/JsonNullValueInput' + - {} StringFilter: type: object properties: @@ -642,6 +725,72 @@ components: format: byte - $ref: '#/components/schemas/NestedBytesNullableFilter' nullable: true + JsonNullableFilter: + type: object + properties: + equals: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' + path: + type: array + items: + type: string + mode: + $ref: '#/components/schemas/QueryMode' + string_contains: + type: string + string_starts_with: + type: string + string_ends_with: + type: string + array_starts_with: + nullable: true + array_ends_with: + nullable: true + array_contains: + nullable: true + lt: {} + lte: {} + gt: {} + gte: {} + not: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' + JsonFilter: + type: object + properties: + equals: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' + path: + type: array + items: + type: string + mode: + $ref: '#/components/schemas/QueryMode' + string_contains: + type: string + string_starts_with: + type: string + string_ends_with: + type: string + array_starts_with: + nullable: true + array_ends_with: + nullable: true + array_contains: + nullable: true + lt: {} + lte: {} + gt: {} + gte: {} + not: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' SortOrderInput: type: object properties: @@ -931,6 +1080,84 @@ components: $ref: '#/components/schemas/NestedBytesNullableFilter' _max: $ref: '#/components/schemas/NestedBytesNullableFilter' + JsonNullableWithAggregatesFilter: + type: object + properties: + equals: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' + path: + type: array + items: + type: string + mode: + $ref: '#/components/schemas/QueryMode' + string_contains: + type: string + string_starts_with: + type: string + string_ends_with: + type: string + array_starts_with: + nullable: true + array_ends_with: + nullable: true + array_contains: + nullable: true + lt: {} + lte: {} + gt: {} + gte: {} + not: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' + _count: + $ref: '#/components/schemas/NestedIntNullableFilter' + _min: + $ref: '#/components/schemas/NestedJsonNullableFilter' + _max: + $ref: '#/components/schemas/NestedJsonNullableFilter' + JsonWithAggregatesFilter: + type: object + properties: + equals: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' + path: + type: array + items: + type: string + mode: + $ref: '#/components/schemas/QueryMode' + string_contains: + type: string + string_starts_with: + type: string + string_ends_with: + type: string + array_starts_with: + nullable: true + array_ends_with: + nullable: true + array_contains: + nullable: true + lt: {} + lte: {} + gt: {} + gte: {} + not: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _min: + $ref: '#/components/schemas/NestedJsonFilter' + _max: + $ref: '#/components/schemas/NestedJsonFilter' StringFieldUpdateOperationsInput: type: object properties: @@ -1537,6 +1764,72 @@ components: - type: integer - $ref: '#/components/schemas/NestedIntNullableFilter' nullable: true + NestedJsonNullableFilter: + type: object + properties: + equals: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' + path: + type: array + items: + type: string + mode: + $ref: '#/components/schemas/QueryMode' + string_contains: + type: string + string_starts_with: + type: string + string_ends_with: + type: string + array_starts_with: + nullable: true + array_ends_with: + nullable: true + array_contains: + nullable: true + lt: {} + lte: {} + gt: {} + gte: {} + not: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' + NestedJsonFilter: + type: object + properties: + equals: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' + path: + type: array + items: + type: string + mode: + $ref: '#/components/schemas/QueryMode' + string_contains: + type: string + string_starts_with: + type: string + string_ends_with: + type: string + array_starts_with: + nullable: true + array_ends_with: + nullable: true + array_contains: + nullable: true + lt: {} + lte: {} + gt: {} + gte: {} + not: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' FooSelect: type: object properties: @@ -1558,6 +1851,10 @@ components: type: boolean bytes: type: boolean + json: + type: boolean + plainJson: + type: boolean FooCountAggregateInput: type: object properties: @@ -1579,6 +1876,10 @@ components: type: boolean bytes: type: boolean + json: + type: boolean + plainJson: + type: boolean _all: type: boolean FooAvgAggregateInput: @@ -1694,6 +1995,9 @@ components: type: string format: byte nullable: true + json: + nullable: true + plainJson: {} _count: allOf: - $ref: '#/components/schemas/FooCountAggregateOutputType' @@ -1723,6 +2027,7 @@ components: - float - decimal - boolean + - plainJson FooCountAggregateOutputType: type: object properties: @@ -1744,6 +2049,10 @@ components: type: integer bytes: type: integer + json: + type: integer + plainJson: + type: integer _all: type: integer required: @@ -1756,6 +2065,8 @@ components: - decimal - boolean - bytes + - json + - plainJson - _all FooAvgAggregateOutputType: type: object @@ -1957,8 +2268,6 @@ components: $ref: '#/components/schemas/FooSelect' where: $ref: '#/components/schemas/FooWhereInput' - meta: - $ref: '#/components/schemas/_Meta' orderBy: oneOf: - $ref: '#/components/schemas/FooOrderByWithRelationInput' @@ -1971,6 +2280,8 @@ components: type: integer skip: type: integer + meta: + $ref: '#/components/schemas/_Meta' FooUpdateArgs: type: object required: diff --git a/packages/plugins/openapi/tests/baseline/rpc-type-coverage-3.1.0.baseline.yaml b/packages/plugins/openapi/tests/baseline/rpc-type-coverage-3.1.0.baseline.yaml index f2d3b4c0e..5f3e59136 100644 --- a/packages/plugins/openapi/tests/baseline/rpc-type-coverage-3.1.0.baseline.yaml +++ b/packages/plugins/openapi/tests/baseline/rpc-type-coverage-3.1.0.baseline.yaml @@ -19,16 +19,33 @@ components: - decimal - boolean - bytes + - json + - plainJson SortOrder: type: string enum: - asc - desc + NullableJsonNullValueInput: + type: string + enum: + - DbNull + - JsonNull + JsonNullValueInput: + type: string + enum: + - JsonNull QueryMode: type: string enum: - default - insensitive + JsonNullValueFilter: + type: string + enum: + - DbNull + - JsonNull + - AnyNull NullsOrder: type: string enum: @@ -61,6 +78,11 @@ components: - type: 'null' - type: string format: byte + json: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/Meta' + plainJson: {} required: - id - string @@ -70,6 +92,15 @@ components: - float - decimal - boolean + - plainJson + Meta: + type: object + description: The "Meta" TypeDef + properties: + something: + type: string + required: + - something FooWhereInput: type: object properties: @@ -130,6 +161,10 @@ components: - type: string format: byte - type: 'null' + json: + $ref: '#/components/schemas/JsonNullableFilter' + plainJson: + $ref: '#/components/schemas/JsonFilter' FooOrderByWithRelationInput: type: object properties: @@ -153,6 +188,12 @@ components: oneOf: - $ref: '#/components/schemas/SortOrder' - $ref: '#/components/schemas/SortOrderInput' + json: + oneOf: + - $ref: '#/components/schemas/SortOrder' + - $ref: '#/components/schemas/SortOrderInput' + plainJson: + $ref: '#/components/schemas/SortOrder' FooWhereUniqueInput: type: object properties: @@ -211,6 +252,10 @@ components: - type: string format: byte - type: 'null' + json: + $ref: '#/components/schemas/JsonNullableFilter' + plainJson: + $ref: '#/components/schemas/JsonFilter' FooScalarWhereWithAggregatesInput: type: object properties: @@ -271,6 +316,10 @@ components: - type: string format: byte - type: 'null' + json: + $ref: '#/components/schemas/JsonNullableWithAggregatesFilter' + plainJson: + $ref: '#/components/schemas/JsonWithAggregatesFilter' FooCreateInput: type: object properties: @@ -298,6 +347,14 @@ components: - type: 'null' - type: string format: byte + json: + oneOf: + - $ref: '#/components/schemas/NullableJsonNullValueInput' + - {} + plainJson: + oneOf: + - $ref: '#/components/schemas/JsonNullValueInput' + - {} required: - string - int @@ -306,6 +363,7 @@ components: - float - decimal - boolean + - plainJson FooUpdateInput: type: object properties: @@ -350,6 +408,14 @@ components: format: byte - $ref: '#/components/schemas/NullableBytesFieldUpdateOperationsInput' - type: 'null' + json: + oneOf: + - $ref: '#/components/schemas/NullableJsonNullValueInput' + - {} + plainJson: + oneOf: + - $ref: '#/components/schemas/JsonNullValueInput' + - {} FooCreateManyInput: type: object properties: @@ -377,6 +443,14 @@ components: - type: 'null' - type: string format: byte + json: + oneOf: + - $ref: '#/components/schemas/NullableJsonNullValueInput' + - {} + plainJson: + oneOf: + - $ref: '#/components/schemas/JsonNullValueInput' + - {} required: - string - int @@ -385,6 +459,7 @@ components: - float - decimal - boolean + - plainJson FooUpdateManyMutationInput: type: object properties: @@ -429,6 +504,14 @@ components: format: byte - $ref: '#/components/schemas/NullableBytesFieldUpdateOperationsInput' - type: 'null' + json: + oneOf: + - $ref: '#/components/schemas/NullableJsonNullValueInput' + - {} + plainJson: + oneOf: + - $ref: '#/components/schemas/JsonNullValueInput' + - {} StringFilter: type: object properties: @@ -648,6 +731,84 @@ components: format: byte - $ref: '#/components/schemas/NestedBytesNullableFilter' - type: 'null' + JsonNullableFilter: + type: object + properties: + equals: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' + path: + type: array + items: + type: string + mode: + $ref: '#/components/schemas/QueryMode' + string_contains: + type: string + string_starts_with: + type: string + string_ends_with: + type: string + array_starts_with: + oneOf: + - type: 'null' + - {} + array_ends_with: + oneOf: + - type: 'null' + - {} + array_contains: + oneOf: + - type: 'null' + - {} + lt: {} + lte: {} + gt: {} + gte: {} + not: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' + JsonFilter: + type: object + properties: + equals: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' + path: + type: array + items: + type: string + mode: + $ref: '#/components/schemas/QueryMode' + string_contains: + type: string + string_starts_with: + type: string + string_ends_with: + type: string + array_starts_with: + oneOf: + - type: 'null' + - {} + array_ends_with: + oneOf: + - type: 'null' + - {} + array_contains: + oneOf: + - type: 'null' + - {} + lt: {} + lte: {} + gt: {} + gte: {} + not: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' SortOrderInput: type: object properties: @@ -940,6 +1101,96 @@ components: $ref: '#/components/schemas/NestedBytesNullableFilter' _max: $ref: '#/components/schemas/NestedBytesNullableFilter' + JsonNullableWithAggregatesFilter: + type: object + properties: + equals: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' + path: + type: array + items: + type: string + mode: + $ref: '#/components/schemas/QueryMode' + string_contains: + type: string + string_starts_with: + type: string + string_ends_with: + type: string + array_starts_with: + oneOf: + - type: 'null' + - {} + array_ends_with: + oneOf: + - type: 'null' + - {} + array_contains: + oneOf: + - type: 'null' + - {} + lt: {} + lte: {} + gt: {} + gte: {} + not: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' + _count: + $ref: '#/components/schemas/NestedIntNullableFilter' + _min: + $ref: '#/components/schemas/NestedJsonNullableFilter' + _max: + $ref: '#/components/schemas/NestedJsonNullableFilter' + JsonWithAggregatesFilter: + type: object + properties: + equals: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' + path: + type: array + items: + type: string + mode: + $ref: '#/components/schemas/QueryMode' + string_contains: + type: string + string_starts_with: + type: string + string_ends_with: + type: string + array_starts_with: + oneOf: + - type: 'null' + - {} + array_ends_with: + oneOf: + - type: 'null' + - {} + array_contains: + oneOf: + - type: 'null' + - {} + lt: {} + lte: {} + gt: {} + gte: {} + not: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _min: + $ref: '#/components/schemas/NestedJsonFilter' + _max: + $ref: '#/components/schemas/NestedJsonFilter' StringFieldUpdateOperationsInput: type: object properties: @@ -1556,6 +1807,84 @@ components: - type: integer - $ref: '#/components/schemas/NestedIntNullableFilter' - type: 'null' + NestedJsonNullableFilter: + type: object + properties: + equals: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' + path: + type: array + items: + type: string + mode: + $ref: '#/components/schemas/QueryMode' + string_contains: + type: string + string_starts_with: + type: string + string_ends_with: + type: string + array_starts_with: + oneOf: + - type: 'null' + - {} + array_ends_with: + oneOf: + - type: 'null' + - {} + array_contains: + oneOf: + - type: 'null' + - {} + lt: {} + lte: {} + gt: {} + gte: {} + not: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' + NestedJsonFilter: + type: object + properties: + equals: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' + path: + type: array + items: + type: string + mode: + $ref: '#/components/schemas/QueryMode' + string_contains: + type: string + string_starts_with: + type: string + string_ends_with: + type: string + array_starts_with: + oneOf: + - type: 'null' + - {} + array_ends_with: + oneOf: + - type: 'null' + - {} + array_contains: + oneOf: + - type: 'null' + - {} + lt: {} + lte: {} + gt: {} + gte: {} + not: + oneOf: + - {} + - $ref: '#/components/schemas/JsonNullValueFilter' FooSelect: type: object properties: @@ -1577,6 +1906,10 @@ components: type: boolean bytes: type: boolean + json: + type: boolean + plainJson: + type: boolean FooCountAggregateInput: type: object properties: @@ -1598,6 +1931,10 @@ components: type: boolean bytes: type: boolean + json: + type: boolean + plainJson: + type: boolean _all: type: boolean FooAvgAggregateInput: @@ -1714,6 +2051,11 @@ components: - type: 'null' - type: string format: byte + json: + oneOf: + - type: 'null' + - {} + plainJson: {} _count: oneOf: - type: 'null' @@ -1743,6 +2085,7 @@ components: - float - decimal - boolean + - plainJson FooCountAggregateOutputType: type: object properties: @@ -1764,6 +2107,10 @@ components: type: integer bytes: type: integer + json: + type: integer + plainJson: + type: integer _all: type: integer required: @@ -1776,6 +2123,8 @@ components: - decimal - boolean - bytes + - json + - plainJson - _all FooAvgAggregateOutputType: type: object @@ -1999,8 +2348,6 @@ components: $ref: '#/components/schemas/FooSelect' where: $ref: '#/components/schemas/FooWhereInput' - meta: - $ref: '#/components/schemas/_Meta' orderBy: oneOf: - $ref: '#/components/schemas/FooOrderByWithRelationInput' @@ -2013,6 +2360,8 @@ components: type: integer skip: type: integer + meta: + $ref: '#/components/schemas/_Meta' FooUpdateArgs: type: object required: diff --git a/packages/plugins/openapi/tests/openapi-rpc.test.ts b/packages/plugins/openapi/tests/openapi-rpc.test.ts index 930341ffb..c61e01b1a 100644 --- a/packages/plugins/openapi/tests/openapi-rpc.test.ts +++ b/packages/plugins/openapi/tests/openapi-rpc.test.ts @@ -377,6 +377,10 @@ plugin openapi { specVersion = '${specVersion}' } +type Meta { + something String +} + model Foo { id String @id @default(cuid()) @@ -388,6 +392,8 @@ model Foo { decimal Decimal boolean Boolean bytes Bytes? + json Meta? @json + plainJson Json @@allow('all', true) } @@ -411,6 +417,107 @@ model Foo { } }); + it('complex TypeDef structures', async () => { + for (const specVersion of ['3.0.0', '3.1.0']) { + const { model, dmmf, modelFile } = await loadZModelAndDmmf(` +plugin openapi { + provider = '${normalizePath(path.resolve(__dirname, '../dist'))}' + specVersion = '${specVersion}' +} + +enum Status { + PENDING + APPROVED + REJECTED +} + +type Address { + street String + city String + country String + zipCode String? +} + +type ContactInfo { + email String + phone String? + addresses Address[] +} + +type ReviewItem { + id String + status Status + reviewer ContactInfo + score Int + comments String[] + metadata Json? +} + +type ComplexData { + reviews ReviewItem[] + primaryContact ContactInfo + tags String[] + settings Json +} + +model Product { + id String @id @default(cuid()) + name String + data ComplexData @json + simpleJson Json + + @@allow('all', true) +} + `); + + const { name: output } = tmp.fileSync({ postfix: '.yaml' }); + + const options = buildOptions(model, modelFile, output); + await generate(model, options, dmmf); + + await OpenAPIParser.validate(output); + + const parsed = YAML.parse(fs.readFileSync(output, 'utf-8')); + expect(parsed.openapi).toBe(specVersion); + + // Verify all TypeDefs are generated + expect(parsed.components.schemas.Address).toBeDefined(); + expect(parsed.components.schemas.ContactInfo).toBeDefined(); + expect(parsed.components.schemas.ReviewItem).toBeDefined(); + expect(parsed.components.schemas.ComplexData).toBeDefined(); + + // Verify enum reference in TypeDef + expect(parsed.components.schemas.ReviewItem.properties.status.$ref).toBe('#/components/schemas/Status'); + + // Json field inside a TypeDef should remain generic (wrapped with nullable since it's optional) + // OpenAPI 3.1 uses oneOf with null type, while 3.0 uses nullable: true + if (specVersion === '3.1.0') { + expect(parsed.components.schemas.ReviewItem.properties.metadata).toEqual({ + oneOf: [ + { type: 'null' }, + {} + ] + }); + } else { + expect(parsed.components.schemas.ReviewItem.properties.metadata).toEqual({ nullable: true }); + } + + // Verify nested TypeDef references + expect(parsed.components.schemas.ContactInfo.properties.addresses.type).toBe('array'); + expect(parsed.components.schemas.ContactInfo.properties.addresses.items.$ref).toBe('#/components/schemas/Address'); + + // Verify array of complex objects + expect(parsed.components.schemas.ComplexData.properties.reviews.type).toBe('array'); + expect(parsed.components.schemas.ComplexData.properties.reviews.items.$ref).toBe('#/components/schemas/ReviewItem'); + + // Verify the Product model references the ComplexData TypeDef + expect(parsed.components.schemas.Product.properties.data.$ref).toBe('#/components/schemas/ComplexData'); + + // Verify plain Json field remains generic + expect(parsed.components.schemas.Product.properties.simpleJson).toEqual({}); + } + }); + it('full-text search', async () => { const { model, dmmf, modelFile } = await loadZModelAndDmmf(` generator js { diff --git a/packages/plugins/swr/package.json b/packages/plugins/swr/package.json index 00f0fb1b0..7e90b800a 100644 --- a/packages/plugins/swr/package.json +++ b/packages/plugins/swr/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/swr", "displayName": "ZenStack plugin for generating SWR hooks", - "version": "2.18.0", + "version": "2.18.1", "description": "ZenStack plugin for generating SWR hooks", "main": "index.js", "repository": { diff --git a/packages/plugins/tanstack-query/package.json b/packages/plugins/tanstack-query/package.json index fdf337d9b..b23fd55b1 100644 --- a/packages/plugins/tanstack-query/package.json +++ b/packages/plugins/tanstack-query/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/tanstack-query", "displayName": "ZenStack plugin for generating tanstack-query hooks", - "version": "2.18.0", + "version": "2.18.1", "description": "ZenStack plugin for generating tanstack-query hooks", "main": "index.js", "exports": { diff --git a/packages/plugins/tanstack-query/src/generator.ts b/packages/plugins/tanstack-query/src/generator.ts index 4f901da6c..aed43b643 100644 --- a/packages/plugins/tanstack-query/src/generator.ts +++ b/packages/plugins/tanstack-query/src/generator.ts @@ -117,7 +117,10 @@ function generateQueryHook( const capOperation = upperCaseFirst(operation); const argsType = overrideInputType ?? `Prisma.${model}${capOperation}Args`; - const inputType = makeQueryArgsType(target, argsType); + let inputType = makeQueryArgsType(target, argsType); + if (target === 'angular') { + inputType = `${inputType} | (() => ${inputType})`; + } const infinite = generateMode.includes('Infinite'); const suspense = generateMode.includes('Suspense'); @@ -673,7 +676,7 @@ function makeBaseImports(target: TargetFramework, version: TanStackVersion) { } case 'angular': { return [ - `import type { CreateMutationOptions, CreateQueryOptions, CreateInfiniteQueryOptions, InfiniteData } from '@tanstack/angular-query-v5';`, + `import type { CreateMutationOptions, CreateQueryOptions, CreateInfiniteQueryOptions, InfiniteData } from '@tanstack/angular-query-experimental';`, `import { getHooksContext } from '${runtimeImportBase}/${target}';`, ...shared, ]; diff --git a/packages/plugins/tanstack-query/src/runtime-v5/angular.ts b/packages/plugins/tanstack-query/src/runtime-v5/angular.ts index 87f0881cd..c5a67c44f 100644 --- a/packages/plugins/tanstack-query/src/runtime-v5/angular.ts +++ b/packages/plugins/tanstack-query/src/runtime-v5/angular.ts @@ -8,8 +8,6 @@ import { type CreateMutationOptions, type CreateInfiniteQueryOptions, type InfiniteData, - CreateInfiniteQueryResult, - QueryKey, } from '@tanstack/angular-query-v5'; import type { ModelMeta } from '@zenstackhq/runtime/cross'; import { inject, InjectionToken } from '@angular/core'; @@ -29,6 +27,9 @@ import { export { APIContext as RequestHandlerContext } from '../runtime/common'; +type AnyFn = (...a: unknown[]) => unknown; +const isFn = (v: unknown): v is AnyFn => typeof v === 'function'; + export const AngularQueryContextKey = new InjectionToken('zenstack-angular-query-context'); /** @@ -74,19 +75,21 @@ export function useModelQuery( options?: Omit, 'queryKey'> & ExtraQueryOptions, fetch?: FetchFn ) { - const reqUrl = makeUrl(url, args); - const queryKey = getQueryKey(model, url, args, { - infinite: false, - optimisticUpdate: options?.optimisticUpdate !== false, - }); - return { - queryKey, - ...injectQuery(() => ({ + const query = injectQuery(() => { + const resolvedArgs = isFn(args) ? args() : args; + + const reqUrl = makeUrl(url, resolvedArgs); + const queryKey = getQueryKey(model, url, resolvedArgs, { + infinite: false, + optimisticUpdate: options?.optimisticUpdate !== false, + }); + return { queryKey, queryFn: ({ signal }) => fetcher(reqUrl, { signal }, fetch, false), ...options, - })), - }; + }; + }); + return query; } /** @@ -108,19 +111,22 @@ export function useInfiniteModelQuery( 'queryKey' | 'initialPageParam' >, fetch?: FetchFn -): CreateInfiniteQueryResult, TError> & { queryKey: QueryKey } { - const queryKey = getQueryKey(model, url, args, { infinite: true, optimisticUpdate: false }); - return { - queryKey, - ...injectInfiniteQuery(() => ({ +) { + const query = injectInfiniteQuery(() => { + const resolvedArgs = isFn(args) ? args() : args; + + const queryKey = getQueryKey(model, url, resolvedArgs, { infinite: true, optimisticUpdate: false }); + + return { queryKey, queryFn: ({ pageParam, signal }) => { - return fetcher(makeUrl(url, pageParam ?? args), { signal }, fetch, false); + return fetcher(makeUrl(url, pageParam ?? resolvedArgs), { signal }, fetch, false); }, - initialPageParam: args, + initialPageParam: resolvedArgs, ...options, - })), - }; + }; + }); + return query; } /** diff --git a/packages/plugins/trpc/package.json b/packages/plugins/trpc/package.json index ce6efbb50..63015ed59 100644 --- a/packages/plugins/trpc/package.json +++ b/packages/plugins/trpc/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/trpc", "displayName": "ZenStack plugin for tRPC", - "version": "2.18.0", + "version": "2.18.1", "description": "ZenStack plugin for tRPC", "main": "index.js", "repository": { diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/package.json b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/package.json index a829d8509..8878cf2ab 100644 --- a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/package.json +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/package.json @@ -10,7 +10,7 @@ "postinstall": "nuxt prepare" }, "dependencies": { - "@prisma/client": "6.13.x", + "@prisma/client": "6.14.x", "@trpc/client": "^10.45.2", "@trpc/server": "^10.45.2", "nuxt": "^3.14.1592", @@ -21,7 +21,7 @@ }, "devDependencies": { "esbuild": "^0.24.0", - "prisma": "6.13.x", + "prisma": "6.14.x", "typescript": "^5.6.2", "vue-tsc": "^2.1.10" } diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/package.json b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/package.json index 81f6e0d58..70f7cee39 100644 --- a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/package.json +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/package.json @@ -10,7 +10,7 @@ "postinstall": "nuxt prepare" }, "dependencies": { - "@prisma/client": "6.13.x", + "@prisma/client": "6.14.x", "@trpc/client": "^11.0.0-rc.563", "@trpc/server": "^11.0.0-rc.563", "nuxt": "^3.14.1592", @@ -21,7 +21,7 @@ }, "devDependencies": { "esbuild": "^0.24.0", - "prisma": "6.13.x", + "prisma": "6.14.x", "typescript": "^5.6.2", "vue-tsc": "^2.1.10" } diff --git a/packages/plugins/trpc/tests/projects/t3-trpc-v11/package.json b/packages/plugins/trpc/tests/projects/t3-trpc-v11/package.json index 29d1ea320..7eb7ab042 100644 --- a/packages/plugins/trpc/tests/projects/t3-trpc-v11/package.json +++ b/packages/plugins/trpc/tests/projects/t3-trpc-v11/package.json @@ -15,7 +15,7 @@ "start": "next start" }, "dependencies": { - "@prisma/client": "6.13.x", + "@prisma/client": "6.14.x", "@t3-oss/env-nextjs": "^0.10.1", "@tanstack/react-query": "^5.50.0", "@trpc/client": "^11.0.0-rc.446", @@ -39,7 +39,7 @@ "@typescript-eslint/parser": "^8.1.0", "eslint": "^8.57.0", "eslint-config-next": "^14.2.4", - "prisma": "6.13.x", + "prisma": "6.14.x", "typescript": "^5.5.3" }, "ct3aMetadata": { diff --git a/packages/runtime/package.json b/packages/runtime/package.json index a5be906ca..ee4c006eb 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/runtime", "displayName": "ZenStack Runtime Library", - "version": "2.18.0", + "version": "2.18.1", "description": "Runtime of ZenStack for both client-side and server-side environments.", "repository": { "type": "git", @@ -113,7 +113,7 @@ "zod-validation-error": "catalog:" }, "peerDependencies": { - "@prisma/client": "5.0.0 - 6.13.x", + "@prisma/client": "5.0.0 - 6.14.x", "zod": "catalog:" }, "author": { diff --git a/packages/schema/package.json b/packages/schema/package.json index d41f7b4ae..84c7b89a3 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -3,7 +3,7 @@ "publisher": "zenstack", "displayName": "ZenStack Language Tools", "description": "FullStack enhancement for Prisma ORM: seamless integration from database to UI", - "version": "2.18.0", + "version": "2.18.1", "author": { "name": "ZenStack Team" }, @@ -116,11 +116,11 @@ "zod-validation-error": "catalog:" }, "peerDependencies": { - "prisma": "5.0.0 - 6.13.x", + "prisma": "5.0.0 - 6.14.x", "zod": "catalog:" }, "devDependencies": { - "@prisma/client": "6.13.x", + "@prisma/client": "6.14.x", "@types/async-exit-hook": "^2.0.0", "@types/pluralize": "^0.0.29", "@types/semver": "^7.3.13", diff --git a/packages/sdk/package.json b/packages/sdk/package.json index cb930ee0a..27333338d 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/sdk", - "version": "2.18.0", + "version": "2.18.1", "description": "ZenStack plugin development SDK", "main": "index.js", "scripts": { @@ -18,8 +18,8 @@ "author": "", "license": "MIT", "dependencies": { - "@prisma/generator-helper": "6.13.x", - "@prisma/internals": "6.13.x", + "@prisma/generator-helper": "6.14.x", + "@prisma/internals": "6.14.x", "@zenstackhq/language": "workspace:*", "@zenstackhq/runtime": "workspace:*", "langium": "1.3.1", diff --git a/packages/server/package.json b/packages/server/package.json index aabc3f565..1e51dfa52 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/server", - "version": "2.18.0", + "version": "2.18.1", "displayName": "ZenStack Server-side Adapters", "description": "ZenStack server-side adapters", "homepage": "https://zenstack.dev", diff --git a/packages/testtools/package.json b/packages/testtools/package.json index 193117ff4..d1e9a04af 100644 --- a/packages/testtools/package.json +++ b/packages/testtools/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/testtools", - "version": "2.18.0", + "version": "2.18.1", "description": "ZenStack Test Tools", "main": "index.js", "private": true, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f3e40be76..19cf7f671 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -383,7 +383,7 @@ importers: packages/runtime: dependencies: '@prisma/client': - specifier: 5.0.0 - 6.13.x + specifier: 5.0.0 - 6.14.x version: 6.13.0(prisma@6.0.0)(typescript@5.9.2) bcryptjs: specifier: ^2.4.3 @@ -484,7 +484,7 @@ importers: specifier: ^4.0.0 version: 4.0.1 prisma: - specifier: 5.0.0 - 6.13.x + specifier: 5.0.0 - 6.14.x version: 6.0.0 semver: specifier: ^7.5.2 @@ -527,7 +527,7 @@ importers: version: 4.0.1(zod@3.25.76) devDependencies: '@prisma/client': - specifier: 6.13.x + specifier: 6.14.x version: 6.13.0(prisma@6.0.0)(typescript@5.9.2) '@types/async-exit-hook': specifier: ^2.0.0 @@ -579,10 +579,10 @@ importers: packages/sdk: dependencies: '@prisma/generator-helper': - specifier: 6.13.x + specifier: 6.14.x version: 6.13.0 '@prisma/internals': - specifier: 6.13.x + specifier: 6.14.x version: 6.13.0(typescript@5.9.2) '@zenstackhq/language': specifier: workspace:* diff --git a/tests/integration/test-run/package.json b/tests/integration/test-run/package.json index 48bf46f3f..e5aff4495 100644 --- a/tests/integration/test-run/package.json +++ b/tests/integration/test-run/package.json @@ -10,9 +10,9 @@ "author": "", "license": "ISC", "dependencies": { - "@prisma/client": "6.13.x", + "@prisma/client": "6.14.x", "@zenstackhq/runtime": "file:../../../packages/runtime/dist", - "prisma": "6.13.x", + "prisma": "6.14.x", "react": "^18.2.0", "swr": "^1.3.0", "zenstack": "file:../../../packages/schema/dist", diff --git a/tests/integration/tests/cli/plugins.test.ts b/tests/integration/tests/cli/plugins.test.ts index 7562f47b8..ffb841cd3 100644 --- a/tests/integration/tests/cli/plugins.test.ts +++ b/tests/integration/tests/cli/plugins.test.ts @@ -75,7 +75,7 @@ describe('CLI Plugins Tests', () => { 'swr', '@tanstack/react-query@5.56.x', '@trpc/server', - '@prisma/client@6.13.x', + '@prisma/client@6.14.x', `${path.join(__dirname, '../../../../.build/zenstackhq-language-' + ver + '.tgz')}`, `${path.join(__dirname, '../../../../.build/zenstackhq-sdk-' + ver + '.tgz')}`, `${path.join(__dirname, '../../../../.build/zenstackhq-runtime-' + ver + '.tgz')}`, @@ -85,7 +85,7 @@ describe('CLI Plugins Tests', () => { const devDepPkgs = [ 'typescript', '@types/react', - 'prisma@6.13.x', + 'prisma@6.14.x', `${path.join(__dirname, '../../../../.build/zenstack-' + ver + '.tgz')}`, `${path.join(__dirname, '../../../../.build/zenstackhq-tanstack-query-' + ver + '.tgz')}`, `${path.join(__dirname, '../../../../.build/zenstackhq-swr-' + ver + '.tgz')}`, diff --git a/tests/integration/tests/frameworks/nextjs/test-project/package.json b/tests/integration/tests/frameworks/nextjs/test-project/package.json index 8dc15c490..cae2a6a0a 100644 --- a/tests/integration/tests/frameworks/nextjs/test-project/package.json +++ b/tests/integration/tests/frameworks/nextjs/test-project/package.json @@ -9,7 +9,7 @@ "lint": "next lint" }, "dependencies": { - "@prisma/client": "6.13.x", + "@prisma/client": "6.14.x", "@types/node": "18.11.18", "@types/react": "18.0.27", "@types/react-dom": "18.0.10", @@ -26,6 +26,6 @@ "@zenstackhq/swr": "../../../../../../../packages/plugins/swr/dist" }, "devDependencies": { - "prisma": "6.13.x" + "prisma": "6.14.x" } } diff --git a/tests/integration/tests/frameworks/trpc/test-project/package.json b/tests/integration/tests/frameworks/trpc/test-project/package.json index eaafb9740..8b854c04e 100644 --- a/tests/integration/tests/frameworks/trpc/test-project/package.json +++ b/tests/integration/tests/frameworks/trpc/test-project/package.json @@ -9,7 +9,7 @@ "lint": "next lint" }, "dependencies": { - "@prisma/client": "6.13.x", + "@prisma/client": "6.14.x", "@tanstack/react-query": "^4.22.4", "@trpc/client": "^10.34.0", "@trpc/next": "^10.34.0", @@ -31,6 +31,6 @@ "@zenstackhq/trpc": "../../../../../../../packages/plugins/trpc/dist" }, "devDependencies": { - "prisma": "6.13.x" + "prisma": "6.14.x" } }