Node.js and Vanilla JS
Relevant source files
The following files were used as context for generating this wiki page:
The @cellarnode/beverage-utils library provides a set of core utilities designed for Node.js and vanilla JavaScript environments. These utilities focus on the classification, normalization, and formatting of beverage-related data, serving as the foundation for the platform's industry-standard classification system.
The core implementation is written in pure TypeScript with zero mandatory dependencies for the base entry point, ensuring high performance and compatibility across various runtimes including Node.js, Deno, and Bun. It handles complex tasks such as disambiguating subtypes across categories, resolving international country codes, and parsing diverse volume formats into standard liters.
Sources: README.md:1-12, README.md:38-40, package.json:1-10
Core Utilities and Data Mapping
The library centers around the concept of a LabelMap, which is a flat lookup table generated from hierarchical beverage classification data. This map is essential for resolving human-readable names from IDs, particularly when IDs are reused across different beverage categories (e.g., "Red" appearing under both "Still Wine" and "Sparkling Wine").
Label Map Construction
The buildLabelMap function processes a BeverageClassification object to create three types of keys:
- Category ID: Maps directly to the category name.
- Subtype ID: Maps to the subtype name (last-write-wins for duplicates).
- Composite Key: Uses a
category:subtypeformat to provide unambiguous lookups.
The diagram shows the flow from raw classification data to the generation of a multi-keyed LabelMap.
Sources: src/label-map.ts:5-15, README.md:21-36
Formatting Logic
The formatting functions provide display-ready strings, handling null values and providing fallbacks when a lookup map is not available.
| Function | Purpose | Input | Fallback Behavior |
|---|---|---|---|
formatBeverageLabel | Converts slugs to labels | Key, Optional Map | Humanizes snake_case to Title Case |
formatBeverageType | Formats Category + Subtype | Cat, Sub, Map | Joins humanized slugs with " / " |
Sources: src/format.ts:3-23, README.md:42-63
Data Normalization and Resolution
For backend processing in Node.js or data cleaning in vanilla JS, the library includes robust normalization tools. These ensure that user-entered or third-party data is deterministic for comparison and ranking.
Token Normalization
The normalizeToken function prepares strings for comparison by removing diacritics, lowercasing, and collapsing whitespace into hyphens.
The flow demonstrates the multi-step transformation process used to create canonical tokens.
Sources: src/normalize.ts:7-18
Country and Volume Resolution
The library resolves inconsistent geographical and measurement data into standard formats.
- Country Resolution: Uses
i18n-iso-countriesto map English names, local names (ES, SV), or ISO alpha-3 codes to canonical ISO alpha-2 codes. - Volume Parsing: Converts various strings (e.g., "750ml", "20 hl", "bottles 750ml x 4000") into a numeric liter value.
Sources: src/normalize.ts:33-65, src/normalize.ts:72-114
Technical Architecture
The library is distributed as an ESM-first package with a clear separation between core logic and framework adapters.
Data Structures
The core logic relies on the following TypeScript interfaces:
BeverageSubtype: Containsid,name, and optionaloivType.BeverageCategory: Containsid,name, optionalhsHeading, and an array of subtypes.BeverageClassification: The root container for categories.
Sources: src/types.ts:1-17
Environment and Runtimes
The package is optimized for modern Node.js environments (v20.19.0+) and supports tree-shaking via sideEffects: false. It utilizes the NodeNext module resolution strategy to ensure strict ESM compliance.
This sequence shows the typical lifecycle of data fetching and utility usage in a vanilla JS/Node.js environment.
Sources: package.json:44-93, README.md:120-130, CHANGELOG.md:8-16
Summary
In Node.js and vanilla JS contexts, @cellarnode/beverage-utils provides the essential logic for interacting with the CellarNode classification system. By utilizing composite keys for disambiguation and robust normalization for data entry, it ensures that beverage data remains consistent across the platform. Its zero-dependency core makes it an ideal choice for high-performance server-side logic and lightweight client-side applications.