15153 . Validate a query to check if the syntax is valid.
1616 1 . _ Even if a query is returned as valid, it might still be invalid based on your Salesforce configuration_
1717
18- This library uses [ Chevrotain] ( https://github.com/SAP/chevrotain ) to parse queries. Prior to version 2.0.0, [ antlr4] ( https://github.com/antlr/antlr4 ) was used.
19-
2018Migrating from version 1 to version 2? [ Check out the changelog] ( CHANGELOG.md#200 ) for a full list of changes.
2119
2220Migrating from version 2 to version 3? [ Check out the changelog] ( CHANGELOG.md#300 ) for a full list of changes.
@@ -58,7 +56,7 @@ isQueryValid('SELECT Id Foo FROM Baz'); // false
5856
5957** General Utility**
6058
61- Many of hte utility functions are provided to easily determine the shape of specific data since there are many variations . If you are using Typescript in strict mode, you can use these to narrow types with if statements .
59+ Many of hte utility functions are provided to easily determine the shape of specific data since there are many variants . If you are using Typescript in strict mode, you can use these to narrow your types .
6260
6361| Function | Description | Arguments |
6462| --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
@@ -86,6 +84,7 @@ Many of hte utility functions are provided to easily determine the shape of spec
8684| Property | Type | Description | required | default |
8785| ---------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------- |
8886| allowApexBindVariables | boolean | Determines if apex variables are allowed in parsed query. Example: ` WHERE Id IN :accountIds ` . Only simple Apex is supported. Function calls are not supported. (e.x. ` accountMap.keyset() ` is not supported) | FALSE | FALSE |
87+ | allowPartialQuery | boolean | If provided, you can provide an incomplete soql query. This is useful if you need to parse WHERE clauses, for example. Subqueries are required to be valid. | FALSE | FALSE |
8988| ignoreParseErrors | boolean | If set to true, then queries with partially invalid syntax will still be parsed, but any clauses with invalid parts will be omitted. The SELECT clause and FROM clause must always be valid, but all other clauses can contain invalid parts. | FALSE | FALSE |
9089| logErrors | boolean | If true, parsing and lexing errors will be logged to the console. | FALSE | FALSE |
9190
@@ -117,7 +116,6 @@ Parsing a SOQL query can be completed by calling `parseQuery(soqlQueryString)`.
117116
118117``` typescript
119118import { parseQuery } from ' soql-parser-js' ;
120- // var soqlParserJs = require('soql-parser-js'); // node's require format - usage: soqlParserJs.parseQuery()
121119
122120const soql = `
123121 SELECT UserId, COUNT(Id)
@@ -127,8 +125,6 @@ const soql = `
127125 GROUP BY UserId
128126` ;
129127
130- const soqlQuery = parseQuery (soql );
131-
132128console .log (JSON .stringify (soqlQuery , null , 2 ));
133129```
134130
@@ -176,6 +172,54 @@ console.log(JSON.stringify(soqlQuery, null, 2));
176172
177173</details >
178174
175+ ### Parsing a partial query
176+
177+ Added support for ` allowPartialQuery ` in version ` 4.4.0 `
178+
179+ ``` typescript
180+ import { parseQuery } from ' soql-parser-js' ;
181+
182+ const soql = `
183+ WHERE LoginTime > 2010-09-20T22:16:30.000Z
184+ AND LoginTime < 2010-09-21T22:16:30.000Z
185+ GROUP BY UserId
186+ ` ;
187+
188+ const soqlQuery = parseQuery (soql , { allowPartialQuery: true });
189+
190+ console .log (JSON .stringify (soqlQuery , null , 2 ));
191+ ```
192+
193+ <details >
194+ <summary ><b >Results (click to show)</b ></summary >
195+
196+ ``` json
197+ {
198+ "where" : {
199+ "left" : {
200+ "field" : " LoginTime" ,
201+ "operator" : " >" ,
202+ "value" : " 2010-09-20T22:16:30.000Z" ,
203+ "literalType" : " DATETIME"
204+ },
205+ "operator" : " AND" ,
206+ "right" : {
207+ "left" : {
208+ "field" : " LoginTime" ,
209+ "operator" : " <" ,
210+ "value" : " 2010-09-21T22:16:30.000Z" ,
211+ "literalType" : " DATETIME"
212+ }
213+ }
214+ },
215+ "groupBy" : {
216+ "field" : " UserId"
217+ }
218+ }
219+ ```
220+
221+ </details >
222+
179223### Validating Queries
180224
181225``` typescript
@@ -278,6 +322,41 @@ LIMIT 150
278322
279323### Composing a partial query
280324
325+ Starting in version ` 4.4 ` , compose will not fail if there are missing ` SELECT ` and ` FROM ` clauses in your query.
326+
327+ Partial compose support it supported without any additional steps.
328+
329+ ``` typescript
330+ import { Compose , parseQuery } from ' soql-parser-js' ;
331+
332+ const soql = ` WHERE Name LIKE 'A%' AND MailingCity = 'California ` ;
333+ const parsedQuery = parseQuery (soql , { allowPartialQuery: true });
334+
335+ // Results of Parsed Query:
336+ /**
337+ {
338+ where: {
339+ left: { field: 'Name', operator: 'LIKE', value: "'A%'", literalType: 'STRING' },
340+ operator: 'AND',
341+ right: { left: { field: 'MailingCity', operator: '=', value: "'California'", literalType: 'STRING' } },
342+ },
343+ }
344+ */
345+
346+ const composedQuery = composeQuery (soqlQuery , { format: true });
347+
348+ console .log (composedQuery );
349+ ```
350+
351+ ** Results**
352+
353+ ``` sql
354+ WHERE Name LIKE ' A%' AND MailingCity = ' California
355+ ```
356+
357+ <details>
358+ <summary><b>See the alternate way to compose partial queries by calling the Compose class directly</b></summary>
359+
281360If you need to compose just a part of a query instead of the entire query, you can create an instance of the Compose class directly.
282361
283362For example, if you just need the `WHERE` clause from a query as a string, you can do the following:
@@ -331,6 +410,8 @@ parseOrderBy(orderBy: OrderByClause | OrderByClause[]): string;
331410parseWithDataCategory(withDataCategory: WithDataCategoryClause): string;
332411```
333412
413+ </details>
414+
334415## Format Query
335416
336417This function is provided as a convenience and just calls parse and compose.
@@ -418,11 +499,11 @@ WHERE Name LIKE 'a%'
418499
419500## CLI
420501
421- If you install globally, you can use the cli
502+ Install globally or use `npx` to interact with the cli.
422503
423504### Available Commands
424505
425- - ` soql-parser-js --help `
506+ - `soql-parser-js --help` (or using `npx`: `npx soql-parser-js --help`)
426507- `soql-parser-js parse --help`
427508- `soql-parser-js compose --help`
428509- `soql-parser-js format --help`
@@ -431,29 +512,29 @@ If you install globally, you can use the cli
431512
432513#### Parse
433514
434- ` soql-parser-js parse "SELECT Id FROM Account" `
515+ `npx soql-parser-js parse "SELECT Id FROM Account"`
435516
436517```bash
437518{"fields":[{"type":"Field","field":"Id"}],"sObject":"Account"}
438519```
439520
440521#### Compose
441522
442- ` soql-parser-js compose "{\"fields\":[{\"type\":\"Field\",\"field\":\"Id\"}],\"sObject\":\"Account\"}" `
523+ `npx soql-parser-js compose "{\" fields\" :[{\" type\" :\" Field\" ,\" field\" :\" Id\" }],\" sObject\" :\" Account\" }"`
443524
444525```bash
445526SELECT Id FROM Account
446527```
447528
448- ` soql-parser-js compose "{\"fields\":[{\"type\":\"Field\",\"field\":\"Id\"}],\"sObject\":\"Account\"}" --json ` or -j
529+ `npx soql-parser-js compose "{\" fields\" :[{\" type\" :\" Field\" ,\" field\" :\" Id\" }],\" sObject\" :\" Account\" }" --json` or -j
449530
450531```json
451532{ "query": "SELECT Id FROM Account" }
452533```
453534
454535#### Format
455536
456- ` soql-parser-js format "SELECT Name, COUNT(Id) FROM Account GROUP BY Name HAVING COUNT(Id) > 1" `
537+ `npx soql-parser-js format "SELECT Name, COUNT(Id) FROM Account GROUP BY Name HAVING COUNT(Id) > 1"`
457538
458539```bash
459540SELECT Name, COUNT(Id)
@@ -462,35 +543,35 @@ GROUP BY Name
462543HAVING COUNT(Id) > 1
463544```
464545
465- ` soql-parser-js format "SELECT Name, COUNT(Id) FROM Account GROUP BY Name HAVING COUNT(Id) > 1 -j `
546+ `npx soql-parser-js format "SELECT Name, COUNT(Id) FROM Account GROUP BY Name HAVING COUNT(Id) > 1 -j`
466547
467548```json
468549{ "query": "SELECT Name, COUNT(Id)\n FROM Account\n GROUP BY Name\n HAVING COUNT(Id) > 1" }
469550```
470551
471552#### Is Valid
472553
473- ` soql-parser-js valid "SELECT Id FROM Account" `
554+ `npx soql-parser-js valid "SELECT Id FROM Account"`
474555
475556```bash
476557true
477558```
478559
479- ` soql-parser-js valid "SELECT Id invalid FROM Account" `
560+ `npx soql-parser-js valid "SELECT Id invalid FROM Account"`
480561
481562ℹ️ this returns an exit code of 1
482563
483564```bash
484565false
485566```
486567
487- ` soql-parser-js valid "SELECT Id FROM Account -j `
568+ `npx soql-parser-js valid "SELECT Id FROM Account" -j`
488569
489570```json
490571{ "isValid": true }
491572```
492573
493- ` soql-parser-js valid "SELECT Id invalid invalid FROM Account -j `
574+ `npx soql-parser-js valid "SELECT Id invalid invalid FROM Account" -j`
494575
495576ℹ️ this returns an exit code of 0
496577
@@ -509,19 +590,20 @@ Options:
509590 -h, --help output usage information
510591
511592Commands:
512- parse [options] < query >
593+ parse [options] <sql >
513594 compose [options] <query>
514- format [options] < query >
515- valid < query >
595+ format [options] <sql >
596+ valid <sql >
516597```
517598
518599`soql-parser-js parse --help`
519600
520601```bash
521- Usage: parse [options] < query >
602+ Usage: parse [options] <sql >
522603
523604Options:
524605 -a, --allow-apex allow apex bind variables
606+ -p, --allow-partial allow partial queries
525607 -i, --ignore-errors ignore parse errors, return as much of query as possible
526608 -h, --help output usage information
527609```
@@ -544,9 +626,11 @@ Options:
544626`soql-parser-js format --help`
545627
546628```bash
547- Usage: format [options] < query >
629+ Usage: format [options] <sql >
548630
549631Options:
632+ -a, --allow-apex allow apex bind variables
633+ -p, --allow-partial allow partial queries
550634 -i --indent <chars> number of tab characters to indent (default: 1)
551635 -m --line-length <chars> max number of characters per lins (default: 60)
552636 -s --subquery-parens-new-line subquery parens on own line
@@ -558,9 +642,11 @@ Options:
558642`soql-parser-js valid --help`
559643
560644```bash
561- Usage: valid [options] < query >
645+ Usage: valid [options] <sql >
562646
563647Options:
648+ -a, --allow-apex allow apex bind variables
649+ -p, --allow-partial allow partial queries
564650 -j, --json output as JSON
565651 -h, --help output usage information
566652```
@@ -699,7 +785,7 @@ export interface FieldTypeOfCondition {
699785}
700786
701787export interface QueryBase {
702- fields: FieldType [];
788+ fields? : FieldType[];
703789 sObjectAlias?: string;
704790 usingScope?: string;
705791 where?: WhereClause;
@@ -714,7 +800,7 @@ export interface QueryBase {
714800}
715801
716802export interface Query extends QueryBase {
717- sObject: string ;
803+ sObject? : string;
718804}
719805
720806export interface Subquery extends QueryBase {
0 commit comments