|
1 | | -# Nested filter prisma |
| 1 | +# Nested filter prisma peer |
2 | 2 |
|
3 | 3 | Nested filters allow automatically filter data resolved for projections based on hierarchy of parent queries or mutations |
4 | | - |
5 | | -## Features |
6 | | - |
7 | | -* Transitivite relations A → B, B → C ⇒ A → C |
8 | | -* Automatically applied filters by plugins |
9 | | -* Support to extend existing nested filters |
10 | | -* Validation of not mapped parent entities with support of ignore rules. |
11 | | - |
12 | | -## Api reference |
13 | | -* 🍎 TBD 🍎 |
14 | | - |
15 | | -## Example |
16 | | - |
17 | | -#### **`Prisma model`** |
18 | | -```prisma:prisma/schema.prisma |
19 | | -generator client { |
20 | | - provider = "prisma-client-js" |
21 | | - binaryTargets = ["native", "rhel-openssl-1.0.x"] |
22 | | - // previewFeatures = [] |
23 | | -} |
24 | | -
|
25 | | -datasource db { |
26 | | - provider = "postgresql" |
27 | | - url = env("DATABASE_URL") |
28 | | -} |
29 | | -
|
30 | | -model Post { |
31 | | - id String @id @default(cuid()) |
32 | | - deleted Boolean @default(false) |
33 | | - description String |
34 | | - commentList Comment[] |
35 | | -} |
36 | | -
|
37 | | -model Comment { |
38 | | - id String @id @default(cuid()) |
39 | | - deleted Boolean @default(false) |
40 | | - text String |
41 | | - postId String |
42 | | - post Post @relation(fields: [postId], references: [id]) |
43 | | - authorId String |
44 | | - author Author @relation(fields: [authorId], references: [id]) |
45 | | -} |
46 | | -
|
47 | | -model Author { |
48 | | - id String @id @default(cuid()) |
49 | | - deleted Boolean @default(false) |
50 | | - firstName String |
51 | | - lastName String |
52 | | - commentList Comment[] |
53 | | -} |
54 | | -
|
55 | | -``` |
56 | | - |
57 | | -#### **`Query`** |
58 | | -```graphql |
59 | | -query { |
60 | | - post { |
61 | | - id |
62 | | - commentList { # let's asume this list should return comments that belong to post above |
63 | | - id |
64 | | - author { |
65 | | - id |
66 | | - commentList { # let's assume that this list shourd return only comments that belong to post and author above |
67 | | - id |
68 | | - } |
69 | | - } |
70 | | - } |
71 | | - } |
72 | | -} |
73 | | -``` |
74 | | - |
75 | | -#### **`Context.ts`** |
76 | | -```typescript:example/Context.ts [7] |
77 | | -import { createNestedFilterMap, ResultCache, createContext as _createContext } from '@txo/nested-filter-prisma' |
78 | | -import { PrismaClient } from '@prisma/client' |
79 | | -import type { Context } from '@txo/prisma-graphql' |
80 | | - |
81 | | -import { nestedFilterList } from './NestedFilters' |
82 | | - |
83 | | -export const createContext = (attributes?: { resultCache?: ResultCache }): Context => _createContext({ |
84 | | - prisma: null as unknown as PrismaClient, // << only for tests, usually we create client here by new PrismaClient() |
85 | | - nestedFilterMap: createNestedFilterMap(nestedFilterList), |
86 | | - request: { |
87 | | - headers: {}, |
88 | | - }, |
89 | | - resultCache: attributes?.resultCache as unknown as ResultCache, |
90 | | -}) |
91 | | - |
92 | | -export const context = createContext() |
93 | | - |
94 | | -``` |
95 | | - |
96 | | -#### **`NestedFilters.ts`** |
97 | | -```typescript:example/NestedFilters.ts [7] |
98 | | -import { mapFilter, mapValue, nestedFilter } from '@txo/nested-filter-prisma' |
99 | | -import { Prisma, Comment, Post, Author } from '@prisma/client' |
100 | | - |
101 | | -declare module '@txo/nested-filter-prisma' { |
102 | | - export interface AllNestedFilters { |
103 | | - Author: { |
104 | | - structure: Author, |
105 | | - where: Prisma.AuthorWhereInput, |
106 | | - }, |
107 | | - Comment: { |
108 | | - structure: Comment, |
109 | | - where: Prisma.CommentWhereInput, |
110 | | - }, |
111 | | - Post: { |
112 | | - structure: Post, |
113 | | - where: Prisma.PostWhereInput, |
114 | | - }, |
115 | | - } |
116 | | -} |
117 | | - |
118 | | -export const PostNestedFilter = nestedFilter({ |
119 | | - type: 'Post', |
120 | | - mapping: { |
121 | | - Post: { |
122 | | - id: mapValue('Post.id'), |
123 | | - deleted: false, |
124 | | - }, |
125 | | - }, |
126 | | -}) |
127 | | - |
128 | | -export const AuthorNestedFilter = nestedFilter({ |
129 | | - type: 'Author', |
130 | | - mapping: { |
131 | | - Author: { |
132 | | - id: mapValue('Author.id'), |
133 | | - deleted: false, |
134 | | - }, |
135 | | - }, |
136 | | -}) |
137 | | - |
138 | | -export const CommentNestedFilter = nestedFilter({ |
139 | | - type: 'Comment', |
140 | | - mapping: { |
141 | | - Comment: { |
142 | | - id: mapValue('Comment.id'), |
143 | | - deleted: false, |
144 | | - }, |
145 | | - }, |
146 | | -}) |
147 | | - |
148 | | -export const CommentNestedFilterExtended = nestedFilter({ |
149 | | - type: 'Comment', |
150 | | - mapping: { |
151 | | - Post: { |
152 | | - post: mapFilter('Post'), |
153 | | - }, |
154 | | - }, |
155 | | -}) |
156 | | - |
157 | | -export const nestedFilterList = [ |
158 | | - PostNestedFilter, |
159 | | - AuthorNestedFilter, |
160 | | - CommentNestedFilter, |
161 | | - CommentNestedFilterExtended, |
162 | | -] |
163 | | - |
164 | | -``` |
165 | | - |
166 | | -#### **`Using nestedFilters on field declaration on Author type`** |
167 | | -```typescript |
168 | | -import { nonNull, extendType } from 'nexus' |
169 | | - |
170 | | -import { mapFilter, ignored } from '@txo/nested-filter-prisma' |
171 | | - |
172 | | -export const authorCommentListField = extendType({ |
173 | | - type: 'Author', |
174 | | - definition: t => { |
175 | | - t.list.field('commentList', { |
176 | | - type: 'Comment', |
177 | | - resolve: async (parent, args, ctx, info) => { |
178 | | - return ctx.prisma.comment.findMany({ |
179 | | - where: ctx.withNestedFilters({ |
180 | | - type: 'Comment', |
181 | | - mapping: { |
182 | | - Post: { post: mapFilter('Post') }, |
183 | | - Comment: ignored(), |
184 | | - Author: { author: mapFilter('Author') }, |
185 | | - }, |
186 | | - }) |
187 | | - }) |
188 | | - }), |
189 | | - }) |
190 | | - }, |
191 | | -}) |
192 | | -``` |
0 commit comments