├── .gitignore ├── LICENSE ├── README.md ├── bstudio-sass.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.txt 3 | *.log -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Bootstrap Studio 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bootstrap Studio SASS sidekick 2 | 3 | `bstudio-sass` is a helper utility for compiling SASS in Bootstrap Studio. To use it, install it on your local machine and configure Bootstrap Studio to know where to find it. It runs on Windows, MacOS and Linux. 4 | 5 | ## Installation 6 | 7 | To install `bstudio-sass`, make sure that you have node.js 8.0 or later, and follow the steps outlined in [our tutorial](https://bootstrapstudio.io/tutorials/writing-sass). 8 | 9 | ## Troubleshooting 10 | 11 | If you run `bstudio-sass` and see a *command not found* error, this would mean that the utility is not installed correctly. Make sure that it is installed globally with the `-g` flag. If it still doesn't work, maybe node is not installed correctly or your system needs a restart. 12 | 13 | ## License 14 | 15 | This project is licensed uner the MIT license. 16 | 17 | ## Bug reports 18 | 19 | If you notice any bugs, please [report them here](https://bootstrapstudio.io/bug-report). -------------------------------------------------------------------------------- /bstudio-sass.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | let sass = require('node-sass'); 4 | let path = require('path'); 5 | let readline = require('readline'); 6 | 7 | if (process.stdin.isTTY) { 8 | 9 | console.log('bstudio-sass is Bootstrap Studio\'s sidekick for compiling SASS files.'); 10 | console.log('To link this utility to Bootstrap Studio, please use the following path:'); 11 | 12 | var cmd = process.argv[1]; 13 | 14 | if (process.platform == 'win32') { 15 | cmd = cmd.replace('\\node_modules\\bstudio-sass\\bstudio-sass.js', '\\bstudio-sass'); 16 | } 17 | 18 | console.log(cmd); 19 | 20 | process.exit(); 21 | } 22 | 23 | let supportedVersions = { 24 | inputMessage: 1, 25 | outputMessage: 1 26 | }; 27 | 28 | var rl = readline.createInterface({ 29 | input: process.stdin, 30 | output: process.stdout, 31 | terminal: false 32 | }); 33 | 34 | process.chdir('/'); 35 | 36 | rl.on('line', function(data){ 37 | 38 | let message = {}; 39 | 40 | try { 41 | 42 | message = JSON.parse(data); 43 | 44 | if (!message.version || message.version > supportedVersions.inputMessage) { 45 | throw new Error('This message format is not supported. Please update bstudio-sass.'); 46 | } 47 | 48 | if (!message.files || typeof message.files != 'object') { 49 | throw new Error('Missing or invalid file entry.'); 50 | } 51 | 52 | // Compile all regular sass files 53 | 54 | let result = {}; 55 | 56 | for (let filePath in message.files) { 57 | 58 | if (/^_/.test(path.basename(filePath))) { 59 | // SASS partial. Skip compilation. 60 | continue; 61 | } 62 | 63 | let render = sass.renderSync({ 64 | file: filePath, 65 | data: message.files[filePath] || ' ', 66 | outputStyle: 'expanded', 67 | importer: function(url, prev) { 68 | 69 | if (/^https?:\/\//.test(url)) { 70 | // Leave URLs as is 71 | return null; 72 | } 73 | 74 | // Compensating for libsass' insistence on prepending 75 | // paths with the current working directory. Also, 76 | // normalizing Windows path separators. 77 | 78 | let resolvedPath = path.resolve(path.dirname(prev), url).replace(process.cwd(), '/').replace(/\\/g, '/'); 79 | 80 | if (path.extname(resolvedPath) != 'scss') { 81 | resolvedPath += '.scss'; 82 | } 83 | 84 | let underScorePath = path.dirname(resolvedPath) + '/_' + path.basename(resolvedPath); 85 | underScorePath = underScorePath.replace(/\/+/g, '/'); 86 | 87 | if (underScorePath in message.files) { 88 | resolvedPath = underScorePath; 89 | } 90 | 91 | if (!(resolvedPath in message.files)) { 92 | return new Error('File to import not found: ' + resolvedPath.slice(1)); 93 | } 94 | 95 | return { 96 | file: resolvedPath, 97 | contents: message.files[resolvedPath] 98 | }; 99 | } 100 | }); 101 | 102 | result[filePath] = render.css.toString(); 103 | } 104 | 105 | output({ 106 | version: supportedVersions.outputMessage, 107 | jobID: message.jobID, 108 | result: result 109 | }); 110 | 111 | } 112 | catch (e){ 113 | 114 | if (e.formatted) { 115 | errorAndExit( 116 | 'SASS Compilation Error', 117 | e.message, 118 | message.jobID, 119 | { 120 | formatted: e.formatted, 121 | file: e.file ? 122 | e.file.replace(process.cwd(), '/').replace(/\\/g, '/').slice(1): 123 | null, 124 | line: e.line, 125 | column: e.column 126 | } 127 | ); 128 | } 129 | 130 | errorAndExit('Invalid message format', e.message, message.jobID); 131 | } 132 | 133 | }); 134 | 135 | function output(message) { 136 | console.log(JSON.stringify(message)); 137 | } 138 | 139 | function errorAndExit(short, long, jobID, data = {}) { 140 | outputAndExit({ 141 | status: 'error', 142 | short: short, 143 | long: long || '', 144 | jobID: jobID, 145 | data: data 146 | }); 147 | } 148 | 149 | function outputAndExit(message) { 150 | console.log(JSON.stringify(message)); 151 | process.exit(); 152 | } 153 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bstudio-sass", 3 | "version": "1.0.3", 4 | "description": "Bootstrap Studio SASS Compilation Sidekick", 5 | "main": "bstudio-sass.js", 6 | "bin": { 7 | "bstudio-sass": "bstudio-sass.js" 8 | }, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/bootstrapstudio/bstudio-sass.git" 15 | }, 16 | "keywords": [ 17 | "bootstrap", 18 | "studio", 19 | "command", 20 | "line" 21 | ], 22 | "author": "Zine EOOD (https://zine.bg/)", 23 | "license": "MIT", 24 | "engines" : { "node" : ">=8.0.0" }, 25 | "bugs": { 26 | "url": "https://bootstrapstudio.io/bug-report" 27 | }, 28 | "homepage": "https://github.com/bootstrapstudio/bstudio-sass", 29 | "dependencies": { 30 | "node-sass": "^4.7.2" 31 | } 32 | } 33 | --------------------------------------------------------------------------------