├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .travis.yml ├── Readme.md ├── index.d.ts ├── index.js ├── nightwatch.json ├── package.json └── tests ├── .eslintrc.js ├── integration └── next-cookies.test.js ├── run_integration_tests.js └── test-app ├── package-lock.json ├── package.json └── pages ├── api ├── delete-cookie.js ├── set-cookie-json.js └── set-cookie.js ├── cookies.js ├── index.js └── parsed-unparsed.js /.eslintignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # include it's config file 4 | !.eslintrc.js 5 | 6 | # dependencies 7 | /tests/test-app/node_modules/ 8 | /node_modules 9 | /tests/test-app/.pnp 10 | 11 | # testing 12 | /coverage 13 | /tests_output 14 | 15 | # next.js 16 | /tests/test-app/.next/ 17 | /tests/test-app/out/ 18 | 19 | # production 20 | /tests/test-app/build 21 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["eslint:recommended", "plugin:prettier/recommended"], 3 | env: { 4 | node: true, 5 | browser: true, 6 | es6: false 7 | }, 8 | rules: { 9 | "prettier/prettier": "warn" 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /tests/test-app/node_modules/ 5 | /node_modules 6 | /tests/test-app/.pnp 7 | .pnp.js 8 | 9 | # this is to work around travis ci issues: 10 | # travis only allows you to request the current stable or beta versions of chrome, not a specific version 11 | # chromedriver versions are tied to specific chrome versions 12 | # we currently request chrome stable in .travis.yml and the latest stable chromedriver in package.json 13 | # however, if there is a package-lock.json it will specify a particular version of chromedriver and travis-ci will use that 14 | # this then leads to test failures later on when they get out of sync 15 | package-lock.json 16 | 17 | # testing 18 | /coverage 19 | /tests_output 20 | chromedriver.log 21 | 22 | # next.js 23 | /tests/test-app/.next/ 24 | /tests/test-app/out/ 25 | 26 | # production 27 | /tests/test-app/build 28 | 29 | # misc 30 | .DS_Store 31 | .env* 32 | 33 | # debug 34 | npm-debug.log* 35 | yarn-debug.log* 36 | yarn-error.log* 37 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 12 4 | 5 | addons: 6 | chrome: stable 7 | 8 | deploy: 9 | provider: npm 10 | email: nathan@nfriedly.com 11 | api_key: 12 | secure: Q2G17DR9I1z4dROvPTxCLWZX/6iTA0tVf7hVI773m5gzSz0koCDAzXHc5Y53KwyJHb57z9g6ren3iRxWaZ+OKrilOs9CbmsRHHcjmKeq7sCg0znWhev81C5oU1tUropElnuEYoYDXVwqwkz2yC0bITGrlKbrpvARSTmIuAl1GuseBWgy0+fzQ108cLW/d4TgwBgRP8aaw4g6Rl80s5v3fCbrhF8iWPLVofIK/6ZOvma8LcQVBB7jd7JgprNwTgrydYFTivQ47zs9KTsfuxqN/gQjqkbLNlqd+srSrSVasBnzPc+4QJ5z/RLyjA5uMVt7nTcr1EvXFGwcS3+Uw3A2g70GfQKn7BObw/EWTJ2Q2ldAXWcxEjqEVDEeS6aIsqwI0vs3/MkaWLxS0u728BY2wN+O2HFaQfUv0/PY/fsOwvTIn9SA+3O2DzSiyJnmeZOokmeBWcv+6cTxtXi6d2DmGU+NxR5VRlMYe8LV63G9vMbj7fXPnlvt2cnC2M0VGWCJ2/x4vnCyHB9xSg2pNFGkIkoRAbCL+hvVUml1+CxnQAetI1R6l4XCi7oMYGMB9wAvtepj1jicY4Kn2zFCRhCQ9F3MgUXL+OljocpH06/wSZj9n9I2Zs6wg57md2QSzw5LlPOCrpeEBf8IYsR1EnpihNT4Z2xKL5DS16u1Lj3ORvg= 13 | on: 14 | tags: true 15 | repo: matthewmueller/next-cookies 16 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Next Cookies 2 | 3 | [![Build Status](https://travis-ci.org/matthewmueller/next-cookies.svg?branch=master)](https://travis-ci.org/matthewmueller/next-cookies) 4 | 5 | Tiny little function for getting cookies on both client & server with [next.js](https://nextjs.org). 6 | 7 | This enables easy client-side and server-side rendering of pages that depend on cookies. 8 | 9 | ## Installation 10 | 11 | ``` 12 | yarn add next-cookies 13 | ``` 14 | 15 | or 16 | 17 | ``` 18 | npm install --save next-cookies 19 | ``` 20 | 21 | 22 | ## Usage 23 | 24 | ### Read all cookies: 25 | 26 | ```js 27 | const allCookies = cookies(ctx); 28 | ``` 29 | 30 | `allCookies` will be an object with keys for each cookie. 31 | 32 | The `ctx` object is passed to your [`getInitialProps`](https://nextjs.org/docs#fetching-data-and-component-lifecycle) function by next.js. 33 | 34 | JSON is parsed automatically, to disable this behavior pass an options object with `doNotParse` set to `true`: 35 | 36 | ```js 37 | const allCookies = cookies(ctx, {doNotParse: true}); 38 | ``` 39 | 40 | The options object is passed directly to the underlying [universal-cookie](https://www.npmjs.com/package/universal-cookie) library. 41 | 42 | ### Read a single cookie: 43 | 44 | ```js 45 | const { myCookie } = cookies(ctx); 46 | ``` 47 | or 48 | ```js 49 | const myCookie = cookies(ctx).myCookie; 50 | ``` 51 | 52 | The `ctx` object is passed to your [`getInitialProps`](https://nextjs.org/docs#fetching-data-and-component-lifecycle) function by next.js. 53 | 54 | ### Set a cookie: 55 | 56 | This library does not support setting cookies. However, this is how to do it in client-side code: 57 | 58 | ```js 59 | document.cookie = `foo=bar; path=/`; 60 | ``` 61 | 62 | This sets a cookie named `foo` to the value `bar`. 63 | 64 | The `path` portion is optional but usually desired. 65 | 66 | An expiration date may be appended (see below), otherwise the cookie will be deleted whenever the browser is closed. 67 | 68 | ### Delete a cookie: 69 | 70 | This library does not support deleting cookies. However, this is how to do it in client-side code: 71 | 72 | ```js 73 | document.cookie = `foo=; path=/; expires=Thu, 01 Jan 1970 00:00:01 GMT`; 74 | ``` 75 | 76 | The value doesn't matter, although the `path` does. The expiration date must be in the past. 77 | 78 | ## Complete Example 79 | 80 | ```js 81 | import React from 'react' 82 | import cookies from 'next-cookies' 83 | 84 | class NameForm extends React.Component { 85 | static async getInitialProps(ctx) { 86 | return { 87 | initialName: cookies(ctx).name || '' 88 | } 89 | } 90 | 91 | constructor(props) { 92 | super(props); 93 | this.state = {name: props.initialName || ''}; 94 | this.handleChange = this.handleChange.bind(this); 95 | this.reset = this.reset.bind(this); 96 | } 97 | 98 | handleChange(event) { 99 | const newName = event.target.value; 100 | this.setState({name: newName}); 101 | document.cookie = `name=${newName}; path=/`; 102 | } 103 | 104 | reset() { 105 | this.setState({name: ''}); 106 | document.cookie = 'name=; path=/; expires=Thu, 01 Jan 1970 00:00:01 GMT'; 107 | } 108 | 109 | render() { 110 | return ( 111 |
112 |

