Skip to content

Configuration

Configuration is loaded by reflecting a config class. createApp() defaults to BaseAppConfig, but apps usually extend it.

ts
import { BaseAppConfig, Env } from '@zyno-io/ts-server-foundation';

class AppConfig extends BaseAppConfig {
    STRIPE_KEY_SECRET!: string;
    MAX_UPLOAD_BYTES = 10_000_000;
}

Env.APP_ENV = 'test';

Loading Order

ConfigLoader creates the config class, applies defaultConfig, then loads env files and Env through @zyno-io/config.

Loaded string values receive configuration-specific primitive coercion for reflected numbers, booleans, and matching literals. The completed config instance is then reflected-validated, so required fields, unions, constraints, custom validators, and invalid numeric values such as NaN fail application startup. Configuration loading does not run the general reflected deserializer registry: transforms such as TrimmedString and phone normalization are not applied automatically.

Env files are read from the process cwd:

  1. .env
  2. .env.local
  3. .env.development and .env.development.local in test mode
  4. .env.${APP_ENV}
  5. .env.${APP_ENV}.local

Values from Env override file values.

Keys ending in _SECRET may contain encrypted @zyno-io/config payloads. They are decrypted while loading when CONFIG_DECRYPTION_SECRET is set; CONFIG_DECRYPTION_KEY is also supported as a fallback for older deployments. Encrypted _SECRET values from process env are decrypted the same way.

Env Behavior

Env is the only runtime bridge to process.env. It is preloaded from process.env, typed as optional strings, and exported from the package root.

Config loading reads from Env without deleting consumed keys from process.env. Values loaded into the typed config object remain available to later code and child processes.

Required Environment

APP_ENV is required only when NODE_ENV=production. The loader infers APP_ENV=test under Node's test runner and otherwise defaults to development outside production.

Built-In Configuration And Environment Surface

BaseAppConfig owns the reflected application settings used during createApp(). Some observability keys below are read directly from Env by the early telemetry bootstrap instead, so they do not need to be declared on BaseAppConfig unless an application wants to load them through a custom config class.

Application

VariableTypeDefaultDescription
APP_ENVstringtest/development inferred; required in productionApplication environment.
DEVCONSOLE_ENABLEDbooleanenabled in developmentEnable or disable /_devconsole independently of APP_ENV.
PORTnumber3000HTTP server port. Ignored in APP_ENV=test unless frameworkConfig.port or serverConfig.port is provided.
USE_REAL_IP_HEADERbooleanunsetTrust proxy remote-address headers.
HTTP_MAX_REQUEST_BODY_BYTESnumber104857600Maximum decoded request body bytes.
HTTP_MAX_REQUEST_COMPRESSED_BODY_BYTESnumber26214400Maximum compressed request body bytes before gzip decoding.
HTTP_MAX_FORM_FIELDSnumber10000Maximum URL-encoded or multipart text fields and imported form structure nodes.
HTTP_MAX_FORM_FIELD_NAME_LENGTHnumber2048Maximum decoded form field-name length.
HTTP_MAX_FORM_DEPTHnumber16Maximum bracket/object nesting depth in form bodies.
HTTP_MAX_FORM_ARRAY_INDEXnumber10000Maximum explicit array index accepted in a form field name.

Database

VariableTypeDefaultDescription
DB_ADAPTER'mysql' | 'postgres'unsetDialect used by shared createDatabase(config, entities) calls.
TSF_TEST_DATABASE_NAMEstringunsetInternal test database override used by TestingFacade.

MySQL

VariableTypeDefault
MYSQL_HOSTstringunset
MYSQL_PORTnumberunset
MYSQL_USERstringunset
MYSQL_PASSWORD_SECRETstringunset
MYSQL_DATABASEstringunset
MYSQL_CONNECTION_LIMITnumber10 production, 5 development/test
MYSQL_MIN_IDLE_CONNECTIONSnumberunset
MYSQL_IDLE_TIMEOUT_SECONDSnumber60 production, 5 development/test

PostgreSQL

VariableTypeDefault
PG_HOSTstringunset
PG_PORTnumberunset
PG_USERstringunset
PG_PASSWORD_SECRETstringunset
PG_DATABASEstringunset
PG_SCHEMAstringunset
PG_SSLbooleanunset
PG_SSL_REJECT_UNAUTHORIZEDbooleanunset
PG_CONNECTION_LIMITnumber10 production, 5 development/test
PG_IDLE_TIMEOUT_SECONDSnumber60 production, 5 development/test

