├── .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 | [](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 |
7 | {Object.keys(cookies).map(name => (
8 | -
9 | {name}: {cookies[name].toString()}
10 |
11 | ))}
12 |
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 |
7 | -
8 | parsed: ({typeof parsed}) {JSON.stringify(parsed, null, 2)}
9 |
10 | -
11 | unparsed: ({typeof unparsed}) {unparsed}
12 |
13 |
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 |
--------------------------------------------------------------------------------