|
1 | | -import { MeshTransform, MeshTransformOptions, YamlConfig } from '@graphql-mesh/types'; |
2 | | -import { applyRequestTransforms, applyResultTransforms, applySchemaTransforms } from '@graphql-mesh/utils'; |
3 | | -import { DelegationContext, SubschemaConfig, Transform } from '@graphql-tools/delegate'; |
4 | | -import { ExecutionResult, pruneSchema, Request } from '@graphql-tools/utils'; |
5 | | -import { FilterInputObjectFields, FilterTypes } from '@graphql-tools/wrap'; |
6 | | -import { GraphQLSchema } from 'graphql'; |
7 | | -import { matcher } from 'micromatch'; |
8 | | - |
9 | | -import FilterObjectFieldsAndArguments from './FilterObjectFieldsAndArguments'; |
10 | | -import { FilterRootFieldsAndArguments } from './FilterRootFieldsAndArguments'; |
11 | | - |
12 | | -export default class FilterTransform implements MeshTransform { |
13 | | - private transforms: Transform[] = []; |
14 | | - constructor(options: MeshTransformOptions<YamlConfig.Transform['filterSchema']>) { |
15 | | - const { config } = options; |
16 | | - for (const filter of config) { |
17 | | - const [typeName, fieldGlob] = filter.split('.'); |
18 | | - const isTypeMatch = matcher(typeName); |
19 | | - if (!fieldGlob) { |
20 | | - this.transforms.push( |
21 | | - new FilterTypes(type => { |
22 | | - return isTypeMatch(type.name); |
23 | | - }) |
24 | | - ); |
25 | | - } else { |
26 | | - // returns a match where second match = '{' or '!{' and third match being the content of the array |
27 | | - const outerArrayMatch = fieldGlob.match(/^(\{|!{)(.*)(?=\}$)/); |
28 | | - const fieldGlobStripped = outerArrayMatch ? outerArrayMatch[2] : fieldGlob; |
29 | | - |
30 | | - // split field parts (might include argument filter) |
31 | | - const fieldPatterns = fieldGlobStripped.match(/[\w-!*?[\]]+(\(.*?\))?/g); |
32 | | - |
33 | | - // extract field names only |
34 | | - let fixedFieldGlob = fieldPatterns.map(i => i.split('(')[0].trim()).join(','); |
35 | | - |
36 | | - // if input was glob glob array |
37 | | - if (outerArrayMatch) { |
38 | | - // strip array for single field inputs |
39 | | - if (fieldPatterns.length === 1) { |
40 | | - fixedFieldGlob = `${outerArrayMatch[1].replace('{', '')}${fixedFieldGlob}`; |
41 | | - } else { |
42 | | - fixedFieldGlob = `${outerArrayMatch[1]}${fixedFieldGlob}}`; |
43 | | - } |
44 | | - } |
45 | | - |
46 | | - const fieldArgsPatternMap = fieldPatterns.reduce((prev, match) => { |
47 | | - const fieldParts = match.split('('); |
48 | | - |
49 | | - if (fieldParts.length !== 2) { |
50 | | - return prev; |
51 | | - } |
52 | | - |
53 | | - const fieldName = fieldParts[0].replace(/!{|{|}/g, '').trim(); |
54 | | - const fixedArgGlob = fieldParts[1] |
55 | | - .split(')')[0] |
56 | | - .split(',') |
57 | | - .map(i => i.trim()) |
58 | | - .join(','); |
59 | | - |
60 | | - prev[fieldName] = fixedArgGlob; |
61 | | - return prev; |
62 | | - }, {}); |
63 | | - |
64 | | - const isMatch = matcher(fixedFieldGlob.trim()); |
65 | | - this.transforms.push( |
66 | | - new FilterRootFieldsAndArguments( |
67 | | - (rootTypeName, rootFieldName) => { |
68 | | - if (isTypeMatch(rootTypeName)) { |
69 | | - return isMatch(rootFieldName); |
70 | | - } |
71 | | - return true; |
72 | | - }, |
73 | | - (fieldName, argName) => { |
74 | | - if (!fieldArgsPatternMap[fieldName]) { |
75 | | - return true; |
76 | | - } |
77 | | - return matcher(fieldArgsPatternMap[fieldName])(argName); |
78 | | - } |
79 | | - ) |
80 | | - ); |
81 | | - |
82 | | - this.transforms.push( |
83 | | - new FilterObjectFieldsAndArguments( |
84 | | - (rootTypeName, rootFieldName) => { |
85 | | - if (isTypeMatch(rootTypeName)) { |
86 | | - return isMatch(rootFieldName); |
87 | | - } |
88 | | - return true; |
89 | | - }, |
90 | | - (fieldName, argName) => { |
91 | | - if (!fieldArgsPatternMap[fieldName]) { |
92 | | - return true; |
93 | | - } |
94 | | - return matcher(fieldArgsPatternMap[fieldName])(argName); |
95 | | - } |
96 | | - ) |
97 | | - ); |
98 | | - |
99 | | - this.transforms.push( |
100 | | - new FilterInputObjectFields((inputObjectTypeName, inputObjectFieldName) => { |
101 | | - if (isTypeMatch(inputObjectTypeName)) { |
102 | | - return isMatch(inputObjectFieldName); |
103 | | - } |
104 | | - return true; |
105 | | - }) |
106 | | - ); |
107 | | - } |
108 | | - } |
109 | | - } |
110 | | - |
111 | | - transformSchema( |
112 | | - originalWrappingSchema: GraphQLSchema, |
113 | | - subschemaConfig: SubschemaConfig, |
114 | | - transformedSchema?: GraphQLSchema |
115 | | - ) { |
116 | | - const returnedSchema = applySchemaTransforms( |
117 | | - originalWrappingSchema, |
118 | | - subschemaConfig, |
119 | | - transformedSchema, |
120 | | - this.transforms |
121 | | - ); |
122 | | - // TODO: Need a better solution |
123 | | - return pruneSchema(returnedSchema, { |
124 | | - skipEmptyCompositeTypePruning: false, |
125 | | - skipEmptyUnionPruning: true, |
126 | | - skipUnimplementedInterfacesPruning: true, |
127 | | - skipUnusedTypesPruning: true, |
| 1 | +import { YamlConfig, MeshTransformOptions } from '@graphql-mesh/types'; |
| 2 | +import WrapFilter from './wrapFilter'; |
| 3 | +import BareFilter from './bareFilter'; |
| 4 | + |
| 5 | +export default function FilterTransform(options: MeshTransformOptions<YamlConfig.Transform['filterSchema']>) { |
| 6 | + if (Array.isArray(options.config)) { |
| 7 | + return new WrapFilter({ |
| 8 | + ...options, |
| 9 | + config: { |
| 10 | + mode: 'wrap', |
| 11 | + filters: options.config, |
| 12 | + }, |
128 | 13 | }); |
129 | 14 | } |
130 | 15 |
|
131 | | - transformRequest( |
132 | | - originalRequest: Request, |
133 | | - delegationContext: DelegationContext, |
134 | | - transformationContext: Record<string, any> |
135 | | - ) { |
136 | | - return applyRequestTransforms(originalRequest, delegationContext, transformationContext, this.transforms); |
137 | | - } |
138 | | - |
139 | | - transformResult(originalResult: ExecutionResult, delegationContext: DelegationContext, transformationContext: any) { |
140 | | - return applyResultTransforms(originalResult, delegationContext, transformationContext, this.transforms); |
141 | | - } |
| 16 | + return options.config.mode === 'bare' ? new BareFilter(options) : new WrapFilter(options); |
142 | 17 | } |
0 commit comments