New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

cacheability

Package Overview
Dependencies
Maintainers
1
Versions
109
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cacheability - npm Package Compare versions

Comparing version 3.0.2 to 4.0.0

dist/main/index.mjs

234

package.json
{
"name": "cacheability",
"version": "3.0.2",
"description": "A utility class to parse, store and print http cache headers.",
"author": "Dylan Aubrey <dylanaubrey@gmail.com>",
"version": "4.0.0",
"author": "Dylan Aubrey",
"license": "MIT",
"homepage": "https://github.com/bad-batch/cacheability",
"bugs": {
"url": "https://github.com/bad-batch/cacheability/issues"
"homepage": "https://github.com/badbatch/cacheability",
"repository": "badbatch/cacheability",
"bugs": "https://github.com/badbatch/cacheability/issues",
"type": "module",
"main": "./dist/main/index.mjs",
"types": "./dist/types/index.d.ts",
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/bad-batch/cacheability"
"peerDependencies": {
"@babel/runtime": "<8",
"core-js": "<4",
"lodash": "<5"
},
"engines": {
"node": "< 10.16.0"
"devDependencies": {
"@babel/cli": "^7.21.5",
"@babel/core": "^7.21.8",
"@babel/eslint-parser": "^7.21.8",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-proposal-export-namespace-from": "^7.18.9",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-syntax-import-assertions": "^7.20.0",
"@babel/plugin-transform-runtime": "^7.21.4",
"@babel/preset-env": "^7.21.5",
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.21.5",
"@babel/runtime": "^7.21.5",
"@commitlint/cli": "^17.6.3",
"@commitlint/config-conventional": "^17.6.3",
"@commitlint/prompt-cli": "^17.6.3",
"@jest/globals": "^29.5.0",
"@repodog/babel-config": "^1.1.4",
"@repodog/cli": "^1.1.5",
"@repodog/commitlint-config": "^1.1.4",
"@repodog/eslint-config": "^1.1.4",
"@repodog/jest-config": "^1.1.4",
"@repodog/markdownlint-config": "^1.1.4",
"@repodog/prettier-config": "^1.1.4",
"@repodog/rollup-config": "^1.1.4",
"@repodog/syncpack-config": "^1.1.4",
"@repodog/ts-config": "^1.1.4",
"@rollup/plugin-babel": "^6.0.3",
"@rollup/plugin-image": "^3.0.2",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.0.2",
"@rollup/plugin-terser": "^0.4.1",
"@types/fs-extra": "^11.0.1",
"@types/jest": "^25.1.3",
"@types/json-schema": "^7.0.11",
"@types/lodash": "^4.14.191",
"@types/node": "^18.11.18",
"@types/shelljs": "^0.8.11",
"@types/yargs": "^15.0.4",
"@typescript-eslint/eslint-plugin": "^5.59.5",
"@typescript-eslint/parser": "^5.59.5",
"babel-jest": "^29.5.0",
"babel-plugin-codegen": "^4.1.5",
"babel-plugin-macros": "^3.1.0",
"core-js": "^3.27.2",
"del-cli": "^3.0.0",
"eslint": "^8.40.0",
"eslint-config-prettier": "^8.8.0",
"eslint-import-resolver-typescript": "^3.5.5",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jest": "^27.2.1",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-sort-class-members": "^1.18.0",
"eslint-plugin-sort-destructure-keys": "^1.5.0",
"eslint-plugin-sort-keys-fix": "^1.1.2",
"eslint-plugin-typescript-sort-keys": "^2.3.0",
"eslint-plugin-unicorn": "^46.0.1",
"generate-changelog": "^1.8.0",
"husky": "^8.0.3",
"identity-obj-proxy": "^3.0.0",
"jest": "^29.5.0",
"lodash": "^4.17.21",
"markdownlint-cli": "^0.34.0",
"prettier": "^2.8.8",
"rollup": "^3.21.6",
"rollup-plugin-analyzer": "^4.0.0",
"rollup-plugin-copy": "^3.4.0",
"rollup-plugin-sourcemaps": "^0.6.3",
"suppress-experimental-warnings": "^1.1.17",
"syncpack": "^9.8.6",
"ts-node": "^10.9.1",
"ts-toolbelt": "^9.6.0",
"type-fest": "^3.10.0",
"typescript": "^5.0.3"
},
"main": "lib/main/index.js",
"module": "lib/module/index.mjs",
"browser": "lib/browser/index.js",
"types": "lib/types/index.d.ts",
"keywords": [
"cacheControl",
"cacheability",
"http",
"cacheControl",
"etag",
"headers",
"http",
"parser"
],
"scripts": {
"build": "yarn run clean:libs && yarn run compile",
"clean": "yarn run clean:libs && yarn run clean:docs && yarn run clean:node_modules",
"clean:docs": "del-cli ./docs",
"clean:libs": "del-cli ./lib",
"clean:node_modules": "del-cli ./node_modules",
"compile": "concurrently npm:compile:*",
"compile:browser": "cross-env BABEL_ENV=web rollup -c ./rollup.config.js",
"compile:main": "cross-env BABEL_ENV=main babel ./src --out-dir ./lib/main --extensions \".ts\" --source-maps --config-file ./babel.config.js",
"compile:module": "cross-env BABEL_ENV=module babel ./src --out-dir ./lib/module --extensions \".ts\" --out-file-extension \".mjs\" --source-maps --config-file ./babel.config.js",
"compile:types": "tsc --declaration --declarationMap --emitDeclarationOnly",
"cutoff": "cutoff",
"cutoff:post-version": "yarn run compile && yarn run docs",
"docs": "typedoc --includes ./src --out ./docs --options ./typedoc.js",
"init": "yarn && yarn run compile",
"lint": "concurrently npm:lint:*",
"lint:js": "eslint .",
"lint:ts": "tslint --project ./tsconfig.json",
"publish-cutoff": "publish-cutoff",
"test": "jest --logHeapUsage",
"build": "pnpm run clean:dist && pnpm run compile",
"clean:deps": "del-cli ./node_modules",
"clean:dist": "del-cli ./dist",
"commit": "commit",
"compile": "pnpm run /^compile:.*/",
"compile:main": "rollup -c ./rollup.config.cjs",
"compile:types": "tsc --project ./tsconfig.build.json",
"cut:changelog": "changelog",
"cut:post-version": "pnpm run build",
"lint": "eslint . --ext .ts,.cjs",
"repodog": "repodog",
"syncpack": "syncpack",
"test": "node --require=suppress-experimental-warnings --experimental-vm-modules node_modules/jest/bin/jest.js",
"type-check": "tsc --noEmit",
"validate": "yarn run build && yarn run lint && yarn run type-check && yarn run test",
"wipe": "del-cli ./yarn.lock ./node_modules"
},
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
},
"peerDependencies": {
"@babel/runtime": "< 8",
"core-js": "< 4",
"isomorphic-fetch": "< 3",
"lodash": "< 5"
},
"devDependencies": {
"@babel/cli": "^7.8.4",
"@babel/core": "^7.8.6",
"@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/plugin-proposal-decorators": "^7.8.3",
"@babel/plugin-proposal-export-default-from": "^7.8.3",
"@babel/plugin-proposal-export-namespace-from": "^7.8.3",
"@babel/plugin-proposal-function-sent": "^7.8.3",
"@babel/plugin-proposal-json-strings": "^7.8.3",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3",
"@babel/plugin-proposal-numeric-separator": "^7.8.3",
"@babel/plugin-proposal-optional-chaining": "^7.8.3",
"@babel/plugin-proposal-throw-expressions": "^7.8.3",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-syntax-import-meta": "^7.8.3",
"@babel/plugin-syntax-top-level-await": "^7.8.3",
"@babel/plugin-transform-runtime": "^7.8.3",
"@babel/polyfill": "^7.8.3",
"@babel/preset-env": "^7.8.6",
"@babel/preset-typescript": "^7.8.3",
"@babel/register": "7.8.6",
"@babel/runtime": "^7.8.4",
"@commitlint/cli": "^8.3.5",
"@commitlint/config-conventional": "^8.3.4",
"@repodog/babel-config": "^0.3.31",
"@repodog/commitlint-config": "^0.3.24",
"@repodog/config-helpers": "^0.3.30",
"@repodog/eslint-config": "^0.3.26",
"@repodog/jest-config": "^0.3.31",
"@repodog/markdownlint-config": "^0.3.24",
"@repodog/prettier-config": "^0.3.25",
"@repodog/rollup-config": "^0.3.27",
"@repodog/ts-config": "^0.3.24",
"@repodog/tslint-config": "^0.3.26",
"@repodog/typedoc-config": "^0.3.24",
"@types/isomorphic-fetch": "^0.0.35",
"@types/jest": "^25.1.3",
"@types/lodash": "^4.14.149",
"@types/node": "^13.7.7",
"babel-eslint": "^10.1.0",
"babel-plugin-lodash": "^3.3.4",
"concurrently": "^5.1.0",
"core-js": "^3.6.4",
"cross-env": "^7.0.0",
"cutoff": "^0.2.7",
"del-cli": "^3.0.0",
"eslint": "^6.8.0",
"eslint-config-airbnb": "^18.0.1",
"eslint-config-prettier": "^6.10.0",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-react": "^7.18.3",
"eslint-plugin-react-hooks": "^2.5.0",
"eslint-plugin-sort-class-members": "^1.6.0",
"fs-extra": "^8.1.0",
"husky": "4.2.3",
"isomorphic-fetch": "^2.2.1",
"jest": "^25.1.0",
"lodash": "^4.17.5",
"markdownlint-cli": "^0.22.0",
"prettier": "^1.19.1",
"rollup": "^1.32.0",
"rollup-plugin-analyzer": "^3.2.2",
"rollup-plugin-babel": "^5.0.0-alpha.1",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-json": "^4.0.0",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-terser": "^5.2.0",
"ts-jest": "^25.2.1",
"tslint": "^6.0.0",
"tslint-config-prettier": "^1.18.0",
"tslint-plugin-prettier": "^2.1.0",
"type-fest": "^0.11.0",
"typedoc": "^0.16.11",
"typedoc-plugin-markdown": "^2.2.17",
"typescript": "^3.8.3"
"validate": "syncpack format && syncpack lint-semver-ranges && pnpm run build && pnpm run lint && pnpm run type-check && pnpm run test"
}
}
}

