diff --git a/apps/web/src/app/api/tools/[slug]/route.ts b/apps/web/src/app/api/tools/[...slug]/route.ts similarity index 73% rename from apps/web/src/app/api/tools/[slug]/route.ts rename to apps/web/src/app/api/tools/[...slug]/route.ts index 759cdea..964e639 100644 --- a/apps/web/src/app/api/tools/[slug]/route.ts +++ b/apps/web/src/app/api/tools/[...slug]/route.ts @@ -6,21 +6,25 @@ export const dynamic = 'force-dynamic'; export const maxDuration = 60; /** - * GET /api/tools/[slug] + * GET /api/tools/[...slug] * * Fetch a single tool by its NPM package name (slug) + * Supports catch-all routing for scoped packages like @tpmjs/text-transformer */ export async function GET( _request: NextRequest, - { params }: { params: Promise<{ slug: string }> } + { params }: { params: Promise<{ slug: string[] }> } ): Promise { try { const { slug } = await params; + // Join slug array to reconstruct package name (e.g., ['@tpmjs', 'text-transformer'] -> '@tpmjs/text-transformer') + const packageName = slug.join('/'); + // Find the tool by npmPackageName const tool = await prisma.tool.findUnique({ where: { - npmPackageName: decodeURIComponent(slug), + npmPackageName: packageName, }, }); diff --git a/apps/web/src/app/tool/[...slug]/page.tsx b/apps/web/src/app/tool/[...slug]/page.tsx index 4bf5528..df763fb 100644 --- a/apps/web/src/app/tool/[...slug]/page.tsx +++ b/apps/web/src/app/tool/[...slug]/page.tsx @@ -89,7 +89,7 @@ export default function ToolDetailPage({ const fetchTool = async () => { try { setLoading(true); - const response = await fetch(`/api/tools/${encodeURIComponent(slug)}`); + const response = await fetch(`/api/tools/${slug}`); const data = await response.json(); if (data.success) { diff --git a/packages/db/check-tool.js b/packages/db/check-tool.js new file mode 100644 index 0000000..a358ce4 --- /dev/null +++ b/packages/db/check-tool.js @@ -0,0 +1,30 @@ +const { PrismaClient } = require('@prisma/client'); +const prisma = new PrismaClient(); + +async function main() { + const tool = await prisma.tool.findUnique({ + where: { npmPackageName: '@tpmjs/text-transformer' }, + select: { + npmPackageName: true, + npmVersion: true, + npmReadme: true, + }, + }); + + if (tool) { + console.log('Tool found:', tool.npmPackageName, tool.npmVersion); + console.log('Has README:', tool.npmReadme ? `Yes (${tool.npmReadme.length} chars)` : 'No'); + } else { + console.log('Tool @tpmjs/text-transformer not found in database'); + + // List all tools to see what's available + const allTools = await prisma.tool.findMany({ + select: { npmPackageName: true }, + take: 10, + }); + console.log('\nAvailable tools:'); + allTools.forEach((t) => console.log(' -', t.npmPackageName)); + } +} + +main().finally(() => prisma.$disconnect()); diff --git a/packages/db/check-tool.mjs b/packages/db/check-tool.mjs new file mode 100644 index 0000000..4fd8e43 --- /dev/null +++ b/packages/db/check-tool.mjs @@ -0,0 +1,30 @@ +import { PrismaClient } from '@prisma/client'; +const prisma = new PrismaClient(); + +async function main() { + const tool = await prisma.tool.findUnique({ + where: { npmPackageName: '@tpmjs/text-transformer' }, + select: { + npmPackageName: true, + npmVersion: true, + npmReadme: true, + } + }); + + if (tool) { + console.log('Tool found:', tool.npmPackageName, tool.npmVersion); + console.log('Has README:', tool.npmReadme ? `Yes (${tool.npmReadme.length} chars)` : 'No'); + } else { + console.log('Tool @tpmjs/text-transformer not found in database'); + + // List all tools to see what's available + const allTools = await prisma.tool.findMany({ + select: { npmPackageName: true }, + take: 10 + }); + console.log('\nAvailable tools:'); + allTools.forEach(t => console.log(' -', t.npmPackageName)); + } +} + +main().finally(() => prisma.$disconnect());