UNPKG

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