<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Swapnil Srivastava</title>
    <description>The latest articles on DEV Community by Swapnil Srivastava (@swapniluneva).</description>
    <link>https://dev.to/swapniluneva</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4050576%2F9a375594-ef73-4333-b795-921d07ced92d.jpg</url>
      <title>DEV Community: Swapnil Srivastava</title>
      <link>https://dev.to/swapniluneva</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/swapniluneva"/>
    <language>en</language>
    <item>
      <title>Is Your Node.js App Vulnerable to SSRF? Secure Axios &amp; Fetch in 5 Minutes</title>
      <dc:creator>Swapnil Srivastava</dc:creator>
      <pubDate>Tue, 28 Jul 2026 05:42:41 +0000</pubDate>
      <link>https://dev.to/swapniluneva/is-your-nodejs-app-vulnerable-to-ssrf-secure-axios-fetch-in-5-minutes-46of</link>
      <guid>https://dev.to/swapniluneva/is-your-nodejs-app-vulnerable-to-ssrf-secure-axios-fetch-in-5-minutes-46of</guid>
      <description>&lt;p&gt;If your Node.js application accepts user-supplied URLs—whether you are building a webhook system, a link preview feature, or a file uploader—you might be wide open to &lt;strong&gt;Server-Side Request Forgery (SSRF)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Most developers think a quick regex check to block &lt;code&gt;localhost&lt;/code&gt; or &lt;code&gt;127.0.0.1&lt;/code&gt; makes them safe. &lt;/p&gt;

&lt;p&gt;It doesn't. &lt;/p&gt;

