"use strict"; const Promise = require("bluebird"); const path = require("path"); const core = require("../core"); const nodeSass = Promise.promisifyAll(require("node-sass")); const copyProps = require("copy-props"); const replaceExtension = require("../core/util/replace-extension"); const createSyntaxError = require("../core/errors/syntax-error"); let optionsToCopy = [ "functions", "indentedSyntax", "indentType", "indentWidth", "linefeed", "omitSourceMapUrl", // FIXME: outFile stuff "outputStyle", "precision", "sourceComments", "sourceMap", // FIXME: outFile stuff "sourceMapContents", "sourceMapEmbed", "sourceMapRoot" ]; module.exports = function (options = {}) { return core.createSingleFileTransform({ displayName: "SCSS (node-sass)", // stream: where 'contents' is a stream supportsStreams: false, // virtual files: files with a contents buffer/stream but without a path supportsVirtualFiles: true, // virtual filesystem: not-on-disk, eg. for includes of transformed files supportsVirtualFilesystem: (options.virtualFilesystemSupport === true), transform: ({metadata, contents}) => { let includePaths; if (!metadata.isVirtual) { includePaths = [path.dirname(metadata.path)]; } else { includePaths = []; } if (options.includePaths != null) { includePaths = includePaths.concat(options.includePaths); } let importer; if (options.virtualFilesystemSupport === true && metadata.virtualFilesystem != null) { importer = function include(target, previousPath, done) { if (/^[a-z]+:/i.test(target)) { /* Probably a URL; don't handle this. */ return null; } else { return Promise.try(() => { return metadata.virtualFilesystem.readFile(target); }).then((contents) => { done(contents.toString()); }).catch((err) => { done(err); }); } }; } return Promise.try(() => { let stringContents = contents.toString(); if (stringContents.length > 0) { let renderOptions = { data: stringContents, includePaths: includePaths, importer: importer, }; copyProps(options, renderOptions, optionsToCopy); return nodeSass.renderAsync(renderOptions); } else { return {css: contents}; } }).then((result) => { return { metadata: { /* FIXME: Implement a check that throws errors when a transform returns isVirtual:false for a non-existent path on a non-virtual FS */ isVirtual: true, /* FIXME: Verify that every transform returns a relativePath? */ relativePath: replaceExtension(metadata.relativePath, "css") }, contents: result.css }; }).catch({status: 1}, (err) => { /* Syntax error */ throw createSyntaxError({ error: err.message, line: err.line, column: err.column }); }).catch({status: 3}, (err) => { // no input provided throw new Error(err.message); }).catch((err) => { // console.log(require("util").inspect(err, {colors: true, depth: null})); throw err; }); /* FIXME: Error mapping! */ } }); };