Skip to content

Commit

Permalink
merge dev to main (#235)
Browse files Browse the repository at this point in the history
  • Loading branch information
ymc9 authored Mar 4, 2023
2 parents 5aae301 + 88828e3 commit fa75f59
Show file tree
Hide file tree
Showing 16 changed files with 109 additions and 37 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": "1.0.0-alpha.53",
"version": "1.0.0-alpha.55",
"description": "",
"scripts": {
"build": "pnpm -r build",
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": "1.0.0-alpha.53",
"version": "1.0.0-alpha.55",
"displayName": "ZenStack modeling language compiler",
"description": "ZenStack modeling language compiler",
"homepage": "https://zenstack.dev",
Expand Down
2 changes: 1 addition & 1 deletion packages/next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/next",
"version": "1.0.0-alpha.53",
"version": "1.0.0-alpha.55",
"displayName": "ZenStack Next.js integration",
"description": "ZenStack Next.js integration",
"homepage": "https://zenstack.dev",
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/react/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/react",
"displayName": "ZenStack plugin and runtime for ReactJS",
"version": "1.0.0-alpha.53",
"version": "1.0.0-alpha.55",
"description": "ZenStack plugin and runtime for ReactJS",
"main": "index.js",
"repository": {
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": "1.0.0-alpha.53",
"version": "1.0.0-alpha.55",
"description": "ZenStack plugin for tRPC",
"main": "index.js",
"repository": {
Expand Down
3 changes: 1 addition & 2 deletions 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": "1.0.0-alpha.53",
"version": "1.0.0-alpha.55",
"description": "Runtime of ZenStack for both client-side and server-side environments.",
"repository": {
"type": "git",
Expand Down Expand Up @@ -29,7 +29,6 @@
"decimal.js": "^10.4.2",
"deepcopy": "^2.1.0",
"superjson": "^1.11.0",
"swr": "^1.3.0",
"tslib": "^2.4.1",
"zod": "^3.19.1",
"zod-validation-error": "^0.2.1"
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": "A toolkit for building secure CRUD apps with Next.js + Typescript",
"version": "1.0.0-alpha.53",
"version": "1.0.0-alpha.55",
"author": {
"name": "ZenStack Team"
},
Expand Down
41 changes: 29 additions & 12 deletions packages/schema/src/language-server/validator/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
DataModelAttribute,
DataModelField,
DataModelFieldAttribute,
Expression,
ExpressionType,
isArrayExpr,
isAttribute,
Expand Down Expand Up @@ -54,10 +55,21 @@ export function getStringLiteral(node: AstNode | undefined): string | undefined
}
}

const isoDateTimeRegex = /^\d{4}(-\d\d(-\d\d(T\d\d:\d\d(:\d\d)?(\.\d+)?(([+-]\d\d:\d\d)|Z)?)?)?)?$/i;

/**
* Determines if the given sourceType is assignable to a destination of destType
*/
export function typeAssignable(destType: ExpressionType, sourceType: ExpressionType): boolean {
export function typeAssignable(destType: ExpressionType, sourceType: ExpressionType, sourceExpr?: Expression): boolean {
// implicit conversion from ISO datetime string to datetime
if (destType === 'DateTime' && sourceType === 'String' && sourceExpr && isLiteralExpr(sourceExpr)) {
const literal = getStringLiteral(sourceExpr);
if (literal && isoDateTimeRegex.test(literal)) {
// implicitly convert to DateTime
sourceType = 'DateTime';
}
}

switch (destType) {
case 'Any':
return true;
Expand Down Expand Up @@ -108,6 +120,19 @@ export function assignableToAttributeParam(
let dstIsArray = param.type.array;
const dstRef = param.type.reference;

// destination is field reference or transitive field reference, check if
// argument is reference or array or reference
if (dstType === 'FieldReference' || dstType === 'TransitiveFieldReference') {
if (dstIsArray) {
return (
isArrayExpr(arg.value) &&
!arg.value.items.find((item) => !isReferenceExpr(item) || !isDataModelField(item.target.ref))
);
} else {
return isReferenceExpr(arg.value) && isDataModelField(arg.value.target.ref);
}
}

if (isEnum(argResolvedType.decl)) {
// enum type

Expand All @@ -127,16 +152,7 @@ export function assignableToAttributeParam(
return false;
}

if (dstType === 'FieldReference' || dstType === 'TransitiveFieldReference') {
if (dstIsArray) {
return (
isArrayExpr(arg.value) &&
!arg.value.items.find((item) => !isReferenceExpr(item) || !isDataModelField(item.target.ref))
);
} else {
return isReferenceExpr(arg.value) && isDataModelField(arg.value.target.ref);
}
} else if (dstType === 'ContextType') {
if (dstType === 'ContextType') {
// attribute parameter type is ContextType, need to infer type from
// the attribute's container
if (isDataModelField(attr.$container)) {
Expand All @@ -151,7 +167,8 @@ export function assignableToAttributeParam(
}

return (
typeAssignable(dstType, argResolvedType.decl) && (dstType === 'Any' || dstIsArray === argResolvedType.array)
typeAssignable(dstType, argResolvedType.decl, arg.value) &&
(dstType === 'Any' || dstIsArray === argResolvedType.array)
);
} else {
// reference type
Expand Down
8 changes: 7 additions & 1 deletion packages/schema/src/plugins/prisma/prisma-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,13 @@ export class FunctionCallArg {
constructor(public name: string | undefined, public value: any) {}

toString(): string {
return this.name ? `${this.name}: ${this.value}` : this.value;
const val =
this.value === null || this.value === undefined
? 'null'
: typeof this.value === 'string'
? `"${this.value}"`
: this.value.toString();
return this.name ? `${this.name}: ${val}` : val;
}
}

Expand Down
12 changes: 12 additions & 0 deletions packages/schema/tests/generator/prisma-builder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
FieldReference,
FieldReferenceArg,
FunctionCall,
FunctionCallArg,
ModelFieldType,
PrismaModel,
} from '../../src/plugins/prisma/prisma-builder';
Expand Down Expand Up @@ -94,6 +95,17 @@ describe('Prisma Builder Tests', () => {
post.addField('id', 'String', [new FieldAttribute('@id')]);
post.addField('slug', 'String');
post.addField('space', 'String');
post.addField('tsid', 'String', [
new FieldAttribute('@default', [
new AttributeArg(
undefined,
new AttributeArgValue(
'FunctionCall',
new FunctionCall('dbgenerated', [new FunctionCallArg(undefined, 'timestamp_id()')])
)
),
]),
]);
post.addAttribute('@@unique', [
new AttributeArg(
'fields',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,34 @@ describe('Attribute tests', () => {
}
`)
).toContain(`Attribute "@default" doesn't have a parameter named "foo"`);

expect(
await loadModelWithError(`
${prelude}
model M {
id String @id()
dt DateTime @default('2020abc')
}
`)
).toContain('Value is not assignable to parameter');

// auto-convert of string to date time
await loadModel(`
${prelude}
model M {
id String @id()
dt DateTime @default('2000-01-01T00:00:00Z')
}
`);

// auto-convert of string to bytes
await loadModel(`
${prelude}
model M {
id String @id()
dt Bytes @default('abc123')
}
`);
});

it('field attribute coverage', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,5 +370,27 @@ describe('Data Model Validation Tests', () => {
}
`)
).toContain(`Could not resolve reference to ReferenceTarget named 'aId'.`);

// enum as foreign key
await loadModel(`
${prelude}
enum Role {
ADMIN
USER
}
model A {
id String @id
role Role @unique
bs B[]
}
model B {
id String @id
a A @relation(fields: [aRole], references: [role])
aRole Role
}
`);
});
});
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": "1.0.0-alpha.53",
"version": "1.0.0-alpha.55",
"description": "ZenStack plugin development SDK",
"main": "index.js",
"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": "1.0.0-alpha.53",
"version": "1.0.0-alpha.55",
"description": "ZenStack Test Tools",
"main": "index.js",
"publishConfig": {
Expand Down
10 changes: 0 additions & 10 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 2 additions & 4 deletions tests/integration/test-run/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit fa75f59

Please sign in to comment.