Skip to content

Commit 059c834

Browse files
authored
Add support for Redis V4 through legacyMode (#345)
The `legacyMode` option in `redis@v4` has matured enough such that all our tests pass now. Also includes: - Remove legacy v3 -> v4 upgrade docs - Switch to double quotes for formatting #336
1 parent 78997f9 commit 059c834

File tree

12 files changed

+168
-229
lines changed

12 files changed

+168
-229
lines changed

.github/release-drafter.yml

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
1-
name-template: 'v$RESOLVED_VERSION'
2-
tag-template: 'v$RESOLVED_VERSION'
1+
name-template: "v$RESOLVED_VERSION"
2+
tag-template: "v$RESOLVED_VERSION"
33
template: |
44
$CHANGES
5-
category-template: '#### $TITLE'
6-
change-template: '* #$NUMBER - $TITLE (@$AUTHOR)'
5+
category-template: "#### $TITLE"
6+
change-template: "* #$NUMBER - $TITLE (@$AUTHOR)"
77
categories:
8-
- title: 'Breaking changes'
9-
label: 'breaking'
10-
- title: 'Enhancements'
11-
label: 'enhancement'
12-
- title: 'Bug fixes'
13-
label: 'bug'
14-
- title: 'Maintenance'
15-
label: 'chore'
8+
- title: "Breaking changes"
9+
label: "breaking"
10+
- title: "Enhancements"
11+
label: "enhancement"
12+
- title: "Bug fixes"
13+
label: "bug"
14+
- title: "Maintenance"
15+
label: "chore"
1616

1717
version-resolver:
1818
major:
1919
labels:
20-
- 'breaking'
20+
- "breaking"
2121
minor:
2222
labels:
23-
- 'enhancement'
23+
- "enhancement"
2424
patch:
2525
labels:
26-
- 'bug'
27-
- 'chore'
26+
- "bug"
27+
- "chore"
2828

2929
exclude-labels:
30-
- 'skip-changelog'
30+
- "skip-changelog"

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
runs-on: ubuntu-latest
1010
strategy:
1111
matrix:
12-
node: ['12', '14', '16']
12+
node: ["12", "14", "16"]
1313
name: Node v${{ matrix.node }}
1414
steps:
1515
- uses: actions/checkout@v2

.github/workflows/stale.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@ name: stale-issues-prs
22
on:
33
workflow_dispatch:
44
schedule:
5-
- cron: '0 0 * * *'
5+
- cron: "0 0 * * *"
66
jobs:
77
stale:
88
runs-on: ubuntu-latest
99
steps:
1010
- uses: actions/stale@v3
1111
with:
12-
stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.'
13-
stale-pr-message: 'This PR is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.'
14-
close-issue-message: 'This issue was closed because it has been stalled for 5 days with no activity.'
12+
stale-issue-message: "This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days."
13+
stale-pr-message: "This PR is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days."
14+
close-issue-message: "This issue was closed because it has been stalled for 5 days with no activity."
1515
days-before-stale: 30
1616
days-before-close: 5
1717
stale-issue-label: stale

.prettierrc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
{
22
"tabWidth": 2,
3-
"semi": false,
4-
"singleQuote": true
3+
"semi": false
54
}

index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
module.exports = require('./lib/connect-redis')
1+
module.exports = require("./lib/connect-redis")

lib/connect-redis.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@ module.exports = function (session) {
1010
// All callbacks should have a noop if none provided for compatibility
1111
// with the most Redis clients.
1212
const noop = () => {}
13-
const TOMBSTONE = 'TOMBSTONE'
13+
const TOMBSTONE = "TOMBSTONE"
1414

1515
class RedisStore extends Store {
1616
constructor(options = {}) {
1717
super(options)
1818
if (!options.client) {
19-
throw new Error('A client must be directly provided to the RedisStore')
19+
throw new Error("A client must be directly provided to the RedisStore")
2020
}
2121

22-
this.prefix = options.prefix == null ? 'sess:' : options.prefix
22+
this.prefix = options.prefix == null ? "sess:" : options.prefix
2323
this.scanCount = Number(options.scanCount) || 100
2424
this.serializer = options.serializer || JSON
2525
this.client = options.client
@@ -64,12 +64,12 @@ module.exports = function (session) {
6464
return cb(er)
6565
}
6666
args.push(value)
67-
args.push('EX', this._getTTL(sess))
67+
args.push("EX", this._getTTL(sess))
6868

6969
let ttl = 1
7070
if (!this.disableTTL) {
7171
ttl = this._getTTL(sess)
72-
args.push('EX', ttl)
72+
args.push("EX", ttl)
7373
}
7474

7575
if (ttl > 0) {
@@ -88,14 +88,14 @@ module.exports = function (session) {
8888
let key = this.prefix + sid
8989
this.client.expire(key, this._getTTL(sess), (err, ret) => {
9090
if (err) return cb(err)
91-
if (ret !== 1) return cb(null, 'EXPIRED')
92-
cb(null, 'OK')
91+
if (ret !== 1) return cb(null, "EXPIRED")
92+
cb(null, "OK")
9393
})
9494
}
9595

9696
destroy(sid, cb = noop) {
9797
let key = this.prefix + sid
98-
this.client.set([key, TOMBSTONE, 'EX', 300], (err) => {
98+
this.client.set([key, TOMBSTONE, "EX", 300], (err) => {
9999
cb(err, 1)
100100
})
101101
}
@@ -163,12 +163,12 @@ module.exports = function (session) {
163163
}
164164

165165
_getAllKeys(cb = noop) {
166-
let pattern = this.prefix + '*'
166+
let pattern = this.prefix + "*"
167167
this._scanKeys({}, 0, pattern, this.scanCount, cb)
168168
}
169169

170170
_scanKeys(keys = {}, cursor, pattern, count, cb = noop) {
171-
let args = [cursor, 'match', pattern, 'count', count]
171+
let args = [cursor, "match", pattern, "count", count]
172172
this.client.scan(args, (err, data) => {
173173
if (err) return cb(err)
174174

@@ -196,7 +196,7 @@ module.exports = function (session) {
196196
* @returns {boolean}
197197
*/
198198
function isObject(item) {
199-
return item && typeof item === 'object' && !Array.isArray(item)
199+
return item && typeof item === "object" && !Array.isArray(item)
200200
}
201201

202202
/**

license

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2010-2020 TJ Holowaychuk
3+
Copyright (c) 2010-2022 TJ Holowaychuk
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

migration-to-v4.md

Lines changed: 0 additions & 78 deletions
This file was deleted.

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
"mockdate": "^2.0.5",
2222
"nyc": "^15.0.1",
2323
"prettier": "^2.0.5",
24-
"redis": "^3.1.2",
24+
"redis-v4": "npm:redis@4",
25+
"redis-v3": "npm:redis@3",
2526
"redis-mock": "^0.56.3"
2627
},
2728
"engines": {
@@ -33,7 +34,7 @@
3334
"scripts": {
3435
"test": "nyc tape \"test/*-test.js\"",
3536
"lint": "eslint index.js test lib",
36-
"fmt": "prettier --write \"**/*.{js,md,json,*rc}\"",
37-
"fmt-check": "prettier --check \"**/*.{js,md,json,*rc}\""
37+
"fmt": "prettier --write .",
38+
"fmt-check": "prettier --check ."
3839
}
3940
}

readme.md

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,44 @@
22

33
**connect-redis** provides Redis session storage for Express. Requires Redis >= `2.0.0`.
44

5-
**Migrating to V4?** See [this guide](migration-to-v4.md) on what's changed.
6-
75
## Installation
86

97
npm:
108

119
```sh
12-
npm install redis@v3 connect-redis express-session
10+
npm install redis connect-redis express-session
1311
```
1412

1513
Yarn:
1614

1715
```sh
18-
yarn add redis@v3 connect-redis express-session
16+
yarn add redis connect-redis express-session
1917
```
2018

2119
## API
2220

2321
```js
24-
const { createClient } = require('redis')
25-
const session = require('express-session')
22+
const session = require("express-session")
23+
let RedisStore = require("connect-redis")(session)
24+
25+
// redis@v4
26+
const { createClient } = require("redis")
27+
let redisClient = createClient({ legacyMode: true })
28+
redisClient.connect().catch(console.error)
2629

27-
let RedisStore = require('connect-redis')(session)
30+
// redis@v3
31+
const { createClient } = require("redis")
2832
let redisClient = createClient()
2933

34+
// ioredis
35+
const Redis = require("ioredis")
36+
let redisClient = new Redis()
37+
3038
app.use(
3139
session({
3240
store: new RedisStore({ client: redisClient }),
3341
saveUninitialized: false,
34-
secret: 'keyboard cat',
42+
secret: "keyboard cat",
3543
resave: false,
3644
})
3745
)
@@ -49,13 +57,10 @@ An instance of [`redis`][1] or a `redis` compatible client.
4957

5058
Known compatible and tested clients:
5159

52-
- [redis][1] (v3, **v4 currently is not supported**)
60+
- [redis][1] (v3, v4 with `legacyMode: true`)
5361
- [ioredis](https://github.com/luin/ioredis)
5462
- [redis-mock](https://github.com/yeahoffline/redis-mock) for testing.
5563

56-
> Note: In order to use [redis][1] v4 for other things and connect-redis for sessions, an acceptable solution for the time being would be to add both v3 and v4 as dependencies and pass the v3 client in to connect-redis.
57-
> [How to install multiple versions of same package?](https://stackoverflow.com/questions/26414587/how-to-install-multiple-versions-of-package-using-npm/56495651#56495651)
58-
5964
##### prefix
6065

6166
Key prefix in Redis (default: `sess:`).
@@ -108,7 +113,7 @@ Value used for _count_ parameter in [Redis `SCAN` command](https://redis.io/comm
108113
#### How to log Redis errors?
109114

110115
```js
111-
client.on('error', console.error)
116+
client.on("error", console.error)
112117
```
113118

114119
#### How do I handle lost connections to Redis?
@@ -119,7 +124,7 @@ By default, the [`redis`][1] client will [auto-reconnect](https://github.com/mra
119124
app.use(session(/* setup session here */))
120125
app.use(function (req, res, next) {
121126
if (!req.session) {
122-
return next(new Error('oh no')) // handle error
127+
return next(new Error("oh no")) // handle error
123128
}
124129
next() // otherwise continue
125130
})

0 commit comments

Comments
 (0)