diff --git a/package-lock.json b/package-lock.json index ca71bc67..9a8e7260 100644 --- a/package-lock.json +++ b/package-lock.json @@ -402,7 +402,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -1516,6 +1515,10 @@ "resolved": "recipes/import-assertions-to-attributes", "link": true }, + "node_modules/@nodejs/net-setsimultaneousaccepts-migration": { + "resolved": "recipes/net-setSimultaneousAccepts-migration", + "link": true + }, "node_modules/@nodejs/node-url-to-whatwg-url": { "resolved": "recipes/node-url-to-whatwg-url", "link": true @@ -1574,7 +1577,6 @@ "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.2.tgz", "integrity": "sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==", "license": "MIT", - "peer": true, "dependencies": { "@octokit/auth-token": "^4.0.0", "@octokit/graphql": "^7.1.0", @@ -1772,7 +1774,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -2091,7 +2092,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.19", "caniuse-lite": "^1.0.30001751", @@ -4369,6 +4369,17 @@ "@codemod.com/jssg-types": "^1.0.9" } }, + "recipes/net-setSimultaneousAccepts-migration": { + "name": "@nodejs/net-setsimultaneousaccepts-migration", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@nodejs/codemod-utils": "*" + }, + "devDependencies": { + "@codemod.com/jssg-types": "^1.0.9" + } + }, "recipes/node-url-to-whatwg-url": { "name": "@nodejs/node-url-to-whatwg-url", "version": "1.0.0", diff --git a/package.json b/package.json index 1fbe95b8..191fe0ba 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "automation", "codemod", "migrations", - "node.js" + "node.js" ], "license": "MIT", "bugs": { diff --git a/recipes/net-setSimultaneousAccepts-migration/README.md b/recipes/net-setSimultaneousAccepts-migration/README.md new file mode 100644 index 00000000..a04c94e3 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/README.md @@ -0,0 +1,77 @@ +# `net._setSimultaneousAccepts()` DEP0121 + +This recipe provides a guide for removing `net._setSimultaneousAccepts()`. + +See [DEP0121](https://nodejs.org/api/deprecations.html#DEP0121). + +## Examples + +### Remove internal API call + +```diff + const net = require("node:net"); + +- net._setSimultaneousAccepts(false); + const server = net.createServer(); +``` + +### Remove from server initialization + +```diff + const net = require("node:net"); + + function createServer() { +- net._setSimultaneousAccepts(true); + return net.createServer((socket) => { + // handle connection + }); + } +``` + +### Remove from module setup + +```diff + const net = require("node:net"); + +- net._setSimultaneousAccepts(false); + module.exports = { + createServer: () => net.createServer() + }; +``` + +### Remove from application startup + +```diff + const net = require("node:net"); + + function initializeApp() { +- net._setSimultaneousAccepts(true); + const server = net.createServer(); + server.listen(3000); + } +``` + +### ESM import cleanup + +```diff + import net from "node:net"; + +- net._setSimultaneousAccepts(false); + const server = net.createServer(); +``` + +### Remove from configuration + +```diff + const net = require("node:net"); + + const config = { +- simultaneousAccepts: false, + port: 8080 + }; + + function setupServer(config) { +- net._setSimultaneousAccepts(config.simultaneousAccepts); + return net.createServer().listen(config.port); + } +``` diff --git a/recipes/net-setSimultaneousAccepts-migration/codemod.yaml b/recipes/net-setSimultaneousAccepts-migration/codemod.yaml new file mode 100644 index 00000000..34efd690 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/codemod.yaml @@ -0,0 +1,21 @@ +schema_version: "1.0" +name: "@nodejs/net-setSimultaneousAccepts-deprecation" +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 diff --git a/recipes/net-setSimultaneousAccepts-migration/package.json b/recipes/net-setSimultaneousAccepts-migration/package.json new file mode 100644 index 00000000..6b9d8ce9 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/package.json @@ -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": "*" + } +} diff --git a/recipes/net-setSimultaneousAccepts-migration/src/workflow.ts b/recipes/net-setSimultaneousAccepts-migration/src/workflow.ts new file mode 100644 index 00000000..8c683bc2 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/src/workflow.ts @@ -0,0 +1,305 @@ +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, SgNode } 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 + * 5. Removes unused variables/properties passed to the function + * + * Note: This was an internal API (DEP0121) that reached End-of-Life in Node.js v24.0.0 + */ +export default function transform(root: SgRoot): string | null { + const rootNode = root.root(); + const edits: Edit[] = []; + const linesToRemove: Range[] = []; + + const netImportStatements = getAllNetImportStatements(root); + + // If no import found we don't process the file + if (!netImportStatements.length) return null; + + for (const statement of netImportStatements) { + processNetImportStatement(rootNode, statement, linesToRemove, edits); + } + + //No changes, nothing to do + if (!edits.length && !linesToRemove.length) return null; + + return applyTransformations(rootNode, edits, linesToRemove); +} + +/** + * Collects all import/require statements for 'node:net' + */ +function getAllNetImportStatements(root: SgRoot): SgNode[] { + return [ + ...getNodeImportStatements(root, 'net'), + ...getNodeImportCalls(root, 'net'), + ...getNodeRequireCalls(root, 'net'), + ]; +} + +/** + * Processes a single net import statement and finds all _setSimultaneousAccepts calls + */ +function processNetImportStatement( + rootNode: SgNode, + statementNode: SgNode, + linesToRemove: Range[], + edits: Edit[] +): void { + const bindingPath = resolveBindingPath(statementNode, '$'); + + if (!bindingPath) return; + + const callExpressions = rootNode.findAll({ + rule: { + pattern: `${bindingPath}._setSimultaneousAccepts($ARG)`, + }, + }); + + for (const callNode of callExpressions) { + const argNode = callNode.getMatch('ARG'); + + if (argNode) { + handleCallArgument(rootNode, argNode, linesToRemove); + } + + removeCallExpression(callNode, linesToRemove, edits); + } +} + +/** + * Handles the argument passed to _setSimultaneousAccepts() + * If it's a member expression or identifier that's only used here, marks it for removal + */ +function handleCallArgument( + rootNode: SgNode, + argNode: SgNode, + linesToRemove: Range[] +): void { + const argKind = argNode.kind(); + + switch(argKind) { + case 'member_expression': handleMemberExpressionArgument(rootNode, argNode, linesToRemove); break; + case 'identifier': handleIdentifierArgument(rootNode, argNode, linesToRemove); break; + } +} + +/** + * Handles member expression arguments (e.g., config.flag) + * Removes the property from the object if it's only used in this call + */ +function handleMemberExpressionArgument( + rootNode: SgNode, + argNode: SgNode, + linesToRemove: Range[] +): void { + const objectNode = argNode.child(0); + const propertyNode = argNode.child(2); + + if (!objectNode || !propertyNode) return; + + const objectName = objectNode.text(); + const propertyName = propertyNode.text(); + + const propertyRefs = rootNode.findAll({ + rule: { pattern: `${objectName}.${propertyName}` }, + }); + + // Remove when this is the only reference + if (propertyRefs.length === 1) { + removePropertyFromObjectDeclaration(rootNode, objectName, propertyName, linesToRemove); + } +} + +/** + * Removes a property from an object literal declaration + */ +function removePropertyFromObjectDeclaration( + rootNode: SgNode, + objectName: string, + propertyName: string, + linesToRemove: Range[] +): void { + const pairs = rootNode + .findAll({ + rule: { + kind: 'variable_declarator', + has: { + kind: 'identifier', + field: 'name', + pattern: objectName, + }, + }, + }) + .flatMap((decl) => + decl.findAll({ + rule: { + kind: 'pair', + has: { + field: 'key', + regex: propertyName, + }, + }, + }), + ); + + for (const pair of pairs) { + const rangeWithComma = expandRangeToIncludeTrailingComma( + pair.range(), + rootNode.text() + ); + linesToRemove.push(rangeWithComma); + } +} + +/** + * Expands a range to include a trailing comma if present + */ +function expandRangeToIncludeTrailingComma(range: Range, sourceText: string): Range { + const endPos = range.end.index; + + if (endPos < sourceText.length && sourceText[endPos] === ',') { + return { + start: range.start, + end: { + ...range.end, + index: endPos + 1, + column: range.end.column + 1 + } + }; + } + + return range; +} + +/** + * Handles identifier arguments (e.g., a variable name) + * Removes the variable declaration if it's only used in this call + */ +function handleIdentifierArgument( + rootNode: SgNode, + argNode: SgNode, + linesToRemove: Range[] +): void { + const varName = argNode.text().trim(); + + const allIdentifiers = rootNode.findAll({ + rule: { + pattern: varName, + kind: 'identifier', + }, + }); + + // Only remove if there are exactly 2 references (declaration + usage) + if (allIdentifiers.length === 2) { + removeVariableDeclaration(rootNode, varName, linesToRemove); + } +} + +/** + * Removes a variable declaration statement + */ +function removeVariableDeclaration( + rootNode: SgNode, + varName: string, + linesToRemove: Range[] +): void { + const varDeclarationStatements = rootNode.findAll({ + rule: { + kind: 'variable_declarator', + has: { + kind: 'identifier', + field: 'name', + pattern: varName, + }, + }, + }); + + for (const declNode of varDeclarationStatements) { + const topLevelStatement = findTopLevelStatement(declNode); + if (topLevelStatement) { + linesToRemove.push(topLevelStatement.range()); + } + } +} + +/** + * Finds the top-level statement (direct child of program) for a given node + */ +function findTopLevelStatement(node: SgNode): SgNode | null { + let current: SgNode | null = node; + + while (current) { + const parent = current.parent(); + if (!parent) break; + + if (parent.kind() === 'program') { + return current; + } + + current = parent; + } + + return null; +} + +/** + * Removes the call expression itself + */ +function removeCallExpression( + callNode: SgNode, + linesToRemove: Range[], + edits: Edit[] +): void { + const expressionStatement = findParentExpressionStatement(callNode); + + if (expressionStatement) { + linesToRemove.push(expressionStatement.range()); + } else { + edits.push(callNode.replace('')); + } +} + +/** + * Finds the parent expression_statement node + */ +function findParentExpressionStatement(node: SgNode): SgNode | null { + let current: SgNode | null = node.parent(); + + while (current && current.kind() !== 'expression_statement') { + current = current.parent(); + } + + return current; +} + +/** + * Applies all edits and line removals to the source code + */ +function applyTransformations( + rootNode: SgNode, + edits: Edit[], + linesToRemove: Range[] +): string { + const sourceCode = edits.length > 0 + ? rootNode.commitEdits(edits) + : rootNode.text(); + + return linesToRemove.length > 0 + ? removeLines(sourceCode, linesToRemove) + : sourceCode; +} diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-1.js b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-1.js new file mode 100644 index 00000000..3e1b402d --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-1.js @@ -0,0 +1,3 @@ +const net = require("node:net"); + +const server = net.createServer(); diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-10.js b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-10.js new file mode 100644 index 00000000..6cc1eaaa --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-10.js @@ -0,0 +1,5 @@ +const net = await import("node:net"); + +module.exports = { + createServer: () => net.createServer() +}; diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-11.js b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-11.js new file mode 100644 index 00000000..6d2f9654 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-11.js @@ -0,0 +1,18 @@ +const net = require("node:net"); + + +const server = net.createServer((socket) => { + socket.on('data', (data) => { + console.log(data); + }); + socket.write('Hello World!'); + socket.end(); +}); + +server.listen(3000, () => { + console.log('Server listening on port 3000'); +}); + +server.on('connection', (socket) => { + console.log('New connection'); +}); diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-12.js b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-12.js new file mode 100644 index 00000000..a41e9c3a --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-12.js @@ -0,0 +1,16 @@ +const net = require("node:net"); + +const client = net.createConnection({ port: 3000 }, () => { + console.log('connected to server!'); + client.write('world!\r\n'); +}); + + +client.on('data', (data) => { + console.log(data.toString()); + client.end(); +}); + +client.on('end', () => { + console.log('disconnected from server'); +}); diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-13.js b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-13.js new file mode 100644 index 00000000..b6ed10b7 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-13.js @@ -0,0 +1,8 @@ +import net, { isIP, isIPv4, isIPv6 } from "node:net"; + + +const ipv4 = isIPv4('127.0.0.1'); +const ipv6 = isIPv6('::1'); +const ip = isIP('192.168.1.1'); + +console.log({ ipv4, ipv6, ip }); diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-14.js b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-14.js new file mode 100644 index 00000000..fecd44b8 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-14.js @@ -0,0 +1,21 @@ +const net = require("node:net"); + +class ServerManager { + constructor() { + this.server = net.createServer(); + } + + start(port) { + this.server.listen(port); + } + + getAddress() { + return this.server.address(); + } + + stop() { + this.server.close(); + } +} + +module.exports = ServerManager; diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-15.js b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-15.js new file mode 100644 index 00000000..9b87b39d --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-15.js @@ -0,0 +1,15 @@ +const net = require("node:net"); + +const server = net.createServer(); + +server.on('error', (err) => { + console.error(err); +}); + + +server.maxConnections = 10; +server.listen(8080, '0.0.0.0'); + +const socket = new net.Socket(); +socket.connect(8080, 'localhost'); +socket.setTimeout(3000); diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-2.js b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-2.js new file mode 100644 index 00000000..c90799b7 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-2.js @@ -0,0 +1,7 @@ +const net = require("node:net"); + +function createServer() { + return net.createServer((socket) => { + // handle connection + }); +} diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-3.js b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-3.js new file mode 100644 index 00000000..08793080 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-3.js @@ -0,0 +1,5 @@ +const net = require("node:net"); + +module.exports = { + createServer: () => net.createServer() +}; diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-4.js b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-4.js new file mode 100644 index 00000000..e6398fa2 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-4.js @@ -0,0 +1,6 @@ +const net = require("node:net"); + +function initializeApp() { + const server = net.createServer(); + server.listen(3000); +} diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-5.js b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-5.js new file mode 100644 index 00000000..5cd16aa9 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-5.js @@ -0,0 +1,3 @@ +import net from "node:net"; + +const server = net.createServer(); diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-6.js b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-6.js new file mode 100644 index 00000000..3c15f15a --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-6.js @@ -0,0 +1,9 @@ +const net = require("node:net"); + +const config = { + port: 8080 +}; + +function setupServer(config) { + return net.createServer().listen(config.port); +} diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-7.js b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-7.js new file mode 100644 index 00000000..646fffb7 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-7.js @@ -0,0 +1,6 @@ +const net = require("node:net"); + + +function setupServer(config) { + return net.createServer().listen(8080); +} diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-8.js b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-8.js new file mode 100644 index 00000000..bccd83cb --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-8.js @@ -0,0 +1,7 @@ +const net = require("node:net"); + +const simultaneousAccepts = false; + +function setupServer(config) { + return net.createServer().listen(simultaneousAccepts); +} diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-9.js b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-9.js new file mode 100644 index 00000000..233209fa --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/expected/file-9.js @@ -0,0 +1,5 @@ +const net = require("node:net"); + +function setupServer(config) { + return net.createServer().listen(8080); +} diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/input/file-1.js b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-1.js new file mode 100644 index 00000000..89bcc3b8 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-1.js @@ -0,0 +1,4 @@ +const net = require("node:net"); + +net._setSimultaneousAccepts(false); +const server = net.createServer(); diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/input/file-10.js b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-10.js new file mode 100644 index 00000000..b86d73d1 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-10.js @@ -0,0 +1,6 @@ +const net = await import("node:net"); + +net._setSimultaneousAccepts(false); +module.exports = { + createServer: () => net.createServer() +}; diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/input/file-11.js b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-11.js new file mode 100644 index 00000000..353fd789 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-11.js @@ -0,0 +1,19 @@ +const net = require("node:net"); + +net._setSimultaneousAccepts(true); + +const server = net.createServer((socket) => { + socket.on('data', (data) => { + console.log(data); + }); + socket.write('Hello World!'); + socket.end(); +}); + +server.listen(3000, () => { + console.log('Server listening on port 3000'); +}); + +server.on('connection', (socket) => { + console.log('New connection'); +}); diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/input/file-12.js b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-12.js new file mode 100644 index 00000000..a689234d --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-12.js @@ -0,0 +1,17 @@ +const net = require("node:net"); + +const client = net.createConnection({ port: 3000 }, () => { + console.log('connected to server!'); + client.write('world!\r\n'); +}); + +net._setSimultaneousAccepts(false); + +client.on('data', (data) => { + console.log(data.toString()); + client.end(); +}); + +client.on('end', () => { + console.log('disconnected from server'); +}); diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/input/file-13.js b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-13.js new file mode 100644 index 00000000..dda9da53 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-13.js @@ -0,0 +1,9 @@ +import net, { isIP, isIPv4, isIPv6 } from "node:net"; + +net._setSimultaneousAccepts(true); + +const ipv4 = isIPv4('127.0.0.1'); +const ipv6 = isIPv6('::1'); +const ip = isIP('192.168.1.1'); + +console.log({ ipv4, ipv6, ip }); diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/input/file-14.js b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-14.js new file mode 100644 index 00000000..9a50d5c1 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-14.js @@ -0,0 +1,22 @@ +const net = require("node:net"); + +class ServerManager { + constructor() { + this.server = net.createServer(); + net._setSimultaneousAccepts(true); + } + + start(port) { + this.server.listen(port); + } + + getAddress() { + return this.server.address(); + } + + stop() { + this.server.close(); + } +} + +module.exports = ServerManager; diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/input/file-15.js b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-15.js new file mode 100644 index 00000000..31ba3103 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-15.js @@ -0,0 +1,16 @@ +const net = require("node:net"); + +const server = net.createServer(); + +server.on('error', (err) => { + console.error(err); +}); + +net._setSimultaneousAccepts(false); + +server.maxConnections = 10; +server.listen(8080, '0.0.0.0'); + +const socket = new net.Socket(); +socket.connect(8080, 'localhost'); +socket.setTimeout(3000); diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/input/file-2.js b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-2.js new file mode 100644 index 00000000..4868322d --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-2.js @@ -0,0 +1,8 @@ +const net = require("node:net"); + +function createServer() { + net._setSimultaneousAccepts(true); + return net.createServer((socket) => { + // handle connection + }); +} diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/input/file-3.js b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-3.js new file mode 100644 index 00000000..78b47dd1 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-3.js @@ -0,0 +1,6 @@ +const net = require("node:net"); + +net._setSimultaneousAccepts(false); +module.exports = { + createServer: () => net.createServer() +}; diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/input/file-4.js b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-4.js new file mode 100644 index 00000000..d4154e6c --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-4.js @@ -0,0 +1,7 @@ +const net = require("node:net"); + +function initializeApp() { + net._setSimultaneousAccepts(true); + const server = net.createServer(); + server.listen(3000); +} diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/input/file-5.js b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-5.js new file mode 100644 index 00000000..cf037959 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-5.js @@ -0,0 +1,4 @@ +import net from "node:net"; + +net._setSimultaneousAccepts(false); +const server = net.createServer(); diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/input/file-6.js b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-6.js new file mode 100644 index 00000000..24505c41 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-6.js @@ -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); +} diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/input/file-7.js b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-7.js new file mode 100644 index 00000000..5237bedc --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-7.js @@ -0,0 +1,8 @@ +const net = require("node:net"); + +let simultaneousAccepts = false; + +function setupServer(config) { + net._setSimultaneousAccepts(simultaneousAccepts); + return net.createServer().listen(8080); +} diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/input/file-8.js b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-8.js new file mode 100644 index 00000000..e14c6086 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-8.js @@ -0,0 +1,8 @@ +const net = require("node:net"); + +const simultaneousAccepts = false; + +function setupServer(config) { + net._setSimultaneousAccepts(simultaneousAccepts); + return net.createServer().listen(simultaneousAccepts); +} diff --git a/recipes/net-setSimultaneousAccepts-migration/tests/input/file-9.js b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-9.js new file mode 100644 index 00000000..c10d4c99 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/tests/input/file-9.js @@ -0,0 +1,7 @@ +const net = require("node:net"); +const simultaneousAccepts = require("some-module"); + +function setupServer(config) { + net._setSimultaneousAccepts(simultaneousAccepts); + return net.createServer().listen(8080); +} diff --git a/recipes/net-setSimultaneousAccepts-migration/workflow.yaml b/recipes/net-setSimultaneousAccepts-migration/workflow.yaml new file mode 100644 index 00000000..e41bcbe7 --- /dev/null +++ b/recipes/net-setSimultaneousAccepts-migration/workflow.yaml @@ -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