Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

cache-headers

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cache-headers - npm Package Compare versions

Comparing version 1.0.0 to 1.1.0

__coverage__/clover.xml

139

dist/index.js

@@ -7,10 +7,7 @@ 'use strict';

var url = _interopDefault(require('fast-url-parser'));
var url = _interopDefault(require('url'));
var globject = _interopDefault(require('globject'));
var slasher = _interopDefault(require('glob-slasher'));
var regular = _interopDefault(require('regular'));
var isEmpty = _interopDefault(require('lodash.isempty'));
var moment_src_lib_moment_moment = require('moment/src/lib/moment/moment');
var moment_src_lib_locale_locale = require('moment/src/lib/locale/locale');
var moment_src_lib_format_format = require('moment/src/lib/format/format');
var regular = _interopDefault(require('regular'));

@@ -22,2 +19,5 @@ /**

var KEY_LAST_MODIFIED = 'lastModified';
var KEY_STALE_IF_ERROR = 'staleError';
var KEY_STALE_WHILE_REVALIDATE = 'staleRevalidate';
var KEY_SURROGATE_CONTROL = 'maxAge';

@@ -35,5 +35,2 @@

// Mon, 01, Jan 2016, 00:00:00 UTC
var defaultDateFormat = 'ddd, DD MMM YYYY HH:mm:ss z';
/**

@@ -43,3 +40,3 @@ * @param {*} val The value to check if it is an actual object. Arrays are not considered objects in this case

*/
function isNonEmptyObject(val) {
function isValidObject(val) {
return !Array.isArray(val) && (typeof val === 'undefined' ? 'undefined' : _typeof(val)) === 'object' && !isEmpty(val);

@@ -58,16 +55,5 @@ }

/**
* @param {object} [time] Date object
* @return {object} moment object in UTC format
*/
function getUtcTime() {
var time = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new Date();
return moment_src_lib_moment_moment.createUTC(time);
}
/**
* Format a UTC Date value
* @param {object} options
* @param {number} [options.date=now()] UTC time format. A JavaScript date must be passed in, not a moment date object
* @param {string} [options.dateFormat=defaultDateFormat] Primarily used for testing
* @param {number} [options.date=new Date()] UTC time format. A JavaScript date object
* @return {string} header date string in GMT format

@@ -78,14 +64,11 @@ */

var _options$date = options.date,
date = _options$date === undefined ? moment_src_lib_moment_moment.now() : _options$date,
_options$dateFormat = options.dateFormat,
dateFormat = _options$dateFormat === undefined ? defaultDateFormat : _options$dateFormat;
// keeping this here if we want to
// support setting locales in the future
date = _options$date === undefined ? new Date() : _options$date;
var locale = { key: undefined, config: undefined };
// need to set locale before formatting
moment_src_lib_locale_locale.updateLocale(locale.key, locale.config);
var formatted = moment_src_lib_format_format.formatMoment(getUtcTime(date), dateFormat);
// do browsers require using GMT instead of UTC?
return formatted.replace('UTC', 'GMT');
if (date && date.toString() === 'Invalid Date' || !date) {
// covers if the following are passed in:
// new Date('invalid_date_string')
// date = null
date = new Date();
}
return date.toUTCString();
}

@@ -157,5 +140,3 @@

