This commit is contained in:
tree 2023-06-28 10:44:59 +00:00
rodič 60cc6780f6
revize 1b1fb2d8cd
25 změnil soubory, kde provedl 271 přidání a 111 odebrání

Zobrazit soubor

@ -25,7 +25,7 @@ router
item.host = item.url.replace(/^https?:\/\//, "");
item.env = (ats.BSKY_OFFICIAL_PDS.includes(item.url) &&
item.plcs.includes("https://plc.directory"))
? "bsky"
? "bluesky"
: (item.plcs.includes("https://plc.bsky-sandbox.dev")
? "sandbox"
: null);
@ -47,7 +47,7 @@ router
ctx.response.body = out;
perf(ctx);
})
.get("/did", async (ctx) => {
.get("/dids", async (ctx) => {
const out = [];
const query = { $and: [{}] };
let sort = { time: -1 };
@ -115,9 +115,9 @@ router
const did = ctx.params.id;
const item = await ats.db.did.findOne({ did });
item.env = (item.src === "https://plc.directory")
? "bsky"
? "bluesky"
: (item.src === "https://plc.bsky-sandbox.dev")
? "sbox"
? "sandbox"
: null;
ctx.response.body = item;
perf(ctx);
@ -137,7 +137,7 @@ router
item.host = item.url.replace(/^https?:\/\//, "");
item.env = (ats.BSKY_OFFICIAL_PDS.includes(item.url) &&
item.plcs.includes("https://plc.directory"))
? "bsky"
? "bluesky"
: (item.plcs.includes("https://plc.bsky-sandbox.dev") ? "sandbox" : null);
ctx.response.body = item;
perf(ctx);

Zobrazit soubor

@ -1,6 +1,6 @@
{
"name": "atscan-fe",
"version": "0.3.5-alpha",
"version": "0.4.0-alpha",
"private": true,
"scripts": {
"dev": "vite dev",

Zobrazit soubor

@ -6,10 +6,8 @@
export let data;
function tableMap({ val, key, row }) {
if (key === 'world') {
}
if (key === 'srcHost') {
val = `<a href="/did?q=plc:${val}" class="anchor">${val}</a>`;
val = `<a href="/dids?q=plc:${val}" class="anchor">${val}</a>`;
}
if (key === 'pds') {
const host = (val = val
@ -21,7 +19,8 @@
}
if (key === 'did') {
const did = val;
const plc = data.plc.find((i) => i.url === row.src);
const fedId = row.src === 'https://plc.directory' ? 'bluesky' : 'sandbox';
const fed = data.ecosystem.data.federations.find((f) => f.id === fedId);
val = `<div class="flex gap-6">`;
val += ` <div>`;
val += ` <div class="text-lg inline-block"><a href="/${did}" class=""><span class="opacity-50">did:plc:</span><span class="font-semibold opacity-100">${did.replace(
@ -32,7 +31,7 @@
.filter((h) => !h.match(/at:\/\/data:x\//))
.map((h) => h.replace(/^at:\/\//, ''));
val += ` <div class="mt-1.5">`;
val += ` <span class="mr-2 badge text-xs variant-filled ${plc.color} dark:${plc.color} opacity-70 text-white dark:text-black">${plc.name}</span>`;
val += ` <span class="mr-2 badge text-xs variant-filled bg-ats-fed-${fed.id} dark:bg-ats-fed-${fed.id} opacity-70 text-white dark:text-black">${fed.id}</span>`;
val += ` <span>${handles
.map(
(h) => `<a href="https://bsky.app/profile/${h}" target="_blank" class="anchor">@${h}</a>`

Zobrazit soubor

@ -9,7 +9,7 @@
if (key === 'plcs' && val) {
val = val
.map((i) => i.replace(/^https?:\/\//, ''))
.map((p) => `<a href="/did?q=plc:${p}" class="anchor">${p}</a>`)
.map((p) => `<a href="/dids?q=plc:${p}" class="anchor">${p}</a>`)
.join(', ');
if (row.inspect?.current.data?.availableUserDomains) {
val += '<br/>(' + row.inspect?.current.data?.availableUserDomains.join(', ') + ')';
@ -17,15 +17,10 @@
}
if (key === 'env') {
let arr = [];
const plc =
val === 'sandbox'
? data.plc.find((i) => i.code === 'sbox')
: val === 'bsky'
? data.plc.find((i) => i.code === 'bsky')
: null;
if (plc) {
const fed = data.ecosystem.data.federations.find((f) => f.id === val);
if (fed) {
arr.push(
`<span class="badge variant-filled ${plc.color} dark:${plc.color} opacity-70 text-white dark:text-black">${plc.name}</span>`
`<span class="badge variant-filled bg-ats-fed-${fed.id} dark:bg-ats-fed-${fed.id} opacity-70 text-white dark:text-black">${fed.id}</span>`
);
}
val = arr.reverse().join(' ');
@ -65,7 +60,7 @@
}
}
if (key === 'didsCount') {
val = `<a href="/did?q=pds:${row.host}" class="anchor">${formatNumber(val)}</a>`;
val = `<a href="/dids?q=pds:${row.host}" class="anchor">${formatNumber(val)}</a>`;
}
if (key === 'lastOnline' && row.inspect) {
val = `<span class="text-xs">${

Zobrazit soubor

@ -6,7 +6,9 @@
const models = {
pds: { url: `${data.config.api}/pds/%`, key: 'host' },
did: { url: `${data.config.api}/%`, key: 'did' }
did: { url: `${data.config.api}/%`, key: 'did' },
client: { url: `${data.config.api}/client/%`, key: 'id' },
fed: { url: `${data.config.api}/fed/%`, key: 'id' }
};
const config = models[model];
const url = config.url.replace('%', data.item[config.key]);

Zobrazit soubor

@ -45,7 +45,10 @@
/** @event {rowMetaData} selected - Fires when a table row is clicked. */
dispatch('selected', rowMetaData);
}
if (event.target.className !== 'anchor') {
if (
event.target.className !== 'anchor' &&
!event.target.parentElement.className.includes('anchor')
) {
event.preventDefault();
const rowMetaData = source.meta ? source.meta[rowIndex] : source.body[rowIndex];
const url = rowMetaData[1];

Zobrazit soubor

@ -4,7 +4,6 @@ import * as _ from 'lodash';
import { env } from '$env/dynamic/private';
export async function load({ fetch }) {
const config = {
name: 'ATScan',
domain: 'atscan.net',
@ -12,13 +11,18 @@ export async function load({ fetch }) {
web: 'https://atscan.net',
git: 'https://github.com/atscan/atscan',
status: 'https://status.gwei.cz/status/atscan',
ecosystem: 'https://ecosystem.atscan.net/index.json'
};
const ecosystemRes = await fetch(config.ecosystem);
const ecosystem = ecosystemRes ? await ecosystemRes.json() : null;
const res = await fetch(`${config.api}/plc`);
const plc = _.orderBy(await res.json(), ['code'], ['asc']);
return {
config,
ecosystem,
pkg,
plc,
config
plc
};
}

Zobrazit soubor

@ -56,9 +56,9 @@
<div class="lg:ml-8 flex gap-1">
<div class="relative hidden lg:block">
<a
href="/did"
href="/dids"
class="btn hover:variant-soft-primary"
class:bg-primary-active-token={$page.url.pathname.startsWith('/did')}
class:bg-primary-active-token={$page.url.pathname.startsWith('/dids')}
><span>DIDs</span></a
>
</div>
@ -72,17 +72,18 @@
</div>
<div class="relative hidden lg:block">
<a
href="/plc"
href="/feds"
class="btn hover:variant-soft-primary"
class:bg-primary-active-token={$page.url.pathname === '/plc'}
><span>PLC Directories</span></a
class:bg-primary-active-token={$page.url.pathname === '/feds'}
><span>Federations</span></a
>
</div>
<div class="relative hidden lg:block">
<a
href="/api"
href="/clients"
class="btn hover:variant-soft-primary"
class:bg-primary-active-token={$page.url.pathname === '/api'}><span>API</span></a
class:bg-primary-active-token={$page.url.pathname === '/clients'}
><span>Clients</span></a
>
</div>
</div>
@ -106,6 +107,13 @@
Twitter
</a>
-->
<div class="relative hidden lg:block">
<a
href="/api"
class="btn hover:variant-soft-primary"
class:bg-primary-active-token={$page.url.pathname === '/api'}><span>API</span></a
>
</div>
<div class="text-sm opacity-50">v{data.pkg.version}</div>
<a
class="btn btn-sm variant-ghost-surface hover:variant-soft-primary external"

Zobrazit soubor

@ -2,5 +2,5 @@ import { redirect } from '@sveltejs/kit';
export function load() {
// ...
throw redirect(302, '/did');
throw redirect(302, '/dids');
}

Zobrazit soubor

@ -1,5 +1,5 @@
<script>
/** dark:bg-ats-bsky dark:bg-ats-sbox */
/** dark:bg-ats-fed-bluesky dark:bg-ats-fed-sandbox */
</script>
<div class="w-full h-full bg-ats-bsky" />

Zobrazit soubor

@ -8,14 +8,16 @@
const sourceData = [
{
path: '/did',
path: '/dids',
desc: 'Get all DIDs',
example: ['/did', '/did?q=pds:bsky.social', '/did?q=.cz$']
example: ['/dids', '/dids?q=pds:bsky.social', '/dids?q=.cz$']
},
{ path: '/[did]', desc: 'Get DID item', example: ['/did:plc:524tuhdhh3m7li5gycdn6boe'] },
{ path: '/pds', desc: 'Get all PDS Instances', example: ['/pds', '/pds?q=gwei.cz'] },
{ path: '/pds/[id]', desc: 'Get PDS item', example: ['/pds/bsky.social'] },
{ path: '/plc', desc: 'Get all PLC Directories', example: ['/plc'] }
{ path: '/plc', desc: 'Get all PLC Directories', example: ['/plc'] },
{ path: '/feds', desc: 'Get all Federations', example: ['/feds'] },
{ path: '/clients', desc: 'Get all Clients', example: ['/clients'] }
];
$: tableSimple = {
@ -69,12 +71,12 @@
<h3 class="h3">Mirrored paths (web & api)</h3>
<p>
Most endpoints mirror the web interface path, so for example the <a
href="{data.config.api}/did?q=pds:test-pds.gwei.cz"
class="code">{data.config.api}/did?q=pds:test-pds.gwei.cz</a
href="{data.config.web}/dids?q=pds:test-pds.gwei.cz"
class="code">{data.config.web}/dids?q=pds:test-pds.gwei.cz</a
>
page will list all DIDs on this PDS and the
<a href="{data.config.api}/did?q=pds:test-pds.gwei.cz" class="code"
>{data.config.api}/did?q=pds:test-pds.gwei.cz</a
<a href="{data.config.api}/dids?q=pds:test-pds.gwei.cz" class="code"
>{data.config.api}/dids?q=pds:test-pds.gwei.cz</a
> page will return the same as JSON.
</p>
@ -82,7 +84,7 @@
<Table source={tableSimple} />
<!--CodeBlock code={`http -F {data.config.api}/did
<!--CodeBlock code={`http -F {data.config.api}/dids
> HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Alt-Svc: h3=":443"; ma=2592000

Zobrazit soubor

@ -0,0 +1,13 @@
import { error } from '@sveltejs/kit';
export async function load({ params, fetch, parent }) {
const data = await parent();
const item = data.ecosystem.data.clients.find((c) => c.id === params.id);
if (!item) {
throw error(404, { message: 'Not found' });
}
return {
item
};
}

Zobrazit soubor

@ -0,0 +1,20 @@
<script>
import Breadcrumb from '$lib/components/Breadcrumb.svelte';
import SourceSection from '$lib/components/SourceSection.svelte';
export let data;
const item = data.item;
</script>
<svelte:head>
<title>{item.name} | {data.config.name}</title>
</svelte:head>
<div class="container mx-auto p-8 space-y-8">
<Breadcrumb data={[{ label: 'Clients', link: '/clients' }]} />
<h1 class="h1">{item.name}</h1>
<SourceSection {data} model="client" />
</div>

Zobrazit soubor

@ -0,0 +1,74 @@
<script>
import { customTableMapper } from '$lib/utils.js';
import Table from '$lib/components/Table.svelte';
export let data;
const platformMap = {
ios: { title: 'iOS' },
android: { title: 'Android' },
macos: { title: 'macOS' },
web: { title: 'Web' },
cli: { title: 'CLI' }
};
const langMap = {
js: { title: 'JavaScript' },
kotlin: { title: 'Kotlin' },
go: { title: 'Go' }
};
function tableMap({ val, key, row }) {
if (key === 'name') {
val = `<span class="text-lg font-semibold">${val}</span>`;
}
if (key === 'platforms') {
val = [...new Set(row.apps.map((a) => platformMap[a.platform]?.title || a.platform))].join(
', '
);
val +=
'<br /><span class="text-xs">' +
[...new Set(row.apps.map((a) => langMap[a.language]?.title || a.language))].join(', ') +
'</span>';
}
if (key === 'links') {
val = row.links?.git
? `<a href="${row.links.git}" class="anchor text-lg" target="_blank"><i class="fa-brands fa-github"></i></a>`
: '';
}
if (key === 'authors') {
val = val
.map((p) => `<a href="${p.links?.bsky}" class="anchor" target="_blank">${p.name}</a>`)
.join(', ');
}
if (key === 'popularity') {
val =
'<i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-regular fa-star"></i>';
}
if (key === 'url_raw') {
val = `/client/${row.id}`;
}
return val;
}
const tableSimple = {
// A list of heading labels.
head: ['Name', 'Platforms', 'Authors', 'Links', 'Popularity'],
body: customTableMapper(
data.ecosystem.data.clients,
['name', 'platforms', 'authors', 'links', 'popularity'],
tableMap
),
meta: customTableMapper(data.ecosystem.data.clients, ['id', 'url_raw'], tableMap)
};
</script>
<svelte:head>
<title>Clients | {data.config.name}</title>
</svelte:head>
<div class="container mx-auto p-8 space-y-8">
<h1 class="h1">Clients</h1>
<Table source={tableSimple} />
</div>

Zobrazit soubor

@ -54,12 +54,12 @@
<div class="container mx-auto p-8 space-y-8">
<Breadcrumb
data={[
{ label: 'DIDs', link: '/did' },
{ label: 'DIDs', link: '/dids' },
{
label: `<span class="mr-2 badge ${
item.env ? 'bg-ats-' + item.env : 'bg-gray-500'
item.env ? 'bg-ats-fed-' + item.env : 'bg-gray-500'
} text-white dark:text-black">${item.env}</span> federation`,
link: `/did?q=${item.env}`
link: `/dids?q=${item.env}`
}
]}
/>

Zobrazit soubor

@ -4,7 +4,7 @@ import * as _ from 'lodash';
export async function load({ fetch, url, parent }) {
const { config } = await parent();
let q = url.searchParams.get('q');
const res = await fetch(`${config.api}/did` + (q ? `?q=${q}` : ''), {
const res = await fetch(`${config.api}/dids` + (q ? `?q=${q}` : ''), {
headers: { 'x-ats-wrapped': 'true' }
});
const json = await res.json();

Zobrazit soubor

@ -20,7 +20,7 @@
let periodicUpdate = null;
onMount(() => {
periodicUpdate = setInterval(() => {
invalidate((url) => url.pathname === '/did');
invalidate((url) => url.pathname === '/dids');
}, 60 * 1000);
});
onDestroy(() => {
@ -36,7 +36,7 @@
q = q.replace(/env:sbox/, '');
}
q = q.trim();
const path = '/did' + (q !== '' ? `?q=${q}` : '');
const path = '/dids' + (q !== '' ? `?q=${q}` : '');
const currentPath = $page.url.pathname + $page.url.search;
if (currentPath === path) {
return null;

Zobrazit soubor

@ -0,0 +1,13 @@
import { error } from '@sveltejs/kit';
export async function load({ params, parent }) {
const data = await parent();
const item = data.ecosystem.data.federations.find((c) => c.id === params.id);
if (!item) {
throw error(404, { message: 'Not found' });
}
return {
item
};
}

Zobrazit soubor

@ -0,0 +1,20 @@
<script>
import Breadcrumb from '$lib/components/Breadcrumb.svelte';
import SourceSection from '$lib/components/SourceSection.svelte';
export let data;
const item = data.item;
</script>
<svelte:head>
<title>{item.name} | {data.config.name}</title>
</svelte:head>
<div class="container mx-auto p-8 space-y-8">
<Breadcrumb data={[{ label: 'Federations', link: '/feds' }]} />
<h1 class="h1">{item.name}</h1>
<SourceSection {data} model="fed" />
</div>

Zobrazit soubor

@ -0,0 +1,8 @@
export async function load({ fetch, parent }) {
const { config } = await parent();
const plcRes = await fetch(`${config.api}/plc`);
return {
plc: await plcRes.json()
};
}

Zobrazit soubor

@ -0,0 +1,51 @@
<script>
import Table from '$lib/components/Table.svelte';
import { dataTableHandler, tableMapperValues, tableSourceValues } from '@skeletonlabs/skeleton';
import { dateDistance, formatNumber, customTableMapper } from '$lib/utils.js';
export let data;
function tableMap({ val, key, row }) {
if (key === 'world') {
val = `<span class="badge variant-filled bg-ats-fed-${row.id} dark:bg-ats-fed-${row.id} opacity-70 text-white dark:text-black ucfirst">${row.id}</span>`;
}
if (key === 'name') {
val = `<span class="text-xl font-semibold">${val}</span>`;
}
if (key === 'dids') {
const host = row.plc.replace(/^https?:\/\//, '');
const plc = data.plc?.find((p) => p.host === host) || { didsCount: 0 };
val = `<a href="/dids?q=plc:${host}" class="anchor">${formatNumber(plc.didsCount)}</a>`;
}
if (key === 'plc') {
const host = row.plc.replace(/^https?:\/\//, '');
val = `<a href="/dids?q=plc:${host}" class="anchor">${host}</a>`;
}
if (key === 'lastUpdate') {
const host = row.plc.replace(/^https?:\/\//, '');
const plc = data.plc?.find((p) => p.host === host);
val = plc ? `<span class="text-xs">${dateDistance(plc.lastUpdate)} ago</a>` : '-';
}
if (key === 'url_raw') {
val = `/fed/${row.id}`;
}
return val;
}
const sourceData = data.ecosystem.data.federations;
const tableSimple = {
// A list of heading labels.
head: ['Federation', 'Name', 'DIDs', 'PLC Directory', 'PLC Last mod'],
body: customTableMapper(sourceData, ['world', 'name', 'dids', 'plc', 'lastUpdate'], tableMap),
meta: customTableMapper(sourceData, ['id', 'url_raw'], tableMap)
};
</script>
<svelte:head>
<title>Federations | {data.config.name}</title>
</svelte:head>
<div class="container mx-auto p-8 space-y-8">
<h1 class="h1">Federations</h1>
<Table source={tableSimple} />
</div>

Zobrazit soubor

@ -2,7 +2,7 @@ export async function load({ params, fetch, parent }) {
const { config } = await parent();
const itemResp = await fetch(`${config.api}/pds/${params.host}`);
const didsResp = await fetch(`${config.api}/did?q=pds:${params.host}&limit=10`, {
const didsResp = await fetch(`${config.api}/dids?q=pds:${params.host}&limit=10`, {
headers: { 'x-ats-wrapped': 'true' }
});
return {

Zobrazit soubor

@ -16,7 +16,7 @@
value: item.plcs
.map((p) => {
const host = p.replace(/^https?:\/\//, '');
return `<a href="/plc/${host}" class="anchor">${host}</a>`;
return `<a href="/dids?q=plc:${host}" class="anchor">${host}</a>`;
})
.join(', ')
},
@ -26,7 +26,7 @@
},
{
title: 'DID count',
value: `${formatNumber(item.didsCount)} (<a href="/did?q=pds:${
value: `${formatNumber(item.didsCount)} (<a href="/dids?q=pds:${
item.host
}" class="anchor">list</a>)`
},
@ -90,10 +90,10 @@
{ label: 'PDS Instances', link: '/pds' },
{
label: `<span class="mr-2 badge ${
item.env === 'bsky'
? 'bg-ats-bsky'
item.env === 'bluesky'
? 'bg-ats-fed-bluesky'
: item.env === 'sandbox'
? 'bg-ats-sbox'
? 'bg-ats-fed-sandbox'
: 'bg-gray-500'
} text-white dark:text-black">${item.env}</span> federation`,
link: `/pds?federation=${item.env}`
@ -122,13 +122,13 @@
</div>
<h2 class="h2">
<a href="/did?q=pds:{item.host}">DIDs</a>
<a href="/dids?q=pds:{item.host}">DIDs</a>
<span class="font-normal text-2xl">({formatNumber(data.dids.count)})</span>
</h2>
<DIDTable sourceData={data.dids.items} {data} />
{#if data.dids.count > data.dids.items.length}
<div>
<a href="/did?q=pds:{item.host}"
<a href="/dids?q=pds:{item.host}"
><button class="btn variant-filled"
>Show all {formatNumber(data.dids.count)} DIDs hosted by {item.host}</button
></a

Zobrazit soubor

@ -1,52 +0,0 @@
<script>
import Table from '$lib/components/Table.svelte';
import { dataTableHandler, tableMapperValues, tableSourceValues } from '@skeletonlabs/skeleton';
import { dateDistance, formatNumber } from '$lib/utils.js';
export let data;
function tableMapperValuesLocal(source, keys) {
return tableSourceValues(
source.map((row) => {
const mappedRow = {};
keys.forEach((key) => {
let val = row[key];
if (key === 'world') {
val = `<span class="badge variant-filled ${row.color} dark:${row.color} opacity-70 text-white dark:text-black">${row.name}</span>`;
}
if (key === 'host') {
val = `<span class="text-xl font-semibold">${val}</span>`;
}
if (key === 'code') {
val = `<div class="inline-block font-mono">${val}</div>`;
}
if (key === 'lastUpdate') {
val = dateDistance(val);
}
if (key === 'didsCount') {
val = `<a href="/did?q=plc:${row.host}" class="anchor">${formatNumber(val)}</a>`;
}
return (mappedRow[key] = val);
});
return mappedRow;
})
);
}
const sourceData = data.plc;
const tableSimple = {
// A list of heading labels.
head: ['Federation', 'Host', 'DIDs', 'Last mod'],
body: tableMapperValuesLocal(sourceData, ['world', 'host', 'didsCount', 'lastUpdate']),
meta: tableMapperValues(sourceData, ['position', 'name', 'symbol', 'weight'])
};
</script>
<svelte:head>
<title>PLC Directories | {data.config.name}</title>
</svelte:head>
<div class="container mx-auto p-8 space-y-8">
<h1 class="h1">PLC Directories ({sourceData.length})</h1>
<Table source={tableSimple} />
</div>

Zobrazit soubor

@ -12,8 +12,8 @@ module.exports = {
theme: {
extend: {
colors: {
'ats-bsky': '#3399ff',
'ats-sbox': '#eab308'
'ats-fed-bluesky': '#3399ff',
'ats-fed-sandbox': '#eab308'
}
}
},