Skip to content

Commit

Permalink
Fix broken windows (#415)
Browse files Browse the repository at this point in the history
Includes:

 - Update to ESLint 9
 - Switch to vite for packaging and testing
 - Switch to named export (update readme)
 - Remove Node 16 support

#411
  • Loading branch information
wavded authored Nov 27, 2024
1 parent 2f1ce8f commit 1ae375e
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 112 deletions.
26 changes: 0 additions & 26 deletions .eslintrc

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node: [16, 18, 20]
node: [18, 20, 22]
name: Node v${{ matrix.node }}
steps:
- uses: actions/checkout@v3
Expand Down
22 changes: 22 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import js from "@eslint/js"
import prettier from "eslint-plugin-prettier/recommended"
import ts from "typescript-eslint"

export default ts.config({
extends: [js.configs.recommended, ...ts.configs.recommended, prettier],
rules: {
"prefer-const": 0,
"@typescript-eslint/no-explicit-any": 0,
"@typescript-eslint/no-unused-vars": [
"error",
{
argsIgnorePattern: "^_",
caughtErrorsIgnorePattern: "^_",
destructuredArrayIgnorePattern: "^_",
varsIgnorePattern: "^_",
ignoreRestSiblings: true,
},
],
},
ignores: ["dist/**"],
})
4 changes: 1 addition & 3 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ interface RedisStoreOptions {
disableTouch?: boolean
}

class RedisStore extends Store {
export class RedisStore extends Store {
client: NormalizedRedisClient
prefix: string
scanCount: number
Expand Down Expand Up @@ -204,5 +204,3 @@ class RedisStore extends Store {
return keys
}
}

export default RedisStore
70 changes: 31 additions & 39 deletions index_test.ts
Original file line number Diff line number Diff line change
@@ -1,125 +1,117 @@
import test from "blue-tape"
import {Cookie} from "express-session"
import {Redis} from "ioredis"
import {promisify} from "node:util"
import {createClient} from "redis"
import RedisStore from "./"
import {expect, test} from "vitest"
import {RedisStore} from "./"
import * as redisSrv from "./testdata/server"

test("setup", async () => {
await redisSrv.connect()
})

test("defaults", async (t) => {
test("defaults", async () => {
let client = createClient({url: `redis://localhost:${redisSrv.port}`})
await client.connect()

let store = new RedisStore({client})

t.ok(store.client, "stores client")
t.equal(store.prefix, "sess:", "defaults to sess:")
t.equal(store.ttl, 86400, "defaults to one day")
t.equal(store.scanCount, 100, "defaults SCAN count to 100")
t.equal(store.serializer, JSON, "defaults to JSON serialization")
t.equal(store.disableTouch, false, "defaults to having `touch` enabled")
t.equal(store.disableTTL, false, "defaults to having `ttl` enabled")
expect(store.client).toBeDefined()
expect(store.prefix).toBe("sess:")
expect(store.ttl).toBe(86400) // defaults to one day
expect(store.scanCount).toBe(100)
expect(store.serializer).toBe(JSON)
expect(store.disableTouch).toBe(false)
expect(store.disableTTL).toBe(false)
await client.disconnect()
})

test("redis", async (t) => {
test("redis", async () => {
let client = createClient({url: `redis://localhost:${redisSrv.port}`})
await client.connect()
let store = new RedisStore({client})
await lifecycleTest(store, client, t)
await lifecycleTest(store, client)
await client.disconnect()
})

test("ioredis", async (t) => {
test("ioredis", async () => {
let client = new Redis(`redis://localhost:${redisSrv.port}`)
let store = new RedisStore({client})
await lifecycleTest(store, client, t)
await lifecycleTest(store, client)
client.disconnect()
})

test("teardown", redisSrv.disconnect)

async function lifecycleTest(
store: RedisStore,
client: any,
t: test.Test,
): Promise<void> {
async function lifecycleTest(store: RedisStore, client: any): Promise<void> {
const P = (f: any) => promisify(f).bind(store)
let res = await P(store.clear)()

let sess = {foo: "bar"}
await P(store.set)("123", sess)

res = await P(store.get)("123")
t.same(res, sess, "store.get")
expect(res).toEqual(sess)

let ttl = await client.ttl("sess:123")
t.ok(ttl >= 86399, "check one day ttl")
expect(ttl).toBeGreaterThanOrEqual(86399)

ttl = 60
let expires = new Date(Date.now() + ttl * 1000).toISOString()
await P(store.set)("456", {cookie: {expires}})
ttl = await client.ttl("sess:456")
t.ok(ttl <= 60, "check expires ttl")
expect(ttl).toBeLessThanOrEqual(60)

ttl = 90
let expires2 = new Date(Date.now() + ttl * 1000).toISOString()
await P(store.touch)("456", {cookie: {expires: expires2}})
ttl = await client.ttl("sess:456")
t.ok(ttl > 60, "check expires ttl touch")
expect(ttl).toBeGreaterThan(60)

res = await P(store.length)()
t.equal(res, 2, "stored two keys length")
expect(res).toBe(2) // stored two keys length

res = await P(store.ids)()
res.sort()
t.same(res, ["123", "456"], "stored two keys ids")
expect(res).toEqual(["123", "456"])

res = await P(store.all)()
res.sort((a: any, b: any) => (a.id > b.id ? 1 : -1))
t.same(
res,
[
{id: "123", foo: "bar"},
{id: "456", cookie: {expires}},
],
"stored two keys data",
)
expect(res).toEqual([
{id: "123", foo: "bar"},
{id: "456", cookie: {expires}},
])

await P(store.destroy)("456")
res = await P(store.length)()
t.equal(res, 1, "one key remains")
expect(res).toBe(1) // one key remains

res = await P(store.clear)()

res = await P(store.length)()
t.equal(res, 0, "no keys remain")
expect(res).toBe(0) // no keys remain

let count = 1000
await load(store, count)

res = await P(store.length)()
t.equal(res, count, "bulk count")
expect(res).toBe(count)

await P(store.clear)()
res = await P(store.length)()
t.equal(res, 0, "bulk clear")
expect(res).toBe(0)

expires = new Date(Date.now() + ttl * 1000).toISOString() // expires in the future
res = await P(store.set)("789", {cookie: {expires}})

res = await P(store.length)()
t.equal(res, 1, "one key exists (session 789)")
expect(res).toBe(1)

expires = new Date(Date.now() - ttl * 1000).toISOString() // expires in the past
await P(store.set)("789", {cookie: {expires}})

res = await P(store.length)()
t.equal(res, 0, "no key remains and that includes session 789")
expect(res).toBe(0) // no key remains and that includes session 789
}

async function load(store: RedisStore, count: number) {
Expand Down
54 changes: 29 additions & 25 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
{
"name": "connect-redis",
"description": "Redis session store for Connect",
"version": "7.1.1",
"version": "8.0.0",
"author": "TJ Holowaychuk <[email protected]>",
"contributors": [
"Marc Harter <[email protected]>"
],
"license": "MIT",
"main": "./dist/esm/index.js",
"type": "module",
"main": "./dist/connect-redis.cjs",
"module": "./dist/connect-redis.js",
"types": "./dist/connect-redis.d.ts",
"exports": {
".": {
"import": "./dist/esm/index.js",
"require": "./dist/cjs/index.js",
"default": "./dist/esm/index.js"
"import": "./dist/connect-redis.js",
"require": "./dist/connect-redis.cjs"
}
},
"types": "./dist/esm/index.d.ts",
"scripts": {
"prepublishOnly": "rm -rf dist && tsc & tsc --project tsconfig.esm.json && echo '{\"type\":\"module\"}' > dist/esm/package.json",
"build": "npm run prepublishOnly",
"test": "nyc ts-node node_modules/blue-tape/bin/blue-tape \"**/*_test.ts\"",
"lint": "tsc --noemit && eslint --max-warnings 0 --ext ts testdata *.ts",
"prepublishOnly": "vite build",
"build": "vite build",
"test": "vitest run --silent --coverage",
"lint": "tsc --noemit && eslint --max-warnings 0 testdata *.ts",
"fmt": "prettier --write .",
"fmt-check": "prettier --check ."
},
Expand All @@ -29,28 +30,31 @@
"url": "[email protected]:tj/connect-redis.git"
},
"devDependencies": {
"@types/blue-tape": "^0.1.36",
"@types/express-session": "^1.17.10",
"@types/node": "^20.11.5",
"@typescript-eslint/eslint-plugin": "^6.19.0",
"@typescript-eslint/parser": "^6.19.0",
"blue-tape": "^1.0.0",
"eslint": "^8.56.0",
"@eslint/js": "^9.15.0",
"@types/eslint__js": "^8.42.3",
"@types/express-session": "^1.18.1",
"@types/node": "^20.17.8",
"@vitest/coverage-v8": "^2.1.6",
"eslint": "^9.15.0",
"eslint-config-prettier": "^9.1.0",
"express-session": "^1.17.3",
"ioredis": "^5.3.2",
"nyc": "^15.1.0",
"prettier": "^3.2.4",
"prettier-plugin-organize-imports": "^3.2.4",
"redis": "^4.6.12",
"eslint-plugin-prettier": "^5.2.1",
"express-session": "^1.18.1",
"ioredis": "^5.4.1",
"prettier": "^3.4.1",
"prettier-plugin-organize-imports": "^4.1.0",
"redis": "^4.7.0",
"ts-node": "^10.9.2",
"typescript": "^5.3.3"
"typescript": "^5.7.2",
"typescript-eslint": "^8.16.0",
"vite": "^6.0.1",
"vite-plugin-dts": "^4.3.0",
"vitest": "^2.1.6"
},
"peerDependencies": {
"express-session": ">=1"
},
"engines": {
"node": ">=16"
"node": ">=18"
},
"bugs": {
"url": "https://github.com/tj/connect-redis/issues"
Expand Down
6 changes: 3 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,21 @@ npm install ioredis connect-redis express-session
Import using ESM/Typescript:

```js
import RedisStore from "connect-redis"
import {RedisStore} from "connect-redis"
```

Require using CommonJS:

```js
const RedisStore = require("connect-redis").default
const {RedisStore} = require("connect-redis")
```

## API

Full setup using [`redis`][1] package:

```js
import RedisStore from "connect-redis"
import {RedisStore} from "connect-redis"
import session from "express-session"
import {createClient} from "redis"

Expand Down
7 changes: 0 additions & 7 deletions tsconfig.esm.json

This file was deleted.

14 changes: 6 additions & 8 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
{
"compilerOptions": {
"target": "es2020",
"module": "commonjs",
"isolatedModules": true,
"target": "es2022",
"module": "esnext",
"strict": true,
"isolatedModules": true,
"skipLibCheck": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"declaration": true,
"outDir": "./dist/cjs",
"esModuleInterop": true,
"resolveJsonModule": true,
"resolveJsonModule": true
},
"exclude": ["node_modules", "dist"],
"exclude": ["node_modules", "dist"]
}
Loading

0 comments on commit 1ae375e

Please sign in to comment.