Commit db3d8cf1 authored by wuhao's avatar wuhao 🎯

uploaded

parent 3411cec9
...@@ -18,8 +18,10 @@ ...@@ -18,8 +18,10 @@
"@prisma/client": "^5.11.0", "@prisma/client": "^5.11.0",
"ahooks": "^3.7.10", "ahooks": "^3.7.10",
"antd": "^5.16.0", "antd": "^5.16.0",
"formidable": "^3.5.1", "date-fns": "^3.6.0",
"dayjs": "^1.11.10",
"framer-motion": "^11.0.23", "framer-motion": "^11.0.23",
"mime": "^4.0.1",
"next": "14.1.4", "next": "14.1.4",
"prisma": "^5.11.0", "prisma": "^5.11.0",
"react": "^18", "react": "^18",
......
// RESTFUl api 匹配带路由参数
import response from "@/lib/res";
import prisma from "@/lib/prisma";
// R -> Read One
export async function GET(request, { params }) {
const slug = params.slug; // 'a', 'b', or 'c'
try {
const folder = await prisma.folder.findUnique({
where: {
id: parseInt(slug),
},
});
return response(folder);
} catch (error) {
return response(error, "err");
}
}
//U -> Update
export async function PUT(request) {
const res = await request.json();
return Response.json({ res });
}
//D -> Delete
export async function DELETE(request) {
const res = await request.json();
return Response.json({ res });
}
// RESTFUl api 匹配无路由参数
import prisma from "@/lib/prisma";
import response from "@/lib/res";
// C -> Create
export async function POST(request) {
const body = await request.json();
//获取body参数
const res = await prisma.folder.create({
data: { ...body },
});
return response({ res });
}
// R -> Read
export async function GET(request, { params }) {
// const searchParams = request.nextUrl.searchParams
// const query = searchParams.get('query')
// query is "hello" for /api/search?query=hello
// const slug = params.slug; // 路由参数
try {
const folders = await prisma.folder.findMany({
// where: { published: true },
// include: {
// author: {
// select: { name: true },
// },
// },
});
return response(folders);
} catch (error) {
return response(error, "err");
}
}
// pages/api/upload.js
import mime from "mime";
import { join } from "path";
import { stat, mkdir, writeFile } from "fs/promises";
import * as dateFn from "date-fns";
import response from "@/lib/res";
export async function POST(req) {
const formData = await req.formData();
const file = formData.get("file");
if (!file) {
return response({ msg: "请选择文件上传" }, "err");
}
const buffer = Buffer.from(await file.arrayBuffer());
const relativeUploadDir = `/uploads/${dateFn.format(
Date.now(),
"yyyy-MM-dd"
)}`;
const uploadDir = join(process.cwd(), "public", relativeUploadDir);
//找文件夹 未找到->创建
try {
await stat(uploadDir);
} catch (e) {
if (e.code === "ENOENT") {
await mkdir(uploadDir, { recursive: true });
} else {
return response({ msg: "当上传文件时创建文件夹失败" }, "err");
}
}
//写入文件到指定日期到文件夹
try {
const uniqueSuffix = `${Date.now()}-${Math.round(Math.random() * 1e9)}`;
const filename = `${file.name.replace(
/\.[^/.]+$/,
""
)}-${uniqueSuffix}.${mime.getExtension(file.type)}`;
await writeFile(`${uploadDir}/${filename}`, buffer);
return response(
{ fileUrl: `${relativeUploadDir}/${filename}`, fileName: file.name },
"上传成功"
);
} catch (e) {
return response({ msg: "文件上传失败" }, "err");
}
}
...@@ -25,4 +25,7 @@ ...@@ -25,4 +25,7 @@
html,body{ html,body{
height: 100%; height: 100%;
}
.ant-upload-select{
border-radius: 16px !important;
} }
\ No newline at end of file
"use client"; "use client";
import React from "react"; import React from "react";
import AddFolder from '@/components/AddFolder'; import AddFolder from "@/components/AddFolder";
import Cards from '@/components/Cards'; import AddFileInfo from "@/components/AddFileInfo";
import Cards from "@/components/Cards";
import { useRequest } from "ahooks";
import { getFetch } from "@/lib/doFetch";
export default function Home() { export default function Home() {
const { data, refreshAsync, refresh } = useRequest(async () => {
const res = await getFetch({ url: "/api/folder", params: {} });
return res?.data ?? [];
});
return ( return (
<div> <div>
<AddFolder/> <div className="flex gap-4">
<Cards></Cards> <AddFolder refresh={refreshAsync} />
<AddFileInfo refresh={refreshAsync} />
</div>
<Cards list={data ?? []} />
</div> </div>
); );
} }
import React from "react";
import {
Modal,
ModalContent,
ModalHeader,
ModalBody,
ModalFooter,
Button,
useDisclosure,
Input,
Avatar,
} from "@nextui-org/react";
import { AiFillPlusSquare } from "react-icons/ai";
import { useForm } from "react-hook-form";
import { doFetch } from "@/lib/doFetch";
import UploadImage from "./UploadImage";
export default function AddFolder(refresh) {
const { isOpen, onOpen, onOpenChange } = useDisclosure();
const { register, handleSubmit, control, setValue } = useForm();
const handleButtonClick = async (close) => {
// 手动触发表单提交
handleSubmit(onSubmit)();
await refresh();
close();
};
const onSubmit = async (data) => {
// 提交表单数据
let res = await doFetch({ url: "/api/folder", params: data });
};
return (
<>
<Button
radius="full"
className="bg-gradient-to-tr from-pink-500 to-yellow-500 text-white shadow-lg mb-4"
onPress={onOpen}
>
<AiFillPlusSquare />
添加文件夹
</Button>
<Modal
isOpen={isOpen}
backdrop={"blur"}
onOpenChange={onOpenChange}
motionProps={{
variants: {
enter: {
y: 0,
opacity: 1,
transition: {
duration: 0.3,
ease: "easeOut",
},
},
exit: {
y: -20,
opacity: 0,
transition: {
duration: 0.2,
ease: "easeIn",
},
},
},
}}
>
<ModalContent>
{(onClose) => (
<>
<ModalHeader className="flex flex-col gap-1">
添加文件夹
</ModalHeader>
<ModalBody>
<form action="">
<input type="hidden" {...register("poster")} />
<div className="flex justify-center items-center flex-col mb-8">
<UploadImage
control={control}
setValue={setValue}
></UploadImage>
</div>
<Input
type="text"
label="文件夹"
name="name"
{...register("name", { required: true, maxLength: 20 })}
/>
</form>
</ModalBody>
<ModalFooter>
<Button color="danger" variant="light" onPress={onClose}>
取消
</Button>
<Button
color="primary"
onPress={() => {
handleButtonClick(onClose);
}}
>
提交
</Button>
</ModalFooter>
</>
)}
</ModalContent>
</Modal>
</>
);
}
...@@ -15,22 +15,20 @@ import { useForm } from "react-hook-form"; ...@@ -15,22 +15,20 @@ import { useForm } from "react-hook-form";
import { doFetch } from "@/lib/doFetch"; import { doFetch } from "@/lib/doFetch";
import UploadImage from "./UploadImage"; import UploadImage from "./UploadImage";
export default function AddFolder() { export default function AddFolder(refresh) {
const { isOpen, onOpen, onOpenChange } = useDisclosure(); const { isOpen, onOpen, onOpenChange } = useDisclosure();
const { register, handleSubmit } = useForm(); const { register, handleSubmit, control, setValue } = useForm();
const handleButtonClick = (close) => { const handleButtonClick = async (close) => {
// 手动触发表单提交 // 手动触发表单提交
handleSubmit(onSubmit)(); handleSubmit(onSubmit)();
await refresh();
close();
}; };
const onSubmit = async (data) => { const onSubmit = async (data) => {
// 提交表单数据 // 提交表单数据
console.log(data);
let res = await doFetch({ url: "/api/folder", params: data }); let res = await doFetch({ url: "/api/folder", params: data });
console.log("====================================");
console.log(res);
console.log("====================================");
}; };
return ( return (
...@@ -43,7 +41,31 @@ export default function AddFolder() { ...@@ -43,7 +41,31 @@ export default function AddFolder() {
<AiFillPlusSquare /> <AiFillPlusSquare />
添加文件夹 添加文件夹
</Button> </Button>
<Modal isOpen={isOpen} onOpenChange={onOpenChange}> <Modal
isOpen={isOpen}
backdrop={"blur"}
onOpenChange={onOpenChange}
motionProps={{
variants: {
enter: {
y: 0,
opacity: 1,
transition: {
duration: 0.3,
ease: "easeOut",
},
},
exit: {
y: -20,
opacity: 0,
transition: {
duration: 0.2,
ease: "easeIn",
},
},
},
}}
>
<ModalContent> <ModalContent>
{(onClose) => ( {(onClose) => (
<> <>
...@@ -52,8 +74,12 @@ export default function AddFolder() { ...@@ -52,8 +74,12 @@ export default function AddFolder() {
</ModalHeader> </ModalHeader>
<ModalBody> <ModalBody>
<form action=""> <form action="">
<input type="hidden" {...register("poster")} />
<div className="flex justify-center items-center flex-col mb-8"> <div className="flex justify-center items-center flex-col mb-8">
<UploadImage></UploadImage> <UploadImage
control={control}
setValue={setValue}
></UploadImage>
</div> </div>
<Input <Input
......
/* eslint-disable import/no-anonymous-default-export */ /* eslint-disable import/no-anonymous-default-export */
/* eslint-disable react/display-name */ /* eslint-disable react/display-name */
import React from "react"; import React,{memo} from "react";
import { Card, CardBody, CardFooter, Image } from "@nextui-org/react"; import { Card, CardBody, CardFooter, Image } from "@nextui-org/react";
import prisma from '@/lib/prisma'; import prisma from '@/lib/prisma';
import { useRequest } from "ahooks"; import { getFetch } from "@/lib/doFetch";
import { difftime } from "@/lib/time";
export default memo(({list}) => {
export default (props) => {
const {data} = useRequest(async ()=>{
const folders = await prisma.folder.findMany({
// where: { published: true },
// include: {
// author: {
// select: { name: true },
// },
// },
});
console.log(folders)
return folders;
})
const list = [
{
title: "Orange",
img: "/images/fruit-1.jpeg",
price: "$5.50",
},
{
title: "Tangerine",
img: "/images/fruit-2.jpeg",
price: "$3.00",
},
{
title: "Raspberry",
img: "/images/fruit-3.jpeg",
price: "$10.00",
},
{
title: "Lemon",
img: "/images/fruit-4.jpeg",
price: "$5.30",
},
{
title: "Avocado",
img: "/images/fruit-5.jpeg",
price: "$15.70",
},
{
title: "Lemon 2",
img: "/images/fruit-6.jpeg",
price: "$8.00",
},
{
title: "Banana",
img: "/images/fruit-7.jpeg",
price: "$7.50",
},
{
title: "Watermelon",
img: "/images/fruit-8.jpeg",
price: "$12.20",
},
];
return ( return (
<div className="gap-2 grid xl:grid-cols-8 lg:grid-cols-6 md:grid-cols-4 sm:grid-cols-2"> <div className="gap-2 grid xl:grid-cols-8 lg:grid-cols-6 md:grid-cols-4 sm:grid-cols-2">
...@@ -80,17 +23,17 @@ export default (props) => { ...@@ -80,17 +23,17 @@ export default (props) => {
shadow="sm" shadow="sm"
radius="lg" radius="lg"
width="100%" width="100%"
alt={item.title} alt={item.name}
className="w-full object-cover h-[140px]" className="w-full object-cover h-[140px]"
src={"https://nextui.org" + item.img} src={item.poster}
/> />
</CardBody> </CardBody>
<CardFooter className="text-small justify-between"> <CardFooter className="text-small justify-between">
<b>{item.title}</b> <b>{item.name}</b>
<p className="text-default-500">{item.price}</p> <p className="text-default-500">{difftime(item.createdAt)}</p>
</CardFooter> </CardFooter>
</Card> </Card>
))} ))}
</div> </div>
); );
} })
\ No newline at end of file \ No newline at end of file
import React, { useState } from 'react'; import React, { useState } from "react";
import { LoadingOutlined, PlusOutlined } from '@ant-design/icons'; import { LoadingOutlined, PlusOutlined } from "@ant-design/icons";
import { message, Upload } from 'antd'; import { message, Upload } from "antd";
import { Image } from "@nextui-org/react"; import { Image } from "@nextui-org/react";
import { useWatch, useForm } from "react-hook-form";
const getBase64 = (img, callback) => { const getBase64 = (img, callback) => {
const reader = new FileReader(); const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result)); reader.addEventListener("load", () => callback(reader.result));
reader.readAsDataURL(img); reader.readAsDataURL(img);
}; };
const beforeUpload = (file) => { const beforeUpload = (file) => {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'; const isJpgOrPng = file.type === "image/jpeg" || file.type === "image/png";
if (!isJpgOrPng) { if (!isJpgOrPng) {
message.error('You can only upload JPG/PNG file!'); message.error("You can only upload JPG/PNG file!");
} }
const isLt2M = file.size / 1024 / 1024 < 2; const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) { if (!isLt2M) {
message.error('Image must smaller than 2MB!'); message.error("Image must smaller than 2MB!");
} }
return isJpgOrPng && isLt2M; return isJpgOrPng && isLt2M;
}; };
const UploadImage = ({ control, setValue }) => {
const UploadImage = () => {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [imageUrl, setImageUrl] = useState();
const imageUrl = useWatch({
control,
name: "poster",
defaultValue: null,
});
function setImageUrl(path) {
setValue("poster", path);
}
const handleChange = (info) => { const handleChange = (info) => {
if (info.file.status === 'uploading') { if (info.file.status === "uploading") {
setLoading(true); setLoading(true);
return; return;
} }
if (info.file.status === 'done') { if (info.file.status === "done") {
// Get this url from response in real world. // Get this url from response in real world.
getBase64(info.file.originFileObj, (url) => { const url = info?.file?.response?.data?.fileUrl ?? '';
setLoading(false); setLoading(false);
setImageUrl(url); setImageUrl(url);
});
} }
}; };
const uploadButton = ( const uploadButton = (
<button <button
style={{ style={{
border: 0, border: 0,
background: 'none', background: "none",
}} }}
type="button" type="button"
> >
...@@ -56,6 +65,7 @@ const UploadImage = () => { ...@@ -56,6 +65,7 @@ const UploadImage = () => {
</div> </div>
</button> </button>
); );
return ( return (
<> <>
<Upload <Upload
...@@ -72,7 +82,7 @@ const UploadImage = () => { ...@@ -72,7 +82,7 @@ const UploadImage = () => {
src={imageUrl} src={imageUrl}
alt="avatar" alt="avatar"
style={{ style={{
width: '100%', width: "100%",
}} }}
/> />
) : ( ) : (
...@@ -82,4 +92,4 @@ const UploadImage = () => { ...@@ -82,4 +92,4 @@ const UploadImage = () => {
</> </>
); );
}; };
export default UploadImage; export default UploadImage;
\ No newline at end of file
...@@ -4,6 +4,8 @@ export const doFetch = ({ url, params }) => { ...@@ -4,6 +4,8 @@ export const doFetch = ({ url, params }) => {
return request(url, { return request(url, {
method: "POST", method: "POST",
data: params ?? {}, data: params ?? {},
}).then((response) =>{
}); });
}; };
......
/* eslint-disable import/no-anonymous-default-export */
import { NextRequest, NextResponse } from "next/server";
// code 控制返回的类型
export default (data, code) => {
if (!code) {
return NextResponse.json(
{
code: 0,
data,
success: true,
},
{ status: 200 }
);
} else if (code === "err") {
return NextResponse.json(
{
code: -1,
data: data,
msg: data?.msg ?? "服务器内部错误",
success: false,
},
{ status: 500 }
);
} else {
return NextResponse.json(
{
code: 0,
data,
msg: code,
success: true,
},
{ status: 200 }
);
}
};
import dayjs from 'dayjs';
export function difftime(start) {
const s = dayjs(),e = dayjs(start);
const diffInMs = s.diff(e);
if (diffInMs < 60 * 60 * 1000) {
// 时间差小于 1 小时,转为分钟
const diffInMinutes = Math.round(diffInMs / (60 * 1000));
return diffInMinutes + '分钟前';
} else {
// 时间差大于等于 1 小时,继续判断是否超过 24 小时
const diffInHours = Math.round(diffInMs / (60 * 60 * 1000));
if (diffInHours >= 24) {
// 时间差超过 24 小时,转为天
const diffInDays = Math.round(diffInHours / 24);
return diffInDays + '天前';
} else {
// 时间差在 1 小时到 24 小时之间,直接输出小时数
return diffInHours + '小时前';
}
}
}
export function formartime(now) {
// 获取当前时间
const hour = now.hour();
let timeOfDay = '';
if (hour >= 5 && hour < 12) {
timeOfDay = '上午';
} else if (hour === 12) {
timeOfDay = '中午';
} else if (hour > 12 && hour < 18) {
timeOfDay = '下午';
} else if (hour >= 18 && hour < 24) {
timeOfDay = '晚上';
} else {
timeOfDay = '凌晨';
}
return timeOfDay;
}
...@@ -22,3 +22,5 @@ export default function handler(req, res) { ...@@ -22,3 +22,5 @@ export default function handler(req, res) {
res.status(405).end(`Method ${method} Not Allowed`); res.status(405).end(`Method ${method} Not Allowed`);
} }
} }
// pages/api/upload.js
import fs from "fs";
import path from "path";
import formidable from "formidable";
export default async function handler(req, res) {
if (req.method === "POST") {
const formData = await req.formData();
// Get the file from the form data
const file = formData.get("file");
console.log("====================================");
console.log(file);
console.log("====================================");
res.status(200).json({ data: "sad" });
} else {
res.status(405).end(`Method ${method} Not Allowed`);
}
}
...@@ -2347,11 +2347,6 @@ arraybuffer.prototype.slice@^1.0.3: ...@@ -2347,11 +2347,6 @@ arraybuffer.prototype.slice@^1.0.3:
is-array-buffer "^3.0.4" is-array-buffer "^3.0.4"
is-shared-array-buffer "^1.0.2" is-shared-array-buffer "^1.0.2"
asap@^2.0.0:
version "2.0.6"
resolved "https://registry.npmmirror.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==
ast-types-flow@^0.0.8: ast-types-flow@^0.0.8:
version "0.0.8" version "0.0.8"
resolved "https://registry.npmmirror.com/ast-types-flow/-/ast-types-flow-0.0.8.tgz#0a85e1c92695769ac13a428bb653e7538bea27d6" resolved "https://registry.npmmirror.com/ast-types-flow/-/ast-types-flow-0.0.8.tgz#0a85e1c92695769ac13a428bb653e7538bea27d6"
...@@ -2617,6 +2612,11 @@ data-view-byte-offset@^1.0.0: ...@@ -2617,6 +2612,11 @@ data-view-byte-offset@^1.0.0:
es-errors "^1.3.0" es-errors "^1.3.0"
is-data-view "^1.0.1" is-data-view "^1.0.1"
date-fns@^3.6.0:
version "3.6.0"
resolved "https://registry.npmmirror.com/date-fns/-/date-fns-3.6.0.tgz#f20ca4fe94f8b754951b24240676e8618c0206bf"
integrity sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==
dayjs@^1.11.10, dayjs@^1.9.1: dayjs@^1.11.10, dayjs@^1.9.1:
version "1.11.10" version "1.11.10"
resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0" resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0"
...@@ -2674,14 +2674,6 @@ detect-node-es@^1.1.0: ...@@ -2674,14 +2674,6 @@ detect-node-es@^1.1.0:
resolved "https://registry.npmmirror.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493" resolved "https://registry.npmmirror.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493"
integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ== integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==
dezalgo@^1.0.4:
version "1.0.4"
resolved "https://registry.npmmirror.com/dezalgo/-/dezalgo-1.0.4.tgz#751235260469084c132157dfa857f386d4c33d81"
integrity sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==
dependencies:
asap "^2.0.0"
wrappy "1"
didyoumean@^1.2.2: didyoumean@^1.2.2:
version "1.2.2" version "1.2.2"
resolved "https://registry.npmmirror.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" resolved "https://registry.npmmirror.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
...@@ -3171,15 +3163,6 @@ foreground-child@^3.1.0: ...@@ -3171,15 +3163,6 @@ foreground-child@^3.1.0:
cross-spawn "^7.0.0" cross-spawn "^7.0.0"
signal-exit "^4.0.1" signal-exit "^4.0.1"
formidable@^3.5.1:
version "3.5.1"
resolved "https://registry.npmmirror.com/formidable/-/formidable-3.5.1.tgz#9360a23a656f261207868b1484624c4c8d06ee1a"
integrity sha512-WJWKelbRHN41m5dumb0/k8TeAx7Id/y3a+Z7QfhxP/htI9Js5zYaEDtG8uMgG0vM0lOlqnmjE99/kfpOYi/0Og==
dependencies:
dezalgo "^1.0.4"
hexoid "^1.0.0"
once "^1.4.0"
fraction.js@^4.3.7: fraction.js@^4.3.7:
version "4.3.7" version "4.3.7"
resolved "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7" resolved "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7"
...@@ -3386,11 +3369,6 @@ hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2: ...@@ -3386,11 +3369,6 @@ hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2:
dependencies: dependencies:
function-bind "^1.1.2" function-bind "^1.1.2"
hexoid@^1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/hexoid/-/hexoid-1.0.0.tgz#ad10c6573fb907de23d9ec63a711267d9dc9bc18"
integrity sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==
iconv-lite@^0.6.2: iconv-lite@^0.6.2:
version "0.6.3" version "0.6.3"
resolved "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" resolved "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501"
...@@ -3874,6 +3852,11 @@ micromatch@^4.0.4, micromatch@^4.0.5: ...@@ -3874,6 +3852,11 @@ micromatch@^4.0.4, micromatch@^4.0.5:
braces "^3.0.2" braces "^3.0.2"
picomatch "^2.3.1" picomatch "^2.3.1"
mime@^4.0.1:
version "4.0.1"
resolved "https://registry.npmmirror.com/mime/-/mime-4.0.1.tgz#ad7563d1bfe30253ad97dedfae2b1009d01b9470"
integrity sha512-5lZ5tyrIfliMXzFtkYyekWbtRXObT9OWa8IwQ5uxTBDHucNNwniRqo0yInflj+iYi5CBa6qxadGzGarDfuEOxA==
minimatch@9.0.3: minimatch@9.0.3:
version "9.0.3" version "9.0.3"
resolved "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" resolved "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825"
...@@ -4056,7 +4039,7 @@ object.values@^1.1.6, object.values@^1.1.7: ...@@ -4056,7 +4039,7 @@ object.values@^1.1.6, object.values@^1.1.7:
define-properties "^1.2.1" define-properties "^1.2.1"
es-object-atoms "^1.0.0" es-object-atoms "^1.0.0"
once@^1.3.0, once@^1.4.0: once@^1.3.0:
version "1.4.0" version "1.4.0"
resolved "https://registry.npmmirror.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" resolved "https://registry.npmmirror.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment