npm package: @jaeyeong/nestjs-graphql-search-field
Description: NestJS GraphQL decorator metadata for building TypeORM where inputs
Latest version: 0.1.1

# NestJS GraphQL Search Field Decorator

A small NestJS GraphQL decorator that stores metadata for building TypeORM `where` inputs.

## Install

```
npm i @jaeyeong/nestjs-graphql-search-field
```

## Usage

### SearchField

`SearchField` is a decorator that attaches metadata to an input field. The metadata includes:

- `type`: how to build the condition (see `SearchType`)
- `targetField`: optional actual column name (defaults to the property name)
- `graphqlType`: GraphQL field type for the input
- `joinColumn`: optional relation alias for joined fields (e.g. `user.name`)

### SearchType

`SearchType` defines how the value is translated into a query condition:

- `EQUAL`: `field = value`
- `LIKE`: `field LIKE %value%`
- `DATE_BETWEEN`: `field BETWEEN start AND end`
- `IN`: `field IN (...)`
- `IS_NULL`: `field IS NULL`
- `NOT`: `field != value`
- `NOT_IN`: `field NOT IN (...)`

```ts
import "reflect-metadata";
import { InputType } from "@nestjs/graphql";
import {
  SearchField,
  SearchType,
  searchAndFilter,
} from "@jaeyeong/nestjs-graphql-search-field";
import GraphQLJSON from "graphql-type-json";

@InputType()
export class ExampleWhereInput {
  @SearchField(
    {
      type: SearchType.EQUAL,
      graphqlType: () => [String],
    },
    { nullable: true },
  )
  entityId: string;

  @SearchField(
    {
      type: SearchType.LIKE,
      graphqlType: () => String,
      joinColumn: "user",
    },
    { nullable: true },
  )
  name: string;

  @SearchField(
    {
      type: SearchType.EQUAL,
      graphqlType: () => String,
    },
    { nullable: true },
  )
  category: string;

  @SearchField(
    {
      type: SearchType.DATE_BETWEEN,
      graphqlType: () => GraphQLJSON,
    },
    { nullable: true },
  )
  createdAt: {
    start: Date;
    end: Date;
  };

  @SearchField(
    {
      type: SearchType.IN,
      graphqlType: () => [String],
    },
    { nullable: true },
  )
  categoryIn: string[];

  @SearchField(
    {
      type: SearchType.IS_NULL,
      graphqlType: () => Boolean,
    },
    { nullable: true },
  )
  deletedAtIsNull: boolean;

  @SearchField(
    {
      type: SearchType.NOT,
      graphqlType: () => String,
    },
    { nullable: true },
  )
  categoryNot: string;

  @SearchField(
    {
      type: SearchType.NOT_IN,
      graphqlType: () => [String],
    },
    { nullable: true },
  )
  categoryNotIn: string[];
}
```

## Where Helpers

Helpers convert decorator metadata into TypeORM query conditions.

Build `FindOperator` filters:

```ts
import { searchAndFilter } from "@jaeyeong/nestjs-graphql-search-field";
import { Repository } from "typeorm";

const filter = searchAndFilter(where, ExampleWhereInput);
const results = await repo.find({ where: filter });
```

Apply to `QueryBuilder`:

```ts
import { applyWhereFromDecorators } from "@jaeyeong/nestjs-graphql-search-field";

const qb = repo.createQueryBuilder("entity");
applyWhereFromDecorators(qb, where, ExampleWhereInput);
const results = await qb.getMany();
```

## Exports

- `SearchField`
- `SearchType`
- `SEARCH_TYPE_KEY`
- `SEARCH_FIELD_KEY`
- `JOIN_COLUMN_KEY`
- `searchAndFilter`
- `applyWhereFromDecorators`

## License

MIT