catastrogps 1.1.0 → 1.2.0

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.ts CHANGED
@@ -14,11 +14,33 @@ interface CatastroGPSOptions {
14
14
  interface CountryOption<C extends string = CountryCode> {
15
15
  country?: C;
16
16
  }
17
+ declare const ADDRESS_COUNTRY_CODES: readonly ["ES", "FR", "IT", "DE", "AT", "NL", "BE", "PL", "CH", "CZ", "DK", "NO", "FI", "EE", "LV", "LT", "SI", "SK", "BG", "GR", "CY", "LU", "LI", "IS", "IE", "UK", "PT"];
18
+ type AddressCountryCode = (typeof ADDRESS_COUNTRY_CODES)[number];
19
+ declare const UNITS_COUNTRY_CODES: readonly ["ES", "PV", "NA"];
20
+ type UnitsCountryCode = (typeof UNITS_COUNTRY_CODES)[number];
21
+ interface PrepaidOverage {
22
+ enabled: boolean;
23
+ balance?: number;
24
+ unitPrice?: number;
25
+ remainingUnits?: number;
26
+ }
27
+ interface BurstLimit {
28
+ limit?: number;
29
+ remaining?: number;
30
+ resetSeconds?: number;
31
+ }
32
+ interface FincaCap {
33
+ cap?: number;
34
+ used?: number;
35
+ }
17
36
  interface Quota {
18
37
  plan?: string;
19
38
  limit?: number;
20
39
  remaining?: number;
21
40
  resetsAt?: string;
41
+ overage?: PrepaidOverage;
42
+ rateLimit?: BurstLimit;
43
+ fincaCap?: FincaCap;
22
44
  }
23
45
  interface Parcel {
24
46
  refCatastral: string;
@@ -119,6 +141,7 @@ interface ResolveResult {
119
141
  }
120
142
  interface AddressCandidatesQuery {
121
143
  q?: string;
144
+ country?: AddressCountryCode;
122
145
  street?: string;
123
146
  number?: number;
124
147
  municipality?: string;
@@ -219,8 +242,130 @@ interface UnitsResult {
219
242
  pages: UnitsPage[];
220
243
  }
221
244
  interface GetUnitsOptions {
245
+ country?: UnitsCountryCode;
222
246
  previous?: UnitsResult;
223
247
  }
248
+ interface LocatedOptions extends CountryOption<Exclude<CountryCode, 'UK' | 'HR'>> {
249
+ lat?: number;
250
+ lng?: number;
251
+ }
252
+ interface DataSource {
253
+ name?: string;
254
+ provider?: string;
255
+ license?: string;
256
+ attribution?: string;
257
+ url?: string;
258
+ resolution?: string;
259
+ edition?: string;
260
+ }
261
+ type BlockStatus = 'ok' | 'no_data' | 'unavailable';
262
+ interface ProtectedSite {
263
+ code: string;
264
+ name: string;
265
+ type?: 'SPA' | 'SCI' | 'SPA_SCI' | string;
266
+ designation?: string;
267
+ country?: string;
268
+ overlap_pct?: number | null;
269
+ }
270
+ interface Terrain {
271
+ refcat: string;
272
+ country: string;
273
+ relief: {
274
+ status: BlockStatus;
275
+ elevation_m?: {
276
+ mean: number;
277
+ min: number;
278
+ max: number;
279
+ };
280
+ slope?: {
281
+ mean_pct: number;
282
+ mean_deg: number;
283
+ max_pct: number;
284
+ class: string;
285
+ max_class: string;
286
+ share_over_10_pct: number;
287
+ classes_pct: Record<string, number>;
288
+ };
289
+ aspect?: {
290
+ dominant: string;
291
+ dominant_share_pct: number;
292
+ mean_deg: number | null;
293
+ flat_share_pct: number;
294
+ sectors_pct: Record<string, number>;
295
+ };
296
+ sample?: {
297
+ method: string;
298
+ cells: number;
299
+ resolution_m: number;
300
+ };
301
+ source?: DataSource;
302
+ };
303
+ protected_areas: {
304
+ status: BlockStatus;
305
+ intersects?: boolean;
306
+ inside?: boolean;
307
+ max_overlap_pct?: number | null;
308
+ natura2000?: ProtectedSite[];
309
+ national?: ProtectedSite[];
310
+ method?: string;
311
+ sources?: DataSource[];
312
+ };
313
+ climate?: {
314
+ status: BlockStatus;
315
+ baseline?: Record<string, number>;
316
+ recent?: Record<string, number>;
317
+ [key: string]: unknown;
318
+ };
319
+ calculated_at?: string;
320
+ provenance?: string;
321
+ }
322
+ interface GroundMotion {
323
+ refcat: string;
324
+ country: string;
325
+ status: BlockStatus;
326
+ reason?: 'no_reflectors' | 'outside_coverage' | 'parcel_too_large' | string;
327
+ period?: {
328
+ from: string;
329
+ to: string;
330
+ label: string;
331
+ };
332
+ ground_motion?: {
333
+ class: string;
334
+ worst_class?: string;
335
+ vertical: {
336
+ mean_mm_year: number;
337
+ max_subsidence_mm_year?: number;
338
+ max_uplift_mm_year?: number;
339
+ std_mm_year?: number;
340
+ acceleration_mm_year2?: number;
341
+ rmse_mm?: number;
342
+ };
343
+ east_west?: {
344
+ mean_mm_year: number;
345
+ std_mm_year?: number;
346
+ };
347
+ yearly_displacement?: Array<{
348
+ year: number;
349
+ mm: number;
350
+ }>;
351
+ cells_with_data: number;
352
+ cells_considered: number;
353
+ coverage_pct: number;
354
+ basis?: 'parcel' | 'surroundings' | string;
355
+ cell_size_m?: number;
356
+ };
357
+ source?: DataSource;
358
+ calculated_at?: string;
359
+ provenance?: string;
360
+ }
361
+ type MarketData = Record<string, unknown>;
362
+ type ScoreData = Record<string, unknown>;
363
+ type ValueHistory = Record<string, unknown>;
364
+ type Comparison = Record<string, unknown>;
365
+ interface CompareItem {
366
+ reference: string;
367
+ country: EnrichmentCountryCode;
368
+ }
224
369
 
225
370
  declare class ExportResource {
226
371
  private readonly client;
@@ -249,6 +394,12 @@ declare class ParcelsResource {
249
394
  geometry(reference: string, options?: CountryOption<Exclude<CountryCode, 'UK'>>): Promise<ParcelGeometry>;
250
395
  solar(reference: string, options?: CountryOption<EnrichmentCountryCode>): Promise<SolarEstimate>;
251
396
  agriculture(reference: string, options?: CountryOption<EnrichmentCountryCode>): Promise<AgricultureData>;
397
+ terrain(reference: string, options?: LocatedOptions): Promise<Terrain>;
398
+ groundMotion(reference: string, options?: LocatedOptions): Promise<GroundMotion>;
399
+ market(reference: string, options?: CountryOption<EnrichmentCountryCode>): Promise<MarketData>;
400
+ score(reference: string, options?: CountryOption<EnrichmentCountryCode>): Promise<ScoreData>;
401
+ valueHistory(reference: string, options?: CountryOption<EnrichmentCountryCode | 'AT'>): Promise<ValueHistory>;
402
+ compare(parcels: CompareItem[]): Promise<Comparison>;
252
403
  }
253
404
 
254
405
  declare const DEFAULT_BASE_URL = "https://api.catastrogps.es";
@@ -265,6 +416,7 @@ interface ConditionalResponse<T> {
265
416
  data?: T;
266
417
  etag?: string;
267
418
  notModified: boolean;
419
+ quota?: Quota;
268
420
  }
269
421
  declare class CatastroGPS {
270
422
  readonly parcels: ParcelsResource;
@@ -291,8 +443,9 @@ declare class CatastroGPS {
291
443
  private retryDelayMs;
292
444
  private captureQuota;
293
445
  }
446
+ declare function readQuota(headers: Headers): Quota | undefined;
294
447
 
295
- declare const VERSION = "1.1.0";
448
+ declare const VERSION = "1.2.0";
296
449
 
297
450
  declare class CatastroGPSError extends Error {
298
451
  readonly status?: number;
@@ -318,8 +471,20 @@ declare class NotFoundError extends CatastroGPSError {
318
471
  declare class ValidationError extends CatastroGPSError {
319
472
  name: string;
320
473
  }
474
+ declare class PlaceNameError extends ValidationError {
475
+ name: string;
476
+ get location(): {
477
+ lat: number;
478
+ lng: number;
479
+ address?: string;
480
+ label?: string;
481
+ } | undefined;
482
+ }
321
483
  declare class CoverageError extends CatastroGPSError {
322
484
  name: string;
485
+ get country(): string | undefined;
486
+ get feature(): string | undefined;
487
+ get supportedCountries(): string[];
323
488
  }
324
489
  declare class AmbiguousReferenceError extends CatastroGPSError {
325
490
  name: string;
@@ -331,6 +496,8 @@ declare class AmbiguousReferenceError extends CatastroGPSError {
331
496
  }
332
497
  declare class QuotaExceededError extends CatastroGPSError {
333
498
  name: string;
499
+ quota?: Quota;
500
+ get prepaidBalanceEmpty(): boolean;
334
501
  }
335
502
  declare class RateLimitError extends CatastroGPSError {
336
503
  name: string;
@@ -350,4 +517,4 @@ declare class NetworkError extends CatastroGPSError {
350
517
  name: string;
351
518
  }
352
519
 
353
- export { type AddressCandidate, type AddressCandidatesQuery, type AddressCandidatesResult, type AddressMatch, type AgricultureData, AmbiguousReferenceError, AuthenticationError, COUNTRY_CODES, CatastroGPS, CatastroGPSError, type CatastroGPSOptions, type ConditionalResponse, type Construction, type CountryCode, type CountryOption, CoverageError, DEFAULT_BASE_URL, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT_MS, ENRICHMENT_COUNTRY_CODES, type EnrichmentCountryCode, type ExportFormat, type FetchLike, ForbiddenError, type GetUnitsOptions, NetworkError, NotFoundError, type Parcel, type ParcelGeometry, type PointMatch, type PointQuery, type Quota, QuotaExceededError, RateLimitError, type ResolveCandidate, type ResolveResult, ServerError, ServiceUnavailableError, type SolarEstimate, TimeoutError, type Unit, type UnitsPage, type UnitsPageData, type UnitsResult, VERSION, ValidationError };
520
+ export { ADDRESS_COUNTRY_CODES, type AddressCandidate, type AddressCandidatesQuery, type AddressCandidatesResult, type AddressCountryCode, type AddressMatch, type AgricultureData, AmbiguousReferenceError, AuthenticationError, type BlockStatus, type BurstLimit, COUNTRY_CODES, CatastroGPS, CatastroGPSError, type CatastroGPSOptions, type CompareItem, type Comparison, type ConditionalResponse, type Construction, type CountryCode, type CountryOption, CoverageError, DEFAULT_BASE_URL, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT_MS, type DataSource, ENRICHMENT_COUNTRY_CODES, type EnrichmentCountryCode, type ExportFormat, type FetchLike, type FincaCap, ForbiddenError, type GetUnitsOptions, type GroundMotion, type LocatedOptions, type MarketData, NetworkError, NotFoundError, type Parcel, type ParcelGeometry, PlaceNameError, type PointMatch, type PointQuery, type PrepaidOverage, type ProtectedSite, type Quota, QuotaExceededError, RateLimitError, type ResolveCandidate, type ResolveResult, type ScoreData, ServerError, ServiceUnavailableError, type SolarEstimate, type Terrain, TimeoutError, UNITS_COUNTRY_CODES, type Unit, type UnitsCountryCode, type UnitsPage, type UnitsPageData, type UnitsResult, VERSION, ValidationError, type ValueHistory, readQuota };
package/dist/index.js CHANGED
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ ADDRESS_COUNTRY_CODES: () => ADDRESS_COUNTRY_CODES,
23
24
  AmbiguousReferenceError: () => AmbiguousReferenceError,
24
25
  AuthenticationError: () => AuthenticationError,
25
26
  COUNTRY_CODES: () => COUNTRY_CODES,
@@ -33,13 +34,16 @@ __export(index_exports, {
33
34
  ForbiddenError: () => ForbiddenError,
34
35
  NetworkError: () => NetworkError,
35
36
  NotFoundError: () => NotFoundError,
37
+ PlaceNameError: () => PlaceNameError,
36
38
  QuotaExceededError: () => QuotaExceededError,
37
39
  RateLimitError: () => RateLimitError,
38
40
  ServerError: () => ServerError,
39
41
  ServiceUnavailableError: () => ServiceUnavailableError,
40
42
  TimeoutError: () => TimeoutError,
43
+ UNITS_COUNTRY_CODES: () => UNITS_COUNTRY_CODES,
41
44
  VERSION: () => VERSION,
42
- ValidationError: () => ValidationError
45
+ ValidationError: () => ValidationError,
46
+ readQuota: () => readQuota
43
47
  });
44
48
  module.exports = __toCommonJS(index_exports);
45
49
 
@@ -70,8 +74,24 @@ var NotFoundError = class extends CatastroGPSError {
70
74
  var ValidationError = class extends CatastroGPSError {
71
75
  name = "ValidationError";
72
76
  };
77
+ var PlaceNameError = class extends ValidationError {
78
+ name = "PlaceNameError";
79
+ get location() {
80
+ const details = this.details;
81
+ return details?.location;
82
+ }
83
+ };
73
84
  var CoverageError = class extends CatastroGPSError {
74
85
  name = "CoverageError";
86
+ get country() {
87
+ return this.details?.country;
88
+ }
89
+ get feature() {
90
+ return this.details?.feature;
91
+ }
92
+ get supportedCountries() {
93
+ return this.details?.supportedCountries ?? [];
94
+ }
75
95
  };
76
96
  var AmbiguousReferenceError = class extends CatastroGPSError {
77
97
  name = "AmbiguousReferenceError";
@@ -82,6 +102,10 @@ var AmbiguousReferenceError = class extends CatastroGPSError {
82
102
  };
83
103
  var QuotaExceededError = class extends CatastroGPSError {
84
104
  name = "QuotaExceededError";
105
+ quota;
106
+ get prepaidBalanceEmpty() {
107
+ return this.quota?.overage?.enabled === true;
108
+ }
85
109
  };
86
110
  var RateLimitError = class extends CatastroGPSError {
87
111
  name = "RateLimitError";
@@ -100,14 +124,19 @@ var TimeoutError = class extends CatastroGPSError {
100
124
  var NetworkError = class extends CatastroGPSError {
101
125
  name = "NetworkError";
102
126
  };
103
- function errorFromResponse(status, body, retryAfter) {
127
+ function errorFromResponse(status, body, retryAfter, quota) {
104
128
  const code = typeof body.code === "string" ? body.code : void 0;
105
129
  const message = typeof body.error === "string" && body.error || typeof body.message === "string" && body.message || `HTTP ${status}`;
106
130
  const details = body.data ?? body.parsed;
107
131
  const options = { status, code, details, body };
108
132
  if (code === "CNV_AMBIGUOUS" || status === 300) return new AmbiguousReferenceError(message, options);
109
133
  if (code === "CNV_COVERAGE") return new CoverageError(message, options);
110
- if (code === "KEY_AUTH_004") return new QuotaExceededError(message, options);
134
+ if (code === "CNV_PLACE_NAME") return new PlaceNameError(message, options);
135
+ if (code === "KEY_AUTH_004") {
136
+ const error = new QuotaExceededError(message, options);
137
+ error.quota = quota;
138
+ return error;
139
+ }
111
140
  if (status === 429) {
112
141
  const error = new RateLimitError(message, options);
113
142
  error.retryAfterSeconds = retryAfter;
@@ -145,7 +174,75 @@ var ExportResource = class {
145
174
  }
146
175
  };
147
176
 
177
+ // src/types.ts
178
+ var COUNTRY_CODES = [
179
+ "ES",
180
+ "PV",
181
+ "NA",
182
+ "PT",
183
+ "FR",
184
+ "IT",
185
+ "DE",
186
+ "AT",
187
+ "CH",
188
+ "LI",
189
+ "BE",
190
+ "NL",
191
+ "LU",
192
+ "PL",
193
+ "CZ",
194
+ "SK",
195
+ "SI",
196
+ "HR",
197
+ "BG",
198
+ "GR",
199
+ "CY",
200
+ "DK",
201
+ "SE",
202
+ "NO",
203
+ "FI",
204
+ "IS",
205
+ "EE",
206
+ "LV",
207
+ "LT",
208
+ "IE",
209
+ "UK"
210
+ ];
211
+ var ENRICHMENT_COUNTRY_CODES = ["ES", "PV", "NA", "PT", "FR", "IT", "DE"];
212
+ var ADDRESS_COUNTRY_CODES = [
213
+ "ES",
214
+ "FR",
215
+ "IT",
216
+ "DE",
217
+ "AT",
218
+ "NL",
219
+ "BE",
220
+ "PL",
221
+ "CH",
222
+ "CZ",
223
+ "DK",
224
+ "NO",
225
+ "FI",
226
+ "EE",
227
+ "LV",
228
+ "LT",
229
+ "SI",
230
+ "SK",
231
+ "BG",
232
+ "GR",
233
+ "CY",
234
+ "LU",
235
+ "LI",
236
+ "IS",
237
+ "IE",
238
+ "UK",
239
+ "PT"
240
+ ];
241
+ var UNITS_COUNTRY_CODES = ["ES", "PV", "NA"];
242
+
148
243
  // src/resources/parcels.ts
244
+ var MIN_COMPARE = 2;
245
+ var MAX_COMPARE = 3;
149
246
  var ParcelsResource = class {
150
247
  constructor(client) {
151
248
  this.client = client;
@@ -178,7 +275,46 @@ var ParcelsResource = class {
178
275
  });
179
276
  return data.agro ?? data;
180
277
  }
278
+ async terrain(reference, options = {}) {
279
+ return this.client.request("GET", parcelPath(reference, "/terrain"), { query: locatedQuery(options) });
280
+ }
281
+ async groundMotion(reference, options = {}) {
282
+ return this.client.request("GET", parcelPath(reference, "/ground-motion"), { query: locatedQuery(options) });
283
+ }
284
+ async market(reference, options = {}) {
285
+ return this.client.request("GET", parcelPath(reference, "/market"), { query: { country: options.country } });
286
+ }
287
+ async score(reference, options = {}) {
288
+ return this.client.request("GET", parcelPath(reference, "/score"), { query: { country: options.country } });
289
+ }
290
+ async valueHistory(reference, options = {}) {
291
+ return this.client.request("GET", parcelPath(reference, "/value-history"), {
292
+ query: { country: options.country }
293
+ });
294
+ }
295
+ async compare(parcels) {
296
+ if (parcels.length < MIN_COMPARE || parcels.length > MAX_COMPARE) {
297
+ throw new CatastroGPSError(`compare takes ${MIN_COMPARE} or ${MAX_COMPARE} parcels`);
298
+ }
299
+ const parcelas = parcels.map((parcel) => {
300
+ if (!parcel.reference?.trim()) throw new CatastroGPSError("reference must not be empty");
301
+ if (!ENRICHMENT_COUNTRY_CODES.includes(parcel.country)) {
302
+ throw new CatastroGPSError(`country must be one of ${ENRICHMENT_COUNTRY_CODES.join(", ")}`);
303
+ }
304
+ return { ref_catastral: parcel.reference.trim(), country: parcel.country };
305
+ });
306
+ return this.client.request("POST", "/api/catastro/compare", { body: { parcelas } });
307
+ }
181
308
  };
309
+ function locatedQuery(options) {
310
+ const hasLat = options.lat !== void 0;
311
+ const hasLng = options.lng !== void 0;
312
+ if (hasLat !== hasLng) throw new CatastroGPSError("lat and lng go together");
313
+ if (hasLat && (!Number.isFinite(options.lat) || !Number.isFinite(options.lng))) {
314
+ throw new CatastroGPSError("lat and lng must be finite numbers");
315
+ }
316
+ return { country: options.country, lat: options.lat, lng: options.lng };
317
+ }
182
318
  function parcelPath(reference, suffix = "") {
183
319
  if (!reference.trim()) throw new CatastroGPSError("reference must not be empty");
184
320
  return `/api/catastro/${encodeURIComponent(reference.trim())}${suffix}`;
@@ -196,6 +332,7 @@ var FincasResource = class {
196
332
  if (!params.q?.trim() && !params.street?.trim()) throw new CatastroGPSError("q or street is required");
197
333
  return this.client.request("GET", "/api/search/address/candidates", {
198
334
  query: {
335
+ country: params.country,
199
336
  q: params.q?.trim(),
200
337
  street: params.street?.trim(),
201
338
  number: params.number,
@@ -212,7 +349,7 @@ var FincasResource = class {
212
349
  for (let count = 0; count < MAX_PAGES; count += 1) {
213
350
  const previous = previousByCursor.get(cursor ?? "");
214
351
  const response = await this.client.conditionalRequest("GET", path, {
215
- query: { cursor },
352
+ query: { cursor, country: options.country },
216
353
  ifNoneMatch: previous?.etag
217
354
  });
218
355
  const data = response.notModified && previous ? previous.data : response.data;
@@ -250,7 +387,7 @@ var FincasResource = class {
250
387
  };
251
388
 
252
389
  // src/version.ts
253
- var VERSION = "1.1.0";
390
+ var VERSION = "1.2.0";
254
391
 
255
392
  // src/client.ts
256
393
  var DEFAULT_BASE_URL = "https://api.catastrogps.es";
@@ -345,17 +482,22 @@ var CatastroGPS = class {
345
482
  } finally {
346
483
  clearTimeout(timer);
347
484
  }
348
- this.captureQuota(response.headers);
485
+ const quota = this.captureQuota(response.headers);
349
486
  const etag = response.headers.get("ETag") ?? void 0;
350
- if (response.status === NOT_MODIFIED) return { etag: etag ?? options.ifNoneMatch, notModified: true };
487
+ if (response.status === NOT_MODIFIED) return { etag: etag ?? options.ifNoneMatch, notModified: true, quota };
351
488
  if (!response.ok) {
352
489
  const body2 = await readJson(response);
353
490
  const retryAfter = Number(response.headers.get("Retry-After"));
354
- throw errorFromResponse(response.status, body2, Number.isFinite(retryAfter) && retryAfter > 0 ? retryAfter : void 0);
491
+ throw errorFromResponse(
492
+ response.status,
493
+ body2,
494
+ Number.isFinite(retryAfter) && retryAfter > 0 ? retryAfter : void 0,
495
+ readQuota(response.headers)
496
+ );
355
497
  }
356
- if (options.raw) return { data: await response.arrayBuffer(), etag, notModified: false };
498
+ if (options.raw) return { data: await response.arrayBuffer(), etag, notModified: false, quota };
357
499
  const body = await readJson(response);
358
- return { data: "data" in body ? body.data : body, etag, notModified: false };
500
+ return { data: "data" in body ? body.data : body, etag, notModified: false, quota };
359
501
  }
360
502
  buildUrl(path, query) {
361
503
  const url = new URL(`${this.baseUrl}${path}`);
@@ -379,20 +521,47 @@ var CatastroGPS = class {
379
521
  captureQuota(headers) {
380
522
  const quota = readQuota(headers);
381
523
  if (quota) this.lastQuota = quota;
524
+ return quota;
382
525
  }
383
526
  };
384
527
  function readQuota(headers) {
385
- const plan = headers.get("X-Quota-Tier") ?? void 0;
386
- const family = headers.has("X-Quota-Limit") ? "X-Quota" : plan ? "X-RateLimit" : void 0;
387
- if (!family) return void 0;
388
- const limit = headers.get(`${family}-Limit`);
389
- const remaining = headers.get(`${family}-Remaining`);
390
- return {
391
- plan,
392
- limit: limit === null ? void 0 : Number(limit),
393
- remaining: remaining === null ? void 0 : Number(remaining),
394
- resetsAt: headers.get(`${family}-Reset`) ?? void 0
395
- };
528
+ const quota = {};
529
+ const plan = headers.get("X-Quota-Tier");
530
+ if (plan !== null) quota.plan = plan;
531
+ const limit = numberHeader(headers, "X-Quota-Limit");
532
+ if (limit !== void 0) quota.limit = limit;
533
+ const remaining = numberHeader(headers, "X-Quota-Remaining");
534
+ if (remaining !== void 0) quota.remaining = remaining;
535
+ const resetsAt = headers.get("X-Quota-Reset");
536
+ if (resetsAt !== null) quota.resetsAt = resetsAt;
537
+ if (headers.get("X-Quota-Overage")?.toLowerCase() === "on") {
538
+ quota.overage = {
539
+ enabled: true,
540
+ balance: numberHeader(headers, "X-Quota-Balance"),
541
+ unitPrice: numberHeader(headers, "X-Quota-Overage-Unit-Price"),
542
+ remainingUnits: numberHeader(headers, "X-Quota-Overage-Remaining")
543
+ };
544
+ }
545
+ if (headers.has("X-RateLimit-Limit") || headers.has("X-RateLimit-Remaining")) {
546
+ quota.rateLimit = {
547
+ limit: numberHeader(headers, "X-RateLimit-Limit"),
548
+ remaining: numberHeader(headers, "X-RateLimit-Remaining"),
549
+ resetSeconds: numberHeader(headers, "X-RateLimit-Reset")
550
+ };
551
+ }
552
+ if (headers.has("X-Quota-Finca-Cap")) {
553
+ quota.fincaCap = {
554
+ cap: numberHeader(headers, "X-Quota-Finca-Cap"),
555
+ used: numberHeader(headers, "X-Quota-Finca-Cap-Used")
556
+ };
557
+ }
558
+ return Object.keys(quota).length > 0 ? quota : void 0;
559
+ }
560
+ function numberHeader(headers, name) {
561
+ const raw = headers.get(name);
562
+ if (raw === null || raw.trim() === "") return void 0;
563
+ const value = Number(raw);
564
+ return Number.isFinite(value) ? value : void 0;
396
565
  }
397
566
  async function readJson(response) {
398
567
  try {
@@ -409,44 +578,9 @@ function readEnv(name) {
409
578
  function sleep(ms) {
410
579
  return new Promise((resolve) => setTimeout(resolve, ms));
411
580
  }
412
-
413
- // src/types.ts
414
- var COUNTRY_CODES = [
415
- "ES",
416
- "PV",
417
- "NA",
418
- "PT",
419
- "FR",
420
- "IT",
421
- "DE",
422
- "AT",
423
- "CH",
424
- "LI",
425
- "BE",
426
- "NL",
427
- "LU",
428
- "PL",
429
- "CZ",
430
- "SK",
431
- "SI",
432
- "HR",
433
- "BG",
434
- "GR",
435
- "CY",
436
- "DK",
437
- "SE",
438
- "NO",
439
- "FI",
440
- "IS",
441
- "EE",
442
- "LV",
443
- "LT",
444
- "IE",
445
- "UK"
446
- ];
447
- var ENRICHMENT_COUNTRY_CODES = ["ES", "PV", "NA", "PT", "FR", "IT", "DE"];
448
581
  // Annotate the CommonJS export names for ESM import in node:
449
582
  0 && (module.exports = {
583
+ ADDRESS_COUNTRY_CODES,
450
584
  AmbiguousReferenceError,
451
585
  AuthenticationError,
452
586
  COUNTRY_CODES,
@@ -460,11 +594,14 @@ var ENRICHMENT_COUNTRY_CODES = ["ES", "PV", "NA", "PT", "FR", "IT", "DE"];
460
594
  ForbiddenError,
461
595
  NetworkError,
462
596
  NotFoundError,
597
+ PlaceNameError,
463
598
  QuotaExceededError,
464
599
  RateLimitError,
465
600
  ServerError,
466
601
  ServiceUnavailableError,
467
602
  TimeoutError,
603
+ UNITS_COUNTRY_CODES,
468
604
  VERSION,
469
- ValidationError
605
+ ValidationError,
606
+ readQuota
470
607
  });