UNPKG

@ai-growth/n8n-nodes-wordpress

Version:

n8n node for WordPress integration with AI GROWTH - SEO WP plugin

874 lines 37.4 kB
"use strict"; 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