Popsicle Content Encoding Middleware

raw JSON →
1.0.0 verified Thu Apr 23 auth: no javascript

This package, `popsicle-content-encoding`, provides a specialized middleware for the `Popsicle` HTTP client library, designed to transparently manage HTTP `Content-Encoding` compression and decompression. Currently at its initial stable release, version `1.0.0`, it emerged from the core `popsicle` project to offer a modular solution for handling content negotiation. The middleware automatically detects and adds appropriate `Accept-Encoding` headers to outgoing requests based on the Node.js runtime's supported compression algorithms (e.g., gzip, deflate, brotli). Upon receiving a response, it automatically decodes the body if a matching `Content-Encoding` header is present, simplifying client-side data handling. A key differentiator is its seamless integration within the `servie` and `popsicle` middleware composition pattern, abstracting away the complexities of manual compression negotiation and decompression. It operates passively if `Accept-Encoding` is already defined, allowing for manual override when necessary. Its release cadence is currently tied to user feedback and the broader `serviejs` ecosystem, with `1.0.0` marking its first standalone stable version.

error Error: Cannot find module 'servie'
cause The required peer dependency `servie` is not installed in the project.
fix
Install servie using your package manager: npm install servie@^4.0.0 or yarn add servie@^4.0.0.
error TypeError: Cannot destructure property 'contentEncoding' of 'undefined' or 'null'.
cause Attempting to `require` a named export from `popsicle-content-encoding` in a CommonJS context without proper destructuring, or when the module itself might not be correctly interpreted as CommonJS.
fix
Ensure you are using const { contentEncoding } = require('popsicle-content-encoding'); for CommonJS. For ESM, use import { contentEncoding } from 'popsicle-content-encoding';.
error TypeError: request.send is not a function
cause The `popsicle` request object does not have a `.send()` method because the necessary transport middleware (e.g., `servie-http`) was not included or correctly composed in the middleware chain.
fix
Ensure servie-http (or another servie-compatible transport) is installed and included at the end of your middleware compose array, e.g., compose([contentEncoding(), transport()]).
breaking The `popsicle-content-encoding` functionality, previously integrated directly into `popsicle` core, has been extracted into this standalone package. Applications upgrading from older `popsicle` versions that relied on implicit content encoding will need to explicitly install and include this middleware in their request pipelines.
fix Install `popsicle-content-encoding` via `npm install popsicle-content-encoding` and add `contentEncoding()` to your Popsicle middleware chain (e.g., `compose([contentEncoding(), transport()])`).
gotcha This package has a peer dependency on `servie` (version `^4.0.0`), which is not automatically installed by npm or yarn. Failure to install `servie` will result in runtime errors due to missing modules or type definitions.
fix Ensure `servie` is installed alongside this package: `npm install servie@^4.0.0` or `yarn add servie@^4.0.0`.
gotcha The `contentEncoding` middleware will not modify the `Accept-Encoding` header or perform decoding if an `Accept-Encoding` header is already present in the request. This behavior allows for manual control but can be a source of confusion if automatic handling is expected.
fix If automatic `Accept-Encoding` population is desired, ensure the header is not manually set *before* the `contentEncoding` middleware runs. To override the automatic behavior, explicitly set `Accept-Encoding` in your request headers.
npm install popsicle-content-encoding
yarn add popsicle-content-encoding
pnpm add popsicle-content-encoding

This quickstart demonstrates how to integrate `popsicle-content-encoding` into a Popsicle request pipeline, showing how to configure its `Options` to control `Content-Encoding` negotiation and decompression for HTTP requests.

import { compose } from 'servie';
import popsicle from 'popsicle'; // popsicle is typically a default export
import { transport } from 'servie-http'; // Common transport for servie/popsicle
import { contentEncoding, Options } from 'popsicle-content-encoding'; // Import Options

async function fetchDataWithCompression() {
  const API_URL = 'https://jsonplaceholder.typicode.com/posts/1'; // A public API for demonstration

  // Configure contentEncoding middleware with specific options
  // For example, to explicitly enable gzip and brotli, or disable certain types.
  const encodingOptions: Options = {
    gzip: true,
    brotli: true,
    deflate: false, // Explicitly disable deflate for this request
  };

  // Compose the middleware pipeline: contentEncoding first to handle headers, then transport
  const requestMiddleware = compose([
    contentEncoding(encodingOptions), // Pass the configuration options
    transport()
  ]);

  const request = popsicle(API_URL, {
    method: 'GET',
    middleware: requestMiddleware, // Apply the composed middleware
  });

  try {
    const response = await request.send();
    console.log(`Status: ${response.status}`);
    const contentEncodingHeader = response.headers.get('Content-Encoding');
    console.log(`Content-Encoding Header (from response): ${contentEncodingHeader || 'N/A'}`);
    console.log(`Response URL: ${response.url}`);

    const data = await response.json(); // Body is automatically decoded by the middleware
    console.log('Decoded data snippet (first 100 chars):', JSON.stringify(data).substring(0, 100) + '...');

    if (typeof data === 'object' && data !== null) {
      console.log('Successfully decoded JSON response and processed.');
    } else {
      console.warn('Response body might not be JSON or was not correctly decoded by the middleware.');
    }
  } catch (error: any) {
    console.error('Error fetching data:', error.message);
  }
}

fetchDataWithCompression();