Skip to content

Commit d4ef755

Browse files
author
Liza K
committed
Merge branch 'master' of github.com:elastic/kibana into pr/82545
2 parents 1ad2f0b + 423888c commit d4ef755

File tree

74 files changed

+2247
-422
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+2247
-422
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
2+
3+
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [exporters](./kibana-plugin-plugins-data-public.exporters.md)
4+
5+
## exporters variable
6+
7+
<b>Signature:</b>
8+
9+
```typescript
10+
exporters: {
11+
datatableToCSV: typeof datatableToCSV;
12+
CSV_MIME_TYPE: string;
13+
}
14+
```

docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
| [esFilters](./kibana-plugin-plugins-data-public.esfilters.md) | |
109109
| [esKuery](./kibana-plugin-plugins-data-public.eskuery.md) | |
110110
| [esQuery](./kibana-plugin-plugins-data-public.esquery.md) | |
111+
| [exporters](./kibana-plugin-plugins-data-public.exporters.md) | |
111112
| [extractSearchSourceReferences](./kibana-plugin-plugins-data-public.extractsearchsourcereferences.md) | |
112113
| [fieldFormats](./kibana-plugin-plugins-data-public.fieldformats.md) | |
113114
| [fieldList](./kibana-plugin-plugins-data-public.fieldlist.md) | |
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
2+
3+
[Home](./index.md) &gt; [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) &gt; [exporters](./kibana-plugin-plugins-data-server.exporters.md)
4+
5+
## exporters variable
6+
7+
<b>Signature:</b>
8+
9+
```typescript
10+
exporters: {
11+
datatableToCSV: typeof datatableToCSV;
12+
CSV_MIME_TYPE: string;
13+
}
14+
```

docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
| [esFilters](./kibana-plugin-plugins-data-server.esfilters.md) | |
7777
| [esKuery](./kibana-plugin-plugins-data-server.eskuery.md) | |
7878
| [esQuery](./kibana-plugin-plugins-data-server.esquery.md) | |
79+
| [exporters](./kibana-plugin-plugins-data-server.exporters.md) | |
7980
| [fieldFormats](./kibana-plugin-plugins-data-server.fieldformats.md) | |
8081
| [indexPatterns](./kibana-plugin-plugins-data-server.indexpatterns.md) | |
8182
| [mergeCapabilitiesWithFields](./kibana-plugin-plugins-data-server.mergecapabilitieswithfields.md) | |

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@
106106
"@babel/runtime": "^7.11.2",
107107
"@elastic/datemath": "link:packages/elastic-datemath",
108108
"@elastic/elasticsearch": "7.10.0-rc.1",
109-
"@elastic/ems-client": "7.10.0",
109+
"@elastic/ems-client": "7.11.0",
110110
"@elastic/eui": "30.2.0",
111111
"@elastic/filesaver": "1.1.2",
112112
"@elastic/good": "8.1.1-kibana2",
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
import { Datatable } from 'src/plugins/expressions';
21+
import { FieldFormat } from '../../common/field_formats';
22+
import { datatableToCSV } from './export_csv';
23+
24+
function getDefaultOptions() {
25+
const formatFactory = jest.fn();
26+
formatFactory.mockReturnValue({ convert: (v: unknown) => `Formatted_${v}` } as FieldFormat);
27+
return {
28+
csvSeparator: ',',
29+
quoteValues: true,
30+
formatFactory,
31+
};
32+
}
33+
34+
function getDataTable({ multipleColumns }: { multipleColumns?: boolean } = {}): Datatable {
35+
const layer1: Datatable = {
36+
type: 'datatable',
37+
columns: [{ id: 'col1', name: 'columnOne', meta: { type: 'string' } }],
38+
rows: [{ col1: 'value' }],
39+
};
40+
if (multipleColumns) {
41+
layer1.columns.push({ id: 'col2', name: 'columnTwo', meta: { type: 'number' } });
42+
layer1.rows[0].col2 = 5;
43+
}
44+
return layer1;
45+
}
46+
47+
describe('CSV exporter', () => {
48+
test('should not break with empty data', () => {
49+
expect(
50+
datatableToCSV({ type: 'datatable', columns: [], rows: [] }, getDefaultOptions())
51+
).toMatch('');
52+
});
53+
54+
test('should export formatted values by default', () => {
55+
expect(datatableToCSV(getDataTable(), getDefaultOptions())).toMatch(
56+
'columnOne\r\n"Formatted_value"\r\n'
57+
);
58+
});
59+
60+
test('should not quote values when requested', () => {
61+
return expect(
62+
datatableToCSV(getDataTable(), { ...getDefaultOptions(), quoteValues: false })
63+
).toMatch('columnOne\r\nFormatted_value\r\n');
64+
});
65+
66+
test('should use raw values when requested', () => {
67+
expect(datatableToCSV(getDataTable(), { ...getDefaultOptions(), raw: true })).toMatch(
68+
'columnOne\r\nvalue\r\n'
69+
);
70+
});
71+
72+
test('should use separator for multiple columns', () => {
73+
expect(datatableToCSV(getDataTable({ multipleColumns: true }), getDefaultOptions())).toMatch(
74+
'columnOne,columnTwo\r\n"Formatted_value","Formatted_5"\r\n'
75+
);
76+
});
77+
78+
test('should escape values', () => {
79+
const datatable = getDataTable();
80+
datatable.rows[0].col1 = '"value"';
81+
expect(datatableToCSV(datatable, getDefaultOptions())).toMatch(
82+
'columnOne\r\n"Formatted_""value"""\r\n'
83+
);
84+
});
85+
});
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
// Inspired by the inspector CSV exporter
21+
22+
import { FormatFactory } from 'src/plugins/data/common/field_formats/utils';
23+
import { Datatable } from 'src/plugins/expressions';
24+
25+
const LINE_FEED_CHARACTER = '\r\n';
26+
const nonAlphaNumRE = /[^a-zA-Z0-9]/;
27+
const allDoubleQuoteRE = /"/g;
28+
export const CSV_MIME_TYPE = 'text/plain;charset=utf-8';
29+
30+
// TODO: enhance this later on
31+
function escape(val: object | string, quoteValues: boolean) {
32+
if (val != null && typeof val === 'object') {
33+
val = val.valueOf();
34+
}
35+
36+
val = String(val);
37+
38+
if (quoteValues && nonAlphaNumRE.test(val)) {
39+
val = `"${val.replace(allDoubleQuoteRE, '""')}"`;
40+
}
41+
42+
return val;
43+
}
44+
45+
interface CSVOptions {
46+
csvSeparator: string;
47+
quoteValues: boolean;
48+
formatFactory: FormatFactory;
49+
raw?: boolean;
50+
}
51+
52+
export function datatableToCSV(
53+
{ columns, rows }: Datatable,
54+
{ csvSeparator, quoteValues, formatFactory, raw }: CSVOptions
55+
) {
56+
// Build the header row by its names
57+
const header = columns.map((col) => escape(col.name, quoteValues));
58+
59+
const formatters = columns.reduce<Record<string, ReturnType<FormatFactory>>>(
60+
(memo, { id, meta }) => {
61+
memo[id] = formatFactory(meta?.params);
62+
return memo;
63+
},
64+
{}
65+
);
66+
67+
// Convert the array of row objects to an array of row arrays
68+
const csvRows = rows.map((row) => {
69+
return columns.map((column) =>
70+
escape(raw ? row[column.id] : formatters[column.id].convert(row[column.id]), quoteValues)
71+
);
72+
});
73+
74+
if (header.length === 0) {
75+
return '';
76+
}
77+
78+
return (
79+
[header, ...csvRows].map((row) => row.join(csvSeparator)).join(LINE_FEED_CHARACTER) +
80+
LINE_FEED_CHARACTER
81+
); // Add \r\n after last line
82+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
export { datatableToCSV, CSV_MIME_TYPE } from './export_csv';

src/plugins/data/common/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export * from './query';
2626
export * from './search';
2727
export * from './types';
2828
export * from './utils';
29+
export * from './exports';
2930

3031
/**
3132
* Use data plugin interface instead

src/plugins/data/public/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,16 @@ export {
212212
FieldFormat,
213213
} from '../common';
214214

215+
/**
216+
* Exporters (CSV)
217+
*/
218+
219+
import { datatableToCSV, CSV_MIME_TYPE } from '../common';
220+
export const exporters = {
221+
datatableToCSV,
222+
CSV_MIME_TYPE,
223+
};
224+
215225
/*
216226
* Index patterns:
217227
*/

0 commit comments

Comments
 (0)