1 | import {FileImporter, Importer} from './importer';
|
2 | import {Logger} from './logger';
|
3 | import {Value} from './value';
|
4 | import {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 | */
|
18 | export 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 | */
|
31 | export 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 | */
|
76 | export 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 | */
|
90 | export 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 | */
|
360 | export 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 | */
|
396 | export 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 | */
|
433 | export type StringOptions<sync extends 'sync' | 'async'> =
|
434 | | StringOptionsWithImporter<sync>
|
435 | | StringOptionsWithoutImporter<sync>;
|