1*7cebda5aSEvan Baconimport resolveFrom from 'resolve-from';
2*7cebda5aSEvan Bacon
3*7cebda5aSEvan Baconlet sassInstance: typeof import('sass') | null = null;
4*7cebda5aSEvan Bacon
5*7cebda5aSEvan Baconfunction getSassInstance(projectRoot: string) {
6*7cebda5aSEvan Bacon  if (!sassInstance) {
7*7cebda5aSEvan Bacon    const sassPath = resolveFrom.silent(projectRoot, 'sass');
8*7cebda5aSEvan Bacon
9*7cebda5aSEvan Bacon    if (!sassPath) {
10*7cebda5aSEvan Bacon      throw new Error(
11*7cebda5aSEvan Bacon        `Cannot parse Sass files without the module 'sass' installed. Run 'yarn add sass' and try again.`
12*7cebda5aSEvan Bacon      );
13*7cebda5aSEvan Bacon    }
14*7cebda5aSEvan Bacon
15*7cebda5aSEvan Bacon    sassInstance = require(sassPath) as typeof import('sass');
16*7cebda5aSEvan Bacon  }
17*7cebda5aSEvan Bacon
18*7cebda5aSEvan Bacon  return sassInstance;
19*7cebda5aSEvan Bacon}
20*7cebda5aSEvan Bacon
21*7cebda5aSEvan Baconexport function matchSass(filename: string): import('sass').Syntax | null {
22*7cebda5aSEvan Bacon  if (filename.endsWith('.sass')) {
23*7cebda5aSEvan Bacon    return 'indented';
24*7cebda5aSEvan Bacon  } else if (filename.endsWith('.scss')) {
25*7cebda5aSEvan Bacon    return 'scss';
26*7cebda5aSEvan Bacon  }
27*7cebda5aSEvan Bacon  return null;
28*7cebda5aSEvan Bacon}
29*7cebda5aSEvan Bacon
30*7cebda5aSEvan Baconexport function compileSass(
31*7cebda5aSEvan Bacon  projectRoot: string,
32*7cebda5aSEvan Bacon  { filename, src }: { filename: string; src: string },
33*7cebda5aSEvan Bacon  // TODO: Expose to users somehow...
34*7cebda5aSEvan Bacon  options?: Partial<import('sass').StringOptions<'sync'>>
35*7cebda5aSEvan Bacon) {
36*7cebda5aSEvan Bacon  const sass = getSassInstance(projectRoot);
37*7cebda5aSEvan Bacon  const result = sass.compileString(src, options);
38*7cebda5aSEvan Bacon  return {
39*7cebda5aSEvan Bacon    src: result.css,
40*7cebda5aSEvan Bacon    // TODO: Should we use this? Leaning towards no since the CSS will be parsed again by the CSS loader.
41*7cebda5aSEvan Bacon    map: result.sourceMap,
42*7cebda5aSEvan Bacon  };
43*7cebda5aSEvan Bacon}
44