Socket
Socket
Sign inDemoInstall

node-sass

Package Overview
Dependencies
Maintainers
5
Versions
148
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-sass - npm Package Compare versions

Comparing version 1.2.3 to 2.0.0-beta

src/libsass/appveyor.yml

182

lib/index.js

@@ -39,7 +39,7 @@ var fs = require('fs'),

if (!file || !outFile || typeof outFile !== 'string' || typeof file !== 'string') {
return false;
return null;
}
if (path.resolve(outFile) !== path.normalize(outFile).replace(new RegExp(path.sep + '$'), '')) {
return false;
if (path.resolve(outFile) === path.normalize(outFile).replace(/(.+)([\/|\\])$/, '$1')) {
return outFile;
}

@@ -58,3 +58,3 @@

function getStats(options) {
var stats = options.stats;
var stats = {};

@@ -70,3 +70,3 @@ stats.entry = options.file || 'data';

*
* @param {Object} options
* @param {Object} stats
* @param {Object} sourceMap

@@ -76,8 +76,5 @@ * @api private

function endStats(options, sourceMap) {
var stats = options.stats || {};
function endStats(stats) {
stats.end = Date.now();
stats.duration = stats.end - stats.start;
stats.sourceMap = sourceMap;

@@ -142,7 +139,6 @@ return stats;

options.imagePath = options.image_path || options.imagePath || '';
options.outFile = getOutFile(options) || null;
options.outFile = getOutFile(options);
options.paths = (options.include_paths || options.includePaths || []).join(path.delimiter);
options.precision = parseInt(options.precision) || 5;
options.sourceMap = getSourceMap(options);
options.stats = options.stats || {};
options.style = getStyle(options) || 0;

@@ -154,21 +150,51 @@

getStats(options);
var error = options.error;
var success = options.success;
var importer = options.importer;
options.error = function(err, code) {
try {
err = JSON.parse(err);
} catch (e) {
err = { message: err };
}
err.code = code;
if (error) {
error(err, code);
error(err);
}
};
options.success = function(css, sourceMap) {
endStats(options, sourceMap);
options.success = function() {
options.result.sourceMap = JSON.parse(options.result.sourceMap);
var stats = endStats(options.result.stats);
if (success) {
success(css, sourceMap);
success({
css: options.result.css,
map: options.result.sourceMap,
stats: stats
});
}
};
if (importer) {
options.importer = function(file, prev, key) {
var done = function(data) {
binding.importedCallback({
index: key,
objectLiteral: data
});
};
var result = importer(file, prev, done);
if (result) {
done(result);
}
};
}
delete options.image_path;

@@ -180,2 +206,6 @@ delete options.include_paths;

options.result = {
stats: getStats(options)
};
return options;

@@ -191,37 +221,2 @@ }

/**
* Render (deprecated)
*
* @param {String} css
* @param {Function} cb
* @param {Object} options
* @api private
*/
function deprecatedRender(css, cb, options) {
options = getOptions(options);
options.data = css;
options.error = cb;
options.success = function(css) {
cb(null, css);
};
binding.render(options);
}
/**
* Render sync (deprecated)
*
* @param {String} css
* @param {Object} options
* @api private
*/
function deprecatedRenderSync(css, options) {
options = getOptions(options);
options.data = css;
return binding.renderSync(options);
}
/**
* Render

@@ -234,8 +229,5 @@ *

module.exports.render = function(options) {
if (typeof arguments[0] === 'string') {
return deprecatedRender.apply(this, arguments);
}
options = getOptions(options);
options = getOptions(options);
options.file ? binding.renderFile(options) : binding.render(options);
options.data ? binding.render(options) : binding.renderFile(options);
};

@@ -251,77 +243,25 @@

module.exports.renderSync = function(options) {
if (typeof arguments[0] === 'string') {
return deprecatedRenderSync.apply(this, arguments);
}
var output;
options = getOptions(options);
output = options.file ? binding.renderFileSync(options) : binding.renderSync(options);
endStats(options, options.stats.sourceMap);
return output;
};
var result = options.data ? binding.renderSync(options) : binding.renderFileSync(options);
/**
* Render file
*
* `options.sourceMap` can be used to specify that the source map should be saved:
*
* - If falsy the source map will not be saved
* - If `options.sourceMap === true` the source map will be saved to the
* standard location of `options.file + '.map'`
* - Else `options.sourceMap` specifies the path (relative to the `outFile`)
* where the source map should be saved
*
* @param {Object} options
* @api public
*/
if(result) {
options.result.stats = endStats(options.result.stats);
module.exports.renderFile = function(options) {
options = options || {};
var outFile = options.outFile;
var success = options.success;
if (options.sourceMap === true) {
options.sourceMap = outFile + '.map';
return options.result;
}
options.success = function(css, sourceMap) {
fs.writeFile(outFile, css, function(err) {
if (err) {
return options.error(err);
}
if (!options.sourceMap) {
return success(outFile);
}
var dir = path.dirname(outFile);
var sourceMapFile = path.resolve(dir, options.sourceMap);
fs.writeFile(sourceMapFile, sourceMap, function(err) {
if (err) {
return options.error(err);
}
success(outFile, sourceMapFile);
});
});
};
module.exports.render(options);
};
/**
* Middleware
* API Info
*
* @api public
*/
module.exports.middleware = function() {
return new Error([
'The middleware has been moved to',
'https://github.com/sass/node-sass-middleware'
].join(' '));
module.exports.info = function() {
var package = require('../package.json');
return [
'node-sass version: ' + package.version,
'libsass version: ' + package.libsass
].join('\n');
};

@@ -23,3 +23,6 @@ var fs = require('fs'),

sourceComments: options.sourceComments,
sourceMap: options.sourceMap
sourceMapEmbed: options.sourceMapEmbed,
sourceMapContents: options.sourceMapContents,
sourceMap: options.sourceMap,
importer: options.importer
};

@@ -33,3 +36,3 @@

renderOptions.success = function(css, sourceMap) {
renderOptions.success = function(result) {
var todo = 1;

@@ -42,4 +45,4 @@ var done = function() {

if (options.stdout || (!options.dest && !process.stdout.isTTY)) {
emitter.emit('log', css);
if (options.stdout || (!options.dest && !process.stdout.isTTY) || options.stdin) {
emitter.emit('log', result.css);
return done();

@@ -50,9 +53,9 @@ }

fs.writeFile(options.dest, css, function(err) {
fs.writeFile(options.dest, result.css, function(err) {
if (err) {
return emitter.emit('error', chalk.red('Error: ' + err));
return emitter.emit('error', chalk.red(err));
}
emitter.emit('warn', chalk.green('Wrote CSS to ' + options.dest));
emitter.emit('write', err, options.dest, css);
emitter.emit('write', err, options.dest, result.css);
done();

@@ -64,3 +67,3 @@ });

fs.writeFile(options.sourceMap, sourceMap, function(err) {
fs.writeFile(options.sourceMap, result.map, function(err) {
if (err) {

@@ -71,3 +74,3 @@ return emitter.emit('error', chalk.red('Error' + err));

emitter.emit('warn', chalk.green('Wrote Source Map to ' + options.sourceMap));
emitter.emit('write-source-map', err, options.sourceMap, sourceMap);
emitter.emit('write-source-map', err, options.sourceMap, result.sourceMap);
done();

@@ -77,7 +80,7 @@ });

emitter.emit('render', css);
emitter.emit('render', result.css);
};
renderOptions.error = function(error) {
emitter.emit('error', chalk.red(error));
emitter.emit('error', chalk.red(JSON.stringify(error, null, 2)));
};

@@ -84,0 +87,0 @@

{
"name": "node-sass",
"version": "1.2.3",
"version": "2.0.0-beta",
"libsass": "3.1.0-beta",
"description": "Wrapper around libsass",

@@ -53,3 +54,3 @@ "license": "MIT",

"nan": "^1.3.0",
"object-assign": "^1.0.0",
"object-assign": "^2.0.0",
"replace-ext": "0.0.1",

@@ -56,0 +57,0 @@ "request": "^2.48.0",

@@ -1,2 +0,2 @@

# node-sass
# node-sass

@@ -48,5 +48,5 @@ ![logo](https://rawgit.com/sass/node-sass/master/media/logo.svg)

// OR
var css = sass.renderSync({
data: scss_content
[, options..]
var result = sass.renderSync({
data: scss_content
[, options..]
});

@@ -69,4 +69,7 @@ ```

#### error
`error` is a `Function` to be called upon occurance of an error when rendering the scss to css. This option is optional, and only applies to the render function. If provided to renderSync it will be ignored.
`error` is a `Function` to be called upon occurrence of an error when rendering the scss to css. This option is optional, and only applies to the render function. If provided to renderSync it will be ignored.
#### importer (starting from v2)
`importer` is a `Function` to be called when libsass parser encounters the import directive. If present, libsass will call node-sass and let the user change file, data or both during the compilation. This option is optional, and applies to both render and renderSync functions. Also, it can either return object of form `{file:'..', contents: '..'}` or send it back via `done({})`. Note in renderSync or render, there is no restriction imposed on using `done()` callback or `return` statement (dispite of the asnchrony difference).
#### includePaths

@@ -78,2 +81,11 @@ `includePaths` is an `Array` of path `String`s to look for any `@import`ed files. It is recommended that you use this option if you are using the `data` option and have **any** `@import` directives, as otherwise [libsass] may not find your depended-on files.

#### indentedSyntax
`indentedSyntax` is a `Boolean` flag to determine if [Sass Indented Syntax](http://sass-lang.com/documentation/file.INDENTED_SYNTAX.html) should be used to parse provided string or a file.
#### omitSourceMapUrl
`omitSourceMapUrl` is a `Boolean` flag to determine whether to include `sourceMappingURL` comment in the output file.
#### outFile
`outFile` specifies where to save the CSS.
#### outputStyle

@@ -89,44 +101,11 @@ `outputStyle` is a `String` to determine how the final CSS should be rendered. Its value should be one of `'nested'` or `'compressed'`.

#### omitSourceMapUrl
`omitSourceMapUrl` is a `Boolean` flag to determine whether to include `sourceMappingURL` comment in the output file.
#### sourceMap
If your `sourceComments` option is set to `map`, `sourceMap` allows setting a new path context for the referenced Sass files.
The source map describes a path from your CSS file location, into the the folder where the Sass files are located. In most occasions this will work out-of-the-box but, in some cases, you may need to set a different output.
`sourceMap` can be set as `String` or `Boolean`. If it is set to `true`, the path of sourceMap would be computed by node-sass w.r.t the outFile path. It can also be set to absolute or relative (to outFile) path.
#### stats
`stats` is an empty `Object` that will be filled with stats from the compilation:
#### sourceMapEmbed
`sourceMapEmbed` is a `Boolean` flag to determine whether to embed `sourceMappingUrl` as data URI.
```javascript
{
entry: "path/to/entry.scss", // or just "data" if the source was not a file
start: 10000000, // Date.now() before the compilation
end: 10000001, // Date.now() after the compilation
duration: 1, // end - start
includedFiles: [ ... ], // absolute paths to all related scss files
sourceMap: "..." // the source map string or null
}
```
#### sourceMapContents
`sourceMapContents` is a `Boolean` flag to determine whether to include `contents` in maps.
`includedFiles` isn't sorted in any meaningful way, it's just a list of all imported scss files including the entry.
### renderFile()
Same as `render()` but writes the CSS and sourceMap (if requested) to the filesystem.
#### outFile
`outFile` specifies where to save the CSS.
#### sourceMap
`sourceMap` specifies that the source map should be saved.
- If falsy the source map will not be saved
- If `sourceMap === true` the source map will be saved to the
standard location of `path.basename(options.outFile) + '.map'`
- Otherwise specifies the path (relative to the `outFile`)
where the source map should be saved
### Examples

@@ -136,30 +115,92 @@

var sass = require('node-sass');
var stats = {};
sass.render({
file: '/path/to/myFile.scss',
data: 'body{background:blue; a{color:black;}}',
success: function(css) {
console.log(css);
console.log(stats);
success: function(result) {
// result is an object: v2 change
console.log(result.css);
console.log(result.stats);
console.log(result.map)
},
error: function(error) {
console.log(error);
// error is an object: v2 change
console.log(error.message);
console.log(error.code);
},
importer: function(url, prev, done) {
// url is the path in import as is, which libsass encountered.
// prev is the previously resolved path.
// done is an optional callback, either consume it or return value synchronously.
someAsyncFunction(url, prev, function(result){
done({
file: result.path, // only one of them is required, see section Sepcial Behaviours.
contents: result.data
});
});
// OR
var result = someSyncFunction(url, prev);
return {file: result.path, contents: result.data};
},
includePaths: [ 'lib/', 'mod/' ],
outputStyle: 'compressed',
stats: stats
outputStyle: 'compressed'
});
// OR
console.log(sass.renderSync({
var result = sass.renderSync({
file: '/path/to/file.scss',
data: 'body{background:blue; a{color:black;}}',
outputStyle: 'compressed',
stats: stats
outFile: '/to/my/output.css',
sourceMap: true, // or an absolute or relative (to outFile) path
importer: function(url, prev, done) {
// url is the path in import as is, which libsass encountered.
// prev is the previously resolved path.
// done is an optional callback, either consume it or return value synchronously.
someAsyncFunction(url, prev, function(result){
done({
file: result.path, // only one of them is required, see section Sepcial Behaviours.
contents: result.data
});
});
// OR
var result = someSyncFunction(url, prev);
return {file: result.path, contents: result.data};
},
}));
console.log(stats);
console.log(result.css);
console.log(result.map);
console.log(result.stats);
```
### Edge-case behaviours
The stats object consists of the following constituents:
* In the case that both `file` and `data` options are set, node-sass will only attempt to honour the `file` directive.
```javascript
{
entry: "path/to/entry.scss", // or just "data" if the source was not a file
start: 10000000, // Date.now() before the compilation
end: 10000001, // Date.now() after the compilation
duration: 1, // end - start
includedFiles: [ ... ], // absolute paths to all related scss files
sourceMap: "..." // the source map string or null
}
```
Note: `includedFiles` isn't sorted in any meaningful way, it's just a list of all imported scss files including the entry.
### Sepecial behaviours
* In the case that both `file` and `data` options are set, node-sass will give precedence to `data` and use `file` to calculate paths in sourcemaps.
### Version information (v2 change)
Both `node-sass` and `libsass` version info is now present in `package.json` and is expoded via `info()` method:
```javascript
require('node-sass').info();
// outputs something like:
// node-sass version: 2.0.0-beta
// libsass version: 3.1.0-beta
```
## Integrations

@@ -226,9 +267,14 @@

git clone --recursive https://github.com/sass/node-sass.git
cd node-sass
git submodule update --init --recursive
npm install
npm install -g node-gyp
node-gyp rebuild
```bash
git clone --recursive https://github.com/sass/node-sass.git
cd node-sass
git submodule update --init --recursive
npm install
npm install -g node-gyp
node-gyp rebuild # to make debug release, use -d switch
```
### Workaround for node `v0.11.13` `v0.11.14`
Follow the steps above, but comment out this [line](https://github.com/sass/node-sass/blob/e01497c4d4b8a7a7f4dbf9d607920ac10ad64445/lib/index.js#L181) in `lib/index.js` before the `npm install` step. Then uncomment it back again, and continue with the rest of the steps (see issue [#563](https://github.com/sass/node-sass/issues/563)).
## Command Line Interface

@@ -245,8 +291,23 @@

--output-style CSS output style (nested|expanded|compact|compressed) [default: "nested"]
--source-comments Include debug info in output [default: false]
--omit-source-map-url Omit source map URL comment from output [default: false]
--include-path Path to look for @import-ed files [default: cwd]
--help, -h Print usage info
```bash
-w, --watch Watch a directory or file
-r, --recursive Recursively watch directories or files
-o, --output Output directory
-x, --omit-source-map-url Omit source map URL comment from output
-i, --indented-syntax Treat data from stdin as sass code (versus scss)
--output-style CSS output style (nested|expanded|compact|compressed)
--source-comments Include debug info in output
--source-map Emit source map
--source-map-embed Embed sourceMappingUrl as data URI
--source-map-contents Embed include contents in map
--include-path Path to look for imported files
--image-path Path to prepend when using the `image-url()` helper
--precision The amount of precision allowed in decimal numbers
--stdout Print the resulting CSS to stdout
--importer Path to custom importer
--help Print usage info
```
Note `--importer` takes the (absolute or relative to pwd) path to a js file, which needs to have a default `module.exports` set to the importer function. See our test [fixtures](https://github.com/sass/node-sass/tree/974f93e76ddd08ea850e3e663cfe64bb6a059dd3/test/fixtures/extras) for example.
## Post-install Build

@@ -264,2 +325,3 @@

* Adeel Mujahid - Project Lead ([Github](https://github.com/am11) / [Twitter](https://twitter.com/adeelbm))
* Andrew Nesbitt ([Github](https://github.com/andrew) / [Twitter](https://twitter.com/teabass))

@@ -266,0 +328,0 @@ * Dean Mao ([Github](https://github.com/deanmao) / [Twitter](https://twitter.com/deanmao))

@@ -122,2 +122,4 @@ var fs = require('fs'),

return; // TODO: remove it once TravisCI build pass 90% and above tests
fs.stat(path.join(__dirname, '..', 'vendor', options.bin, 'binding.node'), function (err) {

@@ -124,0 +126,0 @@ if (err) {

@@ -18,3 +18,3 @@ var fs = require('fs'),

var file = fs.createWriteStream(dest);
var options = { proxy: getProxy() };
var options = { proxy: getProxy(), rejectUnauthorized: false };
var returnError = function(err) {

@@ -38,3 +38,3 @@ fs.unlink(dest);

req.on('error', returnError);
};
}

@@ -65,3 +65,3 @@ /**

var env = process.env;
return env.HTTPS_PROXY || env.https_proxy || env.HTTP_PROXY || env.http_proxy
return env.HTTPS_PROXY || env.https_proxy || env.HTTP_PROXY || env.http_proxy;
}

@@ -68,0 +68,0 @@

@@ -9,75 +9,24 @@ var assert = require('assert'),

describe('api (deprecated)', function() {
describe('.render(src, fn)', function() {
it('should compile sass to css', function(done) {
var src = read(fixture('simple/index.scss'), 'utf8');
describe('api', function() {
describe('.render(options)', function() {
it('should compile sass to css with file', function(done) {
var expected = read(fixture('simple/expected.css'), 'utf8').trim();
sass.render(src, function(err, css) {
assert(!err);
assert.equal(css.trim(), expected.replace(/\r\n/g, '\n'));
done();
sass.render({
file: fixture('simple/index.scss'),
success: function(result) {
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n'));
done();
}
});
});
it('should compile sass to css using indented syntax', function(done) {
var src = read(fixture('indent/index.sass'), 'utf8');
var expected = read(fixture('indent/expected.css'), 'utf8').trim();
sass.render(src, function(err, css) {
assert(!err);
assert.equal(css.trim(), expected.replace(/\r\n/g, '\n'));
done();
}, {
indentedSyntax: true
});
});
it('should throw error for bad input', function(done) {
sass.render('#navbar width 80%;', function(err) {
assert(err);
done();
});
});
});
describe('.renderSync(src)', function() {
it('should compile sass to css', function(done) {
it('should compile sass to css with data', function(done) {
var src = read(fixture('simple/index.scss'), 'utf8');
var expected = read(fixture('simple/expected.css'), 'utf8').trim();
var css = sass.renderSync(src).trim();
assert.equal(css, expected.replace(/\r\n/g, '\n'));
done();
});
it('should compile sass to css using indented syntax', function(done) {
var src = read(fixture('indent/index.sass'), 'utf8');
var expected = read(fixture('indent/expected.css'), 'utf8').trim();
var css = sass.renderSync(src, {indentedSyntax: true}).trim();
assert.equal(css, expected.replace(/\r\n/g, '\n'));
done();
});
it('should throw error for bad input', function(done) {
assert.throws(function() {
sass.renderSync('#navbar width 80%;');
});
done();
});
});
});
describe('api', function() {
describe('.render(options)', function() {
it('should compile sass to css', function(done) {
var src = read(fixture('simple/index.scss'), 'utf8');
var expected = read(fixture('simple/expected.css'), 'utf8').trim();
sass.render({
data: src,
success: function(css) {
assert.equal(css.trim(), expected.replace(/\r\n/g, '\n'));
success: function(result) {
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n'));
done();

@@ -95,4 +44,4 @@ }

indentedSyntax: true,
success: function(css) {
assert.equal(css.trim(), expected.replace(/\r\n/g, '\n'));
success: function(result) {
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n'));
done();

@@ -106,5 +55,5 @@ }

data: '#navbar width 80%;',
error: function(err, status) {
assert(err);
assert.equal(status, 1);
error: function(error) {
assert(error.message);
assert.equal(error.status, 1);
done();

@@ -125,4 +74,4 @@ }

],
success: function(css) {
assert.equal(css.trim(), expected.replace(/\r\n/g, '\n'));
success: function(result) {
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n'));
done();

@@ -140,4 +89,4 @@ }

imagePath: '/path/to/images',
success: function(css) {
assert.equal(css.trim(), expected.replace(/\r\n/g, '\n'));
success: function(result) {
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n'));
done();

@@ -168,4 +117,4 @@ }

precision: 10,
success: function(css) {
assert.equal(css.trim(), expected.replace(/\r\n/g, '\n'));
success: function(result) {
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n'));
done();

@@ -176,12 +125,14 @@ }

it('should compile with stats', function(done) {
var src = fixture('precision/index.scss');
var stats = {};
it('should contain all included files in stats when data is passed', function(done) {
var src = read(fixture('include-files/index.scss'), 'utf8');
var expected = [
fixture('include-files/bar.scss').replace(/\\/g, '/'),
fixture('include-files/foo.scss').replace(/\\/g, '/')
];
sass.render({
file: src,
stats: stats,
sourceMap: true,
success: function() {
assert.equal(stats.entry, src);
data: src,
includePaths: [fixture('include-files')],
success: function(result) {
assert.deepEqual(result.stats.includedFiles, expected);
done();

@@ -191,31 +142,207 @@ }

});
});
it('should contain all included files in stats when data is passed', function(done) {
var src = fixture('include-files/index.scss');
var stats = {};
var expected = [
fixture('include-files/bar.scss').replace(/\\/g, '/'),
fixture('include-files/foo.scss').replace(/\\/g, '/'),
'stdin'
];
describe('.render(importer)', function() {
var src = read(fixture('include-files/index.scss'), 'utf8');
it('should override imports with "data" as input and fires callback with file and contents', function(done) {
sass.render({
data: read(src, 'utf8'),
includePaths: [fixture('include-files')],
stats: stats,
success: function() {
assert.deepEqual(stats.includedFiles, expected);
data: src,
success: function(result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
},
importer: function(url, prev, done) {
done({
file: '/some/other/path.scss',
contents: 'div {color: yellow;}'
});
}
});
});
it('should override imports with "file" as input and fires callback with file and contents', function(done) {
sass.render({
file: fixture('include-files/index.scss'),
success: function(result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
},
importer: function(url, prev, done) {
done({
file: '/some/other/path.scss',
contents: 'div {color: yellow;}'
});
}
});
});
it('should override imports with "data" as input and returns file and contents', function(done) {
sass.render({
data: src,
success: function(result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
},
importer: function(url, prev) {
return {
file: prev + url,
contents: 'div {color: yellow;}'
};
}
});
});
it('should override imports with "file" as input and returns file and contents', function(done) {
sass.render({
file: fixture('include-files/index.scss'),
success: function(result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
},
importer: function(url, prev) {
return {
file: prev + url,
contents: 'div {color: yellow;}'
};
}
});
});
it('should override imports with "data" as input and fires callback with file', function(done) {
sass.render({
data: src,
success: function(result) {
assert.equal(result.css.trim(), '');
done();
},
importer: function(url, /* jshint unused:false */ prev, done) {
done({
file: path.resolve(path.dirname(fixture('include-files/index.scss')), url + (path.extname(url) ? '' : '.scss'))
});
}
});
});
it('should override imports with "file" as input and fires callback with file', function(done) {
sass.render({
file: fixture('include-files/index.scss'),
success: function(result) {
assert.equal(result.css.trim(), '');
done();
},
importer: function(url, prev, done) {
done({
file: path.resolve(path.dirname(prev), url + (path.extname(url) ? '' : '.scss'))
});
}
});
});
it('should override imports with "data" as input and returns file', function(done) {
sass.render({
data: src,
success: function(result) {
assert.equal(result.css.trim(), '');
done();
},
importer: function(url, /* jshint unused:false */ prev) {
return {
file: path.resolve(path.dirname(fixture('include-files/index.scss')), url + (path.extname(url) ? '' : '.scss'))
};
}
});
});
it('should override imports with "file" as input and returns file', function(done) {
sass.render({
file: fixture('include-files/index.scss'),
success: function(result) {
assert.equal(result.css.trim(), '');
done();
},
importer: function(url, prev) {
return {
file: path.resolve(path.dirname(prev), url + (path.extname(url) ? '' : '.scss'))
};
}
});
});
it('should override imports with "data" as input and fires callback with contents', function(done) {
sass.render({
data: src,
success: function(result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
},
importer: function(url, prev, done) {
done({
contents: 'div {color: yellow;}'
});
}
});
});
it('should override imports with "file" as input and fires callback with contents', function(done) {
sass.render({
file: fixture('include-files/index.scss'),
success: function(result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
},
importer: function(url, prev, done) {
done({
contents: 'div {color: yellow;}'
});
}
});
});
it('should override imports with "data" as input and returns contents', function(done) {
sass.render({
data: src,
success: function(result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
},
importer: function() {
return {
contents: 'div {color: yellow;}'
};
}
});
});
it('should override imports with "file" as input and returns contents', function(done) {
sass.render({
file: fixture('include-files/index.scss'),
success: function(result) {
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
},
importer: function() {
return {
contents: 'div {color: yellow;}'
};
}
});
});
});
describe('.renderSync(options)', function() {
it('should compile sass to css', function(done) {
it('should compile sass to css with file', function(done) {
var expected = read(fixture('simple/expected.css'), 'utf8').trim();
var result = sass.renderSync({file: fixture('simple/index.scss')});
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n'));
done();
});
it('should compile sass to css with data', function(done) {
var src = read(fixture('simple/index.scss'), 'utf8');
var expected = read(fixture('simple/expected.css'), 'utf8').trim();
var css = sass.renderSync({data: src}).trim();
var result = sass.renderSync({data: src});
assert.equal(css, expected.replace(/\r\n/g, '\n'));
assert.equal(result.css.trim(), expected.replace(/\r\n/g, '\n'));
done();

@@ -230,3 +357,3 @@ });

indentedSyntax: true
}).trim();
}).css.trim();

@@ -246,94 +373,176 @@ assert.equal(css, expected.replace(/\r\n/g, '\n'));

describe('.renderFile(options)', function() {
it('should compile sass to css', function(done) {
var src = read(fixture('simple/index.scss'), 'utf8');
var dest = fixture('simple/build.css');
var expected = read(fixture('simple/expected.css'), 'utf8').trim();
describe('.renderSync(importer)', function() {
var src = read(fixture('include-files/index.scss'), 'utf8');
sass.renderFile({
it('should override imports with "data" as input and fires callback with file and contents', function(done) {
var result = sass.renderSync({
data: src,
outFile: dest,
success: function() {
assert.equal(read(dest, 'utf8').trim(), expected.replace(/\r\n/g, '\n'));
fs.unlinkSync(dest);
done();
importer: function(url, prev, done) {
done({
file: '/some/other/path.scss',
contents: 'div {color: yellow;}'
});
}
});
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
});
it('should compile sass to css using indented syntax', function(done) {
var src = read(fixture('indent/index.sass'), 'utf8');
var dest = fixture('indent/build.css');
var expected = read(fixture('indent/expected.css'), 'utf8').trim();
it('should override imports with "file" as input and fires callback with file and contents', function(done) {
var result = sass.renderSync({
file: fixture('include-files/index.scss'),
importer: function(url, prev, done) {
done({
file: '/some/other/path.scss',
contents: 'div {color: yellow;}'
});
}
});
sass.renderFile({
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
});
it('should override imports with "data" as input and returns file and contents', function(done) {
var result = sass.renderSync({
data: src,
outFile: dest,
indentedSyntax: true,
success: function() {
assert.equal(read(dest, 'utf8').trim(), expected.replace(/\r\n/g, '\n'));
fs.unlinkSync(dest);
done();
importer: function(url, prev) {
return {
file: prev + url,
contents: 'div {color: yellow;}'
};
}
});
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
});
it('should save source map to default name', function(done) {
var src = fixture('source-map/index.scss');
var dest = fixture('source-map/build.css');
var name = 'build.css.map';
it('should override imports with "file" as input and returns file and contents', function(done) {
var result = sass.renderSync({
file: fixture('include-files/index.scss'),
importer: function(url, prev) {
return {
file: prev + url,
contents: 'div {color: yellow;}'
};
}
});
sass.renderFile({
file: src,
outFile: dest,
sourceMap: true,
success: function(file, map) {
assert.equal(path.basename(map), name);
assert(read(dest, 'utf8').indexOf('sourceMappingURL=' + name) !== -1);
fs.unlinkSync(map);
fs.unlinkSync(dest);
done();
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
});
it('should override imports with "data" as input and fires callback with file', function(done) {
var result = sass.renderSync({
data: src,
importer: function(url, /* jshint unused:false */ prev, done) {
done({
file: path.resolve(path.dirname(fixture('include-files/index.scss')), url + (path.extname(url) ? '' : '.scss'))
});
}
});
assert.equal(result.css.trim(), '');
done();
});
it('should save source map to specified name', function(done) {
var src = fixture('source-map/index.scss');
var dest = fixture('source-map/build.css');
var name = 'foo.css.map';
it('should override imports with "file" as input and fires callback with file', function(done) {
var result = sass.renderSync({
file: fixture('include-files/index.scss'),
importer: function(url, prev, done) {
done({
file: path.resolve(path.dirname(prev), url + (path.extname(url) ? '' : '.scss'))
});
}
});
sass.renderFile({
file: src,
outFile: dest,
sourceMap: name,
success: function(file, map) {
assert.equal(path.basename(map), name);
assert(read(dest, 'utf8').indexOf('sourceMappingURL=' + name) !== -1);
fs.unlinkSync(map);
fs.unlinkSync(dest);
done();
assert.equal(result.css.trim(), '');
done();
});
it('should override imports with "data" as input and returns file', function(done) {
var result = sass.renderSync({
data: src,
importer: function(url, /* jshint unused:false */ prev) {
return {
file: path.resolve(path.dirname(fixture('include-files/index.scss')), url + (path.extname(url) ? '' : '.scss'))
};
}
});
assert.equal(result.css.trim(), '');
done();
});
it('should save source paths relative to the source map file', function(done) {
var src = fixture('include-files/index.scss');
var dest = fixture('include-files/build.css');
var obj;
it('should override imports with "file" as input and returns file', function(done) {
var result = sass.renderSync({
file: fixture('include-files/index.scss'),
importer: function(url, prev) {
return {
file: path.resolve(path.dirname(prev), url + (path.extname(url) ? '' : '.scss'))
};
}
});
sass.renderFile({
file: src,
outFile: dest,
sourceMap: true,
success: function(file, map) {
obj = JSON.parse(read(map, 'utf8'));
assert.equal(obj.sources[0], 'index.scss');
assert.equal(obj.sources[1], 'foo.scss');
assert.equal(obj.sources[2], 'bar.scss');
fs.unlinkSync(map);
fs.unlinkSync(dest);
done();
assert.equal(result.css.trim(), '');
done();
});
it('should override imports with "data" as input and fires callback with contents', function(done) {
var result = sass.renderSync({
data: src,
importer: function(url, prev, done) {
done({
contents: 'div {color: yellow;}'
});
}
});
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
});
it('should override imports with "file" as input and fires callback with contents', function(done) {
var result = sass.renderSync({
file: fixture('include-files/index.scss'),
importer: function(url, prev, done) {
done({
contents: 'div {color: yellow;}'
});
}
});
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
});
it('should override imports with "data" as input and returns contents', function(done) {
var result = sass.renderSync({
data: src,
importer: function() {
return {
contents: 'div {color: yellow;}'
};
}
});
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
});
it('should override imports with "file" as input and returns contents', function(done) {
var result = sass.renderSync({
file: fixture('include-files/index.scss'),
importer: function() {
return {
contents: 'div {color: yellow;}'
};
}
});
assert.equal(result.css.trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
done();
});
});

@@ -343,9 +552,9 @@

var start = Date.now();
var stats = {};
before(function(done) {
it('should provide a start timestamp', function(done) {
sass.render({
file: fixture('include-files/index.scss'),
stats: stats,
success: function() {
success: function(result) {
assert(typeof result.stats.start === 'number');
assert(result.stats.start >= start);
done();

@@ -360,23 +569,44 @@ },

it('should provide a start timestamp', function(done) {
assert(typeof stats.start === 'number');
assert(stats.start >= start);
done();
});
it('should provide an end timestamp', function(done) {
assert(typeof stats.end === 'number');
assert(stats.end >= stats.start);
done();
sass.render({
file: fixture('include-files/index.scss'),
success: function(result) {
assert(typeof result.stats.end === 'number');
assert(result.stats.end >= result.stats.start);
done();
},
error: function(err) {
assert(!err);
done();
}
});
});
it('should provide a duration', function(done) {
assert(typeof stats.duration === 'number');
assert.equal(stats.end - stats.start, stats.duration);
done();
sass.render({
file: fixture('include-files/index.scss'),
success: function(result) {
assert(typeof result.stats.duration === 'number');
assert.equal(result.stats.end - result.stats.start, result.stats.duration);
done();
},
error: function(err) {
assert(!err);
done();
}
});
});
it('should contain the given entry file', function(done) {
assert.equal(stats.entry, fixture('include-files/index.scss'));
done();
sass.render({
file: fixture('include-files/index.scss'),
success: function(result) {
assert.equal(result.stats.entry, fixture('include-files/index.scss'));
done();
},
error: function(err) {
assert(!err);
done();
}
});
});

@@ -391,4 +621,13 @@

assert.deepEqual(stats.includedFiles, expected);
done();
sass.render({
file: fixture('include-files/index.scss'),
success: function(result) {
assert.deepEqual(result.stats.includedFiles, expected);
done();
},
error: function(err) {
assert(!err);
done();
}
});
});

@@ -401,5 +640,4 @@

file: fixture('simple/index.scss'),
stats: stats,
success: function() {
assert.deepEqual(stats.includedFiles, [expected]);
success: function(result) {
assert.deepEqual(result.stats.includedFiles, [expected]);
done();

@@ -413,5 +651,4 @@ }

data: read(fixture('simple/index.scss'), 'utf8'),
stats: stats,
success: function() {
assert.equal(stats.entry, 'data');
success: function(result) {
assert.equal(result.stats.entry, 'data');
done();

@@ -425,5 +662,4 @@ }

data: read(fixture('simple/index.scss'), 'utf8'),
stats: stats,
success: function() {
assert.deepEqual(stats.includedFiles, []);
success: function(result) {
assert.deepEqual(result.stats.includedFiles, []);
done();

@@ -433,16 +669,2 @@ }

});
it('should report correct source map in stats', function(done) {
sass.render({
file: fixture('simple/index.scss'),
outFile: fixture('simple/build.css'),
stats: stats,
sourceMap: true,
success: function() {
var map = JSON.parse(stats.sourceMap);
assert.equal(map.sources[0], 'index.scss');
done();
}
});
});
});

@@ -452,14 +674,9 @@

var start = Date.now();
var stats = {};
before(function() {
sass.renderSync({
file: fixture('include-files/index.scss'),
stats: stats
});
var result = sass.renderSync({
file: fixture('include-files/index.scss')
});
it('should provide a start timestamp', function(done) {
assert(typeof stats.start === 'number');
assert(stats.start >= start);
assert(typeof result.stats.start === 'number');
assert(result.stats.start >= start);
done();

@@ -469,4 +686,4 @@ });

it('should provide an end timestamp', function(done) {
assert(typeof stats.end === 'number');
assert(stats.end >= stats.start);
assert(typeof result.stats.end === 'number');
assert(result.stats.end >= result.stats.start);
done();

@@ -476,4 +693,4 @@ });

it('should provide a duration', function(done) {
assert(typeof stats.duration === 'number');
assert.equal(stats.end - stats.start, stats.duration);
assert(typeof result.stats.duration === 'number');
assert.equal(result.stats.end - result.stats.start, result.stats.duration);
done();

@@ -483,3 +700,3 @@ });

it('should contain the given entry file', function(done) {
assert.equal(stats.entry, resolveFixture('include-files/index.scss'));
assert.equal(result.stats.entry, resolveFixture('include-files/index.scss'));
done();

@@ -495,5 +712,5 @@ });

assert.equal(stats.includedFiles[0], expected[0]);
assert.equal(stats.includedFiles[1], expected[1]);
assert.equal(stats.includedFiles[2], expected[2]);
assert.equal(result.stats.includedFiles[0], expected[0]);
assert.equal(result.stats.includedFiles[1], expected[1]);
assert.equal(result.stats.includedFiles[2], expected[2]);
done();

@@ -505,8 +722,7 @@ });

sass.renderSync({
file: fixture('simple/index.scss'),
stats: stats
var result = sass.renderSync({
file: fixture('simple/index.scss')
});
assert.deepEqual(stats.includedFiles, [expected]);
assert.deepEqual(result.stats.includedFiles, [expected]);
done();

@@ -516,8 +732,7 @@ });

it('should state `data` as entry file', function(done) {
sass.renderSync({
data: read(fixture('simple/index.scss'), 'utf8'),
stats: stats
var result = sass.renderSync({
data: read(fixture('simple/index.scss'), 'utf8')
});
assert.equal(stats.entry, 'data');
assert.equal(result.stats.entry, 'data');
done();

@@ -527,31 +742,21 @@ });

it('should contain an empty array as includedFiles', function(done) {
sass.renderSync({
data: read(fixture('simple/index.scss'), 'utf8'),
stats: stats
var result = sass.renderSync({
data: read(fixture('simple/index.scss'), 'utf8')
});
assert.deepEqual(stats.includedFiles, []);
assert.deepEqual(result.stats.includedFiles, []);
done();
});
});
it('should report correct source map in stats', function(done) {
sass.renderSync({
file: fixture('simple/index.scss'),
outFile: fixture('simple/build.css'),
stats: stats,
sourceMap: true
});
describe('.info()', function() {
it('should return a correct version info', function(done) {
assert.equal(sass.info(), [
'node-sass version: ' + require('../package.json').version,
'libsass version: ' + require('../package.json').libsass
].join('\n'));
var map = JSON.parse(stats.sourceMap);
assert.equal(map.sources[0], 'index.scss');
done();
});
});
describe('.middleware()', function() {
it('should throw error on require', function(done) {
assert.throws(sass.middleware());
done();
});
});
});

@@ -226,2 +226,104 @@ var assert = require('assert'),

});
describe('importer', function() {
var dest = fixture('include-files/index.css');
var src = fixture('include-files/index.scss');
var expected = read(fixture('include-files/expected-importer.css'), 'utf8').trim().replace(/\r\n/g, '\n');
it('should override imports and fire callback with file and contents', function(done) {
var bin = spawn(cli, [
src, '--output', path.dirname(dest),
'--importer', fixture('extras/my_custom_importer_file_and_data_cb.js')
]);
bin.on('close', function () {
assert.equal(read(dest, 'utf8').trim(), expected);
fs.unlinkSync(dest);
done();
});
});
it('should override imports and fire callback with file', function(done) {
var bin = spawn(cli, [
src, '--output', path.dirname(dest),
'--importer', fixture('extras/my_custom_importer_file_cb.js')
]);
bin.on('close', function () {
if (fs.existsSync(dest)) {
assert.equal(read(dest, 'utf8').trim(), '');
fs.unlinkSync(dest);
}
done();
});
});
it('should override imports and fire callback with data', function(done) {
var bin = spawn(cli, [
src, '--output', path.dirname(dest),
'--importer', fixture('extras/my_custom_importer_data_cb.js')
]);
bin.on('close', function () {
assert.equal(read(dest, 'utf8').trim(), expected);
fs.unlinkSync(dest);
done();
});
});
it('should override imports and return file and contents', function(done) {
var bin = spawn(cli, [
src, '--output', path.dirname(dest),
'--importer', fixture('extras/my_custom_importer_file_and_data.js')
]);
bin.on('close', function () {
assert.equal(read(dest, 'utf8').trim(), expected);
fs.unlinkSync(dest);
done();
});
});
it('should override imports and return file', function(done) {
var bin = spawn(cli, [
src, '--output', path.dirname(dest),
'--importer', fixture('extras/my_custom_importer_file.js')
]);
bin.on('close', function () {
if (fs.existsSync(dest)) {
assert.equal(read(dest, 'utf8').trim(), '');
fs.unlinkSync(dest);
}
done();
});
});
it('should override imports and return data', function(done) {
var bin = spawn(cli, [
src, '--output', path.dirname(dest),
'--importer', fixture('extras/my_custom_importer_data.js')
]);
bin.on('close', function () {
assert.equal(read(dest, 'utf8').trim(), expected);
fs.unlinkSync(dest);
done();
});
});
it('should return error on for invalid importer file path', function(done) {
var bin = spawn(cli, [
src, '--output', path.dirname(dest),
'--importer', fixture('non/existing/path')
]);
bin.on('close', function (code) {
assert(code !== 0);
done();
});
});
});
});

@@ -43,4 +43,4 @@ var assert = require('assert'),

includePaths: t.paths,
success: function(css) {
assert.equal(util.normalize(css), expected);
success: function(result) {
assert.equal(util.normalize(result.css), expected);
done();

@@ -47,0 +47,0 @@ },

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc