less 4.8.1 → 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 (129) hide show
  1. package/README.md +19 -5
  2. package/bin/lessc +190 -630
  3. package/dist/less-node.cjs +398 -14282
  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 +33 -40
  13. package/dist/less.cjs +0 -14929
  14. package/dist/less.js +0 -14929
  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 -36
  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/parser-input.js +0 -400
  52. package/lib/less/parser/parser.js +0 -2894
  53. package/lib/less/plugin-manager.js +0 -168
  54. package/lib/less/render.js +0 -41
  55. package/lib/less/source-map-builder.js +0 -82
  56. package/lib/less/source-map-output.js +0 -151
  57. package/lib/less/transform-tree.js +0 -102
  58. package/lib/less/tree/anonymous.js +0 -57
  59. package/lib/less/tree/assignment.js +0 -48
  60. package/lib/less/tree/atrule-syntax.js +0 -8
  61. package/lib/less/tree/atrule.js +0 -340
  62. package/lib/less/tree/attribute.js +0 -63
  63. package/lib/less/tree/call.js +0 -132
  64. package/lib/less/tree/color.js +0 -285
  65. package/lib/less/tree/combinator.js +0 -38
  66. package/lib/less/tree/comment.js +0 -48
  67. package/lib/less/tree/condition.js +0 -65
  68. package/lib/less/tree/container.js +0 -104
  69. package/lib/less/tree/debug-info.js +0 -80
  70. package/lib/less/tree/declaration.js +0 -139
  71. package/lib/less/tree/detached-ruleset.js +0 -45
  72. package/lib/less/tree/dimension.js +0 -215
  73. package/lib/less/tree/element.js +0 -93
  74. package/lib/less/tree/expression.js +0 -100
  75. package/lib/less/tree/extend.js +0 -88
  76. package/lib/less/tree/import.js +0 -299
  77. package/lib/less/tree/index.js +0 -56
  78. package/lib/less/tree/javascript.js +0 -45
  79. package/lib/less/tree/js-eval-node.js +0 -74
  80. package/lib/less/tree/keyword.js +0 -28
  81. package/lib/less/tree/media.js +0 -90
  82. package/lib/less/tree/merge-rules.js +0 -47
  83. package/lib/less/tree/mixin-call.js +0 -283
  84. package/lib/less/tree/mixin-definition.js +0 -319
  85. package/lib/less/tree/namespace-value.js +0 -95
  86. package/lib/less/tree/negative.js +0 -37
  87. package/lib/less/tree/nested-at-rule.js +0 -198
  88. package/lib/less/tree/node.js +0 -310
  89. package/lib/less/tree/operation.js +0 -81
  90. package/lib/less/tree/paren.js +0 -41
  91. package/lib/less/tree/property.js +0 -96
  92. package/lib/less/tree/query-in-parens.js +0 -64
  93. package/lib/less/tree/quoted.js +0 -114
  94. package/lib/less/tree/ruleset.js +0 -1066
  95. package/lib/less/tree/selector.js +0 -201
  96. package/lib/less/tree/unicode-descriptor.js +0 -14
  97. package/lib/less/tree/unit.js +0 -170
  98. package/lib/less/tree/url.js +0 -83
  99. package/lib/less/tree/value.js +0 -60
  100. package/lib/less/tree/variable-call.js +0 -60
  101. package/lib/less/tree/variable.js +0 -85
  102. package/lib/less/utils.js +0 -126
  103. package/lib/less/visitors/extend-visitor.js +0 -505
  104. package/lib/less/visitors/import-sequencer.js +0 -56
  105. package/lib/less/visitors/import-visitor.js +0 -203
  106. package/lib/less/visitors/index.js +0 -15
  107. package/lib/less/visitors/join-selector-visitor.js +0 -65
  108. package/lib/less/visitors/set-tree-visibility-visitor.js +0 -57
  109. package/lib/less/visitors/to-css-visitor.js +0 -332
  110. package/lib/less/visitors/visitor.js +0 -165
  111. package/lib/less-browser/add-default-options.js +0 -53
  112. package/lib/less-browser/bootstrap.js +0 -67
  113. package/lib/less-browser/browser.js +0 -65
  114. package/lib/less-browser/cache.js +0 -43
  115. package/lib/less-browser/error-reporting.js +0 -170
  116. package/lib/less-browser/file-manager.js +0 -112
  117. package/lib/less-browser/image-size.js +0 -28
  118. package/lib/less-browser/index.js +0 -284
  119. package/lib/less-browser/log-listener.js +0 -42
  120. package/lib/less-browser/plugin-loader.js +0 -24
  121. package/lib/less-browser/utils.js +0 -30
  122. package/lib/less-node/environment.js +0 -43
  123. package/lib/less-node/file-manager.js +0 -156
  124. package/lib/less-node/fs.js +0 -14
  125. package/lib/less-node/image-size.js +0 -78
  126. package/lib/less-node/index.js +0 -31
  127. package/lib/less-node/lessc-helper.js +0 -95
  128. package/lib/less-node/plugin-loader.js +0 -62
  129. 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();