Label Map Builder
Relevant source files
The following files were used as context for generating this wiki page:
The Label Map Builder is a core utility within the @cellarnode/beverage-utils library designed to transform complex beverage classification data into a flattened, high-performance lookup map. Its primary purpose is to solve the ambiguity inherent in beverage industry classifications, where identical subtype identifiers (e.g., "Red") may exist across different categories (e.g., "Still Wine" vs. "Sparkling Wine").
By generating composite keys, the Label Map Builder allows developers to perform unambiguous lookups and format human-readable labels for display in user interfaces. It serves as the foundational data structure for the library's formatting functions and framework-specific adapters for React, Vue, and Angular.
Sources: README.md:18-24, src/label-map.ts:5-15
Core Logic and Data Transformation
The system processes a BeverageClassification object, which consists of a hierarchy of categories and subtypes. The transformation logic iterates through this hierarchy to populate a LabelMap, a simple key-value record where keys are strings and values are human-readable names.
Composite Key Generation
To prevent naming collisions, the builder implements a three-way mapping strategy for every entry:
- Category Mapping: Maps the Category ID to the Category Name.
- Flat Subtype Mapping: Maps the Subtype ID directly to the Subtype Name (note: last-write-wins for duplicate IDs).
- Composite Mapping: Maps a combined string of
category_id:subtype_idto the Subtype Name.
The resulting LabelMap allows for direct access via category IDs or specific composite keys to ensure precision.
Sources: src/label-map.ts:7-14, README.md:28-34
Data Structures
The Label Map Builder relies on specific TypeScript interfaces to define the shape of the classification data and the resulting lookup table.
| Interface | Description | Key Fields |
|---|---|---|
BeverageClassification | The root container for classification data. | categories: BeverageCategory[] |
BeverageCategory | Represents a high-level group (e.g., Wine, Beer). | id, name, subtypes |
BeverageSubtype | Represents specific types within a category. | id, name, oivType |
LabelMap | The output dictionary for lookups. | Record<string, string> |
Sources: src/types.ts:1-15, src/label-map.ts:3
Integration with Formatting Utilities
The LabelMap produced by the builder is intended to be consumed by the library's formatting functions to provide human-readable output.
formatBeverageType Logic
This function utilizes the LabelMap to construct a display string for a beverage's classification. It prioritizes the composite key (category:subtype) to ensure the correct subtype name is retrieved, falling back to a humanized slug if the map or specific entry is missing.
Sources: src/format.ts:13-22, README.md:49-55
Framework Implementation and Fetching
In modern web applications, the Label Map is typically generated from data fetched from the CellarNode Public API. The library provides hooks and services that automate the fetching, building, and caching process using TanStack Query.
API Interaction
The data is retrieved from the following endpoint:
GET /api/v1/classifications/beverage-types
Hook Architecture (React Example)
The useBeverageLabelMap hook encapsulates the fetch logic and the call to buildLabelMap.
export function beverageLabelMapOptions(apiBaseUrl: string) {
return queryOptions({
queryKey: ["beverage-classifications"] as const,
queryFn: async (): Promise<LabelMap> => {
const res = await fetch(`${apiBaseUrl}/api/v1/classifications/beverage-types`);
const data = await res.json();
return buildLabelMap(data.jsonData as BeverageClassification);
},
staleTime: Infinity,
});
}
Sources: src/react/use-beverage-label-map.ts:7-20, README.md:120-135
Summary
The Label Map Builder is an essential utility for handling the hierarchical and sometimes overlapping nature of beverage classifications. By transforming nested structures into a flat, composite-key LabelMap, it enables unambiguous identification and consistent formatting of beverage types across various software platforms and frameworks.
Sources: README.md:18-24, src/label-map.ts:5-15