Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / configstore / node_modules / dot-prop / index.js
1 'use strict';
2 const isObj = require('is-obj');
3
4 const disallowedKeys = [
5         '__proto__',
6         'prototype',
7         'constructor'
8 ];
9
10 const isValidPath = pathSegments => !pathSegments.some(segment => disallowedKeys.includes(segment));
11
12 function getPathSegments(path) {
13         const pathArr = path.split('.');
14         const parts = [];
15
16         for (let i = 0; i < pathArr.length; i++) {
17                 let p = pathArr[i];
18
19                 while (p[p.length - 1] === '\\' && pathArr[i + 1] !== undefined) {
20                         p = p.slice(0, -1) + '.';
21                         p += pathArr[++i];
22                 }
23
24                 parts.push(p);
25         }
26
27         if (!isValidPath(parts)) {
28                 return [];
29         }
30
31         return parts;
32 }
33
34 module.exports = {
35         get(obj, path, value) {
36                 if (!isObj(obj) || typeof path !== 'string') {
37                         return value === undefined ? obj : value;
38                 }
39
40                 const pathArr = getPathSegments(path);
41                 if (pathArr.length === 0) {
42                         return;
43                 }
44
45                 for (let i = 0; i < pathArr.length; i++) {
46                         if (!Object.prototype.propertyIsEnumerable.call(obj, pathArr[i])) {
47                                 return value;
48                         }
49
50                         obj = obj[pathArr[i]];
51
52                         if (obj === undefined || obj === null) {
53                                 // `obj` is either `undefined` or `null` so we want to stop the loop, and
54                                 // if this is not the last bit of the path, and
55                                 // if it did't return `undefined`
56                                 // it would return `null` if `obj` is `null`
57                                 // but we want `get({foo: null}, 'foo.bar')` to equal `undefined`, or the supplied value, not `null`
58                                 if (i !== pathArr.length - 1) {
59                                         return value;
60                                 }
61
62                                 break;
63                         }
64                 }
65
66                 return obj;
67         },
68
69         set(obj, path, value) {
70                 if (!isObj(obj) || typeof path !== 'string') {
71                         return obj;
72                 }
73
74                 const root = obj;
75                 const pathArr = getPathSegments(path);
76                 if (pathArr.length === 0) {
77                         return;
78                 }
79
80                 for (let i = 0; i < pathArr.length; i++) {
81                         const p = pathArr[i];
82
83                         if (!isObj(obj[p])) {
84                                 obj[p] = {};
85                         }
86
87                         if (i === pathArr.length - 1) {
88                                 obj[p] = value;
89                         }
90
91                         obj = obj[p];
92                 }
93
94                 return root;
95         },
96
97         delete(obj, path) {
98                 if (!isObj(obj) || typeof path !== 'string') {
99                         return;
100                 }
101
102                 const pathArr = getPathSegments(path);
103
104                 for (let i = 0; i < pathArr.length; i++) {
105                         const p = pathArr[i];
106
107                         if (i === pathArr.length - 1) {
108                                 delete obj[p];
109                                 return;
110                         }
111
112                         obj = obj[p];
113
114                         if (!isObj(obj)) {
115                                 return;
116                         }
117                 }
118         },
119
120         has(obj, path) {
121                 if (!isObj(obj) || typeof path !== 'string') {
122                         return false;
123                 }
124
125                 const pathArr = getPathSegments(path);
126
127                 for (let i = 0; i < pathArr.length; i++) {
128                         if (isObj(obj)) {
129                                 if (!(pathArr[i] in obj)) {
130                                         return false;
131                                 }
132
133                                 obj = obj[pathArr[i]];
134                         } else {
135                                 return false;
136                         }
137                 }
138
139                 return true;
140         }
141 };