From 5d8a6ccc35acc8941f692d16c7000756e85874f5 Mon Sep 17 00:00:00 2001 From: Maxime Le Conte des Floris Date: Fri, 18 Mar 2022 18:56:11 +0100 Subject: [PATCH] init fork --- README.md | 10 +- src/components/ConfigEditor.tsx | 31 +----- src/components/TabbedQueryEditor.tsx | 154 +-------------------------- src/datasource.ts | 79 +++++--------- src/plugin.json | 26 +---- src/types.ts | 2 +- 6 files changed, 42 insertions(+), 260 deletions(-) diff --git a/README.md b/README.md index 5eeae79..9f8fc5f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# JSON API data source for Grafana +# JSON local data source for Grafana [![Build](https://github.com/marcusolsson/grafana-json-datasource/workflows/CI/badge.svg)](https://github.com/marcusolsson/grafana-json-datasource/actions?query=workflow%3A%22CI%22) [![Release](https://github.com/marcusolsson/grafana-json-datasource/workflows/Release/badge.svg)](https://github.com/marcusolsson/grafana-json-datasource/actions?query=workflow%3ARelease) @@ -7,16 +7,10 @@ [![License](https://img.shields.io/github/license/marcusolsson/grafana-json-datasource)](LICENSE) [![Twitter](https://img.shields.io/twitter/follow/marcusolsson?color=%231DA1F2&label=twitter&style=plastic)](https://twitter.com/marcusolsson) -A data source plugin for loading JSON APIs into [Grafana](https://grafana.com) using [JSONPath](https://goessner.net/articles/JsonPath/). +A data source plugin for loading local JSON into [Grafana](https://grafana.com) using [JSONPath](https://goessner.net/articles/JsonPath/). ![Screenshot](https://github.com/marcusolsson/grafana-json-datasource/raw/main/src/img/dark.png) ## Documentation Full documentation for the plugin is available on the [website](https://marcusolsson.github.io/grafana-json-datasource). - -## Maintenance - -I maintain [several plugins](https://marcus.se.net/projects/) for Grafana. While my employer allows me to spend some time on developing plugins, most of the work happens on evenings and weekends. At the moment, I'm prioritizing fixing bugs and reviewing PRs over introducing new features. - -If you'd still like to propose a new feature, [create a new Discussion](https://github.com/marcusolsson/grafana-json-datasource/discussions/new?category=ideas). While I likely won't be able to work on features myself, I'd be happy to accept pull requests. If you'd like to contribute a feature, please let me know before you start working on it. diff --git a/src/components/ConfigEditor.tsx b/src/components/ConfigEditor.tsx index 3d70be3..71d7ef6 100644 --- a/src/components/ConfigEditor.tsx +++ b/src/components/ConfigEditor.tsx @@ -1,6 +1,6 @@ import {} from '@emotion/core'; import { DataSourcePluginOptionsEditorProps } from '@grafana/data'; -import { DataSourceHttpSettings, InlineField, InlineFieldRow, Input } from '@grafana/ui'; +import { TextArea } from '@grafana/ui'; import React, { ChangeEvent } from 'react'; import { JsonApiDataSourceOptions } from '../types'; @@ -11,41 +11,20 @@ type Props = DataSourcePluginOptionsEditorProps; * authentication. */ export const ConfigEditor: React.FC = ({ options, onOptionsChange }) => { - const onParamsChange = (e: ChangeEvent) => { + const onParamsChange = (e: ChangeEvent) => { onOptionsChange({ ...options, jsonData: { ...options.jsonData, - queryParams: e.currentTarget.value, + data: e.currentTarget.value, }, }); }; return ( <> - {/* DataSourceHttpSettings handles most the settings for connecting over - HTTP. */} - - - {/* The Grafana proxy strips query parameters from the URL set in - DataSourceHttpSettings. To support custom query parameters, the user need - to set them explicitly. */} -

Misc

- - - - - +

RAW Json

