29582da1dedf4acff93ac70f6be2479c3d96f4d57c04b054bb09a458d9c84fbc0925c313513cf381db955a2ddba8f05f942b87ee2e02669d8b2c8e5678902f 16 KB

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