@jesscss/core 2.0.0-alpha.5 → 2.0.0-alpha.6

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 (637) hide show
  1. package/lib/index.cjs +20159 -0
  2. package/lib/index.d.cts +5993 -0
  3. package/lib/index.d.cts.map +1 -0
  4. package/lib/index.d.ts +5992 -21
  5. package/lib/index.d.ts.map +1 -1
  6. package/lib/index.js +19926 -22
  7. package/lib/index.js.map +1 -1
  8. package/package.json +15 -14
  9. package/src/__tests__/define-function-record.test.ts +58 -0
  10. package/src/__tests__/define-function-simple.test.ts +55 -0
  11. package/src/__tests__/define-function-split-sequence.test.ts +547 -0
  12. package/src/__tests__/define-function-type-parity.test.ts +9 -0
  13. package/src/__tests__/define-function.test.ts +763 -0
  14. package/src/__tests__/num-operations.test.ts +91 -0
  15. package/src/__tests__/safe-parse.test.ts +374 -0
  16. package/src/context.ts +896 -0
  17. package/src/conversions.ts +282 -0
  18. package/src/debug-log.ts +29 -0
  19. package/src/define-function.ts +1006 -0
  20. package/src/deprecation.ts +67 -0
  21. package/src/globals.d.ts +26 -0
  22. package/src/index.ts +31 -0
  23. package/src/jess-error.ts +773 -0
  24. package/src/logger/deprecation-processing.ts +109 -0
  25. package/src/logger.ts +31 -0
  26. package/src/plugin.ts +292 -0
  27. package/src/tree/LOOKUP_CHAINS.md +35 -0
  28. package/src/tree/README.md +18 -0
  29. package/src/tree/__tests__/__snapshots__/extend-eval-integration.test.ts.snap +1455 -0
  30. package/src/tree/__tests__/ampersand.test.ts +382 -0
  31. package/src/tree/__tests__/at-rule.test.ts +2047 -0
  32. package/src/tree/__tests__/basic-render.test.ts +212 -0
  33. package/src/tree/__tests__/block.test.ts +40 -0
  34. package/src/tree/__tests__/call.test.ts +346 -0
  35. package/src/tree/__tests__/color.test.ts +537 -0
  36. package/src/tree/__tests__/condition.test.ts +186 -0
  37. package/src/tree/__tests__/control.test.ts +564 -0
  38. package/src/tree/__tests__/declaration.test.ts +253 -0
  39. package/src/tree/__tests__/dependency-graph.test.ts +177 -0
  40. package/src/tree/__tests__/detached-rulesets.test.ts +213 -0
  41. package/src/tree/__tests__/dimension.test.ts +236 -0
  42. package/src/tree/__tests__/expression.test.ts +73 -0
  43. package/src/tree/__tests__/ext-node.test.ts +31 -0
  44. package/src/tree/__tests__/extend-eval-integration.test.ts +1033 -0
  45. package/src/tree/__tests__/extend-import-style.test.ts +929 -0
  46. package/src/tree/__tests__/extend-less-fixtures.test.ts +851 -0
  47. package/src/tree/__tests__/extend-list.test.ts +31 -0
  48. package/src/tree/__tests__/extend-roots.test.ts +1045 -0
  49. package/src/tree/__tests__/extend-rules.test.ts +740 -0
  50. package/src/tree/__tests__/func.test.ts +171 -0
  51. package/src/tree/__tests__/import-js.test.ts +33 -0
  52. package/src/tree/__tests__/import-style-test-helpers.ts +56 -0
  53. package/src/tree/__tests__/import-style.test.ts +1967 -0
  54. package/src/tree/__tests__/interpolated-reference.test.ts +44 -0
  55. package/src/tree/__tests__/interpolated.test.ts +41 -0
  56. package/src/tree/__tests__/list.test.ts +177 -0
  57. package/src/tree/__tests__/log.test.ts +83 -0
  58. package/src/tree/__tests__/mixin-recursion.test.ts +639 -0
  59. package/src/tree/__tests__/mixin.test.ts +2171 -0
  60. package/src/tree/__tests__/negative.test.ts +45 -0
  61. package/src/tree/__tests__/nesting-collapse.test.ts +519 -0
  62. package/src/tree/__tests__/node-flags-perf.test.ts +195 -0
  63. package/src/tree/__tests__/node-flags.test.ts +410 -0
  64. package/src/tree/__tests__/node-graph.test.ts +598 -0
  65. package/src/tree/__tests__/node-mutation.test.ts +182 -0
  66. package/src/tree/__tests__/operation.test.ts +18 -0
  67. package/src/tree/__tests__/paren.test.ts +90 -0
  68. package/src/tree/__tests__/preserve-mode-output.test.ts +50 -0
  69. package/src/tree/__tests__/quoted.test.ts +72 -0
  70. package/src/tree/__tests__/range.test.ts +59 -0
  71. package/src/tree/__tests__/reference.test.ts +743 -0
  72. package/src/tree/__tests__/rest.test.ts +29 -0
  73. package/src/tree/__tests__/rules-raw.test.ts +14 -0
  74. package/src/tree/__tests__/rules.test.ts +1271 -0
  75. package/src/tree/__tests__/ruleset.test.ts +597 -0
  76. package/src/tree/__tests__/selector-attr.test.ts +50 -0
  77. package/src/tree/__tests__/selector-basic.test.ts +44 -0
  78. package/src/tree/__tests__/selector-capture.test.ts +22 -0
  79. package/src/tree/__tests__/selector-complex.test.ts +120 -0
  80. package/src/tree/__tests__/selector-compound.test.ts +74 -0
  81. package/src/tree/__tests__/selector-interpolated.test.ts +50 -0
  82. package/src/tree/__tests__/selector-list.test.ts +59 -0
  83. package/src/tree/__tests__/selector-pseudo.test.ts +23 -0
  84. package/src/tree/__tests__/selector.test.ts +182 -0
  85. package/src/tree/__tests__/sequence.test.ts +226 -0
  86. package/src/tree/__tests__/serialize-types.test.ts +529 -0
  87. package/src/tree/__tests__/spaced.test.ts +8 -0
  88. package/src/tree/__tests__/url.test.ts +72 -0
  89. package/src/tree/__tests__/var-declaration.test.ts +90 -0
  90. package/src/tree/ampersand.ts +538 -0
  91. package/src/tree/any.ts +169 -0
  92. package/src/tree/at-rule.ts +760 -0
  93. package/src/tree/block.ts +72 -0
  94. package/src/tree/bool.ts +46 -0
  95. package/src/tree/call.ts +593 -0
  96. package/src/tree/collection.ts +52 -0
  97. package/src/tree/color.ts +629 -0
  98. package/src/tree/combinator.ts +30 -0
  99. package/src/tree/comment.ts +36 -0
  100. package/src/tree/condition.ts +194 -0
  101. package/src/tree/control.ts +452 -0
  102. package/src/tree/declaration-custom.ts +56 -0
  103. package/src/tree/declaration-var.ts +87 -0
  104. package/src/tree/declaration.ts +742 -0
  105. package/src/tree/default-guard.ts +35 -0
  106. package/src/tree/dimension.ts +392 -0
  107. package/src/tree/expression.ts +97 -0
  108. package/src/tree/extend-list.ts +51 -0
  109. package/src/tree/extend.ts +391 -0
  110. package/src/tree/function.ts +254 -0
  111. package/src/tree/import-js.ts +130 -0
  112. package/src/tree/import-style.ts +875 -0
  113. package/{lib/tree/index.js → src/tree/index.ts} +49 -22
  114. package/src/tree/interpolated.ts +346 -0
  115. package/src/tree/js-array.ts +21 -0
  116. package/src/tree/js-expr.ts +50 -0
  117. package/src/tree/js-function.ts +31 -0
  118. package/src/tree/js-object.ts +22 -0
  119. package/src/tree/list.ts +415 -0
  120. package/src/tree/log.ts +89 -0
  121. package/src/tree/mixin.ts +331 -0
  122. package/src/tree/negative.ts +58 -0
  123. package/src/tree/nil.ts +57 -0
  124. package/src/tree/node-base.ts +1716 -0
  125. package/src/tree/node-type.ts +122 -0
  126. package/src/tree/node.ts +118 -0
  127. package/src/tree/number.ts +54 -0
  128. package/src/tree/operation.ts +187 -0
  129. package/src/tree/paren.ts +132 -0
  130. package/src/tree/query-condition.ts +47 -0
  131. package/src/tree/quoted.ts +119 -0
  132. package/src/tree/range.ts +101 -0
  133. package/src/tree/reference.ts +1099 -0
  134. package/src/tree/rest.ts +55 -0
  135. package/src/tree/rules-raw.ts +52 -0
  136. package/src/tree/rules.ts +2896 -0
  137. package/src/tree/ruleset.ts +1217 -0
  138. package/src/tree/selector-attr.ts +172 -0
  139. package/src/tree/selector-basic.ts +75 -0
  140. package/src/tree/selector-capture.ts +85 -0
  141. package/src/tree/selector-complex.ts +189 -0
  142. package/src/tree/selector-compound.ts +205 -0
  143. package/src/tree/selector-interpolated.ts +95 -0
  144. package/src/tree/selector-list.ts +245 -0
  145. package/src/tree/selector-pseudo.ts +173 -0
  146. package/src/tree/selector-simple.ts +10 -0
  147. package/src/tree/selector.ts +152 -0
  148. package/src/tree/sequence.ts +463 -0
  149. package/src/tree/tree.ts +130 -0
  150. package/src/tree/url.ts +95 -0
  151. package/src/tree/util/EXTEND_ARCHITECTURE_ANALYSIS.md +215 -0
  152. package/src/tree/util/EXTEND_AUDIT.md +233 -0
  153. package/src/tree/util/EXTEND_BASELINE.md +64 -0
  154. package/src/tree/util/EXTEND_CALL_GRAPH_ANALYSIS.md +244 -0
  155. package/src/tree/util/EXTEND_DOCS.md +24 -0
  156. package/src/tree/util/EXTEND_FINAL_SUMMARY.md +95 -0
  157. package/src/tree/util/EXTEND_FUNCTION_AUDIT.md +1433 -0
  158. package/src/tree/util/EXTEND_OPTIMIZATION_PLAN.md +114 -0
  159. package/src/tree/util/EXTEND_REFACTORING_SUMMARY.md +152 -0
  160. package/src/tree/util/EXTEND_RULES.md +74 -0
  161. package/src/tree/util/EXTEND_UNUSED_FUNCTIONS.md +127 -0
  162. package/src/tree/util/EXTEND_UNUSED_FUNCTIONS_ANALYSIS.md +227 -0
  163. package/src/tree/util/NODE_COPY_REDUCTION_PLAN.md +12 -0
  164. package/src/tree/util/__tests__/EXTEND_TEST_INDEX.md +59 -0
  165. package/src/tree/util/__tests__/OPTIMIZATION-ANALYSIS.md +130 -0
  166. package/src/tree/util/__tests__/WALK_AND_CONSUME_DESIGN.md +138 -0
  167. package/src/tree/util/__tests__/_archive/2026-02-09__OPTIMIZATION-ANALYSIS.md +9 -0
  168. package/src/tree/util/__tests__/_archive/README.md +4 -0
  169. package/src/tree/util/__tests__/bitset.test.ts +142 -0
  170. package/src/tree/util/__tests__/debug-log.ts +50 -0
  171. package/src/tree/util/__tests__/extend-comment-handling.test.ts +187 -0
  172. package/src/tree/util/__tests__/extend-core-unit.test.ts +941 -0
  173. package/src/tree/util/__tests__/extend-pipeline-bench.test.ts +154 -0
  174. package/src/tree/util/__tests__/extend-pipeline-bench.ts +190 -0
  175. package/src/tree/util/__tests__/fast-reject.test.ts +377 -0
  176. package/src/tree/util/__tests__/is-node.test.ts +63 -0
  177. package/src/tree/util/__tests__/list-like.test.ts +63 -0
  178. package/src/tree/util/__tests__/outputwriter.test.ts +523 -0
  179. package/src/tree/util/__tests__/print.test.ts +183 -0
  180. package/src/tree/util/__tests__/process-extends.test.ts +226 -0
  181. package/src/tree/util/__tests__/process-leading-is.test.ts +205 -0
  182. package/src/tree/util/__tests__/recursion-helper.test.ts +184 -0
  183. package/src/tree/util/__tests__/selector-match-unit.test.ts +1427 -0
  184. package/src/tree/util/__tests__/sourcemap.test.ts +117 -0
  185. package/src/tree/util/ampersand-template.ts +9 -0
  186. package/src/tree/util/bitset.ts +194 -0
  187. package/src/tree/util/calculate.ts +11 -0
  188. package/src/tree/util/cast.ts +89 -0
  189. package/src/tree/util/cloning.ts +8 -0
  190. package/src/tree/util/collections.ts +299 -0
  191. package/src/tree/util/compare.ts +90 -0
  192. package/src/tree/util/cursor.ts +171 -0
  193. package/src/tree/util/extend-core.ts +2139 -0
  194. package/src/tree/util/extend-roots.ts +1108 -0
  195. package/src/tree/util/field-helpers.ts +354 -0
  196. package/src/tree/util/is-node.ts +43 -0
  197. package/src/tree/util/list-like.ts +93 -0
  198. package/src/tree/util/mixin-instance-primitives.ts +2020 -0
  199. package/src/tree/util/print.ts +303 -0
  200. package/src/tree/util/process-leading-is.ts +421 -0
  201. package/src/tree/util/recursion-helper.ts +54 -0
  202. package/src/tree/util/regex.ts +2 -0
  203. package/src/tree/util/registry-utils.ts +1953 -0
  204. package/src/tree/util/ruleset-trace.ts +17 -0
  205. package/src/tree/util/scoped-body-eval.ts +320 -0
  206. package/src/tree/util/selector-match-core.ts +2005 -0
  207. package/src/tree/util/selector-utils.ts +757 -0
  208. package/src/tree/util/serialize-helper.ts +535 -0
  209. package/src/tree/util/serialize-types.ts +318 -0
  210. package/src/tree/util/should-operate.ts +78 -0
  211. package/src/tree/util/sourcemap.ts +37 -0
  212. package/src/types/config.ts +247 -0
  213. package/src/types/index.ts +12 -0
  214. package/{lib/types/modes.d.ts → src/types/modes.ts} +2 -1
  215. package/src/types.d.ts +9 -0
  216. package/src/types.ts +68 -0
  217. package/src/use-webpack-resolver.ts +56 -0
  218. package/src/visitor/__tests__/visitor.test.ts +136 -0
  219. package/src/visitor/index.ts +263 -0
  220. package/{lib/visitor/less-visitor.js → src/visitor/less-visitor.ts} +3 -2
  221. package/lib/context.d.ts +0 -352
  222. package/lib/context.d.ts.map +0 -1
  223. package/lib/context.js +0 -636
  224. package/lib/context.js.map +0 -1
  225. package/lib/conversions.d.ts +0 -73
  226. package/lib/conversions.d.ts.map +0 -1
  227. package/lib/conversions.js +0 -253
  228. package/lib/conversions.js.map +0 -1
  229. package/lib/debug-log.d.ts +0 -2
  230. package/lib/debug-log.d.ts.map +0 -1
  231. package/lib/debug-log.js +0 -27
  232. package/lib/debug-log.js.map +0 -1
  233. package/lib/define-function.d.ts +0 -587
  234. package/lib/define-function.d.ts.map +0 -1
  235. package/lib/define-function.js +0 -726
  236. package/lib/define-function.js.map +0 -1
  237. package/lib/deprecation.d.ts +0 -34
  238. package/lib/deprecation.d.ts.map +0 -1
  239. package/lib/deprecation.js +0 -57
  240. package/lib/deprecation.js.map +0 -1
  241. package/lib/jess-error.d.ts +0 -343
  242. package/lib/jess-error.d.ts.map +0 -1
  243. package/lib/jess-error.js +0 -508
  244. package/lib/jess-error.js.map +0 -1
  245. package/lib/logger/deprecation-processing.d.ts +0 -41
  246. package/lib/logger/deprecation-processing.d.ts.map +0 -1
  247. package/lib/logger/deprecation-processing.js +0 -81
  248. package/lib/logger/deprecation-processing.js.map +0 -1
  249. package/lib/logger.d.ts +0 -10
  250. package/lib/logger.d.ts.map +0 -1
  251. package/lib/logger.js +0 -20
  252. package/lib/logger.js.map +0 -1
  253. package/lib/plugin.d.ts +0 -94
  254. package/lib/plugin.d.ts.map +0 -1
  255. package/lib/plugin.js +0 -174
  256. package/lib/plugin.js.map +0 -1
  257. package/lib/tree/ampersand.d.ts +0 -98
  258. package/lib/tree/ampersand.d.ts.map +0 -1
  259. package/lib/tree/ampersand.js +0 -319
  260. package/lib/tree/ampersand.js.map +0 -1
  261. package/lib/tree/any.d.ts +0 -58
  262. package/lib/tree/any.d.ts.map +0 -1
  263. package/lib/tree/any.js +0 -104
  264. package/lib/tree/any.js.map +0 -1
  265. package/lib/tree/at-rule.d.ts +0 -53
  266. package/lib/tree/at-rule.d.ts.map +0 -1
  267. package/lib/tree/at-rule.js +0 -503
  268. package/lib/tree/at-rule.js.map +0 -1
  269. package/lib/tree/block.d.ts +0 -22
  270. package/lib/tree/block.d.ts.map +0 -1
  271. package/lib/tree/block.js +0 -24
  272. package/lib/tree/block.js.map +0 -1
  273. package/lib/tree/bool.d.ts +0 -18
  274. package/lib/tree/bool.d.ts.map +0 -1
  275. package/lib/tree/bool.js +0 -28
  276. package/lib/tree/bool.js.map +0 -1
  277. package/lib/tree/call.d.ts +0 -66
  278. package/lib/tree/call.d.ts.map +0 -1
  279. package/lib/tree/call.js +0 -306
  280. package/lib/tree/call.js.map +0 -1
  281. package/lib/tree/collection.d.ts +0 -30
  282. package/lib/tree/collection.d.ts.map +0 -1
  283. package/lib/tree/collection.js +0 -37
  284. package/lib/tree/collection.js.map +0 -1
  285. package/lib/tree/color.d.ts +0 -101
  286. package/lib/tree/color.d.ts.map +0 -1
  287. package/lib/tree/color.js +0 -513
  288. package/lib/tree/color.js.map +0 -1
  289. package/lib/tree/combinator.d.ts +0 -13
  290. package/lib/tree/combinator.d.ts.map +0 -1
  291. package/lib/tree/combinator.js +0 -12
  292. package/lib/tree/combinator.js.map +0 -1
  293. package/lib/tree/comment.d.ts +0 -20
  294. package/lib/tree/comment.d.ts.map +0 -1
  295. package/lib/tree/comment.js +0 -19
  296. package/lib/tree/comment.js.map +0 -1
  297. package/lib/tree/condition.d.ts +0 -31
  298. package/lib/tree/condition.d.ts.map +0 -1
  299. package/lib/tree/condition.js +0 -103
  300. package/lib/tree/condition.js.map +0 -1
  301. package/lib/tree/control.d.ts +0 -104
  302. package/lib/tree/control.d.ts.map +0 -1
  303. package/lib/tree/control.js +0 -430
  304. package/lib/tree/control.js.map +0 -1
  305. package/lib/tree/declaration-custom.d.ts +0 -18
  306. package/lib/tree/declaration-custom.d.ts.map +0 -1
  307. package/lib/tree/declaration-custom.js +0 -24
  308. package/lib/tree/declaration-custom.js.map +0 -1
  309. package/lib/tree/declaration-var.d.ts +0 -35
  310. package/lib/tree/declaration-var.d.ts.map +0 -1
  311. package/lib/tree/declaration-var.js +0 -63
  312. package/lib/tree/declaration-var.js.map +0 -1
  313. package/lib/tree/declaration.d.ts +0 -78
  314. package/lib/tree/declaration.d.ts.map +0 -1
  315. package/lib/tree/declaration.js +0 -286
  316. package/lib/tree/declaration.js.map +0 -1
  317. package/lib/tree/default-guard.d.ts +0 -15
  318. package/lib/tree/default-guard.d.ts.map +0 -1
  319. package/lib/tree/default-guard.js +0 -19
  320. package/lib/tree/default-guard.js.map +0 -1
  321. package/lib/tree/dimension.d.ts +0 -34
  322. package/lib/tree/dimension.d.ts.map +0 -1
  323. package/lib/tree/dimension.js +0 -294
  324. package/lib/tree/dimension.js.map +0 -1
  325. package/lib/tree/expression.d.ts +0 -25
  326. package/lib/tree/expression.d.ts.map +0 -1
  327. package/lib/tree/expression.js +0 -32
  328. package/lib/tree/expression.js.map +0 -1
  329. package/lib/tree/extend-list.d.ts +0 -23
  330. package/lib/tree/extend-list.d.ts.map +0 -1
  331. package/lib/tree/extend-list.js +0 -23
  332. package/lib/tree/extend-list.js.map +0 -1
  333. package/lib/tree/extend.d.ts +0 -47
  334. package/lib/tree/extend.d.ts.map +0 -1
  335. package/lib/tree/extend.js +0 -296
  336. package/lib/tree/extend.js.map +0 -1
  337. package/lib/tree/function.d.ts +0 -48
  338. package/lib/tree/function.d.ts.map +0 -1
  339. package/lib/tree/function.js +0 -74
  340. package/lib/tree/function.js.map +0 -1
  341. package/lib/tree/import-js.d.ts +0 -35
  342. package/lib/tree/import-js.d.ts.map +0 -1
  343. package/lib/tree/import-js.js +0 -45
  344. package/lib/tree/import-js.js.map +0 -1
  345. package/lib/tree/import-style.d.ts +0 -156
  346. package/lib/tree/import-style.d.ts.map +0 -1
  347. package/lib/tree/import-style.js +0 -566
  348. package/lib/tree/import-style.js.map +0 -1
  349. package/lib/tree/index.d.ts +0 -71
  350. package/lib/tree/index.d.ts.map +0 -1
  351. package/lib/tree/index.js.map +0 -1
  352. package/lib/tree/interpolated-reference.d.ts +0 -24
  353. package/lib/tree/interpolated-reference.d.ts.map +0 -1
  354. package/lib/tree/interpolated-reference.js +0 -37
  355. package/lib/tree/interpolated-reference.js.map +0 -1
  356. package/lib/tree/interpolated.d.ts +0 -62
  357. package/lib/tree/interpolated.d.ts.map +0 -1
  358. package/lib/tree/interpolated.js +0 -204
  359. package/lib/tree/interpolated.js.map +0 -1
  360. package/lib/tree/js-array.d.ts +0 -10
  361. package/lib/tree/js-array.d.ts.map +0 -1
  362. package/lib/tree/js-array.js +0 -10
  363. package/lib/tree/js-array.js.map +0 -1
  364. package/lib/tree/js-expr.d.ts +0 -23
  365. package/lib/tree/js-expr.d.ts.map +0 -1
  366. package/lib/tree/js-expr.js +0 -28
  367. package/lib/tree/js-expr.js.map +0 -1
  368. package/lib/tree/js-function.d.ts +0 -20
  369. package/lib/tree/js-function.d.ts.map +0 -1
  370. package/lib/tree/js-function.js +0 -16
  371. package/lib/tree/js-function.js.map +0 -1
  372. package/lib/tree/js-object.d.ts +0 -10
  373. package/lib/tree/js-object.d.ts.map +0 -1
  374. package/lib/tree/js-object.js +0 -10
  375. package/lib/tree/js-object.js.map +0 -1
  376. package/lib/tree/list.d.ts +0 -38
  377. package/lib/tree/list.d.ts.map +0 -1
  378. package/lib/tree/list.js +0 -83
  379. package/lib/tree/list.js.map +0 -1
  380. package/lib/tree/log.d.ts +0 -29
  381. package/lib/tree/log.d.ts.map +0 -1
  382. package/lib/tree/log.js +0 -56
  383. package/lib/tree/log.js.map +0 -1
  384. package/lib/tree/mixin.d.ts +0 -87
  385. package/lib/tree/mixin.d.ts.map +0 -1
  386. package/lib/tree/mixin.js +0 -112
  387. package/lib/tree/mixin.js.map +0 -1
  388. package/lib/tree/negative.d.ts +0 -17
  389. package/lib/tree/negative.d.ts.map +0 -1
  390. package/lib/tree/negative.js +0 -22
  391. package/lib/tree/negative.js.map +0 -1
  392. package/lib/tree/nil.d.ts +0 -30
  393. package/lib/tree/nil.d.ts.map +0 -1
  394. package/lib/tree/nil.js +0 -35
  395. package/lib/tree/nil.js.map +0 -1
  396. package/lib/tree/node-base.d.ts +0 -361
  397. package/lib/tree/node-base.d.ts.map +0 -1
  398. package/lib/tree/node-base.js +0 -930
  399. package/lib/tree/node-base.js.map +0 -1
  400. package/lib/tree/node.d.ts +0 -10
  401. package/lib/tree/node.d.ts.map +0 -1
  402. package/lib/tree/node.js +0 -45
  403. package/lib/tree/node.js.map +0 -1
  404. package/lib/tree/number.d.ts +0 -21
  405. package/lib/tree/number.d.ts.map +0 -1
  406. package/lib/tree/number.js +0 -27
  407. package/lib/tree/number.js.map +0 -1
  408. package/lib/tree/operation.d.ts +0 -26
  409. package/lib/tree/operation.d.ts.map +0 -1
  410. package/lib/tree/operation.js +0 -103
  411. package/lib/tree/operation.js.map +0 -1
  412. package/lib/tree/paren.d.ts +0 -19
  413. package/lib/tree/paren.d.ts.map +0 -1
  414. package/lib/tree/paren.js +0 -92
  415. package/lib/tree/paren.js.map +0 -1
  416. package/lib/tree/query-condition.d.ts +0 -17
  417. package/lib/tree/query-condition.d.ts.map +0 -1
  418. package/lib/tree/query-condition.js +0 -39
  419. package/lib/tree/query-condition.js.map +0 -1
  420. package/lib/tree/quoted.d.ts +0 -28
  421. package/lib/tree/quoted.d.ts.map +0 -1
  422. package/lib/tree/quoted.js +0 -75
  423. package/lib/tree/quoted.js.map +0 -1
  424. package/lib/tree/range.d.ts +0 -33
  425. package/lib/tree/range.d.ts.map +0 -1
  426. package/lib/tree/range.js +0 -47
  427. package/lib/tree/range.js.map +0 -1
  428. package/lib/tree/reference.d.ts +0 -76
  429. package/lib/tree/reference.d.ts.map +0 -1
  430. package/lib/tree/reference.js +0 -521
  431. package/lib/tree/reference.js.map +0 -1
  432. package/lib/tree/rest.d.ts +0 -15
  433. package/lib/tree/rest.d.ts.map +0 -1
  434. package/lib/tree/rest.js +0 -32
  435. package/lib/tree/rest.js.map +0 -1
  436. package/lib/tree/rules-raw.d.ts +0 -17
  437. package/lib/tree/rules-raw.d.ts.map +0 -1
  438. package/lib/tree/rules-raw.js +0 -37
  439. package/lib/tree/rules-raw.js.map +0 -1
  440. package/lib/tree/rules.d.ts +0 -262
  441. package/lib/tree/rules.d.ts.map +0 -1
  442. package/lib/tree/rules.js +0 -2359
  443. package/lib/tree/rules.js.map +0 -1
  444. package/lib/tree/ruleset.d.ts +0 -92
  445. package/lib/tree/ruleset.d.ts.map +0 -1
  446. package/lib/tree/ruleset.js +0 -528
  447. package/lib/tree/ruleset.js.map +0 -1
  448. package/lib/tree/selector-attr.d.ts +0 -31
  449. package/lib/tree/selector-attr.d.ts.map +0 -1
  450. package/lib/tree/selector-attr.js +0 -99
  451. package/lib/tree/selector-attr.js.map +0 -1
  452. package/lib/tree/selector-basic.d.ts +0 -24
  453. package/lib/tree/selector-basic.d.ts.map +0 -1
  454. package/lib/tree/selector-basic.js +0 -38
  455. package/lib/tree/selector-basic.js.map +0 -1
  456. package/lib/tree/selector-capture.d.ts +0 -23
  457. package/lib/tree/selector-capture.d.ts.map +0 -1
  458. package/lib/tree/selector-capture.js +0 -34
  459. package/lib/tree/selector-capture.js.map +0 -1
  460. package/lib/tree/selector-complex.d.ts +0 -40
  461. package/lib/tree/selector-complex.d.ts.map +0 -1
  462. package/lib/tree/selector-complex.js +0 -143
  463. package/lib/tree/selector-complex.js.map +0 -1
  464. package/lib/tree/selector-compound.d.ts +0 -16
  465. package/lib/tree/selector-compound.d.ts.map +0 -1
  466. package/lib/tree/selector-compound.js +0 -114
  467. package/lib/tree/selector-compound.js.map +0 -1
  468. package/lib/tree/selector-interpolated.d.ts +0 -23
  469. package/lib/tree/selector-interpolated.d.ts.map +0 -1
  470. package/lib/tree/selector-interpolated.js +0 -27
  471. package/lib/tree/selector-interpolated.js.map +0 -1
  472. package/lib/tree/selector-list.d.ts +0 -17
  473. package/lib/tree/selector-list.d.ts.map +0 -1
  474. package/lib/tree/selector-list.js +0 -174
  475. package/lib/tree/selector-list.js.map +0 -1
  476. package/lib/tree/selector-pseudo.d.ts +0 -42
  477. package/lib/tree/selector-pseudo.d.ts.map +0 -1
  478. package/lib/tree/selector-pseudo.js +0 -204
  479. package/lib/tree/selector-pseudo.js.map +0 -1
  480. package/lib/tree/selector-simple.d.ts +0 -5
  481. package/lib/tree/selector-simple.d.ts.map +0 -1
  482. package/lib/tree/selector-simple.js +0 -6
  483. package/lib/tree/selector-simple.js.map +0 -1
  484. package/lib/tree/selector.d.ts +0 -43
  485. package/lib/tree/selector.d.ts.map +0 -1
  486. package/lib/tree/selector.js +0 -56
  487. package/lib/tree/selector.js.map +0 -1
  488. package/lib/tree/sequence.d.ts +0 -43
  489. package/lib/tree/sequence.d.ts.map +0 -1
  490. package/lib/tree/sequence.js +0 -151
  491. package/lib/tree/sequence.js.map +0 -1
  492. package/lib/tree/tree.d.ts +0 -87
  493. package/lib/tree/tree.d.ts.map +0 -1
  494. package/lib/tree/tree.js +0 -2
  495. package/lib/tree/tree.js.map +0 -1
  496. package/lib/tree/url.d.ts +0 -18
  497. package/lib/tree/url.d.ts.map +0 -1
  498. package/lib/tree/url.js +0 -35
  499. package/lib/tree/url.js.map +0 -1
  500. package/lib/tree/util/__tests__/debug-log.d.ts +0 -1
  501. package/lib/tree/util/__tests__/debug-log.d.ts.map +0 -1
  502. package/lib/tree/util/__tests__/debug-log.js +0 -36
  503. package/lib/tree/util/__tests__/debug-log.js.map +0 -1
  504. package/lib/tree/util/calculate.d.ts +0 -3
  505. package/lib/tree/util/calculate.d.ts.map +0 -1
  506. package/lib/tree/util/calculate.js +0 -10
  507. package/lib/tree/util/calculate.js.map +0 -1
  508. package/lib/tree/util/cast.d.ts +0 -10
  509. package/lib/tree/util/cast.d.ts.map +0 -1
  510. package/lib/tree/util/cast.js +0 -87
  511. package/lib/tree/util/cast.js.map +0 -1
  512. package/lib/tree/util/cloning.d.ts +0 -4
  513. package/lib/tree/util/cloning.d.ts.map +0 -1
  514. package/lib/tree/util/cloning.js +0 -8
  515. package/lib/tree/util/cloning.js.map +0 -1
  516. package/lib/tree/util/collections.d.ts +0 -57
  517. package/lib/tree/util/collections.d.ts.map +0 -1
  518. package/lib/tree/util/collections.js +0 -136
  519. package/lib/tree/util/collections.js.map +0 -1
  520. package/lib/tree/util/compare.d.ts +0 -11
  521. package/lib/tree/util/compare.d.ts.map +0 -1
  522. package/lib/tree/util/compare.js +0 -89
  523. package/lib/tree/util/compare.js.map +0 -1
  524. package/lib/tree/util/extend-helpers.d.ts +0 -2
  525. package/lib/tree/util/extend-helpers.d.ts.map +0 -1
  526. package/lib/tree/util/extend-helpers.js +0 -2
  527. package/lib/tree/util/extend-helpers.js.map +0 -1
  528. package/lib/tree/util/extend-roots.d.ts +0 -37
  529. package/lib/tree/util/extend-roots.d.ts.map +0 -1
  530. package/lib/tree/util/extend-roots.js +0 -700
  531. package/lib/tree/util/extend-roots.js.map +0 -1
  532. package/lib/tree/util/extend-roots.old.d.ts +0 -132
  533. package/lib/tree/util/extend-roots.old.d.ts.map +0 -1
  534. package/lib/tree/util/extend-roots.old.js +0 -2272
  535. package/lib/tree/util/extend-roots.old.js.map +0 -1
  536. package/lib/tree/util/extend-trace-debug.d.ts +0 -13
  537. package/lib/tree/util/extend-trace-debug.d.ts.map +0 -1
  538. package/lib/tree/util/extend-trace-debug.js +0 -34
  539. package/lib/tree/util/extend-trace-debug.js.map +0 -1
  540. package/lib/tree/util/extend-walk.d.ts +0 -53
  541. package/lib/tree/util/extend-walk.d.ts.map +0 -1
  542. package/lib/tree/util/extend-walk.js +0 -881
  543. package/lib/tree/util/extend-walk.js.map +0 -1
  544. package/lib/tree/util/extend.d.ts +0 -218
  545. package/lib/tree/util/extend.d.ts.map +0 -1
  546. package/lib/tree/util/extend.js +0 -3182
  547. package/lib/tree/util/extend.js.map +0 -1
  548. package/lib/tree/util/find-extendable-locations.d.ts +0 -2
  549. package/lib/tree/util/find-extendable-locations.d.ts.map +0 -1
  550. package/lib/tree/util/find-extendable-locations.js +0 -2
  551. package/lib/tree/util/find-extendable-locations.js.map +0 -1
  552. package/lib/tree/util/format.d.ts +0 -20
  553. package/lib/tree/util/format.d.ts.map +0 -1
  554. package/lib/tree/util/format.js +0 -67
  555. package/lib/tree/util/format.js.map +0 -1
  556. package/lib/tree/util/is-node.d.ts +0 -13
  557. package/lib/tree/util/is-node.d.ts.map +0 -1
  558. package/lib/tree/util/is-node.js +0 -43
  559. package/lib/tree/util/is-node.js.map +0 -1
  560. package/lib/tree/util/print.d.ts +0 -80
  561. package/lib/tree/util/print.d.ts.map +0 -1
  562. package/lib/tree/util/print.js +0 -205
  563. package/lib/tree/util/print.js.map +0 -1
  564. package/lib/tree/util/process-leading-is.d.ts +0 -25
  565. package/lib/tree/util/process-leading-is.d.ts.map +0 -1
  566. package/lib/tree/util/process-leading-is.js +0 -364
  567. package/lib/tree/util/process-leading-is.js.map +0 -1
  568. package/lib/tree/util/recursion-helper.d.ts +0 -15
  569. package/lib/tree/util/recursion-helper.d.ts.map +0 -1
  570. package/lib/tree/util/recursion-helper.js +0 -43
  571. package/lib/tree/util/recursion-helper.js.map +0 -1
  572. package/lib/tree/util/regex.d.ts +0 -4
  573. package/lib/tree/util/regex.d.ts.map +0 -1
  574. package/lib/tree/util/regex.js +0 -4
  575. package/lib/tree/util/regex.js.map +0 -1
  576. package/lib/tree/util/registry-utils.d.ts +0 -192
  577. package/lib/tree/util/registry-utils.d.ts.map +0 -1
  578. package/lib/tree/util/registry-utils.js +0 -1214
  579. package/lib/tree/util/registry-utils.js.map +0 -1
  580. package/lib/tree/util/ruleset-trace.d.ts +0 -4
  581. package/lib/tree/util/ruleset-trace.d.ts.map +0 -1
  582. package/lib/tree/util/ruleset-trace.js +0 -14
  583. package/lib/tree/util/ruleset-trace.js.map +0 -1
  584. package/lib/tree/util/selector-compare.d.ts +0 -2
  585. package/lib/tree/util/selector-compare.d.ts.map +0 -1
  586. package/lib/tree/util/selector-compare.js +0 -2
  587. package/lib/tree/util/selector-compare.js.map +0 -1
  588. package/lib/tree/util/selector-match-core.d.ts +0 -184
  589. package/lib/tree/util/selector-match-core.d.ts.map +0 -1
  590. package/lib/tree/util/selector-match-core.js +0 -1603
  591. package/lib/tree/util/selector-match-core.js.map +0 -1
  592. package/lib/tree/util/selector-utils.d.ts +0 -30
  593. package/lib/tree/util/selector-utils.d.ts.map +0 -1
  594. package/lib/tree/util/selector-utils.js +0 -100
  595. package/lib/tree/util/selector-utils.js.map +0 -1
  596. package/lib/tree/util/serialize-helper.d.ts +0 -13
  597. package/lib/tree/util/serialize-helper.d.ts.map +0 -1
  598. package/lib/tree/util/serialize-helper.js +0 -387
  599. package/lib/tree/util/serialize-helper.js.map +0 -1
  600. package/lib/tree/util/serialize-types.d.ts +0 -9
  601. package/lib/tree/util/serialize-types.d.ts.map +0 -1
  602. package/lib/tree/util/serialize-types.js +0 -216
  603. package/lib/tree/util/serialize-types.js.map +0 -1
  604. package/lib/tree/util/should-operate.d.ts +0 -23
  605. package/lib/tree/util/should-operate.d.ts.map +0 -1
  606. package/lib/tree/util/should-operate.js +0 -46
  607. package/lib/tree/util/should-operate.js.map +0 -1
  608. package/lib/tree/util/sourcemap.d.ts +0 -7
  609. package/lib/tree/util/sourcemap.d.ts.map +0 -1
  610. package/lib/tree/util/sourcemap.js +0 -25
  611. package/lib/tree/util/sourcemap.js.map +0 -1
  612. package/lib/types/config.d.ts +0 -205
  613. package/lib/types/config.d.ts.map +0 -1
  614. package/lib/types/config.js +0 -2
  615. package/lib/types/config.js.map +0 -1
  616. package/lib/types/index.d.ts +0 -15
  617. package/lib/types/index.d.ts.map +0 -1
  618. package/lib/types/index.js +0 -3
  619. package/lib/types/index.js.map +0 -1
  620. package/lib/types/modes.d.ts.map +0 -1
  621. package/lib/types/modes.js +0 -2
  622. package/lib/types/modes.js.map +0 -1
  623. package/lib/types.d.ts +0 -61
  624. package/lib/types.d.ts.map +0 -1
  625. package/lib/types.js +0 -2
  626. package/lib/types.js.map +0 -1
  627. package/lib/use-webpack-resolver.d.ts +0 -9
  628. package/lib/use-webpack-resolver.d.ts.map +0 -1
  629. package/lib/use-webpack-resolver.js +0 -41
  630. package/lib/use-webpack-resolver.js.map +0 -1
  631. package/lib/visitor/index.d.ts +0 -136
  632. package/lib/visitor/index.d.ts.map +0 -1
  633. package/lib/visitor/index.js +0 -135
  634. package/lib/visitor/index.js.map +0 -1
  635. package/lib/visitor/less-visitor.d.ts +0 -7
  636. package/lib/visitor/less-visitor.d.ts.map +0 -1
  637. package/lib/visitor/less-visitor.js.map +0 -1
