@witchcraft/expressit 0.2.1 → 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 (119) hide show
  1. package/README.md +6 -4
  2. package/dist/Lexer.d.ts +102 -99
  3. package/dist/Lexer.d.ts.map +1 -1
  4. package/dist/Lexer.js +211 -557
  5. package/dist/Parser.d.ts +27 -27
  6. package/dist/Parser.d.ts.map +1 -1
  7. package/dist/Parser.js +5 -2
  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 +3 -3
  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 +4 -4
  42. package/dist/examples/ParserWithSqlSupport.d.ts +62 -0
  43. package/dist/examples/ParserWithSqlSupport.d.ts.map +1 -0
  44. package/dist/examples/ParserWithSqlSupport.js +271 -0
  45. package/dist/examples/{shortcutContextParser.d.ts → ShortcutContextParser.d.ts} +5 -5
  46. package/dist/examples/ShortcutContextParser.d.ts.map +1 -0
  47. package/dist/examples/{shortcutContextParser.js → ShortcutContextParser.js} +2 -2
  48. package/dist/examples/index.d.ts +2 -1
  49. package/dist/examples/index.d.ts.map +1 -1
  50. package/dist/examples/index.js +3 -1
  51. package/dist/index.js +2 -2
  52. package/dist/internal/ExpressitError.d.ts +2 -2
  53. package/dist/internal/ExpressitError.d.ts.map +1 -1
  54. package/dist/internal/ExpressitError.js +2 -1
  55. package/dist/internal/checkParserOpts.d.ts +1 -1
  56. package/dist/internal/checkParserOpts.d.ts.map +1 -1
  57. package/dist/internal/checkParserOpts.js +11 -11
  58. package/dist/internal/parseParserOptions.d.ts +1 -1
  59. package/dist/internal/parseParserOptions.d.ts.map +1 -1
  60. package/dist/package.json.js +4 -195
  61. package/dist/types/ast.d.ts +60 -58
  62. package/dist/types/ast.d.ts.map +1 -1
  63. package/dist/types/ast.js +26 -27
  64. package/dist/types/autocomplete.d.ts +23 -21
  65. package/dist/types/autocomplete.d.ts.map +1 -1
  66. package/dist/types/autocomplete.js +24 -21
  67. package/dist/types/errors.d.ts +12 -10
  68. package/dist/types/errors.d.ts.map +1 -1
  69. package/dist/types/errors.js +8 -7
  70. package/dist/types/index.js +2 -2
  71. package/dist/types/parser.d.ts +9 -9
  72. package/dist/types/parser.d.ts.map +1 -1
  73. package/dist/utils/getCursorInfo.js +3 -1
  74. package/dist/utils/getOppositeDelimiter.d.ts +2 -2
  75. package/dist/utils/getOppositeDelimiter.d.ts.map +1 -1
  76. package/dist/utils/isDelimiter.d.ts +2 -2
  77. package/dist/utils/isDelimiter.d.ts.map +1 -1
  78. package/dist/utils/isParen.d.ts +2 -2
  79. package/dist/utils/isParen.d.ts.map +1 -1
  80. package/dist/utils/isQuote.d.ts +2 -2
  81. package/dist/utils/isQuote.d.ts.map +1 -1
  82. package/package.json +29 -27
  83. package/src/Lexer.ts +103 -92
  84. package/src/Parser.ts +70 -64
  85. package/src/ast/builders/condition.ts +3 -3
  86. package/src/ast/builders/delim.ts +5 -5
  87. package/src/ast/builders/error.ts +3 -3
  88. package/src/ast/builders/expression.ts +4 -8
  89. package/src/ast/builders/group.ts +2 -4
  90. package/src/ast/builders/pos.ts +3 -3
  91. package/src/ast/builders/token.ts +2 -2
  92. package/src/ast/builders/type.ts +2 -2
  93. package/src/ast/builders/variable.ts +5 -5
  94. package/src/ast/createConditionNode.ts +2 -2
  95. package/src/ast/createGroupNode.ts +4 -4
  96. package/src/ast/createToken.ts +6 -6
  97. package/src/ast/error.ts +2 -2
  98. package/src/ast/handlers.ts +23 -23
  99. package/src/examples/ParserWithSqlSupport.ts +371 -0
  100. package/src/examples/{shortcutContextParser.ts → ShortcutContextParser.ts} +14 -14
  101. package/src/examples/index.ts +2 -1
  102. package/src/internal/ExpressitError.ts +4 -4
  103. package/src/internal/checkParserOpts.ts +14 -14
  104. package/src/internal/parseParserOptions.ts +2 -2
  105. package/src/types/ast.ts +101 -96
  106. package/src/types/autocomplete.ts +26 -22
  107. package/src/types/errors.ts +18 -13
  108. package/src/types/parser.ts +9 -9
  109. package/src/utils/getCursorInfo.ts +1 -1
  110. package/src/utils/getOppositeDelimiter.ts +2 -2
  111. package/src/utils/getSurroundingErrors.ts +4 -4
  112. package/src/utils/isDelimiter.ts +3 -3
  113. package/src/utils/isParen.ts +2 -2
  114. package/src/utils/isQuote.ts +2 -2
  115. package/dist/examples/shortcutContextParser.d.ts.map +0 -1
  116. package/dist/global.d.js +0 -1
  117. package/dist/package.js +0 -7
  118. package/src/global.d.ts +0 -4
  119. package/src/package.js +0 -11
package/src/Parser.ts CHANGED
@@ -19,9 +19,9 @@ import { extractPosition } from "./internal/extractPosition.js"
19
19
  import { getUnclosedRightParenCount } from "./internal/getUnclosedRightParenCount.js"
20
20
  import { parseParserOptions } from "./internal/parseParserOptions.js"
21
21
  import { unescape } from "./internal/unescape.js"
