@jesscss/core 2.0.0-alpha.4 → 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 -94
  258. package/lib/tree/ampersand.d.ts.map +0 -1
  259. package/lib/tree/ampersand.js +0 -269
  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,763 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { defineFunction, callWithContext } from '../define-function.js';
3
+ import { Context } from '../context.js';
4
+ import { expectTypeOf } from 'vitest';
5
+ import { Color, Dimension } from '../tree/index.js';
6
+
7
+ describe('defineFunction', () => {
8
+ const args = [
9
+ { name: 'name', type: 'string' },
10
+ { name: 'value', type: 'number' }
11
+ ] as const;
12
+
13
+ const myFunc = defineFunction(
14
+ 'test',
15
+ (name: string, value: number) => `${name}: ${value}`,
16
+ { params: args }
17
+ );
18
+
19
+ describe('positional calls', () => {
20
+ it('should work with valid positional arguments', () => {
21
+ const myFunc = defineFunction(
22
+ 'test',
23
+ (name: string, value: number) => `${name}: ${value}`,
24
+ { params: [
25
+ { name: 'name', type: 'string' },
26
+ { name: 'value', type: 'number' }
27
+ ] }
28
+ );
29
+ expect(myFunc('hello', 42)).toBe('hello: 42');
30
+ });
31
+
32
+ it('should throw error for invalid first argument type', () => {
33
+ expect(() => {
34
+ (myFunc as any)(1, 42);
35
+ }).toThrow('Argument \'name\' must be of type \'string\'. Got: number');
36
+ });
37
+
38
+ it('should throw error for invalid second argument type', () => {
39
+ expect(() => {
40
+ (myFunc as any)('hello', 'not a number');
41
+ }).toThrow('Argument \'value\' must be of type \'number\'. Got: string');
42
+ });
43
+
44
+ it('should handle undefined arguments gracefully', () => {
45
+ // With the new validation, undefined arguments for required parameters should throw
46
+ expect(() => {
47
+ myFunc('hello', undefined as any);
48
+ }).toThrow('Required argument \'value\' is missing');
49
+ });
50
+ });
51
+
52
+ describe('record calls', () => {
53
+ it('should work with valid record arguments', () => {
54
+ expect(myFunc({ name: 'hello', value: 42 })).toBe('hello: 42');
55
+ });
56
+
57
+ it('should work with partial record (missing optional parameters)', () => {
58
+ // With the new validation, missing required parameters should throw
59
+ expect(() => {
60
+ (myFunc as any)({ name: 'hello' });
61
+ }).toThrow('Required argument \'value\' is missing');
62
+ });
63
+
64
+ it('should throw error for invalid property type in record', () => {
65
+ expect(() => {
66
+ (myFunc as any)({ name: 123, value: 42 });
67
+ }).toThrow('Argument \'name\' must be of type \'string\'. Got: number');
68
+ });
69
+
70
+ it('should throw error for invalid second property type in record', () => {
71
+ expect(() => {
72
+ (myFunc as any)({ name: 'hello', value: 'not a number' });
73
+ }).toThrow('Argument \'value\' must be of type \'number\'. Got: string');
74
+ });
75
+ });
76
+
77
+ describe('hybrid calls', () => {
78
+ it('should work with positional + record arguments', () => {
79
+ expect(myFunc('hello', { value: 42 })).toBe('hello: 42');
80
+ });
81
+
82
+ it('should prioritize record over positional for same parameter', () => {
83
+ // Record takes precedence over positional arguments
84
+ expect(myFunc('ignored', { name: 'hello', value: 42 })).toBe('hello: 42');
85
+ });
86
+
87
+ it('should handle partial record in hybrid call', () => {
88
+ // Only the value from record, name from positional
89
+ expect(myFunc('hello', { value: 42 })).toBe('hello: 42');
90
+ });
91
+
92
+ it('should handle record with extra properties', () => {
93
+ // Extra properties in record should be ignored
94
+ (myFunc as any)('hello', { value: 42, extra: 'ignored' });
95
+ // The function should still work correctly despite extra properties
96
+ expect(myFunc('hello', { value: 42 })).toBe('hello: 42');
97
+ });
98
+
99
+ it('should throw error for invalid positional argument in hybrid call', () => {
100
+ expect(() => {
101
+ (myFunc as any)(123, { value: 42 });
102
+ }).toThrow('Argument \'name\' must be of type \'string\'. Got: number');
103
+ });
104
+
105
+ it('should throw error for invalid record property in hybrid call', () => {
106
+ expect(() => {
107
+ (myFunc as any)('hello', { value: 'not a number' });
108
+ }).toThrow('Argument \'value\' must be of type \'number\'. Got: string');
109
+ });
110
+ });
111
+
112
+ describe('edge cases', () => {
113
+ it('should handle empty record', () => {
114
+ // With the new validation, empty record should throw for missing required parameters
115
+ expect(() => {
116
+ (myFunc as any)({});
117
+ }).toThrow('Required argument \'name\' is missing');
118
+ });
119
+
120
+ it('should handle null values', () => {
121
+ expect(() => {
122
+ (myFunc as any)(null, 42);
123
+ }).toThrow('Argument \'name\' must be of type \'string\'. Got: object');
124
+ });
125
+
126
+ it('should handle boolean values', () => {
127
+ expect(() => {
128
+ (myFunc as any)(true, 42);
129
+ }).toThrow('Argument \'name\' must be of type \'string\'. Got: boolean');
130
+ });
131
+ });
132
+
133
+ describe('type inference', () => {
134
+ it('should provide correct return type', () => {
135
+ const result = myFunc({ name: 'hello', value: 42 });
136
+ expect(typeof result).toBe('string');
137
+ });
138
+
139
+ it('should maintain function signature for record calls', () => {
140
+ // This should compile without errors
141
+ const testFunc = (fn: typeof myFunc) => {
142
+ fn({ name: 'hello', value: 42 });
143
+ };
144
+ testFunc(myFunc);
145
+ });
146
+ });
147
+
148
+ describe('complex scenarios', () => {
149
+ it('should work with more complex function', () => {
150
+ const complexArgs = [
151
+ { name: 'name', type: 'string' },
152
+ { name: 'age', type: 'number' },
153
+ { name: 'active', type: 'boolean' }
154
+ ] as const;
155
+
156
+ const complexFunc = defineFunction(
157
+ 'complex',
158
+ (name: string, age: number, active: boolean) =>
159
+ `${name} is ${age} years old and is ${active ? 'active' : 'inactive'}`,
160
+ { params: complexArgs }
161
+ );
162
+
163
+ expect(complexFunc({ name: 'John', age: 30, active: true })).toBe('John is 30 years old and is active');
164
+ expect(complexFunc({ name: 'Jane', age: 25, active: false })).toBe('Jane is 25 years old and is inactive');
165
+ expect(complexFunc({ name: 'Bob', age: 35, active: true })).toBe('Bob is 35 years old and is active');
166
+ });
167
+
168
+ it('should handle optional parameters correctly', () => {
169
+ const optionalArgs = [
170
+ { name: 'required', type: 'string' },
171
+ { name: 'optional', type: 'number', optional: true }
172
+ ] as const;
173
+
174
+ const optionalFunc = defineFunction(
175
+ 'optional',
176
+ (required: string, optional?: number) =>
177
+ `${required}${optional ? `: ${optional}` : ''}`,
178
+ { params: optionalArgs }
179
+ );
180
+
181
+ expect(optionalFunc({ required: 'hello' })).toBe('hello');
182
+ expect(optionalFunc({ required: 'hello', optional: 42 })).toBe('hello: 42');
183
+ expect(optionalFunc({ required: 'world' })).toBe('world');
184
+ expect(optionalFunc({ required: 'world', optional: 123 })).toBe('world: 123');
185
+ });
186
+
187
+ it('should throw error for missing required parameters', () => {
188
+ const requiredArgs = [
189
+ { name: 'name', type: 'string' },
190
+ { name: 'value', type: 'number' }
191
+ ] as const;
192
+
193
+ const requiredFunc = defineFunction(
194
+ 'required',
195
+ (name: string, value: number) => `${name}: ${value}`,
196
+ { params: requiredArgs }
197
+ );
198
+
199
+ expect(() => {
200
+ (requiredFunc as any)();
201
+ }).toThrow('Required argument \'name\' is missing');
202
+
203
+ expect(() => {
204
+ (requiredFunc as any)('hello');
205
+ }).toThrow('Required argument \'value\' is missing');
206
+ });
207
+
208
+ it('should work with all optional parameters', () => {
209
+ const allOptionalArgs = [
210
+ { name: 'name', type: 'string', optional: true },
211
+ { name: 'value', type: 'number', optional: true }
212
+ ] as const;
213
+
214
+ const allOptionalFunc = defineFunction(
215
+ 'allOptional',
216
+ (name?: string, value?: number) => `${name || 'default'}: ${value || 0}`,
217
+ { params: allOptionalArgs }
218
+ );
219
+
220
+ // Should work with no arguments
221
+ expect(allOptionalFunc()).toBe('default: 0');
222
+
223
+ // Should work with partial arguments
224
+ expect(allOptionalFunc('hello')).toBe('hello: 0');
225
+ expect(allOptionalFunc(undefined, 42)).toBe('default: 42');
226
+
227
+ // Should work with all arguments
228
+ expect(allOptionalFunc('hello', 42)).toBe('hello: 42');
229
+ });
230
+
231
+ it('should have strong typing for positional arguments', () => {
232
+ const typedArgs = [
233
+ { name: 'name', type: 'string' },
234
+ { name: 'value', type: 'number' }
235
+ ] as const;
236
+
237
+ const typedFunc = defineFunction(
238
+ 'typed',
239
+ (name: string, value: number) => `${name}: ${value}`,
240
+ { params: typedArgs }
241
+ );
242
+
243
+ // These should have proper type checking
244
+ expect(typedFunc({ name: 'hello', value: 42 })).toBe('hello: 42');
245
+
246
+ // TypeScript should catch these at compile time:
247
+ // typedFunc('hello', 'not-a-number'); // Should be type error
248
+ // typedFunc(123, 42); // Should be type error
249
+ // typedFunc('hello'); // Should be type error (missing required param)
250
+ });
251
+
252
+ it('should preserve parameter names from function signature', () => {
253
+ const args = [
254
+ { name: 'name', type: 'string' },
255
+ { name: 'age', type: 'number' },
256
+ { name: 'active', type: 'boolean' }
257
+ ] as const;
258
+
259
+ const func = defineFunction(
260
+ 'preserveNames',
261
+ (name: string, age: number, active: boolean) => `${name}: ${age}, ${active}`,
262
+ { params: args }
263
+ );
264
+
265
+ // The function should have the same parameter names as the original function
266
+ expect(func({ name: 'John', age: 30, active: true })).toBe('John: 30, true');
267
+ expect(func({ name: 'Jane', age: 25, active: false })).toBe('Jane: 25, false');
268
+
269
+ // Test that parameter names are preserved in the type
270
+ expectTypeOf(func).toBeFunction();
271
+ expectTypeOf(func).returns.toBeString();
272
+ });
273
+
274
+ it('should validate that args match function signature', () => {
275
+ // This should work - args match function signature
276
+ const validArgs = [
277
+ { name: 'name', type: 'string' },
278
+ { name: 'value', type: 'number' }
279
+ ] as const;
280
+
281
+ const validFunc = defineFunction(
282
+ 'valid',
283
+ (name: string, value: number) => `${name}: ${value}`,
284
+ { params: validArgs }
285
+ );
286
+
287
+ expect(validFunc({ name: 'hello', value: 42 })).toBe('hello: 42');
288
+
289
+ // Test that the function signature matches the original
290
+ expectTypeOf(validFunc).toBeFunction();
291
+ expectTypeOf(validFunc).returns.toBeString();
292
+
293
+ // This should cause a type error at compile time if uncommented:
294
+ // const invalidArgs = [
295
+ // { name: 'name', type: 'string' },
296
+ // { name: 'value', type: 'boolean' } // Wrong type!
297
+ // ] as const;
298
+ //
299
+ // const invalidFunc = defineFunction(
300
+ // 'invalid',
301
+ // (name: string, value: number) => `${name}: ${value}`, // Expects number, but args says boolean
302
+ // { params: invalidArgs }
303
+ // );
304
+ });
305
+
306
+ it('should have correct return type', () => {
307
+ const args = [
308
+ { name: 'name', type: 'string' },
309
+ { name: 'value', type: 'number' }
310
+ ] as const;
311
+
312
+ const func = defineFunction(
313
+ 'returnType',
314
+ (name: string, value: number): string => `${name}: ${value}`,
315
+ { params: args }
316
+ );
317
+
318
+ // Test that return type is preserved
319
+ expectTypeOf(func({ name: 'hello', value: 42 })).toBeString();
320
+ });
321
+
322
+ it('should catch type mismatches between args and function signature', () => {
323
+ // This test demonstrates that TypeScript will catch mismatches
324
+ // Uncomment the following lines to see the type error:
325
+
326
+ // const mismatchedArgs = [
327
+ // { name: 'name', type: 'string' },
328
+ // { name: 'value', type: 'boolean' } // Wrong type!
329
+ // ] as const;
330
+ //
331
+ // const mismatchedFunc = defineFunction(
332
+ // 'mismatched',
333
+ // (name: string, value: number) => `${name}: ${value}`, // Expects number, but args says boolean
334
+ // { params: mismatchedArgs }
335
+ // );
336
+
337
+ // The above should cause a TypeScript error because:
338
+ // - Function expects (name: string, value: number)
339
+ // - Args says value should be boolean
340
+ // - TypeScript should catch this mismatch
341
+ });
342
+
343
+ it('should handle default values correctly', () => {
344
+ const defaultArgs = [
345
+ { name: 'name', type: 'string', default: 'anonymous' },
346
+ { name: 'age', type: 'number', default: 18 },
347
+ { name: 'active', type: 'boolean', default: true }
348
+ ] as const;
349
+
350
+ const defaultFunc = defineFunction(
351
+ 'defaults',
352
+ (name: string, age: number, active: boolean) => `${name} (${age}) - ${active ? 'active' : 'inactive'}`,
353
+ { params: defaultArgs }
354
+ );
355
+
356
+ // Should use defaults when no arguments provided
357
+ expect(defaultFunc({})).toBe('anonymous (18) - active');
358
+
359
+ // Should use defaults for missing parameters
360
+ expect(defaultFunc({ name: 'John' })).toBe('John (18) - active');
361
+ expect(defaultFunc({ name: 'Jane', age: 25 })).toBe('Jane (25) - active');
362
+
363
+ // Should override defaults when provided
364
+ expect(defaultFunc({ name: 'Bob', age: 30, active: false })).toBe('Bob (30) - inactive');
365
+ });
366
+
367
+ it('should automatically make parameters optional when they have defaults', () => {
368
+ const autoOptionalArgs = [
369
+ { name: 'name', type: 'string' }, // Required
370
+ { name: 'age', type: 'number', default: 18 }, // Auto-optional due to default
371
+ { name: 'city', type: 'string', default: 'Unknown' } // Auto-optional due to default
372
+ ] as const;
373
+
374
+ const autoOptionalFunc = defineFunction(
375
+ 'autoOptional',
376
+ (name: string, age: number, city: string) => `${name} (${age}) from ${city}`,
377
+ { params: autoOptionalArgs }
378
+ );
379
+
380
+ // Should work with just the required parameter
381
+ expect(autoOptionalFunc({ name: 'John' })).toBe('John (18) from Unknown');
382
+
383
+ // Should work with partial parameters
384
+ expect(autoOptionalFunc({ name: 'Jane', age: 25 })).toBe('Jane (25) from Unknown');
385
+
386
+ // Should work with all parameters
387
+ expect(autoOptionalFunc({ name: 'Bob', age: 30, city: 'New York' })).toBe('Bob (30) from New York');
388
+ });
389
+
390
+ it('should not require explicit optional flag when using defaults', () => {
391
+ const implicitOptionalArgs = [
392
+ { name: 'name', type: 'string' }, // Required
393
+ { name: 'count', type: 'number', default: 0 }, // Implicitly optional due to default
394
+ { name: 'enabled', type: 'boolean', default: true } // Implicitly optional due to default
395
+ ] as const;
396
+
397
+ const implicitOptionalFunc = defineFunction(
398
+ 'implicitOptional',
399
+ (name: string, count: number, enabled: boolean) => `${name}: ${count} items, ${enabled ? 'enabled' : 'disabled'}`,
400
+ { params: implicitOptionalArgs }
401
+ );
402
+
403
+ // Should work with just required parameter (others use defaults)
404
+ expect(implicitOptionalFunc({ name: 'Widget' })).toBe('Widget: 0 items, enabled');
405
+
406
+ // Should work with partial parameters
407
+ expect(implicitOptionalFunc({ name: 'Gadget', count: 5 })).toBe('Gadget: 5 items, enabled');
408
+
409
+ // Should work with all parameters
410
+ expect(implicitOptionalFunc({ name: 'Tool', count: 10, enabled: false })).toBe('Tool: 10 items, disabled');
411
+ });
412
+
413
+ it('should work with tree node types', () => {
414
+ const treeNodeArgs = [
415
+ { name: 'color', type: Color },
416
+ { name: 'dimension', type: Dimension, default: new Dimension({ number: 0, unit: 'px' }) },
417
+ { name: 'alpha', type: 'number', default: 1 }
418
+ ] as const;
419
+
420
+ const treeNodeFunc = defineFunction(
421
+ 'treeNodes',
422
+ (color: Color, dimension?: Dimension, alpha?: number) => {
423
+ return {
424
+ colorType: color.type,
425
+ dimensionType: dimension?.type || 'none',
426
+ alpha: alpha || 1
427
+ };
428
+ },
429
+ { params: treeNodeArgs }
430
+ );
431
+
432
+ const testColor = new Color('#ff0000');
433
+ const testDimension = new Dimension({ number: 10, unit: 'px' });
434
+
435
+ // Test with all parameters
436
+ const result1 = treeNodeFunc(testColor, testDimension, 0.8);
437
+ expect(result1.colorType).toBe('Color');
438
+ expect(result1.dimensionType).toBe('Dimension');
439
+ expect(result1.alpha).toBe(0.8);
440
+
441
+ // Test with missing optional parameter (should use defaults)
442
+ const result2 = treeNodeFunc(testColor);
443
+ expect(result2.colorType).toBe('Color');
444
+ expect(result2.dimensionType).toBe('Dimension'); // Uses default
445
+ expect(result2.alpha).toBe(1); // Uses default
446
+
447
+ // Test that instanceof checks work correctly
448
+ expect(testColor instanceof Color).toBe(true);
449
+ expect(testDimension instanceof Dimension).toBe(true);
450
+
451
+ // Test that runtime validation works with instanceof checks
452
+ expect(() => {
453
+ treeNodeFunc('not a color' as any, testDimension);
454
+ }).toThrow('Argument \'color\' must be of type \'Color\'');
455
+ });
456
+
457
+ it('should support rest parameters and lazy evaluation', async () => {
458
+ const calls: string[] = [];
459
+ class TestNode extends Color {
460
+ override async evalNode(context: any): Promise<any> {
461
+ calls.push(`${(this as any)._nodeValue}`);
462
+ return this;
463
+ }
464
+ }
465
+
466
+ const restFunc = defineFunction(
467
+ 'rest',
468
+ async (...values: Array<() => Promise<Color>>) => {
469
+ const firstThunk = values[0]!;
470
+ const first = await firstThunk() as TestNode;
471
+ return first;
472
+ },
473
+ { params: [{ name: 'values', type: Color, rest: true, lazy: true }] }
474
+ );
475
+
476
+ // Call positionally: only first should be evaluated
477
+ const a = new TestNode('#000');
478
+ const b = new TestNode('#111');
479
+ const c = new TestNode('#222');
480
+ const ctx = new Context();
481
+ const result = await callWithContext(ctx, restFunc as any, a, b, c);
482
+ expect(result).toBe(a);
483
+ // Only first element evaluated lazily upon access
484
+ expect(calls).toEqual(['#000']);
485
+ });
486
+
487
+ it('should support lazy evaluation of object parameters', async () => {
488
+ const calls: string[] = [];
489
+ class TestNode extends Color {
490
+ override async evalNode(context: any): Promise<any> {
491
+ calls.push(`${(this as any)._nodeValue}`);
492
+ return this;
493
+ }
494
+ }
495
+
496
+ const objFunc = defineFunction(
497
+ 'obj',
498
+ async (aThunk: () => Promise<Color>, bThunk: () => Promise<Color>) => {
499
+ const a = await aThunk() as TestNode;
500
+ return a;
501
+ },
502
+ { params: [
503
+ { name: 'a', type: Color, lazy: true },
504
+ { name: 'b', type: Color, lazy: true }
505
+ ] }
506
+ );
507
+
508
+ const a = new TestNode('#000');
509
+ const b = new TestNode('#111');
510
+ const ctx = new Context();
511
+ const result = await callWithContext(ctx, objFunc as any, { a, b });
512
+ expect(result).toBe(a);
513
+ expect(calls).toEqual(['#000']);
514
+ });
515
+
516
+ it('should validate lazy parameters when thunk is called, not when function is defined', async () => {
517
+ // This test ensures lazy parameters are validated when the thunk is called,
518
+ // not when the function is initially called. This prevents "Got: function" errors.
519
+ const directFunc = defineFunction(
520
+ 'direct',
521
+ async (valueThunk: any) => {
522
+ // When this thunk is called, it should validate the resolved value, not the function
523
+ const value = await valueThunk();
524
+ return value;
525
+ },
526
+ { params: [
527
+ { name: 'value', type: Dimension, lazy: true }
528
+ ] }
529
+ );
530
+
531
+ // Should throw when function returns wrong type - validation happens when thunk is called
532
+ // This would previously fail with "Got: function" but now correctly validates the resolved value
533
+ await expect(
534
+ directFunc(() => new Color('#000') as any)
535
+ ).rejects.toThrow('Argument \'value\' must be of type \'Dimension\'');
536
+ });
537
+ });
538
+
539
+ describe('type checking', () => {
540
+ it('should have strong typing for 1 parameter', () => {
541
+ const singleParamFunc = defineFunction(
542
+ 'singleParam',
543
+ (name: string) => `Hello ${name}`,
544
+ { params: [{ name: 'name', type: 'string' }] }
545
+ );
546
+
547
+ // These should have strong typing
548
+ expectTypeOf(singleParamFunc).toBeFunction();
549
+ expectTypeOf(singleParamFunc).returns.toBeString();
550
+
551
+ // Test that it works
552
+ expect(singleParamFunc('World')).toBe('Hello World');
553
+ });
554
+
555
+ it('should have strong typing for 2 parameters', () => {
556
+ const twoParamFunc = defineFunction(
557
+ 'twoParam',
558
+ (name: string, age: number) => `${name} is ${age} years old`,
559
+ { params: [
560
+ { name: 'name', type: 'string' },
561
+ { name: 'age', type: 'number' }
562
+ ] }
563
+ );
564
+
565
+ // These should have strong typing
566
+ expectTypeOf(twoParamFunc).toBeFunction();
567
+ expectTypeOf(twoParamFunc).returns.toBeString();
568
+
569
+ // Test that it works
570
+ expect(twoParamFunc('Alice', 25)).toBe('Alice is 25 years old');
571
+ });
572
+
573
+ it('should have strong typing for 3 parameters', () => {
574
+ const threeParamFunc = defineFunction(
575
+ 'threeParam',
576
+ (name: string, age: number, city: string) => `${name} is ${age} from ${city}`,
577
+ { params: [
578
+ { name: 'name', type: 'string' },
579
+ { name: 'age', type: 'number' },
580
+ { name: 'city', type: 'string' }
581
+ ] }
582
+ );
583
+
584
+ // These should have strong typing
585
+ expectTypeOf(threeParamFunc).toBeFunction();
586
+ expectTypeOf(threeParamFunc).returns.toBeString();
587
+
588
+ // Test that it works
589
+ expect(threeParamFunc('Bob', 30, 'New York')).toBe('Bob is 30 from New York');
590
+ });
591
+
592
+ it('should have strong typing for 4 parameters', () => {
593
+ const fourParamFunc = defineFunction(
594
+ 'fourParam',
595
+ (name: string, age: number, city: string, active: boolean) =>
596
+ `${name} is ${age} from ${city}, ${active ? 'active' : 'inactive'}`,
597
+ { params: [
598
+ { name: 'name', type: 'string' },
599
+ { name: 'age', type: 'number' },
600
+ { name: 'city', type: 'string' },
601
+ { name: 'active', type: 'boolean' }
602
+ ] }
603
+ );
604
+
605
+ // These should have strong typing
606
+ expectTypeOf(fourParamFunc).toBeFunction();
607
+ expectTypeOf(fourParamFunc).returns.toBeString();
608
+
609
+ // Test that it works
610
+ expect(fourParamFunc('Charlie', 35, 'London', true)).toBe('Charlie is 35 from London, active');
611
+ });
612
+
613
+ it('should have strong typing for 5 parameters', () => {
614
+ const fiveParamFunc = defineFunction(
615
+ 'fiveParam',
616
+ (name: string, age: number, city: string, active: boolean, score: number) =>
617
+ `${name} is ${age} from ${city}, ${active ? 'active' : 'inactive'}, score: ${score}`,
618
+ { params: [
619
+ { name: 'name', type: 'string' },
620
+ { name: 'age', type: 'number' },
621
+ { name: 'city', type: 'string' },
622
+ { name: 'active', type: 'boolean' },
623
+ { name: 'score', type: 'number' }
624
+ ] }
625
+ );
626
+
627
+ // These should have strong typing
628
+ expectTypeOf(fiveParamFunc).toBeFunction();
629
+ expectTypeOf(fiveParamFunc).returns.toBeString();
630
+
631
+ // Test that it works
632
+ expect(fiveParamFunc('David', 40, 'Paris', false, 85)).toBe('David is 40 from Paris, inactive, score: 85');
633
+ });
634
+
635
+ it('should work with 6+ parameters (fallback typing)', () => {
636
+ const sixParamFunc = defineFunction(
637
+ 'sixParam',
638
+ (name: string, age: number, city: string, active: boolean, score: number, level: string) =>
639
+ `${name} is ${age} from ${city}, ${active ? 'active' : 'inactive'}, score: ${score}, level: ${level}`,
640
+ { params: [
641
+ { name: 'name', type: 'string' },
642
+ { name: 'age', type: 'number' },
643
+ { name: 'city', type: 'string' },
644
+ { name: 'active', type: 'boolean' },
645
+ { name: 'score', type: 'number' },
646
+ { name: 'level', type: 'string' }
647
+ ] }
648
+ );
649
+
650
+ // Should still be a function, but without specific overloads
651
+ expectTypeOf(sixParamFunc).toBeFunction();
652
+ expectTypeOf(sixParamFunc).returns.toBeString();
653
+
654
+ // Test that it works
655
+ expect(sixParamFunc('Eve', 45, 'Tokyo', true, 92, 'expert')).toBe('Eve is 45 from Tokyo, active, score: 92, level: expert');
656
+ });
657
+
658
+ it('should work with 7+ parameters (fallback typing)', () => {
659
+ const sevenParamFunc = defineFunction(
660
+ 'sevenParam',
661
+ (name: string, age: number, city: string, active: boolean, score: number, level: string, rank: number) =>
662
+ `${name} is ${age} from ${city}, ${active ? 'active' : 'inactive'}, score: ${score}, level: ${level}, rank: ${rank}`,
663
+ { params: [
664
+ { name: 'name', type: 'string' },
665
+ { name: 'age', type: 'number' },
666
+ { name: 'city', type: 'string' },
667
+ { name: 'active', type: 'boolean' },
668
+ { name: 'score', type: 'number' },
669
+ { name: 'level', type: 'string' },
670
+ { name: 'rank', type: 'number' }
671
+ ] }
672
+ );
673
+
674
+ // Should still be a function, but without specific overloads
675
+ expectTypeOf(sevenParamFunc).toBeFunction();
676
+ expectTypeOf(sevenParamFunc).returns.toBeString();
677
+
678
+ // Test that it works
679
+ expect(sevenParamFunc('Frank', 50, 'Berlin', false, 78, 'intermediate', 3)).toBe('Frank is 50 from Berlin, inactive, score: 78, level: intermediate, rank: 3');
680
+ });
681
+
682
+ it('should demonstrate parameter name preservation in strong typing', () => {
683
+ const preservedFunc = defineFunction(
684
+ 'preserved',
685
+ (firstName: string, lastName: string, age: number) => `${firstName} ${lastName} is ${age}`,
686
+ { params: [
687
+ { name: 'firstName', type: 'string' },
688
+ { name: 'lastName', type: 'string' },
689
+ { name: 'age', type: 'number' }
690
+ ] }
691
+ );
692
+
693
+ // The function should preserve parameter names in the type signature
694
+ expectTypeOf(preservedFunc).toBeFunction();
695
+ expectTypeOf(preservedFunc).returns.toBeString();
696
+
697
+ // Test that it works
698
+ expect(preservedFunc('John', 'Doe', 30)).toBe('John Doe is 30');
699
+ });
700
+
701
+ it('should demonstrate optional parameters in strong typing', () => {
702
+ const optionalFunc = defineFunction(
703
+ 'optional',
704
+ (name: string, age?: number, city?: string) => `${name}${age ? ` is ${age}` : ''}${city ? ` from ${city}` : ''}`,
705
+ { params: [
706
+ { name: 'name', type: 'string' },
707
+ { name: 'age', type: 'number', optional: true },
708
+ { name: 'city', type: 'string', optional: true }
709
+ ] }
710
+ );
711
+
712
+ // Should have strong typing for optional parameters
713
+ expectTypeOf(optionalFunc).toBeFunction();
714
+ expectTypeOf(optionalFunc).returns.toBeString();
715
+
716
+ // Test various combinations
717
+ expect(optionalFunc('Alice')).toBe('Alice');
718
+ expect(optionalFunc('Bob', 25)).toBe('Bob is 25');
719
+ expect(optionalFunc('Charlie', 30, 'London')).toBe('Charlie is 30 from London');
720
+ });
721
+
722
+ it('should demonstrate default values in strong typing', () => {
723
+ const defaultFunc = defineFunction(
724
+ 'default',
725
+ (name: string, age: number, city: string) => `${name} is ${age} from ${city}`,
726
+ { params: [
727
+ { name: 'name', type: 'string' },
728
+ { name: 'age', type: 'number', default: 25 },
729
+ { name: 'city', type: 'string', default: 'Unknown' }
730
+ ] }
731
+ );
732
+
733
+ // Should have strong typing with defaults
734
+ expectTypeOf(defaultFunc).toBeFunction();
735
+ expectTypeOf(defaultFunc).returns.toBeString();
736
+
737
+ // Test that defaults work
738
+ expect(defaultFunc('David')).toBe('David is 25 from Unknown');
739
+ expect(defaultFunc('Eve', 30)).toBe('Eve is 30 from Unknown');
740
+ expect(defaultFunc('Frank', 35, 'Paris')).toBe('Frank is 35 from Paris');
741
+ });
742
+ });
743
+
744
+ describe('error messages', () => {
745
+ it('should provide descriptive error messages', () => {
746
+ try {
747
+ (myFunc as any)(123, 'invalid');
748
+ } catch (error) {
749
+ expect((error as Error).message).toContain('Argument \'name\' must be of type \'string\'');
750
+ expect((error as Error).message).toContain('Got: number');
751
+ }
752
+ });
753
+
754
+ it('should provide error messages for record calls', () => {
755
+ try {
756
+ (myFunc as any)({ name: 456, value: 'invalid' });
757
+ } catch (error) {
758
+ expect((error as Error).message).toContain('Argument \'name\' must be of type \'string\'');
759
+ expect((error as Error).message).toContain('Got: number');
760
+ }
761
+ });
762
+ });
763
+ });