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
··· 9 "serve": "vite preview" 10 }, 11 "devDependencies": { 12 - "@iconify-json/lucide": "^1.2.74", 13 "@iconify/tailwind4": "^1.1.0", 14 "@tailwindcss/vite": "^4.1.17", 15 "prettier": "^3.6.2",
··· 9 "serve": "vite preview" 10 }, 11 "devDependencies": { 12 + "@iconify-json/lucide": "^1.2.75", 13 "@iconify/tailwind4": "^1.1.0", 14 "@tailwindcss/vite": "^4.1.17", 15 "prettier": "^3.6.2",
+13 -13
pnpm-lock.yaml
··· 94 version: 1.9.10 95 devDependencies: 96 '@iconify-json/lucide': 97 - specifier: ^1.2.74 98 - version: 1.2.74 99 '@iconify/tailwind4': 100 specifier: ^1.1.0 101 version: 1.1.0(tailwindcss@4.1.17) ··· 634 '@codemirror/view': ^6.0.0 635 '@lezer/highlight': ^1.0.0 636 637 - '@iconify-json/lucide@1.2.74': 638 - resolution: {integrity: sha512-vDoGHcDZdWgUbt9J3TCJlxFzX/Mw0vUIAoZdkfI2mINOi1/cgVZHivgZ8QtiGlepskTL3PcG8t93Ky/vtQgXGA==} 639 640 '@iconify/tailwind4@1.1.0': 641 resolution: {integrity: sha512-HqgAYtYk4eFtLvdYfhQrBRT9ohToh+VJJVhHtJ7B4Qhw+J+mRPvGC9Wr6Cgtb36YbIWqBxWuBaAUw9TE/8m2/w==} ··· 957 solid-js: 958 optional: true 959 960 - baseline-browser-mapping@2.8.30: 961 - resolution: {integrity: sha512-aTUKW4ptQhS64+v2d6IkPzymEzzhw+G0bA1g3uBRV3+ntkH+svttKseW5IOR4Ed6NUVKqnY7qT3dKvzQ7io4AA==} 962 hasBin: true 963 964 boolbase@1.0.0: ··· 976 resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} 977 engines: {node: '>= 0.4'} 978 979 - caniuse-lite@1.0.30001756: 980 - resolution: {integrity: sha512-4HnCNKbMLkLdhJz3TToeVWHSnfJvPaq6vu/eRP0Ahub/07n484XHhBF5AJoSGHdVrS8tKFauUQz8Bp9P7LVx7A==} 981 982 cheerio-select@2.1.0: 983 resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} ··· 2170 '@codemirror/view': 6.38.8 2171 '@lezer/highlight': 1.2.3 2172 2173 - '@iconify-json/lucide@1.2.74': 2174 dependencies: 2175 '@iconify/types': 2.0.0 2176 ··· 2474 optionalDependencies: 2475 solid-js: 1.9.10 2476 2477 - baseline-browser-mapping@2.8.30: {} 2478 2479 boolbase@1.0.0: {} 2480 2481 browserslist@4.28.0: 2482 dependencies: 2483 - baseline-browser-mapping: 2.8.30 2484 - caniuse-lite: 1.0.30001756 2485 electron-to-chromium: 1.5.259 2486 node-releases: 2.0.27 2487 update-browserslist-db: 1.1.4(browserslist@4.28.0) ··· 2493 es-errors: 1.3.0 2494 function-bind: 1.1.2 2495 2496 - caniuse-lite@1.0.30001756: {} 2497 2498 cheerio-select@2.1.0: 2499 dependencies:
··· 94 version: 1.9.10 95 devDependencies: 96 '@iconify-json/lucide': 97 + specifier: ^1.2.75 98 + version: 1.2.75 99 '@iconify/tailwind4': 100 specifier: ^1.1.0 101 version: 1.1.0(tailwindcss@4.1.17) ··· 634 '@codemirror/view': ^6.0.0 635 '@lezer/highlight': ^1.0.0 636 637 + '@iconify-json/lucide@1.2.75': 638 + resolution: {integrity: sha512-sWBN0t/rTo1FxWG/46xKgkIcDerHpsjyNgMH48nvtC4/kUG88sFQXI+7mxX3SD8eSUaQQ2kS9C7ZKWm2DKgBlw==} 639 640 '@iconify/tailwind4@1.1.0': 641 resolution: {integrity: sha512-HqgAYtYk4eFtLvdYfhQrBRT9ohToh+VJJVhHtJ7B4Qhw+J+mRPvGC9Wr6Cgtb36YbIWqBxWuBaAUw9TE/8m2/w==} ··· 957 solid-js: 958 optional: true 959 960 + baseline-browser-mapping@2.8.31: 961 + resolution: {integrity: sha512-a28v2eWrrRWPpJSzxc+mKwm0ZtVx/G8SepdQZDArnXYU/XS+IF6mp8aB/4E+hH1tyGCoDo3KlUCdlSxGDsRkAw==} 962 hasBin: true 963 964 boolbase@1.0.0: ··· 976 resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} 977 engines: {node: '>= 0.4'} 978 979 + caniuse-lite@1.0.30001757: 980 + resolution: {integrity: sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ==} 981 982 cheerio-select@2.1.0: 983 resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} ··· 2170 '@codemirror/view': 6.38.8 2171 '@lezer/highlight': 1.2.3 2172 2173 + '@iconify-json/lucide@1.2.75': 2174 dependencies: 2175 '@iconify/types': 2.0.0 2176 ··· 2474 optionalDependencies: 2475 solid-js: 1.9.10 2476 2477 + baseline-browser-mapping@2.8.31: {} 2478 2479 boolbase@1.0.0: {} 2480 2481 browserslist@4.28.0: 2482 dependencies: 2483 + baseline-browser-mapping: 2.8.31 2484 + caniuse-lite: 1.0.30001757 2485 electron-to-chromium: 1.5.259 2486 node-releases: 2.0.27 2487 update-browserslist-db: 1.1.4(browserslist@4.28.0) ··· 2493 es-errors: 1.3.0 2494 function-bind: 1.1.2 2495 2496 + caniuse-lite@1.0.30001757: {} 2497 2498 cheerio-select@2.1.0: 2499 dependencies:
+19 -4
src/views/record.tsx
··· 59 } 60 61 const didDocument = await didDocPromise; 62 - 63 const pdsEndpoint = getPdsEndpoint(didDocument); 64 65 if (!pdsEndpoint) { ··· 199 const [validSchema, setValidSchema] = createSignal<boolean | undefined>(undefined); 200 const [schema, setSchema] = createSignal<ResolvedSchema>(); 201 const [lexiconNotFound, setLexiconNotFound] = createSignal<boolean>(); 202 const did = params.repo; 203 let rpc: Client; 204 ··· 250 251 const validateRemoteSchema = async (record: Record<string, unknown>) => { 252 try { 253 const { resolved, failed } = await resolveAllLexicons(params.collection as Nsid); 254 255 if (failed.size > 0) { ··· 274 setValidSchema(false); 275 setValidationError(err.message || String(err)); 276 } 277 }; 278 279 const verifyRecordIntegrity = async () => { ··· 518 ></span> 519 </div> 520 <Show when={validRecord() === false}> 521 - <div class="wrap-break-word">{verifyError()}</div> 522 </Show> 523 </div> 524 <div> ··· 530 "iconify lucide--check text-green-500 dark:text-green-400": 531 validSchema() === true, 532 "iconify lucide--x text-red-500 dark:text-red-400": validSchema() === false, 533 - "iconify lucide--loader-circle animate-spin": validSchema() === undefined, 534 }} 535 ></span> 536 </div> 537 <Show when={validSchema() === false}> 538 - <div class="wrap-break-word">{validationError()}</div> 539 </Show> 540 </div> 541 <Show when={lexiconUri()}>
··· 59 } 60 61 const didDocument = await didDocPromise; 62 const pdsEndpoint = getPdsEndpoint(didDocument); 63 64 if (!pdsEndpoint) { ··· 198 const [validSchema, setValidSchema] = createSignal<boolean | undefined>(undefined); 199 const [schema, setSchema] = createSignal<ResolvedSchema>(); 200 const [lexiconNotFound, setLexiconNotFound] = createSignal<boolean>(); 201 + const [remoteValidation, setRemoteValidation] = createSignal<boolean>(); 202 const did = params.repo; 203 let rpc: Client; 204 ··· 250 251 const validateRemoteSchema = async (record: Record<string, unknown>) => { 252 try { 253 + setRemoteValidation(true); 254 const { resolved, failed } = await resolveAllLexicons(params.collection as Nsid); 255 256 if (failed.size > 0) { ··· 275 setValidSchema(false); 276 setValidationError(err.message || String(err)); 277 } 278 + setRemoteValidation(false); 279 }; 280 281 const verifyRecordIntegrity = async () => { ··· 520 ></span> 521 </div> 522 <Show when={validRecord() === false}> 523 + <div class="text-xs wrap-break-word">{verifyError()}</div> 524 </Show> 525 </div> 526 <div> ··· 532 "iconify lucide--check text-green-500 dark:text-green-400": 533 validSchema() === true, 534 "iconify lucide--x text-red-500 dark:text-red-400": validSchema() === false, 535 + "iconify lucide--loader-circle animate-spin": 536 + validSchema() === undefined && remoteValidation(), 537 }} 538 ></span> 539 </div> 540 <Show when={validSchema() === false}> 541 + <div class="text-xs wrap-break-word">{validationError()}</div> 542 + </Show> 543 + <Show 544 + when={ 545 + !remoteValidation() && 546 + validSchema() === undefined && 547 + params.collection && 548 + !(params.collection in lexicons) 549 + } 550 + > 551 + <Button onClick={() => validateRemoteSchema(record()!.value)}> 552 + Validate remotely 553 + </Button> 554 </Show> 555 </div> 556 <Show when={lexiconUri()}>