less 4.9.0 → 5.0.0-alpha.1
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 +19 -5
- package/bin/lessc +190 -630
- package/dist/less-node.cjs +399 -14570
- package/index.cjs +5 -2
- package/lib/index.js +164 -0
- package/lib/lessc-helper.js +52 -0
- package/lib/logger.js +76 -0
- package/lib/options.d.ts +46 -0
- package/lib/options.js +145 -0
- package/lib/types.js +20 -0
- package/lib/version.js +19 -0
- package/package.json +34 -40
- package/dist/less.cjs +0 -15215
- package/dist/less.js +0 -15215
- package/dist/less.min.js +0 -11
- package/dist/less.min.js.map +0 -1
- package/lib/less/constants.js +0 -13
- package/lib/less/contexts.js +0 -165
- package/lib/less/data/colors.js +0 -150
- package/lib/less/data/index.js +0 -4
- package/lib/less/data/unit-conversions.js +0 -21
- package/lib/less/default-options.js +0 -89
- package/lib/less/deprecation.js +0 -82
- package/lib/less/environment/abstract-file-manager.js +0 -140
- package/lib/less/environment/abstract-plugin-loader.js +0 -185
- package/lib/less/environment/environment-api.ts +0 -21
- package/lib/less/environment/environment.js +0 -59
- package/lib/less/environment/file-manager-api.ts +0 -77
- package/lib/less/functions/boolean.js +0 -29
- package/lib/less/functions/color-blending.js +0 -85
- package/lib/less/functions/color.js +0 -452
- package/lib/less/functions/data-uri.js +0 -74
- package/lib/less/functions/default.js +0 -26
- package/lib/less/functions/function-caller.js +0 -55
- package/lib/less/functions/function-registry.js +0 -36
- package/lib/less/functions/index.js +0 -35
- package/lib/less/functions/list.js +0 -158
- package/lib/less/functions/math-helper.js +0 -22
- package/lib/less/functions/math.js +0 -30
- package/lib/less/functions/number.js +0 -95
- package/lib/less/functions/string.js +0 -39
- package/lib/less/functions/style.js +0 -29
- package/lib/less/functions/svg.js +0 -87
- package/lib/less/functions/types.js +0 -70
- package/lib/less/import-manager.js +0 -183
- package/lib/less/index.js +0 -95
- package/lib/less/less-error.js +0 -166
- package/lib/less/logger.js +0 -34
- package/lib/less/parse-tree.js +0 -124
- package/lib/less/parse.js +0 -87
- package/lib/less/parser/lookup-pattern.js +0 -26
- package/lib/less/parser/parser-input.js +0 -400
- package/lib/less/parser/parser.js +0 -2998
- package/lib/less/plugin-manager.js +0 -168
- package/lib/less/render.js +0 -41
- package/lib/less/source-map-builder.js +0 -82
- package/lib/less/source-map-output.js +0 -151
- package/lib/less/transform-tree.js +0 -102
- package/lib/less/tree/anonymous.js +0 -61
- package/lib/less/tree/assignment.js +0 -48
- package/lib/less/tree/atrule-syntax.js +0 -8
- package/lib/less/tree/atrule.js +0 -340
- package/lib/less/tree/attribute.js +0 -63
- package/lib/less/tree/call.js +0 -132
- package/lib/less/tree/color.js +0 -285
- package/lib/less/tree/combinator.js +0 -38
- package/lib/less/tree/comment.js +0 -48
- package/lib/less/tree/condition.js +0 -65
- package/lib/less/tree/container.js +0 -104
- package/lib/less/tree/debug-info.js +0 -80
- package/lib/less/tree/declaration.js +0 -139
- package/lib/less/tree/detached-ruleset.js +0 -45
- package/lib/less/tree/dimension.js +0 -215
- package/lib/less/tree/element.js +0 -93
- package/lib/less/tree/expression.js +0 -100
- package/lib/less/tree/extend.js +0 -88
- package/lib/less/tree/import.js +0 -299
- package/lib/less/tree/index.js +0 -56
- package/lib/less/tree/interpolated-variable.js +0 -106
- package/lib/less/tree/javascript.js +0 -45
- package/lib/less/tree/js-eval-node.js +0 -80
- package/lib/less/tree/keyword.js +0 -28
- package/lib/less/tree/media.js +0 -90
- package/lib/less/tree/merge-rules.js +0 -47
- package/lib/less/tree/mixin-call.js +0 -283
- package/lib/less/tree/mixin-definition.js +0 -319
- package/lib/less/tree/namespace-value.js +0 -95
- package/lib/less/tree/negative.js +0 -37
- package/lib/less/tree/nested-at-rule.js +0 -239
- package/lib/less/tree/node.js +0 -310
- package/lib/less/tree/operation.js +0 -81
- package/lib/less/tree/paren.js +0 -41
- package/lib/less/tree/property.js +0 -96
- package/lib/less/tree/query-in-parens.js +0 -64
- package/lib/less/tree/quoted.js +0 -131
- package/lib/less/tree/ruleset.js +0 -1068
- package/lib/less/tree/selector.js +0 -201
- package/lib/less/tree/unicode-descriptor.js +0 -14
- package/lib/less/tree/unit.js +0 -170
- package/lib/less/tree/url.js +0 -83
- package/lib/less/tree/value.js +0 -60
- package/lib/less/tree/variable-call.js +0 -60
- package/lib/less/tree/variable.js +0 -85
- package/lib/less/utils.js +0 -126
- package/lib/less/visitors/extend-visitor.js +0 -505
- package/lib/less/visitors/import-sequencer.js +0 -56
- package/lib/less/visitors/import-visitor.js +0 -203
- package/lib/less/visitors/index.js +0 -15
- package/lib/less/visitors/join-selector-visitor.js +0 -65
- package/lib/less/visitors/set-tree-visibility-visitor.js +0 -57
- package/lib/less/visitors/to-css-visitor.js +0 -332
- package/lib/less/visitors/visitor.js +0 -165
- package/lib/less-browser/add-default-options.js +0 -53
- package/lib/less-browser/bootstrap.js +0 -67
- package/lib/less-browser/browser.js +0 -65
- package/lib/less-browser/cache.js +0 -43
- package/lib/less-browser/error-reporting.js +0 -170
- package/lib/less-browser/file-manager.js +0 -112
- package/lib/less-browser/image-size.js +0 -28
- package/lib/less-browser/index.js +0 -284
- package/lib/less-browser/log-listener.js +0 -42
- package/lib/less-browser/plugin-loader.js +0 -24
- package/lib/less-browser/utils.js +0 -30
- package/lib/less-node/environment.js +0 -43
- package/lib/less-node/file-manager.js +0 -156
- package/lib/less-node/fs.js +0 -14
- package/lib/less-node/image-size.js +0 -78
- package/lib/less-node/index.js +0 -31
- package/lib/less-node/lessc-helper.js +0 -95
- package/lib/less-node/plugin-loader.js +0 -62
- package/lib/less-node/url-file-manager.js +0 -60
package/index.cjs
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
// CJS entry
|
|
2
|
-
|
|
1
|
+
// CJS entry: unwrap the Rollup namespace so require('less') returns the Less API object.
|
|
2
|
+
const bundle = require('./dist/less-node.cjs');
|
|
3
|
+
|
|
4
|
+
module.exports = bundle.default || bundle;
|
|
5
|
+
Object.assign(module.exports, bundle);
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Less.js v5 — powered by Jess
|
|
3
|
+
*
|
|
4
|
+
* This module provides a Less-compatible API backed by the Jess compiler.
|
|
5
|
+
* It supports the same `less.render()` interface that Less 4.x users expect,
|
|
6
|
+
* while delegating all parsing, evaluation, and output to Jess with the
|
|
7
|
+
* `@jesscss/plugin-less` and `@jesscss/plugin-less-compat` plugins.
|
|
8
|
+
*
|
|
9
|
+
* @module less
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { readFileSync } from 'node:fs';
|
|
13
|
+
import { readFile } from 'node:fs/promises';
|
|
14
|
+
import { Compiler } from '@jesscss/compiler';
|
|
15
|
+
import nodeModulesPlugin from '@jesscss/plugin-node-modules';
|
|
16
|
+
import { createLessOptions, getCompilerCacheKey, mapRenderResult } from './options.js';
|
|
17
|
+
import { version } from './version.js';
|
|
18
|
+
import { logger } from './logger.js';
|
|
19
|
+
import { lesscHelper } from './lessc-helper.js';
|
|
20
|
+
|
|
21
|
+
const compilerCache = new Map();
|
|
22
|
+
const lessVersion = version.array;
|
|
23
|
+
|
|
24
|
+
function normalizeDiagnosticLines(lines, lineNumber, filePath) {
|
|
25
|
+
if (Array.isArray(lines)) {
|
|
26
|
+
return lines.map((line) => typeof line === 'string' ? line : String(line));
|
|
27
|
+
}
|
|
28
|
+
if (lines && typeof lines === 'object') {
|
|
29
|
+
const current = Number(lineNumber) || 1;
|
|
30
|
+
return [current - 1, current, current + 1]
|
|
31
|
+
.filter((line) => line > 0 && Object.prototype.hasOwnProperty.call(lines, line))
|
|
32
|
+
.map((line) => {
|
|
33
|
+
const value = lines[line];
|
|
34
|
+
return typeof value === 'string' ? value : String(value);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
if (typeof filePath === 'string') {
|
|
38
|
+
try {
|
|
39
|
+
const sourceLines = readFileSync(filePath, 'utf8').split(/\r?\n/);
|
|
40
|
+
const current = Number(lineNumber) || 1;
|
|
41
|
+
return [current - 1, current, current + 1]
|
|
42
|
+
.filter((line) => line > 0 && line <= sourceLines.length)
|
|
43
|
+
.map((line) => sourceLines[line - 1]);
|
|
44
|
+
} catch {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function createRenderErrorFromJessDiagnostic(result, filePath) {
|
|
52
|
+
const errors = result?.errors || [];
|
|
53
|
+
const diagnostic = errors[0];
|
|
54
|
+
const error = new Error(diagnostic?.message || 'Less render failed');
|
|
55
|
+
|
|
56
|
+
error.type = diagnostic?.phase || 'Syntax';
|
|
57
|
+
error.filename = diagnostic?.filePath || filePath;
|
|
58
|
+
error.line = diagnostic?.line || 1;
|
|
59
|
+
error.column = diagnostic?.column || 1;
|
|
60
|
+
error.extract = normalizeDiagnosticLines(diagnostic?.lines, error.line, error.filename);
|
|
61
|
+
error.jessErrors = errors;
|
|
62
|
+
error.jessWarnings = result?.warnings || [];
|
|
63
|
+
|
|
64
|
+
return error;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @param {object} configOptions
|
|
69
|
+
*/
|
|
70
|
+
function getCompiler(configOptions) {
|
|
71
|
+
const cacheKey = getCompilerCacheKey(configOptions);
|
|
72
|
+
let compiler = compilerCache.get(cacheKey);
|
|
73
|
+
if (!compiler) {
|
|
74
|
+
compiler = new Compiler(configOptions, {
|
|
75
|
+
defaultPlugins: context => [nodeModulesPlugin({ basePath: context.resolutionBaseDir })],
|
|
76
|
+
scriptPluginSpecifier: '@jesscss/plugin-js',
|
|
77
|
+
scriptPluginResolveFrom: import.meta.url
|
|
78
|
+
});
|
|
79
|
+
compilerCache.set(cacheKey, compiler);
|
|
80
|
+
}
|
|
81
|
+
return compiler;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Render Less source to CSS.
|
|
86
|
+
*
|
|
87
|
+
* @param {string} input - Less source string
|
|
88
|
+
* @param {import('./options.js').LessRenderOptions} [options={}]
|
|
89
|
+
* @param {Function} [callback] - Optional Node-style callback(err, result)
|
|
90
|
+
* @returns {Promise<import('./options.js').LessRenderResult>}
|
|
91
|
+
*/
|
|
92
|
+
function render(input, options = {}, callback) {
|
|
93
|
+
if (typeof options === 'function') {
|
|
94
|
+
callback = options;
|
|
95
|
+
options = {};
|
|
96
|
+
}
|
|
97
|
+
const promise = (async () => {
|
|
98
|
+
const { configOptions, filePath } = createLessOptions(options, { source: input });
|
|
99
|
+
const compiler = getCompiler(configOptions);
|
|
100
|
+
|
|
101
|
+
const result = await compiler.renderToResult(
|
|
102
|
+
{ source: input, filePath, language: 'less', extension: '.less' },
|
|
103
|
+
{ ...configOptions, suppressWarnings: true }
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
if (result.errors?.length) {
|
|
107
|
+
throw createRenderErrorFromJessDiagnostic(result, filePath);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return mapRenderResult(result, options);
|
|
111
|
+
})();
|
|
112
|
+
|
|
113
|
+
if (callback) {
|
|
114
|
+
promise.then(
|
|
115
|
+
result => callback(null, result),
|
|
116
|
+
err => callback(err)
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
return promise;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Render a Less file to CSS.
|
|
124
|
+
*
|
|
125
|
+
* @param {string} filePath - Absolute or relative path to .less file
|
|
126
|
+
* @param {import('./options.js').LessRenderOptions} [options={}]
|
|
127
|
+
* @returns {Promise<import('./options.js').LessRenderResult>}
|
|
128
|
+
*/
|
|
129
|
+
async function renderFile(filePath, options = {}) {
|
|
130
|
+
const source = await readFile(filePath, 'utf8');
|
|
131
|
+
const { configOptions } = createLessOptions(options, { source });
|
|
132
|
+
const compiler = getCompiler(configOptions);
|
|
133
|
+
|
|
134
|
+
const result = await compiler.renderToResult(filePath, { ...configOptions, suppressWarnings: true });
|
|
135
|
+
if (result.errors?.length) {
|
|
136
|
+
throw createRenderErrorFromJessDiagnostic(result, filePath);
|
|
137
|
+
}
|
|
138
|
+
return mapRenderResult(result, options);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* COMPAT GAP (v5): the Less 4.x `less.functions` (custom-function registry via
|
|
143
|
+
* `less.functions.functionRegistry.add/addMultiple`) and `less.tree` (node
|
|
144
|
+
* constructors) are intentionally NOT present on the Jess-backed build. Jess
|
|
145
|
+
* registers custom functions with `defineFunction(name, fn, opts)` supplied
|
|
146
|
+
* through the compiler config/plugins, and its values are Jess nodes, not
|
|
147
|
+
* `less.tree.*`. Providing these as throwing stubs would break feature-detection
|
|
148
|
+
* (`if (less.functions)`), so they are left absent until a real compat surface
|
|
149
|
+
* (registry -> defineFunction bridge + tree-node shims) is built. Tracked for
|
|
150
|
+
* the broader Less-runner/API-parity work; see also test/less-test.js guards.
|
|
151
|
+
*
|
|
152
|
+
* @type {import('./types.js').LessStatic}
|
|
153
|
+
*/
|
|
154
|
+
const less = {
|
|
155
|
+
version: lessVersion,
|
|
156
|
+
render,
|
|
157
|
+
renderFile,
|
|
158
|
+
logger,
|
|
159
|
+
lesscHelper,
|
|
160
|
+
Compiler,
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export default less;
|
|
164
|
+
export { render, renderFile, logger, lesscHelper, Compiler, lessVersion as version };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper functions for lessc CLI.
|
|
3
|
+
* Adapted from lib.bak/less-node/lessc-helper.js.
|
|
4
|
+
* @module less/lib/lessc-helper
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** @type {Record<string, [number, number]>} */
|
|
8
|
+
const STYLES = {
|
|
9
|
+
reset: [0, 0],
|
|
10
|
+
bold: [1, 22],
|
|
11
|
+
inverse: [7, 27],
|
|
12
|
+
underline: [4, 24],
|
|
13
|
+
yellow: [33, 39],
|
|
14
|
+
green: [32, 39],
|
|
15
|
+
red: [31, 39],
|
|
16
|
+
grey: [90, 39],
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const lesscHelper = {
|
|
20
|
+
/** @param {string} str @param {string} style */
|
|
21
|
+
stylize(str, style) {
|
|
22
|
+
const s = STYLES[style] ?? STYLES.reset;
|
|
23
|
+
return `\x1b[${s[0]}m${str}\x1b[${s[1]}m`;
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
printUsage() {
|
|
27
|
+
console.log('usage: lessc [option option=parameter ...] <source> [destination]');
|
|
28
|
+
console.log('');
|
|
29
|
+
console.log('If source is set to `-\' (dash or hyphen-minus), input is read from stdin.');
|
|
30
|
+
console.log('');
|
|
31
|
+
console.log('options:');
|
|
32
|
+
console.log(' -h, --help Prints help (this message) and exit.');
|
|
33
|
+
console.log(' -I PATH, -IPATH Adds an import search path.');
|
|
34
|
+
console.log(' --include-path=PATHS Sets include paths. Separated by `:\'. `;\' also supported on windows.');
|
|
35
|
+
console.log(' --no-color Disables colorized output.');
|
|
36
|
+
console.log(' -s, --silent Suppresses output of error messages.');
|
|
37
|
+
console.log(' --quiet Suppresses output of warnings.');
|
|
38
|
+
console.log(' -v, --version Prints version number and exit.');
|
|
39
|
+
console.log(' --verbose Be verbose.');
|
|
40
|
+
console.log(' --collapse-nesting Flatten nested rules after preserving source-order cascade.');
|
|
41
|
+
console.log('');
|
|
42
|
+
console.log('This release intentionally supports a smaller CLI surface.');
|
|
43
|
+
console.log('Source maps, browser compilation, legacy plugin flags, lint-only mode, and');
|
|
44
|
+
console.log('URL rewrite flags will be revisited in later alphas.');
|
|
45
|
+
console.log('');
|
|
46
|
+
console.log('Report bugs to: http://github.com/less/less.js/issues');
|
|
47
|
+
console.log('Home page: <http://lesscss.org/>');
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export { lesscHelper };
|
|
52
|
+
export default lesscHelper;
|
package/lib/logger.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Less logger wired to Jess's logger singleton.
|
|
3
|
+
* Forwards to Jess and maintains Less-style addListener/removeListener for compatibility.
|
|
4
|
+
* @module less/lib/logger
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { logger as jessLogger } from '@jesscss/core';
|
|
8
|
+
|
|
9
|
+
/** @typedef {{ error?: (msg: string) => void, warn?: (msg: string) => void, info?: (msg: string) => void, debug?: (msg: string) => void }} LogListener */
|
|
10
|
+
|
|
11
|
+
/** @type {LogListener[]} */
|
|
12
|
+
const _listeners = [];
|
|
13
|
+
|
|
14
|
+
/** @param {'error'|'warn'|'info'|'debug'} type @param {string} msg */
|
|
15
|
+
function _fireEvent(type, msg) {
|
|
16
|
+
for (const listener of _listeners) {
|
|
17
|
+
const fn = listener[type];
|
|
18
|
+
if (fn) fn(msg);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Wrap Jess's logger so Less listeners receive Jess's log output without
|
|
23
|
+
// writing directly to stderr/stdout. Library consumers should be able to catch
|
|
24
|
+
// `less.render()` rejections without surprise terminal output; the CLI owns
|
|
25
|
+
// deciding whether/how to print diagnostics.
|
|
26
|
+
jessLogger.configure?.({
|
|
27
|
+
log(...args) {
|
|
28
|
+
_fireEvent('debug', args.map(String).join(' '));
|
|
29
|
+
},
|
|
30
|
+
info(...args) {
|
|
31
|
+
_fireEvent('info', args.map(String).join(' '));
|
|
32
|
+
},
|
|
33
|
+
warn(...args) {
|
|
34
|
+
_fireEvent('warn', args.map(String).join(' '));
|
|
35
|
+
},
|
|
36
|
+
error(...args) {
|
|
37
|
+
_fireEvent('error', args.map(String).join(' '));
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
/** Less-compatible logger backed by Jess's singleton */
|
|
42
|
+
const logger = {
|
|
43
|
+
/** @param {string} msg */
|
|
44
|
+
error(msg) {
|
|
45
|
+
_fireEvent('error', msg);
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
/** @param {string} msg */
|
|
49
|
+
warn(msg) {
|
|
50
|
+
_fireEvent('warn', msg);
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
/** @param {string} msg */
|
|
54
|
+
info(msg) {
|
|
55
|
+
_fireEvent('info', msg);
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
/** @param {string} msg */
|
|
59
|
+
debug(msg) {
|
|
60
|
+
_fireEvent('debug', msg);
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
/** @param {LogListener} listener */
|
|
64
|
+
addListener(listener) {
|
|
65
|
+
_listeners.push(listener);
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
/** @param {LogListener} listener */
|
|
69
|
+
removeListener(listener) {
|
|
70
|
+
const i = _listeners.indexOf(listener);
|
|
71
|
+
if (i >= 0) _listeners.splice(i, 1);
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export { logger };
|
|
76
|
+
export default logger;
|
package/lib/options.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options mapping between Less render options and Jess compiler config.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface LessRenderOptions {
|
|
6
|
+
filename?: string;
|
|
7
|
+
paths?: string[];
|
|
8
|
+
/**
|
|
9
|
+
* Legacy Less render plugins are routed through the alpha compatibility
|
|
10
|
+
* layer. File-manager, pre/post-processor, and @plugin execution are not
|
|
11
|
+
* alpha.1-supported surfaces yet.
|
|
12
|
+
*/
|
|
13
|
+
plugins?: unknown[];
|
|
14
|
+
math?: number | 'always' | 'parens-division' | 'parens' | 'strict';
|
|
15
|
+
/**
|
|
16
|
+
* Opt into Less 4-style flattened output. Less v5 preserves authored nesting
|
|
17
|
+
* by default.
|
|
18
|
+
*/
|
|
19
|
+
collapseNesting?: boolean;
|
|
20
|
+
/** @internal Jess alpha benchmark-only flag for source graphs already proven @plugin-free. */
|
|
21
|
+
__jessSkipLessCompatWhenPluginFree?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface LessRenderResult {
|
|
25
|
+
css: string;
|
|
26
|
+
map?: string;
|
|
27
|
+
imports?: string[];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface JessRenderResult {
|
|
31
|
+
css?: string;
|
|
32
|
+
map?: string | object;
|
|
33
|
+
imports?: string[];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function createLessOptions(options?: LessRenderOptions): {
|
|
37
|
+
configOptions: object;
|
|
38
|
+
filePath?: string;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export function getCompilerCacheKey(configOptions: object): string;
|
|
42
|
+
|
|
43
|
+
export function mapRenderResult(
|
|
44
|
+
result: JessRenderResult,
|
|
45
|
+
options?: LessRenderOptions
|
|
46
|
+
): LessRenderResult;
|
package/lib/options.js
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options mapping between Less render options and Jess compiler config.
|
|
3
|
+
* @module less/lib/options
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import lessPlugin from '@jesscss/plugin-less';
|
|
7
|
+
import { lessCompatPlugin } from '@jesscss/plugin-less-compat';
|
|
8
|
+
|
|
9
|
+
const unsupportedAlphaOptions = new Map([
|
|
10
|
+
['sourceMap', 'source maps are not supported'],
|
|
11
|
+
['sourceMapFilename', 'source maps are not supported'],
|
|
12
|
+
['sourceMapRootpath', 'source maps are not supported'],
|
|
13
|
+
['sourceMapBasepath', 'source maps are not supported'],
|
|
14
|
+
['sourceMapURL', 'source maps are not supported'],
|
|
15
|
+
['sourceMapFileInline', 'source maps are not supported'],
|
|
16
|
+
['globalVars', 'global variable injection is not supported'],
|
|
17
|
+
['modifyVars', 'modify-var injection is not supported'],
|
|
18
|
+
['strictUnits', 'strict unit mode is not supported'],
|
|
19
|
+
['rootpath', 'URL rootpath rewriting is not supported'],
|
|
20
|
+
['rewriteUrls', 'URL rewriting is not supported'],
|
|
21
|
+
['urlArgs', 'URL argument rewriting is not supported'],
|
|
22
|
+
['javascriptEnabled', 'JavaScript evaluation is not supported'],
|
|
23
|
+
['compress', 'compressed output is not supported'],
|
|
24
|
+
]);
|
|
25
|
+
|
|
26
|
+
function validateAlphaOptions(options) {
|
|
27
|
+
for (const [name, reason] of unsupportedAlphaOptions) {
|
|
28
|
+
if (Object.prototype.hasOwnProperty.call(options, name)) {
|
|
29
|
+
throw new Error(`${name} is not supported: ${reason}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @param {any} value
|
|
36
|
+
* @param {WeakSet<object>} [seen]
|
|
37
|
+
* @returns {string}
|
|
38
|
+
*/
|
|
39
|
+
function stableStringify(value, seen = new WeakSet()) {
|
|
40
|
+
if (value == null || typeof value !== 'object') {
|
|
41
|
+
if (typeof value === 'function') {
|
|
42
|
+
return JSON.stringify(`[function ${value.name || 'anonymous'}]`);
|
|
43
|
+
}
|
|
44
|
+
return JSON.stringify(value);
|
|
45
|
+
}
|
|
46
|
+
if (seen.has(value)) {
|
|
47
|
+
return '"[Circular]"';
|
|
48
|
+
}
|
|
49
|
+
seen.add(value);
|
|
50
|
+
if (Array.isArray(value)) {
|
|
51
|
+
return `[${value.map((item) => stableStringify(item, seen)).join(',')}]`;
|
|
52
|
+
}
|
|
53
|
+
if (value.name && typeof value.name === 'string' && ('install' in value || 'parser' in value || 'opts' in value)) {
|
|
54
|
+
return stableStringify({
|
|
55
|
+
plugin: value.name,
|
|
56
|
+
opts: value.opts || {},
|
|
57
|
+
}, seen);
|
|
58
|
+
}
|
|
59
|
+
const entries = Object.keys(value)
|
|
60
|
+
.sort()
|
|
61
|
+
.map((key) => `${JSON.stringify(key)}:${stableStringify(value[key], seen)}`);
|
|
62
|
+
return `{${entries.join(',')}}`;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Map Less render options to Jess compiler config.
|
|
67
|
+
* @param {import('./options.js').LessRenderOptions} [options] Less-style options
|
|
68
|
+
* @returns {{ configOptions: object, filePath?: string }}
|
|
69
|
+
*/
|
|
70
|
+
export function createLessOptions(options) {
|
|
71
|
+
const opts = options || {};
|
|
72
|
+
validateAlphaOptions(opts);
|
|
73
|
+
const filePath = opts.filename || undefined;
|
|
74
|
+
const lessPlugins = Array.isArray(opts.plugins) ? opts.plugins : [];
|
|
75
|
+
const skipLessCompat =
|
|
76
|
+
opts.__jessSkipLessCompatWhenPluginFree === true && lessPlugins.length === 0;
|
|
77
|
+
|
|
78
|
+
const math = /** @type {number|string|undefined} */ (opts.math);
|
|
79
|
+
const mathMode =
|
|
80
|
+
math === 0 || math === 'always' ? 'always' :
|
|
81
|
+
math === 2 || math === 'parens' || math === 'strict' ? 'parens' :
|
|
82
|
+
'parens-division';
|
|
83
|
+
|
|
84
|
+
const plugins = [lessPlugin()];
|
|
85
|
+
if (!skipLessCompat) {
|
|
86
|
+
plugins.push(lessCompatPlugin({ plugins: lessPlugins }));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const configOptions = {
|
|
90
|
+
compile: {
|
|
91
|
+
searchPaths: opts.paths || [],
|
|
92
|
+
mathMode,
|
|
93
|
+
plugins,
|
|
94
|
+
},
|
|
95
|
+
// Less v5 preserves authored nesting unless its explicit compatibility
|
|
96
|
+
// switch requests flattened CSS. Keep that public Less option at the
|
|
97
|
+
// wrapper boundary; Jess owns the one renderer and its output mode.
|
|
98
|
+
// A file's styles.config may use an output array. A file-less output entry
|
|
99
|
+
// is the compiler's documented per-render override for that shape, so an
|
|
100
|
+
// explicit public Less option remains authoritative over fixture config.
|
|
101
|
+
output: Object.prototype.hasOwnProperty.call(opts, 'collapseNesting')
|
|
102
|
+
? [{ collapseNesting: opts.collapseNesting === true }]
|
|
103
|
+
: {},
|
|
104
|
+
language: {},
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
return { configOptions, filePath };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Stable compiler cache key for a Jess compiler configured from Less options.
|
|
112
|
+
* @param {object} configOptions Jess compiler config
|
|
113
|
+
* @returns {string}
|
|
114
|
+
*/
|
|
115
|
+
export function getCompilerCacheKey(configOptions) {
|
|
116
|
+
return stableStringify(configOptions);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Map Jess render result to Less-style result.
|
|
121
|
+
* @param {import('./options.js').JessRenderResult} result Jess compiler result
|
|
122
|
+
* @param {import('./options.js').LessRenderOptions} [options] Original Less options
|
|
123
|
+
* @returns {import('./options.js').LessRenderResult}
|
|
124
|
+
*/
|
|
125
|
+
export function mapRenderResult(result, options) {
|
|
126
|
+
const opts = options || {};
|
|
127
|
+
/** @type {import('./options.js').LessRenderResult} */
|
|
128
|
+
const out = {
|
|
129
|
+
css: result.css ?? '',
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
if (result.imports && Array.isArray(result.imports)) {
|
|
133
|
+
out.imports = result.imports;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Structured Jess warnings (e.g. selector/parentless-ampersand). Exposed so
|
|
137
|
+
// callers and tests can assert them, mirroring how errors surface.
|
|
138
|
+
if (result.warnings && Array.isArray(result.warnings)) {
|
|
139
|
+
out.warnings = result.warnings;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return out;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export default { createLessOptions, getCompilerCacheKey, mapRenderResult };
|
package/lib/types.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSDoc type definitions for Less.js v5 (Jess wrapper).
|
|
3
|
+
* @module less/lib/types
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {import('./options.js').LessRenderResult} LessRenderResult
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @typedef {Object} LessStatic
|
|
12
|
+
* @property {number[]} version Less-compatible version tuple
|
|
13
|
+
* @property {function(string, import('./options.js').LessRenderOptions?, function?): Promise<LessRenderResult>} render Render Less to CSS
|
|
14
|
+
* @property {function(string, import('./options.js').LessRenderOptions?): Promise<LessRenderResult>} renderFile Render Less file to CSS
|
|
15
|
+
* @property {import('./logger.js').default} logger Logger instance
|
|
16
|
+
* @property {import('./lessc-helper.js').default} lesscHelper CLI helper
|
|
17
|
+
* @property {object} Compiler Jess Compiler class
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
export {};
|
package/lib/version.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version info for Less.js v5 (Jess wrapper).
|
|
3
|
+
* @module less/lib/version
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { createRequire } from 'module';
|
|
7
|
+
import parseNodeVersion from 'parse-node-version';
|
|
8
|
+
|
|
9
|
+
const require = createRequire(import.meta.url);
|
|
10
|
+
const pkg = require('../package.json');
|
|
11
|
+
const semver = pkg.version || '5.0.0-alpha.0';
|
|
12
|
+
const parsed = parseNodeVersion(`v${semver}`);
|
|
13
|
+
|
|
14
|
+
export const version = {
|
|
15
|
+
semver,
|
|
16
|
+
array: [parsed.major, parsed.minor, parsed.patch],
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default version;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "less",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0-alpha.1",
|
|
4
4
|
"description": "Leaner CSS",
|
|
5
5
|
"homepage": "http://lesscss.org",
|
|
6
6
|
"author": {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"repository": {
|
|
17
17
|
"type": "git",
|
|
18
|
-
"url": "https://github.com/less/less.js.git"
|
|
18
|
+
"url": "git+https://github.com/less/less.js.git"
|
|
19
19
|
},
|
|
20
20
|
"master": {
|
|
21
21
|
"url": "https://github.com/less/less.js/blob/master/",
|
|
@@ -24,21 +24,17 @@
|
|
|
24
24
|
"license": "Apache-2.0",
|
|
25
25
|
"type": "module",
|
|
26
26
|
"bin": {
|
|
27
|
-
"lessc": "
|
|
27
|
+
"lessc": "bin/lessc"
|
|
28
28
|
},
|
|
29
29
|
"main": "./dist/less-node.cjs",
|
|
30
30
|
"exports": {
|
|
31
31
|
".": {
|
|
32
|
-
"
|
|
33
|
-
"import": "./lib/less-node/index.js",
|
|
32
|
+
"import": "./lib/index.js",
|
|
34
33
|
"require": "./dist/less-node.cjs",
|
|
35
|
-
"default": "./lib/
|
|
34
|
+
"default": "./lib/index.js"
|
|
36
35
|
},
|
|
37
36
|
"./lib/*": "./lib/*",
|
|
38
|
-
"./dist/less-node.cjs": "./dist/less-node.cjs"
|
|
39
|
-
"./dist/less.cjs": "./dist/less.cjs",
|
|
40
|
-
"./dist/less.js": "./dist/less.js",
|
|
41
|
-
"./dist/less.min.js": "./dist/less.min.js"
|
|
37
|
+
"./dist/less-node.cjs": "./dist/less-node.cjs"
|
|
42
38
|
},
|
|
43
39
|
"directories": {
|
|
44
40
|
"test": "./test"
|
|
@@ -51,30 +47,25 @@
|
|
|
51
47
|
"index.cjs",
|
|
52
48
|
"README.md"
|
|
53
49
|
],
|
|
54
|
-
"browser": "./dist/less.js",
|
|
55
50
|
"engines": {
|
|
56
|
-
"node": ">=
|
|
51
|
+
"node": "^20.19.0 || >=22.12.0"
|
|
57
52
|
},
|
|
58
53
|
"scripts": {
|
|
59
|
-
"quicktest": "
|
|
60
|
-
"test": "
|
|
61
|
-
"test:
|
|
62
|
-
"test
|
|
63
|
-
"
|
|
54
|
+
"quicktest": "npm run test:legacy-node",
|
|
55
|
+
"test:alpha": "npm run typecheck && npm run build && npm run test:lessc && node test/jess-alpha-fast-path.mjs && node test/alpha-support.mjs && node test/alpha-fixtures.mjs",
|
|
56
|
+
"test:lessc": "node test/lessc-alpha.mjs",
|
|
57
|
+
"test": "npm run test:alpha",
|
|
58
|
+
"test:module": "node test/test-es6.js && node test/test-cjs.cjs",
|
|
59
|
+
"test:legacy-node": "node test/index.js",
|
|
60
|
+
"test:node": "npm run test:module",
|
|
61
|
+
"test:coverage": "c8 -r lcov -r json-summary -r text-summary -r html --include=\"lib/**/*.js\" --include=\"bin/**/*.js\" --exclude=\"dist/**\" --exclude=\"**/*.test.js\" --exclude=\"**/*.spec.js\" --exclude=\"test/**\" --exclude=\"tmp/**\" --exclude=\"**/abstract-file-manager.js\" --exclude=\"**/abstract-plugin-loader.js\" npm run test:legacy-node && node scripts/coverage-report.js && node scripts/coverage-lines.js",
|
|
64
62
|
"lint": "eslint '**/*.{ts,js}'",
|
|
65
63
|
"lint:fix": "eslint '**/*.{ts,js}' --fix",
|
|
66
64
|
"typecheck": "tsc --noEmit",
|
|
67
65
|
"build": "node build/rollup.js --dist",
|
|
68
|
-
"
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
"errno": "^0.1.1",
|
|
72
|
-
"graceful-fs": "^4.1.2",
|
|
73
|
-
"probe-image-size": "^7.2.3",
|
|
74
|
-
"make-dir": "^5.1.0",
|
|
75
|
-
"mime": "^1.4.1",
|
|
76
|
-
"needle": "^3.1.0",
|
|
77
|
-
"source-map": "~0.6.0"
|
|
66
|
+
"benchmark": "node benchmark/benchmark-runner.cjs",
|
|
67
|
+
"benchmark:all": "node benchmark/run-and-compare.mjs",
|
|
68
|
+
"prepublishOnly": "npm run typecheck && npm run build && npm run test:lessc"
|
|
78
69
|
},
|
|
79
70
|
"devDependencies": {
|
|
80
71
|
"@less/test-data": "workspace:*",
|
|
@@ -94,19 +85,10 @@
|
|
|
94
85
|
"cross-env": "^7.0.3",
|
|
95
86
|
"eslint": "^7.29.0",
|
|
96
87
|
"fs-extra": "^8.1.0",
|
|
97
|
-
"git-rev": "^0.2.1",
|
|
98
88
|
"glob": "~11.0.3",
|
|
99
89
|
"globby": "^10.0.1",
|
|
100
|
-
"grunt": "^1.5.0",
|
|
101
|
-
"grunt-cli": "^1.3.2",
|
|
102
|
-
"grunt-contrib-clean": "^1.0.0",
|
|
103
|
-
"grunt-contrib-connect": "^1.0.2",
|
|
104
|
-
"grunt-eslint": "^23.0.0",
|
|
105
|
-
"grunt-saucelabs": "^9.0.1",
|
|
106
|
-
"grunt-shell": "^1.3.0",
|
|
107
90
|
"html-template-tag": "^3.2.0",
|
|
108
91
|
"jest-diff": "~30.1.2",
|
|
109
|
-
"jit-grunt": "^0.10.0",
|
|
110
92
|
"less-plugin-autoprefix": "^1.5.1",
|
|
111
93
|
"less-plugin-clean-css": "^1.6.0",
|
|
112
94
|
"minimist": "^1.2.0",
|
|
@@ -114,15 +96,14 @@
|
|
|
114
96
|
"mocha-teamcity-reporter": "^3.0.0",
|
|
115
97
|
"npm-run-all": "^4.1.5",
|
|
116
98
|
"performance-now": "^0.2.0",
|
|
117
|
-
"phin": "^2.2.3",
|
|
118
99
|
"playwright": "1.50.1",
|
|
119
100
|
"promise": "^7.1.1",
|
|
120
101
|
"read-glob": "^3.0.0",
|
|
121
102
|
"resolve": "^1.17.0",
|
|
122
103
|
"rollup": "^2.52.2",
|
|
123
104
|
"rollup-plugin-terser": "^5.1.1",
|
|
105
|
+
"semver": "^6.3.0",
|
|
124
106
|
"shx": "^0.3.2",
|
|
125
|
-
"time-grunt": "^1.3.0",
|
|
126
107
|
"typescript": "^5.7.0",
|
|
127
108
|
"uikit": "2.27.4",
|
|
128
109
|
"url": "^0.11.4",
|
|
@@ -158,8 +139,21 @@
|
|
|
158
139
|
"rawcurrent": "https://raw.github.com/less/less.js/v",
|
|
159
140
|
"sourcearchive": "https://github.com/less/less.js/archive/v",
|
|
160
141
|
"dependencies": {
|
|
161
|
-
"
|
|
162
|
-
"
|
|
142
|
+
"@jesscss/compiler": "2.0.0-alpha.11",
|
|
143
|
+
"@jesscss/core": "2.0.0-alpha.11",
|
|
144
|
+
"@jesscss/plugin-less": "2.0.0-alpha.11",
|
|
145
|
+
"@jesscss/plugin-less-compat": "2.0.0-alpha.11",
|
|
146
|
+
"@jesscss/plugin-node-modules": "2.0.0-alpha.11",
|
|
147
|
+
"parse-node-version": "^1.0.1",
|
|
148
|
+
"parseman": "^0.41.0"
|
|
149
|
+
},
|
|
150
|
+
"peerDependencies": {
|
|
151
|
+
"@jesscss/plugin-js": "2.0.0-alpha.11"
|
|
152
|
+
},
|
|
153
|
+
"peerDependenciesMeta": {
|
|
154
|
+
"@jesscss/plugin-js": {
|
|
155
|
+
"optional": true
|
|
156
|
+
}
|
|
163
157
|
},
|
|
164
158
|
"gitHead": "1df9072ee9ebdadc791bf35dfb1dbc3ef9f1948f"
|
|
165
159
|
}
|