feat(promql): typed PromQL parser, AST builders, and deparser#95
Merged
Conversation
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a new dependency-free package
promql(naked npm name, confirmed available) to the dev-utils monorepo, following the exact shape of the sibling AST packages (nginx-ast,toml-ast,bash-ast,docker-parser):lexer → parser → deparser → types → clean+ parser/deparser/roundtrip tests,makagebuild, published to npm.Motivation: composing PromQL with template strings is error-prone (label escaping, operator precedence, parentheses). This package lets you build queries as a typed AST and render them safely.
What's in it
lexer.ts— bracket-aware tokenizer.:is a subquery separator inside[...]but part of a (recording-rule) metric name outside it; durations (5m,1h30m,100ms) vs numbers (5,5e3) disambiguated at lex time.parser.ts— precedence-climbing parser: vector/matrix selectors, subqueries,offset/@modifiers, unary, binary ops (withbool+on/ignoring/group_left/group_rightvector matching), aggregations (grouping clause accepted both beforesum by (x) (...)and aftersum(...) by (x), plustopk/bottomk/quantile/count_valuesparams), function calls,Inf/NaN.deparser.ts— AST → canonical PromQL. Inserts parentheses from operator precedence, so ASTs built by hand (no explicitParenExpr) still render to a string that reparses to the same tree.builders.ts— the ergonomic layer the other packages don't have:metric/selector/eq/neq/re/nre,range/subquery,rate/irate/increase/*_over_time,sum/min/max/avg/count/... + topk/bottomk/quantile/countValues,by/without,add/sub/mul/.../and/or/unless,on/ignoring,offset/at.clean.ts—cleanTree/astEqual/printAst.Note on the
rangefield nameThe sibling packages use
rangeonBaseNodefor source position. PromQL's ownrange(the[5m]duration on matrix selectors / subqueries) collides with that, andcleanTreewas stripping it. Resolved by naming the position fieldloc(still stripped bycleanTree) and keeping the idiomatic semanticrangefield intact.Tests / CI
^right-assoc,bool+matching, subqueries, modifiers, colon metric names.tsc --noEmitclean;makage build(CJS+ESM) clean.promqlto the CI test matrix in.github/workflows/ci.yml.Lint note:
eslint .fails repo-wide because ESLint 9 is installed while the repo still uses legacy.eslintrc.json(same for all sibling packages); CI does not run a lint step. Not addressed here as it's a repo-wide config issue.Follow-up (separate PR)
Refactor the
constructive-dbcompute-usage-collectorto build its namespace CPU/memory PromQL via these builders +deparse()instead of template literals (it already consumes dev-utils packages from npm, e.g.schema-typescript).Link to Devin session: https://app.devin.ai/sessions/16409487e97d44828dfb46277767604b
Requested by: @pyramation