@jesscss/plugin-less 2.0.0-alpha.10 → 2.0.0-alpha.11
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 +103 -0
- package/lib/index.d.ts +18 -1
- package/lib/index.js +102 -1
- package/package.json +7 -7
package/lib/index.cjs
CHANGED
|
@@ -50,6 +50,107 @@ const lessPluginDefaults = {
|
|
|
50
50
|
collapseNesting: false
|
|
51
51
|
};
|
|
52
52
|
const lessValueEvaluator = (0, _jesscss_core.buildEvaluator)((0, _jesscss_fns_less_registry.makeLessRegistry)());
|
|
53
|
+
function stableStringify(value) {
|
|
54
|
+
if (value == null || typeof value !== "object") return JSON.stringify(value);
|
|
55
|
+
if (Array.isArray(value)) return `[${value.map(stableStringify).join(",")}]`;
|
|
56
|
+
if (!isObjectRecord(value)) return JSON.stringify(value);
|
|
57
|
+
return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(value[key])}`).join(",")}}`;
|
|
58
|
+
}
|
|
59
|
+
function isObjectRecord(value) {
|
|
60
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
61
|
+
}
|
|
62
|
+
function isPluginInterface(value) {
|
|
63
|
+
return isObjectRecord(value) && typeof value.name === "string";
|
|
64
|
+
}
|
|
65
|
+
function normalizeVariableName(name) {
|
|
66
|
+
return name.startsWith("@") ? name : `@${name}`;
|
|
67
|
+
}
|
|
68
|
+
function renderVariableOverrides(vars) {
|
|
69
|
+
if (!vars) return "";
|
|
70
|
+
return Object.entries(vars).map(([name, value]) => `${normalizeVariableName(name)}: ${String(value)};`).join("\n");
|
|
71
|
+
}
|
|
72
|
+
function getVariableOverrides(value) {
|
|
73
|
+
return isObjectRecord(value) ? value : null;
|
|
74
|
+
}
|
|
75
|
+
function cloneConfiguredPlugin(plugin) {
|
|
76
|
+
if (plugin.name !== "less-compat" || typeof plugin.constructor !== "function") return plugin;
|
|
77
|
+
try {
|
|
78
|
+
const opts = isObjectRecord(plugin) ? plugin.opts : void 0;
|
|
79
|
+
const freshPlugin = Reflect.construct(plugin.constructor, [opts]);
|
|
80
|
+
return isPluginInterface(freshPlugin) ? freshPlugin : plugin;
|
|
81
|
+
} catch {
|
|
82
|
+
return plugin;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function prepareLessRootSource(source, context) {
|
|
86
|
+
if (context.language !== void 0 && context.language !== "less") return source;
|
|
87
|
+
return [
|
|
88
|
+
[typeof context.activeOptions.banner === "string" ? context.activeOptions.banner : void 0, renderVariableOverrides(getVariableOverrides(context.activeOptions.globalVars))].filter(Boolean).join("\n"),
|
|
89
|
+
source,
|
|
90
|
+
renderVariableOverrides(getVariableOverrides(context.activeOptions.modifyVars))
|
|
91
|
+
].filter(Boolean).join("\n");
|
|
92
|
+
}
|
|
93
|
+
var LessPluginResolver = class {
|
|
94
|
+
pluginInstanceCache = /* @__PURE__ */ new Map();
|
|
95
|
+
nativePluginIds = /* @__PURE__ */ new Map();
|
|
96
|
+
nextNativePluginId = 0;
|
|
97
|
+
getCacheKey(lessOptions, nativePlugins = []) {
|
|
98
|
+
const optionsKey = stableStringify({
|
|
99
|
+
math: lessOptions.math,
|
|
100
|
+
mathMode: lessOptions.mathMode,
|
|
101
|
+
strictUnits: lessOptions.strictUnits,
|
|
102
|
+
unitMode: lessOptions.unitMode,
|
|
103
|
+
equalityMode: lessOptions.equalityMode,
|
|
104
|
+
allowExtendSelectors: lessOptions.allowExtendSelectors,
|
|
105
|
+
leakyScope: lessOptions.leakyScope,
|
|
106
|
+
bubbleRootAtRules: lessOptions.bubbleRootAtRules,
|
|
107
|
+
collapseNesting: lessOptions.collapseNesting,
|
|
108
|
+
rootpath: lessOptions.rootpath,
|
|
109
|
+
rewriteUrls: lessOptions.rewriteUrls,
|
|
110
|
+
urlArgs: lessOptions.urlArgs,
|
|
111
|
+
processImports: lessOptions.processImports
|
|
112
|
+
});
|
|
113
|
+
if (nativePlugins.length === 0) return optionsKey;
|
|
114
|
+
return `${optionsKey}|native-plugins:${nativePlugins.map((plugin) => {
|
|
115
|
+
let id = this.nativePluginIds.get(plugin);
|
|
116
|
+
if (id === void 0) {
|
|
117
|
+
id = ++this.nextNativePluginId;
|
|
118
|
+
this.nativePluginIds.set(plugin, id);
|
|
119
|
+
}
|
|
120
|
+
return id;
|
|
121
|
+
}).join(",")}`;
|
|
122
|
+
}
|
|
123
|
+
getOrCreate(lessOptions, nativePlugins = []) {
|
|
124
|
+
const key = this.getCacheKey(lessOptions, nativePlugins);
|
|
125
|
+
let plugin = this.pluginInstanceCache.get(key);
|
|
126
|
+
if (!plugin) {
|
|
127
|
+
plugin = lessPlugin({
|
|
128
|
+
...lessOptions,
|
|
129
|
+
...nativePlugins.length === 0 ? {} : { plugins: nativePlugins }
|
|
130
|
+
});
|
|
131
|
+
this.pluginInstanceCache.set(key, plugin);
|
|
132
|
+
}
|
|
133
|
+
return plugin;
|
|
134
|
+
}
|
|
135
|
+
normalizeConfiguredPlugin(plugin, context) {
|
|
136
|
+
if (plugin.name !== "less") return cloneConfiguredPlugin(plugin);
|
|
137
|
+
const pluginOptions = isObjectRecord(plugin) && isObjectRecord(plugin.opts) ? plugin.opts : {};
|
|
138
|
+
const resolvedLessOptions = Object.fromEntries(Object.entries(context.optionsFor("less")).filter(([, value]) => value !== void 0));
|
|
139
|
+
const nativePlugins = Array.isArray(pluginOptions.plugins) ? pluginOptions.plugins : [];
|
|
140
|
+
return this.getOrCreate({
|
|
141
|
+
...pluginOptions,
|
|
142
|
+
...resolvedLessOptions
|
|
143
|
+
}, nativePlugins);
|
|
144
|
+
}
|
|
145
|
+
dispose() {
|
|
146
|
+
for (const plugin of this.pluginInstanceCache.values()) try {
|
|
147
|
+
plugin.dispose?.();
|
|
148
|
+
} catch {}
|
|
149
|
+
this.pluginInstanceCache.clear();
|
|
150
|
+
this.nativePluginIds.clear();
|
|
151
|
+
this.nextNativePluginId = 0;
|
|
152
|
+
}
|
|
153
|
+
};
|
|
53
154
|
/** Match Less's URL normalization without treating URL text as an import path. */
|
|
54
155
|
function normalizeUrlPath(url) {
|
|
55
156
|
const segments = url.split("/");
|
|
@@ -233,5 +334,7 @@ const lessPlugin = ((opts) => {
|
|
|
233
334
|
});
|
|
234
335
|
//#endregion
|
|
235
336
|
exports.LessPlugin = LessPlugin;
|
|
337
|
+
exports.LessPluginResolver = LessPluginResolver;
|
|
236
338
|
exports.default = lessPlugin;
|
|
237
339
|
exports.lessPluginDefaults = lessPluginDefaults;
|
|
340
|
+
exports.prepareLessRootSource = prepareLessRootSource;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AbstractPlugin, Context, type UrlTransformRequest, type ISafeParseResult, type SafeParseOptions } from '@jesscss/core';
|
|
1
|
+
import { AbstractPlugin, Context, type UrlTransformRequest, type ISafeParseResult, type SafeParseOptions, type PluginInterface } from '@jesscss/core';
|
|
2
2
|
import type { EqualityMode, MathMode, UnitMode, LessOptions } from 'styles-config';
|
|
3
3
|
export type LessPluginOptions = LessOptions;
|
|
4
4
|
/**
|
|
@@ -17,6 +17,23 @@ export declare const lessPluginDefaults: {
|
|
|
17
17
|
readonly processImports: true;
|
|
18
18
|
readonly collapseNesting: false;
|
|
19
19
|
};
|
|
20
|
+
export type LessSourcePreparationContext = {
|
|
21
|
+
language?: string;
|
|
22
|
+
activeOptions: Record<string, unknown>;
|
|
23
|
+
};
|
|
24
|
+
export type LessPluginResolverContext = {
|
|
25
|
+
optionsFor(language?: string): Record<string, unknown>;
|
|
26
|
+
};
|
|
27
|
+
export declare function prepareLessRootSource(source: string, context: LessSourcePreparationContext): string;
|
|
28
|
+
export declare class LessPluginResolver {
|
|
29
|
+
private pluginInstanceCache;
|
|
30
|
+
private nativePluginIds;
|
|
31
|
+
private nextNativePluginId;
|
|
32
|
+
private getCacheKey;
|
|
33
|
+
getOrCreate(lessOptions: Record<string, unknown>, nativePlugins?: readonly unknown[]): PluginInterface;
|
|
34
|
+
normalizeConfiguredPlugin(plugin: PluginInterface, context: LessPluginResolverContext): PluginInterface;
|
|
35
|
+
dispose(): void;
|
|
36
|
+
}
|
|
20
37
|
export declare class LessPlugin extends AbstractPlugin {
|
|
21
38
|
opts: LessPluginOptions;
|
|
22
39
|
name: string;
|
package/lib/index.js
CHANGED
|
@@ -23,6 +23,107 @@ const lessPluginDefaults = {
|
|
|
23
23
|
collapseNesting: false
|
|
24
24
|
};
|
|
25
25
|
const lessValueEvaluator = buildEvaluator(makeLessRegistry());
|
|
26
|
+
function stableStringify(value) {
|
|
27
|
+
if (value == null || typeof value !== "object") return JSON.stringify(value);
|
|
28
|
+
if (Array.isArray(value)) return `[${value.map(stableStringify).join(",")}]`;
|
|
29
|
+
if (!isObjectRecord(value)) return JSON.stringify(value);
|
|
30
|
+
return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(value[key])}`).join(",")}}`;
|
|
31
|
+
}
|
|
32
|
+
function isObjectRecord(value) {
|
|
33
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
34
|
+
}
|
|
35
|
+
function isPluginInterface(value) {
|
|
36
|
+
return isObjectRecord(value) && typeof value.name === "string";
|
|
37
|
+
}
|
|
38
|
+
function normalizeVariableName(name) {
|
|
39
|
+
return name.startsWith("@") ? name : `@${name}`;
|
|
40
|
+
}
|
|
41
|
+
function renderVariableOverrides(vars) {
|
|
42
|
+
if (!vars) return "";
|
|
43
|
+
return Object.entries(vars).map(([name, value]) => `${normalizeVariableName(name)}: ${String(value)};`).join("\n");
|
|
44
|
+
}
|
|
45
|
+
function getVariableOverrides(value) {
|
|
46
|
+
return isObjectRecord(value) ? value : null;
|
|
47
|
+
}
|
|
48
|
+
function cloneConfiguredPlugin(plugin) {
|
|
49
|
+
if (plugin.name !== "less-compat" || typeof plugin.constructor !== "function") return plugin;
|
|
50
|
+
try {
|
|
51
|
+
const opts = isObjectRecord(plugin) ? plugin.opts : void 0;
|
|
52
|
+
const freshPlugin = Reflect.construct(plugin.constructor, [opts]);
|
|
53
|
+
return isPluginInterface(freshPlugin) ? freshPlugin : plugin;
|
|
54
|
+
} catch {
|
|
55
|
+
return plugin;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function prepareLessRootSource(source, context) {
|
|
59
|
+
if (context.language !== void 0 && context.language !== "less") return source;
|
|
60
|
+
return [
|
|
61
|
+
[typeof context.activeOptions.banner === "string" ? context.activeOptions.banner : void 0, renderVariableOverrides(getVariableOverrides(context.activeOptions.globalVars))].filter(Boolean).join("\n"),
|
|
62
|
+
source,
|
|
63
|
+
renderVariableOverrides(getVariableOverrides(context.activeOptions.modifyVars))
|
|
64
|
+
].filter(Boolean).join("\n");
|
|
65
|
+
}
|
|
66
|
+
var LessPluginResolver = class {
|
|
67
|
+
pluginInstanceCache = /* @__PURE__ */ new Map();
|
|
68
|
+
nativePluginIds = /* @__PURE__ */ new Map();
|
|
69
|
+
nextNativePluginId = 0;
|
|
70
|
+
getCacheKey(lessOptions, nativePlugins = []) {
|
|
71
|
+
const optionsKey = stableStringify({
|
|
72
|
+
math: lessOptions.math,
|
|
73
|
+
mathMode: lessOptions.mathMode,
|
|
74
|
+
strictUnits: lessOptions.strictUnits,
|
|
75
|
+
unitMode: lessOptions.unitMode,
|
|
76
|
+
equalityMode: lessOptions.equalityMode,
|
|
77
|
+
allowExtendSelectors: lessOptions.allowExtendSelectors,
|
|
78
|
+
leakyScope: lessOptions.leakyScope,
|
|
79
|
+
bubbleRootAtRules: lessOptions.bubbleRootAtRules,
|
|
80
|
+
collapseNesting: lessOptions.collapseNesting,
|
|
81
|
+
rootpath: lessOptions.rootpath,
|
|
82
|
+
rewriteUrls: lessOptions.rewriteUrls,
|
|
83
|
+
urlArgs: lessOptions.urlArgs,
|
|
84
|
+
processImports: lessOptions.processImports
|
|
85
|
+
});
|
|
86
|
+
if (nativePlugins.length === 0) return optionsKey;
|
|
87
|
+
return `${optionsKey}|native-plugins:${nativePlugins.map((plugin) => {
|
|
88
|
+
let id = this.nativePluginIds.get(plugin);
|
|
89
|
+
if (id === void 0) {
|
|
90
|
+
id = ++this.nextNativePluginId;
|
|
91
|
+
this.nativePluginIds.set(plugin, id);
|
|
92
|
+
}
|
|
93
|
+
return id;
|
|
94
|
+
}).join(",")}`;
|
|
95
|
+
}
|
|
96
|
+
getOrCreate(lessOptions, nativePlugins = []) {
|
|
97
|
+
const key = this.getCacheKey(lessOptions, nativePlugins);
|
|
98
|
+
let plugin = this.pluginInstanceCache.get(key);
|
|
99
|
+
if (!plugin) {
|
|
100
|
+
plugin = lessPlugin({
|
|
101
|
+
...lessOptions,
|
|
102
|
+
...nativePlugins.length === 0 ? {} : { plugins: nativePlugins }
|
|
103
|
+
});
|
|
104
|
+
this.pluginInstanceCache.set(key, plugin);
|
|
105
|
+
}
|
|
106
|
+
return plugin;
|
|
107
|
+
}
|
|
108
|
+
normalizeConfiguredPlugin(plugin, context) {
|
|
109
|
+
if (plugin.name !== "less") return cloneConfiguredPlugin(plugin);
|
|
110
|
+
const pluginOptions = isObjectRecord(plugin) && isObjectRecord(plugin.opts) ? plugin.opts : {};
|
|
111
|
+
const resolvedLessOptions = Object.fromEntries(Object.entries(context.optionsFor("less")).filter(([, value]) => value !== void 0));
|
|
112
|
+
const nativePlugins = Array.isArray(pluginOptions.plugins) ? pluginOptions.plugins : [];
|
|
113
|
+
return this.getOrCreate({
|
|
114
|
+
...pluginOptions,
|
|
115
|
+
...resolvedLessOptions
|
|
116
|
+
}, nativePlugins);
|
|
117
|
+
}
|
|
118
|
+
dispose() {
|
|
119
|
+
for (const plugin of this.pluginInstanceCache.values()) try {
|
|
120
|
+
plugin.dispose?.();
|
|
121
|
+
} catch {}
|
|
122
|
+
this.pluginInstanceCache.clear();
|
|
123
|
+
this.nativePluginIds.clear();
|
|
124
|
+
this.nextNativePluginId = 0;
|
|
125
|
+
}
|
|
126
|
+
};
|
|
26
127
|
/** Match Less's URL normalization without treating URL text as an import path. */
|
|
27
128
|
function normalizeUrlPath(url) {
|
|
28
129
|
const segments = url.split("/");
|
|
@@ -205,4 +306,4 @@ const lessPlugin = ((opts) => {
|
|
|
205
306
|
return new LessPlugin(opts);
|
|
206
307
|
});
|
|
207
308
|
//#endregion
|
|
208
|
-
export { LessPlugin, lessPlugin as default, lessPluginDefaults };
|
|
309
|
+
export { LessPlugin, LessPluginResolver, lessPlugin as default, lessPluginDefaults, prepareLessRootSource };
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
7
|
"description": "A Less stylesheet engine for Jess",
|
|
8
|
-
"version": "2.0.0-alpha.
|
|
8
|
+
"version": "2.0.0-alpha.11",
|
|
9
9
|
"engines": {
|
|
10
10
|
"node": "^20.19.0 || >=22.12.0"
|
|
11
11
|
},
|
|
@@ -23,12 +23,12 @@
|
|
|
23
23
|
"lib"
|
|
24
24
|
],
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@jesscss/fns": "2.0.0-alpha.
|
|
27
|
-
"@jesscss/
|
|
28
|
-
"@jesscss/plugin-less-compat": "2.0.0-alpha.
|
|
29
|
-
"@jesscss/
|
|
30
|
-
"@jesscss/style-resolver": "2.0.0-alpha.
|
|
31
|
-
"styles-config": "2.0.0-alpha.
|
|
26
|
+
"@jesscss/fns": "2.0.0-alpha.11",
|
|
27
|
+
"@jesscss/core": "2.0.0-alpha.11",
|
|
28
|
+
"@jesscss/plugin-less-compat": "2.0.0-alpha.11",
|
|
29
|
+
"@jesscss/less-parser": "2.0.0-alpha.11",
|
|
30
|
+
"@jesscss/style-resolver": "2.0.0-alpha.11",
|
|
31
|
+
"styles-config": "2.0.0-alpha.11"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {},
|
|
34
34
|
"author": "Matthew Dean <matthew-dean@users.noreply.github.com>",
|