@witchcraft/expressit 0.0.2

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 (307) hide show
  1. package/README.md +86 -0
  2. package/dist/ast/builders/array.d.ts +8 -0
  3. package/dist/ast/builders/array.d.ts.map +1 -0
  4. package/dist/ast/builders/array.js +31 -0
  5. package/dist/ast/builders/condition.d.ts +20 -0
  6. package/dist/ast/builders/condition.d.ts.map +1 -0
  7. package/dist/ast/builders/condition.js +28 -0
  8. package/dist/ast/builders/delim.d.ts +11 -0
  9. package/dist/ast/builders/delim.d.ts.map +1 -0
  10. package/dist/ast/builders/delim.js +20 -0
  11. package/dist/ast/builders/error.d.ts +9 -0
  12. package/dist/ast/builders/error.d.ts.map +1 -0
  13. package/dist/ast/builders/error.js +16 -0
  14. package/dist/ast/builders/expression.d.ts +12 -0
  15. package/dist/ast/builders/expression.d.ts.map +1 -0
  16. package/dist/ast/builders/expression.js +31 -0
  17. package/dist/ast/builders/group.d.ts +20 -0
  18. package/dist/ast/builders/group.d.ts.map +1 -0
  19. package/dist/ast/builders/group.js +47 -0
  20. package/dist/ast/builders/index.d.ts +12 -0
  21. package/dist/ast/builders/index.d.ts.map +1 -0
  22. package/dist/ast/builders/index.js +24 -0
  23. package/dist/ast/builders/isFullPos.d.ts +6 -0
  24. package/dist/ast/builders/isFullPos.d.ts.map +1 -0
  25. package/dist/ast/builders/isFullPos.js +6 -0
  26. package/dist/ast/builders/pos.d.ts +21 -0
  27. package/dist/ast/builders/pos.d.ts.map +1 -0
  28. package/dist/ast/builders/pos.js +28 -0
  29. package/dist/ast/builders/token.d.ts +12 -0
  30. package/dist/ast/builders/token.d.ts.map +1 -0
  31. package/dist/ast/builders/token.js +26 -0
  32. package/dist/ast/builders/type.d.ts +6 -0
  33. package/dist/ast/builders/type.d.ts.map +1 -0
  34. package/dist/ast/builders/type.js +37 -0
  35. package/dist/ast/builders/variable.d.ts +17 -0
  36. package/dist/ast/builders/variable.d.ts.map +1 -0
  37. package/dist/ast/builders/variable.js +62 -0
  38. package/dist/ast/classes/ArrayNode.d.ts +18 -0
  39. package/dist/ast/classes/ArrayNode.d.ts.map +1 -0
  40. package/dist/ast/classes/ArrayNode.js +55 -0
  41. package/dist/ast/classes/Condition.d.ts +13 -0
  42. package/dist/ast/classes/Condition.d.ts.map +1 -0
  43. package/dist/ast/classes/Condition.js +21 -0
  44. package/dist/ast/classes/ConditionNode.d.ts +73 -0
  45. package/dist/ast/classes/ConditionNode.d.ts.map +1 -0
  46. package/dist/ast/classes/ConditionNode.js +101 -0
  47. package/dist/ast/classes/ErrorToken.d.ts +27 -0
  48. package/dist/ast/classes/ErrorToken.d.ts.map +1 -0
  49. package/dist/ast/classes/ErrorToken.js +47 -0
  50. package/dist/ast/classes/Expression.d.ts +13 -0
  51. package/dist/ast/classes/Expression.d.ts.map +1 -0
  52. package/dist/ast/classes/Expression.js +19 -0
  53. package/dist/ast/classes/ExpressionNode.d.ts +21 -0
  54. package/dist/ast/classes/ExpressionNode.d.ts.map +1 -0
  55. package/dist/ast/classes/ExpressionNode.js +57 -0
  56. package/dist/ast/classes/GroupNode.d.ts +64 -0
  57. package/dist/ast/classes/GroupNode.d.ts.map +1 -0
  58. package/dist/ast/classes/GroupNode.js +69 -0
  59. package/dist/ast/classes/Node.d.ts +22 -0
  60. package/dist/ast/classes/Node.d.ts.map +1 -0
  61. package/dist/ast/classes/Node.js +28 -0
  62. package/dist/ast/classes/Token.d.ts +27 -0
  63. package/dist/ast/classes/Token.d.ts.map +1 -0
  64. package/dist/ast/classes/Token.js +28 -0
  65. package/dist/ast/classes/ValidToken.d.ts +26 -0
  66. package/dist/ast/classes/ValidToken.d.ts.map +1 -0
  67. package/dist/ast/classes/ValidToken.js +49 -0
  68. package/dist/ast/classes/VariableNode.d.ts +33 -0
  69. package/dist/ast/classes/VariableNode.d.ts.map +1 -0
  70. package/dist/ast/classes/VariableNode.js +58 -0
  71. package/dist/ast/classes/index.d.ts +12 -0
  72. package/dist/ast/classes/index.d.ts.map +1 -0
  73. package/dist/ast/classes/index.js +24 -0
  74. package/dist/ast/handlers.d.ts +42 -0
  75. package/dist/ast/handlers.d.ts.map +1 -0
  76. package/dist/ast/handlers.js +150 -0
  77. package/dist/ast/index.d.ts +4 -0
  78. package/dist/ast/index.d.ts.map +1 -0
  79. package/dist/ast/index.js +8 -0
  80. package/dist/examples/advancedValueComparer.d.ts +3 -0
  81. package/dist/examples/advancedValueComparer.d.ts.map +1 -0
  82. package/dist/examples/advancedValueComparer.js +28 -0
  83. package/dist/examples/shortcutContextParser.d.ts +22 -0
  84. package/dist/examples/shortcutContextParser.d.ts.map +1 -0
  85. package/dist/examples/shortcutContextParser.js +126 -0
  86. package/dist/global.d.js +1 -0
  87. package/dist/grammar/ParserBase.d.ts +51 -0
  88. package/dist/grammar/ParserBase.d.ts.map +1 -0
  89. package/dist/grammar/ParserBase.js +516 -0
  90. package/dist/grammar/createTokens.d.ts +56 -0
  91. package/dist/grammar/createTokens.d.ts.map +1 -0
  92. package/dist/grammar/createTokens.js +843 -0
  93. package/dist/grammar/index.d.ts +3 -0
  94. package/dist/grammar/index.d.ts.map +1 -0
  95. package/dist/grammar/index.js +6 -0
  96. package/dist/helpers/errors.d.ts +9 -0
  97. package/dist/helpers/errors.d.ts.map +1 -0
  98. package/dist/helpers/errors.js +41 -0
  99. package/dist/helpers/general/applyBoolean.d.ts +3 -0
  100. package/dist/helpers/general/applyBoolean.d.ts.map +1 -0
  101. package/dist/helpers/general/applyBoolean.js +17 -0
  102. package/dist/helpers/general/applyPrefix.d.ts +4 -0
  103. package/dist/helpers/general/applyPrefix.d.ts.map +1 -0
  104. package/dist/helpers/general/applyPrefix.js +9 -0
  105. package/dist/helpers/general/defaultConditionNormalizer.d.ts +3 -0
  106. package/dist/helpers/general/defaultConditionNormalizer.d.ts.map +1 -0
  107. package/dist/helpers/general/defaultConditionNormalizer.js +6 -0
  108. package/dist/helpers/general/defaultKeyParser.d.ts +3 -0
  109. package/dist/helpers/general/defaultKeyParser.d.ts.map +1 -0
  110. package/dist/helpers/general/defaultKeyParser.js +8 -0
  111. package/dist/helpers/general/defaultPrefixApplier.d.ts +3 -0
  112. package/dist/helpers/general/defaultPrefixApplier.d.ts.map +1 -0
  113. package/dist/helpers/general/defaultPrefixApplier.js +6 -0
  114. package/dist/helpers/general/defaultValueComparer.d.ts +3 -0
  115. package/dist/helpers/general/defaultValueComparer.d.ts.map +1 -0
  116. package/dist/helpers/general/defaultValueComparer.js +6 -0
  117. package/dist/helpers/general/index.d.ts +7 -0
  118. package/dist/helpers/general/index.d.ts.map +1 -0
  119. package/dist/helpers/general/index.js +14 -0
  120. package/dist/helpers/index.d.ts +4 -0
  121. package/dist/helpers/index.d.ts.map +1 -0
  122. package/dist/helpers/index.js +8 -0
  123. package/dist/helpers/parser/assignParents.d.ts +4 -0
  124. package/dist/helpers/parser/assignParents.d.ts.map +1 -0
  125. package/dist/helpers/parser/assignParents.js +71 -0
  126. package/dist/helpers/parser/checkParserOpts.d.ts +3 -0
  127. package/dist/helpers/parser/checkParserOpts.d.ts.map +1 -0
  128. package/dist/helpers/parser/checkParserOpts.js +126 -0
  129. package/dist/helpers/parser/extractPosition.d.ts +9 -0
  130. package/dist/helpers/parser/extractPosition.d.ts.map +1 -0
  131. package/dist/helpers/parser/extractPosition.js +9 -0
  132. package/dist/helpers/parser/getUnclosedRightParenCount.d.ts +5 -0
  133. package/dist/helpers/parser/getUnclosedRightParenCount.d.ts.map +1 -0
  134. package/dist/helpers/parser/getUnclosedRightParenCount.js +20 -0
  135. package/dist/helpers/parser/index.d.ts +9 -0
  136. package/dist/helpers/parser/index.d.ts.map +1 -0
  137. package/dist/helpers/parser/index.js +18 -0
  138. package/dist/helpers/parser/parseParserOptions.d.ts +4 -0
  139. package/dist/helpers/parser/parseParserOptions.d.ts.map +1 -0
  140. package/dist/helpers/parser/parseParserOptions.js +45 -0
  141. package/dist/helpers/parser/seal.d.ts +8 -0
  142. package/dist/helpers/parser/seal.d.ts.map +1 -0
  143. package/dist/helpers/parser/seal.js +10 -0
  144. package/dist/helpers/parser/setParent.d.ts +6 -0
  145. package/dist/helpers/parser/setParent.d.ts.map +1 -0
  146. package/dist/helpers/parser/setParent.js +4 -0
  147. package/dist/helpers/parser/unescape.d.ts +3 -0
  148. package/dist/helpers/parser/unescape.d.ts.map +1 -0
  149. package/dist/helpers/parser/unescape.js +6 -0
  150. package/dist/index.d.ts +6 -0
  151. package/dist/index.d.ts.map +1 -0
  152. package/dist/index.js +17 -0
  153. package/dist/methods/autocomplete.d.ts +18 -0
  154. package/dist/methods/autocomplete.d.ts.map +1 -0
  155. package/dist/methods/autocomplete.js +109 -0
  156. package/dist/methods/autoreplace.d.ts +13 -0
  157. package/dist/methods/autoreplace.d.ts.map +1 -0
  158. package/dist/methods/autoreplace.js +36 -0
  159. package/dist/methods/autosuggest.d.ts +28 -0
  160. package/dist/methods/autosuggest.d.ts.map +1 -0
  161. package/dist/methods/autosuggest.js +371 -0
  162. package/dist/methods/evaluate.d.ts +11 -0
  163. package/dist/methods/evaluate.d.ts.map +1 -0
  164. package/dist/methods/evaluate.js +30 -0
  165. package/dist/methods/getBestIndex.d.ts +19 -0
  166. package/dist/methods/getBestIndex.d.ts.map +1 -0
  167. package/dist/methods/getBestIndex.js +53 -0
  168. package/dist/methods/getIndexes.d.ts +17 -0
  169. package/dist/methods/getIndexes.d.ts.map +1 -0
  170. package/dist/methods/getIndexes.js +97 -0
  171. package/dist/methods/index.d.ts +9 -0
  172. package/dist/methods/index.d.ts.map +1 -0
  173. package/dist/methods/index.js +18 -0
  174. package/dist/methods/normalize.d.ts +12 -0
  175. package/dist/methods/normalize.d.ts.map +1 -0
  176. package/dist/methods/normalize.js +99 -0
  177. package/dist/methods/validate.d.ts +11 -0
  178. package/dist/methods/validate.d.ts.map +1 -0
  179. package/dist/methods/validate.js +111 -0
  180. package/dist/package.js +7 -0
  181. package/dist/package.json.js +193 -0
  182. package/dist/parser.d.ts +58 -0
  183. package/dist/parser.d.ts.map +1 -0
  184. package/dist/parser.js +136 -0
  185. package/dist/types/ast.d.ts +70 -0
  186. package/dist/types/ast.d.ts.map +1 -0
  187. package/dist/types/ast.js +29 -0
  188. package/dist/types/autocomplete.d.ts +143 -0
  189. package/dist/types/autocomplete.d.ts.map +1 -0
  190. package/dist/types/autocomplete.js +24 -0
  191. package/dist/types/errors.d.ts +34 -0
  192. package/dist/types/errors.d.ts.map +1 -0
  193. package/dist/types/errors.js +10 -0
  194. package/dist/types/index.d.ts +5 -0
  195. package/dist/types/index.d.ts.map +1 -0
  196. package/dist/types/index.js +9 -0
  197. package/dist/types/parser.d.ts +451 -0
  198. package/dist/types/parser.d.ts.map +1 -0
  199. package/dist/types/parser.js +1 -0
  200. package/dist/utils/extractTokens.d.ts +8 -0
  201. package/dist/utils/extractTokens.d.ts.map +1 -0
  202. package/dist/utils/extractTokens.js +50 -0
  203. package/dist/utils/getCursorInfo.d.ts +7 -0
  204. package/dist/utils/getCursorInfo.d.ts.map +1 -0
  205. package/dist/utils/getCursorInfo.js +86 -0
  206. package/dist/utils/getOppositeDelimiter.d.ts +6 -0
  207. package/dist/utils/getOppositeDelimiter.d.ts.map +1 -0
  208. package/dist/utils/getOppositeDelimiter.js +35 -0
  209. package/dist/utils/getSurroundingErrors.d.ts +25 -0
  210. package/dist/utils/getSurroundingErrors.d.ts.map +1 -0
  211. package/dist/utils/getSurroundingErrors.js +37 -0
  212. package/dist/utils/index.d.ts +10 -0
  213. package/dist/utils/index.d.ts.map +1 -0
  214. package/dist/utils/index.js +20 -0
  215. package/dist/utils/isBracket.d.ts +3 -0
  216. package/dist/utils/isBracket.d.ts.map +1 -0
  217. package/dist/utils/isBracket.js +7 -0
  218. package/dist/utils/isDelimiter.d.ts +6 -0
  219. package/dist/utils/isDelimiter.d.ts.map +1 -0
  220. package/dist/utils/isDelimiter.js +17 -0
  221. package/dist/utils/isParen.d.ts +3 -0
  222. package/dist/utils/isParen.d.ts.map +1 -0
  223. package/dist/utils/isParen.js +7 -0
  224. package/dist/utils/isQuote.d.ts +4 -0
  225. package/dist/utils/isQuote.d.ts.map +1 -0
  226. package/dist/utils/isQuote.js +7 -0
  227. package/dist/utils/prettyAst.d.ts +35 -0
  228. package/dist/utils/prettyAst.d.ts.map +1 -0
  229. package/dist/utils/prettyAst.js +112 -0
  230. package/package.json +152 -0
  231. package/src/ast/builders/array.ts +45 -0
  232. package/src/ast/builders/condition.ts +56 -0
  233. package/src/ast/builders/delim.ts +39 -0
  234. package/src/ast/builders/error.ts +22 -0
  235. package/src/ast/builders/expression.ts +66 -0
  236. package/src/ast/builders/group.ts +79 -0
  237. package/src/ast/builders/index.ts +13 -0
  238. package/src/ast/builders/isFullPos.ts +10 -0
  239. package/src/ast/builders/pos.ts +57 -0
  240. package/src/ast/builders/token.ts +46 -0
  241. package/src/ast/builders/type.ts +32 -0
  242. package/src/ast/builders/variable.ts +89 -0
  243. package/src/ast/classes/ArrayNode.ts +46 -0
  244. package/src/ast/classes/Condition.ts +22 -0
  245. package/src/ast/classes/ConditionNode.ts +141 -0
  246. package/src/ast/classes/ErrorToken.ts +49 -0
  247. package/src/ast/classes/Expression.ts +26 -0
  248. package/src/ast/classes/ExpressionNode.ts +62 -0
  249. package/src/ast/classes/GroupNode.ts +127 -0
  250. package/src/ast/classes/Node.ts +47 -0
  251. package/src/ast/classes/Token.ts +59 -0
  252. package/src/ast/classes/ValidToken.ts +56 -0
  253. package/src/ast/classes/VariableNode.ts +67 -0
  254. package/src/ast/classes/index.ts +13 -0
  255. package/src/ast/handlers.ts +190 -0
  256. package/src/ast/index.ts +5 -0
  257. package/src/examples/advancedValueComparer.ts +31 -0
  258. package/src/examples/shortcutContextParser.ts +140 -0
  259. package/src/global.d.ts +4 -0
  260. package/src/grammar/ParserBase.ts +715 -0
  261. package/src/grammar/createTokens.ts +512 -0
  262. package/src/grammar/index.ts +4 -0
  263. package/src/helpers/errors.ts +45 -0
  264. package/src/helpers/general/applyBoolean.ts +9 -0
  265. package/src/helpers/general/applyPrefix.ts +7 -0
  266. package/src/helpers/general/defaultConditionNormalizer.ts +9 -0
  267. package/src/helpers/general/defaultKeyParser.ts +8 -0
  268. package/src/helpers/general/defaultPrefixApplier.ts +7 -0
  269. package/src/helpers/general/defaultValueComparer.ts +7 -0
  270. package/src/helpers/general/index.ts +8 -0
  271. package/src/helpers/index.ts +5 -0
  272. package/src/helpers/parser/assignParents.ts +51 -0
  273. package/src/helpers/parser/checkParserOpts.ts +143 -0
  274. package/src/helpers/parser/extractPosition.ts +15 -0
  275. package/src/helpers/parser/getUnclosedRightParenCount.ts +22 -0
  276. package/src/helpers/parser/index.ts +10 -0
  277. package/src/helpers/parser/parseParserOptions.ts +54 -0
  278. package/src/helpers/parser/seal.ts +14 -0
  279. package/src/helpers/parser/setParent.ts +5 -0
  280. package/src/helpers/parser/unescape.ts +4 -0
  281. package/src/index.ts +7 -0
  282. package/src/methods/autocomplete.ts +128 -0
  283. package/src/methods/autoreplace.ts +46 -0
  284. package/src/methods/autosuggest.ts +543 -0
  285. package/src/methods/evaluate.ts +37 -0
  286. package/src/methods/getBestIndex.ts +53 -0
  287. package/src/methods/getIndexes.ts +99 -0
  288. package/src/methods/index.ts +10 -0
  289. package/src/methods/normalize.ts +138 -0
  290. package/src/methods/validate.ts +141 -0
  291. package/src/package.js +11 -0
  292. package/src/parser.ts +183 -0
  293. package/src/types/ast.ts +148 -0
  294. package/src/types/autocomplete.ts +152 -0
  295. package/src/types/errors.ts +40 -0
  296. package/src/types/index.ts +6 -0
  297. package/src/types/parser.ts +479 -0
  298. package/src/utils/extractTokens.ts +67 -0
  299. package/src/utils/getCursorInfo.ts +106 -0
  300. package/src/utils/getOppositeDelimiter.ts +36 -0
  301. package/src/utils/getSurroundingErrors.ts +57 -0
  302. package/src/utils/index.ts +11 -0
  303. package/src/utils/isBracket.ts +6 -0
  304. package/src/utils/isDelimiter.ts +18 -0
  305. package/src/utils/isParen.ts +6 -0
  306. package/src/utils/isQuote.ts +6 -0
  307. package/src/utils/prettyAst.ts +152 -0
