@juicyllama/utils
v1.6.1
Published
Juicyllama Utils
Readme
Visit the JuicyLlama to learn more.
@juicyllama/utils
A collection of TypeScript utilities used across JuicyLlama projects. The package targets Node.js but several helpers also work in the browser where noted.
Contents
- Overview
- Install
- Quick start
- Utilities
- Enums
- Types
- Assets
- Environment variables
- Development
- Testing
- Build
Overview
This repo ships a single package that exports a set of small, focused utility classes and enums. The public API is defined in src/index.ts.
Install
npm install @juicyllama/utilsyarn add @juicyllama/utilspnpm add @juicyllama/utilsQuick start
import { Api, Dates, Logger, Strings } from '@juicyllama/utils'
const api = new Api()
const logger = new Logger(['example'])
const name = Strings.capitalize('juicy')
const nextWeek = Dates.addDays(new Date(), 7)
logger.log(`Hello ${name}`)Utilities
Api
HTTP wrapper around axios with structured logging via Logger.
get<T>(domain, url, config?, uuid?, interceptor?): GET request that returnsTor throws.post<T>(domain, url, data?, config?, uuid?, skipDebugLog?): POST request that returnsTor throws.patch<T>(domain, url, data?, config?, uuid?): PATCH request that returnsTor throws.put<T>(domain, url, data?, config?, uuid?): PUT request that returnsTor throws.delete(domain, url, config?, uuid?): DELETE request that returnstrueor throws.defaultConfig(): Default axios config with JSON headers.processError(...): Logs details and throws a newErrorwith a formatted message.
Notes:
domain and uuid are used only for logging context. Errors are logged and rethrown.
Classes
Utility for composing multiple classes.
ExtendsMultiple(baseClasses): Returns a constructor that mixes all base class instances and prototypes.
Color
Detects whether a color is light or dark.
lightOrDark(color): Accepts hex (#fff/#ffffff) orrgb(...)/rgba(...)strings. Throws on invalid formats.
Countries
Country helpers backed by src/assets/countries.json.
convertISO2ToISO3(iso2): Returns ISO3 code ornull.countryNameToISO2(countryName): Returns ISO2 code ornull.getCountry(ISO2): Returns aCountryrecord orundefined.
Csv
CSV parsing helpers for Express.Multer.File objects.
parseCsvFile(file, mappers?): Parses a CSV file buffer into an array of objects. Optional header remapping.createTempCSVFileFromString(content): Creates a temp CSV file for testing and returns{ filePath, csv_file, dirPath }.
Dates
Date and time utilities.
now(): Returns the current localDate.utc(): Returns aDateconstructed from UTC components.format(date, format): Formats a date. Supportsiso,date,time,datetime, and tokens likeYYYY,MMMM,MMM,MM,DD,Do,Day,HH,mm,ss,SSS.dayName(date): Returns day name with Monday as index 0.addDays(date, days)andsubtractDays(date, days).addMinutes(date, minutes).addHours(date, hours)andsubtractHours(date, hours).addStep(date, step, steps?): Adds aStepTypeto a date. Note the enum valueStepType.MONHTHS(spelling).lastMonth(): Returns{ from, to }for the previous month.isBetween(date, from, to).nextDate(frequency): Returns the next date forSubscriptionFrequency.ahead(date): Humanized time until a future date.ago(date, decimals?): Humanized time since a past date.diff(date1, date2, decimals?): Humanized duration between two dates.minutesAgo(minutes),hoursAgo(hours),daysAgo(days),weeksAgo(weeks),monthsAgo(months),yearsAgo(years).daysToGo(days, top_level?): Humanized remaining time for a number of days.
Emails
maskEmail(email): Returns a masked email address.
Enums (utility)
getKeyName(enumObj, value): Returns the enum key for a value.toArray(enumObj, key_name, pair_name): Converts an enum to an array of objects. Handles numeric enum reverse mappings.
Env
Environment helpers and .env file utilities.
get(): ReturnsEnvironmentbased onNODE_ENV.IsProd(),IsDev(),IsTest(),IsNotTest(),IsNotProd(),IsSandbox().useCache(): ReturnstrueunlessNODE_ENVistest.readEnvVars({ envPath, fileName }): Reads a.envfile into an array of lines.getEnvValue({ key, envPath, fileName }): Reads a single value from a.envfile.setEnvValue({ key, value, envPath?, fileName? }): Updates or inserts a key in a.envfile.setEnv({ values, envPath?, fileName? }): Batch updates a.envfile.
Errors (internal)
Errors exists in src/utils/Errors.ts but is not exported from src/index.ts.
format(error): Returns anErrorif passed one, wraps strings, otherwise returnsnew Error('Unknown error').
File
File and buffer helpers (Node.js only).
unlink(filePath?, dirPath?): Deletes a file or directory.createTempFileFromString({ fileName, mimetype, content }): Writes a temp file and returns{ filePath, file, dirPath }.createTempFilePath(fileName?): Returns{ filePath, dirPath, fileName }.md5Checksum(buffer): Returns a base64 MD5 hash.createFileFromBase64(base64, filename): Creates anExpress.Multer.File-shaped object.downloadFile(url): Downloads a file and returns anExpress.Multer.File-shaped object.getMimeType(fileName): Looks up MIME type insrc/assets/mimetypes.json.exists(filePath): Checks file existence.read(filePath): Reads a file as UTF-8.
Functions
whoIsMyDaddy(): Returns the calling function name based on the stack trace.
Geocoding
Geospatial helpers powered by Turf.js.
areCoordinatesInBoundingBox(coordinates, boundingBox).areCoordinatesInPolygon(coordinates, polygonCoords).areCoordinatesBetweenTwoPoints(coordinates, northeast, southwest, expand_by_meters?).expandBoundingBox(northeast, southwest, expand_by_meters).getDistance(from, to): Distance in meters.getBoundingBoxCenter(northeast, southwest).getDistanceBetweenTwoPoints(point1, point2): Distance in kilometers.
Json
JSON helpers for Express.Multer.File objects and browser storage.
parseJsonFile(file, mappers?): Parses a JSON array from a file buffer and optionally remaps keys.createTempJSONFileFromString(content): Creates a temp JSON file for testing.changeKeyValues(mappers, results).getLocalStorageObject(store_key): Returns parsed JSON fromlocalStorageornull.
Languages
Language lookup backed by src/assets/languages.json.
getLanguage(ISO2): Returns aLanguagerecord orundefined.
Locale
Browser locale detection with Node fallbacks.
getLocale(): Returns the browser locale orDEFAULT_LOCALE/VITE_DEFAULT_LOCALE.getCountry(): Extracts the country part from the locale.getLanguage(): Extracts the language part from the locale.
Logger
Structured logger with optional Grafana Loki push.
error(message, opts?),warn(...),log(...),debug(...),verbose(...).status(): Logs sample messages and Grafana status.table(data):console.tablein development.data(key, value): Deprecated convenience wrapper.
Log levels use LOG_LEVEL where 1=VERBOSE, 2=DEBUG, 3=LOG, 4=WARN, 5=ERROR. Default is 3.
Measurements
LbsToKgs(number)andKgsToLbs(number).GramsToOz(number).FtInchesToCm(number)andCmToFtInches(number).
Numbers
amountToCents(number).toCurrency(number, currency)usingSupportedCurrencies.toFinancial(number).
Objects
clean(object): Removes keys withundefined,'undefined', or empty string values.
OTP
generateVerificationCode(length): Returns a numeric string.
Phone
internationalCode(iso2): Returns the country dialling code as digits only.
Poll
Repeatedly executes a request until a validation function succeeds.
url(validate, url, config?, interval?, max_attempts?, domain?, uuid?).function(validate, func, interval?, max_attempts?, domain?, uuid?).
Defaults: interval=2000 ms, max_attempts=10. Throws an error after the max attempts.
Random
Random helpers and mock data.
LlamaFact(): Returns a random entry fromsrc/assets/llama.facts.json.uppercase,lowercase,number,symbol: Random single character getters.Number(min, max): Random integer in[min, max).String(length?): Random alphanumeric string.Password(length?): Random password containing upper, lower, number, symbol.Words(seperator?, length?, type?, transform?): Returns random words. Uses a simple internal faker-like stub.
Security
hashPassword(password): SHA-512 hash. Ifpassword.length === 128, returns the input.referrerCheck(referrer, domain): Enforces origin match in production.encode(data)anddecode(token): JWT encode/decode usingjwt-simpleandJWT-SIMPLE-SECRET.
Stopwatch
start(): Starts timing.check(): Returns elapsed seconds without stopping.stop(): Returns elapsed seconds and resets.seconds: Public property updated oncheck()andstop().
Strings
String helpers.
capitalize(str).replacer(template, obj): Template string replacement usingFunction. Use trusted templates only.numbersToLetters(number).numbersTo26Letters(number).toHTMLConversion(string)andfromHTMLtoStringConversion(string).az09Lowercase(string, skipClean?).onlyNumbers(string).slug(string): Lowercases, removes symbols, and replaces whitespace with dashes.plural(word, amount?)andsingular(word, amount?).stringToEmojis(string).numberToSlackEmojis(number).randomize(string).
System
isOffline(): ReturnstruewhenOFFLINEis set.
UUID
v4(): Generates a UUID v4 string.
Enums
CachePeriod:NEVER=0,MINUTE=60,TWENTY=1200,HOUR=3600,DAY=86400,WEEK=604800,MONTH=2419200,YEAR=31535965.Environment:production,sandbox,development,test. HelperfromStringToEnv(env?)maps a string to an enum.StatsMethods:COUNT,SUM,AVG.StepType:MINUTES,HOURS,DAYS,WEEKS,MONHTHS,YEARS.SupportedCurrencies:AUD,CAD,CHF,EUR,GBP,INR,MXN,USD,JPY,CNY,HKD,NZD,SEK,KRW,SGD,NOK,RUB,ZAR,TRY,BRL.SupportedLanguages:ENGLISH='en'.SubscriptionFrequency:DAILY=1,WEEKLY=7,BIWEEKLY=14,MONTHLY=30,BIMONTHLY=60,QUARTERLY=90,BIQUARTERLY=180,YEARLY=365.FrequencyPerYear:DAILY=365,TWICE_PER_WEEK=104,WEEKLY=52,TWICE_PER_MONTH=24,MONTHLY=12,QUARTERLY=4,YEARLY=1,NONE=0.DayNames:Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday.MonthNames:JanuarythroughDecember.MonthNamesShort:JanthroughDec.ComparisonOperator:GT,GTE,LT,LTE,EQ,NE,IS,NNULL.
Types
export interface Country {
'Country Name': string
ISO2: string
ISO3: string
'Top Level Domain': string
FIPS: string
'ISO Numeric': string
GeoNameID: number
E164: number
'Phone Code': number
Continent: string
Capital: string
'Time Zone in Capital': string
Currency: string
'Language Codes': string
Languages: string
'Area KM2': number
'Internet Hosts': number
'Internet Users': number
'Phones (Mobile)': number
'Phones (Landline)': number
GDP: number
}
export interface Language {
code: string
name: string
native: string
}Assets
The following JSON assets back the utilities:
src/assets/countries.json: Used byCountries.src/assets/languages.json: Used byLanguages.src/assets/dailing_codes.json: Used byPhone.src/assets/mimetypes.json: Used byFile.src/assets/llama.facts.json: Used byRandom.
Environment variables
These utilities read environment variables:
NODE_ENV: DeterminesEnvironmentand affectsEnvhelpers.DEFAULT_LOCALEandVITE_DEFAULT_LOCALE: Used byLocale.OFFLINE: Used bySystem.isOffline().LOG_LEVEL: Used byLogger.GRAFANA_BEARER_TOKEN,GRAFANA_SERVICE_NAME,GRAFANA_HOST: Used byLoggerfor Loki push.JWT-SIMPLE-SECRET: Used bySecurityfor JWT encoding and decoding.
Development
npm run lint
npm run format
npm run test
npm run buildnpm run go runs lint, format, test, and build in sequence.
Testing
Tests are written with Jest and live next to the utilities under src/utils/*.test.spec.ts.
npm testBuild
The compiled output is emitted to dist/ and type declarations are written to dist/index.d.ts by tsc.
