fix(chore): prettier format

This commit is contained in:
Shahrad Elahi 2023-12-19 13:21:11 +03:30
parent 42bc3dc971
commit 8488858c46
66 changed files with 340 additions and 277 deletions

View File

@ -4,20 +4,14 @@
"singleQuote": true,
"jsxSingleQuote": true,
"trailingComma": "all",
"printWidth": 120,
"jsxBracketSameLine": true,
"printWidth": 100,
"overrides": [
{
"files": "*.svelte",
"options": {
"parser": "svelte",
"plugins": [
"prettier-plugin-svelte"
]
"plugins": ["prettier-plugin-svelte"]
}
}
],
"pluginSearchDirs": [
"."
]
}

View File

@ -10,4 +10,4 @@
"components": "$lib/components",
"utils": "$lib/utils"
}
}
}

View File

@ -9,8 +9,8 @@
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"test": "mocha",
"lint": "prettier --plugin-search-dir . --check .",
"format": "prettier --plugin-search-dir . --write .",
"lint": "prettier --check .",
"format": "prettier --write .",
"start": "node ./build/index.js"
},
"devDependencies": {
@ -55,4 +55,4 @@
"tailwind-merge": "^2.1.0",
"tailwind-variants": "^0.1.18"
}
}
}

View File

@ -6,8 +6,8 @@ const config = {
//Some plugins, like tailwindcss/nesting, need to run before Tailwind,
tailwindcss(),
//But others, like autoprefixer, need to run after,
autoprefixer
]
autoprefixer,
],
};
module.exports = config;
module.exports = config;

View File

@ -79,7 +79,6 @@
}
@layer base {
h1 {
@apply text-4xl font-bold;
}
@ -108,5 +107,4 @@
text-decoration: none;
transition: color 0.2s ease-in-out;
}
}
}

View File

@ -1,12 +1,12 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover" class="min-h-screen">
<div style="display: contents" class="min-h-screen">%sveltekit.body%</div>
</body>
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover" class="min-h-screen">
<div style="display: contents" class="min-h-screen">%sveltekit.body%</div>
</body>
</html>

View File

@ -3,5 +3,5 @@ import Root from './EditableText.svelte';
export {
Root,
//
Root as EditableText
}
Root as EditableText,
};

View File

@ -21,7 +21,7 @@
viewBox="0 0 64 41"
xmlns="http://www.w3.org/2000/svg"
{...$$restProps}
class={cn('max-w-full h-full m-auto',className)}
class={cn('max-w-full h-full m-auto', className)}
>
<g transform="translate(0 1)" fill="none" fill-rule="evenodd">
<ellipse fill={shadowColor} cx="32" cy="33" rx="32" ry="7" />

View File

@ -10,9 +10,9 @@
</script>
<div class="w-full min-h-screen flex justify-center px-2 md:px-6 py-2">
<div class={cn("w-full mx-auto max-w-3xl space-y-3.5", rootClass)}>
<div class={cn('w-full mx-auto max-w-3xl space-y-3.5', rootClass)}>
<PageHeader {showLogout} />
<main class={cn("py-2", className)}>
<main class={cn('py-2', className)}>
<slot />
</main>
<PageFooter />

View File

