feat: support GraphQL Upload scalar via multipart requests

This MR adds the capability to upload scalar (files) via multipart requests in GraphQL client methods.

GraphQL.Do previously had no way to send a variable of the Upload scalar type.

Add a GraphQLUpload type: placing one anywhere inside GraphQLQuery.Variables, at any nesting depth including inside lists, switches Do to a multipart/form-data request following the GraphQL multipart request specification (https://github.com/jaydenseric/graphql-multipart-request-spec), which GitLab implements through apollo_upload_server.

Queries without uploads keep the existing JSON path untouched.

Variable paths are computed by mirroring encoding/json semantics (json tags, embedded struct flattening, sorted map keys) so the multipart "map" field always matches the marshaled operations. Content is buffered so the body stays replayable across retryablehttp retries; uploads are validated before any reader is consumed; a single upload referenced from several variables is sent once.

This is usable by any service that needs an Upload scalar, split out of !2962 ahead of the achievements service that first needed it, per review at !2962 (comment 3625833627)

Signed-off-by: BoxBoxJason contact@boxboxjason.dev

Merge request reports

Loading