+38
-37
src/views/record.tsx
+38
-37
src/views/record.tsx
···
7
7
import { AtprotoDid, Did, isNsid } from "@atcute/lexicons/syntax";
8
8
import { verifyRecord } from "@atcute/repo";
9
9
import { A, useLocation, useNavigate, useParams } from "@solidjs/router";
10
-
import {
11
-
createEffect,
12
-
createResource,
13
-
createSignal,
14
-
ErrorBoundary,
15
-
Show,
16
-
Suspense,
17
-
} from "solid-js";
10
+
import { createResource, createSignal, ErrorBoundary, Show, Suspense } from "solid-js";
18
11
import { Backlinks } from "../components/backlinks.jsx";
19
12
import { Button } from "../components/button.jsx";
20
13
import { RecordEditor, setPlaceholder } from "../components/create.jsx";
···
230
223
setPlaceholder(res.data.value);
231
224
setExternalLink(checkUri(res.data.uri, res.data.value));
232
225
resolveLexicon(params.collection as Nsid);
226
+
verifyRecordIntegrity();
227
+
validateLocalSchema(res.data.value);
233
228
234
229
return res.data;
235
230
};
236
231
237
232
const [record, { refetch }] = createResource(fetchRecord);
238
233
239
-
const validateSchema = async (record: Record<string, unknown>) => {
234
+
const validateLocalSchema = async (record: Record<string, unknown>) => {
240
235
try {
241
236
if (params.collection === "com.atproto.lexicon.schema") {
242
237
setLexiconNotFound(false);
···
245
240
} else if (params.collection && params.collection in lexicons) {
246
241
if (is(lexicons[params.collection], record)) setValidSchema(true);
247
242
else setValidSchema(false);
248
-
} else {
249
-
const { resolved, failed } = await resolveAllLexicons(params.collection as Nsid);
243
+
}
244
+
} catch (err: any) {
245
+
console.error("Schema validation error:", err);
246
+
setValidSchema(false);
247
+
setValidationError(err.message || String(err));
248
+
}
249
+
};
250
250
251
-
if (failed.size > 0) {
252
-
console.error(`Failed to resolve ${failed.size} documents:`, Array.from(failed));
253
-
setValidSchema(false);
254
-
setValidationError(
255
-
`Unable to resolve lexicon documents: ${Array.from(failed).join(", ")}`,
256
-
);
257
-
return;
258
-
}
251
+
const validateRemoteSchema = async (record: Record<string, unknown>) => {
252
+
try {
253
+
const { resolved, failed } = await resolveAllLexicons(params.collection as Nsid);
259
254
260
-
const lexiconDocs = Object.fromEntries(resolved);
261
-
console.log(lexiconDocs);
255
+
if (failed.size > 0) {
256
+
console.error(`Failed to resolve ${failed.size} documents:`, Array.from(failed));
257
+
setValidSchema(false);
258
+
setValidationError(`Unable to resolve lexicon documents: ${Array.from(failed).join(", ")}`);
259
+
return;
260
+
}
262
261
263
-
const validator = new RecordValidator(lexiconDocs, params.collection as Nsid);
264
-
validator.parse({
265
-
key: params.rkey ?? null,
266
-
object: record,
267
-
});
262
+
const lexiconDocs = Object.fromEntries(resolved);
263
+
console.log(lexiconDocs);
264
+
265
+
const validator = new RecordValidator(lexiconDocs, params.collection as Nsid);
266
+
validator.parse({
267
+
key: params.rkey ?? null,
268
+
object: record,
269
+
});
268
270
269
-
setValidSchema(true);
270
-
}
271
+
setValidSchema(true);
271
272
} catch (err: any) {
272
273
console.error("Schema validation error:", err);
273
274
setValidSchema(false);
···
302
303
}
303
304
};
304
305
305
-
createEffect(() => {
306
-
if (location.hash === "#info" && record()) {
307
-
if (validSchema() === undefined) validateSchema(record()!.value);
308
-
if (validRecord() === undefined) verifyRecordIntegrity();
309
-
}
310
-
});
311
-
312
306
const resolveLexicon = async (nsid: Nsid) => {
313
307
try {
314
308
const authority = await resolveLexiconAuthority(nsid);
···
350
344
return template(parsedUri, record);
351
345
};
352
346
353
-
const RecordTab = (props: { tab: "record" | "backlinks" | "info" | "schema"; label: string }) => {
347
+
const RecordTab = (props: {
348
+
tab: "record" | "backlinks" | "info" | "schema";
349
+
label: string;
350
+
error?: boolean;
351
+
}) => {
354
352
const isActive = () => {
355
353
if (!location.hash && props.tab === "record") return true;
356
354
if (location.hash === `#${props.tab}`) return true;
···
370
368
>
371
369
{props.label}
372
370
</A>
371
+
<Show when={props.error && (validRecord() === false || validSchema() === false)}>
372
+
<span class="iconify lucide--x text-red-500 dark:text-red-400"></span>
373
+
</Show>
373
374
</div>
374
375
);
375
376
};
···
382
383
<RecordTab tab="record" label="Record" />
383
384
<RecordTab tab="schema" label="Schema" />
384
385
<RecordTab tab="backlinks" label="Backlinks" />
385
-
<RecordTab tab="info" label="Info" />
386
+
<RecordTab tab="info" label="Info" error />
386
387
</div>
387
388
<div class="flex gap-0.5">
388
389
<Show when={agent() && agent()?.sub === record()?.uri.split("/")[2]}>