UNPKG

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