nodejs / nodejs/userland-migrations

`dns.lookup()` and `dnsPromises.lookup()` options type coercion

Open
#409 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

good first issue human help wanted let's do it
Dominant language
TypeScript
Stars
85
Forks
55
Avg merge
3d 11h
Merged PRs (30d)
9

Description

Description

Since using non-proper types for options in dns.lookup() and dnsPromises.lookup() is deprecated (DEP0153) and has reached End-of-Life status in Node.js v18.0.0, we should provide a codemod to replace them.

  • The codemod should ensure family option is a nullish value or an integer.
  • The codemod should ensure hints option is a nullish value or a number.
  • The codemod should ensure all option is a nullish value or a boolean.
  • The codemod should ensure verbatim option is a nullish value or a boolean.
  • The codemod should add explicit type conversions where needed.

Additional Information

Note that in Node.js v18.0.0, passing non-proper types for dns.lookup options now throws an ERR_INVALID_ARG_TYPE error. This change enforces proper type usage:

  • family: must be undefined, null, or an integer (0, 4, or 6)
  • hints: must be undefined, null, or a number
  • all: must be undefined, null, or a boolean
  • verbatim: must be undefined, null, or a boolean

The automatic type coercion was removed to prevent unexpected behavior and make the API more predictable.

Examples

Example 1: String family option

Before:

const dns = require("node:dns");

dns.lookup("example.com", { family: "4" }, (err, address) => {
  console.log(address);
});

After:

const dns = require("node:dns");

dns.lookup("example.com", { family: 4 }, (err, address) => {
  console.log(address);
});
Example 2: String all option

Before:

const dns = require("node:dns");

dns.lookup("example.com", { all: "true" }, (err, addresses) => {
  console.log(addresses);
});

After:

const dns = require("node:dns");

dns.lookup("example.com", { all: true }, (err, addresses) => {
  console.log(addresses);
});
Example 3: Number verbatim option

Before:

const dns = require("node:dns");

dns.lookup("example.com", { verbatim: 1 }, (err, address) => {
  console.log(address);
});

After:

const dns = require("node:dns");

dns.lookup("example.com", { verbatim: true }, (err, address) => {
  console.log(address);
});
Example 4: Promises API with string family

Before:

const { lookup } = require("node:dns").promises;

const address = await lookup("example.com", { family: "6" });

After:

const { lookup } = require("node:dns").promises;

const address = await lookup("example.com", { family: 6 });
Example 5: ESM with multiple invalid options

Before:

import { lookup } from "node:dns/promises";

const result = await lookup("example.com", {
  family: "4",
  all: 1,
  verbatim: 0
});

After:

import { lookup } from "node:dns/promises";

const result = await lookup("example.com", {
  family: 4,
  all: true,
  verbatim: false
});
Example 6: Dynamic family value

Before:

const dns = require("node:dns");

const familyStr = "4";
dns.lookup("example.com", { family: familyStr }, callback);

After:

const dns = require("node:dns");

const familyStr = "4";
dns.lookup("example.com", { family: parseInt(familyStr, 10) }, callback);
Example 7: Hints option with string

Before:

const dns = require("node:dns");

dns.lookup("example.com", { hints: "0" }, (err, address) => {
  console.log(address);
});

After:

const dns = require("node:dns");

dns.lookup("example.com", { hints: 0 }, (err, address) => {
  console.log(address);
});
Example 8: Valid options (no change needed)

Before:

const dns = require("node:dns");

dns.lookup("example.com", {
  family: 4,
  hints: dns.ADDRCONFIG,
  all: false,
  verbatim: true
}, (err, address) => {
  console.log(address);
});

After:

const dns = require("node:dns");

dns.lookup("example.com", {
  family: 4,
  hints: dns.ADDRCONFIG,
  all: false,
  verbatim: true
}, (err, address) => {
  console.log(address);
});
Example 9: Null and undefined values (no change needed)

Before:

const dns = require("node:dns");

dns.lookup("example.com", {
  family: undefined,
  all: null,
  verbatim: undefined
}, callback);

After:

const dns = require("node:dns");

dns.lookup("example.com", {
  family: undefined,
  all: null,
  verbatim: undefined
}, callback);

Refs

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the codemod entry points for dns.lookup() and dnsPromises.lookup(), using the issue examples and DEP0153 behavior as the requirements. Inspect the repository's existing codemod structure and tests before implementing support for both APIs; done means invalid family, hints, all, and verbatim values receive explicit conversions while nullish and already-valid values remain unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, typescript
Domain
tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.