This repository was archived by the owner on Aug 15, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 604
Expand file tree
/
Copy pathindex.js
More file actions
executable file
·148 lines (132 loc) · 4.51 KB
/
index.js
File metadata and controls
executable file
·148 lines (132 loc) · 4.51 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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
(function() {
var JsPath,
__slice = Array.prototype.slice;
module.exports = JsPath = (function() {
var primTypes,
_this = this;
primTypes = /^(string|number|boolean)$/;
/*
@constructor.
@signature: new JsPath(path, val)
@param: path - a dot-notation style "path" to identify a
nested JS object.
@description: Initialize a new js object with the provided
path. I've never actually used this constructor for any-
thing, and it is here for the sake of "comprehensiveness"
at this time, although I am incredulous as to it's overall
usefulness.
*/
function JsPath(path, val) {
return JsPath.setAt({}, path, val || {});
}
['forEach', 'indexOf', 'join', 'pop', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'push'].forEach(function(method) {
return JsPath[method + 'At'] = function() {
var obj, path, rest, target;
obj = arguments[0], path = arguments[1], rest = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
target = JsPath.getAt(obj, path);
if ('function' === typeof (target != null ? target[method] : void 0)) {
return target[method].apply(target, rest);
} else {
throw new Error("Does not implement method " + method + " at " + path);
}
};
});
/*
@method. property of the constructor.
@signature: JsPath.getAt(ref, path)
@param: ref - the object to traverse.
@param: path - a dot-notation style "path" to identify a
nested JS object.
@return: the object that can be found inside ref at the path
described by the second parameter or undefined if the path
is not valid.
*/
JsPath.getAt = function(ref, path) {
var prop;
if ('function' === typeof path.split) {
path = path.split('.');
} else {
path = path.slice();
}
while ((ref != null) && (prop = path.shift())) {
ref = ref[prop];
}
return ref;
};
/*
@method. property of the constructor.
@signature: JsPath.getAt(ref, path)
@param: obj - the object to extend.
@param: path - a dot-notation style "path" to identify a
nested JS object.
@param: val - the value to assign to the path of the obj.
@return: the object that was extended.
@description: set a property to the path provided by the
second parameter with the value provided by the third
parameter.
*/
JsPath.setAt = function(obj, path, val) {
var component, last, prev, ref;
if ('function' === typeof path.split) {
path = path.split('.');
} else {
path = path.slice();
}
last = path.pop();
prev = [];
ref = obj;
while (component = path.shift()) {
if (primTypes.test(typeof ref[component])) {
throw new Error("" + (prev.concat(component).join('.')) + " is\nprimitive, and cannot be extended.");
}
ref = ref[component] || (ref[component] = {});
prev.push(component);
}
ref[last] = val;
return obj;
};
JsPath.assureAt = function(ref, path, initializer) {
var obj;
if (obj = JsPath.getAt(ref, path)) {
return obj;
} else {
JsPath.setAt(ref, path, initializer);
return initializer;
}
};
/*
@method. property of the constructor.
@signature: JsPath.deleteAt(ref, path)
@param: obj - the object to extend.
@param: path - a dot-notation style "path" to identify a
nested JS object to dereference.
@return: boolean success.
@description: deletes the reference specified by the last
unit of the path from the object specified by other
components of the path, belonging to the provided object.
*/
JsPath.deleteAt = function(ref, path) {
var component, last, prev;
if ('function' === typeof path.split) {
path = path.split('.');
} else {
path = path.slice();
}
prev = [];
last = path.pop();
while (component = path.shift()) {
if (primTypes.test(typeof ref[component])) {
throw new Error("" + (prev.concat(component).join('.')) + " is\nprimitive; cannot drill any deeper.");
}
if (!(ref = ref[component])) return false;
prev.push(component);
}
return delete ref[last];
};
return JsPath;
}).call(this);
/*
Footnotes:
1 - if there's no .split() method, assume it's already an array
*/
}).call(this);