Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

soql-parser-js

Package Overview
Dependencies
Maintainers
1
Versions
90
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

soql-parser-js - npm Package Compare versions

Comparing version 1.2.1 to 2.0.0-rc.1

dist_esm/api/api-models.js

182

CHANGELOG.md
# Changelog
## 2.0.0
### Summary
Version 2.0 brings some significant bundle size and performance improvements. This library now uses [Chevrotain](https://github.com/SAP/chevrotain) instead of [antlr4](https://github.com/antlr/antlr4). With this change, everything related to parsing had to be re-written from scratch. Chevrotain uses pure javascript to handle lexing, parsing, and visiting the generated ast/cst as opposed to using a grammar file and generating a javascript parser based on the grammar.
With this change, the data model was reviewed and analyzed, and there are some significant breaking changes to the data structures. Review the 🔥breaking changes🔥 below for a detailed description of each breaking change.
#### Bundle Size
`soql-parser-js` bundles all of the library code and two dependencies `chevrotain` and `regexp-to-ast` (required by chevrotain) into the javascript bundle. Previously, `antlr4` was not bundled and was required to be installed separately.
The following bundle size uses the default webpack configuration (e.x. `npx webpack`) with no webpack configuration explicitly defined.
```javascript
var soqlParser = require('soql-parser-js');
const query = soqlParser.parseQuery(`SELECT Id FROM Account WHERE Id = 'FOO'`);
console.log('query', query);
const soql = soqlParser.composeQuery(query);
console.log('soql', soql);
```
- Version 1.x: **545kb**
- Version 2.0: **197kb**
#### Benchmarks
Here is an example benchmark of parsing all the unit tests 1,000 times
```
OLD PARSER: ~6.2 seconds for ~60K parses
NEW PARSER AFTER OPTIMIZATION: ~2.25 seconds for 60K parses
```
### Breaking Changes 🔥
#### General Changes
- The CLI was removed.
- The `parseQuery()` function no longer accepts `options` as a second parameter.
- `rawValue` will always have a space between parameters `GROUPING(Id, BillingCountry)`
- Some `literalType` values may have differing case from prior versions, regardless of the data input.
- `TRUE`, `FALSE`, and all functions except those listed below will always be returned in uppercase, regardless of case of input.
- **Exceptions**:
- `toLabel`, `convertTimezone`, `convertCurrency` will always be in camelCase.
- Added new available types for `DateLiteral` and `DateNLiteral`.
#### Compose Query
- `getComposedField()` is deprecated, you should now use `getField()`. `getComposedField()` will remain available for backward compatibility.
- `getField()`/`getComposedField()` has the following changes:
1. `fn` property is has been deprecated (but still exists), you should now use `functionName` instead.
2. The `from` property has been removed for subqueries. The `relationshipName` is required to be populated to compose a subquery.
- On the FormatOptions interface `fieldMaxLineLen` was renamed to `fieldMaxLineLength`.
```diff
export interface FormatOptions {
numIndent?: number;
- fieldMaxLineLen?: number;
+ fieldMaxLineLength?: number;
fieldSubqueryParensOnOwnLine?: boolean;
whereClauseOperatorsIndented?: boolean;
logging?: boolean;
}
```
#### Parse Query
- `rawValue` will now be included on `Field` if `objectPrefix` is defined.
- `alias` may be included on `Field`, if defined.
- On `FieldFunctionExpression`, `fn` was renamed to `functionName`. this was done because all other usages of `fn` were `FunctionExp`, but it was a string in this case.
- The `parameters` type on `FieldFunctionExpression` was modified to allow an array of varying types.
- Removed `from` property from `FieldSubquery`.
- `having` was removed from `QueryBase` and now lives as a property on `GroupByClause`.
- On the `Condition` object, `literalType` may be an array. This will be an array if `value` is an array and there are variable types within the `value`. For example: `WHERE Foo IN ('a', null, 'b')` would produce `literalType: ['STRING', 'NULL', 'STRING']`.
- The `GroupByClause` has the following modifications:
- `field` is now optional, and will be populated only if the grouping is on a single field.
- `type` has been renamed to `fn` and will be populated when `CUBE` and `ROLLUP` are used.
- The `having` clause has been moved as a top-level property to the `GroupByClause` and will be populated only if a `having` clause is present.
- The `HavingCondition` now has a `literalType` that will be populated with the type of the `value` property.
- `FunctionExp` has the following modifications
- `text` was renamed to `rawValue` to be more consistent with other places in the data model.
- `name` was renamed to `functionName`.
- `parameter` was renamed to `parameters` and the type was changed to `(string | FunctionExp)[]` to support nested functions. This will ALWAYS be an array now even if there is only one parameter.
```diff
export interface Field {
type: 'Field';
field: string;
objectPrefix?: string;
+ rawValue?: string;
+ alias?: string;
}
export interface FieldFunctionExpression {
type: 'FieldFunctionExpression';
- fn: string;
+ functionName: string;
- parameters?: string[] | FieldFunctionExpression[];
+ parameters?: (string | FieldFunctionExpression)[];
alias?: string;
isAggregateFn?: boolean;
rawValue?: string;
}
export interface FieldRelationship {
type: 'FieldRelationship';
field: string;
relationships: string[];
objectPrefix?: string;
rawValue?: string;
+ alias?: string;
}
export interface FieldSubquery {
type: 'FieldSubquery';
subquery: Subquery;
- from?: string;
}
export interface QueryBase {
fields: FieldType[];
sObjectAlias?: string;
where?: WhereClause;
limit?: number;
offset?: number;
groupBy?: GroupByClause;
- having?: HavingClause;
orderBy?: OrderByClause | OrderByClause[];
withDataCategory?: WithDataCategoryClause;
withSecurityEnforced?: boolean;
for?: ForClause;
update?: UpdateClause;
}
export interface Condition {
openParen?: number;
closeParen?: number;
logicalPrefix?: LogicalPrefix;
field?: string;
fn?: FunctionExp;
operator: Operator;
value?: string | string[];
valueQuery?: Query;
- literalType?: LiteralType;
+ literalType?: LiteralType | LiteralType[];
dateLiteralVariable?: number;parsed
}
export interface GroupByClause {
- field: string | string[];
+ field?: string | string[];
- type?: GroupByType;
+ fn?: FunctionExp;
+ having?: HavingClause;
}
export interface HavingCondition {
openParen?: number;
closeParen?: number;
field?: string;
fn?: FunctionExp;
operator: string;
value: string | number;
+ literalType?: String;
}
export interface FunctionExp {
- text?: string;
+ rawValue?: string;
- name?: string;
+ functionName?: string;
alias?: string;
- parameter?: string | string[];
+ parameters?: (string | FunctionExp)[];
isAggregateFn?: boolean;
- fn?: FunctionExp;
}
```
## 1.2.1

@@ -4,0 +186,0 @@

73

package.json
{
"name": "soql-parser-js",
"version": "1.2.1",
"description": "Salesforce.com SOQL parser.",
"version": "2.0.0-rc.1",
"description": "Salesforce.com SOQL parser and composer",
"main": "dist/index.js",
"module": "dist/index.es.js",
"types": "dist/index.d.ts",
"bin": {
"soql": "dist/cli.js"
},
"module": "dist_esm/index.js",
"types": "dist/src/index.d.ts",
"scripts": {
"clean": "rm -rf ./dist/*",
"test": "TS_NODE_PROJECT=\"test/tsconfig.test.json\" mocha -r ts-node/register test/**/*.spec.ts -P test/tsconfig.test.json",
"debug": "TS_NODE_PROJECT=\"tsconfig.json\" ts-node ./debug/test.ts -P tsconfig.json",
"clean:esm": "rm -rf ./dist_esm/*",
"prebuild": "npm run clean",
"build": "rollup -c",
"build": "npm-run-all compile bundle:regular bundle:min build:esm",
"build:esm": "npm-run-all clean:esm compile:esm",
"compile": "tsc",
"compile:esm": "tsc --project tsconfig-esm.json",
"bundle:regular": "webpack --config webpack-regular.config.js",
"bundle:min": "webpack --config webpack-min.config.js",
"tsc": "./node_modules/.bin/tsc",
"preantlr": "rm -rf lib/generated/*",
"antlr": "npm run preantlr && ./node_modules/.bin/antlr4ts -visitor SOQL.g4 -o lib/generated/",
"release": "release-it",
"update-docs": "cd docs && npm run update",
"update-docs:no-git": "cd docs && npm run deploy"
"test": "TS_NODE_PROJECT=\"test/tsconfig.json\" mocha --timeout 10000 -r ts-node/register test/**/*.spec.ts -P test/tsconfig.json"
},
"author": "Austin Turner <paustint@gmail.com>",
"license": "MIT",
"files": [
"dist_esm/**/*.js",
"lib/src/**/*.js",
"lib/src/**/*.d.ts",
"lib/index.js",
"lib/index.min.js",
"lib/main.licenses.txt",
"README.md",
"LICENSE.txt",
"CHANGELOG.md"
],
"dependencies": {
"@types/lodash": "^4.14.136",
"antlr4ts": "0.4.1-alpha.0",
"lodash": "^4.17.14",
"minimist": "^1.2.0"
"chevrotain": "^6.5.0",
"lodash.get": "^4.4.2"
},
"devDependencies": {
"@types/chai": "^4.1.6",
"@types/minimist": "^1.2.0",
"@types/mocha": "^5.2.5",
"@types/node": "^8.0.14",
"antlr4ts-cli": "0.4.0-alpha.4",
"@types/chai": "^4.2.3",
"@types/lodash.get": "^4.4.6",
"@types/mocha": "^5.2.7",
"@types/node": "^12.7.5",
"chai": "^4.1.2",
"lodash.get": "^4.4.2",
"magic-string": "^0.25.1",
"chalk": "^2.4.2",
"jsonfile": "^5.0.0",
"license-webpack-plugin": "^2.1.2",
"mocha": "^5.2.0",
"release-it": "^12.3.3",
"rollup": "^0.66.6",
"rollup-plugin-cli": "^0.1.5",
"rollup-plugin-typescript2": "^0.21.1",
"npm-run-all": "^4.1.5",
"release-it": "^12.4.1",
"string-replace-loader": "^2.2.0",
"ts-node": "^7.0.1",
"typescript": "^2.4.1"
"typescript": "^3.6.3",
"webpack": "^4.40.2",
"webpack-cli": "^3.3.9"
},

@@ -52,3 +60,6 @@ "peerDependencies": {},

"soql",
"Salesforce"
"salesforce",
"parse",
"compose",
"parser"
],

@@ -55,0 +66,0 @@ "repository": {

@@ -9,28 +9,63 @@ # SOQL Parser JS

:sunny: This library allows parsing Salesforce SOQL queries using JavaScript or Typescript. Works in the browser and node. :sunny:
**This library allows parsing and composing SOQL queries from Salesforce using JavaScript or Typescript.**
SOQL Parser JS provides the following capabilities:
**Available Features:**
1. Parse a SOQL query into a usable data structure.
2. Turn a parsed data structure back into a well formed SOQL query with various format options.
3. Check if a SOQL query is syntactically valid (**note**: some cases may be structurally valid but not allowed by Salesforce, e.x. invalid field name).
1. Parse SOQL queries into a common `Query` data structure.
2. Compose a `Query` data structure back into a SOQL query.
3. Validate a query to check if the syntax is valid. (Note: even if a query is valid, it might still be invalid based on your org configuration)
This library is written in Typescript and all type definitions are included with the library for your benefit if you choose to use Typescript or use VSCode's automatic type checking.
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. The move to Chevrotain provided a 35% performance improvement and resulted in a 36% decrease in bundle size. :tada:
:warning: antlr4 is dependency for this library and is a rather large library (~600 KB) and is required for the parser to function. Consider using dynamic imports to achieve lazy loading.
Want to try it out? [Check out the demo](https://paustint.github.io/soql-parser-js/).
## Examples
## Quick Start
Want to try it out? [Check out the demo](https://paustint.github.io/soql-parser-js/).
```javascript
import { parseQuery, composeQuery, isQueryValid } from 'soql-parser-js';
Look through the [unit tests](./test/TestCases.ts) for additional examples.
const query = parseQuery(`SELECT Id FROM Account WHERE Id = 'FOO'`);
console.log('query', query);
# Usage
const soql = composeQuery(query);
console.log('soql', soql); // SELECT Id FROM Account WHERE Id = 'FOO'
## Parsing
isQueryValid('SELECT Id, Foo FROM Baz'); // true
isQueryValid('SELECT Id Foo FROM Baz'); // false
```
Parsing a SOQL query can be completed by calling `parseQuery(soqlQueryString, options)`. A `Query` data structure will be returned;
## Available Features
#### Typescript / ES6
| Function | Description | Arguments |
| ------------ | ------------------------------------------------------ | ------------------------------------------ |
| parseQuery | Parse a SOQL query string into a Query data structure. | soql: Query |
| isQueryValid | Returns true if the query was able to be parsed. | soql: Query |
| composeQuery | Turn a Query object back into a SOQL statement | soql: Query<br> config?: SoqlComposeConfig |
| formatQuery | Format a SOQL query string. | soql: Query<br> config?: FormatOptions |
**SoqlComposeConfig**
| Property | Type | Description | required | default |
| ------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | ------- |
| format | boolean | Apply formatting the the composed query. This will result in a multi-line soql statement. | FALSE | TRUE |
| formatOptions | FormatOptions | Options to apply to the formatter. | FALSE | |
| autoCompose | boolean | If you need to compose just part of a query, you can create your own instance of the Compose class and set this to false, then call any methods that you need to just for what you would like to turn into a SOQL query. | FALSE | TRUE |
| logging | boolean | Print out logging statements to the console about the format operation. | FALSE | FALSE |
**FormatOptions**
| Property | Type | Description | required | default |
| ---------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------ | -------- | ------- |
| numIndent | number | The number of tab characters to indent. | FALSE | 1 |
| fieldMaxLineLength | number | The number of characters that the fields should take up before making a new line. Set this to 1 to have every field on its own line. | FALSE | 60 |
| fieldSubqueryParensOnOwnLine | boolean | If true, the opening and closing parentheses will be on their own line for subqueries. | FALSE | TRUE |
| whereClauseOperatorsIndented | boolean | If true, indents the where clause operators | FALSE | FALSE |
| logging | boolean | Print out logging statements to the console about the format operation. | FALSE | FALSE |
## Examples
### Parsing Queries
Parsing a SOQL query can be completed by calling `parseQuery(soqlQueryString)`. A `Query` data structure will be returned.
```typescript

@@ -45,3 +80,3 @@ import { parseQuery } from 'soql-parser-js';

AND LoginTime < 2010-09-21T22:16:30.000Z
GROUP BY UserId';
GROUP BY UserId
`;

@@ -54,3 +89,4 @@

**Results**
<details>
<summary><b>Results (click to show)</b></summary>

@@ -66,6 +102,6 @@ ```json

"type": "FieldFunctionExpression",
"rawValue": "COUNT(Id)",
"fn": "COUNT",
"functionName": "COUNT",
"parameters": ["Id"],
"isAggregateFn": true,
"parameters": ["Id"]
"rawValue": "COUNT(Id)"
}

@@ -97,13 +133,21 @@ ],

#### Options
</details>
### Validating Queries
```typescript
export interface SoqlQueryConfig {
continueIfErrors?: boolean; // default=false
logging: boolean; // default=false
}
import { isQueryValid } from 'soql-parser-js';
// var soqlParserJs = require('soql-parser-js'); // node's require format - usage: soqlParserJs.parseQuery()
const invalidSoql = `SELECT UserId, COUNT(Id) Account`;
const validSoql = `SELECT UserId, COUNT(Id) Account`;
console.log(isQueryValid(soql));
console.log(isQueryValid(soql));
```
## Composing
### Composing Queries
Build a `Query` data structure to have it converted back into a SOQL query.
Composing a query will turn a Query object back to a SOQL query string. The exact same data structure returned from `parseQuery()` can be used,

@@ -113,51 +157,21 @@ but depending on your use-case, you may need to build your own data structure to compose a query.

:page_facing_up: **Note:** Some operators may be converted to upper case (e.x. NOT, AND)
Some utility methods have been provided to make it easier to build the field data structures.
:page_facing_up: **Note:** There are a number of fields populated on the Query object when `parseQuery()` is called that are not required to compose a query. Look at the examples below and the comments in the data model for more information.
**Note:** Some operators may be converted to upper case (e.x. NOT, AND)
**The base query object is shaped like this:**
**Note:** There are a number of fields populated on the Query object when `parseQuery()` is called that are not required to compose a query. Look at the examples below and the comments in the data model for more information.
```typescript
export interface QueryBase {
fields: FieldType[];
sObjectAlias?: string;
where?: WhereClause;
limit?: number;
offset?: number;
groupBy?: GroupByClause;
having?: HavingClause;
orderBy?: OrderByClause | OrderByClause[];
withDataCategory?: WithDataCategoryClause;
for?: ForClause;
update?: UpdateClause;
}
```
import { composeQuery, getField, Query } from 'soql-parser-js';
The easiest way to build the fields is to call the utility function `getComposedField()`.
### Example
This is the query that will be composed programmatically
```sql
SELECT Id, Name, FORMAT(Amount) MyFormattedAmount,
(SELECT Quantity, ListPrice, PricebookEntry.UnitPrice, PricebookEntry.Name FROM OpportunityLineItems)
FROM Opportunity
WHERE CreatedDate > LAST_N_YEARS:1
AND StageName = 'Closed Won'
LIMIT 150
```
```typescript
import { composeQuery, getComposedField } from 'soql-parser-js';
// Build a subquery
const oppLineItemsSubquery = {
fields: [
getComposedField('Quantity'),
getComposedField('ListPrice'),
getComposedField({
getField('Quantity'),
getField('ListPrice'),
getField({
field: 'UnitPrice',
relationships: ['PricebookEntry'],
}),
getComposedField({
getField({
field: 'Name',

@@ -170,12 +184,13 @@ relationships: ['PricebookEntry'],

const soqlQuery = {
// build the main query and add the subquery as a field
const soqlQuery: Query = {
fields: [
getComposedField('Id'),
getComposedField('Name'),
getComposedField({
fn: 'FORMAT',
getField('Id'),
getField('Name'),
getField({
functionName: 'FORMAT',
parameters: 'Amount',
alias: 'MyFormattedAmount',
}),
getComposedField({ subquery: oppLineItemsSubquery }),
getField({ subquery: oppLineItemsSubquery }),
],

@@ -209,32 +224,15 @@ sObject: 'Opportunity',

In the example above, we made use of `getComposedField(input: string | ComposeFieldInput)` to compose the fields. The input expects a string or one of the following data structures listed below. An error will be thrown if the data passed in is not one of the following shapes.
**Results**
This returns a `FieldType` object.
```typescript
export interface ComposeField {
field: string;
objectPrefix?: string;
}
export interface ComposeFieldFunction {
fn: string;
parameters?: string | string[] | FieldFunctionExpression | FieldFunctionExpression[];
alias?: string;
}
export interface ComposeFieldRelationship {
field: string;
relationships: string[];
objectPrefix?: string;
}
export interface ComposeFieldSubquery {
subquery?: Subquery;
}
export interface ComposeFieldTypeof {
field: string;
conditions: FieldTypeOfCondition[];
}
```sql
SELECT Id, Name, FORMAT(Amount) MyFormattedAmount,
(
SELECT Quantity, ListPrice, PricebookEntry.UnitPrice,
PricebookEntry.Name
FROM OpportunityLineItems
)
FROM Opportunity
WHERE CreatedDate > LAST_N_YEARS:1
AND StageName = 'Closed Won'
LIMIT 150
```

@@ -281,3 +279,2 @@

// Name = 'Foo'
}

@@ -287,26 +284,2 @@

## Checking if a Query is Valid
This will parse a Query to confirm valid syntax, but will not parse into the Query data structure, which will have a small performance gain.
This method is faster than parsing the full query.
Options:
```typescript
export interface ConfigBase {
logging: boolean; // default=false
}
```
```typescript
import { isQueryValid } from 'soql-parser-js';
const soql =
'SELECT UserId, COUNT(Id) from LoginHistory WHERE LoginTime > 2010-09-20T22:16:30.000Z AND LoginTime < 2010-09-21T22:16:30.000Z GROUP BY UserId';
const isValid = isQueryValid(soql);
console.log(isValid);
```
## Format Query

@@ -324,3 +297,3 @@

const formattedQuery2 = formatQuery(query, {
fieldMaxLineLen: 20,
fieldMaxLineLength: 20,
fieldSubqueryParensOnOwnLine: false,

@@ -398,27 +371,2 @@ whereClauseOperatorsIndented: true,

### Options
```typescript
export interface SoqlQueryConfig {
continueIfErrors?: boolean; // default=false
logging: boolean; // default=false
includeSubqueryAsField: boolean; // default=true
}
export interface SoqlComposeConfig {
logging: boolean; // default=false
format: boolean; // default=false
formatOptions?: FormatOptions;
autoCompose: boolean; // default=true
}
export interface FormatOptions {
numIndent?: number; // default=1
fieldMaxLineLen?: number; // default=60
fieldSubqueryParensOnOwnLine?: boolean; // default=true
whereClauseOperatorsIndented?: boolean; // default=false
logging?: boolean; // default=false
}
```
## Utility Functions

@@ -428,3 +376,3 @@

1. `getComposedField(input: string | ComposeFieldInput)`
1. `getField(input: string | ComposeFieldInput)`
1. Convenience method to construct fields in the correct data format. See example usage in the Compose example.

@@ -434,3 +382,3 @@ 2. `isSubquery(query: Query | Subquery)`

3. `getFlattenedFields(query: Query)`
1. Flatten a Salesforce record based on the parsed SOQL Query. this is useful if you have relationships in your query and want to show the results in a table, using `.` dot notation for the relationship fields.
1. Flatten a Salesforce record based on the parsed SOQL Query. this is useful if you have relationships in your query and want to show the results in a table, using `.` dot notation for the relationship field headings.
2. Refer to `tests/publicUtils.spec.ts` for usage examples.

@@ -440,4 +388,2 @@

These are all available for import in your typescript projects
### Query

@@ -453,12 +399,3 @@

export type UpdateClause = 'TRACKING' | 'VIEWSTAT';
export type LiteralType =
| 'STRING'
| 'INTEGER'
| 'DECIMAL'
| 'BOOLEAN'
| 'NULL'
| 'DATETIME'
| 'DATE'
| 'DATE_LITERAL'
| 'DATE_N_LITERAL';
export type LiteralType = 'STRING' | 'INTEGER' | 'DECIMAL' | 'BOOLEAN' | 'NULL' | 'DATETIME' | 'DATE' | 'DATE_LITERAL' | 'DATE_N_LITERAL';
export type FieldType = Field | FieldFunctionExpression | FieldRelationship | FieldSubquery | FieldTypeOf;

@@ -468,3 +405,51 @@ export type OrderByCriterion = 'ASC' | 'DESC';

export type GroupByType = 'CUBE' | 'ROLLUP';
export type DateLiteral =
| 'YESTERDAY'
| 'TODAY'
| 'TOMORROW'
| 'LAST_WEEK'
| 'THIS_WEEK'
| 'NEXT_WEEK'
| 'LAST_MONTH'
| 'THIS_MONTH'
| 'NEXT_MONTH'
| 'LAST_90_DAYS'
| 'NEXT_90_DAYS'
| 'THIS_QUARTER'
| 'LAST_QUARTER'
| 'NEXT_QUARTER'
| 'THIS_YEAR'
| 'LAST_YEAR'
| 'NEXT_YEAR'
| 'THIS_FISCAL_QUARTER'
| 'LAST_FISCAL_QUARTER'
| 'NEXT_FISCAL_QUARTER'
| 'THIS_FISCAL_YEAR'
| 'LAST_FISCAL_YEAR'
| 'NEXT_FISCAL_YEAR';
export type DateNLiteral =
| 'YESTERDAY'
| 'NEXT_N_DAYS'
| 'LAST_N_DAYS'
| 'N_DAYS_AGO'
| 'NEXT_N_WEEKS'
| 'LAST_N_WEEKS'
| 'N_WEEKS_AGO'
| 'NEXT_N_MONTHS'
| 'LAST_N_MONTHS'
| 'N_MONTHS_AGO'
| 'NEXT_N_QUARTERS'
| 'LAST_N_QUARTERS'
| 'N_QUARTERS_AGO'
| 'NEXT_N_YEARS'
| 'LAST_N_YEARS'
| 'N_YEARS_AGO'
| 'NEXT_N_FISCAL_QUARTERS'
| 'LAST_N_FISCAL_QUARTERS'
| 'N_FISCAL_QUARTERS_AGO'
| 'NEXT_N_FISCAL_YEARS'
| 'LAST_N_FISCAL_YEARS'
| 'N_FISCAL_YEARS_AGO';
export interface Field {

@@ -474,2 +459,4 @@ type: 'Field';

objectPrefix?: string; // required if object is aliased
rawValue?: string; // only included if objectPrefix is defined
alias?: string;
}

@@ -479,4 +466,4 @@

type: 'FieldFunctionExpression';
fn: string;
parameters?: string[] | FieldFunctionExpression[];
functionName: string;
parameters?: (string | FieldFunctionExpression)[];
alias?: string;

@@ -493,2 +480,3 @@ isAggregateFn?: boolean; // not required for compose, will be populated if SOQL is parsed

rawValue?: string; // not required for compose, will be populated if SOQL is parsed with the raw value of the entire field
alias?: string;
}

@@ -499,3 +487,2 @@

subquery: Subquery;
from?: string; // not required for compose, will be populated if SOQL is parsed
}

@@ -522,5 +509,5 @@

groupBy?: GroupByClause;
having?: HavingClause;
orderBy?: OrderByClause | OrderByClause[];
withDataCategory?: WithDataCategoryClause;
withSecurityEnforced?: boolean;
for?: ForClause;

@@ -554,3 +541,3 @@ update?: UpdateClause;

valueQuery?: Query;
literalType?: LiteralType; // If populated with STRING on compose, the value(s) will be wrapped in "'" if they are not already. - All other values ignored
literalType?: LiteralType | LiteralType[]; // If populated with STRING on compose, the value(s) will be wrapped in "'" if they are not already. - All other values ignored
dateLiteralVariable?: number; // not required for compose, will be populated if SOQL is parsed

@@ -567,4 +554,5 @@ }

export interface GroupByClause {
field: string | string[];
type?: GroupByType;
field?: string | string[];
fn?: FunctionExp;
having?: HavingClause;
}

@@ -585,11 +573,11 @@

value: string | number;
literalType?: String;
}
export interface FunctionExp {
text?: string; // Should be formatted like this: Count(Id)
name?: string; // not used for compose, will be populated if SOQL is parsed
rawValue?: string; // Should be formatted like this: Count(Id)
functionName?: string; // not used for compose, will be populated if SOQL is parsed
alias?: string;
parameter?: string | string[]; // not used for compose, will be populated if SOQL is parsed
parameters?: (string | FunctionExp)[]; // not used for compose, will be populated if SOQL is parsed
isAggregateFn?: boolean; // not used for compose, will be populated if SOQL is parsed
fn?: FunctionExp; // used for nested functions FORMAT(MIN(CloseDate))
}

@@ -632,3 +620,2 @@

parseWithDataCategory(withDataCategory: WithDataCategoryClause): string
```

@@ -639,3 +626,5 @@

```typescript
export interface ComposeField {
type ComposeFieldInput = ComposeField | ComposeFieldFunction | ComposeFieldRelationship | ComposeFieldSubquery | ComposeFieldTypeof;
interface ComposeField {
field: string;

@@ -645,3 +634,3 @@ objectPrefix?: string;

export interface ComposeFieldFunction {
interface ComposeFieldFunction {
fn: string;

@@ -652,3 +641,3 @@ parameters?: string | string[] | FieldFunctionExpression | FieldFunctionExpression[];

export interface ComposeFieldRelationship {
interface ComposeFieldRelationship {
field: string;

@@ -659,7 +648,7 @@ relationships: string[];

export interface ComposeFieldSubquery {
interface ComposeFieldSubquery {
subquery?: Subquery;
}
export interface ComposeFieldTypeof {
interface ComposeFieldTypeof {
field: string;

@@ -669,47 +658,10 @@ conditions: FieldTypeOfCondition[];

export type ComposeFieldInput =
| ComposeField
| ComposeFieldFunction
| ComposeFieldRelationship
| ComposeFieldSubquery
| ComposeFieldTypeof;
function isSubquery(query: Query | Subquery): query is Subquery;
function getComposedField(input: string | ComposeFieldInput): SoqlModels.FieldType;
function getField(input: string | ComposeFieldInput): SoqlModels.FieldType;
function getFlattenedFields(query: SoqlModels.Query, isAggregateResult?: boolean): string[];
```
## CLI Usage
The CLI can be used to parse a query or compose a previously parsed query back to SOQL.
**Examples:**
```shell
$ npm install -g soql-parser-js
$ soql --help
$ soql --query "SELECT Id FROM Account"
$ soql -query "SELECT Id FROM Account"
$ soql -query "SELECT Id FROM Account" -output some-output-file.json
$ soql -query "SELECT Id FROM Account" -json
$ soql -query some-input-file.txt
$ soql -compose some-input-file.json
$ soql -compose some-input-file.json
$ soql -compose some-input-file.json -output some-output-file.json
```
**Arguments:**
```
--query, -q A SOQL query surrounded in quotes or a file path to a text file containing a SOQL query.
--compose, -c An escaped and quoted parsed SOQL JSON string or a file path to a text file containing a parsed query JSON object.
--output, -o Filepath.
--json, -j Provide all output messages as JSON.
--debug, -d Print additional debug log messages.
--help, -h Show this help message.
```
## Contributing
All contributions are welcome on the project. Please read the [contribution guidelines](https://github.com/paustint/soql-parser-js/blob/master/CONTRIBUTING.md).
## Special Thanks
- This library is based on the ANTLR4 grammar file [produced by Mulesoft](https://github.com/mulesoft/salesforce-soql-parser/blob/antlr4/SOQL.g4).
- The following repository also was a help to get things started: https://github.com/petermetz/antlr-4-ts-test

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc