From 1480595fbc183f322e4bbd7aa18790cc906b0c9e Mon Sep 17 00:00:00 2001 From: Xi Xu Date: Wed, 20 Aug 2025 22:17:48 +0800 Subject: [PATCH] Add Kaggle platform support and path transformation Introduces Kaggle as a supported platform in the configuration and health check. Implements special path transformation logic for Kaggle API endpoints in transformPath, and adds comprehensive tests to verify correct path handling for various Kaggle API routes. --- api/health.js | 3 +- src/config/platforms.js | 20 +++++++++++++ test/kaggle.test.js | 64 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 test/kaggle.test.js diff --git a/api/health.js b/api/health.js index cae4218..7d48cfb 100644 --- a/api/health.js +++ b/api/health.js @@ -45,7 +45,8 @@ export default async function handler(request) { 'Container Registries', 'AI Inference Providers', 'arXiv', - 'F-Droid' + 'F-Droid', + 'Kaggle' ] }; diff --git a/src/config/platforms.js b/src/config/platforms.js index 09afad1..64142c5 100644 --- a/src/config/platforms.js +++ b/src/config/platforms.js @@ -38,6 +38,7 @@ export const PLATFORMS = { arch: 'https://geo.mirror.pkgbuild.com', arxiv: 'https://arxiv.org', fdroid: 'https://f-droid.org', + kaggle: 'https://www.kaggle.com', // AI Inference Providers 'ip-openai': 'https://api.openai.com', @@ -157,5 +158,24 @@ export function transformPath(path, platformKey) { } } + // Special handling for Kaggle API paths + if (platformKey === 'kaggle') { + // Transform paths to include the API prefix + if (transformedPath.startsWith('/')) { + // Handle different Kaggle API endpoints: + // /datasets/download/owner/dataset-slug -> /api/v1/datasets/download/owner/dataset-slug + // /competitions/data/download/competition-name -> /api/v1/competitions/data/download/competition-name + // /datasets/list -> /api/v1/datasets/list + // /competitions/list -> /api/v1/competitions/list + // /models/list -> /api/v1/models/list + // /kernels/list -> /api/v1/kernels/list + + // Add API prefix if not already present + if (!transformedPath.startsWith('/api/v1/')) { + transformedPath = `/api/v1${transformedPath}`; + } + } + } + return transformedPath; } diff --git a/test/kaggle.test.js b/test/kaggle.test.js new file mode 100644 index 0000000..f1f2757 --- /dev/null +++ b/test/kaggle.test.js @@ -0,0 +1,64 @@ +import { describe, expect, it } from 'vitest'; +import { transformPath } from '../src/config/platforms.js'; + +describe('Kaggle API path transformation', () => { + it('should transform dataset download URLs correctly', () => { + const path = '/kaggle/datasets/download/zillow/zecon'; + const result = transformPath(path, 'kaggle'); + expect(result).toBe('/api/v1/datasets/download/zillow/zecon'); + }); + + it('should transform dataset list URLs correctly', () => { + const path = '/kaggle/datasets/list'; + const result = transformPath(path, 'kaggle'); + expect(result).toBe('/api/v1/datasets/list'); + }); + + it('should transform competition data download URLs correctly', () => { + const path = '/kaggle/competitions/data/download/titanic'; + const result = transformPath(path, 'kaggle'); + expect(result).toBe('/api/v1/competitions/data/download/titanic'); + }); + + it('should transform competition list URLs correctly', () => { + const path = '/kaggle/competitions/list'; + const result = transformPath(path, 'kaggle'); + expect(result).toBe('/api/v1/competitions/list'); + }); + + it('should transform model list URLs correctly', () => { + const path = '/kaggle/models/list'; + const result = transformPath(path, 'kaggle'); + expect(result).toBe('/api/v1/models/list'); + }); + + it('should transform kernel list URLs correctly', () => { + const path = '/kaggle/kernels/list'; + const result = transformPath(path, 'kaggle'); + expect(result).toBe('/api/v1/kernels/list'); + }); + + it('should handle URLs that already have API prefix', () => { + const path = '/kaggle/api/v1/datasets/download/owner/dataset'; + const result = transformPath(path, 'kaggle'); + expect(result).toBe('/api/v1/datasets/download/owner/dataset'); + }); + + it('should handle search endpoints with query parameters', () => { + const path = '/kaggle/datasets/list?search=housing&sortBy=votes'; + const result = transformPath(path, 'kaggle'); + expect(result).toBe('/api/v1/datasets/list?search=housing&sortBy=votes'); + }); + + it('should handle dataset metadata URLs', () => { + const path = '/kaggle/datasets/metadata/owner/dataset-slug'; + const result = transformPath(path, 'kaggle'); + expect(result).toBe('/api/v1/datasets/metadata/owner/dataset-slug'); + }); + + it('should handle competition submissions', () => { + const path = '/kaggle/competitions/submissions/submit'; + const result = transformPath(path, 'kaggle'); + expect(result).toBe('/api/v1/competitions/submissions/submit'); + }); +});