Skip to content

Commit

Permalink
fix(compatibility): Make model types compatible from both sides Prism…
Browse files Browse the repository at this point in the history
…a and GraphQL

close: unlight#41
  • Loading branch information
unlight committed Jul 23, 2021
1 parent 0703f7e commit c015f12
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 134 deletions.
8 changes: 8 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ model User {
countComments Int?
rating Float?
role Role?
profile Profile?
}

model Tag {
Expand Down Expand Up @@ -87,6 +88,13 @@ enum Role {
USER
}

model Profile {
id Int @id @default(autoincrement())
user User @relation(fields: [userId], references: [id])
userId String
dummy String?
}

model Dummy {
id String @id
created DateTime @default(now())
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/model-output-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ export function modelOutputType(outputType: OutputType, args: EventArguments) {
name: field.name,
isNullable: field.isNullable,
hasExclamationToken: true,
hasQuestionToken: false,
hasQuestionToken: location === 'outputObjectTypes',
propertyType,
isList,
});
Expand Down
5 changes: 4 additions & 1 deletion src/helpers/get-property-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ export function getPropertyType(args: {
case 'BigInt':
return ['bigint', 'number'];
}
if (['inputObjectTypes', 'outputObjectTypes', 'enumTypes'].includes(location)) {
if (['inputObjectTypes', 'outputObjectTypes'].includes(location)) {
return [type];
}
if (location === 'enumTypes') {
return [`keyof typeof ${type}`];
}
if (location === 'scalar') {
return [type];
}
Expand Down
184 changes: 64 additions & 120 deletions src/test/compatibility.ts
Original file line number Diff line number Diff line change
@@ -1,223 +1,167 @@
/* eslint-disable prefer-const, unicorn/no-null */
import { Prisma, PrismaClient } from '@prisma/client';
import * as P from '@prisma/client';
import { Decimal } from 'decimal.js';

import { Comment } from '../@generated/comment/comment.model';
import { Dummy } from '../@generated/dummy/dummy.model';
import { DummyCreateInput } from '../@generated/dummy/dummy-create.input';
import { DateTimeFilter } from '../@generated/prisma/date-time-filter.input';
import { FloatFilter } from '../@generated/prisma/float-filter.input';
import { IntFilter } from '../@generated/prisma/int-filter.input';
import { StringFilter } from '../@generated/prisma/string-filter.input';
import { UserAggregateArgs } from '../@generated/prisma/user-aggregate.args';
import { FindManyUserArgs } from '../@generated/user/find-many-user.args';
import { User } from '../@generated/user/user.model';
import { UserAggregateArgs } from '../@generated/user/user-aggregate.args';
import { UserCreateInput } from '../@generated/user/user-create.input';
import { UserCreateWithoutArticlesInput } from '../@generated/user/user-create-without-articles.input';
import { UserCreateWithoutCommentsInput } from '../@generated/user/user-create-without-comments.input';
import { UserGroupByArgs } from '../@generated/user/user-group-by.args';
import { UserListRelationFilter } from '../@generated/user/user-list-relation-filter.input';
import { UserMaxOrderByAggregateInput } from '../@generated/user/user-max-order-by-aggregate.input';
import { UserScalarFieldEnum } from '../@generated/user/user-scalar-field.enum';
import { UserWhereInput } from '../@generated/user/user-where.input';

const $prisma = new PrismaClient();
let $prisma = new PrismaClient();

{
const t: Array<Date> | Array<string> = [];
const m: Array<Date | string> = t; // t => m will fail
let p: P.User = {} as unknown as P.User;
let o: User = {} as unknown as User;
o = p;
p = o;
}
{
let t: Array<Date> | Array<string> = [];
let m: Array<Date | string> = t; // t => m will fail
m;
}
{
// Scalar filter
const x: IntFilter = {};
let x: IntFilter = {};
let p: Prisma.IntFilter = {};
p = x;
p; // x = p fail (enumerable)
}
{
// Scalar filter
const x: DateTimeFilter = {};
let x: DateTimeFilter = {};
let p: Prisma.DateTimeFilter = {};
p = x;
p;
}
{
// Scalar filter
const x: StringFilter = {};
let x: StringFilter = {};
let p: Prisma.StringFilter = {};
p = x;
p;
}
{
// Nullable filter
const x: FloatFilter = {};
let x: FloatFilter = {};
let p: Prisma.FloatNullableFilter = {};
p = x;
p;
}
{
const x: UserWhereInput = {};
let x: UserWhereInput = {};
let p: Prisma.UserWhereInput = {};
p = x;
p;
$prisma.user.findMany({ where: x });
}
{
const x: UserListRelationFilter = {};
let x: UserListRelationFilter = {};
let p: Prisma.UserListRelationFilter = {};
p = x;
p;
}
{
const x: FindManyUserArgs = {};
let x: FindManyUserArgs = {};
let p: Prisma.UserFindManyArgs = {};
p = x;
p;
$prisma.user.findMany(x);
}
{
const x: UserCreateWithoutArticlesInput = {
email: '',
name: '',
password: '',
};
let p: Prisma.UserCreateWithoutArticlesInput = {
email: '',
name: '',
password: '',
};
let x: UserCreateWithoutArticlesInput =
{} as unknown as UserCreateWithoutArticlesInput;
let p: Prisma.UserCreateWithoutArticlesInput =
{} as unknown as Prisma.UserCreateWithoutArticlesInput;
p = x;
p;
$prisma.user.create({
data: x,
});
}
{
const x: UserCreateWithoutCommentsInput = {
email: '',
name: '',
password: '',
};
let p: Prisma.UserCreateWithoutCommentsInput = {
email: '',
name: '',
password: '',
};
let x: UserCreateWithoutCommentsInput =
{} as unknown as UserCreateWithoutCommentsInput;
let p: Prisma.UserCreateWithoutCommentsInput =
{} as unknown as Prisma.UserCreateWithoutCommentsInput;
p = x;
p;
$prisma.user.create({
data: x,
});
}
{
const x: UserAggregateArgs = {};
let x: UserAggregateArgs = {};
let p: Prisma.UserAggregateArgs = {};
p = x;
p;
x;
}
{
const x: UserGroupByArgs = {
let x: UserGroupByArgs = {
by: ['id'] as UserScalarFieldEnum[],
};
let p: Prisma.UserGroupByArgs = {
by: ['id'] as UserScalarFieldEnum[],
};
p = x;
p;
x;
}
{
const x: DummyCreateInput = { id: '1', floaty: 1 };
let x: DummyCreateInput = { id: '1', floaty: 1 };
let p: Prisma.DummyCreateInput = { id: '2', floaty: 2 };
p = x;
p;
x;
}
{
const x: DummyCreateInput['json'] = {};
let x: DummyCreateInput['json'] = {};
let p: Prisma.DummyCreateInput['json'] = {};
p = x;
p;
}
{
const x: UserCreateInput = {
email: '',
name: '',
password: '',
};
let p: Prisma.UserCreateInput = {
email: '',
name: '',
password: '',
};
let x: UserMaxOrderByAggregateInput = {};
let p: Prisma.UserMaxOrderByAggregateInput = {};
p = x; // To prisma
x = p; // To object type
}
{
let x: UserCreateInput = {} as unknown as UserCreateInput;
let p: Prisma.UserCreateInput = {} as unknown as Prisma.UserCreateInput;
p = x;
p;
}
{
// $prisma.user.groupBy({ by: ['name'], count: { _all: true } }).then(([user]) => {
// user.name;
// user.count;
// });
}
// {
// // incompatible
// let x: User = {
// id: '',
// email: '',
// name: '',
// password: '',
// };
// let p: P.User = {
// id: '',
// email: '',
// name: '',
// password: '',
// bio: null,
// image: null,
// countComments: null,
// rating: null,
// role: null,
// };
// x = p;
// }
{
// OK
// const x: RDecimal = new RDecimal(0);
// let p: Prisma.Decimal = new Prisma.Decimal(0);
// p = x;
}
{
// Fails
// const x: Decimal = new Decimal(0);
// let p: Prisma.Decimal = new Prisma.Decimal(0);
// p = x;
}
{
// Fails
// const x: Prisma.Decimal = new Prisma.Decimal(0);
// let p: Decimal = new Decimal(0);
// p = x;
}
{
const x: Dummy = {
id: '',
created: new Date(),
floaty: 1,
int: 1,
float: 1,
bytes: Buffer.from('b'),
// eslint-disable-next-line unicorn/no-null
decimal: '0.1',
bigInt: BigInt('1'),
json: {},
friends: [],
};
let p: P.Dummy = {
id: '',
created: new Date(),
floaty: 1,
int: 1,
float: 1,
bytes: Buffer.from('b'),
// eslint-disable-next-line unicorn/no-null
decimal: new Prisma.Decimal(0),
bigInt: BigInt('1'),
json: {},
friends: [],
};
let x: Dummy = {} as unknown as Dummy;
let p: P.Dummy = {} as unknown as P.Dummy;
p = x;
x = p;
}
{
const x: UserGroupByArgs = {
let x: UserGroupByArgs = {
by: [UserScalarFieldEnum.id],
};
let p: Prisma.UserGroupByArgs = {
by: [UserScalarFieldEnum.id],
};
p = x;
// $prisma.user.groupBy(x); // Error
p;
// x = p; // fails (enumerable)
// $prisma.user.groupBy(x); // Error (prisma issue https://github.com/unlight/prisma-nestjs-graphql/issues/31)
// $prisma.user.groupBy(p); // Error
}
Loading

0 comments on commit c015f12

Please sign in to comment.