@@ -0,0 +1,190 @@
1
+ /* eslint-disable @typescript-eslint/no-shadow */
2
+
3
+ import { ArrayNode } from "./classes/ArrayNode.js"
4
+ import { ConditionNode } from "./classes/ConditionNode.js"
5
+ import { ErrorToken } from "./classes/ErrorToken.js"
6
+ import { ExpressionNode } from "./classes/ExpressionNode.js"
7
+ import { GroupNode } from "./classes/GroupNode.js"
8
+ import { ValidToken } from "./classes/ValidToken.js"
9
+ import { VariableNode } from "./classes/VariableNode.js"
10
+
11
+ import { type AnyToken, type FirstConstructorParam, type Position, TOKEN_TYPE, type TokenBooleanTypes, type TokenDelimiterTypes, type TokenOperatorTypes, type TokenQuoteTypes } from "../types/ast.js"
12
+
13
+
14
+ /* #region HELPERS */
15
+ function error<T extends TOKEN_TYPE>(pos: number, expected: T[]): ErrorToken<T> {
16
+ if (pos === undefined) throw new Error("should never happen, passed undefined position for error token")
17
+ return new ErrorToken({ expected, start: pos, end: pos })
18
+ }
19
+ /* #regionend */
20
+
21
+ /* #region TOKENS */
22
+ const operators = <T extends TokenOperatorTypes>
23
+ (type: T) =>
24
+ (value: string, pos: Position): ValidToken<T> => new ValidToken({ value, type, ...pos })
25
+
26
+ const delimiters = <T extends TokenDelimiterTypes>
27
+ (type: T) =>
28
+ (value: string | undefined, pos: Position): ValidToken<T> | undefined =>
29
+ // check must be falsy, we want to return undefined when given ""
30
+ value ? new ValidToken({ value, type, ...pos }) : undefined
31
+
32
+ const maybeToken = <T extends TOKEN_TYPE>(type: T) => (value: string | undefined, pos: Position,): AnyToken<T> => {
33
+ if (value === undefined) {
34
+ return error(pos.end, [type])
35
+ } else {
36
+ return new ValidToken({ value, type, ...pos })
37
+ }
38
+ }
39
+
40
+ export const token = {
41
+ value: maybeToken(TOKEN_TYPE.VALUE),
42
+ custom: maybeToken(TOKEN_TYPE.OP_CUSTOM),
43
+ sep: maybeToken(TOKEN_TYPE.OP_EXPANDED_SEP),
44
+ }
45
+
46
+ /** We want to handle all the types outside the grammar file. This makes it easier without trying to check the value. */
47
+ export const delimiter = {
48
+ parenL: delimiters(TOKEN_TYPE.PARENL),
49
+ parenR: delimiters(TOKEN_TYPE.PARENR),
50
+ bracketL: delimiters(TOKEN_TYPE.BRACKETL),
51
+ bracketR: delimiters(TOKEN_TYPE.BRACKETR),
52
+ double: delimiters(TOKEN_TYPE.DOUBLEQUOTE),
53
+ single: delimiters(TOKEN_TYPE.SINGLEQUOTE),
54
+ regex: delimiters(TOKEN_TYPE.REGEX),
55
+ tick: delimiters(TOKEN_TYPE.BACKTICK),
56
+ tokenError: error,
57
+ }
58
+ export const operator = {
59
+ and: operators(TOKEN_TYPE.AND),
60
+ or: operators(TOKEN_TYPE.OR),
61
+ not: operators(TOKEN_TYPE.NOT),
62
+ }
63
+ /* #regionend */
64
+
65
+ /* #region AST NODES */
66
+ export function variable(
67
+ prefix: ValidToken<TOKEN_TYPE.VALUE> | null | undefined,
68
+ quoteL: AnyToken<TokenQuoteTypes> | null | undefined,
69
+ value: AnyToken<TOKEN_TYPE.VALUE> | null | undefined,
70
+ quoteR: AnyToken<TokenQuoteTypes> | null | undefined,
71
+ flags?: ValidToken<TOKEN_TYPE.VALUE>
72
+ ): VariableNode {
73
+ const node: FirstConstructorParam<typeof VariableNode> = {
74
+ prefix: prefix ?? undefined,
75
+ value: value ?? error((prefix?.end ?? quoteL?.end ?? quoteR?.start)!, [TOKEN_TYPE.VALUE]),
76
+ start: (prefix?.start ?? quoteL?.start ?? value?.start ?? quoteR?.start)!,
77
+ end: (quoteR?.end ?? value?.end ?? quoteL?.end ?? prefix?.end)!,
78
+ }
79
+
80
+ if (quoteL || quoteR) {
81
+ node.quote = {
82
+ left: quoteL ?? error(node.value.start, [(quoteR!.type)]),
83
+ right: quoteR ?? error(node.value.end, [(quoteL!.type)]),
84
+ }
85
+ if (flags) {
86
+ node.quote.flags = flags
87
+ node.end = node.quote?.flags.end
88
+ }
89
+ }
90
+
91
+ const instance = new VariableNode(node as any)
92
+ return instance
93
+ }
94
+
95
+
96
+ export function condition(
97
+ not: ValidToken<TOKEN_TYPE.NOT> | null | undefined,
98
+ property: VariableNode | null | undefined,
99
+ { propertyOperator, sepL, sepR }: {
100
+ propertyOperator?: ConditionNode["propertyOperator"] | null
101
+ sepL?: ValidToken<TOKEN_TYPE.OP_EXPANDED_SEP> | null
102
+ sepR?: ValidToken<TOKEN_TYPE.OP_EXPANDED_SEP> | null
103
+ } = {},
104
+ value?: VariableNode | GroupNode | ArrayNode | null,
105
+ ): ConditionNode {
106
+ const start = (not?.start ?? property?.start ?? sepL?.start ?? propertyOperator?.start ?? sepR?.start ?? value?.start)!
107
+ const end = (value?.end ?? sepR?.end ?? propertyOperator?.end ?? sepL?.end ?? property?.end ?? not?.end)!
108
+ const node: FirstConstructorParam<typeof ConditionNode> = {
109
+ value: value ? value : error(end, [TOKEN_TYPE.VALUE]),
110
+ start,
111
+ end,
112
+ }
113
+ if (not) { node.operator = not }
114
+ if (property) node.property = property
115
+ if (propertyOperator) node.propertyOperator = propertyOperator
116
+ if (sepL || sepR) {
117
+ node.sep = {}
118
+ if (sepL) {
119
+ node.sep.left = sepL
120
+ node.property ||= error(sepL.start, [TOKEN_TYPE.VALUE])
121
+ node.propertyOperator ||= error(sepL?.end ?? sepR?.start, [TOKEN_TYPE.VALUE])
122
+ }
123
+ if (sepR) node.sep.right = sepR
124
+ else if (!node.value || node.value instanceof VariableNode) {
125
+ node.sep.right = error(node.value?.start ?? end, [TOKEN_TYPE.OP_EXPANDED_SEP])
126
+ }
127
+ } else if (propertyOperator) {
128
+ node.property ||= error(propertyOperator.start, [TOKEN_TYPE.VALUE])
129
+ }
130
+
131
+ const instance = new ConditionNode(node as any)
132
+ return instance
133
+ }
134
+
135
+ export function expression(
136
+ left: ConditionNode | GroupNode | null | undefined,
137
+ operator: ValidToken<TokenBooleanTypes> | null | undefined,
138
+ right: ConditionNode | GroupNode | null | undefined,
139
+ ): ExpressionNode {
140
+ const instance = new ExpressionNode({
141
+ left: left ?? error((operator?.start ?? right?.start)!, [TOKEN_TYPE.VALUE]),
142
+ operator: operator ?? error((left?.end ?? right?.start)!, [TOKEN_TYPE.AND, TOKEN_TYPE.OR]),
143
+ right: right ?? error((operator?.end ?? left?.end)!, [TOKEN_TYPE.VALUE]),
144
+ start: (left?.start ?? operator?.start ?? right?.start)!,
145
+ end: (right?.end ?? operator?.end ?? left?.end)!,
146
+ })
147
+ return instance
148
+ }
149
+
150
+ export function group(
151
+ operator: ValidToken<TOKEN_TYPE.NOT> | null | undefined,
152
+ prefix: ConditionNode | null | undefined,
153
+ parenL: ValidToken<TOKEN_TYPE.PARENL> | null | undefined,
154
+ condition: GroupNode["expression"],
155
+ parenR: ValidToken<TOKEN_TYPE.PARENR> | null | undefined
156
+ ): GroupNode {
157
+ const node: FirstConstructorParam<typeof GroupNode> = {
158
+ prefix: prefix ?? operator ?? undefined,
159
+ expression: condition ?? error((parenL?.end ?? parenR?.start)!, [TOKEN_TYPE.VALUE]),
160
+ paren: {
161
+ left: parenL ?? error((prefix?.end ?? operator?.end ?? condition?.start ?? parenR?.start)!, [TOKEN_TYPE.PARENL]),
162
+ right: parenR ?? error((condition?.end ?? parenL?.end)!, [TOKEN_TYPE.PARENR]),
163
+ },
164
+ start: (prefix?.start ?? operator?.start ?? parenL?.start ?? condition?.start ?? parenR?.start)!,
165
+ end: (parenR?.end ?? condition?.end ?? parenL?.end ?? operator?.end ?? prefix?.end)!,
166
+ }
167
+
168
+ const instance = new GroupNode(node as any)
169
+ return instance
170
+ }
171
+
172
+ export function array(
173
+ bracketL: ValidToken<TOKEN_TYPE.BRACKETL>,
174
+ values: VariableNode[],
175
+ bracketR: ValidToken<TOKEN_TYPE.BRACKETR> | null | undefined
176
+ ): ArrayNode {
177
+ const node: FirstConstructorParam<typeof ArrayNode> = {
178
+ values,
179
+ bracket: {
180
+ left: bracketL, // always valid for now
181
+ right: bracketR ?? error((values[values.length - 1]?.end ?? bracketL?.end)!, [TOKEN_TYPE.BRACKETR]),
182
+ },
183
+ start: bracketL.start,
184
+ end: (bracketR?.end ?? values[values.length - 1]?.end ?? bracketL.end)!,
185
+ }
186
+
187
+ const instance = new ArrayNode(node as any)
188
+ return instance
189
+ }
190
+ /* #regionend */
@@ -0,0 +1,5 @@
1
+ /* Autogenerated Index */
2
+
3
+ export * as builders from "./builders/index.js"
4
+ export * as classes from "./classes/index.js"
5
+ export { token } from "./handlers.js"
@@ -0,0 +1,31 @@
1
+ import type { ValueQuery } from "../types/parser.js"
2
+
3
+ /* TODO TOUPDATE */
4
+ type Operators = ">" | "contains"
5
+ type Prefixes = "num"
6
+ export function valueComparer(contextValue: string, { operator, prefix, value, isRegex, regexFlags }: ValueQuery): boolean {
7
+ let finalValue: any = value
8
+ if (prefix) {
9
+ const val = value as string // it's always a string if prefixed
10
+ switch (prefix as Prefixes) {
11
+ case "num": finalValue = parseInt(val, 2); break
12
+ // ...
13
+ }
14
+ }
15
+ if (isRegex) {
16
+ const val = value as string // it's always a string and never prefixed if it's a regex
17
+ const regex = new RegExp(val, regexFlags)
18
+ return contextValue.match(regex) !== null
19
+ }
20
+ if (operator) {
21
+ switch (operator as Operators) {
22
+ // custom operators
23
+ case ">": return contextValue > finalValue
24
+ // ...
25
+ // custom expanded operators
26
+ case "contains": return contextValue.includes(finalValue)
27
+ // ...
28
+ }
29
+ }
30
+ return contextValue === finalValue
31
+ }
@@ -0,0 +1,140 @@
1
+ /* TODO TOUPDATE */
2
+ /**
3
+ * A pre-configured parser for parsing shortcut contexts (similar to VSCode's [when clause contexts](https://code.visualstudio.com/docs/getstarted/keybindings#_when-clause-contexts)).
4
+ *
5
+ * The only difference is that it does not have a regex operator since you can just do `prop == /regex/`, and because of how it has `prefixableGroups` turned on and how the parser allows groups as values, user's can use shorter queries.
6
+ *
7
+ * It also automatically implements a prefixApplier (variables are joined with `.`) and a value validator (which is why it requires a dummy context and a list of valid regex flags be passed). The value of the dummy context should be true to indicate the key is regexable, otherwise just false or a nested object. Any nested keys found are joined with a `.` and added to a list of valid keys. The prefixApplier is loose and allows things like `a.(b.(c))` and `a(b(c))` to both be parsed as `a.b.c`.
8
+ *
9
+ * The validate function will return a list of positions with a list of errors which includes handling invalid or duplicate regex flags.
10
+ */
11
+
12
+ import { Parser } from "../parser.js"
13
+ import type { Position } from "../types/ast.js"
14
+ import type { ValueQuery } from "../types/parser.js"
15
+
16
+
17
+ export class ShortcutContextParser<T extends
18
+ Position & { type: ("invalidKey" | "unregexableKey" | "invalidRegexFlag" | "duplicateRegexFlag") } =
19
+ Position & { type: ("invalidKey" | "unregexableKey" | "invalidRegexFlag" | "duplicateRegexFlag") },
20
+ > extends Parser<T> {
21
+ validKeys: string[] = []
22
+
23
+ regexablekeys: string[] = []
24
+
25
+ constructor(
26
+ dummyContext: Record<string, any>,
27
+ validRegexFlags: string[] = ["i", "u", "m"]
28
+ ) {
29
+ super({
30
+ arrayValues: false,
31
+ keyParser: (key: string) => key.split(/\.+/),
32
+ keywords: {
33
+ and: [{ isSymbol: true, value: "&&" }],
34
+ or: [{ isSymbol: true, value: "||" }],
35
+ not: [{ isSymbol: true, value: "!" }],
36
+ },
37
+ regexValues: (property, operator) => property !== undefined && operator !== undefined,
38
+ customPropertyOperators: ["!=", "=="],
39
+ prefixableGroups: true,
40
+ prefixApplier: (prefix: string, variable: string) => {
41
+ if (!prefix.endsWith(".")) {
42
+ return `${prefix}.${variable}`
43
+ }
44
+ return prefix + variable
45
+ },
46
+ valueComparer: (_condition, contextValue, query) => {
47
+ if (query.isRegex) {
48
+ return contextValue.match(new RegExp(query.value as string, query.regexFlags ?? "")) !== null
49
+ }
50
+ return contextValue === query.value
51
+ },
52
+ valueValidator: (_contextValue, query): T[] | void => {
53
+ let tokens: T[] = []
54
+ if (!this.validKeys.includes(query.propertyName!)) {
55
+ tokens = tokens.concat(query.property.map(token => ({
56
+ start: token.start,
57
+ end: token.end,
58
+ type: "invalidKey",
59
+ })) as T[])
60
+ }
61
+ if (query.isRegex && !this.regexablekeys.includes(query.propertyName!)) {
62
+ tokens = tokens.concat(query.property.map(token => ({
63
+ start: token.start,
64
+ end: token.end,
65
+ type: "unregexableKey",
66
+ })) as T[])
67
+ }
68
+ if (query.regexFlags) {
69
+ const chars = query.regexFlags.value.split("")
70
+ const start = query.regexFlags.start
71
+ for (let i = 0; i < chars.length; i++) {
72
+ const char = chars[i]
73
+ if (chars.slice(0, i).includes(char)) {
74
+ tokens.push({
75
+ start: start + i,
76
+ end: start + i + 1,
77
+ type: "duplicateRegexFlag",
78
+ } as T)
79
+ }
80
+ if (!validRegexFlags.includes(char)) {
81
+ tokens.push({
82
+ start: start + i,
83
+ end: start + i + 1,
84
+ type: "invalidRegexFlag",
85
+ } as T)
86
+ }
87
+ }
88
+ }
89
+ if (tokens.length > 0) return tokens
90
+ },
91
+ conditionNormalizer({ operator, value, regexFlags, isRegex, isNegated, isQuoted }: ValueQuery) {
92
+ let finalValue: any = value
93
+ let finalOperator: any = operator
94
+ // another way to allow special unquoted value types is something like this:
95
+ if (typeof value === "string" && !isQuoted) {
96
+ const asNum = parseInt(value, 2)
97
+ if (!isNaN(asNum)) finalValue = asNum
98
+ if (["true", "false"].includes(value)) {
99
+ finalValue = value === "true"
100
+ }
101
+ }
102
+ if (isRegex) {
103
+ const val = value as string // it's always a string and never prefixed if it's a regex
104
+ const regex = new RegExp(val, regexFlags) // this can throw if the user passes invalid flags
105
+ finalValue = regex
106
+ }
107
+ if (operator) {
108
+ switch (operator as any) {
109
+ case "==": {
110
+ finalOperator = "equals"
111
+ break
112
+ }
113
+ case "!=": {
114
+ finalOperator = "equals"
115
+ isNegated = !isNegated
116
+ break
117
+ }
118
+ }
119
+ }
120
+ return { value: finalValue, operator: finalOperator, negate: isNegated }
121
+ },
122
+ })
123
+ this._extractKeysFromContext(dummyContext)
124
+ }
125
+
126
+ private _extractKeysFromContext(context: Record<string, any>, prev?: string): void {
127
+ for (const key of Object.keys(context)) {
128
+ if (typeof context[key] === "boolean") {
129
+ this.validKeys.push(prev ? `${prev}.${key}` : key)
130
+ if (context[key] === true) {
131
+ this.regexablekeys.push(prev ? `${prev}.${key}` : key)
132
+ }
133
+ } else {
134
+ if (typeof context[key] !== "object") throw new Error("A dummy context value must be a boolean or an object.")
135
+ this._extractKeysFromContext(context[key], prev ? `${prev}.${key}` : key)
136
+ }
137
+ }
138
+ }
139
+ }
140
+
@@ -0,0 +1,4 @@
1
+ declare module "./package.js" {
2
+ export const version: string
3
+ export const repository: string
4
+ }