From 4f791c56822dc9d1645cbe852738056412d5d0e6 Mon Sep 17 00:00:00 2001 From: Valeriy Date: Tue, 28 Jun 2022 23:56:57 +0300 Subject: [PATCH] fix(replaceParams): correctly substitute params with special content (#29) --- src/replace-params.spec.ts | 26 ++++++++++++++++++++++++++ src/replace-params.ts | 28 +++++++++++++++++++--------- 2 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 src/replace-params.spec.ts diff --git a/src/replace-params.spec.ts b/src/replace-params.spec.ts new file mode 100644 index 0000000..86bd1f5 --- /dev/null +++ b/src/replace-params.spec.ts @@ -0,0 +1,26 @@ +import {replaceParams} from './replace-params'; + +describe('replaceParams', () => { + it('should substitute params', () => { + expect(replaceParams('{{test}}', {test: 'text'})).toBe('text'); + expect(replaceParams('{{test}}{{test}}', {test: 'text'})).toBe('texttext'); + expect(replaceParams('some {{test}}', {test: 'text'})).toBe('some text'); + expect(replaceParams('some {{test}} text', {test: 'cool'})).toBe('some cool text'); + expect(replaceParams('{{test}} text', {test: 'cool'})).toBe('cool text'); + expect(replaceParams('some {{test}} text {{test2}} !!', {test: 'cool', test2: 'hey'})).toBe('some cool text hey !!'); + }); + it('should not replace missing params', () => { + expect(replaceParams('{{test}}', {})).toBe('{{test}}'); + expect(replaceParams('some {{test}}', {})).toBe('some {{test}}'); + expect(replaceParams('some {{test}} text', {})).toBe('some {{test}} text'); + expect(replaceParams('{{test}} text', {})).toBe('{{test}} text'); + expect(replaceParams('some {{test}} text {{test2}} !!', {test: 'cool'})).toBe('some cool text {{test2}} !!'); + }) + it('should correctly substitute content with specials', () => { + expect(replaceParams('{{test}}', {test: '$'})).toBe('$'); + expect(replaceParams('{{test}}', {test: '$$'})).toBe('$$'); + expect(replaceParams('{{test1}} {{test2}}', {test1: '{{test2}}', test2: '{{test3}}', test3: 'content'})).toBe( + '{{test2}} {{test3}}', + ); + }); +}); diff --git a/src/replace-params.ts b/src/replace-params.ts index 3e3d95f..d2106e7 100644 --- a/src/replace-params.ts +++ b/src/replace-params.ts @@ -1,18 +1,28 @@ import {Params} from './types'; +const PARAM_REGEXP = /{{(.*?)}}/g; + export function replaceParams(keyValue: string, params: Params): string { - let result = keyValue; + let result = ''; - Object.keys(params).forEach((param) => { - let replacer = params[param]; - if (typeof replacer === 'string' && replacer.indexOf('$') > -1) { - // заменить все одиночные символы '$' на '$$' - replacer = replacer.replace(/(?:([^$])\$|^\$)(?!\$)/g, '$1$$$$'); + let lastIndex = (PARAM_REGEXP.lastIndex = 0); + let match; + while ((match = PARAM_REGEXP.exec(keyValue))) { + if (lastIndex !== match.index) { + result += keyValue.slice(lastIndex, match.index); } + lastIndex = PARAM_REGEXP.lastIndex; - // eslint-disable-next-line security/detect-non-literal-regexp - result = result.replace(new RegExp(`({{${param}}})`, 'g'), replacer) - }); + const [all, key] = match; + if (Object.prototype.hasOwnProperty.call(params, key)) { + result += params[key]; + } else { + result += all; + } + } + if (lastIndex < keyValue.length) { + result += keyValue.slice(lastIndex); + } return result; }