Skip to content

Commit 0368f2f

Browse files
authored
repl: runtime deprecate instantiating without new
PR-URL: #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>
1 parent f38cefa commit 0368f2f

File tree

6 files changed

+32
-9
lines changed

6 files changed

+32
-9
lines changed

doc/api/deprecations.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3748,14 +3748,17 @@ It is recommended to use the `new` qualifier instead. This applies to all Zlib c
37483748

37493749
<!-- YAML
37503750
changes:
3751+
- version: REPLACEME
3752+
pr-url: https://github.com/nodejs/node/pull/54869
3753+
description: Runtime deprecation.
37513754
- version:
37523755
- v22.9.0
37533756
- v20.18.0
37543757
pr-url: https://github.com/nodejs/node/pull/54842
37553758
description: Documentation-only deprecation.
37563759
-->
37573760

3758-
Type: Documentation-only
3761+
Type: Runtime
37593762

37603763
Instantiating classes without the `new` qualifier exported by the `node:repl` module is deprecated.
37613764
It is recommended to use the `new` qualifier instead. This applies to all REPL classes, including

lib/internal/util.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ const {
6363
} = internalBinding('util');
6464
const { isNativeError, isPromise } = internalBinding('types');
6565
const { getOptionValue } = require('internal/options');
66+
const assert = require('internal/assert');
6667
const { encodings } = internalBinding('string_decoder');
6768

6869
const noCrypto = !process.versions.openssl;
@@ -179,6 +180,14 @@ function deprecate(fn, msg, code, useEmitSync) {
179180
return deprecated;
180181
}
181182

183+
function deprecateInstantiation(target, code, ...args) {
184+
assert(typeof code === 'string');
185+
186+
getDeprecationWarningEmitter(code, `Instantiating ${target.name} without the 'new' keyword has been deprecated.`, target)();
187+
188+
return ReflectConstruct(target, args);
189+
}
190+
182191
function decorateErrorStack(err) {
183192
if (!(isError(err) && err.stack) || err[decorated_private_symbol])
184193
return;
@@ -879,6 +888,7 @@ module.exports = {
879888
defineLazyProperties,
880889
defineReplaceableLazyAttribute,
881890
deprecate,
891+
deprecateInstantiation,
882892
emitExperimentalWarning,
883893
encodingsMap,
884894
exposeInterface,

lib/repl.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ const {
111111
decorateErrorStack,
112112
isError,
113113
deprecate,
114+
deprecateInstantiation,
114115
SideEffectFreeRegExpPrototypeSymbolReplace,
115116
SideEffectFreeRegExpPrototypeSymbolSplit,
116117
} = require('internal/util');
@@ -262,12 +263,7 @@ function REPLServer(prompt,
262263
ignoreUndefined,
263264
replMode) {
264265
if (!(this instanceof REPLServer)) {
265-
return new REPLServer(prompt,
266-
stream,
267-
eval_,
268-
useGlobal,
269-
ignoreUndefined,
270-
replMode);
266+
return deprecateInstantiation(REPLServer, 'DEP0185', prompt, stream, eval_, useGlobal, ignoreUndefined, replMode);
271267
}
272268

273269
let options;

test/parallel/test-repl-preview-without-inspector.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ function runAndWait(cmds, repl) {
6565
return promise;
6666
}
6767

68-
const repl = REPLServer({
68+
const repl = new REPLServer({
6969
prompt: PROMPT,
7070
stream: new REPLStream(),
7171
ignoreUndefined: true,

test/parallel/test-repl-preview.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ function runAndWait(cmds, repl) {
5757
}
5858

5959
async function tests(options) {
60-
const repl = REPLServer({
60+
const repl = new REPLServer({
6161
prompt: PROMPT,
6262
stream: new REPLStream(),
6363
ignoreUndefined: true,

test/parallel/test-repl.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,3 +1035,17 @@ function event(ee, expected) {
10351035
}));
10361036
});
10371037
}
1038+
1039+
{
1040+
const server = repl.REPLServer();
1041+
common.expectWarning({
1042+
DeprecationWarning: {
1043+
DEP0185: 'Instantiating REPLServer without the \'new\' keyword has been deprecated.',
1044+
// For the 'url.format' test-case.
1045+
DEP0169:
1046+
'`url.parse()` behavior is not standardized and prone to errors that have security implications. ' +
1047+
'Use the WHATWG URL API instead. CVEs are not issued for `url.parse()` vulnerabilities.',
1048+
}
1049+
});
1050+
server.emit('line', '.exit');
1051+
}

0 commit comments

Comments
 (0)