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.
Files changed (131) hide show
  1. package/README.md +19 -5
  2. package/bin/lessc +190 -630
  3. package/dist/less-node.cjs +399 -14570
  4. package/index.cjs +5 -2
  5. package/lib/index.js +164 -0
  6. package/lib/lessc-helper.js +52 -0
  7. package/lib/logger.js +76 -0
  8. package/lib/options.d.ts +46 -0
  9. package/lib/options.js +145 -0
  10. package/lib/types.js +20 -0
  11. package/lib/version.js +19 -0
  12. package/package.json +34 -40
  13. package/dist/less.cjs +0 -15215
  14. package/dist/less.js +0 -15215
  15. package/dist/less.min.js +0 -11
  16. package/dist/less.min.js.map +0 -1
  17. package/lib/less/constants.js +0 -13
  18. package/lib/less/contexts.js +0 -165
  19. package/lib/less/data/colors.js +0 -150
  20. package/lib/less/data/index.js +0 -4
  21. package/lib/less/data/unit-conversions.js +0 -21
  22. package/lib/less/default-options.js +0 -89
  23. package/lib/less/deprecation.js +0 -82
  24. package/lib/less/environment/abstract-file-manager.js +0 -140
  25. package/lib/less/environment/abstract-plugin-loader.js +0 -185
  26. package/lib/less/environment/environment-api.ts +0 -21
  27. package/lib/less/environment/environment.js +0 -59
  28. package/lib/less/environment/file-manager-api.ts +0 -77
  29. package/lib/less/functions/boolean.js +0 -29
  30. package/lib/less/functions/color-blending.js +0 -85
  31. package/lib/less/functions/color.js +0 -452
  32. package/lib/less/functions/data-uri.js +0 -74
  33. package/lib/less/functions/default.js +0 -26
  34. package/lib/less/functions/function-caller.js +0 -55
  35. package/lib/less/functions/function-registry.js +0 -36
  36. package/lib/less/functions/index.js +0 -35
  37. package/lib/less/functions/list.js +0 -158
  38. package/lib/less/functions/math-helper.js +0 -22
  39. package/lib/less/functions/math.js +0 -30
  40. package/lib/less/functions/number.js +0 -95
  41. package/lib/less/functions/string.js +0 -39
  42. package/lib/less/functions/style.js +0 -29
  43. package/lib/less/functions/svg.js +0 -87
  44. package/lib/less/functions/types.js +0 -70
  45. package/lib/less/import-manager.js +0 -183
  46. package/lib/less/index.js +0 -95
  47. package/lib/less/less-error.js +0 -166
  48. package/lib/less/logger.js +0 -34
  49. package/lib/less/parse-tree.js +0 -124
  50. package/lib/less/parse.js +0 -87
  51. package/lib/less/parser/lookup-pattern.js +0 -26
  52. package/lib/less/parser/parser-input.js +0 -400
  53. package/lib/less/parser/parser.js +0 -2998
  54. package/lib/less/plugin-manager.js +0 -168
  55. package/lib/less/render.js +0 -41
  56. package/lib/less/source-map-builder.js +0 -82
  57. package/lib/less/source-map-output.js +0 -151
  58. package/lib/less/transform-tree.js +0 -102
  59. package/lib/less/tree/anonymous.js +0 -61
  60. package/lib/less/tree/assignment.js +0 -48
  61. package/lib/less/tree/atrule-syntax.js +0 -8
  62. package/lib/less/tree/atrule.js +0 -340
  63. package/lib/less/tree/attribute.js +0 -63
  64. package/lib/less/tree/call.js +0 -132
  65. package/lib/less/tree/color.js +0 -285
  66. package/lib/less/tree/combinator.js +0 -38
  67. package/lib/less/tree/comment.js +0 -48
  68. package/lib/less/tree/condition.js +0 -65
  69. package/lib/less/tree/container.js +0 -104
  70. package/lib/less/tree/debug-info.js +0 -80
  71. package/lib/less/tree/declaration.js +0 -139
  72. package/lib/less/tree/detached-ruleset.js +0 -45
  73. package/lib/less/tree/dimension.js +0 -215
  74. package/lib/less/tree/element.js +0 -93
  75. package/lib/less/tree/expression.js +0 -100
  76. package/lib/less/tree/extend.js +0 -88
  77. package/lib/less/tree/import.js +0 -299
  78. package/lib/less/tree/index.js +0 -56
  79. package/lib/less/tree/interpolated-variable.js +0 -106
  80. package/lib/less/tree/javascript.js +0 -45
  81. package/lib/less/tree/js-eval-node.js +0 -80
  82. package/lib/less/tree/keyword.js +0 -28
  83. package/lib/less/tree/media.js +0 -90
  84. package/lib/less/tree/merge-rules.js +0 -47
  85. package/lib/less/tree/mixin-call.js +0 -283
  86. package/lib/less/tree/mixin-definition.js +0 -319
  87. package/lib/less/tree/namespace-value.js +0 -95
  88. package/lib/less/tree/negative.js +0 -37
  89. package/lib/less/tree/nested-at-rule.js +0 -239
  90. package/lib/less/tree/node.js +0 -310
  91. package/lib/less/tree/operation.js +0 -81
  92. package/lib/less/tree/paren.js +0 -41
  93. package/lib/less/tree/property.js +0 -96
  94. package/lib/less/tree/query-in-parens.js +0 -64
  95. package/lib/less/tree/quoted.js +0 -131
  96. package/lib/less/tree/ruleset.js +0 -1068
  97. package/lib/less/tree/selector.js +0 -201
  98. package/lib/less/tree/unicode-descriptor.js +0 -14
  99. package/lib/less/tree/unit.js +0 -170
  100. package/lib/less/tree/url.js +0 -83
  101. package/lib/less/tree/value.js +0 -60
  102. package/lib/less/tree/variable-call.js +0 -60
  103. package/lib/less/tree/variable.js +0 -85
  104. package/lib/less/utils.js +0 -126
  105. package/lib/less/visitors/extend-visitor.js +0 -505
  106. package/lib/less/visitors/import-sequencer.js +0 -56
  107. package/lib/less/visitors/import-visitor.js +0 -203
  108. package/lib/less/visitors/index.js +0 -15
  109. package/lib/less/visitors/join-selector-visitor.js +0 -65
  110. package/lib/less/visitors/set-tree-visibility-visitor.js +0 -57
  111. package/lib/less/visitors/to-css-visitor.js +0 -332
  112. package/lib/less/visitors/visitor.js +0 -165
  113. package/lib/less-browser/add-default-options.js +0 -53
  114. package/lib/less-browser/bootstrap.js +0 -67
  115. package/lib/less-browser/browser.js +0 -65
  116. package/lib/less-browser/cache.js +0 -43
  117. package/lib/less-browser/error-reporting.js +0 -170
  118. package/lib/less-browser/file-manager.js +0 -112
  119. package/lib/less-browser/image-size.js +0 -28
  120. package/lib/less-browser/index.js +0 -284
  121. package/lib/less-browser/log-listener.js +0 -42
  122. package/lib/less-browser/plugin-loader.js +0 -24
  123. package/lib/less-browser/utils.js +0 -30
  124. package/lib/less-node/environment.js +0 -43
  125. package/lib/less-node/file-manager.js +0 -156
  126. package/lib/less-node/fs.js +0 -14
  127. package/lib/less-node/image-size.js +0 -78
  128. package/lib/less-node/index.js +0 -31
  129. package/lib/less-node/lessc-helper.js +0 -95
  130. package/lib/less-node/plugin-loader.js +0 -62
  131. package/lib/less-node/url-file-manager.js +0 -60
