Skip to content

Brainstorm: url.parse() -> new url #92

@AugustinMauroy

Description

@AugustinMauroy

Description

This codemod should migrate url.parse() to new url.

  • It's should handle both require() function and import statement.
  • It's should support both url node:url specifier.
  • If the url module isn't use elsewhere we should remove the importation.
  • auth property should be replaced by ${modernURL.username}:${modernURL.password}
  • path property should be replaced by ${modernURL.pathname}${modernURL.search}
  • hostname property should be replaced by modernURL.hostname.replace(/^\[|\]$/, '') to remove the brackets for IPv6 addresses.

Example

In these example we use legacyURL to refer to the object returned by url.parse(), and modernURL to refer to the object created with new URL().
In the codemod implementation, it' will be the name of the variable that is used by the user so it's shouldn't be changed.

Case 1: Basic usage

Before:

const url = require('node:url');

const legacyURL = url.parse('https://example.com/path?query=string#hash');

After:

const modernURL = new URL('https://example.com/path?query=string#hash');

Case 2: auth property

Before:

const url = require('node:url');

const legacyURL = url.parse('https://user:[email protected]/path');

const { auth } = legacyURL;
const urlAuth = legacyURL.auth;

After:

const modernURL = new URL('https://user:[email protected]/path');

const auth  = `${modernURL.username}:${modernURL.password}`;
const urlAuth = `${modernURL.username}:${modernURL.password}`;

Case 3: path property

Before:

const url = require('node:url');

const legacyURL = url.parse('https://example.com/path?query=string#hash');

const { path } = legacyURL;
const urlPath = legacyURL.path;

After:

const modernURL = new URL('https://example.com/path?query=string#hash');

const path = `$(modernURL.pathname}${modernURL.search}`;
const urlPath = `${modernURL.pathname}${modernURL.search}`;

Case 4: hostname property with IPv6 address

Before:

const url = require('node:url');

const legacyURL = url.parse('https://[2001:db8::1]/path');

const { hostname } = legacyURL;
const urlHostname = legacyURL.hostname;

After:

const modernURL = new URL('https://[2001:db8::1]/path');

const hostname = modernURL.hostname.replace(/^\[|\]$/, '');
const urlHostname = modernURL.hostname.replace(/^\[|\]$/, '');

Case 5: cjs url module elsewhere

Before:

const { parse, foo } = require('node:url');

const legacyURL = parse('https://example.com/path?query=string#hash');

foo(); // does something else

After:

const { foo } = require('node:url');

const modernURL = new URL('https://example.com/path?query=string#hash');

foo(); // does something else

Case 6: import statement

Before:

import { parse } from 'node:url';

const legacyURL = parse('https://example.com/path?query=string#hash');

After:

import { URL } from 'node:url';

const modernURL = new URL('https://example.com/path?query=string#hash');

Case 7: import statement with other named exports

Before:

import { parse, foo } from 'node:url';

const legacyURL = parse('https://example.com/path?query=string#hash');

foo(); // does something else

After:

import { URL, foo } from 'node:url';

const modernURL = new URL('https://example.com/path?query=string#hash');

foo(); // does something else

REFS

https://nodejs.org/dist/docs/api/url.html
https://url.spec.whatwg.org

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    Status

    🏗 In progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions