UNPKG

15.9 kBTypeScriptView Raw
1import {DeprecationOrId, Version} from './deprecations';
2import {FileImporter, Importer, NodePackageImporter} from './importer';
3import {Logger} from './logger';
4import {Value} from './value';
5import {PromiseOr} from './util/promise_or';
6
7/**
8 * Syntaxes supported by Sass:
9 *
10 * - `'scss'` is the [SCSS
11 * syntax](https://sass-lang.com/documentation/syntax#scss).
12 * - `'indented'` is the [indented
13 * syntax](https://sass-lang.com/documentation/syntax#the-indented-syntax)
14 * - `'css'` is plain CSS, which is parsed like SCSS but forbids the use of any
15 * special Sass features.
16 *
17 * @category Options
18 */
19export type Syntax = 'scss' | 'indented' | 'css';
20
21/**
22 * Possible output styles for the compiled CSS:
23 *
24 * - `"expanded"` (the default for Dart Sass) writes each selector and
25 * declaration on its own line.
26 *
27 * - `"compressed"` removes as many extra characters as possible, and writes
28 * the entire stylesheet on a single line.
29 *
30 * @category Options
31 */
32export type OutputStyle = 'expanded' | 'compressed';
33
34/**
35 * A callback that implements a custom Sass function. This can be passed to
36 * {@link Options.functions}.
37 *
38 * ```js
39 * const result = sass.compile('style.scss', {
40 * functions: {
41 * "sum($arg1, $arg2)": (args) => {
42 * const arg1 = args[0].assertNumber('arg1');
43 * const value1 = arg1.value;
44 * const value2 = args[1].assertNumber('arg2')
45 * .convertValueToMatch(arg1, 'arg2', 'arg1');
46 * return new sass.SassNumber(value1 + value2).coerceToMatch(arg1);
47 * }
48 * }
49 * });
50 * ```
51 *
52 * @typeParam sync - A `CustomFunction<'sync'>` must return synchronously, but
53 * in return it can be passed to {@link compile} and {@link compileString} in
54 * addition to {@link compileAsync} and {@link compileStringAsync}.
55 *
56 * A `CustomFunction<'async'>` may either return synchronously or
57 * asynchronously, but it can only be used with {@link compileAsync} and {@link
58 * compileStringAsync}.
59 *
60 * @param args - An array of arguments passed by the function's caller. If the
61 * function takes [arbitrary
62 * arguments](https://sass-lang.com/documentation/at-rules/function#taking-arbitrary-arguments),
63 * the last element will be a {@link SassArgumentList}.
64 *
65 * @returns The function's result. This may be in the form of a `Promise`, but
66 * if it is the function may only be passed to {@link compileAsync} and {@link
67 * compileStringAsync}, not {@link compile} or {@link compileString}.
68 *
69 * @throws any - This function may throw an error, which the Sass compiler will
70 * treat as the function call failing. If the exception object has a `message`
71 * property, it will be used as the wrapped exception's message; otherwise, the
72 * exception object's `toString()` will be used. This means it's safe for custom
73 * functions to throw plain strings.
74 *
75 * @category Custom Function
76 */
77export type CustomFunction<sync extends 'sync' | 'async'> = (
78 args: Value[]
79) => PromiseOr<Value, sync>;
80
81/**
82 * Options that can be passed to {@link compile}, {@link compileAsync}, {@link
83 * compileString}, or {@link compileStringAsync}.
84 *
85 * @typeParam sync - This lets the TypeScript checker verify that asynchronous
86 * {@link Importer}s, {@link FileImporter}s, and {@link CustomFunction}s aren't
87 * passed to {@link compile} or {@link compileString}.
88 *
89 * @category Options
90 */
91export interface Options<sync extends 'sync' | 'async'> {
92 /**
93 * If this is `true`, the compiler will exclusively use ASCII characters in
94 * its error and warning messages. Otherwise, it may use non-ASCII Unicode
95 * characters as well.
96 *
97 * @defaultValue `false`
98 * @category Messages
99 */
100 alertAscii?: boolean;
101
102 /**
103 * If this is `true`, the compiler will use ANSI color escape codes in its
104 * error and warning messages. If it's `false`, it won't use these. If it's
105 * undefined, the compiler will determine whether or not to use colors
106 * depending on whether the user is using an interactive terminal.
107 *
108 * @category Messages
109 */
110 alertColor?: boolean;
111
112 /**
113 * If `true`, the compiler may prepend `@charset "UTF-8";` or U+FEFF
114 * (byte-order marker) if it outputs non-ASCII CSS.
115 *
116 * If `false`, the compiler never emits these byte sequences. This is ideal
117 * when concatenating or embedding in HTML `<style>` tags. (The output will
118 * still be UTF-8.)
119 *
120 * @defaultValue `true`
121 * @category Output
122 * @compatibility dart: "1.54.0", node: false
123 */
124 charset?: boolean;
125
126 /**
127 * A set of deprecations to treat as fatal.
128 *
129 * If a deprecation warning of any provided type is encountered during
130 * compilation, the compiler will error instead.
131 *
132 * If a `Version` is provided, then all deprecations that were active in that
133 * compiler version will be treated as fatal.
134 *
135 * @category Messages
136 * @compatiblity dart: "1.74.0", node: false
137 */
138 fatalDeprecations?: (DeprecationOrId | Version)[];
139
140 /**
141 * Additional built-in Sass functions that are available in all stylesheets.
142 * This option takes an object whose keys are Sass function signatures like
143 * you'd write for the [`@function
144 * rule`](https://sass-lang.com/documentation/at-rules/function) and whose
145 * values are {@link CustomFunction}s.
146 *
147 * Functions are passed subclasses of {@link Value}, and must return the same.
148 * If the return value includes {@link SassCalculation}s they will be
149 * simplified before being returned.
150 *
151 * When writing custom functions, it's important to make them as user-friendly
152 * and as close to the standards set by Sass's core functions as possible. Some
153 * good guidelines to follow include:
154 *
155 * * Use `Value.assert*` methods, like {@link Value.assertString}, to cast
156 * untyped `Value` objects to more specific types. For values that were
157 * passed directly as arguments, pass in the argument name as well. This
158 * ensures that the user gets good error messages when they pass in the
159 * wrong type to your function.
160 *
161 * * Individual classes may have more specific `assert*` methods, like {@link
162 * SassNumber.assertInt}, which should be used when possible.
163 *
164 * * In Sass, every value counts as a list. Rather than trying to detect the
165 * {@link SassList} type, you should use {@link Value.asList} to treat all
166 * values as lists.
167 *
168 * * When manipulating values like lists, strings, and numbers that have
169 * metadata (comma versus space separated, bracketed versus unbracketed,
170 * quoted versus unquoted, units), the output metadata should match the
171 * input metadata.
172 *
173 * * When in doubt, lists should default to comma-separated, strings should
174 * default to quoted, and numbers should default to unitless.
175 *
176 * * In Sass, lists and strings use one-based indexing and use negative
177 * indices to index from the end of value. Functions should follow these
178 * conventions. {@link Value.sassIndexToListIndex} and {@link
179 * SassString.sassIndexToStringIndex} can be used to do this automatically.
180 *
181 * * String indexes in Sass refer to Unicode code points while JavaScript
182 * string indices refer to UTF-16 code units. For example, the character
183 * U+1F60A SMILING FACE WITH SMILING EYES is a single Unicode code point but
184 * is represented in UTF-16 as two code units (`0xD83D` and `0xDE0A`). So in
185 * JavaScript, `"a😊b".charCodeAt(1)` returns `0xD83D`, whereas in Sass
186 * `str-slice("a😊b", 1, 1)` returns `"😊"`. Functions should follow Sass's
187 * convention. {@link SassString.sassIndexToStringIndex} can be used to do
188 * this automatically, and the {@link SassString.sassLength} getter can be
189 * used to access a string's length in code points.
190 *
191 * @example
192 *
193 * ```js
194 * sass.compileString(`
195 * h1 {
196 * font-size: pow(2, 5) * 1px;
197 * }`, {
198 * functions: {
199 * // Note: in real code, you should use `math.pow()` from the built-in
200 * // `sass:math` module.
201 * 'pow($base, $exponent)': function(args) {
202 * const base = args[0].assertNumber('base').assertNoUnits('base');
203 * const exponent =
204 * args[1].assertNumber('exponent').assertNoUnits('exponent');
205 *
206 * return new sass.SassNumber(Math.pow(base.value, exponent.value));
207 * }
208 * }
209 * });
210 * ```
211 *
212 * @category Plugins
213 */
214 functions?: Record<string, CustomFunction<sync>>;
215
216 /**
217 * A set of future deprecations to opt into early.
218 *
219 * Future deprecations passed here will be treated as active by the compiler,
220 * emitting warnings as necessary.
221 *
222 * @category Messages
223 * @compatiblity dart: "1.74.0", node: false
224 */
225 futureDeprecations?: DeprecationOrId[];
226
227 /**
228 * Custom importers that control how Sass resolves loads from rules like
229 * [`@use`](https://sass-lang.com/documentation/at-rules/use) and
230 * [`@import`](https://sass-lang.com/documentation/at-rules/import).
231 *
232 * Loads are resolved by trying, in order:
233 *
234 * - The importer that was used to load the current stylesheet, with the
235 * loaded URL resolved relative to the current stylesheet's canonical URL.
236 *
237 * - Each {@link Importer}, {@link FileImporter}, or
238 * {@link NodePackageImporter} in {@link importers}, in order.
239 *
240 * - Each load path in {@link loadPaths}, in order.
241 *
242 * If none of these return a Sass file, the load fails and Sass throws an
243 * error.
244 *
245 * @category Plugins
246 */
247 importers?: (Importer<sync> | FileImporter<sync> | NodePackageImporter)[];
248
249 /**
250 * Paths in which to look for stylesheets loaded by rules like
251 * [`@use`](https://sass-lang.com/documentation/at-rules/use) and
252 * [`@import`](https://sass-lang.com/documentation/at-rules/import).
253 *
254 * A load path `loadPath` is equivalent to the following {@link FileImporter}:
255 *
256 * ```js
257 * {
258 * findFileUrl(url) {
259 * // Load paths only support relative URLs.
260 * if (/^[a-z]+:/i.test(url)) return null;
261 * return new URL(url, pathToFileURL(loadPath));
262 * }
263 * }
264 * ```
265 *
266 * @category Input
267 */
268 loadPaths?: string[];
269
270 /**
271 * An object to use to handle warnings and/or debug messages from Sass.
272 *
273 * By default, Sass emits warnings and debug messages to standard error, but
274 * if {@link Logger.warn} or {@link Logger.debug} is set, this will invoke
275 * them instead.
276 *
277 * The special value {@link Logger.silent} can be used to easily silence all
278 * messages.
279 *
280 * @category Messages
281 */
282 logger?: Logger;
283
284 /**
285 * If this option is set to `true`, Sass won’t print warnings that are caused
286 * by dependencies. A “dependency” is defined as any file that’s loaded
287 * through {@link loadPaths} or {@link importers}. Stylesheets that are
288 * imported relative to the entrypoint are not considered dependencies.
289 *
290 * This is useful for silencing deprecation warnings that you can’t fix on
291 * your own. However, please <em>also</em> notify your dependencies of the deprecations
292 * so that they can get fixed as soon as possible!
293 *
294 * **Heads up!** If {@link compileString} or {@link compileStringAsync} is
295 * called without {@link StringOptions.url}, <em>all</em> stylesheets it loads
296 * will be considered dependencies. Since it doesn’t have a path of its own,
297 * everything it loads is coming from a load path rather than a relative
298 * import.
299 *
300 * @defaultValue `false`
301 * @category Messages
302 */
303 quietDeps?: boolean;
304
305 /**
306 * A set of active deprecations to ignore.
307 *
308 * If a deprecation warning of any provided type is encountered during
309 * compilation, the compiler will ignore it instead.
310 *
311 * **Heads up!** The deprecated functionality you're depending on will
312 * eventually break.
313 *
314 * @category Messages
315 * @compatiblity dart: "1.74.0", node: false
316 */
317 silenceDeprecations?: DeprecationOrId[];
318
319 /**
320 * Whether or not Sass should generate a source map. If it does, the source
321 * map will be available as {@link CompileResult.sourceMap}.
322 *
323 * **Heads up!** Sass doesn't automatically add a `sourceMappingURL` comment
324 * to the generated CSS. It's up to callers to do that, since callers have
325 * full knowledge of where the CSS and the source map will exist in relation
326 * to one another and how they'll be served to the browser.
327 *
328 * @defaultValue `false`
329 * @category Output
330 */
331 sourceMap?: boolean;
332
333 /**
334 * Whether Sass should include the sources in the generated source map.
335 *
336 * This option has no effect if {@link sourceMap} is `false`.
337 *
338 * @defaultValue `false`
339 * @category Output
340 */
341 sourceMapIncludeSources?: boolean;
342
343 /**
344 * The {@link OutputStyle} of the compiled CSS.
345 *
346 * @example
347 *
348 * ```js
349 * const source = `
350 * h1 {
351 * font-size: 40px;
352 * code {
353 * font-face: Roboto Mono;
354 * }
355 * }`;
356 *
357 * let result = sass.compileString(source, {style: "expanded"});
358 * console.log(result.css.toString());
359 * // h1 {
360 * // font-size: 40px;
361 * // }
362 * // h1 code {
363 * // font-face: Roboto Mono;
364 * // }
365 *
366 * result = sass.compileString(source, {style: "compressed"})
367 * console.log(result.css.toString());
368 * // h1{font-size:40px}h1 code{font-face:Roboto Mono}
369 * ```
370 *
371 * @category Output
372 */
373 style?: OutputStyle;
374
375 /**
376 * By default, Dart Sass will print only five instances of the same
377 * deprecation warning per compilation to avoid deluging users in console
378 * noise. If you set `verbose` to `true`, it will instead print every
379 * deprecation warning it encounters.
380 *
381 * @defaultValue `false`
382 * @category Messages
383 */
384 verbose?: boolean;
385}
386
387/**
388 * Options that can be passed to {@link compileString} or {@link
389 * compileStringAsync}.
390 *
391 * If the {@link StringOptions.importer} field isn't passed, the entrypoint file
392 * can load files relative to itself if a `file://` URL is passed to the {@link
393 * url} field. If it is passed, the entrypoint file uses it to load files
394 * relative to itself.
395 *
396 * @typeParam sync - This lets the TypeScript checker verify that asynchronous
397 * {@link Importer}s, {@link FileImporter}s, and {@link CustomFunction}s aren't
398 * passed to {@link compile} or {@link compileString}.
399 *
400 * @category Options
401 */
402export interface StringOptions<sync extends 'sync' | 'async'>
403 extends Options<sync> {
404 /**
405 * The {@link Syntax} to use to parse the entrypoint stylesheet.
406 *
407 * @default `'scss'`
408 *
409 * @category Input
410 */
411 syntax?: Syntax;
412
413 /**
414 * The importer to use to handle loads that are relative to the entrypoint
415 * stylesheet.
416 *
417 * A relative load's URL is first resolved relative to {@link url}, then
418 * passed to {@link importer}. (It's passed as-is if {@link url} isn't
419 * passed.) If the importer doesn't recognize it, it's then passed to {@link
420 * importers} and {@link loadPaths}.
421 *
422 * @category Input
423 */
424 importer?: Importer<sync> | FileImporter<sync>;
425
426 /**
427 * The canonical URL of the entrypoint stylesheet.
428 *
429 * A relative load's URL is first resolved relative to {@link url}, then
430 * resolved to a file on disk if it's a `file://` URL. If it can't be resolved
431 * to a file on disk, it's then passed to {@link importers} and {@link
432 * loadPaths}.
433 *
434 * @category Input
435 * @compatibility feature: "Undefined URL with importer", dart: "1.75.0", node: false
436 *
437 * Earlier versions of Dart Sass required {@link url} to be defined when
438 * passing {@link StringOptions.importer}.
439 */
440 url?: URL;
441}
442
443/**
444 * @category Options
445 * @deprecated Use {@link StringOptions} instead.
446 */
447type StringOptionsWithoutImporter<sync extends 'sync' | 'async'> =
448 StringOptions<sync>;
449
450/**
451 * @category Options
452 * @deprecated Use {@link StringOptions} instead.
453 */
454type StringOptionsWithImporter<sync extends 'sync' | 'async'> =
455 StringOptions<sync>;