Socket
Socket
Sign inDemoInstall

cacheable-request

Package Overview
Dependencies
8
Maintainers
3
Versions
61
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 8.3.1 to 9.0.0

10

dist/index.d.ts

@@ -1,6 +0,10 @@

/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" resolution-mode="require"/>
/// <reference types="node" resolution-mode="require"/>
import EventEmitter from 'node:events';
declare const CacheableRequest: {
(request: Function, cacheAdapter?: any): (options: any, cb?: ((response: {}) => void) | undefined) => EventEmitter;
(request: Function, cacheAdapter?: any): (options: any, cb?: ((response: Record<string, unknown>) => void) | undefined) => EventEmitter;
addHook(name: string, fn: Function): void;
removeHook(name: string): boolean;
getHook(name: string): any;
runHook(name: string, response: any): Promise<any>;
RequestError: {

@@ -7,0 +11,0 @@ new (error: any): {

@@ -1,47 +0,20 @@

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const node_events_1 = __importDefault(require("node:events"));
const node_url_1 = __importDefault(require("node:url"));
const node_crypto_1 = __importDefault(require("node:crypto"));
const node_stream_1 = __importStar(require("node:stream"));
const normalize_url_1 = __importDefault(require("normalize-url"));
const get_stream_1 = __importDefault(require("get-stream"));
const http_cache_semantics_1 = __importDefault(require("http-cache-semantics"));
const responselike_1 = __importDefault(require("responselike"));
const keyv_1 = __importDefault(require("keyv"));
const mimic_response_1 = __importDefault(require("mimic-response"));
const { Readable } = node_stream_1.default;
import EventEmitter from 'node:events';
import urlLib from 'node:url';
import crypto from 'node:crypto';
import stream, { PassThrough as PassThroughStream } from 'node:stream';
import normalizeUrl from 'normalize-url';
import getStream from 'get-stream';
import CachePolicy from 'http-cache-semantics';
import Response from 'responselike';
import Keyv from 'keyv';
import mimicResponse from 'mimic-response';
const hooks = new Map();
// eslint-disable-next-line @typescript-eslint/naming-convention
const CacheableRequest = function (request, cacheAdapter) {
let cache = {};
if (cacheAdapter instanceof keyv_1.default) {
if (cacheAdapter instanceof Keyv) {
cache = cacheAdapter;
}
else {
cache = new keyv_1.default({
cache = new Keyv({
uri: (typeof cacheAdapter === 'string' && cacheAdapter) || '',

@@ -58,7 +31,7 @@ store: typeof cacheAdapter !== 'string' && cacheAdapter,

if (typeof options === 'string') {
url = normalizeUrlObject(node_url_1.default.parse(options));
url = normalizeUrlObject(urlLib.parse(options));
options = {};
}
else if (options instanceof node_url_1.default.URL) {
url = normalizeUrlObject(node_url_1.default.parse(options.toString()));
else if (options instanceof urlLib.URL) {
url = normalizeUrlObject(urlLib.parse(options.toString()));
options = {};

@@ -83,4 +56,4 @@ }

options.headers = Object.fromEntries(Object.entries(options.headers).map(([key, value]) => [key.toLowerCase(), value]));
const ee = new node_events_1.default();
const normalizedUrlString = (0, normalize_url_1.default)(node_url_1.default.format(url), {
const ee = new EventEmitter();
const normalizedUrlString = normalizeUrl(urlLib.format(url), {
stripWWW: false,

@@ -95,3 +68,3 @@ removeTrailingSlash: false,

if (options.body && ['POST', 'PATCH', 'PUT'].includes(options.method)) {
if (options.body instanceof Readable) {
if (options.body instanceof stream.Readable) {
// Streamed bodies should completely skip the cache because they may

@@ -103,3 +76,3 @@ // or may not be hashable and in either case the stream would need to

else {
key += `:${node_crypto_1.default.createHash('md5').update(options.body).digest('hex')}`;
key += `:${crypto.createHash('md5').update(options.body).digest('hex')}`;
}

@@ -122,8 +95,8 @@ }

const handler = (response) => {
if (revalidate && !options_.forceRefresh) {
if (revalidate) {
response.status = response.statusCode;
const revalidatedPolicy = http_cache_semantics_1.default.fromObject(revalidate.cachePolicy).revalidatedPolicy(options_, response);
const revalidatedPolicy = CachePolicy.fromObject(revalidate.cachePolicy).revalidatedPolicy(options_, response);
if (!revalidatedPolicy.modified) {
const headers = revalidatedPolicy.policy.responseHeaders();
response = new responselike_1.default(revalidate.statusCode, headers, revalidate.body, revalidate.url);
const headers = convertHeaders(revalidatedPolicy.policy.responseHeaders());
response = new Response({ statusCode: revalidate.statusCode, headers, body: revalidate.body, url: revalidate.url });
response.cachePolicy = revalidatedPolicy.policy;

@@ -134,3 +107,3 @@ response.fromCache = true;

if (!response.fromCache) {
response.cachePolicy = new http_cache_semantics_1.default(options_, response, options_);
response.cachePolicy = new CachePolicy(options_, response, options_);
response.fromCache = false;

@@ -143,3 +116,3 @@ }

try {
const bodyPromise = get_stream_1.default.buffer(response);
const bodyPromise = getStream.buffer(response);
await Promise.race([

@@ -160,2 +133,9 @@ requestErrorPromise,

}
if (hooks.size > 0) {
/* eslint-disable no-await-in-loop */
for (const key_ of hooks.keys()) {
value.body = await CacheableRequest.runHook(key_, value.body);
}
/* eslint-enable no-await-in-loop */
}
await cache.set(key, value, ttl);

@@ -197,10 +177,10 @@ }

const cacheEntry = options_.cache ? await cache.get(key) : undefined;
if (typeof cacheEntry === 'undefined') {
if (typeof cacheEntry === 'undefined' && !options_.forceRefresh) {
makeRequest(options_);
return;
}
const policy = http_cache_semantics_1.default.fromObject(cacheEntry.cachePolicy);
const policy = CachePolicy.fromObject(cacheEntry.cachePolicy);
if (policy.satisfiesWithoutRevalidation(options_) && !options_.forceRefresh) {
const headers = policy.responseHeaders();
const response = new responselike_1.default(cacheEntry.statusCode, headers, cacheEntry.body, cacheEntry.url);
const headers = convertHeaders(policy.responseHeaders());
const response = new Response({ statusCode: cacheEntry.statusCode, headers, body: cacheEntry.body, url: cacheEntry.url });
response.cachePolicy = policy;

@@ -213,2 +193,7 @@ response.fromCache = true;

}
else if (policy.satisfiesWithoutRevalidation(options_) && Date.now() >= policy.timeToLive() && options_.forceRefresh) {
await cache.delete(key);
options_.headers = policy.revalidationHeaders(options_);
makeRequest(options_);
}
else {

@@ -236,5 +221,18 @@ revalidate = cacheEntry;

}
CacheableRequest.addHook = (name, fn) => {
if (!hooks.has(name)) {
hooks.set(name, fn);
}
};
CacheableRequest.removeHook = (name) => hooks.delete(name);
CacheableRequest.getHook = (name) => hooks.get(name);
CacheableRequest.runHook = async (name, response) => {
if (!response) {
return new CacheableRequest.CacheError(new Error('runHooks requires response argument'));
}
return hooks.get(name)(response);
};
function cloneResponse(response) {
const clone = new node_stream_1.PassThrough({ autoDestroy: false });
(0, mimic_response_1.default)(response, clone);
const clone = new PassThroughStream({ autoDestroy: false });
mimicResponse(response, clone);
return response.pipe(clone);

@@ -266,2 +264,9 @@ }

}
function convertHeaders(headers) {
const result = {};
for (const name of Object.keys(headers)) {
result[name.toLowerCase()] = headers[name];
}
return result;
}
CacheableRequest.RequestError = class extends Error {

@@ -281,3 +286,3 @@ constructor(error) {

};
exports.default = CacheableRequest;
export default CacheableRequest;
//# sourceMappingURL=index.js.map
{
"name": "cacheable-request",
"version": "8.3.1",
"version": "9.0.0",
"description": "Wrap native HTTP requests with RFC compliant cache support",

@@ -8,3 +8,4 @@ "license": "MIT",

"author": "Jared Wray <me@jaredwray.com> (http://jaredwray.com)",
"main": "./dist/index.js",
"type": "module",
"exports": "./dist/index.js",
"types": "./dist/index.d.ts",

@@ -15,3 +16,3 @@ "engines": {

"scripts": {
"test": "xo && jest --coverage",
"test": "xo && NODE_OPTIONS=--experimental-vm-modules jest --coverage ",
"build": "tsc --project tsconfig.build.json",

@@ -38,11 +39,9 @@ "clean": "rm -rf node_modules && rm -rf ./coverage && rm -rf ./package-lock.json && rm -rf ./test/testdb.sqlite && rm -rf ./dist"

"http-cache-semantics": "^4.1.0",
"keyv": "^4.3.2",
"mimic-response": "^3.1.0",
"normalize-url": "^6.0.3",
"responselike": "^2.0.0"
"keyv": "^4.3.3",
"mimic-response": "^4.0.0",
"normalize-url": "^7.0.3",
"responselike": "^3.0.0"
},
"devDependencies": {
"@babel/core": "^7.18.5",
"@babel/preset-env": "^7.18.2",
"@keyv/sqlite": "^3.5.2",
"@keyv/sqlite": "^3.5.3",
"@types/create-test-server": "^3.0.1",

@@ -52,4 +51,4 @@ "@types/delay": "^3.1.0",

"@types/http-cache-semantics": "^4.0.1",
"@types/jest": "^28.1.3",
"@types/node": "^18.0.0",
"@types/jest": "^28.1.6",
"@types/node": "^18.7.3",
"@types/pify": "^5.0.1",

@@ -59,16 +58,22 @@ "@types/responselike": "^1.0.0",

"create-test-server": "3.0.1",
"eslint-plugin-jest": "^26.5.3",
"delay": "^5.0.0",
"jest": "^28.1.1",
"pify": "^5.0.0",
"sqlite3": "^5.0.8",
"ts-jest": "^28.0.5",
"ts-node": "^10.8.1",
"eslint-plugin-jest": "^26.8.2",
"jest": "^28.1.3",
"pify": "^6.0.0",
"sqlite3": "^5.0.11",
"ts-jest": "^28.0.7",
"ts-jest-resolver": "^2.0.0",
"ts-node": "^10.9.1",
"typescript": "^4.7.4",
"xo": "^0.50.0"
"xo": "^0.51.0"
},
"jest": {
"extensionsToTreatAsEsm": [
".ts"
],
"resolver": "ts-jest-resolver",
"globals": {
"ts-jest": {
"tsconfig": "./tsconfig.json"
"tsconfig": "./tsconfig.build.json",
"useESM": true
}

@@ -96,4 +101,2 @@ },

"rules": {
"@typescript-eslint/object-curly-spacing": 0,
"@typescript-eslint/naming-convention": 0,
"@typescript-eslint/no-unsafe-assignment": 0,

@@ -105,8 +108,5 @@ "@typescript-eslint/no-unsafe-call": 0,

"new-cap": 0,
"@typescript-eslint/no-empty-function": 0,
"@typescript-eslint/restrict-plus-operands": 0,
"@typescript-eslint/no-floating-promises": 0,
"@typescript-eslint/await-thenable": 0
"@typescript-eslint/restrict-plus-operands": 0
}
}
}

@@ -14,2 +14,7 @@ # cacheable-request

## ESM Support in version 9 and higher.
We are now using pure esm support in our package. If you need to use commonjs you can use v8 or lower. To learn more about using ESM please read this from `sindresorhus`: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
## Features

@@ -203,2 +208,23 @@

## Add Hooks
The hook will pre compute response right before saving it in cache. You can include many hooks and it will run in order you add hook on response object.
```js
CacheableRequest.addHook('response', async (response: any) => {
const buffer = await pm(gunzip)(response);
return buffer.toString();
});
const cacheableRequest = CacheableRequest(request, cache);
```
## Remove Hooks
You can also remove hook by using below
```js
CacheableRequest.removeHook('response');
```
**Note:** Database connection errors are emitted here, however `cacheable-request` will attempt to re-request the resource and bypass the cache on a connection error. Therefore a database connection error doesn't necessarily mean the request won't be fulfilled.

@@ -205,0 +231,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc