environment-configuration
Environment Configuration with @pgpmjs/env
Unified environment configuration for PGPM and Constructive projects. Provides config file discovery, environment variable parsing, and hierarchical option merging.
When to Apply
Use this skill when:
- Configuring PostgreSQL connections programmatically
- Setting up PGPM environment options
- Managing database configuration across environments
- Writing code that needs consistent environment handling
Installation
pnpm add @pgpmjs/env
Core Concepts
Configuration Hierarchy
Options are merged in this order (later overrides earlier):
- PGPM defaults — Built-in sensible defaults
- Config file —
pgpm.jsondiscovered via walkUp - Environment variables —
PGHOST,PGPORT, etc. - Runtime overrides — Passed programmatically
Basic Usage
getEnvOptions()
Get merged PGPM options:
import { getEnvOptions } from '@pgpmjs/env';
const options = getEnvOptions();
// Returns merged options from defaults + config + env vars
// With runtime overrides
const options = getEnvOptions({
pg: { database: 'mydb' }
});
// With custom working directory
const options = getEnvOptions({}, '/path/to/project');
getConnEnvOptions()
Get database connection options specifically:
import { getConnEnvOptions } from '@pgpmjs/env';
const connOptions = getConnEnvOptions();
// Returns db-specific options with roles and connections resolved
getDeploymentEnvOptions()
Get deployment-specific options:
import { getDeploymentEnvOptions } from '@pgpmjs/env';
const deployOptions = getDeploymentEnvOptions();
// Returns deployment options (useTx, fast, usePlan, etc.)
Environment Variables
PostgreSQL Connection
| Variable | Description | Default |
|---|---|---|
PGHOST |
Database host | localhost |
PGPORT |
Database port | 5432 |
PGDATABASE |
Database name | — |
PGUSER |
Database user | postgres |
PGPASSWORD |
Database password | — |
Database Configuration
| Variable | Description |
|---|---|
PGROOTDATABASE |
Root database for admin operations |
PGTEMPLATE |
Template database for createdb |
DB_PREFIX |
Prefix for database names |
DB_EXTENSIONS |
Comma-separated list of extensions |
DB_CWD |
Working directory for database operations |
Connection Credentials
| Variable | Description |
|---|---|
DB_CONNECTION_USER |
App connection user |
DB_CONNECTION_PASSWORD |
App connection password |
DB_CONNECTION_ROLE |
App connection role |
DB_CONNECTIONS_APP_USER |
App-level user |
DB_CONNECTIONS_APP_PASSWORD |
App-level password |
DB_CONNECTIONS_ADMIN_USER |
Admin-level user |
DB_CONNECTIONS_ADMIN_PASSWORD |
Admin-level password |
Deployment Options
| Variable | Description |
|---|---|
DEPLOYMENT_USE_TX |
Use transactions for deployment |
DEPLOYMENT_FAST |
Fast deployment mode |
DEPLOYMENT_USE_PLAN |
Use deployment plan |
DEPLOYMENT_CACHE |
Enable deployment caching |
DEPLOYMENT_TO_CHANGE |
Deploy to specific change |
Server Configuration
| Variable | Description |
|---|---|
PORT |
Server port |
SERVER_HOST |
Server host |
SERVER_TRUST_PROXY |
Trust proxy headers |
SERVER_ORIGIN |
Server origin URL |
SERVER_STRICT_AUTH |
Strict authentication mode |
CDN/Storage
| Variable | Description |
|---|---|
BUCKET_PROVIDER |
Storage provider (s3, minio) |
BUCKET_NAME |
Bucket name |
AWS_REGION |
AWS region |
AWS_ACCESS_KEY_ID |
AWS access key |
AWS_SECRET_ACCESS_KEY |
AWS secret key |
MINIO_ENDPOINT |
MinIO endpoint URL |
Jobs Configuration
| Variable | Description |
|---|---|
JOBS_SCHEMA |
Schema for job tables |
JOBS_SUPPORT_ANY |
Support any job type |
JOBS_SUPPORTED |
Comma-separated supported job types |
INTERNAL_GATEWAY_URL |
Internal gateway URL |
INTERNAL_JOBS_CALLBACK_URL |
Jobs callback URL |
INTERNAL_JOBS_CALLBACK_PORT |
Jobs callback port |
Error Output
| Variable | Description |
|---|---|
PGPM_ERROR_QUERY_HISTORY_LIMIT |
Query history limit in errors |
PGPM_ERROR_MAX_LENGTH |
Max error message length |
PGPM_ERROR_VERBOSE |
Verbose error output |
Config File Discovery
loadConfigSync()
Load pgpm.json by walking up directory tree:
import { loadConfigSync } from '@pgpmjs/env';
const config = loadConfigSync('/path/to/project');
// Finds nearest pgpm.json walking up from given path
loadConfigSyncFromDir()
Load config from specific directory:
import { loadConfigSyncFromDir } from '@pgpmjs/env';
const config = loadConfigSyncFromDir('/path/to/project');
resolvePgpmPath()
Find the pgpm.json file path:
import { resolvePgpmPath } from '@pgpmjs/env';
const pgpmPath = resolvePgpmPath('/path/to/project');
// Returns full path to pgpm.json or undefined
Workspace Resolution
resolvePnpmWorkspace()
Find pnpm-workspace.yaml:
import { resolvePnpmWorkspace } from '@pgpmjs/env';
const workspacePath = resolvePnpmWorkspace('/path/to/project');
resolveLernaWorkspace()
Find lerna.json:
import { resolveLernaWorkspace } from '@pgpmjs/env';
const lernaPath = resolveLernaWorkspace('/path/to/project');
resolveWorkspaceByType()
Find workspace config by type:
import { resolveWorkspaceByType, WorkspaceType } from '@pgpmjs/env';
const path = resolveWorkspaceByType('/path/to/project', 'pnpm');
// WorkspaceType: 'pnpm' | 'lerna' | 'npm'
Utility Functions
walkUp()
Walk up directory tree to find a file:
import { walkUp } from '@pgpmjs/env';
const found = walkUp('/start/path', 'pgpm.json');
// Returns path to file or undefined
getEnvVars()
Parse environment variables into PgpmOptions:
import { getEnvVars } from '@pgpmjs/env';
const envOptions = getEnvVars();
// Or with custom env object
const envOptions = getEnvVars(process.env);
getNodeEnv()
Get normalized NODE_ENV:
import { getNodeEnv } from '@pgpmjs/env';
const env = getNodeEnv();
// Returns 'development' | 'production' | 'test'
parseEnvBoolean()
Parse boolean environment variable:
import { parseEnvBoolean } from '@pgpmjs/env';
parseEnvBoolean('true'); // true
parseEnvBoolean('1'); // true
parseEnvBoolean('yes'); // true
parseEnvBoolean('false'); // false
parseEnvBoolean(undefined); // undefined
parseEnvNumber()
Parse numeric environment variable:
import { parseEnvNumber } from '@pgpmjs/env';
parseEnvNumber('5432'); // 5432
parseEnvNumber('invalid'); // undefined
parseEnvNumber(undefined); // undefined
pgpm.json Configuration
Example pgpm.json with environment options:
{
"name": "my-module",
"version": "1.0.0",
"db": {
"rootDb": "postgres",
"template": "template1",
"prefix": "myapp_",
"extensions": ["uuid-ossp", "pgcrypto"],
"roles": {
"admin": "admin_role",
"app": "app_role",
"anonymous": "anon_role",
"authenticated": "auth_role"
},
"connections": {
"app": {
"user": "app_user",
"password": "app_password"
},
"admin": {
"user": "admin_user",
"password": "admin_password"
}
}
},
"deployment": {
"useTx": true,
"fast": false,
"usePlan": true
}
}
Integration with pgsql-test
import { getConnEnvOptions } from '@pgpmjs/env';
import { getConnections } from 'pgsql-test';
const connOptions = getConnEnvOptions();
const { db, teardown } = await getConnections(connOptions);
Integration with pgpm CLI
The pgpm CLI uses @pgpmjs/env internally. Quick setup:
# Export standard PostgreSQL env vars
eval "$(pgpm env)"
# Now all pgpm commands use these vars
pgpm deploy --createdb
Best Practices
- Use getEnvOptions(): Let the library handle merging
- Config file for defaults: Put project defaults in pgpm.json
- Env vars for secrets: Never commit passwords to pgpm.json
- Override at runtime: Pass overrides for test-specific config
- Consistent cwd: Pass explicit cwd when running from different directories
References
- Related skill:
pgpm-clifor CLI commands - Related skill:
pgpm-workspacefor workspace configuration - Related skill:
github-workflows-pgpmfor CI/CD environment setup