[6.x] move canvas interpreter to OSS (#25711) (#25921)

This commit is contained in:
Peter Pisljar 2018-11-20 20:17:17 +01:00 committed by GitHub
parent debfd58b69
commit d76c0aeb11
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
159 changed files with 2456 additions and 1202 deletions

View file

@ -27,7 +27,8 @@ bower_components
/x-pack/coverage
/x-pack/build
/x-pack/plugins/**/__tests__/fixtures/**
/x-pack/plugins/canvas/common/lib/grammar.js
/packages/kbn-interpreter/common/lib/grammar.js
/packages/kbn-interpreter/plugin
/x-pack/plugins/canvas/canvas_plugin
/x-pack/plugins/canvas/canvas_plugin_src/lib/flot-charts
**/*.js.snap

1
.gitignore vendored
View file

@ -43,3 +43,4 @@ package-lock.json
npm-debug.log*
.tern-project
index.css
/packages/kbn-interpreter/plugin

View file

@ -108,6 +108,7 @@
"@kbn/pm": "1.0.0",
"@kbn/test-subj-selector": "0.2.1",
"@kbn/ui-framework": "1.0.0",
"@kbn/interpreter": "1.0.0",
"JSONStream": "1.1.1",
"abortcontroller-polyfill": "^1.1.9",
"angular": "1.6.9",
@ -402,4 +403,4 @@
"node": "8.11.4",
"yarn": "^1.10.1"
}
}
}

View file

@ -0,0 +1,3 @@
{
"presets": ["@kbn/babel-preset/webpack_preset"]
}

View file

