| 'use strict'; |
|
|
| import utils from '../utils.js'; |
| import parseHeaders from '../helpers/parseHeaders.js'; |
|
|
| const $internals = Symbol('internals'); |
|
|
| function normalizeHeader(header) { |
| return header && String(header).trim().toLowerCase(); |
| } |
|
|
| function normalizeValue(value) { |
| if (value === false || value == null) { |
| return value; |
| } |
|
|
| return utils.isArray(value) ? value.map(normalizeValue) : String(value); |
| } |
|
|
| function parseTokens(str) { |
| const tokens = Object.create(null); |
| const tokensRE = /([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g; |
| let match; |
|
|
| while ((match = tokensRE.exec(str))) { |
| tokens[match[1]] = match[2]; |
| } |
|
|
| return tokens; |
| } |
|
|
| const isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim()); |
|
|
| function matchHeaderValue(context, value, header, filter, isHeaderNameFilter) { |
| if (utils.isFunction(filter)) { |
| return filter.call(this, value, header); |
| } |
|
|
| if (isHeaderNameFilter) { |
| value = header; |
| } |
|
|
| if (!utils.isString(value)) return; |
|
|
| if (utils.isString(filter)) { |
| return value.indexOf(filter) !== -1; |
| } |
|
|
| if (utils.isRegExp(filter)) { |
| return filter.test(value); |
| } |
| } |
|
|
| function formatHeader(header) { |
| return header.trim() |
| .toLowerCase().replace(/([a-z\d])(\w*)/g, (w, char, str) => { |
| return char.toUpperCase() + str; |
| }); |
| } |
|
|
| function buildAccessors(obj, header) { |
| const accessorName = utils.toCamelCase(' ' + header); |
|
|
| ['get', 'set', 'has'].forEach(methodName => { |
| Object.defineProperty(obj, methodName + accessorName, { |
| value: function(arg1, arg2, arg3) { |
| return this[methodName].call(this, header, arg1, arg2, arg3); |
| }, |
| configurable: true |
| }); |
| }); |
| } |
|
|
| class AxiosHeaders { |
| constructor(headers) { |
| headers && this.set(headers); |
| } |
|
|
| set(header, valueOrRewrite, rewrite) { |
| const self = this; |
|
|
| function setHeader(_value, _header, _rewrite) { |
| const lHeader = normalizeHeader(_header); |
|
|
| if (!lHeader) { |
| throw new Error('header name must be a non-empty string'); |
| } |
|
|
| const key = utils.findKey(self, lHeader); |
|
|
| if(!key || self[key] === undefined || _rewrite === true || (_rewrite === undefined && self[key] !== false)) { |
| self[key || _header] = normalizeValue(_value); |
| } |
| } |
|
|
| const setHeaders = (headers, _rewrite) => |
| utils.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite)); |
|
|
| if (utils.isPlainObject(header) || header instanceof this.constructor) { |
| setHeaders(header, valueOrRewrite) |
| } else if(utils.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) { |
| setHeaders(parseHeaders(header), valueOrRewrite); |
| } else if (utils.isObject(header) && utils.isIterable(header)) { |
| let obj = {}, dest, key; |
| for (const entry of header) { |
| if (!utils.isArray(entry)) { |
| throw TypeError('Object iterator must return a key-value pair'); |
| } |
|
|
| obj[key = entry[0]] = (dest = obj[key]) ? |
| (utils.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]]) : entry[1]; |
| } |
|
|
| setHeaders(obj, valueOrRewrite) |
| } else { |
| header != null && setHeader(valueOrRewrite, header, rewrite); |
| } |
|
|
| return this; |
| } |
|
|
| get(header, parser) { |
| header = normalizeHeader(header); |
|
|
| if (header) { |
| const key = utils.findKey(this, header); |
|
|
| if (key) { |
| const value = this[key]; |
|
|
| if (!parser) { |
| return value; |
| } |
|
|
| if (parser === true) { |
| return parseTokens(value); |
| } |
|
|
| if (utils.isFunction(parser)) { |
| return parser.call(this, value, key); |
| } |
|
|
| if (utils.isRegExp(parser)) { |
| return parser.exec(value); |
| } |
|
|
| throw new TypeError('parser must be boolean|regexp|function'); |
| } |
| } |
| } |
|
|
| has(header, matcher) { |
| header = normalizeHeader(header); |
|
|
| if (header) { |
| const key = utils.findKey(this, header); |
|
|
| return !!(key && this[key] !== undefined && (!matcher || matchHeaderValue(this, this[key], key, matcher))); |
| } |
|
|
| return false; |
| } |
|
|
| delete(header, matcher) { |
| const self = this; |
| let deleted = false; |
|
|
| function deleteHeader(_header) { |
| _header = normalizeHeader(_header); |
|
|
| if (_header) { |
| const key = utils.findKey(self, _header); |
|
|
| if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) { |
| delete self[key]; |
|
|
| deleted = true; |
| } |
| } |
| } |
|
|
| if (utils.isArray(header)) { |
| header.forEach(deleteHeader); |
| } else { |
| deleteHeader(header); |
| } |
|
|
| return deleted; |
| } |
|
|
| clear(matcher) { |
| const keys = Object.keys(this); |
| let i = keys.length; |
| let deleted = false; |
|
|
| while (i--) { |
| const key = keys[i]; |
| if(!matcher || matchHeaderValue(this, this[key], key, matcher, true)) { |
| delete this[key]; |
| deleted = true; |
| } |
| } |
|
|
| return deleted; |
| } |
|
|
| normalize(format) { |
| const self = this; |
| const headers = {}; |
|
|
| utils.forEach(this, (value, header) => { |
| const key = utils.findKey(headers, header); |
|
|
| if (key) { |
| self[key] = normalizeValue(value); |
| delete self[header]; |
| return; |
| } |
|
|
| const normalized = format ? formatHeader(header) : String(header).trim(); |
|
|
| if (normalized !== header) { |
| delete self[header]; |
| } |
|
|
| self[normalized] = normalizeValue(value); |
|
|
| headers[normalized] = true; |
| }); |
|
|
| return this; |
| } |
|
|
| concat(...targets) { |
| return this.constructor.concat(this, ...targets); |
| } |
|
|
| toJSON(asStrings) { |
| const obj = Object.create(null); |
|
|
| utils.forEach(this, (value, header) => { |
| value != null && value !== false && (obj[header] = asStrings && utils.isArray(value) ? value.join(', ') : value); |
| }); |
|
|
| return obj; |
| } |
|
|
| [Symbol.iterator]() { |
| return Object.entries(this.toJSON())[Symbol.iterator](); |
| } |
|
|
| toString() { |
| return Object.entries(this.toJSON()).map(([header, value]) => header + ': ' + value).join('\n'); |
| } |
|
|
| getSetCookie() { |
| return this.get("set-cookie") || []; |
| } |
|
|
| get [Symbol.toStringTag]() { |
| return 'AxiosHeaders'; |
| } |
|
|
| static from(thing) { |
| return thing instanceof this ? thing : new this(thing); |
| } |
|
|
| static concat(first, ...targets) { |
| const computed = new this(first); |
|
|
| targets.forEach((target) => computed.set(target)); |
|
|
| return computed; |
| } |
|
|
| static accessor(header) { |
| const internals = this[$internals] = (this[$internals] = { |
| accessors: {} |
| }); |
|
|
| const accessors = internals.accessors; |
| const prototype = this.prototype; |
|
|
| function defineAccessor(_header) { |
| const lHeader = normalizeHeader(_header); |
|
|
| if (!accessors[lHeader]) { |
| buildAccessors(prototype, _header); |
| accessors[lHeader] = true; |
| } |
| } |
|
|
| utils.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header); |
|
|
| return this; |
| } |
| } |
|
|
| AxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent', 'Authorization']); |
|
|
| |
| utils.reduceDescriptors(AxiosHeaders.prototype, ({value}, key) => { |
| let mapped = key[0].toUpperCase() + key.slice(1); |
| return { |
| get: () => value, |
| set(headerValue) { |
| this[mapped] = headerValue; |
| } |
| } |
| }); |
|
|
| utils.freezeMethods(AxiosHeaders); |
|
|
| export default AxiosHeaders; |
|
|