Shape-wrangling shared by Gamend.Payments and its provider adapters.
Every provider receives a JSON body from somewhere outside — Apple's signed notifications, Google's RTDN envelopes, Steam's form responses — and each one needed the same four things: string-keyed maps, an epoch-millis timestamp as an ISO-8601 string, a positive integer with a fallback, and a required non-empty string.
So each one had them. normalize_params/1 and its normalize_nested/1
existed verbatim in four modules (Apple twice, once in Apple.JWS),
millis_to_iso8601/1 and parse_positive_int/2 in two, required_binary/2
in two. None of the copies had drifted yet, which is the only reason this is
a tidy-up rather than a bug hunt.
Summary
Functions
A DateTime as ISO-8601; nil for anything else.
A stored provider payload with newer fields merged over it.
Epoch milliseconds as an ISO-8601 string; nil when it is not one.
Recursively string-keys a map, so a body that arrived as atoms and one that arrived as JSON can be read the same way.
An ISO 4217 code in upper case.
Turns the literal \n sequences a PEM key picks up when it travels through an
environment variable back into real newlines.
An integer, or an integer written as a string. See Gamend.Parse.integer/1.
A positive integer, or default when the value is missing or not one.
Whether value is a non-empty string.
Puts value under key when condition is true and the value is a non-empty string.
Fetches key as a non-empty string, or {:error, :missing_<key>}.
A non-empty string, or an integer as its string, at key; {:error, :missing_<key>} otherwise.
Epoch seconds (integer or string) as a second-precision DateTime; nil when it is not one.
Functions
A DateTime as ISO-8601; nil for anything else.
A stored provider payload with newer fields merged over it.
Epoch milliseconds as an ISO-8601 string; nil when it is not one.
Recursively string-keys a map, so a body that arrived as atoms and one that arrived as JSON can be read the same way.
An ISO 4217 code in upper case.
Turns the literal \n sequences a PEM key picks up when it travels through an
environment variable back into real newlines.
@spec parse_datetime(term()) :: DateTime.t() | nil
An ISO-8601 string, or a DateTime, as a second-precision DateTime; nil otherwise.
An integer, or an integer written as a string. See Gamend.Parse.integer/1.
A positive integer, or default when the value is missing or not one.
Whether value is a non-empty string.
Puts value under key when condition is true and the value is a non-empty string.
Fetches key as a non-empty string, or {:error, :missing_<key>}.
A non-empty string, or an integer as its string, at key; {:error, :missing_<key>} otherwise.
@spec unix_seconds_to_datetime(term()) :: DateTime.t() | nil
Epoch seconds (integer or string) as a second-precision DateTime; nil when it is not one.