2022-04-02 00:33:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								import  {  SyntaxNode ,  TreeCursor  }  from  '@lezer/common' ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-22 21:33:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-25 18:19:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								import  {  QueryBuilderOperation ,  QueryBuilderOperationParamValue  }  from  '@grafana/experimental' ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-02 00:33:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-16 00:15:20 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// Although 0 isn't explicitly provided in the @grafana/lezer-logql library as the error node ID, it does appear to be the ID of error nodes within lezer.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-16 21:35:20 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								export  const  ErrorId  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-02 00:33:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  function  getLeftMostChild ( cur : SyntaxNode ) :  SyntaxNode  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  cur . firstChild  ?  getLeftMostChild ( cur . firstChild )  :  cur ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  function  makeError ( expr : string ,  node : SyntaxNode )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    text : getString ( expr ,  node ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // TODO: this are positions in the string with the replaced variables. Means it cannot be used to show exact
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //  placement of the error for the user. We need some translation table to positions before the variable
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //  replace.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    from :  node . from , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    to : node.to , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    parentType : node.parent?.name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Taken from template_srv, but copied so to not mess with the regex.index which is manipulated in the service
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/ * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  This  regex  matches  3  types  of  variable  reference  with  an  optional  format  specifier 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ $ ( \ w + )                           $var1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ [ \ [ ( [ \ s \ S ] + ? ) ( ? : : ( \ w + ) ) ? \ ] \ ]     [ [ var2 ] ]  or  [ [ var2 :fmt2 ] ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ $ { ( \ w + ) ( ? : : ( \ w + ) ) ? }              $ { var3 }  or  $ { var3 :fmt3 } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * / 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 01:43:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  const  variableRegex  =  /\$(\w+)|\[\[([\s\S]+?)(?::(\w+))?\]\]|\${(\w+)(?:\.([^:^\}]+))?(?::([^\}]+))?}/g ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-02 00:33:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/ * * 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-06 17:17:49 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								 *  As  variables  with  $  are  creating  parsing  errors ,  we  first  replace  them  with  magic  string  that  is  parsable  and  at 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-09 16:19:30 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								 *  the  same  time  we  can  get  the  variable  and  its  format  back  from  it . 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-02 00:33:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								 *  @param  expr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  function  replaceVariables ( expr : string )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  expr . replace ( variableRegex ,  ( match ,  var1 ,  var2 ,  fmt2 ,  var3 ,  fieldPath ,  fmt3 )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  fmt  =  fmt2  ||  fmt3 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    let  variable  =  var1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    let  varType  =  '0' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( var2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      variable  =  var2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      varType  =  '1' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( var3 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      variable  =  var3 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      varType  =  '2' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ` __V_ ${ varType } __ `  +  variable  +  '__V__'  +  ( fmt  ?  '__F__'  +  fmt  +  '__F__'  :  '' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								const  varTypeFunc  =  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ( v : string ,  f? : string )  = >  ` \ $ ${ v } ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ( v : string ,  f? : string )  = >  ` [[ ${ v } ${ f  ?  ` : ${ f } `  :  '' } ]] ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ( v : string ,  f? : string )  = >  ` \ $ \ { ${ v } ${ f  ?  ` : ${ f } `  :  '' } \ } ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/ * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Get  back  the  text  with  variables  in  their  original  format . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  @param  expr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * / 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-09 18:04:51 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								export  function  returnVariables ( expr : string )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-02 00:33:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  return  expr . replace ( /__V_(\d)__(.+?)__V__(?:__F__(\w+)__F__)?/g ,  ( match ,  type ,  v ,  f )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  varTypeFunc [ parseInt ( type ,  10 ) ] ( v ,  f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/ * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Get  the  actual  string  of  the  expression .  That  is  not  stored  in  the  tree  so  we  have  to  get  the  indexes  from  the  node 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  and  then  based  on  that  get  it  from  the  expression . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  @param  expr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  @param  node 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  function  getString ( expr : string ,  node : SyntaxNode  |  TreeCursor  |  null  |  undefined )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  '' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  returnVariables ( expr . substring ( node . from ,  node . to ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/ * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Create  simple  scalar  binary  op  object . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  @param  opDef  -  definition  of  the  op  to  be  created 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  @param  expr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  @param  numberNode  -  the  node  for  the  scalar 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  @param  hasBool  -  whether  operation  has  a  bool  modifier .  Is  used  only  for  ops  for  which  it  makes  sense . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  function  makeBinOp ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  opDef :  {  id : string ;  comparison? : boolean  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  expr : string , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  numberNode : SyntaxNode , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  hasBool : boolean 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  QueryBuilderOperation  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-24 00:54:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  const  params : QueryBuilderOperationParamValue [ ]  =  [ parseFloat ( getString ( expr ,  numberNode ) ) ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-02 00:33:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  if  ( opDef . comparison )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    params . push ( hasBool ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    id : opDef.id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    params , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-05 00:11:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								/ * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Get  all  nodes  with  type  in  the  tree .  This  traverses  the  tree  so  it  is  safe  only  when  you  know  there  shouldn ' t  be 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  too  much  nesting  but  you  just  want  to  skip  some  of  the  wrappers .  For  example  getting  function  args  this  way  would 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  not  be  safe  is  it  would  also  find  arguments  of  nested  functions . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  @param  expr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  @param  cur 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-03 22:57:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								 *  @param  type  -  can  be  string  or  number ,  some  data - sources  ( loki )  haven ' t  migrated  over  to  using  numeric  constants  defined  in  the  lezer  parsing  library  ( e . g .  lezer - promql ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  @todo  Remove  string  type  definition  when  all  data - sources  have  migrated  to  numeric  constants 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-05 00:11:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								 * / 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-03 22:57:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								export  function  getAllByType ( expr : string ,  cur : SyntaxNode ,  type :  number  |  string ) :  string [ ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( cur . type . id  ===  type  ||  cur . name  ===  type )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-05 00:11:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    return  [ getString ( expr ,  cur ) ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  values : string [ ]  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  let  pos  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  let  child  =  cur . childAfter ( pos ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  while  ( child )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    values . push ( . . . getAllByType ( expr ,  child ,  type ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pos  =  child . to ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    child  =  cur . childAfter ( pos ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  values ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-10 03:54:51 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								/ * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  There  aren 't any spaces in the metric names, so let' s  introduce  a  wildcard  into  the  regex  for  each  space  to  better  facilitate  a  fuzzy  search 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  const  regexifyLabelValuesQueryString  =  ( query : string )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  queryArray  =  query . split ( ' ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  queryArray . map ( ( query )  = >  ` ${ query } .* ` ) . join ( '' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ;