nicklabs-utils
v1.0.5
Published
A lightweight utility library for Vue 3 applications, providing helpers for localStorage, file handling, image processing, device detection, and more.
Readme
nicklabs-utils
A lightweight utility library for Vue 3 applications, providing helpers for localStorage, file handling, image processing, device detection, and more.
Version: 1.0.2 | Framework: Vue 3.5+
Table of Contents
Installation
npm install nicklabs-utils
# or
pnpm add nicklabs-utilsSetup
Import the default export and use its modules:
import utils from 'nicklabs-utils'
// Use any module
utils.store.set('key', 'value')
utils.str.random()
utils.device.isMobile()Prototype Extensions (optional)
Call utils.init() once at app startup to register extensions on Array, Date, and FileList:
// main.ts
import utils from 'nicklabs-utils'
utils.init()After calling init(), native types gain additional methods (see Prototype Extensions).
Modules
store
Persistent key-value storage backed by localStorage, with optional expiration and base64 encoding.
import utils from 'nicklabs-utils'
const { store } = utilsstore.set(key, value, expire?)
Store a value. Optionally set an expiration time in seconds.
| Parameter | Type | Description |
|-----------|------|-------------|
| key | string | Storage key |
| value | any | Value to store (auto-serialized) |
| expire | number | TTL in seconds (optional) |
// Store indefinitely
store.set('theme', 'dark')
// Store with 1-hour expiry
store.set('authToken', 'abc123', 3600)
// Store an object
store.set('user', { id: 1, name: 'Alice' })store.get<T>(key, defaultValue)
Retrieve a stored value. Returns defaultValue if missing or expired.
| Parameter | Type | Description |
|-----------|------|-------------|
| key | string | Storage key |
| defaultValue | T | Fallback value |
const theme = store.get<string>('theme', 'light')
const user = store.get<User>('user', null)store.has(key)
Check whether a key exists (and has not expired).
if (store.has('authToken')) {
// proceed
}store.forget(key)
Delete a stored key.
store.forget('authToken')str
String generation and clipboard utilities.
import utils from 'nicklabs-utils'
const { str } = utilsstr.random(length?)
Generate a random alphanumeric string.
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| length | number | 5 | Output length |
str.random() // e.g. "aB3xZ"
str.random(12) // e.g. "k9mXpQ2nLrTw"str.copy(text)
Copy a string to the clipboard.
await str.copy('Hello, world!')date
Date calculation and calendar generation utilities.
import utils from 'nicklabs-utils'
const { date } = utilsdate.getCalendarByDate(date)
Generate a full month calendar structure for the given date.
| Parameter | Type | Description |
|-----------|------|-------------|
| date | Date | Any date within the target month |
Returns IUtilsDateCalendar:
interface IUtilsDateCalendar {
year: number
month: number // 1–12
days: {
day: number // Day of month
week: number // 1=Monday ... 6=Saturday, 7=Sunday
}[]
}const calendar = date.getCalendarByDate(new Date())
// {
// year: 2025,
// month: 5,
// days: [
// { day: 1, week: 4 }, // Thursday
// { day: 2, week: 5 }, // Friday
// ...
// ]
// }image
Image processing utilities: resizing, thumbnail generation, and format conversion.
import utils from 'nicklabs-utils'
const { image } = utilsAll conversions use JPEG encoding at 0.8 quality and maintain aspect ratio.
Core Functions
| Function | Signature | Description |
|----------|-----------|-------------|
| base64StringToBlob | (base64: string) => Promise<Blob> | Convert base64 string to Blob (auto-detects MIME type) |
| getImageElement | (source: Blob \| string) => Promise<HTMLImageElement> | Load an image from Blob or base64 |
| createCanvasWithWidth | (img: HTMLImageElement, maxWidth: number) => HTMLCanvasElement | Resize image to max width, preserving aspect ratio |
| canvasToBase64 | (canvas: HTMLCanvasElement) => string | Export canvas as base64 string |
| canvasToBlob | (canvas: HTMLCanvasElement) => Promise<Blob> | Export canvas as Blob |
| createThumbnailCanvas | (source: Blob \| string, width: number) => Promise<HTMLCanvasElement> | Create a resized canvas from Blob or base64 |
Thumbnail Convenience Functions
| Function | Input → Output |
|----------|----------------|
| thumbnailFromBlobToBase64(blob, width) | Blob → base64 string |
| thumbnailFromBlobToBlob(blob, width) | Blob → Blob |
| thumbnailFromBase64ToBase64(base64, width) | base64 → base64 string |
| thumbnailFromBase64ToBlob(base64, width) | base64 → Blob |
// Generate a 200px-wide thumbnail from a file input
async function handleFileUpload(file: File) {
const base64 = await utils.file.convertBase64(file)
const thumbnail = await image.thumbnailFromBase64ToBase64(base64, 200)
// thumbnail is a base64 string ready for <img src>
}
// Resize a blob and re-upload
const resizedBlob = await image.thumbnailFromBlobToBlob(originalBlob, 800)file
File and Blob URL utilities.
import utils from 'nicklabs-utils'
const { file } = utilsfile.convertBase64(file)
Convert a File object to a base64 string (data URI prefix stripped).
const base64 = await file.convertBase64(myFile)
// "iVBORw0KGgoAAAANSUhEUgAA..."file.createImageUrlFromFile(file)
Create a temporary object URL from a File.
const url = await file.createImageUrlFromFile(myFile)
// "blob:http://localhost:5173/abc123..."
img.src = urlfile.createImageUrlFromBlob(blob)
Create a temporary object URL from a Blob.
const url = file.createImageUrlFromBlob(myBlob)
img.src = urlfile.revokeObjectUrl(url)
Release a previously created object URL to free memory.
file.revokeObjectUrl(url)Example: Preview + cleanup
const url = await file.createImageUrlFromFile(selectedFile)
previewSrc.value = url
// Clean up when done
onUnmounted(() => file.revokeObjectUrl(url))input
Programmatic file picker dialogs that return typed file metadata.
import utils from 'nicklabs-utils'
const { input } = utilsAll methods return Promise<IFile[]> — see IFile in the type reference.
| Method | Accepted Types | Description |
|--------|---------------|-------------|
| input.all(multiple?, convertBase64?) | Any | Open generic file picker |
| input.image(multiple?, convertBase64?) | jpg, jpeg, png, gif, bmp | Image files only |
| input.documentFile(multiple?, convertBase64?) | pdf, doc, docx, txt, md | Document files only |
| input.video(multiple?, convertBase64?) | mp4, mov, webm, ogg | Video files only |
| input.audio(multiple?, convertBase64?) | mp3, wav, ogg, aac, flac | Audio files only |
| input.custom(accept?, multiple?, convertBase64?) | Custom MIME string | Any type with custom accept |
Parameters
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| multiple | boolean | false | Allow multiple file selection |
| convertBase64 | boolean | false | Auto-convert files to base64 |
| accept | string | — | MIME type string (custom only) |
// Pick a single image
const [selected] = await input.image()
console.log(selected.name, selected.sizeInMB)
// Pick multiple documents
const files = await input.documentFile(true)
files.forEach(f => console.log(f.name, f.type))
// Pick images and get base64 immediately
const [img] = await input.image(false, true)
previewSrc.value = img.base64String
// Custom MIME types
const files = await input.custom('application/json,.csv', true)device
User-agent based device detection.
import utils from 'nicklabs-utils'
const { device } = utils| Method | Returns | Description |
|--------|---------|-------------|
| device.isMobile() | boolean | True for phones (Android, iPhone, etc.) |
| device.isTablet() | boolean | True for tablets (iPad, Android tablet, etc.) |
| device.isDesktop() | boolean | True if not mobile and not tablet |
if (device.isMobile()) {
// show mobile layout
} else if (device.isTablet()) {
// show tablet layout
} else {
// show desktop layout
}link
File download and external link utilities.
import utils from 'nicklabs-utils'
const { link } = utilslink.download(url, name?)
Trigger a file download from a URL.
| Parameter | Type | Description |
|-----------|------|-------------|
| url | string | File URL to download |
| name | string | Optional filename for the downloaded file |
link.download('https://example.com/report.pdf', 'monthly-report.pdf')
link.download('/exports/data.csv')link.openExternalLink(url)
Open a URL in a new browser tab.
link.openExternalLink('https://github.com')screen
Fullscreen API wrapper.
import utils from 'nicklabs-utils'
const { screen } = utilsscreen.fullScreenToggle()
Toggle the browser fullscreen mode on/off.
// In a button handler
function toggleFullscreen() {
screen.fullScreenToggle()
}tool
Timing and flow-control utilities.
import utils from 'nicklabs-utils'
const { tool } = utilstool.debounce(callback, wait?)
Execute a callback after a delay, resetting the timer on each call. Useful for search inputs and resize handlers.
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| callback | () => void | — | Function to execute |
| wait | number | 50 | Delay in milliseconds |
// Debounce a search input
function onSearchInput(value: string) {
tool.debounce(() => {
fetchResults(value)
}, 300)
}
// Debounce a resize handler
window.addEventListener('resize', () => {
tool.debounce(updateLayout, 100)
})Prototype Extensions
Call utils.init() once at app startup to register these extensions on native types.
import utils from 'nicklabs-utils'
utils.init()Array Extensions
| Method | Returns | Description |
|--------|---------|-------------|
| .clear() | void | Remove all elements (mutates in place) |
| .first() | T \| undefined | Get the first element |
| .last() | T \| undefined | Get the last element |
const items = [1, 2, 3]
items.first() // 1
items.last() // 3
items.clear() // items is now []Date Extensions
| Method | Returns | Description |
|--------|---------|-------------|
| .isValid() | boolean | Check if the date is valid |
| .getRealMonth() | number | Month as 1–12 (not 0–11) |
| .getFullMonth() | string | Zero-padded month, e.g. "05" |
| .getFullDate() | string | Zero-padded day, e.g. "07" |
| .daysInMonth() | number | Number of days in the month |
| .addYears(n?) | Date | Add years (default: 1) |
| .minusYears(n?) | Date | Subtract years (default: 1) |
| .addMonths(n?) | Date | Add months (default: 1) |
| .minusMonths(n?) | Date | Subtract months (default: 1) |
| .addDays(n?) | Date | Add days (default: 1) |
| .minusDays(n?) | Date | Subtract days (default: 1) |
const d = new Date('2025-05-07')
d.isValid() // true
d.getRealMonth() // 5
d.getFullMonth() // "05"
d.getFullDate() // "07"
d.daysInMonth() // 31
d.addDays(10) // 2025-05-17
d.minusDays(7) // 2025-04-30
d.addMonths(2) // 2025-07-07
d.minusMonths(1) // 2025-04-07
d.addYears() // 2026-05-07
d.minusYears(3) // 2022-05-07
// Format a date
const today = new Date()
const label = `${today.getFullYear()}-${today.getFullMonth()}-${today.getFullDate()}`
// "2025-05-07"FileList Extensions
| Method | Returns | Description |
|--------|---------|-------------|
| .toArray() | File[] | Convert FileList to a standard Array |
// In a file input change handler
function onFileChange(event: Event) {
const files = (event.target as HTMLInputElement).files?.toArray() ?? []
files.forEach(f => console.log(f.name))
}Type Reference
IFile
Returned by all input.* methods.
interface IFile {
file: File // Original File object
name: string // Filename
size: number // Size in bytes
sizeInKB: number // Size in KB
sizeInMB: number // Size in MB
type: string // MIME type
base64String?: string // Base64 content (if convertBase64=true)
}IUtilsDateCalendar
Returned by date.getCalendarByDate().
interface IUtilsDateCalendar {
year: number
month: number // 1–12
days: {
day: number // Day of month
week: number // 1=Monday ... 6=Saturday, 7=Sunday
}[]
}ILocalSession
Internal structure used by the store module.
interface ILocalSession {
key: string
value: any
expireTime?: number // Unix timestamp in ms
}