# prisma-nestjs-graphql

Generate object types, inputs, args, etc. from prisma schema file for usage with @nestjs/graphql module.

## Features

- Generates only necessary imports
- Combines zoo of nested/nullable filters
- Does not generate resolvers, since it's application specific

## Install

```
npm install --save-dev prisma-nestjs-graphql @prisma/generator-helper identity-type
```

## Usage

1. Add new generator section to `schema.prisma` file

```prisma
generator nestgraphql {
  provider = "prisma-nestjs-graphql"
  // Or explicit node execution
  provider = "node node_modules/prisma-nestjs-graphql/bin.mjs"
  output = "../src/@generated"
}
```

2. Add a configuration file

Create `prisma/nestgraphql.config.mjs` and reference it in your schema:

```prisma
generator nestgraphql {
  provider = "prisma-nestjs-graphql"
  configFile = "./nestgraphql.config.mjs"
}
```

```js
// prisma/nestgraphql.config.mjs
/**
 * @type {import('prisma-nestjs-graphql').ExternalConfig}
 */
export default {
  output: '../src/@generated',
};
```

All generator options—including `decorators`, `fields`, `useInputType`, `customImport`,
and `graphqlScalars`—are defined as **structured JavaScript objects** in the config file
instead of using underscore-delimited keys (`decorate_1_*`, `fields_Validator_*`, etc.)
directly in the schema.

3. Run prisma generate

```sh
npx prisma generate
```

4. If your models have `Decimal` and `Json` types, you need install:

```sh
npm install graphql-type-json prisma-graphql-type-decimal

```

