Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
"automation",
"codemod",
"migrations",
"node.js"
],
"node.js" ],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should revert this change

"license": "MIT",
"bugs": {
"url": "https://github.com/nodejs/userland-migrations/issues"
Expand Down
17 changes: 17 additions & 0 deletions recipes/net-setSimultaneousAccepts-migration/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# `net._setSimultaneousAccepts()` DEP0121

This recipe provides a guide for removing `net._setSimultaneousAccepts()`.

See [DEP0121](https://nodejs.org/api/deprecations.html#DEP0121).

## Examples

**Before:**

```js
```

**After:**

```js
```
21 changes: 21 additions & 0 deletions recipes/net-setSimultaneousAccepts-migration/codemod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
schema_version: "1.0"
name: "@nodejs/net-setSimultaneousAccepts-migration"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
name: "@nodejs/net-setSimultaneousAccepts-migration"
name: "@nodejs/net-setSimultaneousAccepts-deprecation"

#namingIsHard @nodejs/userland-migrations what do you think

version: 1.0.0
description: "Handle DEDEP0121: Remove net._setSimultaneousAccepts()"
author: Alejandro Espa
license: MIT
workflow: workflow.yaml
category: migration

targets:
languages:
- javascript
- typescript

keywords:
- transformation
- migration

registry:
access: public
visibility: public
24 changes: 24 additions & 0 deletions recipes/net-setSimultaneousAccepts-migration/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "@nodejs/net-setsimultaneousaccepts-migration",
"version": "1.0.0",
"description": "Handle DEP0121: Remove net._setSimultaneousAccepts().",
"type": "module",
"scripts": {
"test": "npx codemod jssg test -l typescript ./src/workflow.ts ./"
},
"repository": {
"type": "git",
"url": "git+https://github.com/nodejs/userland-migrations.git",
"directory": "recipes/net-setsimultaneousaccepts-migration",
"bugs": "https://github.com/nodejs/userland-migrations/issues"
},
"author": "Alejandro Espa",
"license": "MIT",
"homepage": "https://github.com/nodejs/userland-migrations/blob/main/recipes/net-setsimultaneousaccepts-migration/README.md",
"devDependencies": {
"@codemod.com/jssg-types": "^1.0.9"
},
"dependencies": {
"@nodejs/codemod-utils": "*"
}
}
82 changes: 82 additions & 0 deletions recipes/net-setSimultaneousAccepts-migration/src/workflow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import {
getNodeImportStatements,
getNodeImportCalls,
} from '@nodejs/codemod-utils/ast-grep/import-statement';
import { getNodeRequireCalls } from '@nodejs/codemod-utils/ast-grep/require-call';
import { resolveBindingPath } from '@nodejs/codemod-utils/ast-grep/resolve-binding-path';
import { removeLines } from '@nodejs/codemod-utils/ast-grep/remove-lines';
import type { SgRoot, Edit, Range } from '@codemod.com/jssg-types/main';
import type Js from '@codemod.com/jssg-types/langs/javascript';

/**
* Transform function that removes deprecated net._setSimultaneousAccepts() calls
*
* Handles:
* 1. net._setSimultaneousAccepts(true) → removed
* 2. net._setSimultaneousAccepts(false) → removed
* 3. Works with both CommonJS (require) and ESM (import) syntax
* 4. Handles aliased imports/requires
*
* Note: This was an internal API (DEP0121) that reached End-of-Life in Node.js v24.0.0
*/
export default function transform(root: SgRoot<Js>): string | null {
const rootNode = root.root();
const edits: Edit[] = [];
const linesToRemove: Range[] = [];

// Collect all 'node:net' module imports/requires
const allStatements = [
...getNodeImportStatements(root, 'node:net'),
...getNodeImportCalls(root, 'node:net'),
...getNodeRequireCalls(root, 'node:net'),
Comment on lines +45 to +47
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
...getNodeImportStatements(root, 'node:net'),
...getNodeImportCalls(root, 'node:net'),
...getNodeRequireCalls(root, 'node:net'),
...getNodeImportStatements(root, 'net'),
...getNodeImportCalls(root, 'net'),
...getNodeRequireCalls(root, 'net'),

the node: isn't needed theses functions catch it

];

// If no net module statements found, skip transformation
if (allStatements.length === 0) return null;

for (const statementNode of allStatements) {
// Resolve the binding path for the net module
const bindingPath = resolveBindingPath(statementNode, '$');

if (!bindingPath) continue;

// Find all calls to _setSimultaneousAccepts on the resolved binding
const callExpressions = rootNode.findAll({
rule: {
pattern: `${bindingPath}._setSimultaneousAccepts($$$ARGS)`,
},
});

for (const callNode of callExpressions) {
// Find the parent statement (expression_statement) to remove the entire line
let parentStatement = callNode.parent();

// Traverse up to find the expression_statement
while (parentStatement && parentStatement.kind() !== 'expression_statement') {
parentStatement = parentStatement.parent();
}

if (parentStatement) {
// Get the range of the entire statement including semicolon
const range = parentStatement.range();
linesToRemove.push(range);
} else {
// Fallback: just remove the call itself if we can't find the statement
edits.push(callNode.replace(''));
}
}
}

// If no changes were made, return null
if (edits.length === 0 && linesToRemove.length === 0) return null;

// Apply edits first if any
const sourceCode = edits.length > 0
? rootNode.commitEdits(edits)
: rootNode.text();

// Then remove the lines
return linesToRemove.length > 0
? removeLines(sourceCode, linesToRemove)
: sourceCode;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const net = require("node:net");

const server = net.createServer();
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const net = require("node:net");

function createServer() {
return net.createServer((socket) => {
// handle connection
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const net = require("node:net");

module.exports = {
createServer: () => net.createServer()
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const net = require("node:net");

function initializeApp() {
const server = net.createServer();
server.listen(3000);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import net from "node:net";

const server = net.createServer();
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const net = require("node:net");

const config = {
port: 8080
};

function setupServer(config) {
return net.createServer().listen(config.port);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const net = require("node:net");

net._setSimultaneousAccepts(false);
const server = net.createServer();
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const net = require("node:net");

function createServer() {
net._setSimultaneousAccepts(true);
return net.createServer((socket) => {
// handle connection
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const net = require("node:net");

net._setSimultaneousAccepts(false);
module.exports = {
createServer: () => net.createServer()
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const net = require("node:net");

function initializeApp() {
net._setSimultaneousAccepts(true);
const server = net.createServer();
server.listen(3000);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import net from "node:net";

net._setSimultaneousAccepts(false);
const server = net.createServer();
11 changes: 11 additions & 0 deletions recipes/net-setSimultaneousAccepts-migration/tests/input/file-6.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const net = require("node:net");

const config = {
simultaneousAccepts: false,
port: 8080
};

function setupServer(config) {
net._setSimultaneousAccepts(config.simultaneousAccepts);
return net.createServer().listen(config.port);
}
25 changes: 25 additions & 0 deletions recipes/net-setSimultaneousAccepts-migration/workflow.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/codemod-com/codemod/refs/heads/main/schemas/workflow.json

version: "1"

nodes:
- id: apply-transforms
name: Apply AST Transformations
type: automatic
steps:
- name: Handle DEDEP0121 Remove net._setSimultaneousAccepts().
js-ast-grep:
js_file: src/workflow.ts
base_path: .
include:
- "**/*.js"
- "**/*.jsx"
- "**/*.mjs"
- "**/*.cjs"
- "**/*.cts"
- "**/*.mts"
- "**/*.ts"
- "**/*.tsx"
exclude:
- "**/node_modules/**"
language: typescript