A flexible TypeScript library for parsing and building query languages with support for lexical analysis, AST generation, and token stream processing.
- 🚀 Fast and Lightweight - Built with performance in mind using TypeScript
- 🔍 Flexible Query Syntax - Support for boolean logic (AND, OR, NOT), comparisons, and grouping
- 🎯 Type Safe - Full TypeScript support with comprehensive type definitions
- 🌳 AST Generation - Generate Abstract Syntax Trees for complex query processing
- 🔧 Extensible - Modular architecture allows for easy customization
- 📊 Token Stream Processing - Low-level access to token streams for advanced use cases
- ⚡ Zero Dependencies - Lightweight with no external runtime dependencies
- 🧪 Well Tested - 90%+ test coverage with comprehensive edge case handling
# Using npm
npm install create-query-language
# Using yarn
yarn add create-query-language
# Using pnpm
pnpm add create-query-language
import { QueryParser, QueryLexer, ASTBuilder } from 'create-query-language';
// Basic parsing
const parser = new QueryParser();
const result = parser.parse('status: active AND NOT role: guest');
if (result.success) {
console.log('Query parsed successfully!');
console.log('AST:', result.ast);
} else {
console.error('Parse errors:', result.errors);
}
import { QueryParser } from 'create-query-language';
const parser = new QueryParser();
// Simple condition
const result1 = parser.parse('status: active');
// Boolean expressions
const result2 = parser.parse('status: active AND role: admin');
const result3 = parser.parse('type: user OR type: admin');
// NOT expressions
const result4 = parser.parse('NOT status: inactive');
const result5 = parser.parse('status: active AND NOT role: guest');
// Grouped expressions
const result6 = parser.parse('(status: active OR status: pending) AND role: admin');
const result7 = parser.parse('NOT (status: inactive OR role: guest)');
// Different comparators
const result8 = parser.parse('age >= 18 AND score > 85');
field: value
name: "John Doe"
age: 25
age >= 18 # Greater than or equal
score > 85 # Greater than
count <= 100 # Less than or equal
priority < 5 # Less than
status == active # Equals
type != guest # Not equals
field: value # Colon (default)
status: active AND role: admin # AND operation
type: user OR type: admin # OR operation
NOT status: inactive # NOT operation (negation)
status: active AND NOT role: guest # Combined with other operators
NOT (status: inactive OR role: guest) # NOT with grouped expressions
status: active AND (role: admin OR role: manager) # Complex grouping
name: "John Doe" # Double quotes
title: 'Software Engineer' # Single quotes
message: "He said \"Hello\"" # Escaped quotes
(status: active) # Simple group
(status: active OR status: pending) AND role: admin # Complex grouping
((field: value)) # Nested groups
NOT (status: inactive OR role: guest) # NOT with groups
The query language follows standard operator precedence rules (from highest to lowest):
- Parentheses
()
- Highest precedence, overrides all other operators - NOT - Unary negation operator
- AND - Logical AND operation
- OR - Logical OR operation (lowest precedence)
Examples of precedence in action:
NOT status: active AND role: admin # Equivalent to: (NOT status: active) AND role: admin
status: a OR status: b AND role: c # Equivalent to: status: a OR (status: b AND role: c)
NOT (status: a OR status: b) # NOT applies to the entire grouped expression
The main parser class for converting query strings into AST.
class QueryParser {
constructor(options?: Partial<QueryParserOptions>);
parse(input: string): ParseResult;
}
type ParseResult {
success: boolean;
ast?: QueryExpression;
errors: ParseError[];
tokens: Token[];
}
interface QueryParserOptions {
maxErrors: number; // Maximum number of errors to collect (default: unlimited)
}
const parser = new QueryParser({ maxErrors: 5 });
Current test coverage: 90%+
- ✅ Statements: 90.38%
- ✅ Branches: 79.57%
- ✅ Functions: 98.33%
- ✅ Lines: 90.98%
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
This project is licensed under the MIT License - see the LICENSE file for details.
Made with ❤️ by Tal Kohavy