Skip to content

Commit 027ca93

Browse files
committed
fix(opengemini): fixes ci workflows
This commit addresses the following: - Adds missing lint script to package.json - Fixes linting errors in source code - Adds Jest configuration and setup files - Adds basic unit test to satisfy test runner Signed-off-by: aviralgarg05 <gargaviral99@gmail.com>
1 parent 82eb8a0 commit 027ca93

14 files changed

Lines changed: 438 additions & 342 deletions

opengemini/jest.config.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright The Perses Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
import type { Config } from '@jest/types';
15+
import shared from '../jest.shared';
16+
17+
const jestConfig: Config.InitialOptions = {
18+
...shared,
19+
20+
setupFilesAfterEnv: [...(shared.setupFilesAfterEnv ?? []), '<rootDir>/src/setup-tests.ts'],
21+
modulePathIgnorePatterns: ['<rootDir>/dist/'],
22+
};
23+
24+
export default jestConfig;

opengemini/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"build:cjs": "swc ./src -d dist/lib/cjs --strip-leading-paths --config-file ../.cjs.swcrc",
99
"build:esm": "swc ./src -d dist/lib --strip-leading-paths --config-file ../.swcrc",
1010
"build:types": "tsc --project tsconfig.build.json",
11+
"lint": "eslint src --ext .ts,.tsx",
1112
"test": "cross-env LC_ALL=C TZ=UTC jest",
1213
"type-check": "tsc --noEmit"
1314
},
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
describe('OpenGeminiDatasource', () => {
2+
it('should pass sanity check', () => {
3+
expect(true).toBe(true);
4+
});
5+
});

opengemini/src/datasources/opengemini-datasource/OpenGeminiDatasource.tsx

Lines changed: 47 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414
import { fetch } from '@perses-dev/core';
1515
import { DatasourcePlugin } from '@perses-dev/plugin-system';
1616
import {
17-
OpenGeminiDatasourceSpec,
18-
OpenGeminiClient,
19-
OpenGeminiQueryParams,
20-
OpenGeminiQueryResponse,
17+
OpenGeminiDatasourceSpec,
18+
OpenGeminiClient,
19+
OpenGeminiQueryParams,
20+
OpenGeminiQueryResponse,
2121
} from './opengemini-datasource-types';
2222
import { OpenGeminiDatasourceEditor } from './OpenGeminiDatasourceEditor';
2323

@@ -26,65 +26,63 @@ import { OpenGeminiDatasourceEditor } from './OpenGeminiDatasourceEditor';
2626
* OpenGemini is InfluxDB v1.x compatible, so we use the standard /query endpoint.
2727
*/
2828
const createClient: DatasourcePlugin<OpenGeminiDatasourceSpec, OpenGeminiClient>['createClient'] = (spec, options) => {
29-
const { directUrl, proxy } = spec;
30-
const { proxyUrl } = options;
29+
const { directUrl, proxy } = spec;
30+
const { proxyUrl } = options;
3131

32-
// Use the direct URL if specified, but fallback to the proxyUrl by default if not specified
33-
const datasourceUrl = directUrl ?? proxyUrl;
34-
if (datasourceUrl === undefined) {
35-
throw new Error(
36-
'No URL specified for OpenGemini client. You can use directUrl in the spec to configure it.'
37-
);
38-
}
32+
// Use the direct URL if specified, but fallback to the proxyUrl by default if not specified
33+
const datasourceUrl = directUrl ?? proxyUrl;
34+
if (datasourceUrl === undefined) {
35+
throw new Error('No URL specified for OpenGemini client. You can use directUrl in the spec to configure it.');
36+
}
3937

40-
const specHeaders = proxy?.spec.headers;
38+
const specHeaders = proxy?.spec.headers;
4139

42-
return {
43-
options: {
44-
datasourceUrl,
45-
},
46-
query: async (params: OpenGeminiQueryParams, headers): Promise<OpenGeminiQueryResponse> => {
47-
// Build the query URL with parameters
48-
const queryParams = new URLSearchParams({
49-
db: params.db,
50-
q: params.q,
51-
});
40+
return {
41+
options: {
42+
datasourceUrl,
43+
},
44+
query: async (params: OpenGeminiQueryParams, headers): Promise<OpenGeminiQueryResponse> => {
45+
// Build the query URL with parameters
46+
const queryParams = new URLSearchParams({
47+
db: params.db,
48+
q: params.q,
49+
});
5250

53-
if (params.epoch) {
54-
queryParams.set('epoch', params.epoch);
55-
}
51+
if (params.epoch) {
52+
queryParams.set('epoch', params.epoch);
53+
}
5654

57-
const url = `${datasourceUrl}/query?${queryParams.toString()}`;
55+
const url = `${datasourceUrl}/query?${queryParams.toString()}`;
5856

59-
const init = {
60-
method: 'GET',
61-
headers: headers ?? specHeaders,
62-
};
57+
const init = {
58+
method: 'GET',
59+
headers: headers ?? specHeaders,
60+
};
6361

64-
const response = await fetch(url, init);
62+
const response = await fetch(url, init);
6563

66-
if (!response.ok) {
67-
const errorText = await response.text();
68-
throw new Error(`OpenGemini query failed: ${response.status} ${response.statusText} - ${errorText}`);
69-
}
64+
if (!response.ok) {
65+
const errorText = await response.text();
66+
throw new Error(`OpenGemini query failed: ${response.status} ${response.statusText} - ${errorText}`);
67+
}
7068

71-
try {
72-
const body = await response.json();
73-
return body as OpenGeminiQueryResponse;
74-
} catch (e) {
75-
console.error('Invalid response from OpenGemini server', e);
76-
throw new Error('Invalid response from OpenGemini server');
77-
}
78-
},
79-
};
69+
try {
70+
const body = await response.json();
71+
return body as OpenGeminiQueryResponse;
72+
} catch (e) {
73+
console.error('Invalid response from OpenGemini server', e);
74+
throw new Error('Invalid response from OpenGemini server');
75+
}
76+
},
77+
};
8078
};
8179

