-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
60 lines (49 loc) · 1.64 KB
/
index.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
'use strict';
/**
* Make a step in ast
*
* @param {Ast|undefined} ast
* @param {String|Number} step
*
* @returns {Ast|undefined}
*/
function stepInto(ast, step) {
if (typeof ast === 'undefined') return;
// index step in array
if (typeof step === 'number' && ast.type === 'ArrayExpression') {
return ast.elements[step];
}
// property step in object
if (typeof step === 'string' && ast.type === 'ObjectExpression') {
const itemProperty = ast.properties.find(property => {
const key = property.key;
return (key.type === 'Identifier' && key.name === step) ||
(key.type === 'Literal' && key.value === step);
});
return itemProperty && itemProperty.value;
}
}
module.exports = {
_jsonParse: require('./lib/json-parser'),
_jsonPathParse: require('./lib/json-path-parser'),
/**
* Returns line/column location of path in json
*
* @param {String} jsExpression
* @param {Array.<String|Number>|String} path - path in json like '["prop1", 1, "prop2"]' or 'prop1[1].prop2'
*
* @returns {AstLocation}
*/
getLocationOf: function(jsExpression, path) {
const parsedPath = Array.isArray(path) ? path : this._jsonPathParse(path),
beginAst = this._jsonParse(jsExpression);
if (typeof beginAst === 'undefined') {
throw new Error('invalid source');
}
const endAst = parsedPath.reduce(stepInto, beginAst);
if (typeof endAst === 'undefined') {
throw new Error('unexpected end of path ' + JSON.stringify(path));
}
return endAst.loc.start;
}
};