@ai-growth/n8n-nodes-wordpress
Version:
n8n node for WordPress integration with AI GROWTH - SEO WP plugin
874 lines • 37.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TaxonomyService = void 0;
const ErrorUtils_1 = require("../utils/ErrorUtils");
/**
* Serviço para gerenciamento de taxonomias do WordPress (categorias e tags)
*/
class TaxonomyService {
/**
* Construtor do serviço
* @param client Cliente WordPress
*/
constructor(client) {
this.taxonomyEndpoints = {
category: 'categories',
post_tag: 'tags'
};
this.client = client;
}
/**
* Obtém o endpoint para o tipo de taxonomia
* @param type Tipo de taxonomia
* @returns Endpoint da taxonomia
*/
getTaxonomyEndpoint(type) {
return this.taxonomyEndpoints[type];
}
/**
* Converte opções de consulta para parâmetros de requisição
* @param options Opções de consulta
* @returns Parâmetros da requisição
*/
getQueryParams(options) {
const params = {};
// Paginação
if (options.page) {
params.page = options.page.toString();
}
if (options.perPage) {
params.per_page = options.perPage.toString();
}
// Busca
if (options.search) {
params.search = options.search;
}
// Pai (apenas para categorias)
if (options.parent !== undefined) {
params.parent = options.parent.toString();
}
return params;
}
/**
* Verifica se uma taxonomia existe, considerando hierarquia
* @param type Tipo de taxonomia
* @param nameOrId Nome ou ID da taxonomia
* @param parentId ID do pai (opcional) para categorias hierárquicas
* @returns A taxonomia encontrada ou null
*/
async checkExists(type, nameOrId, parentId) {
try {
const endpoint = this.getTaxonomyEndpoint(type);
// Se nameOrId é número, buscar por ID
if (typeof nameOrId === 'number') {
try {
const result = await this.client.get(`${endpoint}/${nameOrId}`);
return result;
}
catch (error) {
// Se não encontrar pelo ID, retorna null
if (error instanceof ErrorUtils_1.WordPressError && error.type === ErrorUtils_1.WordPressErrorType.NOT_FOUND) {
return null;
}
throw error;
}
}
// Se nameOrId é string, buscar por nome considerando hierarquia
let params = { search: nameOrId, per_page: '100' };
// Para categorias, incluir parâmetro de pai se especificado
if (type === 'category' && parentId !== undefined) {
params.parent = parentId.toString();
}
const results = await this.client.get(endpoint, params);
// Verificar resultados para encontrar correspondência exata
if (Array.isArray(results) && results.length > 0) {
const matches = results.filter(item => {
if (typeof item.name === 'string' && typeof item.slug === 'string' && typeof nameOrId === 'string') {
const nameMatch = item.name.toLowerCase() === nameOrId.toLowerCase();
const slugMatch = item.slug.toLowerCase() === nameOrId.toLowerCase();
// Para categorias, verificar também a hierarquia
if (type === 'category' && parentId !== undefined) {
return (nameMatch || slugMatch) && item.parent === parentId;
}
return nameMatch || slugMatch;
}
return false;
});
// Retornar a primeira correspondência exata
if (matches.length > 0) {
return matches[0];
}
}
return null;
}
catch (error) {
if (error instanceof ErrorUtils_1.WordPressError) {
throw error;
}
throw new ErrorUtils_1.WordPressError(`Erro ao verificar existência de ${type}: ${nameOrId}`, ErrorUtils_1.WordPressErrorType.UNKNOWN, error);
}
}
/**
* Obtém uma categoria por ID ou nome
* @param idOrName ID ou nome da categoria
* @returns Categoria encontrada ou null
*/
async getCategory(idOrName) {
return this.checkExists('category', idOrName);
}
/**
* Obtém uma tag por ID ou nome
* @param idOrName ID ou nome da tag
* @returns Tag encontrada ou null
*/
async getTag(idOrName) {
return this.checkExists('post_tag', idOrName);
}
/**
* Obtém categorias com base em opções de filtro
* @param options Opções de consulta
* @returns Lista de categorias
*/
async getCategories(options = {}) {
try {
const endpoint = this.getTaxonomyEndpoint('category');
const params = this.getQueryParams(options);
const results = await this.client.get(endpoint, params);
return results;
}
catch (error) {
if (error instanceof ErrorUtils_1.WordPressError) {
throw error;
}
throw new ErrorUtils_1.WordPressError('Erro ao obter categorias', ErrorUtils_1.WordPressErrorType.UNKNOWN, error);
}
}
/**
* Obtém tags com base em opções de filtro
* @param options Opções de consulta
* @returns Lista de tags
*/
async getTags(options = {}) {
try {
const endpoint = this.getTaxonomyEndpoint('post_tag');
const params = this.getQueryParams(options);
const results = await this.client.get(endpoint, params);
return results;
}
catch (error) {
if (error instanceof ErrorUtils_1.WordPressError) {
throw error;
}
throw new ErrorUtils_1.WordPressError('Erro ao obter tags', ErrorUtils_1.WordPressErrorType.UNKNOWN, error);
}
}
/**
* Obtém hierarquia de categorias
* @param options Opções de consulta
* @returns Lista de categorias com hierarquia
*/
async getCategoryHierarchy(options = {}) {
try {
// Obter todas as categorias
const categories = await this.getCategories(options);
// Identificar categorias de nível superior (sem pai)
const topLevelCategories = categories.filter(cat => !cat.parent || cat.parent === 0);
// Função para obter categorias filhas
const getChildCategories = (parentId) => {
return categories.filter(cat => {
const catParent = typeof cat.parent === 'number' ? cat.parent : 0;
return catParent === parentId;
});
};
// Função para construir hierarquia recursivamente
const buildHierarchy = (category) => {
const children = getChildCategories(category.id);
return {
...category,
children: children.map(child => buildHierarchy(child))
};
};
// Construir hierarquia para cada categoria de nível superior
return topLevelCategories.map(cat => buildHierarchy(cat));
}
catch (error) {
if (error instanceof ErrorUtils_1.WordPressError) {
throw error;
}
throw new ErrorUtils_1.WordPressError('Erro ao obter hierarquia de categorias', ErrorUtils_1.WordPressErrorType.UNKNOWN, error);
}
}
/**
* Cria uma categoria
* @param data Dados da categoria
* @returns Categoria criada
*/
async createCategory(data) {
try {
const endpoint = this.getTaxonomyEndpoint('category');
const result = await this.client.post(endpoint, data);
return result;
}
catch (error) {
if (error instanceof ErrorUtils_1.WordPressError) {
throw error;
}
throw new ErrorUtils_1.WordPressError(`Erro ao criar categoria: ${data.name}`, ErrorUtils_1.WordPressErrorType.UNKNOWN, error);
}
}
/**
* Cria uma tag
* @param data Dados da tag
* @returns Tag criada
*/
async createTag(data) {
try {
const endpoint = this.getTaxonomyEndpoint('post_tag');
const result = await this.client.post(endpoint, data);
return result;
}
catch (error) {
if (error instanceof ErrorUtils_1.WordPressError) {
throw error;
}
throw new ErrorUtils_1.WordPressError(`Erro ao criar tag: ${data.name}`, ErrorUtils_1.WordPressErrorType.UNKNOWN, error);
}
}
/**
* Atualiza uma categoria
* @param id ID da categoria
* @param data Dados atualizados
* @returns Categoria atualizada
*/
async updateCategory(id, data) {
try {
const endpoint = this.getTaxonomyEndpoint('category');
const result = await this.client.put(`${endpoint}/${id}`, data);
return result;
}
catch (error) {
if (error instanceof ErrorUtils_1.WordPressError) {
throw error;
}
throw new ErrorUtils_1.WordPressError(`Erro ao atualizar categoria: ${id}`, ErrorUtils_1.WordPressErrorType.UNKNOWN, error);
}
}
/**
* Atualiza uma tag
* @param id ID da tag
* @param data Dados atualizados
* @returns Tag atualizada
*/
async updateTag(id, data) {
try {
const endpoint = this.getTaxonomyEndpoint('post_tag');
const result = await this.client.put(`${endpoint}/${id}`, data);
return result;
}
catch (error) {
if (error instanceof ErrorUtils_1.WordPressError) {
throw error;
}
throw new ErrorUtils_1.WordPressError(`Erro ao atualizar tag: ${id}`, ErrorUtils_1.WordPressErrorType.UNKNOWN, error);
}
}
/**
* Exclui uma categoria
* @param id ID da categoria
* @returns true se excluída com sucesso
*/
async deleteCategory(id) {
try {
const endpoint = this.getTaxonomyEndpoint('category');
await this.client.delete(`${endpoint}/${id}`);
return true;
}
catch (error) {
if (error instanceof ErrorUtils_1.WordPressError) {
throw error;
}
throw new ErrorUtils_1.WordPressError(`Erro ao excluir categoria: ${id}`, ErrorUtils_1.WordPressErrorType.UNKNOWN, error);
}
}
/**
* Exclui uma tag
* @param id ID da tag
* @returns true se excluída com sucesso
*/
async deleteTag(id) {
try {
const endpoint = this.getTaxonomyEndpoint('post_tag');
await this.client.delete(`${endpoint}/${id}`);
return true;
}
catch (error) {
if (error instanceof ErrorUtils_1.WordPressError) {
throw error;
}
throw new ErrorUtils_1.WordPressError(`Erro ao excluir tag: ${id}`, ErrorUtils_1.WordPressErrorType.UNKNOWN, error);
}
}
/**
* Garante que uma categoria existe (cria se não existir)
* @param name Nome da categoria
* @param parent ID da categoria pai (opcional)
* @returns Categoria existente ou nova
*/
async ensureCategory(name, parent) {
try {
// Verificar se categoria já existe, considerando hierarquia
const existingCategory = await this.checkExists('category', name, parent);
if (existingCategory) {
return existingCategory;
}
// Criar categoria se não existir
const data = { name };
if (parent) {
data.parent = parent;
}
try {
return await this.createCategory(data);
}
catch (error) {
// Se o erro for de categoria duplicada, tentar buscar novamente
if (error instanceof ErrorUtils_1.WordPressError &&
error.message &&
(error.message.includes('já existe') ||
error.message.includes('already exists') ||
error.message.includes('duplicate'))) {
// Tentar buscar a categoria novamente com uma busca mais abrangente
const searchResults = await this.getCategories({ search: name, perPage: 100 });
// Procurar pela categoria que corresponde exatamente
const exactMatch = searchResults.find(cat => {
const nameMatch = cat.name.toLowerCase() === name.toLowerCase();
// Se há parent especificado, verificar se a categoria tem o mesmo parent
if (parent !== undefined) {
return nameMatch && cat.parent === parent;
}
return nameMatch;
});
if (exactMatch) {
return exactMatch;
}
}
// Se não conseguiu resolver, relançar o erro original
throw error;
}
}
catch (error) {
if (error instanceof ErrorUtils_1.WordPressError) {
throw error;
}
throw new ErrorUtils_1.WordPressError(`Erro ao garantir existência da categoria: ${name}`, ErrorUtils_1.WordPressErrorType.UNKNOWN, error);
}
}
/**
* Garante que uma tag existe (cria se não existir)
* @param name Nome da tag
* @returns Tag existente ou nova
*/
async ensureTag(name) {
try {
// Verificar se tag já existe
const existingTag = await this.getTag(name);
if (existingTag) {
return existingTag;
}
// Criar tag se não existir
const data = { name };
return await this.createTag(data);
}
catch (error) {
if (error instanceof ErrorUtils_1.WordPressError) {
throw error;
}
throw new ErrorUtils_1.WordPressError(`Erro ao garantir existência da tag: ${name}`, ErrorUtils_1.WordPressErrorType.UNKNOWN, error);
}
}
/**
* Garante que múltiplas categorias existam
* @param names Nomes das categorias
* @returns Categorias existentes ou novas
*/
async ensureCategories(names) {
const results = [];
// Processar categorias sequencialmente para evitar race conditions
for (const name of names) {
try {
const category = await this.ensureCategory(name);
results.push(category);
}
catch (error) {
// Verificar se é erro de categoria duplicada
if (error instanceof Error &&
(error.message.includes('Um termo com o nome fornecido já existe') ||
error.message.includes('A term with the name provided already exists'))) {
// Tentar buscar a categoria existente
try {
const existingCategory = await this.checkExists('category', name);
if (existingCategory) {
results.push(existingCategory);
continue;
}
}
catch (searchError) {
// Se não conseguir buscar, continuar com o erro original
}
}
// Para outros erros ou se não conseguir encontrar a categoria,
// registrar o erro mas continuar o processamento das demais categorias
console.warn(`Aviso: Falha ao processar categoria "${name}": ${error instanceof Error ? error.message : 'Unknown error'}`);
// Continuar processamento das outras categorias em vez de interromper
continue;
}
}
return results;
}
/**
* Garante que múltiplas tags existam
* @param names Nomes das tags
* @returns Tags existentes ou novas
*/
async ensureTags(names) {
const results = [];
// Processar tags sequencialmente para evitar race conditions
for (const name of names) {
try {
const tag = await this.ensureTag(name);
results.push(tag);
}
catch (error) {
// Verificar se é erro de tag duplicada
if (error instanceof Error &&
(error.message.includes('Um termo com o nome fornecido já existe') ||
error.message.includes('A term with the name provided already exists'))) {
// Tentar buscar a tag existente
try {
const existingTag = await this.checkExists('post_tag', name);
if (existingTag) {
results.push(existingTag);
continue;
}
}
catch (searchError) {
// Se não conseguir buscar, continuar com o erro original
}
}
// Para outros erros ou se não conseguir encontrar a tag,
// registrar o erro mas continuar o processamento das demais tags
console.warn(`Aviso: Falha ao processar tag "${name}": ${error instanceof Error ? error.message : 'Unknown error'}`);
// Continuar processamento das outras tags em vez de interromper
continue;
}
}
return results;
}
/**
* Gera um slug a partir do nome da taxonomia
* @param name Nome da taxonomia
* @returns Slug gerado
*/
generateSlug(name) {
if (!name) {
return '';
}
// Converter para minúsculas
let slug = name.toLowerCase();
// Remover acentos
slug = slug.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
// Substituir espaços por hífens
slug = slug.replace(/\s+/g, '-');
// Remover caracteres especiais e manter apenas alfanuméricos e hífens
slug = slug.replace(/[^a-z0-9-]/g, '');
// Remover hífens duplicados
slug = slug.replace(/-+/g, '-');
// Remover hífens do início e fim
slug = slug.replace(/^-|-$/g, '');
return slug;
}
/**
* Associa categorias e tags a um post
* @param postId ID do post
* @param categories Nomes ou slugs das categorias
* @param tags Nomes ou slugs das tags
* @returns Post atualizado
*/
async associateTaxonomiesWithPost(postId, categories = [], tags = []) {
try {
// Validar entrada
if (!postId || postId <= 0) {
throw new ErrorUtils_1.WordPressError(`Invalid post ID: ${postId}`, ErrorUtils_1.WordPressErrorType.VALIDATION);
}
// Verificar se o post existe
const endpoint = 'posts';
let post;
try {
post = await this.client.get(`${endpoint}/${postId}`);
}
catch (error) {
throw new ErrorUtils_1.WordPressError(`Post não encontrado: ${postId}`, ErrorUtils_1.WordPressErrorType.NOT_FOUND, undefined, error);
}
// Processar categorias - garantir que existam e converter para IDs numéricos
let categoryIds = [];
if (categories.length > 0) {
const processedCategories = [];
for (const category of categories) {
// Validar entrada
if (category === null || category === undefined || category === '') {
continue; // Pular valores vazios
}
if (typeof category === 'number') {
// Se é um número, verificar se a categoria existe
if (category <= 0) {
throw new ErrorUtils_1.WordPressError(`Invalid category ID: ${category}. Category IDs must be positive numbers.`, ErrorUtils_1.WordPressErrorType.VALIDATION);
}
const existingCategory = await this.getCategory(category);
if (existingCategory) {
categoryIds.push(category);
}
else {
throw new ErrorUtils_1.WordPressError(`Category with ID ${category} not found. Please verify the category exists or use category names instead.`, ErrorUtils_1.WordPressErrorType.NOT_FOUND);
}
}
else {
// Se é uma string, validar e adicionar à lista para processamento
const categoryName = category.toString().trim();
if (categoryName.length === 0) {
continue; // Pular strings vazias
}
if (categoryName.length > 200) {
throw new ErrorUtils_1.WordPressError(`Category name too long: "${categoryName}". Maximum length is 200 characters.`, ErrorUtils_1.WordPressErrorType.VALIDATION);
}
processedCategories.push(categoryName);
}
}
// Garantir que todas as categorias por nome existam
if (processedCategories.length > 0) {
try {
const categoryResults = await this.ensureCategories(processedCategories);
categoryIds.push(...categoryResults.map(cat => cat.id));
}
catch (error) {
throw new ErrorUtils_1.WordPressError(`Failed to process categories: ${processedCategories.join(', ')}. ${error instanceof Error ? error.message : 'Unknown error'}`, ErrorUtils_1.WordPressErrorType.VALIDATION, undefined, error);
}
}
}
// Processar tags - garantir que existam e converter para IDs numéricos
let tagIds = [];
if (tags.length > 0) {
const processedTags = [];
for (const tag of tags) {
// Validar entrada
if (tag === null || tag === undefined || tag === '') {
continue; // Pular valores vazios
}
if (typeof tag === 'number') {
// Se é um número, verificar se a tag existe
if (tag <= 0) {
throw new ErrorUtils_1.WordPressError(`Invalid tag ID: ${tag}. Tag IDs must be positive numbers.`, ErrorUtils_1.WordPressErrorType.VALIDATION);
}
const existingTag = await this.getTag(tag);
if (existingTag) {
tagIds.push(tag);
}
else {
throw new ErrorUtils_1.WordPressError(`Tag with ID ${tag} not found. Please verify the tag exists or use tag names instead.`, ErrorUtils_1.WordPressErrorType.NOT_FOUND);
}
}
else {
// Se é uma string, validar e adicionar à lista para processamento
const tagName = tag.toString().trim();
if (tagName.length === 0) {
continue; // Pular strings vazias
}
if (tagName.length > 200) {
throw new ErrorUtils_1.WordPressError(`Tag name too long: "${tagName}". Maximum length is 200 characters.`, ErrorUtils_1.WordPressErrorType.VALIDATION);
}
processedTags.push(tagName);
}
}
// Garantir que todas as tags por nome existam
if (processedTags.length > 0) {
try {
const tagResults = await this.ensureTags(processedTags);
tagIds.push(...tagResults.map(tag => tag.id));
}
catch (error) {
throw new ErrorUtils_1.WordPressError(`Failed to process tags: ${processedTags.join(', ')}. ${error instanceof Error ? error.message : 'Unknown error'}`, ErrorUtils_1.WordPressErrorType.VALIDATION, undefined, error);
}
}
}
// Atualizar post com as taxonomias (apenas IDs numéricos)
const data = {};
// Validar que todos os IDs são números válidos antes de enviar
if (categoryIds.length > 0) {
const validCategoryIds = categoryIds.filter(id => typeof id === 'number' && id > 0);
if (validCategoryIds.length !== categoryIds.length) {
throw new ErrorUtils_1.WordPressError(`Invalid category IDs detected. All category IDs must be positive numbers.`, ErrorUtils_1.WordPressErrorType.VALIDATION);
}
data.categories = validCategoryIds;
}
if (tagIds.length > 0) {
const validTagIds = tagIds.filter(id => typeof id === 'number' && id > 0);
if (validTagIds.length !== tagIds.length) {
throw new ErrorUtils_1.WordPressError(`Invalid tag IDs detected. All tag IDs must be positive numbers.`, ErrorUtils_1.WordPressErrorType.VALIDATION);
}
data.tags = validTagIds;
}
// Se não há taxonomias para associar, retornar o post atual
if (Object.keys(data).length === 0) {
return post;
}
// Atualizar o post com apenas IDs numéricos
try {
const updatedPost = await this.client.put(`${endpoint}/${postId}`, data);
return updatedPost;
}
catch (error) {
// Verificar se é um erro de parâmetros inválidos
if (error instanceof ErrorUtils_1.WordPressError && error.statusCode === 400) {
throw new ErrorUtils_1.WordPressError(`Failed to associate taxonomies with post ${postId}. WordPress API rejected the request. Ensure all category and tag IDs are valid and exist in WordPress.`, ErrorUtils_1.WordPressErrorType.VALIDATION, error.statusCode, error.originalError);
}
throw error;
}
}
catch (error) {
if (error instanceof ErrorUtils_1.WordPressError) {
throw error;
}
throw new ErrorUtils_1.WordPressError(`Erro ao associar taxonomias ao post: ${postId}`, ErrorUtils_1.WordPressErrorType.UNKNOWN, error);
}
}
/**
* Associa categorias e tags a uma página
* @param pageId ID da página
* @param categories Nomes ou slugs das categorias
* @param tags Nomes ou slugs das tags
* @returns Página atualizada
*/
async associateTaxonomiesWithPage(pageId, categories = [], tags = []) {
try {
// Verificar se a página existe
const endpoint = 'pages';
let page;
try {
page = await this.client.get(`${endpoint}/${pageId}`);
}
catch (error) {
throw new ErrorUtils_1.WordPressError(`Página não encontrada: ${pageId}`, ErrorUtils_1.WordPressErrorType.NOT_FOUND, error);
}
// Nem todas as instalações WordPress suportam categorias e tags em páginas
// Verificar se a instalação atual suporta
const data = {};
// Processar categorias para páginas
if (categories.length > 0) {
try {
const processedCategories = [];
let categoryIds = [];
for (const category of categories) {
if (typeof category === 'number') {
// Se é um número, verificar se a categoria existe
const existingCategory = await this.getCategory(category);
if (existingCategory) {
categoryIds.push(category);
}
}
else {
// Se é uma string, adicionar à lista para processamento
processedCategories.push(category.toString().trim());
}
}
// Garantir que todas as categorias por nome existam
if (processedCategories.length > 0) {
const categoryResults = await this.ensureCategories(processedCategories);
categoryIds.push(...categoryResults.map(cat => cat.id));
}
if (categoryIds.length > 0) {
data.categories = categoryIds;
}
}
catch (error) {
// Ignorar erros - nem todas as instalações suportam categorias em páginas
console.warn('Aviso: Esta instalação WordPress pode não suportar categorias em páginas');
}
}
// Processar tags para páginas
if (tags.length > 0) {
try {
const processedTags = [];
let tagIds = [];
for (const tag of tags) {
if (typeof tag === 'number') {
// Se é um número, verificar se a tag existe
const existingTag = await this.getTag(tag);
if (existingTag) {
tagIds.push(tag);
}
}
else {
// Se é uma string, adicionar à lista para processamento
processedTags.push(tag.toString().trim());
}
}
// Garantir que todas as tags por nome existam
if (processedTags.length > 0) {
const tagResults = await this.ensureTags(processedTags);
tagIds.push(...tagResults.map(tag => tag.id));
}
if (tagIds.length > 0) {
data.tags = tagIds;
}
}
catch (error) {
// Ignorar erros - nem todas as instalações suportam tags em páginas
console.warn('Aviso: Esta instalação WordPress pode não suportar tags em páginas');
}
}
// Se não há taxonomias para associar, retornar a página atual
if (Object.keys(data).length === 0) {
return page;
}
// Atualizar a página
const updatedPage = await this.client.put(`${endpoint}/${pageId}`, data);
return updatedPage;
}
catch (error) {
if (error instanceof ErrorUtils_1.WordPressError) {
throw error;
}
throw new ErrorUtils_1.WordPressError(`Erro ao associar taxonomias à página: ${pageId}`, ErrorUtils_1.WordPressErrorType.UNKNOWN, error);
}
}
/**
* Obtém subcategorias de uma categoria específica
* @param parentId ID da categoria pai
* @param options Opções de consulta
* @returns Lista de subcategorias
*/
async getSubcategories(parentId, options = {}) {
try {
// Adicionar filtro por pai
const queryOptions = {
...options,
parent: parentId
};
return await this.getCategories(queryOptions);
}
catch (error) {
if (error instanceof ErrorUtils_1.WordPressError) {
throw error;
}
throw new ErrorUtils_1.WordPressError(`Erro ao obter subcategorias de: ${parentId}`, ErrorUtils_1.WordPressErrorType.UNKNOWN, error);
}
}
/**
* Obtém o caminho completo da hierarquia de uma categoria
* @param categoryId ID da categoria
* @returns Lista de categorias do topo até a categoria especificada
*/
async getCategoryPath(categoryId) {
try {
// Obter a categoria
const category = await this.getCategory(categoryId);
if (!category) {
throw new ErrorUtils_1.WordPressError(`Categoria não encontrada: ${categoryId}`, ErrorUtils_1.WordPressErrorType.NOT_FOUND);
}
const path = [category];
// Se tem pai, buscar o caminho do pai recursivamente
if (category.parent && category.parent > 0) {
const parentPath = await this.getCategoryPath(category.parent);
return [...parentPath, category];
}
return path;
}
catch (error) {
if (error instanceof ErrorUtils_1.WordPressError) {
throw error;
}
throw new ErrorUtils_1.WordPressError(`Erro ao obter caminho da categoria: ${categoryId}`, ErrorUtils_1.WordPressErrorType.UNKNOWN, error);
}
}
/**
* Obtém todas as categorias e organiza em uma estrutura hierárquica de árvore
* @param options Opções de consulta
* @returns Árvore de categorias
*/
async getCategoryTree(options = {}) {
try {
// Obter hierarquia de categorias
const hierarchicalCategories = await this.getCategoryHierarchy(options);
// Converter para formato de árvore
const buildTree = (categories) => {
return categories.map(category => {
const node = {
id: category.id,
name: category.name,
slug: category.slug,
description: category.description || '',
count: category.count || 0
};
if (category.children && category.children.length > 0) {
node.children = buildTree(category.children);
}
else {
node.children = [];
}
return node;
});
};
return {
count: hierarchicalCategories.length,
items: buildTree(hierarchicalCategories)
};
}
catch (error) {
if (error instanceof ErrorUtils_1.WordPressError) {
throw error;
}
throw new ErrorUtils_1.WordPressError('Erro ao obter árvore de categorias', ErrorUtils_1.WordPressErrorType.UNKNOWN, error);
}
}
/**
* Obtém estatísticas sobre taxonomias
* @returns Estatísticas de taxonomias
*/
async getTaxonomyStats() {
try {
// Obter categorias
const categories = await this.getCategories({
perPage: 1,
page: 1
});
// Obter total de categorias
const totalCategories = parseInt(this.client.getLastResponseHeader('X-WP-Total') || '0');
// Obter categorias de nível superior
const topLevelCategories = await this.getCategories({
parent: 0
});
// Obter tags
const tags = await this.getTags({
perPage: 1,
page: 1
});
// Obter total de tags
const totalTags = parseInt(this.client.getLastResponseHeader('X-WP-Total') || '0');
return {
categories: {
total: totalCategories,
topLevel: topLevelCategories.length
},
tags: {
total: totalTags
}
};
}
catch (error) {
if (error instanceof ErrorUtils_1.WordPressError) {
throw error;
}
throw new ErrorUtils_1.WordPressError('Erro ao obter estatísticas de taxonomias', ErrorUtils_1.WordPressErrorType.UNKNOWN, error);
}
}
}
exports.TaxonomyService = TaxonomyService;
//# sourceMappingURL=TaxonomyService.js.map