114 lines
3.2 KiB
TypeScript
114 lines
3.2 KiB
TypeScript
import type { CassandraConfig } from "#types/config";
|
|
|
|
function isValidHost(host: string): boolean {
|
|
if (!host || host.trim().length === 0) return false;
|
|
|
|
if (host === "localhost") return true;
|
|
|
|
const ipv4Regex =
|
|
/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
|
|
if (ipv4Regex.test(host)) return true;
|
|
|
|
const hostnameRegex =
|
|
/^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
|
|
return hostnameRegex.test(host);
|
|
}
|
|
|
|
function isValidPort(port: number): boolean {
|
|
return Number.isInteger(port) && port > 0 && port <= 65535;
|
|
}
|
|
|
|
function isValidKeyspace(keyspace: string): boolean {
|
|
if (!keyspace || keyspace.trim().length === 0) return false;
|
|
|
|
const keyspaceRegex = /^[a-zA-Z][a-zA-Z0-9_]{0,47}$/;
|
|
return keyspaceRegex.test(keyspace);
|
|
}
|
|
|
|
function isValidContactPoints(contactPoints: string[]): boolean {
|
|
if (!Array.isArray(contactPoints) || contactPoints.length === 0) return false;
|
|
|
|
return contactPoints.every((point) => {
|
|
const trimmed = point.trim();
|
|
return trimmed.length > 0 && isValidHost(trimmed);
|
|
});
|
|
}
|
|
|
|
function isValidCredentials(
|
|
username: string,
|
|
password: string,
|
|
authEnabled: boolean,
|
|
): boolean {
|
|
if (!authEnabled) return true;
|
|
|
|
return username.trim().length > 0 && password.trim().length > 0;
|
|
}
|
|
|
|
function isValidDatacenter(datacenter: string, authEnabled: boolean): boolean {
|
|
if (!authEnabled) return true;
|
|
|
|
return datacenter.trim().length > 0;
|
|
}
|
|
|
|
function validateCassandraConfig(config: CassandraConfig): {
|
|
isValid: boolean;
|
|
errors: string[];
|
|
} {
|
|
const errors: string[] = [];
|
|
|
|
if (!isValidHost(config.host)) {
|
|
errors.push(`Invalid host: ${config.host}`);
|
|
}
|
|
|
|
if (!isValidPort(config.port)) {
|
|
errors.push(
|
|
`Invalid port: ${config.port}. Port must be between 1 and 65535`,
|
|
);
|
|
}
|
|
|
|
if (!isValidKeyspace(config.keyspace)) {
|
|
errors.push(
|
|
`Invalid keyspace: ${config.keyspace}. Must start with letter, contain only alphanumeric and underscores, max 48 chars`,
|
|
);
|
|
}
|
|
|
|
if (!isValidContactPoints(config.contactPoints)) {
|
|
errors.push(
|
|
`Invalid contact points: ${config.contactPoints.join(", ")}. All contact points must be valid hosts`,
|
|
);
|
|
}
|
|
|
|
if (
|
|
!isValidCredentials(config.username, config.password, config.authEnabled)
|
|
) {
|
|
errors.push(
|
|
"Invalid credentials: Username and password are required when authentication is enabled",
|
|
);
|
|
}
|
|
|
|
if (!isValidDatacenter(config.datacenter, config.authEnabled)) {
|
|
errors.push(
|
|
"Invalid datacenter: Datacenter is required when authentication is enabled",
|
|
);
|
|
}
|
|
|
|
return {
|
|
isValid: errors.length === 0,
|
|
errors,
|
|
};
|
|
}
|
|
|
|
const rawConfig: CassandraConfig = {
|
|
host: process.env.CASSANDRA_HOST || "localhost",
|
|
port: Number.parseInt(process.env.CASSANDRA_PORT || "9042", 10),
|
|
keyspace: process.env.CASSANDRA_KEYSPACE || "void_db",
|
|
username: process.env.CASSANDRA_USERNAME || "",
|
|
password: process.env.CASSANDRA_PASSWORD || "",
|
|
datacenter: process.env.CASSANDRA_DATACENTER || "",
|
|
contactPoints: (process.env.CASSANDRA_CONTACT_POINTS || "localhost")
|
|
.split(",")
|
|
.map((point) => point.trim()),
|
|
authEnabled: process.env.CASSANDRA_AUTH_ENABLED !== "false",
|
|
};
|
|
|
|
export { rawConfig as cassandraConfig, validateCassandraConfig };
|