UNPKG

30.9 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.ModelConnectionTransformer = void 0;
4const graphql_transformer_core_1 = require("graphql-transformer-core");
5const graphql_1 = require("graphql");
6const resources_1 = require("./resources");
7const graphql_dynamodb_transformer_1 = require("graphql-dynamodb-transformer");
8const graphql_transformer_common_1 = require("graphql-transformer-common");
9const graphql_transformer_common_2 = require("graphql-transformer-common");
10const definitions_1 = require("./definitions");
11const CONNECTION_STACK_NAME = 'ConnectionStack';
12function makeConnectionAttributeName(type, field) {
13 return field ? graphql_transformer_common_1.toCamelCase([type, field, 'id']) : graphql_transformer_common_1.toCamelCase([type, 'id']);
14}
15function validateKeyField(field) {
16 if (!field) {
17 return;
18 }
19 const baseType = graphql_transformer_common_1.getBaseType(field.type);
20 const isAList = graphql_transformer_common_1.isListType(field.type);
21 if ((baseType === 'ID' || baseType === 'String') && !isAList) {
22 return;
23 }
24 throw new graphql_transformer_core_1.InvalidDirectiveError(`If you define a field and specify it as a 'keyField', it must be of type 'ID' or 'String'.`);
25}
26function validateKeyFieldConnectionWithKey(field, ctx) {
27 const isNonNull = graphql_transformer_common_1.isNonNullType(field.type);
28 const isAList = graphql_transformer_common_1.isListType(field.type);
29 const isAScalarOrEnum = graphql_transformer_common_1.isScalarOrEnum(field.type, ctx.getTypeDefinitionsOfKind(graphql_1.Kind.ENUM_TYPE_DEFINITION));
30 if (!isAList && isNonNull && isAScalarOrEnum) {
31 return;
32 }
33 throw new graphql_transformer_core_1.InvalidDirectiveError(`All fields provided to an @connection must be non-null scalar or enum fields.`);
34}
35function getFieldType(fields, fieldName) {
36 return fields.find(f => f.name.value === fieldName).type;
37}
38function checkFieldsAgainstIndex(parentFields, relatedTypeFields, inputFieldNames, keySchema, field) {
39 const hashAttributeName = keySchema[0].AttributeName;
40 const tablePKType = getFieldType(relatedTypeFields, String(hashAttributeName));
41 const queryPKType = getFieldType(parentFields, inputFieldNames[0]);
42 const numFields = inputFieldNames.length;
43 if (graphql_transformer_common_1.getBaseType(tablePKType) !== graphql_transformer_common_1.getBaseType(queryPKType)) {
44 throw new graphql_transformer_core_1.InvalidDirectiveError(`${inputFieldNames[0]} field is not of type ${graphql_transformer_common_1.getBaseType(tablePKType)}`);
45 }
46 if (numFields > keySchema.length && keySchema.length !== 2) {
47 throw new graphql_transformer_core_1.InvalidDirectiveError('Too many fields passed in to @connection directive.');
48 }
49 if (numFields > 1) {
50 const querySortFields = inputFieldNames.slice(1);
51 const tableSortFields = String(keySchema[1].AttributeName).split(graphql_transformer_common_2.ModelResourceIDs.ModelCompositeKeySeparator());
52 if (querySortFields.length !== tableSortFields.length) {
53 throw new graphql_transformer_core_1.InvalidDirectiveError(`Invalid @connection directive ${field.name.value}. fields does not accept partial sort key`);
54 }
55 }
56 if (numFields === 2) {
57 const sortAttributeName = String(keySchema[1].AttributeName).split(graphql_transformer_common_2.ModelResourceIDs.ModelCompositeKeySeparator())[0];
58 const tableSKType = getFieldType(relatedTypeFields, String(sortAttributeName));
59 const querySKType = getFieldType(parentFields, inputFieldNames[1]);
60 if (graphql_transformer_common_1.getBaseType(tableSKType) !== graphql_transformer_common_1.getBaseType(querySKType)) {
61 throw new graphql_transformer_core_1.InvalidDirectiveError(`${inputFieldNames[1]} field is not of type ${graphql_transformer_common_1.getBaseType(tableSKType)}`);
62 }
63 }
64 else if (numFields > 2) {
65 const tableSortFields = String(keySchema[1].AttributeName).split(graphql_transformer_common_2.ModelResourceIDs.ModelCompositeKeySeparator());
66 const tableSortKeyTypes = tableSortFields.map(name => getFieldType(relatedTypeFields, name));
67 const querySortFields = inputFieldNames.slice(1);
68 const querySortKeyTypes = querySortFields.map(name => getFieldType(parentFields, name));
69 querySortKeyTypes.forEach((fieldType, index) => {
70 if (graphql_transformer_common_1.getBaseType(fieldType) !== graphql_transformer_common_1.getBaseType(tableSortKeyTypes[index])) {
71 throw new graphql_transformer_core_1.InvalidDirectiveError(`${querySortFields[index]} field is not of type ${graphql_transformer_common_1.getBaseType(tableSortKeyTypes[index])} arguments`);
72 }
73 });
74 }
75}
76class ModelConnectionTransformer extends graphql_transformer_core_1.Transformer {
77 constructor() {
78 super('ModelConnectionTransformer', graphql_transformer_core_1.gql `
79 directive @connection(
80 name: String
81 keyField: String
82 sortField: String
83 keyName: String
84 limit: Int
85 fields: [String!]
86 ) on FIELD_DEFINITION
87 `);
88 this.before = (ctx) => {
89 const template = this.resources.initTemplate();
90 ctx.mergeResources(template.Resources);
91 ctx.mergeParameters(template.Parameters);
92 ctx.mergeOutputs(template.Outputs);
93 };
94 this.field = (parent, field, directive, ctx) => {
95 const parentTypeName = parent.name.value;
96 const fieldName = field.name.value;
97 ctx.mapResourceToStack(CONNECTION_STACK_NAME, graphql_transformer_common_2.ResolverResourceIDs.ResolverResourceID(parentTypeName, fieldName));
98 const parentModelDirective = parent.directives.find((dir) => dir.name.value === 'model');
99 if (!parentModelDirective) {
100 throw new graphql_transformer_core_1.InvalidDirectiveError(`@connection must be on an @model object type field.`);
101 }
102 const relatedTypeName = graphql_transformer_common_1.getBaseType(field.type);
103 const relatedType = ctx.inputDocument.definitions.find(d => d.kind === graphql_1.Kind.OBJECT_TYPE_DEFINITION && d.name.value === relatedTypeName);
104 if (!relatedType) {
105 throw new graphql_transformer_core_1.InvalidDirectiveError(`Could not find an object type named ${relatedTypeName}.`);
106 }
107 const modelDirective = relatedType.directives.find((dir) => dir.name.value === 'model');
108 if (!modelDirective) {
109 throw new graphql_transformer_core_1.InvalidDirectiveError(`Object type ${relatedTypeName} must be annotated with @model.`);
110 }
111 if (graphql_transformer_common_1.getDirectiveArgument(directive, 'fields')) {
112 this.connectionWithKey(parent, field, directive, ctx);
113 return;
114 }
115 let connectionName = graphql_transformer_common_1.getDirectiveArgument(directive, 'name');
116 let associatedSortFieldName = null;
117 let sortType = null;
118 const associatedConnectionField = relatedType.fields.find((f) => {
119 if (f === field) {
120 return false;
121 }
122 const relatedDirective = f.directives.find((dir) => dir.name.value === 'connection');
123 if (relatedDirective) {
124 const relatedDirectiveName = graphql_transformer_common_1.getDirectiveArgument(relatedDirective, 'name');
125 if (connectionName && relatedDirectiveName && relatedDirectiveName === connectionName) {
126 associatedSortFieldName = graphql_transformer_common_1.getDirectiveArgument(relatedDirective, 'sortField');
127 return true;
128 }
129 }
130 return false;
131 });
132 if (connectionName && !associatedConnectionField) {
133 throw new graphql_transformer_core_1.InvalidDirectiveError(`Found one half of connection "${connectionName}" at ${parentTypeName}.${fieldName} but no related field on type ${relatedTypeName}`);
134 }
135 connectionName = connectionName || `${parentTypeName}.${fieldName}`;
136 const leftConnectionIsList = graphql_transformer_common_1.isListType(field.type);
137 const leftConnectionIsNonNull = graphql_transformer_common_1.isNonNullType(field.type);
138 const rightConnectionIsList = associatedConnectionField ? graphql_transformer_common_1.isListType(associatedConnectionField.type) : undefined;
139 const rightConnectionIsNonNull = associatedConnectionField ? graphql_transformer_common_1.isNonNullType(associatedConnectionField.type) : undefined;
140 const limit = graphql_transformer_common_1.getDirectiveArgument(directive, 'limit');
141 let connectionAttributeName = graphql_transformer_common_1.getDirectiveArgument(directive, 'keyField');
142 const associatedSortField = associatedSortFieldName && parent.fields.find((f) => f.name.value === associatedSortFieldName);
143 if (associatedSortField) {
144 if (graphql_transformer_common_1.isListType(associatedSortField.type)) {
145 throw new graphql_transformer_core_1.InvalidDirectiveError(`sortField "${associatedSortFieldName}" is a list. It should be a scalar.`);
146 }
147 sortType = graphql_transformer_common_1.getBaseType(associatedSortField.type);
148 if (!graphql_transformer_common_1.isScalar(associatedSortField.type) || sortType === graphql_transformer_common_1.STANDARD_SCALARS.Boolean) {
149 throw new graphql_transformer_core_1.InvalidDirectiveError(`sortField "${associatedSortFieldName}" is of type "${sortType}". ` +
150 `It should be a scalar that maps to a DynamoDB "String", "Number", or "Binary"`);
151 }
152 }
153 const foreignAssociatedSortField = associatedSortFieldName && relatedType.fields.find((f) => f.name.value === associatedSortFieldName);
154 const sortKeyInfo = foreignAssociatedSortField
155 ? {
156 fieldName: foreignAssociatedSortField.name.value,
157 attributeType: graphql_transformer_common_1.attributeTypeFromScalar(foreignAssociatedSortField.type),
158 typeName: graphql_transformer_common_1.getBaseType(foreignAssociatedSortField.type),
159 }
160 : undefined;
161 if (leftConnectionIsList && rightConnectionIsList) {
162 throw new graphql_transformer_core_1.InvalidDirectiveError(`Invalid Connection (${connectionName}): Many to Many connections are not yet supported.`);
163 }
164 else if (leftConnectionIsList && rightConnectionIsList === false) {
165 const primaryKeyField = this.getPrimaryKeyField(ctx, parent);
166 const idFieldName = primaryKeyField ? primaryKeyField.name.value : 'id';
167 if (!connectionAttributeName) {
168 connectionAttributeName = makeConnectionAttributeName(relatedTypeName, associatedConnectionField.name.value);
169 }
170 const existingKeyField = relatedType.fields.find(f => f.name.value === connectionAttributeName);
171 validateKeyField(existingKeyField);
172 const queryResolver = this.resources.makeQueryConnectionResolver(parentTypeName, fieldName, relatedTypeName, connectionAttributeName, connectionName, idFieldName, sortKeyInfo, limit);
173 ctx.setResource(graphql_transformer_common_2.ResolverResourceIDs.ResolverResourceID(parentTypeName, fieldName), queryResolver);
174 this.extendTypeWithConnection(ctx, parent, field, relatedType, sortKeyInfo);
175 }
176 else if (!leftConnectionIsList && rightConnectionIsList) {
177 if (associatedSortFieldName && !associatedSortField) {
178 throw new graphql_transformer_core_1.InvalidDirectiveError(`sortField "${associatedSortFieldName}" not found on type "${parent.name.value}", other half of connection "${connectionName}".`);
179 }
180 const primaryKeyField = this.getPrimaryKeyField(ctx, relatedType);
181 const idFieldName = primaryKeyField ? primaryKeyField.name.value : 'id';
182 if (!connectionAttributeName) {
183 connectionAttributeName = makeConnectionAttributeName(parentTypeName, fieldName);
184 }
185 const existingKeyField = parent.fields.find(f => f.name.value === connectionAttributeName);
186 validateKeyField(existingKeyField);
187 const tableLogicalId = graphql_transformer_common_2.ModelResourceIDs.ModelTableResourceID(parentTypeName);
188 const table = ctx.getResource(tableLogicalId);
189 const sortField = associatedSortField ? { name: associatedSortFieldName, type: sortType } : null;
190 const updated = this.resources.updateTableForConnection(table, connectionName, connectionAttributeName, sortField);
191 ctx.setResource(tableLogicalId, updated);
192 const getResolver = this.resources.makeGetItemConnectionResolver(parentTypeName, fieldName, relatedTypeName, connectionAttributeName, idFieldName);
193 ctx.setResource(graphql_transformer_common_2.ResolverResourceIDs.ResolverResourceID(parentTypeName, fieldName), getResolver);
194 const createInputName = graphql_transformer_common_2.ModelResourceIDs.ModelCreateInputObjectName(parentTypeName);
195 const createInput = ctx.getType(createInputName);
196 if (createInput) {
197 const updated = definitions_1.updateCreateInputWithConnectionField(createInput, connectionAttributeName, leftConnectionIsNonNull);
198 ctx.putType(updated);
199 }
200 const updateInputName = graphql_transformer_common_2.ModelResourceIDs.ModelUpdateInputObjectName(parentTypeName);
201 const updateInput = ctx.getType(updateInputName);
202 if (updateInput) {
203 const updated = definitions_1.updateUpdateInputWithConnectionField(updateInput, connectionAttributeName);
204 ctx.putType(updated);
205 }
206 }
207 else if (leftConnectionIsList) {
208 const primaryKeyField = this.getPrimaryKeyField(ctx, parent);
209 const idFieldName = primaryKeyField ? primaryKeyField.name.value : 'id';
210 if (!connectionAttributeName) {
211 connectionAttributeName = makeConnectionAttributeName(parentTypeName, fieldName);
212 }
213 const existingKeyField = relatedType.fields.find(f => f.name.value === connectionAttributeName);
214 validateKeyField(existingKeyField);
215 const tableLogicalId = graphql_transformer_common_2.ModelResourceIDs.ModelTableResourceID(relatedTypeName);
216 const table = ctx.getResource(tableLogicalId);
217 const updated = this.resources.updateTableForConnection(table, connectionName, connectionAttributeName);
218 ctx.setResource(tableLogicalId, updated);
219 const queryResolver = this.resources.makeQueryConnectionResolver(parentTypeName, fieldName, relatedTypeName, connectionAttributeName, connectionName, idFieldName, sortKeyInfo, limit);
220 ctx.setResource(graphql_transformer_common_2.ResolverResourceIDs.ResolverResourceID(parentTypeName, fieldName), queryResolver);
221 this.extendTypeWithConnection(ctx, parent, field, relatedType, sortKeyInfo);
222 const createInputName = graphql_transformer_common_2.ModelResourceIDs.ModelCreateInputObjectName(relatedTypeName);
223 const createInput = ctx.getType(createInputName);
224 if (createInput) {
225 const updated = definitions_1.updateCreateInputWithConnectionField(createInput, connectionAttributeName);
226 ctx.putType(updated);
227 }
228 const updateInputName = graphql_transformer_common_2.ModelResourceIDs.ModelUpdateInputObjectName(relatedTypeName);
229 const updateInput = ctx.getType(updateInputName);
230 if (updateInput) {
231 const updated = definitions_1.updateUpdateInputWithConnectionField(updateInput, connectionAttributeName);
232 ctx.putType(updated);
233 }
234 }
235 else {
236 const primaryKeyField = this.getPrimaryKeyField(ctx, relatedType);
237 const idFieldName = primaryKeyField ? primaryKeyField.name.value : 'id';
238 if (!connectionAttributeName) {
239 connectionAttributeName = makeConnectionAttributeName(parentTypeName, fieldName);
240 }
241 let sortFieldInfo;
242 const sortFieldName = graphql_transformer_common_1.getDirectiveArgument(directive, 'sortField');
243 if (sortFieldName) {
244 const relatedSortField = this.getSortField(relatedType);
245 if (!relatedSortField) {
246 throw new graphql_transformer_core_1.InvalidDirectiveError(`sortField "${sortFieldName}" requires a primary @key on type "${relatedTypeName}" with a sort key that was not found.`);
247 }
248 const sortField = parent.fields.find(f => f.name.value === sortFieldName);
249 if (!sortField) {
250 throw new graphql_transformer_core_1.InvalidDirectiveError(`sortField with name "${sortFieldName} cannot be found on type: ${parent.name.value}`);
251 }
252 const relatedSortFieldType = graphql_transformer_common_1.getBaseType(relatedSortField.type);
253 const sortFieldType = graphql_transformer_common_1.getBaseType(sortField.type);
254 if (relatedSortFieldType !== sortFieldType) {
255 throw new graphql_transformer_core_1.InvalidDirectiveError(`sortField "${relatedSortField.name.value}" on type "${relatedTypeName}" is not matching the ` +
256 `type of field "${sortFieldName}" on type "${parentTypeName}"`);
257 }
258 let sortFieldIsStringLike = true;
259 if (sortFieldType === graphql_transformer_common_1.STANDARD_SCALARS.Int ||
260 sortFieldType === graphql_transformer_common_1.STANDARD_SCALARS.Float ||
261 sortFieldType === graphql_transformer_common_1.STANDARD_SCALARS.Bolean) {
262 sortFieldIsStringLike = false;
263 }
264 sortFieldInfo = {
265 primarySortFieldName: relatedSortField.name.value,
266 sortFieldName,
267 sortFieldIsStringLike,
268 };
269 }
270 const existingKeyField = parent.fields.find(f => f.name.value === connectionAttributeName);
271 validateKeyField(existingKeyField);
272 const getResolver = this.resources.makeGetItemConnectionResolver(parentTypeName, fieldName, relatedTypeName, connectionAttributeName, idFieldName, sortFieldInfo);
273 ctx.setResource(graphql_transformer_common_2.ResolverResourceIDs.ResolverResourceID(parentTypeName, fieldName), getResolver);
274 const createInputName = graphql_transformer_common_2.ModelResourceIDs.ModelCreateInputObjectName(parentTypeName);
275 const createInput = ctx.getType(createInputName);
276 if (createInput) {
277 const updated = definitions_1.updateCreateInputWithConnectionField(createInput, connectionAttributeName, leftConnectionIsNonNull);
278 ctx.putType(updated);
279 }
280 const updateInputName = graphql_transformer_common_2.ModelResourceIDs.ModelUpdateInputObjectName(parentTypeName);
281 const updateInput = ctx.getType(updateInputName);
282 if (updateInput) {
283 const updated = definitions_1.updateUpdateInputWithConnectionField(updateInput, connectionAttributeName);
284 ctx.putType(updated);
285 }
286 }
287 };
288 this.connectionWithKey = (parent, field, directive, ctx) => {
289 const parentTypeName = parent.name.value;
290 const fieldName = field.name.value;
291 const args = graphql_transformer_core_1.getDirectiveArguments(directive);
292 if (args.fields.length === 0) {
293 throw new graphql_transformer_core_1.InvalidDirectiveError('No fields passed in to @connection directive.');
294 }
295 const relatedTypeName = graphql_transformer_common_1.getBaseType(field.type);
296 const relatedType = ctx.inputDocument.definitions.find(d => d.kind === graphql_1.Kind.OBJECT_TYPE_DEFINITION && d.name.value === relatedTypeName);
297 const tableLogicalID = graphql_transformer_common_2.ModelResourceIDs.ModelTableResourceID(relatedType.name.value);
298 const tableResource = ctx.getResource(tableLogicalID);
299 let inputFields = [];
300 args.fields.forEach(item => {
301 const fieldsArrayLength = inputFields.length;
302 inputFields.push(parent.fields.find(f => f.name.value === item));
303 if (!inputFields[fieldsArrayLength]) {
304 throw new graphql_transformer_core_1.InvalidDirectiveError(`${item} is not a field in ${parentTypeName}`);
305 }
306 validateKeyFieldConnectionWithKey(inputFields[fieldsArrayLength], ctx);
307 });
308 let index = undefined;
309 if (!args.keyName) {
310 checkFieldsAgainstIndex(parent.fields, relatedType.fields, args.fields, tableResource.Properties.KeySchema, field);
311 }
312 else {
313 index =
314 (tableResource.Properties.GlobalSecondaryIndexes
315 ? tableResource.Properties.GlobalSecondaryIndexes.find(GSI => GSI.IndexName === args.keyName)
316 : null) ||
317 (tableResource.Properties.LocalSecondaryIndexes
318 ? tableResource.Properties.LocalSecondaryIndexes.find(LSI => LSI.IndexName === args.keyName)
319 : null);
320 if (!index) {
321 throw new graphql_transformer_core_1.InvalidDirectiveError(`Key ${args.keyName} does not exist for model ${relatedTypeName}`);
322 }
323 checkFieldsAgainstIndex(parent.fields, relatedType.fields, args.fields, index.KeySchema, field);
324 }
325 if (!graphql_transformer_common_1.isListType(field.type)) {
326 if (args.keyName) {
327 throw new graphql_transformer_core_1.InvalidDirectiveError(`Connection is to a single object but the keyName ${args.keyName} was provided which does not reference the default table.`);
328 }
329 const getResolver = this.resources.makeGetItemConnectionWithKeyResolver(parentTypeName, fieldName, relatedTypeName, args.fields, tableResource.Properties.KeySchema);
330 ctx.setResource(graphql_transformer_common_2.ResolverResourceIDs.ResolverResourceID(parentTypeName, fieldName), getResolver);
331 }
332 else {
333 const keySchema = index ? index.KeySchema : tableResource.Properties.KeySchema;
334 const queryResolver = this.resources.makeQueryConnectionWithKeyResolver(parentTypeName, fieldName, relatedType, args.fields, keySchema, index ? String(index.IndexName) : undefined, args.limit);
335 ctx.setResource(graphql_transformer_common_2.ResolverResourceIDs.ResolverResourceID(parentTypeName, fieldName), queryResolver);
336 let sortKeyInfo = undefined;
337 if (args.fields.length > 1) {
338 sortKeyInfo = undefined;
339 }
340 else {
341 const compositeSortKeyType = 'Composite';
342 const compositeSortKeyName = keySchema[1] ? this.resources.makeCompositeSortKeyName(String(keySchema[1].AttributeName)) : undefined;
343 const sortKeyField = keySchema[1] ? relatedType.fields.find(f => f.name.value === keySchema[1].AttributeName) : undefined;
344 if (sortKeyField) {
345 sortKeyInfo = keySchema[1]
346 ? {
347 fieldName: String(keySchema[1].AttributeName),
348 typeName: graphql_transformer_common_1.getBaseType(sortKeyField.type),
349 model: relatedTypeName,
350 keyName: index ? String(index.IndexName) : 'Primary',
351 }
352 : undefined;
353 }
354 else {
355 sortKeyInfo = keySchema[1]
356 ? {
357 fieldName: compositeSortKeyName,
358 typeName: compositeSortKeyType,
359 model: relatedTypeName,
360 keyName: index ? String(index.IndexName) : 'Primary',
361 }
362 : undefined;
363 }
364 }
365 this.extendTypeWithConnection(ctx, parent, field, relatedType, sortKeyInfo);
366 }
367 };
368 this.resources = new resources_1.ResourceFactory();
369 }
370 typeExist(type, ctx) {
371 return Boolean(type in ctx.nodeMap);
372 }
373 generateModelXConnectionType(ctx, typeDef) {
374 const tableXConnectionName = graphql_transformer_common_2.ModelResourceIDs.ModelConnectionTypeName(typeDef.name.value);
375 if (this.typeExist(tableXConnectionName, ctx)) {
376 return;
377 }
378 const connectionType = graphql_transformer_common_1.blankObject(tableXConnectionName);
379 ctx.addObject(connectionType);
380 ctx.addObjectExtension(graphql_dynamodb_transformer_1.makeModelConnectionType(typeDef.name.value));
381 }
382 generateFilterAndKeyConditionInputs(ctx, field, sortKeyInfo) {
383 const scalarFilters = graphql_dynamodb_transformer_1.makeScalarFilterInputs(this.supportsConditions(ctx));
384 for (const filter of scalarFilters) {
385 if (!this.typeExist(filter.name.value, ctx)) {
386 ctx.addInput(filter);
387 }
388 }
389 const enumFilters = graphql_dynamodb_transformer_1.makeEnumFilterInputObjects(field, ctx, this.supportsConditions(ctx));
390 for (const filter of enumFilters) {
391 if (!this.typeExist(filter.name.value, ctx)) {
392 ctx.addInput(filter);
393 }
394 }
395 const tableXQueryFilterInput = graphql_dynamodb_transformer_1.makeModelXFilterInputObject(field, ctx, this.supportsConditions(ctx));
396 if (!this.typeExist(tableXQueryFilterInput.name.value, ctx)) {
397 ctx.addInput(tableXQueryFilterInput);
398 }
399 if (this.supportsConditions(ctx)) {
400 const attributeTypeEnum = graphql_dynamodb_transformer_1.makeAttributeTypeEnum();
401 if (!this.typeExist(attributeTypeEnum.name.value, ctx)) {
402 ctx.addType(attributeTypeEnum);
403 }
404 }
405 if (sortKeyInfo && sortKeyInfo.typeName !== 'Composite') {
406 const sortKeyConditionInput = graphql_transformer_common_1.makeScalarKeyConditionForType(graphql_transformer_common_1.makeNamedType(sortKeyInfo.typeName));
407 if (!this.typeExist(sortKeyConditionInput.name.value, ctx)) {
408 ctx.addInput(sortKeyConditionInput);
409 }
410 }
411 }
412 supportsConditions(context) {
413 return context.getTransformerVersion() >= graphql_dynamodb_transformer_1.CONDITIONS_MINIMUM_VERSION;
414 }
415 extendTypeWithConnection(ctx, parent, field, returnType, sortKeyInfo) {
416 this.generateModelXConnectionType(ctx, returnType);
417 const type = ctx.getType(parent.name.value);
418 if (type && (type.kind === graphql_1.Kind.OBJECT_TYPE_DEFINITION || type.kind === graphql_1.Kind.INTERFACE_TYPE_DEFINITION)) {
419 const newFields = type.fields.map((f) => {
420 if (f.name.value === field.name.value) {
421 const updated = graphql_dynamodb_transformer_1.makeModelConnectionField(field.name.value, returnType.name.value, sortKeyInfo, [...f.directives]);
422 return updated;
423 }
424 return f;
425 });
426 const updatedType = {
427 ...type,
428 fields: newFields,
429 };
430 ctx.putType(updatedType);
431 if (!this.typeExist('ModelSortDirection', ctx)) {
432 const modelSortDirection = graphql_dynamodb_transformer_1.makeModelSortDirectionEnumObject();
433 ctx.addEnum(modelSortDirection);
434 }
435 this.generateFilterAndKeyConditionInputs(ctx, returnType, sortKeyInfo);
436 }
437 else {
438 throw new graphql_transformer_core_1.InvalidDirectiveError(`Could not find a object or interface type named ${parent.name.value}.`);
439 }
440 }
441 getPrimaryKeyField(ctx, type) {
442 let field;
443 for (const keyDirective of type.directives.filter(d => d.name.value === 'key')) {
444 if (graphql_transformer_common_1.getDirectiveArgument(keyDirective, 'name') === undefined) {
445 const fieldsArg = graphql_transformer_common_1.getDirectiveArgument(keyDirective, 'fields');
446 if (fieldsArg && fieldsArg.length && fieldsArg.length >= 1 && fieldsArg.length <= 2) {
447 field = type.fields.find(f => f.name.value === fieldsArg[0]);
448 }
449 break;
450 }
451 }
452 return field;
453 }
454 getSortField(type) {
455 let field;
456 for (const keyDirective of type.directives.filter(d => d.name.value === 'key')) {
457 if (graphql_transformer_common_1.getDirectiveArgument(keyDirective, 'name') === undefined) {
458 const fieldsArg = graphql_transformer_common_1.getDirectiveArgument(keyDirective, 'fields');
459 if (fieldsArg && fieldsArg.length && fieldsArg.length === 2) {
460 field = type.fields.find(f => f.name.value === fieldsArg[1]);
461 }
462 break;
463 }
464 }
465 return field;
466 }
467}
468exports.ModelConnectionTransformer = ModelConnectionTransformer;
469//# sourceMappingURL=ModelConnectionTransformer.js.map
\No newline at end of file