Authentication

VariableTypeDefault
AUTH_JWT_ISSUERstringunset
AUTH_JWT_EXPIRATION_MINSnumberruntime fallback 60
AUTH_JWT_COOKIE_NAMEstringruntime fallback jwt
AUTH_JWT_SECRETstringunset
AUTH_JWT_SECRET_B64stringunset
AUTH_JWT_ED_SECRETstringunset
AUTH_JWT_ENABLE_VERIFYbooleantrue
AUTH_BASIC_SECRETstringunset

Crypto

VariableTypeDefault
CRYPTO_SECRETstringunset
CRYPTO_IV_LENGTHnumber12

Redis And Workers

VariableTypeDefault
REDIS_SENTINEL_HOSTstringunset
REDIS_SENTINEL_PORTnumberunset
REDIS_SENTINEL_NAMEstringunset
REDIS_HOSTstringunset
REDIS_PORTnumberunset
REDIS_PREFIXstringpackage name
REDIS_UNAVAILABLE_ALERT_AFTER_MSnumber60000
CACHE_REDIS_*string/numberfalls back to REDIS_*
MUTEX_REDIS_*string/numberfalls back to REDIS_*
BROADCAST_REDIS_*string/numberfalls back to REDIS_*
MESH_REDIS_*string/numberfalls back to REDIS_*
BULL_REDIS_*string/numberfalls back to REDIS_*
BULL_QUEUEstringdefault
MUTEX_MODE'local' | 'redis'local
ENABLE_JOB_RUNNERbooleanunset
TEST_KEEP_DBstringunset
TEST_RUN_TSstringunset

Observability

VariableTypeDefault
SENTRY_DSNstringunset
OTEL_EXPORTER_OTLP_ENDPOINTstringunset
OTEL_EXPORTER_OTLP_TRACES_ENDPOINTstringunset
OTEL_EXPORTER_OTLP_METRICS_ENDPOINTstringunset
OTEL_METRICS_ENDPOINT_ENABLEDbooleanunset
OTEL_DEBUGbooleanunset
OTEL_SDK_DISABLEDbooleanunset
ALERTS_SLACK_WEBHOOK_URLstringunset

SRPC

VariableTypeDefault
SRPC_AUTH_SECRETstringunset
SRPC_AUTH_CLOCK_DRIFT_MSnumber30000

HTTP And OpenAPI

VariableTypeDefaultDescription
HTTP_REQUEST_LOGGING_MODE'none' | 'e2e' | 'finish' | 'errors'errors in test, e2e otherwiseControls request start, finish, and error logs.
HEALTHZ_ENABLE_REQUEST_LOGGINGbooleanfalseIncludes /healthz in normal request logging.
ENABLE_OPENAPI_SCHEMAbooleandevelopment outside Node testsWrites openapi.yaml after startup; legacy route fallback when the route flag is unset.
ENABLE_OPENAPI_ROUTEbooleanenabled in development/testServes /openapi.json and /openapi.yaml; takes precedence over the schema flag.
ENABLE_PINO_PRETTYbooleanenabled in development/testEnables pretty log output.
ENABLE_PINO_SINGLE_LINEbooleanenabled in development/testKeeps pretty log entries on one line.
LOG_LEVELstringdebug outside production, info in productionSets the pino-pretty output filter; JSON logging is not filtered by this key.

Mail

VariableTypeDefault
MAIL_FROMstringunset
MAIL_FROM_NAMEstringunset
MAIL_PROVIDER'smtp' | 'postmark'smtp
SMTP_HOSTstring127.0.0.1
SMTP_PORTnumber1025
SMTP_USERstringunset
SMTP_PASSWORD_SECRETstringunset
SMTP_TLSbooleanfalse
POSTMARK_SECRETstringunset

isDevFeatureEnabled

ts
import { isDevFeatureEnabled } from '@zyno-io/ts-server-foundation';

if (isDevFeatureEnabled(config.ENABLE_OPENAPI_SCHEMA)) {
    // enabled
}

'1' and 'true' enable a flag. '0' and 'false' disable a flag. Undefined flags default to enabled in development/test and disabled in production unless a different default is passed.

Released under the MIT License.