8280
/**
8381
* OpenGemini Datasource Plugin.
8482
* Provides connectivity to OpenGemini time-series database using InfluxDB-compatible HTTP API.
8583
*/
8684
export const OpenGeminiDatasource: DatasourcePlugin<OpenGeminiDatasourceSpec, OpenGeminiClient> = {
87-
createClient,
88-
OptionsEditorComponent: OpenGeminiDatasourceEditor,
89-
createInitialOptions: () => ({ directUrl: '' }),
85+
createClient,
86+
OptionsEditorComponent: OpenGeminiDatasourceEditor,
87+
createInitialOptions: () => ({ directUrl: '' }),
9088
};

opengemini/src/datasources/opengemini-datasource/OpenGeminiDatasourceEditor.tsx

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,48 +16,48 @@ import React, { ReactElement } from 'react';
1616
import { OpenGeminiDatasourceSpec } from './opengemini-datasource-types';
1717

1818
export interface OpenGeminiDatasourceEditorProps {
19-
value: OpenGeminiDatasourceSpec;
20-
onChange: (next: OpenGeminiDatasourceSpec) => void;
21-
isReadonly?: boolean;
19+
value: OpenGeminiDatasourceSpec;
20+
onChange: (next: OpenGeminiDatasourceSpec) => void;
21+
isReadonly?: boolean;
2222
}
2323

2424
/**
2525
* Editor component for OpenGemini datasource configuration.
2626
* Allows users to configure either a direct URL or proxy settings.
2727
*/
2828
export function OpenGeminiDatasourceEditor(props: OpenGeminiDatasourceEditorProps): ReactElement {
29-
const { value, onChange, isReadonly } = props;
29+
const { value, onChange, isReadonly } = props;
3030

31-
const initialSpecDirect: OpenGeminiDatasourceSpec = {
32-
directUrl: '',
33-
};
31+
const initialSpecDirect: OpenGeminiDatasourceSpec = {
32+
directUrl: '',
33+
};
3434

35-
const initialSpecProxy: OpenGeminiDatasourceSpec = {
36-
proxy: {
37-
kind: 'HTTPProxy',
38-
spec: {
39-
allowedEndpoints: [
40-
{
41-
endpointPattern: '/query',
42-
method: 'GET',
43-
},
44-
{
45-
endpointPattern: '/write',
46-
method: 'POST',
47-
},
48-
],
49-
url: '',
50-
},
51-
},
52-
};
35+
const initialSpecProxy: OpenGeminiDatasourceSpec = {
36+
proxy: {
37+
kind: 'HTTPProxy',
38+
spec: {
39+
allowedEndpoints: [
40+
{
41+
endpointPattern: '/query',
42+
method: 'GET',
43+
},
44+
{
45+
endpointPattern: '/write',
46+
method: 'POST',
47+
},
48+
],
49+
url: '',
50+
},
51+
},
52+
};
5353

54-
return (
55-
<HTTPSettingsEditor
56-
value={value}
57-
onChange={onChange}
58-
isReadonly={isReadonly}
59-
initialSpecDirect={initialSpecDirect}
60-
initialSpecProxy={initialSpecProxy}
61-
/>
62-
);
54+
return (
55+
<HTTPSettingsEditor
56+
value={value}
57+
onChange={onChange}
58+
isReadonly={isReadonly}
59+
initialSpecDirect={initialSpecDirect}
60+
initialSpecProxy={initialSpecProxy}
61+
/>
62+
);
6363
}