@ -1,7 +1,20 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { getType } from '../lib/get_type';
@ -19,8 +32,9 @@ export function castProvider(types) {
for (let i = 0; i < toTypeNames.length; i++) {
// First check if the current type can cast to this type
if (fromTypeDef && fromTypeDef.castsTo(toTypeNames[i]))
if (fromTypeDef && fromTypeDef.castsTo(toTypeNames[i])) {
return fromTypeDef.to(node, toTypeNames[i], types);
}
// If that isn't possible, check if this type can cast from the current type
const toTypeDef = types[toTypeNames[i]];

View file

@ -0,0 +1,26 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export const createError = err => ({
type: 'error',
error: {
stack: process.env.NODE_ENV === 'production' ? undefined : err.stack,
message: typeof err === 'string' ? err : err.message,
},
});

View file

@ -1,7 +1,20 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import clone from 'lodash.clone';
@ -112,8 +125,9 @@ export function interpretProvider(config) {
(argAsts, argAst, argName) => {
const argDef = getByAlias(argDefs, argName);
// TODO: Implement a system to allow for undeclared arguments
if (!argDef)
if (!argDef) {
throw new Error(`Unknown argument '${argName}' passed to function '${fnDef.name}'`);
}
argAsts[argDef.name] = (argAsts[argDef.name] || []).concat(argAst);
return argAsts;
@ -142,8 +156,9 @@ export function interpretProvider(config) {
const argAstsWithDefaults = reduce(
argDefs,
(argAsts, argDef, argName) => {
if (typeof argAsts[argName] === 'undefined' && typeof argDef.default !== 'undefined')
if (typeof argAsts[argName] === 'undefined' && typeof argDef.default !== 'undefined') {
argAsts[argName] = [fromExpression(argDef.default, 'argument')];
}
return argAsts;
},

View file

@ -1,7 +1,20 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import uuid from 'uuid/v4';
@ -40,8 +53,9 @@ export function socketInterpreterProvider({
// Get the list of functions that are known elsewhere
return Promise.resolve(referableFunctions).then(referableFunctionMap => {
// Check if the not-found function is in the list of alternatives, if not, throw
if (!getByAlias(referableFunctionMap, functionName))
if (!getByAlias(referableFunctionMap, functionName)) {
throw new Error(`Function not found: ${functionName}`);
}
// set a unique message ID so the code knows what response to process
const id = uuid();

View file

@ -0,0 +1,37 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { includes } from 'lodash';
export function Arg(config) {
if (config.name === '_') throw Error('Arg names must not be _. Use it in aliases instead.');
this.name = config.name;
this.required = config.required || false;
this.help = config.help || '';
this.types = config.types || [];
this.default = config.default;
this.aliases = config.aliases || [];
this.multi = config.multi == null ? false : config.multi;
this.resolve = config.resolve == null ? true : config.resolve;
this.options = config.options || [];
this.accepts = type => {
if (!this.types.length) return true;
return includes(config.types, type);
};
}

View file

@ -0,0 +1,35 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { Arg } from './arg';
describe('Arg', () => {
it('sets required to false by default', () => {
const isOptional = new Arg({
name: 'optional_me',
});
expect(isOptional.required).toBe(false);
const isRequired = new Arg({
name: 'require_me',
required: true,
});
expect(isRequired.required).toBe(true);
});
});

View file

@ -1,35 +1,47 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import expect from 'expect.js';
import { fromExpression } from '../ast';
import { getType } from '../../lib/get_type';
import { fromExpression } from './ast';
import { getType } from './get_type';
describe('ast fromExpression', () => {
describe('invalid expression', () => {
it('throws when empty', () => {
const check = () => fromExpression('');
expect(check).to.throwException(/Unable to parse expression/i);
expect(check).toThrowError(/Unable to parse expression/i);
});
it('throws with invalid expression', () => {
const check = () => fromExpression('wat!');
expect(check).to.throwException(/Unable to parse expression/i);
expect(check).toThrowError(/Unable to parse expression/i);
});
});
describe('single item expression', () => {
it('is a chain', () => {
const expression = 'whatever';
expect(fromExpression(expression)).to.have.property('chain');
expect(fromExpression(expression)).toHaveProperty('chain');
});
it('is a value', () => {
const expression = '"hello"';
expect(fromExpression(expression, 'argument')).to.equal('hello');
expect(fromExpression(expression, 'argument')).toBe('hello');
});
describe('function without arguments', () => {
@ -44,15 +56,15 @@ describe('ast fromExpression', () => {
});
it('is a function ', () => {
expect(getType(block)).to.equal('function');
expect(getType(block)).toBe('function');
});
it('is csv function', () => {
expect(block.function).to.equal('csv');
expect(block.function).toBe('csv');
});
it('has no arguments', () => {
expect(block.arguments).to.eql({});
expect(block.arguments).toEqual({});
});
});
@ -68,17 +80,17 @@ describe('ast fromExpression', () => {
});
it('has arguemnts properties', () => {
expect(block.arguments).not.to.eql({});
expect(block.arguments).not.toEqual({});
});
it('has index argument with string value', () => {
expect(block.arguments).to.have.property('index');
expect(block.arguments.index).to.eql(['logstash-*']);
expect(block.arguments).toHaveProperty('index');
expect(block.arguments.index).toEqual(['logstash-*']);
});
it('has oranges argument with string value', () => {
expect(block.arguments).to.have.property('oranges');
expect(block.arguments.oranges).to.eql(['bananas']);
expect(block.arguments).toHaveProperty('oranges');
expect(block.arguments.oranges).toEqual(['bananas']);
});
});
@ -94,12 +106,12 @@ describe('ast fromExpression', () => {
});
it('is expression type', () => {
expect(block.arguments).to.have.property('exampleFunction');
expect(block.arguments.exampleFunction[0]).to.have.property('type', 'expression');
expect(block.arguments).toHaveProperty('exampleFunction');
expect(block.arguments.exampleFunction[0]).toHaveProperty('type');
});
it('has expected shape', () => {
expect(block.arguments.exampleFunction).to.eql([
expect(block.arguments.exampleFunction).toEqual([
{
type: 'expression',
chain: [
@ -128,12 +140,12 @@ describe('ast fromExpression', () => {
});
it('is expression type', () => {
expect(block.arguments).to.have.property('examplePartial');
expect(block.arguments.examplePartial[0]).to.have.property('type', 'expression');
expect(block.arguments).toHaveProperty('examplePartial');
expect(block.arguments.examplePartial[0]).toHaveProperty('type');
});
it('has expected shape', () => {
expect(block.arguments.examplePartial).to.eql([
expect(block.arguments.examplePartial).toEqual([
{
type: 'expression',
chain: [

View file

@ -1,10 +1,23 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { getType } from '../lib/get_type';
import { getType } from './get_type';
import { parse } from './grammar';
function getArgumentString(arg, argKey, level = 0) {
@ -48,8 +61,9 @@ function getExpressionArgs(block, level = 0) {
const lineLength = acc.split('\n').pop().length;
// if arg values are too long, move it to the next line
if (level === 0 && lineLength + argString.length > MAX_LINE_LENGTH)
if (level === 0 && lineLength + argString.length > MAX_LINE_LENGTH) {
return `${acc}\n ${argString}`;
}
// append arg values to existing arg values
if (lineLength > 0) return `${acc} ${argString}`;

View file

@ -1,18 +1,39 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import expect from 'expect.js';
import { toExpression } from '../ast';
import { toExpression } from './ast';
describe('ast toExpression', () => {
describe('single expression', () => {
it('throws if no type included', () => {
const errMsg = 'Objects must have a type property';
const astObject = { hello: 'world' };
expect(() => toExpression(astObject)).toThrowError(errMsg);
});
it('throws if not correct type', () => {
const errMsg = 'Expression must be an expression or argument function';
const astObject = { hello: 'world' };
expect(() => toExpression(astObject)).to.throwException(errMsg);
const astObject = {
type: 'hi',
hello: 'world',
};
expect(() => toExpression(astObject)).toThrowError(errMsg);
});
it('throws if expression without chain', () => {
@ -21,7 +42,7 @@ describe('ast toExpression', () => {
type: 'expression',
hello: 'world',
};
expect(() => toExpression(astObject)).to.throwException(errMsg);
expect(() => toExpression(astObject)).toThrowError(errMsg);
});
it('throws if arguments type is invalid', () => {
@ -29,7 +50,7 @@ describe('ast toExpression', () => {
const invalidTypes = [null, []];
function validate(obj) {
expect(() => toExpression(obj)).to.throwException(errMsg);
expect(() => toExpression(obj)).toThrowError(errMsg);
}
for (let i = 0; i < invalidTypes.length; i++) {
@ -56,12 +77,12 @@ describe('ast toExpression', () => {
function: 'pointseries',
arguments: null,
};
expect(() => toExpression(astObject)).to.throwException(errMsg);
expect(() => toExpression(astObject)).toThrowError(errMsg);
});
it('throws on invalid argument type', () => {
const argType = '__invalid__wat__';
const errMsg = `invalid argument type: ${argType}`;
const errMsg = `Invalid argument type in AST: ${argType}`;
const astObject = {
type: 'expression',
chain: [
@ -80,7 +101,7 @@ describe('ast toExpression', () => {
],
};
expect(() => toExpression(astObject)).to.throwException(errMsg);
expect(() => toExpression(astObject)).toThrowError(errMsg);
});
it('throws on expressions without chains', () => {
@ -104,7 +125,7 @@ describe('ast toExpression', () => {
],
};
expect(() => toExpression(astObject)).to.throwException(errMsg);
expect(() => toExpression(astObject)).toThrowError(errMsg);
});
it('throws on nameless functions and partials', () => {
@ -120,7 +141,7 @@ describe('ast toExpression', () => {
],
};
expect(() => toExpression(astObject)).to.throwException(errMsg);
expect(() => toExpression(astObject)).toThrowError(errMsg);
});
it('single expression', () => {
@ -136,7 +157,7 @@ describe('ast toExpression', () => {
};
const expression = toExpression(astObj);
expect(expression).to.equal('csv');
expect(expression).toBe('csv');
});
it('single expression with string argument', () => {
@ -154,7 +175,7 @@ describe('ast toExpression', () => {
};
const expression = toExpression(astObj);
expect(expression).to.equal('csv input="stuff\nthings"');
expect(expression).toBe('csv input="stuff\nthings"');
});
it('single expression string value with a backslash', () => {
@ -172,7 +193,7 @@ describe('ast toExpression', () => {
};
const expression = toExpression(astObj);
expect(expression).to.equal('csv input="slash \\\\\\\\ slash"');
expect(expression).toBe('csv input="slash \\\\\\\\ slash"');
});
it('single expression string value with a double quote', () => {
@ -190,7 +211,7 @@ describe('ast toExpression', () => {
};
const expression = toExpression(astObj);
expect(expression).to.equal('csv input="stuff\nthings\n\\"such\\""');
expect(expression).toBe('csv input="stuff\nthings\n\\"such\\""');
});
it('single expression with number argument', () => {
@ -208,7 +229,7 @@ describe('ast toExpression', () => {
};
const expression = toExpression(astObj);
expect(expression).to.equal('series input=1234');
expect(expression).toBe('series input=1234');
});
it('single expression with boolean argument', () => {
@ -226,7 +247,7 @@ describe('ast toExpression', () => {
};
const expression = toExpression(astObj);
expect(expression).to.equal('series input=true');
expect(expression).toBe('series input=true');
});
it('single expression with null argument', () => {
@ -244,7 +265,7 @@ describe('ast toExpression', () => {
};
const expression = toExpression(astObj);
expect(expression).to.equal('series input=null');
expect(expression).toBe('series input=null');
});
it('single expression with multiple arguments', () => {
@ -263,7 +284,7 @@ describe('ast toExpression', () => {
};
const expression = toExpression(astObj);
expect(expression).to.equal('csv input="stuff\nthings" separator="\\\\n"');
expect(expression).toBe('csv input="stuff\nthings" separator="\\\\n"');
});
it('single expression with multiple and repeated arguments', () => {
@ -282,12 +303,12 @@ describe('ast toExpression', () => {
};
const expression = toExpression(astObj);
expect(expression).to.equal(
expect(expression).toBe(
'csv input="stuff\nthings" input="more,things\nmore,stuff" separator="\\\\n"'
);
});
it('single expression with expression argument', () => {
it('single expression with `getcalc` expression argument', () => {
const astObj = {
type: 'expression',
chain: [
@ -314,10 +335,10 @@ describe('ast toExpression', () => {
};
const expression = toExpression(astObj);
expect(expression).to.equal('csv calc={getcalc} input="stuff\nthings"');
expect(expression).toBe('csv calc={getcalc} input="stuff\nthings"');
});
it('single expression with expression argument', () => {
it('single expression with `partcalc` expression argument', () => {
const astObj = {
type: 'expression',
chain: [
@ -344,7 +365,7 @@ describe('ast toExpression', () => {
};
const expression = toExpression(astObj);
expect(expression).to.equal('csv calc={partcalc} input="stuff\nthings"');
expect(expression).toBe('csv calc={partcalc} input="stuff\nthings"');
});
it('single expression with expression arguments, with arguments', () => {
@ -390,7 +411,7 @@ describe('ast toExpression', () => {
};
const expression = toExpression(astObj);
expect(expression).to.equal(
expect(expression).toBe(
'csv sep={partcalc type="comma"} input="stuff\nthings" break={setBreak type="newline"}'
);
});
@ -468,7 +489,7 @@ describe('ast toExpression', () => {
'2016,honda,fit,15890,',
'2016,honda,civic,18640"\n| line x={distinct f="year"} y={sum f="price"} colors={distinct f="model"}',
];
expect(expression).to.equal(expected.join('\n'));
expect(expression).toBe(expected.join('\n'));
});
it('three chained expressions', () => {
@ -563,7 +584,7 @@ describe('ast toExpression', () => {
'2016,honda,civic,18640"\n| pointseries x={distinct f="year"} y={sum f="price"} ' +
'colors={distinct f="model"}\n| line pallette={getColorPallette name="elastic"}',
];
expect(expression).to.equal(expected.join('\n'));
expect(expression).toBe(expected.join('\n'));
});
});
@ -583,7 +604,7 @@ describe('ast toExpression', () => {
};
const expression = toExpression(astObj);
expect(expression).to.equal('list "one" "two" "three"');
expect(expression).toBe('list "one" "two" "three"');
});
it('named and unnamed', () => {
@ -603,7 +624,7 @@ describe('ast toExpression', () => {
};
const expression = toExpression(astObj);
expect(expression).to.equal('both named="example" another="item" "one" "two" "three"');
expect(expression).toBe('both named="example" another="item" "one" "two" "three"');
});
});
});

View file

@ -1,7 +1,20 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { mapValues, includes } from 'lodash';

View file

@ -0,0 +1,29 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { Registry } from './registry';
import { Fn } from './fn';
class FunctionsRegistry extends Registry {
wrapper(obj) {
return new Fn(obj);
}
}
export const functionsRegistry = new FunctionsRegistry();

View file

@ -0,0 +1,33 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* This is used for looking up function/argument definitions. It looks through
* the given object/array for a case-insensitive match, which could be either the
* `name` itself, or something under the `aliases` property.
*/
export function getByAlias(specs, name) {
const lowerCaseName = name.toLowerCase();
return Object.values(specs).find(({ name, aliases }) => {
if (name.toLowerCase() === lowerCaseName) return true;
return (aliases || []).some(alias => {
return alias.toLowerCase() === lowerCaseName;
});
});
}

View file

@ -0,0 +1,86 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { getByAlias } from './get_by_alias';
describe('getByAlias', () => {
const fnsObject = {
foo: { name: 'foo', aliases: ['f'] },
bar: { name: 'bar', aliases: ['b'] },
};
const fnsArray = [{ name: 'foo', aliases: ['f'] }, { name: 'bar', aliases: ['b'] }];
it('returns the function by name', () => {
expect(getByAlias(fnsObject, 'foo')).toBe(fnsObject.foo);
expect(getByAlias(fnsObject, 'bar')).toBe(fnsObject.bar);
expect(getByAlias(fnsArray, 'foo')).toBe(fnsArray[0]);
expect(getByAlias(fnsArray, 'bar')).toBe(fnsArray[1]);
});
it('returns the function by alias', () => {
expect(getByAlias(fnsObject, 'f')).toBe(fnsObject.foo);
expect(getByAlias(fnsObject, 'b')).toBe(fnsObject.bar);
expect(getByAlias(fnsArray, 'f')).toBe(fnsArray[0]);
expect(getByAlias(fnsArray, 'b')).toBe(fnsArray[1]);
});
it('returns the function by case-insensitive name', () => {
expect(getByAlias(fnsObject, 'FOO')).toBe(fnsObject.foo);
expect(getByAlias(fnsObject, 'BAR')).toBe(fnsObject.bar);
expect(getByAlias(fnsArray, 'FOO')).toBe(fnsArray[0]);
expect(getByAlias(fnsArray, 'BAR')).toBe(fnsArray[1]);
});
it('returns the function by case-insensitive alias', () => {
expect(getByAlias(fnsObject, 'F')).toBe(fnsObject.foo);
expect(getByAlias(fnsObject, 'B')).toBe(fnsObject.bar);
expect(getByAlias(fnsArray, 'F')).toBe(fnsArray[0]);
expect(getByAlias(fnsArray, 'B')).toBe(fnsArray[1]);
});
it('handles empty strings', () => {
const emptyStringFnsObject = { '': { name: '' } };
const emptyStringAliasFnsObject = { foo: { name: 'foo', aliases: [''] } };
expect(getByAlias(emptyStringFnsObject, '')).toBe(emptyStringFnsObject['']);
expect(getByAlias(emptyStringAliasFnsObject, '')).toBe(emptyStringAliasFnsObject.foo);
const emptyStringFnsArray = [{ name: '' }];
const emptyStringAliasFnsArray = [{ name: 'foo', aliases: [''] }];
expect(getByAlias(emptyStringFnsArray, '')).toBe(emptyStringFnsArray[0]);
expect(getByAlias(emptyStringAliasFnsArray, '')).toBe(emptyStringAliasFnsArray[0]);
});
it('handles "undefined" strings', () => {
const undefinedFnsObject = { undefined: { name: 'undefined' } };
const undefinedAliasFnsObject = { foo: { name: 'undefined', aliases: ['undefined'] } };
expect(getByAlias(undefinedFnsObject, 'undefined')).toBe(undefinedFnsObject.undefined);
expect(getByAlias(undefinedAliasFnsObject, 'undefined')).toBe(undefinedAliasFnsObject.foo);
const emptyStringFnsArray = [{ name: 'undefined' }];
const emptyStringAliasFnsArray = [{ name: 'foo', aliases: ['undefined'] }];
expect(getByAlias(emptyStringFnsArray, 'undefined')).toBe(emptyStringFnsArray[0]);
expect(getByAlias(emptyStringAliasFnsArray, 'undefined')).toBe(emptyStringAliasFnsArray[0]);
});
it('returns undefined if not found', () => {
expect(getByAlias(fnsObject, 'baz')).toBe(undefined);
expect(getByAlias(fnsArray, 'baz')).toBe(undefined);
});
});

View file

@ -0,0 +1,28 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export function getType(node) {
if (node == null) return 'null';
if (typeof node === 'object') {
if (!node.type) throw new Error('Objects must have a type property');
return node.type;
}
return typeof node;
}

View file

@ -0,0 +1,65 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
class PathsRegistry {
constructor() {
this.paths = new Map();
}
register = (type, paths) => {
if (!type) {
throw new Error(`Register requires a type`);
}
const lowerCaseType = type.toLowerCase();
const pathArray = Array.isArray(paths) ? paths : [paths];
if (!this.paths.has(lowerCaseType)) {
this.paths.set(lowerCaseType, []);
}
pathArray.forEach(p => {
this.paths.get(lowerCaseType).push(p);
});
};
registerAll = (paths) => {
Object.keys(paths).forEach(type => {
this.register(type, paths[type]);
});
};
toArray = () => {
return [...this.paths.values()];
};
get = (type) => {
if (!type) {
return [];
}
const lowerCaseType = type.toLowerCase();
return this.paths.has(lowerCaseType) ? this.paths.get(lowerCaseType) : [];
};
reset = () => {
this.paths.clear();
};
}
export const pathsRegistry = new PathsRegistry();

View file

@ -0,0 +1,92 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
describe('pathsRegistry', () => {
let registry;
beforeEach(() => {
jest.resetModules();
registry = require('./paths_registry').pathsRegistry;
});
const paths = {
foo: 'bar',
sometype: [
'Here',
'be',
'more',
'paths!'
],
anothertype: ['with just one lonely path']
};
it('throws when no type is provided', () => {
const check = () => registry.register(null, paths.foo);
expect(check).toThrowError(/requires a type/);
});
it('accepts paths as a string', () => {
registry.register('foo', paths.foo);
expect(registry.get('foo')).toEqual([paths.foo]);
});
it('accepts paths as an array', () => {
registry.register('sometype', paths.sometype);
expect(registry.get('sometype')).toEqual(paths.sometype);
});
it('ignores case when setting items', () => {
registry.register('FOO', paths.foo);
expect(registry.get('foo')).toEqual([paths.foo]);
});
it('gets items by lookup property', () => {
registry.register('sometype', paths.sometype);
expect(registry.get('sometype')).toEqual(paths.sometype);
});
it('can register an object of `type: path` key-value pairs', () => {
registry.registerAll(paths);
expect(registry.get('foo')).toEqual([paths.foo]);
expect(registry.get('sometype')).toEqual(paths.sometype);
expect(registry.get('anothertype')).toEqual(paths.anothertype);
});
it('ignores case when getting items', () => {
registry.registerAll(paths);
expect(registry.get('FOO')).toEqual([paths.foo]);
expect(registry.get('SOmEType')).toEqual(paths.sometype);
expect(registry.get('anoThertYPE')).toEqual(paths.anothertype);
});
it('returns an empty array with no match', () => {
expect(registry.get('@@nope_nope')).toEqual([]);
});
it('returns an array of all path values', () => {
registry.registerAll(paths);
expect(registry.toArray()).toEqual([[paths.foo], paths.sometype, paths.anothertype]);
});
it('resets the registry', () => {
registry.registerAll(paths);
expect(registry.get('sometype')).toEqual(paths.sometype);
registry.reset();
expect(registry.get('sometype')).toEqual([]);
});
});

View file

@ -1,7 +1,20 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import clone from 'lodash.clone';
@ -22,8 +35,9 @@ export class Registry {
const obj = fn();
if (typeof obj !== 'object' || !obj[this._prop])
if (typeof obj !== 'object' || !obj[this._prop]) {
throw new Error(`Registered functions must return an object with a ${this._prop} property`);
}
this._indexed[obj[this._prop].toLowerCase()] = this.wrapper(obj);
}

View file

@ -1,51 +1,63 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import expect from 'expect.js';
import { Registry } from '../registry';
import { Registry } from './registry';
function validateRegistry(registry, elements) {
it('gets items by lookup property', () => {
expect(registry.get('__test2')).to.eql(elements[1]());
expect(registry.get('__test2')).toEqual(elements[1]());
});
it('ignores case when getting items', () => {
expect(registry.get('__TeSt2')).to.eql(elements[1]());
expect(registry.get('__tESt2')).to.eql(elements[1]());
expect(registry.get('__TeSt2')).toEqual(elements[1]());
expect(registry.get('__tESt2')).toEqual(elements[1]());
});
it('gets a shallow clone', () => {
expect(registry.get('__test2')).to.not.equal(elements[1]());
expect(registry.get('__test2')).not.toBe(elements[1]());
});
it('is null with no match', () => {
expect(registry.get('@@nope_nope')).to.be(null);
expect(registry.get('@@nope_nope')).toBe(null);
});
it('returns shallow clone of the whole registry via toJS', () => {
const regAsJs = registry.toJS();
expect(regAsJs).to.eql({
expect(regAsJs).toEqual({
__test1: elements[0](),
__test2: elements[1](),
});
expect(regAsJs.__test1).to.eql(elements[0]());
expect(regAsJs.__test1).to.not.equal(elements[0]());
expect(regAsJs.__test1).toEqual(elements[0]());
expect(regAsJs.__test1).not.toBe(elements[0]());
});
it('returns shallow clone array via toArray', () => {
const regAsArray = registry.toArray();
expect(regAsArray).to.be.an(Array);
expect(regAsArray[0]).to.eql(elements[0]());
expect(regAsArray[0]).to.not.equal(elements[0]());
expect(regAsArray).toBeInstanceOf(Array);
expect(regAsArray[0]).toEqual(elements[0]());
expect(regAsArray[0]).not.toBe(elements[0]());
});
it('resets the registry', () => {
expect(registry.get('__test2')).to.eql(elements[1]());
expect(registry.get('__test2')).toEqual(elements[1]());
registry.reset();
expect(registry.get('__test2')).to.equal(null);
expect(registry.get('__test2')).toBe(null);
});
}
@ -70,12 +82,12 @@ describe('Registry', () => {
validateRegistry(registry, elements);
it('has a prop of name', () => {
expect(registry.getProp()).to.equal('name');
expect(registry.getProp()).toBe('name');
});
it('throws when object is missing the lookup prop', () => {
const check = () => registry.register(() => ({ hello: 'world' }));
expect(check).to.throwException(/object with a name property/i);
expect(check).toThrowError(/object with a name property/);
});
});
@ -99,12 +111,12 @@ describe('Registry', () => {
validateRegistry(registry, elements);
it('has a prop of type', () => {
expect(registry.getProp()).to.equal('type');
expect(registry.getProp()).toBe('type');
});
it('throws when object is missing the lookup prop', () => {
const check = () => registry.register(() => ({ hello: 'world' }));
expect(check).to.throwException(/object with a type property/i);
expect(check).toThrowError(/object with a type property/);
});
});
@ -137,9 +149,8 @@ describe('Registry', () => {
registry.register(elements[1]);
it('contains wrapped elements', () => {
// test for the custom prop on the returned elements
expect(registry.get(elements[0]().name)).to.have.property('__CUSTOM_PROP__', 1);
expect(registry.get(elements[1]().name)).to.have.property('__CUSTOM_PROP__', 2);
expect(registry.get(elements[0]().name)).toHaveProperty('__CUSTOM_PROP__');
expect(registry.get(elements[1]().name)).toHaveProperty('__CUSTOM_PROP__');
});
});
@ -171,20 +182,18 @@ describe('Registry', () => {
});
it('get contains the full prototype', () => {
expect(thing().baseFunc).to.be.a('function');
expect(registry.get(name).baseFunc).to.be.a('function');
expect(typeof thing().baseFunc).toBe('function');
expect(typeof registry.get(name).baseFunc).toBe('function');
});
it('toJS contains the full prototype', () => {
const val = registry.toJS();
expect(val[name].baseFunc).to.be.a('function');
expect(typeof val[name].baseFunc).toBe('function');
});
});
describe('throws when lookup prop is not a string', () => {
const check = () => new Registry(2);
expect(check).to.throwException(e => {
expect(e.message).to.be('Registry property name must be a string');
});
expect(check).toThrowError(/must be a string/);
});
});

View file

@ -0,0 +1,37 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { get, identity } from 'lodash';
import { getType } from './get_type';
export function serializeProvider(types) {
return {
serialize: provider('serialize'),
deserialize: provider('deserialize'),
};
function provider(key) {
return context => {
const type = getType(context);
const typeDef = types[type];
const fn = get(typeDef, key) || identity;
return fn(context);
};
}
}

View file

@ -1,12 +1,25 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// All types must be universal and be castable on the client or on the server
import { get } from 'lodash';
import { getType } from '../lib/get_type';
import { getType } from './get_type';
// TODO: Currently all casting functions must be syncronous.
@ -35,10 +48,12 @@ export function Type(config) {
this.to = (node, toTypeName, types) => {
const typeName = getType(node);
if (typeName !== this.name)
if (typeName !== this.name) {
throw new Error(`Can not cast object of type '${typeName}' using '${this.name}'`);
else if (!this.castsTo(toTypeName))
}
else if (!this.castsTo(toTypeName)) {
throw new Error(`Can not cast '${typeName}' to '${toTypeName}'`);
}
return getToFn(toTypeName)(node, types);
};

View file

@ -0,0 +1,29 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { Registry } from './registry';
import { Type } from './type';
class TypesRegistry extends Registry {
wrapper(obj) {
return new Type(obj);
}
}
export const typesRegistry = new TypesRegistry();

View file

@ -0,0 +1,10 @@
{
"name": "@kbn/interpreter",
"version": "1.0.0",
"license": "Apache-2.0",
"scripts": {
"build": "node tasks/build.js",
"canvas:peg": "pegjs common/lib/grammar.peg",
"kbn:bootstrap": "yarn build"
}
}

View file

@ -0,0 +1,27 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export const clog = () => ({
name: 'clog',
help: 'Outputs the context to the console',
fn: context => {
console.log(context); //eslint-disable-line no-console
return context;
},
});

View file

@ -0,0 +1,24 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { clog } from './clog';
export const commonFunctions = [
clog,
];

View file

@ -0,0 +1,23 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { commonFunctions } from './index';
// eslint-disable-next-line no-undef
commonFunctions.forEach(canvas.register);

View file

@ -0,0 +1,42 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export const boolean = () => ({
name: 'boolean',
from: {
null: () => false,
number: n => Boolean(n),
string: s => Boolean(s),
},
to: {
render: value => {
const text = `${value}`;
return {
type: 'render',
as: 'text',
value: { text },
};
},
datatable: value => ({
type: 'datatable',
columns: [{ name: 'value', type: 'boolean' }],
rows: [{ value }],
}),
},
});

View file

@ -1,7 +1,20 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { map, zipObject } from 'lodash';
@ -10,8 +23,9 @@ export const datatable = () => ({
name: 'datatable',
validate: datatable => {
// TODO: Check columns types. Only string, boolean, number, date, allowed for now.
if (!datatable.columns)
if (!datatable.columns) {
throw new Error('datatable must have a columns array, even if it is empty');
}
if (!datatable.rows) throw new Error('datatable must have a rows array, even if it is empty');
},

View file

@ -0,0 +1,35 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export const error = () => ({
name: 'error',
to: {
render: input => {
const { error, info } = input;
return {
type: 'render',
as: 'error',
value: {
error,
info,
},
};
},
},
});

View file

@ -0,0 +1,33 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export const filter = () => ({
name: 'filter',
from: {
null: () => {
return {
type: 'filter',
// Any meta data you wish to pass along.
meta: {},
// And filters. If you need an "or", create a filter type for it.
and: [],
};
},
},
});

View file

@ -0,0 +1,31 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export const image = () => ({
name: 'image',
to: {
render: input => {
return {
type: 'render',
as: 'image',
value: input,
};
},
},
});

View file

@ -0,0 +1,46 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { boolean } from './boolean';
import { datatable } from './datatable';
import { error } from './error';
import { filter } from './filter';
import { image } from './image';
import { nullType } from './null';
import { number } from './number';
import { pointseries } from './pointseries';
import { render } from './render';
import { shape } from './shape';
import { string } from './string';
import { style } from './style';
export const typeSpecs = [
boolean,
datatable,
error,
filter,
image,
number,
nullType,
pointseries,
render,
shape,
string,
style,
];

View file

@ -0,0 +1,25 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export const nullType = () => ({
name: 'null',
from: {
'*': () => null,
},
});

View file

@ -0,0 +1,42 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export const number = () => ({
name: 'number',
from: {
null: () => 0,
boolean: b => Number(b),
string: n => Number(n),
},
to: {
render: value => {
const text = `${value}`;
return {
type: 'render',
as: 'text',
value: { text },
};
},
datatable: value => ({
type: 'datatable',
columns: [{ name: 'value', type: 'number' }],
rows: [{ value }],
}),
},
});

View file

@ -0,0 +1,44 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export const pointseries = () => ({
name: 'pointseries',
from: {
null: () => {
return {
type: 'pointseries',
rows: [],
columns: [],
};
},
},
to: {
render: (pointseries, types) => {
const datatable = types.datatable.from(pointseries, types);
return {
type: 'render',
as: 'table',
value: {
datatable,
showHeader: true,
},
};
},
},
});

View file

@ -0,0 +1,24 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import 'babel-polyfill';
import { typeSpecs } from './index';
// eslint-disable-next-line no-undef
typeSpecs.forEach(canvas.register);

View file

@ -0,0 +1,29 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export const render = () => ({
name: 'render',
from: {
'*': v => ({
type: 'render',
as: 'debug',
value: v,
}),
},
});

View file

@ -0,0 +1,31 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export const shape = () => ({
name: 'shape',
to: {
render: input => {
return {
type: 'render',
as: 'shape',
value: input,
};
},
},
});

View file

@ -0,0 +1,41 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export const string = () => ({
name: 'string',
from: {
null: () => '',
boolean: b => String(b),
number: n => String(n),
},
to: {
render: text => {
return {
type: 'render',
as: 'text',
value: { text },
};
},
datatable: value => ({
type: 'datatable',
columns: [{ name: 'value', type: 'string' }],
rows: [{ value }],
}),
},
});

View file

@ -0,0 +1,31 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export const style = () => ({
name: 'style',
from: {
null: () => {
return {
type: 'style',
spec: {},
css: '',
};
},
},
});

View file

@ -0,0 +1,83 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import chrome from 'ui/chrome';
import $script from 'scriptjs';
let resolvePromise = null;
let called = false;
let populatePromise = new Promise(_resolve => {
resolvePromise = _resolve;
});
export const getBrowserRegistries = () => {
return populatePromise;
};
const loadBrowserRegistries = (registries) => {
const remainingTypes = Object.keys(registries);
const populatedTypes = {};
return new Promise(resolve => {
function loadType() {
if (!remainingTypes.length) {
resolve(populatedTypes);
return;
}
const type = remainingTypes.pop();
window.canvas = window.canvas || {};
window.canvas.register = d => registries[type].register(d);
// Load plugins one at a time because each needs a different loader function
// $script will only load each of these once, we so can call this as many times as we need?
const pluginPath = chrome.addBasePath(`/api/canvas/plugins?type=${type}`);
$script(pluginPath, () => {
populatedTypes[type] = registries[type];
loadType();
});
}
loadType();
});
};
export const populateBrowserRegistries = (registries) => {
if (called) {
const oldPromise = populatePromise;
let newResolve;
populatePromise = new Promise(_resolve => {
newResolve = _resolve;
});
oldPromise.then(oldTypes => {
loadBrowserRegistries(registries).then(newTypes => {
newResolve({
...oldTypes,
...newTypes,
});
});
});
return populatePromise;
}
called = true;
loadBrowserRegistries(registries).then(registries => {
resolvePromise(registries);
});
return populatePromise;
};

View file

@ -0,0 +1,24 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export function createHandlers(/*socket*/) {
return {
environment: 'client',
};
}

View file

@ -1,15 +1,28 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { socketInterpreterProvider } from '../../common/interpreter/socket_interpret';
import { serializeProvider } from '../../common/lib/serialize';
import { getSocket } from '../socket';
import { typesRegistry } from '../../common/lib/types_registry';
import { socketInterpreterProvider } from '../common/interpreter/socket_interpret';
import { serializeProvider } from '../common/lib/serialize';
import { getSocket } from './socket';
import { typesRegistry } from '../common/lib/types_registry';
import { createHandlers } from './create_handlers';
import { functionsRegistry } from './functions_registry';
import { functionsRegistry } from '../common/lib/functions_registry';
import { getBrowserRegistries } from './browser_registries';
let socket;

View file

@ -1,12 +1,25 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import io from 'socket.io-client';
import { functionsRegistry } from '../common/lib/functions_registry';
import { getBrowserRegistries } from './lib/browser_registries';
import { getBrowserRegistries } from './browser_registries';
const SOCKET_CONNECTION_TIMEOUT = 5000; // timeout in ms
let socket;

View file

@ -0,0 +1,55 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import fs from 'fs';
import { resolve } from 'path';
import { promisify } from 'util';
import { flatten } from 'lodash';
import { pathsRegistry } from '../common/lib/paths_registry';
const lstat = promisify(fs.lstat);
const readdir = promisify(fs.readdir);
const isDirectory = path =>
lstat(path)
.then(stat => stat.isDirectory())
.catch(() => false);
export const getPluginPaths = type => {
const typePaths = pathsRegistry.get(type);
if (!typePaths) {
throw new Error(`Unknown type: ${type}`);
}
return Promise.all(typePaths.map(async path => {
const isDir = await isDirectory(path);
if (!isDir) {
return;
}
// Get the full path of all js files in the directory
return readdir(path).then(files => {
return files.reduce((acc, file) => {
if (file.endsWith('.js')) {
acc.push(resolve(path, file));
}
return acc;
}, []);
}).catch();
})).then(flatten);
};

View file

@ -0,0 +1,78 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { typesRegistry } from '../common/lib/types_registry';
import { functionsRegistry as serverFunctions } from '../common/lib/functions_registry';
import { getPluginPaths } from './get_plugin_paths';
const registries = {
serverFunctions: serverFunctions,
commonFunctions: serverFunctions,
types: typesRegistry,
};
let resolve = null;
let called = false;
const populatePromise = new Promise(_resolve => {
resolve = _resolve;
});
export const getServerRegistries = () => {
return populatePromise;
};
export const populateServerRegistries = types => {
if (called) {
console.log('function should only be called once per process');
return populatePromise;
}
called = true;
if (!types || !types.length) throw new Error('types is required');
const remainingTypes = types;
const populatedTypes = {};
const globalKeys = Object.keys(global);
const loadType = () => {
const type = remainingTypes.pop();
getPluginPaths(type).then(paths => {
global.canvas = global.canvas || {};
global.canvas.register = d => registries[type].register(d);
paths.forEach(path => {
require(path);
});
Object.keys(global).forEach(key => {
if (!globalKeys.includes(key)) {
delete global[key];
}
});
populatedTypes[type] = registries[type];
if (remainingTypes.length) loadType();
else resolve(populatedTypes);
});
};
if (remainingTypes.length) loadType();
return populatePromise;
};

View file

@ -0,0 +1,40 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
const webpack = require('webpack');
const webpackConfig = require('./webpack.plugins');
const devtool = 'inline-cheap-module-source-map';
const onComplete = function (done) {
return function (err, stats) {
if (err) {
done && done(err);
} else {
const seconds = ((stats.endTime - stats.startTime) / 1000).toFixed(2);
console.log(`Plugins built in ${seconds} seconds`);
done && done();
}
};
};
webpack({ ...webpackConfig, devtool }, onComplete(function () {
console.log('all done');
}));

View file

@ -0,0 +1,100 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
const path = require('path');
const sourceDir = path.resolve(__dirname, '../plugin_src');
const buildDir = path.resolve(__dirname, '../plugin');
module.exports = {
entry: {
'types/all': path.join(sourceDir, 'types/register.js'),
'functions/common/all': path.join(sourceDir, 'functions/common/register.js'),
},
target: 'webworker',
output: {
path: buildDir,
filename: '[name].js', // Need long paths here.
libraryTarget: 'umd',
},
resolve: {
extensions: ['.js', '.json'],
mainFields: ['browser', 'main'],
},
plugins: [
function loaderFailHandler() {
// bails on error, including loader errors
// see https://github.com/webpack/webpack/issues/708, which does not fix loader errors
let isWatch = true;
this.plugin('run', function (compiler, callback) {
isWatch = false;
callback.call(compiler);
});
this.plugin('done', function (stats) {
if (!stats.hasErrors()) {
return;
}
const errorMessage = stats.toString('errors-only');
if (isWatch) {
console.error(errorMessage);
}
else {
throw new Error(errorMessage);
}
});
},
],
module: {
rules: [
{
test: /\.js$/,
exclude: [/node_modules/],
loaders: 'babel-loader',
options: {
babelrc: false,
presets: [require.resolve('@kbn/babel-preset/webpack_preset')],
},
},
{
test: /\.(png|jpg|gif|jpeg|svg)$/,
loaders: ['url-loader'],
},
{
test: /\.(css|scss)$/,
loaders: ['style-loader', 'css-loader', 'sass-loader'],
},
],
},
node: {
// Don't replace built-in globals
__filename: false,
__dirname: false,
},
watchOptions: {
ignored: [/node_modules/],
},
};

View file

@ -0,0 +1,21 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export const SECURITY_AUTH_MESSAGE = 'Authentication failed';
export const API_ROUTE = '/api/canvas';

View file

@ -0,0 +1,41 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { resolve } from 'path';
import init from './init';
import { pathsRegistry } from '@kbn/interpreter/common/lib/paths_registry';
import { pluginPaths } from './plugin_paths';
export default function (kibana) {
return new kibana.Plugin({
id: 'interpreter',
require: ['kibana', 'elasticsearch'],
publicDir: resolve(__dirname, 'public'),
uiExports: {
hacks: [
'plugins/interpreter/load_browser_plugins.js',
],
},
preInit: () => {
pathsRegistry.registerAll(pluginPaths);
},
init,
});
}

View file

@ -0,0 +1,41 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { routes } from './server/routes';
import { functionsRegistry } from '@kbn/interpreter/common/lib/functions_registry';
import { populateServerRegistries } from '@kbn/interpreter/server/server_registries';
export default function (server /*options*/) {
server.injectUiAppVars('canvas', () => {
const config = server.config();
const basePath = config.get('server.basePath');
const reportingBrowserType = config.get('xpack.reporting.capture.browser.type');
return {
kbnIndex: config.get('kibana.index'),
esShardTimeout: config.get('elasticsearch.shardTimeout'),
esApiVersion: config.get('elasticsearch.apiVersion'),
serverFunctions: functionsRegistry.toArray(),
basePath,
reportingBrowserType,
};
});
populateServerRegistries(['serverFunctions', 'types']).then(() => routes(server));
}

View file

@ -0,0 +1,4 @@
{
"name": "interpreter",
"version": "kibana"
}

View file

@ -0,0 +1,27 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { resolve } from 'path';
const dir = resolve(__dirname, '..', '..', '..');
export const pluginPaths = {
commonFunctions: resolve(dir, 'node_modules/@kbn/interpreter/plugin/functions/common'),
types: resolve(dir, 'node_modules/@kbn/interpreter/plugin/types'),
};

View file

@ -0,0 +1,30 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { populateBrowserRegistries } from '@kbn/interpreter/public/browser_registries';
import { typesRegistry } from '@kbn/interpreter/common/lib/types_registry';
import { functionsRegistry } from '@kbn/interpreter/common/lib/functions_registry';
const types = {
commonFunctions: functionsRegistry,
browserFunctions: functionsRegistry,
types: typesRegistry
};
populateBrowserRegistries(types);

View file

@ -1,12 +1,25 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import expect from 'expect.js';
import { createHandlers } from '../create_handlers';
import { SECURITY_AUTH_MESSAGE } from '../../../common/lib/constants';
import { SECURITY_AUTH_MESSAGE } from '../../../common/constants';
let securityMode = 'pass';
let isSecurityAvailable = true;

View file

@ -1,12 +1,25 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import boom from 'boom';
import { SECURITY_AUTH_MESSAGE } from '../../common/lib/constants';
import { isSecurityEnabled } from './feature_check';
import { SECURITY_AUTH_MESSAGE } from '../../common/constants';
export const createHandlers = (request, server) => {
const { callWithRequest } = server.plugins.elasticsearch.getCluster('data');
@ -24,8 +37,9 @@ export const createHandlers = (request, server) => {
if (isSecurityEnabled(server)) {
try {
const authenticationResult = await server.plugins.security.authenticate(request);
if (!authenticationResult.succeeded())
if (!authenticationResult.succeeded()) {
throw boom.unauthorized(authenticationResult.error);
}
} catch (e) {
// if authenticate throws, show error in development
if (process.env.NODE_ENV !== 'production') {

View file

@ -0,0 +1,26 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// TODO: replace this when we use the method exposed by security https://github.com/elastic/kibana/pull/24616
export const isSecurityEnabled = server => {
const kibanaSecurity = server.plugins.security;
const esSecurity = server.plugins.xpack_main.info.feature('security');
return kibanaSecurity && esSecurity.isAvailable() && esSecurity.isEnabled();
};

View file

@ -0,0 +1,37 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import fs from 'fs';
import ss from 'stream-stream';
import { getPluginPaths } from '@kbn/interpreter/server/get_plugin_paths';
export const getPluginStream = type => {
const stream = ss({
separator: '\n',
});
getPluginPaths(type).then(files => {
files.forEach(file => {
stream.write(fs.createReadStream(file));
});
stream.end();
});
return stream;
};

View file

@ -0,0 +1,44 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import boom from 'boom';
import { API_ROUTE } from '../../common/constants';
export function getRequest(server, { headers }) {
const url = `${API_ROUTE}/ping`;
return server
.inject({
method: 'POST',
url,
headers,
})
.then(res => {
if (res.statusCode !== 200) {
if (process.env.NODE_ENV !== 'production') {
console.error(
new Error(`Auth request failed: [${res.statusCode}] ${res.result.message}`)
);
}
throw boom.unauthorized('Failed to authenticate socket connection');
}
return res.request;
});
}

View file

@ -1,7 +1,20 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import uuid from 'uuid/v4';

View file

@ -1,9 +1,23 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { createError } from '../../../common/interpreter/create_error';
import { createError } from '@kbn/interpreter/common/interpreter/create_error';
export const routeExpressionProvider = environments => {
async function routeExpression(ast, context = null) {

View file

@ -0,0 +1,40 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { getServerRegistries } from '@kbn/interpreter/server/server_registries';
import { interpretProvider } from '@kbn/interpreter/common/interpreter/interpret';
import { createHandlers } from '../create_handlers';
export const server = async ({ onFunctionNotFound, server, request }) => {
const { serverFunctions, types } = await getServerRegistries(['serverFunctions', 'types']);
return {
interpret: (ast, context) => {
const interpret = interpretProvider({
types: types.toJS(),
functions: serverFunctions.toJS(),
handlers: createHandlers(request, server),
onFunctionNotFound,
});
return interpret(ast, context);
},
getFunctions: () => Object.keys(serverFunctions.toJS()),
};
};

View file

@ -0,0 +1,32 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
require('babel-register')({
ignore: [
// stolen from kibana/src/setup_node_env/babel_register/register.js
// ignore paths matching `/node_modules/{a}/{b}`, unless `a`
// is `x-pack` and `b` is not `node_modules`
/\/node_modules\/(?!x-pack\/(?!node_modules)([^\/]+))([^\/]+\/[^\/]+)/,
],
babelrc: false,
presets: [require.resolve('@kbn/babel-preset/node_preset')],
});
require('./polyfill');
require('./worker');

View file

@ -1,7 +1,20 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { fork } from 'child_process';

View file

@ -0,0 +1,31 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// taken from kibana/src/setup_node_env/babel_register/polyfill.js
// ...
// `babel-preset-env` looks for and rewrites the following import
// statement into a list of import statements based on the polyfills
// necessary for our target environment (the current version of node)
// but since it does that during compilation, `import 'babel-polyfill'`
// must be in a file that is loaded with `require()` AFTER `babel-register`
// is configured.
//
// This is why we have this single statement in it's own file and require
// it from ./babeled.js
import 'babel-polyfill';

View file

@ -1,13 +1,26 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import uuid from 'uuid/v4';
import { populateServerRegistries } from '../../server_registries';
import { interpretProvider } from '../../../../common/interpreter/interpret';
import { serializeProvider } from '../../../../common/lib/serialize';
import { populateServerRegistries } from '@kbn/interpreter/server/server_registries';
import { interpretProvider } from '@kbn/interpreter/common/interpreter/interpret';
import { serializeProvider } from '@kbn/interpreter/common/lib/serialize';
// We actually DO need populateServerRegistries here since this is a different node process
const pluginsReady = populateServerRegistries(['commonFunctions', 'types']);
@ -44,8 +57,9 @@ process.on('message', msg => {
},
});
if (type === 'getFunctions')
if (type === 'getFunctions') {
process.send({ type: 'functionList', value: Object.keys(commonFunctions.toJS()) });
}
if (type === 'msgSuccess') {
heap[id].resolve(deserialize(value));

View file

@ -0,0 +1,28 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { socketApi } from './socket';
import { translate } from './translate';
import { plugins } from './plugins';
export function routes(server) {
plugins(server);
socketApi(server);
translate(server);
}

View file

@ -0,0 +1,35 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { getPluginStream } from '../lib/get_plugin_stream';
export function plugins(server) {
server.route({
method: 'GET',
path: '/api/canvas/plugins',
handler: function (request) {
const { type } = request.query;
return getPluginStream(type);
},
config: {
auth: false,
},
});
}

View file

@ -1,19 +1,32 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import socket from 'socket.io';
import { serializeProvider } from '../../common/lib/serialize';
import { typesRegistry } from '../../common/lib/types_registry';
import { getServerRegistries } from '../lib/server_registries';
import { routeExpressionProvider } from '../lib/route_expression';
import { serializeProvider } from '@kbn/interpreter/common/lib/serialize';
import { typesRegistry } from '@kbn/interpreter/common/lib/types_registry';
import { getServerRegistries } from '@kbn/interpreter/server/server_registries';
import { routeExpressionProvider } from '../lib/route_expression/index';
import { browser } from '../lib/route_expression/browser';
import { thread } from '../lib/route_expression/thread';
import { thread } from '../lib/route_expression/thread/index';
import { server as serverEnv } from '../lib/route_expression/server';
import { getRequest } from '../lib/get_request';
import { API_ROUTE } from '../../common/lib/constants';
import { API_ROUTE } from '../../common/constants';
async function getModifiedRequest(server, socket) {
try {

View file

@ -0,0 +1,48 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { fromExpression, toExpression } from '@kbn/interpreter/common/lib/ast';
export function translate(server) {
/*
Get AST from expression
*/
server.route({
method: 'GET',
path: '/api/canvas/ast',
handler: function (request, h) {
if (!request.query.expression) {
return h.response({ error: '"expression" query is required' }).code(400);
}
return fromExpression(request.query.expression);
},
});
server.route({
method: 'POST',
path: '/api/canvas/expression',
handler: function (request, h) {
try {
return toExpression(request.payload);
} catch (e) {
return h.response({ error: e.message }).code(400);
}
},
});
}

View file

@ -150,8 +150,9 @@ export default class BaseOptimizer {
},
{
test,
include: /[\/\\]node_modules[\/\\]x-pack[\/\\]/,
exclude: /[\/\\]node_modules[\/\\]x-pack[\/\\](.+?[\/\\])*node_modules[\/\\]/,
include: /[\/\\]node_modules[\/\\](x-pack|@kbn[\/\\]interpreter)[\/\\]/,
exclude: /[\/\\]node_modules[\/\\](x-pack|@kbn[\/\\]interpreter)[\/\\]node_modules[\/\\]/,
}
];
};

View file

@ -39,7 +39,7 @@ var ignore = [
// ignore paths matching `/node_modules/{a}/{b}`, unless `a`
// is `x-pack` and `b` is not `node_modules`
/\/node_modules\/(?!x-pack\/(?!node_modules)([^\/]+))([^\/]+\/[^\/]+)/
/\/node_modules\/(?!(x-pack\/|@kbn\/interpreter\/)(?!node_modules)([^\/]+))([^\/]+\/[^\/]+)/
];
if (global.__BUILT_WITH_BABEL__) {

View file

@ -201,4 +201,4 @@ describe('createOrUpgradeSavedConfig()', () => {
'5.4.0-rc1': true,
});
});
});
});

View file

@ -126,6 +126,7 @@
"@kbn/datemath": "5.0.0",
"@kbn/i18n": "1.0.0",
"@kbn/ui-framework": "1.0.0",
"@kbn/interpreter": "1.0.0",
"@samverschueren/stream-to-observable": "^0.3.0",
"@scant/router": "^0.1.0",
"@slack/client": "^4.2.2",

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { Fn } from '../../common/lib/fn';
import { Fn } from '@kbn/interpreter/common/lib/fn';
import { functions as browserFns } from '../../canvas_plugin_src/functions/browser';
import { functions as commonFns } from '../../canvas_plugin_src/functions/common';
import { functions as serverFns } from '../../canvas_plugin_src/functions/server/src';

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { getType } from '../../../common/lib/get_type';
import { getType } from '@kbn/interpreter/common/lib/get_type';
export const asFn = () => ({
name: 'as',

View file

@ -1,14 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export const clog = () => ({
name: 'clog',
help: 'Outputs the context to the console',
fn: context => {
console.log(context); //eslint-disable-line no-console
return context;
},
});

View file

@ -11,7 +11,6 @@ import { asFn } from './as';
import { axisConfig } from './axisConfig';
import { compare } from './compare';
import { containerStyle } from './containerStyle';
import { clog } from './clog';
import { context } from './context';
import { columns } from './columns';
import { csv } from './csv';
@ -65,7 +64,6 @@ export const functions = [
any,
asFn,
axisConfig,
clog,
columns,
compare,
containerStyle,

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { getType } from '../../../common/lib/get_type';
import { getType } from '@kbn/interpreter/common/lib/get_type';
export const mapColumn = () => ({
name: 'mapColumn',

View file

@ -5,7 +5,7 @@
*/
import { get, map } from 'lodash';
import { getType } from '../../../../common/lib/get_type';
import { getType } from '@kbn/interpreter/common/lib/get_type';
export const getFlotAxisConfig = (axis, argValue, { columns, ticks, font } = {}) => {
if (!argValue || argValue.show === false) return { show: false };

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { getType } from '../../../common/lib/get_type';
import { getType } from '@kbn/interpreter/common/lib/get_type';
export const staticColumn = () => ({
name: 'staticColumn',

View file

@ -7,7 +7,7 @@
import ReactDOM from 'react-dom';
import React from 'react';
import { get } from 'lodash';
import { fromExpression, toExpression } from '../../../common/lib/ast';
import { fromExpression, toExpression } from '@kbn/interpreter/common/lib/ast';
import { DropdownFilter } from './component';
export const dropdownFilter = () => ({

View file

@ -7,7 +7,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { get } from 'lodash';
import { fromExpression } from '../../../../../common/lib/ast';
import { fromExpression } from '@kbn/interpreter/common/lib/ast';
import { TimePicker } from '../time_picker';
import { TimePickerMini } from '../time_picker_mini';

View file

@ -7,7 +7,7 @@
import ReactDOM from 'react-dom';
import React from 'react';
import { get, set } from 'lodash';
import { fromExpression, toExpression } from '../../../common/lib/ast';
import { fromExpression, toExpression } from '@kbn/interpreter/common/lib/ast';
import { TimeFilter } from './components/time_filter';
export const timeFilter = () => ({

View file

@ -1,29 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export const boolean = () => ({
name: 'boolean',
from: {
null: () => false,
number: n => Boolean(n),
string: s => Boolean(s),
},
to: {
render: value => {
const text = `${value}`;
return {
type: 'render',
as: 'text',
value: { text },
};
},
datatable: value => ({
type: 'datatable',
columns: [{ name: 'value', type: 'boolean' }],
rows: [{ value }],
}),
},
});

View file

@ -1,22 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export const error = () => ({
name: 'error',
to: {
render: input => {
const { error, info } = input;
return {
type: 'render',
as: 'error',
value: {
error,
info,
},
};
},
},
});

View file

@ -1,20 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export const filter = () => ({
name: 'filter',
from: {
null: () => {
return {
type: 'filter',
// Any meta data you wish to pass along.
meta: {},
// And filters. If you need an "or", create a filter type for it.
and: [],
};
},
},
});

View file

@ -1,18 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export const image = () => ({
name: 'image',
to: {
render: input => {
return {
type: 'render',
as: 'image',
value: input,
};
},
},
});

View file

@ -1,33 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { boolean } from './boolean';
import { datatable } from './datatable';
import { error } from './error';
import { filter } from './filter';
import { image } from './image';
import { nullType } from './null';
import { number } from './number';
import { pointseries } from './pointseries';
import { render } from './render';
import { shape } from './shape';
import { string } from './string';
import { style } from './style';
export const typeSpecs = [
boolean,
datatable,
error,
filter,
image,
number,
nullType,
pointseries,
render,
shape,
string,
style,
];

View file

@ -1,12 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export const nullType = () => ({
name: 'null',
from: {
'*': () => null,
},
});

View file

@ -1,29 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export const number = () => ({
name: 'number',
from: {
null: () => 0,
boolean: b => Number(b),
string: n => Number(n),
},
to: {
render: value => {
const text = `${value}`;
return {
type: 'render',
as: 'text',
value: { text },
};
},
datatable: value => ({
type: 'datatable',
columns: [{ name: 'value', type: 'number' }],
rows: [{ value }],
}),
},
});

View file

@ -1,31 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export const pointseries = () => ({
name: 'pointseries',
from: {
null: () => {
return {
type: 'pointseries',
rows: [],
columns: [],
};
},
},
to: {
render: (pointseries, types) => {
const datatable = types.datatable.from(pointseries, types);
return {
type: 'render',
as: 'table',
value: {
datatable,
showHeader: true,
},
};
},
},
});

View file

@ -1,10 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import 'babel-polyfill';
import { typeSpecs } from './index';
typeSpecs.forEach(canvas.register);

View file

@ -1,16 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export const render = () => ({
name: 'render',
from: {
'*': v => ({
type: 'render',
as: 'debug',
value: v,
}),
},
});

View file

@ -1,18 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export const shape = () => ({
name: 'shape',
to: {
render: input => {
return {
type: 'render',
as: 'shape',
value: input,
};
},
},
});

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