Skip to content

Commit

Permalink
dynamic badges
Browse files Browse the repository at this point in the history
  • Loading branch information
ieedan committed Feb 25, 2025
1 parent 644a6e9 commit e43deee
Show file tree
Hide file tree
Showing 19 changed files with 421 additions and 67 deletions.
16 changes: 2 additions & 14 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,7 @@
"bugs": {
"url": "https://github.com/ieedan/jsrepo/issues"
},
"keywords": [
"repo",
"cli",
"svelte",
"vue",
"typescript",
"javascript",
"shadcn",
"registry"
],
"keywords": ["repo", "cli", "svelte", "vue", "typescript", "javascript", "shadcn", "registry"],
"type": "module",
"exports": {
".": {
Expand All @@ -34,10 +25,7 @@
},
"bin": "./dist/index.js",
"main": "./dist/index.js",
"files": [
"./schemas/**/*",
"dist/**/*"
],
"files": ["./schemas/**/*", "dist/**/*"],
"scripts": {
"start": "tsup --silent && node ./dist/index.js",
"build": "tsup",
Expand Down
51 changes: 51 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions sites/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"@types/npm-package-arg": "^6.1.4",
"@upstash/redis": "^1.34.4",
"autoprefixer": "^10.4.20",
"badge-maker": "^4.1.0",
"bits-ui": "1.3.4",
"clsx": "^2.1.1",
"eslint": "^9.21.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
interface Props extends Omit<ButtonProps, 'href'> {
text: string;
icon?: Snippet<[]>;
child?: Snippet<[{ status: UseClipboard['status'] }]>;
animationDuration?: number;
onCopy?: (status: UseClipboard['status']) => void;
}
Expand All @@ -27,6 +28,7 @@
variant = 'ghost',
size = 'icon',
onCopy,
child,
class: className,
...restProps
}: Props = $props();
Expand All @@ -48,7 +50,9 @@
onCopy?.(status);
}}
>
{#if clipboard.status === 'success'}
{#if child}
{@render child({ status: clipboard.status })}
{:else if clipboard.status === 'success'}
<div in:scale={{ duration: animationDuration, start: 0.85 }}>
<Check />
<span class="sr-only">Copied</span>
Expand Down
7 changes: 7 additions & 0 deletions sites/docs/src/lib/components/ui/label/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Root from './label.svelte';

export {
Root,
//
Root as Label
};
19 changes: 19 additions & 0 deletions sites/docs/src/lib/components/ui/label/label.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<script lang="ts">
import { Label as LabelPrimitive } from 'bits-ui';
import { cn } from '$lib/utils.js';
let {
ref = $bindable(null),
class: className,
...restProps
}: LabelPrimitive.RootProps = $props();
</script>

<LabelPrimitive.Root
bind:ref
class={cn(
'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70',
className
)}
{...restProps}
/>
17 changes: 17 additions & 0 deletions sites/docs/src/lib/components/ui/popover/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Popover as PopoverPrimitive } from 'bits-ui';
import Content from './popover-content.svelte';
const Root = PopoverPrimitive.Root;
const Trigger = PopoverPrimitive.Trigger;
const Close = PopoverPrimitive.Close;

export {
Root,
Content,
Trigger,
Close,
//
Root as Popover,
Content as PopoverContent,
Trigger as PopoverTrigger,
Close as PopoverClose
};
28 changes: 28 additions & 0 deletions sites/docs/src/lib/components/ui/popover/popover-content.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<script lang="ts">
import { cn } from '$lib/utils.js';
import { Popover as PopoverPrimitive } from 'bits-ui';
let {
ref = $bindable(null),
class: className,
sideOffset = 4,
align = 'center',
portalProps,
...restProps
}: PopoverPrimitive.ContentProps & {
portalProps?: PopoverPrimitive.PortalProps;
} = $props();
</script>

<PopoverPrimitive.Portal {...portalProps}>
<PopoverPrimitive.Content
bind:ref
{sideOffset}
{align}
class={cn(
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 rounded-md border p-4 shadow-md outline-none',
className
)}
{...restProps}
/>
</PopoverPrimitive.Portal>
2 changes: 1 addition & 1 deletion sites/docs/src/lib/ts/registry/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export const fetchReadme = async (state: RegistryProviderState): Promise<string
}
};

const getProviderToken = (provider: RegistryProvider): string | undefined => {
export const getProviderToken = (provider: RegistryProvider): string | undefined => {
switch (provider.name) {
case github.name:
return GITHUB_TOKEN;
Expand Down
23 changes: 23 additions & 0 deletions sites/docs/src/routes/badges/build/[state]/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { error } from '@sveltejs/kit';

Check failure on line 1 in sites/docs/src/routes/badges/build/[state]/+server.ts

View workflow job for this annotation

GitHub Actions / CI

'error' is defined but never used. Allowed unused vars must match /^_/u
import { makeBadge } from 'badge-maker';

export const GET = async ({ params }) => {
let state = params.state;

if (state.endsWith('.svg')) state = state.slice(0, state.length - 4);

if (!['passing', 'failing'].includes(state));

const svg = makeBadge({
label: 'jsrepo',
labelColor: '#f7df1e',
color: state === 'failing' ? '#ff0000' : '',
message: `build ${state}`
});

return new Response(svg, {
headers: {
'Content-Type': 'image/svg+xml'
}
});
};
35 changes: 35 additions & 0 deletions sites/docs/src/routes/badges/registry/blocks/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { getProviderState, getProviderToken } from '$lib/ts/registry';
import { error } from '@sveltejs/kit';
import { fetchManifest, selectProvider } from 'jsrepo';
import { makeBadge } from 'badge-maker';

export const GET = async ({ url }) => {
const registryUrl = url.searchParams.get('url');

if (registryUrl == null) throw error(400, 'Expected `url` search param');

const provider = selectProvider(registryUrl);

if (!provider) throw error(400, 'Invalid registry url');

const state = await getProviderState(registryUrl, provider, { cache: true });

const manifest = (await fetchManifest(state, { token: getProviderToken(state.provider) })).match(
(v) => v,
(err) => {
throw error(400, `Error fetching manifest: ${err}`);
}
);

const svg = makeBadge({
label: 'jsrepo',
labelColor: '#f7df1e',
message: `${manifest.categories.flatMap((c) => c.blocks).length} blocks`
});

return new Response(svg, {
headers: {
'Content-Type': 'image/svg+xml'
}
});
};
35 changes: 35 additions & 0 deletions sites/docs/src/routes/badges/registry/categories/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { getProviderState, getProviderToken } from '$lib/ts/registry';
import { error } from '@sveltejs/kit';
import { fetchManifest, selectProvider } from 'jsrepo';
import { makeBadge } from 'badge-maker';

export const GET = async ({ url }) => {
const registryUrl = url.searchParams.get('url');

if (registryUrl == null) throw error(400, 'Expected `url` search param');

const provider = selectProvider(registryUrl);

if (!provider) throw error(400, 'Invalid registry url');

const state = await getProviderState(registryUrl, provider, { cache: true });

const manifest = (await fetchManifest(state, { token: getProviderToken(state.provider) })).match(
(v) => v,
(err) => {
throw error(400, `Error fetching manifest: ${err}`);
}
);

const svg = makeBadge({
label: 'jsrepo',
labelColor: '#f7df1e',
message: `${manifest.categories.length} categories`
});

return new Response(svg, {
headers: {
'Content-Type': 'image/svg+xml'
}
});
};
Loading

0 comments on commit e43deee

Please sign in to comment.