diff --git a/api-extractor.json b/api-extractor.json index 2751721e9d5..af1049c5a08 100644 --- a/api-extractor.json +++ b/api-extractor.json @@ -23,6 +23,10 @@ "extractorMessageReporting": { "default": { "logLevel": "warning" + }, + "ae-internal-missing-underscore": { + "logLevel": "none", + "addToApiReportFile": false } }, "tsdocMessageReporting": { diff --git a/packages/grafana-runtime/src/config.ts b/packages/grafana-runtime/src/config.ts index 406a741b119..0aef5f8dbe4 100644 --- a/packages/grafana-runtime/src/config.ts +++ b/packages/grafana-runtime/src/config.ts @@ -2,32 +2,63 @@ import extend from 'lodash/extend'; import { getTheme } from '@grafana/ui'; import { DataSourceInstanceSettings, GrafanaTheme, GrafanaThemeType, PanelPluginMeta } from '@grafana/data'; +/** + * Describes the build information that will be available via the Grafana cofiguration. + * + * @public + */ export interface BuildInfo { version: string; commit: string; - isEnterprise: boolean; // deprecated: use licenseInfo.hasLicense instead + /** + * Is set to true when running Grafana Enterprise edition. + * + * @deprecated use `licenseInfo.hasLicense` instead + */ + isEnterprise: boolean; env: string; edition: string; latestVersion: string; hasUpdate: boolean; } -interface FeatureToggles { +/** + * Describes available feature toggles in Grafana. These can be configured via the + * `conf/custom.ini` to enable features under development or not yet available in + * stable version. + * + * @public + */ +export interface FeatureToggles { transformations: boolean; expressions: boolean; newEdit: boolean; - meta: boolean; // enterprise + /** + * @remarks + * Available only in Grafana Enterprise + */ + meta: boolean; newVariables: boolean; tracingIntegration: boolean; } -interface LicenseInfo { +/** + * Describes the license information about the current running instance of Grafana. + * + * @public + */ +export interface LicenseInfo { hasLicense: boolean; expiry: number; licenseUrl: string; stateInfo: string; } +/** + * Describes all the different Grafana configuration values available for an instance. + * + * @public + */ export class GrafanaBootConfig { datasources: { [str: string]: DataSourceInstanceSettings } = {}; panels: { [key: string]: PanelPluginMeta } = {}; @@ -110,4 +141,9 @@ const bootData = (window as any).grafanaBootData || { const options = bootData.settings; options.bootData = bootData; +/** + * Use this to access the {@link GrafanaBootConfig} for the current running Grafana instance. + * + * @public + */ export const config = new GrafanaBootConfig(options); diff --git a/packages/grafana-runtime/src/index.ts b/packages/grafana-runtime/src/index.ts index 347e4df40d2..2b0463417aa 100644 --- a/packages/grafana-runtime/src/index.ts +++ b/packages/grafana-runtime/src/index.ts @@ -6,6 +6,6 @@ export * from './services'; export * from './config'; export * from './types'; -export { loadPluginCss, SystemJS } from './utils/plugin'; +export { loadPluginCss, SystemJS, PluginCssOptions } from './utils/plugin'; export { reportMetaAnalytics } from './utils/analytics'; -export { DataSourceWithBackend } from './utils/DataSourceWithBackend'; +export { DataSourceWithBackend, HealthCheckResult, HealthStatus } from './utils/DataSourceWithBackend'; diff --git a/packages/grafana-runtime/src/services/AngularLoader.ts b/packages/grafana-runtime/src/services/AngularLoader.ts index 9565a6d41f4..8948e9e8922 100644 --- a/packages/grafana-runtime/src/services/AngularLoader.ts +++ b/packages/grafana-runtime/src/services/AngularLoader.ts @@ -1,19 +1,87 @@ +/** + * Used to enable rendering of Angular components within a + * React component without loosing proper typings. + * + * @example + * ```typescript + * class Component extends PureComponent { + * element: HTMLElement; + * angularComponent: AngularComponent; + * + * componentDidMount() { + * const template = '' // angular template here; + * const scopeProps = { ctrl: angularController }; // angular scope properties here + * const loader = getAngularLoader(); + * this.angularComponent = loader.load(this.element, scopeProps, template); + * } + * + * componentWillUnmount() { + * if (this.angularComponent) { + * this.angularComponent.destroy(); + * } + * } + * + * render() { + * return ( + *
(this.element = element)} /> + * ); + * } + * } + * ``` + * + * @public + */ export interface AngularComponent { + /** + * Should be called when the React component will unmount. + */ destroy(): void; + /** + * Can be used to trigger a re-render of the Angular component. + */ digest(): void; + /** + * Used to access the Angular scope from the React component. + */ getScope(): any; } +/** + * Used to load an Angular component from the context of a React component. + * Please see the {@link AngularComponent} for a proper example. + * + * @public + */ export interface AngularLoader { + /** + * + * @param elem - the element that the Angular component will be loaded into. + * @param scopeProps - values that will be accessed via the Angular scope. + * @param template - template used by the Angular component. + */ load(elem: any, scopeProps: any, template: string): AngularComponent; } let instance: AngularLoader; +/** + * Used during startup by Grafana to set the AngularLoader so it is available + * via the the {@link getAngularLoader} to the rest of the application. + * + * @internal + */ export function setAngularLoader(v: AngularLoader) { instance = v; } +/** + * Used to retrieve the {@link AngularLoader} that enables the use of Angular + * components within a React component. + * + * Please see the {@link AngularComponent} for a proper example. + * + * @public + */ export function getAngularLoader(): AngularLoader { return instance; } diff --git a/packages/grafana-runtime/src/services/EchoSrv.ts b/packages/grafana-runtime/src/services/EchoSrv.ts index 2fcf729b781..23e127e7e18 100644 --- a/packages/grafana-runtime/src/services/EchoSrv.ts +++ b/packages/grafana-runtime/src/services/EchoSrv.ts @@ -1,8 +1,18 @@ -interface SizeMeta { +/** + * Describes a size with width/height + * + * @public + */ +export interface SizeMeta { width: number; height: number; } +/** + * Describes the meta information that are sent together with each event. + * + * @public + */ export interface EchoMeta { screenSize: SizeMeta; windowSize: SizeMeta; @@ -12,8 +22,17 @@ export interface EchoMeta { * A unique browser session */ sessionId: string; + /** + * The current users username used to login into Grafana e.g. email. + */ userLogin: string; + /** + * The current users uniqe identifier. + */ userId: number; + /** + * True when user is logged in into Grafana. + */ userSignedIn: boolean; /** * A millisecond epoch @@ -25,6 +44,11 @@ export interface EchoMeta { timeSinceNavigationStart: number; } +/** + * Describes echo backends that can be registered to receive of events. + * + * @public + */ export interface EchoBackend { options: O; supportedEvents: EchoEventType[]; @@ -32,33 +56,84 @@ export interface EchoBackend { addEvent: (event: T) => void; } +/** + * Describes an echo event. + * + * @public + */ export interface EchoEvent { type: EchoEventType; + /** + * Event payload containing event specific data. + */ payload: P; meta: EchoMeta; } +/** + * Supported echo event types that can be sent via the {@link EchoSrv}. + * + * @public + */ export enum EchoEventType { Performance = 'performance', MetaAnalytics = 'meta-analytics', } +/** + * Used to send events to all the registered backends. This should be accessed via the + * {@link getEchoSrv} function. Will, by default, flush events to the backends every + * 10s or when the flush function is triggered. + * + * @public + */ export interface EchoSrv { + /** + * Call this to flush current events to the echo backends. + */ flush(): void; + /** + * Add a new echo backend to the list of backends that will receive events. + */ addBackend(backend: EchoBackend): void; + /** + * Call this to add event that will be sent to the echo backends upon next + * flush. + * + * @param event - Object containing event information. + * @param meta - Object that will extend/override the default meta object. + */ addEvent(event: Omit, meta?: {}): void; } let singletonInstance: EchoSrv; +/** + * Used during startup by Grafana to set the EchoSrv so it is available + * via the the {@link getEchoSrv} to the rest of the application. + * + * @internal + */ export function setEchoSrv(instance: EchoSrv) { singletonInstance = instance; } +/** + * Used to retrieve the {@link EchoSrv} that can be used to report events to registered + * echo backends. + * + * @public + */ export function getEchoSrv(): EchoSrv { return singletonInstance; } +/** + * Used to register echo backends that will receive Grafana echo events during application + * runtime. + * + * @public + */ export const registerEchoBackend = (backend: EchoBackend) => { getEchoSrv().addBackend(backend); }; diff --git a/packages/grafana-runtime/src/services/LocationSrv.ts b/packages/grafana-runtime/src/services/LocationSrv.ts index 0f041feef0a..12dec43eaac 100644 --- a/packages/grafana-runtime/src/services/LocationSrv.ts +++ b/packages/grafana-runtime/src/services/LocationSrv.ts @@ -1,36 +1,84 @@ +/** + * Passed as options to the {@link LocationSrv} to describe how the automatically navigation + * should be performed. + * + * @public + */ export interface LocationUpdate { + /** + * Target path where you automatically wants to navigate the user. + */ path?: string; + + /** + * Specify this value if you want to add values to the query string of the URL. + */ query?: UrlQueryMap; /** - * Add the query argument to the existing URL + * If set to true, the query argument will be added to the existing URL. */ partial?: boolean; /** - * Do not change this unless you are the angular router + * Used internally to sync the Redux state from Angular to make sure that the Redux location + * state is in sync when navigating using the Angular router. + * + * @remarks + * Do not change this unless you are the Angular router. + * + * @internal */ routeParams?: UrlQueryMap; /* - * If true this will replace url state (ie cause no new browser history) + * If set to true, this will replace URL state (ie. cause no new browser history). */ replace?: boolean; } +/** + * Type to represent the value of a single query variable. + * + * @public + */ export type UrlQueryValue = string | number | boolean | string[] | number[] | boolean[] | undefined | null; + +/** + * Type to represent the values parsed from the query string. + * + * @public + */ export type UrlQueryMap = Record; +/** + * If you need to automatically navigate the user to a new place in the application this should + * be done via the LocationSrv and it will make sure to update the application state accordingly. + * + * @public + */ export interface LocationSrv { update(options: LocationUpdate): void; } let singletonInstance: LocationSrv; +/** + * Used during startup by Grafana to set the LocationSrv so it is available + * via the the {@link getLocationSrv} to the rest of the application. + * + * @internal + */ export function setLocationSrv(instance: LocationSrv) { singletonInstance = instance; } +/** + * Used to retrieve the {@link LocationSrv} that can be used to automatically navigate + * the user to a new place in Grafana. + * + * @public + */ export function getLocationSrv(): LocationSrv { return singletonInstance; } diff --git a/packages/grafana-runtime/src/services/backendSrv.ts b/packages/grafana-runtime/src/services/backendSrv.ts index 2585cdd1395..9e107709bbe 100644 --- a/packages/grafana-runtime/src/services/backendSrv.ts +++ b/packages/grafana-runtime/src/services/backendSrv.ts @@ -1,50 +1,92 @@ /** - * Currently implemented with: - * https://docs.angularjs.org/api/ng/service/$http#usage - * but that will likely change in the future + * Used to initiate a remote call via the {@link BackendSrv} + * + * @public */ export type BackendSrvRequest = { url: string; + /** + * Number of times to retry the remote call if it fails. + */ retry?: number; + + /** + * HTTP headers that should be passed along with the remote call. + * Please have a look at {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API | Fetch API} + * for supported headers. + */ headers?: any; + + /** + * HTTP verb to perform in the remote call GET, POST, PUT etc. + */ method?: string; - // Show a message with the result + /** + * If set to true an alert with the response message will be displayed + * upon successful remote call + */ showSuccessAlert?: boolean; - // A requestID is provided by the datasource as a unique identifier for a - // particular query. If the requestID exists, the promise it is keyed to - // is canceled, canceling the previous datasource request if it is still - // in-flight. + /** + * Provided by the initiator to identify a particular remote call. An example + * of this is when a datasource plugin triggers a query. If the request id already + * exist the backendSrv will try to cancel and replace the previous call with the + * new one. + */ requestId?: string; - - // Allow any other parameters [key: string]: any; }; +/** + * Used to communicate via http(s) to a remote backend such as the Grafana backend, + * a datasource etc. The BackendSrv is using the {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API | Fetch API} + * under the hood to handle all the communication. + * + * The request function can be used to perform a remote call by specifing a {@link BackendSrvRequest}. + * To make the BackendSrv a bit easier to use we have added a couple of shorthand functions that will + * use default values executing the request. + * + * @remarks + * By default Grafana will display an error message alert if the remote call fails. If you want + * to prevent this from happending you need to catch the error thrown by the BackendSrv and + * set the `isHandled = true` on the incoming error. + * + * @public + */ export interface BackendSrv { get(url: string, params?: any, requestId?: string): Promise; - delete(url: string): Promise; - post(url: string, data?: any): Promise; - patch(url: string, data?: any): Promise; - put(url: string, data?: any): Promise; - - // If there is an error, set: err.isHandled = true - // otherwise the backend will show a message for you request(options: BackendSrvRequest): Promise; - // DataSource requests add hooks into the query inspector + /** + * Special function used to communicate with datasources that will emit core + * events that the Grafana QueryInspector and QueryEditor is listening for to be able + * to display datasource query information. Can be skipped by adding `option.silent` + * when initializing the request. + */ datasourceRequest(options: BackendSrvRequest): Promise; } let singletonInstance: BackendSrv; +/** + * Used during startup by Grafana to set the BackendSrv so it is available + * via the the {@link getBackendSrv} to the rest of the application. + * + * @internal + */ export const setBackendSrv = (instance: BackendSrv) => { singletonInstance = instance; }; +/** + * Used to retrieve the {@link BackendSrv} that can be used to communicate + * via http(s) to a remote backend such as the Grafana backend, a datasource etc. + * + * @public + */ export const getBackendSrv = (): BackendSrv => singletonInstance; diff --git a/packages/grafana-runtime/src/services/dataSourceSrv.ts b/packages/grafana-runtime/src/services/dataSourceSrv.ts index f0894644c80..4e87fc56157 100644 --- a/packages/grafana-runtime/src/services/dataSourceSrv.ts +++ b/packages/grafana-runtime/src/services/dataSourceSrv.ts @@ -1,15 +1,39 @@ import { ScopedVars, DataSourceApi } from '@grafana/data'; +/** + * This is the entry point for communicating with a datasource that is added as + * a plugin (both external and internal). Via this service you will get access + * to the {@link @grafana/data#DataSourceApi | DataSourceApi} that have a rich API for + * communicating with the datasource. + * + * @public + */ export interface DataSourceSrv { + /** + * @param name - name of the datasource plugin you want to use. + * @param scopedVars - variables used to interpolate a templated passed as name. + */ get(name?: string, scopedVars?: ScopedVars): Promise; } let singletonInstance: DataSourceSrv; +/** + * Used during startup by Grafana to set the DataSourceSrv so it is available + * via the the {@link getDataSourceSrv} to the rest of the application. + * + * @internal + */ export function setDataSourceSrv(instance: DataSourceSrv) { singletonInstance = instance; } +/** + * Used to retrieve the {@link DataSourceSrv} that is the entry point for communicating with + * a datasource that is added as a plugin (both external and internal). + * + * @public + */ export function getDataSourceSrv(): DataSourceSrv { return singletonInstance; } diff --git a/packages/grafana-runtime/src/services/templateSrv.ts b/packages/grafana-runtime/src/services/templateSrv.ts index 40fb64932e9..3362b581fcc 100644 --- a/packages/grafana-runtime/src/services/templateSrv.ts +++ b/packages/grafana-runtime/src/services/templateSrv.ts @@ -1,13 +1,32 @@ import { VariableModel } from '@grafana/data'; +/** + * Via the TemplateSrv consumers get access to all the available template variables + * that can be used within the current active dashboard. + * + * For a mor in-depth description visit: https://grafana.com/docs/grafana/latest/reference/templating + * @public + */ export interface TemplateSrv { getVariables(): VariableModel[]; } let singletonInstance: TemplateSrv; +/** + * Used during startup by Grafana to set the TemplateSrv so it is available + * via the the {@link getTemplateSrv} to the rest of the application. + * + * @internal + */ export const setTemplateSrv = (instance: TemplateSrv) => { singletonInstance = instance; }; +/** + * Used to retrieve the {@link TemplateSrv} that can be used to fetch available + * template variables. + * + * @public + */ export const getTemplateSrv = (): TemplateSrv => singletonInstance; diff --git a/packages/grafana-runtime/src/types/analytics.ts b/packages/grafana-runtime/src/types/analytics.ts index 41a792d6ac5..526fb1b3acf 100644 --- a/packages/grafana-runtime/src/types/analytics.ts +++ b/packages/grafana-runtime/src/types/analytics.ts @@ -1,5 +1,11 @@ import { EchoEvent, EchoEventType } from '../services/EchoSrv'; +/** + * Describes the basic dashboard information that can be passed as the meta + * analytics payload. + * + * @public + */ export interface DashboardInfo { dashboardId: number; dashboardUid: string; @@ -7,6 +13,11 @@ export interface DashboardInfo { folderName?: string; } +/** + * Describes the data request information passed as the meta analytics payload. + * + * @public + */ export interface DataRequestInfo extends Partial { datasourceName: string; datasourceId?: number; @@ -17,19 +28,44 @@ export interface DataRequestInfo extends Partial { dataSize?: number; } +/** + * The meta analytics events that can be added to the echo service. + * + * @public + */ export enum MetaAnalyticsEventName { DashboardView = 'dashboard-view', DataRequest = 'data-request', } +/** + * Describes the payload of a dashboard view event. + * + * @public + */ export interface DashboardViewEventPayload extends DashboardInfo { eventName: MetaAnalyticsEventName.DashboardView; } +/** + * Describes the payload of a data request event. + * + * @public + */ export interface DataRequestEventPayload extends DataRequestInfo { eventName: MetaAnalyticsEventName.DataRequest; } +/** + * Describes the meta analytics payload passed with the {@link MetaAnalyticsEvent} + * + * @public + */ export type MetaAnalyticsEventPayload = DashboardViewEventPayload | DataRequestEventPayload; +/** + * Describes meta analytics event with predefined {@link EchoEventType.MetaAnalytics} type. + * + * @public + */ export interface MetaAnalyticsEvent extends EchoEvent {} diff --git a/packages/grafana-runtime/src/utils/DataSourceWithBackend.ts b/packages/grafana-runtime/src/utils/DataSourceWithBackend.ts index 7d408a0eff7..535cb20b265 100644 --- a/packages/grafana-runtime/src/utils/DataSourceWithBackend.ts +++ b/packages/grafana-runtime/src/utils/DataSourceWithBackend.ts @@ -10,21 +10,37 @@ import { Observable, from } from 'rxjs'; import { config } from '..'; import { getBackendSrv } from '../services'; -// Ideally internal (exported for consistency) const ExpressionDatasourceID = '__expr__'; +/** + * Describes the current healt status of a data source plugin. + * + * @public + */ export enum HealthStatus { Unknown = 'UNKNOWN', OK = 'OK', Error = 'ERROR', } +/** + * Describes the payload returned when checking the health of a data source + * plugin. + * + * @public + */ export interface HealthCheckResult { status: HealthStatus; message: string; details?: Record; } +/** + * Extend this class to implement a data source plugin that is depending on the Grafana + * backend API. + * + * @public + */ export class DataSourceWithBackend< TQuery extends DataQuery = DataQuery, TOptions extends DataSourceJsonData = DataSourceJsonData @@ -86,6 +102,8 @@ export class DataSourceWithBackend< /** * Override to apply template variables + * + * @virtual */ applyTemplateVariables(query: DataQuery) { return query; diff --git a/packages/grafana-runtime/src/utils/analytics.ts b/packages/grafana-runtime/src/utils/analytics.ts index 72da85390de..b3f090b3314 100644 --- a/packages/grafana-runtime/src/utils/analytics.ts +++ b/packages/grafana-runtime/src/utils/analytics.ts @@ -1,6 +1,11 @@ import { getEchoSrv, EchoEventType } from '../services/EchoSrv'; import { MetaAnalyticsEvent, MetaAnalyticsEventPayload } from '../types/analytics'; +/** + * Helper function to report meta analytics to the {@link EchoSrv}. + * + * @public + */ export const reportMetaAnalytics = (payload: MetaAnalyticsEventPayload) => { getEchoSrv().addEvent({ type: EchoEventType.MetaAnalytics, diff --git a/packages/grafana-runtime/src/utils/plugin.ts b/packages/grafana-runtime/src/utils/plugin.ts index 1e12cb75850..5791dd00519 100644 --- a/packages/grafana-runtime/src/utils/plugin.ts +++ b/packages/grafana-runtime/src/utils/plugin.ts @@ -3,13 +3,29 @@ import { config } from '../config'; // @ts-ignore import System from 'systemjs/dist/system.js'; +/** + * Option to specify a plugin css that should be applied for the dark + * and the light theme. + * + * @public + */ export interface PluginCssOptions { light: string; dark: string; } +/** + * @internal + */ export const SystemJS = System; +/** + * Use this to load css for a Grafana plugin by specifying a {@link PluginCssOptions} + * containing styling for the dark and the light theme. + * + * @param options - plugin styling for light and dark theme. + * @public + */ export function loadPluginCss(options: PluginCssOptions): Promise { const theme = config.bootData.user.lightTheme ? options.light : options.dark; return SystemJS.import(`${theme}!css`);