161 أسطر
7.4 KiB
TypeScript
161 أسطر
7.4 KiB
TypeScript
export default () => ({
|
|
nodeEnv: process.env.NODE_ENV ?? 'development',
|
|
port: Number(process.env.PORT ?? 4000),
|
|
host: process.env.HOST ?? '0.0.0.0',
|
|
publicBaseUrl:
|
|
process.env.PUBLIC_BASE_URL ?? `http://localhost:${Number(process.env.PORT ?? 4000)}`,
|
|
responseEnvelopeEnabled:
|
|
(process.env.RESPONSE_ENVELOPE_ENABLED ?? 'false').toLowerCase() === 'true',
|
|
globalPrefix: process.env.GLOBAL_PREFIX ?? 'api/v1',
|
|
cors: {
|
|
origins: (process.env.CORS_ORIGINS ?? '')
|
|
.split(',')
|
|
.map((origin) => origin.trim())
|
|
.filter((origin) => origin.length > 0),
|
|
},
|
|
mongodb: {
|
|
uri: process.env.MONGODB_URI ?? 'mongodb://127.0.0.1:27017/oudelaa',
|
|
},
|
|
jwt: {
|
|
accessSecret: process.env.JWT_ACCESS_SECRET ?? '',
|
|
accessExpiresIn: process.env.JWT_ACCESS_EXPIRES_IN ?? '15m',
|
|
refreshSecret: process.env.JWT_REFRESH_SECRET ?? '',
|
|
refreshExpiresIn: process.env.JWT_REFRESH_EXPIRES_IN ?? '30d',
|
|
},
|
|
superAdmin: {
|
|
email: (process.env.SUPERADMIN_EMAIL ?? '').toLowerCase(),
|
|
password: process.env.SUPERADMIN_PASSWORD ?? '',
|
|
accessSecret: process.env.SUPERADMIN_ACCESS_SECRET ?? '',
|
|
accessExpiresIn: process.env.SUPERADMIN_ACCESS_EXPIRES_IN ?? '15m',
|
|
refreshSecret: process.env.SUPERADMIN_REFRESH_SECRET ?? '',
|
|
refreshExpiresIn: process.env.SUPERADMIN_REFRESH_EXPIRES_IN ?? '30d',
|
|
},
|
|
google: {
|
|
clientId: process.env.GOOGLE_CLIENT_ID ?? '',
|
|
clientSecret: process.env.GOOGLE_CLIENT_SECRET ?? '',
|
|
callbackUrl:
|
|
process.env.GOOGLE_CALLBACK_URL ?? 'http://localhost:4000/api/v1/auth/google/callback',
|
|
},
|
|
email: {
|
|
enabled: (process.env.EMAIL_ENABLED ?? 'false').toLowerCase() === 'true',
|
|
smtpHost: process.env.EMAIL_SMTP_HOST ?? 'smtp.gmail.com',
|
|
smtpPort: Number(process.env.EMAIL_SMTP_PORT ?? 587),
|
|
smtpSecure: (process.env.EMAIL_SMTP_SECURE ?? 'false').toLowerCase() === 'true',
|
|
smtpUser: process.env.EMAIL_SMTP_USER ?? '',
|
|
smtpPass: process.env.EMAIL_SMTP_PASS ?? '',
|
|
fromName: process.env.EMAIL_FROM_NAME ?? 'Oudelaa',
|
|
fromEmail: process.env.EMAIL_FROM_EMAIL ?? process.env.EMAIL_SMTP_USER ?? '',
|
|
},
|
|
aiMusic: {
|
|
enabled: (process.env.AI_MUSIC_ENABLED ?? 'false').toLowerCase() === 'true',
|
|
apiKey: process.env.AI_MUSIC_API_KEY ?? '',
|
|
projectId: process.env.AI_MUSIC_PROJECT_ID ?? '',
|
|
location: process.env.AI_MUSIC_LOCATION ?? 'us-central1',
|
|
model: process.env.AI_MUSIC_MODEL ?? 'lyria-002',
|
|
},
|
|
security: {
|
|
bcryptSaltRounds: Number(process.env.BCRYPT_SALT_ROUNDS ?? 12),
|
|
refreshTokenHashSecret:
|
|
process.env.REFRESH_TOKEN_HASH_SECRET ?? process.env.JWT_REFRESH_SECRET ?? '',
|
|
},
|
|
redis: {
|
|
enabled: (process.env.REDIS_ENABLED ?? 'false').toLowerCase() === 'true',
|
|
url: process.env.REDIS_URL ?? '',
|
|
host: process.env.REDIS_HOST ?? '127.0.0.1',
|
|
port: Number(process.env.REDIS_PORT ?? 6379),
|
|
username: process.env.REDIS_USERNAME ?? '',
|
|
password: process.env.REDIS_PASSWORD ?? '',
|
|
db: Number(process.env.REDIS_DB ?? 0),
|
|
keyPrefix: process.env.REDIS_KEY_PREFIX ?? 'oudelaa',
|
|
socketAdapterEnabled:
|
|
(process.env.REDIS_SOCKET_ADAPTER_ENABLED ?? 'false').toLowerCase() === 'true',
|
|
},
|
|
queue: {
|
|
enabled: (process.env.QUEUE_ENABLED ?? 'false').toLowerCase() === 'true',
|
|
name: process.env.QUEUE_NAME ?? 'app-jobs',
|
|
defaultJobAttempts: Number(process.env.QUEUE_DEFAULT_ATTEMPTS ?? 3),
|
|
defaultJobBackoffMs: Number(process.env.QUEUE_DEFAULT_BACKOFF_MS ?? 1000),
|
|
removeOnComplete: (process.env.QUEUE_REMOVE_ON_COMPLETE ?? 'true').toLowerCase() === 'true',
|
|
workerConcurrency: Number(process.env.QUEUE_WORKER_CONCURRENCY ?? 5),
|
|
},
|
|
storage: {
|
|
provider: process.env.STORAGE_PROVIDER ?? 'local',
|
|
basePath: process.env.STORAGE_BASE_PATH ?? 'uploads',
|
|
publicBaseUrl: process.env.STORAGE_PUBLIC_BASE_URL ?? '',
|
|
s3: {
|
|
bucket: process.env.S3_BUCKET ?? '',
|
|
region: process.env.S3_REGION ?? 'auto',
|
|
endpoint: process.env.S3_ENDPOINT ?? '',
|
|
accessKeyId: process.env.S3_ACCESS_KEY_ID ?? '',
|
|
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY ?? '',
|
|
forcePathStyle: (process.env.S3_FORCE_PATH_STYLE ?? 'false').toLowerCase() === 'true',
|
|
healthWriteTestEnabled:
|
|
(process.env.S3_HEALTH_WRITE_TEST_ENABLED ?? 'false').toLowerCase() === 'true',
|
|
},
|
|
},
|
|
imageProcessing: {
|
|
enabled:
|
|
typeof process.env.IMAGE_PROCESSING_ENABLED === 'string'
|
|
? process.env.IMAGE_PROCESSING_ENABLED.toLowerCase() === 'true'
|
|
: (process.env.VIDEO_PROCESSING_ENABLED ?? 'false').toLowerCase() === 'true',
|
|
ffmpegPath:
|
|
process.env.IMAGE_PROCESSING_FFMPEG_PATH ??
|
|
process.env.VIDEO_PROCESSING_FFMPEG_PATH ??
|
|
'ffmpeg',
|
|
lowWidth: Number(process.env.IMAGE_PROCESSING_LOW_WIDTH ?? 360),
|
|
mediumWidth: Number(process.env.IMAGE_PROCESSING_MEDIUM_WIDTH ?? 720),
|
|
highWidth: Number(process.env.IMAGE_PROCESSING_HIGH_WIDTH ?? 1280),
|
|
quality: Number(process.env.IMAGE_PROCESSING_QUALITY ?? 78),
|
|
},
|
|
videoProcessing: {
|
|
enabled: (process.env.VIDEO_PROCESSING_ENABLED ?? 'false').toLowerCase() === 'true',
|
|
ffmpegPath: process.env.VIDEO_PROCESSING_FFMPEG_PATH ?? 'ffmpeg',
|
|
ffprobePath: process.env.VIDEO_PROCESSING_FFPROBE_PATH ?? '',
|
|
maxWidth: Number(process.env.VIDEO_PROCESSING_MAX_WIDTH ?? 1280),
|
|
maxFps: Number(process.env.VIDEO_PROCESSING_MAX_FPS ?? 30),
|
|
crf: Number(process.env.VIDEO_PROCESSING_CRF ?? 28),
|
|
preset: process.env.VIDEO_PROCESSING_PRESET ?? 'veryfast',
|
|
audioBitrateKbps: Number(process.env.VIDEO_PROCESSING_AUDIO_BITRATE_KBPS ?? 128),
|
|
generateThumbnails:
|
|
(process.env.VIDEO_PROCESSING_GENERATE_THUMBNAILS ?? 'true').toLowerCase() === 'true',
|
|
generateHls: (process.env.VIDEO_PROCESSING_GENERATE_HLS ?? 'true').toLowerCase() === 'true',
|
|
hlsSegmentDurationSeconds: Number(
|
|
process.env.VIDEO_PROCESSING_HLS_SEGMENT_DURATION_SECONDS ?? 4,
|
|
),
|
|
thumbnailWidth: Number(process.env.VIDEO_PROCESSING_THUMBNAIL_WIDTH ?? 720),
|
|
},
|
|
audioProcessing: {
|
|
enabled: (process.env.AUDIO_PROCESSING_ENABLED ?? 'false').toLowerCase() === 'true',
|
|
waveformPeaks: Number(process.env.AUDIO_WAVEFORM_PEAKS ?? 48),
|
|
},
|
|
logging: {
|
|
level: process.env.LOG_LEVEL ?? 'log',
|
|
requestEnabled: (process.env.REQUEST_LOGGING_ENABLED ?? 'true').toLowerCase() === 'true',
|
|
},
|
|
feedCache: {
|
|
enabled: (process.env.FEED_CACHE_ENABLED ?? 'true').toLowerCase() === 'true',
|
|
userFeedTtlSeconds: Number(process.env.FEED_CACHE_USER_TTL_SECONDS ?? 15),
|
|
trendingTtlSeconds: Number(process.env.FEED_CACHE_TRENDING_TTL_SECONDS ?? 30),
|
|
},
|
|
performance: {
|
|
feedTimingLogsEnabled:
|
|
(process.env.FEED_TIMING_LOGS_ENABLED ?? 'false').toLowerCase() === 'true',
|
|
},
|
|
passwordReset: {
|
|
codeExpiresMinutes: Number(process.env.PASSWORD_RESET_CODE_EXPIRES_MINUTES ?? 10),
|
|
maxAttempts: Number(process.env.PASSWORD_RESET_MAX_ATTEMPTS ?? 5),
|
|
tokenSecret: process.env.PASSWORD_RESET_TOKEN_SECRET ?? process.env.JWT_ACCESS_SECRET ?? '',
|
|
tokenExpiresIn: process.env.PASSWORD_RESET_TOKEN_EXPIRES_IN ?? '15m',
|
|
},
|
|
emailVerification: {
|
|
codeExpiresMinutes: Number(process.env.EMAIL_VERIFICATION_CODE_EXPIRES_MINUTES ?? 10),
|
|
maxAttempts: Number(process.env.EMAIL_VERIFICATION_MAX_ATTEMPTS ?? 5),
|
|
},
|
|
swagger: {
|
|
title: process.env.SWAGGER_TITLE ?? 'Oudelaa API',
|
|
description: process.env.SWAGGER_DESCRIPTION ?? 'Social media backend API documentation',
|
|
version: process.env.SWAGGER_VERSION ?? '1.0.0',
|
|
path: process.env.SWAGGER_PATH ?? 'docs',
|
|
},
|
|
});
|