cacheability
Advanced tools
Comparing version 3.0.2 to 4.0.0
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 { |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
3
Yes
71169
76
19
555
1
1
1