import {FileImporter, Importer} from './importer'; import {Logger} from './logger'; import {Value} from './value'; import {PromiseOr} from './util/promise_or'; /** * Syntaxes supported by Sass: * * - `'scss'` is the [SCSS * syntax](https://sass-lang.com/documentation/syntax#scss). * - `'indented'` is the [indented * syntax](https://sass-lang.com/documentation/syntax#the-indented-syntax) * - `'css'` is plain CSS, which is parsed like SCSS but forbids the use of any * special Sass features. * * @category Options */ export type Syntax = 'scss' | 'indented' | 'css'; /** * Possible output styles for the compiled CSS: * * - `"expanded"` (the default for Dart Sass) writes each selector and * declaration on its own line. * * - `"compressed"` removes as many extra characters as possible, and writes * the entire stylesheet on a single line. * * @category Options */ export type OutputStyle = 'expanded' | 'compressed'; /** * A callback that implements a custom Sass function. This can be passed to * [[Options.functions]]. * * ```js * const result = sass.compile('style.scss', { * functions: { * "sum($arg1, $arg2)": (args) => { * const value1 = args[0].assertNumber('arg1').value; * const value2 = args[1].assertNumber('arg2') * .convertValueToMatch(arg1, 'arg2', 'arg1'); * return new sass.SassNumber(value1 + value2).coerceToMatch(arg1); * } * } * }); * ``` * * @typeParam sync - A `CustomFunction<'sync'>` must return synchronously, but * in return it can be passed to [[compile]] and [[compileString]] in addition * to [[compileAsync]] and [[compileStringAsync]]. * * A `CustomFunction<'async'>` may either return synchronously or * asynchronously, but it can only be used with [[compileAsync]] and * [[compileStringAsync]]. * * @param args - An array of arguments passed by the function's caller. If the * function takes [arbitrary * arguments](https://sass-lang.com/documentation/at-rules/function#taking-arbitrary-arguments), * the last element will be a [[SassArgumentList]]. * * @returns The function's result. This may be in the form of a `Promise`, but * if it is the function may only be passed to [[compileAsync]] and * [[compileStringAsync]], not [[compile]] or [[compileString]]. * * @throws any - This function may throw an error, which the Sass compiler will * treat as the function call failing. If the exception object has a `message` * property, it will be used as the wrapped exception's message; otherwise, the * exception object's `toString()` will be used. This means it's safe for custom * functions to throw plain strings. * * @category Custom Function */ export type CustomFunction = ( args: Value[] ) => PromiseOr; /** * Options that can be passed to [[compile]], [[compileAsync]], * [[compileString]], or [[compileStringAsync]]. * * @typeParam sync - This lets the TypeScript checker verify that asynchronous * [[Importer]]s, [[FileImporter]]s, and [[CustomFunction]]s aren't passed to * [[compile]] or [[compileString]]. * * @category Options */ export interface Options { /** * If this is `true`, the compiler will exclusively use ASCII characters in * its error and warning messages. Otherwise, it may use non-ASCII Unicode * characters as well. * * @defaultValue `false` * @category Messages */ alertAscii?: boolean; /** * If this is `true`, the compiler will use ANSI color escape codes in its * error and warning messages. If it's `false`, it won't use these. If it's * undefined, the compiler will determine whether or not to use colors * depending on whether the user is using an interactive terminal. * * @category Messages */ alertColor?: boolean; /** * Additional built-in Sass functions that are available in all stylesheets. * This option takes an object whose keys are Sass function signatures like * you'd write for the [`@function * rule`](https://sass-lang.com/documentation/at-rules/function) and whose * values are [[CustomFunction]]s. * * Functions are passed JavaScript representations of [Sass value * types](https://sass-lang.com/documentation/js-api#value-types), and must * return the same. * * When writing custom functions, it's important to make them as user-friendly * and as close to the standards set by Sass's core functions as possible. Some * good guidelines to follow include: * * * Use `Value.assert*` methods, like [[Value.assertString]], to cast untyped * `Value` objects to more specific types. For values that were passed * directly as arguments, pass in the argument name as well. This ensures * that the user gets good error messages when they pass in the wrong type * to your function. * * * Individual classes may have more specific `assert*` methods, like * [[SassNumber.assertInt]], which should be used when possible. * * * In Sass, every value counts as a list. Rather than trying to detect the * [[SassList]] type, you should use [[Value.asList]] to treat all values as * lists. * * * When manipulating values like lists, strings, and numbers that have * metadata (comma versus space separated, bracketed versus unbracketed, * quoted versus unquoted, units), the output metadata should match the * input metadata. * * * When in doubt, lists should default to comma-separated, strings should * default to quoted, and numbers should default to unitless. * * * In Sass, lists and strings use one-based indexing and use negative * indices to index from the end of value. Functions should follow these * conventions. [[Value.sassIndexToListIndex]] and * [[SassString.sassIndexToStringIndex]] can be used to do this * automatically. * * * String indexes in Sass refer to Unicode code points while JavaScript * string indices refer to UTF-16 code units. For example, the character * U+1F60A SMILING FACE WITH SMILING EYES is a single Unicode code point but * is represented in UTF-16 as two code units (`0xD83D` and `0xDE0A`). So in * JavaScript, `"ašŸ˜Šb".charCodeAt(1)` returns `0xD83D`, whereas in Sass * `str-slice("ašŸ˜Šb", 1, 1)` returns `"šŸ˜Š"`. Functions should follow Sass's * convention. [[SassString.sassIndexToStringIndex]] can be used to do this * automatically, and the [[SassString.sassLength]] getter can be used to * access a string's length in code points. * * @example * * ```js * sass.compileString(` * h1 { * font-size: pow(2, 5) * 1px; * }`, { * functions: { * // Note: in real code, you should use `math.pow()` from the built-in * // `sass:math` module. * 'pow($base, $exponent)': function(args) { * const base = args[0].assertNumber('base').assertNoUnits('base'); * const exponent = * args[1].assertNumber('exponent').assertNoUnits('exponent'); * * return new sass.SassNumber(Math.pow(base.value, exponent.value)); * } * } * }); * ``` * * @category Plugins */ functions?: Record>; /** * Custom importers that control how Sass resolves loads from rules like * [`@use`](https://sass-lang.com/documentation/at-rules/use) and * [`@import`](https://sass-lang.com/documentation/at-rules/import). * * Loads are resolved by trying, in order: * * - The importer that was used to load the current stylesheet, with the * loaded URL resolved relative to the current stylesheet's canonical URL. * * - Each [[Importer]] or [[FileImporter]] in [[importers]], in order. * * - Each load path in [[loadPaths]], in order. * * If none of these return a Sass file, the load fails and Sass throws an * error. * * @category Plugins */ importers?: (Importer | FileImporter)[]; /** * Paths in which to look for stylesheets loaded by rules like * [`@use`](https://sass-lang.com/documentation/at-rules/use) and * [`@import`](https://sass-lang.com/documentation/at-rules/import). * * A load path `loadPath` is equivalent to the following [[FileImporter]]: * * ```js * { * findFileUrl(url) { * // Load paths only support relative URLs. * if (/^[a-z]+:/i.test(url)) return null; * return new URL(url, pathToFileURL(loadPath)); * } * } * ``` * * @category Input */ loadPaths?: string[]; /** * An object to use to handle warnings and/or debug messages from Sass. * * By default, Sass emits warnings and debug messages to standard error, but * if [[Logger.warn]] or [[Logger.debug]] is set, this will invoke them * instead. * * The special value [[Logger.silent]] can be used to easily silence all * messages. * * @category Messages */ logger?: Logger; /** * If this option is set to `true`, Sass wonā€™t print warnings that are caused * by dependencies. A ā€œdependencyā€ is defined as any file thatā€™s loaded * through [[loadPaths]] or [[importer]]. Stylesheets that are imported * relative to the entrypoint are not considered dependencies. * * This is useful for silencing deprecation warnings that you canā€™t fix on * your own. However, please also notify your dependencies of the deprecations * so that they can get fixed as soon as possible! * * **Heads up!** If [[compileString]] or [[compileStringAsync]] is called * without [[StringWithoutImporter.url]], all stylesheets it loads * will be considered dependencies. Since it doesnā€™t have a path of its own, * everything it loads is coming from a load path rather than a relative * import. * * @defaultValue `false` * @category Messages */ quietDeps?: boolean; /** * Whether or not Sass should generate a source map. If it does, the source * map will be available as [[CompileResult.sourceMap]]. * * **Heads up!** Sass doesn't automatically add a `sourceMappingURL` comment * to the generated CSS. It's up to callers to do that, since callers have * full knowledge of where the CSS and the source map will exist in relation * to one another and how they'll be served to the browser. * * @defaultValue `false` * @category Output */ sourceMap?: boolean; /** * Whether Sass should include the sources in the generated source map. * * This option has no effect if [[sourceMap]] is `false`. * * @defaultValue `false` * @category Output */ sourceMapIncludeSources?: boolean; /** * The [[OutputStyle]] of the compiled CSS. * * @example * * ```js * const source = ` * h1 { * font-size: 40px; * code { * font-face: Roboto Mono; * } * }`; * * let result = sass.compileString(source, {style: "expanded"}); * console.log(result.css.toString()); * // h1 { * // font-size: 40px; * // } * // h1 code { * // font-face: Roboto Mono; * // } * * result = sass.compileString(source, {style: "compressed"}) * console.log(result.css.toString()); * // h1{font-size:40px}h1 code{font-face:Roboto Mono} * ``` * * @category Output */ style?: OutputStyle; /** * By default, Dart Sass will print only five instances of the same * deprecation warning per compilation to avoid deluging users in console * noise. If you set `verbose` to `true`, it will instead print every * deprecation warning it encounters. * * @defaultValue `false` * @category Messages */ verbose?: boolean; } /** * Options that can be passed to [[compileString]] or [[compileStringAsync]]. * * If the [[StringOptionsWithImporter.importer]] field isn't passed, the * entrypoint file can't load files relative to itself and the [[url]] field is * optional. * * @typeParam sync - This lets the TypeScript checker verify that asynchronous * [[Importer]]s, [[FileImporter]]s, and [[CustomFunction]]s aren't passed to * [[compile]] or [[compileString]]. * * @category Options */ export interface StringOptionsWithoutImporter extends Options { /** * The [[Syntax]] to use to parse the entrypoint stylesheet. * * @default `'scss'` * * @category Input */ syntax?: Syntax; /** * The canonical URL of the entrypoint stylesheet. If this isn't passed along * with [[StringOptionsWithoutImporter.importer]], it's optional and only used * for error reporting. * * @category Input */ url?: URL; } /** * Options that can be passed to [[compileString]] or [[compileStringAsync]]. * * If the [[StringOptionsWithImporter.importer]] field is passed, the entrypoint * file uses it to load files relative to itself and the [[url]] field is * mandatory. * * @typeParam sync - This lets the TypeScript checker verify that asynchronous * [[Importer]]s, [[FileImporter]]s, and [[CustomFunction]]s aren't passed to * [[compile]] or [[compileString]]. * * @category Options */ export interface StringOptionsWithImporter extends StringOptionsWithoutImporter { /** * The importer to use to handle loads that are relative to the entrypoint * stylesheet. * * A relative load's URL is first resolved relative to [[url]], then passed to * [[importer]]. If the importer doesn't recognize it, it's then passed to * [[importers]] and [[loadPaths]]. * * @category Input */ importer: Importer | FileImporter; /** * The canonical URL of the entrypoint stylesheet. If this is passed along * with [[importer]], it's used to resolve relative loads in the entrypoint * stylesheet. * * @category Input */ url: URL; } /** * Options that can be passed to [[compileString]] or [[compileStringAsync]]. * * This is a [[StringOptionsWithImporter]] if it has a * [[StringOptionsWithImporter.importer]] field, and a * [[StringOptionsWithoutImporter]] otherwise. * * @typeParam sync - This lets the TypeScript checker verify that asynchronous * [[Importer]]s, [[FileImporter]]s, and [[CustomFunction]]s aren't passed to * [[compile]] or [[compileString]]. * * @category Options */ export type StringOptions = | StringOptionsWithImporter | StringOptionsWithoutImporter;