mirror of https://github.com/grafana/grafana
TemplateSrv: Refactoring out all formats to a formatRegistry (#26607)
parent
0d933b79b7
commit
cfac143244
@ -0,0 +1,212 @@ |
|||||||
|
import kbn from 'app/core/utils/kbn'; |
||||||
|
import { Registry, RegistryItem, VariableModel, textUtil, dateTime } from '@grafana/data'; |
||||||
|
import { map, isArray, replace } from 'lodash'; |
||||||
|
|
||||||
|
export interface FormatRegistryItem extends RegistryItem { |
||||||
|
formatter(value: any, args: string[], variable: VariableModel): string; |
||||||
|
} |
||||||
|
|
||||||
|
export const formatRegistry = new Registry<FormatRegistryItem>(() => { |
||||||
|
const formats: FormatRegistryItem[] = [ |
||||||
|
{ |
||||||
|
id: 'lucene', |
||||||
|
name: 'Lucene', |
||||||
|
description: 'Values are lucene escaped and multi-valued variables generate an OR expression', |
||||||
|
formatter: value => { |
||||||
|
if (typeof value === 'string') { |
||||||
|
return luceneEscape(value); |
||||||
|
} |
||||||
|
|
||||||
|
if (value instanceof Array && value.length === 0) { |
||||||
|
return '__empty__'; |
||||||
|
} |
||||||
|
|
||||||
|
const quotedValues = map(value, (val: string) => { |
||||||
|
return '"' + luceneEscape(val) + '"'; |
||||||
|
}); |
||||||
|
|
||||||
|
return '(' + quotedValues.join(' OR ') + ')'; |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 'regex', |
||||||
|
name: 'Regex', |
||||||
|
description: 'Values are regex escaped and multi-valued variables generate a (<value>|<value>) expression', |
||||||
|
formatter: value => { |
||||||
|
if (typeof value === 'string') { |
||||||
|
return kbn.regexEscape(value); |
||||||
|
} |
||||||
|
|
||||||
|
const escapedValues = map(value, kbn.regexEscape); |
||||||
|
if (escapedValues.length === 1) { |
||||||
|
return escapedValues[0]; |
||||||
|
} |
||||||
|
return '(' + escapedValues.join('|') + ')'; |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 'pipe', |
||||||
|
name: 'Pipe', |
||||||
|
description: 'Values are seperated by | character', |
||||||
|
formatter: value => { |
||||||
|
if (typeof value === 'string') { |
||||||
|
return value; |
||||||
|
} |
||||||
|
return value.join('|'); |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 'distributed', |
||||||
|
name: 'Distributed', |
||||||
|
description: 'Multiple values are formatted like variable=value', |
||||||
|
formatter: (value, args, variable) => { |
||||||
|
if (typeof value === 'string') { |
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
value = map(value, (val: any, index: number) => { |
||||||
|
if (index !== 0) { |
||||||
|
return variable.name + '=' + val; |
||||||
|
} else { |
||||||
|
return val; |
||||||
|
} |
||||||
|
}); |
||||||
|
return value.join(','); |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 'csv', |
||||||
|
name: 'Csv', |
||||||
|
description: 'Comma seperated values', |
||||||
|
formatter: (value, args, variable) => { |
||||||
|
if (isArray(value)) { |
||||||
|
return value.join(','); |
||||||
|
} |
||||||
|
return value; |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 'html', |
||||||
|
name: 'HTML', |
||||||
|
description: 'HTML escaping of values', |
||||||
|
formatter: (value, args, variable) => { |
||||||
|
if (isArray(value)) { |
||||||
|
return textUtil.escapeHtml(value.join(', ')); |
||||||
|
} |
||||||
|
return textUtil.escapeHtml(value); |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 'json', |
||||||
|
name: 'JSON', |
||||||
|
description: 'JSON stringify valu', |
||||||
|
formatter: (value, args, variable) => { |
||||||
|
return JSON.stringify(value); |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 'percentencode', |
||||||
|
name: 'Percent encode', |
||||||
|
description: 'Useful for url escaping values', |
||||||
|
formatter: (value, args, variable) => { |
||||||
|
// like glob, but url escaped
|
||||||
|
if (isArray(value)) { |
||||||
|
return encodeURIComponentStrict('{' + value.join(',') + '}'); |
||||||
|
} |
||||||
|
return encodeURIComponentStrict(value); |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 'singlequote', |
||||||
|
name: 'Single quote', |
||||||
|
description: 'Single quoted values', |
||||||
|
formatter: (value, args, variable) => { |
||||||
|
// escape single quotes with backslash
|
||||||
|
const regExp = new RegExp(`'`, 'g'); |
||||||
|
if (isArray(value)) { |
||||||
|
return map(value, (v: string) => `'${replace(v, regExp, `\\'`)}'`).join(','); |
||||||
|
} |
||||||
|
return `'${replace(value, regExp, `\\'`)}'`; |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 'doublequote', |
||||||
|
name: 'Double quote', |
||||||
|
description: 'Double quoted values', |
||||||
|
formatter: (value, args, variable) => { |
||||||
|
// escape double quotes with backslash
|
||||||
|
const regExp = new RegExp('"', 'g'); |
||||||
|
if (isArray(value)) { |
||||||
|
return map(value, (v: string) => `"${replace(v, regExp, '\\"')}"`).join(','); |
||||||
|
} |
||||||
|
return `"${replace(value, regExp, '\\"')}"`; |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 'sqlstring', |
||||||
|
name: 'SQL string', |
||||||
|
description: 'SQL string quoting and commas for use in IN statements and other scenarios', |
||||||
|
formatter: (value, args, variable) => { |
||||||
|
// escape single quotes by pairing them
|
||||||
|
const regExp = new RegExp(`'`, 'g'); |
||||||
|
if (isArray(value)) { |
||||||
|
return map(value, v => `'${replace(v, regExp, "''")}'`).join(','); |
||||||
|
} |
||||||
|
return `'${replace(value, regExp, "''")}'`; |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 'date', |
||||||
|
name: 'Date', |
||||||
|
description: 'Format date in different ways', |
||||||
|
formatter: (value, args, variable) => { |
||||||
|
const arg = args[0] ?? 'iso'; |
||||||
|
|
||||||
|
switch (arg) { |
||||||
|
case 'ms': |
||||||
|
return value; |
||||||
|
case 'seconds': |
||||||
|
return `${Math.round(parseInt(value, 10)! / 1000)}`; |
||||||
|
case 'iso': |
||||||
|
return dateTime(parseInt(value, 10)).toISOString(); |
||||||
|
default: |
||||||
|
return dateTime(parseInt(value, 10)).format(arg); |
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 'glob', |
||||||
|
name: 'Glob', |
||||||
|
description: 'Format multi valued variables using glob syntax, example {value1,value2}', |
||||||
|
formatter: (value, args, variable) => { |
||||||
|
if (isArray(value) && value.length > 1) { |
||||||
|
return '{' + value.join(',') + '}'; |
||||||
|
} |
||||||
|
return value; |
||||||
|
}, |
||||||
|
}, |
||||||
|
]; |
||||||
|
|
||||||
|
return formats; |
||||||
|
}); |
||||||
|
|
||||||
|
function luceneEscape(value: string) { |
||||||
|
return value.replace(/([\!\*\+\-\=<>\s\&\|\(\)\[\]\{\}\^\~\?\:\\/"])/g, '\\$1'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* encode string according to RFC 3986; in contrast to encodeURIComponent() |
||||||
|
* also the sub-delims "!", "'", "(", ")" and "*" are encoded; |
||||||
|
* unicode handling uses UTF-8 as in ECMA-262. |
||||||
|
*/ |
||||||
|
function encodeURIComponentStrict(str: string) { |
||||||
|
return encodeURIComponent(str).replace(/[!'()*]/g, c => { |
||||||
|
return ( |
||||||
|
'%' + |
||||||
|
c |
||||||
|
.charCodeAt(0) |
||||||
|
.toString(16) |
||||||
|
.toUpperCase() |
||||||
|
); |
||||||
|
}); |
||||||
|
} |
||||||
Loading…
Reference in new issue