Getting Started
Relevant source files
The following files were used as context for generating this wiki page:
The @cellarnode/beverage-utils library provides a suite of utilities for handling beverage classifications on the CellarNode platform. Its primary purpose is to simplify the mapping, formatting, and normalization of beverage data, such as categories, subtypes, and production volumes. The library is built as a pure TypeScript core with zero external dependencies for the main entry point, ensuring compatibility with any JavaScript environment, including Node.js, Deno, Bun, and browser-based frameworks.
Sources: README.md:1-12, package.json:5-15, src/index.ts:1-6
Installation and Entry Points
The library is distributed via npm and supports multiple integration paths based on the target framework. While the core utilities are standalone, framework-specific adapters for React, Vue, and Angular are provided to integrate with TanStack Query for data fetching and caching.
| Import Path | Purpose | Peer Dependencies |
|---|---|---|
@cellarnode/beverage-utils | Core utilities (Label mapping, formatting, normalization) | None |
@cellarnode/beverage-utils/react | React hooks and query options | react, @tanstack/react-query |
@cellarnode/beverage-utils/vue | Vue composables and query options | vue, @tanstack/vue-query |
@cellarnode/beverage-utils/angular | Angular services and query options | @angular/core, @tanstack/angular-query-experimental |
Sources: README.md:14-23, package.json:20-41
Core Concepts: Composite Keys
A central feature of the library is the resolution of ambiguous beverage subtypes. In the CellarNode classification system, subtype IDs (e.g., red) may be reused across different categories (e.g., "Still Wine" vs. "Sparkling Wine"). To ensure unambiguous lookups, the library generates composite keys in the format category:subtype.
The diagram above illustrates how the buildLabelMap function generates different key types to prevent ID collisions across categories.
Sources: README.md:25-33, src/label-map.ts:5-15
Primary Utilities
Label Mapping and Formatting
The library provides functions to transform raw classification data into human-readable labels.
buildLabelMap(classification): Transforms aBeverageClassificationobject into a flatLabelMapdictionary.formatBeverageLabel(key, map?): Returns a display label for a given key. If no map is provided or no match is found, it "humanizes" the key (e.g.,sparkling_winebecomesSparkling Wine).formatBeverageType(category, subtype?, map?): Combines a category and optional subtype into a single string (e.g.,"Still Wine / Red Wine").
Sources: src/label-map.ts:5-15, src/format.ts:3-23
Data Normalization
Beyond label formatting, the library includes utilities for cleaning and standardizing data inputs.
normalizeToken(raw): Canonicalizes strings by removing diacritics, lowercasing, and replacing whitespace/underscores with hyphens.resolveCountryCode(raw): Converts various country references (names in English/Spanish/Swedish, or ISO alpha-3 codes) into a canonical ISO alpha-2 code.parseVolumeToLiters(raw): Parses free-text strings like "750ml", "20 hl", or "bottles 750ml x 4000" into a numeric value representing liters.
Sources: src/normalize.ts:7-21, src/normalize.ts:33-65, src/normalize.ts:72-118
Framework Integration
All framework adapters use TanStack Query to interact with the CellarNode Classification API. Data is cached with a staleTime of Infinity because classification structures are highly stable.
This sequence diagram shows the data flow from the external API through the core mapping logic to the UI framework.
Sources: src/react/use-beverage-label-map.ts:7-22, src/vue/use-beverage-label-map.ts:7-22, src/angular/beverage-label-map.service.ts:7-22
Data Models
The following TypeScript interfaces define the structure of the beverage classification data used by the utilities.
| Interface | Field | Type | Description |
|---|---|---|---|
BeverageSubtype | id | string | Unique identifier (within category). |
name | string | Human-readable name. | |
oivType | string? | Optional OIV classification code. | |
BeverageCategory | id | string | Unique identifier. |
name | string | Human-readable name. | |
subtypes | BeverageSubtype[] | Array of associated subtypes. | |
BeverageClassification | categories | BeverageCategory[] | Root object containing all categories. |
Sources: src/types.ts:1-17
Summary
The @cellarnode/beverage-utils library acts as a bridge between the CellarNode classification API and front-end applications. By providing a combination of core TypeScript logic and framework-specific hooks, it ensures that beverage data is displayed consistently and accurately across different platforms, while solving common data integrity issues like subtype ID collisions and inconsistent unit formatting.