diff --git a/package.json b/package.json
index df4fbfb681f6..eb792ff93702 100644
--- a/package.json
+++ b/package.json
@@ -225,6 +225,7 @@
"@kbn/eslint-plugin-license-header": "link:packages/kbn-eslint-plugin-license-header",
"@kbn/plugin-generator": "link:packages/kbn-plugin-generator",
"@kbn/test": "link:packages/kbn-test",
+ "@types/babel-core": "^6.25.5",
"@types/angular": "^1.6.45",
"@types/babel-core": "^6.25.5",
"@types/bluebird": "^3.1.1",
diff --git a/src/core_plugins/kibana/public/kibana.js b/src/core_plugins/kibana/public/kibana.js
index 2cc54a5b8103..aa5a563ca710 100644
--- a/src/core_plugins/kibana/public/kibana.js
+++ b/src/core_plugins/kibana/public/kibana.js
@@ -30,6 +30,7 @@ import 'uiExports/visTypes';
import 'uiExports/visResponseHandlers';
import 'uiExports/visRequestHandlers';
import 'uiExports/visEditorTypes';
+import 'uiExports/visualize';
import 'uiExports/savedObjectTypes';
import 'uiExports/fieldFormats';
import 'uiExports/fieldFormatEditors';
diff --git a/src/core_plugins/kibana/public/visualize/editor/editor.js b/src/core_plugins/kibana/public/visualize/editor/editor.js
index 0beae4c623b1..da49932d0efe 100644
--- a/src/core_plugins/kibana/public/visualize/editor/editor.js
+++ b/src/core_plugins/kibana/public/visualize/editor/editor.js
@@ -20,7 +20,6 @@
import _ from 'lodash';
import '../saved_visualizations/saved_visualizations';
import 'ui/vis/editors/default/sidebar';
-import './agg_filter';
import 'ui/visualize';
import 'ui/collapsible_sidebar';
import 'ui/share';
diff --git a/src/core_plugins/kibana/public/visualize/index.js b/src/core_plugins/kibana/public/visualize/index.js
index c7b57bcb75f5..255e4a2eaea5 100644
--- a/src/core_plugins/kibana/public/visualize/index.js
+++ b/src/core_plugins/kibana/public/visualize/index.js
@@ -20,7 +20,6 @@
import './styles/main.less';
import './editor/editor';
import './wizard/wizard';
-import './editor/agg_filter';
import 'ui/draggable/draggable_container';
import 'ui/draggable/draggable_item';
import 'ui/draggable/draggable_handle';
diff --git a/src/ui/public/agg_types/__tests__/buckets/date_histogram/_editor.js b/src/ui/public/agg_types/__tests__/buckets/date_histogram/_editor.js
index 2fd398a879cd..40202efa568b 100644
--- a/src/ui/public/agg_types/__tests__/buckets/date_histogram/_editor.js
+++ b/src/ui/public/agg_types/__tests__/buckets/date_histogram/_editor.js
@@ -58,11 +58,12 @@ describe('editor', function () {
]
});
- const $el = $('');
+ const $el = $('');
const $parentScope = $injector.get('$rootScope').$new();
agg = $parentScope.agg = vis.aggs.bySchemaName.segment[0];
$parentScope.groupName = 'buckets';
+ $parentScope.vis = vis;
$compile($el)($parentScope);
$scope = $el.scope();
diff --git a/src/ui/public/agg_types/agg_type.d.ts b/src/ui/public/agg_types/agg_type.d.ts
new file mode 100644
index 000000000000..5485221cb543
--- /dev/null
+++ b/src/ui/public/agg_types/agg_type.d.ts
@@ -0,0 +1,20 @@
+/*
+ * 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 type AggType = any;
diff --git a/src/ui/public/agg_types/controls/order_agg.html b/src/ui/public/agg_types/controls/order_agg.html
index 8066dc91da17..61f2cec29a49 100644
--- a/src/ui/public/agg_types/controls/order_agg.html
+++ b/src/ui/public/agg_types/controls/order_agg.html
@@ -24,6 +24,7 @@
diff --git a/src/ui/public/agg_types/controls/sub_agg.html b/src/ui/public/agg_types/controls/sub_agg.html
index 5b99d2de4c75..76936a586196 100644
--- a/src/ui/public/agg_types/controls/sub_agg.html
+++ b/src/ui/public/agg_types/controls/sub_agg.html
@@ -25,6 +25,7 @@
diff --git a/src/ui/public/agg_types/controls/sub_metric.html b/src/ui/public/agg_types/controls/sub_metric.html
index 88011451676b..d6805e7560b8 100644
--- a/src/ui/public/agg_types/controls/sub_metric.html
+++ b/src/ui/public/agg_types/controls/sub_metric.html
@@ -5,6 +5,7 @@
diff --git a/src/ui/public/agg_types/filter/agg_type_filters.test.ts b/src/ui/public/agg_types/filter/agg_type_filters.test.ts
new file mode 100644
index 000000000000..915f688e7aca
--- /dev/null
+++ b/src/ui/public/agg_types/filter/agg_type_filters.test.ts
@@ -0,0 +1,76 @@
+/*
+ * 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 { first } from 'rxjs/operators';
+import { AggTypeFilters } from './agg_type_filters';
+
+describe('AggTypeFilters', () => {
+ let registry: AggTypeFilters;
+ const indexPattern = {};
+ const aggConfig = {};
+
+ beforeEach(() => {
+ registry = new AggTypeFilters();
+ });
+
+ it('should filter nothing without registered filters', async () => {
+ const aggTypes = [{ name: 'count' }, { name: 'sum' }];
+ const observable = registry.filter$(aggTypes, indexPattern, aggConfig);
+ const filtered = await observable.pipe(first()).toPromise();
+ expect(filtered).toEqual(aggTypes);
+ });
+
+ it('should emit a new filtered list when registering a new filter', async () => {
+ const aggTypes = [{ name: 'count' }, { name: 'sum' }];
+ const observable = registry.filter$(aggTypes, indexPattern, aggConfig);
+ const spy = jest.fn();
+ observable.subscribe(spy);
+ expect(spy).toHaveBeenCalledTimes(1);
+ registry.addFilter(() => true);
+ expect(spy).toHaveBeenCalledTimes(2);
+ });
+
+ it('should pass all aggTypes to the registered filter', async () => {
+ const aggTypes = [{ name: 'count' }, { name: 'sum' }];
+ const filter = jest.fn();
+ registry.addFilter(filter);
+ await registry
+ .filter$(aggTypes, indexPattern, aggConfig)
+ .pipe(first())
+ .toPromise();
+ expect(filter).toHaveBeenCalledWith(aggTypes[0], indexPattern, aggConfig);
+ expect(filter).toHaveBeenCalledWith(aggTypes[1], indexPattern, aggConfig);
+ });
+
+ it('should allow registered filters to filter out aggTypes', async () => {
+ const aggTypes = [{ name: 'count' }, { name: 'sum' }, { name: 'avg' }];
+ const observable = registry.filter$(aggTypes, indexPattern, aggConfig);
+ let filtered = await observable.pipe(first()).toPromise();
+ expect(filtered).toEqual(aggTypes);
+
+ registry.addFilter(() => true);
+ registry.addFilter(aggType => aggType.name !== 'count');
+ filtered = await observable.pipe(first()).toPromise();
+ expect(filtered).toEqual([aggTypes[1], aggTypes[2]]);
+
+ registry.addFilter(aggType => aggType.name !== 'avg');
+ filtered = await observable.pipe(first()).toPromise();
+ expect(filtered).toEqual([aggTypes[1]]);
+ });
+});
diff --git a/src/ui/public/agg_types/filter/agg_type_filters.ts b/src/ui/public/agg_types/filter/agg_type_filters.ts
new file mode 100644
index 000000000000..8840af54e8cd
--- /dev/null
+++ b/src/ui/public/agg_types/filter/agg_type_filters.ts
@@ -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 { BehaviorSubject } from 'rxjs';
+import { map } from 'rxjs/operators';
+import { AggType } from '..';
+import { IndexPattern } from '../../index_patterns';
+import { AggConfig } from '../../vis';
+
+type AggTypeFilter = (
+ aggType: AggType,
+ indexPattern: IndexPattern,
+ aggConfig: AggConfig
+) => boolean;
+
+/**
+ * A registry to store {@link AggTypeFilter} which are used to filter down
+ * available aggregations for a specific visualization and {@link AggConfig}.
+ */
+class AggTypeFilters {
+ private filters = new Set();
+ private subject = new BehaviorSubject>(this.filters);
+
+ /**
+ * Register a new {@link AggTypeFilter} with this registry.
+ * This will emit a new set of filtered aggTypes on every Observer returned
+ * by the {@link #filter$|filter method}.
+ *
+ * @param filter The filter to register.
+ */
+ public addFilter(filter: AggTypeFilter): void {
+ this.filters.add(filter);
+ this.subject.next(this.filters);
+ }
+
+ /**
+ * Returns an Observable that will emit a filtered list of the passed {@link AggType|aggTypes}.
+ * A new filtered list will always be emitted when the {@link AggTypeFilter}
+ * registered with this registry will change.
+ *
+ * @param aggTypes A list of aggTypes that will be filtered down by this registry.
+ * @param indexPattern The indexPattern for which this list should be filtered down.
+ * @param aggConfig The aggConfig for which the returning list will be used.
+ * @return A filtered list of the passed aggTypes.
+ */
+ public filter$(
+ aggTypes: AggType[],
+ indexPattern: IndexPattern,
+ aggConfig: AggConfig
+ ) {
+ return this.subject.pipe(
+ map(filters => {
+ const allFilters = Array.from(filters);
+ const allowedAggTypes = aggTypes.filter(aggType => {
+ const isAggTypeAllowed = allFilters.every(filter =>
+ filter(aggType, indexPattern, aggConfig)
+ );
+ return isAggTypeAllowed;
+ });
+ return allowedAggTypes;
+ })
+ );
+ }
+}
+
+const aggTypeFilters = new AggTypeFilters();
+
+export { aggTypeFilters, AggTypeFilters };
diff --git a/src/ui/public/agg_types/filter/index.ts b/src/ui/public/agg_types/filter/index.ts
new file mode 100644
index 000000000000..9582119b28b3
--- /dev/null
+++ b/src/ui/public/agg_types/filter/index.ts
@@ -0,0 +1,20 @@
+/*
+ * 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 { aggTypeFilters } from './agg_type_filters';
diff --git a/src/ui/public/agg_types/index.d.ts b/src/ui/public/agg_types/index.d.ts
new file mode 100644
index 000000000000..81d52bb8e788
--- /dev/null
+++ b/src/ui/public/agg_types/index.d.ts
@@ -0,0 +1,20 @@
+/*
+ * 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 { AggType } from './agg_type';
diff --git a/src/core_plugins/kibana/public/visualize/editor/agg_filter.js b/src/ui/public/filters/_prop_filter.d.ts
similarity index 80%
rename from src/core_plugins/kibana/public/visualize/editor/agg_filter.js
rename to src/ui/public/filters/_prop_filter.d.ts
index 782a8fa7a154..284619b50fb6 100644
--- a/src/core_plugins/kibana/public/visualize/editor/agg_filter.js
+++ b/src/ui/public/filters/_prop_filter.d.ts
@@ -17,11 +17,8 @@
* under the License.
*/
-import { propFilter } from 'ui/filters/_prop_filter';
-import { uiModules } from 'ui/modules';
+type FilterFunc = (item: I) => boolean;
-uiModules
- .get('kibana')
- .filter('aggFilter', function () {
- return propFilter('name');
- });
+export const propFilter: (
+ prop: string
+) => (list: T[], filters: string[] | string | FilterFunc) => T[];
diff --git a/src/ui/public/index_patterns/_index_pattern.d.ts b/src/ui/public/index_patterns/_index_pattern.d.ts
new file mode 100644
index 000000000000..d31b546a6a97
--- /dev/null
+++ b/src/ui/public/index_patterns/_index_pattern.d.ts
@@ -0,0 +1,20 @@
+/*
+ * 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 type IndexPattern = any;
diff --git a/src/ui/public/index_patterns/index.d.ts b/src/ui/public/index_patterns/index.d.ts
new file mode 100644
index 000000000000..44bcd163d174
--- /dev/null
+++ b/src/ui/public/index_patterns/index.d.ts
@@ -0,0 +1,20 @@
+/*
+ * 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 { IndexPattern } from './_index_pattern';
diff --git a/src/ui/public/vis/agg_config.d.ts b/src/ui/public/vis/agg_config.d.ts
new file mode 100644
index 000000000000..8ed9023ab247
--- /dev/null
+++ b/src/ui/public/vis/agg_config.d.ts
@@ -0,0 +1,20 @@
+/*
+ * 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 type AggConfig = any;
diff --git a/src/ui/public/vis/editors/default/__tests__/agg_params.js b/src/ui/public/vis/editors/default/__tests__/agg_params.js
index 3497db7cec6b..70abf6d676f7 100644
--- a/src/ui/public/vis/editors/default/__tests__/agg_params.js
+++ b/src/ui/public/vis/editors/default/__tests__/agg_params.js
@@ -77,10 +77,11 @@ describe('Vis-Editor-Agg-Params plugin directive', function () {
});
$parentScope.agg = new AggConfig(vis, state);
+ $parentScope.vis = vis;
// make the element
$elem = angular.element(
- ``
+ ``
);
// compile the html
diff --git a/src/ui/public/vis/editors/default/agg.html b/src/ui/public/vis/editors/default/agg.html
index 0d2970076be4..9241473dc07d 100644
--- a/src/ui/public/vis/editors/default/agg.html
+++ b/src/ui/public/vis/editors/default/agg.html
@@ -93,6 +93,7 @@
agg="agg"
group-name="groupName"
ng-show="editorOpen"
+ index-pattern="vis.indexPattern"
class="vis-editor-agg-editor">
diff --git a/src/ui/public/vis/editors/default/agg_params.js b/src/ui/public/vis/editors/default/agg_params.js
index 9a8660ae5be3..cf4d7b1f7d49 100644
--- a/src/ui/public/vis/editors/default/agg_params.js
+++ b/src/ui/public/vis/editors/default/agg_params.js
@@ -27,6 +27,7 @@ import { aggTypes } from '../../../agg_types';
import { uiModules } from '../../../modules';
import { documentationLinks } from '../../../documentation_links/documentation_links';
import aggParamsTemplate from './agg_params.html';
+import { aggTypeFilters } from '../../../agg_types/filter';
uiModules
.get('app/visualize')
@@ -39,8 +40,16 @@ uiModules
link: function ($scope, $el, attr) {
$scope.$bind('agg', attr.agg);
$scope.$bind('groupName', attr.groupName);
+ $scope.$bind('indexPattern', attr.indexPattern);
+
+ const aggTypeSubscription = aggTypeFilters
+ .filter$(aggTypes.byType[$scope.groupName], $scope.indexPattern, $scope.agg)
+ .subscribe(aggTypes => $scope.aggTypeOptions = aggTypes);
+
+ $scope.$on('$destroy', () => {
+ aggTypeSubscription.unsubscribe();
+ });
- $scope.aggTypeOptions = aggTypes.byType[$scope.groupName];
$scope.advancedToggled = false;
// We set up this watch prior to adding the controls below, because when the controls are added,
diff --git a/src/ui/public/vis/editors/default/agg_select.html b/src/ui/public/vis/editors/default/agg_select.html
index 05910af4a626..1a966dd31eb7 100644
--- a/src/ui/public/vis/editors/default/agg_select.html
+++ b/src/ui/public/vis/editors/default/agg_select.html
@@ -25,7 +25,6 @@
{
+ const doesSchemaAllowAggType =
+ filterByName([aggType], aggConfig.schema.aggFilter).length !== 0;
+ return doesSchemaAllowAggType;
+ }
+);
diff --git a/src/ui/public/vis/index.d.ts b/src/ui/public/vis/index.d.ts
new file mode 100644
index 000000000000..0ee214507a9f
--- /dev/null
+++ b/src/ui/public/vis/index.d.ts
@@ -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 { AggConfig } from './agg_config';
+export { Vis, VisProvider } from './vis';
diff --git a/src/ui/public/vis/vis.d.ts b/src/ui/public/vis/vis.d.ts
new file mode 100644
index 000000000000..004795920ab4
--- /dev/null
+++ b/src/ui/public/vis/vis.d.ts
@@ -0,0 +1,22 @@
+/*
+ * 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 type Vis = any;
+
+export type VisProvider = (...dependencies: any[]) => Vis;
diff --git a/src/ui/ui_exports/ui_export_types/index.js b/src/ui/ui_exports/ui_export_types/index.js
index 1fb32b0eb021..b584cdbc27ec 100644
--- a/src/ui/ui_exports/ui_export_types/index.js
+++ b/src/ui/ui_exports/ui_export_types/index.js
@@ -51,6 +51,7 @@ export {
home,
visTypeEnhancers,
aliases,
+ visualize
} from './ui_app_extensions';
export {
diff --git a/src/ui/ui_exports/ui_export_types/ui_app_extensions.js b/src/ui/ui_exports/ui_export_types/ui_app_extensions.js
index bee0dca31e87..a01e7059d794 100644
--- a/src/ui/ui_exports/ui_export_types/ui_app_extensions.js
+++ b/src/ui/ui_exports/ui_export_types/ui_app_extensions.js
@@ -50,6 +50,8 @@ export const docViews = appExtension;
export const hacks = appExtension;
export const home = appExtension;
export const inspectorViews = appExtension;
+// Add a visualize app extension that should be used for visualize specific stuff
+export const visualize = appExtension;
// aliases visTypeEnhancers to the visTypes group
export const visTypeEnhancers = wrap(alias('visTypes'), appExtension);