diff --git a/src/admin/mod.rs b/src/admin/mod.rs index d4077ac..fa7722a 100644 --- a/src/admin/mod.rs +++ b/src/admin/mod.rs @@ -63,6 +63,10 @@ pub fn admin_routes(_state: AppState) -> Router { "/network-lexicons", post(network_lexicons::add).get(network_lexicons::list), ) + .route( + "/network-lexicons/resolve/{nsid}", + get(network_lexicons::resolve), + ) .route("/network-lexicons/{nsid}", delete(network_lexicons::remove)) .route( "/script-variables", diff --git a/src/admin/network_lexicons.rs b/src/admin/network_lexicons.rs index cc6f3b3..a0b7fb8 100644 --- a/src/admin/network_lexicons.rs +++ b/src/admin/network_lexicons.rs @@ -20,6 +20,34 @@ async fn notify_collections(state: &AppState) { let _ = state.collections_tx.send(collections); } +/// GET /admin/network-lexicons/resolve/{nsid} — preview-resolve a network lexicon without persisting. +pub(super) async fn resolve( + State(state): State, + auth: UserAuth, + Path(nsid): Path, +) -> Result, AppError> { + auth.require(Permission::LexiconsRead).await?; + + let (authority_did, pds_endpoint) = + resolve_nsid_authority(&state.http, &state.config.plc_url, &nsid).await?; + + let lexicon_json = + fetch_lexicon_from_pds(&state.http, &pds_endpoint, &authority_did, &nsid).await?; + + let main_type = lexicon_json + .get("defs") + .and_then(|d| d.get("main")) + .and_then(|m| m.get("type")) + .and_then(|t| t.as_str()); + + Ok(Json(serde_json::json!({ + "nsid": nsid, + "authority_did": authority_did, + "type": main_type, + "lexicon_json": lexicon_json, + }))) +} + /// POST /admin/network-lexicons — add a network lexicon to watch. pub(super) async fn add( State(state): State, diff --git a/web/src/app/dashboard/lexicons/new/page.tsx b/web/src/app/dashboard/lexicons/new/page.tsx index feb6ccf..26a6886 100644 --- a/web/src/app/dashboard/lexicons/new/page.tsx +++ b/web/src/app/dashboard/lexicons/new/page.tsx @@ -6,9 +6,9 @@ import { Empty, EmptyDescription, EmptyTitle } from "@/components/ui/empty"; import { useCurrentUser } from "@/hooks/use-current-user"; import { addNetworkLexicon, + resolveNetworkLexicon, uploadLexicon, } from "@/lib/api"; -import { resolveNsid } from "@/lib/nsid"; import { LEXICON_TEMPLATE, procedureScript, queryScript } from "@/lib/lua-templates"; import { useLuaCompletions } from "@/hooks/use-lua-completions"; import { CodePanels } from "@/components/code-panels"; @@ -103,17 +103,23 @@ export default function AddLexiconPage() { abortRef.current = controller; setResolving(true); - resolveNsid(nsid, controller.signal) + resolveNetworkLexicon(nsid, controller.signal) .then((result) => { if (!controller.signal.aborted) { - setMainType(result.type); + setMainType(result.type ?? undefined); setNetworkJson( - result.lexiconJson - ? JSON.stringify(result.lexiconJson, null, 2) + result.lexicon_json + ? JSON.stringify(result.lexicon_json, null, 2) : "", ); } }) + .catch(() => { + if (!controller.signal.aborted) { + setMainType(undefined); + setNetworkJson(""); + } + }) .finally(() => { if (!controller.signal.aborted) setResolving(false); }); diff --git a/web/src/lib/api.ts b/web/src/lib/api.ts index f75875b..4e50670 100644 --- a/web/src/lib/api.ts +++ b/web/src/lib/api.ts @@ -142,6 +142,18 @@ export function getNetworkLexicons() { return apiFetch("/admin/network-lexicons"); } +export function resolveNetworkLexicon( + nsid: string, + signal?: AbortSignal, +) { + return apiFetch<{ + nsid: string; + authority_did: string; + type: string | null; + lexicon_json: Record; + }>(`/admin/network-lexicons/resolve/${encodeURIComponent(nsid)}`, { signal }); +} + export function addNetworkLexicon(body: { nsid: string; target_collection?: string;