405 lines
7.8 KiB
TypeScript
405 lines
7.8 KiB
TypeScript
import { plainToClass } from 'class-transformer';
|
|
import { IsBoolean, IsEnum, IsNotEmpty, IsNumber, IsString, Max, Min, validateSync } from 'class-validator';
|
|
import { NodeEnv } from '../types/NodeEnv';
|
|
import { ShopFiatCurrency } from '../types/ShopFiatCurrency';
|
|
import { IsBase64 } from '../validation/decorators/isBase64';
|
|
import { IsConfirmationTiers } from '../validation/decorators/isConfirmationTiers';
|
|
import { IsEnabledPaymentMethods } from '../validation/decorators/isEnabledPaymentMethods';
|
|
import { ElectrumNetwork } from '../types/ElectrumNetwork';
|
|
import { MoneroNetwork } from '../types/MoneroNetwork';
|
|
|
|
class EnvironmentVariables {
|
|
@IsNotEmpty()
|
|
@IsEnum(NodeEnv)
|
|
NODE_ENV: NodeEnv;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
BACKEND_PORT: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
POSTGRES_USER: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
POSTGRES_PASSWORD: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
POSTGRES_DB: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
POSTGRES_HOST: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
POSTGRES_PORT: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsBoolean()
|
|
POSTGRES_MIGRATIONS_RUN: boolean;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
CORS_ORIGINS: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
JWT_SECRET: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
JWT_EXPIRES_IN_MS: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
CMS_PASSWORD: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
SHOP_NAME: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsEnum(ShopFiatCurrency)
|
|
SHOP_FIAT_CURRENCY: ShopFiatCurrency;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
MULTER_PRODUCT_THUMB_ALLOWED_MIMES: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
@Max(10 * 1024 * 1024) // 10MB
|
|
MULTER_PRODUCT_THUMB_MAX_FILE_BYTES: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
MULTER_SHOP_LOGO_ALLOWED_MIMES: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
@Max(10 * 1024 * 1024) // 10MB
|
|
MULTER_SHOP_LOGO_MAX_FILE_BYTES: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
MULTER_SHOP_FAVICON_ALLOWED_MIMES: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
@Max(10 * 1024 * 1024) // 10MB
|
|
MULTER_SHOP_FAVICON_MAX_FILE_BYTES: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
@Max(256)
|
|
VALIDATION_PRODUCT_TITLE_MAX_LENGTH: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
@Max(256)
|
|
VALIDATION_CATEGORY_NAME_MAX_LENGTH: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
@Max(64)
|
|
VALIDATION_DISCOUNT_CODE_MAX_LENGTH: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
@Max(100)
|
|
VALIDATION_VARIANT_IMAGES_MAX: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
MULTER_DIGITAL_STOCK_ATTACHMENT_ALLOWED_MIMES: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
@Max(50 * 1024 * 1024) // 50MB
|
|
MULTER_DIGITAL_STOCK_ATTACHMENT_MAX_FILE_BYTES: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
@Max(20)
|
|
VALIDATION_DIGITAL_STOCK_ATTACHMENTS_MAX: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
@Max(1000)
|
|
VALIDATION_SHIPPING_NOTE_MIN_LENGTH: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
@Max(10000)
|
|
VALIDATION_SHIPPING_NOTE_MAX_LENGTH: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
@Max(10000)
|
|
VALIDATION_ORDER_MESSAGE_MAX_LENGTH: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(4)
|
|
@Max(8)
|
|
CAPTCHA_LENGTH: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1000)
|
|
@Max(3_600_000)
|
|
THROTTLE_TTL_MS: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
@Max(10_000)
|
|
THROTTLE_LIMIT: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
SIGNED_COOKIE_JWT_SECRET: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
SIGNED_COOKIE_FEEDBACK_NAME: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
SIGNED_COOKIE_FEEDBACK_EXPIRES_IN_MS: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
SIGNED_COOKIE_CART_NAME: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
SIGNED_COOKIE_CART_EXPIRES_IN_MS: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
SIGNED_COOKIE_CAPTCHA_NAME: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
SIGNED_COOKIE_CAPTCHA_EXPIRES_IN_MS: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
SIGNED_COOKIE_DISCOUNT_NAME: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
SIGNED_COOKIE_DISCOUNT_EXPIRES_IN_MS: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
SIGNED_COOKIE_ERROR_NAME: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
SIGNED_COOKIE_ERROR_EXPIRES_IN_MS: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
SIGNED_COOKIE_CHECKOUT_SESSION_NAME: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
SIGNED_COOKIE_ORDER_AUTH_NAME: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
SIGNED_COOKIE_ORDER_AUTH_EXPIRES_IN_MS: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
SIGNED_COOKIE_THEME_NAME: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
SIGNED_COOKIE_THEME_EXPIRES_IN_MS: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
COINGECKO_API_BASE_URL: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
COINPAPRIKA_API_BASE_URL: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
COINPAPRIKA_RATE_FETCH_TIMEOUT_MS: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
COINGECKO_RATE_FETCH_TIMEOUT_MS: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
@IsBase64({ byteLength: 32 })
|
|
BASE64_ENCRYPTION_KEY: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
@IsConfirmationTiers()
|
|
MONERO_CONFIRMATION_TIERS: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
@IsConfirmationTiers()
|
|
BITCOIN_CONFIRMATION_TIERS: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
@IsEnabledPaymentMethods()
|
|
PAYMENT_METHODS_ENABLED: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(60000)
|
|
ORDER_CHECKOUT_VALIDITY_MS: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
ORDER_CHECKOUT_STATUS_REFRESH_SEC: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(60000)
|
|
ORDER_SHIPPING_PAYMENT_VALIDITY_MS: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
ORDER_DATA_RETENTION_DAYS: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(0)
|
|
@Max(Number.MAX_SAFE_INTEGER)
|
|
MONERO_MIN_INCOMING_ATOMIC: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(0)
|
|
@Max(Number.MAX_SAFE_INTEGER)
|
|
BITCOIN_MIN_INCOMING_ATOMIC: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
MONERO_DAEMON_ADDRESS: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsEnum(MoneroNetwork)
|
|
MONERO_NETWORK: MoneroNetwork;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
MONERO_WALLET_RPC_HOST: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
@Max(65535)
|
|
MONERO_WALLET_RPC_PORT: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
MONERO_WALLET_RPC_USERNAME: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
MONERO_WALLET_RPC_PASSWORD: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1000)
|
|
MONERO_WALLET_RPC_TIMEOUT_MS: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsEnum(ElectrumNetwork)
|
|
ELECTRUM_NETWORK: ElectrumNetwork;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
ELECTRUM_SERVER: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
ELECTRUM_DAEMON_HOST: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
@Max(65535)
|
|
ELECTRUM_DAEMON_PORT: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
ELECTRUM_DAEMON_RPC_USER: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
ELECTRUM_DAEMON_RPC_PASSWORD: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1000)
|
|
ELECTRUM_DAEMON_RPC_TIMEOUT_MS: number;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
ELECTRUM_WALLET_PASSWORD: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
SIMPLEX_WS_URL: string;
|
|
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
SIMPLEX_BOT_DISPLAY_NAME: string;
|
|
}
|
|
|
|
export const validate = (config: Record<string, unknown>) => {
|
|
const validatedConfig = plainToClass(EnvironmentVariables, config, {
|
|
enableImplicitConversion: true
|
|
});
|
|
|
|
const errors = validateSync(validatedConfig, {
|
|
skipMissingProperties: false
|
|
});
|
|
|
|
if (errors.length > 0) {
|
|
throw new Error(errors.toString());
|
|
}
|
|
|
|
return validatedConfig;
|
|
};
|