connect-pg-simple
Advanced tools
Comparing version 7.0.0 to 8.0.0
122
index.js
@@ -11,3 +11,2 @@ // @ts-check | ||
/** @typedef {*} ExpressSessionStore */ | ||
/** @typedef {import('pg').Pool} Pool */ | ||
@@ -26,2 +25,3 @@ /** | ||
if (!cb) { | ||
// eslint-disable-next-line promise/prefer-await-to-then | ||
value.catch(() => {}); | ||
@@ -64,3 +64,3 @@ } else { | ||
* @property {typeof console.error} [errorLog] | ||
* @property {Pool} [pool] | ||
* @property {import('pg').Pool} [pool] | ||
* @property {*} [pgPromise] | ||
@@ -84,2 +84,25 @@ * @property {string} [conString] | ||
class PGStore extends Store { | ||
/** @type {boolean} */ | ||
#createTableIfMissing; | ||
/** @type {boolean} */ | ||
#disableTouch; | ||
/** @type {typeof console.error} */ | ||
#errorLog; | ||
/** @type {boolean} */ | ||
#ownsPg; | ||
/** @type {*} */ | ||
#pgPromise; | ||
/** @type {import('pg').Pool|undefined} */ | ||
#pool; | ||
/** @type {false|number} */ | ||
#pruneSessionInterval; | ||
/** @type {PGStorePruneDelayRandomizer|undefined} */ | ||
#pruneSessionRandomizedInterval; | ||
/** @type {string|undefined} */ | ||
#schemaName; | ||
/** @type {Promise<void>|undefined} */ | ||
#tableCreationPromise; | ||
/** @type {string} */ | ||
#tableName; | ||
/** @param {PGStoreOptions} options */ | ||
@@ -89,25 +112,23 @@ constructor (options = {}) { | ||
this.schemaName = options.schemaName ? escapePgIdentifier(options.schemaName) : undefined; | ||
/** @type {string} */ | ||
this.tableName = options.tableName ? escapePgIdentifier(options.tableName) : 'session'; | ||
this.#schemaName = options.schemaName ? escapePgIdentifier(options.schemaName) : undefined; | ||
this.#tableName = options.tableName ? escapePgIdentifier(options.tableName) : 'session'; | ||
if (!this.schemaName && this.tableName.includes('"."')) { | ||
if (!this.#schemaName && this.#tableName.includes('"."')) { | ||
// eslint-disable-next-line no-console | ||
console.warn('DEPRECATION WARNING: Schema should be provided through its dedicated "schemaName" option rather than through "tableName"'); | ||
this.tableName = this.tableName.replace(/^([^"]+)""\.""([^"]+)$/, '$1"."$2'); | ||
this.#tableName = this.#tableName.replace(/^([^"]+)""\.""([^"]+)$/, '$1"."$2'); | ||
} | ||
this.createTableIfMissing = !!options.createTableIfMissing; | ||
/** @type {Promise<void>|undefined} */ | ||
this.tableCreationPromise = undefined; | ||
this.#createTableIfMissing = !!options.createTableIfMissing; | ||
this.#tableCreationPromise = undefined; | ||
this.ttl = options.ttl; | ||
this.disableTouch = !!options.disableTouch; | ||
this.ttl = options.ttl; // TODO: Make this private as well, some bug in at least TS 4.6.4 stops that | ||
this.#disableTouch = !!options.disableTouch; | ||
// eslint-disable-next-line no-console | ||
this.errorLog = options.errorLog || console.error.bind(console); | ||
this.#errorLog = options.errorLog || console.error.bind(console); | ||
if (options.pool !== undefined) { | ||
this.pool = options.pool; | ||
this.ownsPg = false; | ||
this.#pool = options.pool; | ||
this.#ownsPg = false; | ||
} else if (options.pgPromise !== undefined) { | ||
@@ -117,4 +138,4 @@ if (typeof options.pgPromise.any !== 'function') { | ||
} | ||
this.pgPromise = options.pgPromise; | ||
this.ownsPg = false; | ||
this.#pgPromise = options.pgPromise; | ||
this.#ownsPg = false; | ||
} else { | ||
@@ -131,17 +152,15 @@ const conString = options.conString || process.env['DATABASE_URL']; | ||
} | ||
this.pool = new (require('pg')).Pool(conObject); | ||
this.pool.on('error', err => { | ||
this.errorLog('PG Pool error:', err.message); | ||
this.#pool = new (require('pg')).Pool(conObject); | ||
this.#pool.on('error', err => { | ||
this.#errorLog('PG Pool error:', err.message); | ||
}); | ||
this.ownsPg = true; | ||
this.#ownsPg = true; | ||
} | ||
if (options.pruneSessionInterval === false) { | ||
/** @type {false|number} */ | ||
this.pruneSessionInterval = false; | ||
this.#pruneSessionInterval = false; | ||
} else { | ||
/** @type {false|number} */ | ||
this.pruneSessionInterval = (options.pruneSessionInterval || DEFAULT_PRUNE_INTERVAL_IN_SECONDS) * 1000; | ||
this.#pruneSessionInterval = (options.pruneSessionInterval || DEFAULT_PRUNE_INTERVAL_IN_SECONDS) * 1000; | ||
if (options.pruneSessionRandomizedInterval !== false) { | ||
this.pruneSessionRandomizedInterval = ( | ||
this.#pruneSessionRandomizedInterval = ( | ||
options.pruneSessionRandomizedInterval || | ||
@@ -168,4 +187,4 @@ // Results in at least 50% of the specified interval and at most 150%. Makes it so that multiple instances doesn't all prune at the same time. | ||
if (res && res['to_regclass'] === null) { | ||
const pathModule = require('path'); | ||
const fs = require('fs').promises; | ||
const pathModule = require('node:path'); | ||
const fs = require('node:fs').promises; | ||
@@ -188,9 +207,9 @@ // eslint-disable-next-line security/detect-non-literal-fs-filename | ||
async _ensureSessionStoreTable (noTableCreation) { | ||
if (noTableCreation || this.createTableIfMissing === false) return; | ||
if (noTableCreation || this.#createTableIfMissing === false) return; | ||
if (!this.tableCreationPromise) { | ||
this.tableCreationPromise = this._rawEnsureSessionStoreTable(); | ||
if (!this.#tableCreationPromise) { | ||
this.#tableCreationPromise = this._rawEnsureSessionStoreTable(); | ||
} | ||
return this.tableCreationPromise; | ||
return this.#tableCreationPromise; | ||
} | ||
@@ -214,4 +233,4 @@ | ||
if (this.ownsPg && this.pool) { | ||
await this.pool.end(); | ||
if (this.#ownsPg && this.#pool) { | ||
await this.#pool.end(); | ||
} | ||
@@ -226,7 +245,7 @@ } | ||
*/ | ||
getPruneDelay () { | ||
const delay = this.pruneSessionInterval; | ||
#getPruneDelay () { | ||
const delay = this.#pruneSessionInterval; | ||
if (!delay) throw new Error('Can not calculate delay when pruning is inactivated'); | ||
if (this.pruneSessionRandomizedInterval) return this.pruneSessionRandomizedInterval(delay); | ||
if (this.#pruneSessionRandomizedInterval) return this.#pruneSessionRandomizedInterval(delay); | ||
@@ -240,2 +259,3 @@ return delay; | ||
* @param {SimpleErrorCallback} [fn] - standard Node.js callback called on completion | ||
* @returns {void} | ||
* @access public | ||
@@ -250,6 +270,6 @@ */ | ||
if (err) { | ||
this.errorLog('Failed to prune sessions:', err.message); | ||
this.#errorLog('Failed to prune sessions:', err.message); | ||
} | ||
if (this.pruneSessionInterval && !this.closed) { | ||
if (this.#pruneSessionInterval && !this.closed) { | ||
if (this.pruneTimer) { | ||
@@ -260,3 +280,3 @@ clearTimeout(this.pruneTimer); | ||
() => { this.pruneSessions(); }, | ||
this.getPruneDelay() | ||
this.#getPruneDelay() | ||
); | ||
@@ -275,6 +295,6 @@ this.pruneTimer.unref(); | ||
quotedTable () { | ||
let result = '"' + this.tableName + '"'; | ||
let result = '"' + this.#tableName + '"'; | ||
if (this.schemaName) { | ||
result = '"' + this.schemaName + '".' + result; | ||
if (this.#schemaName) { | ||
result = '"' + this.#schemaName + '".' + result; | ||
} | ||
@@ -292,3 +312,3 @@ | ||
*/ | ||
_getExpireTime (sess) { | ||
#getExpireTime (sess) { | ||
let expire; | ||
@@ -319,8 +339,8 @@ | ||
if (this.pgPromise) { | ||
const res = await this.pgPromise.any(query, params); | ||
if (this.#pgPromise) { | ||
const res = await this.#pgPromise.any(query, params); | ||
return res && res[0] ? res[0] : undefined; | ||
} else { | ||
if (!this.pool) throw new Error('Pool missing for some reason'); | ||
const res = await this.pool.query(query, params); | ||
if (!this.#pool) throw new Error('Pool missing for some reason'); | ||
const res = await this.#pool.query(query, params); | ||
return res && res.rows && res.rows[0] ? res.rows[0] : undefined; | ||
@@ -387,3 +407,3 @@ } | ||
set (sid, sess, fn) { | ||
const expireTime = this._getExpireTime(sess); | ||
const expireTime = this.#getExpireTime(sess); | ||
const query = 'INSERT INTO ' + this.quotedTable() + ' (sess, expire, sid) SELECT $1, to_timestamp($2), $3 ON CONFLICT (sid) DO UPDATE SET sess=$1, expire=to_timestamp($2) RETURNING sid'; | ||
@@ -422,3 +442,3 @@ | ||
touch (sid, sess, fn) { | ||
if (this.disableTouch) { | ||
if (this.#disableTouch) { | ||
// eslint-disable-next-line unicorn/no-null | ||
@@ -429,3 +449,3 @@ fn && fn(null); | ||
const expireTime = this._getExpireTime(sess); | ||
const expireTime = this.#getExpireTime(sess); | ||
@@ -432,0 +452,0 @@ this.query( |
{ | ||
"name": "connect-pg-simple", | ||
"version": "7.0.0", | ||
"version": "8.0.0", | ||
"description": "A simple, minimal PostgreSQL session store for Connect/Express", | ||
@@ -17,7 +17,7 @@ "url": "http://github.com/voxpelli/node-connect-pg-simple", | ||
"dependencies": { | ||
"@types/pg": "^8.6.1", | ||
"pg": "^8.7.1" | ||
"@types/pg": "^8.6.5", | ||
"pg": "^8.8.0" | ||
}, | ||
"engines": { | ||
"node": ">=12.0.0" | ||
"node": "^14.18.0 || >=16.0.0" | ||
}, | ||
@@ -31,58 +31,60 @@ "main": "index.js", | ||
"check:dependency-check": "dependency-check *.js 'test/**/*.js' --no-dev -i @types/pg", | ||
"check:installed-check": "installed-check -i eslint -i mocha -i @voxpelli/eslint-config -i @voxpelli/eslint-config-jsdoc-ts", | ||
"check:lint": "eslint .", | ||
"check:installed-check": "installed-check -i eslint-plugin-jsdoc", | ||
"check:lint": "eslint --report-unused-disable-directives .", | ||
"check:tsc": "tsc", | ||
"check:type-coverage": "type-coverage --detail --strict --at-least 85 --ignore-files 'test/**/*'", | ||
"check": "run-p check:*", | ||
"light:mocha": "nyc --reporter=lcov --reporter text mocha test/*.spec.js", | ||
"light:mocha": "c8 --reporter=lcov --reporter text mocha test/*.spec.js", | ||
"prepare": "husky install", | ||
"test-light": "run-s check light:*", | ||
"test:mocha": "nyc --reporter=lcov --reporter text mocha 'test/**/*.spec.js' --exit", | ||
"test:mocha": "c8 --reporter=lcov --reporter text mocha 'test/**/*.spec.js' --exit", | ||
"test-ci": "run-s test:*", | ||
"test": "run-s check test:*" | ||
}, | ||
"devDependencies": { | ||
"@types/chai": "^4.2.21", | ||
"@types/chai-as-promised": "^7.1.4", | ||
"@types/cookie-signature": "^1.0.3", | ||
"@types/express": "^4.17.13", | ||
"@types/express-session": "^1.17.4", | ||
"@types/mocha": "^9.0.0", | ||
"@types/node": "^12.20.23", | ||
"@types/chai": "^4.3.3", | ||
"@types/chai-as-promised": "^7.1.5", | ||
"@types/cookie-signature": "^1.0.4", | ||
"@types/express": "^4.17.14", | ||
"@types/express-session": "^1.17.5", | ||
"@types/mocha": "^10.0.0", | ||
"@types/node": "^14.18.33", | ||
"@types/proxyquire": "^1.3.28", | ||
"@types/sinon": "^10.0.2", | ||
"@types/sinon-chai": "^3.2.5", | ||
"@types/supertest": "^2.0.11", | ||
"@voxpelli/eslint-config": "^12.0.1", | ||
"@voxpelli/eslint-config-jsdoc-ts": "^0.3.1", | ||
"@voxpelli/tsconfig": "^3.0.0-0", | ||
"chai": "^4.3.4", | ||
"@types/sinon": "^10.0.13", | ||
"@types/sinon-chai": "^3.2.9", | ||
"@types/supertest": "^2.0.12", | ||
"@voxpelli/eslint-config": "^15.2.0", | ||
"@voxpelli/tsconfig": "^4.0.0", | ||
"c8": "^7.12.0", | ||
"chai": "^4.3.7", | ||
"chai-as-promised": "^7.1.1", | ||
"cookie-signature": "^1.1.0", | ||
"cookiejar": "^2.1.2", | ||
"dependency-check": "^4.1.0", | ||
"dotenv": "^10.0.0", | ||
"eslint": "^7.32.0", | ||
"eslint-config-standard": "^16.0.3", | ||
"cookie-signature": "^1.2.0", | ||
"cookiejar": "^2.1.3", | ||
"dependency-check": "^5.0.0-7", | ||
"dotenv": "^16.0.2", | ||
"eslint": "^8.27.0", | ||
"eslint-config-standard": "^17.0.0", | ||
"eslint-plugin-es": "^4.1.0", | ||
"eslint-plugin-import": "^2.24.2", | ||
"eslint-plugin-jsdoc": "^30.7.13", | ||
"eslint-plugin-mocha": "^9.0.0", | ||
"eslint-plugin-node": "^11.1.0", | ||
"eslint-plugin-promise": "^4.3.1", | ||
"eslint-plugin-security": "^1.4.0", | ||
"eslint-plugin-standard": "^4.1.0", | ||
"eslint-plugin-unicorn": "^35.0.0", | ||
"express": "^4.17.1", | ||
"express-session": "^1.17.2", | ||
"husky": "^7.0.0", | ||
"installed-check": "^4.0.0", | ||
"mocha": "^9.1.1", | ||
"npm-run-all": "^4.1.5", | ||
"nyc": "^15.1.0", | ||
"pg-promise": "^10.10.2", | ||
"eslint-plugin-import": "^2.26.0", | ||
"eslint-plugin-jsdoc": "^39.6.2", | ||
"eslint-plugin-mocha": "^10.1.0", | ||
"eslint-plugin-n": "^15.5.1", | ||
"eslint-plugin-promise": "^6.1.1", | ||
"eslint-plugin-security": "^1.5.0", | ||
"eslint-plugin-sort-destructure-keys": "^1.4.0", | ||
"eslint-plugin-unicorn": "^43.0.2", | ||
"express": "^4.18.2", | ||
"express-session": "^1.17.3", | ||
"husky": "^8.0.2", | ||
"installed-check": "^6.0.4", | ||
"mocha": "^10.1.0", | ||
"npm-run-all2": "^6.0.2", | ||
"pg-promise": "^10.12.1", | ||
"proxyquire": "^2.1.3", | ||
"sinon": "^11.1.2", | ||
"sinon": "^14.0.2", | ||
"sinon-chai": "^3.7.0", | ||
"supertest": "^6.1.6", | ||
"typescript": "^4.4.2" | ||
"supertest": "^6.3.1", | ||
"type-coverage": "^2.23.0", | ||
"typescript": "~4.6.4" | ||
} | ||
} |
@@ -5,12 +5,8 @@ # Connect PG Simple | ||
[![js-semistandard-style](https://img.shields.io/badge/code%20style-semistandard-brightgreen.svg?style=flat)](https://github.com/Flet/semistandard) | ||
[![Build Status](https://github.com/voxpelli/node-connect-pg-simple/workflows/Node%20CI/badge.svg)](https://github.com/voxpelli/node-connect-pg-simple/actions) | ||
[![dependencies Status](https://david-dm.org/voxpelli/node-connect-pg-simple/status.svg)](https://david-dm.org/voxpelli/node-connect-pg-simple) | ||
[![Known Vulnerabilities](https://snyk.io/test/github/voxpelli/node-connect-pg-simple/badge.svg?targetFile=package.json)](https://snyk.io/test/github/voxpelli/node-connect-pg-simple?targetFile=package.json) | ||
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fvoxpelli%2Fnode-connect-pg-simple.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fvoxpelli%2Fnode-connect-pg-simple?ref=badge_shield) | ||
[![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/voxpelli/node-connect-pg-simple.svg)](https://isitmaintained.com/project/voxpelli/node-connect-pg-simple "Average time to resolve an issue") | ||
[![Percentage of issues still open](https://isitmaintained.com/badge/open/voxpelli/node-connect-pg-simple.svg)](https://isitmaintained.com/project/voxpelli/node-connect-pg-simple "Percentage of issues still open") | ||
[![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/voxpelli/node-connect-pg-simple.svg?style=flat)](https://lgtm.com/projects/g/voxpelli/node-connect-pg-simple/context:javascript) | ||
[![npm version](https://img.shields.io/npm/v/connect-pg-simple.svg?style=flat)](https://www.npmjs.com/package/connect-pg-simple) | ||
[![npm downloads](https://img.shields.io/npm/dm/connect-pg-simple.svg?style=flat)](https://www.npmjs.com/package/connect-pg-simple) | ||
[![Module type: CJS](https://img.shields.io/badge/module%20type-cjs-brightgreen)](https://github.com/voxpelli/badges-cjs-esm) | ||
[![js-semistandard-style](https://img.shields.io/badge/code%20style-semistandard-brightgreen.svg)](https://github.com/voxpelli/eslint-config) | ||
[![Follow @voxpelli](https://img.shields.io/twitter/follow/voxpelli?style=social)](https://twitter.com/voxpelli) | ||
## Installation | ||
@@ -89,4 +85,4 @@ | ||
* **pgPromise** - Database object from `pg-promise` to be used for DB communications. | ||
* **conObject** - If you don't specify a pool object, use this option or `conString` to specify a PostgreSQL Pool connection [object](https://github.com/brianc/node-postgres#pooling-example) and this module will create a new pool for you. | ||
* **conString** - If you don't specify a pool object, use this option or `conObject` to specify a PostgreSQL connection [string](https://github.com/brianc/node-postgres/wiki/Client#new-clientstring-url-client) and this module will create a new pool for you. If the connection string is in the `DATABASE_URL` environment variable (as you do by default on eg. Heroku) – then this module fallback to that if this option is not specified. | ||
* **conObject** - If you don't specify a pool object, use this option or `conString` to specify a [PostgreSQL Pool connection object](https://node-postgres.com/api/client#constructor) and this module will create a new pool for you. | ||
* **conString** - If you don't specify a pool object, use this option or `conObject` to specify a PostgreSQL connection string like `postgres://user:password@host:5432/database` and this module will create a new pool for you. If there's a connection string in the `DATABASE_URL` environment variable (as it is by default on eg. Heroku) then this module will fallback to that if no other connection method has been specified. | ||
@@ -109,6 +105,2 @@ ### Other options | ||
## License | ||
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fvoxpelli%2Fnode-connect-pg-simple.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fvoxpelli%2Fnode-connect-pg-simple?ref=badge_large) | ||
## For enterprise | ||
@@ -115,0 +107,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
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
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
382
1
0
24860
108
Updated@types/pg@^8.6.5
Updatedpg@^8.8.0