mirror of
https://github.com/Drop-OSS/drop.git
synced 2026-07-25 01:13:39 +10:00
feat(store): new endpoints, ui and beginnings of main store page
This commit is contained in:
+49
-31
@@ -3,49 +3,67 @@
|
|||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
$motiva: (
|
$motiva: (
|
||||||
("MotivaSansThin.ttf", "ttf", 100, normal),
|
("MotivaSansThin.ttf", "ttf", 100, normal),
|
||||||
("MotivaSansLight.woff.ttf", "woff", 300, normal),
|
("MotivaSansLight.woff.ttf", "woff", 300, normal),
|
||||||
("MotivaSansRegular.woff.ttf", "woff", 400, normal),
|
("MotivaSansRegular.woff.ttf", "woff", 400, normal),
|
||||||
("MotivaSansMedium.woff.ttf", "woff", 500, normal),
|
("MotivaSansMedium.woff.ttf", "woff", 500, normal),
|
||||||
("MotivaSansBold.woff.ttf", "woff", 600, normal),
|
("MotivaSansBold.woff.ttf", "woff", 600, normal),
|
||||||
("MotivaSansExtraBold.ttf", "woff", 700, normal),
|
("MotivaSansExtraBold.ttf", "woff", 700, normal),
|
||||||
("MotivaSansBlack.woff.ttf", "woff", 900, normal)
|
("MotivaSansBlack.woff.ttf", "woff", 900, normal)
|
||||||
);
|
);
|
||||||
|
|
||||||
$helvetica: (
|
$helvetica: (
|
||||||
("Helvetica.woff", "woff", 400, normal),
|
("Helvetica.woff", "woff", 400, normal),
|
||||||
("Helvetica-Oblique.woff", "woff", 400, italic),
|
("Helvetica-Oblique.woff", "woff", 400, italic),
|
||||||
("Helvetica-Bold.woff", "woff", 600, normal),
|
("Helvetica-Bold.woff", "woff", 600, normal),
|
||||||
("Helvetica-BoldOblique.woff", "woff", 600, italic),
|
("Helvetica-BoldOblique.woff", "woff", 600, italic),
|
||||||
("helvetica-light-587ebe5a59211.woff2", "woff2", 300, normal)
|
("helvetica-light-587ebe5a59211.woff2", "woff2", 300, normal)
|
||||||
);
|
);
|
||||||
|
|
||||||
@each $file, $format, $weight, $style in $motiva {
|
@each $file, $format, $weight, $style in $motiva {
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Motiva Sans";
|
font-family: "Motiva Sans";
|
||||||
src: url("/fonts/motiva/#{$file}") format($format);
|
src: url("/fonts/motiva/#{$file}") format($format);
|
||||||
font-weight: $weight;
|
font-weight: $weight;
|
||||||
font-style: $style;
|
font-style: $style;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@each $file, $format, $weight, $style in $helvetica {
|
@each $file, $format, $weight, $style in $helvetica {
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Helvetica";
|
font-family: "Helvetica";
|
||||||
src: url("/fonts/helvetica/#{$file}") format($format);
|
src: url("/fonts/helvetica/#{$file}") format($format);
|
||||||
font-weight: $weight;
|
font-weight: $weight;
|
||||||
font-style: $style;
|
font-style: $style;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Inter";
|
font-family: "Inter";
|
||||||
src: url("/fonts/inter/InterVariable.ttf");
|
src: url("/fonts/inter/InterVariable.ttf");
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Inter";
|
font-family: "Inter";
|
||||||
src: url("/fonts/inter/InterVariable-Italic.ttf");
|
src: url("/fonts/inter/InterVariable-Italic.ttf");
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.carousel__icon {
|
||||||
|
color: #f4f4f5;
|
||||||
|
}
|
||||||
|
.carousel__pagination-button::after {
|
||||||
|
background-color: #3f3f46;
|
||||||
|
border-radius: 999999px;
|
||||||
|
}
|
||||||
|
.carousel__pagination-button:hover::after {
|
||||||
|
background-color: #27272a;
|
||||||
|
border-radius: 999999px;
|
||||||
|
}
|
||||||
|
.carousel__pagination-button--active::after {
|
||||||
|
background-color: #a1a1aa;
|
||||||
|
}
|
||||||
|
.carousel__pagination-button--active:hover::after {
|
||||||
|
background-color: #d4d4d8;
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<template>
|
||||||
|
<div class="flex flex-row flex-wrap gap-3 justify-center">
|
||||||
|
<button
|
||||||
|
v-for="(_, i) in amount"
|
||||||
|
@click="() => slideTo(i)"
|
||||||
|
:class="[
|
||||||
|
currentSlide == i ? 'bg-zinc-300' : 'bg-zinc-700',
|
||||||
|
'w-4 h-2 rounded-full',
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
const maxSlide = inject("maxSlide", ref(1));
|
||||||
|
const minSlide = inject("minSlide", ref(1));
|
||||||
|
const currentSlide = inject("currentSlide", ref(1));
|
||||||
|
const nav: { slideTo?: (index: number) => any } = inject("nav", {});
|
||||||
|
|
||||||
|
const amount = computed(() => maxSlide.value - minSlide.value + 1);
|
||||||
|
|
||||||
|
function slideTo(index: number) {
|
||||||
|
if (!nav.slideTo) return console.warn(`error moving slide: nav not defined`);
|
||||||
|
const offsetIndex = index + minSlide.value;
|
||||||
|
nav.slideTo(offsetIndex);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
+1
-1
@@ -54,4 +54,4 @@ export default defineNuxtConfig({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -38,7 +38,6 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/forms": "^0.5.9",
|
"@tailwindcss/forms": "^0.5.9",
|
||||||
"@tailwindcss/typography": "^0.5.15",
|
"@tailwindcss/typography": "^0.5.15",
|
||||||
"@types/bcrypt": "^5.0.2",
|
|
||||||
"@types/bcryptjs": "^2.4.6",
|
"@types/bcryptjs": "^2.4.6",
|
||||||
"@types/markdown-it": "^14.1.2",
|
"@types/markdown-it": "^14.1.2",
|
||||||
"@types/turndown": "^5.0.5",
|
"@types/turndown": "^5.0.5",
|
||||||
|
|||||||
@@ -43,14 +43,16 @@
|
|||||||
>
|
>
|
||||||
<div class="flex min-w-0 gap-x-4">
|
<div class="flex min-w-0 gap-x-4">
|
||||||
<div class="min-w-0 flex-auto">
|
<div class="min-w-0 flex-auto">
|
||||||
<p class="text-sm/6 font-semibold text-zinc-100">
|
<div class="text-sm/6 font-semibold text-zinc-100">
|
||||||
|
<p v-if="invitationUrls">
|
||||||
<span v-if="invitationUrls">
|
|
||||||
{{ invitationUrls[invitationIdx] }}
|
{{ invitationUrls[invitationIdx] }}
|
||||||
</span>
|
</p>
|
||||||
<div v-else class="h-4 w-full bg-zinc-800 animate-pulse rounded" />
|
<div
|
||||||
|
v-else
|
||||||
|
class="h-4 w-full bg-zinc-800 animate-pulse rounded"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
</p>
|
|
||||||
<p class="mt-1 flex text-xs/5 text-gray-500">
|
<p class="mt-1 flex text-xs/5 text-gray-500">
|
||||||
{{ invitation.username ?? "No username enforced." }}
|
{{ invitation.username ?? "No username enforced." }}
|
||||||
|
|
|
|
||||||
@@ -126,8 +128,8 @@
|
|||||||
<DialogTitle
|
<DialogTitle
|
||||||
as="h3"
|
as="h3"
|
||||||
class="text-base font-semibold text-zinc-100"
|
class="text-base font-semibold text-zinc-100"
|
||||||
>Invite user to Drop</DialogTitle
|
>Invite user to Drop
|
||||||
>
|
</DialogTitle>
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
<p class="text-sm text-zinc-400">
|
<p class="text-sm text-zinc-400">
|
||||||
Drop will generate a URL that you can send to the
|
Drop will generate a URL that you can send to the
|
||||||
@@ -203,8 +205,8 @@
|
|||||||
as="span"
|
as="span"
|
||||||
class="text-sm/6 font-medium text-zinc-100"
|
class="text-sm/6 font-medium text-zinc-100"
|
||||||
passive
|
passive
|
||||||
>Admin invitation</SwitchLabel
|
>Admin invitation
|
||||||
>
|
</SwitchLabel>
|
||||||
<SwitchDescription
|
<SwitchDescription
|
||||||
as="span"
|
as="span"
|
||||||
class="text-sm text-zinc-400"
|
class="text-sm text-zinc-400"
|
||||||
@@ -391,11 +393,11 @@ useHead({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const headers = useRequestHeaders(["cookie"]);
|
const headers = useRequestHeaders(["cookie"]);
|
||||||
const invitations = ref(
|
const { data } = await useFetch<Array<SerializeObject<Invitation>>>(
|
||||||
await $fetch<Array<SerializeObject<Invitation>>>("/api/v1/admin/auth/invitation", {
|
"/api/v1/admin/auth/invitation",
|
||||||
headers,
|
{ headers }
|
||||||
})
|
|
||||||
);
|
);
|
||||||
|
const invitations = ref(data.value ?? []);
|
||||||
|
|
||||||
const generateInvitationUrl = (id: string) =>
|
const generateInvitationUrl = (id: string) =>
|
||||||
`${window.location.protocol}//${window.location.host}/register?id=${id}`;
|
`${window.location.protocol}//${window.location.host}/register?id=${id}`;
|
||||||
|
|||||||
+1
-1
@@ -18,5 +18,5 @@ useHead({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const headers = useRequestHeaders(["cookie"]);
|
const headers = useRequestHeaders(["cookie"]);
|
||||||
const games = await $fetch("/api/v1/games/front", { headers });
|
const games = await $fetch("/api/v1/store/recent", { headers });
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -79,7 +79,7 @@
|
|||||||
|
|
||||||
<template #addons>
|
<template #addons>
|
||||||
<VueNavigation />
|
<VueNavigation />
|
||||||
<VuePagination />
|
<CarouselPagination class="py-2 px-12" />
|
||||||
</template>
|
</template>
|
||||||
</VueCarousel>
|
</VueCarousel>
|
||||||
</div>
|
</div>
|
||||||
@@ -115,19 +115,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.carousel__icon {
|
|
||||||
color: #f4f4f5;
|
|
||||||
}
|
|
||||||
.carousel__pagination-button::after {
|
|
||||||
background-color: #3f3f46;
|
|
||||||
border-radius: 999999px;
|
|
||||||
}
|
|
||||||
.carousel__pagination-button--active::after {
|
|
||||||
background-color: #a1a1aa;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { PlusIcon } from "@heroicons/vue/20/solid";
|
import { PlusIcon } from "@heroicons/vue/20/solid";
|
||||||
import { ArrowTopRightOnSquareIcon } from "@heroicons/vue/24/outline";
|
import { ArrowTopRightOnSquareIcon } from "@heroicons/vue/24/outline";
|
||||||
|
|||||||
+139
-2
@@ -1,3 +1,140 @@
|
|||||||
|
<!--
|
||||||
|
This example requires some changes to your config:
|
||||||
|
|
||||||
|
```
|
||||||
|
// tailwind.config.js
|
||||||
|
module.exports = {
|
||||||
|
// ...
|
||||||
|
plugins: [
|
||||||
|
// ...
|
||||||
|
require('@tailwindcss/forms'),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
```
|
||||||
|
-->
|
||||||
<template>
|
<template>
|
||||||
|
<div class="w-full">
|
||||||
</template>
|
<!-- Hero section -->
|
||||||
|
<VueCarousel
|
||||||
|
:wrapAround="true"
|
||||||
|
:items-to-show="1"
|
||||||
|
:autoplay="15 * 1000"
|
||||||
|
:transition="500"
|
||||||
|
:pauseAutoplayOnHover="true"
|
||||||
|
>
|
||||||
|
<VueSlide v-for="game in recent" :key="game.id">
|
||||||
|
<div class="w-full h-full relative overflow-hidden">
|
||||||
|
<div class="absolute inset-0">
|
||||||
|
<img
|
||||||
|
:src="useObject(game.mBannerId)"
|
||||||
|
alt=""
|
||||||
|
class="size-full object-cover object-center"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="relative w-full h-full bg-gray-900/75 px-6 py-32 sm:px-12 sm:py-40 lg:px-16"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="relative mx-auto flex max-w-xl flex-col items-center text-center"
|
||||||
|
>
|
||||||
|
<h3 class="text-base/7 font-semibold text-blue-300">
|
||||||
|
Newly added
|
||||||
|
</h3>
|
||||||
|
<h2
|
||||||
|
class="text-3xl font-bold tracking-tight text-white sm:text-5xl"
|
||||||
|
>
|
||||||
|
{{ game.mName }}
|
||||||
|
</h2>
|
||||||
|
<p class="mt-3 text-lg text-zinc-300 line-clamp-2">
|
||||||
|
{{ game.mShortDescription }}
|
||||||
|
</p>
|
||||||
|
<NuxtLink
|
||||||
|
:href="`/store/${game.id}`"
|
||||||
|
class="mt-8 block w-full rounded-md border border-transparent bg-white px-8 py-3 text-base font-medium text-gray-900 hover:bg-gray-100 sm:w-auto"
|
||||||
|
>Check it out</NuxtLink
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</VueSlide>
|
||||||
|
|
||||||
|
<template #addons>
|
||||||
|
<CarouselPagination class="py-2" :items="recent"/>
|
||||||
|
</template>
|
||||||
|
</VueCarousel>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
const headers = useRequestHeaders(["cookie"]);
|
||||||
|
const { data: recent } = await useFetch("/api/v1/store/recent", { headers });
|
||||||
|
|
||||||
|
useHead({
|
||||||
|
title: "Store",
|
||||||
|
});
|
||||||
|
|
||||||
|
const categories = [
|
||||||
|
{
|
||||||
|
name: "New Arrivals",
|
||||||
|
href: "#",
|
||||||
|
imageSrc:
|
||||||
|
"https://tailwindui.com/plus/img/ecommerce-images/home-page-01-category-01.jpg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Productivity",
|
||||||
|
href: "#",
|
||||||
|
imageSrc:
|
||||||
|
"https://tailwindui.com/plus/img/ecommerce-images/home-page-01-category-02.jpg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Workspace",
|
||||||
|
href: "#",
|
||||||
|
imageSrc:
|
||||||
|
"https://tailwindui.com/plus/img/ecommerce-images/home-page-01-category-04.jpg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Accessories",
|
||||||
|
href: "#",
|
||||||
|
imageSrc:
|
||||||
|
"https://tailwindui.com/plus/img/ecommerce-images/home-page-01-category-05.jpg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Sale",
|
||||||
|
href: "#",
|
||||||
|
imageSrc:
|
||||||
|
"https://tailwindui.com/plus/img/ecommerce-images/home-page-01-category-03.jpg",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const collections = [
|
||||||
|
{
|
||||||
|
name: "Handcrafted Collection",
|
||||||
|
href: "#",
|
||||||
|
imageSrc:
|
||||||
|
"https://tailwindui.com/plus/img/ecommerce-images/home-page-01-collection-01.jpg",
|
||||||
|
imageAlt:
|
||||||
|
"Brown leather key ring with brass metal loops and rivets on wood table.",
|
||||||
|
description:
|
||||||
|
"Keep your phone, keys, and wallet together, so you can lose everything at once.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Organized Desk Collection",
|
||||||
|
href: "#",
|
||||||
|
imageSrc:
|
||||||
|
"https://tailwindui.com/plus/img/ecommerce-images/home-page-01-collection-02.jpg",
|
||||||
|
imageAlt:
|
||||||
|
"Natural leather mouse pad on white desk next to porcelain mug and keyboard.",
|
||||||
|
description:
|
||||||
|
"The rest of the house will still be a mess, but your desk will look great.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Focus Collection",
|
||||||
|
href: "#",
|
||||||
|
imageSrc:
|
||||||
|
"https://tailwindui.com/plus/img/ecommerce-images/home-page-01-collection-03.jpg",
|
||||||
|
imageAlt:
|
||||||
|
"Person placing task list card into walnut card holder next to felt carrying case on leather desk pad.",
|
||||||
|
description:
|
||||||
|
"Be more productive than enterprise project managers with a single piece of paper.",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
</script>
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Game" ADD COLUMN "created" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "GameVersion" ADD COLUMN "created" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
enum MetadataSource {
|
enum MetadataSource {
|
||||||
Custom
|
Custom
|
||||||
GiantBomb
|
GiantBomb
|
||||||
}
|
}
|
||||||
|
|
||||||
model Game {
|
model Game {
|
||||||
@@ -8,6 +8,7 @@ model Game {
|
|||||||
|
|
||||||
metadataSource MetadataSource
|
metadataSource MetadataSource
|
||||||
metadataId String
|
metadataId String
|
||||||
|
created DateTime @default(now())
|
||||||
|
|
||||||
// Any field prefixed with m is filled in from metadata
|
// Any field prefixed with m is filled in from metadata
|
||||||
// Acts as a cache so we can search and filter it
|
// Acts as a cache so we can search and filter it
|
||||||
@@ -34,8 +35,10 @@ model Game {
|
|||||||
// A particular set of files that relate to the version
|
// A particular set of files that relate to the version
|
||||||
model GameVersion {
|
model GameVersion {
|
||||||
gameId String
|
gameId String
|
||||||
game Game @relation(fields: [gameId], references: [id])
|
game Game @relation(fields: [gameId], references: [id])
|
||||||
versionName String // Sub directory for the game files
|
versionName String // Sub directory for the game files
|
||||||
|
|
||||||
|
created DateTime @default(now())
|
||||||
|
|
||||||
platform Platform
|
platform Platform
|
||||||
launchCommand String // Command to run to start. Platform-specific. Windows games on Linux will wrap this command in Proton/Wine
|
launchCommand String // Command to run to start. Platform-specific. Windows games on Linux will wrap this command in Proton/Wine
|
||||||
|
|||||||
@@ -4,12 +4,13 @@ export default defineEventHandler(async (h3) => {
|
|||||||
const userId = await h3.context.session.getUserId(h3);
|
const userId = await h3.context.session.getUserId(h3);
|
||||||
if (!userId) throw createError({ statusCode: 403 });
|
if (!userId) throw createError({ statusCode: 403 });
|
||||||
|
|
||||||
const rawGames = await prisma.game.findMany({
|
const games = await prisma.game.findMany({
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
mName: true,
|
mName: true,
|
||||||
mShortDescription: true,
|
mShortDescription: true,
|
||||||
mCoverId:true,
|
mCoverId: true,
|
||||||
|
mBannerId: true,
|
||||||
mDevelopers: {
|
mDevelopers: {
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
@@ -22,15 +23,12 @@ export default defineEventHandler(async (h3) => {
|
|||||||
mName: true,
|
mName: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
versions: {
|
|
||||||
select: {
|
|
||||||
platform: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
orderBy: {
|
||||||
|
created: "desc",
|
||||||
|
},
|
||||||
|
take: 8,
|
||||||
});
|
});
|
||||||
|
|
||||||
const games = rawGames.map((e) => ({...e, platforms: e.versions.map((e) => e.platform).filter((e, _, r) => !r.includes(e))}))
|
|
||||||
|
|
||||||
return games;
|
return games;
|
||||||
});
|
});
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import prisma from "~/server/internal/db/database";
|
||||||
|
|
||||||
|
export default defineEventHandler(async (h3) => {
|
||||||
|
const userId = await h3.context.session.getUserId(h3);
|
||||||
|
if (!userId) throw createError({ statusCode: 403 });
|
||||||
|
|
||||||
|
const versions = await prisma.gameVersion.findMany({
|
||||||
|
select: {
|
||||||
|
game: true,
|
||||||
|
created: true,
|
||||||
|
platform: true,
|
||||||
|
},
|
||||||
|
orderBy: {
|
||||||
|
created: "desc",
|
||||||
|
},
|
||||||
|
take: 8,
|
||||||
|
});
|
||||||
|
|
||||||
|
return { versions };
|
||||||
|
});
|
||||||
@@ -1382,13 +1382,6 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad"
|
resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad"
|
||||||
integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==
|
integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==
|
||||||
|
|
||||||
"@types/bcrypt@^5.0.2":
|
|
||||||
version "5.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/bcrypt/-/bcrypt-5.0.2.tgz#22fddc11945ea4fbc3655b3e8b8847cc9f811477"
|
|
||||||
integrity sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==
|
|
||||||
dependencies:
|
|
||||||
"@types/node" "*"
|
|
||||||
|
|
||||||
"@types/bcryptjs@^2.4.6":
|
"@types/bcryptjs@^2.4.6":
|
||||||
version "2.4.6"
|
version "2.4.6"
|
||||||
resolved "https://registry.yarnpkg.com/@types/bcryptjs/-/bcryptjs-2.4.6.tgz#2b92e3c2121c66eba3901e64faf8bb922ec291fa"
|
resolved "https://registry.yarnpkg.com/@types/bcryptjs/-/bcryptjs-2.4.6.tgz#2b92e3c2121c66eba3901e64faf8bb922ec291fa"
|
||||||
|
|||||||
Reference in New Issue
Block a user