@limitly/limitly-nextjs
Version:
Official Next.js SDK for Limitly - API Key management, plans, users and request validation optimized for server-side
166 lines • 6.76 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ValidationModule = exports.UsersModule = exports.PlansModule = exports.ApiKeysModule = exports.HttpClient = exports.Limitly = void 0;
const client_1 = require("./client");
const api_keys_1 = require("./modules/api-keys");
const plans_1 = require("./modules/plans");
const users_1 = require("./modules/users");
const validation_1 = require("./modules/validation");
/**
* Main Limitly SDK client for Next.js
* Optimized for server-side rendering and Next.js applications
*
* @example
* ```typescript
* import { Limitly } from '@limitly/limitly-nextjs';
*
* const limitly = new Limitly({
* apiKey: 'your_limitly_api_key'
* });
*
* // Validate a request in a Next.js API route
* export async function GET(request: Request) {
* const apiKey = request.headers.get('authorization')?.replace('Bearer ', '');
*
* if (!apiKey) {
* return Response.json({ error: 'API Key required' }, { status: 401 });
* }
*
* const result = await limitly.validation.validate(
* apiKey,
* '/api/users',
* 'GET'
* );
*
* if (!result.success) {
* return Response.json({ error: 'Rate limit exceeded' }, { status: 429 });
* }
*
* return Response.json({ message: 'Request allowed' });
* }
* ```
*/
class Limitly {
apiKeys;
plans;
users;
validation;
client;
constructor(config) {
this.client = new client_1.HttpClient(config);
this.apiKeys = new api_keys_1.ApiKeysModule(this.client);
this.plans = new plans_1.PlansModule(this.client);
this.users = new users_1.UsersModule(this.client);
this.validation = new validation_1.ValidationModule(this.client);
}
/**
* Gets the internal HTTP client
* Useful for debugging and testing
*/
getClient() {
return this.client;
}
/**
* Creates a middleware function for Next.js API routes
* @param options - Middleware configuration options
* @returns Middleware function
*/
createMiddleware(options) {
const apiKeyHeader = options?.apiKeyHeader || 'authorization';
return async (req, res, next) => {
try {
const apiKey = req.headers?.[apiKeyHeader]?.replace('Bearer ', '') ||
req.headers?.authorization?.replace('Bearer ', '');
if (!apiKey) {
if (options?.onValidationError) {
options.onValidationError(req, res, new Error('API Key required'));
}
return res.status(401).json({ error: 'API Key required' });
}
const result = await this.validation.validate(apiKey, req.url || req.path, req.method);
if (!result.success) {
if (options?.onRateLimitExceeded) {
options.onRateLimitExceeded(req, res);
}
return res.status(429).json({
error: 'Rate limit exceeded',
details: result.details
});
}
if (next) {
next();
}
}
catch (error) {
if (options?.onValidationError) {
options.onValidationError(req, res, error);
}
return res.status(500).json({ error: 'Validation error' });
}
};
}
/**
* Creates a Next.js API route handler with built-in rate limiting
* @param handler - The API route handler function
* @param options - Rate limiting options
* @returns Wrapped API route handler
*/
withRateLimit(handler, options) {
const apiKeyHeader = options?.apiKeyHeader || 'authorization';
return async (request, ...args) => {
try {
const apiKey = request.headers.get(apiKeyHeader)?.replace('Bearer ', '') ||
request.headers.get('authorization')?.replace('Bearer ', '');
if (!apiKey) {
return Response.json({ error: 'API Key required' }, { status: 401 });
}
const result = await this.validation.validate(apiKey, new URL(request.url).pathname, request.method);
if (!result.success) {
if (options?.onRateLimitExceeded) {
return options.onRateLimitExceeded(request);
}
return Response.json({
error: 'Rate limit exceeded',
details: result.details
}, { status: 429 });
}
return handler(request, ...args);
}
catch (error) {
console.error('Rate limiting error:', error);
return Response.json({ error: 'Validation error' }, { status: 500 });
}
};
}
}
exports.Limitly = Limitly;
// Exportar tipos
__exportStar(require("./types"), exports);
// Exportar clases individuales para uso avanzado
var client_2 = require("./client");
Object.defineProperty(exports, "HttpClient", { enumerable: true, get: function () { return client_2.HttpClient; } });
var api_keys_2 = require("./modules/api-keys");
Object.defineProperty(exports, "ApiKeysModule", { enumerable: true, get: function () { return api_keys_2.ApiKeysModule; } });
var plans_2 = require("./modules/plans");
Object.defineProperty(exports, "PlansModule", { enumerable: true, get: function () { return plans_2.PlansModule; } });
var users_2 = require("./modules/users");
Object.defineProperty(exports, "UsersModule", { enumerable: true, get: function () { return users_2.UsersModule; } });
var validation_2 = require("./modules/validation");
Object.defineProperty(exports, "ValidationModule", { enumerable: true, get: function () { return validation_2.ValidationModule; } });
// Exportar la clase principal como default
exports.default = Limitly;
//# sourceMappingURL=index.js.map