diff --git a/internal-packages/tsql/.gitignore b/internal-packages/tsql/.gitignore
new file mode 100644
index 000000000..be2243751
--- /dev/null
+++ b/internal-packages/tsql/.gitignore
@@ -0,0 +1,3 @@
+# Generated ANTLR parser files
+src/generated/
+
diff --git a/internal-packages/tsql/README.md b/internal-packages/tsql/README.md
new file mode 100644
index 000000000..e7a58c92e
--- /dev/null
+++ b/internal-packages/tsql/README.md
@@ -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
+```
diff --git a/internal-packages/tsql/package.json b/internal-packages/tsql/package.json
new file mode 100644
index 000000000..e2c0a1bed
--- /dev/null
+++ b/internal-packages/tsql/package.json
@@ -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"
+ }
+}
diff --git a/internal-packages/tsql/src/grammar/TSQLLexer.common.g4 b/internal-packages/tsql/src/grammar/TSQLLexer.common.g4
new file mode 100644
index 000000000..7988b54eb
--- /dev/null
+++ b/internal-packages/tsql/src/grammar/TSQLLexer.common.g4
@@ -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_OPEN_GT : '>' -> type(GT), popMode, pushMode(TSQLX_TEXT); //
+
+// 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);
diff --git a/internal-packages/tsql/src/grammar/TSQLLexer.typescript.g4 b/internal-packages/tsql/src/grammar/TSQLLexer.typescript.g4
new file mode 100644
index 000000000..f09eb2aaa
--- /dev/null
+++ b/internal-packages/tsql/src/grammar/TSQLLexer.typescript.g4
@@ -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;
+}
+
+}
\ No newline at end of file
diff --git a/internal-packages/tsql/src/grammar/TSQLParser.g4 b/internal-packages/tsql/src/grammar/TSQLParser.g4
new file mode 100644
index 000000000..6cade4e63
--- /dev/null
+++ b/internal-packages/tsql/src/grammar/TSQLParser.g4
@@ -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
+ | 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;
\ No newline at end of file
diff --git a/internal-packages/tsql/src/index.ts b/internal-packages/tsql/src/index.ts
new file mode 100644
index 000000000..6580918fb
--- /dev/null
+++ b/internal-packages/tsql/src/index.ts
@@ -0,0 +1 @@
+import { Logger } from "@trigger.dev/core/logger";
diff --git a/internal-packages/tsql/tsconfig.json b/internal-packages/tsql/tsconfig.json
new file mode 100644
index 000000000..010433962
--- /dev/null
+++ b/internal-packages/tsql/tsconfig.json
@@ -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"]
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6fa66945d..ce2bde953 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -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