axios 1.1.2 → 1.2.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of axios might be problematic. Click here for more details.

package/lib/axios.js CHANGED
@@ -14,6 +14,7 @@ import toFormData from './helpers/toFormData.js';
14
14
  import AxiosError from './core/AxiosError.js';
15
15
  import spread from './helpers/spread.js';
16
16
  import isAxiosError from './helpers/isAxiosError.js';
17
+ import AxiosHeaders from "./core/AxiosHeaders.js";
17
18
 
18
19
  /**
19
20
  * Create an instance of Axios
@@ -69,8 +70,11 @@ axios.spread = spread;
69
70
  // Expose isAxiosError
70
71
  axios.isAxiosError = isAxiosError;
71
72
 
72
- axios.formToJSON = thing => {
73
- return formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing);
74
- };
73
+ axios.AxiosHeaders = AxiosHeaders;
74
+
75
+ axios.formToJSON = thing => formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing);
76
+
77
+ axios.default = axios;
75
78
 
79
+ // this module should only have a default export
76
80
  export default axios
package/lib/core/Axios.js CHANGED
@@ -47,7 +47,7 @@ class Axios {
47
47
 
48
48
  config = mergeConfig(this.defaults, config);
49
49
 
50
- const transitional = config.transitional;
50
+ const {transitional, paramsSerializer, headers} = config;
51
51
 
52
52
  if (transitional !== undefined) {
53
53
  validator.assertOptions(transitional, {
@@ -57,23 +57,32 @@ class Axios {
57
57
  }, false);
58
58
  }
59
59
 
60
+ if (paramsSerializer !== undefined) {
61
+ validator.assertOptions(paramsSerializer, {
62
+ encode: validators.function,
63
+ serialize: validators.function
64
+ }, true);
65
+ }
66
+
60
67
  // Set config.method
61
68
  config.method = (config.method || this.defaults.method || 'get').toLowerCase();
62
69
 
70
+ let contextHeaders;
71
+
63
72
  // Flatten headers
64
- const defaultHeaders = config.headers && utils.merge(
65
- config.headers.common,
66
- config.headers[config.method]
73
+ contextHeaders = headers && utils.merge(
74
+ headers.common,
75
+ headers[config.method]
67
76
  );
68
77
 
69
- defaultHeaders && utils.forEach(
78
+ contextHeaders && utils.forEach(
70
79
  ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],
71
- function cleanHeaderConfig(method) {
72
- delete config.headers[method];
80
+ (method) => {
81
+ delete headers[method];
73
82
  }
74
83
  );
75
84
 
76
- config.headers = new AxiosHeaders(config.headers, defaultHeaders);
85
+ config.headers = AxiosHeaders.concat(contextHeaders, headers);
77
86
 
78
87
  // filter out skipped interceptors
79
88
  const requestInterceptorChain = [];
@@ -4,7 +4,6 @@ import utils from '../utils.js';
4
4
  import parseHeaders from '../helpers/parseHeaders.js';
5
5
 
6
6
  const $internals = Symbol('internals');
7
- const $defaults = Symbol('defaults');
8
7
 
9
8
  function normalizeHeader(header) {
10
9
  return header && String(header).trim().toLowerCase();
@@ -15,7 +14,7 @@ function normalizeValue(value) {
15
14
  return value;
16
15
  }
17
16
 
18
- return String(value);
17
+ return utils.isArray(value) ? value.map(normalizeValue) : String(value);
19
18
  }
20
19
 
21
20
  function parseTokens(str) {
@@ -30,6 +29,10 @@ function parseTokens(str) {
30
29
  return tokens;
31
30
  }
32
31
 
32
+ function isValidHeaderName(str) {
33
+ return /^[-_a-zA-Z]+$/.test(str.trim());
34
+ }
35
+
33
36
  function matchHeaderValue(context, value, header, filter) {
34
37
  if (utils.isFunction(filter)) {
35
38
  return filter.call(this, value, header);
@@ -66,27 +69,12 @@ function buildAccessors(obj, header) {
66
69
  });
67
70
  }
68
71
 
69
- function findKey(obj, key) {
70
- key = key.toLowerCase();
71
- const keys = Object.keys(obj);
72
- let i = keys.length;
73
- let _key;
74
- while (i-- > 0) {
75
- _key = keys[i];
76
- if (key === _key.toLowerCase()) {
77
- return _key;
78
- }
72
+ class AxiosHeaders {
73
+ constructor(headers) {
74
+ headers && this.set(headers);
79
75
  }
80
- return null;
81
- }
82
-
83
- function AxiosHeaders(headers, defaults) {
84
- headers && this.set(headers);
85
- this[$defaults] = defaults || null;
86
- }
87
76
 
88
- Object.assign(AxiosHeaders.prototype, {
89
- set: function(header, valueOrRewrite, rewrite) {
77
+ set(header, valueOrRewrite, rewrite) {
90
78
  const self = this;
91
79
 
92
80
  function setHeader(_value, _header, _rewrite) {
@@ -96,75 +84,70 @@ Object.assign(AxiosHeaders.prototype, {
96
84
  throw new Error('header name must be a non-empty string');
97
85
  }
98
86
 
99
- const key = findKey(self, lHeader);
87
+ const key = utils.findKey(self, lHeader);
100
88
 
101
- if (key && _rewrite !== true && (self[key] === false || _rewrite === false)) {
102
- return;
103
- }
104
-
105
- if (utils.isArray(_value)) {
106
- _value = _value.map(normalizeValue);
107
- } else {
108
- _value = normalizeValue(_value);
89
+ if(!key || self[key] === undefined || _rewrite === true || (_rewrite === undefined && self[key] !== false)) {
90
+ self[key || _header] = normalizeValue(_value);
109
91
  }
110
-
111
- self[key || _header] = _value;
112
92
  }
113
93
 
114
- if (utils.isPlainObject(header)) {
115
- utils.forEach(header, (_value, _header) => {
116
- setHeader(_value, _header, valueOrRewrite);
117
- });
94
+ const setHeaders = (headers, _rewrite) =>
95
+ utils.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite));
96
+
97
+ if (utils.isPlainObject(header) || header instanceof this.constructor) {
98
+ setHeaders(header, valueOrRewrite)
99
+ } else if(utils.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {
100
+ setHeaders(parseHeaders(header), valueOrRewrite);
118
101
  } else {
119
- setHeader(valueOrRewrite, header, rewrite);
102
+ header != null && setHeader(valueOrRewrite, header, rewrite);
120
103
  }
121
104
 
122
105
  return this;
123
- },
106
+ }
124
107
 
125
- get: function(header, parser) {
108
+ get(header, parser) {
126
109
  header = normalizeHeader(header);
127
110
 
128
- if (!header) return undefined;
111
+ if (header) {
112
+ const key = utils.findKey(this, header);
129
113
 
130
- const key = findKey(this, header);
114
+ if (key) {
115
+ const value = this[key];
131
116
 
132
- if (key) {
133
- const value = this[key];
117
+ if (!parser) {
118
+ return value;
119
+ }
134
120
 
135
- if (!parser) {
136
- return value;
137
- }
121
+ if (parser === true) {
122
+ return parseTokens(value);
123
+ }
138
124
 
139
- if (parser === true) {
140
- return parseTokens(value);
141
- }
125
+ if (utils.isFunction(parser)) {
126
+ return parser.call(this, value, key);
127
+ }
142
128
 
143
- if (utils.isFunction(parser)) {
144
- return parser.call(this, value, key);
145
- }
129
+ if (utils.isRegExp(parser)) {
130
+ return parser.exec(value);
131
+ }
146
132
 
147
- if (utils.isRegExp(parser)) {
148
- return parser.exec(value);
133
+ throw new TypeError('parser must be boolean|regexp|function');
149
134
  }
150
-
151
- throw new TypeError('parser must be boolean|regexp|function');
152
135
  }
153
- },
136
+ }
154
137
 
155
- has: function(header, matcher) {
138
+ has(header, matcher) {
156
139
  header = normalizeHeader(header);
157
140
 
158
141
  if (header) {
159
- const key = findKey(this, header);
142
+ const key = utils.findKey(this, header);
160
143
 
161
144
  return !!(key && (!matcher || matchHeaderValue(this, this[key], key, matcher)));
162
145
  }
163
146
 
164
147
  return false;
165
- },
148
+ }
166
149
 
167
- delete: function(header, matcher) {
150
+ delete(header, matcher) {
168
151
  const self = this;
169
152
  let deleted = false;
170
153
 
@@ -172,7 +155,7 @@ Object.assign(AxiosHeaders.prototype, {
172
155
  _header = normalizeHeader(_header);
173
156
 
174
157
  if (_header) {
175
- const key = findKey(self, _header);
158
+ const key = utils.findKey(self, _header);
176
159
 
177
160
  if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) {
178
161
  delete self[key];
@@ -189,18 +172,18 @@ Object.assign(AxiosHeaders.prototype, {
189
172
  }
190
173
 
191
174
  return deleted;
192
- },
175
+ }
193
176
 
194
- clear: function() {
177
+ clear() {
195
178
  return Object.keys(this).forEach(this.delete.bind(this));
196
- },
179
+ }
197
180
 
198
- normalize: function(format) {
181
+ normalize(format) {
199
182
  const self = this;
200
183
  const headers = {};
201
184
 
202
185
  utils.forEach(this, (value, header) => {
203
- const key = findKey(headers, header);
186
+ const key = utils.findKey(headers, header);
204
187
 
205
188
  if (key) {
206
189
  self[key] = normalizeValue(value);
@@ -220,30 +203,47 @@ Object.assign(AxiosHeaders.prototype, {
220
203
  });
221
204
 
222
205
  return this;
223
- },
206
+ }
224
207
 
225
- toJSON: function() {
208
+ concat(...targets) {
209
+ return this.constructor.concat(this, ...targets);
210
+ }
211
+
212
+ toJSON(asStrings) {
226
213
  const obj = Object.create(null);
227
214
 
228
- utils.forEach(Object.assign({}, this[$defaults] || null, this),
229
- (value, header) => {
230
- if (value == null || value === false) return;
231
- obj[header] = utils.isArray(value) ? value.join(', ') : value;
232
- });
215
+ utils.forEach(this, (value, header) => {
216
+ value != null && value !== false && (obj[header] = asStrings && utils.isArray(value) ? value.join(', ') : value);
217
+ });
233
218
 
234
219
  return obj;
235
220
  }
236
- });
237
221
 
238
- Object.assign(AxiosHeaders, {
239
- from: function(thing) {
240
- if (utils.isString(thing)) {
241
- return new this(parseHeaders(thing));
242
- }
222
+ [Symbol.iterator]() {
223
+ return Object.entries(this.toJSON())[Symbol.iterator]();
224
+ }
225
+
226
+ toString() {
227
+ return Object.entries(this.toJSON()).map(([header, value]) => header + ': ' + value).join('\n');
228
+ }
229
+
230
+ get [Symbol.toStringTag]() {
231
+ return 'AxiosHeaders';
232
+ }
233
+
234
+ static from(thing) {
243
235
  return thing instanceof this ? thing : new this(thing);
244
- },
236
+ }
245
237
 
246
- accessor: function(header) {
238
+ static concat(first, ...targets) {
239
+ const computed = new this(first);
240
+
241
+ targets.forEach((target) => computed.set(target));
242
+
243
+ return computed;
244
+ }
245
+
246
+ static accessor(header) {
247
247
  const internals = this[$internals] = (this[$internals] = {
248
248
  accessors: {}
249
249
  });
@@ -264,7 +264,7 @@ Object.assign(AxiosHeaders, {
264
264
 
265
265
  return this;
266
266
  }
267
- });
267
+ }
268
268
 
269
269
  AxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent']);
270
270
 
@@ -41,6 +41,10 @@ export default function dispatchRequest(config) {
41
41
  config.transformRequest
42
42
  );
43
43
 
44
+ if (['post', 'put', 'patch'].indexOf(config.method) !== -1) {
45
+ config.headers.setContentType('application/x-www-form-urlencoded', false);
46
+ }
47
+
44
48
  const adapter = config.adapter || defaults.adapter;
45
49
 
46
50
  return adapter(config).then(function onAdapterResolution(response) {
@@ -1,6 +1,9 @@
1
1
  'use strict';
2
2
 
3
3
  import utils from '../utils.js';
4
+ import AxiosHeaders from "./AxiosHeaders.js";
5
+
6
+ const headersToObject = (thing) => thing instanceof AxiosHeaders ? thing.toJSON() : thing;
4
7
 
5
8
  /**
6
9
  * Config-specific merge-function which creates a new config-object
@@ -16,9 +19,9 @@ export default function mergeConfig(config1, config2) {
16
19
  config2 = config2 || {};
17
20
  const config = {};
18
21
 
19
- function getMergedValue(target, source) {
22
+ function getMergedValue(target, source, caseless) {
20
23
  if (utils.isPlainObject(target) && utils.isPlainObject(source)) {
21
- return utils.merge(target, source);
24
+ return utils.merge.call({caseless}, target, source);
22
25
  } else if (utils.isPlainObject(source)) {
23
26
  return utils.merge({}, source);
24
27
  } else if (utils.isArray(source)) {
@@ -28,72 +31,73 @@ export default function mergeConfig(config1, config2) {
28
31
  }
29
32
 
30
33
  // eslint-disable-next-line consistent-return
31
- function mergeDeepProperties(prop) {
32
- if (!utils.isUndefined(config2[prop])) {
33
- return getMergedValue(config1[prop], config2[prop]);
34
- } else if (!utils.isUndefined(config1[prop])) {
35
- return getMergedValue(undefined, config1[prop]);
34
+ function mergeDeepProperties(a, b, caseless) {
35
+ if (!utils.isUndefined(b)) {
36
+ return getMergedValue(a, b, caseless);
37
+ } else if (!utils.isUndefined(a)) {
38
+ return getMergedValue(undefined, a, caseless);
36
39
  }
37
40
  }
38
41
 
39
42
  // eslint-disable-next-line consistent-return
40
- function valueFromConfig2(prop) {
41
- if (!utils.isUndefined(config2[prop])) {
42
- return getMergedValue(undefined, config2[prop]);
43
+ function valueFromConfig2(a, b) {
44
+ if (!utils.isUndefined(b)) {
45
+ return getMergedValue(undefined, b);
43
46
  }
44
47
  }
45
48
 
46
49
  // eslint-disable-next-line consistent-return
47
- function defaultToConfig2(prop) {
48
- if (!utils.isUndefined(config2[prop])) {
49
- return getMergedValue(undefined, config2[prop]);
50
- } else if (!utils.isUndefined(config1[prop])) {
51
- return getMergedValue(undefined, config1[prop]);
50
+ function defaultToConfig2(a, b) {
51
+ if (!utils.isUndefined(b)) {
52
+ return getMergedValue(undefined, b);
53
+ } else if (!utils.isUndefined(a)) {
54
+ return getMergedValue(undefined, a);
52
55
  }
53
56
  }
54
57
 
55
58
  // eslint-disable-next-line consistent-return
56
- function mergeDirectKeys(prop) {
59
+ function mergeDirectKeys(a, b, prop) {
57
60
  if (prop in config2) {
58
- return getMergedValue(config1[prop], config2[prop]);
61
+ return getMergedValue(a, b);
59
62
  } else if (prop in config1) {
60
- return getMergedValue(undefined, config1[prop]);
63
+ return getMergedValue(undefined, a);
61
64
  }
62
65
  }
63
66
 
64
67
  const mergeMap = {
65
- 'url': valueFromConfig2,
66
- 'method': valueFromConfig2,
67
- 'data': valueFromConfig2,
68
- 'baseURL': defaultToConfig2,
69
- 'transformRequest': defaultToConfig2,
70
- 'transformResponse': defaultToConfig2,
71
- 'paramsSerializer': defaultToConfig2,
72
- 'timeout': defaultToConfig2,
73
- 'timeoutMessage': defaultToConfig2,
74
- 'withCredentials': defaultToConfig2,
75
- 'adapter': defaultToConfig2,
76
- 'responseType': defaultToConfig2,
77
- 'xsrfCookieName': defaultToConfig2,
78
- 'xsrfHeaderName': defaultToConfig2,
79
- 'onUploadProgress': defaultToConfig2,
80
- 'onDownloadProgress': defaultToConfig2,
81
- 'decompress': defaultToConfig2,
82
- 'maxContentLength': defaultToConfig2,
83
- 'maxBodyLength': defaultToConfig2,
84
- 'beforeRedirect': defaultToConfig2,
85
- 'transport': defaultToConfig2,
86
- 'httpAgent': defaultToConfig2,
87
- 'httpsAgent': defaultToConfig2,
88
- 'cancelToken': defaultToConfig2,
89
- 'socketPath': defaultToConfig2,
90
- 'responseEncoding': defaultToConfig2,
91
- 'validateStatus': mergeDirectKeys
68
+ url: valueFromConfig2,
69
+ method: valueFromConfig2,
70
+ data: valueFromConfig2,
71
+ baseURL: defaultToConfig2,
72
+ transformRequest: defaultToConfig2,
73
+ transformResponse: defaultToConfig2,
74
+ paramsSerializer: defaultToConfig2,
75
+ timeout: defaultToConfig2,
76
+ timeoutMessage: defaultToConfig2,
77
+ withCredentials: defaultToConfig2,
78
+ adapter: defaultToConfig2,
79
+ responseType: defaultToConfig2,
80
+ xsrfCookieName: defaultToConfig2,
81
+ xsrfHeaderName: defaultToConfig2,
82
+ onUploadProgress: defaultToConfig2,
83
+ onDownloadProgress: defaultToConfig2,
84
+ decompress: defaultToConfig2,
85
+ maxContentLength: defaultToConfig2,
86
+ maxBodyLength: defaultToConfig2,
87
+ beforeRedirect: defaultToConfig2,
88
+ transport: defaultToConfig2,
89
+ httpAgent: defaultToConfig2,
90
+ httpsAgent: defaultToConfig2,
91
+ cancelToken: defaultToConfig2,
92
+ socketPath: defaultToConfig2,
93
+ responseEncoding: defaultToConfig2,
94
+ validateStatus: mergeDirectKeys,
95
+ headers: (a, b) => mergeDeepProperties(headersToObject(a), headersToObject(b), true)
92
96
  };
93
97
 
94
98
  utils.forEach(Object.keys(config1).concat(Object.keys(config2)), function computeConfigValue(prop) {
95
99
  const merge = mergeMap[prop] || mergeDeepProperties;
96
- const configValue = merge(prop);
100
+ const configValue = merge(config1[prop], config2[prop], prop);
97
101
  (utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);
98
102
  });
99
103
 
@@ -10,7 +10,7 @@ import formDataToJSON from '../helpers/formDataToJSON.js';
10
10
  import adapters from '../adapters/index.js';
11
11
 
12
12
  const DEFAULT_CONTENT_TYPE = {
13
- 'Content-Type': 'application/x-www-form-urlencoded'
13
+ 'Content-Type': undefined
14
14
  };
15
15
 
16
16
  /**
package/lib/env/data.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = "1.1.2";
1
+ export const VERSION = "1.2.0-alpha.1";
@@ -35,21 +35,28 @@ export default function buildURL(url, params, options) {
35
35
  if (!params) {
36
36
  return url;
37
37
  }
38
+
39
+ const _encode = options && options.encode || encode;
38
40
 
39
- const hashmarkIndex = url.indexOf('#');
41
+ const serializeFn = options && options.serialize;
40
42
 
41
- if (hashmarkIndex !== -1) {
42
- url = url.slice(0, hashmarkIndex);
43
- }
43
+ let serializedParams;
44
44
 
45
- const _encode = options && options.encode || encode;
45
+ if (serializeFn) {
46
+ serializedParams = serializeFn(params, options);
47
+ } else {
48
+ serializedParams = utils.isURLSearchParams(params) ?
49
+ params.toString() :
50
+ new AxiosURLSearchParams(params, options).toString(_encode);
51
+ }
46
52
 
47
- const serializerParams = utils.isURLSearchParams(params) ?
48
- params.toString() :
49
- new AxiosURLSearchParams(params, options).toString(_encode);
53
+ if (serializedParams) {
54
+ const hashmarkIndex = url.indexOf("#");
50
55
 
51
- if (serializerParams) {
52
- url += (url.indexOf('?') === -1 ? '?' : '&') + serializerParams;
56
+ if (hashmarkIndex !== -1) {
57
+ url = url.slice(0, hashmarkIndex);
58
+ }
59
+ url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;
53
60
  }
54
61
 
55
62
  return url;
@@ -168,7 +168,7 @@ function toFormData(obj, formData, options) {
168
168
  key = removeBrackets(key);
169
169
 
170
170
  arr.forEach(function each(el, index) {
171
- !utils.isUndefined(el) && formData.append(
171
+ !(utils.isUndefined(el) || el === null) && formData.append(
172
172
  // eslint-disable-next-line no-nested-ternary
173
173
  indexes === true ? renderKey([key], index, dots) : (indexes === null ? key : key + '[]'),
174
174
  convertValue(el)
@@ -205,7 +205,7 @@ function toFormData(obj, formData, options) {
205
205
  stack.push(value);
206
206
 
207
207
  utils.forEach(value, function each(el, key) {
208
- const result = !utils.isUndefined(el) && visitor.call(
208
+ const result = !(utils.isUndefined(el) || el === null) && visitor.call(
209
209
  formData, el, utils.isString(key) ? key.trim() : key, path, exposedHelpers
210
210
  );
211
211
 
package/lib/utils.js CHANGED
@@ -228,7 +228,7 @@ const trim = (str) => str.trim ?
228
228
  * @param {Function} fn The callback to invoke for each item
229
229
  *
230
230
  * @param {Boolean} [allOwnKeys = false]
231
- * @returns {void}
231
+ * @returns {any}
232
232
  */
