
Product
Introducing Webhook Events for Alert Changes
Add real-time Socket webhook events to your workflows to automatically receive software supply chain alert changes in real time.
@flaconi/metadata-mapper
Advanced tools
A TypeScript library for parsing and mapping Flaconi metadata including stores, languages, currencies, and channels configuration
Standardized TypeScript library for Flaconi's metadata processing
A comprehensive TypeScript library for parsing and mapping Flaconi metadata including stores, languages, currencies, and channels configuration. This library provides a robust, type-safe interface for working with Flaconi's multi-regional store setup.
# Using npm
npm install @flaconi/metadata-mapper
# Using yarn
yarn add @flaconi/metadata-mapper
import { MetadataMapper, defaultFlaconiMetadata } from '@flaconi/metadata-mapper';
// Initialize with default embedded metadata
const mapper = new MetadataMapper(defaultFlaconiMetadata);
// Get language by store code (uppercase format)
const language = mapper.getLanguageByStore('DE');
console.log(language); // 'de-DE'
// Get language by website identifier (this is the key use case!)
const websiteLanguage = mapper.getLanguageByWebsite('base');
console.log(websiteLanguage); // 'de-DE'
// Map store to website identifier
const websiteId = mapper.mapStoreToWebsiteId('de');
console.log(websiteId); // 'base'
This library is a drop-in replacement for LocaleMapper. Simply replace your import and instance:
// Before
import { LocaleMapper } from 'path/to/locale-mapper';
const localeMapper = new LocaleMapper(metadata);
// After
import { MetadataMapper, defaultFlaconiMetadata } from '@flaconi/metadata-mapper';
const localeMapper = new MetadataMapper(defaultFlaconiMetadata);
// All method calls remain the same!
const language = localeMapper.getLanguageByWebsite('base');
const store = localeMapper.getStoreByWebsite('flaconi_at');
const currency = localeMapper.getCurrencyByStore('CH');
import { MetadataMapper, defaultFlaconiMetadata } from '@flaconi/metadata-mapper';
const mapper = new MetadataMapper(defaultFlaconiMetadata);
// Get language by store (expects uppercase store codes)
const language = mapper.getLanguageByStore('AT');
console.log(language); // 'de-AT'
// Get currency by store
const currency = mapper.getCurrencyByStore('CH');
console.log(currency); // 'CHF'
// Get price channel by store
const channel = mapper.getChannelByStore('FR');
console.log(channel); // 'flaconi-fr'
// Get all available stores
const stores = mapper.getStores();
console.log(stores); // ['DE', 'AT', 'CH', 'FR', 'IT', 'PL', 'BERLIN_1', 'BERLIN_2']
This library provides full compatibility for website-based mapping operations:
// Real-world example: Processing price data with website identifiers
interface PriceData {
websites: string; // e.g., 'base', 'flaconi_at', 'berlin_1'
// ... other price fields
}
const newPrice: PriceData = {
websites: 'base' // This is the website identifier for DE store
};
// Get language by website (replaces localeMapper.getLanguageByWebsite)
const language = mapper.getLanguageByWebsite(newPrice.websites);
console.log(language); // 'de-DE'
// Get store by website identifier
const store = mapper.getStoreByWebsite(newPrice.websites);
console.log(store); // 'DE'
// Map website back to other store properties
const currency = mapper.getCurrencyByStore(store);
console.log(currency); // 'EUR'
// Map store codes to website identifiers (special logic for DE and Berlin stores)
const websiteId1 = mapper.mapStoreToWebsiteId('de');
console.log(websiteId1); // 'base' (special case)
const websiteId2 = mapper.mapStoreToWebsiteId('at');
console.log(websiteId2); // 'flaconi_at'
const websiteId3 = mapper.mapStoreToWebsiteId('berlin_1');
console.log(websiteId3); // 'berlin_1' (special case)
// Get all available websites
const websites = mapper.getWebsites();
console.log(websites); // ['base', 'flaconi_at', 'flaconi_ch', 'flaconi_fr', 'flaconi_it', 'flaconi_pl', 'berlin_1', 'berlin_2']
// Before: Using LocaleMapper in your service
// const language = this.localeMapper.getLanguageByWebsite(newPrice.websites);
// const store = this.localeMapper.getStoreByWebsite(newPrice.websites);
// const currency = this.localeMapper.getCurrencyByStore(store);
// After: Using MetadataMapper (drop-in replacement)
const language = mapper.getLanguageByWebsite(newPrice.websites);
const store = mapper.getStoreByWebsite(newPrice.websites);
const currency = mapper.getCurrencyByStore(store);
console.log(`Website: ${newPrice.websites}`); // 'base'
console.log(`Language: ${language}`); // 'de-DE'
console.log(`Store: ${store}`); // 'DE'
console.log(`Currency: ${currency}`); // 'EUR'
import { MetadataMapper, defaultFlaconiMetadata } from '@flaconi/metadata-mapper';
// Initialize the mapper (replaces your LocaleMapper instance)
const mapper = new MetadataMapper(defaultFlaconiMetadata);
// Example: Processing price data objects
interface PriceData {
websites: string; // e.g., 'base', 'flaconi_at', 'berlin_1'
price: number;
// ... other fields
}
function processPriceData(newPrice: PriceData) {
// This exact line from your codebase now works with MetadataMapper:
const language = mapper.getLanguageByWebsite(newPrice.websites);
// Get additional context for processing
const store = mapper.getStoreByWebsite(newPrice.websites);
const currency = mapper.getCurrencyByStore(store);
const channel = mapper.getChannelByStore(store);
console.log(`Processing price for website: ${newPrice.websites}`);
console.log(`→ Language: ${language}`);
console.log(`→ Store: ${store}`);
console.log(`→ Currency: ${currency}`);
console.log(`→ Channel: ${channel}`);
return {
language,
store,
currency,
channel
};
}
// Example usage with different website identifiers
processPriceData({ websites: 'base', price: 29.99 }); // German store
processPriceData({ websites: 'flaconi_at', price: 29.99 }); // Austrian store
processPriceData({ websites: 'berlin_1', price: 29.99 }); // Berlin physical store
import { MetadataMapper, defaultFlaconiMetadata } from '@flaconi/metadata-mapper';
// Use with default embedded data (no external dependencies)
const mapper = new MetadataMapper(defaultFlaconiMetadata);
// Or use with custom metadata (useful for testing)
const customMetadata = {
stores: {
us: {
languages: ['en-US'],
currency: 'USD',
priceChannel: 'flaconi-us'
}
}
};
const customMapper = new MetadataMapper(customMetadata);
// Methods return values directly or throw errors for invalid input
try {
const language = mapper.getLanguageByStore('US'); // Throws if 'US' doesn't exist
console.log(language);
} catch (error) {
console.error('Store not found:', error.message);
}
// The library throws descriptive errors for invalid input
try {
const language = mapper.getLanguageByStore('INVALID_STORE');
} catch (error) {
console.error('Store not found:', error.message);
// Error: Language not found for store: INVALID_STORE
}
try {
const store = mapper.getStoreByWebsite('invalid_website');
} catch (error) {
console.error('Website not found:', error.message);
// Error: Store not found for website: invalid_website
}
// Get all available stores (including special stores like BERLIN_1, BERLIN_2)
const stores = mapper.getStores();
console.log(stores); // ['DE', 'AT', 'CH', 'FR', 'IT', 'PL', 'BERLIN_1', 'BERLIN_2']
// Get all available website identifiers
const websites = mapper.getWebsites();
console.log(websites); // ['base', 'flaconi_at', 'flaconi_ch', 'flaconi_fr', 'flaconi_it', 'flaconi_pl', 'berlin_1', 'berlin_2']
// Direct mapping without additional lookups
const websiteId = mapper.mapStoreToWebsiteId('ch');
console.log(websiteId); // 'flaconi_ch'
| Method | Parameters | Returns | Description |
|---|---|---|---|
getLanguageByStore(store) | store: string | string | Get language code by store (expects uppercase) |
getCurrencyByStore(store) | store: string | string | Get currency code by store |
getChannelByStore(store) | store: string | string | Get price channel by store |
getLanguageByWebsite(website) | website: string | string | Get language code by website identifier |
getStoreByWebsite(website) | website: string | string | Get store code by website identifier |
mapStoreToWebsiteId(store) | store: string | string | Map store code to website identifier |
getStores() | - | string[] | Get all available store codes |
getWebsites() | - | string[] | Get all available website identifiers |
interface FlaconiMetadata {
stores: Record<string, {
languages: string[]; // Array of supported languages (first is primary)
currency: string; // ISO 4217 currency code
priceChannel: string; // Price channel identifier
}>;
physicalStores?: Record<string, {
languages: string[]; // Languages for physical stores
currency: string; // Currency for physical stores
priceChannel: string; // Price channel for physical stores
}>;
}
The library is built with the following principles:
de store → base websiteberlin_1 store → berlin_1 website (special case)berlin_2 store → berlin_2 website (special case)flaconi_{storeCode} websiteThe library includes comprehensive tests with 100% coverage:
# Run tests
yarn test
# Run tests with coverage
yarn test:coverage
# Run tests in watch mode
yarn test:watch
# Install dependencies
yarn install
# Run type checking
yarn type-check
# Run linting
yarn lint
# Build the library
yarn build
# Run all checks (used in CI)
yarn prepublishOnly
The library provides multiple build formats:
dist/esm/ - ES Modules for modern bundlersdist/cjs/ - CommonJS for Node.jsdist/types/ - TypeScript declaration filesBeta versions are automatically published for feature branches:
git checkout -b feature/my-feature
git push origin feature/my-feature
# Publishes as @flaconi/metadata-mapper@x.x.x-beta.feature-my-feature.sha123
Stable versions are published when merging to main/master:
package.jsonCHANGELOG.mdgit checkout -b feature/my-featureyarn testyarn lintgit commit -am 'Add my feature'git push origin feature/my-featureThis project is licensed under the MIT License - see the LICENSE file for details.
This library is developed and maintained by Flaconi GmbH. Flaconi is one of the leading online beauty retailers in Europe.
@flaconi/aws-parameter-extension-helper - AWS Parameter Store integration@flaconi/eslint-config-typescript - ESLint configuration for TypeScriptNeed help? Create an issue in the GitHub repository.
FAQs
A TypeScript library for parsing and mapping Flaconi metadata including stores, languages, currencies, and channels configuration
We found that @flaconi/metadata-mapper demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 54 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Add real-time Socket webhook events to your workflows to automatically receive software supply chain alert changes in real time.

Security News
ENISA has become a CVE Program Root, giving the EU a central authority for coordinating vulnerability reporting, disclosure, and cross-border response.

Product
Socket now scans OpenVSX extensions, giving teams early detection of risky behaviors, hidden capabilities, and supply chain threats in developer tools.