@jesscss/plugin-less-compat 2.0.0-alpha.6 → 2.0.0-alpha.7

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 (116) hide show
  1. package/README.md +3 -2
  2. package/lib/index.cjs +844 -0
  3. package/lib/index.d.ts +1 -0
  4. package/lib/index.js +800 -10
  5. package/lib/less-adapter.cjs +216 -0
  6. package/lib/less-adapter.js +181 -0
  7. package/lib/less-compat-structures.cjs +378 -0
  8. package/lib/less-compat-structures.d.ts +2 -2
  9. package/lib/less-compat-structures.js +367 -512
  10. package/lib/nodes/at-rule.d.ts +2 -2
  11. package/lib/nodes/attribute-selector.d.ts +2 -2
  12. package/lib/nodes/call.d.ts +2 -2
  13. package/lib/nodes/color.d.ts +2 -1
  14. package/lib/nodes/combinator.d.ts +2 -1
  15. package/lib/nodes/comment.d.ts +2 -1
  16. package/lib/nodes/condition.d.ts +2 -2
  17. package/lib/nodes/declaration.d.ts +2 -2
  18. package/lib/nodes/dimension.d.ts +2 -1
  19. package/lib/nodes/expression.d.ts +2 -2
  20. package/lib/nodes/extend.d.ts +2 -1
  21. package/lib/nodes/import.d.ts +2 -2
  22. package/lib/nodes/keyword.d.ts +2 -1
  23. package/lib/nodes/list.d.ts +3 -2
  24. package/lib/nodes/mixin.d.ts +2 -2
  25. package/lib/nodes/negative.d.ts +2 -2
  26. package/lib/nodes/operation.d.ts +2 -2
  27. package/lib/nodes/paren.d.ts +2 -2
  28. package/lib/nodes/quoted.d.ts +2 -1
  29. package/lib/nodes/reference.d.ts +2 -1
  30. package/lib/nodes/ruleset.d.ts +2 -2
  31. package/lib/nodes/selector.d.ts +2 -2
  32. package/lib/nodes/sequence.d.ts +2 -2
  33. package/lib/nodes/url.d.ts +2 -1
  34. package/lib/nodes/var-declaration.d.ts +2 -2
  35. package/lib/plugin.d.ts +44 -16
  36. package/lib/transform/adapter.d.ts +9 -11
  37. package/lib/transform/index.cjs +13 -0
  38. package/lib/transform/index.d.ts +1 -1
  39. package/lib/transform/index.js +3 -8
  40. package/lib/transform/less-adapter.d.ts +29 -0
  41. package/lib/transform.cjs +1045 -0
  42. package/lib/transform.js +1015 -0
  43. package/lib/types.d.ts +153 -28
  44. package/package.json +6 -9
  45. package/lib/index.js.map +0 -1
  46. package/lib/less-compat-structures.js.map +0 -1
  47. package/lib/nodes/at-rule.js +0 -21
  48. package/lib/nodes/at-rule.js.map +0 -1
  49. package/lib/nodes/attribute-selector.js +0 -18
  50. package/lib/nodes/attribute-selector.js.map +0 -1
  51. package/lib/nodes/call.js +0 -27
  52. package/lib/nodes/call.js.map +0 -1
  53. package/lib/nodes/color.js +0 -23
  54. package/lib/nodes/color.js.map +0 -1
  55. package/lib/nodes/combinator.js +0 -7
  56. package/lib/nodes/combinator.js.map +0 -1
  57. package/lib/nodes/comment.js +0 -9
  58. package/lib/nodes/comment.js.map +0 -1
  59. package/lib/nodes/condition.js +0 -19
  60. package/lib/nodes/condition.js.map +0 -1
  61. package/lib/nodes/declaration.js +0 -38
  62. package/lib/nodes/declaration.js.map +0 -1
  63. package/lib/nodes/dimension.js +0 -9
  64. package/lib/nodes/dimension.js.map +0 -1
  65. package/lib/nodes/expression.js +0 -16
  66. package/lib/nodes/expression.js.map +0 -1
  67. package/lib/nodes/extend.js +0 -18
  68. package/lib/nodes/extend.js.map +0 -1
  69. package/lib/nodes/import.js +0 -22
  70. package/lib/nodes/import.js.map +0 -1
  71. package/lib/nodes/index.js +0 -308
  72. package/lib/nodes/index.js.map +0 -1
  73. package/lib/nodes/keyword.js +0 -8
  74. package/lib/nodes/keyword.js.map +0 -1
  75. package/lib/nodes/list.js +0 -61
  76. package/lib/nodes/list.js.map +0 -1
  77. package/lib/nodes/mixin.js +0 -22
  78. package/lib/nodes/mixin.js.map +0 -1
  79. package/lib/nodes/negative.js +0 -13
  80. package/lib/nodes/negative.js.map +0 -1
  81. package/lib/nodes/operation.js +0 -22
  82. package/lib/nodes/operation.js.map +0 -1
  83. package/lib/nodes/paren.js +0 -13
  84. package/lib/nodes/paren.js.map +0 -1
  85. package/lib/nodes/quoted.js +0 -23
  86. package/lib/nodes/quoted.js.map +0 -1
  87. package/lib/nodes/reference.js +0 -44
  88. package/lib/nodes/reference.js.map +0 -1
  89. package/lib/nodes/ruleset.js +0 -67
  90. package/lib/nodes/ruleset.js.map +0 -1
  91. package/lib/nodes/selector.js +0 -158
  92. package/lib/nodes/selector.js.map +0 -1
  93. package/lib/nodes/sequence.js +0 -56
  94. package/lib/nodes/sequence.js.map +0 -1
  95. package/lib/nodes/url.js +0 -13
  96. package/lib/nodes/url.js.map +0 -1
  97. package/lib/nodes/var-declaration.js +0 -21
  98. package/lib/nodes/var-declaration.js.map +0 -1
  99. package/lib/plugin-utils.js +0 -100
  100. package/lib/plugin-utils.js.map +0 -1
  101. package/lib/plugin.js +0 -1026
  102. package/lib/plugin.js.map +0 -1
  103. package/lib/transform/adapter.js +0 -111
  104. package/lib/transform/adapter.js.map +0 -1
  105. package/lib/transform/from-less.js +0 -170
  106. package/lib/transform/from-less.js.map +0 -1
  107. package/lib/transform/index.js.map +0 -1
  108. package/lib/transform/proxy.d.ts +0 -32
  109. package/lib/transform/proxy.js +0 -138
  110. package/lib/transform/proxy.js.map +0 -1
  111. package/lib/transform/to-less.js +0 -130
  112. package/lib/transform/to-less.js.map +0 -1
  113. package/lib/transform/type-map.js +0 -105
  114. package/lib/transform/type-map.js.map +0 -1
  115. package/lib/types.js +0 -5
  116. package/lib/types.js.map +0 -1