233
233
  function forEach(obj, fn, {allOwnKeys = false} = {}) {
234
234
  // Don't bother if no value provided
@@ -263,6 +263,24 @@ function forEach(obj, fn, {allOwnKeys = false} = {}) {
263
263
  }
264
264
  }
265
265
 
266
+ function findKey(obj, key) {
267
+ key = key.toLowerCase();
268
+ const keys = Object.keys(obj);
269
+ let i = keys.length;
270
+ let _key;
271
+ while (i-- > 0) {
272
+ _key = keys[i];
273
+ if (key === _key.toLowerCase()) {
274
+ return _key;
275
+ }
276
+ }
277
+ return null;
278
+ }
279
+
280
+ const _global = typeof self === "undefined" ? typeof global === "undefined" ? this : global : self;
281
+
282
+ const isContextDefined = (context) => !isUndefined(context) && context !== _global;
283
+
266
284
  /**
267
285
  * Accepts varargs expecting each argument to be an object, then
268
286
  * immutably merges the properties of each object and returns result.
@@ -282,16 +300,18 @@ function forEach(obj, fn, {allOwnKeys = false} = {}) {
282
300
  * @returns {Object} Result of all merge properties
283
301
  */
284
302
  function merge(/* obj1, obj2, obj3, ... */) {
303
+ const {caseless} = isContextDefined(this) && this || {};
285
304
  const result = {};
286
305
  const assignValue = (val, key) => {
287
- if (isPlainObject(result[key]) && isPlainObject(val)) {
288
- result[key] = merge(result[key], val);
306
+ const targetKey = caseless && findKey(result, key) || key;
307
+ if (isPlainObject(result[targetKey]) && isPlainObject(val)) {
308
+ result[targetKey] = merge(result[targetKey], val);
289
309
  } else if (isPlainObject(val)) {
290
- result[key] = merge({}, val);
310
+ result[targetKey] = merge({}, val);
291
311
  } else if (isArray(val)) {
292
- result[key] = val.slice();
312
+ result[targetKey] = val.slice();
293
313
  } else {
294
- result[key] = val;
314
+ result[targetKey] = val;
295
315
  }
296
316
  }
297
317
 
@@ -527,6 +547,11 @@ const reduceDescriptors = (obj, reducer) => {
527
547
 
528
548
  const freezeMethods = (obj) => {
529
549
  reduceDescriptors(obj, (descriptor, name) => {
550
+ // skip restricted props in strict mode
551
+ if (isFunction(obj) && ['arguments', 'caller', 'callee'].indexOf(name) !== -1) {
552
+ return false;
553
+ }
554
+
530
555
  const value = obj[name];
531
556
 
532
557
  if (!isFunction(value)) return;
@@ -540,7 +565,7 @@ const freezeMethods = (obj) => {
540
565
 
541
566
  if (!descriptor.set) {
542
567
  descriptor.set = () => {
543
- throw Error('Can not read-only method \'' + name + '\'');
568
+ throw Error('Can not rewrite read-only method \'' + name + '\'');
544
569
  };
545
570
  }
546
571
  });
@@ -609,5 +634,8 @@ export default {
609
634
  toObjectSet,
610
635
  toCamelCase,
611
636
  noop,
612
- toFiniteNumber
637
+ toFiniteNumber,
638
+ findKey,
639
+ global: _global,
640
+ isContextDefined
613
641
  };