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 | * Additional built-in Sass functions that are available in all stylesheets.
|
113 | * This option takes an object whose keys are Sass function signatures like
|
114 | * you'd write for the [`@function
|
115 | * rule`](https://sass-lang.com/documentation/at-rules/function) and whose
|
116 | * values are [[CustomFunction]]s.
|
117 | *
|
118 | * Functions are passed JavaScript representations of [Sass value
|
119 | * types](https://sass-lang.com/documentation/js-api#value-types), and must
|
120 | * return the same.
|
121 | *
|
122 | * When writing custom functions, it's important to make them as user-friendly
|
123 | * and as close to the standards set by Sass's core functions as possible. Some
|
124 | * good guidelines to follow include:
|
125 | *
|
126 | * * Use `Value.assert*` methods, like [[Value.assertString]], to cast untyped
|
127 | * `Value` objects to more specific types. For values that were passed
|
128 | * directly as arguments, pass in the argument name as well. This ensures
|
129 | * that the user gets good error messages when they pass in the wrong type
|
130 | * to your function.
|
131 | *
|
132 | * * Individual classes may have more specific `assert*` methods, like
|
133 | * [[SassNumber.assertInt]], which should be used when possible.
|
134 | *
|
135 | * * In Sass, every value counts as a list. Rather than trying to detect the
|
136 | * [[SassList]] type, you should use [[Value.asList]] to treat all values as
|
137 | * lists.
|
138 | *
|
139 | * * When manipulating values like lists, strings, and numbers that have
|
140 | * metadata (comma versus space separated, bracketed versus unbracketed,
|
141 | * quoted versus unquoted, units), the output metadata should match the
|
142 | * input metadata.
|
143 | *
|
144 | * * When in doubt, lists should default to comma-separated, strings should
|
145 | * default to quoted, and numbers should default to unitless.
|
146 | *
|
147 | * * In Sass, lists and strings use one-based indexing and use negative
|
148 | * indices to index from the end of value. Functions should follow these
|
149 | * conventions. [[Value.sassIndexToListIndex]] and
|
150 | * [[SassString.sassIndexToStringIndex]] can be used to do this
|
151 | * automatically.
|
152 | *
|
153 | * * String indexes in Sass refer to Unicode code points while JavaScript
|
154 | * string indices refer to UTF-16 code units. For example, the character
|
155 | * U+1F60A SMILING FACE WITH SMILING EYES is a single Unicode code point but
|
156 | * is represented in UTF-16 as two code units (`0xD83D` and `0xDE0A`). So in
|
157 | * JavaScript, `"a😊b".charCodeAt(1)` returns `0xD83D`, whereas in Sass
|
158 | * `str-slice("a😊b", 1, 1)` returns `"😊"`. Functions should follow Sass's
|
159 | * convention. [[SassString.sassIndexToStringIndex]] can be used to do this
|
160 | * automatically, and the [[SassString.sassLength]] getter can be used to
|
161 | * access a string's length in code points.
|
162 | *
|
163 | * @example
|
164 | *
|
165 | * ```js
|
166 | * sass.compileString(`
|
167 | * h1 {
|
168 | * font-size: pow(2, 5) * 1px;
|
169 | * }`, {
|
170 | * functions: {
|
171 | * // Note: in real code, you should use `math.pow()` from the built-in
|
172 | * // `sass:math` module.
|
173 | * 'pow($base, $exponent)': function(args) {
|
174 | * const base = args[0].assertNumber('base').assertNoUnits('base');
|
175 | * const exponent =
|
176 | * args[1].assertNumber('exponent').assertNoUnits('exponent');
|
177 | *
|
178 | * return new sass.SassNumber(Math.pow(base.value, exponent.value));
|
179 | * }
|
180 | * }
|
181 | * });
|
182 | * ```
|
183 | *
|
184 | * @category Plugins
|
185 | */
|
186 | functions?: Record<string, CustomFunction<sync>>;
|
187 |
|
188 | /**
|
189 | * Custom importers that control how Sass resolves loads from rules like
|
190 | * [`@use`](https://sass-lang.com/documentation/at-rules/use) and
|
191 | * [`@import`](https://sass-lang.com/documentation/at-rules/import).
|
192 | *
|
193 | * Loads are resolved by trying, in order:
|
194 | *
|
195 | * - The importer that was used to load the current stylesheet, with the
|
196 | * loaded URL resolved relative to the current stylesheet's canonical URL.
|
197 | *
|
198 | * - Each [[Importer]] or [[FileImporter]] in [[importers]], in order.
|
199 | *
|
200 | * - Each load path in [[loadPaths]], in order.
|
201 | *
|
202 | * If none of these return a Sass file, the load fails and Sass throws an
|
203 | * error.
|
204 | *
|
205 | * @category Plugins
|
206 | */
|
207 | importers?: (Importer<sync> | FileImporter<sync>)[];
|
208 |
|
209 | /**
|
210 | * Paths in which to look for stylesheets loaded by rules like
|
211 | * [`@use`](https://sass-lang.com/documentation/at-rules/use) and
|
212 | * [`@import`](https://sass-lang.com/documentation/at-rules/import).
|
213 | *
|
214 | * A load path `loadPath` is equivalent to the following [[FileImporter]]:
|
215 | *
|
216 | * ```js
|
217 | * {
|
218 | * findFileUrl(url) {
|
219 | * // Load paths only support relative URLs.
|
220 | * if (/^[a-z]+:/i.test(url)) return null;
|
221 | * return new URL(url, pathToFileURL(loadPath));
|
222 | * }
|
223 | * }
|
224 | * ```
|
225 | *
|
226 | * @category Input
|
227 | */
|
228 | loadPaths?: string[];
|
229 |
|
230 | /**
|
231 | * An object to use to handle warnings and/or debug messages from Sass.
|
232 | *
|
233 | * By default, Sass emits warnings and debug messages to standard error, but
|
234 | * if [[Logger.warn]] or [[Logger.debug]] is set, this will invoke them
|
235 | * instead.
|
236 | *
|
237 | * The special value [[Logger.silent]] can be used to easily silence all
|
238 | * messages.
|
239 | *
|
240 | * @category Messages
|
241 | */
|
242 | logger?: Logger;
|
243 |
|
244 | /**
|
245 | * If this option is set to `true`, Sass won’t print warnings that are caused
|
246 | * by dependencies. A “dependency” is defined as any file that’s loaded
|
247 | * through [[loadPaths]] or [[importer]]. Stylesheets that are imported
|
248 | * relative to the entrypoint are not considered dependencies.
|
249 | *
|
250 | * This is useful for silencing deprecation warnings that you can’t fix on
|
251 | * your own. However, please <em>also</em> notify your dependencies of the deprecations
|
252 | * so that they can get fixed as soon as possible!
|
253 | *
|
254 | * **Heads up!** If [[compileString]] or [[compileStringAsync]] is called
|
255 | * without [[StringWithoutImporter.url]], <em>all</em> stylesheets it loads
|
256 | * will be considered dependencies. Since it doesn’t have a path of its own,
|
257 | * everything it loads is coming from a load path rather than a relative
|
258 | * import.
|
259 | *
|
260 | * @defaultValue `false`
|
261 | * @category Messages
|
262 | */
|
263 | quietDeps?: boolean;
|
264 |
|
265 | /**
|
266 | * Whether or not Sass should generate a source map. If it does, the source
|
267 | * map will be available as [[CompileResult.sourceMap]].
|
268 | *
|
269 | * **Heads up!** Sass doesn't automatically add a `sourceMappingURL` comment
|
270 | * to the generated CSS. It's up to callers to do that, since callers have
|
271 | * full knowledge of where the CSS and the source map will exist in relation
|
272 | * to one another and how they'll be served to the browser.
|
273 | *
|
274 | * @defaultValue `false`
|
275 | * @category Output
|
276 | */
|
277 | sourceMap?: boolean;
|
278 |
|
279 | /**
|
280 | * Whether Sass should include the sources in the generated source map.
|
281 | *
|
282 | * This option has no effect if [[sourceMap]] is `false`.
|
283 | *
|
284 | * @defaultValue `false`
|
285 | * @category Output
|
286 | */
|
287 | sourceMapIncludeSources?: boolean;
|
288 |
|
289 | /**
|
290 | * The [[OutputStyle]] of the compiled CSS.
|
291 | *
|
292 | * @example
|
293 | *
|
294 | * ```js
|
295 | * const source = `
|
296 | * h1 {
|
297 | * font-size: 40px;
|
298 | * code {
|
299 | * font-face: Roboto Mono;
|
300 | * }
|
301 | * }`;
|
302 | *
|
303 | * let result = sass.compileString(source, {style: "expanded"});
|
304 | * console.log(result.css.toString());
|
305 | * // h1 {
|
306 | * // font-size: 40px;
|
307 | * // }
|
308 | * // h1 code {
|
309 | * // font-face: Roboto Mono;
|
310 | * // }
|
311 | *
|
312 | * result = sass.compileString(source, {style: "compressed"})
|
313 | * console.log(result.css.toString());
|
314 | * // h1{font-size:40px}h1 code{font-face:Roboto Mono}
|
315 | * ```
|
316 | *
|
317 | * @category Output
|
318 | */
|
319 | style?: OutputStyle;
|
320 |
|
321 | /**
|
322 | * By default, Dart Sass will print only five instances of the same
|
323 | * deprecation warning per compilation to avoid deluging users in console
|
324 | * noise. If you set `verbose` to `true`, it will instead print every
|
325 | * deprecation warning it encounters.
|
326 | *
|
327 | * @defaultValue `false`
|
328 | * @category Messages
|
329 | */
|
330 | verbose?: boolean;
|
331 | }
|
332 |
|
333 | /**
|
334 | * Options that can be passed to [[compileString]] or [[compileStringAsync]].
|
335 | *
|
336 | * If the [[StringOptionsWithImporter.importer]] field isn't passed, the
|
337 | * entrypoint file can load files relative to itself if a `file://` URL is
|
338 | * passed to the [[url]] field.
|
339 | *
|
340 | * @typeParam sync - This lets the TypeScript checker verify that asynchronous
|
341 | * [[Importer]]s, [[FileImporter]]s, and [[CustomFunction]]s aren't passed to
|
342 | * [[compile]] or [[compileString]].
|
343 | *
|
344 | * @category Options
|
345 | */
|
346 | export interface StringOptionsWithoutImporter<sync extends 'sync' | 'async'>
|
347 | extends Options<sync> {
|
348 | /**
|
349 | * The [[Syntax]] to use to parse the entrypoint stylesheet.
|
350 | *
|
351 | * @default `'scss'`
|
352 | *
|
353 | * @category Input
|
354 | */
|
355 | syntax?: Syntax;
|
356 |
|
357 | /**
|
358 | * The canonical URL of the entrypoint stylesheet.
|
359 | *
|
360 | * A relative load's URL is first resolved relative to [[url]], then resolved
|
361 | * to a file on disk if it's a `file://` URL. If it can't be resolved to a
|
362 | * file on disk, it's then passed to [[importers]] and [[loadPaths]].
|
363 | *
|
364 | * @category Input
|
365 | */
|
366 | url?: URL;
|
367 | }
|
368 |
|
369 | /**
|
370 | * Options that can be passed to [[compileString]] or [[compileStringAsync]].
|
371 | *
|
372 | * If the [[StringOptionsWithImporter.importer]] field is passed, the entrypoint
|
373 | * file uses it to load files relative to itself and the [[url]] field is
|
374 | * mandatory.
|
375 | *
|
376 | * @typeParam sync - This lets the TypeScript checker verify that asynchronous
|
377 | * [[Importer]]s, [[FileImporter]]s, and [[CustomFunction]]s aren't passed to
|
378 | * [[compile]] or [[compileString]].
|
379 | *
|
380 | * @category Options
|
381 | */
|
382 | export interface StringOptionsWithImporter<sync extends 'sync' | 'async'>
|
383 | extends StringOptionsWithoutImporter<sync> {
|
384 | /**
|
385 | * The importer to use to handle loads that are relative to the entrypoint
|
386 | * stylesheet.
|
387 | *
|
388 | * A relative load's URL is first resolved relative to [[url]], then passed to
|
389 | * [[importer]]. If the importer doesn't recognize it, it's then passed to
|
390 | * [[importers]] and [[loadPaths]].
|
391 | *
|
392 | * @category Input
|
393 | */
|
394 | importer: Importer<sync> | FileImporter<sync>;
|
395 |
|
396 | /**
|
397 | * The canonical URL of the entrypoint stylesheet. If this is passed along
|
398 | * with [[importer]], it's used to resolve relative loads in the entrypoint
|
399 | * stylesheet.
|
400 | *
|
401 | * @category Input
|
402 | */
|
403 | url: URL;
|
404 | }
|
405 |
|
406 | /**
|
407 | * Options that can be passed to [[compileString]] or [[compileStringAsync]].
|
408 | *
|
409 | * This is a [[StringOptionsWithImporter]] if it has a
|
410 | * [[StringOptionsWithImporter.importer]] field, and a
|
411 | * [[StringOptionsWithoutImporter]] otherwise.
|
412 | *
|
413 | * @typeParam sync - This lets the TypeScript checker verify that asynchronous
|
414 | * [[Importer]]s, [[FileImporter]]s, and [[CustomFunction]]s aren't passed to
|
415 | * [[compile]] or [[compileString]].
|
416 | *
|
417 | * @category Options
|
418 | */
|
419 | export type StringOptions<sync extends 'sync' | 'async'> =
|
420 | | StringOptionsWithImporter<sync>
|
421 | | StringOptionsWithoutImporter<sync>;
|