func graphQLInputForMutation()

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)
    }