iptuapi 2.1.0 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +398 -435
- package/dist/index.d.ts +398 -435
- package/dist/index.js +487 -431
- package/dist/index.mjs +487 -430
- package/package.json +27 -29
package/dist/index.js
CHANGED
|
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
AuthenticationError: () => AuthenticationError,
|
|
24
|
+
CidadeEnum: () => CidadeEnum,
|
|
24
25
|
ForbiddenError: () => ForbiddenError,
|
|
25
26
|
IPTUAPIError: () => IPTUAPIError,
|
|
26
27
|
IPTUClient: () => IPTUClient,
|
|
@@ -29,618 +30,673 @@ __export(index_exports, {
|
|
|
29
30
|
RateLimitError: () => RateLimitError,
|
|
30
31
|
ServerError: () => ServerError,
|
|
31
32
|
TimeoutError: () => TimeoutError,
|
|
32
|
-
ValidationError: () => ValidationError
|
|
33
|
+
ValidationError: () => ValidationError,
|
|
34
|
+
default: () => index_default
|
|
33
35
|
});
|
|
34
36
|
module.exports = __toCommonJS(index_exports);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
var CidadeEnum = {
|
|
38
|
+
SAO_PAULO: "sp",
|
|
39
|
+
BELO_HORIZONTE: "bh",
|
|
40
|
+
RECIFE: "recife",
|
|
41
|
+
PORTO_ALEGRE: "poa",
|
|
42
|
+
FORTALEZA: "fortaleza",
|
|
43
|
+
CURITIBA: "curitiba",
|
|
44
|
+
RIO_DE_JANEIRO: "rj",
|
|
45
|
+
BRASILIA: "brasilia"
|
|
46
|
+
};
|
|
37
47
|
var IPTUAPIError = class _IPTUAPIError extends Error {
|
|
38
48
|
statusCode;
|
|
39
49
|
requestId;
|
|
40
|
-
|
|
41
|
-
constructor(message, statusCode, requestId,
|
|
50
|
+
responseBody;
|
|
51
|
+
constructor(message, statusCode, requestId, responseBody) {
|
|
42
52
|
super(message);
|
|
43
53
|
this.name = "IPTUAPIError";
|
|
44
54
|
this.statusCode = statusCode;
|
|
45
55
|
this.requestId = requestId;
|
|
46
|
-
this.
|
|
56
|
+
this.responseBody = responseBody;
|
|
47
57
|
Object.setPrototypeOf(this, _IPTUAPIError.prototype);
|
|
48
58
|
}
|
|
49
|
-
isRetryable() {
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
toJSON() {
|
|
53
|
-
return {
|
|
54
|
-
error: this.name,
|
|
55
|
-
message: this.message,
|
|
56
|
-
statusCode: this.statusCode,
|
|
57
|
-
requestId: this.requestId,
|
|
58
|
-
retryable: this.isRetryable()
|
|
59
|
-
};
|
|
59
|
+
get isRetryable() {
|
|
60
|
+
return this.statusCode ? [429, 500, 502, 503, 504].includes(this.statusCode) : false;
|
|
60
61
|
}
|
|
61
62
|
};
|
|
62
63
|
var AuthenticationError = class _AuthenticationError extends IPTUAPIError {
|
|
63
|
-
constructor(message = "API Key
|
|
64
|
-
super(message, 401, requestId);
|
|
64
|
+
constructor(message = "API Key inv\xE1lida ou expirada", requestId, responseBody) {
|
|
65
|
+
super(message, 401, requestId, responseBody);
|
|
65
66
|
this.name = "AuthenticationError";
|
|
66
67
|
Object.setPrototypeOf(this, _AuthenticationError.prototype);
|
|
67
68
|
}
|
|
68
69
|
};
|
|
69
70
|
var ForbiddenError = class _ForbiddenError extends IPTUAPIError {
|
|
70
71
|
requiredPlan;
|
|
71
|
-
constructor(message = "
|
|
72
|
-
super(message, 403, requestId);
|
|
72
|
+
constructor(message = "Plano n\xE3o autorizado para este recurso", requiredPlan, requestId, responseBody) {
|
|
73
|
+
super(message, 403, requestId, responseBody);
|
|
73
74
|
this.name = "ForbiddenError";
|
|
74
75
|
this.requiredPlan = requiredPlan;
|
|
75
76
|
Object.setPrototypeOf(this, _ForbiddenError.prototype);
|
|
76
77
|
}
|
|
77
|
-
toJSON() {
|
|
78
|
-
return {
|
|
79
|
-
...super.toJSON(),
|
|
80
|
-
requiredPlan: this.requiredPlan
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
78
|
};
|
|
84
79
|
var NotFoundError = class _NotFoundError extends IPTUAPIError {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
super(message, 404, requestId);
|
|
80
|
+
constructor(message = "Recurso n\xE3o encontrado", requestId, responseBody) {
|
|
81
|
+
super(message, 404, requestId, responseBody);
|
|
88
82
|
this.name = "NotFoundError";
|
|
89
|
-
this.resource = resource;
|
|
90
83
|
Object.setPrototypeOf(this, _NotFoundError.prototype);
|
|
91
84
|
}
|
|
92
|
-
toJSON() {
|
|
93
|
-
return {
|
|
94
|
-
...super.toJSON(),
|
|
95
|
-
resource: this.resource
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
85
|
};
|
|
99
86
|
var RateLimitError = class _RateLimitError extends IPTUAPIError {
|
|
100
87
|
retryAfter;
|
|
101
|
-
|
|
102
|
-
|
|
88
|
+
limit;
|
|
89
|
+
remaining;
|
|
90
|
+
constructor(message = "Limite de requisi\xE7\xF5es excedido", retryAfter, limit, remaining, requestId, responseBody) {
|
|
91
|
+
super(message, 429, requestId, responseBody);
|
|
103
92
|
this.name = "RateLimitError";
|
|
104
93
|
this.retryAfter = retryAfter;
|
|
94
|
+
this.limit = limit;
|
|
95
|
+
this.remaining = remaining;
|
|
105
96
|
Object.setPrototypeOf(this, _RateLimitError.prototype);
|
|
106
97
|
}
|
|
107
|
-
isRetryable() {
|
|
98
|
+
get isRetryable() {
|
|
108
99
|
return true;
|
|
109
100
|
}
|
|
110
|
-
toJSON() {
|
|
111
|
-
return {
|
|
112
|
-
...super.toJSON(),
|
|
113
|
-
retryAfter: this.retryAfter
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
101
|
};
|
|
117
102
|
var ValidationError = class _ValidationError extends IPTUAPIError {
|
|
118
103
|
errors;
|
|
119
|
-
constructor(message = "
|
|
120
|
-
super(message,
|
|
104
|
+
constructor(message = "Par\xE2metros inv\xE1lidos", errors, requestId, responseBody) {
|
|
105
|
+
super(message, 400, requestId, responseBody);
|
|
121
106
|
this.name = "ValidationError";
|
|
122
|
-
this.errors = errors
|
|
107
|
+
this.errors = errors;
|
|
123
108
|
Object.setPrototypeOf(this, _ValidationError.prototype);
|
|
124
109
|
}
|
|
125
|
-
toJSON() {
|
|
126
|
-
return {
|
|
127
|
-
...super.toJSON(),
|
|
128
|
-
validationErrors: this.errors
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
110
|
};
|
|
132
111
|
var ServerError = class _ServerError extends IPTUAPIError {
|
|
133
|
-
constructor(message = "Erro interno do servidor", statusCode = 500, requestId) {
|
|
134
|
-
super(message, statusCode, requestId);
|
|
112
|
+
constructor(message = "Erro interno do servidor", statusCode = 500, requestId, responseBody) {
|
|
113
|
+
super(message, statusCode, requestId, responseBody);
|
|
135
114
|
this.name = "ServerError";
|
|
136
115
|
Object.setPrototypeOf(this, _ServerError.prototype);
|
|
137
116
|
}
|
|
138
|
-
isRetryable() {
|
|
117
|
+
get isRetryable() {
|
|
139
118
|
return true;
|
|
140
119
|
}
|
|
141
120
|
};
|
|
142
121
|
var TimeoutError = class _TimeoutError extends IPTUAPIError {
|
|
143
|
-
|
|
144
|
-
constructor(message = "Timeout na
|
|
145
|
-
super(message, 408
|
|
122
|
+
timeoutMs;
|
|
123
|
+
constructor(message = "Timeout na requisi\xE7\xE3o", timeoutMs) {
|
|
124
|
+
super(message, 408);
|
|
146
125
|
this.name = "TimeoutError";
|
|
147
|
-
this.
|
|
126
|
+
this.timeoutMs = timeoutMs;
|
|
148
127
|
Object.setPrototypeOf(this, _TimeoutError.prototype);
|
|
149
128
|
}
|
|
150
|
-
isRetryable() {
|
|
129
|
+
get isRetryable() {
|
|
151
130
|
return true;
|
|
152
131
|
}
|
|
153
|
-
toJSON() {
|
|
154
|
-
return {
|
|
155
|
-
...super.toJSON(),
|
|
156
|
-
timeoutSeconds: this.timeoutSeconds
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
132
|
};
|
|
160
133
|
var NetworkError = class _NetworkError extends IPTUAPIError {
|
|
161
134
|
originalError;
|
|
162
|
-
constructor(message = "Erro de
|
|
163
|
-
super(message
|
|
135
|
+
constructor(message = "Erro de conex\xE3o com a API", originalError) {
|
|
136
|
+
super(message);
|
|
164
137
|
this.name = "NetworkError";
|
|
165
138
|
this.originalError = originalError;
|
|
166
139
|
Object.setPrototypeOf(this, _NetworkError.prototype);
|
|
167
140
|
}
|
|
168
|
-
isRetryable() {
|
|
141
|
+
get isRetryable() {
|
|
169
142
|
return true;
|
|
170
143
|
}
|
|
171
144
|
};
|
|
172
|
-
|
|
173
|
-
// src/client.ts
|
|
174
145
|
var DEFAULT_RETRY_CONFIG = {
|
|
175
146
|
maxRetries: 3,
|
|
176
|
-
initialDelay:
|
|
177
|
-
maxDelay:
|
|
147
|
+
initialDelay: 500,
|
|
148
|
+
maxDelay: 1e4,
|
|
178
149
|
backoffFactor: 2,
|
|
179
|
-
|
|
180
|
-
};
|
|
181
|
-
var DEFAULT_CONFIG = {
|
|
182
|
-
baseUrl: "https://iptuapi.com.br/api/v1",
|
|
183
|
-
timeout: 3e4,
|
|
184
|
-
retryConfig: DEFAULT_RETRY_CONFIG
|
|
150
|
+
retryableStatuses: [429, 500, 502, 503, 504]
|
|
185
151
|
};
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
result[camelKey] = value;
|
|
152
|
+
var IPTUClient = class {
|
|
153
|
+
apiKey;
|
|
154
|
+
baseUrl;
|
|
155
|
+
timeout;
|
|
156
|
+
retryConfig;
|
|
157
|
+
logger;
|
|
158
|
+
logRequests;
|
|
159
|
+
logResponses;
|
|
160
|
+
userAgent;
|
|
161
|
+
_rateLimit;
|
|
162
|
+
_lastRequestId;
|
|
163
|
+
constructor(apiKey, options = {}) {
|
|
164
|
+
if (!apiKey) {
|
|
165
|
+
throw new Error("API Key \xE9 obrigat\xF3ria");
|
|
201
166
|
}
|
|
167
|
+
this.apiKey = apiKey;
|
|
168
|
+
this.baseUrl = options.baseUrl || "https://iptuapi.com.br/api/v1";
|
|
169
|
+
this.timeout = options.timeout || 3e4;
|
|
170
|
+
this.retryConfig = { ...DEFAULT_RETRY_CONFIG, ...options.retry };
|
|
171
|
+
this.logger = options.logger;
|
|
172
|
+
this.logRequests = options.logRequests || false;
|
|
173
|
+
this.logResponses = options.logResponses || false;
|
|
174
|
+
this.userAgent = options.userAgent || "iptuapi-js/2.1.0";
|
|
175
|
+
}
|
|
176
|
+
// ===========================================================================
|
|
177
|
+
// Properties
|
|
178
|
+
// ===========================================================================
|
|
179
|
+
/** Rate limit info from last request */
|
|
180
|
+
get rateLimit() {
|
|
181
|
+
return this._rateLimit;
|
|
182
|
+
}
|
|
183
|
+
/** Request ID from last request (useful for support) */
|
|
184
|
+
get lastRequestId() {
|
|
185
|
+
return this._lastRequestId;
|
|
202
186
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
210
|
-
result[snakeKey] = toSnakeCase(value);
|
|
211
|
-
} else if (Array.isArray(value)) {
|
|
212
|
-
result[snakeKey] = value.map(
|
|
213
|
-
(item) => typeof item === "object" && item !== null ? toSnakeCase(item) : item
|
|
214
|
-
);
|
|
215
|
-
} else {
|
|
216
|
-
result[snakeKey] = value;
|
|
187
|
+
// ===========================================================================
|
|
188
|
+
// Private Methods
|
|
189
|
+
// ===========================================================================
|
|
190
|
+
log(level, message, ...args) {
|
|
191
|
+
if (this.logger && this.logger[level]) {
|
|
192
|
+
this.logger[level](message, ...args);
|
|
217
193
|
}
|
|
218
194
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
var IPTUClient = class {
|
|
222
|
-
apiKey;
|
|
223
|
-
config;
|
|
224
|
-
_rateLimitInfo = null;
|
|
225
|
-
_lastRequestId = null;
|
|
226
|
-
/**
|
|
227
|
-
* Cria uma nova instancia do cliente.
|
|
228
|
-
*
|
|
229
|
-
* @param apiKey - Chave de API para autenticacao
|
|
230
|
-
* @param options - Opcoes de configuracao
|
|
231
|
-
*/
|
|
232
|
-
constructor(apiKey, options) {
|
|
233
|
-
this.apiKey = apiKey;
|
|
234
|
-
this.config = {
|
|
235
|
-
baseUrl: options?.baseUrl || DEFAULT_CONFIG.baseUrl,
|
|
236
|
-
timeout: options?.timeout || DEFAULT_CONFIG.timeout,
|
|
237
|
-
retryConfig: {
|
|
238
|
-
...DEFAULT_RETRY_CONFIG,
|
|
239
|
-
...options?.retryConfig
|
|
240
|
-
}
|
|
241
|
-
};
|
|
195
|
+
sleep(ms) {
|
|
196
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
242
197
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
198
|
+
combineSignals(signal1, signal2) {
|
|
199
|
+
const controller = new AbortController();
|
|
200
|
+
const abort = () => controller.abort();
|
|
201
|
+
if (signal1.aborted || signal2.aborted) {
|
|
202
|
+
controller.abort();
|
|
203
|
+
return controller.signal;
|
|
204
|
+
}
|
|
205
|
+
signal1.addEventListener("abort", abort, { once: true });
|
|
206
|
+
signal2.addEventListener("abort", abort, { once: true });
|
|
207
|
+
return controller.signal;
|
|
248
208
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
get lastRequestId() {
|
|
253
|
-
return this._lastRequestId;
|
|
209
|
+
calculateDelay(attempt) {
|
|
210
|
+
const delay = this.retryConfig.initialDelay * Math.pow(this.retryConfig.backoffFactor, attempt);
|
|
211
|
+
return Math.min(delay, this.retryConfig.maxDelay);
|
|
254
212
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
213
|
+
extractRateLimit(headers) {
|
|
214
|
+
const limit = headers.get("X-RateLimit-Limit");
|
|
215
|
+
const remaining = headers.get("X-RateLimit-Remaining");
|
|
216
|
+
const reset = headers.get("X-RateLimit-Reset");
|
|
217
|
+
if (limit && remaining && reset) {
|
|
218
|
+
const resetTimestamp = parseInt(reset, 10);
|
|
219
|
+
return {
|
|
220
|
+
limit: parseInt(limit, 10),
|
|
221
|
+
remaining: parseInt(remaining, 10),
|
|
222
|
+
reset: resetTimestamp,
|
|
223
|
+
resetDate: new Date(resetTimestamp * 1e3)
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
return void 0;
|
|
227
|
+
}
|
|
228
|
+
async handleErrorResponse(response, requestId) {
|
|
229
|
+
let body = {};
|
|
230
|
+
try {
|
|
231
|
+
body = await response.json();
|
|
232
|
+
} catch {
|
|
233
|
+
body = { detail: response.statusText };
|
|
234
|
+
}
|
|
235
|
+
let message;
|
|
236
|
+
const detail = body.detail;
|
|
237
|
+
if (detail && typeof detail === "object") {
|
|
238
|
+
const detailObj = detail;
|
|
239
|
+
message = detailObj.error || detailObj.detail || detailObj.message || JSON.stringify(detail);
|
|
240
|
+
} else {
|
|
241
|
+
message = detail || `HTTP ${response.status}`;
|
|
242
|
+
}
|
|
243
|
+
switch (response.status) {
|
|
244
|
+
case 400:
|
|
245
|
+
case 422:
|
|
246
|
+
throw new ValidationError(
|
|
247
|
+
message,
|
|
248
|
+
body.errors,
|
|
249
|
+
requestId,
|
|
250
|
+
body
|
|
251
|
+
);
|
|
252
|
+
case 401:
|
|
253
|
+
throw new AuthenticationError(message, requestId, body);
|
|
254
|
+
case 403:
|
|
255
|
+
throw new ForbiddenError(
|
|
256
|
+
message,
|
|
257
|
+
body.required_plan,
|
|
258
|
+
requestId,
|
|
259
|
+
body
|
|
260
|
+
);
|
|
261
|
+
case 404:
|
|
262
|
+
throw new NotFoundError(message, requestId, body);
|
|
263
|
+
case 429:
|
|
264
|
+
const retryAfter = response.headers.get("Retry-After");
|
|
265
|
+
throw new RateLimitError(
|
|
266
|
+
message,
|
|
267
|
+
retryAfter ? parseInt(retryAfter, 10) : void 0,
|
|
268
|
+
this._rateLimit?.limit,
|
|
269
|
+
this._rateLimit?.remaining,
|
|
270
|
+
requestId,
|
|
271
|
+
body
|
|
272
|
+
);
|
|
273
|
+
case 500:
|
|
274
|
+
case 502:
|
|
275
|
+
case 503:
|
|
276
|
+
case 504:
|
|
277
|
+
throw new ServerError(message, response.status, requestId, body);
|
|
278
|
+
default:
|
|
279
|
+
throw new IPTUAPIError(message, response.status, requestId, body);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
async request(method, endpoint, params, body, options) {
|
|
283
|
+
const url = new URL(`${this.baseUrl}${endpoint}`);
|
|
260
284
|
if (params) {
|
|
261
|
-
|
|
262
|
-
if (value !== void 0 && value !== null) {
|
|
285
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
286
|
+
if (value !== void 0 && value !== null && value !== "") {
|
|
263
287
|
url.searchParams.append(key, String(value));
|
|
264
288
|
}
|
|
265
|
-
}
|
|
289
|
+
});
|
|
266
290
|
}
|
|
267
|
-
const
|
|
268
|
-
|
|
269
|
-
|
|
291
|
+
const headers = {
|
|
292
|
+
"X-API-Key": this.apiKey,
|
|
293
|
+
"Content-Type": "application/json",
|
|
294
|
+
Accept: "application/json",
|
|
295
|
+
"User-Agent": this.userAgent
|
|
296
|
+
};
|
|
297
|
+
const requestTimeout = options?.timeout ?? this.timeout;
|
|
298
|
+
const externalSignal = options?.signal;
|
|
299
|
+
let lastError;
|
|
300
|
+
let attempt = 0;
|
|
301
|
+
while (attempt <= this.retryConfig.maxRetries) {
|
|
302
|
+
if (externalSignal?.aborted) {
|
|
303
|
+
throw new IPTUAPIError("Request aborted", void 0, void 0, void 0);
|
|
304
|
+
}
|
|
270
305
|
const controller = new AbortController();
|
|
271
|
-
const timeoutId = setTimeout(
|
|
272
|
-
|
|
273
|
-
this.config.timeout
|
|
274
|
-
);
|
|
306
|
+
const timeoutId = setTimeout(() => controller.abort(), requestTimeout);
|
|
307
|
+
const combinedSignal = externalSignal ? this.combineSignals(externalSignal, controller.signal) : controller.signal;
|
|
275
308
|
try {
|
|
309
|
+
if (this.logRequests) {
|
|
310
|
+
this.log(
|
|
311
|
+
"debug",
|
|
312
|
+
`Request: ${method} ${url}`,
|
|
313
|
+
params ? { params } : {},
|
|
314
|
+
body ? { body } : {}
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
const startTime = Date.now();
|
|
276
318
|
const response = await fetch(url.toString(), {
|
|
277
319
|
method,
|
|
278
|
-
headers
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
Accept: "application/json",
|
|
282
|
-
"User-Agent": "iptuapi-js/1.0.0"
|
|
283
|
-
},
|
|
284
|
-
body: body ? JSON.stringify(toSnakeCase(body)) : void 0,
|
|
285
|
-
signal: controller.signal
|
|
320
|
+
headers,
|
|
321
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
322
|
+
signal: combinedSignal
|
|
286
323
|
});
|
|
287
324
|
clearTimeout(timeoutId);
|
|
288
|
-
|
|
289
|
-
this.
|
|
290
|
-
|
|
291
|
-
|
|
325
|
+
const elapsedMs = Date.now() - startTime;
|
|
326
|
+
this._rateLimit = this.extractRateLimit(response.headers);
|
|
327
|
+
this._lastRequestId = response.headers.get("X-Request-ID") || void 0;
|
|
328
|
+
if (this.logResponses) {
|
|
329
|
+
this.log(
|
|
330
|
+
"debug",
|
|
331
|
+
`Response: ${response.status} ${url} (${elapsedMs}ms)`
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
if (response.ok) {
|
|
335
|
+
return await response.json();
|
|
292
336
|
}
|
|
293
|
-
|
|
294
|
-
|
|
337
|
+
if (this.retryConfig.retryableStatuses.includes(response.status) && attempt < this.retryConfig.maxRetries) {
|
|
338
|
+
const delay = this.calculateDelay(attempt);
|
|
339
|
+
this.log(
|
|
340
|
+
"warn",
|
|
341
|
+
`Request failed with ${response.status}, retrying in ${delay}ms (attempt ${attempt + 1}/${this.retryConfig.maxRetries})`
|
|
342
|
+
);
|
|
343
|
+
await this.sleep(delay);
|
|
344
|
+
attempt++;
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
await this.handleErrorResponse(response, this._lastRequestId);
|
|
295
348
|
} catch (error) {
|
|
296
349
|
clearTimeout(timeoutId);
|
|
297
350
|
if (error instanceof IPTUAPIError) {
|
|
298
|
-
if (error.isRetryable() && attempt < maxRetries && this.config.retryConfig.retryableStatusCodes.includes(
|
|
299
|
-
error.statusCode || 0
|
|
300
|
-
)) {
|
|
301
|
-
await this.sleep(delay);
|
|
302
|
-
delay = Math.min(delay * backoffFactor, maxDelay);
|
|
303
|
-
continue;
|
|
304
|
-
}
|
|
305
351
|
throw error;
|
|
306
352
|
}
|
|
307
353
|
if (error instanceof Error) {
|
|
308
354
|
if (error.name === "AbortError") {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
`
|
|
316
|
-
|
|
355
|
+
lastError = new TimeoutError(
|
|
356
|
+
`Timeout ap\xF3s ${this.timeout}ms`,
|
|
357
|
+
this.timeout
|
|
358
|
+
);
|
|
359
|
+
} else if (error.message.includes("fetch") || error.message.includes("network")) {
|
|
360
|
+
lastError = new NetworkError(
|
|
361
|
+
`Erro de conex\xE3o: ${error.message}`,
|
|
362
|
+
error
|
|
317
363
|
);
|
|
364
|
+
} else {
|
|
365
|
+
lastError = error;
|
|
318
366
|
}
|
|
319
|
-
if (attempt < maxRetries) {
|
|
367
|
+
if (attempt < this.retryConfig.maxRetries) {
|
|
368
|
+
const delay = this.calculateDelay(attempt);
|
|
369
|
+
this.log(
|
|
370
|
+
"warn",
|
|
371
|
+
`Request failed: ${error.message}, retrying in ${delay}ms (attempt ${attempt + 1}/${this.retryConfig.maxRetries})`
|
|
372
|
+
);
|
|
320
373
|
await this.sleep(delay);
|
|
321
|
-
|
|
374
|
+
attempt++;
|
|
322
375
|
continue;
|
|
323
376
|
}
|
|
324
|
-
throw new NetworkError(`Erro de conexao: ${error.message}`, error);
|
|
325
377
|
}
|
|
326
|
-
throw
|
|
378
|
+
throw lastError || error;
|
|
327
379
|
}
|
|
328
380
|
}
|
|
329
|
-
throw new
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
381
|
+
throw lastError || new IPTUAPIError("Max retries exceeded");
|
|
382
|
+
}
|
|
383
|
+
async consultaEndereco(paramsOrLogradouro, numeroOrOptions, cidade, options) {
|
|
384
|
+
let params;
|
|
385
|
+
let requestOptions;
|
|
386
|
+
if (typeof paramsOrLogradouro === "string") {
|
|
387
|
+
const numero = typeof numeroOrOptions === "string" ? numeroOrOptions : void 0;
|
|
388
|
+
requestOptions = typeof numeroOrOptions === "object" ? numeroOrOptions : options;
|
|
389
|
+
params = {
|
|
390
|
+
logradouro: paramsOrLogradouro,
|
|
391
|
+
numero,
|
|
392
|
+
cidade: cidade || "sp"
|
|
393
|
+
};
|
|
394
|
+
} else {
|
|
395
|
+
requestOptions = numeroOrOptions;
|
|
396
|
+
params = {
|
|
397
|
+
logradouro: paramsOrLogradouro.logradouro,
|
|
398
|
+
numero: paramsOrLogradouro.numero,
|
|
399
|
+
complemento: paramsOrLogradouro.complemento,
|
|
400
|
+
cidade: paramsOrLogradouro.cidade || "sp",
|
|
401
|
+
incluir_historico: paramsOrLogradouro.incluirHistorico,
|
|
402
|
+
incluir_comparaveis: paramsOrLogradouro.incluirComparaveis,
|
|
403
|
+
incluir_zoneamento: paramsOrLogradouro.incluirZoneamento
|
|
343
404
|
};
|
|
344
405
|
}
|
|
406
|
+
return this.request(
|
|
407
|
+
"GET",
|
|
408
|
+
"/consulta/endereco",
|
|
409
|
+
params,
|
|
410
|
+
void 0,
|
|
411
|
+
requestOptions
|
|
412
|
+
);
|
|
345
413
|
}
|
|
346
414
|
/**
|
|
347
|
-
*
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
data = await response.json();
|
|
355
|
-
message = data.detail || data.message || message;
|
|
356
|
-
} catch {
|
|
357
|
-
message = response.statusText || message;
|
|
358
|
-
}
|
|
359
|
-
switch (response.status) {
|
|
360
|
-
case 401:
|
|
361
|
-
throw new AuthenticationError(message, requestId);
|
|
362
|
-
case 403:
|
|
363
|
-
throw new ForbiddenError(
|
|
364
|
-
message,
|
|
365
|
-
data.required_plan,
|
|
366
|
-
requestId
|
|
367
|
-
);
|
|
368
|
-
case 404:
|
|
369
|
-
throw new NotFoundError(
|
|
370
|
-
message,
|
|
371
|
-
data.resource,
|
|
372
|
-
requestId
|
|
373
|
-
);
|
|
374
|
-
case 429: {
|
|
375
|
-
const retryAfter = parseInt(
|
|
376
|
-
response.headers.get("Retry-After") || "60",
|
|
377
|
-
10
|
|
378
|
-
);
|
|
379
|
-
throw new RateLimitError(message, retryAfter, requestId);
|
|
380
|
-
}
|
|
381
|
-
case 400:
|
|
382
|
-
case 422:
|
|
383
|
-
throw new ValidationError(
|
|
384
|
-
message,
|
|
385
|
-
data.errors,
|
|
386
|
-
response.status,
|
|
387
|
-
requestId
|
|
388
|
-
);
|
|
389
|
-
default:
|
|
390
|
-
if (response.status >= 500) {
|
|
391
|
-
throw new ServerError(message, response.status, requestId);
|
|
392
|
-
}
|
|
393
|
-
throw new IPTUAPIError(message, response.status, requestId, data);
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
/**
|
|
397
|
-
* Aguarda um tempo em milissegundos.
|
|
415
|
+
* Busca dados de IPTU por número SQL (contribuinte).
|
|
416
|
+
*
|
|
417
|
+
* @param sql - Número SQL do imóvel
|
|
418
|
+
* @param cidade - Cidade da consulta
|
|
419
|
+
* @param options - Opções adicionais (incluirHistorico, incluirComparaveis)
|
|
420
|
+
* @param requestOptions - Opções de request (signal para cancelamento, timeout)
|
|
421
|
+
* @returns Dados completos do imóvel
|
|
398
422
|
*/
|
|
399
|
-
|
|
400
|
-
return
|
|
423
|
+
async consultaSQL(sql, cidade = "sp", options, requestOptions) {
|
|
424
|
+
return this.request("GET", `/consulta/sql/${sql}`, {
|
|
425
|
+
cidade,
|
|
426
|
+
incluir_historico: options?.incluirHistorico,
|
|
427
|
+
incluir_comparaveis: options?.incluirComparaveis
|
|
428
|
+
}, void 0, requestOptions);
|
|
401
429
|
}
|
|
402
|
-
// ==================== CONSULTAS IPTU ====================
|
|
403
430
|
/**
|
|
404
|
-
*
|
|
431
|
+
* Busca imóveis por CEP.
|
|
405
432
|
*
|
|
406
|
-
* @param
|
|
407
|
-
* @param
|
|
408
|
-
* @param
|
|
409
|
-
* @returns Lista de
|
|
433
|
+
* @param cep - CEP do imóvel
|
|
434
|
+
* @param cidade - Cidade da consulta
|
|
435
|
+
* @param requestOptions - Opções de request (signal para cancelamento, timeout)
|
|
436
|
+
* @returns Lista de imóveis no CEP
|
|
410
437
|
*/
|
|
411
|
-
async
|
|
412
|
-
const
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
438
|
+
async consultaCEP(cep, cidade = "sp", requestOptions) {
|
|
439
|
+
const cleanCep = cep.replace(/\D/g, "");
|
|
440
|
+
return this.request(
|
|
441
|
+
"GET",
|
|
442
|
+
`/consulta/cep/${cleanCep}`,
|
|
443
|
+
{ cidade },
|
|
444
|
+
void 0,
|
|
445
|
+
requestOptions
|
|
446
|
+
);
|
|
418
447
|
}
|
|
419
448
|
/**
|
|
420
|
-
* Consulta
|
|
421
|
-
* Requer plano Starter ou superior.
|
|
449
|
+
* Consulta zoneamento por coordenadas.
|
|
422
450
|
*
|
|
423
|
-
* @param
|
|
424
|
-
* @param
|
|
425
|
-
* @
|
|
451
|
+
* @param latitude - Latitude do ponto
|
|
452
|
+
* @param longitude - Longitude do ponto
|
|
453
|
+
* @param requestOptions - Opções de request (signal para cancelamento, timeout)
|
|
454
|
+
* @returns Dados de zoneamento
|
|
426
455
|
*/
|
|
427
|
-
async
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
});
|
|
432
|
-
|
|
433
|
-
|
|
456
|
+
async consultaZoneamento(latitude, longitude, requestOptions) {
|
|
457
|
+
return this.request("GET", "/consulta/zoneamento", {
|
|
458
|
+
latitude,
|
|
459
|
+
longitude
|
|
460
|
+
}, void 0, requestOptions);
|
|
461
|
+
}
|
|
462
|
+
// ===========================================================================
|
|
463
|
+
// Valuation Endpoints (Pro+)
|
|
464
|
+
// ===========================================================================
|
|
434
465
|
/**
|
|
435
|
-
*
|
|
466
|
+
* Estima o valor de mercado do imóvel usando ML.
|
|
467
|
+
* Disponível apenas para planos Pro e Enterprise.
|
|
436
468
|
*
|
|
437
|
-
* @param
|
|
438
|
-
* @param
|
|
439
|
-
* @returns
|
|
469
|
+
* @param params - Parâmetros do imóvel
|
|
470
|
+
* @param requestOptions - Opções de request (signal para cancelamento, timeout)
|
|
471
|
+
* @returns Estimativa de valor
|
|
472
|
+
* @throws {ForbiddenError} Se o plano não permitir
|
|
440
473
|
*/
|
|
441
|
-
async
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
474
|
+
async valuationEstimate(params, requestOptions) {
|
|
475
|
+
return this.request(
|
|
476
|
+
"POST",
|
|
477
|
+
"/valuation/estimate",
|
|
478
|
+
void 0,
|
|
479
|
+
{
|
|
480
|
+
area_terreno: params.area_terreno,
|
|
481
|
+
area_construida: params.area_construida,
|
|
482
|
+
bairro: params.bairro,
|
|
483
|
+
zona: params.zona,
|
|
484
|
+
tipo_uso: params.tipo_uso,
|
|
485
|
+
tipo_padrao: params.tipo_padrao,
|
|
486
|
+
ano_construcao: params.ano_construcao,
|
|
487
|
+
cidade: params.cidade || "sp"
|
|
488
|
+
},
|
|
489
|
+
requestOptions
|
|
490
|
+
);
|
|
447
491
|
}
|
|
448
492
|
/**
|
|
449
|
-
*
|
|
493
|
+
* Valuation em lote (até 100 imóveis).
|
|
494
|
+
* Disponível apenas para plano Enterprise.
|
|
450
495
|
*
|
|
451
|
-
* @param
|
|
452
|
-
* @param
|
|
453
|
-
* @returns
|
|
496
|
+
* @param imoveis - Lista de imóveis para avaliar
|
|
497
|
+
* @param requestOptions - Opções de request (signal para cancelamento, timeout)
|
|
498
|
+
* @returns Resultados de valuation para cada imóvel
|
|
454
499
|
*/
|
|
455
|
-
async
|
|
456
|
-
return this.
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
500
|
+
async valuationBatch(imoveis, requestOptions) {
|
|
501
|
+
return this.request(
|
|
502
|
+
"POST",
|
|
503
|
+
"/valuation/estimate/batch",
|
|
504
|
+
void 0,
|
|
505
|
+
{ imoveis },
|
|
506
|
+
requestOptions
|
|
507
|
+
);
|
|
460
508
|
}
|
|
461
|
-
// ==================== VALUATION ====================
|
|
462
509
|
/**
|
|
463
|
-
*
|
|
464
|
-
* Requer plano Pro ou superior.
|
|
510
|
+
* Busca imóveis comparáveis para análise.
|
|
465
511
|
*
|
|
466
|
-
* @param
|
|
467
|
-
* @
|
|
512
|
+
* @param bairro - Nome do bairro
|
|
513
|
+
* @param areaMin - Área mínima em m²
|
|
514
|
+
* @param areaMax - Área máxima em m²
|
|
515
|
+
* @param options - Opções adicionais
|
|
516
|
+
* @param requestOptions - Opções de request (signal para cancelamento, timeout)
|
|
517
|
+
* @returns Lista de imóveis comparáveis
|
|
468
518
|
*/
|
|
469
|
-
async
|
|
470
|
-
return this.
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
ano_construcao: params.anoConstrucao
|
|
479
|
-
});
|
|
519
|
+
async valuationComparables(bairro, areaMin, areaMax, options, requestOptions) {
|
|
520
|
+
return this.request("GET", "/valuation/comparables", {
|
|
521
|
+
bairro,
|
|
522
|
+
area_min: areaMin,
|
|
523
|
+
area_max: areaMax,
|
|
524
|
+
tipo_uso: options?.tipoUso,
|
|
525
|
+
cidade: options?.cidade || "sp",
|
|
526
|
+
limit: options?.limit || 10
|
|
527
|
+
}, void 0, requestOptions);
|
|
480
528
|
}
|
|
481
529
|
/**
|
|
482
|
-
*
|
|
483
|
-
* Requer plano Pro ou superior.
|
|
530
|
+
* Estatísticas de valores por bairro.
|
|
484
531
|
*
|
|
485
|
-
* @param
|
|
486
|
-
* @
|
|
532
|
+
* @param bairro - Nome do bairro
|
|
533
|
+
* @param cidade - Cidade da consulta
|
|
534
|
+
* @param requestOptions - Opções de request (signal para cancelamento, timeout)
|
|
535
|
+
* @returns Estatísticas: média, mediana, min, max, etc
|
|
487
536
|
*/
|
|
488
|
-
async
|
|
489
|
-
|
|
537
|
+
async valuationStatistics(bairro, cidade = "sp", requestOptions) {
|
|
538
|
+
return this.request(
|
|
490
539
|
"GET",
|
|
491
|
-
|
|
492
|
-
{
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
area_max: params.areaMax,
|
|
496
|
-
cidade: params.cidade || "sp",
|
|
497
|
-
limit: params.limit || 10
|
|
498
|
-
}
|
|
540
|
+
`/valuation/statistics/${encodeURIComponent(bairro)}`,
|
|
541
|
+
{ cidade },
|
|
542
|
+
void 0,
|
|
543
|
+
requestOptions
|
|
499
544
|
);
|
|
500
|
-
return Array.isArray(response) ? response : [];
|
|
501
545
|
}
|
|
546
|
+
// ===========================================================================
|
|
547
|
+
// Dados Endpoints
|
|
548
|
+
// ===========================================================================
|
|
502
549
|
/**
|
|
503
|
-
*
|
|
504
|
-
* Combina dados do modelo AVM (ML) com transacoes ITBI reais.
|
|
505
|
-
* Requer plano Pro ou superior.
|
|
550
|
+
* Histórico de valores IPTU de um imóvel.
|
|
506
551
|
*
|
|
507
|
-
* @param
|
|
508
|
-
* @
|
|
552
|
+
* @param sql - Número SQL do imóvel
|
|
553
|
+
* @param cidade - Cidade da consulta
|
|
554
|
+
* @param requestOptions - Opções de request (signal para cancelamento, timeout)
|
|
555
|
+
* @returns Lista com histórico anual
|
|
509
556
|
*/
|
|
510
|
-
async
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
};
|
|
516
|
-
if (params.sql) {
|
|
517
|
-
body.sql = params.sql;
|
|
518
|
-
} else {
|
|
519
|
-
if (params.logradouro) body.logradouro = params.logradouro;
|
|
520
|
-
if (params.numero !== void 0) body.numero = params.numero;
|
|
521
|
-
if (params.complemento) body.complemento = params.complemento;
|
|
522
|
-
if (params.bairro) body.bairro = params.bairro;
|
|
523
|
-
}
|
|
524
|
-
return this.makeRequest(
|
|
525
|
-
"POST",
|
|
526
|
-
"/valuation/evaluate",
|
|
557
|
+
async dadosIPTUHistorico(sql, cidade = "sp", requestOptions) {
|
|
558
|
+
return this.request(
|
|
559
|
+
"GET",
|
|
560
|
+
`/dados/iptu/historico/${sql}`,
|
|
561
|
+
{ cidade },
|
|
527
562
|
void 0,
|
|
528
|
-
|
|
563
|
+
requestOptions
|
|
529
564
|
);
|
|
530
565
|
}
|
|
531
|
-
// ==================== ITBI ====================
|
|
532
566
|
/**
|
|
533
|
-
* Consulta
|
|
567
|
+
* Consulta dados de empresa por CNPJ.
|
|
534
568
|
*
|
|
535
|
-
* @param
|
|
536
|
-
* @param
|
|
537
|
-
* @returns
|
|
569
|
+
* @param cnpj - CNPJ da empresa
|
|
570
|
+
* @param requestOptions - Opções de request (signal para cancelamento, timeout)
|
|
571
|
+
* @returns Dados cadastrais
|
|
538
572
|
*/
|
|
539
|
-
async
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
573
|
+
async dadosCNPJ(cnpj, requestOptions) {
|
|
574
|
+
const cleanCnpj = cnpj.replace(/\D/g, "");
|
|
575
|
+
return this.request(
|
|
576
|
+
"GET",
|
|
577
|
+
`/dados/cnpj/${cleanCnpj}`,
|
|
578
|
+
void 0,
|
|
579
|
+
void 0,
|
|
580
|
+
requestOptions
|
|
581
|
+
);
|
|
544
582
|
}
|
|
545
583
|
/**
|
|
546
|
-
*
|
|
584
|
+
* Índice IPCA histórico.
|
|
547
585
|
*
|
|
548
|
-
* @param
|
|
549
|
-
* @
|
|
586
|
+
* @param dataInicio - Data inicial (YYYY-MM)
|
|
587
|
+
* @param dataFim - Data final (YYYY-MM)
|
|
588
|
+
* @param requestOptions - Opções de request (signal para cancelamento, timeout)
|
|
589
|
+
* @returns Série histórica do IPCA
|
|
550
590
|
*/
|
|
551
|
-
async
|
|
552
|
-
return this.
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
591
|
+
async dadosIPCA(dataInicio, dataFim, requestOptions) {
|
|
592
|
+
return this.request(
|
|
593
|
+
"GET",
|
|
594
|
+
"/dados/ipca",
|
|
595
|
+
{
|
|
596
|
+
data_inicio: dataInicio,
|
|
597
|
+
data_fim: dataFim
|
|
598
|
+
},
|
|
599
|
+
void 0,
|
|
600
|
+
requestOptions
|
|
601
|
+
);
|
|
557
602
|
}
|
|
558
603
|
/**
|
|
559
|
-
*
|
|
560
|
-
* Requer plano Starter ou superior.
|
|
604
|
+
* Correção monetária pelo IPCA.
|
|
561
605
|
*
|
|
562
|
-
* @param
|
|
563
|
-
* @param
|
|
564
|
-
* @
|
|
606
|
+
* @param valor - Valor a corrigir
|
|
607
|
+
* @param dataOrigem - Data do valor original (YYYY-MM)
|
|
608
|
+
* @param dataDestino - Data destino (default: atual)
|
|
609
|
+
* @param requestOptions - Opções de request (signal para cancelamento, timeout)
|
|
610
|
+
* @returns Valor corrigido e fator de correção
|
|
565
611
|
*/
|
|
566
|
-
async
|
|
567
|
-
|
|
612
|
+
async dadosIPCACorrigir(valor, dataOrigem, dataDestino, requestOptions) {
|
|
613
|
+
return this.request(
|
|
568
614
|
"GET",
|
|
569
|
-
"/
|
|
570
|
-
{
|
|
615
|
+
"/dados/ipca/corrigir",
|
|
616
|
+
{
|
|
617
|
+
valor,
|
|
618
|
+
data_origem: dataOrigem,
|
|
619
|
+
data_destino: dataDestino
|
|
620
|
+
},
|
|
621
|
+
void 0,
|
|
622
|
+
requestOptions
|
|
571
623
|
);
|
|
572
|
-
return Array.isArray(response) ? response : [];
|
|
573
624
|
}
|
|
625
|
+
// ===========================================================================
|
|
626
|
+
// IPTU Tools Endpoints (Ferramentas IPTU 2026)
|
|
627
|
+
// ===========================================================================
|
|
574
628
|
/**
|
|
575
|
-
*
|
|
629
|
+
* Lista todas as cidades com calendario de IPTU disponivel.
|
|
576
630
|
*
|
|
577
|
-
* @param
|
|
578
|
-
* @returns
|
|
631
|
+
* @param requestOptions - Opções de request (signal para cancelamento, timeout)
|
|
632
|
+
* @returns Lista de cidades com codigo, nome, desconto e parcelas
|
|
579
633
|
*/
|
|
580
|
-
async
|
|
581
|
-
return this.
|
|
634
|
+
async iptuToolsCidades(requestOptions) {
|
|
635
|
+
return this.request("GET", "/iptu-tools/cidades", void 0, void 0, requestOptions);
|
|
582
636
|
}
|
|
583
637
|
/**
|
|
584
|
-
*
|
|
638
|
+
* Retorna o calendario completo de IPTU para a cidade especificada.
|
|
585
639
|
*
|
|
586
|
-
* @param cidade - Codigo da cidade (sp, bh, recife)
|
|
587
|
-
* @
|
|
640
|
+
* @param cidade - Codigo da cidade (sp, bh, rj, recife, curitiba, poa, fortaleza)
|
|
641
|
+
* @param requestOptions - Opções de request (signal para cancelamento, timeout)
|
|
642
|
+
* @returns Calendario com vencimentos, descontos, alertas e novidades
|
|
588
643
|
*/
|
|
589
|
-
async
|
|
590
|
-
|
|
591
|
-
"GET",
|
|
592
|
-
"/itbi/isencoes",
|
|
593
|
-
{ cidade }
|
|
594
|
-
);
|
|
595
|
-
return Array.isArray(response) ? response : [];
|
|
644
|
+
async iptuToolsCalendario(cidade = "sp", requestOptions) {
|
|
645
|
+
return this.request("GET", "/iptu-tools/calendario", { cidade }, void 0, requestOptions);
|
|
596
646
|
}
|
|
597
647
|
/**
|
|
598
|
-
*
|
|
599
|
-
* Requer plano Starter ou superior.
|
|
648
|
+
* Simula as opcoes de pagamento do IPTU (a vista vs parcelado).
|
|
600
649
|
*
|
|
601
|
-
* @param
|
|
602
|
-
* @
|
|
650
|
+
* @param valorIptu - Valor total do IPTU
|
|
651
|
+
* @param cidade - Codigo da cidade
|
|
652
|
+
* @param valorVenal - Valor venal do imovel (para verificar isencao)
|
|
653
|
+
* @param requestOptions - Opções de request (signal para cancelamento, timeout)
|
|
654
|
+
* @returns Comparativo entre pagamento a vista e parcelado com recomendacao
|
|
603
655
|
*/
|
|
604
|
-
async
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
}
|
|
656
|
+
async iptuToolsSimulador(valorIptu, cidade = "sp", valorVenal, requestOptions) {
|
|
657
|
+
const body = {
|
|
658
|
+
valor_iptu: valorIptu,
|
|
659
|
+
cidade
|
|
660
|
+
};
|
|
661
|
+
if (valorVenal !== void 0) {
|
|
662
|
+
body.valor_venal = valorVenal;
|
|
663
|
+
}
|
|
664
|
+
return this.request("POST", "/iptu-tools/simulador", void 0, body, requestOptions);
|
|
612
665
|
}
|
|
613
666
|
/**
|
|
614
|
-
*
|
|
667
|
+
* Verifica se um imovel e elegivel para isencao de IPTU.
|
|
615
668
|
*
|
|
616
|
-
* @param
|
|
617
|
-
* @param cidade - Codigo da cidade
|
|
618
|
-
* @
|
|
669
|
+
* @param valorVenal - Valor venal do imovel
|
|
670
|
+
* @param cidade - Codigo da cidade
|
|
671
|
+
* @param requestOptions - Opções de request (signal para cancelamento, timeout)
|
|
672
|
+
* @returns Elegibilidade para isencao total ou parcial
|
|
619
673
|
*/
|
|
620
|
-
async
|
|
621
|
-
return this.
|
|
622
|
-
|
|
674
|
+
async iptuToolsIsencao(valorVenal, cidade = "sp", requestOptions) {
|
|
675
|
+
return this.request("GET", "/iptu-tools/isencao", {
|
|
676
|
+
valor_venal: valorVenal,
|
|
623
677
|
cidade
|
|
624
|
-
});
|
|
678
|
+
}, void 0, requestOptions);
|
|
625
679
|
}
|
|
626
680
|
/**
|
|
627
|
-
*
|
|
681
|
+
* Retorna informacoes sobre o proximo vencimento do IPTU.
|
|
628
682
|
*
|
|
629
|
-
* @param
|
|
630
|
-
* @
|
|
683
|
+
* @param cidade - Codigo da cidade
|
|
684
|
+
* @param parcela - Numero da parcela (1-12)
|
|
685
|
+
* @param requestOptions - Opções de request (signal para cancelamento, timeout)
|
|
686
|
+
* @returns Data de vencimento, dias restantes e status
|
|
631
687
|
*/
|
|
632
|
-
async
|
|
633
|
-
return this.
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
valorFinanciado: params.valorFinanciado
|
|
638
|
-
});
|
|
688
|
+
async iptuToolsProximoVencimento(cidade = "sp", parcela = 1, requestOptions) {
|
|
689
|
+
return this.request("GET", "/iptu-tools/proximo-vencimento", {
|
|
690
|
+
cidade,
|
|
691
|
+
parcela
|
|
692
|
+
}, void 0, requestOptions);
|
|
639
693
|
}
|
|
640
694
|
};
|
|
695
|
+
var index_default = IPTUClient;
|
|
641
696
|
// Annotate the CommonJS export names for ESM import in node:
|
|
642
697
|
0 && (module.exports = {
|
|
643
698
|
AuthenticationError,
|
|
699
|
+
CidadeEnum,
|
|
644
700
|
ForbiddenError,
|
|
645
701
|
IPTUAPIError,
|
|
646
702
|
IPTUClient,
|