New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

gulp-shopify-sass

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

gulp-shopify-sass - npm Package Compare versions

Comparing version 0.3.1 to 0.3.2

lib/compiler.js

219

index.js
'use strict';
var through = require('through2');
var path = require('path');
var gutil = require('gulp-util');
var PluginError = gutil.PluginError;
var vfile = require('vinyl-file');
var vinyl = require('vinyl');
var fs = require('fs');
var path = require('path');
var gutil = require('gulp-util');
var through = require('through2');
var clonedeep = require('lodash.clonedeep');
const PLUGIN_NAME = 'gulp-shopify-sass';
// @param: dir full path and name
// @return: boolean
function checkFileExist (dir) {
try {
fs.accessSync(dir , fs.F_OK);
return true;
} catch (e) {
return false;
}
}
/*
* Most of the code in index.js are copied from gulp-sass
*/
// @param: dir full path and name
// @return: string | boolean
function analyseDir (dir) {
// possible extension array
const dirReg = new RegExp(/(.+\/)(.+)$/, 'g');
const filenameReg = new RegExp(/^(\_)?(?:(.*(?=.scss))(.*)|(.*))$/, 'i');
//////////////////////////////
// Main Gulp Shopify Sass function
//////////////////////////////
var gulpShopifySass = function gulpShopifySass (options, sync) {
return through.obj(function (file, enc, cb) {
// split whole path into path the filename
let pathAndName = dirReg.exec(dir);
var opts, contents;
const filepath = pathAndName[1] || '';
let filename = pathAndName[2] || '';
if (file.isNull()) {
return cb(null, file);
}
// [0] original filename
// [1] '_' if exist in the filename, otherwise undefined
// [2] filename if it has extension .scss or .scss.liquid, otherwise undefined
// [3] file extension if filename has extionsion .scss or .scss.liquid, otherwise undefined
// [4] filename if it doesn't have extension, otherwise undefined
let filenameFrags = filenameReg.exec(filename);
// do not support stream
if(file.isStream()) {
return cb(new gutil.PluginError(PLUGIN_NAME, 'Streaming not supported!'));
}
// move filename[4] to filename[2] if filename[2] is undefined
filenameFrags[2] = filenameFrags[2] || filenameFrags[4];
//////////////////////////////
// Handles returning the file to the stream
//////////////////////////////
var filePush = function filePush(contents) {
// console.log(file);
// console.log(file.contents);
// console.log(contents);
// file = new gutil.File({
// 'cwd': __dirname,
// 'base': file.base,
// 'path': gutil.replaceExtension(file.path, '.cat.scss.liquid'),
// 'contents': contents
// });
// remove original name, all index will reduce 1
filenameFrags.shift();
file.contents = new Buffer(contents);
file.path = gutil.replaceExtension(file.path, '.cat.scss.liquid');
// remove filename[4] since it's been moved to [2]
filenameFrags.pop()
cb(null, file);
};
// [0] was [1], [2] was [3]
let prefix = filenameFrags[0] ? [filenameFrags[0]] : ['', '_'];
let suffix = filenameFrags[2] ? [filenameFrags[2]] : ['.scss', '.scss.liquid'];
let allCombinations = [];
//////////////////////////////
// Handles error message
//////////////////////////////
var errorM = function errorM(error) {
var relativePath = '',
filePath = error.file === 'stdin' ? file.path : error.file,
message = '';
// check all possible combimations
for (let i in prefix) {
for (let j in suffix) {
filenameFrags[0] = prefix[i];
filenameFrags[2] = suffix[j];
filename = filenameFrags.join('');
filePath = filePath ? filePath : file.path;
relativePath = path.relative(process.cwd(), filePath);
pathAndName = path.join(filepath, filename);
message += gutil.colors.underline(relativePath) + '\n';
message += error.formatted;
if (checkFileExist(pathAndName)) {
return pathAndName;
}
}
}
error.messageFormatted = message;
error.messageOriginal = error.message;
// error.message = gutil.colors.stripColor(message);
gutil.log('File to import: "' + dir + '" not found.');
error.relativePath = relativePath;
return false;
}
return cb(new gutil.PluginError(
PLUGIN_NAME, error
));
};
// processing buffer
if(file.isBuffer()) {
//////////////////////////////
// gulpShopifySass main process BEGIN
//////////////////////////////
function importReplacer (file) {
opts = clonedeep(options || {});
opts.data = file.contents.toString();
var rex = /@import\s*(?:(?:'([^']+)')|(?:"([^"]+)"))\s*;/gi;
var fileContents = file.contents.toString();
var fileDirname = path.dirname(file.path);
var imports = {};
var match;
// we set the file path here so that libsass can correctly resolve import paths
opts.file = file.path;
while(match = rex.exec(fileContents)) {
// TODO: add includePaths feature in options and relavent processer
// [1] single quotes
// [2] double quotes
var importFile = path.join(fileDirname, (match[1] || match[2]));
// Ensure file's parent directory in the include path
// if (opts.includePaths) {
// if (typeof opts.includePaths === 'string') {
// opts.includePaths = [opts.includePaths];
// }
// } else {
// opts.includePaths = [];
// }
const fileExistCheck = analyseDir(importFile);
// opts.includePaths.unshift(path.dirname(file.path));
// if file exists, replace it
if(fileExistCheck) {
imports[match[0]] = fileExistCheck;
}
// TDDO: enable sync option once async render is done. Only support renderSync for now
// if (sync === true) {
//////////////////////////////
// Sync Sass render
//////////////////////////////
}
try {
contents = gulpShopifySass.compiler.renderSync(opts);
for(let imp in imports) {
// replace @import with import file contents
fileContents = fileContents.replace(new RegExp(imp, 'g'), importReplacer(vfile.readSync(imports[imp])).contents.toString());
}
filePush(contents);
} catch (error) {
return errorM(error);
}
file.contents = new Buffer(fileContents);
// } else {
// //////////////////////////////
// // Async Sass render
// //////////////////////////////
// var callback = function(error, catFile) {
// if (error) {
// return errorM(error);
// }
// filePush(catFile);
// };
return file;
// gulpShopifySass.compiler.render(opts, callback);
// }
//////////////////////////////
// gulpShopifySass main process END
//////////////////////////////
}
});
}
module.exports = function () {
return through.obj(function (file, enc, cb) {
//////////////////////////////
// Sync Shopify Sass render
//////////////////////////////
// do not support stream
if(file.isStream()) {
this.emit('error', new PluginError(PLUGIN_NAME, 'Streams are not supported!'));
return cb();
}
// TDDO: enable sync option once async render is done. Only support renderSync for now
// processing buffer
if(file.isBuffer()) {
importReplacer(file);
}
// gulpShopifySass.sync = function sync(options) {
// return gulpShopifySass(options, true);
// };
this.push(file);
//////////////////////////////
// Log errors nicely
//////////////////////////////
gulpShopifySass.logError = function logError(error) {
var message = new gutil.PluginError('sass', error.messageFormatted).toString();
process.stderr.write(message + '\n');
this.emit('end');
};
cb();
});
}
//////////////////////////////
// Store compiler in a prop
//////////////////////////////
gulpShopifySass.compiler = require('./lib/compiler');
module.exports = gulpShopifySass;
{
"name": "gulp-shopify-sass",
"version": "0.3.1",
"version": "0.3.2",
"description": "Concatenate Sass files defined by the @import order",

@@ -28,3 +28,6 @@ "main": "./index.js",

"gulp": "^3.9.0",
"lodash.clonedeep": "^4.5.0",
"mocha": "^2.3.4",
"pegjs": "^0.10.0",
"pegjs-util": "^1.3.5",
"should": "^8.1.1",

@@ -31,0 +34,0 @@ "stream-array": "^1.1.1",

@@ -17,20 +17,25 @@ # gulp-shopify-sass [![Build Status](https://travis-ci.org/theJian/gulp-shopify-sass.svg?branch=master)](https://travis-ci.org/theJian/gulp-shopify-sass)

@import 'path-to-file/name';
@import 'path-to-file/_name';
@import 'path-to-file/name.scss';
@import 'path-to-file/_name.scss';
```javascript
@import 'path-to-file/name';
@import 'path-to-file/_name';
@import 'path-to-file/name.scss';
@import 'path-to-file/_name.scss';
```
All of above will have the same result.
```javascript
'use strict';
var gulp = require('gulp');
var gss = require('gulp-shopify-sass');
var gulp = require('gulp');
var gss = require('gulp-shopify-sass');
gulp.task('default', function() {
return gulp.src('./*.scss')
.pipe(gss());
});
gulp.task('default', function() {
return gulp.src('./*.scss')
.pipe(gss())
.pipe(gulp.dest('./path/to/dist'));
});
```
# License
MIT license
MIT license

@@ -5,89 +5,204 @@ var assert = require('stream-assert');

var gulp = require('gulp');
var path = require('path');
var gutil = require('gulp-util');
var fs = require('fs');
var gulpShopifySass = require('../index');
var test = require('./test-stream');
describe('gulp-shopify-sass', function () {
describe('in buffer mode', function () {
var createVinyl = function createVinyl(filename, contents) {
var base = path.join(__dirname, 'fixtures', 'scss');
var filePath = path.join(base, filename);
return new gutil.File({
'cwd': __dirname,
'base': base,
'path': filePath,
'contents': contents || fs.readFileSync(filePath)
});
};
it('skip files doesn\'t exist', function (done) {
test('@import "foo.scss";')
.pipe(gulpShopifySass())
.pipe(assert.length(1))
.pipe(assert.first(function(f){f.contents.toString().should.equal('@import "foo.scss";')}))
.pipe(assert.end(done));
describe('gulp-shopify-sass', function() {
it('skip files doesn\'t exist', function(done) {
var stream = gulpShopifySass();
var emptyFile = {
'isNull': function() {
return true;
}
};
stream.on('data', function (data) {
data.should.equal(emptyFile);
done();
});
stream.write(emptyFile);
});
it('work on single sass file', function (done) {
test('.class-name{}')
.pipe(gulpShopifySass())
.pipe(assert.length(1))
.pipe(assert.first(function(f){f.contents.toString().should.equal('.class-name{}')}))
.pipe(assert.end(done));
it('should emit error when file isStream()', function(done) {
var stream = gulpShopifySass();
var streamFile = {
'isNull': function() {
return false;
},
'isStream': function() {
return true;
}
};
stream.on('error', function (err) {
err.message.should.equal('Streaming not supported!');
done();
});
stream.write(streamFile);
});
// it('replace import on single file', function (done) {
// test('@import "file1.scss";', '.class-name{}')
// .pipe(gulpShopifySass())
// .pipe(assert.length(2))
// .pipe(assert.first(function(f){f.contents.toString().should.equal('.class-name{}')}))
// .pipe(assert.end(done));
// });
it('should compile an empty sass file', function(done) {
var sassFile = createVinyl('empty.scss');
var stream = gulpShopifySass();
// it('replace import recursively', function (done) {
// test('@import "file1.scss";', '@import "file2.scss";', '.class-name{}')
// .pipe(gulpShopifySass())
// .pipe(assert.length(3))
// .pipe(assert.first(function(f){f.contents.toString().should.equal('.class-name{}')}))
// .pipe(assert.end(done));
// });
stream.on('data', function(catScssFile) {
should.exist(catScssFile);
should.exist(catScssFile.path);
should.exist(catScssFile.relative);
should.exist(catScssFile.contents);
should.equal(path.basename(catScssFile.path), 'empty.cat.scss.liquid');
String(catScssFile.contents).should.equal('');
done();
});
it('replace import', function (done) {
gulp.src('./test/fixtures/b.scss')
.pipe(gulpShopifySass())
.pipe(assert.length(1))
.pipe(assert.first(function(f){f.contents.toString().should.equal('.class-name {}')}))
.pipe(assert.end(done));
stream.write(sassFile);
});
it('replace import recursively', function (done) {
gulp.src('./test/fixtures/c.scss')
.pipe(gulpShopifySass())
.pipe(assert.length(1))
.pipe(assert.first(function(f){f.contents.toString().should.equal('.class-name {}')}))
.pipe(assert.end(done));
it('work on single sass file', function(done) {
var sassFile = createVinyl('_single.scss');
var stream = gulpShopifySass();
stream.on('data', function(catScssFile) {
should.exist(catScssFile);
should.exist(catScssFile.path);
should.exist(catScssFile.relative);
should.exist(catScssFile.contents);
should.equal(path.basename(catScssFile.path), '_single.cat.scss.liquid');
String(catScssFile.contents).should.equal(
fs.readFileSync(path.join(__dirname, 'fixtures', 'scss', '_single.scss'), 'utf8')
);
done();
});
stream.write(sassFile);
});
it('replace multiple import', function (done) {
gulp.src('./test/fixtures/d.scss')
.pipe(gulpShopifySass())
.pipe(assert.length(1))
.pipe(assert.first(function(f){f.contents.toString().should.equal('.class-name {}\n.class-name {}')}))
.pipe(assert.end(done));
it('should replace import', function(done) {
var sassFile = createVinyl('import.scss');
var stream = gulpShopifySass();
stream.on('data', function(catScssFile) {
should.exist(catScssFile);
should.exist(catScssFile.path);
should.exist(catScssFile.relative);
should.exist(catScssFile.contents);
should.equal(path.basename(catScssFile.path), 'import.cat.scss.liquid');
String(catScssFile.contents).should.equal(
fs.readFileSync(path.join(__dirname, 'fixtures', 'scss', '_single.scss'), 'utf8')
);
done();
});
stream.write(sassFile);
});
it('replace multiple types of import', function (done) {
gulp.src('./test/fixtures/e.scss')
.pipe(gulpShopifySass())
.pipe(assert.length(1))
.pipe(assert.first(function(f){f.contents.toString().should.equal('.class-name {}\n.class-name {}\n.class-name {}\n.class-name {}')}))
.pipe(assert.end(done));
it('replace import recursively', function(done) {
var sassFile = createVinyl('recursive.scss');
var stream = gulpShopifySass();
stream.on('data', function(catScssFile) {
should.exist(catScssFile);
should.exist(catScssFile.path);
should.exist(catScssFile.relative);
should.exist(catScssFile.contents);
should.equal(path.basename(catScssFile.path), 'recursive.cat.scss.liquid');
String(catScssFile.contents).should.equal(
fs.readFileSync(path.join(__dirname, 'fixtures', 'scss', '_single.scss'), 'utf8')
);
done();
});
stream.write(sassFile);
});
it('replace import .scss.liquid', function (done) {
gulp.src('./test/fixtures/f.scss')
.pipe(gulpShopifySass())
.pipe(assert.length(1))
.pipe(assert.first(function(f){f.contents.toString().should.equal('.dash {}\n.dash {}\n.dash {}\n.dash {}')}))
.pipe(assert.end(done));
it('replace multiple import', function(done) {
var sassFile = createVinyl('multiple.scss');
var stream = gulpShopifySass();
stream.on('data', function(catScssFile) {
should.exist(catScssFile);
should.exist(catScssFile.path);
should.exist(catScssFile.relative);
should.exist(catScssFile.contents);
should.equal(path.basename(catScssFile.path), 'multiple.cat.scss.liquid');
String(catScssFile.contents).should.equal(
fs.readFileSync(path.join(__dirname, 'fixtures', 'expected', 'multiple.cat.scss.liquid'), 'utf8')
);
done();
});
stream.write(sassFile);
});
it('do not import .scss.liquid if .scss exist', function (done) {
gulp.src('./test/fixtures/g.scss')
.pipe(gulpShopifySass())
.pipe(assert.length(1))
.pipe(assert.first(function(f){f.contents.toString().should.equal('.class-name {}\n.class-name {}')}))
.pipe(assert.end(done));
it('replace import with different name variations', function(done) {
var sassFile = createVinyl('variations.scss');
var stream = gulpShopifySass();
stream.on('data', function(catScssFile) {
should.exist(catScssFile);
should.exist(catScssFile.path);
should.exist(catScssFile.relative);
should.exist(catScssFile.contents);
should.equal(path.basename(catScssFile.path), 'variations.cat.scss.liquid');
String(catScssFile.contents).should.equal(
fs.readFileSync(path.join(__dirname, 'fixtures', 'expected', 'variations.cat.scss.liquid'), 'utf8')
);
done();
});
stream.write(sassFile);
});
});
});
it('replace import .scss.liquid', function(done) {
var sassFile = createVinyl('import.liquid.scss');
var stream = gulpShopifySass();
stream.on('data', function(catScssFile) {
should.exist(catScssFile);
should.exist(catScssFile.path);
should.exist(catScssFile.relative);
should.exist(catScssFile.contents);
should.equal(path.basename(catScssFile.path), 'import.liquid.cat.scss.liquid');
String(catScssFile.contents).should.equal(
fs.readFileSync(path.join(__dirname, 'fixtures', 'expected', 'import.liquid.cat.scss.liquid'), 'utf8')
);
done();
});
stream.write(sassFile);
});
it('do not import .scss.liquid if .scss exist', function(done) {
var sassFile = createVinyl('extensionOverride.scss');
var stream = gulpShopifySass();
stream.on('data', function(catScssFile) {
should.exist(catScssFile);
should.exist(catScssFile.path);
should.exist(catScssFile.relative);
should.exist(catScssFile.contents);
should.equal(path.basename(catScssFile.path), 'extensionOverride.cat.scss.liquid');
String(catScssFile.contents).should.equal(
fs.readFileSync(path.join(__dirname, 'fixtures', 'expected', 'extentionOverride.cat.scss.liquid'), 'utf8')
);
done();
});
stream.write(sassFile);
});
});
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