-
Notifications
You must be signed in to change notification settings - Fork 57
Expand file tree
/
Copy pathindex.js
More file actions
94 lines (79 loc) · 2.83 KB
/
index.js
File metadata and controls
94 lines (79 loc) · 2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import _ from 'lodash';
import isThere from 'is-there';
import path, {resolve, basename, extname} from 'path';
import 'json5/lib/register'; // Enable JSON5 support
export default function(options = {}) {
return function(url, prev) {
if (!isJSONfile(url)) {
return null;
}
let includePaths = this.options.includePaths ? this.options.includePaths.split(path.delimiter) : [];
let paths = []
.concat(prev.slice(0, prev.lastIndexOf('/')))
.concat(includePaths);
const resolver = options.resolver || resolve;
let fileName = paths
.map(path => resolver(path, url))
.filter(isThere)
.pop();
if (!fileName) {
return new Error(`Unable to find "${url}" from the following path(s): ${paths.join(', ')}. Check includePaths.`);
}
// Prevent file from being cached by Node's `require` on continuous builds.
// https://github.com/Updater/node-sass-json-importer/issues/21
delete require.cache[require.resolve(fileName)];
try {
const fileContents = require(fileName);
const extensionlessFilename = basename(fileName, extname(fileName));
const json = Array.isArray(fileContents) ? { [extensionlessFilename]: fileContents } : fileContents;
return {
contents: transformJSONtoSass(json),
file: fileName,
};
} catch(error) {
return new Error(`node-sass-json-importer: Error transforming JSON/JSON5 to SASS. Check if your JSON/JSON5 parses correctly. ${error}`);
}
}
}
export function isJSONfile(url) {
return /\.json5?$/.test(url);
}
export function transformJSONtoSass(json) {
return Object.keys(json)
.filter(key => isValidKey(key))
.filter(key => json[key] !== '#')
.map(key => `$${key}: ${parseValue(json[key])};`)
.join('\n');
}
export function isValidKey(key) {
return /^[^$@:].*/.test(key)
}
export function parseValue(value) {
if (_.isArray(value)) {
return parseList(value);
} else if (_.isPlainObject(value)) {
return parseMap(value);
} else if (value === '') {
return '""'; // Return explicitly an empty string (Sass would otherwise throw an error as the variable is set to nothing)
} else {
return value;
}
}
export function parseList(list) {
const listContent = list
.map(value => parseValue(value))
.join(',');
return listContent ? `(${listContent},)` : `()`;
}
export function parseMap(map) {
return `(${Object.keys(map)
.filter(key => isValidKey(key))
.map(key => `${key}: ${parseValue(map[key])}`)
.join(',')})`;
}
// Super-hacky: Override Babel's transpiled export to provide both
// a default CommonJS export and named exports.
// Fixes: https://github.com/Updater/node-sass-json-importer/issues/32
// TODO: Remove in 3.0.0. Upgrade to Babel6.
module.exports = exports.default;
Object.keys(exports).forEach(key => module.exports[key] = exports[key]);