- [graphql-type-json](https://github.com/taion/graphql-type-json)
- [prisma-graphql-type-decimal](https://github.com/unlight/prisma-graphql-type-decimal)

Or write you own graphql scalar types, [read more on docs.nestjs.com](https://docs.nestjs.com/graphql/scalars).

## Configuration File

Instead of defining all options as flat keys in `schema.prisma`, you can use a structured JavaScript config file
for better readability, validation, and IDE autocompletion.

### Migration from flatten-style keys

**Before** (underscore-delimited keys in `schema.prisma`):

```
fields_Validator_from = "class-validator"
fields_Validator_input = true
decorate_1_type = "CreateOneUserArgs"
decorate_1_field = data
decorate_1_from = "class-validator"
decorate_1_name = ValidateNested
decorate_1_arguments = "[]"
```

**After** (structured objects in `nestgraphql.config.mjs`):

```js
fields: {
  Validator: { from: 'class-validator', input: true },
},
decorators: [
  {
    match: ({ objectName, propertyName }) =>
      objectName === 'CreateOneUserArgs' && propertyName === 'data',
    from: 'class-validator',
    name: 'ValidateNested',
    arguments: [],
    namedImport: true,
  },
],
```

### Backward compatibility

The old flatten-style keys still work if no `configFile` is specified.
Options from the config file take precedence.

## Generator options

#### `output`

Output folder, if path relative and defined in schema it will be relative to schema,
if defined in config file it will be relative to this config file.
Type: `string`

#### `outputFilePattern`

File path and name pattern  
Type: `string`  
Default: `{model}/{name}.{type}.ts`  
Possible tokens:

- `{model}` Model name in dashed case or 'prisma' if unknown
- `{name}` Dashed-case name of model/input/arg without suffix
- `{type}` Short type name (model, input, args, output)
- `{plural.type}` Plural short type name (models, inputs, enums)

#### `tsConfigFilePath`

Path to `tsconfig.json` (absolute path or relative to current working directory)  
Type: `string | undefined`  
Default: `tsconfig.json` if exists, `undefined` otherwise

#### `prismaClientImport`

The path to use to import the Prisma Client package
Type: `string | undefined`
Default: `@prisma/client`

#### `importExtension`

Append an extension to relative import and export module specifiers (without dot, eg. 'js, 'ts', 'mjs')
Type: `string`
Default: `''` (empty string)

#### `combineScalarFilters`

Combine nested/nullable scalar filters to single
Type: `boolean`
Default: `true`

#### `noAtomicOperations`

Remove input types for atomic operations
Type: `boolean`
Default: `true`

#### `reExport`

Create `index.ts` file with re-export
Type: `enum`
Values:
`None` Default, create nothing
`Directories` Create index file in all root directories
`Single` Create single index file in output directory
`All` Create index file in all root directories and in output directory

Example configuration:

```prisma
generator nestgraphql {
    provider = "node node_modules/prisma-nestjs-graphql"
    output = "../src/@generated"
    reExport = Directories
}
```

#### `emitSingle`

Generate single file with merged classes and enums.
Type: `boolean`
Default: `false`

#### `emitCompiled`

Emit compiled JavaScript and definitions instead of TypeScript sources.
Type: `boolean`
Default: `false`

#### `emitBlocks`

Emit only selected blocks. Be aware, that some blocks do depend on others, e.g. one can't emit `models` without emitting `enums`.
Type: `("args" | "inputs" | "outputs" | "models" | "enums")[]`
Default: `["args", "inputs", "outputs", "models", "enums"]`

#### `omitModelsCount`

Omit `_count` field from models.
Type: `boolean`
Default: `false`

#### `purgeOutput`

Delete all files in `output` folder.
Type: `boolean`
Default: `false`

#### `noTypeId`

Disable usage of graphql `ID` type and use `Int/Float` for fields marked as `@id` in schema.
Type: `boolean`
Default: `false`

#### `typeListNullable`

Adds `nullable: true` for relation list properties out output models,
it makes graphql field looks like `[Type!]`, default `[Type!]!`
Type: `boolean`
Default: `false`

#### `requireSingleFieldsInWhereUniqueInput`

When a model `*WhereUniqueInput` class has only a single field, mark that field as **required** (TypeScript) and **not nullable** (GraphQL).
See [#58](https://github.com/unlight/prisma-nestjs-graphql/issues/58) for more details.
Type: `boolean`
Default: `false`
**Note**: It will break compatiblity between Prisma types and generated classes.

#### `unsafeCompatibleWhereUniqueInput`

Set TypeScript property type as non optional for all fields in `*WhereUniqueInput` classes.
See [#177](https://github.com/unlight/prisma-nestjs-graphql/issues/177) for more details.
Type: `boolean`
Default: `false`

#### `inputType`

Since GraphQL does not support input union type, this setting map
allow to choose which input type is preferable.

**New (config file)**:

```js
/**
 * Input type mapping.
 * Select which input type should be exposed when multiple candidates exist.
 * Since GraphQL does not support input unions, this setting can resolve
 * ambiguous fields (e.g. `UserRelationFilter` vs `UserWhereInput`).
 *
 * Supports two variants:
 * - object map: `{ [inputTypeName]: { [fieldName|'*']: pattern } }`
 * - function: return either an `InputTypeRef` or a string pattern
 *   (same matching behavior as map patterns, including `match:` syntax)
 * @example
 * // Force all WhereInput relation properties to use the plain WhereInput type:
 * { WhereInput: { '*': 'WhereInput' } }
 * // Or for a specific property in a specific type:
 * { PostCreateInput: { author: 'UserCreateNestedOneWithoutPostsInput' } }
 * // Function variant returning a pattern:
 * ({ inputTypeName, fieldName }) =>
 *   inputTypeName.includes('CreateOne') && fieldName === 'data'
 *     ? 'UncheckedCreate'
 *     : undefined
 */
inputType: GetInputTypeFunction | ConfigInputTypeMap;
```

Where:

- `typeName` — Full or partial name of the class where need to choose input type
- `property` — Property of the class. Special case `ALL` means any/all properties
- `pattern` — Part of name (or full) of type to choose; use `match:*UncheckedCreateInput` for wildcard/negation matching

**Legacy (schema.prisma, flatten-style)**:

```sh
generator nestgraphql {
  useInputType_{typeName}_{property} = "{pattern}"
}
```

Example:

```ts
export type PostWhereInput = {
  author?: XOR<UserRelationFilter, UserWhereInput>;
};
export type UserRelationFilter = {
  is?: UserWhereInput;
  isNot?: UserWhereInput;
};

export type UserWhereInput = {
  AND?: Enumerable<UserWhereInput>;
  OR?: Enumerable<UserWhereInput>;
  NOT?: Enumerable<UserWhereInput>;
  id?: StringFilter | string;
  name?: StringFilter | string;
};
```

We have generated types above, by default property `author` will be decorated as `UserRelationFilter`,
to set `UserWhereInput` need to configure generator the following way (legacy way):

```prisma
generator nestgraphql {
  provider = "node node_modules/prisma-nestjs-graphql"
  output = "../src/@generated"
  useInputType_WhereInput_ALL = "WhereInput"
}
```

```ts
@InputType()
export class PostWhereInput {
  @Field(() => UserWhereInput, { nullable: true })
  author?: UserWhereInput;
}
```

#### `decorators`

Modern way to attach custom decorators in config file (`decorators: DecoratorItem[]`).

```js
decorators: [
  {
    match: ({ objectName, propertyName }) =>
      objectName === 'CreateOneUserArgs' && propertyName === 'data',
    from: 'class-validator',
    name: 'ValidateNested',
    arguments: [],
    namedImport: true,
  },
  {
    match: ({ objectName, propertyName }) =>
      objectName === 'CreateOneUserArgs' && propertyName === 'data',
    from: 'class-transformer',
    name: 'Type',
    arguments: ['() => {propertyType.0}'],
    namedImport: true,
  },
];
```

`match` receives one argument `FieldInfo`:

```ts
type FieldInfo = {
  /**
   * Prisma DMMF field location type
   * Can be: 'scalar', 'inputObjectTypes', 'outputObjectTypes', 'enumTypes', 'fieldRefTypes'
   */
  location: FieldLocation;
  /**
   * Class name
   */
  objectName: string;
  /**
   * Property name
   */
  propertyName: string;
  /**
   * Property type (may contain TypeScript elements, like parameters for generics, etc.)
   */
  propertyType: string;
  /**
   * GraphQL/Prisma type name
   */
  typeName: string;
};
```

Decorator item type:

```ts
type DecoratorItem = {
  /** Return `true` to apply this decorator to the current field. */
  match: (args: FieldInfo) => boolean;
  /** Arguments passed to the decorator call.
   * Supports templates like `{propertyType.0}`. */
  arguments?: string[];
  /** Module specifier to import from (e.g. 'class-validator') */
  from: string;
  /** Decorator name. Can include namespace, e.g. `Transform.Type`. */
  name: string;
  /** Import as a named export. */
  namedImport: boolean;
  /** Import as default export.
   * Use `true` to import by decorator name. */
  defaultImport?: string | true;
  /** Import entire module under this namespace. */
  namespaceImport?: string;
};
```

Special token in arguments: `{propertyType.0}` resolves to the field's TypeScript type.

Example result:

```ts
import { ValidateNested } from 'class-validator';
import { Type } from 'class-transformer';

@ArgsType()
export class CreateOneUserArgs {
  @Field(() => UserCreateInput, { nullable: false })
  @ValidateNested()
  @Type(() => UserCreateInput)
  data!: UserCreateInput;
}
```

**Legacy (`decorate` / `decorate_*`)**

Legacy flatten-style keys in `schema.prisma` are still supported for backward compatibility:

```sh
generator nestgraphql {
  decorate_{key}_type = "outmatch pattern"
  decorate_{key}_field = "outmatch pattern"
  decorate_{key}_from = "module specifier"
  decorate_{key}_name = "import name"
  decorate_{key}_arguments = "[argument1, argument2]"
  decorate_{key}_defaultImport = "default import name" | true
  decorate_{key}_namespaceImport = "namespace import name"
  decorate_{key}_namedImport = "import name" | true
}
```

Prefer `decorators` in `nestgraphql.config.*` for new configuration.

#### `graphqlScalars`

Allow to set custom graphql type for Prisma scalar type.

**New (config file)**:

```js
graphqlScalars: {
  BigInt: { name: 'GraphQLBigInt', specifier: 'graphql-scalars' },
}
```

**Legacy (schema.prisma, flatten-style)**:

```
graphqlScalars_{type}_name = "string"
graphqlScalars_{type}_specifier = "string"
```

where `{type}` is a prisma scalar type name (e.g. BigInt)

Example:

```
graphqlScalars_BigInt_name = "GraphQLBigInt"
graphqlScalars_BigInt_specifier = "graphql-scalars"
```

May generate:

```ts
import { GraphQLBigInt } from 'graphql-scalars';

export class BigIntFilter {
  @Field(() => GraphQLBigInt, { nullable: true })
  equals?: bigint | number;
}
```

It will affect all inputs and outputs types (including models).

#### `customImports`

Allow to declare custom import statements.
**Note**: Only works with `emitSingle = true`

**New (config file)**:

```js
customImports: [
  { from: 'nestjs-i18n', name: 'I18n', defaultImport: true },
  { from: 'class-transformer', name: 'Transform', namedImport: true },
];
```

**Legacy (schema.prisma, flatten-style)**:

```sh
generator nestgraphql {
  customImport_{key}_from = "module specifier"
  customImport_{key}_name = "import name"
  customImport_{key}_defaultImport = "default import name" | true
  customImport_{key}_namespaceImport = "namespace import name"
  customImport_{key}_namedImport = "import name" | true
}
```

Where `{key}` any identifier to group values (written in [flatten](https://github.com/hughsk/flat) style)

- `customImport_{key}_from` - module specifier to import from (e.g `nestjs-i18n`)
- `customImport_{key}_name` - import name or name with namespace
- `customImport_{key}_defaultImport` - import as default
- `customImport_{key}_namespaceImport` - use this name as import namespace
- `customImport_{key}_namedImport` - named import (without namespace)

#### `fieldDecoratorArguments`

Override `@Field()` decorator arguments for specific fields. Use this to customize pagination fields (take, skip, cursor) or other generated Args fields that don't come from your Prisma schema.

Each rule is evaluated against generated field metadata and applied when the `match` function returns `true`. Multiple matching rules are merged in order.

**New (config file)**:

```js
fieldDecoratorArguments: [
  {
    match: ({ objectName, propertyName }) =>
      objectName.endsWith('Args') && propertyName === 'take',
    decoratorArguments: {
      name: 'first',
      defaultValue: 10,
      description: 'Number of records to return',
    },
  },
  {
    match: ({ objectName, propertyName }) =>
      objectName.endsWith('Args') && propertyName === 'skip',
    decoratorArguments: {
      name: 'offset',
      defaultValue: 0,
      description: 'Number of records to skip',
    },
  },
]
```

**Available `decoratorArguments` options:**
- `nullable` — Mark field as nullable in GraphQL schema
- `defaultValue` — Default value for the field
- `description` — Description shown in GraphQL schema
- `deprecationReason` — Mark field as deprecated
- `name` — Custom name for the field in GraphQL schema (TypeScript property name stays the same)
- `complexity` — Complexity value for query cost analysis
- `middleware` — Middleware function name(s) to apply to the field

**Middleware Example:**

To use field middleware, combine `customImports` with `fieldDecoratorArguments`. Middleware values are emitted as identifier references (not string literals), allowing them to reference your imported middleware functions:

```js
export default {
  customImports: [
    { from: './middleware/logger', name: 'loggerMiddleware', defaultImport: true },
    { from: './middleware/auth', name: 'authMiddleware', defaultImport: true },
  ],
  fieldDecoratorArguments: [
    {
      match: ({ objectName, propertyName }) =>
        objectName === 'User' && propertyName === 'email',
      decoratorArguments: {
        middleware: ['loggerMiddleware', 'authMiddleware'],
        description: 'User email with logging and auth',
      },
    },
  ],
};
```

This generates:

```ts
@Field(() => String, {
  description: 'User email with logging and auth',
  middleware: [loggerMiddleware, authMiddleware]
})
email: string;
```

**Note:** When using the `name` option to override a field name in GraphQL, ensure you understand Prisma field mapping. For example, if you override the `take` field name to `first`, you must update any Prisma query logic that references the field by its original name. Consider using a mapping helper if doing this across multiple queries.

The `match` function receives `FieldInfo` with:
- `objectName` — Class name (e.g., 'FindManyUserArgs')
- `propertyName` — Property name (e.g., 'take', 'skip')
- `propertyType` — TypeScript property type
- `typeName` — GraphQL/Prisma type name
- `location` — Prisma field location ('scalar', 'inputObjectTypes', etc.)

## Documentation and field options

Comments with triple slash will projected to typescript code comments
and some `@Field()` decorator options

For example:

```prisma
model Product {
  /// Old description
  /// @deprecated Use new name instead
  /// @complexity 1
  oldName String
}
```

May produce:

```ts
@ObjectType()
export class Product {
  /**
   * Old description
   * @deprecated Use new name instead
   */
  @Field(() => String, {
    description: 'Old description',
    deprecationReason: 'Use new name instead',
    complexity: 1,
  })
  oldName: string;
}
```

## Field Settings

Special directives in triple slash comments for more precise code generation.

#### @HideField()

Removes field from GraphQL schema.
By default (without arguments) field will be decorated for hide only in output types (type in schema).
To hide field in input types add `input: true`.
To hide field in specific type you can use glob pattern `match: string | string[]`
see [outmatch](https://github.com/axtgr/outmatch#usage) for details.

For config-file based rules, use `shouldHideField`:

```js
export default {
  shouldHideField: ({ location, objectName, propertyName }) =>
    location === 'inputObjectTypes' &&
    objectName.endsWith('CreateInput') &&
    ['id', 'createdAt', 'updatedAt'].includes(propertyName),
};
```

The callback receives `FieldInfo` (`location`, `objectName`, `propertyName`, `propertyType`, `typeName`).
When `shouldHideField` is defined, it overrides `@HideField(...)` settings from field comments and legacy `decorate` rules.

Examples:

- `@HideField()` same as `@HideField({ output: true })`
- `@HideField({ input: true, output: true })`
- `@HideField({ match: 'UserCreate*Input' })`

```prisma
model User {
  id String @id @default(cuid())
  /// @HideField()
  password String
  /// @HideField({ output: true, input: true })
  secret String
  /// @HideField({ match: '@(User|Comment)Create*Input' })
  createdAt DateTime @default(now())
}
```

May generate classes:

```ts
@ObjectType()
export class User {
  @HideField()
  password: string;
  @HideField()
  secret: string;
  @Field(() => Date, { nullable: false })
  createdAt: Date;
}
```

```ts
@InputType()
export class UserCreateInput {
  @Field()
  password: string;
  @HideField()
  secret: string;
  @HideField()
  createdAt: Date;
}
```

#### Custom Decorators

Applying custom decorators requires configuration of generator.

```prisma
// Legacy configuration, prefer config file
generator nestgraphql {
  fields_{namespace}_from = "module specifier"
  fields_{namespace}_input = true | false
  fields_{namespace}_output = true | false
  fields_{namespace}_model = true | false
  fields_{namespace}_defaultImport = "default import name" | true
  fields_{namespace}_namespaceImport = "namespace import name"
  fields_{namespace}_namedImport = true | false
}
```

Create configuration map in [flatten](https://github.com/hughsk/flat) style for `{namespace}`.
Where `{namespace}` is a namespace used in field triple slash comment.

##### `fields_{namespace}_from`

Required. Name of the module, which will be used in import (`class-validator`, `graphql-scalars`, etc.)
Type: `string`

##### `fields_{namespace}_input`

Means that it will be applied on input types (classes decorated by `InputType`)
Type: `boolean`
Default: `false`

##### `fields_{namespace}_output`

Means that it will be applied on output types (classes decorated by `ObjectType`),
including models
Type: `boolean`
Default: `false`

##### `fields_{namespace}_model`

Means that it will be applied only on model types (classes decorated by `ObjectType`)
Type: `boolean`
Default: `false`

##### `fields_{namespace}_defaultImport`

Default import name, if module have no namespace.
Type: `undefined | string | true`
Default: `undefined`
If defined as `true` then import name will be same as `{namespace}`

##### `fields_{namespace}_namespaceImport`

Import all as this namespace from module
Type: `undefined | string`
Default: Equals to `{namespace}`

##### `fields_{namespace}_namedImport`

If imported module has internal namespace, this allow to generate named import,
imported name will be equal to `{namespace}`, see [example of usage](#propertytype)
Type: `boolean`
Default: `false`

Custom decorators example:

```prisma
generator nestgraphql {
  fields_Validator_from = "class-validator"
  fields_Validator_input = true
}

model User {
  id Int @id
  /// @Validator.MinLength(3)
  name String
}
```

May generate following class:

```ts
import { InputType, Field } from '@nestjs/graphql';
import * as Validator from 'class-validator';

@InputType()
export class UserCreateInput {
  @Field(() => String, { nullable: false })
  @Validator.MinLength(3)
  name!: string;
}
```

Custom decorators can be applied on classes (models):

```
/// @NG.Directive('@extends')
/// @NG.Directive('@key(fields: "id")')
model User {
  /// @NG.Directive('@external')
  id String @id
}

generator nestgraphql {
  fields_NG_from = "@nestjs/graphql"
  fields_NG_output = false
  fields_NG_model = true
}
```

May generate:

```ts
import * as NG from '@nestjs/graphql';

@NG.Directive('@extends')
@NG.Directive('@key(fields: "id")')
export class User {
  @Field(() => ID, { nullable: false })
  @NG.Directive('@external')
  id!: string;
```

#### @FieldType()

Allow set custom GraphQL scalar type for field

To override scalar type in specific classes, you can use glob pattern `match: string | string[]`
see [outmatch](https://github.com/axtgr/outmatch#usage) for details.

```prisma
model User {
  id Int @id
  /// @FieldType({ name: 'Scalars.GraphQLEmailAddress', from: 'graphql-scalars', input: true })
  email String
}
```

May generate following class:

```ts
import { InputType, Field } from '@nestjs/graphql';
import * as Scalars from 'graphql-scalars';

@InputType()
export class UserCreateInput {
  @Field(() => Scalars.GraphQLEmailAddress, { nullable: false })
  email!: string;
}
```

And following GraphQL schema:

```grapqhl
scalar EmailAddress

input UserCreateInput {
  email: EmailAddress!
}
```

Same field type may be used in different models and it is not convenient to specify every time all options.
There is a shortcut:

```grapqhl
generator nestgraphql {
  fields_Scalars_from = "graphql-scalars"
  fields_Scalars_input = true
  fields_Scalars_output = true
}

model User {
  id Int @id
  /// @FieldType('Scalars.GraphQLEmailAddress')
  email String
}
```

The result will be the same. `Scalars` is the namespace here.
Missing field options will merged from generator configuration.

#### @PropertyType()

Similar to `@FieldType()` but refer to TypeScript property (actually field too).

To override TypeScript type in specific classes, you can use glob pattern `match: string | string[]`
see [outmatch](https://github.com/axtgr/outmatch#usage) for details.

Example:

```
generator nestgraphql {
  fields_TF_from = "type-fest"
}

model User {
  id String @id
  /// @PropertyType('TF.JsonObject')
  data Json
}
```

May generate:

```ts
import * as TF from 'type-fest';

@ObjectType()
export class User {
  @Field(() => GraphQLJSON)
  data!: TF.JsonObject;
}
```

### @Directive()

Allow attach `@Directive` decorator from `@nestjs/graphql`

GraphQL federation example:

```
/// @Directive({ arguments: ['@extends'] })
/// @Directive({ arguments: ['@key(fields: "id")'] })
model User {
  /// @Directive({ arguments: ['@external'] })
  id String @id
}
```

May generate:

```ts
@ObjectType()
@Directive('@extends')
@Directive('@key(fields: "id")')
export class User {
  @Field(() => ID, { nullable: false })
  @Directive('@external')
  id!: string;
}
```

#### @ObjectType()

Allow rename type in schema and mark as abstract.

Example 1:

```
// schema.prisma
/// @ObjectType({ isAbstract: true })
model User {
  id Int @id
}
```

```ts
@ObjectType({ isAbstract: true })
export class User {}
```

Example 2:

```
// schema.prisma
/// @ObjectType('Human', { isAbstract: true })
model User {
  id Int @id
}
```

```ts
@ObjectType('Human', { isAbstract: true })
export class User {}
```

### Using library in other generators

```ts
import { generate } from 'prisma-nestjs-graphql';
```

## Similar Projects

- <https://github.com/jasonraimondi/prisma-generator-nestjs-graphql>
- <https://github.com/omar-dulaimi/prisma-class-validator-generator>
- <https://github.com/kimjbstar/prisma-class-generator>
- <https://github.com/odroe/nest-gql-mix>
- <https://github.com/rfermann/nestjs-prisma-graphql-generator>
- <https://github.com/madscience/graphql-codegen-nestjs>
- <https://github.com/wSedlacek/prisma-generators/tree/master/libs/nestjs>
- <https://github.com/EndyKaufman/typegraphql-prisma-nestjs>
- <https://github.com/MichalLytek/typegraphql-prisma>
- <https://github.com/mk668a/nestjs-prisma-graphql-crud-gen>

## Resources

- Todo - <https://github.com/unlight/prisma-nestjs-graphql/issues/2>
- <https://github.com/prisma/prisma/blob/main/packages/client/src/generation/TSClient/TSClient.ts>
- <https://ts-ast-viewer.com/>
- <https://github.com/unlight/nestjs-graphql-prisma-realworld-example-app>
- <https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-schema/data-model>
- JSON type for the code first approach - <https://github.com/nestjs/graphql/issues/111#issuecomment-631452899>
- <https://github.com/paljs/prisma-tools/tree/master/packages/plugins>
- <https://github.com/wasp-lang/wasp>

## TODO

- CommentUncheckedUpdateManyWithoutAuthorNestedInput and CommentUpdateManyWithoutAuthorNestedInput are same
- Add logic to detect view models and skip generation of mutation inputs/args for them https://github.com/unlight/prisma-nestjs-graphql/issues/248
- dummy-createfriends.input.ts -> `create-friends`
- check 'TODO FIXME'
- rework test, use setup file

## License

[MIT License](https://opensource.org/licenses/MIT) (c) 2026
