Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
FROM node:22.12.0-alpine3.19 AS builder
WORKDIR /app

COPY package*.json ./

RUN npm ci

COPY . .

RUN npm run build





# 使用轻量级的 Node.js 镜像
FROM node:22.12.0-alpine3.19 AS runner

# 设置工作目录
WORKDIR /app

# 复制构建好的文件
COPY --from=builder /app ./

# 暴露应用运行的端口
EXPOSE 3000

# 启动应用
CMD ["npm", "start"]
152 changes: 61 additions & 91 deletions app/homepage/[nsfront]/[nsbehind]/[name]/[version]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,104 +1,76 @@
//Overview页面
// Overview页面
"use client";
import React, { useEffect, useState } from 'react';
import Link from 'next/link';
//import { useSearchParams } from 'next/navigation';
import { cratesInfo } from '@/app/lib/all_interface';
import { useParams } from 'next/navigation';





const CratePage = () => {

const params = useParams();






const [results, setResults] = useState<cratesInfo | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);



useEffect(() => {
const fetchCrateData = async () => {
try {
const response = await fetch(`/api/crates/${params.nsfront}/${params.nsbehind}/${params.name}/${params.version}`);

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

const data = await response.json();
console.log('overviewwwwwwwwwwwwww:', data);

setResults(data); // 设置获取的数据

setResults(data);
} catch (error) {
console.log('Error fetching data:', error);
console.error('Error fetching data:', error);
setError('An error occurred');
} finally {
setLoading(false); // 完成加载
setLoading(false);
}
};

fetchCrateData();
}, [params.name, params.version, params.nsfront, params.nsbehind]);

fetchCrateData(); // 调用函数来获取数据
}, [params.name, params.version, params.nsfront, params.nsbehind]); // 依赖项数组,确保在 name 或 version 改变时重新获取数据

// 渲染部分
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;




