autofix all violations

This commit is contained in:
spalger 2019-12-14 12:00:45 -07:00
parent a1f1079a0d
commit 956aeb1cee
4652 changed files with 98042 additions and 93129 deletions

View file

@ -19,7 +19,7 @@
require('./src/setup_node_env');
module.exports = function (grunt) {
module.exports = function(grunt) {
// set the config once before calling load-grunt-config
// and once during so that we have access to it via
// grunt.config.get() within the config files
@ -35,8 +35,8 @@ module.exports = function (grunt) {
init: true,
config: config,
loadGruntTasks: {
pattern: ['grunt-*', '@*/grunt-*', 'gruntify-*', '@*/gruntify-*']
}
pattern: ['grunt-*', '@*/grunt-*', 'gruntify-*', '@*/gruntify-*'],
},
});
// load task definitions

View file

@ -22,7 +22,7 @@ module.exports = {
plugins: ['@babel/plugin-proposal-class-properties'],
env: {
web: {
presets: ['@kbn/babel-preset/webpack_preset']
presets: ['@kbn/babel-preset/webpack_preset'],
},
node: {
presets: ['@kbn/babel-preset/node_preset'],

View file

@ -28,7 +28,7 @@ export function canRequire(entry, cwd = require.resolve.paths(entry) || []) {
// looking recursively as normal starting
// from those locations.
return require.resolve(entry, {
paths: [].concat(cwd)
paths: [].concat(cwd),
});
} catch (e) {
return false;

View file

@ -81,7 +81,7 @@ export async function parseEntries(cwd, entries, strategy, results, wasParsed =
// Test each entry against canRequire function
const entriesQueue = entries.map(entry => canRequire(entry));
while(entriesQueue.length) {
while (entriesQueue.length) {
// Get the first element in the queue as
// select it as our current entry to parse
const mainEntry = entriesQueue.shift();
@ -93,7 +93,9 @@ export async function parseEntries(cwd, entries, strategy, results, wasParsed =
}
// Find new entries and adds them to the end of the queue
entriesQueue.push(...(await strategy(sanitizedCwd, parseSingleFile, mainEntry, wasParsed, results)));
entriesQueue.push(
...(await strategy(sanitizedCwd, parseSingleFile, mainEntry, wasParsed, results))
);
// Mark the current main entry as already parsed
wasParsed[mainEntry] = true;

View file

@ -48,14 +48,21 @@ export function _calculateTopLevelDependency(inputDep, outputDep = '') {
return _calculateTopLevelDependency(depSplitPaths.join(pathSeparator), outputDep);
}
export async function dependenciesParseStrategy(cwd, parseSingleFile, mainEntry, wasParsed, results) {
export async function dependenciesParseStrategy(
cwd,
parseSingleFile,
mainEntry,
wasParsed,
results
) {
// Retrieve native nodeJS modules
const natives = process.binding('natives');
// Get dependencies from a single file and filter
// out node native modules from the result
const dependencies = (await parseSingleFile(mainEntry, dependenciesVisitorsGenerator))
.filter(dep => !natives[dep]);
const dependencies = (await parseSingleFile(mainEntry, dependenciesVisitorsGenerator)).filter(
dep => !natives[dep]
);
// Return the list of all the new entries found into
// the current mainEntry that we could use to look for

View file

@ -23,11 +23,11 @@ import { parseSingleFile } from './code_parser';
import { _calculateTopLevelDependency, dependenciesParseStrategy } from './strategies';
jest.mock('./can_require', () => ({
canRequire: jest.fn()
canRequire: jest.fn(),
}));
jest.mock('fs', () => ({
readFile: jest.fn()
readFile: jest.fn(),
}));
const mockCwd = '/tmp/project/dir/';
@ -69,7 +69,13 @@ describe('Code Parser Strategies', () => {
}
});
const results = await dependenciesParseStrategy(mockCwd, parseSingleFile, 'dep1/file.js', {}, {});
const results = await dependenciesParseStrategy(
mockCwd,
parseSingleFile,
'dep1/file.js',
{},
{}
);
expect(results[0]).toBe(`${mockCwd}node_modules/dep_from_node_modules/index.js`);
});
@ -78,7 +84,7 @@ describe('Code Parser Strategies', () => {
cb(null, `require('./relative_dep')`);
});
canRequire.mockImplementation((entry) => {
canRequire.mockImplementation(entry => {
if (entry === `${mockCwd}dep1/relative_dep`) {
return `${entry}/index.js`;
}
@ -86,7 +92,13 @@ describe('Code Parser Strategies', () => {
return false;
});
const results = await dependenciesParseStrategy(mockCwd, parseSingleFile, 'dep1/file.js', {}, {});
const results = await dependenciesParseStrategy(
mockCwd,
parseSingleFile,
'dep1/file.js',
{},
{}
);
expect(results[0]).toBe(`${mockCwd}dep1/relative_dep/index.js`);
});

View file

@ -21,29 +21,29 @@ export function dependenciesVisitorsGenerator(dependenciesAcc) {
// raw values on require + require.resolve
CallExpression: ({ node }) => {
// AST check for require expressions
const isRequire = (node) => {
const isRequire = node => {
return matches({
callee: {
type: 'Identifier',
name: 'require'
}
name: 'require',
},
})(node);
};
// AST check for require.resolve expressions
const isRequireResolve = (node) => {
const isRequireResolve = node => {
return matches({
callee: {
type: 'MemberExpression',
object: {
type: 'Identifier',
name: 'require'
name: 'require',
},
property: {
type: 'Identifier',
name: 'resolve'
}
}
name: 'resolve',
},
},
})(node);
};
@ -66,12 +66,12 @@ export function dependenciesVisitorsGenerator(dependenciesAcc) {
// raw values on import
ImportDeclaration: ({ node }) => {
// AST check for supported import expressions
const isImport = (node) => {
const isImport = node => {
return matches({
type: 'ImportDeclaration',
source: {
type: 'StringLiteral'
}
type: 'StringLiteral',
},
})(node);
};
@ -85,12 +85,12 @@ export function dependenciesVisitorsGenerator(dependenciesAcc) {
// raw values on export from
ExportNamedDeclaration: ({ node }) => {
// AST check for supported export from expressions
const isExportFrom = (node) => {
const isExportFrom = node => {
return matches({
type: 'ExportNamedDeclaration',
source: {
type: 'StringLiteral'
}
type: 'StringLiteral',
},
})(node);
};
@ -104,12 +104,12 @@ export function dependenciesVisitorsGenerator(dependenciesAcc) {
// raw values on export * from
ExportAllDeclaration: ({ node }) => {
// AST check for supported export * from expressions
const isExportAllFrom = (node) => {
const isExportAllFrom = node => {
return matches({
type: 'ExportAllDeclaration',
source: {
type: 'StringLiteral'
}
type: 'StringLiteral',
},
})(node);
};
@ -118,7 +118,7 @@ export function dependenciesVisitorsGenerator(dependenciesAcc) {
const exportAllFromSource = node.source;
dependenciesAcc.push(exportAllFromSource.value);
}
}
},
};
})();
}

View file

@ -21,12 +21,12 @@ import * as parser from '@babel/parser';
import traverse from '@babel/traverse';
import { dependenciesVisitorsGenerator } from './visitors';
const visitorsApplier = (code) => {
const visitorsApplier = code => {
const result = [];
traverse(
parser.parse(code, {
sourceType: 'unambiguous',
plugins: ['exportDefaultFrom']
plugins: ['exportDefaultFrom'],
}),
dependenciesVisitorsGenerator(result)
);

View file

@ -28,6 +28,6 @@ module.exports = {
'exportDefaultFrom',
'exportNamespaceFrom',
'objectRestSpread',
'throwExpressions'
'throwExpressions',
],
};

View file

@ -39,7 +39,7 @@ module.exports = (_, options = {}) => {
modules: 'cjs',
corejs: 3,
...(options['@babel/preset-env'] || {})
...(options['@babel/preset-env'] || {}),
},
],
require('./common_preset'),
@ -48,9 +48,9 @@ module.exports = (_, options = {}) => {
[
require.resolve('babel-plugin-transform-define'),
{
'global.__BUILT_WITH_BABEL__': 'true'
}
]
]
'global.__BUILT_WITH_BABEL__': 'true',
},
],
],
};
};

View file

@ -33,6 +33,6 @@ module.exports = () => {
plugins: [
require.resolve('@babel/plugin-transform-modules-commonjs'),
require.resolve('@babel/plugin-syntax-dynamic-import'),
]
],
};
};

View file

@ -21,14 +21,10 @@
module.exports = {
env: {
public: {
presets: [
'@kbn/babel-preset/webpack_preset'
],
presets: ['@kbn/babel-preset/webpack_preset'],
},
server: {
presets: [
'@kbn/babel-preset/node_preset'
],
presets: ['@kbn/babel-preset/node_preset'],
},
},
ignore: ['**/__tests__/**/*', '**/*.test.ts', '**/*.test.tsx'],

View file

@ -21,44 +21,42 @@ import expect from '@kbn/expect';
import _ from 'lodash';
import { migrateFilter } from '../migrate_filter';
describe('migrateFilter', function () {
describe('migrateFilter', function() {
const oldMatchPhraseFilter = {
match: {
fieldFoo: {
query: 'foobar',
type: 'phrase'
}
}
type: 'phrase',
},
},
};
const newMatchPhraseFilter = {
match_phrase: {
fieldFoo: {
query: 'foobar'
}
}
query: 'foobar',
},
},
};
// https://github.com/elastic/elasticsearch/pull/17508
it('should migrate match filters of type phrase', function () {
it('should migrate match filters of type phrase', function() {
const migratedFilter = migrateFilter(oldMatchPhraseFilter);
expect(_.isEqual(migratedFilter, newMatchPhraseFilter)).to.be(true);
});
it('should not modify the original filter', function () {
it('should not modify the original filter', function() {
const oldMatchPhraseFilterCopy = _.clone(oldMatchPhraseFilter, true);
migrateFilter(oldMatchPhraseFilter);
expect(_.isEqual(oldMatchPhraseFilter, oldMatchPhraseFilterCopy)).to.be(true);
});
it('should return the original filter if no migration is necessary', function () {
it('should return the original filter if no migration is necessary', function() {
const originalFilter = {
match_all: {}
match_all: {},
};
const migratedFilter = migrateFilter(originalFilter);
expect(migratedFilter).to.be(originalFilter);
expect(_.isEqual(migratedFilter, originalFilter)).to.be(true);
});
});

View file

@ -24,10 +24,9 @@ import { fromKueryExpression, toElasticsearchQuery } from '../../kuery';
import { luceneStringToDsl } from '../lucene_string_to_dsl';
import { decorateQuery } from '../decorate_query';
describe('build query', function () {
describe('buildEsQuery', function () {
it('should return the parameters of an Elasticsearch bool query', function () {
describe('build query', function() {
describe('buildEsQuery', function() {
it('should return the parameters of an Elasticsearch bool query', function() {
const result = buildEsQuery();
const expected = {
bool: {
@ -35,12 +34,12 @@ describe('build query', function () {
filter: [],
should: [],
must_not: [],
}
},
};
expect(result).to.eql(expected);
});
it('should combine queries and filters from multiple query languages into a single ES bool query', function () {
it('should combine queries and filters from multiple query languages into a single ES bool query', function() {
const queries = [
{ query: 'extension:jpg', language: 'kuery' },
{ query: 'bar:baz', language: 'lucene' },
@ -58,16 +57,14 @@ describe('build query', function () {
const expectedResult = {
bool: {
must: [
decorateQuery(luceneStringToDsl('bar:baz'), config.queryStringOptions),
],
must: [decorateQuery(luceneStringToDsl('bar:baz'), config.queryStringOptions)],
filter: [
toElasticsearchQuery(fromKueryExpression('extension:jpg'), indexPattern),
{ match_all: {} },
],
should: [],
must_not: [],
}
},
};
const result = buildEsQuery(indexPattern, queries, filters, config);
@ -75,7 +72,7 @@ describe('build query', function () {
expect(result).to.eql(expectedResult);
});
it('should accept queries and filters as either single objects or arrays', function () {
it('should accept queries and filters as either single objects or arrays', function() {
const queries = { query: 'extension:jpg', language: 'lucene' };
const filters = {
match_all: {},
@ -88,13 +85,11 @@ describe('build query', function () {
const expectedResult = {
bool: {
must: [
decorateQuery(luceneStringToDsl('extension:jpg'), config.queryStringOptions),
],
must: [decorateQuery(luceneStringToDsl('extension:jpg'), config.queryStringOptions)],
filter: [{ match_all: {} }],
should: [],
must_not: [],
}
},
};
const result = buildEsQuery(indexPattern, queries, filters, config);
@ -102,14 +97,12 @@ describe('build query', function () {
expect(result).to.eql(expectedResult);
});
it('should use the default time zone set in the Advanced Settings in queries and filters', function () {
it('should use the default time zone set in the Advanced Settings in queries and filters', function() {
const queries = [
{ query: '@timestamp:"2019-03-23T13:18:00"', language: 'kuery' },
{ query: '@timestamp:"2019-03-23T13:18:00"', language: 'lucene' }
];
const filters = [
{ match_all: {}, meta: { type: 'match_all' } }
{ query: '@timestamp:"2019-03-23T13:18:00"', language: 'lucene' },
];
const filters = [{ match_all: {}, meta: { type: 'match_all' } }];
const config = {
allowLeadingWildcards: true,
queryStringOptions: {},
@ -120,20 +113,26 @@ describe('build query', function () {
const expectedResult = {
bool: {
must: [
decorateQuery(luceneStringToDsl('@timestamp:"2019-03-23T13:18:00"'), config.queryStringOptions, config.dateFormatTZ),
decorateQuery(
luceneStringToDsl('@timestamp:"2019-03-23T13:18:00"'),
config.queryStringOptions,
config.dateFormatTZ
),
],
filter: [
toElasticsearchQuery(fromKueryExpression('@timestamp:"2019-03-23T13:18:00"'), indexPattern, config),
{ match_all: {} }
toElasticsearchQuery(
fromKueryExpression('@timestamp:"2019-03-23T13:18:00"'),
indexPattern,
config
),
{ match_all: {} },
],
should: [],
must_not: [],
}
},
};
const result = buildEsQuery(indexPattern, queries, filters, config);
expect(result).to.eql(expectedResult);
});
});
});

View file

@ -20,18 +20,27 @@
import expect from '@kbn/expect';
import { decorateQuery } from '../decorate_query';
describe('Query decorator', function () {
it('should be a function', function () {
describe('Query decorator', function() {
it('should be a function', function() {
expect(decorateQuery).to.be.a(Function);
});
it('should merge in the query string options', function () {
const decoratedQuery = decorateQuery({ query_string: { query: '*' } }, { analyze_wildcard: true });
it('should merge in the query string options', function() {
const decoratedQuery = decorateQuery(
{ query_string: { query: '*' } },
{ analyze_wildcard: true }
);
expect(decoratedQuery).to.eql({ query_string: { query: '*', analyze_wildcard: true } });
});
it('should add a default of a time_zone parameter if one is provided', function () {
const decoratedQuery = decorateQuery({ query_string: { query: '*' } }, { analyze_wildcard: true }, 'America/Phoenix');
expect(decoratedQuery).to.eql({ query_string: { query: '*', analyze_wildcard: true, time_zone: 'America/Phoenix' } });
it('should add a default of a time_zone parameter if one is provided', function() {
const decoratedQuery = decorateQuery(
{ query_string: { query: '*' } },
{ analyze_wildcard: true },
'America/Phoenix'
);
expect(decoratedQuery).to.eql({
query_string: { query: '*', analyze_wildcard: true, time_zone: 'America/Phoenix' },
});
});
});

View file

@ -20,7 +20,7 @@
import expect from '@kbn/expect';
import { filterMatchesIndex } from '../filter_matches_index';
describe('filterMatchesIndex', function () {
describe('filterMatchesIndex', function() {
it('should return true if the filter has no meta', () => {
const filter = {};
const indexPattern = { id: 'foo', fields: [{ name: 'bar' }] };

View file

@ -20,9 +20,9 @@
import expect from '@kbn/expect';
import { buildQueryFromFilters } from '../from_filters';
describe('build query', function () {
describe('buildQueryFromFilters', function () {
it('should return the parameters of an Elasticsearch bool query', function () {
describe('build query', function() {
describe('buildQueryFromFilters', function() {
it('should return the parameters of an Elasticsearch bool query', function() {
const result = buildQueryFromFilters([]);
const expected = {
must: [],
@ -33,7 +33,7 @@ describe('build query', function () {
expect(result).to.eql(expected);
});
it('should transform an array of kibana filters into ES queries combined in the bool clauses', function () {
it('should transform an array of kibana filters into ES queries combined in the bool clauses', function() {
const filters = [
{
match_all: {},
@ -45,17 +45,14 @@ describe('build query', function () {
},
];
const expectedESQueries = [
{ match_all: {} },
{ exists: { field: 'foo' } },
];
const expectedESQueries = [{ match_all: {} }, { exists: { field: 'foo' } }];
const result = buildQueryFromFilters(filters);
expect(result.filter).to.eql(expectedESQueries);
});
it('should place negated filters in the must_not clause', function () {
it('should place negated filters in the must_not clause', function() {
const filters = [
{
match_all: {},
@ -70,7 +67,7 @@ describe('build query', function () {
expect(result.must_not).to.eql(expectedESQueries);
});
it('should translate old ES filter syntax into ES 5+ query objects', function () {
it('should translate old ES filter syntax into ES 5+ query objects', function() {
const filters = [
{
query: { exists: { field: 'foo' } },
@ -89,7 +86,7 @@ describe('build query', function () {
expect(result.filter).to.eql(expectedESQueries);
});
it('should migrate deprecated match syntax', function () {
it('should migrate deprecated match syntax', function() {
const filters = [
{
query: { match: { extension: { query: 'foo', type: 'phrase' } } },
@ -108,7 +105,7 @@ describe('build query', function () {
expect(result.filter).to.eql(expectedESQueries);
});
it('should not add query:queryString:options to query_string filters', function () {
it('should not add query:queryString:options to query_string filters', function() {
const filters = [
{
query: { query_string: { query: 'foo' } },

View file

@ -22,9 +22,9 @@ import indexPattern from '../../__fixtures__/index_pattern_response.json';
import expect from '@kbn/expect';
import { fromKueryExpression, toElasticsearchQuery } from '../../kuery';
describe('build query', function () {
describe('buildQueryFromKuery', function () {
it('should return the parameters of an Elasticsearch bool query', function () {
describe('build query', function() {
describe('buildQueryFromKuery', function() {
it('should return the parameters of an Elasticsearch bool query', function() {
const result = buildQueryFromKuery(null, [], true);
const expected = {
must: [],
@ -35,38 +35,12 @@ describe('build query', function () {
expect(result).to.eql(expected);
});
it('should transform an array of kuery queries into ES queries combined in the bool\'s filter clause', function () {
it("should transform an array of kuery queries into ES queries combined in the bool's filter clause", function() {
const queries = [
{ query: 'extension:jpg', language: 'kuery' },
{ query: 'machine.os:osx', language: 'kuery' },
];
const expectedESQueries = queries.map(
(query) => {
return toElasticsearchQuery(fromKueryExpression(query.query), indexPattern);
}
);
const result = buildQueryFromKuery(indexPattern, queries, true);
expect(result.filter).to.eql(expectedESQueries);
});
it('should accept a specific date format for a kuery query into an ES query in the bool\'s filter clause', function () {
const queries = [{ query: '@timestamp:"2018-04-03T19:04:17"', language: 'kuery' }];
const expectedESQueries = queries.map(query => {
return toElasticsearchQuery(fromKueryExpression(query.query), indexPattern, { dateFormatTZ: 'America/Phoenix' });
});
const result = buildQueryFromKuery(indexPattern, queries, true, 'America/Phoenix');
expect(result.filter).to.eql(expectedESQueries);
});
it('should gracefully handle date queries when no date format is provided', function () {
const queries = [{ query: '@timestamp:"2018-04-03T19:04:17Z"', language: 'kuery' }];
const expectedESQueries = queries.map(query => {
return toElasticsearchQuery(fromKueryExpression(query.query), indexPattern);
});
@ -76,6 +50,30 @@ describe('build query', function () {
expect(result.filter).to.eql(expectedESQueries);
});
});
it("should accept a specific date format for a kuery query into an ES query in the bool's filter clause", function() {
const queries = [{ query: '@timestamp:"2018-04-03T19:04:17"', language: 'kuery' }];
const expectedESQueries = queries.map(query => {
return toElasticsearchQuery(fromKueryExpression(query.query), indexPattern, {
dateFormatTZ: 'America/Phoenix',
});
});
const result = buildQueryFromKuery(indexPattern, queries, true, 'America/Phoenix');
expect(result.filter).to.eql(expectedESQueries);
});
it('should gracefully handle date queries when no date format is provided', function() {
const queries = [{ query: '@timestamp:"2018-04-03T19:04:17Z"', language: 'kuery' }];
const expectedESQueries = queries.map(query => {
return toElasticsearchQuery(fromKueryExpression(query.query), indexPattern);
});
const result = buildQueryFromKuery(indexPattern, queries, true);
expect(result.filter).to.eql(expectedESQueries);
});
});
});

View file

@ -22,11 +22,9 @@ import { buildQueryFromLucene } from '../from_lucene';
import { decorateQuery } from '../decorate_query';
import { luceneStringToDsl } from '../lucene_string_to_dsl';
describe('build query', function () {
describe('buildQueryFromLucene', function () {
it('should return the parameters of an Elasticsearch bool query', function () {
describe('build query', function() {
describe('buildQueryFromLucene', function() {
it('should return the parameters of an Elasticsearch bool query', function() {
const result = buildQueryFromLucene();
const expected = {
must: [],
@ -37,51 +35,43 @@ describe('build query', function () {
expect(result).to.eql(expected);
});
it('should transform an array of lucene queries into ES queries combined in the bool\'s must clause', function () {
it("should transform an array of lucene queries into ES queries combined in the bool's must clause", function() {
const queries = [
{ query: 'foo:bar', language: 'lucene' },
{ query: 'bar:baz', language: 'lucene' },
];
const expectedESQueries = queries.map(
(query) => {
return decorateQuery(luceneStringToDsl(query.query), {});
}
);
const expectedESQueries = queries.map(query => {
return decorateQuery(luceneStringToDsl(query.query), {});
});
const result = buildQueryFromLucene(queries, {});
expect(result.must).to.eql(expectedESQueries);
});
it('should also accept queries in ES query DSL format, simply passing them through', function () {
const queries = [
{ query: { match_all: {} }, language: 'lucene' },
];
it('should also accept queries in ES query DSL format, simply passing them through', function() {
const queries = [{ query: { match_all: {} }, language: 'lucene' }];
const result = buildQueryFromLucene(queries, {});
expect(result.must).to.eql([queries[0].query]);
});
});
it('should accept a date format in the decorated queries and combine that into the bool\'s must clause', function () {
it("should accept a date format in the decorated queries and combine that into the bool's must clause", function() {
const queries = [
{ query: 'foo:bar', language: 'lucene' },
{ query: 'bar:baz', language: 'lucene' },
];
const dateFormatTZ = 'America/Phoenix';
const expectedESQueries = queries.map(
(query) => {
return decorateQuery(luceneStringToDsl(query.query), {}, dateFormatTZ);
}
);
const expectedESQueries = queries.map(query => {
return decorateQuery(luceneStringToDsl(query.query), {}, dateFormatTZ);
});
const result = buildQueryFromLucene(queries, {}, dateFormatTZ);
expect(result.must).to.eql(expectedESQueries);
});
});

View file

@ -38,8 +38,8 @@ const config = {
},
};
describe('getEsQueryConfig', function () {
it('should return the parameters of an Elasticsearch query config requested', function () {
describe('getEsQueryConfig', function() {
it('should return the parameters of an Elasticsearch query config requested', function() {
const result = getEsQueryConfig(config);
const expected = {
allowLeadingWildcards: {

View file

@ -20,34 +20,30 @@
import { luceneStringToDsl } from '../lucene_string_to_dsl';
import expect from '@kbn/expect';
describe('build query', function () {
describe('luceneStringToDsl', function () {
it('should wrap strings with an ES query_string query', function () {
describe('build query', function() {
describe('luceneStringToDsl', function() {
it('should wrap strings with an ES query_string query', function() {
const result = luceneStringToDsl('foo:bar');
const expectedResult = {
query_string: { query: 'foo:bar' }
query_string: { query: 'foo:bar' },
};
expect(result).to.eql(expectedResult);
});
it('should return a match_all query for empty strings and whitespace', function () {
it('should return a match_all query for empty strings and whitespace', function() {
const expectedResult = {
match_all: {}
match_all: {},
};
expect(luceneStringToDsl('')).to.eql(expectedResult);
expect(luceneStringToDsl(' ')).to.eql(expectedResult);
});
it('should return non-string arguments without modification', function () {
it('should return non-string arguments without modification', function() {
const expectedResult = {};
const result = luceneStringToDsl(expectedResult);
expect(result).to.be(expectedResult);
expect(result).to.eql(expectedResult);
});
});
});

View file

@ -39,15 +39,29 @@ export function buildEsQuery(
queryStringOptions: {},
ignoreFilterIfFieldNotInIndex: false,
dateFormatTZ: null,
}) {
}
) {
queries = Array.isArray(queries) ? queries : [queries];
filters = Array.isArray(filters) ? filters : [filters];
const validQueries = queries.filter((query) => has(query, 'query'));
const validQueries = queries.filter(query => has(query, 'query'));
const queriesByLanguage = groupBy(validQueries, 'language');
const kueryQuery = buildQueryFromKuery(indexPattern, queriesByLanguage.kuery, config.allowLeadingWildcards, config.dateFormatTZ);
const luceneQuery = buildQueryFromLucene(queriesByLanguage.lucene, config.queryStringOptions, config.dateFormatTZ);
const filterQuery = buildQueryFromFilters(filters, indexPattern, config.ignoreFilterIfFieldNotInIndex);
const kueryQuery = buildQueryFromKuery(
indexPattern,
queriesByLanguage.kuery,
config.allowLeadingWildcards,
config.dateFormatTZ
);
const luceneQuery = buildQueryFromLucene(
queriesByLanguage.lucene,
config.queryStringOptions,
config.dateFormatTZ
);
const filterQuery = buildQueryFromFilters(
filters,
indexPattern,
config.ignoreFilterIfFieldNotInIndex
);
return {
bool: {
@ -55,6 +69,6 @@ export function buildEsQuery(
filter: [].concat(kueryQuery.filter, luceneQuery.filter, filterQuery.filter),
should: [].concat(kueryQuery.should, luceneQuery.should, filterQuery.should),
must_not: [].concat(kueryQuery.must_not, luceneQuery.must_not, filterQuery.must_not),
}
},
};
}

View file

@ -28,8 +28,8 @@ import { filterMatchesIndex } from './filter_matches_index';
* through otherwise it will filter out
* @returns {function}
*/
const filterNegate = function (reverse) {
return function (filter) {
const filterNegate = function(reverse) {
return function(filter) {
if (_.isUndefined(filter.meta) || _.isUndefined(filter.meta.negate)) return !reverse;
return filter.meta && filter.meta.negate === reverse;
};
@ -40,7 +40,7 @@ const filterNegate = function (reverse) {
* @param {Object} filter - The filter to translate
* @return {Object} the query version of that filter
*/
const translateToQuery = function (filter) {
const translateToQuery = function(filter) {
if (!filter) return;
if (filter.query) {
@ -55,7 +55,7 @@ const translateToQuery = function (filter) {
* @param {object} filter The filter to clean
* @returns {object}
*/
const cleanFilter = function (filter) {
const cleanFilter = function(filter) {
return _.omit(filter, ['meta', '$state']);
};

View file

@ -17,13 +17,14 @@
* under the License.
*/
import {
fromKueryExpression,
toElasticsearchQuery,
nodeTypes,
} from '../kuery';
import { fromKueryExpression, toElasticsearchQuery, nodeTypes } from '../kuery';
export function buildQueryFromKuery(indexPattern, queries = [], allowLeadingWildcards, dateFormatTZ = null) {
export function buildQueryFromKuery(
indexPattern,
queries = [],
allowLeadingWildcards,
dateFormatTZ = null
) {
const queryASTs = queries.map(query => {
return fromKueryExpression(query.query, { allowLeadingWildcards });
});
@ -38,6 +39,6 @@ function buildQuery(indexPattern, queryASTs, config = null) {
filter: [],
should: [],
must_not: [],
...kueryQuery.bool
...kueryQuery.bool,
};
}

View file

@ -22,7 +22,7 @@ import { decorateQuery } from './decorate_query';
import { luceneStringToDsl } from './lucene_string_to_dsl';
export function buildQueryFromLucene(queries, queryStringOptions, dateFormatTZ = null) {
const combinedQueries = _.map(queries, (query) => {
const combinedQueries = _.map(queries, query => {
const queryDsl = luceneStringToDsl(query.query);
return decorateQuery(queryDsl, queryStringOptions, dateFormatTZ);
});

View file

@ -24,7 +24,6 @@ export function migrateFilter(filter, indexPattern) {
if (filter.match) {
const fieldName = Object.keys(filter.match)[0];
if (isMatchPhraseFilter(filter, fieldName)) {
const params = _.get(filter, ['match', fieldName]);
if (indexPattern) {

View file

@ -17,7 +17,6 @@
* under the License.
*/
import { buildInlineScriptForPhraseFilter, buildPhraseFilter } from '../phrase';
import expect from '@kbn/expect';
import _ from 'lodash';
@ -26,30 +25,30 @@ import filterSkeleton from '../../__fixtures__/filter_skeleton';
let expected;
describe('Filter Manager', function () {
describe('Phrase filter builder', function () {
describe('Filter Manager', function() {
describe('Phrase filter builder', function() {
beforeEach(() => {
expected = _.cloneDeep(filterSkeleton);
});
it('should be a function', function () {
it('should be a function', function() {
expect(buildPhraseFilter).to.be.a(Function);
});
it('should return a match query filter when passed a standard field', function () {
it('should return a match query filter when passed a standard field', function() {
const field = getField(indexPattern, 'bytes');
expected.query = {
match: {
bytes: {
query: 5,
type: 'phrase'
}
}
type: 'phrase',
},
},
};
expect(buildPhraseFilter(field, 5, indexPattern)).to.eql(expected);
});
it('should return a script filter when passed a scripted field', function () {
it('should return a script filter when passed a scripted field', function() {
const field = getField(indexPattern, 'script number');
expected.meta.field = 'script number';
_.set(expected, 'script.script', {
@ -57,27 +56,27 @@ describe('Filter Manager', function () {
lang: 'expression',
params: {
value: 5,
}
},
});
expect(buildPhraseFilter(field, 5, indexPattern)).to.eql(expected);
});
});
describe('buildInlineScriptForPhraseFilter', function () {
it('should wrap painless scripts in a lambda', function () {
describe('buildInlineScriptForPhraseFilter', function() {
it('should wrap painless scripts in a lambda', function() {
const field = {
lang: 'painless',
script: 'return foo;',
};
const expected = `boolean compare(Supplier s, def v) {return s.get() == v;}` +
`compare(() -> { return foo; }, params.value);`;
const expected =
`boolean compare(Supplier s, def v) {return s.get() == v;}` +
`compare(() -> { return foo; }, params.value);`;
expect(buildInlineScriptForPhraseFilter(field)).to.be(expected);
});
it('should create a simple comparison for other langs', function () {
it('should create a simple comparison for other langs', function() {
const field = {
lang: 'expression',
script: 'doc[bytes].value',

View file

@ -25,22 +25,21 @@ import filterSkeleton from '../../__fixtures__/filter_skeleton';
let expected;
describe('Filter Manager', function () {
describe('Phrase filter builder', function () {
describe('Filter Manager', function() {
describe('Phrase filter builder', function() {
beforeEach(() => {
expected = cloneDeep(filterSkeleton);
});
it('should be a function', function () {
it('should be a function', function() {
expect(buildQueryFilter).to.be.a(Function);
});
it('should return a query filter when passed a standard field', function () {
it('should return a query filter when passed a standard field', function() {
expected.query = {
foo: 'bar'
foo: 'bar',
};
expect(buildQueryFilter({ foo: 'bar' }, indexPattern.id)).to.eql(expected);
});
});
});

View file

@ -25,28 +25,28 @@ import filterSkeleton from '../../__fixtures__/filter_skeleton';
let expected;
describe('Filter Manager', function () {
describe('Range filter builder', function () {
describe('Filter Manager', function() {
describe('Range filter builder', function() {
beforeEach(() => {
expected = _.cloneDeep(filterSkeleton);
});
it('should be a function', function () {
it('should be a function', function() {
expect(buildRangeFilter).to.be.a(Function);
});
it('should return a range filter when passed a standard field', function () {
it('should return a range filter when passed a standard field', function() {
const field = getField(indexPattern, 'bytes');
expected.range = {
bytes: {
gte: 1,
lte: 3
}
lte: 3,
},
};
expect(buildRangeFilter(field, { gte: 1, lte: 3 }, indexPattern)).to.eql(expected);
});
it('should return a script filter when passed a scripted field', function () {
it('should return a script filter when passed a scripted field', function() {
const field = getField(indexPattern, 'script number');
expected.meta.field = 'script number';
_.set(expected, 'script.script', {
@ -55,69 +55,69 @@ describe('Filter Manager', function () {
params: {
value: '>=1 <=3',
gte: 1,
lte: 3
}
lte: 3,
},
});
expect(buildRangeFilter(field, { gte: 1, lte: 3 }, indexPattern)).to.eql(expected);
});
it('should wrap painless scripts in comparator lambdas', function () {
it('should wrap painless scripts in comparator lambdas', function() {
const field = getField(indexPattern, 'script date');
const expected = `boolean gte(Supplier s, def v) {return !s.get().toInstant().isBefore(Instant.parse(v))} ` +
`boolean lte(Supplier s, def v) {return !s.get().toInstant().isAfter(Instant.parse(v))}` +
`gte(() -> { ${field.script} }, params.gte) && ` +
`lte(() -> { ${field.script} }, params.lte)`;
const expected =
`boolean gte(Supplier s, def v) {return !s.get().toInstant().isBefore(Instant.parse(v))} ` +
`boolean lte(Supplier s, def v) {return !s.get().toInstant().isAfter(Instant.parse(v))}` +
`gte(() -> { ${field.script} }, params.gte) && ` +
`lte(() -> { ${field.script} }, params.lte)`;
const inlineScript = buildRangeFilter(field, { gte: 1, lte: 3 }, indexPattern).script.script.source;
const inlineScript = buildRangeFilter(field, { gte: 1, lte: 3 }, indexPattern).script.script
.source;
expect(inlineScript).to.be(expected);
});
it('should throw an error when gte and gt, or lte and lt are both passed', function () {
it('should throw an error when gte and gt, or lte and lt are both passed', function() {
const field = getField(indexPattern, 'script number');
expect(function () {
expect(function() {
buildRangeFilter(field, { gte: 1, gt: 3 }, indexPattern);
}).to.throwError();
expect(function () {
expect(function() {
buildRangeFilter(field, { lte: 1, lt: 3 }, indexPattern);
}).to.throwError();
});
it('to use the right operator for each of gte, gt, lt and lte', function () {
it('to use the right operator for each of gte, gt, lt and lte', function() {
const field = getField(indexPattern, 'script number');
_.each({ gte: '>=', gt: '>', lte: '<=', lt: '<' }, function (operator, key) {
_.each({ gte: '>=', gt: '>', lte: '<=', lt: '<' }, function(operator, key) {
const params = {};
params[key] = 5;
const filter = buildRangeFilter(field, params, indexPattern);
expect(filter.script.script.source).to.be(
'(' + field.script + ')' + operator + key);
expect(filter.script.script.source).to.be('(' + field.script + ')' + operator + key);
expect(filter.script.script.params[key]).to.be(5);
expect(filter.script.script.params.value).to.be(operator + 5);
});
});
describe('when given params where one side is infinite', function () {
describe('when given params where one side is infinite', function() {
const field = getField(indexPattern, 'script number');
let filter;
beforeEach(function () {
beforeEach(function() {
filter = buildRangeFilter(field, { gte: 0, lt: Infinity }, indexPattern);
});
describe('returned filter', function () {
it('is a script filter', function () {
describe('returned filter', function() {
it('is a script filter', function() {
expect(filter).to.have.property('script');
});
it('contain a param for the finite side', function () {
it('contain a param for the finite side', function() {
expect(filter.script.script.params).to.have.property('gte', 0);
});
it('does not contain a param for the infinite side', function () {
it('does not contain a param for the infinite side', function() {
expect(filter.script.script.params).not.to.have.property('lt');
});
it('does not contain a script condition for the infinite side', function () {
it('does not contain a script condition for the infinite side', function() {
const field = getField(indexPattern, 'script number');
const script = field.script;
expect(filter.script.script.source).to.equal(`(${script})>=gte`);
@ -125,25 +125,24 @@ describe('Filter Manager', function () {
});
});
describe('when given params where both sides are infinite', function () {
describe('when given params where both sides are infinite', function() {
const field = getField(indexPattern, 'script number');
let filter;
beforeEach(function () {
filter = buildRangeFilter(
field, { gte: -Infinity, lt: Infinity }, indexPattern);
beforeEach(function() {
filter = buildRangeFilter(field, { gte: -Infinity, lt: Infinity }, indexPattern);
});
describe('returned filter', function () {
it('is a match_all filter', function () {
describe('returned filter', function() {
it('is a match_all filter', function() {
expect(filter).not.to.have.property('script');
expect(filter).to.have.property('match_all');
});
it('does not contain params', function () {
it('does not contain params', function() {
expect(filter).not.to.have.property('params');
});
it('meta field is set to field name', function () {
it('meta field is set to field name', function() {
expect(filter.meta.field).to.equal('script number');
});
});

View file

@ -21,10 +21,10 @@
export function buildExistsFilter(field, indexPattern) {
return {
meta: {
index: indexPattern.id
index: indexPattern.id,
},
exists: {
field: field.name
}
field: field.name,
},
};
}

View file

@ -29,7 +29,7 @@ export function buildPhraseFilter(field, value, indexPattern) {
filter.query = { match: {} };
filter.query.match[field.name] = {
query: convertedValue,
type: 'phrase'
type: 'phrase',
};
}
return filter;
@ -44,9 +44,9 @@ export function getPhraseScript(field, value) {
source: script,
lang: field.lang,
params: {
value: convertedValue
}
}
value: convertedValue,
},
},
};
}
@ -57,11 +57,9 @@ export function getConvertedValueForField(field, value) {
if (typeof value !== 'boolean' && field.type === 'boolean') {
if ([1, 'true'].includes(value)) {
return true;
}
else if ([0, 'false'].includes(value)) {
} else if ([0, 'false'].includes(value)) {
return false;
}
else {
} else {
throw new Error(`${value} is not a valid boolean value for boolean field ${field.name}`);
}
}
@ -79,10 +77,11 @@ export function getConvertedValueForField(field, value) {
export function buildInlineScriptForPhraseFilter(scriptedField) {
// We must wrap painless scripts in a lambda in case they're more than a simple expression
if (scriptedField.lang === 'painless') {
return `boolean compare(Supplier s, def v) {return s.get() == v;}` +
`compare(() -> { ${scriptedField.script} }, params.value);`;
}
else {
return (
`boolean compare(Supplier s, def v) {return s.get() == v;}` +
`compare(() -> { ${scriptedField.script} }, params.value);`
);
} else {
return `(${scriptedField.script}) == value`;
}
}

View file

@ -25,39 +25,35 @@ export function buildPhrasesFilter(field, params, indexPattern) {
const index = indexPattern.id;
const type = 'phrases';
const key = field.name;
const value = params
.map(value => format(field, value))
.join(', ');
const value = params.map(value => format(field, value)).join(', ');
const filter = {
meta: { index, type, key, value, params }
meta: { index, type, key, value, params },
};
let should;
if (field.scripted) {
should = params.map((value) => ({
script: getPhraseScript(field, value)
should = params.map(value => ({
script: getPhraseScript(field, value),
}));
} else {
should = params.map((value) => ({
should = params.map(value => ({
match_phrase: {
[field.name]: value
}
[field.name]: value,
},
}));
}
filter.query = {
bool: {
should,
minimum_should_match: 1
}
minimum_should_match: 1,
},
};
return filter;
}
function format(field, value) {
return field && field.format && field.format.convert
? field.format.convert(value)
: value;
return field && field.format && field.format.convert ? field.format.convert(value) : value;
}

View file

@ -23,7 +23,7 @@ export function buildQueryFilter(query, index, alias) {
query: query,
meta: {
index,
}
},
};
if (alias) {

View file

@ -49,8 +49,8 @@ export function buildRangeFilter(field, params, indexPattern, formattedValue) {
const filter = { meta: { index: indexPattern.id } };
if (formattedValue) filter.meta.formattedValue = formattedValue;
params = _.mapValues(params, (value) => {
return (field.type === 'number') ? parseFloat(value) : value;
params = _.mapValues(params, value => {
return field.type === 'number' ? parseFloat(value) : value;
});
if ('gte' in params && 'gt' in params) throw new Error('gte and gt are mutually exclusive');
@ -88,16 +88,20 @@ export function getRangeScript(field, params) {
const knownParams = _.pick(params, (val, key) => {
return key in operators;
});
let script = _.map(knownParams, function (val, key) {
let script = _.map(knownParams, function(val, key) {
return '(' + field.script + ')' + operators[key] + key;
}).join(' && ');
// We must wrap painless scripts in a lambda in case they're more than a simple expression
if (field.lang === 'painless') {
const comp = field.type === 'date' ? dateComparators : comparators;
const currentComparators = _.reduce(knownParams, (acc, val, key) => acc.concat(comp[key]), []).join(' ');
const currentComparators = _.reduce(
knownParams,
(acc, val, key) => acc.concat(comp[key]),
[]
).join(' ');
const comparisons = _.map(knownParams, function (val, key) {
const comparisons = _.map(knownParams, function(val, key) {
return `${key}(() -> { ${field.script} }, params.${key})`;
}).join(' && ');
@ -108,14 +112,11 @@ export function getRangeScript(field, params) {
script: {
source: script,
params: knownParams,
lang: field.lang
}
lang: field.lang,
},
};
}
function format(field, value) {
return field && field.format && field.format.convert
? field.format.convert(value)
: value;
return field && field.format && field.format.convert ? field.format.convert(value) : value;
}

View file

@ -24,40 +24,37 @@ import indexPatternResponse from '../../../__fixtures__/index_pattern_response.j
let indexPattern;
describe('kuery AST API', function () {
describe('kuery AST API', function() {
beforeEach(() => {
indexPattern = indexPatternResponse;
});
describe('fromKueryExpression', function () {
it('should return a match all "is" function for whitespace', function () {
describe('fromKueryExpression', function() {
it('should return a match all "is" function for whitespace', function() {
const expected = nodeTypes.function.buildNode('is', '*', '*');
const actual = ast.fromKueryExpression(' ');
expect(actual).to.eql(expected);
});
it('should return an "is" function with a null field for single literals', function () {
it('should return an "is" function with a null field for single literals', function() {
const expected = nodeTypes.function.buildNode('is', null, 'foo');
const actual = ast.fromKueryExpression('foo');
expect(actual).to.eql(expected);
});
it('should ignore extraneous whitespace at the beginning and end of the query', function () {
it('should ignore extraneous whitespace at the beginning and end of the query', function() {
const expected = nodeTypes.function.buildNode('is', null, 'foo');
const actual = ast.fromKueryExpression(' foo ');
expect(actual).to.eql(expected);
});
it('should not split on whitespace', function () {
it('should not split on whitespace', function() {
const expected = nodeTypes.function.buildNode('is', null, 'foo bar');
const actual = ast.fromKueryExpression('foo bar');
expect(actual).to.eql(expected);
});
it('should support "and" as a binary operator', function () {
it('should support "and" as a binary operator', function() {
const expected = nodeTypes.function.buildNode('and', [
nodeTypes.function.buildNode('is', null, 'foo'),
nodeTypes.function.buildNode('is', null, 'bar'),
@ -66,7 +63,7 @@ describe('kuery AST API', function () {
expect(actual).to.eql(expected);
});
it('should support "or" as a binary operator', function () {
it('should support "or" as a binary operator', function() {
const expected = nodeTypes.function.buildNode('or', [
nodeTypes.function.buildNode('is', null, 'foo'),
nodeTypes.function.buildNode('is', null, 'bar'),
@ -75,8 +72,9 @@ describe('kuery AST API', function () {
expect(actual).to.eql(expected);
});
it('should support negation of queries with a "not" prefix', function () {
const expected = nodeTypes.function.buildNode('not',
it('should support negation of queries with a "not" prefix', function() {
const expected = nodeTypes.function.buildNode(
'not',
nodeTypes.function.buildNode('or', [
nodeTypes.function.buildNode('is', null, 'foo'),
nodeTypes.function.buildNode('is', null, 'bar'),
@ -86,7 +84,7 @@ describe('kuery AST API', function () {
expect(actual).to.eql(expected);
});
it('"and" should have a higher precedence than "or"', function () {
it('"and" should have a higher precedence than "or"', function() {
const expected = nodeTypes.function.buildNode('or', [
nodeTypes.function.buildNode('is', null, 'foo'),
nodeTypes.function.buildNode('or', [
@ -95,13 +93,13 @@ describe('kuery AST API', function () {
nodeTypes.function.buildNode('is', null, 'baz'),
]),
nodeTypes.function.buildNode('is', null, 'qux'),
])
]),
]);
const actual = ast.fromKueryExpression('foo or bar and baz or qux');
expect(actual).to.eql(expected);
});
it('should support grouping to override default precedence', function () {
it('should support grouping to override default precedence', function() {
const expected = nodeTypes.function.buildNode('and', [
nodeTypes.function.buildNode('or', [
nodeTypes.function.buildNode('is', null, 'foo'),
@ -113,25 +111,25 @@ describe('kuery AST API', function () {
expect(actual).to.eql(expected);
});
it('should support matching against specific fields', function () {
it('should support matching against specific fields', function() {
const expected = nodeTypes.function.buildNode('is', 'foo', 'bar');
const actual = ast.fromKueryExpression('foo:bar');
expect(actual).to.eql(expected);
});
it('should also not split on whitespace when matching specific fields', function () {
it('should also not split on whitespace when matching specific fields', function() {
const expected = nodeTypes.function.buildNode('is', 'foo', 'bar baz');
const actual = ast.fromKueryExpression('foo:bar baz');
expect(actual).to.eql(expected);
});
it('should treat quoted values as phrases', function () {
it('should treat quoted values as phrases', function() {
const expected = nodeTypes.function.buildNode('is', 'foo', 'bar baz', true);
const actual = ast.fromKueryExpression('foo:"bar baz"');
expect(actual).to.eql(expected);
});
it('should support a shorthand for matching multiple values against a single field', function () {
it('should support a shorthand for matching multiple values against a single field', function() {
const expected = nodeTypes.function.buildNode('or', [
nodeTypes.function.buildNode('is', 'foo', 'bar'),
nodeTypes.function.buildNode('is', 'foo', 'baz'),
@ -140,21 +138,19 @@ describe('kuery AST API', function () {
expect(actual).to.eql(expected);
});
it('should support "and" and "not" operators and grouping in the shorthand as well', function () {
it('should support "and" and "not" operators and grouping in the shorthand as well', function() {
const expected = nodeTypes.function.buildNode('and', [
nodeTypes.function.buildNode('or', [
nodeTypes.function.buildNode('is', 'foo', 'bar'),
nodeTypes.function.buildNode('is', 'foo', 'baz'),
]),
nodeTypes.function.buildNode('not',
nodeTypes.function.buildNode('is', 'foo', 'qux')
),
nodeTypes.function.buildNode('not', nodeTypes.function.buildNode('is', 'foo', 'qux')),
]);
const actual = ast.fromKueryExpression('foo:((bar or baz) and not qux)');
expect(actual).to.eql(expected);
});
it('should support exclusive range operators', function () {
it('should support exclusive range operators', function() {
const expected = nodeTypes.function.buildNode('and', [
nodeTypes.function.buildNode('range', 'bytes', {
gt: 1000,
@ -167,7 +163,7 @@ describe('kuery AST API', function () {
expect(actual).to.eql(expected);
});
it('should support inclusive range operators', function () {
it('should support inclusive range operators', function() {
const expected = nodeTypes.function.buildNode('and', [
nodeTypes.function.buildNode('range', 'bytes', {
gte: 1000,
@ -180,29 +176,27 @@ describe('kuery AST API', function () {
expect(actual).to.eql(expected);
});
it('should support wildcards in field names', function () {
it('should support wildcards in field names', function() {
const expected = nodeTypes.function.buildNode('is', 'machine*', 'osx');
const actual = ast.fromKueryExpression('machine*:osx');
expect(actual).to.eql(expected);
});
it('should support wildcards in values', function () {
it('should support wildcards in values', function() {
const expected = nodeTypes.function.buildNode('is', 'foo', 'ba*');
const actual = ast.fromKueryExpression('foo:ba*');
expect(actual).to.eql(expected);
});
it('should create an exists "is" query when a field is given and "*" is the value', function () {
it('should create an exists "is" query when a field is given and "*" is the value', function() {
const expected = nodeTypes.function.buildNode('is', 'foo', '*');
const actual = ast.fromKueryExpression('foo:*');
expect(actual).to.eql(expected);
});
});
describe('fromLiteralExpression', function () {
it('should create literal nodes for unquoted values with correct primitive types', function () {
describe('fromLiteralExpression', function() {
it('should create literal nodes for unquoted values with correct primitive types', function() {
const stringLiteral = nodeTypes.literal.buildNode('foo');
const booleanFalseLiteral = nodeTypes.literal.buildNode(false);
const booleanTrueLiteral = nodeTypes.literal.buildNode(true);
@ -214,43 +208,44 @@ describe('kuery AST API', function () {
expect(ast.fromLiteralExpression('42')).to.eql(numberLiteral);
});
it('should allow escaping of special characters with a backslash', function () {
it('should allow escaping of special characters with a backslash', function() {
const expected = nodeTypes.literal.buildNode('\\():<>"*');
// yo dawg
const actual = ast.fromLiteralExpression('\\\\\\(\\)\\:\\<\\>\\"\\*');
expect(actual).to.eql(expected);
});
it('should support double quoted strings that do not need escapes except for quotes', function () {
it('should support double quoted strings that do not need escapes except for quotes', function() {
const expected = nodeTypes.literal.buildNode('\\():<>"*');
const actual = ast.fromLiteralExpression('"\\():<>\\"*"');
expect(actual).to.eql(expected);
});
it('should support escaped backslashes inside quoted strings', function () {
it('should support escaped backslashes inside quoted strings', function() {
const expected = nodeTypes.literal.buildNode('\\');
const actual = ast.fromLiteralExpression('"\\\\"');
expect(actual).to.eql(expected);
});
it('should detect wildcards and build wildcard AST nodes', function () {
it('should detect wildcards and build wildcard AST nodes', function() {
const expected = nodeTypes.wildcard.buildNode('foo*bar');
const actual = ast.fromLiteralExpression('foo*bar');
expect(actual).to.eql(expected);
});
});
describe('toElasticsearchQuery', function () {
it('should return the given node type\'s ES query representation', function () {
describe('toElasticsearchQuery', function() {
it("should return the given node type's ES query representation", function() {
const node = nodeTypes.function.buildNode('exists', 'response');
const expected = nodeTypes.function.toElasticsearchQuery(node, indexPattern);
const result = ast.toElasticsearchQuery(node, indexPattern);
expect(result).to.eql(expected);
});
it('should return an empty "and" function for undefined nodes and unknown node types', function () {
const expected = nodeTypes.function.toElasticsearchQuery(nodeTypes.function.buildNode('and', []));
it('should return an empty "and" function for undefined nodes and unknown node types', function() {
const expected = nodeTypes.function.toElasticsearchQuery(
nodeTypes.function.buildNode('and', [])
);
expect(ast.toElasticsearchQuery()).to.eql(expected);
@ -263,91 +258,89 @@ describe('kuery AST API', function () {
expect(ast.toElasticsearchQuery(unknownTypeNode)).to.eql(expected);
});
it('should return the given node type\'s ES query representation including a time zone parameter when one is provided', function () {
it("should return the given node type's ES query representation including a time zone parameter when one is provided", function() {
const config = { dateFormatTZ: 'America/Phoenix' };
const node = nodeTypes.function.buildNode('is', '@timestamp', '"2018-04-03T19:04:17"');
const expected = nodeTypes.function.toElasticsearchQuery(node, indexPattern, config);
const result = ast.toElasticsearchQuery(node, indexPattern, config);
expect(result).to.eql(expected);
});
});
describe('doesKueryExpressionHaveLuceneSyntaxError', function () {
it('should return true for Lucene ranges', function () {
describe('doesKueryExpressionHaveLuceneSyntaxError', function() {
it('should return true for Lucene ranges', function() {
const result = ast.doesKueryExpressionHaveLuceneSyntaxError('bar: [1 TO 10]');
expect(result).to.eql(true);
});
it('should return false for KQL ranges', function () {
it('should return false for KQL ranges', function() {
const result = ast.doesKueryExpressionHaveLuceneSyntaxError('bar < 1');
expect(result).to.eql(false);
});
it('should return true for Lucene exists', function () {
it('should return true for Lucene exists', function() {
const result = ast.doesKueryExpressionHaveLuceneSyntaxError('_exists_: bar');
expect(result).to.eql(true);
});
it('should return false for KQL exists', function () {
it('should return false for KQL exists', function() {
const result = ast.doesKueryExpressionHaveLuceneSyntaxError('bar:*');
expect(result).to.eql(false);
});
it('should return true for Lucene wildcards', function () {
it('should return true for Lucene wildcards', function() {
const result = ast.doesKueryExpressionHaveLuceneSyntaxError('bar: ba?');
expect(result).to.eql(true);
});
it('should return false for KQL wildcards', function () {
it('should return false for KQL wildcards', function() {
const result = ast.doesKueryExpressionHaveLuceneSyntaxError('bar: ba*');
expect(result).to.eql(false);
});
it('should return true for Lucene regex', function () {
it('should return true for Lucene regex', function() {
const result = ast.doesKueryExpressionHaveLuceneSyntaxError('bar: /ba.*/');
expect(result).to.eql(true);
});
it('should return true for Lucene fuzziness', function () {
it('should return true for Lucene fuzziness', function() {
const result = ast.doesKueryExpressionHaveLuceneSyntaxError('bar: ba~');
expect(result).to.eql(true);
});
it('should return true for Lucene proximity', function () {
it('should return true for Lucene proximity', function() {
const result = ast.doesKueryExpressionHaveLuceneSyntaxError('bar: "ba"~2');
expect(result).to.eql(true);
});
it('should return true for Lucene boosting', function () {
it('should return true for Lucene boosting', function() {
const result = ast.doesKueryExpressionHaveLuceneSyntaxError('bar: ba^2');
expect(result).to.eql(true);
});
it('should return true for Lucene + operator', function () {
it('should return true for Lucene + operator', function() {
const result = ast.doesKueryExpressionHaveLuceneSyntaxError('+foo: bar');
expect(result).to.eql(true);
});
it('should return true for Lucene - operators', function () {
it('should return true for Lucene - operators', function() {
const result = ast.doesKueryExpressionHaveLuceneSyntaxError('-foo: bar');
expect(result).to.eql(true);
});
it('should return true for Lucene && operators', function () {
it('should return true for Lucene && operators', function() {
const result = ast.doesKueryExpressionHaveLuceneSyntaxError('foo: bar && baz: qux');
expect(result).to.eql(true);
});
it('should return true for Lucene || operators', function () {
it('should return true for Lucene || operators', function() {
const result = ast.doesKueryExpressionHaveLuceneSyntaxError('foo: bar || baz: qux');
expect(result).to.eql(true);
});
it('should return true for mixed KQL/Lucene queries', function () {
it('should return true for mixed KQL/Lucene queries', function() {
const result = ast.doesKueryExpressionHaveLuceneSyntaxError('foo: bar and (baz: qux || bag)');
expect(result).to.eql(true);
});
});
});

View file

@ -76,6 +76,6 @@ export function doesKueryExpressionHaveLuceneSyntaxError(expression) {
fromExpression(expression, { errorOnLuceneSyntax: true }, parseKuery);
return false;
} catch (e) {
return (e.message.startsWith('Lucene'));
return e.message.startsWith('Lucene');
}
}

View file

@ -25,7 +25,6 @@ const endOfInputText = i18n.translate('kbnESQuery.kql.errors.endOfInputText', {
});
export class KQLSyntaxError extends Error {
constructor(error, expression) {
const grammarRuleTranslations = {
fieldName: i18n.translate('kbnESQuery.kql.errors.fieldNameText', {
@ -42,7 +41,7 @@ export class KQLSyntaxError extends Error {
}),
};
const translatedExpectations = error.expected.map((expected) => {
const translatedExpectations = error.expected.map(expected => {
return grammarRuleTranslations[expected.description] || expected.description;
});
@ -56,11 +55,9 @@ export class KQLSyntaxError extends Error {
},
});
const fullMessage = [
message,
expression,
repeat('-', error.location.start.offset) + '^',
].join('\n');
const fullMessage = [message, expression, repeat('-', error.location.start.offset) + '^'].join(
'\n'
);
super(fullMessage);
this.name = 'KQLSyntaxError';

View file

@ -19,87 +19,88 @@
import { fromKueryExpression } from '../ast';
describe('kql syntax errors', () => {
it('should throw an error for a field query missing a value', () => {
expect(() => {
fromKueryExpression('response:');
}).toThrow('Expected "(", value, whitespace but end of input found.\n' +
'response:\n' +
'---------^');
}).toThrow(
'Expected "(", value, whitespace but end of input found.\n' + 'response:\n' + '---------^'
);
});
it('should throw an error for an OR query missing a right side sub-query', () => {
expect(() => {
fromKueryExpression('response:200 or ');
}).toThrow('Expected "(", NOT, field name, value but end of input found.\n' +
'response:200 or \n' +
'----------------^');
}).toThrow(
'Expected "(", NOT, field name, value but end of input found.\n' +
'response:200 or \n' +
'----------------^'
);
});
it('should throw an error for an OR list of values missing a right side sub-query', () => {
expect(() => {
fromKueryExpression('response:(200 or )');
}).toThrow('Expected "(", NOT, value but ")" found.\n' +
'response:(200 or )\n' +
'-----------------^');
}).toThrow(
'Expected "(", NOT, value but ")" found.\n' + 'response:(200 or )\n' + '-----------------^'
);
});
it('should throw an error for a NOT query missing a sub-query', () => {
expect(() => {
fromKueryExpression('response:200 and not ');
}).toThrow('Expected "(", field name, value but end of input found.\n' +
'response:200 and not \n' +
'---------------------^');
}).toThrow(
'Expected "(", field name, value but end of input found.\n' +
'response:200 and not \n' +
'---------------------^'
);
});
it('should throw an error for a NOT list missing a sub-query', () => {
expect(() => {
fromKueryExpression('response:(200 and not )');
}).toThrow('Expected "(", value but ")" found.\n' +
'response:(200 and not )\n' +
'----------------------^');
}).toThrow(
'Expected "(", value but ")" found.\n' +
'response:(200 and not )\n' +
'----------------------^'
);
});
it('should throw an error for unbalanced quotes', () => {
expect(() => {
fromKueryExpression('foo:"ba ');
}).toThrow('Expected "(", value, whitespace but "\"" found.\n' +
'foo:"ba \n' +
'----^');
}).toThrow('Expected "(", value, whitespace but """ found.\n' + 'foo:"ba \n' + '----^');
});
it('should throw an error for unescaped quotes in a quoted string', () => {
expect(() => {
fromKueryExpression('foo:"ba "r"');
}).toThrow('Expected AND, OR, end of input, whitespace but "r" found.\n' +
'foo:"ba "r"\n' +
'---------^');
}).toThrow(
'Expected AND, OR, end of input, whitespace but "r" found.\n' + 'foo:"ba "r"\n' + '---------^'
);
});
it('should throw an error for unescaped special characters in literals', () => {
expect(() => {
fromKueryExpression('foo:ba:r');
}).toThrow('Expected AND, OR, end of input, whitespace but ":" found.\n' +
'foo:ba:r\n' +
'------^');
}).toThrow(
'Expected AND, OR, end of input, whitespace but ":" found.\n' + 'foo:ba:r\n' + '------^'
);
});
it('should throw an error for range queries missing a value', () => {
expect(() => {
fromKueryExpression('foo > ');
}).toThrow('Expected literal, whitespace but end of input found.\n' +
'foo > \n' +
'------^');
}).toThrow('Expected literal, whitespace but end of input found.\n' + 'foo > \n' + '------^');
});
it('should throw an error for range queries missing a field', () => {
expect(() => {
fromKueryExpression('< 1000');
}).toThrow('Expected "(", NOT, end of input, field name, value, whitespace but "<" found.\n' +
'< 1000\n' +
'^');
}).toThrow(
'Expected "(", NOT, end of input, field name, value, whitespace but "<" found.\n' +
'< 1000\n' +
'^'
);
});
});

View file

@ -20,16 +20,14 @@
import expect from '@kbn/expect';
import { convertExistsFilter } from '../exists';
describe('filter to kuery migration', function () {
describe('exists filter', function () {
it('should return a kuery node equivalent to the given filter', function () {
describe('filter to kuery migration', function() {
describe('exists filter', function() {
it('should return a kuery node equivalent to the given filter', function() {
const filter = {
meta: {
type: 'exists',
key: 'foo',
}
},
};
const result = convertExistsFilter(filter);
@ -38,18 +36,16 @@ describe('filter to kuery migration', function () {
expect(result.arguments[0].value).to.be('foo');
});
it('should throw an exception if the given filter is not of type "exists"', function () {
it('should throw an exception if the given filter is not of type "exists"', function() {
const filter = {
meta: {
type: 'foo'
}
type: 'foo',
},
};
expect(convertExistsFilter).withArgs(filter).to.throwException(
/Expected filter of type "exists", got "foo"/
);
expect(convertExistsFilter)
.withArgs(filter)
.to.throwException(/Expected filter of type "exists", got "foo"/);
});
});
});

View file

@ -21,16 +21,14 @@ import _ from 'lodash';
import expect from '@kbn/expect';
import { filterToKueryAST } from '../filter_to_kuery';
describe('filter to kuery migration', function () {
describe('filterToKueryAST', function () {
it('should hand off conversion of known filter types to the appropriate converter', function () {
describe('filter to kuery migration', function() {
describe('filterToKueryAST', function() {
it('should hand off conversion of known filter types to the appropriate converter', function() {
const filter = {
meta: {
type: 'exists',
key: 'foo',
}
},
};
const result = filterToKueryAST(filter);
@ -38,22 +36,24 @@ describe('filter to kuery migration', function () {
expect(result).to.have.property('function', 'exists');
});
it('should thrown an error when an unknown filter type is encountered', function () {
it('should thrown an error when an unknown filter type is encountered', function() {
const filter = {
meta: {
type: 'foo',
}
},
};
expect(filterToKueryAST).withArgs(filter).to.throwException(/Couldn't convert that filter to a kuery/);
expect(filterToKueryAST)
.withArgs(filter)
.to.throwException(/Couldn't convert that filter to a kuery/);
});
it('should wrap the AST node of negated filters in a "not" function', function () {
it('should wrap the AST node of negated filters in a "not" function', function() {
const filter = {
meta: {
type: 'exists',
key: 'foo',
}
},
};
const negatedFilter = _.set(_.cloneDeep(filter), 'meta.negate', true);
@ -64,7 +64,5 @@ describe('filter to kuery migration', function () {
expect(negatedResult).to.have.property('function', 'not');
expect(negatedResult.arguments[0]).to.eql(result);
});
});
});

View file

@ -21,11 +21,9 @@ import _ from 'lodash';
import expect from '@kbn/expect';
import { convertGeoBoundingBox } from '../geo_bounding_box';
describe('filter to kuery migration', function () {
describe('geo_bounding_box filter', function () {
it('should return a kuery node equivalent to the given filter', function () {
describe('filter to kuery migration', function() {
describe('geo_bounding_box filter', function() {
it('should return a kuery node equivalent to the given filter', function() {
const filter = {
meta: {
type: 'geo_bounding_box',
@ -40,14 +38,16 @@ describe('filter to kuery migration', function () {
lon: 40,
},
},
}
},
};
const result = convertGeoBoundingBox(filter);
expect(result).to.have.property('type', 'function');
expect(result).to.have.property('function', 'geoBoundingBox');
const { arguments: [ { value: fieldName }, ...args ] } = result;
const {
arguments: [{ value: fieldName }, ...args],
} = result;
expect(fieldName).to.be('foo');
const argByName = _.mapKeys(args, 'name');
@ -55,18 +55,16 @@ describe('filter to kuery migration', function () {
expect(argByName.bottomRight.value.value).to.be('30, 40');
});
it('should throw an exception if the given filter is not of type "geo_bounding_box"', function () {
it('should throw an exception if the given filter is not of type "geo_bounding_box"', function() {
const filter = {
meta: {
type: 'foo'
}
type: 'foo',
},
};
expect(convertGeoBoundingBox).withArgs(filter).to.throwException(
/Expected filter of type "geo_bounding_box", got "foo"/
);
expect(convertGeoBoundingBox)
.withArgs(filter)
.to.throwException(/Expected filter of type "geo_bounding_box", got "foo"/);
});
});
});

View file

@ -20,11 +20,9 @@
import expect from '@kbn/expect';
import { convertGeoPolygon } from '../geo_polygon';
describe('filter to kuery migration', function () {
describe('geo_polygon filter', function () {
it('should return a kuery node equivalent to the given filter', function () {
describe('filter to kuery migration', function() {
describe('geo_polygon filter', function() {
it('should return a kuery node equivalent to the given filter', function() {
const filter = {
meta: {
type: 'geo_polygon',
@ -39,34 +37,34 @@ describe('filter to kuery migration', function () {
lat: 30,
lon: 40,
},
]
}
}
],
},
},
};
const result = convertGeoPolygon(filter);
expect(result).to.have.property('type', 'function');
expect(result).to.have.property('function', 'geoPolygon');
const { arguments: [ { value: fieldName }, ...args ] } = result;
const {
arguments: [{ value: fieldName }, ...args],
} = result;
expect(fieldName).to.be('foo');
expect(args[0].value).to.be('10, 20');
expect(args[1].value).to.be('30, 40');
});
it('should throw an exception if the given filter is not of type "geo_polygon"', function () {
it('should throw an exception if the given filter is not of type "geo_polygon"', function() {
const filter = {
meta: {
type: 'foo'
}
type: 'foo',
},
};
expect(convertGeoPolygon).withArgs(filter).to.throwException(
/Expected filter of type "geo_polygon", got "foo"/
);
expect(convertGeoPolygon)
.withArgs(filter)
.to.throwException(/Expected filter of type "geo_polygon", got "foo"/);
});
});
});

View file

@ -20,42 +20,40 @@
import expect from '@kbn/expect';
import { convertPhraseFilter } from '../phrase';
describe('filter to kuery migration', function () {
describe('phrase filter', function () {
it('should return a kuery node equivalent to the given filter', function () {
describe('filter to kuery migration', function() {
describe('phrase filter', function() {
it('should return a kuery node equivalent to the given filter', function() {
const filter = {
meta: {
type: 'phrase',
key: 'foo',
params: {
query: 'bar'
query: 'bar',
},
}
},
};
const result = convertPhraseFilter(filter);
expect(result).to.have.property('type', 'function');
expect(result).to.have.property('function', 'is');
const { arguments: [ { value: fieldName }, { value: value } ] } = result;
const {
arguments: [{ value: fieldName }, { value: value }],
} = result;
expect(fieldName).to.be('foo');
expect(value).to.be('bar');
});
it('should throw an exception if the given filter is not of type "phrase"', function () {
it('should throw an exception if the given filter is not of type "phrase"', function() {
const filter = {
meta: {
type: 'foo'
}
type: 'foo',
},
};
expect(convertPhraseFilter).withArgs(filter).to.throwException(
/Expected filter of type "phrase", got "foo"/
);
expect(convertPhraseFilter)
.withArgs(filter)
.to.throwException(/Expected filter of type "phrase", got "foo"/);
});
});
});

View file

@ -21,11 +21,9 @@ import _ from 'lodash';
import expect from '@kbn/expect';
import { convertRangeFilter } from '../range';
describe('filter to kuery migration', function () {
describe('range filter', function () {
it('should return a kuery node equivalent to the given filter', function () {
describe('filter to kuery migration', function() {
describe('range filter', function() {
it('should return a kuery node equivalent to the given filter', function() {
const filter = {
meta: {
type: 'range',
@ -34,14 +32,16 @@ describe('filter to kuery migration', function () {
gt: 1000,
lt: 8000,
},
}
},
};
const result = convertRangeFilter(filter);
expect(result).to.have.property('type', 'function');
expect(result).to.have.property('function', 'range');
const { arguments: [ { value: fieldName }, ...args ] } = result;
const {
arguments: [{ value: fieldName }, ...args],
} = result;
expect(fieldName).to.be('foo');
const argByName = _.mapKeys(args, 'name');
@ -49,18 +49,16 @@ describe('filter to kuery migration', function () {
expect(argByName.lt.value.value).to.be(8000);
});
it('should throw an exception if the given filter is not of type "range"', function () {
it('should throw an exception if the given filter is not of type "range"', function() {
const filter = {
meta: {
type: 'foo'
}
type: 'foo',
},
};
expect(convertRangeFilter).withArgs(filter).to.throwException(
/Expected filter of type "range", got "foo"/
);
expect(convertRangeFilter)
.withArgs(filter)
.to.throwException(/Expected filter of type "range", got "foo"/);
});
});
});

View file

@ -40,8 +40,7 @@ export function filterToKueryAST(filter) {
try {
return converter(filter);
}
catch (ex) {
} catch (ex) {
return null;
}
}, null);

View file

@ -24,6 +24,9 @@ export function convertGeoPolygon(filter) {
throw new Error(`Expected filter of type "geo_polygon", got "${filter.meta.type}"`);
}
const { key, params: { points } } = filter.meta;
const {
key,
params: { points },
} = filter.meta;
return nodeTypes.function.buildNode('geoPolygon', key, points);
}

View file

@ -28,32 +28,33 @@ let indexPattern;
const childNode1 = nodeTypes.function.buildNode('is', 'machine.os', 'osx');
const childNode2 = nodeTypes.function.buildNode('is', 'extension', 'jpg');
describe('kuery functions', function () {
describe('and', function () {
describe('kuery functions', function() {
describe('and', function() {
beforeEach(() => {
indexPattern = indexPatternResponse;
});
describe('buildNodeParams', function () {
it('arguments should contain the unmodified child nodes', function () {
describe('buildNodeParams', function() {
it('arguments should contain the unmodified child nodes', function() {
const result = and.buildNodeParams([childNode1, childNode2]);
const { arguments: [ actualChildNode1, actualChildNode2 ] } = result;
const {
arguments: [actualChildNode1, actualChildNode2],
} = result;
expect(actualChildNode1).to.be(childNode1);
expect(actualChildNode2).to.be(childNode2);
});
});
describe('toElasticsearchQuery', function () {
it('should wrap subqueries in an ES bool query\'s filter clause', function () {
describe('toElasticsearchQuery', function() {
it("should wrap subqueries in an ES bool query's filter clause", function() {
const node = nodeTypes.function.buildNode('and', [childNode1, childNode2]);
const result = and.toElasticsearchQuery(node, indexPattern);
expect(result).to.only.have.keys('bool');
expect(result.bool).to.only.have.keys('filter');
expect(result.bool.filter).to.eql(
[childNode1, childNode2].map((childNode) => ast.toElasticsearchQuery(childNode, indexPattern))
[childNode1, childNode2].map(childNode =>
ast.toElasticsearchQuery(childNode, indexPattern)
)
);
});
});

View file

@ -23,33 +23,33 @@ import { nodeTypes } from '../../node_types';
import _ from 'lodash';
import indexPatternResponse from '../../../__fixtures__/index_pattern_response.json';
let indexPattern;
describe('kuery functions', function () {
describe('exists', function () {
describe('kuery functions', function() {
describe('exists', function() {
beforeEach(() => {
indexPattern = indexPatternResponse;
});
describe('buildNodeParams', function () {
it('should return a single "arguments" param', function () {
describe('buildNodeParams', function() {
it('should return a single "arguments" param', function() {
const result = exists.buildNodeParams('response');
expect(result).to.only.have.key('arguments');
});
it('arguments should contain the provided fieldName as a literal', function () {
const { arguments: [ arg ] } = exists.buildNodeParams('response');
it('arguments should contain the provided fieldName as a literal', function() {
const {
arguments: [arg],
} = exists.buildNodeParams('response');
expect(arg).to.have.property('type', 'literal');
expect(arg).to.have.property('value', 'response');
});
});
describe('toElasticsearchQuery', function () {
it('should return an ES exists query', function () {
describe('toElasticsearchQuery', function() {
it('should return an ES exists query', function() {
const expected = {
exists: { field: 'response' }
exists: { field: 'response' },
};
const existsNode = nodeTypes.function.buildNode('exists', 'response');
@ -57,9 +57,9 @@ describe('kuery functions', function () {
expect(_.isEqual(expected, result)).to.be(true);
});
it('should return an ES exists query without an index pattern', function () {
it('should return an ES exists query without an index pattern', function() {
const expected = {
exists: { field: 'response' }
exists: { field: 'response' },
};
const existsNode = nodeTypes.function.buildNode('exists', 'response');
@ -67,10 +67,11 @@ describe('kuery functions', function () {
expect(_.isEqual(expected, result)).to.be(true);
});
it('should throw an error for scripted fields', function () {
it('should throw an error for scripted fields', function() {
const existsNode = nodeTypes.function.buildNode('exists', 'script string');
expect(exists.toElasticsearchQuery)
.withArgs(existsNode, indexPattern).to.throwException(/Exists query does not support scripted fields/);
.withArgs(existsNode, indexPattern)
.to.throwException(/Exists query does not support scripted fields/);
});
});
});

View file

@ -26,41 +26,43 @@ let indexPattern;
const params = {
bottomRight: {
lat: 50.73,
lon: -135.35
lon: -135.35,
},
topLeft: {
lat: 73.12,
lon: -174.37
}
lon: -174.37,
},
};
describe('kuery functions', function () {
describe('geoBoundingBox', function () {
describe('kuery functions', function() {
describe('geoBoundingBox', function() {
beforeEach(() => {
indexPattern = indexPatternResponse;
});
describe('buildNodeParams', function () {
it('should return an "arguments" param', function () {
describe('buildNodeParams', function() {
it('should return an "arguments" param', function() {
const result = geoBoundingBox.buildNodeParams('geo', params);
expect(result).to.only.have.keys('arguments');
});
it('arguments should contain the provided fieldName as a literal', function () {
it('arguments should contain the provided fieldName as a literal', function() {
const result = geoBoundingBox.buildNodeParams('geo', params);
const { arguments: [ fieldName ] } = result;
const {
arguments: [fieldName],
} = result;
expect(fieldName).to.have.property('type', 'literal');
expect(fieldName).to.have.property('value', 'geo');
});
it('arguments should contain the provided params as named arguments with "lat, lon" string values', function () {
it('arguments should contain the provided params as named arguments with "lat, lon" string values', function() {
const result = geoBoundingBox.buildNodeParams('geo', params);
const { arguments: [ , ...args ] } = result;
const {
arguments: [, ...args],
} = result;
args.map((param) => {
args.map(param => {
expect(param).to.have.property('type', 'namedArg');
expect(['bottomRight', 'topLeft'].includes(param.name)).to.be(true);
expect(param.value.type).to.be('literal');
@ -70,12 +72,10 @@ describe('kuery functions', function () {
expect(param.value.value).to.be(expectedLatLon);
});
});
});
describe('toElasticsearchQuery', function () {
it('should return an ES geo_bounding_box query representing the given node', function () {
describe('toElasticsearchQuery', function() {
it('should return an ES geo_bounding_box query representing the given node', function() {
const node = nodeTypes.function.buildNode('geoBoundingBox', 'geo', params);
const result = geoBoundingBox.toElasticsearchQuery(node, indexPattern);
expect(result).to.have.property('geo_bounding_box');
@ -83,7 +83,7 @@ describe('kuery functions', function () {
expect(result.geo_bounding_box.geo).to.have.property('bottom_right', '50.73, -135.35');
});
it('should return an ES geo_bounding_box query without an index pattern', function () {
it('should return an ES geo_bounding_box query without an index pattern', function() {
const node = nodeTypes.function.buildNode('geoBoundingBox', 'geo', params);
const result = geoBoundingBox.toElasticsearchQuery(node);
expect(result).to.have.property('geo_bounding_box');
@ -91,16 +91,17 @@ describe('kuery functions', function () {
expect(result.geo_bounding_box.geo).to.have.property('bottom_right', '50.73, -135.35');
});
it('should use the ignore_unmapped parameter', function () {
it('should use the ignore_unmapped parameter', function() {
const node = nodeTypes.function.buildNode('geoBoundingBox', 'geo', params);
const result = geoBoundingBox.toElasticsearchQuery(node, indexPattern);
expect(result.geo_bounding_box.ignore_unmapped).to.be(true);
});
it('should throw an error for scripted fields', function () {
it('should throw an error for scripted fields', function() {
const node = nodeTypes.function.buildNode('geoBoundingBox', 'script number', params);
expect(geoBoundingBox.toElasticsearchQuery)
.withArgs(node, indexPattern).to.throwException(/Geo bounding box query does not support scripted fields/);
.withArgs(node, indexPattern)
.to.throwException(/Geo bounding box query does not support scripted fields/);
});
});
});

View file

@ -22,50 +22,49 @@ import * as geoPolygon from '../geo_polygon';
import { nodeTypes } from '../../node_types';
import indexPatternResponse from '../../../__fixtures__/index_pattern_response.json';
let indexPattern;
const points = [
{
lat: 69.77,
lon: -171.56
lon: -171.56,
},
{
lat: 50.06,
lon: -169.10
lon: -169.1,
},
{
lat: 69.16,
lon: -125.85
}
lon: -125.85,
},
];
describe('kuery functions', function () {
describe('geoPolygon', function () {
describe('kuery functions', function() {
describe('geoPolygon', function() {
beforeEach(() => {
indexPattern = indexPatternResponse;
});
describe('buildNodeParams', function () {
it('should return an "arguments" param', function () {
describe('buildNodeParams', function() {
it('should return an "arguments" param', function() {
const result = geoPolygon.buildNodeParams('geo', points);
expect(result).to.only.have.keys('arguments');
});
it('arguments should contain the provided fieldName as a literal', function () {
it('arguments should contain the provided fieldName as a literal', function() {
const result = geoPolygon.buildNodeParams('geo', points);
const { arguments: [ fieldName ] } = result;
const {
arguments: [fieldName],
} = result;
expect(fieldName).to.have.property('type', 'literal');
expect(fieldName).to.have.property('value', 'geo');
});
it('arguments should contain the provided points literal "lat, lon" string values', function () {
it('arguments should contain the provided points literal "lat, lon" string values', function() {
const result = geoPolygon.buildNodeParams('geo', points);
const { arguments: [ , ...args ] } = result;
const {
arguments: [, ...args],
} = result;
args.forEach((param, index) => {
expect(param).to.have.property('type', 'literal');
@ -74,12 +73,10 @@ describe('kuery functions', function () {
expect(param.value).to.be(expectedLatLon);
});
});
});
describe('toElasticsearchQuery', function () {
it('should return an ES geo_polygon query representing the given node', function () {
describe('toElasticsearchQuery', function() {
it('should return an ES geo_polygon query representing the given node', function() {
const node = nodeTypes.function.buildNode('geoPolygon', 'geo', points);
const result = geoPolygon.toElasticsearchQuery(node, indexPattern);
expect(result).to.have.property('geo_polygon');
@ -91,7 +88,7 @@ describe('kuery functions', function () {
});
});
it('should return an ES geo_polygon query without an index pattern', function () {
it('should return an ES geo_polygon query without an index pattern', function() {
const node = nodeTypes.function.buildNode('geoPolygon', 'geo', points);
const result = geoPolygon.toElasticsearchQuery(node);
expect(result).to.have.property('geo_polygon');
@ -103,16 +100,17 @@ describe('kuery functions', function () {
});
});
it('should use the ignore_unmapped parameter', function () {
it('should use the ignore_unmapped parameter', function() {
const node = nodeTypes.function.buildNode('geoPolygon', 'geo', points);
const result = geoPolygon.toElasticsearchQuery(node, indexPattern);
expect(result.geo_polygon.ignore_unmapped).to.be(true);
});
it('should throw an error for scripted fields', function () {
it('should throw an error for scripted fields', function() {
const node = nodeTypes.function.buildNode('geoPolygon', 'script number', points);
expect(geoPolygon.toElasticsearchQuery)
.withArgs(node, indexPattern).to.throwException(/Geo polygon query does not support scripted fields/);
.withArgs(node, indexPattern)
.to.throwException(/Geo polygon query does not support scripted fields/);
});
});
});

View file

@ -24,24 +24,24 @@ import indexPatternResponse from '../../../__fixtures__/index_pattern_response.j
let indexPattern;
describe('kuery functions', function () {
describe('is', function () {
describe('kuery functions', function() {
describe('is', function() {
beforeEach(() => {
indexPattern = indexPatternResponse;
});
describe('buildNodeParams', function () {
it('fieldName and value should be required arguments', function () {
describe('buildNodeParams', function() {
it('fieldName and value should be required arguments', function() {
expect(is.buildNodeParams).to.throwException(/fieldName is a required argument/);
expect(is.buildNodeParams).withArgs('foo').to.throwException(/value is a required argument/);
expect(is.buildNodeParams)
.withArgs('foo')
.to.throwException(/value is a required argument/);
});
it('arguments should contain the provided fieldName and value as literals', function () {
const { arguments: [fieldName, value] } = is.buildNodeParams('response', 200);
it('arguments should contain the provided fieldName and value as literals', function() {
const {
arguments: [fieldName, value],
} = is.buildNodeParams('response', 200);
expect(fieldName).to.have.property('type', 'literal');
expect(fieldName).to.have.property('value', 'response');
@ -50,29 +50,34 @@ describe('kuery functions', function () {
expect(value).to.have.property('value', 200);
});
it('should detect wildcards in the provided arguments', function () {
const { arguments: [fieldName, value] } = is.buildNodeParams('machine*', 'win*');
it('should detect wildcards in the provided arguments', function() {
const {
arguments: [fieldName, value],
} = is.buildNodeParams('machine*', 'win*');
expect(fieldName).to.have.property('type', 'wildcard');
expect(value).to.have.property('type', 'wildcard');
});
it('should default to a non-phrase query', function () {
const { arguments: [, , isPhrase] } = is.buildNodeParams('response', 200);
it('should default to a non-phrase query', function() {
const {
arguments: [, , isPhrase],
} = is.buildNodeParams('response', 200);
expect(isPhrase.value).to.be(false);
});
it('should allow specification of a phrase query', function () {
const { arguments: [, , isPhrase] } = is.buildNodeParams('response', 200, true);
it('should allow specification of a phrase query', function() {
const {
arguments: [, , isPhrase],
} = is.buildNodeParams('response', 200, true);
expect(isPhrase.value).to.be(true);
});
});
describe('toElasticsearchQuery', function () {
it('should return an ES match_all query when fieldName and value are both "*"', function () {
describe('toElasticsearchQuery', function() {
it('should return an ES match_all query when fieldName and value are both "*"', function() {
const expected = {
match_all: {}
match_all: {},
};
const node = nodeTypes.function.buildNode('is', '*', '*');
@ -80,13 +85,13 @@ describe('kuery functions', function () {
expect(result).to.eql(expected);
});
it('should return an ES multi_match query using default_field when fieldName is null', function () {
it('should return an ES multi_match query using default_field when fieldName is null', function() {
const expected = {
multi_match: {
query: 200,
type: 'best_fields',
lenient: true,
}
},
};
const node = nodeTypes.function.buildNode('is', null, 200);
@ -94,11 +99,11 @@ describe('kuery functions', function () {
expect(result).to.eql(expected);
});
it('should return an ES query_string query using default_field when fieldName is null and value contains a wildcard', function () {
it('should return an ES query_string query using default_field when fieldName is null and value contains a wildcard', function() {
const expected = {
query_string: {
query: 'jpg*',
}
},
};
const node = nodeTypes.function.buildNode('is', null, 'jpg*');
@ -106,21 +111,19 @@ describe('kuery functions', function () {
expect(result).to.eql(expected);
});
it('should return an ES bool query with a sub-query for each field when fieldName is "*"', function () {
it('should return an ES bool query with a sub-query for each field when fieldName is "*"', function() {
const node = nodeTypes.function.buildNode('is', '*', 200);
const result = is.toElasticsearchQuery(node, indexPattern);
expect(result).to.have.property('bool');
expect(result.bool.should).to.have.length(indexPattern.fields.length);
});
it('should return an ES exists query when value is "*"', function () {
it('should return an ES exists query when value is "*"', function() {
const expected = {
bool: {
should: [
{ exists: { field: 'extension' } },
],
minimum_should_match: 1
}
should: [{ exists: { field: 'extension' } }],
minimum_should_match: 1,
},
};
const node = nodeTypes.function.buildNode('is', 'extension', '*');
@ -128,14 +131,12 @@ describe('kuery functions', function () {
expect(result).to.eql(expected);
});
it('should return an ES match query when a concrete fieldName and value are provided', function () {
it('should return an ES match query when a concrete fieldName and value are provided', function() {
const expected = {
bool: {
should: [
{ match: { extension: 'jpg' } },
],
minimum_should_match: 1
}
should: [{ match: { extension: 'jpg' } }],
minimum_should_match: 1,
},
};
const node = nodeTypes.function.buildNode('is', 'extension', 'jpg');
@ -143,14 +144,12 @@ describe('kuery functions', function () {
expect(result).to.eql(expected);
});
it('should return an ES match query when a concrete fieldName and value are provided without an index pattern', function () {
it('should return an ES match query when a concrete fieldName and value are provided without an index pattern', function() {
const expected = {
bool: {
should: [
{ match: { extension: 'jpg' } },
],
minimum_should_match: 1
}
should: [{ match: { extension: 'jpg' } }],
minimum_should_match: 1,
},
};
const node = nodeTypes.function.buildNode('is', 'extension', 'jpg');
@ -158,14 +157,12 @@ describe('kuery functions', function () {
expect(result).to.eql(expected);
});
it('should support creation of phrase queries', function () {
it('should support creation of phrase queries', function() {
const expected = {
bool: {
should: [
{ match_phrase: { extension: 'jpg' } },
],
minimum_should_match: 1
}
should: [{ match_phrase: { extension: 'jpg' } }],
minimum_should_match: 1,
},
};
const node = nodeTypes.function.buildNode('is', 'extension', 'jpg', true);
@ -173,19 +170,19 @@ describe('kuery functions', function () {
expect(result).to.eql(expected);
});
it('should create a query_string query for wildcard values', function () {
it('should create a query_string query for wildcard values', function() {
const expected = {
bool: {
should: [
{
query_string: {
fields: ['extension'],
query: 'jpg*'
}
query: 'jpg*',
},
},
],
minimum_should_match: 1
}
minimum_should_match: 1,
},
};
const node = nodeTypes.function.buildNode('is', 'extension', 'jpg*');
@ -193,13 +190,13 @@ describe('kuery functions', function () {
expect(result).to.eql(expected);
});
it('should support scripted fields', function () {
it('should support scripted fields', function() {
const node = nodeTypes.function.buildNode('is', 'script string', 'foo');
const result = is.toElasticsearchQuery(node, indexPattern);
expect(result.bool.should[0]).to.have.key('script');
});
it('should support date fields without a dateFormat provided', function () {
it('should support date fields without a dateFormat provided', function() {
const expected = {
bool: {
should: [
@ -208,12 +205,12 @@ describe('kuery functions', function () {
'@timestamp': {
gte: '2018-04-03T19:04:17',
lte: '2018-04-03T19:04:17',
}
}
}
},
},
},
],
minimum_should_match: 1
}
minimum_should_match: 1,
},
};
const node = nodeTypes.function.buildNode('is', '@timestamp', '"2018-04-03T19:04:17"');
@ -221,7 +218,7 @@ describe('kuery functions', function () {
expect(result).to.eql(expected);
});
it('should support date fields with a dateFormat provided', function () {
it('should support date fields with a dateFormat provided', function() {
const config = { dateFormatTZ: 'America/Phoenix' };
const expected = {
bool: {
@ -232,19 +229,18 @@ describe('kuery functions', function () {
gte: '2018-04-03T19:04:17',
lte: '2018-04-03T19:04:17',
time_zone: 'America/Phoenix',
}
}
}
},
},
},
],
minimum_should_match: 1
}
minimum_should_match: 1,
},
};
const node = nodeTypes.function.buildNode('is', '@timestamp', '"2018-04-03T19:04:17"');
const result = is.toElasticsearchQuery(node, indexPattern, config);
expect(result).to.eql(expected);
});
});
});
});

View file

@ -27,34 +27,29 @@ let indexPattern;
const childNode = nodeTypes.function.buildNode('is', 'extension', 'jpg');
describe('kuery functions', function () {
describe('not', function () {
describe('kuery functions', function() {
describe('not', function() {
beforeEach(() => {
indexPattern = indexPatternResponse;
});
describe('buildNodeParams', function () {
it('arguments should contain the unmodified child node', function () {
const { arguments: [ actualChild ] } = not.buildNodeParams(childNode);
describe('buildNodeParams', function() {
it('arguments should contain the unmodified child node', function() {
const {
arguments: [actualChild],
} = not.buildNodeParams(childNode);
expect(actualChild).to.be(childNode);
});
});
describe('toElasticsearchQuery', function () {
it('should wrap a subquery in an ES bool query\'s must_not clause', function () {
describe('toElasticsearchQuery', function() {
it("should wrap a subquery in an ES bool query's must_not clause", function() {
const node = nodeTypes.function.buildNode('not', childNode);
const result = not.toElasticsearchQuery(node, indexPattern);
expect(result).to.only.have.keys('bool');
expect(result.bool).to.only.have.keys('must_not');
expect(result.bool.must_not).to.eql(ast.toElasticsearchQuery(childNode, indexPattern));
});
});
});
});

View file

@ -28,45 +28,41 @@ let indexPattern;
const childNode1 = nodeTypes.function.buildNode('is', 'machine.os', 'osx');
const childNode2 = nodeTypes.function.buildNode('is', 'extension', 'jpg');
describe('kuery functions', function () {
describe('or', function () {
describe('kuery functions', function() {
describe('or', function() {
beforeEach(() => {
indexPattern = indexPatternResponse;
});
describe('buildNodeParams', function () {
it('arguments should contain the unmodified child nodes', function () {
describe('buildNodeParams', function() {
it('arguments should contain the unmodified child nodes', function() {
const result = or.buildNodeParams([childNode1, childNode2]);
const { arguments: [ actualChildNode1, actualChildNode2 ] } = result;
const {
arguments: [actualChildNode1, actualChildNode2],
} = result;
expect(actualChildNode1).to.be(childNode1);
expect(actualChildNode2).to.be(childNode2);
});
});
describe('toElasticsearchQuery', function () {
it('should wrap subqueries in an ES bool query\'s should clause', function () {
describe('toElasticsearchQuery', function() {
it("should wrap subqueries in an ES bool query's should clause", function() {
const node = nodeTypes.function.buildNode('or', [childNode1, childNode2]);
const result = or.toElasticsearchQuery(node, indexPattern);
expect(result).to.only.have.keys('bool');
expect(result.bool).to.have.keys('should');
expect(result.bool.should).to.eql(
[childNode1, childNode2].map((childNode) => ast.toElasticsearchQuery(childNode, indexPattern))
[childNode1, childNode2].map(childNode =>
ast.toElasticsearchQuery(childNode, indexPattern)
)
);
});
it('should require one of the clauses to match', function () {
it('should require one of the clauses to match', function() {
const node = nodeTypes.function.buildNode('or', [childNode1, childNode2]);
const result = or.toElasticsearchQuery(node, indexPattern);
expect(result.bool).to.have.property('minimum_should_match', 1);
});
});
});
});

View file

@ -24,46 +24,44 @@ import indexPatternResponse from '../../../__fixtures__/index_pattern_response.j
let indexPattern;
describe('kuery functions', function () {
describe('range', function () {
describe('kuery functions', function() {
describe('range', function() {
beforeEach(() => {
indexPattern = indexPatternResponse;
});
describe('buildNodeParams', function () {
it('arguments should contain the provided fieldName as a literal', function () {
describe('buildNodeParams', function() {
it('arguments should contain the provided fieldName as a literal', function() {
const result = range.buildNodeParams('bytes', { gt: 1000, lt: 8000 });
const { arguments: [fieldName] } = result;
const {
arguments: [fieldName],
} = result;
expect(fieldName).to.have.property('type', 'literal');
expect(fieldName).to.have.property('value', 'bytes');
});
it('arguments should contain the provided params as named arguments', function () {
it('arguments should contain the provided params as named arguments', function() {
const givenParams = { gt: 1000, lt: 8000, format: 'epoch_millis' };
const result = range.buildNodeParams('bytes', givenParams);
const { arguments: [, ...params] } = result;
const {
arguments: [, ...params],
} = result;
expect(params).to.be.an('array');
expect(params).to.not.be.empty();
params.map((param) => {
params.map(param => {
expect(param).to.have.property('type', 'namedArg');
expect(['gt', 'lt', 'format'].includes(param.name)).to.be(true);
expect(param.value.type).to.be('literal');
expect(param.value.value).to.be(givenParams[param.name]);
});
});
});
describe('toElasticsearchQuery', function () {
it('should return an ES range query for the node\'s field and params', function () {
describe('toElasticsearchQuery', function() {
it("should return an ES range query for the node's field and params", function() {
const expected = {
bool: {
should: [
@ -71,13 +69,13 @@ describe('kuery functions', function () {
range: {
bytes: {
gt: 1000,
lt: 8000
}
}
}
lt: 8000,
},
},
},
],
minimum_should_match: 1
}
minimum_should_match: 1,
},
};
const node = nodeTypes.function.buildNode('range', 'bytes', { gt: 1000, lt: 8000 });
@ -85,7 +83,7 @@ describe('kuery functions', function () {
expect(result).to.eql(expected);
});
it('should return an ES range query without an index pattern', function () {
it('should return an ES range query without an index pattern', function() {
const expected = {
bool: {
should: [
@ -93,13 +91,13 @@ describe('kuery functions', function () {
range: {
bytes: {
gt: 1000,
lt: 8000
}
}
}
lt: 8000,
},
},
},
],
minimum_should_match: 1
}
minimum_should_match: 1,
},
};
const node = nodeTypes.function.buildNode('range', 'bytes', { gt: 1000, lt: 8000 });
@ -107,7 +105,7 @@ describe('kuery functions', function () {
expect(result).to.eql(expected);
});
it('should support wildcard field names', function () {
it('should support wildcard field names', function() {
const expected = {
bool: {
should: [
@ -115,13 +113,13 @@ describe('kuery functions', function () {
range: {
bytes: {
gt: 1000,
lt: 8000
}
}
}
lt: 8000,
},
},
},
],
minimum_should_match: 1
}
minimum_should_match: 1,
},
};
const node = nodeTypes.function.buildNode('range', 'byt*', { gt: 1000, lt: 8000 });
@ -129,13 +127,13 @@ describe('kuery functions', function () {
expect(result).to.eql(expected);
});
it('should support scripted fields', function () {
it('should support scripted fields', function() {
const node = nodeTypes.function.buildNode('range', 'script number', { gt: 1000, lt: 8000 });
const result = range.toElasticsearchQuery(node, indexPattern);
expect(result.bool.should[0]).to.have.key('script');
});
it('should support date fields without a dateFormat provided', function () {
it('should support date fields without a dateFormat provided', function() {
const expected = {
bool: {
should: [
@ -144,20 +142,23 @@ describe('kuery functions', function () {
'@timestamp': {
gt: '2018-01-03T19:04:17',
lt: '2018-04-03T19:04:17',
}
}
}
},
},
},
],
minimum_should_match: 1
}
minimum_should_match: 1,
},
};
const node = nodeTypes.function.buildNode('range', '@timestamp', { gt: '2018-01-03T19:04:17', lt: '2018-04-03T19:04:17' });
const node = nodeTypes.function.buildNode('range', '@timestamp', {
gt: '2018-01-03T19:04:17',
lt: '2018-04-03T19:04:17',
});
const result = range.toElasticsearchQuery(node, indexPattern);
expect(result).to.eql(expected);
});
it('should support date fields with a dateFormat provided', function () {
it('should support date fields with a dateFormat provided', function() {
const config = { dateFormatTZ: 'America/Phoenix' };
const expected = {
bool: {
@ -168,19 +169,21 @@ describe('kuery functions', function () {
gt: '2018-01-03T19:04:17',
lt: '2018-04-03T19:04:17',
time_zone: 'America/Phoenix',
}
}
}
},
},
},
],
minimum_should_match: 1
}
minimum_should_match: 1,
},
};
const node = nodeTypes.function.buildNode('range', '@timestamp', { gt: '2018-01-03T19:04:17', lt: '2018-04-03T19:04:17' });
const node = nodeTypes.function.buildNode('range', '@timestamp', {
gt: '2018-01-03T19:04:17',
lt: '2018-04-03T19:04:17',
});
const result = range.toElasticsearchQuery(node, indexPattern, config);
expect(result).to.eql(expected);
});
});
});
});

View file

@ -25,23 +25,20 @@ import { nodeTypes } from '../../..';
let indexPattern;
describe('getFields', function () {
describe('getFields', function() {
beforeEach(() => {
indexPattern = indexPatternResponse;
});
describe('field names without a wildcard', function () {
it('should return an empty array if the field does not exist in the index pattern', function () {
describe('field names without a wildcard', function() {
it('should return an empty array if the field does not exist in the index pattern', function() {
const fieldNameNode = nodeTypes.literal.buildNode('nonExistentField');
const expected = [];
const actual = getFields(fieldNameNode, indexPattern);
expect(actual).to.eql(expected);
});
it('should return the single matching field in an array', function () {
it('should return the single matching field in an array', function() {
const fieldNameNode = nodeTypes.literal.buildNode('extension');
const results = getFields(fieldNameNode, indexPattern);
expect(results).to.be.an('array');
@ -49,7 +46,7 @@ describe('getFields', function () {
expect(results[0].name).to.be('extension');
});
it('should not match a wildcard in a literal node', function () {
it('should not match a wildcard in a literal node', function() {
const indexPatternWithWildField = {
title: 'wildIndex',
fields: [
@ -72,26 +69,29 @@ describe('getFields', function () {
});
});
describe('field name patterns with a wildcard', function () {
it('should return an empty array if it does not match any fields in the index pattern', function () {
describe('field name patterns with a wildcard', function() {
it('should return an empty array if it does not match any fields in the index pattern', function() {
const fieldNameNode = nodeTypes.wildcard.buildNode('nonExistent*');
const expected = [];
const actual = getFields(fieldNameNode, indexPattern);
expect(actual).to.eql(expected);
});
it('should return all fields that match the pattern in an array', function () {
it('should return all fields that match the pattern in an array', function() {
const fieldNameNode = nodeTypes.wildcard.buildNode('machine*');
const results = getFields(fieldNameNode, indexPattern);
expect(results).to.be.an('array');
expect(results).to.have.length(2);
expect(results.find((field) => {
return field.name === 'machine.os';
})).to.be.ok();
expect(results.find((field) => {
return field.name === 'machine.os.raw';
})).to.be.ok();
expect(
results.find(field => {
return field.name === 'machine.os';
})
).to.be.ok();
expect(
results.find(field => {
return field.name === 'machine.os.raw';
})
).to.be.ok();
});
});
});

View file

@ -30,10 +30,9 @@ export function toElasticsearchQuery(node, indexPattern, config) {
return {
bool: {
filter: children.map((child) => {
filter: children.map(child => {
return ast.toElasticsearchQuery(child, indexPattern, config);
})
}
}),
},
};
}

View file

@ -27,7 +27,9 @@ export function buildNodeParams(fieldName) {
}
export function toElasticsearchQuery(node, indexPattern) {
const { arguments: [ fieldNameArg ] } = node;
const {
arguments: [fieldNameArg],
} = node;
const fieldName = literal.toElasticsearchQuery(fieldNameArg);
const field = get(indexPattern, 'fields', []).find(field => field.name === fieldName);
@ -35,6 +37,6 @@ export function toElasticsearchQuery(node, indexPattern) {
throw new Error(`Exists query does not support scripted fields`);
}
return {
exists: { field: fieldName }
exists: { field: fieldName },
};
}

View file

@ -35,7 +35,7 @@ export function buildNodeParams(fieldName, params) {
}
export function toElasticsearchQuery(node, indexPattern) {
const [ fieldNameArg, ...args ] = node.arguments;
const [fieldNameArg, ...args] = node.arguments;
const fieldName = nodeTypes.literal.toElasticsearchQuery(fieldNameArg);
const field = _.get(indexPattern, 'fields', []).find(field => field.name === fieldName);
const queryParams = args.reduce((acc, arg) => {
@ -57,4 +57,3 @@ export function toElasticsearchQuery(node, indexPattern) {
},
};
}

View file

@ -23,7 +23,7 @@ import * as ast from '../ast';
export function buildNodeParams(fieldName, points) {
const fieldNameArg = nodeTypes.literal.buildNode(fieldName);
const args = points.map((point) => {
const args = points.map(point => {
const latLon = `${point.lat}, ${point.lon}`;
return nodeTypes.literal.buildNode(latLon);
});
@ -34,11 +34,11 @@ export function buildNodeParams(fieldName, points) {
}
export function toElasticsearchQuery(node, indexPattern) {
const [ fieldNameArg, ...points ] = node.arguments;
const [fieldNameArg, ...points] = node.arguments;
const fieldName = nodeTypes.literal.toElasticsearchQuery(fieldNameArg);
const field = get(indexPattern, 'fields', []).find(field => field.name === fieldName);
const queryParams = {
points: points.map(ast.toElasticsearchQuery)
points: points.map(ast.toElasticsearchQuery),
};
if (field && field.scripted) {

View file

@ -32,8 +32,12 @@ export function buildNodeParams(fieldName, value, isPhrase = false) {
if (_.isUndefined(value)) {
throw new Error('value is a required argument');
}
const fieldNode = typeof fieldName === 'string' ? ast.fromLiteralExpression(fieldName) : literal.buildNode(fieldName);
const valueNode = typeof value === 'string' ? ast.fromLiteralExpression(value) : literal.buildNode(value);
const fieldNode =
typeof fieldName === 'string'
? ast.fromLiteralExpression(fieldName)
: literal.buildNode(fieldName);
const valueNode =
typeof value === 'string' ? ast.fromLiteralExpression(value) : literal.buildNode(value);
const isPhraseNode = literal.buildNode(isPhrase);
return {
arguments: [fieldNode, valueNode, isPhraseNode],
@ -41,7 +45,9 @@ export function buildNodeParams(fieldName, value, isPhrase = false) {
}
export function toElasticsearchQuery(node, indexPattern = null, config = {}) {
const { arguments: [fieldNameArg, valueArg, isPhraseArg] } = node;
const {
arguments: [fieldNameArg, valueArg, isPhraseArg],
} = node;
const fieldName = ast.toElasticsearchQuery(fieldNameArg);
const value = !_.isUndefined(valueArg) ? ast.toElasticsearchQuery(valueArg) : valueArg;
const type = isPhraseArg.value ? 'phrase' : 'best_fields';
@ -59,7 +65,7 @@ export function toElasticsearchQuery(node, indexPattern = null, config = {}) {
type,
query: value,
lenient: true,
}
},
};
}
@ -78,8 +84,8 @@ export function toElasticsearchQuery(node, indexPattern = null, config = {}) {
const isExistsQuery = valueArg.type === 'wildcard' && value === '*';
const isAllFieldsQuery =
(fieldNameArg.type === 'wildcard' && fieldName === '*')
|| (fields && indexPattern && fields.length === indexPattern.fields.length);
(fieldNameArg.type === 'wildcard' && fieldName === '*') ||
(fields && indexPattern && fields.length === indexPattern.fields.length);
const isMatchAllQuery = isExistsQuery && isAllFieldsQuery;
if (isMatchAllQuery) {
@ -90,60 +96,71 @@ export function toElasticsearchQuery(node, indexPattern = null, config = {}) {
if (field.scripted) {
// Exists queries don't make sense for scripted fields
if (!isExistsQuery) {
return [...accumulator, {
script: {
...getPhraseScript(field, value)
}
}];
return [
...accumulator,
{
script: {
...getPhraseScript(field, value),
},
},
];
}
}
else if (isExistsQuery) {
return [...accumulator, {
exists: {
field: field.name
}
}];
}
else if (valueArg.type === 'wildcard') {
return [...accumulator, {
query_string: {
fields: [field.name],
query: wildcard.toQueryStringQuery(valueArg),
}
}];
}
/*
} else if (isExistsQuery) {
return [
...accumulator,
{
exists: {
field: field.name,
},
},
];
} else if (valueArg.type === 'wildcard') {
return [
...accumulator,
{
query_string: {
fields: [field.name],
query: wildcard.toQueryStringQuery(valueArg),
},
},
];
} else if (field.type === 'date') {
/*
If we detect that it's a date field and the user wants an exact date, we need to convert the query to both >= and <= the value provided to force a range query. This is because match and match_phrase queries do not accept a timezone parameter.
dateFormatTZ can have the value of 'Browser', in which case we guess the timezone using moment.tz.guess.
*/
else if (field.type === 'date') {
const timeZoneParam = config.dateFormatTZ ? { time_zone: getTimeZoneFromSettings(config.dateFormatTZ) } : {};
return [...accumulator, {
range: {
[field.name]: {
gte: value,
lte: value,
...timeZoneParam,
const timeZoneParam = config.dateFormatTZ
? { time_zone: getTimeZoneFromSettings(config.dateFormatTZ) }
: {};
return [
...accumulator,
{
range: {
[field.name]: {
gte: value,
lte: value,
...timeZoneParam,
},
},
}
}];
}
else {
},
];
} else {
const queryType = type === 'phrase' ? 'match_phrase' : 'match';
return [...accumulator, {
[queryType]: {
[field.name]: value
}
}];
return [
...accumulator,
{
[queryType]: {
[field.name]: value,
},
},
];
}
}, []);
return {
bool: {
should: queries,
minimum_should_match: 1
}
minimum_should_match: 1,
},
};
}

View file

@ -26,12 +26,11 @@ export function buildNodeParams(child) {
}
export function toElasticsearchQuery(node, indexPattern, config) {
const [ argument ] = node.arguments;
const [argument] = node.arguments;
return {
bool: {
must_not: ast.toElasticsearchQuery(argument, indexPattern, config)
}
must_not: ast.toElasticsearchQuery(argument, indexPattern, config),
},
};
}

View file

@ -30,7 +30,7 @@ export function toElasticsearchQuery(node, indexPattern, config) {
return {
bool: {
should: children.map((child) => {
should: children.map(child => {
return ast.toElasticsearchQuery(child, indexPattern, config);
}),
minimum_should_match: 1,

View file

@ -26,7 +26,10 @@ import { getTimeZoneFromSettings } from '../../utils/get_time_zone_from_settings
export function buildNodeParams(fieldName, params) {
params = _.pick(params, 'gt', 'lt', 'gte', 'lte', 'format');
const fieldNameArg = typeof fieldName === 'string' ? ast.fromLiteralExpression(fieldName) : nodeTypes.literal.buildNode(fieldName);
const fieldNameArg =
typeof fieldName === 'string'
? ast.fromLiteralExpression(fieldName)
: nodeTypes.literal.buildNode(fieldName);
const args = _.map(params, (value, key) => {
return nodeTypes.namedArg.buildNode(key, value);
});
@ -37,7 +40,7 @@ export function buildNodeParams(fieldName, params) {
}
export function toElasticsearchQuery(node, indexPattern = null, config = {}) {
const [ fieldNameArg, ...args ] = node.arguments;
const [fieldNameArg, ...args] = node.arguments;
const fields = indexPattern ? getFields(fieldNameArg, indexPattern) : [];
const namedArgs = extractArguments(args);
const queryParams = _.mapValues(namedArgs, ast.toElasticsearchQuery);
@ -54,36 +57,36 @@ export function toElasticsearchQuery(node, indexPattern = null, config = {}) {
});
}
const queries = fields.map((field) => {
const queries = fields.map(field => {
if (field.scripted) {
return {
script: getRangeScript(field, queryParams),
};
}
else if (field.type === 'date') {
const timeZoneParam = config.dateFormatTZ ? { time_zone: getTimeZoneFromSettings(config.dateFormatTZ) } : {};
} else if (field.type === 'date') {
const timeZoneParam = config.dateFormatTZ
? { time_zone: getTimeZoneFromSettings(config.dateFormatTZ) }
: {};
return {
range: {
[field.name]: {
...queryParams,
...timeZoneParam,
}
}
},
},
};
}
return {
range: {
[field.name]: queryParams
}
[field.name]: queryParams,
},
};
});
return {
bool: {
should: queries,
minimum_should_match: 1
}
minimum_should_match: 1,
},
};
}
@ -97,8 +100,7 @@ function extractArguments(args) {
return args.reduce((acc, arg, index) => {
if (arg.type === 'namedArg') {
acc[arg.name] = arg.value;
}
else {
} else {
acc[unnamedArgOrder[index]] = arg;
}

View file

@ -25,30 +25,25 @@ import indexPatternResponse from '../../../__fixtures__/index_pattern_response.j
import { nodeTypes } from '../../node_types';
describe('kuery node types', function () {
describe('function', function () {
describe('kuery node types', function() {
describe('function', function() {
let indexPattern;
beforeEach(() => {
indexPattern = indexPatternResponse;
});
describe('buildNode', function () {
it('should return a node representing the given kuery function', function () {
describe('buildNode', function() {
it('should return a node representing the given kuery function', function() {
const result = functionType.buildNode('is', 'extension', 'jpg');
expect(result).to.have.property('type', 'function');
expect(result).to.have.property('function', 'is');
expect(result).to.have.property('arguments');
});
});
describe('buildNodeWithArgumentNodes', function () {
it('should return a function node with the given argument list untouched', function () {
describe('buildNodeWithArgumentNodes', function() {
it('should return a function node with the given argument list untouched', function() {
const fieldNameLiteral = nodeTypes.literal.buildNode('extension');
const valueLiteral = nodeTypes.literal.buildNode('jpg');
const argumentNodes = [fieldNameLiteral, valueLiteral];
@ -60,21 +55,15 @@ describe('kuery node types', function () {
expect(result.arguments).to.be(argumentNodes);
expect(result.arguments).to.eql(argumentNodes);
});
});
describe('toElasticsearchQuery', function () {
it('should return the given function type\'s ES query representation', function () {
describe('toElasticsearchQuery', function() {
it("should return the given function type's ES query representation", function() {
const node = functionType.buildNode('is', 'extension', 'jpg');
const expected = isFunction.toElasticsearchQuery(node, indexPattern);
const result = functionType.toElasticsearchQuery(node, indexPattern);
expect(_.isEqual(expected, result)).to.be(true);
});
});
});
});

View file

@ -20,31 +20,22 @@
import expect from '@kbn/expect';
import * as literal from '../literal';
describe('kuery node types', function () {
describe('literal', function () {
describe('buildNode', function () {
it('should return a node representing the given value', function () {
describe('kuery node types', function() {
describe('literal', function() {
describe('buildNode', function() {
it('should return a node representing the given value', function() {
const result = literal.buildNode('foo');
expect(result).to.have.property('type', 'literal');
expect(result).to.have.property('value', 'foo');
});
});
describe('toElasticsearchQuery', function () {
it('should return the literal value represented by the given node', function () {
describe('toElasticsearchQuery', function() {
it('should return the literal value represented by the given node', function() {
const node = literal.buildNode('foo');
const result = literal.toElasticsearchQuery(node);
expect(result).to.be('foo');
});
});
});
});

View file

@ -21,13 +21,10 @@ import expect from '@kbn/expect';
import * as namedArg from '../named_arg';
import { nodeTypes } from '../../node_types';
describe('kuery node types', function () {
describe('named arg', function () {
describe('buildNode', function () {
it('should return a node representing a named argument with the given value', function () {
describe('kuery node types', function() {
describe('named arg', function() {
describe('buildNode', function() {
it('should return a node representing a named argument with the given value', function() {
const result = namedArg.buildNode('fieldName', 'foo');
expect(result).to.have.property('type', 'namedArg');
expect(result).to.have.property('name', 'fieldName');
@ -38,25 +35,20 @@ describe('kuery node types', function () {
expect(literalValue).to.have.property('value', 'foo');
});
it('should support literal nodes as values', function () {
it('should support literal nodes as values', function() {
const value = nodeTypes.literal.buildNode('foo');
const result = namedArg.buildNode('fieldName', value);
expect(result.value).to.be(value);
expect(result.value).to.eql(value);
});
});
describe('toElasticsearchQuery', function () {
it('should return the argument value represented by the given node', function () {
describe('toElasticsearchQuery', function() {
it('should return the argument value represented by the given node', function() {
const node = namedArg.buildNode('fieldName', 'foo');
const result = namedArg.toElasticsearchQuery(node);
expect(result).to.be('foo');
});
});
});
});

View file

@ -20,56 +20,47 @@
import expect from '@kbn/expect';
import * as wildcard from '../wildcard';
describe('kuery node types', function () {
describe('wildcard', function () {
describe('buildNode', function () {
it('should accept a string argument representing a wildcard string', function () {
describe('kuery node types', function() {
describe('wildcard', function() {
describe('buildNode', function() {
it('should accept a string argument representing a wildcard string', function() {
const wildcardValue = `foo${wildcard.wildcardSymbol}bar`;
const result = wildcard.buildNode(wildcardValue);
expect(result).to.have.property('type', 'wildcard');
expect(result).to.have.property('value', wildcardValue);
});
it('should accept and parse a wildcard string', function () {
it('should accept and parse a wildcard string', function() {
const result = wildcard.buildNode('foo*bar');
expect(result).to.have.property('type', 'wildcard');
expect(result.value).to.be(`foo${wildcard.wildcardSymbol}bar`);
});
});
describe('toElasticsearchQuery', function () {
it('should return the string representation of the wildcard literal', function () {
describe('toElasticsearchQuery', function() {
it('should return the string representation of the wildcard literal', function() {
const node = wildcard.buildNode('foo*bar');
const result = wildcard.toElasticsearchQuery(node);
expect(result).to.be('foo*bar');
});
});
describe('toQueryStringQuery', function () {
it('should return the string representation of the wildcard literal', function () {
describe('toQueryStringQuery', function() {
it('should return the string representation of the wildcard literal', function() {
const node = wildcard.buildNode('foo*bar');
const result = wildcard.toQueryStringQuery(node);
expect(result).to.be('foo*bar');
});
it('should escape query_string query special characters other than wildcard', function () {
it('should escape query_string query special characters other than wildcard', function() {
const node = wildcard.buildNode('+foo*bar');
const result = wildcard.toQueryStringQuery(node);
expect(result).to.be('\\+foo*bar');
});
});
describe('test', function () {
it('should return a boolean indicating whether the string matches the given wildcard node', function () {
describe('test', function() {
it('should return a boolean indicating whether the string matches the given wildcard node', function() {
const node = wildcard.buildNode('foo*bar');
expect(wildcard.test(node, 'foobar')).to.be(true);
expect(wildcard.test(node, 'foobazbar')).to.be(true);
@ -79,15 +70,15 @@ describe('kuery node types', function () {
expect(wildcard.test(node, 'bazbar')).to.be(false);
});
it('should return a true even when the string has newlines or tabs', function () {
it('should return a true even when the string has newlines or tabs', function() {
const node = wildcard.buildNode('foo*bar');
expect(wildcard.test(node, 'foo\nbar')).to.be(true);
expect(wildcard.test(node, 'foo\tbar')).to.be(true);
});
});
describe('hasLeadingWildcard', function () {
it('should determine whether a wildcard node contains a leading wildcard', function () {
describe('hasLeadingWildcard', function() {
it('should determine whether a wildcard node contains a leading wildcard', function() {
const node = wildcard.buildNode('foo*bar');
expect(wildcard.hasLeadingWildcard(node)).to.be(false);
@ -96,12 +87,10 @@ describe('kuery node types', function () {
});
// Lone wildcards become exists queries, so we aren't worried about their performance
it('should not consider a lone wildcard to be a leading wildcard', function () {
it('should not consider a lone wildcard to be a leading wildcard', function() {
const leadingWildcardNode = wildcard.buildNode('*');
expect(wildcard.hasLeadingWildcard(leadingWildcardNode)).to.be(false);
});
});
});
});

View file

@ -21,7 +21,6 @@ import _ from 'lodash';
import { functions } from '../functions';
export function buildNode(functionName, ...functionArgs) {
const kueryFunction = functions[functionName];
if (_.isUndefined(kueryFunction)) {
throw new Error(`Unknown function "${functionName}"`);
@ -30,7 +29,7 @@ export function buildNode(functionName, ...functionArgs) {
return {
type: 'function',
function: functionName,
...kueryFunction.buildNodeParams(...functionArgs)
...kueryFunction.buildNodeParams(...functionArgs),
};
}
@ -51,4 +50,3 @@ export function toElasticsearchQuery(node, indexPattern, config = {}) {
const kueryFunction = functions[node.function];
return kueryFunction.toElasticsearchQuery(node, indexPattern, config);
}

View file

@ -27,4 +27,3 @@ export function buildNode(value) {
export function toElasticsearchQuery(node) {
return node.value;
}

View file

@ -22,7 +22,8 @@ import * as ast from '../ast';
import { nodeTypes } from '../node_types';
export function buildNode(name, value) {
const argumentNode = (_.get(value, 'type') === 'literal') ? value : nodeTypes.literal.buildNode(value);
const argumentNode =
_.get(value, 'type') === 'literal' ? value : nodeTypes.literal.buildNode(value);
return {
type: 'namedArg',
name,
@ -33,4 +34,3 @@ export function buildNode(name, value) {
export function toElasticsearchQuery(node) {
return ast.toElasticsearchQuery(node.value);
}

View file

@ -69,8 +69,5 @@ export function hasLeadingWildcard(node) {
const { value } = node;
// A lone wildcard turns into an `exists` query, so we're only concerned with
// leading wildcards followed by additional characters.
return (
value.startsWith(wildcardSymbol) &&
value.replace(wildcardSymbol, '').length > 0
);
return value.startsWith(wildcardSymbol) && value.replace(wildcardSymbol, '').length > 0;
}

View file

@ -20,17 +20,14 @@
import expect from '@kbn/expect';
import { getTimeZoneFromSettings } from '../get_time_zone_from_settings';
describe('get timezone from settings', function () {
it('should return the config timezone if the time zone is set', function () {
describe('get timezone from settings', function() {
it('should return the config timezone if the time zone is set', function() {
const result = getTimeZoneFromSettings('America/Chicago');
expect(result).to.eql('America/Chicago');
});
it('should return the system timezone if the time zone is set to "Browser"', function () {
it('should return the system timezone if the time zone is set to "Browser"', function() {
const result = getTimeZoneFromSettings('Browser');
expect(result).to.not.equal('Browser');
});
});

View file

@ -17,7 +17,6 @@
* under the License.
*/
/**
* Add a new set of registries to an existing set of registries.
*

View file

@ -24,27 +24,19 @@ const del = require('del');
const supportsColor = require('supports-color');
const { ToolingLog, withProcRunner, pickLevelFromFlags } = require('@kbn/dev-utils');
const {
ROOT_DIR,
BUILD_DIR,
} = require('./paths');
const { ROOT_DIR, BUILD_DIR } = require('./paths');
const unknownFlags = [];
const flags = getopts(process.argv, {
boolean: [
'watch',
'dev',
'help',
'debug'
],
boolean: ['watch', 'dev', 'help', 'debug'],
unknown(name) {
unknownFlags.push(name);
}
},
});
const log = new ToolingLog({
level: pickLevelFromFlags(flags),
writeTo: process.stdout
writeTo: process.stdout,
});
if (unknownFlags.length) {
@ -64,7 +56,7 @@ if (flags.help) {
process.exit();
}
withProcRunner(log, async (proc) => {
withProcRunner(log, async proc => {
log.info('Deleting old output');
await del(BUILD_DIR);
@ -80,20 +72,22 @@ withProcRunner(log, async (proc) => {
cmd: 'babel',
args: [
'src',
'--ignore', `*.test.js`,
'--out-dir', relative(cwd, BUILD_DIR),
'--ignore',
`*.test.js`,
'--out-dir',
relative(cwd, BUILD_DIR),
'--copy-files',
...(flags.dev ? ['--source-maps', 'inline'] : []),
...(flags.watch ? ['--watch'] : ['--quiet'])
...(flags.watch ? ['--watch'] : ['--quiet']),
],
wait: true,
env,
cwd
cwd,
}),
]);
log.success('Complete');
}).catch((error) => {
}).catch(error => {
log.error(error);
process.exit(1);
});

View file

@ -24,4 +24,3 @@ exports.SOURCE_DIR = resolve(exports.ROOT_DIR, 'src');
exports.BUILD_DIR = resolve(exports.ROOT_DIR, 'target');
exports.BABEL_PRESET_PATH = require.resolve('@kbn/babel-preset/webpack_preset');

View file

@ -21,7 +21,7 @@ const { extname } = require('path');
const { transform } = require('@babel/core');
exports.createServerCodeTransformer = (sourceMaps) => {
exports.createServerCodeTransformer = sourceMaps => {
return (content, path) => {
switch (extname(path)) {
case '.js':

View file

@ -17,7 +17,6 @@
* under the License.
*/
const fs = require('fs');
const path = require('path');
const program = require('commander');
@ -48,7 +47,7 @@ files.forEach(file => {
try {
fs.mkdirSync(program.directory, { recursive: true });
fs.writeFileSync(outputPath, output + '\n');
} catch(e) {
} catch (e) {
console.log('Cannot write file ', e);
}
} else {

View file

@ -17,6 +17,5 @@
* under the License.
*/
const convert = require('./lib/convert');
module.exports = convert;

View file

@ -17,7 +17,6 @@
* under the License.
*/
const convert = require('./convert');
const clusterHealthSpec = require('../test/fixtures/cluster_health_spec');

View file

@ -17,7 +17,6 @@
* under the License.
*/
module.exports = methods => {
return methods;
};

View file

@ -17,7 +17,6 @@
* under the License.
*/
module.exports = params => {
const result = {};
Object.keys(params).forEach(param => {

View file

@ -26,7 +26,7 @@ const debounce = require('lodash/function/debounce');
const platform = require('os').platform();
const isPlatformWindows = /^win/.test(platform);
module.exports = function (grunt) {
module.exports = function(grunt) {
grunt.initConfig({
clean: {
target: ['target'],
@ -43,23 +43,18 @@ module.exports = function (grunt) {
'!**/__snapshots__/**/*',
],
dest: 'target',
}
},
},
babel: {
prodBuild: {
expand: true,
src: [
'target/components/**/*.js',
'target/src/**/*.js',
],
src: ['target/components/**/*.js', 'target/src/**/*.js'],
dest: '.',
options: {
presets: [
require.resolve('@kbn/babel-preset/webpack_preset')
]
presets: [require.resolve('@kbn/babel-preset/webpack_preset')],
},
}
}
},
},
});
grunt.loadNpmTasks('grunt-babel');
@ -67,7 +62,7 @@ module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.registerTask('prodBuild', ['clean:target', 'copy:makeProdBuild', 'babel:prodBuild']);
grunt.registerTask('docSiteBuild', function () {
grunt.registerTask('docSiteBuild', function() {
const done = this.async();
const serverCmd = {
@ -77,7 +72,7 @@ module.exports = function (grunt) {
'--config=doc_site/webpack.config.js',
'--devtool=null', // Prevent the source map from being generated
],
opts: { stdio: 'inherit' }
opts: { stdio: 'inherit' },
};
const uiFrameworkServerBuild = new Promise((resolve, reject) => {
@ -99,24 +94,26 @@ module.exports = function (grunt) {
uiFrameworkServerBuild.then(done);
});
grunt.registerTask('docSiteStart', function () {
grunt.registerTask('docSiteStart', function() {
const done = this.async();
Promise.all([uiFrameworkWatch(), uiFrameworkServerStart()]).then(done);
});
grunt.registerTask('compileCssLight', function () {
grunt.registerTask('compileCssLight', function() {
const done = this.async();
uiFrameworkCompileLight().then(done);
});
grunt.registerTask('compileCssDark', function () {
grunt.registerTask('compileCssDark', function() {
const done = this.async();
uiFrameworkCompileDark().then(done);
});
function uiFrameworkServerStart() {
const serverCmd = {
cmd: isPlatformWindows ? '.\\node_modules\\.bin\\webpack-dev-server.cmd' : './node_modules/.bin/webpack-dev-server',
cmd: isPlatformWindows
? '.\\node_modules\\.bin\\webpack-dev-server.cmd'
: './node_modules/.bin/webpack-dev-server',
args: [
'--config=doc_site/webpack.config.js',
'--hot',
@ -125,7 +122,7 @@ module.exports = function (grunt) {
'--host=0.0.0.0',
'--port=8020',
],
opts: { stdio: 'inherit' }
opts: { stdio: 'inherit' },
};
return new Promise((resolve, reject) => {
@ -142,7 +139,6 @@ module.exports = function (grunt) {
resolve();
});
});
}
@ -151,25 +147,28 @@ module.exports = function (grunt) {
const dest = 'dist/kui_light.css';
return new Promise(resolve => {
sass.render({
file: src,
}, function (error, result) {
if (error) {
grunt.log.error(error);
sass.render(
{
file: src,
},
function(error, result) {
if (error) {
grunt.log.error(error);
}
postcss([postcssConfig])
.process(result.css, { from: src, to: dest })
.then(result => {
grunt.file.write(dest, result.css);
if (result.map) {
grunt.file.write(`${dest}.map`, result.map);
}
resolve();
});
}
postcss([postcssConfig])
.process(result.css, { from: src, to: dest })
.then(result => {
grunt.file.write(dest, result.css);
if (result.map) {
grunt.file.write(`${dest}.map`, result.map);
}
resolve();
});
});
);
});
}
@ -178,46 +177,55 @@ module.exports = function (grunt) {
const dest = 'dist/kui_dark.css';
return new Promise(resolve => {
sass.render({
file: src,
}, function (error, result) {
if (error) {
grunt.log.error(error);
sass.render(
{
file: src,
},
function(error, result) {
if (error) {
grunt.log.error(error);
}
postcss([postcssConfig])
.process(result.css, { from: src, to: dest })
.then(result => {
grunt.file.write(dest, result.css);
if (result.map) {
grunt.file.write(`${dest}.map`, result.map);
}
resolve();
});
}
postcss([postcssConfig])
.process(result.css, { from: src, to: dest })
.then(result => {
grunt.file.write(dest, result.css);
if (result.map) {
grunt.file.write(`${dest}.map`, result.map);
}
resolve();
});
});
);
});
}
function uiFrameworkWatch() {
const debouncedCompile = debounce(() => {
// Compile the SCSS in a separate process because node-sass throws a fatal error if it fails
// to compile.
grunt.util.spawn({
cmd: isPlatformWindows ? '.\\node_modules\\.bin\\grunt.cmd' : './node_modules/.bin/grunt',
args: [
'compileCssLight',
'compileCssDark',
],
}, (error, result) => {
if (error) {
grunt.log.error(result.stdout);
} else {
grunt.log.writeln(result);
}
});
}, 400, { leading: true });
const debouncedCompile = debounce(
() => {
// Compile the SCSS in a separate process because node-sass throws a fatal error if it fails
// to compile.
grunt.util.spawn(
{
cmd: isPlatformWindows
? '.\\node_modules\\.bin\\grunt.cmd'
: './node_modules/.bin/grunt',
args: ['compileCssLight', 'compileCssDark'],
},
(error, result) => {
if (error) {
grunt.log.error(result.stdout);
} else {
grunt.log.writeln(result);
}
}
);
},
400,
{ leading: true }
);
return new Promise(() => {
debouncedCompile();

View file

@ -18,7 +18,5 @@
*/
module.exports = {
plugins: [
require('autoprefixer')()
]
plugins: [require('autoprefixer')()],
};

View file

@ -17,11 +17,9 @@
* under the License.
*/
import keyMirror from 'keymirror';
export default keyMirror({
// Source code viewer actions
OPEN_CODE_VIEWER: null,
CLOSE_CODE_VIEWER: null,
@ -33,5 +31,4 @@ export default keyMirror({
// Example nav actions
REGISTER_SECTION: null,
UNREGISTER_SECTION: null,
});

View file

@ -17,17 +17,8 @@
* under the License.
*/
export {
openCodeViewer,
closeCodeViewer,
} from './code_viewer_actions';
export { openCodeViewer, closeCodeViewer } from './code_viewer_actions';
export {
openSandbox,
closeSandbox,
} from './sandbox_actions';
export { openSandbox, closeSandbox } from './sandbox_actions';
export {
registerSection,
unregisterSection,
} from './example_nav_actions';
export { registerSection, unregisterSection } from './example_nav_actions';

View file

@ -19,6 +19,4 @@
import React from 'react';
export const GuideCode = props => (
<code className="guideCode">{props.children}</code>
);
export const GuideCode = props => <code className="guideCode">{props.children}</code>;

View file

@ -49,14 +49,9 @@ export class GuideCodeViewer extends Component {
if (code) {
return (
<div className="guideCodeViewer__section" key={type}>
<div className="guideCodeViewer__title">
{type}
</div>
<div className="guideCodeViewer__title">{type}</div>
<pre className="guideCodeViewer__content">
<code
ref={codeClass}
className={codeClass}
>
<code ref={codeClass} className={codeClass}>
{code}
</code>
</pre>
@ -70,20 +65,15 @@ export class GuideCodeViewer extends Component {
'is-code-viewer-open': this.props.isOpen,
});
const codeSections = this.props.source.map(sourceObject => (
const codeSections = this.props.source.map(sourceObject =>
this.renderSection(sourceObject.type, sourceObject.code)
));
);
return (
<div className={classes}>
<div className="guideCodeViewer__header">
{this.props.title}
</div>
<div className="guideCodeViewer__header">{this.props.title}</div>
<div
className="guideCodeViewer__closeButton fa fa-times"
onClick={this.props.onClose}
/>
<div className="guideCodeViewer__closeButton fa fa-times" onClick={this.props.onClose} />
{codeSections}
</div>

View file

@ -68,11 +68,7 @@ export class GuideDemo extends Component {
});
return (
<div
className={classes}
ref={c => (this.content = c)}
{...rest}
>
<div className={classes} ref={c => (this.content = c)} {...rest}>
{children}
</div>
);

View file

@ -20,11 +20,7 @@
import React from 'react';
export const GuideLink = props => (
<a
href={props.href}
target={props.target}
className="guideLink"
>
<a href={props.href} target={props.target} className="guideLink">
{props.children}
</a>
);

View file

@ -59,11 +59,7 @@ export class GuideNav extends Component {
}
renderNoItems(name) {
return (
<p className="guideNavNoItems">
{ `No ${name} match your search` }
</p>
);
return <p className="guideNavNoItems">{`No ${name} match your search`}</p>;
}
renderPagination() {
@ -85,10 +81,7 @@ export class GuideNav extends Component {
});
const nextButton = (
<Link
className={nextClasses}
to={this.state.nextRoute ? this.state.nextRoute.path : ''}
>
<Link className={nextClasses} to={this.state.nextRoute ? this.state.nextRoute.path : ''}>
<span className="fa fa-angle-right" />
</Link>
);
@ -126,21 +119,13 @@ export class GuideNav extends Component {
'is-menu-button-pinned': this.props.isNavOpen,
});
const componentNavItems =
this.props.components.filter(item => (
item.name.toLowerCase().indexOf(this.state.search.toLowerCase()) !== -1
)).map((item, index) => {
const icon =
item.hasReact
? <div className="guideNavItem__reactLogo" />
: undefined;
const componentNavItems = this.props.components
.filter(item => item.name.toLowerCase().indexOf(this.state.search.toLowerCase()) !== -1)
.map((item, index) => {
const icon = item.hasReact ? <div className="guideNavItem__reactLogo" /> : undefined;
return (
<div key={`componentNavItem-${index}`} className="guideNavItem">
<Link
className="guideNavItem__link"
to={item.path}
onClick={this.props.onClickNavItem}
>
<Link className="guideNavItem__link" to={item.path} onClick={this.props.onClickNavItem}>
{item.name}
</Link>
@ -149,21 +134,13 @@ export class GuideNav extends Component {
);
});
const sandboxNavItems =
this.props.sandboxes.filter(item => (
item.name.toLowerCase().indexOf(this.state.search.toLowerCase()) !== -1
)).map((item, index) => {
const icon =
item.hasReact
? <div className="guideNavItem__reactLogo" />
: undefined;
const sandboxNavItems = this.props.sandboxes
.filter(item => item.name.toLowerCase().indexOf(this.state.search.toLowerCase()) !== -1)
.map((item, index) => {
const icon = item.hasReact ? <div className="guideNavItem__reactLogo" /> : undefined;
return (
<div key={`sandboxNavItem-${index}`} className="guideNavItem">
<Link
className="guideNavItem__link"
to={item.path}
onClick={this.props.onClickNavItem}
>
<Link className="guideNavItem__link" to={item.path} onClick={this.props.onClickNavItem}>
{item.name}
</Link>
@ -175,18 +152,15 @@ export class GuideNav extends Component {
return (
<div className={classes}>
<div className="guideNav__header">
<div
className={buttonClasses}
onClick={this.props.onToggleNav}
/>
<Link
className="guideNav__title"
to="/"
onClick={this.props.onClickNavItem}
>
<div className={buttonClasses} onClick={this.props.onToggleNav} />
<Link className="guideNav__title" to="/" onClick={this.props.onClickNavItem}>
Kibana UI Framework <span className="guideNav__version">{this.props.version}</span>
</Link>
<a href="http://elastic.co" className="guideNav__elasticLogo" aria-label="Go to the Elastic website" />
<a
href="http://elastic.co"
className="guideNav__elasticLogo"
aria-label="Go to the Elastic website"
/>
{this.renderPagination()}
</div>
@ -203,24 +177,17 @@ export class GuideNav extends Component {
<div className="guideNavItemsContainer">
<div className="guideNavItems">
<div className="guideNavSectionTitle">
Components
</div>
<div className="guideNavSectionTitle">Components</div>
{ componentNavItems.length ? componentNavItems : this.renderNoItems('components') }
{componentNavItems.length ? componentNavItems : this.renderNoItems('components')}
<div className="guideNavSectionTitle">
Sandboxes
</div>
<div className="guideNavSectionTitle">Sandboxes</div>
{ sandboxNavItems.length ? sandboxNavItems : this.renderNoItems('sandboxes') }
{sandboxNavItems.length ? sandboxNavItems : this.renderNoItems('sandboxes')}
</div>
</div>
<button
className="guideLink guideNav__showButton"
onClick={this.props.onShowChrome}
>
<button className="guideLink guideNav__showButton" onClick={this.props.onShowChrome}>
Show chrome
</button>
</div>

View file

@ -20,10 +20,7 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import {
GuidePageSideNav,
GuidePageSideNavItem,
} from '../';
import { GuidePageSideNav, GuidePageSideNavItem } from '../';
export class GuidePage extends Component {
constructor(props) {
@ -34,20 +31,20 @@ export class GuidePage extends Component {
onClickLink(id) {
// Scroll to element.
$('html, body').animate({ // eslint-disable-line no-undef
scrollTop: $(`#${id}`).offset().top - 100 // eslint-disable-line no-undef
}, 250);
$('html, body').animate(
{
// eslint-disable-line no-undef
scrollTop: $(`#${id}`).offset().top - 100, // eslint-disable-line no-undef
},
250
);
}
renderSideNavMenu() {
// Traverse sections and build side nav from it.
return this.props.sections.map((section, index) => {
return (
<GuidePageSideNavItem
key={index}
id={section.id}
onClick={this.onClickLink}
>
<GuidePageSideNavItem key={index} id={section.id} onClick={this.onClickLink}>
{section.name}
</GuidePageSideNavItem>
);
@ -57,15 +54,11 @@ export class GuidePage extends Component {
render() {
return (
<div className="guidePage">
<GuidePageSideNav title={this.props.title}>
{this.renderSideNavMenu()}
</GuidePageSideNav>
<GuidePageSideNav title={this.props.title}>{this.renderSideNavMenu()}</GuidePageSideNav>
<div className="guidePageBody">
<div className="guidePageKillScreen">
<h1 className="guideTitle">
The Kibana UI Framework has been DEPRECATED.
</h1>
<h1 className="guideTitle">The Kibana UI Framework has been DEPRECATED.</h1>
<h2 className="guideTitle">
Please use the <a href="https://github.com/elastic/eui">EUI Framework instead</a>.

View file

@ -20,16 +20,12 @@
import PropTypes from 'prop-types';
import React from 'react';
export const GuidePageSideNav = props => {
export const GuidePageSideNav = props => {
return (
<div className="guidePageSideNav">
<div className="guidePageSideNav__title">
{props.title}
</div>
<div className="guidePageSideNav__title">{props.title}</div>
<div className="guidePageSideNavMenu">
{props.children}
</div>
<div className="guidePageSideNavMenu">{props.children}</div>
</div>
);
};

View file

@ -21,7 +21,6 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
export class GuidePageSideNavItem extends Component {
constructor(props) {
super(props);
@ -35,16 +34,12 @@ export class GuidePageSideNavItem extends Component {
render() {
return (
<div className="guidePageSideNavMenu__item">
<div
className="guidePageSideNavMenu__itemLink"
onClick={this.onClick}
>
<div className="guidePageSideNavMenu__itemLink" onClick={this.onClick}>
{this.props.children}
</div>
</div>
);
}
}
GuidePageSideNavItem.propTypes = {

View file

@ -17,21 +17,14 @@
* under the License.
*/
import React, {
Component,
} from 'react';
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import {
getIsSandbox,
} from '../../store';
import { getIsSandbox } from '../../store';
import {
openSandbox,
closeSandbox,
} from '../../actions';
import { openSandbox, closeSandbox } from '../../actions';
function mapStateToProps(state) {
return {
@ -58,11 +51,7 @@ class GuideSandboxComponent extends Component {
}
render() {
return (
<div className="guideSandbox">
{this.props.children}
</div>
);
return <div className="guideSandbox">{this.props.children}</div>;
}
}
@ -71,4 +60,7 @@ GuideSandboxComponent.propTypes = {
closeSandbox: PropTypes.func,
};
export const GuideSandbox = connect(mapStateToProps, mapDispatchToProps)(GuideSandboxComponent);
export const GuideSandbox = connect(
mapStateToProps,
mapDispatchToProps
)(GuideSandboxComponent);

View file

@ -20,13 +20,11 @@
import { connect } from 'react-redux';
import { GuideSandboxCodeToggle } from './guide_sandbox_code_toggle';
import {
openCodeViewer,
} from '../../actions';
import { openCodeViewer } from '../../actions';
export const GuideSandboxCodeToggleContainer = connect(
null,
{
openCodeViewer,
},
}
)(GuideSandboxCodeToggle);

View file

@ -46,18 +46,10 @@ export class GuideSection extends Component {
render() {
return (
<div
id={this.getId()}
className="guideSection"
>
<div id={this.getId()} className="guideSection">
<div className="guideSection__header">
<div className="guideSection__title">
{this.props.title}
</div>
<button
className="guideSection__sourceButton"
onClick={this.onClickSource}
>
<div className="guideSection__title">{this.props.title}</div>
<button className="guideSection__sourceButton" onClick={this.onClickSource}>
<span className="fa fa-code" />
</button>
</div>

View file

@ -20,11 +20,7 @@
import { connect } from 'react-redux';
import { GuideSection } from './guide_section';
import {
openCodeViewer,
registerSection,
unregisterSection,
} from '../../actions';
import { openCodeViewer, registerSection, unregisterSection } from '../../actions';
export const GuideSectionContainer = connect(
null,
@ -32,5 +28,5 @@ export const GuideSectionContainer = connect(
openCodeViewer,
registerSection,
unregisterSection,
},
}
)(GuideSection);

View file

@ -19,6 +19,4 @@
import React from 'react';
export const GuideText = props => (
<div className="guideText">{props.children}</div>
);
export const GuideText = props => <div className="guideText">{props.children}</div>;

View file

@ -27,7 +27,7 @@ export { GuidePageSideNav } from './guide_page_side_nav/guide_page_side_nav';
export { GuidePageSideNavItem } from './guide_page_side_nav/guide_page_side_nav_item';
export { GuideSandbox } from './guide_sandbox/guide_sandbox';
export {
GuideSandboxCodeToggleContainer as GuideSandboxCodeToggle
GuideSandboxCodeToggleContainer as GuideSandboxCodeToggle,
} from './guide_sandbox/guide_sandbox_code_toggle_container';
export { GuideSectionContainer as GuideSection } from './guide_section/guide_section_container';
export { GuideSectionTypes } from './guide_section/guide_section_types';

View file

@ -34,9 +34,7 @@ import AppContainer from './views/app_container';
import { HomeView } from './views/home/home_view';
import { NotFoundView } from './views/not_found/not_found_view';
import {
Routes,
} from './services';
import { Routes } from './services';
const store = configureStore();
@ -47,22 +45,24 @@ childRoutes.push({
name: 'Page Not Found',
});
const routes = [{
path: '/',
component: AppContainer,
indexRoute: {
component: HomeView,
source: 'views/home/HomeView',
const routes = [
{
path: '/',
component: AppContainer,
indexRoute: {
component: HomeView,
source: 'views/home/HomeView',
},
childRoutes,
},
childRoutes,
}];
];
// Update document title with route name.
const onRouteEnter = route => {
const leafRoute = route.routes[route.routes.length - 1];
document.title = leafRoute.name ?
`Kibana UI Framework - ${leafRoute.name}` :
'Kibana UI Framework';
document.title = leafRoute.name
? `Kibana UI Framework - ${leafRoute.name}`
: 'Kibana UI Framework';
};
const syncTitleWithRoutes = routesList => {
@ -82,10 +82,7 @@ syncTitleWithRoutes(routes);
ReactDOM.render(
<Provider store={store}>
<Router
history={hashHistory}
routes={routes}
/>
<Router history={hashHistory} routes={routes} />
</Provider>,
document.getElementById('guide')
);

Some files were not shown because too many files have changed in this diff Show more