@witchcraft/expressit 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -2
- package/dist/Lexer.d.ts +99 -94
- package/dist/Lexer.d.ts.map +1 -1
- package/dist/Lexer.js +211 -559
- package/dist/Parser.d.ts +26 -26
- package/dist/Parser.d.ts.map +1 -1
- package/dist/Parser.js +2 -1
- package/dist/ast/builders/condition.d.ts +1 -1
- package/dist/ast/builders/condition.d.ts.map +1 -1
- package/dist/ast/builders/condition.js +1 -0
- package/dist/ast/builders/delim.d.ts +2 -2
- package/dist/ast/builders/delim.d.ts.map +1 -1
- package/dist/ast/builders/error.d.ts +2 -2
- package/dist/ast/builders/error.d.ts.map +1 -1
- package/dist/ast/builders/expression.d.ts +2 -2
- package/dist/ast/builders/expression.d.ts.map +1 -1
- package/dist/ast/builders/expression.js +2 -6
- package/dist/ast/builders/group.d.ts +1 -1
- package/dist/ast/builders/group.d.ts.map +1 -1
- package/dist/ast/builders/group.js +1 -3
- package/dist/ast/builders/pos.d.ts +2 -2
- package/dist/ast/builders/pos.d.ts.map +1 -1
- package/dist/ast/builders/token.d.ts +2 -2
- package/dist/ast/builders/token.d.ts.map +1 -1
- package/dist/ast/builders/type.d.ts +2 -2
- package/dist/ast/builders/type.d.ts.map +1 -1
- package/dist/ast/builders/variable.d.ts +3 -3
- package/dist/ast/builders/variable.d.ts.map +1 -1
- package/dist/ast/createConditionNode.d.ts +1 -1
- package/dist/ast/createConditionNode.d.ts.map +1 -1
- package/dist/ast/createGroupNode.d.ts +1 -1
- package/dist/ast/createGroupNode.d.ts.map +1 -1
- package/dist/ast/createToken.d.ts +2 -2
- package/dist/ast/createToken.d.ts.map +1 -1
- package/dist/ast/createToken.js +2 -2
- package/dist/ast/error.d.ts +2 -2
- package/dist/ast/error.d.ts.map +1 -1
- package/dist/ast/error.js +1 -0
- package/dist/ast/handlers.d.ts +23 -23
- package/dist/ast/handlers.d.ts.map +1 -1
- package/dist/ast/handlers.js +1 -1
- package/dist/examples/ParserWithSqlSupport.d.ts +5 -5
- package/dist/examples/ParserWithSqlSupport.d.ts.map +1 -1
- package/dist/examples/ParserWithSqlSupport.js +2 -0
- package/dist/index.js +2 -2
- package/dist/internal/ExpressitError.d.ts +2 -2
- package/dist/internal/ExpressitError.d.ts.map +1 -1
- package/dist/internal/checkParserOpts.js +11 -11
- package/dist/package.json.js +2 -60
- package/dist/types/ast.d.ts +60 -58
- package/dist/types/ast.d.ts.map +1 -1
- package/dist/types/ast.js +26 -27
- package/dist/types/autocomplete.d.ts +23 -21
- package/dist/types/autocomplete.d.ts.map +1 -1
- package/dist/types/autocomplete.js +24 -21
- package/dist/types/errors.d.ts +12 -10
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/errors.js +8 -7
- package/dist/types/index.js +2 -2
- package/dist/types/parser.d.ts +3 -3
- package/dist/types/parser.d.ts.map +1 -1
- package/dist/utils/getCursorInfo.js +2 -0
- package/dist/utils/getOppositeDelimiter.d.ts +2 -2
- package/dist/utils/getOppositeDelimiter.d.ts.map +1 -1
- package/dist/utils/isDelimiter.d.ts +2 -2
- package/dist/utils/isDelimiter.d.ts.map +1 -1
- package/dist/utils/isParen.d.ts +2 -2
- package/dist/utils/isParen.d.ts.map +1 -1
- package/dist/utils/isQuote.d.ts +2 -2
- package/dist/utils/isQuote.d.ts.map +1 -1
- package/package.json +13 -13
- package/src/Lexer.ts +98 -88
- package/src/Parser.ts +61 -61
- package/src/ast/builders/condition.ts +3 -3
- package/src/ast/builders/delim.ts +4 -4
- package/src/ast/builders/error.ts +3 -3
- package/src/ast/builders/expression.ts +4 -8
- package/src/ast/builders/group.ts +2 -4
- package/src/ast/builders/pos.ts +3 -3
- package/src/ast/builders/token.ts +2 -2
- package/src/ast/builders/type.ts +2 -2
- package/src/ast/builders/variable.ts +5 -5
- package/src/ast/createConditionNode.ts +2 -2
- package/src/ast/createGroupNode.ts +4 -4
- package/src/ast/createToken.ts +6 -6
- package/src/ast/error.ts +2 -2
- package/src/ast/handlers.ts +20 -20
- package/src/examples/ParserWithSqlSupport.ts +11 -5
- package/src/internal/ExpressitError.ts +3 -3
- package/src/internal/checkParserOpts.ts +11 -11
- package/src/types/ast.ts +101 -96
- package/src/types/autocomplete.ts +26 -22
- package/src/types/errors.ts +18 -13
- package/src/types/parser.ts +3 -3
- package/src/utils/getOppositeDelimiter.ts +2 -2
- package/src/utils/getSurroundingErrors.ts +4 -4
- package/src/utils/isDelimiter.ts +3 -3
- package/src/utils/isParen.ts +2 -2
- package/src/utils/isQuote.ts +2 -2
package/src/ast/error.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createToken } from "./createToken.js"
|
|
2
2
|
|
|
3
|
-
import { type ErrorToken,type
|
|
3
|
+
import { type ErrorToken,type TokenType } from "../types/ast.js"
|
|
4
4
|
|
|
5
|
-
export function error<T extends
|
|
5
|
+
export function error<T extends TokenType>(pos: number, expected: T[]): ErrorToken {
|
|
6
6
|
if (pos === undefined) throw new Error("should never happen, passed undefined position for error token")
|
|
7
7
|
return createToken({ expected, start: pos, end: pos })
|
|
8
8
|
}
|
package/src/ast/handlers.ts
CHANGED
|
@@ -7,28 +7,28 @@ import { createGroupNode } from "./createGroupNode.js"
|
|
|
7
7
|
import { createToken } from "./createToken.js"
|
|
8
8
|
import { createVariableNode } from "./createVariableNode.js"
|
|
9
9
|
|
|
10
|
-
import { type AnyToken, type ArrayNode,AST_TYPE,type ConditionNode, type ErrorToken, type ExpressionNode,type FirstParam,type GroupNode, type Position, TOKEN_TYPE, type
|
|
10
|
+
import { type AnyToken, type ArrayNode,AST_TYPE,type ConditionNode, type ErrorToken, type ExpressionNode,type FirstParam,type GroupNode, type Position, TOKEN_TYPE, type TokenBoolean, type TokenDelimiter, type TokenOperator, type TokenQuote, type TokenType, type ValidToken, type VariableNode } from "../types/ast.js"
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
/* #region HELPERS */
|
|
14
|
-
function error<T extends
|
|
14
|
+
function error<T extends TokenType>(pos: number, expected: T[]): ErrorToken {
|
|
15
15
|
if (pos === undefined) throw new Error("should never happen, passed undefined position for error token")
|
|
16
16
|
return createToken({ expected, start: pos, end: pos })
|
|
17
17
|
}
|
|
18
18
|
/* #regionend */
|
|
19
19
|
|
|
20
20
|
/* #region TOKENS */
|
|
21
|
-
const operators = <T extends
|
|
21
|
+
const operators = <T extends TokenOperator>
|
|
22
22
|
(type: T) =>
|
|
23
23
|
(value: string, pos: Position): ValidToken<T> => createToken({ value, type, ...pos })
|
|
24
24
|
|
|
25
|
-
const delimiters = <T extends
|
|
25
|
+
const delimiters = <T extends TokenDelimiter>
|
|
26
26
|
(type: T) =>
|
|
27
27
|
(value: string | undefined, pos: Position): ValidToken<T> | undefined =>
|
|
28
28
|
// check must be falsy, we want to return undefined when given ""
|
|
29
29
|
value ? createToken({ value, type, ...pos }) : undefined
|
|
30
30
|
|
|
31
|
-
const maybeToken = <T extends
|
|
31
|
+
const maybeToken = <T extends TokenType> (type: T) => <TVal extends string | undefined> (value: TVal, pos: Position): TVal extends string ? ValidToken<T> : ErrorToken => {
|
|
32
32
|
if (value === undefined) {
|
|
33
33
|
return error(pos.end, [type]) as any
|
|
34
34
|
} else {
|
|
@@ -63,11 +63,11 @@ export const operator = {
|
|
|
63
63
|
|
|
64
64
|
/* #region AST NODES */
|
|
65
65
|
export function variable(
|
|
66
|
-
prefix: ValidToken<TOKEN_TYPE.VALUE> | null | undefined,
|
|
67
|
-
quoteL: AnyToken<
|
|
68
|
-
value: AnyToken<TOKEN_TYPE.VALUE> | null | undefined,
|
|
69
|
-
quoteR: AnyToken<
|
|
70
|
-
flags?: ValidToken<TOKEN_TYPE.VALUE>,
|
|
66
|
+
prefix: ValidToken<typeof TOKEN_TYPE.VALUE> | null | undefined,
|
|
67
|
+
quoteL: AnyToken<TokenQuote> | null | undefined,
|
|
68
|
+
value: AnyToken<typeof TOKEN_TYPE.VALUE> | null | undefined,
|
|
69
|
+
quoteR: AnyToken<TokenQuote> | null | undefined,
|
|
70
|
+
flags?: ValidToken<typeof TOKEN_TYPE.VALUE>,
|
|
71
71
|
): VariableNode {
|
|
72
72
|
const node: FirstParam<typeof createVariableNode> = {
|
|
73
73
|
prefix: prefix ?? undefined,
|
|
@@ -92,19 +92,19 @@ export function variable(
|
|
|
92
92
|
|
|
93
93
|
|
|
94
94
|
export function condition(
|
|
95
|
-
not: ValidToken<TOKEN_TYPE.NOT> | null | undefined,
|
|
95
|
+
not: ValidToken<typeof TOKEN_TYPE.NOT> | null | undefined,
|
|
96
96
|
property: VariableNode | null | undefined,
|
|
97
97
|
{ propertyOperator, sepL, sepR }: {
|
|
98
98
|
propertyOperator?: ConditionNode["propertyOperator"] | null
|
|
99
|
-
sepL?: ValidToken<TOKEN_TYPE.OP_EXPANDED_SEP> | null
|
|
100
|
-
sepR?: ValidToken<TOKEN_TYPE.OP_EXPANDED_SEP> | null
|
|
99
|
+
sepL?: ValidToken<typeof TOKEN_TYPE.OP_EXPANDED_SEP> | null
|
|
100
|
+
sepR?: ValidToken<typeof TOKEN_TYPE.OP_EXPANDED_SEP> | null
|
|
101
101
|
} = {},
|
|
102
102
|
value?: VariableNode | GroupNode | ArrayNode | null,
|
|
103
103
|
): ConditionNode {
|
|
104
104
|
const start = (not?.start ?? property?.start ?? sepL?.start ?? propertyOperator?.start ?? sepR?.start ?? value?.start)!
|
|
105
105
|
const end = (value?.end ?? sepR?.end ?? propertyOperator?.end ?? sepL?.end ?? property?.end ?? not?.end)!
|
|
106
106
|
const node: FirstParam<typeof createConditionNode> = {
|
|
107
|
-
value: value
|
|
107
|
+
value: value ?? error(end, [TOKEN_TYPE.VALUE]),
|
|
108
108
|
start,
|
|
109
109
|
end,
|
|
110
110
|
}
|
|
@@ -130,7 +130,7 @@ export function condition(
|
|
|
130
130
|
|
|
131
131
|
export function expression(
|
|
132
132
|
left: ConditionNode | GroupNode | null | undefined,
|
|
133
|
-
operator: ValidToken<
|
|
133
|
+
operator: ValidToken<TokenBoolean> | null | undefined,
|
|
134
134
|
right: ConditionNode | GroupNode | null | undefined,
|
|
135
135
|
): ExpressionNode {
|
|
136
136
|
return createExpressionNode({
|
|
@@ -143,11 +143,11 @@ export function expression(
|
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
export function group(
|
|
146
|
-
operator: ValidToken<TOKEN_TYPE.NOT> | null | undefined,
|
|
146
|
+
operator: ValidToken<typeof TOKEN_TYPE.NOT> | null | undefined,
|
|
147
147
|
prefix: ConditionNode | null | undefined,
|
|
148
|
-
parenL: ValidToken<TOKEN_TYPE.PARENL> | null | undefined,
|
|
148
|
+
parenL: ValidToken<typeof TOKEN_TYPE.PARENL> | null | undefined,
|
|
149
149
|
condition: GroupNode["expression"],
|
|
150
|
-
parenR: ValidToken<TOKEN_TYPE.PARENR> | null | undefined,
|
|
150
|
+
parenR: ValidToken<typeof TOKEN_TYPE.PARENR> | null | undefined,
|
|
151
151
|
): GroupNode {
|
|
152
152
|
return createGroupNode({
|
|
153
153
|
prefix: prefix ?? operator ?? undefined,
|
|
@@ -162,9 +162,9 @@ export function group(
|
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
export function array(
|
|
165
|
-
bracketL: ValidToken<TOKEN_TYPE.BRACKETL>,
|
|
165
|
+
bracketL: ValidToken<typeof TOKEN_TYPE.BRACKETL>,
|
|
166
166
|
values: VariableNode[],
|
|
167
|
-
bracketR: ValidToken<TOKEN_TYPE.BRACKETR> | null | undefined,
|
|
167
|
+
bracketR: ValidToken<typeof TOKEN_TYPE.BRACKETR> | null | undefined,
|
|
168
168
|
): ArrayNode {
|
|
169
169
|
return createArrayNode({
|
|
170
170
|
values,
|
|
@@ -29,7 +29,7 @@ export interface BaseOperatorDefinition {
|
|
|
29
29
|
/** How to compare the value when evualuating a condition. This is only used if using `evaluate`. */
|
|
30
30
|
valueComparer: (condition: any, contextValue: any) => boolean
|
|
31
31
|
}
|
|
32
|
-
export type
|
|
32
|
+
export type SqlParserError =
|
|
33
33
|
| "invalidKey"
|
|
34
34
|
| "unknownProperty"
|
|
35
35
|
| "unknownOperator"
|
|
@@ -53,11 +53,11 @@ export type BaseErrorTokenTypes =
|
|
|
53
53
|
*/
|
|
54
54
|
export class ParserWithSqlSupport<TErrorToken extends
|
|
55
55
|
Position & {
|
|
56
|
-
type:
|
|
56
|
+
type: SqlParserError
|
|
57
57
|
message?: string
|
|
58
58
|
} =
|
|
59
59
|
Position & {
|
|
60
|
-
type:
|
|
60
|
+
type: SqlParserError
|
|
61
61
|
message?: string
|
|
62
62
|
},
|
|
63
63
|
TPropertyDefinition extends BasePropertyDefinition = BasePropertyDefinition,
|
|
@@ -70,9 +70,13 @@ export class ParserWithSqlSupport<TErrorToken extends
|
|
|
70
70
|
|
|
71
71
|
operatorMap: Record<string, string>
|
|
72
72
|
|
|
73
|
+
propertyDefinitions: TPropertyDefinitions
|
|
74
|
+
|
|
75
|
+
operatorDefinitions: TOperatorDefinitions
|
|
76
|
+
|
|
73
77
|
constructor(
|
|
74
|
-
|
|
75
|
-
|
|
78
|
+
propertyDefinitions: TPropertyDefinitions,
|
|
79
|
+
operatorDefinitions: TOperatorDefinitions,
|
|
76
80
|
{ sqlEscapeValue }: { sqlEscapeValue: TSqlEscapeValue }
|
|
77
81
|
) {
|
|
78
82
|
const operators = []
|
|
@@ -229,6 +233,8 @@ export class ParserWithSqlSupport<TErrorToken extends
|
|
|
229
233
|
return { value: finalValue, operator: finalOperator, negate: isNegated }
|
|
230
234
|
},
|
|
231
235
|
})
|
|
236
|
+
this.propertyDefinitions = propertyDefinitions
|
|
237
|
+
this.operatorDefinitions = operatorDefinitions
|
|
232
238
|
this.operatorMap = operatorMap
|
|
233
239
|
this.sqlEscapeValue = sqlEscapeValue
|
|
234
240
|
}
|
|
@@ -3,12 +3,12 @@ import { indent } from "@alanscodelog/utils/indent.js"
|
|
|
3
3
|
import { pretty } from "@alanscodelog/utils/pretty.js"
|
|
4
4
|
import type { Keys } from "@alanscodelog/utils/types"
|
|
5
5
|
|
|
6
|
-
import packageJson from "../../package.json"
|
|
6
|
+
import packageJson from "../../package.json" with { type: "json" }
|
|
7
7
|
const { version, repository } = packageJson
|
|
8
|
-
import type {
|
|
8
|
+
import type { ErrorInfo, ParserError } from "../types/errors.js"
|
|
9
9
|
|
|
10
10
|
/** @internal */
|
|
11
|
-
export class ExpressitError<T extends
|
|
11
|
+
export class ExpressitError<T extends ParserError> extends Error {
|
|
12
12
|
version: string = version
|
|
13
13
|
|
|
14
14
|
repo: string = repository
|
|
@@ -5,7 +5,7 @@ import { ExpressitError } from "./ExpressitError.js"
|
|
|
5
5
|
|
|
6
6
|
import { defaultConditionNormalizer } from "../defaults/defaultConditionNormalizer.js"
|
|
7
7
|
import { defaultValueComparer } from "../defaults/defaultValueComparer.js"
|
|
8
|
-
import {
|
|
8
|
+
import { PARSER_ERROR } from "../types/errors.js"
|
|
9
9
|
import type { FullParserOptions, ParserOptions } from "../types/parser.js"
|
|
10
10
|
|
|
11
11
|
/** @internal */
|
|
@@ -27,7 +27,7 @@ export function checkParserOpts<T>(opts: FullParserOptions<T>, evaluatorChecks:
|
|
|
27
27
|
/* #region Blank Operator Checks */
|
|
28
28
|
if (opts.expandedPropertySeparator && isBlank(opts.expandedPropertySeparator)) {
|
|
29
29
|
throw new ExpressitError(
|
|
30
|
-
|
|
30
|
+
PARSER_ERROR.CONFLICTING_OPTIONS_ERROR,
|
|
31
31
|
{ prohibited: [""], invalid: opts.expandedPropertySeparator },
|
|
32
32
|
`expandedPropertySeparator cannot be blank`,
|
|
33
33
|
)
|
|
@@ -35,7 +35,7 @@ export function checkParserOpts<T>(opts: FullParserOptions<T>, evaluatorChecks:
|
|
|
35
35
|
const customInvalid = opts.customPropertyOperators?.find(_ => isBlank(_))
|
|
36
36
|
if (customInvalid !== undefined) {
|
|
37
37
|
throw new ExpressitError(
|
|
38
|
-
|
|
38
|
+
PARSER_ERROR.CONFLICTING_OPTIONS_ERROR,
|
|
39
39
|
{ prohibited: [""], invalid: customInvalid },
|
|
40
40
|
`customPropertyOperators cannot contain blank entries`,
|
|
41
41
|
)
|
|
@@ -43,7 +43,7 @@ export function checkParserOpts<T>(opts: FullParserOptions<T>, evaluatorChecks:
|
|
|
43
43
|
const prefixInvalid = opts.prefixableStrings?.find(_ => isBlank(_))
|
|
44
44
|
if (prefixInvalid !== undefined) {
|
|
45
45
|
throw new ExpressitError(
|
|
46
|
-
|
|
46
|
+
PARSER_ERROR.CONFLICTING_OPTIONS_ERROR,
|
|
47
47
|
{ prohibited: [""], invalid: prefixInvalid },
|
|
48
48
|
`prefixableStrings cannot contain blank entries`,
|
|
49
49
|
)
|
|
@@ -54,7 +54,7 @@ export function checkParserOpts<T>(opts: FullParserOptions<T>, evaluatorChecks:
|
|
|
54
54
|
?.value
|
|
55
55
|
if (invalid !== undefined) {
|
|
56
56
|
throw new ExpressitError(
|
|
57
|
-
|
|
57
|
+
PARSER_ERROR.CONFLICTING_OPTIONS_ERROR,
|
|
58
58
|
{ prohibited: [""], invalid },
|
|
59
59
|
`keywords.${key} cannot contain entries with blank values`,
|
|
60
60
|
)
|
|
@@ -77,7 +77,7 @@ export function checkParserOpts<T>(opts: FullParserOptions<T>, evaluatorChecks:
|
|
|
77
77
|
const invalidPrefixableString = opts.prefixableStrings?.find(val => all.includes(val))
|
|
78
78
|
if (invalidPrefixableString) {
|
|
79
79
|
throw new ExpressitError(
|
|
80
|
-
|
|
80
|
+
PARSER_ERROR.CONFLICTING_OPTIONS_ERROR,
|
|
81
81
|
{ prohibited: all, invalid: invalidPrefixableString },
|
|
82
82
|
`prefixableStrings ${messageInvalidAny} "${invalidPrefixableString}"`,
|
|
83
83
|
)
|
|
@@ -87,7 +87,7 @@ export function checkParserOpts<T>(opts: FullParserOptions<T>, evaluatorChecks:
|
|
|
87
87
|
.find(_ => _ === opts.expandedPropertySeparator as any)
|
|
88
88
|
if (invalidExpandedPropertySeparator) {
|
|
89
89
|
throw new ExpressitError(
|
|
90
|
-
|
|
90
|
+
PARSER_ERROR.CONFLICTING_OPTIONS_ERROR,
|
|
91
91
|
{ prohibited: allKeywords, invalid: invalidExpandedPropertySeparator },
|
|
92
92
|
`expandedPropertySeparator ${messageInvalidBool} "${invalidExpandedPropertySeparator}"`,
|
|
93
93
|
)
|
|
@@ -98,7 +98,7 @@ export function checkParserOpts<T>(opts: FullParserOptions<T>, evaluatorChecks:
|
|
|
98
98
|
: undefined
|
|
99
99
|
if (invalidCustomPropertyOperator) {
|
|
100
100
|
throw new ExpressitError(
|
|
101
|
-
|
|
101
|
+
PARSER_ERROR.CONFLICTING_OPTIONS_ERROR,
|
|
102
102
|
{ prohibited: keywords, invalid: invalidCustomPropertyOperator },
|
|
103
103
|
`customPropertyOperator ${messageInvalidBool} "${invalidCustomPropertyOperator}"`,
|
|
104
104
|
)
|
|
@@ -115,7 +115,7 @@ export function checkParserOpts<T>(opts: FullParserOptions<T>, evaluatorChecks:
|
|
|
115
115
|
|
|
116
116
|
if (requireCustomNormalizer.length > 0 && opts.conditionNormalizer === defaultConditionNormalizer) {
|
|
117
117
|
throw new ExpressitError(
|
|
118
|
-
|
|
118
|
+
PARSER_ERROR.OPTION_REQUIRED_ERROR,
|
|
119
119
|
{ options: requireCustomNormalizer, requires: "conditionNormalizer" },
|
|
120
120
|
`A custom conditionNormalizer function must be specified when using the following options: ${requireCustomNormalizer.join(", ")}`,
|
|
121
121
|
)
|
|
@@ -126,7 +126,7 @@ export function checkParserOpts<T>(opts: FullParserOptions<T>, evaluatorChecks:
|
|
|
126
126
|
|
|
127
127
|
if (requireCustomComparer.length > 0 && opts.valueComparer === defaultValueComparer) {
|
|
128
128
|
throw new ExpressitError(
|
|
129
|
-
|
|
129
|
+
PARSER_ERROR.OPTION_REQUIRED_ERROR,
|
|
130
130
|
{ options: requireCustomComparer, requires: "valueComparer" },
|
|
131
131
|
`A custom valueComparer function must be specified when using the following options: ${requireCustomComparer.join(", ")}`,
|
|
132
132
|
)
|
|
@@ -135,7 +135,7 @@ export function checkParserOpts<T>(opts: FullParserOptions<T>, evaluatorChecks:
|
|
|
135
135
|
if (validatorChecks) {
|
|
136
136
|
if (opts.valueValidator === undefined) {
|
|
137
137
|
throw new ExpressitError(
|
|
138
|
-
|
|
138
|
+
PARSER_ERROR.OPTION_REQUIRED_ERROR,
|
|
139
139
|
{ requires: "valueValidator" },
|
|
140
140
|
`A custom valueValidator function must be specified when using the validate method.`,
|
|
141
141
|
)
|
package/src/types/ast.ts
CHANGED
|
@@ -1,94 +1,97 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { enumFromArray } from "@alanscodelog/utils/enumFromArray.js"
|
|
2
|
+
import type { AnyFunction, EnumLike } from "@alanscodelog/utils/types"
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
export type AddParameters<T extends AnyFunction, TExtra extends any[] = [boolean]> = (...args: [...Parameters<T>, ...TExtra]) => ReturnType<T>
|
|
5
6
|
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
OP_EXPANDED_SEP
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
7
|
+
export const TOKEN_TYPE = enumFromArray([
|
|
8
|
+
"VALUE",
|
|
9
|
+
"AND",
|
|
10
|
+
"OR",
|
|
11
|
+
"NOT",
|
|
12
|
+
"BACKTICK",
|
|
13
|
+
"SINGLEQUOTE",
|
|
14
|
+
"DOUBLEQUOTE",
|
|
15
|
+
"PARENL",
|
|
16
|
+
"PARENR",
|
|
17
|
+
"BRACKETL",
|
|
18
|
+
"BRACKETR",
|
|
19
|
+
"OP_EXPANDED_SEP",
|
|
20
|
+
"OP_CUSTOM",
|
|
21
|
+
"REGEX",
|
|
22
|
+
])
|
|
23
|
+
|
|
24
|
+
export type TokenType = EnumLike<typeof TOKEN_TYPE>
|
|
22
25
|
|
|
23
26
|
/**
|
|
24
27
|
* @internal
|
|
25
28
|
* Note if the negation operator, `!`, is used as a propertyOperator, this will return the wrong type.
|
|
26
29
|
*/
|
|
27
|
-
export type
|
|
30
|
+
export type ExtractToken<T extends string> =
|
|
28
31
|
T extends "`"
|
|
29
|
-
? TOKEN_TYPE.BACKTICK
|
|
32
|
+
? typeof TOKEN_TYPE.BACKTICK
|
|
30
33
|
: T extends `'`
|
|
31
|
-
? TOKEN_TYPE.SINGLEQUOTE
|
|
34
|
+
? typeof TOKEN_TYPE.SINGLEQUOTE
|
|
32
35
|
: T extends `"`
|
|
33
|
-
? TOKEN_TYPE.DOUBLEQUOTE
|
|
36
|
+
? typeof TOKEN_TYPE.DOUBLEQUOTE
|
|
34
37
|
: T extends `/`
|
|
35
|
-
? TOKEN_TYPE.REGEX
|
|
38
|
+
? typeof TOKEN_TYPE.REGEX
|
|
36
39
|
: T extends `(`
|
|
37
|
-
? TOKEN_TYPE.PARENL
|
|
40
|
+
? typeof TOKEN_TYPE.PARENL
|
|
38
41
|
: T extends `)`
|
|
39
|
-
? TOKEN_TYPE.PARENR
|
|
42
|
+
? typeof TOKEN_TYPE.PARENR
|
|
40
43
|
: T extends `[`
|
|
41
|
-
? TOKEN_TYPE.BRACKETL
|
|
44
|
+
? typeof TOKEN_TYPE.BRACKETL
|
|
42
45
|
: T extends `]`
|
|
43
|
-
? TOKEN_TYPE.BRACKETR
|
|
46
|
+
? typeof TOKEN_TYPE.BRACKETR
|
|
44
47
|
: T extends `and`
|
|
45
|
-
? TOKEN_TYPE.AND
|
|
48
|
+
? typeof TOKEN_TYPE.AND
|
|
46
49
|
: T extends `&&`
|
|
47
|
-
? TOKEN_TYPE.AND
|
|
50
|
+
? typeof TOKEN_TYPE.AND
|
|
48
51
|
: T extends `&`
|
|
49
|
-
? TOKEN_TYPE.AND
|
|
52
|
+
? typeof TOKEN_TYPE.AND
|
|
50
53
|
: T extends `or`
|
|
51
|
-
? TOKEN_TYPE.OR
|
|
54
|
+
? typeof TOKEN_TYPE.OR
|
|
52
55
|
: T extends `||`
|
|
53
|
-
? TOKEN_TYPE.OR
|
|
56
|
+
? typeof TOKEN_TYPE.OR
|
|
54
57
|
: T extends `|`
|
|
55
|
-
? TOKEN_TYPE.OR
|
|
58
|
+
? typeof TOKEN_TYPE.OR
|
|
56
59
|
: T extends `not`
|
|
57
|
-
? TOKEN_TYPE.NOT
|
|
60
|
+
? typeof TOKEN_TYPE.NOT
|
|
58
61
|
: T extends `!`
|
|
59
|
-
? TOKEN_TYPE.NOT
|
|
60
|
-
: TOKEN_TYPE.VALUE
|
|
62
|
+
? typeof TOKEN_TYPE.NOT
|
|
63
|
+
: typeof TOKEN_TYPE.VALUE
|
|
61
64
|
|
|
62
|
-
export type
|
|
63
|
-
| TOKEN_TYPE.PARENL
|
|
64
|
-
| TOKEN_TYPE.PARENR
|
|
65
|
+
export type TokenParen =
|
|
66
|
+
| typeof TOKEN_TYPE.PARENL
|
|
67
|
+
| typeof TOKEN_TYPE.PARENR
|
|
65
68
|
export type TokenBracketTypes =
|
|
66
|
-
| TOKEN_TYPE.BRACKETL
|
|
67
|
-
| TOKEN_TYPE.BRACKETR
|
|
69
|
+
| typeof TOKEN_TYPE.BRACKETL
|
|
70
|
+
| typeof TOKEN_TYPE.BRACKETR
|
|
68
71
|
|
|
69
|
-
export type
|
|
70
|
-
|
|
|
71
|
-
|
|
|
72
|
+
export type TokenDelimiter =
|
|
73
|
+
| TokenParen
|
|
74
|
+
| TokenQuote
|
|
72
75
|
| TokenBracketTypes
|
|
73
|
-
| TOKEN_TYPE.OP_EXPANDED_SEP
|
|
76
|
+
| typeof TOKEN_TYPE.OP_EXPANDED_SEP
|
|
74
77
|
|
|
75
|
-
export type
|
|
76
|
-
| TOKEN_TYPE.BACKTICK
|
|
77
|
-
| TOKEN_TYPE.SINGLEQUOTE
|
|
78
|
-
| TOKEN_TYPE.DOUBLEQUOTE
|
|
79
|
-
| TOKEN_TYPE.REGEX
|
|
78
|
+
export type TokenQuote =
|
|
79
|
+
| typeof TOKEN_TYPE.BACKTICK
|
|
80
|
+
| typeof TOKEN_TYPE.SINGLEQUOTE
|
|
81
|
+
| typeof TOKEN_TYPE.DOUBLEQUOTE
|
|
82
|
+
| typeof TOKEN_TYPE.REGEX
|
|
80
83
|
|
|
81
|
-
export type
|
|
82
|
-
| TOKEN_TYPE.AND
|
|
83
|
-
| TOKEN_TYPE.OR
|
|
84
|
+
export type TokenBoolean =
|
|
85
|
+
| typeof TOKEN_TYPE.AND
|
|
86
|
+
| typeof TOKEN_TYPE.OR
|
|
84
87
|
|
|
85
|
-
export type
|
|
86
|
-
|
|
|
87
|
-
| TOKEN_TYPE.NOT
|
|
88
|
+
export type TokenOperator =
|
|
89
|
+
| TokenBoolean
|
|
90
|
+
| typeof TOKEN_TYPE.NOT
|
|
88
91
|
|
|
89
|
-
export type
|
|
90
|
-
| TOKEN_TYPE.OP_CUSTOM
|
|
91
|
-
| TOKEN_TYPE.OP_EXPANDED_SEP
|
|
92
|
+
export type TokenPropertyOperator =
|
|
93
|
+
| typeof TOKEN_TYPE.OP_CUSTOM
|
|
94
|
+
| typeof TOKEN_TYPE.OP_EXPANDED_SEP
|
|
92
95
|
|
|
93
96
|
|
|
94
97
|
// export type EmptyObj = Record<"start"|"end", undefined>
|
|
@@ -101,16 +104,18 @@ export type Position = {
|
|
|
101
104
|
end: number
|
|
102
105
|
}
|
|
103
106
|
|
|
104
|
-
export
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
107
|
+
export const AST_TYPE = enumFromArray([
|
|
108
|
+
"EXPRESSION",
|
|
109
|
+
"NORMALIZED_EXPRESSION",
|
|
110
|
+
"GROUP",
|
|
111
|
+
"ARRAY",
|
|
112
|
+
"CONDITION",
|
|
113
|
+
"NORMALIZED_CONDITION",
|
|
114
|
+
"VARIABLE",
|
|
115
|
+
])
|
|
116
|
+
|
|
113
117
|
// #region AST nodes
|
|
118
|
+
export type AstType = EnumLike<typeof AST_TYPE>
|
|
114
119
|
|
|
115
120
|
|
|
116
121
|
export type RawNode<T extends Node> = Omit<T, "valid" | "type" | "isNode">
|
|
@@ -130,7 +135,7 @@ export interface BaseToken {
|
|
|
130
135
|
/**
|
|
131
136
|
* Valid tokens always have a value, even if it might be an empty string.
|
|
132
137
|
*/
|
|
133
|
-
export interface ValidToken<TType extends
|
|
138
|
+
export interface ValidToken<TType extends TokenType = TokenType> extends BaseToken {
|
|
134
139
|
valid: true
|
|
135
140
|
type: TType
|
|
136
141
|
value: string
|
|
@@ -150,7 +155,7 @@ export interface ErrorToken extends BaseToken {
|
|
|
150
155
|
type?: undefined
|
|
151
156
|
value?: undefined
|
|
152
157
|
valid: false
|
|
153
|
-
expected:
|
|
158
|
+
expected: TokenType[]
|
|
154
159
|
}
|
|
155
160
|
|
|
156
161
|
/**
|
|
@@ -159,7 +164,7 @@ export interface ErrorToken extends BaseToken {
|
|
|
159
164
|
* Using {@link Token} does not work well in certain situations and is also more complex because it has so many generics.
|
|
160
165
|
*/
|
|
161
166
|
export type AnyToken<
|
|
162
|
-
TType extends
|
|
167
|
+
TType extends TokenType = TokenType,
|
|
163
168
|
> =
|
|
164
169
|
| ValidToken<TType>
|
|
165
170
|
| ErrorToken
|
|
@@ -175,7 +180,7 @@ export type ParserResults = ExpressionNode | ConditionNode | GroupNode | ErrorTo
|
|
|
175
180
|
*/
|
|
176
181
|
|
|
177
182
|
export interface Node<
|
|
178
|
-
TType extends
|
|
183
|
+
TType extends AstType = AstType,
|
|
179
184
|
TValid extends boolean = boolean,
|
|
180
185
|
> {
|
|
181
186
|
isNode: true
|
|
@@ -222,16 +227,16 @@ export interface GroupNode<
|
|
|
222
227
|
TPrefix extends
|
|
223
228
|
TPrefixable extends true
|
|
224
229
|
? ConditionNode<TValid> |
|
|
225
|
-
ValidToken<TOKEN_TYPE.NOT> |
|
|
230
|
+
ValidToken<typeof TOKEN_TYPE.NOT> |
|
|
226
231
|
undefined
|
|
227
|
-
: ValidToken<TOKEN_TYPE.NOT> |
|
|
232
|
+
: ValidToken<typeof TOKEN_TYPE.NOT> |
|
|
228
233
|
undefined =
|
|
229
234
|
TPrefixable extends true
|
|
230
235
|
? ConditionNode<TValid> |
|
|
231
|
-
ValidToken<TOKEN_TYPE.NOT> |
|
|
236
|
+
ValidToken<typeof TOKEN_TYPE.NOT> |
|
|
232
237
|
undefined
|
|
233
|
-
: ValidToken<TOKEN_TYPE.NOT>,
|
|
234
|
-
> extends Node<AST_TYPE.GROUP> {
|
|
238
|
+
: ValidToken<typeof TOKEN_TYPE.NOT>,
|
|
239
|
+
> extends Node<typeof AST_TYPE.GROUP> {
|
|
235
240
|
/**
|
|
236
241
|
* If the condition is negated this will contain a "not" **token**, {@link ValidToken} .
|
|
237
242
|
*
|
|
@@ -250,7 +255,7 @@ export interface GroupNode<
|
|
|
250
255
|
/**
|
|
251
256
|
* The parenthesis tokens, {@link ValidToken} . These will always be defined (although not necessarily with valid tokens).
|
|
252
257
|
*/
|
|
253
|
-
paren: NodeDelimiters<TOKEN_TYPE.PARENL, TOKEN_TYPE.PARENR>
|
|
258
|
+
paren: NodeDelimiters<typeof TOKEN_TYPE.PARENL, typeof TOKEN_TYPE.PARENR>
|
|
254
259
|
}
|
|
255
260
|
|
|
256
261
|
|
|
@@ -266,18 +271,18 @@ export interface GroupNode<
|
|
|
266
271
|
* If `prefixableStrings` is true, the `prefix` property might contain a value token.
|
|
267
272
|
*/
|
|
268
273
|
|
|
269
|
-
export interface VariableNode<TValid extends boolean = boolean> extends Node<AST_TYPE.VARIABLE, TValid> {
|
|
274
|
+
export interface VariableNode<TValid extends boolean = boolean> extends Node<typeof AST_TYPE.VARIABLE, TValid> {
|
|
270
275
|
value: TValid extends boolean
|
|
271
|
-
? AnyToken<TOKEN_TYPE.VALUE>
|
|
276
|
+
? AnyToken<typeof TOKEN_TYPE.VALUE>
|
|
272
277
|
: TValid extends true
|
|
273
|
-
? ValidToken<TOKEN_TYPE.VALUE>
|
|
278
|
+
? ValidToken<typeof TOKEN_TYPE.VALUE>
|
|
274
279
|
: ErrorToken
|
|
275
|
-
prefix?: ValidToken<TOKEN_TYPE.VALUE> // todo
|
|
276
|
-
quote?: NodeDelimiters<
|
|
280
|
+
prefix?: ValidToken<typeof TOKEN_TYPE.VALUE> // todo
|
|
281
|
+
quote?: NodeDelimiters<TokenQuote, TokenQuote>
|
|
277
282
|
}
|
|
278
283
|
|
|
279
|
-
export interface ExpressionNode<TValid extends boolean = boolean> extends Node<AST_TYPE.EXPRESSION> {
|
|
280
|
-
operator: AnyToken<
|
|
284
|
+
export interface ExpressionNode<TValid extends boolean = boolean> extends Node<typeof AST_TYPE.EXPRESSION> {
|
|
285
|
+
operator: AnyToken<TokenBoolean>
|
|
281
286
|
left:
|
|
282
287
|
| ExpressionNode<TValid>
|
|
283
288
|
| ConditionNode<TValid>
|
|
@@ -298,17 +303,17 @@ export type Nodes = ExpressionNode | ConditionNode | GroupNode | VariableNode |
|
|
|
298
303
|
*
|
|
299
304
|
* These are usually not important for evaluating an expression but are useful for syntax highlighting.
|
|
300
305
|
*/
|
|
301
|
-
export type NodeDelimiters<TLEFT extends
|
|
306
|
+
export type NodeDelimiters<TLEFT extends TokenType, TRIGHT extends TokenType = TLEFT> = {
|
|
302
307
|
left: AnyToken<TLEFT>
|
|
303
308
|
right: AnyToken<TRIGHT>
|
|
304
309
|
/** Only exists if regexes are enabled and this is a regex value. */
|
|
305
|
-
flags?: ValidToken<TOKEN_TYPE.VALUE>
|
|
310
|
+
flags?: ValidToken<typeof TOKEN_TYPE.VALUE>
|
|
306
311
|
}
|
|
307
312
|
|
|
308
313
|
|
|
309
|
-
export interface ArrayNode<TValid extends boolean = boolean> extends Node<AST_TYPE.ARRAY> {
|
|
314
|
+
export interface ArrayNode<TValid extends boolean = boolean> extends Node<typeof AST_TYPE.ARRAY> {
|
|
310
315
|
values: VariableNode[]
|
|
311
|
-
bracket: NodeDelimiters<TOKEN_TYPE.BRACKETL, TOKEN_TYPE.BRACKETR>
|
|
316
|
+
bracket: NodeDelimiters<typeof TOKEN_TYPE.BRACKETL, typeof TOKEN_TYPE.BRACKETR>
|
|
312
317
|
valid: TValid
|
|
313
318
|
}
|
|
314
319
|
|
|
@@ -321,7 +326,7 @@ export interface ArrayNode<TValid extends boolean = boolean> extends Node<AST_TY
|
|
|
321
326
|
*/
|
|
322
327
|
export interface ConditionNode<
|
|
323
328
|
TValid extends boolean = boolean,
|
|
324
|
-
> extends Node<AST_TYPE.CONDITION> {
|
|
329
|
+
> extends Node<typeof AST_TYPE.CONDITION> {
|
|
325
330
|
/**
|
|
326
331
|
* Contains a value node which could be a variable, an array node (if enabled), or a group.
|
|
327
332
|
*
|
|
@@ -337,7 +342,7 @@ export interface ConditionNode<
|
|
|
337
342
|
/**
|
|
338
343
|
* If the condition was negated, contains the "not" token, {@link ValidToken} , the condition was negated with.
|
|
339
344
|
*/
|
|
340
|
-
operator?: ValidToken<TOKEN_TYPE.NOT>
|
|
345
|
+
operator?: ValidToken<typeof TOKEN_TYPE.NOT>
|
|
341
346
|
/**
|
|
342
347
|
* If condition property operators are used, this will contain the property (as a variable), or an error token if it was missing (but some separator or operator was passed).
|
|
343
348
|
*
|
|
@@ -355,7 +360,7 @@ export interface ConditionNode<
|
|
|
355
360
|
*
|
|
356
361
|
* See the corresponding {@link ParserOptions} for more details.
|
|
357
362
|
*/
|
|
358
|
-
propertyOperator?: AnyToken<TOKEN_TYPE.OP_CUSTOM | TOKEN_TYPE.VALUE>
|
|
363
|
+
propertyOperator?: AnyToken<typeof TOKEN_TYPE.OP_CUSTOM | typeof TOKEN_TYPE.VALUE>
|
|
359
364
|
/**
|
|
360
365
|
* If "long/expanded" form condition property operators are used, this will contain the separators, otherwise it is undefined.
|
|
361
366
|
*
|
|
@@ -368,8 +373,8 @@ export interface ConditionNode<
|
|
|
368
373
|
* See the corresponding {@link ParserOptions} for more details.
|
|
369
374
|
*/
|
|
370
375
|
sep?: {
|
|
371
|
-
left?: AnyToken<TOKEN_TYPE.OP_EXPANDED_SEP>
|
|
372
|
-
right?: AnyToken<TOKEN_TYPE.OP_EXPANDED_SEP>
|
|
376
|
+
left?: AnyToken<typeof TOKEN_TYPE.OP_EXPANDED_SEP>
|
|
377
|
+
right?: AnyToken<typeof TOKEN_TYPE.OP_EXPANDED_SEP>
|
|
373
378
|
}
|
|
374
379
|
}
|
|
375
380
|
|
|
@@ -377,7 +382,7 @@ export interface NormalizedCondition<
|
|
|
377
382
|
TOp extends string = string,
|
|
378
383
|
TValue = any,
|
|
379
384
|
> {
|
|
380
|
-
type: AST_TYPE.NORMALIZED_CONDITION
|
|
385
|
+
type: typeof AST_TYPE.NORMALIZED_CONDITION
|
|
381
386
|
value: TValue
|
|
382
387
|
operator?: TOp
|
|
383
388
|
property: string[]
|
|
@@ -386,14 +391,14 @@ export interface NormalizedCondition<
|
|
|
386
391
|
|
|
387
392
|
|
|
388
393
|
export interface NormalizedExpression<TType extends string = string, TValue = any> {
|
|
389
|
-
type: AST_TYPE.NORMALIZED_EXPRESSION
|
|
394
|
+
type: typeof AST_TYPE.NORMALIZED_EXPRESSION
|
|
390
395
|
left:
|
|
391
396
|
| NormalizedExpression<TType, TValue>
|
|
392
397
|
| NormalizedCondition<TType, TValue>
|
|
393
398
|
right:
|
|
394
399
|
| NormalizedExpression<TType, TValue>
|
|
395
400
|
| NormalizedCondition<TType, TValue>
|
|
396
|
-
operator:
|
|
401
|
+
operator: TokenBoolean
|
|
397
402
|
}
|
|
398
403
|
|
|
399
404
|
export type ParentTypes<T extends Node | BaseToken | undefined> =
|