@ -13,7 +13,11 @@
</div>
<div class={'flex items-center gap-x-8'}>
<a href={'https://github.com/shahradelahi/wireadmin'} title={'Giv me a star on Github'} class="hidden md:block">
<a
href={'https://github.com/shahradelahi/wireadmin'}
title={'Giv me a star on Github'}
class="hidden md:block"
>
<img
src={'https://img.shields.io/github/stars/shahradelahi/wireadmin.svg?style=social&label=Star'}
alt={'Giv me a star on Github'}
@ -21,8 +25,15 @@
</a>
{#if showLogout}
<a href="/logout" rel="external" title="Logout" class="group text-sm/2 font-medium text-neutral-700 hover:text-neutral-800">
<i class="far fa-arrow-right-from-arc text-sm text-neutral-500 group-hover:text-neutral-800 mr-0.5"></i>
<a
href="/logout"
rel="external"
title="Logout"
class="group text-sm/2 font-medium text-neutral-700 hover:text-neutral-800"
>
<i
class="far fa-arrow-right-from-arc text-sm text-neutral-500 group-hover:text-neutral-800 mr-0.5"
></i>
Logout
</a>
{/if}

View File

@ -8,6 +8,11 @@
export { className as class };
</script>
<svelte:element this={href ? 'a' : 'span'} {href} class={cn(badgeVariants({ variant, className }))} {...$$restProps}>
<svelte:element
this={href ? 'a' : 'span'}
{href}
class={cn(badgeVariants({ variant, className }))}
{...$$restProps}
>
<slot />
</svelte:element>

View File

@ -8,7 +8,8 @@ export const badgeVariants = tv({
default: 'bg-primary hover:bg-primary/80 border-transparent text-primary-foreground',
secondary: 'bg-secondary hover:bg-secondary/80 border-transparent text-secondary-foreground',
success: 'bg-green-500 hover:bg-green-500/80 border-transparent text-white',
destructive: 'bg-destructive hover:bg-destructive/80 border-transparent text-destructive-foreground',
destructive:
'bg-destructive hover:bg-destructive/80 border-transparent text-destructive-foreground',
outline: 'text-foreground',
},
},

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { Button as ButtonPrimitive } from 'bits-ui';
import { Button as ButtonPrimitive } from 'bits-ui';
import { cn } from '$lib/utils';
import { buttonVariants, type Props, type Events } from '.';
@ -21,5 +21,5 @@
on:click
on:keydown
>
<slot />
<slot />
</ButtonPrimitive.Root>

View File

@ -7,14 +7,10 @@ const buttonVariants = tv({
variants: {
variant: {
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
destructive:
'bg-destructive text-destructive-foreground hover:bg-destructive/90',
success:
'bg-green-500 text-white hover:bg-green-500/90 hover:text-gray-50',
outline:
'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
secondary:
'bg-secondary text-secondary-foreground hover:bg-secondary/80',
destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
success: 'bg-green-500 text-white hover:bg-green-500/90 hover:text-gray-50',
outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
ghost: 'hover:bg-accent hover:text-accent-foreground',
link: 'text-primary underline-offset-4 hover:underline',
},

View File

@ -12,6 +12,10 @@
export { className as class };
</script>
<svelte:element this={tag} class={cn('text-lg font-semibold leading-none tracking-tight', className)} {...$$restProps}>
<svelte:element
this={tag}
class={cn('text-lg font-semibold leading-none tracking-tight', className)}
{...$$restProps}
>
<slot />
</svelte:element>

View File

@ -8,6 +8,9 @@
export { className as class };
</script>
<div class={cn('rounded-lg border bg-card text-card-foreground shadow-sm', className)} {...$$restProps}>
<div
class={cn('rounded-lg border bg-card text-card-foreground shadow-sm', className)}
{...$$restProps}
>
<slot />
</div>

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { Checkbox as CheckboxPrimitive } from 'bits-ui';
import { Checkbox as CheckboxPrimitive } from 'bits-ui';
import { Check, Minus } from 'lucide-svelte';
import { cn } from '$lib/utils';
@ -13,22 +13,22 @@
<CheckboxPrimitive.Root
class={cn(
"box-content peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50",
className
)}
'box-content peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50',
className,
)}
bind:checked
{...$$restProps}
on:click
>
<CheckboxPrimitive.Indicator
class={cn("flex items-center justify-center text-current h-4 w-4")}
<CheckboxPrimitive.Indicator
class={cn('flex items-center justify-center text-current h-4 w-4')}
let:isChecked
let:isIndeterminate
>
{#if isChecked}
<Check class="h-3.5 w-3.5" />
{:else if isIndeterminate}
<Minus class="h-3.5 w-3.5" />
{/if}
</CheckboxPrimitive.Indicator>
{#if isChecked}
<Check class="h-3.5 w-3.5" />
{:else if isIndeterminate}
<Minus class="h-3.5 w-3.5" />
{/if}
</CheckboxPrimitive.Indicator>
</CheckboxPrimitive.Root>

View File

@ -1,15 +1,15 @@
<script lang="ts">
import { Collapsible as CollapsiblePrimitive } from "bits-ui";
import { slide } from "svelte/transition";
import { Collapsible as CollapsiblePrimitive } from 'bits-ui';
import { slide } from 'svelte/transition';
type $$Props = CollapsiblePrimitive.ContentProps;
type $$Props = CollapsiblePrimitive.ContentProps;
export let transition: $$Props["transition"] = slide;
export let transitionConfig: $$Props["transitionConfig"] = {
duration: 150
};
export let transition: $$Props['transition'] = slide;
export let transitionConfig: $$Props['transitionConfig'] = {
duration: 150,
};
</script>
<CollapsiblePrimitive.Content {transition} {transitionConfig} {...$$restProps}>
<slot />
<slot />
</CollapsiblePrimitive.Content>

View File

@ -1,15 +1,15 @@
import { Collapsible as CollapsiblePrimitive } from "bits-ui";
import Content from "./collapsible-content.svelte";
import { Collapsible as CollapsiblePrimitive } from 'bits-ui';
import Content from './collapsible-content.svelte';
const Root = CollapsiblePrimitive.Root;
const Trigger = CollapsiblePrimitive.Trigger;
export {
Root,
Content,
Trigger,
//
Root as Collapsible,
Content as CollapsibleContent,
Trigger as CollapsibleTrigger
Root,
Content,
Trigger,
//
Root as Collapsible,
Content as CollapsibleContent,
Trigger as CollapsibleTrigger,
};

View File

@ -8,6 +8,9 @@
export { className as class };
</script>
<DialogPrimitive.Description class={cn('text-sm text-muted-foreground', className)} {...$$restProps}>
<DialogPrimitive.Description
class={cn('text-sm text-muted-foreground', className)}
{...$$restProps}
>
<slot />
</DialogPrimitive.Description>

View File

@ -8,6 +8,9 @@
export { className as class };
</script>
<div class={cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', className)} {...$$restProps}>
<div
class={cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', className)}
{...$$restProps}
>
<slot />
</div>

View File

@ -8,6 +8,9 @@
export { className as class };
</script>
<DialogPrimitive.Title class={cn('text-lg font-semibold leading-none tracking-tight', className)} {...$$restProps}>
<DialogPrimitive.Title
class={cn('text-lg font-semibold leading-none tracking-tight', className)}
{...$$restProps}
>
<slot />
</DialogPrimitive.Title>

View File

@ -1,10 +1,10 @@
<script lang="ts">
import * as Button from '$lib/components/ui/button';
import * as Button from '$lib/components/ui/button';
type $$Props = Button.Props;
type $$Events = Button.Events;
</script>
<Button.Root type="submit" {...$$restProps} on:click on:keydown>
<slot />
<slot />
</Button.Root>

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { getFormField } from 'formsnap';
import { getFormField } from 'formsnap';
import type { Checkbox as CheckboxPrimitive } from 'bits-ui';
import { Checkbox } from '$lib/components/ui/checkbox';
@ -15,11 +15,11 @@
<Checkbox
{...rest}
checked={typeof $value === "boolean" ? $value : false}
checked={typeof $value === 'boolean' ? $value : false}
onCheckedChange={(v) => {
onCheckedChange?.(v);
setValue(v);
}}
onCheckedChange?.(v);
setValue(v);
}}
{...$$restProps}
on:click
on:keydown

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { Form as FormPrimitive } from 'formsnap';
import { Form as FormPrimitive } from 'formsnap';
import { cn } from '$lib/utils';
import type { HTMLAttributes } from 'svelte/elements';
@ -8,9 +8,6 @@
export { className as class };
</script>
<FormPrimitive.Description
class={cn("text-sm text-muted-foreground", className)}
{...$$restProps}
>
<slot />
<FormPrimitive.Description class={cn('text-sm text-muted-foreground', className)} {...$$restProps}>
<slot />
</FormPrimitive.Description>

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { getFormField } from 'formsnap';
import { getFormField } from 'formsnap';
import type { HTMLInputAttributes } from 'svelte/elements';
import { Input, type InputEvents } from '$lib/components/ui/input';

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { cn } from '$lib/utils';
import { cn } from '$lib/utils';
import type { HTMLAttributes } from 'svelte/elements';
type $$Props = HTMLAttributes<HTMLDivElement>;
@ -7,6 +7,6 @@
export { className as class };
</script>
<div class={cn("space-y-2", className)} {...$$restProps}>
<slot />
<div class={cn('space-y-2', className)} {...$$restProps}>
<slot />
</div>

View File

@ -1,5 +1,5 @@
<script lang="ts">
import type { Label as LabelPrimitive } from 'bits-ui';
import type { Label as LabelPrimitive } from 'bits-ui';
import { getFormField } from 'formsnap';
import { cn } from '$lib/utils';
import { Label } from '$lib/components/ui/label';
@ -12,10 +12,6 @@
const { errors, ids } = getFormField();
</script>
<Label
for={$ids.input}
class={cn($errors && "text-destructive", className)}
{...$$restProps}
>
<slot />
<Label for={$ids.input} class={cn($errors && 'text-destructive', className)} {...$$restProps}>
<slot />
</Label>

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { Form as FormPrimitive } from 'formsnap';
import { Form as FormPrimitive } from 'formsnap';
import { buttonVariants } from '$lib/components/ui/button';
import { cn } from '$lib/utils';
import { ChevronDown } from 'lucide-svelte';
@ -13,12 +13,12 @@
<FormPrimitive.Select
class={cn(
buttonVariants({ variant: "outline" }),
"appearance-none bg-transparent font-normal",
className
)}
buttonVariants({ variant: 'outline' }),
'appearance-none bg-transparent font-normal',
className,
)}
{...$$restProps}
>
<slot />
<slot />
</FormPrimitive.Select>
<ChevronDown class="absolute right-3 top-2.5 h-4 w-4 opacity-50" />

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { getFormField } from 'formsnap';
import { getFormField } from 'formsnap';
import type { RadioGroup as RadioGroupPrimitive } from 'bits-ui';
import * as RadioGroup from '$lib/components/ui/radio-group';
@ -12,11 +12,11 @@
<RadioGroup.Root
{...$attrStore}
onValueChange={(v) => {
onValueChange?.(v);
setValue(v);
}}
onValueChange?.(v);
setValue(v);
}}
{...$$restProps}
>
<slot />
<input hidden {name} value={$value} />
<slot />
<input hidden {name} value={$value} />
</RadioGroup.Root>

