soql-parser-js
Advanced tools
Comparing version 4.1.0 to 4.1.1
# Changelog | ||
## 4.1.0 | ||
June 6, 2021 | ||
#153 - A new parser option has been added named `ignoreParseErrors`, which will remove invalid parts of a query if there are parsing errors. | ||
The general structure of the query must be valid and the `SELECT` and `WHERE` clauses must both be valid, but any other clause may be removed from the parsed output if there are errors parsing the query and `ignoreParseErrors` is set to `true`. | ||
This option has been added to the documentation application. | ||
## 4.0.0 | ||
@@ -4,0 +14,0 @@ |
@@ -38,5 +38,7 @@ var __extends = (this && this.__extends) || (function () { | ||
__extends(SoqlParser, _super); | ||
function SoqlParser() { | ||
function SoqlParser(_a) { | ||
var _b = _a === void 0 ? { ignoreParseErrors: false } : _a, ignoreParseErrors = _b.ignoreParseErrors; | ||
var _this = _super.call(this, lexer.allTokens, { | ||
skipValidations: false, | ||
recoveryEnabled: ignoreParseErrors, | ||
}) || this; | ||
@@ -53,2 +55,3 @@ _this.$_dateFunctionOr = undefined; | ||
_this.allowApexBindVariables = false; | ||
_this.ignoreParseErrors = false; | ||
_this.selectStatement = _this.RULE('selectStatement', function () { | ||
@@ -106,3 +109,3 @@ _this.SUBRULE(_this.selectClause); | ||
}); | ||
}); | ||
}, { resyncEnabled: false }); | ||
_this.selectClauseFunctionIdentifier = _this.RULE('selectClauseFunctionIdentifier', function () { | ||
@@ -118,3 +121,3 @@ _this.OR(_this.$_selectClauseFunctionIdentifier || | ||
_this.OPTION(function () { return _this.CONSUME(lexer.Identifier, { LABEL: 'alias' }); }); | ||
}); | ||
}, { resyncEnabled: false }); | ||
_this.selectClauseSubqueryIdentifier = _this.RULE('selectClauseSubqueryIdentifier', function () { | ||
@@ -124,3 +127,3 @@ _this.CONSUME(lexer.LParen); | ||
_this.CONSUME(lexer.RParen); | ||
}); | ||
}, { resyncEnabled: false }); | ||
_this.selectClauseTypeOf = _this.RULE('selectClauseTypeOf', function () { | ||
@@ -138,7 +141,7 @@ _this.CONSUME(lexer.Typeof); | ||
_this.CONSUME(lexer.End); | ||
}); | ||
}, { resyncEnabled: false }); | ||
_this.selectClauseIdentifier = _this.RULE('selectClauseIdentifier', function () { | ||
_this.CONSUME(lexer.Identifier, { LABEL: 'field' }); | ||
_this.OPTION(function () { return _this.CONSUME1(lexer.Identifier, { LABEL: 'alias' }); }); | ||
}); | ||
}, { resyncEnabled: false }); | ||
_this.selectClauseTypeOfThen = _this.RULE('selectClauseTypeOfThen', function () { | ||
@@ -154,3 +157,3 @@ _this.CONSUME(lexer.When); | ||
}); | ||
}); | ||
}, { resyncEnabled: false }); | ||
_this.selectClauseTypeOfElse = _this.RULE('selectClauseTypeOfElse', function () { | ||
@@ -164,3 +167,3 @@ _this.CONSUME(lexer.Else); | ||
}); | ||
}); | ||
}, { resyncEnabled: false }); | ||
_this.fromClause = _this.RULE('fromClause', function () { | ||
@@ -173,3 +176,3 @@ _this.CONSUME(lexer.From); | ||
}); | ||
}); | ||
}, { resyncEnabled: false }); | ||
_this.usingScopeClause = _this.RULE('usingScopeClause', function () { | ||
@@ -559,2 +562,3 @@ _this.CONSUME(lexer.Using); | ||
}); | ||
_this.ignoreParseErrors = ignoreParseErrors; | ||
_this.performSelfAnalysis(); | ||
@@ -579,6 +583,10 @@ return _this; | ||
export function parse(soql, options) { | ||
options = options || { allowApexBindVariables: false, logErrors: false }; | ||
var _a = options || { | ||
allowApexBindVariables: false, | ||
logErrors: false, | ||
ignoreParseErrors: false, | ||
}, allowApexBindVariables = _a.allowApexBindVariables, logErrors = _a.logErrors, ignoreParseErrors = _a.ignoreParseErrors; | ||
var lexResult = lexer.lex(soql); | ||
if (lexResult.errors.length > 0) { | ||
if (options.logErrors) { | ||
if (logErrors) { | ||
console.log('Lexing Errors:'); | ||
@@ -589,14 +597,22 @@ console.log(lexResult.errors); | ||
} | ||
if (parser.ignoreParseErrors !== ignoreParseErrors) { | ||
parser = new SoqlParser({ ignoreParseErrors: ignoreParseErrors }); | ||
} | ||
parser.input = lexResult.tokens; | ||
parser.allowApexBindVariables = options.allowApexBindVariables || false; | ||
parser.allowApexBindVariables = allowApexBindVariables || false; | ||
var cst = parser.selectStatement(); | ||
if (parser.errors.length > 0) { | ||
if (options.logErrors) { | ||
if (logErrors) { | ||
console.log('Parsing Errors:'); | ||
console.log(parser.errors); | ||
} | ||
throw new ParsingError(parser.errors[0]); | ||
if (!ignoreParseErrors) { | ||
throw new ParsingError(parser.errors[0]); | ||
} | ||
} | ||
return cst; | ||
return { | ||
cst: cst, | ||
parseErrors: parser.errors.map(function (err) { return new ParsingError(err); }), | ||
}; | ||
} | ||
//# sourceMappingURL=parser.js.map |
@@ -191,10 +191,12 @@ var __extends = (this && this.__extends) || (function () { | ||
} | ||
if (ctx.usingScopeClause) { | ||
if (ctx.usingScopeClause && !ctx.usingScopeClause[0].recoveredNode) { | ||
output.usingScope = this.visit(ctx.usingScopeClause); | ||
} | ||
if (ctx.whereClause) { | ||
if (ctx.whereClause && !ctx.whereClause[0].recoveredNode) { | ||
output.where = this.visit(ctx.whereClause); | ||
} | ||
if (ctx.withClause) { | ||
ctx.withClause.forEach(function (item) { | ||
ctx.withClause | ||
.filter(function (item) { return !item.recoveredNode; }) | ||
.forEach(function (item) { | ||
var _a = _this.visit(item), withSecurityEnforced = _a.withSecurityEnforced, withDataCategory = _a.withDataCategory; | ||
@@ -209,21 +211,21 @@ if (withSecurityEnforced) { | ||
} | ||
if (ctx.groupByClause) { | ||
if (ctx.groupByClause && !ctx.groupByClause[0].recoveredNode) { | ||
output.groupBy = this.visit(ctx.groupByClause); | ||
} | ||
if (ctx.havingClause) { | ||
if (ctx.havingClause && !ctx.havingClause[0].recoveredNode) { | ||
output.having = this.visit(ctx.havingClause); | ||
} | ||
if (ctx.orderByClause) { | ||
if (ctx.orderByClause && !ctx.orderByClause[0].recoveredNode) { | ||
output.orderBy = this.visit(ctx.orderByClause); | ||
} | ||
if (ctx.limitClause) { | ||
if (ctx.limitClause && !ctx.limitClause[0].recoveredNode) { | ||
output.limit = Number(this.visit(ctx.limitClause)); | ||
} | ||
if (ctx.offsetClause) { | ||
if (ctx.offsetClause && !ctx.offsetClause[0].recoveredNode) { | ||
output.offset = Number(this.visit(ctx.offsetClause)); | ||
} | ||
if (ctx.forViewOrReference) { | ||
if (ctx.forViewOrReference && !ctx.forViewOrReference[0].recoveredNode) { | ||
output.for = this.visit(ctx.forViewOrReference); | ||
} | ||
if (ctx.updateTrackingViewstat) { | ||
if (ctx.updateTrackingViewstat && !ctx.updateTrackingViewstat[0].recoveredNode) { | ||
output.update = this.visit(ctx.updateTrackingViewstat); | ||
@@ -753,3 +755,4 @@ } | ||
export function parseQuery(soql, options) { | ||
var query = visitor.visit(parse(soql, options)); | ||
var cst = parse(soql, options).cst; | ||
var query = visitor.visit(cst); | ||
return query; | ||
@@ -759,4 +762,4 @@ } | ||
try { | ||
parse(soql, options); | ||
return true; | ||
var parseErrors = parse(soql, options).parseErrors; | ||
return parseErrors.length === 0 ? true : false; | ||
} | ||
@@ -763,0 +766,0 @@ catch (ex) { |
@@ -1,6 +0,10 @@ | ||
import { CstParser } from 'chevrotain'; | ||
import { CstParser, IRecognitionException } from 'chevrotain'; | ||
export interface ParseQueryConfig { | ||
allowApexBindVariables?: boolean; | ||
ignoreParseErrors?: boolean; | ||
logErrors?: boolean; | ||
} | ||
declare class ParsingError extends Error { | ||
constructor(parsingError: IRecognitionException); | ||
} | ||
export declare class SoqlParser extends CstParser { | ||
@@ -17,3 +21,6 @@ private $_dateFunctionOr; | ||
allowApexBindVariables: boolean; | ||
constructor(); | ||
ignoreParseErrors: boolean; | ||
constructor({ ignoreParseErrors }?: { | ||
ignoreParseErrors: boolean; | ||
}); | ||
selectStatement: (idxInCallingRule?: number, ...args: any[]) => import("chevrotain").CstNode; | ||
@@ -68,2 +75,6 @@ private $_checkBalancedParens; | ||
} | ||
export declare function parse(soql: string, options?: ParseQueryConfig): import("chevrotain").CstNode; | ||
export declare function parse(soql: string, options?: ParseQueryConfig): { | ||
cst: import("chevrotain").CstNode; | ||
parseErrors: ParsingError[]; | ||
}; | ||
export {}; |
@@ -41,5 +41,7 @@ "use strict"; | ||
__extends(SoqlParser, _super); | ||
function SoqlParser() { | ||
function SoqlParser(_a) { | ||
var _b = _a === void 0 ? { ignoreParseErrors: false } : _a, ignoreParseErrors = _b.ignoreParseErrors; | ||
var _this = _super.call(this, lexer.allTokens, { | ||
skipValidations: false, | ||
recoveryEnabled: ignoreParseErrors, | ||
}) || this; | ||
@@ -56,2 +58,3 @@ _this.$_dateFunctionOr = undefined; | ||
_this.allowApexBindVariables = false; | ||
_this.ignoreParseErrors = false; | ||
_this.selectStatement = _this.RULE('selectStatement', function () { | ||
@@ -109,3 +112,3 @@ _this.SUBRULE(_this.selectClause); | ||
}); | ||
}); | ||
}, { resyncEnabled: false }); | ||
_this.selectClauseFunctionIdentifier = _this.RULE('selectClauseFunctionIdentifier', function () { | ||
@@ -121,3 +124,3 @@ _this.OR(_this.$_selectClauseFunctionIdentifier || | ||
_this.OPTION(function () { return _this.CONSUME(lexer.Identifier, { LABEL: 'alias' }); }); | ||
}); | ||
}, { resyncEnabled: false }); | ||
_this.selectClauseSubqueryIdentifier = _this.RULE('selectClauseSubqueryIdentifier', function () { | ||
@@ -127,3 +130,3 @@ _this.CONSUME(lexer.LParen); | ||
_this.CONSUME(lexer.RParen); | ||
}); | ||
}, { resyncEnabled: false }); | ||
_this.selectClauseTypeOf = _this.RULE('selectClauseTypeOf', function () { | ||
@@ -141,7 +144,7 @@ _this.CONSUME(lexer.Typeof); | ||
_this.CONSUME(lexer.End); | ||
}); | ||
}, { resyncEnabled: false }); | ||
_this.selectClauseIdentifier = _this.RULE('selectClauseIdentifier', function () { | ||
_this.CONSUME(lexer.Identifier, { LABEL: 'field' }); | ||
_this.OPTION(function () { return _this.CONSUME1(lexer.Identifier, { LABEL: 'alias' }); }); | ||
}); | ||
}, { resyncEnabled: false }); | ||
_this.selectClauseTypeOfThen = _this.RULE('selectClauseTypeOfThen', function () { | ||
@@ -157,3 +160,3 @@ _this.CONSUME(lexer.When); | ||
}); | ||
}); | ||
}, { resyncEnabled: false }); | ||
_this.selectClauseTypeOfElse = _this.RULE('selectClauseTypeOfElse', function () { | ||
@@ -167,3 +170,3 @@ _this.CONSUME(lexer.Else); | ||
}); | ||
}); | ||
}, { resyncEnabled: false }); | ||
_this.fromClause = _this.RULE('fromClause', function () { | ||
@@ -176,3 +179,3 @@ _this.CONSUME(lexer.From); | ||
}); | ||
}); | ||
}, { resyncEnabled: false }); | ||
_this.usingScopeClause = _this.RULE('usingScopeClause', function () { | ||
@@ -562,2 +565,3 @@ _this.CONSUME(lexer.Using); | ||
}); | ||
_this.ignoreParseErrors = ignoreParseErrors; | ||
_this.performSelfAnalysis(); | ||
@@ -582,6 +586,10 @@ return _this; | ||
function parse(soql, options) { | ||
options = options || { allowApexBindVariables: false, logErrors: false }; | ||
var _a = options || { | ||
allowApexBindVariables: false, | ||
logErrors: false, | ||
ignoreParseErrors: false, | ||
}, allowApexBindVariables = _a.allowApexBindVariables, logErrors = _a.logErrors, ignoreParseErrors = _a.ignoreParseErrors; | ||
var lexResult = lexer.lex(soql); | ||
if (lexResult.errors.length > 0) { | ||
if (options.logErrors) { | ||
if (logErrors) { | ||
console.log('Lexing Errors:'); | ||
@@ -592,15 +600,23 @@ console.log(lexResult.errors); | ||
} | ||
if (parser.ignoreParseErrors !== ignoreParseErrors) { | ||
parser = new SoqlParser({ ignoreParseErrors: ignoreParseErrors }); | ||
} | ||
parser.input = lexResult.tokens; | ||
parser.allowApexBindVariables = options.allowApexBindVariables || false; | ||
parser.allowApexBindVariables = allowApexBindVariables || false; | ||
var cst = parser.selectStatement(); | ||
if (parser.errors.length > 0) { | ||
if (options.logErrors) { | ||
if (logErrors) { | ||
console.log('Parsing Errors:'); | ||
console.log(parser.errors); | ||
} | ||
throw new ParsingError(parser.errors[0]); | ||
if (!ignoreParseErrors) { | ||
throw new ParsingError(parser.errors[0]); | ||
} | ||
} | ||
return cst; | ||
return { | ||
cst: cst, | ||
parseErrors: parser.errors.map(function (err) { return new ParsingError(err); }), | ||
}; | ||
} | ||
exports.parse = parse; | ||
//# sourceMappingURL=parser.js.map |
@@ -194,10 +194,12 @@ "use strict"; | ||
} | ||
if (ctx.usingScopeClause) { | ||
if (ctx.usingScopeClause && !ctx.usingScopeClause[0].recoveredNode) { | ||
output.usingScope = this.visit(ctx.usingScopeClause); | ||
} | ||
if (ctx.whereClause) { | ||
if (ctx.whereClause && !ctx.whereClause[0].recoveredNode) { | ||
output.where = this.visit(ctx.whereClause); | ||
} | ||
if (ctx.withClause) { | ||
ctx.withClause.forEach(function (item) { | ||
ctx.withClause | ||
.filter(function (item) { return !item.recoveredNode; }) | ||
.forEach(function (item) { | ||
var _a = _this.visit(item), withSecurityEnforced = _a.withSecurityEnforced, withDataCategory = _a.withDataCategory; | ||
@@ -212,21 +214,21 @@ if (withSecurityEnforced) { | ||
} | ||
if (ctx.groupByClause) { | ||
if (ctx.groupByClause && !ctx.groupByClause[0].recoveredNode) { | ||
output.groupBy = this.visit(ctx.groupByClause); | ||
} | ||
if (ctx.havingClause) { | ||
if (ctx.havingClause && !ctx.havingClause[0].recoveredNode) { | ||
output.having = this.visit(ctx.havingClause); | ||
} | ||
if (ctx.orderByClause) { | ||
if (ctx.orderByClause && !ctx.orderByClause[0].recoveredNode) { | ||
output.orderBy = this.visit(ctx.orderByClause); | ||
} | ||
if (ctx.limitClause) { | ||
if (ctx.limitClause && !ctx.limitClause[0].recoveredNode) { | ||
output.limit = Number(this.visit(ctx.limitClause)); | ||
} | ||
if (ctx.offsetClause) { | ||
if (ctx.offsetClause && !ctx.offsetClause[0].recoveredNode) { | ||
output.offset = Number(this.visit(ctx.offsetClause)); | ||
} | ||
if (ctx.forViewOrReference) { | ||
if (ctx.forViewOrReference && !ctx.forViewOrReference[0].recoveredNode) { | ||
output.for = this.visit(ctx.forViewOrReference); | ||
} | ||
if (ctx.updateTrackingViewstat) { | ||
if (ctx.updateTrackingViewstat && !ctx.updateTrackingViewstat[0].recoveredNode) { | ||
output.update = this.visit(ctx.updateTrackingViewstat); | ||
@@ -756,3 +758,4 @@ } | ||
function parseQuery(soql, options) { | ||
var query = visitor.visit(parser_1.parse(soql, options)); | ||
var cst = parser_1.parse(soql, options).cst; | ||
var query = visitor.visit(cst); | ||
return query; | ||
@@ -763,4 +766,4 @@ } | ||
try { | ||
parser_1.parse(soql, options); | ||
return true; | ||
var parseErrors = parser_1.parse(soql, options).parseErrors; | ||
return parseErrors.length === 0 ? true : false; | ||
} | ||
@@ -767,0 +770,0 @@ catch (ex) { |
{ | ||
"name": "soql-parser-js", | ||
"version": "4.1.0", | ||
"version": "4.1.1", | ||
"description": "Salesforce.com SOQL parser and composer", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -21,2 +21,3 @@ <img src="./assets/soql-parser-js-logo.svg"> | ||
Migrating from version 1 to version 2? [Check out the changelog](CHANGELOG.md#200) for a full list of changes. | ||
Migrating from version 2 to version 3? [Check out the changelog](CHANGELOG.md#300) for a full list of changes. | ||
@@ -84,6 +85,7 @@ | ||
| Property | Type | Description | required | default | | ||
| ---------------------- | ------- | ---------------------------------------------------------------------------------------------------- | -------- | ------- | | ||
| allowApexBindVariables | boolean | Determines if apex variables are allowed in parsed query. Example: `WHERE Id IN :accountIds`. | FALSE | FALSE | | ||
| logErrors | boolean | If true, then additional detail will be logged to the console if there is a lexing or parsing error. | FALSE | FALSE | | ||
| Property | Type | Description | required | default | | ||
| ---------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------- | | ||
| 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 | | ||
| 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 | | ||
| logErrors | boolean | If true, parsing and lexing errors will be logged to the console. | FALSE | FALSE | | ||
@@ -90,0 +92,0 @@ **SoqlComposeConfig** |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1292785
19548
688