@s3p/console-ui
v0.15.0
Published
The auto-generated /server admin console for an s3p project (object browser, users, roles, secrets, email, functions).
Readme
@s3p/console-ui
The ONE admin console for S3-Native App Platform projects — this
project's equivalent of the Firebase Console. It is deployed once
by the platform and served at console.s3p.dev/{slug} for every
project; operators sign in with their platform identity (operator
federation), not a per-project account. Projects do not ship or embed
their own copy.
Historical naming: each project used to serve its own copy at
{slug}.s3p.dev/server. That URL now 302s to the hosted console; "/server" and "server-ui" are dead names (the mount API and custom element keep their legacy identifiers for compatibility).
s3p dev still auto-serves a local /server/ console shell for any
project that has an s3p.project.json record — a dev convenience so
you can inspect your project without leaving localhost.
Panels (today)
Overview (what the project is + what your session can do to it —
the merge of the old thin Identity and Project screens; both ids
still route here), Users (App users — this project's own pool),
Team (operators — the developers who can open this console, via
app.operators), Permissions
(edits s3p.permissions.json / .s3p/permissions.json + sync),
Database (s3db/, scope-aware — see below), Files, Logs, Functions
(registry + CloudWatch logs + in-flight viewer), Secrets (ciphertext
list; decrypting is runtime-only), Email (templates + suppression),
Sign-in, and Domains.
The Database panel is an admin browser, which means it must never
conflate "you may not see this" with "this does not exist". Groups are
keyed by s3db scope (shared / admin / private), private rows
carry the user whose space they are in, the access card describes the
audience that scope actually has, and any root the caller's role can't
list is reported in a banner instead of silently vanishing.
All S3 calls go through the caller-supplied app.getS3Client() so
the panels share the host's STS session and credential refresh path
— no second auth dance. Refresh buttons everywhere (no auto-poll) so
the UI doesn't churn while operators are typing.
Usage (platform-internal / dev shell)
Web component (drop-in HTML)
<script type="module">
import { connect } from "/sdk/index.js";
import "/console-ui/index.js"; // side-effect: defines <s3p-server-ui>
const app = await connect();
const el = document.querySelector("s3p-server-ui");
el.platform = app; // pass the configured SDK client
el.project = app.project;
</script>
<s3p-server-ui></s3p-server-ui>Programmatic mount
import { mountServerUi } from "@s3p/console-ui";
const unmount = mountServerUi(document.getElementById("console-root"), {
platform: app, // anything that exposes getS3Client()
defaultBucket: app.bucket,
defaultPrefix: "s3db/",
project: app.project,
});
// later
unmount();Host shape
interface ServerUiHost {
getS3Client(): Promise<S3Client>;
getClaims?: () => { sub?, role?, preferred_username? } | null;
users?: UsersFacade; // enables the App-users panel
operators?: OperatorsFacade; // enables the Admins panel
roleAdmin?: RolesFacade; // enables the Roles panel
}The PlatformClient returned by @s3p/sdk matches this
shape; any equivalent object works.
Dev loop
From the workspace root:
npm run build --workspace=@s3p/console-ui
npm test --workspace=@s3p/console-ui
npm run typecheck --workspace=@s3p/console-ui
npm run lint --workspace=@s3p/console-uiTests
Vitest covers:
- Database panel classifier (collection / log / doc detection from storage layout, s3db scope + private-owner attribution, per-scope grouping, and the scope-aware access analysis).
