ar-common-lib
v1.0.5
Published
A utility library for the project providing geolocation services based on IP addresses and rate limiting functionality.
Readme
Utils
A utility library for the project providing geolocation services based on IP addresses and rate limiting functionality.
Features
- IP geolocation lookup using multiple fallback APIs
- Normalized response format across different data providers
- Fault-tolerant design with automatic failover between services
- Rate limiting for API endpoints with configurable limits
Installation
npm install ar-common-libUsage
Geolocation
import { getIpInfo } from 'ar-common-lib';
async function example() {
const ipInfo = await getIpInfo('8.8.8.8');
console.log(ipInfo);
// Output: { ip: '8.8.8.8', country: 'United States', city: 'Mountain View', state: 'California', lat: '37.4056', lon: '-122.0775' }
}Rate Limiting
// pages/api/protected-data.js
import { initRateLimit, getClientIp } from 'ar-common-lib';
// Configure this rate limiter:
// - Max 10 requests per minute per IP.
// - Track up to 1000 unique IPs in this window.
const limiter = initRateLimit({
interval: 60 * 1000, // 1 minute in milliseconds
uniqueTokenPerInterval: 1000, // Max 1000 unique IPs (maps to maxKeys)
// stdTTL will be automatically set to 60 seconds
// checkperiod will be automatically set based on stdTTL
});
export default async function handler(req, res) {
const clientIp = getClientIp(req);
if (!clientIp || clientIp === 'unknown') {
console.warn('Could not determine client IP for rate limiting.');
// Potentially handle anonymous users differently if needed
}
try {
// Check the rate limit: 10 requests per minute for this IP
const rateLimitResult = await limiter.check(10, clientIp || 'ANONYMOUS_USER');
// Set rate limit headers (optional)
res.setHeader('X-RateLimit-Limit', rateLimitResult.limit);
res.setHeader('X-RateLimit-Remaining', rateLimitResult.remaining);
res.setHeader('X-RateLimit-Reset', rateLimitResult.resetTime);
res.status(200).json({
message: 'This is protected data.',
ip: clientIp,
timestamp: new Date().toISOString(),
});
} catch (error) {
// Rate limit exceeded, handle the error
res.setHeader('Retry-After', error.resetTime);
res.status(429).json({
error: error.error,
retryAfter: error.resetTime
});
return;
}
}Using isRateLimited Method
// Example of using isRateLimited for custom handling
import { initRateLimit, getClientIp } from 'ar-common-lib';
const limiter = initRateLimit({
interval: 60 * 1000,
uniqueTokenPerInterval: 1000,
});
export default function handler(req, res) {
const clientIp = getClientIp(req);
const token = clientIp || 'ANONYMOUS_USER';
// Check if the request is rate limited (this will increment the counter)
const isLimited = limiter.isRateLimited(5, token);
if (isLimited) {
// Custom handling for rate limited requests
return res.status(429).json({
error: 'Custom rate limit error message',
retryAfter: 60, // seconds
});
}
// Process the request normally
return res.status(200).json({
message: 'Request processed successfully',
});
}API Reference
Geolocation
getIpInfo(ip)
Retrieves geolocation information for a given IP address.
Parameters:
ip(string): The IP address to look up
Returns: A Promise that resolves to an object with the following properties:
ip: The input IP addresscountry: Country namecity: City namestate: State or region namelat: Latitude coordinatelon: Longitude coordinate
Rate Limiting
initRateLimit(options)
Initializes a rate limiter with the specified options.
Parameters:
options(object): Configuration optionsinterval(number): Time window in milliseconds (default: 60000)uniqueTokenPerInterval(number): Maximum number of unique tokens to track (default: 500)stdTTL(number): Default TTL for items in seconds (automatically set based on interval if not provided)checkperiod(number): How often to check for expired items in seconds (automatically set based on stdTTL if not provided)customKey(string): Optional identifier for this rate limiter instance
Returns: An object with the following methods:
check(limit, token): Checks if the request is within rate limits and returns rate limit informationisRateLimited(limit, token): Checks if a token exceeds the rate limit and increments its counter
The check method returns a Promise that resolves with the following information:
{
success: true,
currentUsage: number, // Current count for the token
limit: number, // Maximum allowed requests
remaining: number, // Requests remaining in the window
resetTime: number // Seconds until the rate limit resets
}If the rate limit is exceeded, the Promise rejects with an error object:
{
error: string, // User-friendly error message
resetTime: number, // Seconds until the rate limit resets
limit: number, // Maximum allowed requests
token: string, // The token that exceeded the limit
message: string // Detailed error message
}getClientIp(req)
Helper function to extract the client IP address from a request object.
Parameters:
req(object): HTTP request object
Returns: A string containing the client's IP address
Data Sources
The library attempts to retrieve data from the free services in sequence until a successful response is received:
Testing
To run the test script:
node src/test-geo.jsDependencies
- axios: HTTP client for making API requests
License
ISC
