@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,36 @@
1
+ import { unreachable } from "@alanscodelog/utils"
2
+
3
+ import { isBracket } from "./isBracket.js"
4
+ import { isDelimiter } from "./isDelimiter.js"
5
+ import { isParen } from "./isParen.js"
6
+ import { isQuote } from "./isQuote.js"
7
+
8
+ import type { ArrayNode, ConditionNode, GroupNode, VariableNode } from "../ast/classes/index.js"
9
+ import { type AnyToken, TOKEN_TYPE, type TokenDelimiterTypes } from "../types/ast.js"
10
+
11
+ /**
12
+ * Given a delimiter token, returns it's opposite pair, or undefined if the type passed was not a delimiter token (so you can pass any type without checking).
13
+ */
14
+ export function getOppositeDelimiter(token: AnyToken): AnyToken<TokenDelimiterTypes> | undefined {
15
+ if (!isDelimiter(token)) throw new Error("Token is not a delimiter type.")
16
+ if (isParen(token)) {
17
+ const paren = (token.parent as GroupNode).paren
18
+ const opposite = paren.left === token ? "right" : "left"
19
+ return paren[opposite]
20
+ } else if (isBracket(token)) {
21
+ const bracket = (token.parent as ArrayNode).bracket
22
+ const opposite = bracket.left === token ? "right" : "left"
23
+ return bracket[opposite]
24
+ } else if (isQuote(token)) {
25
+ const quotes = (token.parent as VariableNode).quote
26
+ if (quotes === undefined) unreachable()
27
+ const opposite = quotes.left === token ? "right" : "left"
28
+ return quotes[opposite]
29
+ } else if (token.type === TOKEN_TYPE.OP_EXPANDED_SEP) {
30
+ const sep = (token.parent as ConditionNode).sep
31
+ if (sep === undefined) unreachable()
32
+ const opposite = sep.left === token ? "right" : "left"
33
+ return sep[opposite]
34
+ }
35
+ unreachable()
36
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Mostly for internal use by @see autosuggest.
3
+ *
4
+ * Returns all error tokens immediately before/after cursor (since there might be multiple error tokens one after the other).
5
+ *
6
+ * The errors are sorted by closeness to the given cursor (inside @see CursorInfo), with quote errors having priority, then paren errors, then any other errors. They can be sorted by closeness because although two errors might follow each other, their positions might be different because of whitespace, but they can still be fixed from any cursor position between their ends.
7
+ *
8
+ * For example:
9
+ * ```
10
+ * a a"
11
+ * ^ operator missing at 1
12
+ * ^ doublequote missing at 2
13
+ * if the cursor is at 1 (`a| a"`):
14
+ * errors = [operator, doublequote]
15
+ * if the cursor is at 2 (`a |a"`):
16
+ * errors = [doublequote, operator]
17
+ *
18
+ * either insertion would fix the issue for either position would fix the issue, albeit with different results
19
+ * ```
20
+ */
21
+
22
+ import { ErrorToken } from "../ast/classes/ErrorToken.js"
23
+ import { type AnyToken, TOKEN_TYPE } from "../types/ast.js"
24
+ import type { CursorInfo } from "../types/autocomplete.js"
25
+
26
+
27
+ export function getSurroundingErrors(tokens: AnyToken[], token: CursorInfo): ErrorToken[] {
28
+ if (token.at) {return []}
29
+ const i = tokens.indexOf(token.next ?? token.prev as any)
30
+
31
+ let iNext: number = tokens[i] === token.next ? i : i + 1
32
+ let iPrev: number = tokens[i] === token.next ? i - 1 : i
33
+
34
+ const errors = []
35
+ while (tokens[iNext] instanceof ErrorToken) {
36
+ errors.push(tokens[iNext])
37
+ iNext++
38
+ }
39
+ while (tokens[iPrev] instanceof ErrorToken) {
40
+ errors.push(tokens[iPrev])
41
+ iPrev--
42
+ }
43
+
44
+ return errors.sort((a, b) => {
45
+ const aIsQuote = [TOKEN_TYPE.DOUBLEQUOTE, TOKEN_TYPE.BACKTICK, TOKEN_TYPE.SINGLEQUOTE].includes(a.expected[0])
46
+ const bIsQuote = [TOKEN_TYPE.DOUBLEQUOTE, TOKEN_TYPE.BACKTICK, TOKEN_TYPE.SINGLEQUOTE].includes(b.expected[0])
47
+ const aIsParen = [TOKEN_TYPE.PARENR, TOKEN_TYPE.PARENL].includes(a.expected[0])
48
+ const bIsParen = [TOKEN_TYPE.PARENR, TOKEN_TYPE.PARENL].includes(b.expected[0])
49
+ const aCloseness = Math.abs(i - tokens.indexOf(a))
50
+ const bCloseness = Math.abs(i - tokens.indexOf(b))
51
+ const closenessComparison = aCloseness - bCloseness
52
+ if (aIsQuote === bIsQuote) {
53
+ if (aIsParen !== bIsParen) {return aIsParen ? -1 : 1}
54
+ }
55
+ return closenessComparison
56
+ }) as ErrorToken[]
57
+ }
@@ -0,0 +1,11 @@
1
+ /* Autogenerated Index */
2
+
3
+ export { extractTokens } from "./extractTokens.js"
4
+ export { getCursorInfo } from "./getCursorInfo.js"
5
+ export { getOppositeDelimiter } from "./getOppositeDelimiter.js"
6
+ export { getSurroundingErrors } from "./getSurroundingErrors.js"
7
+ export { isBracket } from "./isBracket.js"
8
+ export { isDelimiter } from "./isDelimiter.js"
9
+ export { isParen } from "./isParen.js"
10
+ export { isQuote } from "./isQuote.js"
11
+ export { prettyAst } from "./prettyAst.js"
@@ -0,0 +1,6 @@
1
+ import { type AnyToken, TOKEN_TYPE, type TokenBracketTypes } from "../types/ast.js"
2
+
3
+
4
+ export function isBracket(token?: AnyToken): token is AnyToken<TokenBracketTypes> {
5
+ return ([TOKEN_TYPE.BRACKETL, TOKEN_TYPE.BRACKETR] as any[]).includes(token?.type)
6
+ }
@@ -0,0 +1,18 @@
1
+ import { type AnyToken, TOKEN_TYPE, type TokenDelimiterTypes } from "../types/ast.js"
2
+
3
+ /**
4
+ * Returns whether token is a delimiter type (including if it's an expanded operator separator).
5
+ */
6
+ export function isDelimiter(token?: AnyToken): token is AnyToken<TokenDelimiterTypes> {
7
+ return ([
8
+ TOKEN_TYPE.BACKTICK,
9
+ TOKEN_TYPE.DOUBLEQUOTE,
10
+ TOKEN_TYPE.SINGLEQUOTE,
11
+ TOKEN_TYPE.PARENL,
12
+ TOKEN_TYPE.PARENR,
13
+ TOKEN_TYPE.BRACKETL,
14
+ TOKEN_TYPE.BRACKETR,
15
+ TOKEN_TYPE.OP_EXPANDED_SEP,
16
+ TOKEN_TYPE.REGEX,
17
+ ] as TokenDelimiterTypes[]).includes(token?.type as TokenDelimiterTypes)
18
+ }
@@ -0,0 +1,6 @@
1
+ import { type AnyToken, TOKEN_TYPE, type TokenParenTypes } from "../types/ast.js"
2
+
3
+
4
+ export function isParen(token?: AnyToken): token is AnyToken<TokenParenTypes> {
5
+ return ([TOKEN_TYPE.PARENL, TOKEN_TYPE.PARENR] as any[]).includes(token?.type)
6
+ }
@@ -0,0 +1,6 @@
1
+ import { type AnyToken, TOKEN_TYPE, type TokenQuoteTypes } from "../types/ast.js"
2
+
3
+ /** Returns if the token is a quote token. This includes regex delimiters. */
4
+ export function isQuote(token?: AnyToken): token is AnyToken<TokenQuoteTypes> {
5
+ return ([TOKEN_TYPE.BACKTICK, TOKEN_TYPE.DOUBLEQUOTE, TOKEN_TYPE.SINGLEQUOTE, TOKEN_TYPE.REGEX] as any[]).includes(token?.type)
6
+ }
@@ -0,0 +1,152 @@
1
+ /* eslint-disable prefer-rest-params */
2
+ import { type AddParameters, colors as color } from "@alanscodelog/utils"
3
+ import { isBlank, unreachable } from "@alanscodelog/utils"
4
+
5
+ import { ArrayNode, ConditionNode, ErrorToken, ExpressionNode, GroupNode, ValidToken, VariableNode } from "../ast/classes/index.js"
6
+ import { type AnyToken, type ParserResults, TOKEN_TYPE } from "../types/ast.js"
7
+
8
+
9
+ type Colors = {
10
+ /** Color used to highlight the actual text content of the token nodes. */
11
+ values: string
12
+ /** Color used to highlight the extra information some nodes contain in their headers for a quick overview (e.g. which operator for expression nodes, if a condition/group value is true, how long an array value is etc). */
13
+ info: string
14
+ position: string
15
+ /** Color used to highlight the hints in parens that indicate how the node is being used (e.g. a variable node might be a property, or alone as a variable, etc) */
16
+ hint: string
17
+ error: string
18
+ /** Color used to reset highlights. */
19
+ reset: string
20
+ }
21
+
22
+ const defaultColors: Colors = {
23
+ values: color.yellow,
24
+ info: color.cyan,
25
+ position: color.green,
26
+ hint: color.blue,
27
+ error: color.red,
28
+ reset: color.reset,
29
+ }
30
+ const disableColors: Colors = Object.fromEntries(Object.keys(defaultColors).map(key => [key, ""])) as Colors
31
+
32
+ const toRows = (rows: string[], opts: Required<NonNullable<Parameters<typeof prettyAst>[1]>>): string[] => {
33
+ rows = rows.filter(child => child !== "")
34
+
35
+ return [
36
+ ...rows.slice(0, rows.length - 1).map(child => `${opts.indent}${opts.children}${child}`),
37
+ `${opts.indent}${opts.last}${rows[rows.length - 1]}`,
38
+ ]
39
+ }
40
+ /**
41
+ * Returns a more compressed, color coded, string representation of the ast for debugging.
42
+ *
43
+ * There are options to change which symbols are used for tree and if the variables are surrounded by quotes (default false).
44
+ *
45
+ * Colors can changed by passing ansi codes (or whatever you want\*) to the third parameter. Or you can pass false instead of an object to disable them. Default colors are:
46
+ * ```ts
47
+ * {
48
+ * values: // yellow,
49
+ * position: // green,
50
+ * info: // cyan,
51
+ * hint: // blue,
52
+ * error: // red,
53
+ * reset: // ansi reset code
54
+ * }
55
+ * ```
56
+ * \* For example, you could pass html tags to show this in the browser instead (this is how the demo works). This is why the reset color is exposed. For example, a color might be `<span class="error">` and reset can be `</span>`.
57
+ */
58
+
59
+ export function prettyAst(
60
+ ast: ParserResults | AnyToken | VariableNode | ArrayNode | GroupNode,
61
+ { indent = " ", children = "├╴", last = "└╴", branch = "│", quote = "" }: Partial<Record<"indent" | "children" | "last" | "branch" | "quote", string>> = {},
62
+ colors: Partial<Colors> | false = {},
63
+ ): string {
64
+ const opts = { indent, children, last, branch, quote }
65
+ const c: Colors = colors ? { ...defaultColors, ...colors } : disableColors
66
+ const pos = `${c.position}(${ast.start}, ${ast.end})${c.reset}`
67
+ const _ = indent
68
+ // accumulated indent
69
+ const __: string = arguments[3] ?? ""
70
+ let extra: string = arguments[4] ?? ""
71
+ if (!isBlank(extra)) extra = ` ${c.hint}${extra}${c.reset}`
72
+ // indent to add to children items
73
+ const ___ = __ + _ + branch
74
+ // indent to add to last child item
75
+ // eslint-disable-next-line @typescript-eslint/naming-convention
76
+ const __L = __ + _ + indent[0]
77
+ const prettyAst_ = prettyAst as any as AddParameters<typeof prettyAst, [
78
+ typeof __,
79
+ typeof extra,
80
+ ]>
81
+ if (ast instanceof ValidToken) {
82
+ const value = `${ast.value}`
83
+ return `TOKEN ${pos} ${c.values}${quote}${value}${quote}${c.reset}${extra}`
84
+ }
85
+ if (ast instanceof ErrorToken) {
86
+ const value = `[${ast.expected.join(", ")}]`
87
+ return `ERROR ${pos} ${c.error}${value}${c.reset}${extra}`
88
+ }
89
+ if (ast instanceof ConditionNode) {
90
+ const header = `${c.info}${ast.operator === undefined}${c.reset}`
91
+ const not = ast.operator ? prettyAst_(ast.operator, opts, c, ___, `(negation)`) : ""
92
+ const property = ast.property ? prettyAst_(ast.property, opts, c, ___, `(property)`) : ""
93
+ const sepL = ast.sep?.left ? prettyAst_(ast.sep.left, opts, c, ___, `(separator)`) : ""
94
+ const op = ast.propertyOperator ? prettyAst_(ast.propertyOperator, opts, c, ___, `(property operator)`) : ""
95
+ const sepR = ast.sep?.right ? prettyAst_(ast.sep.right, opts, c, ___, `(separator)`) : ""
96
+ const isRegex = ast.value instanceof VariableNode && ast.value.quote?.left.type === TOKEN_TYPE.REGEX
97
+ const isArray = ast.value instanceof ArrayNode
98
+ const variable = prettyAst_(ast.value, opts, c, __L, `(${property ? "value" : "variable/alone"}${isRegex ? " - regex" : isArray ? "- array" : ""})`)
99
+ return [
100
+ `CONDITION ${pos} ${header}${extra}`,
101
+ ...toRows([not, property, sepL, op, sepR, variable], opts),
102
+ ].join(`\n${__}`)
103
+ }
104
+ if (ast instanceof VariableNode) {
105
+ const prefix = ast.prefix ? prettyAst_(ast.prefix, opts, c, ___, `(value prefix)`) : ""
106
+ const left = ast.quote?.left ? prettyAst_(ast.quote.left, opts, c, ___, "") : ""
107
+ const value = prettyAst_(ast.value, opts, c, !ast.quote ? __L : !ast.quote?.right ? __L : ___, "")
108
+ const right = ast.quote?.right ? prettyAst_(ast.quote.right, opts, c, !ast.quote?.flags ? __L : ___, "") : ""
109
+ const flags = ast.quote?.flags ? prettyAst_(ast.quote.flags, opts, c, __L, "(flags)") : ""
110
+
111
+ return [
112
+ `VARIABLE ${pos}${extra}`,
113
+ ...toRows([prefix, left, value, right, flags], opts),
114
+ ].join(`\n${__}`)
115
+ }
116
+ if (ast instanceof GroupNode) {
117
+ const header = `${c.info}${ast.prefix === undefined || (ast.prefix as ConditionNode).operator === undefined}${c.reset}`
118
+ const prefix = ast.prefix ? prettyAst_(ast.prefix, opts, c, ___, `(group prefix)`) : ""
119
+ const expression = prettyAst_(ast.expression, opts, c, __L, "")
120
+ return [
121
+ `GROUP ${pos}${!extra.includes("value") ? ` ${header}` : ""}${extra}`,
122
+ ...toRows([prefix, expression], opts),
123
+ ].join(`\n${__}`)
124
+ }
125
+ if (ast instanceof ArrayNode) {
126
+ const bracketL = ast.bracket.left ? prettyAst_(ast.bracket.left, opts, c, ast.values.length === 0 && !ast.bracket.right ? __L : ___, "") : ""
127
+ const values = ast.values.length > 0
128
+ ? ast.values.map((node, i) =>
129
+ prettyAst_(node, opts, c, !ast.bracket.right && i === ast.values.length - 1 ? __L : ___, "")
130
+ )
131
+ : []
132
+ const bracketR = ast.bracket.right ? prettyAst_(ast.bracket.right, opts, c, __L, "") : ""
133
+ return [
134
+ `ARRAY ${pos} ${c.info}[${ast.values.length}]${c.reset}${extra}`,
135
+ ...toRows([bracketL, ...values, bracketR], opts),
136
+ ].join(`\n${__}`)
137
+ }
138
+ if (ast instanceof ExpressionNode) {
139
+ const left = prettyAst_(ast.left, opts, c, ___, "")
140
+ const operator = prettyAst_(ast.operator, opts, c, ___, `(boolean operator)`)
141
+ const right = prettyAst_(ast.right, opts, c, __L, "")
142
+
143
+ const header = ast.operator instanceof ErrorToken
144
+ ? `${c.info}[${ast.operator.expected.join(",")}]${c.reset}`
145
+ : `${c.info}"${ast.operator.value}"${c.reset}`
146
+ return [
147
+ `EXPRESSION ${pos} ${header}${extra}`,
148
+ ...toRows([left, operator, right], opts),
149
+ ].join(`\n${__}`)
150
+ }
151
+ unreachable()
152
+ }