feat: infra 패키지 추가 및 PostgreSQL, Redis 커넥터 구현
This commit is contained in:
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './postgres.js';
|
||||
export * from './redis.js';
|
||||
@@ -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(),
|
||||
};
|
||||
};
|
||||
@@ -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(),
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"composite": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
Reference in New Issue
Block a user