diff --git a/packages/@n8n/expression-runtime/src/extensions/__tests__/string-extensions.test.ts b/packages/@n8n/expression-runtime/src/extensions/__tests__/string-extensions.test.ts index c52bc1c1614..19f6c361fe6 100644 --- a/packages/@n8n/expression-runtime/src/extensions/__tests__/string-extensions.test.ts +++ b/packages/@n8n/expression-runtime/src/extensions/__tests__/string-extensions.test.ts @@ -7,6 +7,8 @@ const extractUrlPath = stringExtensions.functions.extractUrlPath as ( const toSentenceCase = stringExtensions.functions.toSentenceCase as (value: string) => string; +const toFloat = stringExtensions.functions.toFloat as (value: string) => number; + describe('extractUrlPath (imperative parser, no URL constructor)', () => { it.each([ ['https://example.com/path', '/path'], @@ -64,3 +66,17 @@ describe('toSentenceCase', () => { expect(toSentenceCase(input)).toBe(expected); }); }); + +describe('toFloat', () => { + it.each([ + ['R$5.50', 5.5], + ['$5.50', 5.5], + ['5.50 €', 5.5], + ])('should strip the currency symbol from %s', (input, expected) => { + expect(toFloat(input)).toBe(expected); + }); + + it('should not accept a symbol that is not in the list', () => { + expect(() => toFloat('Rb5')).toThrow(); + }); +}); diff --git a/packages/@n8n/expression-runtime/src/extensions/string-extensions.ts b/packages/@n8n/expression-runtime/src/extensions/string-extensions.ts index f026f1b5c9a..1a423680147 100644 --- a/packages/@n8n/expression-runtime/src/extensions/string-extensions.ts +++ b/packages/@n8n/expression-runtime/src/extensions/string-extensions.ts @@ -21,7 +21,7 @@ export const SupportedHashAlgorithms = [ // All symbols from https://www.xe.com/symbols/ as for 2022/11/09 const CURRENCY_REGEXP = - /(\u004c\u0065\u006b|\u060b|\u0024|\u0192|\u20bc|\u0042\u0072|\u0042\u005a\u0024|\u0024\u0062|\u004b\u004d|\u0050|\u043b\u0432|\u0052\u0062|\u17db|\u00a5|\u20a1|\u006b\u006e|\u20b1|\u004b\u010d|\u006b\u0072|\u0052\u0044\u0024|\u00a3|\u20ac|\u00a2|\u0051|\u004c|\u0046\u0074|\u20b9|\u0052\u0070|\ufdfc|\u20aa|\u004a\u0024|\u20a9|\u20ad|\u0434\u0435\u043d|\u0052\u004d|\u20a8|\u20ae|\u004d\u0054|\u0043\u0024|\u20a6|\u0042\u002f\u002e|\u0047\u0073|\u0053\u002f\u002e|\u007a\u0142|\u006c\u0065\u0069|\u20bd|\u0414\u0438\u043d\u002e|\u0053|\u0052|\u0043\u0048\u0046|\u004e\u0054\u0024|\u0e3f|\u0054\u0054\u0024|\u20ba|\u20b4|\u0024\u0055|\u0042\u0073|\u20ab|\u005a\u0024)/gu; + /(\u004c\u0065\u006b|\u060b|\u0024|\u0192|\u20bc|\u0042\u0072|\u0042\u005a\u0024|\u0024\u0062|\u004b\u004d|\u0050|\u043b\u0432|\u0052\u0024|\u17db|\u00a5|\u20a1|\u006b\u006e|\u20b1|\u004b\u010d|\u006b\u0072|\u0052\u0044\u0024|\u00a3|\u20ac|\u00a2|\u0051|\u004c|\u0046\u0074|\u20b9|\u0052\u0070|\ufdfc|\u20aa|\u004a\u0024|\u20a9|\u20ad|\u0434\u0435\u043d|\u0052\u004d|\u20a8|\u20ae|\u004d\u0054|\u0043\u0024|\u20a6|\u0042\u002f\u002e|\u0047\u0073|\u0053\u002f\u002e|\u007a\u0142|\u006c\u0065\u0069|\u20bd|\u0414\u0438\u043d\u002e|\u0053|\u0052|\u0043\u0048\u0046|\u004e\u0054\u0024|\u0e3f|\u0054\u0054\u0024|\u20ba|\u20b4|\u0024\u0055|\u0042\u0073|\u20ab|\u005a\u0024)/gu; const DOMAIN_EXTRACT_REGEXP = /^(?:(?:https?|ftp):\/\/)?(?:mailto:)?(?:\/\/)?((?:www\.)?(?:(?:[-\w]+\.)+(?:[a-zA-Z]{2,}|xn--[a-zA-Z0-9]+)|localhost|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))(?::\d+)?(?:\/[^\s?]*)?(?:\?[^\s#]*)?(?:#[^\s]*)?$/i;