cacheability
Advanced tools
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["cacheability/index.ts"],"names":["process","env","WEB_ENV","require","Cacheability","metadata","ttl","TypeError","Date","now","cacheControl","parsedCacheControl","_parseCacheControl","_setTTL","headers","Headers","message","_parseHeaders","etag","Object","values","length","assign","sMaxage","maxAge","checkTTL","Math","round","directives","keys","forEach","key","push","join","split","obj","_getDirectives","dir","match","value","Number","_headerKeys","headerValue","get","metadataKey","sec","Infinity","ms"],"mappings":"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","file":"index.js","sourcesContent":["import {\r\n camelCase,\r\n isBoolean,\r\n isNumber,\r\n isPlainObject,\r\n isString,\r\n kebabCase,\r\n} from \"lodash\";\r\n\r\nimport { CacheControl, CacheHeaders, Metadata } from \"../types\";\r\n\r\nif (!process.env.WEB_ENV) {\r\n require(\"isomorphic-fetch\");\r\n}\r\n\r\nexport type CacheabilityCacheControl = CacheControl;\r\nexport type CacheabilityMetadata = Metadata;\r\n\r\n/**\r\n * A utility class to parse, store and print http cache headers.\r\n * ```typescript\r\n * const cacheability = new Cacheability();\r\n * ```\r\n *\r\n */\r\nexport class Cacheability {\r\n private static _headerKeys: Array<\"cache-control\" | \"etag\"> = [\"cache-control\", \"etag\"];\r\n\r\n private static _getDirectives(cacheControl: string): string[] {\r\n return cacheControl.split(\", \");\r\n }\r\n\r\n private static _parseCacheControl(cacheControl: string): CacheControl {\r\n const obj: CacheControl = {};\r\n if (!cacheControl.length) return obj;\r\n const directives = Cacheability._getDirectives(cacheControl);\r\n\r\n directives.forEach((dir) => {\r\n if (dir.match(/=/)) {\r\n const [key, value] = dir.split(\"=\");\r\n obj[camelCase(key)] = Number(value);\r\n return;\r\n }\r\n\r\n obj[camelCase(dir)] = true;\r\n });\r\n\r\n return obj;\r\n }\r\n\r\n private static _parseHeaders(headers: Headers): CacheHeaders {\r\n const metadata: CacheHeaders = {};\r\n\r\n Cacheability._headerKeys.forEach((key) => {\r\n const headerValue = headers.get(key);\r\n if (!headerValue) return;\r\n const metadataKey = camelCase(key) as \"cacheControl\" | \"etag\";\r\n metadata[metadataKey] = headerValue;\r\n });\r\n\r\n return metadata;\r\n }\r\n\r\n private static _setTTL({ maxAge, sMaxage }: CacheControl): number {\r\n const sec = sMaxage || maxAge;\r\n if (!isNumber(sec)) return Infinity;\r\n const ms = sec * 1000;\r\n return Date.now() + ms;\r\n }\r\n\r\n /**\r\n * The property holds the cacheability instance's parsed cache\r\n * headers data, including cache control directives, etag, and\r\n * a derived TTL timestamp.\r\n *\r\n */\r\n public metadata: Metadata;\r\n\r\n /**\r\n * The method checks whether the TTL timestamp stored in the cacheability\r\n * instance is still valid, by comparing it to the current timestamp.\r\n * ```typescript\r\n * cacheability.parseCacheControl(\"public, max-age=3\");\r\n * // One second elapses...\r\n * const isValid = cacheability.checkTTL();\r\n * // isValid is true\r\n * // Three seconds elapse...\r\n * const isStillValid = cacheability.checkTTL();\r\n * // isStillValid is false\r\n * ```\r\n */\r\n public checkTTL(): boolean {\r\n if (!this.metadata || !this.metadata.ttl) {\r\n throw new TypeError(\"checkTTL expected this._metadata.ttl to be a number.\");\r\n }\r\n\r\n return this.metadata.ttl > Date.now();\r\n }\r\n\r\n /**\r\n * The method takes a cache-control header field value, parses it into\r\n * an object literal and derives a TTL from the max-age or s-maxage\r\n * directives. If no max-age or s-maxage directives are present,\r\n * the TTL is given a value of Infinity. The data is stored on the\r\n * cacheability instance's metadata property.\r\n * ```typescript\r\n * const {\r\n * cacheControl,\r\n * ttl,\r\n * } = cacheability.parseCacheControl(\"public, max-age=60, s-maxage=60\");\r\n * // cacheControl is { maxAge: 60, public: true, sMaxage: 60 }\r\n * // if Date.now is 1516060501948, ttl is 1516060712991\r\n * ```\r\n *\r\n */\r\n public parseCacheControl(cacheControl: string): Metadata {\r\n if (!isString(cacheControl)) {\r\n throw new TypeError(\"parseCacheControl expected cacheControl to be a string.\");\r\n }\r\n\r\n const parsedCacheControl = Cacheability._parseCacheControl(cacheControl);\r\n\r\n this.metadata = {\r\n cacheControl: parsedCacheControl,\r\n ttl: Cacheability._setTTL(parsedCacheControl),\r\n };\r\n\r\n return this.metadata;\r\n }\r\n\r\n /**\r\n * Takes a Headers instance or object literal of header key/values,\r\n * filters the cache-control and etag header fields, parses the\r\n * cache-control into an object literal and derives a TTL from the\r\n * max-age or s-maxage directives. If no max-age or s-maxage\r\n * directives are present, the TTL is given a value of Infinity.\r\n * The data is stored on the cacheability instance's metadata property.\r\n * ```typescript\r\n * const headers = new Headers({\r\n * \"cache-control\": \"public, max-age=60\",\r\n * \"content-type\": \"application/json\",\r\n * \"etag\": \"33a64df551425fcc55e4d42a148795d9f25f89d4\",\r\n * });\r\n * const { cacheControl, etag, ttl } = cacheability.parseHeaders(headers);\r\n * // cacheControl is { maxAge: 60, public: true }\r\n * // etag is 33a64df551425fcc55e4d42a148795d9f25f89d4\r\n * // if Date.now is 1516060501948, ttl is 1516060712991\r\n * ```\r\n *\r\n */\r\n public parseHeaders(headers: Headers | CacheHeaders): Metadata {\r\n if (!(headers instanceof Headers) && !isPlainObject(headers)) {\r\n const message = \"parseHeaders expected headers to be an instance of Headers or a plain object.\";\r\n throw new TypeError(message);\r\n }\r\n\r\n const { cacheControl = \"\", etag } = headers instanceof Headers\r\n ? Cacheability._parseHeaders(headers) : headers;\r\n\r\n const parsedCacheControl = Cacheability._parseCacheControl(cacheControl);\r\n\r\n this.metadata = {\r\n cacheControl: parsedCacheControl,\r\n etag,\r\n ttl: Cacheability._setTTL(parsedCacheControl),\r\n };\r\n\r\n return this.metadata;\r\n }\r\n\r\n /**\r\n * The method prints a cache-control header field value based on\r\n * the cacheability instance's metadata. The max-age and/or s-maxage\r\n * are derived from the TTL stored in the metadata.\r\n * ```typescript\r\n * cacheability.parseCacheControl(\"public, max-age=60, s-maxage=60\");\r\n * // Five seconds elapse...\r\n * const cacheControl = cacheability.printCacheControl();\r\n * // cacheControl is \"public, max-age=55, s-maxage=55\"\r\n * ```\r\n *\r\n */\r\n public printCacheControl(): string {\r\n if (!this.metadata || !this.metadata.cacheControl) {\r\n throw new TypeError(\"printCacheControl expected this._metadata.cacheControl to be an object\");\r\n }\r\n\r\n if (!Object.values(this.metadata.cacheControl).length) return \"\";\r\n const cacheControl: CacheControl = { ...this.metadata.cacheControl };\r\n\r\n if (cacheControl.sMaxage || cacheControl.maxAge) {\r\n const maxAge = this.checkTTL() ? Math.round((this.metadata.ttl - Date.now()) / 1000) : 0;\r\n if (cacheControl.sMaxage) cacheControl.sMaxage = maxAge;\r\n if (cacheControl.maxAge) cacheControl.maxAge = maxAge;\r\n }\r\n\r\n const directives: string[] = [];\r\n\r\n Object.keys(cacheControl).forEach((key) => {\r\n if (isBoolean(cacheControl[key])) {\r\n directives.push(kebabCase(key));\r\n return;\r\n }\r\n\r\n directives.push(`${kebabCase(key)}=${cacheControl[key]}`);\r\n });\r\n\r\n return directives.join(\", \");\r\n }\r\n}\r\n"]} | ||
| {"version":3,"sources":["cacheability/index.ts"],"names":["process","env","WEB_ENV","require","Cacheability","metadata","ttl","TypeError","Date","now","cacheControl","parsedCacheControl","_parseCacheControl","_setTTL","headers","Headers","message","_parseHeaders","etag","Object","values","length","assign","sMaxage","maxAge","checkTTL","Math","round","directives","keys","forEach","key","push","join","split","obj","_getDirectives","dir","match","value","Number","_headerKeys","headerValue","get","metadataKey","sec","Infinity","ms"],"mappings":"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","file":"index.js","sourcesContent":["import {\r\n camelCase,\r\n isBoolean,\r\n isNumber,\r\n isPlainObject,\r\n isString,\r\n kebabCase,\r\n} from \"lodash\";\r\n\r\nimport { CacheControl, CacheHeaders, Metadata } from \"../types\";\r\n\r\nif (!process.env.WEB_ENV) {\r\n require(\"isomorphic-fetch\");\r\n}\r\n\r\nexport type CacheabilityCacheControl = CacheControl;\r\nexport type CacheabilityMetadata = Metadata;\r\n\r\n/**\r\n * A utility class to parse, store and print http cache headers.\r\n *\r\n * ```typescript\r\n * import { Cacheability } from \"cacheability\";\r\n * const cacheability = new Cacheability();\r\n * ```\r\n *\r\n */\r\nexport class Cacheability {\r\n private static _headerKeys: Array<\"cache-control\" | \"etag\"> = [\"cache-control\", \"etag\"];\r\n\r\n private static _getDirectives(cacheControl: string): string[] {\r\n return cacheControl.split(\", \");\r\n }\r\n\r\n private static _parseCacheControl(cacheControl: string): CacheControl {\r\n const obj: CacheControl = {};\r\n if (!cacheControl.length) return obj;\r\n const directives = Cacheability._getDirectives(cacheControl);\r\n\r\n directives.forEach((dir) => {\r\n if (dir.match(/=/)) {\r\n const [key, value] = dir.split(\"=\");\r\n obj[camelCase(key)] = Number(value);\r\n return;\r\n }\r\n\r\n obj[camelCase(dir)] = true;\r\n });\r\n\r\n return obj;\r\n }\r\n\r\n private static _parseHeaders(headers: Headers): CacheHeaders {\r\n const metadata: CacheHeaders = {};\r\n\r\n Cacheability._headerKeys.forEach((key) => {\r\n const headerValue = headers.get(key);\r\n if (!headerValue) return;\r\n const metadataKey = camelCase(key) as \"cacheControl\" | \"etag\";\r\n metadata[metadataKey] = headerValue;\r\n });\r\n\r\n return metadata;\r\n }\r\n\r\n private static _setTTL({ maxAge, sMaxage }: CacheControl): number {\r\n const sec = sMaxage || maxAge;\r\n if (!isNumber(sec)) return Infinity;\r\n const ms = sec * 1000;\r\n return Date.now() + ms;\r\n }\r\n\r\n /**\r\n * The property holds the cacheability instance's parsed cache\r\n * headers data, including cache control directives, etag, and\r\n * a derived TTL timestamp.\r\n *\r\n */\r\n public metadata: Metadata;\r\n\r\n /**\r\n * The method checks whether the TTL timestamp stored in the cacheability\r\n * instance is still valid, by comparing it to the current timestamp.\r\n *\r\n * ```typescript\r\n * cacheability.parseCacheControl(\"public, max-age=3\");\r\n * // One second elapses...\r\n * const isValid = cacheability.checkTTL();\r\n * // isValid is true\r\n * // Three seconds elapse...\r\n * const isStillValid = cacheability.checkTTL();\r\n * // isStillValid is false\r\n * ```\r\n *\r\n */\r\n public checkTTL(): boolean {\r\n if (!this.metadata || !this.metadata.ttl) {\r\n throw new TypeError(\"checkTTL expected this._metadata.ttl to be a number.\");\r\n }\r\n\r\n return this.metadata.ttl > Date.now();\r\n }\r\n\r\n /**\r\n * The method takes a cache-control header field value, parses it into\r\n * an object literal and derives a TTL from the max-age or s-maxage\r\n * directives. If no max-age or s-maxage directives are present,\r\n * the TTL is given a value of Infinity. The data is stored on the\r\n * cacheability instance's metadata property.\r\n *\r\n * ```typescript\r\n * const {\r\n * cacheControl,\r\n * ttl,\r\n * } = cacheability.parseCacheControl(\"public, max-age=60, s-maxage=60\");\r\n * // cacheControl is { maxAge: 60, public: true, sMaxage: 60 }\r\n * // if Date.now is 1516060501948, ttl is 1516060712991\r\n * ```\r\n *\r\n */\r\n public parseCacheControl(cacheControl: string): Metadata {\r\n if (!isString(cacheControl)) {\r\n throw new TypeError(\"parseCacheControl expected cacheControl to be a string.\");\r\n }\r\n\r\n const parsedCacheControl = Cacheability._parseCacheControl(cacheControl);\r\n\r\n this.metadata = {\r\n cacheControl: parsedCacheControl,\r\n ttl: Cacheability._setTTL(parsedCacheControl),\r\n };\r\n\r\n return this.metadata;\r\n }\r\n\r\n /**\r\n * Takes a Headers instance or object literal of header key/values,\r\n * filters the cache-control and etag header fields, parses the\r\n * cache-control into an object literal and derives a TTL from the\r\n * max-age or s-maxage directives. If no max-age or s-maxage\r\n * directives are present, the TTL is given a value of Infinity.\r\n * The data is stored on the cacheability instance's metadata property.\r\n *\r\n * ```typescript\r\n * const headers = new Headers({\r\n * \"cache-control\": \"public, max-age=60\",\r\n * \"content-type\": \"application/json\",\r\n * \"etag\": \"33a64df551425fcc55e4d42a148795d9f25f89d4\",\r\n * });\r\n * const { cacheControl, etag, ttl } = cacheability.parseHeaders(headers);\r\n * // cacheControl is { maxAge: 60, public: true }\r\n * // etag is 33a64df551425fcc55e4d42a148795d9f25f89d4\r\n * // if Date.now is 1516060501948, ttl is 1516060712991\r\n * ```\r\n *\r\n */\r\n public parseHeaders(headers: Headers | CacheHeaders): Metadata {\r\n if (!(headers instanceof Headers) && !isPlainObject(headers)) {\r\n const message = \"parseHeaders expected headers to be an instance of Headers or a plain object.\";\r\n throw new TypeError(message);\r\n }\r\n\r\n const { cacheControl = \"\", etag } = headers instanceof Headers\r\n ? Cacheability._parseHeaders(headers) : headers;\r\n\r\n const parsedCacheControl = Cacheability._parseCacheControl(cacheControl);\r\n\r\n this.metadata = {\r\n cacheControl: parsedCacheControl,\r\n etag,\r\n ttl: Cacheability._setTTL(parsedCacheControl),\r\n };\r\n\r\n return this.metadata;\r\n }\r\n\r\n /**\r\n * The method prints a cache-control header field value based on\r\n * the cacheability instance's metadata. The max-age and/or s-maxage\r\n * are derived from the TTL stored in the metadata.\r\n *\r\n * ```typescript\r\n * cacheability.parseCacheControl(\"public, max-age=60, s-maxage=60\");\r\n * // Five seconds elapse...\r\n * const cacheControl = cacheability.printCacheControl();\r\n * // cacheControl is \"public, max-age=55, s-maxage=55\"\r\n * ```\r\n *\r\n */\r\n public printCacheControl(): string {\r\n if (!this.metadata || !this.metadata.cacheControl) {\r\n throw new TypeError(\"printCacheControl expected this._metadata.cacheControl to be an object\");\r\n }\r\n\r\n if (!Object.values(this.metadata.cacheControl).length) return \"\";\r\n const cacheControl: CacheControl = { ...this.metadata.cacheControl };\r\n\r\n if (cacheControl.sMaxage || cacheControl.maxAge) {\r\n const maxAge = this.checkTTL() ? Math.round((this.metadata.ttl - Date.now()) / 1000) : 0;\r\n if (cacheControl.sMaxage) cacheControl.sMaxage = maxAge;\r\n if (cacheControl.maxAge) cacheControl.maxAge = maxAge;\r\n }\r\n\r\n const directives: string[] = [];\r\n\r\n Object.keys(cacheControl).forEach((key) => {\r\n if (isBoolean(cacheControl[key])) {\r\n directives.push(kebabCase(key));\r\n return;\r\n }\r\n\r\n directives.push(`${kebabCase(key)}=${cacheControl[key]}`);\r\n });\r\n\r\n return directives.join(\", \");\r\n }\r\n}\r\n"]} |
@@ -6,3 +6,5 @@ import { CacheControl, CacheHeaders, Metadata } from "../types"; | ||
| * A utility class to parse, store and print http cache headers. | ||
| * | ||
| * ```typescript | ||
| * import { Cacheability } from "cacheability"; | ||
| * const cacheability = new Cacheability(); | ||
@@ -28,2 +30,3 @@ * ``` | ||
| * instance is still valid, by comparing it to the current timestamp. | ||
| * | ||
| * ```typescript | ||
@@ -38,2 +41,3 @@ * cacheability.parseCacheControl("public, max-age=3"); | ||
| * ``` | ||
| * | ||
| */ | ||
@@ -47,2 +51,3 @@ checkTTL(): boolean; | ||
| * cacheability instance's metadata property. | ||
| * | ||
| * ```typescript | ||
@@ -66,2 +71,3 @@ * const { | ||
| * The data is stored on the cacheability instance's metadata property. | ||
| * | ||
| * ```typescript | ||
@@ -85,2 +91,3 @@ * const headers = new Headers({ | ||
| * are derived from the TTL stored in the metadata. | ||
| * | ||
| * ```typescript | ||
@@ -87,0 +94,0 @@ * cacheability.parseCacheControl("public, max-age=60, s-maxage=60"); |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["cacheability/index.js","cacheability/index.ts"],"names":["Object","defineProperty","exports","value","lodash_1","require","process","env","WEB_ENV","Cacheability","_getDirectives","cacheControl","split","_parseCacheControl","obj","length","directives","forEach","dir","match","key","camelCase","Number","_parseHeaders","headers","metadata","_headerKeys","headerValue","get","metadataKey","_setTTL","maxAge","sMaxage","sec","isNumber","Infinity","ms","Date","now","checkTTL","ttl","TypeError","parseCacheControl","isString","parsedCacheControl","parseHeaders","Headers","isPlainObject","message","etag","printCacheControl","values","assign","Math","round","keys","isBoolean","push","kebabCase","join"],"mappings":"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","file":"index.js","sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst lodash_1 = require(\"lodash\");\nif (!process.env.WEB_ENV) {\n require(\"isomorphic-fetch\");\n}\n/**\n * A utility class to parse, store and print http cache headers.\n * ```typescript\n * const cacheability = new Cacheability();\n * ```\n *\n */\nclass Cacheability {\n static _getDirectives(cacheControl) {\n return cacheControl.split(\", \");\n }\n static _parseCacheControl(cacheControl) {\n const obj = {};\n if (!cacheControl.length)\n return obj;\n const directives = Cacheability._getDirectives(cacheControl);\n directives.forEach((dir) => {\n if (dir.match(/=/)) {\n const [key, value] = dir.split(\"=\");\n obj[lodash_1.camelCase(key)] = Number(value);\n return;\n }\n obj[lodash_1.camelCase(dir)] = true;\n });\n return obj;\n }\n static _parseHeaders(headers) {\n const metadata = {};\n Cacheability._headerKeys.forEach((key) => {\n const headerValue = headers.get(key);\n if (!headerValue)\n return;\n const metadataKey = lodash_1.camelCase(key);\n metadata[metadataKey] = headerValue;\n });\n return metadata;\n }\n static _setTTL({ maxAge, sMaxage }) {\n const sec = sMaxage || maxAge;\n if (!lodash_1.isNumber(sec))\n return Infinity;\n const ms = sec * 1000;\n return Date.now() + ms;\n }\n /**\n * The method checks whether the TTL timestamp stored in the cacheability\n * instance is still valid, by comparing it to the current timestamp.\n * ```typescript\n * cacheability.parseCacheControl(\"public, max-age=3\");\n * // One second elapses...\n * const isValid = cacheability.checkTTL();\n * // isValid is true\n * // Three seconds elapse...\n * const isStillValid = cacheability.checkTTL();\n * // isStillValid is false\n * ```\n */\n checkTTL() {\n if (!this.metadata || !this.metadata.ttl) {\n throw new TypeError(\"checkTTL expected this._metadata.ttl to be a number.\");\n }\n return this.metadata.ttl > Date.now();\n }\n /**\n * The method takes a cache-control header field value, parses it into\n * an object literal and derives a TTL from the max-age or s-maxage\n * directives. If no max-age or s-maxage directives are present,\n * the TTL is given a value of Infinity. The data is stored on the\n * cacheability instance's metadata property.\n * ```typescript\n * const {\n * cacheControl,\n * ttl,\n * } = cacheability.parseCacheControl(\"public, max-age=60, s-maxage=60\");\n * // cacheControl is { maxAge: 60, public: true, sMaxage: 60 }\n * // if Date.now is 1516060501948, ttl is 1516060712991\n * ```\n *\n */\n parseCacheControl(cacheControl) {\n if (!lodash_1.isString(cacheControl)) {\n throw new TypeError(\"parseCacheControl expected cacheControl to be a string.\");\n }\n const parsedCacheControl = Cacheability._parseCacheControl(cacheControl);\n this.metadata = {\n cacheControl: parsedCacheControl,\n ttl: Cacheability._setTTL(parsedCacheControl),\n };\n return this.metadata;\n }\n /**\n * Takes a Headers instance or object literal of header key/values,\n * filters the cache-control and etag header fields, parses the\n * cache-control into an object literal and derives a TTL from the\n * max-age or s-maxage directives. If no max-age or s-maxage\n * directives are present, the TTL is given a value of Infinity.\n * The data is stored on the cacheability instance's metadata property.\n * ```typescript\n * const headers = new Headers({\n * \"cache-control\": \"public, max-age=60\",\n * \"content-type\": \"application/json\",\n * \"etag\": \"33a64df551425fcc55e4d42a148795d9f25f89d4\",\n * });\n * const { cacheControl, etag, ttl } = cacheability.parseHeaders(headers);\n * // cacheControl is { maxAge: 60, public: true }\n * // etag is 33a64df551425fcc55e4d42a148795d9f25f89d4\n * // if Date.now is 1516060501948, ttl is 1516060712991\n * ```\n *\n */\n parseHeaders(headers) {\n if (!(headers instanceof Headers) && !lodash_1.isPlainObject(headers)) {\n const message = \"parseHeaders expected headers to be an instance of Headers or a plain object.\";\n throw new TypeError(message);\n }\n const { cacheControl = \"\", etag } = headers instanceof Headers\n ? Cacheability._parseHeaders(headers) : headers;\n const parsedCacheControl = Cacheability._parseCacheControl(cacheControl);\n this.metadata = {\n cacheControl: parsedCacheControl,\n etag,\n ttl: Cacheability._setTTL(parsedCacheControl),\n };\n return this.metadata;\n }\n /**\n * The method prints a cache-control header field value based on\n * the cacheability instance's metadata. The max-age and/or s-maxage\n * are derived from the TTL stored in the metadata.\n * ```typescript\n * cacheability.parseCacheControl(\"public, max-age=60, s-maxage=60\");\n * // Five seconds elapse...\n * const cacheControl = cacheability.printCacheControl();\n * // cacheControl is \"public, max-age=55, s-maxage=55\"\n * ```\n *\n */\n printCacheControl() {\n if (!this.metadata || !this.metadata.cacheControl) {\n throw new TypeError(\"printCacheControl expected this._metadata.cacheControl to be an object\");\n }\n if (!Object.values(this.metadata.cacheControl).length)\n return \"\";\n const cacheControl = Object.assign({}, this.metadata.cacheControl);\n if (cacheControl.sMaxage || cacheControl.maxAge) {\n const maxAge = this.checkTTL() ? Math.round((this.metadata.ttl - Date.now()) / 1000) : 0;\n if (cacheControl.sMaxage)\n cacheControl.sMaxage = maxAge;\n if (cacheControl.maxAge)\n cacheControl.maxAge = maxAge;\n }\n const directives = [];\n Object.keys(cacheControl).forEach((key) => {\n if (lodash_1.isBoolean(cacheControl[key])) {\n directives.push(lodash_1.kebabCase(key));\n return;\n }\n directives.push(`${lodash_1.kebabCase(key)}=${cacheControl[key]}`);\n });\n return directives.join(\", \");\n }\n}\nCacheability._headerKeys = [\"cache-control\", \"etag\"];\nexports.Cacheability = Cacheability;\n","import {\r\n camelCase,\r\n isBoolean,\r\n isNumber,\r\n isPlainObject,\r\n isString,\r\n kebabCase,\r\n} from \"lodash\";\r\n\r\nimport { CacheControl, CacheHeaders, Metadata } from \"../types\";\r\n\r\nif (!process.env.WEB_ENV) {\r\n require(\"isomorphic-fetch\");\r\n}\r\n\r\nexport type CacheabilityCacheControl = CacheControl;\r\nexport type CacheabilityMetadata = Metadata;\r\n\r\n/**\r\n * A utility class to parse, store and print http cache headers.\r\n * ```typescript\r\n * const cacheability = new Cacheability();\r\n * ```\r\n *\r\n */\r\nexport class Cacheability {\r\n private static _headerKeys: Array<\"cache-control\" | \"etag\"> = [\"cache-control\", \"etag\"];\r\n\r\n private static _getDirectives(cacheControl: string): string[] {\r\n return cacheControl.split(\", \");\r\n }\r\n\r\n private static _parseCacheControl(cacheControl: string): CacheControl {\r\n const obj: CacheControl = {};\r\n if (!cacheControl.length) return obj;\r\n const directives = Cacheability._getDirectives(cacheControl);\r\n\r\n directives.forEach((dir) => {\r\n if (dir.match(/=/)) {\r\n const [key, value] = dir.split(\"=\");\r\n obj[camelCase(key)] = Number(value);\r\n return;\r\n }\r\n\r\n obj[camelCase(dir)] = true;\r\n });\r\n\r\n return obj;\r\n }\r\n\r\n private static _parseHeaders(headers: Headers): CacheHeaders {\r\n const metadata: CacheHeaders = {};\r\n\r\n Cacheability._headerKeys.forEach((key) => {\r\n const headerValue = headers.get(key);\r\n if (!headerValue) return;\r\n const metadataKey = camelCase(key) as \"cacheControl\" | \"etag\";\r\n metadata[metadataKey] = headerValue;\r\n });\r\n\r\n return metadata;\r\n }\r\n\r\n private static _setTTL({ maxAge, sMaxage }: CacheControl): number {\r\n const sec = sMaxage || maxAge;\r\n if (!isNumber(sec)) return Infinity;\r\n const ms = sec * 1000;\r\n return Date.now() + ms;\r\n }\r\n\r\n /**\r\n * The property holds the cacheability instance's parsed cache\r\n * headers data, including cache control directives, etag, and\r\n * a derived TTL timestamp.\r\n *\r\n */\r\n public metadata: Metadata;\r\n\r\n /**\r\n * The method checks whether the TTL timestamp stored in the cacheability\r\n * instance is still valid, by comparing it to the current timestamp.\r\n * ```typescript\r\n * cacheability.parseCacheControl(\"public, max-age=3\");\r\n * // One second elapses...\r\n * const isValid = cacheability.checkTTL();\r\n * // isValid is true\r\n * // Three seconds elapse...\r\n * const isStillValid = cacheability.checkTTL();\r\n * // isStillValid is false\r\n * ```\r\n */\r\n public checkTTL(): boolean {\r\n if (!this.metadata || !this.metadata.ttl) {\r\n throw new TypeError(\"checkTTL expected this._metadata.ttl to be a number.\");\r\n }\r\n\r\n return this.metadata.ttl > Date.now();\r\n }\r\n\r\n /**\r\n * The method takes a cache-control header field value, parses it into\r\n * an object literal and derives a TTL from the max-age or s-maxage\r\n * directives. If no max-age or s-maxage directives are present,\r\n * the TTL is given a value of Infinity. The data is stored on the\r\n * cacheability instance's metadata property.\r\n * ```typescript\r\n * const {\r\n * cacheControl,\r\n * ttl,\r\n * } = cacheability.parseCacheControl(\"public, max-age=60, s-maxage=60\");\r\n * // cacheControl is { maxAge: 60, public: true, sMaxage: 60 }\r\n * // if Date.now is 1516060501948, ttl is 1516060712991\r\n * ```\r\n *\r\n */\r\n public parseCacheControl(cacheControl: string): Metadata {\r\n if (!isString(cacheControl)) {\r\n throw new TypeError(\"parseCacheControl expected cacheControl to be a string.\");\r\n }\r\n\r\n const parsedCacheControl = Cacheability._parseCacheControl(cacheControl);\r\n\r\n this.metadata = {\r\n cacheControl: parsedCacheControl,\r\n ttl: Cacheability._setTTL(parsedCacheControl),\r\n };\r\n\r\n return this.metadata;\r\n }\r\n\r\n /**\r\n * Takes a Headers instance or object literal of header key/values,\r\n * filters the cache-control and etag header fields, parses the\r\n * cache-control into an object literal and derives a TTL from the\r\n * max-age or s-maxage directives. If no max-age or s-maxage\r\n * directives are present, the TTL is given a value of Infinity.\r\n * The data is stored on the cacheability instance's metadata property.\r\n * ```typescript\r\n * const headers = new Headers({\r\n * \"cache-control\": \"public, max-age=60\",\r\n * \"content-type\": \"application/json\",\r\n * \"etag\": \"33a64df551425fcc55e4d42a148795d9f25f89d4\",\r\n * });\r\n * const { cacheControl, etag, ttl } = cacheability.parseHeaders(headers);\r\n * // cacheControl is { maxAge: 60, public: true }\r\n * // etag is 33a64df551425fcc55e4d42a148795d9f25f89d4\r\n * // if Date.now is 1516060501948, ttl is 1516060712991\r\n * ```\r\n *\r\n */\r\n public parseHeaders(headers: Headers | CacheHeaders): Metadata {\r\n if (!(headers instanceof Headers) && !isPlainObject(headers)) {\r\n const message = \"parseHeaders expected headers to be an instance of Headers or a plain object.\";\r\n throw new TypeError(message);\r\n }\r\n\r\n const { cacheControl = \"\", etag } = headers instanceof Headers\r\n ? Cacheability._parseHeaders(headers) : headers;\r\n\r\n const parsedCacheControl = Cacheability._parseCacheControl(cacheControl);\r\n\r\n this.metadata = {\r\n cacheControl: parsedCacheControl,\r\n etag,\r\n ttl: Cacheability._setTTL(parsedCacheControl),\r\n };\r\n\r\n return this.metadata;\r\n }\r\n\r\n /**\r\n * The method prints a cache-control header field value based on\r\n * the cacheability instance's metadata. The max-age and/or s-maxage\r\n * are derived from the TTL stored in the metadata.\r\n * ```typescript\r\n * cacheability.parseCacheControl(\"public, max-age=60, s-maxage=60\");\r\n * // Five seconds elapse...\r\n * const cacheControl = cacheability.printCacheControl();\r\n * // cacheControl is \"public, max-age=55, s-maxage=55\"\r\n * ```\r\n *\r\n */\r\n public printCacheControl(): string {\r\n if (!this.metadata || !this.metadata.cacheControl) {\r\n throw new TypeError(\"printCacheControl expected this._metadata.cacheControl to be an object\");\r\n }\r\n\r\n if (!Object.values(this.metadata.cacheControl).length) return \"\";\r\n const cacheControl: CacheControl = { ...this.metadata.cacheControl };\r\n\r\n if (cacheControl.sMaxage || cacheControl.maxAge) {\r\n const maxAge = this.checkTTL() ? Math.round((this.metadata.ttl - Date.now()) / 1000) : 0;\r\n if (cacheControl.sMaxage) cacheControl.sMaxage = maxAge;\r\n if (cacheControl.maxAge) cacheControl.maxAge = maxAge;\r\n }\r\n\r\n const directives: string[] = [];\r\n\r\n Object.keys(cacheControl).forEach((key) => {\r\n if (isBoolean(cacheControl[key])) {\r\n directives.push(kebabCase(key));\r\n return;\r\n }\r\n\r\n directives.push(`${kebabCase(key)}=${cacheControl[key]}`);\r\n });\r\n\r\n return directives.join(\", \");\r\n }\r\n}\r\n"]} | ||
| {"version":3,"sources":["cacheability/index.js","cacheability/index.ts"],"names":["Object","defineProperty","exports","value","lodash_1","require","process","env","WEB_ENV","Cacheability","_getDirectives","cacheControl","split","_parseCacheControl","obj","length","directives","forEach","dir","match","key","camelCase","Number","_parseHeaders","headers","metadata","_headerKeys","headerValue","get","metadataKey","_setTTL","maxAge","sMaxage","sec","isNumber","Infinity","ms","Date","now","checkTTL","ttl","TypeError","parseCacheControl","isString","parsedCacheControl","parseHeaders","Headers","isPlainObject","message","etag","printCacheControl","values","assign","Math","round","keys","isBoolean","push","kebabCase","join"],"mappings":"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","file":"index.js","sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst lodash_1 = require(\"lodash\");\nif (!process.env.WEB_ENV) {\n require(\"isomorphic-fetch\");\n}\n/**\n * A utility class to parse, store and print http cache headers.\n *\n * ```typescript\n * import { Cacheability } from \"cacheability\";\n * const cacheability = new Cacheability();\n * ```\n *\n */\nclass Cacheability {\n static _getDirectives(cacheControl) {\n return cacheControl.split(\", \");\n }\n static _parseCacheControl(cacheControl) {\n const obj = {};\n if (!cacheControl.length)\n return obj;\n const directives = Cacheability._getDirectives(cacheControl);\n directives.forEach((dir) => {\n if (dir.match(/=/)) {\n const [key, value] = dir.split(\"=\");\n obj[lodash_1.camelCase(key)] = Number(value);\n return;\n }\n obj[lodash_1.camelCase(dir)] = true;\n });\n return obj;\n }\n static _parseHeaders(headers) {\n const metadata = {};\n Cacheability._headerKeys.forEach((key) => {\n const headerValue = headers.get(key);\n if (!headerValue)\n return;\n const metadataKey = lodash_1.camelCase(key);\n metadata[metadataKey] = headerValue;\n });\n return metadata;\n }\n static _setTTL({ maxAge, sMaxage }) {\n const sec = sMaxage || maxAge;\n if (!lodash_1.isNumber(sec))\n return Infinity;\n const ms = sec * 1000;\n return Date.now() + ms;\n }\n /**\n * The method checks whether the TTL timestamp stored in the cacheability\n * instance is still valid, by comparing it to the current timestamp.\n *\n * ```typescript\n * cacheability.parseCacheControl(\"public, max-age=3\");\n * // One second elapses...\n * const isValid = cacheability.checkTTL();\n * // isValid is true\n * // Three seconds elapse...\n * const isStillValid = cacheability.checkTTL();\n * // isStillValid is false\n * ```\n *\n */\n checkTTL() {\n if (!this.metadata || !this.metadata.ttl) {\n throw new TypeError(\"checkTTL expected this._metadata.ttl to be a number.\");\n }\n return this.metadata.ttl > Date.now();\n }\n /**\n * The method takes a cache-control header field value, parses it into\n * an object literal and derives a TTL from the max-age or s-maxage\n * directives. If no max-age or s-maxage directives are present,\n * the TTL is given a value of Infinity. The data is stored on the\n * cacheability instance's metadata property.\n *\n * ```typescript\n * const {\n * cacheControl,\n * ttl,\n * } = cacheability.parseCacheControl(\"public, max-age=60, s-maxage=60\");\n * // cacheControl is { maxAge: 60, public: true, sMaxage: 60 }\n * // if Date.now is 1516060501948, ttl is 1516060712991\n * ```\n *\n */\n parseCacheControl(cacheControl) {\n if (!lodash_1.isString(cacheControl)) {\n throw new TypeError(\"parseCacheControl expected cacheControl to be a string.\");\n }\n const parsedCacheControl = Cacheability._parseCacheControl(cacheControl);\n this.metadata = {\n cacheControl: parsedCacheControl,\n ttl: Cacheability._setTTL(parsedCacheControl),\n };\n return this.metadata;\n }\n /**\n * Takes a Headers instance or object literal of header key/values,\n * filters the cache-control and etag header fields, parses the\n * cache-control into an object literal and derives a TTL from the\n * max-age or s-maxage directives. If no max-age or s-maxage\n * directives are present, the TTL is given a value of Infinity.\n * The data is stored on the cacheability instance's metadata property.\n *\n * ```typescript\n * const headers = new Headers({\n * \"cache-control\": \"public, max-age=60\",\n * \"content-type\": \"application/json\",\n * \"etag\": \"33a64df551425fcc55e4d42a148795d9f25f89d4\",\n * });\n * const { cacheControl, etag, ttl } = cacheability.parseHeaders(headers);\n * // cacheControl is { maxAge: 60, public: true }\n * // etag is 33a64df551425fcc55e4d42a148795d9f25f89d4\n * // if Date.now is 1516060501948, ttl is 1516060712991\n * ```\n *\n */\n parseHeaders(headers) {\n if (!(headers instanceof Headers) && !lodash_1.isPlainObject(headers)) {\n const message = \"parseHeaders expected headers to be an instance of Headers or a plain object.\";\n throw new TypeError(message);\n }\n const { cacheControl = \"\", etag } = headers instanceof Headers\n ? Cacheability._parseHeaders(headers) : headers;\n const parsedCacheControl = Cacheability._parseCacheControl(cacheControl);\n this.metadata = {\n cacheControl: parsedCacheControl,\n etag,\n ttl: Cacheability._setTTL(parsedCacheControl),\n };\n return this.metadata;\n }\n /**\n * The method prints a cache-control header field value based on\n * the cacheability instance's metadata. The max-age and/or s-maxage\n * are derived from the TTL stored in the metadata.\n *\n * ```typescript\n * cacheability.parseCacheControl(\"public, max-age=60, s-maxage=60\");\n * // Five seconds elapse...\n * const cacheControl = cacheability.printCacheControl();\n * // cacheControl is \"public, max-age=55, s-maxage=55\"\n * ```\n *\n */\n printCacheControl() {\n if (!this.metadata || !this.metadata.cacheControl) {\n throw new TypeError(\"printCacheControl expected this._metadata.cacheControl to be an object\");\n }\n if (!Object.values(this.metadata.cacheControl).length)\n return \"\";\n const cacheControl = Object.assign({}, this.metadata.cacheControl);\n if (cacheControl.sMaxage || cacheControl.maxAge) {\n const maxAge = this.checkTTL() ? Math.round((this.metadata.ttl - Date.now()) / 1000) : 0;\n if (cacheControl.sMaxage)\n cacheControl.sMaxage = maxAge;\n if (cacheControl.maxAge)\n cacheControl.maxAge = maxAge;\n }\n const directives = [];\n Object.keys(cacheControl).forEach((key) => {\n if (lodash_1.isBoolean(cacheControl[key])) {\n directives.push(lodash_1.kebabCase(key));\n return;\n }\n directives.push(`${lodash_1.kebabCase(key)}=${cacheControl[key]}`);\n });\n return directives.join(\", \");\n }\n}\nCacheability._headerKeys = [\"cache-control\", \"etag\"];\nexports.Cacheability = Cacheability;\n","import {\r\n camelCase,\r\n isBoolean,\r\n isNumber,\r\n isPlainObject,\r\n isString,\r\n kebabCase,\r\n} from \"lodash\";\r\n\r\nimport { CacheControl, CacheHeaders, Metadata } from \"../types\";\r\n\r\nif (!process.env.WEB_ENV) {\r\n require(\"isomorphic-fetch\");\r\n}\r\n\r\nexport type CacheabilityCacheControl = CacheControl;\r\nexport type CacheabilityMetadata = Metadata;\r\n\r\n/**\r\n * A utility class to parse, store and print http cache headers.\r\n *\r\n * ```typescript\r\n * import { Cacheability } from \"cacheability\";\r\n * const cacheability = new Cacheability();\r\n * ```\r\n *\r\n */\r\nexport class Cacheability {\r\n private static _headerKeys: Array<\"cache-control\" | \"etag\"> = [\"cache-control\", \"etag\"];\r\n\r\n private static _getDirectives(cacheControl: string): string[] {\r\n return cacheControl.split(\", \");\r\n }\r\n\r\n private static _parseCacheControl(cacheControl: string): CacheControl {\r\n const obj: CacheControl = {};\r\n if (!cacheControl.length) return obj;\r\n const directives = Cacheability._getDirectives(cacheControl);\r\n\r\n directives.forEach((dir) => {\r\n if (dir.match(/=/)) {\r\n const [key, value] = dir.split(\"=\");\r\n obj[camelCase(key)] = Number(value);\r\n return;\r\n }\r\n\r\n obj[camelCase(dir)] = true;\r\n });\r\n\r\n return obj;\r\n }\r\n\r\n private static _parseHeaders(headers: Headers): CacheHeaders {\r\n const metadata: CacheHeaders = {};\r\n\r\n Cacheability._headerKeys.forEach((key) => {\r\n const headerValue = headers.get(key);\r\n if (!headerValue) return;\r\n const metadataKey = camelCase(key) as \"cacheControl\" | \"etag\";\r\n metadata[metadataKey] = headerValue;\r\n });\r\n\r\n return metadata;\r\n }\r\n\r\n private static _setTTL({ maxAge, sMaxage }: CacheControl): number {\r\n const sec = sMaxage || maxAge;\r\n if (!isNumber(sec)) return Infinity;\r\n const ms = sec * 1000;\r\n return Date.now() + ms;\r\n }\r\n\r\n /**\r\n * The property holds the cacheability instance's parsed cache\r\n * headers data, including cache control directives, etag, and\r\n * a derived TTL timestamp.\r\n *\r\n */\r\n public metadata: Metadata;\r\n\r\n /**\r\n * The method checks whether the TTL timestamp stored in the cacheability\r\n * instance is still valid, by comparing it to the current timestamp.\r\n *\r\n * ```typescript\r\n * cacheability.parseCacheControl(\"public, max-age=3\");\r\n * // One second elapses...\r\n * const isValid = cacheability.checkTTL();\r\n * // isValid is true\r\n * // Three seconds elapse...\r\n * const isStillValid = cacheability.checkTTL();\r\n * // isStillValid is false\r\n * ```\r\n *\r\n */\r\n public checkTTL(): boolean {\r\n if (!this.metadata || !this.metadata.ttl) {\r\n throw new TypeError(\"checkTTL expected this._metadata.ttl to be a number.\");\r\n }\r\n\r\n return this.metadata.ttl > Date.now();\r\n }\r\n\r\n /**\r\n * The method takes a cache-control header field value, parses it into\r\n * an object literal and derives a TTL from the max-age or s-maxage\r\n * directives. If no max-age or s-maxage directives are present,\r\n * the TTL is given a value of Infinity. The data is stored on the\r\n * cacheability instance's metadata property.\r\n *\r\n * ```typescript\r\n * const {\r\n * cacheControl,\r\n * ttl,\r\n * } = cacheability.parseCacheControl(\"public, max-age=60, s-maxage=60\");\r\n * // cacheControl is { maxAge: 60, public: true, sMaxage: 60 }\r\n * // if Date.now is 1516060501948, ttl is 1516060712991\r\n * ```\r\n *\r\n */\r\n public parseCacheControl(cacheControl: string): Metadata {\r\n if (!isString(cacheControl)) {\r\n throw new TypeError(\"parseCacheControl expected cacheControl to be a string.\");\r\n }\r\n\r\n const parsedCacheControl = Cacheability._parseCacheControl(cacheControl);\r\n\r\n this.metadata = {\r\n cacheControl: parsedCacheControl,\r\n ttl: Cacheability._setTTL(parsedCacheControl),\r\n };\r\n\r\n return this.metadata;\r\n }\r\n\r\n /**\r\n * Takes a Headers instance or object literal of header key/values,\r\n * filters the cache-control and etag header fields, parses the\r\n * cache-control into an object literal and derives a TTL from the\r\n * max-age or s-maxage directives. If no max-age or s-maxage\r\n * directives are present, the TTL is given a value of Infinity.\r\n * The data is stored on the cacheability instance's metadata property.\r\n *\r\n * ```typescript\r\n * const headers = new Headers({\r\n * \"cache-control\": \"public, max-age=60\",\r\n * \"content-type\": \"application/json\",\r\n * \"etag\": \"33a64df551425fcc55e4d42a148795d9f25f89d4\",\r\n * });\r\n * const { cacheControl, etag, ttl } = cacheability.parseHeaders(headers);\r\n * // cacheControl is { maxAge: 60, public: true }\r\n * // etag is 33a64df551425fcc55e4d42a148795d9f25f89d4\r\n * // if Date.now is 1516060501948, ttl is 1516060712991\r\n * ```\r\n *\r\n */\r\n public parseHeaders(headers: Headers | CacheHeaders): Metadata {\r\n if (!(headers instanceof Headers) && !isPlainObject(headers)) {\r\n const message = \"parseHeaders expected headers to be an instance of Headers or a plain object.\";\r\n throw new TypeError(message);\r\n }\r\n\r\n const { cacheControl = \"\", etag } = headers instanceof Headers\r\n ? Cacheability._parseHeaders(headers) : headers;\r\n\r\n const parsedCacheControl = Cacheability._parseCacheControl(cacheControl);\r\n\r\n this.metadata = {\r\n cacheControl: parsedCacheControl,\r\n etag,\r\n ttl: Cacheability._setTTL(parsedCacheControl),\r\n };\r\n\r\n return this.metadata;\r\n }\r\n\r\n /**\r\n * The method prints a cache-control header field value based on\r\n * the cacheability instance's metadata. The max-age and/or s-maxage\r\n * are derived from the TTL stored in the metadata.\r\n *\r\n * ```typescript\r\n * cacheability.parseCacheControl(\"public, max-age=60, s-maxage=60\");\r\n * // Five seconds elapse...\r\n * const cacheControl = cacheability.printCacheControl();\r\n * // cacheControl is \"public, max-age=55, s-maxage=55\"\r\n * ```\r\n *\r\n */\r\n public printCacheControl(): string {\r\n if (!this.metadata || !this.metadata.cacheControl) {\r\n throw new TypeError(\"printCacheControl expected this._metadata.cacheControl to be an object\");\r\n }\r\n\r\n if (!Object.values(this.metadata.cacheControl).length) return \"\";\r\n const cacheControl: CacheControl = { ...this.metadata.cacheControl };\r\n\r\n if (cacheControl.sMaxage || cacheControl.maxAge) {\r\n const maxAge = this.checkTTL() ? Math.round((this.metadata.ttl - Date.now()) / 1000) : 0;\r\n if (cacheControl.sMaxage) cacheControl.sMaxage = maxAge;\r\n if (cacheControl.maxAge) cacheControl.maxAge = maxAge;\r\n }\r\n\r\n const directives: string[] = [];\r\n\r\n Object.keys(cacheControl).forEach((key) => {\r\n if (isBoolean(cacheControl[key])) {\r\n directives.push(kebabCase(key));\r\n return;\r\n }\r\n\r\n directives.push(`${kebabCase(key)}=${cacheControl[key]}`);\r\n });\r\n\r\n return directives.join(\", \");\r\n }\r\n}\r\n"]} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["cacheability/index.ts"],"names":["process","env","WEB_ENV","require","Cacheability","_getDirectives","cacheControl","split","_parseCacheControl","obj","length","directives","forEach","dir","match","key","value","Number","_parseHeaders","headers","metadata","_headerKeys","headerValue","get","metadataKey","_setTTL","maxAge","sMaxage","sec","Infinity","ms","Date","now","checkTTL","ttl","TypeError","parseCacheControl","parsedCacheControl","parseHeaders","Headers","message","etag","printCacheControl","Object","values","assign","Math","round","keys","push","join"],"mappings":"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","file":"index.js","sourcesContent":["import {\r\n camelCase,\r\n isBoolean,\r\n isNumber,\r\n isPlainObject,\r\n isString,\r\n kebabCase,\r\n} from \"lodash\";\r\n\r\nimport { CacheControl, CacheHeaders, Metadata } from \"../types\";\r\n\r\nif (!process.env.WEB_ENV) {\r\n require(\"isomorphic-fetch\");\r\n}\r\n\r\nexport type CacheabilityCacheControl = CacheControl;\r\nexport type CacheabilityMetadata = Metadata;\r\n\r\n/**\r\n * A utility class to parse, store and print http cache headers.\r\n * ```typescript\r\n * const cacheability = new Cacheability();\r\n * ```\r\n *\r\n */\r\nexport class Cacheability {\r\n private static _headerKeys: Array<\"cache-control\" | \"etag\"> = [\"cache-control\", \"etag\"];\r\n\r\n private static _getDirectives(cacheControl: string): string[] {\r\n return cacheControl.split(\", \");\r\n }\r\n\r\n private static _parseCacheControl(cacheControl: string): CacheControl {\r\n const obj: CacheControl = {};\r\n if (!cacheControl.length) return obj;\r\n const directives = Cacheability._getDirectives(cacheControl);\r\n\r\n directives.forEach((dir) => {\r\n if (dir.match(/=/)) {\r\n const [key, value] = dir.split(\"=\");\r\n obj[camelCase(key)] = Number(value);\r\n return;\r\n }\r\n\r\n obj[camelCase(dir)] = true;\r\n });\r\n\r\n return obj;\r\n }\r\n\r\n private static _parseHeaders(headers: Headers): CacheHeaders {\r\n const metadata: CacheHeaders = {};\r\n\r\n Cacheability._headerKeys.forEach((key) => {\r\n const headerValue = headers.get(key);\r\n if (!headerValue) return;\r\n const metadataKey = camelCase(key) as \"cacheControl\" | \"etag\";\r\n metadata[metadataKey] = headerValue;\r\n });\r\n\r\n return metadata;\r\n }\r\n\r\n private static _setTTL({ maxAge, sMaxage }: CacheControl): number {\r\n const sec = sMaxage || maxAge;\r\n if (!isNumber(sec)) return Infinity;\r\n const ms = sec * 1000;\r\n return Date.now() + ms;\r\n }\r\n\r\n /**\r\n * The property holds the cacheability instance's parsed cache\r\n * headers data, including cache control directives, etag, and\r\n * a derived TTL timestamp.\r\n *\r\n */\r\n public metadata: Metadata;\r\n\r\n /**\r\n * The method checks whether the TTL timestamp stored in the cacheability\r\n * instance is still valid, by comparing it to the current timestamp.\r\n * ```typescript\r\n * cacheability.parseCacheControl(\"public, max-age=3\");\r\n * // One second elapses...\r\n * const isValid = cacheability.checkTTL();\r\n * // isValid is true\r\n * // Three seconds elapse...\r\n * const isStillValid = cacheability.checkTTL();\r\n * // isStillValid is false\r\n * ```\r\n */\r\n public checkTTL(): boolean {\r\n if (!this.metadata || !this.metadata.ttl) {\r\n throw new TypeError(\"checkTTL expected this._metadata.ttl to be a number.\");\r\n }\r\n\r\n return this.metadata.ttl > Date.now();\r\n }\r\n\r\n /**\r\n * The method takes a cache-control header field value, parses it into\r\n * an object literal and derives a TTL from the max-age or s-maxage\r\n * directives. If no max-age or s-maxage directives are present,\r\n * the TTL is given a value of Infinity. The data is stored on the\r\n * cacheability instance's metadata property.\r\n * ```typescript\r\n * const {\r\n * cacheControl,\r\n * ttl,\r\n * } = cacheability.parseCacheControl(\"public, max-age=60, s-maxage=60\");\r\n * // cacheControl is { maxAge: 60, public: true, sMaxage: 60 }\r\n * // if Date.now is 1516060501948, ttl is 1516060712991\r\n * ```\r\n *\r\n */\r\n public parseCacheControl(cacheControl: string): Metadata {\r\n if (!isString(cacheControl)) {\r\n throw new TypeError(\"parseCacheControl expected cacheControl to be a string.\");\r\n }\r\n\r\n const parsedCacheControl = Cacheability._parseCacheControl(cacheControl);\r\n\r\n this.metadata = {\r\n cacheControl: parsedCacheControl,\r\n ttl: Cacheability._setTTL(parsedCacheControl),\r\n };\r\n\r\n return this.metadata;\r\n }\r\n\r\n /**\r\n * Takes a Headers instance or object literal of header key/values,\r\n * filters the cache-control and etag header fields, parses the\r\n * cache-control into an object literal and derives a TTL from the\r\n * max-age or s-maxage directives. If no max-age or s-maxage\r\n * directives are present, the TTL is given a value of Infinity.\r\n * The data is stored on the cacheability instance's metadata property.\r\n * ```typescript\r\n * const headers = new Headers({\r\n * \"cache-control\": \"public, max-age=60\",\r\n * \"content-type\": \"application/json\",\r\n * \"etag\": \"33a64df551425fcc55e4d42a148795d9f25f89d4\",\r\n * });\r\n * const { cacheControl, etag, ttl } = cacheability.parseHeaders(headers);\r\n * // cacheControl is { maxAge: 60, public: true }\r\n * // etag is 33a64df551425fcc55e4d42a148795d9f25f89d4\r\n * // if Date.now is 1516060501948, ttl is 1516060712991\r\n * ```\r\n *\r\n */\r\n public parseHeaders(headers: Headers | CacheHeaders): Metadata {\r\n if (!(headers instanceof Headers) && !isPlainObject(headers)) {\r\n const message = \"parseHeaders expected headers to be an instance of Headers or a plain object.\";\r\n throw new TypeError(message);\r\n }\r\n\r\n const { cacheControl = \"\", etag } = headers instanceof Headers\r\n ? Cacheability._parseHeaders(headers) : headers;\r\n\r\n const parsedCacheControl = Cacheability._parseCacheControl(cacheControl);\r\n\r\n this.metadata = {\r\n cacheControl: parsedCacheControl,\r\n etag,\r\n ttl: Cacheability._setTTL(parsedCacheControl),\r\n };\r\n\r\n return this.metadata;\r\n }\r\n\r\n /**\r\n * The method prints a cache-control header field value based on\r\n * the cacheability instance's metadata. The max-age and/or s-maxage\r\n * are derived from the TTL stored in the metadata.\r\n * ```typescript\r\n * cacheability.parseCacheControl(\"public, max-age=60, s-maxage=60\");\r\n * // Five seconds elapse...\r\n * const cacheControl = cacheability.printCacheControl();\r\n * // cacheControl is \"public, max-age=55, s-maxage=55\"\r\n * ```\r\n *\r\n */\r\n public printCacheControl(): string {\r\n if (!this.metadata || !this.metadata.cacheControl) {\r\n throw new TypeError(\"printCacheControl expected this._metadata.cacheControl to be an object\");\r\n }\r\n\r\n if (!Object.values(this.metadata.cacheControl).length) return \"\";\r\n const cacheControl: CacheControl = { ...this.metadata.cacheControl };\r\n\r\n if (cacheControl.sMaxage || cacheControl.maxAge) {\r\n const maxAge = this.checkTTL() ? Math.round((this.metadata.ttl - Date.now()) / 1000) : 0;\r\n if (cacheControl.sMaxage) cacheControl.sMaxage = maxAge;\r\n if (cacheControl.maxAge) cacheControl.maxAge = maxAge;\r\n }\r\n\r\n const directives: string[] = [];\r\n\r\n Object.keys(cacheControl).forEach((key) => {\r\n if (isBoolean(cacheControl[key])) {\r\n directives.push(kebabCase(key));\r\n return;\r\n }\r\n\r\n directives.push(`${kebabCase(key)}=${cacheControl[key]}`);\r\n });\r\n\r\n return directives.join(\", \");\r\n }\r\n}\r\n"]} | ||
| {"version":3,"sources":["cacheability/index.ts"],"names":["process","env","WEB_ENV","require","Cacheability","_getDirectives","cacheControl","split","_parseCacheControl","obj","length","directives","forEach","dir","match","key","value","Number","_parseHeaders","headers","metadata","_headerKeys","headerValue","get","metadataKey","_setTTL","maxAge","sMaxage","sec","Infinity","ms","Date","now","checkTTL","ttl","TypeError","parseCacheControl","parsedCacheControl","parseHeaders","Headers","message","etag","printCacheControl","Object","values","assign","Math","round","keys","push","join"],"mappings":"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","file":"index.js","sourcesContent":["import {\r\n camelCase,\r\n isBoolean,\r\n isNumber,\r\n isPlainObject,\r\n isString,\r\n kebabCase,\r\n} from \"lodash\";\r\n\r\nimport { CacheControl, CacheHeaders, Metadata } from \"../types\";\r\n\r\nif (!process.env.WEB_ENV) {\r\n require(\"isomorphic-fetch\");\r\n}\r\n\r\nexport type CacheabilityCacheControl = CacheControl;\r\nexport type CacheabilityMetadata = Metadata;\r\n\r\n/**\r\n * A utility class to parse, store and print http cache headers.\r\n *\r\n * ```typescript\r\n * import { Cacheability } from \"cacheability\";\r\n * const cacheability = new Cacheability();\r\n * ```\r\n *\r\n */\r\nexport class Cacheability {\r\n private static _headerKeys: Array<\"cache-control\" | \"etag\"> = [\"cache-control\", \"etag\"];\r\n\r\n private static _getDirectives(cacheControl: string): string[] {\r\n return cacheControl.split(\", \");\r\n }\r\n\r\n private static _parseCacheControl(cacheControl: string): CacheControl {\r\n const obj: CacheControl = {};\r\n if (!cacheControl.length) return obj;\r\n const directives = Cacheability._getDirectives(cacheControl);\r\n\r\n directives.forEach((dir) => {\r\n if (dir.match(/=/)) {\r\n const [key, value] = dir.split(\"=\");\r\n obj[camelCase(key)] = Number(value);\r\n return;\r\n }\r\n\r\n obj[camelCase(dir)] = true;\r\n });\r\n\r\n return obj;\r\n }\r\n\r\n private static _parseHeaders(headers: Headers): CacheHeaders {\r\n const metadata: CacheHeaders = {};\r\n\r\n Cacheability._headerKeys.forEach((key) => {\r\n const headerValue = headers.get(key);\r\n if (!headerValue) return;\r\n const metadataKey = camelCase(key) as \"cacheControl\" | \"etag\";\r\n metadata[metadataKey] = headerValue;\r\n });\r\n\r\n return metadata;\r\n }\r\n\r\n private static _setTTL({ maxAge, sMaxage }: CacheControl): number {\r\n const sec = sMaxage || maxAge;\r\n if (!isNumber(sec)) return Infinity;\r\n const ms = sec * 1000;\r\n return Date.now() + ms;\r\n }\r\n\r\n /**\r\n * The property holds the cacheability instance's parsed cache\r\n * headers data, including cache control directives, etag, and\r\n * a derived TTL timestamp.\r\n *\r\n */\r\n public metadata: Metadata;\r\n\r\n /**\r\n * The method checks whether the TTL timestamp stored in the cacheability\r\n * instance is still valid, by comparing it to the current timestamp.\r\n *\r\n * ```typescript\r\n * cacheability.parseCacheControl(\"public, max-age=3\");\r\n * // One second elapses...\r\n * const isValid = cacheability.checkTTL();\r\n * // isValid is true\r\n * // Three seconds elapse...\r\n * const isStillValid = cacheability.checkTTL();\r\n * // isStillValid is false\r\n * ```\r\n *\r\n */\r\n public checkTTL(): boolean {\r\n if (!this.metadata || !this.metadata.ttl) {\r\n throw new TypeError(\"checkTTL expected this._metadata.ttl to be a number.\");\r\n }\r\n\r\n return this.metadata.ttl > Date.now();\r\n }\r\n\r\n /**\r\n * The method takes a cache-control header field value, parses it into\r\n * an object literal and derives a TTL from the max-age or s-maxage\r\n * directives. If no max-age or s-maxage directives are present,\r\n * the TTL is given a value of Infinity. The data is stored on the\r\n * cacheability instance's metadata property.\r\n *\r\n * ```typescript\r\n * const {\r\n * cacheControl,\r\n * ttl,\r\n * } = cacheability.parseCacheControl(\"public, max-age=60, s-maxage=60\");\r\n * // cacheControl is { maxAge: 60, public: true, sMaxage: 60 }\r\n * // if Date.now is 1516060501948, ttl is 1516060712991\r\n * ```\r\n *\r\n */\r\n public parseCacheControl(cacheControl: string): Metadata {\r\n if (!isString(cacheControl)) {\r\n throw new TypeError(\"parseCacheControl expected cacheControl to be a string.\");\r\n }\r\n\r\n const parsedCacheControl = Cacheability._parseCacheControl(cacheControl);\r\n\r\n this.metadata = {\r\n cacheControl: parsedCacheControl,\r\n ttl: Cacheability._setTTL(parsedCacheControl),\r\n };\r\n\r\n return this.metadata;\r\n }\r\n\r\n /**\r\n * Takes a Headers instance or object literal of header key/values,\r\n * filters the cache-control and etag header fields, parses the\r\n * cache-control into an object literal and derives a TTL from the\r\n * max-age or s-maxage directives. If no max-age or s-maxage\r\n * directives are present, the TTL is given a value of Infinity.\r\n * The data is stored on the cacheability instance's metadata property.\r\n *\r\n * ```typescript\r\n * const headers = new Headers({\r\n * \"cache-control\": \"public, max-age=60\",\r\n * \"content-type\": \"application/json\",\r\n * \"etag\": \"33a64df551425fcc55e4d42a148795d9f25f89d4\",\r\n * });\r\n * const { cacheControl, etag, ttl } = cacheability.parseHeaders(headers);\r\n * // cacheControl is { maxAge: 60, public: true }\r\n * // etag is 33a64df551425fcc55e4d42a148795d9f25f89d4\r\n * // if Date.now is 1516060501948, ttl is 1516060712991\r\n * ```\r\n *\r\n */\r\n public parseHeaders(headers: Headers | CacheHeaders): Metadata {\r\n if (!(headers instanceof Headers) && !isPlainObject(headers)) {\r\n const message = \"parseHeaders expected headers to be an instance of Headers or a plain object.\";\r\n throw new TypeError(message);\r\n }\r\n\r\n const { cacheControl = \"\", etag } = headers instanceof Headers\r\n ? Cacheability._parseHeaders(headers) : headers;\r\n\r\n const parsedCacheControl = Cacheability._parseCacheControl(cacheControl);\r\n\r\n this.metadata = {\r\n cacheControl: parsedCacheControl,\r\n etag,\r\n ttl: Cacheability._setTTL(parsedCacheControl),\r\n };\r\n\r\n return this.metadata;\r\n }\r\n\r\n /**\r\n * The method prints a cache-control header field value based on\r\n * the cacheability instance's metadata. The max-age and/or s-maxage\r\n * are derived from the TTL stored in the metadata.\r\n *\r\n * ```typescript\r\n * cacheability.parseCacheControl(\"public, max-age=60, s-maxage=60\");\r\n * // Five seconds elapse...\r\n * const cacheControl = cacheability.printCacheControl();\r\n * // cacheControl is \"public, max-age=55, s-maxage=55\"\r\n * ```\r\n *\r\n */\r\n public printCacheControl(): string {\r\n if (!this.metadata || !this.metadata.cacheControl) {\r\n throw new TypeError(\"printCacheControl expected this._metadata.cacheControl to be an object\");\r\n }\r\n\r\n if (!Object.values(this.metadata.cacheControl).length) return \"\";\r\n const cacheControl: CacheControl = { ...this.metadata.cacheControl };\r\n\r\n if (cacheControl.sMaxage || cacheControl.maxAge) {\r\n const maxAge = this.checkTTL() ? Math.round((this.metadata.ttl - Date.now()) / 1000) : 0;\r\n if (cacheControl.sMaxage) cacheControl.sMaxage = maxAge;\r\n if (cacheControl.maxAge) cacheControl.maxAge = maxAge;\r\n }\r\n\r\n const directives: string[] = [];\r\n\r\n Object.keys(cacheControl).forEach((key) => {\r\n if (isBoolean(cacheControl[key])) {\r\n directives.push(kebabCase(key));\r\n return;\r\n }\r\n\r\n directives.push(`${kebabCase(key)}=${cacheControl[key]}`);\r\n });\r\n\r\n return directives.join(\", \");\r\n }\r\n}\r\n"]} |
+1
-1
| { | ||
| "name": "cacheability", | ||
| "version": "0.0.57", | ||
| "version": "0.0.59", | ||
| "description": "A utility class to parse, store and print http cache headers.", | ||
@@ -5,0 +5,0 @@ "author": "Dylan Aubrey <dylanaubrey@gmail.com>", |
Sorry, the diff of this file is too big to display
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
217989
0.27%585
1.21%