semanticpen
Version:
AI Article Writer & SEO Blog Generator SDK - Professional TypeScript/JavaScript library for automated content creation, AI-powered article generation, and SEO blog writing with SemanticPen
182 lines • 6.22 kB
JavaScript
import { ArticleService } from '../services/ArticleService';
import { StatusPoller } from '../utils/StatusPoller';
import { ValidationError } from '../errors';
export class SemanticPenClient {
constructor(config) {
this.config = { ...config };
this.articleService = new ArticleService(this.config);
this.statusPoller = new StatusPoller(this.articleService);
}
static create(apiKey, options) {
return new SemanticPenClient({
apiKey,
...options
});
}
static createWithConfig(config) {
return new SemanticPenClient(config);
}
async testConnection() {
return this.articleService.testConnection();
}
getConfig() {
return this.articleService.getConfig();
}
async generateArticle(keyword, options) {
return this.articleService.generateArticle(keyword, options);
}
async generateArticles(keywords, options) {
return this.articleService.generateBulkArticles(keywords, options);
}
async generateWithRequest(request) {
return this.articleService.generateArticles(request);
}
async getArticle(articleId) {
return this.articleService.getArticle(articleId);
}
async getArticles(articleIds) {
return this.articleService.getArticles(articleIds);
}
async isArticleComplete(articleId) {
return this.articleService.isArticleComplete(articleId);
}
async getArticleStatus(articleId) {
return this.articleService.getArticleStatus(articleId);
}
async waitForArticle(articleId, options) {
const result = await this.statusPoller.pollUntilComplete(articleId, options?.polling, options?.callbacks);
if (!result.success || !result.article) {
throw new Error(result.error || 'Failed to wait for article completion');
}
return result.article;
}
async waitForArticles(articleIds, options) {
return this.statusPoller.waitForGenerationComplete(articleIds, options?.polling, options?.onProgress);
}
async getMultipleStatus(articleIds) {
return this.statusPoller.getMultipleStatus(articleIds);
}
async generateAndWait(keyword, options) {
const generation = await this.generateArticle(keyword, options?.generation);
return this.waitForArticle(generation.articleId, {
polling: options?.polling,
callbacks: options?.callbacks
});
}
async generateBulkAndWait(keywords, options) {
const startTime = Date.now();
const generation = await this.generateArticles(keywords, options?.generation);
if (generation.successCount === 0) {
return {
successful: [],
failed: generation.failed.map(f => ({ keyword: f.item, error: f.error })),
totalTime: Date.now() - startTime
};
}
const articleIds = generation.successful.map(s => s.articleId);
const completion = await this.waitForArticles(articleIds, {
polling: options?.polling,
onProgress: options?.onProgress
});
const allFailed = [
...generation.failed.map(f => ({ keyword: f.item, error: f.error })),
...completion.failed.map(f => {
const successItem = generation.successful.find(s => s.articleId === f.articleId);
return {
keyword: successItem?.keyword || f.articleId,
error: f.error
};
})
];
return {
successful: completion.completed,
failed: allFailed,
totalTime: Date.now() - startTime
};
}
static validateKeyword(keyword) {
return typeof keyword === 'string' && keyword.trim().length > 0;
}
static validateKeywords(keywords) {
const errors = [];
if (!Array.isArray(keywords)) {
errors.push('Keywords must be an array');
return { valid: false, errors };
}
if (keywords.length === 0) {
errors.push('Keywords array cannot be empty');
return { valid: false, errors };
}
keywords.forEach((keyword, index) => {
if (!this.validateKeyword(keyword)) {
errors.push(`Invalid keyword at index ${index}: ${keyword}`);
}
});
return {
valid: errors.length === 0,
errors
};
}
createRequestBuilder() {
return new ArticleRequestBuilder(this);
}
}
export class ArticleRequestBuilder {
constructor(client) {
this.request = {};
this.client = client;
}
keyword(keyword) {
this.request.targetKeyword = keyword;
return this;
}
gptVersion(version) {
this.request.gptVersion = version;
return this;
}
integration(id) {
this.request.integrationId = id;
return this;
}
preset(id) {
this.request.presetId = id;
return this;
}
projectName(name) {
this.request.projectName = name;
return this;
}
personalization(name) {
this.request.personalisationName = name;
return this;
}
parameter(key, value) {
this.request[key] = value;
return this;
}
async generate() {
if (!this.request.targetKeyword) {
throw new ValidationError('Target keyword is required');
}
return this.client.generateWithRequest(this.request);
}
async generateAndWait(pollingConfig, callbacks) {
const response = await this.generate();
if (response.articleIds.length === 1) {
return this.client.waitForArticle(response.articleIds[0], {
polling: pollingConfig,
callbacks
});
}
else {
const result = await this.client.waitForArticles(response.articleIds, {
polling: pollingConfig
});
return result.completed;
}
}
getRequest() {
return Object.freeze({ ...this.request });
}
}
//# sourceMappingURL=SemanticPenClient.js.map