Skip to content

Commit

Permalink
repl: runtime deprecate instantiating without new
Browse files Browse the repository at this point in the history
PR-URL: #54869
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: LiviaMedeiros <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Jacob Smith <[email protected]>
  • Loading branch information
Aviv Keller authored Nov 7, 2024
1 parent f38cefa commit 0368f2f
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 9 deletions.
5 changes: 4 additions & 1 deletion doc/api/deprecations.md
Original file line number Diff line number Diff line change
Expand Up @@ -3748,14 +3748,17 @@ 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
pr-url: https://github.com/nodejs/node/pull/54842
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
Expand Down
10 changes: 10 additions & 0 deletions lib/internal/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -879,6 +888,7 @@ module.exports = {
defineLazyProperties,
defineReplaceableLazyAttribute,
deprecate,
deprecateInstantiation,
emitExperimentalWarning,
encodingsMap,
exposeInterface,
Expand Down
8 changes: 2 additions & 6 deletions lib/repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ const {
decorateErrorStack,
isError,
deprecate,
deprecateInstantiation,
SideEffectFreeRegExpPrototypeSymbolReplace,
SideEffectFreeRegExpPrototypeSymbolSplit,
} = require('internal/util');
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-repl-preview-without-inspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ function runAndWait(cmds, repl) {
return promise;
}

const repl = REPLServer({
const repl = new REPLServer({
prompt: PROMPT,
stream: new REPLStream(),
ignoreUndefined: true,
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-repl-preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
14 changes: 14 additions & 0 deletions test/parallel/test-repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
}

0 comments on commit 0368f2f

Please sign in to comment.