mirror of
https://github.com/jorgev259/soc_site-astro.git
synced 2025-06-29 07:57:41 +00:00
Compare commits
7 commits
628e4cee5f
...
74d6bfbe77
| Author | SHA1 | Date | |
|---|---|---|---|
| 74d6bfbe77 | |||
| 54775f79c5 | |||
| 32a86b7a72 | |||
| e03508f57c | |||
| 6cef84a358 | |||
| d3581eaeef | |||
| 13a7f99a5d |
34 changed files with 1461 additions and 133 deletions
|
|
@ -20,20 +20,24 @@
|
||||||
"@types/react-dom": "^18.3.1",
|
"@types/react-dom": "^18.3.1",
|
||||||
"astro": "^5.3.0",
|
"astro": "^5.3.0",
|
||||||
"astro-icon": "^1.1.1",
|
"astro-icon": "^1.1.1",
|
||||||
|
"astro-seo": "^0.8.4",
|
||||||
"better-auth": "^1.1.11",
|
"better-auth": "^1.1.11",
|
||||||
"axios": "^1.8.1",
|
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
"decode-formdata": "^0.9.0",
|
||||||
|
"immer": "^10.1.1",
|
||||||
"nodemailer": "^6.10.0",
|
"nodemailer": "^6.10.0",
|
||||||
"prisma": "^6.4.1",
|
"prisma": "^6.4.1",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-hot-toast": "^2.4.1",
|
"react-hot-toast": "^2.4.1",
|
||||||
|
"react-multi-select-component": "^4.3.4",
|
||||||
"react-svg-spinners": "^0.3.1",
|
"react-svg-spinners": "^0.3.1",
|
||||||
"sharp": "^0.33.5",
|
"sharp": "^0.33.5",
|
||||||
"slugify": "^1.6.6",
|
"slugify": "^1.6.6",
|
||||||
"superstruct": "^2.0.2",
|
"superstruct": "^2.0.2",
|
||||||
"tailwindcss": "^4.0.7",
|
"tailwindcss": "^4.0.7",
|
||||||
"typescript": "^5.6.2"
|
"typescript": "^5.6.2",
|
||||||
|
"use-immer": "^0.11.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@inlang/paraglide-js": "1.11.2",
|
"@inlang/paraglide-js": "1.11.2",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- You are about to drop the column `small` on the `downloads` table. All the data in the column will be lost.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE `downloads` DROP COLUMN `small`;
|
||||||
8
prisma/migrations/20250404144405_/migration.sql
Normal file
8
prisma/migrations/20250404144405_/migration.sql
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- You are about to drop the column `custom` on the `links` table. All the data in the column will be lost.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE `links` DROP COLUMN `custom`;
|
||||||
|
|
@ -219,11 +219,10 @@ model discs {
|
||||||
}
|
}
|
||||||
|
|
||||||
model downloads {
|
model downloads {
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
title String? @db.VarChar(255)
|
title String? @db.VarChar(255)
|
||||||
small Boolean?
|
|
||||||
albumId Int
|
albumId Int
|
||||||
album albums? @relation(fields: [albumId], references: [id], onDelete: Cascade, map: "downloads_ibfk_1")
|
album albums? @relation(fields: [albumId], references: [id], onDelete: Cascade, map: "downloads_ibfk_1")
|
||||||
links links[]
|
links links[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -276,7 +275,6 @@ model links {
|
||||||
url String? @db.VarChar(255)
|
url String? @db.VarChar(255)
|
||||||
directUrl String? @db.VarChar(255)
|
directUrl String? @db.VarChar(255)
|
||||||
provider String? @db.VarChar(255)
|
provider String? @db.VarChar(255)
|
||||||
custom String? @db.VarChar(255)
|
|
||||||
downloadId Int
|
downloadId Int
|
||||||
url2 String? @db.VarChar(255)
|
url2 String? @db.VarChar(255)
|
||||||
download downloads? @relation(fields: [downloadId], references: [id], map: "links_ibfk_1")
|
download downloads? @relation(fields: [downloadId], references: [id], map: "links_ibfk_1")
|
||||||
|
|
|
||||||
BIN
public/img/assets/clouds_thumb.png
Normal file
BIN
public/img/assets/clouds_thumb.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 45 KiB |
|
|
@ -2,26 +2,24 @@ import type { PropsWithChildren, JSX } from 'react'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { BarsRotateFade } from 'react-svg-spinners'
|
import { BarsRotateFade } from 'react-svg-spinners'
|
||||||
|
|
||||||
export default function Button(
|
export default function Button(props: PropsWithChildren<{ loading?: boolean }> & JSX.IntrinsicElements['button']) {
|
||||||
props: PropsWithChildren<{ className?: string; loading?: boolean }> & JSX.IntrinsicElements['button']
|
const { children, className, loading = false, type = 'button', ...restProps } = props
|
||||||
) {
|
|
||||||
const { children, className, loading = false, ...restProps } = props
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
type={type}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
{ 'cursor-progress': loading },
|
{ 'cursor-progress': loading, loading },
|
||||||
'py-2 px-3.5 rounded-lg bg-blue-600 hover:bg-blue-700 disabled:bg-blue-400',
|
'group py-2 px-3.5 rounded-lg bg-blue-600 hover:bg-blue-700 disabled:bg-blue-400',
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
<div className='relative flex'>
|
<div className='relative flex'>
|
||||||
<span className={clsx({ invisible: loading })}>{children}</span>
|
<span className='group-[.loading]:invisible'>{children}</span>
|
||||||
{loading ? (
|
<div className='hidden group-[.loading]:flex absolute top-0 left-0 w-full justify-center'>
|
||||||
<div className='absolute top-0 left-0 w-full flex justify-center'>
|
<BarsRotateFade color='white' />
|
||||||
<BarsRotateFade color='white' />
|
</div>
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
25
src/components/DefaultSEO.astro
Normal file
25
src/components/DefaultSEO.astro
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
---
|
||||||
|
import { SEO } from 'astro-seo'
|
||||||
|
---
|
||||||
|
|
||||||
|
<SEO
|
||||||
|
slot='head'
|
||||||
|
titleDefault='Sitting on Clouds'
|
||||||
|
title='Sitting on Clouds'
|
||||||
|
description='Largest Video Game & Animation Soundtrack サウンドトラック Archive'
|
||||||
|
openGraph={{
|
||||||
|
basic: {
|
||||||
|
title: 'Sitting on Clouds — High Quality soundtrack library',
|
||||||
|
type: 'website',
|
||||||
|
image: '/img/assets/clouds_thumb.png',
|
||||||
|
url: Astro.site
|
||||||
|
},
|
||||||
|
optional: {
|
||||||
|
description: 'Largest Video Game & Animation Soundtrack サウンドトラック Archive',
|
||||||
|
siteName: 'Sitting on Clouds'
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
extend={{
|
||||||
|
meta: [{ name: 'theme-color', content: '#ffffff' }]
|
||||||
|
}}
|
||||||
|
/>
|
||||||
57
src/components/adminAlbum/DiscSection.tsx
Normal file
57
src/components/adminAlbum/DiscSection.tsx
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
import { useImmer } from 'use-immer'
|
||||||
|
import { Prisma } from '@prisma/client'
|
||||||
|
|
||||||
|
import Button from 'components/Button'
|
||||||
|
import { InputArea } from 'components/form/Input'
|
||||||
|
|
||||||
|
type Disc = Prisma.discsGetPayload<{ select: { number: true; body: true } }>
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
defaultValue?: Disc[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function DiscSection(props: Props) {
|
||||||
|
const { defaultValue = [{ number: 0, body: '' }] } = props
|
||||||
|
const [discs, setDiscs] = useImmer<Disc[]>(defaultValue)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className='flex gap-x-2'>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
setDiscs((current) => {
|
||||||
|
current.push({ number: 0, body: '' })
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add empty disc
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
setDiscs((current) => current.filter((value, index) => (value.body?.length ?? 0) > 0 || index === 0))
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Remove empty discs
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className='grid grid-cols-3 gap-4'>
|
||||||
|
{discs.map((value, index) => (
|
||||||
|
<div key={index}>
|
||||||
|
<input hidden name={`discs.${index}.number`} value={index} readOnly type='number' />
|
||||||
|
<InputArea
|
||||||
|
dark
|
||||||
|
label={`Disc ${index + 1}`}
|
||||||
|
name={`discs.${index}.body`}
|
||||||
|
defaultValue={value.body}
|
||||||
|
onChange={(ev) => {
|
||||||
|
setDiscs((current) => {
|
||||||
|
current[index].body = ev.target.value
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
126
src/components/adminAlbum/DownloadSections.tsx
Normal file
126
src/components/adminAlbum/DownloadSections.tsx
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
import { useImmer } from 'use-immer'
|
||||||
|
import type { Prisma } from '@prisma/client'
|
||||||
|
|
||||||
|
import Button from 'components/Button'
|
||||||
|
import { Input, InputSelect } from 'components/form/Input'
|
||||||
|
|
||||||
|
import { DownloadProvider } from 'utils/consts'
|
||||||
|
|
||||||
|
type Download = Prisma.downloadsGetPayload<{
|
||||||
|
select: { title: true; links: { select: { provider: true; url: true; url2: true; directUrl: true } } }
|
||||||
|
}>
|
||||||
|
|
||||||
|
const defaultLink = { provider: DownloadProvider.MEDIAFIRE, url: null, url2: null, directUrl: null }
|
||||||
|
const defaultSection: Download = { title: '', links: [defaultLink] }
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
defaultValue?: Download[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function DownloadSection(props: Props) {
|
||||||
|
const { defaultValue = [defaultSection] } = props
|
||||||
|
const [downloads, setDownloads] = useImmer<Download[]>(defaultValue)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className='flex gap-x-2'>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
setDownloads((current) => {
|
||||||
|
current.push(defaultSection)
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add download section
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-col gap-y-1.5'>
|
||||||
|
{downloads.map((d, index) => (
|
||||||
|
<div key={index} className='border-2 border-white/60 rounded-md p-2'>
|
||||||
|
<div>
|
||||||
|
<Input
|
||||||
|
dark
|
||||||
|
label='Title'
|
||||||
|
name={`downloads.${index}.title`}
|
||||||
|
value={d.title ?? ''}
|
||||||
|
onChange={(ev) => {
|
||||||
|
setDownloads((current) => {
|
||||||
|
current[index].title = ev.target.value
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{d.links.map((link, linkIndex) => (
|
||||||
|
<div key={linkIndex} className='flex'>
|
||||||
|
<div className='grid grid-cols-4 gap-4'>
|
||||||
|
<InputSelect
|
||||||
|
dark
|
||||||
|
name={`downloads.${index}.links.${linkIndex}.provider`}
|
||||||
|
label='Provider'
|
||||||
|
defaultValue={link.provider ?? ''}
|
||||||
|
>
|
||||||
|
{Object.values(DownloadProvider).map((provider) => (
|
||||||
|
<option key={provider} value={provider}>
|
||||||
|
{provider}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</InputSelect>
|
||||||
|
<Input
|
||||||
|
dark
|
||||||
|
label='Ouo.io (Url)'
|
||||||
|
name={`downloads.${index}.links.${linkIndex}.url`}
|
||||||
|
defaultValue={link.url ?? ''}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
dark
|
||||||
|
label='Fly.inc (Url 2)'
|
||||||
|
name={`downloads.${index}.links.${linkIndex}.url2`}
|
||||||
|
defaultValue={link.url2 ?? ''}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
dark
|
||||||
|
label='Direct'
|
||||||
|
name={`downloads.${index}.links.${linkIndex}.directUrl`}
|
||||||
|
defaultValue={link.directUrl ?? ''}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className='flex p-3'>
|
||||||
|
<Button
|
||||||
|
className='mt-auto bg-red-500 hover:bg-red-600'
|
||||||
|
onClick={() => {
|
||||||
|
setDownloads((current) => {
|
||||||
|
current[index].links.splice(linkIndex, 1)
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
X
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
<div className='flex gap-x-2'>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
setDownloads((current) => {
|
||||||
|
current[index].links.push(defaultLink)
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add link
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
setDownloads((current) => {
|
||||||
|
current.splice(index, 1)
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Remove section
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
73
src/components/adminAlbum/StoresSection.tsx
Normal file
73
src/components/adminAlbum/StoresSection.tsx
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
import { useImmer } from 'use-immer'
|
||||||
|
import type { Prisma } from '@prisma/client'
|
||||||
|
|
||||||
|
import Button from 'components/Button'
|
||||||
|
import { Input, InputSelect } from 'components/form/Input'
|
||||||
|
|
||||||
|
import { StoreProviders } from 'utils/consts'
|
||||||
|
|
||||||
|
type Store = Prisma.storesGetPayload<{ select: { url: true; provider: true } }>
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
defaultValue?: Store[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultStore: Store = { provider: StoreProviders.AMAZON, url: '' }
|
||||||
|
|
||||||
|
export default function StoresSection(props: Props) {
|
||||||
|
const { defaultValue = [defaultStore] } = props
|
||||||
|
const [stores, setStores] = useImmer<typeof defaultValue>(defaultValue)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className='flex gap-x-2'>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
setStores((current) => {
|
||||||
|
current.push(defaultStore)
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add store link
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-col gap-y-2.5'>
|
||||||
|
{stores.map((d, index) => (
|
||||||
|
<div key={index} className='flex gap-x-2 '>
|
||||||
|
<InputSelect dark name={`stores.${index}.provider`} label='Provider' defaultValue={d.provider ?? ''}>
|
||||||
|
{Object.values(StoreProviders).map((provider) => (
|
||||||
|
<option key={provider} value={provider}>
|
||||||
|
{provider}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</InputSelect>
|
||||||
|
|
||||||
|
<Input
|
||||||
|
dark
|
||||||
|
label='Url'
|
||||||
|
name={`stores.${index}.url`}
|
||||||
|
value={d.url ?? ''}
|
||||||
|
onChange={(ev) => {
|
||||||
|
setStores((current) => {
|
||||||
|
current[index].url = ev.target.value
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div className='flex py-3'>
|
||||||
|
<Button
|
||||||
|
className='mt-auto bg-red-500 hover:bg-red-600'
|
||||||
|
onClick={() => {
|
||||||
|
setStores((current) => {
|
||||||
|
current.splice(index, 1)
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
X
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
71
src/components/form/AsyncMultiSelect.tsx
Normal file
71
src/components/form/AsyncMultiSelect.tsx
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import { MultiSelect, type Option } from 'react-multi-select-component'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
url: string
|
||||||
|
nameColumn: string
|
||||||
|
className?: string
|
||||||
|
valueColumn?: string
|
||||||
|
defaultSelected?: Option[]
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
function toMapValue(data: any[], nameColumn: string, valueColumn: string) {
|
||||||
|
return data.map((item: { [nameColumn]: string; [valueColumn]: string }) => ({
|
||||||
|
label: item[nameColumn],
|
||||||
|
value: item[valueColumn]
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function AsyncMultiSelect(props: Props) {
|
||||||
|
const { url: defaultUrl, nameColumn, valueColumn = 'id', className, defaultSelected = [], name } = props
|
||||||
|
const [url, setUrl] = useState(defaultUrl)
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [selected, setSelected] = useState<Option[]>(defaultSelected)
|
||||||
|
const [options, setOptions] = useState<Option[]>(defaultSelected)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
async function fetchData() {
|
||||||
|
try {
|
||||||
|
setLoading(true)
|
||||||
|
const res = await fetch(url)
|
||||||
|
if (!res.ok) return
|
||||||
|
|
||||||
|
const data = await res.json()
|
||||||
|
const dataOptions = toMapValue(data, nameColumn, valueColumn)
|
||||||
|
|
||||||
|
setOptions([...defaultSelected, ...dataOptions])
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
} finally {
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchData()
|
||||||
|
}, [url])
|
||||||
|
|
||||||
|
function filterOptions(options: Option[], search: string) {
|
||||||
|
if (search.length === 0) setUrl(defaultUrl)
|
||||||
|
else setUrl(`${defaultUrl}?q=${search}`)
|
||||||
|
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<MultiSelect
|
||||||
|
labelledBy={name}
|
||||||
|
isLoading={loading}
|
||||||
|
options={options}
|
||||||
|
value={selected}
|
||||||
|
onChange={setSelected}
|
||||||
|
filterOptions={filterOptions}
|
||||||
|
className={className}
|
||||||
|
/>
|
||||||
|
{selected.map((s, i) => (
|
||||||
|
<input key={i} hidden name={`${name}.${i}`} value={s.value} readOnly />
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -1,15 +1,67 @@
|
||||||
import type { ComponentProps, PropsWithChildren } from 'react'
|
import type { ComponentProps, PropsWithChildren } from 'react'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
|
|
||||||
export default function Input(props: PropsWithChildren<ComponentProps<'input'>>) {
|
export function InputLabel(props: PropsWithChildren<{ dark: boolean; name: string }>) {
|
||||||
const { name, className, children, ...attrs } = props
|
const { dark, name, children } = props
|
||||||
|
return (
|
||||||
|
<label htmlFor={name} className={clsx('font-medium', dark ? 'text-white' : 'text-black')}>
|
||||||
|
{children}:
|
||||||
|
</label>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CustomInputProps {
|
||||||
|
name: string
|
||||||
|
label: string
|
||||||
|
dark?: boolean
|
||||||
|
defaultValue?: string | number | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Input(props: CustomInputProps & Omit<ComponentProps<'input'>, 'defaultValue'>) {
|
||||||
|
const { name, className, dark = false, defaultValue, label, ...attrs } = props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col'>
|
<div className={clsx('flex flex-col', className)}>
|
||||||
<label htmlFor={name} className='font-medium text-black'>
|
<InputLabel dark={dark} name={name}>
|
||||||
{children}:
|
{label}
|
||||||
</label>
|
</InputLabel>
|
||||||
<input {...attrs} name={name} className={clsx('bg-zinc-200 rounded-md p-2 mt-2 mb-3 text-black', className)} />
|
<input
|
||||||
|
{...attrs}
|
||||||
|
defaultValue={defaultValue ?? undefined}
|
||||||
|
name={name}
|
||||||
|
className='bg-zinc-200 rounded-md p-2 mt-2 mb-3 text-black'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function InputArea(props: CustomInputProps & Omit<ComponentProps<'textarea'>, 'defaultValue'>) {
|
||||||
|
const { name, className, dark = false, defaultValue, label, ...attrs } = props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={clsx('flex flex-col', className)}>
|
||||||
|
<InputLabel dark={dark} name={name}>
|
||||||
|
{label}
|
||||||
|
</InputLabel>
|
||||||
|
<textarea
|
||||||
|
{...attrs}
|
||||||
|
defaultValue={defaultValue ?? undefined}
|
||||||
|
name={name}
|
||||||
|
className='bg-zinc-200 rounded-md p-2 mt-2 mb-3 text-black'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function InputSelect(props: CustomInputProps & ComponentProps<'select'>) {
|
||||||
|
const { name, className, dark = false, label, ...attrs } = props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='flex flex-col'>
|
||||||
|
<InputLabel dark={dark} name={name}>
|
||||||
|
{label}
|
||||||
|
</InputLabel>
|
||||||
|
<select name={name} className='bg-zinc-200 rounded-md p-2 mt-2 h-full mb-3 text-black' {...attrs} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
21
src/components/form/MultiSelectWrapper.tsx
Normal file
21
src/components/form/MultiSelectWrapper.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { type SelectProps, type Option, MultiSelect } from 'react-multi-select-component'
|
||||||
|
|
||||||
|
interface Props extends Omit<SelectProps, 'value' | 'onChange'> {
|
||||||
|
name: string
|
||||||
|
defaultSelected?: Option[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function MultiSelectWrapper(props: Props) {
|
||||||
|
const { defaultSelected = [], name, ...rest } = props
|
||||||
|
const [selected, setSelected] = useState<Option[]>(defaultSelected)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<MultiSelect value={selected} onChange={setSelected} {...rest} />
|
||||||
|
{selected.map((s, i) => (
|
||||||
|
<input key={i} name={`${name}.${i}`} value={s.value} hidden readOnly />
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
import { useState, type FormEvent } from 'react'
|
import { useState, type FormEvent } from 'react'
|
||||||
import toast from 'react-hot-toast'
|
import toast from 'react-hot-toast'
|
||||||
|
|
||||||
import * as m from 'paraglide/messages.js'
|
import * as m from 'paraglide/messages.js'
|
||||||
|
|
||||||
import Button from 'components/Button'
|
import Button from 'components/Button'
|
||||||
import Modal from 'components/Modal'
|
import Modal from 'components/Modal'
|
||||||
import Input from 'components/form/Input'
|
import { Input } from 'components/form/Input'
|
||||||
|
|
||||||
import { signUp } from 'utils/auth-client'
|
import { signUp } from 'utils/auth-client'
|
||||||
|
|
||||||
export default function RegisterBtn() {
|
export default function RegisterBtn() {
|
||||||
|
|
@ -46,19 +47,11 @@ export default function RegisterBtn() {
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
<div className='px-4 pt-5 pb-4 gap-x-4 gap-y-1 flex flex-col'>
|
<div className='px-4 pt-5 pb-4 gap-x-4 gap-y-1 flex flex-col'>
|
||||||
<div className='flex gap-x-4'>
|
<div className='flex gap-x-4'>
|
||||||
<Input name='username' required>
|
<Input name='username' required label={m.username()} />
|
||||||
{m.username()}
|
<Input name='name' required label={m.displayName()} />
|
||||||
</Input>
|
|
||||||
<Input name='name' required>
|
|
||||||
{m.displayName()}
|
|
||||||
</Input>
|
|
||||||
</div>
|
</div>
|
||||||
<Input name='email' type='email' required>
|
<Input name='email' type='email' required label={m.email()} />
|
||||||
{m.email()}
|
<Input name='password' type='password' required label={m.password()} />
|
||||||
</Input>
|
|
||||||
<Input name='password' type='password' required>
|
|
||||||
{m.password()}
|
|
||||||
</Input>
|
|
||||||
<div className='mx-auto'>
|
<div className='mx-auto'>
|
||||||
<Button type='submit' loading={loading} disabled={loading}>
|
<Button type='submit' loading={loading} disabled={loading}>
|
||||||
{m.register()}
|
{m.register()}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { Prisma } from '@prisma/client'
|
import { Prisma } from '@prisma/client'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import prismaClient from 'utils/prisma-client'
|
import prismaClient from 'utils/prisma-client'
|
||||||
import { getImage } from 'astro:assets'
|
|
||||||
|
|
||||||
import { WEBHOOK_URL } from 'astro:env/server'
|
import { WEBHOOK_URL } from 'astro:env/server'
|
||||||
|
|
||||||
|
|
@ -13,29 +12,11 @@ type AlbumArtistNames = Prisma.albumsGetPayload<typeof albumArtistNames>
|
||||||
async function postWebhook(album: AlbumArtistNames, userText = '') {
|
async function postWebhook(album: AlbumArtistNames, userText = '') {
|
||||||
const url = `https://www.sittingonclouds.net/album/${album.id}`
|
const url = `https://www.sittingonclouds.net/album/${album.id}`
|
||||||
const content = `${url}${userText}`
|
const content = `${url}${userText}`
|
||||||
const artistNames = album.artists.map((a) => a.artist.name)
|
const payload = { content }
|
||||||
const coverImage = await getImage({
|
|
||||||
src: `https://cdn.sittingonclouds.net/album/${album.id}.png`,
|
|
||||||
height: 150,
|
|
||||||
width: 150
|
|
||||||
})
|
|
||||||
const embeds = [
|
|
||||||
{
|
|
||||||
title: album.title,
|
|
||||||
type: 'rich',
|
|
||||||
description: album.subTitle || artistNames.join(' - '),
|
|
||||||
url,
|
|
||||||
color: parseInt(album.headerColor.substring(1), 16),
|
|
||||||
thumbnail: { url: `https://www.sittingonclouds.net${coverImage.src}` }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
const payload = { content, embeds }
|
|
||||||
await axios.post(WEBHOOK_URL, payload)
|
await axios.post(WEBHOOK_URL, payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const requestPOST = (operation: string, body: any) => axios.post(`http://localhost:7001/${operation}`, body)
|
|
||||||
|
|
||||||
export async function handleComplete(album: AlbumArtistNames, requestId?: number) {
|
export async function handleComplete(album: AlbumArtistNames, requestId?: number) {
|
||||||
if (requestId) {
|
if (requestId) {
|
||||||
const request = await prismaClient.requests.findUnique({
|
const request = await prismaClient.requests.findUnique({
|
||||||
|
|
@ -44,7 +25,7 @@ export async function handleComplete(album: AlbumArtistNames, requestId?: number
|
||||||
})
|
})
|
||||||
if (!request || request.state === 'complete') return
|
if (!request || request.state === 'complete') return
|
||||||
|
|
||||||
await requestPOST('complete', { requestId: request.id })
|
await fetch('http://localhost:7001/complete', { method: 'POST', body: JSON.stringify({ requestId: request.id }) })
|
||||||
|
|
||||||
const userText =
|
const userText =
|
||||||
request.userID || request.user
|
request.userID || request.user
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ interface Props {
|
||||||
|
|
||||||
import Base from './base.astro'
|
import Base from './base.astro'
|
||||||
import AlbumBox from 'components/AlbumBox.astro'
|
import AlbumBox from 'components/AlbumBox.astro'
|
||||||
|
import DefaultSEO from 'components/DefaultSEO.astro'
|
||||||
import FooterNav from 'components/lastAdded/FooterNav.astro'
|
import FooterNav from 'components/lastAdded/FooterNav.astro'
|
||||||
|
|
||||||
const { albums, limitMD, limitXS, ...listProps } = Astro.props
|
const { albums, limitMD, limitXS, ...listProps } = Astro.props
|
||||||
|
|
@ -18,6 +19,7 @@ if (albums.length === 0) {
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
|
||||||
|
<DefaultSEO />
|
||||||
<Base>
|
<Base>
|
||||||
<div class='flex flex-col w-full'>
|
<div class='flex flex-col w-full'>
|
||||||
<div class='w-full min-h-100vh mx-auto max-w-[1140px]'>
|
<div class='w-full min-h-100vh mx-auto max-w-[1140px]'>
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,6 @@ import 'styles/global.css'
|
||||||
|
|
||||||
<html lang={languageTag()} dir={Astro.locals.paraglide.dir} class='h-full'>
|
<html lang={languageTag()} dir={Astro.locals.paraglide.dir} class='h-full'>
|
||||||
<head>
|
<head>
|
||||||
<title>Sitting on Clouds</title>
|
|
||||||
<meta property='og:type' content='website' />
|
|
||||||
<meta property='og:site_name' content='Sitting on Clouds' />
|
|
||||||
|
|
||||||
<link rel='preconnect' href='https://fonts.googleapis.com' />
|
<link rel='preconnect' href='https://fonts.googleapis.com' />
|
||||||
<link rel='preconnect' href='https://fonts.gstatic.com' crossorigin />
|
<link rel='preconnect' href='https://fonts.gstatic.com' crossorigin />
|
||||||
<link
|
<link
|
||||||
|
|
@ -21,12 +17,7 @@ import 'styles/global.css'
|
||||||
rel='stylesheet'
|
rel='stylesheet'
|
||||||
/>
|
/>
|
||||||
<meta name='viewport' content='width=device-width, initial-scale=1.0' />
|
<meta name='viewport' content='width=device-width, initial-scale=1.0' />
|
||||||
|
<slot name='head' />
|
||||||
<meta name='theme-color' content='#ffffff' />
|
|
||||||
<meta property='og:url' content='/' />
|
|
||||||
<meta property='og:title' content='Sitting on Clouds — High Quality soundtrack library' />
|
|
||||||
<meta property='og:description' content='Largest Video Game & Animation Soundtrack サウンドトラック Archive' />
|
|
||||||
<meta property='og:image' content='/img/assets/clouds_thumb.png' />
|
|
||||||
<meta name='generator' content={Astro.generator} />
|
<meta name='generator' content={Astro.generator} />
|
||||||
<meta charset='utf-8' />
|
<meta charset='utf-8' />
|
||||||
|
|
||||||
|
|
|
||||||
219
src/pages/admin/album/[id].astro
Normal file
219
src/pages/admin/album/[id].astro
Normal file
|
|
@ -0,0 +1,219 @@
|
||||||
|
---
|
||||||
|
import { AlbumStatus } from '@prisma/client'
|
||||||
|
import prismaClient from 'utils/prisma-client'
|
||||||
|
|
||||||
|
import Base from 'layouts/base.astro'
|
||||||
|
import DiscSection from 'components/adminAlbum/DiscSection'
|
||||||
|
import DownloadSections from 'components/adminAlbum/DownloadSections'
|
||||||
|
import AsyncMultiSelect from 'components/form/AsyncMultiSelect'
|
||||||
|
import { Input, InputArea, InputLabel, InputSelect } from 'components/form/Input'
|
||||||
|
import Button from 'components/Button'
|
||||||
|
import MultiSelectWrapper from 'components/form/MultiSelectWrapper'
|
||||||
|
import StoresSection from 'components/adminAlbum/StoresSection'
|
||||||
|
import DefaultSEO from 'components/DefaultSEO.astro'
|
||||||
|
|
||||||
|
const { user, permissions } = Astro.locals
|
||||||
|
if (!user || !permissions.includes('UPDATE')) return Astro.redirect('/404')
|
||||||
|
|
||||||
|
const albumId = parseInt(Astro.params.id as string)
|
||||||
|
const album = await prismaClient.albums.findUnique({
|
||||||
|
where: { id: albumId },
|
||||||
|
include: {
|
||||||
|
categories: true,
|
||||||
|
classifications: true,
|
||||||
|
platforms: { select: { platform: { select: { id: true, name: true } } } },
|
||||||
|
games: { select: { game: { select: { slug: true, name: true } } } },
|
||||||
|
animations: { select: { animation: { select: { id: true, title: true } } } },
|
||||||
|
artists: { select: { artist: { select: { name: true } } } },
|
||||||
|
relatedAlbums: {
|
||||||
|
select: {
|
||||||
|
relatedAlbum: { select: { id: true, title: true } }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
stores: { select: { provider: true, url: true } },
|
||||||
|
downloads: {
|
||||||
|
select: { title: true, links: { select: { provider: true, url: true, url2: true, directUrl: true } } }
|
||||||
|
},
|
||||||
|
discs: { select: { number: true, body: true } }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!album) {
|
||||||
|
return Astro.redirect('/404')
|
||||||
|
}
|
||||||
|
---
|
||||||
|
|
||||||
|
<style>
|
||||||
|
hr {
|
||||||
|
margin-block: calc(var(--spacing) * 2);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import toast from 'react-hot-toast'
|
||||||
|
|
||||||
|
document.getElementById('editAlbum')?.addEventListener('submit', async (e: SubmitEvent) => {
|
||||||
|
e.preventDefault()
|
||||||
|
const formData = new FormData(e.target as HTMLFormElement)
|
||||||
|
|
||||||
|
document.getElementById('editAlbumSubmit')?.classList.add('loading')
|
||||||
|
const response = await fetch('/api/album/edit', { method: 'POST', body: formData })
|
||||||
|
document.getElementById('editAlbumSubmit')?.classList.remove('loading')
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
toast.success('Album updated successfully')
|
||||||
|
} else {
|
||||||
|
toast.error(response.statusText)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<DefaultSEO />
|
||||||
|
<Base>
|
||||||
|
<div class='flex flex-col w-full'>
|
||||||
|
<div class='w-full min-h-100vh mx-auto max-w-[1140px]'>
|
||||||
|
<form id='editAlbum' class='my-4 p-4 bg-dark rounded-md mx-2 flex gap-y-2 flex-col'>
|
||||||
|
<input hidden readonly name='albumId' value={album.id} type='number' />
|
||||||
|
<div class='grid grid-cols-4 gap-x-4 gap-y-1'>
|
||||||
|
<Input dark defaultValue={album.title} name='title' label='Title' className='col-span-2' />
|
||||||
|
<Input dark defaultValue={album.subTitle} name='subTitle' label='Subtitle' className='col-span-2' />
|
||||||
|
|
||||||
|
<Input dark defaultValue={album.description} name='description' label='Description' className='col-span-3' />
|
||||||
|
<Input dark name='cover' label='Cover image' type='file' />
|
||||||
|
|
||||||
|
<InputSelect dark name='status' label='Status' value={album.status}>
|
||||||
|
<option value={AlbumStatus.HIDDEN}>Hidden</option>
|
||||||
|
<option value={AlbumStatus.SHOW}>Show</option>
|
||||||
|
</InputSelect>
|
||||||
|
<Input
|
||||||
|
dark
|
||||||
|
defaultValue={album.releaseDate?.toISOString().slice(0, 10)}
|
||||||
|
name='releaseDate'
|
||||||
|
type='date'
|
||||||
|
label='Release Date'
|
||||||
|
/>
|
||||||
|
<Input dark defaultValue={album.label} name='label' label='Label' />
|
||||||
|
<Input dark defaultValue={album.vgmdb} name='vgmdb' label='VGMDB' />
|
||||||
|
|
||||||
|
<InputArea
|
||||||
|
dark
|
||||||
|
defaultValue={album.artists.map((a) => a.artist.name).join(', ')}
|
||||||
|
name='artists'
|
||||||
|
label='Artists'
|
||||||
|
className='col-span-3'
|
||||||
|
/>
|
||||||
|
<div class='flex flex-col'>
|
||||||
|
<InputLabel dark name='classifications'>Classifications</InputLabel>
|
||||||
|
<MultiSelectWrapper
|
||||||
|
client:only='react'
|
||||||
|
name='classifications'
|
||||||
|
options={[
|
||||||
|
{ value: 'Arrangement', label: 'Arrangement' },
|
||||||
|
{ value: 'Drama', label: 'Drama' },
|
||||||
|
{ value: 'GameRip', label: 'GameRip' },
|
||||||
|
{ value: 'Live Event', label: 'Live Event' },
|
||||||
|
{ value: 'Original Soundtrack', label: 'Original Soundtrack' },
|
||||||
|
{ value: 'Vocal', label: 'Vocal' }
|
||||||
|
]}
|
||||||
|
defaultSelected={album.classifications?.map(({ classificationName }) => ({
|
||||||
|
value: classificationName,
|
||||||
|
label: classificationName
|
||||||
|
})) || []}
|
||||||
|
labelledBy='classifications'
|
||||||
|
className='rounded-md py-2 h-full'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class='flex flex-col'>
|
||||||
|
<InputLabel dark name='categories'>Categories</InputLabel>
|
||||||
|
<MultiSelectWrapper
|
||||||
|
client:only='react'
|
||||||
|
options={[
|
||||||
|
{ value: 'Game', label: 'Game' },
|
||||||
|
{ value: 'Animation', label: 'Animation' }
|
||||||
|
]}
|
||||||
|
name='categories'
|
||||||
|
defaultSelected={album.categories?.map(({ categoryName }) => ({
|
||||||
|
value: categoryName,
|
||||||
|
label: categoryName
|
||||||
|
})) || []}
|
||||||
|
labelledBy='categories'
|
||||||
|
className='rounded-md py-2 h-full'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class='flex flex-col'>
|
||||||
|
<InputLabel dark name='platforms'>Platforms</InputLabel>
|
||||||
|
<AsyncMultiSelect
|
||||||
|
client:only='react'
|
||||||
|
name='platforms'
|
||||||
|
url='/api/platform/find'
|
||||||
|
nameColumn='name'
|
||||||
|
defaultSelected={album.platforms?.map((p) => ({
|
||||||
|
value: p.platform.id,
|
||||||
|
label: p.platform.name as string
|
||||||
|
})) || []}
|
||||||
|
className='rounded-md py-2 h-full'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='flex flex-col'>
|
||||||
|
<InputLabel dark name='games'>Games</InputLabel>
|
||||||
|
<AsyncMultiSelect
|
||||||
|
client:only='react'
|
||||||
|
name='games'
|
||||||
|
url='/api/game/find'
|
||||||
|
valueColumn='slug'
|
||||||
|
nameColumn='name'
|
||||||
|
defaultSelected={album.games?.map((g) => ({
|
||||||
|
value: g.game.slug,
|
||||||
|
label: g.game.name as string
|
||||||
|
})) || []}
|
||||||
|
className='rounded-md py-2 h-full'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class='flex flex-col'>
|
||||||
|
<InputLabel dark name='animations'>Animations</InputLabel>
|
||||||
|
<AsyncMultiSelect
|
||||||
|
client:only='react'
|
||||||
|
name='animations'
|
||||||
|
url='/api/anim/find'
|
||||||
|
nameColumn='title'
|
||||||
|
defaultSelected={album.animations?.map((g) => ({
|
||||||
|
value: g.animation.id,
|
||||||
|
label: g.animation.title as string
|
||||||
|
})) || []}
|
||||||
|
className='rounded-md py-2 h-full'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class='flex flex-col'>
|
||||||
|
<InputLabel dark name='related'>Related albums</InputLabel>
|
||||||
|
<AsyncMultiSelect
|
||||||
|
client:only='react'
|
||||||
|
name='related'
|
||||||
|
url='/api/album/find'
|
||||||
|
nameColumn='title'
|
||||||
|
defaultSelected={album.relatedAlbums?.map((g) => ({
|
||||||
|
value: g.relatedAlbum.id,
|
||||||
|
label: g.relatedAlbum.title as string
|
||||||
|
})) || []}
|
||||||
|
className='rounded-md py-2 h-full'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<StoresSection client:only='react' defaultValue={album.stores} />
|
||||||
|
<hr />
|
||||||
|
<div class='flex flex-col gap-y-4'>
|
||||||
|
<DiscSection client:only='react' defaultValue={album.discs} />
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<div class='flex flex-col gap-y-4'>
|
||||||
|
<DownloadSections client:only='react' defaultValue={album.downloads} />
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<div class=''>
|
||||||
|
<Button type='submit' id='editAlbumSubmit'>Save changes</Button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Base>
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
---
|
---
|
||||||
import prismaClient from 'utils/prisma-client'
|
import prismaClient from 'utils/prisma-client'
|
||||||
import * as m from 'paraglide/messages'
|
import * as m from 'paraglide/messages'
|
||||||
import { Image } from 'astro:assets'
|
import { getImage, Image } from 'astro:assets'
|
||||||
import { AlbumStatus } from '@prisma/client'
|
import { AlbumStatus } from '@prisma/client'
|
||||||
|
import { SEO } from 'astro-seo'
|
||||||
|
|
||||||
import BaseLayout from 'layouts/base.astro'
|
import BaseLayout from 'layouts/base.astro'
|
||||||
import TrackList from 'components/albumPage/TrackList'
|
import TrackList from 'components/albumPage/TrackList'
|
||||||
|
|
@ -47,7 +48,13 @@ if (!album) {
|
||||||
Astro.response.status = 404
|
Astro.response.status = 404
|
||||||
Astro.response.statusText = 'Not found'
|
Astro.response.statusText = 'Not found'
|
||||||
}
|
}
|
||||||
|
|
||||||
const { currentLocale } = Astro
|
const { currentLocale } = Astro
|
||||||
|
const coverImage = await getImage({
|
||||||
|
src: `https://cdn.sittingonclouds.net/album/${album?.id}.png`,
|
||||||
|
height: 150,
|
||||||
|
width: 150
|
||||||
|
})
|
||||||
---
|
---
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
@ -58,6 +65,27 @@ const { currentLocale } = Astro
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<SEO
|
||||||
|
slot='head'
|
||||||
|
titleDefault='Sitting on Clouds'
|
||||||
|
title={album?.title ?? undefined}
|
||||||
|
description='Largest Video Game & Animation Soundtrack サウンドトラック Archive'
|
||||||
|
openGraph={{
|
||||||
|
basic: {
|
||||||
|
title: album?.title ?? '',
|
||||||
|
type: 'website',
|
||||||
|
image: `https://www.sittingonclouds.net${coverImage.src}`,
|
||||||
|
url: Astro.url.pathname
|
||||||
|
},
|
||||||
|
optional: {
|
||||||
|
description: album?.subTitle || album?.artists.map((a) => a.artist.name).join(' - '),
|
||||||
|
siteName: 'Sitting on Clouds'
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
extend={{
|
||||||
|
meta: [{ name: 'theme-color', content: album?.headerColor }]
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<BaseLayout>
|
<BaseLayout>
|
||||||
<div
|
<div
|
||||||
class={`w-full min-h-100vh bg-fixed bg-center bg-cover`}
|
class={`w-full min-h-100vh bg-fixed bg-center bg-cover`}
|
||||||
|
|
@ -286,13 +314,13 @@ const { currentLocale } = Astro
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{url2 && (
|
{url2 && (
|
||||||
<DownloadBtn href={url2} alt='fly' icon={flyIcon}>
|
<DownloadBtn href={url2} alt='fly inc' icon={flyIcon}>
|
||||||
{m.flyInc()}
|
Fly.inc
|
||||||
</DownloadBtn>
|
</DownloadBtn>
|
||||||
)}
|
)}
|
||||||
{url ? (
|
{url ? (
|
||||||
<DownloadBtn href={url} alt='ouo' icon={ouoIcon}>
|
<DownloadBtn href={url} alt='ouo' icon={ouoIcon}>
|
||||||
{m.ouoIO()}
|
ouo.io
|
||||||
</DownloadBtn>
|
</DownloadBtn>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import prismaClient from 'utils/prisma-client'
|
||||||
import BaseLayout from 'layouts/base.astro'
|
import BaseLayout from 'layouts/base.astro'
|
||||||
import Sidebar from 'components/Sidebar.astro'
|
import Sidebar from 'components/Sidebar.astro'
|
||||||
import LetterSection from 'components/albumList/letterSection.astro'
|
import LetterSection from 'components/albumList/letterSection.astro'
|
||||||
|
import DefaultSEO from 'components/DefaultSEO.astro'
|
||||||
|
|
||||||
const letters: { letter: string; count: BigInt }[] = await prismaClient.$queryRaw`
|
const letters: { letter: string; count: BigInt }[] = await prismaClient.$queryRaw`
|
||||||
SELECT DISTINCT UPPER(LEFT(title, 1)) AS letter, COUNT(*) AS count
|
SELECT DISTINCT UPPER(LEFT(title, 1)) AS letter, COUNT(*) AS count
|
||||||
|
|
@ -14,6 +15,7 @@ const letters: { letter: string; count: BigInt }[] = await prismaClient.$queryRa
|
||||||
`
|
`
|
||||||
---
|
---
|
||||||
|
|
||||||
|
<DefaultSEO />
|
||||||
<BaseLayout>
|
<BaseLayout>
|
||||||
<div class='flex flex-col md:flex-row flex-1 max-w-[2000px]'>
|
<div class='flex flex-col md:flex-row flex-1 max-w-[2000px]'>
|
||||||
<div class='flex-1 px-5 bg-dark'>
|
<div class='flex-1 px-5 bg-dark'>
|
||||||
|
|
@ -38,11 +40,11 @@ const letters: { letter: string; count: BigInt }[] = await prismaClient.$queryRa
|
||||||
<div class='flex uppercase border-y-2 text-4xl justify-center border-white py-1.5'>{l.letter}</div>
|
<div class='flex uppercase border-y-2 text-4xl justify-center border-white py-1.5'>{l.letter}</div>
|
||||||
<div class='my-4'>
|
<div class='my-4'>
|
||||||
<LetterSection letter={l.letter} server:defer>
|
<LetterSection letter={l.letter} server:defer>
|
||||||
<Fragment slot="fallback">
|
<Fragment slot='fallback'>
|
||||||
<div class='flex flex-col gap-y-2'>
|
<div class='flex flex-col gap-y-2'>
|
||||||
{Array.from({ length: Number(l.count) }).map(() => (
|
{Array.from({ length: Number(l.count) }).map(() => (
|
||||||
<div class='animate-pulse h-3.5 w-lg bg-gray/85' />
|
<div class='animate-pulse h-3.5 w-lg bg-gray/85' />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
</LetterSection>
|
</LetterSection>
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,21 @@
|
||||||
import type { APIRoute } from 'astro'
|
import type { APIRoute } from 'astro'
|
||||||
import * as s from 'superstruct'
|
import * as s from 'superstruct'
|
||||||
import prismaClient from 'utils/prisma-client'
|
import prismaClient from 'utils/prisma-client'
|
||||||
|
|
||||||
import { AlbumStatus } from '@prisma/client'
|
import { AlbumStatus } from '@prisma/client'
|
||||||
|
|
||||||
import { Status, parseForm, slug } from 'utils/form'
|
import { Status, parseForm, slug } from 'utils/form'
|
||||||
import { writeImg, getImgColor } from 'utils/img'
|
import { handleCover } from 'utils/img'
|
||||||
import { handleComplete } from 'integrations/requestCat'
|
import { handleComplete } from 'integrations/requestCat'
|
||||||
import { CreateAlbum } from 'schemas/album'
|
import { AlbumBase } from 'schemas/album'
|
||||||
|
|
||||||
export const POST: APIRoute = async ({ request, locals }) => {
|
export const POST: APIRoute = async ({ request, locals }) => {
|
||||||
const { session, permissions, user } = locals
|
const { permissions, user } = locals
|
||||||
|
if (!user || !permissions.includes('CREATE')) return Status(403)
|
||||||
if (!session || !user) return Status(401)
|
|
||||||
if (!permissions.includes('CREATE')) return Status(403)
|
|
||||||
|
|
||||||
let body
|
let body
|
||||||
try {
|
try {
|
||||||
const formData = await parseForm(request)
|
const formData = await parseForm(await request.formData())
|
||||||
body = s.create(formData, CreateAlbum)
|
body = s.create(formData, AlbumBase)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return Status(422, (err as Error).message)
|
return Status(422, (err as Error).message)
|
||||||
}
|
}
|
||||||
|
|
@ -58,21 +56,13 @@ export const POST: APIRoute = async ({ request, locals }) => {
|
||||||
include: { artists: { include: { artist: { select: { name: true } } } } }
|
include: { artists: { include: { artist: { select: { name: true } } } } }
|
||||||
})
|
})
|
||||||
|
|
||||||
const handleCover = async () => {
|
|
||||||
const coverPath = await writeImg(body.cover, 'album', albumRow.id)
|
|
||||||
const headerColor = await getImgColor(coverPath)
|
|
||||||
await tx.albums.update({ where: { id: albumRow.id }, data: { headerColor } })
|
|
||||||
albumRow.headerColor = headerColor
|
|
||||||
}
|
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
handleCover(),
|
handleCover(body.cover, 'album', albumRow.id, tx),
|
||||||
Promise.all(
|
Promise.all(
|
||||||
body.downloads.map((d) =>
|
body.downloads.map((d) =>
|
||||||
tx.downloads.create({
|
tx.downloads.create({
|
||||||
data: {
|
data: {
|
||||||
title: d.title,
|
title: d.title,
|
||||||
small: d.small,
|
|
||||||
albumId: albumRow.id,
|
albumId: albumRow.id,
|
||||||
links: { create: d.links }
|
links: { create: d.links }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
87
src/pages/api/album/edit.ts
Normal file
87
src/pages/api/album/edit.ts
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
import type { APIRoute } from 'astro'
|
||||||
|
import * as s from 'superstruct'
|
||||||
|
import prismaClient from 'utils/prisma-client'
|
||||||
|
|
||||||
|
import { Status, parseForm, slug } from 'utils/form'
|
||||||
|
import { handleCover } from 'utils/img'
|
||||||
|
import { EditAlbum } from 'schemas/album'
|
||||||
|
|
||||||
|
export const POST: APIRoute = async ({ request, locals }) => {
|
||||||
|
const { permissions, user } = locals
|
||||||
|
if (!user || !permissions.includes('UPDATE')) return Status(403)
|
||||||
|
|
||||||
|
let body
|
||||||
|
try {
|
||||||
|
const formData = await parseForm(await request.formData())
|
||||||
|
body = s.create(formData, EditAlbum)
|
||||||
|
} catch (err) {
|
||||||
|
return Status(422, (err as Error).message)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await prismaClient.$transaction(async (tx) => {
|
||||||
|
const {
|
||||||
|
artists,
|
||||||
|
animations,
|
||||||
|
categories,
|
||||||
|
classifications,
|
||||||
|
games,
|
||||||
|
platforms,
|
||||||
|
discs,
|
||||||
|
downloads,
|
||||||
|
stores,
|
||||||
|
cover,
|
||||||
|
related,
|
||||||
|
albumId,
|
||||||
|
...rest
|
||||||
|
} = body
|
||||||
|
|
||||||
|
await tx.albums.update({
|
||||||
|
where: { id: body.albumId },
|
||||||
|
data: {
|
||||||
|
...rest,
|
||||||
|
artists: {
|
||||||
|
deleteMany: {},
|
||||||
|
create: artists
|
||||||
|
?.split(',')
|
||||||
|
.map((name: string) => ({ slug: slug(name.trim()), name: name.trim() }))
|
||||||
|
.map((a) => ({
|
||||||
|
artist: {
|
||||||
|
connectOrCreate: {
|
||||||
|
create: a,
|
||||||
|
where: { slug: a.slug }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
animations: { deleteMany: {}, create: animations?.map((id) => ({ animation: { connect: { id } } })) },
|
||||||
|
categories: { deleteMany: {}, create: categories?.map((c) => ({ category: { connect: { name: c } } })) },
|
||||||
|
games: { deleteMany: {}, create: games?.map((slug) => ({ game: { connect: { slug } } })) },
|
||||||
|
platforms: { deleteMany: {}, create: platforms?.map((id) => ({ platform: { connect: { id } } })) },
|
||||||
|
discs: { deleteMany: {}, createMany: { data: body.discs ?? [] } },
|
||||||
|
relatedAlbums: { deleteMany: {}, create: related?.map((id) => ({ relatedAlbum: { connect: { id } } })) }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
cover ? handleCover(cover, 'album', albumId, tx) : undefined,
|
||||||
|
downloads
|
||||||
|
? tx.downloads.createMany({
|
||||||
|
data: downloads.map((d) => ({
|
||||||
|
title: d.title,
|
||||||
|
albumId: albumId,
|
||||||
|
links: { create: d.links }
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
: undefined
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
// if (albumRow.status === AlbumStatus.SHOW) await handleComplete(albumRow, body.request)
|
||||||
|
|
||||||
|
return Status(200, body.albumId.toString())
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
return Status(500, (err as Error).message)
|
||||||
|
}
|
||||||
|
}
|
||||||
23
src/pages/api/album/find.ts
Normal file
23
src/pages/api/album/find.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
import type { APIRoute } from 'astro'
|
||||||
|
import prismaClient from 'utils/prisma-client'
|
||||||
|
|
||||||
|
export const GET: APIRoute = async (context) => {
|
||||||
|
const { url } = context
|
||||||
|
const titleParam = url.searchParams.get('q')
|
||||||
|
|
||||||
|
const anims = await prismaClient.albums.findMany({
|
||||||
|
where: titleParam
|
||||||
|
? { OR: [{ title: { contains: titleParam } }, { subTitle: { contains: titleParam } }] }
|
||||||
|
: undefined,
|
||||||
|
select: { id: true, title: true },
|
||||||
|
take: 10,
|
||||||
|
orderBy: { createdAt: 'desc' }
|
||||||
|
})
|
||||||
|
|
||||||
|
return new Response(JSON.stringify(anims), {
|
||||||
|
status: 200,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
21
src/pages/api/anim/find.ts
Normal file
21
src/pages/api/anim/find.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
import type { APIRoute } from 'astro'
|
||||||
|
import prismaClient from 'utils/prisma-client'
|
||||||
|
|
||||||
|
export const GET: APIRoute = async (context) => {
|
||||||
|
const { url } = context
|
||||||
|
const titleParam = url.searchParams.get('q')
|
||||||
|
|
||||||
|
const anims = await prismaClient.animation.findMany({
|
||||||
|
where: titleParam ? { title: { contains: titleParam } } : undefined,
|
||||||
|
select: { id: true, title: true },
|
||||||
|
take: 10,
|
||||||
|
orderBy: { createdAt: 'desc' }
|
||||||
|
})
|
||||||
|
|
||||||
|
return new Response(JSON.stringify(anims), {
|
||||||
|
status: 200,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
21
src/pages/api/game/find.ts
Normal file
21
src/pages/api/game/find.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
import type { APIRoute } from 'astro'
|
||||||
|
import prismaClient from 'utils/prisma-client'
|
||||||
|
|
||||||
|
export const GET: APIRoute = async (context) => {
|
||||||
|
const { url } = context
|
||||||
|
const titleParam = url.searchParams.get('q')
|
||||||
|
|
||||||
|
const anims = await prismaClient.game.findMany({
|
||||||
|
where: titleParam ? { name: { contains: titleParam } } : undefined,
|
||||||
|
select: { slug: true, name: true },
|
||||||
|
take: 10,
|
||||||
|
orderBy: { createdAt: 'desc' }
|
||||||
|
})
|
||||||
|
|
||||||
|
return new Response(JSON.stringify(anims), {
|
||||||
|
status: 200,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
21
src/pages/api/platform/find.ts
Normal file
21
src/pages/api/platform/find.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
import type { APIRoute } from 'astro'
|
||||||
|
import prismaClient from 'utils/prisma-client'
|
||||||
|
|
||||||
|
export const GET: APIRoute = async (context) => {
|
||||||
|
const { url } = context
|
||||||
|
const titleParam = url.searchParams.get('q')
|
||||||
|
|
||||||
|
const anims = await prismaClient.platform.findMany({
|
||||||
|
where: titleParam ? { name: { contains: titleParam } } : undefined,
|
||||||
|
select: { id: true, name: true },
|
||||||
|
take: 10,
|
||||||
|
orderBy: { createdAt: 'desc' }
|
||||||
|
})
|
||||||
|
|
||||||
|
return new Response(JSON.stringify(anims), {
|
||||||
|
status: 200,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
---
|
---
|
||||||
|
import DefaultSEO from 'components/DefaultSEO.astro'
|
||||||
import ForgorForm from 'components/form/ForgorForm'
|
import ForgorForm from 'components/form/ForgorForm'
|
||||||
import BaseLayout from 'layouts/base.astro'
|
import BaseLayout from 'layouts/base.astro'
|
||||||
|
|
||||||
|
|
@ -7,4 +8,5 @@ const token = Astro.url.searchParams.get('token')
|
||||||
if (!token) return Astro.redirect('/404')
|
if (!token) return Astro.redirect('/404')
|
||||||
---
|
---
|
||||||
|
|
||||||
|
<DefaultSEO />
|
||||||
<BaseLayout><ForgorForm token={token} client:only='react' /></BaseLayout>
|
<BaseLayout><ForgorForm token={token} client:only='react' /></BaseLayout>
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import * as s from 'superstruct'
|
import * as s from 'superstruct'
|
||||||
import { AlbumStatus } from '@prisma/client'
|
import { AlbumStatus } from '@prisma/client'
|
||||||
|
import { DownloadProvider } from 'utils/consts'
|
||||||
|
|
||||||
const LinkInput = s.object({
|
export const LinkInput = s.object({
|
||||||
provider: s.string(),
|
provider: s.enums(Object.values(DownloadProvider)),
|
||||||
custom: s.optional(s.string()),
|
|
||||||
url: s.optional(s.string()),
|
url: s.optional(s.string()),
|
||||||
url2: s.optional(s.string()),
|
url2: s.optional(s.string()),
|
||||||
directUrl: s.optional(s.string())
|
directUrl: s.optional(s.string())
|
||||||
|
|
@ -11,28 +11,36 @@ const LinkInput = s.object({
|
||||||
|
|
||||||
export const DownloadInput = s.object({
|
export const DownloadInput = s.object({
|
||||||
title: s.string(),
|
title: s.string(),
|
||||||
small: s.defaulted(s.boolean(), false),
|
|
||||||
links: s.defaulted(s.array(LinkInput), [])
|
links: s.defaulted(s.array(LinkInput), [])
|
||||||
})
|
})
|
||||||
|
|
||||||
export const CreateAlbum = s.object({
|
const coerceInt = s.coerce(s.integer(), s.string(), (value) => parseInt(value))
|
||||||
|
export const StoreInput = s.object({ provider: s.string(), url: s.string() })
|
||||||
|
export const DiscInput = s.object({ number: coerceInt, body: s.string() })
|
||||||
|
|
||||||
|
export const AlbumBase = s.object({
|
||||||
cover: s.instance(File),
|
cover: s.instance(File),
|
||||||
title: s.optional(s.string()),
|
title: s.optional(s.string()),
|
||||||
subTitle: s.optional(s.string()),
|
subTitle: s.optional(s.string()),
|
||||||
releaseDate: s.optional(s.string()),
|
releaseDate: s.optional(s.date()),
|
||||||
label: s.optional(s.string()),
|
label: s.optional(s.string()),
|
||||||
vgmdb: s.optional(s.string()),
|
vgmdb: s.optional(s.string()),
|
||||||
description: s.optional(s.string()),
|
description: s.optional(s.string()),
|
||||||
status: s.defaulted(s.enums(Object.values(AlbumStatus)), AlbumStatus.HIDDEN),
|
status: s.defaulted(s.enums(Object.values(AlbumStatus)), AlbumStatus.HIDDEN),
|
||||||
animations: s.defaulted(s.array(s.integer()), []),
|
animations: s.defaulted(s.array(coerceInt), []),
|
||||||
artists: s.defaulted(s.array(s.string()), []),
|
artists: s.defaulted(s.array(s.string()), []),
|
||||||
categories: s.defaulted(s.array(s.string()), []),
|
categories: s.defaulted(s.array(s.string()), []),
|
||||||
classifications: s.defaulted(s.array(s.string()), []),
|
classifications: s.defaulted(s.array(s.string()), []),
|
||||||
games: s.defaulted(s.array(s.string()), []),
|
games: s.defaulted(s.array(s.string()), []),
|
||||||
platforms: s.defaulted(s.array(s.integer()), []),
|
platforms: s.defaulted(s.array(coerceInt), []),
|
||||||
discs: s.defaulted(s.array(s.object({ number: s.integer(), body: s.string() })), []),
|
discs: s.defaulted(s.array(DiscInput), []),
|
||||||
downloads: s.defaulted(s.array(DownloadInput), []),
|
downloads: s.defaulted(s.array(DownloadInput), []),
|
||||||
related: s.defaulted(s.array(s.number()), []),
|
related: s.defaulted(s.array(coerceInt), []),
|
||||||
stores: s.defaulted(s.array(s.object({ provider: s.string(), url: s.string() })), []),
|
stores: s.defaulted(s.array(StoreInput), []),
|
||||||
request: s.optional(s.integer())
|
request: s.optional(coerceInt)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const EditAlbum = s.assign(
|
||||||
|
s.partial(AlbumBase),
|
||||||
|
s.object({ albumId: coerceInt, artists: s.optional(s.string()) })
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -42,4 +42,19 @@
|
||||||
color: var(--color-hover-link);
|
color: var(--color-hover-link);
|
||||||
text-decoration-line: underline;
|
text-decoration-line: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
option {
|
||||||
|
color: var(--color-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rmsc .select-item .item-renderer span,
|
||||||
|
.rmsc .dropdown-heading-value span {
|
||||||
|
color: var(--color-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rmsc svg.gray,
|
||||||
|
.rmsc svg.gray line {
|
||||||
|
fill: var(--color-dark);
|
||||||
|
color: var(--color-dark);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
22
src/utils/consts.ts
Normal file
22
src/utils/consts.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
export enum DownloadProvider {
|
||||||
|
MEGA = 'MEGA',
|
||||||
|
MEDIAFIRE = 'MEDIAFIRE',
|
||||||
|
RANOZ = 'RANOZ',
|
||||||
|
TERABOX = 'TERABOX',
|
||||||
|
MIRROR = 'MIRROR'
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum StoreProviders {
|
||||||
|
AMAZON = 'amazon',
|
||||||
|
AMAZON_JP = 'amazon_jp',
|
||||||
|
PLAY_ASIA = 'play_asia',
|
||||||
|
CD_JAPAN = 'cd_japan',
|
||||||
|
SPOTIFY = 'spotify',
|
||||||
|
GOOGLE_PLAY = 'google_play',
|
||||||
|
STEAM = 'steam',
|
||||||
|
MORA = 'mora',
|
||||||
|
APPLE_MUSIC = 'apple_music',
|
||||||
|
OTOTOY = 'ototoy',
|
||||||
|
BANDCAMP = 'bandcamp',
|
||||||
|
DEEZER = 'deezer'
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
import slugify from 'slugify'
|
import slugify from 'slugify'
|
||||||
|
import { decode } from 'decode-formdata'
|
||||||
|
|
||||||
export const Status = (status: number, statusText?: string) => new Response(null, { status, statusText })
|
export const Status = (status: number, statusText?: string) => new Response(null, { status, statusText })
|
||||||
export const slug = (text: string) => slugify(text, { lower: true, strict: true })
|
export const slug = (text: string) => slugify(text, { lower: true, strict: true })
|
||||||
|
|
||||||
function formToObject(formData: FormData) {
|
export function formToObject(formData: FormData) {
|
||||||
const object: Record<string, any> = {}
|
const object: Record<string, any> = {}
|
||||||
for (const entry of formData.entries()) {
|
for (const entry of formData.entries()) {
|
||||||
const [key, value] = entry
|
const [key, value] = entry
|
||||||
|
|
@ -13,13 +14,13 @@ function formToObject(formData: FormData) {
|
||||||
return object
|
return object
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function parseForm(request: Request) {
|
export async function parseForm(formData: FormData) {
|
||||||
const formData = await request.formData()
|
const formObject = decode(formData, {
|
||||||
const formObject = formToObject(formData)
|
arrays: ['animations', 'classifications', 'categories', 'platforms', 'related', 'games', 'downloads', 'discs'],
|
||||||
const { data: dataInput, ...rest } = formObject
|
dates: ['releaseDate']
|
||||||
|
})
|
||||||
|
|
||||||
const data = JSON.parse(dataInput)
|
return formObject
|
||||||
return { ...data, ...rest }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getRandom<T>(array: T[]): T {
|
export function getRandom<T>(array: T[]): T {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import path from 'node:path'
|
import path from 'node:path'
|
||||||
import fs from 'node:fs/promises'
|
import fs from 'node:fs/promises'
|
||||||
import sharp from 'sharp'
|
import sharp from 'sharp'
|
||||||
|
import type { PrismaClient } from '@prisma/client/extension'
|
||||||
|
|
||||||
function colorToHex(color: number) {
|
function colorToHex(color: number) {
|
||||||
const hexadecimal = color.toString(16)
|
const hexadecimal = color.toString(16)
|
||||||
|
|
@ -16,11 +17,27 @@ export async function writeImg(file: File, folder: string, id: number | string)
|
||||||
const fullPath = path.join(pathString, `${id}.png`)
|
const fullPath = path.join(pathString, `${id}.png`)
|
||||||
|
|
||||||
const fileArray = Buffer.from(await file.arrayBuffer())
|
const fileArray = Buffer.from(await file.arrayBuffer())
|
||||||
await fs.writeFile(fullPath, fileArray)
|
await fs.mkdir(pathString, { recursive: true })
|
||||||
|
|
||||||
|
if (await fs.stat(fullPath).catch(() => false)) {
|
||||||
|
await fs.rm(fullPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
await fs.writeFile(fullPath, fileArray)
|
||||||
return fullPath
|
return fullPath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function handleImg(file: File, folder: string, id: number | string) {
|
||||||
|
const coverPath = await writeImg(file, folder, id)
|
||||||
|
const headerColor = await getImgColor(coverPath)
|
||||||
|
return headerColor
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function handleCover(file: File, folder: string, id: number | string, tx: PrismaClient) {
|
||||||
|
const headerColor = await handleImg(file, folder, id)
|
||||||
|
await tx.albums.update({ where: { id: id }, data: { headerColor } })
|
||||||
|
}
|
||||||
|
|
||||||
export async function getImgColor(filePath: string) {
|
export async function getImgColor(filePath: string) {
|
||||||
const { dominant } = await sharp(filePath).stats()
|
const { dominant } = await sharp(filePath).stats()
|
||||||
const { r, g, b } = dominant
|
const { r, g, b } = dominant
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { PrismaClient } from '@prisma/client'
|
import { PrismaClient } from '@prisma/client'
|
||||||
|
|
||||||
const prismaClient = new PrismaClient()
|
const prismaClient = new PrismaClient({ log: ['error'] })
|
||||||
|
|
||||||
export default prismaClient
|
export default prismaClient
|
||||||
|
|
|
||||||
471
yarn.lock
471
yarn.lock
|
|
@ -23,6 +23,17 @@
|
||||||
resolved "https://registry.yarnpkg.com/@antfu/utils/-/utils-8.1.1.tgz#95b1947d292a9a2efffba2081796dcaa05ecedfb"
|
resolved "https://registry.yarnpkg.com/@antfu/utils/-/utils-8.1.1.tgz#95b1947d292a9a2efffba2081796dcaa05ecedfb"
|
||||||
integrity sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==
|
integrity sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==
|
||||||
|
|
||||||
|
"@astrojs/check@^0.5.4":
|
||||||
|
version "0.5.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/@astrojs/check/-/check-0.5.10.tgz#1e6aa4d2392bb34ae9938f894b6765bd858363b4"
|
||||||
|
integrity sha512-vliHXM9cu/viGeKiksUM4mXfO816ohWtawTl2ADPgTsd4nUMjFiyAl7xFZhF34yy4hq4qf7jvK1F2PlR3b5I5w==
|
||||||
|
dependencies:
|
||||||
|
"@astrojs/language-server" "^2.8.4"
|
||||||
|
chokidar "^3.5.3"
|
||||||
|
fast-glob "^3.3.1"
|
||||||
|
kleur "^4.1.5"
|
||||||
|
yargs "^17.7.2"
|
||||||
|
|
||||||
"@astrojs/compiler@^2.0.0", "@astrojs/compiler@^2.10.3":
|
"@astrojs/compiler@^2.0.0", "@astrojs/compiler@^2.10.3":
|
||||||
version "2.10.4"
|
version "2.10.4"
|
||||||
resolved "https://registry.yarnpkg.com/@astrojs/compiler/-/compiler-2.10.4.tgz#883e469600d06d101d77829c91c4215b270cd503"
|
resolved "https://registry.yarnpkg.com/@astrojs/compiler/-/compiler-2.10.4.tgz#883e469600d06d101d77829c91c4215b270cd503"
|
||||||
|
|
@ -33,6 +44,30 @@
|
||||||
resolved "https://registry.yarnpkg.com/@astrojs/internal-helpers/-/internal-helpers-0.5.1.tgz#c9253669cf9caea48744d27f5cc30a06eec8d3d9"
|
resolved "https://registry.yarnpkg.com/@astrojs/internal-helpers/-/internal-helpers-0.5.1.tgz#c9253669cf9caea48744d27f5cc30a06eec8d3d9"
|
||||||
integrity sha512-M7rAge1n2+aOSxNvKUFa0u/KFn0W+sZy7EW91KOSERotm2Ti8qs+1K0xx3zbOxtAVrmJb5/J98eohVvvEqtNkw==
|
integrity sha512-M7rAge1n2+aOSxNvKUFa0u/KFn0W+sZy7EW91KOSERotm2Ti8qs+1K0xx3zbOxtAVrmJb5/J98eohVvvEqtNkw==
|
||||||
|
|
||||||
|
"@astrojs/language-server@^2.8.4":
|
||||||
|
version "2.15.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@astrojs/language-server/-/language-server-2.15.4.tgz#9c2eeb64e4b9df9a52f19c6bfdce5397b8dba094"
|
||||||
|
integrity sha512-JivzASqTPR2bao9BWsSc/woPHH7OGSGc9aMxXL4U6egVTqBycB3ZHdBJPuOCVtcGLrzdWTosAqVPz1BVoxE0+A==
|
||||||
|
dependencies:
|
||||||
|
"@astrojs/compiler" "^2.10.3"
|
||||||
|
"@astrojs/yaml2ts" "^0.2.2"
|
||||||
|
"@jridgewell/sourcemap-codec" "^1.4.15"
|
||||||
|
"@volar/kit" "~2.4.7"
|
||||||
|
"@volar/language-core" "~2.4.7"
|
||||||
|
"@volar/language-server" "~2.4.7"
|
||||||
|
"@volar/language-service" "~2.4.7"
|
||||||
|
fast-glob "^3.2.12"
|
||||||
|
muggle-string "^0.4.1"
|
||||||
|
volar-service-css "0.0.62"
|
||||||
|
volar-service-emmet "0.0.62"
|
||||||
|
volar-service-html "0.0.62"
|
||||||
|
volar-service-prettier "0.0.62"
|
||||||
|
volar-service-typescript "0.0.62"
|
||||||
|
volar-service-typescript-twoslash-queries "0.0.62"
|
||||||
|
volar-service-yaml "0.0.62"
|
||||||
|
vscode-html-languageservice "^5.2.0"
|
||||||
|
vscode-uri "^3.0.8"
|
||||||
|
|
||||||
"@astrojs/markdown-remark@6.1.0":
|
"@astrojs/markdown-remark@6.1.0":
|
||||||
version "6.1.0"
|
version "6.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@astrojs/markdown-remark/-/markdown-remark-6.1.0.tgz#c451c4d802116d1b9aa1a22d71a672199318678d"
|
resolved "https://registry.yarnpkg.com/@astrojs/markdown-remark/-/markdown-remark-6.1.0.tgz#c451c4d802116d1b9aa1a22d71a672199318678d"
|
||||||
|
|
@ -104,6 +139,13 @@
|
||||||
is-wsl "^3.1.0"
|
is-wsl "^3.1.0"
|
||||||
which-pm-runs "^1.1.0"
|
which-pm-runs "^1.1.0"
|
||||||
|
|
||||||
|
"@astrojs/yaml2ts@^0.2.2":
|
||||||
|
version "0.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@astrojs/yaml2ts/-/yaml2ts-0.2.2.tgz#eabcb75a57a97c5a2f0422a0a03ca14f000f4f5e"
|
||||||
|
integrity sha512-GOfvSr5Nqy2z5XiwqTouBBpy5FyI6DEe+/g/Mk5am9SjILN1S5fOEvYK0GuWHg98yS/dobP4m8qyqw/URW35fQ==
|
||||||
|
dependencies:
|
||||||
|
yaml "^2.5.0"
|
||||||
|
|
||||||
"@babel/code-frame@^7.26.2":
|
"@babel/code-frame@^7.26.2":
|
||||||
version "7.26.2"
|
version "7.26.2"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85"
|
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85"
|
||||||
|
|
@ -276,6 +318,50 @@
|
||||||
resolved "https://registry.yarnpkg.com/@better-fetch/fetch/-/fetch-1.1.15.tgz#d4170657315191cf7b15ab93e0f103776ee9b9ad"
|
resolved "https://registry.yarnpkg.com/@better-fetch/fetch/-/fetch-1.1.15.tgz#d4170657315191cf7b15ab93e0f103776ee9b9ad"
|
||||||
integrity sha512-0Bl8YYj1f8qCTNHeSn5+1DWv2hy7rLBrQ8rS8Y9XYloiwZEfc3k4yspIG0llRxafxqhGCwlGRg+F8q1HZRCMXA==
|
integrity sha512-0Bl8YYj1f8qCTNHeSn5+1DWv2hy7rLBrQ8rS8Y9XYloiwZEfc3k4yspIG0llRxafxqhGCwlGRg+F8q1HZRCMXA==
|
||||||
|
|
||||||
|
"@emmetio/abbreviation@^2.3.3":
|
||||||
|
version "2.3.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@emmetio/abbreviation/-/abbreviation-2.3.3.tgz#ed2b88fe37b972292d6026c7c540aaf887cecb6e"
|
||||||
|
integrity sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA==
|
||||||
|
dependencies:
|
||||||
|
"@emmetio/scanner" "^1.0.4"
|
||||||
|
|
||||||
|
"@emmetio/css-abbreviation@^2.1.8":
|
||||||
|
version "2.1.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/@emmetio/css-abbreviation/-/css-abbreviation-2.1.8.tgz#b785313486eba6cb7eb623ad39378c4e1063dc00"
|
||||||
|
integrity sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw==
|
||||||
|
dependencies:
|
||||||
|
"@emmetio/scanner" "^1.0.4"
|
||||||
|
|
||||||
|
"@emmetio/css-parser@^0.4.0":
|
||||||
|
version "0.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@emmetio/css-parser/-/css-parser-0.4.0.tgz#96135093480c79703df0e4f178f7f8f2b669fbc2"
|
||||||
|
integrity sha512-z7wkxRSZgrQHXVzObGkXG+Vmj3uRlpM11oCZ9pbaz0nFejvCDmAiNDpY75+wgXOcffKpj4rzGtwGaZxfJKsJxw==
|
||||||
|
dependencies:
|
||||||
|
"@emmetio/stream-reader" "^2.2.0"
|
||||||
|
"@emmetio/stream-reader-utils" "^0.1.0"
|
||||||
|
|
||||||
|
"@emmetio/html-matcher@^1.3.0":
|
||||||
|
version "1.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@emmetio/html-matcher/-/html-matcher-1.3.0.tgz#43b7a71b91cdc511cb699cbe9c67bb5d4cab6754"
|
||||||
|
integrity sha512-NTbsvppE5eVyBMuyGfVu2CRrLvo7J4YHb6t9sBFLyY03WYhXET37qA4zOYUjBWFCRHO7pS1B9khERtY0f5JXPQ==
|
||||||
|
dependencies:
|
||||||
|
"@emmetio/scanner" "^1.0.0"
|
||||||
|
|
||||||
|
"@emmetio/scanner@^1.0.0", "@emmetio/scanner@^1.0.4":
|
||||||
|
version "1.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@emmetio/scanner/-/scanner-1.0.4.tgz#e9cdc67194fd91f8b7eb141014be4f2d086c15f1"
|
||||||
|
integrity sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA==
|
||||||
|
|
||||||
|
"@emmetio/stream-reader-utils@^0.1.0":
|
||||||
|
version "0.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@emmetio/stream-reader-utils/-/stream-reader-utils-0.1.0.tgz#244cb02c77ec2e74f78a9bd318218abc9c500a61"
|
||||||
|
integrity sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A==
|
||||||
|
|
||||||
|
"@emmetio/stream-reader@^2.2.0":
|
||||||
|
version "2.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@emmetio/stream-reader/-/stream-reader-2.2.0.tgz#46cffea119a0a003312a21c2d9b5628cb5fcd442"
|
||||||
|
integrity sha512-fXVXEyFA5Yv3M3n8sUGT7+fvecGrZP4k6FnWWMSZVQf69kAq0LLpaBQLGcPR30m3zMmKYhECP4k/ZkzvhEW5kw==
|
||||||
|
|
||||||
"@emnapi/runtime@^1.2.0":
|
"@emnapi/runtime@^1.2.0":
|
||||||
version "1.3.1"
|
version "1.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.3.1.tgz#0fcaa575afc31f455fd33534c19381cfce6c6f60"
|
resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.3.1.tgz#0fcaa575afc31f455fd33534c19381cfce6c6f60"
|
||||||
|
|
@ -949,7 +1035,7 @@
|
||||||
resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280"
|
resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280"
|
||||||
integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==
|
integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==
|
||||||
|
|
||||||
"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0":
|
"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15", "@jridgewell/sourcemap-codec@^1.5.0":
|
||||||
version "1.5.0"
|
version "1.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a"
|
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a"
|
||||||
integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
|
integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
|
||||||
|
|
@ -1981,6 +2067,79 @@
|
||||||
"@types/babel__core" "^7.20.5"
|
"@types/babel__core" "^7.20.5"
|
||||||
react-refresh "^0.14.2"
|
react-refresh "^0.14.2"
|
||||||
|
|
||||||
|
"@volar/kit@~2.4.7":
|
||||||
|
version "2.4.12"
|
||||||
|
resolved "https://registry.yarnpkg.com/@volar/kit/-/kit-2.4.12.tgz#26ee33aef0272757f9fe3b6da12279bf56cd9224"
|
||||||
|
integrity sha512-f9JE8oy9C2rBcCWxUYKUF23hOXz4mwgVXFjk7nHhxzplaoVjEOsKpBm8NI2nBH7Cwu8DRxDwBsbIxMl/8wlLxw==
|
||||||
|
dependencies:
|
||||||
|
"@volar/language-service" "2.4.12"
|
||||||
|
"@volar/typescript" "2.4.12"
|
||||||
|
typesafe-path "^0.2.2"
|
||||||
|
vscode-languageserver-textdocument "^1.0.11"
|
||||||
|
vscode-uri "^3.0.8"
|
||||||
|
|
||||||
|
"@volar/language-core@2.4.12", "@volar/language-core@~2.4.7":
|
||||||
|
version "2.4.12"
|
||||||
|
resolved "https://registry.yarnpkg.com/@volar/language-core/-/language-core-2.4.12.tgz#98c8424f8d81a9cad1760a587b1c6db27d05f0cc"
|
||||||
|
integrity sha512-RLrFdXEaQBWfSnYGVxvR2WrO6Bub0unkdHYIdC31HzIEqATIuuhRRzYu76iGPZ6OtA4Au1SnW0ZwIqPP217YhA==
|
||||||
|
dependencies:
|
||||||
|
"@volar/source-map" "2.4.12"
|
||||||
|
|
||||||
|
"@volar/language-server@~2.4.7":
|
||||||
|
version "2.4.12"
|
||||||
|
resolved "https://registry.yarnpkg.com/@volar/language-server/-/language-server-2.4.12.tgz#71856dce6432aec906dbf3a242def9b1133a82bb"
|
||||||
|
integrity sha512-KC0YqTXCZMaImMWyAKC+dLB2BXjfz80kqesJkV6oXxJsGEQPfmdqug299idwtrT6FVSmZ7q5UrPfvgKwA0S3JA==
|
||||||
|
dependencies:
|
||||||
|
"@volar/language-core" "2.4.12"
|
||||||
|
"@volar/language-service" "2.4.12"
|
||||||
|
"@volar/typescript" "2.4.12"
|
||||||
|
path-browserify "^1.0.1"
|
||||||
|
request-light "^0.7.0"
|
||||||
|
vscode-languageserver "^9.0.1"
|
||||||
|
vscode-languageserver-protocol "^3.17.5"
|
||||||
|
vscode-languageserver-textdocument "^1.0.11"
|
||||||
|
vscode-uri "^3.0.8"
|
||||||
|
|
||||||
|
"@volar/language-service@2.4.12", "@volar/language-service@~2.4.7":
|
||||||
|
version "2.4.12"
|
||||||
|
resolved "https://registry.yarnpkg.com/@volar/language-service/-/language-service-2.4.12.tgz#b9064e40f638c364bec01c382abb00b6a69a6f97"
|
||||||
|
integrity sha512-nifOPGYYPnCmxja6/ML/Gl2EgFkUdw4gLbYqbh8FjqX3gSpXSZl/0ebqORjKo1KW56YWHWRZd1jFutEtCiRYhA==
|
||||||
|
dependencies:
|
||||||
|
"@volar/language-core" "2.4.12"
|
||||||
|
vscode-languageserver-protocol "^3.17.5"
|
||||||
|
vscode-languageserver-textdocument "^1.0.11"
|
||||||
|
vscode-uri "^3.0.8"
|
||||||
|
|
||||||
|
"@volar/source-map@2.4.12":
|
||||||
|
version "2.4.12"
|
||||||
|
resolved "https://registry.yarnpkg.com/@volar/source-map/-/source-map-2.4.12.tgz#7cc8c6b1b134a2215f06c91ad011d94eef81b0ed"
|
||||||
|
integrity sha512-bUFIKvn2U0AWojOaqf63ER0N/iHIBYZPpNGogfLPQ68F5Eet6FnLlyho7BS0y2HJ1jFhSif7AcuTx1TqsCzRzw==
|
||||||
|
|
||||||
|
"@volar/typescript@2.4.12":
|
||||||
|
version "2.4.12"
|
||||||
|
resolved "https://registry.yarnpkg.com/@volar/typescript/-/typescript-2.4.12.tgz#8c638c23cab89ab131cdcd2d6f2a51768caaa015"
|
||||||
|
integrity sha512-HJB73OTJDgPc80K30wxi3if4fSsZZAOScbj2fcicMuOPoOkcf9NNAINb33o+DzhBdF9xTKC1gnPmIRDous5S0g==
|
||||||
|
dependencies:
|
||||||
|
"@volar/language-core" "2.4.12"
|
||||||
|
path-browserify "^1.0.1"
|
||||||
|
vscode-uri "^3.0.8"
|
||||||
|
|
||||||
|
"@vscode/emmet-helper@^2.9.3":
|
||||||
|
version "2.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vscode/emmet-helper/-/emmet-helper-2.11.0.tgz#7a53e4fdb17329cc2ed88036905c78d811d231d6"
|
||||||
|
integrity sha512-QLxjQR3imPZPQltfbWRnHU6JecWTF1QSWhx3GAKQpslx7y3Dp6sIIXhKjiUJ/BR9FX8PVthjr9PD6pNwOJfAzw==
|
||||||
|
dependencies:
|
||||||
|
emmet "^2.4.3"
|
||||||
|
jsonc-parser "^2.3.0"
|
||||||
|
vscode-languageserver-textdocument "^1.0.1"
|
||||||
|
vscode-languageserver-types "^3.15.1"
|
||||||
|
vscode-uri "^3.0.8"
|
||||||
|
|
||||||
|
"@vscode/l10n@^0.0.18":
|
||||||
|
version "0.0.18"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vscode/l10n/-/l10n-0.0.18.tgz#916d3a5e960dbab47c1c56f58a7cb5087b135c95"
|
||||||
|
integrity sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==
|
||||||
|
|
||||||
acorn-jsx@^5.3.2:
|
acorn-jsx@^5.3.2:
|
||||||
version "5.3.2"
|
version "5.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
|
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
|
||||||
|
|
@ -2009,6 +2168,16 @@ ajv@^6.12.4:
|
||||||
json-schema-traverse "^0.4.1"
|
json-schema-traverse "^0.4.1"
|
||||||
uri-js "^4.2.2"
|
uri-js "^4.2.2"
|
||||||
|
|
||||||
|
ajv@^8.11.0:
|
||||||
|
version "8.17.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6"
|
||||||
|
integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==
|
||||||
|
dependencies:
|
||||||
|
fast-deep-equal "^3.1.3"
|
||||||
|
fast-uri "^3.0.1"
|
||||||
|
json-schema-traverse "^1.0.0"
|
||||||
|
require-from-string "^2.0.2"
|
||||||
|
|
||||||
ansi-align@^3.0.1:
|
ansi-align@^3.0.1:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59"
|
resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59"
|
||||||
|
|
@ -2185,6 +2354,13 @@ astro-icon@^1.1.1:
|
||||||
"@iconify/types" "^2.0.0"
|
"@iconify/types" "^2.0.0"
|
||||||
"@iconify/utils" "^2.1.30"
|
"@iconify/utils" "^2.1.30"
|
||||||
|
|
||||||
|
astro-seo@^0.8.4:
|
||||||
|
version "0.8.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/astro-seo/-/astro-seo-0.8.4.tgz#b4e156dca08ac46037168479f133cedcbb8b884b"
|
||||||
|
integrity sha512-Ou1vzQSXAxa0K8rtNtXNvSpYqOGEgMhh0immMxJeXmbVZac3UKCNWAoXWyOQDFYsZvBugCRSg0N1phBqPMVgCw==
|
||||||
|
dependencies:
|
||||||
|
"@astrojs/check" "^0.5.4"
|
||||||
|
|
||||||
astro@^5.3.0:
|
astro@^5.3.0:
|
||||||
version "5.3.0"
|
version "5.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/astro/-/astro-5.3.0.tgz#20a2772c019448f6797396f9dbabe72615877842"
|
resolved "https://registry.yarnpkg.com/astro/-/astro-5.3.0.tgz#20a2772c019448f6797396f9dbabe72615877842"
|
||||||
|
|
@ -2295,15 +2471,6 @@ axios@^1.6.0, axios@^1.7.4, axios@^1.7.9:
|
||||||
form-data "^4.0.0"
|
form-data "^4.0.0"
|
||||||
proxy-from-env "^1.1.0"
|
proxy-from-env "^1.1.0"
|
||||||
|
|
||||||
axios@^1.8.1:
|
|
||||||
version "1.8.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/axios/-/axios-1.8.1.tgz#7c118d2146e9ebac512b7d1128771cdd738d11e3"
|
|
||||||
integrity sha512-NN+fvwH/kV01dYUQ3PTOZns4LWtWhOFCAhQ/pHb88WQ1hNe5V/dvFwc4VJcDL11LT9xSX0QtsR8sWUuyOuOq7g==
|
|
||||||
dependencies:
|
|
||||||
follow-redirects "^1.15.6"
|
|
||||||
form-data "^4.0.0"
|
|
||||||
proxy-from-env "^1.1.0"
|
|
||||||
|
|
||||||
axobject-query@^4.1.0:
|
axobject-query@^4.1.0:
|
||||||
version "4.1.0"
|
version "4.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-4.1.0.tgz#28768c76d0e3cff21bc62a9e2d0b6ac30042a1ee"
|
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-4.1.0.tgz#28768c76d0e3cff21bc62a9e2d0b6ac30042a1ee"
|
||||||
|
|
@ -2537,7 +2704,7 @@ cheerio@1.0.0:
|
||||||
undici "^6.19.5"
|
undici "^6.19.5"
|
||||||
whatwg-mimetype "^4.0.0"
|
whatwg-mimetype "^4.0.0"
|
||||||
|
|
||||||
chokidar@^3.6.0:
|
chokidar@^3.5.3, chokidar@^3.6.0:
|
||||||
version "3.6.0"
|
version "3.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b"
|
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b"
|
||||||
integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==
|
integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==
|
||||||
|
|
@ -2807,6 +2974,11 @@ debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3
|
||||||
dependencies:
|
dependencies:
|
||||||
ms "^2.1.3"
|
ms "^2.1.3"
|
||||||
|
|
||||||
|
decode-formdata@^0.9.0:
|
||||||
|
version "0.9.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/decode-formdata/-/decode-formdata-0.9.0.tgz#fa9c0c0ea0a279d6d1ea825c156534d2d5fa6721"
|
||||||
|
integrity sha512-q5uwOjR3Um5YD+ZWPOF/1sGHVW9A5rCrRwITQChRXlmPkxDFBqCm4jNTIVdGHNH9OnR+V9MoZVgRhsFb+ARbUw==
|
||||||
|
|
||||||
decode-named-character-reference@^1.0.0:
|
decode-named-character-reference@^1.0.0:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz#daabac9690874c394c81e4162a0304b35d824f0e"
|
resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz#daabac9690874c394c81e4162a0304b35d824f0e"
|
||||||
|
|
@ -2989,6 +3161,14 @@ electron-to-chromium@^1.5.73:
|
||||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.102.tgz#81a452ace8e2c3fa7fba904ea4fed25052c53d3f"
|
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.102.tgz#81a452ace8e2c3fa7fba904ea4fed25052c53d3f"
|
||||||
integrity sha512-eHhqaja8tE/FNpIiBrvBjFV/SSKpyWHLvxuR9dPTdo+3V9ppdLmFB7ZZQ98qNovcngPLYIz0oOBF9P0FfZef5Q==
|
integrity sha512-eHhqaja8tE/FNpIiBrvBjFV/SSKpyWHLvxuR9dPTdo+3V9ppdLmFB7ZZQ98qNovcngPLYIz0oOBF9P0FfZef5Q==
|
||||||
|
|
||||||
|
emmet@^2.4.3:
|
||||||
|
version "2.4.11"
|
||||||
|
resolved "https://registry.yarnpkg.com/emmet/-/emmet-2.4.11.tgz#b331f572df37a252360ebee7dc4462c8d2e32f5c"
|
||||||
|
integrity sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ==
|
||||||
|
dependencies:
|
||||||
|
"@emmetio/abbreviation" "^2.3.3"
|
||||||
|
"@emmetio/css-abbreviation" "^2.1.8"
|
||||||
|
|
||||||
emoji-regex-xs@^1.0.0:
|
emoji-regex-xs@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz#e8af22e5d9dbd7f7f22d280af3d19d2aab5b0724"
|
resolved "https://registry.yarnpkg.com/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz#e8af22e5d9dbd7f7f22d280af3d19d2aab5b0724"
|
||||||
|
|
@ -3510,7 +3690,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
||||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
||||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||||
|
|
||||||
fast-glob@^3.3.2, fast-glob@^3.3.3:
|
fast-glob@^3.2.12, fast-glob@^3.3.1, fast-glob@^3.3.2, fast-glob@^3.3.3:
|
||||||
version "3.3.3"
|
version "3.3.3"
|
||||||
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818"
|
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818"
|
||||||
integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==
|
integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==
|
||||||
|
|
@ -3531,6 +3711,11 @@ fast-levenshtein@^2.0.6:
|
||||||
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
||||||
integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
|
integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
|
||||||
|
|
||||||
|
fast-uri@^3.0.1:
|
||||||
|
version "3.0.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.6.tgz#88f130b77cfaea2378d56bf970dea21257a68748"
|
||||||
|
integrity sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==
|
||||||
|
|
||||||
fast-xml-parser@^4.5.0:
|
fast-xml-parser@^4.5.0:
|
||||||
version "4.5.2"
|
version "4.5.2"
|
||||||
resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.5.2.tgz#f535f77b1396b859498203a2fd1994c4230a0ff9"
|
resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.5.2.tgz#f535f77b1396b859498203a2fd1994c4230a0ff9"
|
||||||
|
|
@ -4032,6 +4217,11 @@ ignore@^5.2.0, ignore@^5.3.1, ignore@^5.3.2:
|
||||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5"
|
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5"
|
||||||
integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==
|
integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==
|
||||||
|
|
||||||
|
immer@^10.1.1:
|
||||||
|
version "10.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/immer/-/immer-10.1.1.tgz#206f344ea372d8ea176891545ee53ccc062db7bc"
|
||||||
|
integrity sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==
|
||||||
|
|
||||||
import-fresh@^3.2.1:
|
import-fresh@^3.2.1:
|
||||||
version "3.3.1"
|
version "3.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.1.tgz#9cecb56503c0ada1f2741dbbd6546e4b13b57ccf"
|
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.1.tgz#9cecb56503c0ada1f2741dbbd6546e4b13b57ccf"
|
||||||
|
|
@ -4359,6 +4549,11 @@ json-schema-traverse@^0.4.1:
|
||||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
||||||
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
|
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
|
||||||
|
|
||||||
|
json-schema-traverse@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
|
||||||
|
integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
|
||||||
|
|
||||||
json-stable-stringify-without-jsonify@^1.0.1:
|
json-stable-stringify-without-jsonify@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
|
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
|
||||||
|
|
@ -4369,6 +4564,16 @@ json5@2.2.3, json5@^2.2.3:
|
||||||
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
|
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
|
||||||
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
|
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
|
||||||
|
|
||||||
|
jsonc-parser@^2.3.0:
|
||||||
|
version "2.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.3.1.tgz#59549150b133f2efacca48fe9ce1ec0659af2342"
|
||||||
|
integrity sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==
|
||||||
|
|
||||||
|
jsonc-parser@^3.0.0:
|
||||||
|
version "3.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.3.1.tgz#f2a524b4f7fd11e3d791e559977ad60b98b798b4"
|
||||||
|
integrity sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==
|
||||||
|
|
||||||
jsonwebtoken@^9.0.2:
|
jsonwebtoken@^9.0.2:
|
||||||
version "9.0.2"
|
version "9.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3"
|
resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3"
|
||||||
|
|
@ -4607,7 +4812,7 @@ lodash.once@^4.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
||||||
integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==
|
integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==
|
||||||
|
|
||||||
lodash@^4.17.21:
|
lodash@4.17.21, lodash@^4.17.21:
|
||||||
version "4.17.21"
|
version "4.17.21"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||||
|
|
@ -5186,6 +5391,11 @@ ms@^2.1.1, ms@^2.1.3:
|
||||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||||
|
|
||||||
|
muggle-string@^0.4.1:
|
||||||
|
version "0.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/muggle-string/-/muggle-string-0.4.1.tgz#3b366bd43b32f809dc20659534dd30e7c8a0d328"
|
||||||
|
integrity sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==
|
||||||
|
|
||||||
murmurhash3js@^3.0.1:
|
murmurhash3js@^3.0.1:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/murmurhash3js/-/murmurhash3js-3.0.1.tgz#3e983e5b47c2a06f43a713174e7e435ca044b998"
|
resolved "https://registry.yarnpkg.com/murmurhash3js/-/murmurhash3js-3.0.1.tgz#3e983e5b47c2a06f43a713174e7e435ca044b998"
|
||||||
|
|
@ -5504,6 +5714,11 @@ parse5@^7.0.0, parse5@^7.1.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
entities "^4.5.0"
|
entities "^4.5.0"
|
||||||
|
|
||||||
|
path-browserify@^1.0.1:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd"
|
||||||
|
integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==
|
||||||
|
|
||||||
path-exists@^4.0.0:
|
path-exists@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
|
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
|
||||||
|
|
@ -5636,6 +5851,11 @@ prettier-config-standard@^7.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/prettier-config-standard/-/prettier-config-standard-7.0.0.tgz#23fbc6f7240dd007b49d0d4c084ba58fd2ce57c2"
|
resolved "https://registry.yarnpkg.com/prettier-config-standard/-/prettier-config-standard-7.0.0.tgz#23fbc6f7240dd007b49d0d4c084ba58fd2ce57c2"
|
||||||
integrity sha512-NgZy4TYupJR6aMMuV/Aqs0ONnVhlFT8PXVkYRskxREq8EUhJHOddVfBxPV6fWpgcASpJSgvvhVLk0CBO5M3Hvw==
|
integrity sha512-NgZy4TYupJR6aMMuV/Aqs0ONnVhlFT8PXVkYRskxREq8EUhJHOddVfBxPV6fWpgcASpJSgvvhVLk0CBO5M3Hvw==
|
||||||
|
|
||||||
|
prettier@2.8.7:
|
||||||
|
version "2.8.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.7.tgz#bb79fc8729308549d28fe3a98fce73d2c0656450"
|
||||||
|
integrity sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==
|
||||||
|
|
||||||
prettier@^3.3.3:
|
prettier@^3.3.3:
|
||||||
version "3.5.1"
|
version "3.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.5.1.tgz#22fac9d0b18c0b92055ac8fb619ac1c7bef02fb7"
|
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.5.1.tgz#22fac9d0b18c0b92055ac8fb619ac1c7bef02fb7"
|
||||||
|
|
@ -5750,6 +5970,11 @@ react-is@^16.13.1:
|
||||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||||
|
|
||||||
|
react-multi-select-component@^4.3.4:
|
||||||
|
version "4.3.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-multi-select-component/-/react-multi-select-component-4.3.4.tgz#4f4b354bfa1f0353fa9c3bccf8178c87c9780450"
|
||||||
|
integrity sha512-Ui/bzCbROF4WfKq3OKWyQJHmy/bd1mW7CQM+L83TfiltuVvHElhKEyPM3JzO9urIcWplBUKv+kyxqmEnd9jPcA==
|
||||||
|
|
||||||
react-refresh@^0.14.2:
|
react-refresh@^0.14.2:
|
||||||
version "0.14.2"
|
version "0.14.2"
|
||||||
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.2.tgz#3833da01ce32da470f1f936b9d477da5c7028bf9"
|
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.2.tgz#3833da01ce32da470f1f936b9d477da5c7028bf9"
|
||||||
|
|
@ -5914,11 +6139,26 @@ remark-stringify@^11.0.0:
|
||||||
mdast-util-to-markdown "^2.0.0"
|
mdast-util-to-markdown "^2.0.0"
|
||||||
unified "^11.0.0"
|
unified "^11.0.0"
|
||||||
|
|
||||||
|
request-light@^0.5.7:
|
||||||
|
version "0.5.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.5.8.tgz#8bf73a07242b9e7b601fac2fa5dc22a094abcc27"
|
||||||
|
integrity sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg==
|
||||||
|
|
||||||
|
request-light@^0.7.0:
|
||||||
|
version "0.7.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.7.0.tgz#885628bb2f8040c26401ebf258ec51c4ae98ac2a"
|
||||||
|
integrity sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q==
|
||||||
|
|
||||||
require-directory@^2.1.1:
|
require-directory@^2.1.1:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
||||||
integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
|
integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
|
||||||
|
|
||||||
|
require-from-string@^2.0.2:
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
|
||||||
|
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
|
||||||
|
|
||||||
resolve-from@^4.0.0:
|
resolve-from@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
|
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
|
||||||
|
|
@ -6082,7 +6322,7 @@ semver@^6.3.1:
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
|
||||||
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
|
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
|
||||||
|
|
||||||
semver@^7.3.8, semver@^7.5.4, semver@^7.6.0, semver@^7.6.3, semver@^7.7.1:
|
semver@^7.3.8, semver@^7.5.4, semver@^7.6.0, semver@^7.6.2, semver@^7.6.3, semver@^7.7.1:
|
||||||
version "7.7.1"
|
version "7.7.1"
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f"
|
||||||
integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==
|
integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==
|
||||||
|
|
@ -6612,6 +6852,18 @@ typed-array-length@^1.0.7:
|
||||||
possible-typed-array-names "^1.0.0"
|
possible-typed-array-names "^1.0.0"
|
||||||
reflect.getprototypeof "^1.0.6"
|
reflect.getprototypeof "^1.0.6"
|
||||||
|
|
||||||
|
typesafe-path@^0.2.2:
|
||||||
|
version "0.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/typesafe-path/-/typesafe-path-0.2.2.tgz#91a436681b2f514badb114061b6a5e5c2b8943b1"
|
||||||
|
integrity sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA==
|
||||||
|
|
||||||
|
typescript-auto-import-cache@^0.3.3:
|
||||||
|
version "0.3.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/typescript-auto-import-cache/-/typescript-auto-import-cache-0.3.5.tgz#402f98995037734ef3fc208180331adfd5e495fc"
|
||||||
|
integrity sha512-fAIveQKsoYj55CozUiBoj4b/7WpN0i4o74wiGY5JVUEoD0XiqDk1tJqTEjgzL2/AizKQrXxyRosSebyDzBZKjw==
|
||||||
|
dependencies:
|
||||||
|
semver "^7.3.8"
|
||||||
|
|
||||||
typescript-eslint@^8.15.0:
|
typescript-eslint@^8.15.0:
|
||||||
version "8.24.1"
|
version "8.24.1"
|
||||||
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.24.1.tgz#ce85d791392608a2a9f80c4b2530a214d16a2a47"
|
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.24.1.tgz#ce85d791392608a2a9f80c4b2530a214d16a2a47"
|
||||||
|
|
@ -6798,6 +7050,11 @@ uri-js@^4.2.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
punycode "^2.1.0"
|
punycode "^2.1.0"
|
||||||
|
|
||||||
|
use-immer@^0.11.0:
|
||||||
|
version "0.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/use-immer/-/use-immer-0.11.0.tgz#8dd46cbc913cbc3298e60b8f2d9f58d82fc22e08"
|
||||||
|
integrity sha512-RNAqi3GqsWJ4bcCd4LMBgdzvPmTABam24DUaFiKfX9s3MSorNRz9RDZYJkllJoMHUxVLMDetwAuCDeyWNrp1yA==
|
||||||
|
|
||||||
util-deprecate@^1.0.2:
|
util-deprecate@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||||
|
|
@ -6848,6 +7105,164 @@ vitefu@^1.0.5:
|
||||||
resolved "https://registry.yarnpkg.com/vitefu/-/vitefu-1.0.5.tgz#eab501e07da167bbb68e957685823e6b425e7ce2"
|
resolved "https://registry.yarnpkg.com/vitefu/-/vitefu-1.0.5.tgz#eab501e07da167bbb68e957685823e6b425e7ce2"
|
||||||
integrity sha512-h4Vflt9gxODPFNGPwp4zAMZRpZR7eslzwH2c5hn5kNZ5rhnKyRJ50U+yGCdc2IRaBs8O4haIgLNGrV5CrpMsCA==
|
integrity sha512-h4Vflt9gxODPFNGPwp4zAMZRpZR7eslzwH2c5hn5kNZ5rhnKyRJ50U+yGCdc2IRaBs8O4haIgLNGrV5CrpMsCA==
|
||||||
|
|
||||||
|
volar-service-css@0.0.62:
|
||||||
|
version "0.0.62"
|
||||||
|
resolved "https://registry.yarnpkg.com/volar-service-css/-/volar-service-css-0.0.62.tgz#4866091bd217b548470f24706f53feba7a57345b"
|
||||||
|
integrity sha512-JwNyKsH3F8PuzZYuqPf+2e+4CTU8YoyUHEHVnoXNlrLe7wy9U3biomZ56llN69Ris7TTy/+DEX41yVxQpM4qvg==
|
||||||
|
dependencies:
|
||||||
|
vscode-css-languageservice "^6.3.0"
|
||||||
|
vscode-languageserver-textdocument "^1.0.11"
|
||||||
|
vscode-uri "^3.0.8"
|
||||||
|
|
||||||
|
volar-service-emmet@0.0.62:
|
||||||
|
version "0.0.62"
|
||||||
|
resolved "https://registry.yarnpkg.com/volar-service-emmet/-/volar-service-emmet-0.0.62.tgz#451c60f73cb2c84c5ce2e4b70901de09c38920af"
|
||||||
|
integrity sha512-U4dxWDBWz7Pi4plpbXf4J4Z/ss6kBO3TYrACxWNsE29abu75QzVS0paxDDhI6bhqpbDFXlpsDhZ9aXVFpnfGRQ==
|
||||||
|
dependencies:
|
||||||
|
"@emmetio/css-parser" "^0.4.0"
|
||||||
|
"@emmetio/html-matcher" "^1.3.0"
|
||||||
|
"@vscode/emmet-helper" "^2.9.3"
|
||||||
|
vscode-uri "^3.0.8"
|
||||||
|
|
||||||
|
volar-service-html@0.0.62:
|
||||||
|
version "0.0.62"
|
||||||
|
resolved "https://registry.yarnpkg.com/volar-service-html/-/volar-service-html-0.0.62.tgz#791c2b05f5e97bc4c35fac4dbae1cb57cc66570a"
|
||||||
|
integrity sha512-Zw01aJsZRh4GTGUjveyfEzEqpULQUdQH79KNEiKVYHZyuGtdBRYCHlrus1sueSNMxwwkuF5WnOHfvBzafs8yyQ==
|
||||||
|
dependencies:
|
||||||
|
vscode-html-languageservice "^5.3.0"
|
||||||
|
vscode-languageserver-textdocument "^1.0.11"
|
||||||
|
vscode-uri "^3.0.8"
|
||||||
|
|
||||||
|
volar-service-prettier@0.0.62:
|
||||||
|
version "0.0.62"
|
||||||
|
resolved "https://registry.yarnpkg.com/volar-service-prettier/-/volar-service-prettier-0.0.62.tgz#aae89a26b27ad048f4452482888533ed7123f5c4"
|
||||||
|
integrity sha512-h2yk1RqRTE+vkYZaI9KYuwpDfOQRrTEMvoHol0yW4GFKc75wWQRrb5n/5abDrzMPrkQbSip8JH2AXbvrRtYh4w==
|
||||||
|
dependencies:
|
||||||
|
vscode-uri "^3.0.8"
|
||||||
|
|
||||||
|
volar-service-typescript-twoslash-queries@0.0.62:
|
||||||
|
version "0.0.62"
|
||||||
|
resolved "https://registry.yarnpkg.com/volar-service-typescript-twoslash-queries/-/volar-service-typescript-twoslash-queries-0.0.62.tgz#9bf63fcf89688fae12f492168d3b447be3bdf385"
|
||||||
|
integrity sha512-KxFt4zydyJYYI0kFAcWPTh4u0Ha36TASPZkAnNY784GtgajerUqM80nX/W1d0wVhmcOFfAxkVsf/Ed+tiYU7ng==
|
||||||
|
dependencies:
|
||||||
|
vscode-uri "^3.0.8"
|
||||||
|
|
||||||
|
volar-service-typescript@0.0.62:
|
||||||
|
version "0.0.62"
|
||||||
|
resolved "https://registry.yarnpkg.com/volar-service-typescript/-/volar-service-typescript-0.0.62.tgz#d99c42e2e08742f27b9bb186180dac93ce730ee6"
|
||||||
|
integrity sha512-p7MPi71q7KOsH0eAbZwPBiKPp9B2+qrdHAd6VY5oTo9BUXatsOAdakTm9Yf0DUj6uWBAaOT01BSeVOPwucMV1g==
|
||||||
|
dependencies:
|
||||||
|
path-browserify "^1.0.1"
|
||||||
|
semver "^7.6.2"
|
||||||
|
typescript-auto-import-cache "^0.3.3"
|
||||||
|
vscode-languageserver-textdocument "^1.0.11"
|
||||||
|
vscode-nls "^5.2.0"
|
||||||
|
vscode-uri "^3.0.8"
|
||||||
|
|
||||||
|
volar-service-yaml@0.0.62:
|
||||||
|
version "0.0.62"
|
||||||
|
resolved "https://registry.yarnpkg.com/volar-service-yaml/-/volar-service-yaml-0.0.62.tgz#143aaab83cae8c7c82f68502100d300ec687b59e"
|
||||||
|
integrity sha512-k7gvv7sk3wa+nGll3MaSKyjwQsJjIGCHFjVkl3wjaSP2nouKyn9aokGmqjrl39mi88Oy49giog2GkZH526wjig==
|
||||||
|
dependencies:
|
||||||
|
vscode-uri "^3.0.8"
|
||||||
|
yaml-language-server "~1.15.0"
|
||||||
|
|
||||||
|
vscode-css-languageservice@^6.3.0:
|
||||||
|
version "6.3.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-6.3.4.tgz#0b58d261441ced4667a1d5fe7f710af65bfaadf5"
|
||||||
|
integrity sha512-qutdhFg4hnlf6IsOynwtfsN8W0Xc7g3SZd+KK9F2moUEjHtkcZoj5p8uH7BSwHx9hSEXjwKgSRRyHTXThfwAkQ==
|
||||||
|
dependencies:
|
||||||
|
"@vscode/l10n" "^0.0.18"
|
||||||
|
vscode-languageserver-textdocument "^1.0.12"
|
||||||
|
vscode-languageserver-types "3.17.5"
|
||||||
|
vscode-uri "^3.1.0"
|
||||||
|
|
||||||
|
vscode-html-languageservice@^5.2.0, vscode-html-languageservice@^5.3.0:
|
||||||
|
version "5.3.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-5.3.3.tgz#42f7f22411a26b327ac4c4a5d26a0369fa7c529e"
|
||||||
|
integrity sha512-AK/jJM0VIWRrlfqkDBMZxNMnxYT5I2uoMVRoNJ5ePSplnSaT9mbYjqJlxxeLvUrOW7MEH0vVIDzU48u44QZE0w==
|
||||||
|
dependencies:
|
||||||
|
"@vscode/l10n" "^0.0.18"
|
||||||
|
vscode-languageserver-textdocument "^1.0.12"
|
||||||
|
vscode-languageserver-types "^3.17.5"
|
||||||
|
vscode-uri "^3.1.0"
|
||||||
|
|
||||||
|
vscode-json-languageservice@4.1.8:
|
||||||
|
version "4.1.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-4.1.8.tgz#397a39238d496e3e08a544a8b93df2cd13347d0c"
|
||||||
|
integrity sha512-0vSpg6Xd9hfV+eZAaYN63xVVMOTmJ4GgHxXnkLCh+9RsQBkWKIghzLhW2B9ebfG+LQQg8uLtsQ2aUKjTgE+QOg==
|
||||||
|
dependencies:
|
||||||
|
jsonc-parser "^3.0.0"
|
||||||
|
vscode-languageserver-textdocument "^1.0.1"
|
||||||
|
vscode-languageserver-types "^3.16.0"
|
||||||
|
vscode-nls "^5.0.0"
|
||||||
|
vscode-uri "^3.0.2"
|
||||||
|
|
||||||
|
vscode-jsonrpc@6.0.0:
|
||||||
|
version "6.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz#108bdb09b4400705176b957ceca9e0880e9b6d4e"
|
||||||
|
integrity sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==
|
||||||
|
|
||||||
|
vscode-jsonrpc@8.2.0:
|
||||||
|
version "8.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz#f43dfa35fb51e763d17cd94dcca0c9458f35abf9"
|
||||||
|
integrity sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==
|
||||||
|
|
||||||
|
vscode-languageserver-protocol@3.16.0:
|
||||||
|
version "3.16.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz#34135b61a9091db972188a07d337406a3cdbe821"
|
||||||
|
integrity sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==
|
||||||
|
dependencies:
|
||||||
|
vscode-jsonrpc "6.0.0"
|
||||||
|
vscode-languageserver-types "3.16.0"
|
||||||
|
|
||||||
|
vscode-languageserver-protocol@3.17.5, vscode-languageserver-protocol@^3.17.5:
|
||||||
|
version "3.17.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz#864a8b8f390835572f4e13bd9f8313d0e3ac4bea"
|
||||||
|
integrity sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==
|
||||||
|
dependencies:
|
||||||
|
vscode-jsonrpc "8.2.0"
|
||||||
|
vscode-languageserver-types "3.17.5"
|
||||||
|
|
||||||
|
vscode-languageserver-textdocument@^1.0.1, vscode-languageserver-textdocument@^1.0.11, vscode-languageserver-textdocument@^1.0.12:
|
||||||
|
version "1.0.12"
|
||||||
|
resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz#457ee04271ab38998a093c68c2342f53f6e4a631"
|
||||||
|
integrity sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==
|
||||||
|
|
||||||
|
vscode-languageserver-types@3.16.0:
|
||||||
|
version "3.16.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz#ecf393fc121ec6974b2da3efb3155644c514e247"
|
||||||
|
integrity sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==
|
||||||
|
|
||||||
|
vscode-languageserver-types@3.17.5, vscode-languageserver-types@^3.15.1, vscode-languageserver-types@^3.16.0, vscode-languageserver-types@^3.17.5:
|
||||||
|
version "3.17.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz#3273676f0cf2eab40b3f44d085acbb7f08a39d8a"
|
||||||
|
integrity sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==
|
||||||
|
|
||||||
|
vscode-languageserver@^7.0.0:
|
||||||
|
version "7.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-7.0.0.tgz#49b068c87cfcca93a356969d20f5d9bdd501c6b0"
|
||||||
|
integrity sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==
|
||||||
|
dependencies:
|
||||||
|
vscode-languageserver-protocol "3.16.0"
|
||||||
|
|
||||||
|
vscode-languageserver@^9.0.1:
|
||||||
|
version "9.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz#500aef82097eb94df90d008678b0b6b5f474015b"
|
||||||
|
integrity sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==
|
||||||
|
dependencies:
|
||||||
|
vscode-languageserver-protocol "3.17.5"
|
||||||
|
|
||||||
|
vscode-nls@^5.0.0, vscode-nls@^5.2.0:
|
||||||
|
version "5.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.2.0.tgz#3cb6893dd9bd695244d8a024bdf746eea665cc3f"
|
||||||
|
integrity sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==
|
||||||
|
|
||||||
|
vscode-uri@^3.0.2, vscode-uri@^3.0.8, vscode-uri@^3.1.0:
|
||||||
|
version "3.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.1.0.tgz#dd09ec5a66a38b5c3fffc774015713496d14e09c"
|
||||||
|
integrity sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==
|
||||||
|
|
||||||
web-namespaces@^2.0.0:
|
web-namespaces@^2.0.0:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-2.0.1.tgz#1010ff7c650eccb2592cebeeaf9a1b253fd40692"
|
resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-2.0.1.tgz#1010ff7c650eccb2592cebeeaf9a1b253fd40692"
|
||||||
|
|
@ -6996,6 +7411,34 @@ yallist@^4.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
|
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
|
||||||
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
|
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
|
||||||
|
|
||||||
|
yaml-language-server@~1.15.0:
|
||||||
|
version "1.15.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/yaml-language-server/-/yaml-language-server-1.15.0.tgz#3bd36f1f7fd74e63b591e5148df992c7327be05a"
|
||||||
|
integrity sha512-N47AqBDCMQmh6mBLmI6oqxryHRzi33aPFPsJhYy3VTUGCdLHYjGh4FZzpUjRlphaADBBkDmnkM/++KNIOHi5Rw==
|
||||||
|
dependencies:
|
||||||
|
ajv "^8.11.0"
|
||||||
|
lodash "4.17.21"
|
||||||
|
request-light "^0.5.7"
|
||||||
|
vscode-json-languageservice "4.1.8"
|
||||||
|
vscode-languageserver "^7.0.0"
|
||||||
|
vscode-languageserver-textdocument "^1.0.1"
|
||||||
|
vscode-languageserver-types "^3.16.0"
|
||||||
|
vscode-nls "^5.0.0"
|
||||||
|
vscode-uri "^3.0.2"
|
||||||
|
yaml "2.2.2"
|
||||||
|
optionalDependencies:
|
||||||
|
prettier "2.8.7"
|
||||||
|
|
||||||
|
yaml@2.2.2:
|
||||||
|
version "2.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.2.2.tgz#ec551ef37326e6d42872dad1970300f8eb83a073"
|
||||||
|
integrity sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA==
|
||||||
|
|
||||||
|
yaml@^2.5.0:
|
||||||
|
version "2.7.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.7.1.tgz#44a247d1b88523855679ac7fa7cda6ed7e135cf6"
|
||||||
|
integrity sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==
|
||||||
|
|
||||||
yargs-parser@^21.1.1:
|
yargs-parser@^21.1.1:
|
||||||
version "21.1.1"
|
version "21.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
|
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue