Skip to content
/ pb-env Public

PB-ENV is a powerful, secure replacement for dotenv that supports encryption, image variables, directory imports, and advanced features using `.pb` files. Compatible with Node.js, React, and EJS environments.

License

Notifications You must be signed in to change notification settings

zppqrr/pb-env

Repository files navigation

PB-ENV - Advanced Environment Configuration

npm version TypeScript React EJS

PB-ENV is a powerful, secure replacement for dotenv that supports encryption, image variables, directory imports, and advanced features using .pb files. Compatible with Node.js, React, and EJS environments.

🚀 Features

🔒 Security & Encryption

  • AES-256-GCM encryption for sensitive data
  • Automatic key management with secure file permissions
  • Key rotation support
  • Encrypted JSON configurations

📷 Image Variables

  • Direct image storage in config files
  • Automatic base64 encoding/decoding
  • Image caching for performance
  • React components for easy image rendering

📁 Directory Imports

  • Import entire directories with HANDLERS_DIR=./src/handlers
  • Recursive directory traversal
  • File content access in templates and components
  • Extraction to filesystem

🔧 Advanced Configuration

  • Type validation (string, number, boolean, JSON, image, directory)
  • Variable interpolation with ${VAR_NAME}
  • Environment-specific configs
  • Configuration inheritance
  • Hot reloading with cache invalidation

⚛️ React Integration

  • Custom hooks for configuration access
  • Image components with automatic data URL generation
  • Directory file viewers and navigation components
  • Configuration debugger component

🎨 EJS Integration

  • Template helpers for easy variable access
  • Express.js middleware for automatic setup
  • Image data URL generation for templates
  • Directory file rendering in views

📦 Installation

npm install @zppqr/pb-env

🚀 Quick Start

Node.js Usage

// Load configuration
require('@zppqr/pb-env').config();

// Or with ES modules
import pb from '@zppqr/pb-env';
pb.config();

// Access variables
console.log(process.env.APP_NAME);
console.log(process.env.PORT); // Automatically typed

React Usage

import React from 'react';
import { usePBConfig, PBImage, PBDirectoryList } from '@zppqr/pb-env';

function App() {
  const { config, loading, error } = usePBConfig();

  if (loading) return <div>Loading configuration...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      <h1>{config.APP_NAME}</h1>
      <PBImage configKey="LOGO_IMAGE" alt="Logo" />
      <PBDirectoryList 
        configKey="TEMPLATES_DIR" 
        onFileSelect={(file) => console.log('Selected:', file)}
      />
    </div>
  );
}

EJS Usage

// Express.js setup
import express from 'express';
import { pbEJSMiddleware } from '@zppqr/pb-env';

const app = express();

// Add PB middleware
app.use(pbEJSMiddleware({
  path: './config.pb',
  environment: process.env.NODE_ENV
}));

app.set('view engine', 'ejs');
<!-- In your EJS template -->
<h1><%= APP_NAME %></h1>
<img src="<%= pb.getImageDataUrl('LOGO_IMAGE') %>" alt="Logo">

<% pb.getDirectoryFiles('TEMPLATES_DIR').forEach(file => { %>
  <div><%= file %></div>
<% }) %>

📝 .pb File Format

# Metadata
@version 2.0.0
@author "Your Name"
@description "Application configuration"

# Basic variables
APP_NAME="My Application"
APP_VERSION="1.0.0"

# Typed variables
PORT=3000
@type number
@required

DEBUG=true
@type boolean

# Encrypted sensitive data
DATABASE_PASSWORD="secret-password"
@encrypted
@required

API_KEY="sk-1234567890"
@encrypted

# Image variables
LOGO_IMAGE="./assets/logo.png"
@type image
@description "Company logo"

HERO_BANNER="./assets/hero.jpg"
@type image

# Directory imports
HANDLERS_DIR="./src/handlers"
@type directory
@description "API route handlers"

TEMPLATES_DIR="./email-templates"
@type directory

# JSON configuration (can be encrypted)
DATABASE_CONFIG='{
  "host": "localhost",
  "port": 5432,
  "ssl": true
}'
@type json
@encrypted

# Multiline values
PRIVATE_KEY="""
-----BEGIN PRIVATE KEY-----
Your private key content here
Can span multiple lines safely
-----END PRIVATE KEY-----
"""
@encrypted

# Variable interpolation
API_URL="https://api.${APP_NAME}.com"
DATABASE_URL="postgresql://user:${DATABASE_PASSWORD}@localhost/${APP_NAME}"

# Required with defaults
REDIS_URL=""
@required
@default "redis://localhost:6379"

LOG_LEVEL="info"
@default "warn"

# Extend other configs
@extends base.pb, secrets.pb

🛠️ CLI Usage

# Initialize new config
pb init

# Validate configuration
pb validate

# Load specific environment
pb load -e production

# Encrypt a value
pb encrypt "my-secret-value"

# Decrypt a value
pb decrypt "PB_ENCRYPTED:..."

# Use custom config file
pb validate -f custom-config.pb

⚛️ React API

