@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.
Files changed (99) hide show
  1. package/README.md +1 -2
  2. package/dist/Lexer.d.ts +99 -94
  3. package/dist/Lexer.d.ts.map +1 -1
  4. package/dist/Lexer.js +211 -559
  5. package/dist/Parser.d.ts +26 -26
  6. package/dist/Parser.d.ts.map +1 -1
  7. package/dist/Parser.js +2 -1
  8. package/dist/ast/builders/condition.d.ts +1 -1
  9. package/dist/ast/builders/condition.d.ts.map +1 -1
  10. package/dist/ast/builders/condition.js +1 -0
  11. package/dist/ast/builders/delim.d.ts +2 -2
  12. package/dist/ast/builders/delim.d.ts.map +1 -1
  13. package/dist/ast/builders/error.d.ts +2 -2
  14. package/dist/ast/builders/error.d.ts.map +1 -1
  15. package/dist/ast/builders/expression.d.ts +2 -2
  16. package/dist/ast/builders/expression.d.ts.map +1 -1
  17. package/dist/ast/builders/expression.js +2 -6
  18. package/dist/ast/builders/group.d.ts +1 -1
  19. package/dist/ast/builders/group.d.ts.map +1 -1
  20. package/dist/ast/builders/group.js +1 -3
  21. package/dist/ast/builders/pos.d.ts +2 -2
  22. package/dist/ast/builders/pos.d.ts.map +1 -1
  23. package/dist/ast/builders/token.d.ts +2 -2
  24. package/dist/ast/builders/token.d.ts.map +1 -1
  25. package/dist/ast/builders/type.d.ts +2 -2
  26. package/dist/ast/builders/type.d.ts.map +1 -1
  27. package/dist/ast/builders/variable.d.ts +3 -3
  28. package/dist/ast/builders/variable.d.ts.map +1 -1
  29. package/dist/ast/createConditionNode.d.ts +1 -1
  30. package/dist/ast/createConditionNode.d.ts.map +1 -1
  31. package/dist/ast/createGroupNode.d.ts +1 -1
  32. package/dist/ast/createGroupNode.d.ts.map +1 -1
  33. package/dist/ast/createToken.d.ts +2 -2
  34. package/dist/ast/createToken.d.ts.map +1 -1
  35. package/dist/ast/createToken.js +2 -2
  36. package/dist/ast/error.d.ts +2 -2
  37. package/dist/ast/error.d.ts.map +1 -1
  38. package/dist/ast/error.js +1 -0
  39. package/dist/ast/handlers.d.ts +23 -23
  40. package/dist/ast/handlers.d.ts.map +1 -1
  41. package/dist/ast/handlers.js +1 -1
  42. package/dist/examples/ParserWithSqlSupport.d.ts +5 -5
  43. package/dist/examples/ParserWithSqlSupport.d.ts.map +1 -1
  44. package/dist/examples/ParserWithSqlSupport.js +2 -0
  45. package/dist/index.js +2 -2
  46. package/dist/internal/ExpressitError.d.ts +2 -2
  47. package/dist/internal/ExpressitError.d.ts.map +1 -1
  48. package/dist/internal/checkParserOpts.js +11 -11
  49. package/dist/package.json.js +2 -60
  50. package/dist/types/ast.d.ts +60 -58
  51. package/dist/types/ast.d.ts.map +1 -1
  52. package/dist/types/ast.js +26 -27
  53. package/dist/types/autocomplete.d.ts +23 -21
  54. package/dist/types/autocomplete.d.ts.map +1 -1
  55. package/dist/types/autocomplete.js +24 -21
  56. package/dist/types/errors.d.ts +12 -10
  57. package/dist/types/errors.d.ts.map +1 -1
  58. package/dist/types/errors.js +8 -7
  59. package/dist/types/index.js +2 -2
  60. package/dist/types/parser.d.ts +3 -3
  61. package/dist/types/parser.d.ts.map +1 -1
  62. package/dist/utils/getCursorInfo.js +2 -0
  63. package/dist/utils/getOppositeDelimiter.d.ts +2 -2
  64. package/dist/utils/getOppositeDelimiter.d.ts.map +1 -1
  65. package/dist/utils/isDelimiter.d.ts +2 -2
  66. package/dist/utils/isDelimiter.d.ts.map +1 -1
  67. package/dist/utils/isParen.d.ts +2 -2
  68. package/dist/utils/isParen.d.ts.map +1 -1
  69. package/dist/utils/isQuote.d.ts +2 -2
  70. package/dist/utils/isQuote.d.ts.map +1 -1
  71. package/package.json +13 -13
  72. package/src/Lexer.ts +98 -88
  73. package/src/Parser.ts +61 -61
  74. package/src/ast/builders/condition.ts +3 -3
  75. package/src/ast/builders/delim.ts +4 -4
  76. package/src/ast/builders/error.ts +3 -3
  77. package/src/ast/builders/expression.ts +4 -8
  78. package/src/ast/builders/group.ts +2 -4
  79. package/src/ast/builders/pos.ts +3 -3
  80. package/src/ast/builders/token.ts +2 -2
  81. package/src/ast/builders/type.ts +2 -2
  82. package/src/ast/builders/variable.ts +5 -5
  83. package/src/ast/createConditionNode.ts +2 -2
  84. package/src/ast/createGroupNode.ts +4 -4
  85. package/src/ast/createToken.ts +6 -6
  86. package/src/ast/error.ts +2 -2
  87. package/src/ast/handlers.ts +20 -20
  88. package/src/examples/ParserWithSqlSupport.ts +11 -5
  89. package/src/internal/ExpressitError.ts +3 -3
  90. package/src/internal/checkParserOpts.ts +11 -11
  91. package/src/types/ast.ts +101 -96
  92. package/src/types/autocomplete.ts +26 -22
  93. package/src/types/errors.ts +18 -13
  94. package/src/types/parser.ts +3 -3
  95. package/src/utils/getOppositeDelimiter.ts +2 -2
  96. package/src/utils/getSurroundingErrors.ts +4 -4
  97. package/src/utils/isDelimiter.ts +3 -3
  98. package/src/utils/isParen.ts +2 -2
  99. 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 TOKEN_TYPE } from "../types/ast.js"
