@oxog/utils
v1.0.1
Published
Zero-dependency, type-safe utility functions for Node.js backends
Maintainers
Readme
@oxog/utils
Zero-dependency, type-safe utility functions for Node.js backends.
Modern, tree-shakeable utility library for Node.js backend development with zero dependencies. Full TypeScript support with automatic type inference.
✨ Features
- 📦 Zero dependencies - No runtime dependencies
- 🔒 Type-safe - Written in TypeScript with full type inference
- 🌳 Tree-shakeable - Import only what you need
- 🛡️ Secure - Prototype pollution protection built-in
- ⚡ Performant - Immutable by default, optimized for Node.js backends
- 🧪 Well-tested - 247 tests with 100% success rate
- 📝 LLM-native - Designed for AI/LLM code generation
📦 Installation
npm install @oxog/utils🚀 Quick Start
import { get, set, groupBy, camelCase } from '@oxog/utils';
// Object utilities
const user = { name: 'Ersin', address: { city: 'Istanbul' } };
const city = get(user, 'address.city'); // 'Istanbul'
const updated = set(user, 'name', 'Ali'); // new object, immutable
// Array utilities
const users = [
{ id: 1, name: 'Alice', role: 'admin' },
{ id: 2, name: 'Bob', role: 'user' }
];
const grouped = groupBy(users, 'role');
// { admin: [{ id: 1, ... }], user: [{ id: 2, ... }] }
// String utilities
const slug = camelCase('hello-world'); // 'helloWorld'📖 Import Patterns
Main Package
// Direct imports (recommended for tree-shaking)
import { get, set, merge, pick, omit } from '@oxog/utils';
// Namespace imports
import * as utils from '@oxog/utils';
utils.get(obj, 'path');Optional Plugins
// Deep operations (clone, merge, diff, equality)
import { cloneDeep, isEqual, mergeDeep } from '@oxog/utils/deep';
// Async utilities (debounce, throttle, retry, timeout)
import { debounce, throttle, retry, sleep } from '@oxog/utils/async';
// Type guards (isEmpty, isNil, isPlainObject, etc.)
import { isEmpty, isNil, isPlainObject } from '@oxog/utils/guard';
// Function utilities (compose, pipe, mapKeys, etc.)
import { compose, pipe, flip } from '@oxog/utils/transform';📚 API Reference
Object Utilities
| Function | Description |
|----------|-------------|
| get(obj, path, defaultValue?) | Safe nested property access with type inference |
| set(obj, path, value) | Immutable property setter |
| setMut(obj, path, value) | Mutable property setter |
| has(obj, path) | Check if path exists in object |
| pick(obj, keys) | Create object with specified keys |
| omit(obj, keys) | Create object excluding specified keys |
| merge(target, ...sources) | Safe shallow merge with prototype pollution protection |
| keys(obj) | Type-safe Object.keys() |
| values(obj) | Type-safe Object.values() |
| entries(obj) | Type-safe Object.entries() |
| fromEntries(entries) | Type-safe Object.fromEntries() |
Array Utilities
| Function | Description |
|----------|-------------|
| groupBy(arr, key) | Group array items by property or function |
| keyBy(arr, key) | Index array by property value |
| chunk(arr, size) | Split array into chunks |
| uniq(arr) | Remove duplicate values |
| uniqBy(arr, key) | Remove duplicates by key |
| flatten(arr, depth?) | Flatten nested arrays |
| compact(arr) | Remove falsy values |
| first(arr, n?) | Get first n elements |
| last(arr, n?) | Get last n elements |
| sample(arr, n?) | Get random sample(s) |
String Utilities
| Function | Description |
|----------|-------------|
| camelCase(str) | Convert to camelCase |
| kebabCase(str) | Convert to kebab-case |
| snakeCase(str) | Convert to snake_case |
| pascalCase(str) | Convert to PascalCase |
| capitalize(str) | Capitalize first letter |
| truncate(str, length, suffix?) | Truncate string to length |
| slugify(str) | URL-safe slug with Turkish/Unicode support |
| template(str, data) | String interpolation with {{variable}} |
Deep Utilities (@oxog/utils/deep)
| Function | Description |
|----------|-------------|
| cloneDeep(obj) | Deep clone with circular reference support |
| mergeDeep(target, ...sources) | Deep merge with prototype pollution protection |
| isEqual(a, b) | Deep equality comparison |
| diff(a, b) | Get differences between two objects |
Async Utilities (@oxog/utils/async)
| Function | Description |
|----------|-------------|
| debounce(fn, wait, options?) | Debounce function execution |
| throttle(fn, wait, options?) | Throttle function execution |
| sleep(ms) | Sleep for specified milliseconds |
| retry(options) | Retry function with backoff |
| timeout(promise, ms) | Add timeout to promise |
Type Guards (@oxog/utils/guard)
| Function | Description |
|----------|-------------|
| isEmpty(value) | Check if collection is empty |
| isNil(value) | Check if null or undefined |
| isPlainObject(value) | Check if plain object |
| isArray(value) | Type guard for arrays |
| isString(value) | Type guard for strings |
| isNumber(value) | Type guard for numbers (excludes NaN) |
| isFunction(value) | Type guard for functions |
| isDate(value) | Type guard for valid dates |
Transform Utilities (@oxog/utils/transform)
| Function | Description |
|----------|-------------|
| mapKeys(obj, fn) | Transform object keys |
| mapValues(obj, fn) | Transform object values |
| invert(obj) | Swap keys and values |
| flip(fn) | Flip function argument order |
| compose(...fns) | Compose functions right-to-left |
| pipe(...fns) | Compose functions left-to-right |
Kernel (Plugin System)
| Function/Class | Description |
|----------------|-------------|
| Kernel<TContext> | Micro-kernel for plugin management |
| kernel.register(plugin) | Register a plugin |
| kernel.init() | Initialize all plugins (async) |
| kernel.unregister(name) | Unregister a plugin (async) |
| kernel.destroy() | Destroy kernel and all plugins (async) |
| kernel.getPluginState(name) | Get plugin lifecycle state |
| kernel.getScopedEventBus(name) | Get scoped event bus for plugin |
| ScopedEventBus | Auto-cleanup event bus for plugins |
import { Kernel, type Plugin } from '@oxog/utils';
interface AppContext {
db: Database;
}
const kernel = new Kernel<AppContext>({
context: { db: myDatabase }
});
const loggerPlugin: Plugin<AppContext> = {
name: 'logger',
version: '1.0.0',
install: (kernel) => {
// Setup during registration
},
onInit: async (ctx) => {
// Async initialization
},
onDestroy: async () => {
// Cleanup on unregister
}
};
kernel.register(loggerPlugin);
await kernel.init();
// Plugin states: 'registered' | 'initializing' | 'active' | 'error' | 'destroyed'
console.log(kernel.getPluginState('logger')); // 'active'💡 Usage Examples
Type-Safe Property Access
import { get, set } from '@oxog/utils';
interface User {
profile?: {
name: string;
settings?: {
theme: 'light' | 'dark';
};
};
}
const user: User = { profile: { name: 'Ersin' } };
// TypeScript infers return type automatically
const theme: 'light' | 'dark' | undefined = get(user, 'profile.settings.theme');
const updated = set(user, 'profile.settings.theme', 'dark' as const);Safe Deep Merging
import { mergeDeep } from '@oxog/utils/deep';
const config = mergeDeep(
{ database: { host: 'localhost', port: 5432 } },
{ database: { credentials: { user: 'admin' } } }
);Retry with Exponential Backoff
import { retry } from '@oxog/utils/async';
const data = await retry({
fn: () => fetch('https://api.example.com'),
attempts: 3,
delay: 1000,
backoff: 'exponential'
});Function Composition
import { pipe } from '@oxog/utils/transform';
const processUser = pipe(
(data: any) => validateUser(data),
(user: User) => transformUser(user),
(user: ProcessedUser) => saveUser(user)
);🧪 Testing
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run coverage report
npm run test:coverage- 247 tests with 100% success rate
- 98.36% statement coverage
- 100% function coverage
- 94.74% branch coverage
🔧 Scripts
npm run build # Build the project
npm test # Run tests
npm run test:watch # Watch mode
npm run test:coverage # Coverage report
npm run lint # Lint source code
npm run format # Format code with Prettier
npm run typecheck # TypeScript type checking🏗️ Build Output
dist/
├── index.js # ESM entry
├── index.cjs # CommonJS entry
├── index.d.ts # TypeScript definitions
├── index.d.cts # CommonJS definitions
├── plugins/
│ ├── deep.js # Deep operations
│ ├── async.js # Async utilities
│ ├── guard.js # Type guards
│ └── transform.js # Transform utilities🛡️ Security
This library includes built-in protection against prototype pollution attacks:
import { merge } from '@oxog/utils';
// Dangerous keys are filtered automatically
const result = merge({}, { __proto__: { evil: true } });
console.log(result.evil); // undefined📄 License
MIT © Ersin Koç
🔗 Links
- Documentation: https://utils.oxog.dev
- GitHub: https://github.com/ersinkoc/utils
- Issues: https://github.com/ersinkoc/utils/issues
Made with ❤️ by Ersin Koç
