Warn when functions intended as constructors are called without new (#2021)

* Warn when pg.Pool() isn’t called as a constructor

in preparation for #1541. `eval` is a bit awkward, but it’s more accurate than an `instanceof` check and will work on platforms new enough to support pg 8 (i.e. only not Node 4).

* Warn when Query() isn’t called as a constructor
This commit is contained in:
Charmander 2019-12-17 08:02:38 -08:00 committed by Brian C
parent c1f954b7a6
commit 2b59209cf3
4 changed files with 49 additions and 1 deletions

View File

@ -0,0 +1,22 @@
'use strict'
const warnDeprecation = require('./warn-deprecation')
// Node 4 doesnt support new.target.
let hasNewTarget
try {
// eslint-disable-next-line no-eval
eval('(function () { new.target })')
hasNewTarget = true
} catch (error) {
hasNewTarget = false
}
const checkConstructor = (name, code, getNewTarget) => {
if (hasNewTarget && getNewTarget() === undefined) {
warnDeprecation(`Constructing a ${name} without new is deprecated and will stop working in pg 8.`, code)
}
}
module.exports = checkConstructor

View File

@ -0,0 +1,19 @@
'use strict'
const util = require('util')
const dummyFunctions = new Map()
// Node 4 doesnt support process.emitWarning(message, 'DeprecationWarning', code).
const emitDeprecationWarning = (message, code) => {
let dummy = dummyFunctions.get(code)
if (dummy === undefined) {
dummy = util.deprecate(() => {}, message)
dummyFunctions.set(code, dummy)
}
dummy()
}
module.exports = emitDeprecationWarning

View File

@ -12,9 +12,13 @@ var Client = require('./client')
var defaults = require('./defaults')
var Connection = require('./connection')
var Pool = require('pg-pool')
const checkConstructor = require('./compat/check-constructor')
const poolFactory = (Client) => {
var BoundPool = function (options) {
// eslint-disable-next-line no-eval
checkConstructor('pg.Pool', 'PG-POOL-NEW', () => eval('new.target'))
var config = Object.assign({ Client: Client }, options)
return new Pool(config)
}

View File

@ -9,12 +9,15 @@
var EventEmitter = require('events').EventEmitter
var util = require('util')
const checkConstructor = require('./compat/check-constructor')
var Result = require('./result')
var utils = require('./utils')
var Query = function (config, values, callback) {
// use of "new" optional
// use of "new" optional in pg 7
// eslint-disable-next-line no-eval
checkConstructor('Query', 'PG-QUERY-NEW', () => eval('new.target'))
if (!(this instanceof Query)) { return new Query(config, values, callback) }
config = utils.normalizeQueryConfig(config, values, callback)