2023-08-31 15:45:44 +02:00
|
|
|
import {
|
|
|
|
|
AppPlugin,
|
|
|
|
|
DataSourceApi,
|
|
|
|
|
DataSourceJsonData,
|
|
|
|
|
DataSourcePlugin,
|
|
|
|
|
DataSourcePluginMeta,
|
|
|
|
|
PluginMeta,
|
|
|
|
|
} from '@grafana/data';
|
|
|
|
|
import { SystemJS } from '@grafana/runtime';
|
|
|
|
|
import { DataQuery } from '@grafana/schema';
|
2022-04-22 14:33:13 +01:00
|
|
|
|
2022-07-20 09:25:09 +02:00
|
|
|
import { GenericDataSourcePlugin } from '../datasources/types';
|
2022-04-22 14:33:13 +01:00
|
|
|
|
|
|
|
|
import builtInPlugins from './built_in_plugins';
|
2023-08-31 15:45:44 +02:00
|
|
|
import { registerPluginInCache } from './loader/cache';
|
|
|
|
|
import { sharedDependenciesMap } from './loader/sharedDependencies';
|
|
|
|
|
import { decorateSystemJSFetch, decorateSystemJSResolve, decorateSystemJsOnload } from './loader/systemjsHooks';
|
|
|
|
|
import { SystemJSWithLoaderHooks } from './loader/types';
|
|
|
|
|
import { buildImportMap } from './loader/utils';
|
2023-06-05 10:51:36 +02:00
|
|
|
import { importPluginModuleInSandbox } from './sandbox/sandbox_plugin_loader';
|
2023-08-31 15:45:44 +02:00
|
|
|
import { isFrontendSandboxSupported } from './sandbox/utils';
|
2023-04-27 07:18:38 +02:00
|
|
|
|
2023-08-31 15:45:44 +02:00
|
|
|
const imports = buildImportMap(sharedDependenciesMap);
|
|
|
|
|
SystemJS.addImportMap({ imports });
|
2017-10-26 12:07:23 +02:00
|
|
|
|
2023-08-31 15:45:44 +02:00
|
|
|
const systemJSPrototype: SystemJSWithLoaderHooks = SystemJS.constructor.prototype;
|
2018-06-14 12:32:57 +01:00
|
|
|
|
2023-08-31 15:45:44 +02:00
|
|
|
// Monaco Editors reliance on RequireJS means we need to transform
|
|
|
|
|
// the content of the plugin code at runtime which can only be done with fetch/eval.
|
|
|
|
|
systemJSPrototype.shouldFetch = () => true;
|
2017-10-20 10:38:52 +02:00
|
|
|
|
2023-08-31 15:45:44 +02:00
|
|
|
const systemJSFetch = systemJSPrototype.fetch;
|
|
|
|
|
systemJSPrototype.fetch = function (url: string, options?: Record<string, unknown>) {
|
|
|
|
|
return decorateSystemJSFetch(systemJSFetch, url, options);
|
|
|
|
|
};
|
2019-04-12 09:45:22 -07:00
|
|
|
|
2023-08-31 15:45:44 +02:00
|
|
|
const systemJSResolve = systemJSPrototype.resolve;
|
|
|
|
|
systemJSPrototype.resolve = decorateSystemJSResolve.bind(systemJSPrototype, systemJSResolve);
|
2017-10-01 20:02:25 +02:00
|
|
|
|
2023-08-31 15:45:44 +02:00
|
|
|
// Older plugins load .css files which resolves to a CSS Module.
|
|
|
|
|
// https://github.com/WICG/webcomponents/blob/gh-pages/proposals/css-modules-v1-explainer.md#importing-a-css-module
|
|
|
|
|
// Any css files loaded via SystemJS have their styles applied onload.
|
|
|
|
|
systemJSPrototype.onload = decorateSystemJsOnload;
|
2017-10-01 20:02:25 +02:00
|
|
|
|
2023-06-05 10:51:36 +02:00
|
|
|
export async function importPluginModule({
|
|
|
|
|
path,
|
|
|
|
|
version,
|
|
|
|
|
isAngular,
|
|
|
|
|
pluginId,
|
|
|
|
|
}: {
|
|
|
|
|
path: string;
|
|
|
|
|
pluginId: string;
|
|
|
|
|
version?: string;
|
|
|
|
|
isAngular?: boolean;
|
2023-08-31 15:45:44 +02:00
|
|
|
}): Promise<System.Module> {
|
2021-11-10 11:54:58 +01:00
|
|
|
if (version) {
|
|
|
|
|
registerPluginInCache({ path, version });
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-26 17:14:40 +02:00
|
|
|
const builtIn = builtInPlugins[path];
|
2017-10-01 20:02:25 +02:00
|
|
|
if (builtIn) {
|
2019-09-03 09:29:02 +01:00
|
|
|
// for handling dynamic imports
|
|
|
|
|
if (typeof builtIn === 'function') {
|
|
|
|
|
return await builtIn();
|
|
|
|
|
} else {
|
2021-11-10 19:06:55 +01:00
|
|
|
return builtIn;
|
2019-09-03 09:29:02 +01:00
|
|
|
}
|
2017-10-01 20:02:25 +02:00
|
|
|
}
|
2023-06-05 10:51:36 +02:00
|
|
|
|
|
|
|
|
// the sandboxing environment code cannot work in nodejs and requires a real browser
|
2023-07-05 11:16:56 +02:00
|
|
|
if (isFrontendSandboxSupported({ isAngular, pluginId })) {
|
2023-06-05 10:51:36 +02:00
|
|
|
return importPluginModuleInSandbox({ pluginId });
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-31 15:45:44 +02:00
|
|
|
return SystemJS.import(path);
|
2023-06-05 10:51:36 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-31 15:45:44 +02:00
|
|
|
export function importDataSourcePlugin(meta: DataSourcePluginMeta): Promise<GenericDataSourcePlugin> {
|
2023-06-05 10:51:36 +02:00
|
|
|
return importPluginModule({
|
|
|
|
|
path: meta.module,
|
|
|
|
|
version: meta.info?.version,
|
|
|
|
|
isAngular: meta.angularDetected,
|
|
|
|
|
pluginId: meta.id,
|
|
|
|
|
}).then((pluginExports) => {
|
2019-04-04 18:30:15 +02:00
|
|
|
if (pluginExports.plugin) {
|
2023-08-31 15:45:44 +02:00
|
|
|
const dsPlugin: GenericDataSourcePlugin = pluginExports.plugin;
|
2019-04-30 22:36:46 -07:00
|
|
|
dsPlugin.meta = meta;
|
|
|
|
|
return dsPlugin;
|
2019-04-04 18:30:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pluginExports.Datasource) {
|
2023-08-31 15:45:44 +02:00
|
|
|
const dsPlugin = new DataSourcePlugin<
|
|
|
|
|
DataSourceApi<DataQuery, DataSourceJsonData>,
|
|
|
|
|
DataQuery,
|
|
|
|
|
DataSourceJsonData
|
2019-11-15 09:18:09 +00:00
|
|
|
>(pluginExports.Datasource);
|
2019-04-04 18:30:15 +02:00
|
|
|
dsPlugin.setComponentsFromLegacyExports(pluginExports);
|
2019-04-30 22:36:46 -07:00
|
|
|
dsPlugin.meta = meta;
|
2019-04-04 18:30:15 +02:00
|
|
|
return dsPlugin;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw new Error('Plugin module is missing DataSourcePlugin or Datasource constructor export');
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-31 15:45:44 +02:00
|
|
|
export function importAppPlugin(meta: PluginMeta): Promise<AppPlugin> {
|
2023-06-05 10:51:36 +02:00
|
|
|
return importPluginModule({
|
|
|
|
|
path: meta.module,
|
|
|
|
|
version: meta.info?.version,
|
|
|
|
|
isAngular: meta.angularDetected,
|
|
|
|
|
pluginId: meta.id,
|
|
|
|
|
}).then((pluginExports) => {
|
2023-08-31 15:45:44 +02:00
|
|
|
const plugin: AppPlugin = pluginExports.plugin ? pluginExports.plugin : new AppPlugin();
|
2019-05-20 13:05:23 -07:00
|
|
|
plugin.init(meta);
|
|
|
|
|
plugin.meta = meta;
|
2019-06-15 08:26:31 +02:00
|
|
|
plugin.setComponentsFromLegacyExports(pluginExports);
|
2019-04-30 22:36:46 -07:00
|
|
|
return plugin;
|
2019-04-04 18:30:15 +02:00
|
|
|
});
|
|
|
|
|
}
|