-
Notifications
You must be signed in to change notification settings - Fork 2
/
util.js
96 lines (84 loc) · 2.51 KB
/
util.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
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
95
96
const fs = require('fs')
const path = require('path')
// 转义正则中的特殊字符
function escapeForRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
}
// 判断是否是对象
function isObject(obj) {
// incase of arrow function and array
return Object(obj) === obj && typeof obj !== 'function' && !Array.isArray(obj)
}
// 判断是否是string
function isString(str) {
return typeof str === 'string' || str instanceof String
}
// 判断是否为空
// '', {}, [], 0, null, undefined, false
function isEmpty(obj) {
if(Array.isArray(obj)) {
return obj.length === 0
} if(isObject(obj)) {
return Object.keys(obj).length === 0
}
return !obj
}
// 在上下文中调用eval
function evalWithApiContext(withContext, apiContext, str) {
with(withContext) {
let ret
try {
ret = eval(str);
} catch(e) {
apiContext.emitError('变量表达式执行错误')
apiContext.emitError(e)
ret = ''
}
return ret
}
}
// 是否是个纯的变量: 不包含条件表达式
function isPureVar(varName) {
return !(varName.includes('?') && varName.includes(':'))
}
// 替换include
function replaceIncludeRecursive({
apiContext, content, includeRE, variableRE, pathRelative, maxIncludes,
}) {
return content.replace(includeRE, (match, quotationStart, filePathStr, argsStr) => {
let args = {}
try {
if(argsStr) {
args = JSON.parse(argsStr)
}
} catch (e) {
apiContext.emitError(new Error('传入参数格式错误,无法进行JSON解析成'))
}
const filePath = path.resolve(pathRelative, filePathStr)
const fileContent = fs.readFileSync(filePath, {encoding: 'utf-8'})
apiContext.addDependency(filePath)
// 先替换当前文件内的变量
const fileContentReplacedVars = fileContent.replace(variableRE, (matchedVar, variable) => {
// 如果属性存在,则直接返回,说明为简单变量
if(args[variable]) {
return args[variable]
}
if(isPureVar(variable)) return ''
// 否则尝试下执行传入的变量,并返回值
return evalWithApiContext(args, apiContext, variable)
})
if(--maxIncludes > 0 && includeRE.test(fileContent)) {
return replaceIncludeRecursive({
apiContext, content: fileContentReplacedVars, includeRE, variableRE, pathRelative: path.dirname(filePath), maxIncludes,
})
}
return fileContentReplacedVars
})
}
module.exports = {
escapeForRegExp,
isObject,
isString,
isEmpty,
replaceIncludeRecursive,
}