return (
<div>
{/* cve */}
<div className="container mx-auto my-8 grid grid-cols-1 lg:grid-cols-2 gap-6">
<div className="space-y-6">
{/* Security Advisories */}
<div className="bg-white shadow rounded-lg p-4">
<h2 className="text-lg font-bold mb-2">Security Advisories</h2>
<p>cve: {results ? JSON.stringify(results.cves) : 'No results available'}</p>
<p className="text-gray-500 text-sm">
cve: {results && results.cves && results.cves.length > 0 && results.cves[0] !== '' ? JSON.stringify(results.cves) : 'No results available'}
</p>
</div>
{/* Licenses */}
<div className="bg-white shadow rounded-lg p-4">
<h2 className="text-lg font-bold mb-2">Licenses</h2>
<div className="mb-2">
<span className="font-bold">LICENSES:</span> MIT
<span className="font-bold">LICENSES: {results ? results.license : 'No results available'}</span>
</div>
<div className="mb-2">
<span className="font-bold">DEPENDENCY LICENSES:</span>
<ul className="list-disc pl-6">
<li>Apache-2.0 OR MIT (116)</li>
<li>MIT (27)</li>
<li>MIT OR Uniclicense (7)</li>
{/* Add more dependency licenses */}
</ul>
</div>
</div>
{/* Dependencies */}
<div className="bg-white shadow rounded-lg p-4">
<h2 className="text-lg font-bold mb-2">Dependencies</h2>
<div className="mb-2">
<span className="font-bold">Direct: {results ? JSON.stringify(results.dependencies.direct) : 'No results available'}</span>
<span className="font-bold">Direct: {results ? JSON.stringify(results.dependencies.direct) : 'No cves detected.'}</span>
</div>
<div className="mb-2">
<span className="font-bold">Indirect: {results ? JSON.stringify(results.dependencies.indirect) : 'No results available'}</span>
</div>
<Link
href={`/homepage/${params.nsfront}/${params.nsbehind}/${params.name}/${params.version}/dependencies`}
>
<div className="text-blue-500 hover:underline">
View all dependencies
</div>
<Link href={`/homepage/${params.nsfront}/${params.nsbehind}/${params.name}/${params.version}/dependencies`}>
<div className="text-blue-500 hover:underline">View all dependencies</div>
</Link>
</div>
{/* Dependents */}
Expand All @@ -110,66 +82,64 @@ const CratePage = () => {
<div className="mb-2">
<span className="font-bold">Indirect: {results ? JSON.stringify(results.dependents.indirect) : 'No results available'}</span>
</div>
<Link
href={`/homepage/${params.nsfront}/${params.nsbehind}/${params.name}/${params.version}/dependents`}
>
<div className="text-blue-500 hover:underline">
View all dependencies
</div>
<Link href={`/homepage/${params.nsfront}/${params.nsbehind}/${params.name}/${params.version}/dependents`}>
<div className="text-blue-500 hover:underline">View all dependents</div>
</Link>
</div>
</div>
<div className="bg-white shadow rounded-lg p-4">
<h2 className="text-lg font-bold mb-2">OpenSSF scorecard</h2>
<p>The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.</p>
<a href="#" className="text-blue-500 hover:underline">
View information about checks and how to fix failures.
</a>
<div className="flex items-center justify-between mt-4">
<div className="text-3xl font-bold">8.3/10</div>
<div className="text-sm text-gray-500">Scorecard as of November 11, 2024.</div>
</div>
<div className="mt-4 space-y-2">
<div className="flex justify-between">
<span>Code-Review</span>
<span>10/10</span>
</div>
<div className="flex justify-between">
<span>Maintained</span>
<span>10/10</span>
</div>
<div className="flex justify-between">
<span>CI/Best-Practices</span>
<span>0/10</span>
</div>
<div className="flex justify-between">
<span>License</span>
<span>10/10</span>
</div>
<div className="flex justify-between">
<span>Dangerous-Workflow</span>
<span>10/10</span>
</div>
<div className="flex justify-between">
<span>Security-Policy</span>
<span>10/10</span>

{/* 新增的块: doc_url 和 github_url */}
<div className="space-y-6">
<div className="bg-white shadow rounded-lg p-4 mb-6">
<h2 className="text-lg font-bold mb-2">Documentation & GitHub Links</h2>
<div className="mb-2">
<span className="font-bold">Documentation URL: </span>
<a
href={results ? results.doc_url : 'No results available'}
className="text-blue-500 hover:underline"
target="_blank"
rel="noopener noreferrer"
>
{results ? results.doc_url : 'No results available'}
</a>
</div>
<div className="flex justify-between">
<span>Token-Permissions</span>
<span>10/10</span>
<div className="mb-2">
<span className="font-bold">GitHub URL: </span>
<a
href={results ? results.github_url : 'No results available'}
className="text-blue-500 hover:underline"
target="_blank"
rel="noopener noreferrer"
>
{results ? results.github_url : 'No results available'}
</a>
</div>
<div className="flex justify-between">
<span>Binary-Artifacts</span>
<span>10/10</span>
</div>

{/* OpenSSF scorecard */}
<div className="bg-white shadow rounded-lg p-4">
<h2 className="text-lg font-bold mb-2">OpenSSF scorecard</h2>
<p>The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.</p>
<a href="#" className="text-blue-500 hover:underline">View information about checks and how to fix failures.</a>
<div className="flex items-center justify-between mt-4">
<div className="text-3xl font-bold">8.3/10</div>
<div className="text-sm text-gray-500">Scorecard as of November 11, 2024.</div>
</div>
<div className="flex justify-between">
<span>Pinned-Dependencies</span>
<span>0/10</span>
<div className="mt-4 space-y-2">
<div className="flex justify-between"><span>Code-Review</span><span>10/10</span></div>
<div className="flex justify-between"><span>Maintained</span><span>10/10</span></div>
<div className="flex justify-between"><span>CI/Best-Practices</span><span>0/10</span></div>
<div className="flex justify-between"><span>License</span><span>10/10</span></div>
<div className="flex justify-between"><span>Dangerous-Workflow</span><span>10/10</span></div>
<div className="flex justify-between"><span>Security-Policy</span><span>10/10</span></div>
<div className="flex justify-between"><span>Token-Permissions</span><span>10/10</span></div>
<div className="flex justify-between"><span>Binary-Artifacts</span><span>10/10</span></div>
<div className="flex justify-between"><span>Pinned-Dependencies</span><span>0/10</span></div>
</div>
</div>
</div>
</div>
</div>
</div >
);
};

