-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathcallback-loader.js
64 lines (56 loc) · 2.14 KB
/
callback-loader.js
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
var astQuery = require('ast-query');
var loaderUtils = require('loader-utils');
var escodegen = require('escodegen');
module.exports = function (source) {
var self = this;
var query = loaderUtils.parseQuery(this.query);
var configKey = query.config || 'callbackLoader';
var cacheable = (typeof query.cacheable !== 'undefined') ? query.cacheable : true;
if (cacheable) {
this.cacheable();
}
//Disabling async mode for this loader.
this.async = function() {};
var functions = this.options[configKey];
var functionNames = Object.keys(query).filter(function (key) {
return (key !== 'config') && (key !== 'cacheable');
});
if (functionNames.length === 0) {
functionNames = Object.keys(functions);
}
//Offset for future replaces
var indexOffset;
//Replace substring between *indexFrom* and *indexTo* in *text* with *replaceText*
function replaceIn(text, indexFrom, indexTo, replaceText) {
var actualIndexFrom = indexFrom + indexOffset;
var actualIndexTo = indexTo + indexOffset;
//Correcting the offset
indexOffset = indexOffset + replaceText.length - (indexTo - indexFrom);
return text.substr(0, actualIndexFrom) + replaceText + text.substr(actualIndexTo, text.length);
}
functionNames.forEach(function (funcName) {
var ast = astQuery(source);
var query = ast.callExpression(funcName);
indexOffset = 0;
query.nodes.forEach(function (node) {
var args = node.arguments.map(function (argument) {
if (argument.type == 'Literal') {
return argument.value;
} else if (argument.type == 'ObjectExpression') {
var value = escodegen.generate(argument, {format: {json: true}});
// Take the keys of the object to quotes for JSON.parse
value = value.replace(/([{,])(?:\s*)([A-Za-z0-9_\-]+?)\s*:/g, '$1"$2":');
value = JSON.parse(value);
return value;
} else {
var msg = 'Error when parsing arguments of function ' + funcName + '. Only absolute values accepted. Index: ' + argument.range[0];
console.error(msg);
throw msg;
}
});
var value = functions[funcName].apply(self, args);
source = replaceIn(source, node.range[0], node.range[1], value.toString());
});
});
return source;
};