&lt;p&gt;An attacker can easily bypass standard string-matching filters using advanced exploitation techniques:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;DNS Rebinding:&lt;/strong&gt; Setting up a custom domain that resolves to a safe public IP on the first lookup (passing your validation) but resolves to a local IP on the second lookup (when your app actually executes the &lt;code&gt;fetch&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Metadata Exploitation:&lt;/strong&gt; Accessing internal cloud provider endpoints like AWS IMDSv2 (&lt;code&gt;169.254.169.254&lt;/code&gt;) to steal IAM roles, API tokens, and infrastructure credentials.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Internal Subnet Scanning:&lt;/strong&gt; Forcing your server to act as a proxy to probe private company microservices (&lt;code&gt;10.0.0.0/8&lt;/code&gt; or &lt;code&gt;192.168.0.0/16&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To solve this problem comprehensively at the network runtime layer, I built &lt;strong&gt;&lt;code&gt;ssrf-agent-guard&lt;/code&gt;&lt;/strong&gt;—a lightweight, defensive TypeScript module that hardens &lt;code&gt;http.Agent&lt;/code&gt; and &lt;code&gt;https.Agent&lt;/code&gt; against runtime exploits.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔒 Deep Protection via Custom Network Agents
&lt;/h2&gt;

&lt;p&gt;Instead of trying to sanitize unsafe string inputs, &lt;code&gt;ssrf-agent-guard&lt;/code&gt; intercepts requests during the actual network cycle. It executes pre-and-post DNS resolution host checks, ensuring your application never communicates with a forbidden destination.&lt;/p&gt;

&lt;p&gt;Here is how easily it drops right into &lt;strong&gt;Axios&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ssrfAgentGuard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ssrf-agent-guard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;unsafeUserUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://169.254.169&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;unsafeUserUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Automatically intercept and abort before connections are established&lt;/span&gt;
  &lt;span class="na"&gt;httpAgent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ssrfAgentGuard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;unsafeUserUrl&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;httpsAgent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ssrfAgentGuard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;unsafeUserUrl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Blocked Securely:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works exactly the same way with native &lt;strong&gt;&lt;code&gt;fetch&lt;/code&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;code&gt;node-fetch&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;unsafeUserUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ssrfAgentGuard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;unsafeUserUrl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🛡️ Core Security Capabilities
&lt;/h2&gt;

&lt;p&gt;This package abstracts away complex networking logic into clean, production-grade defenses:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Cloud Provider Metadata Detection
&lt;/h3&gt;

&lt;p&gt;It blocks explicit access to cloud environment endpoints across all major infrastructure systems, covering AWS, Google Cloud Platform (GCP), Microsoft Azure, Oracle Cloud, DigitalOcean, and Kubernetes clusters.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Built-in DNS Rebinding Mitigation
&lt;/h3&gt;

&lt;p&gt;The agent evaluates the resolved IP addresses right before a socket connection opens. If a malicious domain attempts to switch its resolution from a public address to a restricted internal IP post-validation, the module catches the shift and terminates the request immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Policy-Based Domain Filtering
&lt;/h3&gt;

&lt;p&gt;You can configure explicit access rules using strict allowlists, denylists, and top-level domain (TLD) blocking architectures:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ssrfAgentGuard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;block&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;              &lt;span class="c1"&gt;// Options: 'block' | 'report' | 'allow'&lt;/span&gt;
  &lt;span class="na"&gt;detectDnsRebinding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;// Kill time-of-check to time-of-use exploits&lt;/span&gt;
  &lt;span class="na"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;allowDomains&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;*.trustedpartners.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; 
    &lt;span class="na"&gt;denyDomains&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;untrusted-source.evil&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; 
    &lt;span class="na"&gt;denyTLD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;local&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;internal&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lan&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; 
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📊 Flexible Operation Modes
&lt;/h2&gt;

&lt;p&gt;Securing a legacy system can be intimidating. &lt;code&gt;ssrf-agent-guard&lt;/code&gt; includes multiple operation modes so you can safely gauge its impact before turning on enforcement:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;block&lt;/code&gt;&lt;/strong&gt;: The default defensive state. Dropping malicious requests instantly.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;report&lt;/code&gt;&lt;/strong&gt;: A passive observational mode. It logs violations via a custom handler so you can trace vulnerabilities in your production traffic without breaking current user loops.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;allow&lt;/code&gt;&lt;/strong&gt;: Bypasses restrictions entirely for specialized debugging environments.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠️ Fully Typed and Production-Tested
&lt;/h2&gt;

&lt;p&gt;The engine is authored completely in TypeScript, bringing full autocompletion support to your IDE. It ships with ready-made architecture guides and implementation examples for major modern web frameworks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Express.js&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Fastify&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;NestJS&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stop leaving your backend servers open to simple network manipulation. Drop the agent guard into your network configuration stack today:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;ssrf-agent-guard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check out the full security rationale breakdown, read the list of globally restricted IP blocks, and join the development over on GitHub:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://github.com/swapniluneva/ssrf-agent-guard" rel="noopener noreferrer"&gt;GitHub: swapniluneva/ssrf-agent-guard&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;How is your team currently validating outgoing webhooks or link generation requests? Let's discuss security best practices in the comments below!&lt;/p&gt;

</description>
      <category>node</category>
      <category>security</category>
      <category>typescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Stop Writing Boilerplate API Pagination Loops: Meet lazy-api-paginator</title>
      <dc:creator>Swapnil Srivastava</dc:creator>
      <pubDate>Tue, 28 Jul 2026 05:40:49 +0000</pubDate>
      <link>https://dev.to/swapniluneva/stop-writing-boilerplate-api-pagination-loops-meet-lazy-api-paginator-nha</link>
      <guid>https://dev.to/swapniluneva/stop-writing-boilerplate-api-pagination-loops-meet-lazy-api-paginator-nha</guid>
      <description>&lt;p&gt;We have all written this exact chunk of boilerplate code at least a dozen times:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;nextUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allItems&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextUrl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;allItems&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;nextUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next_page_url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It looks simple, but this naive implementation breaks instantly in production. &lt;/p&gt;

&lt;p&gt;What happens when the API hits you with a &lt;code&gt;429 Too Many Requests&lt;/code&gt; error? Your script crashes. What if the dataset contains 500,000 records? Your server runs out of RAM, triggers a memory leak, and throws an &lt;code&gt;Out of Memory&lt;/code&gt; panic. What if the API requires cursor, keyset, or Link-header pagination? You are back to rewiring custom loops from scratch.&lt;/p&gt;

&lt;p&gt;To solve this once and for all, I built &lt;strong&gt;&lt;code&gt;lazy-api-paginator&lt;/code&gt;&lt;/strong&gt;—a lightweight, zero-dependency TypeScript engine designed to stream paginated API data seamlessly using async generators.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 The Core Solution: Lazy Async Data Streams
&lt;/h2&gt;

&lt;p&gt;Instead of pulling thousands of items into local memory before processing them, &lt;code&gt;lazy-api-paginator&lt;/code&gt; fetches pages dynamically on-demand. It yields items &lt;strong&gt;one-by-one&lt;/strong&gt; using native JavaScript &lt;code&gt;for await...of&lt;/code&gt; loops.&lt;/p&gt;

&lt;p&gt;Here is how simple a basic integration looks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createPaginator&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lazy-api-paginator&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;paginator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createPaginator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ApiResponse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;initialUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;extractItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;getNextPageUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nextCursor&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;`https://example.com?cursor=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nextCursor&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Memory consumption remains constant, no matter how large the API dataset is!&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;await &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;paginator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Processing: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🛠️ Production-Ready Features Built-In
&lt;/h2&gt;

&lt;p&gt;This isn't just a wrapper around &lt;code&gt;fetch&lt;/code&gt;. It includes the mission-critical safeguards that production environments demand:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Smart Rate Limiting &amp;amp; 429 Handling
&lt;/h3&gt;

&lt;p&gt;The paginator automatically throttles outward requests to match a target rate limit. If it encounters a &lt;code&gt;429&lt;/code&gt; status code, it intelligently parses standard &lt;code&gt;Retry-After&lt;/code&gt;, &lt;code&gt;X-RateLimit-*&lt;/code&gt;, or &lt;code&gt;RateLimit-*&lt;/code&gt; headers to pause execution before gracefully retrying.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;rateLimit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;requestsPerSecond&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="c1"&gt;// Throttles requests safely&lt;/span&gt;
  &lt;span class="nx"&gt;respectRetryAfter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;// Automatically honors API headers&lt;/span&gt;
  &lt;span class="nx"&gt;maxRateLimitDelay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60000&lt;/span&gt;     &lt;span class="c1"&gt;// Maximum wait cap&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Exponential Backoff with Jitter
&lt;/h3&gt;

&lt;p&gt;Network blips happen. The library includes built-in exponential backoff configuration complete with configurable randomness (jitter) to ensure your microservices do not accidentally DDoS your target API endpoints when recovering from a downtime window.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Server-Side Request Forgery (SSRF) Protection
&lt;/h3&gt;

&lt;p&gt;If you are passing user-submitted URLs into your backend API integrations, you are exposing yourself to internal network scanning vulnerabilities. &lt;code&gt;lazy-api-paginator&lt;/code&gt; provides an optional, pluggable &lt;code&gt;ssrfProtection&lt;/code&gt; layer to lock down server-to-server calls away from internal cloud metadata instances (&lt;code&gt;169.254.169.254&lt;/code&gt;) and local subnets.&lt;/p&gt;




&lt;h2&gt;
  
  
  📦 Zero Boilerplate Templates for Common APIs
&lt;/h2&gt;

&lt;p&gt;Different platforms use completely different pagination mental models. The package ships with ready-to-use structural strategies to eliminate manual token plumbing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Cursor-based:&lt;/strong&gt; Out-of-the-box configurations mapping straight to the data schemas of &lt;strong&gt;Stripe, Slack, and Notion&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Link Headers:&lt;/strong&gt; Automatic header extraction custom-tailored for the &lt;strong&gt;GitHub REST API&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Page number-based:&lt;/strong&gt; Perfect for applications consuming default frameworks like &lt;strong&gt;Laravel&lt;/strong&gt; or &lt;strong&gt;Django&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Offset/Keyset Seek:&lt;/strong&gt; Highly optimized for traditional database pagination setups.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createPaginator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;strategies&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lazy-api-paginator&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Zero boilerplate pagination for GitHub Issues&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;githubPaginator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createPaginator&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;initialUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://github.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;strategies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;linkHeader&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;dataPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🌟 Open Source &amp;amp; Open to Feedback
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;lazy-api-paginator&lt;/code&gt; works out of the box in both modern ECMAScript Modules (ESM) and legacy CommonJS (CJS) environments with full, native TypeScript autocomplete types.&lt;/p&gt;

&lt;p&gt;If you are tired of writing fragile, memory-heavy &lt;code&gt;while&lt;/code&gt; loops every time you connect to an external API service, give it a spin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;lazy-api-paginator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check out the full documentation, lifecycle hooks guides, and feature roadmaps over on the GitHub repository:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://github.com" rel="noopener noreferrer"&gt;GitHub: swapniluneva/lazy-api-paginator&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I would love to hear your thoughts! What pagination patterns does your team run into most often? Let me know in the comments below!&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>node</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