package/bin/lessc CHANGED
@@ -1,678 +1,238 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- /* eslint indent: [2, 2, {"SwitchCase": 1}] */
3
+ /**
4
+ * Less compiler (Jess-powered) — compiles .less files to CSS.
5
+ */
4
6
 
5
7
  import path from 'path';
6
- import os from 'os';
7
- import { createRequire } from 'module';
8
- import fs from '../lib/less-node/fs.js';
9
- import * as utils from '../lib/less/utils.js';
10
- import * as Constants from '../lib/less/constants.js';
11
- import less from '../lib/less-node/index.js';
12
-
13
- const require = createRequire(import.meta.url);
14
-
15
- var errno;
8
+ import fs from 'fs';
9
+ import less from '../lib/index.js';
10
+ import { version as versionInfo } from '../lib/version.js';
11
+ import { outputDiagnostics } from '@jesscss/compiler/diagnostics';
12
+
13
+ const args = process.argv.slice(1);
14
+ let options = { paths: [], filename: '' };
15
+ let input = null;
16
+ let output = null;
17
+ let silent = false;
18
+ let quiet = false;
19
+ let verbose = false;
20
+
21
+ const unsupportedOptions = new Map([
22
+ ['--source-map', 'source maps are not supported'],
23
+ ['--source-map-map-inline', 'source maps are not supported'],
24
+ ['--source-map-include-source', 'source maps are not supported'],
25
+ ['--source-map-rootpath', 'source maps are not supported'],
26
+ ['--source-map-basepath', 'source maps are not supported'],
27
+ ['--source-map-url', 'source maps are not supported'],
28
+ ['--plugin', 'legacy lessc plugin flags are not supported'],
29
+ ['--depends', 'dependency-only output is not supported'],
30
+ ['--lint', 'lint-only mode is not supported'],
31
+ ['--compress', 'compressed output is not supported'],
32
+ ['-x', 'compressed output is not supported'],
33
+ ['--clean-css', 'clean-css compression is not supported'],
34
+ ['--rewrite-urls', 'URL rewriting is not supported'],
35
+ ['--rootpath', 'URL rootpath rewriting is not supported'],
36
+ ['--url-args', 'URL argument rewriting is not supported'],
37
+ ['--global-var', 'global variable injection is not supported'],
38
+ ['--modify-var', 'modify-var injection is not supported'],
39
+ ['--js', 'JavaScript evaluation is not supported'],
40
+ ['--no-js', 'JavaScript evaluation flags are not supported'],
41
+ ['--strict-units', 'strict unit mode is not supported'],
42
+ ]);
43
+
44
+ function stripTerminalFormatting(value) {
45
+ return String(value)
46
+ .replace(/\x1B\]8;;[^\x1B]*(?:\x1B\\|\x07)/gu, '')
47
+ .replace(/\x1B\[[0-?]*[ -/]*[@-~]/gu, '');
48
+ }
16
49
 
