diff --git a/src/@generated/prisma/enum-role-field-update-operations.input.ts b/src/@generated/prisma/enum-role-field-update-operations.input.ts deleted file mode 100644 index ca8db53c..00000000 --- a/src/@generated/prisma/enum-role-field-update-operations.input.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Field, InputType } from '@nestjs/graphql'; - -import { Role } from './role.enum'; - -@InputType() -export class EnumRoleFieldUpdateOperationsInput { - @Field(() => Role, { - nullable: true, - description: undefined, - }) - set?: Role | null; -} diff --git a/src/@generated/user/user-update-many-mutation.input.ts b/src/@generated/user/user-update-many-mutation.input.ts index ab7fd2fb..4c717051 100644 --- a/src/@generated/user/user-update-many-mutation.input.ts +++ b/src/@generated/user/user-update-many-mutation.input.ts @@ -1,6 +1,5 @@ import { Field, Float, InputType, Int } from '@nestjs/graphql'; -import { EnumRoleFieldUpdateOperationsInput } from '../prisma/enum-role-field-update-operations.input'; import { Role } from '../prisma/role.enum'; @InputType() @@ -53,9 +52,9 @@ export class UserUpdateManyMutationInput { }) rating?: number | null; - @Field(() => EnumRoleFieldUpdateOperationsInput, { + @Field(() => Role, { nullable: true, description: undefined, }) - role?: Role | EnumRoleFieldUpdateOperationsInput | null; + role?: Role | null; } diff --git a/src/@generated/user/user-update-without-articles.input.ts b/src/@generated/user/user-update-without-articles.input.ts index 954f0294..8b1b06b3 100644 --- a/src/@generated/user/user-update-without-articles.input.ts +++ b/src/@generated/user/user-update-without-articles.input.ts @@ -2,7 +2,6 @@ import { Field, Float, InputType, Int } from '@nestjs/graphql'; import { ArticleUpdateManyWithoutFavoritedByInput } from '../article/article-update-many-without-favorited-by.input'; import { CommentUpdateManyWithoutAuthorInput } from '../comment/comment-update-many-without-author.input'; -import { EnumRoleFieldUpdateOperationsInput } from '../prisma/enum-role-field-update-operations.input'; import { Role } from '../prisma/role.enum'; import { UserUpdateManyWithoutFollowersInput } from './user-update-many-without-followers.input'; import { UserUpdateManyWithoutFollowingInput } from './user-update-many-without-following.input'; @@ -57,11 +56,11 @@ export class UserUpdateWithoutArticlesInput { }) rating?: number | null; - @Field(() => EnumRoleFieldUpdateOperationsInput, { + @Field(() => Role, { nullable: true, description: undefined, }) - role?: Role | EnumRoleFieldUpdateOperationsInput | null; + role?: Role | null; @Field(() => UserUpdateManyWithoutFollowersInput, { nullable: true, diff --git a/src/@generated/user/user-update-without-comments.input.ts b/src/@generated/user/user-update-without-comments.input.ts index 7e8492ff..c0276617 100644 --- a/src/@generated/user/user-update-without-comments.input.ts +++ b/src/@generated/user/user-update-without-comments.input.ts @@ -2,7 +2,6 @@ import { Field, Float, InputType, Int } from '@nestjs/graphql'; import { ArticleUpdateManyWithoutAuthorInput } from '../article/article-update-many-without-author.input'; import { ArticleUpdateManyWithoutFavoritedByInput } from '../article/article-update-many-without-favorited-by.input'; -import { EnumRoleFieldUpdateOperationsInput } from '../prisma/enum-role-field-update-operations.input'; import { Role } from '../prisma/role.enum'; import { UserUpdateManyWithoutFollowersInput } from './user-update-many-without-followers.input'; import { UserUpdateManyWithoutFollowingInput } from './user-update-many-without-following.input'; @@ -57,11 +56,11 @@ export class UserUpdateWithoutCommentsInput { }) rating?: number | null; - @Field(() => EnumRoleFieldUpdateOperationsInput, { + @Field(() => Role, { nullable: true, description: undefined, }) - role?: Role | EnumRoleFieldUpdateOperationsInput | null; + role?: Role | null; @Field(() => UserUpdateManyWithoutFollowersInput, { nullable: true, diff --git a/src/@generated/user/user-update-without-favorite-articles.input.ts b/src/@generated/user/user-update-without-favorite-articles.input.ts index d01e3f8c..01d634e9 100644 --- a/src/@generated/user/user-update-without-favorite-articles.input.ts +++ b/src/@generated/user/user-update-without-favorite-articles.input.ts @@ -2,7 +2,6 @@ import { Field, Float, InputType, Int } from '@nestjs/graphql'; import { ArticleUpdateManyWithoutAuthorInput } from '../article/article-update-many-without-author.input'; import { CommentUpdateManyWithoutAuthorInput } from '../comment/comment-update-many-without-author.input'; -import { EnumRoleFieldUpdateOperationsInput } from '../prisma/enum-role-field-update-operations.input'; import { Role } from '../prisma/role.enum'; import { UserUpdateManyWithoutFollowersInput } from './user-update-many-without-followers.input'; import { UserUpdateManyWithoutFollowingInput } from './user-update-many-without-following.input'; @@ -57,11 +56,11 @@ export class UserUpdateWithoutFavoriteArticlesInput { }) rating?: number | null; - @Field(() => EnumRoleFieldUpdateOperationsInput, { + @Field(() => Role, { nullable: true, description: undefined, }) - role?: Role | EnumRoleFieldUpdateOperationsInput | null; + role?: Role | null; @Field(() => UserUpdateManyWithoutFollowersInput, { nullable: true, diff --git a/src/@generated/user/user-update-without-followers.input.ts b/src/@generated/user/user-update-without-followers.input.ts index bc26a338..27777ca9 100644 --- a/src/@generated/user/user-update-without-followers.input.ts +++ b/src/@generated/user/user-update-without-followers.input.ts @@ -3,7 +3,6 @@ import { Field, Float, InputType, Int } from '@nestjs/graphql'; import { ArticleUpdateManyWithoutAuthorInput } from '../article/article-update-many-without-author.input'; import { ArticleUpdateManyWithoutFavoritedByInput } from '../article/article-update-many-without-favorited-by.input'; import { CommentUpdateManyWithoutAuthorInput } from '../comment/comment-update-many-without-author.input'; -import { EnumRoleFieldUpdateOperationsInput } from '../prisma/enum-role-field-update-operations.input'; import { Role } from '../prisma/role.enum'; import { UserUpdateManyWithoutFollowersInput } from './user-update-many-without-followers.input'; @@ -57,11 +56,11 @@ export class UserUpdateWithoutFollowersInput { }) rating?: number | null; - @Field(() => EnumRoleFieldUpdateOperationsInput, { + @Field(() => Role, { nullable: true, description: undefined, }) - role?: Role | EnumRoleFieldUpdateOperationsInput | null; + role?: Role | null; @Field(() => UserUpdateManyWithoutFollowersInput, { nullable: true, diff --git a/src/@generated/user/user-update-without-following.input.ts b/src/@generated/user/user-update-without-following.input.ts index 020e9cc4..33c40412 100644 --- a/src/@generated/user/user-update-without-following.input.ts +++ b/src/@generated/user/user-update-without-following.input.ts @@ -3,7 +3,6 @@ import { Field, Float, InputType, Int } from '@nestjs/graphql'; import { ArticleUpdateManyWithoutAuthorInput } from '../article/article-update-many-without-author.input'; import { ArticleUpdateManyWithoutFavoritedByInput } from '../article/article-update-many-without-favorited-by.input'; import { CommentUpdateManyWithoutAuthorInput } from '../comment/comment-update-many-without-author.input'; -import { EnumRoleFieldUpdateOperationsInput } from '../prisma/enum-role-field-update-operations.input'; import { Role } from '../prisma/role.enum'; import { UserUpdateManyWithoutFollowingInput } from './user-update-many-without-following.input'; @@ -57,11 +56,11 @@ export class UserUpdateWithoutFollowingInput { }) rating?: number | null; - @Field(() => EnumRoleFieldUpdateOperationsInput, { + @Field(() => Role, { nullable: true, description: undefined, }) - role?: Role | EnumRoleFieldUpdateOperationsInput | null; + role?: Role | null; @Field(() => UserUpdateManyWithoutFollowingInput, { nullable: true, diff --git a/src/@generated/user/user-update.input.ts b/src/@generated/user/user-update.input.ts index 5b6e8ff0..60951cd9 100644 --- a/src/@generated/user/user-update.input.ts +++ b/src/@generated/user/user-update.input.ts @@ -3,7 +3,6 @@ import { Field, Float, InputType, Int } from '@nestjs/graphql'; import { ArticleUpdateManyWithoutAuthorInput } from '../article/article-update-many-without-author.input'; import { ArticleUpdateManyWithoutFavoritedByInput } from '../article/article-update-many-without-favorited-by.input'; import { CommentUpdateManyWithoutAuthorInput } from '../comment/comment-update-many-without-author.input'; -import { EnumRoleFieldUpdateOperationsInput } from '../prisma/enum-role-field-update-operations.input'; import { Role } from '../prisma/role.enum'; import { UserUpdateManyWithoutFollowersInput } from './user-update-many-without-followers.input'; import { UserUpdateManyWithoutFollowingInput } from './user-update-many-without-following.input'; @@ -58,11 +57,11 @@ export class UserUpdateInput { }) rating?: number | null; - @Field(() => EnumRoleFieldUpdateOperationsInput, { + @Field(() => Role, { nullable: true, description: undefined, }) - role?: Role | EnumRoleFieldUpdateOperationsInput | null; + role?: Role | null; @Field(() => UserUpdateManyWithoutFollowersInput, { nullable: true, diff --git a/src/generate-class.ts b/src/generate-class.ts index 8426dfb3..997e2d77 100644 --- a/src/generate-class.ts +++ b/src/generate-class.ts @@ -2,7 +2,7 @@ import assert from 'assert'; import { ClassDeclaration, Node, ObjectLiteralExpression, SourceFile } from 'ts-morph'; import { generateGraphqlImport } from './generate-graphql-import'; -import { updateObjectProperty } from './update-object-property'; +import { updateObjectProperty } from './utils'; export type DecoratorPropertyType = { name: string; diff --git a/src/generate-decorator.ts b/src/generate-decorator.ts index 1065b45d..500cfd9e 100644 --- a/src/generate-decorator.ts +++ b/src/generate-decorator.ts @@ -1,7 +1,7 @@ import assert from 'assert'; import { Node, ObjectLiteralExpression, PropertyDeclaration } from 'ts-morph'; -import { updateObjectProperty } from './update-object-property'; +import { updateObjectProperty } from './utils'; type GenerateDecoratorArgs = { propertyDeclaration: PropertyDeclaration; diff --git a/src/generate-enum/generate-enum.ts b/src/generate-enum/generate-enum.ts index e70ec831..284dbf8f 100644 --- a/src/generate-enum/generate-enum.ts +++ b/src/generate-enum/generate-enum.ts @@ -9,7 +9,7 @@ import { import { generateGraphqlImport } from '../generate-graphql-import'; import { PrismaDMMF } from '../types'; -import { updateObjectProperty } from '../update-object-property'; +import { updateObjectProperty } from '../utils'; type GenerateEnumArgs = { enumerable: PrismaDMMF.SchemaEnum & { documentation?: string }; diff --git a/src/generate.spec.ts b/src/generate.spec.ts index 75ca4c87..d91fc9b8 100644 --- a/src/generate.spec.ts +++ b/src/generate.spec.ts @@ -428,4 +428,49 @@ describe('main generate', () => { }); } }); + + it('option atomicNumberOperations false', async () => { + await getResult({ + schema: ` + model User { + id String @id + int1 Int + int2 Int? + f1 Float? + f2 Float + role1 Role? + role2 Role + } + enum Role { + USER + } + `, + atomicNumberOperations: false, + }); + expect(sourceFiles.length).to.be.greaterThan(0); + for (const sourceFile of sourceFiles) { + sourceFile.getClasses().forEach((classDeclaration) => { + if (classDeclaration.getName()?.endsWith('FieldUpdateOperationsInput')) { + assert.fail(`Class should not exists ${classDeclaration.getName()!}`); + } + }); + } + sourceFiles + .flatMap((s) => s.getClasses()) + .filter((c) => + ['UserUpdateInput', 'UserUpdateManyMutationInput'].includes(c.getName()!), + ) + .flatMap((c) => c.getProperties()) + .map((p) => p.getStructure()) + .map(({ name, type }) => ({ + name, + type, + types: (type as string).split('|').map((s) => s.trim()), + })) + .forEach((struct) => { + if (struct.types.find((s) => s.endsWith('FieldUpdateOperationsInput'))) { + expect.fail(`Property ${struct.name} typed ${struct.type}`); + } + }); + }); }); diff --git a/src/generate.ts b/src/generate.ts index 34637d90..5a5650ac 100644 --- a/src/generate.ts +++ b/src/generate.ts @@ -77,14 +77,15 @@ export async function generate(args: GenerateArgs) { generateModel({ model, sourceFile, projectFilePath }); } // Generate inputs - const inputTypes = prismaClientDmmf.schema.inputTypes.filter( - mutateFilters(prismaClientDmmf.schema.inputTypes, { + let inputTypes = prismaClientDmmf.schema.inputTypes; + inputTypes = inputTypes.filter( + mutateFilters(inputTypes, { combineScalarFilters: JSON.parse( (generator.config.combineScalarFilters as string | undefined) ?? 'true', - ), + ) as boolean, atomicNumberOperations: JSON.parse( (generator.config.atomicNumberOperations as string | undefined) ?? 'false', - ), + ) as boolean, }), ); // Create aggregate inputs diff --git a/src/mutate-filters/mutate-filters.ts b/src/mutate-filters/mutate-filters.ts index 628fbac0..949ddd12 100644 --- a/src/mutate-filters/mutate-filters.ts +++ b/src/mutate-filters/mutate-filters.ts @@ -9,20 +9,8 @@ type MutateFiltersOptions = { export function mutateFilters(inputTypes: PrismaDMMF.InputType[], options: MutateFiltersOptions) { const mutations = [ - options.combineScalarFilters && [combineScalarFilters(inputTypes)], - !options.atomicNumberOperations && - noAtomicNumberOperations([ - 'StringFieldUpdateOperationsInput', - 'NullableStringFieldUpdateOperationsInput', - 'IntFieldUpdateOperationsInput', - 'NullableIntFieldUpdateOperationsInput', - 'FloatFieldUpdateOperationsInput', - 'NullableFloatFieldUpdateOperationsInput', - 'BoolFieldUpdateOperationsInput', - 'NullableBoolFieldUpdateOperationsInput', - 'DateTimeFieldUpdateOperationsInput', - 'NullableDateTimeFieldUpdateOperationsInput', - ]), + options.combineScalarFilters && combineScalarFilters(inputTypes), + !options.atomicNumberOperations && noAtomicNumberOperations(), ]; return function (inputType: PrismaDMMF.InputType) { diff --git a/src/mutate-filters/no-atomic-number-operations.ts b/src/mutate-filters/no-atomic-number-operations.ts index 5f889038..d6c4bdef 100644 --- a/src/mutate-filters/no-atomic-number-operations.ts +++ b/src/mutate-filters/no-atomic-number-operations.ts @@ -1,16 +1,20 @@ import { PrismaDMMF } from '../types'; -export function noAtomicNumberOperations(names: string[]) { +export function noAtomicNumberOperations() { return (inputType: PrismaDMMF.InputType) => { - if (names.includes(inputType.name)) { + if (isAtomicOperation(inputType.name)) { return false; } inputType.fields = inputType.fields.map((field) => { field.inputTypes = field.inputTypes.filter((inputType) => { - return !names.includes(String(inputType.type)); + return !isAtomicOperation(String(inputType.type)); }); return field; }); return inputType; }; } + +function isAtomicOperation(name: string) { + return name.endsWith('FieldUpdateOperationsInput'); +} diff --git a/src/testing/generator-options.ts b/src/testing/generator-options.ts index 7d12d378..c1ddec93 100644 --- a/src/testing/generator-options.ts +++ b/src/testing/generator-options.ts @@ -6,6 +6,10 @@ import fs from 'fs'; import { PrismaDMMF } from '../types'; +const { + dependencies: { '@prisma/generator-helper': generatorVersion }, +} = require('../../package.json'); + const cachePath: string = findCacheDir({ name: 'createGeneratorOptions', create: true }); /** @@ -16,7 +20,7 @@ export async function generatorOptions( options?: Record, ): Promise { // eslint-disable-next-line prefer-rest-params - const data = JSON.stringify(arguments); + const data = JSON.stringify([generatorVersion, arguments]); const hash = crypto.createHash('md5').update(data).digest('hex'); const optionsCacheFile = `${cachePath}/options-${hash}.js`; if (!fs.existsSync(optionsCacheFile)) { diff --git a/src/update-object-property.ts b/src/update-object-property.ts deleted file mode 100644 index 9f6c6278..00000000 --- a/src/update-object-property.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { ObjectLiteralExpression, PropertyAssignment, StructureKind } from 'ts-morph'; - -type UpdateObjectPropertyArgs = { - expression: ObjectLiteralExpression; - name: string; - value: string | number | boolean | undefined; - defaultValue?: string | number | boolean; -}; - -export function updateObjectProperty(args: UpdateObjectPropertyArgs) { - const { expression, name, value, defaultValue } = args; - let descriptionProperty = expression.getProperty(name) as PropertyAssignment | undefined; - - if (!descriptionProperty) { - descriptionProperty = expression.addProperty({ - name, - kind: StructureKind.PropertyAssignment, - initializer: defaultValue !== undefined ? String(defaultValue) : 'undefined', - }) as PropertyAssignment; - } - descriptionProperty.set({ - initializer: - JSON.stringify(value) || - (defaultValue !== undefined ? String(defaultValue) : 'undefined'), - }); -} diff --git a/src/utils.ts b/src/utils.ts index 94a2865f..c2763012 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,3 +1,5 @@ +import { ObjectLiteralExpression, PropertyAssignment, StructureKind } from 'ts-morph'; + import { PrismaDMMF } from './types'; type ToGraphqlImportTypeArgs = { @@ -111,3 +113,28 @@ export function schemaFieldToArgument(field: PrismaDMMF.SchemaField): PrismaDMMF export function getOutputTypeName(name: string) { return name.replace(/OutputType$/, ''); } + +type UpdateObjectPropertyArgs = { + expression: ObjectLiteralExpression; + name: string; + value: string | number | boolean | undefined; + defaultValue?: string | number | boolean; +}; + +export function updateObjectProperty(args: UpdateObjectPropertyArgs) { + const { expression, name, value, defaultValue } = args; + let descriptionProperty = expression.getProperty(name) as PropertyAssignment | undefined; + + if (!descriptionProperty) { + descriptionProperty = expression.addProperty({ + name, + kind: StructureKind.PropertyAssignment, + initializer: defaultValue !== undefined ? String(defaultValue) : 'undefined', + }) as PropertyAssignment; + } + descriptionProperty.set({ + initializer: + JSON.stringify(value) || + (defaultValue !== undefined ? String(defaultValue) : 'undefined'), + }); +}