mirror of
https://github.com/prometheus/prometheus.git
synced 2025-01-11 05:47:27 -08:00
UI: stabilize dependencies and environment (#10517)
* create lezer-promql module + move codemirror to a pure esm module + unified dependencies Signed-off-by: Augustin Husson <husson.augustin@gmail.com> * ignore test utils file and remove the type "module" in package.json Signed-off-by: Augustin Husson <husson.augustin@gmail.com> * use jest to run the lezer-promql test Signed-off-by: Augustin Husson <husson.augustin@gmail.com> * give an automatic way to update the ui dependencies Signed-off-by: Augustin Husson <husson.augustin@gmail.com> * update all dependencies using make update-npm-deps Signed-off-by: Augustin Husson <husson.augustin@gmail.com> * fix react-app test Signed-off-by: Augustin Husson <husson.augustin@gmail.com> * remove generated file Signed-off-by: Augustin Husson <husson.augustin@gmail.com> * remove unnecessary backslash in script Signed-off-by: Augustin Husson <husson.augustin@gmail.com> * fix reviews Signed-off-by: Augustin Husson <husson.augustin@gmail.com> * rewording Signed-off-by: Augustin Husson <husson.augustin@gmail.com> * use npx to run lezer-generator Signed-off-by: Augustin Husson <husson.augustin@gmail.com>
This commit is contained in:
parent
063319087c
commit
043a2954f8
12
Makefile
12
Makefile
|
@ -29,6 +29,16 @@ include Makefile.common
|
||||||
|
|
||||||
DOCKER_IMAGE_NAME ?= prometheus
|
DOCKER_IMAGE_NAME ?= prometheus
|
||||||
|
|
||||||
|
.PHONY: update-npm-deps
|
||||||
|
update-npm-deps:
|
||||||
|
@echo ">> updating npm dependencies"
|
||||||
|
./scripts/npm-deps.sh "minor"
|
||||||
|
|
||||||
|
.PHONY: upgrade-npm-deps
|
||||||
|
upgrade-npm-deps:
|
||||||
|
@echo ">> upgrading npm dependencies"
|
||||||
|
./scripts/npm-deps.sh "latest"
|
||||||
|
|
||||||
.PHONY: ui-install
|
.PHONY: ui-install
|
||||||
ui-install:
|
ui-install:
|
||||||
cd $(UI_PATH) && npm install
|
cd $(UI_PATH) && npm install
|
||||||
|
@ -43,7 +53,7 @@ ui-build-module:
|
||||||
|
|
||||||
.PHONY: ui-test
|
.PHONY: ui-test
|
||||||
ui-test:
|
ui-test:
|
||||||
cd $(UI_PATH) && CI=true npm run test:coverage
|
cd $(UI_PATH) && CI=true npm run test
|
||||||
|
|
||||||
.PHONY: ui-lint
|
.PHONY: ui-lint
|
||||||
ui-lint:
|
ui-lint:
|
||||||
|
|
15
RELEASE.md
15
RELEASE.md
|
@ -104,12 +104,19 @@ git commit -m "Update dependencies"
|
||||||
#### Updating React dependencies
|
#### Updating React dependencies
|
||||||
|
|
||||||
The React application recently moved to a monorepo system with multiple internal npm packages. Dependency upgrades are
|
The React application recently moved to a monorepo system with multiple internal npm packages. Dependency upgrades are
|
||||||
quite sensitive for the time being and should be done manually with caution.
|
quite sensitive for the time being.
|
||||||
|
|
||||||
When you want to update a dependency, you have to go to every internal npm package where the dependency is used and
|
In case you want to update the UI dependencies, you can run the following command:
|
||||||
manually change the version. Once you have taken care of that, you need to go back to `web/ui` and run `npm install`
|
|
||||||
|
|
||||||
**NOTE**: We are researching ways to automate and improve this.
|
```bash
|
||||||
|
make update-npm-deps
|
||||||
|
```
|
||||||
|
|
||||||
|
Once this step completes, please verify that no additional `node_modules` directory was created in any of the module subdirectories
|
||||||
|
(which could indicate conflicting dependency versions across modules). Then run `make ui-build` to verify that the build is still working.
|
||||||
|
|
||||||
|
Note: Once in a while, the npm dependencies should also be updated to their latest release versions (major or minor) with `make upgrade-npm-deps`,
|
||||||
|
though this may be done at convenient times (e.g. by the UI maintainers) that are out-of-sync with Prometheus releases.
|
||||||
|
|
||||||
### 1. Prepare your release
|
### 1. Prepare your release
|
||||||
|
|
||||||
|
|
16
scripts/npm-deps.sh
Executable file
16
scripts/npm-deps.sh
Executable file
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
function ncu() {
|
||||||
|
target=$1
|
||||||
|
npx npm-check-updates -u --target "${target}"
|
||||||
|
}
|
||||||
|
|
||||||
|
cd web/ui
|
||||||
|
for workspace in $(npm ls --production --depth 1 -json | jq -r '.dependencies[].resolved[8:]'); do
|
||||||
|
cd "${workspace}"
|
||||||
|
ncu "$1"
|
||||||
|
cd ../
|
||||||
|
done
|
||||||
|
|
||||||
|
ncu "$1"
|
||||||
|
npm install
|
|
@ -16,7 +16,7 @@
|
||||||
set -e
|
set -e
|
||||||
current=$(pwd)
|
current=$(pwd)
|
||||||
|
|
||||||
buildOrder=(module/codemirror-promql)
|
buildOrder=(module/lezer-promql module/codemirror-promql)
|
||||||
|
|
||||||
function buildModule() {
|
function buildModule() {
|
||||||
for module in "${buildOrder[@]}"; do
|
for module in "${buildOrder[@]}"; do
|
||||||
|
|
4
web/ui/module/codemirror-promql/.gitignore
vendored
4
web/ui/module/codemirror-promql/.gitignore
vendored
|
@ -4,8 +4,4 @@ node_modules/
|
||||||
dist/
|
dist/
|
||||||
lib/
|
lib/
|
||||||
|
|
||||||
src/grammar/**.ts
|
|
||||||
src/grammar/parser.js
|
|
||||||
src/grammar/parser.terms.js
|
|
||||||
|
|
||||||
/.nyc_output
|
/.nyc_output
|
||||||
|
|
|
@ -16,5 +16,5 @@
|
||||||
set -ex
|
set -ex
|
||||||
|
|
||||||
# build the lib (both ES2015 and CommonJS)
|
# build the lib (both ES2015 and CommonJS)
|
||||||
tsc --module ES2015 --target ES2015 --outDir dist/esm
|
tsc --module esnext --target es2018 --outDir dist/esm
|
||||||
tsc --module commonjs --target es5 --outDir dist/cjs --downlevelIteration
|
tsc --module commonjs --target es5 --outDir dist/cjs --downlevelIteration
|
||||||
|
|
18
web/ui/module/codemirror-promql/jest.config.cjs
Normal file
18
web/ui/module/codemirror-promql/jest.config.cjs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
|
||||||
|
module.exports = {
|
||||||
|
preset: 'ts-jest',
|
||||||
|
extensionsToTreatAsEsm: ['.ts'],
|
||||||
|
testEnvironment: 'node',
|
||||||
|
setupFiles: [
|
||||||
|
'./setupJest.cjs'
|
||||||
|
],
|
||||||
|
globals: {
|
||||||
|
'ts-jest': {
|
||||||
|
useESM: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
moduleNameMapper: {
|
||||||
|
'lezer-promql': '<rootDir>/../../node_modules/lezer-promql/dist/index.es.js'
|
||||||
|
},
|
||||||
|
transformIgnorePatterns: ["<rootDir>/../../node_modules/(?!lezer-promql)/"]
|
||||||
|
};
|
|
@ -2,21 +2,19 @@
|
||||||
"name": "codemirror-promql",
|
"name": "codemirror-promql",
|
||||||
"version": "0.19.0",
|
"version": "0.19.0",
|
||||||
"description": "a CodeMirror mode for the PromQL language",
|
"description": "a CodeMirror mode for the PromQL language",
|
||||||
"main": "dist/cjs/index.js",
|
"types": "dist/esm/index.d.ts",
|
||||||
"module": "dist/esm/index.js",
|
"module": "dist/esm/index.js",
|
||||||
|
"main": "dist/cjs/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "npm run build:grammar && npm run build:lib",
|
"build": "npm run build:lib",
|
||||||
"build:grammar": "npx lezer-generator src/grammar/promql.grammar -o src/grammar/parser",
|
|
||||||
"build:lib": "bash ./build.sh",
|
"build:lib": "bash ./build.sh",
|
||||||
"test": "npm run build:grammar && ts-mocha -p tsconfig.json src/**/*.test.ts",
|
"test": "NODE_OPTIONS=--experimental-vm-modules jest",
|
||||||
"test:coverage": "npm run build:grammar && nyc ts-mocha -p tsconfig.json src/**/*.test.ts",
|
|
||||||
"codecov": "nyc report --reporter=text-lcov > coverage.lcov && codecov",
|
|
||||||
"lint": "eslint src/ --ext .ts",
|
"lint": "eslint src/ --ext .ts",
|
||||||
"lint:fix": "eslint --fix src/ --ext .ts"
|
"lint:fix": "eslint --fix src/ --ext .ts"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/prometheus/codemirror-promql.git"
|
"url": "git+https://github.com/prometheus/prometheus.git"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"promql",
|
"promql",
|
||||||
|
@ -27,54 +25,34 @@
|
||||||
"author": "Prometheus Authors <prometheus-developers@googlegroups.com>",
|
"author": "Prometheus Authors <prometheus-developers@googlegroups.com>",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/prometheus/codemirror-promql/issues"
|
"url": "https://github.com/prometheus/prometheus/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/prometheus/codemirror-promql/blob/main/README.md",
|
"homepage": "https://github.com/prometheus/prometheus/blob/main/web/ui/module/codemirror-promql/README.md",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"lezer-promql": "0.23.0",
|
||||||
"lru-cache": "^6.0.0"
|
"lru-cache": "^6.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@codemirror/autocomplete": "^0.19.9",
|
"@codemirror/autocomplete": "^0.19.15",
|
||||||
"@codemirror/basic-setup": "^0.19.0",
|
"@codemirror/highlight": "^0.19.8",
|
||||||
"@codemirror/highlight": "^0.19.6",
|
"@codemirror/language": "^0.19.10",
|
||||||
"@codemirror/language": "^0.19.7",
|
"@codemirror/lint": "^0.19.6",
|
||||||
"@codemirror/lint": "^0.19.3",
|
"@codemirror/state": "^0.19.9",
|
||||||
"@codemirror/state": "^0.19.6",
|
"@codemirror/view": "^0.19.48",
|
||||||
"@codemirror/view": "^0.19.27",
|
"@lezer/common": "^0.15.12",
|
||||||
"@lezer/common": "^0.15.11",
|
"@lezer/lr": "^0.15.8",
|
||||||
"@lezer/lr": "^0.15.5",
|
|
||||||
"@lezer/generator": "^0.15.2",
|
|
||||||
"@types/chai": "^4.2.22",
|
|
||||||
"@types/lru-cache": "^5.1.1",
|
"@types/lru-cache": "^5.1.1",
|
||||||
"@types/mocha": "^9.0.0",
|
|
||||||
"@types/node": "^16.11.12",
|
|
||||||
"@typescript-eslint/eslint-plugin": "^5.8.0",
|
|
||||||
"@typescript-eslint/parser": "^5.8.0",
|
|
||||||
"chai": "^4.2.0",
|
|
||||||
"codecov": "^3.8.3",
|
|
||||||
"eslint": "^8.4.1",
|
|
||||||
"eslint-config-prettier": "^8.3.0",
|
|
||||||
"eslint-plugin-flowtype": "^8.0.3",
|
|
||||||
"eslint-plugin-import": "^2.25.3",
|
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
|
||||||
"isomorphic-fetch": "^3.0.0",
|
"isomorphic-fetch": "^3.0.0",
|
||||||
"mocha": "^8.4.0",
|
"nock": "^13.2.4"
|
||||||
"nock": "^13.2.1",
|
|
||||||
"nyc": "^15.1.0",
|
|
||||||
"prettier": "^2.5.1",
|
|
||||||
"ts-loader": "^7.0.5",
|
|
||||||
"ts-mocha": "^8.0.0",
|
|
||||||
"ts-node": "^10.4.0",
|
|
||||||
"typescript": "^4.6.2"
|
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@codemirror/autocomplete": "^0.19.9",
|
"@codemirror/autocomplete": "^0.19.15",
|
||||||
"@codemirror/highlight": "^0.19.6",
|
"@codemirror/highlight": "^0.19.8",
|
||||||
"@codemirror/language": "^0.19.7",
|
"@codemirror/language": "^0.19.10",
|
||||||
"@codemirror/lint": "^0.19.3",
|
"@codemirror/lint": "^0.19.6",
|
||||||
"@codemirror/state": "^0.19.6",
|
"@codemirror/state": "^0.19.9",
|
||||||
"@codemirror/view": "^0.19.27",
|
"@codemirror/view": "^0.19.48",
|
||||||
"@lezer/common": "^0.15.11"
|
"@lezer/common": "^0.15.12"
|
||||||
},
|
},
|
||||||
"prettier": {
|
"prettier": {
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
|
|
1
web/ui/module/codemirror-promql/setupJest.cjs
Normal file
1
web/ui/module/codemirror-promql/setupJest.cjs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
global.fetch = require('isomorphic-fetch')
|
|
@ -11,9 +11,8 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import chai from 'chai';
|
|
||||||
import { analyzeCompletion, computeStartCompletePosition, ContextKind } from './hybrid';
|
import { analyzeCompletion, computeStartCompletePosition, ContextKind } from './hybrid';
|
||||||
import { createEditorState, mockedMetricsTerms, mockPrometheusServer } from '../test/utils.test';
|
import { createEditorState, mockedMetricsTerms, mockPrometheusServer } from '../test/utils-test';
|
||||||
import { Completion, CompletionContext } from '@codemirror/autocomplete';
|
import { Completion, CompletionContext } from '@codemirror/autocomplete';
|
||||||
import {
|
import {
|
||||||
aggregateOpModifierTerms,
|
aggregateOpModifierTerms,
|
||||||
|
@ -27,7 +26,7 @@ import {
|
||||||
numberTerms,
|
numberTerms,
|
||||||
snippets,
|
snippets,
|
||||||
} from './promql.terms';
|
} from './promql.terms';
|
||||||
import { EqlSingle, Neq } from '../grammar/parser.terms';
|
import { EqlSingle, Neq } from 'lezer-promql';
|
||||||
import { syntaxTree } from '@codemirror/language';
|
import { syntaxTree } from '@codemirror/language';
|
||||||
import { newCompleteStrategy } from './index';
|
import { newCompleteStrategy } from './index';
|
||||||
|
|
||||||
|
@ -530,7 +529,7 @@ describe('analyzeCompletion test', () => {
|
||||||
const state = createEditorState(value.expr);
|
const state = createEditorState(value.expr);
|
||||||
const node = syntaxTree(state).resolve(value.pos, -1);
|
const node = syntaxTree(state).resolve(value.pos, -1);
|
||||||
const result = analyzeCompletion(state, node);
|
const result = analyzeCompletion(state, node);
|
||||||
chai.expect(value.expectedContext).to.deep.equal(result);
|
expect(value.expectedContext).toEqual(result);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -717,7 +716,7 @@ describe('computeStartCompletePosition test', () => {
|
||||||
const state = createEditorState(value.expr);
|
const state = createEditorState(value.expr);
|
||||||
const node = syntaxTree(state).resolve(value.pos, -1);
|
const node = syntaxTree(state).resolve(value.pos, -1);
|
||||||
const result = computeStartCompletePosition(node, value.pos);
|
const result = computeStartCompletePosition(node, value.pos);
|
||||||
chai.expect(value.expectedStart).to.equal(result);
|
expect(value.expectedStart).toEqual(result);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1285,7 +1284,7 @@ describe('autocomplete promQL test', () => {
|
||||||
const context = new CompletionContext(state, value.pos, true);
|
const context = new CompletionContext(state, value.pos, true);
|
||||||
const completion = newCompleteStrategy(value.conf);
|
const completion = newCompleteStrategy(value.conf);
|
||||||
const result = await completion.promQL(context);
|
const result = await completion.promQL(context);
|
||||||
chai.expect(value.expectedResult).to.deep.equal(result);
|
expect(value.expectedResult).toEqual(result);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -58,7 +58,7 @@ import {
|
||||||
SubqueryExpr,
|
SubqueryExpr,
|
||||||
Unless,
|
Unless,
|
||||||
VectorSelector,
|
VectorSelector,
|
||||||
} from '../grammar/parser.terms';
|
} from 'lezer-promql';
|
||||||
import { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
|
import { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
|
||||||
import { EditorState } from '@codemirror/state';
|
import { EditorState } from '@codemirror/state';
|
||||||
import { buildLabelMatchers, containsAtLeastOneChild, containsChild, retrieveAllRecursiveNodes, walkBackward, walkThrough } from '../parser';
|
import { buildLabelMatchers, containsAtLeastOneChild, containsChild, retrieveAllRecursiveNodes, walkBackward, walkThrough } from '../parser';
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
import { parser } from '../parser';
|
|
||||||
import { fileTests } from '@lezer/generator/dist/test';
|
|
||||||
|
|
||||||
import * as fs from 'fs';
|
|
||||||
import * as path from 'path';
|
|
||||||
|
|
||||||
const caseDir = './src/grammar/test';
|
|
||||||
for (const file of fs.readdirSync(caseDir)) {
|
|
||||||
if (!/\.txt$/.test(file)) continue;
|
|
||||||
|
|
||||||
const name = /^[^\.]*/.exec(file)[0];
|
|
||||||
describe(name, () => {
|
|
||||||
for (const { name, run } of fileTests(fs.readFileSync(path.join(caseDir, file), 'utf8'), file)) it(name, () => run(parser));
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,85 +0,0 @@
|
||||||
// Copyright 2021 The Prometheus Authors
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
import {
|
|
||||||
And,
|
|
||||||
Avg,
|
|
||||||
Atan2,
|
|
||||||
Bool,
|
|
||||||
Bottomk,
|
|
||||||
By,
|
|
||||||
Count,
|
|
||||||
CountValues,
|
|
||||||
End,
|
|
||||||
Group,
|
|
||||||
GroupLeft,
|
|
||||||
GroupRight,
|
|
||||||
Ignoring,
|
|
||||||
inf,
|
|
||||||
Max,
|
|
||||||
Min,
|
|
||||||
nan,
|
|
||||||
Offset,
|
|
||||||
On,
|
|
||||||
Or,
|
|
||||||
Quantile,
|
|
||||||
Start,
|
|
||||||
Stddev,
|
|
||||||
Stdvar,
|
|
||||||
Sum,
|
|
||||||
Topk,
|
|
||||||
Unless,
|
|
||||||
Without,
|
|
||||||
} from './parser.terms.js';
|
|
||||||
|
|
||||||
const keywordTokens = {
|
|
||||||
inf: inf,
|
|
||||||
nan: nan,
|
|
||||||
bool: Bool,
|
|
||||||
ignoring: Ignoring,
|
|
||||||
on: On,
|
|
||||||
group_left: GroupLeft,
|
|
||||||
group_right: GroupRight,
|
|
||||||
offset: Offset,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const specializeIdentifier = (value, stack) => {
|
|
||||||
return keywordTokens[value.toLowerCase()] || -1;
|
|
||||||
};
|
|
||||||
|
|
||||||
const contextualKeywordTokens = {
|
|
||||||
avg: Avg,
|
|
||||||
atan2: Atan2,
|
|
||||||
bottomk: Bottomk,
|
|
||||||
count: Count,
|
|
||||||
count_values: CountValues,
|
|
||||||
group: Group,
|
|
||||||
max: Max,
|
|
||||||
min: Min,
|
|
||||||
quantile: Quantile,
|
|
||||||
stddev: Stddev,
|
|
||||||
stdvar: Stdvar,
|
|
||||||
sum: Sum,
|
|
||||||
topk: Topk,
|
|
||||||
by: By,
|
|
||||||
without: Without,
|
|
||||||
and: And,
|
|
||||||
or: Or,
|
|
||||||
unless: Unless,
|
|
||||||
start: Start,
|
|
||||||
end: End,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const extendIdentifier = (value, stack) => {
|
|
||||||
return contextualKeywordTokens[value.toLowerCase()] || -1;
|
|
||||||
};
|
|
|
@ -11,10 +11,9 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { EqlRegex, EqlSingle, Neq, NeqRegex } from '../grammar/parser.terms';
|
import { EqlRegex, EqlSingle, Neq, NeqRegex } from 'lezer-promql';
|
||||||
import { labelMatchersToString } from './matcher';
|
import { labelMatchersToString } from './matcher';
|
||||||
import { Matcher } from '../types';
|
import { Matcher } from '../types';
|
||||||
import chai from 'chai';
|
|
||||||
|
|
||||||
describe('labelMatchersToString test', () => {
|
describe('labelMatchersToString test', () => {
|
||||||
const testCases = [
|
const testCases = [
|
||||||
|
@ -131,7 +130,7 @@ describe('labelMatchersToString test', () => {
|
||||||
|
|
||||||
testCases.forEach((value) => {
|
testCases.forEach((value) => {
|
||||||
it(value.title, () => {
|
it(value.title, () => {
|
||||||
chai.expect(labelMatchersToString(value.metricName, value.matchers, value.labelName)).to.equal(value.result);
|
expect(labelMatchersToString(value.metricName, value.matchers, value.labelName)).toEqual(value.result);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { SyntaxNode } from '@lezer/common';
|
import { SyntaxNode } from '@lezer/common';
|
||||||
import { EqlRegex, EqlSingle, LabelName, MatchOp, Neq, NeqRegex, StringLiteral } from '../grammar/parser.terms';
|
import { EqlRegex, EqlSingle, LabelName, MatchOp, Neq, NeqRegex, StringLiteral } from 'lezer-promql';
|
||||||
import { EditorState } from '@codemirror/state';
|
import { EditorState } from '@codemirror/state';
|
||||||
import { Matcher } from '../types';
|
import { Matcher } from '../types';
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,9 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import chai from 'chai';
|
|
||||||
import { Parser } from './parser';
|
import { Parser } from './parser';
|
||||||
import { Diagnostic } from '@codemirror/lint';
|
import { Diagnostic } from '@codemirror/lint';
|
||||||
import { createEditorState } from '../test/utils.test';
|
import { createEditorState } from '../test/utils-test';
|
||||||
import { syntaxTree } from '@codemirror/language';
|
import { syntaxTree } from '@codemirror/language';
|
||||||
import { ValueType } from '../types';
|
import { ValueType } from '../types';
|
||||||
|
|
||||||
|
@ -752,8 +751,8 @@ describe('promql operations', () => {
|
||||||
const state = createEditorState(value.expr);
|
const state = createEditorState(value.expr);
|
||||||
const parser = new Parser(state);
|
const parser = new Parser(state);
|
||||||
it(value.expr, () => {
|
it(value.expr, () => {
|
||||||
chai.expect(parser.checkAST(syntaxTree(state).topNode.firstChild)).to.equal(value.expectedValueType);
|
expect(parser.checkAST(syntaxTree(state).topNode.firstChild)).toEqual(value.expectedValueType);
|
||||||
chai.expect(parser.getDiagnostics()).to.deep.equal(value.expectedDiag);
|
expect(parser.getDiagnostics()).toEqual(value.expectedDiag);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -47,7 +47,7 @@ import {
|
||||||
UnaryExpr,
|
UnaryExpr,
|
||||||
Unless,
|
Unless,
|
||||||
VectorSelector,
|
VectorSelector,
|
||||||
} from '../grammar/parser.terms';
|
} from 'lezer-promql';
|
||||||
import { containsAtLeastOneChild, retrieveAllRecursiveNodes, walkThrough } from './path-finder';
|
import { containsAtLeastOneChild, retrieveAllRecursiveNodes, walkThrough } from './path-finder';
|
||||||
import { getType } from './type';
|
import { getType } from './type';
|
||||||
import { buildLabelMatchers } from './matcher';
|
import { buildLabelMatchers } from './matcher';
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import chai from 'chai';
|
|
||||||
import {
|
import {
|
||||||
Add,
|
Add,
|
||||||
AggregateExpr,
|
AggregateExpr,
|
||||||
|
@ -32,8 +31,8 @@ import {
|
||||||
NumberLiteral,
|
NumberLiteral,
|
||||||
Sub,
|
Sub,
|
||||||
VectorSelector,
|
VectorSelector,
|
||||||
} from '../grammar/parser.terms';
|
} from 'lezer-promql';
|
||||||
import { createEditorState } from '../test/utils.test';
|
import { createEditorState } from '../test/utils-test';
|
||||||
import { containsAtLeastOneChild, containsChild, retrieveAllRecursiveNodes, walkBackward, walkThrough } from './path-finder';
|
import { containsAtLeastOneChild, containsChild, retrieveAllRecursiveNodes, walkBackward, walkThrough } from './path-finder';
|
||||||
import { SyntaxNode } from '@lezer/common';
|
import { SyntaxNode } from '@lezer/common';
|
||||||
import { syntaxTree } from '@codemirror/language';
|
import { syntaxTree } from '@codemirror/language';
|
||||||
|
@ -86,12 +85,12 @@ describe('walkThrough test', () => {
|
||||||
const subTree = syntaxTree(state).resolve(value.pos, -1);
|
const subTree = syntaxTree(state).resolve(value.pos, -1);
|
||||||
const node = walkThrough(subTree, ...value.path);
|
const node = walkThrough(subTree, ...value.path);
|
||||||
if (typeof value.expectedNode === 'number') {
|
if (typeof value.expectedNode === 'number') {
|
||||||
chai.expect(value.expectedNode).to.equal(node?.type.id);
|
expect(value.expectedNode).toEqual(node?.type.id);
|
||||||
} else {
|
} else {
|
||||||
chai.expect(value.expectedNode).to.equal(node?.type.name);
|
expect(value.expectedNode).toEqual(node?.type.name);
|
||||||
}
|
}
|
||||||
if (node) {
|
if (node) {
|
||||||
chai.expect(value.expectedDoc).to.equal(state.sliceDoc(node.from, node.to));
|
expect(value.expectedDoc).toEqual(state.sliceDoc(node.from, node.to));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -129,9 +128,9 @@ describe('containsAtLeastOneChild test', () => {
|
||||||
const state = createEditorState(value.expr);
|
const state = createEditorState(value.expr);
|
||||||
const subTree = syntaxTree(state).resolve(value.pos, -1);
|
const subTree = syntaxTree(state).resolve(value.pos, -1);
|
||||||
const node = walkThrough(subTree, ...value.walkThrough);
|
const node = walkThrough(subTree, ...value.walkThrough);
|
||||||
chai.expect(node).to.not.null;
|
expect(node).toBeTruthy();
|
||||||
if (node) {
|
if (node) {
|
||||||
chai.expect(value.expectedResult).to.equal(containsAtLeastOneChild(node, ...value.child));
|
expect(value.expectedResult).toEqual(containsAtLeastOneChild(node, ...value.child));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -162,9 +161,9 @@ describe('containsChild test', () => {
|
||||||
const subTree = syntaxTree(state).resolve(value.pos, -1);
|
const subTree = syntaxTree(state).resolve(value.pos, -1);
|
||||||
const node: SyntaxNode | null = walkThrough(subTree, ...value.walkThrough);
|
const node: SyntaxNode | null = walkThrough(subTree, ...value.walkThrough);
|
||||||
|
|
||||||
chai.expect(node).to.not.null;
|
expect(node).toBeTruthy();
|
||||||
if (node) {
|
if (node) {
|
||||||
chai.expect(value.expectedResult).to.equal(containsChild(node, ...value.child));
|
expect(value.expectedResult).toEqual(containsChild(node, ...value.child));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -174,9 +173,9 @@ describe('retrieveAllRecursiveNodes test', () => {
|
||||||
it('should find every occurrence', () => {
|
it('should find every occurrence', () => {
|
||||||
const state = createEditorState('rate(1,2,3)');
|
const state = createEditorState('rate(1,2,3)');
|
||||||
const tree = syntaxTree(state).topNode.firstChild;
|
const tree = syntaxTree(state).topNode.firstChild;
|
||||||
chai.expect(tree).to.not.null;
|
expect(tree).toBeTruthy();
|
||||||
if (tree) {
|
if (tree) {
|
||||||
chai.expect(3).to.equal(retrieveAllRecursiveNodes(walkThrough(tree, FunctionCall, FunctionCallBody), FunctionCallArgs, Expr).length);
|
expect(3).toEqual(retrieveAllRecursiveNodes(walkThrough(tree, FunctionCall, FunctionCallBody), FunctionCallArgs, Expr).length);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -195,7 +194,7 @@ describe('walkbackward test', () => {
|
||||||
it(value.title, () => {
|
it(value.title, () => {
|
||||||
const state = createEditorState(value.expr);
|
const state = createEditorState(value.expr);
|
||||||
const tree = syntaxTree(state).resolve(value.pos, -1);
|
const tree = syntaxTree(state).resolve(value.pos, -1);
|
||||||
chai.expect(value.expectedResult).to.equal(walkBackward(tree, value.exit)?.type.id);
|
expect(value.expectedResult).toEqual(walkBackward(tree, value.exit)?.type.id);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -26,7 +26,7 @@ import {
|
||||||
SubqueryExpr,
|
SubqueryExpr,
|
||||||
UnaryExpr,
|
UnaryExpr,
|
||||||
VectorSelector,
|
VectorSelector,
|
||||||
} from '../grammar/parser.terms';
|
} from 'lezer-promql';
|
||||||
import { walkThrough } from './path-finder';
|
import { walkThrough } from './path-finder';
|
||||||
import { getFunction, ValueType } from '../types';
|
import { getFunction, ValueType } from '../types';
|
||||||
|
|
||||||
|
|
|
@ -12,10 +12,9 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { buildVectorMatching } from './vector';
|
import { buildVectorMatching } from './vector';
|
||||||
import { createEditorState } from '../test/utils.test';
|
import { createEditorState } from '../test/utils-test';
|
||||||
import { walkThrough } from './path-finder';
|
import { walkThrough } from './path-finder';
|
||||||
import { BinaryExpr, Expr } from '../grammar/parser.terms';
|
import { BinaryExpr, Expr } from 'lezer-promql';
|
||||||
import chai from 'chai';
|
|
||||||
import { syntaxTree } from '@codemirror/language';
|
import { syntaxTree } from '@codemirror/language';
|
||||||
import { VectorMatchCardinality } from '../types';
|
import { VectorMatchCardinality } from '../types';
|
||||||
|
|
||||||
|
@ -203,10 +202,9 @@ describe('buildVectorMatching test', () => {
|
||||||
it(value.binaryExpr, () => {
|
it(value.binaryExpr, () => {
|
||||||
const state = createEditorState(value.binaryExpr);
|
const state = createEditorState(value.binaryExpr);
|
||||||
const node = walkThrough(syntaxTree(state).topNode, Expr, BinaryExpr);
|
const node = walkThrough(syntaxTree(state).topNode, Expr, BinaryExpr);
|
||||||
chai.expect(node).to.not.null;
|
expect(node).toBeTruthy();
|
||||||
chai.expect(node).to.not.undefined;
|
|
||||||
if (node) {
|
if (node) {
|
||||||
chai.expect(value.expectedVectorMatching).to.deep.equal(buildVectorMatching(state, node));
|
expect(value.expectedVectorMatching).toEqual(buildVectorMatching(state, node));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -26,7 +26,7 @@ import {
|
||||||
OnOrIgnoring,
|
OnOrIgnoring,
|
||||||
Or,
|
Or,
|
||||||
Unless,
|
Unless,
|
||||||
} from '../grammar/parser.terms';
|
} from 'lezer-promql';
|
||||||
import { VectorMatchCardinality, VectorMatching } from '../types';
|
import { VectorMatchCardinality, VectorMatching } from '../types';
|
||||||
import { containsAtLeastOneChild, retrieveAllRecursiveNodes } from './path-finder';
|
import { containsAtLeastOneChild, retrieveAllRecursiveNodes } from './path-finder';
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { parser } from './grammar/parser';
|
import { parser } from 'lezer-promql';
|
||||||
import { styleTags, tags } from '@codemirror/highlight';
|
import { styleTags, tags } from '@codemirror/highlight';
|
||||||
import { Extension } from '@codemirror/state';
|
import { Extension } from '@codemirror/state';
|
||||||
import { CompleteConfiguration, CompleteStrategy, newCompleteStrategy } from './complete';
|
import { CompleteConfiguration, CompleteStrategy, newCompleteStrategy } from './complete';
|
||||||
|
|
|
@ -11,16 +11,17 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { parser } from '../grammar/parser';
|
import { parser } from 'lezer-promql';
|
||||||
import { EditorState } from '@codemirror/state';
|
import { EditorState } from '@codemirror/state';
|
||||||
import { LRLanguage } from '@codemirror/language';
|
import { LRLanguage } from '@codemirror/language';
|
||||||
import nock from 'nock';
|
import nock from 'nock';
|
||||||
|
import path from 'path';
|
||||||
// used to inject an implementation of fetch in NodeJS
|
import { fileURLToPath } from 'url';
|
||||||
require('isomorphic-fetch');
|
|
||||||
|
|
||||||
const lightPromQLSyntax = LRLanguage.define({ parser: parser });
|
const lightPromQLSyntax = LRLanguage.define({ parser: parser });
|
||||||
|
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
export function createEditorState(expr: string): EditorState {
|
export function createEditorState(expr: string): EditorState {
|
||||||
return EditorState.create({
|
return EditorState.create({
|
||||||
doc: expr,
|
doc: expr,
|
|
@ -78,7 +78,7 @@ import {
|
||||||
Timestamp,
|
Timestamp,
|
||||||
Vector,
|
Vector,
|
||||||
Year,
|
Year,
|
||||||
} from '../grammar/parser.terms';
|
} from 'lezer-promql';
|
||||||
|
|
||||||
export enum ValueType {
|
export enum ValueType {
|
||||||
none = 'none',
|
none = 'none',
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { EqlSingle, Neq } from '../grammar/parser.terms';
|
import { EqlSingle, Neq } from 'lezer-promql';
|
||||||
|
|
||||||
export class Matcher {
|
export class Matcher {
|
||||||
type: number;
|
type: number;
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
{
|
{
|
||||||
"compileOnSave": false,
|
"compileOnSave": false,
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2015",
|
"target": "es2018",
|
||||||
"module": "commonjs",
|
"module": "esnext",
|
||||||
"lib": [
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
"es6",
|
|
||||||
"dom"
|
|
||||||
],
|
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"outDir": "dist",
|
"outDir": "dist",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
@ -21,6 +18,7 @@
|
||||||
"src/"
|
"src/"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"src/**/*.test.ts"
|
"src/**/*.test.ts",
|
||||||
|
"src/test/**"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
5
web/ui/module/lezer-promql/.gitignore
vendored
Normal file
5
web/ui/module/lezer-promql/.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
lib/
|
||||||
|
src/parser.js
|
||||||
|
src/parser.terms.js
|
25
web/ui/module/lezer-promql/build.sh
Normal file
25
web/ui/module/lezer-promql/build.sh
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Copyright 2021 The Prometheus Authors
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
npx lezer-generator src/promql.grammar -o src/parser
|
||||||
|
|
||||||
|
cat src/parser.terms.js >> src/parser.js
|
||||||
|
|
||||||
|
bash ./generate-types.sh
|
||||||
|
|
||||||
|
rollup -c
|
45
web/ui/module/lezer-promql/generate-types.sh
Normal file
45
web/ui/module/lezer-promql/generate-types.sh
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Copyright 2021 The Prometheus Authors
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
mkdir -p ./dist
|
||||||
|
indexFile='./dist/index.d.ts'
|
||||||
|
if [[ -f ${indexFile} ]]; then
|
||||||
|
rm ${indexFile}
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat <<EOF >> ${indexFile}
|
||||||
|
// Copyright 2021 The Prometheus Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// This file was generated by lezer-promql. You probably should not edit it.
|
||||||
|
import { LRParser } from '@lezer/lr'
|
||||||
|
|
||||||
|
export const parser: LRParser
|
||||||
|
$(sed -E 's/ = [0-9]+/: number/' src/parser.terms.js)
|
||||||
|
EOF
|
11
web/ui/module/lezer-promql/jest.config.cjs
Normal file
11
web/ui/module/lezer-promql/jest.config.cjs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
|
||||||
|
module.exports = {
|
||||||
|
preset: 'ts-jest',
|
||||||
|
extensionsToTreatAsEsm: ['.ts'],
|
||||||
|
testEnvironment: 'node',
|
||||||
|
globals: {
|
||||||
|
'ts-jest': {
|
||||||
|
useESM: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
39
web/ui/module/lezer-promql/package.json
Normal file
39
web/ui/module/lezer-promql/package.json
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"name": "lezer-promql",
|
||||||
|
"version": "0.23.0",
|
||||||
|
"description": "lezer-based PromQL grammar",
|
||||||
|
"main": "index.cjs",
|
||||||
|
"type": "module",
|
||||||
|
"exports": {
|
||||||
|
"import": "./dist/index.es.js",
|
||||||
|
"require": "./dist/index.cjs"
|
||||||
|
},
|
||||||
|
"module": "dist/index.es.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"author": "Prometheus Authors <prometheus-developers@googlegroups.com>",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/prometheus/prometheus.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"lezer",
|
||||||
|
"promql"
|
||||||
|
],
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/prometheus/prometheus/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/prometheus/prometheus/blob/main/web/ui/module/lezer-promql/README.md",
|
||||||
|
"scripts": {
|
||||||
|
"build": "bash ./build.sh",
|
||||||
|
"lint": "echo 'nothing to do'",
|
||||||
|
"test": "NODE_OPTIONS=--experimental-vm-modules jest"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@lezer/generator": "^0.15.4",
|
||||||
|
"@lezer/lr": "^0.15.8"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@lezer/lr": "^0.15.8"
|
||||||
|
}
|
||||||
|
}
|
16
web/ui/module/lezer-promql/rollup.config.js
Normal file
16
web/ui/module/lezer-promql/rollup.config.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import { nodeResolve } from "@rollup/plugin-node-resolve"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
input: "./src/parser.js",
|
||||||
|
output: [{
|
||||||
|
format: "cjs",
|
||||||
|
file: "./dist/index.cjs"
|
||||||
|
}, {
|
||||||
|
format: "es",
|
||||||
|
file: "./dist/index.es.js"
|
||||||
|
}],
|
||||||
|
external(id) { return !/^[.\/]/.test(id) },
|
||||||
|
plugins: [
|
||||||
|
nodeResolve()
|
||||||
|
]
|
||||||
|
}
|
85
web/ui/module/lezer-promql/src/tokens.js
Normal file
85
web/ui/module/lezer-promql/src/tokens.js
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
// Copyright 2021 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import {
|
||||||
|
And,
|
||||||
|
Avg,
|
||||||
|
Atan2,
|
||||||
|
Bool,
|
||||||
|
Bottomk,
|
||||||
|
By,
|
||||||
|
Count,
|
||||||
|
CountValues,
|
||||||
|
End,
|
||||||
|
Group,
|
||||||
|
GroupLeft,
|
||||||
|
GroupRight,
|
||||||
|
Ignoring,
|
||||||
|
inf,
|
||||||
|
Max,
|
||||||
|
Min,
|
||||||
|
nan,
|
||||||
|
Offset,
|
||||||
|
On,
|
||||||
|
Or,
|
||||||
|
Quantile,
|
||||||
|
Start,
|
||||||
|
Stddev,
|
||||||
|
Stdvar,
|
||||||
|
Sum,
|
||||||
|
Topk,
|
||||||
|
Unless,
|
||||||
|
Without,
|
||||||
|
} from './parser.terms.js';
|
||||||
|
|
||||||
|
const keywordTokens = {
|
||||||
|
inf: inf,
|
||||||
|
nan: nan,
|
||||||
|
bool: Bool,
|
||||||
|
ignoring: Ignoring,
|
||||||
|
on: On,
|
||||||
|
group_left: GroupLeft,
|
||||||
|
group_right: GroupRight,
|
||||||
|
offset: Offset,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const specializeIdentifier = (value, stack) => {
|
||||||
|
return keywordTokens[value.toLowerCase()] || -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
const contextualKeywordTokens = {
|
||||||
|
avg: Avg,
|
||||||
|
atan2: Atan2,
|
||||||
|
bottomk: Bottomk,
|
||||||
|
count: Count,
|
||||||
|
count_values: CountValues,
|
||||||
|
group: Group,
|
||||||
|
max: Max,
|
||||||
|
min: Min,
|
||||||
|
quantile: Quantile,
|
||||||
|
stddev: Stddev,
|
||||||
|
stdvar: Stdvar,
|
||||||
|
sum: Sum,
|
||||||
|
topk: Topk,
|
||||||
|
by: By,
|
||||||
|
without: Without,
|
||||||
|
and: And,
|
||||||
|
or: Or,
|
||||||
|
unless: Unless,
|
||||||
|
start: Start,
|
||||||
|
end: End,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const extendIdentifier = (value, stack) => {
|
||||||
|
return contextualKeywordTokens[value.toLowerCase()] || -1;
|
||||||
|
};
|
16
web/ui/module/lezer-promql/test/promql.test.js
Normal file
16
web/ui/module/lezer-promql/test/promql.test.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import { parser } from '../dist/index.es.js';
|
||||||
|
import { fileTests } from '@lezer/generator/dist/test';
|
||||||
|
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
|
||||||
|
let caseDir = path.dirname(fileURLToPath(import.meta.url))
|
||||||
|
for (const file of fs.readdirSync(caseDir)) {
|
||||||
|
if (!/\.txt$/.test(file)) continue;
|
||||||
|
|
||||||
|
const name = /^[^.]*/.exec(file)[0];
|
||||||
|
describe(name, () => {
|
||||||
|
for (const { name, run } of fileTests(fs.readFileSync(path.join(caseDir, file), 'utf8'), file)) it(name, () => run(parser));
|
||||||
|
});
|
||||||
|
}
|
13268
web/ui/package-lock.json
generated
13268
web/ui/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -6,7 +6,6 @@
|
||||||
"build:module": "bash build_ui.sh --build-module",
|
"build:module": "bash build_ui.sh --build-module",
|
||||||
"start": "npm run start -w react-app",
|
"start": "npm run start -w react-app",
|
||||||
"test": "npm run test --workspaces",
|
"test": "npm run test --workspaces",
|
||||||
"test:coverage": "npm run test:coverage --workspaces",
|
|
||||||
"lint": "npm run lint --workspaces"
|
"lint": "npm run lint --workspaces"
|
||||||
},
|
},
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
|
@ -15,5 +14,18 @@
|
||||||
],
|
],
|
||||||
"engines": {
|
"engines": {
|
||||||
"npm": ">=7.0.0"
|
"npm": ">=7.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/jest": "^27.4.1",
|
||||||
|
"@types/node": "^16.11.26",
|
||||||
|
"eslint-config-prettier": "^8.5.0",
|
||||||
|
"eslint-config-react-app": "^7.0.0",
|
||||||
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
|
"jest-canvas-mock": "^2.3.1",
|
||||||
|
"jest-fetch-mock": "^3.0.3",
|
||||||
|
"react-scripts": "^5.0.0",
|
||||||
|
"prettier": "^2.6.1",
|
||||||
|
"ts-jest": "^27.1.4",
|
||||||
|
"typescript": "^4.6.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,9 +69,7 @@
|
||||||
"@testing-library/react-hooks": "^7.0.1",
|
"@testing-library/react-hooks": "^7.0.1",
|
||||||
"@types/enzyme": "^3.10.10",
|
"@types/enzyme": "^3.10.10",
|
||||||
"@types/flot": "0.0.32",
|
"@types/flot": "0.0.32",
|
||||||
"@types/jest": "^27.0.3",
|
|
||||||
"@types/jquery": "^3.5.9",
|
"@types/jquery": "^3.5.9",
|
||||||
"@types/node": "^16.11.12",
|
|
||||||
"@types/react": "^17.0.39",
|
"@types/react": "^17.0.39",
|
||||||
"@types/react-copy-to-clipboard": "^5.0.2",
|
"@types/react-copy-to-clipboard": "^5.0.2",
|
||||||
"@types/react-dom": "^17.0.11",
|
"@types/react-dom": "^17.0.11",
|
||||||
|
@ -82,16 +80,8 @@
|
||||||
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.6",
|
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.6",
|
||||||
"enzyme": "^3.11.0",
|
"enzyme": "^3.11.0",
|
||||||
"enzyme-to-json": "^3.6.2",
|
"enzyme-to-json": "^3.6.2",
|
||||||
"eslint-config-prettier": "^8.5.0",
|
|
||||||
"eslint-config-react-app": "^7.0.0",
|
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
|
||||||
"jest-canvas-mock": "^2.3.1",
|
|
||||||
"jest-fetch-mock": "^3.0.3",
|
|
||||||
"mutationobserver-shim": "^0.3.7",
|
"mutationobserver-shim": "^0.3.7",
|
||||||
"prettier": "^2.5.1",
|
"sinon": "^12.0.1"
|
||||||
"react-scripts": "5.0.0",
|
|
||||||
"sinon": "^12.0.1",
|
|
||||||
"typescript": "^4.6.2"
|
|
||||||
},
|
},
|
||||||
"proxy": "http://localhost:9090",
|
"proxy": "http://localhost:9090",
|
||||||
"jest": {
|
"jest": {
|
||||||
|
@ -99,8 +89,12 @@
|
||||||
"enzyme-to-json/serializer"
|
"enzyme-to-json/serializer"
|
||||||
],
|
],
|
||||||
"transformIgnorePatterns": [
|
"transformIgnorePatterns": [
|
||||||
"/node_modules/(?!codemirror-promql).+(js|jsx)$"
|
"<rootDir>/../node_modules/(?!codemirror-promql)/",
|
||||||
]
|
"<rootDir>/../node_modules/(?!lezer-promql)/"
|
||||||
|
],
|
||||||
|
"moduleNameMapper": {
|
||||||
|
"lezer-promql": "<rootDir>/../node_modules/lezer-promql/dist/index.cjs"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"fsevents": "^2.3.2"
|
"fsevents": "^2.3.2"
|
||||||
|
|
Loading…
Reference in a new issue