+32
| IPTU API - PROPRIETARY LICENSE | ||
| Copyright (c) 2025-2026 IPTU API. All rights reserved. | ||
| This software and associated documentation files (the "Software") are the | ||
| exclusive property of IPTU API. The Software is licensed, not sold. | ||
| GRANT OF LICENSE: | ||
| Subject to the terms of this license and your compliance with the IPTU API | ||
| Terms of Service (https://iptuapi.com.br/termos), you are granted a limited, | ||
| non-exclusive, non-transferable license to use the Software solely for the | ||
| purpose of accessing the IPTU API services. | ||
| RESTRICTIONS: | ||
| You may NOT: | ||
| - Copy, modify, or distribute the Software | ||
| - Reverse engineer, decompile, or disassemble the Software | ||
| - Sublicense, rent, lease, or lend the Software | ||
| - Use the Software for any purpose other than accessing IPTU API services | ||
| - Remove or alter any proprietary notices | ||
| TERMINATION: | ||
| This license is effective until terminated. It will terminate automatically | ||
| if you fail to comply with any term of this license or the IPTU API Terms | ||
| of Service. | ||
| DISCLAIMER: | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED. IN NO EVENT SHALL IPTU API BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
| OTHER LIABILITY ARISING FROM THE USE OF THE SOFTWARE. | ||
| For questions, contact: contato@iptuapi.com.br |
+357
-434
| /** | ||
| * Tipos e interfaces para a IPTU API. | ||
| * IPTU API - JavaScript/TypeScript SDK | ||
| * | ||
| * SDK oficial para integração com a IPTU API. | ||
| * Suporta retry automático, logging e rate limit tracking. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * import { IPTUClient } from 'iptuapi'; | ||
| * | ||
| * const client = new IPTUClient('sua_api_key'); | ||
| * const resultado = await client.consultaEndereco('Avenida Paulista', '1000'); | ||
| * console.log(resultado); | ||
| * ``` | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Com configuração customizada | ||
| * const client = new IPTUClient('sua_api_key', { | ||
| * timeout: 60000, | ||
| * retries: 5, | ||
| * logger: console, | ||
| * }); | ||
| * ``` | ||
| */ | ||
| interface RetryConfig { | ||
| maxRetries: number; | ||
| initialDelay: number; | ||
| maxDelay: number; | ||
| backoffFactor: number; | ||
| retryableStatusCodes: number[]; | ||
| } | ||
| interface ClientConfig { | ||
| baseUrl: string; | ||
| timeout: number; | ||
| retryConfig: RetryConfig; | ||
| } | ||
| interface ClientOptions { | ||
| baseUrl?: string; | ||
| timeout?: number; | ||
| retryConfig?: Partial<RetryConfig>; | ||
| } | ||
| type Cidade = 'sp' | 'bh' | 'recife' | 'poa' | 'fortaleza' | 'curitiba' | 'rj' | 'brasilia'; | ||
| declare const CidadeEnum: { | ||
| readonly SAO_PAULO: Cidade; | ||
| readonly BELO_HORIZONTE: Cidade; | ||
| readonly RECIFE: Cidade; | ||
| readonly PORTO_ALEGRE: Cidade; | ||
| readonly FORTALEZA: Cidade; | ||
| readonly CURITIBA: Cidade; | ||
| readonly RIO_DE_JANEIRO: Cidade; | ||
| readonly BRASILIA: Cidade; | ||
| }; | ||
| interface RateLimitInfo { | ||
| limit: number; | ||
| remaining: number; | ||
| resetAt: Date; | ||
| reset: number; | ||
| resetDate: Date; | ||
| } | ||
| interface Imovel { | ||
| interface ConsultaEnderecoParams { | ||
| logradouro: string; | ||
| numero?: string; | ||
| complemento?: string; | ||
| cidade?: Cidade; | ||
| incluirHistorico?: boolean; | ||
| incluirComparaveis?: boolean; | ||
| incluirZoneamento?: boolean; | ||
| } | ||
| interface ConsultaEnderecoResult { | ||
| sql: string; | ||
| logradouro: string; | ||
| numero: string; | ||
| bairro: string; | ||
| numero?: string; | ||
| complemento?: string; | ||
| bairro?: string; | ||
| cep?: string; | ||
| areaTerreno?: number; | ||
| areaConstruida?: number; | ||
| valorVenal?: number; | ||
| valorVenalTerreno?: number; | ||
| valorVenalConstrucao?: number; | ||
| anoConstrucao?: number; | ||
| uso?: string; | ||
| padrao?: string; | ||
| testada?: number; | ||
| fracaoIdeal?: number; | ||
| quantidadePavimentos?: number; | ||
| } | ||
| interface Zoneamento { | ||
| zona: string; | ||
| usoPermitido: string; | ||
| coeficienteAproveitamento?: number; | ||
| taxaOcupacao?: number; | ||
| gabarito?: number; | ||
| recuoFrontal?: number; | ||
| legislacao?: string; | ||
| } | ||
| interface Valuation { | ||
| valorEstimado: number; | ||
| valorMinimo: number; | ||
| valorMaximo: number; | ||
| confianca: number; | ||
| valorM2: number; | ||
| metodologia: string; | ||
| dataReferencia: string; | ||
| } | ||
| interface ValuationParams { | ||
| areaTerreno: number; | ||
| areaConstruida: number; | ||
| bairro: string; | ||
| cidade?: string; | ||
| area_terreno?: number; | ||
| area_construida?: number; | ||
| valor_venal_terreno?: number; | ||
| valor_venal_construcao?: number; | ||
| valor_venal_total?: number; | ||
| iptu_valor?: number; | ||
| ano_construcao?: number; | ||
| tipo_uso?: string; | ||
| zona?: string; | ||
| tipoUso?: string; | ||
| tipoPadrao?: string; | ||
| anoConstrucao?: number; | ||
| historico?: HistoricoItem[]; | ||
| comparaveis?: ComparavelItem[]; | ||
| zoneamento?: ZoneamentoResult; | ||
| } | ||
| interface Comparavel { | ||
| interface ConsultaSQLResult { | ||
| sql: string; | ||
| logradouro: string; | ||
| bairro: string; | ||
| areaConstruida: number; | ||
| valorVenal: number; | ||
| valorM2: number; | ||
| distanciaKm?: number; | ||
| ano?: number; | ||
| valor_venal?: number; | ||
| valor_venal_terreno?: number; | ||
| valor_venal_construcao?: number; | ||
| valor_venal_total?: number; | ||
| iptu_valor?: number; | ||
| logradouro?: string; | ||
| numero?: string; | ||
| bairro?: string; | ||
| area_terreno?: number; | ||
| area_construida?: number; | ||
| } | ||
| interface ComparablesParams { | ||
| bairro: string; | ||
| areaMin: number; | ||
| areaMax: number; | ||
| cidade?: string; | ||
| limit?: number; | ||
| interface HistoricoItem { | ||
| ano: number; | ||
| valor_venal_terreno?: number; | ||
| valor_venal_construcao?: number; | ||
| valor_venal_total?: number; | ||
| iptu_valor?: number; | ||
| } | ||
| interface ITBIStatus { | ||
| protocolo: string; | ||
| status: string; | ||
| dataSolicitacao: string; | ||
| valorTransacao: number; | ||
| valorVenalReferencia: number; | ||
| baseCalculo: number; | ||
| aliquota: number; | ||
| valorITBI: number; | ||
| dataAprovacao?: string; | ||
| interface ComparavelItem { | ||
| sql?: string; | ||
| logradouro?: string; | ||
| numero?: string; | ||
| bairro?: string; | ||
| area_terreno?: number; | ||
| area_construida?: number; | ||
| valor_venal_total?: number; | ||
| distancia_metros?: number; | ||
| } | ||
| interface ITBICalculo { | ||
| sql: string; | ||
| valorTransacao: number; | ||
| valorVenalReferencia: number; | ||
| baseCalculo: number; | ||
| aliquota: number; | ||
| valorITBI: number; | ||
| isencaoAplicavel: boolean; | ||
| fundamentacaoLegal: string; | ||
| interface ZoneamentoResult { | ||
| zona?: string; | ||
| zona_descricao?: string; | ||
| coeficiente_aproveitamento_basico?: number; | ||
| coeficiente_aproveitamento_maximo?: number; | ||
| taxa_ocupacao_maxima?: number; | ||
| gabarito_maximo?: number; | ||
| } | ||
| interface ITBICalculoParams { | ||
| sql: string; | ||
| valorTransacao: number; | ||
| cidade?: string; | ||
| interface ValuationParams { | ||
| area_terreno: number; | ||
| area_construida: number; | ||
| bairro: string; | ||
| zona: string; | ||
| tipo_uso: string; | ||
| tipo_padrao: string; | ||
| ano_construcao?: number; | ||
| cidade?: Cidade; | ||
| } | ||
| interface ITBIHistorico { | ||
| protocolo: string; | ||
| dataTransacao: string; | ||
| tipoTransacao: string; | ||
| valorTransacao: number; | ||
| valorITBI: number; | ||
| interface ValuationResult { | ||
| valor_estimado: number; | ||
| valor_minimo?: number; | ||
| valor_maximo?: number; | ||
| confianca?: number; | ||
| metodo?: string; | ||
| comparaveis_utilizados?: number; | ||
| data_avaliacao?: string; | ||
| } | ||
| interface ITBIAliquota { | ||
| cidade: string; | ||
| aliquotaPadrao: number; | ||
| aliquotaFinanciamentoSFH: number; | ||
| valorMinimoIsencao: number; | ||
| baseLegal: string; | ||
| vigencia: string; | ||
| interface BatchValuationResult { | ||
| resultados: ValuationResult[]; | ||
| total_processados: number; | ||
| total_erros: number; | ||
| erros?: Array<{ | ||
| index: number; | ||
| error: string; | ||
| }>; | ||
| } | ||
| interface ITBIIsencao { | ||
| tipo: string; | ||
| descricao: string; | ||
| requisitos: string[]; | ||
| baseLegal: string; | ||
| declare class IPTUAPIError extends Error { | ||
| readonly statusCode?: number; | ||
| readonly requestId?: string; | ||
| readonly responseBody?: Record<string, unknown>; | ||
| constructor(message: string, statusCode?: number, requestId?: string, responseBody?: Record<string, unknown>); | ||
| get isRetryable(): boolean; | ||
| } | ||
| interface Pessoa { | ||
| nome: string; | ||
| documento: string; | ||
| email?: string; | ||
| declare class AuthenticationError extends IPTUAPIError { | ||
| constructor(message?: string, requestId?: string, responseBody?: Record<string, unknown>); | ||
| } | ||
| interface ITBIGuiaParams { | ||
| sql: string; | ||
| valorTransacao: number; | ||
| comprador: Pessoa; | ||
| vendedor: Pessoa; | ||
| cidade?: string; | ||
| declare class ForbiddenError extends IPTUAPIError { | ||
| readonly requiredPlan?: string; | ||
| constructor(message?: string, requiredPlan?: string, requestId?: string, responseBody?: Record<string, unknown>); | ||
| } | ||
| interface ITBIGuia { | ||
| protocolo: string; | ||
| codigoBarras: string; | ||
| linhaDigitavel: string; | ||
| dataEmissao: string; | ||
| dataVencimento: string; | ||
| valorITBI: number; | ||
| declare class NotFoundError extends IPTUAPIError { | ||
| constructor(message?: string, requestId?: string, responseBody?: Record<string, unknown>); | ||
| } | ||
| interface ITBIValidacao { | ||
| protocolo: string; | ||
| valido: boolean; | ||
| pago: boolean; | ||
| dataPagamento?: string; | ||
| valorPago?: number; | ||
| declare class RateLimitError extends IPTUAPIError { | ||
| readonly retryAfter?: number; | ||
| readonly limit?: number; | ||
| readonly remaining?: number; | ||
| constructor(message?: string, retryAfter?: number, limit?: number, remaining?: number, requestId?: string, responseBody?: Record<string, unknown>); | ||
| get isRetryable(): boolean; | ||
| } | ||
| interface ITBISimularParams { | ||
| valorTransacao: number; | ||
| cidade?: string; | ||
| tipoFinanciamento?: 'sfh' | 'nao_sfh'; | ||
| valorFinanciado?: number; | ||
| declare class ValidationError extends IPTUAPIError { | ||
| readonly errors?: Array<{ | ||
| field: string; | ||
| message: string; | ||
| }>; | ||
| constructor(message?: string, errors?: Array<{ | ||
| field: string; | ||
| message: string; | ||
| }>, requestId?: string, responseBody?: Record<string, unknown>); | ||
| } | ||
| interface ITBISimulacao { | ||
| valorTransacao: number; | ||
| valorFinanciado: number; | ||
| valorNaoFinanciado: number; | ||
| aliquotaSFH: number; | ||
| aliquotaPadrao: number; | ||
| valorITBIFinanciado: number; | ||
| valorITBINaoFinanciado: number; | ||
| valorITBITotal: number; | ||
| economiaSFH: number; | ||
| declare class ServerError extends IPTUAPIError { | ||
| constructor(message?: string, statusCode?: number, requestId?: string, responseBody?: Record<string, unknown>); | ||
| get isRetryable(): boolean; | ||
| } | ||
| interface EvaluateParams { | ||
| /** Numero SQL do imovel (alternativa ao endereco) */ | ||
| sql?: string; | ||
| /** Nome da rua/avenida (alternativa ao SQL) */ | ||
| logradouro?: string; | ||
| /** Numero do imovel */ | ||
| numero?: number; | ||
| /** Apartamento, sala, etc. */ | ||
| complemento?: string; | ||
| /** Bairro */ | ||
| bairro?: string; | ||
| /** Codigo da cidade (sp, bh) */ | ||
| cidade?: string; | ||
| /** Incluir estimativa baseada em ITBI */ | ||
| incluirItbi?: boolean; | ||
| /** Incluir lista de imoveis comparaveis */ | ||
| incluirComparaveis?: boolean; | ||
| declare class TimeoutError extends IPTUAPIError { | ||
| readonly timeoutMs?: number; | ||
| constructor(message?: string, timeoutMs?: number); | ||
| get isRetryable(): boolean; | ||
| } | ||
| interface AVMEstimate { | ||
| /** Valor estimado em R$ */ | ||
| valorEstimado: number; | ||
| /** Valor minimo do intervalo */ | ||
| valorMinimo: number; | ||
| /** Valor maximo do intervalo */ | ||
| valorMaximo: number; | ||
| /** Valor por m2 */ | ||
| valorM2: number; | ||
| /** Nivel de confianca (0-1) */ | ||
| confianca: number; | ||
| /** Versao do modelo */ | ||
| modeloVersao: string; | ||
| declare class NetworkError extends IPTUAPIError { | ||
| readonly originalError?: Error; | ||
| constructor(message?: string, originalError?: Error); | ||
| get isRetryable(): boolean; | ||
| } | ||
| interface ITBIMarketEstimate { | ||
| /** Valor estimado em R$ */ | ||
| valorEstimado: number; | ||
| /** Valor minimo da faixa */ | ||
| faixaMinima: number; | ||
| /** Valor maximo da faixa */ | ||
| faixaMaxima: number; | ||
| /** Valor por m2 (mediana) */ | ||
| valorM2Mediana: number; | ||
| /** Total de transacoes analisadas */ | ||
| totalTransacoes: number; | ||
| /** Periodo considerado */ | ||
| periodo: string; | ||
| /** Fonte dos dados */ | ||
| fonte: string; | ||
| interface Logger { | ||
| debug?(message: string, ...args: unknown[]): void; | ||
| info?(message: string, ...args: unknown[]): void; | ||
| warn?(message: string, ...args: unknown[]): void; | ||
| error?(message: string, ...args: unknown[]): void; | ||
| } | ||
| interface FinalValuation { | ||
| /** Valor estimado final */ | ||
| estimado: number; | ||
| /** Valor minimo */ | ||
| minimo: number; | ||
| /** Valor maximo */ | ||
| maximo: number; | ||
| /** Metodo utilizado (blend_avm_itbi, avm_only, itbi_only) */ | ||
| metodo: string; | ||
| /** Peso do AVM no calculo (0-1) */ | ||
| pesoAvm: number; | ||
| /** Peso do ITBI no calculo (0-1) */ | ||
| pesoItbi: number; | ||
| /** Nivel de confianca */ | ||
| confianca: number; | ||
| /** Nota explicativa */ | ||
| nota?: string; | ||
| interface RetryConfig { | ||
| /** Maximum number of retry attempts (default: 3) */ | ||
| maxRetries: number; | ||
| /** Initial delay in ms between retries (default: 500) */ | ||
| initialDelay: number; | ||
| /** Maximum delay in ms between retries (default: 10000) */ | ||
| maxDelay: number; | ||
| /** Backoff factor (default: 2) */ | ||
| backoffFactor: number; | ||
| /** Status codes that trigger retry (default: [429, 500, 502, 503, 504]) */ | ||
| retryableStatuses: number[]; | ||
| } | ||
| interface PropertyEvaluation { | ||
| /** Se a avaliacao foi bem sucedida */ | ||
| success: boolean; | ||
| /** Dados cadastrais do imovel */ | ||
| imovel: Record<string, unknown>; | ||
| /** Avaliacao pelo modelo ML (AVM) */ | ||
| avaliacaoAvm?: AVMEstimate; | ||
| /** Avaliacao por transacoes ITBI reais */ | ||
| avaliacaoItbi?: ITBIMarketEstimate; | ||
| /** Valor final combinado */ | ||
| valorFinal: FinalValuation; | ||
| /** Imoveis comparaveis */ | ||
| comparaveis?: Record<string, unknown>; | ||
| /** Metadados da avaliacao */ | ||
| metadata: { | ||
| processadoEm: string; | ||
| fontes: string[]; | ||
| cidade: string; | ||
| }; | ||
| interface IPTUClientOptions { | ||
| /** Base URL for the API (default: https://iptuapi.com.br/api/v1) */ | ||
| baseUrl?: string; | ||
| /** Request timeout in milliseconds (default: 30000) */ | ||
| timeout?: number; | ||
| /** Retry configuration */ | ||
| retry?: Partial<RetryConfig>; | ||
| /** Logger instance for debugging */ | ||
| logger?: Logger; | ||
| /** Enable request logging (default: false) */ | ||
| logRequests?: boolean; | ||
| /** Enable response logging (default: false) */ | ||
| logResponses?: boolean; | ||
| /** Custom User-Agent header */ | ||
| userAgent?: string; | ||
| } | ||
| type Cidade = 'sp' | 'bh' | 'recife' | 'poa' | 'fortaleza' | 'curitiba' | 'rj' | 'brasilia'; | ||
| /** | ||
| * Cliente principal para a IPTU API. | ||
| */ | ||
| /** | ||
| * Cliente para interagir com a IPTU API. | ||
| */ | ||
| declare class IPTUClient { | ||
| private readonly apiKey; | ||
| private readonly config; | ||
| private _rateLimitInfo; | ||
| private _lastRequestId; | ||
| /** | ||
| * Cria uma nova instancia do cliente. | ||
| * | ||
| * @param apiKey - Chave de API para autenticacao | ||
| * @param options - Opcoes de configuracao | ||
| */ | ||
| constructor(apiKey: string, options?: ClientOptions); | ||
| /** | ||
| * Retorna informacoes do rate limit da ultima requisicao. | ||
| */ | ||
| get rateLimitInfo(): RateLimitInfo | null; | ||
| /** | ||
| * Retorna o ID da ultima requisicao. | ||
| */ | ||
| get lastRequestId(): string | null; | ||
| /** | ||
| * Executa uma requisicao HTTP com retry. | ||
| */ | ||
| private makeRequest; | ||
| /** | ||
| * Atualiza informacoes de rate limit a partir dos headers. | ||
| */ | ||
| private updateRateLimitInfo; | ||
| /** | ||
| * Converte resposta HTTP em excecao apropriada. | ||
| */ | ||
| private handleError; | ||
| /** | ||
| * Aguarda um tempo em milissegundos. | ||
| */ | ||
| private readonly baseUrl; | ||
| private readonly timeout; | ||
| private readonly retryConfig; | ||
| private readonly logger?; | ||
| private readonly logRequests; | ||
| private readonly logResponses; | ||
| private readonly userAgent; | ||
| private _rateLimit?; | ||
| private _lastRequestId?; | ||
| constructor(apiKey: string, options?: IPTUClientOptions); | ||
| /** Rate limit info from last request */ | ||
| get rateLimit(): RateLimitInfo | undefined; | ||
| /** Request ID from last request (useful for support) */ | ||
| get lastRequestId(): string | undefined; | ||
| private log; | ||
| private sleep; | ||
| private calculateDelay; | ||
| private extractRateLimit; | ||
| private handleErrorResponse; | ||
| private request; | ||
| /** | ||
| * Consulta imoveis por endereco. | ||
| * Busca dados de IPTU por endereço. | ||
| * | ||
| * @param logradouro - Nome da rua/avenida | ||
| * @param numero - Numero do imovel | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Lista de imoveis encontrados | ||
| * @param params - Parâmetros da consulta | ||
| * @returns Dados do imóvel encontrado | ||
| * @throws {NotFoundError} Se o imóvel não for encontrado | ||
| * @throws {ValidationError} Se os parâmetros forem inválidos | ||
| * @throws {AuthenticationError} Se a API Key for inválida | ||
| * @throws {RateLimitError} Se exceder o limite de requisições | ||
| */ | ||
| consultaEndereco(logradouro: string, numero: string, cidade?: Cidade): Promise<Imovel[]>; | ||
| consultaEndereco(params: ConsultaEnderecoParams): Promise<ConsultaEnderecoResult>; | ||
| consultaEndereco(logradouro: string, numero?: string, cidade?: Cidade): Promise<ConsultaEnderecoResult>; | ||
| /** | ||
| * Consulta imovel por numero SQL/Indice Cadastral. | ||
| * Requer plano Starter ou superior. | ||
| * Busca dados de IPTU por número SQL (contribuinte). | ||
| * | ||
| * @param sql - Numero SQL (SP), Indice Cadastral (BH) ou Sequencial (Recife) | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Lista de imoveis encontrados | ||
| * @param sql - Número SQL do imóvel | ||
| * @param cidade - Cidade da consulta | ||
| * @param options - Opções adicionais | ||
| * @returns Dados completos do imóvel | ||
| */ | ||
| consultaSQL(sql: string, cidade?: Cidade): Promise<Imovel[]>; | ||
| consultaSQL(sql: string, cidade?: Cidade, options?: { | ||
| incluirHistorico?: boolean; | ||
| incluirComparaveis?: boolean; | ||
| }): Promise<ConsultaSQLResult>; | ||
| /** | ||
| * Consulta imoveis por CEP. | ||
| * Busca imóveis por CEP. | ||
| * | ||
| * @param cep - CEP do endereco | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Lista de imoveis encontrados | ||
| * @param cep - CEP do imóvel | ||
| * @param cidade - Cidade da consulta | ||
| * @returns Lista de imóveis no CEP | ||
| */ | ||
| consultaCEP(cep: string, cidade?: Cidade): Promise<Imovel[]>; | ||
| consultaCEP(cep: string, cidade?: Cidade): Promise<ConsultaEnderecoResult[]>; | ||
| /** | ||
@@ -341,179 +280,163 @@ * Consulta zoneamento por coordenadas. | ||
| * @param longitude - Longitude do ponto | ||
| * @returns Informacoes de zoneamento | ||
| * @returns Dados de zoneamento | ||
| */ | ||
| consultaZoneamento(latitude: number, longitude: number): Promise<Zoneamento>; | ||
| consultaZoneamento(latitude: number, longitude: number): Promise<ZoneamentoResult>; | ||
| /** | ||
| * Calcula estimativa de valor de mercado. | ||
| * Requer plano Pro ou superior. | ||
| * Estima o valor de mercado do imóvel usando ML. | ||
| * Disponível apenas para planos Pro e Enterprise. | ||
| * | ||
| * @param params - Parametros da avaliacao | ||
| * @returns Avaliacao de mercado | ||
| * @param params - Parâmetros do imóvel | ||
| * @returns Estimativa de valor | ||
| * @throws {ForbiddenError} Se o plano não permitir | ||
| */ | ||
| valuationEstimate(params: ValuationParams): Promise<Valuation>; | ||
| valuationEstimate(params: ValuationParams): Promise<ValuationResult>; | ||
| /** | ||
| * Busca imoveis comparaveis. | ||
| * Requer plano Pro ou superior. | ||
| * Valuation em lote (até 100 imóveis). | ||
| * Disponível apenas para plano Enterprise. | ||
| * | ||
| * @param params - Parametros da busca | ||
| * @returns Lista de imoveis comparaveis | ||
| * @param imoveis - Lista de imóveis para avaliar | ||
| * @returns Resultados de valuation para cada imóvel | ||
| */ | ||
| valuationComparables(params: ComparablesParams): Promise<Comparavel[]>; | ||
| valuationBatch(imoveis: ValuationParams[]): Promise<BatchValuationResult>; | ||
| /** | ||
| * Avalia imovel por endereco OU SQL. | ||
| * Combina dados do modelo AVM (ML) com transacoes ITBI reais. | ||
| * Requer plano Pro ou superior. | ||
| * Busca imóveis comparáveis para análise. | ||
| * | ||
| * @param params - Parametros da avaliacao (sql OU logradouro+numero) | ||
| * @returns Avaliacao completa do imovel | ||
| * @param bairro - Nome do bairro | ||
| * @param areaMin - Área mínima em m² | ||
| * @param areaMax - Área máxima em m² | ||
| * @param options - Opções adicionais | ||
| * @returns Lista de imóveis comparáveis | ||
| */ | ||
| valuationEvaluate(params: EvaluateParams): Promise<PropertyEvaluation>; | ||
| valuationComparables(bairro: string, areaMin: number, areaMax: number, options?: { | ||
| tipoUso?: string; | ||
| cidade?: Cidade; | ||
| limit?: number; | ||
| }): Promise<ComparavelItem[]>; | ||
| /** | ||
| * Consulta status de transacao ITBI. | ||
| * Histórico de valores IPTU de um imóvel. | ||
| * | ||
| * @param protocolo - Numero do protocolo ITBI | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Status da transacao | ||
| * @param sql - Número SQL do imóvel | ||
| * @param cidade - Cidade da consulta | ||
| * @returns Lista com histórico anual | ||
| */ | ||
| itbiStatus(protocolo: string, cidade?: Cidade): Promise<ITBIStatus>; | ||
| dadosIPTUHistorico(sql: string, cidade?: Cidade): Promise<HistoricoItem[]>; | ||
| /** | ||
| * Calcula valor do ITBI. | ||
| * Consulta dados de empresa por CNPJ. | ||
| * | ||
| * @param params - Parametros do calculo | ||
| * @returns Calculo do ITBI | ||
| * @param cnpj - CNPJ da empresa | ||
| * @returns Dados cadastrais | ||
| */ | ||
| itbiCalcular(params: ITBICalculoParams): Promise<ITBICalculo>; | ||
| dadosCNPJ(cnpj: string): Promise<Record<string, unknown>>; | ||
| /** | ||
| * Consulta historico de transacoes ITBI de um imovel. | ||
| * Requer plano Starter ou superior. | ||
| * Correção monetária pelo IPCA. | ||
| * | ||
| * @param sql - Numero SQL do imovel | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Lista de transacoes historicas | ||
| * @param valor - Valor a corrigir | ||
| * @param dataOrigem - Data do valor original (YYYY-MM) | ||
| * @param dataDestino - Data destino (default: atual) | ||
| * @returns Valor corrigido e fator de correção | ||
| */ | ||
| itbiHistorico(sql: string, cidade?: Cidade): Promise<ITBIHistorico[]>; | ||
| dadosIPCACorrigir(valor: number, dataOrigem: string, dataDestino?: string): Promise<{ | ||
| valor_corrigido: number; | ||
| fator: number; | ||
| }>; | ||
| /** | ||
| * Consulta aliquotas ITBI vigentes. | ||
| * Lista todas as cidades com calendario de IPTU disponivel. | ||
| * | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Aliquotas vigentes | ||
| * @returns Lista de cidades com codigo, nome, desconto e parcelas | ||
| */ | ||
| itbiAliquotas(cidade?: Cidade): Promise<ITBIAliquota>; | ||
| iptuToolsCidades(): Promise<{ | ||
| cidades: Array<{ | ||
| codigo: string; | ||
| nome: string; | ||
| ano: number; | ||
| desconto_vista: string; | ||
| parcelas_max: number; | ||
| site_oficial: string; | ||
| }>; | ||
| total: number; | ||
| }>; | ||
| /** | ||
| * Consulta isencoes ITBI disponiveis. | ||
| * Retorna o calendario completo de IPTU para a cidade especificada. | ||
| * | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Lista de isencoes disponiveis | ||
| * @param cidade - Codigo da cidade (sp, bh, rj, recife, curitiba, poa, fortaleza) | ||
| * @returns Calendario com vencimentos, descontos, alertas e novidades | ||
| */ | ||
| itbiIsencoes(cidade?: Cidade): Promise<ITBIIsencao[]>; | ||
| iptuToolsCalendario(cidade?: Cidade): Promise<{ | ||
| cidade: string; | ||
| ano: number; | ||
| desconto_vista_percentual: number; | ||
| desconto_vista_texto: string; | ||
| parcelas_max: number; | ||
| valor_minimo_parcela: number; | ||
| isencao_valor_venal?: number; | ||
| isencao_texto?: string; | ||
| site_oficial: string; | ||
| novidades?: string[]; | ||
| alertas?: string[]; | ||
| formas_pagamento?: string[]; | ||
| vencimentos_cota_unica: string[]; | ||
| vencimentos_parcelado: string[]; | ||
| proximo_vencimento?: string; | ||
| dias_para_proximo_vencimento?: number; | ||
| }>; | ||
| /** | ||
| * Gera guia de pagamento ITBI. | ||
| * Requer plano Starter ou superior. | ||
| * Simula as opcoes de pagamento do IPTU (a vista vs parcelado). | ||
| * | ||
| * @param params - Parametros da guia | ||
| * @returns Guia de pagamento gerada | ||
| * @param valorIptu - Valor total do IPTU | ||
| * @param cidade - Codigo da cidade | ||
| * @param valorVenal - Valor venal do imovel (para verificar isencao) | ||
| * @returns Comparativo entre pagamento a vista e parcelado com recomendacao | ||
| */ | ||
| itbiGuia(params: ITBIGuiaParams): Promise<ITBIGuia>; | ||
| iptuToolsSimulador(valorIptu: number, cidade?: Cidade, valorVenal?: number): Promise<{ | ||
| valor_original: number; | ||
| valor_vista: number; | ||
| desconto_vista: number; | ||
| desconto_percentual: number; | ||
| parcelas: number; | ||
| valor_parcela: number; | ||
| valor_total_parcelado: number; | ||
| economia_vista: number; | ||
| economia_percentual: number; | ||
| recomendacao: string; | ||
| elegivel_isencao: boolean; | ||
| isencao_mensagem?: string; | ||
| cidade: string; | ||
| ano: number; | ||
| proximo_vencimento?: string; | ||
| }>; | ||
| /** | ||
| * Valida autenticidade de uma guia ITBI. | ||
| * Verifica se um imovel e elegivel para isencao de IPTU. | ||
| * | ||
| * @param protocolo - Numero do protocolo da guia | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Resultado da validacao | ||
| * @param valorVenal - Valor venal do imovel | ||
| * @param cidade - Codigo da cidade | ||
| * @returns Elegibilidade para isencao total ou parcial | ||
| */ | ||
| itbiValidarGuia(protocolo: string, cidade?: Cidade): Promise<ITBIValidacao>; | ||
| iptuToolsIsencao(valorVenal: number, cidade?: Cidade): Promise<{ | ||
| cidade: string; | ||
| valor_venal: number; | ||
| limite_isencao: number; | ||
| elegivel_isencao_total: boolean; | ||
| elegivel_desconto_parcial: boolean; | ||
| desconto_estimado_percentual?: number; | ||
| mensagem: string; | ||
| requisitos_adicionais: string[]; | ||
| }>; | ||
| /** | ||
| * Simula calculo de ITBI. | ||
| * Retorna informacoes sobre o proximo vencimento do IPTU. | ||
| * | ||
| * @param params - Parametros da simulacao | ||
| * @returns Resultado da simulacao | ||
| * @param cidade - Codigo da cidade | ||
| * @param parcela - Numero da parcela (1-12) | ||
| * @returns Data de vencimento, dias restantes e status | ||
| */ | ||
| itbiSimular(params: ITBISimularParams): Promise<ITBISimulacao>; | ||
| iptuToolsProximoVencimento(cidade?: Cidade, parcela?: number): Promise<{ | ||
| cidade: string; | ||
| data_vencimento: string; | ||
| dias_restantes: number; | ||
| status: "em_dia" | "proximo" | "vence_hoje" | "vencido"; | ||
| mensagem: string; | ||
| multa_estimada?: number; | ||
| juros_estimados?: number; | ||
| }>; | ||
| } | ||
| /** | ||
| * Excecoes customizadas para a IPTU API. | ||
| */ | ||
| interface ErrorDetails { | ||
| error: string; | ||
| message: string; | ||
| statusCode?: number; | ||
| requestId?: string; | ||
| retryable: boolean; | ||
| [key: string]: unknown; | ||
| } | ||
| /** | ||
| * Excecao base para todos os erros da IPTU API. | ||
| */ | ||
| declare class IPTUAPIError extends Error { | ||
| readonly statusCode?: number; | ||
| readonly requestId?: string; | ||
| readonly responseData: Record<string, unknown>; | ||
| constructor(message: string, statusCode?: number, requestId?: string, responseData?: Record<string, unknown>); | ||
| isRetryable(): boolean; | ||
| toJSON(): ErrorDetails; | ||
| } | ||
| /** | ||
| * Erro de autenticacao (401). API Key invalida ou ausente. | ||
| */ | ||
| declare class AuthenticationError extends IPTUAPIError { | ||
| constructor(message?: string, requestId?: string); | ||
| } | ||
| /** | ||
| * Erro de autorizacao (403). Plano nao permite acesso ao recurso. | ||
| */ | ||
| declare class ForbiddenError extends IPTUAPIError { | ||
| readonly requiredPlan?: string; | ||
| constructor(message?: string, requiredPlan?: string, requestId?: string); | ||
| toJSON(): ErrorDetails; | ||
| } | ||
| /** | ||
| * Erro de recurso nao encontrado (404). | ||
| */ | ||
| declare class NotFoundError extends IPTUAPIError { | ||
| readonly resource?: string; | ||
| constructor(message?: string, resource?: string, requestId?: string); | ||
| toJSON(): ErrorDetails; | ||
| } | ||
| /** | ||
| * Erro de rate limit excedido (429). | ||
| */ | ||
| declare class RateLimitError extends IPTUAPIError { | ||
| readonly retryAfter: number; | ||
| constructor(message?: string, retryAfter?: number, requestId?: string); | ||
| isRetryable(): boolean; | ||
| toJSON(): ErrorDetails; | ||
| } | ||
| /** | ||
| * Erro de validacao de parametros (400, 422). | ||
| */ | ||
| declare class ValidationError extends IPTUAPIError { | ||
| readonly errors: Record<string, string[]>; | ||
| constructor(message?: string, errors?: Record<string, string[]>, statusCode?: number, requestId?: string); | ||
| toJSON(): ErrorDetails; | ||
| } | ||
| /** | ||
| * Erro interno do servidor (5xx). Retryable. | ||
| */ | ||
| declare class ServerError extends IPTUAPIError { | ||
| constructor(message?: string, statusCode?: number, requestId?: string); | ||
| isRetryable(): boolean; | ||
| } | ||
| /** | ||
| * Erro de timeout na requisicao. | ||
| */ | ||
| declare class TimeoutError extends IPTUAPIError { | ||
| readonly timeoutSeconds?: number; | ||
| constructor(message?: string, timeoutSeconds?: number, requestId?: string); | ||
| isRetryable(): boolean; | ||
| toJSON(): ErrorDetails; | ||
| } | ||
| /** | ||
| * Erro de conexao de rede. | ||
| */ | ||
| declare class NetworkError extends IPTUAPIError { | ||
| readonly originalError?: Error; | ||
| constructor(message?: string, originalError?: Error); | ||
| isRetryable(): boolean; | ||
| } | ||
| export { type AVMEstimate, AuthenticationError, type Cidade, type ClientConfig, type ClientOptions, type ComparablesParams, type Comparavel, type EvaluateParams, type FinalValuation, ForbiddenError, IPTUAPIError, IPTUClient, type ITBIAliquota, type ITBICalculo, type ITBICalculoParams, type ITBIGuia, type ITBIGuiaParams, type ITBIHistorico, type ITBIIsencao, type ITBIMarketEstimate, type ITBISimulacao, type ITBISimularParams, type ITBIStatus, type ITBIValidacao, type Imovel, NetworkError, NotFoundError, type Pessoa, type PropertyEvaluation, RateLimitError, type RateLimitInfo, type RetryConfig, ServerError, TimeoutError, ValidationError, type Valuation, type ValuationParams, type Zoneamento }; | ||
| export { AuthenticationError, type BatchValuationResult, type Cidade, CidadeEnum, type ComparavelItem, type ConsultaEnderecoParams, type ConsultaEnderecoResult, type ConsultaSQLResult, ForbiddenError, type HistoricoItem, IPTUAPIError, IPTUClient, type IPTUClientOptions, type Logger, NetworkError, NotFoundError, RateLimitError, type RateLimitInfo, type RetryConfig, ServerError, TimeoutError, ValidationError, type ValuationParams, type ValuationResult, type ZoneamentoResult, IPTUClient as default }; |
+357
-434
| /** | ||
| * Tipos e interfaces para a IPTU API. | ||
| * IPTU API - JavaScript/TypeScript SDK | ||
| * | ||
| * SDK oficial para integração com a IPTU API. | ||
| * Suporta retry automático, logging e rate limit tracking. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * import { IPTUClient } from 'iptuapi'; | ||
| * | ||
| * const client = new IPTUClient('sua_api_key'); | ||
| * const resultado = await client.consultaEndereco('Avenida Paulista', '1000'); | ||
| * console.log(resultado); | ||
| * ``` | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Com configuração customizada | ||
| * const client = new IPTUClient('sua_api_key', { | ||
| * timeout: 60000, | ||
| * retries: 5, | ||
| * logger: console, | ||
| * }); | ||
| * ``` | ||
| */ | ||
| interface RetryConfig { | ||
| maxRetries: number; | ||
| initialDelay: number; | ||
| maxDelay: number; | ||
| backoffFactor: number; | ||
| retryableStatusCodes: number[]; | ||
| } | ||
| interface ClientConfig { | ||
| baseUrl: string; | ||
| timeout: number; | ||
| retryConfig: RetryConfig; | ||
| } | ||
| interface ClientOptions { | ||
| baseUrl?: string; | ||
| timeout?: number; | ||
| retryConfig?: Partial<RetryConfig>; | ||
| } | ||
| type Cidade = 'sp' | 'bh' | 'recife' | 'poa' | 'fortaleza' | 'curitiba' | 'rj' | 'brasilia'; | ||
| declare const CidadeEnum: { | ||
| readonly SAO_PAULO: Cidade; | ||
| readonly BELO_HORIZONTE: Cidade; | ||
| readonly RECIFE: Cidade; | ||
| readonly PORTO_ALEGRE: Cidade; | ||
| readonly FORTALEZA: Cidade; | ||
| readonly CURITIBA: Cidade; | ||
| readonly RIO_DE_JANEIRO: Cidade; | ||
| readonly BRASILIA: Cidade; | ||
| }; | ||
| interface RateLimitInfo { | ||
| limit: number; | ||
| remaining: number; | ||
| resetAt: Date; | ||
| reset: number; | ||
| resetDate: Date; | ||
| } | ||
| interface Imovel { | ||
| interface ConsultaEnderecoParams { | ||
| logradouro: string; | ||
| numero?: string; | ||
| complemento?: string; | ||
| cidade?: Cidade; | ||
| incluirHistorico?: boolean; | ||
| incluirComparaveis?: boolean; | ||
| incluirZoneamento?: boolean; | ||
| } | ||
| interface ConsultaEnderecoResult { | ||
| sql: string; | ||
| logradouro: string; | ||
| numero: string; | ||
| bairro: string; | ||
| numero?: string; | ||
| complemento?: string; | ||
| bairro?: string; | ||
| cep?: string; | ||
| areaTerreno?: number; | ||
| areaConstruida?: number; | ||
| valorVenal?: number; | ||
| valorVenalTerreno?: number; | ||
| valorVenalConstrucao?: number; | ||
| anoConstrucao?: number; | ||
| uso?: string; | ||
| padrao?: string; | ||
| testada?: number; | ||
| fracaoIdeal?: number; | ||
| quantidadePavimentos?: number; | ||
| } | ||
| interface Zoneamento { | ||
| zona: string; | ||
| usoPermitido: string; | ||
| coeficienteAproveitamento?: number; | ||
| taxaOcupacao?: number; | ||
| gabarito?: number; | ||
| recuoFrontal?: number; | ||
| legislacao?: string; | ||
| } | ||
| interface Valuation { | ||
| valorEstimado: number; | ||
| valorMinimo: number; | ||
| valorMaximo: number; | ||
| confianca: number; | ||
| valorM2: number; | ||
| metodologia: string; | ||
| dataReferencia: string; | ||
| } | ||
| interface ValuationParams { | ||
| areaTerreno: number; | ||
| areaConstruida: number; | ||
| bairro: string; | ||
| cidade?: string; | ||
| area_terreno?: number; | ||
| area_construida?: number; | ||
| valor_venal_terreno?: number; | ||
| valor_venal_construcao?: number; | ||
| valor_venal_total?: number; | ||
| iptu_valor?: number; | ||
| ano_construcao?: number; | ||
| tipo_uso?: string; | ||
| zona?: string; | ||
| tipoUso?: string; | ||
| tipoPadrao?: string; | ||
| anoConstrucao?: number; | ||
| historico?: HistoricoItem[]; | ||
| comparaveis?: ComparavelItem[]; | ||
| zoneamento?: ZoneamentoResult; | ||
| } | ||
| interface Comparavel { | ||
| interface ConsultaSQLResult { | ||
| sql: string; | ||
| logradouro: string; | ||
| bairro: string; | ||
| areaConstruida: number; | ||
| valorVenal: number; | ||
| valorM2: number; | ||
| distanciaKm?: number; | ||
| ano?: number; | ||
| valor_venal?: number; | ||
| valor_venal_terreno?: number; | ||
| valor_venal_construcao?: number; | ||
| valor_venal_total?: number; | ||
| iptu_valor?: number; | ||
| logradouro?: string; | ||
| numero?: string; | ||
| bairro?: string; | ||
| area_terreno?: number; | ||
| area_construida?: number; | ||
| } | ||
| interface ComparablesParams { | ||
| bairro: string; | ||
| areaMin: number; | ||
| areaMax: number; | ||
| cidade?: string; | ||
| limit?: number; | ||
| interface HistoricoItem { | ||
| ano: number; | ||
| valor_venal_terreno?: number; | ||
| valor_venal_construcao?: number; | ||
| valor_venal_total?: number; | ||
| iptu_valor?: number; | ||
| } | ||
| interface ITBIStatus { | ||
| protocolo: string; | ||
| status: string; | ||
| dataSolicitacao: string; | ||
| valorTransacao: number; | ||
| valorVenalReferencia: number; | ||
| baseCalculo: number; | ||
| aliquota: number; | ||
| valorITBI: number; | ||
| dataAprovacao?: string; | ||
| interface ComparavelItem { | ||
| sql?: string; | ||
| logradouro?: string; | ||
| numero?: string; | ||
| bairro?: string; | ||
| area_terreno?: number; | ||
| area_construida?: number; | ||
| valor_venal_total?: number; | ||
| distancia_metros?: number; | ||
| } | ||
| interface ITBICalculo { | ||
| sql: string; | ||
| valorTransacao: number; | ||
| valorVenalReferencia: number; | ||
| baseCalculo: number; | ||
| aliquota: number; | ||
| valorITBI: number; | ||
| isencaoAplicavel: boolean; | ||
| fundamentacaoLegal: string; | ||
| interface ZoneamentoResult { | ||
| zona?: string; | ||
| zona_descricao?: string; | ||
| coeficiente_aproveitamento_basico?: number; | ||
| coeficiente_aproveitamento_maximo?: number; | ||
| taxa_ocupacao_maxima?: number; | ||
| gabarito_maximo?: number; | ||
| } | ||
| interface ITBICalculoParams { | ||
| sql: string; | ||
| valorTransacao: number; | ||
| cidade?: string; | ||
| interface ValuationParams { | ||
| area_terreno: number; | ||
| area_construida: number; | ||
| bairro: string; | ||
| zona: string; | ||
| tipo_uso: string; | ||
| tipo_padrao: string; | ||
| ano_construcao?: number; | ||
| cidade?: Cidade; | ||
| } | ||
| interface ITBIHistorico { | ||
| protocolo: string; | ||
| dataTransacao: string; | ||
| tipoTransacao: string; | ||
| valorTransacao: number; | ||
| valorITBI: number; | ||
| interface ValuationResult { | ||
| valor_estimado: number; | ||
| valor_minimo?: number; | ||
| valor_maximo?: number; | ||
| confianca?: number; | ||
| metodo?: string; | ||
| comparaveis_utilizados?: number; | ||
| data_avaliacao?: string; | ||
| } | ||
| interface ITBIAliquota { | ||
| cidade: string; | ||
| aliquotaPadrao: number; | ||
| aliquotaFinanciamentoSFH: number; | ||
| valorMinimoIsencao: number; | ||
| baseLegal: string; | ||
| vigencia: string; | ||
| interface BatchValuationResult { | ||
| resultados: ValuationResult[]; | ||
| total_processados: number; | ||
| total_erros: number; | ||
| erros?: Array<{ | ||
| index: number; | ||
| error: string; | ||
| }>; | ||
| } | ||
| interface ITBIIsencao { | ||
| tipo: string; | ||
| descricao: string; | ||
| requisitos: string[]; | ||
| baseLegal: string; | ||
| declare class IPTUAPIError extends Error { | ||
| readonly statusCode?: number; | ||
| readonly requestId?: string; | ||
| readonly responseBody?: Record<string, unknown>; | ||
| constructor(message: string, statusCode?: number, requestId?: string, responseBody?: Record<string, unknown>); | ||
| get isRetryable(): boolean; | ||
| } | ||
| interface Pessoa { | ||
| nome: string; | ||
| documento: string; | ||
| email?: string; | ||
| declare class AuthenticationError extends IPTUAPIError { | ||
| constructor(message?: string, requestId?: string, responseBody?: Record<string, unknown>); | ||
| } | ||
| interface ITBIGuiaParams { | ||
| sql: string; | ||
| valorTransacao: number; | ||
| comprador: Pessoa; | ||
| vendedor: Pessoa; | ||
| cidade?: string; | ||
| declare class ForbiddenError extends IPTUAPIError { | ||
| readonly requiredPlan?: string; | ||
| constructor(message?: string, requiredPlan?: string, requestId?: string, responseBody?: Record<string, unknown>); | ||
| } | ||
| interface ITBIGuia { | ||
| protocolo: string; | ||
| codigoBarras: string; | ||
| linhaDigitavel: string; | ||
| dataEmissao: string; | ||
| dataVencimento: string; | ||
| valorITBI: number; | ||
| declare class NotFoundError extends IPTUAPIError { | ||
| constructor(message?: string, requestId?: string, responseBody?: Record<string, unknown>); | ||
| } | ||
| interface ITBIValidacao { | ||
| protocolo: string; | ||
| valido: boolean; | ||
| pago: boolean; | ||
| dataPagamento?: string; | ||
| valorPago?: number; | ||
| declare class RateLimitError extends IPTUAPIError { | ||
| readonly retryAfter?: number; | ||
| readonly limit?: number; | ||
| readonly remaining?: number; | ||
| constructor(message?: string, retryAfter?: number, limit?: number, remaining?: number, requestId?: string, responseBody?: Record<string, unknown>); | ||
| get isRetryable(): boolean; | ||
| } | ||
| interface ITBISimularParams { | ||
| valorTransacao: number; | ||
| cidade?: string; | ||
| tipoFinanciamento?: 'sfh' | 'nao_sfh'; | ||
| valorFinanciado?: number; | ||
| declare class ValidationError extends IPTUAPIError { | ||
| readonly errors?: Array<{ | ||
| field: string; | ||
| message: string; | ||
| }>; | ||
| constructor(message?: string, errors?: Array<{ | ||
| field: string; | ||
| message: string; | ||
| }>, requestId?: string, responseBody?: Record<string, unknown>); | ||
| } | ||
| interface ITBISimulacao { | ||
| valorTransacao: number; | ||
| valorFinanciado: number; | ||
| valorNaoFinanciado: number; | ||
| aliquotaSFH: number; | ||
| aliquotaPadrao: number; | ||
| valorITBIFinanciado: number; | ||
| valorITBINaoFinanciado: number; | ||
| valorITBITotal: number; | ||
| economiaSFH: number; | ||
| declare class ServerError extends IPTUAPIError { | ||
| constructor(message?: string, statusCode?: number, requestId?: string, responseBody?: Record<string, unknown>); | ||
| get isRetryable(): boolean; | ||
| } | ||
| interface EvaluateParams { | ||
| /** Numero SQL do imovel (alternativa ao endereco) */ | ||
| sql?: string; | ||
| /** Nome da rua/avenida (alternativa ao SQL) */ | ||
| logradouro?: string; | ||
| /** Numero do imovel */ | ||
| numero?: number; | ||
| /** Apartamento, sala, etc. */ | ||
| complemento?: string; | ||
| /** Bairro */ | ||
| bairro?: string; | ||
| /** Codigo da cidade (sp, bh) */ | ||
| cidade?: string; | ||
| /** Incluir estimativa baseada em ITBI */ | ||
| incluirItbi?: boolean; | ||
| /** Incluir lista de imoveis comparaveis */ | ||
| incluirComparaveis?: boolean; | ||
| declare class TimeoutError extends IPTUAPIError { | ||
| readonly timeoutMs?: number; | ||
| constructor(message?: string, timeoutMs?: number); | ||
| get isRetryable(): boolean; | ||
| } | ||
| interface AVMEstimate { | ||
| /** Valor estimado em R$ */ | ||
| valorEstimado: number; | ||
| /** Valor minimo do intervalo */ | ||
| valorMinimo: number; | ||
| /** Valor maximo do intervalo */ | ||
| valorMaximo: number; | ||
| /** Valor por m2 */ | ||
| valorM2: number; | ||
| /** Nivel de confianca (0-1) */ | ||
| confianca: number; | ||
| /** Versao do modelo */ | ||
| modeloVersao: string; | ||
| declare class NetworkError extends IPTUAPIError { | ||
| readonly originalError?: Error; | ||
| constructor(message?: string, originalError?: Error); | ||
| get isRetryable(): boolean; | ||
| } | ||
| interface ITBIMarketEstimate { | ||
| /** Valor estimado em R$ */ | ||
| valorEstimado: number; | ||
| /** Valor minimo da faixa */ | ||
| faixaMinima: number; | ||
| /** Valor maximo da faixa */ | ||
| faixaMaxima: number; | ||
| /** Valor por m2 (mediana) */ | ||
| valorM2Mediana: number; | ||
| /** Total de transacoes analisadas */ | ||
| totalTransacoes: number; | ||
| /** Periodo considerado */ | ||
| periodo: string; | ||
| /** Fonte dos dados */ | ||
| fonte: string; | ||
| interface Logger { | ||
| debug?(message: string, ...args: unknown[]): void; | ||
| info?(message: string, ...args: unknown[]): void; | ||
| warn?(message: string, ...args: unknown[]): void; | ||
| error?(message: string, ...args: unknown[]): void; | ||
| } | ||
| interface FinalValuation { | ||
| /** Valor estimado final */ | ||
| estimado: number; | ||
| /** Valor minimo */ | ||
| minimo: number; | ||
| /** Valor maximo */ | ||
| maximo: number; | ||
| /** Metodo utilizado (blend_avm_itbi, avm_only, itbi_only) */ | ||
| metodo: string; | ||
| /** Peso do AVM no calculo (0-1) */ | ||
| pesoAvm: number; | ||
| /** Peso do ITBI no calculo (0-1) */ | ||
| pesoItbi: number; | ||
| /** Nivel de confianca */ | ||
| confianca: number; | ||
| /** Nota explicativa */ | ||
| nota?: string; | ||
| interface RetryConfig { | ||
| /** Maximum number of retry attempts (default: 3) */ | ||
| maxRetries: number; | ||
| /** Initial delay in ms between retries (default: 500) */ | ||
| initialDelay: number; | ||
| /** Maximum delay in ms between retries (default: 10000) */ | ||
| maxDelay: number; | ||
| /** Backoff factor (default: 2) */ | ||
| backoffFactor: number; | ||
| /** Status codes that trigger retry (default: [429, 500, 502, 503, 504]) */ | ||
| retryableStatuses: number[]; | ||
| } | ||
| interface PropertyEvaluation { | ||
| /** Se a avaliacao foi bem sucedida */ | ||
| success: boolean; | ||
| /** Dados cadastrais do imovel */ | ||
| imovel: Record<string, unknown>; | ||
| /** Avaliacao pelo modelo ML (AVM) */ | ||
| avaliacaoAvm?: AVMEstimate; | ||
| /** Avaliacao por transacoes ITBI reais */ | ||
| avaliacaoItbi?: ITBIMarketEstimate; | ||
| /** Valor final combinado */ | ||
| valorFinal: FinalValuation; | ||
| /** Imoveis comparaveis */ | ||
| comparaveis?: Record<string, unknown>; | ||
| /** Metadados da avaliacao */ | ||
| metadata: { | ||
| processadoEm: string; | ||
| fontes: string[]; | ||
| cidade: string; | ||
| }; | ||
| interface IPTUClientOptions { | ||
| /** Base URL for the API (default: https://iptuapi.com.br/api/v1) */ | ||
| baseUrl?: string; | ||
| /** Request timeout in milliseconds (default: 30000) */ | ||
| timeout?: number; | ||
| /** Retry configuration */ | ||
| retry?: Partial<RetryConfig>; | ||
| /** Logger instance for debugging */ | ||
| logger?: Logger; | ||
| /** Enable request logging (default: false) */ | ||
| logRequests?: boolean; | ||
| /** Enable response logging (default: false) */ | ||
| logResponses?: boolean; | ||
| /** Custom User-Agent header */ | ||
| userAgent?: string; | ||
| } | ||
| type Cidade = 'sp' | 'bh' | 'recife' | 'poa' | 'fortaleza' | 'curitiba' | 'rj' | 'brasilia'; | ||
| /** | ||
| * Cliente principal para a IPTU API. | ||
| */ | ||
| /** | ||
| * Cliente para interagir com a IPTU API. | ||
| */ | ||
| declare class IPTUClient { | ||
| private readonly apiKey; | ||
| private readonly config; | ||
| private _rateLimitInfo; | ||
| private _lastRequestId; | ||
| /** | ||
| * Cria uma nova instancia do cliente. | ||
| * | ||
| * @param apiKey - Chave de API para autenticacao | ||
| * @param options - Opcoes de configuracao | ||
| */ | ||
| constructor(apiKey: string, options?: ClientOptions); | ||
| /** | ||
| * Retorna informacoes do rate limit da ultima requisicao. | ||
| */ | ||
| get rateLimitInfo(): RateLimitInfo | null; | ||
| /** | ||
| * Retorna o ID da ultima requisicao. | ||
| */ | ||
| get lastRequestId(): string | null; | ||
| /** | ||
| * Executa uma requisicao HTTP com retry. | ||
| */ | ||
| private makeRequest; | ||
| /** | ||
| * Atualiza informacoes de rate limit a partir dos headers. | ||
| */ | ||
| private updateRateLimitInfo; | ||
| /** | ||
| * Converte resposta HTTP em excecao apropriada. | ||
| */ | ||
| private handleError; | ||
| /** | ||
| * Aguarda um tempo em milissegundos. | ||
| */ | ||
| private readonly baseUrl; | ||
| private readonly timeout; | ||
| private readonly retryConfig; | ||
| private readonly logger?; | ||
| private readonly logRequests; | ||
| private readonly logResponses; | ||
| private readonly userAgent; | ||
| private _rateLimit?; | ||
| private _lastRequestId?; | ||
| constructor(apiKey: string, options?: IPTUClientOptions); | ||
| /** Rate limit info from last request */ | ||
| get rateLimit(): RateLimitInfo | undefined; | ||
| /** Request ID from last request (useful for support) */ | ||
| get lastRequestId(): string | undefined; | ||
| private log; | ||
| private sleep; | ||
| private calculateDelay; | ||
| private extractRateLimit; | ||
| private handleErrorResponse; | ||
| private request; | ||
| /** | ||
| * Consulta imoveis por endereco. | ||
| * Busca dados de IPTU por endereço. | ||
| * | ||
| * @param logradouro - Nome da rua/avenida | ||
| * @param numero - Numero do imovel | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Lista de imoveis encontrados | ||
| * @param params - Parâmetros da consulta | ||
| * @returns Dados do imóvel encontrado | ||
| * @throws {NotFoundError} Se o imóvel não for encontrado | ||
| * @throws {ValidationError} Se os parâmetros forem inválidos | ||
| * @throws {AuthenticationError} Se a API Key for inválida | ||
| * @throws {RateLimitError} Se exceder o limite de requisições | ||
| */ | ||
| consultaEndereco(logradouro: string, numero: string, cidade?: Cidade): Promise<Imovel[]>; | ||
| consultaEndereco(params: ConsultaEnderecoParams): Promise<ConsultaEnderecoResult>; | ||
| consultaEndereco(logradouro: string, numero?: string, cidade?: Cidade): Promise<ConsultaEnderecoResult>; | ||
| /** | ||
| * Consulta imovel por numero SQL/Indice Cadastral. | ||
| * Requer plano Starter ou superior. | ||
| * Busca dados de IPTU por número SQL (contribuinte). | ||
| * | ||
| * @param sql - Numero SQL (SP), Indice Cadastral (BH) ou Sequencial (Recife) | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Lista de imoveis encontrados | ||
| * @param sql - Número SQL do imóvel | ||
| * @param cidade - Cidade da consulta | ||
| * @param options - Opções adicionais | ||
| * @returns Dados completos do imóvel | ||
| */ | ||
| consultaSQL(sql: string, cidade?: Cidade): Promise<Imovel[]>; | ||
| consultaSQL(sql: string, cidade?: Cidade, options?: { | ||
| incluirHistorico?: boolean; | ||
| incluirComparaveis?: boolean; | ||
| }): Promise<ConsultaSQLResult>; | ||
| /** | ||
| * Consulta imoveis por CEP. | ||
| * Busca imóveis por CEP. | ||
| * | ||
| * @param cep - CEP do endereco | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Lista de imoveis encontrados | ||
| * @param cep - CEP do imóvel | ||
| * @param cidade - Cidade da consulta | ||
| * @returns Lista de imóveis no CEP | ||
| */ | ||
| consultaCEP(cep: string, cidade?: Cidade): Promise<Imovel[]>; | ||
| consultaCEP(cep: string, cidade?: Cidade): Promise<ConsultaEnderecoResult[]>; | ||
| /** | ||
@@ -341,179 +280,163 @@ * Consulta zoneamento por coordenadas. | ||
| * @param longitude - Longitude do ponto | ||
| * @returns Informacoes de zoneamento | ||
| * @returns Dados de zoneamento | ||
| */ | ||
| consultaZoneamento(latitude: number, longitude: number): Promise<Zoneamento>; | ||
| consultaZoneamento(latitude: number, longitude: number): Promise<ZoneamentoResult>; | ||
| /** | ||
| * Calcula estimativa de valor de mercado. | ||
| * Requer plano Pro ou superior. | ||
| * Estima o valor de mercado do imóvel usando ML. | ||
| * Disponível apenas para planos Pro e Enterprise. | ||
| * | ||
| * @param params - Parametros da avaliacao | ||
| * @returns Avaliacao de mercado | ||
| * @param params - Parâmetros do imóvel | ||
| * @returns Estimativa de valor | ||
| * @throws {ForbiddenError} Se o plano não permitir | ||
| */ | ||
| valuationEstimate(params: ValuationParams): Promise<Valuation>; | ||
| valuationEstimate(params: ValuationParams): Promise<ValuationResult>; | ||
| /** | ||
| * Busca imoveis comparaveis. | ||
| * Requer plano Pro ou superior. | ||
| * Valuation em lote (até 100 imóveis). | ||
| * Disponível apenas para plano Enterprise. | ||
| * | ||
| * @param params - Parametros da busca | ||
| * @returns Lista de imoveis comparaveis | ||
| * @param imoveis - Lista de imóveis para avaliar | ||
| * @returns Resultados de valuation para cada imóvel | ||
| */ | ||
| valuationComparables(params: ComparablesParams): Promise<Comparavel[]>; | ||
| valuationBatch(imoveis: ValuationParams[]): Promise<BatchValuationResult>; | ||
| /** | ||
| * Avalia imovel por endereco OU SQL. | ||
| * Combina dados do modelo AVM (ML) com transacoes ITBI reais. | ||
| * Requer plano Pro ou superior. | ||
| * Busca imóveis comparáveis para análise. | ||
| * | ||
| * @param params - Parametros da avaliacao (sql OU logradouro+numero) | ||
| * @returns Avaliacao completa do imovel | ||
| * @param bairro - Nome do bairro | ||
| * @param areaMin - Área mínima em m² | ||
| * @param areaMax - Área máxima em m² | ||
| * @param options - Opções adicionais | ||
| * @returns Lista de imóveis comparáveis | ||
| */ | ||
| valuationEvaluate(params: EvaluateParams): Promise<PropertyEvaluation>; | ||
| valuationComparables(bairro: string, areaMin: number, areaMax: number, options?: { | ||
| tipoUso?: string; | ||
| cidade?: Cidade; | ||
| limit?: number; | ||
| }): Promise<ComparavelItem[]>; | ||
| /** | ||
| * Consulta status de transacao ITBI. | ||
| * Histórico de valores IPTU de um imóvel. | ||
| * | ||
| * @param protocolo - Numero do protocolo ITBI | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Status da transacao | ||
| * @param sql - Número SQL do imóvel | ||
| * @param cidade - Cidade da consulta | ||
| * @returns Lista com histórico anual | ||
| */ | ||
| itbiStatus(protocolo: string, cidade?: Cidade): Promise<ITBIStatus>; | ||
| dadosIPTUHistorico(sql: string, cidade?: Cidade): Promise<HistoricoItem[]>; | ||
| /** | ||
| * Calcula valor do ITBI. | ||
| * Consulta dados de empresa por CNPJ. | ||
| * | ||
| * @param params - Parametros do calculo | ||
| * @returns Calculo do ITBI | ||
| * @param cnpj - CNPJ da empresa | ||
| * @returns Dados cadastrais | ||
| */ | ||
| itbiCalcular(params: ITBICalculoParams): Promise<ITBICalculo>; | ||
| dadosCNPJ(cnpj: string): Promise<Record<string, unknown>>; | ||
| /** | ||
| * Consulta historico de transacoes ITBI de um imovel. | ||
| * Requer plano Starter ou superior. | ||
| * Correção monetária pelo IPCA. | ||
| * | ||
| * @param sql - Numero SQL do imovel | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Lista de transacoes historicas | ||
| * @param valor - Valor a corrigir | ||
| * @param dataOrigem - Data do valor original (YYYY-MM) | ||
| * @param dataDestino - Data destino (default: atual) | ||
| * @returns Valor corrigido e fator de correção | ||
| */ | ||
| itbiHistorico(sql: string, cidade?: Cidade): Promise<ITBIHistorico[]>; | ||
| dadosIPCACorrigir(valor: number, dataOrigem: string, dataDestino?: string): Promise<{ | ||
| valor_corrigido: number; | ||
| fator: number; | ||
| }>; | ||
| /** | ||
| * Consulta aliquotas ITBI vigentes. | ||
| * Lista todas as cidades com calendario de IPTU disponivel. | ||
| * | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Aliquotas vigentes | ||
| * @returns Lista de cidades com codigo, nome, desconto e parcelas | ||
| */ | ||
| itbiAliquotas(cidade?: Cidade): Promise<ITBIAliquota>; | ||
| iptuToolsCidades(): Promise<{ | ||
| cidades: Array<{ | ||
| codigo: string; | ||
| nome: string; | ||
| ano: number; | ||
| desconto_vista: string; | ||
| parcelas_max: number; | ||
| site_oficial: string; | ||
| }>; | ||
| total: number; | ||
| }>; | ||
| /** | ||
| * Consulta isencoes ITBI disponiveis. | ||
| * Retorna o calendario completo de IPTU para a cidade especificada. | ||
| * | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Lista de isencoes disponiveis | ||
| * @param cidade - Codigo da cidade (sp, bh, rj, recife, curitiba, poa, fortaleza) | ||
| * @returns Calendario com vencimentos, descontos, alertas e novidades | ||
| */ | ||
| itbiIsencoes(cidade?: Cidade): Promise<ITBIIsencao[]>; | ||
| iptuToolsCalendario(cidade?: Cidade): Promise<{ | ||
| cidade: string; | ||
| ano: number; | ||
| desconto_vista_percentual: number; | ||
| desconto_vista_texto: string; | ||
| parcelas_max: number; | ||
| valor_minimo_parcela: number; | ||
| isencao_valor_venal?: number; | ||
| isencao_texto?: string; | ||
| site_oficial: string; | ||
| novidades?: string[]; | ||
| alertas?: string[]; | ||
| formas_pagamento?: string[]; | ||
| vencimentos_cota_unica: string[]; | ||
| vencimentos_parcelado: string[]; | ||
| proximo_vencimento?: string; | ||
| dias_para_proximo_vencimento?: number; | ||
| }>; | ||
| /** | ||
| * Gera guia de pagamento ITBI. | ||
| * Requer plano Starter ou superior. | ||
| * Simula as opcoes de pagamento do IPTU (a vista vs parcelado). | ||
| * | ||
| * @param params - Parametros da guia | ||
| * @returns Guia de pagamento gerada | ||
| * @param valorIptu - Valor total do IPTU | ||
| * @param cidade - Codigo da cidade | ||
| * @param valorVenal - Valor venal do imovel (para verificar isencao) | ||
| * @returns Comparativo entre pagamento a vista e parcelado com recomendacao | ||
| */ | ||
| itbiGuia(params: ITBIGuiaParams): Promise<ITBIGuia>; | ||
| iptuToolsSimulador(valorIptu: number, cidade?: Cidade, valorVenal?: number): Promise<{ | ||
| valor_original: number; | ||
| valor_vista: number; | ||
| desconto_vista: number; | ||
| desconto_percentual: number; | ||
| parcelas: number; | ||
| valor_parcela: number; | ||
| valor_total_parcelado: number; | ||
| economia_vista: number; | ||
| economia_percentual: number; | ||
| recomendacao: string; | ||
| elegivel_isencao: boolean; | ||
| isencao_mensagem?: string; | ||
| cidade: string; | ||
| ano: number; | ||
| proximo_vencimento?: string; | ||
| }>; | ||
| /** | ||
| * Valida autenticidade de uma guia ITBI. | ||
| * Verifica se um imovel e elegivel para isencao de IPTU. | ||
| * | ||
| * @param protocolo - Numero do protocolo da guia | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Resultado da validacao | ||
| * @param valorVenal - Valor venal do imovel | ||
| * @param cidade - Codigo da cidade | ||
| * @returns Elegibilidade para isencao total ou parcial | ||
| */ | ||
| itbiValidarGuia(protocolo: string, cidade?: Cidade): Promise<ITBIValidacao>; | ||
| iptuToolsIsencao(valorVenal: number, cidade?: Cidade): Promise<{ | ||
| cidade: string; | ||
| valor_venal: number; | ||
| limite_isencao: number; | ||
| elegivel_isencao_total: boolean; | ||
| elegivel_desconto_parcial: boolean; | ||
| desconto_estimado_percentual?: number; | ||
| mensagem: string; | ||
| requisitos_adicionais: string[]; | ||
| }>; | ||
| /** | ||
| * Simula calculo de ITBI. | ||
| * Retorna informacoes sobre o proximo vencimento do IPTU. | ||
| * | ||
| * @param params - Parametros da simulacao | ||
| * @returns Resultado da simulacao | ||
| * @param cidade - Codigo da cidade | ||
| * @param parcela - Numero da parcela (1-12) | ||
| * @returns Data de vencimento, dias restantes e status | ||
| */ | ||
| itbiSimular(params: ITBISimularParams): Promise<ITBISimulacao>; | ||
| iptuToolsProximoVencimento(cidade?: Cidade, parcela?: number): Promise<{ | ||
| cidade: string; | ||
| data_vencimento: string; | ||
| dias_restantes: number; | ||
| status: "em_dia" | "proximo" | "vence_hoje" | "vencido"; | ||
| mensagem: string; | ||
| multa_estimada?: number; | ||
| juros_estimados?: number; | ||
| }>; | ||
| } | ||
| /** | ||
| * Excecoes customizadas para a IPTU API. | ||
| */ | ||
| interface ErrorDetails { | ||
| error: string; | ||
| message: string; | ||
| statusCode?: number; | ||
| requestId?: string; | ||
| retryable: boolean; | ||
| [key: string]: unknown; | ||
| } | ||
| /** | ||
| * Excecao base para todos os erros da IPTU API. | ||
| */ | ||
| declare class IPTUAPIError extends Error { | ||
| readonly statusCode?: number; | ||
| readonly requestId?: string; | ||
| readonly responseData: Record<string, unknown>; | ||
| constructor(message: string, statusCode?: number, requestId?: string, responseData?: Record<string, unknown>); | ||
| isRetryable(): boolean; | ||
| toJSON(): ErrorDetails; | ||
| } | ||
| /** | ||
| * Erro de autenticacao (401). API Key invalida ou ausente. | ||
| */ | ||
| declare class AuthenticationError extends IPTUAPIError { | ||
| constructor(message?: string, requestId?: string); | ||
| } | ||
| /** | ||
| * Erro de autorizacao (403). Plano nao permite acesso ao recurso. | ||
| */ | ||
| declare class ForbiddenError extends IPTUAPIError { | ||
| readonly requiredPlan?: string; | ||
| constructor(message?: string, requiredPlan?: string, requestId?: string); | ||
| toJSON(): ErrorDetails; | ||
| } | ||
| /** | ||
| * Erro de recurso nao encontrado (404). | ||
| */ | ||
| declare class NotFoundError extends IPTUAPIError { | ||
| readonly resource?: string; | ||
| constructor(message?: string, resource?: string, requestId?: string); | ||
| toJSON(): ErrorDetails; | ||
| } | ||
| /** | ||
| * Erro de rate limit excedido (429). | ||
| */ | ||
| declare class RateLimitError extends IPTUAPIError { | ||
| readonly retryAfter: number; | ||
| constructor(message?: string, retryAfter?: number, requestId?: string); | ||
| isRetryable(): boolean; | ||
| toJSON(): ErrorDetails; | ||
| } | ||
| /** | ||
| * Erro de validacao de parametros (400, 422). | ||
| */ | ||
| declare class ValidationError extends IPTUAPIError { | ||
| readonly errors: Record<string, string[]>; | ||
| constructor(message?: string, errors?: Record<string, string[]>, statusCode?: number, requestId?: string); | ||
| toJSON(): ErrorDetails; | ||
| } | ||
| /** | ||
| * Erro interno do servidor (5xx). Retryable. | ||
| */ | ||
| declare class ServerError extends IPTUAPIError { | ||
| constructor(message?: string, statusCode?: number, requestId?: string); | ||
| isRetryable(): boolean; | ||
| } | ||
| /** | ||
| * Erro de timeout na requisicao. | ||
| */ | ||
| declare class TimeoutError extends IPTUAPIError { | ||
| readonly timeoutSeconds?: number; | ||
| constructor(message?: string, timeoutSeconds?: number, requestId?: string); | ||
| isRetryable(): boolean; | ||
| toJSON(): ErrorDetails; | ||
| } | ||
| /** | ||
| * Erro de conexao de rede. | ||
| */ | ||
| declare class NetworkError extends IPTUAPIError { | ||
| readonly originalError?: Error; | ||
| constructor(message?: string, originalError?: Error); | ||
| isRetryable(): boolean; | ||
| } | ||
| export { type AVMEstimate, AuthenticationError, type Cidade, type ClientConfig, type ClientOptions, type ComparablesParams, type Comparavel, type EvaluateParams, type FinalValuation, ForbiddenError, IPTUAPIError, IPTUClient, type ITBIAliquota, type ITBICalculo, type ITBICalculoParams, type ITBIGuia, type ITBIGuiaParams, type ITBIHistorico, type ITBIIsencao, type ITBIMarketEstimate, type ITBISimulacao, type ITBISimularParams, type ITBIStatus, type ITBIValidacao, type Imovel, NetworkError, NotFoundError, type Pessoa, type PropertyEvaluation, RateLimitError, type RateLimitInfo, type RetryConfig, ServerError, TimeoutError, ValidationError, type Valuation, type ValuationParams, type Zoneamento }; | ||
| export { AuthenticationError, type BatchValuationResult, type Cidade, CidadeEnum, type ComparavelItem, type ConsultaEnderecoParams, type ConsultaEnderecoResult, type ConsultaSQLResult, ForbiddenError, type HistoricoItem, IPTUAPIError, IPTUClient, type IPTUClientOptions, type Logger, NetworkError, NotFoundError, RateLimitError, type RateLimitInfo, type RetryConfig, ServerError, TimeoutError, ValidationError, type ValuationParams, type ValuationResult, type ZoneamentoResult, IPTUClient as default }; |
+395
-424
@@ -24,2 +24,3 @@ "use strict"; | ||
| AuthenticationError: () => AuthenticationError, | ||
| CidadeEnum: () => CidadeEnum, | ||
| ForbiddenError: () => ForbiddenError, | ||
@@ -33,12 +34,21 @@ IPTUAPIError: () => IPTUAPIError, | ||
| TimeoutError: () => TimeoutError, | ||
| ValidationError: () => ValidationError | ||
| ValidationError: () => ValidationError, | ||
| default: () => index_default | ||
| }); | ||
| module.exports = __toCommonJS(index_exports); | ||
| // src/errors.ts | ||
| var CidadeEnum = { | ||
| SAO_PAULO: "sp", | ||
| BELO_HORIZONTE: "bh", | ||
| RECIFE: "recife", | ||
| PORTO_ALEGRE: "poa", | ||
| FORTALEZA: "fortaleza", | ||
| CURITIBA: "curitiba", | ||
| RIO_DE_JANEIRO: "rj", | ||
| BRASILIA: "brasilia" | ||
| }; | ||
| var IPTUAPIError = class _IPTUAPIError extends Error { | ||
| statusCode; | ||
| requestId; | ||
| responseData; | ||
| constructor(message, statusCode, requestId, responseData) { | ||
| responseBody; | ||
| constructor(message, statusCode, requestId, responseBody) { | ||
| super(message); | ||
@@ -48,21 +58,12 @@ this.name = "IPTUAPIError"; | ||
| this.requestId = requestId; | ||
| this.responseData = responseData || {}; | ||
| this.responseBody = responseBody; | ||
| Object.setPrototypeOf(this, _IPTUAPIError.prototype); | ||
| } | ||
| isRetryable() { | ||
| return false; | ||
| get isRetryable() { | ||
| return this.statusCode ? [429, 500, 502, 503, 504].includes(this.statusCode) : false; | ||
| } | ||
| toJSON() { | ||
| return { | ||
| error: this.name, | ||
| message: this.message, | ||
| statusCode: this.statusCode, | ||
| requestId: this.requestId, | ||
| retryable: this.isRetryable() | ||
| }; | ||
| } | ||
| }; | ||
| var AuthenticationError = class _AuthenticationError extends IPTUAPIError { | ||
| constructor(message = "API Key invalida ou ausente", requestId) { | ||
| super(message, 401, requestId); | ||
| constructor(message = "API Key inv\xE1lida ou expirada", requestId, responseBody) { | ||
| super(message, 401, requestId, responseBody); | ||
| this.name = "AuthenticationError"; | ||
@@ -74,4 +75,4 @@ Object.setPrototypeOf(this, _AuthenticationError.prototype); | ||
| requiredPlan; | ||
| constructor(message = "Acesso negado", requiredPlan, requestId) { | ||
| super(message, 403, requestId); | ||
| constructor(message = "Plano n\xE3o autorizado para este recurso", requiredPlan, requestId, responseBody) { | ||
| super(message, 403, requestId, responseBody); | ||
| this.name = "ForbiddenError"; | ||
@@ -81,64 +82,42 @@ this.requiredPlan = requiredPlan; | ||
| } | ||
| toJSON() { | ||
| return { | ||
| ...super.toJSON(), | ||
| requiredPlan: this.requiredPlan | ||
| }; | ||
| } | ||
| }; | ||
| var NotFoundError = class _NotFoundError extends IPTUAPIError { | ||
| resource; | ||
| constructor(message = "Recurso nao encontrado", resource, requestId) { | ||
| super(message, 404, requestId); | ||
| constructor(message = "Recurso n\xE3o encontrado", requestId, responseBody) { | ||
| super(message, 404, requestId, responseBody); | ||
| this.name = "NotFoundError"; | ||
| this.resource = resource; | ||
| Object.setPrototypeOf(this, _NotFoundError.prototype); | ||
| } | ||
| toJSON() { | ||
| return { | ||
| ...super.toJSON(), | ||
| resource: this.resource | ||
| }; | ||
| } | ||
| }; | ||
| var RateLimitError = class _RateLimitError extends IPTUAPIError { | ||
| retryAfter; | ||
| constructor(message = "Rate limit excedido", retryAfter = 60, requestId) { | ||
| super(message, 429, requestId); | ||
| limit; | ||
| remaining; | ||
| constructor(message = "Limite de requisi\xE7\xF5es excedido", retryAfter, limit, remaining, requestId, responseBody) { | ||
| super(message, 429, requestId, responseBody); | ||
| this.name = "RateLimitError"; | ||
| this.retryAfter = retryAfter; | ||
| this.limit = limit; | ||
| this.remaining = remaining; | ||
| Object.setPrototypeOf(this, _RateLimitError.prototype); | ||
| } | ||
| isRetryable() { | ||
| get isRetryable() { | ||
| return true; | ||
| } | ||
| toJSON() { | ||
| return { | ||
| ...super.toJSON(), | ||
| retryAfter: this.retryAfter | ||
| }; | ||
| } | ||
| }; | ||
| var ValidationError = class _ValidationError extends IPTUAPIError { | ||
| errors; | ||
| constructor(message = "Parametros invalidos", errors, statusCode = 422, requestId) { | ||
| super(message, statusCode, requestId); | ||
| constructor(message = "Par\xE2metros inv\xE1lidos", errors, requestId, responseBody) { | ||
| super(message, 400, requestId, responseBody); | ||
| this.name = "ValidationError"; | ||
| this.errors = errors || {}; | ||
| this.errors = errors; | ||
| Object.setPrototypeOf(this, _ValidationError.prototype); | ||
| } | ||
| toJSON() { | ||
| return { | ||
| ...super.toJSON(), | ||
| validationErrors: this.errors | ||
| }; | ||
| } | ||
| }; | ||
| var ServerError = class _ServerError extends IPTUAPIError { | ||
| constructor(message = "Erro interno do servidor", statusCode = 500, requestId) { | ||
| super(message, statusCode, requestId); | ||
| constructor(message = "Erro interno do servidor", statusCode = 500, requestId, responseBody) { | ||
| super(message, statusCode, requestId, responseBody); | ||
| this.name = "ServerError"; | ||
| Object.setPrototypeOf(this, _ServerError.prototype); | ||
| } | ||
| isRetryable() { | ||
| get isRetryable() { | ||
| return true; | ||
@@ -148,23 +127,17 @@ } | ||
| var TimeoutError = class _TimeoutError extends IPTUAPIError { | ||
| timeoutSeconds; | ||
| constructor(message = "Timeout na requisicao", timeoutSeconds, requestId) { | ||
| super(message, 408, requestId); | ||
| timeoutMs; | ||
| constructor(message = "Timeout na requisi\xE7\xE3o", timeoutMs) { | ||
| super(message, 408); | ||
| this.name = "TimeoutError"; | ||
| this.timeoutSeconds = timeoutSeconds; | ||
| this.timeoutMs = timeoutMs; | ||
| Object.setPrototypeOf(this, _TimeoutError.prototype); | ||
| } | ||
| isRetryable() { | ||
| get isRetryable() { | ||
| return true; | ||
| } | ||
| toJSON() { | ||
| return { | ||
| ...super.toJSON(), | ||
| timeoutSeconds: this.timeoutSeconds | ||
| }; | ||
| } | ||
| }; | ||
| var NetworkError = class _NetworkError extends IPTUAPIError { | ||
| originalError; | ||
| constructor(message = "Erro de conexao", originalError) { | ||
| super(message, void 0, void 0); | ||
| constructor(message = "Erro de conex\xE3o com a API", originalError) { | ||
| super(message); | ||
| this.name = "NetworkError"; | ||
@@ -174,139 +147,195 @@ this.originalError = originalError; | ||
| } | ||
| isRetryable() { | ||
| get isRetryable() { | ||
| return true; | ||
| } | ||
| }; | ||
| // src/client.ts | ||
| var DEFAULT_RETRY_CONFIG = { | ||
| maxRetries: 3, | ||
| initialDelay: 1e3, | ||
| maxDelay: 3e4, | ||
| initialDelay: 500, | ||
| maxDelay: 1e4, | ||
| backoffFactor: 2, | ||
| retryableStatusCodes: [429, 500, 502, 503, 504] | ||
| retryableStatuses: [429, 500, 502, 503, 504] | ||
| }; | ||
| var DEFAULT_CONFIG = { | ||
| baseUrl: "https://iptuapi.com.br/api/v1", | ||
| timeout: 3e4, | ||
| retryConfig: DEFAULT_RETRY_CONFIG | ||
| }; | ||
| function toCamelCase(obj) { | ||
| const result = {}; | ||
| for (const [key, value] of Object.entries(obj)) { | ||
| const camelKey = key.replace( | ||
| /_([a-z])/g, | ||
| (_, letter) => letter.toUpperCase() | ||
| ); | ||
| if (value !== null && typeof value === "object" && !Array.isArray(value)) { | ||
| result[camelKey] = toCamelCase(value); | ||
| } else if (Array.isArray(value)) { | ||
| result[camelKey] = value.map( | ||
| (item) => typeof item === "object" && item !== null ? toCamelCase(item) : item | ||
| ); | ||
| } else { | ||
| result[camelKey] = value; | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| function toSnakeCase(obj) { | ||
| const result = {}; | ||
| for (const [key, value] of Object.entries(obj)) { | ||
| const snakeKey = key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`); | ||
| if (value !== null && typeof value === "object" && !Array.isArray(value)) { | ||
| result[snakeKey] = toSnakeCase(value); | ||
| } else if (Array.isArray(value)) { | ||
| result[snakeKey] = value.map( | ||
| (item) => typeof item === "object" && item !== null ? toSnakeCase(item) : item | ||
| ); | ||
| } else { | ||
| result[snakeKey] = value; | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| var IPTUClient = class { | ||
| apiKey; | ||
| config; | ||
| _rateLimitInfo = null; | ||
| _lastRequestId = null; | ||
| /** | ||
| * Cria uma nova instancia do cliente. | ||
| * | ||
| * @param apiKey - Chave de API para autenticacao | ||
| * @param options - Opcoes de configuracao | ||
| */ | ||
| constructor(apiKey, options) { | ||
| baseUrl; | ||
| timeout; | ||
| retryConfig; | ||
| logger; | ||
| logRequests; | ||
| logResponses; | ||
| userAgent; | ||
| _rateLimit; | ||
| _lastRequestId; | ||
| constructor(apiKey, options = {}) { | ||
| if (!apiKey) { | ||
| throw new Error("API Key \xE9 obrigat\xF3ria"); | ||
| } | ||
| this.apiKey = apiKey; | ||
| this.config = { | ||
| baseUrl: options?.baseUrl || DEFAULT_CONFIG.baseUrl, | ||
| timeout: options?.timeout || DEFAULT_CONFIG.timeout, | ||
| retryConfig: { | ||
| ...DEFAULT_RETRY_CONFIG, | ||
| ...options?.retryConfig | ||
| } | ||
| }; | ||
| this.baseUrl = options.baseUrl || "https://iptuapi.com.br/api/v1"; | ||
| this.timeout = options.timeout || 3e4; | ||
| this.retryConfig = { ...DEFAULT_RETRY_CONFIG, ...options.retry }; | ||
| this.logger = options.logger; | ||
| this.logRequests = options.logRequests || false; | ||
| this.logResponses = options.logResponses || false; | ||
| this.userAgent = options.userAgent || "iptuapi-js/2.1.0"; | ||
| } | ||
| /** | ||
| * Retorna informacoes do rate limit da ultima requisicao. | ||
| */ | ||
| get rateLimitInfo() { | ||
| return this._rateLimitInfo; | ||
| // =========================================================================== | ||
| // Properties | ||
| // =========================================================================== | ||
| /** Rate limit info from last request */ | ||
| get rateLimit() { | ||
| return this._rateLimit; | ||
| } | ||
| /** | ||
| * Retorna o ID da ultima requisicao. | ||
| */ | ||
| /** Request ID from last request (useful for support) */ | ||
| get lastRequestId() { | ||
| return this._lastRequestId; | ||
| } | ||
| /** | ||
| * Executa uma requisicao HTTP com retry. | ||
| */ | ||
| async makeRequest(method, endpoint, params, body) { | ||
| const url = new URL(`${this.config.baseUrl}/${endpoint.replace(/^\//, "")}`); | ||
| // =========================================================================== | ||
| // Private Methods | ||
| // =========================================================================== | ||
| log(level, message, ...args) { | ||
| if (this.logger && this.logger[level]) { | ||
| this.logger[level](message, ...args); | ||
| } | ||
| } | ||
| sleep(ms) { | ||
| return new Promise((resolve) => setTimeout(resolve, ms)); | ||
| } | ||
| calculateDelay(attempt) { | ||
| const delay = this.retryConfig.initialDelay * Math.pow(this.retryConfig.backoffFactor, attempt); | ||
| return Math.min(delay, this.retryConfig.maxDelay); | ||
| } | ||
| extractRateLimit(headers) { | ||
| const limit = headers.get("X-RateLimit-Limit"); | ||
| const remaining = headers.get("X-RateLimit-Remaining"); | ||
| const reset = headers.get("X-RateLimit-Reset"); | ||
| if (limit && remaining && reset) { | ||
| const resetTimestamp = parseInt(reset, 10); | ||
| return { | ||
| limit: parseInt(limit, 10), | ||
| remaining: parseInt(remaining, 10), | ||
| reset: resetTimestamp, | ||
| resetDate: new Date(resetTimestamp * 1e3) | ||
| }; | ||
| } | ||
| return void 0; | ||
| } | ||
| async handleErrorResponse(response, requestId) { | ||
| let body = {}; | ||
| try { | ||
| body = await response.json(); | ||
| } catch { | ||
| body = { detail: response.statusText }; | ||
| } | ||
| let message; | ||
| const detail = body.detail; | ||
| if (detail && typeof detail === "object") { | ||
| const detailObj = detail; | ||
| message = detailObj.error || detailObj.detail || detailObj.message || JSON.stringify(detail); | ||
| } else { | ||
| message = detail || `HTTP ${response.status}`; | ||
| } | ||
| switch (response.status) { | ||
| case 400: | ||
| case 422: | ||
| throw new ValidationError( | ||
| message, | ||
| body.errors, | ||
| requestId, | ||
| body | ||
| ); | ||
| case 401: | ||
| throw new AuthenticationError(message, requestId, body); | ||
| case 403: | ||
| throw new ForbiddenError( | ||
| message, | ||
| body.required_plan, | ||
| requestId, | ||
| body | ||
| ); | ||
| case 404: | ||
| throw new NotFoundError(message, requestId, body); | ||
| case 429: | ||
| const retryAfter = response.headers.get("Retry-After"); | ||
| throw new RateLimitError( | ||
| message, | ||
| retryAfter ? parseInt(retryAfter, 10) : void 0, | ||
| this._rateLimit?.limit, | ||
| this._rateLimit?.remaining, | ||
| requestId, | ||
| body | ||
| ); | ||
| case 500: | ||
| case 502: | ||
| case 503: | ||
| case 504: | ||
| throw new ServerError(message, response.status, requestId, body); | ||
| default: | ||
| throw new IPTUAPIError(message, response.status, requestId, body); | ||
| } | ||
| } | ||
| async request(method, endpoint, params, body) { | ||
| const url = new URL(`${this.baseUrl}${endpoint}`); | ||
| if (params) { | ||
| for (const [key, value] of Object.entries(params)) { | ||
| if (value !== void 0 && value !== null) { | ||
| Object.entries(params).forEach(([key, value]) => { | ||
| if (value !== void 0 && value !== null && value !== "") { | ||
| url.searchParams.append(key, String(value)); | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| const { maxRetries, initialDelay, maxDelay, backoffFactor } = this.config.retryConfig; | ||
| let delay = initialDelay; | ||
| for (let attempt = 0; attempt <= maxRetries; attempt++) { | ||
| const headers = { | ||
| "X-API-Key": this.apiKey, | ||
| "Content-Type": "application/json", | ||
| Accept: "application/json", | ||
| "User-Agent": this.userAgent | ||
| }; | ||
| let lastError; | ||
| let attempt = 0; | ||
| while (attempt <= this.retryConfig.maxRetries) { | ||
| const controller = new AbortController(); | ||
| const timeoutId = setTimeout( | ||
| () => controller.abort(), | ||
| this.config.timeout | ||
| ); | ||
| const timeoutId = setTimeout(() => controller.abort(), this.timeout); | ||
| try { | ||
| if (this.logRequests) { | ||
| this.log( | ||
| "debug", | ||
| `Request: ${method} ${url}`, | ||
| params ? { params } : {}, | ||
| body ? { body } : {} | ||
| ); | ||
| } | ||
| const startTime = Date.now(); | ||
| const response = await fetch(url.toString(), { | ||
| method, | ||
| headers: { | ||
| "X-API-Key": this.apiKey, | ||
| "Content-Type": "application/json", | ||
| Accept: "application/json", | ||
| "User-Agent": "iptuapi-js/1.0.0" | ||
| }, | ||
| body: body ? JSON.stringify(toSnakeCase(body)) : void 0, | ||
| headers, | ||
| body: body ? JSON.stringify(body) : void 0, | ||
| signal: controller.signal | ||
| }); | ||
| clearTimeout(timeoutId); | ||
| this.updateRateLimitInfo(response.headers); | ||
| this._lastRequestId = response.headers.get("X-Request-ID"); | ||
| if (!response.ok) { | ||
| await this.handleError(response); | ||
| const elapsedMs = Date.now() - startTime; | ||
| this._rateLimit = this.extractRateLimit(response.headers); | ||
| this._lastRequestId = response.headers.get("X-Request-ID") || void 0; | ||
| if (this.logResponses) { | ||
| this.log( | ||
| "debug", | ||
| `Response: ${response.status} ${url} (${elapsedMs}ms)` | ||
| ); | ||
| } | ||
| const data = await response.json(); | ||
| return toCamelCase(data.data || data); | ||
| if (response.ok) { | ||
| return await response.json(); | ||
| } | ||
| if (this.retryConfig.retryableStatuses.includes(response.status) && attempt < this.retryConfig.maxRetries) { | ||
| const delay = this.calculateDelay(attempt); | ||
| this.log( | ||
| "warn", | ||
| `Request failed with ${response.status}, retrying in ${delay}ms (attempt ${attempt + 1}/${this.retryConfig.maxRetries})` | ||
| ); | ||
| await this.sleep(delay); | ||
| attempt++; | ||
| continue; | ||
| } | ||
| await this.handleErrorResponse(response, this._lastRequestId); | ||
| } catch (error) { | ||
| clearTimeout(timeoutId); | ||
| if (error instanceof IPTUAPIError) { | ||
| if (error.isRetryable() && attempt < maxRetries && this.config.retryConfig.retryableStatusCodes.includes( | ||
| error.statusCode || 0 | ||
| )) { | ||
| await this.sleep(delay); | ||
| delay = Math.min(delay * backoffFactor, maxDelay); | ||
| continue; | ||
| } | ||
| throw error; | ||
@@ -316,140 +345,84 @@ } | ||
| if (error.name === "AbortError") { | ||
| if (attempt < maxRetries) { | ||
| await this.sleep(delay); | ||
| delay = Math.min(delay * backoffFactor, maxDelay); | ||
| continue; | ||
| } | ||
| throw new TimeoutError( | ||
| `Timeout apos ${this.config.timeout}ms`, | ||
| this.config.timeout / 1e3 | ||
| lastError = new TimeoutError( | ||
| `Timeout ap\xF3s ${this.timeout}ms`, | ||
| this.timeout | ||
| ); | ||
| } else if (error.message.includes("fetch") || error.message.includes("network")) { | ||
| lastError = new NetworkError( | ||
| `Erro de conex\xE3o: ${error.message}`, | ||
| error | ||
| ); | ||
| } else { | ||
| lastError = error; | ||
| } | ||
| if (attempt < maxRetries) { | ||
| if (attempt < this.retryConfig.maxRetries) { | ||
| const delay = this.calculateDelay(attempt); | ||
| this.log( | ||
| "warn", | ||
| `Request failed: ${error.message}, retrying in ${delay}ms (attempt ${attempt + 1}/${this.retryConfig.maxRetries})` | ||
| ); | ||
| await this.sleep(delay); | ||
| delay = Math.min(delay * backoffFactor, maxDelay); | ||
| attempt++; | ||
| continue; | ||
| } | ||
| throw new NetworkError(`Erro de conexao: ${error.message}`, error); | ||
| } | ||
| throw new NetworkError("Erro desconhecido"); | ||
| throw lastError || error; | ||
| } | ||
| } | ||
| throw new NetworkError("Maximo de tentativas excedido"); | ||
| throw lastError || new IPTUAPIError("Max retries exceeded"); | ||
| } | ||
| /** | ||
| * Atualiza informacoes de rate limit a partir dos headers. | ||
| */ | ||
| updateRateLimitInfo(headers) { | ||
| const limit = headers.get("X-RateLimit-Limit"); | ||
| const remaining = headers.get("X-RateLimit-Remaining"); | ||
| const reset = headers.get("X-RateLimit-Reset"); | ||
| if (limit && remaining && reset) { | ||
| this._rateLimitInfo = { | ||
| limit: parseInt(limit, 10), | ||
| remaining: parseInt(remaining, 10), | ||
| resetAt: new Date(parseInt(reset, 10) * 1e3) | ||
| async consultaEndereco(paramsOrLogradouro, numero, cidade) { | ||
| let params; | ||
| if (typeof paramsOrLogradouro === "string") { | ||
| params = { | ||
| logradouro: paramsOrLogradouro, | ||
| numero, | ||
| cidade: cidade || "sp" | ||
| }; | ||
| } else { | ||
| params = { | ||
| logradouro: paramsOrLogradouro.logradouro, | ||
| numero: paramsOrLogradouro.numero, | ||
| complemento: paramsOrLogradouro.complemento, | ||
| cidade: paramsOrLogradouro.cidade || "sp", | ||
| incluir_historico: paramsOrLogradouro.incluirHistorico, | ||
| incluir_comparaveis: paramsOrLogradouro.incluirComparaveis, | ||
| incluir_zoneamento: paramsOrLogradouro.incluirZoneamento | ||
| }; | ||
| } | ||
| return this.request( | ||
| "GET", | ||
| "/consulta/endereco", | ||
| params | ||
| ); | ||
| } | ||
| /** | ||
| * Converte resposta HTTP em excecao apropriada. | ||
| */ | ||
| async handleError(response) { | ||
| const requestId = response.headers.get("X-Request-ID") || void 0; | ||
| let data = {}; | ||
| let message = "Erro desconhecido"; | ||
| try { | ||
| data = await response.json(); | ||
| message = data.detail || data.message || message; | ||
| } catch { | ||
| message = response.statusText || message; | ||
| } | ||
| switch (response.status) { | ||
| case 401: | ||
| throw new AuthenticationError(message, requestId); | ||
| case 403: | ||
| throw new ForbiddenError( | ||
| message, | ||
| data.required_plan, | ||
| requestId | ||
| ); | ||
| case 404: | ||
| throw new NotFoundError( | ||
| message, | ||
| data.resource, | ||
| requestId | ||
| ); | ||
| case 429: { | ||
| const retryAfter = parseInt( | ||
| response.headers.get("Retry-After") || "60", | ||
| 10 | ||
| ); | ||
| throw new RateLimitError(message, retryAfter, requestId); | ||
| } | ||
| case 400: | ||
| case 422: | ||
| throw new ValidationError( | ||
| message, | ||
| data.errors, | ||
| response.status, | ||
| requestId | ||
| ); | ||
| default: | ||
| if (response.status >= 500) { | ||
| throw new ServerError(message, response.status, requestId); | ||
| } | ||
| throw new IPTUAPIError(message, response.status, requestId, data); | ||
| } | ||
| } | ||
| /** | ||
| * Aguarda um tempo em milissegundos. | ||
| */ | ||
| sleep(ms) { | ||
| return new Promise((resolve) => setTimeout(resolve, ms)); | ||
| } | ||
| // ==================== CONSULTAS IPTU ==================== | ||
| /** | ||
| * Consulta imoveis por endereco. | ||
| * Busca dados de IPTU por número SQL (contribuinte). | ||
| * | ||
| * @param logradouro - Nome da rua/avenida | ||
| * @param numero - Numero do imovel | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Lista de imoveis encontrados | ||
| * @param sql - Número SQL do imóvel | ||
| * @param cidade - Cidade da consulta | ||
| * @param options - Opções adicionais | ||
| * @returns Dados completos do imóvel | ||
| */ | ||
| async consultaEndereco(logradouro, numero, cidade = "sp") { | ||
| const response = await this.makeRequest("GET", "/consulta/endereco", { | ||
| logradouro, | ||
| numero, | ||
| cidade | ||
| async consultaSQL(sql, cidade = "sp", options) { | ||
| return this.request("GET", `/consulta/sql/${sql}`, { | ||
| cidade, | ||
| incluir_historico: options?.incluirHistorico, | ||
| incluir_comparaveis: options?.incluirComparaveis | ||
| }); | ||
| return Array.isArray(response) ? response : []; | ||
| } | ||
| /** | ||
| * Consulta imovel por numero SQL/Indice Cadastral. | ||
| * Requer plano Starter ou superior. | ||
| * Busca imóveis por CEP. | ||
| * | ||
| * @param sql - Numero SQL (SP), Indice Cadastral (BH) ou Sequencial (Recife) | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Lista de imoveis encontrados | ||
| * @param cep - CEP do imóvel | ||
| * @param cidade - Cidade da consulta | ||
| * @returns Lista de imóveis no CEP | ||
| */ | ||
| async consultaSQL(sql, cidade = "sp") { | ||
| const response = await this.makeRequest("GET", "/consulta/sql", { | ||
| sql, | ||
| cidade | ||
| }); | ||
| return Array.isArray(response) ? response : []; | ||
| } | ||
| /** | ||
| * Consulta imoveis por CEP. | ||
| * | ||
| * @param cep - CEP do endereco | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Lista de imoveis encontrados | ||
| */ | ||
| async consultaCEP(cep, cidade = "sp") { | ||
| const response = await this.makeRequest("GET", "/consulta/cep", { | ||
| cep, | ||
| cidade | ||
| }); | ||
| return Array.isArray(response) ? response : []; | ||
| const cleanCep = cep.replace(/\D/g, ""); | ||
| return this.request( | ||
| "GET", | ||
| `/consulta/cep/${cleanCep}`, | ||
| { cidade } | ||
| ); | ||
| } | ||
@@ -461,193 +434,191 @@ /** | ||
| * @param longitude - Longitude do ponto | ||
| * @returns Informacoes de zoneamento | ||
| * @returns Dados de zoneamento | ||
| */ | ||
| async consultaZoneamento(latitude, longitude) { | ||
| return this.makeRequest("GET", "/consulta/zoneamento", { | ||
| lat: latitude, | ||
| lng: longitude | ||
| return this.request("GET", "/consulta/zoneamento", { | ||
| latitude, | ||
| longitude | ||
| }); | ||
| } | ||
| // ==================== VALUATION ==================== | ||
| // =========================================================================== | ||
| // Valuation Endpoints (Pro+) | ||
| // =========================================================================== | ||
| /** | ||
| * Calcula estimativa de valor de mercado. | ||
| * Requer plano Pro ou superior. | ||
| * Estima o valor de mercado do imóvel usando ML. | ||
| * Disponível apenas para planos Pro e Enterprise. | ||
| * | ||
| * @param params - Parametros da avaliacao | ||
| * @returns Avaliacao de mercado | ||
| * @param params - Parâmetros do imóvel | ||
| * @returns Estimativa de valor | ||
| * @throws {ForbiddenError} Se o plano não permitir | ||
| */ | ||
| async valuationEstimate(params) { | ||
| return this.makeRequest("GET", "/valuation/estimate", { | ||
| area_terreno: params.areaTerreno, | ||
| area_construida: params.areaConstruida, | ||
| bairro: params.bairro, | ||
| cidade: params.cidade || "sp", | ||
| zona: params.zona, | ||
| tipo_uso: params.tipoUso, | ||
| tipo_padrao: params.tipoPadrao, | ||
| ano_construcao: params.anoConstrucao | ||
| }); | ||
| } | ||
| /** | ||
| * Busca imoveis comparaveis. | ||
| * Requer plano Pro ou superior. | ||
| * | ||
| * @param params - Parametros da busca | ||
| * @returns Lista de imoveis comparaveis | ||
| */ | ||
| async valuationComparables(params) { | ||
| const response = await this.makeRequest( | ||
| "GET", | ||
| "/valuation/comparables", | ||
| return this.request( | ||
| "POST", | ||
| "/valuation/estimate", | ||
| void 0, | ||
| { | ||
| area_terreno: params.area_terreno, | ||
| area_construida: params.area_construida, | ||
| bairro: params.bairro, | ||
| area_min: params.areaMin, | ||
| area_max: params.areaMax, | ||
| cidade: params.cidade || "sp", | ||
| limit: params.limit || 10 | ||
| zona: params.zona, | ||
| tipo_uso: params.tipo_uso, | ||
| tipo_padrao: params.tipo_padrao, | ||
| ano_construcao: params.ano_construcao, | ||
| cidade: params.cidade || "sp" | ||
| } | ||
| ); | ||
| return Array.isArray(response) ? response : []; | ||
| } | ||
| /** | ||
| * Avalia imovel por endereco OU SQL. | ||
| * Combina dados do modelo AVM (ML) com transacoes ITBI reais. | ||
| * Requer plano Pro ou superior. | ||
| * Valuation em lote (até 100 imóveis). | ||
| * Disponível apenas para plano Enterprise. | ||
| * | ||
| * @param params - Parametros da avaliacao (sql OU logradouro+numero) | ||
| * @returns Avaliacao completa do imovel | ||
| * @param imoveis - Lista de imóveis para avaliar | ||
| * @returns Resultados de valuation para cada imóvel | ||
| */ | ||
| async valuationEvaluate(params) { | ||
| const body = { | ||
| cidade: params.cidade || "sp", | ||
| incluirItbi: params.incluirItbi ?? true, | ||
| incluirComparaveis: params.incluirComparaveis ?? true | ||
| }; | ||
| if (params.sql) { | ||
| body.sql = params.sql; | ||
| } else { | ||
| if (params.logradouro) body.logradouro = params.logradouro; | ||
| if (params.numero !== void 0) body.numero = params.numero; | ||
| if (params.complemento) body.complemento = params.complemento; | ||
| if (params.bairro) body.bairro = params.bairro; | ||
| } | ||
| return this.makeRequest( | ||
| async valuationBatch(imoveis) { | ||
| return this.request( | ||
| "POST", | ||
| "/valuation/evaluate", | ||
| "/valuation/estimate/batch", | ||
| void 0, | ||
| body | ||
| { imoveis } | ||
| ); | ||
| } | ||
| // ==================== ITBI ==================== | ||
| /** | ||
| * Consulta status de transacao ITBI. | ||
| * Busca imóveis comparáveis para análise. | ||
| * | ||
| * @param protocolo - Numero do protocolo ITBI | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Status da transacao | ||
| * @param bairro - Nome do bairro | ||
| * @param areaMin - Área mínima em m² | ||
| * @param areaMax - Área máxima em m² | ||
| * @param options - Opções adicionais | ||
| * @returns Lista de imóveis comparáveis | ||
| */ | ||
| async itbiStatus(protocolo, cidade = "sp") { | ||
| return this.makeRequest("GET", "/itbi/status", { | ||
| protocolo, | ||
| cidade | ||
| async valuationComparables(bairro, areaMin, areaMax, options) { | ||
| return this.request("GET", "/valuation/comparables", { | ||
| bairro, | ||
| area_min: areaMin, | ||
| area_max: areaMax, | ||
| tipo_uso: options?.tipoUso, | ||
| cidade: options?.cidade || "sp", | ||
| limit: options?.limit || 10 | ||
| }); | ||
| } | ||
| // =========================================================================== | ||
| // Dados Endpoints | ||
| // =========================================================================== | ||
| /** | ||
| * Calcula valor do ITBI. | ||
| * Histórico de valores IPTU de um imóvel. | ||
| * | ||
| * @param params - Parametros do calculo | ||
| * @returns Calculo do ITBI | ||
| * @param sql - Número SQL do imóvel | ||
| * @param cidade - Cidade da consulta | ||
| * @returns Lista com histórico anual | ||
| */ | ||
| async itbiCalcular(params) { | ||
| return this.makeRequest("POST", "/itbi/calcular", void 0, { | ||
| sql: params.sql, | ||
| valorTransacao: params.valorTransacao, | ||
| cidade: params.cidade || "sp" | ||
| }); | ||
| async dadosIPTUHistorico(sql, cidade = "sp") { | ||
| return this.request( | ||
| "GET", | ||
| `/dados/iptu/historico/${sql}`, | ||
| { cidade } | ||
| ); | ||
| } | ||
| /** | ||
| * Consulta historico de transacoes ITBI de um imovel. | ||
| * Requer plano Starter ou superior. | ||
| * Consulta dados de empresa por CNPJ. | ||
| * | ||
| * @param sql - Numero SQL do imovel | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Lista de transacoes historicas | ||
| * @param cnpj - CNPJ da empresa | ||
| * @returns Dados cadastrais | ||
| */ | ||
| async itbiHistorico(sql, cidade = "sp") { | ||
| const response = await this.makeRequest( | ||
| async dadosCNPJ(cnpj) { | ||
| const cleanCnpj = cnpj.replace(/\D/g, ""); | ||
| return this.request( | ||
| "GET", | ||
| "/itbi/historico", | ||
| { sql, cidade } | ||
| `/dados/cnpj/${cleanCnpj}` | ||
| ); | ||
| return Array.isArray(response) ? response : []; | ||
| } | ||
| /** | ||
| * Consulta aliquotas ITBI vigentes. | ||
| * Correção monetária pelo IPCA. | ||
| * | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Aliquotas vigentes | ||
| * @param valor - Valor a corrigir | ||
| * @param dataOrigem - Data do valor original (YYYY-MM) | ||
| * @param dataDestino - Data destino (default: atual) | ||
| * @returns Valor corrigido e fator de correção | ||
| */ | ||
| async itbiAliquotas(cidade = "sp") { | ||
| return this.makeRequest("GET", "/itbi/aliquotas", { cidade }); | ||
| async dadosIPCACorrigir(valor, dataOrigem, dataDestino) { | ||
| return this.request( | ||
| "GET", | ||
| "/dados/ipca/corrigir", | ||
| { | ||
| valor, | ||
| data_origem: dataOrigem, | ||
| data_destino: dataDestino | ||
| } | ||
| ); | ||
| } | ||
| // =========================================================================== | ||
| // IPTU Tools Endpoints (Ferramentas IPTU 2026) | ||
| // =========================================================================== | ||
| /** | ||
| * Consulta isencoes ITBI disponiveis. | ||
| * Lista todas as cidades com calendario de IPTU disponivel. | ||
| * | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Lista de isencoes disponiveis | ||
| * @returns Lista de cidades com codigo, nome, desconto e parcelas | ||
| */ | ||
| async itbiIsencoes(cidade = "sp") { | ||
| const response = await this.makeRequest( | ||
| "GET", | ||
| "/itbi/isencoes", | ||
| { cidade } | ||
| ); | ||
| return Array.isArray(response) ? response : []; | ||
| async iptuToolsCidades() { | ||
| return this.request("GET", "/iptu-tools/cidades"); | ||
| } | ||
| /** | ||
| * Gera guia de pagamento ITBI. | ||
| * Requer plano Starter ou superior. | ||
| * Retorna o calendario completo de IPTU para a cidade especificada. | ||
| * | ||
| * @param params - Parametros da guia | ||
| * @returns Guia de pagamento gerada | ||
| * @param cidade - Codigo da cidade (sp, bh, rj, recife, curitiba, poa, fortaleza) | ||
| * @returns Calendario com vencimentos, descontos, alertas e novidades | ||
| */ | ||
| async itbiGuia(params) { | ||
| return this.makeRequest("POST", "/itbi/guia", void 0, { | ||
| sql: params.sql, | ||
| valorTransacao: params.valorTransacao, | ||
| comprador: params.comprador, | ||
| vendedor: params.vendedor, | ||
| cidade: params.cidade || "sp" | ||
| }); | ||
| async iptuToolsCalendario(cidade = "sp") { | ||
| return this.request("GET", "/iptu-tools/calendario", { cidade }); | ||
| } | ||
| /** | ||
| * Valida autenticidade de uma guia ITBI. | ||
| * Simula as opcoes de pagamento do IPTU (a vista vs parcelado). | ||
| * | ||
| * @param protocolo - Numero do protocolo da guia | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Resultado da validacao | ||
| * @param valorIptu - Valor total do IPTU | ||
| * @param cidade - Codigo da cidade | ||
| * @param valorVenal - Valor venal do imovel (para verificar isencao) | ||
| * @returns Comparativo entre pagamento a vista e parcelado com recomendacao | ||
| */ | ||
| async itbiValidarGuia(protocolo, cidade = "sp") { | ||
| return this.makeRequest("GET", "/itbi/validar", { | ||
| protocolo, | ||
| async iptuToolsSimulador(valorIptu, cidade = "sp", valorVenal) { | ||
| const body = { | ||
| valor_iptu: valorIptu, | ||
| cidade | ||
| }; | ||
| if (valorVenal !== void 0) { | ||
| body.valor_venal = valorVenal; | ||
| } | ||
| return this.request("POST", "/iptu-tools/simulador", void 0, body); | ||
| } | ||
| /** | ||
| * Verifica se um imovel e elegivel para isencao de IPTU. | ||
| * | ||
| * @param valorVenal - Valor venal do imovel | ||
| * @param cidade - Codigo da cidade | ||
| * @returns Elegibilidade para isencao total ou parcial | ||
| */ | ||
| async iptuToolsIsencao(valorVenal, cidade = "sp") { | ||
| return this.request("GET", "/iptu-tools/isencao", { | ||
| valor_venal: valorVenal, | ||
| cidade | ||
| }); | ||
| } | ||
| /** | ||
| * Simula calculo de ITBI. | ||
| * Retorna informacoes sobre o proximo vencimento do IPTU. | ||
| * | ||
| * @param params - Parametros da simulacao | ||
| * @returns Resultado da simulacao | ||
| * @param cidade - Codigo da cidade | ||
| * @param parcela - Numero da parcela (1-12) | ||
| * @returns Data de vencimento, dias restantes e status | ||
| */ | ||
| async itbiSimular(params) { | ||
| return this.makeRequest("POST", "/itbi/simular", void 0, { | ||
| valorTransacao: params.valorTransacao, | ||
| cidade: params.cidade || "sp", | ||
| tipoFinanciamento: params.tipoFinanciamento, | ||
| valorFinanciado: params.valorFinanciado | ||
| async iptuToolsProximoVencimento(cidade = "sp", parcela = 1) { | ||
| return this.request("GET", "/iptu-tools/proximo-vencimento", { | ||
| cidade, | ||
| parcela | ||
| }); | ||
| } | ||
| }; | ||
| var index_default = IPTUClient; | ||
| // Annotate the CommonJS export names for ESM import in node: | ||
| 0 && (module.exports = { | ||
| AuthenticationError, | ||
| CidadeEnum, | ||
| ForbiddenError, | ||
@@ -654,0 +625,0 @@ IPTUAPIError, |
+395
-423
@@ -1,7 +0,17 @@ | ||
| // src/errors.ts | ||
| // src/index.ts | ||
| var CidadeEnum = { | ||
| SAO_PAULO: "sp", | ||
| BELO_HORIZONTE: "bh", | ||
| RECIFE: "recife", | ||
| PORTO_ALEGRE: "poa", | ||
| FORTALEZA: "fortaleza", | ||
| CURITIBA: "curitiba", | ||
| RIO_DE_JANEIRO: "rj", | ||
| BRASILIA: "brasilia" | ||
| }; | ||
| var IPTUAPIError = class _IPTUAPIError extends Error { | ||
| statusCode; | ||
| requestId; | ||
| responseData; | ||
| constructor(message, statusCode, requestId, responseData) { | ||
| responseBody; | ||
| constructor(message, statusCode, requestId, responseBody) { | ||
| super(message); | ||
@@ -11,21 +21,12 @@ this.name = "IPTUAPIError"; | ||
| this.requestId = requestId; | ||
| this.responseData = responseData || {}; | ||
| this.responseBody = responseBody; | ||
| Object.setPrototypeOf(this, _IPTUAPIError.prototype); | ||
| } | ||
| isRetryable() { | ||
| return false; | ||
| get isRetryable() { | ||
| return this.statusCode ? [429, 500, 502, 503, 504].includes(this.statusCode) : false; | ||
| } | ||
| toJSON() { | ||
| return { | ||
| error: this.name, | ||
| message: this.message, | ||
| statusCode: this.statusCode, | ||
| requestId: this.requestId, | ||
| retryable: this.isRetryable() | ||
| }; | ||
| } | ||
| }; | ||
| var AuthenticationError = class _AuthenticationError extends IPTUAPIError { | ||
| constructor(message = "API Key invalida ou ausente", requestId) { | ||
| super(message, 401, requestId); | ||
| constructor(message = "API Key inv\xE1lida ou expirada", requestId, responseBody) { | ||
| super(message, 401, requestId, responseBody); | ||
| this.name = "AuthenticationError"; | ||
@@ -37,4 +38,4 @@ Object.setPrototypeOf(this, _AuthenticationError.prototype); | ||
| requiredPlan; | ||
| constructor(message = "Acesso negado", requiredPlan, requestId) { | ||
| super(message, 403, requestId); | ||
| constructor(message = "Plano n\xE3o autorizado para este recurso", requiredPlan, requestId, responseBody) { | ||
| super(message, 403, requestId, responseBody); | ||
| this.name = "ForbiddenError"; | ||
@@ -44,64 +45,42 @@ this.requiredPlan = requiredPlan; | ||
| } | ||
| toJSON() { | ||
| return { | ||
| ...super.toJSON(), | ||
| requiredPlan: this.requiredPlan | ||
| }; | ||
| } | ||
| }; | ||
| var NotFoundError = class _NotFoundError extends IPTUAPIError { | ||
| resource; | ||
| constructor(message = "Recurso nao encontrado", resource, requestId) { | ||
| super(message, 404, requestId); | ||
| constructor(message = "Recurso n\xE3o encontrado", requestId, responseBody) { | ||
| super(message, 404, requestId, responseBody); | ||
| this.name = "NotFoundError"; | ||
| this.resource = resource; | ||
| Object.setPrototypeOf(this, _NotFoundError.prototype); | ||
| } | ||
| toJSON() { | ||
| return { | ||
| ...super.toJSON(), | ||
| resource: this.resource | ||
| }; | ||
| } | ||
| }; | ||
| var RateLimitError = class _RateLimitError extends IPTUAPIError { | ||
| retryAfter; | ||
| constructor(message = "Rate limit excedido", retryAfter = 60, requestId) { | ||
| super(message, 429, requestId); | ||
| limit; | ||
| remaining; | ||
| constructor(message = "Limite de requisi\xE7\xF5es excedido", retryAfter, limit, remaining, requestId, responseBody) { | ||
| super(message, 429, requestId, responseBody); | ||
| this.name = "RateLimitError"; | ||
| this.retryAfter = retryAfter; | ||
| this.limit = limit; | ||
| this.remaining = remaining; | ||
| Object.setPrototypeOf(this, _RateLimitError.prototype); | ||
| } | ||
| isRetryable() { | ||
| get isRetryable() { | ||
| return true; | ||
| } | ||
| toJSON() { | ||
| return { | ||
| ...super.toJSON(), | ||
| retryAfter: this.retryAfter | ||
| }; | ||
| } | ||
| }; | ||
| var ValidationError = class _ValidationError extends IPTUAPIError { | ||
| errors; | ||
| constructor(message = "Parametros invalidos", errors, statusCode = 422, requestId) { | ||
| super(message, statusCode, requestId); | ||
| constructor(message = "Par\xE2metros inv\xE1lidos", errors, requestId, responseBody) { | ||
| super(message, 400, requestId, responseBody); | ||
| this.name = "ValidationError"; | ||
| this.errors = errors || {}; | ||
| this.errors = errors; | ||
| Object.setPrototypeOf(this, _ValidationError.prototype); | ||
| } | ||
| toJSON() { | ||
| return { | ||
| ...super.toJSON(), | ||
| validationErrors: this.errors | ||
| }; | ||
| } | ||
| }; | ||
| var ServerError = class _ServerError extends IPTUAPIError { | ||
| constructor(message = "Erro interno do servidor", statusCode = 500, requestId) { | ||
| super(message, statusCode, requestId); | ||
| constructor(message = "Erro interno do servidor", statusCode = 500, requestId, responseBody) { | ||
| super(message, statusCode, requestId, responseBody); | ||
| this.name = "ServerError"; | ||
| Object.setPrototypeOf(this, _ServerError.prototype); | ||
| } | ||
| isRetryable() { | ||
| get isRetryable() { | ||
| return true; | ||
@@ -111,23 +90,17 @@ } | ||
| var TimeoutError = class _TimeoutError extends IPTUAPIError { | ||
| timeoutSeconds; | ||
| constructor(message = "Timeout na requisicao", timeoutSeconds, requestId) { | ||
| super(message, 408, requestId); | ||
| timeoutMs; | ||
| constructor(message = "Timeout na requisi\xE7\xE3o", timeoutMs) { | ||
| super(message, 408); | ||
| this.name = "TimeoutError"; | ||
| this.timeoutSeconds = timeoutSeconds; | ||
| this.timeoutMs = timeoutMs; | ||
| Object.setPrototypeOf(this, _TimeoutError.prototype); | ||
| } | ||
| isRetryable() { | ||
| get isRetryable() { | ||
| return true; | ||
| } | ||
| toJSON() { | ||
| return { | ||
| ...super.toJSON(), | ||
| timeoutSeconds: this.timeoutSeconds | ||
| }; | ||
| } | ||
| }; | ||
| var NetworkError = class _NetworkError extends IPTUAPIError { | ||
| originalError; | ||
| constructor(message = "Erro de conexao", originalError) { | ||
| super(message, void 0, void 0); | ||
| constructor(message = "Erro de conex\xE3o com a API", originalError) { | ||
| super(message); | ||
| this.name = "NetworkError"; | ||
@@ -137,139 +110,195 @@ this.originalError = originalError; | ||
| } | ||
| isRetryable() { | ||
| get isRetryable() { | ||
| return true; | ||
| } | ||
| }; | ||
| // src/client.ts | ||
| var DEFAULT_RETRY_CONFIG = { | ||
| maxRetries: 3, | ||
| initialDelay: 1e3, | ||
| maxDelay: 3e4, | ||
| initialDelay: 500, | ||
| maxDelay: 1e4, | ||
| backoffFactor: 2, | ||
| retryableStatusCodes: [429, 500, 502, 503, 504] | ||
| retryableStatuses: [429, 500, 502, 503, 504] | ||
| }; | ||
| var DEFAULT_CONFIG = { | ||
| baseUrl: "https://iptuapi.com.br/api/v1", | ||
| timeout: 3e4, | ||
| retryConfig: DEFAULT_RETRY_CONFIG | ||
| }; | ||
| function toCamelCase(obj) { | ||
| const result = {}; | ||
| for (const [key, value] of Object.entries(obj)) { | ||
| const camelKey = key.replace( | ||
| /_([a-z])/g, | ||
| (_, letter) => letter.toUpperCase() | ||
| ); | ||
| if (value !== null && typeof value === "object" && !Array.isArray(value)) { | ||
| result[camelKey] = toCamelCase(value); | ||
| } else if (Array.isArray(value)) { | ||
| result[camelKey] = value.map( | ||
| (item) => typeof item === "object" && item !== null ? toCamelCase(item) : item | ||
| ); | ||
| } else { | ||
| result[camelKey] = value; | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| function toSnakeCase(obj) { | ||
| const result = {}; | ||
| for (const [key, value] of Object.entries(obj)) { | ||
| const snakeKey = key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`); | ||
| if (value !== null && typeof value === "object" && !Array.isArray(value)) { | ||
| result[snakeKey] = toSnakeCase(value); | ||
| } else if (Array.isArray(value)) { | ||
| result[snakeKey] = value.map( | ||
| (item) => typeof item === "object" && item !== null ? toSnakeCase(item) : item | ||
| ); | ||
| } else { | ||
| result[snakeKey] = value; | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| var IPTUClient = class { | ||
| apiKey; | ||
| config; | ||
| _rateLimitInfo = null; | ||
| _lastRequestId = null; | ||
| /** | ||
| * Cria uma nova instancia do cliente. | ||
| * | ||
| * @param apiKey - Chave de API para autenticacao | ||
| * @param options - Opcoes de configuracao | ||
| */ | ||
| constructor(apiKey, options) { | ||
| baseUrl; | ||
| timeout; | ||
| retryConfig; | ||
| logger; | ||
| logRequests; | ||
| logResponses; | ||
| userAgent; | ||
| _rateLimit; | ||
| _lastRequestId; | ||
| constructor(apiKey, options = {}) { | ||
| if (!apiKey) { | ||
| throw new Error("API Key \xE9 obrigat\xF3ria"); | ||
| } | ||
| this.apiKey = apiKey; | ||
| this.config = { | ||
| baseUrl: options?.baseUrl || DEFAULT_CONFIG.baseUrl, | ||
| timeout: options?.timeout || DEFAULT_CONFIG.timeout, | ||
| retryConfig: { | ||
| ...DEFAULT_RETRY_CONFIG, | ||
| ...options?.retryConfig | ||
| } | ||
| }; | ||
| this.baseUrl = options.baseUrl || "https://iptuapi.com.br/api/v1"; | ||
| this.timeout = options.timeout || 3e4; | ||
| this.retryConfig = { ...DEFAULT_RETRY_CONFIG, ...options.retry }; | ||
| this.logger = options.logger; | ||
| this.logRequests = options.logRequests || false; | ||
| this.logResponses = options.logResponses || false; | ||
| this.userAgent = options.userAgent || "iptuapi-js/2.1.0"; | ||
| } | ||
| /** | ||
| * Retorna informacoes do rate limit da ultima requisicao. | ||
| */ | ||
| get rateLimitInfo() { | ||
| return this._rateLimitInfo; | ||
| // =========================================================================== | ||
| // Properties | ||
| // =========================================================================== | ||
| /** Rate limit info from last request */ | ||
| get rateLimit() { | ||
| return this._rateLimit; | ||
| } | ||
| /** | ||
| * Retorna o ID da ultima requisicao. | ||
| */ | ||
| /** Request ID from last request (useful for support) */ | ||
| get lastRequestId() { | ||
| return this._lastRequestId; | ||
| } | ||
| /** | ||
| * Executa uma requisicao HTTP com retry. | ||
| */ | ||
| async makeRequest(method, endpoint, params, body) { | ||
| const url = new URL(`${this.config.baseUrl}/${endpoint.replace(/^\//, "")}`); | ||
| // =========================================================================== | ||
| // Private Methods | ||
| // =========================================================================== | ||
| log(level, message, ...args) { | ||
| if (this.logger && this.logger[level]) { | ||
| this.logger[level](message, ...args); | ||
| } | ||
| } | ||
| sleep(ms) { | ||
| return new Promise((resolve) => setTimeout(resolve, ms)); | ||
| } | ||
| calculateDelay(attempt) { | ||
| const delay = this.retryConfig.initialDelay * Math.pow(this.retryConfig.backoffFactor, attempt); | ||
| return Math.min(delay, this.retryConfig.maxDelay); | ||
| } | ||
| extractRateLimit(headers) { | ||
| const limit = headers.get("X-RateLimit-Limit"); | ||
| const remaining = headers.get("X-RateLimit-Remaining"); | ||
| const reset = headers.get("X-RateLimit-Reset"); | ||
| if (limit && remaining && reset) { | ||
| const resetTimestamp = parseInt(reset, 10); | ||
| return { | ||
| limit: parseInt(limit, 10), | ||
| remaining: parseInt(remaining, 10), | ||
| reset: resetTimestamp, | ||
| resetDate: new Date(resetTimestamp * 1e3) | ||
| }; | ||
| } | ||
| return void 0; | ||
| } | ||
| async handleErrorResponse(response, requestId) { | ||
| let body = {}; | ||
| try { | ||
| body = await response.json(); | ||
| } catch { | ||
| body = { detail: response.statusText }; | ||
| } | ||
| let message; | ||
| const detail = body.detail; | ||
| if (detail && typeof detail === "object") { | ||
| const detailObj = detail; | ||
| message = detailObj.error || detailObj.detail || detailObj.message || JSON.stringify(detail); | ||
| } else { | ||
| message = detail || `HTTP ${response.status}`; | ||
| } | ||
| switch (response.status) { | ||
| case 400: | ||
| case 422: | ||
| throw new ValidationError( | ||
| message, | ||
| body.errors, | ||
| requestId, | ||
| body | ||
| ); | ||
| case 401: | ||
| throw new AuthenticationError(message, requestId, body); | ||
| case 403: | ||
| throw new ForbiddenError( | ||
| message, | ||
| body.required_plan, | ||
| requestId, | ||
| body | ||
| ); | ||
| case 404: | ||
| throw new NotFoundError(message, requestId, body); | ||
| case 429: | ||
| const retryAfter = response.headers.get("Retry-After"); | ||
| throw new RateLimitError( | ||
| message, | ||
| retryAfter ? parseInt(retryAfter, 10) : void 0, | ||
| this._rateLimit?.limit, | ||
| this._rateLimit?.remaining, | ||
| requestId, | ||
| body | ||
| ); | ||
| case 500: | ||
| case 502: | ||
| case 503: | ||
| case 504: | ||
| throw new ServerError(message, response.status, requestId, body); | ||
| default: | ||
| throw new IPTUAPIError(message, response.status, requestId, body); | ||
| } | ||
| } | ||
| async request(method, endpoint, params, body) { | ||
| const url = new URL(`${this.baseUrl}${endpoint}`); | ||
| if (params) { | ||
| for (const [key, value] of Object.entries(params)) { | ||
| if (value !== void 0 && value !== null) { | ||
| Object.entries(params).forEach(([key, value]) => { | ||
| if (value !== void 0 && value !== null && value !== "") { | ||
| url.searchParams.append(key, String(value)); | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| const { maxRetries, initialDelay, maxDelay, backoffFactor } = this.config.retryConfig; | ||
| let delay = initialDelay; | ||
| for (let attempt = 0; attempt <= maxRetries; attempt++) { | ||
| const headers = { | ||
| "X-API-Key": this.apiKey, | ||
| "Content-Type": "application/json", | ||
| Accept: "application/json", | ||
| "User-Agent": this.userAgent | ||
| }; | ||
| let lastError; | ||
| let attempt = 0; | ||
| while (attempt <= this.retryConfig.maxRetries) { | ||
| const controller = new AbortController(); | ||
| const timeoutId = setTimeout( | ||
| () => controller.abort(), | ||
| this.config.timeout | ||
| ); | ||
| const timeoutId = setTimeout(() => controller.abort(), this.timeout); | ||
| try { | ||
| if (this.logRequests) { | ||
| this.log( | ||
| "debug", | ||
| `Request: ${method} ${url}`, | ||
| params ? { params } : {}, | ||
| body ? { body } : {} | ||
| ); | ||
| } | ||
| const startTime = Date.now(); | ||
| const response = await fetch(url.toString(), { | ||
| method, | ||
| headers: { | ||
| "X-API-Key": this.apiKey, | ||
| "Content-Type": "application/json", | ||
| Accept: "application/json", | ||
| "User-Agent": "iptuapi-js/1.0.0" | ||
| }, | ||
| body: body ? JSON.stringify(toSnakeCase(body)) : void 0, | ||
| headers, | ||
| body: body ? JSON.stringify(body) : void 0, | ||
| signal: controller.signal | ||
| }); | ||
| clearTimeout(timeoutId); | ||
| this.updateRateLimitInfo(response.headers); | ||
| this._lastRequestId = response.headers.get("X-Request-ID"); | ||
| if (!response.ok) { | ||
| await this.handleError(response); | ||
| const elapsedMs = Date.now() - startTime; | ||
| this._rateLimit = this.extractRateLimit(response.headers); | ||
| this._lastRequestId = response.headers.get("X-Request-ID") || void 0; | ||
| if (this.logResponses) { | ||
| this.log( | ||
| "debug", | ||
| `Response: ${response.status} ${url} (${elapsedMs}ms)` | ||
| ); | ||
| } | ||
| const data = await response.json(); | ||
| return toCamelCase(data.data || data); | ||
| if (response.ok) { | ||
| return await response.json(); | ||
| } | ||
| if (this.retryConfig.retryableStatuses.includes(response.status) && attempt < this.retryConfig.maxRetries) { | ||
| const delay = this.calculateDelay(attempt); | ||
| this.log( | ||
| "warn", | ||
| `Request failed with ${response.status}, retrying in ${delay}ms (attempt ${attempt + 1}/${this.retryConfig.maxRetries})` | ||
| ); | ||
| await this.sleep(delay); | ||
| attempt++; | ||
| continue; | ||
| } | ||
| await this.handleErrorResponse(response, this._lastRequestId); | ||
| } catch (error) { | ||
| clearTimeout(timeoutId); | ||
| if (error instanceof IPTUAPIError) { | ||
| if (error.isRetryable() && attempt < maxRetries && this.config.retryConfig.retryableStatusCodes.includes( | ||
| error.statusCode || 0 | ||
| )) { | ||
| await this.sleep(delay); | ||
| delay = Math.min(delay * backoffFactor, maxDelay); | ||
| continue; | ||
| } | ||
| throw error; | ||
@@ -279,140 +308,84 @@ } | ||
| if (error.name === "AbortError") { | ||
| if (attempt < maxRetries) { | ||
| await this.sleep(delay); | ||
| delay = Math.min(delay * backoffFactor, maxDelay); | ||
| continue; | ||
| } | ||
| throw new TimeoutError( | ||
| `Timeout apos ${this.config.timeout}ms`, | ||
| this.config.timeout / 1e3 | ||
| lastError = new TimeoutError( | ||
| `Timeout ap\xF3s ${this.timeout}ms`, | ||
| this.timeout | ||
| ); | ||
| } else if (error.message.includes("fetch") || error.message.includes("network")) { | ||
| lastError = new NetworkError( | ||
| `Erro de conex\xE3o: ${error.message}`, | ||
| error | ||
| ); | ||
| } else { | ||
| lastError = error; | ||
| } | ||
| if (attempt < maxRetries) { | ||
| if (attempt < this.retryConfig.maxRetries) { | ||
| const delay = this.calculateDelay(attempt); | ||
| this.log( | ||
| "warn", | ||
| `Request failed: ${error.message}, retrying in ${delay}ms (attempt ${attempt + 1}/${this.retryConfig.maxRetries})` | ||
| ); | ||
| await this.sleep(delay); | ||
| delay = Math.min(delay * backoffFactor, maxDelay); | ||
| attempt++; | ||
| continue; | ||
| } | ||
| throw new NetworkError(`Erro de conexao: ${error.message}`, error); | ||
| } | ||
| throw new NetworkError("Erro desconhecido"); | ||
| throw lastError || error; | ||
| } | ||
| } | ||
| throw new NetworkError("Maximo de tentativas excedido"); | ||
| throw lastError || new IPTUAPIError("Max retries exceeded"); | ||
| } | ||
| /** | ||
| * Atualiza informacoes de rate limit a partir dos headers. | ||
| */ | ||
| updateRateLimitInfo(headers) { | ||
| const limit = headers.get("X-RateLimit-Limit"); | ||
| const remaining = headers.get("X-RateLimit-Remaining"); | ||
| const reset = headers.get("X-RateLimit-Reset"); | ||
| if (limit && remaining && reset) { | ||
| this._rateLimitInfo = { | ||
| limit: parseInt(limit, 10), | ||
| remaining: parseInt(remaining, 10), | ||
| resetAt: new Date(parseInt(reset, 10) * 1e3) | ||
| async consultaEndereco(paramsOrLogradouro, numero, cidade) { | ||
| let params; | ||
| if (typeof paramsOrLogradouro === "string") { | ||
| params = { | ||
| logradouro: paramsOrLogradouro, | ||
| numero, | ||
| cidade: cidade || "sp" | ||
| }; | ||
| } else { | ||
| params = { | ||
| logradouro: paramsOrLogradouro.logradouro, | ||
| numero: paramsOrLogradouro.numero, | ||
| complemento: paramsOrLogradouro.complemento, | ||
| cidade: paramsOrLogradouro.cidade || "sp", | ||
| incluir_historico: paramsOrLogradouro.incluirHistorico, | ||
| incluir_comparaveis: paramsOrLogradouro.incluirComparaveis, | ||
| incluir_zoneamento: paramsOrLogradouro.incluirZoneamento | ||
| }; | ||
| } | ||
| return this.request( | ||
| "GET", | ||
| "/consulta/endereco", | ||
| params | ||
| ); | ||
| } | ||
| /** | ||
| * Converte resposta HTTP em excecao apropriada. | ||
| */ | ||
| async handleError(response) { | ||
| const requestId = response.headers.get("X-Request-ID") || void 0; | ||
| let data = {}; | ||
| let message = "Erro desconhecido"; | ||
| try { | ||
| data = await response.json(); | ||
| message = data.detail || data.message || message; | ||
| } catch { | ||
| message = response.statusText || message; | ||
| } | ||
| switch (response.status) { | ||
| case 401: | ||
| throw new AuthenticationError(message, requestId); | ||
| case 403: | ||
| throw new ForbiddenError( | ||
| message, | ||
| data.required_plan, | ||
| requestId | ||
| ); | ||
| case 404: | ||
| throw new NotFoundError( | ||
| message, | ||
| data.resource, | ||
| requestId | ||
| ); | ||
| case 429: { | ||
| const retryAfter = parseInt( | ||
| response.headers.get("Retry-After") || "60", | ||
| 10 | ||
| ); | ||
| throw new RateLimitError(message, retryAfter, requestId); | ||
| } | ||
| case 400: | ||
| case 422: | ||
| throw new ValidationError( | ||
| message, | ||
| data.errors, | ||
| response.status, | ||
| requestId | ||
| ); | ||
| default: | ||
| if (response.status >= 500) { | ||
| throw new ServerError(message, response.status, requestId); | ||
| } | ||
| throw new IPTUAPIError(message, response.status, requestId, data); | ||
| } | ||
| } | ||
| /** | ||
| * Aguarda um tempo em milissegundos. | ||
| */ | ||
| sleep(ms) { | ||
| return new Promise((resolve) => setTimeout(resolve, ms)); | ||
| } | ||
| // ==================== CONSULTAS IPTU ==================== | ||
| /** | ||
| * Consulta imoveis por endereco. | ||
| * Busca dados de IPTU por número SQL (contribuinte). | ||
| * | ||
| * @param logradouro - Nome da rua/avenida | ||
| * @param numero - Numero do imovel | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Lista de imoveis encontrados | ||
| * @param sql - Número SQL do imóvel | ||
| * @param cidade - Cidade da consulta | ||
| * @param options - Opções adicionais | ||
| * @returns Dados completos do imóvel | ||
| */ | ||
| async consultaEndereco(logradouro, numero, cidade = "sp") { | ||
| const response = await this.makeRequest("GET", "/consulta/endereco", { | ||
| logradouro, | ||
| numero, | ||
| cidade | ||
| async consultaSQL(sql, cidade = "sp", options) { | ||
| return this.request("GET", `/consulta/sql/${sql}`, { | ||
| cidade, | ||
| incluir_historico: options?.incluirHistorico, | ||
| incluir_comparaveis: options?.incluirComparaveis | ||
| }); | ||
| return Array.isArray(response) ? response : []; | ||
| } | ||
| /** | ||
| * Consulta imovel por numero SQL/Indice Cadastral. | ||
| * Requer plano Starter ou superior. | ||
| * Busca imóveis por CEP. | ||
| * | ||
| * @param sql - Numero SQL (SP), Indice Cadastral (BH) ou Sequencial (Recife) | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Lista de imoveis encontrados | ||
| * @param cep - CEP do imóvel | ||
| * @param cidade - Cidade da consulta | ||
| * @returns Lista de imóveis no CEP | ||
| */ | ||
| async consultaSQL(sql, cidade = "sp") { | ||
| const response = await this.makeRequest("GET", "/consulta/sql", { | ||
| sql, | ||
| cidade | ||
| }); | ||
| return Array.isArray(response) ? response : []; | ||
| } | ||
| /** | ||
| * Consulta imoveis por CEP. | ||
| * | ||
| * @param cep - CEP do endereco | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Lista de imoveis encontrados | ||
| */ | ||
| async consultaCEP(cep, cidade = "sp") { | ||
| const response = await this.makeRequest("GET", "/consulta/cep", { | ||
| cep, | ||
| cidade | ||
| }); | ||
| return Array.isArray(response) ? response : []; | ||
| const cleanCep = cep.replace(/\D/g, ""); | ||
| return this.request( | ||
| "GET", | ||
| `/consulta/cep/${cleanCep}`, | ||
| { cidade } | ||
| ); | ||
| } | ||
@@ -424,192 +397,190 @@ /** | ||
| * @param longitude - Longitude do ponto | ||
| * @returns Informacoes de zoneamento | ||
| * @returns Dados de zoneamento | ||
| */ | ||
| async consultaZoneamento(latitude, longitude) { | ||
| return this.makeRequest("GET", "/consulta/zoneamento", { | ||
| lat: latitude, | ||
| lng: longitude | ||
| return this.request("GET", "/consulta/zoneamento", { | ||
| latitude, | ||
| longitude | ||
| }); | ||
| } | ||
| // ==================== VALUATION ==================== | ||
| // =========================================================================== | ||
| // Valuation Endpoints (Pro+) | ||
| // =========================================================================== | ||
| /** | ||
| * Calcula estimativa de valor de mercado. | ||
| * Requer plano Pro ou superior. | ||
| * Estima o valor de mercado do imóvel usando ML. | ||
| * Disponível apenas para planos Pro e Enterprise. | ||
| * | ||
| * @param params - Parametros da avaliacao | ||
| * @returns Avaliacao de mercado | ||
| * @param params - Parâmetros do imóvel | ||
| * @returns Estimativa de valor | ||
| * @throws {ForbiddenError} Se o plano não permitir | ||
| */ | ||
| async valuationEstimate(params) { | ||
| return this.makeRequest("GET", "/valuation/estimate", { | ||
| area_terreno: params.areaTerreno, | ||
| area_construida: params.areaConstruida, | ||
| bairro: params.bairro, | ||
| cidade: params.cidade || "sp", | ||
| zona: params.zona, | ||
| tipo_uso: params.tipoUso, | ||
| tipo_padrao: params.tipoPadrao, | ||
| ano_construcao: params.anoConstrucao | ||
| }); | ||
| } | ||
| /** | ||
| * Busca imoveis comparaveis. | ||
| * Requer plano Pro ou superior. | ||
| * | ||
| * @param params - Parametros da busca | ||
| * @returns Lista de imoveis comparaveis | ||
| */ | ||
| async valuationComparables(params) { | ||
| const response = await this.makeRequest( | ||
| "GET", | ||
| "/valuation/comparables", | ||
| return this.request( | ||
| "POST", | ||
| "/valuation/estimate", | ||
| void 0, | ||
| { | ||
| area_terreno: params.area_terreno, | ||
| area_construida: params.area_construida, | ||
| bairro: params.bairro, | ||
| area_min: params.areaMin, | ||
| area_max: params.areaMax, | ||
| cidade: params.cidade || "sp", | ||
| limit: params.limit || 10 | ||
| zona: params.zona, | ||
| tipo_uso: params.tipo_uso, | ||
| tipo_padrao: params.tipo_padrao, | ||
| ano_construcao: params.ano_construcao, | ||
| cidade: params.cidade || "sp" | ||
| } | ||
| ); | ||
| return Array.isArray(response) ? response : []; | ||
| } | ||
| /** | ||
| * Avalia imovel por endereco OU SQL. | ||
| * Combina dados do modelo AVM (ML) com transacoes ITBI reais. | ||
| * Requer plano Pro ou superior. | ||
| * Valuation em lote (até 100 imóveis). | ||
| * Disponível apenas para plano Enterprise. | ||
| * | ||
| * @param params - Parametros da avaliacao (sql OU logradouro+numero) | ||
| * @returns Avaliacao completa do imovel | ||
| * @param imoveis - Lista de imóveis para avaliar | ||
| * @returns Resultados de valuation para cada imóvel | ||
| */ | ||
| async valuationEvaluate(params) { | ||
| const body = { | ||
| cidade: params.cidade || "sp", | ||
| incluirItbi: params.incluirItbi ?? true, | ||
| incluirComparaveis: params.incluirComparaveis ?? true | ||
| }; | ||
| if (params.sql) { | ||
| body.sql = params.sql; | ||
| } else { | ||
| if (params.logradouro) body.logradouro = params.logradouro; | ||
| if (params.numero !== void 0) body.numero = params.numero; | ||
| if (params.complemento) body.complemento = params.complemento; | ||
| if (params.bairro) body.bairro = params.bairro; | ||
| } | ||
| return this.makeRequest( | ||
| async valuationBatch(imoveis) { | ||
| return this.request( | ||
| "POST", | ||
| "/valuation/evaluate", | ||
| "/valuation/estimate/batch", | ||
| void 0, | ||
| body | ||
| { imoveis } | ||
| ); | ||
| } | ||
| // ==================== ITBI ==================== | ||
| /** | ||
| * Consulta status de transacao ITBI. | ||
| * Busca imóveis comparáveis para análise. | ||
| * | ||
| * @param protocolo - Numero do protocolo ITBI | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Status da transacao | ||
| * @param bairro - Nome do bairro | ||
| * @param areaMin - Área mínima em m² | ||
| * @param areaMax - Área máxima em m² | ||
| * @param options - Opções adicionais | ||
| * @returns Lista de imóveis comparáveis | ||
| */ | ||
| async itbiStatus(protocolo, cidade = "sp") { | ||
| return this.makeRequest("GET", "/itbi/status", { | ||
| protocolo, | ||
| cidade | ||
| async valuationComparables(bairro, areaMin, areaMax, options) { | ||
| return this.request("GET", "/valuation/comparables", { | ||
| bairro, | ||
| area_min: areaMin, | ||
| area_max: areaMax, | ||
| tipo_uso: options?.tipoUso, | ||
| cidade: options?.cidade || "sp", | ||
| limit: options?.limit || 10 | ||
| }); | ||
| } | ||
| // =========================================================================== | ||
| // Dados Endpoints | ||
| // =========================================================================== | ||
| /** | ||
| * Calcula valor do ITBI. | ||
| * Histórico de valores IPTU de um imóvel. | ||
| * | ||
| * @param params - Parametros do calculo | ||
| * @returns Calculo do ITBI | ||
| * @param sql - Número SQL do imóvel | ||
| * @param cidade - Cidade da consulta | ||
| * @returns Lista com histórico anual | ||
| */ | ||
| async itbiCalcular(params) { | ||
| return this.makeRequest("POST", "/itbi/calcular", void 0, { | ||
| sql: params.sql, | ||
| valorTransacao: params.valorTransacao, | ||
| cidade: params.cidade || "sp" | ||
| }); | ||
| async dadosIPTUHistorico(sql, cidade = "sp") { | ||
| return this.request( | ||
| "GET", | ||
| `/dados/iptu/historico/${sql}`, | ||
| { cidade } | ||
| ); | ||
| } | ||
| /** | ||
| * Consulta historico de transacoes ITBI de um imovel. | ||
| * Requer plano Starter ou superior. | ||
| * Consulta dados de empresa por CNPJ. | ||
| * | ||
| * @param sql - Numero SQL do imovel | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Lista de transacoes historicas | ||
| * @param cnpj - CNPJ da empresa | ||
| * @returns Dados cadastrais | ||
| */ | ||
| async itbiHistorico(sql, cidade = "sp") { | ||
| const response = await this.makeRequest( | ||
| async dadosCNPJ(cnpj) { | ||
| const cleanCnpj = cnpj.replace(/\D/g, ""); | ||
| return this.request( | ||
| "GET", | ||
| "/itbi/historico", | ||
| { sql, cidade } | ||
| `/dados/cnpj/${cleanCnpj}` | ||
| ); | ||
| return Array.isArray(response) ? response : []; | ||
| } | ||
| /** | ||
| * Consulta aliquotas ITBI vigentes. | ||
| * Correção monetária pelo IPCA. | ||
| * | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Aliquotas vigentes | ||
| * @param valor - Valor a corrigir | ||
| * @param dataOrigem - Data do valor original (YYYY-MM) | ||
| * @param dataDestino - Data destino (default: atual) | ||
| * @returns Valor corrigido e fator de correção | ||
| */ | ||
| async itbiAliquotas(cidade = "sp") { | ||
| return this.makeRequest("GET", "/itbi/aliquotas", { cidade }); | ||
| async dadosIPCACorrigir(valor, dataOrigem, dataDestino) { | ||
| return this.request( | ||
| "GET", | ||
| "/dados/ipca/corrigir", | ||
| { | ||
| valor, | ||
| data_origem: dataOrigem, | ||
| data_destino: dataDestino | ||
| } | ||
| ); | ||
| } | ||
| // =========================================================================== | ||
| // IPTU Tools Endpoints (Ferramentas IPTU 2026) | ||
| // =========================================================================== | ||
| /** | ||
| * Consulta isencoes ITBI disponiveis. | ||
| * Lista todas as cidades com calendario de IPTU disponivel. | ||
| * | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Lista de isencoes disponiveis | ||
| * @returns Lista de cidades com codigo, nome, desconto e parcelas | ||
| */ | ||
| async itbiIsencoes(cidade = "sp") { | ||
| const response = await this.makeRequest( | ||
| "GET", | ||
| "/itbi/isencoes", | ||
| { cidade } | ||
| ); | ||
| return Array.isArray(response) ? response : []; | ||
| async iptuToolsCidades() { | ||
| return this.request("GET", "/iptu-tools/cidades"); | ||
| } | ||
| /** | ||
| * Gera guia de pagamento ITBI. | ||
| * Requer plano Starter ou superior. | ||
| * Retorna o calendario completo de IPTU para a cidade especificada. | ||
| * | ||
| * @param params - Parametros da guia | ||
| * @returns Guia de pagamento gerada | ||
| * @param cidade - Codigo da cidade (sp, bh, rj, recife, curitiba, poa, fortaleza) | ||
| * @returns Calendario com vencimentos, descontos, alertas e novidades | ||
| */ | ||
| async itbiGuia(params) { | ||
| return this.makeRequest("POST", "/itbi/guia", void 0, { | ||
| sql: params.sql, | ||
| valorTransacao: params.valorTransacao, | ||
| comprador: params.comprador, | ||
| vendedor: params.vendedor, | ||
| cidade: params.cidade || "sp" | ||
| }); | ||
| async iptuToolsCalendario(cidade = "sp") { | ||
| return this.request("GET", "/iptu-tools/calendario", { cidade }); | ||
| } | ||
| /** | ||
| * Valida autenticidade de uma guia ITBI. | ||
| * Simula as opcoes de pagamento do IPTU (a vista vs parcelado). | ||
| * | ||
| * @param protocolo - Numero do protocolo da guia | ||
| * @param cidade - Codigo da cidade (sp, bh, recife) | ||
| * @returns Resultado da validacao | ||
| * @param valorIptu - Valor total do IPTU | ||
| * @param cidade - Codigo da cidade | ||
| * @param valorVenal - Valor venal do imovel (para verificar isencao) | ||
| * @returns Comparativo entre pagamento a vista e parcelado com recomendacao | ||
| */ | ||
| async itbiValidarGuia(protocolo, cidade = "sp") { | ||
| return this.makeRequest("GET", "/itbi/validar", { | ||
| protocolo, | ||
| async iptuToolsSimulador(valorIptu, cidade = "sp", valorVenal) { | ||
| const body = { | ||
| valor_iptu: valorIptu, | ||
| cidade | ||
| }; | ||
| if (valorVenal !== void 0) { | ||
| body.valor_venal = valorVenal; | ||
| } | ||
| return this.request("POST", "/iptu-tools/simulador", void 0, body); | ||
| } | ||
| /** | ||
| * Verifica se um imovel e elegivel para isencao de IPTU. | ||
| * | ||
| * @param valorVenal - Valor venal do imovel | ||
| * @param cidade - Codigo da cidade | ||
| * @returns Elegibilidade para isencao total ou parcial | ||
| */ | ||
| async iptuToolsIsencao(valorVenal, cidade = "sp") { | ||
| return this.request("GET", "/iptu-tools/isencao", { | ||
| valor_venal: valorVenal, | ||
| cidade | ||
| }); | ||
| } | ||
| /** | ||
| * Simula calculo de ITBI. | ||
| * Retorna informacoes sobre o proximo vencimento do IPTU. | ||
| * | ||
| * @param params - Parametros da simulacao | ||
| * @returns Resultado da simulacao | ||
| * @param cidade - Codigo da cidade | ||
| * @param parcela - Numero da parcela (1-12) | ||
| * @returns Data de vencimento, dias restantes e status | ||
| */ | ||
| async itbiSimular(params) { | ||
| return this.makeRequest("POST", "/itbi/simular", void 0, { | ||
| valorTransacao: params.valorTransacao, | ||
| cidade: params.cidade || "sp", | ||
| tipoFinanciamento: params.tipoFinanciamento, | ||
| valorFinanciado: params.valorFinanciado | ||
| async iptuToolsProximoVencimento(cidade = "sp", parcela = 1) { | ||
| return this.request("GET", "/iptu-tools/proximo-vencimento", { | ||
| cidade, | ||
| parcela | ||
| }); | ||
| } | ||
| }; | ||
| var index_default = IPTUClient; | ||
| export { | ||
| AuthenticationError, | ||
| CidadeEnum, | ||
| ForbiddenError, | ||
@@ -623,3 +594,4 @@ IPTUAPIError, | ||
| TimeoutError, | ||
| ValidationError | ||
| ValidationError, | ||
| index_default as default | ||
| }; |
+27
-29
| { | ||
| "name": "iptuapi", | ||
| "version": "2.1.0", | ||
| "description": "SDK oficial para a IPTU API - Dados de IPTU e ITBI de Sao Paulo, Belo Horizonte e Recife", | ||
| "version": "2.1.1", | ||
| "description": "SDK oficial para a IPTU API - Dados de IPTU de São Paulo, Belo Horizonte e Recife", | ||
| "main": "dist/index.js", | ||
@@ -10,19 +10,17 @@ "module": "dist/index.mjs", | ||
| ".": { | ||
| "require": "./dist/index.js", | ||
| "types": "./dist/index.d.ts", | ||
| "import": "./dist/index.mjs", | ||
| "types": "./dist/index.d.ts" | ||
| "require": "./dist/index.js" | ||
| } | ||
| }, | ||
| "files": [ | ||
| "dist", | ||
| "README.md", | ||
| "LICENSE" | ||
| "dist" | ||
| ], | ||
| "scripts": { | ||
| "build": "tsup src/index.ts --format cjs,esm --dts --clean", | ||
| "build": "tsup src/index.ts --format cjs,esm --dts", | ||
| "test": "vitest run", | ||
| "test:watch": "vitest", | ||
| "test:coverage": "vitest run --coverage", | ||
| "lint": "eslint src --ext .ts", | ||
| "typecheck": "tsc --noEmit", | ||
| "lint": "eslint src tests", | ||
| "prepublishOnly": "npm run build" | ||
@@ -32,34 +30,34 @@ }, | ||
| "iptu", | ||
| "itbi", | ||
| "api", | ||
| "imoveis", | ||
| "real-estate", | ||
| "brazil", | ||
| "sao-paulo", | ||
| "belo-horizonte", | ||
| "recife" | ||
| "são paulo", | ||
| "belo horizonte", | ||
| "recife", | ||
| "imóveis", | ||
| "dados", | ||
| "real estate", | ||
| "property", | ||
| "typescript", | ||
| "sdk" | ||
| ], | ||
| "author": "IPTU API <suporte@iptuapi.com.br>", | ||
| "license": "SEE LICENSE IN LICENSE", | ||
| "author": "IPTU API <contato@iptuapi.com.br>", | ||
| "license": "UNLICENSED", | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "git+https://github.com/raphaeltorquat0/iptuapi-js.git" | ||
| "url": "https://github.com/iptuapi/iptuapi-js" | ||
| }, | ||
| "homepage": "https://iptuapi.com.br", | ||
| "bugs": { | ||
| "url": "https://github.com/raphaeltorquat0/iptuapi-js/issues" | ||
| "url": "https://github.com/iptuapi/iptuapi-js/issues" | ||
| }, | ||
| "homepage": "https://iptuapi.com.br", | ||
| "engines": { | ||
| "node": ">=18.0.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@types/node": "^20.10.0", | ||
| "eslint": "^8.55.0", | ||
| "@typescript-eslint/eslint-plugin": "^6.13.0", | ||
| "@typescript-eslint/parser": "^6.13.0", | ||
| "@vitest/coverage-v8": "^4.0.16", | ||
| "msw": "^2.0.0", | ||
| "tsup": "^8.0.0", | ||
| "typescript": "^5.3.0", | ||
| "vitest": "^1.0.0", | ||
| "@vitest/coverage-v8": "^1.0.0" | ||
| "vitest": "^4.0.16" | ||
| }, | ||
| "engines": { | ||
| "node": ">=18" | ||
| } | ||
| } |
+125
-497
| # IPTU API - JavaScript/TypeScript SDK | ||
| SDK oficial para integracao com a IPTU API. Acesso a dados de IPTU e ITBI de Sao Paulo, Belo Horizonte e Recife. | ||
| SDK oficial JavaScript/TypeScript para integracao com a IPTU API. Acesso a dados de IPTU de Sao Paulo, Belo Horizonte e Recife. | ||
| [](https://www.npmjs.com/package/iptuapi) | ||
| [](https://www.typescriptlang.org/) | ||
| [](https://www.npmjs.com/package/iptuapi) | ||
| [](https://www.typescriptlang.org/) | ||
| [](LICENSE) | ||
@@ -13,21 +13,8 @@ | ||
| npm install iptuapi | ||
| ``` | ||
| ou com yarn: | ||
| ```bash | ||
| # ou | ||
| yarn add iptuapi | ||
| ``` | ||
| ou com pnpm: | ||
| ```bash | ||
| # ou | ||
| pnpm add iptuapi | ||
| ``` | ||
| ## Requisitos | ||
| - Node.js 18+ | ||
| - TypeScript 5.0+ (opcional, para tipagem) | ||
| ## Uso Rapido | ||
@@ -41,20 +28,9 @@ | ||
| // Consulta por endereco | ||
| const imoveis = await client.consultaEndereco('Avenida Paulista', '1000', 'sp'); | ||
| for (const imovel of imoveis) { | ||
| console.log(`SQL: ${imovel.sql}`); | ||
| console.log(`Valor Venal: R$ ${imovel.valorVenal?.toLocaleString('pt-BR')}`); | ||
| } | ||
| const resultado = await client.consultaEndereco('Avenida Paulista', '1000'); | ||
| console.log(resultado); | ||
| // Consulta por SQL (Starter+) | ||
| const dados = await client.consultaSQL('008.045.0123-4', 'sp'); | ||
| const dados = await client.consultaSQL('100-01-001-001'); | ||
| ``` | ||
| ### CommonJS | ||
| ```javascript | ||
| const { IPTUClient } = require('iptuapi'); | ||
| const client = new IPTUClient('sua_api_key'); | ||
| ``` | ||
| ## Configuracao | ||
@@ -73,153 +49,84 @@ | ||
| ```typescript | ||
| import { IPTUClient } from 'iptuapi'; | ||
| import { IPTUClient, ClientConfig, RetryConfig } from 'iptuapi'; | ||
| const client = new IPTUClient('sua_api_key', { | ||
| const retryConfig: RetryConfig = { | ||
| maxRetries: 5, | ||
| initialDelayMs: 1000, | ||
| maxDelayMs: 30000, | ||
| backoffFactor: 2.0, | ||
| retryableStatuses: [429, 500, 502, 503, 504] | ||
| }; | ||
| const config: ClientConfig = { | ||
| baseUrl: 'https://iptuapi.com.br/api/v1', | ||
| timeout: 60000, // 60 segundos | ||
| retryConfig: { | ||
| maxRetries: 5, | ||
| initialDelay: 1000, // ms | ||
| maxDelay: 30000, // ms | ||
| backoffFactor: 2.0, | ||
| retryableStatusCodes: [429, 500, 502, 503, 504], | ||
| }, | ||
| }); | ||
| timeout: 60000, | ||
| retryConfig, | ||
| logger: console // ou seu logger customizado | ||
| }; | ||
| const client = new IPTUClient('sua_api_key', config); | ||
| ``` | ||
| --- | ||
| ### Logging Customizado | ||
| ## Endpoints de Consulta IPTU | ||
| ### Consulta por Endereco | ||
| Busca dados de IPTU por logradouro e numero. Disponivel em **todos os planos**. | ||
| ```typescript | ||
| const imoveis = await client.consultaEndereco('Avenida Paulista', '1000', 'sp'); | ||
| import { IPTUClient, Logger } from 'iptuapi'; | ||
| for (const imovel of imoveis) { | ||
| console.log(`SQL: ${imovel.sql}`); | ||
| console.log(`Bairro: ${imovel.bairro}`); | ||
| console.log(`Area Terreno: ${imovel.areaTerreno} m2`); | ||
| console.log(`Area Construida: ${imovel.areaConstruida} m2`); | ||
| console.log(`Valor Venal: R$ ${imovel.valorVenal?.toLocaleString('pt-BR')}`); | ||
| } | ||
| ``` | ||
| const customLogger: Logger = { | ||
| debug: (msg, meta) => console.debug(`[IPTU] ${msg}`, meta), | ||
| info: (msg, meta) => console.info(`[IPTU] ${msg}`, meta), | ||
| warn: (msg, meta) => console.warn(`[IPTU] ${msg}`, meta), | ||
| error: (msg, meta) => console.error(`[IPTU] ${msg}`, meta) | ||
| }; | ||
| **Parametros:** | ||
| | Parametro | Tipo | Obrigatorio | Descricao | | ||
| |-----------|------|-------------|-----------| | ||
| | logradouro | string | Sim | Nome da rua/avenida | | ||
| | numero | string | Sim | Numero do imovel | | ||
| | cidade | Cidade | Nao | Codigo da cidade (sp, bh, recife). Default: sp | | ||
| **Tipo Imovel:** | ||
| ```typescript | ||
| interface Imovel { | ||
| sql: string; | ||
| logradouro: string; | ||
| numero: string; | ||
| bairro: string; | ||
| cep?: string; | ||
| areaTerreno?: number; | ||
| areaConstruida?: number; | ||
| valorVenal?: number; | ||
| valorVenalTerreno?: number; | ||
| valorVenalConstrucao?: number; | ||
| anoConstrucao?: number; | ||
| uso?: string; | ||
| padrao?: string; | ||
| } | ||
| const client = new IPTUClient('sua_api_key', { logger: customLogger }); | ||
| ``` | ||
| --- | ||
| ## Endpoints da API | ||
| ### Consulta por SQL/Indice Cadastral | ||
| ### Consultas (Todos os Planos) | ||
| Busca por identificador unico do imovel. Disponivel a partir do plano **Starter**. | ||
| ```typescript | ||
| // Sao Paulo - numero SQL | ||
| const imoveis = await client.consultaSQL('008.045.0123-4', 'sp'); | ||
| // Consulta por endereco | ||
| const resultado = await client.consultaEndereco('Avenida Paulista', '1000', 'sp'); | ||
| // Belo Horizonte - indice cadastral | ||
| const imoveisBH = await client.consultaSQL('007028 005 0086', 'bh'); | ||
| // Consulta por CEP | ||
| const resultado = await client.consultaCEP('01310-100', 'sp'); | ||
| // Recife - sequencial | ||
| const imoveisRecife = await client.consultaSQL('123456', 'recife'); | ||
| // Consulta por coordenadas (zoneamento) | ||
| const resultado = await client.consultaZoneamento(-23.5505, -46.6333); | ||
| ``` | ||
| --- | ||
| ### Consultas Avancadas (Starter+) | ||
| ### Consulta por CEP | ||
| Busca todos os imoveis de um CEP. Disponivel em **todos os planos**. | ||
| ```typescript | ||
| const imoveis = await client.consultaCEP('01310-100', 'sp'); | ||
| console.log(`Encontrados: ${imoveis.length} imoveis`); | ||
| ``` | ||
| // Consulta por numero SQL | ||
| const resultado = await client.consultaSQL('100-01-001-001', 'sp'); | ||
| --- | ||
| // Historico de valores IPTU | ||
| const historico = await client.dadosIPTUHistorico('100-01-001-001', 'sp'); | ||
| ### Consulta Zoneamento | ||
| // Consulta CNPJ | ||
| const empresa = await client.dadosCNPJ('12345678000100'); | ||
| Retorna informacoes de zoneamento por coordenadas. Disponivel em **todos os planos**. | ||
| ```typescript | ||
| const zoneamento = await client.consultaZoneamento(-23.5505, -46.6333); | ||
| console.log(`Zona: ${zoneamento.zona}`); | ||
| console.log(`Uso Permitido: ${zoneamento.usoPermitido}`); | ||
| console.log(`Coeficiente: ${zoneamento.coeficienteAproveitamento}`); | ||
| // Correcao monetaria IPCA | ||
| const corrigido = await client.dadosIPCACorrigir(100000, '2020-01', '2024-01'); | ||
| ``` | ||
| --- | ||
| ### Valuation (Pro+) | ||
| ## Endpoints de Valuation | ||
| ### Estimativa de Valor de Mercado | ||
| Calcula valor estimado de mercado. Disponivel a partir do plano **Pro**. | ||
| ```typescript | ||
| // Estimativa de valor de mercado | ||
| const avaliacao = await client.valuationEstimate({ | ||
| areaTerreno: 250, | ||
| areaConstruida: 180, | ||
| area_terreno: 250, | ||
| area_construida: 180, | ||
| bairro: 'Pinheiros', | ||
| cidade: 'sp', | ||
| zona: 'ZM', | ||
| tipoUso: 'Residencial', | ||
| tipoPadrao: 'Medio', | ||
| anoConstrucao: 2010, | ||
| tipo_uso: 'Residencial', | ||
| tipo_padrao: 'Medio', | ||
| ano_construcao: 2010 | ||
| }); | ||
| console.log(`Valor estimado: R$ ${avaliacao.valor_estimado.toLocaleString()}`); | ||
| console.log(`Valor Estimado: R$ ${avaliacao.valorEstimado.toLocaleString('pt-BR')}`); | ||
| console.log(`Confianca: ${(avaliacao.confianca * 100).toFixed(1)}%`); | ||
| console.log(`Faixa: R$ ${avaliacao.valorMinimo.toLocaleString('pt-BR')} - R$ ${avaliacao.valorMaximo.toLocaleString('pt-BR')}`); | ||
| ``` | ||
| **Tipo Valuation:** | ||
| ```typescript | ||
| interface Valuation { | ||
| valorEstimado: number; | ||
| valorMinimo: number; | ||
| valorMaximo: number; | ||
| confianca: number; | ||
| valorM2: number; | ||
| metodologia: string; | ||
| dataReferencia: string; | ||
| } | ||
| ``` | ||
| --- | ||
| ### Buscar Comparaveis | ||
| Retorna imoveis similares para comparacao. Disponivel a partir do plano **Pro**. | ||
| ```typescript | ||
| // Buscar comparaveis | ||
| const comparaveis = await client.valuationComparables({ | ||
@@ -230,192 +137,17 @@ bairro: 'Pinheiros', | ||
| cidade: 'sp', | ||
| limit: 10, | ||
| limit: 10 | ||
| }); | ||
| for (const comp of comparaveis) { | ||
| console.log(`SQL: ${comp.sql}`); | ||
| console.log(`Area: ${comp.areaConstruida} m2`); | ||
| console.log(`Valor: R$ ${comp.valorVenal.toLocaleString('pt-BR')}`); | ||
| } | ||
| ``` | ||
| --- | ||
| ### Batch Operations (Enterprise) | ||
| ## Endpoints de ITBI | ||
| ### Status da Transacao ITBI | ||
| Consulta status de uma transacao ITBI. Disponivel em **todos os planos**. | ||
| ```typescript | ||
| const status = await client.itbiStatus('ITBI-2024-123456', 'sp'); | ||
| console.log(`Protocolo: ${status.protocolo}`); | ||
| console.log(`Status: ${status.status}`); | ||
| console.log(`Valor Transacao: R$ ${status.valorTransacao.toLocaleString('pt-BR')}`); | ||
| console.log(`Valor ITBI: R$ ${status.valorITBI.toLocaleString('pt-BR')}`); | ||
| // Valuation em lote (ate 100 imoveis) | ||
| const imoveis = [ | ||
| { area_terreno: 250, area_construida: 180, bairro: 'Pinheiros' }, | ||
| { area_terreno: 300, area_construida: 200, bairro: 'Moema' } | ||
| ]; | ||
| const resultados = await client.valuationBatch(imoveis); | ||
| ``` | ||
| **Tipo ITBIStatus:** | ||
| ```typescript | ||
| interface ITBIStatus { | ||
| protocolo: string; | ||
| status: string; | ||
| dataSolicitacao: string; | ||
| valorTransacao: number; | ||
| valorVenalReferencia: number; | ||
| baseCalculo: number; | ||
| aliquota: number; | ||
| valorITBI: number; | ||
| dataAprovacao?: string; | ||
| } | ||
| ``` | ||
| --- | ||
| ### Calculo de ITBI | ||
| Calcula valor do ITBI para uma transacao. Disponivel em **todos os planos**. | ||
| ```typescript | ||
| const calculo = await client.itbiCalcular({ | ||
| sql: '008.045.0123-4', | ||
| valorTransacao: 500000, | ||
| cidade: 'sp', | ||
| }); | ||
| console.log(`Base de Calculo: R$ ${calculo.baseCalculo.toLocaleString('pt-BR')}`); | ||
| console.log(`Aliquota: ${(calculo.aliquota * 100).toFixed(1)}%`); | ||
| console.log(`Valor ITBI: R$ ${calculo.valorITBI.toLocaleString('pt-BR')}`); | ||
| ``` | ||
| --- | ||
| ### Historico de Transacoes ITBI | ||
| Retorna historico de transacoes de um imovel. Disponivel a partir do plano **Starter**. | ||
| ```typescript | ||
| const historico = await client.itbiHistorico('008.045.0123-4', 'sp'); | ||
| for (const tx of historico) { | ||
| console.log(`${tx.dataTransacao} - R$ ${tx.valorTransacao.toLocaleString('pt-BR')} (${tx.tipoTransacao})`); | ||
| } | ||
| ``` | ||
| --- | ||
| ### Aliquotas ITBI | ||
| Retorna aliquotas vigentes por cidade. Disponivel em **todos os planos**. | ||
| ```typescript | ||
| const aliquotas = await client.itbiAliquotas('sp'); | ||
| console.log(`Aliquota Padrao: ${(aliquotas.aliquotaPadrao * 100).toFixed(1)}%`); | ||
| console.log(`Aliquota SFH: ${(aliquotas.aliquotaFinanciamentoSFH * 100).toFixed(2)}%`); | ||
| console.log(`Base Legal: ${aliquotas.baseLegal}`); | ||
| ``` | ||
| --- | ||
| ### Isencoes ITBI | ||
| Verifica isencoes aplicaveis. Disponivel em **todos os planos**. | ||
| ```typescript | ||
| const isencoes = await client.itbiIsencoes('sp'); | ||
| for (const isencao of isencoes) { | ||
| console.log(`- ${isencao.tipo}: ${isencao.descricao}`); | ||
| console.log(` Requisitos: ${isencao.requisitos.join(', ')}`); | ||
| } | ||
| ``` | ||
| --- | ||
| ### Guia ITBI | ||
| Gera guia de pagamento do ITBI. Disponivel a partir do plano **Starter**. | ||
| ```typescript | ||
| const guia = await client.itbiGuia({ | ||
| sql: '008.045.0123-4', | ||
| valorTransacao: 500000, | ||
| comprador: { | ||
| nome: 'Joao da Silva', | ||
| documento: '123.456.789-00', | ||
| email: 'joao@email.com', | ||
| }, | ||
| vendedor: { | ||
| nome: 'Maria Santos', | ||
| documento: '987.654.321-00', | ||
| }, | ||
| cidade: 'sp', | ||
| }); | ||
| console.log(`Protocolo: ${guia.protocolo}`); | ||
| console.log(`Codigo de Barras: ${guia.codigoBarras}`); | ||
| console.log(`Vencimento: ${guia.dataVencimento}`); | ||
| console.log(`Valor: R$ ${guia.valorITBI.toLocaleString('pt-BR')}`); | ||
| ``` | ||
| --- | ||
| ### Validar Guia ITBI | ||
| Valida autenticidade de uma guia. Disponivel em **todos os planos**. | ||
| ```typescript | ||
| const validacao = await client.itbiValidarGuia('ITBI-2024-789012', 'sp'); | ||
| if (validacao.valido) { | ||
| console.log('Guia valida!'); | ||
| if (validacao.pago) { | ||
| console.log(`Pago em: ${validacao.dataPagamento}`); | ||
| console.log(`Valor pago: R$ ${validacao.valorPago?.toLocaleString('pt-BR')}`); | ||
| } | ||
| } else { | ||
| console.log('Guia invalida!'); | ||
| } | ||
| ``` | ||
| --- | ||
| ### Simular ITBI | ||
| Simula calculo sem gerar guia. Disponivel em **todos os planos**. | ||
| ```typescript | ||
| const simulacao = await client.itbiSimular({ | ||
| valorTransacao: 500000, | ||
| cidade: 'sp', | ||
| tipoFinanciamento: 'sfh', | ||
| valorFinanciado: 400000, | ||
| }); | ||
| console.log(`Valor ITBI Total: R$ ${simulacao.valorITBITotal.toLocaleString('pt-BR')}`); | ||
| console.log(` - Parte financiada (SFH): R$ ${simulacao.valorITBIFinanciado.toLocaleString('pt-BR')}`); | ||
| console.log(` - Parte nao financiada: R$ ${simulacao.valorITBINaoFinanciado.toLocaleString('pt-BR')}`); | ||
| console.log(`Economia com SFH: R$ ${simulacao.economiaSFH.toLocaleString('pt-BR')}`); | ||
| ``` | ||
| **Tipo ITBISimulacao:** | ||
| ```typescript | ||
| interface ITBISimulacao { | ||
| valorTransacao: number; | ||
| valorFinanciado: number; | ||
| valorNaoFinanciado: number; | ||
| aliquotaSFH: number; | ||
| aliquotaPadrao: number; | ||
| valorITBIFinanciado: number; | ||
| valorITBINaoFinanciado: number; | ||
| valorITBITotal: number; | ||
| economiaSFH: number; | ||
| } | ||
| ``` | ||
| --- | ||
| ## Tratamento de Erros | ||
@@ -434,3 +166,3 @@ | ||
| TimeoutError, | ||
| NetworkError, | ||
| NetworkError | ||
| } from 'iptuapi'; | ||
@@ -441,26 +173,22 @@ | ||
| try { | ||
| const imoveis = await client.consultaEndereco('Rua Teste', '100'); | ||
| const resultado = await client.consultaEndereco('Rua Teste', '100'); | ||
| } catch (error) { | ||
| if (error instanceof AuthenticationError) { | ||
| console.log(`API Key invalida: ${error.message}`); | ||
| console.log('API Key invalida'); | ||
| } else if (error instanceof ForbiddenError) { | ||
| console.log(`Plano nao autorizado. Requer: ${error.requiredPlan}`); | ||
| } else if (error instanceof NotFoundError) { | ||
| console.log(`Imovel nao encontrado: ${error.resource}`); | ||
| console.log('Imovel nao encontrado'); | ||
| } else if (error instanceof RateLimitError) { | ||
| console.log(`Rate limit excedido. Retry em ${error.retryAfter}s`); | ||
| } else if (error instanceof ValidationError) { | ||
| console.log('Parametros invalidos:'); | ||
| for (const [field, messages] of Object.entries(error.errors)) { | ||
| console.log(` ${field}: ${messages.join(', ')}`); | ||
| } | ||
| console.log('Parametros invalidos:', error.errors); | ||
| } else if (error instanceof ServerError) { | ||
| console.log(`Erro no servidor (retryable): ${error.message}`); | ||
| console.log('Erro no servidor (retryable)'); | ||
| } else if (error instanceof TimeoutError) { | ||
| console.log(`Timeout apos ${error.timeoutSeconds}s`); | ||
| console.log(`Timeout apos ${error.timeoutMs}ms`); | ||
| } else if (error instanceof NetworkError) { | ||
| console.log(`Erro de conexao: ${error.message}`); | ||
| console.log('Erro de conexao'); | ||
| } else if (error instanceof IPTUAPIError) { | ||
| console.log(`Erro: ${error.message}`); | ||
| console.log(`Request ID: ${error.requestId}`); | ||
| console.log(`Erro: ${error.message}, Request ID: ${error.requestId}`); | ||
| } | ||
@@ -474,3 +202,3 @@ } | ||
| try { | ||
| const imoveis = await client.consultaEndereco('Rua Teste', '100'); | ||
| const resultado = await client.consultaEndereco('Rua Teste', '100'); | ||
| } catch (error) { | ||
@@ -480,7 +208,3 @@ if (error instanceof IPTUAPIError) { | ||
| console.log(`Request ID: ${error.requestId}`); | ||
| console.log(`Retryable: ${error.isRetryable() ? 'Sim' : 'Nao'}`); | ||
| // Converter para JSON | ||
| const errorData = error.toJSON(); | ||
| console.log(errorData); | ||
| console.log(`Retryable: ${error.isRetryable}`); | ||
| } | ||
@@ -490,35 +214,2 @@ } | ||
| ### Verificar Tipo de Erro | ||
| ```typescript | ||
| try { | ||
| const imoveis = await client.consultaEndereco('Rua Teste', '100'); | ||
| } catch (error) { | ||
| if (error instanceof IPTUAPIError && error.isRetryable()) { | ||
| const waitTime = error instanceof RateLimitError ? error.retryAfter : 5; | ||
| console.log(`Aguardando ${waitTime}s antes de tentar novamente...`); | ||
| await new Promise(resolve => setTimeout(resolve, waitTime * 1000)); | ||
| const imoveis = await client.consultaEndereco('Rua Teste', '100'); | ||
| } | ||
| } | ||
| ``` | ||
| --- | ||
| ## Hierarquia de Excecoes | ||
| ``` | ||
| IPTUAPIError (base) | ||
| ├── AuthenticationError (401) | ||
| ├── ForbiddenError (403) | ||
| ├── NotFoundError (404) | ||
| ├── RateLimitError (429) - retryable | ||
| ├── ValidationError (400, 422) | ||
| ├── ServerError (5xx) - retryable | ||
| ├── TimeoutError (408) - retryable | ||
| └── NetworkError - retryable | ||
| ``` | ||
| --- | ||
| ## Rate Limiting | ||
@@ -528,137 +219,77 @@ | ||
| // Verificar rate limit apos requisicao | ||
| const rateLimitInfo = client.rateLimitInfo; | ||
| if (rateLimitInfo) { | ||
| console.log(`Limite: ${rateLimitInfo.limit}`); | ||
| console.log(`Restantes: ${rateLimitInfo.remaining}`); | ||
| console.log(`Reset em: ${rateLimitInfo.resetAt.toISOString()}`); | ||
| const rateLimit = client.getRateLimitInfo(); | ||
| if (rateLimit) { | ||
| console.log(`Limite: ${rateLimit.limit}`); | ||
| console.log(`Restantes: ${rateLimit.remaining}`); | ||
| console.log(`Reset em: ${new Date(rateLimit.reset * 1000)}`); | ||
| } | ||
| // ID da ultima requisicao (util para suporte) | ||
| console.log(`Request ID: ${client.lastRequestId}`); | ||
| console.log(`Request ID: ${client.getLastRequestId()}`); | ||
| ``` | ||
| ### Limites por Plano | ||
| ## Tipos TypeScript | ||
| | Plano | Requisicoes/mes | Requisicoes/minuto | | ||
| |-------|-----------------|-------------------| | ||
| | Free | 100 | 10 | | ||
| | Starter | 5.000 | 60 | | ||
| | Pro | 50.000 | 300 | | ||
| | Enterprise | Ilimitado | 1.000 | | ||
| --- | ||
| ## Cidades Suportadas | ||
| | Codigo | Cidade | Identificador | Registros | | ||
| |--------|--------|---------------|-----------| | ||
| | sp | Sao Paulo | Numero SQL | 4.5M+ | | ||
| | bh | Belo Horizonte | Indice Cadastral | 800K+ | | ||
| | recife | Recife | Sequencial | 400K+ | | ||
| --- | ||
| ## Exemplo Completo | ||
| ```typescript | ||
| import { IPTUClient, RateLimitError, IPTUAPIError } from 'iptuapi'; | ||
| import type { | ||
| ClientConfig, | ||
| RetryConfig, | ||
| RateLimitInfo, | ||
| PropertyData, | ||
| ValuationParams, | ||
| ValuationResult, | ||
| ComparableProperty, | ||
| ZoningInfo, | ||
| IPTUHistoryItem | ||
| } from 'iptuapi'; | ||
| async function main() { | ||
| const client = new IPTUClient(process.env.IPTU_API_KEY!, { | ||
| timeout: 30000, | ||
| retryConfig: { | ||
| maxRetries: 3, | ||
| }, | ||
| }); | ||
| // Exemplo de uso com tipos | ||
| const config: ClientConfig = { | ||
| timeout: 30000 | ||
| }; | ||
| // Lista de enderecos para consultar | ||
| const enderecos = [ | ||
| { logradouro: 'Avenida Paulista', numero: '1000' }, | ||
| { logradouro: 'Rua Augusta', numero: '500' }, | ||
| { logradouro: 'Avenida Faria Lima', numero: '3000' }, | ||
| ]; | ||
| const params: ValuationParams = { | ||
| area_terreno: 250, | ||
| area_construida: 180, | ||
| bairro: 'Pinheiros' | ||
| }; | ||
| for (const endereco of enderecos) { | ||
| try { | ||
| const imoveis = await client.consultaEndereco( | ||
| endereco.logradouro, | ||
| endereco.numero, | ||
| 'sp' | ||
| ); | ||
| const resultado: ValuationResult = await client.valuationEstimate(params); | ||
| ``` | ||
| for (const imovel of imoveis) { | ||
| console.log(`SQL: ${imovel.sql}, Valor Venal: R$ ${imovel.valorVenal?.toLocaleString('pt-BR')}`); | ||
| } | ||
| ## Browser Support | ||
| // Verificar rate limit | ||
| const rateLimitInfo = client.rateLimitInfo; | ||
| if (rateLimitInfo && rateLimitInfo.remaining < 10) { | ||
| console.log(`Atencao: Apenas ${rateLimitInfo.remaining} requisicoes restantes`); | ||
| } | ||
| } catch (error) { | ||
| if (error instanceof RateLimitError) { | ||
| console.log(`Rate limit atingido. Aguardando ${error.retryAfter}s...`); | ||
| await new Promise(resolve => setTimeout(resolve, error.retryAfter * 1000)); | ||
| } else if (error instanceof IPTUAPIError) { | ||
| console.log(`Erro ao consultar ${endereco.logradouro}: ${error.message}`); | ||
| } | ||
| } | ||
| } | ||
| O SDK funciona tanto em Node.js quanto em browsers modernos: | ||
| // Exemplo ITBI | ||
| console.log('\n--- Simulacao ITBI ---'); | ||
| try { | ||
| const simulacao = await client.itbiSimular({ | ||
| valorTransacao: 800000, | ||
| cidade: 'sp', | ||
| tipoFinanciamento: 'sfh', | ||
| valorFinanciado: 600000, | ||
| }); | ||
| console.log(`Valor ITBI: R$ ${simulacao.valorITBITotal.toLocaleString('pt-BR')}`); | ||
| console.log(`Economia com SFH: R$ ${simulacao.economiaSFH.toLocaleString('pt-BR')}`); | ||
| } catch (error) { | ||
| if (error instanceof IPTUAPIError) { | ||
| console.log(`Erro na simulacao ITBI: ${error.message}`); | ||
| } | ||
| } | ||
| } | ||
| ```html | ||
| <script type="module"> | ||
| import { IPTUClient } from 'https://unpkg.com/iptuapi@latest/dist/browser.js'; | ||
| main(); | ||
| const client = new IPTUClient('sua_api_key'); | ||
| const resultado = await client.consultaEndereco('Avenida Paulista', '1000'); | ||
| console.log(resultado); | ||
| </script> | ||
| ``` | ||
| --- | ||
| ## Testes | ||
| ```bash | ||
| # Instalar dependencias | ||
| npm install | ||
| # Rodar testes | ||
| npm test | ||
| # Com coverage | ||
| npm run test:coverage | ||
| # Watch mode | ||
| npm run test:watch | ||
| # Coverage | ||
| npm run test:coverage | ||
| ``` | ||
| --- | ||
| ## Cidades Suportadas | ||
| ## Build | ||
| | Codigo | Cidade | | ||
| |--------|--------| | ||
| | sp | Sao Paulo | | ||
| | bh | Belo Horizonte | | ||
| | recife | Recife | | ||
| ```bash | ||
| # Compilar TypeScript | ||
| npm run build | ||
| # Type check | ||
| npm run typecheck | ||
| # Lint | ||
| npm run lint | ||
| ``` | ||
| --- | ||
| ## Licenca | ||
@@ -670,4 +301,2 @@ | ||
| --- | ||
| ## Links | ||
@@ -678,2 +307,1 @@ | ||
| - [Portal do Desenvolvedor](https://iptuapi.com.br/dashboard) | ||
| - [Suporte](mailto:suporte@iptuapi.com.br) |
Explicitly Unlicensed Item
LicenseSomething was found which is explicitly marked as unlicensed.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Misc. License Issues
LicenseA package's licensing information has fine-grained problems.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
Unidentified License
LicenseSomething that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
6
-25%7
16.67%77782
-7.84%1
Infinity%1
Infinity%1
Infinity%0
-100%1653
-7.24%1
Infinity%296
-55.69%