@vouchington/utils
v0.5.1
Published
Dependency-free runtime utilities for Vouchington-style applications.
Readme
@vouchington/utils
Dependency-free utilities for Node.js 24 applications. This package deliberately has no root export: import the capability you use from an explicit subpath.
import { createTokenSecrets } from '@vouchington/utils/token-secrets'
import { createMoneyCatalog } from '@vouchington/utils/money'
import { parseCookies, serializeCookie } from '@vouchington/utils/cookies'
import { buildSignatureHeaders, verifySignature } from '@vouchington/utils/http-signatures'
import { bestAcceptLanguageMatch } from '@vouchington/utils/language-tags'
import { createMessageTranslator } from '@vouchington/utils/message-catalog'
import { createReportInputParser } from '@vouchington/utils/moderation'Subpaths
token-secrets: Node-only (node:crypto) purpose-bound HMAC and AES-256-GCM encryption.createTokenSecrets({ hashSecret, encryptionKeys })throws for invalid keys or ciphertext.deploy-environment:getDeployEnvironment(source)classifies explicit environment inputs without throwing.url-signing: Node-only HMAC SHA-256signPathWithKey(path, key)and verification; invalid keys throw and invalid signatures returnfalse.request-client-info:createClientInfoParser(config)validates caller-selected headers, families, platforms, compatibility, and versions.money:createMoneyCatalog(currencies, scale)supplies exact integer parsing and validation for the caller's catalog.allocateProportionalAmount(amount, numerator, denominator, rounding)allocates an inclusive fraction withdownorupinteger rounding chosen explicitly by the caller; it uses exact integer arithmetic rather than floating-point division.env-contract:groupEnvContracts()andnormalizeEnvContractGroups()produce delimiter-safe metadata keys and surface/sensitivity lookups.cookies:serializeCookie(name, value, attributes)validates cookie grammar and requires the caller to supply every policy attribute.SameSite=NonerequiresSecure.parseCookies(header)splits aCookierequest header into a name/valueMap.http-signatures: Node-only (node:crypto) Cavage-12 HTTP Signatures. Callers pass signed headers, allowed algorithms, andmaxAgeSecondson both sign and verify. The package has no default header set or product keyId policy.collections,async, andstable-json: collection deduplication/merging, bounded async mapping, and deterministic JSON serialization.feature-flags: base64 JSON feature-flag cookie parsing and serialization with caller-injected codecs, cookie names, and size policy.dates,format,strings, andtext-metrics: UTC-day, duration, weighted-average and display formatting, text normalization, title casing, and word/sentence helpers.gtin,bigint-ids, andvalidation: GTIN predicates, canonical positive PostgreSQL bigint IDs, and basic email/UUID predicates.moderation: caller-configured report target, reason, identifier, note, and cross-field input validation. Applications own catalogs, policy, error mapping, persistence, and HTTP behavior.queryandquery-string: generic array/boolean/number parsing, bounded integer parsing, and query-string serialization. Cursor parsing intentionally belongs to@vouchington/pagination.slugsandurls: ASCII-only slugification, theisSluglowercase[a-z0-9-]+predicate (leading, trailing, and consecutive hyphens are allowed), and URL/hostname primitives. URL hostname helpers returnnullfor invalid input;normalizeAsciiHostnamenames its ASCII-only contract directly, whilenormalizeHostnamealso supports WHATWG IDN conversion.matchesHostnamePatternsupports exact and inclusive*.hostname patterns.hashtags: caller-configured authored/key length and separator policy for canonical ASCII hashtag keys, plusmaskHashtagBearingUrlsto blank absolute URLs and fragment-bearing relative paths. The package does not choose application limits or accepted input separators.utm:createUtmParser({ sourceAliases, fallbackSourceParam? })lowercases and trims UTM fields and resolvesutm_sourcethrough caller-owned aliases. The package has no default shortcode map.fetch-ports: the Fetch standard forbidden-port list and membership predicates.http-body: bounded Fetch response-body reads with abort propagation and typed missing/oversize errors.http-link-pagination: fail-closed RFC 8288 next-link parsing with same-origin URL and unambiguous cursor extraction.language-tags: caller-configured locale normalization and strictAccept-Languageparsing and best matching. HTTP ranges reject malformed syntax and quality parameters; explicitq=0ranges exclude a candidate when they tie for that candidate's most-specific matching range, soen;q=0overrides an equalen;q=1, whileen-US;q=1overrides broaderen;q=0for supporteden-US. A truncated fallback (en-USto supporteden) instead uses the ranges that matchen, soen;q=0or*;q=0excludes it. Matching compares an exact supported tag, then truncates the request (en-UScan match supporteden); it never expandsento an arbitrary regional supported tag. Invalid configured tags are ignored. This subpath has no default locale or supported-tag policy.message-catalog: typed nested catalog translation for string, plural, and select-plural JSON descriptors. Catalog segments cannot contain dots because dots delimit nested keys. Plural values and configured number parameters must be finite numbers; callers own catalog content, locale choice, and number formatting.observability: SDK-free URL, request, event, and span scrubbing plus a bounded spike-window tracker. Callers provide credential headers and environment or spike policy; this package has no product defaults.
const money = createMoneyCatalog([{ code: 'credit', minorUnitExponent: 2 }] as const, 6)
money.parseMajorUnitsToMoney('12.34', 'credit')Applications supply all product identifiers, environment names, header names, policy, and catalogs.
