import pify from 'pify'
import resolve from 'resolve';
import sass from 'sass';
import { dirname } from 'path';
import { writeFileSync } from 'fs';
import { isString, isFunction } from 'util';
import { createFilter } from 'rollup-pluginutils';
import { insertStyle } from './style.js';
import { ensureFileSync } from 'fs-extra';

const MATCH_SASS_FILENAME_RE = /\.sass$/;
const MATCH_NODE_MODULE_RE = /^~([a-z0-9]|@).+/i;

export default function plugin(options = {}) {
  const {
    include = [ '**/*.sass', '**/*.scss' ],
    exclude = 'node_modules/**',
  } = options;
  const filter = createFilter(include, exclude);
  const insertFnName = '___$insertStyle';
  const styles = [];
  const styleMaps = {};

  options.output = options.output || false;
  options.insert = options.insert || false;

  const sassRuntime = options.runtime || sass;

  return {
    name: 'sass',

    intro() {
      if (options.insert) {
        return insertStyle.toString().replace(/insertStyle/, insertFnName);
      }
    },

    async transform(code, id) {
      if (!filter(id)) {
        return;
      }

      try {
        const paths = [dirname(id), process.cwd()];
        const customizedSassOptions = options.options || {};
        const res = await pify(sassRuntime.render.bind(sassRuntime))(Object.assign({}, customizedSassOptions, {
          file: id,
          data: customizedSassOptions.data && `${customizedSassOptions.data}${code}`,
          indentedSyntax: MATCH_SASS_FILENAME_RE.test(id),
          includePaths: customizedSassOptions.includePaths
            ? customizedSassOptions.includePaths.concat(paths)
            : paths,
          importer: [
            (url, importer, done) => {
              if (!MATCH_NODE_MODULE_RE.test(url)) {
                return null;
              }

              const moduleUrl = url.slice(1);
              const resolveOptions = {
                basedir: dirname(importer),
                extensions: ['.scss', '.sass'],
              };

              try {
                done({
                  file: resolve.sync(moduleUrl, resolveOptions),
                });
              } catch (err) {
                if (customizedSassOptions.importer && customizedSassOptions.importer.length) {
                  return null;
                }
                done({
                  file: url,
                });
              }
            },
          ].concat(customizedSassOptions.importer || []),
        }));
        let css = res.css.toString().trim();
        let defaultExport = '';
        let restExports;

        if (css) {
          if (isFunction(options.processor)) {
            const processResult = await options.processor(css, id);

            if (typeof processResult === 'object') {
              if (typeof processResult.css !== 'string') {
                throw new Error('You need to return the styles using the `css` property. See https://github.com/differui/rollup-plugin-sass#processor');
              }
              css = processResult.css;
              delete processResult.css;
              restExports = Object.keys(processResult).map(name => `export const ${name} = ${JSON.stringify(processResult[name])};`);
            } else if (typeof processResult === 'string') {
              css = processResult;
            }
          }
          if (styleMaps[id]) {
            styleMaps[id].content = css;
          } else {
            styles.push(styleMaps[id] = {
              id: id,
              content: css,
            });
          }
          if (options.insert === true) {
            defaultExport = `${insertFnName}(${JSON.stringify(css)});`;
          } else if (options.output === false) {
            defaultExport = JSON.stringify(css);
          } else {
            defaultExport = `"";`;
          }
        }
        return {
          code: [
            `export default ${defaultExport};`,
            ...(restExports || []),
          ].join('\n'),
          map: {
            mappings: res.map
              ? res.map.toString()
              : '',
          },
        };
      } catch (error) {
        throw error;
      }
    },

    async generateBundle(generateOptions, bundle, isWrite) {
      if (!options.insert && (!styles.length || options.output === false)) {
        return;
      }
      if (isWrite) {
        return;
      }

      const css = styles.map(style => style.content).join('');

      if (isString(options.output)) {
        ensureFileSync(options.output, (err) => {
          if (err) {
            throw err;
          }
        });
        return writeFileSync(options.output, css);
      } else if (isFunction(options.output)) {
        return options.output(css, styles);
      } else if (!options.insert && generateOptions.file && options.output === true) {
        let dest = generateOptions.file;

        if (dest.endsWith('.js') || dest.endsWith('.ts')) {
          dest = dest.slice(0, -3);
        }
        dest = `${dest}.css`;
        ensureFileSync(dest, (err) => {
          if (err) {
            throw err;
          }
        });
        return writeFileSync(dest, css);
      }
    },
  };
}

@@ -4314,16 +4314,17 @@
     if (
+!
 isWrite)

Fix generateBundle hook not working