novel-reader-sdk
Version:
SDK for Novel Reader API
256 lines • 7.92 kB
JavaScript
;
/**
* Scraping Service SDK Client
*
* Type-safe client for consuming the scraping service API
* Provides methods for all endpoints with proper error handling
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ScrapingServiceClient = void 0;
exports.createScrapingServiceClient = createScrapingServiceClient;
const utils_1 = require("./utils");
const errors_1 = require("./errors");
// ===== Main Client Class =====
class ScrapingServiceClient {
config;
constructor(config) {
this.config = {
timeout: 30000,
retry: {},
debug: false,
...config,
};
// Ensure base URL doesn't end with slash
this.config.baseUrl = this.config.baseUrl.replace(/\/$/, '');
}
// ===== Database Operations =====
/**
* List available database scrapers
*/
async listDatabases() {
return this.makeRequest({
method: 'GET',
path: '/api/v1/databases',
}).then(response => response.results);
}
/**
* Search novels in a database
*/
async searchNovels(databaseId, request) {
(0, utils_1.validateDatabaseId)(databaseId);
return this.makeRequest({
method: 'GET',
path: '/api/v1/databases/:id/search',
params: { id: databaseId },
query: request,
});
}
/**
* Get latest novels from a database
*/
async getLatestNovels(databaseId, request = {}) {
(0, utils_1.validateDatabaseId)(databaseId);
return this.makeRequest({
method: 'GET',
path: '/api/v1/databases/:id/latest',
params: { id: databaseId },
query: request,
});
}
/**
* Get popular novels from a database
*/
async getPopularNovels(databaseId, request = {}) {
(0, utils_1.validateDatabaseId)(databaseId);
return this.makeRequest({
method: 'GET',
path: '/api/v1/databases/:id/popular',
params: { id: databaseId },
query: request,
});
}
/**
* Get detailed novel information
*/
async getNovelDetails(databaseId, request) {
(0, utils_1.validateDatabaseId)(databaseId);
if (!request.url) {
throw new errors_1.ValidationError('Novel URL is required');
}
return this.makeRequest({
method: 'GET',
path: '/api/v1/databases/:id/novel',
params: { id: databaseId },
query: request,
}).then(response => response.results);
}
// ===== Chapter Operations =====
/**
* Scrape single chapter content
*/
async scrapeChapter(request) {
if (!request.url) {
throw new errors_1.ValidationError('Chapter URL is required');
}
return this.makeRequest({
method: 'POST',
path: '/api/v1/chapters/scrape',
body: request,
}).then(response => response.results);
}
/**
* Scrape multiple chapters in batch
*/
async scrapeChaptersBatch(request) {
if (!request.urls || request.urls.length === 0) {
throw new errors_1.ValidationError('At least one URL is required');
}
return this.makeRequest({
method: 'POST',
path: '/api/v1/chapters/batch',
body: request,
}).then(response => response.results);
}
/**
* Validate if URL is supported for scraping
*/
async validateChapterUrl(request) {
if (!request.url) {
throw new errors_1.ValidationError('URL is required');
}
return this.makeRequest({
method: 'GET',
path: '/api/v1/chapters/validate-url',
query: request,
}).then(response => response.results);
}
// ===== Site Configuration Operations =====
/**
* List all site configurations
*/
async listSiteConfigurations() {
return this.makeRequest({
method: 'GET',
path: '/api/v1/sites',
}).then(response => response.results);
}
/**
* Get site configuration by hostname
*/
async getSiteConfiguration(hostname) {
if (!hostname) {
throw new errors_1.ValidationError('Hostname is required');
}
return this.makeRequest({
method: 'GET',
path: '/api/v1/sites/:hostname',
params: { hostname },
}).then(response => response.results);
}
/**
* Update site configuration
*/
async updateSiteConfiguration(hostname, update) {
if (!hostname) {
throw new errors_1.ValidationError('Hostname is required');
}
return this.makeRequest({
method: 'PUT',
path: '/api/v1/sites/:hostname',
params: { hostname },
body: update,
}).then(response => response.results);
}
/**
* Test site configuration
*/
async testSiteConfiguration(hostname, request) {
if (!hostname) {
throw new errors_1.ValidationError('Hostname is required');
}
if (!request.testUrl) {
throw new errors_1.ValidationError('Test URL is required');
}
return this.makeRequest({
method: 'POST',
path: '/api/v1/sites/:hostname/test',
params: { hostname },
body: request,
}).then(response => response.results);
}
// ===== Health Operations =====
/**
* Get overall service health status
* @deprecated Use getHealthOverview() for comprehensive health data
*/
async getHealthStatus() {
return this.makeRequest({
method: 'GET',
path: '/api/v1/health',
});
}
/**
* Get comprehensive health overview for dashboards
*/
async getHealthOverview() {
return this.makeRequest({
method: 'GET',
path: '/api/v1/health/overview',
});
}
/**
* Get detailed proxy health status
*/
async getProxyHealth() {
return this.makeRequest({
method: 'GET',
path: '/api/v1/health/proxy',
});
}
/**
* Get browser manager health status
*/
async getBrowserHealth() {
return this.makeRequest({
method: 'GET',
path: '/api/v1/health/browser',
});
}
// ===== Private Request Handler =====
async makeRequest(options) {
const { method, path, params, query, body } = options;
// Build URL
const url = (0, utils_1.buildFullUrl)(this.config.baseUrl, path, params, query);
// Prepare request options
const fetchOptions = {
method,
timeout: this.config.timeout,
};
// Add body for POST/PUT requests
if (body && (method === 'POST' || method === 'PUT')) {
fetchOptions.body = JSON.stringify(body);
}
// Log request if debug enabled
if (this.config.debug) {
(0, utils_1.logRequest)(method, url, body);
}
// Make request with retry logic
return (0, utils_1.withRetry)(async () => {
const response = await (0, utils_1.fetchWithTimeout)(url, fetchOptions);
// Log response if debug enabled
if (this.config.debug) {
(0, utils_1.logResponse)(url, response.status);
}
return (0, utils_1.parseJsonResponse)(response);
}, this.config.retry);
}
}
exports.ScrapingServiceClient = ScrapingServiceClient;
// ===== Convenience Factory Function =====
/**
* Create a new scraping service client
*/
function createScrapingServiceClient(config) {
return new ScrapingServiceClient(config);
}
//# sourceMappingURL=client.js.map