atproto explorer pdsls.dev
atproto tool

local validation

juli.ee 80b949a4 56735887

verified
Changed files
+38 -37
src
views
+38 -37
src/views/record.tsx
···
import { AtprotoDid, Did, isNsid } from "@atcute/lexicons/syntax";
import { verifyRecord } from "@atcute/repo";
import { A, useLocation, useNavigate, useParams } from "@solidjs/router";
-
import {
-
createEffect,
-
createResource,
-
createSignal,
-
ErrorBoundary,
-
Show,
-
Suspense,
-
} from "solid-js";
+
import { createResource, createSignal, ErrorBoundary, Show, Suspense } from "solid-js";
import { Backlinks } from "../components/backlinks.jsx";
import { Button } from "../components/button.jsx";
import { RecordEditor, setPlaceholder } from "../components/create.jsx";
···
setPlaceholder(res.data.value);
setExternalLink(checkUri(res.data.uri, res.data.value));
resolveLexicon(params.collection as Nsid);
+
verifyRecordIntegrity();
+
validateLocalSchema(res.data.value);
return res.data;
};
const [record, { refetch }] = createResource(fetchRecord);
-
const validateSchema = async (record: Record<string, unknown>) => {
+
const validateLocalSchema = async (record: Record<string, unknown>) => {
try {
if (params.collection === "com.atproto.lexicon.schema") {
setLexiconNotFound(false);
···
} else if (params.collection && params.collection in lexicons) {
if (is(lexicons[params.collection], record)) setValidSchema(true);
else setValidSchema(false);
-
} else {
-
const { resolved, failed } = await resolveAllLexicons(params.collection as Nsid);
+
}
+
} catch (err: any) {
+
console.error("Schema validation error:", err);
+
setValidSchema(false);
+
setValidationError(err.message || String(err));
+
}
+
};
-
if (failed.size > 0) {
-
console.error(`Failed to resolve ${failed.size} documents:`, Array.from(failed));
-
setValidSchema(false);
-
setValidationError(
-
`Unable to resolve lexicon documents: ${Array.from(failed).join(", ")}`,
-
);
-
return;
-
}
+
const validateRemoteSchema = async (record: Record<string, unknown>) => {
+
try {
+
const { resolved, failed } = await resolveAllLexicons(params.collection as Nsid);
-
const lexiconDocs = Object.fromEntries(resolved);
-
console.log(lexiconDocs);
+
if (failed.size > 0) {
+
console.error(`Failed to resolve ${failed.size} documents:`, Array.from(failed));
+
setValidSchema(false);
+
setValidationError(`Unable to resolve lexicon documents: ${Array.from(failed).join(", ")}`);
+
return;
+
}
-
const validator = new RecordValidator(lexiconDocs, params.collection as Nsid);
-
validator.parse({
-
key: params.rkey ?? null,
-
object: record,
-
});
+
const lexiconDocs = Object.fromEntries(resolved);
+
console.log(lexiconDocs);
+
+
const validator = new RecordValidator(lexiconDocs, params.collection as Nsid);
+
validator.parse({
+
key: params.rkey ?? null,
+
object: record,
+
});
-
setValidSchema(true);
-
}
+
setValidSchema(true);
} catch (err: any) {
console.error("Schema validation error:", err);
setValidSchema(false);
···
}
};
-
createEffect(() => {
-
if (location.hash === "#info" && record()) {
-
if (validSchema() === undefined) validateSchema(record()!.value);
-
if (validRecord() === undefined) verifyRecordIntegrity();
-
}
-
});
-
const resolveLexicon = async (nsid: Nsid) => {
try {
const authority = await resolveLexiconAuthority(nsid);
···
return template(parsedUri, record);
};
-
const RecordTab = (props: { tab: "record" | "backlinks" | "info" | "schema"; label: string }) => {
+
const RecordTab = (props: {
+
tab: "record" | "backlinks" | "info" | "schema";
+
label: string;
+
error?: boolean;
+
}) => {
const isActive = () => {
if (!location.hash && props.tab === "record") return true;
if (location.hash === `#${props.tab}`) return true;
···
>
{props.label}
</A>
+
<Show when={props.error && (validRecord() === false || validSchema() === false)}>
+
<span class="iconify lucide--x text-red-500 dark:text-red-400"></span>
+
</Show>
</div>
);
};
···
<RecordTab tab="record" label="Record" />
<RecordTab tab="schema" label="Schema" />
<RecordTab tab="backlinks" label="Backlinks" />
-
<RecordTab tab="info" label="Info" />
+
<RecordTab tab="info" label="Info" error />
</div>
<div class="flex gap-0.5">
<Show when={agent() && agent()?.sub === record()?.uri.split("/")[2]}>