Codemod Registry
Explore community-led codemods to migrate, optimize, and transform your codebase.
Ready to contribute?
Build your own codemod and share it with the community.
Explore community-led codemods to migrate, optimize, and transform your codebase.
Build your own codemod and share it with the community.
Explore community-led codemods to migrate, optimize, and transform your codebase.
# Correct TypeScript Specifiers This package transforms import specifiers from the old `tsc` (TypeScript's compiler) requirement of using `.js` file extensions in source-code to import files that are actually typescript; the corrected specifiers enable source-code to be runnable by standards-compliant software like Node.js. This is a one-and-done process, and the updated source-code should be committed to your version control (eg git); thereafter, source-code import statements should be authored compliant with the ECMAScript (JavaScript) standard. > [!TIP] > Those using `tsc` to compile will need to enable [`rewriteRelativeImportExtensions`](https://www.typescriptlang.org/tsconfig/#rewriteRelativeImportExtensions); using `tsc` for only type-checking (ex via a lint/test step like `npm run test:types`) needs [`allowImportingTsExtensions`](https://www.typescriptlang.org/tsconfig/#allowImportingTsExtensions) (and some additional compile options—see the cited documentation); This package does not just blindly find & replace file extensions within specifiers: It confirms that the replacement specifier actually exists; in ambiguous cases (such as two files with the same basename in the same location but different relevant file extensions like `/tmp/foo.js` and `/tmp/foo.ts`), it logs an error, skips that specifier, and continues processing. > [!CAUTION] > This package does not confirm that imported modules contain the desired export(s). This _shouldn't_ actually ever result in a problem because ambiguous cases are skipped (so if there is a problem, it existed before the migration started). Merely running your source-code after the mirgration completes will confirm all is well (if there are problems, node will error, citing the problems). > [!TIP] > Node.js requires the `type` keyword be present on type imports. For own code, this package usually handles that. However, in some cases and for node modules, it does not. Robust tooling already exists that will automatically fix this, such as > > * [`use-import-type` via biome](https://biomejs.dev/linter/rules/use-import-type/) > * [`typescript/no-import-type-side-effects` via oxlint](https://oxc.rs/docs/guide/usage/linter/rules/typescript/no-import-type-side-effects) > * [`consistent-type-imports` via typescript-lint](https://typescript-eslint.io/rules/consistent-type-imports) > > If your source code needs that, first run this codemod and then one of those fixers. ## Running > [!CAUTION] > This will change your source-code. Commit any unsaved changes before running this package. > [!IMPORTANT] > [`--experimental-import-meta-resolve`](https://nodejs.org/api/cli.html#--experimental-import-meta-resolve) MUST be enabled; the feature is not really experimental—it's nonstandard because it's not relevant for browsers. ```console $ NODE_OPTIONS="--experimental-import-meta-resolve" \ npx codemod@latest correct-ts-specifiers ``` ### Monorepos For best results, run this _within_ each workspace of the monorepo. ```text project-root/ ├ workspaces/ ├ foo/ ←--------- RUN HERE ├ … ├ package.json └ tsconfig.json └ bar/ ←--------- RUN HERE ├ … ├ package.json └ tsconfig.json └ utils/ ←--------- RUN HERE ├ qux.js └ zed.js ``` ## Supported cases * no file extension → `.cts`, `.mts`, `.js`, `.ts`, `.d.cts`, `.d.mts`, or `.d.ts` * `.cjs` → `.cts`, `.mjs` → `.mts`, `.js` → `.ts` * `.js` → `.d.cts`, `.d.mts`, or `.d.ts` * [Package.json subpath imports](https://nodejs.org/api/packages.html#subpath-imports) * [tsconfig paths](https://www.typescriptlang.org/tsconfig/#paths) (via [`@nodejs-loaders/alias`](https://github.com/JakobJingleheimer/nodejs-loaders/blob/main/packages/alias?tab=readme-ov-file)) * In order to subsequently run code via node, you will need to add this (or another) loader to your own project. Or, switch to [subimports](https://nodejs.org/api/packages.html#subpath-imports). * Commonjs-like directory specifiers Before: ```ts import { URL } from 'node:url'; import { bar } from '@dep/bar'; import { foo } from 'foo'; import { Bird } from './Bird'; // a directory import { Cat } from './Cat.ts'; import { Dog } from '…/Dog/index.mjs'; // tsconfig paths import { baseUrl } from '#config.js'; // package.json imports export { Zed } from './zed'; export const makeLink = (path: URL) => (new URL(path, baseUrl)).href; const nil = await import('./nil.js'); const bird = new Bird('Tweety'); const cat = new Cat('Milo'); const dog = new Dog('Otis'); ``` After: ```ts import { URL } from 'node:url'; import { bar } from '@dep/bar'; import { foo } from 'foo'; import { Bird } from './Bird/index.ts'; import { Cat } from './Cat.ts'; import { Dog } from '…/Dog/index.mts'; // tsconfig paths import { baseUrl } from '#config.js'; // package.json imports export type { Zed } from './zed.d.ts'; export const makeLink = (path: URL) => (new URL(path, baseUrl)).href; const nil = await import('./nil.ts'); const bird = new Bird('Tweety'); const cat = new Cat('Milo'); const dog = new Dog('Otis'); ```
# DevCycle to OpenFeature Node.js - Update Imports CodeMod This Codemod helps to convert DevCycle Node.js SDK implementations to the OpenFeature Node.js SDK using the DevCycle Provider. It handles the first step of the conversion by updating the packages imports: - Only if the file is using `initializeDevCycle`, removes the imports of `initializeDevCycle`, and replaces those imports with `DevCycleProvider` from `@devcycle/nodejs-server-sdk` - Only if the file is using `DevCycleClient`, removes the import of `DevCycleClient`, and replaces those imports with `DevCycleProvider` from `@devcycle/nodejs-server-sdk` - Replaces `DevCycleUser` type with `EvaluationContext` from `@openfeature/server-sdk` - Add imports for `OpenFeature` from `@openfeature/server-sdk` if the file is using `initializeDevCycle` or `DevCycleClient` ## Before ```ts import { initializeDevCycle, DevCycleClient, } from "@devcycle/nodejs-server-sdk"; ``` ## After ```ts import { DevCycleProvider } from "@devcycle/nodejs-server-sdk"; import { OpenFeature, Client } from "@openfeature/server-sdk"; ```
# DevCycle to OpenFeature Node.js Workflow This Codemod runs a series of DevCycle Codemods in a workflow to convert your Node.js project from using [DevCycle's Node.js Server SDK](https://docs.devcycle.com/sdk/server-side-sdks/node/) to using [OpenFeature's Node.js SDK](https://openfeature.dev/docs/reference/technologies/server/javascript/) with [DevCycle's OpenFeature Provider](https://docs.devcycle.com/sdk/server-side-sdks/node/node-openfeature). The workflows that it runs are: - [Update Imports](https://codemod.com/registry/devcycle-to-openfeature-nodejs-update-imports) - [Initialization Transform](https://codemod.com/registry/devcycle-to-openfeature-nodejs-initialization-transform) - [User Context Transform](https://codemod.com/registry/devcycle-to-openfeature-nodejs-user-context-transform) - [Variable Transform](https://codemod.com/registry/devcycle-to-openfeature-nodejs-variable-transform)
# DevCycle to OpenFeature Node.js - Variable Transform CodeMod This Codemod changes DevCycle variable calls to openfeature flags: - Replace `variableValue()` and `variable()` calls with `get<Type>Value()` and `get<Type>Details()` respectively, where `<Type>` is `Boolean`, `String`, `Number`, or `Object`. - move the first parameter (user/context) to the third parameter for each variable call being coverted. - all Openfeature calls should be awaited. ## Before ```ts const booleanValue = client.variableValue(user, "boolean-key", false); const booleanValue2 = client2.variableValue(user2, "boolean-key-2", false); const booleanVariable = client.variable(user, "boolean-key", false); const stringValue = client.variableValue(user, "string-key", "default"); const stringVariable = client.variable(user, "string-key", "default"); const numberValue = client.variableValue(user, "number-key", 0.0); const numberVariable = client.variable(user, "number-key", 0.0); const objectValue = client.variableValue(user, "object-key", { default: true, }); const objectVariable = client.variable(user, "object-key", { default: true, }); const booleanValue3 = client.variableValue( { targetingKey: "1234" }, "boolean-key", false ); ``` ### After ```ts const booleanValue = await client.getBooleanValue("boolean-key", false, user); const booleanValue2 = await client2.getBooleanValue( "boolean-key-2", false, user2 ); const booleanVariable = await client.getBooleanDetails( "boolean-key", false, user ); const stringValue = await client.getStringValue("string-key", "default", user); const stringVariable = await client.getStringDetails( "string-key", "default", user ); const numberValue = await client.getNumberValue("number-key", 0.0, user); const numberVariable = await client.getNumberDetails("number-key", 0.0, user); const objectValue = await client.getObjectValue( "object-key", { default: true, }, user ); const objectVariable = await client.getObjectDetails( "object-key", { default: true, }, user ); const booleanValue3 = await client.getBooleanValue("boolean-key", false, { targetingKey: "1234", }); ```
# DevCycle to OpenFeature Node.js - User Context Transform CodeMod This Codemod updates the `DevCycleUser` object to an OpenFeature `EvaluationContext` object: - Replace the `DevCycleUser` object / types with an `EvaluationContext` - Rename the `user_id` field to `targetingKey` in the `EvaluationContext` - If the code is using Typescript types where its typed as `DevCycleUser`, update it to use `EvaluationContext` from `@openfeature/server-sdk`. ## Before ```ts export interface DevCycleRequest extends Request { user: DevCycleUser; } const user: DevCycleUser = { user_id: "123", email: "test@test.com", name: "Test User", customData: { custom_field: "custom_value", number_field: 123, boolean_field: true, }, privateCustomData: { private_field: "private_value", }, }; const varValue = devCycleClient.variableValue( { user_id: "123" }, "test-variable", "default" ); const user2 = { user_id: "1234", email: "test@test.com", name: "Test User" }; const boolVarValue = devCycleClient.variable( user2, "test-boolean-variable", false ); ``` ## After ```ts export interface DevCycleRequest extends Request { user: EvaluationContext; } const user: EvaluationContext = { targetingKey: "123", email: "test@test.com", name: "Test User", customData: { custom_field: "custom_value", number_field: 123, boolean_field: true, }, privateCustomData: { private_field: "private_value", }, }; const varValue = devCycleClient.variableValue( { targetingKey: "123" }, "test-variable", "default" ); const user2 = { targetingKey: "1234", email: "test@test.com", name: "Test User", }; const boolVarValue = devCycleClient.variable( user2, "test-boolean-variable", false ); ```
# DevCycle to OpenFeature Node.js - Initialization Transform CodeMod This Codemod will transform the initialization of the DevCycle Node.js Server SDK to use OpenFeature Node.js SDK. - Calls to `initializeDevCycle()` should be replaced with `new DevCycleProvider()` where the same parameters used. - The variable named from the `initializeDevCycle()` call should be renamed to replace `client` with `provider`. For example: `devcycleClient` renamed to `devcycleProvider`. - The new provider should be passed into `await OpenFeature.setProviderAndWait(devcycleProvider);` - C new `openFeatureClient` should be created from `OpenFeature.getClient()` - Usages of the variabled named from the `initializeDevCycle()` call should be updated to use the `openFeatureClient` instead. ## Before ```ts let devcycleClient: DevCycleClient; async function initializeDevCycleClient() { devcycleClient = await initializeDevCycle(DEVCYCLE_SERVER_SDK_KEY, { logLevel: "info", eventFlushIntervalMS: 1000, }).onClientInitialized(); return devcycleClient; } function getDevCycleClient() { return devcycleClient; } export { initializeDevCycleClient, getDevCycleClient }; ``` ## After ```ts let openFeatureClient: Client; async function initializeDevCycleClient() { const Devcycleprovider = new DevCycleProvider(DEVCYCLE_SERVER_SDK_KEY, { logLevel: "info", eventFlushIntervalMS: 1000, }); await OpenFeature.setProviderAndWait(Devcycleprovider); const openFeatureClient = OpenFeature.getClient(); return openFeatureClient; } function getDevCycleClient() { return openFeatureClient; } export { initializeDevCycleClient, getDevCycleClient }; ```
# DevCycle to OpenFeature Node.js - Update Imports CodeMod This Codemod helps to convert DevCycle Node.js SDK implementations to the OpenFeature Node.js SDK using the DevCycle Provider. It handles the first step of the conversion by updating the packages imports: - Only if the file is using `initializeDevCycle`, removes the imports of `initializeDevCycle`, and replaces those imports with `DevCycleProvider` from `@devcycle/nodejs-server-sdk` - Only if the file is using `DevCycleClient`, removes the import of `DevCycleClient`, and replaces those imports with `DevCycleProvider` from `@devcycle/nodejs-server-sdk` - Replaces `DevCycleUser` type with `EvaluationContext` from `@openfeature/server-sdk` - Add imports for `OpenFeature` from `@openfeature/server-sdk` if the file is using `initializeDevCycle` or `DevCycleClient` ## Before ```ts import { initializeDevCycle, DevCycleClient, } from "@devcycle/nodejs-server-sdk"; ``` ## After ```ts import { DevCycleProvider } from "@devcycle/nodejs-server-sdk"; import { OpenFeature, Client } from "@openfeature/server-sdk"; ```
# Correct TypeScript Specifiers This package transforms import specifiers from the old `tsc` (TypeScript's compiler) requirement of using `.js` file extensions in source-code to import files that are actually typescript; the corrected specifiers enable source-code to be runnable by standards-compliant software like Node.js. This is a one-and-done process, and the updated source-code should be committed to your version control (eg git); thereafter, source-code import statements should be authored compliant with the ECMAScript (JavaScript) standard. > [!TIP] > Those using `tsc` to compile will need to enable [`rewriteRelativeImportExtensions`](https://www.typescriptlang.org/tsconfig/#rewriteRelativeImportExtensions); using `tsc` for only type-checking (ex via a lint/test step like `npm run test:types`) needs [`allowImportingTsExtensions`](https://www.typescriptlang.org/tsconfig/#allowImportingTsExtensions) (and some additional compile options—see the cited documentation); This package does not just blindly find & replace file extensions within specifiers: It confirms that the replacement specifier actually exists; in ambiguous cases (such as two files with the same basename in the same location but different relevant file extensions like `/tmp/foo.js` and `/tmp/foo.ts`), it logs an error, skips that specifier, and continues processing. > [!CAUTION] > This package does not confirm that imported modules contain the desired export(s). This _shouldn't_ actually ever result in a problem because ambiguous cases are skipped (so if there is a problem, it existed before the migration started). Merely running your source-code after the mirgration completes will confirm all is well (if there are problems, node will error, citing the problems). > [!TIP] > Node.js requires the `type` keyword be present on type imports. For own code, this package usually handles that. However, in some cases and for node modules, it does not. Robust tooling already exists that will automatically fix this, such as [`consistent-type-imports` via typescript-lint](https://typescript-eslint.io/rules/consistent-type-imports) and [`use-import-type` via biome](https://biomejs.dev/linter/rules/use-import-type/). If your source code needs that, first run this codemod and then one of those fixers. ## Running > [!CAUTION] > This will change your source-code. Commit any unsaved changes before running this package. ```sh NODE_OPTIONS="--experimental-import-meta-resolve" \ npx codemod@latest correct-ts-specifiers ``` ### Monorepos For best results, run this _within_ each workspace of the monorepo. ```text project-root/ ├ workspaces/ ├ foo/ ←--------- RUN HERE ├ … ├ package.json └ tsconfig.json └ bar/ ←--------- RUN HERE ├ … ├ package.json └ tsconfig.json └ utils/ ←--------- RUN HERE ├ qux.js └ zed.js ``` ## Supported cases * no file extension → `.cts`, `.mts`, `.js`, `.ts`, `.d.cts`, `.d.mts`, or `.d.ts` * `.cjs` → `.cts`, `.mjs` → `.mts`, `.js` → `.ts` * `.js` → `.d.cts`, `.d.mts`, or `.d.ts` * [Package.json subimports](https://nodejs.org/api/packages.html#subpath-imports) * [tsconfig paths](https://www.typescriptlang.org/tsconfig/#paths) (via [`@nodejs-loaders/alias`](https://github.com/JakobJingleheimer/nodejs-loaders/blob/main/packages/alias?tab=readme-ov-file)) * In order to subsequently run code via node, you will need to add this (or another) loader to your own project. Or, switch to [subimports](https://nodejs.org/api/packages.html#subpath-imports). * Commonjs-like directory specifiers Before: ```ts import { URL } from 'node:url'; import { bar } from '@dep/bar'; import { foo } from 'foo'; import { Bird } from './Bird'; // a directory import { Cat } from './Cat.ts'; import { Dog } from '…/Dog/index.mjs'; // tsconfig paths import { baseUrl } from '#config.js'; // package.json imports export { Zed } from './zed'; export const makeLink = (path: URL) => (new URL(path, baseUrl)).href; const nil = await import('./nil.js'); const bird = new Bird('Tweety'); const cat = new Cat('Milo'); const dog = new Dog('Otis'); ``` After: ```ts import { URL } from 'node:url'; import { bar } from '@dep/bar'; import { foo } from 'foo'; import { Bird } from './Bird/index.ts'; import { Cat } from './Cat.ts'; import { Dog } from '…/Dog/index.mts'; // tsconfig paths import { baseUrl } from '#config.js'; // package.json imports export type { Zed } from './zed.d.ts'; export const makeLink = (path: URL) => (new URL(path, baseUrl)).href; const nil = await import('./nil.ts'); const bird = new Bird('Tweety'); const cat = new Cat('Milo'); const dog = new Dog('Otis'); ```
This codemod removes redundant import process from 'node:process'; statements, as process is now globally available in Deno v2 ### Before ```ts import process from "node:process"; console.log(process.env.NODE_ENV); ``` ### After ```ts console.log(process.env.NODE_ENV); ```
No description available
Node.js implements a flavor of vm.createContext() and friends that creates a context without contextifying its global object when vm.constants.DONT_CONTEXTIFY is used. This is suitable when users want to freeze the context (impossible when the global is contextified i.e. has interceptors installed) or speed up the global access if they don't need the interceptor behavior. ### Before ```ts const vm = require('node:vm'); // Creating a context with a contextified global object const context = vm.createContext(); // Attempting to freeze the global object try { vm.runInContext('Object.freeze(globalThis);', context); } catch (e) { console.log(e); // TypeError: Cannot freeze } // Accessing global variables console.log(vm.runInContext('globalThis.foo = 1; foo;', context)); // 1 ``` ### After ```ts const vm = require('node:vm'); // Using vm.constants.DONT_CONTEXTIFY to create a context with an ordinary global object const context = vm.createContext(vm.constants.DONT_CONTEXTIFY); // Successfully freezing the global object vm.runInContext('Object.freeze(globalThis);', context); // Attempting to modify a variable that doesn't exist try { vm.runInContext('bar = 1; bar;', context); } catch (e) { console.log(e); // Uncaught ReferenceError: bar is not defined } ```
This release adds a new API module.enableCompileCache() that can be used to enable on-disk code caching of all modules loaded after this API is called. Previously this could only be enabled by the NODE_COMPILE_CACHE environment variable, so it could only set by end-users. This API allows tooling and library authors to enable caching of their own code. This is a built-in alternative to the v8-compile-cache/v8-compile-cache-lib packages, but have better performance and supports ESM. ### Before ```ts const http = require('http'); function startServer() { // Create an HTTP server const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello, Node.js!\n'); }); server.listen(3000, () => { console.log('Server is running at http://localhost:3000/'); }); } startServer(); ``` ### After ```ts const http = require('http'); function startServer() { // Enable compile cache for all modules loaded after this point const result = module.enableCompileCache(); // Create an HTTP server const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello, Node.js!\n'); }); server.listen(3000, () => { console.log('Server is running at http://localhost:3000/'); }); } startServer(); ```
Build your own codemod and share it with the community.