From 307e17e8d6da9597de561b897e6b6c173e831ad3 Mon Sep 17 00:00:00 2001 From: bkellam Date: Mon, 17 Nov 2025 18:47:13 -0800 Subject: [PATCH] support search contexts --- packages/queryLanguage/src/parser.terms.ts | 21 +++++++------- packages/queryLanguage/src/parser.ts | 16 +++++----- packages/queryLanguage/src/query.grammar | 5 +++- packages/queryLanguage/test/negation.txt | 8 +++++ packages/queryLanguage/test/prefixes.txt | 16 ++++++++++ .../app/api/(server)/stream_search/route.ts | 24 +++++++++++++-- .../api/(server)/stream_search/transformer.ts | 29 +++++++++++++++---- 7 files changed, 92 insertions(+), 27 deletions(-) diff --git a/packages/queryLanguage/src/parser.terms.ts b/packages/queryLanguage/src/parser.terms.ts index 7be7ac7a..1682bb04 100644 --- a/packages/queryLanguage/src/parser.terms.ts +++ b/packages/queryLanguage/src/parser.terms.ts @@ -1,6 +1,6 @@ // This file was generated by lezer-generator. You probably shouldn't edit it. export const - negate = 21, + negate = 22, Program = 1, OrExpr = 2, AndExpr = 3, @@ -9,12 +9,13 @@ export const ArchivedExpr = 6, RevisionExpr = 7, ContentExpr = 8, - FileExpr = 9, - ForkExpr = 10, - VisibilityExpr = 11, - RepoExpr = 12, - LangExpr = 13, - SymExpr = 14, - RepoSetExpr = 15, - ParenExpr = 16, - Term = 17 + ContextExpr = 9, + FileExpr = 10, + ForkExpr = 11, + VisibilityExpr = 12, + RepoExpr = 13, + LangExpr = 14, + SymExpr = 15, + RepoSetExpr = 16, + ParenExpr = 17, + Term = 18 diff --git a/packages/queryLanguage/src/parser.ts b/packages/queryLanguage/src/parser.ts index 7a0a698b..fb867c4f 100644 --- a/packages/queryLanguage/src/parser.ts +++ b/packages/queryLanguage/src/parser.ts @@ -3,16 +3,16 @@ import {LRParser} from "@lezer/lr" import {negateToken} from "./tokens" export const parser = LRParser.deserialize({ version: 14, - states: "'OOVQROOO!TQQO'#CcO!TQQO'#CdO!TQQO'#CeO!]QSO'#CfO!hQSO'#CgO!TQQO'#ChO!TQQO'#CiO!TQQO'#CjO!TQQO'#CkOOQP'#Ca'#CaOVQRO'#ClO!sQQO'#C`OOQP'#Cm'#CmOOQP'#Cv'#CvO#hQRO'#CuO#uQQO'#CuO$QQQO'#C^OOQO'#Ct'#CtQOQQOOO!]QSO'#CbOOQP'#C|'#C|OOQP,58},58}OOQP,59O,59OOOQP,59P,59POOQP'#DS'#DSOOQP,59Q,59QOOQP'#DU'#DUOOQP,59R,59ROOQP,59S,59SOOQP,59T,59TOOQP,59U,59UOOQP,59V,59VO$VQQO,59WOOQP,58z,58zOOQP'#Cn'#CnO$[QRO,58yOVQRO'#CoO$iQQO,58xOOQP,58|,58|OOQP1G.r1G.rOOQP-E6l-E6lO$tQRO'#CuOOQO'#Cu'#CuOOQO,59Z,59ZOOQO-E6m-E6m", - stateData: "%b~OgOS~Oe[OkdOoPOq]Or]OsQOtROuSOwTO|UO}VO!OWO!PXO!QZO~OqeOreO~OliOmiOniO~OykOzkO{kO~OkdOoPOsQOtROuSOwTO|UO}VO!OWO!PXO!QZO~OdhX!SiX!RhX~PVOdhX!SiX!RhX~O!SuO~O!RxO~OdRa!SRa!RRa~PVO!SuOdQa!RQa~OdiX!SiX!RiX~PVOqkostuw|}!O!P!Srw~", - goto: "$ZyPPz!O!V!_!j!j!j!j!j!j!j!j!j!j!_!V!s!zPPPP#Q#W#_PPPPP#kPPPPP$QP$WTbOZS`OZR{u]^OZ_tuz[^OZ_tuzRr[_YOZ[_tuzSt_zRytQvaR}vQcORqZSaOZR|uS_OZUs_tzRzuQfPQgQQhRQmUQnVQoWRpXQjSRwdRlT", - nodeNames: "⚠ Program OrExpr AndExpr NegateExpr PrefixExpr ArchivedExpr RevisionExpr ContentExpr FileExpr ForkExpr VisibilityExpr RepoExpr LangExpr SymExpr RepoSetExpr ParenExpr Term", - maxTerm: 50, + states: "'[OVQROOO!WQQO'#CcO!WQQO'#CdO!WQQO'#CeO!WQQO'#CfO!`QSO'#CgO!kQSO'#ChO!WQQO'#CiO!WQQO'#CjO!WQQO'#CkO!WQQO'#ClOOQP'#Ca'#CaOVQRO'#CmO!vQQO'#C`OOQP'#Cn'#CnOOQP'#Cw'#CwO#nQRO'#CvO#{QQO'#CvO$WQQO'#C^OOQO'#Cu'#CuQOQQOOO!`QSO'#CbOOQP'#C}'#C}OOQP,58},58}OOQP,59O,59OOOQP,59P,59POOQP,59Q,59QOOQP'#DU'#DUOOQP,59R,59ROOQP'#DW'#DWOOQP,59S,59SOOQP,59T,59TOOQP,59U,59UOOQP,59V,59VOOQP,59W,59WO$]QQO,59XOOQP,58z,58zOOQP'#Co'#CoO$bQRO,58yOVQRO'#CpO$oQQO,58xOOQP,58|,58|OOQP1G.s1G.sOOQP-E6m-E6mO$zQRO'#CvOOQO'#Cv'#CvOOQO,59[,59[OOQO-E6n-E6n", + stateData: "%i~OhOS~Of]OleOpPOr^Os^OtQOuROvSOwTOyUO!OVO!PWO!QXO!RYO!S[O~OrfOsfO~OmkOnkOokO~O{mO|mO}mO~OleOpPOtQOuROvSOwTOyUO!OVO!PWO!QXO!RYO!S[O~OeiX!UjX!TiX~PVOeiX!UjX!TiX~O!UwO~O!TzO~OeRa!URa!TRa~PVO!UwOeQa!TQa~OejX!UjX!TjX~PVOrlptuvwy!O!P!Q!R!Usy~", + goto: "$`{PP|!Q!X!a!l!l!l!l!l!l!l!l!l!l!l!a!X!u!|PPPP#S#Y#aPPPPP#mPPPPPP$VP$]TcO[SaO[R}w]_O[`vw|[_O[`vw|Rt]_ZO[]`vw|Sv`|R{vQxbR!PxQdORs[SbO[R!OwS`O[Uu`v|R|wQgPQhQQiRQjSQoVQpWQqXRrYQlTRyeRnU", + nodeNames: "⚠ Program OrExpr AndExpr NegateExpr PrefixExpr ArchivedExpr RevisionExpr ContentExpr ContextExpr FileExpr ForkExpr VisibilityExpr RepoExpr LangExpr SymExpr RepoSetExpr ParenExpr Term", + maxTerm: 52, skippedNodes: [0], repeatNodeCount: 2, - tokenData: "!Em~RpOX#VXY$TYZ$TZp#Vpq$Tqr#Vrs$csx#Vxy&Vyz&[z#T#V#T#U&a#U#V#V#V#W0q#W#Y#V#Y#Z8V#Z#`#V#`#a@e#a#b#V#b#cEP#c#dFw#d#eMa#e#f#V#f#g!*u#g#h!4{#h#j#V#j#k!8i#k#m#V#m#n!Bw#n;'S#V;'S;=`#}<%lO#VP#[ZrPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#VP$QP;=`<%l#V~$YRg~XY$TYZ$Tpq$T~$fWOY$cZr$crs%Os#O$c#O#P%T#P;'S$c;'S;=`&P<%lO$c~%TOq~~%WRO;'S$c;'S;=`%a;=`O$c~%dXOY$cZr$crs%Os#O$c#O#P%T#P;'S$c;'S;=`&P;=`<%l$c<%lO$c~&SP;=`<%l$c~&[O!Q~~&aO!R~~&f_rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#b#V#b#c'e#c#f#V#f#g)]#g;'S#V;'S;=`#}<%lO#VR'j]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#m#V#m#n(c#n;'S#V;'S;=`#}<%lO#VR(jZ{QrPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#V~)b]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#V#V#V#W*Z#W;'S#V;'S;=`#}<%lO#V~*`]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#[#V#[#]+X#];'S#V;'S;=`#}<%lO#V~+^]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#]#V#]#^,V#^;'S#V;'S;=`#}<%lO#V~,[]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#j#V#j#k-T#k;'S#V;'S;=`#}<%lO#V~-Y]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#X#V#X#Y.R#Y;'S#V;'S;=`#}<%lO#V~.W]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#W#V#W#X/P#X;'S#V;'S;=`#}<%lO#V~/UZrPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]/w!];'S#V;'S;=`#}<%lO#V~0OZk~rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#V~0v]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]1o!]#c#V#c#d2i#d;'S#V;'S;=`#}<%lO#V~1vZs~rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#V~2n]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#b#V#b#c3g#c;'S#V;'S;=`#}<%lO#V~3l]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#h#V#h#i4e#i;'S#V;'S;=`#}<%lO#V~4j]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#X#V#X#Y5c#Y;'S#V;'S;=`#}<%lO#V~5h]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#b#V#b#c6a#c;'S#V;'S;=`#}<%lO#V~6f]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#h#V#h#i7_#i;'S#V;'S;=`#}<%lO#V~7dZrPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]1o!];'S#V;'S;=`#}<%lO#V~8[_rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]9Z!]#]#V#]#^:T#^#c#V#c#ds#`;'S#V;'S;=`#}<%lO#V~>xZrPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]?k!];'S#V;'S;=`#}<%lO#V~?rZu~rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#V~@j]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#T#V#T#UAc#U;'S#V;'S;=`#}<%lO#V~Ah]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#b#V#b#cBa#c;'S#V;'S;=`#}<%lO#V~Bf]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#Z#V#Z#[C_#[;'S#V;'S;=`#}<%lO#V~CdZrPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]DV!];'S#V;'S;=`#}<%lO#V~D^Z}~rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#VREU]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#c#V#c#dE}#d;'S#V;'S;=`#}<%lO#VRFUZmQrPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#V~F|_rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#b#V#b#cG{#c#f#V#f#gJq#g;'S#V;'S;=`#}<%lO#VRHQ]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#`#V#`#aHy#a;'S#V;'S;=`#}<%lO#VRIO]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#m#V#m#nIw#n;'S#V;'S;=`#}<%lO#VRJOZnQrPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#V~JvfrPOXL[XZMUZpL[pqMUqrL[rsMUsxL[xzMUz}L[}!OL[!O!QL[!Q![#V![!]L[!]!cL[!c!}#V!}#RL[#R#S#V#S#TL[#T#o#V#o;'SL[;'S;=`MZ<%lOL[~LcZ!S~rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#V~MZO!S~~M^P;=`<%lL[RMf_rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#f#V#f#gNe#g#i#V#i#j!&T#j;'S#V;'S;=`#}<%lO#VRNj]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#]#V#]#^! c#^;'S#V;'S;=`#}<%lO#VR! h]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#j#V#j#k!!a#k;'S#V;'S;=`#}<%lO#VR!!f]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#T#V#T#U!#_#U;'S#V;'S;=`#}<%lO#VR!#d]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#h#V#h#i!$]#i;'S#V;'S;=`#}<%lO#VR!$b]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#X#V#X#Y!%Z#Y;'S#V;'S;=`#}<%lO#VR!%bZzQrPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#VR!&Y]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#U#V#U#V!'R#V;'S#V;'S;=`#}<%lO#VR!'W]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#`#V#`#a!(P#a;'S#V;'S;=`#}<%lO#VR!(U]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#]#V#]#^!(}#^;'S#V;'S;=`#}<%lO#VR!)S]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#V#V#V#W!){#W;'S#V;'S;=`#}<%lO#VR!*SZyQrPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#V~!*z]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]!+s!]#X#V#X#Y!,m#Y;'S#V;'S;=`#}<%lO#V~!+zZ|~rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#V~!,r_rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#d#V#d#e!-q#e#j#V#j#k!3Z#k;'S#V;'S;=`#}<%lO#V~!-v]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#c#V#c#d!.o#d;'S#V;'S;=`#}<%lO#V~!.t]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]!+s!]#g#V#g#h!/m#h;'S#V;'S;=`#}<%lO#V~!/r]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#X#V#X#Y!0k#Y;'S#V;'S;=`#}<%lO#V~!0p]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#h#V#h#i!1i#i;'S#V;'S;=`#}<%lO#V~!1nZrPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]!2a!];'S#V;'S;=`#}<%lO#V~!2hZ!P~rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#V~!3`ZrPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]!4R!];'S#V;'S;=`#}<%lO#V~!4YZo~rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#V~!5Q]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#m#V#m#n!5y#n;'S#V;'S;=`#}<%lO#V~!6O]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#a#V#a#b!6w#b;'S#V;'S;=`#}<%lO#V~!6|ZrPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]!7o!];'S#V;'S;=`#}<%lO#V~!7vZ!O~rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#V~!8n]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#]#V#]#^!9g#^;'S#V;'S;=`#}<%lO#V~!9l]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#g#V#g#h!:e#h;'S#V;'S;=`#}<%lO#V~!:j]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#]#V#]#^!;c#^;'S#V;'S;=`#}<%lO#V~!;h]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#U#V#U#V!]#a;'S#V;'S;=`#}<%lO#V~!>b]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#]#V#]#^!?Z#^;'S#V;'S;=`#}<%lO#V~!?`]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#h#V#h#i!@X#i;'S#V;'S;=`#}<%lO#V~!@^]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#m#V#m#n!AV#n;'S#V;'S;=`#}<%lO#V~!A[ZrPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]!A}!];'S#V;'S;=`#}<%lO#V~!BUZw~rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#VR!B|]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#X#V#X#Y!Cu#Y;'S#V;'S;=`#}<%lO#VR!Cz]rPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#g#V#g#h!Ds#h;'S#V;'S;=`#}<%lO#VR!DzZlQrPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#V", + tokenData: "!Hc~RpOX#VXY$TYZ$TZp#Vpq$Tqr#Vrs$csx#Vxy&Vyz&[z#T#V#T#U&a#U#V#V#V#W0q#W#Y#V#Y#Z:{#Z#`#V#`#aCZ#a#b#V#b#cGu#c#dIm#d#e!!V#e#f#V#f#g!-k#g#h!7q#h#j#V#j#k!;_#k#m#V#m#n!Em#n;'S#V;'S;=`#}<%lO#VP#[ZsPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#VP$QP;=`<%l#V~$YRh~XY$TYZ$Tpq$T~$fWOY$cZr$crs%Os#O$c#O#P%T#P;'S$c;'S;=`&P<%lO$c~%TOr~~%WRO;'S$c;'S;=`%a;=`O$c~%dXOY$cZr$crs%Os#O$c#O#P%T#P;'S$c;'S;=`&P;=`<%l$c<%lO$c~&SP;=`<%l$c~&[O!S~~&aO!T~~&f_sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#b#V#b#c'e#c#f#V#f#g)]#g;'S#V;'S;=`#}<%lO#VR'j]sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#m#V#m#n(c#n;'S#V;'S;=`#}<%lO#VR(jZ}QsPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#V~)b]sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#V#V#V#W*Z#W;'S#V;'S;=`#}<%lO#V~*`]sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#[#V#[#]+X#];'S#V;'S;=`#}<%lO#V~+^]sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#]#V#]#^,V#^;'S#V;'S;=`#}<%lO#V~,[]sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#j#V#j#k-T#k;'S#V;'S;=`#}<%lO#V~-Y]sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#X#V#X#Y.R#Y;'S#V;'S;=`#}<%lO#V~.W]sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#W#V#W#X/P#X;'S#V;'S;=`#}<%lO#V~/UZsPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]/w!];'S#V;'S;=`#}<%lO#V~0OZl~sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#V~0v]sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]1o!]#c#V#c#d2i#d;'S#V;'S;=`#}<%lO#V~1vZt~sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#V~2n]sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#b#V#b#c3g#c;'S#V;'S;=`#}<%lO#V~3l]sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#h#V#h#i4e#i;'S#V;'S;=`#}<%lO#V~4j]sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#X#V#X#Y5c#Y;'S#V;'S;=`#}<%lO#V~5h_sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#b#V#b#c6g#c#l#V#l#m8]#m;'S#V;'S;=`#}<%lO#V~6l]sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#h#V#h#i7e#i;'S#V;'S;=`#}<%lO#V~7jZsPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]1o!];'S#V;'S;=`#}<%lO#V~8b]sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#h#V#h#i9Z#i;'S#V;'S;=`#}<%lO#V~9`ZsPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]:R!];'S#V;'S;=`#}<%lO#V~:YZu~sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#V~;Q_sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]u#Y;'S#V;'S;=`#}<%lO#V~>zZsPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]X#^;'S#V;'S;=`#}<%lO#V~!>^]sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#U#V#U#V!?V#V;'S#V;'S;=`#}<%lO#V~!?[]sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#]#V#]#^!@T#^;'S#V;'S;=`#}<%lO#V~!@Y]sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#`#V#`#a!AR#a;'S#V;'S;=`#}<%lO#V~!AW]sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#]#V#]#^!BP#^;'S#V;'S;=`#}<%lO#V~!BU]sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#h#V#h#i!B}#i;'S#V;'S;=`#}<%lO#V~!CS]sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#m#V#m#n!C{#n;'S#V;'S;=`#}<%lO#V~!DQZsPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]!Ds!];'S#V;'S;=`#}<%lO#V~!DzZy~sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#VR!Er]sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#X#V#X#Y!Fk#Y;'S#V;'S;=`#}<%lO#VR!Fp]sPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!]#g#V#g#h!Gi#h;'S#V;'S;=`#}<%lO#VR!GpZmQsPOX#VZp#Vqr#Vsx#Vz}#V}!O#V!O![#V![!]#V!];'S#V;'S;=`#}<%lO#V", tokenizers: [negateToken, 0, 1], topRules: {"Program":[0,1]}, - tokenPrec: 187, - termNames: {"0":"⚠","1":"@top","2":"OrExpr","3":"AndExpr","4":"NegateExpr","5":"PrefixExpr","6":"ArchivedExpr","7":"RevisionExpr","8":"ContentExpr","9":"FileExpr","10":"ForkExpr","11":"VisibilityExpr","12":"RepoExpr","13":"LangExpr","14":"SymExpr","15":"RepoSetExpr","16":"ParenExpr","17":"Term","18":"expr+","19":"(or andExpr)+","20":"␄","21":"negate","22":"%mainskip","23":"space","24":"query","25":"andExpr","26":"expr","27":"archivedKw","28":"\"yes\"","29":"\"no\"","30":"\"only\"","31":"revisionKw","32":"value","33":"quotedString","34":"word","35":"contentKw","36":"fileKw","37":"forkKw","38":"forkValue","39":"visibilityKw","40":"visibilityValue","41":"\"public\"","42":"\"private\"","43":"\"any\"","44":"repoKw","45":"langKw","46":"symKw","47":"reposetKw","48":"\"(\"","49":"\")\"","50":"or"} + tokenPrec: 193, + termNames: {"0":"⚠","1":"@top","2":"OrExpr","3":"AndExpr","4":"NegateExpr","5":"PrefixExpr","6":"ArchivedExpr","7":"RevisionExpr","8":"ContentExpr","9":"ContextExpr","10":"FileExpr","11":"ForkExpr","12":"VisibilityExpr","13":"RepoExpr","14":"LangExpr","15":"SymExpr","16":"RepoSetExpr","17":"ParenExpr","18":"Term","19":"expr+","20":"(or andExpr)+","21":"␄","22":"negate","23":"%mainskip","24":"space","25":"query","26":"andExpr","27":"expr","28":"archivedKw","29":"\"yes\"","30":"\"no\"","31":"\"only\"","32":"revisionKw","33":"value","34":"quotedString","35":"word","36":"contentKw","37":"contextKw","38":"fileKw","39":"forkKw","40":"forkValue","41":"visibilityKw","42":"visibilityValue","43":"\"public\"","44":"\"private\"","45":"\"any\"","46":"repoKw","47":"langKw","48":"symKw","49":"reposetKw","50":"\"(\"","51":"\")\"","52":"or"} }) diff --git a/packages/queryLanguage/src/query.grammar b/packages/queryLanguage/src/query.grammar index 4058d543..66c0ee83 100644 --- a/packages/queryLanguage/src/query.grammar +++ b/packages/queryLanguage/src/query.grammar @@ -35,6 +35,7 @@ PrefixExpr { ArchivedExpr | RevisionExpr | ContentExpr | + ContextExpr | FileExpr | ForkExpr | VisibilityExpr | @@ -46,6 +47,7 @@ PrefixExpr { RevisionExpr { revisionKw value } ContentExpr { contentKw value } +ContextExpr { contextKw value } FileExpr { fileKw value } RepoExpr { repoKw value } LangExpr { langKw value } @@ -71,6 +73,7 @@ value { quotedString | word } archivedKw { "archived:" } revisionKw { "rev:" } contentKw { "content:" | "c:" } + contextKw { "context:" } fileKw { "file:" | "f:" } forkKw { "fork:" } visibilityKw { "visibility:" } @@ -91,7 +94,7 @@ value { quotedString | word } @precedence { quotedString, - archivedKw, revisionKw, contentKw, fileKw, + archivedKw, revisionKw, contentKw, contextKw, fileKw, forkKw, visibilityKw, repoKw, langKw, symKw, reposetKw, or, word diff --git a/packages/queryLanguage/test/negation.txt b/packages/queryLanguage/test/negation.txt index 98a8f0c6..716da115 100644 --- a/packages/queryLanguage/test/negation.txt +++ b/packages/queryLanguage/test/negation.txt @@ -94,6 +94,14 @@ Program(NegateExpr(PrefixExpr(ForkExpr))) Program(NegateExpr(PrefixExpr(VisibilityExpr))) +# Negate context prefix + +-context:backend + +==> + +Program(NegateExpr(PrefixExpr(ContextExpr))) + # Negate symbol prefix -sym:OldClass diff --git a/packages/queryLanguage/test/prefixes.txt b/packages/queryLanguage/test/prefixes.txt index 06e43528..00533ec0 100644 --- a/packages/queryLanguage/test/prefixes.txt +++ b/packages/queryLanguage/test/prefixes.txt @@ -102,6 +102,14 @@ visibility:public Program(PrefixExpr(VisibilityExpr)) +# Context prefix + +context:web + +==> + +Program(PrefixExpr(ContextExpr)) + # Symbol prefix sym:MyClass @@ -302,6 +310,14 @@ content:@Component Program(PrefixExpr(ContentExpr)) +# Context with underscores + +context:data_engineering + +==> + +Program(PrefixExpr(ContextExpr)) + # Prefix in parentheses (file:test.js) diff --git a/packages/web/src/app/api/(server)/stream_search/route.ts b/packages/web/src/app/api/(server)/stream_search/route.ts index 96846fa5..4b267922 100644 --- a/packages/web/src/app/api/(server)/stream_search/route.ts +++ b/packages/web/src/app/api/(server)/stream_search/route.ts @@ -18,6 +18,7 @@ import { NextRequest } from 'next/server'; import * as path from 'path'; import { parser as _parser } from '@sourcebot/query-language'; import { transformToZoektQuery } from './transformer'; +import { SINGLE_TENANT_ORG_ID } from '@/lib/constants'; const logger = createLogger('streamSearchApi'); @@ -78,14 +79,33 @@ export const POST = async (request: NextRequest) => { const parser = _parser.configure({ strict: true, - }) + }); const tree = parser.parse(query); - const zoektQuery = transformToZoektQuery({ + const zoektQuery = await transformToZoektQuery({ tree, input: query, isCaseSensitivityEnabled, isRegexEnabled, + onExpandSearchContext: async (contextName: string) => { + const context = await prisma.searchContext.findUnique({ + where: { + name_orgId: { + name: contextName, + orgId: SINGLE_TENANT_ORG_ID, + } + }, + include: { + repos: true, + } + }); + + if (!context) { + throw new Error(`Search context "${contextName}" not found`); + } + + return context.repos.map((repo) => repo.name); + }, }); console.log(JSON.stringify(zoektQuery, null, 2)); diff --git a/packages/web/src/app/api/(server)/stream_search/transformer.ts b/packages/web/src/app/api/(server)/stream_search/transformer.ts index 2fa35edf..caf71a51 100644 --- a/packages/web/src/app/api/(server)/stream_search/transformer.ts +++ b/packages/web/src/app/api/(server)/stream_search/transformer.ts @@ -12,6 +12,7 @@ import { RepoExpr, RevisionExpr, ContentExpr, + ContextExpr, LangExpr, SymExpr, ArchivedExpr, @@ -44,14 +45,16 @@ export const transformToZoektQuery = ({ input, isCaseSensitivityEnabled, isRegexEnabled, + onExpandSearchContext, }: { tree: Tree; input: string; isCaseSensitivityEnabled: boolean; isRegexEnabled: boolean; -}): Q => { + onExpandSearchContext: (contextName: string) => Promise; +}): Promise => { - const transformNode = (node: SyntaxNode): Q => { + const transformNode = async (node: SyntaxNode): Promise => { switch (node.type.id) { case Program: { // Program wraps the actual query - transform its child @@ -65,7 +68,7 @@ export const transformToZoektQuery = ({ case AndExpr: return { and: { - children: getChildren(node).map(c => transformNode(c)) + children: await Promise.all(getChildren(node).map(c => transformNode(c))) }, query: "and" } @@ -73,7 +76,7 @@ export const transformToZoektQuery = ({ case OrExpr: return { or: { - children: getChildren(node).map(c => transformNode(c)) + children: await Promise.all(getChildren(node).map(c => transformNode(c))) }, query: "or" }; @@ -86,7 +89,7 @@ export const transformToZoektQuery = ({ } return { not: { - child: transformNode(negateChild) + child: await transformNode(negateChild) }, query: "not" }; @@ -130,7 +133,7 @@ export const transformToZoektQuery = ({ } } - const transformPrefixExpr = (node: SyntaxNode): Q => { + const transformPrefixExpr = async (node: SyntaxNode): Promise => { // Find which specific prefix type this is const prefixNode = node.firstChild; if (!prefixNode) { @@ -189,6 +192,7 @@ export const transformToZoektQuery = ({ query: "substring" }; + case LangExpr: return { language: { @@ -287,6 +291,19 @@ export const transformToZoektQuery = ({ }; } + case ContextExpr: { + const repoNames = await onExpandSearchContext(value); + return { + repo_set: { + set: repoNames.reduce((acc, s) => { + acc[s.trim()] = true; + return acc; + }, {} as Record) + }, + query: "repo_set" + }; + } + case RepoSetExpr: { return { repo_set: {