yap #1
18 changed files with 255 additions and 151 deletions
|
@ -0,0 +1,9 @@
|
|||
AUTH_SECRET=
|
||||
|
||||
MYSQL_HOST=
|
||||
MYSQL_USERNAME=
|
||||
MYSQL_PASSWORD=
|
||||
|
||||
KEYCLOAK_CLIENT_ID=
|
||||
KEYCLOAK_CLIENT_SECRET=
|
||||
KEYCLOAK_CLIENT_ISSUER=
|
|
@ -32,4 +32,3 @@ COPY --from=build /usr/src/app/build/ .
|
|||
|
||||
EXPOSE 3000/tcp
|
||||
CMD [ "node", "index.js" ]
|
||||
|
||||
|
|
|
@ -5,3 +5,11 @@
|
|||
[![forthebadge](https://forthebadge.com/images/badges/license-mit.svg)](https://forthebadge.com) [![forthebadge](https://forthebadge.com/images/badges/designed-in-ms-paint.svg)](https://forthebadge.com) [![forthebadge](https://forthebadge.com/images/badges/gluten-free.svg)](https://forthebadge.com) [![forthebadge](https://forthebadge.com/images/badges/powered-by-black-magic.svg)](https://forthebadge.com)
|
||||
|
||||
A file uploading website.
|
||||
|
||||
## Developing
|
||||
|
||||
You can start a development SQL server with Docker:
|
||||
|
||||
```sh
|
||||
sudo docker run -e MYSQL_ROOT_PASSWORD=development -e MYSQL_DATABASE=fileuploader -d mysql:latest
|
||||
```
|
||||
|
|
11
drizzle.config.js
Normal file
11
drizzle.config.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
/** @type { import("drizzle-kit").Config } */
|
||||
export default {
|
||||
schema: 'src/lib/server/database/schema.js',
|
||||
driver: 'mysql2',
|
||||
dbCredentials: {
|
||||
host: process.env.MYSQL_HOST,
|
||||
user: process.env.MYSQL_USERNAME,
|
||||
password: process.env.MYSQL_PASSWORD,
|
||||
database: 'fileuploader'
|
||||
}
|
||||
};
|
|
@ -25,6 +25,9 @@
|
|||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@auth/core": "^0.28.0",
|
||||
"@auth/drizzle-adapter": "^0.8.0",
|
||||
"@auth/sveltekit": "^0.14.0",
|
||||
"drizzle-orm": "^0.30.2",
|
||||
"lucide-svelte": "^0.358.0",
|
||||
"mysql2": "^3.9.2",
|
||||
|
|
|
@ -1,12 +1,25 @@
|
|||
// import { redirect } from '@sveltejs/kit';
|
||||
import { sequence } from '@sveltejs/kit/hooks';
|
||||
import { handle as authenticationHandle } from '$lib/server/auth.js';
|
||||
|
||||
async function authorizationHandle({ event, resolve }) {
|
||||
// if (event.url.pathname.startsWith('/(app)')) {
|
||||
// const session = await event.locals.auth();
|
||||
// if (!session) {
|
||||
// throw redirect(303, '/auth/signin');
|
||||
// }
|
||||
// }
|
||||
|
||||
return resolve(event);
|
||||
}
|
||||
|
||||
export const handle = sequence(authenticationHandle, authorizationHandle);
|
||||
|
||||
/** @type {import('@sveltejs/kit').HandleServerError} */
|
||||
export async function handleError({ error, event, status, message }) {
|
||||
|
||||
console.log(error)
|
||||
|
||||
const id = crypto.randomUUID();
|
||||
console.log(error);
|
||||
|
||||
return {
|
||||
id,
|
||||
status,
|
||||
message
|
||||
};
|
||||
|
|
30
src/lib/components/LoggedOut.svelte
Normal file
30
src/lib/components/LoggedOut.svelte
Normal file
|
@ -0,0 +1,30 @@
|
|||
<script>
|
||||
import { LogIn } from 'lucide-svelte';
|
||||
|
||||
import { signIn } from '@auth/sveltekit/client';
|
||||
|
||||
import ThemeSwitcher from '$lib/components/ThemeSwitcher.svelte';
|
||||
import Button from '$lib/components/Button.svelte';
|
||||
import Logo from '$lib/components/Logo.svelte';
|
||||
</script>
|
||||
|
||||
<div class="flex justify-center items-center h-screen">
|
||||
<div class="flex flex-col space-y-1.5">
|
||||
<div>
|
||||
<div class="transition-colors fill-black dark:fill-white">
|
||||
<Logo />
|
||||
</div>
|
||||
<p class="text-center">Currently hosting <strong>0</strong> files.</p>
|
||||
<p class="text-center">Elon musk <strong>found dead</strong> in a <strong>pool</strong></p>
|
||||
</div>
|
||||
|
||||
<div class="flex place-content-around mx-auto space-x-2">
|
||||
<ThemeSwitcher />
|
||||
|
||||
<Button click={() => signIn('keycloak')}>
|
||||
<LogIn />
|
||||
<p>Keycloak Login</p>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
23
src/lib/server/auth.js
Normal file
23
src/lib/server/auth.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
import { SvelteKitAuth } from '@auth/sveltekit';
|
||||
import Keycloak from '@auth/core/providers/keycloak';
|
||||
import { DrizzleAdapter } from '@auth/drizzle-adapter';
|
||||
import { db } from '$lib/server/database';
|
||||
import { env } from '$env/dynamic/private';
|
||||
|
||||
export const { handle, signIn, signOut } = SvelteKitAuth({
|
||||
adapter: DrizzleAdapter(db),
|
||||
providers: [
|
||||
Keycloak({
|
||||
clientId: env.KEYCLOAK_CLIENT_ID,
|
||||
clientSecret: env.KEYCLOAK_CLIENT_SECRET,
|
||||
issuer: env.KEYCLOAK_ISSUER,
|
||||
profile(profile) {
|
||||
return {
|
||||
id: profile.sub,
|
||||
name: profile.preferred_username,
|
||||
email: profile.email
|
||||
};
|
||||
}
|
||||
})
|
||||
]
|
||||
});
|
13
src/lib/server/database/index.js
Normal file
13
src/lib/server/database/index.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { drizzle } from 'drizzle-orm/mysql2';
|
||||
import mysql from 'mysql2/promise';
|
||||
import { env } from '$env/dynamic/private';
|
||||
import * as schema from './schema';
|
||||
|
||||
const connection = await mysql.createConnection({
|
||||
host: env.MYSQL_HOST,
|
||||
user: env.MYSQL_USERNAME,
|
||||
password: env.MYSQL_PASSWORD,
|
||||
database: 'fileuploader'
|
||||
});
|
||||
|
||||
export const db = drizzle(connection, { schema, mode: 'default' });
|
53
src/lib/server/database/schema.js
Normal file
53
src/lib/server/database/schema.js
Normal file
|
@ -0,0 +1,53 @@
|
|||
import { int, timestamp, mysqlTable, primaryKey, varchar } from 'drizzle-orm/mysql-core';
|
||||
|
||||
export const users = mysqlTable('user', {
|
||||
id: varchar('id', { length: 255 }).notNull().primaryKey(),
|
||||
name: varchar('name', { length: 255 }),
|
||||
email: varchar('email', { length: 255 }).notNull(),
|
||||
emailVerified: timestamp('emailVerified', { mode: 'date', fsp: 3 }).defaultNow(),
|
||||
image: varchar('image', { length: 255 })
|
||||
});
|
||||
|
||||
export const accounts = mysqlTable(
|
||||
'account',
|
||||
{
|
||||
userId: varchar('userId', { length: 255 })
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: 'cascade' }),
|
||||
type: varchar('type', { length: 255 }).notNull(),
|
||||
provider: varchar('provider', { length: 255 }).notNull(),
|
||||
providerAccountId: varchar('providerAccountId', { length: 255 }).notNull(),
|
||||
refresh_token: varchar('refresh_token', { length: 2048 }),
|
||||
access_token: varchar('access_token', { length: 2048 }),
|
||||
expires_at: int('expires_at'),
|
||||
token_type: varchar('token_type', { length: 255 }),
|
||||
scope: varchar('scope', { length: 255 }),
|
||||
id_token: varchar('id_token', { length: 2048 }),
|
||||
session_state: varchar('session_state', { length: 255 })
|
||||
},
|
||||
(account) => ({
|
||||
compoundKey: primaryKey({
|
||||
columns: [account.provider, account.providerAccountId]
|
||||
})
|
||||
})
|
||||
);
|
||||
|
||||
export const sessions = mysqlTable('session', {
|
||||
sessionToken: varchar('sessionToken', { length: 255 }).notNull().primaryKey(),
|
||||
userId: varchar('userId', { length: 255 })
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: 'cascade' }),
|
||||
expires: timestamp('expires', { mode: 'date' }).notNull()
|
||||
});
|
||||
|
||||
export const verificationTokens = mysqlTable(
|
||||
'verificationToken',
|
||||
{
|
||||
identifier: varchar('identifier', { length: 255 }).notNull(),
|
||||
token: varchar('token', { length: 255 }).notNull(),
|
||||
expires: timestamp('expires', { mode: 'date' }).notNull()
|
||||
},
|
||||
(vt) => ({
|
||||
compoundKey: primaryKey({ columns: [vt.identifier, vt.token] })
|
||||
})
|
||||
);
|
|
@ -1,10 +0,0 @@
|
|||
import { drizzle } from 'drizzle-orm/mysql2';
|
||||
import mysql from 'mysql2/promise';
|
||||
|
||||
const connection = await mysql.createConnection({
|
||||
host: process.env.DATABASE_HOST,
|
||||
user: process.env.DATABASE_USER,
|
||||
password: process.env.DATABASE_PASSWORD
|
||||
});
|
||||
|
||||
export default drizzle(connection);
|
|
@ -1,7 +0,0 @@
|
|||
import { int, mysqlTable, text } from 'drizzle-orm/mysql-core';
|
||||
|
||||
export const users = mysqlTable('users', {
|
||||
id: int('id').autoincrement().primaryKey(),
|
||||
username: text('username').unique().notNull(),
|
||||
password: text('password').notNull()
|
||||
});
|
5
src/routes/+layout.server.js
Normal file
5
src/routes/+layout.server.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
export const load = async ({ locals }) => {
|
||||
return {
|
||||
session: await locals.getSession()
|
||||
};
|
||||
};
|
|
@ -2,8 +2,10 @@
|
|||
import '../app.css';
|
||||
|
||||
import { Toaster } from 'svelte-sonner';
|
||||
import { page } from '$app/stores';
|
||||
|
||||
import { darkMode } from '$lib/stores.js';
|
||||
import LoggedOut from '$lib/components/LoggedOut.svelte';
|
||||
import ThemeHandler from '$lib/components/ThemeHandler.svelte';
|
||||
import PageMeta from '$lib/components/PageMeta.svelte';
|
||||
</script>
|
||||
|
@ -12,6 +14,10 @@
|
|||
<ThemeHandler />
|
||||
<Toaster theme={$darkMode ? 'dark' : 'light'} />
|
||||
|
||||
{#if $page.data.session?.user}
|
||||
<div class="container">
|
||||
<slot />
|
||||
</div>
|
||||
{:else}
|
||||
<LoggedOut />
|
||||
{/if}
|
||||
|
|
|
@ -1,45 +1,16 @@
|
|||
<script>
|
||||
import { toast } from 'svelte-sonner';
|
||||
import { LogIn, UserPlus } from 'lucide-svelte';
|
||||
import { page } from '$app/stores';
|
||||
import { signOut } from '@auth/sveltekit/client';
|
||||
|
||||
import ThemeSwitcher from '$lib/components/ThemeSwitcher.svelte';
|
||||
import Link from '$lib/components/Link.svelte';
|
||||
import Button from '$lib/components/Button.svelte';
|
||||
import Logo from '$lib/components/Logo.svelte';
|
||||
|
||||
function fuckYou() {
|
||||
toast.error('Not Implemented');
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex justify-center items-center h-screen">
|
||||
<div class="flex flex-col space-y-1.5">
|
||||
<div>
|
||||
<div class="transition-colors fill-black dark:fill-white">
|
||||
<Logo />
|
||||
</div>
|
||||
<p>Currently hosting <strong>0</strong> files.</p>
|
||||
<p>Elon musk <strong>found dead</strong> in a <strong>pool</strong></p>
|
||||
</div>
|
||||
<p>
|
||||
<tt class="block whitespace-pre-wrap">
|
||||
{JSON.stringify($page.data?.session, null, 4)}
|
||||
</tt>
|
||||
</p>
|
||||
|
||||
<div class="flex space-x-2">
|
||||
<ThemeSwitcher />
|
||||
|
||||
<Link style="button" href="/login">
|
||||
<LogIn />
|
||||
<p>Login</p>
|
||||
</Link>
|
||||
|
||||
<Link style="button" href="/register">
|
||||
<UserPlus />
|
||||
<p>Register</p>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<Button click={fuckYou}>
|
||||
<p class="w-full text-center">Keycloak Login</p>
|
||||
<Button click={signOut}>
|
||||
<p>Logout</p>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
<script>
|
||||
import { Mail, SquareAsterisk, LogIn, Undo } from 'lucide-svelte';
|
||||
import { goBack } from '$lib/';
|
||||
|
||||
import Logo from '$lib/components/Logo.svelte';
|
||||
import FormInput from '$lib/components/FormInput.svelte';
|
||||
import Button from '$lib/components/Button.svelte';
|
||||
</script>
|
||||
|
||||
<div class="flex justify-center items-center h-screen">
|
||||
<div class="flex flex-col space-y-2">
|
||||
<div class="transition-colors fill-black dark:fill-white">
|
||||
<Logo />
|
||||
</div>
|
||||
<form action="">
|
||||
<div class="flex flex-col space-y-2">
|
||||
<FormInput type={'email'} name={'email'} id={'email'} placeholder={'user@example.com'}>
|
||||
<Mail />
|
||||
</FormInput>
|
||||
<FormInput type={'password'} name={'password'} id={'password'} placeholder={'•'.repeat(16)}>
|
||||
<SquareAsterisk />
|
||||
</FormInput>
|
||||
<div class="flex place-content-between">
|
||||
<Button click={goBack}>
|
||||
<Undo />
|
||||
<p>Go Back</p>
|
||||
</Button>
|
||||
<Button>
|
||||
<LogIn />
|
||||
<p>Login</p>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
|
@ -1,47 +0,0 @@
|
|||
<script>
|
||||
import { Mail, SquareAsterisk, LogIn, Undo, User, UserPlus } from 'lucide-svelte';
|
||||
import { goBack } from '$lib/';
|
||||
|
||||
import Logo from '$lib/components/Logo.svelte';
|
||||
import FormInput from '$lib/components/FormInput.svelte';
|
||||
import Button from '$lib/components/Button.svelte';
|
||||
</script>
|
||||
|
||||
<div class="flex justify-center items-center h-screen">
|
||||
<div class="flex flex-col space-y-2">
|
||||
<div class="transition-colors fill-black dark:fill-white">
|
||||
<Logo />
|
||||
</div>
|
||||
<form action="">
|
||||
<div class="flex flex-col space-y-2">
|
||||
<FormInput type={'username'} name={'username'} id={'username'} placeholder={'Username'}>
|
||||
<User />
|
||||
</FormInput>
|
||||
<FormInput type={'email'} name={'email'} id={'email'} placeholder={'user@example.com'}>
|
||||
<Mail />
|
||||
</FormInput>
|
||||
<FormInput type={'password'} name={'password'} id={'password'} placeholder={'•'.repeat(16)}>
|
||||
<SquareAsterisk />
|
||||
</FormInput>
|
||||
<FormInput
|
||||
type={'password'}
|
||||
name={'cpassword'}
|
||||
id={'cpassword'}
|
||||
placeholder={'•'.repeat(16)}
|
||||
>
|
||||
<SquareAsterisk />
|
||||
</FormInput>
|
||||
<div class="flex place-content-between">
|
||||
<Button click={goBack}>
|
||||
<Undo />
|
||||
<p>Go Back</p>
|
||||
</Button>
|
||||
<Button>
|
||||
<UserPlus />
|
||||
<p>Register</p>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
64
yarn.lock
64
yarn.lock
|
@ -15,6 +15,34 @@
|
|||
"@jridgewell/gen-mapping" "^0.3.5"
|
||||
"@jridgewell/trace-mapping" "^0.3.24"
|
||||
|
||||
"@auth/core@0.28.0", "@auth/core@^0.28.0":
|
||||
version "0.28.0"
|
||||
resolved "https://registry.yarnpkg.com/@auth/core/-/core-0.28.0.tgz#3e3aa723062e3f1daf28eb47688db622bf119396"
|
||||
integrity sha512-/fh/tb/L4NMSYcyPoo4Imn8vN6MskcVfgESF8/ndgtI4fhD/7u7i5fTVzWgNRZ4ebIEGHNDbWFRxaTu1NtQgvA==
|
||||
dependencies:
|
||||
"@panva/hkdf" "^1.1.1"
|
||||
"@types/cookie" "0.6.0"
|
||||
cookie "0.6.0"
|
||||
jose "^5.1.3"
|
||||
oauth4webapi "^2.4.0"
|
||||
preact "10.11.3"
|
||||
preact-render-to-string "5.2.3"
|
||||
|
||||
"@auth/drizzle-adapter@^0.8.0":
|
||||
version "0.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@auth/drizzle-adapter/-/drizzle-adapter-0.8.0.tgz#a2d5a84528d0398d7853a0dde6d661a58b40b2d5"
|
||||
integrity sha512-cwLMOJHf+R8VeHYFzdA5DReKelidWSx8bz9kJ6hydPjUugHate2F7u9XHoCOu7zXIA5azSPb3b2WR9C0Fjq7eA==
|
||||
dependencies:
|
||||
"@auth/core" "0.28.0"
|
||||
|
||||
"@auth/sveltekit@^0.14.0":
|
||||
version "0.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@auth/sveltekit/-/sveltekit-0.14.0.tgz#4d410f67b53fe398a2e5df121c7438d2f8c13d89"
|
||||
integrity sha512-I4ec4hcL4BTHgebJ1KvjX/8VclLuJAkcJdPwH0BOGt20qlu+wipI7EQjJy6EG2s4p0cAEWaIGGKFhMZIUfb+1Q==
|
||||
dependencies:
|
||||
"@auth/core" "0.28.0"
|
||||
set-cookie-parser "^2.6.0"
|
||||
|
||||
"@drizzle-team/studio@^0.0.39":
|
||||
version "0.0.39"
|
||||
resolved "https://registry.yarnpkg.com/@drizzle-team/studio/-/studio-0.0.39.tgz#70e9155503f7343e8f1917d316f93e64c23760e1"
|
||||
|
@ -328,6 +356,11 @@
|
|||
"@nodelib/fs.scandir" "2.1.5"
|
||||
fastq "^1.6.0"
|
||||
|
||||
"@panva/hkdf@^1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@panva/hkdf/-/hkdf-1.1.1.tgz#ab9cd8755d1976e72fc77a00f7655a64efe6cd5d"
|
||||
integrity sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==
|
||||
|
||||
"@pkgjs/parseargs@^0.11.0":
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
|
||||
|
@ -498,7 +531,7 @@
|
|||
svelte-hmr "^0.15.3"
|
||||
vitefu "^0.2.5"
|
||||
|
||||
"@types/cookie@^0.6.0":
|
||||
"@types/cookie@0.6.0", "@types/cookie@^0.6.0":
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.6.0.tgz#eac397f28bf1d6ae0ae081363eca2f425bedf0d5"
|
||||
integrity sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==
|
||||
|
@ -712,7 +745,7 @@ commondir@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
|
||||
integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==
|
||||
|
||||
cookie@^0.6.0:
|
||||
cookie@0.6.0, cookie@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051"
|
||||
integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==
|
||||
|
@ -1257,6 +1290,11 @@ jiti@^1.19.1:
|
|||
resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d"
|
||||
integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==
|
||||
|
||||
jose@^5.1.3:
|
||||
version "5.2.3"
|
||||
resolved "https://registry.yarnpkg.com/jose/-/jose-5.2.3.tgz#071c87f9fe720cff741a403c8080b69bfe13164a"
|
||||
integrity sha512-KUXdbctm1uHVL8BYhnyHkgp3zDX5KW8ZhAKVFEfUbU2P8Alpzjb+48hHvjOdQIyPshoblhzsuqOwEEAbtHVirA==
|
||||
|
||||
json-diff@0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/json-diff/-/json-diff-0.9.0.tgz#e7c536798053cb409113d7403c774849e8a0d7ff"
|
||||
|
@ -1470,6 +1508,11 @@ normalize-range@^0.1.2:
|
|||
resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
|
||||
integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==
|
||||
|
||||
oauth4webapi@^2.4.0:
|
||||
version "2.10.3"
|
||||
resolved "https://registry.yarnpkg.com/oauth4webapi/-/oauth4webapi-2.10.3.tgz#8e6d5a8a984a297dd80276a6c52634359319d034"
|
||||
integrity sha512-9FkXEXfzVKzH63GUOZz1zMr3wBaICSzk6DLXx+CGdrQ10ItNk2ePWzYYc1fdmKq1ayGFb2aX97sRCoZ2s0mkDw==
|
||||
|
||||
object-assign@^4.0.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
|
@ -1587,6 +1630,18 @@ postcss@^8.4.23, postcss@^8.4.35:
|
|||
picocolors "^1.0.0"
|
||||
source-map-js "^1.0.2"
|
||||
|
||||
preact-render-to-string@5.2.3:
|
||||
version "5.2.3"
|
||||
resolved "https://registry.yarnpkg.com/preact-render-to-string/-/preact-render-to-string-5.2.3.tgz#23d17376182af720b1060d5a4099843c7fe92fe4"
|
||||
integrity sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==
|
||||
dependencies:
|
||||
pretty-format "^3.8.0"
|
||||
|
||||
preact@10.11.3:
|
||||
version "10.11.3"
|
||||
resolved "https://registry.yarnpkg.com/preact/-/preact-10.11.3.tgz#8a7e4ba19d3992c488b0785afcc0f8aa13c78d19"
|
||||
integrity sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==
|
||||
|
||||
prettier-plugin-svelte@^3.1.2:
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/prettier-plugin-svelte/-/prettier-plugin-svelte-3.2.2.tgz#df576c8a92088dc0aaec8e27fce8a7d9683de93c"
|
||||
|
@ -1597,6 +1652,11 @@ prettier@^3.1.1:
|
|||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368"
|
||||
integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==
|
||||
|
||||
pretty-format@^3.8.0:
|
||||
version "3.8.0"
|
||||
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-3.8.0.tgz#bfbed56d5e9a776645f4b1ff7aa1a3ac4fa3c385"
|
||||
integrity sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==
|
||||
|
||||
queue-microtask@^1.2.2:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
||||
|
|
Loading…
Reference in a new issue