refactor: replace exportName with name throughout codebase

- Update TpmjsToolDefinitionSchema to only use 'name' field
- Add 'sandbox' as valid category for sprites tools
- Update all package.json files to use 'name' instead of 'exportName'
- Update documentation and source files accordingly
- Add 11 new sprites tools for sandbox/code-execution
This commit is contained in:
Ajax Davis 2026-01-14 14:18:36 +10:00
parent b1dd3371cd
commit 2cd2b10cd0
91 changed files with 4019 additions and 195 deletions

View file

@ -10,27 +10,27 @@ interface ToolDetailPageProps {
}
/**
* Parse the URL slug to extract package name and optional export name
* Parse the URL slug to extract package name and optional tool name
*/
function parseSlug(slug: string[]): { packageName: string; exportName?: string } {
function parseSlug(slug: string[]): { packageName: string; toolName?: string } {
// URL-decode slug components (@ comes as %40)
const decodedSlug = slug.map((s) => decodeURIComponent(s));
if (decodedSlug[0]?.startsWith('@')) {
// Scoped package: ['@scope', 'package', 'exportName?']
// Scoped package: ['@scope', 'package', 'toolName?']
const packageName = decodedSlug.slice(0, 2).join('/');
const exportName = decodedSlug[2];
return { packageName, exportName };
const toolName = decodedSlug[2];
return { packageName, toolName };
}
// Unscoped: ['package', 'exportName?']
return { packageName: decodedSlug[0] || '', exportName: decodedSlug[1] };
// Unscoped: ['package', 'toolName?']
return { packageName: decodedSlug[0] || '', toolName: decodedSlug[1] };
}
/**
* Fetch tool data from database
*/
async function getTool(slug: string[]): Promise<Tool | null> {
const { packageName, exportName } = parseSlug(slug);
const { packageName, toolName } = parseSlug(slug);
if (!packageName) {
return null;
@ -49,7 +49,7 @@ async function getTool(slug: string[]): Promise<Tool | null> {
const tool = await prisma.tool.findFirst({
where: {
packageId: pkg.id,
...(exportName && { name: exportName }),
...(toolName && { name: toolName }),
},
include: {
package: true,
@ -122,9 +122,9 @@ export async function generateMetadata({ params }: ToolDetailPageProps): Promise
};
}
const { packageName, exportName } = parseSlug(slug);
const ogPath = exportName
? `/api/og/tool/${encodeURIComponent(packageName)}/${encodeURIComponent(exportName)}`
const { packageName, toolName } = parseSlug(slug);
const ogPath = toolName
? `/api/og/tool/${encodeURIComponent(packageName)}/${encodeURIComponent(toolName)}`
: `/api/og/tool/${encodeURIComponent(packageName)}`;
return {

View file

@ -102,41 +102,41 @@ export function normalizePath(path: string): string {
}
/**
* Parse tool path to extract package name and export name
* Parse tool path to extract package name and tool name
*/
function parseToolPath(path: string): { packageName: string; exportName?: string } {
function parseToolPath(path: string): { packageName: string; toolName?: string } {
// Remove /tool/ prefix
const segments = path.replace(/^\/tool\//, '').split('/');
let packageName: string;
let exportName: string | undefined;
let toolName: string | undefined;
if (segments[0]?.startsWith('@')) {
// Scoped package: @scope/package/export
// Scoped package: @scope/package/toolName
packageName = segments.slice(0, 2).join('/');
exportName = segments[2];
toolName = segments[2];
} else {
// Unscoped: package/export
// Unscoped: package/toolName
packageName = segments[0] || '';
exportName = segments[1];
toolName = segments[1];
}
return { packageName, exportName };
return { packageName, toolName };
}
/**
* Fetch tool data from internal API
*/
async function fetchToolContent(path: string): Promise<PageContent> {
const { packageName, exportName } = parseToolPath(path);
const { packageName, toolName } = parseToolPath(path);
// Build API URL
const baseUrl = process.env.VERCEL_URL
? `https://${process.env.VERCEL_URL}`
: process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000';
const apiPath = exportName
? `/api/tools/${encodeURIComponent(packageName)}/${encodeURIComponent(exportName)}`
const apiPath = toolName
? `/api/tools/${encodeURIComponent(packageName)}/${encodeURIComponent(toolName)}`
: `/api/tools/${encodeURIComponent(packageName)}`;
try {
@ -157,11 +157,11 @@ async function fetchToolContent(path: string): Promise<PageContent> {
return {
pageType: 'tool',
title: tool.name || exportName || packageName,
title: tool.name || toolName || packageName,
description: tool.description || `AI tool from ${packageName}`,
keywords: [tool.package?.category || 'tool', 'AI', 'npm', packageName],
tool: {
name: tool.name || exportName || 'Tool',
name: tool.name || toolName || 'Tool',
packageName: tool.package?.npmPackageName || packageName,
category: tool.package?.category || 'other',
description: tool.description || '',
@ -175,11 +175,11 @@ async function fetchToolContent(path: string): Promise<PageContent> {
// Return basic content on failure
return {
pageType: 'tool',
title: exportName || packageName,
title: toolName || packageName,
description: `AI tool from ${packageName}`,
keywords: ['tool', 'AI', 'npm'],
tool: {
name: exportName || 'Tool',
name: toolName || 'Tool',
packageName,
category: 'other',
description: '',