Skip to content

Commit

Permalink
merge dev to main (v2.8.1) (#1838)
Browse files Browse the repository at this point in the history
  • Loading branch information
ymc9 authored Nov 7, 2024
2 parents 59fe945 + 1bd1b8f commit d2554f2
Show file tree
Hide file tree
Showing 24 changed files with 294 additions and 43 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.8.0",
"version": "2.8.1",
"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.8.0"
version = "2.8.1"

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.8.0",
"version": "2.8.1",
"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.8.0",
"version": "2.8.1",
"displayName": "ZenStack modeling language compiler",
"description": "ZenStack modeling language compiler",
"homepage": "https://zenstack.dev",
Expand Down
23 changes: 17 additions & 6 deletions packages/language/src/generated/ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ export function isTypeDeclaration(item: unknown): item is TypeDeclaration {
return reflection.isInstance(item, TypeDeclaration);
}

export type TypeDefFieldTypes = Enum | TypeDef;

export const TypeDefFieldTypes = 'TypeDefFieldTypes';

export function isTypeDefFieldTypes(item: unknown): item is TypeDefFieldTypes {
return reflection.isInstance(item, TypeDefFieldTypes);
}

export interface Argument extends AstNode {
readonly $container: InvocationExpr;
readonly $type: 'Argument';
Expand Down Expand Up @@ -654,7 +662,7 @@ export interface TypeDefFieldType extends AstNode {
readonly $type: 'TypeDefFieldType';
array: boolean
optional: boolean
reference?: Reference<TypeDef>
reference?: Reference<TypeDefFieldTypes>
type?: BuiltinType
}

Expand Down Expand Up @@ -738,14 +746,15 @@ export type ZModelAstType = {
TypeDef: TypeDef
TypeDefField: TypeDefField
TypeDefFieldType: TypeDefFieldType
TypeDefFieldTypes: TypeDefFieldTypes
UnaryExpr: UnaryExpr
UnsupportedFieldType: UnsupportedFieldType
}

export class ZModelAstReflection extends AbstractAstReflection {

getAllTypes(): string[] {
return ['AbstractDeclaration', 'Argument', 'ArrayExpr', 'Attribute', 'AttributeArg', 'AttributeParam', 'AttributeParamType', 'BinaryExpr', 'BooleanLiteral', 'ConfigArrayExpr', 'ConfigExpr', 'ConfigField', 'ConfigInvocationArg', 'ConfigInvocationExpr', 'DataModel', 'DataModelAttribute', 'DataModelField', 'DataModelFieldAttribute', 'DataModelFieldType', 'DataSource', 'Enum', 'EnumField', 'Expression', 'FieldInitializer', 'FunctionDecl', 'FunctionParam', 'FunctionParamType', 'GeneratorDecl', 'InternalAttribute', 'InvocationExpr', 'LiteralExpr', 'MemberAccessExpr', 'Model', 'ModelImport', 'NullExpr', 'NumberLiteral', 'ObjectExpr', 'Plugin', 'PluginField', 'ReferenceArg', 'ReferenceExpr', 'ReferenceTarget', 'StringLiteral', 'ThisExpr', 'TypeDeclaration', 'TypeDef', 'TypeDefField', 'TypeDefFieldType', 'UnaryExpr', 'UnsupportedFieldType'];
return ['AbstractDeclaration', 'Argument', 'ArrayExpr', 'Attribute', 'AttributeArg', 'AttributeParam', 'AttributeParamType', 'BinaryExpr', 'BooleanLiteral', 'ConfigArrayExpr', 'ConfigExpr', 'ConfigField', 'ConfigInvocationArg', 'ConfigInvocationExpr', 'DataModel', 'DataModelAttribute', 'DataModelField', 'DataModelFieldAttribute', 'DataModelFieldType', 'DataSource', 'Enum', 'EnumField', 'Expression', 'FieldInitializer', 'FunctionDecl', 'FunctionParam', 'FunctionParamType', 'GeneratorDecl', 'InternalAttribute', 'InvocationExpr', 'LiteralExpr', 'MemberAccessExpr', 'Model', 'ModelImport', 'NullExpr', 'NumberLiteral', 'ObjectExpr', 'Plugin', 'PluginField', 'ReferenceArg', 'ReferenceExpr', 'ReferenceTarget', 'StringLiteral', 'ThisExpr', 'TypeDeclaration', 'TypeDef', 'TypeDefField', 'TypeDefFieldType', 'TypeDefFieldTypes', 'UnaryExpr', 'UnsupportedFieldType'];
}

protected override computeIsSubtype(subtype: string, supertype: string): boolean {
Expand Down Expand Up @@ -775,16 +784,18 @@ export class ZModelAstReflection extends AbstractAstReflection {
case ConfigArrayExpr: {
return this.isSubtype(ConfigExpr, supertype);
}
case DataModel:
case Enum:
case TypeDef: {
case DataModel: {
return this.isSubtype(AbstractDeclaration, supertype) || this.isSubtype(TypeDeclaration, supertype);
}
case DataModelField:
case EnumField:
case FunctionParam: {
return this.isSubtype(ReferenceTarget, supertype);
}
case Enum:
case TypeDef: {
return this.isSubtype(AbstractDeclaration, supertype) || this.isSubtype(TypeDeclaration, supertype) || this.isSubtype(TypeDefFieldTypes, supertype);
}
case InvocationExpr:
case LiteralExpr: {
return this.isSubtype(ConfigExpr, supertype) || this.isSubtype(Expression, supertype);
Expand Down Expand Up @@ -821,7 +832,7 @@ export class ZModelAstReflection extends AbstractAstReflection {
return ReferenceTarget;
}
case 'TypeDefFieldType:reference': {
return TypeDef;
return TypeDefFieldTypes;
}
default: {
throw new Error(`${referenceId} is not a valid reference id.`);
Expand Down
31 changes: 26 additions & 5 deletions packages/language/src/generated/grammar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2165,7 +2165,7 @@ export const ZModelGrammar = (): Grammar => loadedZModelGrammar ?? (loadedZModel
"terminal": {
"$type": "CrossReference",
"type": {
"$ref": "#/types@1"
"$ref": "#/types@2"
},
"terminal": {
"$type": "RuleCall",
Expand Down Expand Up @@ -2267,7 +2267,7 @@ export const ZModelGrammar = (): Grammar => loadedZModelGrammar ?? (loadedZModel
},
"arguments": []
},
"cardinality": "+"
"cardinality": "*"
},
{
"$type": "Keyword",
Expand Down Expand Up @@ -2375,7 +2375,7 @@ export const ZModelGrammar = (): Grammar => loadedZModelGrammar ?? (loadedZModel
"terminal": {
"$type": "CrossReference",
"type": {
"$ref": "#/rules@40"
"$ref": "#/types@1"
},
"terminal": {
"$type": "RuleCall",
Expand Down Expand Up @@ -2827,7 +2827,7 @@ export const ZModelGrammar = (): Grammar => loadedZModelGrammar ?? (loadedZModel
"terminal": {
"$type": "CrossReference",
"type": {
"$ref": "#/types@1"
"$ref": "#/types@2"
},
"terminal": {
"$type": "RuleCall",
Expand Down Expand Up @@ -3255,7 +3255,7 @@ export const ZModelGrammar = (): Grammar => loadedZModelGrammar ?? (loadedZModel
"terminal": {
"$type": "CrossReference",
"type": {
"$ref": "#/types@1"
"$ref": "#/types@2"
},
"terminal": {
"$type": "RuleCall",
Expand Down Expand Up @@ -3838,6 +3838,27 @@ export const ZModelGrammar = (): Grammar => loadedZModelGrammar ?? (loadedZModel
]
}
},
{
"$type": "Type",
"name": "TypeDefFieldTypes",
"type": {
"$type": "UnionType",
"types": [
{
"$type": "SimpleType",
"typeRef": {
"$ref": "#/rules@40"
}
},
{
"$type": "SimpleType",
"typeRef": {
"$ref": "#/rules@44"
}
}
]
}
},
{
"$type": "Type",
"name": "TypeDeclaration",
Expand Down
8 changes: 5 additions & 3 deletions packages/language/src/zmodel.langium
Original file line number Diff line number Diff line change
Expand Up @@ -183,15 +183,17 @@ TypeDef:
(comments+=TRIPLE_SLASH_COMMENT)*
'type' name=RegularID '{' (
fields+=TypeDefField
)+
)*
'}';

type TypeDefFieldTypes = TypeDef | Enum;

TypeDefField:
(comments+=TRIPLE_SLASH_COMMENT)*
(comments+=TRIPLE_SLASH_COMMENT)*
name=RegularIDWithTypeNames type=TypeDefFieldType (attributes+=DataModelFieldAttribute)*;

TypeDefFieldType:
(type=BuiltinType | reference=[TypeDef:RegularID]) (array?='[' ']')? (optional?='?')?;
(type=BuiltinType | reference=[TypeDefFieldTypes:RegularID]) (array?='[' ']')? (optional?='?')?;

UnsupportedFieldType:
'Unsupported' '(' (value=LiteralExpr) ')';
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.8.0",
"version": "2.8.1",
"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.8.0",
"version": "2.8.1",
"description": "ZenStack plugin and runtime supporting OpenAPI",
"main": "index.js",
"repository": {
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.8.0",
"version": "2.8.1",
"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.8.0",
"version": "2.8.1",
"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.8.0",
"version": "2.8.1",
"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.8.0",
"version": "2.8.1",
"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.8.0",
"version": "2.8.1",
"author": {
"name": "ZenStack Team"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
isTypeDef,
} from '@zenstackhq/language/ast';
import {
getDataSourceProvider,
getModelFieldsWithBases,
getModelIdFields,
getModelUniqueFields,
Expand Down Expand Up @@ -108,10 +107,6 @@ export default class DataModelValidator implements AstValidator<DataModel> {
if (!hasAttribute(field, '@json')) {
accept('error', 'Custom-typed field must have @json attribute', { node: field });
}

if (getDataSourceProvider(field.$container.$container) !== 'postgresql') {
accept('error', 'Custom-typed field is only supported with "postgresql" provider', { node: field });
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { PluginError } from '@zenstackhq/sdk';
import { BuiltinType, TypeDef, TypeDefFieldType } from '@zenstackhq/sdk/ast';
import { getDataModels, PluginError } from '@zenstackhq/sdk';
import { BuiltinType, Enum, isEnum, TypeDef, TypeDefFieldType } from '@zenstackhq/sdk/ast';
import { SourceFile } from 'ts-morph';
import { match } from 'ts-pattern';
import { name } from '..';
Expand Down Expand Up @@ -36,7 +36,11 @@ function zmodelTypeToTsType(type: TypeDefFieldType) {
if (type.type) {
result = builtinTypeToTsType(type.type);
} else if (type.reference?.ref) {
result = type.reference.ref.name;
if (isEnum(type.reference.ref)) {
result = makeEnumTypeReference(type.reference.ref);
} else {
result = type.reference.ref.name;
}
} else {
throw new PluginError(name, `Unsupported field type: ${type}`);
}
Expand All @@ -61,3 +65,17 @@ function builtinTypeToTsType(type: BuiltinType) {
.with('Json', () => 'unknown')
.exhaustive();
}

function makeEnumTypeReference(enumDecl: Enum) {
const zmodel = enumDecl.$container;
const models = getDataModels(zmodel);

if (models.some((model) => model.fields.some((field) => field.type.reference?.ref === enumDecl))) {
// if the enum is referenced by any data model, Prisma already generates its type,
// we just need to reference it
return enumDecl.name;
} else {
// otherwise, we need to inline the enum
return enumDecl.fields.map((field) => `'${field.name}'`).join(' | ');
}
}
10 changes: 10 additions & 0 deletions packages/schema/src/plugins/prisma/schema-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
getAttribute,
getAttributeArg,
getAttributeArgLiteral,
getDataSourceProvider,
getInheritedFromDelegate,
getLiteral,
getRelationKeyPairs,
Expand Down Expand Up @@ -81,6 +82,7 @@ import {
const MODEL_PASSTHROUGH_ATTR = '@@prisma.passthrough';
const FIELD_PASSTHROUGH_ATTR = '@prisma.passthrough';
const PROVIDERS_SUPPORTING_NAMED_CONSTRAINTS = ['postgresql', 'mysql', 'cockroachdb'];
const PROVIDERS_SUPPORTING_TYPEDEF_FIELDS = ['postgresql'];

// Some database providers like postgres and mysql have default limit to the length of identifiers
// Here we use a conservative value that should work for most cases, and truncate names if needed
Expand Down Expand Up @@ -794,6 +796,7 @@ export class PrismaSchemaGenerator {
} else if (field.type.reference?.ref) {
// model, enum, or type-def
if (isTypeDef(field.type.reference.ref)) {
this.ensureSupportingTypeDefFields(this.zmodel);
fieldType = 'Json';
} else {
fieldType = field.type.reference.ref.name;
Expand Down Expand Up @@ -846,6 +849,13 @@ export class PrismaSchemaGenerator {
return result;
}

private ensureSupportingTypeDefFields(zmodel: Model) {
const dsProvider = getDataSourceProvider(zmodel);
if (dsProvider && !PROVIDERS_SUPPORTING_TYPEDEF_FIELDS.includes(dsProvider)) {
throw new PluginError(name, `Datasource provider "${dsProvider}" does not support "@json" fields`);
}
}

private setDummyDefault(result: ModelField, field: DataModelField) {
const dummyDefaultValue = match(field.type.type)
.with('String', () => new AttributeArgValue('String', ''))
Expand Down
Loading

0 comments on commit d2554f2

Please sign in to comment.