TSQL initial commit

This commit is contained in:
Matt Aitken
2025-11-28 16:48:27 +00:00
parent acc10e847c
commit 459a179ef3
9 changed files with 986 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
# Generated ANTLR parser files
src/generated/
+15
View File
@@ -0,0 +1,15 @@
# TSQL (TriggerSQL)
TriggerSQL is a DSL that is safely converted into ClickHouse SQL queries with protection against SQL injection and it's tenant-safe (users can only query their own data).
## ANTLR Grammar
The ANTLR grammer is heavily inspired by [PostHog's HogQL](https://github.com/PostHog/posthog/tree/master/posthog/hogql).
These are found in [./grammar] and are the `.g4` files.
## Generating the source code
```sh
pnpm run grammar:build
```
+18
View File
@@ -0,0 +1,18 @@
{
"name": "@internal/tsql",
"private": true,
"version": "0.0.1",
"main": "./src/index.ts",
"types": "./src/index.ts",
"type": "module",
"dependencies": {
"@trigger.dev/core": "workspace:*"
},
"scripts": {
"typecheck": "tsc --noEmit",
"grammar:build": "antlr4 -Dlanguage=TypeScript -visitor -o src/generated src/grammar/*.g4"
},
"devDependencies": {
"antlr4ts": "0.5.0-alpha.4"
}
}
@@ -0,0 +1,288 @@
lexer grammar TSQLLexer;
// NB! We cat TSQLLexter.typescript.g4 when generating the grammar.
// NOTE: don't forget to add new keywords to the parser rule "keyword"!
// Keywords
ALL: A L L;
AND: A N D;
ANTI: A N T I;
ANY: A N Y;
ARRAY: A R R A Y;
AS: A S;
ASCENDING: A S C | A S C E N D I N G;
ASOF: A S O F;
BETWEEN: B E T W E E N;
BOTH: B O T H;
BY: B Y;
CASE: C A S E;
CAST: C A S T;
CATCH: C A T C H;
COHORT: C O H O R T;
COLLATE: C O L L A T E;
CROSS: C R O S S;
CUBE: C U B E;
CURRENT: C U R R E N T;
DATE: D A T E;
DAY: D A Y;
DESC: D E S C;
DESCENDING: D E S C E N D I N G;
DISTINCT: D I S T I N C T;
ELSE: E L S E;
END: E N D;
EXCEPT: E X C E P T;
EXTRACT: E X T R A C T;
FINAL: F I N A L;
FINALLY: F I N A L L Y;
FIRST: F I R S T;
FN: F N;
FOLLOWING: F O L L O W I N G;
FOR: F O R;
FROM: F R O M;
FULL: F U L L;
FUN: F U N;
GROUP: G R O U P;
HAVING: H A V I N G;
HOUR: H O U R;
ID: I D;
IF: I F;
ILIKE: I L I K E;
IN: I N;
INF: I N F | I N F I N I T Y;
INNER: I N N E R;
INTERSECT: I N T E R S E C T;
INTERVAL: I N T E R V A L;
IS: I S;
JOIN: J O I N;
KEY: K E Y;
LAST: L A S T;
LEADING: L E A D I N G;
LEFT: L E F T;
LET: L E T;
LIKE: L I K E;
LIMIT: L I M I T;
MINUTE: M I N U T E;
MONTH: M O N T H;
NAN_SQL: N A N; // conflicts with macro NAN
NOT: N O T;
NULL_SQL: N U L L; // conflicts with macro NULL
NULLS: N U L L S;
OFFSET: O F F S E T;
ON: O N;
OR: O R;
ORDER: O R D E R;
OUTER: O U T E R;
OVER: O V E R;
PARTITION: P A R T I T I O N;
PRECEDING: P R E C E D I N G;
PREWHERE: P R E W H E R E;
QUARTER: Q U A R T E R;
RANGE: R A N G E;
RETURN: R E T U R N;
RIGHT: R I G H T;
ROLLUP: R O L L U P;
ROW: R O W;
ROWS: R O W S;
SAMPLE: S A M P L E;
SECOND: S E C O N D;
SELECT: S E L E C T;
SEMI: S E M I;
SETTINGS: S E T T I N G S;
SUBSTRING: S U B S T R I N G;
THEN: T H E N;
THROW: T H R O W;
TIES: T I E S;
TIMESTAMP: T I M E S T A M P;
TO: T O;
TOP: T O P;
TOTALS: T O T A L S;
TRAILING: T R A I L I N G;
TRIM: T R I M;
TRUNCATE: T R U N C A T E;
TRY: T R Y;
UNBOUNDED: U N B O U N D E D;
UNION: U N I O N;
USING: U S I N G;
WEEK: W E E K;
WHEN: W H E N;
WHERE: W H E R E;
WHILE: W H I L E;
WINDOW: W I N D O W;
WITH: W I T H;
YEAR: Y E A R | Y Y Y Y;
// Tokens
// copied from clickhouse_driver/util/escape.py
ESCAPE_CHAR_COMMON
: BACKSLASH B
| BACKSLASH F
| BACKSLASH R
| BACKSLASH N
| BACKSLASH T
| BACKSLASH '0'
| BACKSLASH A
| BACKSLASH V
| BACKSLASH BACKSLASH;
IDENTIFIER
: (LETTER | UNDERSCORE | DOLLAR) (LETTER | UNDERSCORE | DEC_DIGIT | DOLLAR)*
| BACKQUOTE ( ~([\\`]) | ESCAPE_CHAR_COMMON | BACKSLASH QUOTE_SINGLE | (BACKQUOTE BACKQUOTE) )* BACKQUOTE
| QUOTE_DOUBLE ( ~([\\"]) | ESCAPE_CHAR_COMMON | BACKSLASH QUOTE_DOUBLE | (QUOTE_DOUBLE QUOTE_DOUBLE) )* QUOTE_DOUBLE
;
FLOATING_LITERAL
: HEXADECIMAL_LITERAL DOT HEX_DIGIT* (P | E) (PLUS | DASH)? DEC_DIGIT+
| HEXADECIMAL_LITERAL (P | E) (PLUS | DASH)? DEC_DIGIT+
| DECIMAL_LITERAL DOT DEC_DIGIT* E (PLUS | DASH)? DEC_DIGIT+
| DOT DECIMAL_LITERAL E (PLUS | DASH)? DEC_DIGIT+
| DECIMAL_LITERAL E (PLUS | DASH)? DEC_DIGIT+
;
OCTAL_LITERAL: '0' OCT_DIGIT+;
DECIMAL_LITERAL: DEC_DIGIT+;
HEXADECIMAL_LITERAL: '0' X HEX_DIGIT+;
// It's important that quote-symbol is a single character.
STRING_LITERAL: QUOTE_SINGLE ( ~([\\']) | ESCAPE_CHAR_COMMON | BACKSLASH QUOTE_SINGLE | (QUOTE_SINGLE QUOTE_SINGLE) )* QUOTE_SINGLE;
// Alphabet and allowed symbols
fragment A: [aA];
fragment B: [bB];
fragment C: [cC];
fragment D: [dD];
fragment E: [eE];
fragment F: [fF];
fragment G: [gG];
fragment H: [hH];
fragment I: [iI];
fragment J: [jJ];
fragment K: [kK];
fragment L: [lL];
fragment M: [mM];
fragment N: [nN];
fragment O: [oO];
fragment P: [pP];
fragment Q: [qQ];
fragment R: [rR];
fragment S: [sS];
fragment T: [tT];
fragment U: [uU];
fragment V: [vV];
fragment W: [wW];
fragment X: [xX];
fragment Y: [yY];
fragment Z: [zZ];
fragment LETTER: [a-zA-Z];
fragment OCT_DIGIT: [0-7];
fragment DEC_DIGIT: [0-9];
fragment HEX_DIGIT: [0-9a-fA-F];
ARROW: '->';
ASTERISK: '*';
BACKQUOTE: '`';
BACKSLASH: '\\';
COLON: ':';
COMMA: ',';
CONCAT: '||';
DASH: '-';
DOLLAR: '$';
DOT: '.';
EQ_DOUBLE: '==';
EQ_SINGLE: '=';
GT_EQ: '>=';
GT: '>';
HASH: '#';
IREGEX_SINGLE: '~*';
IREGEX_DOUBLE: '=~*';
LBRACE: '{' -> pushMode(DEFAULT_MODE);
LBRACKET: '[';
LPAREN: '(';
LT_EQ: '<=';
TAG_LT_SLASH: '</' -> type(LT_SLASH), pushMode(TSQLX_TAG_CLOSE);
TAG_LT_OPEN: '<' {isOpeningTag()}? -> type(LT), pushMode(TSQLX_TAG_OPEN);
LT: '<';
LT_SLASH: '</';
NOT_EQ: '!=' | '<>';
NOT_IREGEX: '!~*';
NOT_REGEX: '!~';
NULL_PROPERTY: '?.';
NULLISH: '??';
PERCENT: '%';
PLUS: '+';
QUERY: '?';
QUOTE_DOUBLE: '"';
QUOTE_SINGLE_TEMPLATE: 'f\'' -> pushMode(IN_TEMPLATE_STRING); // start of regular f'' template strings
QUOTE_SINGLE_TEMPLATE_FULL: 'F\'' -> pushMode(IN_FULL_TEMPLATE_STRING); // magic F' symbol used to parse "full text" templates
QUOTE_SINGLE: '\'';
REGEX_SINGLE: '~';
REGEX_DOUBLE: '=~';
RBRACE: '}' -> popMode;
RBRACKET: ']';
RPAREN: ')';
SEMICOLON: ';';
SLASH: '/';
SLASH_GT: '/>';
UNDERSCORE: '_';
// Comments and whitespace
MULTI_LINE_COMMENT: '/*' .*? '*/' -> skip;
SINGLE_LINE_COMMENT: ('--' | '//') ~('\n'|'\r')* ('\n' | '\r' | EOF) -> skip;
// whitespace is hidden and not skipped so that it's preserved in ANTLR errors like "no viable alternative"
WHITESPACE: [ \u000B\u000C\t\r\n] -> channel(HIDDEN);
// ───────── f' TEMPLATE STRING MODE ─────────
mode IN_TEMPLATE_STRING;
STRING_TEXT: ((~([\\'{])) | ESCAPE_CHAR_COMMON | BACKSLASH QUOTE_SINGLE | (BACKSLASH LBRACE) | (QUOTE_SINGLE QUOTE_SINGLE))+;
STRING_ESCAPE_TRIGGER: LBRACE -> pushMode(DEFAULT_MODE);
STRING_QUOTE_SINGLE: QUOTE_SINGLE -> type(QUOTE_SINGLE), popMode;
// ───────── F' FULL TEMPLATE STRING MODE ─────────
// a magic F' takes us to "full template strings" mode, where we don't need to escape single quotes and parse until EOF
// this can't be used within a normal columnExpr, but has to be parsed for separately
mode IN_FULL_TEMPLATE_STRING;
FULL_STRING_TEXT: ((~([{])) | ESCAPE_CHAR_COMMON | (BACKSLASH LBRACE))+;
FULL_STRING_ESCAPE_TRIGGER: LBRACE -> pushMode(DEFAULT_MODE);
// ───────── TSQLX TAG MODE for opening/self-closing tags ─────────
mode TSQLX_TAG_OPEN;
TAG_SELF_CLOSE_GT : '/>' -> type(SLASH_GT), popMode; // <tag …/>
TAG_OPEN_GT : '>' -> type(GT), popMode, pushMode(TSQLX_TEXT); // <tag …>
// minimal token set; map everything back to the default token types
TAG_IDENT : [a-zA-Z_][a-zA-Z0-9_-]* -> type(IDENTIFIER);
TAG_EQ : '=' -> type(EQ_SINGLE);
TAG_STRING : STRING_LITERAL -> type(STRING_LITERAL);
TAG_WS : [ \t\r\n]+ -> channel(HIDDEN);
TAG_LBRACE : '{' -> type(LBRACE), pushMode(DEFAULT_MODE);
// ───────── TSQLX TAG MODE for closing tags ─────────
mode TSQLX_TAG_CLOSE;
TAGC_GT : '>' -> type(GT), popMode; // *** no TEXT push ***
TAGC_IDENT : [a-zA-Z_][a-zA-Z0-9_-]* -> type(IDENTIFIER);
TAGC_WS : [ \t\r\n]+ -> channel(HIDDEN);
// ───────── TSQLX TEXT MODE ─────────
mode TSQLX_TEXT;
TSQLX_TEXT_TEXT
: ~[<{]+ ; // everything except “{” or “<”
TSQLX_TEXT_LBRACE
: '{' -> type(LBRACE), pushMode(DEFAULT_MODE);
TSQLX_TEXT_LT_SLASH
: '</' -> type(LT_SLASH), popMode, pushMode(TSQLX_TAG_CLOSE);
TSQLX_TEXT_LT
: '<' -> type(LT), pushMode(TSQLX_TAG_OPEN);
TSQLX_TEXT_WS
: [ \t\r\n]+ -> channel(HIDDEN);
@@ -0,0 +1,81 @@
lexer grammar TSQLLexer;
@header {
// put any global imports you need here
}
@members {
private _peekChar(k: number): string {
// Return the k-th look-ahead as a *single-char string* or '\0' at EOF.
const c = this._input.LA(k); // int code point or IntStream.EOF (-1)
if (c < 0 || c > 0x10FFFF) { // EOF or out-of-range → sentinel
return '\0';
}
return String.fromCharCode(c);
}
private _skipWsAndComments(idx: number): number {
// Return the first index ≥ idx that is *not* whitespace / single-line comment.
while (true) {
const ch = this._peekChar(idx);
if (/\s/.test(ch)) { // spaces, newlines, tabs …
idx++;
continue;
}
// single-line comments
if (ch === '/' && this._peekChar(idx + 1) === '/') { // //
idx += 2;
} else if (ch === '-' && this._peekChar(idx + 1) === '-') { // --
idx += 2;
} else if (ch === '#') { // #
idx++;
} else {
break; // no ws / comment
}
// consume until EOL / EOF
while (!['\0', '\n', '\r'].includes(this._peekChar(idx))) {
idx++;
}
}
return idx;
}
// ───── opening tag test ─────
isOpeningTag(): boolean {
const ch1 = this._peekChar(1);
if (!(/[a-zA-Z]/.test(ch1) || ch1 === '_')) {
return false; // not a tag name start
}
// skip tag name
let i = 2;
while (true) {
const ch = this._peekChar(i);
if (/[a-zA-Z0-9]/.test(ch) || ch === '_' || ch === '-') {
i++;
} else {
break;
}
}
let ch = this._peekChar(i);
// immediate delimiter → tag
if (ch === '>' || ch === '/') {
return true;
}
// need to look beyond whitespace
if (/\s/.test(ch)) {
i = this._skipWsAndComments(i + 1);
ch = this._peekChar(i);
return ch === '>' || ch === '/' || /[a-zA-Z0-9]/.test(ch) || ch === '_';
}
// anything else → not a tag
return false;
}
}
@@ -0,0 +1,317 @@
parser grammar TSQLParser;
options {
tokenVocab = TSQLLexer;
}
program: declaration* EOF;
declaration: varDecl | statement ;
expression: columnExpr;
varDecl: LET identifier ( COLON EQ_SINGLE expression )? ;
identifierList: identifier (COMMA identifier)* COMMA?;
statement : returnStmt
| throwStmt
| tryCatchStmt
| ifStmt
| whileStmt
| forInStmt
| forStmt
| funcStmt
| varAssignment
| block
| exprStmt
| emptyStmt
;
returnStmt : RETURN expression? SEMICOLON?;
throwStmt : THROW expression? SEMICOLON?;
catchBlock : CATCH (LPAREN catchVar=identifier (COLON catchType=identifier)? RPAREN)? catchStmt=block;
tryCatchStmt : TRY tryStmt=block catchBlock* (FINALLY finallyStmt=block)?;
ifStmt : IF LPAREN expression RPAREN statement ( ELSE statement )? ;
whileStmt : WHILE LPAREN expression RPAREN statement SEMICOLON?;
forStmt : FOR LPAREN
(initializerVarDeclr=varDecl | initializerVarAssignment=varAssignment | initializerExpression=expression)? SEMICOLON
condition=expression? SEMICOLON
(incrementVarDeclr=varDecl | incrementVarAssignment=varAssignment | incrementExpression=expression)?
RPAREN statement SEMICOLON?;
forInStmt : FOR LPAREN LET identifier (COMMA identifier)? IN expression RPAREN statement SEMICOLON?;
funcStmt : (FN | FUN) identifier LPAREN identifierList? RPAREN block;
varAssignment : expression COLON EQ_SINGLE expression ;
exprStmt : expression SEMICOLON?;
emptyStmt : SEMICOLON ;
block : LBRACE declaration* RBRACE ;
kvPair: expression ':' expression ;
kvPairList: kvPair (COMMA kvPair)* COMMA?;
// SELECT statement
select: (selectSetStmt | selectStmt | TSQLxTagElement) SEMICOLON? EOF;
selectStmtWithParens: selectStmt | LPAREN selectSetStmt RPAREN | placeholder;
subsequentSelectSetClause: (EXCEPT | UNION ALL | UNION DISTINCT | INTERSECT | INTERSECT DISTINCT) selectStmtWithParens;
selectSetStmt: selectStmtWithParens (subsequentSelectSetClause)*;
selectStmt:
with=withClause?
SELECT DISTINCT? topClause?
columns=columnExprList
from=fromClause?
arrayJoinClause?
prewhereClause?
where=whereClause?
groupByClause? (WITH (CUBE | ROLLUP))? (WITH TOTALS)?
havingClause?
windowClause?
orderByClause?
limitByClause?
(limitAndOffsetClause | offsetOnlyClause)?
settingsClause?
;
withClause: WITH withExprList;
topClause: TOP DECIMAL_LITERAL (WITH TIES)?;
fromClause: FROM joinExpr;
arrayJoinClause: (LEFT | INNER)? ARRAY JOIN columnExprList;
windowClause: WINDOW identifier AS LPAREN windowExpr RPAREN (COMMA identifier AS LPAREN windowExpr RPAREN)*;
prewhereClause: PREWHERE columnExpr;
whereClause: WHERE columnExpr;
groupByClause: GROUP BY ((CUBE | ROLLUP) LPAREN columnExprList RPAREN | columnExprList);
havingClause: HAVING columnExpr;
orderByClause: ORDER BY orderExprList;
projectionOrderByClause: ORDER BY columnExprList;
limitByClause: LIMIT limitExpr BY columnExprList;
limitAndOffsetClause
: LIMIT columnExpr (COMMA columnExpr)? (WITH TIES)? // compact OFFSET-optional form
| LIMIT columnExpr (WITH TIES)? OFFSET columnExpr // verbose OFFSET-included form with WITH TIES
;
offsetOnlyClause: OFFSET columnExpr;
settingsClause: SETTINGS settingExprList;
joinExpr
: joinExpr joinOp? JOIN joinExpr joinConstraintClause # JoinExprOp
| joinExpr joinOpCross joinExpr # JoinExprCrossOp
| tableExpr FINAL? sampleClause? # JoinExprTable
| LPAREN joinExpr RPAREN # JoinExprParens
;
joinOp
: ((ALL | ANY | ASOF)? INNER | INNER (ALL | ANY | ASOF)? | (ALL | ANY | ASOF)) # JoinOpInner
| ( (SEMI | ALL | ANTI | ANY | ASOF)? (LEFT | RIGHT) OUTER?
| (LEFT | RIGHT) OUTER? (SEMI | ALL | ANTI | ANY | ASOF)?
) # JoinOpLeftRight
| ((ALL | ANY)? FULL OUTER? | FULL OUTER? (ALL | ANY)?) # JoinOpFull
;
joinOpCross
: CROSS JOIN
| COMMA
;
joinConstraintClause
: ON columnExprList
| USING LPAREN columnExprList RPAREN
| USING columnExprList
;
sampleClause: SAMPLE ratioExpr (OFFSET ratioExpr)?;
limitExpr: columnExpr ((COMMA | OFFSET) columnExpr)?;
orderExprList: orderExpr (COMMA orderExpr)*;
orderExpr: columnExpr (ASCENDING | DESCENDING | DESC)? (NULLS (FIRST | LAST))? (COLLATE STRING_LITERAL)?;
ratioExpr: placeholder | numberLiteral (SLASH numberLiteral)?;
settingExprList: settingExpr (COMMA settingExpr)*;
settingExpr: identifier EQ_SINGLE literal;
windowExpr: winPartitionByClause? winOrderByClause? winFrameClause?;
winPartitionByClause: PARTITION BY columnExprList;
winOrderByClause: ORDER BY orderExprList;
winFrameClause: (ROWS | RANGE) winFrameExtend;
winFrameExtend
: winFrameBound # frameStart
| BETWEEN winFrameBound AND winFrameBound # frameBetween
;
winFrameBound: (CURRENT ROW | UNBOUNDED PRECEDING | UNBOUNDED FOLLOWING | numberLiteral PRECEDING | numberLiteral FOLLOWING);
//rangeClause: RANGE LPAREN (MIN identifier MAX identifier | MAX identifier MIN identifier) RPAREN;
// Columns
expr: columnExpr EOF;
columnTypeExpr
: identifier # ColumnTypeExprSimple // UInt64
| identifier LPAREN identifier columnTypeExpr (COMMA identifier columnTypeExpr)* COMMA? RPAREN # ColumnTypeExprNested // Nested
| identifier LPAREN enumValue (COMMA enumValue)* COMMA? RPAREN # ColumnTypeExprEnum // Enum
| identifier LPAREN columnTypeExpr (COMMA columnTypeExpr)* COMMA? RPAREN # ColumnTypeExprComplex // Array, Tuple
| identifier LPAREN columnExprList? RPAREN # ColumnTypeExprParam // FixedString(N)
;
columnExprList: columnExpr (COMMA columnExpr)* COMMA?;
columnExpr
: CASE caseExpr=columnExpr? (WHEN whenExpr=columnExpr THEN thenExpr=columnExpr)+ (ELSE elseExpr=columnExpr)? END # ColumnExprCase
| CAST LPAREN columnExpr AS columnTypeExpr RPAREN # ColumnExprCast
| DATE STRING_LITERAL # ColumnExprDate
// | EXTRACT LPAREN interval FROM columnExpr RPAREN # ColumnExprExtract // Interferes with a function call
| INTERVAL STRING_LITERAL # ColumnExprIntervalString
| INTERVAL columnExpr interval # ColumnExprInterval
| SUBSTRING LPAREN columnExpr FROM columnExpr (FOR columnExpr)? RPAREN # ColumnExprSubstring
| TIMESTAMP STRING_LITERAL # ColumnExprTimestamp
| TRIM LPAREN (BOTH | LEADING | TRAILING) string FROM columnExpr RPAREN # ColumnExprTrim
| identifier (LPAREN columnExprs=columnExprList? RPAREN) (LPAREN DISTINCT? columnArgList=columnExprList? RPAREN)? OVER LPAREN windowExpr RPAREN # ColumnExprWinFunction
| identifier (LPAREN columnExprs=columnExprList? RPAREN) (LPAREN DISTINCT? columnArgList=columnExprList? RPAREN)? OVER identifier # ColumnExprWinFunctionTarget
| identifier (LPAREN columnExprs=columnExprList? RPAREN)? LPAREN DISTINCT? columnArgList=columnExprList? RPAREN # ColumnExprFunction
| columnExpr LPAREN selectSetStmt RPAREN # ColumnExprCallSelect
| columnExpr LPAREN columnExprList? RPAREN # ColumnExprCall
| TSQLxTagElement # ColumnExprTagElement
| templateString # ColumnExprTemplateString
| literal # ColumnExprLiteral
// FIXME(ilezhankin): this part looks very ugly, maybe there is another way to express it
| columnExpr LBRACKET columnExpr RBRACKET # ColumnExprArrayAccess
| columnExpr DOT DECIMAL_LITERAL # ColumnExprTupleAccess
| columnExpr DOT identifier # ColumnExprPropertyAccess
| columnExpr NULL_PROPERTY LBRACKET columnExpr RBRACKET # ColumnExprNullArrayAccess
| columnExpr NULL_PROPERTY DECIMAL_LITERAL # ColumnExprNullTupleAccess
| columnExpr NULL_PROPERTY identifier # ColumnExprNullPropertyAccess
| DASH columnExpr # ColumnExprNegate
| left=columnExpr ( operator=ASTERISK // *
| operator=SLASH // /
| operator=PERCENT // %
) right=columnExpr # ColumnExprPrecedence1
| left=columnExpr ( operator=PLUS // +
| operator=DASH // -
| operator=CONCAT // ||
) right=columnExpr # ColumnExprPrecedence2
| left=columnExpr ( operator=EQ_DOUBLE // =
| operator=EQ_SINGLE // ==
| operator=NOT_EQ // !=
| operator=LT_EQ // <=
| operator=LT // <
| operator=GT_EQ // >=
| operator=GT // >
| operator=NOT? IN COHORT? // in, not in; in cohort; not in cohort
| operator=NOT? (LIKE | ILIKE) // like, not like, ilike, not ilike
| operator=REGEX_SINGLE // ~
| operator=REGEX_DOUBLE // =~
| operator=NOT_REGEX // !~
| operator=IREGEX_SINGLE // ~*
| operator=IREGEX_DOUBLE // =~*
| operator=NOT_IREGEX // !~*
) right=columnExpr # ColumnExprPrecedence3
| columnExpr IS NOT? NULL_SQL # ColumnExprIsNull
| columnExpr NULLISH columnExpr # ColumnExprNullish
| NOT columnExpr # ColumnExprNot
| columnExpr AND columnExpr # ColumnExprAnd
| columnExpr OR columnExpr # ColumnExprOr
// TODO(ilezhankin): `BETWEEN a AND b AND c` is parsed in a wrong way: `BETWEEN (a AND b) AND c`
| columnExpr NOT? BETWEEN columnExpr AND columnExpr # ColumnExprBetween
| <assoc=right> columnExpr QUERY columnExpr COLON columnExpr # ColumnExprTernaryOp
| columnExpr (AS identifier | AS STRING_LITERAL) # ColumnExprAlias
| (tableIdentifier DOT)? ASTERISK # ColumnExprAsterisk // single-column only
| LPAREN selectSetStmt RPAREN # ColumnExprSubquery // single-column only
| LPAREN columnExpr RPAREN # ColumnExprParens // single-column only
| LPAREN columnExprList RPAREN # ColumnExprTuple
| LBRACKET columnExprList? RBRACKET # ColumnExprArray
| LBRACE (kvPairList)? RBRACE # ColumnExprDict
| columnLambdaExpr # ColumnExprLambda
| columnIdentifier # ColumnExprIdentifier
;
columnLambdaExpr:
( LPAREN identifier (COMMA identifier)* COMMA? RPAREN
| identifier (COMMA identifier)* COMMA?
| LPAREN RPAREN
)
ARROW (columnExpr | block)
;
TSQLxChildElement
: TSQLxTagElement
| TSQLxText
| LBRACE columnExpr RBRACE;
TSQLxText : TSQLX_TEXT_TEXT ;
TSQLxTagElement
: LT identifier TSQLxTagAttribute* SLASH_GT
| LT identifier TSQLxTagAttribute* GT TSQLxChildElement* LT_SLASH identifier GT
;
TSQLxTagAttribute
: identifier EQ_SINGLE string
| identifier EQ_SINGLE LBRACE columnExpr RBRACE
| identifier
;
withExprList: withExpr (COMMA withExpr)* COMMA?;
withExpr
: identifier AS LPAREN selectSetStmt RPAREN # WithExprSubquery
// NOTE: asterisk and subquery goes before |columnExpr| so that we can mark them as multi-column expressions.
| columnExpr AS identifier # WithExprColumn
;
// This is slightly different in TSQL compared to ClickHouse SQL
// TSQL allows unlimited ("*") nestedIdentifier-s "properties.b.a.a.w.a.s".
// We parse and convert "databaseIdentifier.tableIdentifier.columnIdentifier.nestedIdentifier.*"
// to just one ast.Field(chain=['a','b','columnIdentifier','on','and','on']).
columnIdentifier: placeholder | ((tableIdentifier DOT)? nestedIdentifier);
nestedIdentifier: identifier (DOT identifier)*;
tableExpr
: tableIdentifier # TableExprIdentifier
| tableFunctionExpr # TableExprFunction
| LPAREN selectSetStmt RPAREN # TableExprSubquery
| tableExpr (alias | AS identifier) # TableExprAlias
| TSQLxTagElement # TableExprTag
| placeholder # TableExprPlaceholder
;
tableFunctionExpr: identifier LPAREN tableArgList? RPAREN;
tableIdentifier: (databaseIdentifier DOT)? nestedIdentifier;
tableArgList: columnExpr (COMMA columnExpr)* COMMA?;
// Databases
databaseIdentifier: identifier;
// Basics
floatingLiteral
: FLOATING_LITERAL
| DOT (DECIMAL_LITERAL | OCTAL_LITERAL)
| DECIMAL_LITERAL DOT (DECIMAL_LITERAL | OCTAL_LITERAL)? // can't move this to the lexer or it will break nested tuple access: t.1.2
;
numberLiteral: (PLUS | DASH)? (floatingLiteral | OCTAL_LITERAL | DECIMAL_LITERAL | HEXADECIMAL_LITERAL | INF | NAN_SQL);
literal
: numberLiteral
| STRING_LITERAL
| NULL_SQL
;
interval: SECOND | MINUTE | HOUR | DAY | WEEK | MONTH | QUARTER | YEAR;
keyword
// except NULL_SQL, INF, NAN_SQL
: ALL | AND | ANTI | ANY | ARRAY | AS | ASCENDING | ASOF | BETWEEN | BOTH | BY | CASE
| CAST | COHORT | COLLATE | CROSS | CUBE | CURRENT | DATE | DESC | DESCENDING
| DISTINCT | ELSE | END | EXTRACT | FINAL | FIRST
| FOR | FOLLOWING | FROM | FULL | GROUP | HAVING | ID | IS
| IF | ILIKE | IN | INNER | INTERVAL | JOIN | KEY
| LAST | LEADING | LEFT | LIKE | LIMIT
| NOT | NULLS | OFFSET | ON | OR | ORDER | OUTER | OVER | PARTITION
| PRECEDING | PREWHERE | RANGE | RETURN | RIGHT | ROLLUP | ROW
| ROWS | SAMPLE | SELECT | SEMI | SETTINGS | SUBSTRING
| THEN | TIES | TIMESTAMP | TOTALS | TRAILING | TRIM | TRUNCATE | TO | TOP
| UNBOUNDED | UNION | USING | WHEN | WHERE | WINDOW | WITH
;
keywordForAlias
: DATE | FIRST | ID | KEY
;
alias: IDENTIFIER | keywordForAlias; // |interval| can't be an alias, otherwise 'INTERVAL 1 SOMETHING' becomes ambiguous.
identifier: IDENTIFIER | interval | keyword;
enumValue: string EQ_SINGLE numberLiteral;
placeholder: LBRACE columnExpr RBRACE;
string: STRING_LITERAL | templateString;
templateString : QUOTE_SINGLE_TEMPLATE stringContents* QUOTE_SINGLE ;
stringContents : STRING_ESCAPE_TRIGGER columnExpr RBRACE | STRING_TEXT;
// These are magic "full template strings", which are used to parse "full text field" templates without the surrounding SQL.
// We will need to add F' to the start of the string to change the lexer's mode.
fullTemplateString: QUOTE_SINGLE_TEMPLATE_FULL stringContentsFull* EOF ;
stringContentsFull : FULL_STRING_ESCAPE_TRIGGER columnExpr RBRACE | FULL_STRING_TEXT;
+1
View File
@@ -0,0 +1 @@
import { Logger } from "@trigger.dev/core/logger";
+23
View File
@@ -0,0 +1,23 @@
{
"compilerOptions": {
"target": "ES2019",
"lib": ["ES2019", "DOM", "DOM.Iterable", "DOM.AsyncIterable"],
"module": "Node16",
"moduleResolution": "Node16",
"moduleDetection": "force",
"verbatimModuleSyntax": false,
"types": ["vitest/globals"],
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"preserveWatchOutput": true,
"skipLibCheck": true,
"noEmit": true,
"strict": true,
"paths": {
"@trigger.dev/core": ["../../packages/core/src/index"],
"@trigger.dev/core/*": ["../../packages/core/src/*"]
}
},
"exclude": ["node_modules"]
}
+240
View File
@@ -695,10 +695,28 @@ importers:
version: 2.0.2(@remix-run/server-runtime@2.1.0(typescript@5.9.3))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3)))
remix-auth-github:
specifier: ^1.6.0
<<<<<<< ours
version: 1.6.0(@remix-run/server-runtime@2.1.0(typescript@5.9.3))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3)))
||||||| ancestor
version: 1.6.0(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4)))
=======
<<<<<<< ours
version: 1.6.0(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4)))
>>>>>>> theirs
remix-auth-google:
specifier: ^2.0.0
<<<<<<< ours
version: 2.0.0(@remix-run/server-runtime@2.1.0(typescript@5.9.3))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3)))
||||||| ancestor
version: 2.0.0(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4)))
=======
version: 2.0.0(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4)))
||||||| ancestor
version: 1.6.0(@remix-run/server-runtime@2.1.0(typescript@5.9.3))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3)))
=======
version: 1.6.0(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4)))
>>>>>>> theirs
>>>>>>> theirs
remix-typedjson:
specifier: 0.3.1
version: 0.3.1(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3))(react@18.2.0)
@@ -1263,6 +1281,16 @@ importers:
specifier: workspace:*
version: link:../../packages/core
internal-packages/tsql:
dependencies:
'@trigger.dev/core':
specifier: workspace:*
version: link:../../packages/core
devDependencies:
antlr4ts:
specifier: 0.5.0-alpha.4
version: 0.5.0-alpha.4
internal-packages/zod-worker:
dependencies:
'@internal/tracing':
@@ -5788,6 +5816,7 @@ packages:
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
<<<<<<< ours
libc: [glibc]
'@next/swc-linux-arm64-gnu@15.4.8':
@@ -5796,6 +5825,10 @@ packages:
cpu: [arm64]
os: [linux]
libc: [glibc]
||||||| ancestor
=======
libc: [glibc]
>>>>>>> theirs
'@next/swc-linux-arm64-gnu@15.5.6':
resolution: {integrity: sha512-qvz4SVKQ0P3/Im9zcS2RmfFL/UCQnsJKJwQSkissbngnB/12c6bZTCB0gHTexz1s6d/mD0+egPKXAIRFVS7hQg==}
@@ -5823,6 +5856,7 @@ packages:
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
<<<<<<< ours
libc: [musl]
'@next/swc-linux-arm64-musl@15.4.8':
@@ -5831,6 +5865,10 @@ packages:
cpu: [arm64]
os: [linux]
libc: [musl]
||||||| ancestor
=======
libc: [musl]
>>>>>>> theirs
'@next/swc-linux-arm64-musl@15.5.6':
resolution: {integrity: sha512-FsbGVw3SJz1hZlvnWD+T6GFgV9/NYDeLTNQB2MXoPN5u9VA9OEDy6fJEfePfsUKAhJufFbZLgp0cPxMuV6SV0w==}
@@ -5858,6 +5896,7 @@ packages:
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
<<<<<<< ours
libc: [glibc]
'@next/swc-linux-x64-gnu@15.4.8':
@@ -5866,6 +5905,10 @@ packages:
cpu: [x64]
os: [linux]
libc: [glibc]
||||||| ancestor
=======
libc: [glibc]
>>>>>>> theirs
'@next/swc-linux-x64-gnu@15.5.6':
resolution: {integrity: sha512-3QnHGFWlnvAgyxFxt2Ny8PTpXtQD7kVEeaFat5oPAHHI192WKYB+VIKZijtHLGdBBvc16tiAkPTDmQNOQ0dyrA==}
@@ -5893,6 +5936,7 @@ packages:
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
<<<<<<< ours
libc: [musl]
'@next/swc-linux-x64-musl@15.4.8':
@@ -5901,6 +5945,10 @@ packages:
cpu: [x64]
os: [linux]
libc: [musl]
||||||| ancestor
=======
libc: [musl]
>>>>>>> theirs
'@next/swc-linux-x64-musl@15.5.6':
resolution: {integrity: sha512-OsGX148sL+TqMK9YFaPFPoIaJKbFJJxFzkXZljIgA9hjMjdruKht6xDCEv1HLtlLNfkx3c5w2GLKhj7veBQizQ==}
@@ -9415,11 +9463,16 @@ packages:
'@smithy/core@3.18.3':
resolution: {integrity: sha512-qqpNskkbHOSfrbFbjhYj5o8VMXO26fvN1K/+HbCzUNlTuxgNcPRouUDNm+7D6CkN244WG7aK533Ne18UtJEgAA==}
engines: {node: '>=18.0.0'}
<<<<<<< ours
deprecated: Please upgrade your lockfile to use the latest 3.x version of @smithy/core for various fixes, see https://github.com/smithy-lang/smithy-typescript/blob/main/packages/core/CHANGELOG.md
'@smithy/core@3.18.5':
resolution: {integrity: sha512-6gnIz3h+PEPQGDj8MnRSjDvKBah042jEoPgjFGJ4iJLBE78L4lY/n98x14XyPF4u3lN179Ub/ZKFY5za9GeLQw==}
engines: {node: '>=18.0.0'}
||||||| ancestor
=======
deprecated: Please upgrade your lockfile to use the latest 3.x version of @smithy/core for various fixes, see https://github.com/smithy-lang/smithy-typescript/blob/main/packages/core/CHANGELOG.md
>>>>>>> theirs
'@smithy/core@3.6.0':
resolution: {integrity: sha512-Pgvfb+TQ4wUNLyHzvgCP4aYZMh16y7GcfF59oirRHcgGgkH1e/s9C0nv/v3WP+Quymyr5je71HeFQCwh+44XLg==}
@@ -11366,6 +11419,9 @@ packages:
resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
engines: {node: '>=12'}
antlr4ts@0.5.0-alpha.4:
resolution: {integrity: sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==}
any-promise@1.3.0:
resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
@@ -28968,14 +29024,32 @@ snapshots:
'@rushstack/eslint-patch@1.2.0': {}
<<<<<<< ours
'@s2-dev/streamstore@0.17.3(typescript@5.9.3)':
||||||| ancestor
'@s2-dev/streamstore@0.17.3(typescript@5.5.4)':
=======
<<<<<<< ours
'@s2-dev/streamstore@0.17.3(typescript@5.5.4)':
>>>>>>> theirs
dependencies:
'@protobuf-ts/runtime': 2.11.1
typescript: 5.9.3
'@s2-dev/streamstore@0.17.6':
||||||| ancestor
'@s2-dev/streamstore@0.17.3(typescript@5.9.3)':
=======
'@s2-dev/streamstore@0.17.3(typescript@5.5.4)':
>>>>>>> theirs
dependencies:
'@protobuf-ts/runtime': 2.11.1
<<<<<<< ours
||||||| ancestor
typescript: 5.9.3
=======
typescript: 5.5.4
>>>>>>> theirs
'@sec-ant/readable-stream@0.4.1': {}
@@ -31798,6 +31872,8 @@ snapshots:
ansi-styles@6.2.1: {}
antlr4ts@0.5.0-alpha.4: {}
any-promise@1.3.0: {}
anymatch@3.1.3:
@@ -32753,6 +32829,41 @@ snapshots:
dependencies:
layout-base: 2.0.1
<<<<<<< ours
||||||| ancestor
cosmiconfig@8.3.6(typescript@5.5.4):
dependencies:
import-fresh: 3.3.0
js-yaml: 4.1.1
parse-json: 5.2.0
path-type: 4.0.0
optionalDependencies:
typescript: 5.5.4
=======
<<<<<<< ours
cosmiconfig@8.3.6(typescript@5.5.4):
dependencies:
import-fresh: 3.3.0
js-yaml: 4.1.1
parse-json: 5.2.0
path-type: 4.0.0
optionalDependencies:
typescript: 5.5.4
||||||| ancestor
=======
cosmiconfig@8.3.6(typescript@5.5.4):
dependencies:
import-fresh: 3.3.0
js-yaml: 4.1.0
parse-json: 5.2.0
path-type: 4.0.0
optionalDependencies:
typescript: 5.5.4
>>>>>>> theirs
>>>>>>> theirs
cosmiconfig@8.3.6(typescript@5.9.3):
dependencies:
import-fresh: 3.3.0
@@ -35039,6 +35150,58 @@ snapshots:
transitivePeerDependencies:
- supports-color
<<<<<<< ours
||||||| ancestor
graphile-worker@0.16.6(patch_hash=798129c99ed02177430fc90a1fdef800ec94e5fd1d491b931297dc52f4c98ab1)(typescript@5.5.4):
dependencies:
'@graphile/logger': 0.2.0
'@types/debug': 4.1.12
'@types/pg': 8.11.6
cosmiconfig: 8.3.6(typescript@5.5.4)
graphile-config: 0.0.1-beta.8
json5: 2.2.3
pg: 8.11.5
tslib: 2.6.2
yargs: 17.7.2
transitivePeerDependencies:
- pg-native
- supports-color
- typescript
=======
graphile-worker@0.16.6(patch_hash=798129c99ed02177430fc90a1fdef800ec94e5fd1d491b931297dc52f4c98ab1)(typescript@5.5.4):
dependencies:
'@graphile/logger': 0.2.0
'@types/debug': 4.1.12
'@types/pg': 8.11.6
cosmiconfig: 8.3.6(typescript@5.5.4)
graphile-config: 0.0.1-beta.8
json5: 2.2.3
pg: 8.11.5
tslib: 2.6.2
yargs: 17.7.2
transitivePeerDependencies:
- pg-native
- supports-color
- typescript
graphile-worker@0.16.6(patch_hash=798129c99ed02177430fc90a1fdef800ec94e5fd1d491b931297dc52f4c98ab1)(typescript@5.5.4):
dependencies:
'@graphile/logger': 0.2.0
'@types/debug': 4.1.12
'@types/pg': 8.11.6
cosmiconfig: 8.3.6(typescript@5.5.4)
graphile-config: 0.0.1-beta.8
json5: 2.2.3
pg: 8.11.5
tslib: 2.6.2
yargs: 17.7.2
transitivePeerDependencies:
- pg-native
- supports-color
- typescript
>>>>>>> theirs
graphile-worker@0.16.6(patch_hash=798129c99ed02177430fc90a1fdef800ec94e5fd1d491b931297dc52f4c98ab1)(typescript@5.9.3):
dependencies:
'@graphile/logger': 0.2.0
@@ -39431,11 +39594,34 @@ snapshots:
transitivePeerDependencies:
- supports-color
<<<<<<< ours
remix-auth-google@2.0.0(@remix-run/server-runtime@2.1.0(typescript@5.9.3))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3))):
||||||| ancestor
remix-auth-google@2.0.0(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))):
=======
<<<<<<< ours
remix-auth-google@2.0.0(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))):
||||||| ancestor
remix-auth-oauth2@1.11.0(@remix-run/server-runtime@2.1.0(typescript@5.9.3))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3))):
=======
remix-auth-oauth2@1.11.0(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))):
>>>>>>> theirs
>>>>>>> theirs
dependencies:
<<<<<<< ours
'@remix-run/server-runtime': 2.1.0(typescript@5.9.3)
remix-auth: 3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3))
remix-auth-oauth2: 1.11.0(@remix-run/server-runtime@2.1.0(typescript@5.9.3))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3)))
||||||| ancestor
'@remix-run/server-runtime': 2.1.0(typescript@5.5.4)
remix-auth: 3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))
remix-auth-oauth2: 1.11.0(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4)))
=======
<<<<<<< ours
'@remix-run/server-runtime': 2.1.0(typescript@5.5.4)
remix-auth: 3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))
remix-auth-oauth2: 1.11.0(@remix-run/server-runtime@2.1.0(typescript@5.5.4))(remix-auth@3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4)))
>>>>>>> theirs
transitivePeerDependencies:
- supports-color
@@ -39443,7 +39629,22 @@ snapshots:
dependencies:
'@remix-run/server-runtime': 2.1.0(typescript@5.9.3)
debug: 4.4.1(supports-color@10.0.0)
<<<<<<< ours
remix-auth: 3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3))
||||||| ancestor
remix-auth: 3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))
=======
remix-auth: 3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))
||||||| ancestor
'@remix-run/server-runtime': 2.1.0(typescript@5.9.3)
debug: 4.4.0
remix-auth: 3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.9.3))(@remix-run/server-runtime@2.1.0(typescript@5.9.3))
=======
'@remix-run/server-runtime': 2.1.0(typescript@5.5.4)
debug: 4.4.0
remix-auth: 3.6.0(@remix-run/react@2.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.5.4))(@remix-run/server-runtime@2.1.0(typescript@5.5.4))
>>>>>>> theirs
>>>>>>> theirs
transitivePeerDependencies:
- supports-color
@@ -41655,6 +41856,7 @@ snapshots:
- supports-color
- typescript
<<<<<<< ours
vite-tsconfig-paths@4.0.5(typescript@5.9.3):
dependencies:
debug: 4.3.7(supports-color@10.0.0)
@@ -41664,6 +41866,44 @@ snapshots:
- supports-color
- typescript
||||||| ancestor
=======
<<<<<<< ours
||||||| ancestor
vite-tsconfig-paths@4.0.5(typescript@5.9.3):
dependencies:
debug: 4.3.7(supports-color@10.0.0)
globrex: 0.1.2
tsconfck: 2.1.2(typescript@5.9.3)
transitivePeerDependencies:
- supports-color
- typescript
vite@4.1.4(@types/node@20.14.14)(terser@5.44.1):
dependencies:
esbuild: 0.16.17
postcss: 8.5.3
resolve: 1.22.8
rollup: 3.10.0
optionalDependencies:
'@types/node': 20.14.14
fsevents: 2.3.3
terser: 5.44.1
=======
vite@4.1.4(@types/node@20.14.14)(terser@5.44.1):
dependencies:
esbuild: 0.16.17
postcss: 8.5.3
resolve: 1.22.8
rollup: 3.10.0
optionalDependencies:
'@types/node': 20.14.14
fsevents: 2.3.3
terser: 5.44.1
>>>>>>> theirs
>>>>>>> theirs
vite@4.4.9(@types/node@22.13.9)(lightningcss@1.29.2)(terser@5.44.1):
dependencies:
esbuild: 0.18.11