qast 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +428 -0
- package/dist/adapters/prisma.d.ts +12 -0
- package/dist/adapters/prisma.d.ts.map +1 -0
- package/dist/adapters/prisma.js +132 -0
- package/dist/adapters/prisma.js.map +1 -0
- package/dist/adapters/sequelize.d.ts +37 -0
- package/dist/adapters/sequelize.d.ts.map +1 -0
- package/dist/adapters/sequelize.js +166 -0
- package/dist/adapters/sequelize.js.map +1 -0
- package/dist/adapters/typeorm.d.ts +18 -0
- package/dist/adapters/typeorm.d.ts.map +1 -0
- package/dist/adapters/typeorm.js +112 -0
- package/dist/adapters/typeorm.js.map +1 -0
- package/dist/errors.d.ts +35 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +61 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +78 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/parser.d.ts +49 -0
- package/dist/parser/parser.d.ts.map +1 -0
- package/dist/parser/parser.js +148 -0
- package/dist/parser/parser.js.map +1 -0
- package/dist/parser/tokenizer.d.ts +73 -0
- package/dist/parser/tokenizer.d.ts.map +1 -0
- package/dist/parser/tokenizer.js +352 -0
- package/dist/parser/tokenizer.js.map +1 -0
- package/dist/parser/validator.d.ts +14 -0
- package/dist/parser/validator.d.ts.map +1 -0
- package/dist/parser/validator.js +94 -0
- package/dist/parser/validator.js.map +1 -0
- package/dist/types/ast.d.ts +72 -0
- package/dist/types/ast.d.ts.map +1 -0
- package/dist/types/ast.js +17 -0
- package/dist/types/ast.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Parser = void 0;
|
|
4
|
+
exports.parseQueryString = parseQueryString;
|
|
5
|
+
const tokenizer_1 = require("./tokenizer");
|
|
6
|
+
const errors_1 = require("../errors");
|
|
7
|
+
/**
|
|
8
|
+
* Parser for QAST query strings
|
|
9
|
+
* Grammar:
|
|
10
|
+
* expression -> term (("and" | "or") term)*
|
|
11
|
+
* term -> factor | "(" expression ")"
|
|
12
|
+
* factor -> IDENTIFIER OPERATOR VALUE
|
|
13
|
+
*/
|
|
14
|
+
class Parser {
|
|
15
|
+
constructor(tokens) {
|
|
16
|
+
this.tokens = tokens;
|
|
17
|
+
this.position = 0;
|
|
18
|
+
this.currentToken = this.tokens[0];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Advance to the next token
|
|
22
|
+
*/
|
|
23
|
+
advance() {
|
|
24
|
+
this.position++;
|
|
25
|
+
if (this.position < this.tokens.length) {
|
|
26
|
+
this.currentToken = this.tokens[this.position];
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
this.currentToken = this.tokens[this.tokens.length - 1]; // Keep EOF
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Expect a token of a specific type, throw error if not found
|
|
34
|
+
*/
|
|
35
|
+
expect(type, errorMessage) {
|
|
36
|
+
if (this.currentToken.type !== type) {
|
|
37
|
+
throw new errors_1.ParseError(errorMessage ||
|
|
38
|
+
`Expected ${type}, but got ${this.currentToken.type} at position ${this.currentToken.position}`);
|
|
39
|
+
}
|
|
40
|
+
const token = this.currentToken;
|
|
41
|
+
this.advance();
|
|
42
|
+
return token;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Check if current token matches a type
|
|
46
|
+
*/
|
|
47
|
+
check(type) {
|
|
48
|
+
return this.currentToken.type === type;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Parse a factor: IDENTIFIER OPERATOR VALUE
|
|
52
|
+
*/
|
|
53
|
+
parseFactor() {
|
|
54
|
+
// Get field name (identifier)
|
|
55
|
+
const fieldToken = this.expect(tokenizer_1.TokenType.IDENTIFIER, 'Expected field name (identifier)');
|
|
56
|
+
const field = fieldToken.value;
|
|
57
|
+
// Get operator
|
|
58
|
+
const operatorToken = this.expect(tokenizer_1.TokenType.OPERATOR, 'Expected operator (eq, ne, gt, lt, gte, lte, in, contains)');
|
|
59
|
+
const op = operatorToken.value;
|
|
60
|
+
// Get value
|
|
61
|
+
const valueToken = this.expect(tokenizer_1.TokenType.VALUE, 'Expected value');
|
|
62
|
+
const value = valueToken.value;
|
|
63
|
+
// Validate operator and value combination
|
|
64
|
+
if (op === 'in') {
|
|
65
|
+
if (!Array.isArray(value)) {
|
|
66
|
+
throw new errors_1.ParseError(`Operator 'in' requires an array value, got ${typeof value} at position ${valueToken.position}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
type: 'COMPARISON',
|
|
71
|
+
field,
|
|
72
|
+
op,
|
|
73
|
+
value: value,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Parse a term: factor | "(" expression ")"
|
|
78
|
+
*/
|
|
79
|
+
parseTerm() {
|
|
80
|
+
if (this.check(tokenizer_1.TokenType.PAREN_OPEN)) {
|
|
81
|
+
// Handle parentheses: "(" expression ")"
|
|
82
|
+
this.advance(); // Skip '('
|
|
83
|
+
const expr = this.parseExpression();
|
|
84
|
+
this.expect(tokenizer_1.TokenType.PAREN_CLOSE, 'Expected closing parenthesis )');
|
|
85
|
+
return expr;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// Handle factor
|
|
89
|
+
return this.parseFactor();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Parse an expression: term (("and" | "or") term)*
|
|
94
|
+
* Left-associative: a and b or c is parsed as (a and b) or c
|
|
95
|
+
*/
|
|
96
|
+
parseExpression() {
|
|
97
|
+
let left = this.parseTerm();
|
|
98
|
+
// Process logical operators (left-associative)
|
|
99
|
+
while (this.check(tokenizer_1.TokenType.LOGICAL_OP) &&
|
|
100
|
+
this.currentToken.type !== tokenizer_1.TokenType.EOF) {
|
|
101
|
+
const logicalOpToken = this.currentToken;
|
|
102
|
+
const logicalOp = logicalOpToken.value.toUpperCase();
|
|
103
|
+
this.advance(); // Skip logical operator
|
|
104
|
+
const right = this.parseTerm();
|
|
105
|
+
// Create logical node (left-associative)
|
|
106
|
+
left = {
|
|
107
|
+
type: logicalOp,
|
|
108
|
+
left,
|
|
109
|
+
right,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
return left;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Parse the query and return the AST
|
|
116
|
+
*/
|
|
117
|
+
parse() {
|
|
118
|
+
if (this.tokens.length === 1 && this.tokens[0].type === tokenizer_1.TokenType.EOF) {
|
|
119
|
+
throw new errors_1.ParseError('Empty query string');
|
|
120
|
+
}
|
|
121
|
+
const ast = this.parseExpression();
|
|
122
|
+
// Ensure we've consumed all tokens (except EOF)
|
|
123
|
+
if (this.currentToken.type !== tokenizer_1.TokenType.EOF &&
|
|
124
|
+
!this.check(tokenizer_1.TokenType.EOF)) {
|
|
125
|
+
throw new errors_1.ParseError(`Unexpected token: ${this.currentToken.type} at position ${this.currentToken.position}. Expected end of query.`);
|
|
126
|
+
}
|
|
127
|
+
return ast;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
exports.Parser = Parser;
|
|
131
|
+
/**
|
|
132
|
+
* Parse a query string into an AST
|
|
133
|
+
*/
|
|
134
|
+
function parseQueryString(query) {
|
|
135
|
+
try {
|
|
136
|
+
const tokenizer = new tokenizer_1.Tokenizer(query);
|
|
137
|
+
const tokens = tokenizer.tokenize();
|
|
138
|
+
const parser = new Parser(tokens);
|
|
139
|
+
return parser.parse();
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
if (error instanceof errors_1.TokenizationError || error instanceof errors_1.ParseError) {
|
|
143
|
+
throw error;
|
|
144
|
+
}
|
|
145
|
+
throw new errors_1.ParseError(`Failed to parse query: ${error instanceof Error ? error.message : String(error)}`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/parser/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token types in the query language
|
|
3
|
+
*/
|
|
4
|
+
export declare enum TokenType {
|
|
5
|
+
IDENTIFIER = "IDENTIFIER",
|
|
6
|
+
OPERATOR = "OPERATOR",
|
|
7
|
+
VALUE = "VALUE",
|
|
8
|
+
LOGICAL_OP = "LOGICAL_OP",
|
|
9
|
+
PAREN_OPEN = "PAREN_OPEN",
|
|
10
|
+
PAREN_CLOSE = "PAREN_CLOSE",
|
|
11
|
+
BRACKET_OPEN = "BRACKET_OPEN",
|
|
12
|
+
BRACKET_CLOSE = "BRACKET_CLOSE",
|
|
13
|
+
COMMA = "COMMA",
|
|
14
|
+
EOF = "EOF"
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Token structure
|
|
18
|
+
*/
|
|
19
|
+
export interface Token {
|
|
20
|
+
type: TokenType;
|
|
21
|
+
value: string | number | boolean | string[] | number[];
|
|
22
|
+
position: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Tokenizer for QAST query strings
|
|
26
|
+
*/
|
|
27
|
+
export declare class Tokenizer {
|
|
28
|
+
private input;
|
|
29
|
+
private position;
|
|
30
|
+
private currentChar;
|
|
31
|
+
constructor(input: string);
|
|
32
|
+
/**
|
|
33
|
+
* Advance to the next character
|
|
34
|
+
*/
|
|
35
|
+
private advance;
|
|
36
|
+
/**
|
|
37
|
+
* Skip whitespace characters
|
|
38
|
+
*/
|
|
39
|
+
private skipWhitespace;
|
|
40
|
+
/**
|
|
41
|
+
* Peek at the next character without advancing
|
|
42
|
+
*/
|
|
43
|
+
private peek;
|
|
44
|
+
/**
|
|
45
|
+
* Read an identifier (field name)
|
|
46
|
+
*/
|
|
47
|
+
private readIdentifier;
|
|
48
|
+
/**
|
|
49
|
+
* Read a string literal (single or double quotes)
|
|
50
|
+
*/
|
|
51
|
+
private readString;
|
|
52
|
+
/**
|
|
53
|
+
* Read a number (integer or float, including negative numbers)
|
|
54
|
+
*/
|
|
55
|
+
private readNumber;
|
|
56
|
+
/**
|
|
57
|
+
* Read a boolean value
|
|
58
|
+
*/
|
|
59
|
+
private readBoolean;
|
|
60
|
+
/**
|
|
61
|
+
* Read an array (for 'in' operator)
|
|
62
|
+
*/
|
|
63
|
+
private readArray;
|
|
64
|
+
/**
|
|
65
|
+
* Get the next token from the input
|
|
66
|
+
*/
|
|
67
|
+
nextToken(): Token;
|
|
68
|
+
/**
|
|
69
|
+
* Tokenize the entire input string
|
|
70
|
+
*/
|
|
71
|
+
tokenize(): Token[];
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=tokenizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenizer.d.ts","sourceRoot":"","sources":["../../src/parser/tokenizer.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,oBAAY,SAAS;IACnB,UAAU,eAAe;IACzB,QAAQ,aAAa;IACrB,KAAK,UAAU;IACf,UAAU,eAAe;IACzB,UAAU,eAAe;IACzB,WAAW,gBAAgB;IAC3B,YAAY,iBAAiB;IAC7B,aAAa,kBAAkB;IAC/B,KAAK,UAAU;IACf,GAAG,QAAQ;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IACvD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAYD;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAgB;gBAEvB,KAAK,EAAE,MAAM;IAMzB;;OAEG;IACH,OAAO,CAAC,OAAO;IASf;;OAEG;IACH,OAAO,CAAC,cAAc;IAOtB;;OAEG;IACH,OAAO,CAAC,IAAI;IAOZ;;OAEG;IACH,OAAO,CAAC,cAAc;IAWtB;;OAEG;IACH,OAAO,CAAC,UAAU;IA2ClB;;OAEG;IACH,OAAO,CAAC,UAAU;IAmClB;;OAEG;IACH,OAAO,CAAC,WAAW;IAkBnB;;OAEG;IACH,OAAO,CAAC,SAAS;IAoDjB;;OAEG;IACI,SAAS,IAAI,KAAK;IA0IzB;;OAEG;IACI,QAAQ,IAAI,KAAK,EAAE;CAU3B"}
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Tokenizer = exports.TokenType = void 0;
|
|
4
|
+
const errors_1 = require("../errors");
|
|
5
|
+
/**
|
|
6
|
+
* Token types in the query language
|
|
7
|
+
*/
|
|
8
|
+
var TokenType;
|
|
9
|
+
(function (TokenType) {
|
|
10
|
+
TokenType["IDENTIFIER"] = "IDENTIFIER";
|
|
11
|
+
TokenType["OPERATOR"] = "OPERATOR";
|
|
12
|
+
TokenType["VALUE"] = "VALUE";
|
|
13
|
+
TokenType["LOGICAL_OP"] = "LOGICAL_OP";
|
|
14
|
+
TokenType["PAREN_OPEN"] = "PAREN_OPEN";
|
|
15
|
+
TokenType["PAREN_CLOSE"] = "PAREN_CLOSE";
|
|
16
|
+
TokenType["BRACKET_OPEN"] = "BRACKET_OPEN";
|
|
17
|
+
TokenType["BRACKET_CLOSE"] = "BRACKET_CLOSE";
|
|
18
|
+
TokenType["COMMA"] = "COMMA";
|
|
19
|
+
TokenType["EOF"] = "EOF";
|
|
20
|
+
})(TokenType || (exports.TokenType = TokenType = {}));
|
|
21
|
+
/**
|
|
22
|
+
* Supported operators
|
|
23
|
+
*/
|
|
24
|
+
const OPERATORS = ['eq', 'ne', 'gt', 'lt', 'gte', 'lte', 'in', 'contains'];
|
|
25
|
+
/**
|
|
26
|
+
* Logical operators
|
|
27
|
+
*/
|
|
28
|
+
const LOGICAL_OPS = ['and', 'or'];
|
|
29
|
+
/**
|
|
30
|
+
* Tokenizer for QAST query strings
|
|
31
|
+
*/
|
|
32
|
+
class Tokenizer {
|
|
33
|
+
constructor(input) {
|
|
34
|
+
this.input = input;
|
|
35
|
+
this.position = 0;
|
|
36
|
+
this.currentChar = this.input.length > 0 ? this.input[0] : null;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Advance to the next character
|
|
40
|
+
*/
|
|
41
|
+
advance() {
|
|
42
|
+
this.position++;
|
|
43
|
+
if (this.position >= this.input.length) {
|
|
44
|
+
this.currentChar = null;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
this.currentChar = this.input[this.position];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Skip whitespace characters
|
|
52
|
+
*/
|
|
53
|
+
skipWhitespace() {
|
|
54
|
+
while (this.currentChar !== null && /\s/.test(this.currentChar)) {
|
|
55
|
+
this.advance();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Peek at the next character without advancing
|
|
60
|
+
*/
|
|
61
|
+
peek() {
|
|
62
|
+
if (this.position + 1 >= this.input.length) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
return this.input[this.position + 1];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Read an identifier (field name)
|
|
69
|
+
*/
|
|
70
|
+
readIdentifier() {
|
|
71
|
+
const start = this.position;
|
|
72
|
+
while (this.currentChar !== null &&
|
|
73
|
+
(/\w/.test(this.currentChar) || this.currentChar === '_')) {
|
|
74
|
+
this.advance();
|
|
75
|
+
}
|
|
76
|
+
return this.input.substring(start, this.position);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Read a string literal (single or double quotes)
|
|
80
|
+
*/
|
|
81
|
+
readString() {
|
|
82
|
+
const quote = this.currentChar;
|
|
83
|
+
this.advance(); // Skip opening quote
|
|
84
|
+
const start = this.position;
|
|
85
|
+
let escaped = false;
|
|
86
|
+
const chars = [];
|
|
87
|
+
while (this.currentChar !== null) {
|
|
88
|
+
if (escaped) {
|
|
89
|
+
if (this.currentChar === 'n') {
|
|
90
|
+
chars.push('\n');
|
|
91
|
+
}
|
|
92
|
+
else if (this.currentChar === 't') {
|
|
93
|
+
chars.push('\t');
|
|
94
|
+
}
|
|
95
|
+
else if (this.currentChar === 'r') {
|
|
96
|
+
chars.push('\r');
|
|
97
|
+
}
|
|
98
|
+
else if (this.currentChar === '\\') {
|
|
99
|
+
chars.push('\\');
|
|
100
|
+
}
|
|
101
|
+
else if (this.currentChar === quote) {
|
|
102
|
+
chars.push(quote);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
chars.push(this.currentChar);
|
|
106
|
+
}
|
|
107
|
+
escaped = false;
|
|
108
|
+
this.advance();
|
|
109
|
+
}
|
|
110
|
+
else if (this.currentChar === '\\') {
|
|
111
|
+
escaped = true;
|
|
112
|
+
this.advance();
|
|
113
|
+
}
|
|
114
|
+
else if (this.currentChar === quote) {
|
|
115
|
+
this.advance(); // Skip closing quote
|
|
116
|
+
return chars.join('');
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
chars.push(this.currentChar);
|
|
120
|
+
this.advance();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
throw new errors_1.TokenizationError(`Unterminated string literal starting at position ${start - 1}`, start - 1, this.input);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Read a number (integer or float, including negative numbers)
|
|
127
|
+
*/
|
|
128
|
+
readNumber() {
|
|
129
|
+
const start = this.position;
|
|
130
|
+
let hasDecimal = false;
|
|
131
|
+
// Check for negative sign (parseFloat will handle it)
|
|
132
|
+
if (this.currentChar === '-') {
|
|
133
|
+
this.advance();
|
|
134
|
+
}
|
|
135
|
+
// Read digits and decimal point
|
|
136
|
+
while (this.currentChar !== null &&
|
|
137
|
+
(/\d/.test(this.currentChar) || this.currentChar === '.')) {
|
|
138
|
+
if (this.currentChar === '.') {
|
|
139
|
+
if (hasDecimal) {
|
|
140
|
+
break; // Already has decimal point
|
|
141
|
+
}
|
|
142
|
+
hasDecimal = true;
|
|
143
|
+
}
|
|
144
|
+
this.advance();
|
|
145
|
+
}
|
|
146
|
+
const numStr = this.input.substring(start, this.position);
|
|
147
|
+
const num = parseFloat(numStr);
|
|
148
|
+
if (isNaN(num)) {
|
|
149
|
+
throw new errors_1.TokenizationError(`Invalid number at position ${start}`, start, this.input);
|
|
150
|
+
}
|
|
151
|
+
return num;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Read a boolean value
|
|
155
|
+
*/
|
|
156
|
+
readBoolean() {
|
|
157
|
+
const start = this.position;
|
|
158
|
+
const ident = this.readIdentifier().toLowerCase();
|
|
159
|
+
if (ident === 'true') {
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
else if (ident === 'false') {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
// Not a boolean, reset position
|
|
167
|
+
this.position = start;
|
|
168
|
+
throw new errors_1.TokenizationError(`Expected boolean value at position ${start}`, start, this.input);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Read an array (for 'in' operator)
|
|
173
|
+
*/
|
|
174
|
+
readArray() {
|
|
175
|
+
this.advance(); // Skip opening bracket
|
|
176
|
+
const items = [];
|
|
177
|
+
this.skipWhitespace();
|
|
178
|
+
if (this.currentChar === ']') {
|
|
179
|
+
this.advance(); // Empty array
|
|
180
|
+
return items;
|
|
181
|
+
}
|
|
182
|
+
while (this.currentChar !== null) {
|
|
183
|
+
this.skipWhitespace();
|
|
184
|
+
if (this.currentChar === ']') {
|
|
185
|
+
this.advance();
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
// Read value
|
|
189
|
+
let value;
|
|
190
|
+
if (this.currentChar === '"' || this.currentChar === "'") {
|
|
191
|
+
value = this.readString();
|
|
192
|
+
}
|
|
193
|
+
else if (/\d/.test(this.currentChar)) {
|
|
194
|
+
value = this.readNumber();
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
throw new errors_1.TokenizationError(`Unexpected character in array: ${this.currentChar}`, this.position, this.input);
|
|
198
|
+
}
|
|
199
|
+
items.push(value);
|
|
200
|
+
this.skipWhitespace();
|
|
201
|
+
if (this.currentChar === ']') {
|
|
202
|
+
this.advance();
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
else if (this.currentChar === ',') {
|
|
206
|
+
this.advance();
|
|
207
|
+
this.skipWhitespace();
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
throw new errors_1.TokenizationError(`Expected ',' or ']' in array at position ${this.position}`, this.position, this.input);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return items;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Get the next token from the input
|
|
217
|
+
*/
|
|
218
|
+
nextToken() {
|
|
219
|
+
this.skipWhitespace();
|
|
220
|
+
if (this.currentChar === null) {
|
|
221
|
+
return {
|
|
222
|
+
type: TokenType.EOF,
|
|
223
|
+
value: '',
|
|
224
|
+
position: this.position,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
const position = this.position;
|
|
228
|
+
// Check for operators (must check before identifiers)
|
|
229
|
+
const peekAhead = this.input.substring(this.position);
|
|
230
|
+
for (const op of OPERATORS) {
|
|
231
|
+
if (peekAhead.startsWith(op) && !/\w/.test(peekAhead[op.length] ?? '')) {
|
|
232
|
+
this.position += op.length;
|
|
233
|
+
this.currentChar = this.position < this.input.length ? this.input[this.position] : null;
|
|
234
|
+
return {
|
|
235
|
+
type: TokenType.OPERATOR,
|
|
236
|
+
value: op,
|
|
237
|
+
position,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
// Check for logical operators
|
|
242
|
+
for (const logicalOp of LOGICAL_OPS) {
|
|
243
|
+
if (peekAhead.toLowerCase().startsWith(logicalOp) && !/\w/.test(peekAhead[logicalOp.length] ?? '')) {
|
|
244
|
+
this.position += logicalOp.length;
|
|
245
|
+
this.currentChar = this.position < this.input.length ? this.input[this.position] : null;
|
|
246
|
+
return {
|
|
247
|
+
type: TokenType.LOGICAL_OP,
|
|
248
|
+
value: logicalOp.toLowerCase(),
|
|
249
|
+
position,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// Handle different token types
|
|
254
|
+
if (this.currentChar === '(') {
|
|
255
|
+
this.advance();
|
|
256
|
+
return {
|
|
257
|
+
type: TokenType.PAREN_OPEN,
|
|
258
|
+
value: '(',
|
|
259
|
+
position,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
if (this.currentChar === ')') {
|
|
263
|
+
this.advance();
|
|
264
|
+
return {
|
|
265
|
+
type: TokenType.PAREN_CLOSE,
|
|
266
|
+
value: ')',
|
|
267
|
+
position,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
if (this.currentChar === '[') {
|
|
271
|
+
const arr = this.readArray();
|
|
272
|
+
return {
|
|
273
|
+
type: TokenType.VALUE,
|
|
274
|
+
value: arr,
|
|
275
|
+
position,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
if (this.currentChar === ',') {
|
|
279
|
+
this.advance();
|
|
280
|
+
return {
|
|
281
|
+
type: TokenType.COMMA,
|
|
282
|
+
value: ',',
|
|
283
|
+
position,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
if (this.currentChar === '"' || this.currentChar === "'") {
|
|
287
|
+
const str = this.readString();
|
|
288
|
+
return {
|
|
289
|
+
type: TokenType.VALUE,
|
|
290
|
+
value: str,
|
|
291
|
+
position,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
// Check for negative numbers or positive numbers
|
|
295
|
+
if (/\d/.test(this.currentChar) || (this.currentChar === '-' && /\d/.test(this.peek() ?? ''))) {
|
|
296
|
+
const num = this.readNumber();
|
|
297
|
+
return {
|
|
298
|
+
type: TokenType.VALUE,
|
|
299
|
+
value: num,
|
|
300
|
+
position,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
// Check for boolean values
|
|
304
|
+
if (this.currentChar === 't' || this.currentChar === 'T') {
|
|
305
|
+
const peekAhead = this.input.substring(this.position, this.position + 4).toLowerCase();
|
|
306
|
+
if (peekAhead === 'true' && !/\w/.test(this.input[this.position + 4] ?? '')) {
|
|
307
|
+
const value = this.readBoolean();
|
|
308
|
+
return {
|
|
309
|
+
type: TokenType.VALUE,
|
|
310
|
+
value,
|
|
311
|
+
position,
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
if (this.currentChar === 'f' || this.currentChar === 'F') {
|
|
316
|
+
const peekAhead = this.input.substring(this.position, this.position + 5).toLowerCase();
|
|
317
|
+
if (peekAhead === 'false' && !/\w/.test(this.input[this.position + 5] ?? '')) {
|
|
318
|
+
const value = this.readBoolean();
|
|
319
|
+
return {
|
|
320
|
+
type: TokenType.VALUE,
|
|
321
|
+
value,
|
|
322
|
+
position,
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
// Identifier (field name)
|
|
327
|
+
if (/\w/.test(this.currentChar) || this.currentChar === '_') {
|
|
328
|
+
const ident = this.readIdentifier();
|
|
329
|
+
return {
|
|
330
|
+
type: TokenType.IDENTIFIER,
|
|
331
|
+
value: ident,
|
|
332
|
+
position,
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
throw new errors_1.TokenizationError(`Unexpected character: ${this.currentChar}`, this.position, this.input);
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Tokenize the entire input string
|
|
339
|
+
*/
|
|
340
|
+
tokenize() {
|
|
341
|
+
const tokens = [];
|
|
342
|
+
let token = this.nextToken();
|
|
343
|
+
while (token.type !== TokenType.EOF) {
|
|
344
|
+
tokens.push(token);
|
|
345
|
+
token = this.nextToken();
|
|
346
|
+
}
|
|
347
|
+
tokens.push(token); // Include EOF token
|
|
348
|
+
return tokens;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
exports.Tokenizer = Tokenizer;
|
|
352
|
+
//# sourceMappingURL=tokenizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenizer.js","sourceRoot":"","sources":["../../src/parser/tokenizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { QastNode, WhitelistOptions, Operator } from '../types/ast';
|
|
2
|
+
/**
|
|
3
|
+
* Validate an AST against whitelist options
|
|
4
|
+
*/
|
|
5
|
+
export declare function validateQuery(ast: QastNode, whitelist: WhitelistOptions): void;
|
|
6
|
+
/**
|
|
7
|
+
* Extract all fields used in an AST
|
|
8
|
+
*/
|
|
9
|
+
export declare function extractFields(ast: QastNode): string[];
|
|
10
|
+
/**
|
|
11
|
+
* Extract all operators used in an AST
|
|
12
|
+
*/
|
|
13
|
+
export declare function extractOperators(ast: QastNode): Operator[];
|
|
14
|
+
//# sourceMappingURL=validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/parser/validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAA+B,gBAAgB,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAIjG;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,gBAAgB,GAAG,IAAI,CAE9E;AAyDD;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,EAAE,CAIrD;AAcD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,GAAG,QAAQ,EAAE,CAI1D"}
|