neuwo-api
Version:
TypeScript/JavaScript SDK client for the Neuwo content classification API
268 lines • 10.7 kB
JavaScript
/**
* Data models for Neuwo API requests and responses.
*
* This module defines internal API interfaces (exact API structure) and
* exported SDK classes (JavaScript conventions) with transformation methods.
*/
// ============================================================================
// SDK Model Classes (exported - JavaScript conventions)
// ============================================================================
/**
* Tag parent in the ontology hierarchy.
*/
export class TagParent {
/**
* @param level - Hierarchy level of the parent tag
* @param value - Display value of the parent tag
* @param uri - URI identifier for the parent tag
*/
constructor(level, value, uri) {
this.level = level;
this.value = value;
this.uri = uri;
}
static fromApiResponse(data) {
// Extract the level key (e.g., "Level_1", "Level_2", etc.)
const levelKey = Object.keys(data)[0];
if (!levelKey) {
throw new Error("Invalid API response: TagParent must have a level key");
}
const parentData = data[levelKey];
// Handle both uppercase URI and lowercase uri variants
const uri = parentData.URI ?? parentData.uri;
if (!uri) {
throw new Error("Invalid API response: TagParent must have either URI or uri field");
}
return new TagParent(levelKey, parentData.value, uri);
}
}
/**
* Subject tag with relevance score.
*/
export class Tag {
/**
* @param uri - URI identifier for the tag
* @param value - Display value of the tag
* @param score - Relevance score (0-1)
* @param parents - Optional hierarchy of parent tags
*/
constructor(uri, value, score, parents) {
this.uri = uri;
this.value = value;
this.score = score;
this.parents = parents;
}
static fromApiResponse(data) {
// Handle both uppercase URI and lowercase uri variants
const uri = data.URI ?? data.uri;
if (!uri) {
throw new Error("Invalid API response: Tag must have either URI or uri field");
}
const parents = data.parents?.map((parentGroup) => parentGroup.map((p) => TagParent.fromApiResponse(p)));
return new Tag(uri, data.value, parseFloat(data.score), parents);
}
}
/**
* Brand safety classification.
*/
export class BrandSafetyTag {
/**
* @param score - Brand safety score
* @param indication - Brand safety indication ("yes" for safe, "no" for unsafe)
*/
constructor(score, indication) {
this.score = score;
this.indication = indication;
}
/**
* Whether the content is brand safe.
*/
get isSafe() {
return this.indication === "yes";
}
static fromApiResponse(data) {
// Handle both uppercase (BS_score/BS_indication) and lowercase (score/indication) variants
let score;
let indication;
if (data.BS_score !== undefined && data.BS_indication !== undefined) {
// Uppercase variant
score = parseFloat(data.BS_score);
indication = data.BS_indication;
}
else if (data.score !== undefined && data.indication !== undefined) {
// Lowercase variant with boolean indication
score = parseFloat(data.score);
indication = data.indication ? "yes" : "no";
}
else {
throw new Error("Invalid API response: BrandSafetyTag must have either (BS_score, BS_indication) or (score, indication) fields");
}
return new BrandSafetyTag(score, indication);
}
}
/**
* Taxonomy classification (IAB, Google Topics, etc.).
*/
export class TaxonomyArticle {
/**
* @param id - Unique identifier for the taxonomy category
* @param label - Human-readable label for the category
* @param relevance - Relevance score for this classification
*/
constructor(id, label, relevance) {
this.id = id;
this.label = label;
this.relevance = relevance;
}
static fromApiResponse(data) {
return new TaxonomyArticle(data.ID, data.label, parseFloat(data.relevance));
}
}
/**
* Marketing categories including IAB taxonomies and Google Topics.
*/
export class MarketingCategories {
/**
* @param iabTier1 - IAB Content Taxonomy tier 1 categories
* @param iabTier2 - IAB Content Taxonomy tier 2 categories
* @param iabTier3 - IAB Content Taxonomy tier 3 categories
* @param iabAudienceTier3 - IAB Audience Taxonomy tier 3 categories
* @param iabAudienceTier4 - IAB Audience Taxonomy tier 4 categories
* @param iabAudienceTier5 - IAB Audience Taxonomy tier 5 categories
* @param googleTopics - Google Topics API classifications
* @param marketingItems - Custom marketing category items
*/
constructor(iabTier1, iabTier2, iabTier3, iabAudienceTier3, iabAudienceTier4, iabAudienceTier5, googleTopics, marketingItems) {
this.iabTier1 = iabTier1;
this.iabTier2 = iabTier2;
this.iabTier3 = iabTier3;
this.iabAudienceTier3 = iabAudienceTier3;
this.iabAudienceTier4 = iabAudienceTier4;
this.iabAudienceTier5 = iabAudienceTier5;
this.googleTopics = googleTopics;
this.marketingItems = marketingItems;
}
static fromApiResponse(data) {
return new MarketingCategories((data.iab_tier_1 || []).map(TaxonomyArticle.fromApiResponse), (data.iab_tier_2 || []).map(TaxonomyArticle.fromApiResponse), (data.iab_tier_3 || []).map(TaxonomyArticle.fromApiResponse), (data.iab_audience_tier_3 || []).map(TaxonomyArticle.fromApiResponse), (data.iab_audience_tier_4 || []).map(TaxonomyArticle.fromApiResponse), (data.iab_audience_tier_5 || []).map(TaxonomyArticle.fromApiResponse), (data.google_topics || []).map(TaxonomyArticle.fromApiResponse), (data.Marketing_items || []).map(TaxonomyArticle.fromApiResponse));
}
}
/**
* Smart tag classification.
*/
export class SmartTag {
/**
* @param id - Unique identifier for the smart tag
* @param name - Display name of the smart tag
*/
constructor(id, name) {
this.id = id;
this.name = name;
}
static fromApiResponse(data) {
return new SmartTag(data.ID, data.name);
}
}
/**
* Training tag for model improvement.
*/
export class TrainingTag {
/**
* @param articleId - Unique identifier of the article
* @param tag - Training tag value
* @param addedDate - Date when the training tag was added
*/
constructor(articleId, tag, addedDate) {
this.articleId = articleId;
this.tag = tag;
this.addedDate = addedDate;
}
static fromApiResponse(data) {
return new TrainingTag(data.articleID, data.tag, new Date(data.addedDate.replace(" ", "T")));
}
}
/**
* Similar article result.
*/
export class SimilarArticle {
/**
* @param articleId - Unique identifier of the similar article
* @param score - Similarity score
* @param headline - Optional article headline
* @param articleUrl - Optional URL of the article
* @param imageUrl - Optional URL of the article image
* @param published - Optional publication date
* @param publicationId - Optional publication identifier
*/
constructor(articleId, score, headline, articleUrl, imageUrl, published, publicationId) {
this.articleId = articleId;
this.score = score;
this.headline = headline;
this.articleUrl = articleUrl;
this.imageUrl = imageUrl;
this.published = published;
this.publicationId = publicationId;
}
static fromApiResponse(data) {
return new SimilarArticle(data.articleID, data.score, data.headline, data.articleURL, data.imageURL, data.published ? new Date(data.published) : undefined, data.publicationID);
}
}
/**
* Article metadata.
*/
export class Article {
/**
* @param articleId - Unique identifier of the article
* @param fetchDate - Date when the article was fetched
* @param published - Optional publication date
* @param headline - Optional article headline
* @param writer - Optional article author
* @param category - Optional article category
* @param content - Optional article content
* @param summary - Optional article summary
* @param publicationId - Optional publication identifier
* @param articleUrl - Optional URL of the article
* @param imageUrl - Optional URL of the article image
* @param includeInSim - Optional flag for similarity model inclusion
*/
constructor(articleId, fetchDate, published, headline, writer, category, content, summary, publicationId, articleUrl, imageUrl, includeInSim) {
this.articleId = articleId;
this.fetchDate = fetchDate;
this.published = published;
this.headline = headline;
this.writer = writer;
this.category = category;
this.content = content;
this.summary = summary;
this.publicationId = publicationId;
this.articleUrl = articleUrl;
this.imageUrl = imageUrl;
this.includeInSim = includeInSim;
}
static fromApiResponse(data) {
return new Article(data.articleID, new Date(data.fetchDate.replace(" ", "T")), data.published ? new Date(data.published) : undefined, data.headline, data.writer, data.category, data.content, data.summary, data.publicationID, data.articleURL, data.imageURL, data.includeInSim === "true" || data.includeInSim === true);
}
}
/**
* Complete AI topics response including tags, brand safety, and marketing categories.
*/
export class GetAiTopicsResponse {
/**
* @param tags - List of subject tags with relevance scores
* @param brandSafety - Brand safety classification
* @param marketingCategories - Marketing categories including IAB and Google Topics
* @param smartTags - List of smart tag classifications
*/
constructor(tags, brandSafety, marketingCategories, smartTags) {
this.tags = tags;
this.brandSafety = brandSafety;
this.marketingCategories = marketingCategories;
this.smartTags = smartTags;
}
static fromApiResponse(data) {
if (!data.brand_safety) {
throw new Error("Invalid API response: missing brand_safety field");
}
return new GetAiTopicsResponse((data.tags || []).map(Tag.fromApiResponse), BrandSafetyTag.fromApiResponse(data.brand_safety), MarketingCategories.fromApiResponse(data.marketing_categories || {}), (data.smart_tags || []).map(SmartTag.fromApiResponse));
}
}
//# sourceMappingURL=models.js.map