View File

@ -1,5 +1,5 @@
<script lang="ts">
import * as Select from '$lib/components/ui/select';
import * as Select from '$lib/components/ui/select';
import type { Select as SelectPrimitive } from 'bits-ui';
import { getFormField } from 'formsnap';
@ -12,6 +12,6 @@
</script>
<Select.Trigger {...$$restProps} {...$attrStore} on:click on:keydown>
<Select.Value {placeholder} />
<slot />
<Select.Value {placeholder} />
<slot />
</Select.Trigger>

View File

@ -1,5 +1,5 @@
<script lang="ts">
import * as Select from '$lib/components/ui/select';
import * as Select from '$lib/components/ui/select';
import { getFormField } from 'formsnap';
import type { Select as SelectPrimitive } from 'bits-ui';
@ -10,11 +10,11 @@
<Select.Root
onSelectedChange={(v) => {
onSelectedChange?.(v);
setValue(v ? v.value : undefined);
}}
onSelectedChange?.(v);
setValue(v ? v.value : undefined);
}}
{...$$restProps}
>
<slot />
<input hidden {name} value={$value} />
<slot />
<input hidden {name} value={$value} />
</Select.Root>

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { getFormField } from 'formsnap';
import { getFormField } from 'formsnap';
import type { Switch as SwitchPrimitive } from 'bits-ui';
import { Switch } from '$lib/components/ui/switch';
@ -13,11 +13,11 @@
<Switch
{...$attrStore}
checked={typeof $value === "boolean" ? $value : false}
checked={typeof $value === 'boolean' ? $value : false}
onCheckedChange={(v) => {
onCheckedChange?.(v);
setValue(v);
}}
onCheckedChange?.(v);
setValue(v);
}}
{...$$restProps}
on:click
on:keydown

