dbl-utils
v1.0.21
Published
Utilities for dbl, adba and others projects
Maintainers
Readme
dbl-utils
dbl-utils is a JavaScript/TypeScript utility library designed to simplify common application development tasks. This collection includes functions for event handling, queue processing, text manipulation, and date and currency formatting, among others.
Table of Contents
Installation
You can install dbl-utils via npm:
npm install dbl-utilsOr using yarn:
yarn add dbl-utilsUsage
Import the modules and functions in your project as needed. Below is a basic example of how to use dbl-utils:
// Import individual functions
import { formatCurrency, flatten, t } from 'dbl-utils';
// Use functions
console.log(formatCurrency(1234.56)); // Example of currency formatting
console.log(flatten({ a: { b: { c: 1 } } })); // Converts a nested object into a flat objectMinimal example of the CLI logic for CSS purging:
import purgeCss from 'dbl-utils/src/purge-css';
purgeCss('styles.css', 'index.html', 'clean.css');Imports directly from any file to don't include all:
CommonJS use /dist/cjs/*
// Import individual functions
const i18n = require('dbl-utils/dist/cjs/i18n');
// Use functions
console.log(i18n.formatCurrency(1234.56));ESM use /dist/esm/*
// Import individual functions
import t, { formatCurrency } from 'dbl-utils/dist/esm/i18n';
// Use functions
console.log(i18n.formatCurrency(1234.56));TypeScript use /src/*
// Import individual functions
import t, { formatCurrency } from 'dbl-utils/src/i18n';
// Use functions
console.log(i18n.formatCurrency(1234.56));For a complete reference of all available functions, visit the full documentation here.
Main Modules
Below are the main modules available in dbl-utils:
Utilities
event-handler
Decouple communication by subscribing to and dispatching custom events.
import { EventHandler } from 'dbl-utils';
const handler = new EventHandler();
handler.subscribe('ping', msg => console.log(msg), 'id'); // listen to events
await handler.dispatch('ping', 'pong'); // emit an event
handler.unsubscribe('ping', 'id'); // stop listeningfetch-queue
Deduplicate concurrent HTTP calls so the same request is only made once.
import FetchQueue from 'dbl-utils/src/fetch-queue';
const queue = new FetchQueue(fetch);
const [a, b] = await Promise.all([
queue.addRequest('https://example.com'),
queue.addRequest('https://example.com')
]);
// a === bflat
Convert nested objects to and from dot notation.
import { flatten, unflatten } from 'dbl-utils';
flatten({ a: { b: 1 } }); // { 'a.b': 1 }
unflatten({ 'a.b': 1 }); // { a: { b: 1 } }format-value
Format numbers, dates, or dictionary entries using locale-aware helpers.
import formatValue from 'dbl-utils/src/format-value';
formatValue(1000, { format: 'currency', currency: 'USD' }); // "$1,000.00"i18n
Manage dictionaries and locale-aware formatting.
import t, { addDictionary, setLang, formatDate } from 'dbl-utils';
addDictionary({ es: { hello: 'Hola' } });
setLang('es');
t('hello'); // 'Hola'
formatDate(); // date formatted in Spanishobject-mutation
Combine and transform objects without modifying the originals.
import { deepMerge, mergeWithMutation, transformJson } from 'dbl-utils';
deepMerge({}, { a: 1 }, { b: 2 }); // merge nested structures
await mergeWithMutation({ a: { b: 1 } }, { mutation: () => ({ c: 2 }) }); // async mutation
transformJson({ a: { b: 1 } }, { filter: 'a' }); // extract subsetresolve-refs
Advanced reference resolution system for dynamic object composition and template inheritance. Perfect for configuration management, content templating, and complex data transformations.
Core Features
- 🌐 Global References: Access any value in your data schema
- 🔗 Relative References: Reference values within the current object context
- 📝 String Interpolation: Embed references within strings seamlessly
- 🎨 Template Inheritance: Create reusable object templates with property overrides
- ⚙️ Custom Rules & Tasks: Define advanced transformation logic
- 🔄 Recursive Resolution: Handle complex nested reference chains
Reference Types
1. Global References
const config = { api: { url: "https://api.com", key: "secret" } };
const settings = {
endpoint: "$api/url", // Direct reference → "https://api.com"
auth: "Bearer ${api/key}", // String interpolation → "Bearer secret"
full: "${api/url}/v1/users" // Mixed interpolation → "https://api.com/v1/users"
};2. Template Inheritance
const data = {
// Base template
userTemplate: { name: "Guest", role: "viewer", active: false },
// Inherit and override properties
admin: { ref: "$userTemplate", name: "Admin", role: "admin", active: true },
john: { ref: "$userTemplate", name: "John Doe" }
};
const result = resolveRefs(data);
// result.admin = { name: "Admin", role: "admin", active: true }
// result.john = { name: "John Doe", role: "viewer", active: false }3. Relative References with Template System
const data = {
user1: { ref: "$templates/user", firstName: "Alice", lastName: "Smith" },
user2: { ref: "$templates/user", firstName: "Bob", lastName: "Jones" },
templates: {
user: {
firstName: "",
lastName: "",
".": {
// These resolve AFTER template merging
fullName: "${./firstName} ${./lastName}", // Relative interpolation
email: "${./firstName}.${./lastName}@company.com", // Complex relative refs
profile: {
displayName: "$./fullName", // Reference to another relative ref
initials: "${./firstName/0}${./lastName/0}" // Access array/string indices
}
}
}
}
};
const result = resolveRefs(data);
// result.user1.fullName = "Alice Smith"
// result.user1.email = "[email protected]"
// result.user1.profile.displayName = "Alice Smith"
// result.user1.profile.initials = "AS"Advanced Usage
Configuration Management
const config = {
// Environment settings
env: {
name: "production",
domain: "myapp.com",
apiVersion: "v2"
},
// Service definitions using templates
services: {
auth: { ref: "$templates/service", path: "/auth", timeout: 5000 },
users: { ref: "$templates/service", path: "/users", port: 8080 },
payments: { ref: "$templates/service", path: "/payments", ssl: true }
},
templates: {
service: {
path: "/",
port: 3000,
timeout: 30000,
ssl: false,
".": {
// Dynamic URL generation
baseUrl: "http${./ssl ? 's' : ''}://${env/domain}:${./port}",
fullUrl: "${./baseUrl}/${env/apiVersion}${./path}",
// Service configuration
config: {
endpoint: "$./fullUrl",
timeout: "$./timeout",
retries: 3,
headers: {
"X-Service-Name": "${env/name}",
"X-API-Version": "${env/apiVersion}"
}
}
}
}
}
};
const result = resolveRefs(config);
// result.services.auth.fullUrl = "http://myapp.com:3000/v2/auth"
// result.services.users.fullUrl = "http://myapp.com:8080/v2/users"
// result.services.payments.fullUrl = "https://myapp.com:3000/v2/payments"Custom Rules and Tasks
const data = {
users: ["Alice", "Bob", "Charlie"],
products: [{ name: "Widget", price: 10 }, { name: "Gadget", price: 25 }]
};
const template = {
welcomeMessage: "$greetUsers",
productSummary: "$summarizeProducts",
totalValue: "$calculateTotal"
};
// Define custom processing rules
const rules = {
"$greetUsers": ["join", "$users", " and "],
"$summarizeProducts": ["iterate", "$products", "product"],
"$calculateTotal": ["sum", "$products", "price"]
};
// Custom task implementations
const extraTasks = {
sum: (array: any[], property: string) =>
array.reduce((total, item) => total + item[property], 0),
format: (template: string, ...values: any[]) =>
template.replace(/{(\d+)}/g, (_, i) => values[i]),
conditional: (condition: boolean, trueVal: any, falseVal: any) =>
condition ? trueVal : falseVal
};
const result = resolveRefs(template, data, rules, extraTasks);
// result.welcomeMessage = "Alice and Bob and Charlie"
// result.totalValue = 35Built-in Tasks
iterate(array, itemName)- Process array items with current schema contextjoin(values, separator, ...extras)- Join arrays or concatenate valuesignore(path, fallback)- Safe property access with fallback valuesif(condition, trueValue, falseValue)- Conditional value resolution
API Reference
resolveRefs<T>(
object: ResolvableValue, // Object/array with references to resolve
schema?: Record<string, any>, // Base schema for global references
rules?: ResolveRefsRules, // Custom rule definitions
extraTasks?: ResolveRefsTasks // Additional task implementations
): TBest Practices
- 🏗️ Structure: Organize templates in dedicated sections (e.g.,
templates/,definitions/) - 📋 Naming: Use descriptive paths like
config/database/urlover abbreviated versions - 🎯 Performance: Avoid deep circular references and excessive nesting
- 🔒 Type Safety: Define TypeScript interfaces for your schema structure
- 🧪 Testing: Test complex reference chains with various data combinations
Real-World Examples
For comprehensive examples and advanced use cases, see the detailed examples documentation.
- Multi-environment Configuration: Different API endpoints per environment
- Component Templates: Reusable UI component configurations
- Dynamic Content: Blog posts with shared metadata and custom overrides
- API Documentation: Auto-generated endpoint documentation from templates
- Feature Flags: Conditional configuration based on environment/user settings
utils
sliceIntoChunks
Split an array into smaller arrays for batching.
import { sliceIntoChunks } from 'dbl-utils';
sliceIntoChunks([1,2,3,4],2); // [[1,2],[3,4]]splitAndFlat
Turn a list of strings into unique tokens.
import { splitAndFlat } from 'dbl-utils';
splitAndFlat(['a b','c']); // ['a','b','c']generateRandomColors
Generate distinct colors for visualizations.
import { generateRandomColors } from 'dbl-utils';
generateRandomColors(2); // ['#aabbcc', '#ddeeff']evaluateColorSimilarity
Check how close colors are to each other.
import { evaluateColorSimilarity } from 'dbl-utils';
evaluateColorSimilarity(['#fff','#ffe']); // value near 1normalize
Remove accents and lowercase text.
import { normalize } from 'dbl-utils';
normalize('á'); // 'a'slugify
Create URL-friendly slugs.
import { slugify } from 'dbl-utils';
slugify('Hello World'); // 'hello-world'randomS4
Produce a short hex segment.
import { randomS4 } from 'dbl-utils';
randomS4(); // '9f3b'randomString
Generate a random alphanumeric string.
import { randomString } from 'dbl-utils';
randomString(5); // e.g., 'abcde'timeChunks
Build time intervals between two dates.
import { timeChunks } from 'dbl-utils';
timeChunks({ from:'2020-01-01', to:'2020-01-02', step:3600 }); // [...]delay
Pause execution for a given time.
import { delay } from 'dbl-utils';
await delay(10); // waits 10mshash
Generate a numeric hash.
import { hash } from 'dbl-utils';
hash('data'); // 123456789LCG
Deterministic pseudo-random number generator.
import { LCG } from 'dbl-utils';
const gen = new LCG(123);
gen.random(); // 0.5967...Documentation
For a detailed description of each module and function, visit the full documentation automatically generated with Typedoc. The documentation includes usage examples and in-depth explanations of each function.
For an in-depth analysis of the project architecture, codebase structure, and implementation details, check out the comprehensive DeepWiki analysis.
Testing
Run the test suite with:
npm testThis project uses Jest with ts-jest. New tests cover the i18n and object-mutation modules.
Recent Changes
- Comprehensive resolve-refs documentation: Completely redesigned documentation with:
- Enhanced JSDoc comments with detailed examples and use cases
- Full TypeScript type definitions and interfaces
- Comprehensive README section with visual examples
- Real-world usage examples including configuration management, API documentation, and component systems
- Advanced examples covering feature flags, e-commerce catalogs, and multi-environment setups
- Enhanced resolve-refs module: Added support for relative references with
$./and${./}syntax- New template system using the
"."key for relative references - Ability to create reusable templates that can be extended with different values
- Support for references that point to other references (recursive resolution)
- Comprehensive unit tests covering all relative reference scenarios
- New template system using the
- Fixed handling of numeric keys in
unflattenso arrays are reconstructed correctly. - Added unit tests for the
i18nandobject-mutationmodules. - Expanded coverage with additional tests for
utils,format-value, andi18n.
TODO
- Move number compact formatting to the i18n module.
Development & Testing
When developing or debugging tests, use yarn test -- <pattern> to run only the relevant test cases.
License
This project is under the ISC license. See the LICENSE file for more details.
