graphile-connection-filter 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +23 -0
- package/README.md +107 -0
- package/augmentations.d.ts +104 -0
- package/augmentations.js +11 -0
- package/esm/augmentations.d.ts +104 -0
- package/esm/augmentations.js +9 -0
- package/esm/index.d.ts +55 -0
- package/esm/index.js +56 -0
- package/esm/plugins/ConnectionFilterArgPlugin.d.ts +13 -0
- package/esm/plugins/ConnectionFilterArgPlugin.js +96 -0
- package/esm/plugins/ConnectionFilterAttributesPlugin.d.ts +14 -0
- package/esm/plugins/ConnectionFilterAttributesPlugin.js +79 -0
- package/esm/plugins/ConnectionFilterBackwardRelationsPlugin.d.ts +33 -0
- package/esm/plugins/ConnectionFilterBackwardRelationsPlugin.js +398 -0
- package/esm/plugins/ConnectionFilterComputedAttributesPlugin.d.ts +19 -0
- package/esm/plugins/ConnectionFilterComputedAttributesPlugin.js +133 -0
- package/esm/plugins/ConnectionFilterCustomOperatorsPlugin.d.ts +35 -0
- package/esm/plugins/ConnectionFilterCustomOperatorsPlugin.js +129 -0
- package/esm/plugins/ConnectionFilterForwardRelationsPlugin.d.ts +28 -0
- package/esm/plugins/ConnectionFilterForwardRelationsPlugin.js +168 -0
- package/esm/plugins/ConnectionFilterInflectionPlugin.d.ts +11 -0
- package/esm/plugins/ConnectionFilterInflectionPlugin.js +27 -0
- package/esm/plugins/ConnectionFilterLogicalOperatorsPlugin.d.ts +15 -0
- package/esm/plugins/ConnectionFilterLogicalOperatorsPlugin.js +86 -0
- package/esm/plugins/ConnectionFilterOperatorsPlugin.d.ts +21 -0
- package/esm/plugins/ConnectionFilterOperatorsPlugin.js +677 -0
- package/esm/plugins/ConnectionFilterTypesPlugin.d.ts +12 -0
- package/esm/plugins/ConnectionFilterTypesPlugin.js +225 -0
- package/esm/plugins/index.d.ts +11 -0
- package/esm/plugins/index.js +11 -0
- package/esm/plugins/operatorApply.d.ts +11 -0
- package/esm/plugins/operatorApply.js +70 -0
- package/esm/preset.d.ts +35 -0
- package/esm/preset.js +72 -0
- package/esm/types.d.ts +146 -0
- package/esm/types.js +4 -0
- package/esm/utils.d.ts +44 -0
- package/esm/utils.js +112 -0
- package/index.d.ts +55 -0
- package/index.js +77 -0
- package/package.json +58 -0
- package/plugins/ConnectionFilterArgPlugin.d.ts +13 -0
- package/plugins/ConnectionFilterArgPlugin.js +99 -0
- package/plugins/ConnectionFilterAttributesPlugin.d.ts +14 -0
- package/plugins/ConnectionFilterAttributesPlugin.js +82 -0
- package/plugins/ConnectionFilterBackwardRelationsPlugin.d.ts +33 -0
- package/plugins/ConnectionFilterBackwardRelationsPlugin.js +401 -0
- package/plugins/ConnectionFilterComputedAttributesPlugin.d.ts +19 -0
- package/plugins/ConnectionFilterComputedAttributesPlugin.js +136 -0
- package/plugins/ConnectionFilterCustomOperatorsPlugin.d.ts +35 -0
- package/plugins/ConnectionFilterCustomOperatorsPlugin.js +132 -0
- package/plugins/ConnectionFilterForwardRelationsPlugin.d.ts +28 -0
- package/plugins/ConnectionFilterForwardRelationsPlugin.js +171 -0
- package/plugins/ConnectionFilterInflectionPlugin.d.ts +11 -0
- package/plugins/ConnectionFilterInflectionPlugin.js +30 -0
- package/plugins/ConnectionFilterLogicalOperatorsPlugin.d.ts +15 -0
- package/plugins/ConnectionFilterLogicalOperatorsPlugin.js +89 -0
- package/plugins/ConnectionFilterOperatorsPlugin.d.ts +21 -0
- package/plugins/ConnectionFilterOperatorsPlugin.js +680 -0
- package/plugins/ConnectionFilterTypesPlugin.d.ts +12 -0
- package/plugins/ConnectionFilterTypesPlugin.js +228 -0
- package/plugins/index.d.ts +11 -0
- package/plugins/index.js +25 -0
- package/plugins/operatorApply.d.ts +11 -0
- package/plugins/operatorApply.js +73 -0
- package/preset.d.ts +35 -0
- package/preset.js +75 -0
- package/types.d.ts +146 -0
- package/types.js +7 -0
- package/utils.d.ts +44 -0
- package/utils.js +119 -0
|
@@ -0,0 +1,680 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConnectionFilterOperatorsPlugin = void 0;
|
|
4
|
+
require("../augmentations");
|
|
5
|
+
const operatorApply_1 = require("./operatorApply");
|
|
6
|
+
const version = '1.0.0';
|
|
7
|
+
/**
|
|
8
|
+
* ConnectionFilterOperatorsPlugin
|
|
9
|
+
*
|
|
10
|
+
* Registers all built-in filter operators on the per-scalar operator types
|
|
11
|
+
* (e.g. StringFilter, IntFilter, DatetimeFilter, etc.).
|
|
12
|
+
*
|
|
13
|
+
* Operator categories:
|
|
14
|
+
* - Standard: isNull, equalTo, notEqualTo, distinctFrom, notDistinctFrom, in, notIn
|
|
15
|
+
* - Sort: lessThan, lessThanOrEqualTo, greaterThan, greaterThanOrEqualTo
|
|
16
|
+
* - Pattern matching (text-like): includes, startsWith, endsWith, like + insensitive variants
|
|
17
|
+
* - Hstore: contains, containsKey, containsAllKeys, containsAnyKeys, containedBy
|
|
18
|
+
* - JSONB: contains, containsKey, containsAllKeys, containsAnyKeys, containedBy
|
|
19
|
+
* - Inet: contains, containsOrEqualTo, containedBy, containedByOrEqualTo, containsOrContainedBy
|
|
20
|
+
* - Array: contains, containedBy, overlaps, anyEqualTo, anyNotEqualTo, any comparison operators
|
|
21
|
+
* - Range: contains, containsElement, containedBy, overlaps, strictlyLeftOf, strictlyRightOf, etc.
|
|
22
|
+
* - Enum: standard + sort operators
|
|
23
|
+
* - Case-insensitive variants of standard and sort operators
|
|
24
|
+
*/
|
|
25
|
+
exports.ConnectionFilterOperatorsPlugin = {
|
|
26
|
+
name: 'ConnectionFilterOperatorsPlugin',
|
|
27
|
+
version,
|
|
28
|
+
description: 'Registers built-in filter operators for all scalar types',
|
|
29
|
+
schema: {
|
|
30
|
+
hooks: {
|
|
31
|
+
GraphQLInputObjectType_fields(fields, build, context) {
|
|
32
|
+
const { extend, graphql: { GraphQLNonNull, GraphQLList, isListType, isNonNullType }, dataplanPg: { isEnumCodec, listOfCodec, TYPES, sqlValueWithCodec }, sql, escapeLikeWildcards, options: { connectionFilterAllowedOperators, connectionFilterOperatorNames, }, EXPORTABLE, } = build;
|
|
33
|
+
const { scope: { pgConnectionFilterOperators }, fieldWithHooks, Self, } = context;
|
|
34
|
+
if (!pgConnectionFilterOperators) {
|
|
35
|
+
return fields;
|
|
36
|
+
}
|
|
37
|
+
// --- Helper functions for type resolution ---
|
|
38
|
+
/** Turn `[Foo]` into `[Foo!]` */
|
|
39
|
+
const resolveTypeToListOfNonNullable = EXPORTABLE((GraphQLList, GraphQLNonNull, isListType, isNonNullType) => function (type) {
|
|
40
|
+
if (isListType(type) && !isNonNullType(type.ofType)) {
|
|
41
|
+
return new GraphQLList(new GraphQLNonNull(type.ofType));
|
|
42
|
+
}
|
|
43
|
+
return type;
|
|
44
|
+
}, [GraphQLList, GraphQLNonNull, isListType, isNonNullType]);
|
|
45
|
+
// Types that need casting to text for case-sensitive comparisons
|
|
46
|
+
const forceTextTypesSensitive = [TYPES.citext, TYPES.char, TYPES.bpchar];
|
|
47
|
+
const forceTextTypesInsensitive = [TYPES.char, TYPES.bpchar];
|
|
48
|
+
const resolveDomains = EXPORTABLE(() => function (c) {
|
|
49
|
+
let current = c;
|
|
50
|
+
while (current.domainOfCodec) {
|
|
51
|
+
current = current.domainOfCodec;
|
|
52
|
+
}
|
|
53
|
+
return current;
|
|
54
|
+
}, []);
|
|
55
|
+
// --- Codec resolution helpers for sensitive/insensitive comparisons ---
|
|
56
|
+
const resolveArrayInputCodecSensitive = EXPORTABLE((TYPES, forceTextTypesSensitive, listOfCodec, resolveDomains) => function (c) {
|
|
57
|
+
if (forceTextTypesSensitive.includes(resolveDomains(c))) {
|
|
58
|
+
return listOfCodec(TYPES.text, { extensions: { listItemNonNull: true } });
|
|
59
|
+
}
|
|
60
|
+
return listOfCodec(c, { extensions: { listItemNonNull: true } });
|
|
61
|
+
}, [TYPES, forceTextTypesSensitive, listOfCodec, resolveDomains]);
|
|
62
|
+
const resolveArrayItemInputCodecSensitive = EXPORTABLE((TYPES, forceTextTypesSensitive, resolveDomains) => function (c) {
|
|
63
|
+
if (c.arrayOfCodec) {
|
|
64
|
+
if (forceTextTypesSensitive.includes(resolveDomains(c.arrayOfCodec))) {
|
|
65
|
+
return TYPES.text;
|
|
66
|
+
}
|
|
67
|
+
return c.arrayOfCodec;
|
|
68
|
+
}
|
|
69
|
+
throw new Error('Expected array codec');
|
|
70
|
+
}, [TYPES, forceTextTypesSensitive, resolveDomains]);
|
|
71
|
+
const resolveInputCodecSensitive = EXPORTABLE((TYPES, forceTextTypesSensitive, listOfCodec, resolveDomains) => function (c) {
|
|
72
|
+
if (c.arrayOfCodec) {
|
|
73
|
+
if (forceTextTypesSensitive.includes(resolveDomains(c.arrayOfCodec))) {
|
|
74
|
+
return listOfCodec(TYPES.text, {
|
|
75
|
+
extensions: { listItemNonNull: c.extensions?.listItemNonNull },
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return c;
|
|
79
|
+
}
|
|
80
|
+
if (forceTextTypesSensitive.includes(resolveDomains(c))) {
|
|
81
|
+
return TYPES.text;
|
|
82
|
+
}
|
|
83
|
+
return c;
|
|
84
|
+
}, [TYPES, forceTextTypesSensitive, listOfCodec, resolveDomains]);
|
|
85
|
+
const resolveSqlIdentifierSensitive = EXPORTABLE((TYPES, forceTextTypesSensitive, listOfCodec, resolveDomains, sql) => function (identifier, c) {
|
|
86
|
+
if (c.arrayOfCodec &&
|
|
87
|
+
forceTextTypesSensitive.includes(resolveDomains(c.arrayOfCodec))) {
|
|
88
|
+
return [
|
|
89
|
+
sql `(${identifier})::text[]`,
|
|
90
|
+
listOfCodec(TYPES.text, {
|
|
91
|
+
extensions: { listItemNonNull: c.extensions?.listItemNonNull },
|
|
92
|
+
}),
|
|
93
|
+
];
|
|
94
|
+
}
|
|
95
|
+
else if (forceTextTypesSensitive.includes(resolveDomains(c))) {
|
|
96
|
+
return [sql `(${identifier})::text`, TYPES.text];
|
|
97
|
+
}
|
|
98
|
+
return [identifier, c];
|
|
99
|
+
}, [TYPES, forceTextTypesSensitive, listOfCodec, resolveDomains, sql]);
|
|
100
|
+
const resolveInputCodecInsensitive = EXPORTABLE((TYPES, forceTextTypesInsensitive, listOfCodec, resolveDomains) => function (c) {
|
|
101
|
+
if (c.arrayOfCodec) {
|
|
102
|
+
if (forceTextTypesInsensitive.includes(resolveDomains(c.arrayOfCodec))) {
|
|
103
|
+
return listOfCodec(TYPES.text, {
|
|
104
|
+
extensions: { listItemNonNull: c.extensions?.listItemNonNull },
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return c;
|
|
108
|
+
}
|
|
109
|
+
if (forceTextTypesInsensitive.includes(resolveDomains(c))) {
|
|
110
|
+
return TYPES.text;
|
|
111
|
+
}
|
|
112
|
+
return c;
|
|
113
|
+
}, [TYPES, forceTextTypesInsensitive, listOfCodec, resolveDomains]);
|
|
114
|
+
const resolveSqlIdentifierInsensitive = EXPORTABLE((TYPES, forceTextTypesInsensitive, listOfCodec, resolveDomains, sql) => function (identifier, c) {
|
|
115
|
+
if (c.arrayOfCodec &&
|
|
116
|
+
forceTextTypesInsensitive.includes(resolveDomains(c.arrayOfCodec))) {
|
|
117
|
+
return [
|
|
118
|
+
sql `(${identifier})::text[]`,
|
|
119
|
+
listOfCodec(TYPES.text, {
|
|
120
|
+
extensions: { listItemNonNull: c.extensions?.listItemNonNull },
|
|
121
|
+
}),
|
|
122
|
+
];
|
|
123
|
+
}
|
|
124
|
+
else if (forceTextTypesInsensitive.includes(resolveDomains(c))) {
|
|
125
|
+
return [sql `(${identifier})::text`, TYPES.text];
|
|
126
|
+
}
|
|
127
|
+
return [identifier, c];
|
|
128
|
+
}, [TYPES, forceTextTypesInsensitive, listOfCodec, resolveDomains, sql]);
|
|
129
|
+
// --- Operator definitions ---
|
|
130
|
+
const standardOperators = {
|
|
131
|
+
isNull: {
|
|
132
|
+
description: 'Is null (if `true` is specified) or is not null (if `false` is specified).',
|
|
133
|
+
resolveInputCodec: EXPORTABLE((TYPES) => () => TYPES.boolean, [TYPES]),
|
|
134
|
+
resolveSqlValue: EXPORTABLE((sql) => () => sql.null, [sql]),
|
|
135
|
+
resolve: EXPORTABLE((sql) => (i, _v, input) => sql `${i} ${input ? sql `IS NULL` : sql `IS NOT NULL`}`, [sql]),
|
|
136
|
+
},
|
|
137
|
+
equalTo: {
|
|
138
|
+
description: 'Equal to the specified value.',
|
|
139
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} = ${v}`, [sql]),
|
|
140
|
+
resolveInputCodec: resolveInputCodecSensitive,
|
|
141
|
+
resolveSqlIdentifier: resolveSqlIdentifierSensitive,
|
|
142
|
+
},
|
|
143
|
+
notEqualTo: {
|
|
144
|
+
description: 'Not equal to the specified value.',
|
|
145
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} <> ${v}`, [sql]),
|
|
146
|
+
resolveInputCodec: resolveInputCodecSensitive,
|
|
147
|
+
resolveSqlIdentifier: resolveSqlIdentifierSensitive,
|
|
148
|
+
},
|
|
149
|
+
distinctFrom: {
|
|
150
|
+
description: 'Not equal to the specified value, treating null like an ordinary value.',
|
|
151
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} IS DISTINCT FROM ${v}`, [sql]),
|
|
152
|
+
resolveInputCodec: resolveInputCodecSensitive,
|
|
153
|
+
resolveSqlIdentifier: resolveSqlIdentifierSensitive,
|
|
154
|
+
},
|
|
155
|
+
notDistinctFrom: {
|
|
156
|
+
description: 'Equal to the specified value, treating null like an ordinary value.',
|
|
157
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} IS NOT DISTINCT FROM ${v}`, [sql]),
|
|
158
|
+
resolveInputCodec: resolveInputCodecSensitive,
|
|
159
|
+
resolveSqlIdentifier: resolveSqlIdentifierSensitive,
|
|
160
|
+
},
|
|
161
|
+
in: {
|
|
162
|
+
description: 'Included in the specified list.',
|
|
163
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} = ANY(${v})`, [sql]),
|
|
164
|
+
resolveInputCodec: resolveArrayInputCodecSensitive,
|
|
165
|
+
resolveSqlIdentifier: resolveSqlIdentifierSensitive,
|
|
166
|
+
resolveType: resolveTypeToListOfNonNullable,
|
|
167
|
+
},
|
|
168
|
+
notIn: {
|
|
169
|
+
description: 'Not included in the specified list.',
|
|
170
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} <> ALL(${v})`, [sql]),
|
|
171
|
+
resolveInputCodec: resolveArrayInputCodecSensitive,
|
|
172
|
+
resolveSqlIdentifier: resolveSqlIdentifierSensitive,
|
|
173
|
+
resolveType: resolveTypeToListOfNonNullable,
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
const sortOperators = {
|
|
177
|
+
lessThan: {
|
|
178
|
+
description: 'Less than the specified value.',
|
|
179
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} < ${v}`, [sql]),
|
|
180
|
+
resolveInputCodec: resolveInputCodecSensitive,
|
|
181
|
+
resolveSqlIdentifier: resolveSqlIdentifierSensitive,
|
|
182
|
+
},
|
|
183
|
+
lessThanOrEqualTo: {
|
|
184
|
+
description: 'Less than or equal to the specified value.',
|
|
185
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} <= ${v}`, [sql]),
|
|
186
|
+
resolveInputCodec: resolveInputCodecSensitive,
|
|
187
|
+
resolveSqlIdentifier: resolveSqlIdentifierSensitive,
|
|
188
|
+
},
|
|
189
|
+
greaterThan: {
|
|
190
|
+
description: 'Greater than the specified value.',
|
|
191
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} > ${v}`, [sql]),
|
|
192
|
+
resolveInputCodec: resolveInputCodecSensitive,
|
|
193
|
+
resolveSqlIdentifier: resolveSqlIdentifierSensitive,
|
|
194
|
+
},
|
|
195
|
+
greaterThanOrEqualTo: {
|
|
196
|
+
description: 'Greater than or equal to the specified value.',
|
|
197
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} >= ${v}`, [sql]),
|
|
198
|
+
resolveInputCodec: resolveInputCodecSensitive,
|
|
199
|
+
resolveSqlIdentifier: resolveSqlIdentifierSensitive,
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
const patternMatchingOperators = {
|
|
203
|
+
includes: {
|
|
204
|
+
description: 'Contains the specified string (case-sensitive).',
|
|
205
|
+
resolveInput: EXPORTABLE((escapeLikeWildcards) => (input) => `%${escapeLikeWildcards(input)}%`, [escapeLikeWildcards]),
|
|
206
|
+
resolveInputCodec: resolveInputCodecSensitive,
|
|
207
|
+
resolveSqlIdentifier: resolveSqlIdentifierSensitive,
|
|
208
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} LIKE ${v}`, [sql]),
|
|
209
|
+
},
|
|
210
|
+
notIncludes: {
|
|
211
|
+
description: 'Does not contain the specified string (case-sensitive).',
|
|
212
|
+
resolveInput: EXPORTABLE((escapeLikeWildcards) => (input) => `%${escapeLikeWildcards(input)}%`, [escapeLikeWildcards]),
|
|
213
|
+
resolveInputCodec: resolveInputCodecSensitive,
|
|
214
|
+
resolveSqlIdentifier: resolveSqlIdentifierSensitive,
|
|
215
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} NOT LIKE ${v}`, [sql]),
|
|
216
|
+
},
|
|
217
|
+
includesInsensitive: {
|
|
218
|
+
description: 'Contains the specified string (case-insensitive).',
|
|
219
|
+
resolveInput: EXPORTABLE((escapeLikeWildcards) => (input) => `%${escapeLikeWildcards(input)}%`, [escapeLikeWildcards]),
|
|
220
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} ILIKE ${v}`, [sql]),
|
|
221
|
+
resolveInputCodec: resolveInputCodecInsensitive,
|
|
222
|
+
resolveSqlIdentifier: resolveSqlIdentifierInsensitive,
|
|
223
|
+
},
|
|
224
|
+
notIncludesInsensitive: {
|
|
225
|
+
description: 'Does not contain the specified string (case-insensitive).',
|
|
226
|
+
resolveInput: EXPORTABLE((escapeLikeWildcards) => (input) => `%${escapeLikeWildcards(input)}%`, [escapeLikeWildcards]),
|
|
227
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} NOT ILIKE ${v}`, [sql]),
|
|
228
|
+
resolveInputCodec: resolveInputCodecInsensitive,
|
|
229
|
+
resolveSqlIdentifier: resolveSqlIdentifierInsensitive,
|
|
230
|
+
},
|
|
231
|
+
startsWith: {
|
|
232
|
+
description: 'Starts with the specified string (case-sensitive).',
|
|
233
|
+
resolveInput: EXPORTABLE((escapeLikeWildcards) => (input) => `${escapeLikeWildcards(input)}%`, [escapeLikeWildcards]),
|
|
234
|
+
resolveInputCodec: resolveInputCodecSensitive,
|
|
235
|
+
resolveSqlIdentifier: resolveSqlIdentifierSensitive,
|
|
236
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} LIKE ${v}`, [sql]),
|
|
237
|
+
},
|
|
238
|
+
notStartsWith: {
|
|
239
|
+
description: 'Does not start with the specified string (case-sensitive).',
|
|
240
|
+
resolveInput: EXPORTABLE((escapeLikeWildcards) => (input) => `${escapeLikeWildcards(input)}%`, [escapeLikeWildcards]),
|
|
241
|
+
resolveInputCodec: resolveInputCodecSensitive,
|
|
242
|
+
resolveSqlIdentifier: resolveSqlIdentifierSensitive,
|
|
243
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} NOT LIKE ${v}`, [sql]),
|
|
244
|
+
},
|
|
245
|
+
startsWithInsensitive: {
|
|
246
|
+
description: 'Starts with the specified string (case-insensitive).',
|
|
247
|
+
resolveInput: EXPORTABLE((escapeLikeWildcards) => (input) => `${escapeLikeWildcards(input)}%`, [escapeLikeWildcards]),
|
|
248
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} ILIKE ${v}`, [sql]),
|
|
249
|
+
resolveInputCodec: resolveInputCodecInsensitive,
|
|
250
|
+
resolveSqlIdentifier: resolveSqlIdentifierInsensitive,
|
|
251
|
+
},
|
|
252
|
+
notStartsWithInsensitive: {
|
|
253
|
+
description: 'Does not start with the specified string (case-insensitive).',
|
|
254
|
+
resolveInput: EXPORTABLE((escapeLikeWildcards) => (input) => `${escapeLikeWildcards(input)}%`, [escapeLikeWildcards]),
|
|
255
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} NOT ILIKE ${v}`, [sql]),
|
|
256
|
+
resolveInputCodec: resolveInputCodecInsensitive,
|
|
257
|
+
resolveSqlIdentifier: resolveSqlIdentifierInsensitive,
|
|
258
|
+
},
|
|
259
|
+
endsWith: {
|
|
260
|
+
description: 'Ends with the specified string (case-sensitive).',
|
|
261
|
+
resolveInput: EXPORTABLE((escapeLikeWildcards) => (input) => `%${escapeLikeWildcards(input)}`, [escapeLikeWildcards]),
|
|
262
|
+
resolveInputCodec: resolveInputCodecSensitive,
|
|
263
|
+
resolveSqlIdentifier: resolveSqlIdentifierSensitive,
|
|
264
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} LIKE ${v}`, [sql]),
|
|
265
|
+
},
|
|
266
|
+
notEndsWith: {
|
|
267
|
+
description: 'Does not end with the specified string (case-sensitive).',
|
|
268
|
+
resolveInput: EXPORTABLE((escapeLikeWildcards) => (input) => `%${escapeLikeWildcards(input)}`, [escapeLikeWildcards]),
|
|
269
|
+
resolveInputCodec: resolveInputCodecSensitive,
|
|
270
|
+
resolveSqlIdentifier: resolveSqlIdentifierSensitive,
|
|
271
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} NOT LIKE ${v}`, [sql]),
|
|
272
|
+
},
|
|
273
|
+
endsWithInsensitive: {
|
|
274
|
+
description: 'Ends with the specified string (case-insensitive).',
|
|
275
|
+
resolveInput: EXPORTABLE((escapeLikeWildcards) => (input) => `%${escapeLikeWildcards(input)}`, [escapeLikeWildcards]),
|
|
276
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} ILIKE ${v}`, [sql]),
|
|
277
|
+
resolveInputCodec: resolveInputCodecInsensitive,
|
|
278
|
+
resolveSqlIdentifier: resolveSqlIdentifierInsensitive,
|
|
279
|
+
},
|
|
280
|
+
notEndsWithInsensitive: {
|
|
281
|
+
description: 'Does not end with the specified string (case-insensitive).',
|
|
282
|
+
resolveInput: EXPORTABLE((escapeLikeWildcards) => (input) => `%${escapeLikeWildcards(input)}`, [escapeLikeWildcards]),
|
|
283
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} NOT ILIKE ${v}`, [sql]),
|
|
284
|
+
resolveInputCodec: resolveInputCodecInsensitive,
|
|
285
|
+
resolveSqlIdentifier: resolveSqlIdentifierInsensitive,
|
|
286
|
+
},
|
|
287
|
+
like: {
|
|
288
|
+
description: 'Matches the specified pattern (case-sensitive). An underscore (_) matches any single character; a percent sign (%) matches any sequence of zero or more characters.',
|
|
289
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} LIKE ${v}`, [sql]),
|
|
290
|
+
resolveInputCodec: resolveInputCodecSensitive,
|
|
291
|
+
resolveSqlIdentifier: resolveSqlIdentifierSensitive,
|
|
292
|
+
},
|
|
293
|
+
notLike: {
|
|
294
|
+
description: 'Does not match the specified pattern (case-sensitive). An underscore (_) matches any single character; a percent sign (%) matches any sequence of zero or more characters.',
|
|
295
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} NOT LIKE ${v}`, [sql]),
|
|
296
|
+
resolveInputCodec: resolveInputCodecSensitive,
|
|
297
|
+
resolveSqlIdentifier: resolveSqlIdentifierSensitive,
|
|
298
|
+
},
|
|
299
|
+
likeInsensitive: {
|
|
300
|
+
description: 'Matches the specified pattern (case-insensitive). An underscore (_) matches any single character; a percent sign (%) matches any sequence of zero or more characters.',
|
|
301
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} ILIKE ${v}`, [sql]),
|
|
302
|
+
resolveInputCodec: resolveInputCodecInsensitive,
|
|
303
|
+
resolveSqlIdentifier: resolveSqlIdentifierInsensitive,
|
|
304
|
+
},
|
|
305
|
+
notLikeInsensitive: {
|
|
306
|
+
description: 'Does not match the specified pattern (case-insensitive). An underscore (_) matches any single character; a percent sign (%) matches any sequence of zero or more characters.',
|
|
307
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} NOT ILIKE ${v}`, [sql]),
|
|
308
|
+
resolveInputCodec: resolveInputCodecInsensitive,
|
|
309
|
+
resolveSqlIdentifier: resolveSqlIdentifierInsensitive,
|
|
310
|
+
},
|
|
311
|
+
};
|
|
312
|
+
const resolveTextArrayInputCodec = EXPORTABLE((TYPES, listOfCodec) => () => listOfCodec(TYPES.text, { extensions: { listItemNonNull: true } }), [TYPES, listOfCodec]);
|
|
313
|
+
const hstoreOperators = {
|
|
314
|
+
contains: {
|
|
315
|
+
description: 'Contains the specified KeyValueHash.',
|
|
316
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} @> ${v}`, [sql]),
|
|
317
|
+
},
|
|
318
|
+
containsKey: {
|
|
319
|
+
description: 'Contains the specified key.',
|
|
320
|
+
resolveInputCodec: EXPORTABLE((TYPES) => () => TYPES.text, [TYPES]),
|
|
321
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} ? ${v}`, [sql]),
|
|
322
|
+
},
|
|
323
|
+
containsAllKeys: {
|
|
324
|
+
description: 'Contains all of the specified keys.',
|
|
325
|
+
resolveInputCodec: resolveTextArrayInputCodec,
|
|
326
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} ?& ${v}`, [sql]),
|
|
327
|
+
resolveType: resolveTypeToListOfNonNullable,
|
|
328
|
+
},
|
|
329
|
+
containsAnyKeys: {
|
|
330
|
+
description: 'Contains any of the specified keys.',
|
|
331
|
+
resolveInputCodec: resolveTextArrayInputCodec,
|
|
332
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} ?| ${v}`, [sql]),
|
|
333
|
+
resolveType: resolveTypeToListOfNonNullable,
|
|
334
|
+
},
|
|
335
|
+
containedBy: {
|
|
336
|
+
description: 'Contained by the specified KeyValueHash.',
|
|
337
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} <@ ${v}`, [sql]),
|
|
338
|
+
},
|
|
339
|
+
};
|
|
340
|
+
const jsonbOperators = {
|
|
341
|
+
contains: {
|
|
342
|
+
description: 'Contains the specified JSON.',
|
|
343
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} @> ${v}`, [sql]),
|
|
344
|
+
},
|
|
345
|
+
containsKey: {
|
|
346
|
+
description: 'Contains the specified key.',
|
|
347
|
+
resolveInputCodec: EXPORTABLE((TYPES) => () => TYPES.text, [TYPES]),
|
|
348
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} ? ${v}`, [sql]),
|
|
349
|
+
},
|
|
350
|
+
containsAllKeys: {
|
|
351
|
+
description: 'Contains all of the specified keys.',
|
|
352
|
+
resolveInputCodec: resolveTextArrayInputCodec,
|
|
353
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} ?& ${v}`, [sql]),
|
|
354
|
+
},
|
|
355
|
+
containsAnyKeys: {
|
|
356
|
+
description: 'Contains any of the specified keys.',
|
|
357
|
+
resolveInputCodec: resolveTextArrayInputCodec,
|
|
358
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} ?| ${v}`, [sql]),
|
|
359
|
+
},
|
|
360
|
+
containedBy: {
|
|
361
|
+
description: 'Contained by the specified JSON.',
|
|
362
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} <@ ${v}`, [sql]),
|
|
363
|
+
},
|
|
364
|
+
};
|
|
365
|
+
const inetOperators = {
|
|
366
|
+
contains: {
|
|
367
|
+
description: 'Contains the specified internet address.',
|
|
368
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} >> ${v}`, [sql]),
|
|
369
|
+
},
|
|
370
|
+
containsOrEqualTo: {
|
|
371
|
+
description: 'Contains or equal to the specified internet address.',
|
|
372
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} >>= ${v}`, [sql]),
|
|
373
|
+
},
|
|
374
|
+
containedBy: {
|
|
375
|
+
description: 'Contained by the specified internet address.',
|
|
376
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} << ${v}`, [sql]),
|
|
377
|
+
},
|
|
378
|
+
containedByOrEqualTo: {
|
|
379
|
+
description: 'Contained by or equal to the specified internet address.',
|
|
380
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} <<= ${v}`, [sql]),
|
|
381
|
+
},
|
|
382
|
+
containsOrContainedBy: {
|
|
383
|
+
description: 'Contains or contained by the specified internet address.',
|
|
384
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} && ${v}`, [sql]),
|
|
385
|
+
},
|
|
386
|
+
};
|
|
387
|
+
// --- Case-insensitive variants of standard + sort operators ---
|
|
388
|
+
const insensitiveOperators = {};
|
|
389
|
+
for (const [name, spec] of [
|
|
390
|
+
...Object.entries(standardOperators),
|
|
391
|
+
...Object.entries(sortOperators),
|
|
392
|
+
]) {
|
|
393
|
+
if (name === 'isNull')
|
|
394
|
+
continue;
|
|
395
|
+
const description = `${spec.description.substring(0, spec.description.length - 1)} (case-insensitive).`;
|
|
396
|
+
const resolveSqlIdentifier = EXPORTABLE((TYPES, resolveDomains, sql) => function (sourceAlias, codec) {
|
|
397
|
+
return resolveDomains(codec) === TYPES.citext
|
|
398
|
+
? [sourceAlias, codec]
|
|
399
|
+
: [sql `lower(${sourceAlias}::text)`, TYPES.text];
|
|
400
|
+
}, [TYPES, resolveDomains, sql]);
|
|
401
|
+
const resolveSqlValue = EXPORTABLE((TYPES, name, sql, sqlValueWithCodec) => function (_unused, input, inputCodec) {
|
|
402
|
+
if (name === 'in' || name === 'notIn') {
|
|
403
|
+
const sqlList = sqlValueWithCodec(input, inputCodec);
|
|
404
|
+
if (inputCodec.arrayOfCodec === TYPES.citext) {
|
|
405
|
+
return sqlList;
|
|
406
|
+
}
|
|
407
|
+
return sql `(select lower(t) from unnest(${sqlList}) t)`;
|
|
408
|
+
}
|
|
409
|
+
const sqlValue = sqlValueWithCodec(input, inputCodec);
|
|
410
|
+
if (inputCodec === TYPES.citext) {
|
|
411
|
+
return sqlValue;
|
|
412
|
+
}
|
|
413
|
+
return sql `lower(${sqlValue})`;
|
|
414
|
+
}, [TYPES, name, sql, sqlValueWithCodec]);
|
|
415
|
+
const resolveInputCodec = EXPORTABLE((TYPES, listOfCodec, name, resolveDomains) => function (inputCodec) {
|
|
416
|
+
if (name === 'in' || name === 'notIn') {
|
|
417
|
+
const t = resolveDomains(inputCodec) === TYPES.citext
|
|
418
|
+
? inputCodec
|
|
419
|
+
: TYPES.text;
|
|
420
|
+
return listOfCodec(t, { extensions: { listItemNonNull: true } });
|
|
421
|
+
}
|
|
422
|
+
return resolveDomains(inputCodec) === TYPES.citext
|
|
423
|
+
? inputCodec
|
|
424
|
+
: TYPES.text;
|
|
425
|
+
}, [TYPES, listOfCodec, name, resolveDomains]);
|
|
426
|
+
insensitiveOperators[`${name}Insensitive`] = {
|
|
427
|
+
...spec,
|
|
428
|
+
description,
|
|
429
|
+
resolveInputCodec: resolveInputCodec,
|
|
430
|
+
resolveSqlIdentifier: resolveSqlIdentifier,
|
|
431
|
+
resolveSqlValue: resolveSqlValue,
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
// --- Composite operator sets for specific type categories ---
|
|
435
|
+
const connectionFilterEnumOperators = {
|
|
436
|
+
...standardOperators,
|
|
437
|
+
...sortOperators,
|
|
438
|
+
};
|
|
439
|
+
const connectionFilterRangeOperators = {
|
|
440
|
+
...standardOperators,
|
|
441
|
+
...sortOperators,
|
|
442
|
+
contains: {
|
|
443
|
+
description: 'Contains the specified range.',
|
|
444
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} @> ${v}`, [sql]),
|
|
445
|
+
},
|
|
446
|
+
containsElement: {
|
|
447
|
+
description: 'Contains the specified value.',
|
|
448
|
+
resolveInputCodec: EXPORTABLE(() => function (c) {
|
|
449
|
+
if (c.rangeOfCodec)
|
|
450
|
+
return c.rangeOfCodec;
|
|
451
|
+
throw new Error("Couldn't determine the range element type to use");
|
|
452
|
+
}, []),
|
|
453
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} @> ${v}`, [sql]),
|
|
454
|
+
},
|
|
455
|
+
containedBy: {
|
|
456
|
+
description: 'Contained by the specified range.',
|
|
457
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} <@ ${v}`, [sql]),
|
|
458
|
+
},
|
|
459
|
+
overlaps: {
|
|
460
|
+
description: 'Overlaps the specified range.',
|
|
461
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} && ${v}`, [sql]),
|
|
462
|
+
},
|
|
463
|
+
strictlyLeftOf: {
|
|
464
|
+
description: 'Strictly left of the specified range.',
|
|
465
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} << ${v}`, [sql]),
|
|
466
|
+
},
|
|
467
|
+
strictlyRightOf: {
|
|
468
|
+
description: 'Strictly right of the specified range.',
|
|
469
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} >> ${v}`, [sql]),
|
|
470
|
+
},
|
|
471
|
+
notExtendsRightOf: {
|
|
472
|
+
description: 'Does not extend right of the specified range.',
|
|
473
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} &< ${v}`, [sql]),
|
|
474
|
+
},
|
|
475
|
+
notExtendsLeftOf: {
|
|
476
|
+
description: 'Does not extend left of the specified range.',
|
|
477
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} &> ${v}`, [sql]),
|
|
478
|
+
},
|
|
479
|
+
adjacentTo: {
|
|
480
|
+
description: 'Adjacent to the specified range.',
|
|
481
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} -|- ${v}`, [sql]),
|
|
482
|
+
},
|
|
483
|
+
};
|
|
484
|
+
const connectionFilterArrayOperators = {
|
|
485
|
+
isNull: standardOperators.isNull,
|
|
486
|
+
equalTo: standardOperators.equalTo,
|
|
487
|
+
notEqualTo: standardOperators.notEqualTo,
|
|
488
|
+
distinctFrom: standardOperators.distinctFrom,
|
|
489
|
+
notDistinctFrom: standardOperators.notDistinctFrom,
|
|
490
|
+
...sortOperators,
|
|
491
|
+
contains: {
|
|
492
|
+
description: 'Contains the specified list of values.',
|
|
493
|
+
resolveSqlIdentifier: resolveSqlIdentifierSensitive,
|
|
494
|
+
resolveInputCodec: resolveInputCodecSensitive,
|
|
495
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} @> ${v}`, [sql]),
|
|
496
|
+
},
|
|
497
|
+
containedBy: {
|
|
498
|
+
description: 'Contained by the specified list of values.',
|
|
499
|
+
resolveSqlIdentifier: resolveSqlIdentifierSensitive,
|
|
500
|
+
resolveInputCodec: resolveInputCodecSensitive,
|
|
501
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} <@ ${v}`, [sql]),
|
|
502
|
+
},
|
|
503
|
+
overlaps: {
|
|
504
|
+
description: 'Overlaps the specified list of values.',
|
|
505
|
+
resolveSqlIdentifier: resolveSqlIdentifierSensitive,
|
|
506
|
+
resolveInputCodec: resolveInputCodecSensitive,
|
|
507
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${i} && ${v}`, [sql]),
|
|
508
|
+
},
|
|
509
|
+
anyEqualTo: {
|
|
510
|
+
description: 'Any array item is equal to the specified value.',
|
|
511
|
+
resolveInputCodec: resolveArrayItemInputCodecSensitive,
|
|
512
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${v} = ANY (${i})`, [sql]),
|
|
513
|
+
},
|
|
514
|
+
anyNotEqualTo: {
|
|
515
|
+
description: 'Any array item is not equal to the specified value.',
|
|
516
|
+
resolveInputCodec: resolveArrayItemInputCodecSensitive,
|
|
517
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${v} <> ANY (${i})`, [sql]),
|
|
518
|
+
},
|
|
519
|
+
anyLessThan: {
|
|
520
|
+
description: 'Any array item is less than the specified value.',
|
|
521
|
+
resolveInputCodec: resolveArrayItemInputCodecSensitive,
|
|
522
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${v} > ANY (${i})`, [sql]),
|
|
523
|
+
},
|
|
524
|
+
anyLessThanOrEqualTo: {
|
|
525
|
+
description: 'Any array item is less than or equal to the specified value.',
|
|
526
|
+
resolveInputCodec: resolveArrayItemInputCodecSensitive,
|
|
527
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${v} >= ANY (${i})`, [sql]),
|
|
528
|
+
},
|
|
529
|
+
anyGreaterThan: {
|
|
530
|
+
description: 'Any array item is greater than the specified value.',
|
|
531
|
+
resolveInputCodec: resolveArrayItemInputCodecSensitive,
|
|
532
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${v} < ANY (${i})`, [sql]),
|
|
533
|
+
},
|
|
534
|
+
anyGreaterThanOrEqualTo: {
|
|
535
|
+
description: 'Any array item is greater than or equal to the specified value.',
|
|
536
|
+
resolveInputCodec: resolveArrayItemInputCodecSensitive,
|
|
537
|
+
resolve: EXPORTABLE((sql) => (i, v) => sql `${v} <= ANY (${i})`, [sql]),
|
|
538
|
+
},
|
|
539
|
+
};
|
|
540
|
+
// --- Determine which operators to use based on codec characteristics ---
|
|
541
|
+
const { pgCodecs } = pgConnectionFilterOperators;
|
|
542
|
+
const someCodec = pgCodecs[0];
|
|
543
|
+
const fieldInputType = build.getGraphQLTypeByPgCodec(someCodec, 'input');
|
|
544
|
+
let textLike = true;
|
|
545
|
+
let sortable = true;
|
|
546
|
+
let inetLike = true;
|
|
547
|
+
let jsonLike = true;
|
|
548
|
+
let hstoreLike = true;
|
|
549
|
+
let arrayLike = true;
|
|
550
|
+
let rangeLike = true;
|
|
551
|
+
let enumLike = true;
|
|
552
|
+
for (const codec of pgCodecs) {
|
|
553
|
+
const underlyingType = codec.domainOfCodec ?? codec;
|
|
554
|
+
if (!underlyingType.arrayOfCodec)
|
|
555
|
+
arrayLike = false;
|
|
556
|
+
if (!underlyingType.rangeOfCodec)
|
|
557
|
+
rangeLike = false;
|
|
558
|
+
if (!isEnumCodec(underlyingType))
|
|
559
|
+
enumLike = false;
|
|
560
|
+
switch (underlyingType) {
|
|
561
|
+
case TYPES.numeric:
|
|
562
|
+
case TYPES.money:
|
|
563
|
+
case TYPES.float:
|
|
564
|
+
case TYPES.float4:
|
|
565
|
+
case TYPES.bigint:
|
|
566
|
+
case TYPES.int:
|
|
567
|
+
case TYPES.int2:
|
|
568
|
+
case TYPES.boolean:
|
|
569
|
+
case TYPES.varbit:
|
|
570
|
+
case TYPES.bit:
|
|
571
|
+
case TYPES.date:
|
|
572
|
+
case TYPES.timestamp:
|
|
573
|
+
case TYPES.timestamptz:
|
|
574
|
+
case TYPES.time:
|
|
575
|
+
case TYPES.timetz:
|
|
576
|
+
case TYPES.interval:
|
|
577
|
+
case TYPES.json:
|
|
578
|
+
case TYPES.jsonb:
|
|
579
|
+
case TYPES.cidr:
|
|
580
|
+
case TYPES.inet:
|
|
581
|
+
case TYPES.macaddr:
|
|
582
|
+
case TYPES.macaddr8:
|
|
583
|
+
case TYPES.text:
|
|
584
|
+
case TYPES.name:
|
|
585
|
+
case TYPES.citext:
|
|
586
|
+
case TYPES.varchar:
|
|
587
|
+
case TYPES.char:
|
|
588
|
+
case TYPES.bpchar:
|
|
589
|
+
case TYPES.uuid:
|
|
590
|
+
break;
|
|
591
|
+
default:
|
|
592
|
+
sortable = false;
|
|
593
|
+
}
|
|
594
|
+
switch (underlyingType) {
|
|
595
|
+
case TYPES.cidr:
|
|
596
|
+
case TYPES.inet:
|
|
597
|
+
case TYPES.macaddr:
|
|
598
|
+
case TYPES.macaddr8:
|
|
599
|
+
break;
|
|
600
|
+
default:
|
|
601
|
+
inetLike = false;
|
|
602
|
+
}
|
|
603
|
+
switch (underlyingType) {
|
|
604
|
+
case TYPES.text:
|
|
605
|
+
case TYPES.name:
|
|
606
|
+
case TYPES.citext:
|
|
607
|
+
case TYPES.varchar:
|
|
608
|
+
case TYPES.char:
|
|
609
|
+
case TYPES.bpchar:
|
|
610
|
+
break;
|
|
611
|
+
default:
|
|
612
|
+
textLike = false;
|
|
613
|
+
}
|
|
614
|
+
switch (underlyingType) {
|
|
615
|
+
case TYPES.json:
|
|
616
|
+
case TYPES.jsonb:
|
|
617
|
+
break;
|
|
618
|
+
default:
|
|
619
|
+
jsonLike = false;
|
|
620
|
+
}
|
|
621
|
+
switch (underlyingType) {
|
|
622
|
+
case TYPES.hstore:
|
|
623
|
+
break;
|
|
624
|
+
default:
|
|
625
|
+
hstoreLike = false;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
// Choose the correct operator set
|
|
629
|
+
const operatorSpecs = arrayLike
|
|
630
|
+
? connectionFilterArrayOperators
|
|
631
|
+
: rangeLike
|
|
632
|
+
? connectionFilterRangeOperators
|
|
633
|
+
: enumLike
|
|
634
|
+
? connectionFilterEnumOperators
|
|
635
|
+
: {
|
|
636
|
+
...standardOperators,
|
|
637
|
+
...(sortable ? sortOperators : null),
|
|
638
|
+
...(inetLike ? inetOperators : null),
|
|
639
|
+
...(jsonLike ? jsonbOperators : null),
|
|
640
|
+
...(hstoreLike ? hstoreOperators : null),
|
|
641
|
+
...(textLike ? patternMatchingOperators : null),
|
|
642
|
+
...(textLike ? insensitiveOperators : null),
|
|
643
|
+
};
|
|
644
|
+
// Build the operator fields
|
|
645
|
+
const operatorFields = Object.entries(operatorSpecs).reduce((memo, [name, spec]) => {
|
|
646
|
+
const { description, resolveInputCodec, resolveType } = spec;
|
|
647
|
+
if (connectionFilterAllowedOperators &&
|
|
648
|
+
!connectionFilterAllowedOperators.includes(name)) {
|
|
649
|
+
return memo;
|
|
650
|
+
}
|
|
651
|
+
if (!fieldInputType)
|
|
652
|
+
return memo;
|
|
653
|
+
const firstCodec = pgCodecs[0];
|
|
654
|
+
const inputCodec = resolveInputCodec
|
|
655
|
+
? resolveInputCodec(firstCodec)
|
|
656
|
+
: firstCodec;
|
|
657
|
+
const codecGraphQLType = build.getGraphQLTypeByPgCodec(inputCodec, 'input');
|
|
658
|
+
if (!codecGraphQLType)
|
|
659
|
+
return memo;
|
|
660
|
+
const type = resolveType
|
|
661
|
+
? resolveType(codecGraphQLType)
|
|
662
|
+
: codecGraphQLType;
|
|
663
|
+
const operatorName = (connectionFilterOperatorNames &&
|
|
664
|
+
connectionFilterOperatorNames[name]) ||
|
|
665
|
+
name;
|
|
666
|
+
memo[operatorName] = fieldWithHooks({
|
|
667
|
+
fieldName: operatorName,
|
|
668
|
+
isPgConnectionFilterOperator: true,
|
|
669
|
+
}, {
|
|
670
|
+
description,
|
|
671
|
+
type,
|
|
672
|
+
apply: (0, operatorApply_1.makeApplyFromOperatorSpec)(build, Self.name, operatorName, spec, type),
|
|
673
|
+
});
|
|
674
|
+
return memo;
|
|
675
|
+
}, Object.create(null));
|
|
676
|
+
return extend(fields, operatorFields, '');
|
|
677
|
+
},
|
|
678
|
+
},
|
|
679
|
+
},
|
|
680
|
+
};
|