├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── package-lock.json
├── package.json
├── protect.js
└── tests
├── index.html
├── mocha.css
├── mocha.js
└── tests.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | coverage
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "8"
4 | - "7"
5 | - "6"
6 | - "5"
7 | - "4"
8 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Tremayne Christ
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ProtectJS / Protect JS
2 |
3 | [](https://travis-ci.org/TremayneChrist/ProtectJS)
4 | [](https://coveralls.io/github/TremayneChrist/ProtectJS?branch=master)
5 |
6 | #### Methods/Functions
7 | Adding private methods to an object in JavaScript has always been an awkward thing to do, as JavaScript doesn't exactly support it. Instead, we either place enclosed functions in the constructor, which consumes more memory per object, or, we enclose both the object definition and our private methods inside of a closure.
8 |
9 | The latter is a good way to accomplish private methods in JavaScript as it creates truly private methods and doesn't add to the memory consumption. The problem with it is, is that your private methods are separate from the object and your coding style is different compared to public definitions on the prototype.
10 |
11 | **ProtectJS** is a library that extends objects you define, to allow you to add all your private methods to the prototype chain. It does this by adding protection checks to all of your methods, any marked with a prepending underscore (_) is treated as a private method.
12 |
13 | #### Other properties
14 |
15 | As well as methods, JavaScript doesn't exactly support any type of private property. This becomes a problem when dangerous modifications to these properties occur.
16 |
17 | Think of complex algorithms - If these could be modified by external sources, their output would be completely invalidated, potentially causing huge implications.
18 |
19 |
20 | ### Examples
21 |
22 | In many languages, it is custom to prepend private variables with an underscore (_), so we use this in JavaScript to show that an object should be considered as a private. Obviously this has absolutely no affect to whether it is actually private or not, it's more of a visual reference for a developer.
23 |
24 | Let's create a basic object using this approach...
25 |
26 | ```javascript
27 |
28 | // Create the object
29 | function MyObject() {}
30 |
31 | // This is our public method
32 | MyObject.prototype.public = function () {
33 | console.log('PUBLIC method has been called');
34 | };
35 |
36 | // This is our private method, using (_)
37 | MyObject.prototype._private = function () {
38 | console.log('PRIVATE method has been called');
39 | };
40 |
41 | // Create an instance of the object
42 | var mo = new MyObject();
43 |
44 | // Call its methods
45 | mo.public(); // Pass
46 | mo._private(); // Pass
47 |
48 | ```
49 | As I stated previously, there is no protection here, so I could easily call the **_private()** method and get a message saying "PRIVATE method has been called".
50 |
51 | **Now let's protect the object with ProtectJS!..**
52 |
53 | Add ProtectJS into your source, making sure it loads before the code you want to protect.
54 |
55 | ```html
56 |
57 | PrivateJS
58 |
59 |
60 |
61 | ```
62 |
63 | Now that ProtectJS is available, we need to use it on the object
64 |
65 | ```javascript
66 |
67 | // Create the object
68 | function MyObject() {}
69 |
70 | // This is our public method
71 | MyObject.prototype.public = function () {
72 | console.log('PUBLIC method has been called');
73 | };
74 |
75 | // This is our private method, using (_)
76 | MyObject.prototype._private = function () {
77 | console.log('PRIVATE method has been called');
78 | };
79 |
80 | protect(MyObject); // Protect the object prototype
81 |
82 | // Create an instance of the object
83 | var mo = new MyObject();
84 |
85 | // Call its methods
86 | mo.public(); // Pass
87 | mo._private(); // Fail
88 |
89 | ```
90 |
91 | ProtectJS assumes that all methods starting with underscores in the prototype are private, and will add protection checks to prevent them from being called outside of the object.
92 |
93 | Once protected, the only way to call a private method is by calling it through another method inside the same object.
94 |
95 |
96 | ---
97 |
98 | ### Pros
99 |
100 | 1. Enables private methods to be added onto the prototype, keeping object memory to a minimum.
101 |
102 | 2. Protects your other properties from being modified by external sources.
103 |
104 | 3. Keeps code creation clean and easy to read.
105 |
106 | 4. Allows you to define objects in a natural way.
107 |
108 | 5. Doesn't change your coding style.
109 |
110 | 6. Protects properties you don't want to be used.
111 |
112 |
113 | ### Cons
114 |
115 | 1. You have to include the ProtectJS library in your project.
116 | 2. Marginal overheads to be considered (Performance tests to come)
117 |
118 | ---
119 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "protect.js",
3 | "version": "3.1.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "abbrev": {
8 | "version": "1.0.9",
9 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz",
10 | "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=",
11 | "dev": true
12 | },
13 | "ajv": {
14 | "version": "5.2.3",
15 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.2.3.tgz",
16 | "integrity": "sha1-wG9Zh3jETGsWGrr+NGa4GtGBTtI=",
17 | "dev": true,
18 | "requires": {
19 | "co": "4.6.0",
20 | "fast-deep-equal": "1.0.0",
21 | "json-schema-traverse": "0.3.1",
22 | "json-stable-stringify": "1.0.1"
23 | }
24 | },
25 | "align-text": {
26 | "version": "0.1.4",
27 | "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
28 | "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
29 | "dev": true,
30 | "requires": {
31 | "kind-of": "3.2.2",
32 | "longest": "1.0.1",
33 | "repeat-string": "1.6.1"
34 | }
35 | },
36 | "amdefine": {
37 | "version": "1.0.1",
38 | "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
39 | "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
40 | "dev": true
41 | },
42 | "argparse": {
43 | "version": "1.0.9",
44 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
45 | "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
46 | "dev": true,
47 | "requires": {
48 | "sprintf-js": "1.0.3"
49 | }
50 | },
51 | "asn1": {
52 | "version": "0.2.3",
53 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
54 | "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
55 | "dev": true
56 | },
57 | "assert-plus": {
58 | "version": "1.0.0",
59 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
60 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
61 | "dev": true
62 | },
63 | "assertion-error": {
64 | "version": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz",
65 | "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=",
66 | "dev": true
67 | },
68 | "async": {
69 | "version": "1.5.2",
70 | "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
71 | "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
72 | "dev": true
73 | },
74 | "asynckit": {
75 | "version": "0.4.0",
76 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
77 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
78 | "dev": true
79 | },
80 | "aws-sign2": {
81 | "version": "0.7.0",
82 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
83 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
84 | "dev": true
85 | },
86 | "aws4": {
87 | "version": "1.6.0",
88 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
89 | "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
90 | "dev": true
91 | },
92 | "balanced-match": {
93 | "version": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
94 | "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
95 | "dev": true
96 | },
97 | "bcrypt-pbkdf": {
98 | "version": "1.0.1",
99 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
100 | "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
101 | "dev": true,
102 | "optional": true,
103 | "requires": {
104 | "tweetnacl": "0.14.5"
105 | }
106 | },
107 | "boom": {
108 | "version": "4.3.1",
109 | "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
110 | "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
111 | "dev": true,
112 | "requires": {
113 | "hoek": "4.2.0"
114 | }
115 | },
116 | "brace-expansion": {
117 | "version": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz",
118 | "integrity": "sha1-cZfX6qm4fmSDkOph/GbIRCdCDfk=",
119 | "dev": true,
120 | "requires": {
121 | "balanced-match": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
122 | "concat-map": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
123 | }
124 | },
125 | "browser-stdout": {
126 | "version": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz",
127 | "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=",
128 | "dev": true
129 | },
130 | "camelcase": {
131 | "version": "1.2.1",
132 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
133 | "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
134 | "dev": true,
135 | "optional": true
136 | },
137 | "caseless": {
138 | "version": "0.12.0",
139 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
140 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
141 | "dev": true
142 | },
143 | "center-align": {
144 | "version": "0.1.3",
145 | "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
146 | "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
147 | "dev": true,
148 | "optional": true,
149 | "requires": {
150 | "align-text": "0.1.4",
151 | "lazy-cache": "1.0.4"
152 | }
153 | },
154 | "chai": {
155 | "version": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz",
156 | "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=",
157 | "dev": true,
158 | "requires": {
159 | "assertion-error": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz",
160 | "deep-eql": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz",
161 | "type-detect": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz"
162 | }
163 | },
164 | "cliui": {
165 | "version": "2.1.0",
166 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
167 | "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
168 | "dev": true,
169 | "optional": true,
170 | "requires": {
171 | "center-align": "0.1.3",
172 | "right-align": "0.1.3",
173 | "wordwrap": "0.0.2"
174 | },
175 | "dependencies": {
176 | "wordwrap": {
177 | "version": "0.0.2",
178 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
179 | "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=",
180 | "dev": true,
181 | "optional": true
182 | }
183 | }
184 | },
185 | "co": {
186 | "version": "4.6.0",
187 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
188 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
189 | "dev": true
190 | },
191 | "combined-stream": {
192 | "version": "1.0.5",
193 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
194 | "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
195 | "dev": true,
196 | "requires": {
197 | "delayed-stream": "1.0.0"
198 | }
199 | },
200 | "commander": {
201 | "version": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
202 | "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=",
203 | "dev": true,
204 | "requires": {
205 | "graceful-readlink": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz"
206 | }
207 | },
208 | "concat-map": {
209 | "version": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
210 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
211 | "dev": true
212 | },
213 | "core-util-is": {
214 | "version": "1.0.2",
215 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
216 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
217 | "dev": true
218 | },
219 | "coveralls": {
220 | "version": "3.0.0",
221 | "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.0.tgz",
222 | "integrity": "sha512-ZppXR9y5PraUOrf/DzHJY6gzNUhXYE3b9D43xEXs4QYZ7/Oe0Gy0CS+IPKWFfvQFXB3RG9QduaQUFehzSpGAFw==",
223 | "dev": true,
224 | "requires": {
225 | "js-yaml": "3.10.0",
226 | "lcov-parse": "0.0.10",
227 | "log-driver": "1.2.5",
228 | "minimist": "1.2.0",
229 | "request": "2.83.0"
230 | },
231 | "dependencies": {
232 | "minimist": {
233 | "version": "1.2.0",
234 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
235 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
236 | "dev": true
237 | }
238 | }
239 | },
240 | "cryptiles": {
241 | "version": "3.1.2",
242 | "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
243 | "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
244 | "dev": true,
245 | "requires": {
246 | "boom": "5.2.0"
247 | },
248 | "dependencies": {
249 | "boom": {
250 | "version": "5.2.0",
251 | "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
252 | "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
253 | "dev": true,
254 | "requires": {
255 | "hoek": "4.2.0"
256 | }
257 | }
258 | }
259 | },
260 | "dashdash": {
261 | "version": "1.14.1",
262 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
263 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
264 | "dev": true,
265 | "requires": {
266 | "assert-plus": "1.0.0"
267 | }
268 | },
269 | "debug": {
270 | "version": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
271 | "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
272 | "dev": true,
273 | "requires": {
274 | "ms": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
275 | }
276 | },
277 | "decamelize": {
278 | "version": "1.2.0",
279 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
280 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
281 | "dev": true,
282 | "optional": true
283 | },
284 | "deep-eql": {
285 | "version": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz",
286 | "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=",
287 | "dev": true,
288 | "requires": {
289 | "type-detect": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz"
290 | },
291 | "dependencies": {
292 | "type-detect": {
293 | "version": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz",
294 | "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=",
295 | "dev": true
296 | }
297 | }
298 | },
299 | "deep-is": {
300 | "version": "0.1.3",
301 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
302 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
303 | "dev": true
304 | },
305 | "delayed-stream": {
306 | "version": "1.0.0",
307 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
308 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
309 | "dev": true
310 | },
311 | "diff": {
312 | "version": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz",
313 | "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=",
314 | "dev": true
315 | },
316 | "ecc-jsbn": {
317 | "version": "0.1.1",
318 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
319 | "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
320 | "dev": true,
321 | "optional": true,
322 | "requires": {
323 | "jsbn": "0.1.1"
324 | }
325 | },
326 | "escape-string-regexp": {
327 | "version": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
328 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
329 | "dev": true
330 | },
331 | "escodegen": {
332 | "version": "1.8.1",
333 | "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz",
334 | "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=",
335 | "dev": true,
336 | "requires": {
337 | "esprima": "2.7.3",
338 | "estraverse": "1.9.3",
339 | "esutils": "2.0.2",
340 | "optionator": "0.8.2",
341 | "source-map": "0.2.0"
342 | },
343 | "dependencies": {
344 | "esprima": {
345 | "version": "2.7.3",
346 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
347 | "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
348 | "dev": true
349 | }
350 | }
351 | },
352 | "esprima": {
353 | "version": "4.0.0",
354 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
355 | "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
356 | "dev": true
357 | },
358 | "estraverse": {
359 | "version": "1.9.3",
360 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz",
361 | "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=",
362 | "dev": true
363 | },
364 | "esutils": {
365 | "version": "2.0.2",
366 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
367 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
368 | "dev": true
369 | },
370 | "extend": {
371 | "version": "3.0.1",
372 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
373 | "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
374 | "dev": true
375 | },
376 | "extsprintf": {
377 | "version": "1.3.0",
378 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
379 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
380 | "dev": true
381 | },
382 | "fast-deep-equal": {
383 | "version": "1.0.0",
384 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
385 | "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=",
386 | "dev": true
387 | },
388 | "fast-levenshtein": {
389 | "version": "2.0.6",
390 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
391 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
392 | "dev": true
393 | },
394 | "forever-agent": {
395 | "version": "0.6.1",
396 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
397 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
398 | "dev": true
399 | },
400 | "form-data": {
401 | "version": "2.3.1",
402 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
403 | "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=",
404 | "dev": true,
405 | "requires": {
406 | "asynckit": "0.4.0",
407 | "combined-stream": "1.0.5",
408 | "mime-types": "2.1.17"
409 | }
410 | },
411 | "fs.realpath": {
412 | "version": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
413 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
414 | "dev": true
415 | },
416 | "getpass": {
417 | "version": "0.1.7",
418 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
419 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
420 | "dev": true,
421 | "requires": {
422 | "assert-plus": "1.0.0"
423 | }
424 | },
425 | "glob": {
426 | "version": "https://registry.npmjs.org/glob/-/glob-7.0.5.tgz",
427 | "integrity": "sha1-tCAqaQmbu00pKnwblbZoK2fr3JU=",
428 | "dev": true,
429 | "requires": {
430 | "fs.realpath": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
431 | "inflight": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
432 | "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
433 | "minimatch": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz",
434 | "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
435 | "path-is-absolute": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz"
436 | }
437 | },
438 | "graceful-readlink": {
439 | "version": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
440 | "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=",
441 | "dev": true
442 | },
443 | "growl": {
444 | "version": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz",
445 | "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=",
446 | "dev": true
447 | },
448 | "handlebars": {
449 | "version": "4.0.10",
450 | "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz",
451 | "integrity": "sha1-PTDHGLCaPZbyPqTMH0A8TTup/08=",
452 | "dev": true,
453 | "requires": {
454 | "async": "1.5.2",
455 | "optimist": "0.6.1",
456 | "source-map": "0.4.4",
457 | "uglify-js": "2.8.29"
458 | },
459 | "dependencies": {
460 | "source-map": {
461 | "version": "0.4.4",
462 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
463 | "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
464 | "dev": true,
465 | "requires": {
466 | "amdefine": "1.0.1"
467 | }
468 | }
469 | }
470 | },
471 | "har-schema": {
472 | "version": "2.0.0",
473 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
474 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
475 | "dev": true
476 | },
477 | "har-validator": {
478 | "version": "5.0.3",
479 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
480 | "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
481 | "dev": true,
482 | "requires": {
483 | "ajv": "5.2.3",
484 | "har-schema": "2.0.0"
485 | }
486 | },
487 | "has-flag": {
488 | "version": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
489 | "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
490 | "dev": true
491 | },
492 | "hawk": {
493 | "version": "6.0.2",
494 | "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
495 | "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
496 | "dev": true,
497 | "requires": {
498 | "boom": "4.3.1",
499 | "cryptiles": "3.1.2",
500 | "hoek": "4.2.0",
501 | "sntp": "2.0.2"
502 | }
503 | },
504 | "hoek": {
505 | "version": "4.2.0",
506 | "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz",
507 | "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==",
508 | "dev": true
509 | },
510 | "http-signature": {
511 | "version": "1.2.0",
512 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
513 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
514 | "dev": true,
515 | "requires": {
516 | "assert-plus": "1.0.0",
517 | "jsprim": "1.4.1",
518 | "sshpk": "1.13.1"
519 | }
520 | },
521 | "inflight": {
522 | "version": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
523 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
524 | "dev": true,
525 | "requires": {
526 | "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
527 | "wrappy": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
528 | }
529 | },
530 | "inherits": {
531 | "version": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
532 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
533 | "dev": true
534 | },
535 | "is-buffer": {
536 | "version": "1.1.5",
537 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
538 | "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=",
539 | "dev": true
540 | },
541 | "is-typedarray": {
542 | "version": "1.0.0",
543 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
544 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
545 | "dev": true
546 | },
547 | "isexe": {
548 | "version": "2.0.0",
549 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
550 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
551 | "dev": true
552 | },
553 | "isstream": {
554 | "version": "0.1.2",
555 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
556 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
557 | "dev": true
558 | },
559 | "istanbul": {
560 | "version": "0.4.5",
561 | "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz",
562 | "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=",
563 | "dev": true,
564 | "requires": {
565 | "abbrev": "1.0.9",
566 | "async": "1.5.2",
567 | "escodegen": "1.8.1",
568 | "esprima": "2.7.3",
569 | "glob": "5.0.15",
570 | "handlebars": "4.0.10",
571 | "js-yaml": "3.10.0",
572 | "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
573 | "nopt": "3.0.6",
574 | "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
575 | "resolve": "1.1.7",
576 | "supports-color": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz",
577 | "which": "1.3.0",
578 | "wordwrap": "1.0.0"
579 | },
580 | "dependencies": {
581 | "esprima": {
582 | "version": "2.7.3",
583 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
584 | "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
585 | "dev": true
586 | },
587 | "glob": {
588 | "version": "5.0.15",
589 | "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
590 | "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
591 | "dev": true,
592 | "requires": {
593 | "inflight": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
594 | "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
595 | "minimatch": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz",
596 | "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
597 | "path-is-absolute": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz"
598 | }
599 | }
600 | }
601 | },
602 | "js-yaml": {
603 | "version": "3.10.0",
604 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz",
605 | "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==",
606 | "dev": true,
607 | "requires": {
608 | "argparse": "1.0.9",
609 | "esprima": "4.0.0"
610 | }
611 | },
612 | "jsbn": {
613 | "version": "0.1.1",
614 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
615 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
616 | "dev": true,
617 | "optional": true
618 | },
619 | "json-schema": {
620 | "version": "0.2.3",
621 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
622 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
623 | "dev": true
624 | },
625 | "json-schema-traverse": {
626 | "version": "0.3.1",
627 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
628 | "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
629 | "dev": true
630 | },
631 | "json-stable-stringify": {
632 | "version": "1.0.1",
633 | "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
634 | "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
635 | "dev": true,
636 | "requires": {
637 | "jsonify": "0.0.0"
638 | }
639 | },
640 | "json-stringify-safe": {
641 | "version": "5.0.1",
642 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
643 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
644 | "dev": true
645 | },
646 | "json3": {
647 | "version": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz",
648 | "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=",
649 | "dev": true
650 | },
651 | "jsonify": {
652 | "version": "0.0.0",
653 | "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
654 | "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
655 | "dev": true
656 | },
657 | "jsprim": {
658 | "version": "1.4.1",
659 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
660 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
661 | "dev": true,
662 | "requires": {
663 | "assert-plus": "1.0.0",
664 | "extsprintf": "1.3.0",
665 | "json-schema": "0.2.3",
666 | "verror": "1.10.0"
667 | }
668 | },
669 | "kind-of": {
670 | "version": "3.2.2",
671 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
672 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
673 | "dev": true,
674 | "requires": {
675 | "is-buffer": "1.1.5"
676 | }
677 | },
678 | "lazy-cache": {
679 | "version": "1.0.4",
680 | "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
681 | "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
682 | "dev": true,
683 | "optional": true
684 | },
685 | "lcov-parse": {
686 | "version": "0.0.10",
687 | "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz",
688 | "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=",
689 | "dev": true
690 | },
691 | "levn": {
692 | "version": "0.3.0",
693 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
694 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
695 | "dev": true,
696 | "requires": {
697 | "prelude-ls": "1.1.2",
698 | "type-check": "0.3.2"
699 | }
700 | },
701 | "lodash._baseassign": {
702 | "version": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz",
703 | "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=",
704 | "dev": true,
705 | "requires": {
706 | "lodash._basecopy": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz",
707 | "lodash.keys": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz"
708 | }
709 | },
710 | "lodash._basecopy": {
711 | "version": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz",
712 | "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=",
713 | "dev": true
714 | },
715 | "lodash._basecreate": {
716 | "version": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz",
717 | "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=",
718 | "dev": true
719 | },
720 | "lodash._getnative": {
721 | "version": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
722 | "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=",
723 | "dev": true
724 | },
725 | "lodash._isiterateecall": {
726 | "version": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz",
727 | "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=",
728 | "dev": true
729 | },
730 | "lodash.create": {
731 | "version": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz",
732 | "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=",
733 | "dev": true,
734 | "requires": {
735 | "lodash._baseassign": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz",
736 | "lodash._basecreate": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz",
737 | "lodash._isiterateecall": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz"
738 | }
739 | },
740 | "lodash.isarguments": {
741 | "version": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
742 | "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=",
743 | "dev": true
744 | },
745 | "lodash.isarray": {
746 | "version": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz",
747 | "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=",
748 | "dev": true
749 | },
750 | "lodash.keys": {
751 | "version": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
752 | "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=",
753 | "dev": true,
754 | "requires": {
755 | "lodash._getnative": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
756 | "lodash.isarguments": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
757 | "lodash.isarray": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz"
758 | }
759 | },
760 | "log-driver": {
761 | "version": "1.2.5",
762 | "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.5.tgz",
763 | "integrity": "sha1-euTsJXMC/XkNVXyxDJcQDYV7AFY=",
764 | "dev": true
765 | },
766 | "longest": {
767 | "version": "1.0.1",
768 | "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
769 | "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=",
770 | "dev": true
771 | },
772 | "mime-db": {
773 | "version": "1.30.0",
774 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
775 | "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=",
776 | "dev": true
777 | },
778 | "mime-types": {
779 | "version": "2.1.17",
780 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
781 | "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
782 | "dev": true,
783 | "requires": {
784 | "mime-db": "1.30.0"
785 | }
786 | },
787 | "minimatch": {
788 | "version": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz",
789 | "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=",
790 | "dev": true,
791 | "requires": {
792 | "brace-expansion": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz"
793 | }
794 | },
795 | "minimist": {
796 | "version": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
797 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
798 | "dev": true
799 | },
800 | "mkdirp": {
801 | "version": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
802 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
803 | "dev": true,
804 | "requires": {
805 | "minimist": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz"
806 | }
807 | },
808 | "mocha": {
809 | "version": "https://registry.npmjs.org/mocha/-/mocha-3.2.0.tgz",
810 | "integrity": "sha1-fcT0XlCIB1FxpoiWgU5q6et6heM=",
811 | "dev": true,
812 | "requires": {
813 | "browser-stdout": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz",
814 | "commander": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
815 | "debug": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
816 | "diff": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz",
817 | "escape-string-regexp": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
818 | "glob": "https://registry.npmjs.org/glob/-/glob-7.0.5.tgz",
819 | "growl": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz",
820 | "json3": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz",
821 | "lodash.create": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz",
822 | "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
823 | "supports-color": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz"
824 | }
825 | },
826 | "ms": {
827 | "version": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
828 | "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=",
829 | "dev": true
830 | },
831 | "nopt": {
832 | "version": "3.0.6",
833 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
834 | "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
835 | "dev": true,
836 | "requires": {
837 | "abbrev": "1.0.9"
838 | }
839 | },
840 | "oauth-sign": {
841 | "version": "0.8.2",
842 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
843 | "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
844 | "dev": true
845 | },
846 | "once": {
847 | "version": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
848 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
849 | "dev": true,
850 | "requires": {
851 | "wrappy": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
852 | }
853 | },
854 | "optimist": {
855 | "version": "0.6.1",
856 | "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
857 | "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
858 | "dev": true,
859 | "requires": {
860 | "minimist": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
861 | "wordwrap": "0.0.3"
862 | },
863 | "dependencies": {
864 | "wordwrap": {
865 | "version": "0.0.3",
866 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
867 | "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
868 | "dev": true
869 | }
870 | }
871 | },
872 | "optionator": {
873 | "version": "0.8.2",
874 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
875 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
876 | "dev": true,
877 | "requires": {
878 | "deep-is": "0.1.3",
879 | "fast-levenshtein": "2.0.6",
880 | "levn": "0.3.0",
881 | "prelude-ls": "1.1.2",
882 | "type-check": "0.3.2",
883 | "wordwrap": "1.0.0"
884 | }
885 | },
886 | "path-is-absolute": {
887 | "version": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
888 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
889 | "dev": true
890 | },
891 | "performance-now": {
892 | "version": "2.1.0",
893 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
894 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
895 | "dev": true
896 | },
897 | "prelude-ls": {
898 | "version": "1.1.2",
899 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
900 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
901 | "dev": true
902 | },
903 | "punycode": {
904 | "version": "1.4.1",
905 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
906 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
907 | "dev": true
908 | },
909 | "qs": {
910 | "version": "6.5.1",
911 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
912 | "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==",
913 | "dev": true
914 | },
915 | "repeat-string": {
916 | "version": "1.6.1",
917 | "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
918 | "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
919 | "dev": true
920 | },
921 | "request": {
922 | "version": "2.83.0",
923 | "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
924 | "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==",
925 | "dev": true,
926 | "requires": {
927 | "aws-sign2": "0.7.0",
928 | "aws4": "1.6.0",
929 | "caseless": "0.12.0",
930 | "combined-stream": "1.0.5",
931 | "extend": "3.0.1",
932 | "forever-agent": "0.6.1",
933 | "form-data": "2.3.1",
934 | "har-validator": "5.0.3",
935 | "hawk": "6.0.2",
936 | "http-signature": "1.2.0",
937 | "is-typedarray": "1.0.0",
938 | "isstream": "0.1.2",
939 | "json-stringify-safe": "5.0.1",
940 | "mime-types": "2.1.17",
941 | "oauth-sign": "0.8.2",
942 | "performance-now": "2.1.0",
943 | "qs": "6.5.1",
944 | "safe-buffer": "5.1.1",
945 | "stringstream": "0.0.5",
946 | "tough-cookie": "2.3.3",
947 | "tunnel-agent": "0.6.0",
948 | "uuid": "3.1.0"
949 | }
950 | },
951 | "resolve": {
952 | "version": "1.1.7",
953 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
954 | "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
955 | "dev": true
956 | },
957 | "right-align": {
958 | "version": "0.1.3",
959 | "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
960 | "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
961 | "dev": true,
962 | "optional": true,
963 | "requires": {
964 | "align-text": "0.1.4"
965 | }
966 | },
967 | "safe-buffer": {
968 | "version": "5.1.1",
969 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
970 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
971 | "dev": true
972 | },
973 | "sntp": {
974 | "version": "2.0.2",
975 | "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.0.2.tgz",
976 | "integrity": "sha1-UGQRDwr4X3z9t9a2ekACjOUrSys=",
977 | "dev": true,
978 | "requires": {
979 | "hoek": "4.2.0"
980 | }
981 | },
982 | "source-map": {
983 | "version": "0.2.0",
984 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz",
985 | "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=",
986 | "dev": true,
987 | "optional": true,
988 | "requires": {
989 | "amdefine": "1.0.1"
990 | }
991 | },
992 | "sprintf-js": {
993 | "version": "1.0.3",
994 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
995 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
996 | "dev": true
997 | },
998 | "sshpk": {
999 | "version": "1.13.1",
1000 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
1001 | "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
1002 | "dev": true,
1003 | "requires": {
1004 | "asn1": "0.2.3",
1005 | "assert-plus": "1.0.0",
1006 | "bcrypt-pbkdf": "1.0.1",
1007 | "dashdash": "1.14.1",
1008 | "ecc-jsbn": "0.1.1",
1009 | "getpass": "0.1.7",
1010 | "jsbn": "0.1.1",
1011 | "tweetnacl": "0.14.5"
1012 | }
1013 | },
1014 | "stringstream": {
1015 | "version": "0.0.5",
1016 | "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
1017 | "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
1018 | "dev": true
1019 | },
1020 | "supports-color": {
1021 | "version": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz",
1022 | "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=",
1023 | "dev": true,
1024 | "requires": {
1025 | "has-flag": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz"
1026 | }
1027 | },
1028 | "tough-cookie": {
1029 | "version": "2.3.3",
1030 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
1031 | "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
1032 | "dev": true,
1033 | "requires": {
1034 | "punycode": "1.4.1"
1035 | }
1036 | },
1037 | "tunnel-agent": {
1038 | "version": "0.6.0",
1039 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
1040 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
1041 | "dev": true,
1042 | "requires": {
1043 | "safe-buffer": "5.1.1"
1044 | }
1045 | },
1046 | "tweetnacl": {
1047 | "version": "0.14.5",
1048 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
1049 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
1050 | "dev": true,
1051 | "optional": true
1052 | },
1053 | "type-check": {
1054 | "version": "0.3.2",
1055 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
1056 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
1057 | "dev": true,
1058 | "requires": {
1059 | "prelude-ls": "1.1.2"
1060 | }
1061 | },
1062 | "type-detect": {
1063 | "version": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz",
1064 | "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI=",
1065 | "dev": true
1066 | },
1067 | "uglify-js": {
1068 | "version": "2.8.29",
1069 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
1070 | "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
1071 | "dev": true,
1072 | "optional": true,
1073 | "requires": {
1074 | "source-map": "0.5.7",
1075 | "uglify-to-browserify": "1.0.2",
1076 | "yargs": "3.10.0"
1077 | },
1078 | "dependencies": {
1079 | "source-map": {
1080 | "version": "0.5.7",
1081 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
1082 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
1083 | "dev": true,
1084 | "optional": true
1085 | }
1086 | }
1087 | },
1088 | "uglify-to-browserify": {
1089 | "version": "1.0.2",
1090 | "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
1091 | "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
1092 | "dev": true,
1093 | "optional": true
1094 | },
1095 | "uuid": {
1096 | "version": "3.1.0",
1097 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
1098 | "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==",
1099 | "dev": true
1100 | },
1101 | "verror": {
1102 | "version": "1.10.0",
1103 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
1104 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
1105 | "dev": true,
1106 | "requires": {
1107 | "assert-plus": "1.0.0",
1108 | "core-util-is": "1.0.2",
1109 | "extsprintf": "1.3.0"
1110 | }
1111 | },
1112 | "which": {
1113 | "version": "1.3.0",
1114 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
1115 | "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
1116 | "dev": true,
1117 | "requires": {
1118 | "isexe": "2.0.0"
1119 | }
1120 | },
1121 | "window-size": {
1122 | "version": "0.1.0",
1123 | "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
1124 | "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
1125 | "dev": true,
1126 | "optional": true
1127 | },
1128 | "wordwrap": {
1129 | "version": "1.0.0",
1130 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
1131 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
1132 | "dev": true
1133 | },
1134 | "wrappy": {
1135 | "version": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1136 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
1137 | "dev": true
1138 | },
1139 | "yargs": {
1140 | "version": "3.10.0",
1141 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
1142 | "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
1143 | "dev": true,
1144 | "optional": true,
1145 | "requires": {
1146 | "camelcase": "1.2.1",
1147 | "cliui": "2.1.0",
1148 | "decamelize": "1.2.0",
1149 | "window-size": "0.1.0"
1150 | }
1151 | }
1152 | }
1153 | }
1154 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "protect.js",
3 | "version": "3.1.0",
4 | "description": "Tool for protecting private properties",
5 | "main": "protect.js",
6 | "directories": {
7 | "test": "tests"
8 | },
9 | "devDependencies": {
10 | "chai": "^3.5.0",
11 | "coveralls": "^3.0.0",
12 | "istanbul": "^0.4.5",
13 | "mocha": "^3.0.1"
14 | },
15 | "scripts": {
16 | "ut": "mocha tests --reporter min",
17 | "coverage": "istanbul cover ./node_modules/mocha/bin/_mocha tests -- -R spec",
18 | "test": "istanbul cover ./node_modules/mocha/bin/_mocha tests --report lcovonly -- -R spec && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage"
19 | },
20 | "repository": {
21 | "type": "git",
22 | "url": "git+https://github.com/TremayneChrist/ProtectJS.git"
23 | },
24 | "keywords": [
25 | "private",
26 | "methods",
27 | "functions",
28 | "properties"
29 | ],
30 | "author": "Tremayne Christ",
31 | "license": "MIT",
32 | "bugs": {
33 | "url": "https://github.com/TremayneChrist/ProtectJS/issues"
34 | },
35 | "homepage": "https://github.com/TremayneChrist/ProtectJS#readme"
36 | }
37 |
--------------------------------------------------------------------------------
/protect.js:
--------------------------------------------------------------------------------
1 | (function () {
2 |
3 | 'use strict';
4 |
5 | // The protect object
6 | this.protect = function (_O) {
7 |
8 | var callDepth = 0; // Stores the call depth of the current execution
9 |
10 | var locked = function () {
11 | return !callDepth;
12 | };
13 |
14 | var O = _O.prototype || _O; // Protect the prototype, if there is one
15 |
16 | Object.keys(O).forEach(function (key) {
17 |
18 | var value = O[key]; // The original property value
19 | var isFunction = typeof value === 'function';
20 |
21 | if (key.indexOf('_') === 0) { // Should the object be protected
22 | Object.defineProperty(O, key, {
23 | get: function () {
24 | if (locked()) {
25 | return undefined;
26 | }
27 | else {
28 | if (!isFunction) {
29 | return value;
30 | }
31 | return function () {
32 | return value.apply(this, arguments);
33 | };
34 | }
35 | },
36 | set: function () {
37 | if (!locked()) {
38 | value = arguments[0];
39 | isFunction = typeof value === 'function';
40 | }
41 | },
42 | enumerable: false // Remove from Object.keys
43 | });
44 | }
45 | else { // Allow functions to retrieve private properties
46 | Object.defineProperty(O, key, {
47 | get: function () {
48 | if (!isFunction) {
49 | return value;
50 | }
51 | return function () {
52 | var result;
53 | try {
54 | callDepth++;
55 | result = value.apply(this, arguments);
56 | }
57 | catch (e) {
58 | throw e;
59 | }
60 | finally {
61 | callDepth--;
62 | }
63 | return result;
64 | };
65 | },
66 | set: function () {
67 | value = arguments[0];
68 | isFunction = false; // New functions cannot unlock private properties
69 | }
70 | });
71 | }
72 | });
73 | };
74 |
75 | // Make it available for both Node and Browser
76 | if(typeof module !== 'undefined' && module.exports) {
77 | module.exports = this.protect;
78 | }
79 |
80 | }).call(this);
81 |
--------------------------------------------------------------------------------
/tests/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Mocha
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/tests/mocha.css:
--------------------------------------------------------------------------------
1 | @charset "utf-8";
2 |
3 | body {
4 | margin:0;
5 | }
6 |
7 | #mocha {
8 | font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
9 | margin: 60px 50px;
10 | }
11 |
12 | #mocha ul,
13 | #mocha li {
14 | margin: 0;
15 | padding: 0;
16 | }
17 |
18 | #mocha ul {
19 | list-style: none;
20 | }
21 |
22 | #mocha h1,
23 | #mocha h2 {
24 | margin: 0;
25 | }
26 |
27 | #mocha h1 {
28 | margin-top: 15px;
29 | font-size: 1em;
30 | font-weight: 200;
31 | }
32 |
33 | #mocha h1 a {
34 | text-decoration: none;
35 | color: inherit;
36 | }
37 |
38 | #mocha h1 a:hover {
39 | text-decoration: underline;
40 | }
41 |
42 | #mocha .suite .suite h1 {
43 | margin-top: 0;
44 | font-size: .8em;
45 | }
46 |
47 | #mocha .hidden {
48 | display: none;
49 | }
50 |
51 | #mocha h2 {
52 | font-size: 12px;
53 | font-weight: normal;
54 | cursor: pointer;
55 | }
56 |
57 | #mocha .suite {
58 | margin-left: 15px;
59 | }
60 |
61 | #mocha .test {
62 | margin-left: 15px;
63 | overflow: hidden;
64 | }
65 |
66 | #mocha .test.pending:hover h2::after {
67 | content: '(pending)';
68 | font-family: arial, sans-serif;
69 | }
70 |
71 | #mocha .test.pass.medium .duration {
72 | background: #c09853;
73 | }
74 |
75 | #mocha .test.pass.slow .duration {
76 | background: #b94a48;
77 | }
78 |
79 | #mocha .test.pass::before {
80 | content: '✓';
81 | font-size: 12px;
82 | display: block;
83 | float: left;
84 | margin-right: 5px;
85 | color: #00d6b2;
86 | }
87 |
88 | #mocha .test.pass .duration {
89 | font-size: 9px;
90 | margin-left: 5px;
91 | padding: 2px 5px;
92 | color: #fff;
93 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
94 | -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
95 | box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
96 | -webkit-border-radius: 5px;
97 | -moz-border-radius: 5px;
98 | -ms-border-radius: 5px;
99 | -o-border-radius: 5px;
100 | border-radius: 5px;
101 | }
102 |
103 | #mocha .test.pass.fast .duration {
104 | display: none;
105 | }
106 |
107 | #mocha .test.pending {
108 | color: #0b97c4;
109 | }
110 |
111 | #mocha .test.pending::before {
112 | content: '◦';
113 | color: #0b97c4;
114 | }
115 |
116 | #mocha .test.fail {
117 | color: #c00;
118 | }
119 |
120 | #mocha .test.fail pre {
121 | color: black;
122 | }
123 |
124 | #mocha .test.fail::before {
125 | content: '✖';
126 | font-size: 12px;
127 | display: block;
128 | float: left;
129 | margin-right: 5px;
130 | color: #c00;
131 | }
132 |
133 | #mocha .test pre.error {
134 | color: #c00;
135 | max-height: 300px;
136 | overflow: auto;
137 | }
138 |
139 | #mocha .test .html-error {
140 | overflow: auto;
141 | color: black;
142 | line-height: 1.5;
143 | display: block;
144 | float: left;
145 | clear: left;
146 | font: 12px/1.5 monaco, monospace;
147 | margin: 5px;
148 | padding: 15px;
149 | border: 1px solid #eee;
150 | max-width: 85%; /*(1)*/
151 | max-width: -webkit-calc(100% - 42px);
152 | max-width: -moz-calc(100% - 42px);
153 | max-width: calc(100% - 42px); /*(2)*/
154 | max-height: 300px;
155 | word-wrap: break-word;
156 | border-bottom-color: #ddd;
157 | -webkit-box-shadow: 0 1px 3px #eee;
158 | -moz-box-shadow: 0 1px 3px #eee;
159 | box-shadow: 0 1px 3px #eee;
160 | -webkit-border-radius: 3px;
161 | -moz-border-radius: 3px;
162 | border-radius: 3px;
163 | }
164 |
165 | #mocha .test .html-error pre.error {
166 | border: none;
167 | -webkit-border-radius: 0;
168 | -moz-border-radius: 0;
169 | border-radius: 0;
170 | -webkit-box-shadow: 0;
171 | -moz-box-shadow: 0;
172 | box-shadow: 0;
173 | padding: 0;
174 | margin: 0;
175 | margin-top: 18px;
176 | max-height: none;
177 | }
178 |
179 | /**
180 | * (1): approximate for browsers not supporting calc
181 | * (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border)
182 | * ^^ seriously
183 | */
184 | #mocha .test pre {
185 | display: block;
186 | float: left;
187 | clear: left;
188 | font: 12px/1.5 monaco, monospace;
189 | margin: 5px;
190 | padding: 15px;
191 | border: 1px solid #eee;
192 | max-width: 85%; /*(1)*/
193 | max-width: -webkit-calc(100% - 42px);
194 | max-width: -moz-calc(100% - 42px);
195 | max-width: calc(100% - 42px); /*(2)*/
196 | word-wrap: break-word;
197 | border-bottom-color: #ddd;
198 | -webkit-box-shadow: 0 1px 3px #eee;
199 | -moz-box-shadow: 0 1px 3px #eee;
200 | box-shadow: 0 1px 3px #eee;
201 | -webkit-border-radius: 3px;
202 | -moz-border-radius: 3px;
203 | border-radius: 3px;
204 | }
205 |
206 | #mocha .test h2 {
207 | position: relative;
208 | }
209 |
210 | #mocha .test a.replay {
211 | position: absolute;
212 | top: 3px;
213 | right: 0;
214 | text-decoration: none;
215 | vertical-align: middle;
216 | display: block;
217 | width: 15px;
218 | height: 15px;
219 | line-height: 15px;
220 | text-align: center;
221 | background: #eee;
222 | font-size: 15px;
223 | -webkit-border-radius: 15px;
224 | -moz-border-radius: 15px;
225 | border-radius: 15px;
226 | -webkit-transition:opacity 200ms;
227 | -moz-transition:opacity 200ms;
228 | -o-transition:opacity 200ms;
229 | transition: opacity 200ms;
230 | opacity: 0.3;
231 | color: #888;
232 | }
233 |
234 | #mocha .test:hover a.replay {
235 | opacity: 1;
236 | }
237 |
238 | #mocha-report.pass .test.fail {
239 | display: none;
240 | }
241 |
242 | #mocha-report.fail .test.pass {
243 | display: none;
244 | }
245 |
246 | #mocha-report.pending .test.pass,
247 | #mocha-report.pending .test.fail {
248 | display: none;
249 | }
250 | #mocha-report.pending .test.pass.pending {
251 | display: block;
252 | }
253 |
254 | #mocha-error {
255 | color: #c00;
256 | font-size: 1.5em;
257 | font-weight: 100;
258 | letter-spacing: 1px;
259 | }
260 |
261 | #mocha-stats {
262 | position: fixed;
263 | top: 15px;
264 | right: 10px;
265 | font-size: 12px;
266 | margin: 0;
267 | color: #888;
268 | z-index: 1;
269 | }
270 |
271 | #mocha-stats .progress {
272 | float: right;
273 | padding-top: 0;
274 |
275 | /**
276 | * Set safe initial values, so mochas .progress does not inherit these
277 | * properties from Bootstrap .progress (which causes .progress height to
278 | * equal line height set in Bootstrap).
279 | */
280 | height: auto;
281 | -webkit-box-shadow: none;
282 | -moz-box-shadow: none;
283 | box-shadow: none;
284 | background-color: initial;
285 | }
286 |
287 | #mocha-stats em {
288 | color: black;
289 | }
290 |
291 | #mocha-stats a {
292 | text-decoration: none;
293 | color: inherit;
294 | }
295 |
296 | #mocha-stats a:hover {
297 | border-bottom: 1px solid #eee;
298 | }
299 |
300 | #mocha-stats li {
301 | display: inline-block;
302 | margin: 0 5px;
303 | list-style: none;
304 | padding-top: 11px;
305 | }
306 |
307 | #mocha-stats canvas {
308 | width: 40px;
309 | height: 40px;
310 | }
311 |
312 | #mocha code .comment { color: #ddd; }
313 | #mocha code .init { color: #2f6fad; }
314 | #mocha code .string { color: #5890ad; }
315 | #mocha code .keyword { color: #8a6343; }
316 | #mocha code .number { color: #2f6fad; }
317 |
318 | @media screen and (max-device-width: 480px) {
319 | #mocha {
320 | margin: 60px 0px;
321 | }
322 |
323 | #mocha #stats {
324 | position: absolute;
325 | }
326 | }
327 |
--------------------------------------------------------------------------------
/tests/tests.js:
--------------------------------------------------------------------------------
1 |
2 | var fn;
3 | var testObject;
4 | var autoProtect;
5 | var protect = this.protect || require('../protect.js');
6 | var chai = this.chai || require('chai');
7 | var expect = chai.expect;
8 |
9 | describe('ProtectJS', function () {
10 |
11 | var test = function () {
12 |
13 | it('Should successfully protect the object', function () {
14 | fn = function () {
15 | protect(testObj);
16 | autoProtect = true;
17 | }
18 | // Should show all properties as enumerable
19 | expect(Object.keys(testObj.prototype || testObj)).lengthOf(16);
20 | // Should protect the object without any errors
21 | expect(fn).to.not.throw();
22 | // Once protected, the enumerable values should only be public ones
23 | expect(Object.keys(testObj.prototype || testObj)).lengthOf(8);
24 | });
25 |
26 | it('Should NOT return PRIVATE properties', function () {
27 | fn = function () {
28 | return testObj._function();
29 | }
30 | expect(testObj._string).to.be.undefined;
31 | expect(testObj._number).to.be.undefined;
32 | expect(testObj._object).to.be.undefined;
33 | expect(testObj._null).to.be.undefined;
34 | expect(testObj._undefined).to.be.undefined;
35 | expect(testObj._function).to.be.undefined;
36 | expect(fn).to.throw();
37 | });
38 |
39 | it('Should return PUBLIC properties', function () {
40 | expect(testObj.string).to.equal('Hello Universe');
41 | expect(testObj.number).to.equal(2016);
42 | expect(testObj.object).to.not.be.undefined;
43 | expect(testObj.null).to.be.null;
44 | expect(testObj.undefined).to.be.undefined;
45 | expect(testObj.function).to.not.throw();
46 | expect(testObj.function()).to.equal('Hello Universe 2016');
47 | });
48 |
49 | it('Should allow PRIVATE methods to be called from PUBLIC ones', function () {
50 | fn = function () {
51 | return testObj.public();
52 | }
53 | expect(fn).to.not.throw();
54 | expect(function () {
55 | return testObj._private();
56 | }).to.throw();
57 | expect(fn()).to.equal(2016);
58 | });
59 |
60 | it('Should allow PUBLIC strings to be set', function () {
61 | expect(testObj.string).to.equal('Hello Universe');
62 | testObj.string = 'ProtectJS is cool!';
63 | expect(testObj.string).to.equal('ProtectJS is cool!');
64 | });
65 |
66 | it('Should allow PUBLIC numbers to be set', function () {
67 | expect(testObj.number).to.equal(2016);
68 | testObj.number *= 2;
69 | expect(testObj.number).to.equal(4032);
70 | });
71 |
72 | it('Should allow PUBLIC functions to be set', function () {
73 | var newFn = function () {};
74 | expect(testObj.function).to.not.be.undefined;
75 | testObj.function = newFn;
76 | expect(testObj.function).to.equal(newFn);
77 | });
78 |
79 | it('Should allow PUBLIC functions to set PUBLIC & PRIVATE properties', function () {
80 | var obj = testObj.object;
81 | var newObj = {};
82 | expect(obj).to.not.equal(newObj);
83 | expect(testObj.setFunction(newObj)).to.equal(true);
84 | });
85 |
86 | it('Should allow PUBLIC properties\' types to be changed', function () {
87 | fn = function () { return 'fn'; };
88 | expect(testObj.number).to.equal(2016);
89 | testObj.number = 'hello';
90 | expect(testObj.number).to.equal('hello');
91 | testObj.number = fn;
92 | testObj.function = 123;
93 | expect(testObj.number).to.equal(fn);
94 | expect(testObj.number()).to.equal('fn');
95 | expect(testObj.function).to.equal(123);
96 | });
97 |
98 | it('Should allow new PUBLIC functions to access PUBLIC properties', function () {
99 | testObj.newFn = function () { return this.number; };
100 | expect(testObj.newFn()).to.equal(2016);
101 | });
102 |
103 | it('Should NOT allow new PUBLIC functions to access PRIVATE properties', function () {
104 | testObj.newFn = function () { return this._number; };
105 | expect(testObj.newFn()).to.be.undefined;
106 | });
107 |
108 | it('Should NOT allow modified PUBLIC functions to access private properties', function () {
109 | var newFn = function () {
110 | return 10 + this._private();
111 | };
112 | expect(testObj.public()).to.equal(2016);
113 | testObj.public = newFn;
114 | expect(testObj.public).to.throw();
115 | });
116 |
117 | it('Should NOT allow PRIVATE strings to be set', function () {
118 | expect(testObj._string).to.be.undefined;
119 | testObj._string = 'ProtectJS is cool!';
120 | expect(testObj._string).to.be.undefined;
121 | });
122 |
123 | it('Should NOT allow PRIVATE numbers to be set', function () {
124 | expect(testObj._number).to.be.undefined;
125 | testObj._number = 'ProtectJS is cool!';
126 | expect(testObj._number).to.be.undefined;
127 | });
128 |
129 | it('Should NOT allow PRIVATE functions to be set', function () {
130 | expect(testObj._function).to.be.undefined;
131 | testObj._function = function () {};
132 | expect(testObj._function).to.be.undefined;
133 | });
134 |
135 | it('Should NOT allow PRIVATE property access from other objects', function () {
136 | var obj2 = {
137 | fn: function () {
138 | return testObj._function();
139 | },
140 | prop: function () {
141 | return testObj._number + testObj._string;
142 | }
143 | };
144 |
145 | // Unprotected
146 | expect(obj2.fn).to.throw();
147 | expect(obj2.prop()).to.be.NaN;
148 |
149 | // Protected
150 | protect(obj2);
151 | expect(obj2.fn).to.throw();
152 | expect(obj2.prop()).to.be.NaN;
153 | });
154 | };
155 |
156 | describe('Literal Objects', function () {
157 |
158 | before(function () {
159 | autoProtect = false;
160 | });
161 |
162 | beforeEach(function () {
163 |
164 | testObj = {
165 |
166 | // Private
167 | '_string': 'Hello Universe',
168 | '_number': 2016,
169 | '_object': {},
170 | '_null': null,
171 | '_undefined': undefined,
172 | '_function': function () {
173 | return [this._string, this.number].join(' ');
174 | },
175 |
176 | // Public
177 | 'string': 'Hello Universe',
178 | 'number': 2016,
179 | 'object': {},
180 | 'null': null,
181 | 'undefined': undefined,
182 | 'function': function () {
183 | return [this.string, this.number].join(' ');
184 | },
185 |
186 | // Test functions
187 | setFunction: function (newObj) {
188 | this._object = newObj;
189 | return newObj === this._setFunction();
190 | },
191 | _setFunction: function () {
192 | this.object = this._object;
193 | return this.object;
194 | },
195 | public: function () {
196 | return 10 + this._private();
197 | },
198 | _private: function() {
199 | return 2006;
200 | }
201 |
202 | };
203 |
204 | if (autoProtect) {
205 | protect(testObj);
206 | }
207 |
208 | });
209 |
210 | test(); // Run the generic tests
211 |
212 | });
213 |
214 | describe('Instance Objects', function () {
215 |
216 | before(function () {
217 | autoProtect = false;
218 | });
219 |
220 | beforeEach(function () {
221 |
222 | var MyObject = function () {
223 |
224 | // Private
225 | this._string = 'Hello Universe';
226 | this._number = 2016;
227 | this._object = {};
228 | this._null = null;
229 | this._undefined = undefined;
230 | this._function = function () {
231 | return [this.string, this.number].join(' ');
232 | };
233 |
234 | // Public
235 | this.string = 'Hello Universe';
236 | this.number = 2016;
237 | this.object = {};
238 | this.null = null;
239 | this.undefined = undefined;
240 | this.function = function () {
241 | return [this.string, this.number].join(' ');
242 | };
243 |
244 | // Test functions
245 | this.setFunction = function (newObj) {
246 | this._object = newObj;
247 | return newObj === this._setFunction();
248 | }
249 | this._setFunction = function () {
250 | this.object = this._object;
251 | return this.object;
252 | }
253 | this.public = function () {
254 | return 10 + this._private();
255 | }
256 | this._private = function () {
257 | return 2006;
258 | }
259 |
260 | if (autoProtect) {
261 | protect(this);
262 | }
263 |
264 | };
265 |
266 | testObj = new MyObject();
267 |
268 | });
269 |
270 | test(); // Run the generic tests
271 |
272 | });
273 |
274 | describe('Prototyped Objects', function () {
275 |
276 | before(function () {
277 | autoProtect = false;
278 | });
279 |
280 | beforeEach(function () {
281 |
282 | var MyObject = function () {};
283 |
284 | // Private
285 | MyObject.prototype._string = 'Hello Universe';
286 | MyObject.prototype._number = 2016;
287 | MyObject.prototype._object = {};
288 | MyObject.prototype._null = null;
289 | MyObject.prototype._undefined = undefined;
290 | MyObject.prototype._function = function () {
291 | return [this.string, this.number].join(' ');
292 | };
293 |
294 | // Public
295 | MyObject.prototype.string = 'Hello Universe';
296 | MyObject.prototype.number = 2016;
297 | MyObject.prototype.object = {};
298 | MyObject.prototype.null = null;
299 | MyObject.prototype.undefined = undefined;
300 | MyObject.prototype.function = function () {
301 | return [this.string, this.number].join(' ');
302 | };
303 |
304 | // Test functions
305 | MyObject.prototype.setFunction = function (newObj) {
306 | this._object = newObj;
307 | return newObj === this._setFunction();
308 | }
309 | MyObject.prototype._setFunction = function () {
310 | this.object = this._object;
311 | return this.object;
312 | }
313 | MyObject.prototype.public = function () {
314 | return 10 + this._private();
315 | }
316 | MyObject.prototype._private = function () {
317 | return 2006;
318 | }
319 |
320 | if (autoProtect) {
321 | protect(MyObject);
322 | testObj = new MyObject();
323 | }
324 | else {
325 | testObj = MyObject;
326 | }
327 |
328 | });
329 |
330 | test(); // Run the generic tests
331 |
332 | });
333 |
334 | });
335 |
--------------------------------------------------------------------------------