UNPKG

@swimmable/sdk

Version:

Official JavaScript/TypeScript SDK for the Swimmable API - Real-time swimming conditions and water quality data

428 lines (319 loc) 11.5 kB
# Swimmable JavaScript/TypeScript SDK [![npm version](https://badge.fury.io/js/%40swimmable%2Fsdk.svg)](https://www.npmjs.com/package/@swimmable/sdk) [![TypeScript](https://badges.frapsoft.com/typescript/code/typescript.svg?v=101)](https://github.com/ellerbrock/typescript-badges/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) Official JavaScript/TypeScript SDK for the [Swimmable API](https://swimmable.app) - Get real-time swimming conditions, water quality data, and AI-powered safety scores for beaches, lakes, and pools worldwide. ## Features - 🏊 **Real-time Swimming Conditions** - Water temperature, weather, and safety data - 🌊 **Enhanced Analysis** - AI-powered swimmability scores and detailed breakdowns - 🏖️ **Global Coverage** - 15,000+ beaches, lakes, and swimming spots worldwide - 🔒 **Type Safe** - Full TypeScript support with comprehensive type definitions - ⚡ **Modern** - Promise-based API with async/await support - 🚀 **Lightweight** - Minimal dependencies, works in Node.js and browsers - 📱 **Cross-platform** - Works in browsers, Node.js, React Native, and more ## Installation ```bash npm install @swimmable/sdk ``` ```bash yarn add @swimmable/sdk ``` ```bash pnpm add @swimmable/sdk ``` ## Quick Start ### Basic Usage (No API Key Required) ```typescript import { SwimmableClient } from '@swimmable/sdk'; const client = new SwimmableClient(); // Get current swimming conditions for Santa Monica Beach const conditions = await client.getConditions({ lat: 34.0195, lon: -118.4912 }); console.log(`Water temperature: ${conditions.waterTemperature}°C`); console.log(`Air temperature: ${conditions.airTemperature}°C`); console.log(`Weather: ${conditions.weatherDescription}`); ``` ### Enhanced Conditions with Safety Scores ```typescript // Get detailed analysis with swimmability scoring const enhanced = await client.getEnhancedConditions({ lat: 25.7617, // Miami Beach lon: -80.1918 }); console.log(`Swimmability Score: ${enhanced.swimmabilityScore}/10`); console.log(`Water Quality Score: ${enhanced.subscores.waterQuality}/10`); console.log(`Safety Rating: ${enhanced.subscores.surfHazard}/10`); // Check for any safety warnings if (enhanced.warnings.length > 0) { console.log('⚠️ Safety Warnings:', enhanced.warnings); } ``` ### With API Key (For Production Use) ```typescript const client = new SwimmableClient({ apiKey: 'your-api-key-here' // Get one at https://swimmable.app/signup }); // Now you can access premium features and higher rate limits const stats = await client.getUsageStats(); console.log(`API calls this month: ${stats.total_requests}`); ``` ## API Reference ### Client Configuration ```typescript interface SwimmableConfig { apiKey?: string; // Your Swimmable API key baseUrl?: string; // API base URL (defaults to https://api.swimmable.app) timeout?: number; // Request timeout in ms (defaults to 10000) headers?: Record<string, string>; // Custom headers } ``` ### Basic Methods #### `getConditions(coordinates, options?)` Get basic swimming conditions for a location. ```typescript const conditions = await client.getConditions({ lat: 34.0522, lon: -118.2437 }); // Returns BasicConditions interface interface BasicConditions { airTemperature: number; // °C waterTemperature: number; // °C weatherDescription: string; // e.g., "sunny", "cloudy" uvIndex: number; // 0-11+ UV index windSpeed: number; // km/h waveHeight: number; // meters timestamp: string; // ISO 8601 timestamp } ``` #### `getEnhancedConditions(coordinates, options?)` Get detailed analysis with AI-powered safety scores. ```typescript const enhanced = await client.getEnhancedConditions({ lat: 21.2765, // Waikiki Beach lon: -157.8281 }); // Returns EnhancedConditions with swimmability scores, detailed conditions, and warnings ``` #### `getSpots(options?)` Get list of available swimming spots. ```typescript const spots = await client.getSpots(); console.log(`Found ${spots.count} swimming spots`); spots.spots.forEach(spot => { console.log(`${spot.name} - ${spot.region}`); }); ``` ### API Management (Requires API Key) #### `getUsageStats(days?, options?)` Get your API usage statistics. ```typescript const stats = await client.getUsageStats(30); // Last 30 days console.log(`Total requests: ${stats.total_requests}`); console.log(`Success rate: ${stats.successful_requests / stats.total_requests * 100}%`); ``` #### `getApiKeys(options?)` List your API keys. ```typescript const keys = await client.getApiKeys(); keys.forEach(key => { console.log(`${key.name}: ${key.is_active ? 'Active' : 'Inactive'}`); }); ``` #### `createApiKey(keyData, options?)` Create a new API key. ```typescript const newKey = await client.createApiKey({ name: 'My App Key', description: 'API key for my swimming app', // expires_in_days: 365 // Optional expiration }); console.log('New API key:', newKey.api_key); // ⚠️ Save this key securely - you won't see it again! ``` ### Utility Functions The SDK includes helpful utility functions: ```typescript import { LocationUtils, ConditionsUtils, ApiKeyUtils } from '@swimmable/sdk'; // Distance calculation const distance = LocationUtils.calculateDistance( { lat: 34.0522, lon: -118.2437 }, // Santa Monica { lat: 25.7617, lon: -80.1918 } // Miami ); console.log(`Distance: ${distance.toFixed(2)} km`); // Temperature conversion const fahrenheit = ConditionsUtils.celsiusToFahrenheit(25); console.log(`25°C = ${fahrenheit}°F`); // Safety assessment const isSafe = ConditionsUtils.isSafeForSwimming(enhancedConditions); console.log(isSafe ? '✅ Safe to swim' : '⚠️ Check conditions carefully'); // API key validation const isValidKey = ApiKeyUtils.validateApiKey('swm_1234567890abcdef...'); ``` ## Framework Examples ### React Hook ```typescript import { useEffect, useState } from 'react'; import { SwimmableClient, BasicConditions } from '@swimmable/sdk'; const client = new SwimmableClient({ apiKey: 'your-key' }); function useSwimmingConditions(lat: number, lon: number) { const [conditions, setConditions] = useState<BasicConditions | null>(null); const [loading, setLoading] = useState(true); const [error, setError] = useState<string | null>(null); useEffect(() => { async function fetchConditions() { try { setLoading(true); const data = await client.getConditions({ lat, lon }); setConditions(data); setError(null); } catch (err) { setError(err instanceof Error ? err.message : 'Unknown error'); } finally { setLoading(false); } } fetchConditions(); }, [lat, lon]); return { conditions, loading, error }; } // Usage function BeachConditions() { const { conditions, loading, error } = useSwimmingConditions(34.0195, -118.4912); if (loading) return <div>Loading conditions...</div>; if (error) return <div>Error: {error}</div>; if (!conditions) return null; return ( <div> <h2>Santa Monica Beach</h2> <p>Water: {conditions.waterTemperature}°C</p> <p>Air: {conditions.airTemperature}°C</p> <p>Conditions: {conditions.weatherDescription}</p> </div> ); } ``` ### Vue 3 Composition API ```typescript import { ref, onMounted } from 'vue'; import { SwimmableClient } from '@swimmable/sdk'; export function useSwimmingConditions(lat: number, lon: number) { const client = new SwimmableClient(); const conditions = ref(null); const loading = ref(true); const error = ref(null); const fetchConditions = async () => { try { loading.value = true; conditions.value = await client.getConditions({ lat, lon }); } catch (err) { error.value = err.message; } finally { loading.value = false; } }; onMounted(fetchConditions); return { conditions, loading, error, refresh: fetchConditions }; } ``` ### Express.js API ```typescript import express from 'express'; import { SwimmableClient } from '@swimmable/sdk'; const app = express(); const client = new SwimmableClient({ apiKey: process.env.SWIMMABLE_API_KEY }); app.get('/api/conditions/:lat/:lon', async (req, res) => { try { const { lat, lon } = req.params; const conditions = await client.getConditions({ lat: parseFloat(lat), lon: parseFloat(lon) }); res.json(conditions); } catch (error) { res.status(500).json({ error: error.message }); } }); app.listen(3000); ``` ## Error Handling The SDK throws descriptive errors that you can catch and handle: ```typescript import { SwimmableClient, SwimmableError } from '@swimmable/sdk'; const client = new SwimmableClient(); try { const conditions = await client.getConditions({ lat: 91, lon: 0 }); // Invalid latitude } catch (error) { if (error instanceof SwimmableError) { console.error(`API Error ${error.status}: ${error.message}`); } else { console.error('Unexpected error:', error); } } ``` ## Rate Limiting The SDK includes built-in rate limiting utilities: ```typescript import { RateLimiter } from '@swimmable/sdk'; const limiter = new RateLimiter(100, 60000); // 100 requests per minute async function makeRequest() { if (!limiter.canMakeRequest()) { const resetTime = limiter.getResetTime(); throw new Error(`Rate limit exceeded. Try again in ${resetTime}ms`); } const conditions = await client.getConditions({ lat: 34, lon: -118 }); limiter.recordRequest(); return conditions; } ``` ## TypeScript Support The SDK is written in TypeScript and includes comprehensive type definitions: ```typescript import { SwimmableClient, BasicConditions, EnhancedConditions, SwimmableConfig, Coordinates, SpotInfo } from '@swimmable/sdk'; // All types are exported and documented const config: SwimmableConfig = { apiKey: 'your-key', timeout: 5000 }; const client = new SwimmableClient(config); ``` ## Browser Usage The SDK works in all modern browsers. For older browsers, you may need to polyfill `fetch`: ```html <script src="https://unpkg.com/@swimmable/sdk@1.0.0/dist/index.umd.js"></script> <script> const client = new SwimmableSDK.SwimmableClient(); client.getConditions({ lat: 34.0522, lon: -118.2437 }) .then(conditions => { console.log('Water temperature:', conditions.waterTemperature + '°C'); }); </script> ``` ## API Key Management 1. **Get an API Key**: Sign up at [swimmable.app/signup](https://swimmable.app/signup) 2. **Environment Variables**: Store your API key securely ```bash SWIMMABLE_API_KEY=your-api-key-here ``` 3. **Rate Limits**: Free tier includes generous limits, paid plans available 4. **Security**: Never expose API keys in client-side code ## Contributing We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md). ## Support - 📧 **Email**: [developers@swimmable.app](mailto:developers@swimmable.app) - 📖 **Documentation**: [swimmable.app/docs](https://swimmable.app/docs) - 🐛 **Issues**: [GitHub Issues](https://github.com/swimmable/javascript-sdk/issues) - 💬 **Community**: [Discord](https://discord.gg/swimmable) ## License MIT License - see [LICENSE](LICENSE) file for details. --- Built with ❤️ by the [Swimmable](https://swimmable.app) team. Making water activities safer worldwide! 🏊‍♀️🌊