graphile-build-pg 4.13.0 → 4.14.1
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/README.md +4 -13
- package/node8plus/GraphQLJSON.js +0 -11
- package/node8plus/GraphQLJSON.js.map +1 -1
- package/node8plus/PgLiveProvider.js +4 -11
- package/node8plus/PgLiveProvider.js.map +1 -1
- package/node8plus/QueryBuilder.js +42 -176
- package/node8plus/QueryBuilder.js.map +1 -1
- package/node8plus/index.js +8 -47
- package/node8plus/index.js.map +1 -1
- package/node8plus/inflections.js +9 -61
- package/node8plus/inflections.js.map +1 -1
- package/node8plus/omit.js +7 -22
- package/node8plus/omit.js.map +1 -1
- package/node8plus/parseIdentifier.js +0 -1
- package/node8plus/parseIdentifier.js.map +1 -1
- package/node8plus/pgPrepareAndRun.js +2 -14
- package/node8plus/pgPrepareAndRun.js.map +1 -1
- package/node8plus/plugins/PageInfoStartEndCursor.js +0 -4
- package/node8plus/plugins/PageInfoStartEndCursor.js.map +1 -1
- package/node8plus/plugins/PgAllRows.js +0 -29
- package/node8plus/plugins/PgAllRows.js.map +1 -1
- package/node8plus/plugins/PgBackwardRelationPlugin.js +2 -41
- package/node8plus/plugins/PgBackwardRelationPlugin.js.map +1 -1
- package/node8plus/plugins/PgBasicsPlugin.js +20 -147
- package/node8plus/plugins/PgBasicsPlugin.js.map +1 -1
- package/node8plus/plugins/PgColumnDeprecationPlugin.js +2 -5
- package/node8plus/plugins/PgColumnDeprecationPlugin.js.map +1 -1
- package/node8plus/plugins/PgColumnsPlugin.js +4 -17
- package/node8plus/plugins/PgColumnsPlugin.js.map +1 -1
- package/node8plus/plugins/PgComputedColumnsPlugin.js +4 -19
- package/node8plus/plugins/PgComputedColumnsPlugin.js.map +1 -1
- package/node8plus/plugins/PgConditionComputedColumnPlugin.js +12 -23
- package/node8plus/plugins/PgConditionComputedColumnPlugin.js.map +1 -1
- package/node8plus/plugins/PgConnectionArgCondition.js +1 -9
- package/node8plus/plugins/PgConnectionArgCondition.js.map +1 -1
- package/node8plus/plugins/PgConnectionArgFirstLastBeforeAfter.js +0 -12
- package/node8plus/plugins/PgConnectionArgFirstLastBeforeAfter.js.map +1 -1
- package/node8plus/plugins/PgConnectionArgOrderBy.js +2 -19
- package/node8plus/plugins/PgConnectionArgOrderBy.js.map +1 -1
- package/node8plus/plugins/PgConnectionArgOrderByDefaultValue.js +0 -6
- package/node8plus/plugins/PgConnectionArgOrderByDefaultValue.js.map +1 -1
- package/node8plus/plugins/PgConnectionTotalCount.js +0 -8
- package/node8plus/plugins/PgConnectionTotalCount.js.map +1 -1
- package/node8plus/plugins/PgForwardRelationPlugin.js +2 -25
- package/node8plus/plugins/PgForwardRelationPlugin.js.map +1 -1
- package/node8plus/plugins/PgIntrospectionPlugin.js +91 -180
- package/node8plus/plugins/PgIntrospectionPlugin.js.flow +30 -2
- package/node8plus/plugins/PgIntrospectionPlugin.js.map +1 -1
- package/node8plus/plugins/PgJWTPlugin.js +2 -18
- package/node8plus/plugins/PgJWTPlugin.js.map +1 -1
- package/node8plus/plugins/PgMutationCreatePlugin.js +0 -18
- package/node8plus/plugins/PgMutationCreatePlugin.js.map +1 -1
- package/node8plus/plugins/PgMutationPayloadEdgePlugin.js +4 -25
- package/node8plus/plugins/PgMutationPayloadEdgePlugin.js.map +1 -1
- package/node8plus/plugins/PgMutationProceduresPlugin.js +0 -6
- package/node8plus/plugins/PgMutationProceduresPlugin.js.map +1 -1
- package/node8plus/plugins/PgMutationUpdateDeletePlugin.js +14 -49
- package/node8plus/plugins/PgMutationUpdateDeletePlugin.js.flow +5 -2
- package/node8plus/plugins/PgMutationUpdateDeletePlugin.js.map +1 -1
- package/node8plus/plugins/PgNodeAliasPostGraphile.js +0 -6
- package/node8plus/plugins/PgNodeAliasPostGraphile.js.map +1 -1
- package/node8plus/plugins/PgOrderAllColumnsPlugin.js +0 -4
- package/node8plus/plugins/PgOrderAllColumnsPlugin.js.map +1 -1
- package/node8plus/plugins/PgOrderByPrimaryKeyPlugin.js +0 -6
- package/node8plus/plugins/PgOrderByPrimaryKeyPlugin.js.map +1 -1
- package/node8plus/plugins/PgOrderComputedColumnsPlugin.js +10 -14
- package/node8plus/plugins/PgOrderComputedColumnsPlugin.js.map +1 -1
- package/node8plus/plugins/PgQueryProceduresPlugin.js +4 -16
- package/node8plus/plugins/PgQueryProceduresPlugin.js.map +1 -1
- package/node8plus/plugins/PgRecordFunctionConnectionPlugin.js +3 -20
- package/node8plus/plugins/PgRecordFunctionConnectionPlugin.js.map +1 -1
- package/node8plus/plugins/PgRecordReturnTypesPlugin.js +11 -16
- package/node8plus/plugins/PgRecordReturnTypesPlugin.js.map +1 -1
- package/node8plus/plugins/PgRowByUniqueConstraint.js +4 -25
- package/node8plus/plugins/PgRowByUniqueConstraint.js.map +1 -1
- package/node8plus/plugins/PgRowNode.js +0 -32
- package/node8plus/plugins/PgRowNode.js.map +1 -1
- package/node8plus/plugins/PgScalarFunctionConnectionPlugin.js +3 -17
- package/node8plus/plugins/PgScalarFunctionConnectionPlugin.js.map +1 -1
- package/node8plus/plugins/PgTablesPlugin.js +7 -59
- package/node8plus/plugins/PgTablesPlugin.js.map +1 -1
- package/node8plus/plugins/PgTypesPlugin.js +140 -240
- package/node8plus/plugins/PgTypesPlugin.js.flow +76 -23
- package/node8plus/plugins/PgTypesPlugin.js.map +1 -1
- package/node8plus/plugins/addStartEndCursor.js +2 -5
- package/node8plus/plugins/addStartEndCursor.js.map +1 -1
- package/node8plus/plugins/debugSql.js +1 -16
- package/node8plus/plugins/debugSql.js.map +1 -1
- package/node8plus/plugins/introspectionQuery.js +3 -4
- package/node8plus/plugins/introspectionQuery.js.flow +11 -3
- package/node8plus/plugins/introspectionQuery.js.map +1 -1
- package/node8plus/plugins/makeProcField.js +40 -90
- package/node8plus/plugins/makeProcField.js.map +1 -1
- package/node8plus/plugins/pgField.js +2 -7
- package/node8plus/plugins/pgField.js.map +1 -1
- package/node8plus/plugins/viaTemporaryTable.js +6 -12
- package/node8plus/plugins/viaTemporaryTable.js.map +1 -1
- package/node8plus/postgresInterval.js +4 -4
- package/node8plus/postgresInterval.js.map +1 -1
- package/node8plus/queryFromResolveDataFactory.js +33 -77
- package/node8plus/queryFromResolveDataFactory.js.map +1 -1
- package/node8plus/utils.js +8 -9
- package/node8plus/utils.js.map +1 -1
- package/node8plus/withPgClient.js +4 -26
- package/node8plus/withPgClient.js.map +1 -1
- package/package.json +4 -4
|
@@ -4,21 +4,16 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var _GraphQLJSON = _interopRequireDefault(require("../GraphQLJSON"));
|
|
9
|
-
|
|
10
8
|
var _postgresInterval = require("../postgresInterval");
|
|
11
|
-
|
|
12
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
|
|
10
|
+
const ENUM_DOMAIN_SUFFIX = "_enum_domain";
|
|
14
11
|
function indent(str) {
|
|
15
12
|
return " " + str.replace(/\n/g, "\n ");
|
|
16
13
|
}
|
|
17
|
-
|
|
18
14
|
function identity(value) {
|
|
19
15
|
return value;
|
|
20
16
|
}
|
|
21
|
-
|
|
22
17
|
var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
23
18
|
pgExtendedTypes = true,
|
|
24
19
|
// Adding hstore support is technically a breaking change; this allows people to opt out easily:
|
|
@@ -31,11 +26,13 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
31
26
|
builder.hook("build", build => {
|
|
32
27
|
const {
|
|
33
28
|
pgIntrospectionResultsByKind: introspectionResultsByKind,
|
|
29
|
+
getPgFakeEnumIdentifier,
|
|
34
30
|
getTypeByName,
|
|
35
31
|
pgSql: sql,
|
|
36
32
|
inflection,
|
|
37
33
|
graphql
|
|
38
34
|
} = build;
|
|
35
|
+
|
|
39
36
|
/*
|
|
40
37
|
* Note these do not do `foo.bind(build)` because they want to reference
|
|
41
38
|
* the *latest* value of foo (i.e. after all the build hooks run) rather
|
|
@@ -46,11 +43,8 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
46
43
|
*
|
|
47
44
|
* TODO:v5: move this to the 'init' hook.
|
|
48
45
|
*/
|
|
49
|
-
|
|
50
46
|
const newWithHooks = (...args) => build.newWithHooks(...args);
|
|
51
|
-
|
|
52
47
|
const addType = (...args) => build.addType(...args);
|
|
53
|
-
|
|
54
48
|
const {
|
|
55
49
|
GraphQLNonNull,
|
|
56
50
|
GraphQLString,
|
|
@@ -68,21 +62,18 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
68
62
|
} = graphql;
|
|
69
63
|
const gqlTypeByTypeIdGenerator = {};
|
|
70
64
|
const gqlInputTypeByTypeIdGenerator = {};
|
|
71
|
-
|
|
72
65
|
if (build.pgGqlTypeByTypeId || build.pgGqlInputTypeByTypeId) {
|
|
73
66
|
// I don't expect anyone to receive this error, because I don't think anyone uses this interface.
|
|
74
67
|
throw new Error("Sorry! This interface is no longer supported because it is not granular enough. It's not hard to port it to the new system - please contact Benjie and he'll walk you through it.");
|
|
75
68
|
}
|
|
76
|
-
|
|
77
|
-
|
|
69
|
+
const gqlTypeByTypeIdAndModifier = {
|
|
70
|
+
...build.pgGqlTypeByTypeIdAndModifier
|
|
78
71
|
};
|
|
79
|
-
const gqlInputTypeByTypeIdAndModifier = {
|
|
72
|
+
const gqlInputTypeByTypeIdAndModifier = {
|
|
73
|
+
...build.pgGqlInputTypeByTypeIdAndModifier
|
|
80
74
|
};
|
|
81
|
-
|
|
82
75
|
const isNull = val => val == null || val.__isNull;
|
|
83
|
-
|
|
84
76
|
const pg2GqlMapper = {};
|
|
85
|
-
|
|
86
77
|
const pg2gqlForType = type => {
|
|
87
78
|
if (pg2GqlMapper[type.id]) {
|
|
88
79
|
const map = pg2GqlMapper[type.id].map;
|
|
@@ -93,40 +84,32 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
93
84
|
const elementHandler = pg2gqlForType(type.arrayItemType);
|
|
94
85
|
return val => {
|
|
95
86
|
if (isNull(val)) return null;
|
|
96
|
-
|
|
97
87
|
if (!Array.isArray(val)) {
|
|
98
88
|
throw new Error(`Expected array when converting PostgreSQL data into GraphQL; failing type: '${type.namespaceName}.${type.name}'`);
|
|
99
89
|
}
|
|
100
|
-
|
|
101
90
|
return val.map(elementHandler);
|
|
102
91
|
};
|
|
103
92
|
} else {
|
|
104
93
|
return identity;
|
|
105
94
|
}
|
|
106
95
|
};
|
|
107
|
-
|
|
108
96
|
const pg2gql = (val, type) => pg2gqlForType(type)(val);
|
|
109
|
-
|
|
110
97
|
const gql2pg = (val, type, modifier) => {
|
|
111
98
|
if (modifier === undefined) {
|
|
112
99
|
let stack;
|
|
113
|
-
|
|
114
100
|
try {
|
|
115
101
|
throw new Error();
|
|
116
102
|
} catch (e) {
|
|
117
103
|
stack = e.stack;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
104
|
+
}
|
|
105
|
+
// eslint-disable-next-line no-console
|
|
106
|
+
console.warn("gql2pg should be called with three arguments, the third being the type modifier (or `null`); " + (stack || ""));
|
|
107
|
+
// Hack for backwards compatibility:
|
|
123
108
|
modifier = null;
|
|
124
109
|
}
|
|
125
|
-
|
|
126
110
|
if (val == null) {
|
|
127
111
|
return sql.null;
|
|
128
112
|
}
|
|
129
|
-
|
|
130
113
|
if (pg2GqlMapper[type.id]) {
|
|
131
114
|
return pg2GqlMapper[type.id].unmap(val, modifier);
|
|
132
115
|
} else if (type.domainBaseType) {
|
|
@@ -135,13 +118,11 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
135
118
|
if (!Array.isArray(val)) {
|
|
136
119
|
throw new Error(`Expected array when converting GraphQL data into PostgreSQL data; failing type: '${type.namespaceName}.${type.name}' (type: ${type === null ? "null" : typeof type})`);
|
|
137
120
|
}
|
|
138
|
-
|
|
139
121
|
return sql.fragment`array[${sql.join(val.map(v => gql2pg(v, type.arrayItemType, modifier)), ", ")}]::${type.isFake ? sql.identifier("unknown") : sql.identifier(type.namespaceName, type.name)}`;
|
|
140
122
|
} else {
|
|
141
123
|
return sql.value(val);
|
|
142
124
|
}
|
|
143
125
|
};
|
|
144
|
-
|
|
145
126
|
const makeIntervalFields = () => {
|
|
146
127
|
return {
|
|
147
128
|
seconds: {
|
|
@@ -170,7 +151,6 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
170
151
|
}
|
|
171
152
|
};
|
|
172
153
|
};
|
|
173
|
-
|
|
174
154
|
const GQLInterval = newWithHooks(GraphQLObjectType, {
|
|
175
155
|
name: inflection.builtin("Interval"),
|
|
176
156
|
description: build.wrapDescription("An interval of time that has passed where the smallest distinct unit is a second.", "type"),
|
|
@@ -187,7 +167,6 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
187
167
|
isIntervalInputType: true
|
|
188
168
|
});
|
|
189
169
|
addType(GQLIntervalInput, "graphile-build-pg built-in");
|
|
190
|
-
|
|
191
170
|
const stringType = (name, description, coerce) => new GraphQLScalarType({
|
|
192
171
|
name,
|
|
193
172
|
description,
|
|
@@ -197,7 +176,6 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
197
176
|
if (ast.kind !== Kind.STRING) {
|
|
198
177
|
throw new Error("Can only parse string values");
|
|
199
178
|
}
|
|
200
|
-
|
|
201
179
|
if (coerce) {
|
|
202
180
|
return coerce(ast.value);
|
|
203
181
|
} else {
|
|
@@ -205,34 +183,32 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
205
183
|
}
|
|
206
184
|
}
|
|
207
185
|
});
|
|
208
|
-
|
|
209
186
|
const BigFloat = stringType(inflection.builtin("BigFloat"), build.wrapDescription("A floating point number that requires more precision than IEEE 754 binary 64", "type"));
|
|
210
187
|
const BitString = stringType(inflection.builtin("BitString"), build.wrapDescription("A string representing a series of binary bits", "type"));
|
|
211
188
|
addType(BigFloat, "graphile-build-pg built-in");
|
|
212
189
|
addType(BitString, "graphile-build-pg built-in");
|
|
213
|
-
const rawTypes = [1186,
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
190
|
+
const rawTypes = [1186,
|
|
191
|
+
// interval
|
|
192
|
+
1082,
|
|
193
|
+
// date
|
|
194
|
+
1114,
|
|
195
|
+
// timestamp
|
|
196
|
+
1184,
|
|
197
|
+
// timestamptz
|
|
198
|
+
1083,
|
|
199
|
+
// time
|
|
218
200
|
1266 // timetz
|
|
219
201
|
];
|
|
220
202
|
|
|
221
203
|
const tweakToJson = fragment => fragment; // Since everything is to_json'd now, just pass through
|
|
222
|
-
|
|
223
|
-
|
|
224
204
|
const tweakToJsonArray = fragment => fragment;
|
|
225
|
-
|
|
226
205
|
const tweakToText = fragment => sql.fragment`(${fragment})::text`;
|
|
227
|
-
|
|
228
206
|
const tweakToTextArray = fragment => sql.fragment`(${fragment})::text[]`;
|
|
229
|
-
|
|
230
207
|
const tweakToNumericText = fragment => sql.fragment`(${fragment})::numeric::text`;
|
|
231
|
-
|
|
232
208
|
const tweakToNumericTextArray = fragment => sql.fragment`(${fragment})::numeric[]::text[]`;
|
|
233
|
-
|
|
234
209
|
const pgTweaksByTypeIdAndModifer = {};
|
|
235
|
-
const pgTweaksByTypeId = {
|
|
210
|
+
const pgTweaksByTypeId = {
|
|
211
|
+
// '::text' rawTypes
|
|
236
212
|
...rawTypes.reduce((memo, typeId) => {
|
|
237
213
|
memo[typeId] = tweakToText;
|
|
238
214
|
return memo;
|
|
@@ -248,11 +224,9 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
248
224
|
1266: tweakToJson,
|
|
249
225
|
790: tweakToNumericText
|
|
250
226
|
};
|
|
251
|
-
|
|
252
227
|
const pgTweakFragmentForTypeAndModifier = (fragment, type, typeModifier = null, resolveData) => {
|
|
253
228
|
const typeModifierKey = typeModifier != null ? typeModifier : -1;
|
|
254
229
|
const tweaker = pgTweaksByTypeIdAndModifer[type.id] && pgTweaksByTypeIdAndModifer[type.id][typeModifierKey] || pgTweaksByTypeId[type.id];
|
|
255
|
-
|
|
256
230
|
if (tweaker) {
|
|
257
231
|
return tweaker(fragment, resolveData);
|
|
258
232
|
} else if (type.domainBaseType) {
|
|
@@ -262,26 +236,25 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
262
236
|
// when taking PostgreSQL's JSON into Node.js.
|
|
263
237
|
const arrayItemType = type.domainBaseType.arrayItemType;
|
|
264
238
|
const domainBaseTypeModifierKey = type.domainBaseTypeModifier != null ? type.domainBaseTypeModifier : -1;
|
|
265
|
-
const arrayItemTweaker = pgTweaksByTypeIdAndModifer[arrayItemType.id] && pgTweaksByTypeIdAndModifer[arrayItemType.id][domainBaseTypeModifierKey] || pgTweaksByTypeId[arrayItemType.id];
|
|
266
|
-
// the Array version of the tweaker.
|
|
239
|
+
const arrayItemTweaker = pgTweaksByTypeIdAndModifer[arrayItemType.id] && pgTweaksByTypeIdAndModifer[arrayItemType.id][domainBaseTypeModifierKey] || pgTweaksByTypeId[arrayItemType.id];
|
|
267
240
|
|
|
241
|
+
// If it's a domain over a known type array (e.g. `bigint[]`), use
|
|
242
|
+
// the Array version of the tweaker.
|
|
268
243
|
switch (arrayItemTweaker) {
|
|
269
244
|
case tweakToText:
|
|
270
245
|
return tweakToTextArray(fragment);
|
|
271
|
-
|
|
272
246
|
case tweakToNumericText:
|
|
273
247
|
return tweakToNumericTextArray(fragment);
|
|
274
|
-
|
|
275
248
|
case tweakToJson:
|
|
276
249
|
return tweakToJsonArray(fragment);
|
|
277
|
-
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// If we get here, it's not a simple type, so use our
|
|
278
253
|
// infrastructure to figure out what tweaks to apply to the array
|
|
279
254
|
// item.
|
|
280
255
|
|
|
281
|
-
|
|
282
256
|
const sqlVal = sql.fragment`val`;
|
|
283
257
|
const innerFragment = pgTweakFragmentForTypeAndModifier(sqlVal, arrayItemType, type.domainBaseTypeModifier, resolveData);
|
|
284
|
-
|
|
285
258
|
if (innerFragment === sqlVal) {
|
|
286
259
|
// There was no tweak applied to the fragment, no change
|
|
287
260
|
// necessary.
|
|
@@ -298,13 +271,11 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
298
271
|
}
|
|
299
272
|
} else if (type.isPgArray) {
|
|
300
273
|
const error = new Error(`Internal graphile-build-pg error: should not attempt to tweak an array, please process array before tweaking (type: "${type.namespaceName}.${type.name}")`);
|
|
301
|
-
|
|
302
274
|
if (process.env.NODE_ENV === "test") {
|
|
303
275
|
// This is to ensure that Graphile core does not introduce these problems
|
|
304
276
|
throw error;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
|
|
277
|
+
}
|
|
278
|
+
// eslint-disable-next-line no-console
|
|
308
279
|
console.error(error);
|
|
309
280
|
return fragment;
|
|
310
281
|
} else {
|
|
@@ -316,8 +287,6 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
316
287
|
select oid, typname, typarray, typcategory, typtype from pg_catalog.pg_type where typtype = 'b' order by oid;
|
|
317
288
|
We only need to add oidLookups for types that don't have the correct fallback
|
|
318
289
|
*/
|
|
319
|
-
|
|
320
|
-
|
|
321
290
|
const SimpleDate = stringType(inflection.builtin("Date"), build.wrapDescription("The day, does not include a time.", "type"));
|
|
322
291
|
const SimpleDatetime = stringType(inflection.builtin("Datetime"), build.wrapDescription("A point in time as described by the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) standard. May or may not include a timezone.", "type"));
|
|
323
292
|
const SimpleTime = stringType(inflection.builtin("Time"), build.wrapDescription("The exact time of day, does not include the date. May or may not have a timezone offset.", "type"));
|
|
@@ -326,7 +295,6 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
326
295
|
if (!/^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$/i.test(string)) {
|
|
327
296
|
throw new Error("Invalid UUID, expected 32 hexadecimal characters, optionally with hyphens");
|
|
328
297
|
}
|
|
329
|
-
|
|
330
298
|
return string;
|
|
331
299
|
});
|
|
332
300
|
const InetType = stringType(inflection.builtin("InternetAddress"), build.wrapDescription("An IPv4 or IPv6 host address, and optionally its subnet.", "type"));
|
|
@@ -342,18 +310,16 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
342
310
|
const RegDictionaryType = stringType(inflection.builtin("RegDictionary"), build.wrapDescription("A builtin object identifier type for a text search dictionary", "type"));
|
|
343
311
|
const CidrType = pgUseCustomNetworkScalars ? stringType(inflection.builtin("CidrAddress"), build.wrapDescription("An IPv4 or IPv6 CIDR address.", "type")) : GraphQLString;
|
|
344
312
|
const MacAddrType = pgUseCustomNetworkScalars ? stringType(inflection.builtin("MacAddress"), build.wrapDescription("A 6-byte MAC address.", "type")) : GraphQLString;
|
|
345
|
-
const MacAddr8Type = pgUseCustomNetworkScalars ? stringType(inflection.builtin("MacAddress8"), build.wrapDescription("An 8-byte MAC address.", "type")) : GraphQLString;
|
|
313
|
+
const MacAddr8Type = pgUseCustomNetworkScalars ? stringType(inflection.builtin("MacAddress8"), build.wrapDescription("An 8-byte MAC address.", "type")) : GraphQLString;
|
|
346
314
|
|
|
315
|
+
// pgExtendedTypes might change what types we use for things
|
|
347
316
|
const JSONType = pgExtendedTypes ? (0, _GraphQLJSON.default)(graphql, inflection.builtin("JSON")) : SimpleJSON;
|
|
348
317
|
const UUIDType = SimpleUUID; // GraphQLUUID
|
|
349
|
-
|
|
350
318
|
const DateType = SimpleDate; // GraphQLDate
|
|
351
|
-
|
|
352
319
|
const DateTimeType = SimpleDatetime; // GraphQLDateTime
|
|
353
|
-
|
|
354
320
|
const TimeType = SimpleTime; // GraphQLTime
|
|
355
|
-
// 'point' in PostgreSQL is a 16-byte type that's comprised of two 8-byte floats.
|
|
356
321
|
|
|
322
|
+
// 'point' in PostgreSQL is a 16-byte type that's comprised of two 8-byte floats.
|
|
357
323
|
const Point = newWithHooks(GraphQLObjectType, {
|
|
358
324
|
name: inflection.builtin("Point"),
|
|
359
325
|
fields: {
|
|
@@ -379,8 +345,9 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
379
345
|
}
|
|
380
346
|
}, {
|
|
381
347
|
isPointInputType: true
|
|
382
|
-
});
|
|
348
|
+
});
|
|
383
349
|
|
|
350
|
+
// Other plugins might want to use JSON
|
|
384
351
|
addType(JSONType, "graphile-build-pg built-in");
|
|
385
352
|
addType(UUIDType, "graphile-build-pg built-in");
|
|
386
353
|
addType(DateType, "graphile-build-pg built-in");
|
|
@@ -411,6 +378,7 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
411
378
|
// numeric
|
|
412
379
|
790: GraphQLFloat,
|
|
413
380
|
// money
|
|
381
|
+
|
|
414
382
|
1186: GQLInterval,
|
|
415
383
|
// interval
|
|
416
384
|
1082: DateType,
|
|
@@ -423,24 +391,29 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
423
391
|
// time
|
|
424
392
|
1266: TimeType,
|
|
425
393
|
// timetz
|
|
394
|
+
|
|
426
395
|
114: JSONType,
|
|
427
396
|
// json
|
|
428
397
|
3802: JSONType,
|
|
429
398
|
// jsonb
|
|
430
399
|
2950: UUIDType,
|
|
431
400
|
// uuid
|
|
401
|
+
|
|
432
402
|
1560: BitString,
|
|
433
403
|
// bit
|
|
434
404
|
1562: BitString,
|
|
435
405
|
// varbit
|
|
406
|
+
|
|
436
407
|
18: GraphQLString,
|
|
437
408
|
// char
|
|
438
409
|
25: GraphQLString,
|
|
439
410
|
// text
|
|
440
411
|
1043: GraphQLString,
|
|
441
412
|
// varchar
|
|
413
|
+
|
|
442
414
|
600: Point,
|
|
443
415
|
// point
|
|
416
|
+
|
|
444
417
|
869: InetType,
|
|
445
418
|
650: CidrType,
|
|
446
419
|
829: MacAddrType,
|
|
@@ -460,11 +433,9 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
460
433
|
1186: GQLIntervalInput,
|
|
461
434
|
// interval
|
|
462
435
|
600: PointInput // point
|
|
463
|
-
|
|
464
436
|
};
|
|
465
437
|
|
|
466
438
|
const jsonStringify = o => JSON.stringify(o);
|
|
467
|
-
|
|
468
439
|
if (pgExtendedTypes) {
|
|
469
440
|
pg2GqlMapper[114] = {
|
|
470
441
|
map: identity,
|
|
@@ -476,30 +447,28 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
476
447
|
unmap: str => sql.value(str)
|
|
477
448
|
};
|
|
478
449
|
}
|
|
479
|
-
|
|
480
450
|
pg2GqlMapper[3802] = pg2GqlMapper[114]; // jsonb
|
|
481
|
-
// interval
|
|
482
451
|
|
|
452
|
+
// interval
|
|
483
453
|
pg2GqlMapper[1186] = {
|
|
484
454
|
map: str => (0, _postgresInterval.parseInterval)(str),
|
|
485
455
|
unmap: o => {
|
|
486
456
|
const keys = ["seconds", "minutes", "hours", "days", "months", "years"];
|
|
487
457
|
const parts = [];
|
|
488
|
-
|
|
489
458
|
for (const key of keys) {
|
|
490
459
|
if (o[key]) {
|
|
491
460
|
parts.push(`${o[key]} ${key}`);
|
|
492
461
|
}
|
|
493
462
|
}
|
|
494
|
-
|
|
495
463
|
return sql.value(parts.join(" ") || "0 seconds");
|
|
496
464
|
}
|
|
497
465
|
};
|
|
498
466
|
pg2GqlMapper[790] = {
|
|
499
467
|
map: _ => _,
|
|
500
468
|
unmap: val => sql.fragment`(${sql.value(val)})::money`
|
|
501
|
-
};
|
|
469
|
+
};
|
|
502
470
|
|
|
471
|
+
// point
|
|
503
472
|
pg2GqlMapper[600] = {
|
|
504
473
|
map: f => {
|
|
505
474
|
if (f[0] === "(" && f[f.length - 1] === ")") {
|
|
@@ -511,67 +480,63 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
511
480
|
}
|
|
512
481
|
},
|
|
513
482
|
unmap: o => sql.fragment`point(${sql.value(o.x)}, ${sql.value(o.y)})`
|
|
514
|
-
};
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
// TODO: add more support for geometric types
|
|
515
486
|
|
|
516
487
|
let depth = 0;
|
|
488
|
+
|
|
517
489
|
/*
|
|
518
490
|
* Enforce: this is the fallback when we can't find a specific GraphQL type
|
|
519
491
|
* for a specific PG type. Use the generators from
|
|
520
492
|
* `pgRegisterGqlTypeByTypeId` first, this is a last resort.
|
|
521
493
|
*/
|
|
522
|
-
|
|
523
494
|
const enforceGqlTypeByPgTypeId = (typeId, typeModifier) => {
|
|
524
495
|
const type = introspectionResultsByKind.type.find(t => t.id === typeId);
|
|
525
496
|
depth++;
|
|
526
|
-
|
|
527
497
|
if (depth > 50) {
|
|
528
498
|
throw new Error("Type enforcement went too deep - infinite loop?");
|
|
529
499
|
}
|
|
530
|
-
|
|
531
500
|
try {
|
|
532
501
|
return reallyEnforceGqlTypeByPgTypeAndModifier(type, typeModifier);
|
|
533
502
|
} catch (e) {
|
|
534
|
-
const error = new Error(`Error occurred when processing database type '${type.namespaceName}.${type.name}' (type=${type.type}):\n${indent(e.message)}`);
|
|
535
|
-
|
|
503
|
+
const error = new Error(`Error occurred when processing database type '${type.namespaceName}.${type.name}' (type=${type.type}):\n${indent(e.message)}`);
|
|
504
|
+
// $FlowFixMe
|
|
536
505
|
error.originalError = e;
|
|
537
506
|
throw error;
|
|
538
507
|
} finally {
|
|
539
508
|
depth--;
|
|
540
509
|
}
|
|
541
510
|
};
|
|
542
|
-
|
|
543
511
|
const reallyEnforceGqlTypeByPgTypeAndModifier = (type, typeModifier) => {
|
|
544
512
|
if (!type.id) {
|
|
545
513
|
throw new Error(`Invalid argument to enforceGqlTypeByPgTypeId - expected a full type, received '${type}'`);
|
|
546
514
|
}
|
|
547
|
-
|
|
548
515
|
if (!gqlTypeByTypeIdAndModifier[type.id]) {
|
|
549
516
|
gqlTypeByTypeIdAndModifier[type.id] = {};
|
|
550
517
|
}
|
|
551
|
-
|
|
552
518
|
if (!gqlInputTypeByTypeIdAndModifier[type.id]) {
|
|
553
519
|
gqlInputTypeByTypeIdAndModifier[type.id] = {};
|
|
554
520
|
}
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
521
|
+
const typeModifierKey = typeModifier != null ? typeModifier : -1;
|
|
522
|
+
// Explicit overrides
|
|
558
523
|
if (!gqlTypeByTypeIdAndModifier[type.id][typeModifierKey]) {
|
|
559
524
|
const gqlType = oidLookup[type.id];
|
|
560
|
-
|
|
561
525
|
if (gqlType) {
|
|
562
526
|
gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] = gqlType;
|
|
563
527
|
}
|
|
564
528
|
}
|
|
565
|
-
|
|
566
529
|
if (!gqlInputTypeByTypeIdAndModifier[type.id][typeModifierKey]) {
|
|
567
530
|
const gqlInputType = oidInputLookup[type.id];
|
|
568
|
-
|
|
569
531
|
if (gqlInputType) {
|
|
570
532
|
gqlInputTypeByTypeIdAndModifier[type.id][typeModifierKey] = gqlInputType;
|
|
571
533
|
}
|
|
572
|
-
}
|
|
534
|
+
}
|
|
573
535
|
|
|
536
|
+
// cf https://github.com/graphile/graphile-engine/pull/748#discussion_r650828353
|
|
537
|
+
let shouldSkipAddType = false;
|
|
574
538
|
|
|
539
|
+
// Enums
|
|
575
540
|
if (!gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] && type.type === "e") {
|
|
576
541
|
gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] = newWithHooks(GraphQLEnumType, {
|
|
577
542
|
name: inflection.enumType(type),
|
|
@@ -587,25 +552,20 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
587
552
|
pgIntrospection: type,
|
|
588
553
|
isPgEnumType: true
|
|
589
554
|
});
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
|
|
555
|
+
}
|
|
556
|
+
// Ranges
|
|
593
557
|
if (!gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] && type.type === "r") {
|
|
594
558
|
const subtype = introspectionResultsByKind.typeById[type.rangeSubTypeId];
|
|
595
559
|
const gqlRangeSubType = getGqlTypeByTypeIdAndModifier(subtype.id, typeModifier);
|
|
596
560
|
const gqlRangeInputSubType = getGqlInputTypeByTypeIdAndModifier(subtype.id, typeModifier);
|
|
597
|
-
|
|
598
561
|
if (!gqlRangeSubType) {
|
|
599
562
|
throw new Error("Range of unsupported");
|
|
600
563
|
}
|
|
601
|
-
|
|
602
564
|
if (!gqlRangeInputSubType) {
|
|
603
565
|
throw new Error("Range of unsupported input type");
|
|
604
566
|
}
|
|
605
|
-
|
|
606
567
|
let Range = getTypeByName(inflection.rangeType(gqlRangeSubType.name));
|
|
607
568
|
let RangeInput;
|
|
608
|
-
|
|
609
569
|
if (!Range) {
|
|
610
570
|
const RangeBound = newWithHooks(GraphQLObjectType, {
|
|
611
571
|
name: inflection.rangeBoundType(gqlRangeSubType.name),
|
|
@@ -688,14 +648,11 @@ var PgTypesPlugin = function PgTypesPlugin(builder, {
|
|
|
688
648
|
} else {
|
|
689
649
|
RangeInput = getTypeByName(inflection.inputType(Range.name));
|
|
690
650
|
}
|
|
691
|
-
|
|
692
651
|
gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] = Range;
|
|
693
652
|
gqlInputTypeByTypeIdAndModifier[type.id][typeModifierKey] = RangeInput;
|
|
694
|
-
|
|
695
653
|
if (pgTweaksByTypeIdAndModifer[type.id] === undefined) {
|
|
696
654
|
pgTweaksByTypeIdAndModifer[type.id] = {};
|
|
697
655
|
}
|
|
698
|
-
|
|
699
656
|
pgTweaksByTypeIdAndModifer[type.id][typeModifierKey] = fragment => sql.fragment`\
|
|
700
657
|
case
|
|
701
658
|
when (${fragment}) is null then null
|
|
@@ -710,7 +667,6 @@ else json_build_object(
|
|
|
710
667
|
end
|
|
711
668
|
)
|
|
712
669
|
end`;
|
|
713
|
-
|
|
714
670
|
pg2GqlMapper[type.id] = {
|
|
715
671
|
map: identity,
|
|
716
672
|
unmap: ({
|
|
@@ -725,223 +681,205 @@ end`;
|
|
|
725
681
|
return sql.fragment`${sql.identifier(type.namespaceName, type.name)}(${lower}, ${upper}, ${sql.literal(lowerInclusive + upperInclusive)})`;
|
|
726
682
|
}
|
|
727
683
|
};
|
|
728
|
-
}
|
|
729
|
-
|
|
684
|
+
}
|
|
730
685
|
|
|
686
|
+
// Domains
|
|
731
687
|
if (!gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] && type.type === "d" && type.domainBaseTypeId) {
|
|
732
|
-
|
|
733
|
-
const
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
688
|
+
// might be used as an enum alias: https://github.com/graphile/postgraphile/issues/1500
|
|
689
|
+
const tagEnumName = type.tags && typeof type.tags.enum === "string" ? type.tags.enum : null;
|
|
690
|
+
const truncatedTypeName = !tagEnumName && type.name.endsWith(ENUM_DOMAIN_SUFFIX) ? type.name.slice(0, type.name.length - ENUM_DOMAIN_SUFFIX.length) : null;
|
|
691
|
+
const underlyingEnumTypeName = tagEnumName || truncatedTypeName;
|
|
692
|
+
if (underlyingEnumTypeName !== null) {
|
|
693
|
+
const baseTypeId = getPgFakeEnumIdentifier(type.namespaceName, underlyingEnumTypeName);
|
|
694
|
+
const baseType = getGqlTypeByTypeIdAndModifier(baseTypeId, typeModifierKey);
|
|
695
|
+
const baseInputType = getGqlInputTypeByTypeIdAndModifier(baseTypeId, typeModifierKey);
|
|
696
|
+
if (!baseType || !baseInputType) {
|
|
697
|
+
if (tagEnumName) {
|
|
698
|
+
throw new Error(`The domain ${type.name} uses '@enum ${tagEnumName}' to references its underlying enum type, but no type named ${tagEnumName} could be found.`);
|
|
699
|
+
} else {
|
|
700
|
+
throw new Error(`The domain ${type.name} references the enum type ${underlyingEnumTypeName}, but no such type could be found.`);
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] = baseType;
|
|
704
|
+
gqlInputTypeByTypeIdAndModifier[type.id][typeModifierKey] = baseInputType;
|
|
705
|
+
shouldSkipAddType = true;
|
|
706
|
+
} else {
|
|
707
|
+
const baseType = getGqlTypeByTypeIdAndModifier(type.domainBaseTypeId, typeModifier);
|
|
708
|
+
const baseInputType = getGqlInputTypeByTypeIdAndModifier(type.domainBaseTypeId, typeModifier);
|
|
709
|
+
// Hack stolen from: https://github.com/graphile/postgraphile/blob/ade728ed8f8e3ecdc5fdad7d770c67aa573578eb/src/graphql/schema/type/aliasGqlType.ts#L16
|
|
710
|
+
gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] = Object.assign(Object.create(baseType), {
|
|
711
|
+
name: inflection.domainType(type),
|
|
743
712
|
description: type.description
|
|
744
713
|
});
|
|
714
|
+
if (baseInputType && baseInputType !== baseType) {
|
|
715
|
+
gqlInputTypeByTypeIdAndModifier[type.id][typeModifierKey] = Object.assign(Object.create(baseInputType), {
|
|
716
|
+
name: inflection.inputType(gqlTypeByTypeIdAndModifier[type.id][typeModifierKey]),
|
|
717
|
+
description: type.description
|
|
718
|
+
});
|
|
719
|
+
}
|
|
745
720
|
}
|
|
746
|
-
}
|
|
747
|
-
|
|
721
|
+
}
|
|
748
722
|
|
|
723
|
+
// Arrays
|
|
749
724
|
if (!gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] && type.category === "A") {
|
|
750
725
|
const arrayEntryOutputType = getGqlTypeByTypeIdAndModifier(type.arrayItemTypeId, typeModifier);
|
|
751
726
|
gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] = new GraphQLList(arrayEntryOutputType);
|
|
752
|
-
|
|
753
727
|
if (!disableIssue390Fix) {
|
|
754
728
|
const arrayEntryInputType = getGqlInputTypeByTypeIdAndModifier(type.arrayItemTypeId, typeModifier);
|
|
755
|
-
|
|
756
729
|
if (arrayEntryInputType) {
|
|
757
730
|
gqlInputTypeByTypeIdAndModifier[type.id][typeModifierKey] = new GraphQLList(arrayEntryInputType);
|
|
758
731
|
}
|
|
759
732
|
}
|
|
760
|
-
}
|
|
761
|
-
|
|
733
|
+
}
|
|
762
734
|
|
|
735
|
+
// Booleans
|
|
763
736
|
if (!gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] && type.category === "B") {
|
|
764
737
|
gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] = GraphQLBoolean;
|
|
765
|
-
}
|
|
766
|
-
// default.
|
|
767
|
-
|
|
738
|
+
}
|
|
768
739
|
|
|
740
|
+
// Numbers may be too large for GraphQL/JS to handle, so stringify by
|
|
741
|
+
// default.
|
|
769
742
|
if (!gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] && type.category === "N") {
|
|
770
743
|
pgTweaksByTypeId[type.id] = tweakToText;
|
|
771
744
|
gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] = BigFloat;
|
|
772
|
-
}
|
|
773
|
-
|
|
745
|
+
}
|
|
774
746
|
|
|
747
|
+
// Nothing else worked; pass through as string!
|
|
775
748
|
if (!gqlTypeByTypeIdAndModifier[type.id][typeModifierKey]) {
|
|
776
749
|
// XXX: consider using stringType(upperFirst(camelCase(`fallback_${type.name}`)), type.description)?
|
|
777
750
|
gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] = GraphQLString;
|
|
778
|
-
}
|
|
779
|
-
|
|
780
|
-
|
|
751
|
+
}
|
|
752
|
+
// Now for input types, fall back to output types if possible
|
|
781
753
|
if (!gqlInputTypeByTypeIdAndModifier[type.id][typeModifierKey]) {
|
|
782
754
|
if (isInputType(gqlTypeByTypeIdAndModifier[type.id][typeModifierKey])) {
|
|
783
755
|
gqlInputTypeByTypeIdAndModifier[type.id][typeModifierKey] = gqlTypeByTypeIdAndModifier[type.id][typeModifierKey];
|
|
784
756
|
}
|
|
785
757
|
}
|
|
786
|
-
|
|
787
|
-
|
|
758
|
+
// if its a domain type substituting for an enum table,
|
|
759
|
+
// adding it creates a duplicate
|
|
760
|
+
if (!shouldSkipAddType) {
|
|
761
|
+
addType(getNamedType(gqlTypeByTypeIdAndModifier[type.id][typeModifierKey]));
|
|
762
|
+
}
|
|
788
763
|
return gqlTypeByTypeIdAndModifier[type.id][typeModifierKey];
|
|
789
764
|
};
|
|
790
|
-
|
|
791
765
|
function getGqlTypeByTypeIdAndModifier(typeId, typeModifier = null, useFallback = true) {
|
|
792
766
|
const typeModifierKey = typeModifier != null ? typeModifier : -1;
|
|
793
|
-
|
|
794
767
|
if (!gqlTypeByTypeIdAndModifier[typeId]) {
|
|
795
768
|
gqlTypeByTypeIdAndModifier[typeId] = {};
|
|
796
769
|
}
|
|
797
|
-
|
|
798
770
|
if (!gqlInputTypeByTypeIdAndModifier[typeId]) {
|
|
799
771
|
gqlInputTypeByTypeIdAndModifier[typeId] = {};
|
|
800
772
|
}
|
|
801
|
-
|
|
802
773
|
if (!gqlTypeByTypeIdAndModifier[typeId][typeModifierKey]) {
|
|
803
774
|
const type = introspectionResultsByKind.type.find(t => t.id === typeId);
|
|
804
|
-
|
|
805
775
|
if (!type) {
|
|
806
776
|
throw new Error(`Type '${typeId}' not present in introspection results`);
|
|
807
777
|
}
|
|
808
|
-
|
|
809
778
|
const gen = gqlTypeByTypeIdGenerator[type.id];
|
|
810
|
-
|
|
811
779
|
if (gen) {
|
|
812
780
|
const set = Type => {
|
|
813
781
|
gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] = Type;
|
|
814
782
|
};
|
|
815
|
-
|
|
816
783
|
const result = gen(set, typeModifier);
|
|
817
|
-
|
|
818
784
|
if (result) {
|
|
819
785
|
if (gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] && gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] !== result) {
|
|
820
786
|
throw new Error(`Callback and return types differ when defining type for '${type.id}'`);
|
|
821
787
|
}
|
|
822
|
-
|
|
823
788
|
gqlTypeByTypeIdAndModifier[type.id][typeModifierKey] = result;
|
|
824
789
|
}
|
|
825
790
|
}
|
|
826
791
|
}
|
|
827
|
-
|
|
828
792
|
if (!gqlTypeByTypeIdAndModifier[typeId][typeModifierKey] && typeModifierKey > -1) {
|
|
829
793
|
// Fall back to `null` modifier, but if that still doesn't work, we
|
|
830
794
|
// still want to pass the modifier to enforceGqlTypeByPgTypeId.
|
|
831
795
|
const fallback = getGqlTypeByTypeIdAndModifier(typeId, null, false);
|
|
832
|
-
|
|
833
796
|
if (fallback) {
|
|
834
797
|
return fallback;
|
|
835
798
|
}
|
|
836
799
|
}
|
|
837
|
-
|
|
838
800
|
if (useFallback && !gqlTypeByTypeIdAndModifier[typeId][typeModifierKey]) {
|
|
839
801
|
return enforceGqlTypeByPgTypeId(typeId, typeModifier);
|
|
840
802
|
}
|
|
841
|
-
|
|
842
803
|
return gqlTypeByTypeIdAndModifier[typeId][typeModifierKey];
|
|
843
804
|
}
|
|
844
|
-
|
|
845
805
|
function getGqlInputTypeByTypeIdAndModifier(typeId, typeModifier = null) {
|
|
846
806
|
// First, load the OUTPUT type (it might register an input type)
|
|
847
807
|
getGqlTypeByTypeIdAndModifier(typeId, typeModifier);
|
|
848
808
|
const typeModifierKey = typeModifier != null ? typeModifier : -1;
|
|
849
|
-
|
|
850
809
|
if (!gqlInputTypeByTypeIdAndModifier[typeId]) {
|
|
851
810
|
gqlInputTypeByTypeIdAndModifier[typeId] = {};
|
|
852
811
|
}
|
|
853
|
-
|
|
854
812
|
if (!gqlInputTypeByTypeIdAndModifier[typeId][typeModifierKey]) {
|
|
855
813
|
const type = introspectionResultsByKind.typeById[typeId];
|
|
856
|
-
|
|
857
814
|
if (!type) {
|
|
858
815
|
throw new Error(`Type '${typeId}' not present in introspection results`);
|
|
859
816
|
}
|
|
860
|
-
|
|
861
817
|
const gen = gqlInputTypeByTypeIdGenerator[type.id];
|
|
862
|
-
|
|
863
818
|
if (gen) {
|
|
864
819
|
const set = Type => {
|
|
865
820
|
gqlInputTypeByTypeIdAndModifier[type.id][typeModifierKey] = Type;
|
|
866
821
|
};
|
|
867
|
-
|
|
868
822
|
const result = gen(set, typeModifier);
|
|
869
|
-
|
|
870
823
|
if (result) {
|
|
871
824
|
if (gqlInputTypeByTypeIdAndModifier[type.id][typeModifierKey] && gqlInputTypeByTypeIdAndModifier[type.id][typeModifierKey] !== result) {
|
|
872
825
|
throw new Error(`Callback and return types differ when defining type for '${type.id}'`);
|
|
873
826
|
}
|
|
874
|
-
|
|
875
827
|
gqlInputTypeByTypeIdAndModifier[type.id][typeModifierKey] = result;
|
|
876
828
|
}
|
|
877
829
|
}
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
|
|
830
|
+
}
|
|
831
|
+
// Use the same type as the output type if it's valid input
|
|
881
832
|
if (!gqlInputTypeByTypeIdAndModifier[typeId][typeModifierKey] && gqlTypeByTypeIdAndModifier[typeId] && gqlTypeByTypeIdAndModifier[typeId][typeModifierKey] && isInputType(gqlTypeByTypeIdAndModifier[typeId][typeModifierKey])) {
|
|
882
833
|
gqlInputTypeByTypeIdAndModifier[typeId][typeModifierKey] = gqlTypeByTypeIdAndModifier[typeId][typeModifierKey];
|
|
883
834
|
}
|
|
884
|
-
|
|
885
835
|
if (!gqlInputTypeByTypeIdAndModifier[typeId][typeModifierKey] && typeModifierKey > -1) {
|
|
886
836
|
// Fall back to default
|
|
887
837
|
return getGqlInputTypeByTypeIdAndModifier(typeId, null);
|
|
888
838
|
}
|
|
889
|
-
|
|
890
839
|
return gqlInputTypeByTypeIdAndModifier[typeId][typeModifierKey];
|
|
891
840
|
}
|
|
892
|
-
|
|
893
841
|
function registerGqlTypeByTypeId(typeId, gen, yieldToExisting = false) {
|
|
894
842
|
if (gqlTypeByTypeIdGenerator[typeId]) {
|
|
895
843
|
if (yieldToExisting) {
|
|
896
844
|
return;
|
|
897
845
|
}
|
|
898
|
-
|
|
899
846
|
throw new Error(`There's already a type generator registered for '${typeId}'`);
|
|
900
847
|
}
|
|
901
|
-
|
|
902
848
|
gqlTypeByTypeIdGenerator[typeId] = gen;
|
|
903
849
|
}
|
|
904
|
-
|
|
905
850
|
function registerGqlInputTypeByTypeId(typeId, gen, yieldToExisting = false) {
|
|
906
851
|
if (gqlInputTypeByTypeIdGenerator[typeId]) {
|
|
907
852
|
if (yieldToExisting) {
|
|
908
853
|
return;
|
|
909
854
|
}
|
|
910
|
-
|
|
911
855
|
throw new Error(`There's already an input type generator registered for '${typeId}'`);
|
|
912
856
|
}
|
|
913
|
-
|
|
914
857
|
gqlInputTypeByTypeIdGenerator[typeId] = gen;
|
|
915
|
-
}
|
|
916
|
-
|
|
858
|
+
}
|
|
917
859
|
|
|
860
|
+
// DEPRECATIONS!
|
|
918
861
|
function getGqlTypeByTypeId(typeId, typeModifier) {
|
|
919
862
|
if (typeModifier === undefined) {
|
|
920
863
|
// eslint-disable-next-line no-console
|
|
921
864
|
console.warn("DEPRECATION WARNING: getGqlTypeByTypeId should not be used - for some columns we also require typeModifier to be specified. Please update your code ASAP to pass `attribute.typeModifier` through as the second parameter (or null if it's not available).");
|
|
922
865
|
}
|
|
923
|
-
|
|
924
866
|
return getGqlTypeByTypeIdAndModifier(typeId, typeModifier);
|
|
925
867
|
}
|
|
926
|
-
|
|
927
868
|
function getGqlInputTypeByTypeId(typeId, typeModifier) {
|
|
928
869
|
if (typeModifier === undefined) {
|
|
929
870
|
// eslint-disable-next-line no-console
|
|
930
871
|
console.warn("DEPRECATION WARNING: getGqlInputTypeByTypeId should not be used - for some columns we also require typeModifier to be specified. Please update your code ASAP to pass `attribute.typeModifier` through as the second parameter (or null if it's not available).");
|
|
931
872
|
}
|
|
932
|
-
|
|
933
873
|
return getGqlInputTypeByTypeIdAndModifier(typeId, typeModifier);
|
|
934
874
|
}
|
|
935
|
-
|
|
936
875
|
function pgTweakFragmentForType(fragment, type, typeModifier, resolveData) {
|
|
937
876
|
if (typeModifier === undefined) {
|
|
938
877
|
// eslint-disable-next-line no-console
|
|
939
878
|
console.warn("DEPRECATION WARNING: pgTweakFragmentForType should not be used - for some columns we also require typeModifier to be specified. Please update your code ASAP to pass `attribute.typeModifier` through as the third parameter (or null if it's not available).");
|
|
940
879
|
}
|
|
941
|
-
|
|
942
880
|
return pgTweakFragmentForTypeAndModifier(fragment, type, typeModifier, resolveData);
|
|
943
|
-
}
|
|
944
|
-
|
|
881
|
+
}
|
|
882
|
+
// END OF DEPRECATIONS!
|
|
945
883
|
|
|
946
884
|
return build.extend(build, {
|
|
947
885
|
pgRegisterGqlTypeByTypeId: registerGqlTypeByTypeId,
|
|
@@ -961,11 +899,10 @@ end`;
|
|
|
961
899
|
pgGetGqlInputTypeByTypeId: getGqlInputTypeByTypeId,
|
|
962
900
|
// DEPRECATED, replaced by getGqlInputTypeByTypeIdAndModifier
|
|
963
901
|
pgTweakFragmentForType // DEPRECATED, replaced by pgTweakFragmentForTypeAndModifier
|
|
964
|
-
|
|
965
902
|
});
|
|
966
903
|
}, ["PgTypes"], [], ["PgIntrospection", "StandardTypes"]);
|
|
967
|
-
/* Start of hstore type */
|
|
968
904
|
|
|
905
|
+
/* Start of hstore type */
|
|
969
906
|
builder.hook("inflection", (inflection, build) => {
|
|
970
907
|
// This hook allows you to append a plugin which renames the KeyValueHash
|
|
971
908
|
// (hstore) type name.
|
|
@@ -974,7 +911,6 @@ end`;
|
|
|
974
911
|
hstoreType() {
|
|
975
912
|
return "KeyValueHash";
|
|
976
913
|
}
|
|
977
|
-
|
|
978
914
|
});
|
|
979
915
|
}, ["PgTypesHstore"]);
|
|
980
916
|
builder.hook("build", build => {
|
|
@@ -987,30 +923,31 @@ end`;
|
|
|
987
923
|
pgRegisterGqlInputTypeByTypeId,
|
|
988
924
|
pg2GqlMapper,
|
|
989
925
|
pgSql: sql
|
|
990
|
-
} = build;
|
|
926
|
+
} = build;
|
|
991
927
|
|
|
928
|
+
// Check we have the hstore extension
|
|
992
929
|
const hstoreExtension = introspectionResultsByKind.extension.find(e => e.name === "hstore");
|
|
993
|
-
|
|
994
930
|
if (!hstoreExtension) {
|
|
995
931
|
return build;
|
|
996
|
-
}
|
|
997
|
-
|
|
932
|
+
}
|
|
998
933
|
|
|
934
|
+
// Get the 'hstore' type itself:
|
|
999
935
|
const hstoreType = introspectionResultsByKind.type.find(t => t.name === "hstore" && t.namespaceId === hstoreExtension.namespaceId);
|
|
1000
|
-
|
|
1001
936
|
if (!hstoreType) {
|
|
1002
937
|
return build;
|
|
1003
938
|
}
|
|
939
|
+
const hstoreTypeName = build.inflection.hstoreType();
|
|
1004
940
|
|
|
1005
|
-
|
|
941
|
+
// We're going to use our own special HStore type for this so that we get
|
|
1006
942
|
// better validation; but you could just as easily use JSON directly if you
|
|
1007
943
|
// wanted to.
|
|
944
|
+
const GraphQLHStoreType = makeGraphQLHstoreType(build, hstoreTypeName);
|
|
1008
945
|
|
|
1009
|
-
|
|
1010
|
-
|
|
946
|
+
// Now register the hstore type with the type system for both output and input.
|
|
1011
947
|
pgRegisterGqlTypeByTypeId(hstoreType.id, () => GraphQLHStoreType);
|
|
1012
|
-
pgRegisterGqlInputTypeByTypeId(hstoreType.id, () => GraphQLHStoreType);
|
|
948
|
+
pgRegisterGqlInputTypeByTypeId(hstoreType.id, () => GraphQLHStoreType);
|
|
1013
949
|
|
|
950
|
+
// Finally we must tell the system how to translate the data between PG-land and JS-land:
|
|
1014
951
|
pg2GqlMapper[hstoreType.id] = {
|
|
1015
952
|
// node-postgres parses hstore for us, no action required on map
|
|
1016
953
|
map: identity,
|
|
@@ -1022,7 +959,6 @@ end`;
|
|
|
1022
959
|
/* End of hstore type */
|
|
1023
960
|
|
|
1024
961
|
/* Geometric types */
|
|
1025
|
-
|
|
1026
962
|
builder.hook("build", build => {
|
|
1027
963
|
// This hook tells graphile-build-pg about the hstore database type so it
|
|
1028
964
|
// knows how to express it in input/output.
|
|
@@ -1042,8 +978,9 @@ end`;
|
|
|
1042
978
|
GraphQLFloat
|
|
1043
979
|
},
|
|
1044
980
|
inflection
|
|
1045
|
-
} = build;
|
|
981
|
+
} = build;
|
|
1046
982
|
|
|
983
|
+
// Check we have the hstore extension
|
|
1047
984
|
const LINE = 628;
|
|
1048
985
|
const LSEG = 601;
|
|
1049
986
|
const BOX = 603;
|
|
@@ -1052,11 +989,9 @@ end`;
|
|
|
1052
989
|
const CIRCLE = 718;
|
|
1053
990
|
pgRegisterGqlTypeByTypeId(LINE, () => {
|
|
1054
991
|
const Point = pgGetGqlTypeByTypeIdAndModifier("600", null);
|
|
1055
|
-
|
|
1056
992
|
if (!Point) {
|
|
1057
993
|
throw new Error("Need point type");
|
|
1058
994
|
}
|
|
1059
|
-
|
|
1060
995
|
return new GraphQLObjectType({
|
|
1061
996
|
name: inflection.builtin("Line"),
|
|
1062
997
|
description: build.wrapDescription("An infinite line that passes through points 'a' and 'b'.", "type"),
|
|
@@ -1088,10 +1023,10 @@ end`;
|
|
|
1088
1023
|
pg2GqlMapper[LINE] = {
|
|
1089
1024
|
map: f => {
|
|
1090
1025
|
if (f[0] === "{" && f[f.length - 1] === "}") {
|
|
1091
|
-
const [A, B, C] = f.slice(1, -1).split(",").map(f => parseFloat(f));
|
|
1026
|
+
const [A, B, C] = f.slice(1, -1).split(",").map(f => parseFloat(f));
|
|
1027
|
+
// Lines have the form Ax + By + C = 0.
|
|
1092
1028
|
// So if y = 0, Ax + C = 0; x = -C/A.
|
|
1093
1029
|
// If x = 0, By + C = 0; y = -C/B.
|
|
1094
|
-
|
|
1095
1030
|
return {
|
|
1096
1031
|
a: {
|
|
1097
1032
|
x: -C / A,
|
|
@@ -1237,29 +1172,23 @@ end`;
|
|
|
1237
1172
|
pg2GqlMapper[PATH] = {
|
|
1238
1173
|
map: f => {
|
|
1239
1174
|
let isOpen = null;
|
|
1240
|
-
|
|
1241
1175
|
if (f[0] === "(" && f[f.length - 1] === ")") {
|
|
1242
1176
|
isOpen = false;
|
|
1243
1177
|
} else if (f[0] === "[" && f[f.length - 1] === "]") {
|
|
1244
1178
|
isOpen = true;
|
|
1245
1179
|
}
|
|
1246
|
-
|
|
1247
1180
|
if (isOpen !== null) {
|
|
1248
1181
|
const xsAndYs = f.slice(1, -1).replace(/[()]/g, "").split(",").map(f => parseFloat(f));
|
|
1249
|
-
|
|
1250
1182
|
if (xsAndYs.length % 2 !== 0) {
|
|
1251
1183
|
throw new Error("Invalid path representation");
|
|
1252
1184
|
}
|
|
1253
|
-
|
|
1254
1185
|
const points = [];
|
|
1255
|
-
|
|
1256
1186
|
for (let i = 0, l = xsAndYs.length; i < l; i += 2) {
|
|
1257
1187
|
points.push({
|
|
1258
1188
|
x: xsAndYs[i],
|
|
1259
1189
|
y: xsAndYs[i + 1]
|
|
1260
1190
|
});
|
|
1261
1191
|
}
|
|
1262
|
-
|
|
1263
1192
|
return {
|
|
1264
1193
|
isOpen,
|
|
1265
1194
|
points
|
|
@@ -1299,20 +1228,16 @@ end`;
|
|
|
1299
1228
|
map: f => {
|
|
1300
1229
|
if (f[0] === "(" && f[f.length - 1] === ")") {
|
|
1301
1230
|
const xsAndYs = f.slice(1, -1).replace(/[()]/g, "").split(",").map(f => parseFloat(f));
|
|
1302
|
-
|
|
1303
1231
|
if (xsAndYs.length % 2 !== 0) {
|
|
1304
1232
|
throw new Error("Invalid polygon representation");
|
|
1305
1233
|
}
|
|
1306
|
-
|
|
1307
1234
|
const points = [];
|
|
1308
|
-
|
|
1309
1235
|
for (let i = 0, l = xsAndYs.length; i < l; i += 2) {
|
|
1310
1236
|
points.push({
|
|
1311
1237
|
x: xsAndYs[i],
|
|
1312
1238
|
y: xsAndYs[i + 1]
|
|
1313
1239
|
});
|
|
1314
1240
|
}
|
|
1315
|
-
|
|
1316
1241
|
return {
|
|
1317
1242
|
points
|
|
1318
1243
|
};
|
|
@@ -1365,15 +1290,15 @@ end`;
|
|
|
1365
1290
|
}
|
|
1366
1291
|
},
|
|
1367
1292
|
unmap: o => sql.fragment`circle(point(${sql.value(o.center.x)}, ${sql.value(o.center.y)}), ${sql.value(o.radius)})`
|
|
1368
|
-
};
|
|
1293
|
+
};
|
|
1294
|
+
|
|
1295
|
+
// TODO: add the non-nulls!
|
|
1369
1296
|
|
|
1370
1297
|
return build;
|
|
1371
1298
|
}, ["PgGeometryTypes"], [], ["PgTypes"]);
|
|
1372
1299
|
/* End of geometric types */
|
|
1373
1300
|
};
|
|
1374
|
-
|
|
1375
1301
|
exports.default = PgTypesPlugin;
|
|
1376
|
-
|
|
1377
1302
|
function makeGraphQLHstoreType(build, hstoreTypeName) {
|
|
1378
1303
|
const {
|
|
1379
1304
|
graphql
|
|
@@ -1382,7 +1307,6 @@ function makeGraphQLHstoreType(build, hstoreTypeName) {
|
|
|
1382
1307
|
GraphQLScalarType,
|
|
1383
1308
|
Kind
|
|
1384
1309
|
} = graphql;
|
|
1385
|
-
|
|
1386
1310
|
function isValidHstoreObject(obj) {
|
|
1387
1311
|
if (obj === null) {
|
|
1388
1312
|
// Null is okay
|
|
@@ -1390,67 +1314,56 @@ function makeGraphQLHstoreType(build, hstoreTypeName) {
|
|
|
1390
1314
|
} else if (typeof obj === "object") {
|
|
1391
1315
|
// A hash with string/null values is also okay
|
|
1392
1316
|
const keys = Object.keys(obj);
|
|
1393
|
-
|
|
1394
1317
|
for (const key of keys) {
|
|
1395
1318
|
const val = obj[key];
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
} else if (typeof val === "string") {
|
|
1319
|
+
if (val === null) {
|
|
1320
|
+
// Null is okay
|
|
1321
|
+
} else if (typeof val === "string") {
|
|
1322
|
+
// String is okay
|
|
1399
1323
|
} else {
|
|
1400
1324
|
// Everything else is invalid.
|
|
1401
1325
|
return false;
|
|
1402
1326
|
}
|
|
1403
1327
|
}
|
|
1404
|
-
|
|
1405
1328
|
return true;
|
|
1406
1329
|
} else {
|
|
1407
1330
|
// Everything else is invalid.
|
|
1408
1331
|
return false;
|
|
1409
1332
|
}
|
|
1410
1333
|
}
|
|
1411
|
-
|
|
1412
1334
|
function identityWithCheck(obj) {
|
|
1413
1335
|
if (isValidHstoreObject(obj)) {
|
|
1414
1336
|
return obj;
|
|
1415
1337
|
}
|
|
1416
|
-
|
|
1417
1338
|
throw new TypeError(`This is not a valid ${hstoreTypeName} object, it must be a key/value hash where keys and values are both strings (or null).`);
|
|
1418
1339
|
}
|
|
1419
|
-
|
|
1420
1340
|
function parseValueLiteral(ast, variables) {
|
|
1421
1341
|
switch (ast.kind) {
|
|
1422
1342
|
case Kind.INT:
|
|
1423
1343
|
case Kind.FLOAT:
|
|
1424
1344
|
// Number isn't really okay, but we'll coerce it to a string anyway.
|
|
1425
1345
|
return String(parseFloat(ast.value));
|
|
1426
|
-
|
|
1427
1346
|
case Kind.STRING:
|
|
1428
1347
|
// String is okay.
|
|
1429
1348
|
return String(ast.value);
|
|
1430
|
-
|
|
1431
1349
|
case Kind.NULL:
|
|
1432
1350
|
// Null is okay.
|
|
1433
1351
|
return null;
|
|
1434
|
-
|
|
1435
1352
|
case Kind.VARIABLE:
|
|
1436
1353
|
{
|
|
1437
1354
|
// Variable is okay if that variable is either a string or null.
|
|
1438
1355
|
const name = ast.name.value;
|
|
1439
1356
|
const value = variables ? variables[name] : undefined;
|
|
1440
|
-
|
|
1441
1357
|
if (value === null || typeof value === "string") {
|
|
1442
1358
|
return value;
|
|
1443
1359
|
}
|
|
1444
|
-
|
|
1445
1360
|
return undefined;
|
|
1446
1361
|
}
|
|
1447
|
-
|
|
1448
1362
|
default:
|
|
1449
1363
|
// Everything else is invalid.
|
|
1450
1364
|
return undefined;
|
|
1451
1365
|
}
|
|
1452
1366
|
}
|
|
1453
|
-
|
|
1454
1367
|
function parseLiteral(ast, variables) {
|
|
1455
1368
|
switch (ast.kind) {
|
|
1456
1369
|
case Kind.OBJECT:
|
|
@@ -1459,35 +1372,28 @@ function makeGraphQLHstoreType(build, hstoreTypeName) {
|
|
|
1459
1372
|
memo[field.name.value] = parseValueLiteral(field.value, variables);
|
|
1460
1373
|
return memo;
|
|
1461
1374
|
}, Object.create(null));
|
|
1462
|
-
|
|
1463
1375
|
if (!isValidHstoreObject(value)) {
|
|
1464
1376
|
return undefined;
|
|
1465
1377
|
}
|
|
1466
|
-
|
|
1467
1378
|
return value;
|
|
1468
1379
|
}
|
|
1469
|
-
|
|
1470
1380
|
case Kind.NULL:
|
|
1471
1381
|
return null;
|
|
1472
|
-
|
|
1473
1382
|
case Kind.VARIABLE:
|
|
1474
1383
|
{
|
|
1475
1384
|
const name = ast.name.value;
|
|
1476
1385
|
const value = variables ? variables[name] : undefined;
|
|
1477
|
-
|
|
1478
1386
|
if (!isValidHstoreObject(value)) {
|
|
1479
1387
|
return undefined;
|
|
1480
1388
|
}
|
|
1481
|
-
|
|
1482
1389
|
return value;
|
|
1483
1390
|
}
|
|
1484
|
-
|
|
1485
1391
|
default:
|
|
1486
1392
|
return undefined;
|
|
1487
1393
|
}
|
|
1488
|
-
}
|
|
1489
|
-
|
|
1394
|
+
}
|
|
1490
1395
|
|
|
1396
|
+
// TODO: use newWithHooks instead
|
|
1491
1397
|
const GraphQLHStore = new GraphQLScalarType({
|
|
1492
1398
|
name: hstoreTypeName,
|
|
1493
1399
|
description: build.wrapDescription("A set of key/value pairs, keys are strings, values may be a string or null. Exposed as a JSON object.", "type"),
|
|
@@ -1496,36 +1402,30 @@ function makeGraphQLHstoreType(build, hstoreTypeName) {
|
|
|
1496
1402
|
parseLiteral
|
|
1497
1403
|
});
|
|
1498
1404
|
return GraphQLHStore;
|
|
1499
|
-
}
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
// To include a double quote or a backslash in a key or value, escape it
|
|
1500
1408
|
// with a backslash.
|
|
1501
1409
|
// -- https://www.postgresql.org/docs/10/static/hstore.html
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
1410
|
function toHstoreString(str) {
|
|
1505
1411
|
return '"' + str.replace(/(["\\])/g, "\\$1") + '"';
|
|
1506
1412
|
}
|
|
1507
|
-
|
|
1508
1413
|
function hstoreStringify(o) {
|
|
1509
1414
|
if (o === null) {
|
|
1510
1415
|
return null;
|
|
1511
1416
|
}
|
|
1512
|
-
|
|
1513
1417
|
if (typeof o !== "object") {
|
|
1514
1418
|
throw new TypeError("Expected an hstore object");
|
|
1515
1419
|
}
|
|
1516
|
-
|
|
1517
1420
|
const keys = Object.keys(o);
|
|
1518
|
-
|
|
1519
1421
|
const encodeKeyValue = key => {
|
|
1520
1422
|
const value = o[key];
|
|
1521
|
-
|
|
1522
1423
|
if (value === null) {
|
|
1523
1424
|
return `${toHstoreString(key)} => NULL`;
|
|
1524
1425
|
} else {
|
|
1525
1426
|
return `${toHstoreString(key)} => ${toHstoreString(String(value))}`;
|
|
1526
1427
|
}
|
|
1527
1428
|
};
|
|
1528
|
-
|
|
1529
1429
|
return keys.map(encodeKeyValue).join(", ");
|
|
1530
1430
|
}
|
|
1531
1431
|
//# sourceMappingURL=PgTypesPlugin.js.map
|