repl: runtime deprecate instantiating without new

PR-URL: https://github.com/nodejs/node/pull/54869
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: LiviaMedeiros <livia@cirno.name>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Jacob Smith <jacob@frende.me>
This commit is contained in:
Aviv Keller 2024-11-07 03:03:05 -05:00 committed by GitHub
parent f38cefa04b
commit 0368f2f662
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 32 additions and 9 deletions

View File

@ -3748,6 +3748,9 @@ It is recommended to use the `new` qualifier instead. This applies to all Zlib c
<!-- YAML
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/54869
description: Runtime deprecation.
- version:
- v22.9.0
- v20.18.0
@ -3755,7 +3758,7 @@ changes:
description: Documentation-only deprecation.
-->
Type: Documentation-only
Type: Runtime
Instantiating classes without the `new` qualifier exported by the `node:repl` module is deprecated.
It is recommended to use the `new` qualifier instead. This applies to all REPL classes, including

View File

@ -63,6 +63,7 @@ const {
} = internalBinding('util');
const { isNativeError, isPromise } = internalBinding('types');
const { getOptionValue } = require('internal/options');
const assert = require('internal/assert');
const { encodings } = internalBinding('string_decoder');
const noCrypto = !process.versions.openssl;
@ -179,6 +180,14 @@ function deprecate(fn, msg, code, useEmitSync) {
return deprecated;
}
function deprecateInstantiation(target, code, ...args) {
assert(typeof code === 'string');
getDeprecationWarningEmitter(code, `Instantiating ${target.name} without the 'new' keyword has been deprecated.`, target)();
return ReflectConstruct(target, args);
}
function decorateErrorStack(err) {
if (!(isError(err) && err.stack) || err[decorated_private_symbol])
return;
@ -879,6 +888,7 @@ module.exports = {
defineLazyProperties,
defineReplaceableLazyAttribute,
deprecate,
deprecateInstantiation,
emitExperimentalWarning,
encodingsMap,
exposeInterface,

View File

@ -111,6 +111,7 @@ const {
decorateErrorStack,
isError,
deprecate,
deprecateInstantiation,
SideEffectFreeRegExpPrototypeSymbolReplace,
SideEffectFreeRegExpPrototypeSymbolSplit,
} = require('internal/util');
@ -262,12 +263,7 @@ function REPLServer(prompt,
ignoreUndefined,
replMode) {
if (!(this instanceof REPLServer)) {
return new REPLServer(prompt,
stream,
eval_,
useGlobal,
ignoreUndefined,
replMode);
return deprecateInstantiation(REPLServer, 'DEP0185', prompt, stream, eval_, useGlobal, ignoreUndefined, replMode);
}
let options;

View File

@ -65,7 +65,7 @@ function runAndWait(cmds, repl) {
return promise;
}
const repl = REPLServer({
const repl = new REPLServer({
prompt: PROMPT,
stream: new REPLStream(),
ignoreUndefined: true,

View File

@ -57,7 +57,7 @@ function runAndWait(cmds, repl) {
}
async function tests(options) {
const repl = REPLServer({
const repl = new REPLServer({
prompt: PROMPT,
stream: new REPLStream(),
ignoreUndefined: true,

View File

@ -1035,3 +1035,17 @@ function event(ee, expected) {
}));
});
}
{
const server = repl.REPLServer();
common.expectWarning({
DeprecationWarning: {
DEP0185: 'Instantiating REPLServer without the \'new\' keyword has been deprecated.',
// For the 'url.format' test-case.
DEP0169:
'`url.parse()` behavior is not standardized and prone to errors that have security implications. ' +
'Use the WHATWG URL API instead. CVEs are not issued for `url.parse()` vulnerabilities.',
}
});
server.emit('line', '.exit');
}