View File

@ -1,11 +1,8 @@
<script lang="ts">
import { getFormField } from 'formsnap';
import { getFormField } from 'formsnap';
import type { HTMLTextareaAttributes } from 'svelte/elements';
import type { TextareaGetFormField } from '.';
import {
Textarea,
type TextareaEvents,
} from '$lib/components/ui/textarea';
import { Textarea, type TextareaEvents } from '$lib/components/ui/textarea';
type $$Props = HTMLTextareaAttributes;
type $$Events = TextareaEvents;

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { Form as FormPrimitive } from 'formsnap';
import { Form as FormPrimitive } from 'formsnap';
import { cn } from '$lib/utils';
import type { HTMLAttributes } from 'svelte/elements';
@ -9,6 +9,6 @@
</script>
<FormPrimitive.Validation
class={cn("text-sm font-medium text-destructive", className)}
class={cn('text-sm font-medium text-destructive', className)}
{...$$restProps}
/>

View File

@ -27,10 +27,7 @@ const SelectGroup = SelectComp.Group;
const SelectItem = SelectComp.Item;
const SelectSeparator = SelectComp.Separator;
export type TextareaGetFormField = Omit<
ReturnType<typeof getFormField>,
'value'
> & {
export type TextareaGetFormField = Omit<ReturnType<typeof getFormField>, 'value'> & {
value: Writable<string>;
};

View File

@ -1,5 +1,5 @@
<script lang="ts">
import type { HTMLInputAttributes } from 'svelte/elements';
import type { HTMLInputAttributes } from 'svelte/elements';
import { cn } from '$lib/utils';
import type { InputEvents } from '.';
@ -13,9 +13,9 @@
<input
class={cn(
"flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-foreground file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
'flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-foreground file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
className,
)}
bind:value
on:blur
on:change

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { Label as LabelPrimitive } from 'bits-ui';
import { Label as LabelPrimitive } from 'bits-ui';
import { cn } from '$lib/utils';
type $$Props = LabelPrimitive.Props;
@ -11,11 +11,11 @@
<LabelPrimitive.Root
class={cn(
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
className
)}
'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70',
className,
)}
{...$$restProps}
on:mousedown
>
<slot />
<slot />
</LabelPrimitive.Root>

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { RadioGroup as RadioGroupPrimitive } from 'bits-ui';
import { RadioGroup as RadioGroupPrimitive } from 'bits-ui';
import { Circle } from 'lucide-svelte';
import { cn } from '$lib/utils';
@ -14,15 +14,15 @@
<RadioGroupPrimitive.Item
{value}
class={cn(
"aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
'aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
className,
)}
{...$$restProps}
on:click
>
<div class="flex items-center justify-center">
<RadioGroupPrimitive.ItemIndicator>
<Circle class="h-2.5 w-2.5 fill-current text-current" />
</RadioGroupPrimitive.ItemIndicator>
</div>
<div class="flex items-center justify-center">
<RadioGroupPrimitive.ItemIndicator>
<Circle class="h-2.5 w-2.5 fill-current text-current" />
</RadioGroupPrimitive.ItemIndicator>
</div>
</RadioGroupPrimitive.Item>

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { RadioGroup as RadioGroupPrimitive } from 'bits-ui';
import { RadioGroup as RadioGroupPrimitive } from 'bits-ui';
import { cn } from '$lib/utils';
type $$Props = RadioGroupPrimitive.Props;
@ -9,10 +9,6 @@
export { className as class };
</script>
<RadioGroupPrimitive.Root
bind:value
class={cn("grid gap-2", className)}
{...$$restProps}
>
<slot />
<RadioGroupPrimitive.Root bind:value class={cn('grid gap-2', className)} {...$$restProps}>
<slot />
</RadioGroupPrimitive.Root>

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { Select as SelectPrimitive } from 'bits-ui';
import { Select as SelectPrimitive } from 'bits-ui';
import { cn, flyAndScale } from '$lib/utils';
import { scale } from 'svelte/transition';
@ -24,13 +24,13 @@
{outTransition}
{outTransitionConfig}
class={cn(
"relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md outline-none",
className
)}
'relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md outline-none',
className,
)}
{...$$restProps}
on:keydown
>
<div class="w-full p-1">
<slot />
</div>
<div class="w-full p-1">
<slot />
</div>
</SelectPrimitive.Content>

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { cn } from '$lib/utils';
import { cn } from '$lib/utils';
import { Select as SelectPrimitive } from 'bits-ui';
import { Check } from 'lucide-svelte';
@ -18,9 +18,9 @@
{disabled}
{label}
class={cn(
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className
)}
'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
className,
)}
{...$$restProps}
on:click
on:keydown
@ -29,10 +29,10 @@
on:pointerleave
on:pointermove
>
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<SelectPrimitive.ItemIndicator>
<Check class="h-4 w-4" />
</SelectPrimitive.ItemIndicator>
</span>
<slot />
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<SelectPrimitive.ItemIndicator>
<Check class="h-4 w-4" />
</SelectPrimitive.ItemIndicator>
</span>
<slot />
</SelectPrimitive.Item>

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { Select as SelectPrimitive } from 'bits-ui';
import { Select as SelectPrimitive } from 'bits-ui';
import { cn } from '$lib/utils';
type $$Props = SelectPrimitive.LabelProps;
@ -9,8 +9,8 @@
</script>
<SelectPrimitive.Label
class={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
class={cn('py-1.5 pl-8 pr-2 text-sm font-semibold', className)}
{...$$restProps}
>
<slot />
<slot />
</SelectPrimitive.Label>

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { Select as SelectPrimitive } from 'bits-ui';
import { Select as SelectPrimitive } from 'bits-ui';
import { cn } from '$lib/utils';
type $$Props = SelectPrimitive.SeparatorProps;
@ -8,7 +8,4 @@
export { className as class };
</script>
<SelectPrimitive.Separator
class={cn("-mx-1 my-1 h-px bg-muted", className)}
{...$$restProps}
/>
<SelectPrimitive.Separator class={cn('-mx-1 my-1 h-px bg-muted', className)} {...$$restProps} />

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { Select as SelectPrimitive } from 'bits-ui';
import { Select as SelectPrimitive } from 'bits-ui';
import { ChevronDown } from 'lucide-svelte';
import { cn } from '$lib/utils';
@ -12,16 +12,16 @@
<SelectPrimitive.Trigger
class={cn(
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
'flex h-10 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
className,
)}
{...$$restProps}
let:builder
on:click
on:keydown
>
<slot {builder} />
<div>
<ChevronDown class="h-4 w-4 opacity-50" />
</div>
<slot {builder} />
<div>
<ChevronDown class="h-4 w-4 opacity-50" />
</div>
</SelectPrimitive.Trigger>

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { Select as SelectPrimitive } from 'bits-ui';
import { Select as SelectPrimitive } from 'bits-ui';
type $$Props = SelectPrimitive.Props;
@ -8,5 +8,5 @@
</script>
<SelectPrimitive.Root bind:selected bind:open {...$$restProps}>
<slot />
<slot />
</SelectPrimitive.Root>

View File

@ -1,7 +1,7 @@
import Root from "./skeleton.svelte";
import Root from './skeleton.svelte';
export {
Root,
//
Root as Skeleton
Root,
//
Root as Skeleton,
};

View File

@ -1,14 +1,11 @@
<script lang="ts">
import { cn } from "$lib/utils";
import type { HTMLAttributes } from "svelte/elements";
import { cn } from '$lib/utils';
import type { HTMLAttributes } from 'svelte/elements';
type $$Props = HTMLAttributes<HTMLDivElement>;
type $$Props = HTMLAttributes<HTMLDivElement>;
let className: $$Props["class"] = undefined;
export { className as class };
let className: $$Props['class'] = undefined;
export { className as class };
</script>
<div
class={cn("animate-pulse rounded-md bg-muted", className)}
{...$$restProps}
/>
<div class={cn('animate-pulse rounded-md bg-muted', className)} {...$$restProps} />

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { Switch as SwitchPrimitive } from 'bits-ui';
import { Switch as SwitchPrimitive } from 'bits-ui';
import { cn } from '$lib/utils';
type $$Props = SwitchPrimitive.Props;
@ -12,14 +12,14 @@
<SwitchPrimitive.Root
bind:checked
class={cn(
"peer inline-flex h-[24px] w-[44px] shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
className
)}
'peer inline-flex h-[24px] w-[44px] shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input',
className,
)}
{...$$restProps}
>
<SwitchPrimitive.Thumb
<SwitchPrimitive.Thumb
class={cn(
"pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0"
)}
'pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0',
)}
/>
</SwitchPrimitive.Root>