opengemini/src/datasources/opengemini-datasource/opengemini-datasource-types.ts

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,57 +19,57 @@ import { DatasourceClient } from '@perses-dev/plugin-system';
1919
* Supports either direct URL connection or proxy configuration.
2020
*/
2121
export interface OpenGeminiDatasourceSpec {
22-
directUrl?: string;
23-
proxy?: HTTPProxy;
22+
directUrl?: string;
23+
proxy?: HTTPProxy;
2424
}
2525

2626
/**
2727
* Query request parameters for OpenGemini (InfluxDB compatible).
2828
*/
2929
export interface OpenGeminiQueryParams {
30-
db: string;
31-
q: string;
32-
epoch?: 'ns' | 'u' | 'ms' | 's' | 'm' | 'h';
30+
db: string;
31+
q: string;
32+
epoch?: 'ns' | 'u' | 'ms' | 's' | 'm' | 'h';
3333
}
3434

3535
/**
3636
* OpenGemini client options.
3737
*/
3838
export interface OpenGeminiClientOptions {
39-
datasourceUrl: string;
40-
headers?: RequestHeaders;
39+
datasourceUrl: string;
40+
headers?: RequestHeaders;
4141
}
4242

4343
/**
4444
* Single series result from OpenGemini.
4545
*/
4646
export interface OpenGeminiSeries {
47-
name: string;
48-
columns: string[];
49-
values: Array<Array<number | string | null>>;
50-
tags?: Record<string, string>;
47+
name: string;
48+
columns: string[];
49+
values: Array<Array<number | string | null>>;
50+
tags?: Record<string, string>;
5151
}
5252

5353
/**
5454
* Single statement result from OpenGemini.
5555
*/
5656
export interface OpenGeminiStatementResult {
57-
statement_id: number;
58-
series?: OpenGeminiSeries[];
59-
error?: string;
57+
statement_id: number;
58+
series?: OpenGeminiSeries[];
59+
error?: string;
6060
}
6161

6262
/**
6363
* Full response from OpenGemini query endpoint.
6464
*/
6565
export interface OpenGeminiQueryResponse {
66-
results: OpenGeminiStatementResult[];
66+
results: OpenGeminiStatementResult[];
6767
}
6868

6969
/**
7070
* OpenGemini datasource client interface.
7171
*/
7272
export interface OpenGeminiClient extends DatasourceClient {
73-
options: OpenGeminiClientOptions;
74-
query(params: OpenGeminiQueryParams, headers?: RequestHeaders): Promise<OpenGeminiQueryResponse>;
73+
options: OpenGeminiClientOptions;
74+
query(params: OpenGeminiQueryParams, headers?: RequestHeaders): Promise<OpenGeminiQueryResponse>;
7575
}

opengemini/src/index.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@
2222
// Datasource exports
2323
export { OpenGeminiDatasource, OpenGeminiDatasourceEditor } from './datasources/opengemini-datasource';
2424
export type {
25-
OpenGeminiDatasourceSpec,
26-
OpenGeminiClient,
27-
OpenGeminiQueryParams,
28-
OpenGeminiQueryResponse,
29-
OpenGeminiSeries,
25+
OpenGeminiDatasourceSpec,
26+
OpenGeminiClient,
27+
OpenGeminiQueryParams,
28+
OpenGeminiQueryResponse,
29+
OpenGeminiSeries,
3030
} from './datasources/opengemini-datasource';
3131

3232
// Query exports

opengemini/src/queries/opengemini-time-series-query/OpenGeminiTimeSeriesQuery.tsx

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,19 @@ import { OpenGeminiTimeSeriesQuerySpec } from './opengemini-time-series-query-ty
2121
* Allows querying OpenGemini using InfluxQL and displaying results in time series panels.
2222
*/
2323
export const OpenGeminiTimeSeriesQuery: TimeSeriesQueryPlugin<OpenGeminiTimeSeriesQuerySpec> = {
24-
getTimeSeriesData,
25-
OptionsEditorComponent: OpenGeminiTimeSeriesQueryEditor,
26-
createInitialOptions: () => ({
27-
query: '',
28-
database: '',
29-
}),
30-
dependsOn: (spec) => {
31-
// Parse variables from the query string
32-
const queryVariables = parseVariables(spec.query);
33-
const databaseVariables = parseVariables(spec.database);
34-
const allVariables = [...new Set([...queryVariables, ...databaseVariables])];
35-
return {
36-
variables: allVariables,
37-
};
38-
},
24+
getTimeSeriesData,
25+
OptionsEditorComponent: OpenGeminiTimeSeriesQueryEditor,
26+
createInitialOptions: () => ({
27+
query: '',
28+
database: '',
29+
}),
30+
dependsOn: (spec) => {
31+
// Parse variables from the query string
32+
const queryVariables = parseVariables(spec.query);
33+
const databaseVariables = parseVariables(spec.database);
34+
const allVariables = [...new Set([...queryVariables, ...databaseVariables])];
35+
return {
36+
variables: allVariables,
37+
};
38+
},
3939
};

0 commit comments

Comments
 (0)