Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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 LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2022 ZenStack
Copyright (c) 2022-2025 ZenStack

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
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-monorepo",
"version": "2.18.1",
"version": "2.19.0",
"description": "",
"scripts": {
"build": "pnpm -r --filter=\"!./packages/ide/*\" build",
Expand Down
2 changes: 1 addition & 1 deletion packages/LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2022 ZenStack
Copyright (c) 2022-2025 ZenStack

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
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.18.1"
version = "2.19.0"

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.18.1",
"version": "2.19.0",
"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.18.1",
"version": "2.19.0",
"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.18.1",
"version": "2.19.0",
"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.18.1",
"version": "2.19.0",
"description": "ZenStack plugin and runtime supporting OpenAPI",
"main": "index.js",
"repository": {
Expand Down
4 changes: 2 additions & 2 deletions packages/plugins/openapi/src/generator-base.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { getZodErrorMessage } from '@zenstackhq/runtime/local-helpers';
import { PluginError, getDataModels, hasAttribute, type PluginOptions, type PluginResult } from '@zenstackhq/sdk';
import { Model } from '@zenstackhq/sdk/ast';
import type { DMMF } from '@zenstackhq/sdk/prisma';
import type { OpenAPIV3_1 as OAPI } from 'openapi-types';
import semver from 'semver';
import { fromZodError } from 'zod-validation-error/v3';
import { name } from '.';
import { SecuritySchemesSchema } from './schema';

Expand Down Expand Up @@ -94,7 +94,7 @@ export abstract class OpenAPIGeneratorBase {
if (securitySchemes) {
const parsed = SecuritySchemesSchema.safeParse(securitySchemes);
if (!parsed.success) {
throw new PluginError(name, `"securitySchemes" option is invalid: ${fromZodError(parsed.error)}`);
throw new PluginError(name, `"securitySchemes" option is invalid: ${getZodErrorMessage(parsed.error)}`);
}
return parsed.data;
}
Expand Down
30 changes: 21 additions & 9 deletions packages/plugins/openapi/src/rpc-generator.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
// Inspired by: https://github.com/omar-dulaimi/prisma-trpc-generator

import { PluginError, PluginOptions, analyzePolicies, requireOption, resolvePath } from '@zenstackhq/sdk';
import { DataModel, Model, TypeDef, TypeDefField, TypeDefFieldType, isDataModel, isEnum, isTypeDef } from '@zenstackhq/sdk/ast';
import {
DataModel,
Model,
TypeDef,
TypeDefField,
TypeDefFieldType,
isDataModel,
isEnum,
isTypeDef,
} from '@zenstackhq/sdk/ast';
import {
AggregateOperationSupport,
addMissingInputObjectTypesForAggregate,
Expand Down Expand Up @@ -48,7 +57,7 @@ export class RPCOpenAPIGenerator extends OpenAPIGeneratorBase {
output = resolvePath(output, this.options);

// input types
this.inputObjectTypes.push(...this.dmmf.schema.inputObjectTypes.prisma);
this.inputObjectTypes.push(...(this.dmmf.schema.inputObjectTypes.prisma ?? []));
this.outputObjectTypes.push(...this.dmmf.schema.outputObjectTypes.prisma);

// add input object types that are missing from Prisma dmmf
Expand Down Expand Up @@ -649,13 +658,13 @@ 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)
enum: enumDecl.fields.map((f) => f.name),
};
}
}
Expand Down Expand Up @@ -765,12 +774,15 @@ export class RPCOpenAPIGenerator extends OpenAPIGeneratorBase {
return result;
}

private generateField(def: { kind: DMMF.FieldKind; type: string; isList: boolean; isRequired: boolean; name?: string }, modelName?: string) {
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;
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);
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(
Expand Down Expand Up @@ -876,7 +888,7 @@ export class RPCOpenAPIGenerator extends OpenAPIGeneratorBase {
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)
Expand Down Expand Up @@ -913,7 +925,7 @@ export class RPCOpenAPIGenerator extends OpenAPIGeneratorBase {
.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);
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));
Expand Down
9 changes: 5 additions & 4 deletions packages/plugins/openapi/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import z from 'zod';
* Zod schema for OpenAPI security schemes: https://swagger.io/docs/specification/authentication/
*/
export const SecuritySchemesSchema = z.record(
z.string(),
z.union([
z.object({ type: z.literal('http'), scheme: z.literal('basic') }),
z.object({ type: z.literal('http'), scheme: z.literal('bearer'), bearerFormat: z.string().optional() }),
Expand All @@ -20,22 +21,22 @@ export const SecuritySchemesSchema = z.record(
authorizationUrl: z.string(),
tokenUrl: z.string(),
refreshUrl: z.string(),
scopes: z.record(z.string()),
scopes: z.record(z.string(), z.string()),
}),
implicit: z.object({
authorizationUrl: z.string(),
refreshUrl: z.string(),
scopes: z.record(z.string()),
scopes: z.record(z.string(), z.string()),
}),
password: z.object({
tokenUrl: z.string(),
refreshUrl: z.string(),
scopes: z.record(z.string()),
scopes: z.record(z.string(), z.string()),
}),
clientCredentials: z.object({
tokenUrl: z.string(),
refreshUrl: z.string(),
scopes: z.record(z.string()),
scopes: z.record(z.string(), z.string()),
}),
}),
}),
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.18.1",
"version": "2.19.0",
"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.18.1",
"version": "2.19.0",
"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.18.1",
"version": "2.19.0",
"description": "ZenStack plugin for tRPC",
"main": "index.js",
"repository": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"postinstall": "nuxt prepare"
},
"dependencies": {
"@prisma/client": "6.14.x",
"@prisma/client": "6.16.x",
"@trpc/client": "^10.45.2",
"@trpc/server": "^10.45.2",
"nuxt": "^3.14.1592",
Expand All @@ -21,7 +21,7 @@
},
"devDependencies": {
"esbuild": "^0.24.0",
"prisma": "6.14.x",
"prisma": "6.16.x",
"typescript": "^5.6.2",
"vue-tsc": "^2.1.10"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"postinstall": "nuxt prepare"
},
"dependencies": {
"@prisma/client": "6.14.x",
"@prisma/client": "6.16.x",
"@trpc/client": "^11.0.0-rc.563",
"@trpc/server": "^11.0.0-rc.563",
"nuxt": "^3.14.1592",
Expand All @@ -21,7 +21,7 @@
},
"devDependencies": {
"esbuild": "^0.24.0",
"prisma": "6.14.x",
"prisma": "6.16.x",
"typescript": "^5.6.2",
"vue-tsc": "^2.1.10"
}
Expand Down
4 changes: 2 additions & 2 deletions packages/plugins/trpc/tests/projects/t3-trpc-v10/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
"dependencies": {
"@prisma/client": "6.0.x",
"@t3-oss/env-nextjs": "^0.7.1",
"@t3-oss/env-nextjs": "^0.13.1",
"@tanstack/react-query": "^4.36.1",
"@trpc/client": "^10.43.6",
"@trpc/next": "^10.43.6",
Expand All @@ -24,7 +24,7 @@
"react": "18.2.0",
"react-dom": "18.2.0",
"superjson": "^2.2.1",
"zod": "^3.22.4"
"zod": "^3.25.0"
},
"devDependencies": {
"@types/eslint": "^8.44.7",
Expand Down
Loading
Loading