UNPKG

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