Expand Down
2 changes: 1 addition & 1 deletion app/homepage/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ const HomePage: React.FC = () => {


{/* 一些介绍 */}
<div className="flex container mx-auto p-10">
<div className="relative container mx-auto p-10">
<div className="bg-gray-800 p-5 mb-6 rounded shadow-md">
<h2 className="text-2xl font-semibold">New features in the deps.dev API</h2>
<p className="mt-2">The deps.dev API, which provides free access to the data that powers this website, now has experimental batch and pull support, as well as a new version that comes with a stability guarantee and deprecation policy.</p>
Expand Down
57 changes: 33 additions & 24 deletions app/homepage/search/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { searchResult } from '@/app/lib/all_interface';
const Search = () => {
const [results, setResults] = useState<searchResult | null>(null);
const [currentPage, setCurrentPage] = useState(1); // 添加当前页码状态
const [loading, setLoading] = useState(false); // 添加加载状态
const searchParams = useSearchParams();
const name = searchParams.get('crate_name');

Expand All @@ -18,6 +19,7 @@ const Search = () => {
}, [name, currentPage]); // 当 name 或 currentPage 改变时重新运行

const fetchResults = async (query: string, page: number) => {
setLoading(true); // 开始加载数据
try {
const response = await fetch('/api/search', {
method: 'POST',
Expand All @@ -40,6 +42,8 @@ const Search = () => {
setResults(data); // 假设返回的数据data字段
} catch (error) {
console.error('Error fetching data:', error);
} finally {
setLoading(false); // 数据加载完成
}
};

Expand All @@ -57,12 +61,14 @@ const Search = () => {

console.log("results:", results?.data.items);
return (
<div className="min-h-screen bg-gray-100">
<div className="min-h-screen bg-gray-100 flex flex-col">
<NewHeader />
<div className="max-w-2xl ml-10 p-4">
<div className="max-w-2xl ml-10 p-4 flex-grow">
<div id="results" className="space-y-4">
{results ? (
results.data.total_page > 0 ? (
{loading ? (
<p>Loading...</p>
) : results ? (
results.data.total_page > 0 && results.data.items.length > 0 ? (
results.data.items.map((item, index) => (
<Link
key={index}
Expand All @@ -83,32 +89,35 @@ const Search = () => {
<p>Loading...</p>
)}
</div>
</div>

{/* 显示当前页数和总页数 */}
{/* 当前页数在按钮上方 */}
<div className="flex flex-col items-start mt-2 mb-4 custom-margin-left">
{results && (
<div className="mt-4 text-center">
<div className="mb-2">
<p>
当前页: {currentPage} / 总页数: {results.data.total_page}
Current page: {currentPage} / Total page: {results.data.total_page}
</p>
</div>
)}

<div className="flex justify-between mt-4">
<button
onClick={handlePreviousPage}
disabled={currentPage === 1}
className="px-4 py-2 bg-blue-500 text-white rounded-md disabled:bg-gray-300"
>
Previous
</button>
<button
onClick={handleNextPage}
disabled={results === null || currentPage >= results.data.total_page}
className="px-4 py-2 bg-blue-500 text-white rounded-md disabled:bg-gray-300"
>
Next
</button>
</div>
{results && results.data.total_page > 0 && (
<div className="flex">
<button
onClick={handlePreviousPage}
disabled={currentPage === 1}
className="mx-0 px-4 py-2 bg-blue-500 text-white rounded-md disabled:bg-gray-300"
>
Previous
</button>
<button
onClick={handleNextPage}
disabled={results === null || currentPage >= results.data.total_page}
className="mx-20 px-4 py-2 bg-blue-500 text-white rounded-md disabled:bg-gray-300"
>
Next
</button>
</div>
)}
</div>
</div>
);
Expand Down
5 changes: 5 additions & 0 deletions app/homepage/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/* styles.css */
.custom-margin-left {
margin-left: 100px;
/* 自定义的左边距 */
}
11 changes: 4 additions & 7 deletions app/lib/all_interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,10 @@ export interface cratesInfo {
"indirect": number
},

"cves": [
{
"cve_id": string,
"url": string,
"description": string
}
],
"cves": string[],
"license": string,
"github_url": string,
"doc_url": string,
"versions": string[],

}
Expand Down
Loading
Loading