Repository: sequelize/sequelize
File: packages/core/src/utils/url.ts (TypeScript)

Code before:
import path from 'node:path';
import { URL } from 'node:url';
import type { ConnectionOptions } from 'pg-connection-string';
import pgConnectionString from 'pg-connection-string';
import type { Dialect, DialectOptions, Options } from '../sequelize';

/**
 * Parses a connection string into an Options object with connection properties
 *
 * @param connectionString string value in format schema://username:password@host:port/database
 */
export function parseConnectionString(connectionString: string): Options {
  const options: Options = {};

  // The following connectionStrings are not valid URLs, but they are supported by sqlite.
  if (connectionString.toLowerCase() === 'sqlite://:memory:' || connectionString.toLowerCase() === 'sqlite::memory:') {
    options.dialect = 'sqlite';
    options.host = '';

    return options;
  }

  const urlObject = new URL(connectionString);

  if (urlObject.protocol) {
    let protocol = urlObject.protocol.replace(/:$/, '');
    if (protocol === 'postgresql') {
      protocol = 'postgres';
    }

    options.dialect = protocol as Dialect;
  }

  if (urlObject.hostname != null) {
    options.host = urlObject.hostname;
  }

  if (urlObject.pathname) {
    // decode the URI component from urlObject.pathname value
    options.database = decodeURIComponent(urlObject.pathname.replace(/^\//, ''));
  }

  if (urlObject.port) {

Review comment (suggestion):
we could set `storage` to `:memory:`. Right now it's defaulted in `getConnection`, but it would make it more explicit when inspecting sequelize's options

I also would not set `host` to an empty string, instead I would throw in sqlite's `getConnection` if both `host` and `storage` are defined as they have the same role in sqlite

Code after:
import path from 'node:path';
import { URL } from 'node:url';
import type { ConnectionOptions } from 'pg-connection-string';
import pgConnectionString from 'pg-connection-string';
import type { Dialect, DialectOptions, Options } from '../sequelize';
import { SUPPORTED_DIALECTS } from '../sequelize-typescript';
import { encodeHost } from './deprecations';

/**
 * Parses a connection string into an Options object with connection properties
 *
 * @param connectionString string value in format schema://username:password@host:port/database
 */
export function parseConnectionString(connectionString: string): Options {
  const options: Options = {};

  // The following connectionStrings are not valid URLs, but they are supported by sqlite.
  if (connectionString === 'sqlite://:memory:' || connectionString === 'sqlite::memory:') {
    options.dialect = 'sqlite';
    options.storage = ':memory:';

    return options;
  }

  const urlObject = new URL(connectionString);

  if (urlObject.protocol) {
    let protocol = urlObject.protocol.replace(/:$/, '');
    if (protocol === 'postgresql') {
      protocol = 'postgres';
    }

    if (!SUPPORTED_DIALECTS.includes(protocol as Dialect)) {
      throw new Error(`The protocol was set to ${JSON.stringify(protocol)}, which is not a supported dialect. Set it to one of ${SUPPORTED_DIALECTS.map(d => JSON.stringify(d)).join(', ')} instead.`);
    }

    options.dialect = protocol as Dialect;
  }

  if (urlObject.hostname != null) {
    // TODO: rename options.host to options.hostname, as host can accept a port while hostname can't
    options.host = decodeURIComponent(urlObject.hostname);
  }