+ ); }; diff --git a/src/components/TabbedQueryEditor.tsx b/src/components/TabbedQueryEditor.tsx index d80e429..4507de0 100644 --- a/src/components/TabbedQueryEditor.tsx +++ b/src/components/TabbedQueryEditor.tsx @@ -1,16 +1,8 @@ import { TimeRange } from '@grafana/data'; -import { CodeEditor, InfoBox, InlineField, InlineFieldRow, RadioButtonGroup, Segment, useTheme } from '@grafana/ui'; +import { InlineField, InlineFieldRow, RadioButtonGroup } from '@grafana/ui'; import { JsonDataSource } from 'datasource'; -import { css } from 'emotion'; -import defaults from 'lodash/defaults'; import React, { useState } from 'react'; -import AutoSizer from 'react-virtualized-auto-sizer'; -import { defaultQuery, JsonApiQuery, Pair } from '../types'; -import { KeyValueEditor } from './KeyValueEditor'; -import { PathEditor } from './PathEditor'; - -// Display a warning message when user adds any of the following headers. -const sensitiveHeaders = ['authorization', 'proxy-authorization', 'x-api-key']; +import { JsonApiQuery } from '../types'; interface Props { onChange: (query: JsonApiQuery) => void; @@ -25,118 +17,14 @@ interface Props { experimentalTab: React.ReactNode; } -export const TabbedQueryEditor = ({ query, onChange, onRunQuery, fieldsTab, experimentalTab }: Props) => { - const [bodyType, setBodyType] = useState('plaintext'); +export const TabbedQueryEditor = ({ fieldsTab }: Props) => { const [tabIndex, setTabIndex] = useState(0); - const theme = useTheme(); - - const q = defaults(query, defaultQuery); - - const onBodyChange = (body: string) => { - onChange({ ...q, body }); - onRunQuery(); - }; - - const onParamsChange = (params: Array>) => { - onChange({ ...q, params }); - onRunQuery(); - }; - - const onHeadersChange = (headers: Array>) => { - onChange({ ...q, headers }); - onRunQuery(); - }; const tabs = [ { title: 'Fields', content: fieldsTab, }, - { - title: 'Path', - content: ( - { - onChange({ ...q, method }); - onRunQuery(); - }} - path={q.urlPath ?? ''} - onPathChange={(path) => { - onChange({ ...q, urlPath: path }); - onRunQuery(); - }} - /> - ), - }, - { - title: 'Params', - content: ( - onRunQuery()} - /> - ), - }, - { - title: 'Headers', - content: ( - onRunQuery()} - /> - ), - }, - { - title: 'Body', - content: ( - <> - - - setBodyType(v ?? 'plaintext')} - options={[ - { label: 'Text', value: 'plaintext' }, - { label: 'JSON', value: 'json' }, - { label: 'XML', value: 'xml' }, - ]} - /> - - - - - {({ width }) => ( - - )} - - - - ), - }, - { - title: 'Experimental', - content: experimentalTab, - }, ]; return ( @@ -149,44 +37,8 @@ export const TabbedQueryEditor = ({ query, onChange, onRunQuery, fieldsTab, expe options={tabs.map((tab, idx) => ({ label: tab.title, value: idx }))} /> - - ({ - label: formatCacheTimeLabel(value), - value, - description: value ? '' : 'Response is not cached at all', - }))} - onChange={({ value }) => onChange({ ...q, cacheDurationSeconds: value! })} - /> - - {q.method === 'GET' && q.body && ( - - {"GET requests can't have a body. The body you've defined will be ignored."} - - )} - {(q.headers ?? []).map(([key, _]) => key.toLowerCase()).find((_) => sensitiveHeaders.includes(_)) && ( - - { - "It looks like you're adding credentials in the header. Since queries are stored unencrypted, it's strongly recommended that you add any secrets to the data source config instead." - } - - )} {tabs[tabIndex].content} ); }; - -export const formatCacheTimeLabel = (s: number) => { - if (s < 60) { - return s + 's'; - } else if (s < 3600) { - return s / 60 + 'm'; - } - - return s / 3600 + 'h'; -}; diff --git a/src/datasource.ts b/src/datasource.ts index 8dde470..1f607a3 100644 --- a/src/datasource.ts +++ b/src/datasource.ts @@ -15,18 +15,25 @@ import { getTemplateSrv } from '@grafana/runtime'; import jsonata from 'jsonata'; import { JSONPath } from 'jsonpath-plus'; import _ from 'lodash'; -import API from './api'; + import { detectFieldType } from './detectFieldType'; import { parseValues } from './parseValues'; -import { JsonApiDataSourceOptions, JsonApiQuery, Pair } from './types'; +import { JsonApiDataSourceOptions, JsonApiQuery } from './types'; export class JsonDataSource extends DataSourceApi { - api: API; + data: Object; + isValid: boolean; constructor(instanceSettings: DataSourceInstanceSettings) { super(instanceSettings); - this.api = new API(instanceSettings.url!, instanceSettings.jsonData.queryParams || ''); + try { + this.data = JSON.parse(instanceSettings.jsonData.data || '{}'); + this.isValid = true; + } catch (err: any) { + this.isValid = false; + this.data = err; + } } /** @@ -37,7 +44,7 @@ export class JsonDataSource extends DataSourceApi): Promise { @@ -83,47 +90,24 @@ export class JsonDataSource extends DataSourceApi { const replaceWithVars = replace(scopedVars, range); - const json = await this.requestJson(query, replaceWithVars); + // const json = await this.requestJson(query, replaceWithVars); + const json = Object.assign({}, this.data); if (!json) { throw new Error('Query returned empty data'); @@ -228,19 +212,8 @@ export class JsonDataSource extends DataSourceApi string) { - const interpolateKeyValue = ([key, value]: Pair): Pair => { - return [interpolate(key), interpolate(value)]; - }; - - return await this.api.cachedGet( - query.cacheDurationSeconds, - query.method, - interpolate(query.urlPath), - (query.params ?? []).map(interpolateKeyValue), - (query.headers ?? []).map(interpolateKeyValue), - interpolate(query.body) - ); + requestJson() { + return Promise.resolve(this.data); } } diff --git a/src/plugin.json b/src/plugin.json index 89a2d87..2875d41 100644 --- a/src/plugin.json +++ b/src/plugin.json @@ -1,37 +1,21 @@ { "$schema": "https://github.com/grafana/grafana/raw/main/docs/sources/developers/plugins/plugin.schema.json", "type": "datasource", - "name": "JSON API", - "id": "marcusolsson-json-datasource", + "name": "JSON Local", + "id": "cds-json-datasource", "metrics": true, "logs": true, "annotations": true, "info": { - "description": "A data source plugin for loading JSON APIs into Grafana.", + "description": "A data source plugin for loading local JSON into Grafana.", "author": { - "name": "Marcus Olsson", - "email": "marcus.olsson@hey.com", - "url": "https://marcus.se.net" + "name": "Cdiscount" }, - "keywords": ["json", "api"], + "keywords": ["json", "local"], "logos": { "small": "img/logo.svg", "large": "img/logo.svg" }, - "links": [ - { - "name": "Documentation", - "url": "https://marcusolsson.github.io/grafana-json-datasource" - }, - { - "name": "Website", - "url": "https://github.com/marcusolsson/grafana-json-datasource" - }, - { - "name": "License", - "url": "https://github.com/marcusolsson/grafana-json-datasource/blob/main/LICENSE" - } - ], "screenshots": [ { "name": "Explore (Dark)", "path": "img/dark.png" }, { "name": "Explore (Light)", "path": "img/light.png" } diff --git a/src/types.ts b/src/types.ts index 526ecfc..081dac6 100644 --- a/src/types.ts +++ b/src/types.ts @@ -40,5 +40,5 @@ export const defaultQuery: Partial = { }; export interface JsonApiDataSourceOptions extends DataSourceJsonData { - queryParams?: string; + data: string; }