View File

@ -1,5 +1,5 @@
<script lang="ts">
import type { HTMLTextareaAttributes } from 'svelte/elements';
import type { HTMLTextareaAttributes } from 'svelte/elements';
import { cn } from '$lib/utils';
type $$Props = HTMLTextareaAttributes;
@ -11,9 +11,9 @@
<textarea
class={cn(
"flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
'flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
className,
)}
bind:value
on:blur
on:change

View File

@ -35,7 +35,10 @@ export default class Network {
public static async getInUsePorts(): Promise<number[]> {
const ports = [];
const output = await Shell.exec(`netstat -tulpn | grep LISTEN | awk '{print $4}' | awk -F ':' '{print $NF}'`, true);
const output = await Shell.exec(
`netstat -tulpn | grep LISTEN | awk '{print $4}' | awk -F ':' '{print $NF}'`,
true,
);
for (const line of output.split('\n')) {
const clean = Number(line.trim());
if (!isNaN(clean)) ports.push(clean);

View File

@ -2,7 +2,11 @@ import { exec } from 'child_process';
import logger from '$lib/logger';
export default class Shell {
public static async exec(command: string, safe: boolean = false, ...args: string[]): Promise<string> {
public static async exec(
command: string,
safe: boolean = false,
...args: string[]
): Promise<string> {
if (process.platform !== 'linux') {
throw new Error('This program is not meant to run non UNIX systems');
}

View File

@ -77,9 +77,8 @@ export type APISuccessResponse<D> = {
};
export type SafeReturn<T, K = any> = LeastOne<{
data: T,
error: K
}>
data: T;
error: K;
}>;
export type LeastOne<T, U = { [K in keyof T]: Pick<T, K> }> = Partial<T> & U[keyof U];

View File

@ -531,7 +531,10 @@ export async function isIPReserved(ip: string): Promise<boolean> {
}
export async function isPortReserved(port: number): Promise<boolean> {
const inUsePorts = [await Network.getInUsePorts(), (await getServers()).map((s) => Number(s.listen))].flat();
const inUsePorts = [
await Network.getInUsePorts(),
(await getServers()).map((s) => Number(s.listen)),
].flat();
return inUsePorts.includes(port);
}
@ -594,7 +597,10 @@ export async function findServerIndex(id: string): Promise<number | undefined> {
return undefined;
}
export async function findServer(id: string | undefined, hash?: string): Promise<WgServer | undefined> {
export async function findServer(
id: string | undefined,
hash?: string,
): Promise<WgServer | undefined> {
const servers = await getServers();
return id
? servers.find((s) => s.id === id)
@ -660,7 +666,9 @@ export async function genServerConf(server: WgServer): Promise<string> {
lines.push(`PublicKey = ${peer.publicKey}`);
lines.push(`${peer.preSharedKey ? `PresharedKey = ${peer.preSharedKey}` : 'OMIT'}`);
lines.push(`AllowedIPs = ${peer.allowedIps}/32`);
lines.push(`${peer.persistentKeepalive ? `PersistentKeepalive = ${peer.persistentKeepalive}` : 'OMIT'}`);
lines.push(
`${peer.persistentKeepalive ? `PersistentKeepalive = ${peer.persistentKeepalive}` : 'OMIT'}`,
);
});
return lines.filter((l) => l !== 'OMIT').join('\n');

View File

@ -32,9 +32,7 @@ export const PortSchema = z
},
);
export const TorSchema = z
.boolean()
.default(false);
export const TorSchema = z.boolean().default(false);
export const DnsSchema = z
.string()

View File

@ -3,4 +3,4 @@
import '$lib/assets/fontawesome/index.css';
</script>
<slot />
<slot />

View File

@ -1,6 +1,13 @@
import { type Actions, error } from '@sveltejs/kit';
import type { PageServerLoad } from './$types';
import { findServer, generateWgServer, getServers, isIPReserved, isPortReserved, WGServer } from '$lib/wireguard';
import {
findServer,
generateWgServer,
getServers,
isIPReserved,
isPortReserved,
WGServer,
} from '$lib/wireguard';
import { setError, superValidate } from 'sveltekit-superforms/server';
import { CreateServerSchema } from './schema';
import { NameSchema } from '$lib/wireguard/schema';

View File

@ -22,7 +22,11 @@
import { goto } from '$app/navigation';
import { FormItem } from '$lib/components/ui/form/index.js';
import { cn } from '$lib/utils';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '$lib/components/ui/collapsible';
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from '$lib/components/ui/collapsible';
import { Button } from '$lib/components/ui/button';
let loading: boolean = false;
@ -84,7 +88,9 @@
<FormItem>
<FormLabel>Port</FormLabel>
<FormInput placeholder={'e.g. 51820'} type={'text'} />
<FormDescription>This is the port that the WireGuard server will listen on.</FormDescription>
<FormDescription
>This is the port that the WireGuard server will listen on.</FormDescription
>
<FormValidation />
</FormItem>
</FormField>
@ -112,7 +118,9 @@
<FormItem>
<FormLabel>DNS</FormLabel>
<FormInput placeholder={'e.g. 1.1.1.1'} type={'text'} />
<FormDescription>Optional. This is the DNS server that will be pushed to clients.</FormDescription>
<FormDescription
>Optional. This is the DNS server that will be pushed to clients.</FormDescription
>
<FormValidation />
</FormItem>
</FormField>
@ -130,7 +138,8 @@
<DialogFooter>
<FormButton>
<i class={cn(loading ? 'far fa-arrow-rotate-right animate-spin' : 'far fa-plus', 'mr-2')}></i>
<i class={cn(loading ? 'far fa-arrow-rotate-right animate-spin' : 'far fa-plus', 'mr-2')}
></i>
Create
</FormButton>
</DialogFooter>

View File

@ -17,9 +17,14 @@
<div class="flex items-center justify-between p-4 gap-x-4">
<div class="w-full md:w-2/3 flex items-center gap-x-2">
<div class="flex grow">
<div class={'w-12 aspect-square flex items-center justify-center mr-4 rounded-full bg-gray-200 max-md:hidden'}>
<div
class={'w-12 aspect-square flex items-center justify-center mr-4 rounded-full bg-gray-200 max-md:hidden'}
>
<i
class={cn(server.tor ? 'fa-solid fa-onion text-purple-700' : 'fa-solid fa-server text-gray-400', 'text-xl')}
class={cn(
server.tor ? 'fa-solid fa-onion text-purple-700' : 'fa-solid fa-server text-gray-400',
'text-xl',
)}
/>
</div>
@ -36,7 +41,9 @@
asChild
>
<a href={`/${server.id}`} title="Manage the Server" class={cn({ hidden: editMode })}>
<span class="text-lg md:text-base hover:text-primary hover:font-medium"> {server.name} </span>
<span class="text-lg md:text-base hover:text-primary hover:font-medium">
{server.name}
</span>
</a>
</EditableText>
<CopiableText value={addressPort} class="text-sm" showInHover={true}>

View File

@ -9,7 +9,14 @@
DialogTitle,
DialogTrigger,
} from '$lib/components/ui/dialog';
import { Form, FormButton, FormField, FormInput, FormLabel, FormValidation } from '$lib/components/ui/form';
import {
Form,
FormButton,
FormField,
FormInput,
FormLabel,
FormValidation,
} from '$lib/components/ui/form';
import { FormItem } from '$lib/components/ui/form/index.js';
import { cn } from '$lib/utils';
import { invalidateAll } from '$app/navigation';
@ -70,7 +77,8 @@
<DialogFooter>
<FormButton>
<i class={cn(loading ? 'far fa-arrow-rotate-right animate-spin' : 'far fa-plus', 'mr-2')}></i>
<i class={cn(loading ? 'far fa-arrow-rotate-right animate-spin' : 'far fa-plus', 'mr-2')}
></i>
Create
</FormButton>
</DialogFooter>

View File

@ -35,7 +35,7 @@
return;
}
// create a blob
const blob = new Blob([ conf ], { type: 'text/plain' });
const blob = new Blob([conf], { type: 'text/plain' });
// create a link
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
@ -55,9 +55,13 @@
};
</script>
<div class="flex items-center justify-between p-4 border border-neutral-200/60 rounded-md hover:border-neutral-200">
<div
class="flex items-center justify-between p-4 border border-neutral-200/60 rounded-md hover:border-neutral-200"
>
<div class="flex items-center gap-x-2">
<div class={'w-12 aspect-square flex items-center justify-center mr-4 rounded-full bg-gray-200 max-md:hidden'}>
<div
class={'w-12 aspect-square flex items-center justify-center mr-4 rounded-full bg-gray-200 max-md:hidden'}
>
<i class={'fas fa-user text-gray-400 text-lg'} />
</div>

View File

@ -2,7 +2,10 @@ import type { RequestHandler } from '@sveltejs/kit';
import QRCode from 'qrcode';
export const POST: RequestHandler = async ({ request }) => {
if (!request.headers.has('Content-Type') || request.headers.get('Content-Type') !== 'text/plain') {
if (
!request.headers.has('Content-Type') ||
request.headers.get('Content-Type') !== 'text/plain'
) {
return new Response(null, { status: 400, headers: { 'Content-Type': 'text/plain' } });
}

View File

@ -2,7 +2,15 @@
import { formSchema, type FormSchema } from './schema';
import type { SuperValidated } from 'sveltekit-superforms';
import { Card, CardContent } from '$lib/components/ui/card';
import { Form, FormButton, FormField, FormInput, FormItem, FormLabel, FormValidation } from '$lib/components/ui/form';
import {
Form,
FormButton,
FormField,
FormInput,
FormItem,
FormLabel,
FormValidation,
} from '$lib/components/ui/form';
import { goto } from '$app/navigation';
import type { FormOptions } from 'formsnap';

View File

@ -1,5 +1,12 @@
import { z } from 'zod';
import { AddressSchema, DnsSchema, MtuSchema, NameSchema, PortSchema, TorSchema } from '$lib/wireguard/schema';
import {
AddressSchema,
DnsSchema,
MtuSchema,
NameSchema,
PortSchema,
TorSchema,
} from '$lib/wireguard/schema';
export const CreateServerSchema = z.object({
name: NameSchema,

View File

@ -2,16 +2,16 @@ import { fontFamily } from 'tailwindcss/defaultTheme';
/** @type {import('tailwindcss').Config} */
const config = {
darkMode: [ 'class' ],
content: [ './src/**/*.{html,js,svelte,ts}' ],
safelist: [ 'dark' ],
darkMode: ['class'],
content: ['./src/**/*.{html,js,svelte,ts}'],
safelist: ['dark'],
theme: {
container: {
center: true,
padding: '2rem',
screens: {
'2xl': '1400px'
}
'2xl': '1400px',
},
},
extend: {
colors: {
@ -22,43 +22,43 @@ const config = {
foreground: 'hsl(var(--foreground) / <alpha-value>)',
primary: {
DEFAULT: 'hsl(var(--primary) / <alpha-value>)',
foreground: 'hsl(var(--primary-foreground) / <alpha-value>)'
foreground: 'hsl(var(--primary-foreground) / <alpha-value>)',
},
secondary: {
DEFAULT: 'hsl(var(--secondary) / <alpha-value>)',
foreground: 'hsl(var(--secondary-foreground) / <alpha-value>)'
foreground: 'hsl(var(--secondary-foreground) / <alpha-value>)',
},
destructive: {
DEFAULT: 'hsl(var(--destructive) / <alpha-value>)',
foreground: 'hsl(var(--destructive-foreground) / <alpha-value>)'
foreground: 'hsl(var(--destructive-foreground) / <alpha-value>)',
},
muted: {
DEFAULT: 'hsl(var(--muted) / <alpha-value>)',
foreground: 'hsl(var(--muted-foreground) / <alpha-value>)'
foreground: 'hsl(var(--muted-foreground) / <alpha-value>)',
},
accent: {
DEFAULT: 'hsl(var(--accent) / <alpha-value>)',
foreground: 'hsl(var(--accent-foreground) / <alpha-value>)'
foreground: 'hsl(var(--accent-foreground) / <alpha-value>)',
},
popover: {
DEFAULT: 'hsl(var(--popover) / <alpha-value>)',
foreground: 'hsl(var(--popover-foreground) / <alpha-value>)'
foreground: 'hsl(var(--popover-foreground) / <alpha-value>)',
},
card: {
DEFAULT: 'hsl(var(--card) / <alpha-value>)',
foreground: 'hsl(var(--card-foreground) / <alpha-value>)'
}
foreground: 'hsl(var(--card-foreground) / <alpha-value>)',
},
},
borderRadius: {
lg: 'var(--radius)',
md: 'calc(var(--radius) - 2px)',
sm: 'calc(var(--radius) - 4px)'
sm: 'calc(var(--radius) - 4px)',
},
fontFamily: {
sans: [ ...fontFamily.sans ]
}
}
}
sans: [...fontFamily.sans],
},
},
},
};
export default config;

View File

@ -1,8 +1,8 @@
import { sveltekit } from '@sveltejs/kit/vite';
export default {
plugins: [ sveltekit() ],
plugins: [sveltekit()],
test: {
include: [ 'src/**/*.{test,spec}.{js,ts}' ]
}
include: ['src/**/*.{test,spec}.{js,ts}'],
},
};