diff --git a/apps/site/authors.json b/apps/site/authors.json index 3afd0cd6f7631..e3901173461df 100644 --- a/apps/site/authors.json +++ b/apps/site/authors.json @@ -227,7 +227,7 @@ "name": "Richard Lau", "website": "https://github.com/richardlau" }, - "Richie McColl": { + "richiemccoll": { "id": "richiemccoll", "name": "Richie McColl", "website": "https://github.com/richiemccoll" diff --git a/apps/site/pages/en/blog/migrations/axios-to-fetch.mdx b/apps/site/pages/en/blog/migrations/axios-to-fetch.mdx new file mode 100644 index 0000000000000..cb1f07a590d56 --- /dev/null +++ b/apps/site/pages/en/blog/migrations/axios-to-fetch.mdx @@ -0,0 +1,160 @@ +--- +date: '2026-05-09T00:00:00.000Z' +category: migrations +title: Axios to WHATWG Fetch +layout: blog-post +author: AugustinMauroy +--- + +# Migrate from Axios to WHATWG Fetch + +This codemod transforms code using [Axios](https://github.com/axios/axios) to leverage the [WHATWG Fetch API](https://fetch.spec.whatwg.org/), which is now natively available in Node.js. + +## Why doing this? + +- **Native Support**: Fetch is built into Node.js, eliminating the need for external libraries and their associated maintenance overhead. +- **Improved Performance**: Fetch is optimized for modern JavaScript runtimes, often resulting in better performance compared to Axios. +- **Better Standards Compliance**: Fetch adheres closely to web standards, making it easier to write cross-platform code that works both in Node.js and browsers. +- **Reduced Security Risks**: Removing Axios eliminates potential vulnerabilities associated with third-party dependencies, enhancing the security of your application. + +## Node.js Version Requirements + +- Node.js v18.0.0 or later (Fetch API is available but marked experimental) +- Node.js v21.0.0 or later (Fetch API is stable) + +> If your package currently supports Node.js versions earlier than v18.0.0, you cannot migrate to the Fetch API without dropping support for those versions. +> This requires bumping the major version of your package AND updating the engines field in your package.json to require Node.js >= v18.0.0. + +## Supported Transformations + +The codemod supports the following Axios methods and converts them to their Fetch equivalents: + +- `axios.request(config)` +- `axios.get(url[, config])` +- `axios.delete(url[, config])` +- `axios.head(url[, config])` +- `axios.options(url[, config])` +- `axios.post(url[, data[, config]])` +- `axios.put(url[, data[, config]])` +- `axios.patch(url[, data[, config]])` +- `axios.postForm(url[, data[, config]])` +- `axios.putForm(url[, data[, config]])` +- `axios.patchForm(url[, data[, config]])` + +## Examples + +### GET Request + +```diff +const base = 'https://dummyjson.com/todos'; + +- const all = await axios.get(base); ++ const all = await fetch(base).then(async (res) => Object.assign(res, { data: await res.json() })).catch(() => null); + console.log('\nGET /todos ->', all.status); + console.log(`Preview: ${all.data.todos.length} todos`); +``` + +### POST Request + +```diff +const base = 'https://dummyjson.com/todos'; + +- const created = await axios.post( +- `${base}/add`, { +- todo: 'Use DummyJSON in the project', +- completed: false, +- userId: 5, +- }, { +- headers: { 'Content-Type': 'application/json' } +- } +- ); ++ const created = await fetch(`${base}/add`, { ++ method: 'POST', ++ headers: { 'Content-Type': 'application/json' }, ++ body: JSON.stringify({ ++ todo: 'Use DummyJSON in the project', ++ completed: false, ++ userId: 5, ++ }), ++ }).then(async (res) => Object.assign(res, { data: await res.json() })); + console.log('\nPOST /todos/add ->', created.status); + console.log('Preview:', created.data?.id ? `created id ${created.data.id}` : JSON.stringify(created.data).slice(0,200)); +``` + +### POST Form Request + +```diff +const formEndpoint = '/submit'; + +- const created = await axios.postForm(formEndpoint, { +- title: 'Form Demo', +- completed: false, +- }); ++ const created = await fetch(formEndpoint, { ++ method: 'POST', ++ body: new URLSearchParams({ ++ title: 'Form Demo', ++ completed: false, ++ }), ++ }).then(async (res) => Object.assign(res, { data: await res.json() })); + console.log('Preview:', created.data); +``` + +### PUT Request + +```diff +const base = 'https://dummyjson.com/todos'; + +- const updatedPut = await axios.put( +- `${base}/1`, +- { completed: false }, +- { headers: { 'Content-Type': 'application/json' } } +- ); ++ const updatedPut = await fetch(`${base}/1`, { ++ method: 'PUT', ++ headers: { 'Content-Type': 'application/json' }, ++ body: JSON.stringify({ completed: false }), ++ }).then(async (res) => Object.assign(res, { data: await res.json() })); + console.log('\nPUT /todos/1 ->', updatedPut.status); + console.log('Preview:', updatedPut.data?.completed !== undefined ? `completed=${updatedPut.data.completed}` : JSON.stringify(updatedPut.data).slice(0,200)); +``` + +### DELETE Request + +```diff +const base = 'https://dummyjson.com/todos'; + +- const deleted = await axios.delete(`${base}/1`); ++ const deleted = await fetch(`${base}/1`, { method: 'DELETE' }) ++ .then(async (res) => Object.assign(res, { data: await res.json() })); + console.log('\nDELETE /todos/1 ->', deleted.status); + console.log('Preview:', deleted.data ? JSON.stringify(deleted.data).slice(0,200) : typeof deleted.data); +``` + +### `request` Axios Method + +```diff +const base = 'https://dummyjson.com/todos'; + +- const customRequest = await axios.request({ +- url: `${base}/1`, +- method: 'PATCH', +- headers: { 'Content-Type': 'application/json' }, +- data: { completed: true }, +- }); ++ const customRequest = await fetch(`${base}/1`, { ++ method: 'PATCH', ++ headers: { 'Content-Type': 'application/json' }, ++ body: JSON.stringify({ completed: true }), ++ }).then(async (res) => Object.assign(res, { data: await res.json() })); +console.log('\nPATCH /todos/1 ->', customRequest.status); +console.log('Preview:', customRequest.data?.completed !== undefined ? `completed=${customRequest.data.completed}` : JSON.stringify(customRequest.data).slice(0,200)); +``` + +## Unsupported APIs + +The codemod does not yet cover Axios features outside of direct request helpers, such as interceptors, cancel tokens, or instance configuration from `axios.create()`. + +## Recognition + +We would like to thank the maintainers of [Axios](https://github.com/axios/axios) for their support of the package over time and for its contributions to the ecosystem. diff --git a/apps/site/pages/en/blog/migrations/chalk-to-styletext.mdx b/apps/site/pages/en/blog/migrations/chalk-to-styletext.mdx index a2c4a011576d3..05c4400410892 100644 --- a/apps/site/pages/en/blog/migrations/chalk-to-styletext.mdx +++ b/apps/site/pages/en/blog/migrations/chalk-to-styletext.mdx @@ -8,11 +8,9 @@ author: richiemccoll # Migrate from Chalk to Node.js util styleText -## `chalk-to-util-styletext` - This codemod aims to help you reduce external dependencies by transforming chalk method calls to use the native Node.js styling functionality. It will also handle automatic removal of the [`chalk`](https://github.com/chalk/chalk) package from the package.json. -### Compatible Features: +## Compatible Features: - Basic colors (red, green, blue, yellow, etc.) - Bright colors (redBright, greenBright, etc.) @@ -21,16 +19,14 @@ This codemod aims to help you reduce external dependencies by transforming chalk - Style chaining via array syntax - Environment variable support (NO_COLOR, NODE_DISABLE_COLORS, FORCE_COLOR) -### Incompatible Features: +## Incompatible Features: - Custom RGB colors (chalk.rgb(), chalk.hex()) - 256-color palette (chalk.ansi256()) - Template literal syntax (chalk...``) - Advanced modifiers with limited terminal support (overline, blink, etc.) -### Prerequisites: - -#### Node.js Version Requirements +## Node.js Version Requirements - Node.js v20.12.0 or later (for util.styleText) - `util.styleText` became stable in Node.js v22.13.0 (and v23.5.0) @@ -38,7 +34,7 @@ This codemod aims to help you reduce external dependencies by transforming chalk > If your package currently supports Node.js versions earlier than v20.12.0, you cannot migrate to util.styleText without dropping support for those versions. > This requires bumping the major version of your package AND updating the engines field in your package.json to require Node.js >= v20.12.0. -### Usage: +## Usage: The source code for this codemod can be found in the [chalk-to-util-styletext directory](https://github.com/nodejs/userland-migrations/tree/main/recipes/chalk-to-util-styletext). @@ -48,33 +44,23 @@ You can find this codemod in the [Codemod Registry](https://app.codemod.com/regi npx codemod @nodejs/chalk-to-util-styletext ``` -### Example: +## Example: -```js displayName="Before" -import chalk from 'chalk'; +```diff +- import chalk from 'chalk'; ++ import { styleText } from 'node:util'; -console.log(chalk.red('Error message')); +- console.log(chalk.red('Error message')); ++ console.log(styleText('red', 'Error message')); -console.log(chalk.red.bold('Important error')); +- console.log(chalk.green.underline('Success with emphasis')); ++ console.log(styleText(['green', 'underline'], 'Success with emphasis')); -const red = chalk.red; +- const red = chalk.red; ++ const red = (text) => styleText('red', text); +- const boldBlue = chalk.blue.bold; ++ const boldBlue = (text) => styleText(['blue', 'bold'], text); console.log(red('Error')); - -const boldBlue = chalk.blue.bold; -console.log(boldBlue('Info')); -``` - -```js displayName="After" -import { styleText } from 'node:util'; - -console.log(styleText('red', 'Error message')); - -console.log(styleText(['red', 'bold'], 'Important error')); - -const red = text => styleText('red', text); -console.log(red('Error')); - -const boldBlue = text => styleText(['blue', 'bold'], text); console.log(boldBlue('Info')); ``` diff --git a/apps/site/pages/en/blog/migrations/v12-to-v14.mdx b/apps/site/pages/en/blog/migrations/v12-to-v14.mdx index 58d1753f524d8..16bf51667c01b 100644 --- a/apps/site/pages/en/blog/migrations/v12-to-v14.mdx +++ b/apps/site/pages/en/blog/migrations/v12-to-v14.mdx @@ -30,23 +30,20 @@ The source code for this codemod can be found in the [util-print-to-console-log You can find this codemod in the [Codemod Registry](https://app.codemod.com/registry/@nodejs/util-print-to-console-log). ```bash -npx codemod run @nodejs/create-require-from-path +npx codemod run @nodejs/util-print-to-console-log ``` ### Example: -```js displayName="Before" -const util = require('node:util'); - -util.print('Hello world'); -util.puts('Hello world'); -util.debug('Hello world'); -util.error('Hello world'); -``` - -```js displayName="After" -console.log('Hello world'); -console.log('Hello world'); -console.error('Hello world'); -console.error('Hello world'); +```diff +- const util = require("node:util"); + +- util.print("Hello world"); ++ console.log("Hello world"); +- util.puts("Hello world"); ++ console.log("Hello world"); +- util.debug("Hello world"); ++ console.error("Hello world"); +- util.error("Hello world"); ++ console.error("Hello world"); ``` diff --git a/apps/site/pages/en/blog/migrations/v14-to-v16.mdx b/apps/site/pages/en/blog/migrations/v14-to-v16.mdx index d3dae0e804cc7..a59e413a94cbc 100644 --- a/apps/site/pages/en/blog/migrations/v14-to-v16.mdx +++ b/apps/site/pages/en/blog/migrations/v14-to-v16.mdx @@ -30,18 +30,15 @@ npx codemod run @nodejs/create-require-from-path ### Example: -```js displayName="Before" -import { createRequireFromPath } from 'node:module'; +```diff +- const { createRequireFromPath } = require('node:module'); ++ const { createRequire } = require('node:module'); -const requireFromPath = createRequireFromPath('/path/to/module'); -const myModule = requireFromPath('./myModule.cjs'); -``` - -```js displayName="After" -import { createRequire } from 'node:module'; +- const requireFromPath = createRequireFromPath('/path/to/module'); ++ const require = createRequire('/path/to/module'); -const require = createRequire('/path/to/module'); -const myModule = require('./myModule.cjs'); +- const myModule = requireFromPath('./myModule.cjs'); ++ const myModule = require('./myModule.cjs'); ``` ## `process-main-module` @@ -60,20 +57,13 @@ npx codemod run @nodejs/process-main-module ### Example: -```js displayName="Before" -if (process.mainModule === 'mod.js') { - // cli thing -} else { - // module thing -} -``` - -```js displayName="After" -if (require.main === 'mod.js') { - // cli thing -} else { - // module thing -} +```diff +- if (process.mainModule === "mod.js") { ++ if (require.main === "mod.js") { + // cli thing + } else { + // module thing + } ``` ## `rmdir` @@ -92,30 +82,21 @@ npx codemod run @nodejs/rmdir ### Example: -```js displayName="Before" -const fs = require('node:fs'); - -// Using fs.rmdir with the recursive option -fs.rmdir(path, { recursive: true }, callback); - -// Using fs.rmdirSync with the recursive option -fs.rmdirSync(path, { recursive: true }); - -// Using fs.promises.rmdir with the recursive option -fs.promises.rmdir(path, { recursive: true }); -``` - -```js displayName="After" -const fs = require('node:fs'); - -// Using fs.rm with recursive and force options -fs.rm(path, { recursive: true, force: true }, callback); - -// Using fs.rmSync with recursive and force options -fs.rmSync(path, { recursive: true, force: true }); - -// Using fs.promises.rm with recursive and force options -fs.promises.rm(path, { recursive: true, force: true }); +```diff + // Using fs.rmdir with the recursive option +- fs.rmdir(path, { recursive: true }, callback); ++ // Using fs.rm with recursive and force options ++ fs.rm(path, { recursive: true, force: true }, callback); + + // Using fs.rmdirSync with the recursive option +- fs.rmdirSync(path, { recursive: true }); ++ // Using fs.rmSync with recursive and force options ++ fs.rmSync(path, { recursive: true, force: true }); + + // Using fs.promises.rmdir with the recursive option +- fs.promises.rmdir(path, { recursive: true }); ++ // Using fs.promises.rm with recursive and force options ++ fs.promises.rm(path, { recursive: true, force: true }); ``` ## `tmpDir-to-tmpdir` @@ -134,14 +115,9 @@ npx codemod run @nodejs/tmpDir-to-tmpdir ### Example: -```js displayName="Before" -import { tmpDir } from 'node:os'; - -const foo = tmpDir(); -``` - -```js displayName="After" -import { tmpdir } from 'node:os'; - -const foo = tmpdir(); +```diff +- import { tmpDir } from 'node:os'; ++ import { tmpdir } from 'node:os'; +- const foo = tmpDir() ++ const foo = tmpdir() ``` diff --git a/apps/site/pages/en/blog/migrations/v16-to-v18.mdx b/apps/site/pages/en/blog/migrations/v16-to-v18.mdx new file mode 100644 index 0000000000000..b469c14b80ee2 --- /dev/null +++ b/apps/site/pages/en/blog/migrations/v16-to-v18.mdx @@ -0,0 +1,51 @@ +--- +date: '2025-10-28T00:02:00.000Z' +category: migrations +title: Node.js v16 to v18 +layout: blog-post +author: AugustinMauroy +--- + +# Node.js v16 to v18 + + + This article covers a part of the migration from Node.js v16 to v18. The + userland migrations team is working on more codemods to help you with the + migration. + + +This page provides a list of codemods to help you migrate your code from Node.js v16 to v18. + +## `err-invalid-callback` + +In Node.js v18, the [DEP0159](https://nodejs.org/api/deprecations.html#DEP0159) deprecation was introduced, which deprecated the `ERR_INVALID_CALLBACK` error code in favor of `ERR_INVALID_ARG_TYPE`. This codemod will help you replace any references to the old error code with the new one. + +The source code for this codemod can be found in the [err-invalid-callback directory](https://github.com/nodejs/userland-migrations/tree/main/recipes/err-invalid-callback). + +You can find this codemod in the [Codemod Registry](https://app.codemod.com/registry/@nodejs/err-invalid-callback). + +```bash +npx codemod run @nodejs/err-invalid-callback +``` + +### Example: + +```diff + try { + fs.readFile("file.txt", "invalid-callback"); + } catch (err) { +- if (err.code === "ERR_INVALID_CALLBACK") { ++ if (err.code === "ERR_INVALID_ARG_TYPE") { + console.error("Invalid callback provided"); + } + } +``` + +Also handles deduplication when both codes were already checked: + +```diff + const isCallbackError = +- err.code === "ERR_INVALID_CALLBACK" || +- err.code === "ERR_INVALID_ARG_TYPE"; ++ err.code === "ERR_INVALID_ARG_TYPE"; +``` diff --git a/apps/site/pages/en/blog/migrations/v20-to-v22.mdx b/apps/site/pages/en/blog/migrations/v20-to-v22.mdx index b4bfbe8071ffa..3703da6e63481 100644 --- a/apps/site/pages/en/blog/migrations/v20-to-v22.mdx +++ b/apps/site/pages/en/blog/migrations/v20-to-v22.mdx @@ -1,5 +1,5 @@ --- -date: '2025-10-28T00:02:00.000Z' +date: '2025-10-28T00:03:00.000Z' category: migrations title: Node.js v20 to v22 layout: blog-post @@ -34,10 +34,49 @@ npx codemod run @nodejs/import-assertions-to-attributes ### Example: -```js displayName="Before" -import jsonData from './data.json' assert { type: 'json' }; +```diff +- import data from './data.json' assert { type: 'json' }; ++ import data from './data.json' with { type: 'json' }; ``` -```js displayName="After" -import jsonData from './data.json' with { type: 'json' }; +## `crypto-createcipheriv-migration` + +Migrates deprecated `crypto.createCipher()` / `crypto.createDecipher()` usage to the supported `crypto.createCipheriv()` / `crypto.createDecipheriv()` APIs with explicit key derivation and IV handling. + +Node.js removed `crypto.createCipher()` and `crypto.createDecipher()` in v22.0.0 ([DEP0106](https://nodejs.org/api/deprecations.html#DEP0106)). The legacy helpers derived keys with MD5 and no salt, and silently reused static IVs. This codemod replaces those calls with the modern, explicit APIs and scaffolds secure key derivation and IV management. + +The source code for this codemod can be found in the [crypto-createcipheriv-migration directory](https://github.com/nodejs/userland-migrations/tree/main/recipes/crypto-createcipheriv-migration). + +You can find this codemod in the [Codemod Registry](https://app.codemod.com/registry/@nodejs/crypto-createcipheriv-migration). + +```bash +npx codemod run @nodejs/crypto-createcipheriv-migration ``` + +### What it does + +- Replaces invocations of `createCipher()` / `createDecipher()` with `createCipheriv()` / `createDecipheriv()`. +- Inserts scaffolding that derives keys with `crypto.scryptSync()` and generates random salts and IVs. +- Reminds developers to persist salt + IV for decryption and to adjust key/IV lengths per algorithm. +- Updates destructured imports to include the new helpers (`createCipheriv`, `createDecipheriv`, `randomBytes`, `scryptSync`). + +### Example + +```diff +- const cipher = crypto.createCipher(algorithm, password); ++ const cipher = (() => { ++ const __dep0106Salt = crypto.randomBytes(16); ++ const __dep0106Key = crypto.scryptSync(password, __dep0106Salt, 32); ++ const __dep0106Iv = crypto.randomBytes(16); ++ // DEP0106: Persist __dep0106Salt and __dep0106Iv alongside the ciphertext so it can be decrypted later. ++ return crypto.createCipheriv(algorithm, __dep0106Key, __dep0106Iv); ++ })(); +``` + +### Important notes + +- The codemod cannot guarantee algorithm-specific key/IV sizes. Review the generated `scryptSync` length and IV length defaults and adjust as needed. +- Decryption snippets include placeholders (`Buffer.alloc(16)`) that must be replaced with the salt and IV stored during encryption. +- If your project already wraps key derivation logic, you may prefer to adapt the generated scaffolding to call existing helpers. +- The generated code is not backward-compatible and will be unable to decrypt data that was encrypted using `createCipher()`. +- The use of scrypt is one possible choice for deriving a key from a password, but you may wish to use Argon2id or PBKDF2 instead. diff --git a/apps/site/pages/en/blog/migrations/v22-to-v24.mdx b/apps/site/pages/en/blog/migrations/v22-to-v24.mdx index f6655aeadbdbd..63478577ac4e8 100644 --- a/apps/site/pages/en/blog/migrations/v22-to-v24.mdx +++ b/apps/site/pages/en/blog/migrations/v22-to-v24.mdx @@ -1,5 +1,5 @@ --- -date: '2025-10-28T00:03:00.000Z' +date: '2025-10-28T00:04:00.000Z' category: migrations title: Node.js v22 to v24 layout: blog-post @@ -83,38 +83,29 @@ npx codemod run @nodejs/crypto-rsa-pss-update #### Example -```js displayName="Before" -const crypto = require('node:crypto'); +```diff +const crypto = require("node:crypto"); crypto.generateKeyPair( - 'rsa-pss', + "rsa-pss", { modulusLength: 2048, - hash: 'sha256', - mgf1Hash: 'sha1', +- hash: "sha256", +- mgf1Hash: "sha1", ++ hashAlgorithm: "sha256", ++ mgf1HashAlgorithm: "sha1", saltLength: 32, }, (err, publicKey, privateKey) => { // callback - } -); -``` - -```js displayName="After" -const crypto = require('node:crypto'); - -crypto.generateKeyPair( - 'rsa-pss', - { - modulusLength: 2048, - hashAlgorithm: 'sha256', - mgf1HashAlgorithm: 'sha1', - saltLength: 32, }, - (err, publicKey, privateKey) => { - // callback - } ); + +crypto.generateKeyPairSync("rsa-pss", { + modulusLength: 2048, +- hash: "sha256", ++ hashAlgorithm: "sha256", +}); ``` ### `dirent-path-to-parent-path` @@ -131,40 +122,26 @@ npx codemod run @nodejs/dirent-path-to-parent-path #### Examples -##### readdir +### readdir -```js displayName="Before" -const { readdir } = require('node:fs/promises'); -const entries = await readdir('/some/path', { withFileTypes: true }); -for (const dirent of entries) { - console.log(dirent.path); -} -``` - -```js displayName="After" -const { readdir } = require('node:fs/promises'); -const entries = await readdir('/some/path', { withFileTypes: true }); -for (const dirent of entries) { - console.log(dirent.parentPath); -} +```diff + const { readdir } = require('node:fs/promises'); + const entries = await readdir('/some/path', { withFileTypes: true }); + for (const dirent of entries) { +- console.log(dirent.path); ++ console.log(dirent.parentPath); + } ``` -##### opendir +### opendir -```js displayName="Before" -import { opendir } from 'node:fs/promises'; -const dir = await opendir('./'); -for await (const dirent of dir) { - console.log(`Found ${dirent.name} in ${dirent.path}`); -} -``` - -```js displayName="After" -import { opendir } from 'node:fs/promises'; -const dir = await opendir('./'); -for await (const dirent of dir) { - console.log(`Found ${dirent.name} in ${dirent.parentPath}`); -} +```diff + import { opendir } from 'node:fs/promises'; + const dir = await opendir('./'); + for await (const dirent of dir) { +- console.log(`Found ${dirent.name} in ${dirent.path}`); ++ console.log(`Found ${dirent.name} in ${dirent.parentPath}`); + } ``` ### `fs-access-mode-constants` @@ -183,18 +160,13 @@ npx codemod run @nodejs/fs-access-mode-constants #### Example -```js displayName="Before" -const fs = require('node:fs'); +```diff + const fs = require('node:fs'); -fs.access('/path/to/file', fs.F_OK, callback); -fs.access('/path/to/file', fs.R_OK | fs.W_OK, callback); -``` - -```js displayName="After" -const fs = require('node:fs'); - -fs.access('/path/to/file', fs.constants.F_OK, callback); -fs.access('/path/to/file', fs.constants.R_OK | fs.constants.W_OK, callback); +- fs.access('/path/to/file', fs.F_OK, callback); ++ fs.access('/path/to/file', fs.constants.F_OK, callback); +- fs.access('/path/to/file', fs.R_OK | fs.W_OK, callback); ++ fs.access('/path/to/file', fs.constants.R_OK | fs.constants.W_OK, callback); ``` ### `fs-truncate-to-ftruncate` @@ -211,35 +183,67 @@ npx codemod run @nodejs/fs-truncate-fd-deprecation #### Example -```js displayName="Before" -const { truncate, open, close } = require('node:fs'); +```diff +- const { truncate, open, close } = require('node:fs'); ++ const { ftruncate, open, close } = require('node:fs'); -open('file.txt', 'w', (err, fd) => { - if (err) throw err; - truncate(fd, 10, err => { + open('file.txt', 'w', (err, fd) => { if (err) throw err; - close(fd, () => {}); +- truncate(fd, 10, (err) => { ++ ftruncate(fd, 10, (err) => { + if (err) throw err; + close(fd, () => {}); + }); }); -}); ``` -```js displayName="After" -const { ftruncate, open, close } = require('node:fs'); +### `http2-priority-removal` -open('file.txt', 'w', (err, fd) => { - if (err) throw err; - ftruncate(fd, 10, err => { - if (err) throw err; - close(fd, () => {}); - }); +This recipe removes HTTP/2 priority-related options and methods since priority signaling has been deprecated. + +See [DEP0194](https://nodejs.org/api/deprecations.html#DEP0194). + +The source code for this codemod can be found in the [http2-priority-removal directory](https://github.com/nodejs/userland-migrations/tree/main/recipes/http2-priority-removal). + +You can find this codemod in the [Codemod Registry](https://app.codemod.com/registry/@nodejs/http2-priority-removal). + +```bash +npx codemod run @nodejs/http2-priority-removal +``` + +## What this codemod does + +- Removes the `priority` property from `http2.connect()` call options +- Removes the `priority` property from `session.request()` call options +- Removes entire `stream.priority()` method call statements +- Removes the `priority` property from `client.settings()` call options +- Handles both CommonJS (`require()`) and ESM (`import`) imports + +## Examples + +```diff +import http2 from "node:http2"; + +const session = http2.connect("https://example.com", { +- priority: { weight: 16, parent: 0, exclusive: false } }); + +const stream = session.request({ + ":path": "/api/data", +- priority: { weight: 32 } +}); +- stream.priority({ exclusive: true, parent: 0, weight: 128 }); + +const client = http2.connect("https://example.com"); +-client.settings({ enablePush: false, priority: true }); ++client.settings({ enablePush: false }); ``` ### `process-assert-to-node-assert` -This recipe transforms the usage of `process.assert` to use `node:assert` module. +In Node.js v23 the [DEP0100](https://nodejs.org/api/deprecations.html#DEP0100) deprecation was grantted to End of Life, and `process.assert` was removed in favor of using the `assert` module directly. This codemod will help you replace any references to `process.assert` with the appropriate import of the `assert` module and usage of `assert()`. -See [DEP0100](https://nodejs.org/api/deprecations.html#DEP0100). +The source code for this codemod can be found in the [process-assert-to-node-assert directory](https://github.com/nodejs/userland-migrations/tree/main/recipes/process-assert-to-node-assert). You can find this codemod in the [Codemod Registry](https://app.codemod.com/registry/@nodejs/process-assert-to-node-assert). @@ -249,15 +253,41 @@ npx codemod run @nodejs/process-assert-to-node-assert #### Example -```js displayName="Before" -process.assert(condition, 'Assertion failed'); -``` - -```js displayName="After" -import assert from 'node:assert'; -assert(condition, 'Assertion failed'); +```diff ++ import assert from "node:assert"; +- process.assert(condition, "Assertion failed"); ++ assert(condition, "Assertion failed"); ``` #### Additional Notes This codemod use [`fs` capability](https://docs.codemod.com/jssg/security) to read the `package.json` file and determine if the project is using ES modules or CommonJS. Based on this information, it adds the appropriate import statement for the `assert` module. + +### `tls-create-secure-pair-to-tls-socket` + +This recipe transforms the usage from the deprecated `createSecurePair()` to `TLSSocket()`. + +See [DEP0064](https://nodejs.org/api/deprecations.html#dep0064-tlscreatesecurepair). + +The source code for this codemod can be found in the [tls-create-secure-pair-to-tls-socket directory](https://github.com/nodejs/userland-migrations/tree/main/recipes/tls-create-secure-pair-to-tls-socket). + +You can find this codemod in the [Codemod Registry](https://app.codemod.com/registry/@nodejs/tls-create-secure-pair-to-tls-socket). + +```bash +npx codemod run @nodejs/tls-create-secure-pair-to-tls +``` + +## Examples + +```diff +-const { createSecurePair } = require('node:tls'); ++const { TLSSocket } = require('node:tls'); + +-const pair = createSecurePair(credentials, true, true, false); ++const socket = new TLSSocket(underlyingSocket, { ++ secureContext: credentials, ++ isServer: true, ++ requestCert: true, ++ rejectUnauthorized: false ++}); +```