From 153a6a412b081178a452fb6cc3bb1cfe958c136c Mon Sep 17 00:00:00 2001 From: badrAZ Date: Fri, 6 Sep 2019 14:31:58 +0200 Subject: [PATCH 01/20] fix eslint --- packages/xo-web/src/common/cloud-config.js | 2 ++ packages/xo-web/src/common/utils.js | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/xo-web/src/common/cloud-config.js b/packages/xo-web/src/common/cloud-config.js index 9a403ad1c71..743605de754 100644 --- a/packages/xo-web/src/common/cloud-config.js +++ b/packages/xo-web/src/common/cloud-config.js @@ -30,6 +30,7 @@ const showNetworkConfigInfo = () => noCloudDatasourceLink: ( {_('newVmNoCloudDatasource')} @@ -42,6 +43,7 @@ const showNetworkConfigInfo = () => networkConfigDocLink: ( {_('newVmNetworkConfigDoc')} diff --git a/packages/xo-web/src/common/utils.js b/packages/xo-web/src/common/utils.js index 4a26b6da267..0a9ab2e7a7f 100644 --- a/packages/xo-web/src/common/utils.js +++ b/packages/xo-web/src/common/utils.js @@ -256,7 +256,7 @@ export const parseSize = size => { // ------------------------------------------------------------------- -const _NotFound = () =>

{_('errorPageNotFound')}

+const NotFound = () =>

{_('errorPageNotFound')}

// Decorator to declare routes on a component. // @@ -290,7 +290,7 @@ export const routes = (indexRoute, childRoutes) => target => { } if (childRoutes) { - childRoutes.push({ component: _NotFound, path: '*' }) + childRoutes.push({ component: NotFound, path: '*' }) } target.route = { @@ -660,7 +660,7 @@ export const adminOnly = Component => connectStore({ _isAdmin: isAdmin, })(({ _isAdmin, ...props }) => - _isAdmin ? : <_NotFound /> + _isAdmin ? : ) // =================================================================== From 2abe1a1b776b52069ec1dbf598a4ade717a61e20 Mon Sep 17 00:00:00 2001 From: badrAZ Date: Fri, 6 Sep 2019 15:00:56 +0200 Subject: [PATCH 02/20] ability to respace template vars --- packages/xo-web/src/common/cloud-config.js | 2 ++ packages/xo-web/src/common/intl/messages.js | 3 +++ packages/xo-web/src/common/utils.js | 17 ++++++++++++----- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/packages/xo-web/src/common/cloud-config.js b/packages/xo-web/src/common/cloud-config.js index 743605de754..35dd25a47a8 100644 --- a/packages/xo-web/src/common/cloud-config.js +++ b/packages/xo-web/src/common/cloud-config.js @@ -9,6 +9,8 @@ import { alert } from './modal' const AVAILABLE_TEMPLATE_VARS = { '{name}': 'templateNameInfo', '%': 'templateIndexInfo', + '\\': 'templateEscape', + '\\\\': 'templateAntiSlash', } const showAvailableTemplateVars = () => diff --git a/packages/xo-web/src/common/intl/messages.js b/packages/xo-web/src/common/intl/messages.js index 752c371627d..f4950eff21e 100644 --- a/packages/xo-web/src/common/intl/messages.js +++ b/packages/xo-web/src/common/intl/messages.js @@ -1324,6 +1324,9 @@ const messages = { availableTemplateVarsTitle: 'Available template variables', templateNameInfo: 'the VM\'s name. It must not contain "_"', templateIndexInfo: "the VM's index, it will take 0 in case of single VM", + templateAntiSlash: 'will be replaced by "\\"', + templateEscape: + 'used to escape the template syntaxes, e.g: "\\%" will be replaced by "%" instead of the VM\'s index', coreOsDefaultTemplateError: 'Error on getting the default coreOS cloud template', newVmBootAfterCreate: 'Boot VM after creation', diff --git a/packages/xo-web/src/common/utils.js b/packages/xo-web/src/common/utils.js index 0a9ab2e7a7f..dfafdadc652 100644 --- a/packages/xo-web/src/common/utils.js +++ b/packages/xo-web/src/common/utils.js @@ -14,8 +14,6 @@ import { isFunction, isPlainObject, isString, - join, - keys, map, mapValues, pick, @@ -360,7 +358,7 @@ export const resolveResourceSets = resourceSets => // Creates a string replacer based on a pattern and a list of rules // // ```js -// const myReplacer = buildTemplate('{name}_COPY_{name}_{id}_%', { +// const myReplacer = buildTemplate('{name}_COPY_\{name}_{id}_%\%', { // '{name}': vm => vm.name_label, // '{id}': vm => vm.id, // '%': (_, i) => i @@ -371,13 +369,22 @@ export const resolveResourceSets = resourceSets => // id: 42, // }, 32) // -// newString === 'foo_COPY_foo_42_32' +// newString === 'foo_COPY_foo_42_32%' // ``` export function buildTemplate(pattern, rules) { - const regExp = new RegExp(join(map(keys(rules), escapeRegExp), '|'), 'g') + const syntaxesToReplace = [] + Object.keys(rules).forEach(syntax => + syntaxesToReplace.push(escapeRegExp(syntax), escapeRegExp(`\\${syntax}`)) + ) + syntaxesToReplace.push(escapeRegExp('\\\\')) + + const regExp = new RegExp(syntaxesToReplace.join('|'), 'g') return (...params) => replace(pattern, regExp, match => { const rule = rules[match] + if (rule === undefined) { + return match.slice(1) + } return isFunction(rule) ? rule(...params) : rule }) } From fb76fd1fb0b340ec35f703c7f837046452b3af77 Mon Sep 17 00:00:00 2001 From: badrAZ Date: Fri, 6 Sep 2019 15:12:38 +0200 Subject: [PATCH 03/20] update message --- packages/xo-web/src/common/intl/messages.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/xo-web/src/common/intl/messages.js b/packages/xo-web/src/common/intl/messages.js index f4950eff21e..f0ebda30b93 100644 --- a/packages/xo-web/src/common/intl/messages.js +++ b/packages/xo-web/src/common/intl/messages.js @@ -1326,7 +1326,7 @@ const messages = { templateIndexInfo: "the VM's index, it will take 0 in case of single VM", templateAntiSlash: 'will be replaced by "\\"', templateEscape: - 'used to escape the template syntaxes, e.g: "\\%" will be replaced by "%" instead of the VM\'s index', + 'used to escape the template variables, e.g: "\\%" will be replaced by "%" instead of the VM\'s index', coreOsDefaultTemplateError: 'Error on getting the default coreOS cloud template', newVmBootAfterCreate: 'Boot VM after creation', From 3ba0c552150d0ad654306d60bbb32d2bec8047f2 Mon Sep 17 00:00:00 2001 From: badrAZ Date: Fri, 6 Sep 2019 15:17:06 +0200 Subject: [PATCH 04/20] CHANGELOG --- CHANGELOG.unreleased.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 6585b99726c..cd1fe5ddacc 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -23,6 +23,7 @@ - [Network] Fix inability to set a network name [#4514](https://github.com/vatesfr/xen-orchestra/issues/4514) (PR [4510](https://github.com/vatesfr/xen-orchestra/pull/4510)) - [Backup NG] Fix race conditions that could lead to disabled jobs still running (PR [4510](https://github.com/vatesfr/xen-orchestra/pull/4510)) - [XOA] Remove "Updates" and "Licenses" tabs for non admin users (PR [#4526](https://github.com/vatesfr/xen-orchestra/pull/4526)) +- [New VM] Ability to escape cloud config template variables [#4486](https://github.com/vatesfr/xen-orchestra/issues/4486) (PR [#4501](https://github.com/vatesfr/xen-orchestra/pull/4501)) ### Released packages From df564ce0b77972847eba0799853f3724c3edf54f Mon Sep 17 00:00:00 2001 From: badrAZ Date: Thu, 12 Sep 2019 11:42:23 +0200 Subject: [PATCH 05/20] comment --- packages/xo-web/src/common/utils.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/xo-web/src/common/utils.js b/packages/xo-web/src/common/utils.js index dfafdadc652..4c1c29cceca 100644 --- a/packages/xo-web/src/common/utils.js +++ b/packages/xo-web/src/common/utils.js @@ -382,6 +382,7 @@ export function buildTemplate(pattern, rules) { return (...params) => replace(pattern, regExp, match => { const rule = rules[match] + // delete the backslash in case of escaped syntax if (rule === undefined) { return match.slice(1) } From 44c15793993c6049520ec8756f94255a54349ca3 Mon Sep 17 00:00:00 2001 From: badrAZ Date: Thu, 12 Sep 2019 11:44:15 +0200 Subject: [PATCH 06/20] comment --- packages/xo-web/src/common/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/xo-web/src/common/utils.js b/packages/xo-web/src/common/utils.js index 4c1c29cceca..bccd17d901d 100644 --- a/packages/xo-web/src/common/utils.js +++ b/packages/xo-web/src/common/utils.js @@ -382,7 +382,7 @@ export function buildTemplate(pattern, rules) { return (...params) => replace(pattern, regExp, match => { const rule = rules[match] - // delete the backslash in case of escaped syntax + // delete the backslash in case of escape syntax if (rule === undefined) { return match.slice(1) } From 661c95eb6165a4042e64c8213319d8c2a035391f Mon Sep 17 00:00:00 2001 From: badrAZ Date: Fri, 13 Sep 2019 16:24:06 +0200 Subject: [PATCH 07/20] revert eslint changes --- packages/xo-web/src/common/cloud-config.js | 2 -- packages/xo-web/src/common/utils.js | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/xo-web/src/common/cloud-config.js b/packages/xo-web/src/common/cloud-config.js index 35dd25a47a8..6f6ac26abdb 100644 --- a/packages/xo-web/src/common/cloud-config.js +++ b/packages/xo-web/src/common/cloud-config.js @@ -32,7 +32,6 @@ const showNetworkConfigInfo = () => noCloudDatasourceLink: (
{_('newVmNoCloudDatasource')} @@ -45,7 +44,6 @@ const showNetworkConfigInfo = () => networkConfigDocLink: ( {_('newVmNetworkConfigDoc')} diff --git a/packages/xo-web/src/common/utils.js b/packages/xo-web/src/common/utils.js index bccd17d901d..d4ff02162ae 100644 --- a/packages/xo-web/src/common/utils.js +++ b/packages/xo-web/src/common/utils.js @@ -254,7 +254,7 @@ export const parseSize = size => { // ------------------------------------------------------------------- -const NotFound = () =>

{_('errorPageNotFound')}

+const _NotFound = () =>

{_('errorPageNotFound')}

// Decorator to declare routes on a component. // @@ -288,7 +288,7 @@ export const routes = (indexRoute, childRoutes) => target => { } if (childRoutes) { - childRoutes.push({ component: NotFound, path: '*' }) + childRoutes.push({ component: _NotFound, path: '*' }) } target.route = { @@ -668,7 +668,7 @@ export const adminOnly = Component => connectStore({ _isAdmin: isAdmin, })(({ _isAdmin, ...props }) => - _isAdmin ? : + _isAdmin ? : <_NotFound /> ) // =================================================================== From 69eca1ea5970d6d85cbdacd2f880130d9393be99 Mon Sep 17 00:00:00 2001 From: badrAZ Date: Fri, 13 Sep 2019 17:24:26 +0200 Subject: [PATCH 08/20] better implementation --- packages/xo-web/src/common/cloud-config.js | 18 +++++++++------- packages/xo-web/src/common/intl/messages.js | 5 ++--- packages/xo-web/src/common/utils.js | 23 +++++++++++---------- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/packages/xo-web/src/common/cloud-config.js b/packages/xo-web/src/common/cloud-config.js index 6f6ac26abdb..823e297a194 100644 --- a/packages/xo-web/src/common/cloud-config.js +++ b/packages/xo-web/src/common/cloud-config.js @@ -9,18 +9,22 @@ import { alert } from './modal' const AVAILABLE_TEMPLATE_VARS = { '{name}': 'templateNameInfo', '%': 'templateIndexInfo', - '\\': 'templateEscape', - '\\\\': 'templateAntiSlash', + '\\\\': 'templateBackslash', } const showAvailableTemplateVars = () => alert( _('availableTemplateVarsTitle'), -
    - {map(AVAILABLE_TEMPLATE_VARS, (value, key) => ( -
  • {_.keyValue(key, _(value))}
  • - ))} -
+
+
    + {map(AVAILABLE_TEMPLATE_VARS, (value, key) => ( +
  • {_.keyValue(key, _(value))}
  • + ))} +
+ + {_('templateEscape')} + +
) const showNetworkConfigInfo = () => diff --git a/packages/xo-web/src/common/intl/messages.js b/packages/xo-web/src/common/intl/messages.js index f0ebda30b93..f4ec1d5cdb1 100644 --- a/packages/xo-web/src/common/intl/messages.js +++ b/packages/xo-web/src/common/intl/messages.js @@ -1324,9 +1324,8 @@ const messages = { availableTemplateVarsTitle: 'Available template variables', templateNameInfo: 'the VM\'s name. It must not contain "_"', templateIndexInfo: "the VM's index, it will take 0 in case of single VM", - templateAntiSlash: 'will be replaced by "\\"', - templateEscape: - 'used to escape the template variables, e.g: "\\%" will be replaced by "%" instead of the VM\'s index', + templateBackslash: 'will be replaced by "\\"', + templateEscape: 'Tip: escape any variable with a preceding backslash (\\)', coreOsDefaultTemplateError: 'Error on getting the default coreOS cloud template', newVmBootAfterCreate: 'Boot VM after creation', diff --git a/packages/xo-web/src/common/utils.js b/packages/xo-web/src/common/utils.js index d4ff02162ae..51ccb348f9a 100644 --- a/packages/xo-web/src/common/utils.js +++ b/packages/xo-web/src/common/utils.js @@ -372,20 +372,21 @@ export const resolveResourceSets = resourceSets => // newString === 'foo_COPY_foo_42_32%' // ``` export function buildTemplate(pattern, rules) { - const syntaxesToReplace = [] - Object.keys(rules).forEach(syntax => - syntaxesToReplace.push(escapeRegExp(syntax), escapeRegExp(`\\${syntax}`)) + const rulesWithEscapes = { ...rules, '\\\\': '\\' } + const regExp = new RegExp( + [ + ...Object.keys(rules).map(syntax => { + const syntaxWithBackslash = `\\${syntax}` + rulesWithEscapes[syntaxWithBackslash] = syntax + return `${escapeRegExp(syntax)}|${escapeRegExp(syntaxWithBackslash)}` + }), + escapeRegExp('\\\\'), + ].join('|'), + 'g' ) - syntaxesToReplace.push(escapeRegExp('\\\\')) - - const regExp = new RegExp(syntaxesToReplace.join('|'), 'g') return (...params) => replace(pattern, regExp, match => { - const rule = rules[match] - // delete the backslash in case of escape syntax - if (rule === undefined) { - return match.slice(1) - } + const rule = rulesWithEscapes[match] return isFunction(rule) ? rule(...params) : rule }) } From e805c75d71ff66e10211b21701d71ab8591a5fa2 Mon Sep 17 00:00:00 2001 From: badrAZ Date: Mon, 16 Sep 2019 10:30:32 +0200 Subject: [PATCH 09/20] improvements --- packages/xo-web/src/common/utils.js | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/packages/xo-web/src/common/utils.js b/packages/xo-web/src/common/utils.js index 51ccb348f9a..1c0bd77fcb6 100644 --- a/packages/xo-web/src/common/utils.js +++ b/packages/xo-web/src/common/utils.js @@ -9,6 +9,7 @@ import { escapeRegExp, every, forEach, + forOwn, isArray, isEmpty, isFunction, @@ -372,21 +373,18 @@ export const resolveResourceSets = resourceSets => // newString === 'foo_COPY_foo_42_32%' // ``` export function buildTemplate(pattern, rules) { - const rulesWithEscapes = { ...rules, '\\\\': '\\' } - const regExp = new RegExp( - [ - ...Object.keys(rules).map(syntax => { - const syntaxWithBackslash = `\\${syntax}` - rulesWithEscapes[syntaxWithBackslash] = syntax - return `${escapeRegExp(syntax)}|${escapeRegExp(syntaxWithBackslash)}` - }), - escapeRegExp('\\\\'), - ].join('|'), - 'g' - ) + const rulesWithTheirEscape = { '\\\\': '\\' } + const escapedSyntaxes = [escapeRegExp('\\\\')] + forOwn(rules, (rule, syntax) => { + rulesWithTheirEscape[syntax] = rule + rulesWithTheirEscape[`\\${syntax}`] = syntax + + escapedSyntaxes.push(escapeRegExp(syntax), escapeRegExp(`\\${syntax}`)) + }) + const regExp = new RegExp(escapedSyntaxes.join('|'), 'g') return (...params) => replace(pattern, regExp, match => { - const rule = rulesWithEscapes[match] + const rule = rulesWithTheirEscape[match] return isFunction(rule) ? rule(...params) : rule }) } From a02fa0b3864f78347345b5e8fd55ce7cf699a0ce Mon Sep 17 00:00:00 2001 From: badrAZ Date: Mon, 16 Sep 2019 16:01:19 +0200 Subject: [PATCH 10/20] improvements --- packages/xo-web/src/common/cloud-config.js | 1 - packages/xo-web/src/common/intl/messages.js | 1 - packages/xo-web/src/common/utils.js | 19 +++++++++---------- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/packages/xo-web/src/common/cloud-config.js b/packages/xo-web/src/common/cloud-config.js index 823e297a194..38ae92998f0 100644 --- a/packages/xo-web/src/common/cloud-config.js +++ b/packages/xo-web/src/common/cloud-config.js @@ -9,7 +9,6 @@ import { alert } from './modal' const AVAILABLE_TEMPLATE_VARS = { '{name}': 'templateNameInfo', '%': 'templateIndexInfo', - '\\\\': 'templateBackslash', } const showAvailableTemplateVars = () => diff --git a/packages/xo-web/src/common/intl/messages.js b/packages/xo-web/src/common/intl/messages.js index f4ec1d5cdb1..72526feb08f 100644 --- a/packages/xo-web/src/common/intl/messages.js +++ b/packages/xo-web/src/common/intl/messages.js @@ -1324,7 +1324,6 @@ const messages = { availableTemplateVarsTitle: 'Available template variables', templateNameInfo: 'the VM\'s name. It must not contain "_"', templateIndexInfo: "the VM's index, it will take 0 in case of single VM", - templateBackslash: 'will be replaced by "\\"', templateEscape: 'Tip: escape any variable with a preceding backslash (\\)', coreOsDefaultTemplateError: 'Error on getting the default coreOS cloud template', diff --git a/packages/xo-web/src/common/utils.js b/packages/xo-web/src/common/utils.js index 1c0bd77fcb6..1d1c1e92ea7 100644 --- a/packages/xo-web/src/common/utils.js +++ b/packages/xo-web/src/common/utils.js @@ -370,21 +370,20 @@ export const resolveResourceSets = resourceSets => // id: 42, // }, 32) // -// newString === 'foo_COPY_foo_42_32%' +// newString === 'foo_COPY_{name}_42_32%' // ``` export function buildTemplate(pattern, rules) { - const rulesWithTheirEscape = { '\\\\': '\\' } - const escapedSyntaxes = [escapeRegExp('\\\\')] - forOwn(rules, (rule, syntax) => { - rulesWithTheirEscape[syntax] = rule - rulesWithTheirEscape[`\\${syntax}`] = syntax - - escapedSyntaxes.push(escapeRegExp(syntax), escapeRegExp(`\\${syntax}`)) + const transforms = { '\\\\': '\\' } + const matches = ['\\\\'] + forOwn(rules, (output, input) => { + transforms[input] = output + transforms[`\\${input}`] = input + matches.push(input, `\\${input}`) }) - const regExp = new RegExp(escapedSyntaxes.join('|'), 'g') + const regExp = new RegExp(matches.map(escapeRegExp).join('|'), 'g') return (...params) => replace(pattern, regExp, match => { - const rule = rulesWithTheirEscape[match] + const rule = transforms[match] return isFunction(rule) ? rule(...params) : rule }) } From 214bfc7fdede81e725cd55fce50feedd0d19b2dc Mon Sep 17 00:00:00 2001 From: badrAZ Date: Wed, 18 Sep 2019 11:57:09 +0200 Subject: [PATCH 11/20] improvements --- @xen-orchestra/build-template/.babelrc.js | 3 + @xen-orchestra/build-template/README.md | 65 +++++++++++++++++++ @xen-orchestra/build-template/package.json | 48 ++++++++++++++ @xen-orchestra/build-template/src/index.js | 21 ++++++ .../build-template/src/index.spec.js | 11 ++++ packages/xo-web/package.json | 1 + packages/xo-web/src/common/cloud-config.js | 4 +- packages/xo-web/src/common/utils.js | 37 ----------- packages/xo-web/src/xo-app/new-vm/index.js | 2 +- 9 files changed, 152 insertions(+), 40 deletions(-) create mode 100644 @xen-orchestra/build-template/.babelrc.js create mode 100644 @xen-orchestra/build-template/README.md create mode 100644 @xen-orchestra/build-template/package.json create mode 100644 @xen-orchestra/build-template/src/index.js create mode 100644 @xen-orchestra/build-template/src/index.spec.js diff --git a/@xen-orchestra/build-template/.babelrc.js b/@xen-orchestra/build-template/.babelrc.js new file mode 100644 index 00000000000..4e27ec1353f --- /dev/null +++ b/@xen-orchestra/build-template/.babelrc.js @@ -0,0 +1,3 @@ +module.exports = require('../../@xen-orchestra/babel-config')( + require('./package.json') +) diff --git a/@xen-orchestra/build-template/README.md b/@xen-orchestra/build-template/README.md new file mode 100644 index 00000000000..d9ee0212f4d --- /dev/null +++ b/@xen-orchestra/build-template/README.md @@ -0,0 +1,65 @@ +# ${pkg.name} [![Build Status](https://travis-ci.org/${pkg.shortGitHubPath}.png?branch=master)](https://travis-ci.org/${pkg.shortGitHubPath}) + +> ${pkg.description} + +## Install + +Installation of the [npm package](https://npmjs.org/package/${pkg.name}): + +``` +> npm install --save ${pkg.name} +``` + +## Usage + + +Creates a string replacer based on a pattern and a list of rules + +```js +const myReplacer = buildTemplate('{name}_COPY_\{name}_{id}_%\%', { + '{name}': vm => vm.name_label, + '{id}': vm => vm.id, + '%': (_, i) => i +}) + +const newString = myReplacer({ + name_label: 'foo', + id: 42, +}, 32) + +newString === 'foo_COPY_{name}_42_32%' // true +``` + +## Development + +``` +# Install dependencies +> yarn + +# Run the tests +> yarn test + +# Continuously compile +> yarn dev + +# Continuously run the tests +> yarn dev-test + +# Build for production (automatically called by npm install) +> yarn build +``` + +## Contributions + +Contributions are *very* welcomed, either on the documentation or on +the code. + +You may: + +- report any [issue](${pkg.bugs}) + you've encountered; +- fork and create a pull request. + +## License + +${pkg.license} © [${pkg.author.name}](${pkg.author.url}) diff --git a/@xen-orchestra/build-template/package.json b/@xen-orchestra/build-template/package.json new file mode 100644 index 00000000000..8052fedc01d --- /dev/null +++ b/@xen-orchestra/build-template/package.json @@ -0,0 +1,48 @@ +{ + "name": "@xen-orchestra/build-template", + "version": "0.0.0", + "license": "ISC", + "homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/build-template", + "bugs": "https://github.com/vatesfr/xen-orchestra/issues", + "repository": { + "directory": "@xen-orchestra/build-template", + "type": "git", + "url": "https://github.com/vatesfr/xen-orchestra.git" + }, + "author": { + "name": "Julien Fontanet", + "email": "julien.fontanet@vates.fr" + }, + "preferGlobal": false, + "main": "dist/", + "files": [ + "dist/" + ], + "browserslist": [ + ">2%" + ], + "engines": { + "node": ">=6" + }, + "devDependencies": { + "@babel/cli": "^7.0.0", + "@babel/core": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "@babel/preset-flow": "^7.0.0", + "babel-plugin-lodash": "^3.3.2", + "cross-env": "^5.1.3", + "rimraf": "^3.0.0" + }, + "scripts": { + "build": "cross-env NODE_ENV=production babel --source-maps --out-dir=dist/ src/", + "clean": "rimraf dist/", + "dev": "cross-env NODE_ENV=development babel --watch --source-maps --out-dir=dist/ src/", + "prebuild": "yarn run clean", + "predev": "yarn run prebuild", + "prepublishOnly": "yarn run build", + "postversion": "npm publish" + }, + "dependencies": { + "lodash": "^4.17.15" + } +} diff --git a/@xen-orchestra/build-template/src/index.js b/@xen-orchestra/build-template/src/index.js new file mode 100644 index 00000000000..86f12120cbd --- /dev/null +++ b/@xen-orchestra/build-template/src/index.js @@ -0,0 +1,21 @@ +import { escapeRegExp } from 'lodash' + +const compareLengthDesc = (a, b) => b.length - a.length + +export default (pattern, rules) => { + const keys = Object.keys(rules) + keys.push('\\') + const matches = keys + .sort(compareLengthDesc) + .map(escapeRegExp) + .join('|') + const regExp = new RegExp(`\\\\(?:${matches})|${matches}`, 'g') + return (...params) => + pattern.replace(regExp, match => { + if (match[0] === '\\') { + return match.slice(1) + } + const rule = rules[match] + return typeof rule === 'function' ? rule(...params) : rule + }) +} diff --git a/@xen-orchestra/build-template/src/index.spec.js b/@xen-orchestra/build-template/src/index.spec.js new file mode 100644 index 00000000000..e00af028e6d --- /dev/null +++ b/@xen-orchestra/build-template/src/index.spec.js @@ -0,0 +1,11 @@ +/* eslint-env jest */ +import buildTemplate from '.' + +it('builds a template', () => { + const replacer = buildTemplate('{name}_\\{name}_\\\\{name}_{id}_%_FOO', { + '{name}': obj => obj.name, + '{id}': 1235, + '%': (_, i) => i, + }) + expect(replacer({ name: 'toto' }, 5)).toBe('toto_{name}_\\toto_1235_5_FOO') +}) diff --git a/packages/xo-web/package.json b/packages/xo-web/package.json index 39e607a9797..924b8929e61 100644 --- a/packages/xo-web/package.json +++ b/packages/xo-web/package.json @@ -34,6 +34,7 @@ "@nraynaud/novnc": "0.6.1", "@xen-orchestra/cron": "^1.0.3", "@xen-orchestra/defined": "^0.0.0", + "@xen-orchestra/build-template": "^0.0.0", "ansi_up": "^4.0.3", "asap": "^2.0.6", "babel-core": "^6.26.0", diff --git a/packages/xo-web/src/common/cloud-config.js b/packages/xo-web/src/common/cloud-config.js index 38ae92998f0..0b0954234ac 100644 --- a/packages/xo-web/src/common/cloud-config.js +++ b/packages/xo-web/src/common/cloud-config.js @@ -20,9 +20,9 @@ const showAvailableTemplateVars = () =>
  • {_.keyValue(key, _(value))}
  • ))} - +
    {_('templateEscape')} - +
    ) diff --git a/packages/xo-web/src/common/utils.js b/packages/xo-web/src/common/utils.js index 1d1c1e92ea7..2b9d47abed6 100644 --- a/packages/xo-web/src/common/utils.js +++ b/packages/xo-web/src/common/utils.js @@ -6,10 +6,8 @@ import { connect } from 'react-redux' import { FormattedDate } from 'react-intl' import { clone, - escapeRegExp, every, forEach, - forOwn, isArray, isEmpty, isFunction, @@ -18,7 +16,6 @@ import { map, mapValues, pick, - replace, sample, some, } from 'lodash' @@ -354,40 +351,6 @@ export const resolveResourceSet = resourceSet => { export const resolveResourceSets = resourceSets => map(resourceSets, resolveResourceSet) -// ------------------------------------------------------------------- - -// Creates a string replacer based on a pattern and a list of rules -// -// ```js -// const myReplacer = buildTemplate('{name}_COPY_\{name}_{id}_%\%', { -// '{name}': vm => vm.name_label, -// '{id}': vm => vm.id, -// '%': (_, i) => i -// }) -// -// const newString = myReplacer({ -// name_label: 'foo', -// id: 42, -// }, 32) -// -// newString === 'foo_COPY_{name}_42_32%' -// ``` -export function buildTemplate(pattern, rules) { - const transforms = { '\\\\': '\\' } - const matches = ['\\\\'] - forOwn(rules, (output, input) => { - transforms[input] = output - transforms[`\\${input}`] = input - matches.push(input, `\\${input}`) - }) - const regExp = new RegExp(matches.map(escapeRegExp).join('|'), 'g') - return (...params) => - replace(pattern, regExp, match => { - const rule = transforms[match] - return isFunction(rule) ? rule(...params) : rule - }) -} - // =================================================================== export const streamToString = getStream diff --git a/packages/xo-web/src/xo-app/new-vm/index.js b/packages/xo-web/src/xo-app/new-vm/index.js index 56e4f5a0ae2..2588cc205f2 100644 --- a/packages/xo-web/src/xo-app/new-vm/index.js +++ b/packages/xo-web/src/xo-app/new-vm/index.js @@ -1,6 +1,7 @@ import _, { messages } from 'intl' import ActionButton from 'action-button' import BaseComponent from 'base-component' +import buildTemplate from '@xen-orchestra/build-template' import Button from 'button' import classNames from 'classnames' import defined, { get } from '@xen-orchestra/defined' @@ -78,7 +79,6 @@ import { import { SizeInput, Toggle } from 'form' import { addSubscriptions, - buildTemplate, connectStore, formatSize, getCoresPerSocketPossibilities, From 963c190fa08918ff25574ac30450e7ae2bd0cbd2 Mon Sep 17 00:00:00 2001 From: badrAZ Date: Wed, 18 Sep 2019 12:03:59 +0200 Subject: [PATCH 12/20] update README --- @xen-orchestra/build-template/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/@xen-orchestra/build-template/README.md b/@xen-orchestra/build-template/README.md index d9ee0212f4d..90939b51fcf 100644 --- a/@xen-orchestra/build-template/README.md +++ b/@xen-orchestra/build-template/README.md @@ -12,8 +12,7 @@ Installation of the [npm package](https://npmjs.org/package/${pkg.name}): ## Usage - -Creates a string replacer based on a pattern and a list of rules +Create a string replacer based on a pattern and a list of rules. ```js const myReplacer = buildTemplate('{name}_COPY_\{name}_{id}_%\%', { From c154000d620ff7463e696c4782de583fd531dd68 Mon Sep 17 00:00:00 2001 From: badrAZ Date: Wed, 18 Sep 2019 13:44:40 +0200 Subject: [PATCH 13/20] CHANGELOG --- CHANGELOG.unreleased.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index cd1fe5ddacc..a4cf0e32c78 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -32,6 +32,7 @@ > > Rule of thumb: add packages on top. +- @xen-orchestra/template v0.0.0 - @xen-orchestra/cron v1.0.4 - xo-server-sdn-controller v0.3.0 - xo-server v5.50.0 From 0b374a102fadfd449f54bed4d312e695c1cf18cd Mon Sep 17 00:00:00 2001 From: badrAZ Date: Wed, 18 Sep 2019 14:50:19 +0200 Subject: [PATCH 14/20] fixes --- @xen-orchestra/build-template/src/index.spec.js | 17 +++++++++++------ .../src/common/xo/copy-vms-modal/index.js | 3 ++- .../src/common/xo/snapshot-vm-modal/index.js | 3 ++- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/@xen-orchestra/build-template/src/index.spec.js b/@xen-orchestra/build-template/src/index.spec.js index e00af028e6d..221ba50a31a 100644 --- a/@xen-orchestra/build-template/src/index.spec.js +++ b/@xen-orchestra/build-template/src/index.spec.js @@ -2,10 +2,15 @@ import buildTemplate from '.' it('builds a template', () => { - const replacer = buildTemplate('{name}_\\{name}_\\\\{name}_{id}_%_FOO', { - '{name}': obj => obj.name, - '{id}': 1235, - '%': (_, i) => i, - }) - expect(replacer({ name: 'toto' }, 5)).toBe('toto_{name}_\\toto_1235_5_FOO') + const replacer = buildTemplate( + '{property}_\\{property}_\\\\{property}_{constant}_%_FOO', + { + '{property}': obj => obj.name, + '{constant}': 1235, + '%': (_, i) => i, + } + ) + expect(replacer({ name: 'toto' }, 5)).toBe( + 'toto_{property}_\\toto_1235_5_FOO' + ) }) diff --git a/packages/xo-web/src/common/xo/copy-vms-modal/index.js b/packages/xo-web/src/common/xo/copy-vms-modal/index.js index 67402af1f4a..5027a73d976 100644 --- a/packages/xo-web/src/common/xo/copy-vms-modal/index.js +++ b/packages/xo-web/src/common/xo/copy-vms-modal/index.js @@ -1,4 +1,5 @@ import _, { messages } from 'intl' +import buildTemplate from '@xen-orchestra/build-template' import map from 'lodash/map' import React from 'react' import { injectIntl } from 'react-intl' @@ -8,7 +9,7 @@ import SingleLineRow from 'single-line-row' import Upgrade from 'xoa-upgrade' import { Col } from 'grid' import { SelectSr } from 'select-objects' -import { buildTemplate, connectStore } from 'utils' +import { connectStore } from 'utils' import SelectCompression from '../../select-compression' import ZstdChecker from '../../zstd-checker' diff --git a/packages/xo-web/src/common/xo/snapshot-vm-modal/index.js b/packages/xo-web/src/common/xo/snapshot-vm-modal/index.js index b26fb5ae392..2370b2fbf5e 100644 --- a/packages/xo-web/src/common/xo/snapshot-vm-modal/index.js +++ b/packages/xo-web/src/common/xo/snapshot-vm-modal/index.js @@ -1,9 +1,10 @@ import _ from 'intl' import React from 'react' import BaseComponent from 'base-component' +import buildTemplate from '@xen-orchestra/build-template' import { forEach } from 'lodash' import { createGetObjectsOfType } from 'selectors' -import { buildTemplate, connectStore } from 'utils' +import { connectStore } from 'utils' import { Container, Col, Row } from 'grid' const RULES = { From d4c1d0194d6144aa48e1f1e9e81b7b296168cbae Mon Sep 17 00:00:00 2001 From: badrAZ Date: Wed, 18 Sep 2019 16:18:57 +0200 Subject: [PATCH 15/20] toto -> bar --- @xen-orchestra/build-template/src/index.spec.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/@xen-orchestra/build-template/src/index.spec.js b/@xen-orchestra/build-template/src/index.spec.js index 221ba50a31a..f8dea4c64b6 100644 --- a/@xen-orchestra/build-template/src/index.spec.js +++ b/@xen-orchestra/build-template/src/index.spec.js @@ -10,7 +10,5 @@ it('builds a template', () => { '%': (_, i) => i, } ) - expect(replacer({ name: 'toto' }, 5)).toBe( - 'toto_{property}_\\toto_1235_5_FOO' - ) + expect(replacer({ name: 'bar' }, 5)).toBe('bar_{property}_\\bar_1235_5_FOO') }) From ad453055920963e0ad3659c9206effa1627faa6b Mon Sep 17 00:00:00 2001 From: badrAZ Date: Wed, 18 Sep 2019 16:20:53 +0200 Subject: [PATCH 16/20] test name --- @xen-orchestra/build-template/src/index.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/@xen-orchestra/build-template/src/index.spec.js b/@xen-orchestra/build-template/src/index.spec.js index f8dea4c64b6..006b4ceedd1 100644 --- a/@xen-orchestra/build-template/src/index.spec.js +++ b/@xen-orchestra/build-template/src/index.spec.js @@ -1,7 +1,7 @@ /* eslint-env jest */ import buildTemplate from '.' -it('builds a template', () => { +it("correctly replaces the template's variables", () => { const replacer = buildTemplate( '{property}_\\{property}_\\\\{property}_{constant}_%_FOO', { From e347cc870d6d9b6441a84357a537431ca64b1df1 Mon Sep 17 00:00:00 2001 From: badrAZ Date: Wed, 18 Sep 2019 16:41:00 +0200 Subject: [PATCH 17/20] CHANGELOG --- CHANGELOG.unreleased.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index a4cf0e32c78..fd24ecb70ec 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -23,7 +23,7 @@ - [Network] Fix inability to set a network name [#4514](https://github.com/vatesfr/xen-orchestra/issues/4514) (PR [4510](https://github.com/vatesfr/xen-orchestra/pull/4510)) - [Backup NG] Fix race conditions that could lead to disabled jobs still running (PR [4510](https://github.com/vatesfr/xen-orchestra/pull/4510)) - [XOA] Remove "Updates" and "Licenses" tabs for non admin users (PR [#4526](https://github.com/vatesfr/xen-orchestra/pull/4526)) -- [New VM] Ability to escape cloud config template variables [#4486](https://github.com/vatesfr/xen-orchestra/issues/4486) (PR [#4501](https://github.com/vatesfr/xen-orchestra/pull/4501)) +- [New VM] Ability to escape [cloud config template](https://xen-orchestra.com/blog/xen-orchestra-5-21/#cloudconfigtemplates) variables [#4486](https://github.com/vatesfr/xen-orchestra/issues/4486) (PR [#4501](https://github.com/vatesfr/xen-orchestra/pull/4501)) ### Released packages From 0b75ef5df0c93ef2fc6824ffa687ded8722624a0 Mon Sep 17 00:00:00 2001 From: badrAZ Date: Thu, 19 Sep 2019 14:52:03 +0200 Subject: [PATCH 18/20] improvements --- .../{build-template => template}/.babelrc.js | 0 .../{build-template => template}/README.md | 12 +++++------- .../{build-template => template}/package.json | 8 +++----- .../{build-template => template}/src/index.js | 10 ++++------ .../{build-template => template}/src/index.spec.js | 4 ++-- .../xo-web/src/common/xo/copy-vms-modal/index.js | 2 +- .../xo-web/src/common/xo/snapshot-vm-modal/index.js | 2 +- packages/xo-web/src/xo-app/new-vm/index.js | 2 +- 8 files changed, 17 insertions(+), 23 deletions(-) rename @xen-orchestra/{build-template => template}/.babelrc.js (100%) rename @xen-orchestra/{build-template => template}/README.md (66%) rename @xen-orchestra/{build-template => template}/package.json (84%) rename @xen-orchestra/{build-template => template}/src/index.js (62%) rename @xen-orchestra/{build-template => template}/src/index.spec.js (82%) diff --git a/@xen-orchestra/build-template/.babelrc.js b/@xen-orchestra/template/.babelrc.js similarity index 100% rename from @xen-orchestra/build-template/.babelrc.js rename to @xen-orchestra/template/.babelrc.js diff --git a/@xen-orchestra/build-template/README.md b/@xen-orchestra/template/README.md similarity index 66% rename from @xen-orchestra/build-template/README.md rename to @xen-orchestra/template/README.md index 90939b51fcf..b27b5cd7e87 100644 --- a/@xen-orchestra/build-template/README.md +++ b/@xen-orchestra/template/README.md @@ -1,13 +1,11 @@ -# ${pkg.name} [![Build Status](https://travis-ci.org/${pkg.shortGitHubPath}.png?branch=master)](https://travis-ci.org/${pkg.shortGitHubPath}) - -> ${pkg.description} +# @xen-orchestra/template [![Build Status](https://travis-ci.org/vatesfr/xen-orchestra.png?branch=master)](https://travis-ci.org/vatesfr/xen-orchestra) ## Install -Installation of the [npm package](https://npmjs.org/package/${pkg.name}): +Installation of the [npm package](https://npmjs.org/package/@xen-orchestra/template): ``` -> npm install --save ${pkg.name} +> npm install --save @xen-orchestra/template ``` ## Usage @@ -55,10 +53,10 @@ the code. You may: -- report any [issue](${pkg.bugs}) +- report any [issue](https://github.com/vatesfr/xen-orchestra/issues) you've encountered; - fork and create a pull request. ## License -${pkg.license} © [${pkg.author.name}](${pkg.author.url}) +ISC © [Vates SAS](https://vates.fr) diff --git a/@xen-orchestra/build-template/package.json b/@xen-orchestra/template/package.json similarity index 84% rename from @xen-orchestra/build-template/package.json rename to @xen-orchestra/template/package.json index 8052fedc01d..7e18cc85aff 100644 --- a/@xen-orchestra/build-template/package.json +++ b/@xen-orchestra/template/package.json @@ -1,11 +1,11 @@ { - "name": "@xen-orchestra/build-template", + "name": "@xen-orchestra/template", "version": "0.0.0", "license": "ISC", - "homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/build-template", + "homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/template", "bugs": "https://github.com/vatesfr/xen-orchestra/issues", "repository": { - "directory": "@xen-orchestra/build-template", + "directory": "@xen-orchestra/template", "type": "git", "url": "https://github.com/vatesfr/xen-orchestra.git" }, @@ -28,8 +28,6 @@ "@babel/cli": "^7.0.0", "@babel/core": "^7.0.0", "@babel/preset-env": "^7.0.0", - "@babel/preset-flow": "^7.0.0", - "babel-plugin-lodash": "^3.3.2", "cross-env": "^5.1.3", "rimraf": "^3.0.0" }, diff --git a/@xen-orchestra/build-template/src/index.js b/@xen-orchestra/template/src/index.js similarity index 62% rename from @xen-orchestra/build-template/src/index.js rename to @xen-orchestra/template/src/index.js index 86f12120cbd..08653360faa 100644 --- a/@xen-orchestra/build-template/src/index.js +++ b/@xen-orchestra/template/src/index.js @@ -1,15 +1,13 @@ -import { escapeRegExp } from 'lodash' +import escapeRegExp from 'lodash/escapeRegExp' const compareLengthDesc = (a, b) => b.length - a.length -export default (pattern, rules) => { - const keys = Object.keys(rules) - keys.push('\\') - const matches = keys +export default function compileTemplate(pattern, rules) { + const matches = Object.keys(rules) .sort(compareLengthDesc) .map(escapeRegExp) .join('|') - const regExp = new RegExp(`\\\\(?:${matches})|${matches}`, 'g') + const regExp = new RegExp(`\\\\(?:\\\\|${matches})|${matches}`, 'g') return (...params) => pattern.replace(regExp, match => { if (match[0] === '\\') { diff --git a/@xen-orchestra/build-template/src/index.spec.js b/@xen-orchestra/template/src/index.spec.js similarity index 82% rename from @xen-orchestra/build-template/src/index.spec.js rename to @xen-orchestra/template/src/index.spec.js index 006b4ceedd1..8097b55be14 100644 --- a/@xen-orchestra/build-template/src/index.spec.js +++ b/@xen-orchestra/template/src/index.spec.js @@ -1,8 +1,8 @@ /* eslint-env jest */ -import buildTemplate from '.' +import compileTemplate from '.' it("correctly replaces the template's variables", () => { - const replacer = buildTemplate( + const replacer = compileTemplate( '{property}_\\{property}_\\\\{property}_{constant}_%_FOO', { '{property}': obj => obj.name, diff --git a/packages/xo-web/src/common/xo/copy-vms-modal/index.js b/packages/xo-web/src/common/xo/copy-vms-modal/index.js index 5027a73d976..b405ae8c3f9 100644 --- a/packages/xo-web/src/common/xo/copy-vms-modal/index.js +++ b/packages/xo-web/src/common/xo/copy-vms-modal/index.js @@ -1,5 +1,5 @@ import _, { messages } from 'intl' -import buildTemplate from '@xen-orchestra/build-template' +import buildTemplate from '@xen-orchestra/template' import map from 'lodash/map' import React from 'react' import { injectIntl } from 'react-intl' diff --git a/packages/xo-web/src/common/xo/snapshot-vm-modal/index.js b/packages/xo-web/src/common/xo/snapshot-vm-modal/index.js index 2370b2fbf5e..fc1c6077864 100644 --- a/packages/xo-web/src/common/xo/snapshot-vm-modal/index.js +++ b/packages/xo-web/src/common/xo/snapshot-vm-modal/index.js @@ -1,7 +1,7 @@ import _ from 'intl' import React from 'react' import BaseComponent from 'base-component' -import buildTemplate from '@xen-orchestra/build-template' +import buildTemplate from '@xen-orchestra/template' import { forEach } from 'lodash' import { createGetObjectsOfType } from 'selectors' import { connectStore } from 'utils' diff --git a/packages/xo-web/src/xo-app/new-vm/index.js b/packages/xo-web/src/xo-app/new-vm/index.js index 2588cc205f2..b4e95581320 100644 --- a/packages/xo-web/src/xo-app/new-vm/index.js +++ b/packages/xo-web/src/xo-app/new-vm/index.js @@ -1,7 +1,7 @@ import _, { messages } from 'intl' import ActionButton from 'action-button' import BaseComponent from 'base-component' -import buildTemplate from '@xen-orchestra/build-template' +import buildTemplate from '@xen-orchestra/template' import Button from 'button' import classNames from 'classnames' import defined, { get } from '@xen-orchestra/defined' From d4dbacaf5ebd8da738794fb65b4e0405021f8412 Mon Sep 17 00:00:00 2001 From: badrAZ Date: Thu, 19 Sep 2019 15:11:30 +0200 Subject: [PATCH 19/20] fix --- packages/xo-web/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/xo-web/package.json b/packages/xo-web/package.json index 924b8929e61..db38466cbd3 100644 --- a/packages/xo-web/package.json +++ b/packages/xo-web/package.json @@ -34,7 +34,7 @@ "@nraynaud/novnc": "0.6.1", "@xen-orchestra/cron": "^1.0.3", "@xen-orchestra/defined": "^0.0.0", - "@xen-orchestra/build-template": "^0.0.0", + "@xen-orchestra/template": "^0.0.0", "ansi_up": "^4.0.3", "asap": "^2.0.6", "babel-core": "^6.26.0", From c0c7a5030900149a3a7b6c501092fcc079e878be Mon Sep 17 00:00:00 2001 From: badrAZ Date: Thu, 19 Sep 2019 15:50:26 +0200 Subject: [PATCH 20/20] improvements --- @xen-orchestra/template/README.md | 2 +- @xen-orchestra/template/src/index.js | 2 +- @xen-orchestra/template/src/index.spec.js | 2 +- packages/xo-web/src/common/xo/copy-vms-modal/index.js | 4 ++-- .../xo-web/src/common/xo/snapshot-vm-modal/index.js | 10 +++++----- packages/xo-web/src/xo-app/new-vm/index.js | 10 +++++----- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/@xen-orchestra/template/README.md b/@xen-orchestra/template/README.md index b27b5cd7e87..35d487f6d53 100644 --- a/@xen-orchestra/template/README.md +++ b/@xen-orchestra/template/README.md @@ -13,7 +13,7 @@ Installation of the [npm package](https://npmjs.org/package/@xen-orchestra/templ Create a string replacer based on a pattern and a list of rules. ```js -const myReplacer = buildTemplate('{name}_COPY_\{name}_{id}_%\%', { +const myReplacer = compileTemplate('{name}_COPY_\{name}_{id}_%\%', { '{name}': vm => vm.name_label, '{id}': vm => vm.id, '%': (_, i) => i diff --git a/@xen-orchestra/template/src/index.js b/@xen-orchestra/template/src/index.js index 08653360faa..74280a83617 100644 --- a/@xen-orchestra/template/src/index.js +++ b/@xen-orchestra/template/src/index.js @@ -2,7 +2,7 @@ import escapeRegExp from 'lodash/escapeRegExp' const compareLengthDesc = (a, b) => b.length - a.length -export default function compileTemplate(pattern, rules) { +export function compileTemplate(pattern, rules) { const matches = Object.keys(rules) .sort(compareLengthDesc) .map(escapeRegExp) diff --git a/@xen-orchestra/template/src/index.spec.js b/@xen-orchestra/template/src/index.spec.js index 8097b55be14..dc5cacba764 100644 --- a/@xen-orchestra/template/src/index.spec.js +++ b/@xen-orchestra/template/src/index.spec.js @@ -1,5 +1,5 @@ /* eslint-env jest */ -import compileTemplate from '.' +import { compileTemplate } from '.' it("correctly replaces the template's variables", () => { const replacer = compileTemplate( diff --git a/packages/xo-web/src/common/xo/copy-vms-modal/index.js b/packages/xo-web/src/common/xo/copy-vms-modal/index.js index b405ae8c3f9..00dfc705b23 100644 --- a/packages/xo-web/src/common/xo/copy-vms-modal/index.js +++ b/packages/xo-web/src/common/xo/copy-vms-modal/index.js @@ -1,7 +1,7 @@ import _, { messages } from 'intl' -import buildTemplate from '@xen-orchestra/template' import map from 'lodash/map' import React from 'react' +import { compileTemplate } from '@xen-orchestra/template' import { injectIntl } from 'react-intl' import BaseComponent from 'base-component' @@ -36,7 +36,7 @@ class CopyVmsModalBody extends BaseComponent { const names = namePattern ? map( resolvedVms, - buildTemplate(namePattern, { + compileTemplate(namePattern, { '{name}': vm => vm.name_label, '{id}': vm => vm.id, }) diff --git a/packages/xo-web/src/common/xo/snapshot-vm-modal/index.js b/packages/xo-web/src/common/xo/snapshot-vm-modal/index.js index fc1c6077864..4100fcff3e9 100644 --- a/packages/xo-web/src/common/xo/snapshot-vm-modal/index.js +++ b/packages/xo-web/src/common/xo/snapshot-vm-modal/index.js @@ -1,11 +1,11 @@ import _ from 'intl' import React from 'react' import BaseComponent from 'base-component' -import buildTemplate from '@xen-orchestra/template' -import { forEach } from 'lodash' -import { createGetObjectsOfType } from 'selectors' +import { compileTemplate } from '@xen-orchestra/template' import { connectStore } from 'utils' import { Container, Col, Row } from 'grid' +import { createGetObjectsOfType } from 'selectors' +import { forEach } from 'lodash' const RULES = { '{date}': () => new Date().toISOString(), @@ -31,8 +31,8 @@ export default class SnapshotVmModalBody extends BaseComponent { return { names: {}, descriptions: {}, saveMemory } } - const generateName = buildTemplate(namePattern, RULES) - const generateDescription = buildTemplate(descriptionPattern, RULES) + const generateName = compileTemplate(namePattern, RULES) + const generateDescription = compileTemplate(descriptionPattern, RULES) const names = {} const descriptions = {} diff --git a/packages/xo-web/src/xo-app/new-vm/index.js b/packages/xo-web/src/xo-app/new-vm/index.js index b4e95581320..85c9b3801f0 100644 --- a/packages/xo-web/src/xo-app/new-vm/index.js +++ b/packages/xo-web/src/xo-app/new-vm/index.js @@ -1,7 +1,6 @@ import _, { messages } from 'intl' import ActionButton from 'action-button' import BaseComponent from 'base-component' -import buildTemplate from '@xen-orchestra/template' import Button from 'button' import classNames from 'classnames' import defined, { get } from '@xen-orchestra/defined' @@ -16,6 +15,10 @@ import store from 'store' import Tags from 'tags' import Tooltip from 'tooltip' import Wizard, { Section } from 'wizard' +import { compileTemplate } from '@xen-orchestra/template' +import { confirm } from 'modal' +import { Container, Row, Col } from 'grid' +import { injectIntl } from 'react-intl' import { AvailableTemplateVars, CAN_CLOUD_INIT, @@ -23,9 +26,6 @@ import { DEFAULT_NETWORK_CONFIG_TEMPLATE, NetworkConfigInfo, } from 'cloud-config' -import { confirm } from 'modal' -import { Container, Row, Col } from 'grid' -import { injectIntl } from 'react-intl' import { Input as DebounceInput, Textarea as DebounceTextarea, @@ -744,7 +744,7 @@ export default class NewVm extends BaseComponent { ) _buildTemplate = pattern => - buildTemplate(pattern, { + compileTemplate(pattern, { '{name}': state => state.name_label || '', '%': (_, i) => i, })