🔧 Common Utilities
The Nodeblocks SDK provides general-purpose utility functions for common operations. These utilities handle basic tasks like UUID generation and type checking that are frequently used across applications.
🎯 Overview
Common utilities provide essential helper functions for everyday programming tasks. They focus on simplicity and reliability for common operations.
Key Features
- UUID Generation: Reliable UUID v4 generation via the
uuidpackage - Type Checking: Object, error, and
neverthrowResult validation - Lightweight: Minimal dependencies (
uuid,ramda,neverthrow)
The module exports four functions: generateUUID, isObject, isError, and isResult.
🆔 UUID Generation
generateUUID
Generates a UUID v4 string for unique identifiers.
import { utils } from '@nodeblocks/backend-sdk';
const { generateUUID } = utils;
const id = generateUUID();
// Returns: "550e8400-e29b-41d4-a716-446655440000"
Usage Examples
import { utils } from '@nodeblocks/backend-sdk';
const { generateUUID } = utils;
// Generate unique IDs
const userId = generateUUID();
const sessionId = generateUUID();
const requestId = generateUUID();
// Use in objects
const user = {
id: generateUUID(),
name: 'John Doe',
email: 'john@example.com'
};
// Generate multiple IDs
const ids = Array.from({ length: 5 }, () => generateUUID());
Integration with Entity Utilities
import { utils } from '@nodeblocks/backend-sdk';
const { generateUUID, createBaseEntity } = utils;
// Custom entity creation with additional UUID fields
const createOrder = (orderData: OrderData) => {
const baseEntity = createBaseEntity(orderData);
return {
...baseEntity,
orderNumber: generateUUID(), // Additional UUID field
trackingId: generateUUID() // Another UUID field
};
};
Note: createBaseEntity auto-generates an entity id internally (also UUID v4). Use generateUUID when you need additional unique fields beyond the base entity.
🔍 Type Checking
isObject
Checks if a value is an object type (including functions).
import { utils } from '@nodeblocks/backend-sdk';
const { isObject, isError } = utils;
// Object checks
isObject({}); // true
isObject([]); // true
isObject(() => {}); // true
isObject(null); // false
isObject(undefined); // false
isObject('string'); // false
isObject(123); // false
isObject(true); // false
Note: isObject returns a plain boolean, not a TypeScript type predicate. For compile-time narrowing, build a custom type guard (see Advanced Usage).
isError
Checks if a value is an Error instance.
import { utils } from '@nodeblocks/backend-sdk';
const { isError } = utils;
// Error checks
isError(new Error('message')); // true
isError(new TypeError('type')); // true
isError(new ReferenceError()); // true
isError('error string'); // false
isError({}); // false
isError(null); // false
isError(undefined); // false
isResult
Checks if a value is a neverthrow Ok or Err instance. This is a TypeScript type guard.
import { utils } from '@nodeblocks/backend-sdk';
import { ok, err } from 'neverthrow';
const { isResult } = utils;
isResult(ok(42)); // true
isResult(err('failed')); // true
isResult({ ok: true }); // false
isResult(null); // false
Parameters:
value: Value to check
Returns:
boolean:trueif the value is anOk<T, E>orErr<T, E>instance
Usage: Used internally when logging or sanitizing handler results. Useful when branching on whether a value is a Result before calling .isOk() / .isErr().
import { utils } from '@nodeblocks/backend-sdk';
const { isResult } = utils;
const handleValue = (value: unknown) => {
if (isResult(value)) {
return value.isOk() ? value.value : value.error;
}
return value;
};
Usage Examples
import { utils } from '@nodeblocks/backend-sdk';
const { isObject, isError } = utils;
// Validate function parameters
const processData = (data: unknown) => {
if (!isObject(data)) {
throw new Error('Data must be an object');
}
return Object.keys(data as Record<string, unknown>);
};
// Safe object operations
const safeMerge = (target: unknown, source: unknown) => {
if (!isObject(target) || !isObject(source)) {
return target;
}
return { ...target, ...source };
};
// Conditional processing
const processValue = (value: unknown) => {
if (isObject(value)) {
// Handle object
return JSON.stringify(value);
} else {
// Handle primitive
return String(value);
}
};
Error Handling Examples
import { utils } from '@nodeblocks/backend-sdk';
const { isError } = utils;
// Error handling with isError
const safeAsyncOperation = async () => {
try {
return await riskyOperation();
} catch (error) {
if (isError(error)) {
// Handle Error instance
return { error: error.message };
} else {
// Handle other types of thrown values
return { error: 'Unknown error occurred' };
}
}
};
// Type guard for error handling
const handleResult = (result: unknown) => {
if (isError(result)) {
console.error('Operation failed:', result.message);
return false;
}
return result;
};
🔧 Advanced Usage
The examples below are illustrative patterns built on SDK utilities — they are not additional SDK exports.
Custom Type Guards
import { utils } from '@nodeblocks/backend-sdk';
const { isObject, isError } = utils;
// Build custom type guards
const isUserObject = (value: unknown): value is User => {
return isObject(value) &&
'id' in value &&
'name' in value &&
'email' in value;
};
const isProductObject = (value: unknown): value is Product => {
return isObject(value) &&
'id' in value &&
'name' in value &&
'price' in value;
};
// Usage
const validateUser = (data: unknown) => {
if (!isUserObject(data)) {
throw new Error('Invalid user data');
}
// TypeScript knows data is User type
return data.name;
};
// Error type guards
const isApiError = (error: unknown): error is ApiError => {
return isError(error) &&
'statusCode' in error &&
'message' in error;
};
const isValidationError = (error: unknown): error is ValidationError => {
return isError(error) &&
'field' in error &&
'value' in error;
};
// Usage with error type guards
const handleApiResponse = (result: unknown) => {
if (isApiError(result)) {
// TypeScript knows result is ApiError
console.error(`API Error ${result.statusCode}: ${result.message}`);
} else if (isValidationError(result)) {
// TypeScript knows result is ValidationError
console.error(`Validation Error in ${result.field}: ${result.value}`);
} else {
console.log('Success:', result);
}
};
UUID Utilities (example patterns)
import { utils } from '@nodeblocks/backend-sdk';
const { generateUUID } = utils;
// UUID validation
const isValidUUID = (uuid: string): boolean => {
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
return uuidRegex.test(uuid);
};
// Generate UUID with prefix
const generatePrefixedUUID = (prefix: string): string => {
return `${prefix}-${generateUUID()}`;
};
// Generate short UUID (first 8 characters)
const generateShortUUID = (): string => {
return generateUUID().split('-')[0];
};
// Usage
const orderId = generatePrefixedUUID('order'); // "order-550e8400-e29b-41d4-a716-446655440000"
const shortId = generateShortUUID(); // "550e8400"
Object Utilities (example patterns)
import { utils } from '@nodeblocks/backend-sdk';
const { isObject, isError } = utils;
// Deep object validation
const isDeepObject = (value: unknown): boolean => {
if (!isObject(value)) return false;
// Check if all values are also objects or primitives
return Object.values(value).every(val =>
isObject(val) || typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean'
);
};
// Safe object access
const safeGet = (obj: unknown, path: string): unknown => {
if (!isObject(obj)) return undefined;
return path.split('.').reduce((current, key) => {
return isObject(current) ? current[key] : undefined;
}, obj);
};
// Usage
const data = { user: { profile: { name: 'John' } } };
const userName = safeGet(data, 'user.profile.name'); // "John"
const invalid = safeGet(data, 'user.profile.age'); // undefined
Error Handling Utilities (example patterns)
import { utils } from '@nodeblocks/backend-sdk';
const { isError } = utils;
// Error handling utilities
const createErrorResult = (error: unknown): ErrorResult => {
if (isError(error)) {
return {
success: false,
error: error.message,
type: error.name
};
}
return {
success: false,
error: String(error),
type: 'UnknownError'
};
};
const logError = (error: unknown): void => {
if (isError(error)) {
console.error(`[${error.name}] ${error.message}`);
if (error.stack) {
console.error(error.stack);
}
} else {
console.error('Unknown error:', error);
}
};
📊 Performance Considerations
UUID Generation
- Uses the standard
uuidv4 implementation - Extremely low collision probability for typical application workloads
Type Checking
isObject: lightweighttypeofcheckisError: Ramdais(Error)(instanceofcheck)isResult:instanceof Ok/instanceof Errcheck- Handles edge cases like
null,undefined, arrays, functions, and Error subclasses
📐️ Best Practices
1. Consistent UUID Usage
// ✅ Good: Use generateUUID for all unique identifiers
const userId = generateUUID();
const orderId = generateUUID();
const sessionId = generateUUID();
// ❌ Avoid: Mixing different ID generation methods
const userId = generateUUID();
const orderId = Date.now().toString(); // Inconsistent
2. Runtime validation with isObject
// ✅ Good: Use isObject for runtime checks, then narrow manually if needed
const processData = (data: unknown) => {
if (!isObject(data)) {
throw new Error('Expected object');
}
return Object.keys(data as Record<string, unknown>);
};
// ✅ Better: Use a custom type guard when you need compile-time narrowing
const isRecord = (value: unknown): value is Record<string, unknown> =>
isObject(value) && !Array.isArray(value);
// ❌ Avoid: Direct type assertions without validation
const processData = (data: unknown) => {
const obj = data as object; // Unsafe
return Object.keys(obj);
};
3. Error Handling
// ✅ Good: Proper error handling with type checking
const safeProcess = (data: unknown) => {
try {
if (!isObject(data)) {
return { error: 'Invalid data type' };
}
return { success: true, data };
} catch (error) {
if (isError(error)) {
// Handle Error instances specifically
return { error: error.message, type: error.name };
} else {
// Handle other thrown values
return { error: String(error), type: 'UnknownError' };
}
}
};
// ✅ Good: Type-safe error handling
const handleAsyncOperation = async (): Promise<Result> => {
try {
const result = await riskyAsyncOperation();
return { success: true, data: result };
} catch (error) {
if (isError(error)) {
return { success: false, error: error.message };
}
return { success: false, error: 'Unknown error' };
}
};
🔗 See Also
- Entity Utilities - Using UUIDs in entity creation
- Authentication Utilities - Token generation and validation
- Error Handling - Error handling patterns