asobi_console (asobi v0.84.0)
View SourceThe operator console bundle: what priv/console holds, resolved once.
The console is a Vite/React bundle built from console/ and committed to
priv/console. This application serves it from the same origin as the ops
API it reads - one artefact, no second host and no second container.
A host that has extensions with their own console screens builds a composed
bundle instead - rebar3 asobi console, which compiles every installed
extension's priv/console into one chunk alongside core's own screens - and
points console_bundle_app at the application that bundle was written into.
Nothing below changes for it: the composed bundle is read, validated and served
by exactly this code, because it is the same shape of Vite output. See
guides/console-extensions.md.
Nothing here joins a request path onto a directory. The served set is
derived from the build manifest - the entry chunk, its stylesheets, and the
assets it references - and each file is read into a map keyed by its own
basename before the first request is answered. A request names a key that is
in the map or gets a 404, so there is no traversal primitive to get wrong.
That is worth the indirection: nova_file_controller:get_dir/1 joins wildcard
path segments with no dot-segment check, and this is the shape that has no
wildcard to join.
Manifest paths are validated even though the build writes them. A bundler is a third-party program producing a file this module then reads off disk; a name with a slash or a dot segment in it is refused rather than resolved.
The console is off unless console is set true in the asobi application
env. Nova starts one listener, so the console shares the game port, and an
operator surface appearing on a public port has to be asked for rather than
arriving with an upgrade. With no ops_secret configured it can be loaded and
cannot be used - there is no default credential (asobi_ops_auth).
Both outcomes of the load are memoised, the failure included. A node whose bundle is missing says so once and then answers 503 from a term, rather than stat-ing an absent directory on every request.
Summary
Types
Functions
One asset by basename, or error for anything not in the bundle.
The lookup is a map read. Name is never used to build a path.
The resolved bundle, memoised across both outcomes.
-spec enabled() -> boolean().
Whether this node serves the console.
Default false. See the module doc for why it is not true.
-spec load(file:filename_all()) -> {ok, bundle()} | {error, problem()}.
Read a console bundle out of Dir.
Pure apart from the reads, so a test can point it at a directory it built itself and check what the hardening refuses.