@eusilvio/cep-lookup 1.3.2 → 1.4.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
@@ -1,6 +1,6 @@
1
- import { Address, Fetcher, Provider, CepLookupOptions, BulkCepResult } from "./types";
1
+ import { Address, Fetcher, Provider, CepLookupOptions, BulkCepResult, RateLimitOptions } from "./types";
2
2
  import { Cache, InMemoryCache } from "./cache";
3
- export { Address, Fetcher, Provider, CepLookupOptions, Cache, InMemoryCache, BulkCepResult };
3
+ export { Address, Fetcher, Provider, CepLookupOptions, Cache, InMemoryCache, BulkCepResult, RateLimitOptions };
4
4
  /**
5
5
  * @class CepLookup
6
6
  * @description A class for looking up Brazilian postal codes (CEPs) using multiple providers.
@@ -10,11 +10,14 @@ export declare class CepLookup {
10
10
  private providers;
11
11
  private fetcher;
12
12
  private cache?;
13
+ private rateLimit?;
14
+ private requestTimestamps;
13
15
  /**
14
16
  * @constructor
15
17
  * @param {CepLookupOptions} options - The options for initializing the CepLookup instance.
16
18
  */
17
19
  constructor(options: CepLookupOptions);
20
+ private checkRateLimit;
18
21
  /**
19
22
  * @method lookup
20
23
  * @description Looks up an address for a given CEP.
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var v=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var k=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var C=(s,e)=>{for(var r in e)v(s,r,{get:e[r],enumerable:!0})},y=(s,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of k(e))!A.call(s,t)&&t!==r&&v(s,t,{get:()=>e[t],enumerable:!(n=w(e,t))||n.enumerable});return s};var P=s=>y(v({},"__esModule",{value:!0}),s);var x={};C(x,{CepLookup:()=>u,InMemoryCache:()=>p,lookupCep:()=>b,lookupCeps:()=>E});module.exports=P(x);var p=class{constructor(){this.cache=new Map}get(e){return this.cache.get(e)}set(e,r){this.cache.set(e,r)}clear(){this.cache.clear()}};function T(s){let e=s.replace(/\D/g,"");if(e.length!==8)throw new Error("Invalid CEP. It must have 8 digits.");return e}var u=class{constructor(e){this.providers=e.providers,this.fetcher=e.fetcher||(async(r,n)=>{let t=await fetch(r,{signal:n});if(!t.ok)throw new Error(`HTTP error! status: ${t.status}`);return t.json()}),this.cache=e.cache}async lookup(e,r){let n=T(e);if(this.cache){let o=this.cache.get(n);if(o)return Promise.resolve(r?r(o):o)}let t=new AbortController,{signal:i}=t,h=this.providers.map(o=>{let l=o.buildUrl(n),m=new Promise((c,d)=>{let a,g=()=>{clearTimeout(a),d(new DOMException("Aborted","AbortError"))};o.timeout?(a=setTimeout(()=>{i.removeEventListener("abort",g),d(new Error(`Timeout from ${o.name}`))},o.timeout),i.addEventListener("abort",g,{once:!0})):i.addEventListener("abort",g,{once:!0})}),f=this.fetcher(l,i).then(c=>o.transform(c)).then(c=>(this.cache&&this.cache.set(n,c),r?r(c):c));return Promise.race([f,m])});try{return await Promise.any(h)}finally{t.abort()}}};function b(s){let{cep:e,providers:r,fetcher:n,mapper:t,cache:i}=s;return new u({providers:r,fetcher:n,cache:i}).lookup(e,t)}async function E(s){let{ceps:e,providers:r,fetcher:n,cache:t,concurrency:i=5}=s;if(!e||e.length===0)return[];let h=new u({providers:r,fetcher:n,cache:t}),o=new Array(e.length),l=0,m=async()=>{for(;l<e.length;){let c=l++;if(c>=e.length)break;let d=e[c];try{let a=await h.lookup(d);if(a)o[c]={cep:d,data:a,provider:a.service};else throw new Error("No address found")}catch(a){o[c]={cep:d,data:null,error:a}}}},f=Array.from({length:Math.min(i,e.length)},()=>m());return await Promise.all(f),o.filter(Boolean)}0&&(module.exports={CepLookup,InMemoryCache,lookupCep,lookupCeps});
1
+ "use strict";var g=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var k=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var L=(r,e)=>{for(var t in e)g(r,t,{get:e[t],enumerable:!0})},y=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of k(e))!A.call(r,s)&&s!==t&&g(r,s,{get:()=>e[s],enumerable:!(i=v(e,s))||i.enumerable});return r};var T=r=>y(g({},"__esModule",{value:!0}),r);var x={};L(x,{CepLookup:()=>h,InMemoryCache:()=>m,lookupCep:()=>P,lookupCeps:()=>b});module.exports=T(x);var m=class{constructor(){this.cache=new Map}get(e){return this.cache.get(e)}set(e,t){this.cache.set(e,t)}clear(){this.cache.clear()}};function N(r){if(!/^(\d{8}|\d{5}-\d{3})$/.test(r))throw new Error("Invalid CEP format. Use either NNNNNNNN or NNNNN-NNN.");return r.replace("-","")}function C(r){let e={...r};for(let t in e)typeof e[t]=="string"&&(e[t]=e[t].trim());return e}var h=class{constructor(e){this.requestTimestamps=[];this.providers=e.providers,this.fetcher=e.fetcher||(async(t,i)=>{let s=await fetch(t,{signal:i});if(!s.ok)throw new Error(`HTTP error! status: ${s.status}`);return s.json()}),this.cache=e.cache,this.rateLimit=e.rateLimit}checkRateLimit(){if(!this.rateLimit)return;let e=Date.now(),t=e-this.rateLimit.per;if(this.requestTimestamps=this.requestTimestamps.filter(i=>i>t),this.requestTimestamps.length>=this.rateLimit.requests)throw new Error(`Rate limit exceeded: ${this.rateLimit.requests} requests per ${this.rateLimit.per}ms.`);this.requestTimestamps.push(e)}async lookup(e,t){this.checkRateLimit();let i=N(e);if(this.cache){let o=this.cache.get(i);if(o)return Promise.resolve(t?t(o):o)}let s=new AbortController,{signal:a}=s,u=this.providers.map(o=>{let p=o.buildUrl(i),l=new Promise((c,n)=>{let d,w=()=>{clearTimeout(d),n(new DOMException("Aborted","AbortError"))};o.timeout?(d=setTimeout(()=>{a.removeEventListener("abort",w),n(new Error(`Timeout from ${o.name}`))},o.timeout),a.addEventListener("abort",w,{once:!0})):a.addEventListener("abort",w,{once:!0})}),f=this.fetcher(p,a).then(c=>o.transform(c)).then(c=>{let n=C(c);return this.cache&&this.cache.set(i,n),t?t(n):n});return Promise.race([f,l])});try{return await Promise.any(u)}finally{s.abort()}}};function P(r){let{cep:e,providers:t,fetcher:i,mapper:s,cache:a}=r;return new h({providers:t,fetcher:i,cache:a}).lookup(e,s)}async function b(r){let{ceps:e,providers:t,fetcher:i,cache:s,concurrency:a=5}=r;if(!e||e.length===0)return[];let u=new h({providers:t,fetcher:i,cache:s}),o=new Array(e.length),p=0,l=async()=>{for(;p<e.length;){let c=p++;if(c>=e.length)break;let n=e[c];try{let d=await u.lookup(n);if(d)o[c]={cep:n,data:d,provider:d.service};else throw new Error("No address found")}catch(d){o[c]={cep:n,data:null,error:d}}}},f=Array.from({length:Math.min(a,e.length)},()=>l());return await Promise.all(f),o.filter(Boolean)}0&&(module.exports={CepLookup,InMemoryCache,lookupCep,lookupCeps});
package/dist/types.d.ts CHANGED
@@ -45,6 +45,17 @@ export interface CepLookupOptions {
45
45
  providers: Provider[];
46
46
  fetcher?: Fetcher;
47
47
  cache?: Cache;
48
+ rateLimit?: RateLimitOptions;
49
+ }
50
+ /**
51
+ * @interface RateLimitOptions
52
+ * @description Options for configuring the internal rate limiter.
53
+ * @property {number} requests - The maximum number of requests allowed within the time window.
54
+ * @property {number} per - The time window in milliseconds.
55
+ */
56
+ export interface RateLimitOptions {
57
+ requests: number;
58
+ per: number;
48
59
  }
49
60
  /**
50
61
  * @interface BulkCepResult
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@eusilvio/cep-lookup",
3
- "version": "1.3.2",
3
+ "version": "1.4.0",
4
4
  "description": "A modern, flexible, and agnostic CEP lookup library written in TypeScript.",
5
+ "license": "MIT",
5
6
  "repository": {
6
7
  "type": "git",
7
8
  "url": "git+https://github.com/eusilvio/cep-lookup.git"