@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.
- package/README.md +3 -2
- package/lib/index.cjs +844 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +800 -10
- package/lib/less-adapter.cjs +216 -0
- package/lib/less-adapter.js +181 -0
- package/lib/less-compat-structures.cjs +378 -0
- package/lib/less-compat-structures.d.ts +2 -2
- package/lib/less-compat-structures.js +367 -512
- package/lib/nodes/at-rule.d.ts +2 -2
- package/lib/nodes/attribute-selector.d.ts +2 -2
- package/lib/nodes/call.d.ts +2 -2
- package/lib/nodes/color.d.ts +2 -1
- package/lib/nodes/combinator.d.ts +2 -1
- package/lib/nodes/comment.d.ts +2 -1
- package/lib/nodes/condition.d.ts +2 -2
- package/lib/nodes/declaration.d.ts +2 -2
- package/lib/nodes/dimension.d.ts +2 -1
- package/lib/nodes/expression.d.ts +2 -2
- package/lib/nodes/extend.d.ts +2 -1
- package/lib/nodes/import.d.ts +2 -2
- package/lib/nodes/keyword.d.ts +2 -1
- package/lib/nodes/list.d.ts +3 -2
- package/lib/nodes/mixin.d.ts +2 -2
- package/lib/nodes/negative.d.ts +2 -2
- package/lib/nodes/operation.d.ts +2 -2
- package/lib/nodes/paren.d.ts +2 -2
- package/lib/nodes/quoted.d.ts +2 -1
- package/lib/nodes/reference.d.ts +2 -1
- package/lib/nodes/ruleset.d.ts +2 -2
- package/lib/nodes/selector.d.ts +2 -2
- package/lib/nodes/sequence.d.ts +2 -2
- package/lib/nodes/url.d.ts +2 -1
- package/lib/nodes/var-declaration.d.ts +2 -2
- package/lib/plugin.d.ts +44 -16
- package/lib/transform/adapter.d.ts +9 -11
- package/lib/transform/index.cjs +13 -0
- package/lib/transform/index.d.ts +1 -1
- package/lib/transform/index.js +3 -8
- package/lib/transform/less-adapter.d.ts +29 -0
- package/lib/transform.cjs +1045 -0
- package/lib/transform.js +1015 -0
- package/lib/types.d.ts +153 -28
- package/package.json +6 -9
- package/lib/index.js.map +0 -1
- package/lib/less-compat-structures.js.map +0 -1
- package/lib/nodes/at-rule.js +0 -21
- package/lib/nodes/at-rule.js.map +0 -1
- package/lib/nodes/attribute-selector.js +0 -18
- package/lib/nodes/attribute-selector.js.map +0 -1
- package/lib/nodes/call.js +0 -27
- package/lib/nodes/call.js.map +0 -1
- package/lib/nodes/color.js +0 -23
- package/lib/nodes/color.js.map +0 -1
- package/lib/nodes/combinator.js +0 -7
- package/lib/nodes/combinator.js.map +0 -1
- package/lib/nodes/comment.js +0 -9
- package/lib/nodes/comment.js.map +0 -1
- package/lib/nodes/condition.js +0 -19
- package/lib/nodes/condition.js.map +0 -1
- package/lib/nodes/declaration.js +0 -38
- package/lib/nodes/declaration.js.map +0 -1
- package/lib/nodes/dimension.js +0 -9
- package/lib/nodes/dimension.js.map +0 -1
- package/lib/nodes/expression.js +0 -16
- package/lib/nodes/expression.js.map +0 -1
- package/lib/nodes/extend.js +0 -18
- package/lib/nodes/extend.js.map +0 -1
- package/lib/nodes/import.js +0 -22
- package/lib/nodes/import.js.map +0 -1
- package/lib/nodes/index.js +0 -308
- package/lib/nodes/index.js.map +0 -1
- package/lib/nodes/keyword.js +0 -8
- package/lib/nodes/keyword.js.map +0 -1
- package/lib/nodes/list.js +0 -61
- package/lib/nodes/list.js.map +0 -1
- package/lib/nodes/mixin.js +0 -22
- package/lib/nodes/mixin.js.map +0 -1
- package/lib/nodes/negative.js +0 -13
- package/lib/nodes/negative.js.map +0 -1
- package/lib/nodes/operation.js +0 -22
- package/lib/nodes/operation.js.map +0 -1
- package/lib/nodes/paren.js +0 -13
- package/lib/nodes/paren.js.map +0 -1
- package/lib/nodes/quoted.js +0 -23
- package/lib/nodes/quoted.js.map +0 -1
- package/lib/nodes/reference.js +0 -44
- package/lib/nodes/reference.js.map +0 -1
- package/lib/nodes/ruleset.js +0 -67
- package/lib/nodes/ruleset.js.map +0 -1
- package/lib/nodes/selector.js +0 -158
- package/lib/nodes/selector.js.map +0 -1
- package/lib/nodes/sequence.js +0 -56
- package/lib/nodes/sequence.js.map +0 -1
- package/lib/nodes/url.js +0 -13
- package/lib/nodes/url.js.map +0 -1
- package/lib/nodes/var-declaration.js +0 -21
- package/lib/nodes/var-declaration.js.map +0 -1
- package/lib/plugin-utils.js +0 -100
- package/lib/plugin-utils.js.map +0 -1
- package/lib/plugin.js +0 -1026
- package/lib/plugin.js.map +0 -1
- package/lib/transform/adapter.js +0 -111
- package/lib/transform/adapter.js.map +0 -1
- package/lib/transform/from-less.js +0 -170
- package/lib/transform/from-less.js.map +0 -1
- package/lib/transform/index.js.map +0 -1
- package/lib/transform/proxy.d.ts +0 -32
- package/lib/transform/proxy.js +0 -138
- package/lib/transform/proxy.js.map +0 -1
- package/lib/transform/to-less.js +0 -130
- package/lib/transform/to-less.js.map +0 -1
- package/lib/transform/type-map.js +0 -105
- package/lib/transform/type-map.js.map +0 -1
- package/lib/types.js +0 -5
- 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;
|