UNPKG

20 kBTypeScriptView Raw
1import {Logger} from '../logger';
2import {LegacyImporter} from './importer';
3import {LegacyFunction} from './function';
4
5/**
6 * Options for [[render]] and [[renderSync]] that are shared between
7 * [[LegacyFileOptions]] and [[LegacyStringOptions]].
8 *
9 * @typeParam sync - This lets the TypeScript checker verify that
10 * [[LegacyAsyncImporter]]s and [[LegacyAsyncFunction]]s aren't passed to
11 * [[renderSync]].
12 *
13 * @category Legacy
14 * @deprecated This only works with the legacy [[render]] and [[renderSync]]
15 * APIs. Use [[Options]] with [[compile]], [[compileString]], [[compileAsync]],
16 * and [[compileStringAsync]] instead.
17 */
18export interface LegacySharedOptions<sync extends 'sync' | 'async'> {
19 /**
20 * This array of strings option provides [load
21 * paths](https://sass-lang.com/documentation/at-rules/import#load-paths) for
22 * Sass to look for stylesheets. Earlier load paths will take precedence over
23 * later ones.
24 *
25 * ```js
26 * sass.renderSync({
27 * file: "style.scss",
28 * includePaths: ["node_modules/bootstrap/dist/css"]
29 * });
30 * ```
31 *
32 * Load paths are also loaded from the `SASS_PATH` environment variable, if
33 * it’s set. This variable should be a list of paths separated by `;` (on
34 * Windows) or `:` (on other operating systems). Load paths from the
35 * `includePaths` option take precedence over load paths from `SASS_PATH`.
36 *
37 * ```sh
38 * $ SASS_PATH=node_modules/bootstrap/dist/css sass style.scss style.css
39 * ```
40 *
41 * @category Input
42 * @compatibility feature: "SASS_PATH", dart: "1.15.0", node: "3.9.0"
43 *
44 * Earlier versions of Dart Sass and Node Sass didn’t support the `SASS_PATH`
45 * environment variable.
46 */
47 includePaths?: string[];
48
49 /**
50 * Whether the generated CSS should use spaces or tabs for indentation.
51 *
52 * ```js
53 * const result = sass.renderSync({
54 * file: "style.scss",
55 * indentType: "tab",
56 * indentWidth: 1
57 * });
58 *
59 * result.css.toString();
60 * // "h1 {\n\tfont-size: 40px;\n}\n"
61 * ```
62 *
63 * @defaultValue `'space'`
64 * @category Output
65 * @compatibility dart: true, node: "3.0.0"
66 */
67 indentType?: 'space' | 'tab';
68
69 /**
70 * How many spaces or tabs (depending on [[indentType]]) should be used per
71 * indentation level in the generated CSS. It must be between 0 and 10
72 * (inclusive).
73 *
74 * @defaultValue `2`
75 * @category Output
76 * @compatibility dart: true, node: "3.0.0"
77 */
78 indentWidth?: number;
79
80 /**
81 * Which character sequence to use at the end of each line in the generated
82 * CSS. It can have the following values:
83 *
84 * * `'lf'` uses U+000A LINE FEED.
85 * * `'lfcr'` uses U+000A LINE FEED followed by U+000D CARRIAGE RETURN.
86 * * `'cr'` uses U+000D CARRIAGE RETURN.
87 * * `'crlf'` uses U+000D CARRIAGE RETURN followed by U+000A LINE FEED.
88 *
89 * @defaultValue `'lf'`
90 * @category Output
91 * @compatibility dart: true, node: "3.0.0"
92 */
93 linefeed?: 'cr' | 'crlf' | 'lf' | 'lfcr';
94
95 /**
96 * If `true`, Sass won't add a link from the generated CSS to the source map.
97 *
98 * ```js
99 * const result = sass.renderSync({
100 * file: "style.scss",
101 * sourceMap: "out.map",
102 * omitSourceMapUrl: true
103 * })
104 * console.log(result.css.toString());
105 * // h1 {
106 * // font-size: 40px;
107 * // }
108 * ```
109 *
110 * @defaultValue `false`
111 * @category Source Maps
112 */
113 omitSourceMapUrl?: boolean;
114
115 /**
116 * The location that Sass expects the generated CSS to be saved to. It’s used
117 * to determine the URL used to link from the generated CSS to the source map,
118 * and from the source map to the Sass source files.
119 *
120 * **Heads up!** Despite the name, Sass does *not* write the CSS output to
121 * this file. The caller must do that themselves.
122 *
123 * ```js
124 * result = sass.renderSync({
125 * file: "style.scss",
126 * sourceMap: true,
127 * outFile: "out.css"
128 * })
129 * console.log(result.css.toString());
130 * // h1 {
131 * // font-size: 40px;
132 * // }
133 * // /*# sourceMappingURL=out.css.map * /
134 * ```
135 *
136 * @category Source Maps
137 */
138 outFile?: string;
139
140 /**
141 * The output style of the compiled CSS. There are four possible output styles:
142 *
143 * * `"expanded"` (the default for Dart Sass) writes each selector and
144 * declaration on its own line.
145 *
146 * * `"compressed"` removes as many extra characters as possible, and writes
147 * the entire stylesheet on a single line.
148 *
149 * * `"nested"` (the default for Node Sass, not supported by Dart Sass)
150 * indents CSS rules to match the nesting of the Sass source.
151 *
152 * * `"compact"` (not supported by Dart Sass) puts each CSS rule on its own single line.
153 *
154 * @example
155 *
156 * ```js
157 * const source = `
158 * h1 {
159 * font-size: 40px;
160 * code {
161 * font-face: Roboto Mono;
162 * }
163 * }`;
164 *
165 * let result = sass.renderSync({
166 * data: source,
167 * outputStyle: "expanded"
168 * });
169 * console.log(result.css.toString());
170 * // h1 {
171 * // font-size: 40px;
172 * // }
173 * // h1 code {
174 * // font-face: Roboto Mono;
175 * // }
176 *
177 * result = sass.renderSync({
178 * data: source,
179 * outputStyle: "compressed"
180 * });
181 * console.log(result.css.toString());
182 * // h1{font-size:40px}h1 code{font-face:Roboto Mono}
183 *
184 * result = sass.renderSync({
185 * data: source,
186 * outputStyle: "nested"
187 * });
188 * console.log(result.css.toString());
189 * // h1 {
190 * // font-size: 40px; }
191 * // h1 code {
192 * // font-face: Roboto Mono; }
193 *
194 * result = sass.renderSync({
195 * data: source,
196 * outputStyle: "compact"
197 * });
198 * console.log(result.css.toString());
199 * // h1 { font-size: 40px; }
200 * // h1 code { font-face: Roboto Mono; }
201 * ```
202 *
203 * @category Output
204 */
205 outputStyle?: 'compressed' | 'expanded' | 'nested' | 'compact';
206
207 /**
208 * Whether or not Sass should generate a source map. If it does, the source
209 * map will be available as [[LegacyResult.map]] (unless [[sourceMapEmbed]] is
210 * `true`).
211 *
212 * If this option is a string, it’s the path that the source map is expected
213 * to be written to, which is used to link to the source map from the
214 * generated CSS and to link *from* the source map to the Sass source files.
215 * Note that if `sourceMap` is a string and [[outFile]] isn’t passed, Sass
216 * assumes that the CSS will be written to the same directory as the file
217 * option if it’s passed.
218 *
219 * If this option is `true`, the path is assumed to be [[outFile]] with `.map`
220 * added to the end. If it’s `true` and [[outFile]] isn’t passed, it has no
221 * effect.
222 *
223 * @example
224 *
225 * ```js
226 * let result = sass.renderSync({
227 * file: "style.scss",
228 * sourceMap: "out.map"
229 * })
230 * console.log(result.css.toString());
231 * // h1 {
232 * // font-size: 40px;
233 * // }
234 * // /*# sourceMappingURL=out.map * /
235 *
236 * result = sass.renderSync({
237 * file: "style.scss",
238 * sourceMap: true,
239 * outFile: "out.css"
240 * })
241 * console.log(result.css.toString());
242 * // h1 {
243 * // font-size: 40px;
244 * // }
245 * // /*# sourceMappingURL=out.css.map * /
246 * ```
247 *
248 * @defaultValue `false`
249 * @category Source Maps
250 */
251 sourceMap?: boolean | string;
252
253 /**
254 * Whether to embed the entire contents of the Sass files that contributed to
255 * the generated CSS in the source map. This may produce very large source
256 * maps, but it guarantees that the source will be available on any computer
257 * no matter how the CSS is served.
258 *
259 * @example
260 *
261 * ```js
262 * sass.renderSync({
263 * file: "style.scss",
264 * sourceMap: "out.map",
265 * sourceMapContents: true
266 * })
267 * ```
268 *
269 * @defaultValue `false`
270 * @category Source Maps
271 */
272 sourceMapContents?: boolean;
273
274 /**
275 * Whether to embed the contents of the source map file in the generated CSS,
276 * rather than creating a separate file and linking to it from the CSS.
277 *
278 * @example
279 *
280 * ```js
281 * sass.renderSync({
282 * file: "style.scss",
283 * sourceMap: "out.map",
284 * sourceMapEmbed: true
285 * });
286 * ```
287 *
288 * @defaultValue `false`
289 * @category Source Maps
290 */
291 sourceMapEmbed?: boolean;
292
293 /**
294 * If this is passed, it's prepended to all the links from the source map to
295 * the Sass source files.
296 *
297 * @category Source Maps
298 */
299 sourceMapRoot?: string;
300
301 /**
302 * Additional handler(s) for loading files when a [`@use`
303 * rule](https://sass-lang.com/documentation/at-rules/use) or an [`@import`
304 * rule](https://sass-lang.com/documentation/at-rules/import) is encountered.
305 * It can either be a single [[LegacyImporter]] function, or an array of
306 * [[LegacyImporter]]s.
307 *
308 * Importers take the URL of the `@import` or `@use` rule and return a
309 * [[LegacyImporterResult]] indicating how to handle that rule. For more
310 * details, see [[LegacySyncImporter]] and [[LegacyAsyncImporter]].
311 *
312 * Loads are resolved by trying, in order:
313 *
314 * * Loading a file from disk relative to the file in which the `@use` or
315 * `@import` appeared.
316 *
317 * * Each custom importer.
318 *
319 * * Loading a file relative to the current working directory.
320 *
321 * * Each load path in [[includePaths]].
322 *
323 * * Each load path specified in the `SASS_PATH` environment variable, which
324 * should be semicolon-separated on Windows and colon-separated elsewhere.
325 *
326 * @example
327 *
328 * ```js
329 * sass.render({
330 * file: "style.scss",
331 * importer: [
332 * // This importer uses the synchronous API, and can be passed to either
333 * // renderSync() or render().
334 * function(url, prev) {
335 * // This generates a stylesheet from scratch for `@use "big-headers"`.
336 * if (url != "big-headers") return null;
337 *
338 * return {
339 * contents: `
340 * h1 {
341 * font-size: 40px;
342 * }`
343 * };
344 * },
345 *
346 * // This importer uses the asynchronous API, and can only be passed to
347 * // render().
348 * function(url, prev, done) {
349 * // Convert `@use "foo/bar"` to "node_modules/foo/sass/bar".
350 * const components = url.split('/');
351 * const innerPath = components.slice(1).join('/');
352 * done({
353 * file: `node_modules/${components.first}/sass/${innerPath}`
354 * });
355 * }
356 * ]
357 * }, function(err, result) {
358 * // ...
359 * });
360 * ```
361 *
362 * @category Plugins
363 * @compatibility dart: true, node: "3.0.0"
364 *
365 * Versions of Node Sass before 3.0.0 don’t support arrays of importers, nor
366 * do they support importers that return `Error` objects.
367 *
368 * Versions of Node Sass before 2.0.0 don’t support the `importer` option at
369 * all.
370 *
371 * @compatibility feature: "Import order", dart: "1.20.2", node: false
372 *
373 * Versions of Dart Sass before 1.20.2 preferred resolving imports using
374 * [[includePaths]] before resolving them using custom importers.
375 *
376 * All versions of Node Sass currently pass imports to importers before
377 * loading them relative to the file in which the `@import` appears. This
378 * behavior is considered incorrect and should not be relied on because it
379 * violates the principle of *locality*, which says that it should be possible
380 * to reason about a stylesheet without knowing everything about how the
381 * entire system is set up. If a user tries to import a stylesheet relative to
382 * another stylesheet, that import should *always* work. It shouldn’t be
383 * possible for some configuration somewhere else to break it.
384 */
385 importer?: LegacyImporter<sync> | LegacyImporter<sync>[];
386
387 /**
388 * Additional built-in Sass functions that are available in all stylesheets.
389 * This option takes an object whose keys are Sass function signatures and
390 * whose values are [[LegacyFunction]]s. Each function should take the same
391 * arguments as its signature.
392 *
393 * Functions are passed JavaScript representations of [Sass value
394 * types](https://sass-lang.com/documentation/js-api#value-types), and must
395 * return the same.
396 *
397 * **Heads up!** When writing custom functions, it’s important to ensure that
398 * all the arguments are the types you expect. Otherwise, users’ stylesheets
399 * could crash in hard-to-debug ways or, worse, compile to meaningless CSS.
400 *
401 * @example
402 *
403 * ```js
404 * sass.render({
405 * data: `
406 * h1 {
407 * font-size: pow(2, 5) * 1px;
408 * }`,
409 * functions: {
410 * // This function uses the synchronous API, and can be passed to either
411 * // renderSync() or render().
412 * 'pow($base, $exponent)': function(base, exponent) {
413 * if (!(base instanceof sass.types.Number)) {
414 * throw "$base: Expected a number.";
415 * } else if (base.getUnit()) {
416 * throw "$base: Expected a unitless number.";
417 * }
418 *
419 * if (!(exponent instanceof sass.types.Number)) {
420 * throw "$exponent: Expected a number.";
421 * } else if (exponent.getUnit()) {
422 * throw "$exponent: Expected a unitless number.";
423 * }
424 *
425 * return new sass.types.Number(
426 * Math.pow(base.getValue(), exponent.getValue()));
427 * },
428 *
429 * // This function uses the asynchronous API, and can only be passed to
430 * // render().
431 * 'sqrt($number)': function(number, done) {
432 * if (!(number instanceof sass.types.Number)) {
433 * throw "$number: Expected a number.";
434 * } else if (number.getUnit()) {
435 * throw "$number: Expected a unitless number.";
436 * }
437 *
438 * done(new sass.types.Number(Math.sqrt(number.getValue())));
439 * }
440 * }
441 * }, function(err, result) {
442 * console.log(result.css.toString());
443 * // h1 {
444 * // font-size: 32px;
445 * // }
446 * });
447 * ```
448 *
449 * @category Plugins
450 */
451 functions?: {[key: string]: LegacyFunction<sync>};
452
453 /**
454 * By default, if the CSS document contains non-ASCII characters, Sass adds a
455 * `@charset` declaration (in expanded output mode) or a byte-order mark (in
456 * compressed mode) to indicate its encoding to browsers or other consumers.
457 * If `charset` is `false`, these annotations are omitted.
458 *
459 * @category Output
460 * @compatibility dart: "1.39.0", node: false
461 */
462 charset?: boolean;
463
464 /**
465 * If this option is set to `true`, Sass won’t print warnings that are caused
466 * by dependencies. A “dependency” is defined as any file that’s loaded
467 * through [[loadPaths]] or [[importer]]. Stylesheets that are imported
468 * relative to the entrypoint are not considered dependencies.
469 *
470 * This is useful for silencing deprecation warnings that you can’t fix on
471 * your own. However, please <em>also</em> notify your dependencies of the deprecations
472 * so that they can get fixed as soon as possible!
473 *
474 * **Heads up!** If [[render]] or [[renderSync]] is called without
475 * [[LegacyFileOptions.file]] or [[LegacyStringOptions.file]], <em>all</em>
476 * stylesheets it loads will be considered dependencies. Since it doesn’t have
477 * a path of its own, everything it loads is coming from a load path rather
478 * than a relative import.
479 *
480 * @defaultValue `false`
481 * @category Messages
482 * @compatibility dart: "1.35.0", node: false
483 */
484 quietDeps?: boolean;
485
486 /**
487 * By default, Dart Sass will print only five instances of the same
488 * deprecation warning per compilation to avoid deluging users in console
489 * noise. If you set `verbose` to `true`, it will instead print every
490 * deprecation warning it encounters.
491 *
492 * @defaultValue `false`
493 * @category Messages
494 * @compatibility dart: "1.35.0", node: false
495 */
496 verbose?: boolean;
497
498 /**
499 * An object to use to handle warnings and/or debug messages from Sass.
500 *
501 * By default, Sass emits warnings and debug messages to standard error, but
502 * if [[Logger.warn]] or [[Logger.debug]] is set, this will invoke them
503 * instead.
504 *
505 * The special value [[Logger.silent]] can be used to easily silence all
506 * messages.
507 *
508 * @category Messages
509 * @compatibility dart: "1.43.0", node: false
510 */
511 logger?: Logger;
512}
513
514/**
515 * If [[file]] is passed without [[data]], Sass will load the stylesheet at
516 * [[file]] and compile it to CSS.
517 *
518 * @typeParam sync - This lets the TypeScript checker verify that
519 * [[LegacyAsyncImporter]]s and [[LegacyAsyncFunction]]s aren't passed to
520 * [[renderSync]].
521 */
522export interface LegacyFileOptions<sync extends 'sync' | 'async'>
523 extends LegacySharedOptions<sync> {
524 /**
525 * The path to the file for Sass to load and compile. If the file’s extension
526 * is `.scss`, it will be parsed as SCSS; if it’s `.sass`, it will be parsed
527 * as the indented syntax; and if it’s `.css`, it will be parsed as plain CSS.
528 * If it has no extension, it will be parsed as SCSS.
529 *
530 * @example
531 *
532 * ```js
533 * sass.renderSync({file: "style.scss"});
534 * ```
535 *
536 * @category Input
537 * @compatibility feature: "Plain CSS files", dart: "1.11.0", node: "partial"
538 *
539 * Node Sass and older versions of Dart Sass support loading files with the
540 * extension `.css`, but contrary to the specification they’re treated as SCSS
541 * files rather than being parsed as CSS. This behavior has been deprecated
542 * and should not be relied on. Any files that use Sass features should use
543 * the `.scss` extension.
544 *
545 * All versions of Node Sass and Dart Sass otherwise support the file option
546 * as described below.
547 */
548 file: string;
549
550 /**
551 * See [[LegacyStringOptions.file]] for documentation of passing [[file]] along
552 * with [[data]].
553 *
554 * @category Input
555 */
556 data?: never;
557}
558
559/**
560 * If [[data]] is passed, Sass will use it as the contents of the stylesheet to
561 * compile.
562 *
563 * @typeParam sync - This lets the TypeScript checker verify that
564 * [[LegacyAsyncImporter]]s and [[LegacyAsyncFunction]]s aren't passed to
565 * [[renderSync]].
566 *
567 * @category Legacy
568 * @deprecated This only works with the legacy [[render]] and [[renderSync]]
569 * APIs. Use [[StringOptions]] with [[compile]], [[compileString]],
570 * [[compileAsync]], and [[compileStringAsync]] instead.
571 */
572export interface LegacyStringOptions<sync extends 'sync' | 'async'>
573 extends LegacySharedOptions<sync> {
574 /**
575 * The contents of the stylesheet to compile. Unless [[file]] is passed as
576 * well, the stylesheet’s URL is set to `"stdin"`.
577 *
578 * By default, this stylesheet is parsed as SCSS. This can be controlled using
579 * [[indentedSyntax]].
580 *
581 * @example
582 *
583 * ```js
584 * sass.renderSync({
585 * data: `
586 * h1 {
587 * font-size: 40px;
588 * }`
589 * });
590 * ```
591 *
592 * @category Input
593 */
594 data: string;
595
596 /**
597 * If `file` and [[data]] are both passed, `file` is used as the path of the
598 * stylesheet for error reporting, but [[data]] is used as the contents of the
599 * stylesheet. In this case, `file`’s extension is not used to determine the
600 * syntax of the stylesheet.
601 *
602 * @category Input
603 */
604 file?: string;
605
606 /**
607 * This flag controls whether [[data]] is parsed as the indented syntax or
608 * not.
609 *
610 * @example
611 *
612 * ```js
613 * sass.renderSync({
614 * data: `
615 * h1
616 * font-size: 40px`,
617 * indentedSyntax: true
618 * });
619 * ```
620 *
621 * @defaultValue `false`
622 * @category Input
623 */
624 indentedSyntax?: boolean;
625}
626
627/**
628 * Options for [[render]] and [[renderSync]]. This can either be
629 * [[LegacyFileOptions]] to load a file from disk, or [[LegacyStringOptions]] to
630 * compile a string of Sass code.
631 *
632 * See [[LegacySharedOptions]] for options that are shared across both file and
633 * string inputs.
634 *
635 * @category Legacy
636 * @deprecated This only works with the legacy [[render]] and [[renderSync]]
637 * APIs. Use [[Options]] with [[compile]], [[compileString]], [[compileAsync]],
638 * and [[compileStringAsync]] instead.
639 */
640export type LegacyOptions<sync extends 'sync' | 'async'> =
641 | LegacyFileOptions<sync>
642 | LegacyStringOptions<sync>;