feat: infra 패키지 추가 및 PostgreSQL, Redis 커넥터 구현

This commit is contained in:
2025-12-28 12:18:42 +00:00
parent 77e5b251ef
commit 27b243b121
9 changed files with 37 additions and 10 deletions
+21
View File
@@ -0,0 +1,21 @@
{
"name": "@sammo-ts/infra",
"private": true,
"version": "0.0.0",
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc -p tsconfig.json",
"dev": "node -e \"console.log('dev not configured')\"",
"lint": "node -e \"console.log('lint not configured')\"",
"test": "node -e \"console.log('test not configured')\""
},
"dependencies": {
"@prisma/client": "^5.18.0",
"redis": "^4.7.0"
},
"devDependencies": {
"prisma": "^5.18.0"
}
}
+10
View File
@@ -0,0 +1,10 @@
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// TODO: Translate docs/architecture/postgres-schema.md into Prisma models.
+2
View File
@@ -0,0 +1,2 @@
export * from './postgres.js';
export * from './redis.js';
+42
View File
@@ -0,0 +1,42 @@
import { PrismaClient, type PrismaClientOptions } from '@prisma/client';
export interface PostgresConfig {
url: string;
log?: PrismaClientOptions['log'];
}
export interface PostgresConnector {
readonly prisma: PrismaClient;
connect(): Promise<void>;
disconnect(): Promise<void>;
}
export const resolvePostgresConfigFromEnv = (
env: NodeJS.ProcessEnv = process.env
): PostgresConfig => {
const url = env.DATABASE_URL ?? '';
if (!url) {
throw new Error('DATABASE_URL is required to create a Postgres client.');
}
return { url };
};
export const createPostgresConnector = (
config: PostgresConfig
): PostgresConnector => {
const prisma = new PrismaClient({
datasources: {
db: {
url: config.url,
},
},
log: config.log,
});
return {
prisma,
connect: () => prisma.$connect(),
disconnect: () => prisma.$disconnect(),
};
};
+43
View File
@@ -0,0 +1,43 @@
import { createClient, type RedisClientOptions, type RedisClientType } from 'redis';
export interface RedisConfig {
url: string;
database?: number;
options?: Omit<RedisClientOptions, 'url' | 'database'>;
}
export interface RedisConnector {
readonly client: RedisClientType;
connect(): Promise<void>;
disconnect(): Promise<void>;
}
export const resolveRedisConfigFromEnv = (
env: NodeJS.ProcessEnv = process.env
): RedisConfig => {
const url = env.REDIS_URL ?? '';
if (!url) {
throw new Error('REDIS_URL is required to create a Redis client.');
}
const database = env.REDIS_DB !== undefined ? Number(env.REDIS_DB) : undefined;
if (database !== undefined && Number.isNaN(database)) {
throw new Error('REDIS_DB must be a number when provided.');
}
return { url, database };
};
export const createRedisConnector = (config: RedisConfig): RedisConnector => {
const client = createClient({
url: config.url,
database: config.database,
...config.options,
});
return {
client,
connect: () => client.connect(),
disconnect: () => client.quit(),
};
};
+9
View File
@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"composite": true
},
"include": ["src"]
}