17
- try {
18
- errno = require('errno');
19
- } catch (err) {
20
- errno = null;
50
+ function renderLogMessage(value) {
51
+ const message = String(value);
52
+ return options.color === false ? stripTerminalFormatting(message) : message;
21
53
  }
22
54
 
23
- var pluginManager = new less.PluginManager(less);
24
- var fileManager = new less.FileManager();
25
- var plugins = [];
26
- var queuePlugins = [];
27
- var args = process.argv.slice(1);
28
- var silent = false;
29
- var quiet = false;
30
- var verbose = false;
31
- var options = less.options;
32
- options.plugins = plugins;
33
- options.reUsePluginManager = true;
34
- var sourceMapOptions = {};
35
- var continueProcessing = true;
55
+ function captureJessDiagnostics(errors, warnings) {
56
+ const originalStdoutWrite = process.stdout.write;
57
+ const originalWrite = process.stderr.write;
58
+ let captured = '';
59
+ const captureDiagnosticWrite = function captureDiagnosticWrite(chunk, ...args) {
60
+ captured += String(chunk);
61
+ if (typeof args.at(-1) === 'function') {
62
+ args.at(-1)();
63
+ }
64
+ return true;
65
+ };
66
+ process.stdout.write = captureDiagnosticWrite;
67
+ process.stderr.write = captureDiagnosticWrite;
68
+ try {
69
+ outputDiagnostics(errors, warnings, {
70
+ suppressWarnings: quiet,
71
+ breakOnError: false,
72
+ verbose
73
+ });
74
+ } finally {
75
+ process.stdout.write = originalStdoutWrite;
76
+ process.stderr.write = originalWrite;
77
+ }
78
+ return options.color === false ? stripTerminalFormatting(captured) : captured;
79
+ }
36
80
 
37
- var checkArgFunc = function checkArgFunc(arg, option) {
38
- if (!option) {
39
- console.error(''.concat(arg, ' option requires a parameter'));
40
- continueProcessing = false;
41
- process.exitCode = 1;
81
+ function outputJessDiagnostics(errors, warnings = []) {
82
+ const relevantWarnings = quiet ? [] : warnings;
83
+ if ((!Array.isArray(errors) || errors.length === 0) && relevantWarnings.length === 0) {
42
84
  return false;
43
85
  }
44
-
86
+ process.stderr.write(captureJessDiagnostics(errors || [], relevantWarnings));
45
87
  return true;
46
- };
47
-
48
- var checkBooleanArg = function checkBooleanArg(arg) {
49
- var onOff = /^((on|t|true|y|yes)|(off|f|false|n|no))$/i.exec(arg);
88
+ }
50
89
 
51
- if (!onOff) {
52
- console.error(' unable to parse '.concat(arg, ' as a boolean. use one of on/t/true/y/yes/off/f/false/n/no'));
53
- continueProcessing = false;
54
- process.exitCode = 1;
90
+ function outputJessError(err) {
91
+ if (!Array.isArray(err?.jessErrors) || err.jessErrors.length === 0) {
55
92
  return false;
56
93
  }
94
+ outputJessDiagnostics(err.jessErrors, err.jessWarnings || []);
95
+ return true;
96
+ }
57
97
 
58
- return Boolean(onOff[2]);
59
- };
60
-
61
- var parseVariableOption = function parseVariableOption(option, variables) {
62
- var parts = option.split('=', 2);
63
- variables[parts[0]] = parts[1];
64
- };
98
+ function splitSearchPaths(value) {
99
+ return String(value || '')
100
+ .split(path.delimiter)
101
+ .filter(Boolean);
102
+ }
65
103
 
66
- var sourceMapFileInline = false;
67
- var pendingDeprecations = [];
104
+ function failUnsupportedOption(arg, reason) {
105
+ console.error(`lessc: ${arg} is not supported`);
106
+ if (reason) {
107
+ console.error(`lessc: ${reason}`);
108
+ }
109
+ console.error('lessc: run `lessc --help` for supported options.');
110
+ process.exit(1);
111
+ }
68
112
 
69
113
  function printUsage() {
70
114
  less.lesscHelper.printUsage();
71
-
72
- pluginManager.Loader.printUsage(plugins);
73
- continueProcessing = false;
115
+ process.exit(0);
74
116
  }
75
117
 
76
- function render() {
77
- if (!continueProcessing) {
78
- return;
79
- }
80
-
81
- var input = args[1];
82
-
83
- if (input && input != '-') {
84
- input = path.resolve(process.cwd(), input);
85
- }
86
-
87
- var output = args[2];
88
- var outputbase = args[2];
89
-
90
- if (output) {
91
- output = path.resolve(process.cwd(), output);
92
- }
93
-
94
- if (options.disablePluginRule && queuePlugins.length > 0) {
95
- console.error('--plugin and --disable-plugin-rule may not be used at the same time');
96
- process.exitCode = 1;
97
- return;
98
- }
99
-
100
- if (options.sourceMap) {
101
- // Validate conflicting options
102
- if (sourceMapOptions.sourceMapURL && sourceMapOptions.disableSourcemapAnnotation) {
103
- console.error('You cannot provide flag --source-map-url with --source-map-no-annotation.');
104
- console.error('Please remove one of those flags.');
105
- process.exitcode = 1;
106
- return;
118
+ function parseArgs() {
119
+ for (let i = 0; i < args.length; i++) {
120
+ const arg = args[i];
121
+ if (arg === '-h' || arg === '--help') {
122
+ printUsage();
107
123
  }
108
-
109
- // Handle explicit sourceMapFullFilename (from --source-map=filename)
110
- // Normalization of other options (sourceMapBasepath, sourceMapRootpath, etc.)
111
- // is handled automatically in parse-tree.js
112
- if (sourceMapOptions.sourceMapFullFilename && !sourceMapFileInline) {
113
- var mapFilename = path.resolve(process.cwd(), sourceMapOptions.sourceMapFullFilename);
114
- var mapDir = path.dirname(mapFilename);
115
-
116
- if (output) {
117
- var outputDir = path.dirname(output);
118
- // Set sourceMapOutputFilename relative to map directory
119
- sourceMapOptions.sourceMapOutputFilename = path.join(
120
- path.relative(mapDir, outputDir),
121
- path.basename(output)
122
- );
123
- // Set sourceMapFilename relative to output directory (for sourceMappingURL comment)
124
- sourceMapOptions.sourceMapFilename = path.join(
125
- path.relative(outputDir, mapDir),
126
- path.basename(sourceMapOptions.sourceMapFullFilename)
127
- );
128
- } else {
129
- // No output filename, just use basename
130
- sourceMapOptions.sourceMapOutputFilename = path.basename(output || 'output.css');
131
- sourceMapOptions.sourceMapFilename = path.basename(sourceMapOptions.sourceMapFullFilename);
132
- }
133
- } else if (!sourceMapOptions.sourceMapFullFilename && output && !sourceMapFileInline) {
134
- // No explicit sourcemap filename, derive from output
135
- sourceMapOptions.sourceMapOutputFilename = path.basename(output);
136
- sourceMapOptions.sourceMapFullFilename = ''.concat(output, '.map');
137
- } else if (!output && !sourceMapFileInline) {
138
- console.error('the sourcemap option only has an optional filename if the css filename is given');
139
- console.error('consider adding --source-map-map-inline which embeds the sourcemap into the css');
140
- process.exitCode = 1;
141
- return;
124
+ if (arg === '-v' || arg === '--version') {
125
+ console.log(`lessc ${versionInfo.semver} (Less Compiler) [Jess]`);
126
+ process.exit(0);
142
127
  }
143
- }
144
-
145
- if (!input) {
146
- console.error('lessc: no input files');
147
- console.error('');
148
- printUsage();
149
- process.exitCode = 1;
150
- return;
151
- }
152
-
153
- var mkdirp;
154
- var ensureDirectory = function ensureDirectory(filepath) {
155
- var dir = path.dirname(filepath);
156
- var cmd;
157
- var existsSync = fs.existsSync || path.existsSync;
158
-
159
- if (!existsSync(dir)) {
160
- if (mkdirp === undefined) {
161
- try {
162
- mkdirp = require('make-dir');
163
- } catch (e) {
164
- mkdirp = null;
165
- }
166
- }
167
-
168
- cmd = mkdirp && mkdirp.sync || fs.mkdirSync;
169
- cmd(dir);
128
+ if (arg === '-s' || arg === '--silent') {
129
+ silent = true;
130
+ continue;
170
131
  }
171
- };
172
-
173
- if (options.depends) {
174
- if (!outputbase) {
175
- console.error('option --depends requires an output path to be specified');
176
- process.exitCode = 1;
177
- return;
132
+ if (arg === '--quiet') {
133
+ quiet = true;
134
+ continue;
178
135
  }
179
-
180
- process.stdout.write(''.concat(outputbase, ': '));
181
- }
182
-
183
- if (!sourceMapFileInline) {
184
- var writeSourceMap = function writeSourceMap() {
185
- var output = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
186
- var onDone = arguments.length > 1 ? arguments[1] : undefined;
187
- var filename = sourceMapOptions.sourceMapFullFilename;
188
- ensureDirectory(filename);
189
-
190
- // To fix https://github.com/less/less.js/issues/3646
191
- output = output.toString();
192
-
193
- fs.writeFile(filename, output, 'utf8', function (err) {
194
- if (err) {
195
- var description = 'Error: ';
196
-
197
- if (errno && errno.errno[err.errno]) {
198
- description += errno.errno[err.errno].description;
199
- } else {
200
- description += ''.concat(err.code, ' ').concat(err.message);
201
- }
202
-
203
- console.error('lessc: failed to create file '.concat(filename));
204
- console.error(description);
205
- process.exitCode = 1;
206
- } else {
207
- less.logger.info('lessc: wrote '.concat(filename));
208
- }
209
-
210
- onDone();
211
- });
212
- };
213
- }
214
-
215
- var writeSourceMapIfNeeded = function writeSourceMapIfNeeded(output, onDone) {
216
- if (options.sourceMap && !sourceMapFileInline) {
217
- writeSourceMap(output, onDone);
218
- } else {
219
- onDone();
136
+ if (arg === '--verbose') {
137
+ verbose = true;
138
+ continue;
220
139
  }
221
- };
222
-
223
- var writeOutput = function writeOutput(output, result, onSuccess) {
224
- if (options.depends) {
225
- onSuccess();
226
- } else if (output) {
227
- ensureDirectory(output);
228
-
229
- fs.writeFile(output, result.css, {
230
- encoding: 'utf8'
231
- }, function (err) {
232
- if (err) {
233
- var description = 'Error: ';
234
-
235
- if (errno && errno.errno[err.errno]) {
236
- description += errno.errno[err.errno].description;
237
- } else {
238
- description += ''.concat(err.code, ' ').concat(err.message);
239
- }
240
-
241
- console.error('lessc: failed to create file '.concat(output));
242
- console.error(description);
243
- process.exitCode = 1;
244
- } else {
245
- less.logger.info('lessc: wrote '.concat(output));
246
-
247
- onSuccess();
248
- }
249
- });
250
- } else if (!options.depends) {
251
- process.stdout.write(result.css);
252
- onSuccess();
140
+ if (arg === '--collapse-nesting') {
141
+ options.collapseNesting = true;
142
+ continue;
253
143
  }
254
- };
255
-
256
- var logDependencies = function logDependencies(options, result) {
257
- if (options.depends) {
258
- var depends = '';
259
-
260
- for (var i = 0; i < result.imports.length; i++) {
261
- depends += ''.concat(result.imports[i], ' ');
262
- }
263
-
264
- console.log(depends);
144
+ const optionName = arg.includes('=') ? arg.slice(0, arg.indexOf('=')) : arg;
145
+ if (unsupportedOptions.has(optionName)) {
146
+ failUnsupportedOption(optionName, unsupportedOptions.get(optionName));
265
147
  }
266
- };
267
-
268
- var parseLessFile = function parseLessFile(e, data) {
269
- if (e) {
270
- console.error('lessc: '.concat(e.message));
271
- process.exitCode = 1;
272
- return;
148
+ if (arg === '-I' || arg === '--include-path') {
149
+ const match = arg.match(/^-I(.+)$/);
150
+ const paths = splitSearchPaths(match ? match[1] : args[++i]);
151
+ options.paths.push(...paths);
152
+ continue;
273
153
  }
274
-
275
- data = data.replace(/^\uFEFF/, '');
276
- options.paths = [path.dirname(input)].concat(options.paths);
277
- options.filename = input;
278
-
279
- if (options.lint) {
280
- options.sourceMap = false;
154
+ if (arg.startsWith('-I')) {
155
+ options.paths.push(...splitSearchPaths(arg.slice(2)));
156
+ continue;
281
157
  }
282
-
283
- sourceMapOptions.sourceMapFileInline = sourceMapFileInline;
284
-
285
- if (options.sourceMap) {
286
- options.sourceMap = sourceMapOptions;
158
+ const includeMatch = arg.match(/^--include-path=(.+)$/);
159
+ if (includeMatch) {
160
+ options.paths.push(...splitSearchPaths(includeMatch[1]));
161
+ continue;
287
162
  }
288
-
289
- less.logger.addListener({
290
- info: function info(msg) {
291
- if (verbose) {
292
- console.log(msg);
293
- }
294
- },
295
- warn: function warn(msg) {
296
- // do not show warning if the silent option is used
297
- if (!silent && !quiet) {
298
- console.warn(msg);
299
- }
300
- },
301
- error: function error(msg) {
302
- if (!silent) {
303
- console.error(msg);
304
- }
305
- }
306
- });
307
-
308
- less.render(data, options).then(function (result) {
309
- if (!options.lint) {
310
- writeOutput(output, result, function () {
311
- writeSourceMapIfNeeded(result.map, function () {
312
- logDependencies(options, result);
313
- });
314
- });
315
- }
316
- }, function (err) {
317
- if (!options.silent) {
318
- console.error(err.toString({
319
- stylize: options.color && less.lesscHelper.stylize
320
- }));
163
+ if (arg === '--no-color') {
164
+ options.color = false;
165
+ continue;
166
+ }
167
+ if (arg === '-' || arg.endsWith('.less') || arg.endsWith('.css')) {
168
+ if (input === null) {
169
+ input = arg === '-' ? '-' : path.resolve(process.cwd(), arg);
170
+ } else if (output === null) {
171
+ output = path.resolve(process.cwd(), arg);
321
172
  }
322
-
323
- process.exitCode = 1;
324
- });
325
- };
326
-
327
- if (input != '-') {
328
- fs.readFile(input, 'utf8', parseLessFile);
329
- } else {
330
- process.stdin.resume();
331
- process.stdin.setEncoding('utf8');
332
- var buffer = '';
333
- process.stdin.on('data', function (data) {
334
- buffer += data;
335
- });
336
- process.stdin.on('end', function () {
337
- parseLessFile(false, buffer);
338
- });
173
+ continue;
174
+ }
175
+ if (arg.startsWith('-')) {
176
+ failUnsupportedOption(arg, 'unknown flags are not supported');
177
+ }
339
178
  }
340
179
  }
341
180
 
342
- function processPluginQueue() {
343
- var x = 0;
181
+ async function run() {
182
+ parseArgs();
344
183
 
345
- function pluginError(name) {
346
- console.error('Unable to load plugin '.concat(name, ' please make sure that it is installed under or at the same level as less'));
347
- process.exitCode = 1;
348
- }
349
-
350
- function pluginFinished(plugin) {
351
- x++;
352
- plugins.push(plugin);
353
-
354
- if (x === queuePlugins.length) {
355
- render();
356
- }
184
+ if (!input) {
185
+ console.error('lessc: no input files');
186
+ console.error('');
187
+ printUsage();
357
188
  }
358
189
 
359
- queuePlugins.forEach(function (queue) {
360
- var context = utils.clone(options);
361
- pluginManager.Loader.loadPlugin(queue.name, process.cwd(), context, less.environment, fileManager).then(function (data) {
362
- pluginFinished({
363
- fileContent: data.contents,
364
- filename: data.filename,
365
- options: queue.options
366
- });
367
- }).catch(function () {
368
- pluginError(queue.name);
369
- });
190
+ less.logger.addListener({
191
+ info(msg) {
192
+ if (verbose) console.log(msg);
193
+ },
194
+ warn(msg) {
195
+ if (!silent && !quiet) console.warn(renderLogMessage(msg));
196
+ },
197
+ error(msg) {
198
+ if (!silent) console.error(renderLogMessage(msg));
199
+ },
370
200
  });
371
- } // self executing function so we can return
372
201
 
373
-
374
- (function () {
375
- args = args.filter(function (arg) {
376
- var match;
377
- match = arg.match(/^-I(.+)$/);
378
-
379
- if (match) {
380
- options.paths.push(match[1]);
381
- return false;
202
+ try {
203
+ let result;
204
+ if (input === '-') {
205
+ const data = await new Promise((resolve, reject) => {
206
+ let buf = '';
207
+ process.stdin.setEncoding('utf8');
208
+ process.stdin.on('data', chunk => { buf += chunk; });
209
+ process.stdin.on('end', () => resolve(buf));
210
+ process.stdin.on('error', reject);
211
+ });
212
+ result = await less.render(data, { ...options, filename: 'input.less' });
213
+ } else {
214
+ options.filename = input;
215
+ options.paths = [path.dirname(input), ...options.paths];
216
+ result = await less.renderFile(input, options);
382
217
  }
383
218
 
384
- match = arg.match(/^--?([a-z][0-9a-z-]*)(?:=(.*))?$/i);
385
-
386
- if (match) {
387
- arg = match[1];
219
+ if (output) {
220
+ fs.mkdirSync(path.dirname(output), { recursive: true });
221
+ fs.writeFileSync(output, result.css, 'utf8');
222
+ if (!silent) outputJessDiagnostics([], result.warnings || []);
223
+ if (!silent) console.log(`lessc: wrote ${output}`);
388
224
  } else {
389
- return arg;
225
+ if (!silent) outputJessDiagnostics([], result.warnings || []);
226
+ process.stdout.write(result.css);
390
227
  }
391
-
392
- switch (arg) {
393
- case 'v':
394
- case 'version':
395
- console.log('lessc '.concat(less.version.join('.'), ' (Less Compiler) [JavaScript]'));
396
- continueProcessing = false;
397
- break;
398
-
399
- case 'verbose':
400
- options.verbose = verbose = true;
401
- break;
402
-
403
- case 's':
404
- case 'silent':
405
- options.silent = silent = true;
406
- break;
407
-
408
- case 'quiet':
409
- options.quiet = quiet = true;
410
- break;
411
-
412
- case 'quiet-deprecations':
413
- options.quietDeprecations = true;
414
- break;
415
-
416
- case 'l':
417
- case 'lint':
418
- options.lint = true;
419
- break;
420
-
421
- case 'strict-imports':
422
- options.strictImports = true;
423
- break;
424
-
425
- case 'h':
426
- case 'help':
427
- printUsage();
428
- break;
429
-
430
- case 'x':
431
- case 'compress':
432
- options.compress = true;
433
- break;
434
-
435
- case 'insecure':
436
- options.insecure = true;
437
- break;
438
-
439
- case 'M':
440
- case 'depends':
441
- options.depends = true;
442
- break;
443
-
444
- case 'max-line-len':
445
- if (checkArgFunc(arg, match[2])) {
446
- options.maxLineLen = parseInt(match[2], 10);
447
-
448
- if (options.maxLineLen <= 0) {
449
- options.maxLineLen = -1;
450
- }
451
- }
452
-
453
- break;
454
-
455
- case 'no-color':
456
- options.color = false;
457
- break;
458
-
459
- case 'js':
460
- options.javascriptEnabled = true;
461
- pendingDeprecations.push('Warning: Inline JavaScript (--js) is deprecated and will be removed in Less 5.x. Use Less functions or custom plugins instead. (js-eval)');
462
- break;
463
-
464
- case 'no-js':
465
- // eslint-disable-next-line max-len
466
- console.error('The "--no-js" argument is deprecated, as inline JavaScript is disabled by default. Use "--js" to enable inline JavaScript (not recommended).');
467
- break;
468
-
469
- case 'include-path':
470
- if (checkArgFunc(arg, match[2])) {
471
- // ; supported on windows.
472
- // : supported on windows and linux, excluding a drive letter like C:\ so C:\file:D:\file parses to 2
473
- options.paths = match[2].split(os.type().match(/Windows/) ? /:(?!\\)|;/ : ':').map(function (p) {
474
- if (p) {
475
- return path.resolve(process.cwd(), p);
476
- }
477
- });
478
- }
479
-
480
- break;
481
-
482
- case 'line-numbers':
483
- if (checkArgFunc(arg, match[2])) {
484
- options.dumpLineNumbers = match[2];
485
- pendingDeprecations.push('Warning: The --line-numbers option is deprecated and will be removed in Less 5.x. Use source maps instead (--source-map). (dump-line-numbers)');
486
- }
487
-
488
- break;
489
-
490
- case 'source-map':
491
- options.sourceMap = true;
492
-
493
- if (match[2]) {
494
- sourceMapOptions.sourceMapFullFilename = match[2];
495
- }
496
-
497
- break;
498
-
499
- case 'source-map-rootpath':
500
- if (checkArgFunc(arg, match[2])) {
501
- sourceMapOptions.sourceMapRootpath = match[2];
502
- }
503
-
504
- break;
505
-
506
- case 'source-map-basepath':
507
- if (checkArgFunc(arg, match[2])) {
508
- sourceMapOptions.sourceMapBasepath = match[2];
509
- }
510
-
511
- break;
512
-
513
- case 'source-map-inline':
514
- case 'source-map-map-inline':
515
- sourceMapFileInline = true;
516
- options.sourceMap = true;
517
- break;
518
-
519
- case 'source-map-include-source':
520
- case 'source-map-less-inline':
521
- sourceMapOptions.outputSourceFiles = true;
522
- break;
523
-
524
- case 'source-map-url':
525
- if (checkArgFunc(arg, match[2])) {
526
- sourceMapOptions.sourceMapURL = match[2];
527
- }
528
-
529
- break;
530
-
531
- case 'source-map-no-annotation':
532
- sourceMapOptions.disableSourcemapAnnotation = true;
533
- break;
534
-
535
- case 'rp':
536
- case 'rootpath':
537
- if (checkArgFunc(arg, match[2])) {
538
- options.rootpath = match[2].replace(/\\/g, '/');
539
- }
540
-
541
- break;
542
-
543
- case 'ie-compat':
544
- pendingDeprecations.push('Warning: The --ie-compat option is deprecated, as it has no effect on compilation.');
545
- break;
546
-
547
- case 'relative-urls':
548
- pendingDeprecations.push('Warning: The --relative-urls option has been deprecated. Use --rewrite-urls=all.');
549
- options.rewriteUrls = Constants.RewriteUrls.ALL;
550
- break;
551
-
552
- case 'ru':
553
- case 'rewrite-urls':
554
- var m = match[2];
555
-
556
- if (m) {
557
- if (m === 'local') {
558
- options.rewriteUrls = Constants.RewriteUrls.LOCAL;
559
- } else if (m === 'off') {
560
- options.rewriteUrls = Constants.RewriteUrls.OFF;
561
- } else if (m === 'all') {
562
- options.rewriteUrls = Constants.RewriteUrls.ALL;
563
- } else {
564
- console.error('Unknown rewrite-urls argument '.concat(m));
565
- continueProcessing = false;
566
- process.exitCode = 1;
567
- }
568
- } else {
569
- options.rewriteUrls = Constants.RewriteUrls.ALL;
570
- }
571
-
572
- break;
573
-
574
- case 'sm':
575
- case 'strict-math':
576
- pendingDeprecations.push('Warning: The --strict-math option has been deprecated. Use --math=strict.');
577
-
578
- if (checkArgFunc(arg, match[2])) {
579
- if (checkBooleanArg(match[2])) {
580
- options.math = Constants.Math.PARENS;
581
- }
582
- }
583
-
584
- break;
585
-
586
- case 'm':
587
- case 'math': {
588
- let m = match[2];
589
- if (checkArgFunc(arg, m)) {
590
- if (m === 'always') {
591
- pendingDeprecations.push('Warning: --math=always is deprecated and will be removed in Less 5.x. Use --math=parens-division (default) or --math=parens. (math-always)');
592
- options.math = Constants.Math.ALWAYS;
593
- } else if (m === 'parens-division') {
594
- options.math = Constants.Math.PARENS_DIVISION;
595
- } else if (m === 'parens' || m === 'strict') {
596
- options.math = Constants.Math.PARENS;
597
- } else if (m === 'strict-legacy') {
598
- pendingDeprecations.push('Warning: --math=strict-legacy has been removed. Defaulting to --math=strict.');
599
- options.math = Constants.Math.PARENS;
600
- }
601
- }
602
-
603
- break;
228
+ } catch (err) {
229
+ if (!silent) {
230
+ if (!outputJessError(err)) {
231
+ console.error(renderLogMessage(err.toString?.() || err.message));
604
232
  }
605
- case 'su':
606
- case 'strict-units':
607
- if (checkArgFunc(arg, match[2])) {
608
- options.strictUnits = checkBooleanArg(match[2]);
609
- }
610
-
611
- break;
612
-
613
- case 'global-var':
614
- if (checkArgFunc(arg, match[2])) {
615
- if (!options.globalVars) {
616
- options.globalVars = {};
617
- }
618
-
619
- parseVariableOption(match[2], options.globalVars);
620
- }
621
-
622
- break;
623
-
624
- case 'modify-var':
625
- if (checkArgFunc(arg, match[2])) {
626
- if (!options.modifyVars) {
627
- options.modifyVars = {};
628
- }
629
-
630
- parseVariableOption(match[2], options.modifyVars);
631
- }
632
-
633
- break;
634
-
635
- case 'url-args':
636
- if (checkArgFunc(arg, match[2])) {
637
- options.urlArgs = match[2];
638
- }
639
-
640
- break;
641
-
642
- case 'plugin':
643
- var splitupArg = match[2].match(/^([^=]+)(=(.*))?/);
644
- var name = splitupArg[1];
645
- var pluginOptions = splitupArg[3];
646
- queuePlugins.push({
647
- name: name,
648
- options: pluginOptions
649
- });
650
- break;
651
-
652
- case 'disable-plugin-rule':
653
- options.disablePluginRule = true;
654
- break;
655
-
656
- default:
657
- queuePlugins.push({
658
- name: arg,
659
- options: match[2],
660
- default: true
661
- });
662
- break;
663
233
  }
664
- });
665
-
666
- // Flush queued deprecation warnings (respects --silent, --quiet, --quiet-deprecations)
667
- if (!silent && !quiet && !options.quietDeprecations) {
668
- pendingDeprecations.forEach(function (msg) {
669
- console.warn(msg);
670
- });
234
+ process.exitCode = 1;
671
235
  }
236
+ }
672
237
 
673
- if (queuePlugins.length > 0) {
674
- processPluginQueue();
675
- } else {
676
- render();
677
- }
678
- })();
238
+ run();