@hatkom/nestjs-graphql-plugin
v1.2.3
Published
NestJS GraphQL TypeScript compiler plugin and enum codegen for Prisma-based projects.
Downloads
1,103
Readme
@hatkom/nestjs-graphql-plugin
Two complementary tools that eliminate the GraphQL schema boilerplate you would otherwise write by hand in a NestJS project:
- TypeScript compiler plugin — auto-injects
@Field()decorators on class properties typed as flavoured Prisma IDs, enums, or configured scalar aliases. Also auto-injects@ArgsType()/@InputType()on undecorated classes in*.args.ts/*.input.tsfiles. nestjs-generate-enumsCLI — scans your source tree for enums referenced in GraphQL decorators and in class properties inside*.args.ts/*.input.tsfiles, then generates a single file ofregisterEnumType(...)calls you import once from your app module.
Installation
npm install @hatkom/nestjs-graphql-plugin
# or
bun add @hatkom/nestjs-graphql-pluginTypeScript must be installed separately (peer dependency, >=5.0.0).
1. TypeScript compiler plugin
What it does
NestJS's built-in GraphQL plugin auto-adds @Field() for primitive types but skips branded IDs, enums, and custom scalars. This plugin fills three gaps:
- Flavoured IDs — injects
@Field(() => ID)for properties typed as prisma-generator-flavoured-ids (names matching^[A-Z][A-Za-z0-9_]*Id$imported from the configured module). - Enums — uses the TypeScript type checker to detect both
enum Foo {}andconst Foo = { ... } as constenum patterns and injects@Field(() => Foo)automatically. - Scalar aliases — optionally maps named exports from a shared module to their GraphQL scalar types (e.g.
float→@Field(() => Float)).
It also auto-injects class-level decorators so none need to be written by hand:
@ArgsType()on classes ending inArgsinside*.args.tsfiles@InputType()on classes ending inInputinside*.input.tsfiles@ObjectType()on classes ending inModelinside*.model.tsfiles
Configuration
Register the plugin in nest-cli.json alongside @nestjs/graphql:
{
"compilerOptions": {
"plugins": [
"@nestjs/graphql",
"@hatkom/nestjs-graphql-plugin"
]
}
}With options:
{
"compilerOptions": {
"plugins": [
"@nestjs/graphql",
{
"name": "@hatkom/nestjs-graphql-plugin",
"options": {
"idModulePattern": "@generated/prisma/",
"scalarModule": "@myorg/shared",
"scalars": {
"float": "Float",
"int": "Int"
}
}
}
]
}
}Plugin options
| Option | Type | Default | Description |
|---|---|---|---|
| idModulePattern | string (regex) | @generated/prisma/ | Regex matched against the import path. Matching imports whose exported names satisfy ^[A-Z][A-Za-z0-9_]*Id$ are treated as ID types. |
| scalarModule | string | (disabled) | Module from which scalar aliases are imported. When omitted, scalar handling is skipped. |
| scalars | Record<string, string> | { float: "Float", int: "Int" } | Map of exported identifier → GraphQL scalar name for imports from scalarModule. |
| autoArgsType | boolean | true | Auto-inject @ArgsType() on classes ending in Args inside *.args.ts files. |
| autoInputType | boolean | true | Auto-inject @InputType() on classes ending in Input inside *.input.ts files. |
| autoObjectType | boolean | true | Auto-inject @ObjectType() on classes ending in Model inside *.model.ts files. |
Behaviour
- For
*.args.tsand*.input.tsfiles, auto-injects@ArgsType()/@InputType()on matching class names. For*.model.tsfiles, auto-injects@ObjectType()on classes ending inModel. Classes already carrying any GraphQL class decorator are left untouched. - Inside eligible classes, injects
@Field()for flavoured ID types, enums, and configured scalar aliases. Properties already carrying@Fieldor@HideFieldare skipped. - Handles
T[],Array<T>,T | null, and optional (?:) for array-ness and nullability.
Before / after
// Before — explicit decorators required on every ID, enum, and class
@ArgsType()
export class FindInvoicesArgs {
@Field(() => ID)
fundId: FundId
@Field(() => InvoiceStatus)
status: InvoiceStatus
page?: number
}
// After — everything injected automatically at compile time
export class FindInvoicesArgs {
fundId: FundId
status: InvoiceStatus
page?: number
}2. nestjs-generate-enums CLI
What it does
NestJS requires every enum used in a GraphQL schema to be registered via registerEnumType(MyEnum, { name: 'MyEnum' }). This command scans your source tree and emits a single generated file that registers them all.
It detects enums from two sources:
- GraphQL decorators — any enum referenced via
@Field(() => MyEnum),@Query,@Mutation,@Subscription, or@ResolveField. - Args/Input class properties — enum-typed properties in
*.args.tsand*.input.tsfiles, even without an explicit@Field()decorator (since those are injected at compile time by the plugin).
Usage
nestjs-generate-enums \
--src apps/api/src \
--output apps/api/src/@generated/registered-enums.ts \
[--tsconfig apps/api/tsconfig.json] \
[--override "src/@generated/prisma/client::SortOrder=CommitmentSortOrder"] \
[--override "src/@generated/prisma/client::ISO3166CountryCode=CountryName"]Options
| Option | Required | Description |
|---|---|---|
| --src | Yes | Source directory to scan. Paths are resolved relative to cwd. |
| --output | Yes | Output file path. |
| --tsconfig | No | Path to tsconfig.json. Defaults to <src>/../tsconfig.json. |
| --override | No (repeatable) | Override the GraphQL name for a specific enum. Format: <module>::<EnumName>=<GraphQLName>. |
Output
The generated file imports and registers every detected enum:
// This file is generated by @hatkom/nestjs-graphql-plugin.
// Do not edit by hand. Regenerate by running nestjs-generate-enums.
import { registerEnumType } from '@nestjs/graphql'
import { CommitmentStatus, InvoiceStatus } from 'src/@generated/prisma/client'
import { SortDirection } from 'src/common/dto/sort.enum'
registerEnumType(CommitmentStatus, { name: 'CommitmentStatus' })
registerEnumType(InvoiceStatus, { name: 'InvoiceStatus' })
registerEnumType(SortDirection, { name: 'SortDirection' })Import this file once — typically from app.module.ts and any schema generation script — so NestJS can resolve every enum referenced in your schema.
Recommended workflow
Add the command to your Prisma generation script so it stays in sync:
#!/bin/bash
# prisma-generate.sh
prisma generate
nestjs-generate-enums \
--src src \
--output src/@generated/registered-enums.tsLicense
MIT
