@fc-components/monaco-editor 0.1.16 → 0.1.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/monaco-editor.cjs.development.js +501 -12
- package/dist/monaco-editor.cjs.development.js.map +1 -1
- package/dist/monaco-editor.cjs.production.min.js +1 -1
- package/dist/monaco-editor.cjs.production.min.js.map +1 -1
- package/dist/monaco-editor.esm.js +501 -13
- package/dist/monaco-editor.esm.js.map +1 -1
- package/dist/promql/completion/DataProvider.d.ts +3 -2
- package/dist/promql/index.d.ts +1 -0
- package/dist/promql/types.d.ts +1 -0
- package/dist/sql/completion/getCompletionProvider.d.ts +4 -0
- package/dist/sql/index.d.ts +17 -0
- package/dist/sql/sql.d.ts +85 -0
- package/dist/sql/types.d.ts +8 -0
- package/dist/sql/validation.d.ts +2 -0
- package/package.json +1 -1
- package/src/index.tsx +2 -0
- package/src/promql/completion/DataProvider.ts +22 -1
- package/src/promql/index.tsx +5 -0
- package/src/promql/types.ts +2 -0
- package/src/sql/README.md +140 -0
- package/src/sql/completion/getCompletionProvider.ts +125 -0
- package/src/sql/index.tsx +263 -0
- package/src/sql/sql.ts +250 -0
- package/src/sql/types.ts +8 -0
- package/src/sql/validation.ts +92 -0
|
@@ -9,6 +9,7 @@ export declare class DataProvider {
|
|
|
9
9
|
private readonly errorHandler?;
|
|
10
10
|
private readonly httpMethod;
|
|
11
11
|
private readonly apiPrefix;
|
|
12
|
+
private enableRequests;
|
|
12
13
|
private readonly customRequest;
|
|
13
14
|
metrics: string[];
|
|
14
15
|
labelKeys: string[];
|
|
@@ -23,8 +24,8 @@ export declare class DataProvider {
|
|
|
23
24
|
fetchLabels: (selector: string) => Promise<string[]>;
|
|
24
25
|
fetchLabelValues: (labelName: string, selector: string) => Promise<string[]>;
|
|
25
26
|
getAllMetricNames(): string[];
|
|
26
|
-
start: () => Promise<
|
|
27
|
-
loadMetricsMetadata(): Promise<
|
|
27
|
+
start: () => Promise<PromMetricsMetadata[]>;
|
|
28
|
+
loadMetricsMetadata(): Promise<PromMetricsMetadata>;
|
|
28
29
|
metricNamesToMetrics(metricNames: string[]): Metric[];
|
|
29
30
|
private setInputInRange;
|
|
30
31
|
private enableAutocompleteSuggestionsUpdate;
|
package/dist/promql/index.d.ts
CHANGED
package/dist/promql/types.d.ts
CHANGED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import * as monaco from 'monaco-editor';
|
|
2
|
+
export declare const getSqlCompletionProvider: () => {
|
|
3
|
+
provideCompletionItems(model: monaco.editor.ITextModel, position: monaco.Position, _context: monaco.languages.CompletionContext, _token: monaco.CancellationToken): monaco.languages.ProviderResult<monaco.languages.CompletionList>;
|
|
4
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type * as monacoTypes from 'monaco-editor/esm/vs/editor/editor.api';
|
|
3
|
+
interface SqlEditorProps {
|
|
4
|
+
size?: 'small' | 'middle' | 'large';
|
|
5
|
+
theme?: 'light' | 'dark';
|
|
6
|
+
value?: string;
|
|
7
|
+
placeholder?: string;
|
|
8
|
+
enableAutocomplete?: boolean;
|
|
9
|
+
readOnly?: boolean;
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
onChange?: (value: string) => void;
|
|
12
|
+
onEnter?: (value: string) => void;
|
|
13
|
+
onBlur?: (value: string) => void;
|
|
14
|
+
editorDidMount?: (editor: monacoTypes.editor.IStandaloneCodeEditor) => void;
|
|
15
|
+
}
|
|
16
|
+
export default function SqlEditor(props: SqlEditorProps): React.JSX.Element;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export declare const languageConfiguration: {
|
|
2
|
+
wordPattern: RegExp;
|
|
3
|
+
comments: {
|
|
4
|
+
lineComment: string;
|
|
5
|
+
blockComment: [string, string];
|
|
6
|
+
};
|
|
7
|
+
brackets: any;
|
|
8
|
+
autoClosingPairs: any;
|
|
9
|
+
surroundingPairs: any;
|
|
10
|
+
folding: {
|
|
11
|
+
offSide: boolean;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
export declare const language: {
|
|
15
|
+
defaultToken: string;
|
|
16
|
+
tokenPostfix: string;
|
|
17
|
+
ignoreCase: boolean;
|
|
18
|
+
brackets: {
|
|
19
|
+
open: string;
|
|
20
|
+
close: string;
|
|
21
|
+
token: string;
|
|
22
|
+
}[];
|
|
23
|
+
keywords: string[];
|
|
24
|
+
operators: string[];
|
|
25
|
+
builtinFunctions: string[];
|
|
26
|
+
escapes: RegExp;
|
|
27
|
+
digits: RegExp;
|
|
28
|
+
octaldigits: RegExp;
|
|
29
|
+
hexdigits: RegExp;
|
|
30
|
+
regexpctl: RegExp;
|
|
31
|
+
regexpattern: RegExp;
|
|
32
|
+
tokenizer: {
|
|
33
|
+
root: ((string | RegExp)[] | {
|
|
34
|
+
include: string;
|
|
35
|
+
} | (RegExp | {
|
|
36
|
+
cases: {
|
|
37
|
+
'@builtinFunctions': string;
|
|
38
|
+
'@default': string;
|
|
39
|
+
};
|
|
40
|
+
})[] | (RegExp | {
|
|
41
|
+
cases: {
|
|
42
|
+
'@keywords': string;
|
|
43
|
+
'@default': string;
|
|
44
|
+
};
|
|
45
|
+
})[])[];
|
|
46
|
+
whitespace: (string | RegExp)[][];
|
|
47
|
+
comments: ((string | RegExp)[] | (RegExp | {
|
|
48
|
+
token: string;
|
|
49
|
+
next: string;
|
|
50
|
+
})[])[];
|
|
51
|
+
comment: ((string | RegExp)[] | (RegExp | {
|
|
52
|
+
token: string;
|
|
53
|
+
next: string;
|
|
54
|
+
})[])[];
|
|
55
|
+
'pseudo-columns': (RegExp | {
|
|
56
|
+
cases: {
|
|
57
|
+
'@keywords': string;
|
|
58
|
+
'@default': string;
|
|
59
|
+
};
|
|
60
|
+
})[][];
|
|
61
|
+
builtinVariables: (RegExp | {
|
|
62
|
+
cases: {
|
|
63
|
+
'@keywords': string;
|
|
64
|
+
'@default': string;
|
|
65
|
+
};
|
|
66
|
+
})[][];
|
|
67
|
+
numbers: (string | RegExp)[][];
|
|
68
|
+
strings: (RegExp | {
|
|
69
|
+
token: string;
|
|
70
|
+
next: string;
|
|
71
|
+
})[][];
|
|
72
|
+
string: ((string | RegExp)[] | (RegExp | {
|
|
73
|
+
token: string;
|
|
74
|
+
next: string;
|
|
75
|
+
})[])[];
|
|
76
|
+
string_double: ((string | RegExp)[] | (RegExp | {
|
|
77
|
+
token: string;
|
|
78
|
+
next: string;
|
|
79
|
+
})[])[];
|
|
80
|
+
string_backtick: ((string | RegExp)[] | (RegExp | {
|
|
81
|
+
token: string;
|
|
82
|
+
next: string;
|
|
83
|
+
})[])[];
|
|
84
|
+
};
|
|
85
|
+
};
|
package/package.json
CHANGED
package/src/index.tsx
CHANGED
|
@@ -26,6 +26,7 @@ export class DataProvider {
|
|
|
26
26
|
private readonly errorHandler?: (error: any) => void;
|
|
27
27
|
private readonly httpMethod: 'POST' | 'GET' = 'GET';
|
|
28
28
|
private readonly apiPrefix: string = '/api/v1';
|
|
29
|
+
private enableRequests: boolean = true;
|
|
29
30
|
private readonly customRequest: CustomRequest = (input: RequestInfo, init?: RequestInit): Promise<Response> => fetch(input, init);
|
|
30
31
|
metrics: string[];
|
|
31
32
|
labelKeys: string[];
|
|
@@ -56,6 +57,11 @@ export class DataProvider {
|
|
|
56
57
|
this.apiPrefix = params.apiPrefix;
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
// control whether DataProvider should actually send network requests
|
|
61
|
+
if (typeof params.enableRequests !== 'undefined') {
|
|
62
|
+
this.enableRequests = !!params.enableRequests;
|
|
63
|
+
}
|
|
64
|
+
|
|
59
65
|
this.metrics = [];
|
|
60
66
|
this.labelKeys = [];
|
|
61
67
|
}
|
|
@@ -113,6 +119,9 @@ export class DataProvider {
|
|
|
113
119
|
}
|
|
114
120
|
|
|
115
121
|
fetchSeries = async (selector: string, withLimit?: string): Promise<Record<string, string | undefined>[]> => {
|
|
122
|
+
if (!this.enableRequests) {
|
|
123
|
+
return [] as Record<string, string | undefined>[];
|
|
124
|
+
}
|
|
116
125
|
const end = new Date();
|
|
117
126
|
const start = new Date(end.getTime() - this.lookbackInterval);
|
|
118
127
|
const url = `${this.apiPrefix}/series`;
|
|
@@ -138,6 +147,9 @@ export class DataProvider {
|
|
|
138
147
|
};
|
|
139
148
|
|
|
140
149
|
fetchLabels = async (selector: string): Promise<string[]> => {
|
|
150
|
+
if (!this.enableRequests) {
|
|
151
|
+
return [] as string[];
|
|
152
|
+
}
|
|
141
153
|
const end = new Date();
|
|
142
154
|
const start = new Date(end.getTime() - this.lookbackInterval);
|
|
143
155
|
const url = `${this.apiPrefix}/labels`;
|
|
@@ -164,6 +176,9 @@ export class DataProvider {
|
|
|
164
176
|
};
|
|
165
177
|
|
|
166
178
|
fetchLabelValues = async (labelName: string, selector: string): Promise<string[]> => {
|
|
179
|
+
if (!this.enableRequests) {
|
|
180
|
+
return [] as string[];
|
|
181
|
+
}
|
|
167
182
|
const end = new Date();
|
|
168
183
|
const start = new Date(end.getTime() - this.lookbackInterval);
|
|
169
184
|
const url = `${this.apiPrefix}/label/${labelName}/values`;
|
|
@@ -198,7 +213,11 @@ export class DataProvider {
|
|
|
198
213
|
]);
|
|
199
214
|
};
|
|
200
215
|
|
|
201
|
-
async loadMetricsMetadata() {
|
|
216
|
+
async loadMetricsMetadata(): Promise<PromMetricsMetadata> {
|
|
217
|
+
if (!this.enableRequests) {
|
|
218
|
+
this.metricsMetadata = {} as PromMetricsMetadata;
|
|
219
|
+
return this.metricsMetadata;
|
|
220
|
+
}
|
|
202
221
|
const request = this.buildRequest(`${this.apiPrefix}/metadata`, new URLSearchParams({}));
|
|
203
222
|
this.metricsMetadata = await this.request<PromMetricsMetadata>(request.uri, {
|
|
204
223
|
method: this.httpMethod,
|
|
@@ -206,6 +225,8 @@ export class DataProvider {
|
|
|
206
225
|
}).catch(() => {
|
|
207
226
|
return {} as PromMetricsMetadata;
|
|
208
227
|
});
|
|
228
|
+
|
|
229
|
+
return this.metricsMetadata || ({} as PromMetricsMetadata);
|
|
209
230
|
}
|
|
210
231
|
|
|
211
232
|
metricNamesToMetrics(metricNames: string[]): Metric[] {
|
package/src/promql/index.tsx
CHANGED
|
@@ -20,6 +20,8 @@ interface PromQLEditorProps {
|
|
|
20
20
|
placeholder?: string;
|
|
21
21
|
enableAutocomplete?: boolean;
|
|
22
22
|
durationVariablesCompletion?: boolean;
|
|
23
|
+
// When false, DataProvider will not send network requests. Default: true
|
|
24
|
+
enableRequests?: boolean;
|
|
23
25
|
readOnly?: boolean;
|
|
24
26
|
disabled?: boolean;
|
|
25
27
|
interpolateString?: (query: string) => string;
|
|
@@ -92,6 +94,7 @@ export default function PromQLEditor(props: PromQLEditorProps & DataProviderPara
|
|
|
92
94
|
placeholder,
|
|
93
95
|
interpolateString,
|
|
94
96
|
enableAutocomplete = true,
|
|
97
|
+
enableRequests = true,
|
|
95
98
|
readOnly = false,
|
|
96
99
|
disabled = false,
|
|
97
100
|
onChange,
|
|
@@ -266,6 +269,7 @@ export default function PromQLEditor(props: PromQLEditorProps & DataProviderPara
|
|
|
266
269
|
httpMethod: props.httpMethod,
|
|
267
270
|
apiPrefix: props.apiPrefix,
|
|
268
271
|
httpErrorHandler: props.httpErrorHandler,
|
|
272
|
+
enableRequests: enableRequests,
|
|
269
273
|
});
|
|
270
274
|
dataProviderRef.current = dataProvider;
|
|
271
275
|
dataProvider.start();
|
|
@@ -331,6 +335,7 @@ export default function PromQLEditor(props: PromQLEditorProps & DataProviderPara
|
|
|
331
335
|
props.httpMethod,
|
|
332
336
|
props.apiPrefix,
|
|
333
337
|
placeholder,
|
|
338
|
+
enableRequests,
|
|
334
339
|
]);
|
|
335
340
|
|
|
336
341
|
return (
|
package/src/promql/types.ts
CHANGED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# SQL Editor
|
|
2
|
+
|
|
3
|
+
这是一个基于 Monaco Editor 和 `monaco-sql-languages` 的 SQL 编辑器组件。
|
|
4
|
+
|
|
5
|
+
## 功能特性
|
|
6
|
+
|
|
7
|
+
- ✨ 完整的 SQL 语法高亮
|
|
8
|
+
- 🎯 智能代码补全(关键字、函数等)
|
|
9
|
+
- ✅ SQL 语法验证(括号、引号匹配等)
|
|
10
|
+
- 🎨 支持浅色和深色主题
|
|
11
|
+
- 📏 支持不同尺寸(small, middle, large)
|
|
12
|
+
- ♿ 只读和禁用模式
|
|
13
|
+
- 🎹 快捷键支持(Ctrl+Enter 执行)
|
|
14
|
+
|
|
15
|
+
## 使用方法
|
|
16
|
+
|
|
17
|
+
### 基本用法
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import { SqlMonacoEditor } from '@fc-components/monaco-editor';
|
|
21
|
+
|
|
22
|
+
function MyComponent() {
|
|
23
|
+
const [sql, setSql] = React.useState('SELECT * FROM users;');
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div style={{ height: '400px' }}>
|
|
27
|
+
<SqlMonacoEditor value={sql} onChange={setSql} placeholder='Enter SQL query...' />
|
|
28
|
+
</div>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 完整示例
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
import React, { useState } from 'react';
|
|
37
|
+
import { SqlMonacoEditor } from '@fc-components/monaco-editor';
|
|
38
|
+
|
|
39
|
+
function SqlQueryBuilder() {
|
|
40
|
+
const [sql, setSql] = useState('');
|
|
41
|
+
const [result, setResult] = useState<any>(null);
|
|
42
|
+
|
|
43
|
+
const handleChange = (value: string) => {
|
|
44
|
+
setSql(value);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const handleExecute = (value: string) => {
|
|
48
|
+
console.log('执行 SQL:', value);
|
|
49
|
+
// 发送到后端执行
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const handleBlur = (value: string) => {
|
|
53
|
+
console.log('SQL 失焦:', value);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<div>
|
|
58
|
+
<div style={{ height: '300px', border: '1px solid #ccc', marginBottom: '20px' }}>
|
|
59
|
+
<SqlMonacoEditor
|
|
60
|
+
size='large'
|
|
61
|
+
theme='light'
|
|
62
|
+
value={sql}
|
|
63
|
+
placeholder='输入 SQL 查询...'
|
|
64
|
+
enableAutocomplete={true}
|
|
65
|
+
onChange={handleChange}
|
|
66
|
+
onEnter={handleExecute}
|
|
67
|
+
onBlur={handleBlur}
|
|
68
|
+
/>
|
|
69
|
+
</div>
|
|
70
|
+
{result && (
|
|
71
|
+
<div>
|
|
72
|
+
<h3>查询结果:</h3>
|
|
73
|
+
<pre>{JSON.stringify(result, null, 2)}</pre>
|
|
74
|
+
</div>
|
|
75
|
+
)}
|
|
76
|
+
</div>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export default SqlQueryBuilder;
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Props
|
|
84
|
+
|
|
85
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
86
|
+
| -------------------- | ------------------------------ | -------- | ---------------------- |
|
|
87
|
+
| `size` | 'small' \| 'middle' \| 'large' | 'middle' | 编辑器尺寸 |
|
|
88
|
+
| `theme` | 'light' \| 'dark' | 'light' | 主题 |
|
|
89
|
+
| `value` | string | '' | 编辑器内容 |
|
|
90
|
+
| `placeholder` | string | - | 占位符文本 |
|
|
91
|
+
| `enableAutocomplete` | boolean | true | 启用代码补全 |
|
|
92
|
+
| `readOnly` | boolean | false | 只读模式 |
|
|
93
|
+
| `disabled` | boolean | false | 禁用编辑 |
|
|
94
|
+
| `onChange` | (value: string) => void | - | 内容变化回调 |
|
|
95
|
+
| `onEnter` | (value: string) => void | - | Ctrl+Enter 时触发 |
|
|
96
|
+
| `onBlur` | (value: string) => void | - | 编辑器失焦时触发 |
|
|
97
|
+
| `editorDidMount` | (editor) => void | - | 编辑器挂载完成后的回调 |
|
|
98
|
+
|
|
99
|
+
## 快捷键
|
|
100
|
+
|
|
101
|
+
- **Ctrl+Enter** 或 **Cmd+Enter**: 触发 `onEnter` 事件(通常用于执行查询)
|
|
102
|
+
- **Ctrl+Z** 或 **Cmd+Z**: 撤销
|
|
103
|
+
- **Ctrl+Y** 或 **Cmd+Y**: 重做
|
|
104
|
+
- **Ctrl+F** 或 **Cmd+F**: 查找
|
|
105
|
+
- **Ctrl+H** 或 **Cmd+H**: 查找替换
|
|
106
|
+
- **Ctrl+L**: 选中当前行
|
|
107
|
+
|
|
108
|
+
## 支持的 SQL 关键字
|
|
109
|
+
|
|
110
|
+
包括 SELECT, FROM, WHERE, JOIN, GROUP BY, ORDER BY, INSERT, UPDATE, DELETE, CREATE, DROP 等。
|
|
111
|
+
|
|
112
|
+
## 支持的 SQL 函数
|
|
113
|
+
|
|
114
|
+
- 聚合函数: COUNT, SUM, AVG, MIN, MAX
|
|
115
|
+
- 字符串函数: UPPER, LOWER, LENGTH, SUBSTRING, TRIM, CONCAT
|
|
116
|
+
- 数值函数: ROUND, ABS
|
|
117
|
+
- 日期函数: DATE, NOW, YEAR, MONTH, DAY
|
|
118
|
+
- 其他函数: COALESCE, NULLIF, IFNULL
|
|
119
|
+
|
|
120
|
+
## 验证
|
|
121
|
+
|
|
122
|
+
编辑器会自动检测以下 SQL 语法问题:
|
|
123
|
+
|
|
124
|
+
- 未闭合的单引号、双引号和反引号
|
|
125
|
+
- 未匹配的括号
|
|
126
|
+
- 其他基本的语法问题
|
|
127
|
+
|
|
128
|
+
## 主题定制
|
|
129
|
+
|
|
130
|
+
如需自定义主题,可以添加 CSS 规则覆盖默认样式:
|
|
131
|
+
|
|
132
|
+
```css
|
|
133
|
+
.sql-light {
|
|
134
|
+
/* 浅色主题样式 */
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.sql-dark {
|
|
138
|
+
/* 深色主题样式 */
|
|
139
|
+
}
|
|
140
|
+
```
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import * as monaco from 'monaco-editor';
|
|
2
|
+
|
|
3
|
+
const SQL_KEYWORDS = [
|
|
4
|
+
'SELECT',
|
|
5
|
+
'FROM',
|
|
6
|
+
'WHERE',
|
|
7
|
+
'AND',
|
|
8
|
+
'OR',
|
|
9
|
+
'NOT',
|
|
10
|
+
'JOIN',
|
|
11
|
+
'INNER',
|
|
12
|
+
'LEFT',
|
|
13
|
+
'RIGHT',
|
|
14
|
+
'FULL',
|
|
15
|
+
'OUTER',
|
|
16
|
+
'ON',
|
|
17
|
+
'ORDER',
|
|
18
|
+
'BY',
|
|
19
|
+
'GROUP',
|
|
20
|
+
'HAVING',
|
|
21
|
+
'LIMIT',
|
|
22
|
+
'OFFSET',
|
|
23
|
+
'INSERT',
|
|
24
|
+
'INTO',
|
|
25
|
+
'VALUES',
|
|
26
|
+
'UPDATE',
|
|
27
|
+
'SET',
|
|
28
|
+
'DELETE',
|
|
29
|
+
'CREATE',
|
|
30
|
+
'TABLE',
|
|
31
|
+
'ALTER',
|
|
32
|
+
'DROP',
|
|
33
|
+
'PRIMARY',
|
|
34
|
+
'KEY',
|
|
35
|
+
'FOREIGN',
|
|
36
|
+
'CONSTRAINT',
|
|
37
|
+
'UNIQUE',
|
|
38
|
+
'INDEX',
|
|
39
|
+
'VIEW',
|
|
40
|
+
'DATABASE',
|
|
41
|
+
'SCHEMA',
|
|
42
|
+
'AS',
|
|
43
|
+
'DISTINCT',
|
|
44
|
+
'CASE',
|
|
45
|
+
'WHEN',
|
|
46
|
+
'THEN',
|
|
47
|
+
'ELSE',
|
|
48
|
+
'END',
|
|
49
|
+
'CAST',
|
|
50
|
+
'BETWEEN',
|
|
51
|
+
'IN',
|
|
52
|
+
'LIKE',
|
|
53
|
+
'IS',
|
|
54
|
+
'NULL',
|
|
55
|
+
'TRUE',
|
|
56
|
+
'FALSE',
|
|
57
|
+
'WITH',
|
|
58
|
+
'UNION',
|
|
59
|
+
'EXCEPT',
|
|
60
|
+
'INTERSECT',
|
|
61
|
+
'ASC',
|
|
62
|
+
'DESC',
|
|
63
|
+
'ALL',
|
|
64
|
+
'ANY',
|
|
65
|
+
'EXISTS',
|
|
66
|
+
'CROSS',
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
const SQL_FUNCTIONS = [
|
|
70
|
+
{ name: 'COUNT', signature: 'COUNT(expression)', description: 'Returns the number of rows' },
|
|
71
|
+
{ name: 'SUM', signature: 'SUM(expression)', description: 'Returns the sum of values' },
|
|
72
|
+
{ name: 'AVG', signature: 'AVG(expression)', description: 'Returns the average value' },
|
|
73
|
+
{ name: 'MIN', signature: 'MIN(expression)', description: 'Returns the minimum value' },
|
|
74
|
+
{ name: 'MAX', signature: 'MAX(expression)', description: 'Returns the maximum value' },
|
|
75
|
+
{ name: 'UPPER', signature: 'UPPER(string)', description: 'Converts string to uppercase' },
|
|
76
|
+
{ name: 'LOWER', signature: 'LOWER(string)', description: 'Converts string to lowercase' },
|
|
77
|
+
{ name: 'LENGTH', signature: 'LENGTH(string)', description: 'Returns the length of string' },
|
|
78
|
+
{ name: 'SUBSTRING', signature: 'SUBSTRING(string, start, length)', description: 'Extracts substring' },
|
|
79
|
+
{ name: 'TRIM', signature: 'TRIM(string)', description: 'Removes leading and trailing spaces' },
|
|
80
|
+
{ name: 'ROUND', signature: 'ROUND(number, decimals)', description: 'Rounds a number' },
|
|
81
|
+
{ name: 'ABS', signature: 'ABS(number)', description: 'Returns absolute value' },
|
|
82
|
+
{ name: 'COALESCE', signature: 'COALESCE(value1, value2, ...)', description: 'Returns first non-null value' },
|
|
83
|
+
{ name: 'NULLIF', signature: 'NULLIF(value1, value2)', description: 'Returns null if two values are equal' },
|
|
84
|
+
{ name: 'IFNULL', signature: 'IFNULL(value, default)', description: 'Returns alternative if null' },
|
|
85
|
+
{ name: 'CONCAT', signature: 'CONCAT(string1, string2, ...)', description: 'Concatenates strings' },
|
|
86
|
+
{ name: 'DATE', signature: 'DATE(date)', description: 'Extracts date part' },
|
|
87
|
+
{ name: 'NOW', signature: 'NOW()', description: 'Returns current date and time' },
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
export const getSqlCompletionProvider = () => {
|
|
91
|
+
return {
|
|
92
|
+
provideCompletionItems(
|
|
93
|
+
model: monaco.editor.ITextModel,
|
|
94
|
+
position: monaco.Position,
|
|
95
|
+
_context: monaco.languages.CompletionContext,
|
|
96
|
+
_token: monaco.CancellationToken,
|
|
97
|
+
): monaco.languages.ProviderResult<monaco.languages.CompletionList> {
|
|
98
|
+
const word = model.getWordUntilPosition(position);
|
|
99
|
+
const range = new monaco.Range(position.lineNumber, word.startColumn, position.lineNumber, word.endColumn);
|
|
100
|
+
|
|
101
|
+
const suggestions: monaco.languages.CompletionItem[] = [
|
|
102
|
+
...SQL_KEYWORDS.map((keyword) => ({
|
|
103
|
+
label: keyword,
|
|
104
|
+
kind: monaco.languages.CompletionItemKind.Keyword,
|
|
105
|
+
insertText: keyword,
|
|
106
|
+
range: range,
|
|
107
|
+
sortText: '1' + keyword,
|
|
108
|
+
})),
|
|
109
|
+
...SQL_FUNCTIONS.map((func) => ({
|
|
110
|
+
label: func.name,
|
|
111
|
+
kind: monaco.languages.CompletionItemKind.Function,
|
|
112
|
+
insertText: func.name,
|
|
113
|
+
detail: func.signature,
|
|
114
|
+
documentation: func.description,
|
|
115
|
+
range: range,
|
|
116
|
+
sortText: '2' + func.name,
|
|
117
|
+
})),
|
|
118
|
+
];
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
suggestions: suggestions,
|
|
122
|
+
};
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
};
|