22
- import { $C, $T, Lexer,type RealTokenType, type Token, type TokenCategoryType, type TokenType } from "./Lexer.js"
23
- import type { ArrayNode, ConditionNode, GroupNode, NormalizedCondition, NormalizedExpression, ParserResults, TokenBooleanTypes, ValidToken, VariableNode, } from "./types/ast.js"
24
- import { type AnyToken, AST_TYPE,type Completion, type Position, type Suggestion,SUGGESTION_TYPE, TOKEN_TYPE } from "./types/index.js"
22
+ import { $C, type $CType, $T, type $TType, Lexer, type LexerCategoryToken, type LexerRealToken, type LexerToken,type Token } from "./Lexer.js"
23
+ import type { ArrayNode, ConditionNode, GroupNode, NormalizedCondition, NormalizedExpression, ParserResults, TokenBoolean, TokenType, ValidToken, VariableNode } from "./types/ast.js"
24
+ import { type AnyToken, AST_TYPE, type Completion, type Position, type Suggestion, SUGGESTION_TYPE, type SuggestionType,TOKEN_TYPE } from "./types/index.js"
25
25
  import type { FullParserOptions, KeywordEntry, ParserOptions, ValidationQuery, ValueQuery } from "./types/parser.js"
26
26
  import { extractTokens } from "./utils/extractTokens.js"
27
27
  import { generateParentsMap } from "./utils/generateParentsMap.js"
