bling-mcp
Version:
API MCP para integração com Bling
125 lines (118 loc) • 4.01 kB
text/typescript
import { blingClient, renovarToken } from '../blingClient.js';
import axios from 'axios';
/**
* Interface para parâmetros de listagem de vendedores
*/
interface ListarVendedoresParams {
pagina?: number;
limite?: number;
}
/**
* Interface para o retorno de um vendedor
*/
export interface Vendedor {
id: string;
nome: string;
[key: string]: any;
}
/**
* Interface para resposta de listagem de vendedores
*/
interface VendedoresResponse {
data: Vendedor[];
pagination: {
page: number;
totalPages: number;
totalItems: number;
limit: number;
};
}
/**
* Lista os vendedores cadastrados no Bling
* @param params - Parâmetros para a listagem de vendedores
* @returns Resposta com os vendedores e informações de paginação
*/
export async function listarVendedores(params?: ListarVendedoresParams): Promise<VendedoresResponse> {
try {
console.log(`Buscando vendedores com parâmetros:`, JSON.stringify(params, null, 2));
const response = await blingClient.get('/vendedores', { params });
console.log('Status:', response.status);
if (response.data && Array.isArray(response.data.data)) {
return {
data: response.data.data as Vendedor[],
pagination: {
page: response.data.page || 1,
totalPages: response.data.totalPages || 1,
totalItems: response.data.data.length,
limit: response.data.limit || response.data.data.length
}
};
}
if (Array.isArray(response.data)) {
return {
data: response.data,
pagination: {
page: 1,
totalPages: 1,
totalItems: response.data.length,
limit: 50
}
};
}
return {
data: Array.isArray(response.data) ? response.data : (response.data && Array.isArray(response.data.data)) ? response.data.data : [],
pagination: {
page: 1,
totalPages: 1,
totalItems: Array.isArray(response.data) ? response.data.length : (response.data && Array.isArray(response.data.data)) ? response.data.data.length : 0,
limit: 50
}
};
} catch (error) {
return handleApiError(error, 'listarVendedores', params);
}
}
/**
* Obtém um vendedor pelo ID
* @param id - ID do vendedor
* @returns Dados do vendedor
*/
export async function obterVendedor(id: string): Promise<Vendedor> {
try {
console.log(`Buscando vendedor com ID: ${id}`);
const response = await blingClient.get(`/vendedores/${id}`);
console.log('Status:', response.status);
if (response.data && response.data.data) {
return response.data.data as Vendedor;
}
return response.data as Vendedor;
} catch (error) {
return handleApiError(error, 'obterVendedor', { id });
}
}
/**
* Função auxiliar para tratamento de erros da API
*/
async function handleApiError(error: unknown, funcName: string, params: any): Promise<any> {
if (axios.isAxiosError(error) && error.response?.status === 401) {
// Token expirado, tentar renovar
console.log(`Token expirado (401) em ${funcName}, tentando renovar...`);
try {
await renovarToken();
if (funcName === 'listarVendedores') return listarVendedores(params as ListarVendedoresParams);
if (funcName === 'obterVendedor') return obterVendedor(params.id);
throw new Error(`Função desconhecida: ${funcName}`);
} catch (renewError) {
console.error(`Erro ao renovar token em ${funcName}:`, renewError);
throw new Error(`Falha na renovação do token: ${renewError instanceof Error ? renewError.message : 'Erro desconhecido'}`);
}
}
if (axios.isAxiosError(error)) {
console.error(`Erro em ${funcName}:`);
console.error('Status:', error.response?.status);
console.error('Data:', JSON.stringify(error.response?.data, null, 2));
throw new Error(`Erro ao ${funcName}: ${error.response?.data?.message || error.message}`);
}
console.error(`Erro não relacionado ao Axios em ${funcName}:`, error);
throw error;
}