fix:explore logql 支持语法高亮 以及适配换行输入
This commit is contained in:
151
nezha-fronted/package-lock.json
generated
151
nezha-fronted/package-lock.json
generated
@@ -3127,7 +3127,7 @@
|
||||
"babel-helper-builder-binary-assignment-operator-visitor": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz",
|
||||
"integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=",
|
||||
"integrity": "sha512-gCtfYORSG1fUMX4kKraymq607FWgMWg+j42IFPc18kFQEsmtaibP4UrqsXt8FlEJle25HUd4tsoDR7H2wDhe9Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-helper-explode-assignable-expression": "^6.24.1",
|
||||
@@ -3138,7 +3138,7 @@
|
||||
"babel-helper-call-delegate": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz",
|
||||
"integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=",
|
||||
"integrity": "sha512-RL8n2NiEj+kKztlrVJM9JT1cXzzAdvWFh76xh/H1I4nKwunzE4INBXn8ieCZ+wh4zWszZk7NBS1s/8HR5jDkzQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-helper-hoist-variables": "^6.24.1",
|
||||
@@ -3150,7 +3150,7 @@
|
||||
"babel-helper-define-map": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz",
|
||||
"integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=",
|
||||
"integrity": "sha512-bHkmjcC9lM1kmZcVpA5t2om2nzT/xiZpo6TJq7UlZ3wqKfzia4veeXbIhKvJXAMzhhEBd3cR1IElL5AenWEUpA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-helper-function-name": "^6.24.1",
|
||||
@@ -3162,7 +3162,7 @@
|
||||
"babel-helper-explode-assignable-expression": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz",
|
||||
"integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=",
|
||||
"integrity": "sha512-qe5csbhbvq6ccry9G7tkXbzNtcDiH4r51rrPUbwwoTzZ18AqxWYRZT6AOmxrpxKnQBW0pYlBI/8vh73Z//78nQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
@@ -3185,7 +3185,7 @@
|
||||
"babel-helper-function-name": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
|
||||
"integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=",
|
||||
"integrity": "sha512-Oo6+e2iX+o9eVvJ9Y5eKL5iryeRdsIkwRYheCuhYdVHsdEQysbc2z2QkqCLIYnNxkT5Ss3ggrHdXiDI7Dhrn4Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-helper-get-function-arity": "^6.24.1",
|
||||
@@ -3198,7 +3198,7 @@
|
||||
"babel-helper-get-function-arity": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz",
|
||||
"integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=",
|
||||
"integrity": "sha512-WfgKFX6swFB1jS2vo+DwivRN4NB8XUdM3ij0Y1gnC21y1tdBoe6xjVnd7NSI6alv+gZXCtJqvrTeMW3fR/c0ng==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
@@ -3208,7 +3208,7 @@
|
||||
"babel-helper-hoist-variables": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz",
|
||||
"integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=",
|
||||
"integrity": "sha512-zAYl3tqerLItvG5cKYw7f1SpvIxS9zi7ohyGHaI9cgDUjAT6YcY9jIEH5CstetP5wHIVSceXwNS7Z5BpJg+rOw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
@@ -3218,7 +3218,7 @@
|
||||
"babel-helper-optimise-call-expression": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz",
|
||||
"integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=",
|
||||
"integrity": "sha512-Op9IhEaxhbRT8MDXx2iNuMgciu2V8lDvYCNQbDGjdBNCjaMvyLf4wl4A3b8IgndCyQF8TwfgsQ8T3VD8aX1/pA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
@@ -3239,7 +3239,7 @@
|
||||
"babel-helper-remap-async-to-generator": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz",
|
||||
"integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=",
|
||||
"integrity": "sha512-RYqaPD0mQyQIFRu7Ho5wE2yvA/5jxqCIj/Lv4BXNq23mHYu/vxikOy2JueLiBxQknwapwrJeNCesvY0ZcfnlHg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-helper-function-name": "^6.24.1",
|
||||
@@ -3252,7 +3252,7 @@
|
||||
"babel-helper-replace-supers": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz",
|
||||
"integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=",
|
||||
"integrity": "sha512-sLI+u7sXJh6+ToqDr57Bv973kCepItDhMou0xCP2YPVmR1jkHSCY+p1no8xErbV1Siz5QE8qKT1WIwybSWlqjw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-helper-optimise-call-expression": "^6.24.1",
|
||||
@@ -3311,7 +3311,7 @@
|
||||
"babel-plugin-check-es2015-constants": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz",
|
||||
"integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=",
|
||||
"integrity": "sha512-B1M5KBP29248dViEo1owyY32lk1ZSH2DaNNrXLGt8lyjjHm7pBqAdQ7VKUPR6EEDO323+OvT3MQXbCin8ooWdA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
@@ -3370,7 +3370,7 @@
|
||||
"babel-plugin-syntax-async-functions": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
|
||||
"integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=",
|
||||
"integrity": "sha512-4Zp4unmHgw30A1eWI5EpACji2qMocisdXhAftfhXoSV9j0Tvj6nRFE3tOmRY912E0FMRm/L5xWE7MGVT2FoLnw==",
|
||||
"dev": true
|
||||
},
|
||||
"babel-plugin-syntax-async-generators": {
|
||||
@@ -3388,7 +3388,7 @@
|
||||
"babel-plugin-syntax-decorators": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz",
|
||||
"integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=",
|
||||
"integrity": "sha512-AWj19x2aDm8qFQ5O2JcD6pwJDW1YdcnO+1b81t7gxrGjz5VHiUqeYWAR4h7zueWMalRelrQDXprv2FrY1dbpbw==",
|
||||
"dev": true
|
||||
},
|
||||
"babel-plugin-syntax-dynamic-import": {
|
||||
@@ -3400,13 +3400,13 @@
|
||||
"babel-plugin-syntax-exponentiation-operator": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
|
||||
"integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=",
|
||||
"integrity": "sha512-Z/flU+T9ta0aIEKl1tGEmN/pZiI1uXmCiGFRegKacQfEJzp7iNsKloZmyJlQr+75FCJtiFfGIK03SiCvCt9cPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"babel-plugin-syntax-jsx": {
|
||||
"version": "6.18.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
|
||||
"integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=",
|
||||
"integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==",
|
||||
"dev": true
|
||||
},
|
||||
"babel-plugin-syntax-object-rest-spread": {
|
||||
@@ -3418,7 +3418,7 @@
|
||||
"babel-plugin-syntax-trailing-function-commas": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz",
|
||||
"integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=",
|
||||
"integrity": "sha512-Gx9CH3Q/3GKbhs07Bszw5fPTlU+ygrOGfAhEt7W2JICwufpC4SuO0mG0+4NykPBSYPMJhqvVlDBU17qB1D+hMQ==",
|
||||
"dev": true
|
||||
},
|
||||
"babel-plugin-transform-async-generator-functions": {
|
||||
@@ -3435,7 +3435,7 @@
|
||||
"babel-plugin-transform-async-to-generator": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz",
|
||||
"integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=",
|
||||
"integrity": "sha512-7BgYJujNCg0Ti3x0c/DL3tStvnKS6ktIYOmo9wginv/dfZOrbSZ+qG4IRRHMBOzZ5Awb1skTiAsQXg/+IWkZYw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-helper-remap-async-to-generator": "^6.24.1",
|
||||
@@ -3471,7 +3471,7 @@
|
||||
"babel-plugin-transform-es2015-arrow-functions": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
|
||||
"integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=",
|
||||
"integrity": "sha512-PCqwwzODXW7JMrzu+yZIaYbPQSKjDTAsNNlK2l5Gg9g4rz2VzLnZsStvp/3c46GfXpwkyufb3NCyG9+50FF1Vg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
@@ -3480,7 +3480,7 @@
|
||||
"babel-plugin-transform-es2015-block-scoped-functions": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz",
|
||||
"integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=",
|
||||
"integrity": "sha512-2+ujAT2UMBzYFm7tidUsYh+ZoIutxJ3pN9IYrF1/H6dCKtECfhmB8UkHVpyxDwkj0CYbQG35ykoz925TUnBc3A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
@@ -3489,7 +3489,7 @@
|
||||
"babel-plugin-transform-es2015-block-scoping": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz",
|
||||
"integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=",
|
||||
"integrity": "sha512-YiN6sFAQ5lML8JjCmr7uerS5Yc/EMbgg9G8ZNmk2E3nYX4ckHR01wrkeeMijEf5WHNK5TW0Sl0Uu3pv3EdOJWw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.26.0",
|
||||
@@ -3502,7 +3502,7 @@
|
||||
"babel-plugin-transform-es2015-classes": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz",
|
||||
"integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=",
|
||||
"integrity": "sha512-5Dy7ZbRinGrNtmWpquZKZ3EGY8sDgIVB4CU8Om8q8tnMLrD/m94cKglVcHps0BCTdZ0TJeeAWOq2TK9MIY6cag==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-helper-define-map": "^6.24.1",
|
||||
@@ -3519,7 +3519,7 @@
|
||||
"babel-plugin-transform-es2015-computed-properties": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz",
|
||||
"integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=",
|
||||
"integrity": "sha512-C/uAv4ktFP/Hmh01gMTvYvICrKze0XVX9f2PdIXuriCSvUmV9j+u+BB9f5fJK3+878yMK6dkdcq+Ymr9mrcLzw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
@@ -3529,7 +3529,7 @@
|
||||
"babel-plugin-transform-es2015-destructuring": {
|
||||
"version": "6.23.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz",
|
||||
"integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=",
|
||||
"integrity": "sha512-aNv/GDAW0j/f4Uy1OEPZn1mqD+Nfy9viFGBfQ5bZyT35YqOiqx7/tXdyfZkJ1sC21NyEsBdfDY6PYmLHF4r5iA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
@@ -3538,7 +3538,7 @@
|
||||
"babel-plugin-transform-es2015-duplicate-keys": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz",
|
||||
"integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=",
|
||||
"integrity": "sha512-ossocTuPOssfxO2h+Z3/Ea1Vo1wWx31Uqy9vIiJusOP4TbF7tPs9U0sJ9pX9OJPf4lXRGj5+6Gkl/HHKiAP5ug==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
@@ -3548,7 +3548,7 @@
|
||||
"babel-plugin-transform-es2015-for-of": {
|
||||
"version": "6.23.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz",
|
||||
"integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=",
|
||||
"integrity": "sha512-DLuRwoygCoXx+YfxHLkVx5/NpeSbVwfoTeBykpJK7JhYWlL/O8hgAK/reforUnZDlxasOrVPPJVI/guE3dCwkw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
@@ -3557,7 +3557,7 @@
|
||||
"babel-plugin-transform-es2015-function-name": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz",
|
||||
"integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=",
|
||||
"integrity": "sha512-iFp5KIcorf11iBqu/y/a7DK3MN5di3pNCzto61FqCNnUX4qeBwcV1SLqe10oXNnCaxBUImX3SckX2/o1nsrTcg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-helper-function-name": "^6.24.1",
|
||||
@@ -3568,7 +3568,7 @@
|
||||
"babel-plugin-transform-es2015-literals": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz",
|
||||
"integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=",
|
||||
"integrity": "sha512-tjFl0cwMPpDYyoqYA9li1/7mGFit39XiNX5DKC/uCNjBctMxyL1/PT/l4rSlbvBG1pOKI88STRdUsWXB3/Q9hQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
@@ -3577,7 +3577,7 @@
|
||||
"babel-plugin-transform-es2015-modules-amd": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz",
|
||||
"integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=",
|
||||
"integrity": "sha512-LnIIdGWIKdw7zwckqx+eGjcS8/cl8D74A3BpJbGjKTFFNJSMrjN4bIh22HY1AlkUbeLG6X6OZj56BDvWD+OeFA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
|
||||
@@ -3600,7 +3600,7 @@
|
||||
"babel-plugin-transform-es2015-modules-systemjs": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz",
|
||||
"integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=",
|
||||
"integrity": "sha512-ONFIPsq8y4bls5PPsAWYXH/21Hqv64TBxdje0FvU3MhIV6QM2j5YS7KvAzg/nTIVLot2D2fmFQrFWCbgHlFEjg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-helper-hoist-variables": "^6.24.1",
|
||||
@@ -3611,7 +3611,7 @@
|
||||
"babel-plugin-transform-es2015-modules-umd": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz",
|
||||
"integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=",
|
||||
"integrity": "sha512-LpVbiT9CLsuAIp3IG0tfbVo81QIhn6pE8xBJ7XSeCtFlMltuar5VuBV6y6Q45tpui9QWcy5i0vLQfCfrnF7Kiw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-plugin-transform-es2015-modules-amd": "^6.24.1",
|
||||
@@ -3622,7 +3622,7 @@
|
||||
"babel-plugin-transform-es2015-object-super": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz",
|
||||
"integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=",
|
||||
"integrity": "sha512-8G5hpZMecb53vpD3mjs64NhI1au24TAmokQ4B+TBFBjN9cVoGoOvotdrMMRmHvVZUEvqGUPWL514woru1ChZMA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-helper-replace-supers": "^6.24.1",
|
||||
@@ -3632,7 +3632,7 @@
|
||||
"babel-plugin-transform-es2015-parameters": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz",
|
||||
"integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=",
|
||||
"integrity": "sha512-8HxlW+BB5HqniD+nLkQ4xSAVq3bR/pcYW9IigY+2y0dI+Y7INFeTbfAQr+63T3E4UDsZGjyb+l9txUnABWxlOQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-helper-call-delegate": "^6.24.1",
|
||||
@@ -3646,7 +3646,7 @@
|
||||
"babel-plugin-transform-es2015-shorthand-properties": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz",
|
||||
"integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=",
|
||||
"integrity": "sha512-mDdocSfUVm1/7Jw/FIRNw9vPrBQNePy6wZJlR8HAUBLybNp1w/6lr6zZ2pjMShee65t/ybR5pT8ulkLzD1xwiw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
@@ -3656,7 +3656,7 @@
|
||||
"babel-plugin-transform-es2015-spread": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz",
|
||||
"integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=",
|
||||
"integrity": "sha512-3Ghhi26r4l3d0Js933E5+IhHwk0A1yiutj9gwvzmFbVV0sPMYk2lekhOufHBswX7NCoSeF4Xrl3sCIuSIa+zOg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
@@ -3665,7 +3665,7 @@
|
||||
"babel-plugin-transform-es2015-sticky-regex": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz",
|
||||
"integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=",
|
||||
"integrity": "sha512-CYP359ADryTo3pCsH0oxRo/0yn6UsEZLqYohHmvLQdfS9xkf+MbCzE3/Kolw9OYIY4ZMilH25z/5CbQbwDD+lQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-helper-regex": "^6.24.1",
|
||||
@@ -3676,7 +3676,7 @@
|
||||
"babel-plugin-transform-es2015-template-literals": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz",
|
||||
"integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=",
|
||||
"integrity": "sha512-x8b9W0ngnKzDMHimVtTfn5ryimars1ByTqsfBDwAqLibmuuQY6pgBQi5z1ErIsUOWBdw1bW9FSz5RZUojM4apg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
@@ -3685,7 +3685,7 @@
|
||||
"babel-plugin-transform-es2015-typeof-symbol": {
|
||||
"version": "6.23.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz",
|
||||
"integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=",
|
||||
"integrity": "sha512-fz6J2Sf4gYN6gWgRZaoFXmq93X+Li/8vf+fb0sGDVtdeWvxC9y5/bTD7bvfWMEq6zetGEHpWjtzRGSugt5kNqw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
@@ -3694,7 +3694,7 @@
|
||||
"babel-plugin-transform-es2015-unicode-regex": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz",
|
||||
"integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=",
|
||||
"integrity": "sha512-v61Dbbihf5XxnYjtBN04B/JBvsScY37R1cZT5r9permN1cp+b70DY3Ib3fIkgn1DI9U3tGgBJZVD8p/mE/4JbQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-helper-regex": "^6.24.1",
|
||||
@@ -3705,7 +3705,7 @@
|
||||
"babel-plugin-transform-exponentiation-operator": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz",
|
||||
"integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=",
|
||||
"integrity": "sha512-LzXDmbMkklvNhprr20//RStKVcT8Cu+SQtX18eMHLhjHf2yFzwtQ0S2f0jQ+89rokoNdmwoSqYzAhq86FxlLSQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1",
|
||||
@@ -3726,7 +3726,7 @@
|
||||
"babel-plugin-transform-regenerator": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz",
|
||||
"integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=",
|
||||
"integrity": "sha512-LS+dBkUGlNR15/5WHKe/8Neawx663qttS6AGqoOUhICc9d1KciBvtrQSuc0PI+CxQ2Q/S1aKuJ+u64GtLdcEZg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"regenerator-transform": "^0.10.0"
|
||||
@@ -3735,7 +3735,7 @@
|
||||
"babel-plugin-transform-runtime": {
|
||||
"version": "6.23.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz",
|
||||
"integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=",
|
||||
"integrity": "sha512-cpGMVC1vt/772y3jx1gwSaTitQVZuFDlllgreMsZ+rTYC6jlYXRyf5FQOgSnckOiA5QmzbXTyBY2A5AmZXF1fA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
@@ -3744,7 +3744,7 @@
|
||||
"babel-plugin-transform-strict-mode": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
|
||||
"integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=",
|
||||
"integrity": "sha512-j3KtSpjyLSJxNoCDrhwiJad8kw0gJ9REGj8/CqL0HeRyLnvUNYV9zcqluL6QJSXh3nfsLEmSLvwRfGzrgR96Pw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
@@ -4197,7 +4197,7 @@
|
||||
"boolbase": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
|
||||
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
|
||||
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
@@ -5182,7 +5182,7 @@
|
||||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
|
||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
|
||||
},
|
||||
"color-string": {
|
||||
"version": "1.9.1",
|
||||
@@ -5293,7 +5293,7 @@
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||
},
|
||||
"concat-stream": {
|
||||
"version": "1.6.2",
|
||||
@@ -8139,7 +8139,7 @@
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
|
||||
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="
|
||||
},
|
||||
"escodegen": {
|
||||
"version": "1.14.3",
|
||||
@@ -9199,7 +9199,7 @@
|
||||
"fast-levenshtein": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
|
||||
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
|
||||
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
|
||||
"dev": true
|
||||
},
|
||||
"faye-websocket": {
|
||||
@@ -9617,7 +9617,7 @@
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
||||
},
|
||||
"fsevents": {
|
||||
"version": "1.2.13",
|
||||
@@ -10148,7 +10148,7 @@
|
||||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
|
||||
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="
|
||||
},
|
||||
"has-symbol-support-x": {
|
||||
"version": "1.4.2",
|
||||
@@ -10704,7 +10704,7 @@
|
||||
"imurmurhash": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
|
||||
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o="
|
||||
"integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="
|
||||
},
|
||||
"in-publish": {
|
||||
"version": "2.0.1",
|
||||
@@ -10730,7 +10730,7 @@
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
@@ -10974,7 +10974,7 @@
|
||||
"is-extglob": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
|
||||
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="
|
||||
},
|
||||
"is-finite": {
|
||||
"version": "1.0.2",
|
||||
@@ -11189,7 +11189,7 @@
|
||||
"isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||
"dev": true
|
||||
},
|
||||
"isobject": {
|
||||
@@ -12492,7 +12492,7 @@
|
||||
"json-stable-stringify-without-jsonify": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
|
||||
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE="
|
||||
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
@@ -13806,6 +13806,11 @@
|
||||
"moment": ">= 2.9.0"
|
||||
}
|
||||
},
|
||||
"monaco-editor": {
|
||||
"version": "0.20.0",
|
||||
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.20.0.tgz",
|
||||
"integrity": "sha512-hkvf4EtPJRMQlPC3UbMoRs0vTAFAYdzFQ+gpMb8A+9znae1c43q8Mab9iVsgTcg/4PNiLGGn3SlDIa8uvK1FIQ=="
|
||||
},
|
||||
"move-concurrently": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
||||
@@ -13987,6 +13992,11 @@
|
||||
"integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
|
||||
"dev": true
|
||||
},
|
||||
"nano-assign": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/nano-assign/-/nano-assign-1.0.1.tgz",
|
||||
"integrity": "sha512-1K8ncUoAYFPYcCZqrB+K2XQaFCmA35rryJCtPkGrG3zYkwm+iIUZRIHyaAfuy6zxaK9siPdjeJq7+Inijm6xhw=="
|
||||
},
|
||||
"nanoid": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
|
||||
@@ -14020,7 +14030,7 @@
|
||||
"natural-compare": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
|
||||
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
|
||||
"dev": true
|
||||
},
|
||||
"ncp": {
|
||||
@@ -14510,7 +14520,7 @@
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
@@ -14887,7 +14897,7 @@
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
|
||||
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
|
||||
},
|
||||
"path-is-inside": {
|
||||
"version": "1.0.2",
|
||||
@@ -16633,7 +16643,7 @@
|
||||
"rechoir": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
|
||||
"integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
|
||||
"integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"resolve": "^1.1.6"
|
||||
@@ -16717,7 +16727,7 @@
|
||||
"regexpu-core": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz",
|
||||
"integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=",
|
||||
"integrity": "sha512-tJ9+S4oKjxY8IZ9jmjnp/mtytu1u3iyIQAfmI51IKWH6bFf7XR1ybtaO6j7INhZKXOTYADk7V5qxaqLkmNxiZQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"regenerate": "^1.2.1",
|
||||
@@ -16728,13 +16738,13 @@
|
||||
"regjsgen": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
|
||||
"integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
|
||||
"integrity": "sha512-x+Y3yA24uF68m5GA+tBjbGYo64xXVJpbToBaWCoSNSc1hdk6dfctaRWrNFTVJZIIhL5GxW8zwjoixbnifnK59g==",
|
||||
"dev": true
|
||||
},
|
||||
"regjsparser": {
|
||||
"version": "0.1.5",
|
||||
"resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
|
||||
"integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
|
||||
"integrity": "sha512-jlQ9gYLfk2p3V5Ag5fYhA7fv7OHzd1KUH0PRP46xc3TgwjwgROIW572AfYg/X9kaNq/LJnu6oJcFRXlIrGoTRw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"jsesc": "~0.5.0"
|
||||
@@ -16743,7 +16753,7 @@
|
||||
"jsesc": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
|
||||
"integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
|
||||
"integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
@@ -18465,7 +18475,7 @@
|
||||
"svg-tags": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz",
|
||||
"integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=",
|
||||
"integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==",
|
||||
"dev": true
|
||||
},
|
||||
"svgo": {
|
||||
@@ -19180,7 +19190,7 @@
|
||||
"text-table": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
|
||||
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
||||
"dev": true
|
||||
},
|
||||
"throat": {
|
||||
@@ -19820,7 +19830,7 @@
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||
},
|
||||
"util.promisify": {
|
||||
"version": "1.0.0",
|
||||
@@ -20153,6 +20163,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"vue-monaco": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/vue-monaco/-/vue-monaco-1.2.2.tgz",
|
||||
"integrity": "sha512-+BhCHeAuDmjtCUP9MUxan6OjGgOqDR7xHlNScZ8Cfq32iac76Fv7z6RfC+lSrp0YpCjEPl6bvpY21N11UBRmMg==",
|
||||
"requires": {
|
||||
"monaco-editor": "^0.20.0",
|
||||
"nano-assign": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"vue-quill-editor": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/vue-quill-editor/-/vue-quill-editor-3.0.6.tgz",
|
||||
@@ -21146,7 +21165,7 @@
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
},
|
||||
"write-file-atomic": {
|
||||
"version": "2.4.1",
|
||||
|
||||
@@ -90,6 +90,7 @@
|
||||
"vue-grid-layout": "^2.3.12",
|
||||
"vue-i18n": "^8.15.1",
|
||||
"vue-introjs": "^1.3.2",
|
||||
"vue-monaco": "^1.2.2",
|
||||
"vue-quill-editor": "^3.0.6",
|
||||
"vue-resource": "^1.5.1",
|
||||
"vue-router": "^3.0.1",
|
||||
|
||||
@@ -177,6 +177,12 @@
|
||||
.el-col .el-col-24 .metric-selector-input-box{
|
||||
|
||||
}
|
||||
.lines-content {
|
||||
//height: auto !important;
|
||||
//width: 100% !important;
|
||||
//position: unset !important;
|
||||
top: 5px !important;
|
||||
}
|
||||
}
|
||||
.topo-page {
|
||||
.promqlInput {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import { DefaultTimeRange } from '../../variables/interpolation/defaults.js'
|
||||
import { getClosest } from './utils.js'
|
||||
|
||||
function getTimeRange (sceneObject) {
|
||||
let _a
|
||||
return (_a = getClosest(sceneObject, (s) => s.state.$timeRange)) != null ? _a : DefaultTimeRange
|
||||
}
|
||||
|
||||
export { getTimeRange }
|
||||
@@ -0,0 +1,908 @@
|
||||
const lr = require('@lezer/lr')
|
||||
const lodash = require('lodash')
|
||||
// This file was generated by lezer-generator. You probably shouldn't edit it.
|
||||
const Json$1 = 1
|
||||
const Logfmt$1 = 2
|
||||
const Unpack$1 = 3
|
||||
const Pattern$1 = 4
|
||||
const Regexp$1 = 5
|
||||
const Unwrap$1 = 6
|
||||
const Ip$1 = 7
|
||||
const LabelFormat$1 = 8
|
||||
const LineFormat$1 = 9
|
||||
const LabelReplace$1 = 10
|
||||
const Vector$1 = 11
|
||||
const Offset$1 = 12
|
||||
const Bool$1 = 13
|
||||
const On$1 = 14
|
||||
const Ignoring$1 = 15
|
||||
const GroupLeft$1 = 16
|
||||
const GroupRight$1 = 17
|
||||
const Decolorize$1 = 18
|
||||
const Drop$1 = 19
|
||||
const Keep$1 = 20
|
||||
const By$1 = 21
|
||||
const Without$1 = 22
|
||||
const And$1 = 23
|
||||
const Or$1 = 24
|
||||
const Unless$1 = 25
|
||||
const Sum$1 = 26
|
||||
const Avg$1 = 27
|
||||
const Count$1 = 28
|
||||
const Max$1 = 29
|
||||
const Min$1 = 30
|
||||
const Stddev$1 = 31
|
||||
const Stdvar$1 = 32
|
||||
const Bottomk$1 = 33
|
||||
const Topk$1 = 34
|
||||
const LogExpr$1 = 38
|
||||
const MetricExpr$1 = 86
|
||||
|
||||
const keywordTokens = {
|
||||
json: Json$1,
|
||||
logfmt: Logfmt$1,
|
||||
unpack: Unpack$1,
|
||||
pattern: Pattern$1,
|
||||
regexp: Regexp$1,
|
||||
ip: Ip$1,
|
||||
label_format: LabelFormat$1,
|
||||
line_format: LineFormat$1,
|
||||
label_replace: LabelReplace$1,
|
||||
vector: Vector$1,
|
||||
offset: Offset$1,
|
||||
bool: Bool$1,
|
||||
on: On$1,
|
||||
ignoring: Ignoring$1,
|
||||
group_left: GroupLeft$1,
|
||||
group_right: GroupRight$1,
|
||||
unwrap: Unwrap$1,
|
||||
decolorize: Decolorize$1,
|
||||
drop: Drop$1,
|
||||
keep: Keep$1
|
||||
}
|
||||
|
||||
const specializeIdentifier = (value) => {
|
||||
return keywordTokens[value.toLowerCase()] || -1
|
||||
}
|
||||
|
||||
const contextualKeywordTokens = {
|
||||
by: By$1,
|
||||
without: Without$1,
|
||||
and: And$1,
|
||||
or: Or$1,
|
||||
unless: Unless$1,
|
||||
sum: Sum$1,
|
||||
avg: Avg$1,
|
||||
count: Count$1,
|
||||
max: Max$1,
|
||||
min: Min$1,
|
||||
stddev: Stddev$1,
|
||||
stdvar: Stdvar$1,
|
||||
bottomk: Bottomk$1,
|
||||
topk: Topk$1
|
||||
}
|
||||
|
||||
const extendIdentifier = (value) => {
|
||||
return contextualKeywordTokens[value.toLowerCase()] || -1
|
||||
}
|
||||
|
||||
// This file was generated by lezer-generator. You probably shouldn't edit it.
|
||||
// eslint-disable-next-line camelcase
|
||||
const spec_Identifier = { __proto__: null, count_over_time: 281, rate: 283, rate_counter: 285, bytes_over_time: 287, bytes_rate: 289, avg_over_time: 291, sum_over_time: 293, min_over_time: 295, max_over_time: 297, stddev_over_time: 299, stdvar_over_time: 301, quantile_over_time: 303, first_over_time: 305, last_over_time: 307, absent_over_time: 309, bytes: 315, duration: 317, duration_seconds: 319 }
|
||||
const parser = lr.LRParser.deserialize({
|
||||
version: 14,
|
||||
states: "CdOYQPOOO#]QPO'#DTO$lQPO'#DSOYQPO'#DSOOQO'#EW'#EWO$yQPO'#EVOOQO'#Es'#EsO%OQPO'#ErQ%ZQPOOOOQO'#FR'#FRO&[QPO'#FRO&aQPO'#FSO&fQPO'#FTOOQO'#EU'#EUOOQO'#DR'#DROOQO'#EX'#EXOOQO'#EY'#EYOOQO'#EZ'#EZOOQO'#E['#E[OOQO'#E]'#E]OOQO'#E^'#E^OOQO'#E_'#E_OOQO'#E`'#E`OOQO'#Ea'#EaOOQO'#Eb'#EbOOQO'#Ec'#EcOOQO'#Ed'#EdOOQO'#Ee'#EeOOQO'#Ef'#EfOOQO'#Eg'#EgO&kQPO'#DVOOQO'#DU'#DUO&yQPO,59oOOQO'#Db'#DbO'RQPO'#DaOOQO'#D`'#D`O'ZQPO'#D_O(tQPO'#D_OOQO'#D^'#D^O*vQPO,59nO,UQPO,59nO,]QPO,5:pO,dQPO,5:qO,oQPO'#EpO.tQPO,5;^O.{QPO,5;^O/QQPO,5;`O/QQPO,5;`O/QQPO,5;`O/QQPO,5;`O/QQPO,5;`O/QQPO,5;`OOQO,5;m,5;mOYQPO,5;nO1^QPO,5;oO1cQPO,59qO#]QPO,59pOOQO1G/Z1G/ZOOQO'#De'#DeOOQO,59{,59{O1hQPO,59{OOQO,59z,59zO1mQPO'#DVO2[QPO'#DgOOQO'#Dg'#DgO3xQPO'#DgOOQO'#Dm'#DmOOQO'#Dk'#DkO)dQPO'#DkO3}QPO,59yO5hQPO'#DyO5mQPO'#DzOOQO'#D}'#D}O5rQPO'#EOO5wQPO'#EROOQO,59y,59yOOQO,59x,59xOOQO1G/Y1G/YOOQO1G0[1G0[O5|QPO'#EhO,gQPO'#EhO6bQPO1G0]O6gQPO1G0]O6lQPO,5;[O6tQPO1G0xO8PQPO1G0xO8WQPO1G0xO8_QPO'#EvO:gQPO'#EuO:qQPO'#EuOYQPO1G0zOYQPO1G0zOYQPO1G0zOYQPO1G0zOYQPO1G0zOYQPO1G0zO:{QPO1G1YO;SQPO1G1ZOOQO1G/]1G/]OOQO1G/[1G/[O;XQPO1G/gO;^QPO,59qO;dQPO,5:YO;oQPO'#DjOOQO'#Di'#DiO;tQPO,5:SOOQO,5:R,5:RO=_QPO,5:VO)dQPO,5:VO)dQPO,5:VOOQO,5:e,5:eO=mQPO'#D|OOQO'#D{'#D{O=rQPO,5:fO?]QPO'#EQOOQO'#EQ'#EQOOQO'#EP'#EPO@|QPO,5:jOBgQPO'#ETOOQO'#ET'#ETOOQO'#ES'#ESODWQPO,5:mOEqQPO'#D_O5|QPO,5;SOExQPO'#EiOE}QPO,5;SOFhQPO,5;SOFrQPO,5;SOFyQPO,5;SOGOQPO7+%wO,gQPO7+%wOOQO'#Eq'#EqOH`QPO1G0vOOQO1G0v1G0vOHhQPO7+&dOYQPO7+&dOIxQPO7+&dOJPQPO7+&dOJWQQO'#EwOOQO,5;b,5;bOL`QPO,5;aOLgQPO,5;aOMxQPO7+&fONPQPO7+&fOOQO7+&f7+&fON^QPO7+&fONeQPO7+&fO! jQPO7+&fO! zQPO7+&tOOQO7+&u7+&uO!!PQPO7+%RO!!UQPO1G/rOOQO1G/t1G/tOOQO1G/{1G/{OOQO1G/}1G/}O!!ZQPO,5:UO!!`QPO,5:TOOQO1G/q1G/qO!!eQPO1G/qO!$OQPO,5:hO5mQPO,5:gO5rQPO,5:kO5wQPO,5:nO!$WQPO,5;VOE}QPO1G0nO!$fQPO1G0nO!$nQPO,5;TO)dQPO,5;VO!$sQPO1G0nO!$zQPO'#EjO!%PQPO1G0nO!$sQPO1G0nO!%XQPO1G0nO!%`QPO1G0nO6]QPO1G0nOOQO1G0n1G0nOOQO<<Ic<<IcO!%kQPO<<IcO!%pQPO,5;]OOQO7+&b7+&bOOQO<<JO<<JOO!%uQPO<<JOOYQPO<<JOOOQO'#Ey'#EyO!%|QPO,5;cOOQO'#Ex'#ExOOQO,5;c,5;cOOQO1G0{1G0{O!&UQPO1G0{O!(XQPO<<J`OOQO<<Hm<<HmO!(^QPO7+%^OOQO1G/p1G/pOOQO1G/o1G/oOOQO1G0S1G0SOOQO1G0R1G0ROOQO1G0V1G0VOOQO1G0Y1G0YOOQO'#El'#ElOOQO1G0q1G0qO!(cQPO1G0qOOQO'#Em'#EmOOQO'#En'#EnOOQO'#Eo'#EoOOQO7+&Y7+&YOOQO1G0o1G0oO!(hQPO1G0qO!(|QPO7+&YOOQO,5;U,5;UO!)UQPO7+&YO6]QPO7+&YO!)]QPO7+&YO!)hQPOAN>}OOQO1G0w1G0wO!*xQPOAN?jO!,YQPOAN?jO!,aQQO1G0}OOQO1G0}1G0}OOQO7+&g7+&gO!,iQPOAN?zO!,nQPO<<HxO!,sQPO7+&]O!,xQPO<<ItO!-QQPO<<ItO!-YQPO'#EkO!-_QPO<<ItOOQOG24iG24iOOQOG25UG25UOOQO1G1O1G1OOOQO7+&i7+&iO!-gQPOG25fOOQOAN>dAN>dO!-lQPO<<IwOOQOAN?`AN?`O!-qQPOAN?`O!-yQPOLD+QOOQOAN?cAN?cOOQO,5:f,5:fO!.OQPO!$'NlO!.TQPO!)9DWO!.YQPO!.K9rOOQO!4//^!4//^O5mQPO'#DzO!._QPO'#D_O!/VQPO,59nO!/aQPO'#DSOYQPO1G0zOYQPO1G0zOYQPO1G0zOYQPO1G0zOYQPO1G0zOYQPO1G0zO/QQPO,5;`O/QQPO,5;`O/QQPO,5;`O/QQPO,5;`O/QQPO,5;`O/QQPO,5;`O!0lQPO7+&fO!0sQPO7+&fO!1QQPO7+&fO!2YQPO7+&fO!2aQPO7+&fO!1XQPO'#Et",
|
||||
stateData: '!2n~O#zOSsOS~OYZOZ[OjUOkUOlUOmUOnUOoUOpUOqUOrUO!lXO#oYO#pYO#{PO$ORO$Q_O$R`O$SaO$TbO$UcO$VdO$WeO$XfO$YgO$ZhO$[iO$]jO$^kO$_lO$`mO~OznO~O}qO!PqO!VqO!WqOgvXhvXivX!cvX!evX!fvX!gvX!hvX#ovX#pvX#qvX#rvX#svX#tvX~O!YuO#xvX$PvX~P#bO$OzO~Oe{Of{O$O|O~Og!POh!OOi!PO}!TO!c!TO!e!TO!f!TO!g!TO!h!TO#o!QO#p!QO#q!RO#r!RO#s!RO#t!SO~O!l!UO~O$O!VO~O$O!WO~O{!XO}!XO!O!XO!P!XO~O#|!YO#}!ZO~OV![O|!]O~O}qO!PqO!VqO!WqOg!RXh!RXi!RX!Y!RX!c!RX!e!RX!f!RX!g!RX!h!RX#o!RX#p!RX#q!RX#r!RX#s!RX#t!RX#x!RX$P!RX$a!RX#|!RX~OP!aOQ!bOR!bOS!cOT!cOW!iOX!hOb!jOc!kOd!lOz!`O$O!fO~O}qO!PqO!VqO!WqOgvahvaiva!cva!eva!fva!gva!hva#ova#pva#qva#rva#sva#tva~O!YuO#xva$Pva~P)lOguXhuXiuX}uX!cuX!euX!fuX!guX!huX#ouX#puX#quX#ruX#suX#tuX~O$P!oO~P+TO$P!pO~P+TO!l!tO#{PO$O!rO~O$O!uO~OYZOZ[OjUOkUOlUOmUOnUOoUOpUOqUOrUO#oYO#pYO#{PO$ORO$Q_O$R`O$SaO$TbO$UcO$VdO$WeO$XfO$YgO$ZhO$[iO$]jO$^kO$_lO$`mO~O!l!wO~P,tO$O!xO~O]!{O^!yO_!yOY#iPZ#iPj#iPk#iPl#iPm#iPn#iPo#iPp#iPq#iPr#iP!l#iP#o#iP#p#iP#{#iP$O#iP$Q#iP$R#iP$S#iP$T#iP$U#iP$V#iP$W#iP$X#iP$Y#iP$Z#iP$[#iP$]#iP$^#iP$_#iP$`#iP~O!l#TO~O|#UO~O$O#WO~O{#XO}#XO!O!XO!P!XO!c#YO!e#YO!f#YO!g#YO!h#YO~Oz#ZOg!ZXh!ZXi!ZX}!ZX!P!ZX!V!ZX!W!ZX!Y!ZX!c!ZX!e!ZX!f!ZX!g!ZX!h!ZX#o!ZX#p!ZX#q!ZX#r!ZX#s!ZX#t!ZX#x!ZX$P!ZX$a!ZX#|!ZX~O|#^O~Og#`Oh#aO#|#`Oi!Ra}!Ra!P!Ra!V!Ra!W!Ra!Y!Ra!c!Ra!e!Ra!f!Ra!g!Ra!h!Ra#o!Ra#p!Ra#q!Ra#r!Ra#s!Ra#t!Ra#x!Ra$P!Ra$a!Ra~O|#bO~Oz#cO~Oz#fO~Oz#jO~O}qO!PqO!VqO!WqO!Y#nO$a#pO~O$P#uO~O#|#vO~Oz#wO$P#yO~O$P#zO~P+TOg#uXh#uXi#uX}#uX!c#uX!e#uX!f#uX!g#uX!h#uX#o#uX#p#uX#q#uX#r#uX#s#uX#t#uX$P#uX~O#|#{O~P6{O!l#}O~P,tO$O$OO~OY#iXZ#iXj#iXk#iXl#iXm#iXn#iXo#iXp#iXq#iXr#iX!l#iX#o#iX#p#iX#{#iX$O#iX$Q#iX$R#iX$S#iX$T#iX$U#iX$V#iX$W#iX$X#iX$Y#iX$Z#iX$[#iX$]#iX$^#iX$_#iX$`#iX~O`$QOa$QO~P8dO^!yO_!yO~P8dO#|$YO~P+TO$P$ZO~O|$[O~OV$]O|#UO!d$^O!j$_O!l$`O~O{$aO~O#|$bOg![ah![ai![a}![a!P![a!V![a!W![a!Y![a!c![a!e![a!f![a!g![a!h![a#o![a#p![a#q![a#r![a#s![a#t![a#x![a$P![a$a![a~Og#`Oh#aO#|#`O$P$cO~O{$eO~O#|$fOg!nah!nai!na}!na!P!na!V!na!W!na!Y!na!c!na!e!na!f!na!g!na!h!na#o!na#p!na#q!na#r!na#s!na#t!na#x!na$P!na$a!na~O{!XO}!XO!O!XO!P!XOg!tXh!tXi!tX!V!tX!W!tX!Y!tX!c!tX!e!tX!f!tX!g!tX!h!tX#o!tX#p!tX#q!tX#r!tX#s!tX#t!tX#x!tX#|!tX$P!tX$a!tX~O#|$gOg!rah!rai!ra}!ra!P!ra!V!ra!W!ra!Y!ra!c!ra!e!ra!f!ra!g!ra!h!ra#o!ra#p!ra#q!ra#r!ra#s!ra#t!ra#x!ra$P!ra$a!ra~O{!XO}!XO!O!XO!P!XOg!wXh!wXi!wX!V!wX!W!wX!Y!wX!c!wX!e!wX!f!wX!g!wX!h!wX#o!wX#p!wX#q!wX#r!wX#s!wX#t!wX#x!wX#|!wX$P!wX$a!wX~O#|$hOg!uah!uai!ua}!ua!P!ua!V!ua!W!ua!Y!ua!c!ua!e!ua!f!ua!g!ua!h!ua#o!ua#p!ua#q!ua#r!ua#s!ua#t!ua#x!ua$P!ua$a!ua~OU$iO~P(tO!d$lO~O!Y$mO$a#pO~O}qO!PqO!VqO!WqO!Y#nO~O[$oO$P#[a~PFVO$P$tO~P5|O$P$uO~Oe{Of{Og!yqh!yqi!yq}!yq!c!yq!e!yq!f!yq!g!yq!h!yq#o!yq#p!yq#q!yq#r!yq#s!yq#t!yq#x!yq$P!yq#|!yq~O#|$xO$P$yO~Oe{Of{Og#fqh#fqi#fq}#fq!c#fq!e#fq!f#fq!g#fq!h#fq#o#fq#p#fq#q#fq#r#fq#s#fq#t#fq#x#fq$P#fq#|#fq~O$P$zO~P+TO#|$|O~P6{O#n$}O$P%QO~OY#iaZ#iaj#iak#ial#iam#ian#iao#iap#iaq#iar#ia!l#ia#o#ia#p#ia#{#ia$Q#ia$R#ia$S#ia$T#ia$U#ia$V#ia$W#ia$X#ia$Y#ia$Z#ia$[#ia$]#ia$^#ia$_#ia$`#ia~O$O$OO~PJ`O`%SOa%SO$O#ia~PJ`Og!POi!PO}!TO!c!TO!e!TO!f!TO!g!TO!h!TO#o!QO#p!QO#q#hq#r#hq#s#hq#t#hq#x#hq$P#hq~Oh#hq~PLtOg#hqh#hqi#hq~PLzOh!OO~PLtO#x#hq$P#hq~P%ZOg#hqh#hqi#hq}#hq!c#hq!e#hq!f#hq!g#hq!h#hq#q#hq#r#hq#s#hq#t#hq~O#o!QO#p!QO#x#hq$P#hq~PNoO|%TO~O$P%UO~O$O%VO~O|%WO~Oz#ZO~Og#`O#|#`Oh!_ii!_i}!_i!P!_i!V!_i!W!_i!Y!_i!c!_i!e!_i!f!_i!g!_i!h!_i#o!_i#p!_i#q!_i#r!_i#s!_i#t!_i#x!_i$P!_i$a!_i~Oz%YO|%YO~Oz%_O$c%aO$d%bO$e%cO~O[$oO$P#[i~O$b%eO~O$P#[i~PFVO!d%hO~O!Y$mO$P#[i~O$P%jO~P5|O!Y$mO$P%jO$a#pO~O$P%lO~Oz%mO~O$P%nO~P+TO#|%pO$P%qO~O$O$OOY#iiZ#iij#iik#iil#iim#iin#iio#iip#iiq#iir#ii!l#ii#o#ii#p#ii#{#ii$Q#ii$R#ii$S#ii$T#ii$U#ii$V#ii$W#ii$X#ii$Y#ii$Z#ii$[#ii$]#ii$^#ii$_#ii$`#ii~O#|%sO~O|%tO~O$O%uO~Og#`Oh#aO#|#`O!Y#_i$a#_i$P#_i~O!Y$mO$P#[q~O$P#[q~PFVO[$oO!Y%xO$P#[q~Oe{Of{Og!y!Rh!y!Ri!y!R}!y!R!c!y!R!e!y!R!f!y!R!g!y!R!h!y!R#o!y!R#p!y!R#q!y!R#r!y!R#s!y!R#t!y!R#x!y!R$P!y!R#|!y!R~Oe{Of{Og#f!Rh#f!Ri#f!R}#f!R!c#f!R!e#f!R!f#f!R!g#f!R!h#f!R#o#f!R#p#f!R#q#f!R#r#f!R#s#f!R#t#f!R#x#f!R$P#f!R#|#f!R~O$P%{O~P+TO#n$}O$P%}O~O|&OO~O$P&PO~Oz&QO~O!Y$mO$P#[y~O[$oO$P#[y~OU$iO~O!Y%xO$P#[y~O#|&TO~O$P&UO~O!Y$mO$P#[!R~O|&WO~O#|&XO~O|&YO~O$P&ZO~OP!aOQ!bOR!bOS!cOT!cOW&[OX!hOb!jOc!kOd!lOz!`O$O!fO~O!Y&]O#|va~P)lO!Y&]O#|vX~P#bOg&gOi&gO}&kO!c&kO!e&kO!f&kO!g&kO!h&kO#o&hO#p&hO#q#hq#r#hq#s#hq#t#hq#|#hq~Oh#hq~P!/kOg#hqh#hqi#hq~P!/qOh&fO~P!/kOg&gOh&fOi&gO}&kO!c&kO!e&kO!f&kO!g&kO!h&kO#o&hO#p&hO#q&iO#r&iO#s&iO#t&jO~O#|#hq~P!1XO#o&hO#p&hO#|#hq~PNoO',
|
||||
// eslint-disable-next-line no-template-curly-in-string
|
||||
goto: "0U#xPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP#y$x%a&P&SPPPPPP&k&}'_'m(OPP(_P(b(b(g(j(p)R)R)[PPPPPP)[P)RP(b(b)e)k(b(b)r)u(b){*O*U*w+^+s+s+s+s+s+s+s+s+s+s+s+s+s+s+s,Y,c,v-S-l-o-o-o-r.R*w.U*w.k/a/r/{0OPPPPPPP*w*w*w[WOR|!x#{$|Q$S!|Q$T!}S$U#O&bQ$V#PQ$W#QQ$X#RQ&l&`Q&m&aQ&n&cQ&o&dQ&p&eR&q!Vt^O|!V!x!|!}#O#P#Q#R#{$|&`&a&b&c&d&eRxRjQOR|!V!x!|!}#O#P#Q#R#{$|S!qz#vQ#s!r]&_&`&a&b&c&d&eRpPQoP^!eu!f#`#a#n$m&]Q#V!YS#g!k$gT#k!l$hQwQQ#o!qQ$n#rQ$r#sQ%i$qR&^&_[vQ!q#r#s$q&_]!nw#o$n$r%i&^itQw!q#o#r#s$n$q$r%i&^&_hsQw!q#o#r#s$n$q$r%i&^&_R!_tkrQtw!q#o#r#s$n$q$r%i&^&_R!^rV!mu#n&]R#]!aQ#[!aR%X$bU!gu#n&]Q#_!fQ$c#`Q$d#aR%f$m_!eu!f#`#a#n$m&]_!du!f#`#a#n$m&]Q#e!iR&V&[S#d!i&[R%Z$fR#i!kQ#h!kR%[$gR#m!lQ#l!lR%]$hj^O!|!}#O#P#Q#R&`&a&b&c&d&eQyRQ!v|Q#S!VQ#|!xQ${#{R%o$|w]OR|!V!x!|!}#O#P#Q#R#{$|&`&a&b&c&d&ewTOR|!V!x!|!}#O#P#Q#R#{$|&`&a&b&c&d&ewSOR|!V!x!|!}#O#P#Q#R#{$|&`&a&b&c&d&eQ!szQ#t!rR$w#vS#r!q#sW$k#o#q$r$sQ%d$jQ%k$tR%w%jQ$q#rQ%d$kQ%y%kR&R%wQ#q!qS$j#o$rQ$p#rQ$s#sS%g$n$qS%v%i%kR&S%yR%`$iR%^$iQ}VQ$v#uQ$z#zQ%z%lR%{%nR#x!uwVOR|!V!x!|!}#O#P#Q#R#{$|&`&a&b&c&d&eQ!|!OQ!}!PQ#O!QQ#P!RQ#Q!SQ#R!TQ&`&fQ&a&gQ&b&hQ&c&iQ&d&jR&e&kh!z!O!P!Q!R!S!T&f&g&h&i&j&kR$R!{Q$P!yQ%R$QR%r%SR%O$OQ%P$OR%|%p",
|
||||
nodeNames: '⚠ Json Logfmt Unpack Pattern Regexp Unwrap Ip LabelFormat LineFormat LabelReplace Vector Offset Bool On Ignoring GroupLeft GroupRight Decolorize Drop Keep By Without And Or Unless Sum Avg Count Max Min Stddev Stdvar Bottomk Topk LineComment LogQL Expr LogExpr Selector Matchers Matcher Identifier Eq String Neq Re Nre PipelineExpr PipelineStage LineFilters LineFilter Filter PipeExact PipeMatch FilterOp Pipe LabelParser JsonExpressionParser JsonExpressionList JsonExpression LabelFilter IpLabelFilter UnitFilter DurationFilter Gtr Duration Gte Lss Lte Eql BytesFilter Bytes NumberFilter Number LineFormatExpr LabelFormatExpr LabelsFormat LabelFormatMatcher DecolorizeExpr DropLabelsExpr DropLabels DropLabel KeepLabelsExpr KeepLabels KeepLabel MetricExpr RangeAggregationExpr RangeOp CountOverTime Rate RateCounter BytesOverTime BytesRate AvgOverTime SumOverTime MinOverTime MaxOverTime StddevOverTime StdvarOverTime QuantileOverTime FirstOverTime LastOverTime AbsentOverTime LogRangeExpr Range OffsetExpr UnwrapExpr ConvOp BytesConv DurationConv DurationSecondsConv Grouping Labels VectorAggregationExpr VectorOp BinOpExpr BinOpModifier OnOrIgnoringModifier GroupingLabels GroupingLabelList GroupingLabel LabelName Add Sub Mul Div Mod Pow LiteralExpr LabelReplaceExpr VectorExpr',
|
||||
maxTerm: 159,
|
||||
skippedNodes: [0, 35],
|
||||
repeatNodeCount: 0,
|
||||
tokenData: "3X~RvX^#ipq#iqr$^rs$qst%cuv%nxy%syz%xz{%}{|&S|}&X}!O&^!O!P&c!P!Q'c!Q!R'h!R![)O![!]0O!^!_0d!_!`0q!`!a1W!c!}1e!}#O1{#P#Q2Q#Q#R2V#R#S1e#S#T2[#T#o1e#o#p2h#p#q2m#q#r3S#y#z#i$f$g#i#BY#BZ#i$IS$I_#i$I|$JO#i$JT$JU#i$KV$KW#i&FU&FV#i~#nY#z~X^#ipq#i#y#z#i$f$g#i#BY#BZ#i$IS$I_#i$I|$JO#i$JT$JU#i$KV$KW#i&FU&FV#i~$aQ!_!`$g#r#s$l~$lO}~~$qO!P~~$tUOY$qZr$qrs%Ws#O$q#O#P%]#P~$q~%]O|~~%`PO~$q~%hQs~OY%cZ~%c~%sO#s~~%xO$O~~%}O$P~~&SO#q~~&XO#o~~&^O#|~~&cO#p~~&fP!Q![&i~&nR!l~!Q![&i!g!h&w#X#Y&w~&zR{|'T}!O'T!Q!['Z~'WP!Q!['Z~'`P!l~!Q!['Z~'hO#r~~'me!l~!O!P&i!Q![)O!g!h*c!i!j+Q!m!n+Q!o!p+Q!r!s+Q!v!w+Q#U#V*u#W#X+Z#X#Y-]#Z#[-o#[#]+r#_#`-o#a#b-x#d#e-o#g#h,z#h#i-o#k#l.Z#l#m/d#m#n.u~)Td!l~!O!P&i!Q![)O!g!h*c!i!j+Q!m!n+Q!o!p+Q!r!s+Q!v!w+Q#U#V*u#W#X+Z#X#Y-]#Z#[-o#[#]+r#_#`-o#a#b-x#d#e-o#g#h,z#h#i-o#k#l.Z#m#n.u~*fT{|'T}!O'T!Q!['Z!d!e*u#]#^*z~*zO!j~~*}P#U#V*u~+TQ!d!e*u#]#^*z~+`P!d~!Q![+c~+fS!Q![+c#[#]+r#a#b,W#g#h,z~+wP!d~!Q![+z~+}R!Q![+z#a#b,W#g#h,z~,]Q!d~!Q![,c#g#h,u~,fR!Q![,c#a#b,o#g#h,z~,rP#g#h,u~,zO!d~~-PP!d~!Q![-S~-VQ!Q![-S#a#b,o~-`T{|'T}!O'T!Q!['Z#U#V*u#]#^*z~-rQ#U#V*u#]#^*z~-}S!d~!Q![,c#U#V*u#]#^*z#g#h,u~.`P!d~!Q![.c~.fT!Q![.c#W#X+Z#[#]+r#a#b,W#g#h,z~.zP!d~!Q![.}~/QU!Q![.}#W#X+Z#[#]+r#a#b,W#g#h,z#k#l.Z~/gR!Q![/p!c!i/p#T#Z/p~/uR!l~!Q![/p!c!i/p#T#Z/pP0TTzP!Q![0O![!]0O!c!}0O#R#S0O#T#o0O~0iP!f~!_!`0l~0qO!g~~0vQ{~!_!`0|#r#s1R~1RO!h~~1WO!O~~1]P!c~!_!`1`~1eO!e~R1lTzP#nQ!Q![1e![!]0O!c!}1e#R#S1e#T#o1e~2QO$a~~2VO$b~~2[O#t~~2_RO#S2[#S#T%W#T~2[~2mO#{~~2rQ!Y~!_!`2x#r#s2}~2}O!V~~3SO!W~~3XO#}~",
|
||||
tokenizers: [0, 1],
|
||||
topRules: { LogQL: [0, 36] },
|
||||
specialized: [{ term: 42, get: (value, stack) => (specializeIdentifier(value) << 1) }, { term: 42, get: (value, stack) => (extendIdentifier(value) << 1) | 1 }, { term: 42, get: value => spec_Identifier[value] || -1 }],
|
||||
tokenPrec: 0
|
||||
})
|
||||
// This file was generated by lezer-generator. You probably shouldn't edit it.
|
||||
const Json = 1
|
||||
const Logfmt = 2
|
||||
const Unpack = 3
|
||||
const Pattern = 4
|
||||
const Regexp = 5
|
||||
const Unwrap = 6
|
||||
const Ip = 7
|
||||
const LabelFormat = 8
|
||||
const LineFormat = 9
|
||||
const LabelReplace = 10
|
||||
const Vector = 11
|
||||
const Offset = 12
|
||||
const Bool = 13
|
||||
const On = 14
|
||||
const Ignoring = 15
|
||||
const GroupLeft = 16
|
||||
const GroupRight = 17
|
||||
const Decolorize = 18
|
||||
const Drop = 19
|
||||
const Keep = 20
|
||||
const By = 21
|
||||
const Without = 22
|
||||
const And = 23
|
||||
const Or = 24
|
||||
const Unless = 25
|
||||
const Sum = 26
|
||||
const Avg = 27
|
||||
const Count = 28
|
||||
const Max = 29
|
||||
const Min = 30
|
||||
const Stddev = 31
|
||||
const Stdvar = 32
|
||||
const Bottomk = 33
|
||||
const Topk = 34
|
||||
const LineComment = 35
|
||||
const LogQL = 36
|
||||
const Expr = 37
|
||||
const LogExpr = 38
|
||||
const Selector = 39
|
||||
const Matchers = 40
|
||||
const Matcher = 41
|
||||
const Identifier = 42
|
||||
const Eq = 43
|
||||
const String = 44
|
||||
const Neq = 45
|
||||
const Re = 46
|
||||
const Nre = 47
|
||||
const PipelineExpr = 48
|
||||
const PipelineStage = 49
|
||||
const LineFilters = 50
|
||||
const LineFilter = 51
|
||||
const Filter = 52
|
||||
const PipeExact = 53
|
||||
const PipeMatch = 54
|
||||
const FilterOp = 55
|
||||
const Pipe = 56
|
||||
const LabelParser = 57
|
||||
const JsonExpressionParser = 58
|
||||
const JsonExpressionList = 59
|
||||
const JsonExpression = 60
|
||||
const LabelFilter = 61
|
||||
const IpLabelFilter = 62
|
||||
const UnitFilter = 63
|
||||
const DurationFilter = 64
|
||||
const Gtr = 65
|
||||
const Duration = 66
|
||||
const Gte = 67
|
||||
const Lss = 68
|
||||
const Lte = 69
|
||||
const Eql = 70
|
||||
const BytesFilter = 71
|
||||
const Bytes = 72
|
||||
const NumberFilter = 73
|
||||
const Number = 74
|
||||
const LineFormatExpr = 75
|
||||
const LabelFormatExpr = 76
|
||||
const LabelsFormat = 77
|
||||
const LabelFormatMatcher = 78
|
||||
const DecolorizeExpr = 79
|
||||
const DropLabelsExpr = 80
|
||||
const DropLabels = 81
|
||||
const DropLabel = 82
|
||||
const KeepLabelsExpr = 83
|
||||
const KeepLabels = 84
|
||||
const KeepLabel = 85
|
||||
const MetricExpr = 86
|
||||
const RangeAggregationExpr = 87
|
||||
const RangeOp = 88
|
||||
const CountOverTime = 89
|
||||
const Rate = 90
|
||||
const RateCounter = 91
|
||||
const BytesOverTime = 92
|
||||
const BytesRate = 93
|
||||
const AvgOverTime = 94
|
||||
const SumOverTime = 95
|
||||
const MinOverTime = 96
|
||||
const MaxOverTime = 97
|
||||
const StddevOverTime = 98
|
||||
const StdvarOverTime = 99
|
||||
const QuantileOverTime = 100
|
||||
const FirstOverTime = 101
|
||||
const LastOverTime = 102
|
||||
const AbsentOverTime = 103
|
||||
const LogRangeExpr = 104
|
||||
const Range = 105
|
||||
const OffsetExpr = 106
|
||||
const UnwrapExpr = 107
|
||||
const ConvOp = 108
|
||||
const BytesConv = 109
|
||||
const DurationConv = 110
|
||||
const DurationSecondsConv = 111
|
||||
const Grouping = 112
|
||||
const Labels = 113
|
||||
const VectorAggregationExpr = 114
|
||||
const VectorOp = 115
|
||||
const BinOpExpr = 116
|
||||
const BinOpModifier = 117
|
||||
const OnOrIgnoringModifier = 118
|
||||
const GroupingLabels = 119
|
||||
const GroupingLabelList = 120
|
||||
const GroupingLabel = 121
|
||||
const LabelName = 122
|
||||
const Add = 123
|
||||
const Sub = 124
|
||||
const Mul = 125
|
||||
const Div = 126
|
||||
const Mod = 127
|
||||
const Pow = 128
|
||||
const LiteralExpr = 129
|
||||
const LabelReplaceExpr = 130
|
||||
const VectorExpr = 131
|
||||
|
||||
function getNodeFromQuery (query, nodeType) {
|
||||
const nodes = []
|
||||
const tree = parser.parse(query)
|
||||
tree.iterate({
|
||||
enter: (node) => {
|
||||
if (nodeType === undefined || nodeType === node.type.id) {
|
||||
nodes.push(node.node)
|
||||
}
|
||||
}
|
||||
})
|
||||
return nodes[0]
|
||||
}
|
||||
|
||||
function isLogsQuery (query) {
|
||||
if (getNodeFromQuery(query, MetricExpr$1)) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function indent (level) {
|
||||
return ' '.repeat(level)
|
||||
}
|
||||
|
||||
function indentMultiline (block, level) {
|
||||
const lines = block.split('\n')
|
||||
return lines.map((line) => indent(level) + line).join('\n')
|
||||
}
|
||||
|
||||
function trimMultiline (block) {
|
||||
const lines = block.split('\n')
|
||||
return lines.map((line) => line.trimEnd()).join('\n')
|
||||
}
|
||||
|
||||
function needsBrackets (node, queryType) {
|
||||
const childNodeIsSame = node.firstChild && (node.firstChild.type.id === queryType)
|
||||
let addBrackets = false
|
||||
|
||||
if (node.firstChild && childNodeIsSame) {
|
||||
addBrackets = true
|
||||
node = node.firstChild
|
||||
}
|
||||
|
||||
return { addBrackets, newNode: node }
|
||||
}
|
||||
|
||||
function iterateNode (node, lookingFor) {
|
||||
const nodes = []
|
||||
let child = node.firstChild
|
||||
|
||||
while (child) {
|
||||
if (lookingFor.includes(child.type.id)) {
|
||||
nodes.push(child)
|
||||
}
|
||||
|
||||
nodes.push(...iterateNode(child, lookingFor))
|
||||
child = child.nextSibling
|
||||
}
|
||||
|
||||
return nodes
|
||||
}
|
||||
|
||||
function buildResponse (pipelineType, lastPipelineType, formattedNode) {
|
||||
if (lastPipelineType === pipelineType) {
|
||||
return ` ${formattedNode}`
|
||||
}
|
||||
|
||||
return `\n${indent(1)}${formattedNode}`
|
||||
}
|
||||
|
||||
function trimEnd (input, charactersToTrim) {
|
||||
let endIndex = input.length - 1
|
||||
while (endIndex >= 0 && charactersToTrim.includes(input[endIndex])) {
|
||||
endIndex--
|
||||
}
|
||||
return input.substring(0, endIndex + 1)
|
||||
}
|
||||
|
||||
const formatLogExpr = (node, query) => {
|
||||
const { addBrackets, newNode } = needsBrackets(node, LogExpr)
|
||||
node = newNode
|
||||
|
||||
const tree = parser.parse(query.substring(node.from, node.to))
|
||||
let formatted = ''
|
||||
|
||||
tree.iterate({
|
||||
enter: (ref) => {
|
||||
const node = ref.node
|
||||
|
||||
switch (node.type.id) {
|
||||
case Selector:
|
||||
formatted += formatSelector(node, query)
|
||||
break
|
||||
|
||||
case PipelineExpr:
|
||||
node.parent && (node.parent.type.id !== PipelineExpr && (formatted += formatPipelineExpr(node, query)))
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return addBrackets ? '(' + formatted + ')' : formatted
|
||||
}
|
||||
|
||||
function formatSelector (node, query) {
|
||||
const selector = query.substring(node.from, node.to)
|
||||
const subtree = parser.parse(selector)
|
||||
const labelNodes = []
|
||||
let response = ''
|
||||
|
||||
subtree.iterate({
|
||||
enter: (ref) => {
|
||||
const node = ref.node
|
||||
if (node.type.id === Matcher) {
|
||||
labelNodes.push(node)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
labelNodes.sort((a, b) => {
|
||||
const labelNodeA = a.getChild(Identifier)
|
||||
const labelNodeB = b.getChild(Identifier)
|
||||
|
||||
const labelValueA = labelNodeA && query.substring(labelNodeA.from, labelNodeA.to)
|
||||
const labelValueB = labelNodeB && query.substring(labelNodeB.from, labelNodeB.to)
|
||||
|
||||
if (!labelValueA || !labelValueB) {
|
||||
return 0
|
||||
}
|
||||
|
||||
if (labelValueA < labelValueB) {
|
||||
return -1
|
||||
}
|
||||
|
||||
if (labelValueA > labelValueB) {
|
||||
return 1
|
||||
}
|
||||
|
||||
return 0
|
||||
})
|
||||
|
||||
labelNodes.forEach((node) => {
|
||||
const labelNode = node.getChild(Identifier)
|
||||
const operatorNode = labelNode ? labelNode.nextSibling : null
|
||||
const valueNode = node.getChild(String)
|
||||
|
||||
const label = labelNode ? query.substring(labelNode.from, labelNode.to) : null
|
||||
const operator = operatorNode ? query.substring(operatorNode.from, operatorNode.to) : null
|
||||
const value = valueNode ? query.substring(valueNode.from, valueNode.to) : null
|
||||
|
||||
response += `${label}${operator}${value}, `
|
||||
})
|
||||
|
||||
return '{' + trimEnd(response, ', ') + '}'
|
||||
}
|
||||
|
||||
function formatPipelineExpr (node, query) {
|
||||
const pipelineExprNodes = [
|
||||
LineFilter,
|
||||
LabelParser,
|
||||
LabelFilter,
|
||||
JsonExpressionParser,
|
||||
LineFormatExpr,
|
||||
LabelFormatExpr,
|
||||
DecolorizeExpr
|
||||
]
|
||||
let lastPipelineType
|
||||
let response = ''
|
||||
|
||||
iterateNode(node, pipelineExprNodes).forEach((node) => {
|
||||
switch (node.type.id) {
|
||||
case LineFilter:
|
||||
response += buildResponse(LineFilter, lastPipelineType, formatLineFilter(node, query))
|
||||
lastPipelineType = LineFilter
|
||||
break
|
||||
|
||||
case LabelParser:
|
||||
response += buildResponse(LabelParser, lastPipelineType, formatLabelParser(node, query))
|
||||
lastPipelineType = LabelParser
|
||||
break
|
||||
|
||||
case JsonExpressionParser:
|
||||
response += buildResponse(JsonExpressionParser, lastPipelineType, formatJsonExpressionParser(node, query))
|
||||
lastPipelineType = JsonExpressionParser
|
||||
break
|
||||
|
||||
case LabelFilter:
|
||||
response += buildResponse(LabelFilter, lastPipelineType, formatLabelFilter(node, query))
|
||||
lastPipelineType = LabelFilter
|
||||
break
|
||||
|
||||
case LineFormatExpr:
|
||||
response += buildResponse(LineFormatExpr, lastPipelineType, formatLineFormatExpr(node, query))
|
||||
lastPipelineType = LineFormatExpr
|
||||
break
|
||||
|
||||
case LabelFormatExpr:
|
||||
response += buildResponse(LabelFormatExpr, lastPipelineType, formatLabelFormatExpr(node, query))
|
||||
lastPipelineType = LabelFormatExpr
|
||||
break
|
||||
|
||||
case DecolorizeExpr:
|
||||
response += buildResponse(DecolorizeExpr, lastPipelineType, formatDecolorizeExpr())
|
||||
lastPipelineType = DecolorizeExpr
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
function formatLineFilter (node, query) {
|
||||
const filterNode = node.getChild(Filter)
|
||||
const filterOperationNode = node.getChild(FilterOp)
|
||||
const stringNode = node.getChild(String)
|
||||
|
||||
const filter = filterNode && query.substring(filterNode.from, filterNode.to)
|
||||
const string = stringNode && query.substring(stringNode.from, stringNode.to)
|
||||
|
||||
if (filterOperationNode) {
|
||||
return `${filter} ip(${string})`
|
||||
}
|
||||
return `${filter} ${string}`
|
||||
}
|
||||
|
||||
function formatLabelParser (node, query) {
|
||||
const hasString = node.getChild(String)
|
||||
|
||||
if (hasString) {
|
||||
const parserNode = node.getChild(Regexp) || node.getChild(Pattern)
|
||||
const stringNode = node.getChild(String)
|
||||
|
||||
const parser = parserNode && query.substring(parserNode.from, parserNode.to)
|
||||
const string = stringNode && query.substring(stringNode.from, stringNode.to)
|
||||
|
||||
return `| ${parser}${string}`
|
||||
}
|
||||
|
||||
const labelParser = query.substring(node.from, node.to)
|
||||
return `| ${labelParser}`
|
||||
}
|
||||
|
||||
function formatJsonExpressionParser (node, query) {
|
||||
const jsonExpressionNodes = iterateNode(node, [JsonExpression])
|
||||
let response = ''
|
||||
|
||||
jsonExpressionNodes.forEach((node) => {
|
||||
const identifierNode = node.getChild(Identifier)
|
||||
const valueNode = node.getChild(String)
|
||||
|
||||
const identifier = identifierNode && query.substring(identifierNode.from, identifierNode.to)
|
||||
const value = valueNode && query.substring(valueNode.from, valueNode.to)
|
||||
|
||||
response += `${identifier}=${value}, `
|
||||
})
|
||||
|
||||
return `| json ${trimEnd(response, ', ')}`
|
||||
}
|
||||
|
||||
function formatLabelFilter (node, query) {
|
||||
const selectedFilter =
|
||||
node.getChild(Matcher) ||
|
||||
node.getChild(IpLabelFilter) ||
|
||||
node.getChild(NumberFilter) ||
|
||||
(node.getChild(UnitFilter) && node.getChild(UnitFilter).getChild(DurationFilter)) ||
|
||||
(node.getChild(UnitFilter) && (node.getChild(UnitFilter).getChild(BytesFilter)))
|
||||
|
||||
if (!selectedFilter) {
|
||||
return ''
|
||||
}
|
||||
|
||||
const selectedFilterType = selectedFilter.type.id
|
||||
|
||||
const identifierNode = selectedFilter.getChild(Identifier)
|
||||
const operatorNode = identifierNode && identifierNode.nextSibling
|
||||
let valueNode
|
||||
|
||||
if (selectedFilterType === DurationFilter) {
|
||||
valueNode = selectedFilter.getChild(Duration)
|
||||
} else if (selectedFilterType === BytesFilter) {
|
||||
valueNode = selectedFilter.getChild(Bytes)
|
||||
} else if (selectedFilterType === NumberFilter) {
|
||||
valueNode = selectedFilter.getChild(Number)
|
||||
} else {
|
||||
valueNode = selectedFilter.getChild(String)
|
||||
}
|
||||
|
||||
const identifier = identifierNode && query.substring(identifierNode.from, identifierNode.to)
|
||||
const operator = operatorNode && query.substring(operatorNode.from, operatorNode.to)
|
||||
const value = valueNode && query.substring(valueNode.from, valueNode.to)
|
||||
|
||||
if (selectedFilterType === IpLabelFilter) {
|
||||
return `| ${identifier}${operator}ip(${value})`
|
||||
}
|
||||
|
||||
return `| ${identifier}${operator}${value}`
|
||||
}
|
||||
|
||||
function formatLineFormatExpr (node, query) {
|
||||
const stringNode = node.getChild(String)
|
||||
const string = stringNode && query.substring(stringNode.from, stringNode.to)
|
||||
return `| line_format ${string}`
|
||||
}
|
||||
|
||||
function formatLabelFormatExpr (node, query) {
|
||||
const labelFormatMatcherNodes = iterateNode(node, [LabelFormatMatcher])
|
||||
let response = '| label_format '
|
||||
|
||||
labelFormatMatcherNodes.forEach((labelFormatMatcherNode) => {
|
||||
let identifierNode
|
||||
let valueNode
|
||||
|
||||
if (labelFormatMatcherNode.getChildren(Identifier).length === 2) {
|
||||
[identifierNode, valueNode] = labelFormatMatcherNode.getChildren(Identifier)
|
||||
} else {
|
||||
identifierNode = labelFormatMatcherNode.getChild(Identifier)
|
||||
valueNode = labelFormatMatcherNode.getChild(String)
|
||||
}
|
||||
|
||||
const identifier = identifierNode && query.substring(identifierNode.from, identifierNode.to)
|
||||
const value = valueNode && query.substring(valueNode.from, valueNode.to)
|
||||
|
||||
response += `${identifier}=${value}, `
|
||||
})
|
||||
|
||||
return trimEnd(response, ', ')
|
||||
}
|
||||
|
||||
function formatDecolorizeExpr () {
|
||||
// eslint-disable-next-line quotes
|
||||
return `| decolorize`
|
||||
}
|
||||
|
||||
const formatMetricExpr = (node, query) => {
|
||||
const { addBrackets, newNode } = needsBrackets(node, MetricExpr)
|
||||
node = newNode
|
||||
let formatted = ''
|
||||
|
||||
const childNode = node.firstChild
|
||||
switch (childNode && childNode.type.id) {
|
||||
case RangeAggregationExpr:
|
||||
formatted = formatRangeAggregationExpr(node, query)
|
||||
break
|
||||
|
||||
case VectorAggregationExpr:
|
||||
formatted = formatVectorAggregationExpr(node, query)
|
||||
break
|
||||
|
||||
case BinOpExpr:
|
||||
formatted = formatBinOpExpr(node, query)
|
||||
break
|
||||
|
||||
case LiteralExpr:
|
||||
formatted = formatLiteralExpr(node, query)
|
||||
break
|
||||
|
||||
case LabelReplaceExpr:
|
||||
formatted = formatLabelReplaceExpr(node, query)
|
||||
break
|
||||
|
||||
case VectorExpr:
|
||||
formatted = formatVectorExpr(node, query)
|
||||
break
|
||||
}
|
||||
|
||||
return addBrackets ? '(' + formatted + ')' : formatted
|
||||
}
|
||||
|
||||
function formatRangeAggregationExpr (node, query) {
|
||||
let response = ''
|
||||
|
||||
iterateNode(node, [RangeOp, Number, LogRangeExpr, Grouping]).forEach((node) => {
|
||||
if (node.parent && (node.parent.type.id !== RangeAggregationExpr)) {
|
||||
return
|
||||
}
|
||||
|
||||
switch (node.type.id) {
|
||||
case RangeOp:
|
||||
response += `${query.substring(node.from, node.to)}(\n`
|
||||
break
|
||||
|
||||
case Number:
|
||||
response += `${indent(1) + query.substring(node.from, node.to)},\n`
|
||||
break
|
||||
|
||||
case LogRangeExpr:
|
||||
response += formatLogRangeExpr(node, query)
|
||||
break
|
||||
|
||||
case Grouping:
|
||||
response += formatGrouping(node, query)
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
function formatLogRangeExpr (node, query) {
|
||||
const nodes = []
|
||||
let selector = ''
|
||||
let pipeline = ''
|
||||
let range = ''
|
||||
let offset = ''
|
||||
let unwrap = ''
|
||||
|
||||
iterateNode(node, [Selector, Range, OffsetExpr, UnwrapExpr, PipelineExpr]).forEach((node) => {
|
||||
if (node.parent && (node.parent.type.id !== LogRangeExpr)) {
|
||||
return
|
||||
}
|
||||
|
||||
nodes.push(node)
|
||||
|
||||
switch (node.type.id) {
|
||||
case Selector: {
|
||||
const logExpr = query.substring(node.from, node.to)
|
||||
selector += formatSelector({ ...node, from: 0, to: logExpr.length }, logExpr)
|
||||
break
|
||||
}
|
||||
|
||||
case PipelineExpr:
|
||||
pipeline += formatPipelineExpr(node, query)
|
||||
break
|
||||
|
||||
case Range:
|
||||
range += query.substring(node.from, node.to)
|
||||
break
|
||||
|
||||
case OffsetExpr: {
|
||||
const durationNode = node.getChild(Duration)
|
||||
offset += ` offset ${durationNode ? query.substring(durationNode.from, durationNode.to) : ''}`
|
||||
break
|
||||
}
|
||||
|
||||
case UnwrapExpr:
|
||||
iterateNode(node, [Identifier, ConvOp, LabelFilter]).forEach((node, _, arr) => {
|
||||
switch (node.type.id) {
|
||||
case Identifier: {
|
||||
if (node.parent && (node.parent.type.id !== UnwrapExpr)) {
|
||||
return
|
||||
}
|
||||
|
||||
const hasConvOp = arr.find((node) => node.type.id === ConvOp)
|
||||
|
||||
if (hasConvOp) {
|
||||
return
|
||||
}
|
||||
|
||||
unwrap += `| unwrap ${query.substring(node.from, node.to)} `
|
||||
return
|
||||
}
|
||||
|
||||
case ConvOp: {
|
||||
const identifierNode = arr.find((node) => node.type.id === Identifier)
|
||||
const identifier = identifierNode ? query.substring(identifierNode.from, identifierNode.to) : ''
|
||||
unwrap += `| unwrap ${query.substring(node.from, node.to)}(${identifier}) `
|
||||
return
|
||||
}
|
||||
|
||||
case LabelFilter:
|
||||
unwrap += formatLabelFilter(node, query)
|
||||
}
|
||||
})
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
let response = ''
|
||||
nodes.forEach((node, index, array) => {
|
||||
const previousNode = array[index - 1]
|
||||
|
||||
if (node.type.id === Selector) {
|
||||
response += indent(1) + selector
|
||||
}
|
||||
|
||||
if (node.type.id === PipelineExpr) {
|
||||
response += indentMultiline(pipeline, 1)
|
||||
}
|
||||
|
||||
if (node.type.id === Range) {
|
||||
response += '\n' + indent(1) + range
|
||||
}
|
||||
|
||||
if (node.type.id === OffsetExpr) {
|
||||
response += offset
|
||||
}
|
||||
|
||||
if (node.type.id === UnwrapExpr) {
|
||||
if (previousNode && ((previousNode.type.id !== OffsetExpr)) && (previousNode && (previousNode.type.id !== Range))) {
|
||||
response += '\n' + indent(1) + unwrap
|
||||
} else {
|
||||
response += ' ' + unwrap
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return (response += '\n)')
|
||||
}
|
||||
|
||||
function formatGrouping (node, query) {
|
||||
let response = ''
|
||||
|
||||
const labels = iterateNode(node, [Identifier]).map((node) => {
|
||||
return query.substring(node.from, node.to)
|
||||
})
|
||||
|
||||
iterateNode(node, [By, Without]).forEach((node) => {
|
||||
if (node.parent && (node.parent.type.id !== Grouping)) {
|
||||
return
|
||||
}
|
||||
|
||||
switch (node.type.id) {
|
||||
case By:
|
||||
response = ` by (${labels.join(', ')}) `
|
||||
break
|
||||
|
||||
case Without:
|
||||
response = ` without (${labels.join(', ')}) `
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
function formatVectorAggregationExpr (node, query) {
|
||||
let response = ''
|
||||
|
||||
iterateNode(node, [VectorOp, Number, MetricExpr, Grouping]).forEach((node, _, arr) => {
|
||||
if (node.parent && (node.parent.type.id !== VectorAggregationExpr)) {
|
||||
return
|
||||
}
|
||||
|
||||
switch (node.type.id) {
|
||||
case VectorOp:
|
||||
response += `${query.substring(node.from, node.to)}`
|
||||
break
|
||||
|
||||
case Number:
|
||||
response += '(\n'
|
||||
response += `${indent(1) + query.substring(node.from, node.to)},\n`
|
||||
break
|
||||
|
||||
case MetricExpr: {
|
||||
const hasNumber = arr.find((node) => node.type.id === Number && node.parent.type.id === VectorAggregationExpr)
|
||||
response += hasNumber ? '' : '(\n'
|
||||
|
||||
const metricExpr = query.substring(node.from, node.to)
|
||||
const metricNode = getNodeFromQuery(metricExpr, MetricExpr)
|
||||
response += indentMultiline(formatMetricExpr(metricNode, metricExpr), 1)
|
||||
response += '\n)'
|
||||
break
|
||||
}
|
||||
|
||||
case Grouping:
|
||||
response += formatGrouping(node, query)
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
function formatBinOpExpr (node, query) {
|
||||
let operator
|
||||
|
||||
const [leftExpr, rightExpr] = iterateNode(node, [Expr]).map((node, idx) => {
|
||||
if (idx === 0) {
|
||||
operator = query.substring(node.nextSibling.from || 0, node.nextSibling.to)
|
||||
}
|
||||
|
||||
const expr = query.substring(node.from, node.to)
|
||||
let expressionNode
|
||||
|
||||
if (isLogsQuery(expr)) {
|
||||
expressionNode = getNodeFromQuery(expr, LogExpr$1)
|
||||
return formatLogExpr(expressionNode, expr)
|
||||
} else {
|
||||
expressionNode = getNodeFromQuery(expr, MetricExpr)
|
||||
return formatMetricExpr(expressionNode, expr)
|
||||
}
|
||||
})
|
||||
|
||||
return leftExpr + '\n' + operator + '\n' + rightExpr
|
||||
}
|
||||
|
||||
function formatLiteralExpr (node, query) {
|
||||
node = node.getChild(LiteralExpr) || node
|
||||
const addNode = node.getChild(Add)
|
||||
const subNode = node.getChild(Sub)
|
||||
const numberNode = node.getChild(Number)
|
||||
|
||||
if (!numberNode) {
|
||||
return ''
|
||||
}
|
||||
|
||||
if (addNode) {
|
||||
return `+${query.substring(numberNode.from, numberNode.to)}`
|
||||
}
|
||||
|
||||
if (subNode) {
|
||||
return `-${query.substring(numberNode.from, numberNode.to)}`
|
||||
}
|
||||
|
||||
return query.substring(numberNode.from, numberNode.to)
|
||||
}
|
||||
|
||||
function formatLabelReplaceExpr (node, query) {
|
||||
let response = 'label_replace(\n'
|
||||
|
||||
iterateNode(node, [MetricExpr, String]).forEach((node) => {
|
||||
if (node.parent.type.id !== LabelReplaceExpr) {
|
||||
return
|
||||
}
|
||||
|
||||
if (node.type.id === MetricExpr) {
|
||||
const metricExpr = query.substring(node.from, node.to)
|
||||
const metricNode = getNodeFromQuery(metricExpr, MetricExpr)
|
||||
response += indentMultiline(formatMetricExpr(metricNode, metricExpr), 1) + ',\n'
|
||||
} else {
|
||||
response += indent(1) + query.substring(node.from, node.to) + ',\n'
|
||||
}
|
||||
})
|
||||
|
||||
return trimEnd(response, ',\n') + '\n)'
|
||||
}
|
||||
|
||||
function formatVectorExpr (node, query) {
|
||||
node = node.getChild(VectorExpr) || node
|
||||
const numberNode = node.getChild(Number)
|
||||
|
||||
if (!numberNode) {
|
||||
return ''
|
||||
}
|
||||
|
||||
return `vector(${query.substring(numberNode.from, numberNode.to)})`
|
||||
}
|
||||
|
||||
/**
|
||||
* @experimental This feature is subject to change or removal in future versions.
|
||||
*/
|
||||
const formatLokiQuery = (query) => {
|
||||
const tree = parser.parse(query)
|
||||
let formatted = ''
|
||||
|
||||
tree.iterate({
|
||||
enter: (ref) => {
|
||||
const node = ref.node
|
||||
|
||||
if (lodash.get(node, 'parent.type.id', '') !== Expr || lodash.get(node,'parent.parent.type.id', '') === BinOpExpr) {
|
||||
return
|
||||
}
|
||||
|
||||
switch (node.type.id) {
|
||||
case MetricExpr:
|
||||
formatted = formatMetricExpr(node, query)
|
||||
return false
|
||||
|
||||
case LogExpr:
|
||||
formatted = formatLogExpr(node, query)
|
||||
return false
|
||||
}
|
||||
}
|
||||
})
|
||||
return trimMultiline(formatted)
|
||||
}
|
||||
|
||||
export { AbsentOverTime, Add, And, Avg, AvgOverTime, BinOpExpr, BinOpModifier, Bool, Bottomk, By, Bytes, BytesConv, BytesFilter, BytesOverTime, BytesRate, ConvOp, Count, CountOverTime, Decolorize, DecolorizeExpr, Div, Drop, DropLabel, DropLabels, DropLabelsExpr, Duration, DurationConv, DurationFilter, DurationSecondsConv, Eq, Eql, Expr, Filter, FilterOp, FirstOverTime, GroupLeft, GroupRight, Grouping, GroupingLabel, GroupingLabelList, GroupingLabels, Gte, Gtr, Identifier, Ignoring, Ip, IpLabelFilter, Json, JsonExpression, JsonExpressionList, JsonExpressionParser, Keep, KeepLabel, KeepLabels, KeepLabelsExpr, LabelFilter, LabelFormat, LabelFormatExpr, LabelFormatMatcher, LabelName, LabelParser, LabelReplace, LabelReplaceExpr, Labels, LabelsFormat, LastOverTime, LineComment, LineFilter, LineFilters, LineFormat, LineFormatExpr, LiteralExpr, LogExpr, LogQL, LogRangeExpr, Logfmt, Lss, Lte, Matcher, Matchers, Max, MaxOverTime, MetricExpr, Min, MinOverTime, Mod, Mul, Neq, Nre, Number, NumberFilter, Offset, OffsetExpr, On, OnOrIgnoringModifier, Or, Pattern, Pipe, PipeExact, PipeMatch, PipelineExpr, PipelineStage, Pow, QuantileOverTime, Range, RangeAggregationExpr, RangeOp, Rate, RateCounter, Re, Regexp, Selector, Stddev, StddevOverTime, Stdvar, StdvarOverTime, String, Sub, Sum, SumOverTime, Topk, UnitFilter, Unless, Unpack, Unwrap, UnwrapExpr, Vector, VectorAggregationExpr, VectorExpr, VectorOp, Without, formatLokiQuery, parser }
|
||||
@@ -0,0 +1,388 @@
|
||||
<template>
|
||||
<MonacoEditor
|
||||
v-model="code"
|
||||
theme="nz"
|
||||
ref="monacoEditor"
|
||||
style="width: 100%;height: auto;min-height: 40px;border: 1px solid #dedede"
|
||||
language="logql"
|
||||
:options="MONACO_EDITOR_OPTIONS"
|
||||
@editorWillMount="handelBeforeMount"
|
||||
@editorDidMount="handleMount"
|
||||
@change="handleChange"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { languageConfiguration, monarchlanguage } from './monacoConfig'
|
||||
import { parser, formatLokiQuery } from './lezerConfig'
|
||||
import { validateQuery, placeHolderScopedVars } from './validation.ts'
|
||||
import { getSituation } from './situation'
|
||||
// import { sceneGraph } from '@grafana/scenes'
|
||||
import MonacoEditor from 'vue-monaco'
|
||||
export default {
|
||||
name: 'logql',
|
||||
props: {
|
||||
code: String
|
||||
},
|
||||
// model: {
|
||||
// prop: 'code',
|
||||
// event: 'change'
|
||||
// },
|
||||
components: {
|
||||
MonacoEditor
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
code: '',
|
||||
LANGUAGE_SETUP_STARTED: false,
|
||||
parser,
|
||||
MONACO_EDITOR_OPTIONS: {
|
||||
automaticLayout: false,
|
||||
formatOnType: true,
|
||||
formatOnPaste: true,
|
||||
codeLens: false,
|
||||
contextmenu: false,
|
||||
// we need `fixedOverflowWidgets` because otherwise in grafana-dashboards
|
||||
// the popup is clipped by the panel-visualizations.
|
||||
fixedOverflowWidgets: true,
|
||||
folding: false,
|
||||
fontSize: 14,
|
||||
lineDecorationsWidth: 8, // used as "padding-left"
|
||||
lineNumbers: 'off',
|
||||
minimap: { enabled: true },
|
||||
overviewRulerBorder: false,
|
||||
overviewRulerLanes: 0,
|
||||
padding: {
|
||||
// these numbers were picked so that visually this matches the previous version
|
||||
// of the query-editor the best
|
||||
top: 4,
|
||||
bottom: 5
|
||||
},
|
||||
renderLineHighlight: 'none',
|
||||
scrollbar: {
|
||||
// vertical: 'hidden',
|
||||
verticalScrollbarSize: 8, // used as "padding-right"
|
||||
horizontal: 'hidden',
|
||||
horizontalScrollbarSize: 0
|
||||
},
|
||||
scrollBeyondLastLine: false,
|
||||
suggest: {
|
||||
showWords: true,
|
||||
/**
|
||||
* Enable custom contextmenu.
|
||||
* Defaults to false.
|
||||
*/
|
||||
contextmenu: true,
|
||||
/**
|
||||
* The number of spaces a tab is equal to.
|
||||
* This setting is overridden based on the file contents when `detectIndentation` is on.
|
||||
* Defaults to 4.
|
||||
*/
|
||||
tabSize: 4,
|
||||
/**
|
||||
* Show code lens
|
||||
* Defaults to false.
|
||||
*/
|
||||
codeLens: true,
|
||||
/**
|
||||
* Control the width of line numbers, by reserving horizontal space for rendering at least an amount of digits.
|
||||
* Defaults to 4.
|
||||
*/
|
||||
lineNumbersMinChars: 4,
|
||||
/**
|
||||
* The width reserved for line decorations (in px).
|
||||
* Line decorations are placed between line numbers and the editor content.
|
||||
* You can pass in a string in the format floating point followed by "ch". e.g. 1.3ch.
|
||||
* Defaults to 1 * theme.spacing.gridSize.
|
||||
*/
|
||||
// lineDecorationsWidth?: number | string;
|
||||
/**
|
||||
* Controls if a border should be drawn around the overview ruler.
|
||||
* Defaults to `false`.
|
||||
*/
|
||||
overviewRulerBorder: false,
|
||||
/**
|
||||
* Enable that the editor will install an interval to check if its container dom node size has changed.
|
||||
* Enabling this might have a severe performance impact.
|
||||
* Defaults to true.
|
||||
*/
|
||||
automaticLayout: true
|
||||
},
|
||||
suggestFontSize: 12,
|
||||
wordWrap: 'on',
|
||||
placeHolderScopedVars: {
|
||||
__interval: { text: '1s', value: '1s' },
|
||||
__auto: { text: '1s', value: '1s' },
|
||||
__interval_ms: { text: '1000', value: 1000 },
|
||||
__range_ms: { text: '1000', value: 1000 },
|
||||
__range_s: { text: '1', value: 1 },
|
||||
__range: { text: '1s', value: '1s' }
|
||||
}
|
||||
},
|
||||
templateSrv: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleChange (value, event) {
|
||||
|
||||
},
|
||||
handleMount (editor) {
|
||||
// // const monaco = this.$refs.monaco
|
||||
// console.log(this.$refs.monacoEditor, this.$refs.monacoEditor.monaco)
|
||||
// console.log(editor)
|
||||
const LANG_ID = 'logql'
|
||||
const monaco = this.$refs.monacoEditor.monaco
|
||||
const self = this
|
||||
// self.setPlaceholder(monaco, editor)
|
||||
// editor.onDidChangeModelContent((e) => {
|
||||
// const model = editor.getModel()
|
||||
// if (!model) {
|
||||
// return
|
||||
// }
|
||||
// const query = model.getValue()
|
||||
// const errors =
|
||||
// validateQuery(
|
||||
// query,
|
||||
// self.interpolateString(query, placeHolderScopedVars),
|
||||
// model.getLinesContent()
|
||||
// ) || []
|
||||
// const markers = errors.map(({ error, ...boundary }) => ({
|
||||
// message: `${
|
||||
// error ? `Error parsing "${error}"` : 'Parse error'
|
||||
// }. The query appears to be incorrect and could fail to be executed.`,
|
||||
// severity: monaco.MarkerSeverity.Error,
|
||||
// ...boundary
|
||||
// }))
|
||||
// console.log(errors)
|
||||
// // onTypeDebounced(query)
|
||||
// monaco.editor.setModelMarkers(model, 'owner', markers)
|
||||
// })
|
||||
},
|
||||
handelBeforeMount (monaco) {
|
||||
const LANG_ID = 'logql'
|
||||
const self = this
|
||||
if (this.LANGUAGE_SETUP_STARTED === false) {
|
||||
this.LANGUAGE_SETUP_STARTED = true
|
||||
// console.log(monaco)
|
||||
monaco.languages.register({ id: LANG_ID })
|
||||
monaco.languages.setLanguageConfiguration(LANG_ID, languageConfiguration)
|
||||
monaco.languages.setMonarchTokensProvider(LANG_ID, monarchlanguage)
|
||||
monaco.editor.defineTheme('nz', {
|
||||
base: 'vs',
|
||||
inherit: true,
|
||||
colors: {
|
||||
'editor.background': '#ffffff',
|
||||
'minimap.background': '#f9f9f9'
|
||||
},
|
||||
// fallback syntax highlighting for languages that microsoft doesn't handle (ex cloudwatch's metric math)
|
||||
rules: [
|
||||
{ token: 'predefined', foreground: '#FF6600' },
|
||||
{ token: 'operator', foreground: '#009966' },
|
||||
{ token: 'tag', foreground: '#006699' }
|
||||
]
|
||||
})
|
||||
monaco.languages.registerCompletionItemProvider('logql', {
|
||||
provideCompletionItems: (model, position) => {
|
||||
const suggestions = [
|
||||
...monarchlanguage.keywords.map(k => {
|
||||
// console.log(k)
|
||||
return {
|
||||
label: k,
|
||||
kind: monaco.languages.CompletionItemKind.Keyword,
|
||||
insertText: k
|
||||
}
|
||||
})
|
||||
]
|
||||
return { suggestions: suggestions }
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
nzSuggest (model, position) {
|
||||
// console.log(model, position)
|
||||
const suggestions = []
|
||||
// console.log(parser.parse(this.code))
|
||||
return suggestions
|
||||
},
|
||||
suggest (model, position) {
|
||||
const monaco = this.$refs.monacoEditor.monaco
|
||||
const self = this
|
||||
const word = model.getWordAtPosition(position)
|
||||
const INSERT_AS_SNIPPET_ENUM_VALUE = 4
|
||||
console.log(monaco.Range.fromPositions(position))
|
||||
const range = monaco.Range.fromPositions(position)
|
||||
// documentation says `position` will be "adjusted" in `getOffsetAt`
|
||||
// i don't know what that means, to be sure i clone it
|
||||
const positionClone = {
|
||||
column: position.column,
|
||||
lineNumber: position.lineNumber
|
||||
}
|
||||
const offset = model.getOffsetAt(positionClone)
|
||||
console.log(offset)
|
||||
const situation = getSituation(model.getValue(), offset)
|
||||
console.log(situation)
|
||||
const completionsPromise = situation != null ? Promise.resolve([]) : Promise.resolve([])
|
||||
return completionsPromise.then((items) => {
|
||||
// monaco by default alphabetically orders the items.
|
||||
// to stop it, we use a number-as-string sortkey,
|
||||
// so that monaco keeps the order we use
|
||||
const maxIndexDigits = items.length.toString().length
|
||||
const suggestions = items.map((item, index) => ({
|
||||
kind: self.getMonacoCompletionItemKind(item.type, monaco),
|
||||
label: item.label,
|
||||
insertText: item.insertText,
|
||||
insertTextRules: item.isSnippet ? INSERT_AS_SNIPPET_ENUM_VALUE : undefined,
|
||||
detail: item.detail,
|
||||
documentation: item.documentation,
|
||||
sortText: index.toString().padStart(maxIndexDigits, '0'), // to force the order we have
|
||||
range,
|
||||
command: item.triggerOnInsert
|
||||
? {
|
||||
id: 'editor.action.triggerSuggest',
|
||||
title: ''
|
||||
}
|
||||
: undefined
|
||||
}))
|
||||
return { suggestions }
|
||||
})
|
||||
},
|
||||
getMonacoCompletionItemKind (type, monaco) {
|
||||
switch (type) {
|
||||
case 'DURATION':
|
||||
return monaco.languages.CompletionItemKind.Unit
|
||||
case 'FUNCTION':
|
||||
return monaco.languages.CompletionItemKind.Variable
|
||||
case 'HISTORY':
|
||||
return monaco.languages.CompletionItemKind.Snippet
|
||||
case 'LABEL_NAME':
|
||||
return monaco.languages.CompletionItemKind.Enum
|
||||
case 'LABEL_VALUE':
|
||||
return monaco.languages.CompletionItemKind.EnumMember
|
||||
case 'PATTERN':
|
||||
return monaco.languages.CompletionItemKind.Constructor
|
||||
case 'PARSER':
|
||||
return monaco.languages.CompletionItemKind.Class
|
||||
case 'LINE_FILTER':
|
||||
return monaco.languages.CompletionItemKind.TypeParameter
|
||||
case 'PIPE_OPERATION':
|
||||
return monaco.languages.CompletionItemKind.Interface
|
||||
default:
|
||||
return `Unexpected case in switch statement: ${JSON.stringify(type)}`
|
||||
}
|
||||
},
|
||||
interpolateString (string, scopedVars) {
|
||||
return this.interpolate(string, scopedVars, this.interpolateQueryExpr)
|
||||
},
|
||||
interpolateQueryExpr (value, variable) {
|
||||
// if no multi or include all do not regexEscape
|
||||
if (!variable.multi && !variable.includeAll) {
|
||||
return this.lokiRegularEscape(value)
|
||||
}
|
||||
|
||||
if (typeof value === 'string') {
|
||||
return this.lokiSpecialRegexEscape(value)
|
||||
}
|
||||
|
||||
const escapedValues = this.$lodash.map(value, this.lokiSpecialRegexEscape)
|
||||
return escapedValues.join('|')
|
||||
},
|
||||
lokiRegularEscape (value) {
|
||||
if (typeof value === 'string') {
|
||||
return value.replace(/'/g, "\\\\'")
|
||||
}
|
||||
return value
|
||||
},
|
||||
lokiSpecialRegexEscape (value) {
|
||||
if (typeof value === 'string') {
|
||||
return this.lokiRegularEscape(value.replace(/\\/g, '\\\\\\\\').replace(/[$^*{}\[\]+?.()|]/g, '\\\\$&'))
|
||||
}
|
||||
return value
|
||||
},
|
||||
setPlaceholder (monaco, editor) {
|
||||
const placeholderDecorators = [
|
||||
{
|
||||
range: new monaco.Range(1, 1, 1, 1),
|
||||
options: {
|
||||
className: 'nz-eqweqwe',
|
||||
isWholeLine: true
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
let decorators = []
|
||||
|
||||
const checkDecorators = () => {
|
||||
const model = editor.getModel()
|
||||
|
||||
if (!model) {
|
||||
return
|
||||
}
|
||||
|
||||
const newDecorators = model.getValueLength() === 0 ? placeholderDecorators : []
|
||||
decorators = model.deltaDecorations(decorators, newDecorators)
|
||||
}
|
||||
|
||||
checkDecorators()
|
||||
editor.onDidChangeModelContent(checkDecorators)
|
||||
},
|
||||
interpolate (target, scopedVars, format, interpolations) {
|
||||
if (scopedVars && scopedVars.__sceneObject) {
|
||||
return sceneGraph.interpolate(
|
||||
scopedVars.__sceneObject.value,
|
||||
target,
|
||||
scopedVars,
|
||||
format
|
||||
)
|
||||
}
|
||||
|
||||
if (!target) {
|
||||
return target || ''
|
||||
}
|
||||
|
||||
this.regex.lastIndex = 0
|
||||
|
||||
return this._replaceWithVariableRegex(target, format, (match, variableName, fieldPath, fmt) => {
|
||||
const value = this._evaluateVariableExpression(match, variableName, fieldPath, fmt, scopedVars)
|
||||
|
||||
// If we get passed this interpolations map we will also record all the expressions that were replaced
|
||||
if (interpolations) {
|
||||
interpolations.push({ match, variableName, fieldPath, format: fmt, value, found: value !== match })
|
||||
}
|
||||
|
||||
return value
|
||||
})
|
||||
},
|
||||
sceneInterpolator (sceneObject, target, scopedVars, format) {
|
||||
const VARIABLE_REGEX = /\$(\w+)|\[\[(\w+?)(?::(\w+))?\]\]|\${(\w+)(?:\.([^:^\}]+))?(?::([^\}]+))?}/g
|
||||
if (!target) {
|
||||
return target != null ? target : ''
|
||||
}
|
||||
VARIABLE_REGEX.lastIndex = 0
|
||||
return target.replace(VARIABLE_REGEX, (match, var1, var2, fmt2, var3, fieldPath, fmt3) => {
|
||||
const variableName = var1 || var2 || var3
|
||||
const fmt = fmt2 || fmt3 || format
|
||||
const variable = this.lookupFormatVariable(variableName, match, scopedVars, sceneObject)
|
||||
if (!variable) {
|
||||
return match
|
||||
}
|
||||
return this.formatValue(variable, variable.getValue(fieldPath), fmt)
|
||||
})
|
||||
},
|
||||
formatValue (variable, value, formatNameOrFn) {
|
||||
if (value === null || value === 0) {
|
||||
return ''
|
||||
} else {
|
||||
return value
|
||||
}
|
||||
},
|
||||
lookupFormatVariable (name, match, scopedVars, sceneObject) {
|
||||
console.log(name, match, scopedVars, sceneObject)
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,340 @@
|
||||
import { languageConfiguration, monarchlanguage } from './monacoConfig'
|
||||
import { parser, formatLokiQuery } from './lezerConfig'
|
||||
import { getSituation } from './situation'
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
code: '',
|
||||
LANGUAGE_SETUP_STARTED: false,
|
||||
parser,
|
||||
MONACO_EDITOR_OPTIONS: {
|
||||
automaticLayout: true,
|
||||
formatOnType: true,
|
||||
formatOnPaste: true,
|
||||
codeLens: false,
|
||||
contextmenu: false,
|
||||
// we need `fixedOverflowWidgets` because otherwise in grafana-dashboards
|
||||
// the popup is clipped by the panel-visualizations.
|
||||
fixedOverflowWidgets: true,
|
||||
folding: false,
|
||||
fontSize: 14,
|
||||
lineDecorationsWidth: 8, // used as "padding-left"
|
||||
lineNumbers: 'off',
|
||||
minimap: { enabled: false },
|
||||
overviewRulerBorder: false,
|
||||
overviewRulerLanes: 0,
|
||||
padding: {
|
||||
// these numbers were picked so that visually this matches the previous version
|
||||
// of the query-editor the best
|
||||
top: 10,
|
||||
bottom: 5
|
||||
},
|
||||
renderLineHighlight: 'none',
|
||||
scrollbar: {
|
||||
// vertical: 'hidden',
|
||||
verticalScrollbarSize: 8, // used as "padding-right"
|
||||
horizontal: 'hidden',
|
||||
horizontalScrollbarSize: 0
|
||||
},
|
||||
scrollBeyondLastLine: false,
|
||||
suggest: {
|
||||
showWords: true,
|
||||
/**
|
||||
* Enable custom contextmenu.
|
||||
* Defaults to false.
|
||||
*/
|
||||
contextmenu: true,
|
||||
/**
|
||||
* The number of spaces a tab is equal to.
|
||||
* This setting is overridden based on the file contents when `detectIndentation` is on.
|
||||
* Defaults to 4.
|
||||
*/
|
||||
tabSize: 4,
|
||||
/**
|
||||
* Show code lens
|
||||
* Defaults to false.
|
||||
*/
|
||||
codeLens: true,
|
||||
/**
|
||||
* Control the width of line numbers, by reserving horizontal space for rendering at least an amount of digits.
|
||||
* Defaults to 4.
|
||||
*/
|
||||
lineNumbersMinChars: 4,
|
||||
/**
|
||||
* The width reserved for line decorations (in px).
|
||||
* Line decorations are placed between line numbers and the editor content.
|
||||
* You can pass in a string in the format floating point followed by "ch". e.g. 1.3ch.
|
||||
* Defaults to 1 * theme.spacing.gridSize.
|
||||
*/
|
||||
// lineDecorationsWidth?: number | string;
|
||||
/**
|
||||
* Controls if a border should be drawn around the overview ruler.
|
||||
* Defaults to `false`.
|
||||
*/
|
||||
overviewRulerBorder: false,
|
||||
/**
|
||||
* Enable that the editor will install an interval to check if its container dom node size has changed.
|
||||
* Enabling this might have a severe performance impact.
|
||||
* Defaults to true.
|
||||
*/
|
||||
automaticLayout: true
|
||||
},
|
||||
suggestFontSize: 12,
|
||||
wordWrap: 'on',
|
||||
placeHolderScopedVars: {
|
||||
__interval: { text: '1s', value: '1s' },
|
||||
__auto: { text: '1s', value: '1s' },
|
||||
__interval_ms: { text: '1000', value: 1000 },
|
||||
__range_ms: { text: '1000', value: 1000 },
|
||||
__range_s: { text: '1', value: 1 },
|
||||
__range: { text: '1s', value: '1s' }
|
||||
},
|
||||
},
|
||||
monacoEditorHeight: 30,
|
||||
templateSrv: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleChange (value, event) {
|
||||
this.heightChange()
|
||||
},
|
||||
heightChange () {
|
||||
const dom = this.$refs.monacoEditor.$el
|
||||
const el = dom.getElementsByClassName('view-line')
|
||||
const height = 11 + el.length * 19
|
||||
if (this.monacoEditorHeight !== height) {
|
||||
this.monacoEditorHeight = height
|
||||
}
|
||||
},
|
||||
handleMount (editor) {
|
||||
// const dom = this.$refs.monacoEditor.$el
|
||||
// const el = dom.getElementsByClassName('view-lines')
|
||||
// if (el && el[0]) {
|
||||
// el[0].addEventListener('DOMNodeInserted', this.heightChange)
|
||||
// }
|
||||
},
|
||||
handelBeforeMount (monaco) {
|
||||
const LANG_ID = 'logql'
|
||||
const self = this
|
||||
if (!window.LANGUAGE_SETUP_STARTED) {
|
||||
window.LANGUAGE_SETUP_STARTED = true
|
||||
// console.log(monaco)
|
||||
monaco.languages.register({ id: LANG_ID })
|
||||
monaco.languages.setLanguageConfiguration(LANG_ID, languageConfiguration)
|
||||
monaco.languages.setMonarchTokensProvider(LANG_ID, monarchlanguage)
|
||||
monaco.editor.defineTheme('nz', {
|
||||
base: 'vs',
|
||||
inherit: true,
|
||||
colors: {
|
||||
'editor.background': '#ffffff',
|
||||
'minimap.background': '#f9f9f9'
|
||||
},
|
||||
// fallback syntax highlighting for languages that microsoft doesn't handle (ex cloudwatch's metric math)
|
||||
rules: [
|
||||
{ token: 'predefined', foreground: '#FF6600' },
|
||||
{ token: 'operator', foreground: '#009966' },
|
||||
{ token: 'tag', foreground: '#006699' }
|
||||
]
|
||||
})
|
||||
monaco.languages.registerCompletionItemProvider('logql', {
|
||||
provideCompletionItems: (model, position) => {
|
||||
const suggestions = [
|
||||
...monarchlanguage.keywords.map(k => {
|
||||
// console.log(k)
|
||||
return {
|
||||
label: k,
|
||||
kind: monaco.languages.CompletionItemKind.Keyword,
|
||||
insertText: k
|
||||
}
|
||||
})
|
||||
]
|
||||
return { suggestions: suggestions }
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
nzSuggest (model, position) {
|
||||
// console.log(model, position)
|
||||
const suggestions = []
|
||||
// console.log(parser.parse(this.code))
|
||||
return suggestions
|
||||
},
|
||||
suggest (model, position) {
|
||||
const monaco = this.$refs.monacoEditor.monaco
|
||||
const self = this
|
||||
const word = model.getWordAtPosition(position)
|
||||
const INSERT_AS_SNIPPET_ENUM_VALUE = 4
|
||||
console.log(monaco.Range.fromPositions(position))
|
||||
const range = monaco.Range.fromPositions(position)
|
||||
// documentation says `position` will be "adjusted" in `getOffsetAt`
|
||||
// i don't know what that means, to be sure i clone it
|
||||
const positionClone = {
|
||||
column: position.column,
|
||||
lineNumber: position.lineNumber
|
||||
}
|
||||
const offset = model.getOffsetAt(positionClone)
|
||||
console.log(offset)
|
||||
const situation = getSituation(model.getValue(), offset)
|
||||
console.log(situation)
|
||||
const completionsPromise = situation != null ? Promise.resolve([]) : Promise.resolve([])
|
||||
return completionsPromise.then((items) => {
|
||||
// monaco by default alphabetically orders the items.
|
||||
// to stop it, we use a number-as-string sortkey,
|
||||
// so that monaco keeps the order we use
|
||||
const maxIndexDigits = items.length.toString().length
|
||||
const suggestions = items.map((item, index) => ({
|
||||
kind: self.getMonacoCompletionItemKind(item.type, monaco),
|
||||
label: item.label,
|
||||
insertText: item.insertText,
|
||||
insertTextRules: item.isSnippet ? INSERT_AS_SNIPPET_ENUM_VALUE : undefined,
|
||||
detail: item.detail,
|
||||
documentation: item.documentation,
|
||||
sortText: index.toString().padStart(maxIndexDigits, '0'), // to force the order we have
|
||||
range,
|
||||
command: item.triggerOnInsert
|
||||
? {
|
||||
id: 'editor.action.triggerSuggest',
|
||||
title: ''
|
||||
}
|
||||
: undefined
|
||||
}))
|
||||
return { suggestions }
|
||||
})
|
||||
},
|
||||
getMonacoCompletionItemKind (type, monaco) {
|
||||
switch (type) {
|
||||
case 'DURATION':
|
||||
return monaco.languages.CompletionItemKind.Unit
|
||||
case 'FUNCTION':
|
||||
return monaco.languages.CompletionItemKind.Variable
|
||||
case 'HISTORY':
|
||||
return monaco.languages.CompletionItemKind.Snippet
|
||||
case 'LABEL_NAME':
|
||||
return monaco.languages.CompletionItemKind.Enum
|
||||
case 'LABEL_VALUE':
|
||||
return monaco.languages.CompletionItemKind.EnumMember
|
||||
case 'PATTERN':
|
||||
return monaco.languages.CompletionItemKind.Constructor
|
||||
case 'PARSER':
|
||||
return monaco.languages.CompletionItemKind.Class
|
||||
case 'LINE_FILTER':
|
||||
return monaco.languages.CompletionItemKind.TypeParameter
|
||||
case 'PIPE_OPERATION':
|
||||
return monaco.languages.CompletionItemKind.Interface
|
||||
default:
|
||||
return `Unexpected case in switch statement: ${JSON.stringify(type)}`
|
||||
}
|
||||
},
|
||||
interpolateString (string, scopedVars) {
|
||||
return this.interpolate(string, scopedVars, this.interpolateQueryExpr)
|
||||
},
|
||||
interpolateQueryExpr (value, variable) {
|
||||
// if no multi or include all do not regexEscape
|
||||
if (!variable.multi && !variable.includeAll) {
|
||||
return this.lokiRegularEscape(value)
|
||||
}
|
||||
|
||||
if (typeof value === 'string') {
|
||||
return this.lokiSpecialRegexEscape(value)
|
||||
}
|
||||
|
||||
const escapedValues = this.$lodash.map(value, this.lokiSpecialRegexEscape)
|
||||
return escapedValues.join('|')
|
||||
},
|
||||
lokiRegularEscape (value) {
|
||||
if (typeof value === 'string') {
|
||||
return value.replace(/'/g, "\\\\'")
|
||||
}
|
||||
return value
|
||||
},
|
||||
lokiSpecialRegexEscape (value) {
|
||||
if (typeof value === 'string') {
|
||||
return this.lokiRegularEscape(value.replace(/\\/g, '\\\\\\\\').replace(/[$^*{}\[\]+?.()|]/g, '\\\\$&'))
|
||||
}
|
||||
return value
|
||||
},
|
||||
setPlaceholder (monaco, editor) {
|
||||
const placeholderDecorators = [
|
||||
{
|
||||
range: new monaco.Range(1, 1, 1, 1),
|
||||
options: {
|
||||
className: 'nz-eqweqwe',
|
||||
isWholeLine: true
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
let decorators = []
|
||||
|
||||
const checkDecorators = () => {
|
||||
const model = editor.getModel()
|
||||
|
||||
if (!model) {
|
||||
return
|
||||
}
|
||||
|
||||
const newDecorators = model.getValueLength() === 0 ? placeholderDecorators : []
|
||||
decorators = model.deltaDecorations(decorators, newDecorators)
|
||||
}
|
||||
|
||||
checkDecorators()
|
||||
editor.onDidChangeModelContent(checkDecorators)
|
||||
},
|
||||
interpolate (target, scopedVars, format, interpolations) {
|
||||
if (scopedVars && scopedVars.__sceneObject) {
|
||||
return sceneGraph.interpolate(
|
||||
scopedVars.__sceneObject.value,
|
||||
target,
|
||||
scopedVars,
|
||||
format
|
||||
)
|
||||
}
|
||||
|
||||
if (!target) {
|
||||
return target || ''
|
||||
}
|
||||
|
||||
this.regex.lastIndex = 0
|
||||
|
||||
return this._replaceWithVariableRegex(target, format, (match, variableName, fieldPath, fmt) => {
|
||||
const value = this._evaluateVariableExpression(match, variableName, fieldPath, fmt, scopedVars)
|
||||
|
||||
// If we get passed this interpolations map we will also record all the expressions that were replaced
|
||||
if (interpolations) {
|
||||
interpolations.push({ match, variableName, fieldPath, format: fmt, value, found: value !== match })
|
||||
}
|
||||
|
||||
return value
|
||||
})
|
||||
},
|
||||
sceneInterpolator (sceneObject, target, scopedVars, format) {
|
||||
const VARIABLE_REGEX = /\$(\w+)|\[\[(\w+?)(?::(\w+))?\]\]|\${(\w+)(?:\.([^:^\}]+))?(?::([^\}]+))?}/g
|
||||
if (!target) {
|
||||
return target != null ? target : ''
|
||||
}
|
||||
VARIABLE_REGEX.lastIndex = 0
|
||||
return target.replace(VARIABLE_REGEX, (match, var1, var2, fmt2, var3, fieldPath, fmt3) => {
|
||||
const variableName = var1 || var2 || var3
|
||||
const fmt = fmt2 || fmt3 || format
|
||||
const variable = this.lookupFormatVariable(variableName, match, scopedVars, sceneObject)
|
||||
if (!variable) {
|
||||
return match
|
||||
}
|
||||
return this.formatValue(variable, variable.getValue(fieldPath), fmt)
|
||||
})
|
||||
},
|
||||
formatValue (variable, value, formatNameOrFn) {
|
||||
if (value === null || value === 0) {
|
||||
return ''
|
||||
} else {
|
||||
return value
|
||||
}
|
||||
},
|
||||
lookupFormatVariable (name, match, scopedVars, sceneObject) {
|
||||
console.log(name, match, scopedVars, sceneObject)
|
||||
return null
|
||||
}
|
||||
},
|
||||
beforeDestroy () {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
'use strict'
|
||||
Object.defineProperty(exports, '__esModule', { value: true })
|
||||
exports.monarchlanguage = exports.languageConfiguration = 0
|
||||
exports.languageConfiguration = {
|
||||
// the default separators except `@$`
|
||||
wordPattern: /(-?\d*\.\d\w*)|([^`~!#%^&*()\-=+\[{\]}\\|;:'",.<>\/?\s]+)/g,
|
||||
comments: {
|
||||
lineComment: '#'
|
||||
},
|
||||
brackets: [
|
||||
['{', '}'],
|
||||
['[', ']'],
|
||||
['(', ')']
|
||||
],
|
||||
autoClosingPairs: [
|
||||
{ open: '{', close: '}' },
|
||||
{ open: '[', close: ']' },
|
||||
{ open: '(', close: ')' },
|
||||
{ open: '"', close: '"' },
|
||||
{ open: "'", close: "'" },
|
||||
{ open: '`', close: '`' }
|
||||
],
|
||||
surroundingPairs: [
|
||||
{ open: '{', close: '}' },
|
||||
{ open: '[', close: ']' },
|
||||
{ open: '(', close: ')' },
|
||||
{ open: '"', close: '"' },
|
||||
{ open: "'", close: "'" },
|
||||
{ open: '`', close: '`' },
|
||||
{ open: '<', close: '>' }
|
||||
],
|
||||
folding: {}
|
||||
}
|
||||
// LogQL built-in aggregation operators
|
||||
// https://grafana.com/docs/loki/latest/logql/metric_queries/#built-in-aggregation-operators
|
||||
const aggregations = [
|
||||
'sum',
|
||||
'avg',
|
||||
'min',
|
||||
'max',
|
||||
'stddev',
|
||||
'stdvar',
|
||||
'count',
|
||||
'topk',
|
||||
'bottomk'
|
||||
]
|
||||
// LogQL parser expressions
|
||||
// https://grafana.com/docs/loki/latest/logql/log_queries/#parser-expression
|
||||
const parsers = ['json', 'logfmt', 'regexp', 'unpack', 'pattern']
|
||||
// LogQL format expressions
|
||||
// https://grafana.com/docs/loki/latest/logql/log_queries/#parser-expression
|
||||
// eslint-disable-next-line camelcase
|
||||
const format_expressions = ['line_format', 'label_format']
|
||||
// LogQL vector aggregations
|
||||
// https://grafana.com/docs/loki/latest/logql/metric_queries/#range-vector-aggregation
|
||||
// eslint-disable-next-line camelcase
|
||||
const vector_aggregations = [
|
||||
'count_over_time',
|
||||
'rate',
|
||||
'bytes_over_time',
|
||||
'bytes_rate',
|
||||
'avg_over_time',
|
||||
'sum_over_time',
|
||||
'min_over_time',
|
||||
'max_over_time',
|
||||
'stdvar_over_time',
|
||||
'stddev_over_time',
|
||||
'quantile_over_time',
|
||||
'first_over_time',
|
||||
'last_over_time',
|
||||
'absent_over_time'
|
||||
]
|
||||
// LogQL by and without clauses
|
||||
// eslint-disable-next-line camelcase
|
||||
const vector_matching = ['by', 'without']
|
||||
// Produce a regex matching elements : (by|without)
|
||||
const vectorMatchingRegex = '('.concat(vector_matching.reduce(function (prev, curr) { return ''.concat(prev, '|').concat(curr) }), ')')
|
||||
// LogQL Operators
|
||||
const operators = [
|
||||
'+',
|
||||
'-',
|
||||
'*',
|
||||
'/',
|
||||
'%',
|
||||
'^',
|
||||
'==',
|
||||
'!=',
|
||||
'>',
|
||||
'<',
|
||||
'>=',
|
||||
'<=',
|
||||
'|=',
|
||||
'!=',
|
||||
'|~',
|
||||
'!~',
|
||||
'and',
|
||||
'or',
|
||||
'unless',
|
||||
'|'
|
||||
]
|
||||
// Merging all the keywords in one list
|
||||
const keywords = aggregations
|
||||
.concat(parsers)
|
||||
.concat(format_expressions)
|
||||
.concat(vector_aggregations)
|
||||
.concat(vector_matching)
|
||||
exports.monarchlanguage = {
|
||||
ignoreCase: false,
|
||||
defaultToken: '',
|
||||
tokenPostfix: '.logql',
|
||||
keywords: keywords,
|
||||
operators: operators,
|
||||
vectorMatching: vectorMatchingRegex,
|
||||
// we include these common regular expressions
|
||||
symbols: /[=><!~?:&|+\-*\/^%]+/,
|
||||
escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
|
||||
digits: /\d+(_+\d+)*/,
|
||||
octaldigits: /[0-7]+(_+[0-7]+)*/,
|
||||
binarydigits: /[0-1]+(_+[0-1]+)*/,
|
||||
hexdigits: /[[0-9a-fA-F]+(_+[0-9a-fA-F]+)*/,
|
||||
integersuffix: /(ll|LL|u|U|l|L)?(ll|LL|u|U|l|L)?/,
|
||||
floatsuffix: /[fFlL]?/,
|
||||
// The main tokenizer for our languages
|
||||
tokenizer: {
|
||||
root: [
|
||||
// 'by', 'without' and vector matching
|
||||
[/@vectorMatching\s*(?=\()/, 'type', '@clauses'],
|
||||
// labels
|
||||
[/[a-z_]\w*(?=\s*(=|!=|=~|!~))/, 'tag'],
|
||||
// comments
|
||||
[/(^#.*$)/, 'comment'],
|
||||
// all keywords have the same color
|
||||
[
|
||||
/[a-zA-Z_]\w*/,
|
||||
{
|
||||
cases: {
|
||||
'@keywords': 'type',
|
||||
'@default': 'identifier'
|
||||
}
|
||||
}
|
||||
],
|
||||
// strings
|
||||
[/"/, 'string', '@string_double'],
|
||||
[/'/, 'string', '@string_single'],
|
||||
[/`/, 'string', '@string_backtick'],
|
||||
// whitespace
|
||||
{ include: '@whitespace' },
|
||||
// delimiters and operators
|
||||
[/[{}()\[\]]/, '@brackets'],
|
||||
[/[<>](?!@symbols)/, '@brackets'],
|
||||
[
|
||||
/@symbols/,
|
||||
{
|
||||
cases: {
|
||||
'@operators': 'delimiter',
|
||||
'@default': ''
|
||||
}
|
||||
}
|
||||
],
|
||||
// numbers
|
||||
[/\d+(?:ms|[smhdwy])/, 'number'],
|
||||
[/\d*\d+[eE]([\-+]?\d+)?(@floatsuffix)/, 'number.float'],
|
||||
[/\d*\.\d+([eE][\-+]?\d+)?(@floatsuffix)/, 'number.float'],
|
||||
[/0[xX][0-9a-fA-F']*[0-9a-fA-F](@integersuffix)/, 'number.hex'],
|
||||
[/0[0-7']*[0-7](@integersuffix)/, 'number.octal'],
|
||||
[/0[bB][0-1']*[0-1](@integersuffix)/, 'number.binary'],
|
||||
[/\d[\d']*\d(@integersuffix)/, 'number'],
|
||||
[/\d(@integersuffix)/, 'number']
|
||||
],
|
||||
string_double: [
|
||||
// Set to token: number to differentiate color
|
||||
[/\{\{(.*?)\}\}/, { token: 'number' }],
|
||||
[/[^\\"]/, 'string'],
|
||||
[/@escapes/, 'string.escape'],
|
||||
[/\\./, 'string.escape.invalid'],
|
||||
[/"/, 'string', '@pop']
|
||||
],
|
||||
string_single: [
|
||||
[/[^\\']+/, 'string'],
|
||||
[/@escapes/, 'string.escape'],
|
||||
[/\\./, 'string.escape.invalid'],
|
||||
[/'/, 'string', '@pop']
|
||||
],
|
||||
string_backtick: [
|
||||
// Set to token: number to differentiate color
|
||||
[/\{\{(.*?)\}\}/, { token: 'number' }],
|
||||
[/[^\\`]/, 'string'],
|
||||
[/@escapes/, 'string.escape'],
|
||||
[/\\./, 'string.escape.invalid'],
|
||||
[/`/, 'string', '@pop']
|
||||
],
|
||||
clauses: [
|
||||
[/[^(,)]/, 'tag'],
|
||||
[/\)/, 'identifier', '@pop']
|
||||
],
|
||||
whitespace: [[/[ \t\r\n]+/, 'white']]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
import lodash from 'lodash'
|
||||
const VARIABLE_REGEX = /\$(\w+)|\[\[(\w+?)(?::(\w+))?\]\]|\${(\w+)(?:\.([^:^\}]+))?(?::([^\}]+))?}/g
|
||||
class ScopedVarsVariable {
|
||||
constructor (name, value) {
|
||||
this.state = { name, value, type: 'scopedvar' }
|
||||
}
|
||||
|
||||
getValue (fieldPath) {
|
||||
const { value } = this.state
|
||||
let realValue = value.value
|
||||
if (fieldPath) {
|
||||
realValue = getFieldAccessor(fieldPath)(value.value)
|
||||
} else {
|
||||
realValue = value.value
|
||||
}
|
||||
if (realValue === 'string' || realValue === 'number' || realValue === 'boolean') {
|
||||
return realValue
|
||||
}
|
||||
return String(realValue)
|
||||
}
|
||||
|
||||
getValueText () {
|
||||
const { value } = this.state
|
||||
if (value.text != null) {
|
||||
return String(value.text)
|
||||
}
|
||||
return String(value)
|
||||
}
|
||||
}
|
||||
export const DataLinkBuiltInVars = {
|
||||
keepTime: '__url_time_range',
|
||||
timeRangeFrom: '__from',
|
||||
timeRangeTo: '__to',
|
||||
includeVars: '__all_variables',
|
||||
seriesName: '__series.name',
|
||||
fieldName: '__field.name',
|
||||
valueTime: '__value.time',
|
||||
valueNumeric: '__value.numeric',
|
||||
valueText: '__value.text',
|
||||
valueRaw: '__value.raw',
|
||||
// name of the calculation represented by the value
|
||||
valueCalc: '__value.calc'
|
||||
}
|
||||
class AllVariablesMacro {
|
||||
constructor (name, sceneObject) {
|
||||
this.state = { name, type: 'url_variable' }
|
||||
this._sceneObject = sceneObject
|
||||
}
|
||||
|
||||
getValue () {
|
||||
const allVars = collectAllVariables(this._sceneObject)
|
||||
const format = formatRegistry.get(schema.VariableFormatID.QueryParam)
|
||||
const params = []
|
||||
for (const name of Object.keys(allVars)) {
|
||||
const variable = allVars[name]
|
||||
const value = variable.getValue()
|
||||
if (!value) {
|
||||
continue
|
||||
}
|
||||
if (isCustomVariableValue(value)) {
|
||||
params.push(value.formatter(schema.VariableFormatID.QueryParam))
|
||||
} else {
|
||||
params.push(format.formatter(value, [], variable))
|
||||
}
|
||||
}
|
||||
return new SkipFormattingValue(params.join('&'))
|
||||
}
|
||||
|
||||
getValueText () {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
const macrosIndex = {
|
||||
__all_variables: AllVariablesMacro,
|
||||
__url_time_range: UrlTimeRangeMacro,
|
||||
__value: ValueMacro,
|
||||
__data: DataMacro,
|
||||
__series: SeriesMacro,
|
||||
__field: FieldMacro,
|
||||
__url: UrlMacro,
|
||||
__from: TimeFromAndToMacro,
|
||||
__to: TimeFromAndToMacro,
|
||||
__timezone: TimezoneMacro
|
||||
}
|
||||
const sceneGraph = {
|
||||
// getVariables,
|
||||
// getData,
|
||||
// getTimeRange,
|
||||
// getLayout,
|
||||
interpolate
|
||||
// lookupVariable,
|
||||
// hasVariableDependencyInLoadingState,
|
||||
// findObject
|
||||
}
|
||||
function interpolate (sceneObject, value, scopedVars, format) {
|
||||
if (value === '' || value == null) {
|
||||
return ''
|
||||
}
|
||||
return sceneInterpolator(sceneObject, value, scopedVars, format)
|
||||
}
|
||||
function sceneInterpolator (sceneObject, target, scopedVars, format) {
|
||||
if (!target) {
|
||||
return target != null ? target : ''
|
||||
}
|
||||
VARIABLE_REGEX.lastIndex = 0
|
||||
return target.replace(VARIABLE_REGEX, (match, var1, var2, fmt2, var3, fieldPath, fmt3) => {
|
||||
const variableName = var1 || var2 || var3
|
||||
const fmt = fmt2 || fmt3 || format
|
||||
const variable = lookupFormatVariable(variableName, match, scopedVars, sceneObject)
|
||||
if (!variable) {
|
||||
return match
|
||||
}
|
||||
return formatValue(variable, variable.getValue(fieldPath), fmt)
|
||||
})
|
||||
}
|
||||
function lookupFormatVariable (name, match, scopedVars, sceneObject) {
|
||||
const scopedVar = scopedVars == null ? 0 : scopedVars[name]
|
||||
if (scopedVar) {
|
||||
return getSceneVariableForScopedVar(name, scopedVar)
|
||||
}
|
||||
const variable = lookupVariable(name, sceneObject)
|
||||
if (variable) {
|
||||
return variable
|
||||
}
|
||||
if (macrosIndex[name]) {
|
||||
return new macrosIndex[name](name, sceneObject, match, scopedVars)
|
||||
}
|
||||
return null
|
||||
}
|
||||
let scopedVarsVariable
|
||||
function getSceneVariableForScopedVar (name, value) {
|
||||
if (!scopedVarsVariable) {
|
||||
scopedVarsVariable = new ScopedVarsVariable(name, value)
|
||||
} else {
|
||||
scopedVarsVariable.state.name = name
|
||||
scopedVarsVariable.state.value = value
|
||||
}
|
||||
return scopedVarsVariable
|
||||
}
|
||||
const fieldAccessorCache = {}
|
||||
function getFieldAccessor (fieldPath) {
|
||||
const accessor = fieldAccessorCache[fieldPath]
|
||||
if (accessor) {
|
||||
return accessor
|
||||
}
|
||||
return (fieldAccessorCache[fieldPath] = lodash.property(fieldPath))
|
||||
}
|
||||
function lookupVariable (name, sceneObject) {
|
||||
const variables = sceneObject.state.$variables
|
||||
if (!variables) {
|
||||
if (sceneObject.parent) {
|
||||
return lookupVariable(name, sceneObject.parent)
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
const found = variables.getByName(name)
|
||||
if (found) {
|
||||
return found
|
||||
} else if (sceneObject.parent) {
|
||||
return lookupVariable(name, sceneObject.parent)
|
||||
}
|
||||
return null
|
||||
}
|
||||
export default sceneGraph
|
||||
@@ -0,0 +1,559 @@
|
||||
import {
|
||||
parser,
|
||||
VectorAggregationExpr,
|
||||
String,
|
||||
Selector,
|
||||
RangeAggregationExpr,
|
||||
Range,
|
||||
PipelineExpr,
|
||||
PipelineStage,
|
||||
Matchers,
|
||||
Matcher,
|
||||
LogQL,
|
||||
LogRangeExpr,
|
||||
LogExpr,
|
||||
Identifier,
|
||||
Grouping,
|
||||
Expr,
|
||||
LiteralExpr,
|
||||
MetricExpr,
|
||||
UnwrapExpr,
|
||||
DropLabelsExpr,
|
||||
KeepLabelsExpr,
|
||||
DropLabels,
|
||||
KeepLabels
|
||||
} from './lezerConfig'
|
||||
|
||||
function getLogQueryFromMetricsQuery (text) {
|
||||
return text
|
||||
}
|
||||
|
||||
function move (node, direction) {
|
||||
return node[direction]
|
||||
}
|
||||
|
||||
function walk (node, path) {
|
||||
let current = node
|
||||
for (const [direction, expectedNode] of path) {
|
||||
current = move(current, direction)
|
||||
if (current === null) {
|
||||
// we could not move in the direction, we stop
|
||||
return null
|
||||
}
|
||||
if (current.type.id !== expectedNode) {
|
||||
// the reached node has wrong type, we stop
|
||||
return null
|
||||
}
|
||||
}
|
||||
return current
|
||||
}
|
||||
|
||||
function getNodeText (node, text) {
|
||||
return text.slice(node.from, node.to)
|
||||
}
|
||||
|
||||
function parseStringLiteral (text) {
|
||||
// If it is a string-literal, it is inside quotes of some kind
|
||||
const inside = text.slice(1, text.length - 1)
|
||||
|
||||
// Very simple un-escaping:
|
||||
|
||||
// Double quotes
|
||||
if (text.startsWith('"') && text.endsWith('"')) {
|
||||
// NOTE: this is not 100% perfect, we only unescape the double-quote,
|
||||
// there might be other characters too
|
||||
return inside.replace(/\\"/gm, '"')
|
||||
}
|
||||
|
||||
// Single quotes
|
||||
if (text.startsWith("'") && text.endsWith("'")) {
|
||||
// NOTE: this is not 100% perfect, we only unescape the single-quote,
|
||||
// there might be other characters too
|
||||
return inside.replace(/\\'/gm, "'")
|
||||
}
|
||||
|
||||
// Backticks
|
||||
if (text.startsWith('`') && text.endsWith('`')) {
|
||||
return inside
|
||||
}
|
||||
|
||||
throw new Error(`Invalid string literal: ${text}`)
|
||||
}
|
||||
|
||||
export const LabelOperator = '=' | '!=' | '=~' | '!~'
|
||||
|
||||
export const Label = {}
|
||||
|
||||
export const Situation = {}
|
||||
|
||||
const Resolver = {
|
||||
path: [],
|
||||
fun: (node, text, pos) => Situation
|
||||
}
|
||||
|
||||
function isPathMatch (resolverPath, cursorPath) {
|
||||
return resolverPath.every((item, index) => item === cursorPath[index])
|
||||
}
|
||||
|
||||
const ERROR_NODE_ID = 0
|
||||
|
||||
const RESOLVERS = [
|
||||
{
|
||||
path: [Selector],
|
||||
fun: resolveSelector
|
||||
},
|
||||
{
|
||||
path: [ERROR_NODE_ID, Matchers, Selector],
|
||||
fun: resolveSelector
|
||||
},
|
||||
{
|
||||
path: [LogQL],
|
||||
fun: resolveTopLevel
|
||||
},
|
||||
{
|
||||
path: [String, Matcher],
|
||||
fun: resolveMatcher
|
||||
},
|
||||
{
|
||||
path: [Grouping],
|
||||
fun: resolveLabelsForGrouping
|
||||
},
|
||||
{
|
||||
path: [LogRangeExpr],
|
||||
fun: resolveLogRange
|
||||
},
|
||||
{
|
||||
path: [ERROR_NODE_ID, Matcher],
|
||||
fun: resolveMatcher
|
||||
},
|
||||
{
|
||||
path: [ERROR_NODE_ID, Range],
|
||||
fun: resolveDurations
|
||||
},
|
||||
{
|
||||
path: [ERROR_NODE_ID, LogRangeExpr],
|
||||
fun: resolveLogRangeFromError
|
||||
},
|
||||
{
|
||||
path: [ERROR_NODE_ID, LiteralExpr, MetricExpr, VectorAggregationExpr],
|
||||
fun: () => ({ type: 'IN_AGGREGATION' })
|
||||
},
|
||||
{
|
||||
path: [ERROR_NODE_ID, PipelineStage, PipelineExpr],
|
||||
fun: resolvePipeError
|
||||
},
|
||||
{
|
||||
path: [ERROR_NODE_ID, UnwrapExpr],
|
||||
fun: resolveAfterUnwrap
|
||||
},
|
||||
{
|
||||
path: [UnwrapExpr],
|
||||
fun: resolveAfterUnwrap
|
||||
},
|
||||
{
|
||||
path: [ERROR_NODE_ID, DropLabelsExpr],
|
||||
fun: resolveAfterKeepAndDrop
|
||||
},
|
||||
{
|
||||
path: [ERROR_NODE_ID, DropLabels],
|
||||
fun: resolveAfterKeepAndDrop
|
||||
},
|
||||
{
|
||||
path: [ERROR_NODE_ID, KeepLabelsExpr],
|
||||
fun: resolveAfterKeepAndDrop
|
||||
},
|
||||
{
|
||||
path: [ERROR_NODE_ID, KeepLabels],
|
||||
fun: resolveAfterKeepAndDrop
|
||||
}
|
||||
]
|
||||
|
||||
const LABEL_OP_MAP = new Map([
|
||||
['Eq', '='],
|
||||
['Re', '=~'],
|
||||
['Neq', '!='],
|
||||
['Nre', '!~']
|
||||
])
|
||||
|
||||
function getLabelOp (opNode) {
|
||||
return LABEL_OP_MAP.get(opNode.name) || null
|
||||
}
|
||||
|
||||
function getLabel (matcherNode, text) {
|
||||
if (matcherNode.type.id !== Matcher) {
|
||||
return null
|
||||
}
|
||||
|
||||
const nameNode = walk(matcherNode, [['firstChild', Identifier]])
|
||||
|
||||
if (nameNode === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
const opNode = nameNode.nextSibling
|
||||
if (opNode === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
const op = getLabelOp(opNode)
|
||||
if (op === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
const valueNode = walk(matcherNode, [['lastChild', String]])
|
||||
|
||||
if (valueNode === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
const name = getNodeText(nameNode, text)
|
||||
const value = parseStringLiteral(getNodeText(valueNode, text))
|
||||
|
||||
return { name, value, op }
|
||||
}
|
||||
|
||||
function getLabels (selectorNode, text) {
|
||||
if (selectorNode.type.id !== Selector) {
|
||||
return []
|
||||
}
|
||||
|
||||
let listNode = walk(selectorNode, [['firstChild', Matchers]])
|
||||
|
||||
const labels = []
|
||||
|
||||
while (listNode !== null) {
|
||||
const matcherNode = walk(listNode, [['lastChild', Matcher]])
|
||||
if (matcherNode !== null) {
|
||||
const label = getLabel(matcherNode, text)
|
||||
if (label !== null) {
|
||||
labels.push(label)
|
||||
}
|
||||
}
|
||||
|
||||
// there might be more labels
|
||||
listNode = walk(listNode, [['firstChild', Matchers]])
|
||||
}
|
||||
|
||||
// our labels-list is last-first, so we reverse it
|
||||
labels.reverse()
|
||||
|
||||
return labels
|
||||
}
|
||||
|
||||
function resolveAfterUnwrap (node, text, pos) {
|
||||
return {
|
||||
type: 'AFTER_UNWRAP',
|
||||
logQuery: getLogQueryFromMetricsQuery(text).trim()
|
||||
}
|
||||
}
|
||||
|
||||
function resolvePipeError (node, text, pos) {
|
||||
// for example `{level="info"} |`
|
||||
const exprNode = walk(node, [
|
||||
['parent', PipelineStage],
|
||||
['parent', PipelineExpr]
|
||||
])
|
||||
|
||||
if (exprNode === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
const { parent } = exprNode
|
||||
|
||||
if (parent === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (parent.type.id === LogExpr || parent.type.id === LogRangeExpr) {
|
||||
return resolveLogOrLogRange(parent, text, pos, true)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function resolveLabelsForGrouping (node, text, pos) {
|
||||
const aggrExpNode = walk(node, [['parent', VectorAggregationExpr]])
|
||||
if (aggrExpNode === null) {
|
||||
return null
|
||||
}
|
||||
const bodyNode = aggrExpNode.getChild('MetricExpr')
|
||||
if (bodyNode === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
const selectorNode = walk(bodyNode, [
|
||||
['firstChild', RangeAggregationExpr],
|
||||
['lastChild', LogRangeExpr],
|
||||
['firstChild', Selector]
|
||||
])
|
||||
|
||||
if (selectorNode === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'IN_GROUPING',
|
||||
logQuery: getLogQueryFromMetricsQuery(text).trim()
|
||||
}
|
||||
}
|
||||
|
||||
function resolveMatcher (node, text, pos) {
|
||||
// we can arrive here for two reasons. `node` is either:
|
||||
// - a StringNode (like in `{job="^"}`)
|
||||
// - or an error node (like in `{job=^}`)
|
||||
const inStringNode = !node.type.isError
|
||||
|
||||
const parent = walk(node, [['parent', Matcher]])
|
||||
if (parent === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
const labelNameNode = walk(parent, [['firstChild', Identifier]])
|
||||
if (labelNameNode === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
const labelName = getNodeText(labelNameNode, text)
|
||||
|
||||
// now we need to go up, to the parent of Matcher,
|
||||
// there can be one or many `Matchers` parents, we have
|
||||
// to go through all of them
|
||||
|
||||
const firstListNode = walk(parent, [['parent', Matchers]])
|
||||
if (firstListNode === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
let listNode = firstListNode
|
||||
|
||||
// we keep going through the parent-nodes as long as they are Matchers.
|
||||
// as soon as we reach Selector, we stop
|
||||
let selectorNode = null
|
||||
while (selectorNode === null) {
|
||||
const parent = listNode.parent
|
||||
if (parent === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
switch (parent.type.id) {
|
||||
case Matchers:
|
||||
// we keep looping
|
||||
listNode = parent
|
||||
continue
|
||||
case Selector:
|
||||
// we reached the end, we can stop the loop
|
||||
selectorNode = parent
|
||||
continue
|
||||
default:
|
||||
// we reached some other node, we stop
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
// now we need to find the other names
|
||||
const allLabels = getLabels(selectorNode, text)
|
||||
|
||||
// we need to remove "our" label from all-labels, if it is in there
|
||||
const otherLabels = allLabels.filter((label) => label.name !== labelName)
|
||||
|
||||
return {
|
||||
type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',
|
||||
labelName,
|
||||
betweenQuotes: inStringNode,
|
||||
otherLabels
|
||||
}
|
||||
}
|
||||
|
||||
function resolveTopLevel (node, text, pos) {
|
||||
// we try a couply specific paths here.
|
||||
// `{x="y"}` situation, with the cursor at the end
|
||||
|
||||
const logExprNode = walk(node, [
|
||||
['lastChild', Expr],
|
||||
['lastChild', LogExpr]
|
||||
])
|
||||
|
||||
if (logExprNode != null) {
|
||||
return resolveLogOrLogRange(logExprNode, text, pos, false)
|
||||
}
|
||||
|
||||
// `s` situation, with the cursor at the end.
|
||||
// (basically, user enters a non-special characters as first
|
||||
// character in query field)
|
||||
const idNode = walk(node, [
|
||||
['firstChild', ERROR_NODE_ID],
|
||||
['firstChild', Identifier]
|
||||
])
|
||||
|
||||
if (idNode != null) {
|
||||
return {
|
||||
type: 'AT_ROOT'
|
||||
}
|
||||
}
|
||||
|
||||
// no patterns match
|
||||
return null
|
||||
}
|
||||
|
||||
function resolveDurations (node, text, pos) {
|
||||
return {
|
||||
type: 'IN_RANGE'
|
||||
}
|
||||
}
|
||||
|
||||
function resolveLogRange (node, text, pos) {
|
||||
return resolveLogOrLogRange(node, text, pos, false)
|
||||
}
|
||||
|
||||
function resolveLogRangeFromError (node, text, pos) {
|
||||
const parent = walk(node, [['parent', LogRangeExpr]])
|
||||
if (parent === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
return resolveLogOrLogRange(parent, text, pos, false)
|
||||
}
|
||||
|
||||
function resolveLogOrLogRange (node, text, pos, afterPipe) {
|
||||
// Here the `node` is either a LogExpr or a LogRangeExpr
|
||||
// We want to handle the case where we are next to a selector
|
||||
const selectorNode = walk(node, [['firstChild', Selector]])
|
||||
|
||||
// Check that the selector is before the cursor, not after it
|
||||
if (!selectorNode || selectorNode.to > pos) {
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'AFTER_SELECTOR',
|
||||
afterPipe,
|
||||
hasSpace: text.endsWith(' '),
|
||||
logQuery: getLogQueryFromMetricsQuery(text).trim()
|
||||
}
|
||||
}
|
||||
|
||||
function resolveSelector (node, text, pos) {
|
||||
// for example `{^}`
|
||||
|
||||
// false positive:
|
||||
// `{a="1"^}`
|
||||
const child = walk(node, [['firstChild', Matchers]])
|
||||
if (child !== null) {
|
||||
// means the label-matching part contains at least one label already.
|
||||
//
|
||||
// in this case, we will need to have a `,` character at the end,
|
||||
// to be able to suggest adding the next label.
|
||||
// the area between the end-of-the-child-node and the cursor-pos
|
||||
// must contain a `,` in this case.
|
||||
const textToCheck = text.slice(child.from, pos)
|
||||
if (!textToCheck.trim().endsWith(',')) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const selectorNode =
|
||||
node.type.id === ERROR_NODE_ID
|
||||
? walk(node, [
|
||||
['parent', Matchers],
|
||||
['parent', Selector]
|
||||
])
|
||||
: node
|
||||
if (!selectorNode) {
|
||||
return null
|
||||
}
|
||||
|
||||
const otherLabels = getLabels(selectorNode, text)
|
||||
|
||||
return {
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
otherLabels
|
||||
}
|
||||
}
|
||||
|
||||
function resolveAfterKeepAndDrop (node, text, pos) {
|
||||
let logQuery = getLogQueryFromMetricsQuery(text).trim()
|
||||
let keepAndDropParent = null
|
||||
let parent = node.parent
|
||||
while (parent !== null) {
|
||||
if (parent.type.id === PipelineStage) {
|
||||
keepAndDropParent = parent
|
||||
break
|
||||
}
|
||||
parent = parent.parent
|
||||
}
|
||||
|
||||
if (keepAndDropParent.type && (keepAndDropParent.type.id === PipelineStage)) {
|
||||
logQuery = logQuery.slice(0, keepAndDropParent.from)
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'AFTER_KEEP_AND_DROP',
|
||||
logQuery
|
||||
}
|
||||
}
|
||||
|
||||
// we find the first error-node in the tree that is at the cursor-position.
|
||||
// NOTE: this might be too slow, might need to optimize it
|
||||
// (ideas: we do not need to go into every subtree, based on from/to)
|
||||
// also, only go to places that are in the sub-tree of the node found
|
||||
// by default by lezer. problem is, `next()` will go upward too,
|
||||
// and we do not want to go higher than our node
|
||||
function getErrorNode (tree, text, cursorPos) {
|
||||
// sometimes the cursor is a couple spaces after the end of the expression.
|
||||
// to account for this situation, we "move" the cursor position back,
|
||||
// so that there are no spaces between the end-of-expression and the cursor
|
||||
const trimRightTextLen = text.trimEnd().length
|
||||
console.log(trimRightTextLen)
|
||||
const pos = trimRightTextLen < cursorPos ? trimRightTextLen : cursorPos
|
||||
console.log(pos)
|
||||
const cur = tree.cursorAt(pos)
|
||||
console.log(cur)
|
||||
do {
|
||||
if (cur.from === pos && cur.to === pos) {
|
||||
const { node } = cur
|
||||
console.log(node)
|
||||
console.log(node.type.isError)
|
||||
if (node.type.isError) {
|
||||
return node
|
||||
}
|
||||
}
|
||||
} while (cur.next())
|
||||
return null
|
||||
}
|
||||
|
||||
export function getSituation (text, pos) {
|
||||
// there is a special case when we are at the start of writing text,
|
||||
// so we handle that case first
|
||||
|
||||
if (text === '') {
|
||||
return {
|
||||
type: 'EMPTY'
|
||||
}
|
||||
}
|
||||
|
||||
const tree = parser.parse(text)
|
||||
console.log(tree)
|
||||
// if the tree contains error, it is very probable that
|
||||
// our node is one of those error nodes.
|
||||
// also, if there are errors, the node lezer finds us,
|
||||
// might not be the best node.
|
||||
// so first we check if there is an error node at the cursor position
|
||||
const maybeErrorNode = getErrorNode(tree, text, pos)
|
||||
console.log(maybeErrorNode)
|
||||
const cur = maybeErrorNode.cursor().cursorAt(pos)
|
||||
|
||||
const currentNode = cur.node
|
||||
|
||||
const ids = [cur.type.id]
|
||||
while (cur.parent()) {
|
||||
ids.push(cur.type.id)
|
||||
}
|
||||
|
||||
for (const resolver of RESOLVERS) {
|
||||
if (isPathMatch(resolver.path, ids)) {
|
||||
return resolver.fun(currentNode, text, pos)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package logql
|
||||
|
||||
import (
|
||||
"syscall/js"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/scanner"
|
||||
|
||||
"github.com/prometheus/prometheus/model/labels"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Improve the error messages coming out of yacc.
|
||||
exprErrorVerbose = true
|
||||
for str, tok := range tokens {
|
||||
exprToknames[tok-exprPrivate+1] = str
|
||||
}
|
||||
c := make(chan struct{}, 0)
|
||||
|
||||
// 注册函数
|
||||
js.Global().Set("parsePromQL", js.FuncOf(parsePromQL))
|
||||
|
||||
<-c
|
||||
}
|
||||
|
||||
// ParseExpr parses a string and returns an Expr.
|
||||
func ParseExpr(input string) (Expr, error) {
|
||||
l := lexer{
|
||||
parser: exprNewParser().(*exprParserImpl),
|
||||
}
|
||||
l.Init(strings.NewReader(input))
|
||||
l.Scanner.Error = func(_ *scanner.Scanner, msg string) {
|
||||
l.Error(msg)
|
||||
}
|
||||
|
||||
e := l.parser.Parse(&l)
|
||||
if e != 0 || len(l.errs) > 0 {
|
||||
return nil, l.errs[0]
|
||||
}
|
||||
return l.expr, nil
|
||||
}
|
||||
|
||||
// ParseMatchers parses a string and returns labels matchers, if the expression contains
|
||||
// anything else it will return an error.
|
||||
func ParseMatchers(input string) ([]*labels.Matcher, error) {
|
||||
expr, err := ParseExpr(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
matcherExpr, ok := expr.(*matchersExpr)
|
||||
if !ok {
|
||||
return nil, errors.New("only label matchers is supported")
|
||||
}
|
||||
return matcherExpr.matchers, nil
|
||||
}
|
||||
|
||||
var tokens = map[string]int{
|
||||
",": COMMA,
|
||||
".": DOT,
|
||||
"{": OPEN_BRACE,
|
||||
"}": CLOSE_BRACE,
|
||||
"=": EQ,
|
||||
"!=": NEQ,
|
||||
"=~": RE,
|
||||
"!~": NRE,
|
||||
"|=": PIPE_EXACT,
|
||||
"|~": PIPE_MATCH,
|
||||
}
|
||||
|
||||
type lexer struct {
|
||||
scanner.Scanner
|
||||
errs []ParseError
|
||||
expr Expr
|
||||
parser *exprParserImpl
|
||||
}
|
||||
|
||||
func (l *lexer) Lex(lval *exprSymType) int {
|
||||
r := l.Scan()
|
||||
|
||||
switch r {
|
||||
case scanner.EOF:
|
||||
return 0
|
||||
|
||||
case scanner.String:
|
||||
var err error
|
||||
lval.str, err = strconv.Unquote(l.TokenText())
|
||||
if err != nil {
|
||||
l.Error(err.Error())
|
||||
return 0
|
||||
}
|
||||
return STRING
|
||||
}
|
||||
|
||||
if tok, ok := tokens[l.TokenText()+string(l.Peek())]; ok {
|
||||
l.Next()
|
||||
return tok
|
||||
}
|
||||
|
||||
if tok, ok := tokens[l.TokenText()]; ok {
|
||||
return tok
|
||||
}
|
||||
|
||||
lval.str = l.TokenText()
|
||||
return IDENTIFIER
|
||||
}
|
||||
|
||||
func (l *lexer) Error(msg string) {
|
||||
l.errs = append(l.errs, ParseError{
|
||||
msg: msg,
|
||||
line: l.Line,
|
||||
col: l.Column,
|
||||
})
|
||||
}
|
||||
|
||||
// ParseError is what is returned when we failed to parse.
|
||||
type ParseError struct {
|
||||
msg string
|
||||
line, col int
|
||||
}
|
||||
|
||||
func (p ParseError) Error() string {
|
||||
return fmt.Sprintf("parse error at line %d, col %d: %s", p.line, p.col, p.msg)
|
||||
}
|
||||
@@ -86,20 +86,38 @@
|
||||
class="not-fixed-height no-resize no-close"
|
||||
>
|
||||
</div> -->
|
||||
<el-input
|
||||
v-if="type == 'log'"
|
||||
:id="inputId"
|
||||
v-model="expressionList[index]"
|
||||
size="small" :rows="1"
|
||||
autosize
|
||||
class="not-fixed-height no-resize"
|
||||
type="textarea"
|
||||
show-word-limit maxlength="256"
|
||||
@input="metricKeyDown"
|
||||
@keyup.enter.native="expressionChange"
|
||||
ref="elInput"
|
||||
>
|
||||
</el-input>
|
||||
<!-- <el-input-->
|
||||
<!-- v-if="type == 'log'"-->
|
||||
<!-- :id="inputId"-->
|
||||
<!-- v-model="expressionList[index]"-->
|
||||
<!-- size="small" :rows="1"-->
|
||||
<!-- autosize-->
|
||||
<!-- class="not-fixed-height no-resize"-->
|
||||
<!-- type="textarea"-->
|
||||
<!-- show-word-limit maxlength="256"-->
|
||||
<!-- @input="metricKeyDown"-->
|
||||
<!-- @keyup.enter.native="expressionChange"-->
|
||||
<!-- ref="elInput"-->
|
||||
<!-- >-->
|
||||
<!-- </el-input>-->
|
||||
<div>
|
||||
<MonacoEditor
|
||||
v-if="type == 'log'"
|
||||
v-model="expressionList[index]"
|
||||
theme="nz"
|
||||
class="not-fixed-height no-resize"
|
||||
ref="monacoEditor"
|
||||
style="border: 1px solid #dedede;"
|
||||
:style="{
|
||||
height: monacoEditorHeight + 'px'
|
||||
}"
|
||||
language="logql"
|
||||
:options="MONACO_EDITOR_OPTIONS"
|
||||
@editorWillMount="handelBeforeMount"
|
||||
@editorDidMount="handleMount"
|
||||
@change="expressionChange"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="errorMsg" class="append-msg error" style="position: absolute">
|
||||
<span>{{ errorMsg }}</span>
|
||||
@@ -459,11 +477,15 @@ import {
|
||||
closeBracketsKeymap
|
||||
} from '@codemirror/autocomplete'
|
||||
import exploreHistory from '@/components/page/dashboard/explore/histoyrComponent/exploreHistory'
|
||||
import MonacoEditor from 'vue-monaco'
|
||||
import logqlMixin from '@/components/page/dashboard/explore/logql/logqlMixin'
|
||||
export default {
|
||||
name: 'promqlInput',
|
||||
mixins: [logqlMixin],
|
||||
components: {
|
||||
selectAlertSilence,
|
||||
exploreHistory
|
||||
exploreHistory,
|
||||
MonacoEditor
|
||||
},
|
||||
props: {
|
||||
index: { type: Number },
|
||||
@@ -884,6 +906,11 @@ export default {
|
||||
}
|
||||
},
|
||||
expressionChange: function () {
|
||||
if (this.$refs.monacoEditor) {
|
||||
setTimeout(() => {
|
||||
this.heightChange()
|
||||
}, 100)
|
||||
}
|
||||
this.$emit('change')
|
||||
},
|
||||
setError: function (errMsg) {
|
||||
|
||||
Reference in New Issue
Block a user