{"version":3,"sources":["../src/dsn-parser.type.ts","../src/dsn-parser.util.ts","../src/query-param-parser.ts","../src/parse-dsn.ts","../src/assert-parsable-dsn.ts","../src/convert-jdbc-to-dsn.ts","../src/is-parsable-dsn.ts","../src/parse-dsn-or-throw.ts"],"names":["errorReasons","createErrorResult","reason","msg","isNonEmptyString","value","trim","parsableNumberRegexp","isParsableNumber","isValidNetworkPort","port","removeUndefined","obj","definedObj","key","mergeDsnOverrides","parsedDsn","overrides","merged","params","restDsn","defaultOptions","parseQueryParams","queryParams","options","parseBooleans","parseNumbers","setTrueForUndefinedValues","defaultValue","v","acc","keyValuePair","val","dsnRegexp","parseDsn","dsn","opts","lowercaseDriver","matches","parsed","assertParsableDsn","convertJdbcToDsn","jdbc","part1","rest","isParsableDsn","parseDsnOrThrow","parsedOrError","pfx"],"mappings":"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","file":"index.mjs","sourcesContent":["export type ParsedDsn = {\n  db?: string;\n  driver: string;\n  host: string;\n  /** Query params */\n  params?: Record<string, boolean | number | string>;\n  pass?: string;\n  port?: number;\n  user?: string;\n};\n\nexport type ParseDsnOptions = {\n  /** Whether to lowercase parsed driver name, default: false */\n  lowercaseDriver?: boolean;\n  /** Overrides parsed values by those one (except query params) */\n  overrides?: Omit<Partial<ParsedDsn>, 'params'>;\n};\n\nexport const errorReasons = {\n  EMPTY_DSN: 'DSN cannot be empty',\n  INVALID_ARGUMENT: 'DSN must be a string',\n  INVALID_PORT: 'Invalid port',\n  PARSE_ERROR: 'Cannot parse DSN',\n} as const;\n\nexport type ErrorReasons = keyof typeof errorReasons;\n\ntype ParserSuccessResult = {\n  success: true;\n  value: ParsedDsn;\n};\n\nexport type ParserErrorResult = {\n  message: string;\n  reason: ErrorReasons;\n  success: false;\n};\n\nexport type ParserResult = ParserErrorResult | ParserSuccessResult;\n\ndeclare const tag: unique symbol;\n\nexport type WeakOpaqueContainer<Token> = {\n  readonly [tag]: Token;\n};\n\nexport type ParsableDsn = string & WeakOpaqueContainer<'ParsableDsn'>;\n","import {\n  type ErrorReasons,\n  errorReasons,\n  type ParsedDsn,\n  type ParseDsnOptions,\n  type ParserErrorResult,\n} from './dsn-parser.type';\n\nexport const createErrorResult = (\n  reason: ErrorReasons,\n  msg?: string\n): ParserErrorResult => {\n  return {\n    message: msg ?? errorReasons[reason],\n    reason: reason,\n    success: false,\n  };\n};\n\nexport const isNonEmptyString = (\n  value: unknown,\n  trim = true\n): value is string => {\n  return typeof value === 'string' && (trim ? value.trim() : value).length > 0;\n};\n\nconst parsableNumberRegexp = /^-?\\d{1,16}$/;\n\nexport const isParsableNumber = (value: unknown): value is number => {\n  return typeof value === 'string' && parsableNumberRegexp.test(value);\n};\n\ntype ValidNetworkPort = number;\n\nexport const isValidNetworkPort = (port: number): port is ValidNetworkPort => {\n  return !Number.isNaN(port) && port < 65_536 && port > 0;\n};\n\nexport const removeUndefined = (\n  obj: Record<string, unknown>\n): Record<string, unknown> => {\n  const definedObj: Record<string, unknown> = {};\n  for (const key in obj) {\n    if (obj[key] !== undefined) {\n      definedObj[key] = obj[key];\n    }\n  }\n  return definedObj;\n};\n\nexport const mergeDsnOverrides = (\n  parsedDsn: ParsedDsn,\n  overrides: Exclude<ParseDsnOptions['overrides'], undefined>\n): ParsedDsn => {\n  const merged: Record<string, unknown> = {};\n  const { params, ...restDsn } = parsedDsn;\n  for (const [key, value] of Object.entries(restDsn)) {\n    merged[key] =\n      key in overrides ? (overrides as Record<string, unknown>)[key] : value;\n  }\n  merged.params = params;\n  return merged as unknown as ParsedDsn;\n};\n","import { isParsableNumber } from './dsn-parser.util';\n\ntype ParseQueryParamsOptions = {\n  parseBooleans?: boolean;\n  parseNumbers?: boolean;\n  setTrueForUndefinedValues?: boolean;\n};\n\nconst defaultOptions = {\n  parseBooleans: true,\n  parseNumbers: true,\n  setTrueForUndefinedValues: true,\n};\n\nexport const parseQueryParams = (\n  queryParams: string,\n  options?: ParseQueryParamsOptions\n): Record<string, boolean | null | number | string> => {\n  const { parseBooleans, parseNumbers, setTrueForUndefinedValues } = {\n    ...defaultOptions,\n    ...options,\n  };\n  const defaultValue = setTrueForUndefinedValues ? true : null;\n  const parts = queryParams.split('&').filter((v) => v.trim().length > 0);\n  return parts.reduce((acc, keyValuePair) => {\n    const [key, value = null] = keyValuePair.split('=') as [\n      string,\n      string | undefined,\n    ];\n    let val;\n    if (typeof value === 'string') {\n      if (parseNumbers && isParsableNumber(value)) {\n        val = Number.parseInt(value, 10);\n      } else {\n        val =\n          parseBooleans && ['false', 'true'].includes(value)\n            ? value === 'true'\n            : decodeURIComponent(value);\n      }\n    } else {\n      val = defaultValue;\n    }\n    return { ...acc, [key]: val };\n  }, {});\n};\n","import type {\n  ParsedDsn,\n  ParseDsnOptions,\n  ParserResult,\n} from './dsn-parser.type';\nimport {\n  createErrorResult,\n  isNonEmptyString,\n  isValidNetworkPort,\n  mergeDsnOverrides,\n  removeUndefined,\n} from './dsn-parser.util';\nimport { parseQueryParams } from './query-param-parser';\n\nconst dsnRegexp =\n  // eslint-disable-next-line regexp/no-unused-capturing-group,regexp/no-misleading-capturing-group,sonarjs/regex-complexity,sonarjs/unused-named-groups\n  /^(?<driver>([\\w+-]{1,40})):\\/\\/((?<user>[^/:]{1,200})?(:(?<pass>.{0,200}))?@)?(?<host>[^/:]{1,200}?)(:(?<port>\\d+)?)?(\\/(?<db>([\\w#$.@-])+))?(\\?(?<params>.{1,1000}))?$/;\n\nconst defaultOptions = {\n  lowercaseDriver: false,\n  overrides: {},\n} as const satisfies ParseDsnOptions;\n\nexport const parseDsn = (\n  dsn: unknown,\n  options?: ParseDsnOptions\n): ParserResult => {\n  if (!isNonEmptyString(dsn)) {\n    return createErrorResult(\n      typeof dsn === 'string' ? 'EMPTY_DSN' : 'INVALID_ARGUMENT'\n    );\n  }\n  const opts = { ...defaultOptions, ...options };\n  const { lowercaseDriver, overrides = {} } = opts;\n  const matches = dsnRegexp.exec(dsn);\n  if (!matches?.groups) {\n    return createErrorResult('PARSE_ERROR');\n  }\n  const parsed: Record<string, unknown> = {};\n  for (const [key, value] of Object.entries(matches.groups)) {\n    if (typeof value === 'string') {\n      switch (key) {\n        case 'driver': {\n          parsed.driver = lowercaseDriver ? value.toLowerCase() : value;\n          break;\n        }\n        case 'port': {\n          parsed.port = Number.parseInt(value, 10);\n          break;\n        }\n        case 'params': {\n          parsed.params = parseQueryParams(value);\n          break;\n        }\n        default: {\n          parsed[key] = value;\n        }\n      }\n    }\n  }\n  const val = removeUndefined(\n    mergeDsnOverrides(parsed as ParsedDsn, overrides)\n  ) as ParsedDsn;\n  if (val?.port && !isValidNetworkPort(val.port)) {\n    return createErrorResult(\n      'INVALID_PORT',\n      `Invalid port: ${val.port as unknown as number}`\n    );\n  }\n  return {\n    success: true,\n    value: val,\n  };\n};\n","import type { ParsableDsn } from './dsn-parser.type';\nimport { parseDsn } from './parse-dsn';\n\n/**\n * @throws Error when not parsable\n */\nexport const assertParsableDsn = (\n  dsn: unknown,\n  msg?: string\n): asserts dsn is ParsableDsn => {\n  const parsed = parseDsn(dsn as string);\n  if (!parsed.success) {\n    throw new Error(msg ?? `${parsed.message} (${parsed.reason})`);\n  }\n};\n","export const convertJdbcToDsn = (jdbc: string): string => {\n  const [part1, ...rest] = jdbc.split(';');\n  return [part1, rest ? rest.join('&') : undefined].filter(Boolean).join('?');\n};\n","import type { ParsableDsn } from './dsn-parser.type';\nimport { parseDsn } from './parse-dsn';\n\nexport const isParsableDsn = (dsn: unknown): dsn is ParsableDsn => {\n  return parseDsn(dsn as string).success;\n};\n","import type { ParsedDsn, ParseDsnOptions } from './dsn-parser.type';\nimport { parseDsn } from './parse-dsn';\n\nexport const parseDsnOrThrow = (\n  dsn: unknown,\n  options?: ParseDsnOptions & {\n    errorMsgPrefix?: string;\n  }\n): ParsedDsn => {\n  const parsedOrError = parseDsn(dsn, options);\n  if (parsedOrError.success) {\n    return parsedOrError.value;\n  }\n  const pfx = options?.errorMsgPrefix ?? `Can't parse dsn`;\n  throw new Error(`${pfx}: ${parsedOrError.message} (${parsedOrError.reason})`);\n};\n"]}