@@ -1,2 +0,2 @@

export { default } from "./main";
export * from "./main/types";
export { Cacheability } from './main/index.ts';
export * from './main/types.ts';

@@ -1,15 +0,14 @@

import { isNumber } from "lodash";
import Cacheability from ".";
import { cacheControl, cacheHeaders, defaultMetadata, metadata, rawHeaders } from "../__test__/data";
import { cacheControl, cacheHeaders, defaultMetadata, metadata, rawHeaders } from '../__testUtils__/data.ts';
import { Cacheability } from './index.ts';
describe("the cacheability class", () => {
describe('the cacheability class', () => {
let cacheability: Cacheability;
describe("the constructor", () => {
describe("when nothing is passed into the constructor", () => {
beforeAll(() => {
describe('the constructor', () => {
describe('when nothing is passed into the constructor', () => {
beforeEach(() => {
cacheability = new Cacheability();
});
it("then the constructor should set the default metadata to this._metadata", () => {
it('then the constructor should set the default metadata to this._metadata', () => {
expect(cacheability.metadata).toEqual(defaultMetadata);

@@ -19,8 +18,8 @@ });

describe("when metadata is passed into the constructor", () => {
beforeAll(() => {
describe('when metadata is passed into the constructor', () => {
beforeEach(() => {
cacheability = new Cacheability({ metadata });
});
it("then the constructor should set metadata to this._metadata", () => {
it('then the constructor should set metadata to this._metadata', () => {
expect(cacheability.metadata).toEqual(metadata);

@@ -30,26 +29,36 @@ });

describe("when headers is passed into the constructor", () => {
describe("when headers is an instance of Headers", () => {
beforeAll(() => {
describe('when headers is passed into the constructor', () => {
describe('when headers is an instance of Headers', () => {
beforeEach(() => {
cacheability = new Cacheability({ headers: new Headers(rawHeaders.shortMaxAge) });
});
it("then the constructor should parse the headers and set the resulting data to this._metadata", () => {
expect(cacheability.metadata.cacheControl.maxAge).toEqual(1);
expect(cacheability.metadata.cacheControl.public).toEqual(true);
expect(cacheability.metadata.etag).toEqual("33a64df551425fcc55e4d42a148795d9f25f89d4");
expect(isNumber(cacheability.metadata.ttl)).toBe(true);
it('then the constructor should parse the headers and set the resulting data to this._metadata', () => {
expect(cacheability.metadata).toEqual({
cacheControl: {
maxAge: 1,
public: true,
},
etag: '33a64df551425fcc55e4d42a148795d9f25f89d4',
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
ttl: expect.any(Number),
});
});
});
describe("when headers is a plain object", () => {
beforeAll(() => {
describe('when headers is a plain object', () => {
beforeEach(() => {
cacheability = new Cacheability({ headers: cacheHeaders });
});
it("then the constructor should parse the headers and set the resulting data to this._metadata", () => {
expect(cacheability.metadata.cacheControl.maxAge).toEqual(3);
expect(cacheability.metadata.cacheControl.public).toEqual(true);
expect(cacheability.metadata.etag).toEqual("33a64df551425fcc55e4d42a148795d9f25f89d4");
expect(isNumber(cacheability.metadata.ttl)).toBe(true);
it('then the constructor should parse the headers and set the resulting data to this._metadata', () => {
expect(cacheability.metadata).toEqual({
cacheControl: {
maxAge: 3,
public: true,
},
etag: '33a64df551425fcc55e4d42a148795d9f25f89d4',
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
ttl: expect.any(Number),
});
});

@@ -59,11 +68,18 @@ });

describe("when cacheControl is passed into the constructor", () => {
beforeAll(() => {
describe('when cacheControl is passed into the constructor', () => {
beforeEach(() => {
cacheability = new Cacheability({ cacheControl });
});
it("then the constructor should parse the cacheControl and set the resulting data to this._metadata", () => {
expect(cacheability.metadata.cacheControl.maxAge).toEqual(2);
expect(cacheability.metadata.cacheControl.public).toEqual(true);
expect(isNumber(cacheability.metadata.ttl)).toBe(true);
it('then the constructor should parse the cacheControl and set the resulting data to this._metadata', () => {
expect(cacheability.metadata).toEqual({
cacheControl: {
maxAge: 2,
public: true,
sMaxage: 2,
},
etag: undefined,
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
ttl: expect.any(Number),
});
});

@@ -73,4 +89,4 @@ });

describe("the checkTTL method", () => {
describe("when this._metadata.cacheControl has a property of maxAge", () => {
describe('the checkTTL method', () => {
describe('when this._metadata.cacheControl has a property of maxAge', () => {
beforeEach(() => {

@@ -80,14 +96,17 @@ cacheability = new Cacheability({ headers: new Headers(rawHeaders.shortMaxAge) });

describe("when this._metadata.ttl is valid", () => {
it("then the method should return true", () => {
expect(cacheability.checkTTL()).toEqual(true);
describe('when this._metadata.ttl is valid', () => {
it('then the method should return true', () => {
expect(cacheability.checkTTL()).toBe(true);
});
});
describe("when this._metadata.ttl has expired", () => {
it("then the method should return false", done => {
setTimeout(() => {
expect(cacheability.checkTTL()).toEqual(false);
done();
}, 1000);
describe('when this._metadata.ttl has expired', () => {
it('then the method should return false', async () => {
await new Promise<void>(resolve => {
setTimeout(() => {
resolve();
}, 1000);
});
expect(cacheability.checkTTL()).toBe(false);
});

@@ -97,29 +116,29 @@ });

describe("when this._metadata.cacheControl does not have a property of maxAge", () => {
beforeAll(() => {
describe('when this._metadata.cacheControl does not have a property of maxAge', () => {
beforeEach(() => {
cacheability = new Cacheability({ headers: new Headers(rawHeaders.missingCacheControl) });
});
it("then this._metadata.ttl is valid and the method should return true", () => {
expect(cacheability.checkTTL()).toEqual(true);
it('then this._metadata.ttl is valid and the method should return true', () => {
expect(cacheability.checkTTL()).toBe(true);
});
});
describe("when this._metadata.cacheControl has a property of noCache", () => {
beforeAll(() => {
describe('when this._metadata.cacheControl has a property of noCache', () => {
beforeEach(() => {
cacheability = new Cacheability({ headers: new Headers(rawHeaders.noCache) });
});
it("then this._metadata.ttl is invalid and the method should return false", () => {
expect(cacheability.checkTTL()).toEqual(false);
it('then this._metadata.ttl is invalid and the method should return false', () => {
expect(cacheability.checkTTL()).toBe(false);
});
});
describe("when this._metadata.cacheControl has a property of noStore", () => {
beforeAll(() => {
describe('when this._metadata.cacheControl has a property of noStore', () => {
beforeEach(() => {
cacheability = new Cacheability({ headers: new Headers(rawHeaders.noStore) });
});
it("then this._metadata.ttl is invalid and the method should return false", () => {
expect(cacheability.checkTTL()).toEqual(false);
it('then this._metadata.ttl is invalid and the method should return false', () => {
expect(cacheability.checkTTL()).toBe(false);
});

@@ -129,23 +148,26 @@ });

describe("the printCacheControl method", () => {
describe("when this._metadata.cacheControl has property values", () => {
beforeAll(() => {
describe('the printCacheControl method', () => {
describe('when this._metadata.cacheControl has property values', () => {
beforeEach(() => {
cacheability = new Cacheability({ cacheControl });
});
it("then the method should print a cache control with the updated maxAge based on the time ellapsed", done => {
setTimeout(() => {
expect(cacheability.printCacheControl()).toEqual("public, max-age=1, s-maxage=1");
done();
}, 1000);
it('then the method should print a cache control with the updated maxAge based on the time ellapsed', async () => {
await new Promise<void>(resolve => {
setTimeout(() => {
resolve();
}, 1000);
});
expect(cacheability.printCacheControl()).toBe('public, max-age=1, s-maxage=1');
});
});
describe("when this._metadata.cacheControl does not have property values", () => {
beforeAll(() => {
describe('when this._metadata.cacheControl does not have property values', () => {
beforeEach(() => {
cacheability = new Cacheability({ headers: new Headers(rawHeaders.missingCacheControl) });
});
it("then the method should return an empty string", () => {
expect(cacheability.printCacheControl()).toEqual("");
it('then the method should return an empty string', () => {
expect(cacheability.printCacheControl()).toBe('');
});

@@ -152,0 +174,0 @@ });

@@ -1,4 +0,15 @@

import "isomorphic-fetch";
import { camelCase, isBoolean, isNumber, isPlainObject, isString, kebabCase } from "lodash";
import { CacheControl, CacheHeaders, CacheabilityArgs, HeaderKeys, Metadata, ParsedCacheHeaders } from "./types";
import camelCase from 'lodash/camelCase.js';
import isBoolean from 'lodash/isBoolean.js';
import isNumber from 'lodash/isNumber.js';
import isPlainObject from 'lodash/isPlainObject.js';
import isString from 'lodash/isString.js';
import kebabCase from 'lodash/kebabCase.js';
import {
type CacheControl,
type CacheHeaders,
type CacheabilityArgs as CacheabilityArguments,
type HeaderKeys,
type Metadata,
type ParsedCacheHeaders,
} from './types.ts';

@@ -8,25 +19,25 @@ /**

*/
export default class Cacheability {
private static _headerKeys: HeaderKeys = ["cache-control", "etag"];
export class Cacheability {
private static _headerKeys: HeaderKeys = ['cache-control', 'etag'];
private static _getDirectives(cacheControl: string): string[] {
return cacheControl.split(", ");
return cacheControl.split(', ');
}
private static _parseCacheControl(cacheControl?: string): CacheControl {
const obj: CacheControl = {};
if (!isString(cacheControl) || !cacheControl.length) return obj;
const object: CacheControl = {};
if (!isString(cacheControl) || cacheControl.length === 0) return object;
const directives = Cacheability._getDirectives(cacheControl);
directives.forEach(dir => {
if (dir.match(/=/)) {
const [key, value] = dir.split("=");
obj[camelCase(key)] = Number(value);
return;
for (const directive of directives) {
if (directive.includes('=')) {
const [key, value] = directive.split('=');
object[camelCase(key)] = Number(value);
continue;
}
obj[camelCase(dir)] = true;
});
object[camelCase(directive)] = true;
}
return obj;
return object;
}

@@ -38,8 +49,8 @@

if (headers instanceof Headers) {
Cacheability._headerKeys.forEach(key => {
for (const key of Cacheability._headerKeys) {
const headerValue = headers.get(key);
if (!headerValue) return;
const metadataKey = camelCase(key) as "cacheControl" | "etag";
if (!headerValue) continue;
const metadataKey = camelCase(key) as 'cacheControl' | 'etag';
parsed[metadataKey] = headerValue;
});
}
} else if (isPlainObject(headers)) {

@@ -58,3 +69,3 @@ parsed = headers;

cacheControl: {},
ttl: Infinity,
ttl: Number.POSITIVE_INFINITY,
};

@@ -73,4 +84,4 @@ }

if (noCache || noStore) return 0;
const sec = sMaxage || maxAge;
if (!isNumber(sec)) return Infinity;
const sec = sMaxage ?? maxAge;
if (!isNumber(sec)) return Number.POSITIVE_INFINITY;
const ms = sec * 1000;

@@ -87,3 +98,3 @@ return Date.now() + ms;

etag: isString(etag) ? etag : undefined,
ttl: isNumber(ttl) ? ttl : Infinity,
ttl: isNumber(ttl) ? ttl : Number.POSITIVE_INFINITY,
};

@@ -99,4 +110,4 @@ }

constructor(args: CacheabilityArgs = {}) {
const { cacheControl, headers, metadata } = args;
constructor(arguments_: CacheabilityArguments = {}) {
const { cacheControl, headers, metadata } = arguments_;

@@ -130,3 +141,3 @@ if (cacheControl) {

public printCacheControl(): string {
if (!Object.values(this.metadata.cacheControl).length) return "";
if (Object.values(this.metadata.cacheControl).length === 0) return '';
const cacheControl: CacheControl = { ...this.metadata.cacheControl };

@@ -142,13 +153,13 @@

Object.keys(cacheControl).forEach(key => {
for (const key of Object.keys(cacheControl)) {
if (isBoolean(cacheControl[key])) {
directives.push(kebabCase(key));
return;
continue;
}
directives.push(`${kebabCase(key)}=${cacheControl[key]}`);
});
directives.push(`${kebabCase(key)}=${String(cacheControl[key])}`);
}
return directives.join(", ");
return directives.join(', ');
}
}

@@ -13,2 +13,3 @@ export interface CacheabilityArgs {

export interface CacheControl {
[key: string]: string | number | boolean | undefined;
maxAge?: number;

@@ -18,7 +19,6 @@ noCache?: boolean;

sMaxage?: number;
[key: string]: string | number | boolean | undefined;
}
/** @private */
export type HeaderKeys = ("cache-control" | "etag")[];
export type HeaderKeys = ('cache-control' | 'etag')[];

@@ -25,0 +25,0 @@ export interface Metadata {

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc