{"_id":"@abaktiar/ql-parser","_rev":"8-97e7140671359cee425bba5bdccdeb98","name":"@abaktiar/ql-parser","dist-tags":{"latest":"1.5.0"},"versions":{"1.0.0":{"name":"@abaktiar/ql-parser","version":"1.0.0","keywords":["query","parser","ql","typescript","query-language","expression-parser","query-builder","logical-operators","framework-agnostic"],"author":{"name":"abaktiar"},"license":"MIT","_id":"@abaktiar/ql-parser@1.0.0","maintainers":[{"name":"abaktiar","email":"dev.baktiar@gmail.com"}],"dist":{"shasum":"8bf3c7e927595b1cdaa3542f6c137da2d31c12a7","tarball":"https://registry.npmjs.org/@abaktiar/ql-parser/-/ql-parser-1.0.0.tgz","fileCount":4,"integrity":"sha512-7SP+AkvVG5R2SNGFy7ZiuR2/mYOBoqUIZi7CIwKIWSy5Bya9cKeRqRR+Jh/Syff9wGyqPcLO/sIpg9vqE61rxw==","signatures":[{"sig":"MEUCIAklqOR4IwmJTKfM0xoVxbXUUuMYn+4msFqeu1p1DxenAiEAuggZUawDa60fDdAeM+lA5Vkr0SNLmcbFQ1GDKIMFF3c=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":41618},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"710bcf124f562e87f3f53bbb972b2c070300ca1e","_npmUser":{"name":"abaktiar","email":"dev.baktiar@gmail.com"},"_npmVersion":"10.8.2","description":"Framework-agnostic QL (Query Language) parser and builder for creating complex queries with support for logical operators, functions, and ORDER BY clauses","directories":{},"sideEffects":false,"_nodeVersion":"20.19.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/ql-parser_1.0.0_1748050421012_0.056040055427577506","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@abaktiar/ql-parser","version":"1.0.1","keywords":["query","parser","ql","typescript","query-language","expression-parser","query-builder","logical-operators","framework-agnostic"],"author":{"name":"abaktiar"},"license":"MIT","_id":"@abaktiar/ql-parser@1.0.1","maintainers":[{"name":"abaktiar","email":"dev.baktiar@gmail.com"}],"homepage":"https://github.com/abaktiar/ql-input#readme","bugs":{"url":"https://github.com/abaktiar/ql-input/issues"},"dist":{"shasum":"0bceb62f969f3a5b6dcaba826f3b60203dfa5b28","tarball":"https://registry.npmjs.org/@abaktiar/ql-parser/-/ql-parser-1.0.1.tgz","fileCount":4,"integrity":"sha512-M7gp3bvZzDUMo83QUxSeRWEXm6sioDBwtW6LENZsfRVs7EB0E/saJjybCt/xYrx1MsKaEjB5jYf7aX4jWYyCPw==","signatures":[{"sig":"MEUCIQC+0azKVtStBZOkenU0yglMtFQZ8LhprkfLIft6EW11iAIgSu4CVzgArQWZpFUxC/GPzcJuPsXzH+fa/aFlA8Xxy3w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":41849},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"710bcf124f562e87f3f53bbb972b2c070300ca1e","_npmUser":{"name":"abaktiar","email":"dev.baktiar@gmail.com"},"repository":{"url":"git+https://github.com/abaktiar/ql-input.git","type":"git"},"_npmVersion":"10.8.2","description":"Framework-agnostic QL (Query Language) parser and builder for creating complex queries with support for logical operators, functions, and ORDER BY clauses","directories":{},"sideEffects":false,"_nodeVersion":"20.19.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/ql-parser_1.0.1_1748050698052_0.10787111435991381","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@abaktiar/ql-parser","version":"1.1.0","keywords":["query","parser","ql","typescript","query-language","expression-parser","query-builder","logical-operators","framework-agnostic"],"author":{"name":"abaktiar"},"license":"MIT","_id":"@abaktiar/ql-parser@1.1.0","maintainers":[{"name":"abaktiar","email":"dev.baktiar@gmail.com"}],"homepage":"https://github.com/abaktiar/ql-input#readme","bugs":{"url":"https://github.com/abaktiar/ql-input/issues"},"dist":{"shasum":"41f4f266f3fa6ae5d534f13f60a03df3498f9b0d","tarball":"https://registry.npmjs.org/@abaktiar/ql-parser/-/ql-parser-1.1.0.tgz","fileCount":4,"integrity":"sha512-X13wgnQoBrW9siS7Vh2qc4A5HI9kLAg264Tjcm5YpRJfn0aeO4OWVgJswUwiqf27QgKn+PaI5rWLWuncO1o8Qg==","signatures":[{"sig":"MEQCIDmLxaEJEwkW0KvjgLRdhZp6FWrgAA0TxAgXg8aYoBFlAiByTBhfLjnho1OmsUWPf7vcn4FoGCf64C4NdKYo+bXpIA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":41849},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"d004549602573f5371c512e27427f9ae50fbd64f","_npmUser":{"name":"abaktiar","email":"dev.baktiar@gmail.com"},"repository":{"url":"git+https://github.com/abaktiar/ql-input.git","type":"git"},"_npmVersion":"10.8.2","description":"Framework-agnostic QL (Query Language) parser and builder for creating complex queries with support for logical operators, functions, and ORDER BY clauses","directories":{},"sideEffects":false,"_nodeVersion":"20.19.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/ql-parser_1.1.0_1748053454371_0.005403848161250169","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@abaktiar/ql-parser","version":"1.2.0","keywords":["query","parser","ql","typescript","query-language","expression-parser","query-builder","logical-operators","framework-agnostic"],"author":{"name":"abaktiar"},"license":"MIT","_id":"@abaktiar/ql-parser@1.2.0","maintainers":[{"name":"abaktiar","email":"dev.baktiar@gmail.com"}],"homepage":"https://github.com/abaktiar/ql-input#readme","bugs":{"url":"https://github.com/abaktiar/ql-input/issues"},"dist":{"shasum":"47ed9ddc80c82da6d2e08b400eeae0a5d981edb8","tarball":"https://registry.npmjs.org/@abaktiar/ql-parser/-/ql-parser-1.2.0.tgz","fileCount":4,"integrity":"sha512-SSBXWWIwoTGMncDv25DNlNKGiCploaK/Fa2VTxAIdJP8R6vD8/6dpC0SaIelzWagaltimXzFTpIEV0Q9OGu2/A==","signatures":[{"sig":"MEUCIHWB0nxqjv60XTenx5f/hRbOPMzxxkvi1R/mHWBi8Q9FAiEA2RHw3RdVTkPiuVdXFEcas4fNVWzYT1F13rIgI7Pirzk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":41849},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"d004549602573f5371c512e27427f9ae50fbd64f","_npmUser":{"name":"abaktiar","email":"dev.baktiar@gmail.com"},"repository":{"url":"git+https://github.com/abaktiar/ql-input.git","type":"git"},"_npmVersion":"10.8.2","description":"Framework-agnostic QL (Query Language) parser and builder for creating complex queries with support for logical operators, functions, and ORDER BY clauses","directories":{},"sideEffects":false,"_nodeVersion":"20.19.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/ql-parser_1.2.0_1748056969809_0.8063883481700733","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@abaktiar/ql-parser","version":"1.3.0","keywords":["query","parser","ql","typescript","query-language","expression-parser","query-builder","logical-operators","framework-agnostic"],"author":{"name":"abaktiar"},"license":"MIT","_id":"@abaktiar/ql-parser@1.3.0","maintainers":[{"name":"abaktiar","email":"dev.baktiar@gmail.com"}],"homepage":"https://github.com/abaktiar/ql-input#readme","bugs":{"url":"https://github.com/abaktiar/ql-input/issues"},"dist":{"shasum":"553e797311f7b404d29aed38625ed66b22010777","tarball":"https://registry.npmjs.org/@abaktiar/ql-parser/-/ql-parser-1.3.0.tgz","fileCount":4,"integrity":"sha512-lC8HCvYeg/7592QzlkVIMQz8CIRHbu/09nLJPERcLeQ3pOn/4nn9uF5S7cC7LNkQg79+omEupSbANaRSfTLJ0Q==","signatures":[{"sig":"MEUCIQD0EHgBHpn6JskHICYNxRcGZ4aq9dLdZqqbw+zVOqGSKAIgRKboa7S82XF0K3VASQ2yd1EWrzrm1uCk4+Jbq8afVvs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":41940},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"3f464c32d99b415e3b1b3c69fb2c3a2e2f8bff23","_npmUser":{"name":"abaktiar","email":"dev.baktiar@gmail.com"},"repository":{"url":"git+https://github.com/abaktiar/ql-input.git","type":"git"},"_npmVersion":"10.8.2","description":"Framework-agnostic QL (Query Language) parser and builder for creating complex queries with support for logical operators, functions, and ORDER BY clauses","directories":{},"sideEffects":false,"_nodeVersion":"20.19.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/ql-parser_1.3.0_1748064056054_0.4249146037103968","host":"s3://npm-registry-packages-npm-production"}},"1.3.1":{"name":"@abaktiar/ql-parser","version":"1.3.1","keywords":["query","parser","ql","typescript","query-language","expression-parser","query-builder","logical-operators","framework-agnostic"],"author":{"name":"abaktiar"},"license":"MIT","_id":"@abaktiar/ql-parser@1.3.1","maintainers":[{"name":"abaktiar","email":"dev.baktiar@gmail.com"}],"homepage":"https://github.com/abaktiar/ql-input#readme","bugs":{"url":"https://github.com/abaktiar/ql-input/issues"},"dist":{"shasum":"9e2296b8514c316fdd94853b056a9a7461d7fd45","tarball":"https://registry.npmjs.org/@abaktiar/ql-parser/-/ql-parser-1.3.1.tgz","fileCount":5,"integrity":"sha512-xJo0DurWAsC0rDZFYCETjchkszDgeraCBOXUYVEspgIemoE5/q/Wtu06l922a6kLDofhIccMiWYeSbmLoNrK7Q==","signatures":[{"sig":"MEUCIA6AeHVhJdd4weYues5jE8WSuwXqGJHO5aM1g44yMN2LAiEAhxwphNNZ9jeWxbOVld6yZsEa6bcOeyafEKdgM4qFvGg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":48286},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"16992089ad1cda03c9fdb1255974315e25130a28","_npmUser":{"name":"abaktiar","email":"dev.baktiar@gmail.com"},"repository":{"url":"git+https://github.com/abaktiar/ql-input.git","type":"git"},"_npmVersion":"10.8.2","description":"Framework-agnostic QL (Query Language) parser and builder for creating complex queries with support for logical operators, functions, and ORDER BY clauses","directories":{},"sideEffects":false,"_nodeVersion":"20.19.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/ql-parser_1.3.1_1748345839935_0.03280990666012018","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"@abaktiar/ql-parser","version":"1.4.0","keywords":["query","parser","ql","typescript","query-language","expression-parser","query-builder","logical-operators","parameterized-functions","framework-agnostic","jql"],"author":{"name":"abaktiar"},"license":"MIT","_id":"@abaktiar/ql-parser@1.4.0","maintainers":[{"name":"abaktiar","email":"dev.baktiar@gmail.com"}],"homepage":"https://github.com/abaktiar/ql-input#readme","bugs":{"url":"https://github.com/abaktiar/ql-input/issues"},"dist":{"shasum":"87e4bb3fd42555a22a8ec8c7dbd64155d1369759","tarball":"https://registry.npmjs.org/@abaktiar/ql-parser/-/ql-parser-1.4.0.tgz","fileCount":5,"integrity":"sha512-UTjrbaVwshcu9Zj1hr4TRTOIH3BVdfgVJdVPfVOFG0ymP9/MZK4IJVRUkeQpDBS/5CnxBcPQM0hnNLTDGWPFnA==","signatures":[{"sig":"MEUCIQCFvNWEXrxSz/MeRC5yGUs1lhyQvNNiuXWszXjUe78glAIgaXdM2i7mkssLz3bVkjNE7IMHcJo1YhtDz3iSBJI+3xw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":53338},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"d55521804cdcb28d7666022f149cf4721e31ebee","_npmUser":{"name":"abaktiar","email":"dev.baktiar@gmail.com"},"repository":{"url":"git+https://github.com/abaktiar/ql-input.git","type":"git"},"_npmVersion":"10.8.2","description":"Framework-agnostic QL (Query Language) parser and builder for creating complex queries with support for logical operators, parameterized functions, and ORDER BY clauses","directories":{},"sideEffects":false,"_nodeVersion":"20.19.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/ql-parser_1.4.0_1748442491292_0.5843939258749711","host":"s3://npm-registry-packages-npm-production"}},"1.5.0":{"name":"@abaktiar/ql-parser","version":"1.5.0","description":"Framework-agnostic QL (Query Language) parser and builder for creating complex queries with support for logical operators, parameterized functions, and ORDER BY clauses","main":"./index.js","module":"./index.mjs","types":"./index.d.ts","exports":{".":{"import":"./index.mjs","require":"./index.js","types":"./index.d.ts"}},"keywords":["query","parser","ql","typescript","query-language","expression-parser","query-builder","logical-operators","parameterized-functions","framework-agnostic","jql"],"author":{"name":"abaktiar"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/abaktiar/ql-input.git"},"bugs":{"url":"https://github.com/abaktiar/ql-input/issues"},"homepage":"https://github.com/abaktiar/ql-input#readme","engines":{"node":">=16.0.0"},"sideEffects":false,"_id":"@abaktiar/ql-parser@1.5.0","gitHead":"73b48921a26b488fd187edc4e7d8ec5abe90224f","_nodeVersion":"20.19.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-u3znDhbbAi5v4NInYVzALpb7kEz1W0v1NEoqDKFmqchhTzfv44HBPcPOxv60IfvHIQooszciz6Qv7l6dO+Chmg==","shasum":"c4b06a4185aa712a7704b0b5327ad740cb80dbb0","tarball":"https://registry.npmjs.org/@abaktiar/ql-parser/-/ql-parser-1.5.0.tgz","fileCount":5,"unpackedSize":53829,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDOQRZleD1ZEdEldM18I5+WggO+QrItehdzMHgBwPcrcgIhAPK+8926cH8BnAd1ZynoBCFnwJhh7FNTsjKXQVoUamjj"}]},"_npmUser":{"name":"abaktiar","email":"dev.baktiar@gmail.com"},"directories":{},"maintainers":[{"name":"abaktiar","email":"dev.baktiar@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ql-parser_1.5.0_1749226088915_0.12362057528359371"},"_hasShrinkwrap":false}},"time":{"created":"2025-05-24T01:33:40.906Z","modified":"2025-06-06T16:08:09.378Z","1.0.0":"2025-05-24T01:33:41.185Z","1.0.1":"2025-05-24T01:38:18.234Z","1.1.0":"2025-05-24T02:24:14.542Z","1.2.0":"2025-05-24T03:22:49.989Z","1.3.0":"2025-05-24T05:20:56.223Z","1.3.1":"2025-05-27T11:37:20.143Z","1.4.0":"2025-05-28T14:28:11.453Z","1.5.0":"2025-06-06T16:08:09.110Z"},"bugs":{"url":"https://github.com/abaktiar/ql-input/issues"},"author":{"name":"abaktiar"},"license":"MIT","homepage":"https://github.com/abaktiar/ql-input#readme","keywords":["query","parser","ql","typescript","query-language","expression-parser","query-builder","logical-operators","parameterized-functions","framework-agnostic","jql"],"repository":{"type":"git","url":"git+https://github.com/abaktiar/ql-input.git"},"description":"Framework-agnostic QL (Query Language) parser and builder for creating complex queries with support for logical operators, parameterized functions, and ORDER BY clauses","maintainers":[{"name":"abaktiar","email":"dev.baktiar@gmail.com"}],"readme":"# @abaktiar/ql-parser\n\nA powerful, framework-agnostic QL (Query Language) parser and builder for creating complex queries with support for logical operators, functions, parentheses grouping, and ORDER BY clauses.\n\n**🌐 [Live Demo](https://ql-input.netlify.app/)** - See the parser in action with the React component!\n\n[![npm version](https://badge.fury.io/js/@abaktiar%2Fql-parser.svg)](https://badge.fury.io/js/@abaktiar%2Fql-parser)\n[![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n## 🎉 What's New in v1.5.0\n\n🔧 **Enhanced Function System** - Comprehensive parameterized function support with type validation  \n🧮 **Improved Expression Trees** - Better parsing for complex nested expressions and function calls  \n🎯 **Parameter Validation** - Robust validation for function parameters with descriptive error messages  \n📝 **Extended Documentation** - Comprehensive examples and migration guides for parameterized functions\n\n## ✨ Features\n\n- 🔍 **Complete Query Parsing** - Parse complex QL queries into structured AST\n- 🧮 **Expression Trees** - Build hierarchical expression trees with proper operator precedence\n- 🔧 **Query Building** - Convert parsed queries to MongoDB, SQL, or custom formats\n- 📝 **TypeScript Support** - Full type safety with comprehensive interfaces\n- 🎯 **Parentheses Grouping** - Support for complex condition grouping\n- 📊 **ORDER BY Support** - Sorting clauses with ASC/DESC directions\n- 🔄 **Function Support** - Built-in functions like `currentUser()`, `now()`, etc.\n- ⚡ **Zero Dependencies** - Lightweight with no external dependencies\n- 🌐 **Framework Agnostic** - Works with any JavaScript framework or vanilla JS\n\n## 📦 Installation\n\n```bash\nnpm install @abaktiar/ql-parser\n```\n\n```bash\nyarn add @abaktiar/ql-parser\n```\n\n```bash\npnpm add @abaktiar/ql-parser\n```\n\n## 🚀 Quick Start\n\n```typescript\nimport { QLParser, QLInputConfig } from '@abaktiar/ql-parser';\n\n// Define your field configuration\nconst config: QLInputConfig = {\n  fields: [\n    {\n      name: 'status',\n      displayName: 'Status',\n      type: 'option',\n      operators: ['=', '!=', 'IN', 'NOT IN'],\n      options: [\n        { value: 'open', label: 'Open' },\n        { value: 'closed', label: 'Closed' },\n        { value: 'pending', label: 'Pending' }\n      ]\n    },\n    {\n      name: 'assignee',\n      displayName: 'Assignee',\n      type: 'user',\n      operators: ['=', '!=', 'IS EMPTY', 'IS NOT EMPTY']\n    },\n    {\n      name: 'created',\n      displayName: 'Created Date',\n      type: 'date',\n      operators: ['=', '>', '<', '>=', '<='],\n      sortable: true\n    }\n  ],\n  maxSuggestions: 10,\n  caseSensitive: false,\n  allowParentheses: true,\n  allowOrderBy: true,\n  allowFunctions: true\n};\n\n// Create parser instance\nconst parser = new QLParser(config);\n\n// Parse a query\nconst query = parser.parse('status = \"open\" AND (assignee = currentUser() OR assignee IS EMPTY) ORDER BY created DESC');\n\nconsole.log(query);\n// Output: Structured QLQuery object with parsed expressions and order by clause\n```\n\n## 📖 Core Concepts\n\n### Query Structure\n\nA QL query consists of:\n1. **WHERE clause** - Conditions and logical operators\n2. **ORDER BY clause** - Sorting specifications (optional)\n\n```\nstatus = \"open\" AND assignee = currentUser() ORDER BY created DESC, priority ASC\n```\n\n### Supported Operators\n\n#### Comparison Operators\n- `=` - Equals\n- `!=` - Not equals\n- `>` - Greater than\n- `<` - Less than\n- `>=` - Greater than or equal\n- `<=` - Less than or equal\n\n#### Text Operators\n- `~` - Contains (case-insensitive)\n- `!~` - Does not contain\n\n#### List Operators\n- `IN` - Value in list\n- `NOT IN` - Value not in list\n\n#### Null Operators\n- `IS EMPTY` - Field is empty/null\n- `IS NOT EMPTY` - Field is not empty/null\n\n#### Logical Operators\n- `AND` - Logical AND\n- `OR` - Logical OR\n- `NOT` - Logical NOT (prefix)\n\n### Functions\n\nBuilt-in functions for dynamic values:\n\n#### Parameterless Functions\n- `currentUser()` - Current user identifier\n- `now()` - Current timestamp\n- `today()` - Today's date\n- `startOfWeek()` - Start of current week\n- `endOfWeek()` - End of current week\n- `startOfMonth()` - Start of current month\n- `endOfMonth()` - End of current month\n\n#### Parameterized Functions\n- `daysAgo(days)` - Date N days ago from today\n  ```typescript\n  daysAgo(30)  // 30 days ago\n  daysAgo(7)   // 7 days ago\n  ```\n- `daysFromNow(days)` - Date N days from today\n  ```typescript\n  daysFromNow(14)  // 14 days from now\n  ```\n- `dateRange(start, end)` - Date range between two dates\n  ```typescript\n  dateRange(\"2023-01-01\", \"2023-12-31\")\n  ```\n- `userInRole(role)` - Users with specific role\n  ```typescript\n  userInRole(\"admin\")\n  userInRole(\"manager\")\n  ```\n- `projectsWithPrefix(prefix)` - Projects with name prefix\n  ```typescript\n  projectsWithPrefix(\"PROJ\")\n  projectsWithPrefix(\"DEV\")\n  ```\n\n#### Function Usage in Queries\nFunctions can be used in various contexts:\n- **Single conditions**: `created >= daysAgo(30)`\n- **IN lists**: `assignee IN (currentUser(), userInRole(\"admin\"))`\n- **Complex expressions**: `(created >= daysAgo(30) AND assignee = currentUser()) OR priority = \"High\"`\n- **Nested functions**: `dateRange(\"2023-01-01\", daysAgo(30))`\n\n## 🔧 API Reference\n\n### QLParser\n\nMain parser class for tokenizing and parsing QL queries.\n\n```typescript\nclass QLParser {\n  constructor(config: QLInputConfig)\n\n  // Tokenize input string into tokens\n  tokenize(input: string): QLToken[]\n\n  // Parse input string into structured query\n  parse(input: string): QLQuery\n}\n```\n\n### QLExpressionParser\n\nBuilds hierarchical expression trees from tokens.\n\n```typescript\nclass QLExpressionParser {\n  // Parse tokens into expression tree\n  parse(tokens: QLToken[]): QLExpression | null\n}\n```\n\n### Query Builder Functions\n\nConvert parsed queries to different formats:\n\n```typescript\n// Convert to MongoDB query\nfunction toMongooseQuery(query: QLQuery): object\n\n// Convert to SQL WHERE clause\nfunction toSQLQuery(query: QLQuery): string\n\n// Print expression as readable string\nfunction printExpression(expression: QLExpression): string\n\n// Count total conditions in query\nfunction countConditions(query: QLQuery): number\n```\n\n## 💡 Usage Examples\n\n### Basic Parsing\n\n```typescript\nconst parser = new QLParser(config);\n\n// Simple condition\nconst simple = parser.parse('status = \"open\"');\n\n// Multiple conditions with AND\nconst multiple = parser.parse('status = \"open\" AND priority = \"high\"');\n\n// Conditions with OR\nconst withOr = parser.parse('status = \"open\" OR status = \"pending\"');\n\n// Complex grouping with parentheses\nconst complex = parser.parse('(status = \"open\" OR status = \"pending\") AND assignee = currentUser()');\n```\n\n### Working with Functions\n\n```typescript\n// Using parameterless functions\nconst withFunctions = parser.parse(`\n  assignee = currentUser() AND\n  created >= startOfWeek() AND\n  created <= endOfWeek()\n`);\n\n// Using parameterized functions\nconst withParams = parser.parse(`\n  assignee = userInRole(\"admin\") AND\n  created >= daysAgo(30) AND\n  updated <= daysFromNow(7)\n`);\n\n// Functions with multiple parameters\nconst multiParam = parser.parse('created = dateRange(\"2023-01-01\", \"2023-12-31\")');\n\n// Functions in lists\nconst functionList = parser.parse('assignee IN (currentUser(), userInRole(\"manager\"), \"john.doe\")');\n\n// Nested function calls\nconst nested = parser.parse('created = dateRange(\"2023-01-01\", daysAgo(30))');\n\n// Complex expressions with functions\nconst complex = parser.parse(`\n  (assignee = currentUser() OR assignee = userInRole(\"admin\")) AND\n  created >= daysAgo(30) AND\n  project = projectsWithPrefix(\"PROJ\")\n`);\n```\n\n### ORDER BY Clauses\n\n```typescript\n// Single sort field\nconst singleSort = parser.parse('status = \"open\" ORDER BY created DESC');\n\n// Multiple sort fields\nconst multiSort = parser.parse('status = \"open\" ORDER BY priority ASC, created DESC');\n\n// Sort only (no WHERE clause)\nconst sortOnly = parser.parse('ORDER BY created DESC');\n```\n\n### Converting to Different Formats\n\n```typescript\nimport { toMongooseQuery, toSQLQuery, printExpression } from '@abaktiar/ql-parser';\n\nconst query = parser.parse('status = \"open\" AND assignee = currentUser()');\n\n// Convert to MongoDB query\nconst mongoQuery = toMongooseQuery(query);\nconsole.log(mongoQuery);\n// Output: { status: \"open\", assignee: \"currentUser()\" }\n\n// Convert to SQL\nconst sqlQuery = toSQLQuery(query);\nconsole.log(sqlQuery);\n// Output: \"status = 'open' AND assignee = 'currentUser()'\"\n\n// Print as readable string\nif (query.where) {\n  const readable = printExpression(query.where);\n  console.log(readable);\n  // Output: \"status = \"open\" AND assignee = currentUser()\"\n}\n```\n\n### Function Configuration\n\nYou can define custom functions with parameters in your configuration:\n\n```typescript\nconst config: QLInputConfig = {\n  fields: [...],\n  allowFunctions: true,\n  functions: [\n    {\n      name: 'currentUser',\n      displayName: 'currentUser()',\n      description: 'Current logged in user',\n    },\n    {\n      name: 'daysAgo',\n      displayName: 'daysAgo(days)',\n      description: 'Date N days ago from today',\n      parameters: [{\n        name: 'days',\n        type: 'number',\n        required: true,\n        description: 'Number of days'\n      }]\n    },\n    {\n      name: 'userInRole',\n      displayName: 'userInRole(role)',\n      description: 'Users with specific role',\n      parameters: [{\n        name: 'role',\n        type: 'text',\n        required: true,\n        description: 'User role name'\n      }]\n    },\n    {\n      name: 'dateRange',\n      displayName: 'dateRange(start, end)',\n      description: 'Date range between two dates',\n      parameters: [\n        {\n          name: 'startDate',\n          type: 'date',\n          required: true,\n          description: 'Start date'\n        },\n        {\n          name: 'endDate',\n          type: 'date',\n          required: true,\n          description: 'End date'\n        }\n      ]\n    }\n  ]\n};\n```\n\n### Function Parameter Types\n\n- `text` - String parameters (quoted in queries)\n- `number` - Numeric parameters (unquoted)\n- `date` - Date parameters (quoted)\n- `boolean` - Boolean parameters (true/false)\n\n### Error Handling\n\n```typescript\nconst query = parser.parse('invalid query syntax');\n\nif (!query.valid) {\n  console.log('Parse errors:', query.errors);\n  // Handle parsing errors\n}\n```\n\n### Working with Tokens\n\n```typescript\n// Get detailed token information\nconst tokens = parser.tokenize('status = \"open\" AND assignee = currentUser()');\n\ntokens.forEach(token => {\n  console.log(`${token.type}: \"${token.value}\" at position ${token.start}-${token.end}`);\n});\n```\n\n## 🎯 Advanced Usage\n\n### Custom Field Types\n\n```typescript\nconst config: QLInputConfig = {\n  fields: [\n    {\n      name: 'customField',\n      displayName: 'Custom Field',\n      type: 'text', // or 'number', 'date', 'datetime', 'boolean', 'option', 'multiselect', 'user'\n      operators: ['=', '!=', '~', '!~'],\n      description: 'A custom field for demonstration'\n    }\n  ],\n  // ... other config options\n};\n```\n\n### Complex Expressions\n\n```typescript\n// Nested parentheses\nconst nested = parser.parse(`\n  (status = \"open\" OR status = \"pending\") AND\n  (assignee = currentUser() OR (assignee IS EMPTY AND priority = \"high\"))\n`);\n\n// Mixed operators\nconst mixed = parser.parse(`\n  status IN (\"open\", \"pending\") AND\n  title ~ \"urgent\" AND\n  created >= startOfWeek() AND\n  assignee IS NOT EMPTY\n`);\n```\n\n### Expression Tree Traversal\n\n```typescript\nfunction traverseExpression(expr: QLExpression, depth = 0): void {\n  const indent = '  '.repeat(depth);\n\n  if (expr.type === 'condition') {\n    console.log(`${indent}Condition: ${expr.field} ${expr.operator} ${expr.value}`);\n  } else if (expr.type === 'group') {\n    console.log(`${indent}Group (${expr.operator}):`);\n    expr.conditions.forEach(child => traverseExpression(child, depth + 1));\n  }\n}\n\nconst query = parser.parse('(status = \"open\" OR status = \"pending\") AND assignee = currentUser()');\nif (query.where) {\n  traverseExpression(query.where);\n}\n```\n\n## 📚 Type Definitions\n\n### Core Types\n\n```typescript\n// Field configuration\ninterface QLField {\n  name: string;\n  displayName: string;\n  type: FieldType;\n  operators: OperatorType[];\n  sortable?: boolean;\n  description?: string;\n  options?: QLValue[];\n  asyncValueSuggestions?: boolean;\n}\n\n// Parsed query result\ninterface QLQuery {\n  where?: QLExpression;\n  orderBy?: QLOrderBy[];\n  raw: string;\n  valid: boolean;\n  errors: string[];\n}\n\n// Expression tree node\ninterface QLExpression {\n  type: 'condition' | 'group';\n  // ... additional properties based on type\n}\n```\n\n## 🤝 Related Packages\n\n- **[@abaktiar/ql-input](https://www.npmjs.com/package/@abaktiar/ql-input)** - React component with UI for this parser\n\n## 📄 License\n\nMIT © [abaktiar](https://github.com/abaktiar)\n\n## 🐛 Issues & Support\n\nPlease report issues on [GitHub Issues](https://github.com/abaktiar/ql-input/issues).\n","readmeFilename":"README.md"}