add redis, cassandra support, change helpers to lib
Some checks failed
Code quality checks / biome (push) Failing after 9s

This commit is contained in:
creations 2025-05-01 15:32:09 -04:00
parent a3555c73d2
commit ab81475ad6
Signed by: creations
GPG key ID: 8F553AA4320FC711
8 changed files with 145 additions and 6 deletions

19
.env.example Normal file
View file

@ -0,0 +1,19 @@
# NODE_ENV=development
HOST=0.0.0.0
PORT=8080
# Redis (Required)
REDIS_URL=redis://localhost:6379
REDIS_TTL=3600
# Cassandra (Required)
CASSANDRA_HOST=localhost
CASSANDRA_PORT=9042
CASSANDRA_DATACENTER=datacenter1
CASSANDRA_CONTACT_POINTS=localhost
# Optional
CASSANDRA_KEYSPACE=
CASSANDRA_USERNAME=
CASSANDRA_AUTH_ENABLED=false
CASSANDRA_PASSWORD=

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
/node_modules
bun.lock
.env

View file

@ -1,6 +1,51 @@
import { logger } from "@creations.works/logger";
export const environment: Environment = {
port: Number.parseInt(process.env.PORT || "8080", 10),
port: Number.parseInt(process.env.PORT || "", 10),
host: process.env.HOST || "0.0.0.0",
development:
process.env.NODE_ENV === "development" || process.argv.includes("--dev"),
};
export const redisTtl: number = process.env.REDIS_TTL
? Number.parseInt(process.env.REDIS_TTL, 10)
: 60 * 60 * 1; // 1 hour
export const cassandra: CassandraConfig = {
host: process.env.CASSANDRA_HOST || "localhost",
port: Number.parseInt(process.env.CASSANDRA_PORT || "9042", 10),
keyspace: process.env.CASSANDRA_KEYSPACE || "",
username: process.env.CASSANDRA_USERNAME || "",
password: process.env.CASSANDRA_PASSWORD || "",
datacenter: process.env.CASSANDRA_DATACENTER || "",
contactPoints: (process.env.CASSANDRA_CONTACT_POINTS || "localhost").split(","),
authEnabled: process.env.CASSANDRA_AUTH_ENABLED === "false",
};
export function verifyRequiredVariables(): void {
const requiredVariables = [
"HOST",
"PORT",
"REDIS_URL",
"REDIS_TTL",
"CASSANDRA_HOST",
"CASSANDRA_PORT",
"CASSANDRA_CONTACT_POINTS",
"CASSANDRA_AUTH_ENABLED",
"CASSANDRA_DATACENTER",
];
let hasError = false;
for (const key of requiredVariables) {
const value = process.env[key];
if (value === undefined || value.trim() === "") {
logger.error(`Missing or empty environment variable: ${key}`);
hasError = true;
}
}
if (hasError) {
process.exit(1);
}
}

View file

@ -19,6 +19,7 @@
"typescript": "^5.8.3"
},
"dependencies": {
"@creations.works/logger": "^1.0.3"
"@creations.works/logger": "^1.0.3",
"cassandra-driver": "^4.8.0"
}
}

View file

@ -1,12 +1,27 @@
import { logger } from "@creations.works/logger";
import { CassandraService } from "@/lib/cassandra";
import { serverHandler } from "@/server";
import { verifyRequiredVariables } from "@config/environment";
import { logger } from "@creations.works/logger";
import { redis } from "bun";
async function main(): Promise<void> {
verifyRequiredVariables();
// Redis
try {
await redis.connect();
logger.info("Redis connection successful.");
} catch (error) {
logger.error(["Redis connection failed:", error as Error]);
process.exit(1);
}
await CassandraService.connect();
serverHandler.initialize();
}
main().catch((error: Error) => {
logger.error(["Error initializing the server:", error]);
logger.error(error);
process.exit(1);
});

47
src/lib/cassandra.ts Normal file
View file

@ -0,0 +1,47 @@
import { cassandra as config } from "@config/environment";
import { logger } from "@creations.works/logger";
import { Client, auth } from "cassandra-driver";
class CassandraService {
private static instance: Client | null = null;
private constructor() {}
public static getClient(): Client {
if (!CassandraService.instance) {
CassandraService.instance = new Client({
contactPoints: config.contactPoints,
localDataCenter: config.datacenter,
keyspace: config.keyspace,
authProvider: config.authEnabled
? new auth.PlainTextAuthProvider(config.username, config.password)
: undefined,
protocolOptions: {
port: config.port,
},
});
}
return CassandraService.instance;
}
public static async connect(): Promise<void> {
try {
await CassandraService.getClient().connect();
logger.info("Connected to Cassandra successfully.");
} catch (error) {
logger.error(["Failed to connect to Cassandra:", error as Error]);
process.exit(1);
}
}
public static async shutdown(): Promise<void> {
if (CassandraService.instance) {
await CassandraService.instance.shutdown();
logger.info("Cassandra client shut down.");
CassandraService.instance = null;
}
}
}
export { CassandraService };

View file

@ -5,7 +5,7 @@
"@/*": ["src/*"],
"@config/*": ["config/*"],
"@types/*": ["types/*"],
"@helpers/*": ["src/helpers/*"]
"@lib/*": ["src/lib/*"]
},
"typeRoots": ["./src/types", "./node_modules/@types"],
// Enable latest features

11
types/config.d.ts vendored
View file

@ -3,3 +3,14 @@ type Environment = {
host: string;
development: boolean;
};
type CassandraConfig = {
host: string;
port: number;
keyspace: string;
username: string;
password: string;
datacenter: string;
contactPoints: string[];
authEnabled: boolean;
};