*/
function generateBrowserCacheHeader() {
var setPrivate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
function generateBrowserCacheHeader(setPrivate) {
if (setPrivate) {

@@ -202,4 +183,3 @@ return PRIVATE_VALUE + ', ' + NO_CACHE_NO_STORE;

*/
function generateCacheControl() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
function generateCacheControl(options) {
var _options$staleRevalid = options.staleRevalidate,

@@ -234,4 +214,3 @@ staleRevalidate = _options$staleRevalid === undefined ? false : _options$staleRevalid,

*/
function generateSurrogateControl() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
function generateSurrogateControl(options) {
var _options$setPrivate2 = options.setPrivate,

@@ -266,4 +245,3 @@ setPrivate = _options$setPrivate2 === undefined ? false : _options$setPrivate2;

function generateLastModifiedHeader() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
function generateLastModifiedHeader(options) {
var _options$lastModified = options.lastModified,

@@ -313,3 +291,3 @@ lastModified = _options$lastModified === undefined ? false : _options$lastModified;

res.set(headerData.name, headerData.value);
} else if (isNonEmptyObject(headerData)) {
} else {
res.set(headerData);

@@ -340,37 +318,35 @@ }

* {{@link module:cacheControl#generate}} for acceptable values
* @memberof index
* @param {object} [config]
* @param {object} [config.cacheSettings=undefined] Cache settings to override the default `paths` settings
* @param {object} [config.paths] Cache settings with glob path patterns
* @param {object} pathsConfig Cache settings with glob path patterns
* @return {Function}
*/
function middleware(config) {
var _ref = config || {},
cacheSettings = _ref.cacheSettings,
paths = _ref.paths;
function setupInitialCacheHeaders(pathsConfig) {
pathsConfig = pathsConfig || {};
return function (req, res, next) {
// current path (prefixed with a slash)
var pathname = slasher(url.parse(req.originalUrl).pathname);
var pathname = url.parse(req.originalUrl).pathname;
var cacheValues = globject(slasher(paths || {}, { value: false }));
var values = cacheValues(slasher(pathname));
/**
* Takes a pathname and returns the first config whose glob key matches
*
* @param pathname - pathname prefixed with slash
* @function
*/
var getCacheConfig = globject(slasher(pathsConfig, { value: false }));
if (isNonEmptyObject(cacheSettings)) {
// override default cacheValue settings
values = generateAllCacheHeaders(cacheSettings);
} else if (isNonEmptyObject(values)) {
values = generateAllCacheHeaders(values);
} else if (values === false) {
var _generateAllCacheHead;
// options by default are set to config
var options = getCacheConfig(pathname);
values = generateAllCacheHeaders((_generateAllCacheHead = {}, _defineProperty(_generateAllCacheHead, KEY_SURROGATE_CONTROL, 0), _defineProperty(_generateAllCacheHead, 'setPrivate', true), _generateAllCacheHead));
} else if (isNumberLike(values)) {
if (options === false) {
var _options;
// current path doesn't match any glob key in pathsConfig
options = (_options = {}, _defineProperty(_options, KEY_SURROGATE_CONTROL, 0), _defineProperty(_options, 'setPrivate', true), _options);
} else if (isNumberLike(options)) {
// catch `0` before !cacheValue check
// make sure to convert value to actual number
values = generateAllCacheHeaders(_defineProperty({}, KEY_SURROGATE_CONTROL, Number(values)));
} else if (!values || isEmpty(values)) {
values = generateAllCacheHeaders();
options = _defineProperty({}, KEY_SURROGATE_CONTROL, Number(options));
}
setHeader(res, values);
setHeader(res, generateAllCacheHeaders(options));

@@ -381,4 +357,33 @@ next();

/**
*
* {{@link module:cacheControl#generate}} for acceptable values
* @param {object} overrideConfig cacheSettings to override default
* @returns {function(*, *=, *)}
*/
function overrideCacheHeaders(overrideConfig) {
return function (req, res, next) {
var options = overrideConfig;
if (overrideConfig === false) {
var _options3;
options = (_options3 = {}, _defineProperty(_options3, KEY_SURROGATE_CONTROL, 0), _defineProperty(_options3, 'setPrivate', true), _options3);
}
if (isValidObject(options)) {
setHeader(res, generateAllCacheHeaders(options));
}
next();
};
}
exports.setAdditionalHeaders = setAdditionalHeaders;
exports.middleware = middleware;
exports.setupInitialCacheHeaders = setupInitialCacheHeaders;
exports.overrideCacheHeaders = overrideCacheHeaders;
exports.KEY_LAST_MODIFIED = KEY_LAST_MODIFIED;
exports.KEY_STALE_IF_ERROR = KEY_STALE_IF_ERROR;
exports.KEY_STALE_WHILE_REVALIDATE = KEY_STALE_WHILE_REVALIDATE;
exports.KEY_SURROGATE_CONTROL = KEY_SURROGATE_CONTROL;
exports.ONE_MINUTE = ONE_MINUTE;

@@ -385,0 +390,0 @@ exports.TEN_MINUTES = TEN_MINUTES;

{
"name": "cache-headers",
"version": "1.0.0",
"version": "1.1.0",
"description": "Generate browser and cdn cache header values",
"main": "dist/index.js",
"nyc": {
"check-coverage": true,
"extension": [
".js"
],
"require": [
"babel-register"
],
"branches": 83,
"functions": 100,
"lines": 100,
"statements": 100,
"sourceMap": false,
"instrument": false
},
"scripts": {
"test": "NODE_ENV=test mocha",
"test": "NODE_ENV=test jest --forceExit --no-cache",
"compile": "rm -rf ./dist && NODE_ENV=build rollup -c",
"coverage": "NODE_ENV=test nyc --reporter=lcov --reporter=text yarn test",
"docs": "rm -rf ./docs && esdoc -c ./esdoc.json",
"lint": "dibslint --root=./src -e --git --warnings",
"precommit": "dibslint --git --warnings -e",
"prepublish": "yarn run coverage && yarn run compile",
"lint": "dibslint --root=./src --es6 --git --warnings",
"precommit": "dibslint --es6 --git --warnings",
"prepublish": "yarn run compile",
"updatedocs": "rm -rf ./docs && yarn run docs && git add ./docs && git commit -n -m 'updated docs v${npm show . version}'",

@@ -34,2 +18,22 @@ "generatedist": "./generate.sh compile dist",

},
"jest": {
"collectCoverage": true,
"coverageDirectory": "<rootDir>/__coverage__",
"coverageThreshold": {
"global": {
"branches": 100,
"functions": 100,
"lines": 100,
"statements": 100
}
},
"setupFiles": [
"<rootDir>/__tests__/testHelper.js"
],
"testPathIgnorePatterns": [
"/node_modules/",
"<rootDir>/__tests__/registerBabel.js",
"<rootDir>/__tests__/testHelper.js"
]
},
"keywords": [

@@ -54,3 +58,2 @@ "cache control",

"devDependencies": {
"async": "^1.5.0",
"babel-cli": "^6.1.2",

@@ -60,7 +63,7 @@ "babel-core": "^6.1.2",

"babel-preset-es2015": "^6.1.2",
"core-js": "^1.2.6",
"core-js": "^2.4.1",
"del": "^2.2.0",
"dibslint": "^1.4.2",
"dibslint": "^2.2.7",
"eslint": "^2.13.1",
"express": "^4.13.3",
"fast-url-parser": "^1.1.3",
"glob-slasher": "^1.0.1",

@@ -71,7 +74,5 @@ "globject": "^1.0.1",

"husky": "^0.11.9",
"jest": "^20.0.1",
"lodash.isempty": "^3.0.4",
"mocha": "^2.3.3",
"moment": "^2.15.2",
"mr-doc": "^3.0.7",
"nyc": "^8.4.0",
"regular": "^0.1.6",

@@ -81,13 +82,13 @@ "rollup": "^0.36.3",

"rollup-plugin-commonjs": "^5.0.5",
"supertest": "^1.1.0"
"supertest": "^3.0.0"
},
"peerDependencies": {
"core-js": "^1.2.6",
"fast-url-parser": "^1.1.3",
"core-js": "^2.4.1"
},
"dependencies": {
"glob-slasher": "^1.0.1",
"globject": "^1.0.1",
"lodash.isempty": "^3.0.4",
"moment": "^2.15.2",
"regular": "^0.1.6"
}
}

@@ -11,2 +11,4 @@ # Cache Headers

```sh
$ yarn add cache-headers
// with npm
$ npm install --save cache-headers

@@ -17,2 +19,5 @@ ```

```sh
$ yarn
$ yarn test
// with npm
$ npm install

@@ -24,3 +29,3 @@ $ npm test

### App-level middleware
### App-level setup middleware

@@ -31,18 +36,11 @@ ```es6

const cache = require('cache-headers');
const cacheOptions = {
const pathsConfig = {
paths: {
'/**/generic': {
maxAge: 'TEN_MINUTES',
sMaxAge: 'ONE_DAY',
staleRevalidate: 'ONE_HOUR',
staleError: 'ONE_HOUR'
},
'/short-cached/route': {
maxAge: 60,
sMaxAge: 600
},
'/default/values': {},
'/user/route': false,
'/**': {
maxAge: 600
}
'/**': 60
}

@@ -53,25 +51,23 @@ };

app.use(cache.middleware(cacheOptions));
app.use(cache.setupInitialCacheHeaders(pathsConfig));
// rest of app setup
```
With the example above, the `Cache-Control` header is set as follows when a user hits these different site routes:
- `/**/generic` (any route ending in `generic`): `Cache-Control: max-age=600, s-maxage=84600, stale-while-revalidate=3600, stale-if-error=3600`
- `/cached/route`: `Cache-Control: max-age=60, s-maxage=600`
- `/user/route`: `Cache-Control: no-cache, max-age=0`
- `/**` (any other route not listed): `Cache-Control: max-age=600`
- `/**/generic` (any route ending in `generic`)
- `Cache-Control: no-cache, no-store, must-revalidate, stale-while-revalidate=3600, stale-if-error=3600`
- `Surrogate-Control: maxAge=600`
- `/default/values`
- `Cache-Control: no-cache, no-store, must-revalidate`
- `Surrogate-Control: maxAge=600`
- `/user/route`
- `Cache-Control: private, no-cache, no-store, must-revalidate`
- `Surrogate-Control: maxAge=0`
- `/**` (any other route not listed)
- `Cache-Control: no-cache, no-store, must-revalidate`
- `Surrogate-Control: maxAge=60`
Alternatively for `no-cache`, the following could be used:
```js
'/user/route': {
setNoCache: true
}
```
### Router-level middleware
Taking the app-level setup above, you can additionally override the default `paths` initially set in the `cacheOptions`.
Taking the app-level setup above, you can additionally override the default `pathsConfig` initially set.
```es6

@@ -81,12 +77,10 @@ const express = require('express');

const cache = require('cache-headers');
const cacheOptions = {
cacheSettings: {
"maxAge": 2000
}
const overrideConfig = {
"maxAge": 2000
};
// app.use(cache.middleware(cacheOptions)) is loaded prior to this route, therefore running by default
// app.use(cache.setupInitialCacheHeaders(pathsConfig)) is loaded prior to this route, therefore running by default
// and any subsequent call to set the header is then overwritten
router.get('/endswith/generic', cache.middleware(cacheOptions), (req, res, next) => {
router.get('/endswith/generic', cache.overrideCacheHeaders(overrideConfig), (req, res, next) => {
// do route-y stuff

@@ -98,21 +92,26 @@ next();

Rather than set the original headers defined in the `paths` config in the app-level setup (for the `/**/generic` path), this will output the following: `Cache-Control: max-age=2000`
Rather than set the original headers defined in the `pathsConfig` config in the app-level setup (for the `/**/generic` path), this will output the following:
```
Cache-Control: no-cache, no-store, must-revalidate
Surrogate-Control: maxAge=2000
```
## API
### cache.middleware (all properties optional)
### `cache.setupInitialCacheHeaders(pathsConfig)`
```js
{
cacheSettings: {
maxAge: number|string,
sMaxAge: number|string,
staleRevalidate: number|string,
staleError: number|string
},
paths: {
'/glob/**/path': object|boolean=false
}
'/glob/**/path': object|string|boolean=false
}
```
The following are acceptable keys to use if an object is passed in
| key | type | description | default |
| --- | ---- | ----------- | ------- |
| `lastModified` | string | set `Last-Modified Header` | current date |
| `maxAge` | string, number | number or string representing a number for `Surrogate-Control: max-age` (forced to `0` if `setPrivate=true`) | `TEN_MINUTES` (600 seconds) |
| `setPrivate` | boolean | should add `Cache-Control: private` (if set to `true` forces `Surrogate-Control: maxAge=0`) | false |
| `staleError` | string, number | number or string representing a number for `Cache-Control: stale-if-error` | |
| `staleRevalidate` | string, number | number or string representing a number for `Cache-Control: stale-while-revalidate` | |
The following are acceptable values to use if a string is passed in for cache values:

@@ -128,6 +127,79 @@

If no options are passed in, the default value set is `Cache-Control: max-age=600`
The following are acceptable values to use if a boolean is passed in
- `false` - this is equivalent to passing `{ setPrivate: true, maxAge: 0 }`
If no options are passed in, the default value set is
```
Cache-Control: no-cache, no-store, must-revalidate
Surrogate-Control: max-age=600
```
### `cache.overrideCacheHeaders(overrideConfig)`
```js
{
lastModified: string,
maxAge: number|string,
setPrivate: boolean,
staleError: number|string,
staleRevalidate: number|string
}
```
| key | type | description | default |
| --- | ---- | ----------- | ------- |
| `lastModified` | string | set `Last-Modified Header` | current date |
| `maxAge` | string, number | number or string representing a number for `Surrogate-Control: max-age` (forced to `0` if `setPrivate=true`) | `TEN_MINUTES` (600 seconds) |
| `setPrivate` | boolean | should add `Cache-Control: private` (if set to `true` forces `Surrogate-Control: maxAge=0`) | false |
| `staleError` | string, number | number or string representing a number for `Cache-Control: stale-if-error` | |
| `staleRevalidate` | string, number | number or string representing a number for `Cache-Control: stale-while-revalidate` | |
## Recipes
#### Private Pages
Options for pages that are intended for a single user and should not be cached.
```js
{
setPrivate: true
}
```
Headers Output:
```
'Cache-Control': 'private, no-cache, no-store, must-revalidate'
'Surrogate-Control': 'maxAge=0'
'Pragma': 'no-cache'
'Expires': 0
'Last-Modified': (NOW)
```
#### Browser/Server Cached Pages
Options for pages that are intended for all users and should be cached in both the browser and the server.
```js
{
maxAge: 'ONE_WEEK', // cache on server
staleError: 'ONE_MONTH', // cache on browser if server returns error
staleRevalidate: 'TEN_MINUTES' // cache on browser for 10 min
}
```
Headers Output:
```
'Cache-Control': 'no-cache, no-store, must-revalidate, stale-while-revalidate=600, stale-if-error=2592000'
'Surrogate-Control': 'maxAge=604800'
'Pragma': 'no-cache'
'Expires': 0
'Last-Modified': (NOW)
```
## Additional notes on header use / specification
- `Cache-Control`
- `private` - response intended for single user and should not be cached
- `no-cache, no-store, must-revalidate` - turns off browser caching
- `stale-while-revalidate={seconds}` - use stale version for up to `{seconds}` while re-fetching latest version background
- `stale-if-error={seconds}` - use stale version if re-fetch fails within `{seconds}` of response becoming stale
- `Surrogate-Control`
- takes priority over `Cache-Control`, but is stripped so browsers don't see it
- `max-age={seconds}` - how long the response can be considered fresh
*(For more information on `Surrogate-Control`/`Cache-Control` headers read [Fastly Cache Control Tutorials](https://docs.fastly.com/guides/tutorials/cache-control-tutorial) and [W3 Specification](https://www.w3.org/TR/edge-arch/).)*
## Contributing
All code additions and bugfixes must be accompanied by unit tests. Tests are run with mocha and
All code additions and bugfixes must be accompanied by unit tests. Tests are run with jest and
written with the node [`assert`][assert] module.

@@ -138,2 +210,4 @@

[eslint-rules]: https://github.com/1stdibs/eslint-config-1stdibs

@@ -140,0 +214,0 @@ [babel]: https://babeljs.io/

@@ -36,3 +36,3 @@ import {isNumberLike, formatDate} from './utils';

*/
function generateBrowserCacheHeader(setPrivate = false) {
function generateBrowserCacheHeader(setPrivate) {
if (setPrivate) {

@@ -79,3 +79,3 @@ return `${PRIVATE_VALUE}, ${NO_CACHE_NO_STORE}`;

*/
function generateCacheControl(options = {}) {
function generateCacheControl(options) {
const {

@@ -108,3 +108,3 @@ staleRevalidate = false,

*/
function generateSurrogateControl(options = {}) {
function generateSurrogateControl(options) {
const {

@@ -140,3 +140,3 @@ // private should only be used for user-specific pages. ie account pages

function generateLastModifiedHeader(options = {}) {
function generateLastModifiedHeader(options) {
let {lastModified = false} = options;

@@ -143,0 +143,0 @@

@@ -11,6 +11,5 @@ /**

import url from 'fast-url-parser';
import url from 'url';
import globject from 'globject';
import slasher from 'glob-slasher';
import isEmpty from 'lodash.isempty';
import {

@@ -20,4 +19,5 @@ KEY_SURROGATE_CONTROL

import { generateAllCacheHeaders } from './cacheControl';
import { isNumberLike, isNonEmptyObject } from './utils';
import { isNumberLike, isValidObject } from './utils';
export * from './headerTypes';
export * from './timeValues';

@@ -36,3 +36,3 @@

res.set(headerData.name, headerData.value);
} else if (isNonEmptyObject(headerData)) {
} else {
res.set(headerData);

@@ -59,37 +59,38 @@ }

* {{@link module:cacheControl#generate}} for acceptable values
* @memberof index
* @param {object} [config]
* @param {object} [config.cacheSettings=undefined] Cache settings to override the default `paths` settings
* @param {object} [config.paths] Cache settings with glob path patterns
* @param {object} pathsConfig Cache settings with glob path patterns
* @return {Function}
*/
export function middleware(config) {
export function setupInitialCacheHeaders(pathsConfig) {
pathsConfig = pathsConfig || {};
const { cacheSettings, paths } = config || {};
return (req, res, next) => {
// current path (prefixed with a slash)
const pathname = slasher(url.parse(req.originalUrl).pathname);
const pathname = url.parse(req.originalUrl).pathname;
const cacheValues = globject(slasher(paths || {}, {value: false}));
let values = cacheValues(slasher(pathname));
/**
* Takes a pathname and returns the first config whose glob key matches
*
* @param pathname - pathname prefixed with slash
* @function
*/
const getCacheConfig = globject(slasher(pathsConfig, { value: false }));
if (isNonEmptyObject(cacheSettings)) {
// override default cacheValue settings
values = generateAllCacheHeaders(cacheSettings);
} else if (isNonEmptyObject(values)) {
values = generateAllCacheHeaders(values);
} else if (values === false) {
values = generateAllCacheHeaders({
// options by default are set to config
let options = getCacheConfig(pathname);
if (options === false) {
// current path doesn't match any glob key in pathsConfig
options = {
[KEY_SURROGATE_CONTROL]: 0,
setPrivate: true
});
} else if (isNumberLike(values)) {
};
} else if (isNumberLike(options)) {
// catch `0` before !cacheValue check
// make sure to convert value to actual number
values = generateAllCacheHeaders({ [KEY_SURROGATE_CONTROL]: Number(values) });
} else if (!values || isEmpty(values)) {
values = generateAllCacheHeaders();
options = {
[KEY_SURROGATE_CONTROL]: Number(options)
};
}
setHeader(res, values);
setHeader(res, generateAllCacheHeaders(options));

@@ -99,1 +100,26 @@ next();

}
/**
*
* {{@link module:cacheControl#generate}} for acceptable values
* @param {object} overrideConfig cacheSettings to override default
* @returns {function(*, *=, *)}
*/
export function overrideCacheHeaders(overrideConfig) {
return (req, res, next) => {
let options = overrideConfig;
if (overrideConfig === false) {
options = {
[KEY_SURROGATE_CONTROL]: 0,
setPrivate: true
};
}
if (isValidObject(options)) {
setHeader(res, generateAllCacheHeaders(options));
}
next();
};
}

@@ -11,11 +11,5 @@ /**

import {now, createUTC as utc} from 'moment/src/lib/moment/moment';
import {updateLocale} from 'moment/src/lib/locale/locale';
import {formatMoment} from 'moment/src/lib/format/format';
import regular from 'regular';
import isEmpty from 'lodash.isempty';
// Mon, 01, Jan 2016, 00:00:00 UTC
const defaultDateFormat = 'ddd, DD MMM YYYY HH:mm:ss z';
/**

@@ -25,3 +19,3 @@ * @param {*} val The value to check if it is an actual object. Arrays are not considered objects in this case

*/
export function isNonEmptyObject(val) {
export function isValidObject(val) {
return !Array.isArray(val) && typeof val === 'object' && !isEmpty(val);

@@ -40,29 +34,16 @@ }

/**
* @param {object} [time] Date object
* @return {object} moment object in UTC format
*/
function getUtcTime(time = new Date()) {
return utc(time);
}
/**
* Format a UTC Date value
* @param {object} options
* @param {number} [options.date=now()] UTC time format. A JavaScript date must be passed in, not a moment date object
* @param {string} [options.dateFormat=defaultDateFormat] Primarily used for testing
* @param {number} [options.date=new Date()] UTC time format. A JavaScript date object
* @return {string} header date string in GMT format
*/
export function formatDate(options = {}) {
const {
date = now(),
dateFormat = defaultDateFormat
} = options;
// keeping this here if we want to
// support setting locales in the future
const locale = {key: undefined, config: undefined};
// need to set locale before formatting
updateLocale(locale.key, locale.config);
const formatted = formatMoment(getUtcTime(date), dateFormat);
// do browsers require using GMT instead of UTC?
return formatted.replace('UTC', 'GMT');
let {date = new Date()} = options;
if ((date && date.toString() === 'Invalid Date') || !date) {
// covers if the following are passed in:
// new Date('invalid_date_string')
// date = null
date = new Date();
}
return date.toUTCString();
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc