package graphql import ( "context" "fmt" "strings" ) type Mutation[Payload any, Params any] struct { c *Client gqlType string additionalPayloadParams map[string]interface{} additionalQueryParams map[string]interface{} } func NewMutation[Payload any, Params any](c *Client, gqlType string) *Mutation[Payload, Params] { return &Mutation[Payload, Params]{ c: c, gqlType: gqlType, additionalPayloadParams: make(map[string]interface{}), additionalQueryParams: make(map[string]interface{}), } } func (m *Mutation[Payload, Params]) WithPayloadParam( name string, value interface{}, ) *Mutation[Payload, Params] { m.additionalPayloadParams[name] = value return m } func (m *Mutation[Payload, Params]) WithQueryParam( name string, value interface{}, ) *Mutation[Payload, Params] { m.additionalQueryParams[name] = value return m } func (m *Mutation[Payload, Params]) Execute(ctx context.Context, params Params) (Payload, error) { paramsMap := convertParamsToMap(params) for k, v := range m.additionalPayloadParams { paramsMap[k] = v } gqltype := m.gqlType if len(paramsMap) > 0 { keys := make([]string, 0, len(paramsMap)) for k := range paramsMap { keys = append(keys, fmt.Sprintf("%s:$%s", k, k)) } gqltype = fmt.Sprintf("%s(%s)", gqltype, strings.Join(keys, ",")) } q := NewPayload[Payload](gqltype) for k, v := range m.additionalQueryParams { paramsMap[k] = v } err := m.c.Mutate(ctx, &q, paramsMap) if err != nil { var res Payload return res, err } return q.GetValue(), nil }