| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158 |
1×
1×
1×
1×
1×
1×
1×
1×
1×
2×
1×
1×
1×
1×
1×
1×
3×
3×
1×
1×
55×
55×
55×
55×
1×
1×
1×
1×
55×
8×
8×
6×
42×
| /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
var Action = require("../actionNames");
var ModalDialog = require("../modal/modalDialog.js");
var DatasourcePlugins = require("../datasource/datasourcePlugins");
var WidgetPlugins = require("../widgets/widgetPlugins");
var initialState = {
loadingUrls: []
};
function isUrl(url) {
return _.startsWith(url, "/") || !_.startsWith(url, ".") || !_.startsWith(url, "http:") || !_.startsWith(url, "https:");
}
/**
* Load plugin from URL or registry when starting with plugin://
*/
function startLoadingPluginFromUrl(url) {
return function (dispatch, getState) {
var state = getState();
var registryBaseUrl = state.config.pluginRegistryUrl;
if (_.startsWith(url, "plugin://")) {
url = url.replace("plugin://", registryBaseUrl + "/api/plugin-files/");
}
// No absolute or relative URL
if (!isUrl(url)) {
url = registryBaseUrl + "/api/plugin-files/" + url;
}
if (_.some(_.valuesIn(state.datasourcePlugins), function (p) { return p.url === url && !p.isLoading; })) {
dispatch(ModalDialog.addError("Plugin already loaded: " + url));
return;
}
if (_.some(_.valuesIn(state.widgetPlugins), function (p) { return p.url === url && !p.isLoading; })) {
dispatch(ModalDialog.addError("Plugin already loaded: " + url));
return;
}
dispatch({
type: Action.STARTED_LOADING_PLUGIN_FROM_URL,
url: url
});
};
}
exports.startLoadingPluginFromUrl = startLoadingPluginFromUrl;
function reloadExistingPlugin(url, id) {
return {
type: Action.STARTED_LOADING_PLUGIN_FROM_URL,
id: id,
url: url
};
}
exports.reloadExistingPlugin = reloadExistingPlugin;
function pluginFailedLoading(url) {
return function (dispatch) {
dispatch(ModalDialog.addError("Failed to load plugin from " + url));
dispatch({
type: Action.PLUGIN_FAILED_LOADING,
url: url
});
};
}
exports.pluginFailedLoading = pluginFailedLoading;
function widgetPluginFinishedLoading(plugin, url) {
if (url === void 0) { url = null; }
return {
type: Action.WIDGET_PLUGIN_FINISHED_LOADING,
id: plugin.TYPE_INFO.type,
typeInfo: plugin.TYPE_INFO,
isLoading: false,
url: url
};
}
exports.widgetPluginFinishedLoading = widgetPluginFinishedLoading;
function datasourcePluginFinishedLoading(plugin, url) {
if (url === void 0) { url = null; }
return {
type: Action.DATASOURCE_PLUGIN_FINISHED_LOADING,
id: plugin.TYPE_INFO.type,
typeInfo: plugin.TYPE_INFO,
isLoading: false,
url: url
};
}
exports.datasourcePluginFinishedLoading = datasourcePluginFinishedLoading;
function pluginLoaderReducer(state, action) {
if (state === void 0) { state = initialState; }
var newState = _.assign({}, state);
newState.loadingUrls = urlsReducer(state.loadingUrls, action);
return newState;
}
exports.pluginLoaderReducer = pluginLoaderReducer;
function publishPlugin(id, usePlugin) {
return function (dispatch, getState) {
var state = getState();
var dsPlugin = state.datasourcePlugins[id];
var widgetPlugin = state.widgetPlugins[id];
var isDatasource = !!dsPlugin;
var plugin = isDatasource ? dsPlugin : widgetPlugin;
var registryBaseUrl = state.config.pluginRegistryUrl;
var apiKey = state.config.pluginRegistryApiKey;
fetch(plugin.url, {
method: 'get'
}).then(function (response) {
return response.text();
}).then(function (scriptContent) {
var data = {
"MetaInfo": plugin.typeInfo,
"Code": scriptContent
};
return fetch(registryBaseUrl + '/api/plugins/' + id, {
method: 'post',
body: JSON.stringify(data),
headers: {
Authorization: apiKey
}
});
}).then(function (response) {
if (response.status >= 400) {
return response.json().then(function (json) {
if (json.error) {
throw new Error("Failed to publish Plugin: " + json.error);
}
throw new Error("Failed to publish Plugin");
});
}
return response.json();
}).then(function (json) {
dispatch(ModalDialog.addInfo("Published plugin: " + id + " at " + registryBaseUrl + json.url));
if (usePlugin) {
if (isDatasource) {
dispatch(DatasourcePlugins.usePublishedDatasourcePlugin(id, registryBaseUrl + json.url, json.typeInfo));
}
else {
dispatch(WidgetPlugins.usePublishedWidgetPlugin(id, registryBaseUrl + json.url, json.typeInfo));
}
}
}).catch(function (err) {
dispatch(ModalDialog.addError(err.message));
});
};
}
exports.publishPlugin = publishPlugin;
function urlsReducer(state, action) {
switch (action.type) {
case Action.STARTED_LOADING_PLUGIN_FROM_URL:
Iif (!action.url) {
throw new Error("Can not load plugin from empty URL");
}
return state.slice().concat([action.url]);
case Action.PLUGIN_FAILED_LOADING:
case Action.WIDGET_PLUGIN_FINISHED_LOADING:
case Action.DATASOURCE_PLUGIN_FINISHED_LOADING:
return state.slice().filter(function (url) { return url !== action.url; });
default:
return state;
}
}
|