@@ -52,7 +52,7 @@ const defaultNodeDirs = {
52
52
  const createDefaultRequires = (partial: DeepPartial<Suggestion["requires"]> = {}): Suggestion["requires"] => ({
53
53
  whitespace: {
54
54
  ...defaultNodeDirs,
55
- ...(partial.whitespace ? partial.whitespace : {}),
55
+ ...(partial.whitespace ?? {}),
56
56
  },
57
57
  group: partial.group ?? false,
58
58
  prefix: partial.prefix ?? false,
@@ -62,7 +62,7 @@ const createDefaultRequires = (partial: DeepPartial<Suggestion["requires"]> = {}
62
62
  const tokenRequiresWhitespace = (valid: ValidToken | undefined, whitespace: boolean, wordOps: KeywordEntry[]): boolean => {
63
63
  if (whitespace || valid === undefined) return false
64
64
  return valid.type === TOKEN_TYPE.VALUE ||
65
- ([TOKEN_TYPE.AND, TOKEN_TYPE.OR, TOKEN_TYPE.NOT].includes(valid.type) &&
65
+ (([TOKEN_TYPE.AND, TOKEN_TYPE.OR, TOKEN_TYPE.NOT] as string[]).includes(valid.type) &&
66
66
  wordOps.find(_ => _.value === valid.value) !== undefined)
67
67
  }
68
68
  const tokenVariable = [TOKEN_TYPE.BACKTICK, TOKEN_TYPE.DOUBLEQUOTE, TOKEN_TYPE.SINGLEQUOTE, TOKEN_TYPE.VALUE, TOKEN_TYPE.REGEX]
@@ -70,7 +70,7 @@ const tokenVariable = [TOKEN_TYPE.BACKTICK, TOKEN_TYPE.DOUBLEQUOTE, TOKEN_TYPE.S
70
70
  /**
71
71
  * Creates the main parser class which handles all functionality (evaluation, validation, etc).
72
72
  */
73
- export class Parser<T extends {} = {}> {
73
+ export class Parser<T = any> {
74
74
  // needed for evaluate and validate so they are only checked on demand
75
75
  private evaluationOptionsChecked: boolean = false
76
76
 
@@ -96,9 +96,9 @@ export class Parser<T extends {} = {}> {
96
96
 
97
97
  private readonly lexer: Lexer
98
98
 
99
- private readonly $: Record<$T, RealTokenType<$T>>
99
+ private readonly $: Record<$TType, LexerRealToken<$TType>>
100
100
 
101
- private readonly $categories: Partial<Record<$C, TokenCategoryType<$C>>>
101
+ private readonly $categories: Partial<Record<$CType, LexerCategoryToken<$CType>>>
102
102
 
103
103
  private readonly info: Pick<ReturnType<Lexer["calculateSymbolInfo"]>, "expandedSepAlsoCustom" | "customOpAlsoNegation">
104
104
 
@@ -117,7 +117,7 @@ export class Parser<T extends {} = {}> {
117
117
 
118
118
  state: {
119
119
  rawInput: string
120
- lexedTokens: Token<$T>[]
120
+ lexedTokens: Token<$TType>[]
121
121
  index: number
122
122
  shift: number
123
123
  } = {
@@ -131,7 +131,7 @@ export class Parser<T extends {} = {}> {
131
131
  * This is exposed mainly for debugging purposes. Use parse directly instead.
132
132
  */
133
133
  lex(input: string): {
134
- tokens: Token<$T> []
134
+ tokens: Token<$TType> []
135
135
  shift: number
136
136
  rawInput: string
137
137
  } {
@@ -168,7 +168,7 @@ export class Parser<T extends {} = {}> {
168
168
  parse(
169
169
  input: string
170
170
  | {
171
- tokens: Token<$T> []
171
+ tokens: Token<$TType> []
172
172
  shift: number
173
173
  rawInput: string
174
174
  },
@@ -206,9 +206,9 @@ export class Parser<T extends {} = {}> {
206
206
  }
207
207
 
208
208
 
209
- transformCategoryToken<TC extends $C>(
209
+ transformCategoryToken<TC extends $CType>(
210
210
  token: Token,
211
- categoryToken: TokenCategoryType<TC>,
211
+ categoryToken: LexerCategoryToken<TC>,
212
212
  ): Token<TC> {
213
213
  return {
214
214
  ...token,
@@ -216,37 +216,37 @@ export class Parser<T extends {} = {}> {
216
216
  }
217
217
  }
218
218
 
219
- getCategoryTokens<TType extends $C>(
219
+ getCategoryTokens<TType extends $CType>(
220
220
  type: TType,
221
- ): TokenCategoryType<TType>["entries"] | undefined {
222
- return this.$categories[type as $C]?.entries as any
221
+ ): LexerCategoryToken<TType>["entries"] | undefined {
222
+ return this.$categories[type as $CType]?.entries as any
223
223
  }
224
224
 
225
- getTokenType(type: $T | $C): TokenType<$T> | undefined {
226
- return this.$[type as any as $T] as any
225
+ getTokenType(type: $TType | $CType): LexerToken<$TType> | undefined {
226
+ return this.$[type as any as $TType] as any
227
227
  }
228
228
 
229
- isExactType<TType extends $T>(token: Token, type: TType): token is Token<TType> {
229
+ isExactType<TType extends $TType>(token: Token, type: TType): token is Token<TType> {
230
230
  if (this.$[type]) {
231
231
  return this.isType(token, type)
232
232
  }
233
233
  return false
234
234
  }
235
235
 
236
- isType(token: Token | undefined, type: $T | $C): boolean {
236
+ isType(token: Token | undefined, type: $TType | $CType): boolean {
237
237
  if (token === undefined) return false
238
238
  if (token.type === type) return true
239
239
  const tokenType = this.getTokenType(token.type)
240
240
 
241
241
  if (tokenType?.type === type) return true
242
- const category = this.$categories[type as $C]
243
- if (category?.entries[token.type as $T] !== undefined) {
242
+ const category = this.$categories[type as $CType]
243
+ if (category?.entries[token.type as $TType] !== undefined) {
244
244
  return true
245
245
  }
246
246
  return false
247
247
  }
248
248
 
249
- createErrorToken(type: $T, index?: number): Token {
249
+ createErrorToken(type: $TType, index?: number): Token {
250
250
  return {
251
251
  type,
252
252
  value: "",
@@ -265,7 +265,7 @@ export class Parser<T extends {} = {}> {
265
265
  }
266
266
 
267
267
 
268
- peek(n = 1): Token<$T> | undefined {
268
+ peek(n = 1): Token<$TType> | undefined {
269
269
  return this.state.lexedTokens[this.state.index + n]
270
270
  }
271
271
 
@@ -273,12 +273,12 @@ export class Parser<T extends {} = {}> {
273
273
  return this.peek(1) === undefined
274
274
  }
275
275
 
276
- consumeAny(): Token<$T> {
276
+ consumeAny(): Token<$TType> {
277
277
  return this.consume(this.peek(1)?.type)
278
278
  }
279
279
 
280
280
  consume<
281
- TType extends $T | $C,
281
+ TType extends $TType | $CType,
282
282
  >(
283
283
  type: TType | undefined,
284
284
  ): Token<TType> {
@@ -289,9 +289,9 @@ export class Parser<T extends {} = {}> {
289
289
  if (nextToken === undefined) {
290
290
  throw new Error(`Reached end of input without consuming a token of type ${type}`)
291
291
  }
292
- if (this.$categories[type as $C] !== undefined) {
293
- const categoryToken = this.$categories[type as $C]
294
- const tokenType = categoryToken?.entries[nextToken.type as $T]
292
+ if (this.$categories[type as $CType] !== undefined) {
293
+ const categoryToken = this.$categories[type as $CType]
294
+ const tokenType = categoryToken?.entries[nextToken.type as $TType]
295
295
  if (categoryToken && tokenType) {
296
296
  this.state.index++
297
297
  return this.transformCategoryToken(nextToken, categoryToken) as Token<TType>
@@ -299,7 +299,7 @@ export class Parser<T extends {} = {}> {
299
299
  throw new Error("here")
300
300
  }
301
301
  } else {
302
- const tokenType = this.getTokenType(type as $T)
302
+ const tokenType = this.getTokenType(type as $TType)
303
303
  if (tokenType !== undefined) {
304
304
  if (nextToken?.type === tokenType.type) {
305
305
  this.state.index++
@@ -554,9 +554,9 @@ export class Parser<T extends {} = {}> {
554
554
  { onlyValues = false, convertRegexValues = false, convertArrayValues = false }:
555
555
  { onlyValues?: boolean, convertRegexValues?: boolean, convertArrayValues?: boolean } = {},
556
556
  ): [
557
- ValidToken<TOKEN_TYPE.PARENL> | undefined,
557
+ ValidToken<typeof TOKEN_TYPE.PARENL> | undefined,
558
558
  GroupNode["expression"],
559
- ValidToken<TOKEN_TYPE.PARENR> | undefined,
559
+ ValidToken<typeof TOKEN_TYPE.PARENR> | undefined,
560
560
  ] {
561
561
  const parenL = this.ruleParenL()
562
562
  let parenLeftCount = 0
@@ -709,7 +709,7 @@ export class Parser<T extends {} = {}> {
709
709
  rest = {
710
710
  sepL: undefined,
711
711
  sepR,
712
- propertyOperator: sepL as any as AnyToken<TOKEN_TYPE.OP_CUSTOM>,
712
+ propertyOperator: sepL as any as AnyToken<typeof TOKEN_TYPE.OP_CUSTOM>,
713
713
  }
714
714
  } else {
715
715
  rest = { sepL, sepR, propertyOperator: op }
@@ -756,7 +756,7 @@ export class Parser<T extends {} = {}> {
756
756
  }
757
757
  if (this.isType(next, $C.REGEX_ANY)) {
758
758
  // this is safe since the start can never match flags
759
- const quoteL = this.ruleRegexAny() as ValidToken<TOKEN_TYPE.REGEX>
759
+ const quoteL = this.ruleRegexAny() as ValidToken<typeof TOKEN_TYPE.REGEX>
760
760
  // unlike other values, regexes will swallow all input if incorrect
761
761
  const maybeValue = this.peek(1)
762
762
  // note the inversion (todo inverse map)
@@ -774,7 +774,7 @@ export class Parser<T extends {} = {}> {
774
774
  return handle.variable(undefined, undefined, value, quoteR)
775
775
  }
776
776
  if (this.isType(next, $C.QUOTE_ANY)) {
777
- const quoteToken = next as Token<$T.QUOTE_BACKTICK | $T.QUOTE_DOUBLE | $T.QUOTE_SINGLE>
777
+ const quoteToken = next as Token<typeof $T.QUOTE_BACKTICK | typeof $T.QUOTE_DOUBLE | typeof $T.QUOTE_SINGLE>
778
778
  const quoteL = this.ruleValueDelimAny()
779
779
  const maybeValue = this.peek(1)
780
780
  const value = !quoteL && this.isType(maybeValue, $T.VALUE_UNQUOTED)
@@ -792,7 +792,7 @@ export class Parser<T extends {} = {}> {
792
792
  return undefined
793
793
  }
794
794
 
795
- ruleValueDelimAny(): ValidToken<TOKEN_TYPE.SINGLEQUOTE | TOKEN_TYPE.DOUBLEQUOTE | TOKEN_TYPE.BACKTICK | TOKEN_TYPE.REGEX> | undefined {
795
+ ruleValueDelimAny(): ValidToken<typeof TOKEN_TYPE.SINGLEQUOTE | typeof TOKEN_TYPE.DOUBLEQUOTE | typeof TOKEN_TYPE.BACKTICK | typeof TOKEN_TYPE.REGEX> | undefined {
796
796
  const next = this.peek(1)!
797
797
 
798
798
  if (this.isType(next, $C.QUOTE_ANY)) {
@@ -802,7 +802,7 @@ export class Parser<T extends {} = {}> {
802
802
  return undefined
803
803
  }
804
804
 
805
- ruleRegexAny(): ValidToken<TOKEN_TYPE.REGEX> | [ValidToken<TOKEN_TYPE.REGEX>, AnyToken<TOKEN_TYPE.VALUE>] {
805
+ ruleRegexAny(): ValidToken<typeof TOKEN_TYPE.REGEX> | [ValidToken<typeof TOKEN_TYPE.REGEX>, AnyToken<typeof TOKEN_TYPE.VALUE>] {
806
806
  const value = this.consume($C.REGEX_ANY)
807
807
  if (value.value.length > 1) {
808
808
  // cheat a bit to extract the flags
@@ -826,11 +826,11 @@ export class Parser<T extends {} = {}> {
826
826
  }
827
827
 
828
828
  ruleValueNot<
829
- TType extends $T.QUOTE_SINGLE | $T.QUOTE_DOUBLE | $T.QUOTE_BACKTICK | $C.REGEX_ANY,
829
+ TType extends typeof $T.QUOTE_SINGLE | typeof $T.QUOTE_DOUBLE | typeof $T.QUOTE_BACKTICK | typeof $C.REGEX_ANY,
830
830
  >(
831
831
  type: TType,
832
832
  ): ValidToken<
833
- TOKEN_TYPE.VALUE
833
+ typeof TOKEN_TYPE.VALUE
834
834
  > {
835
835
  const realType = {
836
836
  [$T.QUOTE_SINGLE]: $C.VALUE_FOR_SINGLE,
@@ -848,15 +848,15 @@ export class Parser<T extends {} = {}> {
848
848
  return handle.token.value(...this.processToken(value)) as any
849
849
  }
850
850
 
851
- ruleQuote<TType extends $T.QUOTE_SINGLE | $T.QUOTE_DOUBLE | $T.QUOTE_BACKTICK >(
851
+ ruleQuote<TType extends typeof $T.QUOTE_SINGLE | typeof $T.QUOTE_DOUBLE | typeof $T.QUOTE_BACKTICK >(
852
852
  type: TType,
853
853
  ): ValidToken<
854
- TType extends $T.QUOTE_SINGLE
855
- ? TOKEN_TYPE.SINGLEQUOTE
856
- : TType extends $T.QUOTE_DOUBLE
857
- ? TOKEN_TYPE.DOUBLEQUOTE
858
- : TType extends $T.QUOTE_BACKTICK
859
- ? TOKEN_TYPE.BACKTICK
854
+ TType extends typeof $T.QUOTE_SINGLE
855
+ ? typeof TOKEN_TYPE.SINGLEQUOTE
856
+ : TType extends typeof $T.QUOTE_DOUBLE
857
+ ? typeof TOKEN_TYPE.DOUBLEQUOTE
858
+ : TType extends typeof $T.QUOTE_BACKTICK
859
+ ? typeof TOKEN_TYPE.BACKTICK
860
860
  : never
861
861
  > {
862
862
  const quote = this.peek(1)
@@ -891,7 +891,7 @@ export class Parser<T extends {} = {}> {
891
891
  onlyToken?: TOnlyToken
892
892
  unprefixed?: boolean
893
893
  } = {},
894
- ): TOnlyToken extends true ? Token<$T.VALUE_UNQUOTED> | undefined : AnyToken<TOKEN_TYPE.VALUE> | undefined {
894
+ ): TOnlyToken extends true ? Token<typeof $T.VALUE_UNQUOTED> | undefined : AnyToken<typeof TOKEN_TYPE.VALUE> | undefined {
895
895
  const next = this.peek(1)
896
896
  const next2 = this.peek(2)
897
897
  const next4 = this.peek(4)
@@ -912,13 +912,13 @@ export class Parser<T extends {} = {}> {
912
912
  }: {
913
913
  onlyToken?: TOnlyToken
914
914
  } = {},
915
- ): TOnlyToken extends true ? Token<$T.VALUE_UNQUOTED> : AnyToken<TOKEN_TYPE.VALUE> {
915
+ ): TOnlyToken extends true ? Token<typeof $T.VALUE_UNQUOTED> : AnyToken<typeof TOKEN_TYPE.VALUE> {
916
916
  const t = this.consume($T.VALUE_UNQUOTED)
917
917
  const res = onlyToken ? t : handle.token.value(...this.processToken(t))
918
918
  return (res) as any
919
919
  }
920
920
 
921
- ruleParenL(): ValidToken<TOKEN_TYPE.PARENL> | undefined {
921
+ ruleParenL(): ValidToken<typeof TOKEN_TYPE.PARENL> | undefined {
922
922
  const next = this.peek(1)
923
923
  const value = next?.type === $T.PAREN_L
924
924
  ? this.consume($T.PAREN_L)
@@ -929,12 +929,12 @@ export class Parser<T extends {} = {}> {
929
929
  : undefined
930
930
  }
931
931
 
932
- ruleParenR(): ValidToken<TOKEN_TYPE.PARENR> | undefined {
932
+ ruleParenR(): ValidToken<typeof TOKEN_TYPE.PARENR> | undefined {
933
933
  const value = this.consume($T.PAREN_R)
934
934
  return handle.delimiter.parenR(...this.processToken(value))
935
935
  }
936
936
 
937
- ruleBracketL(): ValidToken<TOKEN_TYPE.BRACKETL> | undefined {
937
+ ruleBracketL(): ValidToken<typeof TOKEN_TYPE.BRACKETL> | undefined {
938
938
  const next = this.peek(1)
939
939
  const value = next?.type === $T.BRACKET_L
940
940
  ? this.consume($T.BRACKET_L)
@@ -945,12 +945,12 @@ export class Parser<T extends {} = {}> {
945
945
  : undefined
946
946
  }
947
947
 
948
- ruleBracketR(): ValidToken<TOKEN_TYPE.BRACKETR> | undefined {
948
+ ruleBracketR(): ValidToken<typeof TOKEN_TYPE.BRACKETR> | undefined {
949
949
  const value = this.consume($T.BRACKET_R)
950
950
  return handle.delimiter.bracketR(...this.processToken(value))
951
951
  }
952
952
 
953
- ruleNot(): ValidToken<TOKEN_TYPE.NOT> | undefined {
953
+ ruleNot(): ValidToken<typeof TOKEN_TYPE.NOT> | undefined {
954
954
  if (this.isType(this.peek(1), $C.OPERATOR_NOT)) {
955
955
  const op = this.consume($C.OPERATOR_NOT)
956
956
  return handle.operator.not(...this.processToken<true>(op))
@@ -1129,13 +1129,13 @@ export class Parser<T extends {} = {}> {
1129
1129
  const wordOps = [...opts.keywords.and, ...opts.keywords.or, ...opts.keywords.not].filter(op => !op.isSymbol)
1130
1130
 
1131
1131
  const canSuggestOpAfterPrev = (
1132
- token.valid.prev && tokenVariable.includes(token.valid.prev?.type) &&
1132
+ token.valid.prev && (tokenVariable as string[]).includes(token.valid.prev?.type) &&
1133
1133
  (token.whitespace.prev || token.valid.prev.type === TOKEN_TYPE.PARENR) &&
1134
1134
  !token.at && token.valid.next === undefined
1135
1135
  )
1136
1136
  const canSuggestOpBeforeNext =
1137
1137
  (
1138
- token.valid.next && tokenVariable.includes(token.valid.next?.type) &&
1138
+ token.valid.next && (tokenVariable as string[]).includes(token.valid.next?.type) &&
1139
1139
  token.whitespace.next && // no parenL allowed since check since there will already be prefix suggestions
1140
1140
  !token.at && token.valid.prev === undefined
1141
1141
  )
@@ -1169,7 +1169,7 @@ export class Parser<T extends {} = {}> {
1169
1169
  } else {
1170
1170
  const surroundingErrors = getSurroundingErrors(tokens, token)
1171
1171
 
1172
- const errorTypesHandled: TOKEN_TYPE[] = []
1172
+ const errorTypesHandled: TokenType[] = []
1173
1173
  const errorSuggestion = {
1174
1174
  isError: true,
1175
1175
  cursorInfo: token,
@@ -1192,7 +1192,7 @@ export class Parser<T extends {} = {}> {
1192
1192
  const isRight = (errorParent as VariableNode).quote!.right === error
1193
1193
  suggestions.push({
1194
1194
  ...errorSuggestion,
1195
- type: type as any as SUGGESTION_TYPE,
1195
+ type: type as any as SuggestionType,
1196
1196
  requires: createDefaultRequires({
1197
1197
  whitespace: {
1198
1198
  before: isRight ? false : requiresWhitespacePrev,
@@ -1229,7 +1229,7 @@ export class Parser<T extends {} = {}> {
1229
1229
  case TOKEN_TYPE.PARENR:
1230
1230
  suggestions.push({
1231
1231
  ...errorSuggestion,
1232
- type: type as any as SUGGESTION_TYPE,
1232
+ type: type as any as SuggestionType,
1233
1233
  requires: createDefaultRequires(),
1234
1234
  range: pos({ start: index }, { fill: true }),
1235
1235
  })
@@ -1803,6 +1803,7 @@ export class Parser<T extends {} = {}> {
1803
1803
  if (prefix !== undefined && !isNested) {
1804
1804
  name = name ? applyPrefix(prefix, name, opts.prefixApplier) : prefix
1805
1805
  }
1806
+
1806
1807
  let value: any
1807
1808
  if (isNested) {
1808
1809
  value = name ?? true
@@ -1855,16 +1856,21 @@ export class Parser<T extends {} = {}> {
1855
1856
  return self_.normalize(ast.value, name, boolValue, operator) as any
1856
1857
  }
1857
1858
  }
1858
-
1859
1859
  if (ast.type === AST_TYPE.GROUP) {
1860
1860
  const _prefix = ast.prefix?.type === AST_TYPE.CONDITION && ast.prefix?.value.type === AST_TYPE.VARIABLE
1861
1861
  ? unescape(ast.prefix.value.value.value!)
1862
1862
  : undefined // we do not want to apply not tokens
1863
+ const isNotToken = _prefix === undefined
1864
+
1863
1865
  const _groupValue = ast.prefix?.type === AST_TYPE.CONDITION
1864
1866
  ? ast.prefix.operator === undefined
1865
1867
  : !(ast.prefix?.valid === true)
1866
1868
 
1867
- const applied = applyPrefix(prefix, _prefix ?? "", opts.prefixApplier)
1869
+ // do not attempt to apply prefix if it's undefined (a not token)
1870
+ // otherwise we would get weird calls to applyPrefix
1871
+ const applied = isNotToken
1872
+ ? prefix
1873
+ : applyPrefix(prefix, _prefix, opts.prefixApplier)
1868
1874
 
1869
1875
  return self_.normalize(ast.expression as any, applied, applyBoolean(groupValue, _groupValue), operator) as any
1870
1876
  }
@@ -1874,7 +1880,7 @@ export class Parser<T extends {} = {}> {
1874
1880
 
1875
1881
  // apply De Morgan's laws if group prefix was negative
1876
1882
  // the values are already flipped, we just have to flip the operator
1877
- const type: TokenBooleanTypes = (groupValue === false ? OPPOSITE[ast.operator!.type!] : ast.operator.type) as TokenBooleanTypes
1883
+ const type: TokenBoolean = (groupValue === false ? OPPOSITE[ast.operator!.type!] : ast.operator.type)!
1878
1884
  return createExpression<TType, TValue>({ operator: type, left: left as any, right: right as any })
1879
1885
  }
1880
1886
  return unreachable()
@@ -1904,7 +1910,7 @@ export class Parser<T extends {} = {}> {
1904
1910
  // eslint-disable-next-line prefer-rest-params
1905
1911
  const prefixes: VariableNode[] = arguments[5] ?? []
1906
1912
  // eslint-disable-next-line prefer-rest-params
1907
- let operator: ValidToken<TOKEN_TYPE.VALUE | TOKEN_TYPE.OP_CUSTOM> | undefined = arguments[6]
1913
+ let operator: ValidToken<typeof TOKEN_TYPE.VALUE | typeof TOKEN_TYPE.OP_CUSTOM> | undefined = arguments[6]
1908
1914
 
1909
1915
  const self_ = this as any as Parser & { validate: AddParameters<Parser["validate"], [typeof prefix, typeof groupValue, typeof results, typeof prefixes, typeof operator]> }
1910
1916
 
@@ -1946,7 +1952,7 @@ export class Parser<T extends {} = {}> {
1946
1952
  const valuePrefix = ast.value.type === AST_TYPE.VARIABLE && ast.value.prefix
1947
1953
  ? ast.value.prefix
1948
1954
  : undefined
1949
- operator ??= ast.propertyOperator as ValidToken<TOKEN_TYPE.VALUE | TOKEN_TYPE.OP_CUSTOM>
1955
+ operator ??= ast.propertyOperator as ValidToken<typeof TOKEN_TYPE.VALUE | typeof TOKEN_TYPE.OP_CUSTOM>
1950
1956
  const isRegex = (ast.value as VariableNode)?.quote?.left.type === TOKEN_TYPE.REGEX
1951
1957
  const isQuoted = (ast.value as VariableNode)?.quote !== undefined
1952
1958
  const isExpanded = ast.sep !== undefined
@@ -1979,7 +1985,7 @@ export class Parser<T extends {} = {}> {
1979
1985
 
1980
1986
  if (ast.property) prefixes.push((ast.property as any))
1981
1987
  // eslint-disable-next-line @typescript-eslint/no-shadow
1982
- const operator = ast.propertyOperator as ValidToken<TOKEN_TYPE.VALUE | TOKEN_TYPE.OP_CUSTOM>
1988
+ const operator = ast.propertyOperator as ValidToken<typeof TOKEN_TYPE.VALUE | typeof TOKEN_TYPE.OP_CUSTOM>
1983
1989
  self_.validate(ast.value, context, name, boolValue, results, prefixes, operator)
1984
1990
  }
1985
1991
  }
@@ -21,10 +21,10 @@ export function condition(
21
21
  | GroupNode
22
22
  | ArrayNode
23
23
  | ErrorToken,
24
- not: true | ValidToken<TOKEN_TYPE.NOT> = true,
24
+ not: true | ValidToken<typeof TOKEN_TYPE.NOT> = true,
25
25
  property?: VariableNode | ErrorToken,
26
- propertyOperator?: AnyToken<TOKEN_TYPE.OP_CUSTOM | TOKEN_TYPE.VALUE>,
27
- { right, left }: Partial<Record<"right" | "left", ValidToken<TOKEN_TYPE.OP_EXPANDED_SEP>>> = { },
26
+ propertyOperator?: AnyToken<typeof TOKEN_TYPE.OP_CUSTOM | typeof TOKEN_TYPE.VALUE>,
27
+ { right, left }: Partial<Record<"right" | "left", ValidToken<typeof TOKEN_TYPE.OP_EXPANDED_SEP>>> = { },
28
28
  ): ConditionNode {
29
29
  const position = pos(value satisfies Position)
30
30
  const notStart = not === true ? undefined : not.start
@@ -1,6 +1,6 @@
1
1
  import { type } from "./type.js"
2
2
 
3
- import { type ExtractTokenType, TOKEN_TYPE } from "../../types/ast.js"
3
+ import { type ExtractToken, TOKEN_TYPE } from "../../types/ast.js"
4
4
 
5
5
  /**
6
6
  * Faster way, more intuitive way to generate the options for matching delimiters (e.g. quotes and parens) for functions like {@link variable} and {@link group} .
@@ -10,9 +10,9 @@ export function delim<
10
10
  TLeft extends boolean | string,
11
11
  TRight extends boolean | string,
12
12
  TType extends TLeft extends string
13
- ? ExtractTokenType<TLeft>
13
+ ? ExtractToken<TLeft>
14
14
  : TRight extends string
15
- ? ExtractTokenType<TRight>
15
+ ? ExtractToken<TRight>
16
16
  : undefined,
17
17
  >(
18
18
  left: TLeft = false as TLeft,
@@ -21,7 +21,7 @@ export function delim<
21
21
  {
22
22
  left: TLeft extends string ? true : TLeft
23
23
  right: TRight extends string ? true : TRight
24
- } & TType extends undefined ? {} : { type: TType } {
24
+ } & TType extends undefined ? Record<string,never> : { type: TType } {
25
25
  let quoteType
26
26
  if (typeof left === "string") quoteType = type(left)
27
27
  else if (typeof right === "string") quoteType = type(right)
@@ -31,7 +31,7 @@ export function delim<
31
31
  right: right === true || (typeof right === "string" && right !== undefined),
32
32
  }
33
33
  if (quoteType !== undefined &&
34
- ![TOKEN_TYPE.PARENL, TOKEN_TYPE.PARENR].includes(quoteType)
34
+ !([TOKEN_TYPE.PARENL, TOKEN_TYPE.PARENR] as string[]).includes(quoteType)
35
35
  ) {
36
36
  opts.type = quoteType
37
37
  }
@@ -1,6 +1,6 @@
1
1
  import { type } from "./type.js"
2
2
 
3
- import { type ErrorToken,TOKEN_TYPE } from "../../types/ast.js"
3
+ import { type ErrorToken,TOKEN_TYPE, type TokenType } from "../../types/ast.js"
4
4
  import { createToken } from "../createToken.js"
5
5
 
6
6
 
@@ -9,8 +9,8 @@ import { createToken } from "../createToken.js"
9
9
  *
10
10
  * @param expected Can be passed an array of {@link ValidToken_TYPE} or strings, in which case it will use {@link type} internally. So instead of `[TOKEN_TYPE.VALUE]` we can do `[""]` and instead of `[TOKEN_TYPE.PARENR]` we can do `[")"]`.
11
11
  */
12
- export function error<T extends TOKEN_TYPE>(pos: number, expected: T[]): ErrorToken
13
- export function error<T extends TOKEN_TYPE>(pos: number, expected_: T[]): ErrorToken {
12
+ export function error<T extends TokenType>(pos: number, expected: T[]): ErrorToken
13
+ export function error<T extends TokenType>(pos: number, expected_: T[]): ErrorToken {
14
14
  const expected = expected_.map(item => {
15
15
  if (TOKEN_TYPE[item as keyof typeof TOKEN_TYPE] === undefined) {
16
16
  return type(item)
@@ -1,7 +1,7 @@
1
1
  import { pos } from "./pos.js"
2
2
  import { token } from "./token.js"
3
3
 
4
- import { type AnyToken, type ConditionNode, type ErrorToken, type ExpressionNode,type GroupNode, type Position, TOKEN_TYPE, type TokenBooleanTypes } from "../../types/ast.js"
4
+ import { type AnyToken, type ConditionNode, type ErrorToken, type ExpressionNode,type GroupNode, type Position, TOKEN_TYPE, type TokenBoolean } from "../../types/ast.js"
5
5
  import { createExpressionNode } from "../createExpressionNode.js"
6
6
 
7
7
 
@@ -18,7 +18,7 @@ export function expression(
18
18
  ErrorToken |
19
19
  undefined,
20
20
  operator:
21
- AnyToken<TokenBooleanTypes> |
21
+ AnyToken<TokenBoolean> |
22
22
  undefined,
23
23
  right:
24
24
  ConditionNode |
@@ -39,17 +39,13 @@ export function expression(
39
39
 
40
40
  const position = pos({ start, end } as Position)
41
41
 
42
- if (left === undefined) {
43
- left = token(TOKEN_TYPE.VALUE, undefined, { start: position.start })
44
- }
42
+ left ??= token(TOKEN_TYPE.VALUE, undefined, { start: position.start })
45
43
  let op!: ExpressionNode["operator"]
46
44
  if (operator === undefined) {
47
45
  operator = token([TOKEN_TYPE.AND, TOKEN_TYPE.OR], undefined, { start: left.end })
48
46
  } else op = operator
49
47
 
50
- if (right === undefined) {
51
- right = token(TOKEN_TYPE.VALUE, undefined, { start: op.end })
52
- }
48
+ right ??= token(TOKEN_TYPE.VALUE, undefined, { start: op.end })
53
49
 
54
50
  return createExpressionNode({
55
51
  left,
@@ -16,7 +16,7 @@ import { createGroupNode } from "../createGroupNode.js"
16
16
  export function group(
17
17
  prefix:
18
18
  | ConditionNode
19
- | ValidToken<TOKEN_TYPE.NOT>
19
+ | ValidToken<typeof TOKEN_TYPE.NOT>
20
20
  | undefined,
21
21
 
22
22
  expression:
@@ -30,9 +30,7 @@ export function group(
30
30
  parenLeftPos?: Position,
31
31
  parenRightPos?: Position,
32
32
  ): GroupNode {
33
- if (expression === undefined) {
34
- expression = token(TOKEN_TYPE.VALUE, undefined, prefix?.end !== undefined ? { start: prefix.end } : undefined)
35
- }
33
+ expression ??= token(TOKEN_TYPE.VALUE, undefined, prefix?.end !== undefined ? { start: prefix.end } : undefined)
36
34
 
37
35
  const node: Partial<FirstParam<typeof createGroupNode>> = {
38
36
  prefix: undefined,
@@ -1,6 +1,6 @@
1
1
  import { isFullPos } from "./isFullPos.js"
2
2
 
3
- import type { AnyToken, AST_TYPE, EmptyObj, Node, Position, TOKEN_TYPE } from "../../types/ast.js"
3
+ import type { AnyToken, AstType, EmptyObj, Node, Position, TokenType } from "../../types/ast.js"
4
4
 
5
5
  /**
6
6
  * Can either:
@@ -22,9 +22,9 @@ export function pos<TItem extends Position | Partial<Position> | EmptyObj>(
22
22
  // not sure why this needs the AnyToken check
23
23
  TItem extends Position
24
24
  ? Position
25
- : TItem extends AnyToken<TOKEN_TYPE> | Position | EmptyObj
25
+ : TItem extends AnyToken<TokenType> | Position | EmptyObj
26
26
  ? Position | EmptyObj
27
- : TItem extends Node<AST_TYPE> | Position | EmptyObj
27
+ : TItem extends Node<AstType> | Position | EmptyObj
28
28
  ? Position | EmptyObj
29
29
  : EmptyObj
30
30
  export function pos(start: number, end: number): Position
@@ -2,7 +2,7 @@ import { isArray } from "@alanscodelog/utils/isArray.js"
2
2
 
3
3
  import { pos } from "./pos.js"
4
4
 
5
- import type { AnyToken, EmptyObj, ErrorToken, Position, TOKEN_TYPE, ValidToken } from "../../types/ast.js"
5
+ import type { AnyToken, EmptyObj, ErrorToken, Position, TokenType, ValidToken } from "../../types/ast.js"
6
6
  import { createToken } from "../createToken.js"
7
7
 
8
8
 
@@ -16,7 +16,7 @@ import { createToken } from "../createToken.js"
16
16
 
17
17
  export function token<
18
18
  TValue extends string | undefined,
19
- TType extends TOKEN_TYPE = TOKEN_TYPE,
19
+ TType extends TokenType = TokenType,
20
20
  >(
21
21
  type: TValue extends undefined ? TType | TType[] : TType,
22
22
  value: TValue,
@@ -1,10 +1,10 @@
1
- import { type ExtractTokenType, TOKEN_TYPE } from "../../types/ast.js"
1
+ import { type ExtractToken, TOKEN_TYPE } from "../../types/ast.js"
2
2
  /**
3
3
  * Given a the string value of an operator or single delimiter token, returns the corresponding {@link ValidToken_TYPE} .
4
4
  */
5
5
  export function type<T extends string>(
6
6
  operatorSymbol: T,
7
- ): ExtractTokenType<T> {
7
+ ): ExtractToken<T> {
8
8
  switch (operatorSymbol) {
9
9
  case "`": return TOKEN_TYPE.BACKTICK as any
10
10
  case `'`: return TOKEN_TYPE.SINGLEQUOTE as any
@@ -1,7 +1,7 @@
1
1
  import { pos } from "./pos.js"
2
2
  import { token } from "./token.js"
3
3
 
4
- import { type AnyToken, type EmptyObj,type FirstParam, type Position, TOKEN_TYPE, type TokenQuoteTypes, type ValidToken, type VariableNode } from "../../types/ast.js"
4
+ import { type AnyToken, type EmptyObj,type FirstParam, type Position, TOKEN_TYPE, type TokenQuote, type ValidToken, type VariableNode } from "../../types/ast.js"
5
5
  import { createVariableNode } from "../createVariableNode.js"
6
6
 
7
7
 
@@ -14,9 +14,9 @@ import { createVariableNode } from "../createVariableNode.js"
14
14
  */
15
15
 
16
16
  export function variable(
17
- prefix: ValidToken<TOKEN_TYPE.VALUE> | undefined,
18
- value: string | AnyToken<TOKEN_TYPE.VALUE>,
19
- quote?: { type: TokenQuoteTypes, left?: boolean, right?: boolean, flags?: string },
17
+ prefix: ValidToken<typeof TOKEN_TYPE.VALUE> | undefined,
18
+ value: string | AnyToken<typeof TOKEN_TYPE.VALUE>,
19
+ quote?: { type: TokenQuote, left?: boolean, right?: boolean, flags?: string },
20
20
  position?: Position | EmptyObj,
21
21
  ): VariableNode {
22
22
  if (typeof value === "string") {
@@ -76,7 +76,7 @@ export function variable(
76
76
  return createVariableNode(node as any)
77
77
  }
78
78
 
79
- function quoteFromType(type: TokenQuoteTypes | undefined): string {
79
+ function quoteFromType(type: TokenQuote | undefined): string {
80
80
  switch (type) {
81
81
  case TOKEN_TYPE.BACKTICK: return "`"
82
82
  case TOKEN_TYPE.DOUBLEQUOTE: return "\""
@@ -5,8 +5,8 @@ import { isNode } from "../utils/isNode.js"
5
5
  export function createConditionNode<
6
6
  TValid extends boolean = boolean,
7
7
  TOperator extends
8
- ValidToken<TOKEN_TYPE.NOT> | undefined =
9
- ValidToken<TOKEN_TYPE.NOT> | undefined,
8
+ ValidToken<typeof TOKEN_TYPE.NOT> | undefined =
9
+ ValidToken<typeof TOKEN_TYPE.NOT> | undefined,
10
10
  >(raw: {
11
11
  operator?: TOperator
12
12
  property?: ConditionNode<TValid>["property"]