package/lib/index.cjs ADDED
@@ -0,0 +1,844 @@
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
4
+ });
5
+ //#region \0rolldown/runtime.js
6
+ var __create = Object.create;
7
+ var __defProp = Object.defineProperty;
8
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
9
+ var __getOwnPropNames = Object.getOwnPropertyNames;
10
+ var __getProtoOf = Object.getPrototypeOf;
11
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
14
+ key = keys[i];
15
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
16
+ get: ((k) => from[k]).bind(null, key),
17
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
18
+ });
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
+ value: mod,
24
+ enumerable: true
25
+ }) : target, mod));
26
+ //#endregion
27
+ const require_less_adapter = require("./less-adapter.cjs");
28
+ const require_transform = require("./transform.cjs");
29
+ const require_less_compat_structures = require("./less-compat-structures.cjs");
30
+ let node_fs = require("node:fs");
31
+ node_fs = __toESM(node_fs);
32
+ let node_module = require("node:module");
33
+ let node_path = require("node:path");
34
+ node_path = __toESM(node_path);
35
+ let _jesscss_core = require("@jesscss/core");
36
+ //#region src/plugin-utils.ts
37
+ /**
38
+ * Detect if a plugin is a Less.js plugin
39
+ */
40
+ function isLessPlugin(plugin) {
41
+ if (!plugin) return false;
42
+ if (typeof plugin.install === "function") return true;
43
+ if (typeof plugin === "function") {
44
+ if (typeof plugin.install === "function") return true;
45
+ if (plugin.prototype && typeof plugin.prototype.install === "function") return true;
46
+ try {
47
+ const instance = new plugin({});
48
+ if (instance && typeof instance.install === "function") return true;
49
+ } catch (e) {
50
+ try {
51
+ const instance = plugin({});
52
+ if (instance && typeof instance.install === "function") return true;
53
+ return true;
54
+ } catch (e2) {}
55
+ }
56
+ }
57
+ return false;
58
+ }
59
+ /**
60
+ * Detect if a plugin is a Jess plugin
61
+ */
62
+ function isJessPlugin(plugin) {
63
+ if (!plugin) return false;
64
+ if (typeof plugin === "object" && "name" in plugin && typeof plugin.name === "string") return true;
65
+ if (typeof plugin === "function") try {
66
+ const instance = plugin({});
67
+ if (instance && typeof instance === "object" && "name" in instance && typeof instance.name === "string") return true;
68
+ } catch (e) {}
69
+ return false;
70
+ }
71
+ /**
72
+ * Filter and separate Less plugins from Jess plugins
73
+ * This allows mixed plugin arrays to be handled correctly
74
+ */
75
+ function filterPlugins(plugins) {
76
+ const lessPlugins = [];
77
+ const jessPlugins = [];
78
+ for (const plugin of plugins) if (isLessPlugin(plugin)) lessPlugins.push(plugin);
79
+ else if (isJessPlugin(plugin)) jessPlugins.push(plugin);
80
+ else lessPlugins.push(plugin);
81
+ return {
82
+ lessPlugins,
83
+ jessPlugins
84
+ };
85
+ }
86
+ //#endregion
87
+ //#region src/plugin.ts
88
+ const isThenable = (v) => !!v && (typeof v === "object" || typeof v === "function") && typeof v.then === "function";
89
+ /**
90
+ * Structural guard for Less/Jess nodes that expose an `eval(context)` method.
91
+ * Used by the @plugin function wrappers to evaluate node arguments before
92
+ * handing them to legacy Less plugin functions.
93
+ */
94
+ const hasEvalMethod = (x) => !!x && (typeof x === "object" || typeof x === "function") && typeof x.eval === "function";
95
+ /** Structural guard for nodes that expose a `removeFlag` mutator. */
96
+ const hasRemoveFlag = (x) => !!x && typeof x.removeFlag === "function";
97
+ const LESS_PLUGIN_JS_RUNTIME_MESSAGE = "Feature not supported. Install @jesscss/plugin-js to enable Less @plugin script execution.";
98
+ const SCRIPT_MODULES_DISABLED_MESSAGE = "Less @plugin is disabled by disableScriptModules.";
99
+ /**
100
+ * Wrap a Less plugin function and add it to a Jess function registry.
101
+ * Used so that deprecated @plugin-loaded functions register into the Rules that
102
+ * contain the @plugin.
103
+ * Conversion of Less return values to Jess uses the shared fromLessPluginReturnValue.
104
+ *
105
+ * @deprecated Legacy Less @plugin support. Prefer @use / @-use for script integration in .less files.
106
+ */
107
+ function addToJessRegistry(jessRegistry, name, func) {
108
+ if (!jessRegistry || typeof jessRegistry.add !== "function") return;
109
+ try {
110
+ name = name.toLowerCase();
111
+ const wrapped = function(...args) {
112
+ const maybeEvaldArgs = args.map((arg) => {
113
+ if (arg instanceof _jesscss_core.Any || arg instanceof _jesscss_core.Declaration || arg instanceof _jesscss_core.Dimension) {}
114
+ if (hasEvalMethod(arg) && arg.evaluated !== true) try {
115
+ return arg.eval(this);
116
+ } catch {
117
+ return arg;
118
+ }
119
+ return arg;
120
+ });
121
+ const call = (finalArgs) => func.apply(this, finalArgs);
122
+ const result = maybeEvaldArgs.some(isThenable) ? Promise.all(maybeEvaldArgs.map((a) => isThenable(a) ? a : Promise.resolve(a))).then(call) : call(maybeEvaldArgs);
123
+ const statementContext = this?.caller?.parent?.type === "Rules";
124
+ const convertResult = (r) => require_transform.fromLessPluginReturnValue(r, { statementContext });
125
+ return isThenable(result) ? result.then(convertResult) : convertResult(result);
126
+ };
127
+ Object.assign(wrapped, func);
128
+ jessRegistry.add(name, wrapped);
129
+ } catch (e) {}
130
+ }
131
+ /**
132
+ * Wrap a Less 4.x-style custom function (as registered through
133
+ * `less.functions.functionRegistry.add`) and add it to a Jess function registry.
134
+ *
135
+ * Unlike {@link addToJessRegistry}, the evaluated arguments are converted to
136
+ * Less-shaped nodes via `toLessNode` before the function runs. Less 4.x custom
137
+ * functions receive `less.tree.*` values (with `.value`, `.unit`, `.rgb`, …),
138
+ * not raw Jess nodes, so this conversion is required for parity.
139
+ */
140
+ function addRootFunctionToJessRegistry(jessRegistry, name, func) {
141
+ if (!jessRegistry || typeof jessRegistry.add !== "function") return;
142
+ name = name.toLowerCase();
143
+ const wrapped = function(...args) {
144
+ const evaldArgs = args.map((arg) => {
145
+ if (hasEvalMethod(arg) && arg.evaluated !== true) try {
146
+ return arg.eval(this);
147
+ } catch {
148
+ return arg;
149
+ }
150
+ return arg;
151
+ });
152
+ const call = (finalArgs) => {
153
+ const lessArgs = finalArgs.map((a) => a instanceof _jesscss_core.Node ? require_transform.toLessNode(a) : a);
154
+ return func.apply(this, lessArgs);
155
+ };
156
+ const statementContext = this?.caller?.parent?.type === "Rules";
157
+ const convertResult = (r) => require_transform.fromLessPluginReturnValue(r, { statementContext });
158
+ const result = evaldArgs.some(isThenable) ? Promise.all(evaldArgs.map((a) => isThenable(a) ? a : Promise.resolve(a))).then(call) : call(evaldArgs);
159
+ return isThenable(result) ? result.then(convertResult) : convertResult(result);
160
+ };
161
+ Object.assign(wrapped, func);
162
+ jessRegistry.add(name, wrapped);
163
+ }
164
+ /**
165
+ * Plugin that enables Less.js compatibility by transforming
166
+ * Jess nodes to Less-compatible format for visitor processing.
167
+ */
168
+ var LessCompatPlugin = class extends _jesscss_core.AbstractPlugin {
169
+ name = "less-compat";
170
+ _cachedVisitor;
171
+ _lessPluginManager;
172
+ _currentFilePath;
173
+ _jessFunctionRegistry;
174
+ _context;
175
+ /** Trees whose root scope already received the configured root functions. */
176
+ _fnRegisteredTrees = /* @__PURE__ */ new WeakSet();
177
+ constructor(opts = {}) {
178
+ super();
179
+ this.opts = opts;
180
+ }
181
+ /**
182
+ * Return the visitor through the early visitor hook so it runs before
183
+ * evaluation. This keeps Less plugin visitors and preprocessors early without
184
+ * bringing back a public node preparation pass.
185
+ *
186
+ * Less plugins can register visitors via:
187
+ * - addVisitor() - these run early by default
188
+ * - addPreProcessor() - these run early
189
+ * - addPostProcessor() - these run on serialized CSS after render
190
+ */
191
+ get beforeEvalVisitor() {
192
+ if (!this._cachedVisitor) this._cachedVisitor = this.visitor;
193
+ return this._cachedVisitor;
194
+ }
195
+ /**
196
+ * Less post-processors operate on final CSS, not on the preRenderVisitor tree hook.
197
+ */
198
+ get postEvalVisitor() {}
199
+ runPostProcessors(css, extra = {}) {
200
+ return (this._lessPluginManager?.getPostProcessors() || []).reduce((current, processor) => {
201
+ if (!processor || typeof processor.process !== "function") return current;
202
+ try {
203
+ const output = processor.process(current, extra);
204
+ return typeof output === "string" ? output : current;
205
+ } catch (error) {
206
+ throw error;
207
+ }
208
+ }, css);
209
+ }
210
+ setCurrentFilePath(filePath) {
211
+ this._currentFilePath = filePath;
212
+ }
213
+ setContext(context) {
214
+ this._context = context;
215
+ try {
216
+ const root = context?.root;
217
+ if (root && typeof root.setFunctionBinding === "function" && typeof root.findFunction === "function") this._jessFunctionRegistry = this.createJessFunctionBindingRegistry(root);
218
+ } catch {}
219
+ }
220
+ createJessFunctionBindingRegistry(root) {
221
+ return {
222
+ add(name, func) {
223
+ const lowerName = name.toLowerCase();
224
+ const jsFunc = func instanceof _jesscss_core.JsFunction ? func : new _jesscss_core.JsFunction({
225
+ name: lowerName,
226
+ fn: func
227
+ });
228
+ if (!jsFunc.name) jsFunc.name = lowerName;
229
+ root.setFunctionBinding(lowerName, jsFunc);
230
+ },
231
+ get(name) {
232
+ const fn = root.findFunction(name.toLowerCase());
233
+ return fn instanceof _jesscss_core.JsFunction ? fn : void 0;
234
+ }
235
+ };
236
+ }
237
+ hasConfiguredBeforeEvalWork() {
238
+ return !!this.opts.plugins?.length || !!this.opts.visitors?.length;
239
+ }
240
+ sourceMayContainPluginDirective(tree) {
241
+ if (!tree) return false;
242
+ const source = tree._treeContext?.file?.source;
243
+ if (typeof source === "string" && source.includes("@plugin")) return true;
244
+ return this.treeContainsPluginDirective(tree);
245
+ }
246
+ treeContainsPluginDirective(node, depth = 0) {
247
+ if (!node || typeof node !== "object" || depth > 32) return false;
248
+ const candidate = node;
249
+ const type = candidate.type;
250
+ if (type === "AtRule" || type === "AtRuleStatement" || type === "Directive") {
251
+ const name = candidate.name;
252
+ let nameValue;
253
+ if (typeof name === "string") nameValue = name;
254
+ else if (name && typeof name === "object") {
255
+ const inner = name.value;
256
+ if (typeof inner === "string") nameValue = inner;
257
+ }
258
+ if (nameValue === "@plugin" || nameValue === "plugin") return true;
259
+ }
260
+ const rules = candidate.rules;
261
+ if (Array.isArray(rules)) {
262
+ for (const child of rules) if (this.treeContainsPluginDirective(child, depth + 1)) return true;
263
+ }
264
+ return false;
265
+ }
266
+ warnForPluginDirective(node) {
267
+ const context = this._context;
268
+ if (!context || !Array.isArray(context.warnings)) return;
269
+ const deprecation = _jesscss_core.Deprecation.fromId("less-plugin") ?? _jesscss_core.Deprecation.userAuthored;
270
+ context.warnings.push((0, _jesscss_core.toDiagnostic)(_jesscss_core.WARN.deprecated({
271
+ node,
272
+ filePath: this._currentFilePath,
273
+ meta: {
274
+ what: "@plugin",
275
+ use: "@use / @-use",
276
+ deprecation
277
+ },
278
+ note: "In .less files compiled through the Less CLI compatibility path, migrate script integration to @use / @-use."
279
+ })));
280
+ }
281
+ markPluginDirectiveInvisible(node) {
282
+ const jessNode = node instanceof require_less_adapter.LessAdapterBase ? node.jessNode : node;
283
+ if (hasRemoveFlag(jessNode)) jessNode.removeFlag(_jesscss_core.F_VISIBLE);
284
+ }
285
+ registerDenoLessPluginFunctions(jessRegistry, functions) {
286
+ if (!jessRegistry || typeof jessRegistry.add !== "function") return;
287
+ for (const [name, fn] of Object.entries(functions)) jessRegistry.add(name.toLowerCase(), async function(...args) {
288
+ const context = this;
289
+ return fn(...await Promise.all(args.map(async (arg) => {
290
+ if (hasEvalMethod(arg) && arg.evaluated !== true) {
291
+ const out = arg.eval(context);
292
+ return isThenable(out) ? await out : out;
293
+ }
294
+ return arg;
295
+ })));
296
+ });
297
+ }
298
+ loadLessPluginFileWithDeno(fullPath, targetJessRegistry) {
299
+ const finish = async (plugin) => {
300
+ if (!plugin || typeof plugin.importLessPlugin !== "function") return false;
301
+ if (this._context?.plugins && !this._context.plugins.includes(plugin)) this._context.plugins.push(plugin);
302
+ const loaded = await plugin.importLessPlugin(fullPath);
303
+ this.registerDenoLessPluginFunctions(targetJessRegistry ?? this._jessFunctionRegistry, loaded.functions ?? {});
304
+ return true;
305
+ };
306
+ const ext = node_path.default.extname(fullPath);
307
+ const existingPlugin = [...this._context?.plugins ?? [], ...this.opts.plugins ?? []].find((plugin) => plugin?.supportedExtensions?.includes(ext) && typeof plugin.importLessPlugin === "function");
308
+ if (existingPlugin) return finish(existingPlugin);
309
+ const loader = this._context?.opts?.loadPluginForExtension;
310
+ if (!loader) return false;
311
+ const load = loader(ext);
312
+ return isThenable(load) ? Promise.resolve(load).then(finish) : finish(load);
313
+ }
314
+ beforeEvalVisitorForTree(tree) {
315
+ this.registerRootFunctions(tree);
316
+ if (!this.hasConfiguredBeforeEvalWork() && !this.sourceMayContainPluginDirective(tree)) return;
317
+ return this.beforeEvalVisitor;
318
+ }
319
+ /**
320
+ * Register the configured Less 4.x root functions onto a parsed tree's root
321
+ * scope, using the same `setFunctionBinding` mechanism the Less plugin uses
322
+ * for built-ins. Idempotent per tree.
323
+ */
324
+ registerRootFunctions(tree) {
325
+ const fns = this.opts.functions;
326
+ if (!fns) return;
327
+ if (!tree || typeof tree.setFunctionBinding !== "function" || typeof tree.findFunction !== "function") return;
328
+ if (this._fnRegisteredTrees.has(tree)) return;
329
+ this._fnRegisteredTrees.add(tree);
330
+ const registry = this.createJessFunctionBindingRegistry(tree);
331
+ for (const [name, fn] of Object.entries(fns)) if (typeof fn === "function") addRootFunctionToJessRegistry(registry, name, fn);
332
+ }
333
+ /**
334
+ * Filter and separate Less plugins from Jess plugins
335
+ * This allows mixed plugin arrays to be handled correctly
336
+ *
337
+ * @deprecated Use filterPlugins from './plugin-utils.js' instead
338
+ */
339
+ static filterLessPlugins(plugins) {
340
+ return filterPlugins(plugins);
341
+ }
342
+ /**
343
+ * Return a visitor that wraps Less visitors
344
+ *
345
+ * This visitor intercepts each node, converts it to Less format,
346
+ * runs the Less visitors, and converts back if modified.
347
+ */
348
+ get visitor() {
349
+ const cacheMap = this.opts.cache !== false ? /* @__PURE__ */ new WeakMap() : void 0;
350
+ const LessVisitor$1 = require_less_compat_structures.LessVisitor;
351
+ const LessPluginManagerClass = require_less_compat_structures.LessPluginManager;
352
+ const lessVisitorInstances = [];
353
+ let pluginManagerRef = null;
354
+ let mockLessRef = null;
355
+ const createUnknownTreeConstructor = (type) => {
356
+ return function(...args) {
357
+ return {
358
+ value: null,
359
+ type,
360
+ name: args[0] || "",
361
+ args: args.slice(1) || [],
362
+ index: 0,
363
+ fileInfo: {},
364
+ accept: function(visitor) {
365
+ return visitor.visit(this);
366
+ }
367
+ };
368
+ };
369
+ };
370
+ const attachFunctionRegistrySurface = (registry) => {
371
+ for (const [name, ctor] of Object.entries(require_less_compat_structures.LessTreeConstructors)) Object.defineProperty(registry, name, {
372
+ value: ctor,
373
+ enumerable: false,
374
+ configurable: true,
375
+ writable: true
376
+ });
377
+ for (const name of [
378
+ "Alpha",
379
+ "Assignment",
380
+ "Condition",
381
+ "Expression",
382
+ "Value"
383
+ ]) if (!(name in registry)) Object.defineProperty(registry, name, {
384
+ value: createUnknownTreeConstructor(name),
385
+ enumerable: false,
386
+ configurable: true,
387
+ writable: true
388
+ });
389
+ return registry;
390
+ };
391
+ function* createVisitorIterator() {
392
+ let index = 0;
393
+ while (index < lessVisitorInstances.length) {
394
+ yield lessVisitorInstances[index];
395
+ index++;
396
+ }
397
+ }
398
+ let currentRealRegistry = this._jessFunctionRegistry;
399
+ const createFunctionRegistry = () => {
400
+ const data = {};
401
+ let base = null;
402
+ return attachFunctionRegistrySurface({
403
+ get _data() {
404
+ return data;
405
+ },
406
+ get _base() {
407
+ return base;
408
+ },
409
+ set _base(v) {
410
+ base = v;
411
+ },
412
+ add(name, func) {
413
+ name = name.toLowerCase();
414
+ data[name] = func;
415
+ if (currentRealRegistry) addToJessRegistry(currentRealRegistry, name, func);
416
+ },
417
+ addMultiple(functions) {
418
+ Object.keys(functions).forEach((name) => {
419
+ this.add(name, functions[name]);
420
+ });
421
+ },
422
+ get(name) {
423
+ name = name.toLowerCase();
424
+ if (data[name]) return data[name];
425
+ if (base) return base.get(name);
426
+ if (currentRealRegistry) try {
427
+ return currentRealRegistry.get(name);
428
+ } catch (_e) {}
429
+ },
430
+ getLocalFunctions() {
431
+ return { ...data };
432
+ },
433
+ inherit() {
434
+ const child = createFunctionRegistry();
435
+ child._base = this;
436
+ return child;
437
+ },
438
+ create(base) {
439
+ const newRegistry = createFunctionRegistry();
440
+ newRegistry._base = base;
441
+ return newRegistry;
442
+ }
443
+ });
444
+ };
445
+ /**
446
+ * Create a mock function registry that forwards add/addMultiple/get to the given
447
+ * Jess registry. Used when loading @plugin scripts so functions register into the
448
+ * Rules that contain the @plugin directive.
449
+ */
450
+ const createScopedFunctionRegistry = (jessRegistry) => {
451
+ const data = {};
452
+ return attachFunctionRegistrySurface({
453
+ add(name, func) {
454
+ name = name.toLowerCase();
455
+ data[name] = func;
456
+ addToJessRegistry(jessRegistry, name, func);
457
+ },
458
+ addMultiple(functions) {
459
+ Object.keys(functions).forEach((name) => {
460
+ this.add(name, functions[name]);
461
+ });
462
+ },
463
+ get(name) {
464
+ name = name.toLowerCase();
465
+ if (data[name]) return data[name];
466
+ try {
467
+ return jessRegistry?.get?.(name);
468
+ } catch {
469
+ return;
470
+ }
471
+ }
472
+ });
473
+ };
474
+ const functionRegistry = createFunctionRegistry();
475
+ const mockLess = require_less_compat_structures.createLessMock(functionRegistry);
476
+ const pluginManager = new LessPluginManagerClass(mockLess, true);
477
+ this._lessPluginManager = pluginManager;
478
+ const loadPluginSource = (fullPath, registerPlugin, targetJessRegistry) => {
479
+ const contents = node_fs.readFileSync(fullPath, "utf8");
480
+ const localModule = { exports: {} };
481
+ const functions = targetJessRegistry != null ? createScopedFunctionRegistry(targetJessRegistry) : functionRegistry;
482
+ new Function("module", "require", "registerPlugin", "functions", "tree", "less", "fileInfo", contents)(localModule, (0, node_module.createRequire)(fullPath), registerPlugin, functions, require_less_compat_structures.LessTreeConstructors, mockLess, { filename: fullPath });
483
+ return {
484
+ module: localModule.exports,
485
+ registered: null
486
+ };
487
+ };
488
+ const requirePluginFile = (fullPath, targetJessRegistry) => {
489
+ const registeredPlugins = [];
490
+ const registerPlugin = (plugin) => {
491
+ registeredPlugins.push(plugin);
492
+ };
493
+ const loaded = loadPluginSource(fullPath, registerPlugin, targetJessRegistry);
494
+ return {
495
+ module: loaded.module,
496
+ registered: registeredPlugins.length > 0 ? registeredPlugins[registeredPlugins.length - 1] : loaded.registered
497
+ };
498
+ };
499
+ pluginManagerRef = pluginManager;
500
+ mockLessRef = mockLess;
501
+ if (this.opts.plugins?.length) {
502
+ const { lessPlugins } = filterPlugins(this.opts.plugins);
503
+ if (lessPlugins.length > 0) {
504
+ const visitorsBefore = pluginManager.visitors ? [...pluginManager.visitors] : [];
505
+ const processedPlugins = [];
506
+ lessPlugins.forEach((plugin) => {
507
+ if (!plugin) return;
508
+ if (typeof plugin === "function") try {
509
+ const pluginInstance = new plugin({});
510
+ if (pluginInstance) processedPlugins.push(pluginInstance);
511
+ else try {
512
+ const pluginInstance2 = plugin({});
513
+ if (pluginInstance2) processedPlugins.push(pluginInstance2);
514
+ else processedPlugins.push(plugin);
515
+ } catch (_e2) {
516
+ processedPlugins.push(plugin);
517
+ }
518
+ } catch (_e) {
519
+ try {
520
+ const pluginInstance = plugin({});
521
+ if (pluginInstance) processedPlugins.push(pluginInstance);
522
+ else processedPlugins.push(plugin);
523
+ } catch (_e2) {
524
+ processedPlugins.push(plugin);
525
+ }
526
+ }
527
+ else processedPlugins.push(plugin);
528
+ });
529
+ processedPlugins.forEach((plugin) => {
530
+ if (!plugin) return;
531
+ try {
532
+ const wrappedVisitor = new LessVisitor$1(plugin);
533
+ lessVisitorInstances.push(wrappedVisitor);
534
+ } catch (e) {}
535
+ if (typeof plugin.install === "function") plugin.install(mockLess, pluginManager, mockLess.functions.functionRegistry);
536
+ else if (typeof plugin === "function") if (plugin.prototype && typeof plugin.prototype.install === "function") try {
537
+ const pluginInstance = new plugin({});
538
+ if (pluginInstance && typeof pluginInstance.install === "function") pluginInstance.install(mockLess, pluginManager, mockLess.functions.functionRegistry);
539
+ } catch (_e) {
540
+ try {
541
+ const pluginInstance = plugin({});
542
+ if (pluginInstance && typeof pluginInstance.install === "function") pluginInstance.install(mockLess, pluginManager, mockLess.functions.functionRegistry);
543
+ else if (pluginInstance) lessVisitorInstances.push(new LessVisitor$1(pluginInstance));
544
+ } catch (_e2) {
545
+ lessVisitorInstances.push(new LessVisitor$1(plugin));
546
+ }
547
+ }
548
+ else try {
549
+ const pluginInstance = plugin({});
550
+ if (pluginInstance && typeof pluginInstance.install === "function") pluginInstance.install(mockLess, pluginManager, mockLess.functions.functionRegistry);
551
+ else if (pluginInstance) lessVisitorInstances.push(new LessVisitor$1(pluginInstance));
552
+ } catch (_e2) {
553
+ lessVisitorInstances.push(new LessVisitor$1(plugin));
554
+ }
555
+ else lessVisitorInstances.push(new LessVisitor$1(plugin));
556
+ });
557
+ if (pluginManager.visitors && pluginManager.visitors.length > visitorsBefore.length) {
558
+ const newVisitors = pluginManager.visitors.slice(visitorsBefore.length);
559
+ lessVisitorInstances.push(...newVisitors.map((v) => {
560
+ if (v instanceof LessVisitor$1) return v;
561
+ return new LessVisitor$1(v);
562
+ }));
563
+ }
564
+ }
565
+ }
566
+ /** @deprecated Less.js Visitor API - Direct visitor support for Less.js compatibility */
567
+ if (this.opts.visitors?.length) this.opts.visitors.forEach((visitorImpl) => {
568
+ if (visitorImpl instanceof LessVisitor$1) lessVisitorInstances.push(visitorImpl);
569
+ else lessVisitorInstances.push(new LessVisitor$1(visitorImpl));
570
+ });
571
+ const processing = /* @__PURE__ */ new WeakSet();
572
+ let insideLessTraversal = false;
573
+ const processedPluginDirectives = /* @__PURE__ */ new WeakSet();
574
+ const visitor = {
575
+ atRule: (node, _ctx) => {
576
+ if (node && (node.type === "AtRule" || node.type === "AtRuleStatement" || node.type === "Directive")) {
577
+ const atRuleName = node.name ?? node.value?.name;
578
+ let nameValue;
579
+ if (typeof atRuleName === "string") nameValue = atRuleName;
580
+ else if (atRuleName?.value) nameValue = atRuleName.value;
581
+ else if (typeof atRuleName?.valueOf === "function") {
582
+ const value = atRuleName.valueOf();
583
+ if (typeof value === "string") nameValue = value;
584
+ }
585
+ if (nameValue === "plugin" || nameValue === "@plugin") {
586
+ const rawDirective = node instanceof require_less_adapter.LessAdapterBase ? node.jessNode : node;
587
+ const pluginDirectiveNode = typeof rawDirective === "object" && rawDirective !== null ? rawDirective : {};
588
+ if (processedPluginDirectives.has(pluginDirectiveNode)) return node;
589
+ processedPluginDirectives.add(pluginDirectiveNode);
590
+ this.warnForPluginDirective(rawDirective);
591
+ if (this._context?.opts?.disableScriptModules || this._context?.opts?.disablePluginRule) throw new Error(SCRIPT_MODULES_DISABLED_MESSAGE);
592
+ const baseDir = this._currentFilePath ? node_path.default.dirname(this._currentFilePath) : void 0;
593
+ const prelude = node.prelude ?? node.value?.prelude ?? node.value;
594
+ let pluginPath;
595
+ let pluginOptions;
596
+ if (prelude) {
597
+ const isObjectLike = (value) => typeof value === "object" && value !== null;
598
+ const hasValueOf = (value) => isObjectLike(value) && typeof value.valueOf === "function";
599
+ const valueOfString = (value, trim = false) => {
600
+ if (!hasValueOf(value)) return;
601
+ const output = value.valueOf();
602
+ return typeof output === "string" ? trim ? output.trim() : output : void 0;
603
+ };
604
+ const stringFromNodeValue = (value) => {
605
+ if (typeof value === "string") return value;
606
+ const valueResult = valueOfString(value);
607
+ if (valueResult !== void 0) return valueResult;
608
+ if (isObjectLike(value) && typeof value.value === "string") return value.value;
609
+ };
610
+ const extractStringValue = (node) => {
611
+ if (!node) return;
612
+ if (typeof node === "string") return node;
613
+ if (!isObjectLike(node)) return;
614
+ if (node.type === "Quoted" && node.value) {
615
+ const value = stringFromNodeValue(node.value);
616
+ if (value !== void 0) return value;
617
+ return valueOfString(node);
618
+ }
619
+ if (node.type === "Url" && node.value) {
620
+ const value = stringFromNodeValue(node.value);
621
+ if (value !== void 0) return value;
622
+ if (isObjectLike(node.value) && node.value.type === "Quoted") return extractStringValue(node.value);
623
+ return valueOfString(node);
624
+ }
625
+ return valueOfString(node, true);
626
+ };
627
+ if (typeof prelude === "string") pluginPath = prelude;
628
+ else if (prelude.type === "Quoted" || prelude.type === "Url") pluginPath = extractStringValue(prelude);
629
+ else if (prelude.type === "Sequence" && Array.isArray(prelude.value)) for (let i = 0; i < prelude.value.length; i++) {
630
+ const item = prelude.value[i];
631
+ const extracted = extractStringValue(item);
632
+ if (item && extracted !== void 0) {
633
+ pluginPath = extracted;
634
+ if (i > 0) {
635
+ const prevItem = prelude.value[i - 1];
636
+ if (prevItem && prevItem.type === "Paren" && prevItem.value) {
637
+ const optionsValue = prevItem.value.valueOf ? prevItem.value.valueOf() : prevItem.value.toString();
638
+ if (typeof optionsValue === "string") pluginOptions = optionsValue.trim();
639
+ } else if (prevItem && typeof prevItem.valueOf === "function") {
640
+ const optionsValue = prevItem.valueOf();
641
+ if (typeof optionsValue === "string" && optionsValue.includes("=")) pluginOptions = optionsValue.trim();
642
+ }
643
+ }
644
+ if (pluginPath) break;
645
+ }
646
+ }
647
+ else if (prelude.type === "Expression" && prelude.value) {
648
+ const values = Array.isArray(prelude.value) ? prelude.value : [prelude.value];
649
+ for (let i = 0; i < values.length; i++) {
650
+ const item = values[i];
651
+ const extracted = extractStringValue(item);
652
+ if (item && extracted !== void 0) {
653
+ pluginPath = extracted;
654
+ if (i > 0) {
655
+ const prevItem = values[i - 1];
656
+ if (prevItem && prevItem.type === "Paren" && prevItem.value) {
657
+ const optionsValue = prevItem.value.valueOf ? prevItem.value.valueOf() : prevItem.value.toString();
658
+ if (typeof optionsValue === "string") pluginOptions = optionsValue.trim();
659
+ }
660
+ }
661
+ if (pluginPath) break;
662
+ }
663
+ }
664
+ } else if (prelude.type === "List" && prelude.value) {
665
+ const items = Array.isArray(prelude.value) ? prelude.value : [prelude.value];
666
+ for (let i = 0; i < items.length; i++) {
667
+ const item = items[i];
668
+ const extracted = extractStringValue(item);
669
+ if (item && extracted !== void 0) {
670
+ pluginPath = extracted;
671
+ if (i > 0) {
672
+ const prevItem = items[i - 1];
673
+ if (prevItem && prevItem.type === "Paren" && prevItem.value) {
674
+ const optionsValue = prevItem.value.valueOf ? prevItem.value.valueOf() : prevItem.value.toString();
675
+ if (typeof optionsValue === "string") pluginOptions = optionsValue.trim();
676
+ }
677
+ }
678
+ if (pluginPath) break;
679
+ }
680
+ }
681
+ } else if (prelude.value && typeof prelude.value === "string") pluginPath = prelude.value;
682
+ if (!pluginPath && typeof prelude.valueOf === "function") {
683
+ const fallbackValue = prelude.valueOf();
684
+ if (typeof fallbackValue === "string") pluginPath = fallbackValue;
685
+ }
686
+ }
687
+ if (pluginPath) {
688
+ if (typeof pluginPath === "string") pluginPath = pluginPath.trim().replace(/^["']|["']$/g, "").trim();
689
+ else pluginPath = String(pluginPath).trim().replace(/^["']|["']$/g, "").trim();
690
+ const isExplicitLocalPath = pluginPath.startsWith(".") || pluginPath.startsWith("/") || pluginPath.includes("/") || pluginPath.includes(node_path.default.sep);
691
+ const localBasePath = baseDir && !node_path.default.isAbsolute(pluginPath) ? node_path.default.resolve(baseDir, pluginPath) : node_path.default.isAbsolute(pluginPath) ? pluginPath : void 0;
692
+ let resolvedLocalPluginFile;
693
+ if (localBasePath) resolvedLocalPluginFile = [
694
+ localBasePath,
695
+ `${localBasePath}.js`,
696
+ `${localBasePath}.cjs`,
697
+ `${localBasePath}.mjs`
698
+ ].find((p) => node_fs.existsSync(p));
699
+ const isLocalPath = isExplicitLocalPath || !!resolvedLocalPluginFile;
700
+ if (isLocalPath && (!pluginManagerRef || !mockLessRef)) throw new Error(LESS_PLUGIN_JS_RUNTIME_MESSAGE);
701
+ if (pluginManagerRef && mockLessRef) try {
702
+ let scopeRules = node instanceof require_less_adapter.LessAdapterBase ? node.jessNode : node;
703
+ while (scopeRules && scopeRules.type !== "Rules") scopeRules = scopeRules.parent;
704
+ if (scopeRules && typeof scopeRules.setFunctionBinding === "function" && typeof scopeRules.findFunction === "function") if (!scopeRules.parent) currentRealRegistry = this._jessFunctionRegistry;
705
+ else currentRealRegistry = this.createJessFunctionBindingRegistry(scopeRules);
706
+ else currentRealRegistry = this._jessFunctionRegistry;
707
+ let pluginInstance = null;
708
+ if (this.opts.pluginRegistry && this.opts.pluginRegistry[pluginPath]) {
709
+ const pluginFactory = this.opts.pluginRegistry[pluginPath];
710
+ pluginInstance = typeof pluginFactory === "function" ? pluginFactory() : pluginFactory;
711
+ } else if (isLocalPath && resolvedLocalPluginFile) {
712
+ const loadedWithDeno = this.loadLessPluginFileWithDeno(resolvedLocalPluginFile, currentRealRegistry);
713
+ if (isThenable(loadedWithDeno)) return loadedWithDeno.then((loaded) => {
714
+ if (!loaded) throw new Error(LESS_PLUGIN_JS_RUNTIME_MESSAGE);
715
+ this.markPluginDirectiveInvisible(node);
716
+ return node;
717
+ });
718
+ if (!loadedWithDeno) throw new Error(LESS_PLUGIN_JS_RUNTIME_MESSAGE);
719
+ } else if (isLocalPath) throw new Error(LESS_PLUGIN_JS_RUNTIME_MESSAGE);
720
+ else if (!isLocalPath && this.opts.autoLoadPlugins !== false) {
721
+ const packageNamesToTry = ["less-plugin-", ""].map((prefix) => prefix + pluginPath);
722
+ let loaded = false;
723
+ if (this.opts.nodeModulesPlugin) for (const packageName of packageNamesToTry) {
724
+ const resolvedPath = this.opts.nodeModulesPlugin.resolvePackage(packageName);
725
+ if (resolvedPath) try {
726
+ const { module: pluginModule, registered } = requirePluginFile(resolvedPath, currentRealRegistry);
727
+ let PluginClass = pluginModule.default || pluginModule;
728
+ pluginInstance = registered || PluginClass;
729
+ loaded = true;
730
+ break;
731
+ } catch {}
732
+ }
733
+ if (!loaded) for (const fullName of packageNamesToTry) try {
734
+ if (typeof require !== "undefined") {
735
+ const { module: pluginModule, registered } = requirePluginFile(fullName, currentRealRegistry);
736
+ let PluginClass = pluginModule.default || pluginModule;
737
+ pluginInstance = registered || PluginClass;
738
+ loaded = true;
739
+ break;
740
+ }
741
+ } catch (e) {
742
+ if (e.code !== "MODULE_NOT_FOUND") {}
743
+ }
744
+ }
745
+ if (pluginInstance) {
746
+ if (typeof pluginInstance === "function") try {
747
+ pluginInstance = new pluginInstance();
748
+ } catch {}
749
+ if (pluginOptions && typeof pluginInstance.setOptions === "function") try {
750
+ pluginInstance.setOptions(pluginOptions);
751
+ } catch {}
752
+ const visitorsBefore = pluginManagerRef.visitors.length;
753
+ pluginManagerRef.registerPlugin(pluginInstance);
754
+ if (pluginOptions && typeof pluginInstance.setOptions === "function") try {
755
+ pluginInstance.setOptions(pluginOptions);
756
+ } catch {}
757
+ if (pluginManagerRef.visitors.length > visitorsBefore) {
758
+ const newVisitors = pluginManagerRef.visitors.slice(visitorsBefore);
759
+ lessVisitorInstances.push(...newVisitors.map((v) => {
760
+ if (v instanceof LessVisitor$1) return v;
761
+ return new LessVisitor$1(v);
762
+ }));
763
+ }
764
+ }
765
+ } catch (e) {
766
+ if (e instanceof Error && e.message === LESS_PLUGIN_JS_RUNTIME_MESSAGE) throw e;
767
+ }
768
+ }
769
+ this.markPluginDirectiveInvisible(node);
770
+ }
771
+ }
772
+ return node;
773
+ },
774
+ visit: (node) => {
775
+ if (!node) return node;
776
+ const jessNode = node instanceof require_less_adapter.LessAdapterBase ? node.jessNode : node;
777
+ if (typeof jessNode !== "object" || jessNode === null) return node;
778
+ if ((node.type === "AtRule" || node.type === "AtRuleStatement" || node.type === "Directive") && visitor.atRule) {
779
+ const atRuleResult = visitor.atRule(node, void 0);
780
+ if (atRuleResult && typeof atRuleResult !== "symbol" && atRuleResult !== node) {
781
+ node = atRuleResult;
782
+ if ((node instanceof require_less_adapter.LessAdapterBase ? node.jessNode : node) !== jessNode) {}
783
+ }
784
+ }
785
+ if (insideLessTraversal) return node;
786
+ if (processing.has(jessNode)) return node;
787
+ processing.add(jessNode);
788
+ try {
789
+ const lessNode = require_transform.toLessNode(jessNode, { cache: cacheMap });
790
+ insideLessTraversal = true;
791
+ try {
792
+ let result = lessNode;
793
+ if (lessVisitorInstances.length > 0) {
794
+ const visitorIterator = createVisitorIterator();
795
+ let iteratorResult = visitorIterator.next();
796
+ let iterationCount = 0;
797
+ while (!iteratorResult.done) {
798
+ iterationCount++;
799
+ if (iterationCount > 100) break;
800
+ result = iteratorResult.value.visit(result);
801
+ if (result === void 0) return _jesscss_core.REMOVE;
802
+ iteratorResult = visitorIterator.next();
803
+ }
804
+ }
805
+ if (result !== lessNode) {
806
+ const converted = require_transform.fromLessNode(result, { cache: cacheMap });
807
+ return converted !== jessNode ? converted : jessNode;
808
+ }
809
+ return jessNode;
810
+ } finally {
811
+ insideLessTraversal = false;
812
+ }
813
+ } finally {}
814
+ }
815
+ };
816
+ return visitor;
817
+ }
818
+ };
819
+ /**
820
+ * Create a Less.js compatibility plugin
821
+ */
822
+ const lessCompatPlugin = (opts) => {
823
+ return new LessCompatPlugin(opts);
824
+ };
825
+ //#endregion
826
+ exports.LessAdapterBase = require_less_adapter.LessAdapterBase;
827
+ exports.LessCompatPlugin = LessCompatPlugin;
828
+ exports.LessTreeConstructors = require_less_compat_structures.LessTreeConstructors;
829
+ exports.__toESM = __toESM;
830
+ exports.createLessAdapter = require_less_adapter.createLessAdapter;
831
+ exports.createLessMock = require_less_compat_structures.createLessMock;
832
+ exports.default = lessCompatPlugin;
833
+ exports.filterPlugins = filterPlugins;
834
+ exports.fromLessNode = require_transform.fromLessNode;
835
+ exports.fromLessPluginReturnValue = require_transform.fromLessPluginReturnValue;
836
+ exports.fromLessTree = require_transform.fromLessTree;
837
+ exports.getLessTypeIndex = require_less_adapter.getLessTypeIndex;
838
+ exports.isJessPlugin = isJessPlugin;
839
+ exports.isLessPlugin = isLessPlugin;
840
+ exports.lessCompatPlugin = lessCompatPlugin;
841
+ exports.mapJessTypeToLessType = require_less_adapter.mapJessTypeToLessType;
842
+ exports.mapLessTypeToJessType = require_less_adapter.mapLessTypeToJessType;
843
+ exports.toLessNode = require_transform.toLessNode;
844
+ exports.toLessTree = require_transform.toLessTree;