Skip to content

Commit

Permalink
Merge pull request #22 from thuoe/next
Browse files Browse the repository at this point in the history
Release `next`: 2024/03/18
  • Loading branch information
thuoe authored Mar 18, 2024
2 parents dd96a35 + 847d6fd commit a163f37
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 10 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
<a href="https://github.com/thuoe/gql-util-directives/actions/workflows/ci.yml">
<img src="https://github.com/thuoe/gql-util-directives/actions/workflows/ci.yml/badge.svg?branch=next" alt="CI status">
</a>
<a href="https://badge.fury.io/js/@thuoe%2Fgql-util-directives">
<img src="https://badge.fury.io/js/@thuoe%2Fgql-util-directives.svg" alt="npm version" height="18">
</a>
</p>

<h3 align="center">
Expand All @@ -23,7 +26,7 @@ Simple utility library for custom GraphQL schema directives
Install package:

```sh
npm install --save @thuoe/gql-util-directive
npm install --save @thuoe/gql-util-directives
```

Example of importing the `@regex` directive & instantiating with Apollo Server:
Expand Down
7 changes: 4 additions & 3 deletions src/directives/cache.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { MapperKind, getDirective, mapSchema } from '@graphql-tools/utils'
import { MapperKind, mapSchema } from '@graphql-tools/utils'
import { fetchDirective } from '@src/utils'
import { GraphQLError, GraphQLSchema, defaultFieldResolver } from 'graphql'

export interface CachingImpl {
Expand Down Expand Up @@ -26,11 +27,11 @@ const inMemoryCache: CachingImpl = {

const cacheDirective = ({ directiveName = 'cache', cache = inMemoryCache }: Partial<Params> = {}) => {
return {
cacheDirectiveTypeDefs: `directive @${directiveName}(key: String, ttl: Int) on FIELD_DEFINITION`,
cacheDirectiveTypeDefs: `directive @${directiveName}(key: String!, ttl: Int!) on FIELD_DEFINITION`,
cacheDirectiveTransformer: (schema: GraphQLSchema) => mapSchema(schema, {
[MapperKind.OBJECT_FIELD]: fieldConfig => {
const { resolve = defaultFieldResolver } = fieldConfig
const cacheDirective = getDirective(schema, fieldConfig, directiveName)?.[0]
const cacheDirective = fetchDirective<{ ttl: number, key: string }>(schema, fieldConfig, directiveName)
if (cacheDirective) {
const { ttl, key } = cacheDirective
return {
Expand Down
7 changes: 4 additions & 3 deletions src/directives/encode.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { MapperKind, getDirective, mapSchema } from '@graphql-tools/utils'
import { MapperKind, mapSchema } from '@graphql-tools/utils'
import { fetchDirective } from '@src/utils'
import { GraphQLError, GraphQLSchema, defaultFieldResolver } from 'graphql'

const encodingDirective = (directiveName: string = 'encode') => {
return {
encodingDirectiveTypeDefs: `directive @${directiveName}(method: String) on FIELD_DEFINITION`,
encodingDirectiveTypeDefs: `directive @${directiveName}(method: String!) on FIELD_DEFINITION`,
encodingDirectiveTransformer: (schema: GraphQLSchema) => mapSchema(schema, {
[MapperKind.OBJECT_FIELD]: fieldConfig => {
const encodingDirective = getDirective(schema, fieldConfig, directiveName)?.[0]
const encodingDirective = fetchDirective<{ method: string }>(schema, fieldConfig, directiveName)
if (encodingDirective) {
const { method } = encodingDirective
const { resolve = defaultFieldResolver } = fieldConfig
Expand Down
7 changes: 4 additions & 3 deletions src/directives/regex.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { MapperKind, getDirective, mapSchema } from '@graphql-tools/utils'
import { MapperKind, mapSchema } from '@graphql-tools/utils'
import { GraphQLError, GraphQLSchema, defaultFieldResolver, isScalarType } from 'graphql'
import ValidationError from '@src/errors'
import { fetchDirective } from '@src/utils'

const regexDirective = (directiveName: string = 'regex') => {
return {
regexDirectiveTypeDefs: `directive @${directiveName}(pattern: String) on FIELD_DEFINITION`,
regexDirectiveTypeDefs: `directive @${directiveName}(pattern: String!) on FIELD_DEFINITION`,
regexDirectiveTransformer: (schema: GraphQLSchema) => mapSchema(schema, {
[MapperKind.OBJECT_FIELD]: fieldConfig => {
const regexDirective = getDirective(schema, fieldConfig, directiveName)?.[0]
const regexDirective = fetchDirective<{ pattern: string }>(schema, fieldConfig, directiveName)
if (regexDirective && isScalarType(fieldConfig.type)) {
const { pattern } = regexDirective
const { resolve = defaultFieldResolver } = fieldConfig
Expand Down
15 changes: 15 additions & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { DirectableGraphQLObject, getDirective } from '@graphql-tools/utils'
import { GraphQLSchema } from 'graphql'

export const isValidDirective = <T extends Record<string, unknown>>(directive: unknown): directive is T => {
return typeof directive === 'object' && directive !== null
}

export const fetchDirective = <T extends Record<string, unknown>>(schema: GraphQLSchema, fieldConfig: DirectableGraphQLObject, directiveName: string): T => {
const directive = getDirective(schema, fieldConfig, directiveName)?.[0]
const isValid = isValidDirective<T>(directive)
if (isValid) {
return directive
}
return null
}

0 comments on commit a163f37

Please sign in to comment.