GcpApi now acts like other APIs.
Since GcpManager can no longer get at the token exipry by inspecting the
raw update, it must depend on the global store instead. This also means
it can check whether the user has configured S3, and not try to refresh
the token in that case.
In the case where no storage is configured, this will spam the console
with request failures since the thread returns 500 if there is no token.
Perhaps this is a good argument for making the thread return a unit.
Also make it type-level optional rather than using explicit null.
Perhaps one day we will want to use undefined to denote "the thread
hasn't returned yet" and null for "GCP Storage is not configured."
Perhaps.
The S3 client has another layer of indirection we missed. To support it
expediently, we just make the promise() method on GcpUpload do all the
work in GcpClient.
It turns out 'devstorage.read_write' also gives us an access token
instead of a JWT, and is probably more the thing that we want.
Took the opportunity to make scope a macro to clean up the make-jwt call
site.
The expiry field we get from Google is not a timestamp, but a count of
seconds after which the token is invalid (hence, 'expires_in'). We
represent this as a @dr by multiplying the integer we get from Google by
~1s. (Perhaps it will wind up being easier on the Landscape side to
consume the raw integer, but we may as well start off more
type-correct.)
Also cleans up some names now that I'm less confused about how the token
API works, and makes some syntax more vertical.
The correct scope to ask for is not devstorage.editor, but
cloud-platform. This will, rather than returning a signed JWT from
Google that looks like it works but doesn't, return a JSON object
containing an access token and expiration time.
Moves =, closer to call sites so it's clearer what's coming from where.
Also uses +ot, allowing a less horrifying +sign-jwt. This also seems to
not jump back and forth between tapes and cords as much, for what that's
worth.
State before: in chrono:userlib, there were second-resolution
@da-to-unix and unix-to-@da functions. In en/dejs:format, there were
millisecond-resolution @da-to-unix and unix-to-@da functions. The
@da-to-unix path in time:enjs confusingly rounded to the nearest
millisecond, meaning millisecond n was a label for [n-0.5, n+0.5) rather
than [n, n+1).
This adds a millisecond-resolution @da-to-unix and unix-to-@da to
chrono:userlib, and a second-resolution conversion to en/dejs:format.
It makes use of the chrono:userlib functions in en/dejs, and doesn't do
any rounding.
Backwards-incompatible changes:
- made unt:chrono:userlib take a @da rather than @.