UNPKG

dbl-utils

Version:

Utilities for dbl, adba and others projects

698 lines (619 loc) 20.6 kB
# Resolve-Refs: Real-World Examples This file contains comprehensive examples showing how to use the `resolve-refs` utility in real-world scenarios. ## Table of Contents 1. [Multi-Environment Configuration](#multi-environment-configuration) 2. [Dynamic API Documentation](#dynamic-api-documentation) 3. [Component Template System](#component-template-system) 4. [Internationalization with Templates](#internationalization-with-templates) 5. [Database Configuration Management](#database-configuration-management) 6. [Feature Flag System](#feature-flag-system) 7. [Build Pipeline Configuration](#build-pipeline-configuration) 8. [E-commerce Product Catalog](#e-commerce-product-catalog) ## Multi-Environment Configuration Manage different configurations across development, staging, and production environments. ```typescript import resolveRefs from 'dbl-utils/src/resolve-refs'; const environmentConfig = { // Environment-specific variables environments: { development: { domain: "localhost", port: 3000, protocol: "http", debug: true, database: { host: "localhost", port: 5432 } }, staging: { domain: "staging.myapp.com", port: 443, protocol: "https", debug: true, database: { host: "staging-db.myapp.com", port: 5432 } }, production: { domain: "myapp.com", port: 443, protocol: "https", debug: false, database: { host: "prod-db.myapp.com", port: 5432 } } }, // Current environment (would be set via ENV variable) currentEnv: "development", // Application configuration using templates app: { ref: "$templates/appConfig" }, services: { api: { ref: "$templates/service", path: "/api/v1", timeout: 30000 }, auth: { ref: "$templates/service", path: "/auth", timeout: 10000 }, uploads: { ref: "$templates/service", path: "/uploads", timeout: 60000 } }, templates: { // Base application configuration appConfig: { ".": { env: "$./currentEnv", baseUrl: "${environments/${./currentEnv}/protocol}://${environments/${./currentEnv}/domain}:${environments/${./currentEnv}/port}", apiUrl: "$./baseUrl/api/v1", debugMode: "${environments/${./currentEnv}/debug}", database: { connectionString: "postgresql://user:pass@${environments/${./currentEnv}/database/host}:${environments/${./currentEnv}/database/port}/myapp" } } }, // Service configuration template service: { path: "/", timeout: 30000, retries: 3, ".": { url: "${app/baseUrl}${./path}", config: { baseURL: "$./url", timeout: "$./timeout", retries: "$./retries", headers: { "User-Agent": "MyApp/1.0", "X-Environment": "${app/env}" } } } } } }; const config = resolveRefs(environmentConfig); console.log(config.app.baseUrl); // "http://localhost:3000" console.log(config.services.api.url); // "http://localhost:3000/api/v1" console.log(config.app.database.connectionString); // "postgresql://user:pass@localhost:5432/myapp" ``` ## Dynamic API Documentation Generate API documentation with shared schemas and endpoint-specific overrides. ```typescript const apiDocumentation = { // API metadata info: { title: "User Management API", version: "2.1.0", baseUrl: "https://api.example.com/v2" }, // Reusable response schemas schemas: { User: { type: "object", properties: { id: { type: "integer", example: 123 }, name: { type: "string", example: "John Doe" }, email: { type: "string", example: "john@example.com" }, createdAt: { type: "string", format: "date-time" } } }, Error: { type: "object", properties: { code: { type: "integer" }, message: { type: "string" }, details: { type: "array", items: { type: "string" } } } } }, // API endpoints using templates endpoints: { getUsers: { ref: "$templates/endpoint", method: "GET", path: "/users", description: "Retrieve a list of users", responses: { 200: { ref: "$templates/successResponse", schema: "$schemas/User" } } }, createUser: { ref: "$templates/endpoint", method: "POST", path: "/users", description: "Create a new user", requestBody: { ref: "$schemas/User" }, responses: { 201: { ref: "$templates/successResponse", schema: "$schemas/User" }, 400: { ref: "$templates/errorResponse" } } }, getUserById: { ref: "$templates/endpoint", method: "GET", path: "/users/{id}", description: "Get user by ID", parameters: [ { name: "id", in: "path", type: "integer", required: true } ], responses: { 200: { ref: "$templates/successResponse", schema: "$schemas/User" }, 404: { ref: "$templates/errorResponse" } } } }, templates: { endpoint: { method: "GET", path: "/", description: "", parameters: [], responses: {}, ".": { operationId: "${./method}_${./path}", fullUrl: "${info/baseUrl}${./path}", summary: "${./description}", tags: ["${./path}" ], curl: "curl -X ${./method} \"${./fullUrl}\"", documentation: { method: "$./method", endpoint: "$./fullUrl", description: "$./description", parameters: "$./parameters", responses: "$./responses" } } }, successResponse: { description: "Successful operation", ".": { content: { "application/json": { schema: "$./schema" } } } }, errorResponse: { description: "Error occurred", ".": { content: { "application/json": { schema: "$schemas/Error" } } } } } }; const docs = resolveRefs(apiDocumentation); console.log(docs.endpoints.getUsers.fullUrl); // "https://api.example.com/v2/users" console.log(docs.endpoints.createUser.curl); // "curl -X POST \"https://api.example.com/v2/users\"" ``` ## Component Template System Create reusable UI component configurations with theme support. ```typescript const componentSystem = { // Theme configuration themes: { light: { colors: { primary: "#007bff", secondary: "#6c757d", success: "#28a745", danger: "#dc3545", background: "#ffffff", text: "#212529" }, spacing: { small: "8px", medium: "16px", large: "24px" } }, dark: { colors: { primary: "#0d6efd", secondary: "#6c757d", success: "#198754", danger: "#dc3545", background: "#212529", text: "#ffffff" }, spacing: { small: "8px", medium: "16px", large: "24px" } } }, currentTheme: "light", // Component instances components: { primaryButton: { ref: "$templates/button", variant: "primary", size: "medium", text: "Click Me" }, dangerButton: { ref: "$templates/button", variant: "danger", size: "small", text: "Delete", icon: "trash" }, loginForm: { ref: "$templates/form", title: "Login", fields: [ { ref: "$templates/input", name: "email", type: "email", label: "Email" }, { ref: "$templates/input", name: "password", type: "password", label: "Password" } ], submitButton: { ref: "$templates/button", variant: "primary", text: "Login" } } }, templates: { button: { variant: "primary", size: "medium", text: "Button", disabled: false, ".": { className: "btn btn-${./variant} btn-${./size}", style: { backgroundColor: "${themes/${../currentTheme}/colors/${./variant}}", color: "${themes/${../currentTheme}/colors/background}", padding: "${themes/${../currentTheme}/spacing/${./size}}", border: "1px solid ${themes/${../currentTheme}/colors/${./variant}}", borderRadius: "4px", cursor: "$./disabled ? 'not-allowed' : 'pointer'" }, props: { type: "button", disabled: "$./disabled", className: "$./className", style: "$./style" }, content: "$./text" } }, input: { type: "text", name: "", label: "", required: false, ".": { id: "input_${./name}", className: "form-control", style: { padding: "${themes/${../currentTheme}/spacing/small}", border: "1px solid ${themes/${../currentTheme}/colors/secondary}", borderRadius: "4px", backgroundColor: "${themes/${../currentTheme}/colors/background}", color: "${themes/${../currentTheme}/colors/text}" }, props: { id: "$./id", name: "$./name", type: "$./type", required: "$./required", className: "$./className", style: "$./style" }, label: { htmlFor: "$./id", text: "$./label", style: { color: "${themes/${../currentTheme}/colors/text}", marginBottom: "${themes/${../currentTheme}/spacing/small}" } } } }, form: { title: "", fields: [], ".": { className: "form", style: { backgroundColor: "${themes/${../currentTheme}/colors/background}", color: "${themes/${../currentTheme}/colors/text}", padding: "${themes/${../currentTheme}/spacing/large}", borderRadius: "8px" }, header: { text: "$./title", style: { fontSize: "24px", marginBottom: "${themes/${../currentTheme}/spacing/medium}", color: "${themes/${../currentTheme}/colors/text}" } } } } } }; const ui = resolveRefs(componentSystem); console.log(ui.components.primaryButton.style.backgroundColor); // "#007bff" console.log(ui.components.loginForm.className); // "form" console.log(ui.components.loginForm.fields[0].label.text); // "Email" ``` ## Feature Flag System Manage feature flags with environment-specific overrides and complex conditions. ```typescript const featureFlagConfig = { // Environment settings environment: { name: "production", region: "us-east-1", version: "2.1.0" }, // User context (would come from authentication) user: { id: 12345, plan: "premium", betaTester: true, region: "us-east-1" }, // Base feature definitions features: { newDashboard: { ref: "$templates/feature", name: "new_dashboard", description: "New user dashboard design", rolloutPercentage: 50, enabledForBeta: true, requiredPlan: "basic" }, advancedAnalytics: { ref: "$templates/feature", name: "advanced_analytics", description: "Advanced analytics features", rolloutPercentage: 25, enabledForBeta: false, requiredPlan: "premium", enabledRegions: ["us-east-1", "eu-west-1"] }, experimentalAPI: { ref: "$templates/feature", name: "experimental_api", description: "Experimental API endpoints", rolloutPercentage: 0, enabledForBeta: true, requiredPlan: "enterprise", minVersion: "2.1.0" } }, templates: { feature: { name: "", description: "", rolloutPercentage: 0, enabledForBeta: false, requiredPlan: "basic", enabledRegions: [], minVersion: "1.0.0", ".": { // Complex feature flag logic enabled: "$isFeatureEnabled", // Metadata for debugging metadata: { featureName: "$./name", description: "$./description", rolloutPercentage: "$./rolloutPercentage", userEligible: "$userMeetsRequirements", regionAllowed: "$regionCheck", versionCompatible: "$versionCheck", betaAccess: "$betaCheck" }, // Configuration based on enablement config: { apiEndpoint: "/api/v1/features/${./name}", telemetryEnabled: "$./enabled", fallbackBehavior: "$./enabled ? 'new' : 'legacy'" } } } }, // Custom rules for complex feature flag logic rules: { "$isFeatureEnabled": ["and", "$userMeetsRequirements", "$regionCheck", "$versionCheck", "$rolloutCheck"], "$userMeetsRequirements": ["planCheck", "$./requiredPlan"], "$regionCheck": ["regionCheck", "$./enabledRegions"], "$versionCheck": ["versionCheck", "$./minVersion"], "$rolloutCheck": ["rollout", "$./rolloutPercentage"], "$betaCheck": ["betaAccess", "$./enabledForBeta"] } }; // Custom tasks for feature flag evaluation const featureTasks = { and: (...conditions: boolean[]) => conditions.every(Boolean), planCheck: (requiredPlan: string) => { const planHierarchy = { basic: 1, premium: 2, enterprise: 3 }; const userPlanLevel = planHierarchy[featureFlagConfig.user.plan as keyof typeof planHierarchy] || 0; const requiredLevel = planHierarchy[requiredPlan as keyof typeof planHierarchy] || 0; return userPlanLevel >= requiredLevel; }, regionCheck: (enabledRegions: string[]) => { if (enabledRegions.length === 0) return true; // No restrictions return enabledRegions.includes(featureFlagConfig.user.region); }, versionCheck: (minVersion: string) => { const parseVersion = (v: string) => v.split('.').map(Number); const current = parseVersion(featureFlagConfig.environment.version); const required = parseVersion(minVersion); for (let i = 0; i < Math.max(current.length, required.length); i++) { const c = current[i] || 0; const r = required[i] || 0; if (c > r) return true; if (c < r) return false; } return true; }, rollout: (percentage: number) => { const hash = featureFlagConfig.user.id % 100; return hash < percentage; }, betaAccess: (enabledForBeta: boolean) => { return !enabledForBeta || featureFlagConfig.user.betaTester; } }; const flags = resolveRefs(featureFlagConfig, undefined, featureFlagConfig.rules, featureTasks); console.log(flags.features.newDashboard.enabled); // true/false based on conditions console.log(flags.features.advancedAnalytics.metadata); // Debugging metadata console.log(flags.features.experimentalAPI.config.fallbackBehavior); // "new" or "legacy" ``` ## E-commerce Product Catalog Create a flexible product catalog with variants, pricing tiers, and localization. ```typescript const productCatalog = { // Pricing and locale settings settings: { currency: "USD", locale: "en-US", taxRate: 0.08, currentSeason: "winter", membershipTier: "gold" // bronze, silver, gold, platinum }, // Discount rules discounts: { seasonal: { winter: 0.15, spring: 0.1, summer: 0.05, fall: 0.1 }, membership: { bronze: 0, silver: 0.05, gold: 0.1, platinum: 0.15 }, bulk: { 5: 0.05, 10: 0.1, 20: 0.15 } }, // Base product templates products: { laptop_macbook: { ref: "$templates/product", category: "electronics", name: "MacBook Pro", basePrice: 1999, variants: [ { ref: "$templates/variant", name: "13-inch", price: 0, sku: "MBP13" }, { ref: "$templates/variant", name: "16-inch", price: 500, sku: "MBP16" } ], specs: { processor: "M2", memory: "16GB", storage: "512GB" }, seasonal: true }, shirt_basic: { ref: "$templates/product", category: "clothing", name: "Basic T-Shirt", basePrice: 25, variants: [ { ref: "$templates/variant", name: "Small", price: 0, sku: "SHIRT-S" }, { ref: "$templates/variant", name: "Medium", price: 0, sku: "SHIRT-M" }, { ref: "$templates/variant", name: "Large", price: 2, sku: "SHIRT-L" }, { ref: "$templates/variant", name: "XL", price: 4, sku: "SHIRT-XL" } ], colors: ["red", "blue", "white", "black"], seasonal: false } }, templates: { product: { category: "", name: "", basePrice: 0, variants: [], seasonal: false, ".": { // Price calculations seasonalDiscount: "$./seasonal ? ${discounts/seasonal/${settings/currentSeason}} : 0", membershipDiscount: "${discounts/membership/${settings/membershipTier}}", totalDiscount: "${./seasonalDiscount} + ${./membershipDiscount}", discountedPrice: "${./basePrice} * (1 - ${./totalDiscount})", // Formatted display display: { name: "$./name", category: "$./category", originalPrice: "$./basePrice", currentPrice: "$./discountedPrice", savings: "${./basePrice} - ${./discountedPrice}", discountPercent: "${./totalDiscount} * 100", // Localized pricing formatted: { originalPrice: "$formatCurrency", currentPrice: "$formatDiscountedPrice", savings: "$formatSavings" } }, // SEO and metadata seo: { title: "${./name} - ${./category}", description: "${./name} starting at ${./display/formatted/currentPrice}", url: "/products/${./category}/${./name}", schema: { "@type": "Product", name: "$./name", category: "$./category", offers: { "@type": "Offer", price: "$./discountedPrice", priceCurrency: "${settings/currency}" } } } } }, variant: { name: "", price: 0, sku: "", ".": { totalPrice: "${../basePrice} + ${./price}", discountedTotal: "${../discountedPrice} + ${./price}", display: { name: "${../name} - ${./name}", sku: "$./sku", price: "$./discountedTotal", formattedPrice: "$formatVariantPrice" } } } }, // Custom formatting rules rules: { "$formatCurrency": ["formatMoney", "$./basePrice"], "$formatDiscountedPrice": ["formatMoney", "$./discountedPrice"], "$formatSavings": ["formatMoney", "$./savings"], "$formatVariantPrice": ["formatMoney", "$./discountedTotal"] } }; // Custom formatting tasks const catalogTasks = { formatMoney: (amount: number) => { const { currency, locale } = productCatalog.settings; return new Intl.NumberFormat(locale, { style: 'currency', currency: currency }).format(amount); } }; const catalog = resolveRefs(productCatalog, undefined, productCatalog.rules, catalogTasks); console.log(catalog.products.laptop_macbook.display.formatted.currentPrice); // "$1,499.25" console.log(catalog.products.laptop_macbook.seo.title); // "MacBook Pro - electronics" console.log(catalog.products.laptop_macbook.variants[0].display.formattedPrice); // "$1,499.25" console.log(catalog.products.shirt_basic.display.discountPercent); // "10" ``` ## Conclusion These examples demonstrate the versatility and power of the `resolve-refs` utility: - **Configuration Management**: Handle complex multi-environment setups - **Template Systems**: Create reusable, extensible object templates - **Dynamic Content**: Generate content based on context and conditions - **Feature Flags**: Implement sophisticated feature flag logic - **E-commerce**: Build flexible product catalogs with dynamic pricing - **API Documentation**: Auto-generate consistent API documentation - **UI Components**: Create theme-aware component systems The key benefits include: 1. **DRY Principle**: Eliminate duplication through template inheritance 2. **Maintainability**: Centralize configuration and templates 3. **Flexibility**: Support for complex conditional logic 4. **Type Safety**: Full TypeScript support with custom interfaces 5. **Performance**: Efficient resolution with caching and cycle detection 6. **Extensibility**: Custom rules and tasks for domain-specific logic Use these patterns as starting points for your own implementations, adapting them to your specific use cases and requirements.