@clickup/pg-microsharding
Version:
Microshards support for PostgreSQL
83 lines (75 loc) • 2.4 kB
text/typescript
import { dsnShort } from "./names";
import { normalizeDsn } from "./normalizeDsn";
/**
* From the list of existingDsns, choose the ones that match the prefixes.
* - When existingDsns is empty, when multiple entries in existingDsns match
* some prefix, or when no existingDsns entries match some prefix, then tries
* to treat that prefix as DSNs itself (and throws if it cannot).
* - If requireMatch=true, each pattern must match exactly one existing DSN.
*/
export function chooseDsns({
patterns,
existingDsns,
requireMatch,
}: {
patterns: string[];
existingDsns: string[];
requireMatch: boolean;
}): [dsns: string[], warnings: string[]] {
existingDsns = existingDsns.map((dsn) => normalizeDsn(dsn)!);
const dsns: string[] = [];
const warnings: string[] = [];
for (const pattern of patterns) {
let normalizedPattern: string | null = null;
try {
normalizedPattern = normalizeDsn(pattern)!;
} catch (e: unknown) {
if (typeof e !== "string") {
throw e;
}
}
const matched =
normalizedPattern && existingDsns.some((dsn) => dsn === normalizedPattern)
? [normalizedPattern]
: existingDsns.filter((dsn) => {
if (pattern.match(/^\d+$/)) {
return dsnShort(dsn).match(
new RegExp(`(\\D|^)0*${pattern}(\\D|$)`),
);
} else {
return (
dsnShort(dsn).startsWith(pattern) ||
(normalizedPattern &&
dsnShort(dsn) === dsnShort(normalizedPattern))
);
}
});
if (matched.length === 0) {
if (requireMatch) {
throw `No DSNs match "${pattern}".`;
}
try {
dsns.push(normalizeDsn(pattern)!);
} catch (e: unknown) {
throw typeof e === "string" ? `No DSNs match "${pattern}". ${e}` : e;
}
} else if (matched.length === 1) {
dsns.push(matched[0]);
} else {
if (requireMatch) {
throw `Multiple DSNs match "${pattern}".`;
}
warnings.push(
`Hint: multiple DSNs match "${pattern}", so treating it as an entire DSN.`,
);
try {
dsns.push(normalizeDsn(pattern)!);
} catch (e: unknown) {
throw typeof e === "string"
? `Multiple DSNs match "${pattern}". ${e}`
: e;
}
}
}
return [dsns, warnings];
}