Comparing version 2.5.0 to 2.5.1
import * as cookie from 'cookie'; | ||
import * as express from 'express'; | ||
import * as next from 'next'; | ||
import * as express from 'express'; | ||
/** | ||
* | ||
* Parses cookies. | ||
* | ||
* @param ctx | ||
* @param options | ||
* @param ctx NextJS page or API context, express context, null or undefined. | ||
* @param options Options that we pass down to `cookie` library. | ||
*/ | ||
@@ -19,9 +18,8 @@ export declare function parseCookies(ctx?: Pick<next.NextPageContext, 'req'> | { | ||
/** | ||
* | ||
* Sets a cookie. | ||
* | ||
* @param ctx | ||
* @param name | ||
* @param value | ||
* @param options | ||
* @param ctx NextJS page or API context, express context, null or undefined. | ||
* @param name The name of your cookie. | ||
* @param value The value of your cookie. | ||
* @param options Options that we pass down to `cookie` library. | ||
*/ | ||
@@ -34,8 +32,7 @@ export declare function setCookie(ctx: Pick<next.NextPageContext, 'res'> | { | ||
/** | ||
* | ||
* Destroys a cookie with a particular name. | ||
* | ||
* @param ctx | ||
* @param name | ||
* @param options | ||
* @param ctx NextJS page or API context, express context, null or undefined. | ||
* @param name Cookie name. | ||
* @param options Options that we pass down to `cookie` library. | ||
*/ | ||
@@ -42,0 +39,0 @@ export declare function destroyCookie(ctx: Pick<next.NextPageContext, 'res'> | { |
@@ -17,62 +17,15 @@ "use strict"; | ||
var setCookieParser = require("set-cookie-parser"); | ||
var isBrowser = function () { return typeof window !== 'undefined'; }; | ||
function hasSameProperties(a, b) { | ||
var aProps = Object.getOwnPropertyNames(a); | ||
var bProps = Object.getOwnPropertyNames(b); | ||
if (aProps.length !== bProps.length) { | ||
return false; | ||
} | ||
for (var i = 0; i < aProps.length; i++) { | ||
var propName = aProps[i]; | ||
if (a[propName] !== b[propName]) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
var utils_1 = require("./utils"); | ||
/** | ||
* Compare the cookie and return true if the cookies has equivalent | ||
* options and the cookies would be overwritten in the browser storage. | ||
* | ||
* @param a first Cookie for comparison | ||
* @param b second Cookie for comparison | ||
*/ | ||
function areCookiesEqual(a, b) { | ||
var sameSiteSame = a.sameSite === b.sameSite; | ||
if (typeof a.sameSite === 'string' && typeof b.sameSite === 'string') { | ||
sameSiteSame = a.sameSite.toLowerCase() === b.sameSite.toLowerCase(); | ||
} | ||
return (hasSameProperties(__assign(__assign({}, a), { sameSite: undefined }), __assign(__assign({}, b), { sameSite: undefined })) && sameSiteSame); | ||
} | ||
/** | ||
* Create an instance of the Cookie interface | ||
* | ||
* @param name name of the Cookie | ||
* @param value value of the Cookie | ||
* @param options Cookie options | ||
*/ | ||
function createCookie(name, value, options) { | ||
var sameSite = options.sameSite; | ||
if (sameSite === true) { | ||
sameSite = 'strict'; | ||
} | ||
if (sameSite === undefined || sameSite === false) { | ||
sameSite = 'lax'; | ||
} | ||
var cookieToSet = __assign(__assign({}, options), { sameSite: sameSite }); | ||
delete cookieToSet.encode; | ||
return __assign({ name: name, value: value }, cookieToSet); | ||
} | ||
/** | ||
* | ||
* Parses cookies. | ||
* | ||
* @param ctx | ||
* @param options | ||
* @param ctx NextJS page or API context, express context, null or undefined. | ||
* @param options Options that we pass down to `cookie` library. | ||
*/ | ||
function parseCookies(ctx, options) { | ||
if (ctx && ctx.req && ctx.req.headers && ctx.req.headers.cookie) { | ||
var _a, _b; | ||
if ((_b = (_a = ctx === null || ctx === void 0 ? void 0 : ctx.req) === null || _a === void 0 ? void 0 : _a.headers) === null || _b === void 0 ? void 0 : _b.cookie) { | ||
return cookie.parse(ctx.req.headers.cookie, options); | ||
} | ||
if (isBrowser()) { | ||
if (utils_1.isBrowser()) { | ||
return cookie.parse(document.cookie, options); | ||
@@ -84,12 +37,22 @@ } | ||
/** | ||
* | ||
* Sets a cookie. | ||
* | ||
* @param ctx | ||
* @param name | ||
* @param value | ||
* @param options | ||
* @param ctx NextJS page or API context, express context, null or undefined. | ||
* @param name The name of your cookie. | ||
* @param value The value of your cookie. | ||
* @param options Options that we pass down to `cookie` library. | ||
*/ | ||
function setCookie(ctx, name, value, options) { | ||
if (ctx && ctx.res && ctx.res.getHeader && ctx.res.setHeader) { | ||
var _a, _b; | ||
// SSR | ||
if (((_a = ctx === null || ctx === void 0 ? void 0 : ctx.res) === null || _a === void 0 ? void 0 : _a.getHeader) && ctx.res.setHeader) { | ||
// Check if response has finished and warn about it. | ||
if ((_b = ctx === null || ctx === void 0 ? void 0 : ctx.res) === null || _b === void 0 ? void 0 : _b.finished) { | ||
console.warn("Not setting \"" + name + "\" cookie. Response has finished."); | ||
console.warn("You should set cookie before res.send()"); | ||
return {}; | ||
} | ||
/** | ||
* Load existing cookies from the header and parse them. | ||
*/ | ||
var cookies = ctx.res.getHeader('Set-Cookie') || []; | ||
@@ -100,15 +63,33 @@ if (typeof cookies === 'string') | ||
cookies = []; | ||
var parsedCookies = setCookieParser.parse(cookies); | ||
/** | ||
* Parse cookies but ignore values - we've already encoded | ||
* them in the previous call. | ||
*/ | ||
var parsedCookies = setCookieParser.parse(cookies, { | ||
decodeValues: false, | ||
}); | ||
/** | ||
* We create the new cookie and make sure that none of | ||
* the existing cookies match it. | ||
*/ | ||
var newCookie_1 = utils_1.createCookie(name, value, options); | ||
var cookiesToSet_1 = []; | ||
parsedCookies.forEach(function (parsedCookie) { | ||
if (!areCookiesEqual(parsedCookie, createCookie(name, value, options))) { | ||
cookiesToSet_1.push(cookie.serialize(parsedCookie.name, parsedCookie.value, __assign({ encode: function (val) { return val; } }, parsedCookie))); | ||
if (!utils_1.areCookiesEqual(parsedCookie, newCookie_1)) { | ||
/** | ||
* We serialize the cookie back to the original format | ||
* if it isn't the same as the new one. | ||
*/ | ||
var serializedCookie = cookie.serialize(parsedCookie.name, parsedCookie.value, __assign({ | ||
// we prevent reencoding by default, but you might override it | ||
encode: function (val) { return val; } }, parsedCookie)); | ||
cookiesToSet_1.push(serializedCookie); | ||
} | ||
}); | ||
cookiesToSet_1.push(cookie.serialize(name, value, options)); | ||
if (!ctx.res.finished) { | ||
ctx.res.setHeader('Set-Cookie', cookiesToSet_1); | ||
} | ||
// Update the header. | ||
ctx.res.setHeader('Set-Cookie', cookiesToSet_1); | ||
} | ||
if (isBrowser()) { | ||
// Browser | ||
if (utils_1.isBrowser()) { | ||
if (options && options.httpOnly) { | ||
@@ -123,26 +104,17 @@ throw new Error('Can not set a httpOnly cookie in the browser.'); | ||
/** | ||
* | ||
* Destroys a cookie with a particular name. | ||
* | ||
* @param ctx | ||
* @param name | ||
* @param options | ||
* @param ctx NextJS page or API context, express context, null or undefined. | ||
* @param name Cookie name. | ||
* @param options Options that we pass down to `cookie` library. | ||
*/ | ||
function destroyCookie(ctx, name, options) { | ||
var opts = __assign(__assign({}, (options || {})), { maxAge: -1 }); | ||
if (ctx && ctx.res && ctx.res.setHeader && ctx.res.getHeader) { | ||
var cookies = ctx.res.getHeader('Set-Cookie') || []; | ||
if (typeof cookies === 'string') | ||
cookies = [cookies]; | ||
if (typeof cookies === 'number') | ||
cookies = []; | ||
cookies.push(cookie.serialize(name, '', opts)); | ||
ctx.res.setHeader('Set-Cookie', cookies); | ||
} | ||
if (isBrowser()) { | ||
document.cookie = cookie.serialize(name, '', opts); | ||
} | ||
return {}; | ||
/** | ||
* We forward the request destroy to setCookie function | ||
* as it is the same function with modified maxAge value. | ||
*/ | ||
return setCookie(ctx, name, '', __assign(__assign({}, (options || {})), { maxAge: -1 })); | ||
} | ||
exports.destroyCookie = destroyCookie; | ||
/* Utility Exports */ | ||
exports.default = { | ||
@@ -149,0 +121,0 @@ set: setCookie, |
@@ -1,2 +0,2 @@ | ||
"use strict";var __assign=this&&this.__assign||function(){return(__assign=Object.assign||function(e){for(var o,r=1,s=arguments.length;r<s;r++)for(var t in o=arguments[r])Object.prototype.hasOwnProperty.call(o,t)&&(e[t]=o[t]);return e}).apply(this,arguments)};Object.defineProperty(exports,"__esModule",{value:!0}),exports.destroyCookie=exports.setCookie=exports.parseCookies=void 0;var cookie=require("cookie"),setCookieParser=require("set-cookie-parser"),isBrowser=function(){return"undefined"!=typeof window};function hasSameProperties(e,o){var r=Object.getOwnPropertyNames(e),s=Object.getOwnPropertyNames(o);if(r.length!==s.length)return!1;for(var t=0;t<r.length;t++){var i=r[t];if(e[i]!==o[i])return!1}return!0}function areCookiesEqual(e,o){var r=e.sameSite===o.sameSite;return"string"==typeof e.sameSite&&"string"==typeof o.sameSite&&(r=e.sameSite.toLowerCase()===o.sameSite.toLowerCase()),hasSameProperties(__assign(__assign({},e),{sameSite:void 0}),__assign(__assign({},o),{sameSite:void 0}))&&r}function createCookie(e,o,r){var s=r.sameSite;!0===s&&(s="strict"),void 0!==s&&!1!==s||(s="lax");var t=__assign(__assign({},r),{sameSite:s});return delete t.encode,__assign({name:e,value:o},t)}function parseCookies(e,o){return e&&e.req&&e.req.headers&&e.req.headers.cookie?cookie.parse(e.req.headers.cookie,o):isBrowser()?cookie.parse(document.cookie,o):{}}function setCookie(e,o,r,s){if(e&&e.res&&e.res.getHeader&&e.res.setHeader){var t=e.res.getHeader("Set-Cookie")||[];"string"==typeof t&&(t=[t]),"number"==typeof t&&(t=[]);var i=setCookieParser.parse(t),a=[];i.forEach((function(e){areCookiesEqual(e,createCookie(o,r,s))||a.push(cookie.serialize(e.name,e.value,__assign({encode:function(e){return e}},e)))})),a.push(cookie.serialize(o,r,s)),e.res.finished||e.res.setHeader("Set-Cookie",a)}if(isBrowser()){if(s&&s.httpOnly)throw new Error("Can not set a httpOnly cookie in the browser.");document.cookie=cookie.serialize(o,r,s)}return{}}function destroyCookie(e,o,r){var s=__assign(__assign({},r||{}),{maxAge:-1});if(e&&e.res&&e.res.setHeader&&e.res.getHeader){var t=e.res.getHeader("Set-Cookie")||[];"string"==typeof t&&(t=[t]),"number"==typeof t&&(t=[]),t.push(cookie.serialize(o,"",s)),e.res.setHeader("Set-Cookie",t)}return isBrowser()&&(document.cookie=cookie.serialize(o,"",s)),{}}exports.parseCookies=parseCookies,exports.setCookie=setCookie,exports.destroyCookie=destroyCookie,exports.default={set:setCookie,get:parseCookies,destroy:destroyCookie}; | ||
"use strict";var __assign=this&&this.__assign||function(){return(__assign=Object.assign||function(e){for(var o,s=1,r=arguments.length;s<r;s++)for(var i in o=arguments[s])Object.prototype.hasOwnProperty.call(o,i)&&(e[i]=o[i]);return e}).apply(this,arguments)};Object.defineProperty(exports,"__esModule",{value:!0}),exports.destroyCookie=exports.setCookie=exports.parseCookies=void 0;var cookie=require("cookie"),setCookieParser=require("set-cookie-parser"),utils_1=require("./utils");function parseCookies(e,o){var s,r;return(null===(r=null===(s=null==e?void 0:e.req)||void 0===s?void 0:s.headers)||void 0===r?void 0:r.cookie)?cookie.parse(e.req.headers.cookie,o):utils_1.isBrowser()?cookie.parse(document.cookie,o):{}}function setCookie(e,o,s,r){var i,t;if((null===(i=null==e?void 0:e.res)||void 0===i?void 0:i.getHeader)&&e.res.setHeader){if(null===(t=null==e?void 0:e.res)||void 0===t?void 0:t.finished)return console.warn('Not setting "'+o+'" cookie. Response has finished.'),console.warn("You should set cookie before res.send()"),{};var n=e.res.getHeader("Set-Cookie")||[];"string"==typeof n&&(n=[n]),"number"==typeof n&&(n=[]);var a=setCookieParser.parse(n,{decodeValues:!1}),u=utils_1.createCookie(o,s,r),l=[];a.forEach((function(e){if(!utils_1.areCookiesEqual(e,u)){var o=cookie.serialize(e.name,e.value,__assign({encode:function(e){return e}},e));l.push(o)}})),l.push(cookie.serialize(o,s,r)),e.res.setHeader("Set-Cookie",l)}if(utils_1.isBrowser()){if(r&&r.httpOnly)throw new Error("Can not set a httpOnly cookie in the browser.");document.cookie=cookie.serialize(o,s,r)}return{}}function destroyCookie(e,o,s){return setCookie(e,o,"",__assign(__assign({},s||{}),{maxAge:-1}))}exports.parseCookies=parseCookies,exports.setCookie=setCookie,exports.destroyCookie=destroyCookie,exports.default={set:setCookie,get:parseCookies,destroy:destroyCookie}; | ||
//# sourceMappingURL=index.min.js.map |
{ | ||
"name": "nookies", | ||
"description": "A set of cookie helpers for Next.js", | ||
"version": "2.5.0", | ||
"version": "2.5.1", | ||
"main": "dist/index.js", | ||
@@ -12,14 +12,8 @@ "types": "dist/index.d.ts", | ||
}, | ||
"files": [ | ||
"dist" | ||
], | ||
"scripts": { | ||
"clean": "rimraf dist", | ||
"compile": "tsc -d && yarn run minify", | ||
"minify": "terser -c -m --source-map \"content='./dist/index.js.map',url='index.min.js.map'\" -o dist/index.min.js -- dist/index.js", | ||
"pretest": "npm run clean && npm run compile", | ||
"test": "echo 'test'", | ||
"posttest": "npm run lint", | ||
"lint": "tslint --project tsconfig.json {src}/**/*.ts && prettier-check --ignore-path .gitignore src/**/*.ts", | ||
"prettier": "prettier --write --ignore-path .gitignore src/**/*.ts", | ||
"prepublishOnly": "npm run compile", | ||
"prerelease": "npm run test", | ||
"semantic-release": "semantic-release" | ||
"build": "yarn g:tsc -d && yarn run minify", | ||
"minify": "terser -c -m --source-map \"content='./dist/index.js.map',url='index.min.js.map'\" -o dist/index.min.js -- dist/index.js" | ||
}, | ||
@@ -32,19 +26,7 @@ "dependencies": { | ||
"@types/cookie": "0.4.0", | ||
"@types/express": "4.17.8", | ||
"@types/express": "4.17.11", | ||
"@types/next": "9.0.0", | ||
"@types/node": "14.14.6", | ||
"@types/node": "14.14.21", | ||
"@types/set-cookie-parser": "2.4.0", | ||
"husky": "4.3.0", | ||
"prettier": "2.1.2", | ||
"prettier-check": "2.0.0", | ||
"pretty-quick": "3.1.0", | ||
"rimraf": "3.0.2", | ||
"semantic-release": "17.2.2", | ||
"terser": "5.3.8", | ||
"ts-loader": "6.2.2", | ||
"ts-node": "9.0.0", | ||
"tslint": "6.1.3", | ||
"tslint-config-prettier": "1.18.0", | ||
"tslint-config-standard": "9.0.0", | ||
"typescript": "4.0.5" | ||
"terser": "5.5.1" | ||
}, | ||
@@ -51,0 +33,0 @@ "keywords": [ |
@@ -1,71 +0,26 @@ | ||
# nookies :cookie: :cookie: :cookie: | ||
# nookies :cookie: | ||
[](https://circleci.com/gh/maticzav/nookies/tree/master) [](https://badge.fury.io/js/nookies) | ||
 | ||
[](https://badge.fury.io/js/nookies) | ||
A collection of cookie helpers for Next.js | ||
> A collection of cookie helpers for Next.js | ||
- SSR support, for setter, parser and destroy | ||
- Custom Express server support | ||
- super light | ||
- perfect for authentication | ||
## Features | ||
- ✨ SSR support, for setter, parser and destroy | ||
- ⚙️ Custom Express server support | ||
- 🪶 super light | ||
- 🛡 perfect for authentication | ||
Setting and destroying cookies also works on server-side. | ||
<!-- BANNER START --> | ||
[](https://label-sync.com) | ||
<!-- BANNER END --> | ||
## Quick start | ||
`npm install --save nookies` | ||
`yarn add nookies` | ||
## Demo | ||
> You can play with the example code [here](https://codesandbox.io/s/charming-herschel-7z362). | ||
Try a demo of the example code below here: | ||
### ServerSide cookies | ||
### [Demo on CodeSandbox](https://codesandbox.io/s/charming-herschel-7z362) | ||
## `getServerSideProps` cookies (SSR + Client) | ||
```js | ||
import { parseCookies, setCookie, destroyCookie } from 'nookies' | ||
export default function Me({ cookies }) { | ||
return ( | ||
<div> | ||
My profile. Cookies: | ||
<ul> | ||
{cookies && | ||
Object.entries(cookies).map(([name, value]) => ( | ||
<li> | ||
{name}: {value} | ||
</li> | ||
))} | ||
</ul> | ||
</div> | ||
) | ||
} | ||
export async function getServerSideProps(ctx) { | ||
// Parse | ||
const cookies = parseCookies(ctx) | ||
// Set | ||
setCookie(ctx, 'fromGetServerSideProps', 'value', { | ||
maxAge: 30 * 24 * 60 * 60, | ||
path: '/', | ||
}) | ||
// Destroy | ||
// destroyCookie(ctx, 'cookieName') | ||
return { cookies } | ||
} | ||
``` | ||
OR | ||
```js | ||
import nookies from 'nookies' | ||
@@ -154,5 +109,5 @@ | ||
> For client side usage, omit the `ctx` parameter. You can do so by setting it to an empty object (`{}`). | ||
> For client side usage, omit the `ctx` parameter. You can do so by setting it to an empty object (`{}`), `null` or `undefined`. | ||
### `parseCookies(ctx, options)` or `cookies.get(ctx, options)` | ||
### `parseCookies(ctx, options)` or `nookies.get(ctx, options)` | ||
@@ -163,4 +118,6 @@ - **ctx:** `Next.js context` || `(Express request object)` | ||
### `setCookie(ctx, name, value, options)` or `cookies.set(ctx, name, value, options)` | ||
### `setCookie(ctx, name, value, options)` or `nookies.set(ctx, name, value, options)` | ||
> Don't forget to end your response on the server with `res.send()`. | ||
- **ctx:** `(Next.js context)` || `(Express request object)` | ||
@@ -179,4 +136,6 @@ - **name:** cookie name | ||
### `destroyCookie(ctx, name, options)` or `cookies.destroy(ctx, 'token', options)` | ||
### `destroyCookie(ctx, name, options)` or `nookies.destroy(ctx, 'token', options)` | ||
> Don't forget to end your response on the server with `res.send()`. This might be the reason your cookie isn't removed. | ||
- **ctx:** `(Next.js context)` || `(Express response object)` | ||
@@ -183,0 +142,0 @@ - **name:** cookie name |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
6
21729
10
271
147
1