@posthog/currency-normalization-plugin
Advanced tools
| const { | ||
| createEvent, | ||
| createIdentify, | ||
| createPageview, | ||
| createCache, | ||
| getMeta, | ||
| resetMeta, | ||
| clone, | ||
| } = require('@posthog/plugin-scaffold/test/utils.js') | ||
| const { setupPlugin, processEvent } = require('../index') | ||
| const rates = require('./rates.json') | ||
| global.fetch = jest.fn(async () => ({ | ||
| json: async () => rates, | ||
| })) | ||
| beforeEach(() => { | ||
| fetch.mockClear() | ||
| resetMeta({ | ||
| config: { | ||
| openExchangeRatesApiKey: 'API_KEY', | ||
| normalizedCurrency: 'EUR', | ||
| amountProperty: 'amount', | ||
| currencyProperty: 'currency', | ||
| normalizedAmountProperty: 'normalized_amount', | ||
| normalizedCurrencyProperty: 'normalized_currency', | ||
| }, | ||
| }) | ||
| }) | ||
| test('setupPlugin', async () => { | ||
| expect(fetch).toHaveBeenCalledTimes(0) | ||
| await setupPlugin(getMeta()) | ||
| expect(fetch).toHaveBeenCalledTimes(1) | ||
| expect(fetch).toHaveBeenCalledWith('https://openexchangerates.org/api/latest.json?app_id=API_KEY') | ||
| await setupPlugin(getMeta()) | ||
| expect(fetch).toHaveBeenCalledTimes(1) | ||
| // clear the cache and try again: | ||
| getMeta().cache = createCache() | ||
| await setupPlugin(getMeta()) | ||
| expect(fetch).toHaveBeenCalledTimes(2) | ||
| // clear the cache and try again: | ||
| getMeta().cache = createCache() | ||
| getMeta().config.openExchangeRatesApiKey = '' | ||
| await expect(setupPlugin(getMeta())).rejects.toThrow('No API key found!') | ||
| }) | ||
| test('changes nothing for $pageview events', async () => { | ||
| const pageviewEvent = createPageview() | ||
| const processedPageviewEvent = await processEvent(clone(pageviewEvent), getMeta()) | ||
| expect(processedPageviewEvent).toEqual(pageviewEvent) | ||
| expect(fetch).toHaveBeenCalledTimes(0) | ||
| }) | ||
| test('changes nothing for $identify events', async () => { | ||
| const identifyEvent = createIdentify() | ||
| const processedIdentifyEvent = await processEvent(clone(identifyEvent), getMeta()) | ||
| expect(processedIdentifyEvent).toEqual(identifyEvent) | ||
| expect(fetch).toHaveBeenCalledTimes(0) | ||
| }) | ||
| test('fetches rates if none found', async () => { | ||
| const currencyEvent = createEvent({ event: 'booking completed', properties: { amount: '20', currency: 'PLN' } }) | ||
| await processEvent(clone(currencyEvent), getMeta()) | ||
| expect(fetch).toHaveBeenCalledTimes(1) | ||
| expect(fetch).toHaveBeenCalledWith('https://openexchangerates.org/api/latest.json?app_id=API_KEY') | ||
| await processEvent(clone(currencyEvent), getMeta()) | ||
| expect(fetch).toHaveBeenCalledTimes(1) | ||
| expect(fetch).toHaveBeenCalledWith('https://openexchangerates.org/api/latest.json?app_id=API_KEY') | ||
| }) | ||
| test('normalizes currency on events', async () => { | ||
| const currencyEvent = createEvent({ event: 'booking completed', properties: { amount: '20', currency: 'PLN' } }) | ||
| const processedCurrencyEvent = await processEvent(clone(currencyEvent), getMeta()) | ||
| expect(processedCurrencyEvent).toEqual({ | ||
| ...currencyEvent, | ||
| properties: { ...currencyEvent.properties, normalized_amount: 4.4691, normalized_currency: 'EUR' }, | ||
| }) | ||
| }) | ||
| test('bails if does not know the currency', async () => { | ||
| const currencyEvent = createEvent({ event: 'booking completed', properties: { amount: '20', currency: 'ABC' } }) | ||
| const processedCurrencyEvent = await processEvent(clone(currencyEvent), getMeta()) | ||
| expect(processedCurrencyEvent).toEqual(currencyEvent) | ||
| }) | ||
| test('bails if no API key found', async () => { | ||
| const currencyEvent = createEvent({ event: 'booking completed', properties: { amount: '20', currency: 'USD' } }) | ||
| getMeta().config.openExchangeRatesApiKey = null | ||
| const processedCurrencyEvent = await processEvent(clone(currencyEvent), getMeta()) | ||
| expect(processedCurrencyEvent).toEqual(currencyEvent) | ||
| }) |
| { | ||
| "disclaimer": "Usage subject to terms: https://openexchangerates.org/terms", | ||
| "license": "https://openexchangerates.org/license", | ||
| "timestamp": 1606395600, | ||
| "base": "USD", | ||
| "rates": { | ||
| "AED": 3.673, | ||
| "AFN": 76.932772, | ||
| "ALL": 104.063386, | ||
| "AMD": 481.616228, | ||
| "ANG": 1.795167, | ||
| "AOA": 655.8475, | ||
| "ARS": 80.799783, | ||
| "AUD": 1.358257, | ||
| "AWG": 1.8, | ||
| "AZN": 1.7025, | ||
| "BAM": 1.643361, | ||
| "BBD": 2, | ||
| "BDT": 84.804658, | ||
| "BGN": 1.6442, | ||
| "BHD": 0.377092, | ||
| "BIF": 1937.803155, | ||
| "BMD": 1, | ||
| "BND": 1.33852, | ||
| "BOB": 6.895827, | ||
| "BRL": 5.3516, | ||
| "BSD": 1, | ||
| "BTC": 0.00005771433, | ||
| "BTN": 73.781715, | ||
| "BWP": 11.032736, | ||
| "BYN": 2.569109, | ||
| "BZD": 2.015897, | ||
| "CAD": 1.300744, | ||
| "CDF": 1965.922948, | ||
| "CHF": 0.90882, | ||
| "CLF": 0.027728, | ||
| "CLP": 765.099489, | ||
| "CNH": 6.571982, | ||
| "CNY": 6.575, | ||
| "COP": 3619.874051, | ||
| "CRC": 600.945306, | ||
| "CUC": 1.000134, | ||
| "CUP": 25.75, | ||
| "CVE": 93.15, | ||
| "CZK": 21.976033, | ||
| "DJF": 178.046302, | ||
| "DKK": 6.255944, | ||
| "DOP": 58.176342, | ||
| "DZD": 128.501426, | ||
| "EGP": 15.6966, | ||
| "ERN": 14.999905, | ||
| "ETB": 38.224749, | ||
| "EUR": 0.840622, | ||
| "FJD": 2.0726, | ||
| "FKP": 0.749208, | ||
| "GBP": 0.749208, | ||
| "GEL": 3.31, | ||
| "GGP": 0.749208, | ||
| "GHS": 5.855698, | ||
| "GIP": 0.749208, | ||
| "GMD": 51.775, | ||
| "GNF": 9832.048898, | ||
| "GTQ": 7.79841, | ||
| "GYD": 209.387141, | ||
| "HKD": 7.75079, | ||
| "HNL": 24.261852, | ||
| "HRK": 6.3513, | ||
| "HTG": 65.957793, | ||
| "HUF": 303.669311, | ||
| "IDR": 14148, | ||
| "ILS": 3.321437, | ||
| "IMP": 0.749208, | ||
| "INR": 73.856592, | ||
| "IQD": 1193.946411, | ||
| "IRR": 42105, | ||
| "ISK": 135.6, | ||
| "JEP": 0.749208, | ||
| "JMD": 147.241502, | ||
| "JOD": 0.709, | ||
| "JPY": 104.255, | ||
| "KES": 109.91, | ||
| "KGS": 84.814716, | ||
| "KHR": 4064.007415, | ||
| "KMF": 413.62507, | ||
| "KPW": 900, | ||
| "KRW": 1107.80002, | ||
| "KWD": 0.30598, | ||
| "KYD": 0.833347, | ||
| "KZT": 423.488053, | ||
| "LAK": 9276.379975, | ||
| "LBP": 1512.176085, | ||
| "LKR": 185.12101, | ||
| "LRD": 157.250002, | ||
| "LSL": 15.200788, | ||
| "LYD": 1.353034, | ||
| "MAD": 9.096661, | ||
| "MDL": 17.221924, | ||
| "MGA": 3909.448965, | ||
| "MKD": 51.77122, | ||
| "MMK": 1315.169225, | ||
| "MNT": 2840.535717, | ||
| "MOP": 7.984859, | ||
| "MRO": 357, | ||
| "MRU": 37.08, | ||
| "MUR": 39.853062, | ||
| "MVR": 15.41, | ||
| "MWK": 758.386392, | ||
| "MXN": 20.05165, | ||
| "MYR": 4.0695, | ||
| "MZN": 74.13, | ||
| "NAD": 15.28, | ||
| "NGN": 381.047523, | ||
| "NIO": 34.853884, | ||
| "NOK": 8.887729, | ||
| "NPR": 118.149105, | ||
| "NZD": 1.428869, | ||
| "OMR": 0.38501, | ||
| "PAB": 1, | ||
| "PEN": 3.60445, | ||
| "PGK": 3.51928, | ||
| "PHP": 48.108, | ||
| "PKR": 159.193036, | ||
| "PLN": 3.761938, | ||
| "PYG": 7049.331237, | ||
| "QAR": 3.64125, | ||
| "RON": 4.0975, | ||
| "RSD": 98.83, | ||
| "RUB": 75.695, | ||
| "RWF": 988.816167, | ||
| "SAR": 3.750463, | ||
| "SBD": 8.02131, | ||
| "SCR": 20.810848, | ||
| "SDG": 55.325, | ||
| "SEK": 8.536843, | ||
| "SGD": 1.3387, | ||
| "SHP": 0.749208, | ||
| "SLL": 10167.392806, | ||
| "SOS": 578.587253, | ||
| "SRD": 14.154, | ||
| "SSP": 130.26, | ||
| "STD": 20900.544238, | ||
| "STN": 20.82, | ||
| "SVC": 8.750231, | ||
| "SYP": 513.03575, | ||
| "SZL": 15.198716, | ||
| "THB": 30.282027, | ||
| "TJS": 11.328751, | ||
| "TMT": 3.51, | ||
| "TND": 2.73825, | ||
| "TOP": 2.289464, | ||
| "TRY": 7.894965, | ||
| "TTD": 6.785252, | ||
| "TWD": 28.511214, | ||
| "TZS": 2319.265, | ||
| "UAH": 28.445815, | ||
| "UGX": 3700.397298, | ||
| "USD": 1, | ||
| "UYU": 42.639526, | ||
| "UZS": 10362.208722, | ||
| "VEF": 248487.642241, | ||
| "VES": 916600, | ||
| "VND": 23177.147306, | ||
| "VUV": 111.952965, | ||
| "WST": 2.57281, | ||
| "XAF": 551.412185, | ||
| "XAG": 0.04281743, | ||
| "XAU": 0.00055163, | ||
| "XCD": 2.70255, | ||
| "XDR": 0.701804, | ||
| "XOF": 551.412185, | ||
| "XPD": 0.00042446, | ||
| "XPF": 100.312942, | ||
| "XPT": 0.00104059, | ||
| "YER": 250.349961, | ||
| "ZAR": 15.220557, | ||
| "ZMW": 21.012402, | ||
| "ZWL": 322 | ||
| } | ||
| } |
| { | ||
| "trailingComma": "es5", | ||
| "tabWidth": 4, | ||
| "semi": false, | ||
| "singleQuote": true, | ||
| "printWidth": 120 | ||
| } |
| releases: | ||
| "@posthog/currency-normalization-plugin": patch |
+19
-21
| async function setupPlugin(meta) { | ||
| const apiKey = meta.config['openExchangeRatesApiKey'] || null; | ||
| const apiKey = meta.config['openExchangeRatesApiKey'] || null | ||
| if (apiKey) { | ||
| await fetchRatesIfNeeded(meta); | ||
| await fetchRatesIfNeeded(meta) | ||
| } else { | ||
@@ -19,3 +19,3 @@ throw new Error('No API key found!') | ||
| normalizedCurrencyProperty, | ||
| } = meta.config; | ||
| } = meta.config | ||
@@ -29,13 +29,13 @@ if ( | ||
| ) { | ||
| await fetchRatesIfNeeded(meta); | ||
| const rates = await meta.cache.get('currency_rates'); | ||
| await fetchRatesIfNeeded(meta) | ||
| const rates = await meta.cache.get('currency_rates') | ||
| if (rates) { | ||
| const amount = event.properties[amountProperty]; | ||
| const currency = event.properties[currencyProperty]; | ||
| const amount = event.properties[amountProperty] | ||
| const currency = event.properties[currencyProperty] | ||
| if (rates[currency] && rates[normalizedCurrency]) { | ||
| const normalizedAmount = roundToDigits((amount * rates[normalizedCurrency]) / rates[currency], 4); | ||
| event.properties[normalizedAmountProperty] = normalizedAmount; | ||
| event.properties[normalizedCurrencyProperty] = normalizedCurrency; | ||
| const normalizedAmount = roundToDigits((amount * rates[normalizedCurrency]) / rates[currency], 4) | ||
| event.properties[normalizedAmountProperty] = normalizedAmount | ||
| event.properties[normalizedCurrencyProperty] = normalizedCurrency | ||
| } | ||
@@ -48,3 +48,3 @@ } | ||
| var currencyNormalizationPlugin = { | ||
| module.exports = { | ||
| setupPlugin, | ||
@@ -58,3 +58,3 @@ processEvent, | ||
| } | ||
| }; | ||
| } | ||
@@ -64,6 +64,6 @@ // Internal library functions below | ||
| async function fetchRatesIfNeeded(meta) { | ||
| const currencyRatesFetchedAt = await meta.cache.get('currency_rates_fetched_at'); | ||
| const currencyRatesFetchedAt = await meta.cache.get('currency_rates_fetched_at') | ||
| if (!currencyRatesFetchedAt || currencyRatesFetchedAt < new Date().getTime() - 86400 * 1000) { | ||
| // 24h | ||
| await fetchRates(meta); | ||
| await fetchRates(meta) | ||
| } | ||
@@ -74,9 +74,9 @@ } | ||
| try { | ||
| const url = `https://openexchangerates.org/api/latest.json?app_id=${config['openExchangeRatesApiKey']}`; | ||
| const response = await fetch(url); | ||
| const json = await response.json(); | ||
| const url = `https://openexchangerates.org/api/latest.json?app_id=${config['openExchangeRatesApiKey']}` | ||
| const response = await fetch(url) | ||
| const json = await response.json() | ||
| if (json && json['rates']) { | ||
| cache.set('currency_rates', json['rates']); | ||
| cache.set('currency_rates_fetched_at', new Date().getTime()); | ||
| cache.set('currency_rates', json['rates']) | ||
| cache.set('currency_rates_fetched_at', new Date().getTime()) | ||
| } else { | ||
@@ -93,3 +93,1 @@ throw new Error('Error fetching currency rates!') | ||
| } | ||
| export { currencyNormalizationPlugin as default }; |
+1
-1
| MIT License | ||
| Copyright (c) 2022 PostHog, Inc. | ||
| Copyright (c) 2020 Marius Andra | ||
@@ -5,0 +5,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy |
+1
-1
| { | ||
| "name": "@posthog/currency-normalization-plugin", | ||
| "version": "0.0.2", | ||
| "version": "0.0.3", | ||
| "description": "Convert ingested payment values between currencies", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
23579
47.53%10
66.67%385
208%15
1400%