Hooks

import { 
  usePBConfig, 
  usePBVariable, 
  usePBImage, 
  usePBDirectory,
  usePBEnvironment 
} from '@zppqr/pb-env';

// Load entire configuration
const { config, loading, error, reload } = usePBConfig();

// Get specific variable with type safety
const appName = usePBVariable('APP_NAME', 'Default App');
const port = usePBVariable('PORT', 3000);

// Work with images
const logoData = usePBImage('LOGO_IMAGE');
// Returns: { dataUrl, mimeType, size, hash, buffer }

// Work with directories
const handlersData = usePBDirectory('HANDLERS_DIR');
// Returns: { files, getFile, fileCount }

// Environment switching
const { environment, switchEnvironment } = usePBEnvironment();

Components

import { PBImage, PBFileViewer, PBDirectoryList, PBConfigDebugger } from '@zppqr/pb-env';

// Display images from config
<PBImage 
  configKey="LOGO_IMAGE" 
  alt="Company Logo"
  className="logo"
  fallback={<div>Logo not found</div>}
  onLoad={() => console.log('Image loaded')}
/>

// View files from directory imports
<PBFileViewer 
  configKey="TEMPLATES_DIR"
  filePath="welcome.html"
  className="code-viewer"
/>

// List directory contents
<PBDirectoryList 
  configKey="HANDLERS_DIR"
  onFileSelect={(file) => setSelectedFile(file)}
  className="file-list"
/>

// Debug configuration (development only)
<PBConfigDebugger className="debug-panel" />

🎨 EJS API

Middleware Setup

import express from 'express';
import { pbEJSMiddleware, PBEJSHelpers } from '@zppqr/pb-env';

const app = express();

// Automatic setup with middleware
app.use(pbEJSMiddleware({
  path: './config.pb',
  environment: process.env.NODE_ENV,
  enableImageCache: true
}));

// Manual setup
PBEJSHelpers.initialize({ path: './config.pb' });
app.locals = PBEJSHelpers.createEJSLocals();

Template Usage

<!-- Basic variable access -->
<h1><%= APP_NAME %></h1>
<p>Version: <%= APP_VERSION %></p>

<!-- Typed variable access -->
<p>Port: <%= pb.getNumber('PORT') %></p>
<p>Debug: <%= pb.getBoolean('DEBUG') %></p>

<!-- Image handling -->
<img src="<%= pb.getImageDataUrl('LOGO_IMAGE') %>" alt="Logo">

<!-- Directory file access -->
<% const handlerFiles = pb.getDirectoryFiles('HANDLERS_DIR'); %>
<ul>
  <% handlerFiles.forEach(file => { %>
    <li><%= file %></li>
  <% }); %>
</ul>

<!-- Render specific file content -->
<pre><%= pb.getDirectoryFile('TEMPLATES_DIR', 'email.html') %></pre>

<!-- JSON configuration -->
<% const dbConfig = pb.getJSON('DATABASE_CONFIG'); %>
<p>Database: <%= dbConfig.host %>:<%= dbConfig.port %></p>

🔒 Security Best Practices

Encryption

# In .pb file
SECRET_KEY="my-secret"
@encrypted

DATABASE_CONFIG='{"password": "secret"}'
@type json
@encrypted

Key Management

  • Keys are automatically generated on first use
  • Stored in .pb.key with secure permissions (600)
  • Never commit .pb.key to version control
  • Use pb rotate-key for key rotation

Environment Separation

# Development
.env.pb

# Production
.env.production.pb

# Testing
.env.test.pb

📊 Performance Features

  • Caching: Configuration parsed once and cached
  • Hot Reloading: Automatic cache invalidation on file changes
  • Lazy Loading: Images and directories loaded on demand
  • Optimized Parsing: Efficient regex-based parsing
  • Memory Management: Automatic cleanup of unused resources

🔄 Migration from dotenv

  1. Rename files: .env.env.pb
  2. Add type annotations:
    # Before
    PORT=3000
    
    # After
    PORT=3000
    @type number
  3. Encrypt sensitive values:
    # Before
    DATABASE_PASSWORD=secret
    
    # After
    DATABASE_PASSWORD="secret"
    @encrypted
  4. Update imports:
    // Before
    require('dotenv').config();
    
    // After
    require('@zppqr/pb-env').config();

🧪 Testing

# Run tests
npm test

# Run tests in watch mode
npm run test:watch

# Run with coverage
npm test -- --coverage

🤝 Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📄 License

MIT License - see LICENSE file for details.

🆘 Support

🗺️ Roadmap

  • Cloud Sync - Secure cloud synchronization
  • VS Code Extension - Syntax highlighting and IntelliSense
  • Web UI - Visual configuration management
  • Database Integration - Direct database connections
  • Audit Logging - Configuration change tracking
  • Schema Validation - JSON schema support
  • Plugin System - Extensible architecture

About

PB-ENV is a powerful, secure replacement for dotenv that supports encryption, image variables, directory imports, and advanced features using `.pb` files. Compatible with Node.js, React, and EJS environments.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •