1import { DataTransformerID } from './ids';
2import { DataTransformerInfo } from '../../types/transformations';
3import { map } from 'rxjs/operators';
4import { DataFrame } from '../../types/dataFrame';
5import { getFieldDisplayName } from '../../field/fieldState';
6
7/**
8 * Options for renameByRegexTransformer
9 *
10 * @public
11 */
12export interface RenameByRegexTransformerOptions {
13  regex: string;
14  renamePattern: string;
15}
16
17/**
18 * Replaces the displayName of a field by applying a regular expression
19 * to match the name and a pattern for the replacement.
20 *
21 * @public
22 */
23export const renameByRegexTransformer: DataTransformerInfo<RenameByRegexTransformerOptions> = {
24  id: DataTransformerID.renameByRegex,
25  name: 'Rename fields by regex',
26  description: 'Rename fields based on regular expression by users.',
27  defaultOptions: {
28    regex: '(.*)',
29    renamePattern: '$1',
30  },
31
32  /**
33   * Return a modified copy of the series.  If the transform is not or should not
34   * be applied, just return the input series
35   */
36  operator: (options) => (source) =>
37    source.pipe(
38      map((data) => {
39        if (!Array.isArray(data) || data.length === 0) {
40          return data;
41        }
42        return data.map(renameFieldsByRegex(options));
43      })
44    ),
45};
46
47const renameFieldsByRegex = (options: RenameByRegexTransformerOptions) => (frame: DataFrame) => {
48  const regex = new RegExp(options.regex);
49  const fields = frame.fields.map((field) => {
50    const displayName = getFieldDisplayName(field, frame);
51    if (!regex.test(displayName)) {
52      return field;
53    }
54    const newDisplayName = displayName.replace(regex, options.renamePattern);
55    return {
56      ...field,
57      config: { ...field.config, displayName: newDisplayName },
58      state: { ...field.state, displayName: newDisplayName },
59    };
60  });
61  return { ...frame, fields };
62};
63