Hi {this.state.name}

113 |

Change cookie: ! 119 |

120 |

Delete cookie:

121 |
122 | ); 123 | } 124 | } 125 | 126 | export default NameForm 127 | ``` 128 | 129 | See, also, the test app: https://github.com/matthewmueller/next-cookies/blob/master/tests/test-app/pages/cookies.js 130 | 131 | ## More Information 132 | 133 | * https://www.npmjs.com/package/universal-cookie 134 | * https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies 135 | * https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie 136 | * https://tools.ietf.org/html/rfc6265 137 | 138 | 139 | ## License 140 | 141 | MIT 142 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | import { CookieGetOptions } from 'universal-cookie' 2 | 3 | declare const cookies: ( 4 | context: { req?: { headers: { cookie?: string } } }, 5 | options?: CookieGetOptions 6 | ) => Record 7 | export = cookies 8 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var Cookies = require("universal-cookie"); 2 | // we seem to sometimes get the ES6 version despite requesting cjs here, not sure why 3 | // this isn't the ideal fix, but it'll do for now 4 | Cookies = Cookies.default || Cookies; 5 | 6 | function nextCookies(ctx, options) { 7 | // Note: Next.js Static export sets ctx.req to a fake request with no headers 8 | var header = ctx.req && ctx.req.headers && ctx.req.headers.cookie; 9 | var uc = new Cookies(header); 10 | return uc.getAll(options); 11 | } 12 | 13 | module.exports = nextCookies; 14 | -------------------------------------------------------------------------------- /nightwatch.json: -------------------------------------------------------------------------------- 1 | { 2 | "src_folders" : ["tests/integration"], 3 | 4 | "webdriver" : { 5 | "start_process": true, 6 | "server_path": "node_modules/.bin/chromedriver", 7 | "port": 9515 8 | }, 9 | 10 | "test_settings" : { 11 | "default" : { 12 | "desiredCapabilities": { 13 | "browserName": "chrome", 14 | "chromeOptions": { 15 | "args": [ "--headless" ] 16 | } 17 | } 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-cookies", 3 | "version": "2.0.3", 4 | "description": "get the cookies on both the client & server", 5 | "main": "index.js", 6 | "types": "index.d.ts", 7 | "repository": "matthewmueller/next-cookies", 8 | "scripts": { 9 | "test-server": "cd tests/test-app && npm run test-server", 10 | "lint": "eslint .", 11 | "autofix": "eslint . --fix", 12 | "test-integration": "node tests/run_integration_tests.js", 13 | "test": "npm run lint && npm run test-integration" 14 | }, 15 | "husky": { 16 | "hooks": { 17 | "pre-commit": "pretty-quick --staged" 18 | } 19 | }, 20 | "files": [ 21 | "index.js", 22 | "index.d.ts" 23 | ], 24 | "keywords": [ 25 | "cookies", 26 | "next.js", 27 | "cookie", 28 | "parser", 29 | "json" 30 | ], 31 | "author": "Matthew Mueller", 32 | "license": "MIT", 33 | "dependencies": { 34 | "universal-cookie": "^4.0.3" 35 | }, 36 | "devDependencies": { 37 | "chromedriver": "^*", 38 | "eslint": "^6.8.0", 39 | "eslint-config-prettier": "^6.10.0", 40 | "eslint-plugin-prettier": "^3.1.2", 41 | "nightwatch": "^1.3.4", 42 | "prettier": "1.18.2", 43 | "react": "16.11.0", 44 | "react-dom": "16.11.0" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /tests/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["eslint:recommended", "plugin:prettier/recommended"], 3 | env: { 4 | node: true, 5 | browser: true, 6 | es6: true 7 | }, 8 | parserOptions: { 9 | sourceType: "module", 10 | ecmaFeatures: { 11 | jsx: true 12 | } 13 | }, 14 | rules: { 15 | "prettier/prettier": "warn" 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /tests/integration/next-cookies.test.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // beforeEach : function(browser) { 3 | // browser 4 | // .url('http://localhost:3000/') 5 | // .deleteCookies() 6 | // .end(); 7 | // }, 8 | 9 | "No cookies, server-side": function(browser) { 10 | browser 11 | .url("http://localhost:3000/cookies") 12 | .waitForElementVisible("h1") 13 | .assert.containsText("h1", "Cookies") 14 | .assert.elementNotPresent("li") 15 | .end(); 16 | }, 17 | 18 | "No cookies, client-side": function(browser) { 19 | browser 20 | .url("http://localhost:3000/") 21 | .waitForElementVisible("a") 22 | .click("a") 23 | .waitForElementVisible("h1") 24 | .assert.containsText("h1", "Cookies") 25 | .assert.elementNotPresent("li") 26 | .end(); 27 | }, 28 | 29 | "With a cookie, server-side": function(browser) { 30 | browser 31 | .url("http://localhost:3000/") 32 | .setCookie({ name: "test_cookie", value: "test value" }) 33 | .url("http://localhost:3000/cookies") 34 | .waitForElementVisible("h1") 35 | .assert.containsText("h1", "Cookies") 36 | .assert.elementPresent("li") 37 | .assert.containsText("li", "test_cookie") 38 | .assert.containsText("li", "test value") 39 | .end(); 40 | }, 41 | 42 | "With a cookie, client-side": function(browser) { 43 | browser 44 | .url("http://localhost:3000/") 45 | .setCookie({ name: "test_cookie", value: "test value" }) 46 | .waitForElementVisible("a") 47 | .click("a") 48 | .waitForElementVisible("h1") 49 | .assert.containsText("h1", "Cookies") 50 | .assert.elementPresent("li") 51 | .assert.containsText("li", "test_cookie") 52 | .assert.containsText("li", "test value") 53 | .end(); 54 | }, 55 | 56 | "Parses a JSON cookie by default": function(browser) { 57 | browser 58 | .url("http://localhost:3000/") 59 | .setCookie({ name: "test_cookie", value: "%7B%22foo%22%3A%22asdf%22%7D" }) 60 | .url("http://localhost:3000/parsed-unparsed") 61 | .waitForElementVisible("#unparsed") 62 | .assert.containsText("#parsed", 'parsed: (object) { "foo": "asdf" }') 63 | .assert.containsText("#unparsed", 'unparsed: (string) {"foo":"asdf"}') 64 | .end(); 65 | } 66 | }; 67 | -------------------------------------------------------------------------------- /tests/run_integration_tests.js: -------------------------------------------------------------------------------- 1 | const child_process = require("child_process"); 2 | const path = require("path"); 3 | 4 | const TEST_APP_DIR = path.join(__dirname, "test-app"); 5 | 6 | // This is kind of dumb, but we need to run two separate processes for the tests: a next.js server and the nightwatch tester 7 | // We also have to remember to shut down the server after the tests finish - that's the part that requires orchestration. 8 | 9 | // first install the deps in the test app 10 | child_process.spawnSync("npm", ["ci"], { 11 | stdio: "inherit", 12 | cwd: TEST_APP_DIR 13 | }); 14 | 15 | // next link the module so that this copy is used in the test app 16 | child_process.spawnSync("npm", ["link"], { stdio: "inherit" }); 17 | child_process.spawnSync("npm", ["link", "next-cookies"], { 18 | stdio: "inherit", 19 | cwd: TEST_APP_DIR 20 | }); 21 | 22 | const server = child_process.spawn("npm", ["run", "test-server"], { 23 | stdio: "inherit", 24 | cwd: TEST_APP_DIR 25 | }); 26 | let tests = null; 27 | 28 | server.on("exit", (code /*, signal */) => { 29 | if (tests) { 30 | tests.kill(); 31 | } 32 | if (code) { 33 | console.error("test server exited with code", code); 34 | process.exit(code); 35 | } 36 | }); 37 | 38 | // todo: check the server output to know when to start the tests instead of this arbitrary wait. 39 | setTimeout(() => { 40 | console.log("starting tests"); 41 | tests = child_process.spawn("npx", ["nightwatch"], { stdio: "inherit" }); 42 | tests.on("exit", (code /*, signal */) => { 43 | server.kill(); 44 | if (code) { 45 | console.error("tests exited with code", code); 46 | process.exit(code); 47 | } 48 | }); 49 | }, 5000); 50 | -------------------------------------------------------------------------------- /tests/test-app/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-app", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@next/env": { 8 | "version": "14.2.10", 9 | "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.10.tgz", 10 | "integrity": "sha512-dZIu93Bf5LUtluBXIv4woQw2cZVZ2DJTjax5/5DOs3lzEOeKLy7GxRSr4caK9/SCPdaW6bCgpye6+n4Dh9oJPw==" 11 | }, 12 | "@next/swc-darwin-arm64": { 13 | "version": "14.2.10", 14 | "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.10.tgz", 15 | "integrity": "sha512-V3z10NV+cvMAfxQUMhKgfQnPbjw+Ew3cnr64b0lr8MDiBJs3eLnM6RpGC46nhfMZsiXgQngCJKWGTC/yDcgrDQ==", 16 | "optional": true 17 | }, 18 | "@next/swc-darwin-x64": { 19 | "version": "14.2.10", 20 | "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.10.tgz", 21 | "integrity": "sha512-Y0TC+FXbFUQ2MQgimJ/7Ina2mXIKhE7F+GUe1SgnzRmwFY3hX2z8nyVCxE82I2RicspdkZnSWMn4oTjIKz4uzA==", 22 | "optional": true 23 | }, 24 | "@next/swc-linux-arm64-gnu": { 25 | "version": "14.2.10", 26 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.10.tgz", 27 | "integrity": "sha512-ZfQ7yOy5zyskSj9rFpa0Yd7gkrBnJTkYVSya95hX3zeBG9E55Z6OTNPn1j2BTFWvOVVj65C3T+qsjOyVI9DQpA==", 28 | "optional": true 29 | }, 30 | "@next/swc-linux-arm64-musl": { 31 | "version": "14.2.10", 32 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.10.tgz", 33 | "integrity": "sha512-n2i5o3y2jpBfXFRxDREr342BGIQCJbdAUi/K4q6Env3aSx8erM9VuKXHw5KNROK9ejFSPf0LhoSkU/ZiNdacpQ==", 34 | "optional": true 35 | }, 36 | "@next/swc-linux-x64-gnu": { 37 | "version": "14.2.10", 38 | "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.10.tgz", 39 | "integrity": "sha512-GXvajAWh2woTT0GKEDlkVhFNxhJS/XdDmrVHrPOA83pLzlGPQnixqxD8u3bBB9oATBKB//5e4vpACnx5Vaxdqg==", 40 | "optional": true 41 | }, 42 | "@next/swc-linux-x64-musl": { 43 | "version": "14.2.10", 44 | "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.10.tgz", 45 | "integrity": "sha512-opFFN5B0SnO+HTz4Wq4HaylXGFV+iHrVxd3YvREUX9K+xfc4ePbRrxqOuPOFjtSuiVouwe6uLeDtabjEIbkmDA==", 46 | "optional": true 47 | }, 48 | "@next/swc-win32-arm64-msvc": { 49 | "version": "14.2.10", 50 | "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.10.tgz", 51 | "integrity": "sha512-9NUzZuR8WiXTvv+EiU/MXdcQ1XUvFixbLIMNQiVHuzs7ZIFrJDLJDaOF1KaqttoTujpcxljM/RNAOmw1GhPPQQ==", 52 | "optional": true 53 | }, 54 | "@next/swc-win32-ia32-msvc": { 55 | "version": "14.2.10", 56 | "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.10.tgz", 57 | "integrity": "sha512-fr3aEbSd1GeW3YUMBkWAu4hcdjZ6g4NBl1uku4gAn661tcxd1bHs1THWYzdsbTRLcCKLjrDZlNp6j2HTfrw+Bg==", 58 | "optional": true 59 | }, 60 | "@next/swc-win32-x64-msvc": { 61 | "version": "14.2.10", 62 | "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.10.tgz", 63 | "integrity": "sha512-UjeVoRGKNL2zfbcQ6fscmgjBAS/inHBh63mjIlfPg/NG8Yn2ztqylXt5qilYb6hoHIwaU2ogHknHWWmahJjgZQ==", 64 | "optional": true 65 | }, 66 | "@swc/counter": { 67 | "version": "0.1.3", 68 | "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", 69 | "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==" 70 | }, 71 | "@swc/helpers": { 72 | "version": "0.5.5", 73 | "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", 74 | "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", 75 | "requires": { 76 | "@swc/counter": "^0.1.3", 77 | "tslib": "^2.4.0" 78 | } 79 | }, 80 | "@types/cookie": { 81 | "version": "0.3.3", 82 | "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.3.3.tgz", 83 | "integrity": "sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow==" 84 | }, 85 | "@types/object-assign": { 86 | "version": "4.0.30", 87 | "resolved": "https://registry.npmjs.org/@types/object-assign/-/object-assign-4.0.30.tgz", 88 | "integrity": "sha1-iUk3HVqZ9Dge4PHfCpt6GH4H5lI=" 89 | }, 90 | "busboy": { 91 | "version": "1.6.0", 92 | "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", 93 | "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", 94 | "requires": { 95 | "streamsearch": "^1.1.0" 96 | } 97 | }, 98 | "caniuse-lite": { 99 | "version": "1.0.30001660", 100 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001660.tgz", 101 | "integrity": "sha512-GacvNTTuATm26qC74pt+ad1fW15mlQ/zuTzzY1ZoIzECTP8HURDfF43kNxPgf7H1jmelCBQTTbBNxdSXOA7Bqg==" 102 | }, 103 | "client-only": { 104 | "version": "0.0.1", 105 | "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", 106 | "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" 107 | }, 108 | "cookie": { 109 | "version": "0.4.0", 110 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 111 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" 112 | }, 113 | "graceful-fs": { 114 | "version": "4.2.11", 115 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", 116 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" 117 | }, 118 | "nanoid": { 119 | "version": "3.3.8", 120 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", 121 | "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==" 122 | }, 123 | "next": { 124 | "version": "14.2.10", 125 | "resolved": "https://registry.npmjs.org/next/-/next-14.2.10.tgz", 126 | "integrity": "sha512-sDDExXnh33cY3RkS9JuFEKaS4HmlWmDKP1VJioucCG6z5KuA008DPsDZOzi8UfqEk3Ii+2NCQSJrfbEWtZZfww==", 127 | "requires": { 128 | "@next/env": "14.2.10", 129 | "@next/swc-darwin-arm64": "14.2.10", 130 | "@next/swc-darwin-x64": "14.2.10", 131 | "@next/swc-linux-arm64-gnu": "14.2.10", 132 | "@next/swc-linux-arm64-musl": "14.2.10", 133 | "@next/swc-linux-x64-gnu": "14.2.10", 134 | "@next/swc-linux-x64-musl": "14.2.10", 135 | "@next/swc-win32-arm64-msvc": "14.2.10", 136 | "@next/swc-win32-ia32-msvc": "14.2.10", 137 | "@next/swc-win32-x64-msvc": "14.2.10", 138 | "@swc/helpers": "0.5.5", 139 | "busboy": "1.6.0", 140 | "caniuse-lite": "^1.0.30001579", 141 | "graceful-fs": "^4.2.11", 142 | "postcss": "8.4.31", 143 | "styled-jsx": "5.1.1" 144 | } 145 | }, 146 | "next-cookies": { 147 | "version": "2.0.0", 148 | "resolved": "https://registry.npmjs.org/next-cookies/-/next-cookies-2.0.0.tgz", 149 | "integrity": "sha512-8VLxOYcsfb0YdSDitzflye6WLlpVzqUgLWuKLwczwhyywwx4QNF9CA73PTamD9kDwr0gUNRmvMEe8jEtSfdWpQ==", 150 | "requires": { 151 | "universal-cookie": "^4.0.2" 152 | } 153 | }, 154 | "object-assign": { 155 | "version": "4.1.1", 156 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 157 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 158 | }, 159 | "picocolors": { 160 | "version": "1.1.0", 161 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", 162 | "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==" 163 | }, 164 | "postcss": { 165 | "version": "8.4.31", 166 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", 167 | "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", 168 | "requires": { 169 | "nanoid": "^3.3.6", 170 | "picocolors": "^1.0.0", 171 | "source-map-js": "^1.0.2" 172 | } 173 | }, 174 | "source-map-js": { 175 | "version": "1.2.1", 176 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", 177 | "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==" 178 | }, 179 | "streamsearch": { 180 | "version": "1.1.0", 181 | "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", 182 | "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==" 183 | }, 184 | "styled-jsx": { 185 | "version": "5.1.1", 186 | "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", 187 | "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", 188 | "requires": { 189 | "client-only": "0.0.1" 190 | } 191 | }, 192 | "tslib": { 193 | "version": "2.7.0", 194 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", 195 | "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" 196 | }, 197 | "universal-cookie": { 198 | "version": "4.0.2", 199 | "resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-4.0.2.tgz", 200 | "integrity": "sha512-n14lhA//lQeYRweP9j9uXsshN9Cs4LunVSnvAGmnA69SofwsjpUU03geaCaPC9LlsH2rkBy99o3zxQyVOldGvA==", 201 | "requires": { 202 | "@types/cookie": "^0.3.3", 203 | "@types/object-assign": "^4.0.30", 204 | "cookie": "^0.4.0", 205 | "object-assign": "^4.1.1" 206 | } 207 | } 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /tests/test-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-app", 3 | "version": "1.0.0", 4 | "description": "", 5 | "private": true, 6 | "main": "index.js", 7 | "scripts": { 8 | "test-server": "next dev", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "MIT", 14 | "dependencies": { 15 | "next": "^14.2.10", 16 | "next-cookies": "*" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/test-app/pages/api/delete-cookie.js: -------------------------------------------------------------------------------- 1 | export default (req, res) => { 2 | res.setHeader("Set-Cookie", "test_cookie=; path=/; Expires=0"); 3 | res.end("test_cookie deleted"); 4 | }; 5 | -------------------------------------------------------------------------------- /tests/test-app/pages/api/set-cookie-json.js: -------------------------------------------------------------------------------- 1 | export default (req, res) => { 2 | res.setHeader( 3 | "Set-Cookie", 4 | "test_cookie=%7B%22foo%22%3A%22asdf%22%7D; path=/;" 5 | ); 6 | res.end("test_cookie set"); 7 | }; 8 | -------------------------------------------------------------------------------- /tests/test-app/pages/api/set-cookie.js: -------------------------------------------------------------------------------- 1 | export default (req, res) => { 2 | res.setHeader("Set-Cookie", "test_cookie=test value; path=/;"); 3 | res.end("test_cookie set"); 4 | }; 5 | -------------------------------------------------------------------------------- /tests/test-app/pages/cookies.js: -------------------------------------------------------------------------------- 1 | import cookies from "next-cookies"; 2 | 3 | const Cookies = ({ cookies }) => ( 4 |
5 |

Cookies:

6 | 13 |
14 | ); 15 | 16 | Cookies.getInitialProps = ctx => ({ 17 | cookies: cookies(ctx) 18 | }); 19 | 20 | export default Cookies; 21 | -------------------------------------------------------------------------------- /tests/test-app/pages/index.js: -------------------------------------------------------------------------------- 1 | // not sure what eslint is smoking here 2 | // eslint-disable-next-line no-unused-vars 3 | import Link from "next/link"; 4 | 5 | const Home = () => ( 6 |
7 |

Pages:

8 | 20 |

API:

21 | 38 |
39 | ); 40 | 41 | export default Home; 42 | -------------------------------------------------------------------------------- /tests/test-app/pages/parsed-unparsed.js: -------------------------------------------------------------------------------- 1 | import cookies from "next-cookies"; 2 | 3 | const Cookies = ({ parsed, unparsed }) => ( 4 |
5 |

test_cookie, parsed and unparsed:

6 | 14 |
15 | ); 16 | 17 | Cookies.getInitialProps = ctx => ({ 18 | parsed: cookies(ctx)["test_cookie"], 19 | unparsed: cookies(ctx, { doNotParse: true })["test_cookie"] 20 | }); 21 | 22 | export default Cookies; 23 | --------------------------------------------------------------------------------