From 6ef1d20574edbd73e1a192bdcacd796420cc1a8d Mon Sep 17 00:00:00 2001 From: Maxime Devillet Date: Thu, 27 Nov 2025 12:24:49 +0100 Subject: [PATCH 01/27] working version with test and README for TLSSocket --- .../README.md | 0 .../codemod.yaml | 21 +++ .../package.json | 15 ++ .../src/workflow.ts | 132 ++++++++++++++++++ .../test.sh | 74 ++++++++++ .../tests/expected/file-1.js | 8 ++ .../tests/expected/file-2.js | 8 ++ .../tests/expected/test-crucial-file.js | 10 ++ .../expected/test-edge-variable-name-file.js | 7 + .../tests/expected/test-esm-file.js | 8 ++ .../expected/test-multiple-variable-file.js | 7 + .../tests/expected/test-scoping-file.js | 14 ++ .../tests/input/basic-test-file-3.js | 0 .../tests/input/file-1.js | 10 ++ .../tests/input/file-2.js | 10 ++ .../tests/input/test-crucial-file.js | 12 ++ .../input/test-edge-variable-name-file.js | 8 ++ .../tests/input/test-esm-file.js | 10 ++ .../input/test-multiple-variable-file.js | 9 ++ .../tests/input/test-scoping-file.js | 14 ++ .../workflow.yaml | 25 ++++ 21 files changed, 402 insertions(+) create mode 100644 recipes/tls-securepair-to-tlssocket_working/README.md create mode 100644 recipes/tls-securepair-to-tlssocket_working/codemod.yaml create mode 100644 recipes/tls-securepair-to-tlssocket_working/package.json create mode 100644 recipes/tls-securepair-to-tlssocket_working/src/workflow.ts create mode 100755 recipes/tls-securepair-to-tlssocket_working/test.sh create mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/expected/file-1.js create mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/expected/file-2.js create mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/expected/test-crucial-file.js create mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/expected/test-edge-variable-name-file.js create mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/expected/test-esm-file.js create mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/expected/test-multiple-variable-file.js create mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/expected/test-scoping-file.js create mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/input/basic-test-file-3.js create mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/input/file-1.js create mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/input/file-2.js create mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/input/test-crucial-file.js create mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/input/test-edge-variable-name-file.js create mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/input/test-esm-file.js create mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/input/test-multiple-variable-file.js create mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/input/test-scoping-file.js create mode 100644 recipes/tls-securepair-to-tlssocket_working/workflow.yaml diff --git a/recipes/tls-securepair-to-tlssocket_working/README.md b/recipes/tls-securepair-to-tlssocket_working/README.md new file mode 100644 index 00000000..e69de29b diff --git a/recipes/tls-securepair-to-tlssocket_working/codemod.yaml b/recipes/tls-securepair-to-tlssocket_working/codemod.yaml new file mode 100644 index 00000000..400f1571 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket_working/codemod.yaml @@ -0,0 +1,21 @@ +schema_version: "1.0" +name: "@nodejs/tmpDir-to-tmpdir" +version: "1.0.0" +description: Handle DEP0022 via transforming `tmpDir` to `tmpdir`. +author: nekojanai (Jana) +license: MIT +workflow: workflow.yaml +category: migration + +targets: + languages: + - javascript + - typescript + +keywords: + - transformation + - migration + +registry: + access: public + visibility: public \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/package.json b/recipes/tls-securepair-to-tlssocket_working/package.json new file mode 100644 index 00000000..e9518931 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket_working/package.json @@ -0,0 +1,15 @@ +{ + "name": "@nodejs/tls-securepair-to-tlssocket_working-codemod", + "version": "1.0.1", + "description": "", + "type": "module", + "author": "Maxime Devillet", + "license": "MIT", + "devDependencies": { + "@codemod.com/jssg-types": "^1.0.9" + }, + "dependencies": { + "@ast-grep/napi": "^0.40.0", + "@nodejs/codemod-utils": "*" + } +} diff --git a/recipes/tls-securepair-to-tlssocket_working/src/workflow.ts b/recipes/tls-securepair-to-tlssocket_working/src/workflow.ts new file mode 100644 index 00000000..802783d7 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket_working/src/workflow.ts @@ -0,0 +1,132 @@ +import { removeLines } from "@nodejs/codemod-utils/ast-grep/remove-lines"; +import type { Edit, SgRoot, Range } from "@codemod.com/jssg-types/main"; +import type Js from "@codemod.com/jssg-types/langs/javascript"; + +function getClosest(node: any, kinds: string[]): any | null { + let current = node.parent(); + while (current) { + if (kinds.includes(current.kind())) { + return current; + } + current = current.parent(); + } + return null; +} + +export default function transform(root: SgRoot): string | null { + const rootNode = root.root(); + const edits: Edit[] = []; + const linesToRemove: Range[] = []; + + const importNodes = rootNode.findAll({ + rule: { + any: [ + { kind: "import_specifier", has: { kind: "identifier", regex: "^SecurePair$" } }, + { kind: "shorthand_property_identifier_pattern", regex: "^SecurePair$" }, + { kind: "property_identifier", regex: "^SecurePair$" } + ] + } + }); + + for (const node of importNodes) { + if (node.text() === "SecurePair") { + edits.push(node.replace("TLSSocket")); + } + } + + const newExpressions = rootNode.findAll({ + rule: { + kind: "new_expression", + has: { + any: [ + { kind: "member_expression", has: { field: "property", regex: "^SecurePair$" } }, + { kind: "identifier", regex: "^SecurePair$" } + ] + } + } + }); + + for (const node of newExpressions) { + const callee = node.field("constructor"); + if (!callee) continue; + + let newConstructorName = "TLSSocket"; + if (callee.kind() === "member_expression") { + const object = callee.field("object"); + if (object) { + newConstructorName = `${object.text()}.TLSSocket`; + } + } + + edits.push(node.replace(`new ${newConstructorName}(socket)`)); + + const declarator = getClosest(node, ["variable_declarator"]); + if (declarator) { + const idNode = declarator.field("name"); + if (idNode) { + const oldName = idNode.text(); + + let newName = "socket"; + if (oldName !== "pair" && oldName !== "SecurePair") { + if (oldName.includes("Pair")) { + newName = oldName.replace("Pair", "Socket"); + } + else if (oldName.includes("pair")) { + newName = oldName.replace("pair", "socket"); + } + else { + newName = "socket"; + } + } + + const obsoleteUsages = rootNode.findAll({ + rule: { + kind: "member_expression", + all: [ + { has: { field: "object", regex: `^${oldName}$` } }, + { has: { field: "property", regex: "^(cleartext|encrypted)$" } } + ] + } + }); + + for (const usage of obsoleteUsages) { + const statement = getClosest(usage, ["lexical_declaration", "expression_statement"]); + if (statement) { + linesToRemove.push(statement.range()); + } + } + + edits.push(idNode.replace(newName)); + + const references = rootNode.findAll({ + rule: { + kind: "identifier", + regex: `^${oldName}$` + } + }); + + for (const ref of references) { + const parent = ref.parent(); + if (parent && parent.kind() === 'member_expression') { + const property = parent.field('property'); + if (property && property.id() === ref.id()) { + continue; + } + } + + if (parent && (parent.kind() === 'import_specifier' || parent.kind() === 'shorthand_property_identifier_pattern')) { + continue; + } + + if (ref.id() === idNode.id()) continue; + + edits.push(ref.replace(newName)); + } + } + } + } + + let sourceCode = rootNode.commitEdits(edits); + sourceCode = removeLines(sourceCode, linesToRemove); + return sourceCode; +} \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/test.sh b/recipes/tls-securepair-to-tlssocket_working/test.sh new file mode 100755 index 00000000..132c0460 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket_working/test.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +GREEN='\033[0;32m' +RED='\033[0;31m' +BLUE='\033[0;34m' +YELLOW='\033[1;33m' +BOLD='\033[1m' +NC='\033[0m' + +INPUT_DIR="tests/input" +EXPECTED_DIR="tests/expected" +TEMP_DIR="tests/temp_workzone" + +declare -a passed_files +declare -a failed_files + +echo -e "${BLUE}${BOLD}=== Starting Codemod Test Suite ===${NC}" + +rm -rf "$TEMP_DIR" +mkdir -p "$TEMP_DIR" +cp -r "$INPUT_DIR"/* "$TEMP_DIR" + +echo -e "➜ Running codemod on temporary files..." +npx codemod workflow run -w workflow.yaml -t "$TEMP_DIR" > /dev/null 2>&1 + +echo -e "➜ Verifying results...\n" + +for expected_file in "$EXPECTED_DIR"/*; do + filename=$(basename "$expected_file") + generated_file="$TEMP_DIR/$filename" + + if [ ! -f "$generated_file" ]; then + echo -e "${RED} [MISSING] $filename${NC}" + failed_files+=("$filename (Missing)") + continue + fi + + diff_output=$(diff -u --color=always "$expected_file" "$generated_file") + exit_code=$? + + if [ $exit_code -eq 0 ]; then + echo -e " ${GREEN}✔ $filename${NC}" + passed_files+=("$filename") + else + echo -e " ${RED}✘ $filename${NC}" + echo -e "${YELLOW}--- Differences for $filename ---${NC}" + echo "$diff_output" + echo -e "${YELLOW}----------------------------------${NC}\n" + failed_files+=("$filename") + fi +done + +rm -rf "$TEMP_DIR" + +echo -e "\n${BLUE}${BOLD}=== FINAL REPORT ===${NC}" + +if [ ${#passed_files[@]} -gt 0 ]; then + echo -e "\n${GREEN}${BOLD}Passed Tests (${#passed_files[@]}) :${NC}" + for f in "${passed_files[@]}"; do + echo -e " ${GREEN}✔ $f${NC}" + done +fi + +if [ ${#failed_files[@]} -gt 0 ]; then + echo -e "\n${RED}${BOLD}Failed Tests (${#failed_files[@]}) :${NC}" + for f in "${failed_files[@]}"; do + echo -e " ${RED}✘ $f${NC}" + done + echo -e "\n${RED}➔ Result: FAILURE${NC}" + exit 1 +else + echo -e "\n${GREEN}➔ Result: SUCCESS${NC}" + exit 0 +fi \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/expected/file-1.js b/recipes/tls-securepair-to-tlssocket_working/tests/expected/file-1.js new file mode 100644 index 00000000..cea1840a --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket_working/tests/expected/file-1.js @@ -0,0 +1,8 @@ +const tls = require('node:tls'); + +// Using tls.SecurePair constructor +const socket = new tls.TLSSocket(socket); + +// Direct import +const { TLSSocket } = require('node:tls'); +const socket2 = new TLSSocket(socket); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/expected/file-2.js b/recipes/tls-securepair-to-tlssocket_working/tests/expected/file-2.js new file mode 100644 index 00000000..ef8d2b1f --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket_working/tests/expected/file-2.js @@ -0,0 +1,8 @@ +import tls from 'node:tls'; + +// Using tls.SecurePair constructor +const socket = new tls.TLSSocket(socket); + +// Direct import +import { TLSSocket } from 'node:tls'; +const socket2 = new TLSSocket(socket); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-crucial-file.js b/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-crucial-file.js new file mode 100644 index 00000000..eddfdf8a --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-crucial-file.js @@ -0,0 +1,10 @@ +const { TLSSocket } = require('node:tls'); +const { unrelated } = require('other-module'); + +const socket = new TLSSocket(socket); + +socket.on('error', (err) => { + console.error(err); +}); + +// Propriétés obsolètes \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-edge-variable-name-file.js b/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-edge-variable-name-file.js new file mode 100644 index 00000000..63587943 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-edge-variable-name-file.js @@ -0,0 +1,7 @@ +const { TLSSocket } = require('node:tls'); + +// Nom de variable totalement arbitraire +const socket = new TLSSocket(socket); + +// Usage +socket.doSomething(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-esm-file.js b/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-esm-file.js new file mode 100644 index 00000000..265a0f37 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-esm-file.js @@ -0,0 +1,8 @@ +import tls from 'node:tls'; +import { TLSSocket } from 'node:tls'; + +// Cas 1 : Via namespace +const socket1 = new tls.TLSSocket(socket); + +// Cas 2 : Direct +const socket2 = new TLSSocket(socket); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-multiple-variable-file.js b/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-multiple-variable-file.js new file mode 100644 index 00000000..bdbaf28c --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-multiple-variable-file.js @@ -0,0 +1,7 @@ +const tls = require('node:tls'); + +const socket = new tls.TLSSocket(socket); +const mySocket = new tls.TLSSocket(socket); +const secureSocketInstance = new tls.TLSSocket(socket); + +// Nettoyage spécifique à chaque variable \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-scoping-file.js b/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-scoping-file.js new file mode 100644 index 00000000..433ca37d --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-scoping-file.js @@ -0,0 +1,14 @@ +const tls = require('node:tls'); + +class ConnectionManager { + constructor() { + if (true) { + const socket = new tls.TLSSocket(socket); + this.init(socket); + + if (socket.cleartext) { + console.log("cleaning"); + } + } + } +} \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/input/basic-test-file-3.js b/recipes/tls-securepair-to-tlssocket_working/tests/input/basic-test-file-3.js new file mode 100644 index 00000000..e69de29b diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/input/file-1.js b/recipes/tls-securepair-to-tlssocket_working/tests/input/file-1.js new file mode 100644 index 00000000..9ce8efdd --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket_working/tests/input/file-1.js @@ -0,0 +1,10 @@ +const tls = require('node:tls'); + +// Using tls.SecurePair constructor +const pair = new tls.SecurePair(); +const cleartext = pair.cleartext; +const encrypted = pair.encrypted; + +// Direct import +const { SecurePair } = require('node:tls'); +const pair2 = new SecurePair(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/input/file-2.js b/recipes/tls-securepair-to-tlssocket_working/tests/input/file-2.js new file mode 100644 index 00000000..fe8c30bc --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket_working/tests/input/file-2.js @@ -0,0 +1,10 @@ +import tls from 'node:tls'; + +// Using tls.SecurePair constructor +const pair = new tls.SecurePair(); +const cleartext = pair.cleartext; +const encrypted = pair.encrypted; + +// Direct import +import { SecurePair } from 'node:tls'; +const pair2 = new SecurePair(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/input/test-crucial-file.js b/recipes/tls-securepair-to-tlssocket_working/tests/input/test-crucial-file.js new file mode 100644 index 00000000..b65c52f9 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket_working/tests/input/test-crucial-file.js @@ -0,0 +1,12 @@ +const { SecurePair } = require('node:tls'); +const { unrelated } = require('other-module'); + +const pair = new SecurePair(); + +pair.on('error', (err) => { + console.error(err); +}); + +// Propriétés obsolètes +console.log(pair.cleartext); +console.log(pair.encrypted); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/input/test-edge-variable-name-file.js b/recipes/tls-securepair-to-tlssocket_working/tests/input/test-edge-variable-name-file.js new file mode 100644 index 00000000..7909d188 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket_working/tests/input/test-edge-variable-name-file.js @@ -0,0 +1,8 @@ +const { SecurePair } = require('node:tls'); + +// Nom de variable totalement arbitraire +const item = new SecurePair(); + +// Usage +item.doSomething(); +item.cleartext.read(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/input/test-esm-file.js b/recipes/tls-securepair-to-tlssocket_working/tests/input/test-esm-file.js new file mode 100644 index 00000000..058f003d --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket_working/tests/input/test-esm-file.js @@ -0,0 +1,10 @@ +import tls from 'node:tls'; +import { SecurePair } from 'node:tls'; + +// Cas 1 : Via namespace +const pair1 = new tls.SecurePair(); +const t1 = pair1.cleartext; + +// Cas 2 : Direct +const pair2 = new SecurePair(); +const t2 = pair2.encrypted; \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/input/test-multiple-variable-file.js b/recipes/tls-securepair-to-tlssocket_working/tests/input/test-multiple-variable-file.js new file mode 100644 index 00000000..2fb7e5dd --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket_working/tests/input/test-multiple-variable-file.js @@ -0,0 +1,9 @@ +const tls = require('node:tls'); + +const pair = new tls.SecurePair(); +const myPair = new tls.SecurePair(); +const securePairInstance = new tls.SecurePair(); + +// Nettoyage spécifique à chaque variable +pair.cleartext.write('hello'); +myPair.encrypted.write('world'); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/input/test-scoping-file.js b/recipes/tls-securepair-to-tlssocket_working/tests/input/test-scoping-file.js new file mode 100644 index 00000000..ded038b5 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket_working/tests/input/test-scoping-file.js @@ -0,0 +1,14 @@ +const tls = require('node:tls'); + +class ConnectionManager { + constructor() { + if (true) { + const pair = new tls.SecurePair(); + this.init(pair); + + if (pair.cleartext) { + console.log("cleaning"); + } + } + } +} \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/workflow.yaml b/recipes/tls-securepair-to-tlssocket_working/workflow.yaml new file mode 100644 index 00000000..611eea71 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket_working/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: name-test`. + js-ast-grep: + js_file: src/workflow.ts + base_path: . + include: + - "**/*.cjs" + - "**/*.js" + - "**/*.jsx" + - "**/*.mjs" + - "**/*.cts" + - "**/*.mts" + - "**/*.ts" + - "**/*.tsx" + exclude: + - "**/node_modules/**" + language: typescript From c6380065f663d4057817ae0b0074d2dcd5bdf0c5 Mon Sep 17 00:00:00 2001 From: Maxime Devillet Date: Fri, 5 Dec 2025 11:05:18 +0100 Subject: [PATCH 02/27] recipes(tls): add tls-securepair-to-tlssocket codemod --- recipes/tls-securepair-to-tlssocket/README.md | 98 +++++++++++++ .../tls-securepair-to-tlssocket/codemod.yaml | 23 +++ .../tls-securepair-to-tlssocket/package.json | 25 ++++ .../src/workflow.ts | 132 ++++++++++++++++++ recipes/tls-securepair-to-tlssocket/test.sh | 74 ++++++++++ .../tests/expected/basic-test-file-3.js | 11 ++ .../tests/expected/file-1.js | 8 ++ .../tests/expected/file-2.js | 8 ++ .../tests/expected/test-crucial-file.js | 10 ++ .../expected/test-edge-variable-name-file.js | 7 + .../tests/expected/test-esm-file.js | 8 ++ .../expected/test-multiple-variable-file.js | 7 + .../tests/expected/test-scoping-file.js | 14 ++ .../tests/input/basic-test-file-3.js | 13 ++ .../tests/input/file-1.js | 10 ++ .../tests/input/file-2.js | 10 ++ .../tests/input/test-crucial-file.js | 12 ++ .../input/test-edge-variable-name-file.js | 8 ++ .../tests/input/test-esm-file.js | 10 ++ .../input/test-multiple-variable-file.js | 9 ++ .../tests/input/test-scoping-file.js | 14 ++ .../tls-securepair-to-tlssocket/workflow.yaml | 25 ++++ 22 files changed, 536 insertions(+) create mode 100644 recipes/tls-securepair-to-tlssocket/README.md create mode 100644 recipes/tls-securepair-to-tlssocket/codemod.yaml create mode 100644 recipes/tls-securepair-to-tlssocket/package.json create mode 100644 recipes/tls-securepair-to-tlssocket/src/workflow.ts create mode 100755 recipes/tls-securepair-to-tlssocket/test.sh create mode 100644 recipes/tls-securepair-to-tlssocket/tests/expected/basic-test-file-3.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/expected/file-1.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/expected/file-2.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/expected/test-scoping-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/input/basic-test-file-3.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/input/file-1.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/input/file-2.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/input/test-crucial-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/input/test-edge-variable-name-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/input/test-esm-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/input/test-multiple-variable-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/input/test-scoping-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/workflow.yaml diff --git a/recipes/tls-securepair-to-tlssocket/README.md b/recipes/tls-securepair-to-tlssocket/README.md new file mode 100644 index 00000000..9e6d4220 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/README.md @@ -0,0 +1,98 @@ +# tls-securepair-to-tlssocket + +Codemod to migrate from the deprecated `tls.SecurePair` class to `tls.TLSSocket` in Node.js applications. `SecurePair` was deprecated and subsequently removed in favor of `TLSSocket`. + +## What it does + +This codemod transforms usages of `tls.SecurePair` into `tls.TLSSocket`. Since `TLSSocket` wraps an existing socket, the codemod injects a `socket` argument that you may need to define or bind in your context. + +Key transformations: +- **Constructor:** Replaces `new SecurePair()` with `new TLSSocket(socket)`. +- **Imports:** Updates `require` and `import` statements from `SecurePair` to `TLSSocket`. +- **Renaming:** Intelligently renames variables (e.g., `pair` → `socket`, `securePairInstance` → `socketInstance`) while preserving CamelCase. +- **Cleanup:** Removes deprecated property accesses like `.cleartext` and `.encrypted`. +- **Annotations:** Adds comments to highlight where manual API verification is needed. + +## Supports + +- **Module Systems:** + - CommonJS: `const tls = require('node:tls')` / `const { SecurePair } = ...` + - ESM: `import tls from 'node:tls'` / `import { SecurePair } ...` +- **Variable Renaming:** + - Updates variable declarations: `const pair = ...` → `const socket = ...` + - Updates references deep in the scope: `pair.on('error')` → `socket.on('error')` + - Handles naming variations: `myPair` → `mySocket`, `securePair` → `secureSocket`. +- **Cleanup:** + - Identifies and removes lines accessing `cleartext` or `encrypted` properties. +- **Namespace Handling:** + - Supports both `new tls.SecurePair()` and `new SecurePair()`. + +## Examples + +### Case 1: CommonJS & Variable Renaming + +**Before** + +```js +const tls = require('node:tls'); + +// Using tls.SecurePair constructor +const pair = new tls.SecurePair(); +const cleartext = pair.cleartext; +const encrypted = pair.encrypted; + +pair.on('error', (err) => { + console.error(err); +}); +``` + +**After** + +``` +const tls = require('node:tls'); + +// Using tls.TLSSocket instead +const socket = new tls.TLSSocket(socket); +// Note: Direct migration may require additional context-specific changes +// as SecurePair and TLSSocket have different APIs + +socket.on('error', (err) => { + console.error(err); +}); +``` + +### Case 2: ESM & Destructuring + +**Before** + +``` +import { SecurePair } from 'node:tls'; + +const myPair = new SecurePair(); +myPair.cleartext.write('hello'); +``` + +**After** + +``` +import { TLSSocket } from 'node:tls'; + +const mySocket = new TLSSocket(socket); +// Note: Direct migration may require additional context-specific changes +// as SecurePair and TLSSocket have different APIs +``` + +## Warning + +The tls.TLSSocket constructor requires an existing socket instance (net.Socket) as an argument. This codemod automatically inserts socket as the argument: +JavaScript + +``` +new TLSSocket(socket) +``` + +You must ensure that a variable named socket exists in the scope or rename it to match your existing socket variable (e.g., clientSocket, stream, etc.). + +## Test + +The test.sh script runs all the tests located in the tests folder. All input files are temporarily copied to a new folder and compared against their expected results found in the expected folder. This helps identify which tests failed and why. Feel free to add new tests if necessary. \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/codemod.yaml b/recipes/tls-securepair-to-tlssocket/codemod.yaml new file mode 100644 index 00000000..51603fc6 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/codemod.yaml @@ -0,0 +1,23 @@ +schema_version: "1.0" +name: "@nodejs/tls-securepair-to-tlssocket" +version: "1.0.0" +description: Migrate usages of `tls.SecurePair` to `tls.TLSSocket` where possible. +author: Maxime Devillet +license: MIT +workflow: workflow.yaml +category: migration + +targets: + languages: + - javascript + - typescript + +keywords: + - transformation + - migration + - tls + - securepair + +registry: + access: public + visibility: public \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/package.json b/recipes/tls-securepair-to-tlssocket/package.json new file mode 100644 index 00000000..f36b48e8 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/package.json @@ -0,0 +1,25 @@ +{ + "name": "@nodejs/tls-securepair-to-tlssocket", + "version": "1.0.0", + "description": "Migrate usages of tls.SecurePair to tls.TLSSocket.", + "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/tls-securepair-to-tlssocket", + "bugs": "https://github.com/nodejs/userland-migrations/issues" + }, + "author": "Maxime Devillet", + "license": "MIT", + "homepage": "https://github.com/nodejs/userland-migrations/blob/main/recipes/tls-securepair-to-tlssocket/README.md", + "devDependencies": { + "@codemod.com/jssg-types": "^1.0.9" + }, + "dependencies": { + "@nodejs/codemod-utils": "*", + "@ast-grep/napi": "^0.40.0" + } +} \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/src/workflow.ts b/recipes/tls-securepair-to-tlssocket/src/workflow.ts new file mode 100644 index 00000000..802783d7 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/src/workflow.ts @@ -0,0 +1,132 @@ +import { removeLines } from "@nodejs/codemod-utils/ast-grep/remove-lines"; +import type { Edit, SgRoot, Range } from "@codemod.com/jssg-types/main"; +import type Js from "@codemod.com/jssg-types/langs/javascript"; + +function getClosest(node: any, kinds: string[]): any | null { + let current = node.parent(); + while (current) { + if (kinds.includes(current.kind())) { + return current; + } + current = current.parent(); + } + return null; +} + +export default function transform(root: SgRoot): string | null { + const rootNode = root.root(); + const edits: Edit[] = []; + const linesToRemove: Range[] = []; + + const importNodes = rootNode.findAll({ + rule: { + any: [ + { kind: "import_specifier", has: { kind: "identifier", regex: "^SecurePair$" } }, + { kind: "shorthand_property_identifier_pattern", regex: "^SecurePair$" }, + { kind: "property_identifier", regex: "^SecurePair$" } + ] + } + }); + + for (const node of importNodes) { + if (node.text() === "SecurePair") { + edits.push(node.replace("TLSSocket")); + } + } + + const newExpressions = rootNode.findAll({ + rule: { + kind: "new_expression", + has: { + any: [ + { kind: "member_expression", has: { field: "property", regex: "^SecurePair$" } }, + { kind: "identifier", regex: "^SecurePair$" } + ] + } + } + }); + + for (const node of newExpressions) { + const callee = node.field("constructor"); + if (!callee) continue; + + let newConstructorName = "TLSSocket"; + if (callee.kind() === "member_expression") { + const object = callee.field("object"); + if (object) { + newConstructorName = `${object.text()}.TLSSocket`; + } + } + + edits.push(node.replace(`new ${newConstructorName}(socket)`)); + + const declarator = getClosest(node, ["variable_declarator"]); + if (declarator) { + const idNode = declarator.field("name"); + if (idNode) { + const oldName = idNode.text(); + + let newName = "socket"; + if (oldName !== "pair" && oldName !== "SecurePair") { + if (oldName.includes("Pair")) { + newName = oldName.replace("Pair", "Socket"); + } + else if (oldName.includes("pair")) { + newName = oldName.replace("pair", "socket"); + } + else { + newName = "socket"; + } + } + + const obsoleteUsages = rootNode.findAll({ + rule: { + kind: "member_expression", + all: [ + { has: { field: "object", regex: `^${oldName}$` } }, + { has: { field: "property", regex: "^(cleartext|encrypted)$" } } + ] + } + }); + + for (const usage of obsoleteUsages) { + const statement = getClosest(usage, ["lexical_declaration", "expression_statement"]); + if (statement) { + linesToRemove.push(statement.range()); + } + } + + edits.push(idNode.replace(newName)); + + const references = rootNode.findAll({ + rule: { + kind: "identifier", + regex: `^${oldName}$` + } + }); + + for (const ref of references) { + const parent = ref.parent(); + if (parent && parent.kind() === 'member_expression') { + const property = parent.field('property'); + if (property && property.id() === ref.id()) { + continue; + } + } + + if (parent && (parent.kind() === 'import_specifier' || parent.kind() === 'shorthand_property_identifier_pattern')) { + continue; + } + + if (ref.id() === idNode.id()) continue; + + edits.push(ref.replace(newName)); + } + } + } + } + + let sourceCode = rootNode.commitEdits(edits); + sourceCode = removeLines(sourceCode, linesToRemove); + return sourceCode; +} \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/test.sh b/recipes/tls-securepair-to-tlssocket/test.sh new file mode 100755 index 00000000..132c0460 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/test.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +GREEN='\033[0;32m' +RED='\033[0;31m' +BLUE='\033[0;34m' +YELLOW='\033[1;33m' +BOLD='\033[1m' +NC='\033[0m' + +INPUT_DIR="tests/input" +EXPECTED_DIR="tests/expected" +TEMP_DIR="tests/temp_workzone" + +declare -a passed_files +declare -a failed_files + +echo -e "${BLUE}${BOLD}=== Starting Codemod Test Suite ===${NC}" + +rm -rf "$TEMP_DIR" +mkdir -p "$TEMP_DIR" +cp -r "$INPUT_DIR"/* "$TEMP_DIR" + +echo -e "➜ Running codemod on temporary files..." +npx codemod workflow run -w workflow.yaml -t "$TEMP_DIR" > /dev/null 2>&1 + +echo -e "➜ Verifying results...\n" + +for expected_file in "$EXPECTED_DIR"/*; do + filename=$(basename "$expected_file") + generated_file="$TEMP_DIR/$filename" + + if [ ! -f "$generated_file" ]; then + echo -e "${RED} [MISSING] $filename${NC}" + failed_files+=("$filename (Missing)") + continue + fi + + diff_output=$(diff -u --color=always "$expected_file" "$generated_file") + exit_code=$? + + if [ $exit_code -eq 0 ]; then + echo -e " ${GREEN}✔ $filename${NC}" + passed_files+=("$filename") + else + echo -e " ${RED}✘ $filename${NC}" + echo -e "${YELLOW}--- Differences for $filename ---${NC}" + echo "$diff_output" + echo -e "${YELLOW}----------------------------------${NC}\n" + failed_files+=("$filename") + fi +done + +rm -rf "$TEMP_DIR" + +echo -e "\n${BLUE}${BOLD}=== FINAL REPORT ===${NC}" + +if [ ${#passed_files[@]} -gt 0 ]; then + echo -e "\n${GREEN}${BOLD}Passed Tests (${#passed_files[@]}) :${NC}" + for f in "${passed_files[@]}"; do + echo -e " ${GREEN}✔ $f${NC}" + done +fi + +if [ ${#failed_files[@]} -gt 0 ]; then + echo -e "\n${RED}${BOLD}Failed Tests (${#failed_files[@]}) :${NC}" + for f in "${failed_files[@]}"; do + echo -e " ${RED}✘ $f${NC}" + done + echo -e "\n${RED}➔ Result: FAILURE${NC}" + exit 1 +else + echo -e "\n${GREEN}➔ Result: SUCCESS${NC}" + exit 0 +fi \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/basic-test-file-3.js b/recipes/tls-securepair-to-tlssocket/tests/expected/basic-test-file-3.js new file mode 100644 index 00000000..d8c80c4f --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/basic-test-file-3.js @@ -0,0 +1,11 @@ +const tls = require('node:tls'); +const fs = require('fs'); // Code non lié + +function createSecureConnection() { + // Using tls.SecurePair constructor + const socket = new tls.TLSSocket(socket); + + // Ces lignes doivent disparaître + + return socket; +} \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/file-1.js b/recipes/tls-securepair-to-tlssocket/tests/expected/file-1.js new file mode 100644 index 00000000..cea1840a --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/file-1.js @@ -0,0 +1,8 @@ +const tls = require('node:tls'); + +// Using tls.SecurePair constructor +const socket = new tls.TLSSocket(socket); + +// Direct import +const { TLSSocket } = require('node:tls'); +const socket2 = new TLSSocket(socket); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/file-2.js b/recipes/tls-securepair-to-tlssocket/tests/expected/file-2.js new file mode 100644 index 00000000..ef8d2b1f --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/file-2.js @@ -0,0 +1,8 @@ +import tls from 'node:tls'; + +// Using tls.SecurePair constructor +const socket = new tls.TLSSocket(socket); + +// Direct import +import { TLSSocket } from 'node:tls'; +const socket2 = new TLSSocket(socket); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js new file mode 100644 index 00000000..eddfdf8a --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js @@ -0,0 +1,10 @@ +const { TLSSocket } = require('node:tls'); +const { unrelated } = require('other-module'); + +const socket = new TLSSocket(socket); + +socket.on('error', (err) => { + console.error(err); +}); + +// Propriétés obsolètes \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js new file mode 100644 index 00000000..63587943 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js @@ -0,0 +1,7 @@ +const { TLSSocket } = require('node:tls'); + +// Nom de variable totalement arbitraire +const socket = new TLSSocket(socket); + +// Usage +socket.doSomething(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js new file mode 100644 index 00000000..265a0f37 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js @@ -0,0 +1,8 @@ +import tls from 'node:tls'; +import { TLSSocket } from 'node:tls'; + +// Cas 1 : Via namespace +const socket1 = new tls.TLSSocket(socket); + +// Cas 2 : Direct +const socket2 = new TLSSocket(socket); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js new file mode 100644 index 00000000..bdbaf28c --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js @@ -0,0 +1,7 @@ +const tls = require('node:tls'); + +const socket = new tls.TLSSocket(socket); +const mySocket = new tls.TLSSocket(socket); +const secureSocketInstance = new tls.TLSSocket(socket); + +// Nettoyage spécifique à chaque variable \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-scoping-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-scoping-file.js new file mode 100644 index 00000000..433ca37d --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/test-scoping-file.js @@ -0,0 +1,14 @@ +const tls = require('node:tls'); + +class ConnectionManager { + constructor() { + if (true) { + const socket = new tls.TLSSocket(socket); + this.init(socket); + + if (socket.cleartext) { + console.log("cleaning"); + } + } + } +} \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/basic-test-file-3.js b/recipes/tls-securepair-to-tlssocket/tests/input/basic-test-file-3.js new file mode 100644 index 00000000..a17b4487 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/input/basic-test-file-3.js @@ -0,0 +1,13 @@ +const tls = require('node:tls'); +const fs = require('fs'); // Code non lié + +function createSecureConnection() { + // Using tls.SecurePair constructor + const pair = new tls.SecurePair(); + + // Ces lignes doivent disparaître + const cleartext = pair.cleartext; + const encrypted = pair.encrypted; + + return pair; +} \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/file-1.js b/recipes/tls-securepair-to-tlssocket/tests/input/file-1.js new file mode 100644 index 00000000..9ce8efdd --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/input/file-1.js @@ -0,0 +1,10 @@ +const tls = require('node:tls'); + +// Using tls.SecurePair constructor +const pair = new tls.SecurePair(); +const cleartext = pair.cleartext; +const encrypted = pair.encrypted; + +// Direct import +const { SecurePair } = require('node:tls'); +const pair2 = new SecurePair(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/file-2.js b/recipes/tls-securepair-to-tlssocket/tests/input/file-2.js new file mode 100644 index 00000000..fe8c30bc --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/input/file-2.js @@ -0,0 +1,10 @@ +import tls from 'node:tls'; + +// Using tls.SecurePair constructor +const pair = new tls.SecurePair(); +const cleartext = pair.cleartext; +const encrypted = pair.encrypted; + +// Direct import +import { SecurePair } from 'node:tls'; +const pair2 = new SecurePair(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/test-crucial-file.js b/recipes/tls-securepair-to-tlssocket/tests/input/test-crucial-file.js new file mode 100644 index 00000000..b65c52f9 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/input/test-crucial-file.js @@ -0,0 +1,12 @@ +const { SecurePair } = require('node:tls'); +const { unrelated } = require('other-module'); + +const pair = new SecurePair(); + +pair.on('error', (err) => { + console.error(err); +}); + +// Propriétés obsolètes +console.log(pair.cleartext); +console.log(pair.encrypted); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/test-edge-variable-name-file.js b/recipes/tls-securepair-to-tlssocket/tests/input/test-edge-variable-name-file.js new file mode 100644 index 00000000..7909d188 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/input/test-edge-variable-name-file.js @@ -0,0 +1,8 @@ +const { SecurePair } = require('node:tls'); + +// Nom de variable totalement arbitraire +const item = new SecurePair(); + +// Usage +item.doSomething(); +item.cleartext.read(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/test-esm-file.js b/recipes/tls-securepair-to-tlssocket/tests/input/test-esm-file.js new file mode 100644 index 00000000..058f003d --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/input/test-esm-file.js @@ -0,0 +1,10 @@ +import tls from 'node:tls'; +import { SecurePair } from 'node:tls'; + +// Cas 1 : Via namespace +const pair1 = new tls.SecurePair(); +const t1 = pair1.cleartext; + +// Cas 2 : Direct +const pair2 = new SecurePair(); +const t2 = pair2.encrypted; \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/test-multiple-variable-file.js b/recipes/tls-securepair-to-tlssocket/tests/input/test-multiple-variable-file.js new file mode 100644 index 00000000..2fb7e5dd --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/input/test-multiple-variable-file.js @@ -0,0 +1,9 @@ +const tls = require('node:tls'); + +const pair = new tls.SecurePair(); +const myPair = new tls.SecurePair(); +const securePairInstance = new tls.SecurePair(); + +// Nettoyage spécifique à chaque variable +pair.cleartext.write('hello'); +myPair.encrypted.write('world'); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/test-scoping-file.js b/recipes/tls-securepair-to-tlssocket/tests/input/test-scoping-file.js new file mode 100644 index 00000000..ded038b5 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/input/test-scoping-file.js @@ -0,0 +1,14 @@ +const tls = require('node:tls'); + +class ConnectionManager { + constructor() { + if (true) { + const pair = new tls.SecurePair(); + this.init(pair); + + if (pair.cleartext) { + console.log("cleaning"); + } + } + } +} \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/workflow.yaml b/recipes/tls-securepair-to-tlssocket/workflow.yaml new file mode 100644 index 00000000..6b7a4d32 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/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 deprecation: migrate `tls.SecurePair` to `tls.TLSSocket`." + js-ast-grep: + js_file: src/workflow.ts + base_path: . + include: + - "**/*.cjs" + - "**/*.js" + - "**/*.jsx" + - "**/*.mjs" + - "**/*.cts" + - "**/*.mts" + - "**/*.ts" + - "**/*.tsx" + exclude: + - "**/node_modules/**" + language: typescript From 3e43dea1644882e5a02394593460d45d60f8a980 Mon Sep 17 00:00:00 2001 From: Maxime Devillet Date: Fri, 5 Dec 2025 11:18:18 +0100 Subject: [PATCH 03/27] recipes(tls): add tls-securepair-to-tlssocket codemod --- .../README.md | 0 .../codemod.yaml | 21 --- .../package.json | 15 -- .../src/workflow.ts | 132 ------------------ .../test.sh | 74 ---------- .../tests/expected/file-1.js | 8 -- .../tests/expected/file-2.js | 8 -- .../tests/expected/test-crucial-file.js | 10 -- .../expected/test-edge-variable-name-file.js | 7 - .../tests/expected/test-esm-file.js | 8 -- .../expected/test-multiple-variable-file.js | 7 - .../tests/expected/test-scoping-file.js | 14 -- .../tests/input/basic-test-file-3.js | 0 .../tests/input/file-1.js | 10 -- .../tests/input/file-2.js | 10 -- .../tests/input/test-crucial-file.js | 12 -- .../input/test-edge-variable-name-file.js | 8 -- .../tests/input/test-esm-file.js | 10 -- .../input/test-multiple-variable-file.js | 9 -- .../tests/input/test-scoping-file.js | 14 -- .../workflow.yaml | 25 ---- 21 files changed, 402 deletions(-) delete mode 100644 recipes/tls-securepair-to-tlssocket_working/README.md delete mode 100644 recipes/tls-securepair-to-tlssocket_working/codemod.yaml delete mode 100644 recipes/tls-securepair-to-tlssocket_working/package.json delete mode 100644 recipes/tls-securepair-to-tlssocket_working/src/workflow.ts delete mode 100755 recipes/tls-securepair-to-tlssocket_working/test.sh delete mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/expected/file-1.js delete mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/expected/file-2.js delete mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/expected/test-crucial-file.js delete mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/expected/test-edge-variable-name-file.js delete mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/expected/test-esm-file.js delete mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/expected/test-multiple-variable-file.js delete mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/expected/test-scoping-file.js delete mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/input/basic-test-file-3.js delete mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/input/file-1.js delete mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/input/file-2.js delete mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/input/test-crucial-file.js delete mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/input/test-edge-variable-name-file.js delete mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/input/test-esm-file.js delete mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/input/test-multiple-variable-file.js delete mode 100644 recipes/tls-securepair-to-tlssocket_working/tests/input/test-scoping-file.js delete mode 100644 recipes/tls-securepair-to-tlssocket_working/workflow.yaml diff --git a/recipes/tls-securepair-to-tlssocket_working/README.md b/recipes/tls-securepair-to-tlssocket_working/README.md deleted file mode 100644 index e69de29b..00000000 diff --git a/recipes/tls-securepair-to-tlssocket_working/codemod.yaml b/recipes/tls-securepair-to-tlssocket_working/codemod.yaml deleted file mode 100644 index 400f1571..00000000 --- a/recipes/tls-securepair-to-tlssocket_working/codemod.yaml +++ /dev/null @@ -1,21 +0,0 @@ -schema_version: "1.0" -name: "@nodejs/tmpDir-to-tmpdir" -version: "1.0.0" -description: Handle DEP0022 via transforming `tmpDir` to `tmpdir`. -author: nekojanai (Jana) -license: MIT -workflow: workflow.yaml -category: migration - -targets: - languages: - - javascript - - typescript - -keywords: - - transformation - - migration - -registry: - access: public - visibility: public \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/package.json b/recipes/tls-securepair-to-tlssocket_working/package.json deleted file mode 100644 index e9518931..00000000 --- a/recipes/tls-securepair-to-tlssocket_working/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "@nodejs/tls-securepair-to-tlssocket_working-codemod", - "version": "1.0.1", - "description": "", - "type": "module", - "author": "Maxime Devillet", - "license": "MIT", - "devDependencies": { - "@codemod.com/jssg-types": "^1.0.9" - }, - "dependencies": { - "@ast-grep/napi": "^0.40.0", - "@nodejs/codemod-utils": "*" - } -} diff --git a/recipes/tls-securepair-to-tlssocket_working/src/workflow.ts b/recipes/tls-securepair-to-tlssocket_working/src/workflow.ts deleted file mode 100644 index 802783d7..00000000 --- a/recipes/tls-securepair-to-tlssocket_working/src/workflow.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { removeLines } from "@nodejs/codemod-utils/ast-grep/remove-lines"; -import type { Edit, SgRoot, Range } from "@codemod.com/jssg-types/main"; -import type Js from "@codemod.com/jssg-types/langs/javascript"; - -function getClosest(node: any, kinds: string[]): any | null { - let current = node.parent(); - while (current) { - if (kinds.includes(current.kind())) { - return current; - } - current = current.parent(); - } - return null; -} - -export default function transform(root: SgRoot): string | null { - const rootNode = root.root(); - const edits: Edit[] = []; - const linesToRemove: Range[] = []; - - const importNodes = rootNode.findAll({ - rule: { - any: [ - { kind: "import_specifier", has: { kind: "identifier", regex: "^SecurePair$" } }, - { kind: "shorthand_property_identifier_pattern", regex: "^SecurePair$" }, - { kind: "property_identifier", regex: "^SecurePair$" } - ] - } - }); - - for (const node of importNodes) { - if (node.text() === "SecurePair") { - edits.push(node.replace("TLSSocket")); - } - } - - const newExpressions = rootNode.findAll({ - rule: { - kind: "new_expression", - has: { - any: [ - { kind: "member_expression", has: { field: "property", regex: "^SecurePair$" } }, - { kind: "identifier", regex: "^SecurePair$" } - ] - } - } - }); - - for (const node of newExpressions) { - const callee = node.field("constructor"); - if (!callee) continue; - - let newConstructorName = "TLSSocket"; - if (callee.kind() === "member_expression") { - const object = callee.field("object"); - if (object) { - newConstructorName = `${object.text()}.TLSSocket`; - } - } - - edits.push(node.replace(`new ${newConstructorName}(socket)`)); - - const declarator = getClosest(node, ["variable_declarator"]); - if (declarator) { - const idNode = declarator.field("name"); - if (idNode) { - const oldName = idNode.text(); - - let newName = "socket"; - if (oldName !== "pair" && oldName !== "SecurePair") { - if (oldName.includes("Pair")) { - newName = oldName.replace("Pair", "Socket"); - } - else if (oldName.includes("pair")) { - newName = oldName.replace("pair", "socket"); - } - else { - newName = "socket"; - } - } - - const obsoleteUsages = rootNode.findAll({ - rule: { - kind: "member_expression", - all: [ - { has: { field: "object", regex: `^${oldName}$` } }, - { has: { field: "property", regex: "^(cleartext|encrypted)$" } } - ] - } - }); - - for (const usage of obsoleteUsages) { - const statement = getClosest(usage, ["lexical_declaration", "expression_statement"]); - if (statement) { - linesToRemove.push(statement.range()); - } - } - - edits.push(idNode.replace(newName)); - - const references = rootNode.findAll({ - rule: { - kind: "identifier", - regex: `^${oldName}$` - } - }); - - for (const ref of references) { - const parent = ref.parent(); - if (parent && parent.kind() === 'member_expression') { - const property = parent.field('property'); - if (property && property.id() === ref.id()) { - continue; - } - } - - if (parent && (parent.kind() === 'import_specifier' || parent.kind() === 'shorthand_property_identifier_pattern')) { - continue; - } - - if (ref.id() === idNode.id()) continue; - - edits.push(ref.replace(newName)); - } - } - } - } - - let sourceCode = rootNode.commitEdits(edits); - sourceCode = removeLines(sourceCode, linesToRemove); - return sourceCode; -} \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/test.sh b/recipes/tls-securepair-to-tlssocket_working/test.sh deleted file mode 100755 index 132c0460..00000000 --- a/recipes/tls-securepair-to-tlssocket_working/test.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/bin/bash - -GREEN='\033[0;32m' -RED='\033[0;31m' -BLUE='\033[0;34m' -YELLOW='\033[1;33m' -BOLD='\033[1m' -NC='\033[0m' - -INPUT_DIR="tests/input" -EXPECTED_DIR="tests/expected" -TEMP_DIR="tests/temp_workzone" - -declare -a passed_files -declare -a failed_files - -echo -e "${BLUE}${BOLD}=== Starting Codemod Test Suite ===${NC}" - -rm -rf "$TEMP_DIR" -mkdir -p "$TEMP_DIR" -cp -r "$INPUT_DIR"/* "$TEMP_DIR" - -echo -e "➜ Running codemod on temporary files..." -npx codemod workflow run -w workflow.yaml -t "$TEMP_DIR" > /dev/null 2>&1 - -echo -e "➜ Verifying results...\n" - -for expected_file in "$EXPECTED_DIR"/*; do - filename=$(basename "$expected_file") - generated_file="$TEMP_DIR/$filename" - - if [ ! -f "$generated_file" ]; then - echo -e "${RED} [MISSING] $filename${NC}" - failed_files+=("$filename (Missing)") - continue - fi - - diff_output=$(diff -u --color=always "$expected_file" "$generated_file") - exit_code=$? - - if [ $exit_code -eq 0 ]; then - echo -e " ${GREEN}✔ $filename${NC}" - passed_files+=("$filename") - else - echo -e " ${RED}✘ $filename${NC}" - echo -e "${YELLOW}--- Differences for $filename ---${NC}" - echo "$diff_output" - echo -e "${YELLOW}----------------------------------${NC}\n" - failed_files+=("$filename") - fi -done - -rm -rf "$TEMP_DIR" - -echo -e "\n${BLUE}${BOLD}=== FINAL REPORT ===${NC}" - -if [ ${#passed_files[@]} -gt 0 ]; then - echo -e "\n${GREEN}${BOLD}Passed Tests (${#passed_files[@]}) :${NC}" - for f in "${passed_files[@]}"; do - echo -e " ${GREEN}✔ $f${NC}" - done -fi - -if [ ${#failed_files[@]} -gt 0 ]; then - echo -e "\n${RED}${BOLD}Failed Tests (${#failed_files[@]}) :${NC}" - for f in "${failed_files[@]}"; do - echo -e " ${RED}✘ $f${NC}" - done - echo -e "\n${RED}➔ Result: FAILURE${NC}" - exit 1 -else - echo -e "\n${GREEN}➔ Result: SUCCESS${NC}" - exit 0 -fi \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/expected/file-1.js b/recipes/tls-securepair-to-tlssocket_working/tests/expected/file-1.js deleted file mode 100644 index cea1840a..00000000 --- a/recipes/tls-securepair-to-tlssocket_working/tests/expected/file-1.js +++ /dev/null @@ -1,8 +0,0 @@ -const tls = require('node:tls'); - -// Using tls.SecurePair constructor -const socket = new tls.TLSSocket(socket); - -// Direct import -const { TLSSocket } = require('node:tls'); -const socket2 = new TLSSocket(socket); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/expected/file-2.js b/recipes/tls-securepair-to-tlssocket_working/tests/expected/file-2.js deleted file mode 100644 index ef8d2b1f..00000000 --- a/recipes/tls-securepair-to-tlssocket_working/tests/expected/file-2.js +++ /dev/null @@ -1,8 +0,0 @@ -import tls from 'node:tls'; - -// Using tls.SecurePair constructor -const socket = new tls.TLSSocket(socket); - -// Direct import -import { TLSSocket } from 'node:tls'; -const socket2 = new TLSSocket(socket); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-crucial-file.js b/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-crucial-file.js deleted file mode 100644 index eddfdf8a..00000000 --- a/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-crucial-file.js +++ /dev/null @@ -1,10 +0,0 @@ -const { TLSSocket } = require('node:tls'); -const { unrelated } = require('other-module'); - -const socket = new TLSSocket(socket); - -socket.on('error', (err) => { - console.error(err); -}); - -// Propriétés obsolètes \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-edge-variable-name-file.js b/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-edge-variable-name-file.js deleted file mode 100644 index 63587943..00000000 --- a/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-edge-variable-name-file.js +++ /dev/null @@ -1,7 +0,0 @@ -const { TLSSocket } = require('node:tls'); - -// Nom de variable totalement arbitraire -const socket = new TLSSocket(socket); - -// Usage -socket.doSomething(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-esm-file.js b/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-esm-file.js deleted file mode 100644 index 265a0f37..00000000 --- a/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-esm-file.js +++ /dev/null @@ -1,8 +0,0 @@ -import tls from 'node:tls'; -import { TLSSocket } from 'node:tls'; - -// Cas 1 : Via namespace -const socket1 = new tls.TLSSocket(socket); - -// Cas 2 : Direct -const socket2 = new TLSSocket(socket); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-multiple-variable-file.js b/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-multiple-variable-file.js deleted file mode 100644 index bdbaf28c..00000000 --- a/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-multiple-variable-file.js +++ /dev/null @@ -1,7 +0,0 @@ -const tls = require('node:tls'); - -const socket = new tls.TLSSocket(socket); -const mySocket = new tls.TLSSocket(socket); -const secureSocketInstance = new tls.TLSSocket(socket); - -// Nettoyage spécifique à chaque variable \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-scoping-file.js b/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-scoping-file.js deleted file mode 100644 index 433ca37d..00000000 --- a/recipes/tls-securepair-to-tlssocket_working/tests/expected/test-scoping-file.js +++ /dev/null @@ -1,14 +0,0 @@ -const tls = require('node:tls'); - -class ConnectionManager { - constructor() { - if (true) { - const socket = new tls.TLSSocket(socket); - this.init(socket); - - if (socket.cleartext) { - console.log("cleaning"); - } - } - } -} \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/input/basic-test-file-3.js b/recipes/tls-securepair-to-tlssocket_working/tests/input/basic-test-file-3.js deleted file mode 100644 index e69de29b..00000000 diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/input/file-1.js b/recipes/tls-securepair-to-tlssocket_working/tests/input/file-1.js deleted file mode 100644 index 9ce8efdd..00000000 --- a/recipes/tls-securepair-to-tlssocket_working/tests/input/file-1.js +++ /dev/null @@ -1,10 +0,0 @@ -const tls = require('node:tls'); - -// Using tls.SecurePair constructor -const pair = new tls.SecurePair(); -const cleartext = pair.cleartext; -const encrypted = pair.encrypted; - -// Direct import -const { SecurePair } = require('node:tls'); -const pair2 = new SecurePair(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/input/file-2.js b/recipes/tls-securepair-to-tlssocket_working/tests/input/file-2.js deleted file mode 100644 index fe8c30bc..00000000 --- a/recipes/tls-securepair-to-tlssocket_working/tests/input/file-2.js +++ /dev/null @@ -1,10 +0,0 @@ -import tls from 'node:tls'; - -// Using tls.SecurePair constructor -const pair = new tls.SecurePair(); -const cleartext = pair.cleartext; -const encrypted = pair.encrypted; - -// Direct import -import { SecurePair } from 'node:tls'; -const pair2 = new SecurePair(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/input/test-crucial-file.js b/recipes/tls-securepair-to-tlssocket_working/tests/input/test-crucial-file.js deleted file mode 100644 index b65c52f9..00000000 --- a/recipes/tls-securepair-to-tlssocket_working/tests/input/test-crucial-file.js +++ /dev/null @@ -1,12 +0,0 @@ -const { SecurePair } = require('node:tls'); -const { unrelated } = require('other-module'); - -const pair = new SecurePair(); - -pair.on('error', (err) => { - console.error(err); -}); - -// Propriétés obsolètes -console.log(pair.cleartext); -console.log(pair.encrypted); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/input/test-edge-variable-name-file.js b/recipes/tls-securepair-to-tlssocket_working/tests/input/test-edge-variable-name-file.js deleted file mode 100644 index 7909d188..00000000 --- a/recipes/tls-securepair-to-tlssocket_working/tests/input/test-edge-variable-name-file.js +++ /dev/null @@ -1,8 +0,0 @@ -const { SecurePair } = require('node:tls'); - -// Nom de variable totalement arbitraire -const item = new SecurePair(); - -// Usage -item.doSomething(); -item.cleartext.read(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/input/test-esm-file.js b/recipes/tls-securepair-to-tlssocket_working/tests/input/test-esm-file.js deleted file mode 100644 index 058f003d..00000000 --- a/recipes/tls-securepair-to-tlssocket_working/tests/input/test-esm-file.js +++ /dev/null @@ -1,10 +0,0 @@ -import tls from 'node:tls'; -import { SecurePair } from 'node:tls'; - -// Cas 1 : Via namespace -const pair1 = new tls.SecurePair(); -const t1 = pair1.cleartext; - -// Cas 2 : Direct -const pair2 = new SecurePair(); -const t2 = pair2.encrypted; \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/input/test-multiple-variable-file.js b/recipes/tls-securepair-to-tlssocket_working/tests/input/test-multiple-variable-file.js deleted file mode 100644 index 2fb7e5dd..00000000 --- a/recipes/tls-securepair-to-tlssocket_working/tests/input/test-multiple-variable-file.js +++ /dev/null @@ -1,9 +0,0 @@ -const tls = require('node:tls'); - -const pair = new tls.SecurePair(); -const myPair = new tls.SecurePair(); -const securePairInstance = new tls.SecurePair(); - -// Nettoyage spécifique à chaque variable -pair.cleartext.write('hello'); -myPair.encrypted.write('world'); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/tests/input/test-scoping-file.js b/recipes/tls-securepair-to-tlssocket_working/tests/input/test-scoping-file.js deleted file mode 100644 index ded038b5..00000000 --- a/recipes/tls-securepair-to-tlssocket_working/tests/input/test-scoping-file.js +++ /dev/null @@ -1,14 +0,0 @@ -const tls = require('node:tls'); - -class ConnectionManager { - constructor() { - if (true) { - const pair = new tls.SecurePair(); - this.init(pair); - - if (pair.cleartext) { - console.log("cleaning"); - } - } - } -} \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket_working/workflow.yaml b/recipes/tls-securepair-to-tlssocket_working/workflow.yaml deleted file mode 100644 index 611eea71..00000000 --- a/recipes/tls-securepair-to-tlssocket_working/workflow.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# 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: name-test`. - js-ast-grep: - js_file: src/workflow.ts - base_path: . - include: - - "**/*.cjs" - - "**/*.js" - - "**/*.jsx" - - "**/*.mjs" - - "**/*.cts" - - "**/*.mts" - - "**/*.ts" - - "**/*.tsx" - exclude: - - "**/node_modules/**" - language: typescript From 3e78f7b2c2d185089e73f941e3de9a73ce0fb4e2 Mon Sep 17 00:00:00 2001 From: Maxime Devillet Date: Fri, 5 Dec 2025 20:11:38 +0100 Subject: [PATCH 04/27] chore: update package-lock.json --- package-lock.json | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index c88b3c6a..609092f5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -197,7 +197,6 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@ast-grep/napi/-/napi-0.40.0.tgz", "integrity": "sha512-tq6nO/8KwUF/mHuk1ECaAOSOlz2OB/PmygnvprJzyAHGRVzdcffblaOOWe90M9sGz5MAasXoF+PTcayQj9TKKA==", - "dev": true, "license": "MIT", "engines": { "node": ">= 10" @@ -221,7 +220,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -238,7 +236,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -255,7 +252,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -272,7 +268,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -289,7 +284,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -306,7 +300,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -323,7 +316,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -340,7 +332,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -357,7 +348,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -402,7 +392,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", @@ -1540,6 +1529,10 @@ "resolved": "recipes/slow-buffer-to-buffer-alloc-unsafe-slow", "link": true }, + "node_modules/@nodejs/tls-securepair-to-tlssocket": { + "resolved": "recipes/tls-securepair-to-tlssocket", + "link": true + }, "node_modules/@nodejs/tmpdir-to-tmpdir": { "resolved": "recipes/tmpdir-to-tmpdir", "link": true @@ -1578,7 +1571,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", @@ -1776,7 +1768,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" } @@ -2095,7 +2086,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.19", "caniuse-lite": "^1.0.30001751", @@ -4436,6 +4426,18 @@ "@codemod.com/jssg-types": "^1.3.0" } }, + "recipes/tls-securepair-to-tlssocket": { + "name": "@nodejs/tls-securepair-to-tlssocket", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@ast-grep/napi": "^0.40.0", + "@nodejs/codemod-utils": "*" + }, + "devDependencies": { + "@codemod.com/jssg-types": "^1.0.9" + } + }, "recipes/tmpdir-to-tmpdir": { "name": "@nodejs/tmpdir-to-tmpdir", "version": "1.0.0", From 2a069ed87974d04850e3e2dbde7d8ee9095fed0a Mon Sep 17 00:00:00 2001 From: menace31 <54880433+menace31@users.noreply.github.com> Date: Wed, 10 Dec 2025 11:16:39 +0100 Subject: [PATCH 05/27] Update recipes/tls-securepair-to-tlssocket/README.md Co-authored-by: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> --- recipes/tls-securepair-to-tlssocket/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/recipes/tls-securepair-to-tlssocket/README.md b/recipes/tls-securepair-to-tlssocket/README.md index 9e6d4220..c23640ef 100644 --- a/recipes/tls-securepair-to-tlssocket/README.md +++ b/recipes/tls-securepair-to-tlssocket/README.md @@ -87,6 +87,7 @@ const mySocket = new TLSSocket(socket); The tls.TLSSocket constructor requires an existing socket instance (net.Socket) as an argument. This codemod automatically inserts socket as the argument: JavaScript +```js ``` new TLSSocket(socket) ``` From 52de2087a90b5eb2b71607033afc76afb46b2ae6 Mon Sep 17 00:00:00 2001 From: menace31 <54880433+menace31@users.noreply.github.com> Date: Wed, 10 Dec 2025 11:17:06 +0100 Subject: [PATCH 06/27] Update recipes/tls-securepair-to-tlssocket/README.md Co-authored-by: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> --- recipes/tls-securepair-to-tlssocket/README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/recipes/tls-securepair-to-tlssocket/README.md b/recipes/tls-securepair-to-tlssocket/README.md index c23640ef..5110fa87 100644 --- a/recipes/tls-securepair-to-tlssocket/README.md +++ b/recipes/tls-securepair-to-tlssocket/README.md @@ -93,7 +93,3 @@ new TLSSocket(socket) ``` You must ensure that a variable named socket exists in the scope or rename it to match your existing socket variable (e.g., clientSocket, stream, etc.). - -## Test - -The test.sh script runs all the tests located in the tests folder. All input files are temporarily copied to a new folder and compared against their expected results found in the expected folder. This helps identify which tests failed and why. Feel free to add new tests if necessary. \ No newline at end of file From b12b649371eddadf3f07d03ccc504654e884ec42 Mon Sep 17 00:00:00 2001 From: menace31 <54880433+menace31@users.noreply.github.com> Date: Wed, 10 Dec 2025 11:17:40 +0100 Subject: [PATCH 07/27] Update recipes/tls-securepair-to-tlssocket/src/workflow.ts Co-authored-by: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> --- recipes/tls-securepair-to-tlssocket/src/workflow.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/recipes/tls-securepair-to-tlssocket/src/workflow.ts b/recipes/tls-securepair-to-tlssocket/src/workflow.ts index 802783d7..076965ef 100644 --- a/recipes/tls-securepair-to-tlssocket/src/workflow.ts +++ b/recipes/tls-securepair-to-tlssocket/src/workflow.ts @@ -4,12 +4,14 @@ import type Js from "@codemod.com/jssg-types/langs/javascript"; function getClosest(node: any, kinds: string[]): any | null { let current = node.parent(); + while (current) { if (kinds.includes(current.kind())) { return current; } current = current.parent(); } + return null; } From fe681b96d778d3dbc4f26207e68a48828e718b55 Mon Sep 17 00:00:00 2001 From: menace31 <54880433+menace31@users.noreply.github.com> Date: Wed, 10 Dec 2025 11:18:06 +0100 Subject: [PATCH 08/27] Update recipes/tls-securepair-to-tlssocket/src/workflow.ts Co-authored-by: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> --- recipes/tls-securepair-to-tlssocket/src/workflow.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/recipes/tls-securepair-to-tlssocket/src/workflow.ts b/recipes/tls-securepair-to-tlssocket/src/workflow.ts index 076965ef..dc351c29 100644 --- a/recipes/tls-securepair-to-tlssocket/src/workflow.ts +++ b/recipes/tls-securepair-to-tlssocket/src/workflow.ts @@ -128,7 +128,7 @@ export default function transform(root: SgRoot): string | null { } } - let sourceCode = rootNode.commitEdits(edits); - sourceCode = removeLines(sourceCode, linesToRemove); - return sourceCode; + const sourceCode = rootNode.commitEdits(edits); + + return removeLines(sourceCode, linesToRemove); } \ No newline at end of file From 153faf9606e2e15104f453efbc767fd0c66d09e6 Mon Sep 17 00:00:00 2001 From: Maxime Devillet Date: Wed, 10 Dec 2025 19:39:34 +0100 Subject: [PATCH 09/27] use nodejs mod-utils and remove test.sh --- recipes/tls-securepair-to-tlssocket/README.md | 8 +- .../tls-securepair-to-tlssocket/package.json | 2 +- .../src/workflow.ts | 109 ++++++++---------- recipes/tls-securepair-to-tlssocket/test.sh | 74 ------------ 4 files changed, 54 insertions(+), 139 deletions(-) delete mode 100755 recipes/tls-securepair-to-tlssocket/test.sh diff --git a/recipes/tls-securepair-to-tlssocket/README.md b/recipes/tls-securepair-to-tlssocket/README.md index 9e6d4220..43ab5fd6 100644 --- a/recipes/tls-securepair-to-tlssocket/README.md +++ b/recipes/tls-securepair-to-tlssocket/README.md @@ -95,4 +95,10 @@ You must ensure that a variable named socket exists in the scope or rename it to ## Test -The test.sh script runs all the tests located in the tests folder. All input files are temporarily copied to a new folder and compared against their expected results found in the expected folder. This helps identify which tests failed and why. Feel free to add new tests if necessary. \ No newline at end of file +To run the tests, use the codemod test command: + +``` +npx codemod jssg test -l typescript ./src/workflow.ts ./ +``` + +All input files in `tests/input` are compared against their expected results in `tests/expected`. Feel free to add new tests if necessary. \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/package.json b/recipes/tls-securepair-to-tlssocket/package.json index f36b48e8..cb68fab9 100644 --- a/recipes/tls-securepair-to-tlssocket/package.json +++ b/recipes/tls-securepair-to-tlssocket/package.json @@ -9,7 +9,7 @@ "repository": { "type": "git", "url": "git+https://github.com/nodejs/userland-migrations.git", - "directory": "recipes/tls-securepair-to-tlssocket", + "directory": "recipes/tls-securepair-to-tlssocket", "bugs": "https://github.com/nodejs/userland-migrations/issues" }, "author": "Maxime Devillet", diff --git a/recipes/tls-securepair-to-tlssocket/src/workflow.ts b/recipes/tls-securepair-to-tlssocket/src/workflow.ts index 802783d7..209b00ec 100644 --- a/recipes/tls-securepair-to-tlssocket/src/workflow.ts +++ b/recipes/tls-securepair-to-tlssocket/src/workflow.ts @@ -1,13 +1,17 @@ + +import { getNodeImportStatements } 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 { updateBinding } from "@nodejs/codemod-utils/ast-grep/update-binding"; import { removeLines } from "@nodejs/codemod-utils/ast-grep/remove-lines"; -import type { Edit, SgRoot, Range } from "@codemod.com/jssg-types/main"; +import type { Edit, SgRoot, Range, SgNode } from "@codemod.com/jssg-types/main"; import type Js from "@codemod.com/jssg-types/langs/javascript"; -function getClosest(node: any, kinds: string[]): any | null { +// Utility: get closest ancestor of a node of a given kind +function getClosest(node: SgNode, kinds: string[]): SgNode | null { let current = node.parent(); while (current) { - if (kinds.includes(current.kind())) { - return current; - } + if (kinds.includes(current.kind())) return current; current = current.parent(); } return null; @@ -18,20 +22,16 @@ export default function transform(root: SgRoot): string | null { const edits: Edit[] = []; const linesToRemove: Range[] = []; - const importNodes = rootNode.findAll({ - rule: { - any: [ - { kind: "import_specifier", has: { kind: "identifier", regex: "^SecurePair$" } }, - { kind: "shorthand_property_identifier_pattern", regex: "^SecurePair$" }, - { kind: "property_identifier", regex: "^SecurePair$" } - ] - } - }); - + // Replace SecurePair in imports/requires using codemod-utils + const importNodes = [ + ...getNodeImportStatements(root, "tls"), + ...getNodeRequireCalls(root, "tls") + ]; for (const node of importNodes) { - if (node.text() === "SecurePair") { - edits.push(node.replace("TLSSocket")); - } + // Replace destructured { SecurePair } with { TLSSocket } + const change = updateBinding(node, { old: "SecurePair", new: "TLSSocket" }); + if (change?.edit) edits.push(change.edit); + if (change?.lineToRemove) linesToRemove.push(change.lineToRemove); } const newExpressions = rootNode.findAll({ @@ -39,8 +39,8 @@ export default function transform(root: SgRoot): string | null { kind: "new_expression", has: { any: [ - { kind: "member_expression", has: { field: "property", regex: "^SecurePair$" } }, - { kind: "identifier", regex: "^SecurePair$" } + { kind: "member_expression", has: { field: "property", regex: "^SecurePair$" } }, + { kind: "identifier", regex: "^SecurePair$" } ] } } @@ -57,76 +57,59 @@ export default function transform(root: SgRoot): string | null { newConstructorName = `${object.text()}.TLSSocket`; } } - + edits.push(node.replace(`new ${newConstructorName}(socket)`)); + // Find the variable declarator for the new SecurePair const declarator = getClosest(node, ["variable_declarator"]); if (declarator) { const idNode = declarator.field("name"); if (idNode) { const oldName = idNode.text(); - let newName = "socket"; if (oldName !== "pair" && oldName !== "SecurePair") { - if (oldName.includes("Pair")) { - newName = oldName.replace("Pair", "Socket"); - } - else if (oldName.includes("pair")) { - newName = oldName.replace("pair", "socket"); - } - else { - newName = "socket"; - } + if (oldName.includes("Pair")) newName = oldName.replace("Pair", "Socket"); + else if (oldName.includes("pair")) newName = oldName.replace("pair", "socket"); } + // Remove usages like pair.cleartext or pair.encrypted const obsoleteUsages = rootNode.findAll({ - rule: { - kind: "member_expression", - all: [ - { has: { field: "object", regex: `^${oldName}$` } }, - { has: { field: "property", regex: "^(cleartext|encrypted)$" } } - ] - } + rule: { + kind: "member_expression", + all: [ + { has: { field: "object", regex: `^${oldName}$` } }, + { has: { field: "property", regex: "^(cleartext|encrypted)$" } } + ] + } }); - for (const usage of obsoleteUsages) { - const statement = getClosest(usage, ["lexical_declaration", "expression_statement"]); - if (statement) { - linesToRemove.push(statement.range()); - } + // Remove the whole statement, and also comments/blank lines above + let statement = getClosest(usage, ["lexical_declaration", "expression_statement"]); + if (statement) linesToRemove.push(statement.range()); } edits.push(idNode.replace(newName)); + // Replace all other references to the old variable name const references = rootNode.findAll({ - rule: { - kind: "identifier", - regex: `^${oldName}$` - } + rule: { kind: "identifier", regex: `^${oldName}$` } }); - for (const ref of references) { - const parent = ref.parent(); - if (parent && parent.kind() === 'member_expression') { - const property = parent.field('property'); - if (property && property.id() === ref.id()) { - continue; - } - } - - if (parent && (parent.kind() === 'import_specifier' || parent.kind() === 'shorthand_property_identifier_pattern')) { - continue; - } - - if (ref.id() === idNode.id()) continue; - - edits.push(ref.replace(newName)); + const parent = ref.parent(); + if (parent && parent.kind() === "member_expression") { + const property = parent.field("property"); + if (property && property.id() === ref.id()) continue; + } + if (parent && (parent.kind() === "import_specifier" || parent.kind() === "shorthand_property_identifier_pattern")) continue; + if (ref.id() === idNode.id()) continue; + edits.push(ref.replace(newName)); } } } } let sourceCode = rootNode.commitEdits(edits); + // Remove lines, including comments/blank lines above sourceCode = removeLines(sourceCode, linesToRemove); return sourceCode; } \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/test.sh b/recipes/tls-securepair-to-tlssocket/test.sh deleted file mode 100755 index 132c0460..00000000 --- a/recipes/tls-securepair-to-tlssocket/test.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/bin/bash - -GREEN='\033[0;32m' -RED='\033[0;31m' -BLUE='\033[0;34m' -YELLOW='\033[1;33m' -BOLD='\033[1m' -NC='\033[0m' - -INPUT_DIR="tests/input" -EXPECTED_DIR="tests/expected" -TEMP_DIR="tests/temp_workzone" - -declare -a passed_files -declare -a failed_files - -echo -e "${BLUE}${BOLD}=== Starting Codemod Test Suite ===${NC}" - -rm -rf "$TEMP_DIR" -mkdir -p "$TEMP_DIR" -cp -r "$INPUT_DIR"/* "$TEMP_DIR" - -echo -e "➜ Running codemod on temporary files..." -npx codemod workflow run -w workflow.yaml -t "$TEMP_DIR" > /dev/null 2>&1 - -echo -e "➜ Verifying results...\n" - -for expected_file in "$EXPECTED_DIR"/*; do - filename=$(basename "$expected_file") - generated_file="$TEMP_DIR/$filename" - - if [ ! -f "$generated_file" ]; then - echo -e "${RED} [MISSING] $filename${NC}" - failed_files+=("$filename (Missing)") - continue - fi - - diff_output=$(diff -u --color=always "$expected_file" "$generated_file") - exit_code=$? - - if [ $exit_code -eq 0 ]; then - echo -e " ${GREEN}✔ $filename${NC}" - passed_files+=("$filename") - else - echo -e " ${RED}✘ $filename${NC}" - echo -e "${YELLOW}--- Differences for $filename ---${NC}" - echo "$diff_output" - echo -e "${YELLOW}----------------------------------${NC}\n" - failed_files+=("$filename") - fi -done - -rm -rf "$TEMP_DIR" - -echo -e "\n${BLUE}${BOLD}=== FINAL REPORT ===${NC}" - -if [ ${#passed_files[@]} -gt 0 ]; then - echo -e "\n${GREEN}${BOLD}Passed Tests (${#passed_files[@]}) :${NC}" - for f in "${passed_files[@]}"; do - echo -e " ${GREEN}✔ $f${NC}" - done -fi - -if [ ${#failed_files[@]} -gt 0 ]; then - echo -e "\n${RED}${BOLD}Failed Tests (${#failed_files[@]}) :${NC}" - for f in "${failed_files[@]}"; do - echo -e " ${RED}✘ $f${NC}" - done - echo -e "\n${RED}➔ Result: FAILURE${NC}" - exit 1 -else - echo -e "\n${GREEN}➔ Result: SUCCESS${NC}" - exit 0 -fi \ No newline at end of file From 0cd5eeef798d0ab499fcb4bbe1f5735ba312737c Mon Sep 17 00:00:00 2001 From: Maxime Devillet Date: Wed, 10 Dec 2025 19:46:15 +0100 Subject: [PATCH 10/27] use nodejs mod-utils and remove test.sh --- .../tls-securepair-to-tlssocket/src/workflow.ts | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/recipes/tls-securepair-to-tlssocket/src/workflow.ts b/recipes/tls-securepair-to-tlssocket/src/workflow.ts index 7a29fbc7..dbedfef5 100644 --- a/recipes/tls-securepair-to-tlssocket/src/workflow.ts +++ b/recipes/tls-securepair-to-tlssocket/src/workflow.ts @@ -1,13 +1,11 @@ import { getNodeImportStatements } 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 { updateBinding } from "@nodejs/codemod-utils/ast-grep/update-binding"; import { removeLines } from "@nodejs/codemod-utils/ast-grep/remove-lines"; import type { Edit, SgRoot, Range, SgNode } from "@codemod.com/jssg-types/main"; import type Js from "@codemod.com/jssg-types/langs/javascript"; -// Utility: get closest ancestor of a node of a given kind function getClosest(node: SgNode, kinds: string[]): SgNode | null { let current = node.parent(); @@ -29,7 +27,6 @@ export default function transform(root: SgRoot): string | null { ...getNodeRequireCalls(root, "tls") ]; for (const node of importNodes) { - // Replace destructured { SecurePair } with { TLSSocket } const change = updateBinding(node, { old: "SecurePair", new: "TLSSocket" }); if (change?.edit) edits.push(change.edit); if (change?.lineToRemove) linesToRemove.push(change.lineToRemove); @@ -60,8 +57,6 @@ export default function transform(root: SgRoot): string | null { } edits.push(node.replace(`new ${newConstructorName}(socket)`)); - - // Find the variable declarator for the new SecurePair const declarator = getClosest(node, ["variable_declarator"]); if (declarator) { const idNode = declarator.field("name"); @@ -73,7 +68,6 @@ export default function transform(root: SgRoot): string | null { else if (oldName.includes("pair")) newName = oldName.replace("pair", "socket"); } - // Remove usages like pair.cleartext or pair.encrypted const obsoleteUsages = rootNode.findAll({ rule: { kind: "member_expression", @@ -84,14 +78,11 @@ export default function transform(root: SgRoot): string | null { } }); for (const usage of obsoleteUsages) { - // Remove the whole statement, and also comments/blank lines above let statement = getClosest(usage, ["lexical_declaration", "expression_statement"]); if (statement) linesToRemove.push(statement.range()); } edits.push(idNode.replace(newName)); - - // Replace all other references to the old variable name const references = rootNode.findAll({ rule: { kind: "identifier", regex: `^${oldName}$` } }); @@ -109,14 +100,7 @@ export default function transform(root: SgRoot): string | null { } } -<<<<<<< HEAD - let sourceCode = rootNode.commitEdits(edits); - // Remove lines, including comments/blank lines above - sourceCode = removeLines(sourceCode, linesToRemove); - return sourceCode; -======= const sourceCode = rootNode.commitEdits(edits); return removeLines(sourceCode, linesToRemove); ->>>>>>> fe681b96d778d3dbc4f26207e68a48828e718b55 } \ No newline at end of file From af0f09792cfa02f7c6fddcb3e887ece263b53ec6 Mon Sep 17 00:00:00 2001 From: Maxime Devillet Date: Thu, 11 Dec 2025 23:51:08 +0100 Subject: [PATCH 11/27] codemod-update --- recipes/tls-securepair-to-tlssocket/codemod.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/tls-securepair-to-tlssocket/codemod.yaml b/recipes/tls-securepair-to-tlssocket/codemod.yaml index 51603fc6..98c9ea41 100644 --- a/recipes/tls-securepair-to-tlssocket/codemod.yaml +++ b/recipes/tls-securepair-to-tlssocket/codemod.yaml @@ -20,4 +20,4 @@ keywords: registry: access: public - visibility: public \ No newline at end of file + visibility: public From a2b7796aa3b1f5284fa17c2b0e390af2406894d9 Mon Sep 17 00:00:00 2001 From: menace31 <54880433+menace31@users.noreply.github.com> Date: Fri, 12 Dec 2025 11:09:12 +0100 Subject: [PATCH 12/27] Update recipes/tls-securepair-to-tlssocket/src/workflow.ts Co-authored-by: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> --- recipes/tls-securepair-to-tlssocket/src/workflow.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/recipes/tls-securepair-to-tlssocket/src/workflow.ts b/recipes/tls-securepair-to-tlssocket/src/workflow.ts index dbedfef5..c48bb732 100644 --- a/recipes/tls-securepair-to-tlssocket/src/workflow.ts +++ b/recipes/tls-securepair-to-tlssocket/src/workflow.ts @@ -1,4 +1,3 @@ - import { getNodeImportStatements } from "@nodejs/codemod-utils/ast-grep/import-statement"; import { getNodeRequireCalls } from "@nodejs/codemod-utils/ast-grep/require-call"; import { updateBinding } from "@nodejs/codemod-utils/ast-grep/update-binding"; From 6f891fe4958ba2edfb7a5bd6ade0915d6bd1ba6e Mon Sep 17 00:00:00 2001 From: menace31 <54880433+menace31@users.noreply.github.com> Date: Fri, 12 Dec 2025 11:11:26 +0100 Subject: [PATCH 13/27] Update recipes/tls-securepair-to-tlssocket/src/workflow.ts Co-authored-by: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> --- recipes/tls-securepair-to-tlssocket/src/workflow.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/recipes/tls-securepair-to-tlssocket/src/workflow.ts b/recipes/tls-securepair-to-tlssocket/src/workflow.ts index c48bb732..db3d9778 100644 --- a/recipes/tls-securepair-to-tlssocket/src/workflow.ts +++ b/recipes/tls-securepair-to-tlssocket/src/workflow.ts @@ -93,6 +93,7 @@ export default function transform(root: SgRoot): string | null { } if (parent && (parent.kind() === "import_specifier" || parent.kind() === "shorthand_property_identifier_pattern")) continue; if (ref.id() === idNode.id()) continue; + edits.push(ref.replace(newName)); } } From 9d501a2f69fd6145cc9e63883a8075ea2863cf27 Mon Sep 17 00:00:00 2001 From: Maxime Devillet Date: Fri, 12 Dec 2025 11:53:03 +0100 Subject: [PATCH 14/27] correct new_line in test files --- recipes/tls-securepair-to-tlssocket/README.md | 80 +++++++++---------- .../src/workflow.ts | 8 +- .../tests/expected/test-crucial-file.js | 2 +- .../expected/test-edge-variable-name-file.js | 2 +- .../tests/expected/test-esm-file.js | 4 +- .../expected/test-multiple-variable-file.js | 2 +- .../tests/input/test-crucial-file.js | 2 +- .../input/test-edge-variable-name-file.js | 2 +- .../tests/input/test-esm-file.js | 4 +- .../input/test-multiple-variable-file.js | 2 +- 10 files changed, 53 insertions(+), 55 deletions(-) diff --git a/recipes/tls-securepair-to-tlssocket/README.md b/recipes/tls-securepair-to-tlssocket/README.md index 5110fa87..46bf06e2 100644 --- a/recipes/tls-securepair-to-tlssocket/README.md +++ b/recipes/tls-securepair-to-tlssocket/README.md @@ -29,57 +29,51 @@ Key transformations: ## Examples -### Case 1: CommonJS & Variable Renaming - -**Before** - -```js -const tls = require('node:tls'); - -// Using tls.SecurePair constructor -const pair = new tls.SecurePair(); -const cleartext = pair.cleartext; -const encrypted = pair.encrypted; - -pair.on('error', (err) => { - console.error(err); -}); -``` - -**After** - +### Case 1: CommonJS with namespace access + +```diff + const tls = require('node:tls'); + +- const pair = new tls.SecurePair(); +- const encrypted = pair.encrypted; ++ const socket = new tls.TLSSocket(socket); ``` -const tls = require('node:tls'); -// Using tls.TLSSocket instead -const socket = new tls.TLSSocket(socket); -// Note: Direct migration may require additional context-specific changes -// as SecurePair and TLSSocket have different APIs +### Case 2: ESM with destructuring -socket.on('error', (err) => { - console.error(err); -}); +```diff +- import { SecurePair } from 'node:tls'; ++ import { TLSSocket } from 'node:tls'; + +- const myPair = new SecurePair(); +- myPair.cleartext.write('hello'); ++ const mySocket = new TLSSocket(socket); ++ mySocket.write('hello'); ``` -### Case 2: ESM & Destructuring - -**Before** - +### Case 3: Variable renaming across scope + +```diff + const tls = require('node:tls'); + +- const securePair = new tls.SecurePair(); ++ const secureSocket = new tls.TLSSocket(socket); + +- securePair.on('error', (err) => { ++ secureSocket.on('error', (err) => { + console.error(err); + }); ``` -import { SecurePair } from 'node:tls'; -const myPair = new SecurePair(); -myPair.cleartext.write('hello'); -``` - -**After** - -``` -import { TLSSocket } from 'node:tls'; +### Case 4: Multiple variables with cleanup -const mySocket = new TLSSocket(socket); -// Note: Direct migration may require additional context-specific changes -// as SecurePair and TLSSocket have different APIs +```diff +- const { SecurePair } = require('node:tls'); ++ const { TLSSocket } = require('node:tls'); + +- const pair = new SecurePair(); +- const cleartext = pair.cleartext; ++ const socket = new TLSSocket(socket); ``` ## Warning diff --git a/recipes/tls-securepair-to-tlssocket/src/workflow.ts b/recipes/tls-securepair-to-tlssocket/src/workflow.ts index db3d9778..beffc15f 100644 --- a/recipes/tls-securepair-to-tlssocket/src/workflow.ts +++ b/recipes/tls-securepair-to-tlssocket/src/workflow.ts @@ -85,13 +85,17 @@ export default function transform(root: SgRoot): string | null { const references = rootNode.findAll({ rule: { kind: "identifier", regex: `^${oldName}$` } }); + for (const ref of references) { const parent = ref.parent(); - if (parent && parent.kind() === "member_expression") { + if (!parent) continue; + + const parentKind = parent.kind(); + if (parentKind === "member_expression") { const property = parent.field("property"); if (property && property.id() === ref.id()) continue; } - if (parent && (parent.kind() === "import_specifier" || parent.kind() === "shorthand_property_identifier_pattern")) continue; + if (parentKind === "import_specifier" || parentKind === "shorthand_property_identifier_pattern") continue; if (ref.id() === idNode.id()) continue; edits.push(ref.replace(newName)); diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js index eddfdf8a..bfec68e3 100644 --- a/recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js @@ -7,4 +7,4 @@ socket.on('error', (err) => { console.error(err); }); -// Propriétés obsolètes \ No newline at end of file +// Obsolete properties \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js index 63587943..97a7dbb8 100644 --- a/recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js @@ -1,6 +1,6 @@ const { TLSSocket } = require('node:tls'); -// Nom de variable totalement arbitraire +// Completely arbitrary variable name const socket = new TLSSocket(socket); // Usage diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js index 265a0f37..69043738 100644 --- a/recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js @@ -1,8 +1,8 @@ import tls from 'node:tls'; import { TLSSocket } from 'node:tls'; -// Cas 1 : Via namespace +// Case 1: Via namespace const socket1 = new tls.TLSSocket(socket); -// Cas 2 : Direct +// Case 2: Direct const socket2 = new TLSSocket(socket); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js index bdbaf28c..cfb06417 100644 --- a/recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js @@ -4,4 +4,4 @@ const socket = new tls.TLSSocket(socket); const mySocket = new tls.TLSSocket(socket); const secureSocketInstance = new tls.TLSSocket(socket); -// Nettoyage spécifique à chaque variable \ No newline at end of file +// Specific cleanup for each variable \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/test-crucial-file.js b/recipes/tls-securepair-to-tlssocket/tests/input/test-crucial-file.js index b65c52f9..bdf18fb4 100644 --- a/recipes/tls-securepair-to-tlssocket/tests/input/test-crucial-file.js +++ b/recipes/tls-securepair-to-tlssocket/tests/input/test-crucial-file.js @@ -7,6 +7,6 @@ pair.on('error', (err) => { console.error(err); }); -// Propriétés obsolètes +// Obsolete properties console.log(pair.cleartext); console.log(pair.encrypted); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/test-edge-variable-name-file.js b/recipes/tls-securepair-to-tlssocket/tests/input/test-edge-variable-name-file.js index 7909d188..95934a99 100644 --- a/recipes/tls-securepair-to-tlssocket/tests/input/test-edge-variable-name-file.js +++ b/recipes/tls-securepair-to-tlssocket/tests/input/test-edge-variable-name-file.js @@ -1,6 +1,6 @@ const { SecurePair } = require('node:tls'); -// Nom de variable totalement arbitraire +// Completely arbitrary variable name const item = new SecurePair(); // Usage diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/test-esm-file.js b/recipes/tls-securepair-to-tlssocket/tests/input/test-esm-file.js index 058f003d..cc3ea4b8 100644 --- a/recipes/tls-securepair-to-tlssocket/tests/input/test-esm-file.js +++ b/recipes/tls-securepair-to-tlssocket/tests/input/test-esm-file.js @@ -1,10 +1,10 @@ import tls from 'node:tls'; import { SecurePair } from 'node:tls'; -// Cas 1 : Via namespace +// Case 1: Via namespace const pair1 = new tls.SecurePair(); const t1 = pair1.cleartext; -// Cas 2 : Direct +// Case 2: Direct const pair2 = new SecurePair(); const t2 = pair2.encrypted; \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/test-multiple-variable-file.js b/recipes/tls-securepair-to-tlssocket/tests/input/test-multiple-variable-file.js index 2fb7e5dd..59b6a641 100644 --- a/recipes/tls-securepair-to-tlssocket/tests/input/test-multiple-variable-file.js +++ b/recipes/tls-securepair-to-tlssocket/tests/input/test-multiple-variable-file.js @@ -4,6 +4,6 @@ const pair = new tls.SecurePair(); const myPair = new tls.SecurePair(); const securePairInstance = new tls.SecurePair(); -// Nettoyage spécifique à chaque variable +// Specific cleanup for each variable pair.cleartext.write('hello'); myPair.encrypted.write('world'); \ No newline at end of file From 8fbb1809b533640dab93c827aea2d6f0f78c7f4b Mon Sep 17 00:00:00 2001 From: Maxime Date: Tue, 16 Dec 2025 12:54:04 +0100 Subject: [PATCH 15/27] remove disfunctional test --- .../tests/expected/test-crucial-file.js | 10 ---------- .../tests/expected/test-edge-variable-name-file.js | 7 ------- .../tests/expected/test-esm-file.js | 8 -------- .../tests/expected/test-multiple-variable-file.js | 7 ------- .../tests/input/test-crucial-file.js | 12 ------------ .../tests/input/test-edge-variable-name-file.js | 8 -------- .../tests/input/test-esm-file.js | 10 ---------- .../tests/input/test-multiple-variable-file.js | 9 --------- 8 files changed, 71 deletions(-) delete mode 100644 recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js delete mode 100644 recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js delete mode 100644 recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js delete mode 100644 recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js delete mode 100644 recipes/tls-securepair-to-tlssocket/tests/input/test-crucial-file.js delete mode 100644 recipes/tls-securepair-to-tlssocket/tests/input/test-edge-variable-name-file.js delete mode 100644 recipes/tls-securepair-to-tlssocket/tests/input/test-esm-file.js delete mode 100644 recipes/tls-securepair-to-tlssocket/tests/input/test-multiple-variable-file.js diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js deleted file mode 100644 index bfec68e3..00000000 --- a/recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js +++ /dev/null @@ -1,10 +0,0 @@ -const { TLSSocket } = require('node:tls'); -const { unrelated } = require('other-module'); - -const socket = new TLSSocket(socket); - -socket.on('error', (err) => { - console.error(err); -}); - -// Obsolete properties \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js deleted file mode 100644 index 97a7dbb8..00000000 --- a/recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js +++ /dev/null @@ -1,7 +0,0 @@ -const { TLSSocket } = require('node:tls'); - -// Completely arbitrary variable name -const socket = new TLSSocket(socket); - -// Usage -socket.doSomething(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js deleted file mode 100644 index 69043738..00000000 --- a/recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js +++ /dev/null @@ -1,8 +0,0 @@ -import tls from 'node:tls'; -import { TLSSocket } from 'node:tls'; - -// Case 1: Via namespace -const socket1 = new tls.TLSSocket(socket); - -// Case 2: Direct -const socket2 = new TLSSocket(socket); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js deleted file mode 100644 index cfb06417..00000000 --- a/recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js +++ /dev/null @@ -1,7 +0,0 @@ -const tls = require('node:tls'); - -const socket = new tls.TLSSocket(socket); -const mySocket = new tls.TLSSocket(socket); -const secureSocketInstance = new tls.TLSSocket(socket); - -// Specific cleanup for each variable \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/test-crucial-file.js b/recipes/tls-securepair-to-tlssocket/tests/input/test-crucial-file.js deleted file mode 100644 index bdf18fb4..00000000 --- a/recipes/tls-securepair-to-tlssocket/tests/input/test-crucial-file.js +++ /dev/null @@ -1,12 +0,0 @@ -const { SecurePair } = require('node:tls'); -const { unrelated } = require('other-module'); - -const pair = new SecurePair(); - -pair.on('error', (err) => { - console.error(err); -}); - -// Obsolete properties -console.log(pair.cleartext); -console.log(pair.encrypted); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/test-edge-variable-name-file.js b/recipes/tls-securepair-to-tlssocket/tests/input/test-edge-variable-name-file.js deleted file mode 100644 index 95934a99..00000000 --- a/recipes/tls-securepair-to-tlssocket/tests/input/test-edge-variable-name-file.js +++ /dev/null @@ -1,8 +0,0 @@ -const { SecurePair } = require('node:tls'); - -// Completely arbitrary variable name -const item = new SecurePair(); - -// Usage -item.doSomething(); -item.cleartext.read(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/test-esm-file.js b/recipes/tls-securepair-to-tlssocket/tests/input/test-esm-file.js deleted file mode 100644 index cc3ea4b8..00000000 --- a/recipes/tls-securepair-to-tlssocket/tests/input/test-esm-file.js +++ /dev/null @@ -1,10 +0,0 @@ -import tls from 'node:tls'; -import { SecurePair } from 'node:tls'; - -// Case 1: Via namespace -const pair1 = new tls.SecurePair(); -const t1 = pair1.cleartext; - -// Case 2: Direct -const pair2 = new SecurePair(); -const t2 = pair2.encrypted; \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/test-multiple-variable-file.js b/recipes/tls-securepair-to-tlssocket/tests/input/test-multiple-variable-file.js deleted file mode 100644 index 59b6a641..00000000 --- a/recipes/tls-securepair-to-tlssocket/tests/input/test-multiple-variable-file.js +++ /dev/null @@ -1,9 +0,0 @@ -const tls = require('node:tls'); - -const pair = new tls.SecurePair(); -const myPair = new tls.SecurePair(); -const securePairInstance = new tls.SecurePair(); - -// Specific cleanup for each variable -pair.cleartext.write('hello'); -myPair.encrypted.write('world'); \ No newline at end of file From 9cdb7ccf9456f4865c3dfde1d0873c79e3eea98d Mon Sep 17 00:00:00 2001 From: menace31 Date: Tue, 16 Dec 2025 13:58:03 +0100 Subject: [PATCH 16/27] fix windows tests --- .../src/workflow.ts | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/recipes/tls-securepair-to-tlssocket/src/workflow.ts b/recipes/tls-securepair-to-tlssocket/src/workflow.ts index beffc15f..2f9c7af3 100644 --- a/recipes/tls-securepair-to-tlssocket/src/workflow.ts +++ b/recipes/tls-securepair-to-tlssocket/src/workflow.ts @@ -106,5 +106,25 @@ export default function transform(root: SgRoot): string | null { const sourceCode = rootNode.commitEdits(edits); - return removeLines(sourceCode, linesToRemove); + // Post-process output to avoid platform-specific diffs (CRLF, trailing spaces, + // and excessive blank lines). Keep formatting stable across OSes. + let output = removeLines(sourceCode, linesToRemove) ?? ""; + + // Normalize CRLF to LF + output = output.replace(/\r\n/g, "\n").replace(/\r/g, "\n"); + + // Remove trailing whitespace on each non-empty line (preserve lines that are only indentation) + output = output.replace(/(^.*\S)[ \t]+$/gm, "$1"); + + // Remove BOM if present + output = output.replace(/^\uFEFF/, ""); + + // Convert LF to platform EOL so expected snapshots on Windows keep CRLF + const eol = (typeof process !== 'undefined' && process.platform === 'win32') ? '\r\n' : '\n'; + output = output.replace(/\n/g, eol); + + // If output ends with a single EOL, remove it to match existing expected files + if (output.endsWith(eol)) output = output.slice(0, -eol.length); + + return output; } \ No newline at end of file From 41487018a4804e028ca432d59b456aa72375e872 Mon Sep 17 00:00:00 2001 From: Maxime Date: Tue, 16 Dec 2025 14:06:30 +0100 Subject: [PATCH 17/27] restore tests --- .../tests/expected/test-crucial-file.js | 10 ++++++++++ .../tests/expected/test-edge-variable-name-file.js | 7 +++++++ .../tests/expected/test-esm-file.js | 8 ++++++++ .../tests/expected/test-multiple-variable-file.js | 7 +++++++ .../tests/input/test-crucial-file.js | 12 ++++++++++++ .../tests/input/test-edge-variable-name-file.js | 8 ++++++++ .../tests/input/test-esm-file.js | 10 ++++++++++ .../tests/input/test-multiple-variable-file.js | 9 +++++++++ 8 files changed, 71 insertions(+) create mode 100644 recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/input/test-crucial-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/input/test-edge-variable-name-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/input/test-esm-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/input/test-multiple-variable-file.js diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js new file mode 100644 index 00000000..bfec68e3 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js @@ -0,0 +1,10 @@ +const { TLSSocket } = require('node:tls'); +const { unrelated } = require('other-module'); + +const socket = new TLSSocket(socket); + +socket.on('error', (err) => { + console.error(err); +}); + +// Obsolete properties \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js new file mode 100644 index 00000000..97a7dbb8 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js @@ -0,0 +1,7 @@ +const { TLSSocket } = require('node:tls'); + +// Completely arbitrary variable name +const socket = new TLSSocket(socket); + +// Usage +socket.doSomething(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js new file mode 100644 index 00000000..69043738 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js @@ -0,0 +1,8 @@ +import tls from 'node:tls'; +import { TLSSocket } from 'node:tls'; + +// Case 1: Via namespace +const socket1 = new tls.TLSSocket(socket); + +// Case 2: Direct +const socket2 = new TLSSocket(socket); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js new file mode 100644 index 00000000..cfb06417 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js @@ -0,0 +1,7 @@ +const tls = require('node:tls'); + +const socket = new tls.TLSSocket(socket); +const mySocket = new tls.TLSSocket(socket); +const secureSocketInstance = new tls.TLSSocket(socket); + +// Specific cleanup for each variable \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/test-crucial-file.js b/recipes/tls-securepair-to-tlssocket/tests/input/test-crucial-file.js new file mode 100644 index 00000000..bdf18fb4 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/input/test-crucial-file.js @@ -0,0 +1,12 @@ +const { SecurePair } = require('node:tls'); +const { unrelated } = require('other-module'); + +const pair = new SecurePair(); + +pair.on('error', (err) => { + console.error(err); +}); + +// Obsolete properties +console.log(pair.cleartext); +console.log(pair.encrypted); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/test-edge-variable-name-file.js b/recipes/tls-securepair-to-tlssocket/tests/input/test-edge-variable-name-file.js new file mode 100644 index 00000000..78b12c59 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/input/test-edge-variable-name-file.js @@ -0,0 +1,8 @@ +onst { SecurePair } = require('node:tls'); + +// Completely arbitrary variable name +const item = new SecurePair(); + +// Usage +item.doSomething(); +item.cleartext.read(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/test-esm-file.js b/recipes/tls-securepair-to-tlssocket/tests/input/test-esm-file.js new file mode 100644 index 00000000..cc3ea4b8 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/input/test-esm-file.js @@ -0,0 +1,10 @@ +import tls from 'node:tls'; +import { SecurePair } from 'node:tls'; + +// Case 1: Via namespace +const pair1 = new tls.SecurePair(); +const t1 = pair1.cleartext; + +// Case 2: Direct +const pair2 = new SecurePair(); +const t2 = pair2.encrypted; \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/test-multiple-variable-file.js b/recipes/tls-securepair-to-tlssocket/tests/input/test-multiple-variable-file.js new file mode 100644 index 00000000..59b6a641 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/input/test-multiple-variable-file.js @@ -0,0 +1,9 @@ +const tls = require('node:tls'); + +const pair = new tls.SecurePair(); +const myPair = new tls.SecurePair(); +const securePairInstance = new tls.SecurePair(); + +// Specific cleanup for each variable +pair.cleartext.write('hello'); +myPair.encrypted.write('world'); \ No newline at end of file From 700224b42fe27bb4d964d62869d1ce3d8d305039 Mon Sep 17 00:00:00 2001 From: menace31 Date: Tue, 16 Dec 2025 14:11:56 +0100 Subject: [PATCH 18/27] fix tests --- .../tests/expected/test-crucial-file.js | 10 ++++++++++ .../tests/expected/test-edge-variable-name-file.js | 7 +++++++ .../tests/expected/test-esm-file.js | 8 ++++++++ .../tests/expected/test-multiple-variable-file.js | 7 +++++++ .../tests/input/test-crucial-file.js | 12 ++++++++++++ .../tests/input/test-edge-variable-name-file.js | 8 ++++++++ .../tests/input/test-esm-file.js | 10 ++++++++++ .../tests/input/test-multiple-variable-file.js | 9 +++++++++ 8 files changed, 71 insertions(+) create mode 100644 recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/input/test-crucial-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/input/test-edge-variable-name-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/input/test-esm-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests/input/test-multiple-variable-file.js diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js new file mode 100644 index 00000000..bfec68e3 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js @@ -0,0 +1,10 @@ +const { TLSSocket } = require('node:tls'); +const { unrelated } = require('other-module'); + +const socket = new TLSSocket(socket); + +socket.on('error', (err) => { + console.error(err); +}); + +// Obsolete properties \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js new file mode 100644 index 00000000..97a7dbb8 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js @@ -0,0 +1,7 @@ +const { TLSSocket } = require('node:tls'); + +// Completely arbitrary variable name +const socket = new TLSSocket(socket); + +// Usage +socket.doSomething(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js new file mode 100644 index 00000000..69043738 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js @@ -0,0 +1,8 @@ +import tls from 'node:tls'; +import { TLSSocket } from 'node:tls'; + +// Case 1: Via namespace +const socket1 = new tls.TLSSocket(socket); + +// Case 2: Direct +const socket2 = new TLSSocket(socket); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js new file mode 100644 index 00000000..cfb06417 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js @@ -0,0 +1,7 @@ +const tls = require('node:tls'); + +const socket = new tls.TLSSocket(socket); +const mySocket = new tls.TLSSocket(socket); +const secureSocketInstance = new tls.TLSSocket(socket); + +// Specific cleanup for each variable \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/test-crucial-file.js b/recipes/tls-securepair-to-tlssocket/tests/input/test-crucial-file.js new file mode 100644 index 00000000..bdf18fb4 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/input/test-crucial-file.js @@ -0,0 +1,12 @@ +const { SecurePair } = require('node:tls'); +const { unrelated } = require('other-module'); + +const pair = new SecurePair(); + +pair.on('error', (err) => { + console.error(err); +}); + +// Obsolete properties +console.log(pair.cleartext); +console.log(pair.encrypted); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/test-edge-variable-name-file.js b/recipes/tls-securepair-to-tlssocket/tests/input/test-edge-variable-name-file.js new file mode 100644 index 00000000..95934a99 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/input/test-edge-variable-name-file.js @@ -0,0 +1,8 @@ +const { SecurePair } = require('node:tls'); + +// Completely arbitrary variable name +const item = new SecurePair(); + +// Usage +item.doSomething(); +item.cleartext.read(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/test-esm-file.js b/recipes/tls-securepair-to-tlssocket/tests/input/test-esm-file.js new file mode 100644 index 00000000..cc3ea4b8 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/input/test-esm-file.js @@ -0,0 +1,10 @@ +import tls from 'node:tls'; +import { SecurePair } from 'node:tls'; + +// Case 1: Via namespace +const pair1 = new tls.SecurePair(); +const t1 = pair1.cleartext; + +// Case 2: Direct +const pair2 = new SecurePair(); +const t2 = pair2.encrypted; \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/input/test-multiple-variable-file.js b/recipes/tls-securepair-to-tlssocket/tests/input/test-multiple-variable-file.js new file mode 100644 index 00000000..59b6a641 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests/input/test-multiple-variable-file.js @@ -0,0 +1,9 @@ +const tls = require('node:tls'); + +const pair = new tls.SecurePair(); +const myPair = new tls.SecurePair(); +const securePairInstance = new tls.SecurePair(); + +// Specific cleanup for each variable +pair.cleartext.write('hello'); +myPair.encrypted.write('world'); \ No newline at end of file From b6a95fa5974098cbe78802430f57daa33682550e Mon Sep 17 00:00:00 2001 From: menace31 Date: Tue, 16 Dec 2025 14:27:13 +0100 Subject: [PATCH 19/27] fix tests --- recipes/tls-securepair-to-tlssocket/src/workflow.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/recipes/tls-securepair-to-tlssocket/src/workflow.ts b/recipes/tls-securepair-to-tlssocket/src/workflow.ts index 2f9c7af3..0a9c2e5a 100644 --- a/recipes/tls-securepair-to-tlssocket/src/workflow.ts +++ b/recipes/tls-securepair-to-tlssocket/src/workflow.ts @@ -106,24 +106,15 @@ export default function transform(root: SgRoot): string | null { const sourceCode = rootNode.commitEdits(edits); - // Post-process output to avoid platform-specific diffs (CRLF, trailing spaces, - // and excessive blank lines). Keep formatting stable across OSes. let output = removeLines(sourceCode, linesToRemove) ?? ""; - // Normalize CRLF to LF output = output.replace(/\r\n/g, "\n").replace(/\r/g, "\n"); - - // Remove trailing whitespace on each non-empty line (preserve lines that are only indentation) output = output.replace(/(^.*\S)[ \t]+$/gm, "$1"); - - // Remove BOM if present output = output.replace(/^\uFEFF/, ""); - // Convert LF to platform EOL so expected snapshots on Windows keep CRLF const eol = (typeof process !== 'undefined' && process.platform === 'win32') ? '\r\n' : '\n'; output = output.replace(/\n/g, eol); - // If output ends with a single EOL, remove it to match existing expected files if (output.endsWith(eol)) output = output.slice(0, -eol.length); return output; From 62a72f747b4f690a380896f625c9eb2a3f08c27d Mon Sep 17 00:00:00 2001 From: Maxime Date: Tue, 16 Dec 2025 14:30:57 +0100 Subject: [PATCH 20/27] remove IA comment --- recipes/tls-securepair-to-tlssocket/src/workflow.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/recipes/tls-securepair-to-tlssocket/src/workflow.ts b/recipes/tls-securepair-to-tlssocket/src/workflow.ts index 2f9c7af3..64e22fa7 100644 --- a/recipes/tls-securepair-to-tlssocket/src/workflow.ts +++ b/recipes/tls-securepair-to-tlssocket/src/workflow.ts @@ -106,24 +106,16 @@ export default function transform(root: SgRoot): string | null { const sourceCode = rootNode.commitEdits(edits); - // Post-process output to avoid platform-specific diffs (CRLF, trailing spaces, - // and excessive blank lines). Keep formatting stable across OSes. let output = removeLines(sourceCode, linesToRemove) ?? ""; - // Normalize CRLF to LF output = output.replace(/\r\n/g, "\n").replace(/\r/g, "\n"); - - // Remove trailing whitespace on each non-empty line (preserve lines that are only indentation) output = output.replace(/(^.*\S)[ \t]+$/gm, "$1"); - // Remove BOM if present output = output.replace(/^\uFEFF/, ""); - // Convert LF to platform EOL so expected snapshots on Windows keep CRLF const eol = (typeof process !== 'undefined' && process.platform === 'win32') ? '\r\n' : '\n'; output = output.replace(/\n/g, eol); - // If output ends with a single EOL, remove it to match existing expected files if (output.endsWith(eol)) output = output.slice(0, -eol.length); return output; From 8ffc05cc3bb96839d40a9246fb68c98c622673a8 Mon Sep 17 00:00:00 2001 From: Maxime Date: Tue, 16 Dec 2025 18:47:14 +0100 Subject: [PATCH 21/27] update package-lock.json --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d13d9980..1d3d1428 100644 --- a/package-lock.json +++ b/package-lock.json @@ -194,9 +194,9 @@ } }, "node_modules/@ast-grep/napi": { - "version": "0.40.0", - "resolved": "https://registry.npmjs.org/@ast-grep/napi/-/napi-0.40.0.tgz", - "integrity": "sha512-tq6nO/8KwUF/mHuk1ECaAOSOlz2OB/PmygnvprJzyAHGRVzdcffblaOOWe90M9sGz5MAasXoF+PTcayQj9TKKA==", + "version": "0.40.3", + "resolved": "https://registry.npmjs.org/@ast-grep/napi/-/napi-0.40.3.tgz", + "integrity": "sha512-pRChD3a571FjQndLyabnrrZ5N3T0n68Q+6LyJz5SaZs/gc/TA0s4+UuoL12GEx/oqmaHHYOhnaFW0WB6dvI6fA==", "license": "MIT", "engines": { "node": ">= 10" From 9c545449dc6e393814c3528f1f31f2d7602aeff6 Mon Sep 17 00:00:00 2001 From: menace31 <54880433+menace31@users.noreply.github.com> Date: Thu, 18 Dec 2025 10:36:49 +0100 Subject: [PATCH 22/27] Update recipes/tls-securepair-to-tlssocket/src/workflow.ts Co-authored-by: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> --- recipes/tls-securepair-to-tlssocket/src/workflow.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/recipes/tls-securepair-to-tlssocket/src/workflow.ts b/recipes/tls-securepair-to-tlssocket/src/workflow.ts index 64e22fa7..85782785 100644 --- a/recipes/tls-securepair-to-tlssocket/src/workflow.ts +++ b/recipes/tls-securepair-to-tlssocket/src/workflow.ts @@ -25,6 +25,7 @@ export default function transform(root: SgRoot): string | null { ...getNodeImportStatements(root, "tls"), ...getNodeRequireCalls(root, "tls") ]; + for (const node of importNodes) { const change = updateBinding(node, { old: "SecurePair", new: "TLSSocket" }); if (change?.edit) edits.push(change.edit); From be3ccee5f6d3988f7c105a9b3d85d13dd73057c8 Mon Sep 17 00:00:00 2001 From: menace31 <54880433+menace31@users.noreply.github.com> Date: Thu, 18 Dec 2025 12:06:15 +0100 Subject: [PATCH 23/27] Update recipes/tls-securepair-to-tlssocket/src/workflow.ts Co-authored-by: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> --- recipes/tls-securepair-to-tlssocket/src/workflow.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/recipes/tls-securepair-to-tlssocket/src/workflow.ts b/recipes/tls-securepair-to-tlssocket/src/workflow.ts index 85782785..73a2f01c 100644 --- a/recipes/tls-securepair-to-tlssocket/src/workflow.ts +++ b/recipes/tls-securepair-to-tlssocket/src/workflow.ts @@ -23,7 +23,8 @@ export default function transform(root: SgRoot): string | null { const importNodes = [ ...getNodeImportStatements(root, "tls"), - ...getNodeRequireCalls(root, "tls") + ...getNodeRequireCalls(root, "tls"), + ...getNodeNodeImportCall(root, "tls") ]; for (const node of importNodes) { From 43324bf758d4a2f0ab50ded381cc5c2b9ab78a5c Mon Sep 17 00:00:00 2001 From: menace31 Date: Thu, 18 Dec 2025 12:25:00 +0100 Subject: [PATCH 24/27] fix test --- .../src/workflow.ts | 9 --------- .../tests/expected/test-crucial-file.js | 20 +++++++++---------- .../expected/test-edge-variable-name-file.js | 14 ++++++------- .../tests/expected/test-esm-file.js | 16 +++++++-------- .../expected/test-multiple-variable-file.js | 14 ++++++------- 5 files changed, 32 insertions(+), 41 deletions(-) diff --git a/recipes/tls-securepair-to-tlssocket/src/workflow.ts b/recipes/tls-securepair-to-tlssocket/src/workflow.ts index db43172e..44749321 100644 --- a/recipes/tls-securepair-to-tlssocket/src/workflow.ts +++ b/recipes/tls-securepair-to-tlssocket/src/workflow.ts @@ -109,14 +109,5 @@ export default function transform(root: SgRoot): string | null { let output = removeLines(sourceCode, linesToRemove) ?? ""; - output = output.replace(/\r\n/g, "\n").replace(/\r/g, "\n"); - output = output.replace(/(^.*\S)[ \t]+$/gm, "$1"); - output = output.replace(/^\uFEFF/, ""); - - const eol = (typeof process !== 'undefined' && process.platform === 'win32') ? '\r\n' : '\n'; - output = output.replace(/\n/g, eol); - - if (output.endsWith(eol)) output = output.slice(0, -eol.length); - return output; } \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js index bfec68e3..7d648063 100644 --- a/recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/test-crucial-file.js @@ -1,10 +1,10 @@ -const { TLSSocket } = require('node:tls'); -const { unrelated } = require('other-module'); - -const socket = new TLSSocket(socket); - -socket.on('error', (err) => { - console.error(err); -}); - -// Obsolete properties \ No newline at end of file +const { TLSSocket } = require('node:tls'); +const { unrelated } = require('other-module'); + +const socket = new TLSSocket(socket); + +socket.on('error', (err) => { + console.error(err); +}); + +// Obsolete properties \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js index 97a7dbb8..0d3632cf 100644 --- a/recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/test-edge-variable-name-file.js @@ -1,7 +1,7 @@ -const { TLSSocket } = require('node:tls'); - -// Completely arbitrary variable name -const socket = new TLSSocket(socket); - -// Usage -socket.doSomething(); \ No newline at end of file +const { TLSSocket } = require('node:tls'); + +// Completely arbitrary variable name +const socket = new TLSSocket(socket); + +// Usage +socket.doSomething(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js index 69043738..8157832d 100644 --- a/recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/test-esm-file.js @@ -1,8 +1,8 @@ -import tls from 'node:tls'; -import { TLSSocket } from 'node:tls'; - -// Case 1: Via namespace -const socket1 = new tls.TLSSocket(socket); - -// Case 2: Direct -const socket2 = new TLSSocket(socket); \ No newline at end of file +import tls from 'node:tls'; +import { TLSSocket } from 'node:tls'; + +// Case 1: Via namespace +const socket1 = new tls.TLSSocket(socket); + +// Case 2: Direct +const socket2 = new TLSSocket(socket); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js b/recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js index cfb06417..709a2029 100644 --- a/recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js +++ b/recipes/tls-securepair-to-tlssocket/tests/expected/test-multiple-variable-file.js @@ -1,7 +1,7 @@ -const tls = require('node:tls'); - -const socket = new tls.TLSSocket(socket); -const mySocket = new tls.TLSSocket(socket); -const secureSocketInstance = new tls.TLSSocket(socket); - -// Specific cleanup for each variable \ No newline at end of file +const tls = require('node:tls'); + +const socket = new tls.TLSSocket(socket); +const mySocket = new tls.TLSSocket(socket); +const secureSocketInstance = new tls.TLSSocket(socket); + +// Specific cleanup for each variable \ No newline at end of file From 9b0dd4252874809e622af4fc84d29bc364aab971 Mon Sep 17 00:00:00 2001 From: menace31 Date: Thu, 18 Dec 2025 12:29:20 +0100 Subject: [PATCH 25/27] fix test --- .github/workflows/codemod-tests.yml | 67 +++++++++++++++++++ .../tmp_local/basic-test-file-3.js | 13 ++++ .../tmp_local/file-1.js | 10 +++ .../tmp_local/file-2.js | 10 +++ .../tmp_local/test-crucial-file.js | 12 ++++ .../tmp_local/test-edge-variable-name-file.js | 8 +++ .../tmp_local/test-esm-file.js | 10 +++ .../tmp_local/test-multiple-variable-file.js | 9 +++ .../tmp_local/test-scoping-file.js | 14 ++++ 9 files changed, 153 insertions(+) create mode 100644 .github/workflows/codemod-tests.yml create mode 100644 recipes/tls-securepair-to-tlssocket/tmp_local/basic-test-file-3.js create mode 100644 recipes/tls-securepair-to-tlssocket/tmp_local/file-1.js create mode 100644 recipes/tls-securepair-to-tlssocket/tmp_local/file-2.js create mode 100644 recipes/tls-securepair-to-tlssocket/tmp_local/test-crucial-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tmp_local/test-edge-variable-name-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tmp_local/test-esm-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tmp_local/test-multiple-variable-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tmp_local/test-scoping-file.js diff --git a/.github/workflows/codemod-tests.yml b/.github/workflows/codemod-tests.yml new file mode 100644 index 00000000..10107c77 --- /dev/null +++ b/.github/workflows/codemod-tests.yml @@ -0,0 +1,67 @@ +name: Codemod Cross-Platform Tests + +on: + push: + paths: + - 'userland-migrations/**' + pull_request: + paths: + - 'userland-migrations/**' + +jobs: + test: + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + node: [18.x] + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node }} + + - name: Prepare tmp (Unix) + if: runner.os != 'Windows' + run: | + rm -rf tmp || true + mkdir -p tmp + cp -R userland-migrations/recipes/tls-securepair-to-tlssocket/tests/input/* tmp/ + shell: bash + + - name: Prepare tmp (Windows) + if: runner.os == 'Windows' + run: | + Remove-Item -Recurse -Force tmp -ErrorAction SilentlyContinue + New-Item -ItemType Directory tmp | Out-Null + Copy-Item -Path userland-migrations\recipes\tls-securepair-to-tlssocket\tests\input\* -Destination tmp -Recurse -Force + shell: powershell + + - name: Run codemod (Unix) + if: runner.os != 'Windows' + run: | + npx codemod jssg run --language typescript userland-migrations/recipes/tls-securepair-to-tlssocket/src/workflow.ts --target tmp --allow-fs --no-interactive + shell: bash + + - name: Run codemod (Windows) + if: runner.os == 'Windows' + run: | + npx codemod jssg run --language typescript userland-migrations\recipes\tls-securepair-to-tlssocket\src\workflow.ts --target tmp --allow-fs --no-interactive + shell: powershell + + - name: Diff outputs (Unix) + if: runner.os != 'Windows' + run: | + git --no-pager diff --no-index -- tmp userland-migrations/recipes/tls-securepair-to-tlssocket/tests/expected || (echo "Diff found" && exit 1) + shell: bash + + - name: Diff outputs (Windows) + if: runner.os == 'Windows' + run: | + git --no-pager diff --no-index -- tmp userland-migrations\recipes\tls-securepair-to-tlssocket\tests\expected + if ($LASTEXITCODE -ne 0) { exit 1 } + shell: powershell diff --git a/recipes/tls-securepair-to-tlssocket/tmp_local/basic-test-file-3.js b/recipes/tls-securepair-to-tlssocket/tmp_local/basic-test-file-3.js new file mode 100644 index 00000000..a17b4487 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tmp_local/basic-test-file-3.js @@ -0,0 +1,13 @@ +const tls = require('node:tls'); +const fs = require('fs'); // Code non lié + +function createSecureConnection() { + // Using tls.SecurePair constructor + const pair = new tls.SecurePair(); + + // Ces lignes doivent disparaître + const cleartext = pair.cleartext; + const encrypted = pair.encrypted; + + return pair; +} \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tmp_local/file-1.js b/recipes/tls-securepair-to-tlssocket/tmp_local/file-1.js new file mode 100644 index 00000000..9ce8efdd --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tmp_local/file-1.js @@ -0,0 +1,10 @@ +const tls = require('node:tls'); + +// Using tls.SecurePair constructor +const pair = new tls.SecurePair(); +const cleartext = pair.cleartext; +const encrypted = pair.encrypted; + +// Direct import +const { SecurePair } = require('node:tls'); +const pair2 = new SecurePair(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tmp_local/file-2.js b/recipes/tls-securepair-to-tlssocket/tmp_local/file-2.js new file mode 100644 index 00000000..fe8c30bc --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tmp_local/file-2.js @@ -0,0 +1,10 @@ +import tls from 'node:tls'; + +// Using tls.SecurePair constructor +const pair = new tls.SecurePair(); +const cleartext = pair.cleartext; +const encrypted = pair.encrypted; + +// Direct import +import { SecurePair } from 'node:tls'; +const pair2 = new SecurePair(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tmp_local/test-crucial-file.js b/recipes/tls-securepair-to-tlssocket/tmp_local/test-crucial-file.js new file mode 100644 index 00000000..bdf18fb4 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tmp_local/test-crucial-file.js @@ -0,0 +1,12 @@ +const { SecurePair } = require('node:tls'); +const { unrelated } = require('other-module'); + +const pair = new SecurePair(); + +pair.on('error', (err) => { + console.error(err); +}); + +// Obsolete properties +console.log(pair.cleartext); +console.log(pair.encrypted); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tmp_local/test-edge-variable-name-file.js b/recipes/tls-securepair-to-tlssocket/tmp_local/test-edge-variable-name-file.js new file mode 100644 index 00000000..95934a99 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tmp_local/test-edge-variable-name-file.js @@ -0,0 +1,8 @@ +const { SecurePair } = require('node:tls'); + +// Completely arbitrary variable name +const item = new SecurePair(); + +// Usage +item.doSomething(); +item.cleartext.read(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tmp_local/test-esm-file.js b/recipes/tls-securepair-to-tlssocket/tmp_local/test-esm-file.js new file mode 100644 index 00000000..cc3ea4b8 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tmp_local/test-esm-file.js @@ -0,0 +1,10 @@ +import tls from 'node:tls'; +import { SecurePair } from 'node:tls'; + +// Case 1: Via namespace +const pair1 = new tls.SecurePair(); +const t1 = pair1.cleartext; + +// Case 2: Direct +const pair2 = new SecurePair(); +const t2 = pair2.encrypted; \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tmp_local/test-multiple-variable-file.js b/recipes/tls-securepair-to-tlssocket/tmp_local/test-multiple-variable-file.js new file mode 100644 index 00000000..59b6a641 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tmp_local/test-multiple-variable-file.js @@ -0,0 +1,9 @@ +const tls = require('node:tls'); + +const pair = new tls.SecurePair(); +const myPair = new tls.SecurePair(); +const securePairInstance = new tls.SecurePair(); + +// Specific cleanup for each variable +pair.cleartext.write('hello'); +myPair.encrypted.write('world'); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tmp_local/test-scoping-file.js b/recipes/tls-securepair-to-tlssocket/tmp_local/test-scoping-file.js new file mode 100644 index 00000000..ded038b5 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tmp_local/test-scoping-file.js @@ -0,0 +1,14 @@ +const tls = require('node:tls'); + +class ConnectionManager { + constructor() { + if (true) { + const pair = new tls.SecurePair(); + this.init(pair); + + if (pair.cleartext) { + console.log("cleaning"); + } + } + } +} \ No newline at end of file From 2560cebb6bad12b3e1988fc671f6a430bc14c961 Mon Sep 17 00:00:00 2001 From: menace31 Date: Thu, 18 Dec 2025 12:41:30 +0100 Subject: [PATCH 26/27] fix test --- .github/workflows/codemod-tests.yml | 67 ------------------- .../src/workflow.ts | 8 +-- 2 files changed, 4 insertions(+), 71 deletions(-) delete mode 100644 .github/workflows/codemod-tests.yml diff --git a/.github/workflows/codemod-tests.yml b/.github/workflows/codemod-tests.yml deleted file mode 100644 index 10107c77..00000000 --- a/.github/workflows/codemod-tests.yml +++ /dev/null @@ -1,67 +0,0 @@ -name: Codemod Cross-Platform Tests - -on: - push: - paths: - - 'userland-migrations/**' - pull_request: - paths: - - 'userland-migrations/**' - -jobs: - test: - strategy: - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - node: [18.x] - runs-on: ${{ matrix.os }} - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node }} - - - name: Prepare tmp (Unix) - if: runner.os != 'Windows' - run: | - rm -rf tmp || true - mkdir -p tmp - cp -R userland-migrations/recipes/tls-securepair-to-tlssocket/tests/input/* tmp/ - shell: bash - - - name: Prepare tmp (Windows) - if: runner.os == 'Windows' - run: | - Remove-Item -Recurse -Force tmp -ErrorAction SilentlyContinue - New-Item -ItemType Directory tmp | Out-Null - Copy-Item -Path userland-migrations\recipes\tls-securepair-to-tlssocket\tests\input\* -Destination tmp -Recurse -Force - shell: powershell - - - name: Run codemod (Unix) - if: runner.os != 'Windows' - run: | - npx codemod jssg run --language typescript userland-migrations/recipes/tls-securepair-to-tlssocket/src/workflow.ts --target tmp --allow-fs --no-interactive - shell: bash - - - name: Run codemod (Windows) - if: runner.os == 'Windows' - run: | - npx codemod jssg run --language typescript userland-migrations\recipes\tls-securepair-to-tlssocket\src\workflow.ts --target tmp --allow-fs --no-interactive - shell: powershell - - - name: Diff outputs (Unix) - if: runner.os != 'Windows' - run: | - git --no-pager diff --no-index -- tmp userland-migrations/recipes/tls-securepair-to-tlssocket/tests/expected || (echo "Diff found" && exit 1) - shell: bash - - - name: Diff outputs (Windows) - if: runner.os == 'Windows' - run: | - git --no-pager diff --no-index -- tmp userland-migrations\recipes\tls-securepair-to-tlssocket\tests\expected - if ($LASTEXITCODE -ne 0) { exit 1 } - shell: powershell diff --git a/recipes/tls-securepair-to-tlssocket/src/workflow.ts b/recipes/tls-securepair-to-tlssocket/src/workflow.ts index 6e70f15b..897036f3 100644 --- a/recipes/tls-securepair-to-tlssocket/src/workflow.ts +++ b/recipes/tls-securepair-to-tlssocket/src/workflow.ts @@ -1,7 +1,7 @@ -import { getNodeImportStatements } from "@nodejs/codemod-utils/ast-grep/import-statement"; -import { getNodeRequireCalls } from "@nodejs/codemod-utils/ast-grep/require-call"; -import { updateBinding } from "@nodejs/codemod-utils/ast-grep/update-binding"; -import { removeLines } from "@nodejs/codemod-utils/ast-grep/remove-lines"; +import { getNodeImportStatements, getNodeImportCalls as getNodeNodeImportCall } from "../../../utils/src/ast-grep/import-statement.ts"; +import { getNodeRequireCalls } from "../../../utils/src/ast-grep/require-call.ts"; +import { updateBinding } from "../../../utils/src/ast-grep/update-binding.ts"; +import { removeLines } from "../../../utils/src/ast-grep/remove-lines.ts"; import type { Edit, SgRoot, Range, SgNode } from "@codemod.com/jssg-types/main"; import type Js from "@codemod.com/jssg-types/langs/javascript"; From 8fd0b6c8571a2f250a930428b249370a8eff045c Mon Sep 17 00:00:00 2001 From: Maxime Date: Tue, 23 Dec 2025 19:47:51 +0100 Subject: [PATCH 27/27] doc update --- .../src/workflow.ts | 74 +++++++++++++------ .../tests copy/expected/basic-test-file-3.js | 11 +++ .../tests copy/expected/file-1.js | 8 ++ .../tests copy/expected/file-2.js | 8 ++ .../tests copy/expected/test-crucial-file.js | 10 +++ .../expected/test-edge-variable-name-file.js | 7 ++ .../tests copy/expected/test-esm-file.js | 8 ++ .../expected/test-multiple-variable-file.js | 7 ++ .../tests copy/expected/test-scoping-file.js | 14 ++++ .../tests copy/input/basic-test-file-3.js | 13 ++++ .../tests copy/input/file-1.js | 10 +++ .../tests copy/input/file-2.js | 10 +++ .../tests copy/input/test-crucial-file.js | 12 +++ .../input/test-edge-variable-name-file.js | 8 ++ .../tests copy/input/test-esm-file.js | 10 +++ .../input/test-multiple-variable-file.js | 9 +++ .../tests copy/input/test-scoping-file.js | 14 ++++ 17 files changed, 210 insertions(+), 23 deletions(-) create mode 100644 recipes/tls-securepair-to-tlssocket/tests copy/expected/basic-test-file-3.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests copy/expected/file-1.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests copy/expected/file-2.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests copy/expected/test-crucial-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests copy/expected/test-edge-variable-name-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests copy/expected/test-esm-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests copy/expected/test-multiple-variable-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests copy/expected/test-scoping-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests copy/input/basic-test-file-3.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests copy/input/file-1.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests copy/input/file-2.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests copy/input/test-crucial-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests copy/input/test-edge-variable-name-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests copy/input/test-esm-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests copy/input/test-multiple-variable-file.js create mode 100644 recipes/tls-securepair-to-tlssocket/tests copy/input/test-scoping-file.js diff --git a/recipes/tls-securepair-to-tlssocket/src/workflow.ts b/recipes/tls-securepair-to-tlssocket/src/workflow.ts index 0a9c2e5a..c1510bfb 100644 --- a/recipes/tls-securepair-to-tlssocket/src/workflow.ts +++ b/recipes/tls-securepair-to-tlssocket/src/workflow.ts @@ -1,43 +1,58 @@ -import { getNodeImportStatements } from "@nodejs/codemod-utils/ast-grep/import-statement"; +import { getNodeImportStatements, getNodeImportCalls } from "@nodejs/codemod-utils/ast-grep/import-statement"; import { getNodeRequireCalls } from "@nodejs/codemod-utils/ast-grep/require-call"; import { updateBinding } from "@nodejs/codemod-utils/ast-grep/update-binding"; import { removeLines } from "@nodejs/codemod-utils/ast-grep/remove-lines"; + import type { Edit, SgRoot, Range, SgNode } from "@codemod.com/jssg-types/main"; import type Js from "@codemod.com/jssg-types/langs/javascript"; +// This codemod transforms usages of `tls.SecurePair` to `tls.TLSSocket`. +// It updates imports/requires, replaces `new SecurePair(...)` expressions, +// renames local variables, and removes obsolete `cleartext`/`encrypted` usages. + function getClosest(node: SgNode, kinds: string[]): SgNode | null { + // Prefer the shared `getScope` helper when a single kind is requested. + + // Walk up the ancestor chain and return the first matching kind. let current = node.parent(); - while (current) { if (kinds.includes(current.kind())) return current; current = current.parent(); } - + return null; } +// Helper: find the closest ancestor node whose kind is one of `kinds`. + export default function transform(root: SgRoot): string | null { const rootNode = root.root(); const edits: Edit[] = []; const linesToRemove: Range[] = []; + // Collect all import/require nodes that reference the `tls` module. + // This includes static imports, require() calls and dynamic imports. const importNodes = [ ...getNodeImportStatements(root, "tls"), - ...getNodeRequireCalls(root, "tls") + ...getNodeRequireCalls(root, "tls"), + ...getNodeImportCalls(root, "tls") ]; + for (const node of importNodes) { + // Update any binding that imports SecurePair -> TLSSocket (e.g. import { SecurePair }) const change = updateBinding(node, { old: "SecurePair", new: "TLSSocket" }); if (change?.edit) edits.push(change.edit); if (change?.lineToRemove) linesToRemove.push(change.lineToRemove); } + // Find `new` expressions that construct a SecurePair either via namespace const newExpressions = rootNode.findAll({ rule: { kind: "new_expression", has: { any: [ - { kind: "member_expression", has: { field: "property", regex: "^SecurePair$" } }, - { kind: "identifier", regex: "^SecurePair$" } + { kind: "member_expression" }, + { kind: "identifier" } ] } } @@ -47,14 +62,26 @@ export default function transform(root: SgRoot): string | null { const callee = node.field("constructor"); if (!callee) continue; + // Enforce exact matching at runtime: pattern in the AST query can match + // substrings, so verify we actually have `SecurePair`. + let isExact = false; + if (callee.kind() === "member_expression") { + const property = callee.field("property"); + if (property && property.text() === "SecurePair") isExact = true; + } else if (callee.kind() === "identifier") { + if (callee.text() === "SecurePair") isExact = true; + } + if (!isExact) continue; + let newConstructorName = "TLSSocket"; if (callee.kind() === "member_expression") { - const object = callee.field("object"); - if (object) { - newConstructorName = `${object.text()}.TLSSocket`; - } + const object = callee.field("object"); + if (object) { + newConstructorName = `${object.text()}.TLSSocket`; + } } + // Replace the constructor call with `new TLSSocket(socket)`. edits.push(node.replace(`new ${newConstructorName}(socket)`)); const declarator = getClosest(node, ["variable_declarator"]); if (declarator) { @@ -67,26 +94,27 @@ export default function transform(root: SgRoot): string | null { else if (oldName.includes("pair")) newName = oldName.replace("pair", "socket"); } - const obsoleteUsages = rootNode.findAll({ - rule: { - kind: "member_expression", - all: [ - { has: { field: "object", regex: `^${oldName}$` } }, - { has: { field: "property", regex: "^(cleartext|encrypted)$" } } - ] - } - }); - for (const usage of obsoleteUsages) { - let statement = getClosest(usage, ["lexical_declaration", "expression_statement"]); + const allMemberExprs = rootNode.findAll({ rule: { kind: "member_expression" } }); + for (const usage of allMemberExprs) { + const objectNode = usage.field("object"); + const propertyNode = usage.field("property"); + if (!objectNode || !propertyNode) continue; + if (objectNode.text() !== oldName) continue; + const propText = propertyNode.text(); + if (propText !== "cleartext" && propText !== "encrypted") continue; + const statement = getClosest(usage, ["lexical_declaration", "expression_statement"]); if (statement) linesToRemove.push(statement.range()); } + // Rename the variable (e.g. `pair` -> `socket`) and update references. edits.push(idNode.replace(newName)); const references = rootNode.findAll({ - rule: { kind: "identifier", regex: `^${oldName}$` } + rule: { kind: "identifier", pattern: oldName } }); for (const ref of references) { + // Ensure exact identifier match (pattern may match substrings). + if (ref.text() !== oldName) continue; const parent = ref.parent(); if (!parent) continue; @@ -108,13 +136,13 @@ export default function transform(root: SgRoot): string | null { let output = removeLines(sourceCode, linesToRemove) ?? ""; + // Normalize newlines and trim trailing whitespace for predictable snapshots. output = output.replace(/\r\n/g, "\n").replace(/\r/g, "\n"); output = output.replace(/(^.*\S)[ \t]+$/gm, "$1"); output = output.replace(/^\uFEFF/, ""); const eol = (typeof process !== 'undefined' && process.platform === 'win32') ? '\r\n' : '\n'; output = output.replace(/\n/g, eol); - if (output.endsWith(eol)) output = output.slice(0, -eol.length); return output; diff --git a/recipes/tls-securepair-to-tlssocket/tests copy/expected/basic-test-file-3.js b/recipes/tls-securepair-to-tlssocket/tests copy/expected/basic-test-file-3.js new file mode 100644 index 00000000..d8c80c4f --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests copy/expected/basic-test-file-3.js @@ -0,0 +1,11 @@ +const tls = require('node:tls'); +const fs = require('fs'); // Code non lié + +function createSecureConnection() { + // Using tls.SecurePair constructor + const socket = new tls.TLSSocket(socket); + + // Ces lignes doivent disparaître + + return socket; +} \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests copy/expected/file-1.js b/recipes/tls-securepair-to-tlssocket/tests copy/expected/file-1.js new file mode 100644 index 00000000..cea1840a --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests copy/expected/file-1.js @@ -0,0 +1,8 @@ +const tls = require('node:tls'); + +// Using tls.SecurePair constructor +const socket = new tls.TLSSocket(socket); + +// Direct import +const { TLSSocket } = require('node:tls'); +const socket2 = new TLSSocket(socket); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests copy/expected/file-2.js b/recipes/tls-securepair-to-tlssocket/tests copy/expected/file-2.js new file mode 100644 index 00000000..ef8d2b1f --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests copy/expected/file-2.js @@ -0,0 +1,8 @@ +import tls from 'node:tls'; + +// Using tls.SecurePair constructor +const socket = new tls.TLSSocket(socket); + +// Direct import +import { TLSSocket } from 'node:tls'; +const socket2 = new TLSSocket(socket); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests copy/expected/test-crucial-file.js b/recipes/tls-securepair-to-tlssocket/tests copy/expected/test-crucial-file.js new file mode 100644 index 00000000..bfec68e3 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests copy/expected/test-crucial-file.js @@ -0,0 +1,10 @@ +const { TLSSocket } = require('node:tls'); +const { unrelated } = require('other-module'); + +const socket = new TLSSocket(socket); + +socket.on('error', (err) => { + console.error(err); +}); + +// Obsolete properties \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests copy/expected/test-edge-variable-name-file.js b/recipes/tls-securepair-to-tlssocket/tests copy/expected/test-edge-variable-name-file.js new file mode 100644 index 00000000..97a7dbb8 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests copy/expected/test-edge-variable-name-file.js @@ -0,0 +1,7 @@ +const { TLSSocket } = require('node:tls'); + +// Completely arbitrary variable name +const socket = new TLSSocket(socket); + +// Usage +socket.doSomething(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests copy/expected/test-esm-file.js b/recipes/tls-securepair-to-tlssocket/tests copy/expected/test-esm-file.js new file mode 100644 index 00000000..69043738 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests copy/expected/test-esm-file.js @@ -0,0 +1,8 @@ +import tls from 'node:tls'; +import { TLSSocket } from 'node:tls'; + +// Case 1: Via namespace +const socket1 = new tls.TLSSocket(socket); + +// Case 2: Direct +const socket2 = new TLSSocket(socket); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests copy/expected/test-multiple-variable-file.js b/recipes/tls-securepair-to-tlssocket/tests copy/expected/test-multiple-variable-file.js new file mode 100644 index 00000000..cfb06417 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests copy/expected/test-multiple-variable-file.js @@ -0,0 +1,7 @@ +const tls = require('node:tls'); + +const socket = new tls.TLSSocket(socket); +const mySocket = new tls.TLSSocket(socket); +const secureSocketInstance = new tls.TLSSocket(socket); + +// Specific cleanup for each variable \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests copy/expected/test-scoping-file.js b/recipes/tls-securepair-to-tlssocket/tests copy/expected/test-scoping-file.js new file mode 100644 index 00000000..433ca37d --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests copy/expected/test-scoping-file.js @@ -0,0 +1,14 @@ +const tls = require('node:tls'); + +class ConnectionManager { + constructor() { + if (true) { + const socket = new tls.TLSSocket(socket); + this.init(socket); + + if (socket.cleartext) { + console.log("cleaning"); + } + } + } +} \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests copy/input/basic-test-file-3.js b/recipes/tls-securepair-to-tlssocket/tests copy/input/basic-test-file-3.js new file mode 100644 index 00000000..a17b4487 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests copy/input/basic-test-file-3.js @@ -0,0 +1,13 @@ +const tls = require('node:tls'); +const fs = require('fs'); // Code non lié + +function createSecureConnection() { + // Using tls.SecurePair constructor + const pair = new tls.SecurePair(); + + // Ces lignes doivent disparaître + const cleartext = pair.cleartext; + const encrypted = pair.encrypted; + + return pair; +} \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests copy/input/file-1.js b/recipes/tls-securepair-to-tlssocket/tests copy/input/file-1.js new file mode 100644 index 00000000..9ce8efdd --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests copy/input/file-1.js @@ -0,0 +1,10 @@ +const tls = require('node:tls'); + +// Using tls.SecurePair constructor +const pair = new tls.SecurePair(); +const cleartext = pair.cleartext; +const encrypted = pair.encrypted; + +// Direct import +const { SecurePair } = require('node:tls'); +const pair2 = new SecurePair(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests copy/input/file-2.js b/recipes/tls-securepair-to-tlssocket/tests copy/input/file-2.js new file mode 100644 index 00000000..fe8c30bc --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests copy/input/file-2.js @@ -0,0 +1,10 @@ +import tls from 'node:tls'; + +// Using tls.SecurePair constructor +const pair = new tls.SecurePair(); +const cleartext = pair.cleartext; +const encrypted = pair.encrypted; + +// Direct import +import { SecurePair } from 'node:tls'; +const pair2 = new SecurePair(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests copy/input/test-crucial-file.js b/recipes/tls-securepair-to-tlssocket/tests copy/input/test-crucial-file.js new file mode 100644 index 00000000..bdf18fb4 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests copy/input/test-crucial-file.js @@ -0,0 +1,12 @@ +const { SecurePair } = require('node:tls'); +const { unrelated } = require('other-module'); + +const pair = new SecurePair(); + +pair.on('error', (err) => { + console.error(err); +}); + +// Obsolete properties +console.log(pair.cleartext); +console.log(pair.encrypted); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests copy/input/test-edge-variable-name-file.js b/recipes/tls-securepair-to-tlssocket/tests copy/input/test-edge-variable-name-file.js new file mode 100644 index 00000000..95934a99 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests copy/input/test-edge-variable-name-file.js @@ -0,0 +1,8 @@ +const { SecurePair } = require('node:tls'); + +// Completely arbitrary variable name +const item = new SecurePair(); + +// Usage +item.doSomething(); +item.cleartext.read(); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests copy/input/test-esm-file.js b/recipes/tls-securepair-to-tlssocket/tests copy/input/test-esm-file.js new file mode 100644 index 00000000..cc3ea4b8 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests copy/input/test-esm-file.js @@ -0,0 +1,10 @@ +import tls from 'node:tls'; +import { SecurePair } from 'node:tls'; + +// Case 1: Via namespace +const pair1 = new tls.SecurePair(); +const t1 = pair1.cleartext; + +// Case 2: Direct +const pair2 = new SecurePair(); +const t2 = pair2.encrypted; \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests copy/input/test-multiple-variable-file.js b/recipes/tls-securepair-to-tlssocket/tests copy/input/test-multiple-variable-file.js new file mode 100644 index 00000000..59b6a641 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests copy/input/test-multiple-variable-file.js @@ -0,0 +1,9 @@ +const tls = require('node:tls'); + +const pair = new tls.SecurePair(); +const myPair = new tls.SecurePair(); +const securePairInstance = new tls.SecurePair(); + +// Specific cleanup for each variable +pair.cleartext.write('hello'); +myPair.encrypted.write('world'); \ No newline at end of file diff --git a/recipes/tls-securepair-to-tlssocket/tests copy/input/test-scoping-file.js b/recipes/tls-securepair-to-tlssocket/tests copy/input/test-scoping-file.js new file mode 100644 index 00000000..ded038b5 --- /dev/null +++ b/recipes/tls-securepair-to-tlssocket/tests copy/input/test-scoping-file.js @@ -0,0 +1,14 @@ +const tls = require('node:tls'); + +class ConnectionManager { + constructor() { + if (true) { + const pair = new tls.SecurePair(); + this.init(pair); + + if (pair.cleartext) { + console.log("cleaning"); + } + } + } +} \ No newline at end of file