@@ -0,0 +1,538 @@
1
+ import { defineType, type NodeOptions, type OptionalLocation, type TreeContext, F_AMPERSAND, F_IMPLICIT_AMPERSAND, type Node } from './node.js';
2
+ import { Nil } from './nil.js';
3
+ import type { Context } from '../context.js';
4
+ import { SimpleSelector } from './selector-simple.js';
5
+ import { PseudoSelector } from './selector-pseudo.js';
6
+ import { SelectorList } from './selector-list.js';
7
+ import { BasicSelector } from './selector-basic.js';
8
+ import { isNode } from './util/is-node.js';
9
+ import { N } from './node-type.js';
10
+ import { type Selector } from './selector.js';
11
+ import { atIndex } from './util/collections.js';
12
+ import { type PrintOptions, getPrintOptions } from './util/print.js';
13
+ import { AMPERSAND_TEMPLATE_CONTENTS_REGEX } from './util/ampersand-template.js';
14
+ import { wrapParentSelectorForNestedContext } from './util/selector-utils.js';
15
+
16
+ const ampersandTemplateInterpolationRegex = /[$@]\{[^}]+\}/g;
17
+ const ampersandTemplateRegex = new RegExp(`^(?:${AMPERSAND_TEMPLATE_CONTENTS_REGEX.source})$`);
18
+
19
+ function isSelectorNode(value: unknown): value is Selector {
20
+ return isNode(value, N.Selector);
21
+ }
22
+
23
+ function isSelectorListNode(value: unknown): value is SelectorList {
24
+ return isNode(value, N.SelectorList);
25
+ }
26
+
27
+ function isNilNode(value: unknown): value is Nil {
28
+ return isNode(value, N.Nil);
29
+ }
30
+
31
+ export type AmpersandValue = {
32
+ /**
33
+ * The only value that may exist is an anonymous value
34
+ * This is represented as &(). Any &() will signal
35
+ * a forced output (as well as an adjacent ident starting with
36
+ * a dash or numbers)
37
+ *
38
+ * @example
39
+ .rule {
40
+ &-foo {
41
+ color: red;
42
+ }
43
+ }
44
+ // output:
45
+ .rule-foo {
46
+ color: red;
47
+ }
48
+
49
+ .rule {
50
+ &(-foo) {
51
+ color: red;
52
+ }
53
+ }
54
+ // output:
55
+ .rule-foo {
56
+ color: red;
57
+ }
58
+
59
+ .rule {
60
+ &.foo {
61
+ color: red;
62
+ }
63
+ }
64
+ // output:
65
+ .rule {
66
+ &.foo {
67
+ color: red;
68
+ }
69
+ }
70
+
71
+ .rule {
72
+ &().foo {
73
+ color: red;
74
+ }
75
+ }
76
+ // output:
77
+ .rule.foo {
78
+ color: red;
79
+ }
80
+
81
+ *
82
+ * `undefined` => plain `&`
83
+ * `''` => `&()` root-hoist while still rendering the parent
84
+ * `string` => `&(template)` / `&-suffix`
85
+ * `Nil` => `&(nil)` and suppress the parent entirely
86
+ *
87
+ * A template without an `&` is shorthand for replacing the parent selector
88
+ * at the same location. So `template: '-1'` means the `&-1` form.
89
+ */
90
+ template?: string | Nil;
91
+ /** @deprecated Use `template` */
92
+ appendValue?: string | Nil;
93
+
94
+ /**
95
+ * When set (e.g. by ruleset preEval), returns the current parent ruleset's selector ("pointer").
96
+ * Prefer this over value.selector so extend sees the parent after it has been mutated (e.g. by extend).
97
+ */
98
+ selectorContainer?: {
99
+ selector?: Selector | Nil | undefined;
100
+ getEffectiveSelector?: (collapseNesting?: boolean, context?: Context) => Selector | Nil | undefined;
101
+ };
102
+ };
103
+
104
+ type SelectorContainer = NonNullable<AmpersandValue['selectorContainer']>;
105
+
106
+ function getSelectorFromContainer(
107
+ selectorContainer: SelectorContainer | undefined,
108
+ context?: Context
109
+ ): Selector | Nil | undefined {
110
+ if (!selectorContainer) {
111
+ return undefined;
112
+ }
113
+ if (typeof selectorContainer.getEffectiveSelector === 'function') {
114
+ return selectorContainer.getEffectiveSelector(false, context);
115
+ }
116
+ return selectorContainer.selector;
117
+ }
118
+
119
+ function cloneStoredSelector(
120
+ storedSelector: Selector | Nil | undefined,
121
+ deep?: boolean
122
+ ): Selector | Nil | undefined {
123
+ if (!isSelectorNode(storedSelector)) {
124
+ return storedSelector;
125
+ }
126
+ const storedClone = storedSelector.clone(deep);
127
+ const sourceLibrary = storedSelector.keySetLibrary;
128
+ if (sourceLibrary && isSelectorNode(storedClone)) {
129
+ storedClone.keySetLibrary = sourceLibrary;
130
+ for (const child of storedClone.children(true)) {
131
+ if (isSelectorNode(child)) {
132
+ child.keySetLibrary = sourceLibrary;
133
+ }
134
+ }
135
+ }
136
+ return storedClone;
137
+ }
138
+
139
+ /**
140
+ * The '&' selector element
141
+ */
142
+ export interface Ampersand {
143
+ type: 'Ampersand';
144
+ shortType: 'amp';
145
+ }
146
+ export class Ampersand extends SimpleSelector<{ template?: string | Nil }> {
147
+ static override childKeys = null as null;
148
+
149
+ template: string | Nil | undefined;
150
+
151
+ private _storedSelector: Selector | Nil | undefined;
152
+ private _selectorContainer: SelectorContainer | undefined;
153
+
154
+ private _getSelector(context?: Context): Selector | Nil | undefined {
155
+ if (!context) {
156
+ return this._storedSelector;
157
+ }
158
+ return getSelectorFromContainer(this._selectorContainer, context) ?? this._storedSelector;
159
+ }
160
+
161
+ constructor(
162
+ value?: AmpersandValue | string | Nil,
163
+ options?: NodeOptions,
164
+ location?: OptionalLocation,
165
+ treeContext?: TreeContext
166
+ ) {
167
+ let finalTemplate: string | Nil | undefined;
168
+ if (typeof value === 'string' || value instanceof Nil) {
169
+ finalTemplate = value;
170
+ super({ template: value }, options, location, treeContext);
171
+ } else {
172
+ finalTemplate = value?.template ?? value?.appendValue;
173
+ super(value ?? {}, options, location, treeContext);
174
+ const selectorContainer = value?.selectorContainer;
175
+ if (selectorContainer) {
176
+ this._selectorContainer = selectorContainer;
177
+ const storedSelector = getSelectorFromContainer(selectorContainer);
178
+ this._storedSelector = cloneStoredSelector(storedSelector, true);
179
+ }
180
+ }
181
+ this.template = finalTemplate;
182
+ if (finalTemplate instanceof Nil) {
183
+ this.adopt(finalTemplate);
184
+ }
185
+
186
+ // Set the F_AMPERSAND flag so it bubbles up to parent selectors
187
+ this.addFlag(F_AMPERSAND);
188
+ }
189
+
190
+ isPlainAmpersand(): boolean {
191
+ return this.template === undefined;
192
+ }
193
+
194
+ omitsParent(): boolean {
195
+ return isNilNode(this.template);
196
+ }
197
+
198
+ get appendValue(): string | Nil | undefined {
199
+ return this.template;
200
+ }
201
+
202
+ set appendValue(value: string | Nil | undefined) {
203
+ this.template = value;
204
+ if (value instanceof Nil) {
205
+ this.adopt(value);
206
+ }
207
+ }
208
+
209
+ override computeKeySets(): void {
210
+ let library = this.keySetLibrary!;
211
+ const stored = this._storedSelector;
212
+ const current = this._getSelector();
213
+ let keySet = this._keySet;
214
+ /** Ampersands don't participate to the visible key set */
215
+ if (!this._visibleKeySet) {
216
+ this._visibleKeySet = library.getBitset();
217
+ }
218
+ if (!this._requiredKeySet) {
219
+ this._requiredKeySet = library.getBitset();
220
+ }
221
+ if (!current || isNode(current, N.Nil)) {
222
+ if (!keySet) {
223
+ this._keySet = library.getBitset();
224
+ }
225
+ return;
226
+ }
227
+ if (!keySet || stored !== current) {
228
+ this._keySet = current.keySet;
229
+ }
230
+ }
231
+
232
+ override getKeySet(context?: Context) {
233
+ if (!context) {
234
+ return this.keySet;
235
+ }
236
+
237
+ const current = this._getSelector(context);
238
+ if (!current || isNode(current, N.Nil)) {
239
+ const library = this.keySetLibrary;
240
+ if (!library) {
241
+ throw new Error('Selector keySet library not found');
242
+ }
243
+ return library.getBitset();
244
+ }
245
+
246
+ return current.getKeySet(context);
247
+ }
248
+
249
+ /**
250
+ * Returns the current selector from the selector container (live when container is ruleset value).
251
+ * Used by extend, serialization, and matching so nested rules see the parent after extend.
252
+ */
253
+ getResolvedSelector(context?: Context): Selector | Nil | undefined {
254
+ const selector = this._getSelector(context);
255
+ if (isSelectorNode(selector) && this.hasFlag(F_IMPLICIT_AMPERSAND)) {
256
+ return wrapParentSelectorForNestedContext(selector);
257
+ }
258
+ return selector;
259
+ }
260
+
261
+ override valueOf(context?: Context) {
262
+ const selector = this._getSelector(context);
263
+ if (selector) {
264
+ return selector.valueOf();
265
+ }
266
+ return '&';
267
+ }
268
+
269
+ override toTrimmedString(options?: PrintOptions): string {
270
+ options = getPrintOptions(options);
271
+ const w = options.writer!;
272
+ const mark = w.mark();
273
+ const { template } = this;
274
+ if (template !== undefined) {
275
+ w.add('&(');
276
+ if (isNilNode(template)) {
277
+ w.add('nil', this);
278
+ } else if (typeof template === 'string' && template) {
279
+ w.add(template, this);
280
+ }
281
+ w.add(')');
282
+ } else {
283
+ w.add('&', this);
284
+ }
285
+ return w.getSince(mark);
286
+ }
287
+
288
+ /**
289
+ * Split a string on commas that aren't inside brackets, parens, or quotes.
290
+ */
291
+ private static splitTopLevelCommas(str: string): string[] {
292
+ const items: string[] = [];
293
+ let depth = 0;
294
+ let inQuote: string | null = null;
295
+ let start = 0;
296
+ for (let i = 0; i < str.length; i++) {
297
+ const ch = str[i]!;
298
+ if (inQuote) {
299
+ if (ch === inQuote && str[i - 1] !== '\\') {
300
+ inQuote = null;
301
+ }
302
+ } else if (ch === '\'' || ch === String.fromCharCode(34)) {
303
+ inQuote = ch;
304
+ } else if (ch === '(' || ch === '[') {
305
+ depth++;
306
+ } else if (ch === ')' || ch === ']') {
307
+ depth--;
308
+ } else if (ch === ',' && depth === 0) {
309
+ const item = str.slice(start, i).trim();
310
+ if (item) {
311
+ items.push(item);
312
+ }
313
+ start = i + 1;
314
+ }
315
+ }
316
+ const last = str.slice(start).trim();
317
+ if (last) {
318
+ items.push(last);
319
+ }
320
+ return items;
321
+ }
322
+
323
+ /** Hmm this should never return Extend */
324
+ override evalNode(context: Context): Selector | Nil {
325
+ this.keySetLibrary = context.selectorBits;
326
+ const template = this.template;
327
+ const hoistToRoot = this.hoistToRoot;
328
+ const selectorContainer = this._selectorContainer;
329
+ const storedSelector = getSelectorFromContainer(selectorContainer, context);
330
+ // Check if template is defined (including empty string), or if hoistToRoot/collapseNesting is set
331
+ if (template !== undefined || hoistToRoot || context.opts.collapseNesting) {
332
+ // Use the stored selector if available, otherwise fall back to frame selector
333
+ let frame = atIndex(context.rulesetFrames, -1);
334
+ let selector = storedSelector ?? frame?.getEffectiveSelector?.(false, context) ?? frame?.get('selector');
335
+ if (isNilNode(template)) {
336
+ const result = new Nil(undefined, undefined, undefined, this.treeContext);
337
+ result.hoistToRoot = true;
338
+ return result;
339
+ }
340
+ if (!selector) {
341
+ return new Nil();
342
+ }
343
+ // Collapse/hoist/template processing normalizes spacing and may rewrite
344
+ // selector contents, so never mutate the live parent selector in place.
345
+ if (isSelectorNode(selector)) {
346
+ selector = selector.copy(true);
347
+ }
348
+ /** Remove any surrounding whitespace */
349
+ selector.pre = undefined;
350
+ selector.post = undefined;
351
+
352
+ if (typeof template === 'string' && template && !isNode(selector, N.Nil)) {
353
+ const normalizedTemplate = template.replace(ampersandTemplateInterpolationRegex, 'x');
354
+ const isBareIdentifierTemplate = /^[A-Za-z_\u0080-\uffff][\w\u0080-\uffff-]*$/u.test(normalizedTemplate);
355
+ if (
356
+ normalizedTemplate === 'nil'
357
+ || (!ampersandTemplateRegex.test(normalizedTemplate) && !isBareIdentifierTemplate)
358
+ ) {
359
+ throw new SyntaxError(`Invalid ampersand template "${template}"`);
360
+ }
361
+ const isTemplateMerge = template.includes('&');
362
+ if (isTemplateMerge) {
363
+ const isIdentJoinChar = (char: string | undefined): boolean => {
364
+ return !!char && /[a-zA-Z0-9_-]/.test(char);
365
+ };
366
+ const assertValidTemplateJoin = (template: string, replacement: string): void => {
367
+ if (!replacement) {
368
+ return;
369
+ }
370
+ let searchFrom = 0;
371
+ while (true) {
372
+ const idx = template.indexOf('&', searchFrom);
373
+ if (idx === -1) {
374
+ break;
375
+ }
376
+ const before = idx > 0 ? template[idx - 1] : undefined;
377
+ const after = idx < template.length - 1 ? template[idx + 1] : undefined;
378
+ const first = replacement[0];
379
+ const last = replacement[replacement.length - 1];
380
+ const invalidHeadJoin = (first === '.' || first === '#') && isIdentJoinChar(before);
381
+ const invalidTailJoin = (last === '.' || last === '#') && isIdentJoinChar(after);
382
+ if (invalidHeadJoin || invalidTailJoin) {
383
+ throw new SyntaxError(`Invalid ampersand merge template "${template}" with parent selector "${replacement}"`);
384
+ }
385
+ searchFrom = idx + 1;
386
+ }
387
+ };
388
+ const mergeTemplate = (baseSelector: Selector): Selector => {
389
+ const baseSelectors: Selector[] = [];
390
+ if (
391
+ isNode(baseSelector, N.PseudoSelector)
392
+ && baseSelector.get('name') === ':is'
393
+ && isSelectorListNode(baseSelector.get('arg'))
394
+ ) {
395
+ for (const item of baseSelector.get('arg').get('value')) {
396
+ if (isSelectorNode(item)) {
397
+ baseSelectors.push(item);
398
+ }
399
+ }
400
+ } else if (isSelectorListNode(baseSelector)) {
401
+ for (const item of baseSelector.get('value')) {
402
+ if (isSelectorNode(item)) {
403
+ baseSelectors.push(item);
404
+ }
405
+ }
406
+ } else {
407
+ // Handle raw comma-separated strings (e.g. from ~'apple, satsuma, banana, pear')
408
+ // by splitting into individual items so the template distributes across all of them.
409
+ const selectorStr = baseSelector.toTrimmedString();
410
+ if (selectorStr.includes(',')) {
411
+ const items = Ampersand.splitTopLevelCommas(selectorStr);
412
+ for (const item of items) {
413
+ baseSelectors.push(new BasicSelector(item).inherit(baseSelector));
414
+ }
415
+ } else {
416
+ baseSelectors.push(baseSelector);
417
+ }
418
+ }
419
+ const merged = baseSelectors.map((item) => {
420
+ const value = item.toTrimmedString();
421
+ assertValidTemplateJoin(template, value);
422
+ return new BasicSelector(template.split('&').join(value)).inherit(baseSelector);
423
+ });
424
+ if (merged.length === 1) {
425
+ return merged[0]!;
426
+ }
427
+ return new SelectorList(merged).inherit(baseSelector);
428
+ };
429
+ if (isSelectorListNode(selector)) {
430
+ const mergedItems: Selector[] = [];
431
+ for (const item of selector.get('value')) {
432
+ if (!isSelectorNode(item)) {
433
+ continue;
434
+ }
435
+ const merged = mergeTemplate(item);
436
+ if (isSelectorListNode(merged)) {
437
+ for (const nestedItem of merged.get('value')) {
438
+ if (isSelectorNode(nestedItem)) {
439
+ mergedItems.push(nestedItem);
440
+ }
441
+ }
442
+ } else {
443
+ mergedItems.push(merged);
444
+ }
445
+ }
446
+ selector = new SelectorList(mergedItems).inherit(selector);
447
+ } else {
448
+ selector = mergeTemplate(selector);
449
+ }
450
+ } else {
451
+ let doAppendValue = (n: Selector) => {
452
+ let appended = false;
453
+ for (let s of n.nodes(true)) {
454
+ /** Find the last simple selector and attempt to append */
455
+ if (isNode(s, N.SimpleSelector)) {
456
+ if ('value' in s && typeof s.value === 'string') {
457
+ s.setData(s.value + template);
458
+ appended = true;
459
+ break;
460
+ }
461
+ throw new SyntaxError(`Cannot append "${template}" to this type of selector`);
462
+ }
463
+ }
464
+ if (!appended) {
465
+ throw new SyntaxError(`Cannot append "${template}" to this type of selector`);
466
+ }
467
+ };
468
+
469
+ if (isSelectorListNode(selector)) {
470
+ selector.get('value').forEach(doAppendValue);
471
+ } else {
472
+ doAppendValue(selector);
473
+ }
474
+ }
475
+ }
476
+
477
+ let result: Selector | Nil;
478
+ const shouldWrapSelectorList = isNode(selector, N.SelectorList) && (hoistToRoot || template !== undefined);
479
+
480
+ if (shouldWrapSelectorList) {
481
+ result = PseudoSelector.create({ name: ':is', arg: selector });
482
+ result.generated = true;
483
+ } else {
484
+ result = selector;
485
+ }
486
+
487
+ if (template !== undefined || shouldWrapSelectorList || hoistToRoot) {
488
+ result.hoistToRoot = true;
489
+ }
490
+ return result;
491
+ }
492
+
493
+ const amp: Ampersand = this.clone();
494
+ let frame = atIndex(context.rulesetFrames, -1);
495
+ const frameSelector = isNode(frame, N.Ruleset) ? frame.get('selector') : undefined;
496
+ /**
497
+ * Attach the current context selector if we need it later, for extends and such.
498
+ * The frame is constant, so we can use the selector directly.
499
+ * If the ampersand already has a stored selector (from getImplicitSelector),
500
+ * preserve it instead of overwriting with the frame selector.
501
+ */
502
+ if (!amp._selectorContainer && frame && frameSelector) {
503
+ amp._selectorContainer = {
504
+ selector: frameSelector,
505
+ getEffectiveSelector: (collapseNesting?: boolean, nestedContext?: Context) => {
506
+ if (frame && isNode(frame, N.Ruleset)) {
507
+ return frame.getEffectiveSelector(collapseNesting, nestedContext);
508
+ }
509
+ return frameSelector;
510
+ }
511
+ };
512
+ }
513
+ return amp;
514
+ }
515
+
516
+ override clone(deep?: boolean, cloneFn?: (n: Node) => Node): this {
517
+ const newNode = super.clone(deep, cloneFn);
518
+ // super.clone() for leaf nodes reconstructs the leaf value generically.
519
+ // Ampersand stores its data in the template instance field, not in .value,
520
+ // so we must patch it explicitly on the clone.
521
+ newNode.template = this.template;
522
+ if (newNode.template instanceof Nil) {
523
+ newNode.adopt(newNode.template);
524
+ }
525
+ // Preserve authored selector context when it already exists. EvalNode will
526
+ // still bind the current frame when the clone has no selector container.
527
+ newNode._selectorContainer = this._selectorContainer;
528
+ newNode._storedSelector = cloneStoredSelector(this._storedSelector, deep);
529
+ return newNode;
530
+ }
531
+
532
+ /** @todo - move to ToModuleVisitor */
533
+ // toModule(context: Context, out: OutputCollector) {
534
+ // out.add('$J.amp()', this.location)
535
+ // }
536
+ }
537
+
538
+ export const amp = defineType(Ampersand, 'Ampersand', 'amp');
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Import from node-base to avoid circular dependency.
3
+ * The patching happens in node.ts
4
+ */
5
+ import { Node, defineType, type OptionalLocation, type NodeOptions, type TreeContext, F_STATIC } from './node-base.js';
6
+ import type { Context } from '../context.js';
7
+ import { type MaybePromise } from '@jesscss/awaitable-pipe';
8
+ import { Nil } from './nil.js';
9
+
10
+ export type AnyRole =
11
+ 'ident'
12
+ | 'name'
13
+ | 'charset'
14
+ | 'keyword'
15
+ | 'property'
16
+ | 'atkeyword'
17
+ | 'urlvalue'
18
+ | 'flag'
19
+ | 'customprop'
20
+ | 'semi'
21
+ | 'operator'
22
+ | 'any';
23
+
24
+ /** Doesn't get assigned but can be used for inference? */
25
+ export type AnyOptions<T extends string> = NodeOptions & {
26
+ role?: T;
27
+ };
28
+
29
+ export interface Any<
30
+ Role extends AnyRole = AnyRole
31
+ > extends Node<string, AnyOptions<Role>> {
32
+ type: 'Any' | 'Keyword';
33
+ shortType: 'any' | 'keyword';
34
+ eval(context: Context): Any<Role>;
35
+ valueOf(): string;
36
+ }
37
+
38
+ /**
39
+ * Any is a simple token that has a string value and a role.
40
+ * Sometimes that role is unspecified. Think of it as a generic,
41
+ * and a placeholder for tokens that don't have anything special
42
+ * to do during evaluation.
43
+ *
44
+ * Called "Anonymous" in Less's original tree, but "anonymous"
45
+ * was somewhat a counter-intuitive name.
46
+ */
47
+ export class Any<
48
+ Role extends AnyRole = AnyRole
49
+ > extends Node<string, AnyOptions<Role>> {
50
+ static override childKeys = null as null;
51
+
52
+ readonly value!: string;
53
+ readonly role: Role | undefined;
54
+
55
+ constructor(
56
+ value: string,
57
+ options?: AnyOptions<Role>,
58
+ location?: OptionalLocation,
59
+ treeContext?: TreeContext
60
+ ) {
61
+ super(value, options, location, treeContext);
62
+ this.value = value;
63
+ this.role = options?.role as Role | undefined;
64
+ this.addFlag(F_STATIC);
65
+ }
66
+
67
+ override preEval(context: Context): this | Nil {
68
+ this.preEvaluated = true;
69
+ // Index should already be assigned by parent Rules
70
+ if (this.role === 'charset') {
71
+ if (!context.currentCharset) {
72
+ /** @todo - Throw error in the future? */
73
+ context.currentCharset = this;
74
+ }
75
+ return new Nil();
76
+ }
77
+ return this;
78
+ }
79
+
80
+ // Any values are static and don't need evaluation
81
+ override evalNode(_context: Context): MaybePromise<Node> {
82
+ return this;
83
+ }
84
+
85
+ override compare(other: Node): 0 | 1 | -1 | undefined {
86
+ // In Less guards, quoted strings are distinct from bare identifiers.
87
+ if (other.type === 'Quoted') {
88
+ return undefined;
89
+ }
90
+ if (other.type === 'Any' || other.type === 'Keyword') {
91
+ return this.value === String(other.valueOf?.() ?? '') ? 0 : undefined;
92
+ }
93
+ if (other.type === 'Num' || other.type === 'Dimension') {
94
+ const text = this.value.trim();
95
+ if (!/^[-+]?(?:\d+\.?\d*|\.\d+)$/.test(text)) {
96
+ return undefined;
97
+ }
98
+ const otherNumber = Reflect.get(other, 'number');
99
+ const otherUnit = Reflect.get(other, 'unit');
100
+ if (typeof otherNumber !== 'number') {
101
+ return undefined;
102
+ }
103
+ if (other.type === 'Dimension' && otherUnit) {
104
+ return undefined;
105
+ }
106
+ return Number(text) === otherNumber ? 0 : undefined;
107
+ }
108
+ if (typeof other.toString === 'function') {
109
+ const normalize = (s: string) => s.replace(/;\s*/g, ', ').replace(/\s+/g, ' ').trim();
110
+ return normalize(this.toString()) === normalize(other.toString()) ? 0 : undefined;
111
+ }
112
+ return undefined;
113
+ }
114
+ }
115
+
116
+ // Custom any function that properly handles role narrowing
117
+ export function any<Role extends AnyRole = AnyRole>(
118
+ value: string,
119
+ options?: AnyOptions<Role>
120
+ ): Any<Role> {
121
+ return new Any(value, options);
122
+ }
123
+ defineType(Any, 'Any');
124
+
125
+ /** Legacy class - remove? */
126
+ export class Anonymous<
127
+ Role extends AnyRole = AnyRole
128
+ > extends Any<Role> {}
129
+ defineType(Anonymous, 'Anonymous');
130
+
131
+ /**
132
+ * Keyword represents a CSS keyword value (e.g., 'auto', 'none', 'inherit', 'and', 'or').
133
+ *
134
+ * This is a convenience class that extends Any with role: 'keyword' fixed.
135
+ * It provides better type safety and aligns with Less.js's Keyword node type
136
+ * for compatibility purposes.
137
+ *
138
+ * Note: In Jess, boolean values ('true', 'false') are represented as Bool nodes,
139
+ * not Keyword nodes, unlike Less.js where they are Keyword instances.
140
+ */
141
+ export interface Keyword {
142
+ type: 'Keyword';
143
+ shortType: 'keyword';
144
+ }
145
+
146
+ export class Keyword extends Any<'keyword'> {
147
+ constructor(
148
+ value: string,
149
+ options?: Omit<NodeOptions, 'role'>,
150
+ location?: OptionalLocation,
151
+ context?: TreeContext
152
+ ) {
153
+ // Force role to 'keyword'
154
+ super(value, { ...options, role: 'keyword' }, location, context);
155
+ }
156
+ }
157
+ defineType(Keyword, 'Keyword');
158
+
159
+ /**
160
+ * Helper function to create a Keyword node
161
+ */
162
+ export function keyword(
163
+ value: string,
164
+ options?: Omit<NodeOptions, 'role'>,
165
+ location?: OptionalLocation,
166
+ context?: TreeContext
167
+ ): Keyword {
168
+ return new Keyword(value, options, location, context);
169
+ }