3
+ import { type ErrorToken,type TokenType } from "../types/ast.js"
4
4
 
5
- export function error<T extends TOKEN_TYPE>(pos: number, expected: T[]): ErrorToken {
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
  }
@@ -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 TokenBooleanTypes, type TokenDelimiterTypes, type TokenOperatorTypes, type TokenQuoteTypes, type ValidToken, type VariableNode } from "../types/ast.js"
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 TOKEN_TYPE>(pos: number, expected: T[]): ErrorToken {
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 TokenOperatorTypes>
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 TokenDelimiterTypes>
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 TOKEN_TYPE> (type: T) => <TVal extends string | undefined> (value: TVal, pos: Position): TVal extends string ? ValidToken<T> : ErrorToken => {
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<TokenQuoteTypes> | null | undefined,
68
- value: AnyToken<TOKEN_TYPE.VALUE> | null | undefined,
69
- quoteR: AnyToken<TokenQuoteTypes> | null | undefined,
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 ? value : error(end, [TOKEN_TYPE.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<TokenBooleanTypes> | null | undefined,
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 BaseErrorTokenTypes =
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: BaseErrorTokenTypes
56
+ type: SqlParserError
57
57
  message?: string
58
58
  } =
59
59
  Position & {
60
- type: BaseErrorTokenTypes
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
- public propertyDefinitions: TPropertyDefinitions,
75
- public operatorDefinitions: TOperatorDefinitions,
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" assert { type: "json" }
6
+ import packageJson from "../../package.json" with { type: "json" }
7
7
  const { version, repository } = packageJson
8
- import type { ERROR_CODES, ErrorInfo } from "../types/errors.js"
8
+ import type { ErrorInfo, ParserError } from "../types/errors.js"
9
9
 
10
10
  /** @internal */
11
- export class ExpressitError<T extends ERROR_CODES> extends Error {
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 { ERROR_CODES } from "../types/errors.js"
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
- ERROR_CODES.PARSER_CONFLICTING_OPTIONS_ERROR,
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
- ERROR_CODES.PARSER_CONFLICTING_OPTIONS_ERROR,
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
- ERROR_CODES.PARSER_CONFLICTING_OPTIONS_ERROR,
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
- ERROR_CODES.PARSER_CONFLICTING_OPTIONS_ERROR,
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
- ERROR_CODES.PARSER_CONFLICTING_OPTIONS_ERROR,
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
- ERROR_CODES.PARSER_CONFLICTING_OPTIONS_ERROR,
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
- ERROR_CODES.PARSER_CONFLICTING_OPTIONS_ERROR,
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
- ERROR_CODES.PARSER_OPTION_REQUIRED_ERROR,
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
- ERROR_CODES.PARSER_OPTION_REQUIRED_ERROR,
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
- ERROR_CODES.PARSER_OPTION_REQUIRED_ERROR,
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 type { AnyFunction } from "@alanscodelog/utils/types"
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 enum TOKEN_TYPE {
7
- VALUE = "VALUE",
8
- AND = "AND",
9
- OR = "OR",
10
- NOT = "NOT",
11
- BACKTICK = "BACKTICK",
12
- SINGLEQUOTE = "SINGLEQUOTE",
13
- DOUBLEQUOTE = "DOUBLEQUOTE",
14
- PARENL = "PARENL",
15
- PARENR = "PARENR",
16
- BRACKETL = "BRACKETL",
17
- BRACKETR = "BRACKETR",
18
- OP_EXPANDED_SEP = "OP_EXPANDED",
19
- OP_CUSTOM = "OP_CUSTOM",
20
- REGEX = "REGEX",
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 ExtractTokenType<T extends string> =
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 TokenParenTypes =
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 TokenDelimiterTypes =
70
- | TokenParenTypes
71
- | TokenQuoteTypes
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 TokenQuoteTypes =
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 TokenBooleanTypes =
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 TokenOperatorTypes =
86
- | TokenBooleanTypes
87
- | TOKEN_TYPE.NOT
88
+ export type TokenOperator =
89
+ | TokenBoolean
90
+ | typeof TOKEN_TYPE.NOT
88
91
 
89
- export type TokenPropertyOperatorTypes =
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 enum AST_TYPE {
105
- EXPRESSION = "EXPRESSION",
106
- NORMALIZED_EXPRESSION = "NORMALIZED_EXPRESSION",
107
- GROUP = "GROUP",
108
- ARRAY = "ARRAY",
109
- CONDITION = "CONDITION",
110
- NORMALIZED_CONDITION = "NORMALIZED_CONDITION",
111
- VARIABLE = "VARIABLE",
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 TOKEN_TYPE = TOKEN_TYPE> extends BaseToken {
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: TOKEN_TYPE[]
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 TOKEN_TYPE = TOKEN_TYPE,
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 AST_TYPE = AST_TYPE,
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<TokenQuoteTypes, TokenQuoteTypes>
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<TokenBooleanTypes>
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 TOKEN_TYPE, TRIGHT extends TOKEN_TYPE = TLEFT> = {
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: TokenBooleanTypes
401
+ operator: TokenBoolean
397
402
  }
398
403
 
399
404
  export type ParentTypes<T extends Node | BaseToken | undefined> =