@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.
- package/lib/index.cjs +20159 -0
- package/lib/index.d.cts +5993 -0
- package/lib/index.d.cts.map +1 -0
- package/lib/index.d.ts +5992 -21
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +19926 -22
- package/lib/index.js.map +1 -1
- package/package.json +15 -14
- package/src/__tests__/define-function-record.test.ts +58 -0
- package/src/__tests__/define-function-simple.test.ts +55 -0
- package/src/__tests__/define-function-split-sequence.test.ts +547 -0
- package/src/__tests__/define-function-type-parity.test.ts +9 -0
- package/src/__tests__/define-function.test.ts +763 -0
- package/src/__tests__/num-operations.test.ts +91 -0
- package/src/__tests__/safe-parse.test.ts +374 -0
- package/src/context.ts +896 -0
- package/src/conversions.ts +282 -0
- package/src/debug-log.ts +29 -0
- package/src/define-function.ts +1006 -0
- package/src/deprecation.ts +67 -0
- package/src/globals.d.ts +26 -0
- package/src/index.ts +31 -0
- package/src/jess-error.ts +773 -0
- package/src/logger/deprecation-processing.ts +109 -0
- package/src/logger.ts +31 -0
- package/src/plugin.ts +292 -0
- package/src/tree/LOOKUP_CHAINS.md +35 -0
- package/src/tree/README.md +18 -0
- package/src/tree/__tests__/__snapshots__/extend-eval-integration.test.ts.snap +1455 -0
- package/src/tree/__tests__/ampersand.test.ts +382 -0
- package/src/tree/__tests__/at-rule.test.ts +2047 -0
- package/src/tree/__tests__/basic-render.test.ts +212 -0
- package/src/tree/__tests__/block.test.ts +40 -0
- package/src/tree/__tests__/call.test.ts +346 -0
- package/src/tree/__tests__/color.test.ts +537 -0
- package/src/tree/__tests__/condition.test.ts +186 -0
- package/src/tree/__tests__/control.test.ts +564 -0
- package/src/tree/__tests__/declaration.test.ts +253 -0
- package/src/tree/__tests__/dependency-graph.test.ts +177 -0
- package/src/tree/__tests__/detached-rulesets.test.ts +213 -0
- package/src/tree/__tests__/dimension.test.ts +236 -0
- package/src/tree/__tests__/expression.test.ts +73 -0
- package/src/tree/__tests__/ext-node.test.ts +31 -0
- package/src/tree/__tests__/extend-eval-integration.test.ts +1033 -0
- package/src/tree/__tests__/extend-import-style.test.ts +929 -0
- package/src/tree/__tests__/extend-less-fixtures.test.ts +851 -0
- package/src/tree/__tests__/extend-list.test.ts +31 -0
- package/src/tree/__tests__/extend-roots.test.ts +1045 -0
- package/src/tree/__tests__/extend-rules.test.ts +740 -0
- package/src/tree/__tests__/func.test.ts +171 -0
- package/src/tree/__tests__/import-js.test.ts +33 -0
- package/src/tree/__tests__/import-style-test-helpers.ts +56 -0
- package/src/tree/__tests__/import-style.test.ts +1967 -0
- package/src/tree/__tests__/interpolated-reference.test.ts +44 -0
- package/src/tree/__tests__/interpolated.test.ts +41 -0
- package/src/tree/__tests__/list.test.ts +177 -0
- package/src/tree/__tests__/log.test.ts +83 -0
- package/src/tree/__tests__/mixin-recursion.test.ts +639 -0
- package/src/tree/__tests__/mixin.test.ts +2171 -0
- package/src/tree/__tests__/negative.test.ts +45 -0
- package/src/tree/__tests__/nesting-collapse.test.ts +519 -0
- package/src/tree/__tests__/node-flags-perf.test.ts +195 -0
- package/src/tree/__tests__/node-flags.test.ts +410 -0
- package/src/tree/__tests__/node-graph.test.ts +598 -0
- package/src/tree/__tests__/node-mutation.test.ts +182 -0
- package/src/tree/__tests__/operation.test.ts +18 -0
- package/src/tree/__tests__/paren.test.ts +90 -0
- package/src/tree/__tests__/preserve-mode-output.test.ts +50 -0
- package/src/tree/__tests__/quoted.test.ts +72 -0
- package/src/tree/__tests__/range.test.ts +59 -0
- package/src/tree/__tests__/reference.test.ts +743 -0
- package/src/tree/__tests__/rest.test.ts +29 -0
- package/src/tree/__tests__/rules-raw.test.ts +14 -0
- package/src/tree/__tests__/rules.test.ts +1271 -0
- package/src/tree/__tests__/ruleset.test.ts +597 -0
- package/src/tree/__tests__/selector-attr.test.ts +50 -0
- package/src/tree/__tests__/selector-basic.test.ts +44 -0
- package/src/tree/__tests__/selector-capture.test.ts +22 -0
- package/src/tree/__tests__/selector-complex.test.ts +120 -0
- package/src/tree/__tests__/selector-compound.test.ts +74 -0
- package/src/tree/__tests__/selector-interpolated.test.ts +50 -0
- package/src/tree/__tests__/selector-list.test.ts +59 -0
- package/src/tree/__tests__/selector-pseudo.test.ts +23 -0
- package/src/tree/__tests__/selector.test.ts +182 -0
- package/src/tree/__tests__/sequence.test.ts +226 -0
- package/src/tree/__tests__/serialize-types.test.ts +529 -0
- package/src/tree/__tests__/spaced.test.ts +8 -0
- package/src/tree/__tests__/url.test.ts +72 -0
- package/src/tree/__tests__/var-declaration.test.ts +90 -0
- package/src/tree/ampersand.ts +538 -0
- package/src/tree/any.ts +169 -0
- package/src/tree/at-rule.ts +760 -0
- package/src/tree/block.ts +72 -0
- package/src/tree/bool.ts +46 -0
- package/src/tree/call.ts +593 -0
- package/src/tree/collection.ts +52 -0
- package/src/tree/color.ts +629 -0
- package/src/tree/combinator.ts +30 -0
- package/src/tree/comment.ts +36 -0
- package/src/tree/condition.ts +194 -0
- package/src/tree/control.ts +452 -0
- package/src/tree/declaration-custom.ts +56 -0
- package/src/tree/declaration-var.ts +87 -0
- package/src/tree/declaration.ts +742 -0
- package/src/tree/default-guard.ts +35 -0
- package/src/tree/dimension.ts +392 -0
- package/src/tree/expression.ts +97 -0
- package/src/tree/extend-list.ts +51 -0
- package/src/tree/extend.ts +391 -0
- package/src/tree/function.ts +254 -0
- package/src/tree/import-js.ts +130 -0
- package/src/tree/import-style.ts +875 -0
- package/{lib/tree/index.js → src/tree/index.ts} +49 -22
- package/src/tree/interpolated.ts +346 -0
- package/src/tree/js-array.ts +21 -0
- package/src/tree/js-expr.ts +50 -0
- package/src/tree/js-function.ts +31 -0
- package/src/tree/js-object.ts +22 -0
- package/src/tree/list.ts +415 -0
- package/src/tree/log.ts +89 -0
- package/src/tree/mixin.ts +331 -0
- package/src/tree/negative.ts +58 -0
- package/src/tree/nil.ts +57 -0
- package/src/tree/node-base.ts +1716 -0
- package/src/tree/node-type.ts +122 -0
- package/src/tree/node.ts +118 -0
- package/src/tree/number.ts +54 -0
- package/src/tree/operation.ts +187 -0
- package/src/tree/paren.ts +132 -0
- package/src/tree/query-condition.ts +47 -0
- package/src/tree/quoted.ts +119 -0
- package/src/tree/range.ts +101 -0
- package/src/tree/reference.ts +1099 -0
- package/src/tree/rest.ts +55 -0
- package/src/tree/rules-raw.ts +52 -0
- package/src/tree/rules.ts +2896 -0
- package/src/tree/ruleset.ts +1217 -0
- package/src/tree/selector-attr.ts +172 -0
- package/src/tree/selector-basic.ts +75 -0
- package/src/tree/selector-capture.ts +85 -0
- package/src/tree/selector-complex.ts +189 -0
- package/src/tree/selector-compound.ts +205 -0
- package/src/tree/selector-interpolated.ts +95 -0
- package/src/tree/selector-list.ts +245 -0
- package/src/tree/selector-pseudo.ts +173 -0
- package/src/tree/selector-simple.ts +10 -0
- package/src/tree/selector.ts +152 -0
- package/src/tree/sequence.ts +463 -0
- package/src/tree/tree.ts +130 -0
- package/src/tree/url.ts +95 -0
- package/src/tree/util/EXTEND_ARCHITECTURE_ANALYSIS.md +215 -0
- package/src/tree/util/EXTEND_AUDIT.md +233 -0
- package/src/tree/util/EXTEND_BASELINE.md +64 -0
- package/src/tree/util/EXTEND_CALL_GRAPH_ANALYSIS.md +244 -0
- package/src/tree/util/EXTEND_DOCS.md +24 -0
- package/src/tree/util/EXTEND_FINAL_SUMMARY.md +95 -0
- package/src/tree/util/EXTEND_FUNCTION_AUDIT.md +1433 -0
- package/src/tree/util/EXTEND_OPTIMIZATION_PLAN.md +114 -0
- package/src/tree/util/EXTEND_REFACTORING_SUMMARY.md +152 -0
- package/src/tree/util/EXTEND_RULES.md +74 -0
- package/src/tree/util/EXTEND_UNUSED_FUNCTIONS.md +127 -0
- package/src/tree/util/EXTEND_UNUSED_FUNCTIONS_ANALYSIS.md +227 -0
- package/src/tree/util/NODE_COPY_REDUCTION_PLAN.md +12 -0
- package/src/tree/util/__tests__/EXTEND_TEST_INDEX.md +59 -0
- package/src/tree/util/__tests__/OPTIMIZATION-ANALYSIS.md +130 -0
- package/src/tree/util/__tests__/WALK_AND_CONSUME_DESIGN.md +138 -0
- package/src/tree/util/__tests__/_archive/2026-02-09__OPTIMIZATION-ANALYSIS.md +9 -0
- package/src/tree/util/__tests__/_archive/README.md +4 -0
- package/src/tree/util/__tests__/bitset.test.ts +142 -0
- package/src/tree/util/__tests__/debug-log.ts +50 -0
- package/src/tree/util/__tests__/extend-comment-handling.test.ts +187 -0
- package/src/tree/util/__tests__/extend-core-unit.test.ts +941 -0
- package/src/tree/util/__tests__/extend-pipeline-bench.test.ts +154 -0
- package/src/tree/util/__tests__/extend-pipeline-bench.ts +190 -0
- package/src/tree/util/__tests__/fast-reject.test.ts +377 -0
- package/src/tree/util/__tests__/is-node.test.ts +63 -0
- package/src/tree/util/__tests__/list-like.test.ts +63 -0
- package/src/tree/util/__tests__/outputwriter.test.ts +523 -0
- package/src/tree/util/__tests__/print.test.ts +183 -0
- package/src/tree/util/__tests__/process-extends.test.ts +226 -0
- package/src/tree/util/__tests__/process-leading-is.test.ts +205 -0
- package/src/tree/util/__tests__/recursion-helper.test.ts +184 -0
- package/src/tree/util/__tests__/selector-match-unit.test.ts +1427 -0
- package/src/tree/util/__tests__/sourcemap.test.ts +117 -0
- package/src/tree/util/ampersand-template.ts +9 -0
- package/src/tree/util/bitset.ts +194 -0
- package/src/tree/util/calculate.ts +11 -0
- package/src/tree/util/cast.ts +89 -0
- package/src/tree/util/cloning.ts +8 -0
- package/src/tree/util/collections.ts +299 -0
- package/src/tree/util/compare.ts +90 -0
- package/src/tree/util/cursor.ts +171 -0
- package/src/tree/util/extend-core.ts +2139 -0
- package/src/tree/util/extend-roots.ts +1108 -0
- package/src/tree/util/field-helpers.ts +354 -0
- package/src/tree/util/is-node.ts +43 -0
- package/src/tree/util/list-like.ts +93 -0
- package/src/tree/util/mixin-instance-primitives.ts +2020 -0
- package/src/tree/util/print.ts +303 -0
- package/src/tree/util/process-leading-is.ts +421 -0
- package/src/tree/util/recursion-helper.ts +54 -0
- package/src/tree/util/regex.ts +2 -0
- package/src/tree/util/registry-utils.ts +1953 -0
- package/src/tree/util/ruleset-trace.ts +17 -0
- package/src/tree/util/scoped-body-eval.ts +320 -0
- package/src/tree/util/selector-match-core.ts +2005 -0
- package/src/tree/util/selector-utils.ts +757 -0
- package/src/tree/util/serialize-helper.ts +535 -0
- package/src/tree/util/serialize-types.ts +318 -0
- package/src/tree/util/should-operate.ts +78 -0
- package/src/tree/util/sourcemap.ts +37 -0
- package/src/types/config.ts +247 -0
- package/src/types/index.ts +12 -0
- package/{lib/types/modes.d.ts → src/types/modes.ts} +2 -1
- package/src/types.d.ts +9 -0
- package/src/types.ts +68 -0
- package/src/use-webpack-resolver.ts +56 -0
- package/src/visitor/__tests__/visitor.test.ts +136 -0
- package/src/visitor/index.ts +263 -0
- package/{lib/visitor/less-visitor.js → src/visitor/less-visitor.ts} +3 -2
- package/lib/context.d.ts +0 -352
- package/lib/context.d.ts.map +0 -1
- package/lib/context.js +0 -636
- package/lib/context.js.map +0 -1
- package/lib/conversions.d.ts +0 -73
- package/lib/conversions.d.ts.map +0 -1
- package/lib/conversions.js +0 -253
- package/lib/conversions.js.map +0 -1
- package/lib/debug-log.d.ts +0 -2
- package/lib/debug-log.d.ts.map +0 -1
- package/lib/debug-log.js +0 -27
- package/lib/debug-log.js.map +0 -1
- package/lib/define-function.d.ts +0 -587
- package/lib/define-function.d.ts.map +0 -1
- package/lib/define-function.js +0 -726
- package/lib/define-function.js.map +0 -1
- package/lib/deprecation.d.ts +0 -34
- package/lib/deprecation.d.ts.map +0 -1
- package/lib/deprecation.js +0 -57
- package/lib/deprecation.js.map +0 -1
- package/lib/jess-error.d.ts +0 -343
- package/lib/jess-error.d.ts.map +0 -1
- package/lib/jess-error.js +0 -508
- package/lib/jess-error.js.map +0 -1
- package/lib/logger/deprecation-processing.d.ts +0 -41
- package/lib/logger/deprecation-processing.d.ts.map +0 -1
- package/lib/logger/deprecation-processing.js +0 -81
- package/lib/logger/deprecation-processing.js.map +0 -1
- package/lib/logger.d.ts +0 -10
- package/lib/logger.d.ts.map +0 -1
- package/lib/logger.js +0 -20
- package/lib/logger.js.map +0 -1
- package/lib/plugin.d.ts +0 -94
- package/lib/plugin.d.ts.map +0 -1
- package/lib/plugin.js +0 -174
- package/lib/plugin.js.map +0 -1
- package/lib/tree/ampersand.d.ts +0 -94
- package/lib/tree/ampersand.d.ts.map +0 -1
- package/lib/tree/ampersand.js +0 -269
- package/lib/tree/ampersand.js.map +0 -1
- package/lib/tree/any.d.ts +0 -58
- package/lib/tree/any.d.ts.map +0 -1
- package/lib/tree/any.js +0 -104
- package/lib/tree/any.js.map +0 -1
- package/lib/tree/at-rule.d.ts +0 -53
- package/lib/tree/at-rule.d.ts.map +0 -1
- package/lib/tree/at-rule.js +0 -503
- package/lib/tree/at-rule.js.map +0 -1
- package/lib/tree/block.d.ts +0 -22
- package/lib/tree/block.d.ts.map +0 -1
- package/lib/tree/block.js +0 -24
- package/lib/tree/block.js.map +0 -1
- package/lib/tree/bool.d.ts +0 -18
- package/lib/tree/bool.d.ts.map +0 -1
- package/lib/tree/bool.js +0 -28
- package/lib/tree/bool.js.map +0 -1
- package/lib/tree/call.d.ts +0 -66
- package/lib/tree/call.d.ts.map +0 -1
- package/lib/tree/call.js +0 -306
- package/lib/tree/call.js.map +0 -1
- package/lib/tree/collection.d.ts +0 -30
- package/lib/tree/collection.d.ts.map +0 -1
- package/lib/tree/collection.js +0 -37
- package/lib/tree/collection.js.map +0 -1
- package/lib/tree/color.d.ts +0 -101
- package/lib/tree/color.d.ts.map +0 -1
- package/lib/tree/color.js +0 -513
- package/lib/tree/color.js.map +0 -1
- package/lib/tree/combinator.d.ts +0 -13
- package/lib/tree/combinator.d.ts.map +0 -1
- package/lib/tree/combinator.js +0 -12
- package/lib/tree/combinator.js.map +0 -1
- package/lib/tree/comment.d.ts +0 -20
- package/lib/tree/comment.d.ts.map +0 -1
- package/lib/tree/comment.js +0 -19
- package/lib/tree/comment.js.map +0 -1
- package/lib/tree/condition.d.ts +0 -31
- package/lib/tree/condition.d.ts.map +0 -1
- package/lib/tree/condition.js +0 -103
- package/lib/tree/condition.js.map +0 -1
- package/lib/tree/control.d.ts +0 -104
- package/lib/tree/control.d.ts.map +0 -1
- package/lib/tree/control.js +0 -430
- package/lib/tree/control.js.map +0 -1
- package/lib/tree/declaration-custom.d.ts +0 -18
- package/lib/tree/declaration-custom.d.ts.map +0 -1
- package/lib/tree/declaration-custom.js +0 -24
- package/lib/tree/declaration-custom.js.map +0 -1
- package/lib/tree/declaration-var.d.ts +0 -35
- package/lib/tree/declaration-var.d.ts.map +0 -1
- package/lib/tree/declaration-var.js +0 -63
- package/lib/tree/declaration-var.js.map +0 -1
- package/lib/tree/declaration.d.ts +0 -78
- package/lib/tree/declaration.d.ts.map +0 -1
- package/lib/tree/declaration.js +0 -286
- package/lib/tree/declaration.js.map +0 -1
- package/lib/tree/default-guard.d.ts +0 -15
- package/lib/tree/default-guard.d.ts.map +0 -1
- package/lib/tree/default-guard.js +0 -19
- package/lib/tree/default-guard.js.map +0 -1
- package/lib/tree/dimension.d.ts +0 -34
- package/lib/tree/dimension.d.ts.map +0 -1
- package/lib/tree/dimension.js +0 -294
- package/lib/tree/dimension.js.map +0 -1
- package/lib/tree/expression.d.ts +0 -25
- package/lib/tree/expression.d.ts.map +0 -1
- package/lib/tree/expression.js +0 -32
- package/lib/tree/expression.js.map +0 -1
- package/lib/tree/extend-list.d.ts +0 -23
- package/lib/tree/extend-list.d.ts.map +0 -1
- package/lib/tree/extend-list.js +0 -23
- package/lib/tree/extend-list.js.map +0 -1
- package/lib/tree/extend.d.ts +0 -47
- package/lib/tree/extend.d.ts.map +0 -1
- package/lib/tree/extend.js +0 -296
- package/lib/tree/extend.js.map +0 -1
- package/lib/tree/function.d.ts +0 -48
- package/lib/tree/function.d.ts.map +0 -1
- package/lib/tree/function.js +0 -74
- package/lib/tree/function.js.map +0 -1
- package/lib/tree/import-js.d.ts +0 -35
- package/lib/tree/import-js.d.ts.map +0 -1
- package/lib/tree/import-js.js +0 -45
- package/lib/tree/import-js.js.map +0 -1
- package/lib/tree/import-style.d.ts +0 -156
- package/lib/tree/import-style.d.ts.map +0 -1
- package/lib/tree/import-style.js +0 -566
- package/lib/tree/import-style.js.map +0 -1
- package/lib/tree/index.d.ts +0 -71
- package/lib/tree/index.d.ts.map +0 -1
- package/lib/tree/index.js.map +0 -1
- package/lib/tree/interpolated-reference.d.ts +0 -24
- package/lib/tree/interpolated-reference.d.ts.map +0 -1
- package/lib/tree/interpolated-reference.js +0 -37
- package/lib/tree/interpolated-reference.js.map +0 -1
- package/lib/tree/interpolated.d.ts +0 -62
- package/lib/tree/interpolated.d.ts.map +0 -1
- package/lib/tree/interpolated.js +0 -204
- package/lib/tree/interpolated.js.map +0 -1
- package/lib/tree/js-array.d.ts +0 -10
- package/lib/tree/js-array.d.ts.map +0 -1
- package/lib/tree/js-array.js +0 -10
- package/lib/tree/js-array.js.map +0 -1
- package/lib/tree/js-expr.d.ts +0 -23
- package/lib/tree/js-expr.d.ts.map +0 -1
- package/lib/tree/js-expr.js +0 -28
- package/lib/tree/js-expr.js.map +0 -1
- package/lib/tree/js-function.d.ts +0 -20
- package/lib/tree/js-function.d.ts.map +0 -1
- package/lib/tree/js-function.js +0 -16
- package/lib/tree/js-function.js.map +0 -1
- package/lib/tree/js-object.d.ts +0 -10
- package/lib/tree/js-object.d.ts.map +0 -1
- package/lib/tree/js-object.js +0 -10
- package/lib/tree/js-object.js.map +0 -1
- package/lib/tree/list.d.ts +0 -38
- package/lib/tree/list.d.ts.map +0 -1
- package/lib/tree/list.js +0 -83
- package/lib/tree/list.js.map +0 -1
- package/lib/tree/log.d.ts +0 -29
- package/lib/tree/log.d.ts.map +0 -1
- package/lib/tree/log.js +0 -56
- package/lib/tree/log.js.map +0 -1
- package/lib/tree/mixin.d.ts +0 -87
- package/lib/tree/mixin.d.ts.map +0 -1
- package/lib/tree/mixin.js +0 -112
- package/lib/tree/mixin.js.map +0 -1
- package/lib/tree/negative.d.ts +0 -17
- package/lib/tree/negative.d.ts.map +0 -1
- package/lib/tree/negative.js +0 -22
- package/lib/tree/negative.js.map +0 -1
- package/lib/tree/nil.d.ts +0 -30
- package/lib/tree/nil.d.ts.map +0 -1
- package/lib/tree/nil.js +0 -35
- package/lib/tree/nil.js.map +0 -1
- package/lib/tree/node-base.d.ts +0 -361
- package/lib/tree/node-base.d.ts.map +0 -1
- package/lib/tree/node-base.js +0 -930
- package/lib/tree/node-base.js.map +0 -1
- package/lib/tree/node.d.ts +0 -10
- package/lib/tree/node.d.ts.map +0 -1
- package/lib/tree/node.js +0 -45
- package/lib/tree/node.js.map +0 -1
- package/lib/tree/number.d.ts +0 -21
- package/lib/tree/number.d.ts.map +0 -1
- package/lib/tree/number.js +0 -27
- package/lib/tree/number.js.map +0 -1
- package/lib/tree/operation.d.ts +0 -26
- package/lib/tree/operation.d.ts.map +0 -1
- package/lib/tree/operation.js +0 -103
- package/lib/tree/operation.js.map +0 -1
- package/lib/tree/paren.d.ts +0 -19
- package/lib/tree/paren.d.ts.map +0 -1
- package/lib/tree/paren.js +0 -92
- package/lib/tree/paren.js.map +0 -1
- package/lib/tree/query-condition.d.ts +0 -17
- package/lib/tree/query-condition.d.ts.map +0 -1
- package/lib/tree/query-condition.js +0 -39
- package/lib/tree/query-condition.js.map +0 -1
- package/lib/tree/quoted.d.ts +0 -28
- package/lib/tree/quoted.d.ts.map +0 -1
- package/lib/tree/quoted.js +0 -75
- package/lib/tree/quoted.js.map +0 -1
- package/lib/tree/range.d.ts +0 -33
- package/lib/tree/range.d.ts.map +0 -1
- package/lib/tree/range.js +0 -47
- package/lib/tree/range.js.map +0 -1
- package/lib/tree/reference.d.ts +0 -76
- package/lib/tree/reference.d.ts.map +0 -1
- package/lib/tree/reference.js +0 -521
- package/lib/tree/reference.js.map +0 -1
- package/lib/tree/rest.d.ts +0 -15
- package/lib/tree/rest.d.ts.map +0 -1
- package/lib/tree/rest.js +0 -32
- package/lib/tree/rest.js.map +0 -1
- package/lib/tree/rules-raw.d.ts +0 -17
- package/lib/tree/rules-raw.d.ts.map +0 -1
- package/lib/tree/rules-raw.js +0 -37
- package/lib/tree/rules-raw.js.map +0 -1
- package/lib/tree/rules.d.ts +0 -262
- package/lib/tree/rules.d.ts.map +0 -1
- package/lib/tree/rules.js +0 -2359
- package/lib/tree/rules.js.map +0 -1
- package/lib/tree/ruleset.d.ts +0 -92
- package/lib/tree/ruleset.d.ts.map +0 -1
- package/lib/tree/ruleset.js +0 -528
- package/lib/tree/ruleset.js.map +0 -1
- package/lib/tree/selector-attr.d.ts +0 -31
- package/lib/tree/selector-attr.d.ts.map +0 -1
- package/lib/tree/selector-attr.js +0 -99
- package/lib/tree/selector-attr.js.map +0 -1
- package/lib/tree/selector-basic.d.ts +0 -24
- package/lib/tree/selector-basic.d.ts.map +0 -1
- package/lib/tree/selector-basic.js +0 -38
- package/lib/tree/selector-basic.js.map +0 -1
- package/lib/tree/selector-capture.d.ts +0 -23
- package/lib/tree/selector-capture.d.ts.map +0 -1
- package/lib/tree/selector-capture.js +0 -34
- package/lib/tree/selector-capture.js.map +0 -1
- package/lib/tree/selector-complex.d.ts +0 -40
- package/lib/tree/selector-complex.d.ts.map +0 -1
- package/lib/tree/selector-complex.js +0 -143
- package/lib/tree/selector-complex.js.map +0 -1
- package/lib/tree/selector-compound.d.ts +0 -16
- package/lib/tree/selector-compound.d.ts.map +0 -1
- package/lib/tree/selector-compound.js +0 -114
- package/lib/tree/selector-compound.js.map +0 -1
- package/lib/tree/selector-interpolated.d.ts +0 -23
- package/lib/tree/selector-interpolated.d.ts.map +0 -1
- package/lib/tree/selector-interpolated.js +0 -27
- package/lib/tree/selector-interpolated.js.map +0 -1
- package/lib/tree/selector-list.d.ts +0 -17
- package/lib/tree/selector-list.d.ts.map +0 -1
- package/lib/tree/selector-list.js +0 -174
- package/lib/tree/selector-list.js.map +0 -1
- package/lib/tree/selector-pseudo.d.ts +0 -42
- package/lib/tree/selector-pseudo.d.ts.map +0 -1
- package/lib/tree/selector-pseudo.js +0 -204
- package/lib/tree/selector-pseudo.js.map +0 -1
- package/lib/tree/selector-simple.d.ts +0 -5
- package/lib/tree/selector-simple.d.ts.map +0 -1
- package/lib/tree/selector-simple.js +0 -6
- package/lib/tree/selector-simple.js.map +0 -1
- package/lib/tree/selector.d.ts +0 -43
- package/lib/tree/selector.d.ts.map +0 -1
- package/lib/tree/selector.js +0 -56
- package/lib/tree/selector.js.map +0 -1
- package/lib/tree/sequence.d.ts +0 -43
- package/lib/tree/sequence.d.ts.map +0 -1
- package/lib/tree/sequence.js +0 -151
- package/lib/tree/sequence.js.map +0 -1
- package/lib/tree/tree.d.ts +0 -87
- package/lib/tree/tree.d.ts.map +0 -1
- package/lib/tree/tree.js +0 -2
- package/lib/tree/tree.js.map +0 -1
- package/lib/tree/url.d.ts +0 -18
- package/lib/tree/url.d.ts.map +0 -1
- package/lib/tree/url.js +0 -35
- package/lib/tree/url.js.map +0 -1
- package/lib/tree/util/__tests__/debug-log.d.ts +0 -1
- package/lib/tree/util/__tests__/debug-log.d.ts.map +0 -1
- package/lib/tree/util/__tests__/debug-log.js +0 -36
- package/lib/tree/util/__tests__/debug-log.js.map +0 -1
- package/lib/tree/util/calculate.d.ts +0 -3
- package/lib/tree/util/calculate.d.ts.map +0 -1
- package/lib/tree/util/calculate.js +0 -10
- package/lib/tree/util/calculate.js.map +0 -1
- package/lib/tree/util/cast.d.ts +0 -10
- package/lib/tree/util/cast.d.ts.map +0 -1
- package/lib/tree/util/cast.js +0 -87
- package/lib/tree/util/cast.js.map +0 -1
- package/lib/tree/util/cloning.d.ts +0 -4
- package/lib/tree/util/cloning.d.ts.map +0 -1
- package/lib/tree/util/cloning.js +0 -8
- package/lib/tree/util/cloning.js.map +0 -1
- package/lib/tree/util/collections.d.ts +0 -57
- package/lib/tree/util/collections.d.ts.map +0 -1
- package/lib/tree/util/collections.js +0 -136
- package/lib/tree/util/collections.js.map +0 -1
- package/lib/tree/util/compare.d.ts +0 -11
- package/lib/tree/util/compare.d.ts.map +0 -1
- package/lib/tree/util/compare.js +0 -89
- package/lib/tree/util/compare.js.map +0 -1
- package/lib/tree/util/extend-helpers.d.ts +0 -2
- package/lib/tree/util/extend-helpers.d.ts.map +0 -1
- package/lib/tree/util/extend-helpers.js +0 -2
- package/lib/tree/util/extend-helpers.js.map +0 -1
- package/lib/tree/util/extend-roots.d.ts +0 -37
- package/lib/tree/util/extend-roots.d.ts.map +0 -1
- package/lib/tree/util/extend-roots.js +0 -700
- package/lib/tree/util/extend-roots.js.map +0 -1
- package/lib/tree/util/extend-roots.old.d.ts +0 -132
- package/lib/tree/util/extend-roots.old.d.ts.map +0 -1
- package/lib/tree/util/extend-roots.old.js +0 -2272
- package/lib/tree/util/extend-roots.old.js.map +0 -1
- package/lib/tree/util/extend-trace-debug.d.ts +0 -13
- package/lib/tree/util/extend-trace-debug.d.ts.map +0 -1
- package/lib/tree/util/extend-trace-debug.js +0 -34
- package/lib/tree/util/extend-trace-debug.js.map +0 -1
- package/lib/tree/util/extend-walk.d.ts +0 -53
- package/lib/tree/util/extend-walk.d.ts.map +0 -1
- package/lib/tree/util/extend-walk.js +0 -881
- package/lib/tree/util/extend-walk.js.map +0 -1
- package/lib/tree/util/extend.d.ts +0 -218
- package/lib/tree/util/extend.d.ts.map +0 -1
- package/lib/tree/util/extend.js +0 -3182
- package/lib/tree/util/extend.js.map +0 -1
- package/lib/tree/util/find-extendable-locations.d.ts +0 -2
- package/lib/tree/util/find-extendable-locations.d.ts.map +0 -1
- package/lib/tree/util/find-extendable-locations.js +0 -2
- package/lib/tree/util/find-extendable-locations.js.map +0 -1
- package/lib/tree/util/format.d.ts +0 -20
- package/lib/tree/util/format.d.ts.map +0 -1
- package/lib/tree/util/format.js +0 -67
- package/lib/tree/util/format.js.map +0 -1
- package/lib/tree/util/is-node.d.ts +0 -13
- package/lib/tree/util/is-node.d.ts.map +0 -1
- package/lib/tree/util/is-node.js +0 -43
- package/lib/tree/util/is-node.js.map +0 -1
- package/lib/tree/util/print.d.ts +0 -80
- package/lib/tree/util/print.d.ts.map +0 -1
- package/lib/tree/util/print.js +0 -205
- package/lib/tree/util/print.js.map +0 -1
- package/lib/tree/util/process-leading-is.d.ts +0 -25
- package/lib/tree/util/process-leading-is.d.ts.map +0 -1
- package/lib/tree/util/process-leading-is.js +0 -364
- package/lib/tree/util/process-leading-is.js.map +0 -1
- package/lib/tree/util/recursion-helper.d.ts +0 -15
- package/lib/tree/util/recursion-helper.d.ts.map +0 -1
- package/lib/tree/util/recursion-helper.js +0 -43
- package/lib/tree/util/recursion-helper.js.map +0 -1
- package/lib/tree/util/regex.d.ts +0 -4
- package/lib/tree/util/regex.d.ts.map +0 -1
- package/lib/tree/util/regex.js +0 -4
- package/lib/tree/util/regex.js.map +0 -1
- package/lib/tree/util/registry-utils.d.ts +0 -192
- package/lib/tree/util/registry-utils.d.ts.map +0 -1
- package/lib/tree/util/registry-utils.js +0 -1214
- package/lib/tree/util/registry-utils.js.map +0 -1
- package/lib/tree/util/ruleset-trace.d.ts +0 -4
- package/lib/tree/util/ruleset-trace.d.ts.map +0 -1
- package/lib/tree/util/ruleset-trace.js +0 -14
- package/lib/tree/util/ruleset-trace.js.map +0 -1
- package/lib/tree/util/selector-compare.d.ts +0 -2
- package/lib/tree/util/selector-compare.d.ts.map +0 -1
- package/lib/tree/util/selector-compare.js +0 -2
- package/lib/tree/util/selector-compare.js.map +0 -1
- package/lib/tree/util/selector-match-core.d.ts +0 -184
- package/lib/tree/util/selector-match-core.d.ts.map +0 -1
- package/lib/tree/util/selector-match-core.js +0 -1603
- package/lib/tree/util/selector-match-core.js.map +0 -1
- package/lib/tree/util/selector-utils.d.ts +0 -30
- package/lib/tree/util/selector-utils.d.ts.map +0 -1
- package/lib/tree/util/selector-utils.js +0 -100
- package/lib/tree/util/selector-utils.js.map +0 -1
- package/lib/tree/util/serialize-helper.d.ts +0 -13
- package/lib/tree/util/serialize-helper.d.ts.map +0 -1
- package/lib/tree/util/serialize-helper.js +0 -387
- package/lib/tree/util/serialize-helper.js.map +0 -1
- package/lib/tree/util/serialize-types.d.ts +0 -9
- package/lib/tree/util/serialize-types.d.ts.map +0 -1
- package/lib/tree/util/serialize-types.js +0 -216
- package/lib/tree/util/serialize-types.js.map +0 -1
- package/lib/tree/util/should-operate.d.ts +0 -23
- package/lib/tree/util/should-operate.d.ts.map +0 -1
- package/lib/tree/util/should-operate.js +0 -46
- package/lib/tree/util/should-operate.js.map +0 -1
- package/lib/tree/util/sourcemap.d.ts +0 -7
- package/lib/tree/util/sourcemap.d.ts.map +0 -1
- package/lib/tree/util/sourcemap.js +0 -25
- package/lib/tree/util/sourcemap.js.map +0 -1
- package/lib/types/config.d.ts +0 -205
- package/lib/types/config.d.ts.map +0 -1
- package/lib/types/config.js +0 -2
- package/lib/types/config.js.map +0 -1
- package/lib/types/index.d.ts +0 -15
- package/lib/types/index.d.ts.map +0 -1
- package/lib/types/index.js +0 -3
- package/lib/types/index.js.map +0 -1
- package/lib/types/modes.d.ts.map +0 -1
- package/lib/types/modes.js +0 -2
- package/lib/types/modes.js.map +0 -1
- package/lib/types.d.ts +0 -61
- package/lib/types.d.ts.map +0 -1
- package/lib/types.js +0 -2
- package/lib/types.js.map +0 -1
- package/lib/use-webpack-resolver.d.ts +0 -9
- package/lib/use-webpack-resolver.d.ts.map +0 -1
- package/lib/use-webpack-resolver.js +0 -41
- package/lib/use-webpack-resolver.js.map +0 -1
- package/lib/visitor/index.d.ts +0 -136
- package/lib/visitor/index.d.ts.map +0 -1
- package/lib/visitor/index.js +0 -135
- package/lib/visitor/index.js.map +0 -1
- package/lib/visitor/less-visitor.d.ts +0 -7
- package/lib/visitor/less-visitor.d.ts.map +0 -1
- package/lib/visitor/less-visitor.js.map +0 -1
package/src/context.ts
ADDED
|
@@ -0,0 +1,896 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AtRule,
|
|
3
|
+
Ruleset,
|
|
4
|
+
Rules,
|
|
5
|
+
ImportOptions,
|
|
6
|
+
Node,
|
|
7
|
+
Any,
|
|
8
|
+
Selector
|
|
9
|
+
} from './tree/index.js';
|
|
10
|
+
import { ExtendRootRegistry } from './tree/util/extend-roots.js';
|
|
11
|
+
import { type Operator } from './tree/util/calculate.js';
|
|
12
|
+
import type { RenderKey } from './tree/node-base.js';
|
|
13
|
+
import type { PluginInterface } from './plugin.js';
|
|
14
|
+
import { EqualityMode, MathMode, UnitMode } from './types/modes.js';
|
|
15
|
+
import * as path from 'node:path';
|
|
16
|
+
import { isNode } from './tree/util/is-node.js';
|
|
17
|
+
import { N } from './tree/node-type.js';
|
|
18
|
+
import { shouldOperateWithMathFrames } from './tree/util/should-operate.js';
|
|
19
|
+
import { type ErrorDiagnostic, type WarningDiagnostic, JessError } from './jess-error.js';
|
|
20
|
+
import type { Call } from './tree/call.js';
|
|
21
|
+
import { CallMap } from './tree/util/recursion-helper.js';
|
|
22
|
+
import { createRequire } from 'node:module';
|
|
23
|
+
import { BitSetLibrary } from './tree/util/bitset.js';
|
|
24
|
+
import type { EvalDependency } from './tree/util/field-helpers.js';
|
|
25
|
+
|
|
26
|
+
export interface ContextOptions {
|
|
27
|
+
/** Hash classes for module output */
|
|
28
|
+
module?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* From docs:
|
|
31
|
+
* "Changes compilation mode so dynamic content
|
|
32
|
+
* is output as CSS variables, and changes
|
|
33
|
+
* the runtime module to generate CSS patches."
|
|
34
|
+
*
|
|
35
|
+
* @todo - Change this behavior to "live expressions"
|
|
36
|
+
* i.e. change compilation to always be static, but
|
|
37
|
+
* generate a separate module for calculated CSS variables.
|
|
38
|
+
*/
|
|
39
|
+
dynamic?: boolean;
|
|
40
|
+
collapseNesting?: boolean;
|
|
41
|
+
|
|
42
|
+
enableJavaScript?: boolean;
|
|
43
|
+
mathMode?: MathMode;
|
|
44
|
+
unitMode?: UnitMode;
|
|
45
|
+
equalityMode?: EqualityMode;
|
|
46
|
+
|
|
47
|
+
/** Directories to search to resolve files */
|
|
48
|
+
searchPaths?: string[];
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Whether to leak variables and mixins into the caller scope,
|
|
52
|
+
* such that they can be referenced / called by subsequent rules.
|
|
53
|
+
*
|
|
54
|
+
* @deprecated - a Less feature
|
|
55
|
+
*/
|
|
56
|
+
leakyRules?: boolean;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Whether to bubble root-only at-rules (like @font-face, @keyframes)
|
|
60
|
+
* to the root level when they're nested inside rulesets.
|
|
61
|
+
*
|
|
62
|
+
* @deprecated - a legacy Less feature; modern CSS allows nesting
|
|
63
|
+
*/
|
|
64
|
+
bubbleRootAtRules?: boolean;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Suppress warnings (similar to Less's suppressWarnings option).
|
|
68
|
+
* When true, warnings are collected but not emitted.
|
|
69
|
+
*/
|
|
70
|
+
suppressWarnings?: boolean;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Break on first error (stop processing after first error).
|
|
74
|
+
* When false, errors are collected and processing continues.
|
|
75
|
+
*/
|
|
76
|
+
breakOnError?: boolean;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface TreeContextOptions extends ContextOptions {
|
|
80
|
+
inlineJavaScript?: boolean;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* For instances where a new tree needs to inherit from scope
|
|
84
|
+
* (like Less / SCSS `@import` rule)
|
|
85
|
+
*
|
|
86
|
+
* @todo - remove?
|
|
87
|
+
*/
|
|
88
|
+
parentScope?: Rules;
|
|
89
|
+
scope?: Rules;
|
|
90
|
+
|
|
91
|
+
isModule?: boolean;
|
|
92
|
+
|
|
93
|
+
file?: {
|
|
94
|
+
/** Filename, e.g. "main.jess" */
|
|
95
|
+
name: string;
|
|
96
|
+
|
|
97
|
+
/** Absolute directory containing the file (no filename) */
|
|
98
|
+
path: string;
|
|
99
|
+
|
|
100
|
+
/** Absolute file path (directory + filename) */
|
|
101
|
+
fullPath: string;
|
|
102
|
+
|
|
103
|
+
/** Full file contents (recommended for code-frames) */
|
|
104
|
+
source?: string;
|
|
105
|
+
|
|
106
|
+
/** Lazy cache of line-start offsets (built on demand) */
|
|
107
|
+
lines?: Uint32Array;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
[k: string]: any;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const idChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @todo - Redo:
|
|
117
|
+
* 1. Create a hash of the file path; that way hashes
|
|
118
|
+
* are unique per file, but also repeatable / predictable.
|
|
119
|
+
* 2. Append file (module) hash after class name
|
|
120
|
+
*/
|
|
121
|
+
export const generateId = (length = 8) => {
|
|
122
|
+
let str = '';
|
|
123
|
+
let idCharsLength = idChars.length;
|
|
124
|
+
for (let i = 0; i < length; i++) {
|
|
125
|
+
str += idChars[Math.floor(Math.random() * idCharsLength)]!;
|
|
126
|
+
}
|
|
127
|
+
return str;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Tree context is attached to each node
|
|
132
|
+
* during the parsing phase / AST creation.
|
|
133
|
+
*
|
|
134
|
+
* Each file (and hence, tree) will get a new tree
|
|
135
|
+
* context. For the most part, it is passed around
|
|
136
|
+
* as an object reference.
|
|
137
|
+
*
|
|
138
|
+
* Additionally, it sets options that may be
|
|
139
|
+
* unique to the tree, such as the math mode.
|
|
140
|
+
*/
|
|
141
|
+
export class TreeContext implements TreeContextOptions {
|
|
142
|
+
opts: Record<string, any>;
|
|
143
|
+
// changed to `rulesVisiblity` set during parsing
|
|
144
|
+
leakyRules: boolean | undefined;
|
|
145
|
+
bubbleRootAtRules: boolean | undefined;
|
|
146
|
+
mathMode: MathMode | undefined;
|
|
147
|
+
unitMode: UnitMode | undefined;
|
|
148
|
+
equalityMode: EqualityMode | undefined;
|
|
149
|
+
|
|
150
|
+
/** @todo - Change how extend works based on this value */
|
|
151
|
+
isModule: boolean | undefined;
|
|
152
|
+
|
|
153
|
+
file?: TreeContextOptions['file'];
|
|
154
|
+
/**
|
|
155
|
+
* The plugin that created this tree. It will have first dibs
|
|
156
|
+
* to resolve any imports.
|
|
157
|
+
*/
|
|
158
|
+
plugin?: PluginInterface;
|
|
159
|
+
|
|
160
|
+
constructor(opts: TreeContextOptions = {}) {
|
|
161
|
+
/**
|
|
162
|
+
* Known options are attached to the instance.
|
|
163
|
+
* Unknown options are assigned to `opts`
|
|
164
|
+
*/
|
|
165
|
+
let {
|
|
166
|
+
mathMode,
|
|
167
|
+
unitMode,
|
|
168
|
+
equalityMode,
|
|
169
|
+
isModule,
|
|
170
|
+
file,
|
|
171
|
+
plugin,
|
|
172
|
+
leakyRules,
|
|
173
|
+
bubbleRootAtRules,
|
|
174
|
+
...rest
|
|
175
|
+
} = opts;
|
|
176
|
+
this.mathMode = mathMode;
|
|
177
|
+
this.unitMode = unitMode;
|
|
178
|
+
this.equalityMode = equalityMode;
|
|
179
|
+
this.isModule = isModule;
|
|
180
|
+
this.file = file;
|
|
181
|
+
this.plugin = plugin;
|
|
182
|
+
this.leakyRules = leakyRules;
|
|
183
|
+
this.bubbleRootAtRules = bubbleRootAtRules;
|
|
184
|
+
// this.scope = scope ?? new Scope(parentScope)
|
|
185
|
+
this.opts = rest;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* .a.b.c
|
|
191
|
+
* simple = 0b1
|
|
192
|
+
* compound = 0b10
|
|
193
|
+
* complex = 0b100
|
|
194
|
+
* a = 0b1000
|
|
195
|
+
* b = 0b10000
|
|
196
|
+
* c = 0b100000
|
|
197
|
+
*
|
|
198
|
+
* .a.b.c.c = 0b111010
|
|
199
|
+
*/
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* This is the context object used for evaluation.
|
|
203
|
+
*
|
|
204
|
+
* @note
|
|
205
|
+
* Most of context represents "state" while evaluating.
|
|
206
|
+
* There should only ever be one Context singleton per parse & evaluation.
|
|
207
|
+
*/
|
|
208
|
+
export class Context {
|
|
209
|
+
readonly plugins: PluginInterface[];
|
|
210
|
+
readonly opts: ContextOptions;
|
|
211
|
+
|
|
212
|
+
treeContext!: TreeContext;
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Collected errors during safeParse/safeRender.
|
|
216
|
+
* Only populated when using safe methods.
|
|
217
|
+
*/
|
|
218
|
+
errors: ErrorDiagnostic[] = [];
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Collected warnings during safeParse/safeRender.
|
|
222
|
+
* Only populated when using safe methods.
|
|
223
|
+
*/
|
|
224
|
+
warnings: WarningDiagnostic[] = [];
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* A feature ported from Less - we suppress any `@charset`
|
|
228
|
+
* after the first one.
|
|
229
|
+
*/
|
|
230
|
+
currentCharset?: Any;
|
|
231
|
+
/** Track whether charset has been emitted during toString to avoid duplicates */
|
|
232
|
+
charsetEmitted?: boolean;
|
|
233
|
+
|
|
234
|
+
/** @import rules must be at the top of CSS output */
|
|
235
|
+
topImports?: Node[];
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* This is set when entering rulesets so that child nodes
|
|
239
|
+
* can use this to lookup values. When evaluating inside a mixin/function,
|
|
240
|
+
* this also enables call-time variable resolution ($~variable).
|
|
241
|
+
*/
|
|
242
|
+
rulesContext!: Rules;
|
|
243
|
+
/**
|
|
244
|
+
* Internal transient lookup-scope override.
|
|
245
|
+
*
|
|
246
|
+
* Used by direct mixin/function invocation so canonical bodies can evaluate
|
|
247
|
+
* against a prepared outer scope without changing the public node API.
|
|
248
|
+
*/
|
|
249
|
+
lookupScope?: Rules;
|
|
250
|
+
/** Entire context root (ultimate root) */
|
|
251
|
+
root!: Rules;
|
|
252
|
+
/** Set so that we can do ruleset selector lookup for extend */
|
|
253
|
+
treeRoot!: Rules;
|
|
254
|
+
allRoots: Rules[] = [];
|
|
255
|
+
|
|
256
|
+
/** The call that is currently being evaluated */
|
|
257
|
+
caller?: Call;
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Current render-key selection for parent/edge-sensitive traversal.
|
|
261
|
+
*
|
|
262
|
+
* Canonical traversal falls back when no alternate edge exists.
|
|
263
|
+
*/
|
|
264
|
+
renderKey?: RenderKey;
|
|
265
|
+
|
|
266
|
+
/** Extend roots registry for managing extend scoping */
|
|
267
|
+
extendRoots!: ExtendRootRegistry;
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Depth-first document order of each Ruleset (assigned once per root before eval).
|
|
271
|
+
* Used so processExtends can apply extends in true source order.
|
|
272
|
+
*
|
|
273
|
+
* @todo - Probably remove once I fix extends
|
|
274
|
+
*/
|
|
275
|
+
documentOrderByRuleset?: WeakMap<Ruleset, number>;
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Registered extends with their extend root context
|
|
279
|
+
* Format: [target, selectorWithExtend, partial, extendRoot, extendNode, documentOrder?, fromReferenceScope?, namespace?]
|
|
280
|
+
*
|
|
281
|
+
* @todo - Probably remove once I fix extends
|
|
282
|
+
*/
|
|
283
|
+
extends: Array<[target: Selector, selectorWithExtend: Selector, partial: boolean, extendRoot: Rules, extendNode: Node, documentOrder?: number, fromReferenceScope?: boolean, namespace?: string]> = [];
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* When doing any kind of lookup, the current node and resolved
|
|
287
|
+
* nodes in the search chain are added to prevent recursion errors.
|
|
288
|
+
*
|
|
289
|
+
* Search-scope identity is canonical when available (`sourceNode ?? node`)
|
|
290
|
+
* so derived wrappers do not bypass recursion guards.
|
|
291
|
+
* Also used to track mixins currently being evaluated to prevent infinite recursion.
|
|
292
|
+
*/
|
|
293
|
+
private _searchScope: Set<Node> | undefined;
|
|
294
|
+
get searchScope() {
|
|
295
|
+
return (this._searchScope ??= new Set());
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
getSearchScopeIdentity(node: Node): Node {
|
|
299
|
+
return node.sourceNode ?? node;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
hasInSearchScope(node: Node): boolean {
|
|
303
|
+
return this.searchScope.has(this.getSearchScopeIdentity(node));
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
addToSearchScope(node: Node): void {
|
|
307
|
+
this.searchScope.add(this.getSearchScopeIdentity(node));
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
deleteFromSearchScope(node: Node): void {
|
|
311
|
+
this.searchScope.delete(this.getSearchScopeIdentity(node));
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* The file (eval) context should have the same ID at compile-time
|
|
316
|
+
* as run-time, so this ID will be set in `toModule()` output
|
|
317
|
+
*
|
|
318
|
+
* @todo - Make the id a hash of the (project-relative) path + contents
|
|
319
|
+
*/
|
|
320
|
+
id = generateId();
|
|
321
|
+
ruleCounter = 0;
|
|
322
|
+
renderCounter = 0;
|
|
323
|
+
|
|
324
|
+
/** Rules depth, used to figure out source order */
|
|
325
|
+
depth = -1;
|
|
326
|
+
|
|
327
|
+
/** Selector valueOf() strings to bitset positions */
|
|
328
|
+
selectorBits = new BitSetLibrary<string>();
|
|
329
|
+
|
|
330
|
+
private _classMap: Map<string, string> | undefined;
|
|
331
|
+
get classMap() {
|
|
332
|
+
return (this._classMap ??= new Map());
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/** Frames for nested rulesets, used for selector evaluation */
|
|
336
|
+
rulesetFrames: Ruleset[] = [];
|
|
337
|
+
/**
|
|
338
|
+
* When mixin eval clears `rulesetFrames`, this preserves the caller's
|
|
339
|
+
* last ruleset frame so at-rule hoisting can still pick up the caller's
|
|
340
|
+
* selector for the wrapper Ruleset.
|
|
341
|
+
*/
|
|
342
|
+
callerRulesetFrame: Ruleset | undefined;
|
|
343
|
+
/** Unified frames array for flat rendering when collapseNesting is true */
|
|
344
|
+
frames: (Ruleset | AtRule)[] = [];
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* We push a boolean to this array when entering a calc() call
|
|
348
|
+
* and pop it when leaving. This helps us determine if operations
|
|
349
|
+
* should be performed or not.
|
|
350
|
+
*
|
|
351
|
+
* @todo - can't this just be a number?
|
|
352
|
+
*/
|
|
353
|
+
calcFrames = 0;
|
|
354
|
+
|
|
355
|
+
private _callMap: CallMap | undefined;
|
|
356
|
+
get callMap() {
|
|
357
|
+
return (this._callMap ??= new CallMap());
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
private _callStack: Call[] | undefined;
|
|
361
|
+
get callStack() {
|
|
362
|
+
return (this._callStack ??= []);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Stack to track reference call chain for clearing matched keys at outermost level
|
|
367
|
+
*/
|
|
368
|
+
private _referenceStack: number = 0;
|
|
369
|
+
get referenceStack() {
|
|
370
|
+
return this._referenceStack;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Import-evaluation scope stack.
|
|
375
|
+
*
|
|
376
|
+
* This intentionally models lexical import scope instead of global counters:
|
|
377
|
+
* - each import branch pushes its semantics on entry
|
|
378
|
+
* - each branch pops in `finally`
|
|
379
|
+
* - readers ask semantic questions (`inReferenceImportScope`) instead of
|
|
380
|
+
* inspecting mutable depth values.
|
|
381
|
+
*
|
|
382
|
+
* Why this exists:
|
|
383
|
+
* some behaviors depend on "how we got here" (call-path scope), not only
|
|
384
|
+
* on the current node's own options. Example: suppressing top-level @import
|
|
385
|
+
* hoists while traversing a reference-only branch.
|
|
386
|
+
*/
|
|
387
|
+
private _importScopeStack: Array<{ reference: boolean; multiple: boolean }> = [];
|
|
388
|
+
get importScope() {
|
|
389
|
+
return this._importScopeStack;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
get inReferenceImportScope() {
|
|
393
|
+
return this._importScopeStack.some(scope => scope.reference);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
get inMultipleImportScope() {
|
|
397
|
+
return this._importScopeStack.some(scope => scope.multiple);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
pushImportScope(scope: { reference?: boolean; multiple?: boolean }) {
|
|
401
|
+
this._importScopeStack.push({
|
|
402
|
+
reference: scope.reference === true,
|
|
403
|
+
multiple: scope.multiple === true
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
popImportScope() {
|
|
408
|
+
if (this._importScopeStack.length > 0) {
|
|
409
|
+
this._importScopeStack.pop();
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
pushReference() {
|
|
414
|
+
this._referenceStack++;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Stack to track when a value comes from an important declaration
|
|
419
|
+
* Used to propagate !important flag to containing declarations
|
|
420
|
+
*/
|
|
421
|
+
private _importantSourceStack: number = 0;
|
|
422
|
+
get hasImportantSource() {
|
|
423
|
+
return this._importantSourceStack > 0;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
pushImportantSource() {
|
|
427
|
+
this._importantSourceStack++;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
popImportantSource() {
|
|
431
|
+
if (this._importantSourceStack > 0) {
|
|
432
|
+
this._importantSourceStack--;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
popReference() {
|
|
437
|
+
this._referenceStack--;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
rulesEvalStack: Rules[] = [];
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* We push a boolean to this array when entering parens call
|
|
444
|
+
* and pop it when leaving. This helps us determine if operations
|
|
445
|
+
* should be performed or not.
|
|
446
|
+
*
|
|
447
|
+
* Sometimes we "reset" the "in parentheses" state by pushing false,
|
|
448
|
+
* such as within a function call.
|
|
449
|
+
*/
|
|
450
|
+
parenFrames: boolean[] = [];
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Keys of @let variables --
|
|
454
|
+
* We need this b/c we need to generate code
|
|
455
|
+
* for over-riding in the exported function.
|
|
456
|
+
*
|
|
457
|
+
* @todo - remove?
|
|
458
|
+
*/
|
|
459
|
+
private _exports: Set<string> | undefined;
|
|
460
|
+
get exports(): Set<string> {
|
|
461
|
+
return (this._exports ??= new Set());
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
nextRenderKey(): RenderKey {
|
|
465
|
+
return ++this.renderCounter;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* currently generating a runtime module or not
|
|
470
|
+
* @todo - remove in favor of ToModuleVisitor?
|
|
471
|
+
*/
|
|
472
|
+
// isRuntime: boolean
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* In a custom declaration's value. All nodes should
|
|
476
|
+
* be preserved as-is and not evaluated, except for
|
|
477
|
+
* $() expressions.
|
|
478
|
+
*/
|
|
479
|
+
inCustom: boolean | undefined;
|
|
480
|
+
|
|
481
|
+
/** A flag set when evaluating conditions */
|
|
482
|
+
isDefault: boolean | undefined;
|
|
483
|
+
|
|
484
|
+
readonly dependencyMap = new WeakMap<Node, EvalDependency>();
|
|
485
|
+
|
|
486
|
+
_leakyRules: boolean | undefined;
|
|
487
|
+
get leakyRules() {
|
|
488
|
+
return this._leakyRules ?? this.treeContext?.leakyRules ?? false;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
_bubbleRootAtRules: boolean | undefined;
|
|
492
|
+
get bubbleRootAtRules() {
|
|
493
|
+
return this._bubbleRootAtRules ?? this.treeContext?.bubbleRootAtRules ?? false;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
constructor(opts: ContextOptions = {}, plugins?: PluginInterface[]) {
|
|
497
|
+
this.opts = opts;
|
|
498
|
+
this.plugins = plugins ?? [];
|
|
499
|
+
this.extendRoots = new ExtendRootRegistry();
|
|
500
|
+
if (opts.leakyRules !== undefined) {
|
|
501
|
+
this._leakyRules = opts.leakyRules;
|
|
502
|
+
}
|
|
503
|
+
if (opts.bubbleRootAtRules !== undefined) {
|
|
504
|
+
this._bubbleRootAtRules = opts.bubbleRootAtRules;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/** Full resolved path -> tree */
|
|
509
|
+
sourceTrees = new Map<string, Rules>();
|
|
510
|
+
evaldTrees = new Map<string, Rules>();
|
|
511
|
+
composeSetValues = new Map<string, Rules>();
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* @param importPath - The bare import path e.g. `@import "foo";` in a .less file.
|
|
515
|
+
*/
|
|
516
|
+
private async _getPath(importPath: string) {
|
|
517
|
+
const currentTree = this.treeContext;
|
|
518
|
+
const currentDirectory = currentTree?.file?.path ?? process.cwd();
|
|
519
|
+
const { searchPaths = [] } = this.opts;
|
|
520
|
+
|
|
521
|
+
const plugins = this.plugins;
|
|
522
|
+
let finalPath: string | undefined;
|
|
523
|
+
let currentPlugin = this.treeContext?.plugin;
|
|
524
|
+
|
|
525
|
+
/** First, expand imports */
|
|
526
|
+
let paths = currentPlugin?.expandImport?.(importPath, currentDirectory) ?? [importPath];
|
|
527
|
+
if (paths.length === 0) {
|
|
528
|
+
throw new Error(`No paths found for import "${importPath}"`);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/** Give current context plugin first dibs to resolve */
|
|
532
|
+
if (currentPlugin?.resolve) {
|
|
533
|
+
const result = await currentPlugin.resolve(paths, currentDirectory, searchPaths);
|
|
534
|
+
if (result) {
|
|
535
|
+
paths = result;
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/** Try to resolve using resolver plugins */
|
|
540
|
+
for (const plugin of plugins) {
|
|
541
|
+
if (plugin === currentPlugin) {
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
544
|
+
if (!plugin.resolve) {
|
|
545
|
+
continue;
|
|
546
|
+
}
|
|
547
|
+
const result = await plugin.resolve(paths, currentDirectory, searchPaths);
|
|
548
|
+
if (result) {
|
|
549
|
+
paths = result;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/** Now, try to locate the first matching file using locator plugins */
|
|
554
|
+
for (const plugin of plugins) {
|
|
555
|
+
if (!plugin.locate) {
|
|
556
|
+
continue;
|
|
557
|
+
}
|
|
558
|
+
const result = await plugin.locate(paths, currentDirectory);
|
|
559
|
+
if (result) {
|
|
560
|
+
finalPath = result;
|
|
561
|
+
break;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
if (!finalPath) {
|
|
566
|
+
// Fallback for bare module specifiers (e.g. "@scope/pkg/path").
|
|
567
|
+
const looksBareSpecifier = (p: string) =>
|
|
568
|
+
!path.isAbsolute(p)
|
|
569
|
+
&& !p.startsWith('./')
|
|
570
|
+
&& !p.startsWith('../')
|
|
571
|
+
&& !p.startsWith('/')
|
|
572
|
+
&& !/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(p);
|
|
573
|
+
const tryResolveModule = (request: string, basedir: string): string | undefined => {
|
|
574
|
+
try {
|
|
575
|
+
const req = createRequire(path.join(basedir, '__jess_resolve__.js'));
|
|
576
|
+
return req.resolve(request);
|
|
577
|
+
} catch {
|
|
578
|
+
return undefined;
|
|
579
|
+
}
|
|
580
|
+
};
|
|
581
|
+
const moduleBaseDirs = [currentDirectory, ...searchPaths, process.cwd()];
|
|
582
|
+
for (const candidate of paths) {
|
|
583
|
+
if (!looksBareSpecifier(candidate)) {
|
|
584
|
+
continue;
|
|
585
|
+
}
|
|
586
|
+
for (const baseDir of moduleBaseDirs) {
|
|
587
|
+
const base = path.isAbsolute(baseDir) ? baseDir : path.resolve(currentDirectory, baseDir);
|
|
588
|
+
const resolved = tryResolveModule(candidate, base) ?? tryResolveModule(`${candidate}.less`, base);
|
|
589
|
+
if (resolved) {
|
|
590
|
+
finalPath = resolved;
|
|
591
|
+
break;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
if (finalPath) {
|
|
595
|
+
break;
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
if (!finalPath) {
|
|
601
|
+
/** @todo - Add messaging around tried paths */
|
|
602
|
+
throw new Error(`File not found: ${importPath} (from: ${currentDirectory})`);
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
const normalizedFinalPath = finalPath.split(/[?#]/)[0]!;
|
|
606
|
+
const ext = path.extname(normalizedFinalPath);
|
|
607
|
+
const friendlyPath = path.relative(process.cwd(), normalizedFinalPath);
|
|
608
|
+
|
|
609
|
+
if (!ext) {
|
|
610
|
+
throw new Error(`File "${friendlyPath}" not supported`);
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
return {
|
|
614
|
+
triedPaths: paths,
|
|
615
|
+
resolvedPath: normalizedFinalPath,
|
|
616
|
+
friendlyPath
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* Find the appropriate plugin for parsing based on type or extension
|
|
622
|
+
*/
|
|
623
|
+
private findParserPlugin(type?: string, extension?: string): PluginInterface {
|
|
624
|
+
const plugins = this.plugins;
|
|
625
|
+
|
|
626
|
+
if (type) {
|
|
627
|
+
const plugin = plugins.find(plugin => plugin.name === type);
|
|
628
|
+
if (!plugin) {
|
|
629
|
+
throw new Error(`Plugin "${type}" not found`);
|
|
630
|
+
}
|
|
631
|
+
if (!plugin.parse) {
|
|
632
|
+
throw new Error(`Plugin "${type}" does not support parsing`);
|
|
633
|
+
}
|
|
634
|
+
return plugin;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
if (extension) {
|
|
638
|
+
const plugin = plugins.find(plugin => plugin.supportedExtensions?.includes(extension) && (plugin.parse || plugin.safeParse));
|
|
639
|
+
if (!plugin) {
|
|
640
|
+
throw new Error(`No plugin found for extension "${extension}"`);
|
|
641
|
+
}
|
|
642
|
+
return plugin;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
throw new Error('No plugin type or extension specified');
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
async getTree(importPath: string, importOptions: ImportOptions = {}) {
|
|
649
|
+
const { resolvedPath, triedPaths, friendlyPath } = await this._getPath(importPath);
|
|
650
|
+
const { type } = importOptions;
|
|
651
|
+
/**
|
|
652
|
+
* We already have resolved this file and parsed it.
|
|
653
|
+
*/
|
|
654
|
+
if (this.sourceTrees.has(resolvedPath)) {
|
|
655
|
+
return {
|
|
656
|
+
node: this.sourceTrees.get(resolvedPath)!,
|
|
657
|
+
triedPaths,
|
|
658
|
+
resolvedPath
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
const plugins = this.plugins;
|
|
663
|
+
|
|
664
|
+
const sourceGetter = plugins.find(plugin => plugin.getSource);
|
|
665
|
+
if (!sourceGetter) {
|
|
666
|
+
/** If we can't actually load files, bail. */
|
|
667
|
+
throw new Error('No source getter found');
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
const ext = path.extname(resolvedPath);
|
|
671
|
+
const plugin = this.findParserPlugin(type, ext);
|
|
672
|
+
let source: string;
|
|
673
|
+
try {
|
|
674
|
+
source = await sourceGetter.getSource!(resolvedPath);
|
|
675
|
+
} catch (error: unknown) {
|
|
676
|
+
throw error;
|
|
677
|
+
}
|
|
678
|
+
const parseResult = plugin.safeParse!(resolvedPath, source, {
|
|
679
|
+
compilerOptions: this.opts
|
|
680
|
+
});
|
|
681
|
+
|
|
682
|
+
// Collect normalized errors and warnings from plugin
|
|
683
|
+
this.errors.push(...parseResult.errors);
|
|
684
|
+
this.warnings.push(...parseResult.warnings);
|
|
685
|
+
|
|
686
|
+
// Check if we have errors and should break
|
|
687
|
+
if (parseResult.errors.length > 0 && this.opts.breakOnError !== false) {
|
|
688
|
+
// Throw the first error as a JessError
|
|
689
|
+
const firstError = parseResult.errors[0]!;
|
|
690
|
+
throw new JessError({
|
|
691
|
+
code: firstError.code,
|
|
692
|
+
phase: firstError.phase,
|
|
693
|
+
severity: 'error',
|
|
694
|
+
ctx: firstError.file ? { file: firstError.file } : undefined,
|
|
695
|
+
filePath: firstError.filePath,
|
|
696
|
+
source: firstError.file?.source,
|
|
697
|
+
line: firstError.line,
|
|
698
|
+
column: firstError.column,
|
|
699
|
+
reason: firstError.reason,
|
|
700
|
+
fix: firstError.fix,
|
|
701
|
+
note: firstError.note,
|
|
702
|
+
errors: firstError.errors,
|
|
703
|
+
lexerErrors: firstError.lexerErrors
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
if (parseResult.tree) {
|
|
708
|
+
// Set context.root so preEval visitors can check if this is the root
|
|
709
|
+
// parseResult.tree should be a Rules node (the root of the parsed tree)
|
|
710
|
+
if (!this.root && isNode(parseResult.tree, N.Rules)) {
|
|
711
|
+
this.root = parseResult.tree;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
this.sourceTrees.set(resolvedPath, parseResult.tree);
|
|
715
|
+
return {
|
|
716
|
+
node: parseResult.tree,
|
|
717
|
+
triedPaths,
|
|
718
|
+
resolvedPath
|
|
719
|
+
};
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
// No tree and no errors means unsupported file
|
|
723
|
+
const notSupportedError = new Error(`File "${friendlyPath}" not supported`);
|
|
724
|
+
if (this.opts.breakOnError !== false) {
|
|
725
|
+
throw notSupportedError;
|
|
726
|
+
}
|
|
727
|
+
// Add error for unsupported file
|
|
728
|
+
this.errors.push({
|
|
729
|
+
code: 'parse/unsupported-file',
|
|
730
|
+
phase: 'parse',
|
|
731
|
+
message: notSupportedError.message,
|
|
732
|
+
reason: `The file "${friendlyPath}" is not supported by any available plugin.`,
|
|
733
|
+
fix: 'Ensure the file has a supported extension or specify a plugin type.',
|
|
734
|
+
filePath: resolvedPath,
|
|
735
|
+
line: 1,
|
|
736
|
+
column: 1
|
|
737
|
+
});
|
|
738
|
+
return {
|
|
739
|
+
node: null,
|
|
740
|
+
triedPaths,
|
|
741
|
+
resolvedPath
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
/**
|
|
746
|
+
* Public path resolution for import nodes that need source-path lookups
|
|
747
|
+
* without triggering parse/eval.
|
|
748
|
+
*/
|
|
749
|
+
async resolveImportPath(importPath: string) {
|
|
750
|
+
return this._getPath(importPath);
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
/**
|
|
754
|
+
* Parse a string content directly using the appropriate plugin
|
|
755
|
+
*/
|
|
756
|
+
async parseString(content: string, options: {
|
|
757
|
+
filePath?: string;
|
|
758
|
+
type?: string;
|
|
759
|
+
extension?: string;
|
|
760
|
+
} = {}) {
|
|
761
|
+
const { filePath, type, extension } = options;
|
|
762
|
+
const virtualPath = filePath || `virtual.${extension || 'jess'}`;
|
|
763
|
+
const ext = extension || path.extname(virtualPath);
|
|
764
|
+
|
|
765
|
+
const plugin = this.findParserPlugin(type, ext);
|
|
766
|
+
const tree = await plugin.parse!(virtualPath, content, {
|
|
767
|
+
compilerOptions: this.opts
|
|
768
|
+
});
|
|
769
|
+
|
|
770
|
+
if (!tree) {
|
|
771
|
+
throw new Error('Failed to parse content');
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
return {
|
|
775
|
+
node: tree,
|
|
776
|
+
resolvedPath: virtualPath
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
/**
|
|
781
|
+
*
|
|
782
|
+
* @param importPath
|
|
783
|
+
* @param importOptions
|
|
784
|
+
*/
|
|
785
|
+
async getModule(importPath: string, importOptions: ImportOptions = {}) {
|
|
786
|
+
const isFnsImport = importPath === '@jesscss/fns'
|
|
787
|
+
|| importPath.startsWith('@jesscss/fns/')
|
|
788
|
+
|| importPath === '#less'
|
|
789
|
+
|| importPath.startsWith('#less/')
|
|
790
|
+
|| importPath === '#sass'
|
|
791
|
+
|| importPath.startsWith('#sass/');
|
|
792
|
+
const { enableJavaScript } = this.opts;
|
|
793
|
+
if (enableJavaScript === false && !isFnsImport) {
|
|
794
|
+
throw new Error('JavaScript evaluation is disabled');
|
|
795
|
+
}
|
|
796
|
+
const { resolvedPath, triedPaths, friendlyPath } = await this._getPath(importPath);
|
|
797
|
+
const { type } = importOptions;
|
|
798
|
+
|
|
799
|
+
const plugins = this.plugins;
|
|
800
|
+
const ext = path.extname(resolvedPath);
|
|
801
|
+
|
|
802
|
+
let plugin: PluginInterface | undefined;
|
|
803
|
+
|
|
804
|
+
if (type) {
|
|
805
|
+
plugin = plugins.find(plugin => plugin.name === type);
|
|
806
|
+
if (!plugin) {
|
|
807
|
+
throw new Error(`Plugin "${type}" not found`);
|
|
808
|
+
}
|
|
809
|
+
if (!plugin.import) {
|
|
810
|
+
throw new Error(`Plugin "${type}" can't import modules`);
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
if (!plugin) {
|
|
815
|
+
plugin = plugins.find(plugin => plugin.supportedExtensions?.includes(ext) && plugin.import);
|
|
816
|
+
if (!plugin) {
|
|
817
|
+
if (['.js', '.mjs', '.cjs', '.ts', '.mts', '.cts'].includes(ext)) {
|
|
818
|
+
throw new Error('Feature not supported. Install @jesscss/plugin-js to enable script execution features.');
|
|
819
|
+
}
|
|
820
|
+
throw new Error(`File "${friendlyPath}" not supported`);
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
const module = await plugin.import!(resolvedPath);
|
|
825
|
+
if (!module) {
|
|
826
|
+
throw new Error(`File "${friendlyPath}" not supported`);
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
return {
|
|
830
|
+
module,
|
|
831
|
+
triedPaths,
|
|
832
|
+
resolvedPath
|
|
833
|
+
};
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
// async getRules(
|
|
837
|
+
// filePath: string,
|
|
838
|
+
// nodeOptions: StyleImportOptions,
|
|
839
|
+
// userOptions: Record<string, any> = {},
|
|
840
|
+
// withNode?: StyleImportValue['withNode']
|
|
841
|
+
// ) {
|
|
842
|
+
// let rules = await this.getTree(filePath, userOptions);
|
|
843
|
+
// if (withValues && isNode(withValues.node, 'Rules')) {
|
|
844
|
+
// if (rules.options.readonly) {
|
|
845
|
+
// throw new Error('Cannot set an import\'s "with" values more than once.');
|
|
846
|
+
// }
|
|
847
|
+
// /** @todo - Throw errors for undefined vars */
|
|
848
|
+
// let withRules = withValues.node.clone(true) as Rules;
|
|
849
|
+
// withRules.value.unshift(rules);
|
|
850
|
+
// rules = withRules;
|
|
851
|
+
// if (withValues.type === 'set') {
|
|
852
|
+
// this.sourceTrees.set(filePath, rules);
|
|
853
|
+
// }
|
|
854
|
+
// }
|
|
855
|
+
// return rules;
|
|
856
|
+
// }
|
|
857
|
+
|
|
858
|
+
/**
|
|
859
|
+
* Hash a CSS class name or not depending on the `module` setting
|
|
860
|
+
*
|
|
861
|
+
* @todo - do module files have different contexts, therefore different
|
|
862
|
+
* hash maps?
|
|
863
|
+
*/
|
|
864
|
+
hashClass(name: string) {
|
|
865
|
+
/** Remove dot for mapping */
|
|
866
|
+
name = name.slice(1);
|
|
867
|
+
let lookup = this.classMap.get(name);
|
|
868
|
+
if (lookup) {
|
|
869
|
+
return `.${lookup}`;
|
|
870
|
+
}
|
|
871
|
+
let mapVal: string;
|
|
872
|
+
if (this.opts.module) {
|
|
873
|
+
mapVal = `${name}_${this.id}`;
|
|
874
|
+
} else {
|
|
875
|
+
mapVal = name;
|
|
876
|
+
}
|
|
877
|
+
this.classMap.set(name, mapVal);
|
|
878
|
+
return `.${mapVal}`;
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
shouldOperate(op: Operator, left: Node, right: Node) {
|
|
882
|
+
const mathMode = this.treeContext?.mathMode
|
|
883
|
+
?? this.opts?.mathMode
|
|
884
|
+
?? 'parens-division';
|
|
885
|
+
return shouldOperateWithMathFrames(
|
|
886
|
+
{
|
|
887
|
+
mathMode,
|
|
888
|
+
parenFrames: this.parenFrames,
|
|
889
|
+
calcFrames: this.calcFrames
|
|
890
|
+
},
|
|
891
|
+
op,
|
|
892
|
+
left,
|
|
893
|
+
right
|
|
894
|
+
);
|
|
895
|
+
}
|
|
896
|
+
}
|