in AmplifyPlugins/Core/AWSPluginsCore/Model/Support/Model+GraphQL.swift [18:86]
func graphQLInputForMutation(_ modelSchema: ModelSchema) -> GraphQLInput {
var input: GraphQLInput = [:]
modelSchema.fields.forEach {
let modelField = $0.value
// When the field is read-only don't add it to the GraphQL input object
if modelField.isReadOnly {
return
}
// TODO how to handle associations of type "many" (i.e. cascade save)?
// This is not supported right now and might be added as a future feature
if case .collection = modelField.type {
return
}
let name = modelField.graphQLName
let fieldValueOptional = getFieldValue(for: modelField.name, modelSchema: modelSchema)
// Since the returned value is Any?? we need to do the following:
// - `guard` to make sure the field name exists on the model
// - `guard` to ensure the returned value isn't nil
guard let fieldValue = fieldValueOptional else {
input.updateValue(nil, forKey: name)
return
}
// swiftlint:disable:next syntactic_sugar
guard case .some(Optional<Any>.some(let value)) = fieldValue else {
input.updateValue(nil, forKey: name)
return
}
switch modelField.type {
case .date, .dateTime, .time:
if let date = value as? TemporalSpec {
input[name] = date.iso8601String
} else {
input[name] = value
}
case .enum:
input[name] = (value as? EnumPersistable)?.rawValue
case .model:
let fieldName = getFieldNameForAssociatedModels(modelField: modelField)
input[fieldName] = getModelId(from: value, modelSchema: modelSchema)
case .embedded, .embeddedCollection:
if let encodable = value as? Encodable {
let jsonEncoder = JSONEncoder(dateEncodingStrategy: ModelDateFormatting.encodingStrategy)
do {
let data = try jsonEncoder.encode(encodable.eraseToAnyEncodable())
input[name] = try JSONSerialization.jsonObject(with: data)
} catch {
preconditionFailure("Could not turn into json object from \(value)")
}
}
case .string:
// The input may contain the same keys from `.model` case when the `getFieldNameForAssociatedModels`
// returns the same value as the `modelField.name`. If this is the case, let the `.model` case take
// precedent over the explicit string field on the Model by ignoring the value that is about to be added
if !input.keys.contains(name) {
input[name] = value
}
default:
input[name] = value
}
}
return fixHasOneAssociationsWithExplicitFieldOnModel(input, modelSchema: modelSchema)
}