Package Exports
- @mxweb/utils
- @mxweb/utils/chunk
- @mxweb/utils/flatten
- @mxweb/utils/format-size
- @mxweb/utils/get-env
- @mxweb/utils/http
- @mxweb/utils/interpolate
- @mxweb/utils/package.json
- @mxweb/utils/pascal-to-kebab
- @mxweb/utils/sleep
- @mxweb/utils/storage
- @mxweb/utils/uri
Readme
@mxweb/utils
A comprehensive collection of TypeScript utilities for modern web development, providing robust solutions for HTTP requests, data manipulation, storage management, and more.
Table of Contents
- Installation
- Features
- Usage
- API Reference
- Examples
- Configuration
- TypeScript Support
- Browser Support
- Contributing
- License
- Changelog
- Authors
- Acknowledgments
Installation
Install @mxweb/utils using your preferred package manager:
# Using npm
npm install @mxweb/utils
# Using yarn
yarn add @mxweb/utils
# Using pnpm
pnpm add @mxweb/utils
# Using bun
bun add @mxweb/utilsFeatures
- ๐ HTTP Client - Full-featured HTTP client with interceptors, authentication, and file upload support
- ๐พ Storage Management - Unified API for localStorage, sessionStorage, and cookies
- ๐ง String Utilities - Case conversion, URI encoding/decoding, template interpolation
- ๐ฆ Object Utilities - Deep flattening for nested objects and arrays
- ๐ Data Formatting - Human-readable file size formatting
- ๐ Environment Variables - Cross-framework environment variable access (React, Next.js, Vite, etc.)
- โฑ๏ธ Async Utilities - Promise-based delay and sleep functions
- ๐ Array Utilities - Array chunking and batch processing
- ๐ Type-Safe - Full TypeScript support with comprehensive type definitions
- ๐ Framework Agnostic - Works with any JavaScript framework or vanilla JS
- ๐ฏ Tree-Shakeable - Import only what you need for optimal bundle size
- ๐ฑ Browser & Node.js - Compatible with both environments
Usage
Importing
You can import utilities in multiple ways:
// Import everything
import * as utils from "@mxweb/utils";
// Import specific utilities
import { Http, storage, chunk, formatSize } from "@mxweb/utils";
// Import from specific modules
import { Http } from "@mxweb/utils/http";
import { storage } from "@mxweb/utils/storage";
import { chunk } from "@mxweb/utils/chunk";Quick Start
Here are some quick examples to get you started:
import { Http, storage, chunk, formatSize, sleep, getEnv } from "@mxweb/utils";
// 1. HTTP Client - Make API requests
const http = new Http("https://api.example.com");
// GET request
const { data, success } = await http.get("/users");
// POST request
await http.post("/users", { name: "John Doe", email: "john@example.com" });
// Upload file with progress
await http.upload("/upload", file, {
name: "document",
onProgress: (progress) => console.log(`${progress.percentage}%`),
});
// 2. Storage - Manage localStorage, sessionStorage, cookies
// Save data
storage.local.setItem("user", { id: 1, name: "John" });
// Retrieve data with type safety
const user = storage.local.getItem<{ id: number; name: string }>("user");
// 3. Array Utilities - Split arrays into chunks
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const chunks = chunk(numbers, 3); // [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
// 4. Format Utilities - Human-readable file sizes
const size = formatSize(1536000); // "1.46 MB"
// 5. Async Utilities - Add delays
await sleep(1000); // Wait 1 second
// 6. Environment Variables - Access env vars across frameworks
const apiUrl = getEnv("API_URL", "http://localhost:3000");
// Automatically checks: API_URL, REACT_APP_API_URL, NEXT_PUBLIC_API_URL, VITE_API_URL, etc.API Reference
Array Utilities
chunk
Splits an array into smaller chunks of a specified size.
function chunk<T>(source: T[], size?: number): T[][];Parameters:
source: T[]- The array to split into chunkssize: number- The maximum size of each chunk (default: 5)
Returns: T[][] - A two-dimensional array of chunks
Example:
import { chunk } from "@mxweb/utils";
chunk([1, 2, 3, 4, 5, 6, 7], 3);
// Returns: [[1, 2, 3], [4, 5, 6], [7]]
// Batch processing
const users = Array.from({ length: 100 }, (_, i) => ({ id: i }));
const batches = chunk(users, 10); // Process 10 users at a timeString Utilities
pascalToKebab
Converts a PascalCase or camelCase string to kebab-case.
function pascalToKebab(str: string): string;Parameters:
str: string- The PascalCase or camelCase string to convert
Returns: string - The kebab-case formatted string
Example:
import { pascalToKebab } from "@mxweb/utils";
pascalToKebab("PascalCase"); // "pascal-case"
pascalToKebab("camelCase"); // "camel-case"
pascalToKebab("XMLHttpRequest"); // "xml-http-request"interpolate
Interpolates a template string by replacing placeholders with values.
function interpolate(pattern: string, params?: Record<string, unknown> | Array<unknown>): string;Parameters:
pattern: string- Template string with placeholders in format{key}params: Record<string, unknown> | Array<unknown>- Values to interpolate
Returns: string - The interpolated string
Example:
import { interpolate } from "@mxweb/utils";
interpolate("Hello {name}!", { name: "John" });
// Returns: "Hello John!"
interpolate("User: {user.name}, Age: {user.age}", {
user: { name: "John", age: 30 },
});
// Returns: "User: John, Age: 30"
interpolate("/api/users/{userId}/posts/{postId}", {
userId: 123,
postId: 456,
});
// Returns: "/api/users/123/posts/456"decodeURISafe
Safely decodes a URI-encoded string with error handling.
function decodeURISafe(str: string, component?: boolean): string;Parameters:
str: string- The URI-encoded string to decodecomponent: boolean- UsedecodeURIComponent(true) ordecodeURI(false). Default: true
Returns: string - The decoded string, or original if decoding fails
Example:
import { decodeURISafe } from "@mxweb/utils";
decodeURISafe("Hello%20World"); // "Hello World"
decodeURISafe("Hello%2World"); // "Hello%2World" (invalid encoding preserved)encodeURISafe
Encodes a string to be safely used in a URI.
function encodeURISafe(str: string, component?: boolean): string;Parameters:
str: string- The string to encodecomponent: boolean- UseencodeURIComponent(true) orencodeURI(false). Default: true
Returns: string - The URI-encoded string
Example:
import { encodeURISafe } from "@mxweb/utils";
encodeURISafe("Hello World"); // "Hello%20World"
encodeURISafe("name=value&other=data"); // "name%3Dvalue%26other%3Ddata"Object Utilities
flatten
Flattens a nested object or array into a single-level object with dot-notated keys.
function flatten(data: Record<string, unknown> | Array<unknown>): Record<string, unknown>;Parameters:
data: Record<string, unknown> | Array<unknown>- The object or array to flatten
Returns: Record<string, unknown> - A flattened object with dot-notated keys
Example:
import { flatten } from "@mxweb/utils";
flatten({
user: {
name: "John",
contacts: { email: "john@example.com" },
},
});
// Returns: { "user.name": "John", "user.contacts.email": "john@example.com" }
flatten([1, 2, { value: 3 }]);
// Returns: { "0": 1, "1": 2, "2.value": 3 }flattenArray
Flattens an array into a single-level object with dot-notated keys.
function flattenArray(data: Array<unknown>): Record<string, unknown>;Parameters:
data: Array<unknown>- The array to flatten
Returns: Record<string, unknown> - A flattened object
Example:
import { flattenArray } from "@mxweb/utils";
flattenArray([{ name: "John" }, { name: "Jane" }]);
// Returns: { "0.name": "John", "1.name": "Jane" }flattenObject
Flattens an object into a single-level object with dot-notated keys.
function flattenObject(data: Record<string, unknown>): Record<string, unknown>;Parameters:
data: Record<string, unknown>- The object to flatten
Returns: Record<string, unknown> - A flattened object
Example:
import { flattenObject } from "@mxweb/utils";
flattenObject({ user: { name: "John", age: 30 } });
// Returns: { "user.name": "John", "user.age": 30 }File & Format Utilities
formatSize
Formats a file size in bytes to a human-readable string.
function formatSize(sizeInBytes: number, base?: Array<string>): string;Parameters:
sizeInBytes: number- The size in bytes to formatbase: Array<string>- Custom unit labels (default:["B", "KB", "MB", "GB", "TB"])
Returns: string - Formatted string with size and unit
Example:
import { formatSize } from "@mxweb/utils";
formatSize(1024); // "1 KB"
formatSize(1536); // "1.5 KB"
formatSize(1048576); // "1 MB"
formatSize(2457600); // "2.34 MB"HTTP Client
Http
Full-featured HTTP client with interceptors, authentication, and file upload support.
Constructor
new Http(baseURL?: string)Parameters:
baseURL: string- Base URL for all requests (default: fromAPI_URLenv var or "/")
Example:
import { Http } from "@mxweb/utils";
const http = new Http("https://api.example.com");Instance Methods
get
Makes a GET request.
get<T = unknown, Query = Record<string, unknown>, E = unknown>(
url: string,
query?: Query,
options?: { headers?, params?, signal? }
): Promise<HttpResponse<T, E>>Example:
const { data, success, status } = await http.get<User[]>("/users");
const response = await http.get("/search", { q: "keyword", page: 1 });post
Makes a POST request.
post<T = unknown, Body = unknown, E = unknown>(
url: string,
body?: Body,
options?: { headers?, params?, signal?, query? }
): Promise<HttpResponse<T, E>>Example:
const response = await http.post<User>("/users", {
name: "John Doe",
email: "john@example.com",
});put
Makes a PUT request.
put<T = unknown, Body = unknown, E = unknown>(
url: string,
body?: Body,
options?: { headers?, params?, signal?, query? }
): Promise<HttpResponse<T, E>>Example:
await http.put(
"/users/{id}",
{ name: "John Updated" },
{
params: { id: 123 },
}
);patch
Makes a PATCH request.
patch<T = unknown, Body = unknown, E = unknown>(
url: string,
body?: Body,
options?: { headers?, params?, signal?, query? }
): Promise<HttpResponse<T, E>>Example:
await http.patch(
"/users/{id}",
{ email: "newemail@example.com" },
{
params: { id: 123 },
}
);delete
Makes a DELETE request.
delete<T = unknown, E = unknown>(
url: string,
options?: { headers?, params?, signal?, query? }
): Promise<HttpResponse<T, E>>Example:
await http.delete("/users/{id}", { params: { id: 123 } });head
Makes a HEAD request.
head<T = unknown, E = unknown>(
url: string,
options?: { headers?, params?, signal?, query? }
): Promise<HttpResponse<T, E>>options
Makes an OPTIONS request.
options<T = unknown, E = unknown>(
url: string,
options?: { headers?, params?, signal?, query? }
): Promise<HttpResponse<T, E>>upload
Uploads files with optional progress tracking.
upload<T = unknown, E = unknown>(
url: string,
file: File | File[] | FileList,
options?: HttpUploadOptions
): Promise<HttpResponse<T, E>>Example:
const file = input.files[0];
await http.upload("/upload", file, {
name: "document",
onProgress: (progress) => {
console.log(`${progress.percentage}%`);
},
body: { userId: 123 },
});
// Multiple files
await http.upload("/upload", input.files, {
name: "files[]",
});on / off
Registers or removes interceptors for this instance.
on(type: 'request' | 'response' | 'error', handler: Function): Http
off(type: 'request' | 'response' | 'error', handler: Function): HttpExample:
http.on("request", async (options) => {
console.log("Request:", options.url);
return options;
});
http.on("response", async (response) => {
console.log("Response:", response.status);
return response;
});
http.on("error", async (error) => {
console.error("Error:", error);
});addHeaders
Adds default headers to all requests.
addHeaders(headers: Record<string, string>): voidExample:
http.addHeaders({
"X-Custom-Header": "value",
"X-API-Version": "2.0",
});setStorage
Sets the storage implementation for authentication tokens.
setStorage(storage: HttpStorage): voidExample:
http.setStorage(storage.local);Static Methods
Http.on / Http.off
Registers or removes global interceptors for all Http instances.
static on(type: 'request' | 'response' | 'error', handler: Function): void
static off(type: 'request' | 'response' | 'error', handler: Function): voidExample:
// Global request interceptor
Http.on("request", async (options) => {
options.headers = { ...options.headers, "X-Timestamp": Date.now() };
return options;
});Http.createInfer
Creates a factory function for generating type-safe API endpoint functions.
static createInfer(options?: HttpInferOptions): InferFunctionExample:
const endpoints = {
"user.list": "/api/users",
"user.get": "/api/users/{id}",
"user.create": "/api/users",
};
const infer = Http.createInfer({
baseURL: "https://api.example.com",
endpoint: endpoints,
});
const getUsers = infer<User[]>("user.list", HttpMethod.GET);
const createUser = infer<User, [UserInput]>("user.create", HttpMethod.POST);
// Use the generated functions
const { data: users } = await getUsers.fn();
const { data: newUser } = await createUser.fn({ name: "John" });Types & Interfaces
HttpMethod
Enum of supported HTTP methods.
enum HttpMethod {
GET = "GET",
POST = "POST",
PUT = "PUT",
DELETE = "DELETE",
PATCH = "PATCH",
HEAD = "HEAD",
OPTIONS = "OPTIONS",
}HttpRequest
Configuration options for an HTTP request.
interface HttpRequest<Body, Params, Query, Headers> {
method: HttpMethod;
url: string;
headers?: Headers;
body?: Body;
query?: Query;
params?: Params;
signal?: AbortSignal;
}HttpResponse
Standardized HTTP response structure.
interface HttpResponse<T, E> {
success: boolean;
data: T;
status: number;
statusText: string;
headers: Record<string, string>;
error: E | null;
}HttpStorage
Interface for storage implementations.
interface HttpStorage {
getItem(key: string): string | null;
setItem(key: string, value: string): void;
removeItem(key: string, options?: any): void;
}HttpUploadOptions
Configuration options for file uploads.
interface HttpUploadOptions {
name: string;
onProgress?: (progress: HttpProgress) => void;
body?: Record<string, unknown>;
headers?: Record<string, string>;
params?: Record<string, unknown>;
signal?: AbortSignal;
query?: HttpQuery;
}HttpProgress
Progress information for file uploads.
interface HttpProgress {
loaded: number;
total: number;
percentage: number;
}Storage Utilities
storage
Unified storage utility for localStorage, sessionStorage, and cookies.
storage.local
Access localStorage with automatic JSON serialization.
storage.local.getItem<T>(key: string): T | null
storage.local.setItem(key: string, value: any): void
storage.local.removeItem(key: string): voidExample:
import { storage } from "@mxweb/utils";
// Store data
storage.local.setItem("user", { id: 1, name: "John" });
// Retrieve with type safety
const user = storage.local.getItem<{ id: number; name: string }>("user");
// Remove
storage.local.removeItem("user");storage.session
Access sessionStorage with automatic JSON serialization.
storage.session.getItem<T>(key: string): T | null
storage.session.setItem(key: string, value: any): void
storage.session.removeItem(key: string): voidExample:
storage.session.setItem("tempData", { timestamp: Date.now() });
const data = storage.session.getItem("tempData");storage.cookie
Access cookies with automatic JSON serialization.
storage.cookie.getItem<T>(key: string): T | null
storage.cookie.setItem(key: string, value: any): void
storage.cookie.removeItem(key: string): voidExample:
storage.cookie.setItem("preferences", { theme: "dark", lang: "en" });
const prefs = storage.cookie.getItem("preferences");storage.from
Create a storage instance of a specific type.
storage.from(type: 'localStorage' | 'sessionStorage' | 'cookie'): InnerStorageExample:
const customStorage = storage.from("localStorage");
customStorage.setItem("key", "value");Environment Variables
getEnv
Gets environment variables with automatic framework prefix detection.
function getEnv<T>(key: string, defaultValue?: T): T | undefined;Parameters:
key: string- The environment variable key (case-insensitive)defaultValue: T- Default value if variable not found
Returns: The environment variable value or default value
Supported Prefixes:
API_URLREACT_API_URL/REACT_APP_API_URLNEXT_PUBLIC_API_URLVITE_API_URLPUBLIC_API_URLNUXT_PUBLIC_API_URLGATSBY_API_URLSNOWPACK_PUBLIC_API_URLASTRO_PUBLIC_API_URL
Example:
import { getEnv } from "@mxweb/utils";
const apiUrl = getEnv("API_URL", "http://localhost:3000");
const apiKey = getEnv("API_KEY");
const debug = getEnv("DEBUG", "false") === "true";Async Utilities
sleep
Pauses execution for a specified duration.
function sleep(ms: number): Promise<void>;Parameters:
ms: number- Duration in milliseconds (negative values clamped to 0)
Returns: Promise<void> - Promise that resolves after the delay
Example:
import { sleep } from "@mxweb/utils";
// Wait 1 second
await sleep(1000);
// Retry with delay
async function retryRequest(fn: () => Promise<any>, attempts = 3) {
for (let i = 0; i < attempts; i++) {
try {
return await fn();
} catch (error) {
if (i < attempts - 1) await sleep(1000);
}
}
}Examples
Basic Examples
import {
Http,
storage,
chunk,
formatSize,
sleep,
pascalToKebab,
interpolate,
flatten,
getEnv,
} from "@mxweb/utils";
// HTTP Client
const http = new Http("https://api.example.com");
const { data } = await http.get("/users");
await http.post("/users", { name: "John" });
// Storage
storage.local.setItem("user", { id: 1, name: "John" });
const user = storage.local.getItem("user");
// String utilities
pascalToKebab("MyComponent"); // 'my-component'
interpolate("Hello {{name}}", { name: "John" }); // 'Hello John'
// Array utilities
chunk([1, 2, 3, 4, 5], 2); // [[1, 2], [3, 4], [5]]
flatten([
[1, 2],
[3, [4, 5]],
]); // [1, 2, 3, 4, 5]
// Format utilities
formatSize(1024); // '1 KB'
formatSize(1048576); // '1 MB'
// Async utilities
await sleep(1000); // Wait 1 second
// Environment variables
const apiUrl = getEnv("API_URL", "https://api.example.com");HTTP Client Examples
Type-Safe API with createInfer
import { Http, HttpMethod } from "@mxweb/utils";
const endpoints = {
"user.list": "/users",
"user.get": "/users/{id}",
"user.create": "/users",
} as const;
const infer = Http.createInfer({
baseURL: "https://api.example.com",
endpoint: endpoints,
});
interface User {
id: number;
name: string;
email: string;
}
const api = {
user: {
list: infer<User[]>("user.list", HttpMethod.GET),
get: infer<User, [{ params: { id: number } }]>("user.get", HttpMethod.GET),
create: infer<User, [{ name: string; email: string }]>("user.create", HttpMethod.POST),
},
};
// Usage
const users = await api.user.list.fn();
const user = await api.user.get.fn({ params: { id: 1 } });
const newUser = await api.user.create.fn({ name: "John", email: "john@example.com" });Server-Side Actions (Next.js)
// lib/api/server-client.ts
'use server';
import { Http, HttpMethod } from '@mxweb/utils';
import { getEnv } from '@mxweb/utils';
const serverHttp = new Http(getEnv('INTERNAL_API_URL'));
serverHttp.addHeaders({
'X-API-Key': getEnv('API_SECRET_KEY', ''),
});
const endpoints = {
'user.list': '/users',
'user.get': '/users/{id}',
};
const infer = Http.createInfer({
http: serverHttp,
endpoint: endpoints
});
export const serverApi = {
user: {
list: infer<User[]>('user.list', HttpMethod.GET),
get: infer<User, [{ params: { id: number } }]>('user.get', HttpMethod.GET),
},
};
// app/actions/user.actions.ts
'use server';
import { serverApi } from '@/lib/api/server-client';
export async function getUsersAction() {
const response = await serverApi.user.list.fn();
return response.data;
}
// app/users/page.tsx
'use client';
import { getUsersAction } from '@/app/actions/user.actions';
export default function UsersPage() {
const [users, setUsers] = useState([]);
useEffect(() => {
getUsersAction().then(setUsers);
}, []);
return <div>{/* Render users */}</div>;
}Storage Examples
import { storage } from "@mxweb/utils";
// User preferences
interface UserPreferences {
theme: "light" | "dark";
language: string;
}
storage.local.setItem("prefs", { theme: "dark", language: "en" });
const prefs = storage.local.getItem<UserPreferences>("prefs");
// Session management
interface Session {
userId: number;
expiresAt: number;
}
storage.session.setItem("session", {
userId: 123,
expiresAt: Date.now() + 24 * 60 * 60 * 1000,
});
// Cookie-based auth
storage.cookie.setItem("access_token", "token123");
const token = storage.cookie.getItem<string>("access_token");Advanced Usage
API Client with Interceptors
import { Http, storage, sleep } from "@mxweb/utils";
class ApiClient {
private http: Http;
constructor(baseURL: string) {
this.http = new Http(baseURL);
this.http.setStorage(storage.local);
this.setupInterceptors();
}
private setupInterceptors() {
// Add auth token
this.http.on("request", async (options) => {
const token = storage.local.getItem<string>("access_token");
if (token) {
options.headers = {
...options.headers,
Authorization: `Bearer ${token}`,
};
}
return options;
});
// Handle token refresh
this.http.on("response", async (response) => {
if (response.status === 401) {
const newToken = await this.refreshToken();
if (newToken) {
response.config.headers["Authorization"] = `Bearer ${newToken}`;
return await this.http.request(response.config);
}
}
return response;
});
// Retry on error
this.http.on("error", async (error) => {
if (!error.retryCount) error.retryCount = 0;
if (error.retryCount < 3) {
error.retryCount++;
await sleep(1000 * error.retryCount);
return await this.http.request(error.config);
}
return error;
});
}
private async refreshToken(): Promise<string | null> {
const refreshToken = storage.local.getItem<string>("refresh_token");
if (!refreshToken) return null;
const response = await this.http.post<{ accessToken: string }>("/auth/refresh", {
refreshToken,
});
if (response.success) {
storage.local.setItem("access_token", response.data.accessToken);
return response.data.accessToken;
}
return null;
}
async get<T>(url: string, query?: any) {
return this.http.get<T>(url, query);
}
async post<T>(url: string, body?: any) {
return this.http.post<T>(url, body);
}
}
// Usage
const api = new ApiClient("https://api.example.com");
const users = await api.get("/users");Configuration
Environment Variables
import { getEnv } from "@mxweb/utils";
// Works with any framework - automatically detects prefix
// React: REACT_APP_API_URL
// Next.js: NEXT_PUBLIC_API_URL
// Vite: VITE_API_URL
// Nuxt: NUXT_PUBLIC_API_URL
// Node.js: API_URL
const config = {
apiUrl: getEnv("API_URL", "https://api.example.com"),
apiKey: getEnv("API_KEY", ""),
debug: getEnv("DEBUG", "false") === "true",
};Authentication
import { Http, storage } from "@mxweb/utils";
const http = new Http("https://api.example.com");
http.setStorage(storage.local);
// Request interceptor - add auth token
http.on("request", async (options) => {
const token = storage.local.getItem<string>("access_token");
if (token) {
options.headers = { ...options.headers, Authorization: `Bearer ${token}` };
}
return options;
});
// Response interceptor - handle 401
http.on("response", async (response) => {
if (response.status === 401) {
// Refresh token or redirect to login
}
return response;
});Interceptors
import { Http, sleep } from "@mxweb/utils";
const http = new Http("https://api.example.com");
// Request interceptor
http.on("request", async (options) => {
options.headers = {
...options.headers,
"X-Request-ID": `req_${Date.now()}`,
};
return options;
});
// Response interceptor
http.on("response", async (response) => {
console.log(`Response: ${response.status}`);
return response;
});
// Error interceptor with retry
http.on("error", async (error) => {
if (!error.retryCount) error.retryCount = 0;
if (error.retryCount < 3) {
error.retryCount++;
await sleep(1000 * error.retryCount);
return await http.request(error.config);
}
return error;
});TypeScript Support
@mxweb/utils is written in TypeScript and provides full type safety with comprehensive type definitions for all utilities.
import { Http, storage, chunk } from "@mxweb/utils";
// Generic types
interface User {
id: number;
name: string;
}
const http = new Http("https://api.example.com");
const response = await http.get<User[]>("/users");
response.data; // Type: User[] | undefined
// Storage with types
storage.local.setItem<User>("user", { id: 1, name: "John" });
const user = storage.local.getItem<User>("user"); // Type: User | null
// Array utilities preserve types
const nums = [1, 2, 3, 4, 5];
const chunks = chunk(nums, 2); // Type: number[][]IDE Support
Full IntelliSense, autocomplete, type hints, and error checking in VS Code, WebStorm, and other TypeScript-aware IDEs.
Browser Support
@mxweb/utils supports all modern browsers and Node.js environments.
Modern Browsers
- โ Chrome 90+
- โ Firefox 88+
- โ Safari 14+
- โ Edge 90+
Mobile Browsers
- โ iOS Safari 14+
- โ Chrome for Android 90+
Node.js
- โ Node.js 14.x+
- โ Node.js 16.x LTS
- โ Node.js 18.x LTS
- โ Node.js 20.x LTS
Contributing
We welcome contributions! Please see our Contributing Guidelines for details.
Quick Start
- Fork the repository
- Install dependencies:
npm install - Make your changes
- Run tests:
npm test - Submit a pull request
License
MIT License
Copyright (c) 2024 MXWeb
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Changelog
[0.0.1] - 2025-10-31
Added
- Initial release of
@mxweb/utils - HTTP client with Fetch API and XMLHttpRequest support
- Type-safe API client with
createInfer - Storage utilities (localStorage, sessionStorage, cookies)
- Array utilities (
chunk,flatten) - String utilities (
pascalToKebab,interpolate) - Object utilities (
flatten) - File/Format utilities (
formatSize) - Environment variable utilities (
getEnv) - Async utilities (
sleep) - Full TypeScript support
- Request/response/error interceptors
- File upload with progress tracking
Authors
- MXWeb Team - MXWeb
Acknowledgments
- Thanks to all contributors
- Inspired by Lodash, Axios, and modern utility libraries
- Built with TypeScript and bundled using Rollup
- Code quality maintained with ESLint and Prettier
- Tested with Vitest for reliability and stability
Made with โค๏ธ by MxWeb.IO
โญ Star us on GitHub โ it helps!