runtime validation #16

merged
opened by juli.ee targeting main from runtime-validation

not a very elegant solution but works "okay"

Changed files
+33 -18
src
views
+1 -1
package.json
···
"serve": "vite preview"
},
"devDependencies": {
-
"@iconify-json/lucide": "^1.2.74",
"@iconify/tailwind4": "^1.1.0",
"@tailwindcss/vite": "^4.1.17",
"prettier": "^3.6.2",
···
"serve": "vite preview"
},
"devDependencies": {
+
"@iconify-json/lucide": "^1.2.75",
"@iconify/tailwind4": "^1.1.0",
"@tailwindcss/vite": "^4.1.17",
"prettier": "^3.6.2",
+13 -13
pnpm-lock.yaml
···
version: 1.9.10
devDependencies:
'@iconify-json/lucide':
-
specifier: ^1.2.74
-
version: 1.2.74
'@iconify/tailwind4':
specifier: ^1.1.0
version: 1.1.0(tailwindcss@4.1.17)
···
'@codemirror/view': ^6.0.0
'@lezer/highlight': ^1.0.0
-
'@iconify-json/lucide@1.2.74':
-
resolution: {integrity: sha512-vDoGHcDZdWgUbt9J3TCJlxFzX/Mw0vUIAoZdkfI2mINOi1/cgVZHivgZ8QtiGlepskTL3PcG8t93Ky/vtQgXGA==}
'@iconify/tailwind4@1.1.0':
resolution: {integrity: sha512-HqgAYtYk4eFtLvdYfhQrBRT9ohToh+VJJVhHtJ7B4Qhw+J+mRPvGC9Wr6Cgtb36YbIWqBxWuBaAUw9TE/8m2/w==}
···
solid-js:
optional: true
-
baseline-browser-mapping@2.8.30:
-
resolution: {integrity: sha512-aTUKW4ptQhS64+v2d6IkPzymEzzhw+G0bA1g3uBRV3+ntkH+svttKseW5IOR4Ed6NUVKqnY7qT3dKvzQ7io4AA==}
hasBin: true
boolbase@1.0.0:
···
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
engines: {node: '>= 0.4'}
-
caniuse-lite@1.0.30001756:
-
resolution: {integrity: sha512-4HnCNKbMLkLdhJz3TToeVWHSnfJvPaq6vu/eRP0Ahub/07n484XHhBF5AJoSGHdVrS8tKFauUQz8Bp9P7LVx7A==}
cheerio-select@2.1.0:
resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==}
···
'@codemirror/view': 6.38.8
'@lezer/highlight': 1.2.3
-
'@iconify-json/lucide@1.2.74':
dependencies:
'@iconify/types': 2.0.0
···
optionalDependencies:
solid-js: 1.9.10
-
baseline-browser-mapping@2.8.30: {}
boolbase@1.0.0: {}
browserslist@4.28.0:
dependencies:
-
baseline-browser-mapping: 2.8.30
-
caniuse-lite: 1.0.30001756
electron-to-chromium: 1.5.259
node-releases: 2.0.27
update-browserslist-db: 1.1.4(browserslist@4.28.0)
···
es-errors: 1.3.0
function-bind: 1.1.2
-
caniuse-lite@1.0.30001756: {}
cheerio-select@2.1.0:
dependencies:
···
version: 1.9.10
devDependencies:
'@iconify-json/lucide':
+
specifier: ^1.2.75
+
version: 1.2.75
'@iconify/tailwind4':
specifier: ^1.1.0
version: 1.1.0(tailwindcss@4.1.17)
···
'@codemirror/view': ^6.0.0
'@lezer/highlight': ^1.0.0
+
'@iconify-json/lucide@1.2.75':
+
resolution: {integrity: sha512-sWBN0t/rTo1FxWG/46xKgkIcDerHpsjyNgMH48nvtC4/kUG88sFQXI+7mxX3SD8eSUaQQ2kS9C7ZKWm2DKgBlw==}
'@iconify/tailwind4@1.1.0':
resolution: {integrity: sha512-HqgAYtYk4eFtLvdYfhQrBRT9ohToh+VJJVhHtJ7B4Qhw+J+mRPvGC9Wr6Cgtb36YbIWqBxWuBaAUw9TE/8m2/w==}
···
solid-js:
optional: true
+
baseline-browser-mapping@2.8.31:
+
resolution: {integrity: sha512-a28v2eWrrRWPpJSzxc+mKwm0ZtVx/G8SepdQZDArnXYU/XS+IF6mp8aB/4E+hH1tyGCoDo3KlUCdlSxGDsRkAw==}
hasBin: true
boolbase@1.0.0:
···
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
engines: {node: '>= 0.4'}
+
caniuse-lite@1.0.30001757:
+
resolution: {integrity: sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ==}
cheerio-select@2.1.0:
resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==}
···
'@codemirror/view': 6.38.8
'@lezer/highlight': 1.2.3
+
'@iconify-json/lucide@1.2.75':
dependencies:
'@iconify/types': 2.0.0
···
optionalDependencies:
solid-js: 1.9.10
+
baseline-browser-mapping@2.8.31: {}
boolbase@1.0.0: {}
browserslist@4.28.0:
dependencies:
+
baseline-browser-mapping: 2.8.31
+
caniuse-lite: 1.0.30001757
electron-to-chromium: 1.5.259
node-releases: 2.0.27
update-browserslist-db: 1.1.4(browserslist@4.28.0)
···
es-errors: 1.3.0
function-bind: 1.1.2
+
caniuse-lite@1.0.30001757: {}
cheerio-select@2.1.0:
dependencies:
+19 -4
src/views/record.tsx
···
}
const didDocument = await didDocPromise;
-
const pdsEndpoint = getPdsEndpoint(didDocument);
if (!pdsEndpoint) {
···
const [validSchema, setValidSchema] = createSignal<boolean | undefined>(undefined);
const [schema, setSchema] = createSignal<ResolvedSchema>();
const [lexiconNotFound, setLexiconNotFound] = createSignal<boolean>();
const did = params.repo;
let rpc: Client;
···
const validateRemoteSchema = async (record: Record<string, unknown>) => {
try {
const { resolved, failed } = await resolveAllLexicons(params.collection as Nsid);
if (failed.size > 0) {
···
setValidSchema(false);
setValidationError(err.message || String(err));
}
};
const verifyRecordIntegrity = async () => {
···
></span>
</div>
<Show when={validRecord() === false}>
-
<div class="wrap-break-word">{verifyError()}</div>
</Show>
</div>
<div>
···
"iconify lucide--check text-green-500 dark:text-green-400":
validSchema() === true,
"iconify lucide--x text-red-500 dark:text-red-400": validSchema() === false,
-
"iconify lucide--loader-circle animate-spin": validSchema() === undefined,
}}
></span>
</div>
<Show when={validSchema() === false}>
-
<div class="wrap-break-word">{validationError()}</div>
</Show>
</div>
<Show when={lexiconUri()}>
···
}
const didDocument = await didDocPromise;
const pdsEndpoint = getPdsEndpoint(didDocument);
if (!pdsEndpoint) {
···
const [validSchema, setValidSchema] = createSignal<boolean | undefined>(undefined);
const [schema, setSchema] = createSignal<ResolvedSchema>();
const [lexiconNotFound, setLexiconNotFound] = createSignal<boolean>();
+
const [remoteValidation, setRemoteValidation] = createSignal<boolean>();
const did = params.repo;
let rpc: Client;
···
const validateRemoteSchema = async (record: Record<string, unknown>) => {
try {
+
setRemoteValidation(true);
const { resolved, failed } = await resolveAllLexicons(params.collection as Nsid);
if (failed.size > 0) {
···
setValidSchema(false);
setValidationError(err.message || String(err));
}
+
setRemoteValidation(false);
};
const verifyRecordIntegrity = async () => {
···
></span>
</div>
<Show when={validRecord() === false}>
+
<div class="text-xs wrap-break-word">{verifyError()}</div>
</Show>
</div>
<div>
···
"iconify lucide--check text-green-500 dark:text-green-400":
validSchema() === true,
"iconify lucide--x text-red-500 dark:text-red-400": validSchema() === false,
+
"iconify lucide--loader-circle animate-spin":
+
validSchema() === undefined && remoteValidation(),
}}
></span>
</div>
<Show when={validSchema() === false}>
+
<div class="text-xs wrap-break-word">{validationError()}</div>
+
</Show>
+
<Show
+
when={
+
!remoteValidation() &&
+
validSchema() === undefined &&
+
params.collection &&
+
!(params.collection in lexicons)
+
}
+
>
+
<Button onClick={() => validateRemoteSchema(record()!.value)}>
+
Validate remotely
+
</Button>
</Show>
</div>
<Show when={lexiconUri()}>